diff -urN linux-2.4.21/CREDITS linux-2.4.22/CREDITS --- linux-2.4.21/CREDITS 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/CREDITS 2003-08-25 04:44:39.000000000 -0700 @@ -111,16 +111,18 @@ S: USA N: Andrea Arcangeli -E: andrea@e-mind.com -W: http://e-mind.com/~andrea/ -P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 +E: andrea@suse.de +W: http://www.kernel.org/pub/linux/kernel/people/andrea/ +P: 1024D/68B9CB43 13D9 8355 295F 4823 7C49 C012 DFA1 686E 68B9 CB43 +P: 1024R/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 D: Parport hacker D: Implemented a workaround for some interrupt buggy printers -D: Author of pscan that helps to fix lp/parport bug +D: Author of pscan that helps to fix lp/parport bugs D: Author of lil (Linux Interrupt Latency benchmark) D: Fixed the shm swap deallocation at swapoff time (try_to_unuse message) +D: VM hacker D: Various other kernel hacks -S: Via Ciaclini 26 +S: Via Cicalini 26 S: Imola 40026 S: Italy @@ -600,10 +602,6 @@ S: USA N: Alan Cox -W: http://roadrunner.swansea.linux.org.uk/alan.shtml -E: alan@lxorguk.ukuu.org.uk -E: alan@www.linux.org.uk (linux.org.uk stuff) -E: Alan.Cox@linux.org (if others fail) D: Linux Networking (0.99.10->2.0.29) D: Original Appletalk, AX.25, and IPX code D: Current 3c501 hacker. >>More 3c501 info/tricks wanted<<. @@ -1348,7 +1346,9 @@ N: Marcel Holtmann E: marcel@holtmann.org W: http://www.holtmann.org -D: Author of the Linux Bluetooth Subsystem PC Card drivers +D: Author and maintainer of the various Bluetooth HCI drivers +D: Author and maintainer of the CAPI message transport protocol driver +D: Various other Bluetooth related patches, cleanups and fixes S: Germany N: Rob W. W. Hooft @@ -1512,6 +1512,18 @@ S: 8103 Rein S: Austria +N: Mitsuru Kanda +E: mk@linux-ipv6.org +E: mk@isl.rdc.toshiba.co.jp +E: mk@karaba.org +W: http://www.karaba.org/~mk/ +P: 1024D/2EC7E30D 9A35 D378 F084 9EA4 EFBA 925B 1C93 B376 F0EF BE59 +D: IPsec, IPv6 +D: USAGI/WIDE Project, TOSHIBA CORPORATION +S: 2-47-8, Takinogawa, +S: Kita, Tokyo 114-0023 +S: Japan + N: Jan Kara E: jack@atrey.karlin.mff.cuni.cz E: jack@suse.cz @@ -1929,7 +1941,7 @@ S: Canada B3J 3C8 N: Kai Mäkisara -E: Kai.Makisara@metla.fi +E: Kai.Makisara@kolumbus.fi D: SCSI Tape Driver N: Dan Malek @@ -2148,6 +2160,17 @@ S: Richardson, Texas 75081 S: USA +N: Kazunori Miyazawa +E: miyazawa@linux-ipv6.org +E: Kazunori.Miyazawa@jp.yokogawa.com +E: kazunori@miyazawa.org +W: http://www.miyazawa.org/~kazunori/ +D: IPsec, IPv6 +D: USAGI/WIDE Project, Yokogawa Electric Corporation +S: 2-20-4-203, Nakacho, +S: Musashino, Tokyo 180-0006 +S: Japan + N: Patrick Mochel E: pat@osdl.org E: mochelp@infinity.powertie.org @@ -2687,6 +2710,14 @@ E: gt8134b@prism.gatech.edu D: Dosemu +N: Duncan Sands +E: duncan.sands@wanadoo.fr +W: http://topo.math.u-psud.fr/~sands +D: Alcatel SpeedTouch USB driver +S: 69 rue Dunois +S: 75013 Paris +S: France + N: Hannu Savolainen E: hannu@opensound.com D: Maintainer of the sound drivers until 2.1.x days. @@ -3062,7 +3093,7 @@ N: Geert Uytterhoeven E: geert@linux-m68k.org W: http://home.tvd.be/cr26864/ -P: 1024/EC4A1EE1 8B 88 38 35 88 1E 95 A1 CD 9E AE DC 4B 4A 2F 41 +P: 1024/862678A6 C51D 361C 0BD1 4C90 B275 C553 6EEA 11BA 8626 78A6 D: m68k/Amiga and PPC/CHRP Longtrail coordinator D: Frame buffer device and XF68_FBDev maintainer D: m68k IDE maintainer @@ -3071,8 +3102,8 @@ D: Atari Falcon chipset IDE D: Amiga Gayle chipset IDE D: mipsel NEC DDB Vrc-5074 -S: C. Huysmansstraat 12 -S: B-3128 Baal +S: Holsbeeksesteenweg 166 +S: B-3010 Kessel-Lo S: Belgium N: Petr Vandrovec @@ -3327,6 +3358,17 @@ D: Workbit NinjaSCSI-32Bi/UDE driver S: Japan +N: Hideaki YOSHIFUJI +E: hideaki@yoshifuji.org +E: yoshfuji@linux-ipv6.org +W: http://www.yoshifuji.org/~hideaki/ +P: 1024D/E0620EEA 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA +D: IPv6 and other networking related stuff +D: USAGI/WIDE Project, The University of Tokyo +S: Green House #102, 1-15-5, Nishikata, +S: Bunkyo, Tokyo 113-0024 +S: Japan + N: Eric Youngdale E: eric@andante.org W: http://www.andante.org diff -urN linux-2.4.21/Documentation/Configure.help linux-2.4.22/Documentation/Configure.help --- linux-2.4.21/Documentation/Configure.help 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/Configure.help 2003-08-25 04:44:39.000000000 -0700 @@ -12,8 +12,8 @@ # # - French, by Pierre Tane , at # -# - Polish, by Dominik Mierzejewski , at -# +# - Polish, by Dominik Mierzejewski , at +# # - German, by SuSE, at . This patch # also includes infrastructure to support different languages. # - Catalan, by Antoni Bella , at @@ -467,6 +467,18 @@ "real" root file system, etc. See for details. +Embed root filesystem ramdisk into the kernel +CONFIG_EMBEDDED_RAMDISK + Select this option if you want to build the ramdisk image into the + the final kernel binary. + +Filename of gziped ramdisk image +CONFIG_EMBEDDED_RAMDISK_IMAGE + This is the filename of the ramdisk image to be built into the + kernel. Relative pathnames are relative to arch/mips/ramdisk/. + The ramdisk image is not part of the kernel distribution; you must + provide one yourself. + Loopback device support CONFIG_BLK_DEV_LOOP Saying Y here will allow you to use a regular file as a block @@ -1474,6 +1486,11 @@ to transfer data to and from memory. Saying Y is safe and improves performance. +Broadcom SiByte onboard IDE support +CONFIG_BLK_DEV_IDE_SIBYTE + Include the driver for on-board IDE on the SiByte Generic Bus. Note + that this limits the number of IDE devices to 4 (ide0...ide3). + Use DMA by default CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO This option allows the driver for the built-in IDE controller on @@ -2095,6 +2112,78 @@ This enables support for the VR5000-based MIPS Malta evaluation board. +# Choice: bcmboard +Support for Broadcom SiByte boards +CONFIG_SIBYTE_SWARM + Enable support for boards based on the Broadcom SiByte family: + + BCM91250A-SWARM BCM1250 ATX size Eval Board (BCM91250A-SWARM) + + BCM91250E-Sentosa BCM1250 PCI card Eval Board (BCM91250E-Sentosa) + + BCM91125E-Rhone BCM1125 PCI card Eval Board (BCM91125E-Rhone) + + Other Non-Broadcom SiByte-based platform + +# Choice: bcmsoc +Support for Broadcom BCM1xxx SOCs +CONFIG_SIBYTE_SB1250 + + BCM1250 Dual-CPU SB1 with PCI and HyperTransport. + + BCM1120 Uniprocessor SB1. + + BCM1125 Uniprocessor SB1 with PCI (and HyperTransport for 1125H). + +BCM1250 Stepping +CONFIG_CPU_SB1_PASS_1 + Which pass of the SOC is supported (see the "system_revision" + register in the User Manual for more discussion of revisions): + + Pass1 1250 "Pass 1" + + An 1250 "Pass 2" + + Bn 1250 "Pass 2.2" + + Cn 1250 "Pass 3" + +BCM112x Stepping +CONFIG_CPU_SB1_PASS_2 + Which pass of the SOC is supported (see the "system_revision" + register in the User Manual for more discussion of revisions): + + Hybrid 1250 "Pass 2" + + An 112x "Pass 1" + +Booting from CFE +CONFIG_SIBYTE_CFE + Make use of the CFE API for enumerating available memory, + controlling secondary CPUs, and possibly console output. + +Use firmware console +CONFIG_SIBYTE_CFE_CONSOLE + Use the CFE API's console write routines during boot. Other console + options (VT console, sb1250 duart console, etc.) should not be + configured. + +Support for Bus Watcher statistics +CONFIG_SIBYTE_BUS_WATCHER + Handle and keep statistics on the bus error interrupts (COR_ECC, + BAD_ECC, IO_BUS). + +Corelis Debugger +CONFIG_SB1XXX_CORELIS + Select compile flags that produce code that can be processed by the + Corelis mksym utility and UDB Emulator. + +DMA for page clear and copy +CONFIG_SIBYTE_DMA_PAGEOPS + Instead of using the CPU to zero and copy pages, use a Data Mover + channel. These DMA channels are otherwise unused by the standard + SiByte Linux port. Seems to give a small performance benefit. + Support for Galileo Evaluation board or CoSine Orion CONFIG_ORION Say Y if configuring for the Galileo evaluation board @@ -2164,11 +2253,6 @@ 4000, Acer PICA, Olivetti M700-10 and a few other identical OEM systems. -MIPS GT96100 support -CONFIG_MIPS_GT96100 - Say Y here to support the Galileo Technology GT96100 communications - controller card. There is a web page at . - MIPS GT96100 Ethernet support CONFIG_MIPS_GT96100ETH Say Y here to support the Ethernet subsystem on your GT96100 card. @@ -2181,16 +2265,31 @@ workstations). Say Y here to make sure it gets initialized correctly before the Linux kernel tries to talk to the controller. -Kernel floating-point instruction emulation -CONFIG_MIPS_FPU_EMULATOR - This option enables the MIPS software floating support. Due to - the way floating point works you should always enable this option - unless you exactly know what you're doing. - SGI PROM Console Support CONFIG_SGI_PROM_CONSOLE Say Y here to set up the boot console on serial port 0. +DECstation serial support +CONFIG_SERIAL_DEC + This selects whether you want to be asked about drivers for + DECstation serial ports. + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about DECstation serial ports. + + If unsure, say Y. + +Support for console on a DECstation serial port +CONFIG_SERIAL_DEC_CONSOLE + If you say Y here, it will be possible to use a serial port as the + system console (the system console is the device which receives all + kernel messages and warnings and which allows logins in single user + mode). Note that the firmware uses ttyS0 as the serial console on + the Maxine and ttyS2 on the others. + + If unsure, say Y. + DZ11 Serial Support CONFIG_DZ DZ11-family serial controllers for VAXstations, including the @@ -2310,6 +2409,8 @@ R10000 MIPS Technologies R10000-series processors. + SB1 Broadcom SiByte SB1 processor. + R6000 CONFIG_CPU_R6000 MIPS Technologies R6000-series processors, including the 64474, @@ -2340,6 +2441,10 @@ CONFIG_CPU_R10000 MIPS Technologies R10000-series processors. +SB1 +CONFIG_CPU_SB1 + Broadcom SiByte SB1 processor. + Discontiguous Memory Support CONFIG_DISCONTIGMEM Say Y to support efficient handling of discontiguous physical memory, @@ -2589,6 +2694,17 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +recent match support +CONFIG_IP_NF_MATCH_RECENT + This match is used for creating one or many lists of recently + used addresses and then matching against that/those list(s). + + Short options are available by using 'iptables -m recent -h' + Official Website: + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + limit match support CONFIG_IP_NF_MATCH_LIMIT limit matching allows you to control the rate at which a rule can be @@ -3052,6 +3168,11 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +ARP payload mangling +CONFIG_IP_NF_ARP_MANGLE + Allows altering the ARP packet payload: source and destination + hardware and network addresses. + TCP Explicit Congestion Notification support CONFIG_INET_ECN Explicit Congestion Notification (ECN) allows routers to notify @@ -3341,7 +3462,7 @@ here. If MILO doesn't work on your system (true for Jensen motherboards), you can bypass it altogether and boot Linux directly from an SRM console; say Y here in order to do that. Note that you - won't be able to boot from an IDE disk using SRM. + won't be able to boot from an IDE disk using old versions of SRM. If unsure, say N. @@ -3432,18 +3553,11 @@ servicing. Say Y here to enable the serial driver to take advantage of those special I/O ports. -SGI Zilog85C30 serial support -CONFIG_SGI_SERIAL - If you want to use your SGI's built-in serial ports under Linux, +SGI IP22 Zilog85C30 serial support +CONFIG_IP22_SERIAL + If you want to use your IP22's built-in serial ports under Linux, answer Y. -SGI Newport Graphics support -CONFIG_SGI_NEWPORT_GFX - If you have an SGI machine and you want to compile the graphics - drivers, say Y here. This will include the code for the - /dev/graphics and /dev/gfx drivers into the kernel for supporting - virtualized access to your graphics hardware. - SGI Newport Console support CONFIG_SGI_NEWPORT_CONSOLE Say Y here if you want the console on the Newport aka XL graphics @@ -3606,6 +3720,14 @@ Say Y here to support the Serverworks AGP card. See for product descriptions and images. +NVIDIA chipset support +CONFIG_AGP_NVIDIA + This option gives you AGP support for the GLX component of the + XFree86 4.x on NVIDIA nForce/nForce2 chipsets. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + ALI chipset support CONFIG_AGP_ALI This option gives you AGP support for the GLX component of the @@ -3977,6 +4099,11 @@ "Bridge" is the name used for the hardware inside your computer that PCMCIA cards are plugged into. If unsure, say N. +CONFIG_PCMCIA_SIBYTE + Say Y here to include support for the SiByte SOC's built-in PCMCIA + interface. Only ATA cards and CompactFlash are currently + supported. + System V IPC CONFIG_SYSVIPC Inter Process Communication is a suite of library functions and @@ -4497,21 +4624,20 @@ Maxine (Personal DECstation) onboard framebuffer support CONFIG_FB_MAXINE - Say Y here to directly support the on-board framebuffer in the - Maxine (5000/20, /25, /33) version of the DECstation. There is a - page dedicated to Linux on DECstations at . + Support for the onboard framebuffer (1024x768x8) in the Personal + DECstation series (Personal DECstation 5000/20, /25, /33, /50, + Codename "Maxine"). PMAG-BA TURBOchannel framebuffer support CONFIG_FB_PMAG_BA - Say Y here to directly support the on-board PMAG-BA framebuffer in - the 5000/1xx versions of the DECstation. There is a page dedicated - to Linux on DECstations at . + Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) + used mainly in the MIPS-based DECstation series. PMAGB-B TURBOchannel framebuffer support CONFIG_FB_PMAGB_B - Say Y here to directly support the on-board PMAGB-B framebuffer in - the 5000/1xx versions of the DECstation. There is a page dedicated - to Linux on DECstations at . + Support for the PMAGB-B TURBOchannel framebuffer card used mainly + in the MIPS-based DECstation series. The card is currently only + supported in 1280x1024x8 mode. FutureTV PCI card CONFIG_ARCH_FTVPCI @@ -4792,27 +4918,46 @@ packed pixel and 32 bpp packed pixel. You can also use font widths different from 8. -Matrox G100/G200/G400/G450/G550 support -CONFIG_FB_MATROX_G100 - Say Y here if you have a Matrox G100, G200, G400, G450, or G550 - based video card. If you select "Advanced lowlevel driver options", - you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp - packed pixel and 32 bpp packed pixel. You can also use font widths +CONFIG_FB_MATROX_G450 + Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based + video card. If you select "Advanced lowlevel driver options", you + should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed + pixel and 32 bpp packed pixel. You can also use font widths different from 8. If you need support for G400 secondary head, you must first say Y to "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. + support" here in the framebuffer section. G450/G550 secondary head + and digital output are supported without additional modules. - 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... + The driver starts in monitor mode. You must use the matroxset tool + (available at ) to + swap primary and secondary head outputs, or to change output mode. + Secondary head driver always start in 640x480 resolution and you + must use fbset to change it. - If you need support for G450 or G550 secondary head, say Y to - "Matrox G450/G550 second head support" below. + Do not forget that second head supports only 16 and 32 bpp + packed pixels, so it is a good idea to compile them into the kernel + too. You can use only some font widths, as the driver uses generic + painting procedures (the secondary head does not use acceleration + engine). + + G450/G550 hardware can display TV picture only from secondary CRTC, + and it performs no scaling, so picture must have 525 or 625 lines. + +CONFIG_FB_MATROX_G100A + Say Y here if you have a Matrox G100, G200 or G400 based + video card. If you select "Advanced lowlevel driver options", you + should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed + pixel and 32 bpp packed pixel. You can also use font widths + different from 8. + + If you need support for G400 secondary head, you must first say Y to + "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. -Matrox I2C support CONFIG_FB_MATROX_I2C This drivers creates I2C buses which are needed for accessing the DDC (I2C) bus present on all Matroxes, an I2C bus which @@ -4855,32 +5000,14 @@ painting procedures (the secondary head does not use acceleration engine). -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 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 - want two independent display devices. - - The driver starts in monitor mode and currently does not support - output in TV modes. You must use the matroxset tool (available - at ) to swap - primary and secondary head outputs. Secondary head driver always - start in 640x480 resolution and you must use fbset to change it. - - Note on most G550 cards the analog output is the secondary head, - so you will need to say Y here to use it. - - Also do not forget that second head supports only 16 and 32 bpp - packed pixels, so it is a good idea to compile them into the kernel - too. You can use only some font widths, as the driver uses generic - painting procedures (the secondary head does not use acceleration - engine). - -Matrox unified driver multihead support +CONFIG_FB_MATROX_PROC + Say Y or M here if you want to access some informations about driver + state through /proc interface. + + You should download matrox_pins tool (available at + ) to get human + readable output. + CONFIG_FB_MATROX_MULTIHEAD Say Y here if you have more than one (supported) Matrox device in your computer and you want to use all of them for different monitors @@ -5476,11 +5603,6 @@ handled by the klogd daemon which is responsible for kernel messages ("man klogd"). -Large routing tables -CONFIG_IP_ROUTE_LARGE_TABLES - If you have routing zones that grow to more than about 64 entries, - you may want to say Y here to speed up the routing process. - Fast network address translation CONFIG_IP_ROUTE_NAT If you say Y here, your router will be able to modify source and @@ -6904,6 +7026,15 @@ the performances of the driver, and the size of your syslog files! Keep the debugging level to 0 during normal operations. +ForeRunner HE Series +CONFIG_ATM_HE + This is a driver for the Marconi ForeRunner HE-series ATM adapter + cards. It simultaneously supports the 155 and 622 versions. + +Use S/UNI PHY driver + Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner + HE cards. This driver provides carrier detection some statistics. + PPP over ATM CONFIG_PPPOATM Support PPP (Point to Point Protocol) encapsulated in ATM frames. @@ -7290,47 +7421,40 @@ Adaptec AIC7xxx support CONFIG_SCSI_AIC7XXX - This driver supports all of Adaptec's PCI based SCSI controllers - (not the hardware RAID controllers though) as well as the aic7770 - based EISA and VLB SCSI controllers (the 274x and 284x series). - This is an Adaptec sponsored driver written by Justin Gibbs. It is - intended to replace the previous aic7xxx driver maintained by Doug - Ledford since Doug is no longer maintaining that driver. + This driver supports all of Adaptec's Fast through Ultra 160 PCI + based SCSI controllers as well as the aic7770 based EISA and VLB + SCSI controllers (the 274x and 284x series). For AAA and ARO based + configurations, only SCSI functionality is provided. If you want to compile the driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called aic7xxx.o. -Adaptec I2O RAID support -CONFIG_SCSI_DPT_I2O - This driver supports all of Adaptec's I2O based RAID controllers as - well as the DPT SmartRaid V cards. This is an Adaptec maintained - driver by Deanna Bonds. See . - - 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 - dpt_i2o.o. - -Default number of TCQ commands per device +Maximum number of TCQ commands per device CONFIG_AIC7XXX_CMDS_PER_DEVICE Specify the number of commands you would like to allocate per SCSI device when Tagged Command Queueing (TCQ) is enabled on that device. This is an upper bound value for the number of tagged transactions to be used for any device. The aic7xxx driver will automatically - vary this number based on device behaviour. For devices with a + vary this number based on device behavior. For devices with a fixed maximum, the driver will eventually lock to this maximum and display a console message indicating this value. - Note: Unless you experience some type of device failure, the default - value, no enforced limit, should work for you. + Due to resource allocation issues in the Linux SCSI mid-layer, using + a high number of commands per device may result in memory allocation + failures when many devices are attached to the system. For this reason, + the default is set to 32. Higher values may result in higer performance + on some devices. The upper bound is 253. 0 disables tagged queueing. - Default: 253 + Per device tag depth can be controlled via the kernel command line + "tag_info" option. See drivers/scsi/aic7xxx/README.aic7xxx + for details. + + Default: 32 -Delay in seconds after SCSI bus reset +Initial bus reset delay in milli-seconds CONFIG_AIC7XXX_RESET_DELAY_MS The number of milliseconds to delay after an initial bus reset. The bus settle delay following all error recovery actions is @@ -7338,16 +7462,43 @@ Default: 15000 (15 seconds) -Build Adapter Firmware with Kernel Build +Probe for EISA and VL AIC7XXX Adapters +CONFIG_AIC7XXX_PROBE_EISA_VL + Probe for EISA and VLB Aic7xxx controllers. In many newer systems, + the invasive probes necessary to detect these controllers can cause + other devices to fail. For this reason, the non-PCI probe code is + disabled by default. The current value of this option can be "toggled" + via the no_probe kernel command line option. + CONFIG_AIC7XXX_BUILD_FIRMWARE This option should only be enabled if you are modifying the firmware source to the aic7xxx driver and wish to have the generated firmware include files updated during a normal kernel build. The assembler for the firmware requires lex and yacc or their equivalents, as well as the db v1 library. You may have to install additional packages - or modify the assembler make file or the files it includes if your + or modify the assembler Makefile or the files it includes if your build environment is different than that of the author. +Compile in Debugging Code +CONFIG_AIC7XXX_DEBUG_ENABLE + Compile in aic7xxx debugging code that can be useful in diagnosing + driver errors. + +Debug code enable mask (2048 for all debugging) +CONFIG_AIC7XXX_DEBUG_MASK + Bit mask of debug options that is only valid if the + CONFIG_AIC7XXX_DEBUG_ENBLE option is enabled. The bits in this mask + are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the + variable ahc_debug in that file to find them. + + Default: 0 + +Decode registers during diagnostics +CONFIG_AIC7XXX_REG_PRETTY_PRINT + Compile in register value tables for the output of expanded register + contents in diagnostics. This make it much easier to understand debug + output without having to refer to a data book and/or the aic7xxx.reg file. + Old Adaptec AIC7xxx support CONFIG_SCSI_AIC7XXX_OLD WARNING This driver is an older aic7xxx driver and is no longer @@ -7456,6 +7607,83 @@ If unsure, say N. +CONFIG_SCSI_AIC79XX + This driver supports all of Adaptec's Ultra 320 PCI-X based SCSI controllers. + +CONFIG_AIC79XX_CMDS_PER_DEVICE 32 + Specify the number of commands you would like to allocate per SCSI + device when Tagged Command Queueing (TCQ) is enabled on that device. + + This is an upper bound value for the number of tagged transactions + to be used for any device. The aic7xxx driver will automatically + vary this number based on device behavior. For devices with a + fixed maximum, the driver will eventually lock to this maximum + and display a console message indicating this value. + + Due to resource allocation issues in the Linux SCSI mid-layer, using + a high number of commands per device may result in memory allocation + failures when many devices are attached to the system. For this reason, + the default is set to 32. Higher values may result in higer performance + on some devices. The upper bound is 253. + + Per device tag depth can be controlled via the kernel command line + "tag_info" option. See drivers/scsi/aic7xxx/README.aic79xx + for details. + + Default: 32 + +CONFIG_AIC79XX_RESET_DELAY_MS 15000 + The number of milliseconds to delay after an initial bus reset. + The bus settle delay following all error recovery actions is + dictated by the SCSI layer and is not affected by this value. + + Default: 15000 (15 seconds) + +CONFIG_AIC79XX_BUILD_FIRMWARE + This option should only be enabled if you are modifying the firmware + source to the aic7xxx driver and wish to have the generated firmware + include files updated during a normal kernel build. The assembler + for the firmware requires lex and yacc or their equivalents, as well + as the db v1 library. You may have to install additional packages + or modify the assembler Makefile or the files it includes if your + build environment is different than that of the author. + +CONFIG_AIC79XX_ENABLE_RD_STRM + Read Streaming is a U320 protocol option that should enhance performance. + Early U320 drive firmware actually performs slower with read streaming + enabled so it is disabled by default. Read Streaming can be configured + in much the same way as tagged queueing using the "rd_strm" command line + option. See drivers/scsi/aic7xxx/README.aic79xx for details. + +CONFIG_AIC79XX_DEBUG_ENABLE + Compile in aic79xx debugging code that can be useful in diagnosing + driver errors. + +CONFIG_AIC79XX_DEBUG_MASK + Bit mask of debug options that is only valid if the + CONFIG_AIC79XX_DEBUG_ENBLE option is enabled. The bits in this mask + are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the + variable ahd_debug in that file to find them. + + Default: 0 + +CONFIG_AIC79XX_REG_PRETTY_PRINT + Compile in register value tables for the output of expanded register + contents in diagnostics. This make it much easier to understand debug + output without having to refer to a data book and/or the aic7xxx.reg file. + +Adaptec I2O RAID support +CONFIG_SCSI_DPT_I2O + This driver supports all of Adaptec's I2O based RAID controllers as + well as the DPT SmartRaid V cards. This is an Adaptec maintained + driver by Deanna Bonds. See . + + 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 + dpt_i2o.o. + IBM ServeRAID support CONFIG_SCSI_IPS This is support for the IBM ServeRAID hardware RAID controllers. @@ -11489,6 +11717,18 @@ module, say M here and read as well as . +Broadcom 4400 ethernet support (EXPERIMENTAL) +CONFIG_B44 + If you have a network (Ethernet) controller of this type, say Y and + read the Ethernet-HOWTO, available from + . + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read as well as + . The module will be + called b44. + CS89x0 support (Daynaport CS and LC cards) CONFIG_CS89x0 Support for CS89x0 chipset based Ethernet cards. If you have a @@ -11861,15 +12101,6 @@ module, say M here and read as well as . -New Tulip bus configuration -CONFIG_TULIP_MWI - This configures your Tulip card specifically for the card and - system cache line size type you are using. - - This is experimental code, not yet tested on many boards. - - If unsure, say N. - Use PCI shared memory for NIC registers CONFIG_TULIP_MMIO Use PCI shared memory for the NIC registers, rather than going through @@ -12789,10 +13020,18 @@ If you say Y here, you will be able to set per user limits for disk usage (also called disk quotas). Currently, it works only for the ext2 file system. You need additional software in order to use quota - support; for details, read the Quota mini-HOWTO, available from + support (you can download sources from + ). For further details, read + the Quota mini-HOWTO, available from . Probably the quota support is only useful for multi user systems. If unsure, say N. +VFS v0 quota format support +CONFIG_QFMT_V2 + This quota format allows using quotas with 32-bit UIDs/GIDs. If you + need this functionality say Y here. Note that you will need latest + quota utilities for new quota format with this kernel. + Memory Technology Device (MTD) support CONFIG_MTD Memory Technology Devices are flash, RAM and similar chips, often @@ -12853,22 +13092,40 @@ . The module will be called redboot.o -Compaq bootldr partition table parsing -CONFIG_MTD_BOOTLDR_PARTS - The Compaq bootldr deals with multiple 'images' in flash devices - by putting a table in one of the first erase blocks of the device, - similar to a partition table, which gives the offsets, lengths and - names of all the images stored in the flash. - - If you need code which can detect and parse this table, and register - MTD 'partitions' corresponding to each image in the table, enable - this option. +CONFIG_MTD_CMDLINE_PARTS + Allow generic configuration of the MTD paritition tables via the kernel + command line. Multiple flash resources are supported for hardware where + different kinds of flash memory are available. You will still need the parsing functions to be called by the driver for your particular device. It won't happen automatically. The SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for example. + The format for the command line is as follows: + + mtdparts=[; := :[,] + := [@offset][][ro] + := unique id used in mapping driver/device + := standard linux memsize OR "-" to denote all + remaining space + := (NAME) + + Due to the way Linux handles the command line, no spaces are + allowed in the partition definition, including mtd id's and partition + names. + + Examples: + + 1 flash resource (mtd-id "sa1100"), with 1 single writable partition: + mtdparts=sa1100:- + + Same flash, but 2 named partitions, the first one being read-only: + mtdparts=sa1100:256k(ARMboot)ro,-(root) + + If unsure, say 'N'. + ARM Firmware Suite flash layout / partition parsing CONFIG_MTD_AFS_PARTS The ARM Firmware Suite allows the user to divide flash devices into @@ -13036,6 +13293,10 @@ If you wish to support CFI devices on a physical bus which is 32 bits wide, say 'Y'. +CONFIG_MTD_CFI_B8 + If you wish to support CFI devices on a physical bus which is + 64 bits wide, say 'Y'. + Support 1-chip flash interleave CONFIG_MTD_CFI_I1 If your flash chips are not interleaved - i.e. you only have one @@ -13051,6 +13312,10 @@ If your flash chips are interleaved in fours - i.e. you have four flash chips addressed by each bus cycle, then say 'Y'. +CONFIG_MTD_CFI_I8 + If your flash chips are interleaved in eights - i.e. you have eight + flash chips addressed by each bus cycle, then say 'Y'. + # Choice: mtd_data_swap Flash cmd/query data swapping CONFIG_MTD_CFI_NOSWAP @@ -13115,6 +13380,11 @@ . The module will be called amd_flash.o +CONFIG_MTD_CFI_STAA + The Common Flash Interface defines a number of different command + sets which a CFI-compliant chip may claim to implement. This code + provides support for one of those command sets. + Support for RAM chips in bus mapping CONFIG_MTD_RAM This option enables basic support for RAM chips accessed through @@ -13535,6 +13805,18 @@ . The module will be called slram.o +DEC MS02-NV NVRAM module support +CONFIG_MTD_MS02NV + This is a MTD driver for the DEC's MS02-NV (54-20948-01) battery + backed-up NVRAM module. The module was originally meant as an NFS + accelerator. Say Y here if you have a DECstation 5000/2x0 or a + DECsystem 5900 equipped with such a module. + + If you want to compile this driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module will + be called ms02-nv.o. + Debugging RAM test driver CONFIG_MTD_MTDRAM This enables a test MTD device driver which uses vmalloc() to @@ -13919,11 +14201,12 @@ The module will be called powermate.o. If you want to compile it as a module, say M here and read . -Aiptek 6000U/8000U tablet support +Aiptek HyperPen tablet support CONFIG_USB_AIPTEK - Say Y here if you want to use the USB version of the Aiptek 6000U/8000U - tablet. Make sure to say Y to "Event interface support" - (CONFIG_INPUT_EVDEV) as well. + Say Y here if you want to use the USB version of the Aiptek HyperPen + Digital Tablet (models 4000U, 5000U, 6000U, 8000U, and 12000U.) + Make sure to say Y to "Mouse support" (CONFIG_INPUT_MOUSEDEV) and/or + "Event interface support" (CONFIG_INPUT_EVDEV) as well. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -14620,6 +14903,24 @@ The module will be called catc.o. If you want to compile it as a module, say M here and read . +USB ASIX AX88172 based ethernet device support +CONFIG_USB_AX8817X + Say Y if you want to use one of the following 10/100 USB2 Ethernet + devices based on the ASIX AX88172 chip. Supported devices are: + Linksys USB200M + Netgear FA120 + D-Link DUB-E100 + Hawking UF200 + + This driver makes the adapter appear as a normal Ethernet interface, + typically on eth0, if it is the only ethernet device, or perhaps on + eth1, if you have a PCI or ISA ethernet card installed. + + 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 ax8817x.o. If you want to compile it as a + module, say M here and read . + USB Kodak DC-2xx Camera support CONFIG_USB_DC2XX Say Y here if you want to connect this type of still camera to your @@ -14903,6 +15204,17 @@ The module will be called dsbr100.o. If you want to compile it as a module, say M here and read . +Alcatel Speedtouch USB support +CONFIG_USB_SPEEDTOUCH + Say Y here if you have an Alcatel SpeedTouch USB or SpeedTouch 330 + modem. In order to use your modem you will need to install some user + space tools, see for details. + + 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 speedtch.o. If you want to compile it as + a module, say M here and read . + Always do synchronous disk IO for UBD CONFIG_BLK_DEV_UBD_SYNC The User-Mode Linux port includes a driver called UBD which will let @@ -15803,6 +16115,30 @@ If unsure, say N. +Allow direct I/O on files in NFS +CONFIG_NFS_DIRECTIO + There are important applications whose performance or correctness + depends on uncached access to file data. Database clusters (multiple + copies of the same instance running on separate hosts) implement their + own cache coherency protocol that subsumes the NFS cache protocols. + Applications that process datasets considerably larger than the client's + memory do not always benefit from a local cache. A streaming video + server, for instance, has no need to cache the contents of a file. + + This option enables applications to perform direct I/O on files in NFS + file systems using the O_DIRECT open() flag. When O_DIRECT is set for + files, their data is not cached in the system's page cache. Direct + read and write operations are aligned to block boundaries. Data is + moved to and from user-level application buffers directly. + + Unless your program is designed to use O_DIRECT properly, you are much + better off allowing the NFS client to manage caching for you. Misusing + O_DIRECT can cause poor server performance or network storms. This + kernel build option defaults OFF to avoid exposing system administrators + unwittingly to a potentially hazardous feature. + + If unsure, say N. + Root file system on NFS CONFIG_ROOT_NFS If you want your Linux box to mount its whole root file system (the @@ -15959,7 +16295,7 @@ say M here and read . If unsure, say N. -Apple Macintosh file system support +Apple HFS file system support CONFIG_HFS_FS If you say Y here, you will be able to mount Macintosh-formatted floppy disks and hard drive partitions with full read-write access. @@ -15972,6 +16308,21 @@ compile it as a module, say M here and read . +Apple HFS+ (Extended HFS) file system support +CONFIG_HFSPLUS_FS + If you say Y here, you will be able to mount extended format + Macintosh-formatted hard drive partitions with full read-write access. + + This file system is often called HFS+ and was introduced with + MacOS 8. It includes all Mac specific filesystem data such as + data forks and creator codes, but it also has several UNIX + style features such as file ownership and permissions. + + This file system 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 hfsplus.o. If you want to compile it + as a module, say M here and read Documentation/modules.txt. + ROM file system support CONFIG_ROMFS_FS This is a very small read-only file system mainly intended for @@ -17287,6 +17638,13 @@ If unsure, say N. +Support for serial port described by EFI HCDP table +CONFIG_SERIAL_HCDP + If you wish to make the serial console port described by the EFI + HCDP table available for use as serial console or general + purpose port, say Y here. See + . + Support for PowerMac serial ports CONFIG_MAC_SERIAL If you have Macintosh style serial ports (8 pin mini-DIN), say Y @@ -17870,6 +18228,16 @@ . The module will be called i2c-adap-ite.o. +SiByte I2C Algorithm +CONFIG_I2C_ALGO_SIBYTE + Supports the SiByte SOC on-chip I2C interfaces (2 channels). + +MAX1617 Temperature Sensor +CONFIG_I2C_MAX1617 + This builds a simple polling driver for the Maxim 1617 temperature + sensor. Currently the device is only supported on a SiByte I2C + adapter, and the driver prints status updates to the system log. + I2C device interface CONFIG_I2C_CHARDEV Say Y here to use i2c-* device files, usually found in the /dev @@ -18602,6 +18970,25 @@ The ACPI Sourceforge project may also be of interest: +ACPI Processor Enumeration for HT +CONFIG_ACPI_HT_ONLY + ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT) + and physical processors. It is designed to obsolete several older + specifications, including the MultiProcessor Specification (MPS), + which supported only physical processors. + + CONFIG_ACPI_HT_ONLY includes just the minimal ACPI boot-time code + necessary to enumerate logical processors and enable HT. + + CONFIG_ACPI includes this code, plus IO APIC enumeration, + and the hooks to run the ACPI AML interpreter for run-time events. + + When CONFIG_ACPI is selected, the command-line option "acpi=ht" + is available to run just the ACPI boot-time code -- just as if + only CONFIG_ACPI_HT_ONLY were selected. + + Note that "acpi=off" can be used to disable all ACPI code in the kernel. + Enable ACPI 2.0 with errata 1.3 CONFIG_ACPI20 Enable support for the 2.0 version of the ACPI interpreter. See the @@ -18618,6 +19005,14 @@ of verbosity. Saying Y enables these statements. This will increase your kernel size by around 50K. +ACPI Relaxed AML Checking +CONFIG_ACPI_RELAXED_AML + If you say `Y' here, the ACPI interpreter will relax its checking + for valid AML and will ignore some AML mistakes, such as off-by-one + errors in region sizes. Some laptops may require this option. In + particular, many Toshiba laptops require this for correct operation + of the AC module. + ACPI Bus Manager CONFIG_ACPI_BUSMGR The ACPI Bus Manager enumerates devices in the ACPI namespace, and @@ -18643,6 +19038,20 @@ down the system. Until then, you can cat it, and see output when a button is pressed. +CONFIG_ACPI_BATTERY + This driver adds support for battery information through + /proc/acpi/battery. If you have a mobile system with a battery, + say Y. + +CONFIG_ACPI_FAN + This driver adds support for ACPI fan devices, allowing user-mode + applications to perform basic fan control (on, off, status). + +CONFIG_ACPI_PROCESSOR + This driver installs ACPI as the idle handler for Linux, and uses + ACPI C2 and C3 processor states to save power, on systems that + support it. + ACPI AC Adapter CONFIG_ACPI_AC This driver adds support for the AC Adapter object, which indicates @@ -18665,6 +19074,53 @@ This driver handles overheating conditions on laptops. It is HIGHLY recommended, as your laptop CPU may be damaged without it. +ACPI ASUS/Medion Laptop Extras +CONFIG_ACPI_ASUS + This driver provides support for extra features of ACPI-compatible + ASUS laptops. As some of Medion laptops are made by ASUS, it may also + support some Medion laptops (such as 9675 for example). It makes all + the extra buttons generate standard ACPI events that go through + /proc/acpi/events, and (on some models) adds support for changing the + display brightness and output, switching the LCD backlight on and off, + and most importantly, allows you to blink those fancy LEDs intended + for reporting mail and wireless status. + + All settings are changed via /proc/acpi/asus directory entries. Owner + and group for these entries can be set with asus_uid and asus_gid + parameters. + + More information and a userspace daemon for handling the extra buttons + at . + + If you have an ACPI-compatible ASUS laptop, say Y or M here. This + driver is still under development, so if your laptop is unsupported or + something works not quite as expected, please use the mailing list + available on the above page (acpi4asus-user@lists.sourceforge.net) + +ACPI Toshiba Laptop Extras +CONFIG_ACPI_TOSHIBA + This driver adds support for access to certain system settings + on "legacy free" Toshiba laptops. These laptops can be recognized by + their lack of a BIOS setup menu and APM support. + + On these machines, all system configuration is handled through the + ACPI. This driver is required for access to controls not covered + by the general ACPI drivers, such as LCD brightness, video output, + etc. + + This driver differs from the non-ACPI Toshiba laptop driver (located + under "Processor type and features") in several aspects. + Configuration is accessed by reading and writing text files in the + /proc tree instead of by program interface to /dev. Furthermore, no + power management functions are exposed, as those are handled by the + general ACPI drivers. + + More information about this driver is available at + . + + If you have a legacy free Toshiba laptop (such as the Libretto L1 + series), say Y. + Advanced Power Management BIOS support CONFIG_APM APM is a BIOS specification for saving power using several different @@ -19171,6 +19627,17 @@ The module is called rtc.o. If you want to compile it as a module, say M here and read . +Generic MIPS RTC Support +CONFIG_MIPS_RTC + + If your machine is a MIPS machine, this option provides a simple, + generic RTC driver for /dev/rtc device. It only implements two IOCTL + operations of the standard PC RTC driver: RTC_RD_TIME and RTC_SET_TIME. + It is sufficient to run hwclock program. + + You should say Y here if there is no machine-specific RTC driver for your + MIPS machine but you do want a simple RTC driver for your RTC device. + Generic Real Time Clock Support CONFIG_GEN_RTC If you say Y here and create a character special file /dev/rtc with @@ -19921,6 +20388,14 @@ See for more information on configuring this card. +Support for Crystal CS4297a on SiByte syncser +CONFIG_SOUND_BCM_CS4297A + The BCM91250A has a Crystal CS4297a on synchronous serial port B (in + addition to the DB-9 serial port). Say Y or M here to enable the + sound chip instead of the UART. Also note that CONFIG_KGDB should + not be enabled at the same time, since it also attempts to use this + UART port. + Support for Yamaha OPL3-SA2 and SA3 based PnP cards CONFIG_SOUND_OPL3SA2 Say Y or M if you have a card based on one of these Yamaha sound @@ -20523,6 +20998,23 @@ compatibility. Since all software available for Linux/MIPS is currently 32-bit you should say Y here. +Kernel support for o32 binaries +CONFIG_MIPS32_O32 + Select this option if you want to run o32 binaries. These are pure + 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of + existing binaries are in this format. + + If unsure, say Y. + +Kernel support for n32 binaries +CONFIG_MIPS32_N32 + Select this option if you want to run n32 binaries. These are + 64-bit binaries using 32-bit quantities for addressing and certain + data that would normally be 64-bit. They are used in special + cases. + + If unsure, say N. + Build fp exception handler module CONFIG_MIPS_FPE_MODULE Build the floating point exception handler module. This option is @@ -20591,19 +21083,12 @@ Palm PCs from Philips (INCOMPLETE). Model-300/301/302/319 -Low-level debugging -CONFIG_LL_DEBUG - Enable low-level debugging assertion macros in the kernel code. - Currently used only by the time services code in the MIPS port. - Don't turn this on unless you know what you are doing. - -Remote GDB kernel debugging -CONFIG_REMOTE_DEBUG - If you say Y here, it will be possible to remotely debug the MIPS - kernel using gdb. This enlarges your kernel image disk size by - several megabytes and requires a machine with more than 16 MB, - better 32 MB RAM to avoid excessive linking time. This is only - useful for kernel hackers. If unsure, say N. +Enable run-time debugging +CONFIG_RUNTIME_DEBUG + If you say Y here, some debugging macros will do run-time checking. + If you say N here, those macros will mostly turn to no-ops. Currently + supported by MIPS arch. See include/asm-mips/debug.h for debuging macros. + If unsure, say N. Run uncached CONFIG_MIPS_UNCACHED @@ -20673,6 +21158,17 @@ feature. See and for more information. +PPP filtering for ISDN +CONFIG_IPPP_FILTER + Say Y here if you want to be able to filter the packets passing over + IPPP interfaces. This allows you to control which packets count as + activity (i.e. which packets will reset the idle timer or bring up + a demand-dialled link) and which packets are to be dropped entirely. + You need to say Y here if you wish to use the pass-filter and + active-filter options to ipppd. + + If unsure, say N. + Support generic MP (RFC 1717) CONFIG_ISDN_MPP With synchronous PPP enabled, it is possible to increase throughput @@ -21521,6 +22017,7 @@ SCO Module (SCO links) RFCOMM Module (RFCOMM protocol) BNEP Module (BNEP protocol) + CMTP Module (CMTP protocol) Say Y here to enable Linux Bluetooth support and to build BlueZ Core layer. @@ -21575,6 +22072,15 @@ Say Y here to compile BNEP support into the kernel or say M to compile it as module (bnep.o). +CMTP protocol support +CONFIG_BLUEZ_CMTP + CMTP (CAPI Message Transport Protocol) is a transport layer + for CAPI messages. CMTP is required for the Bluetooth Common + ISDN Access Profile. + + Say Y here to compile CMTP support into the kernel or say M to + compile it as module (cmtp.o). + BNEP multicast filter support CONFIG_BLUEZ_BNEP_MC_FILTER This option enables the multicast filter support for BNEP. @@ -21651,6 +22157,16 @@ Say Y here to compile support for virtual HCI devices into the kernel or say M to compile it as module (hci_vhci.o). +HCI BFUSB device driver +CONFIG_BLUEZ_HCIBFUSB + Bluetooth HCI BlueFRITZ! USB driver. + This driver provides support for Bluetooth USB devices with AVM + interface: + AVM BlueFRITZ! USB + + Say Y here to compile support for HCI BFUSB devices into the + kernel or say M to compile it as module (bfusb.o). + HCI DTL1 (PC Card) device driver CONFIG_BLUEZ_HCIDTL1 Bluetooth HCI DTL1 (PC Card) driver. @@ -21711,6 +22227,24 @@ If unsure, say N. +SuperH peripheral clock frequency +CONFIG_SH_PCLK_FREQ + Set this value or add "sh_pclk=" command line option to tell + peripheral clock frequency to kernel, if your system has no RTC. + Otherwise leave it 0, and kernel measures peripheral clock frequency + using TMU and RTC while system startup. + + If unsure, set 0. + +Wakeup UBC on startup +CONFIG_UBC_WAKEUP + Selecting this option will wakeup the User Break Controller (UBC) on + startup. Although the UBC is left in an awake state when the processor + comes up, some boot loaders misbehave by putting the UBC to sleep in a + power saving state, which causes issues with things like ptrace(). + + If unsure, say N. + SuperH DMAC support CONFIG_SH_DMA Selecting this option will provide same API as PC's Direct Memory @@ -23538,6 +24072,12 @@ Check out and for more information. +Philips SAA7114H for SiByte BCM91250A +CONFIG_VIDEO_SWARM_7114H + Say Y or M to build the video4linux driver for the Philips SAA7114H + video decoder on Broadcom SWARM board (BCM91250A). The decoder chip + is on the BCM1250's "E2" 8-bit FIFO port. + CPiA Video For Linux CONFIG_VIDEO_CPIA This is the video4linux driver for cameras based on Vision's CPiA @@ -23811,6 +24351,20 @@ enabled, you'll be able to toggle chpids logically offline and online. Even if you don't understand what this means, you should say "Y". +Process warning machine checks +CONFIG_MACHCHK_WARNING + Select this option if you want the machine check handler on IBM S/390 or + zSeries to process warning machine checks (e.g. on power failures). + If unsure, say "Y". + +Use chscs for Common I/O +CONFIG_CHSC + Select this option if you want the s390 common I/O layer to use information + obtained by channel subsystem calls. This will enable Linux to process link + failures and resource accessibility events. Moreover, if you have procfs + enabled, you'll be able to toggle chpids logically offline and online. Even + if you don't understand what this means, you should say "Y". + Kernel support for 31 bit ELF binaries CONFIG_S390_SUPPORT Select this option if you want to enable your system kernel to @@ -26078,6 +26632,9 @@ Select SolutionEngine if configuring for a Hitachi SH7709 or SH7750/7750S evaluation board. + Select SHMobileSolutionEngine if configuring for SH-Mobile Solution + Engine. + Select Overdrive if configuring for a ST407750 Overdrive board. More information at . @@ -26131,6 +26688,11 @@ Select 7751 SolutionEngine if configuring for a Hitachi SH7751 evaluation board. +SHMobileSolutionEngine +CONFIG_SH_MOBILE_SOLUTION_ENGINE + Select SHMobileSolutionEngine if configuring for SH-Mobile Solution + Engine. + Overdrive CONFIG_SH_OVERDRIVE Select Overdrive if configuring for a ST407750 Overdrive board. @@ -26178,6 +26740,14 @@ . There is a Dreamcast project is at . +SH-2000 +CONFIG_SH_SH2000 + SH-2000 is a single-board computer based around SH7709A chip + intended for embedded applications. + It has an Ethernet interface (CS8900A), direct connected + Compact Flash socket, three serial ports and PC-104 bus. + More information at . + BareCPU CONFIG_SH_UNKNOWN "Bare CPU" aka "unknown" means an SH-based system which is not one @@ -26207,6 +26777,12 @@ Select SH7751 if you have a SH7751 Select ST40STB1 if you have a ST40STB1 + Select ST40RA/ST40STB1 if you have a ST40RA + (previously known as ST40STB1). + + Select ST40GX1 if you have an ST40GX1. + + Select SH7300 if you have a HD6417300 CPU. SH7708 CONFIG_CPU_SUBTYPE_SH7708 @@ -26221,6 +26797,35 @@ CONFIG_CPU_SUBTYPE_SH7750 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. +SH7751 +CONFIG_CPU_SUBTYPE_SH7751 + Select SH7750 if you have a 166 Mhz SH-4 HD6417751 CPU. + +ST40RA/ST40STB1 +CONFIG_CPU_SUBTYPE_ST40STB1 + Select ST40RA/ST40STB1 if you have a ST40RA. This chip was + previously called the ST40STB1. Early versions were also + erronously labelled ST40AR166. + +ST40GX1 +CONFIG_CPU_SUBTYPE_ST40GX1 + Select ST40GX1 if you have a ST40GX1 CPU. + +SH7300 +CONFIG_CPU_SUBTYPE_SH7300 + Select SH7300 if you have a HD6417300 CPU. + +Memory on LMI +CONFIG_ST40_LMI_MEMORY + Currently all ST40 CPUs have two external buses the + 'Local Memory Interface' (LMI) which supports SDRAM and + DDR SDRAM, and the 'Enhanced flash Memory Interface' (EMI), + which supports SDRAM, Flash, peripherials and MPX. Linux + can support memory on either of these buses, it is simply + necessary to specify its base address. This option is simply + a shortcut method of specifying that RAM starts from the + bottom of the LMI. + Physical memory start address CONFIG_MEMORY_START Computers built with Hitachi SuperH processors always @@ -26591,6 +27196,140 @@ If compiled as a module, it will be called scx200_docflash.o. +BIOS flash chip on AMD76x southbridge +CONFIG_MTD_AMD76XROM + Support for treating the BIOS flash chip on AMD76x motherboards + as an MTD device - with this you can reprogram your BIOS. + + BE VERY CAREFUL. + + If compiled as a module, it will be called amd76xrom.o. + +BIOS flash chip on Intel Hub Controller 2 +CONFIG_MTD_ICH2ROM + Support for treating the BIOS flash chip on ICH2 motherboards + as an MTD device - with this you can reprogram your BIOS. + + BE VERY CAREFUL. + + If compiled as a module, it will be called ich2rom.o. + +BIOS flash chip on Intel SCB2 boards +CONFIG_MTD_SCB2_FLASH + Support for treating the BIOS flash chip on Intel SCB2 boards + as an MTD device - with this you can reprogram your BIOS. + + BE VERY CAREFUL. + + If compiled as a module, it will be called scb2_flash.o. + +Flash chips on Tsunami TIG bus +CONFIG_MTD_TSUNAMI + Support for the flash chip on Tsunami TIG bus. + + If compiled as a module, it will be called tsunami_flash.o. + +Flash chips on LASAT board +CONFIG_MTD_LASAT + Support for the flash chips on the Lasat 100 and 200 boards. + + If compiled as a module, it will be called lasat.o. + +CFI flash device on SnapGear/SecureEdge +CONFIG_MTD_NETtel + Support for flash chips on NETtel/SecureEdge/SnapGear boards. + + If compiled as a module, it will be called nettel.o. + +CFI Flash device mapped on DIL/Net PC +CONFIG_MTD_DILNETPC + MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP". + For details, see + and + + If compiled as a module, it will be called dilnetpc.o. + +Size of DIL/Net PC flash boot partition +CONFIG_MTD_DILNETPC_BOOTSIZE + The amount of space taken up by the kernel or Etherboot + on the DIL/Net PC flash chips. + +CFI Flash device mapped on Epxa10db +CONFIG_MTD_EPXA10DB + This enables support for the flash devices on the Altera + Excalibur XA10 Development Board. If you are building a kernel + for on of these boards then you should say 'Y' otherwise say 'N'. + + If compiled as a module, it will be called epxa10db-flash.o. + +CFI Flash device mapped on the FortuNet board +CONFIG_MTD_FORTUNET + This enables access to the Flash on the FortuNet board. If you + have such a board, say 'Y'. + + If compiled as a module, it will be called fortunet.o. + +NV-RAM mapping AUTCPU12 board +CONFIG_MTD_AUTCPU12 + This enables access to the NV-RAM on autronix autcpu12 board. + If you have such a board, say 'Y'. + + If compiled as a module, it will be called autcpu12-nvram.o. + +CFI Flash device mapped on EDB7312 +CONFIG_MTD_EDB7312 + This enables access to the CFI Flash on the Cogent EDB7312 board. + If you have such a board, say 'Y' here. + + If compiled as a module, it will be called edb7312.o. + +JEDEC Flash device mapped on impA7 +CONFIG_MTD_IMPA7 + This enables access to the NOR Flash on the impA7 board of + implementa GmbH. If you have such a board, say 'Y' here. + + If compiled as a module, it will be called impa7.o. + +JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame +CONFIG_MTD_CEIVA + This enables access to the flash chips on the Ceiva/Polaroid + PhotoMax Digital Picture Frame. + If you have such a device, say 'Y'. + + If compiled as a module, it will be called ceiva.o. + +System flash on MBX860 board +CONFIG_MTD_MBX860 + This enables access routines for the flash chips on the Motorola + MBX860 board. If you have one of these boards and would like + to use the flash chips on it, say 'Y'. + + If compiled as a module, it will be called mbx860.o. + +PCI MTD driver +CONFIG_MTD_PCI + Mapping for accessing flash devices on add-in cards like the Intel XScale + IQ80310 card, and the Intel EBSA285 card in blank ROM programming mode + (please see the manual for the link settings). + + If compiled as a module, it will be called pci.o. + + If you are not sure, say N. + +PCMCIA MTD driver +CONFIG_MTD_PCMCIA + Map driver for accessing PCMCIA linear flash memory cards. These + cards are usually around 4-16MiB in size. This does not include + Compact Flash cards which are treated as IDE devices. + + If compiled as a module, it will be called pcmciamtd.o. + +Generic uClinux RAM/ROM filesystem support +CONFIG_MTD_UCLINUX + Map driver to support image based filesystems for uClinux. + + If compiled as a module, it will be called uclinux.o. + NatSemi SCx200 I2C using GPIO pins CONFIG_SCx200_GPIO Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. @@ -26649,6 +27388,105 @@ CONFIG_IPMI_WATCHDOG This enables the IPMI watchdog timer. +CRC32 functions +CONFIG_CRC32 + This option is provided for the case where no in-kernel-tree + modules require CRC32 functions, but a module built outside the + kernel tree does. Such modules that use library CRC32 functions + require that you say M or Y here. + +CONFIG_CRYPTO + This option provides the core Cryptographic API. + +CONFIG_CRYPTO_HMAC + HMAC: Keyed-Hashing for Message Authentication (RFC2104). + This is required for IPSec. + +CONFIG_CRYPTO_NULL + These are 'Null' algorithms, used by IPsec, which do nothing. + +CONFIG_CRYPTO_MD4 + MD4 message digest algorithm (RFC1320). + +CONFIG_CRYPTO_MD5 + MD5 message digest algorithm (RFC1321). + +CONFIG_CRYPTO_SHA1 + SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). + +CONFIG_CRYPTO_SHA256 + SHA256 secure hash standard (DFIPS 180-2). + + This version of SHA implements a 256 bit hash with 128 bits of + security against collision attacks. + +CONFIG_CRYPTO_SHA512 + SHA512 secure hash standard (DFIPS 180-2). + + This version of SHA implements a 512 bit hash with 256 bits of + security against collision attacks. + + This code also includes SHA-384, a 384 bit hash with 192 bits + of security against collision attacks. + +CONFIG_CRYPTO_DES + DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). + +CONFIG_CRYPTO_BLOWFISH + Blowfish cipher algorithm, by Bruce Schneier. + + This is a variable key length cipher which can use keys from 32 + bits to 448 bits in length. It's fast, simple and specifically + designed for use on "large microprocessors". + + See also . + +CONFIG_CRYPTO_TWOFISH + Twofish cipher algorithm. + + Twofish was submitted as an AES (Advanced Encryption Standard) + candidate cipher by researchers at CounterPane Systems. It is a + 16 round block cipher supporting key sizes of 128, 192, and 256 + bits. + + See also: + http://www.counterpane.com/twofish.html + +CONFIG_CRYPTO_SERPENT + Serpent cipher algorithm, by Anderson, Biham & Knudsen. + + Keys are allowed to be from 0 to 256 bits in length, in steps + of 8 bits. + + See also: + http://www.cl.cam.ac.uk/~rja14/serpent.html + +CONFIG_CRYPTO_AES + AES cipher algorithms (FIPS-197). AES uses the Rijndael + algorithm. + + Rijndael appears to be consistently a very good performer in + both hardware and software across a wide range of computing + environments regardless of its use in feedback or non-feedback + modes. Its key setup time is excellent, and its key agility is + good. Rijndael's very low memory requirements make it very well + suited for restricted-space environments, in which it also + demonstrates excellent performance. Rijndael's operations are + among the easiest to defend against power and timing attacks. + + The AES specifies three key sizes: 128, 192 and 256 bits + + See http://csrc.nist.gov/encryption/aes/ for more information. + +CONFIG_CRYPTO_DEFLATE + This is the Deflate algorithm (RFC1951), specified for use in + IPSec with the IPCOMP protocol (RFC3173, RFC2394). + + You will most probably want this if using IPSec. + +CONFIG_CRYPTO_TEST + Quick & dirty crypto test module. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff -urN linux-2.4.21/Documentation/arm/SA1100/CERF linux-2.4.22/Documentation/arm/SA1100/CERF --- linux-2.4.21/Documentation/arm/SA1100/CERF 2000-08-13 09:58:24.000000000 -0700 +++ linux-2.4.22/Documentation/arm/SA1100/CERF 2003-08-25 04:44:39.000000000 -0700 @@ -1,23 +1,28 @@ -The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board that measures -approximately 2" square. It includes an Ethernet controller, an RS232-compatible serial port, a -USB function port, and one CompactFlash+ slot on the back. Pictures can be found at the +The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board +that measures approximately 2" square. It includes an Ethernet +controller, an RS232-compatible serial port, a USB function port, and +one CompactFlash+ slot on the back. Pictures can be found at the Intrinsyc website, http://www.intrinsyc.com. -This document describes the support in the Linux kernel for the Intrinsyc CerfBoard as of -version 2.4.0-test4-np1. +This document describes the support in the Linux kernel for the +Intrinsyc CerfBoard as of version 2.4.0-test4-np1. Supported in this version: - - CompactFlash+ slot (select PCMCIA in General Setup and any options that may be required) - - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in Network Devices) + - CompactFlash+ slot (select PCMCIA in General Setup and any options + that may be required) + - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in + Network Devices) - Serial ports with a serial console (hardcoded to 38400 8N1) Not supported in this version (yet): - LCD driver/touchscreen interface - - UDC (a driver exists right now, but is unstable and slow and only works with the Linux USB) + - UDC (a driver exists right now, but is unstable and slow and only + works with the Linux USB) -In order to get this kernel onto your Cerf, you need a server that runs both BOOTP and -TFTP. Detailed instructions should have come with your evaluation kit on how to use the -bootloader. This series of commands will suffice: +In order to get this kernel onto your Cerf, you need a server that runs +both BOOTP and TFTP. Detailed instructions should have come with your +evaluation kit on how to use the bootloader. This series of commands +will suffice: make cerf_config make xconfig @@ -25,10 +30,9 @@ make zImage cp arch/arm/boot/zImage -The default config uses a 4MB RAM disk located at 0xc0500000 as root. Setting the board to -mount root from a NFS partition works, too. +The default config uses a 4MB RAM disk located at 0xc0500000 as root. +Setting the board to mount root from a NFS partition works, too. I-Gene Leong, Intrinsyc Software Inc. ileong@intrinsyc.com - diff -urN linux-2.4.21/Documentation/cciss.txt linux-2.4.22/Documentation/cciss.txt --- linux-2.4.21/Documentation/cciss.txt 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/cciss.txt 2003-08-25 04:44:39.000000000 -0700 @@ -12,6 +12,7 @@ * SA 641 * SA 642 * SA 6400 + * SA 6400 U320 Expansion Module If nodes are not already created in the /dev/cciss directory diff -urN linux-2.4.21/Documentation/crypto/api-intro.txt linux-2.4.22/Documentation/crypto/api-intro.txt --- linux-2.4.21/Documentation/crypto/api-intro.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/Documentation/crypto/api-intro.txt 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,221 @@ + + Scatterlist Cryptographic API + +INTRODUCTION + +The Scatterlist Crypto API takes page vectors (scatterlists) as +arguments, and works directly on pages. In some cases (e.g. ECB +mode ciphers), this will allow for pages to be encrypted in-place +with no copying. + +One of the initial goals of this design was to readily support IPsec, +so that processing can be applied to paged skb's without the need +for linearization. + + +DETAILS + +At the lowest level are algorithms, which register dynamically with the +API. + +'Transforms' are user-instantiated objects, which maintain state, handle all +of the implementation logic (e.g. manipulating page vectors), provide an +abstraction to the underlying algorithms, and handle common logical +operations (e.g. cipher modes, HMAC for digests). However, at the user +level they are very simple. + +Conceptually, the API layering looks like this: + + [transform api] (user interface) + [transform ops] (per-type logic glue e.g. cipher.c, digest.c) + [algorithm api] (for registering algorithms) + +The idea is to make the user interface and algorithm registration API +very simple, while hiding the core logic from both. Many good ideas +from existing APIs such as Cryptoapi and Nettle have been adapted for this. + +The API currently supports three types of transforms: Ciphers, Digests and +Compressors. The compression algorithms especially seem to be performing +very well so far. + +Support for hardware crypto devices via an asynchronous interface is +under development. + +Here's an example of how to use the API: + + #include + + struct scatterlist sg[2]; + char result[128]; + struct crypto_tfm *tfm; + + tfm = crypto_alloc_tfm("md5", 0); + if (tfm == NULL) + fail(); + + /* ... set up the scatterlists ... */ + + crypto_digest_init(tfm); + crypto_digest_update(tfm, &sg, 2); + crypto_digest_final(tfm, result); + + crypto_free_tfm(tfm); + + +Many real examples are available in the regression test module (tcrypt.c). + + +CONFIGURATION NOTES + +As Triple DES is part of the DES module, for those using modular builds, +add the following line to /etc/modules.conf: + + alias des3_ede des + +The Null algorithms reside in the crypto_null module, so these lines +should also be added: + + alias cipher_null crypto_null + alias digest_null crypto_null + alias compress_null crypto_null + +The SHA384 algorithm shares code within the SHA512 module, so you'll +also need: + alias sha384 sha512 + + +DEVELOPER NOTES + +Transforms may only be allocated in user context, and cryptographic +methods may only be called from softirq and user contexts. + +When using the API for ciphers, performance will be optimal if each +scatterlist contains data which is a multiple of the cipher's block +size (typically 8 bytes). This prevents having to do any copying +across non-aligned page fragment boundaries. + + +ADDING NEW ALGORITHMS + +When submitting a new algorithm for inclusion, a mandatory requirement +is that at least a few test vectors from known sources (preferably +standards) be included. + +Converting existing well known code is preferred, as it is more likely +to have been reviewed and widely tested. If submitting code from LGPL +sources, please consider changing the license to GPL (see section 3 of +the LGPL). + +Algorithms submitted must also be generally patent-free (e.g. IDEA +will not be included in the mainline until around 2011), and be based +on a recognized standard and/or have been subjected to appropriate +peer review. + +Also check for any RFCs which may relate to the use of specific algorithms, +as well as general application notes such as RFC2451 ("The ESP CBC-Mode +Cipher Algorithms"). + +It's a good idea to avoid using lots of macros and use inlined functions +instead, as gcc does a good job with inlining, while excessive use of +macros can cause compilation problems on some platforms. + +Also check the TODO list at the web site listed below to see what people +might already be working on. + + +BUGS + +Send bug reports to: +James Morris +Cc: David S. Miller + + +FURTHER INFORMATION + +For further patches and various updates, including the current TODO +list, see: +http://samba.org/~jamesm/crypto/ + + +AUTHORS + +James Morris +David S. Miller + + +CREDITS + +The following people provided invaluable feedback during the development +of the API: + + Alexey Kuznetzov + Rusty Russell + Herbert Valerio Riedel + Jeff Garzik + Michael Richardson + Andrew Morton + Ingo Oeser + Christoph Hellwig + +Portions of this API were derived from the following projects: + + Kerneli Cryptoapi (http://www.kerneli.org/) + Alexander Kjeldaas + Herbert Valerio Riedel + Kyle McMartin + Jean-Luc Cooke + David Bryson + Clemens Fruhwirth + Tobias Ringstrom + Harald Welte + +and; + + Nettle (http://www.lysator.liu.se/~nisse/nettle/) + Niels Möller + +Original developers of the crypto algorithms: + + Dana L. How (DES) + Andrew Tridgell and Steve French (MD4) + Colin Plumb (MD5) + Steve Reid (SHA1) + Jean-Luc Cooke (SHA256, SHA384, SHA512) + Kazunori Miyazawa / USAGI (HMAC) + Matthew Skala (Twofish) + Dag Arne Osvik (Serpent) + Brian Gladman (AES) + + +SHA1 algorithm contributors: + Jean-Francois Dive + +DES algorithm contributors: + Raimar Falke + Gisle Sælensminde + Niels Möller + +Blowfish algorithm contributors: + Herbert Valerio Riedel + Kyle McMartin + +Twofish algorithm contributors: + Werner Koch + Marc Mutz + +SHA256/384/512 algorithm contributors: + Andrew McDonald + Kyle McMartin + Herbert Valerio Riedel + +AES algorithm contributors: + Alexander Kjeldaas + Herbert Valerio Riedel + Kyle McMartin + Adam J. Richter + +Generic scatterwalk code by Adam J. Richter + +Please send any credits updates or corrections to: +James Morris + diff -urN linux-2.4.21/Documentation/crypto/descore-readme.txt linux-2.4.22/Documentation/crypto/descore-readme.txt --- linux-2.4.21/Documentation/crypto/descore-readme.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/Documentation/crypto/descore-readme.txt 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,352 @@ +Below is the orginal README file from the descore.shar package. +------------------------------------------------------------------------------ + +des - fast & portable DES encryption & decryption. +Copyright (C) 1992 Dana L. How + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Library 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 Library General Public License for more details. + +You should have received a copy of the GNU Library General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Author's address: how@isl.stanford.edu + +$Id: README,v 1.15 1992/05/20 00:25:32 how E $ + + +==>> To compile after untarring/unsharring, just `make' <<== + + +This package was designed with the following goals: +1. Highest possible encryption/decryption PERFORMANCE. +2. PORTABILITY to any byte-addressable host with a 32bit unsigned C type +3. Plug-compatible replacement for KERBEROS's low-level routines. + +This second release includes a number of performance enhancements for +register-starved machines. My discussions with Richard Outerbridge, +71755.204@compuserve.com, sparked a number of these enhancements. + +To more rapidly understand the code in this package, inspect desSmallFips.i +(created by typing `make') BEFORE you tackle desCode.h. The latter is set +up in a parameterized fashion so it can easily be modified by speed-daemon +hackers in pursuit of that last microsecond. You will find it more +illuminating to inspect one specific implementation, +and then move on to the common abstract skeleton with this one in mind. + + +performance comparison to other available des code which i could +compile on a SPARCStation 1 (cc -O4, gcc -O2): + +this code (byte-order independent): + 30us per encryption (options: 64k tables, no IP/FP) + 33us per encryption (options: 64k tables, FIPS standard bit ordering) + 45us per encryption (options: 2k tables, no IP/FP) + 48us per encryption (options: 2k tables, FIPS standard bit ordering) + 275us to set a new key (uses 1k of key tables) + this has the quickest encryption/decryption routines i've seen. + since i was interested in fast des filters rather than crypt(3) + and password cracking, i haven't really bothered yet to speed up + the key setting routine. also, i have no interest in re-implementing + all the other junk in the mit kerberos des library, so i've just + provided my routines with little stub interfaces so they can be + used as drop-in replacements with mit's code or any of the mit- + compatible packages below. (note that the first two timings above + are highly variable because of cache effects). + +kerberos des replacement from australia (version 1.95): + 53us per encryption (uses 2k of tables) + 96us to set a new key (uses 2.25k of key tables) + so despite the author's inclusion of some of the performance + improvements i had suggested to him, this package's + encryption/decryption is still slower on the sparc and 68000. + more specifically, 19-40% slower on the 68020 and 11-35% slower + on the sparc, depending on the compiler; + in full gory detail (ALT_ECB is a libdes variant): + compiler machine desCore libdes ALT_ECB slower by + gcc 2.1 -O2 Sun 3/110 304 uS 369.5uS 461.8uS 22% + cc -O1 Sun 3/110 336 uS 436.6uS 399.3uS 19% + cc -O2 Sun 3/110 360 uS 532.4uS 505.1uS 40% + cc -O4 Sun 3/110 365 uS 532.3uS 505.3uS 38% + gcc 2.1 -O2 Sun 4/50 48 uS 53.4uS 57.5uS 11% + cc -O2 Sun 4/50 48 uS 64.6uS 64.7uS 35% + cc -O4 Sun 4/50 48 uS 64.7uS 64.9uS 35% + (my time measurements are not as accurate as his). + the comments in my first release of desCore on version 1.92: + 68us per encryption (uses 2k of tables) + 96us to set a new key (uses 2.25k of key tables) + this is a very nice package which implements the most important + of the optimizations which i did in my encryption routines. + it's a bit weak on common low-level optimizations which is why + it's 39%-106% slower. because he was interested in fast crypt(3) and + password-cracking applications, he also used the same ideas to + speed up the key-setting routines with impressive results. + (at some point i may do the same in my package). he also implements + the rest of the mit des library. + (code from eay@psych.psy.uq.oz.au via comp.sources.misc) + +fast crypt(3) package from denmark: + the des routine here is buried inside a loop to do the + crypt function and i didn't feel like ripping it out and measuring + performance. his code takes 26 sparc instructions to compute one + des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37. + he claims to use 280k of tables but the iteration calculation seems + to use only 128k. his tables and code are machine independent. + (code from glad@daimi.aau.dk via alt.sources or comp.sources.misc) + +swedish reimplementation of Kerberos des library + 108us per encryption (uses 34k worth of tables) + 134us to set a new key (uses 32k of key tables to get this speed!) + the tables used seem to be machine-independent; + he seems to have included a lot of special case code + so that, e.g., `long' loads can be used instead of 4 `char' loads + when the machine's architecture allows it. + (code obtained from chalmers.se:pub/des) + +crack 3.3c package from england: + as in crypt above, the des routine is buried in a loop. it's + also very modified for crypt. his iteration code uses 16k + of tables and appears to be slow. + (code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc) + +``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent): + 165us per encryption (uses 6k worth of tables) + 478us to set a new key (uses <1k of key tables) + so despite the comments in this code, it was possible to get + faster code AND smaller tables, as well as making the tables + machine-independent. + (code obtained from prep.ai.mit.edu) + +UC Berkeley code (depends on machine-endedness): + 226us per encryption +10848us to set a new key + table sizes are unclear, but they don't look very small + (code obtained from wuarchive.wustl.edu) + + +motivation and history + +a while ago i wanted some des routines and the routines documented on sun's +man pages either didn't exist or dumped core. i had heard of kerberos, +and knew that it used des, so i figured i'd use its routines. but once +i got it and looked at the code, it really set off a lot of pet peeves - +it was too convoluted, the code had been written without taking +advantage of the regular structure of operations such as IP, E, and FP +(i.e. the author didn't sit down and think before coding), +it was excessively slow, the author had attempted to clarify the code +by adding MORE statements to make the data movement more `consistent' +instead of simplifying his implementation and cutting down on all data +movement (in particular, his use of L1, R1, L2, R2), and it was full of +idiotic `tweaks' for particular machines which failed to deliver significant +speedups but which did obfuscate everything. so i took the test data +from his verification program and rewrote everything else. + +a while later i ran across the great crypt(3) package mentioned above. +the fact that this guy was computing 2 sboxes per table lookup rather +than one (and using a MUCH larger table in the process) emboldened me to +do the same - it was a trivial change from which i had been scared away +by the larger table size. in his case he didn't realize you don't need to keep +the working data in TWO forms, one for easy use of half the sboxes in +indexing, the other for easy use of the other half; instead you can keep +it in the form for the first half and use a simple rotate to get the other +half. this means i have (almost) half the data manipulation and half +the table size. in fairness though he might be encoding something particular +to crypt(3) in his tables - i didn't check. + +i'm glad that i implemented it the way i did, because this C version is +portable (the ifdef's are performance enhancements) and it is faster +than versions hand-written in assembly for the sparc! + + +porting notes + +one thing i did not want to do was write an enormous mess +which depended on endedness and other machine quirks, +and which necessarily produced different code and different lookup tables +for different machines. see the kerberos code for an example +of what i didn't want to do; all their endedness-specific `optimizations' +obfuscate the code and in the end were slower than a simpler machine +independent approach. however, there are always some portability +considerations of some kind, and i have included some options +for varying numbers of register variables. +perhaps some will still regard the result as a mess! + +1) i assume everything is byte addressable, although i don't actually + depend on the byte order, and that bytes are 8 bits. + i assume word pointers can be freely cast to and from char pointers. + note that 99% of C programs make these assumptions. + i always use unsigned char's if the high bit could be set. +2) the typedef `word' means a 32 bit unsigned integral type. + if `unsigned long' is not 32 bits, change the typedef in desCore.h. + i assume sizeof(word) == 4 EVERYWHERE. + +the (worst-case) cost of my NOT doing endedness-specific optimizations +in the data loading and storing code surrounding the key iterations +is less than 12%. also, there is the added benefit that +the input and output work areas do not need to be word-aligned. + + +OPTIONAL performance optimizations + +1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,' + whichever one is closest to the capabilities of your machine. + see the start of desCode.h to see exactly what this selection implies. + note that if you select the wrong one, the des code will still work; + these are just performance tweaks. +2) for those with functional `asm' keywords: you should change the + ROR and ROL macros to use machine rotate instructions if you have them. + this will save 2 instructions and a temporary per use, + or about 32 to 40 instructions per en/decryption. + note that gcc is smart enough to translate the ROL/R macros into + machine rotates! + +these optimizations are all rather persnickety, yet with them you should +be able to get performance equal to assembly-coding, except that: +1) with the lack of a bit rotate operator in C, rotates have to be synthesized + from shifts. so access to `asm' will speed things up if your machine + has rotates, as explained above in (3) (not necessary if you use gcc). +2) if your machine has less than 12 32-bit registers i doubt your compiler will + generate good code. + `i386' tries to configure the code for a 386 by only declaring 3 registers + (it appears that gcc can use ebx, esi and edi to hold register variables). + however, if you like assembly coding, the 386 does have 7 32-bit registers, + and if you use ALL of them, use `scaled by 8' address modes with displacement + and other tricks, you can get reasonable routines for DesQuickCore... with + about 250 instructions apiece. For DesSmall... it will help to rearrange + des_keymap, i.e., now the sbox # is the high part of the index and + the 6 bits of data is the low part; it helps to exchange these. + since i have no way to conveniently test it i have not provided my + shoehorned 386 version. note that with this release of desCore, gcc is able + to put everything in registers(!), and generate about 370 instructions apiece + for the DesQuickCore... routines! + +coding notes + +the en/decryption routines each use 6 necessary register variables, +with 4 being actively used at once during the inner iterations. +if you don't have 4 register variables get a new machine. +up to 8 more registers are used to hold constants in some configurations. + +i assume that the use of a constant is more expensive than using a register: +a) additionally, i have tried to put the larger constants in registers. + registering priority was by the following: + anything more than 12 bits (bad for RISC and CISC) + greater than 127 in value (can't use movq or byte immediate on CISC) + 9-127 (may not be able to use CISC shift immediate or add/sub quick), + 1-8 were never registered, being the cheapest constants. +b) the compiler may be too stupid to realize table and table+256 should + be assigned to different constant registers and instead repetitively + do the arithmetic, so i assign these to explicit `m' register variables + when possible and helpful. + +i assume that indexing is cheaper or equivalent to auto increment/decrement, +where the index is 7 bits unsigned or smaller. +this assumption is reversed for 68k and vax. + +i assume that addresses can be cheaply formed from two registers, +or from a register and a small constant. +for the 68000, the `two registers and small offset' form is used sparingly. +all index scaling is done explicitly - no hidden shifts by log2(sizeof). + +the code is written so that even a dumb compiler +should never need more than one hidden temporary, +increasing the chance that everything will fit in the registers. +KEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING. +(actually, there are some code fragments now which do require two temps, +but fixing it would either break the structure of the macros or +require declaring another temporary). + + +special efficient data format + +bits are manipulated in this arrangement most of the time (S7 S5 S3 S1): + 003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx +(the x bits are still there, i'm just emphasizing where the S boxes are). +bits are rotated left 4 when computing S6 S4 S2 S0: + 282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx +the rightmost two bits are usually cleared so the lower byte can be used +as an index into an sbox mapping table. the next two x'd bits are set +to various values to access different parts of the tables. + + +how to use the routines + +datatypes: + pointer to 8 byte area of type DesData + used to hold keys and input/output blocks to des. + + pointer to 128 byte area of type DesKeys + used to hold full 768-bit key. + must be long-aligned. + +DesQuickInit() + call this before using any other routine with `Quick' in its name. + it generates the special 64k table these routines need. +DesQuickDone() + frees this table + +DesMethod(m, k) + m points to a 128byte block, k points to an 8 byte des key + which must have odd parity (or -1 is returned) and which must + not be a (semi-)weak key (or -2 is returned). + normally DesMethod() returns 0. + m is filled in from k so that when one of the routines below + is called with m, the routine will act like standard des + en/decryption with the key k. if you use DesMethod, + you supply a standard 56bit key; however, if you fill in + m yourself, you will get a 768bit key - but then it won't + be standard. it's 768bits not 1024 because the least significant + two bits of each byte are not used. note that these two bits + will be set to magic constants which speed up the encryption/decryption + on some machines. and yes, each byte controls + a specific sbox during a specific iteration. + you really shouldn't use the 768bit format directly; i should + provide a routine that converts 128 6-bit bytes (specified in + S-box mapping order or something) into the right format for you. + this would entail some byte concatenation and rotation. + +Des{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s) + performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *). + uses m as a 768bit key as explained above. + the Encrypt|Decrypt choice is obvious. + Fips|Core determines whether a completely standard FIPS initial + and final permutation is done; if not, then the data is loaded + and stored in a nonstandard bit order (FIPS w/o IP/FP). + Fips slows down Quick by 10%, Small by 9%. + Small|Quick determines whether you use the normal routine + or the crazy quick one which gobbles up 64k more of memory. + Small is 50% slower then Quick, but Quick needs 32 times as much + memory. Quick is included for programs that do nothing but DES, + e.g., encryption filters, etc. + + +Getting it to compile on your machine + +there are no machine-dependencies in the code (see porting), +except perhaps the `now()' macro in desTest.c. +ALL generated tables are machine independent. +you should edit the Makefile with the appropriate optimization flags +for your compiler (MAX optimization). + + +Speeding up kerberos (and/or its des library) + +note that i have included a kerberos-compatible interface in desUtil.c +through the functions des_key_sched() and des_ecb_encrypt(). +to use these with kerberos or kerberos-compatible code put desCore.a +ahead of the kerberos-compatible library on your linker's command line. +you should not need to #include desCore.h; just include the header +file provided with the kerberos library. + +Other uses + +the macros in desCode.h would be very useful for putting inline des +functions in more complicated encryption routines. diff -urN linux-2.4.21/Documentation/devices.txt linux-2.4.22/Documentation/devices.txt --- linux-2.4.21/Documentation/devices.txt 2001-11-07 14:46:01.000000000 -0800 +++ linux-2.4.22/Documentation/devices.txt 2003-08-25 04:44:39.000000000 -0700 @@ -2531,17 +2531,17 @@ 1 = /dev/dri/card1 Second graphics card ... -227 char IBM 3270 terminal block-mode access +227 char IBM 3270 terminal Unix tty access + 1 = /dev/3270/tty1 First 3270 terminal + 2 = /dev/3270/tty2 Seconds 3270 terminal + ... + +228 char IBM 3270 terminal block-mode access 0 = /dev/3270/tub Controlling interface 1 = /dev/3270/tub1 First 3270 terminal 2 = /dev/3270/tub2 Second 3270 terminal ... -228 char IBM 3270 terminal Unix tty access - 1 = /dev/3270/tty1 First 3270 terminal - 2 = /dev/3270/tty2 Seconds 3270 terminal - ... - 229 char IBM iSeries virtual console 0 = /dev/iseries/vtty0 First console port 1 = /dev/iseries/vtty1 Second console port diff -urN linux-2.4.21/Documentation/fb/vesafb.txt linux-2.4.22/Documentation/fb/vesafb.txt --- linux-2.4.21/Documentation/fb/vesafb.txt 2000-07-28 12:50:51.000000000 -0700 +++ linux-2.4.22/Documentation/fb/vesafb.txt 2003-08-25 04:44:39.000000000 -0700 @@ -139,13 +139,17 @@ redraw scroll by redrawing the affected part of the screen, this is the safe (and slow) default. - vgapal Use the standard vga registers for palette changes. This is the default. pmipal Use the protected mode interface for palette changes. mtrr setup memory type range registers for the vesafb framebuffer. +vram:n remap 'n' MiB of video RAM. If 0 or not specified, remap memory + according to video mode. (2.5.66 patch/idea by Antonino Daplas + reversed to give override possibility (allocate more fb memory + than the kernel would) to 2.4 by tmb@iki.fi) + Have fun! diff -urN linux-2.4.21/Documentation/filesystems/befs.txt linux-2.4.22/Documentation/filesystems/befs.txt --- linux-2.4.21/Documentation/filesystems/befs.txt 2002-11-28 15:53:08.000000000 -0800 +++ linux-2.4.22/Documentation/filesystems/befs.txt 2003-08-25 04:44:39.000000000 -0700 @@ -18,32 +18,35 @@ AUTHOR ===== Current maintainer: Will Dyson -Has been working on the code since Aug 13, 2001. See the changelog for details. +Has been working on the code since Aug 13, 2001. See the changelog for +details. Original Author: Makoto Kato -His orriginal code can still be found at: -Does anyone know of a more current email address for Makoto? He doesn't respond -to the address given above... +His orriginal code can still be found at: + +Does anyone know of a more current email address for Makoto? He doesn't +respond to the address given above... WHAT IS THIS DRIVER? ================== This module implements the native filesystem of BeOS -for the linux 2.4.1 and later kernels. Currently it is a read-only implementation. +for the linux 2.4.1 and later kernels. Currently it is a read-only +implementation. Which is it, BFS or BEFS? ================ Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". -But Unixware Boot Filesystem is called bfs, too. And they are already in the -kernel. -Because of this nameing conflict, on Linux the BeOS filesystem is called befs. +But Unixware Boot Filesystem is called bfs, too. And they are already in +the kernel. Because of this nameing conflict, on Linux the BeOS +filesystem is called befs. HOW TO INSTALL ============== step 1. Install the BeFS patch into the source code tree of linux. Apply the patchfile to your kernel source tree. -Assuming that your kernel source is in /foo/bar/linux and the patchfile is called -patch-befs-xxx, you would do the following: +Assuming that your kernel source is in /foo/bar/linux and the patchfile +is called patch-befs-xxx, you would do the following: cd /foo/bar/linux patch -p1 < /path/to/patch-befs-xxx @@ -66,8 +69,9 @@ The BeFS module is not a standard part of the linux kernel, so you must first enable support for experimental code under the "Code maturity level" menu. -Then, under the "Filesystems" menu will be an option called "BeFS filesystem (experimental)", -or something like that. Enable that option (it is fine to make it a module). +Then, under the "Filesystems" menu will be an option called "BeFS +filesystem (experimental)", or something like that. Enable that option +(it is fine to make it a module). Save your kernel configuration and then build your kernel. diff -urN linux-2.4.21/Documentation/filesystems/jfs.txt linux-2.4.22/Documentation/filesystems/jfs.txt --- linux-2.4.21/Documentation/filesystems/jfs.txt 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/filesystems/jfs.txt 2003-08-25 04:44:39.000000000 -0700 @@ -4,10 +4,10 @@ Team members ------------ -Steve Best sbest@us.ibm.com Dave Kleikamp shaggy@austin.ibm.com +Dave Blaschke blaschke@us.ibm.com +Steve Best sbest@us.ibm.com Barry Arndt barndt@us.ibm.com -Christoph Hellwig hch@infradead.org The following mount options are supported: diff -urN linux-2.4.21/Documentation/filesystems/sysv-fs.txt linux-2.4.22/Documentation/filesystems/sysv-fs.txt --- linux-2.4.21/Documentation/filesystems/sysv-fs.txt 1997-12-16 09:43:36.000000000 -0800 +++ linux-2.4.22/Documentation/filesystems/sysv-fs.txt 2003-08-25 04:44:39.000000000 -0700 @@ -23,8 +23,9 @@ - Only file systems with no filesystem name and no pack name are recognized. (See Coherent "man mkfs" for a description of these features.) - SystemV Release 2 FS: - The superblock is only searched in the blocks 9, 15, 18, which corresponds to the - beginning of track 1 on floppy disks. No support for this FS on hard disk yet. + The superblock is only searched in the blocks 9, 15, 18, which + corresponds to the beginning of track 1 on floppy disks. No support + for this FS on hard disk yet. Please report any bugs and suggestions to diff -urN linux-2.4.21/Documentation/filesystems/tmpfs.txt linux-2.4.22/Documentation/filesystems/tmpfs.txt --- linux-2.4.21/Documentation/filesystems/tmpfs.txt 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/Documentation/filesystems/tmpfs.txt 2003-08-25 04:44:39.000000000 -0700 @@ -47,26 +47,28 @@ shared memory) 3) Some people (including me) find it very convenient to mount it - e.g. on /tmp and /var/tmp and have a big swap partition. But be - aware: loop mounts of tmpfs files do not work due to the internal - design. So mkinitrd shipped by most distributions will fail with a - tmpfs /tmp. + e.g. on /tmp and /var/tmp and have a big swap partition. And now + loop mounts of tmpfs files do work, so mkinitrd shipped by most + distributions should succeed with a tmpfs /tmp. 4) And probably a lot more I do not know about :-) -tmpfs has a couple of mount options: +tmpfs has three mount options for sizing: -size: The limit of allocated bytes for this tmpfs instance. The +size: The limit of allocated bytes for this tmpfs instance. The default is half of your physical RAM without swap. If you - oversize your tmpfs instances the machine will deadlock - since the OOM handler will not be able to free that memory. -nr_blocks: The same as size, but in blocks of PAGECACHE_SIZE. + oversize your tmpfs instances the machine will deadlock + since the OOM handler will not be able to free that memory. +nr_blocks: The same as size, but in blocks of PAGE_CACHE_SIZE. nr_inodes: The maximum number of inodes for this instance. The default is half of the number of your physical RAM pages. These parameters accept a suffix k, m or g for kilo, mega and giga and -can be changed on remount. +can be changed on remount. The size parameter also accepts a suffix % +to limit this tmpfs instance to that percentage of your physical RAM: +the default, when neither size nor nr_blocks is specified, is size=50% + To specify the initial root directory you can use the following mount options: @@ -84,19 +86,7 @@ RAM/SWAP in 10240 inodes and it is only accessible by root. -TODOs: - -1) give the size option a percent semantic: If you give a mount option - size=50% the tmpfs instance should be able to grow to 50 percent of - RAM + swap. So the instance should adapt automatically if you add - or remove swap space. -2) loop mounts: This is difficult since loop.c relies on the readpage - operation. This operation gets a page from the caller to be filled - with the content of the file at that position. But tmpfs always has - the page and thus cannot copy the content to the given page. So it - cannot provide this operation. The VM had to be changed seriously - to achieve this. -3) Show the number of tmpfs RAM pages. (As shared?) - Author: Christoph Rohland , 1.12.01 +Updated: + Hugh Dickins , 01 April 2003 diff -urN linux-2.4.21/Documentation/ia64/efirtc.txt linux-2.4.22/Documentation/ia64/efirtc.txt --- linux-2.4.21/Documentation/ia64/efirtc.txt 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.22/Documentation/ia64/efirtc.txt 2003-08-25 04:44:39.000000000 -0700 @@ -12,13 +12,13 @@ to get access to the Time Service offered by EFI version 0.92. EFI provides 4 calls one can make once the OS is booted: GetTime(), -SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this driver. -We describe those calls as well the design of the driver in the following -sections. +SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this +driver. We describe those calls as well the design of the driver in the +following sections. II/ Design Decisions -The original ideas was to provide a very simple driver to get access to, +The original ideas was to provide a very simple driver to get access to, at first, the time of day service. This is required in order to access, in a portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock to initialize the system view of the time during boot. @@ -39,8 +39,8 @@ without necessarily impacting any of the user applications. The decoupling enables flexibility and permits writing wrapper code is ncase things change. -The driver exposes two interfaces, one via the device file and a set of ioctl()s. -The other is read-only via the /proc filesystem. +The driver exposes two interfaces, one via the device file and a set of +ioctl()s. The other is read-only via the /proc filesystem. As of today we don't offer a /proc/sys interface. diff -urN linux-2.4.21/Documentation/kernel-parameters.txt linux-2.4.22/Documentation/kernel-parameters.txt --- linux-2.4.21/Documentation/kernel-parameters.txt 2002-11-28 15:53:08.000000000 -0800 +++ linux-2.4.22/Documentation/kernel-parameters.txt 2003-08-25 04:44:39.000000000 -0700 @@ -69,8 +69,10 @@ 53c7xx= [HW,SCSI] Amiga SCSI controllers. acpi= [HW,ACPI] Advanced Configuration and Power Interface - - acpismp=force [IA-32] Early setup parse and use ACPI SMP table. + force Force ACPI on, even if blacklisted platform + off Disable ACPI + ht Limit ACPI to boot-time LAPIC enumeration for HT, + disabling the run-time AML interpreter. ad1816= [HW,SOUND] @@ -341,6 +343,18 @@ memory; to be used when the kernel is not able to see the whole system memory or for test. + mem=nn[KMG]@ss[KMG] + [KNL,BOOT] Force usage of a specific region of memory + Region of memory to be used, from ss to ss+nn. + + mem=nn[KMG]#ss[KMG] + [KNL,BOOT,ACPI] Mark specific memory as ACPI data. + Region of memory to be used, from ss to ss+nn. + + mem=nn[KMG]$ss[KMG] + [KNL,BOOT,ACPI] Mark specific memory as reserved. + Region of memory to be used, from ss to ss+nn. + memfrac= [KNL] mga= [HW,DRM] @@ -393,8 +407,6 @@ instruction doesn't work correctly and not to use it. - noht [SMP,IA-32] Disables P4 Xeon(tm) HyperThreading. - noisapnp [ISAPNP] Disables ISA PnP code. noinitrd [RAM] Tells the kernel not to load any configured @@ -491,7 +503,7 @@ plip= [PPT,NET] Parallel port network link. profile= [KNL] enable kernel profiling via /proc/profile - (param:log level). + (param: profile step/bucket size as a power of 2) prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk before loading. diff -urN linux-2.4.21/Documentation/mips/time.README linux-2.4.22/Documentation/mips/time.README --- linux-2.4.21/Documentation/mips/time.README 2001-04-20 16:23:12.000000000 -0700 +++ linux-2.4.22/Documentation/mips/time.README 2003-08-25 04:44:39.000000000 -0700 @@ -103,9 +103,9 @@ Do you plan to use the CPU counter register as the timer interrupt or use an exnternal timer? - In order to CPU counter register as the timer interrupt source, you must - know the counter speed (mips_counter_frequency). It is usually the - same as the CPU speed (Or it is ALWAYS the same?) + In order to use CPU counter register as the timer interrupt source, you + must know the counter speed (mips_counter_frequency). It is usually the + same as the CPU speed or an integral divisor of it. d) decide on whether you want to use high-level or low-level timer interrupt routines. The low-level one is presumably faster, but should @@ -154,8 +154,45 @@ for some of the functions in time.c. For example, you may define your own timer interrupt routine, which does -its own processing and in turn calls timer_interrupt(). +some of its own processing and then calls timer_interrupt(). You can also over-ride any of the built-in functions (gettimeoffset, RTC routines and/or timer interrupt routine). + +PORTING NOTES FOR SMP +---------------------- + +If you have a SMP box, things are slightly more complicated. + +The time service running every jiffy is logically divided into two parts: + + 1) the one for the whole system (defined in timer_interrupt()) + 2) the one that should run for each CPU (defined in local_timer_interrupt()) + +You need to decide on your timer interrupt sources. + + case 1) - whole system has only one timer interrupt delivered to one CPU + + In this case, you set up timer interrupt as in UP systems. In addtion, + you need to set emulate_local_timer_interrupt to 1 so that other + CPUs get to call local_timer_interrupt(). + + THIS IS CURRENTLY NOT IMPLEMNETED. However, it is rather easy to write + one should such a need arise. You simply make a IPI call. + + case 2) - each CPU has a separate timer interrupt + + In this case, you need to set up IRQ such that each of them will + call local_timer_interrupt(). In addition, you need to arrange + one and only one of them to call timer_interrupt(). + + You can also do the low-level version of those interrupt routines, + following similar dispatching routes described above. + +Note about do_gettimeoffset(): + + It is very likely the CPU counter registers are not sync'ed up in a SMP box. + Therefore you cannot really use the many of the existing routines that + are based on CPU counter. You should wirte your own gettimeoffset rouinte + if you want intra-jiffy resolution. diff -urN linux-2.4.21/Documentation/networking/bonding.txt linux-2.4.22/Documentation/networking/bonding.txt --- linux-2.4.21/Documentation/networking/bonding.txt 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/networking/bonding.txt 2003-08-25 04:44:39.000000000 -0700 @@ -43,10 +43,10 @@ For the latest version of the bonding driver, use kernel 2.4.12 or above (otherwise you will need to apply a patch). -Configure kernel with `make menuconfig/xconfig/config', and select -"Bonding driver support" in the "Network device support" section. It is -recommended to configure the driver as module since it is currently the only way -to pass parameters to the driver and configure more than one bonding device. +Configure kernel with `make menuconfig/xconfig/config', and select "Bonding +driver support" in the "Network device support" section. It is recommended +to configure the driver as module since it is currently the only way to +pass parameters to the driver and configure more than one bonding device. Build and install the new kernel and modules. @@ -108,17 +108,17 @@ SLAVE=yes BOOTPROTO=none -Use DEVICE=eth1 in the ifcfg-eth1 config file. If you configure a second bonding -interface (bond1), use MASTER=bond1 in the config file to make the network -interface be a slave of bond1. +Use DEVICE=eth1 in the ifcfg-eth1 config file. If you configure a second +bonding interface (bond1), use MASTER=bond1 in the config file to make the +network interface be a slave of bond1. Restart the networking subsystem or just bring up the bonding device if your administration tools allow it. Otherwise, reboot. On Red Hat distros you can issue `ifup bond0' or `/etc/rc.d/init.d/network restart'. -If the administration tools of your distribution do not support master/slave -notation in configuring network interfaces, you will need to manually configure -the bonding device with the following commands: +If the administration tools of your distribution do not support +master/slave notation in configuring network interfaces, you will need to +manually configure the bonding device with the following commands: # /sbin/ifconfig bond0 192.168.1.1 netmask 255.255.255.0 \ broadcast 192.168.1.255 up @@ -166,8 +166,9 @@ ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1 This problem is avoided by loading the bonding driver before any network -drivers participating in a bond. Below is an example of loading the bonding -driver first, the IP address 192.168.1.1 is correctly associated with ifDescr.2. +drivers participating in a bond. Below is an example of loading the bonding +driver first, the IP address 192.168.1.1 is correctly associated with +ifDescr.2. interfaces.ifTable.ifEntry.ifDescr.1 = lo interfaces.ifTable.ifEntry.ifDescr.2 = bond0 @@ -200,6 +201,44 @@ parameters be specified, otherwise serious network degradation will occur during link failures. +arp_interval + + Specifies the ARP monitoring frequency in milli-seconds. + If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the + switch should be configured in a mode that evenly distributes packets + across all links - such as round-robin. If the switch is configured to + distribute the packets in an XOR fashion, all replies from the ARP + targets will be received on the same link which could cause the other + team members to fail. ARP monitoring should not be used in conjunction + with miimon. A value of 0 disables ARP monitoring. The default value + is 0. + +arp_ip_target + + Specifies the ip addresses to use when arp_interval is > 0. These + are the targets of the ARP request sent to determine the health of + the link to the targets. Specify these values in ddd.ddd.ddd.ddd + format. Multiple ip adresses must be seperated by a comma. At least + one ip address needs to be given for ARP monitoring to work. The + maximum number of targets that can be specified is set at 16. + +downdelay + + Specifies the delay time in milli-seconds to disable a link after a + link failure has been detected. This should be a multiple of miimon + value, otherwise the value will be rounded. The default value is 0. + +lacp_rate + + Option specifying the rate in which we'll ask our link partner to + transmit LACPDU packets in 802.3ad mode. Possible values are: + + slow or 0 + Request partner to transmit LACPDUs every 30 seconds (default) + + fast or 1 + Request partner to transmit LACPDUs every 1 second + max_bonds Specifies the number of bonding devices to create for this @@ -207,18 +246,27 @@ the bonding driver is not already loaded, then bond0, bond1 and bond2 will be created. The default value is 1. +miimon + + Specifies the frequency in milli-seconds that MII link monitoring + will occur. A value of zero disables MII link monitoring. A value + of 100 is a good starting point. See High Availability section for + additional information. The default value is 0. + mode - Specifies one of four bonding policies. The default is -round-robin (balance-rr). Possible values are (you can use either the -text or numeric option): + Specifies one of the bonding policies. The default is + round-robin (balance-rr). Possible values are (you can use + either the text or numeric option): balance-rr or 0 + Round-robin policy: Transmit in a sequential order from the first available slave through the last. This mode provides load balancing and fault tolerance. active-backup or 1 + Active-backup policy: Only one slave in the bond is active. A different slave becomes active if, and only if, the active slave fails. The bond's MAC address is @@ -226,7 +274,8 @@ to avoid confusing the switch. This mode provides fault tolerance. - balance-xor or 2 + balance-xor or 2 + XOR policy: Transmit based on [(source MAC address XOR'd with destination MAC address) modula slave count]. This selects the same slave for each @@ -234,16 +283,125 @@ balancing and fault tolerance. broadcast or 3 + Broadcast policy: transmits everything on all slave interfaces. This mode provides fault tolerance. -miimon - - Specifies the frequency in milli-seconds that MII link monitoring will - occur. A value of zero disables MII link monitoring. A value of - 100 is a good starting point. See High Availability section for - additional information. The default value is 0. + 802.3ad or 4 + + IEEE 802.3ad Dynamic link aggregation. Creates aggregation + groups that share the same speed and duplex settings. + Transmits and receives on all slaves in the active + aggregator. + + Pre-requisites: + + 1. Ethtool support in the base drivers for retrieving the + speed and duplex of each slave. + + 2. A switch that supports IEEE 802.3ad Dynamic link + aggregation. + + balance-tlb or 5 + + Adaptive transmit load balancing: channel bonding that does + not require any special switch support. The outgoing + traffic is distributed according to the current load + (computed relative to the speed) on each slave. Incoming + traffic is received by the current slave. If the receiving + slave fails, another slave takes over the MAC address of + the failed receiving slave. + + Prerequisite: + + Ethtool support in the base drivers for retrieving the + speed of each slave. + + balance-alb or 6 + + Adaptive load balancing: includes balance-tlb + receive + load balancing (rlb) for IPV4 traffic and does not require + any special switch support. The receive load balancing is + achieved by ARP negotiation. The bonding driver intercepts + the ARP Replies sent by the server on their way out and + overwrites the src hw address with the unique hw address of + one of the slaves in the bond such that different clients + use different hw addresses for the server. + + Receive traffic from connections created by the server is + also balanced. When the server sends an ARP Request the + bonding driver copies and saves the client's IP information + from the ARP. When the ARP Reply arrives from the client, + its hw address is retrieved and the bonding driver + initiates an ARP reply to this client assigning it to one + of the slaves in the bond. A problematic outcome of using + ARP negotiation for balancing is that each time that an ARP + request is broadcasted it uses the hw address of the + bond. Hence, clients learn the hw address of the bond and + the balancing of receive traffic collapses to the current + salve. This is handled by sending updates (ARP Replies) to + all the clients with their assigned hw address such that + the traffic is redistributed. Receive traffic is also + redistributed when a new slave is added to the bond and + when an inactive slave is re-activated. The receive load is + distributed sequentially (round robin) among the group of + highest speed slaves in the bond. + + When a link is reconnected or a new slave joins the bond + the receive traffic is redistributed among all active + slaves in the bond by intiating ARP Replies with the + selected mac address to each of the clients. The updelay + modeprobe parameter must be set to a value equal or greater + than the switch's forwarding delay so that the ARP Replies + sent to the clients will not be blocked by the switch. + + Prerequisites: + + 1. Ethtool support in the base drivers for retrieving the + speed of each slave. + + 2. Base driver support for setting the hw address of a + device also when it is open. This is required so that there + will always be one slave in the team using the bond hw + address (the current_slave) while having a unique hw + address for each slave in the bond. If the current_slave + fails it's hw address is swapped with the new current_slave + that was chosen. + +multicast + + Option specifying the mode of operation for multicast support. + Possible values are: + + disabled or 0 + Disabled (no multicast support) + + active or 1 + Enabled on active slave only, useful in active-backup mode + + all or 2 + Enabled on all slaves, this is the default + +primary + + A string (eth0, eth2, etc) to equate to a primary device. If this + value is entered, and the device is on-line, it will be used first + as the output media. Only when this device is off-line, will + alternate devices be used. Otherwise, once a failover is detected + and a new default output is chosen, it will remain the output media + until it too fails. This is useful when one slave was preferred + over another, i.e. when one slave is 1000Mbps and another is + 100Mbps. If the 1000Mbps slave fails and is later restored, it may + be preferred the faster slave gracefully become the active slave - + without deliberately failing the 100Mbps slave. Specifying a + primary is only valid in active-backup mode. +updelay + + Specifies the delay time in milli-seconds to enable a link after a + link up status has been detected. This should be a multiple of miimon + value, otherwise the value will be rounded. The default value is 0. + use_carrier Specifies whether or not miimon should use MII or ETHTOOL @@ -265,89 +423,37 @@ 0 will use the deprecated MII / ETHTOOL ioctls. The default value is 1. -downdelay - - Specifies the delay time in milli-seconds to disable a link after a - link failure has been detected. This should be a multiple of miimon - value, otherwise the value will be rounded. The default value is 0. - -updelay - - Specifies the delay time in milli-seconds to enable a link after a - link up status has been detected. This should be a multiple of miimon - value, otherwise the value will be rounded. The default value is 0. - -arp_interval - - Specifies the ARP monitoring frequency in milli-seconds. - If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the - switch should be configured in a mode that evenly distributes packets - across all links - such as round-robin. If the switch is configured to - distribute the packets in an XOR fashion, all replies from the ARP - targets will be received on the same link which could cause the other - team members to fail. ARP monitoring should not be used in conjunction - with miimon. A value of 0 disables ARP monitoring. The default value - is 0. - -arp_ip_target - - Specifies the ip addresses to use when arp_interval is > 0. These are - the targets of the ARP request sent to determine the health of the link - to the targets. Specify these values in ddd.ddd.ddd.ddd format. - Multiple ip adresses must be seperated by a comma. At least one ip - address needs to be given for ARP monitoring to work. The maximum number - of targets that can be specified is set at 16. - -primary - - A string (eth0, eth2, etc) to equate to a primary device. If this - value is entered, and the device is on-line, it will be used first as - the output media. Only when this device is off-line, will alternate - devices be used. Otherwise, once a failover is detected and a new - default output is chosen, it will remain the output media until it too - fails. This is useful when one slave was preferred over another, i.e. - when one slave is 1000Mbps and another is 100Mbps. If the 1000Mbps - slave fails and is later restored, it may be preferred the faster slave - gracefully become the active slave - without deliberately failing the - 100Mbps slave. Specifying a primary is only valid in active-backup mode. - -multicast - - Option specifying the mode of operation for multicast support. - Possible values are: - - disabled or 0 - Disabled (no multicast support) - - active or 1 - Enabled on active slave only, useful in active-backup mode - - all or 2 - Enabled on all slaves, this is the default - Configuring Multiple Bonds ========================== -If several bonding interfaces are required, the driver must be loaded -multiple times. For example, to configure two bonding interfaces with link -monitoring performed every 100 milli-seconds, the /etc/conf.modules should +If several bonding interfaces are required, either specify the max_bonds +parameter (described above), or load the driver multiple times. Using +the max_bonds parameter is less complicated, but has the limitation that +all bonding instances created will have the same options. Loading the +driver multiple times allows each instance of the driver to have differing +options. + +For example, to configure two bonding interfaces, one with mii link +monitoring performed every 100 milliseconds, and one with ARP link +monitoring performed every 200 milliseconds, the /etc/conf.modules should resemble the following: alias bond0 bonding alias bond1 bonding options bond0 miimon=100 -options bond1 -o bonding1 miimon=100 +options bond1 -o bonding1 arp_interval=200 arp_ip_target=10.0.0.1 Configuring Multiple ARP Targets ================================ -While ARP monitoring can be done with just one target, it can be usefull +While ARP monitoring can be done with just one target, it can be useful in a High Availability setup to have several targets to monitor. In the case of just one target, the target itself may go down or have a problem making it unresponsive to ARP requests. Having an additional target (or -several) would increase the reliability of the ARP monitoring. +several) increases the reliability of the ARP monitoring. + Multiple ARP targets must be seperated by commas as follows: # example options for ARP monitoring with three targets @@ -410,9 +516,10 @@ Switch Configuration ==================== -While the switch does not need to be configured when the active-backup -policy is used (mode=1), it does need to be configured for the round-robin, -XOR, and broadcast policies (mode=0, mode=2, and mode=3). +While the switch does not need to be configured when the active-backup, +balance-tlb or balance-alb policies (mode=1,5,6) are used, it does need to +be configured for the round-robin, XOR, broadcast, or 802.3ad policies +(mode=0,2,3,4). Verifying Bond Configuration @@ -420,7 +527,7 @@ 1) Bonding information files ---------------------------- -The bonding driver information files reside in the /proc/net/bond* directories. +The bonding driver information files reside in the /proc/net/bond* directories. Sample contents of /proc/net/bond0/info after the driver is loaded with parameters of mode=0 and miimon=1000 is shown below. @@ -445,7 +552,8 @@ The network configuration can be verified using the ifconfig command. In the example below, the bond0 interface is the master (MASTER) while eth0 and eth1 are slaves (SLAVE). Notice all slaves of bond0 have the same MAC address -(HWaddr) as bond0. +(HWaddr) as bond0 for all modes except TLB and ALB that require a unique MAC +address for each slave. [root]# /sbin/ifconfig bond0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 @@ -488,8 +596,7 @@ 3. How many bonding devices can I have? - One for each module you load. See section on Module Parameters for how - to accomplish this. + There is no limit. 4. How many slaves can a bonding device have? @@ -508,10 +615,11 @@ For ethernet cards not supporting MII status, the arp_interval and arp_ip_target parameters must be specified for bonding to work correctly. If packets have not been sent or received during the - specified arp_interval durration, an ARP request is sent to the targets - to generate send and receive traffic. If after this interval, either - the successful send and/or receive count has not incremented, the next - slave in the sequence will become the active slave. + specified arp_interval durration, an ARP request is sent to the + targets to generate send and receive traffic. If after this + interval, either the successful send and/or receive count has not + incremented, the next slave in the sequence will become the active + slave. If neither mii_monitor and arp_interval is configured, the bonding driver will not handle this situation very well. The driver will @@ -522,15 +630,16 @@ 6. Can bonding be used for High Availability? - Yes, if you use MII monitoring and ALL your cards support MII link - status reporting. See section on High Availability for more information. + Yes, if you use MII monitoring and ALL your cards support MII link + status reporting. See section on High Availability for more + information. 7. Which switches/systems does it work with? In round-robin and XOR mode, it works with systems that support trunking: - * Cisco 5500 series (look for EtherChannel support). + * Many Cisco switches and routers (look for EtherChannel support). * SunTrunking software. * Alteon AceDirector switches / WebOS (use Trunks). * BayStack Switches (trunks must be explicitly configured). Stackable @@ -538,7 +647,17 @@ units. * Linux bonding, of course ! - In active-backup mode, it should work with any Layer-II switche. + In 802.3ad mode, it works with with systems that support IEEE 802.3ad + Dynamic Link Aggregation: + + * Extreme networks Summit 7i (look for link-aggregation). + * Many Cisco switches and routers (look for LACP support; this may + require an upgrade to your IOS software; LACP support was added + by Cisco in late 2002). + * Foundry Big Iron 4000 + + In active-backup, balance-tlb and balance-alb modes, it should work + with any Layer-II switch. 8. Where does a bonding device get its MAC address from? @@ -591,6 +710,20 @@ Broadcast policy transmits everything on all slave interfaces. + 802.3ad, based on XOR but distributes traffic among all interfaces + in the active aggregator. + + Transmit load balancing (balance-tlb) balances the traffic + according to the current load on each slave. The balancing is + clients based and the least loaded slave is selected for each new + client. The load of each slave is calculated relative to its speed + and enables load balancing in mixed speed teams. + + Adaptive load balancing (balance-alb) uses the Transmit load + balancing for the transmit load. The receive load is balanced only + among the group of highest speed active slaves in the bond. The + load is distributed with round-robin i.e. next available slave in + the high speed group of active slaves. High Availability ================= @@ -826,10 +959,6 @@ Use the arp_interval/arp_ip_target parameters to count incoming/outgoing frames. - - A Transmit Load Balancing policy is not currently available. This mode - allows every slave in the bond to transmit while only one receives. If - the "receiving" slave fails, another slave takes over the MAC address of - the failed receiving slave. Resources and Links diff -urN linux-2.4.21/Documentation/networking/ifenslave.c linux-2.4.22/Documentation/networking/ifenslave.c --- linux-2.4.21/Documentation/networking/ifenslave.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/networking/ifenslave.c 2003-08-25 04:44:39.000000000 -0700 @@ -27,7 +27,7 @@ * - 2001/02/16 Chad N. Tindel : * - Master is now brought down before setting the MAC address. In * the 2.4 kernel you can't change the MAC address while the device is - * up because you get EBUSY. + * up because you get EBUSY. * * - 2001/09/13 Takao Indoh * - Added the ability to change the active interface on a mode 1 bond @@ -44,17 +44,60 @@ * * - 2002/10/31 Tony Cureington : * - If the master does not have a hardware address when the first slave - * is enslaved, the master is assigned the hardware address of that - * slave - there is a comment in bonding.c stating "ifenslave takes - * care of this now." This corrects the problem of slaves having - * different hardware addresses in active-backup mode when + * is enslaved, the master is assigned the hardware address of that + * slave - there is a comment in bonding.c stating "ifenslave takes + * care of this now." This corrects the problem of slaves having + * different hardware addresses in active-backup mode when * multiple interfaces are specified on a single ifenslave command * (ifenslave bond0 eth0 eth1). * + * - 2003/03/18 - Tsippy Mendelson and + * Shmulik Hen + * - Moved setting the slave's mac address and openning it, from + * the application to the driver. This enables support of modes + * that need to use the unique mac address of each slave. + * The driver also takes care of closing the slave and restoring its + * original mac address upon release. + * In addition, block possibility of enslaving before the master is up. + * This prevents putting the system in an undefined state. + * + * - 2003/05/01 - Amir Noam + * - Added ABI version control to restore compatibility between + * new/old ifenslave and new/old bonding. + * - Prevent adding an adapter that is already a slave. + * Fixes the problem of stalling the transmission and leaving + * the slave in a down state. + * + * - 2003/05/01 - Shmulik Hen + * - Prevent enslaving if the bond device is down. + * Fixes the problem of leaving the system in unstable state and + * halting when trying to remove the module. + * - Close socket on all abnormal exists. + * - Add versioning scheme that follows that of the bonding driver. + * current version is 1.0.0 as a base line. + * + * - 2003/05/22 - Jay Vosburgh + * - ifenslave -c was broken; it's now fixed + * - Fixed problem with routes vanishing from master during enslave + * processing. + * + * - 2003/05/27 - Amir Noam + * - Fix backward compatibility issues: + * For drivers not using ABI versions, slave was set down while + * it should be left up before enslaving. + * Also, master was not set down and the default set_mac_address() + * would fail and generate an error message in the system log. + * - For opt_c: slave should not be set to the master's setting + * while it is running. It was already set during enslave. To + * simplify things, it is now handeled separately. */ +#define APP_VERSION "1.0.12" +#define APP_RELDATE "June 30, 2003" +#define APP_NAME "ifenslave" + static char *version = -"ifenslave.c:v0.07 9/9/97 Donald Becker (becker@cesdis.gsfc.nasa.gov).\n" +APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ") " "\nDonald Becker (becker@cesdis.gsfc.nasa.gov).\n" "detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n" "2.4 kernel support added on 2001/02/16 by Chad N. Tindel (ctindel at ieee dot org.\n"; @@ -97,12 +140,17 @@ #include #include #include -#include -#include +#include #include #include #include +typedef unsigned long long u64; /* hack, so we may include kernel's ethtool.h */ +typedef __uint32_t u32; /* ditto */ +typedef __uint16_t u16; /* ditto */ +typedef __uint8_t u8; /* ditto */ +#include + struct option longopts[] = { /* { name has_arg *flag val } */ {"all-interfaces", 0, 0, 'a'}, /* Show all interfaces. */ @@ -130,18 +178,19 @@ int skfd = -1; /* AF_INET socket for ioctl() calls. */ static void if_print(char *ifname); +static int get_abi_ver(char *master_ifname); int main(int argc, char **argv) { struct ifreq ifr2, if_hwaddr, if_ipaddr, if_metric, if_mtu, if_dstaddr; struct ifreq if_netmask, if_brdaddr, if_flags; - int goterr = 0; + int rv, goterr = 0; int c, errflag = 0; sa_family_t master_family; char **spp, *master_ifname, *slave_ifname; int hwaddr_notset; - int master_up; + int abi_ver = 0; while ((c = getopt_long(argc, argv, "acdfrvV?h", longopts, 0)) != EOF) switch (c) { @@ -207,6 +256,7 @@ char **tempp = spp; if ((master_ifname == NULL)||(slave_ifname == NULL)||(*tempp++ != NULL)) { fprintf(stderr, usage_msg); + (void) close(skfd); return 2; } } @@ -218,6 +268,13 @@ exit(0); } + /* exchange abi version with bonding driver */ + abi_ver = get_abi_ver(master_ifname); + if (abi_ver < 0) { + (void) close(skfd); + exit(1); + } + /* Get the vitals from the master interface. */ { struct ifreq *ifra[7] = { &if_ipaddr, &if_mtu, &if_dstaddr, @@ -242,6 +299,13 @@ } } + /* check if master is up; if not then fail any operation */ + if (!(if_flags.ifr_flags & IFF_UP)) { + fprintf(stderr, "Illegal operation; the specified master interface '%s' is not up.\n", master_ifname); + (void) close(skfd); + exit (1); + } + hwaddr_notset = 1; /* assume master's address not set yet */ for (i = 0; hwaddr_notset && (i < 6); i++) { hwaddr_notset &= ((unsigned char *)if_hwaddr.ifr_hwaddr.sa_data)[i] == 0; @@ -254,7 +318,7 @@ " with ethernet-like network interfaces.\n" " Use the '-f' option to force the operation.\n", master_ifname); - + (void) close(skfd); exit (1); } master_family = if_hwaddr.ifr_hwaddr.sa_family; @@ -278,143 +342,153 @@ fprintf(stderr, "SIOCBONDRELEASE: cannot detach %s from %s. errno=%s.\n", slave_ifname, master_ifname, strerror(errno)); } - else { /* we'll set the interface down to avoid any conflicts due to - same IP/MAC */ + else if (abi_ver < 1) { + /* The driver is using an old ABI, so we'll set the interface + * down to avoid any conflicts due to same IP/MAC + */ strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ); if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) { int saved_errno = errno; fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname, - strerror(saved_errno)); + strerror(saved_errno)); } else { ifr2.ifr_flags &= ~(IFF_UP | IFF_RUNNING); if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) { int saved_errno = errno; fprintf(stderr, "Shutting down interface %s failed: %s\n", - slave_ifname, strerror(saved_errno)); + slave_ifname, strerror(saved_errno)); } } } - } - else { /* attach a slave interface to the master */ - /* two possibilities : - - if hwaddr_notset, do nothing. The bond will assign the - hwaddr from it's first slave. - - if !hwaddr_notset, assign the master's hwaddr to each slave - */ + } else if (opt_c) { /* change primary slave */ + strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ); + strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ); + if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &if_flags) < 0) && + (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &if_flags) < 0)) { + fprintf(stderr, "SIOCBONDCHANGEACTIVE: %s.\n", strerror(errno)); + } + } else { /* attach a slave interface to the master */ strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ); if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) { int saved_errno = errno; fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname, strerror(saved_errno)); + (void) close(skfd); return 1; } + if ((ifr2.ifr_flags & IFF_SLAVE) && !opt_r) { + fprintf(stderr, "%s is already a slave\n", slave_ifname); + (void) close(skfd); + return 1; + } + + /* if hwaddr_notset, assign the slave hw address to the master */ if (hwaddr_notset) { - /* assign the slave hw address to the - * master since it currently does not + /* assign the slave hw address to the + * master since it currently does not * have one; otherwise, slaves may - * have different hw addresses in - * active-backup mode as seen when enslaving + * have different hw addresses in + * active-backup mode as seen when enslaving * using "ifenslave bond0 eth0 eth1" because * hwaddr_notset is set outside this loop. * TODO: put this and the "else" portion in * a function. */ - goterr = 0; - master_up = 0; - if (if_flags.ifr_flags & IFF_UP) { - if_flags.ifr_flags &= ~IFF_UP; - if (ioctl(skfd, SIOCSIFFLAGS, - &if_flags) < 0) { - goterr = 1; - fprintf(stderr, - "Shutting down " - "interface %s failed: " - "%s\n", - master_ifname, - strerror(errno)); - } else { - /* we took the master down, - * so we must bring it up - */ - master_up = 1; - } + /* get the slaves MAC address */ + strncpy(if_hwaddr.ifr_name, slave_ifname, + IFNAMSIZ); + rv = ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr); + if (-1 == rv) { + fprintf(stderr, "Could not get MAC " + "address of %s: %s\n", + slave_ifname, + strerror(errno)); + strncpy(if_hwaddr.ifr_name, + master_ifname, IFNAMSIZ); + goterr = 1; } if (!goterr) { - /* get the slaves MAC address */ - strncpy(if_hwaddr.ifr_name, - slave_ifname, IFNAMSIZ); - if (ioctl(skfd, SIOCGIFHWADDR, - &if_hwaddr) < 0) { - fprintf(stderr, - "Could not get MAC " - "address of %s: %s\n", - slave_ifname, - strerror(errno)); - strncpy(if_hwaddr.ifr_name, - master_ifname, - IFNAMSIZ); - goterr=1; + if (abi_ver < 1) { + /* In ABI versions older than 1, the + * master's set_mac routine couldn't + * work if it was up, because it + * used the default ethernet set_mac + * function. + */ + /* bring master down */ + if_flags.ifr_flags &= ~IFF_UP; + if (ioctl(skfd, SIOCSIFFLAGS, + &if_flags) < 0) { + goterr = 1; + fprintf(stderr, + "Shutting down " + "interface %s failed: " + "%s\n", + master_ifname, + strerror(errno)); + } } - } - if (!goterr) { - strncpy(if_hwaddr.ifr_name, + strncpy(if_hwaddr.ifr_name, master_ifname, IFNAMSIZ); - if (ioctl(skfd, SIOCSIFHWADDR, + if (ioctl(skfd, SIOCSIFHWADDR, &if_hwaddr) < 0) { - fprintf(stderr, + fprintf(stderr, "Could not set MAC " "address of %s: %s\n", - master_ifname, + master_ifname, strerror(errno)); goterr=1; } else { hwaddr_notset = 0; } - } - if (master_up) { - if_flags.ifr_flags |= IFF_UP; - if (ioctl(skfd, SIOCSIFFLAGS, - &if_flags) < 0) { - fprintf(stderr, - "Bringing up interface " - "%s failed: %s\n", - master_ifname, - strerror(errno)); + if (abi_ver < 1) { + /* bring master back up */ + if_flags.ifr_flags |= IFF_UP; + if (ioctl(skfd, SIOCSIFFLAGS, + &if_flags) < 0) { + fprintf(stderr, + "Bringing up interface " + "%s failed: %s\n", + master_ifname, + strerror(errno)); + } } } + } else if (abi_ver < 1) { /* if (hwaddr_notset) */ - } else { - /* we'll assign master's hwaddr to this slave */ + /* The driver is using an old ABI, so we'll set the interface + * down and assign the master's hwaddr to it + */ if (ifr2.ifr_flags & IFF_UP) { ifr2.ifr_flags &= ~IFF_UP; if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) { int saved_errno = errno; fprintf(stderr, "Shutting down interface %s failed: %s\n", - slave_ifname, strerror(saved_errno)); + slave_ifname, strerror(saved_errno)); } } - + strncpy(if_hwaddr.ifr_name, slave_ifname, IFNAMSIZ); if (ioctl(skfd, SIOCSIFHWADDR, &if_hwaddr) < 0) { int saved_errno = errno; fprintf(stderr, "SIOCSIFHWADDR on %s failed: %s\n", if_hwaddr.ifr_name, - strerror(saved_errno)); + strerror(saved_errno)); if (saved_errno == EBUSY) fprintf(stderr, " The slave device %s is busy: it must be" - " idle before running this command.\n", slave_ifname); + " idle before running this command.\n", slave_ifname); else if (saved_errno == EOPNOTSUPP) fprintf(stderr, " The slave device you specified does not support" - " setting the MAC address.\n Your kernel likely does not" - " support slave devices.\n"); + " setting the MAC address.\n Your kernel likely does not" + " support slave devices.\n"); else if (saved_errno == EINVAL) fprintf(stderr, " The slave device's address type does not match" - " the master's address type.\n"); + " the master's address type.\n"); } else { if (verbose) { unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; @@ -424,10 +498,11 @@ } } } - + if (*spp && !strcmp(*spp, "metric")) { if (*++spp == NULL) { fprintf(stderr, usage_msg); + (void) close(skfd); exit(2); } if_metric.ifr_metric = atoi(*spp); @@ -439,7 +514,7 @@ } spp++; } - + if (strncpy(if_ipaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0 || ioctl(skfd, SIOCSIFADDR, &if_ipaddr) < 0) { fprintf(stderr, @@ -452,16 +527,16 @@ slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); } } - + if (strncpy(if_mtu.ifr_name, slave_ifname, IFNAMSIZ) <= 0 - || ioctl(skfd, SIOCSIFMTU, &if_mtu) < 0) { + || ioctl(skfd, SIOCSIFMTU, &if_mtu) < 0) { fprintf(stderr, "Something broke setting the slave MTU: %s.\n", strerror(errno)); } else { if (verbose) printf("Set the slave's (%s) MTU to %d.\n", slave_ifname, if_mtu.ifr_mtu); } - + if (strncpy(if_dstaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0 || ioctl(skfd, SIOCSIFDSTADDR, &if_dstaddr) < 0) { fprintf(stderr, "Error setting the slave (%s) with SIOCSIFDSTADDR: %s.\n", @@ -473,7 +548,7 @@ slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); } } - + if (strncpy(if_brdaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0 || ioctl(skfd, SIOCSIFBRDADDR, &if_brdaddr) < 0) { fprintf(stderr, @@ -486,7 +561,7 @@ slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); } } - + if (strncpy(if_netmask.ifr_name, slave_ifname, IFNAMSIZ) <= 0 || ioctl(skfd, SIOCSIFNETMASK, &if_netmask) < 0) { fprintf(stderr, @@ -499,34 +574,45 @@ slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); } } - - ifr2.ifr_flags |= IFF_UP; /* the interface will need to be up to be bonded */ - if ((ifr2.ifr_flags &= ~(IFF_SLAVE | IFF_MASTER)) == 0 - || strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ) <= 0 - || ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) { - fprintf(stderr, - "Something broke setting the slave (%s) flags: %s.\n", - slave_ifname, strerror(errno)); + + if (abi_ver < 1) { + + /* The driver is using an old ABI, so we'll set the interface + * up before enslaving it + */ + ifr2.ifr_flags |= IFF_UP; + if ((ifr2.ifr_flags &= ~(IFF_SLAVE | IFF_MASTER)) == 0 + || strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ) <= 0 + || ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) { + fprintf(stderr, + "Something broke setting the slave (%s) flags: %s.\n", + slave_ifname, strerror(errno)); + } else { + if (verbose) + printf("Set the slave's (%s) flags %4.4x.\n", + slave_ifname, if_flags.ifr_flags); + } } else { - if (verbose) - printf("Set the slave's (%s) flags %4.4x.\n", slave_ifname, if_flags.ifr_flags); + /* the bonding module takes care of setting the slave's mac address + * and opening its interface + */ + if (ifr2.ifr_flags & IFF_UP) { /* the interface will need to be down */ + ifr2.ifr_flags &= ~IFF_UP; + if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) { + int saved_errno = errno; + fprintf(stderr, "Shutting down interface %s failed: %s\n", + slave_ifname, strerror(saved_errno)); + } + } } - + /* Do the real thing */ - if ( ! opt_r) { + if (!opt_r) { strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ); strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ); - if (!opt_c) { - if ((ioctl(skfd, SIOCBONDENSLAVE, &if_flags) < 0) && - (ioctl(skfd, BOND_ENSLAVE_OLD, &if_flags) < 0)) { - fprintf(stderr, "SIOCBONDENSLAVE: %s.\n", strerror(errno)); - } - } - else { - if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &if_flags) < 0) && - (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &if_flags) < 0)) { - fprintf(stderr, "SIOCBONDCHANGEACTIVE: %s.\n", strerror(errno)); - } + if ((ioctl(skfd, SIOCBONDENSLAVE, &if_flags) < 0) && + (ioctl(skfd, BOND_ENSLAVE_OLD, &if_flags) < 0)) { + fprintf(stderr, "SIOCBONDENSLAVE: %s.\n", strerror(errno)); } } } @@ -639,7 +725,38 @@ } } - +static int get_abi_ver(char *master_ifname) +{ + struct ifreq ifr; + struct ethtool_drvinfo info; + int abi_ver = 0; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); + ifr.ifr_data = (caddr_t)&info; + + info.cmd = ETHTOOL_GDRVINFO; + strncpy(info.driver, "ifenslave", 32); + snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION); + if (ioctl(skfd, SIOCETHTOOL, &ifr) >= 0) { + char *endptr; + + abi_ver = strtoul(info.fw_version, &endptr, 0); + if (*endptr) { + fprintf(stderr, "Error: got invalid string as an ABI " + "version from the bonding module\n"); + return -1; + } + } + + if (verbose) { + printf("ABI ver is %d\n", abi_ver); + } + return abi_ver; +} + + + /* * Local variables: * version-control: t diff -urN linux-2.4.21/Documentation/nmi_watchdog.txt linux-2.4.22/Documentation/nmi_watchdog.txt --- linux-2.4.21/Documentation/nmi_watchdog.txt 2001-09-17 23:03:09.000000000 -0700 +++ linux-2.4.22/Documentation/nmi_watchdog.txt 2003-08-25 04:44:39.000000000 -0700 @@ -1,16 +1,38 @@ -Is your ix86 system locking up unpredictably? No keyboard activity, just +[NMI watchdog is available for x86 and x86-64 architectures] + +Is your system locking up unpredictably? No keyboard activity, just a frustrating complete hard lockup? Do you want to help us debugging such lockups? If all yes then this document is definitely for you. -On Intel and similar ix86 type hardware there is a feature that enables +On many x86/x86-64 type hardware there is a feature that enables us to generate 'watchdog NMI interrupts'. (NMI: Non Maskable Interrupt which get executed even if the system is otherwise locked up hard). This can be used to debug hard kernel lockups. By executing periodic NMI interrupts, the kernel can monitor whether any CPU has locked up, -and print out debugging messages if so. You must enable the NMI -watchdog at boot time with the 'nmi_watchdog=n' boot parameter. Eg. -the relevant lilo.conf entry: +and print out debugging messages if so. + +In order to use the NMI watchdoc, you need to have APIC support in your +kernel. For SMP kernels, APIC support gets compiled in automatically. For +UP, enable either CONFIG_X86_UP_APIC (Processor type and features -> Local +APIC support on uniprocessors) or CONFIG_X86_UP_IOAPIC (Processor type and +features -> IO-APIC support on uniprocessors) in your kernel config. +CONFIG_X86_UP_APIC is for uniprocessor machines without an IO-APIC. +CONFIG_X86_UP_IOAPIC is for uniprocessor with an IO-APIC. [Note: certain +kernel debugging options, such as Kernel Stack Meter or Kernel Tracer, +may implicitly disable the NMI watchdog.] + +For x86-64, the needed APIC is always compiled in, and the NMI watchdog is +always enabled with I/O-APIC mode (nmi_watchdog=1). Currently, local APIC +mode (nmi_watchdog=2) does not work on x86-64. + +Using local APIC (nmi_watchdog=2) needs the first performance register, so +you can't use it for other purposes (such as high precision performance +profiling.) However, at least oprofile and the perfctr driver disable the +local APIC NMI watchdog automatically. + +To actually enable the NMI watchdog, use the 'nmi_watchdog=N' boot +parameter. Eg. the relevant lilo.conf entry: append="nmi_watchdog=1" diff -urN linux-2.4.21/Documentation/pci.txt linux-2.4.22/Documentation/pci.txt --- linux-2.4.21/Documentation/pci.txt 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/Documentation/pci.txt 2003-08-25 04:44:39.000000000 -0700 @@ -51,21 +51,24 @@ execution of pci_register_driver for already existing devices or later if a new device gets inserted) for all PCI devices which match the ID table and are not handled - by the other drivers yet. This function gets passed a pointer - to the pci_dev structure representing the device and also - which entry in the ID table did the device match. It returns - zero when the driver has accepted the device or an error - code (negative number) otherwise. This function always gets - called from process context, so it can sleep. - remove Pointer to a function which gets called whenever a device - being handled by this driver is removed (either during - deregistration of the driver or when it's manually pulled - out of a hot-pluggable slot). This function always gets - called from process context, so it can sleep. + by the other drivers yet. This function gets passed a + pointer to the pci_dev structure representing the device + and also which entry in the ID table did the device + match. It returns zero when the driver has accepted the + device or an error code (negative number) otherwise. + This function always gets called from process context, + so it can sleep. + remove Pointer to a function which gets called whenever a + device being handled by this driver is removed (either + during deregistration of the driver or when it's + manually pulled out of a hot-pluggable slot). This + function always gets called from process context, so it + can sleep. save_state Save a device's state before it's suspend. suspend Put device into low power state. resume Wake device from low power state. - enable_wake Enable device to generate wake events from a low power state. + enable_wake Enable device to generate wake events from a low power + state. (Please see Documentation/power/pci.txt for descriptions of PCI Power Management and the related functions) @@ -186,8 +189,9 @@ See Documentation/IO-mapping.txt for how to access device memory. - You still need to call request_region() for I/O regions and request_mem_region() -for memory regions to make sure nobody else is using the same device. + You still need to call request_region() for I/O regions and +request_mem_region() for memory regions to make sure nobody else is using the +same device. All interrupt handlers should be registered with SA_SHIRQ and use the devid to map IRQs to devices (remember that all PCI interrupts are shared). diff -urN linux-2.4.21/Documentation/power/pci.txt linux-2.4.22/Documentation/power/pci.txt --- linux-2.4.21/Documentation/power/pci.txt 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/Documentation/power/pci.txt 2003-08-25 04:44:39.000000000 -0700 @@ -22,7 +22,7 @@ power management operations. Implementation of the PCI PM Spec is optional, as are several sub-components of -it. If a device supports the PCI PM Spec, the device will have an 8 byte +it. If a device supports the PCI PM Spec, the device will have an 8 byte capability field in its PCI configuration space. This field is used to describe and control the standard PCI power management features. @@ -50,33 +50,35 @@ | D1, D2, D3 | D0 | +---------------------------+ -Note that when the system is entering a global suspend state, all devices will be -placed into D3 and when resuming, all devices will be placed into D0. However, -when the system is running, other state transitions are possible. +Note that when the system is entering a global suspend state, all devices will +be placed into D3 and when resuming, all devices will be placed into D0. +However, when the system is running, other state transitions are possible. 2. How The PCI Subsystem Handles Power Management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The PCI suspend/resume functionality is accessed indirectly via the Power Management -subsystem. At boot, the PCI driver registers a power management callback with that layer. -Upon entering a suspend state, the PM layer iterates through all of its registered -callbacks. This currently takes place only during APM state transitions. - -Upon going to sleep, the PCI subsystem walks its device tree twice. Both times, it does -a depth first walk of the device tree. The first walk saves each of the device's state -and checks for devices that will prevent the system from entering a global power state. -The next walk then places the devices in a low power state. - -The first walk allows a graceful recovery in the event of a failure, since none of the -devices have actually been powered down. - -In both walks, in particular the second, all children of a bridge are touched before the -actual bridge itself. This allows the bridge to retain power while its children are being -accessed. - -Upon resuming from sleep, just the opposite must be true: all bridges must be powered on -and restored before their children are powered on. This is easily accomplished with a -breadth-first walk of the PCI device tree. +The PCI suspend/resume functionality is accessed indirectly via the Power +Management subsystem. At boot, the PCI driver registers a power management +callback with that layer. Upon entering a suspend state, the PM layer iterates +through all of its registered callbacks. This currently takes place only during +APM state transitions. + +Upon going to sleep, the PCI subsystem walks its device tree twice. Both times, +it does a depth first walk of the device tree. The first walk saves each of the +device's state and checks for devices that will prevent the system from entering +a global power state. The next walk then places the devices in a low power +state. + +The first walk allows a graceful recovery in the event of a failure, since none +of the devices have actually been powered down. + +In both walks, in particular the second, all children of a bridge are touched +before the actual bridge itself. This allows the bridge to retain power while +its children are being accessed. + +Upon resuming from sleep, just the opposite must be true: all bridges must be +powered on and restored before their children are powered on. This is easily +accomplished with a breadth-first walk of the PCI device tree. 3. PCI Utility Functions @@ -86,8 +88,8 @@ Assuming that a device behaves as advertised, these should be applicable in most cases. However, results may vary. -Note that these functions are never implicitly called for the driver. The driver is always -responsible for deciding when and if to call these. +Note that these functions are never implicitly called for the driver. The driver +is always responsible for deciding when and if to call these. pci_save_state @@ -97,7 +99,8 @@ pci_save_state(dev, buffer); Description: - Save first 64 bytes of PCI config space. Buffer must be allocated by caller. + Save first 64 bytes of PCI config space. Buffer must be allocated by + caller. pci_restore_state @@ -109,8 +112,8 @@ Description: Restore previously saved config space. (First 64 bytes only); - If buffer is NULL, then restore what information we know about the device - from bootup: BARs and interrupt line. + If buffer is NULL, then restore what information we know about the + device from bootup: BARs and interrupt line. pci_set_power_state @@ -120,7 +123,8 @@ pci_set_power_state(dev, state); Description: - Transition device to low power state using PCI PM Capabilities registers. + Transition device to low power state using PCI PM Capabilities + registers. Will fail under one of the following conditions: - If state is less than current state, but not D0 (illegal transition) @@ -138,14 +142,15 @@ Enable device to generate PME# during low power state using PCI PM Capabilities. - Checks whether if device supports generating PME# from requested state and fail - if it does not, unless enable == 0 (request is to disable wake events, which - is implicit if it doesn't even support it in the first place). - - Note that the PMC Register in the device's PM Capabilties has a bitmask of - the states it supports generating PME# from. D3hot is bit 3 and D3cold is bit - 4. So, while a value of 4 as the state may not seem semantically correct, it - is. + Checks whether if device supports generating PME# from requested state + and fail if it does not, unless enable == 0 (request is to disable wake + events, which is implicit if it doesn't even support it in the first + place). + + Note that the PMC Register in the device's PM Capabilties has a bitmask + of the states it supports generating PME# from. D3hot is bit 3 and + D3cold is bit 4. So, while a value of 4 as the state may not seem + semantically correct, it is. 4. PCI Device Drivers @@ -168,25 +173,26 @@ if (dev->driver && dev->driver->save_state) dev->driver->save_state(dev,state); -The driver should use this callback to save device state. It should take into -account the current state of the device and the requested state in order to avoid -any unnecessary operations. - -For example, a video card that supports all 4 states (D0-D3), all controller context -is preserved when entering D1, but the screen is placed into a low power state -(blanked). - -The driver can also interpret this function as a notification that it may be entering -a sleep state in the near future. If it knows that the device cannot enter the -requested state, either because of lack of support for it, or because the device is -middle of some critical operation, then it should fail. - -This function should not be used to set any state in the device or the driver because -the device may not actually enter the sleep state (e.g. another driver later causes -causes a global state transition to fail). - -Note that in intermediate low power states, a device's I/O and memory spaces may be -disabled and may not be available in subsequent transitions to lower power states. +The driver should use this callback to save device state. It should take into +account the current state of the device and the requested state in order to +avoid any unnecessary operations. + +For example, a video card that supports all 4 states (D0-D3), all controller +context is preserved when entering D1, but the screen is placed into a low power +state (blanked). + +The driver can also interpret this function as a notification that it may be +entering a sleep state in the near future. If it knows that the device cannot +enter the requested state, either because of lack of support for it, or because +the device is middle of some critical operation, then it should fail. + +This function should not be used to set any state in the device or the driver +because the device may not actually enter the sleep state (e.g. another driver +later causes causes a global state transition to fail). + +Note that in intermediate low power states, a device's I/O and memory spaces may +be disabled and may not be available in subsequent transitions to lower power +states. suspend @@ -197,27 +203,27 @@ if (dev->driver && dev->driver->suspend) dev->driver->suspend(dev,state); -A driver uses this function to actually transition the device into a low power -state. This may include disabling I/O, memory and bus-mastering, as well as physically -transitioning the device to a lower power state. +A driver uses this function to actually transition the device into a low power +state. This may include disabling I/O, memory and bus-mastering, as well as +physically transitioning the device to a lower power state. Bus mastering may be disabled by doing: pci_disable_device(dev); -For devices that support the PCI PM Spec, this may be used to set the device's power -state: +For devices that support the PCI PM Spec, this may be used to set the device's +power state: pci_set_power_state(dev,state); The driver is also responsible for disabling any other device-specific features (e.g blanking screen, turning off on-card memory, etc). -The driver should be sure to track the current state of the device, as it may obviate -the need for some operations. +The driver should be sure to track the current state of the device, as it may +obviate the need for some operations. -The driver should update the current_state field in its pci_dev structure in this -function. +The driver should update the current_state field in its pci_dev structure in +this function. resume ------ @@ -227,36 +233,37 @@ if (dev->driver && dev->driver->suspend) dev->driver->resume(dev) -The resume callback may be called from any power state, and is always meant to +The resume callback may be called from any power state, and is always meant to transition the device to the D0 state. -The driver is responsible for reenabling any features of the device that had -been disabled during previous suspend calls and restoring all state that was saved -in previous save_state calls. - -If the device is currently in D3, it must be completely reinitialized, as it must be -assumed that the device has lost all of its context (even that of its PCI config -space). For almost all current drivers, this means that the initialization code that -the driver does at boot must be separated out and called again from the resume -callback. Note that some values for the device may not have to be probed for this -time around if they are saved before entering the low power state. +The driver is responsible for reenabling any features of the device that had +been disabled during previous suspend calls and restoring all state that was +saved in previous save_state calls. + +If the device is currently in D3, it must be completely reinitialized, as it +must be assumed that the device has lost all of its context (even that of its +PCI config space). For almost all current drivers, this means that the +initialization code that the driver does at boot must be separated out and +called again from the resume callback. Note that some values for the device may +not have to be probed for this time around if they are saved before entering the +low power state. -If the device supports the PCI PM Spec, it can use this to physically transition the -device to D0: +If the device supports the PCI PM Spec, it can use this to physically transition +the device to D0: pci_set_power_state(dev,0); -Note that if the entire system is transitioning out of a global sleep state, all -devices will be placed in the D0 state, so this is not necessary. However, in the -event that the device is placed in the D3 state during normal operation, this call -is necessary. It is impossible to determine which of the two events is taking place -in the driver, so it is always a good idea to make that call. +Note that if the entire system is transitioning out of a global sleep state, all +devices will be placed in the D0 state, so this is not necessary. However, in +the event that the device is placed in the D3 state during normal operation, +this call is necessary. It is impossible to determine which of the two events is +taking place in the driver, so it is always a good idea to make that call. -The driver should take note of the state that it is resuming from in order to ensure -correct (and speedy) operation. +The driver should take note of the state that it is resuming from in order to +ensure correct (and speedy) operation. -The driver should update the current_state field in its pci_dev structure in this -function. +The driver should update the current_state field in its pci_dev structure in +this function. enable_wake diff -urN linux-2.4.21/Documentation/s390/CommonIO linux-2.4.22/Documentation/s390/CommonIO --- linux-2.4.21/Documentation/s390/CommonIO 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/Documentation/s390/CommonIO 2003-08-25 04:44:39.000000000 -0700 @@ -21,7 +21,8 @@ Default is on. -* cio_ignore = , , ... +* cio_ignore = | , + | , ... The given device numbers will be ignored by the common I/O-layer; no detection and device sensing will be done on any of those devices. The subchannel to @@ -55,14 +56,22 @@ * /proc/subchannels - Shows for each subchannel - - device number - - device type/model and if applicable control unit type/model - - whether the device is in use - - path installed mask, path available mask, path operational mask and last - path used mask - - the channel path IDs (chpids) + This entry shows information on a per-subchannel basis. + The data is ordered in the following way: + + - device number + - subchannel number + - device type/model (if applicable; if not, this is empty) and control unit + type/model + - whether the device is in use (i. e. a device driver has requested ownership + and registered an interrupt handler) + - path installed mask (PIM), as reflected by last store subchannel + - path available mask (PAM), as reflected by last store subchannel + - path operational mask (POM), as reflected by last store subchannel + - the channel path IDs (CHPIDs) + + All fields are separated by spaces, the chpids are in blocks of four chpids. * /proc/deviceinfo/ @@ -137,3 +146,26 @@ This entry counts how many times s390_process_IRQ has been called for each CPU. This info is in /proc/interrupts on other architectures. + +* /proc/chpids + + This entry will only show up if you specified CONFIG_CHSC=y during kernel + config. + + This entry serves a dual purpose: + + - show which chpids are currently known to Linux and their status (online, + logically offline), + + - toggling known chpids logically online/offline. + + To toggle a known chpid logically offline, do an + echo off > /proc/chpids + is interpreted as hex, even if you omit the '0x'. + The chpid will be treated by Linux as if it were not online, which can mean + some devices will become unavailable. + + You can toggle a logically offline chpid online again by + echo on > /proc/chpids + If devices became unavailable by toggling the chpid logically offline, they + will become available again after you toggle the chpid online again. diff -urN linux-2.4.21/Documentation/s390/Debugging390.txt linux-2.4.22/Documentation/s390/Debugging390.txt --- linux-2.4.21/Documentation/s390/Debugging390.txt 2002-02-25 11:37:51.000000000 -0800 +++ linux-2.4.22/Documentation/s390/Debugging390.txt 2003-08-25 04:44:39.000000000 -0700 @@ -238,7 +238,7 @@ On 390 our limitations & strengths make us slightly different. For backward compatibility ( because of the psw address hi bit which -indicates whether we are in 31 or 64 bit mode ) we are only allowed +indicates whether we are in 31 or 24 bit mode ) we are only allowed use 31 bits (2GB) of our 32 bit addresses. However, we use entirely separate address spaces for the user & kernel. @@ -1475,6 +1475,12 @@ D 00014CB4.20 V00014CB4 2F646576 2F636F6E 736F6C65 00001BF5 V00014CC4 FC00014C B4001001 E0001000 B8070707 + +Alternatively you can do the more elegant +D 0.20;BASE2 +BASE2 telling VM to use GPR2 as the base register. + + Now copy the text till the first 00 hex ( which is the end of the string to an xterm & do hex2ascii on it. hex2ascii 2F646576 2F636F6E 736F6C65 00 diff -urN linux-2.4.21/Documentation/s390/c7000.txt linux-2.4.22/Documentation/s390/c7000.txt --- linux-2.4.21/Documentation/s390/c7000.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/Documentation/s390/c7000.txt 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,92 @@ +Cisco 7000 (CLAW) support + +The c7000 module provides support for a channel attached Cisco 7xxx +family router on Linux/390. The parameters for the module are as follows: + + base0=0xYYYY This parameter defines the base unit address of the + channel attached router. + + lhost0=s1 This parameter defines the local host name and + must match the claw directive "host-name" field + (first string). The default value is "UTS". + + uhost0=s2 This parameter defines the unit's name and must + match the claw directive "device-name" field + (second string). The default value is "C7011". + + lappl0=s3 This parameter defines the local application name + and must match the claw directive "host-app" field + (third string). The default value is "TCPIP". + + uappl0=s4 This parameter defines the unit application name and + must match the claw directive "device-app" field + (fourth string). The default value is "TCPIP". + + dbg=x This parameter defines the message level. Higher + numbers will result in additional diagnostic messages. + The default value is 0. + + noauto=z This parameter controls the automatic detection of + the unit base address (base0). When set to a non + zero value, automatic detection of unit base addresses + is not done. The default value is 0. + +Note that the values coded in strings s1 - s4 are case sensitive. + +For example, assume that the following claw directive has been coded in +the Cisco router: + +claw 0100 6C 129.212.61.101 UTS C7011 TCPIP TCPIP + +The module can be loaded using the following command: + +insmod c7000 base0=0x336c lhost0="UTS" uhost0="C7011" lappl0="TCPIP" \ +uappl0="TCPIP" dbg=0 noauto=1 + +Additional interfaces can be defined via parameters base1 - base3, +lhost1 - lhost3, lappl1 - lappl3, uhost1 - uhost3, uappl1 - uappl3. +The interfaces are named "ci0" - "ci3". After loading the module, the +ifconfig command is used to configure the interface. For example: + +ifconfig ci0 129.212.61.101 +ifconfig ci0 netmask 255.255.255.0 broadcast 129.212.61.0 +ifconfig ci0 + +The route command is used to specify the router as the default route: + +route add default gw 129.212.61.200 + +The interface can be automatically activated at boot time by following this +procedure: + +1) Add the following two lines to file "/etc/conf.modules": + +alias ci0 c7000 +options c7000 base0=0xYYYY lhost0=s1 uhost0=s2 lappl0=s3 uappl0=s4 + +2) Edit file "/etc/sysconfig/network" as follows: + +NETWORKING=yes +FORWARD_IPV4=no +HOSTNAME=your-hostname +GATEWAYDEV=ci0 +GATEWAY=your-gateway-ip-address + +Substitute your own host name and gateway IP address. + +3) Create a file in directory "/etc/sysconfig/network-scripts" called +"ifcfg-ci0". The contents are as follows: + +DEVICE=ci0 +USERCTL=no +ONBOOT=yes +BOOTPROTO=none +BROADCAST=your-broadcast-ip-address +NETWORK=your-network-address +NETMASK=your-netmask +IPADDR=your-ip-address + +Substitute your IP address, broadcast IP address, network address and +network mask. + +4) chmod +x ifcfg-ci0 diff -urN linux-2.4.21/Documentation/s390/cds.txt linux-2.4.22/Documentation/s390/cds.txt --- linux-2.4.21/Documentation/s390/cds.txt 2001-03-02 11:12:06.000000000 -0800 +++ linux-2.4.22/Documentation/s390/cds.txt 2003-08-25 04:44:39.000000000 -0700 @@ -5,12 +5,14 @@ Author : Ingo Adlung -Copyright, IBM Corp. 1999 +Copyright, IBM Corp. 1999-2002 + +ChangeLog: 02/01/2002 Cornelia Huck brought up-to-date Introduction This document describes the common device support routines for Linux/390. -Different than other hardware architectures, ESA/390 hasdefined a unified +Different than other hardware architectures, ESA/390 has defined a unified I/O access method. This gives relief to the device drivers as they don't have to deal with different bus types, polling versus interrupt processing, shared versus non-shared interrupt processing, DMA versus port @@ -26,14 +28,11 @@ In order to build common device support for ESA/390 I/O interfaces, a functional layer was introduced that provides generic I/O access methods to -the hardware. The following figure shows the usage of the common device support -of Linux/390 using a TbCP/IP driven device access an example. Similar figures -could be drawn for other access methods, e.g. file system access to disk -devices. - -The common device support layer shown above comprises the I/O support routines -defined below. Some of them implement common Linux device driver interfaces, -while some of them are ESA/390 platform specific. +the hardware. + +The common device support layer comprises the I/O support routines defined +below. Some of them implement common Linux device driver interfaces, while +some of them are ESA/390 platform specific. get_dev_info_by_irq() / get_dev_info_by_devno() allow a device driver to determine the devices attached (visible) to the @@ -44,10 +43,17 @@ read_dev_chars() read device characteristics + +read_conf_data() + read configuration data. request_irq() obtain ownership for a specific device. +s390_request_irq_special() + obtain ownership for a specific device. Similar to request_irq(), but + allows for device not operational notification too. + free_irq() release ownership for a specific device. @@ -60,6 +66,9 @@ do_IO() initiate an I/O request. +resume_IO() + resume channel program execution. + halt_IO() terminate the current I/O request processed on the device. @@ -70,12 +79,14 @@ interrupt handler according to the rules (flags) defined during I/O request initiation with do_IO(). -The next chapters describe the functions, other than do_IRQ() in more details. +The next chapters describe the functions other than do_IRQ() in more details. The do_IRQ() interface is not described, as it is called from the Linux/390 first level interrupt handler only and does not comprise a device driver callable interface. Instead, the functional description of do_IO() also describes the input to the device specific interrupt handler. +Note: All explanations apply also to the 64 bit architecture s390x. + Common Device Support (CDS) for Linux/390 Device Drivers @@ -90,7 +101,7 @@ of them can be found on other Linux platforms implementations too. Miscellaneous function prototypes, data declarations, and macro definitions can be found in the architecture specific C header file -linux/arch/s390/kernel/irq.h. +linux/include/asm-s390/irq.h. Overview of CDS interface concepts @@ -106,7 +117,7 @@ single device is uniquely identified to the system by a so called subchannel, where the ESA/390 architecture allows for 64k devices be attached. -Linux, however was first built on the Intel PC architecture, with its two +Linux, however, was first built on the Intel PC architecture, with its two cascaded 8259 programmable interrupt controllers (PICs), that allow for a maximum of 15 different interrupt lines. All devices attached to such a system share those 15 interrupt levels. Devices attached to the ISA bus system must @@ -117,7 +128,7 @@ has to call every single device driver registered on this IRQ in order to determine the device driver owning the device that raised the interrupt. -In order to not introduce a new I/O concept to the common Linux code, +In order not to introduce a new I/O concept to the common Linux code, Linux/390 preserves the IRQ concept and semantically maps the ESA/390 subchannels to Linux as IRQs. This allows Linux/390 to support up to 64k different IRQs, uniquely representig a single device each. @@ -126,7 +137,7 @@ of those devices is uniquely defined by a so called subchannel by the ESA/390 channel subsystem. While the subchannel numbers are system generated, each subchannel also takes a user defined attribute, the so called device number. -Both, subchannel number and device number can not exceed 65535. The +Both subchannel number and device number can not exceed 65535. The init_IRQ() routine gathers the information about control unit type and device types that imply specific I/O commands (channel command words - CCWs) in order to operate the device. Device drivers can retrieve this set of hardware @@ -141,7 +152,7 @@ When a device driver has recognized a device it wants to claim ownership for, it calls request_irq() with the device's subchannel id serving as pseudo irq line. One of the required parameters it has to specify is dev_id, defining a -device status block, the CDS layer will use to notify the device driver's +device status block which the CDS layer will use to notify the device driver's interrupt handler about interrupt information observed. It depends on the device driver to properly handle those interrupts. @@ -169,6 +180,41 @@ +get_irq_first() / get_irq_next() - Retrieve Information about available IRQs + +A device driver can use those interface routines to retrieve information for +those IRQs only that have valid device information available. As +Linux for S/390 supports a maximum of 65535 subchannels (devices), it might +be a waste of CPU to scan for the max number of devices while a fraction is +available/usable only. get_irq_first() will retrieve the first usable IRQ. +Using this as input get_irq_next() will retrieve the next IRQ available, etc.. + +int get_irq_first( void ); +int get_irq_next( int irq ); + +irq - defines the subchannel to start scanning with. This must be + a valid subchannel or an error is returned. + +The get_irq_first() / get_irq_next() functions return: + +non-negative value - next available IRQ + -ENODEV - no more IRQs available + +Example : + + irq = get_irq_first(); + while ( irq != -ENODEV) + { + get_dev_info_by_irq( irq, &dinfo); + if ( dinfo.devno == devno_to_look_for + || dinfo.sid_data.cu_type == cu_type_to_look_for ) + { + do_some_action( irq, &dinfo ); + } /* endif */ + + irq = get_irq_next(irq); + } + get_dev_info_by_irq() / get_dev_info_by_devno() - Retrieve Device Information During system startup - init_IRQ() processing - the generic I/O device support @@ -176,60 +222,69 @@ SenseID information. For those devices supporting the command it also obtains extended SenseID information. -int get_dev_info_by_irq( int irq, - dev_info_t *devinfo); +int get_dev_info_by_irq( int irq, + s390_dev_info_t *pdi); -int get_dev_info_by_devno( unsigned int irq, - dev_info_t *devinfo); +int get_dev_info_by_devno( __u16 devno, + s390_dev_info_t *pdi); -irq - defines the subchannel, status information is to be +irq - defines the subchannel status information is to be returned for. devno - device number. -devinfo - pointer to a user buffer of type dev_info_t that should +pdi - pointer to a user buffer of type s390_dev_info_t that should be filled with device specific information. typedef struct { - unsigned int devno; /* device number */ - unsigned int status; /* device status */ - senseid_t sid_data; /* senseID data */ -} dev_info_t; + int irq; /* irq, aka. subchannel */ + __u16 devno; /* device number */ + unsigned int status; /* device status */ + senseid_t sid_data; /* senseID data */ +} s390_dev_info_t; +irq - subchannel. devno - device number as configured in the IOCDS. status - device status sid_data - data obtained by a SenseID call Possible status values are : -DEVSTAT_NOT_OPER - device was found not-operational. In this case - the caller should disregard the sid_data - buffer content. +DEVSTAT_NOT_OPER - device was found not-operational. In this case + the caller should disregard the sid_data + buffer content. +DEVSTAT_UNFRIENDLY_DEV - device is locked by someone else. The sid_data buffer + doesn't contain valid data. +DEVSTAT_UNKNOWN_DEV - The device is unknown, and the sid_data buffer doesn't + contain valid data. +DEVSTAT_DEVICE_OWNED - An interrupt handler is registered. // -// SenseID response buffer layout +// sense-id response buffer layout // typedef struct { /* common part */ - unsigned char reserved; /* always 0x'FF' */ - unsigned short cu_type; /* control unit type */ - unsigned char cu_model; /* control unit model */ - unsigned short dev_type; /* device type */ - unsigned char dev_model; /* device model */ - unsigned char unused; /* padding byte */ + __u8 reserved; /* always 0x'FF' */ + __u16 cu_type; /* control unit type */ + __u8 cu_model; /* control unit model */ + __u16 dev_type; /* device type */ + __u8 dev_model; /* device model */ + __u8 unused; /* padding byte */ /* extended part */ - ciw_t ciw[62]; /* variable # of CIWs */ -} senseid_t; + ciw_t ciw[MAX_CIWS]; /* variable # of CIWs */ +} __attribute__ ((packed,aligned(4))) senseid_t; + +MAX_CIWS is currently defined as 8. The ESA/390 I/O architecture defines certain device specific I/O functions. The device returns the device specific command code together with the SenseID data in so called Command Information Words (CIW) : typedef struct _ciw { - unsigned int et : 2; // entry type - unsigned int reserved : 2; // reserved - unsigned int ct : 4; // command type - unsigned int cmd : 8; // command - unsigned int count : 16; // count -} ciw_t; + __u32 et : 2; // entry type + __u32 reserved : 2; // reserved + __u32 ct : 4; // command type + __u32 cmd : 8; // command + __u32 count : 16; // count +} __attribute__ ((packed)) ciw_t; Possible CIW entry types are : @@ -245,6 +300,7 @@ -ENODEV - irq or devno don't specify a known subchannel or device number. -EINVAL - invalid devinfo value. +-EUSERS - device is locked by someone else. Usage Notes : @@ -252,7 +308,7 @@ calling get_dev_info() until it returns -ENODEV as there aren't any more available devices. -If a device driver wants to request ownership for a specific device it must +If a device driver wants to request ownership for a specific device, it must call request_irq() prior to be able to issue any I/O request for it, including above mentioned device dependent commands. @@ -269,7 +325,7 @@ numbers configured in the IOCDS. The following routines serve the purpose to convert irq values into device numbers and vice versa. -int get_irq_by_devno( unsigned int devno ); +int get_irq_by_devno( __u16 devno ); unsigned int get_devno_by_irq( int irq ); @@ -336,6 +392,41 @@ he specifies, or the buffer he wants to be allocated. +read_conf_data() - Read Configuration Data + +Retrieve the device dependent configuration data. Please have a look at your +device dependent I/O commands for the device specific layout of the node +descriptor elements. + +The function is meant to be called without an irq handler be in place. However, +the irq for the requested device must not be locked or this will cause a +deadlock situation ! + +The function may be called enabled or disabled. + +int read_conf_data( int irq, void **buffer, int *length, __u8 lpm); + +irq - Specifies the subchannel the configuration data is to be + retrieved for. +buffer - Pointer to a buffer pointer. The read_conf_data() routine + will allocate a buffer and initialize the buffer pointer + accordingly. It's the device driver's responsability to + release the kernel memory if no longer needed. +length - Length of the buffer allocated and retrieved. +lpm - Logical path mask to be used for retrieving the data. If + zero the data is retrieved on the next path available. + +The read_conf_data() function returns : + 0 - Successful completion +-ENODEV - irq doesn't specify a valid subchannel number +-EINVAL - An invalid parameter was detected +-EIO - An irrecoverable I/O error occured or the device is + not operational. +-ENOMEM - The read_conf_data() routine couldn't obtain storage. +-EOPNOTSUPP - The device doesn't support the read configuration + data command. + + request_irq() - Request Device Ownership As previously discussed a device driver will scan for the devices its supports @@ -343,6 +434,9 @@ request_irq() to request ownership for it. This call causes the subchannel to be enabled for interrupts if it was found operational. +Note: This function is obsolete and provided for compatibility purposes only. +Device drivers should use s390_request_irq_special() instead. + int request_irq( unsigned int irq, int (*handler)( int, void *, @@ -354,27 +448,28 @@ irq : specifies the subchannel the ownership is requested for handler : specifies the device driver's interrupt handler to be called for interrupt processing -irqflags : IRQ flags, must be 0 (zero) or SA_SAMPLE_RANDOM +irqflags : IRQ flags, currently ignored devname : device name dev_id : required pointer to a device specific buffer of type devstat_t typedef struct { - unsigned int devno; /* device number from irb */ - unsigned int intparm; /* interrupt parameter */ - unsigned char cstat; /* channel status - accumulated */ - unsigned char dstat; /* device status - accumulated */ - unsigned char lpum; /* last path used mask from irb */ - unsigned char unused; /* not used - reserved */ - unsigned int flag; /* flag : see below */ - unsigned long cpa; /* CCW addr from irb at prim. status */ - unsigned int rescnt; /* count from irb at primary status */ - unsigned int scnt; /* sense count, if available */ + __u16 devno; /* device number, aka. "cuu" from irb */ + unsigned long intparm; /* interrupt parameter */ + __u8 cstat; /* channel status - accumulated */ + __u8 dstat; /* device status - accumulated */ + __u8 lpum; /* last path used mask from irb */ + __u8 unused; /* not used - reserved */ + unsigned int flag; /* flag : see below */ + __u32 cpa; /* CCW address from irb at primary status */ + __u32 rescnt; /* res. count from irb at primary status */ + __u32 scnt; /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */ union { - irb_t irb; /* interruption response block */ - sense_t sense; /* sense information */ - } ii; /* interrupt information */ - } devstat_t; + irb_t irb; /* interruption response block */ + sense_t sense; /* sense information */ + } ii; /* interrupt information */ +} devstat_t; + During request_irq() processing, the devstat_t layout does not matter as it won't be used during request_irq() processing. See do_IO() for a functional @@ -396,9 +491,9 @@ layer, and the device specific driver. The value passed to request_irq() must therefore point to a valid devstat_t type buffer area the device driver must preserve for later usage. I.e. it must not be released prior to a call -to free_irq() +to free_irq(). -The only value parameter irqflags supports is SA_SAMPLE_RANDOM if appropriate. +Irqflags are currently ignored by the cds layer. The Linux/390 kernel does neither know about "fast" interrupt handlers, nor does it allow for interrupt sharing. Remember, the term interrupt level (irq), device, and subchannel are used interchangeably in Linux/390. @@ -416,6 +511,126 @@ therefore not rely on this parameter on function entry. +s390_request_irq_special() - Request Device Ownership + +As previously discussed a device driver will scan for the devices its supports +by calling get_dev_info(). Once it has found a device it will call +request_irq() to request ownership. + +Note: This function replaces request_irq() described previously. + +int s390_request_irq_special( + int irq, + io_handler_func_t io_handler, + not_oper_handler_func_t not_oper_handler, + unsigned long irqflags, + const char *devname, + void *dev_id); + +irq : specifies the subchannel the ownership is + requested for +io_handler : specifies the device driver's interrupt handler + to be called for interrupt processing +not_oper_handler : specifies a device driver "not operational" handler +irqflags : IRQ flags, currently ignored +devname : device name +dev_id : required pointer to a device specific buffer of + type devstat_t + + +typedef struct { + __u16 devno; /* device number, aka. "cuu" from irb */ + unsigned long intparm; /* interrupt parameter */ + __u8 cstat; /* channel status - accumulated */ + __u8 dstat; /* device status - accumulated */ + __u8 lpum; /* last path used mask from irb */ + __u8 unused; /* not used - reserved */ + unsigned int flag; /* flag : see below */ + __u32 cpa; /* CCW address from irb at primary status */ + __u32 rescnt; /* res. count from irb at primary status */ + __u32 scnt; /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */ + union { + irb_t irb; /* interruption response block */ + sense_t sense; /* sense information */ + } ii; /* interrupt information */ +} devstat_t; + +During request_irq() processing, the devstat_t layout does not matter as it +won't be used during request_irq() processing. See do_IO() for a functional +description of its usage. + +typedef void (* io_handler_func_t) ( int irq, + void *devstat, + struct pt_regs *rgs); + +irq : IRQ the interrupt handler is called for +devstat : device status block +rgs : obsolete + +typedef (void)(* not_oper_handler_func_t)( int irq, + int status ); + +irq : IRQ the not operational status has been encountered for +status : device status + DEVSTAT_NOT_OPER - device is not operational + DEVSTAT_REVALIDATE - revalidate device number + DEVSTAT_DEVICE_GONE - no such device (irq) + +Note: Revalidate indicates that running under VM the device number has been +modified by means of a DEFINE xxxx [as] yyyy command. Therewith device number +xxxx was altered to yyyy. It's the device drivers responsibility to decide +whether device ownership can be retained. + +Gone indicates that the device was detached under VM, or the device number +became invalid (native, LPAR). In order to prevent further I/O the IRQ was +implicitly freed on behalf of the device driver. The driver must not call +free_irq itself. + +Not Oper indicates the device became not operational. It's the device driver's +responsibility whether it wants to maintain ownership for the IRQ, or not. + +The s390_request_irq_special() function returns : + 0 - successful completion +-EINVAL - an invalid parameter was detected +-EBUSY - device (subchannel) already owned +-ENODEV - the device is not-operational +-ENOMEM - not enough kernel memory to process request + +Usage Notes : + +While Linux for Intel defines dev_id as a unique identifier for shared +interrupt lines, it has a totally different purpose on Linux for S/390. Here +it serves as a shared interrupt status area between the generic device support +layer and the device specific driver. The value passed to request_irq() must +therefore point to a valid devstat_t type buffer area the device driver must +preserve for later usage. I.e. it must not be released prior to a call to +free_irq(). + +Currently, the value of irqflags is ignored. The Linux for S/390 kernel does +neither know about "fast" interrupt handlers, nor does it allow for interrupt +sharing. Remember, the term interrupt level (irq), device, and subchannel are +used interchangeably in Linux for S/390. + +Other than request_irq(), this function does allow for a not operational +handler to be defined. This handler is called when a device either became not +operational, the last path to a device became not operational, or the device +was detached from the system. A detach could be a "detach" under VM or that +the device became unassigned by the Support Element (SE) or Hardware Management +Console (HMC). + +If s390_request_irq_special() was called in enabled state, or if multiple CPUs +are present, the device may present an interrupt to the specified handler prior +to request_irq() return to the caller already ! This includes the possibility +of unsolicited interrupts or a pending interrupt status from an earlier +solicited I/O request. The device driver must be able to handle this situation +properly or the device may become unoperational otherwise ! + +Although the interrupt handler is defined to be called with a pointer to a +struct pt_regs buffer area, this is not implemented by the Linux for S/390 +platform specific common I/O support layer. The device driver's interrupt +handler must therefore not rely on this parameter on function entry. + + free_irq() - Release Device Ownership A device driver may call free_irq() to release ownership of a previously @@ -523,19 +738,19 @@ int do_IO( int irq, ccw1_t *cpa, - unsigned long intparm, + unsigned long user_intparm, unsigned int lpm, unsigned long flag); -irq : irq (subchannel) the I/O request is destined for -cpa : logical start address of channel program -intparm : user specific interrupt information; will be presented - back to the device driver's interrupt handler. Allows a - device driver to associate the interrupt with a - particular I/O request. -lpm : defines the channel path to be used for a specific I/O - request. Valid with flag value DOIO_VALID_LPM only. -flag : defines the action to e parformed for I/O processing +irq : irq (subchannel) the I/O request is destined for +cpa : logical start address of channel program +user_intparm : user specific interrupt information; will be presented + back to the device driver's interrupt handler. Allows a + device driver to associate the interrupt with a + particular I/O request. +lpm : defines the channel path to be used for a specific I/O + request. Valid with flag value DOIO_VALID_LPM only. +flag : defines the action to e parformed for I/O processing Possible flag values are : @@ -543,16 +758,25 @@ DOIO_VALID_LPM - LPM input parameter is valid (see usage notes below for details) DOIO_WAIT_FOR_INTERRUPT - wait synchronously for final status +DOIO_TIMEOUT - perform a loop while waiting for final status + and fail after a timeout DOIO_REPORT_ALL - report all interrupt conditions +DOIO_ALLOW_SUSPEND - channel program may become suspended +DOIO_DENY_PREFETCH - don't allow for CCW prefetch; usually + this implies the channel program might + become modified +DOIO_CANCEL_ON_TIMEOUT - do a cancel_IO if there is a timeout waiting + for the channel program to finish (see usage + notes below for details) The cpa parameter points to the first format 1 CCW of a channel program : typedef struct { - char cmd_code; /* command code */ - char flags; /* flags, like IDA addressing, etc. */ - unsigned short count; /* byte count */ - void *cda; /* data address */ -} ccw1_t __attribute__ ((aligned(8))); + __u8 cmd_code;/* command code */ + __u8 flags; /* flags, like IDA adressing, etc. */ + __u16 count; /* byte count */ + __u32 cda; /* data address */ +} __attribute__ ((packed,aligned(8))) ccw1_t; with the following CCW flags values defined : @@ -605,6 +829,9 @@ successfully be started previously. DEVSTAT_FINAL_STATUS - This is a final interrupt status for the I/O requst identified by intparm. +DEVSTAT_PCI - A PCI was received. +DEVSTAT_SUSPENDED - A "suspended" intermediate status was + received. If device status DEVSTAT_FLAG_SENSE_AVAIL is indicated in field dev_id->flag, field dev_id->scnt describes the numer of device specific sense bytes @@ -612,9 +839,9 @@ driver itself is required. typedef struct { - unsigned char res[32]; /* reserved */ - unsigned char data[32]; /* sense data */ -} sense_t; + __u8 res[32]; /* reserved */ + __u8 data[32]; /* sense data */ + } __attribute__ ((packed)) sense_t; The device interrupt handler can use the following definitions to investigate the primary unit check source coded in sense byte 0 : @@ -625,6 +852,7 @@ SNS0_EQUIPMENT_CHECK 0x10 SNS0_DATA_CHECK 0x08 SNS0_OVERRUN 0x04 +SNS0_INCOMPL_DOMAIN 0x01 Depending on the device status, multiple of those values may be set together. Please refer to the device specific documentation for details. @@ -661,12 +889,10 @@ Usage Notes : -Prior to call do_IO() the device driver must - -assure disabled state, i.e. the I/O mask value in the PSW must be disabled. -This can be accomplished by calling __save_flags( flags). The current PSW -flags are preserved and can be restored by __restore_flags( flags) at a -later time. +Prior to call do_IO() the device driver must assure disabled state, i.e. the +I/O mask value in the PSW must be disabled. This can be accomplished by calling +__save_flags( flags). The current PSW flags are preserved and can be restored +by __restore_flags( flags) at a later time. If the device driver violates this rule while running in a uni-processor environment an interrupt might be presented prior to the do_IO() routine @@ -674,7 +900,7 @@ deadlock situation as the interrupt handler will try to obtain the irq lock the device driver still owns (see below) ! -the driver must assure to hold the device specific lock. This can be +The driver must assure to hold the device specific lock. This can be accomplished by (i) s390irq_spin_lock( irq), or @@ -705,6 +931,10 @@ is therewith primarily meant to be used during device driver initialization for ease of device setup. +If the device driver is using the DOIO_TIMEOUT parameter, it is a good idea +also to specify DOIO_CANCEL_ON_TIMEOUT. Otherwise, the failing channel program +may prevent the execution of any other channel program at the subchannel. + The lpm input parameter might be used for multipath devices shared among multiple systems as the Linux/390 CDS isn't grouping channel paths. Therefore its use might be required if multiple access paths to a device are available @@ -757,6 +987,34 @@ and dev_id->dstat that represent the accumulated subchannel and device status information gathered since do_IO() request initiation. +Channel programs that intend to set the suspend flag on a channel command word +(CCW) must start the I/O operation with the DOIO_ALLOW_SUSPEND option or the +suspend flag will cause a channel program check. At the time the channel program +becomes suspended an intermediate interrupt will be generated by the channel +subsystem. + +resume_IO() - Resume Channel Program Execution + +If a device driver chooses to suspend the current channel program execution by +setting the CCW suspend flag on a particular CCW, the channel program execution +is suspended. In order to resume channel program execution the CIO layer +provides the resume_IO() routine. + +int resume_IO( int irq); + +irq : irq (subchannel) the halt operation is requested for + +The resume_IO() function returns: + + 0 - suspended channel program is resumed +-EBUSY - status pending +-ENODEV - invalid or not-operational subchannel +-EINVAL - resume function not applicable +-ENOTCONN - there is no I/O request pending for completion + +Usage Notes: +Please have a look at the do_IO() usage notes for more details on suspended +channel programs. halt_IO() - Halt I/O Request Processing @@ -765,9 +1023,9 @@ a halt subchannel (HSCH) I/O command. For those purposes the halt_IO() command is provided. -int halt_IO( int irq, /* subchannel number */ - int intparm, /* dummy intparm */ - unsigned int flag); /* operation mode */ +int halt_IO( int irq, /* subchannel number */ + unsigned long intparm, /* dummy intparm */ + unsigned long flag); /* operation mode */ irq : irq (subchannel) the halt operation is requested for intparm : interruption parameter; value is only used if no I/O @@ -867,7 +1125,7 @@ reset_cons_dev - Reset Console Device This routine allows for resetting the console device specification. See -set_cons_dev() for details. +wait_cons_dev() for details. int reset_cons_dev( int irq); diff -urN linux-2.4.21/Documentation/sonypi.txt linux-2.4.22/Documentation/sonypi.txt --- linux-2.4.21/Documentation/sonypi.txt 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/sonypi.txt 2003-08-25 04:44:39.000000000 -0700 @@ -130,7 +130,7 @@ tested) when using the driver with the fnkeyinit parameter. I cannot reproduce it on my laptop and not all users have this problem. This happens because the fnkeyinit parameter enables the ACPI - mode (but without additionnal ACPI control, like processor + mode (but without additional ACPI control, like processor speed handling etc). Use ACPI instead of APM if it works on your laptop. diff -urN linux-2.4.21/Documentation/sound/Introduction linux-2.4.22/Documentation/sound/Introduction --- linux-2.4.21/Documentation/sound/Introduction 2001-02-16 15:53:08.000000000 -0800 +++ linux-2.4.22/Documentation/sound/Introduction 2003-08-25 04:44:39.000000000 -0700 @@ -80,7 +80,7 @@ additional features. 2. The commercial OSS driver may be obtained from the site: - http://www/opensound.com. This may be used for cards that + http://www.opensound.com. This may be used for cards that are unsupported by the kernel driver, or may be used by other operating systems. diff -urN linux-2.4.21/Documentation/sound/OPL3-SA linux-2.4.22/Documentation/sound/OPL3-SA --- linux-2.4.21/Documentation/sound/OPL3-SA 2000-03-08 11:37:03.000000000 -0800 +++ linux-2.4.22/Documentation/sound/OPL3-SA 2003-08-25 04:44:39.000000000 -0700 @@ -34,7 +34,7 @@ mpu_irq: This is the MPU401's IRQ. If you'd like to use the OPL3 FM Synthesizer, make sure you enable -CONFIG_YM3812 (in 'make config'). That'll build the opl3.o module. +CONFIG_SOUND_YM3812 (in 'make config'). That'll build the opl3.o module. Then a simple 'insmod opl3 io=0x388', and you now have FM Synth. diff -urN linux-2.4.21/Documentation/sound/VIBRA16 linux-2.4.22/Documentation/sound/VIBRA16 --- linux-2.4.21/Documentation/sound/VIBRA16 1999-03-07 15:22:06.000000000 -0800 +++ linux-2.4.22/Documentation/sound/VIBRA16 2003-08-25 04:44:39.000000000 -0700 @@ -62,7 +62,7 @@ Or, take the hard way: -insmod souncore +insmod soundcore insmod sound insmod uart401 insmod sb io=0x220 irq=5 dma=1 dma16=3 diff -urN linux-2.4.21/Documentation/video4linux/bttv/CARDLIST linux-2.4.22/Documentation/video4linux/bttv/CARDLIST --- linux-2.4.21/Documentation/video4linux/bttv/CARDLIST 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/video4linux/bttv/CARDLIST 2003-08-25 04:44:39.000000000 -0700 @@ -30,7 +30,7 @@ card=28 - Terratec TerraTV+ Version 1.1 (bt878) card=29 - Imagenation PXC200 card=30 - Lifeview FlyVideo 98 LR50 - card=31 - Formac iProTV + card=31 - Formac iProTV, Formac ProTV I (bt848) card=32 - Intel Create and Share PCI/ Smart Video Recorder III card=33 - Terratec TerraTValue Version Bt878 card=34 - Leadtek WinFast 2000/ WinFast 2000 XP @@ -94,9 +94,16 @@ card=92 - Osprey 2000 card=93 - IDS Eagle card=94 - Pinnacle PCTV Sat - card=95 - Formac ProTV II + card=95 - Formac ProTV II (bt878) card=96 - MachTV card=97 - Euresys Picolo + card=98 - ProVideo PV150 + card=99 - AD-TVK503 + card=100 - Hercules Smart TV Stereo + card=101 - Pace TV & Radio Card + card=102 - IVC-200 + card=103 - Grand X-Guard / Trust 814PCI + card=104 - Nebula Electronics DigiTV tuner.o type=0 - Temic PAL (4002 FH5) @@ -139,3 +146,4 @@ type=37 - LG PAL (newer TAPC series) type=38 - Philips PAL/SECAM multi (FM1216ME MK3) type=39 - LG NTSC (newer TAPC series) + type=40 - HITACHI V7-J180AT diff -urN linux-2.4.21/Documentation/video4linux/bttv/Sound-FAQ linux-2.4.22/Documentation/video4linux/bttv/Sound-FAQ --- linux-2.4.21/Documentation/video4linux/bttv/Sound-FAQ 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/Documentation/video4linux/bttv/Sound-FAQ 2003-08-25 04:44:39.000000000 -0700 @@ -15,18 +15,18 @@ bttv0: model: BT848(Hauppauge old) [autodetected] -You should verify this is correct. If it is'nt, you have to pass the +You should verify this is correct. If it isn't, you have to pass the correct board type as insmod argument, "insmod bttv card=2" for example. The file CARDLIST has a list of valid arguments for card. -If your card is'nt listed there, you might check the source code for -new entries which are not listed yet. If there is'nt one for your +If your card isn't listed there, you might check the source code for +new entries which are not listed yet. If there isn't one for your card, you can check if one of the existing entries does work for you (just trial and error...). Some boards have an extra processor for sound to do stereo decoding and other nice features. The msp34xx chips are used by Hauppauge for example. If your board has one, you might have to load a helper -module like msp3400.o to make sound work. If there is'nt one for the +module like msp3400.o to make sound work. If there isn't one for the chip used on your board: Bad luck. Start writing a new one. Well, you might want to check the video4linux mailing list archive first... @@ -121,7 +121,7 @@ video_inputs - # of video inputs the card has audio_inputs - historical cruft, not used any more. tuner - which input is the tuner -svhs - which input is svhs (all others are labled composite) +svhs - which input is svhs (all others are labeled composite) muxsel - video mux, input->registervalue mapping pll - same as pll= insmod option tuner_type - same as tuner= insmod option diff -urN linux-2.4.21/Documentation/x86_64/boot-options.txt linux-2.4.22/Documentation/x86_64/boot-options.txt --- linux-2.4.21/Documentation/x86_64/boot-options.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/Documentation/x86_64/boot-options.txt 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,151 @@ +AMD64 specific boot options + +There are many others (usually documented in driver documentation), but +only the AMD64 specific ones are listed here. + +Machine check + +(see the Opteron BIOS&Kernel manual for more details on the banks etc.) + + mce=off disable machine check + mce=nok8 disable k8 specific features + mce=disable disable bank NUMBER + mce=enable enable bank number + mce=device Enable more machine check options in Northbridge. + Can be useful for device driver debugging. + mce=NUMBER mcheck timer interval number seconds. + Can be also comma separated in a single mce= + + nomce (for compatibility with i386): same as mce=off + +APICs + + nolocalapic Don't use a local or IO-APIC. This should only + be needed if you have a buggy BIOS. The newer + kernels already turn it off by default if the + BIOS didn't enable the local APIC, so it will + be hopefully not needed. + Note this code path is not very well tested, you are on + your own. + + apic Use IO-APIC. Default + + noapic Don't use the IO-APIC. + Also only lightly tested. + + pirq=... See Documentation/i386/IO-APIC.txt + +Early Console + + syntax: earlyprintk=vga + earlyprintk=serial[,ttySn[,baudrate]] + + The early console is useful when the kernel crashes before the + normal console is initialized. It is not enabled by + default because it has some cosmetic problems. + Append ,keep to not disable it when the real console takes over. + Only vga or serial at a time, not both. + Currently only ttyS0 and ttyS1 are supported. + Interaction with the standard serial driver is not very good. + The VGA output is eventually overwritten by the real console. + +Timing + + notsc + Don't use the CPU time stamp counter to read the wall time. + This can be used to work around timing problems on multiprocessor systems + with not properly synchronized CPUs. Only useful with a SMP kernel + + report_lost_ticks + Report when timer interrupts are lost because some code turned off + interrupts for too long. + + nmi_watchdog=NUMBER + NUMBER can be: + 0 don't use an NMI watchdog + 1 use the IO-APIC timer for the NMI watchdog + 2 use the local APIC for the NMI watchdog using a performance counter. Note + This will use one performance counter. + +Idle loop + + idle=poll + Don't do power saving in the idle loop using HLT, but poll for rescheduling + event. This will make the CPUs eat a lot more power, but may be useful + to get slightly better performance in multiprocessor benchmarks. It also + makes some profiling using performance counters more accurate. + +Rebooting + + reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old] + bios Use the CPU reboto vector for warm reset + warm Don't set the cold reboot flag + cold Set the cold reboto flag + triple Force a triple fault (init) + kbd Use the keyboard controller. cold reset (default) + + Using warm reset will be much faster especially on big memory + systems because the BIOS will not go through the memory check. + Disadvantage is that not all hardware will be completely reinitialized + on reboot so there may be boot problems on some systems. + +Non Executable Mappings + + noexec=on|off + + on Enable + off Disable + noforce (default) Don't enable by default for heap/stack/data, + but allow PROT_EXEC to be effective + + noexec32=opt{,opt} + + Control the no exec default for 32bit processes. + Requires noexec=on or noexec=noforce to be effective. + + Valid options: + all,on Heap,stack,data is non executable. + off (default) Heap,stack,data is executable + stack Stack is non executable, heap/data is. + force Don't imply PROT_EXEC for PROT_READ + compat (default) Imply PROT_EXEC for PROT_READ + +SMP + + nosmp Only use a single CPU + + maxcpus=NUMBER only use upto NUMBER CPUs + + cpumask=MASK only use cpus with bits set in mask + +NUMA + + numa=off Only set up a single NUMA node spanning all memory. + + +ACPI + + acpi=off Don't enable ACPI + +PCI + + pci=off Don't use PCI + pci=conf1 Use conf1 access. + pci=conf2 Use conf2 access. + pci=rom Assign ROMs. + pci=assign-busses Assign busses + pci=irqmask=MASK Set PCI interrupt mask to MASK + pci=lastbus=NUMBER Scan upto NUMBER busses, no matter what the mptable says. + +IOMMU + + iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]] + size set size of iommu (in bytes) + noagp don't initialize the AGP driver and use full aperture. + off don't use the IOMMU + leak turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on) + memaper[=order] allocate an own aperture over RAM with size 32MB^order. + noforce don't force IOMMU usage. Should be fastest. + force Force IOMMU and turn on unmap debugging. + + diff -urN linux-2.4.21/MAINTAINERS linux-2.4.22/MAINTAINERS --- linux-2.4.21/MAINTAINERS 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/MAINTAINERS 2003-08-25 04:44:39.000000000 -0700 @@ -78,12 +78,6 @@ W: http://www.linuxtr.net S: Maintained -3C501 NETWORK DRIVER -P: Alan Cox -M: alan@lxorguk.ukuu.org.uk -L: linux-net@vger.kernel.org -S: Maintained for 2.2 only - 3C505 NETWORK DRIVER P: Philip Blundell M: Philip.Blundell@pobox.com @@ -206,6 +200,21 @@ L: linux-scsi@vger.kernel.org S: Maintained +ALCATEL SPEEDTOUCH USB DRIVER +P: Duncan Sands +M: duncan.sands@wanadoo.fr +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net +W: http://www.linux-usb.org/SpeedTouch/ +S: Maintained + +AIPTEK USB TABLET DRIVER +P: Bryan W. Headley +M: Bryan W. Headley +W: http://aiptektablet.sourceforge.net +L: aiptektablet-users@sourceforge.net +S: Maintained + ALTERA EPXA1/EPXA10 DEVELOPMENT BOARD PORT P: Clive Davies M: cdavies@altera.com @@ -302,18 +311,78 @@ L: linux-kernel@vger.kernel.org S: Maintained -BLUETOOTH SUBSYSTEM (BlueZ) +BLUETOOTH SUBSYSTEM +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH RFCOMM LAYER +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH BNEP LAYER P: Maxim Krasnyansky M: maxk@qualcomm.com W: http://bluez.sf.net S: Maintained -BLUETOOTH SUBSYSTEM (PC Card Drivers) +BLUETOOTH CMTP LAYER +P: Marcel Holtmann +M: marcel@holtmann.org +W: http://www.holtmann.org/linux/bluetooth/ +S: Maintained + +BLUETOOTH HCI USB DRIVER +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH HCI UART DRIVER +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + +BLUETOOTH HCI BFUSB DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org +W: http://www.holtmann.org/linux/bluetooth/ +S: Maintained + +BLUETOOTH HCI DTL1 DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org +W: http://www.holtmann.org/linux/bluetooth/ +S: Maintained + +BLUETOOTH HCI BLUECARD DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org +W: http://www.holtmann.org/linux/bluetooth/ +S: Maintained + +BLUETOOTH HCI BT3C DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org +W: http://www.holtmann.org/linux/bluetooth/ +S: Maintained + +BLUETOOTH HCI BTUART DRIVER P: Marcel Holtmann M: marcel@holtmann.org W: http://www.holtmann.org/linux/bluetooth/ S: Maintained +BLUETOOTH HCI VHCI DRIVER +P: Maxim Krasnyansky +M: maxk@qualcomm.com +W: http://bluez.sf.net +S: Maintained + BONDING DRIVER P: Chad Tindel M: ctindel@users.sourceforge.net @@ -381,8 +450,8 @@ S: Supported COMX/MULTIGATE SYNC SERIAL DRIVERS -P: Gergely Madarasz -M: Gergely Madarasz +P: Pasztor Szilard +M: Pasztor Szilard S: Supported CONFIGURE, MENUCONFIG, XCONFIG @@ -430,6 +499,15 @@ W: http://developer.axis.com S: Maintained +CRYPTO API +P: James Morris +M: jmorris@intercode.com.au +P: David S. Miller +M: davem@redhat.com +W http://samba.org/~jamesm/crypto/ +L: linux-kernel@vger.kernel.org +S: Maintained + CYBERPRO FB DRIVER P: Russell King M: rmk@arm.linux.org.uk @@ -676,8 +754,8 @@ S: Maintained HFS FILESYSTEM -P: Oliver Neukum -M: oliver@neukum.org +P: Roman Zippel +P: zippel@linux-m68k.org L: linux-kernel@vger.kernel.org S: Maintained @@ -825,7 +903,7 @@ IMS TWINTURBO FRAMEBUFFER DRIVER P: Paul Mundt -M: lethal@chaoticdreams.org +M: lethal@linux-sh.org L: linux-fbdev-devel@lists.sourceforge.net S: Maintained @@ -1183,6 +1261,8 @@ M: pekkas@netcore.fi P: James Morris M: jmorris@intercode.com.au +P: Hideaki YOSHIFUJI +M: yoshfuji@linux-ipv6.org L: netdev@oss.sgi.com S: Maintained @@ -1364,9 +1444,9 @@ P: M. R. Brown M: mrbrown@0xd6.org P: Paul Mundt -M: lethal@0xd6.org +M: lethal@linux-sh.org L: linux-fbdev-devel@lists.sourceforge.net -W: http://www.linuxdc.org +L: linuxsh-dev@lists.sourceforge.net S: Maintained PPP PROTOCOL DRIVERS AND COMPRESSORS @@ -1400,13 +1480,13 @@ RADEON FRAMEBUFFER DISPLAY DRIVER P: Ani Joshi -M: ajoshi@shell.unixbox.com +M: ajoshi@kernel.crashing.org L: linux-fbdev-devel@lists.sourceforge.net S: Maintained RAGE128 FRAMEBUFFER DISPLAY DRIVER P: Ani Joshi -M: ajoshi@shell.unixbox.com +M: ajoshi@kernel.crashing.org L: linux-fbdev-devel@lists.sourceforge.net S: Maintained @@ -1499,7 +1579,7 @@ SCSI TAPE DRIVER P: Kai Mäkisara -M: Kai.Makisara@metla.fi +M: Kai.Makisara@kolumbus.fi L: linux-scsi@vger.kernel.org S: Maintained @@ -1569,11 +1649,6 @@ W: http://popies.net/sonypi/ S: Maintained -SOUND -P: Alan Cox -M: alan@redhat.com -S: Maintained for 2.2 only - UltraSPARC (sparc64): P: David S. Miller M: davem@redhat.com @@ -1631,19 +1706,35 @@ W: http://www.stradis.com/ S: Maintained -SUPERH +SUPERH (sh) +P: Paul Mundt +M: lethal@linux-sh.org P: Niibe Yutaka M: gniibe@m17n.org P: Kazumoto Kojima M: kkojima@rr.iij4u.or.jp +L: linuxsh-dev@lists.sourceforge.net L: linux-sh@m17n.org +W: http://www.linux-sh.org W: http://www.m17n.org/linux-sh/ W: http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html S: Maintained +SUPERH64 (sh64) +P: Paul Mundt +M: lethal@linux-sh.org +P: Richard Curnow +M: richard.curnow@superh.com +P: Benedict Gaster +M: benedict.gaster@superh.com +L: linuxsh-shmedia-dev@lists.sourceforge.net +W: http://www.linux-sh.org +W: http://linux-shmedia.bkbits.net +S: Maintained + SUPERH WATCHDOG P: Paul Mundt -M: lethal@0xd6.org +M: lethal@linux-sh.org L: linuxsh-dev@lists.sourceforge.net W: http://www.linuxsh.org S: Maintained @@ -1706,6 +1797,12 @@ W: http://www.linuxtr.net S: Maintained +TOSHIBA ACPI EXTRAS DRIVER +P: John Belmonte +M: toshiba_acpi@memebeam.org +W: http://memebeam.org/toys/ToshibaAcpiDriver +S: Maintained + TOSHIBA SMM DRIVER P: Jonathan Buzzard M: jonathan@buzzard.org.uk @@ -1783,7 +1880,7 @@ L: linux-usb-devel@lists.sourceforge.net S: Maintained -USB BLUETOOTH DRIVER +USB BLUETOOTH TTY CONVERTER DRIVER P: Greg Kroah-Hartman M: greg@kroah.com L: linux-usb-users@lists.sourceforge.net @@ -2032,12 +2129,6 @@ L: linux-kernel@vger.kernel.org S: Maintained -Z85230 SYNCHRONOUS DRIVER -P: Alan Cox -M: alan@redhat.com -W: http://roadrunner.swansea.linux.org.uk/synchronous.shtml -S: Maintained for 2.2 only - Z8530 DRIVER FOR AX.25 P: Joerg Reuter M: jreuter@yaina.de diff -urN linux-2.4.21/Makefile linux-2.4.22/Makefile --- linux-2.4.21/Makefile 2003-06-13 07:51:39.000000000 -0700 +++ linux-2.4.22/Makefile 2003-08-25 04:44:44.000000000 -0700 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 4 -SUBLEVEL = 21 +SUBLEVEL = 22 EXTRAVERSION = KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -40,10 +40,13 @@ MODFLAGS = -DMODULE CFLAGS_KERNEL = PERL = perl +AWK = awk +RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \ + else echo rpm; fi) export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \ CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \ - CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL + CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL AWK all: do-it-all @@ -125,14 +128,14 @@ NETWORKS =net/network.o LIBS =$(TOPDIR)/lib/lib.a -SUBDIRS =kernel drivers mm fs net ipc lib +SUBDIRS =kernel drivers mm fs net ipc lib crypto DRIVERS-n := DRIVERS-y := DRIVERS-m := DRIVERS- := -DRIVERS-$(CONFIG_ACPI) += drivers/acpi/acpi.o +DRIVERS-$(CONFIG_ACPI_BOOT) += drivers/acpi/acpi.o DRIVERS-$(CONFIG_PARPORT) += drivers/parport/driver.o DRIVERS-y += drivers/char/char.o \ drivers/block/block.o \ @@ -190,6 +193,7 @@ DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o +DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o DRIVERS := $(DRIVERS-y) @@ -226,6 +230,7 @@ # files removed with 'make mrproper' MRPROPER_FILES = \ include/linux/autoconf.h include/linux/version.h \ + lib/crc32table.h lib/gen_crc32table \ drivers/net/hamradio/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h \ drivers/net/hamradio/soundmodem/sm_tbl_{hapn4800,psk4800}.h \ drivers/net/hamradio/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h \ @@ -570,5 +575,5 @@ rm $(KERNELPATH) ; \ cd $(TOPDIR) ; \ . scripts/mkversion > .version ; \ - rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \ + $(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \ rm $(TOPDIR)/../$(KERNELPATH).tar.gz diff -urN linux-2.4.21/README linux-2.4.22/README --- linux-2.4.21/README 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/README 2003-08-25 04:44:39.000000000 -0700 @@ -64,12 +64,12 @@ - You can also upgrade between 2.4.xx releases by patching. Patches are distributed in the traditional gzip and the new bzip2 format. To install by patching, get all the newer patch files, enter the - directory in which you unpacked the kernel source and execute: + top level directory of the kernel source (linux-2.4.xx) and execute: - gzip -cd patchXX.gz | patch -p0 + gzip -cd ../patch-2.4.xx.gz | patch -p1 or - bzip2 -dc patchXX.bz2 | patch -p0 + bzip2 -dc ../patch-2.4.xx.bz2 | patch -p1 (repeat xx for all versions bigger than the version of your current source tree, _in_order_) and you should be ok. You may want to remove diff -urN linux-2.4.21/arch/alpha/config.in linux-2.4.22/arch/alpha/config.in --- linux-2.4.21/arch/alpha/config.in 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/config.in 2003-08-25 04:44:39.000000000 -0700 @@ -42,6 +42,7 @@ Eiger CONFIG_ALPHA_EIGER \ Jensen CONFIG_ALPHA_JENSEN \ LX164 CONFIG_ALPHA_LX164 \ + Lynx CONFIG_ALPHA_LYNX \ Marvel CONFIG_ALPHA_MARVEL \ Miata CONFIG_ALPHA_MIATA \ Mikasa CONFIG_ALPHA_MIKASA \ @@ -157,6 +158,16 @@ fi define_bool CONFIG_ALPHA_T2 y fi +if [ "$CONFIG_ALPHA_LYNX" = "y" ] +then + bool 'EV5 CPU(s) (model 5/xxx)?' CONFIG_ALPHA_EV5 + if [ "$CONFIG_ALPHA_EV5" != "y" ] + then + define_bool CONFIG_ALPHA_EV4 y + fi + define_bool CONFIG_ALPHA_GAMMA y + define_bool CONFIG_ALPHA_T2 y +fi if [ "$CONFIG_ALPHA_MIATA" = "y" -o "$CONFIG_ALPHA_LX164" = "y" \ -o "$CONFIG_ALPHA_SX164" = "y" -o "$CONFIG_ALPHA_RUFFIAN" = "y" ] then @@ -216,7 +227,7 @@ -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \ -o "$CONFIG_ALPHA_EIGER" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" \ -o "$CONFIG_ALPHA_TITAN" = "y" -o "$CONFIG_ALPHA_SHARK" = "y" \ - -o "$CONFIG_ALPHA_MARVEL" = "y" ] + -o "$CONFIG_ALPHA_MARVEL" = "y" -o "$CONFIG_ALPHA_LYNX" = "y" ] then define_bool CONFIG_ALPHA_SRM y fi @@ -234,7 +245,7 @@ if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \ -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \ - -o "$CONFIG_ALPHA_RAWHIDE" = "y" ] + -o "$CONFIG_ALPHA_RAWHIDE" = "y" -o "$CONFIG_ALPHA_LYNX" = "y" ] then define_bool CONFIG_ALPHA_EISA y fi @@ -250,7 +261,8 @@ if [ "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \ -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" \ -o "$CONFIG_ALPHA_TITAN" = "y" -o "$CONFIG_ALPHA_GENERIC" = "y" \ - -o "$CONFIG_ALPHA_SHARK" = "y" -o "$CONFIG_ALPHA_MARVEL" = "y" ] + -o "$CONFIG_ALPHA_SHARK" = "y" -o "$CONFIG_ALPHA_MARVEL" = "y" \ + -o "$CONFIG_ALPHA_LYNX" = "y" ] then bool 'Symmetric multi-processing support' CONFIG_SMP fi @@ -355,7 +367,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -443,4 +455,5 @@ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/alpha/kernel/Makefile linux-2.4.22/arch/alpha/kernel/Makefile --- linux-2.4.21/arch/alpha/kernel/Makefile 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -24,8 +24,7 @@ # FIXME! # These should be made conditional on the stuff that needs them! # -obj-y += irq_i8259.o irq_srm.o \ - es1888.o smc37c669.o smc37c93x.o ns87312.o +obj-y += irq_i8259.o irq_srm.o ifdef CONFIG_VGA_HOSE obj-y += console.o @@ -46,7 +45,8 @@ sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \ sys_wildfire.o sys_marvel.o \ err_titan.o err_marvel.o \ - irq_pyxis.o srmcons.o gct.o + irq_pyxis.o srmcons.o gct.o \ + es1888.o smc37c669.o smc37c93x.o ns87312.o else @@ -93,7 +93,10 @@ obj-$(CONFIG_ALPHA_RAWHIDE) += sys_rawhide.o obj-$(CONFIG_ALPHA_RUFFIAN) += sys_ruffian.o obj-$(CONFIG_ALPHA_RX164) += sys_rx164.o -obj-$(CONFIG_ALPHA_SABLE) += sys_sable.o + +ifneq ($(CONFIG_ALPHA_SABLE)$(CONFIG_ALPHA_LYNX),) +obj-y += sys_sable.o +endif ifneq ($(CONFIG_ALPHA_BOOK1)$(CONFIG_ALPHA_AVANTI)$(CONFIG_ALPHA_NONAME)$(CONFIG_ALPHA_P2K)$(CONFIG_ALPHA_XL),) obj-y += sys_sio.o @@ -107,6 +110,22 @@ obj-y += irq_pyxis.o endif +ifneq ($(CONFIG_ALPHA_MIATA)$(CONFIG_ALPHA_DP264),) +obj-y += es1888.o +endif + +ifneq ($(CONFIG_ALPHA_DP264)$(CONFIG_ALPHA_MIATA)$(CONFIG_ALPHA_SX164)$(CONFIG_ALPHA_TITAN),) +obj-y += smc37c669.o +endif + +ifneq ($(CONFIG_ALPHA_PC164)$(CONFIG_ALPHA_LX164),) +obj-y += smc37c93x.o +endif + +ifneq ($(CONFIG_ALPHA_NONAME)$(CONFIG_ALPHA_EB164)$(CONFIG_ALPHA_AVANTI)$(CONFIG_ALPHA_P2K)$(CONFIG_ALPHA_XL)$(CONFIG_ALPHA_TAKARA),) +obj-y += ns87312.o +endif + endif # GENERIC all: kernel.o head.o diff -urN linux-2.4.21/arch/alpha/kernel/core_cia.c linux-2.4.22/arch/alpha/kernel/core_cia.c --- linux-2.4.21/arch/alpha/kernel/core_cia.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/core_cia.c 2003-08-25 04:44:39.000000000 -0700 @@ -47,15 +47,6 @@ #define vip volatile int * -/* Save CIA configuration data as the console had it set up. */ - -struct -{ - unsigned int w_base; - unsigned int w_mask; - unsigned int t_base; -} saved_config[4] __attribute((common)); - /* * Given a bus, device, and function number, compute resulting * configuration space address. It is therefore not safe to have @@ -610,6 +601,74 @@ goto exit; } +#ifdef ALPHA_RESTORE_SRM_SETUP +/* Save CIA configuration data as the console had it set up. */ +struct +{ + unsigned int hae_mem; + unsigned int hae_io; + unsigned int pci_dac_offset; + unsigned int err_mask; + unsigned int cia_ctrl; + unsigned int cia_cnfg; + struct { + unsigned int w_base; + unsigned int w_mask; + unsigned int t_base; + } window[4]; +} saved_config __attribute((common)); + +void +cia_save_srm_settings(int is_pyxis) +{ + int i; + + /* Save some important registers. */ + saved_config.err_mask = *(vip)CIA_IOC_ERR_MASK; + saved_config.cia_ctrl = *(vip)CIA_IOC_CIA_CTRL; + saved_config.hae_mem = *(vip)CIA_IOC_HAE_MEM; + saved_config.hae_io = *(vip)CIA_IOC_HAE_IO; + saved_config.pci_dac_offset = *(vip)CIA_IOC_PCI_W_DAC; + + saved_config.cia_cnfg = is_pyxis ? *(vip)CIA_IOC_CIA_CNFG : 0; + + /* Save DMA windows configuration. */ + for (i = 0; i < 4; i++) { + saved_config.window[i].w_base = *(vip)CIA_IOC_PCI_Wn_BASE(i); + saved_config.window[i].w_mask = *(vip)CIA_IOC_PCI_Wn_MASK(i); + saved_config.window[i].t_base = *(vip)CIA_IOC_PCI_Tn_BASE(i); + } + mb(); +} + +void +cia_restore_srm_settings(void) +{ + int i; + + for (i = 0; i < 4; i++) { + *(vip)CIA_IOC_PCI_Wn_BASE(i) = saved_config.window[i].w_base; + *(vip)CIA_IOC_PCI_Wn_MASK(i) = saved_config.window[i].w_mask; + *(vip)CIA_IOC_PCI_Tn_BASE(i) = saved_config.window[i].t_base; + } + + *(vip)CIA_IOC_HAE_MEM = saved_config.hae_mem; + *(vip)CIA_IOC_HAE_IO = saved_config.hae_io; + *(vip)CIA_IOC_PCI_W_DAC = saved_config.pci_dac_offset; + *(vip)CIA_IOC_ERR_MASK = saved_config.err_mask; + *(vip)CIA_IOC_CIA_CTRL = saved_config.cia_ctrl; + + if (saved_config.cia_cnfg) /* Must be pyxis. */ + *(vip)CIA_IOC_CIA_CNFG = saved_config.cia_cnfg; + + mb(); +} +#else /* ALPHA_RESTORE_SRM_SETUP */ +#define cia_save_srm_settings(p) do {} while (0) +#define cia_restore_srm_settings() do {} while (0) +#endif /* ALPHA_RESTORE_SRM_SETUP */ + + static void __init do_init_arch(int is_pyxis) { @@ -620,6 +679,9 @@ printk("pci: cia revision %d%s\n", cia_rev, is_pyxis ? " (pyxis)" : ""); + if (alpha_using_srm) + cia_save_srm_settings(is_pyxis); + /* Set up error reporting. */ temp = *(vip)CIA_IOC_ERR_MASK; temp &= ~(CIA_ERR_CPU_PE | CIA_ERR_MEM_NEM | CIA_ERR_PA_PTE_INV @@ -689,24 +751,6 @@ hose->dense_io_base = CIA_BW_IO - IDENT_ADDR; } - /* Save CIA configuration data as the console had it set up. */ - - saved_config[0].w_base = *(vip)CIA_IOC_PCI_W0_BASE; - saved_config[0].w_mask = *(vip)CIA_IOC_PCI_W0_MASK; - saved_config[0].t_base = *(vip)CIA_IOC_PCI_T0_BASE; - - saved_config[1].w_base = *(vip)CIA_IOC_PCI_W1_BASE; - saved_config[1].w_mask = *(vip)CIA_IOC_PCI_W1_MASK; - saved_config[1].t_base = *(vip)CIA_IOC_PCI_T1_BASE; - - saved_config[2].w_base = *(vip)CIA_IOC_PCI_W2_BASE; - saved_config[2].w_mask = *(vip)CIA_IOC_PCI_W2_MASK; - saved_config[2].t_base = *(vip)CIA_IOC_PCI_T2_BASE; - - saved_config[3].w_base = *(vip)CIA_IOC_PCI_W3_BASE; - saved_config[3].w_mask = *(vip)CIA_IOC_PCI_W3_MASK; - saved_config[3].t_base = *(vip)CIA_IOC_PCI_T3_BASE; - /* * Set up the PCI to main memory translation windows. * @@ -804,21 +848,8 @@ void cia_kill_arch(int mode) { - *(vip)CIA_IOC_PCI_W0_BASE = saved_config[0].w_base; - *(vip)CIA_IOC_PCI_W0_MASK = saved_config[0].w_mask; - *(vip)CIA_IOC_PCI_T0_BASE = saved_config[0].t_base; - - *(vip)CIA_IOC_PCI_W1_BASE = saved_config[1].w_base; - *(vip)CIA_IOC_PCI_W1_MASK = saved_config[1].w_mask; - *(vip)CIA_IOC_PCI_T1_BASE = saved_config[1].t_base; - - *(vip)CIA_IOC_PCI_W2_BASE = saved_config[2].w_base; - *(vip)CIA_IOC_PCI_W2_MASK = saved_config[2].w_mask; - *(vip)CIA_IOC_PCI_T2_BASE = saved_config[2].t_base; - - *(vip)CIA_IOC_PCI_W3_BASE = saved_config[3].w_base; - *(vip)CIA_IOC_PCI_W3_MASK = saved_config[3].w_mask; - *(vip)CIA_IOC_PCI_T3_BASE = saved_config[3].t_base; + if (alpha_using_srm) + cia_restore_srm_settings(); } void __init diff -urN linux-2.4.21/arch/alpha/kernel/core_lca.c linux-2.4.22/arch/alpha/kernel/core_lca.c --- linux-2.4.21/arch/alpha/kernel/core_lca.c 2001-03-02 11:12:07.000000000 -0800 +++ linux-2.4.22/arch/alpha/kernel/core_lca.c 2003-08-25 04:44:39.000000000 -0700 @@ -282,7 +282,7 @@ lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); - *(vip)LCA_IOC_TBIA = 0; + *(vulp)LCA_IOC_TBIA = 0; mb(); } @@ -308,21 +308,25 @@ /* * Set up the PCI to main memory translation windows. * - * Window 0 is direct access 1GB at 1GB - * Window 1 is scatter-gather 8MB at 8MB (for isa) + * Mimic the SRM settings for the direct-map window. + * Window 0 is scatter-gather 8MB at 8MB (for isa). + * Window 1 is direct access 1GB at 1GB. + * + * Note that we do not try to save any of the DMA window CSRs + * before setting them, since we cannot read those CSRs on LCA. */ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); hose->sg_pci = NULL; __direct_map_base = 0x40000000; __direct_map_size = 0x40000000; - *(vulp)LCA_IOC_W_BASE0 = __direct_map_base | (2UL << 32); - *(vulp)LCA_IOC_W_MASK0 = (__direct_map_size - 1) & 0xfff00000; - *(vulp)LCA_IOC_T_BASE0 = 0; - - *(vulp)LCA_IOC_W_BASE1 = hose->sg_isa->dma_base | (3UL << 32); - *(vulp)LCA_IOC_W_MASK1 = (hose->sg_isa->size - 1) & 0xfff00000; - *(vulp)LCA_IOC_T_BASE1 = virt_to_phys(hose->sg_isa->ptes); + *(vulp)LCA_IOC_W_BASE0 = hose->sg_isa->dma_base | (3UL << 32); + *(vulp)LCA_IOC_W_MASK0 = (hose->sg_isa->size - 1) & 0xfff00000; + *(vulp)LCA_IOC_T_BASE0 = virt_to_phys(hose->sg_isa->ptes); + + *(vulp)LCA_IOC_W_BASE1 = __direct_map_base | (2UL << 32); + *(vulp)LCA_IOC_W_MASK1 = (__direct_map_size - 1) & 0xfff00000; + *(vulp)LCA_IOC_T_BASE1 = 0; *(vulp)LCA_IOC_TB_ENA = 0x80; @@ -334,6 +338,15 @@ * data parity errors. */ *(vulp)LCA_IOC_PAR_DIS = 1UL<<5; + + /* + * Finally, set up for restoring the correct HAE if using SRM. + * Again, since we cannot read many of the CSRs on the LCA, + * one of which happens to be the HAE, we save the value that + * the SRM will expect... + */ + if (alpha_using_srm) + srm_hae = 0x80000000UL; } /* diff -urN linux-2.4.21/arch/alpha/kernel/core_t2.c linux-2.4.22/arch/alpha/kernel/core_t2.c --- linux-2.4.21/arch/alpha/kernel/core_t2.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/core_t2.c 2003-08-25 04:44:39.000000000 -0700 @@ -17,6 +17,7 @@ #include #include +#include #define __EXTERN_INLINE #include @@ -26,6 +27,12 @@ #include "proto.h" #include "pci_impl.h" +/* For dumping initial DMA window settings. */ +#define DEBUG_PRINT_INITIAL_SETTINGS 0 + +/* For dumping final DMA window settings. */ +#define DEBUG_PRINT_FINAL_SETTINGS 0 + /* * By default, we direct-map starting at 2GB, in order to allow the * maximum size direct-map window (2GB) to match the maximum amount of @@ -34,11 +41,23 @@ * ISA DMA, since the maximum ISA DMA address is 2GB-1. * * For now, this seems a reasonable trade-off: even though most SABLEs - * have far less than even 1GB of memory, floppy usage/performance will - * not really be affected by forcing it to go via scatter/gather... + * have less than 1GB of memory, floppy usage/performance will not + * really be affected by forcing it to go via scatter/gather... */ #define T2_DIRECTMAP_2G 1 +#if T2_DIRECTMAP_2G +# define T2_DIRECTMAP_START 0x80000000UL +# define T2_DIRECTMAP_LENGTH 0x80000000UL +#else +# define T2_DIRECTMAP_START 0x40000000UL +# define T2_DIRECTMAP_LENGTH 0x40000000UL +#endif + +/* The ISA scatter/gather window settings. */ +#define T2_ISA_SG_START 0x00800000UL +#define T2_ISA_SG_LENGTH 0x00800000UL + /* * NOTE: Herein lie back-to-back mb instructions. They are magic. * One plausible explanation is that the i/o controller does not properly @@ -57,6 +76,24 @@ # define DBG(args) #endif +static volatile unsigned int t2_mcheck_any_expected; +static volatile unsigned int t2_mcheck_last_taken; + +/* Place to save the DMA Window registers as set up by SRM + for restoration during shutdown. */ +static struct +{ + struct { + unsigned long wbase; + unsigned long wmask; + unsigned long tbase; + } window[2]; + unsigned long hae_1; + unsigned long hae_2; + unsigned long hae_3; + unsigned long hae_4; + unsigned long hbase; +} t2_saved_config __attribute((common)); /* * Given a bus, device, and function number, compute resulting @@ -135,42 +172,34 @@ return 0; } +/* + * NOTE: both conf_read() and conf_write() may set HAE_3 when needing + * to do type1 access. This is protected by the use of spinlock IRQ + * primitives in the wrapper functions pci_{read,write}_config_*() + * defined in drivers/pci/pci.c. + */ static unsigned int conf_read(unsigned long addr, unsigned char type1) { - unsigned long flags; - unsigned int value, cpu; + unsigned int value, cpu, taken; unsigned long t2_cfg = 0; cpu = smp_processor_id(); - __save_and_cli(flags); /* avoid getting hit by machine check */ - DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); -#if 0 - { - unsigned long stat0; - /* Reset status register to avoid losing errors. */ - stat0 = *(vulp)T2_IOCSR; - *(vulp)T2_IOCSR = stat0; - mb(); - DBG(("conf_read: T2 IOCSR was 0x%x\n", stat0)); - } -#endif - /* If Type1 access, must set T2 CFG. */ if (type1) { t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL; *(vulp)T2_HAE_3 = 0x40000000UL | t2_cfg; mb(); - DBG(("conf_read: TYPE1 access\n")); } mb(); draina(); mcheck_expected(cpu) = 1; mcheck_taken(cpu) = 0; + t2_mcheck_any_expected |= (1 << cpu); mb(); /* Access configuration space. */ @@ -178,12 +207,20 @@ mb(); mb(); /* magic */ - if (mcheck_taken(cpu)) { + /* Wait for possible mcheck. Also, this lets other CPUs clear + their mchecks as well, as they can reliably tell when + another CPU is in the midst of handling a real mcheck via + the "taken" function. */ + udelay(100); + + if ((taken = mcheck_taken(cpu))) { mcheck_taken(cpu) = 0; + t2_mcheck_last_taken |= (1 << cpu); value = 0xffffffffU; mb(); } mcheck_expected(cpu) = 0; + t2_mcheck_any_expected = 0; mb(); /* If Type1 access, must reset T2 CFG so normal IO space ops work. */ @@ -191,45 +228,30 @@ *(vulp)T2_HAE_3 = t2_cfg; mb(); } - DBG(("conf_read(): finished\n")); - __restore_flags(flags); return value; } static void conf_write(unsigned long addr, unsigned int value, unsigned char type1) { - unsigned long flags; - unsigned int cpu; + unsigned int cpu, taken; unsigned long t2_cfg = 0; cpu = smp_processor_id(); - __save_and_cli(flags); /* avoid getting hit by machine check */ - -#if 0 - { - unsigned long stat0; - /* Reset status register to avoid losing errors. */ - stat0 = *(vulp)T2_IOCSR; - *(vulp)T2_IOCSR = stat0; - mb(); - DBG(("conf_write: T2 ERR was 0x%x\n", stat0)); - } -#endif - /* If Type1 access, must set T2 CFG. */ if (type1) { t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL; *(vulp)T2_HAE_3 = t2_cfg | 0x40000000UL; mb(); - DBG(("conf_write: TYPE1 access\n")); } mb(); draina(); mcheck_expected(cpu) = 1; + mcheck_taken(cpu) = 0; + t2_mcheck_any_expected |= (1 << cpu); mb(); /* Access configuration space. */ @@ -237,7 +259,19 @@ mb(); mb(); /* magic */ + /* Wait for possible mcheck. Also, this lets other CPUs clear + their mchecks as well, as they can reliably tell when + this CPU is in the midst of handling a real mcheck via + the "taken" function. */ + udelay(100); + + if ((taken = mcheck_taken(cpu))) { + mcheck_taken(cpu) = 0; + t2_mcheck_last_taken |= (1 << cpu); + mb(); + } mcheck_expected(cpu) = 0; + t2_mcheck_any_expected = 0; mb(); /* If Type1 access, must reset T2 CFG so normal IO space ops work. */ @@ -245,8 +279,6 @@ *(vulp)T2_HAE_3 = t2_cfg; mb(); } - DBG(("conf_write(): finished\n")); - __restore_flags(flags); } static int @@ -333,48 +365,121 @@ write_dword: t2_write_config_dword }; +static void __init +t2_direct_map_window1(unsigned long base, unsigned long length) +{ + unsigned long temp; + + __direct_map_base = base; + __direct_map_size = length; + + temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20); + *(vulp)T2_WBASE1 = temp | 0x80000UL; /* OR in ENABLE bit */ + temp = (length - 1) & 0xfff00000UL; + *(vulp)T2_WMASK1 = temp; + *(vulp)T2_TBASE1 = 0; + +#if DEBUG_PRINT_FINAL_SETTINGS + printk("%s: setting WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n", + __FUNCTION__, + *(vulp)T2_WBASE1, + *(vulp)T2_WMASK1, + *(vulp)T2_TBASE1); +#endif +} + +static void __init +t2_sg_map_window2(struct pci_controller *hose, + unsigned long base, + unsigned long length) +{ + unsigned long temp; + + /* Note we can only do 1 SG window, as the other is for direct, so + do an ISA SG area, especially for the floppy. */ + hose->sg_isa = iommu_arena_new(hose, base, length, 0); + hose->sg_pci = NULL; + + temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20); + *(vulp)T2_WBASE2 = temp | 0xc0000UL; /* OR in ENABLE/SG bits */ + temp = (length - 1) & 0xfff00000UL; + *(vulp)T2_WMASK2 = temp; + *(vulp)T2_TBASE2 = virt_to_phys(hose->sg_isa->ptes) >> 1; + mb(); + + t2_pci_tbi(hose, 0, -1); /* flush TLB all */ + +#if DEBUG_PRINT_FINAL_SETTINGS + printk("%s: setting WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n", + __FUNCTION__, + *(vulp)T2_WBASE2, + *(vulp)T2_WMASK2, + *(vulp)T2_TBASE2); +#endif +} + +static void __init +t2_save_configuration(void) +{ +#if DEBUG_PRINT_INITIAL_SETTINGS + printk("%s: HAE_1 was 0x%lx\n", __FUNCTION__, srm_hae); /* HW is 0 */ + printk("%s: HAE_2 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_2); + printk("%s: HAE_3 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_3); + printk("%s: HAE_4 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_4); + printk("%s: HBASE was 0x%lx\n", __FUNCTION__, *(vulp)T2_HBASE); + + printk("%s: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n", __FUNCTION__, + *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1); + printk("%s: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n", __FUNCTION__, + *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2); +#endif + + /* + * Save the DMA Window registers. + */ + t2_saved_config.window[0].wbase = *(vulp)T2_WBASE1; + t2_saved_config.window[0].wmask = *(vulp)T2_WMASK1; + t2_saved_config.window[0].tbase = *(vulp)T2_TBASE1; + t2_saved_config.window[1].wbase = *(vulp)T2_WBASE2; + t2_saved_config.window[1].wmask = *(vulp)T2_WMASK2; + t2_saved_config.window[1].tbase = *(vulp)T2_TBASE2; + + t2_saved_config.hae_1 = srm_hae; /* HW is already set to 0 */ + t2_saved_config.hae_2 = *(vulp)T2_HAE_2; + t2_saved_config.hae_3 = *(vulp)T2_HAE_3; + t2_saved_config.hae_4 = *(vulp)T2_HAE_4; + t2_saved_config.hbase = *(vulp)T2_HBASE; +} + void __init t2_init_arch(void) { struct pci_controller *hose; - unsigned long t2_iocsr; + unsigned long temp; unsigned int i; for (i = 0; i < NR_CPUS; i++) { mcheck_expected(i) = 0; mcheck_taken(i) = 0; } - -#if 0 - /* Set up error reporting. */ - t2_iocsr = *(vulp)T2_IOCSR; - *(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 7); /* TLB error check */ - mb(); - *(vulp)T2_IOCSR; /* read it back to make sure */ -#endif + t2_mcheck_any_expected = 0; + t2_mcheck_last_taken = 0; /* Enable scatter/gather TLB use. */ - t2_iocsr = *(vulp)T2_IOCSR; - if (!(t2_iocsr & (0x1UL << 26))) { + temp = *(vulp)T2_IOCSR; + if (!(temp & (0x1UL << 26))) { printk("t2_init_arch: enabling SG TLB, IOCSR was 0x%lx\n", - t2_iocsr); - *(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 26); + temp); + *(vulp)T2_IOCSR = temp | (0x1UL << 26); mb(); *(vulp)T2_IOCSR; /* read it back to make sure */ } -#if 0 - printk("t2_init_arch: HBASE was 0x%lx\n", *(vulp)T2_HBASE); - printk("t2_init_arch: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n", - *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1); - printk("t2_init_arch: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n", - *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2); -#endif + t2_save_configuration(); /* * Create our single hose. */ - pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; @@ -385,52 +490,58 @@ hose->sparse_io_base = T2_IO - IDENT_ADDR; hose->dense_io_base = 0; - /* Note we can only do 1 SG window, as the other is for direct, so - do an ISA SG area, especially for the floppy. */ - hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); - hose->sg_pci = NULL; - /* * Set up the PCI->physical memory translation windows. * - * Window 1 goes at ? GB and is ?GB large, direct mapped. - * Window 2 goes at 8 MB and is 8MB large, scatter/gather (for ISA). + * Window 1 is direct mapped. + * Window 2 is scatter/gather (for ISA). */ -#if T2_DIRECTMAP_2G - __direct_map_base = 0x80000000UL; - __direct_map_size = 0x80000000UL; - - /* WARNING!! must correspond to the direct map window params!!! */ - *(vulp)T2_WBASE1 = 0x80080fffU; - *(vulp)T2_WMASK1 = 0x7ff00000U; - *(vulp)T2_TBASE1 = 0; -#else /* T2_DIRECTMAP_2G */ - __direct_map_base = 0x40000000UL; - __direct_map_size = 0x40000000UL; - - /* WARNING!! must correspond to the direct map window params!!! */ - *(vulp)T2_WBASE1 = 0x400807ffU; - *(vulp)T2_WMASK1 = 0x3ff00000U; - *(vulp)T2_TBASE1 = 0; -#endif /* T2_DIRECTMAP_2G */ + t2_direct_map_window1(T2_DIRECTMAP_START, T2_DIRECTMAP_LENGTH); - /* WARNING!! must correspond to the SG arena/window params!!! */ - *(vulp)T2_WBASE2 = 0x008c000fU; - *(vulp)T2_WMASK2 = 0x00700000U; - *(vulp)T2_TBASE2 = virt_to_phys(hose->sg_isa->ptes) >> 1; + /* Always make an ISA DMA window. */ + t2_sg_map_window2(hose, T2_ISA_SG_START, T2_ISA_SG_LENGTH); - *(vulp)T2_HBASE = 0x0; + *(vulp)T2_HBASE = 0x0; /* Disable HOLES. */ /* Zero HAE. */ - *(vulp)T2_HAE_1 = 0; mb(); - *(vulp)T2_HAE_2 = 0; mb(); - *(vulp)T2_HAE_3 = 0; mb(); -#if 0 - *(vulp)T2_HAE_4 = 0; mb(); /* DO NOT TOUCH THIS!!! */ -#endif + *(vulp)T2_HAE_1 = 0; mb(); /* Sparse MEM HAE */ + *(vulp)T2_HAE_2 = 0; mb(); /* Sparse I/O HAE */ + *(vulp)T2_HAE_3 = 0; mb(); /* Config Space HAE */ - t2_pci_tbi(hose, 0, -1); /* flush TLB all */ + /* + * We also now zero out HAE_4, the dense memory HAE, so that + * we need not account for its "offset" when accessing dense + * memory resources which we allocated in our normal way. This + * HAE would need to stay untouched were we to keep the SRM + * resource settings. + * + * Thus we can now run standard X servers on SABLE/LYNX. :-) + */ + *(vulp)T2_HAE_4 = 0; mb(); +} + +void +t2_kill_arch(int mode) +{ + /* + * Restore the DMA Window registers. + */ + *(vulp)T2_WBASE1 = t2_saved_config.window[0].wbase; + *(vulp)T2_WMASK1 = t2_saved_config.window[0].wmask; + *(vulp)T2_TBASE1 = t2_saved_config.window[0].tbase; + *(vulp)T2_WBASE2 = t2_saved_config.window[1].wbase; + *(vulp)T2_WMASK2 = t2_saved_config.window[1].wmask; + *(vulp)T2_TBASE2 = t2_saved_config.window[1].tbase; + mb(); + + *(vulp)T2_HAE_1 = srm_hae; + *(vulp)T2_HAE_2 = t2_saved_config.hae_2; + *(vulp)T2_HAE_3 = t2_saved_config.hae_3; + *(vulp)T2_HAE_4 = t2_saved_config.hae_4; + *(vulp)T2_HBASE = t2_saved_config.hbase; + mb(); + *(vulp)T2_HBASE; /* READ it back to ensure WRITE occurred. */ } void @@ -458,13 +569,7 @@ { struct sable_cpu_csr *cpu_regs; - cpu_regs = (struct sable_cpu_csr *)T2_CPU0_BASE; - if (cpu == 1) - cpu_regs = (struct sable_cpu_csr *)T2_CPU1_BASE; - if (cpu == 2) - cpu_regs = (struct sable_cpu_csr *)T2_CPU2_BASE; - if (cpu == 3) - cpu_regs = (struct sable_cpu_csr *)T2_CPU3_BASE; + cpu_regs = (struct sable_cpu_csr *)T2_CPUn_BASE(cpu); cpu_regs->sic &= ~SIC_SEIC; @@ -481,19 +586,76 @@ mb(); /* magic */ } +/* + * SABLE seems to have a "broadcast" style machine check, in that all + * CPUs receive it. And, the issuing CPU, in the case of PCI Config + * space read/write faults, will also receive a second mcheck, upon + * lowering IPL during completion processing in pci_read_config_byte() + * et al. + * + * Hence all the taken/expected/any_expected/last_taken stuff... + */ void t2_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { int cpu = smp_processor_id(); +#if DEBUG_MCHECK > 0 + struct el_common *mchk_header = (struct el_common *)la_ptr; +#endif /* Clear the error before any reporting. */ mb(); mb(); /* magic */ draina(); t2_clear_errors(cpu); - wrmces(rdmces()|1); /* ??? */ - mb(); + + /* This should not actually be done until the logout frame is + examined, but, since we don't do that, go on and do this... */ + wrmces(0x7); + mb(); + + /* Now, do testing for the anomalous conditions. */ + if (!mcheck_expected(cpu) && t2_mcheck_any_expected) { + /* + * FUNKY: Received mcheck on a CPU and not + * expecting it, but another CPU is expecting one. + * + * Just dismiss it for now on this CPU... + */ +#if DEBUG_MCHECK > 0 + printk("t2_machine_check(cpu%d): any_expected 0x%x -" + " (assumed) spurious -" + " code 0x%x\n", cpu, t2_mcheck_any_expected, + (unsigned int)mchk_header->code); +#endif /* DEBUG_MCHECK */ + return; + } + + if (!mcheck_expected(cpu) && !t2_mcheck_any_expected) { + if (t2_mcheck_last_taken & (1 << cpu)) { +#if DEBUG_MCHECK > 0 + printk("t2_machine_check(cpu%d): last_taken 0x%x -" + " unexpected mcheck -" + " code 0x%x\n", cpu, t2_mcheck_last_taken, + (unsigned int)mchk_header->code); +#endif /* DEBUG_MCHECK */ + t2_mcheck_last_taken = 0; + mb(); + return; + } else { + t2_mcheck_last_taken = 0; + mb(); + } + } + +#if DEBUG_MCHECK > 0 + printk("%s t2_mcheck(cpu%d): last_taken 0x%x -" + " any_expected 0x%x - code 0x%x\n", + (mcheck_expected(cpu) ? "EX" : "UN"), + cpu, t2_mcheck_last_taken, t2_mcheck_any_expected, + (unsigned int)mchk_header->code); +#endif /* DEBUG_MCHECK */ process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu)); } diff -urN linux-2.4.21/arch/alpha/kernel/pci.c linux-2.4.22/arch/alpha/kernel/pci.c --- linux-2.4.21/arch/alpha/kernel/pci.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "proto.h" @@ -42,7 +43,7 @@ const char pci_hae0_name[] = "HAE0"; /* Indicate whether we respect the PCI setup left by console. */ -int __initdata pci_probe_only; +int pci_probe_only; /* * The PCI controller list. @@ -196,6 +197,52 @@ return str; } +#ifdef ALPHA_RESTORE_SRM_SETUP +static struct pdev_srm_saved_conf *srm_saved_configs; + +void __init +pdev_save_srm_config(struct pci_dev *dev) +{ + struct pdev_srm_saved_conf *tmp; + static int printed = 0; + + if (!alpha_using_srm || pci_probe_only) + return; + + if (!printed) { + printk(KERN_INFO "pci: enabling save/restore of SRM state\n"); + printed = 1; + } + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) { + printk(KERN_ERR "%s: kmalloc() failed!\n", __FUNCTION__); + return; + } + tmp->next = srm_saved_configs; + tmp->dev = dev; + + pci_save_state(dev, tmp->regs); + + srm_saved_configs = tmp; +} + +void +pci_restore_srm_config(void) +{ + struct pdev_srm_saved_conf *tmp; + + /* No need to restore if probed only. */ + if (pci_probe_only) + return; + + /* Restore SRM config. */ + for (tmp = srm_saved_configs; tmp; tmp = tmp->next) { + pci_restore_state(tmp->dev, tmp->regs); + } +} +#endif + void __init pcibios_fixup_resource(struct resource *res, struct resource *root) { @@ -254,6 +301,8 @@ for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { struct pci_dev *dev = pci_dev_b(ln); + + pdev_save_srm_config(dev); if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) pcibios_fixup_device_resources(dev, bus); } @@ -298,8 +347,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); - - /* ??? FIXME -- record old value for shutdown. */ } /* Most Alphas have straight-forward swizzling needs. */ diff -urN linux-2.4.21/arch/alpha/kernel/pci_impl.h linux-2.4.22/arch/alpha/kernel/pci_impl.h --- linux-2.4.21/arch/alpha/kernel/pci_impl.h 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/pci_impl.h 2003-08-25 04:44:39.000000000 -0700 @@ -147,6 +147,33 @@ unsigned int align_entry; }; +#if defined(CONFIG_ALPHA_SRM) && \ + (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA)) +# define NEED_SRM_SAVE_RESTORE +#else +# undef NEED_SRM_SAVE_RESTORE +#endif + +#if defined(CONFIG_ALPHA_GENERIC) || defined(NEED_SRM_SAVE_RESTORE) +# define ALPHA_RESTORE_SRM_SETUP +#else +# undef ALPHA_RESTORE_SRM_SETUP +#endif + +#ifdef ALPHA_RESTORE_SRM_SETUP +/* Store PCI device configuration left by SRM here. */ +struct pdev_srm_saved_conf +{ + struct pdev_srm_saved_conf *next; + struct pci_dev *dev; + u32 regs[16]; +}; + +extern void pci_restore_srm_config(void); +#else +#define pdev_save_srm_config(dev) do {} while (0) +#define pci_restore_srm_config() do {} while (0) +#endif /* The hose list. */ extern struct pci_controller *hose_head, **hose_tail; diff -urN linux-2.4.21/arch/alpha/kernel/process.c linux-2.4.22/arch/alpha/kernel/process.c --- linux-2.4.21/arch/alpha/kernel/process.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/process.c 2003-08-25 04:44:39.000000000 -0700 @@ -159,7 +159,7 @@ /* This has the effect of resetting the VGA video origin. */ take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); #endif - /* reset_for_srm(); */ + pci_restore_srm_config(); set_hae(srm_hae); } diff -urN linux-2.4.21/arch/alpha/kernel/proto.h linux-2.4.22/arch/alpha/kernel/proto.h --- linux-2.4.21/arch/alpha/kernel/proto.h 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/proto.h 2003-08-25 04:44:39.000000000 -0700 @@ -76,6 +76,7 @@ /* core_t2.c */ extern struct pci_ops t2_pci_ops; extern void t2_init_arch(void); +extern void t2_kill_arch(int); extern void t2_machine_check(u64, u64, struct pt_regs *); extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); diff -urN linux-2.4.21/arch/alpha/kernel/setup.c linux-2.4.22/arch/alpha/kernel/setup.c --- linux-2.4.21/arch/alpha/kernel/setup.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -154,6 +154,7 @@ WEAK(eiger_mv); WEAK(jensen_mv); WEAK(lx164_mv); +WEAK(lynx_mv); WEAK(marvel_ev7_mv); WEAK(miata_mv); WEAK(mikasa_mv); @@ -260,7 +261,7 @@ unsigned long size; size = initrd_end - initrd_start; - start = __alloc_bootmem(size, PAGE_SIZE, 0); + start = __alloc_bootmem(PAGE_ALIGN(size), PAGE_SIZE, 0); if (!start || __pa(start) + size > mem_limit) { initrd_start = initrd_end = 0; return NULL; @@ -720,7 +721,7 @@ NULL, /* Turbolaser */ &avanti_mv, NULL, /* Mustang */ - &alcor_mv, /* Alcor, Bret, Maverick. */ + NULL, /* Alcor, Bret, Maverick. HWRPB inaccurate? */ NULL, /* Tradewind */ NULL, /* Mikasa -- see below. */ NULL, /* EB64 */ @@ -729,7 +730,7 @@ &alphabook1_mv, &rawhide_mv, NULL, /* K2 */ - NULL, /* Lynx */ + &lynx_mv, /* Lynx */ &xl_mv, NULL, /* EB164 -- see variation. */ NULL, /* Noritake -- see below. */ @@ -915,6 +916,7 @@ &eiger_mv, &jensen_mv, &lx164_mv, + &lynx_mv, &miata_mv, &mikasa_mv, &mikasa_primo_mv, diff -urN linux-2.4.21/arch/alpha/kernel/sys_alcor.c linux-2.4.22/arch/alpha/kernel/sys_alcor.c --- linux-2.4.21/arch/alpha/kernel/sys_alcor.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/sys_alcor.c 2003-08-25 04:44:39.000000000 -0700 @@ -222,6 +222,7 @@ { cia_kill_arch(mode); +#ifndef ALPHA_RESTORE_SRM_SETUP switch(mode) { case LINUX_REBOOT_CMD_RESTART: /* Who said DEC engineer's have no sense of humor? ;-) */ @@ -237,6 +238,29 @@ } halt(); +#endif +} + +static void __init +alcor_init_pci(void) +{ + struct pci_dev *dev; + + cia_init_pci(); + + /* + * Now we can look to see if we are really running on an XLT-type + * motherboard, by looking for a 21040 TULIP in slot 6, which is + * built into XLT and BRET/MAVERICK, but not available on ALCOR. + */ + dev = pci_find_device(PCI_VENDOR_ID_DEC, + PCI_DEVICE_ID_DEC_TULIP, + NULL); + if (dev && dev->devfn == PCI_DEVFN(6,0)) { + alpha_mv.sys.cia.gru_int_req_bits = XLT_GRU_INT_REQ_BITS; + printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n", + __FUNCTION__); + } } @@ -262,7 +286,7 @@ init_arch: cia_init_arch, init_irq: alcor_init_irq, init_rtc: common_init_rtc, - init_pci: cia_init_pci, + init_pci: alcor_init_pci, kill_arch: alcor_kill_arch, pci_map_irq: alcor_map_irq, pci_swizzle: common_swizzle, @@ -292,7 +316,7 @@ init_arch: cia_init_arch, init_irq: alcor_init_irq, init_rtc: common_init_rtc, - init_pci: cia_init_pci, + init_pci: alcor_init_pci, kill_arch: alcor_kill_arch, pci_map_irq: alcor_map_irq, pci_swizzle: common_swizzle, diff -urN linux-2.4.21/arch/alpha/kernel/sys_miata.c linux-2.4.22/arch/alpha/kernel/sys_miata.c --- linux-2.4.21/arch/alpha/kernel/sys_miata.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/sys_miata.c 2003-08-25 04:44:39.000000000 -0700 @@ -247,6 +247,7 @@ { cia_kill_arch(mode); +#ifndef ALPHA_RESTORE_SRM_SETUP switch(mode) { case LINUX_REBOOT_CMD_RESTART: /* Who said DEC engineers have no sense of humor? ;-) */ @@ -262,6 +263,7 @@ } halt(); +#endif } diff -urN linux-2.4.21/arch/alpha/kernel/sys_nautilus.c linux-2.4.22/arch/alpha/kernel/sys_nautilus.c --- linux-2.4.21/arch/alpha/kernel/sys_nautilus.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/sys_nautilus.c 2003-08-25 04:44:39.000000000 -0700 @@ -76,6 +76,9 @@ void nautilus_kill_arch(int mode) { + u32 pmuport; + int off; + switch (mode) { case LINUX_REBOOT_CMD_RESTART: if (! alpha_using_srm) { @@ -89,14 +92,18 @@ break; case LINUX_REBOOT_CMD_POWER_OFF: - { - u32 pmuport; - pcibios_read_config_dword(0, 0x88, 0x10, &pmuport); - pmuport &= 0xfffe; - outl(0xffff, pmuport); /* clear pending events */ - outw(0x2000, pmuport+4); /* power off */ - /* NOTREACHED */ + /* Assume M1543C */ + off = 0x2000; /* SLP_TYPE = 0, SLP_EN = 1 */ + pcibios_read_config_dword(0, 0x88, 0x10, &pmuport); + if (!pmuport) { + /* M1535D/D+ */ + off = 0x3400; /* SLP_TYPE = 5, SLP_EN = 1 */ + pcibios_read_config_dword(0, 0x88, 0xe0, &pmuport); } + pmuport &= 0xfffe; + outw(0xffff, pmuport); /* Clear pending events. */ + outw(off, pmuport + 4); + /* NOTREACHED */ break; } } diff -urN linux-2.4.21/arch/alpha/kernel/sys_noritake.c linux-2.4.22/arch/alpha/kernel/sys_noritake.c --- linux-2.4.21/arch/alpha/kernel/sys_noritake.c 2000-10-27 10:55:01.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/sys_noritake.c 2003-08-25 04:44:39.000000000 -0700 @@ -217,7 +217,7 @@ { 16+2, 16+2, 16+3, 32+2, 32+3}, /* IdSel 22, slot 0 */ { 16+4, 16+4, 16+5, 32+4, 32+5}, /* IdSel 23, slot 1 */ { 16+6, 16+6, 16+7, 32+6, 32+7}, /* IdSel 24, slot 2 */ - { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */ + { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */ /* The following 5 are actually on PCI bus 1, which is across the built-in bridge of the NORITAKE only. */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */ @@ -341,6 +341,7 @@ init_irq: noritake_init_irq, init_rtc: common_init_rtc, init_pci: cia_init_pci, + kill_arch: cia_kill_arch, pci_map_irq: noritake_map_irq, pci_swizzle: noritake_swizzle, }; diff -urN linux-2.4.21/arch/alpha/kernel/sys_sable.c linux-2.4.22/arch/alpha/kernel/sys_sable.c --- linux-2.4.21/arch/alpha/kernel/sys_sable.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/sys_sable.c 2003-08-25 04:44:39.000000000 -0700 @@ -5,7 +5,7 @@ * Copyright (C) 1996 Jay A Estabrook * Copyright (C) 1998, 1999 Richard Henderson * - * Code supporting the Sable and Sable-Gamma systems. + * Code supporting the Sable, Sable-Gamma, and Lynx systems. */ #include @@ -30,8 +30,28 @@ #include "pci_impl.h" #include "machvec_impl.h" -spinlock_t sable_irq_lock = SPIN_LOCK_UNLOCKED; +spinlock_t sable_lynx_irq_lock = SPIN_LOCK_UNLOCKED; +typedef struct irq_swizzle_struct +{ + char irq_to_mask[64]; + char mask_to_irq[64]; + + /* Note mask bit is true for DISABLED irqs. */ + unsigned long shadow_mask; + + void (*update_irq_hw)(unsigned long bit, unsigned long mask); + void (*ack_irq_hw)(unsigned long bit); + +} irq_swizzle_t; + +static irq_swizzle_t *sable_lynx_irq_swizzle; + +static void sable_lynx_init_irq(int nr_irqs); + +#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) + +/***********************************************************************/ /* * For SABLE, which is really baroque, we manage 40 IRQ's, but the * hardware really only supports 24, not via normal ISA PIC, @@ -70,30 +90,7 @@ *23 IIC - */ -static struct -{ - char irq_to_mask[40]; - char mask_to_irq[40]; - - /* Note mask bit is true for DISABLED irqs. */ - unsigned long shadow_mask; -} sable_irq_swizzle = { - { - -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */ - -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */ - 2, 1, 0, 4, 5, -1, -1, -1, /* pseudo PCI */ - }, - { - 34, 33, 32, 12, 35, 36, 1, 6, /* mask 0-7 */ - 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */ - 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */ - }, - -1 -}; - -static inline void +static void sable_update_irq_hw(unsigned long bit, unsigned long mask) { int port = 0x537; @@ -109,7 +106,7 @@ outb(mask, port); } -static inline void +static void sable_ack_irq_hw(unsigned long bit) { int port, val1, val2; @@ -132,102 +129,46 @@ outb(val2, 0x534); /* ack the master */ } -static inline void -sable_enable_irq(unsigned int irq) -{ - unsigned long bit, mask; - - bit = sable_irq_swizzle.irq_to_mask[irq]; - spin_lock(&sable_irq_lock); - mask = sable_irq_swizzle.shadow_mask &= ~(1UL << bit); - sable_update_irq_hw(bit, mask); - spin_unlock(&sable_irq_lock); -} - -static void -sable_disable_irq(unsigned int irq) -{ - unsigned long bit, mask; - - bit = sable_irq_swizzle.irq_to_mask[irq]; - spin_lock(&sable_irq_lock); - mask = sable_irq_swizzle.shadow_mask |= 1UL << bit; - sable_update_irq_hw(bit, mask); - spin_unlock(&sable_irq_lock); -} - -static unsigned int -sable_startup_irq(unsigned int irq) -{ - sable_enable_irq(irq); - return 0; -} - -static void -sable_end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - sable_enable_irq(irq); -} - -static void -sable_mask_and_ack_irq(unsigned int irq) -{ - unsigned long bit, mask; - - bit = sable_irq_swizzle.irq_to_mask[irq]; - spin_lock(&sable_irq_lock); - mask = sable_irq_swizzle.shadow_mask |= 1UL << bit; - sable_update_irq_hw(bit, mask); - sable_ack_irq_hw(bit); - spin_unlock(&sable_irq_lock); -} - -static struct hw_interrupt_type sable_irq_type = { - typename: "SABLE", - startup: sable_startup_irq, - shutdown: sable_disable_irq, - enable: sable_enable_irq, - disable: sable_disable_irq, - ack: sable_mask_and_ack_irq, - end: sable_end_irq, +static irq_swizzle_t sable_irq_swizzle = { + { + -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */ + -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */ + 2, 1, 0, 4, 5, -1, -1, -1, /* pseudo PCI */ + -1, -1, -1, -1, -1, -1, -1, -1, /* */ + -1, -1, -1, -1, -1, -1, -1, -1, /* */ + -1, -1, -1, -1, -1, -1, -1, -1 /* */ + }, + { + 34, 33, 32, 12, 35, 36, 1, 6, /* mask 0-7 */ + 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */ + 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* */ + -1, -1, -1, -1, -1, -1, -1, -1, /* */ + -1, -1, -1, -1, -1, -1, -1, -1, /* */ + -1, -1, -1, -1, -1, -1, -1, -1, /* */ + -1, -1, -1, -1, -1, -1, -1, -1 /* */ + }, + -1, + sable_update_irq_hw, + sable_ack_irq_hw }; -static void -sable_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) -{ - /* Note that the vector reported by the SRM PALcode corresponds - to the interrupt mask bits, but we have to manage via more - normal IRQs. */ - - int bit, irq; - - bit = (vector - 0x800) >> 4; - irq = sable_irq_swizzle.mask_to_irq[bit]; - handle_irq(irq, regs); -} - static void __init sable_init_irq(void) { - long i; - outb(-1, 0x537); /* slave 0 */ outb(-1, 0x53b); /* slave 1 */ outb(-1, 0x53d); /* slave 2 */ outb(0x44, 0x535); /* enable cascades in master */ - for (i = 0; i < 40; ++i) { - irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &sable_irq_type; - } - - common_init_isa_dma(); + sable_lynx_irq_swizzle = &sable_irq_swizzle; + sable_lynx_init_irq(40); } - /* - * PCI Fixup configuration for ALPHA SABLE (2100) - 2100A is different ?? + * PCI Fixup configuration for ALPHA SABLE (2100). * * The device to slot mapping looks like: * @@ -255,7 +196,7 @@ static int __init sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[9][5] __initdata = { + static char irq_tab[9][5] __initdata = { /*INT INTA INTB INTC INTD */ { 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */ { 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */ @@ -265,13 +206,349 @@ { -1, -1, -1, -1, -1}, /* IdSel 5, none */ { 32+2, 32+2, 32+2, 32+2, 32+2}, /* IdSel 6, slot 0 */ { 32+3, 32+3, 32+3, 32+3, 32+3}, /* IdSel 7, slot 1 */ - { 32+4, 32+4, 32+4, 32+4, 32+4}, /* IdSel 8, slot 2 */ - }; + { 32+4, 32+4, 32+4, 32+4, 32+4} /* IdSel 8, slot 2 */ + }; const long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5; return COMMON_TABLE_LOOKUP; } +#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) */ + +#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) + +/***********************************************************************/ +/* LYNX hardware specifics + */ +/* + * For LYNX, which is also baroque, we manage 64 IRQs, via a custom IC. + * + * Bit Meaning Kernel IRQ + *------------------------------------------ + * 0 + * 1 + * 2 + * 3 mouse 12 + * 4 + * 5 + * 6 keyboard 1 + * 7 floppy 6 + * 8 COM2 3 + * 9 parallel port 7 + *10 EISA irq 3 - + *11 EISA irq 4 - + *12 EISA irq 5 5 + *13 EISA irq 6 - + *14 EISA irq 7 - + *15 COM1 4 + *16 EISA irq 9 9 + *17 EISA irq 10 10 + *18 EISA irq 11 11 + *19 EISA irq 12 - + *20 + *21 EISA irq 14 14 + *22 EISA irq 15 15 + *23 IIC - + *24 VGA (builtin) - + *25 + *26 + *27 + *28 NCR810 (builtin) 28 + *29 + *30 + *31 + *32 PCI 0 slot 4 A primary bus 32 + *33 PCI 0 slot 4 B primary bus 33 + *34 PCI 0 slot 4 C primary bus 34 + *35 PCI 0 slot 4 D primary bus + *36 PCI 0 slot 5 A primary bus + *37 PCI 0 slot 5 B primary bus + *38 PCI 0 slot 5 C primary bus + *39 PCI 0 slot 5 D primary bus + *40 PCI 0 slot 6 A primary bus + *41 PCI 0 slot 6 B primary bus + *42 PCI 0 slot 6 C primary bus + *43 PCI 0 slot 6 D primary bus + *44 PCI 0 slot 7 A primary bus + *45 PCI 0 slot 7 B primary bus + *46 PCI 0 slot 7 C primary bus + *47 PCI 0 slot 7 D primary bus + *48 PCI 0 slot 0 A secondary bus + *49 PCI 0 slot 0 B secondary bus + *50 PCI 0 slot 0 C secondary bus + *51 PCI 0 slot 0 D secondary bus + *52 PCI 0 slot 1 A secondary bus + *53 PCI 0 slot 1 B secondary bus + *54 PCI 0 slot 1 C secondary bus + *55 PCI 0 slot 1 D secondary bus + *56 PCI 0 slot 2 A secondary bus + *57 PCI 0 slot 2 B secondary bus + *58 PCI 0 slot 2 C secondary bus + *59 PCI 0 slot 2 D secondary bus + *60 PCI 0 slot 3 A secondary bus + *61 PCI 0 slot 3 B secondary bus + *62 PCI 0 slot 3 C secondary bus + *63 PCI 0 slot 3 D secondary bus + */ + +static void +lynx_update_irq_hw(unsigned long bit, unsigned long mask) +{ + /* + * Write the AIR register on the T3/T4 with the + * address of the IC mask register (offset 0x40) + */ + *(vulp)T2_AIR = 0x40; + mb(); + *(vulp)T2_AIR; /* re-read to force write */ + mb(); + *(vulp)T2_DIR = mask; + mb(); + mb(); +} + +static void +lynx_ack_irq_hw(unsigned long bit) +{ + *(vulp)T2_VAR = (u_long) bit; + mb(); + mb(); +} + +static irq_swizzle_t lynx_irq_swizzle = { + { /* irq_to_mask */ + -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */ + -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo */ + -1, -1, -1, -1, 28, -1, -1, -1, /* pseudo */ + 32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */ + 40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */ + 48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */ + 56, 57, 58, 59, 60, 61, 62, 63 /* mask 56-63 */ + }, + { /* mask_to_irq */ + -1, -1, -1, 12, -1, -1, 1, 6, /* mask 0-7 */ + 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */ + 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */ + -1, -1, -1, -1, 28, -1, -1, -1, /* mask 24-31 */ + 32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */ + 40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */ + 48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */ + 56, 57, 58, 59, 60, 61, 62, 63 /* mask 56-63 */ + }, + -1, + lynx_update_irq_hw, + lynx_ack_irq_hw +}; + +static void __init +lynx_init_irq(void) +{ + sable_lynx_irq_swizzle = &lynx_irq_swizzle; + sable_lynx_init_irq(64); +} + +/* + * PCI Fixup configuration for ALPHA LYNX (2100A) + * + * The device to slot mapping looks like: + * + * Slot Device + * 0 none + * 1 none + * 2 PCI-EISA bridge + * 3 PCI-PCI bridge + * 4 NCR 810 (Demi-Lynx only) + * 5 none + * 6 PCI on board slot 4 + * 7 PCI on board slot 5 + * 8 PCI on board slot 6 + * 9 PCI on board slot 7 + * + * And behind the PPB we have: + * + * 11 PCI on board slot 0 + * 12 PCI on board slot 1 + * 13 PCI on board slot 2 + * 14 PCI on board slot 3 + */ +/* + * NOTE: the IRQ assignments below are arbitrary, but need to be consistent + * with the values in the irq swizzling tables above. + */ + +static int __init +lynx_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + static char irq_tab[19][5] __initdata = { + /*INT INTA INTB INTC INTD */ + { -1, -1, -1, -1, -1}, /* IdSel 13, PCEB */ + { -1, -1, -1, -1, -1}, /* IdSel 14, PPB */ + { 28, 28, 28, 28, 28}, /* IdSel 15, NCR demi */ + { -1, -1, -1, -1, -1}, /* IdSel 16, none */ + { 32, 32, 33, 34, 35}, /* IdSel 17, slot 4 */ + { 36, 36, 37, 38, 39}, /* IdSel 18, slot 5 */ + { 40, 40, 41, 42, 43}, /* IdSel 19, slot 6 */ + { 44, 44, 45, 46, 47}, /* IdSel 20, slot 7 */ + { -1, -1, -1, -1, -1}, /* IdSel 22, none */ + /* The following are actually behind the PPB. */ + { -1, -1, -1, -1, -1}, /* IdSel 16 none */ + { 28, 28, 28, 28, 28}, /* IdSel 17 NCR lynx */ + { -1, -1, -1, -1, -1}, /* IdSel 18 none */ + { -1, -1, -1, -1, -1}, /* IdSel 19 none */ + { -1, -1, -1, -1, -1}, /* IdSel 20 none */ + { -1, -1, -1, -1, -1}, /* IdSel 21 none */ + { 48, 48, 49, 50, 51}, /* IdSel 22 slot 0 */ + { 52, 52, 53, 54, 55}, /* IdSel 23 slot 1 */ + { 56, 56, 57, 58, 59}, /* IdSel 24 slot 2 */ + { 60, 60, 61, 62, 63} /* IdSel 25 slot 3 */ + }; + const long min_idsel = 2, max_idsel = 20, irqs_per_slot = 5; + return COMMON_TABLE_LOOKUP; +} + +static u8 __init +lynx_swizzle(struct pci_dev *dev, u8 *pinp) +{ + int slot, pin = *pinp; + + if (dev->bus->number == 0) { + slot = PCI_SLOT(dev->devfn); + } + /* Check for the built-in bridge */ + else if (PCI_SLOT(dev->bus->self->devfn) == 3) { + slot = PCI_SLOT(dev->devfn) + 11; + } + else + { + /* Must be a card-based bridge. */ + do { + if (PCI_SLOT(dev->bus->self->devfn) == 3) { + slot = PCI_SLOT(dev->devfn) + 11; + break; + } + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ; + + /* Move up the chain of bridges. */ + dev = dev->bus->self; + /* Slot of the next bridge. */ + slot = PCI_SLOT(dev->devfn); + } while (dev->bus->self); + } + *pinp = pin; + return slot; +} + +#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) */ + +/***********************************************************************/ +/* GENERIC irq routines */ + +static inline void +sable_lynx_enable_irq(unsigned int irq) +{ + unsigned long bit, mask; + + bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; + spin_lock(&sable_lynx_irq_lock); + mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit); + sable_lynx_irq_swizzle->update_irq_hw(bit, mask); + spin_unlock(&sable_lynx_irq_lock); +#if 0 + printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", + __FUNCTION__, mask, bit, irq); +#endif +} +static void +sable_lynx_disable_irq(unsigned int irq) +{ + unsigned long bit, mask; + bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; + spin_lock(&sable_lynx_irq_lock); + mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit; + sable_lynx_irq_swizzle->update_irq_hw(bit, mask); + spin_unlock(&sable_lynx_irq_lock); +#if 0 + printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", + __FUNCTION__, mask, bit, irq); +#endif +} + +static unsigned int +sable_lynx_startup_irq(unsigned int irq) +{ + sable_lynx_enable_irq(irq); + return 0; +} + +static void +sable_lynx_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + sable_lynx_enable_irq(irq); +} + +static void +sable_lynx_mask_and_ack_irq(unsigned int irq) +{ + unsigned long bit, mask; + + bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; + spin_lock(&sable_lynx_irq_lock); + mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit; + sable_lynx_irq_swizzle->update_irq_hw(bit, mask); + sable_lynx_irq_swizzle->ack_irq_hw(bit); + spin_unlock(&sable_lynx_irq_lock); +} + +static struct hw_interrupt_type sable_lynx_irq_type = { + typename: "SABLE/LYNX", + startup: sable_lynx_startup_irq, + shutdown: sable_lynx_disable_irq, + enable: sable_lynx_enable_irq, + disable: sable_lynx_disable_irq, + ack: sable_lynx_mask_and_ack_irq, + end: sable_lynx_end_irq, +}; + +static void +sable_lynx_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) +{ + /* Note that the vector reported by the SRM PALcode corresponds + to the interrupt mask bits, but we have to manage via the + so-called legacy IRQs for many common devices. */ + + int bit, irq; + + bit = (vector - 0x800) >> 4; + irq = sable_lynx_irq_swizzle->mask_to_irq[bit]; +#if 0 + printk("%s: vector 0x%lx bit 0x%x irq 0x%x\n", + __FUNCTION__, vector, bit, irq); +#endif + handle_irq(irq, regs); +} + +static void __init +sable_lynx_init_irq(int nr_irqs) +{ + long i; + + for (i = 0; i < nr_irqs; ++i) { + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; + irq_desc[i].handler = &sable_lynx_irq_type; + } + + common_init_isa_dma(); +} + +static void __init +sable_lynx_init_pci(void) +{ + common_init_pci(); +} + +/*****************************************************************/ /* * The System Vectors * @@ -279,7 +556,8 @@ * these games with GAMMA_BIAS. */ -#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_GAMMA) +#if defined(CONFIG_ALPHA_GENERIC) || \ + (defined(CONFIG_ALPHA_SABLE) && !defined(CONFIG_ALPHA_GAMMA)) #undef GAMMA_BIAS #define GAMMA_BIAS 0 struct alpha_machine_vector sable_mv __initmv = { @@ -294,13 +572,13 @@ min_mem_address: T2_DEFAULT_MEM_BASE, nr_irqs: 40, - device_interrupt: sable_srm_device_interrupt, + device_interrupt: sable_lynx_srm_device_interrupt, init_arch: t2_init_arch, init_irq: sable_init_irq, init_rtc: common_init_rtc, - init_pci: common_init_pci, - kill_arch: NULL, + init_pci: sable_lynx_init_pci, + kill_arch: t2_kill_arch, pci_map_irq: sable_map_irq, pci_swizzle: common_swizzle, @@ -309,9 +587,10 @@ } } }; ALIAS_MV(sable) -#endif +#endif /* GENERIC || (SABLE && !GAMMA) */ -#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_GAMMA) +#if defined(CONFIG_ALPHA_GENERIC) || \ + (defined(CONFIG_ALPHA_SABLE) && defined(CONFIG_ALPHA_GAMMA)) #undef GAMMA_BIAS #define GAMMA_BIAS _GAMMA_BIAS struct alpha_machine_vector sable_gamma_mv __initmv = { @@ -326,12 +605,13 @@ min_mem_address: T2_DEFAULT_MEM_BASE, nr_irqs: 40, - device_interrupt: sable_srm_device_interrupt, + device_interrupt: sable_lynx_srm_device_interrupt, init_arch: t2_init_arch, init_irq: sable_init_irq, init_rtc: common_init_rtc, - init_pci: common_init_pci, + init_pci: sable_lynx_init_pci, + kill_arch: t2_kill_arch, pci_map_irq: sable_map_irq, pci_swizzle: common_swizzle, @@ -340,4 +620,36 @@ } } }; ALIAS_MV(sable_gamma) -#endif +#endif /* GENERIC || (SABLE && GAMMA) */ + +#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) +#undef GAMMA_BIAS +#define GAMMA_BIAS _GAMMA_BIAS +struct alpha_machine_vector lynx_mv __initmv = { + vector_name: "Lynx", + DO_EV4_MMU, + DO_DEFAULT_RTC, + DO_T2_IO, + DO_T2_BUS, + machine_check: t2_machine_check, + max_dma_address: ALPHA_SABLE_MAX_DMA_ADDRESS, + min_io_address: EISA_DEFAULT_IO_BASE, + min_mem_address: T2_DEFAULT_MEM_BASE, + + nr_irqs: 64, + device_interrupt: sable_lynx_srm_device_interrupt, + + init_arch: t2_init_arch, + init_irq: lynx_init_irq, + init_rtc: common_init_rtc, + init_pci: sable_lynx_init_pci, + kill_arch: t2_kill_arch, + pci_map_irq: lynx_map_irq, + pci_swizzle: lynx_swizzle, + + sys: { t2: { + gamma_bias: _GAMMA_BIAS + } } +}; +ALIAS_MV(lynx) +#endif /* GENERIC || LYNX */ diff -urN linux-2.4.21/arch/alpha/kernel/sys_sio.c linux-2.4.22/arch/alpha/kernel/sys_sio.c --- linux-2.4.21/arch/alpha/kernel/sys_sio.c 2001-06-20 11:10:27.000000000 -0700 +++ linux-2.4.22/arch/alpha/kernel/sys_sio.c 2003-08-25 04:44:39.000000000 -0700 @@ -35,6 +35,14 @@ #include "pci_impl.h" #include "machvec_impl.h" +#ifdef ALPHA_RESTORE_SRM_SETUP +/* Save LCA configuration data as the console had it set up. */ +struct +{ + unsigned int orig_route_tab; /* for SAVE/RESTORE */ +} saved_config __attribute((common)); +#endif + static void __init sio_init_irq(void) @@ -76,6 +84,15 @@ static void __init sio_pci_route(void) { +#ifdef ALPHA_RESTORE_SRM_SETUP + /* First, read and save the original setting. */ + pcibios_read_config_dword(0, PCI_DEVFN(7, 0), 0x60, + &saved_config.orig_route_tab); + printk("%s: PIRQ original 0x%x new 0x%x\n", __FUNCTION__, + saved_config.orig_route_tab, alpha_mv.sys.sio.route_tab); +#endif + + /* Now override with desired setting. */ pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60, alpha_mv.sys.sio.route_tab); } @@ -244,6 +261,21 @@ outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */ } +void +sio_kill_arch(int mode) +{ +#ifdef ALPHA_RESTORE_SRM_SETUP + /* Since we cannot read the PCI DMA Window CSRs, we + * cannot restore them here. + * + * However, we CAN read the PIRQ route register, so restore it + * now... + */ + pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60, + saved_config.orig_route_tab); +#endif +} + /* * The System Vectors @@ -268,7 +300,7 @@ init_irq: sio_init_irq, init_rtc: common_init_rtc, init_pci: alphabook1_init_pci, - kill_arch: NULL, + kill_arch: sio_kill_arch, pci_map_irq: noname_map_irq, pci_swizzle: common_swizzle, @@ -299,6 +331,7 @@ init_irq: sio_init_irq, init_rtc: common_init_rtc, init_pci: noname_init_pci, + kill_arch: sio_kill_arch, pci_map_irq: noname_map_irq, pci_swizzle: common_swizzle, @@ -328,6 +361,7 @@ init_irq: sio_init_irq, init_rtc: common_init_rtc, init_pci: noname_init_pci, + kill_arch: sio_kill_arch, pci_map_irq: noname_map_irq, pci_swizzle: common_swizzle, @@ -366,6 +400,7 @@ init_irq: sio_init_irq, init_rtc: common_init_rtc, init_pci: noname_init_pci, + kill_arch: sio_kill_arch, pci_map_irq: p2k_map_irq, pci_swizzle: common_swizzle, @@ -395,6 +430,7 @@ init_irq: sio_init_irq, init_rtc: common_init_rtc, init_pci: noname_init_pci, + kill_arch: sio_kill_arch, pci_map_irq: noname_map_irq, pci_swizzle: common_swizzle, diff -urN linux-2.4.21/arch/alpha/lib/ev6-stxncpy.S linux-2.4.22/arch/alpha/lib/ev6-stxncpy.S --- linux-2.4.21/arch/alpha/lib/ev6-stxncpy.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/lib/ev6-stxncpy.S 2003-08-25 04:44:39.000000000 -0700 @@ -360,9 +360,9 @@ lda t2, -1 # E : for creating masks later beq t12, $u_head # U : (stall) - nop - cmpbge zero, t1, t8 # E : is there a zero? extql t2, a1, t2 # U : + cmpbge zero, t1, t8 # E : is there a zero? + andnot t2, t6, t12 # E : dest mask for a single word copy or t8, t10, t5 # E : test for end-of-count too cmpbge zero, t2, t3 # E : @@ -379,13 +379,13 @@ negq t8, t6 # E : build bitmask of bytes <= zero mskqh t1, t4, t1 # U : - and t6, t8, t12 # E : - subq t12, 1, t6 # E : (stall) - or t6, t12, t8 # E : (stall) - zapnot t2, t8, t2 # U : prepare source word; mirror changes (stall) + and t6, t8, t2 # E : + subq t2, 1, t6 # E : (stall) + or t6, t2, t8 # E : (stall) + zapnot t12, t8, t12 # U : prepare source word; mirror changes (stall) zapnot t1, t8, t1 # U : to source validity mask - andnot t0, t2, t0 # E : zero place for source to reside + andnot t0, t12, t0 # E : zero place for source to reside or t0, t1, t0 # E : and put it there (stall both t0, t1) stq_u t0, 0(a0) # L : (stall) diff -urN linux-2.4.21/arch/alpha/lib/stxncpy.S linux-2.4.22/arch/alpha/lib/stxncpy.S --- linux-2.4.21/arch/alpha/lib/stxncpy.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/alpha/lib/stxncpy.S 2003-08-25 04:44:39.000000000 -0700 @@ -313,9 +313,9 @@ lda t2, -1 # e0 : for creating masks later beq t12, $u_head # .. e1 : - nop # e0 : - cmpbge zero, t1, t8 # .. e1 : is there a zero? extql t2, a1, t2 # e0 : + cmpbge zero, t1, t8 # .. e1 : is there a zero? + andnot t2, t6, t12 # e0 : dest mask for a single word copy or t8, t10, t5 # .. e1 : test for end-of-count too cmpbge zero, t2, t3 # e0 : cmoveq a2, t5, t8 # .. e1 : @@ -330,14 +330,14 @@ ldq_u t0, 0(a0) # e0 : negq t8, t6 # .. e1 : build bitmask of bytes <= zero mskqh t1, t4, t1 # e0 : - and t6, t8, t12 # .. e1 : - subq t12, 1, t6 # e0 : - or t6, t12, t8 # e1 : + and t6, t8, t2 # .. e1 : + subq t2, 1, t6 # e0 : + or t6, t2, t8 # e1 : - zapnot t2, t8, t2 # e0 : prepare source word; mirror changes + zapnot t12, t8, t12 # e0 : prepare source word; mirror changes zapnot t1, t8, t1 # .. e1 : to source validity mask - andnot t0, t2, t0 # e0 : zero place for source to reside + andnot t0, t12, t0 # e0 : zero place for source to reside or t0, t1, t0 # e1 : and put it there stq_u t0, 0(a0) # e0 : ret (t9) # .. e1 : diff -urN linux-2.4.21/arch/arm/Makefile linux-2.4.22/arch/arm/Makefile --- linux-2.4.21/arch/arm/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -8,8 +8,15 @@ # Copyright (C) 1995-2001 by Russell King LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds +OBJCOPYFLAGS :=-O binary -R .note -R .comment -S GZFLAGS :=-9 -CFLAGS +=-fno-common -pipe +CFLAGS +=-Uarm -fno-common -pipe + +ifeq ($(CONFIG_FRAME_POINTER),y) +CFLAGS :=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog) +endif + +CFLAGS :=$(CFLAGS:-O2=-Os) ifeq ($(CONFIG_DEBUG_INFO),y) CFLAGS +=-g @@ -24,10 +31,13 @@ apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3 -Os # This selects which instruction set is used. +# Note that GCC is lame - it doesn't numerically define an +# architecture version macro, but instead defines a whole +# series of macros. arch-y := -arch-$(CONFIG_CPU_32v3) :=-march=armv3 -arch-$(CONFIG_CPU_32v4) :=-march=armv4 -arch-$(CONFIG_CPU_32v5) :=-march=armv5 +arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 +arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 +arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 -march=armv5 # This selects how we optimise for the processor. tune-y := @@ -40,12 +50,12 @@ tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 -CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float +CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm +CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm AFLAGS +=$(apcs-y) $(arch-y) -mno-fpu -msoft-float ifeq ($(CONFIG_CPU_26),y) -PROCESSOR = armo +PROCESSOR := armo ifeq ($(CONFIG_ROM_KERNEL),y) DATAADDR = 0x02080000 TEXTADDR = 0x03800000 @@ -81,6 +91,10 @@ INCDIR = cl7500 endif +ifeq ($(CONFIG_ARCH_RISCSTATION),y) +MACHINE = riscstation +endif + ifeq ($(CONFIG_FOOTBRIDGE),y) MACHINE = footbridge INCDIR = ebsa285 @@ -121,12 +135,16 @@ MACHINE = integrator endif +ifeq ($(CONFIG_ARCH_AT91RM9200),y) +MACHINE = at91rm9200 +endif + ifeq ($(CONFIG_ARCH_MX1ADS),y) MACHINE = mx1ads endif ifeq ($(CONFIG_ARCH_CAMELOT),y) -MACHINE = epxa10db +MACHINE = epxa endif ifeq ($(CONFIG_ARCH_CLPS711X),y) @@ -135,19 +153,23 @@ endif ifeq ($(CONFIG_ARCH_FORTUNET),y) -TEXTADDR = 0xc0008000 +TEXTADDR = 0xc0208000 endif ifeq ($(CONFIG_ARCH_ANAKIN),y) MACHINE = anakin endif -export MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT +ifeq ($(CONFIG_ARCH_OMAHA),y) +MACHINE = omaha +endif + +export MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT OBJCOPYFLAGS # Only set INCDIR if its not already defined above # Grr, ?= doesn't work as all the other assignment operators do. Make bug? ifeq ($(origin INCDIR), undefined) -INCDIR := $(MACHINE) +INCDIR :=$(MACHINE) endif ifeq ($(origin DATAADDR), undefined) @@ -161,32 +183,42 @@ CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES) endif -HEAD := arch/arm/kernel/head-$(PROCESSOR).o \ - arch/arm/kernel/init_task.o -SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe -CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES) -LIBS := arch/arm/lib/lib.a $(LIBS) +HEAD :=arch/arm/kernel/head-$(PROCESSOR).o \ + arch/arm/kernel/init_task.o +SUBDIRS +=arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe +CORE_FILES :=arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES) +LIBS :=arch/arm/lib/lib.a $(LIBS) ifeq ($(CONFIG_FPE_NWFPE),y) -LIBS := arch/arm/nwfpe/math-emu.o $(LIBS) +LIBS :=arch/arm/nwfpe/math-emu.o $(LIBS) endif # Only include fastfpe if it is part of the kernel tree. -FASTFPE := arch/arm/fastfpe +FASTFPE :=arch/arm/fastfpe ifeq ($(FASTFPE),$(wildcard $(FASTFPE))) -SUBDIRS += $(FASTFPE) +SUBDIRS +=$(FASTFPE) ifeq ($(CONFIG_FPE_FASTFPE),y) -LIBS := arch/arm/fastfpe/fast-math-emu.o $(LIBS) +LIBS :=arch/arm/fastfpe/fast-math-emu.o $(LIBS) +endif endif + +ifeq ($(findstring y,$(CONFIG_USB_OHCI_SA1111) $(CONFIG_USB_OHCI_AT91)),y) + SUBDIRS +=arch/arm/common + CORE_FILES +=arch/arm/common/nopci.o endif ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y) -SUBDIRS += drivers/acorn/char -DRIVERS += drivers/acorn/char/acorn-char.o +SUBDIRS +=drivers/acorn/char +DRIVERS +=drivers/acorn/char/acorn-char.o +endif + +ifeq ($(CONFIG_ARCH_RISCSTATION),y) +SUBDIRS +=drivers/acorn/char +DRIVERS +=drivers/acorn/char/acorn-char.o endif -MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot -MAKETOOLS = $(MAKE) -C arch/$(ARCH)/tools +MAKEBOOT =$(MAKE) -C arch/$(ARCH)/boot +MAKETOOLS =$(MAKE) -C arch/$(ARCH)/tools # The following is a hack to get 'constants.h' up # to date before starting compilation @@ -194,15 +226,44 @@ $(patsubst %,_dir_%, $(SUBDIRS)): maketools $(patsubst %,_modsubdir_%,$(MOD_DIRS)): maketools -symlinks: archsymlinks +symlinks: include/asm-arm/.arch include/asm-arm/.proc -archsymlinks: - $(RM) include/asm-arm/arch include/asm-arm/proc - (cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc) +# Update machine arch and proc symlinks if something which affects +# them changed. We use .arch and .proc to indicate when they were +# updated last, otherwise make uses the target directory mtime. + +include/asm-arm/.arch: $(wildcard include/config/arch/*.h) +ifneq ("$(INCDIR)","") + @echo ' Making asm-arm/arch -> asm-arm/arch-$(INCDIR) symlink' + @rm -f include/asm-arm/arch + @ln -sf arch-$(INCDIR) include/asm-arm/arch + @touch $@ +else + @echo ' No architecture defined. You may want to use a pre-packaged config. make a5k_config, ebsa110_config, footbridge_config, etc.' +endif + +include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/config/cpu/26.h) +ifneq ("$(INCDIR)","") + @echo ' Making asm-arm/proc -> asm-arm/proc-$(PROCESSOR) symlink' + @rm -f include/asm-arm/proc + @ln -sf proc-$(PROCESSOR) include/asm-arm/proc + @touch $@ +else + @echo ' No architecture defined. You may want to use a pre-packaged config. make a5k_config, ebsa110_config, footbridge_config, etc.' +endif + +.PHONY: maketools +maketools: include/asm-arm/.arch include/asm-arm/.proc \ + include/asm-arm/constants.h include/linux/version.h checkbin + @$(MAKETOOLS) vmlinux: arch/arm/vmlinux.lds -arch/arm/vmlinux.lds: $(LDSCRIPT) dummy +arch/arm/vmlinux.lds: arch/arm/Makefile $(LDSCRIPT) \ + $(wildcard include/config/cpu/32.h) \ + $(wildcard include/config/cpu/26.h) \ + $(wildcard include/config/arch/*.h) + @echo ' Generating $@' @sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@ arch/arm/kernel arch/arm/mm arch/arm/lib: dummy @@ -216,39 +277,37 @@ MRPROPER_FILES += \ arch/arm/tools/constants.h* \ - include/asm-arm/arch \ - include/asm-arm/proc \ + include/asm-arm/arch include/asm-arm/.arch \ + include/asm-arm/proc include/asm-arm/.proc \ include/asm-arm/constants.h* \ include/asm-arm/mach-types.h # We use MRPROPER_FILES and CLEAN_FILES now -archmrproper: +archmrproper: FORCE @/bin/true -archclean: +archclean: FORCE @$(MAKEBOOT) clean -archdep: scripts/mkdep archsymlinks +archdep: scripts/mkdep symlinks @$(MAKETOOLS) dep @$(MAKEBOOT) dep -# we need version.h -maketools: checkbin include/linux/version.h - @$(MAKETOOLS) all - -# Ensure this is ld "2.9.4" or later +# Ensure this is ld "2.9.5" or later NEW_LINKER := $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?) ifneq ($(NEW_LINKER),0) -checkbin: +checkbin: FORCE @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.' @echo '*** Please upgrade your binutils to 2.9.5.' @false else -checkbin: +checkbin: FORCE @true endif +.PHONY: FORCE + # My testing targets (that short circuit a few dependencies) zImg:; @$(MAKEBOOT) zImage Img:; @$(MAKEBOOT) Image diff -urN linux-2.4.21/arch/arm/boot/Makefile linux-2.4.22/arch/arm/boot/Makefile --- linux-2.4.21/arch/arm/boot/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -5,34 +5,42 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 1995-2000 Russell King +# Copyright (C) 1995-2002 Russell King # SYSTEM =$(TOPDIR)/vmlinux +# Note: the following conditions must always be true: +# ZRELADDR == virt_to_phys(TEXTADDR) +# PARAMS_PHYS must be with 4MB of ZRELADDR +# INITRD_PHYS must be in RAM + ifeq ($(CONFIG_CPU_26),y) -ZTEXTADDR = 0x02080000 +ZRELADDR = 0x02080000 PARAMS_PHYS = 0x0207c000 INITRD_PHYS = 0x02180000 -INITRD_VIRT = 0x02180000 endif ifeq ($(CONFIG_ARCH_RPC),y) -ZTEXTADDR = 0x10008000 +ZRELADDR = 0x10008000 +PARAMS_PHYS = 0x10000100 +INITRD_PHYS = 0x18000000 +endif + +ifeq ($(CONFIG_ARCH_RISCSTATION),y) +ZRELADDR = 0x10008000 PARAMS_PHYS = 0x10000100 INITRD_PHYS = 0x18000000 -INITRD_VIRT = 0xc8000000 endif ifeq ($(CONFIG_ARCH_CLPS7500),y) -ZTEXTADDR = 0x10008000 +ZRELADDR = 0x10008000 endif ifeq ($(CONFIG_ARCH_EBSA110),y) -ZTEXTADDR = 0x00008000 +ZRELADDR = 0x00008000 PARAMS_PHYS = 0x00000400 INITRD_PHYS = 0x00800000 -INITRD_VIRT = 0xc0800000 endif ifeq ($(CONFIG_ARCH_SHARK),y) @@ -41,126 +49,114 @@ endif ifeq ($(CONFIG_FOOTBRIDGE),y) -ZTEXTADDR = 0x00008000 +ZRELADDR = 0x00008000 PARAMS_PHYS = 0x00000100 INITRD_PHYS = 0x00800000 -INITRD_VIRT = 0xc0800000 endif ifeq ($(CONFIG_ARCH_INTEGRATOR),y) -ZTEXTADDR = 0x00008000 +ZRELADDR = 0x00008000 PARAMS_PHYS = 0x00000100 INITRD_PHYS = 0x00800000 -INITRD_VIRT = 0xc0800000 +endif + +ifeq ($(CONFIG_ARCH_AT91RM9200),y) +ZRELADDR = 0x20008000 endif ifeq ($(CONFIG_ARCH_MX1ADS),y) -ZTEXTADDR = 0x08008000 +ZRELADDR = 0x08008000 endif ifeq ($(CONFIG_ARCH_CAMELOT),y) -ZTEXTADDR = 0x00008000 +ZRELADDR = 0x00008000 endif ifeq ($(CONFIG_ARCH_NEXUSPCI),y) -ZTEXTADDR = 0x40008000 +ZRELADDR = 0x40008000 endif ifeq ($(CONFIG_ARCH_L7200),y) -# RAM based kernel -#ZTEXTADDR = 0xf0400000 -#ZRELADDR = 0xf0008000 - -# FLASH based kernel -ZTEXTADDR = 0x00010000 ZRELADDR = 0xf0008000 -ZBSSADDR = 0xf03e0000 endif # The standard locations for stuff on CLPS711x type processors ifeq ($(CONFIG_ARCH_CLPS711X),y) -ZTEXTADDR = 0xc0028000 +ZRELADDR = 0xc0028000 PARAMS_PHYS = 0xc0000100 endif # Should probably have some agreement on these... ifeq ($(CONFIG_ARCH_P720T),y) INITRD_PHYS = 0xc0400000 -INITRD_VIRT = 0xc0400000 endif ifeq ($(CONFIG_ARCH_CDB89712),y) INITRD_PHYS = 0x00700000 -INITRD_VIRT = 0xc0300000 +endif + +ifeq ($(CONFIG_ARCH_OMAHA),y) +ZTEXTADDR = 0x0c008000 +PARAMS_PHYS = 0x0C000100 +INITRD_PHYS = 0x0C800000 +INITRD_VIRT = 0x0C800000 endif ifeq ($(CONFIG_ARCH_SA1100),y) -ZTEXTADDR = 0xc0008000 ZRELADDR = 0xc0008000 -ifeq ($(CONFIG_SA1100_VICTOR),y) - ZTEXTADDR = 0x00002000 - ZBSSADDR = 0xc0200000 -endif -ifeq ($(CONFIG_SA1100_SHERMAN),y) - ZTEXTADDR = 0x00050000 - ZBSSADDR = 0xc0200000 -endif -ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y) - ZTEXTADDR = 0xC0200000 -endif -ifeq ($(CONFIG_SA1100_GRAPHICSMASTER),y) - ZTEXTADDR = 0xC0400000 -endif -ifeq ($(CONFIG_SA1100_ADSBITSY),y) - ZTEXTADDR = 0xC0400000 -endif -ifeq ($(CONFIG_SA1100_YOPY),y) - ZTEXTADDR = 0x00080000 - ZBSSADDR = 0xc0200000 -endif +# No defconfig file to move this into... +#ifeq ($(CONFIG_SA1100_YOPY),y) +# ZTEXTADDR = 0x00080000 +# ZBSSADDR = 0xc0200000 +#endif ifeq ($(CONFIG_SA1111),y) ZRELADDR = 0xc0208000 endif endif ifeq ($(CONFIG_ARCH_ANAKIN),y) -ZTEXTADDR = 0x20008000 +ZRELADDR = 0x20008000 endif # -# If you don't define ZRELADDR above, -# then it defaults to ZTEXTADDR +# We now have a PIC decompressor implementation. Decompressors running +# from RAM should not define ZTEXTADDR. Decompressors running directly +# from ROM or Flash must define ZTEXTADDR (preferably via the config) # -ifeq ($(ZRELADDR),) -ZRELADDR = $(ZTEXTADDR) +ifeq ($(CONFIG_ZBOOT_ROM),y) +ZTEXTADDR =0x$(CONFIG_ZBOOT_ROM_TEXT) +ZBSSADDR =0x$(CONFIG_ZBOOT_ROM_BSS) +else +ZTEXTADDR =0 +ZBSSADDR =ALIGN(4) endif -export SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS +export SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS -Image: $(CONFIGURE) $(SYSTEM) - $(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@ +Image: $(SYSTEM) + $(OBJCOPY) $(OBJCOPYFLAGS) $< $@ bzImage: zImage -zImage: $(CONFIGURE) compressed/vmlinux - $(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@ +zImage: compressed/vmlinux + $(OBJCOPY) $(OBJCOPYFLAGS) $< $@ bootpImage: bootp/bootp - $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ + $(OBJCOPY) $(OBJCOPYFLAGS) $< $@ -compressed/vmlinux: $(TOPDIR)/vmlinux dep +compressed/vmlinux: $(TOPDIR)/vmlinux FORCE @$(MAKE) -C compressed vmlinux -bootp/bootp: zImage initrd +bootp/bootp: zImage initrd FORCE @$(MAKE) -C bootp bootp initrd: - @test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1) + @test "$(INITRD_PHYS)" != "" || (echo This machine does not support INITRD; exit -1) @test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1) -install: $(CONFIGURE) Image +install: Image sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" -zinstall: $(CONFIGURE) zImage +zinstall: zImage sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" clean: @@ -169,3 +165,5 @@ @$(MAKE) -C bootp clean dep: + +FORCE: diff -urN linux-2.4.21/arch/arm/boot/bootp/Makefile linux-2.4.22/arch/arm/boot/bootp/Makefile --- linux-2.4.21/arch/arm/boot/bootp/Makefile 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/bootp/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -5,9 +5,7 @@ ZSYSTEM =$(TOPDIR)/arch/arm/boot/zImage ZLDFLAGS =-p -X -T bootp.lds \ --defsym initrd_addr=$(INITRD_PHYS) \ - --defsym initrd_virt=$(INITRD_VIRT) \ - --defsym params=$(PARAMS_PHYS) \ - --defsym kernel_addr=$(ZTEXTADDR) + --defsym params=$(PARAMS_PHYS) all: bootp diff -urN linux-2.4.21/arch/arm/boot/bootp/bootp.lds linux-2.4.22/arch/arm/boot/bootp/bootp.lds --- linux-2.4.21/arch/arm/boot/bootp/bootp.lds 2000-09-18 15:15:24.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/bootp/bootp.lds 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/arm/boot/bootp/bootp.lds * - * Copyright (C) 2000 Russell King + * Copyright (C) 2000-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,13 +15,9 @@ _text = .; .text : { _stext = .; - _start = .; - init.o(.start) - kernel_start = .; + *(.start) kernel.o - kernel_len = . - kernel_start; . = ALIGN(32); - *(.text) initrd_start = .; initrd.o initrd_len = . - initrd_start; diff -urN linux-2.4.21/arch/arm/boot/bootp/init.S linux-2.4.22/arch/arm/boot/bootp/init.S --- linux-2.4.21/arch/arm/boot/bootp/init.S 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/bootp/init.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/arm/boot/bootp/init.S * - * Copyright (C) 2000 Russell King + * Copyright (C) 2000-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -11,8 +11,9 @@ * r0 through to r3 straight through. */ .section .start,#alloc,#execinstr - .type _entry, #function -_entry: adr r10, initdata + .type _start, #function + .globl _start +_start: adr r10, initdata ldr r11, initdata sub r11, r10, r11 @ work out exec offset b splitify @@ -22,17 +23,11 @@ initdata: .word initdata @ compiled address of this .size initdata,. - initdata - .text splitify: adr r13, data ldmia r13!, {r4-r6} @ move the initrd add r4, r4, r11 @ correction bl move - ldmia r13!, {r4-r6} @ then the kernel - mov r12, r5 - add r4, r4, r11 @ correction - bl move - /* * Setup the initrd parameters to pass to the kernel. This can either be * passed in via a param_struct or a tag list. We spot the param_struct @@ -52,17 +47,16 @@ ldr r9, [r8, #4] @ get first tag teq r9, r4 - bne taglist @ ok, we have a tag list + beq taglist @ ok, we have a tag list /* * We didn't find a valid tag list - create one. */ str r4, [r8, #4] - mov r4, #8 + mov r4, #(8 >> 2) str r4, [r8, #0] mov r4, #0 str r4, [r8, #8] - /* * find the end of the tag list, and then add an INITRD tag on the end. * If there is already an INITRD tag, then we ignore it; the last INITRD @@ -70,12 +64,12 @@ */ taglist: ldr r9, [r8, #0] @ tag length teq r9, #0 @ last tag? - addne r8, r8, r9 + addne r8, r8, r9, lsl #2 bne taglist - - mov r4, #16 @ length of initrd tag + mov r4, #(16 >> 2) @ length of initrd tag mov r9, #0 @ end of tag list terminator stmia r8, {r4, r5, r6, r7, r9} + adr r12, kernel_start mov pc, r12 @ call kernel /* @@ -83,6 +77,7 @@ */ param_struct: add r8, r8, #16*4 stmia r8, {r6,r7} @ save in param_struct + adr r12, kernel_start mov pc, r12 @ call kernel move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time @@ -97,15 +92,12 @@ .word initrd_addr .word initrd_len - .word kernel_start - .word kernel_addr - .word kernel_len - .word 0x54410001 @ r4 = ATAG_CORE - .word 0x54410005 @ r5 = ATAG_INITRD - .word initrd_virt @ r6 + .word 0x54420005 @ r5 = ATAG_INITRD + .word initrd_addr @ r6 .word initrd_len @ r7 .word params @ r8 - .type kernel_start,#object .type initrd_start,#object + +kernel_start: diff -urN linux-2.4.21/arch/arm/boot/compressed/Makefile linux-2.4.22/arch/arm/boot/compressed/Makefile --- linux-2.4.21/arch/arm/boot/compressed/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -9,7 +9,7 @@ HEAD = head.o OBJS = misc.o -CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_BOOT) +CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_BOOT) -fpic -Uarm FONTC = $(TOPDIR)/drivers/video/font_acorn_8x8.c ZLDFLAGS = -p -X -T vmlinux.lds @@ -18,7 +18,12 @@ # ifeq ($(CONFIG_ARCH_ACORN),y) OBJS += ll_char_wr.o font.o -ZLDFLAGS += -defsym params=$(PARAMS_PHYS) +CFLAGS += -DPARAMS_PHYS=$(PARAMS_PHYS) +endif + +ifeq ($(CONFIG_ARCH_RISCSTATION),y) +OBJS += ll_char_wr.o font.o +CFLAGS += -DPARAMS_PHYS=$(PARAMS_PHYS) endif ifeq ($(CONFIG_ARCH_NETWINDER),y) @@ -33,6 +38,10 @@ OBJS += head-integrator.o endif +ifeq ($(CONFIG_ARCH_AT91RM9200),y) +OBJS += head-at91rm9200.o +endif + ifeq ($(CONFIG_ARCH_MX1ADS),y) OBJS += head-mx1ads.o endif @@ -60,18 +69,9 @@ ifeq ($(CONFIG_ARCH_SA1100),y) OBJS += head-sa1100.o -ifeq ($(CONFIG_SA1100_NANOENGINE),y) - OBJS += hw-bse.o -endif endif -SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/; - -ifneq ($(ZBSSADDR),) -SEDFLAGS += s/BSS_START/$(ZBSSADDR)/ -else -SEDFLAGS += s/BSS_START/ALIGN(4)/ -endif +SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/ LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) @@ -80,11 +80,14 @@ vmlinux: $(HEAD) $(OBJS) piggy.o vmlinux.lds $(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(LIBGCC) -o vmlinux -$(HEAD): $(HEAD:.o=.S) +$(HEAD): $(HEAD:.o=.S) \ + $(wildcard $(TOPDIR)/include/config/zboot/rom.h) \ + $(wildcard $(TOPDIR)/include/config/cpu/32.h) \ + $(wildcard $(TOPDIR)/include/config/cpu/26.h) $(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S) piggy.o: $(SYSTEM) - $(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy + $(OBJCOPY) $(OBJCOPYFLAGS) $(SYSTEM) piggy gzip $(GZFLAGS) < piggy > piggy.gz $(LD) -r -o $@ -b binary piggy.gz rm -f piggy piggy.gz diff -urN linux-2.4.21/arch/arm/boot/compressed/head-at91rm9200.S linux-2.4.22/arch/arm/boot/compressed/head-at91rm9200.S --- linux-2.4.21/arch/arm/boot/compressed/head-at91rm9200.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/boot/compressed/head-at91rm9200.S 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,15 @@ +/* + * linux/arch/arm/boot/compressed/head-at91rm9200.S + * + * Copyright (C) 2003 SAN People + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include + + .section ".start", "ax" + mov r7, #MACH_TYPE_AT91RM9200 diff -urN linux-2.4.21/arch/arm/boot/compressed/head-clps7500.S linux-2.4.22/arch/arm/boot/compressed/head-clps7500.S --- linux-2.4.21/arch/arm/boot/compressed/head-clps7500.S 2001-04-12 12:03:50.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/head-clps7500.S 2003-08-25 04:44:39.000000000 -0700 @@ -13,7 +13,7 @@ /* This branch is taken if the CPU memory width matches the actual device in use. The default at power on is 16 bits so we must be prepared for a mismatch. */ - .section ".start", #alloc, #execinstr + .section ".start", "ax" 2: b 1f .word 0xffff diff -urN linux-2.4.21/arch/arm/boot/compressed/head-epxa10db.S linux-2.4.22/arch/arm/boot/compressed/head-epxa10db.S --- linux-2.4.21/arch/arm/boot/compressed/head-epxa10db.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/head-epxa10db.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ #include #include - .section ".start", #alloc, #execinstr + .section ".start", "ax" mov r7, #MACH_TYPE_CAMELOT diff -urN linux-2.4.21/arch/arm/boot/compressed/head-ftvpci.S linux-2.4.22/arch/arm/boot/compressed/head-ftvpci.S --- linux-2.4.21/arch/arm/boot/compressed/head-ftvpci.S 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.22/arch/arm/boot/compressed/head-ftvpci.S 2003-08-25 04:44:39.000000000 -0700 @@ -13,7 +13,7 @@ * 2 of the License, or (at your option) any later version. */ - .section ".start", #alloc, #execinstr + .section ".start", "ax" ftv_start: mcr p15, 0, r0, c7, c5, 0 @ flush I cache mrc p15, 0, r0, c1, c0 diff -urN linux-2.4.21/arch/arm/boot/compressed/head-integrator.S linux-2.4.22/arch/arm/boot/compressed/head-integrator.S --- linux-2.4.21/arch/arm/boot/compressed/head-integrator.S 2001-06-27 14:12:04.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/head-integrator.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ #include - .section ".start", #alloc, #execinstr + .section ".start", "ax" mov r7, #MACH_TYPE_INTEGRATOR diff -urN linux-2.4.21/arch/arm/boot/compressed/head-l7200.S linux-2.4.22/arch/arm/boot/compressed/head-l7200.S --- linux-2.4.21/arch/arm/boot/compressed/head-l7200.S 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.22/arch/arm/boot/compressed/head-l7200.S 2003-08-25 04:44:39.000000000 -0700 @@ -8,12 +8,13 @@ */ #include +#include #ifndef CONFIG_ARCH_L7200 #error What am I doing here... #endif - .section ".start", #alloc, #execinstr + .section ".start", "ax" __L7200_start: mov r0, #0x00100000 @ FLASH address of initrd @@ -26,4 +27,4 @@ ble 1b mov r8, #0 @ Zero it out - mov r7, #19 @ Set architecture ID + mov r7, #MACH_TYPE_L7200 @ Set architecture ID diff -urN linux-2.4.21/arch/arm/boot/compressed/head-netwinder.S linux-2.4.22/arch/arm/boot/compressed/head-netwinder.S --- linux-2.4.21/arch/arm/boot/compressed/head-netwinder.S 2000-09-18 15:15:24.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/head-netwinder.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,50 +1,13 @@ /* * linux/arch/arm/boot/compressed/head-netwinder.S * - * Copyright (C) 2000 Russell King + * Copyright (C) 2000-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define K(a,b,c) ((a) << 24 | (b) << 12 | (c)) + .section ".start", "ax" - .section ".start", #alloc, #execinstr - - /* - * check to see if we are running from the correct address. - * If not, we move ourselves in a two stage process. Firstly, - * we copy the start of the kernel (which includes this code) - * to 0x8000, and then jump to this code to continue with the - * rest (since this code will get overwritten). - */ - adr r2, 1f - ldmdb r2, {r9, r10} - and r3, r2, #0xc000 - teq r3, #0x8000 @ correctly located? - beq 2f @ skip this code - bic r3, r2, #0xc000 - orr r3, r3, #0x8000 - mov r0, r3 @ new address if '1' - mov r4, #64 @ number of bytes to copy - sub r5, r10, r9 @ total number of bytes to copy - b 1f - - .word _start - .word __bss_start - -1: - .rept 4 - ldmia r2!, {r6, r9, r10, r11} - stmia r3!, {r6, r9, r10, r11} - .endr - subs r4, r4, #64 - bcs 1b - movs r4, r5 @ remaining length - mov r5, #0 @ no more to copy - movne pc, r0 @ jump back to 1 (in the newly copied - @ code) - mov r7, #5 @ only here to fix NeTTroms which dont - mov r8, #2 << 24 @ scheduled for removal in 2.5.xx - orr r8, r8, #5 << 12 -2: +/* mov r7, #5*/ +/* mov r8, #0*/ diff -urN linux-2.4.21/arch/arm/boot/compressed/head-sa1100.S linux-2.4.22/arch/arm/boot/compressed/head-sa1100.S --- linux-2.4.21/arch/arm/boot/compressed/head-sa1100.S 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/head-sa1100.S 2003-08-25 04:44:39.000000000 -0700 @@ -11,7 +11,7 @@ #include #include - .section ".start", #alloc, #execinstr + .section ".start", "ax" __SA1100_start: diff -urN linux-2.4.21/arch/arm/boot/compressed/head-shark.S linux-2.4.22/arch/arm/boot/compressed/head-shark.S --- linux-2.4.21/arch/arm/boot/compressed/head-shark.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/head-shark.S 2003-08-25 04:44:39.000000000 -0700 @@ -16,7 +16,7 @@ #include - .section ".start", #alloc, #execinstr + .section ".start", "ax" b __beginning @@ -38,7 +38,7 @@ adr r1, __ofw_data add r2, r1, #4 mov lr, pc - b SYMBOL_NAME(ofw_init) + b ofw_init mov r1, #0 adr r2, __mmu_off @ calculate physical address @@ -109,7 +109,7 @@ add sp, sp, #128 adr r0, __ofw_data mov lr, pc - b SYMBOL_NAME(create_params) + b create_params mov r8, #0 mov r7, #15 diff -urN linux-2.4.21/arch/arm/boot/compressed/head.S linux-2.4.22/arch/arm/boot/compressed/head.S --- linux-2.4.21/arch/arm/boot/compressed/head.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/head.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/arm/boot/compressed/head.S * - * Copyright (C) 1996-1999 Russell King + * Copyright (C) 1996-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -19,6 +19,13 @@ */ #ifdef DEBUG #if defined(CONFIG_DEBUG_DC21285_PORT) + .macro loadsp, rb + mov \rb, #0x42000000 + .endm + .macro writeb, rb + str \rb, [r3, #0x160] + .endm +#elif defined(CONFIG_FOOTBRIDGE) .macro loadsp, rb mov \rb, #0x7c000000 .endm @@ -40,6 +47,15 @@ .macro writeb, rb strb \rb, [r3, #0] .endm +#elif defined(CONFIG_ARCH_AT91RM9200) + .macro loadsp, rb + mov \rb, #0xFF000000 @ BASE_DBGU (we cannot use ldr \reg, =AT91_DBGU_BASE) + add \rb, \rb, #0x00FF0000 + add \rb, \rb, #0x0000F200 + .endm + .macro writeb, rb + strb \rb, [r3, #0x1C] @ DBGU_THR (Transmitter Holding Register) + .endm #elif defined(CONFIG_ARCH_SA1100) .macro loadsp, rb mov \rb, #0x80000000 @ physical base address @@ -50,6 +66,11 @@ # endif .endm .macro writeb, rb +/* + * "The ARM peripheral bus does not support byte or half-word operations. + * All reads and writes of the UART by the CPU should be wordwide." + * - SA-1100 Developer's Manual, August 1999 + */ str \rb, [r3, #0x14] @ UTDR .endm #else @@ -144,33 +165,98 @@ */ .text -1: adr r2, LC0 - ldmia r2, {r2, r3, r4, r5, sp} + adr r0, LC0 + ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} + subs r0, r0, r1 @ calculate the delta offset + + teq r0, #0 @ if delta is zero, we're + beq not_relocated @ running at the address we + @ were linked at. - mov r0, #0 + /* + * We're running at a different address. We need to fix + * up various pointers: + * r5 - zImage base address + * r6 - GOT start + * ip - GOT end + */ + add r5, r5, r0 + add r6, r6, r0 + add ip, ip, r0 + +#ifndef CONFIG_ZBOOT_ROM + /* + * If we're running fully PIC === CONFIG_ZBOOT_ROM = n, + * we need to fix up pointers into the BSS region. + * r2 - BSS start + * r3 - BSS end + * sp - stack pointer + */ + add r2, r2, r0 + add r3, r3, r0 + add sp, sp, r0 + + /* + * Relocate all entries in the GOT table. + */ +1: ldr r1, [r6, #0] + add r1, r1, r0 + str r1, [r6], #4 + cmp r6, ip + blo 1b +#else + + /* + * Relocate entries in the GOT table. We only relocate + * the entries that are outside the (relocated) BSS region. + */ +1: ldr r1, [r6, #0] + cmp r1, r2 @ entry < bss_start || + cmphs r3, r1 @ _end < entry + addlo r1, r1, r0 + str r1, [r6], #4 + cmp r6, ip + blo 1b + +#endif + +not_relocated: mov r0, #0 1: str r0, [r2], #4 @ clear bss str r0, [r2], #4 str r0, [r2], #4 str r0, [r2], #4 cmp r2, r3 - blt 1b + blo 1b - mrc p15, 0, r6, c0, c0 @ get processor ID + /* + * The C runtime environment should now be setup + * sufficiently. Turn the cache on, set up some + * pointers, and start decompressing. + */ bl cache_on mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max - teq r4, r5 @ will we overwrite ourselves? - moveq r5, r2 @ decompress after image - movne r5, r4 @ decompress to final location +/* + * Check to see if we will overwrite ourselves. + * r4 = final kernel address + * r5 = start of this image + * r2 = end of malloc space (and therefore this image) + * We basically want: + * r4 >= r2 -> OK + * r4 + image length <= r5 -> OK + */ + cmp r4, r2 + bhs wont_overwrite + add r0, r4, #4096*1024 @ 4MB largest kernel size + cmp r0, r5 + bls wont_overwrite + mov r5, r2 @ decompress after malloc space mov r0, r5 mov r3, r7 - bl SYMBOL_NAME(decompress_kernel) - - teq r4, r5 @ do we need to relocate - beq call_kernel @ the kernel? + bl decompress_kernel add r0, r0, #127 bic r0, r0, #127 @ align the kernel length @@ -185,23 +271,39 @@ */ add r1, r5, r0 @ end of decompressed kernel adr r2, reloc_start - adr r3, reloc_end + ldr r3, LC1 + add r3, r2, r3 1: ldmia r2!, {r8 - r13} @ copy relocation code stmia r1!, {r8 - r13} ldmia r2!, {r8 - r13} stmia r1!, {r8 - r13} cmp r2, r3 - blt 1b + blo 1b bl cache_clean_flush add pc, r5, r0 @ call relocation code +/* + * We're not in danger of overwriting ourselves. Do this the simple way. + * + * r4 = kernel execution address + * r7 = architecture ID + */ +wont_overwrite: mov r0, r4 + mov r3, r7 + bl decompress_kernel + b call_kernel + .type LC0, #object -LC0: .word __bss_start - .word _end - .word _load_addr - .word _start - .word user_stack+4096 +LC0: .word LC0 @ r1 + .word __bss_start @ r2 + .word _end @ r3 + .word _load_addr @ r4 + .word _start @ r5 + .word _got_start @ r6 + .word _got_end @ ip + .word user_stack+4096 @ sp +LC1: .word reloc_end - reloc_start .size LC0, . - LC0 /* @@ -218,22 +320,15 @@ * r7 = architecture number * r8 = run-time address of "start" * On exit, - * r0, r1, r2, r3, r8, r9 corrupted + * r1, r2, r3, r8, r9, r12 corrupted * This routine must preserve: * r4, r5, r6, r7 */ .align 5 -cache_on: ldr r1, proc_sa110_type - eor r1, r1, r6 - movs r1, r1, lsr #5 @ catch SA110 and SA1100 - beq 1f - ldr r1, proc_sa1110_type - eor r1, r1, r6 - movs r1, r1, lsr #4 -@ movne pc, lr - bne cache_off -1: - sub r3, r4, #16384 @ Page directory size +cache_on: mov r3, #8 @ cache_on function + b call_cache_fn + +__setup_mmu: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer bic r3, r3, #0x3f00 /* @@ -248,9 +343,9 @@ orr r1, r1, #3 << 10 add r2, r3, #16384 1: cmp r1, r8 @ if virt > start of RAM - orrge r1, r1, #0x0c @ set cacheable, bufferable + orrhs r1, r1, #0x0c @ set cacheable, bufferable cmp r1, r9 @ if virt > end of RAM - bicge r1, r1, #0x0c @ clear cacheable, bufferable + bichs r1, r1, #0x0c @ clear cacheable, bufferable str r1, [r0], #4 @ 1:1 mapping add r1, r1, #1048576 teq r0, r2 @@ -269,24 +364,42 @@ str r1, [r0], #4 add r1, r1, #1048576 str r1, [r0] + mov pc, lr +__armv4_cache_on: + mov r12, lr + bl __setup_mmu mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - mcr p15, 0, r0, c8, c7 @ flush I,D TLBs - mcr p15, 0, r3, c2, c0 @ load page table pointer + mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs + mcr p15, 0, r3, c2, c0, 0 @ load page table pointer mov r0, #-1 - mcr p15, 0, r0, c3, c0 @ load domain access register - mrc p15, 0, r0, c1, c0 + mcr p15, 0, r0, c3, c0, 0 @ load domain access register + mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #0x1000 @ I-cache enable #ifndef DEBUG orr r0, r0, #0x003d @ Write buffer, mmu #endif - mcr p15, 0, r0, c1, c0 - mov pc, lr + mcr p15, 0, r0, c1, c0, 0 + mov pc, r12 + +__arm6_cache_on: + mov r12, lr + bl __setup_mmu + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 + mcr p15, 0, r3, c2, c0, 0 @ load page table pointer + mov r0, #-1 + mcr p15, 0, r0, c3, c0, 0 @ load domain access control + mov r0, #0x3d + mcr p15, 0, r0, c1, c0, 0 @ load control register + mov pc, r12 /* - * This code is relocatable. It is relocated by the above code to the end - * of the kernel and executed there. During this time, we have no stacks. + * All code following this line is relocatable. It is relocated by + * the above code to the end of the decompressed kernel image and + * executed there. During this time, we have no stacks. * * r0 = decompressed kernel length * r1-r3 = unused @@ -307,7 +420,7 @@ .endr cmp r5, r8 - blt 1b + blo 1b debug_reloc_end call_kernel: bl cache_clean_flush @@ -317,47 +430,117 @@ mov pc, r4 @ call kernel /* - * Here follow the relocatable cache support functions for - * the various processors. + * Here follow the relocatable cache support functions for the + * various processors. This is a generic hook for locating an + * entry and jumping to an instruction at the specified offset + * from the start of the block. Please note this is all position + * independent code. + * + * r1 = corrupted + * r2 = corrupted + * r3 = block offset + * r6 = corrupted + * r12 = corrupted */ - .type proc_sa110_type,#object -proc_sa110_type: - .word 0x4401a100 - .size proc_sa110_type, . - proc_sa110_type - - .type proc_sa1110_type,#object -proc_sa1110_type: - .word 0x6901b110 - .size proc_sa1110_type, . - proc_sa1110_type +call_cache_fn: adr r12, proc_types + mrc p15, 0, r6, c0, c0 @ get processor ID +1: ldr r1, [r12, #0] @ get value + ldr r2, [r12, #4] @ get mask + eor r1, r1, r6 @ (real ^ match) + tst r1, r2 @ & mask + addeq pc, r12, r3 @ call cache function + add r12, r12, #4*5 + b 1b + +/* + * Table for cache operations. This is basically: + * - CPU ID match + * - CPU ID mask + * - 'cache on' method instruction + * - 'cache off' method instruction + * - 'cache flush' method instruction + * + * We match an entry using: ((real_id ^ match) & mask) == 0 + * + * Writethrough caches generally only need 'on' and 'off' + * methods. Writeback caches _must_ have the flush method + * defined. + */ + .type proc_types,#object +proc_types: + .word 0x41560600 @ ARM6/610 + .word 0xffffffe0 + b __arm6_cache_off @ works, but slow + b __arm6_cache_off + mov pc, lr +@ b __arm6_cache_on @ untested +@ b __arm6_cache_off +@ b __armv3_cache_flush + + .word 0x41007000 @ ARM7/710 + .word 0xfff8fe00 + b __arm7_cache_off + b __arm7_cache_off + mov pc, lr + + .word 0x41807200 @ ARM720T (writethrough) + .word 0xffffff00 + b __armv4_cache_on + b __armv4_cache_off + mov pc, lr + + .word 0x41129200 @ ARM920T + .word 0xff00fff0 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x41029220 @ ARM922T + .word 0xff00fff0 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x4401a100 @ sa110 / sa1100 + .word 0xffffffe0 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x6901b110 @ sa1110 + .word 0xfffffff0 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x69050000 @ xscale + .word 0xffff0000 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0 @ unrecognised type + .word 0 + mov pc, lr + mov pc, lr + mov pc, lr + + .size proc_types, . - proc_types /* * Turn off the Cache and MMU. ARMv3 does not support * reading the control register, but ARMv4 does. * * On entry, r6 = processor ID - * On exit, r0, r1 corrupted + * On exit, r0, r1, r2, r3, r12 corrupted * This routine must preserve: r4, r6, r7 */ .align 5 -cache_off: -#ifdef CONFIG_CPU_ARM610 - eor r1, r6, #0x41000000 - eor r1, r1, #0x00560000 - bic r1, r1, #0x0000001f - teq r1, #0x00000600 - mov r0, #0x00000060 @ ARM6 control reg. - beq __armv3_cache_off -#endif -#ifdef CONFIG_CPU_ARM710 - eor r1, r6, #0x41000000 - bic r1, r1, #0x00070000 - bic r1, r1, #0x000000ff - teq r1, #0x00007000 @ ARM7 - teqne r1, #0x00007100 @ ARM710 - mov r0, #0x00000070 @ ARM7 control reg. - beq __armv3_cache_off -#endif +cache_off: mov r3, #12 @ cache_off function + b call_cache_fn + +__armv4_cache_off: mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d mcr p15, 0, r0, c1, c0 @ turn MMU and cache off @@ -366,11 +549,19 @@ mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 mov pc, lr +__arm6_cache_off: + mov r0, #0x00000030 @ ARM6 control reg. + b __armv3_cache_off + +__arm7_cache_off: + mov r0, #0x00000070 @ ARM7 control reg. + b __armv3_cache_off + __armv3_cache_off: - mcr p15, 0, r0, c1, c0 @ turn MMU and cache off + mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off mov r0, #0 - mcr p15, 0, r0, c7, c0 @ invalidate whole cache v3 - mcr p15, 0, r0, c5, c0 @ invalidate whole TLB v3 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 mov pc, lr /* @@ -379,23 +570,18 @@ * On entry, * r6 = processor ID * On exit, - * r1, r2, r12 corrupted + * r1, r2, r3, r12 corrupted * This routine must preserve: - * r4, r6, r7 + * r0, r4, r5, r6, r7 */ .align 5 cache_clean_flush: - ldr r1, proc_sa110_type - eor r1, r1, r6 - movs r1, r1, lsr #5 @ catch SA110 and SA1100 - beq 1f - ldr r1, proc_sa1110_type - eor r1, r1, r6 - movs r1, r1, lsr #4 - movne pc, lr -1: + mov r3, #16 + b call_cache_fn + +__armv4_cache_flush: bic r1, pc, #31 - add r2, r1, #32768 + add r2, r1, #65536 @ 2x the largest dcache size 1: ldr r12, [r1], #32 @ s/w flush D cache teq r1, r2 bne 1b @@ -404,6 +590,11 @@ mcr p15, 0, r1, c7, c10, 4 @ drain WB mov pc, lr +__armv3_cache_flush: + mov r1, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mov pc, lr + /* * Various debugging routines for printing hex characters and * memory, which again must be relocatable. @@ -479,5 +670,5 @@ reloc_end: .align - .section ".stack" + .section ".stack", "w" user_stack: .space 4096 diff -urN linux-2.4.21/arch/arm/boot/compressed/hw-bse.c linux-2.4.22/arch/arm/boot/compressed/hw-bse.c --- linux-2.4.21/arch/arm/boot/compressed/hw-bse.c 2000-08-13 09:54:15.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/hw-bse.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,74 +0,0 @@ -/* - * Bright Star Engineering Inc. - * - * code for readng parameters from the - * parameter blocks of the boot block - * flash memory - * - */ - -static int strcmp(const char *s1, const char *s2) -{ - while (*s1 != '\0' && *s1 == *s2) - { - s1++; - s2++; - } - - return (*(unsigned char *) s1) - (*(unsigned char *) s2); -} - -struct pblk_t { - char type; - unsigned short size; -}; - -static char *bse_getflashparam(char *name) { - unsigned int esize; - char *q,*r; - unsigned char *p,*e; - struct pblk_t *thepb = (struct pblk_t *) 0x00004000; - struct pblk_t *altpb = (struct pblk_t *) 0x00006000; - if (thepb->type&1) { - if (altpb->type&1) { - /* no valid param block */ - return (char*)0; - } else { - /* altpb is valid */ - struct pblk_t *tmp; - tmp = thepb; - thepb = altpb; - altpb = tmp; - } - } - p = (char*)thepb + sizeof(struct pblk_t); - e = p + thepb->size; - while (p < e) { - q = p; - esize = *p; - if (esize == 0xFF) break; - if (esize == 0) break; - if (esize > 127) { - esize = (esize&0x7F)<<8 | p[1]; - q++; - } - q++; - r=q; - if (*r && ((name == 0) || (!strcmp(name,r)))) { - while (*q++) ; - return q; - } - p+=esize; - } - return (char*)0; -} - -void bse_setup(void) { - /* extract the linux cmdline from flash */ - char *name=bse_getflashparam("linuxboot"); - char *x = (char *)0xc0000100; - if (name) { - while (*name) *x++=*name++; - } - *x=0; -} diff -urN linux-2.4.21/arch/arm/boot/compressed/ll_char_wr.S linux-2.4.22/arch/arm/boot/compressed/ll_char_wr.S --- linux-2.4.21/arch/arm/boot/compressed/ll_char_wr.S 2001-04-12 12:03:50.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/ll_char_wr.S 2003-08-25 04:44:39.000000000 -0700 @@ -19,144 +19,116 @@ #include #include - .text + .text -#define BOLD 0x01 -#define ITALIC 0x02 -#define UNDERLINE 0x04 -#define FLASH 0x08 -#define INVERSE 0x10 - -LC0: .word SYMBOL_NAME(bytes_per_char_h) - .word SYMBOL_NAME(video_size_row) - .word SYMBOL_NAME(acorndata_8x8) - .word SYMBOL_NAME(con_charconvtable) +LC0: .word LC0 + .word bytes_per_char_h + .word video_size_row + .word acorndata_8x8 + .word con_charconvtable +/* + * r0 = ptr + * r1 = char + * r2 = white + */ ENTRY(ll_write_char) - stmfd sp!, {r4 - r7, lr} + stmfd sp!, {r4 - r7, lr} @ @ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc) @ - eor ip, r1, #UNDERLINE << 9 -/* - * calculate colours - */ - tst r1, #INVERSE << 9 - moveq r2, r1, lsr #16 - moveq r3, r1, lsr #24 - movne r2, r1, lsr #24 - movne r3, r1, lsr #16 - and r3, r3, #255 - and r2, r2, #255 -/* - * calculate offset into character table - */ - mov r1, r1, lsl #23 - mov r1, r1, lsr #20 -/* - * calculate offset required for each row [maybe I should make this an argument to this fn. - * Have to see what the register usage is like in the calling routines. - */ - adr r4, LC0 - ldmia r4, {r4, r5, r6, lr} - ldr r4, [r4] - ldr r5, [r5] -/* - * Go to resolution-dependent routine... - */ - cmp r4, #4 - blt Lrow1bpp - eor r2, r3, r2 @ Create eor mask to change colour from bg - orr r3, r3, r3, lsl #8 @ to fg. - orr r3, r3, r3, lsl #16 - add r0, r0, r5, lsl #3 @ Move to bottom of character - add r1, r1, #7 - ldrb r7, [r6, r1] - tst ip, #UNDERLINE << 9 - eoreq r7, r7, #255 - teq r4, #8 - beq Lrow8bpplp + /* + * calculate offset into character table + */ + mov r1, r1, lsl #3 + /* + * calculate offset required for each row. + */ + adr ip, LC0 + ldmia ip, {r3, r4, r5, r6, lr} + sub ip, ip, r3 + add r6, r6, ip + add lr, lr, ip + ldr r4, [r4, ip] + ldr r5, [r5, ip] + /* + * Go to resolution-dependent routine... + */ + cmp r4, #4 + blt Lrow1bpp + add r0, r0, r5, lsl #3 @ Move to bottom of character + orr r1, r1, #7 + ldrb r7, [r6, r1] + teq r4, #8 + beq Lrow8bpplp @ @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) @ - orr r3, r3, r3, lsl #4 -Lrow4bpplp: ldr r7, [lr, r7, lsl #2] - mul r7, r2, r7 - tst r1, #7 @ avoid using r7 directly after - eor ip, r3, r7 - str ip, [r0, -r5]! - LOADREGS(eqfd, sp!, {r4 - r7, pc}) - sub r1, r1, #1 - ldrb r7, [r6, r1] - ldr r7, [lr, r7, lsl #2] - mul r7, r2, r7 - tst r1, #7 @ avoid using r7 directly after - eor ip, r3, r7 - str ip, [r0, -r5]! - subne r1, r1, #1 - ldrneb r7, [r6, r1] - bne Lrow4bpplp - LOADREGS(fd, sp!, {r4 - r7, pc}) +Lrow4bpplp: + ldr r7, [lr, r7, lsl #2] + mul r7, r2, r7 + sub r1, r1, #1 @ avoid using r7 directly after + str r7, [r0, -r5]! + ldrb r7, [r6, r1] + ldr r7, [lr, r7, lsl #2] + mul r7, r2, r7 + tst r1, #7 @ avoid using r7 directly after + str r7, [r0, -r5]! + subne r1, r1, #1 + ldrneb r7, [r6, r1] + bne Lrow4bpplp + LOADREGS(fd, sp!, {r4 - r7, pc}) @ @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) @ -Lrow8bpplp: mov ip, r7, lsr #4 - ldr ip, [lr, ip, lsl #2] - mul r4, r2, ip - and ip, r7, #15 @ avoid r4 - ldr ip, [lr, ip, lsl #2] @ avoid r4 - mul ip, r2, ip @ avoid r4 - eor r4, r3, r4 @ avoid ip - tst r1, #7 @ avoid ip - sub r0, r0, r5 @ avoid ip - eor ip, r3, ip - stmia r0, {r4, ip} - LOADREGS(eqfd, sp!, {r4 - r7, pc}) - sub r1, r1, #1 - ldrb r7, [r6, r1] - mov ip, r7, lsr #4 - ldr ip, [lr, ip, lsl #2] - mul r4, r2, ip - and ip, r7, #15 @ avoid r4 - ldr ip, [lr, ip, lsl #2] @ avoid r4 - mul ip, r2, ip @ avoid r4 - eor r4, r3, r4 @ avoid ip - tst r1, #7 @ avoid ip - sub r0, r0, r5 @ avoid ip - eor ip, r3, ip - stmia r0, {r4, ip} - subne r1, r1, #1 - ldrneb r7, [r6, r1] - bne Lrow8bpplp - LOADREGS(fd, sp!, {r4 - r7, pc}) +Lrow8bpplp: + mov ip, r7, lsr #4 + ldr ip, [lr, ip, lsl #2] + mul r4, r2, ip + and ip, r7, #15 @ avoid r4 + ldr ip, [lr, ip, lsl #2] @ avoid r4 + mul ip, r2, ip @ avoid r4 + sub r1, r1, #1 @ avoid ip + sub r0, r0, r5 @ avoid ip + stmia r0, {r4, ip} + ldrb r7, [r6, r1] + mov ip, r7, lsr #4 + ldr ip, [lr, ip, lsl #2] + mul r4, r2, ip + and ip, r7, #15 @ avoid r4 + ldr ip, [lr, ip, lsl #2] @ avoid r4 + mul ip, r2, ip @ avoid r4 + tst r1, #7 @ avoid ip + sub r0, r0, r5 @ avoid ip + stmia r0, {r4, ip} + subne r1, r1, #1 + ldrneb r7, [r6, r1] + bne Lrow8bpplp + LOADREGS(fd, sp!, {r4 - r7, pc}) @ @ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc) @ -Lrow1bpp: add r6, r6, r1 - ldmia r6, {r4, r7} - tst ip, #INVERSE << 9 - mvnne r4, r4 - mvnne r7, r7 - strb r4, [r0], r5 - mov r4, r4, lsr #8 - strb r4, [r0], r5 - mov r4, r4, lsr #8 - strb r4, [r0], r5 - mov r4, r4, lsr #8 - strb r4, [r0], r5 - strb r7, [r0], r5 - mov r7, r7, lsr #8 - strb r7, [r0], r5 - mov r7, r7, lsr #8 - strb r7, [r0], r5 - mov r7, r7, lsr #8 - tst ip, #UNDERLINE << 9 - mvneq r7, r7 - strb r7, [r0], r5 - LOADREGS(fd, sp!, {r4 - r7, pc}) +Lrow1bpp: + add r6, r6, r1 + ldmia r6, {r4, r7} + strb r4, [r0], r5 + mov r4, r4, lsr #8 + strb r4, [r0], r5 + mov r4, r4, lsr #8 + strb r4, [r0], r5 + mov r4, r4, lsr #8 + strb r4, [r0], r5 + strb r7, [r0], r5 + mov r7, r7, lsr #8 + strb r7, [r0], r5 + mov r7, r7, lsr #8 + strb r7, [r0], r5 + mov r7, r7, lsr #8 + strb r7, [r0], r5 + LOADREGS(fd, sp!, {r4 - r7, pc}) - .bss + .bss ENTRY(con_charconvtable) - .space 1024 + .space 1024 diff -urN linux-2.4.21/arch/arm/boot/compressed/misc.c linux-2.4.22/arch/arm/boot/compressed/misc.c --- linux-2.4.21/arch/arm/boot/compressed/misc.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/misc.c 2003-08-25 04:44:39.000000000 -0700 @@ -22,7 +22,6 @@ #include #include -#include #ifdef STANDALONE_DEBUG #define puts printf @@ -291,7 +290,6 @@ free_mem_ptr_end = free_mem_ptr_end_p; __machine_arch_type = arch_id; - proc_decomp_setup(); arch_decomp_setup(); makecrc(); @@ -315,4 +313,3 @@ return 0; } #endif - diff -urN linux-2.4.21/arch/arm/boot/compressed/vmlinux.lds.in linux-2.4.22/arch/arm/boot/compressed/vmlinux.lds.in --- linux-2.4.21/arch/arm/boot/compressed/vmlinux.lds.in 2001-07-02 14:40:14.000000000 -0700 +++ linux-2.4.22/arch/arm/boot/compressed/vmlinux.lds.in 2003-08-25 04:44:39.000000000 -0700 @@ -35,29 +35,26 @@ _etext = .; - .data : { - *(.data) - } - + _got_start = .; + .got : { *(.got) } + _got_end = .; + .got.plt : { *(.got.plt) } + .data : { *(.data) } _edata = .; . = BSS_START; __bss_start = .; - .bss : { - *(.bss) - } + .bss : { *(.bss) } _end = .; - .stack : { - *(.stack) - } - - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } + .stack (NOLOAD) : { *(.stack) } + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } } diff -urN linux-2.4.21/arch/arm/common/Makefile linux-2.4.22/arch/arm/common/Makefile --- linux-2.4.21/arch/arm/common/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/common/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,17 @@ +# +# Makefile for the linux kernel. +# + +O_TARGET := nopci.o + +export-objs := pcipool.o + +obj-y := +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_USB_OHCI_SA1111) += pcipool.o +obj-$(CONFIG_USB_OHCI_AT91) += pcipool.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/arm/common/pcipool.c linux-2.4.22/arch/arm/common/pcipool.c --- linux-2.4.21/arch/arm/common/pcipool.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/common/pcipool.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,391 @@ +/* + NOTE: + + this code was lifted straight out of drivers/pci/pci.c; + when compiling for the Intel StrongARM SA-1110/SA-1111 the + usb-ohci.c driver needs these routines even when the architecture + has no pci bus... +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Pool allocator ... wraps the pci_alloc_consistent page allocator, so + * small blocks are easily used by drivers for bus mastering controllers. + * This should probably be sharing the guts of the slab allocator. + */ + +struct pci_pool { /* the pool */ + struct list_head page_list; + spinlock_t lock; + size_t blocks_per_page; + size_t size; + struct pci_dev *dev; + size_t allocation; + char name [32]; + wait_queue_head_t waitq; +}; + +struct pci_page { /* cacheable header for 'allocation' bytes */ + struct list_head page_list; + void *vaddr; + dma_addr_t dma; + unsigned long bitmap [0]; +}; + +#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) +#define POOL_POISON_BYTE 0xa7 + +// #define CONFIG_PCIPOOL_DEBUG + +static inline const char *slot_name(const struct pci_pool *pool) +{ + const struct pci_dev *pdev = pool->dev; + + if (pdev == 0) + return "[0]"; + + else if (dev_is_sa1111(pdev)) + return "[SA-1111]"; + else + return pdev->slot_name; +} + + +/** + * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma. + * @name: name of pool, for diagnostics + * @pdev: pci device that will be doing the DMA + * @size: size of the blocks in this pool. + * @align: alignment requirement for blocks; must be a power of two + * @allocation: returned blocks won't cross this boundary (or zero) + * @mem_flags: SLAB_* flags. + * + * Returns a pci allocation pool with the requested characteristics, or + * null if one can't be created. Given one of these pools, pci_pool_alloc() + * may be used to allocate memory. Such memory will all have "consistent" + * DMA mappings, accessible by the device and its driver without using + * cache flushing primitives. The actual size of blocks allocated may be + * larger than requested because of alignment. + * + * If allocation is nonzero, objects returned from pci_pool_alloc() won't + * cross that size boundary. This is useful for devices which have + * addressing restrictions on individual DMA transfers, such as not crossing + * boundaries of 4KBytes. + */ +struct pci_pool * +pci_pool_create (const char *name, struct pci_dev *pdev, + size_t size, size_t align, size_t allocation, int mem_flags) +{ + struct pci_pool *retval; + + if (align == 0) + align = 1; + if (size == 0) + return 0; + else if (size < align) + size = align; + else if ((size % align) != 0) { + size += align + 1; + size &= ~(align - 1); + } + + if (allocation == 0) { + if (PAGE_SIZE < size) + allocation = size; + else + allocation = PAGE_SIZE; + // FIXME: round up for less fragmentation + } else if (allocation < size) + return 0; + + if (!(retval = kmalloc (sizeof *retval, mem_flags))) + return retval; + + strncpy (retval->name, name, sizeof retval->name); + retval->name [sizeof retval->name - 1] = 0; + + retval->dev = pdev; + INIT_LIST_HEAD (&retval->page_list); + spin_lock_init (&retval->lock); + retval->size = size; + retval->allocation = allocation; + retval->blocks_per_page = allocation / size; + init_waitqueue_head (&retval->waitq); + +#ifdef CONFIG_PCIPOOL_DEBUG + printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n", + slot_name(retval), retval->name, size, + retval->blocks_per_page, allocation); +#endif + + return retval; +} + + +static struct pci_page * +pool_alloc_page (struct pci_pool *pool, int mem_flags) +{ + struct pci_page *page; + int mapsize; + + mapsize = pool->blocks_per_page; + mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG; + mapsize *= sizeof (long); + + page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags); + if (!page) + return 0; + page->vaddr = pci_alloc_consistent (pool->dev, + pool->allocation, + &page->dma); + if (page->vaddr) { + memset (page->bitmap, 0xff, mapsize); // bit set == free +#ifdef CONFIG_DEBUG_SLAB + memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); +#endif + list_add (&page->page_list, &pool->page_list); + } else { + kfree (page); + page = 0; + } + return page; +} + + +static inline int +is_page_busy (int blocks, unsigned long *bitmap) +{ + while (blocks > 0) { + if (*bitmap++ != ~0UL) + return 1; + blocks -= BITS_PER_LONG; + } + return 0; +} + +static void +pool_free_page (struct pci_pool *pool, struct pci_page *page) +{ + dma_addr_t dma = page->dma; + +#ifdef CONFIG_DEBUG_SLAB + memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); +#endif + pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma); + list_del (&page->page_list); + kfree (page); +} + + +/** + * pci_pool_destroy - destroys a pool of pci memory blocks. + * @pool: pci pool that will be destroyed + * + * Caller guarantees that no more memory from the pool is in use, + * and that nothing will try to use the pool after this call. + */ +void +pci_pool_destroy (struct pci_pool *pool) +{ + unsigned long flags; + +#ifdef CONFIG_PCIPOOL_DEBUG + printk (KERN_DEBUG "pcipool destroy %s/%s\n", + slot_name(pool), pool->name); +#endif + + spin_lock_irqsave (&pool->lock, flags); + while (!list_empty (&pool->page_list)) { + struct pci_page *page; + page = list_entry (pool->page_list.next, + struct pci_page, page_list); + if (is_page_busy (pool->blocks_per_page, page->bitmap)) { + printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n", + slot_name(pool), pool->name, page->vaddr); + /* leak the still-in-use consistent memory */ + list_del (&page->page_list); + kfree (page); + } else + pool_free_page (pool, page); + } + spin_unlock_irqrestore (&pool->lock, flags); + kfree (pool); +} + + +/** + * pci_pool_alloc - get a block of consistent memory + * @pool: pci pool that will produce the block + * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC + * @handle: pointer to dma address of block + * + * This returns the kernel virtual address of a currently unused block, + * and reports its dma address through the handle. + * If such a memory block can't be allocated, null is returned. + */ +void * +pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle) +{ + unsigned long flags; + struct list_head *entry; + struct pci_page *page; + int map, block; + size_t offset; + void *retval; + +restart: + spin_lock_irqsave (&pool->lock, flags); + list_for_each (entry, &pool->page_list) { + int i; + page = list_entry (entry, struct pci_page, page_list); + /* only cachable accesses here ... */ + for (map = 0, i = 0; + i < pool->blocks_per_page; + i += BITS_PER_LONG, map++) { + if (page->bitmap [map] == 0) + continue; + block = ffz (~ page->bitmap [map]); + if ((i + block) < pool->blocks_per_page) { + clear_bit (block, &page->bitmap [map]); + offset = (BITS_PER_LONG * map) + block; + offset *= pool->size; + goto ready; + } + } + } + if (!(page = pool_alloc_page (pool, mem_flags))) { + if (mem_flags == SLAB_KERNEL) { + DECLARE_WAITQUEUE (wait, current); + + current->state = TASK_INTERRUPTIBLE; + add_wait_queue (&pool->waitq, &wait); + spin_unlock_irqrestore (&pool->lock, flags); + + schedule_timeout (POOL_TIMEOUT_JIFFIES); + + current->state = TASK_RUNNING; + remove_wait_queue (&pool->waitq, &wait); + goto restart; + } + retval = 0; + goto done; + } + + clear_bit (0, &page->bitmap [0]); + offset = 0; +ready: + retval = offset + page->vaddr; + *handle = offset + page->dma; +done: + spin_unlock_irqrestore (&pool->lock, flags); + return retval; +} + + +static struct pci_page * +pool_find_page (struct pci_pool *pool, dma_addr_t dma) +{ + unsigned long flags; + struct list_head *entry; + struct pci_page *page; + + spin_lock_irqsave (&pool->lock, flags); + list_for_each (entry, &pool->page_list) { + page = list_entry (entry, struct pci_page, page_list); + if (dma < page->dma) + continue; + if (dma < (page->dma + pool->allocation)) + goto done; + } + page = 0; +done: + spin_unlock_irqrestore (&pool->lock, flags); + return page; +} + + +/** + * pci_pool_free - put block back into pci pool + * @pool: the pci pool holding the block + * @vaddr: virtual address of block + * @dma: dma address of block + * + * Caller promises neither device nor driver will again touch this block + * unless it is first re-allocated. + */ +void +pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) +{ + struct pci_page *page; + unsigned long flags; + int map, block; + + if ((page = pool_find_page (pool, dma)) == 0) { + printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n", + pool->dev ? pool->dev->slot_name : NULL, + pool->name, vaddr, (unsigned long) dma); + return; + } + + block = dma - page->dma; + block /= pool->size; + map = block / BITS_PER_LONG; + block %= BITS_PER_LONG; + +#ifdef CONFIG_DEBUG_SLAB + if (((dma - page->dma) + (void *)page->vaddr) != vaddr) { + printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n", + pool->dev ? pool->dev->slot_name : NULL, + pool->name, vaddr, (unsigned long) dma); + return; + } + if (page->bitmap [map] & (1UL << block)) { + printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n", + pool->dev ? pool->dev->slot_name : NULL, + pool->name, dma); + return; + } + memset (vaddr, POOL_POISON_BYTE, pool->size); +#endif + + spin_lock_irqsave (&pool->lock, flags); + set_bit (block, &page->bitmap [map]); + if (waitqueue_active (&pool->waitq)) + wake_up (&pool->waitq); + /* + * Resist a temptation to do + * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page); + * it is not interrupt safe. Better have empty pages hang around. + */ + spin_unlock_irqrestore (&pool->lock, flags); +} + + +EXPORT_SYMBOL (pci_pool_create); +EXPORT_SYMBOL (pci_pool_destroy); +EXPORT_SYMBOL (pci_pool_alloc); +EXPORT_SYMBOL (pci_pool_free); + +/* **************************************** */ + +static int __init pcipool_init(void) +{ + MOD_INC_USE_COUNT; /* never unload */ + + return 0; +} +module_init(pcipool_init); + +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/arch/arm/config.in linux-2.4.22/arch/arm/config.in --- linux-2.4.21/arch/arm/config.in 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/config.in 2003-08-25 04:44:39.000000000 -0700 @@ -2,7 +2,7 @@ # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. # -mainmenu_name "Linux Kernel Configuration" +mainmenu_name "ARM Linux Kernel Configuration" define_bool CONFIG_ARM y define_bool CONFIG_EISA n @@ -39,14 +39,17 @@ CLPS711x/EP721x-based CONFIG_ARCH_CLPS711X \ Co-EBSA285 CONFIG_ARCH_CO285 \ EBSA-110 CONFIG_ARCH_EBSA110 \ - Epxa10db CONFIG_ARCH_CAMELOT \ + Excalibur-ARM CONFIG_ARCH_CAMELOT \ FootBridge CONFIG_ARCH_FOOTBRIDGE \ Integrator CONFIG_ARCH_INTEGRATOR \ + Omaha CONFIG_ARCH_OMAHA \ LinkUp-L7200 CONFIG_ARCH_L7200 \ Motorola-MX1ADS CONFIG_ARCH_MX1ADS \ RiscPC CONFIG_ARCH_RPC \ - SA1100-based CONFIG_ARCH_SA1100 \ - Shark CONFIG_ARCH_SHARK" RiscPC + RiscStation CONFIG_ARCH_RISCSTATION \ + SA1100-based CONFIG_ARCH_SA1100 \ + Shark CONFIG_ARCH_SHARK \ + AT91RM9200-based CONFIG_ARCH_AT91RM9200 " RiscPC mainmenu_option next_comment comment 'Archimedes/A5000 Implementations' @@ -69,10 +72,14 @@ mainmenu_option next_comment comment 'SA11x0 Implementations' +dep_bool ' ACCELENT DevBoard' CONFIG_SA1100_ACCELENT $CONFIG_ARCH_SA1100 dep_bool ' Assabet' CONFIG_SA1100_ASSABET $CONFIG_ARCH_SA1100 dep_bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET $CONFIG_SA1100_ASSABET +dep_bool ' ADS Advanced Graphics Client' CONFIG_SA1100_ADSAGC $CONFIG_ARCH_SA1100 dep_bool ' ADS Bitsy' CONFIG_SA1100_ADSBITSY $CONFIG_ARCH_SA1100 +dep_bool ' ADS Bitsy Plus' CONFIG_SA1100_ADSBITSYPLUS $CONFIG_ARCH_SA1100 dep_bool ' Brutus' CONFIG_SA1100_BRUTUS $CONFIG_ARCH_SA1100 +dep_bool ' Cep' CONFIG_SA1100_CEP $CONFIG_ARCH_SA1100 dep_bool ' CerfBoard' CONFIG_SA1100_CERF $CONFIG_ARCH_SA1100 if [ "$CONFIG_SA1100_CERF" = "y" ]; then choice 'Cerf RAM available' \ @@ -94,6 +101,8 @@ else define_bool CONFIG_SA1100_H3XXX n fi +dep_tristate 'Compaq iPAQ Handheld sleeve support' CONFIG_H3600_SLEEVE $CONFIG_SA1100_H3600 +#dep_bool ' Consus' CONFIG_SA1100_CONSUS $CONFIG_ARCH_SA1100 #dep_bool ' Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100 dep_bool ' Extenex HandHeld Theater (Squashtail)' CONFIG_SA1100_EXTENEX1 $CONFIG_ARCH_SA1100 if [ "$CONFIG_SA1100_EXTENEX1" = "y" ]; then @@ -104,6 +113,7 @@ dep_bool ' Frodo' CONFIG_SA1100_FRODO $CONFIG_ARCH_SA1100 dep_bool ' GraphicsClient Plus' CONFIG_SA1100_GRAPHICSCLIENT $CONFIG_ARCH_SA1100 dep_bool ' GraphicsMaster' CONFIG_SA1100_GRAPHICSMASTER $CONFIG_ARCH_SA1100 +dep_bool ' HackKit Core Board' CONFIG_SA1100_HACKKIT $CONFIG_ARCH_SA1100 dep_bool ' HP Labs BadgePAD 4' CONFIG_SA1100_BADGE4 $CONFIG_ARCH_SA1100 dep_bool ' HP Jornada 720' CONFIG_SA1100_JORNADA720 $CONFIG_ARCH_SA1100 dep_bool ' HuW WebPanel' CONFIG_SA1100_HUW_WEBPANEL $CONFIG_ARCH_SA1100 @@ -117,29 +127,23 @@ dep_bool ' Shannon' CONFIG_SA1100_SHANNON $CONFIG_ARCH_SA1100 dep_bool ' Sherman' CONFIG_SA1100_SHERMAN $CONFIG_ARCH_SA1100 dep_bool ' Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100 +dep_bool ' Simputer' CONFIG_SA1100_SIMPUTER $CONFIG_ARCH_SA1100 dep_bool ' Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100 dep_bool ' Victor' CONFIG_SA1100_VICTOR $CONFIG_ARCH_SA1100 dep_bool ' XP860' CONFIG_SA1100_XP860 $CONFIG_ARCH_SA1100 dep_bool ' Yopy' CONFIG_SA1100_YOPY $CONFIG_ARCH_SA1100 -# Determine if SA1111 support is required -if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \ - "$CONFIG_SA1100_JORNADA720" = "y" -o \ - "$CONFIG_SA1100_PFS168" = "y" -o \ - "$CONFIG_SA1100_XP860" = "y" -o \ - "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \ - "$CONFIG_SA1100_PT_SYSTEM3" = "y" -o \ - "$CONFIG_SA1100_ADSBITSY" = "y" -o \ - "$CONFIG_SA1100_BADGE4" = "y" ]; then - define_bool CONFIG_SA1111 y - define_int CONFIG_FORCE_MAX_ZONEORDER 9 -fi +dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100 +dep_tristate ' Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB +dep_tristate ' Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB -#dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100 -#dep_tristate ' Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB -#dep_tristate ' Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB +dep_tristate 'SA1100 Generic PIO SSP support' CONFIG_SA1100_SSP $CONFIG_ARCH_SA1100 -dep_tristate 'Compaq iPAQ Handheld sleeve support' CONFIG_H3600_SLEEVE $CONFIG_SA1100_H3600 +endmenu + +mainmenu_option next_comment +comment 'AT91RM9200 Implementations' +dep_bool ' Atmel AT91RM9200 Development Board' CONFIG_ARCH_AT91RM9200DK $CONFIG_ARCH_AT91RM9200 endmenu mainmenu_option next_comment @@ -148,8 +152,10 @@ dep_bool ' CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X dep_bool ' CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X dep_bool ' EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X -dep_bool ' P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X dep_bool ' FORTUNET' CONFIG_ARCH_FORTUNET $CONFIG_ARCH_CLPS711X +dep_bool ' GUIDEA07' CONFIG_ARCH_GUIDEA07 $CONFIG_ARCH_CLPS711X +dep_bool ' P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X + # XXX Maybe these should indicate register compatibility # instead of being mutually exclusive. @@ -168,6 +174,11 @@ "$CONFIG_ARCH_EP7212" = "y" ]; then bool ' EP72xx ROM boot' CONFIG_EP72XX_ROM_BOOT fi + +if [ "$CONFIG_ARCH_GUIDEA07" = "y" ]; then + define_bool CONFIG_ARCH_CDB89712 y +fi + endmenu # Definitions to make life easier @@ -178,7 +189,8 @@ define_bool CONFIG_ARCH_ACORN n fi -# see Documentation/arm/ConfigVars for a description of these +##################################################################### +# Footbridge support if [ "$CONFIG_ARCH_CO285" = "y" -o \ "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then define_bool CONFIG_FOOTBRIDGE y @@ -204,6 +216,42 @@ define_bool CONFIG_ARCH_EBSA285 y fi +##################################################################### +# SA1111 support +if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \ + "$CONFIG_SA1100_ACCELENT" = "y" -o \ + "$CONFIG_SA1100_ADSAGC" = "y" -o \ + "$CONFIG_SA1100_ADSBITSY" = "y" -o \ + "$CONFIG_SA1100_ADSBITSYPLUS" = "y" -o \ + "$CONFIG_SA1100_BADGE4" = "y" -o \ + "$CONFIG_SA1100_CONSUS" = "y" -o \ + "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \ + "$CONFIG_SA1100_JORNADA720" = "y" -o \ + "$CONFIG_SA1100_PFS168" = "y" -o \ + "$CONFIG_SA1100_PT_SYSTEM3" = "y" -o \ + "$CONFIG_SA1100_XP860" = "y" ]; then + define_bool CONFIG_SA1111 y + define_int CONFIG_FORCE_MAX_ZONEORDER 9 +fi + +if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then + choice 'EPXA system type' \ + "EPXA10DB CONFIG_EPXA10DB \ + EPXA1DB CONFIG_EPXA1DB" EPXA10DB + +if [ "$CONFIG_EPXA10DB" = "y" ]; then + choice 'EPXA10B version' \ + "SDR CONFIG_EPXA10DB_R2 \ + DDR CONFIG_EPXA10DB_R3" DDR +fi + + comment 'PLD hotswap support' + define_bool CONFIG_PLD y + dep_bool 'Support for PLD device hotplugging' CONFIG_PLD_HOTSWAP $CONFIG_EXPERIMENTAL +fi + +comment 'Processor Type' + # Figure out whether this system uses 26-bit or 32-bit CPUs. if [ "$CONFIG_ARCH_ARCA5K" = "y" ]; then define_bool CONFIG_CPU_32 n @@ -214,28 +262,9 @@ define_bool CONFIG_CPU_26 n fi -comment 'Processor Type' - -# Firstly, figure out what processor architecture version we should be using. -if [ "$CONFIG_ARCH_RPC" = "y" -o "$CONFIG_ARCH_CLPS7500" = "y" ]; then - define_bool CONFIG_CPU_32v3 y -else - define_bool CONFIG_CPU_32v3 n -fi -if [ "$CONFIG_ARCH_EBSA110" = "y" -o "$CONFIG_FOOTBRIDGE" = "y" -o \ - "$CONFIG_ARCH_TBOX" = "y" -o "$CONFIG_ARCH_SHARK" = "y" -o \ - "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \ - "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100" = "y" -o \ - "$CONFIG_ARCH_L7200" = "y" -o "$CONFIG_ARCH_ANAKIN" = "y" -o \ - "$CONFIG_ARCH_CAMELOT" = "y" -o "$CONFIG_ARCH_MX1ADS" = "y" ]; then - define_bool CONFIG_CPU_32v4 y -else - define_bool CONFIG_CPU_32v4 n -fi - -# Select CPU types depending on the architecture selected. -# We use this to select which CPUs are supported, and to select -# the compiler tuning options. +# Select CPU types depending on the architecture selected. This selects +# which CPUs we support in the kernel image, and the compiler instruction +# optimiser behaviour. # ARM610 if [ "$CONFIG_ARCH_RPC" = "y" ]; then @@ -245,7 +274,8 @@ fi # ARM710 -if [ "$CONFIG_ARCH_CLPS7500" = "y" ]; then +if [ "$CONFIG_ARCH_CLPS7500" = "y" -o \ + "$CONFIG_ARCH_RISCSTATION" = "y" ]; then define_bool CONFIG_CPU_ARM710 y else if [ "$CONFIG_ARCH_RPC" = "y" ]; then @@ -269,10 +299,12 @@ fi # ARM920T -if [ "$CONFIG_ARCH_MX1ADS" = "y" ]; then +if [ "$CONFIG_ARCH_MX1ADS" = "y" -o \ + "$CONFIG_ARCH_AT91RM9200" = "y" ]; then define_bool CONFIG_CPU_ARM920T y else - if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then + if [ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \ + "$CONFIG_ARCH_OMAHA" = "y" ]; then bool 'Support ARM920T processor' CONFIG_CPU_ARM920T else define_bool CONFIG_CPU_ARM920T n @@ -280,28 +312,13 @@ fi -if [ "$CONFIG_CPU_ARM920T" = "y" ]; then - bool ' ARM920T CPU idle' CONFIG_CPU_ARM920_CPU_IDLE - bool ' ARM920T I-Cache on' CONFIG_CPU_ARM920_I_CACHE_ON - bool ' ARM920T D-Cache on' CONFIG_CPU_ARM920_D_CACHE_ON - if [ "$CONFIG_CPU_ARM920_D_CACHE_ON" = "y" ] ; then - bool ' Force write through caches on ARM920T' CONFIG_CPU_ARM920_WRITETHROUGH - fi -fi - # ARM922T if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then - define_bool CONFIG_CPU_ARM922T y + define_bool CONFIG_CPU_ARM922T y + define_bool CONFIG_PLD y else - define_bool CONFIG_CPU_ARM922T n -fi -if [ "$CONFIG_CPU_ARM922T" = "y" ]; then - bool ' ARM922T CPU idle' CONFIG_CPU_ARM922_CPU_IDLE - bool ' ARM922T I-Cache on' CONFIG_CPU_ARM922_I_CACHE_ON - bool ' ARM922T D-Cache on' CONFIG_CPU_ARM922_D_CACHE_ON - if [ "$CONFIG_CPU_ARM922_D_CACHE_ON" = "y" ] ; then - bool ' Force write through caches on ARM922T' CONFIG_CPU_ARM922_WRITETHROUGH - fi + define_bool CONFIG_CPU_ARM922T n + define_bool CONFIG_PLD n fi # ARM926T @@ -310,18 +327,6 @@ else define_bool CONFIG_CPU_ARM926T n fi -if [ "$CONFIG_CPU_ARM926T" = "y" ]; then - bool ' ARM926T CPU idle' CONFIG_CPU_ARM926_CPU_IDLE - bool ' ARM926T I-Cache on' CONFIG_CPU_ARM926_I_CACHE_ON - bool ' ARM926T D-Cache on' CONFIG_CPU_ARM926_D_CACHE_ON - if [ "$CONFIG_CPU_ARM926_D_CACHE_ON" = "y" ] ; then - bool ' Force write through caches on ARM926T' CONFIG_CPU_ARM926_WRITETHROUGH - fi - if [ "$CONFIG_CPU_ARM926_I_CACHE_ON" = "y" -o \ - "$CONFIG_CPU_ARM926_D_CACHE_ON" = "y" ]; then - bool ' Round robin I and D cache replacement algorithm' CONFIG_CPU_ARM926_ROUND_ROBIN - fi -fi # ARM1020 if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then @@ -329,16 +334,12 @@ else define_bool CONFIG_CPU_ARM1020 n fi -if [ "$CONFIG_CPU_ARM1020" = "y" ]; then - bool ' ARM1020 I-Cache on' CONFIG_CPU_ARM1020_I_CACHE_ON - bool ' ARM10 D-Cache on' CONFIG_CPU_ARM1020_D_CACHE_ON - if [ "$CONFIG_CPU_ARM1020_D_CACHE_ON" = "y" ] ; then - bool ' Force write through caches on ARM1020' CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH - fi - if [ "$CONFIG_CPU_ARM1020_I_CACHE_ON" = "y" -o \ - "$CONFIG_CPU_ARM1020_D_CACHE_ON" = "y" ]; then - bool ' Round robin I and D cache replacement algorithm' CONFIG_CPU_ARM1020_ROUND_ROBIN - fi + +# ARM1026EJ-S +if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then + bool 'Support ARM1026EJ-S processor' CONFIG_CPU_ARM1026 +else + define_bool CONFIG_CPU_ARM1026 n fi # SA110 @@ -361,13 +362,59 @@ define_bool CONFIG_CPU_SA1100 n fi -if [ "$CONFIG_CPU_32" = "y" ]; then - dep_bool 'Support Thumb instructions (experimental)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL +# Figure out what processor architecture version we should be using. +# This defines the compiler instruction set which depends on the machine type. + +if [ "$CONFIG_ARCH_RPC" = "y" -o \ + "$CONFIG_ARCH_RISCSTATION" = "y" -o \ + "$CONFIG_ARCH_CLPS7500" = "y" ]; then + define_bool CONFIG_CPU_32v3 y +else + define_bool CONFIG_CPU_32v3 n +fi +if [ "$CONFIG_ARCH_EBSA110" = "y" -o "$CONFIG_FOOTBRIDGE" = "y" -o \ + "$CONFIG_ARCH_TBOX" = "y" -o "$CONFIG_ARCH_SHARK" = "y" -o \ + "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \ + "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100" = "y" -o \ + "$CONFIG_ARCH_L7200" = "y" -o "$CONFIG_ARCH_ANAKIN" = "y" -o \ + "$CONFIG_ARCH_CAMELOT" = "y" -o "$CONFIG_ARCH_MX1ADS" = "y" -o \ + "$CONFIG_ARCH_OMAHA" = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" ]; then + define_bool CONFIG_CPU_32v4 y +else + define_bool CONFIG_CPU_32v4 n +fi + +comment 'Processor Features' + +if [ "$CONFIG_CPU_ARM720T" = "y" -o "$CONFIG_CPU_ARM920T" = "y" -o \ + "$CONFIG_CPU_ARM922T" = "y" -o "$CONFIG_CPU_ARM926T" = "y" -o \ + "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then + dep_bool 'Support Thumb instructions (EXPERIMENTAL)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL +fi +if [ "$CONFIG_CPU_ARM920T" = "y" -o "$CONFIG_CPU_ARM922T" = "y" -o \ + "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \ + "$CONFIG_CPU_ARM1026" = "y" ]; then + bool 'Disable I-Cache' CONFIG_CPU_ICACHE_DISABLE + bool 'Disable D-Cache' CONFIG_CPU_DCACHE_DISABLE + if [ "$CONFIG_CPU_DISABLE_DCACHE" = "n" ]; then + bool 'Force write through D-cache' CONFIG_CPU_DCACHE_WRITETHROUGH + fi +fi +if [ "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \ + "$CONFIG_CPU_ARM1026" = "y" ]; then + if [ "$CONFIG_CPU_ICACHE_DISABLE" = "n" -o "$CONFIG_CPU_DCACHE_DISABLE" = "n" ]; then + bool 'Round robin I and D cache replacement algorithm' CONFIG_CPU_CACHE_ROUND_ROBIN + fi fi +if [ "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then + bool 'Disable branch prediction' CONFIG_CPU_BPREDICT_DISABLE +fi + # Select various configuration options depending on the machine type if [ "$CONFIG_ARCH_EDB7211" = "y" -o \ - "$CONFIG_ARCH_SA1100" = "y" ]; then + "$CONFIG_ARCH_SA1100" = "y" -o \ + "$CONFIG_ARCH_RISCSTATION" = "y" ]; then define_bool CONFIG_DISCONTIGMEM y else define_bool CONFIG_DISCONTIGMEM n @@ -395,6 +442,7 @@ if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \ "$CONFIG_ARCH_SHARK" = "y" -o \ "$CONFIG_ARCH_CLPS7500" = "y" -o \ + "$CONFIG_ARCH_RISCSTATION" = "y" -o \ "$CONFIG_ARCH_EBSA110" = "y" -o \ "$CONFIG_ARCH_CDB89712" = "y" -o \ "$CONFIG_ARCH_EDB7211" = "y" -o \ @@ -411,6 +459,12 @@ define_bool CONFIG_ISA_DMA n fi +# Compressed boot loader in ROM. Yes, we really want to ask about +# TEXT and BSS so we preserve their values in the config files. +bool 'Compressed boot loader in ROM/flash' CONFIG_ZBOOT_ROM +hex 'Compressed ROM boot loader base address' CONFIG_ZBOOT_ROM_TEXT 0 +hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0 + if [ "$CONFIG_ARCH_SA1100" = "y" -o \ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL @@ -423,13 +477,23 @@ else define_bool CONFIG_PCMCIA n fi +if [ "$CONFIG_SA1100_ACCELENT" = "y" ]; then + if [ "$CONFIG_PCMCIA" != "n" ]; then + bool ' Use second PCMCIA/CF slot (disables on-board IDE)' CONFIG_SA_PCMCIA_SLOT_1 y + fi +fi bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT bool 'Sysctl support' CONFIG_SYSCTL comment 'At least one math emulation must be selected' tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE -dep_tristate 'FastFPE math emulation (experimental)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL +if [ "$CONFIG_FPE_NWFPE" != "n" ]; then + bool ' Support extended precision' CONFIG_FPE_NWFPE_XP +fi +if [ "$CONFIG_CPU_26" = "n" -a "$CONFIG_CPU_32v3" = "n" ]; then + dep_tristate 'FastFPE math emulation (EXPERIMENTAL)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL +fi choice 'Kernel core (/proc/kcore) format' \ "ELF CONFIG_KCORE_ELF \ A.OUT CONFIG_KCORE_AOUT" ELF @@ -438,19 +502,8 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32 +string 'Default kernel command string' CONFIG_CMDLINE "" -if [ "$CONFIG_ARCH_EBSA110" = "y" -o \ - "$CONFIG_ARCH_SA1100" = "y" -o \ - "$CONFIG_ARCH_CLPS7500" = "y" -o \ - "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \ - "$CONFIG_ARCH_CATS" = "y" -o \ - "$CONFIG_ARCH_P720T" = "y" -o \ - "$CONFIG_ARCH_CDB89712" = "y" -o \ - "$CONFIG_ARCH_CAMELOT" = "y" -o \ - "$CONFIG_ARCH_ANAKIN" = "y" -o \ - "$CONFIG_ARCH_MX1ADS" = "y" ]; then - string 'Default kernel command string' CONFIG_CMDLINE "" -fi if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \ "$CONFIG_ARCH_EBSA110" = "y" -o \ "$CONFIG_ARCH_EBSA285" = "y" -o \ @@ -460,7 +513,8 @@ "$CONFIG_ARCH_SA1100" = "y" -o \ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \ "$CONFIG_ARCH_CDB89712" = "y" -o \ - "$CONFIG_ARCH_P720T" = "y" ]; then + "$CONFIG_ARCH_P720T" = "y" -o \ + "$CONFIG_ARCH_OMAHA" = "y" ]; then bool 'Timer and CPU usage LEDs' CONFIG_LEDS if [ "$CONFIG_LEDS" = "y" ]; then if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \ @@ -469,17 +523,24 @@ "$CONFIG_ARCH_CO285" = "y" -o \ "$CONFIG_ARCH_SA1100" = "y" -o \ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \ - "$CONFIG_ARCH_P720T" = "y" ]; then + "$CONFIG_ARCH_P720T" = "y" -o \ + "$CONFIG_ARCH_OMAHA" = "y" ]; then bool ' Timer LED' CONFIG_LEDS_TIMER bool ' CPU usage LED' CONFIG_LEDS_CPU fi - fi - if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then - define_bool CONFIG_LEDS_TIMER y + if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then + define_bool CONFIG_LEDS_TIMER y + fi fi fi -if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then - bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP +if [ "$CONFIG_ARCH_SA1100" = "y" ]; then + define_bool CONFIG_ALIGNMENT_TRAP y +else + if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then + bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP + else + define_bool CONFIG_ALIGNMENT_TRAP n + fi fi endmenu @@ -487,6 +548,8 @@ if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then source drivers/mtd/Config.in +else + define_bool CONFIG_MTD n fi source drivers/pnp/Config.in @@ -515,9 +578,9 @@ fi mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in @@ -538,7 +601,8 @@ endmenu if [ "$CONFIG_ARCH_CLPS711X" = "y" ]; then - source drivers/scsi/Config.in + # This is _meant_ to be ssi _not_ scsi. It is not a spelling error. + source drivers/ssi/Config.in fi source drivers/ieee1394/Config.in @@ -602,7 +666,7 @@ "$CONFIG_ARCH_MX1ADS" = "y" ]; then define_bool CONFIG_PC_KEYMAP y fi - if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then + if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_ARCH_RISCSTATION" != "y" ]; then bool 'VGA text console' CONFIG_VGA_CONSOLE fi source drivers/video/Config.in @@ -611,6 +675,7 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -o \ "$CONFIG_ARCH_CLPS7500" = "y" -o \ + "$CONFIG_ARCH_RISCSTATION" = "y" -o \ "$CONFIG_ARCH_TBOX" = "y" -o \ "$CONFIG_ARCH_SHARK" = "y" -o \ "$CONFIG_ARCH_SA1100" = "y" -o \ @@ -618,7 +683,7 @@ mainmenu_option next_comment comment 'Sound' - tristate 'Sound card support' CONFIG_SOUND + tristate 'Sound support' CONFIG_SOUND if [ "$CONFIG_SOUND" != "n" ]; then source drivers/sound/Config.in fi @@ -629,7 +694,9 @@ source drivers/usb/Config.in -source net/bluetooth/Config.in +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + source net/bluetooth/Config.in +fi mainmenu_option next_comment comment 'Kernel hacking' @@ -638,7 +705,16 @@ # you know what you are doing and are willing to live without stack traces, you # can get a slightly smaller kernel by setting this option to n, but then RMK # will have to kill you ;). -define_bool CONFIG_FRAME_POINTER y +if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then + # + # Note: We want all the performance we can get, so this means + # we accept the debugging limitations of setting CONFIG_FRAME_POINTER=n + # -- ahaigh@arm.com (23 August 2002) + define_bool CONFIG_FRAME_POINTER n +else + define_bool CONFIG_FRAME_POINTER y +fi + bool 'Verbose user fault messages' CONFIG_DEBUG_USER bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO dep_bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE $CONFIG_CPU_26 @@ -650,10 +726,11 @@ dep_bool ' Wait queue debugging' CONFIG_DEBUG_WAITQ $CONFIG_DEBUG_KERNEL dep_bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE $CONFIG_DEBUG_KERNEL dep_bool ' Verbose kernel error messages' CONFIG_DEBUG_ERRORS $CONFIG_DEBUG_KERNEL -# These options are only for real kernel hackers who want to get their hands dirty. +# These options are only for real kernel hackers who want to get their hands dirty. dep_bool ' Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL 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 crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/arm/def-configs/accelent_sa linux-2.4.22/arch/arm/def-configs/accelent_sa --- linux-2.4.21/arch/arm/def-configs/accelent_sa 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/accelent_sa 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,1099 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +CONFIG_SA1100_ACCELENT=y +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +CONFIG_SA1111=y +CONFIG_FORCE_MAX_ZONEORDER=9 +CONFIG_SA1100_USB=m +CONFIG_SA1100_USB_NETLINK=m +CONFIG_SA1100_USB_CHAR=m +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set + +# +# Processor Type +# +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_SA110 is not set +CONFIG_CPU_SA1100=y +# CONFIG_ARM_THUMB is not set +CONFIG_DISCONTIGMEM=y + +# +# General setup +# +# CONFIG_PCI is not set +CONFIG_ISA=y +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=C0400000 +CONFIG_ZBOOT_ROM_BSS=C0200000 +CONFIG_CPU_FREQ=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +CONFIG_PCMCIA_PROBE=y +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +CONFIG_PCMCIA_SA1100=m +# CONFIG_SA_PCMCIA_SLOT_1 is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="root=1f02" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +CONFIG_PARPORT=m +# CONFIG_PARPORT_PC is not set +CONFIG_PARPORT_IDP=m +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_CFI_B1 is not set +# CONFIG_MTD_CFI_B2 is not set +CONFIG_MTD_CFI_B4=y +# CONFIG_MTD_CFI_B8 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set +CONFIG_CS89x0=y + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=m +# 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_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_IRPORT_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +CONFIG_SA1100_FIR=m + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_SCSI_PCMCIA is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SA1100_DEFAULT_BAUDRATE=115200 +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SA1111_PS2_KEYB=y +CONFIG_ASI_KEYBOARD=y +# CONFIG_RTC_ASI is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# L3 serial bus support +# +CONFIG_L3=y +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +CONFIG_L3_SA1111=y +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=m +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +CONFIG_SA1100_WATCHDOG=m +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_SA1100_RTC=m +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_CRAMFS=m +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_SYSV_FS is not set +CONFIG_UDF_FS=m +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +CONFIG_ZLIB_FS_INFLATE=m + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB2=y +CONFIG_FBCON_CFB4=y +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_SA1100=y +CONFIG_SOUND_UDA1341=y +# CONFIG_SOUND_ASSABET_UDA1341 is not set +# CONFIG_SOUND_H3600_UDA1341 is not set +# CONFIG_SOUND_PANGOLIN_UDA1341 is not set +CONFIG_SOUND_SA1111_UDA1341=y +# CONFIG_SOUND_SA1100SSP is not set +# CONFIG_SOUND_SA1111_AC97 is not set +# CONFIG_SOUND_SA1111_AC97_RATE_CONVERSION is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_WAVEARTIST is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +CONFIG_MCP=y +CONFIG_MCP_SA1100=y +CONFIG_MCP_UCB1200=y +CONFIG_MCP_UCB1200_AUDIO=m +CONFIG_MCP_UCB1200_TS=m + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +CONFIG_USB_OHCI_SA1111=m +CONFIG_USB_SL811HS=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +CONFIG_USB_USBNET=m + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SLAB=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/adsagc linux-2.4.22/arch/arm/def-configs/adsagc --- linux-2.4.21/arch/arm/def-configs/adsagc 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/adsagc 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,1101 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +CONFIG_SA1100_ADSAGC=y +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_ADSBITSYPLUS is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_SA1111=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +CONFIG_CPU_SA1100=y +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y + +# +# Processor Features +# +CONFIG_DISCONTIGMEM=y + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +# CONFIG_CPU_FREQ is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +CONFIG_PCMCIA_PROBE=y +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +CONFIG_PCMCIA_SA1100=y +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=8000000 +CONFIG_MTD_PHYSMAP_LEN=4000000 +CONFIG_MTD_PHYSMAP_BUSWIDTH=4 +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_CIRRUS is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRAMCA is not set +# CONFIG_ULTRA is not set +# CONFIG_ULTRA32 is not set +# CONFIG_SMC9194 is not set +CONFIG_SMC91111=y +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_AIRO_CS is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# 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_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# 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 +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +# CONFIG_INPUT_KEYBDEV is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SA1100_DEFAULT_BAUDRATE=38400 +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_TOUCHSCREEN_ADS784X=y +# CONFIG_UCB1200 is not set +# CONFIG_TOUCHSCREEN_UCB1200 is not set +# CONFIG_AUDIO_UCB1200 is not set +# CONFIG_ADC_UCB1200 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_ADSSIO_I2C_ALGO=y +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set +CONFIG_I2C_DS1307=y +CONFIG_I2C_DS1307_ADS=y + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_SA1100_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_CRAMFS=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +CONFIG_ZLIB_FS_INFLATE=y + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_E13806=y +CONFIG_E13806_REG_BASE=48000000 +CONFIG_E13806_FB_BASE=48200000 +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +CONFIG_FBCON_CFB4=y +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +CONFIG_FBCON_FONTWIDTH8_ONLY=y +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_SA1100=y +# CONFIG_SOUND_UDA1341 is not set +# CONFIG_SOUND_ASSABET_UDA1341 is not set +# CONFIG_SOUND_H3600_UDA1341 is not set +# CONFIG_SOUND_PANGOLIN_UDA1341 is not set +# CONFIG_SOUND_SA1111_UDA1341 is not set +CONFIG_SOUND_SA1111_AC97=y +# CONFIG_SOUND_SA1100SSP is not set +CONFIG_SOUND_OSS=y +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +CONFIG_USB_OHCI_SA1111=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/adsbitsy linux-2.4.22/arch/arm/def-configs/adsbitsy --- linux-2.4.21/arch/arm/def-configs/adsbitsy 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/adsbitsy 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ # -# Automatically generated by make menuconfig: don't edit +# Automatically generated make config: don't edit # CONFIG_ARM=y # CONFIG_EISA is not set @@ -8,6 +8,8 @@ CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set # # Code maturity level options @@ -31,16 +33,25 @@ # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_OMAHA is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set # CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set CONFIG_ARCH_SA1100=y # CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set # # Archimedes/A5000 Implementations # + +# +# Archimedes/A5000 Implementations (select only ONE) +# # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set @@ -56,15 +67,27 @@ # # SA11x0 Implementations # +# CONFIG_SA1100_ACCELENT is not set # CONFIG_SA1100_ASSABET is not set # CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSAGC is not set +CONFIG_SA1100_ADSBITSY=y +# CONFIG_SA1100_ADSBITSYPLUS is not set # CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set # CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_BITSY is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set # CONFIG_SA1100_EXTENEX1 is not set # CONFIG_SA1100_FLEXANET is not set # CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set # CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set # CONFIG_SA1100_JORNADA720 is not set # CONFIG_SA1100_HUW_WEBPANEL is not set # CONFIG_SA1100_ITSY is not set @@ -73,40 +96,61 @@ # CONFIG_SA1100_OMNIMETER is not set # CONFIG_SA1100_PANGOLIN is not set # CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set # CONFIG_SA1100_SHERMAN is not set # CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set # CONFIG_SA1100_PFS168 is not set # CONFIG_SA1100_VICTOR is not set # CONFIG_SA1100_XP860 is not set # CONFIG_SA1100_YOPY is not set -# CONFIG_SA1100_GRAPHICSMASTER is not set -CONFIG_SA1100_ADSBITSY=y -CONFIG_SA1111=y # CONFIG_SA1100_USB is not set # CONFIG_SA1100_USB_NETLINK is not set # CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set # # CLPS711X/EP721X Implementations # +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set # CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set # CONFIG_ARCH_ACORN is not set # CONFIG_FOOTBRIDGE is not set # CONFIG_FOOTBRIDGE_HOST is not set # CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_SA1111=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Processor Type +# CONFIG_CPU_32=y # CONFIG_CPU_26 is not set -# CONFIG_CPU_32v3 is not set -CONFIG_CPU_32v4=y # CONFIG_CPU_ARM610 is not set # CONFIG_CPU_ARM710 is not set # CONFIG_CPU_ARM720T is not set # CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set # CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set # CONFIG_CPU_SA110 is not set CONFIG_CPU_SA1100=y +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y + +# +# Processor Features +# CONFIG_DISCONTIGMEM=y -# CONFIG_CPU_BIG_ENDIAN is not set # # General setup @@ -114,6 +158,9 @@ # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 # CONFIG_CPU_FREQ is not set CONFIG_HOTPLUG=y @@ -121,6 +168,8 @@ # PCMCIA/CardBus support # CONFIG_PCMCIA=y +CONFIG_PCMCIA_PROBE=y +# CONFIG_I82092 is not set # CONFIG_I82365 is not set # CONFIG_TCIC is not set # CONFIG_PCMCIA_CLPS6700 is not set @@ -129,6 +178,10 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# CONFIG_FPE_NWFPE=y # CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y @@ -136,12 +189,12 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set -# CONFIG_APM is not set +CONFIG_PM=y # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="ip=off" -# CONFIG_PFS168_CMDLINE is not set -# CONFIG_LEDS is not set +CONFIG_CMDLINE="console=ttySA0 mem=32m@0xC0000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set CONFIG_ALIGNMENT_TRAP=y # @@ -152,7 +205,79 @@ # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=8000000 +CONFIG_MTD_PHYSMAP_LEN=4000000 +CONFIG_MTD_PHYSMAP_BUSWIDTH=4 +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set # # Plug and Play configuration @@ -168,7 +293,9 @@ # 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_UMEM is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -184,6 +311,7 @@ # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set # CONFIG_BLK_DEV_LVM is not set # @@ -191,7 +319,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 @@ -204,13 +332,24 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -228,6 +367,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -240,19 +384,27 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_CIRRUS is not set # CONFIG_SUNLANCE 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 -# CONFIG_NET_VENDOR_SMC is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRAMCA is not set +# CONFIG_ULTRA is not set +# CONFIG_ULTRA32 is not set +# CONFIG_SMC9194 is not set +CONFIG_SMC91111=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set @@ -262,21 +414,44 @@ # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set -# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_DL2K is not set # CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set -# CONFIG_PPP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set # CONFIG_SLIP is not set # # Wireless LAN (non-hamradio) # -# CONFIG_NET_RADIO is not set +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_AIRO_CS is not set +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -299,6 +474,7 @@ # 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 @@ -317,7 +493,7 @@ # CONFIG_IRDA is not set # -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y @@ -325,10 +501,15 @@ # IDE, ATA and ATAPI Block devices # CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# # CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# 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 @@ -343,6 +524,11 @@ # 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 +# # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set @@ -350,6 +536,9 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set # CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set # # SCSI support @@ -385,35 +574,47 @@ # Character devices # CONFIG_VT=y -# CONFIG_VT_CONSOLE is not set +CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_SERIAL_21285 is not set -# CONFIG_SERIAL_21285_OLD is not set -# CONFIG_SERIAL_21285_CONSOLE is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set # CONFIG_SERIAL_AMBA_CONSOLE is not set # CONFIG_SERIAL_CLPS711X is not set # CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y CONFIG_SA1100_DEFAULT_BAUDRATE=38400 +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set # CONFIG_SERIAL_8250 is not set # CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_TOUCHSCREEN_ADS784X is not set CONFIG_UCB1200=y CONFIG_TOUCHSCREEN_UCB1200=y CONFIG_AUDIO_UCB1200=y CONFIG_ADC_UCB1200=y -# CONFIG_TOUCHSCREEN_BITSY is not set -# CONFIG_PROFILER is not set -# CONFIG_PFS168_SPI is not set -# CONFIG_PFS168_DTMF is not set -# CONFIG_PFS168_MISC is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 # # I2C support @@ -421,6 +622,19 @@ # CONFIG_I2C is not set # +# L3 serial bus support +# +CONFIG_L3=y +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +CONFIG_L3_SA1111=y +# CONFIG_BIT_SA1100_GPIO is not set + +# # Mice # # CONFIG_BUSMOUSE is not set @@ -429,14 +643,43 @@ # # Joysticks # -# CONFIG_JOYSTICK is not set +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_SA1100_RTC is not set @@ -468,23 +711,29 @@ # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 CONFIG_CRAMFS=y # CONFIG_TMPFS is not set CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -509,6 +758,7 @@ # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y @@ -526,6 +776,8 @@ # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +CONFIG_ZLIB_FS_INFLATE=y # # Partition Types @@ -560,6 +812,7 @@ # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set @@ -588,11 +841,11 @@ CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y # CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set # CONFIG_FB_CLPS711X is not set -# CONFIG_FB_CYBER2000 is not set CONFIG_FB_SA1100=y -# CONFIG_FB_ANAKIN is not set -# CONFIG_FB_E1355 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_E13806 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB2=y @@ -610,50 +863,169 @@ # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_SA1100=y +CONFIG_SOUND_UDA1341=y +# CONFIG_SOUND_ASSABET_UDA1341 is not set +# CONFIG_SOUND_H3600_UDA1341 is not set +# CONFIG_SOUND_PANGOLIN_UDA1341 is not set +CONFIG_SOUND_SA1111_UDA1341=y +# CONFIG_SOUND_SA1111_AC97 is not set +# CONFIG_SOUND_SA1100SSP is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set # # USB support # CONFIG_USB=y # CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_UHCI is not set # CONFIG_USB_UHCI_ALT is not set -CONFIG_USB_OHCI=y -CONFIG_USB_OHCI_NOPCI=y +# CONFIG_USB_OHCI is not set +CONFIG_USB_OHCI_SA1111=y + +# +# USB Device Class drivers +# # CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set # CONFIG_USB_BLUETOOTH is not set + +# +# SCSI support is needed for USB Storage +# # CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set -# CONFIG_USB_HID is not set -# CONFIG_USB_KBD is not set -CONFIG_USB_MOUSE=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set # CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# # CONFIG_USB_DC2XX is not set # CONFIG_USB_MDC800 is not set # CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_PWC is not set -# CONFIG_USB_SE401 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_DABUSB is not set -# CONFIG_USB_PLUSB is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# # CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set # CONFIG_USB_CATC is not set -# CONFIG_USB_NET1080 is not set +# CONFIG_USB_CDCETHER is not set # CONFIG_USB_USBNET is not set + +# +# USB port drivers +# # CONFIG_USB_USS720 is not set # # USB Serial Converter support # # CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# # CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set # # Bluetooth support @@ -664,11 +1036,16 @@ # Kernel hacking # CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_INFO is not set -# CONFIG_MAGIC_SYSRQ is not set # CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set # CONFIG_DEBUG_DC21285_PORT is not set # CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/adsbitsyplus linux-2.4.22/arch/arm/def-configs/adsbitsyplus --- linux-2.4.21/arch/arm/def-configs/adsbitsyplus 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/adsbitsyplus 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,1087 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSAGC is not set +# CONFIG_SA1100_ADSBITSY is not set +CONFIG_SA1100_ADSBITSYPLUS=y +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_SA1111=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +CONFIG_CPU_SA1100=y +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y + +# +# Processor Features +# +CONFIG_DISCONTIGMEM=y + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +# CONFIG_CPU_FREQ is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +CONFIG_PCMCIA_PROBE=y +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +CONFIG_PCMCIA_SA1100=y +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="console=ttySA0 mem=32m@0xC0000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=8000000 +CONFIG_MTD_PHYSMAP_LEN=4000000 +CONFIG_MTD_PHYSMAP_BUSWIDTH=4 +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_CIRRUS is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRAMCA is not set +# CONFIG_ULTRA is not set +# CONFIG_ULTRA32 is not set +# CONFIG_SMC9194 is not set +CONFIG_SMC91111=y +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_AIRO_CS is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# 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_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# 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 +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +# CONFIG_INPUT_KEYBDEV is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SA1100_DEFAULT_BAUDRATE=38400 +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_TOUCHSCREEN_ADS784X=y +# CONFIG_UCB1200 is not set +# CONFIG_TOUCHSCREEN_UCB1200 is not set +# CONFIG_AUDIO_UCB1200 is not set +# CONFIG_ADC_UCB1200 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_ADSSIO_I2C_ALGO=y +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set +CONFIG_I2C_DS1307=y +CONFIG_I2C_DS1307_ADS=y + +# +# L3 serial bus support +# +CONFIG_L3=y +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +CONFIG_L3_SA1111=y +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_SA1100_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_CRAMFS=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +CONFIG_ZLIB_FS_INFLATE=y + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_E13806 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB2=y +CONFIG_FBCON_CFB4=y +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_FONTWIDTH8_ONLY=y +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_SA1100=y +# CONFIG_SOUND_UDA1341 is not set +# CONFIG_SOUND_ASSABET_UDA1341 is not set +# CONFIG_SOUND_H3600_UDA1341 is not set +# CONFIG_SOUND_PANGOLIN_UDA1341 is not set +# CONFIG_SOUND_SA1111_UDA1341 is not set +CONFIG_SOUND_SA1111_AC97=y +# CONFIG_SOUND_SA1100SSP is not set +CONFIG_SOUND_OSS=y +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +CONFIG_USB_OHCI_SA1111=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/at91rm9200dk linux-2.4.22/arch/arm/def-configs/at91rm9200dk --- linux-2.4.21/arch/arm/def-configs/at91rm9200dk 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/at91rm9200dk 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,773 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set +CONFIG_ARCH_AT91RM9200=y + +# +# Archimedes/A5000 Implementations +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSAGC is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_ADSBITSYPLUS is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_H3600_SLEEVE is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_SA1100_SSP is not set + +# +# AT91RM9200 Implementations +# +CONFIG_ARCH_AT91RM9200DK=y + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_GUIDEA07 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +CONFIG_CPU_ARM920T=y +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20210000,3145728 root=/dev/ram rw" +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=10000000 +CONFIG_MTD_PHYSMAP_LEN=200000 +CONFIG_MTD_PHYSMAP_BUSWIDTH=2 +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +# CONFIG_MTD_SA1100 is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_AT91_DATAFLASH=y +# CONFIG_MTD_AT91_DATAFLASH_CARD is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_AT91_SMARTMEDIA=y + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_CIRRUS is not set +CONFIG_AT91_ETHER=y +CONFIG_AT91_ETHER_RMII=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_AT91_SPIDEV=y + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set +CONFIG_SERIAL_AT91=y +CONFIG_SERIAL_AT91_CONSOLE=y +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_AT91=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_PROC=y +# CONFIG_I2C_DS1307 is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +# CONFIG_SA1100_WATCHDOG is not set +# CONFIG_OMAHA_WATCHDOG is not set +CONFIG_AT91_WATCHDOG=y +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_AT91_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# 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 +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set +CONFIG_USB_OHCI_AT91=y +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_HID is not set +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/cep linux-2.4.22/arch/arm/def-configs/cep --- linux-2.4.21/arch/arm/def-configs/cep 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/cep 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,615 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +# CONFIG_EXPERIMENTAL is not set +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +CONFIG_SA1100_CEP=y +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_SA110 is not set +CONFIG_CPU_SA1100=y +# CONFIG_ARM_THUMB is not set +CONFIG_DISCONTIGMEM=y + +# +# General setup +# +# CONFIG_PCI is not set +CONFIG_ISA=y +# CONFIG_ISA_DMA is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_SYSCTL is not set +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram" +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SA1100_DEFAULT_BAUDRATE=9600 +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_SA1100_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# 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 +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Kernel hacking +# +# CONFIG_NO_FRAME_POINTER is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/epxa10db linux-2.4.22/arch/arm/def-configs/epxa10db --- linux-2.4.21/arch/arm/def-configs/epxa10db 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/epxa10db 2003-08-25 04:44:39.000000000 -0700 @@ -8,6 +8,8 @@ CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set # # Code maturity level options @@ -34,10 +36,14 @@ CONFIG_ARCH_CAMELOT=y # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_OMAHA is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set # CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set # # Archimedes/A5000 Implementations @@ -57,17 +63,25 @@ # # SA11x0 Implementations # +# CONFIG_SA1100_ACCELENT is not set # CONFIG_SA1100_ASSABET is not set # CONFIG_ASSABET_NEPONSET is not set # CONFIG_SA1100_ADSBITSY is not set # CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set # CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set # CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set # CONFIG_SA1100_EXTENEX1 is not set # CONFIG_SA1100_FLEXANET is not set # CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set # CONFIG_SA1100_GRAPHICSCLIENT is not set # CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set # CONFIG_SA1100_JORNADA720 is not set # CONFIG_SA1100_HUW_WEBPANEL is not set # CONFIG_SA1100_ITSY is not set @@ -76,42 +90,59 @@ # CONFIG_SA1100_OMNIMETER is not set # CONFIG_SA1100_PANGOLIN is not set # CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set # CONFIG_SA1100_SHERMAN is not set # CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set # CONFIG_SA1100_PFS168 is not set # CONFIG_SA1100_VICTOR is not set # CONFIG_SA1100_XP860 is not set # CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set # # CLPS711X/EP721X Implementations # +# CONFIG_ARCH_AUTCPU12 is not set # CONFIG_ARCH_CDB89712 is not set # CONFIG_ARCH_CLEP7312 is not set # CONFIG_ARCH_EDB7211 is not set # CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set # CONFIG_ARCH_EP7211 is not set # CONFIG_ARCH_EP7212 is not set # CONFIG_ARCH_ACORN is not set # CONFIG_FOOTBRIDGE is not set # CONFIG_FOOTBRIDGE_HOST is not set # CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_EPXA10DB=y +# CONFIG_EPXA1DB is not set +# CONFIG_EPXA10DB_R2 is not set +CONFIG_EPXA10DB_R3=y +CONFIG_PLD=y +# CONFIG_PLD_HOTSWAP is not set CONFIG_CPU_32=y # CONFIG_CPU_26 is not set -# CONFIG_CPU_32v3 is not set -CONFIG_CPU_32v4=y # CONFIG_CPU_ARM610 is not set # CONFIG_CPU_ARM710 is not set # CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set CONFIG_CPU_ARM922T=y -CONFIG_CPU_ARM92X_CPU_IDLE=y -CONFIG_CPU_ARM92X_I_CACHE_ON=y -CONFIG_CPU_ARM92X_D_CACHE_ON=y -# CONFIG_CPU_ARM92X_WRITETHROUGH is not set +CONFIG_PLD=y +# CONFIG_CPU_ARM926T is not set # CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set # CONFIG_CPU_SA110 is not set # CONFIG_CPU_SA1100 is not set +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y # CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_DISCONTIGMEM is not set # @@ -120,6 +151,9 @@ # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set CONFIG_NET=y @@ -130,7 +164,7 @@ # CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -150,8 +184,9 @@ CONFIG_MTD_DEBUG=y CONFIG_MTD_DEBUG_VERBOSE=0 CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_BOOTLDR_PARTS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_CMDLINE_PARTS is not set # CONFIG_MTD_AFS_PARTS is not set CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y @@ -171,42 +206,32 @@ # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set # CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set # # Mapping drivers for chip access # # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_SUN_UFLASH is not set # CONFIG_MTD_NORA is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_RPXLITE is not set -# CONFIG_MTD_TQM8XXL is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set -# CONFIG_MTD_DBOX2 is not set -# CONFIG_MTD_CSTM_MIPS_IXX is not set -CONFIG_MTD_EPXA10DB=y -# CONFIG_MTD_CFI_FLAGADM is not set -# CONFIG_MTD_SOLUTIONENGINE is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -# CONFIG_MTD_OCELOT is not set -# CONFIG_MTD_L440GX is not set # CONFIG_MTD_ARM_INTEGRATOR is not set # CONFIG_MTD_CDB89712 is not set # CONFIG_MTD_SA1100 is not set # CONFIG_MTD_DC21285 is not set # CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +CONFIG_MTD_EPXA=y +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set # CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_LART is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_DOC1000 is not set @@ -224,7 +249,6 @@ # # CONFIG_PNP is not set # CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set # # Block devices @@ -234,7 +258,9 @@ # 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_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -250,6 +276,7 @@ # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set # CONFIG_BLK_DEV_LVM is not set # @@ -257,7 +284,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 @@ -270,13 +297,20 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -294,6 +328,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -306,16 +345,18 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_CIRRUS is not set CONFIG_ETHER00=y # CONFIG_SUNLANCE 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 @@ -335,6 +376,7 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -343,8 +385,8 @@ # CONFIG_PPP_FILTER is not set CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_BSDCOMP=y +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set @@ -377,7 +419,7 @@ # CONFIG_IRDA is not set # -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set # CONFIG_BLK_DEV_IDE_MODES is not set @@ -435,6 +477,8 @@ CONFIG_SERIAL_UART00_CONSOLE=y # CONFIG_SERIAL_SA1100 is not set # CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set # CONFIG_SERIAL_8250 is not set # CONFIG_SERIAL_8250_CONSOLE is not set # CONFIG_SERIAL_8250_EXTENDED is not set @@ -460,7 +504,6 @@ # CONFIG_L3_ALGOBIT is not set # CONFIG_L3_BIT_SA1100_GPIO is not set # CONFIG_L3_SA1111 is not set -# CONFIG_L3_DRV_UDA1341 is not set # CONFIG_BIT_SA1100_GPIO is not set # @@ -479,13 +522,11 @@ # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -513,7 +554,6 @@ # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set # CONFIG_JBD_DEBUG is not set @@ -522,16 +562,17 @@ # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -CONFIG_JFFS_FS=y -CONFIG_JFFS_FS_VERBOSE=0 -# CONFIG_JFFS2_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set +# CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set @@ -557,7 +598,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set +CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y @@ -572,6 +613,8 @@ # CONFIG_NCPFS_SMALLDOS is not set # 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 @@ -582,66 +625,18 @@ # CONFIG_NLS is not set # +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# # USB support # # CONFIG_USB is not set -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set -# CONFIG_USB_OHCI_SA1111 is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set -# CONFIG_USB_DABUSB is not set -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# 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_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# 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_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set # # Bluetooth support @@ -652,11 +647,16 @@ # Kernel hacking # CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_USER=y CONFIG_DEBUG_INFO=y -CONFIG_MAGIC_SYSRQ=y # CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SLAB=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_DC21285_PORT is not set # CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/epxa1db linux-2.4.22/arch/arm/def-configs/epxa1db --- linux-2.4.21/arch/arm/def-configs/epxa1db 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/epxa1db 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,703 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_CAMELOT=y +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_EPXA10DB is not set +CONFIG_EPXA1DB=y +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +CONFIG_CPU_ARM922T=y +CONFIG_PLD=y +CONFIG_CPU_ARM922_CPU_IDLE=y +CONFIG_CPU_ARM922_I_CACHE_ON=y +CONFIG_CPU_ARM922_D_CACHE_ON=y +# CONFIG_CPU_ARM922_WRITETHROUGH is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +# CONFIG_ARM_THUMB is not set +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="console=ttyUA0,38400 root=/dev/mtdblock0 rw" +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=0 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +# CONFIG_MTD_SA1100 is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +CONFIG_MTD_EPXA10DB=y +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ETHER00 is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRAMCA is not set +# CONFIG_ULTRA is not set +# CONFIG_ULTRA32 is not set +# CONFIG_SMC9194 is not set +CONFIG_SMC91111=y +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +CONFIG_SERIAL_UART00=y +CONFIG_SERIAL_UART00_CONSOLE=y +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +CONFIG_ROMFS_FS=y +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# 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 +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_INFO=y +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SLAB=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/frodo linux-2.4.22/arch/arm/def-configs/frodo --- linux-2.4.21/arch/arm/def-configs/frodo 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/frodo 2003-08-25 04:44:39.000000000 -0700 @@ -37,6 +37,7 @@ # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set # CONFIG_ARCH_RPC is not set CONFIG_ARCH_SA1100=y # CONFIG_ARCH_SHARK is not set @@ -59,10 +60,12 @@ # # SA11x0 Implementations # +# CONFIG_SA1100_ACCELENT is not set # CONFIG_SA1100_ASSABET is not set # CONFIG_ASSABET_NEPONSET is not set # CONFIG_SA1100_ADSBITSY is not set # CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set # CONFIG_SA1100_CERF is not set # CONFIG_SA1100_H3100 is not set # CONFIG_SA1100_H3600 is not set @@ -71,6 +74,7 @@ # CONFIG_SA1100_EXTENEX1 is not set # CONFIG_SA1100_FLEXANET is not set # CONFIG_SA1100_FREEBIRD is not set +CONFIG_SA1100_FRODO=y # CONFIG_SA1100_GRAPHICSCLIENT is not set # CONFIG_SA1100_GRAPHICSMASTER is not set # CONFIG_SA1100_BADGE4 is not set @@ -86,11 +90,11 @@ # CONFIG_SA1100_SHANNON is not set # CONFIG_SA1100_SHERMAN is not set # CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set # CONFIG_SA1100_PFS168 is not set # CONFIG_SA1100_VICTOR is not set # CONFIG_SA1100_XP860 is not set # CONFIG_SA1100_YOPY is not set -CONFIG_SA1100_FRODO=y # CONFIG_SA1100_USB is not set # CONFIG_SA1100_USB_NETLINK is not set # CONFIG_SA1100_USB_CHAR is not set @@ -113,18 +117,18 @@ # CONFIG_FOOTBRIDGE_ADDIN is not set CONFIG_CPU_32=y # CONFIG_CPU_26 is not set -# CONFIG_CPU_32v3 is not set -CONFIG_CPU_32v4=y # CONFIG_CPU_ARM610 is not set # CONFIG_CPU_ARM710 is not set # CONFIG_CPU_ARM720T is not set # CONFIG_CPU_ARM920T is not set # CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set # CONFIG_CPU_ARM926T is not set # CONFIG_CPU_ARM1020 is not set # CONFIG_CPU_SA110 is not set CONFIG_CPU_SA1100=y -# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y CONFIG_DISCONTIGMEM=y # @@ -133,15 +137,28 @@ # CONFIG_PCI is not set CONFIG_ISA=y # CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 # CONFIG_CPU_FREQ is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +CONFIG_PCMCIA_PROBE=y +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +CONFIG_PCMCIA_SA1100=y CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -# CONFIG_FPE_NWFPE is not set -CONFIG_FPE_FASTFPE=y +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set @@ -149,7 +166,7 @@ # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="console=ttySA0,9600 ramdisk_size=4096 root=/dev/ram idebus=33" +CONFIG_CMDLINE="console=ttySA0,115200 ramdisk_size=12288 root=/dev/ram idebus=33 mem=63M" CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y @@ -163,7 +180,68 @@ # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set # # Plug and Play configuration @@ -179,11 +257,13 @@ # 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_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_SIZE=12288 CONFIG_BLK_DEV_INITRD=y # @@ -201,7 +281,8 @@ # # Networking options # -# CONFIG_PACKET is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set @@ -221,6 +302,11 @@ # CONFIG_VLAN_8021Q is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -238,9 +324,98 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Network device support # -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_CIRRUS=y +# CONFIG_CIRRUS_DEBUG is not set +# CONFIG_CIRRUS_DUPLEX is not set +# CONFIG_ARM_AM79C961A is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=y +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# 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_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set # # Amateur Radio support @@ -253,7 +428,7 @@ # CONFIG_IRDA is not set # -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y @@ -265,6 +440,7 @@ # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# 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 @@ -274,11 +450,12 @@ # CONFIG_BLK_DEV_IDEDISK_WD is not set # CONFIG_BLK_DEV_COMMERIAL is not set # CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECS=y CONFIG_BLK_DEV_IDECD=y # 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 # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set @@ -312,11 +489,13 @@ # # Input core support # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=y # # Character devices @@ -343,7 +522,7 @@ # CONFIG_SERIAL_UART00_CONSOLE is not set CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y -CONFIG_SA1100_DEFAULT_BAUDRATE=9600 +CONFIG_SA1100_DEFAULT_BAUDRATE=115200 # CONFIG_SERIAL_8250 is not set # CONFIG_SERIAL_8250_CONSOLE is not set # CONFIG_SERIAL_8250_EXTENDED is not set @@ -355,12 +534,22 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=16 +CONFIG_UNIX98_PTY_COUNT=64 # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_PHILIPSPAR is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_VELLEMAN is not set +CONFIG_I2C_FRODO=y +# CONFIG_I2C_BIT_SA1100_GPIO is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_PROC=y +CONFIG_I2C_DS1307=y # # L3 serial bus support @@ -381,16 +570,61 @@ # Joysticks # # CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -CONFIG_SA1100_RTC=y +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +CONFIG_SA1100_WATCHDOG=y +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +CONFIG_DS1307_RTC=y +CONFIG_DS1307_NVRAM=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -403,9 +637,50 @@ # CONFIG_DRM is not set # +# PCMCIA character devices +# + +# # Multimedia devices # -# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_DEV=y + +# +# Video For Linux +# +# CONFIG_I2C_PARPORT is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_CYBERPRO is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set # # File systems @@ -424,32 +699,33 @@ # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set # CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=y +# CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set @@ -479,8 +755,8 @@ # CONFIG_NCPFS_SMALLDOS is not set # 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 +CONFIG_ZISOFS_FS=y +CONFIG_ZLIB_FS_INFLATE=y # # Partition Types @@ -488,11 +764,54 @@ # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y # CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # # Console drivers # +CONFIG_PC_KEYB=y CONFIG_PC_KEYMAP=y # CONFIG_VGA_CONSOLE is not set @@ -507,15 +826,32 @@ CONFIG_FB_SA1100=y # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_CFB2=y -CONFIG_FBCON_CFB4=y -CONFIG_FBCON_CFB8=y +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +# CONFIG_FBCON_CFB8 is not set CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set # CONFIG_FBCON_FONTWIDTH8_ONLY is not set -# CONFIG_FBCON_FONTS is not set -CONFIG_FONT_8x8=y +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set CONFIG_FONT_8x16=y +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set # # Sound @@ -534,12 +870,19 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_UHCI is not set # CONFIG_USB_UHCI_ALT is not set # CONFIG_USB_OHCI is not set # CONFIG_USB_OHCI_SA1111 is not set +CONFIG_USB_1161=y # CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set # CONFIG_USB_BLUETOOTH is not set # CONFIG_USB_STORAGE is not set # CONFIG_USB_STORAGE_DEBUG is not set @@ -552,12 +895,25 @@ # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_USB_HIDDEV=y +# CONFIG_USB_WACOM is not set # CONFIG_USB_DC2XX is not set # CONFIG_USB_MDC800 is not set # CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set # CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set # CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_CATC is not set # CONFIG_USB_CDCETHER is not set @@ -575,6 +931,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 @@ -588,11 +945,14 @@ # 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 # CONFIG_USB_SERIAL_OMNINET is not set # CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set # # Bluetooth support diff -urN linux-2.4.21/arch/arm/def-configs/graphicsclient linux-2.4.22/arch/arm/def-configs/graphicsclient --- linux-2.4.21/arch/arm/def-configs/graphicsclient 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/graphicsclient 2003-08-25 04:44:39.000000000 -0700 @@ -8,6 +8,8 @@ CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set # # Code maturity level options @@ -31,12 +33,17 @@ # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_OMAHA is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set # CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set CONFIG_ARCH_SA1100=y # CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set # # Archimedes/A5000 Implementations @@ -60,15 +67,27 @@ # # SA11x0 Implementations # +# CONFIG_SA1100_ACCELENT is not set # CONFIG_SA1100_ASSABET is not set # CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSAGC is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_ADSBITSYPLUS is not set # CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set # CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_BITSY is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set # CONFIG_SA1100_EXTENEX1 is not set # CONFIG_SA1100_FLEXANET is not set # CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set CONFIG_SA1100_GRAPHICSCLIENT=y +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set # CONFIG_SA1100_JORNADA720 is not set # CONFIG_SA1100_HUW_WEBPANEL is not set # CONFIG_SA1100_ITSY is not set @@ -77,43 +96,59 @@ # CONFIG_SA1100_OMNIMETER is not set # CONFIG_SA1100_PANGOLIN is not set # CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set # CONFIG_SA1100_SHERMAN is not set # CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set # CONFIG_SA1100_PFS168 is not set # CONFIG_SA1100_VICTOR is not set # CONFIG_SA1100_XP860 is not set # CONFIG_SA1100_YOPY is not set -# CONFIG_SA1100_GRAPHICSMASTER is not set -# CONFIG_SA1100_ADSBITSY is not set # CONFIG_SA1100_USB is not set # CONFIG_SA1100_USB_NETLINK is not set # CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set # # CLPS711X/EP721X Implementations # +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set # CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set # CONFIG_ARCH_ACORN is not set # CONFIG_FOOTBRIDGE is not set # CONFIG_FOOTBRIDGE_HOST is not set # CONFIG_FOOTBRIDGE_ADDIN is not set -CONFIG_CPU_32=y -# CONFIG_CPU_26 is not set # # Processor Type # -# CONFIG_CPU_32v3 is not set -CONFIG_CPU_32v4=y +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set # CONFIG_CPU_ARM610 is not set # CONFIG_CPU_ARM710 is not set # CONFIG_CPU_ARM720T is not set # CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set # CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set # CONFIG_CPU_SA110 is not set CONFIG_CPU_SA1100=y +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y + +# +# Processor Features +# CONFIG_DISCONTIGMEM=y -# CONFIG_CPU_BIG_ENDIAN is not set # # General setup @@ -121,6 +156,9 @@ # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 # CONFIG_CPU_FREQ is not set CONFIG_HOTPLUG=y @@ -128,6 +166,8 @@ # PCMCIA/CardBus support # CONFIG_PCMCIA=y +CONFIG_PCMCIA_PROBE=y +# CONFIG_I82092 is not set # CONFIG_I82365 is not set # CONFIG_TCIC is not set # CONFIG_PCMCIA_CLPS6700 is not set @@ -136,6 +176,10 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# CONFIG_FPE_NWFPE=y # CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y @@ -143,11 +187,9 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set -# CONFIG_APM is not set +CONFIG_PM=y # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="ip=off" -# CONFIG_PFS168_CMDLINE is not set +CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram" CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y @@ -164,8 +206,9 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_BOOTLDR_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AFS_PARTS is not set # @@ -180,53 +223,44 @@ # RAM/ROM/Flash chip drivers # CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set # CONFIG_MTD_JEDEC is not set # # Mapping drivers for chip access # CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=800000 -CONFIG_MTD_PHYSMAP_LEN=1000000 +CONFIG_MTD_PHYSMAP_START=8000000 +CONFIG_MTD_PHYSMAP_LEN=2000000 CONFIG_MTD_PHYSMAP_BUSWIDTH=4 -# CONFIG_MTD_SUN_UFLASH is not set # CONFIG_MTD_NORA is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_RPXLITE is not set -# CONFIG_MTD_TQM8XXL is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set CONFIG_MTD_SA1100=y -# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set -# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set # CONFIG_MTD_DC21285 is not set # CONFIG_MTD_IQ80310 is not set -# CONFIG_MTD_DBOX2 is not set -# CONFIG_MTD_CSTM_MIPS_IXX is not set -# CONFIG_MTD_CFI_FLAGADM is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_SOLUTIONENGINE is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -# CONFIG_MTD_OCELOT is not set -# CONFIG_MTD_L440GX is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set # CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_LART is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -257,8 +291,10 @@ # 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=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 @@ -273,6 +309,7 @@ # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set # CONFIG_BLK_DEV_LVM is not set # @@ -280,7 +317,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 @@ -293,17 +330,24 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set # -# +# # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -321,6 +365,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -333,15 +382,17 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_CIRRUS is not set # CONFIG_SUNLANCE 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 @@ -351,6 +402,7 @@ # CONFIG_ULTRA is not set # CONFIG_ULTRA32 is not set CONFIG_SMC9194=y +# CONFIG_SMC91111 is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set @@ -360,21 +412,44 @@ # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set -# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_DL2K is not set # CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set -# CONFIG_PPP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set # CONFIG_SLIP is not set # # Wireless LAN (non-hamradio) # -# CONFIG_NET_RADIO is not set +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_AIRO_CS is not set +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -397,6 +472,7 @@ # 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 @@ -415,7 +491,7 @@ # CONFIG_IRDA is not set # -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y @@ -431,6 +507,7 @@ # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# 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 @@ -445,6 +522,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 @@ -456,6 +534,9 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set # CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set # # SCSI support @@ -479,46 +560,84 @@ # # Input core support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_KEYBDEV is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices # CONFIG_VT=y -# CONFIG_VT_CONSOLE is not set +CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_SERIAL_21285 is not set -# CONFIG_SERIAL_21285_OLD is not set -# CONFIG_SERIAL_21285_CONSOLE is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set # CONFIG_SERIAL_AMBA_CONSOLE is not set # CONFIG_SERIAL_CLPS711X is not set # CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y CONFIG_SA1100_DEFAULT_BAUDRATE=38400 +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set # CONFIG_SERIAL_8250 is not set # CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_TOUCHSCREEN_ADS784X is not set CONFIG_UCB1200=y CONFIG_TOUCHSCREEN_UCB1200=y CONFIG_AUDIO_UCB1200=y CONFIG_ADC_UCB1200=y -# CONFIG_TOUCHSCREEN_BITSY is not set -# CONFIG_PROFILER is not set -# CONFIG_PFS168_SPI is not set -# CONFIG_PFS168_DTMF is not set -# CONFIG_PFS168_MISC is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_ADSSIO_I2C_ALGO=y +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set +CONFIG_I2C_DS1307=y +CONFIG_I2C_DS1307_ADS=y + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set # # Mice @@ -529,18 +648,43 @@ # # Joysticks # -# CONFIG_JOYSTICK is not set +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set # -# Input core support is needed for joysticks +# Joysticks # +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_SA1100_RTC is not set @@ -572,18 +716,21 @@ # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set -CONFIG_JFFS_FS=y -CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_CRAMFS=y @@ -591,6 +738,7 @@ CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -615,6 +763,7 @@ # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y @@ -632,6 +781,8 @@ # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +CONFIG_ZLIB_FS_INFLATE=y # # Partition Types @@ -666,6 +817,7 @@ # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set @@ -694,11 +846,11 @@ CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y # CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set # CONFIG_FB_CLPS711X is not set -# CONFIG_FB_CYBER2000 is not set CONFIG_FB_SA1100=y -# CONFIG_FB_ANAKIN is not set -# CONFIG_FB_E1355 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_E13806 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB2=y @@ -719,6 +871,15 @@ # CONFIG_SOUND is not set # +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# # USB support # # CONFIG_USB is not set @@ -732,11 +893,16 @@ # Kernel hacking # CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_INFO is not set -# CONFIG_MAGIC_SYSRQ is not set # CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set # CONFIG_DEBUG_DC21285_PORT is not set # CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/graphicsmaster linux-2.4.22/arch/arm/def-configs/graphicsmaster --- linux-2.4.21/arch/arm/def-configs/graphicsmaster 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/graphicsmaster 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ # -# Automatically generated by make menuconfig: don't edit +# Automatically generated make config: don't edit # CONFIG_ARM=y # CONFIG_EISA is not set @@ -8,6 +8,8 @@ CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set # # Code maturity level options @@ -31,16 +33,25 @@ # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_OMAHA is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set # CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set CONFIG_ARCH_SA1100=y # CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set # # Archimedes/A5000 Implementations # + +# +# Archimedes/A5000 Implementations (select only ONE) +# # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set @@ -56,15 +67,27 @@ # # SA11x0 Implementations # +# CONFIG_SA1100_ACCELENT is not set # CONFIG_SA1100_ASSABET is not set # CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSAGC is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_ADSBITSYPLUS is not set # CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set # CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_BITSY is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set # CONFIG_SA1100_EXTENEX1 is not set # CONFIG_SA1100_FLEXANET is not set # CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set # CONFIG_SA1100_GRAPHICSCLIENT is not set +CONFIG_SA1100_GRAPHICSMASTER=y +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set # CONFIG_SA1100_JORNADA720 is not set # CONFIG_SA1100_HUW_WEBPANEL is not set # CONFIG_SA1100_ITSY is not set @@ -73,40 +96,61 @@ # CONFIG_SA1100_OMNIMETER is not set # CONFIG_SA1100_PANGOLIN is not set # CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set # CONFIG_SA1100_SHERMAN is not set # CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set # CONFIG_SA1100_PFS168 is not set # CONFIG_SA1100_VICTOR is not set # CONFIG_SA1100_XP860 is not set # CONFIG_SA1100_YOPY is not set -CONFIG_SA1100_GRAPHICSMASTER=y -# CONFIG_SA1100_ADSBITSY is not set -CONFIG_SA1111=y # CONFIG_SA1100_USB is not set # CONFIG_SA1100_USB_NETLINK is not set # CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set # # CLPS711X/EP721X Implementations # +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set # CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set # CONFIG_ARCH_ACORN is not set # CONFIG_FOOTBRIDGE is not set # CONFIG_FOOTBRIDGE_HOST is not set # CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_SA1111=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Processor Type +# CONFIG_CPU_32=y # CONFIG_CPU_26 is not set -# CONFIG_CPU_32v3 is not set -CONFIG_CPU_32v4=y # CONFIG_CPU_ARM610 is not set # CONFIG_CPU_ARM710 is not set # CONFIG_CPU_ARM720T is not set # CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set # CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set # CONFIG_CPU_SA110 is not set CONFIG_CPU_SA1100=y +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y + +# +# Processor Features +# CONFIG_DISCONTIGMEM=y -# CONFIG_CPU_BIG_ENDIAN is not set # # General setup @@ -114,6 +158,9 @@ # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 # CONFIG_CPU_FREQ is not set CONFIG_HOTPLUG=y @@ -121,6 +168,8 @@ # PCMCIA/CardBus support # CONFIG_PCMCIA=y +CONFIG_PCMCIA_PROBE=y +# CONFIG_I82092 is not set # CONFIG_I82365 is not set # CONFIG_TCIC is not set # CONFIG_PCMCIA_CLPS6700 is not set @@ -129,6 +178,10 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# CONFIG_FPE_NWFPE=y # CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y @@ -136,11 +189,9 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set -# CONFIG_APM is not set +CONFIG_PM=y # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="ip=off" -# CONFIG_PFS168_CMDLINE is not set +CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram" CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y @@ -157,9 +208,14 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_BOOTLDR_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set @@ -169,55 +225,50 @@ # RAM/ROM/Flash chip drivers # CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set # CONFIG_MTD_JEDEC is not set # # Mapping drivers for chip access # CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=800000 -CONFIG_MTD_PHYSMAP_LEN=1000000 +CONFIG_MTD_PHYSMAP_START=8000000 +CONFIG_MTD_PHYSMAP_LEN=4000000 CONFIG_MTD_PHYSMAP_BUSWIDTH=4 -# CONFIG_MTD_SUN_UFLASH is not set # CONFIG_MTD_NORA is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_RPXLITE is not set -# CONFIG_MTD_TQM8XXL is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set CONFIG_MTD_SA1100=y -# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set -# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set # CONFIG_MTD_DC21285 is not set # CONFIG_MTD_IQ80310 is not set -# CONFIG_MTD_DBOX2 is not set -# CONFIG_MTD_CSTM_MIPS_IXX is not set -# CONFIG_MTD_CFI_FLAGADM is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_SOLUTIONENGINE is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -# CONFIG_MTD_OCELOT is not set -# CONFIG_MTD_L440GX is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PCI is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set # CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_LART is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# # CONFIG_MTD_DOC1000 is not set # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set @@ -242,8 +293,10 @@ # 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=m +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 @@ -258,6 +311,7 @@ # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set # CONFIG_BLK_DEV_LVM is not set # @@ -265,7 +319,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 @@ -278,13 +332,24 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -302,6 +367,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -314,15 +384,17 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_CIRRUS is not set # CONFIG_SUNLANCE 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 @@ -332,6 +404,7 @@ # CONFIG_ULTRA is not set # CONFIG_ULTRA32 is not set CONFIG_SMC9194=y +# CONFIG_SMC91111 is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set @@ -341,21 +414,44 @@ # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set -# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_DL2K is not set # CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set -# CONFIG_PPP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set # CONFIG_SLIP is not set # # Wireless LAN (non-hamradio) # -# CONFIG_NET_RADIO is not set +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_AIRO_CS is not set +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -378,6 +474,7 @@ # 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 @@ -396,7 +493,7 @@ # CONFIG_IRDA is not set # -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y @@ -404,10 +501,15 @@ # IDE, ATA and ATAPI Block devices # CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# # CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# 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 @@ -422,6 +524,11 @@ # 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 +# # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set @@ -429,6 +536,9 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set # CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set # # SCSI support @@ -464,35 +574,47 @@ # Character devices # CONFIG_VT=y -# CONFIG_VT_CONSOLE is not set +CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_SERIAL_21285 is not set -# CONFIG_SERIAL_21285_OLD is not set -# CONFIG_SERIAL_21285_CONSOLE is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set # CONFIG_SERIAL_AMBA is not set # CONFIG_SERIAL_AMBA_CONSOLE is not set # CONFIG_SERIAL_CLPS711X is not set # CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y CONFIG_SA1100_DEFAULT_BAUDRATE=38400 -# CONFIG_SERIAL_8250 is not set -# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_TOUCHSCREEN_ADS784X is not set CONFIG_UCB1200=y CONFIG_TOUCHSCREEN_UCB1200=y CONFIG_AUDIO_UCB1200=y CONFIG_ADC_UCB1200=y -# CONFIG_TOUCHSCREEN_BITSY is not set -# CONFIG_PROFILER is not set -# CONFIG_PFS168_SPI is not set -# CONFIG_PFS168_DTMF is not set -# CONFIG_PFS168_MISC is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 # # I2C support @@ -500,6 +622,19 @@ # CONFIG_I2C is not set # +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# # Mice # # CONFIG_BUSMOUSE is not set @@ -508,14 +643,43 @@ # # Joysticks # -# CONFIG_JOYSTICK is not set +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_SA1100_RTC is not set @@ -533,6 +697,7 @@ # # PCMCIA character devices # +# CONFIG_PCMCIA_SERIAL_CS is not set # # Multimedia devices @@ -547,18 +712,21 @@ # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set -CONFIG_JFFS_FS=y -CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_CRAMFS=y @@ -566,6 +734,7 @@ CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -590,6 +759,7 @@ # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y @@ -607,6 +777,8 @@ # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +CONFIG_ZLIB_FS_INFLATE=y # # Partition Types @@ -641,6 +813,7 @@ # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set @@ -669,11 +842,11 @@ CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y # CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set # CONFIG_FB_CLPS711X is not set -# CONFIG_FB_CYBER2000 is not set CONFIG_FB_SA1100=y -# CONFIG_FB_ANAKIN is not set -# CONFIG_FB_E1355 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_E13806 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB2=y @@ -691,50 +864,169 @@ # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_SA1100=y +# CONFIG_SOUND_UDA1341 is not set +# CONFIG_SOUND_ASSABET_UDA1341 is not set +# CONFIG_SOUND_H3600_UDA1341 is not set +# CONFIG_SOUND_PANGOLIN_UDA1341 is not set +# CONFIG_SOUND_SA1111_UDA1341 is not set +# CONFIG_SOUND_SA1111_AC97 is not set +# CONFIG_SOUND_SA1100SSP is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set # # USB support # CONFIG_USB=y # CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_UHCI is not set # CONFIG_USB_UHCI_ALT is not set -CONFIG_USB_OHCI=y -CONFIG_USB_OHCI_NOPCI=y +# CONFIG_USB_OHCI is not set +CONFIG_USB_OHCI_SA1111=y + +# +# USB Device Class drivers +# # CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set # CONFIG_USB_BLUETOOTH is not set + +# +# SCSI support is needed for USB Storage +# # CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set -# CONFIG_USB_HID is not set -# CONFIG_USB_KBD is not set -CONFIG_USB_MOUSE=y + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set # CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# # CONFIG_USB_DC2XX is not set # CONFIG_USB_MDC800 is not set # CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_PWC is not set -# CONFIG_USB_SE401 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_DABUSB is not set -# CONFIG_USB_PLUSB is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# # CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set # CONFIG_USB_CATC is not set -# CONFIG_USB_NET1080 is not set +# CONFIG_USB_CDCETHER is not set # CONFIG_USB_USBNET is not set + +# +# USB port drivers +# # CONFIG_USB_USS720 is not set # # USB Serial Converter support # # CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# # CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set # # Bluetooth support @@ -745,11 +1037,16 @@ # Kernel hacking # CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_INFO is not set -# CONFIG_MAGIC_SYSRQ is not set # CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set # CONFIG_DEBUG_DC21285_PORT is not set # CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/lusl7200 linux-2.4.22/arch/arm/def-configs/lusl7200 --- linux-2.4.21/arch/arm/def-configs/lusl7200 2000-06-19 17:59:33.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/lusl7200 2003-08-25 04:44:39.000000000 -0700 @@ -23,6 +23,9 @@ # CONFIG_CPU_26 is not set CONFIG_CPU_32v4=y CONFIG_CPU_ARM720=y +CONFIG_ZBOOT_ROM=y +CONFIG_ZBOOT_ROM_TEXT=0x00010000 +CONFIG_ZBOOT_ROM_BSS=0xf03e0000 # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set diff -urN linux-2.4.21/arch/arm/def-configs/nanoengine linux-2.4.22/arch/arm/def-configs/nanoengine --- linux-2.4.21/arch/arm/def-configs/nanoengine 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/nanoengine 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,775 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +CONFIG_SA1100_NANOENGINE=y +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set + +# +# Processor Type +# +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_SA110 is not set +CONFIG_CPU_SA1100=y +# CONFIG_ARM_THUMB is not set +CONFIG_DISCONTIGMEM=y + +# +# General setup +# +# CONFIG_PCI is not set +CONFIG_ISA=y +# CONFIG_ISA_DMA is not set +CONFIG_ZBOOT_ROM=y +CONFIG_ZBOOT_ROM_TEXT=11000 +CONFIG_ZBOOT_ROM_BSS=c1fc0000 +# CONFIG_CPU_FREQ is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="root=/dev/ram" +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_BOOTLDR_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_MTDRAM=y +CONFIG_MTDRAM_TOTAL_SIZE=2048 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_ABS_POS=0 +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SA1100_DEFAULT_BAUDRATE=9600 +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=64 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_SA1100_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=1 +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# 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 +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/omaha linux-2.4.22/arch/arm/def-configs/omaha --- linux-2.4.21/arch/arm/def-configs/omaha 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/omaha 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,798 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +# CONFIG_EXPERIMENTAL is not set +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_OMAHA=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set + +# +# Processor Type +# +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +CONFIG_CPU_ARM920T=y +CONFIG_CPU_ARM920_CPU_IDLE=y +CONFIG_CPU_ARM920_I_CACHE_ON=y +CONFIG_CPU_ARM920_D_CACHE_ON=y +# CONFIG_CPU_ARM920_WRITETHROUGH is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +# CONFIG_ARM_THUMB is not set +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +CONFIG_SMC91C111=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_ARM_DCC is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_OMAHA is not set +# CONFIG_SERIAL_OMAHA_CONSOLE is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_PHILIPSPAR is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_VELLEMAN is not set +CONFIG_I2C_OMAHA=y +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_PROC=y + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +# CONFIG_SA1100_WATCHDOG is not set +CONFIG_OMAHA_WATCHDOG=y +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_OMAHA_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_UMSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_MINIX_FS=y +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# 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 +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# Omaha /proc drivers +# +CONFIG_OMAHA_MISC=y + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Kernel hacking +# +# CONFIG_FRAME_POINTER is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/riscstation linux-2.4.22/arch/arm/def-configs/riscstation --- linux-2.4.21/arch/arm/def-configs/riscstation 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/def-configs/riscstation 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,766 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_RISCSTATION=y +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +CONFIG_CPU_32v3=y +# CONFIG_CPU_32v4 is not set +# CONFIG_CPU_ARM610 is not set +CONFIG_CPU_ARM710=y +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +# CONFIG_ARM_THUMB is not set +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +CONFIG_ISA=y +# CONFIG_ISA_DMA is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="ip=dhcp" +# CONFIG_ALIGNMENT_TRAP is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_ARM_ETHER1 is not set +# CONFIG_ARM_ETHER3 is not set +# CONFIG_ARM_ETHERH is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# 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_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE 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 +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDE_RISCSTATION=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=y +# CONFIG_PSMOUSE is not set +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +CONFIG_7K5MOUSE=y +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_ADFS_FS=y +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +CONFIG_ROMFS_FS=y +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +CONFIG_ZLIB_FS_INFLATE=y + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +CONFIG_ACORN_PARTITION_EESOX=y +CONFIG_ACORN_PARTITION_ICS=y +CONFIG_ACORN_PARTITION_ADFS=y +CONFIG_ACORN_PARTITION_POWERTEC=y +CONFIG_ACORN_PARTITION_RISCIX=y +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FB_ACORN=y +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_MFB=y +CONFIG_FBCON_CFB2=y +CONFIG_FBCON_CFB4=y +CONFIG_FBCON_CFB8=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_FONT_ACORN_8x8=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# 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 +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# 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 +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -urN linux-2.4.21/arch/arm/def-configs/sherman linux-2.4.22/arch/arm/def-configs/sherman --- linux-2.4.21/arch/arm/def-configs/sherman 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/sherman 2003-08-25 04:44:39.000000000 -0700 @@ -47,6 +47,9 @@ # # General setup # +CONFIG_ZBOOT_ROM=y +CONFIG_ZBOOT_ROM_TEXT=0x00050000 +CONFIG_ZBOOT_ROM_BSS=0xc0200000 # CONFIG_NET is not set # CONFIG_SYSVIPC is not set # CONFIG_BSD_PROCESS_ACCT is not set diff -urN linux-2.4.21/arch/arm/def-configs/victor linux-2.4.22/arch/arm/def-configs/victor --- linux-2.4.21/arch/arm/def-configs/victor 2000-06-19 17:59:33.000000000 -0700 +++ linux-2.4.22/arch/arm/def-configs/victor 2003-08-25 04:44:39.000000000 -0700 @@ -46,6 +46,9 @@ # # General setup # +CONFIG_ZBOOT_ROM=y +CONFIG_ZBOOT_ROM_TEXT=0x00002000 +CONFIG_ZBOOT_ROM_BSS=0xc0200000 # CONFIG_NET is not set # CONFIG_SYSVIPC is not set # CONFIG_BSD_PROCESS_ACCT is not set diff -urN linux-2.4.21/arch/arm/kernel/Makefile linux-2.4.22/arch/arm/kernel/Makefile --- linux-2.4.21/arch/arm/kernel/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -18,6 +18,7 @@ O_OBJS_rpc = dma-rpc.o O_OBJS_footbridge = dma-footbridge.o isa.o O_OBJS_l7200 = fiq.o +O_OBJS_riscstation = fiq.o dma-riscstation.o pci-ftvpci = plx90x0.o pci-footbridge = dec21285.o @@ -43,7 +44,8 @@ no-irq-arch := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \ $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \ $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \ - $(CONFIG_ARCH_MX1ADS) + $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_OMAHA) \ + $(CONFIG_ARCH_AT91RM9200) ifneq ($(findstring y,$(no-irq-arch)),y) obj-y += irq-arch.o @@ -51,6 +53,7 @@ obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o +obj-$(CONFIG_ARCH_RISCSTATION) += time-acorn.o obj-$(CONFIG_DEBUG_LL) += debug-$(PROCESSOR).o obj-$(CONFIG_MODULES) += armksyms.o obj-$(CONFIG_ARTHUR) += arthur.o diff -urN linux-2.4.21/arch/arm/kernel/arch.c linux-2.4.22/arch/arm/kernel/arch.c --- linux-2.4.21/arch/arm/kernel/arch.c 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/arch.c 2003-08-25 04:44:39.000000000 -0700 @@ -20,7 +20,7 @@ unsigned int vram_size; -#ifdef CONFIG_ARCH_ACORN +#if defined(CONFIG_ARCH_ACORN) || defined(CONFIG_ARCH_RISCSTATION) unsigned int memc_ctrl_reg; unsigned int number_mfm_drives; @@ -49,7 +49,8 @@ __tagtable(ATAG_ACORN, parse_tag_acorn); -#ifdef CONFIG_ARCH_RPC + +#if defined(CONFIG_ARCH_RPC) || defined(CONFIG_ARCH_RISCSTATION) static void __init fixup_riscpc(struct machine_desc *desc, struct param_struct *unusd, char **cmdline, struct meminfo *mi) @@ -61,7 +62,9 @@ } extern void __init rpc_map_io(void); +extern void __init riscstation_map_io(void); +#ifdef CONFIG_ARCH_RPC MACHINE_START(RISCPC, "Acorn-RiscPC") MAINTAINER("Russell King") BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) @@ -73,6 +76,20 @@ INITIRQ(genarch_init_irq) MACHINE_END #endif + +#ifdef CONFIG_ARCH_RISCSTATION +/* TODO = check all parameters */ +MACHINE_START(RISCSTATION, "RiscStation-RS7500") + MAINTAINER("Ben Dooks, Vincent Sanders") + BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) + BOOT_PARAMS(0x10000100) + FIXUP(fixup_riscpc) + MAPIO(riscstation_map_io) + INITIRQ(genarch_init_irq) +MACHINE_END +#endif + +#endif /* CONFIG_ARCH_RPC | CONFIG_ARCH_RISCSTATION */ #ifdef CONFIG_ARCH_ARC MACHINE_START(ARCHIMEDES, "Acorn-Archimedes") MAINTAINER("Dave Gilbert") diff -urN linux-2.4.21/arch/arm/kernel/armksyms.c linux-2.4.22/arch/arm/kernel/armksyms.c --- linux-2.4.21/arch/arm/kernel/armksyms.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/armksyms.c 2003-08-25 04:44:39.000000000 -0700 @@ -62,9 +62,11 @@ extern void __muldi3(void); extern void __ucmpdi2(void); extern void __udivdi3(void); +extern void __umoddi3(void); extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); +extern void abort(void); extern void ret_from_exception(void); extern void fpundefinstr(void); @@ -106,7 +108,9 @@ /* platform dependent support */ EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(udelay); +EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__ndelay); +EXPORT_SYMBOL(__const_delay); #ifdef CONFIG_CPU_32 EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(__iounmap); @@ -189,6 +193,7 @@ EXPORT_SYMBOL_NOVERS(memmove); EXPORT_SYMBOL_NOVERS(memcmp); EXPORT_SYMBOL_NOVERS(memscan); +EXPORT_SYMBOL_NOVERS(memchr); EXPORT_SYMBOL_NOVERS(__memzero); /* user mem (segment) */ @@ -228,6 +233,7 @@ EXPORT_SYMBOL_NOVERS(__muldi3); EXPORT_SYMBOL_NOVERS(__ucmpdi2); EXPORT_SYMBOL_NOVERS(__udivdi3); +EXPORT_SYMBOL_NOVERS(__umoddi3); EXPORT_SYMBOL_NOVERS(__udivmoddi4); EXPORT_SYMBOL_NOVERS(__udivsi3); EXPORT_SYMBOL_NOVERS(__umodsi3); diff -urN linux-2.4.21/arch/arm/kernel/arthur.c linux-2.4.22/arch/arm/kernel/arthur.c --- linux-2.4.21/arch/arm/kernel/arthur.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/arthur.c 2003-08-25 04:44:39.000000000 -0700 @@ -46,7 +46,7 @@ /* * Linux to Arthur signal map. */ -static unsigned long linux_to_arthur_signals[32] = { +static unsigned long arthur_invmap[32] = { [0] = 0, [SIGHUP] = -1, [SIGINT] = ARTHUR_SIGINT, @@ -97,7 +97,7 @@ .pers_low = PER_RISCOS, .pers_high = PER_RISCOS, .signal_map = arthur_to_linux_signals, - .signal_invmap = linux_to_arthur_signals, + .signal_invmap = arthur_invmap, .module = THIS_MODULE, }; diff -urN linux-2.4.21/arch/arm/kernel/bios32.c linux-2.4.22/arch/arm/kernel/bios32.c --- linux-2.4.21/arch/arm/kernel/bios32.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/arm/kernel/bios32.c 2003-08-25 04:44:39.000000000 -0700 @@ -584,7 +584,7 @@ * pcibios_enable_device - Enable I/O and memory. * @dev: PCI device to be enabled */ -int pcibios_enable_device(struct pci_dev *dev) +int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, old_cmd; int idx; @@ -593,6 +593,10 @@ pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; for (idx = 0; idx < 6; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1 << idx))) + continue; + r = dev->resource + idx; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because" @@ -604,6 +608,13 @@ if (r->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } + + /* + * Bridges (eg, cardbus bridges) need to be fully enabled + */ + if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) + cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { printk("PCI: enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); diff -urN linux-2.4.21/arch/arm/kernel/calls.S linux-2.4.22/arch/arm/kernel/calls.S --- linux-2.4.21/arch/arm/kernel/calls.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/calls.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* - * linux/arch/arm/lib/calls.h + * linux/arch/arm/kernel/calls.S * - * Copyright (C) 1995-1998 Russell King + * Copyright (C) 1995-2003 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -10,7 +10,7 @@ * This file is included twice in entry-common.S */ #ifndef NR_syscalls -#define NR_syscalls 256 +#define NR_syscalls 288 #else __syscall_start: @@ -21,13 +21,13 @@ .long SYMBOL_NAME(sys_write) /* 5 */ .long SYMBOL_NAME(sys_open) .long SYMBOL_NAME(sys_close) - .long SYMBOL_NAME(sys_waitpid) + .long SYMBOL_NAME(sys_ni_syscall) /* was sys_waitpid */ .long SYMBOL_NAME(sys_creat) .long SYMBOL_NAME(sys_link) /* 10 */ .long SYMBOL_NAME(sys_unlink) .long SYMBOL_NAME(sys_execve_wrapper) .long SYMBOL_NAME(sys_chdir) - .long SYMBOL_NAME(sys_time) + .long SYMBOL_NAME(sys_time) /* used by libc4 */ .long SYMBOL_NAME(sys_mknod) /* 15 */ .long SYMBOL_NAME(sys_chmod) .long SYMBOL_NAME(sys_lchown16) @@ -36,15 +36,15 @@ .long SYMBOL_NAME(sys_lseek) /* 20 */ .long SYMBOL_NAME(sys_getpid) .long SYMBOL_NAME(sys_mount) - .long SYMBOL_NAME(sys_oldumount) + .long SYMBOL_NAME(sys_oldumount) /* used by libc4 */ .long SYMBOL_NAME(sys_setuid16) .long SYMBOL_NAME(sys_getuid16) /* 25 */ .long SYMBOL_NAME(sys_stime) .long SYMBOL_NAME(sys_ptrace) - .long SYMBOL_NAME(sys_alarm) + .long SYMBOL_NAME(sys_alarm) /* used by libc4 */ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_fstat */ .long SYMBOL_NAME(sys_pause) -/* 30 */ .long SYMBOL_NAME(sys_utime) +/* 30 */ .long SYMBOL_NAME(sys_utime) /* used by libc4 */ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_stty */ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_getty */ .long SYMBOL_NAME(sys_access) @@ -62,7 +62,7 @@ /* 45 */ .long SYMBOL_NAME(sys_brk) .long SYMBOL_NAME(sys_setgid16) .long SYMBOL_NAME(sys_getgid16) - .long SYMBOL_NAME(sys_signal) + .long SYMBOL_NAME(sys_ni_syscall) /* was sys_signal */ .long SYMBOL_NAME(sys_geteuid16) /* 50 */ .long SYMBOL_NAME(sys_getegid16) .long SYMBOL_NAME(sys_acct) @@ -82,29 +82,29 @@ /* 65 */ .long SYMBOL_NAME(sys_getpgrp) .long SYMBOL_NAME(sys_setsid) .long SYMBOL_NAME(sys_sigaction) - .long SYMBOL_NAME(sys_sgetmask) - .long SYMBOL_NAME(sys_ssetmask) + .long SYMBOL_NAME(sys_ni_syscall) /* was sys_sgetmask */ + .long SYMBOL_NAME(sys_ni_syscall) /* was sys_ssetmask */ /* 70 */ .long SYMBOL_NAME(sys_setreuid16) .long SYMBOL_NAME(sys_setregid16) .long SYMBOL_NAME(sys_sigsuspend_wrapper) .long SYMBOL_NAME(sys_sigpending) .long SYMBOL_NAME(sys_sethostname) /* 75 */ .long SYMBOL_NAME(sys_setrlimit) - .long SYMBOL_NAME(sys_old_getrlimit) + .long SYMBOL_NAME(sys_old_getrlimit) /* used by libc4 */ .long SYMBOL_NAME(sys_getrusage) .long SYMBOL_NAME(sys_gettimeofday) .long SYMBOL_NAME(sys_settimeofday) /* 80 */ .long SYMBOL_NAME(sys_getgroups16) .long SYMBOL_NAME(sys_setgroups16) - .long SYMBOL_NAME(old_select) + .long SYMBOL_NAME(old_select) /* used by libc4 */ .long SYMBOL_NAME(sys_symlink) .long SYMBOL_NAME(sys_ni_syscall) /* was sys_lstat */ /* 85 */ .long SYMBOL_NAME(sys_readlink) .long SYMBOL_NAME(sys_uselib) .long SYMBOL_NAME(sys_swapon) .long SYMBOL_NAME(sys_reboot) - .long SYMBOL_NAME(old_readdir) -/* 90 */ .long SYMBOL_NAME(old_mmap) + .long SYMBOL_NAME(old_readdir) /* used by libc4 */ +/* 90 */ .long SYMBOL_NAME(old_mmap) /* used by libc4 */ .long SYMBOL_NAME(sys_munmap) .long SYMBOL_NAME(sys_truncate) .long SYMBOL_NAME(sys_ftruncate) @@ -240,23 +240,37 @@ .long SYMBOL_NAME(sys_ni_syscall) /* Security */ .long SYMBOL_NAME(sys_gettid) /* 225 */ .long SYMBOL_NAME(sys_readahead) - .long SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */ -/* 230 */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */ -/* 235 */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */ - .long SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* setxattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* lsetxattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* fsetxattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* getxattr */ +/* 230 */ .long SYMBOL_NAME(sys_ni_syscall) /* lgetxattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* fgetxattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* listxattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* llistxattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* flistxattr */ +/* 235 */ .long SYMBOL_NAME(sys_ni_syscall) /* removexattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* lremovexattr */ + .long SYMBOL_NAME(sys_ni_syscall) /* fremovexattr */ .long SYMBOL_NAME(sys_tkill) - /* - * Please check 2.5 _before_ adding calls here, - * and copy changes to rmk@arm.linux.org.uk. Thanks. - */ + .long SYMBOL_NAME(sys_ni_syscall) /* sendfile64 */ +/* 240 */ .long SYMBOL_NAME(sys_ni_syscall) /* futex */ + .long SYMBOL_NAME(sys_ni_syscall) /* sched_setaffinity */ + .long SYMBOL_NAME(sys_ni_syscall) /* sched_getaffinity */ + .long SYMBOL_NAME(sys_ni_syscall) /* io_setup */ + .long SYMBOL_NAME(sys_ni_syscall) /* io_destroy */ +/* 245 */ .long SYMBOL_NAME(sys_ni_syscall) /* io_getevents */ + .long SYMBOL_NAME(sys_ni_syscall) /* io_submit */ + .long SYMBOL_NAME(sys_ni_syscall) /* io_cancel */ + .long SYMBOL_NAME(sys_ni_syscall) /* exit_group */ + .long SYMBOL_NAME(sys_ni_syscall) /* lookup_dcookie */ +/* 250 */ .long SYMBOL_NAME(sys_ni_syscall) /* epoll_create */ + .long SYMBOL_NAME(sys_ni_syscall) /* epoll_ctl */ + .long SYMBOL_NAME(sys_ni_syscall) /* epoll_wait */ + .long SYMBOL_NAME(sys_ni_syscall) /* remap_file_pages */ + .long SYMBOL_NAME(sys_ni_syscall) /* set_thread_area */ +/* 255 */ .long SYMBOL_NAME(sys_ni_syscall) /* get_thread_area */ + .long SYMBOL_NAME(sys_ni_syscall) /* set_tid_address */ __syscall_end: .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 diff -urN linux-2.4.21/arch/arm/kernel/compat.c linux-2.4.22/arch/arm/kernel/compat.c --- linux-2.4.21/arch/arm/kernel/compat.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/compat.c 2003-08-25 04:44:39.000000000 -0700 @@ -33,18 +33,35 @@ return tag; } -static void __init build_tag_list(struct param_struct *params, void *taglist, int mem_init) +static void __init build_tag_list(struct param_struct *params, void *taglist) { struct tag *tag = taglist; - printk(KERN_DEBUG "Converting old-style param struct to taglist\n"); - if (params->u1.s.page_size != PAGE_SIZE) { printk(KERN_WARNING "Warning: bad configuration page, " "trying to continue\n"); return; } + printk(KERN_DEBUG "Converting old-style param struct to taglist\n"); + +#ifdef CONFIG_ARCH_NETWINDER + if (params->u1.s.nr_pages != 0x02000 && + params->u1.s.nr_pages != 0x04000 && + params->u1.s.nr_pages != 0x08000 && + params->u1.s.nr_pages != 0x10000) { + printk(KERN_WARNING "Warning: bad NeTTrom parameters " + "detected, using defaults\n"); + + params->u1.s.nr_pages = 0x1000; /* 16MB */ + params->u1.s.ramdisk_size = 0; + params->u1.s.flags = FLAG_READONLY; + params->u1.s.initrd_start = 0; + params->u1.s.initrd_size = 0; + params->u1.s.rd_start = 0; + } +#endif + tag->hdr.tag = ATAG_CORE; tag->hdr.size = tag_size(tag_core); tag->u.core.flags = params->u1.s.flags & FLAG_READONLY; @@ -76,17 +93,15 @@ tag->hdr.size = tag_size(tag_revision); tag->u.revision.rev = params->u1.s.system_rev; - if (mem_init) { #ifdef CONFIG_ARCH_ACORN - if (machine_is_riscpc()) { - int i; - for (i = 0; i < 4; i++) - tag = memtag(tag, PHYS_OFFSET + (i << 26), - params->u1.s.pages_in_bank[i] * PAGE_SIZE); - } else + if (machine_is_riscpc()) { + int i; + for (i = 0; i < 4; i++) + tag = memtag(tag, PHYS_OFFSET + (i << 26), + params->u1.s.pages_in_bank[i] * PAGE_SIZE); + } else #endif - tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE); - } + tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE); #ifdef CONFIG_FOOTBRIDGE if (params->u1.s.mem_fclk_21285) { @@ -97,6 +112,23 @@ } #endif +#ifdef CONFIG_ARCH_EBSA285 + if (machine_is_ebsa285()) { + tag = tag_next(tag); + tag->hdr.tag = ATAG_VIDEOTEXT; + tag->hdr.size = tag_size(tag_videotext); + tag->u.videotext.x = params->u1.s.video_x; + tag->u.videotext.y = params->u1.s.video_y; + tag->u.videotext.video_page = 0; + tag->u.videotext.video_mode = 0; + tag->u.videotext.video_cols = params->u1.s.video_num_cols; + tag->u.videotext.video_ega_bx = 0; + tag->u.videotext.video_lines = params->u1.s.video_num_rows; + tag->u.videotext.video_isvga = 1; + tag->u.videotext.video_points = 8; + } +#endif + #ifdef CONFIG_ARCH_ACORN tag = tag_next(tag); tag->hdr.tag = ATAG_ACORN; @@ -114,14 +146,22 @@ strcpy(tag->u.cmdline.cmdline, params->commandline); tag = tag_next(tag); - tag->hdr.tag = 0; + tag->hdr.tag = ATAG_NONE; tag->hdr.size = 0; memmove(params, taglist, ((int)tag) - ((int)taglist) + sizeof(struct tag_header)); } -void __init convert_to_tag_list(struct param_struct *params, int mem_init) +void __init convert_to_tag_list(struct tag *tags) +{ + struct param_struct *params = (struct param_struct *)tags; + build_tag_list(params, ¶ms->u2); +} + +void __init squash_mem_tags(struct tag *tag) { - build_tag_list(params, ¶ms->u2, mem_init); + for (; tag->hdr.size; tag = tag_next(tag)) + if (tag->hdr.tag == ATAG_MEM) + tag->hdr.tag = ATAG_NONE; } diff -urN linux-2.4.21/arch/arm/kernel/debug-armv.S linux-2.4.22/arch/arm/kernel/debug-armv.S --- linux-2.4.21/arch/arm/kernel/debug-armv.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/debug-armv.S 2003-08-25 04:44:39.000000000 -0700 @@ -20,9 +20,20 @@ * printk isn't working). For DEBUGGING ONLY!!! Do not leave * references to these in a production kernel! */ -#if defined(CONFIG_ARCH_RPC) +#if defined(CONFIG_ARCH_RPC) || defined(CONFIG_ARCH_RISCSTATION) .macro addruart,rx - mov \rx, #0xe0000000 + +/* note, errors can occur in the head code BEFORE the memory map has been + * setup (and therefore the mapping for the IO) so the #if statement allows + * the address of the uart to be changed to the physical address instead of + * the logical + * + * (bjd) + */ + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + movne \rx, #0xe0000000 + moveq \rx, #0x03000000 orr \rx, \rx, #0x00010000 orr \rx, \rx, #0x00000fe0 .endm @@ -66,7 +77,7 @@ tst \rd, #0x10 beq 1001b .endm - + #elif defined(CONFIG_ARCH_SHARK) .macro addruart,rx mov \rx, #0xe0000000 @@ -287,6 +298,30 @@ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy bne 1001b .endm +#elif defined(CONFIG_ARCH_AT91RM9200) + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =AT91C_BASE_SYS @ System peripherals (phys address) + ldrne \rx, =AT91C_VA_BASE_SYS @ System peripherals (virt address) + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #DBGU_THR] @ DBGU_THR + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #DBGU_CSR] @ DBGU_CSR + tst \rd, #AT91C_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit + beq 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #DBGU_CSR] @ DBGU_CSR + tst \rd, #AT91C_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete + beq 1001b + .endm #elif defined(CONFIG_ARCH_CLPS711X) @@ -322,6 +357,21 @@ bne 1001b 1002: .endm +#elif defined(CONFIG_ARCH_OMAHA) + +#include + + .macro addruart,rx + .endm + + .macro senduart,rd,rx + .endm + + .macro waituart,rd,rx + .endm + + .macro busyuart,rd,rx + .endm #elif defined(CONFIG_ARCH_ANAKIN) @@ -365,7 +415,7 @@ tst \rx, #1 @ MMU enabled? ldr \rx, =EXC_UART00_BASE @ physical base address orrne \rx, \rx, #0xff000000 @ virtual base - orrne \rx, \rx, #0x00f00000 + orrne \rx, \rx, #0x00f00000 .endm .macro senduart,rd,rx @@ -385,6 +435,41 @@ bne 1001b .endm +#elif defined(CONFIG_ARCH_MX1ADS) + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x00000000 @ physical + movne \rx, #0xf0000000 @ virtual + orr \rx, \rx, #0x00200000 + orr \rx, \rx, #0x00006000 @ UART1 offset + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #0x40] @ TXDATA + .endm + + .macro waituart,rd,rx +#if 0 +/* REVISIT: This isn't right. I believe we should be checking CTS here instead + * to see if the user has entered to pause console output. + * gdavis@mvista.com 28apr03 + */ +1001: ldr \rd, [\rx, #0x94] @ SR1 + tst \rd, #1 << 13 @ TRDY + bne 1001b @ wait until TX FIFO ready +#endif + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #0x98] @ SR2 + tst \rd, #1 << 3 @ TXDC + beq 1002b @ wait until transmit done + .endm + + + #else #error Unknown architecture #endif diff -urN linux-2.4.21/arch/arm/kernel/dma-arc.c linux-2.4.22/arch/arm/kernel/dma-arc.c --- linux-2.4.21/arch/arm/kernel/dma-arc.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/dma-arc.c 2003-08-25 04:44:39.000000000 -0700 @@ -34,14 +34,14 @@ extern void fdc1772_setupdma(unsigned int count,unsigned int addr); unsigned long flags; DPRINTK("enable_dma fdc1772 data read\n"); - save_flags(flags); - clf(); + local_save_flags(flags); + __clf(); memcpy ((void *)0x1c, (void *)&fdc1772_dma_read, &fdc1772_dma_read_end - &fdc1772_dma_read); fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */ enable_fiq(FIQ_FLOPPYDATA); - restore_flags(flags); + local_irq_restore(flags); } break; @@ -50,14 +50,14 @@ extern void fdc1772_setupdma(unsigned int count,unsigned int addr); unsigned long flags; DPRINTK("enable_dma fdc1772 data write\n"); - save_flags(flags); - clf(); + local_save_flags(flags); + __clf(); memcpy ((void *)0x1c, (void *)&fdc1772_dma_write, &fdc1772_dma_write_end - &fdc1772_dma_write); fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */ enable_fiq(FIQ_FLOPPYDATA; - restore_flags(flags); + local_irq_restore(flags); } break; default: @@ -81,14 +81,14 @@ DPRINTK("arc_floppy_cmdend_enable_dma\n"); /*printk("enable_dma fdc1772 command end FIQ\n");*/ - save_flags(flags); - clf(); + local_save_flags(flags); + __clf(); /* B fdc1772_comendhandler */ *((unsigned int *)0x1c)=0xea000000 | (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4); - restore_flags(flags); + local_irq_restore(flags); } static int arc_floppy_cmdend_get_dma_residue(dmach_t channel, dma_t *dma) diff -urN linux-2.4.21/arch/arm/kernel/dma-riscstation.c linux-2.4.22/arch/arm/kernel/dma-riscstation.c --- linux-2.4.21/arch/arm/kernel/dma-riscstation.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/kernel/dma-riscstation.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,113 @@ +/* + * linux/arch/arm/kernel/dma-riscstation.c + * + * Copyright (C) 1998 Russell King + * Copyright (C) 2002 Ben Dooks / Simtec Electronics + * + * 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. + * + * DMA functions specific to RiscStatiun architecture + * + * sliced down version of the RiscPC DMA code by RMK + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct fiq_handler fh = { + name: "floppydma" +}; + +static void floppy_enable_dma(dmach_t channel, dma_t *dma) +{ + void *fiqhandler_start; + unsigned int fiqhandler_length; + struct pt_regs regs; + + if (dma->dma_mode == DMA_MODE_READ) { + extern unsigned char floppy_fiqin_start, floppy_fiqin_end; + fiqhandler_start = &floppy_fiqin_start; + fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start; + } else { + extern unsigned char floppy_fiqout_start, floppy_fiqout_end; + fiqhandler_start = &floppy_fiqout_start; + fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start; + } + + regs.ARM_r9 = dma->buf.length; + regs.ARM_r10 = (unsigned long)dma->buf.address; + regs.ARM_fp = FLOPPYDMA_BASE; + + if (claim_fiq(&fh)) { + printk("floppydma: couldn't claim FIQ.\n"); + return; + } + + set_fiq_handler(fiqhandler_start, fiqhandler_length); + set_fiq_regs(®s); + enable_fiq(dma->dma_irq); +} + +static void floppy_disable_dma(dmach_t channel, dma_t *dma) +{ + disable_fiq(dma->dma_irq); + release_fiq(&fh); +} + +static int floppy_get_residue(dmach_t channel, dma_t *dma) +{ + struct pt_regs regs; + get_fiq_regs(®s); + return regs.ARM_r9; +} + +static struct dma_ops floppy_dma_ops = { + type: "FIQDMA", + enable: floppy_enable_dma, + disable: floppy_disable_dma, + residue: floppy_get_residue, +}; + +/* + * This is virtual DMA - we don't need anything here. + */ +static void sound_enable_disable_dma(dmach_t channel, dma_t *dma) +{ +} + +static struct dma_ops sound_dma_ops = { + type: "VIRTUAL", + enable: sound_enable_disable_dma, + disable: sound_enable_disable_dma, +}; + +void __init arch_dma_init(dma_t *dma) +{ +#if 0 + iomd_writeb(0, IOMD_IO0CR); + iomd_writeb(0, IOMD_IO1CR); + iomd_writeb(0, IOMD_IO2CR); + iomd_writeb(0, IOMD_IO3CR); + + iomd_writeb(0xa0, IOMD_DMATCR); +#endif + + dma[DMA_VIRTUAL_FLOPPY].dma_irq = FIQ_FLOPPYDATA; + dma[DMA_VIRTUAL_FLOPPY].d_ops = &floppy_dma_ops; + dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops; +} diff -urN linux-2.4.21/arch/arm/kernel/dma-rpc.c linux-2.4.22/arch/arm/kernel/dma-rpc.c --- linux-2.4.21/arch/arm/kernel/dma-rpc.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/dma-rpc.c 2003-08-25 04:44:39.000000000 -0700 @@ -91,76 +91,40 @@ sg->length |= flags; } -static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma) -{ - iomd_writel(sg->dma_address, dma->dma_base + CURA); - iomd_writel(sg->length, dma->dma_base + ENDA); -} - -static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma) -{ - iomd_writel(sg->dma_address, dma->dma_base + CURB); - iomd_writel(sg->length, dma->dma_base + ENDB); -} - static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) { dma_t *dma = (dma_t *)dev_id; - unsigned int status = 0, no_buffer = dma->sg == NULL; + unsigned long base = dma->dma_base; do { - switch (dma->state) { - case state_prog_a: - iomd_get_next_sg(&dma->cur_sg, dma); - iomd_setup_dma_a(&dma->cur_sg, dma); - dma->state = state_wait_a; - - case state_wait_a: - status = iomd_readb(dma->dma_base + ST); - switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) { - case DMA_ST_OFL|DMA_ST_INT: - iomd_get_next_sg(&dma->cur_sg, dma); - iomd_setup_dma_a(&dma->cur_sg, dma); - break; - - case DMA_ST_INT: - iomd_get_next_sg(&dma->cur_sg, dma); - iomd_setup_dma_b(&dma->cur_sg, dma); - dma->state = state_wait_b; - break; - - case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB: - iomd_setup_dma_b(&dma->cur_sg, dma); - dma->state = state_wait_b; - break; - } + unsigned int status; + + status = iomd_readb(base + ST); + if (!(status & DMA_ST_INT)) + return; + + if (status & DMA_ST_OFL && !dma->sg) + break; + + iomd_get_next_sg(&dma->cur_sg, dma); + + switch (status & (DMA_ST_OFL | DMA_ST_AB)) { + case DMA_ST_OFL: /* OIA */ + case DMA_ST_AB: /* .IB */ + iomd_writel(dma->cur_sg.dma_address, base + CURA); + iomd_writel(dma->cur_sg.length, base + ENDA); break; - case state_wait_b: - status = iomd_readb(dma->dma_base + ST); - switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) { - case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB: - iomd_get_next_sg(&dma->cur_sg, dma); - iomd_setup_dma_b(&dma->cur_sg, dma); - break; - - case DMA_ST_INT|DMA_ST_AB: - iomd_get_next_sg(&dma->cur_sg, dma); - iomd_setup_dma_a(&dma->cur_sg, dma); - dma->state = state_wait_a; - break; - - case DMA_ST_OFL|DMA_ST_INT: - iomd_setup_dma_a(&dma->cur_sg, dma); - dma->state = state_wait_a; - break; - } + case DMA_ST_OFL | DMA_ST_AB: /* OIB */ + case 0: /* .IA */ + iomd_writel(dma->cur_sg.dma_address, base + CURB); + iomd_writel(dma->cur_sg.length, base + ENDB); break; } - } while (dma->sg && (status & DMA_ST_INT)); + } while (1); - if (no_buffer) - disable_irq(irq); + iomd_writeb(0, base + CR); + disable_irq(irq); } static int iomd_request_dma(dmach_t channel, dma_t *dma) @@ -194,7 +158,6 @@ } iomd_writeb(DMA_CR_C, dma_base + CR); - dma->state = state_prog_a; } if (dma->dma_mode == DMA_MODE_READ) @@ -207,11 +170,15 @@ static void iomd_disable_dma(dmach_t channel, dma_t *dma) { unsigned long dma_base = dma->dma_base; + unsigned long flags; unsigned int ctrl; - disable_irq(dma->dma_irq); + local_irq_save(flags); ctrl = iomd_readb(dma_base + CR); + if (ctrl & DMA_CR_E) + disable_irq(dma->dma_irq); iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR); + local_irq_restore(flags); } static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle) diff -urN linux-2.4.21/arch/arm/kernel/dma.c linux-2.4.22/arch/arm/kernel/dma.c --- linux-2.4.21/arch/arm/kernel/dma.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/dma.c 2003-08-25 04:44:39.000000000 -0700 @@ -119,6 +119,10 @@ { dma_t *dma = dma_chan + channel; + if (dma->active) + printk(KERN_ERR "dma%d: altering DMA SG while " + "DMA active\n", channel); + dma->sg = sg; dma->sgcount = nr_sg; dma->using_sg = 1; @@ -217,6 +221,14 @@ BUG(); } +/* + * Is the specified DMA channel active? + */ +int dma_channel_active(dmach_t channel) +{ + return dma_chan[channel].active; +} + void set_dma_page(dmach_t channel, char pagenr) { printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel); @@ -272,6 +284,7 @@ GLOBAL_ALIAS(set_dma_sg, get_dma_residue); GLOBAL_ALIAS(set_dma_speed, get_dma_residue); GLOBAL_ALIAS(init_dma, get_dma_residue); +GLOBAL_ALIAS(dma_channel_active, get_dma_residue); #endif @@ -286,3 +299,6 @@ EXPORT_SYMBOL(get_dma_residue); EXPORT_SYMBOL(set_dma_sg); EXPORT_SYMBOL(set_dma_speed); +EXPORT_SYMBOL(dma_channel_active); + +EXPORT_SYMBOL(dma_spin_lock); diff -urN linux-2.4.21/arch/arm/kernel/ecard.c linux-2.4.22/arch/arm/kernel/ecard.c --- linux-2.4.21/arch/arm/kernel/ecard.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/ecard.c 2003-08-25 04:44:39.000000000 -0700 @@ -38,7 +38,10 @@ #include #include #include +#include +#include #include +#include #include #include @@ -55,7 +58,7 @@ enum req { req_readbytes, - req_reset_all + req_reset }; struct ecard_request { @@ -136,14 +139,11 @@ #define POD_INT_ADDR(x) ((volatile unsigned char *)\ ((BUS_ADDR((x)) - IO_BASE) + IO_START)) -static inline void ecard_task_reset(void) +static inline void ecard_task_reset(struct ecard_request *req) { - ecard_t *ec; - - for (ec = cards; ec; ec = ec->next) - if (ec->loader) - ecard_loader_reset(POD_INT_ADDR(ec->podaddr), - ec->loader); + struct expansion_card *ec = req->ec; + if (ec->loader) + ecard_loader_reset(POD_INT_ADDR(ec->podaddr), ec->loader); } static void @@ -223,8 +223,8 @@ ecard_task_readbytes(req); break; - case req_reset_all: - ecard_task_reset(); + case req_reset: + ecard_task_reset(req); break; } } @@ -371,60 +371,6 @@ /* ======================= Mid-level card control ===================== */ -/* - * This function is responsible for resetting the expansion cards to a - * sensible state immediately prior to rebooting the system. This function - * has process state (keventd), so we can sleep. - * - * Possible "val" values here: - * SYS_RESTART - restarting system - * SYS_HALT - halting system - * SYS_POWER_OFF - powering down system - * - * We ignore all calls, unless it is a SYS_RESTART call - power down/halts - * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again. - */ -static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v) -{ - struct ecard_request req; - - if (val != SYS_RESTART) - return 0; - - /* - * Disable the expansion card interrupt - */ - disable_irq(IRQ_EXPANSIONCARD); - - /* - * If we have any expansion card loader code which will handle - * the reset for us, call it now. - */ - req.req = req_reset_all; - ecard_call(&req); - - /* - * Disable the expansion card interrupt again, just to be sure. - */ - disable_irq(IRQ_EXPANSIONCARD); - - /* - * Finally, reset the expansion card interrupt mask to - * all enable (RISC OS doesn't set this) - */ -#ifdef HAS_EXPMASK - have_expmask = ~0; - __raw_writeb(have_expmask, EXPMASK_ENABLE); -#endif - return 0; -} - -static struct notifier_block ecard_reboot_notifier = { - .notifier_call = ecard_reboot, -}; - - - static void ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld) { @@ -628,8 +574,7 @@ ec->irqaddr, ec->irqmask, *ec->irqaddr); } -static void -ecard_check_lockup(void) +static void ecard_check_lockup(void) { static int last, lockup; ecard_t *ec; @@ -757,8 +702,7 @@ printk(KERN_WARNING "Wild interrupt from backplane (masks)\n"); } -static void __init -ecard_probeirqhw(void) +static void __init ecard_probeirqhw(void) { ecard_t *ec; int found; @@ -785,7 +729,7 @@ __raw_writeb(have_expmask, EXPMASK_ENABLE); } #else -#define ecard_probeirqhw() +#define ecard_probeirqhw() do { } while (0) #endif #ifndef IO_EC_MEMC8_BASE @@ -896,6 +840,57 @@ get_ecard_dev_info); } +#define ec_set_resource(ec,nr,st,sz,flg) \ + do { \ + (ec)->resource[nr].name = ec->name; \ + (ec)->resource[nr].start = st; \ + (ec)->resource[nr].end = (st) + (sz) - 1; \ + (ec)->resource[nr].flags = flg; \ + } while (0) + +static void __init ecard_init_resources(struct expansion_card *ec) +{ + unsigned long base = PODSLOT_IOC4_BASE; + unsigned int slot = ec->slot_no; + int i; + + if (slot < 4) { + ec_set_resource(ec, ECARD_RES_MEMC, + PODSLOT_MEMC_BASE + (slot << 14), + PODSLOT_MEMC_SIZE, IORESOURCE_MEM); + base = PODSLOT_IOC0_BASE; + } + +#ifdef CONFIG_ARCH_RPC + if (slot < 8) { + ec_set_resource(ec, ECARD_RES_EASI, + PODSLOT_EASI_BASE + (slot << 24), + PODSLOT_EASI_SIZE, IORESOURCE_MEM); + } + + if (slot == 8) { + ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE, + NETSLOT_SIZE, IORESOURCE_MEM); + } else +#endif + + for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) { + ec_set_resource(ec, i + ECARD_RES_IOCSLOW, + base + (slot << 14) + (i << 19), + PODSLOT_IOC_SIZE, IORESOURCE_MEM); + } + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) { + if (ec->resource[i].start && + request_resource(&iomem_resource, &ec->resource[i])) { + printk(KERN_ERR "ecard%d: resource(s) not available\n", + ec->slot_no); + ec->resource[i].end -= ec->resource[i].start; + ec->resource[i].start = 0; + } + } +} + /* * Probe for an expansion card. * @@ -964,21 +959,26 @@ break; } - ec->irq = 32 + slot; -#ifdef IO_EC_MEMC8_BASE - if (slot == 8) - ec->irq = 11; -#endif + snprintf(ec->name, sizeof(ec->name), "ecard %04x:%04x", + ec->cid.manufacturer, ec->cid.product); + + ecard_init_resources(ec); + /* * hook the interrupt handlers */ - if (ec->irq != 0 && ec->irq >= 32) { + if (slot < 8) { + ec->irq = 32 + slot; irq_desc[ec->irq].mask_ack = ecard_disableirq; irq_desc[ec->irq].mask = ecard_disableirq; irq_desc[ec->irq].unmask = ecard_enableirq; irq_desc[ec->irq].valid = 1; } +#ifdef IO_EC_MEMC8_BASE + if (slot == 8) + ec->irq = 11; +#endif #ifdef CONFIG_ARCH_RPC /* On RiscPC, only first two slots have DMA capability */ if (slot < 2) @@ -1012,7 +1012,7 @@ finding_pos = finding_pos->next; for (; finding_pos; finding_pos = finding_pos->next) { - if (finding_pos->claimed) + if (finding_pos->claimed || finding_pos->driver) continue; if (!cids) { @@ -1062,11 +1062,6 @@ { int slot; - /* - * Register our reboot notifier - */ - register_reboot_notifier(&ecard_reboot_notifier); - #ifdef CONFIG_CPU_32 init_waitqueue_head(&ecard_wait); #endif @@ -1093,7 +1088,162 @@ ecard_proc_init(); } +/* + * ECARD driver functions + */ +static const struct ecard_id * +ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec) +{ + int i; + + for (i = 0; ids[i].manufacturer != 65535; i++) + if (ec->cid.manufacturer == ids[i].manufacturer && + ec->cid.product == ids[i].product) + return ids + i; + + return NULL; +} + +static int ecard_drv_probe(struct expansion_card *ec, const struct ecard_id *id) +{ + struct ecard_driver *drv = ec->driver; + int ret; + + ecard_claim(ec); + ret = drv->probe(ec, id); + if (ret) + ecard_release(ec); + return ret; +} + +static int ecard_drv_remove(struct expansion_card *ec) +{ + struct ecard_driver *drv = ec->driver; + + drv->remove(ec); + ecard_release(ec); + + return 0; +} + +/* + * Before rebooting, we must make sure that the expansion card is in a + * sensible state, so it can be re-detected. This means that the first + * page of the ROM must be visible. We call the expansion cards reset + * handler, if any. + */ +static void ecard_drv_shutdown(struct expansion_card *ec) +{ + struct ecard_driver *drv = ec->driver; + struct ecard_request req; + + if (drv && drv->shutdown) + drv->shutdown(ec); + ecard_release(ec); + req.req = req_reset; + req.ec = ec; + ecard_call(&req); +} + +int ecard_register_driver(struct ecard_driver *drv) +{ + struct expansion_card *ec; + int ret, found = 0; + + for (ec = cards; ec; ec = ec->next) { + const struct ecard_id *id; + + if (ec->driver || ec->claimed) + continue; + + if (drv->id_table) { + id = ecard_match_device(drv->id_table, ec); + ret = id != NULL; + } else { + id = NULL; + ret = ec->cid.id == drv->id; + } + + if (ret) { + ec->driver = drv; + ret = ecard_drv_probe(ec, id); + if (ret) { + ec->driver = NULL; + } else { + found++; + } + } + } + + return found ? 0 : -ENODEV; +} + +void ecard_remove_driver(struct ecard_driver *drv) +{ + struct expansion_card *ec; + + for (ec = cards; ec; ec = ec->next) + if (ec->driver == drv) { + ecard_drv_remove(ec); + ec->driver = NULL; + } +} + +/* + * This function is responsible for resetting the expansion cards to a + * sensible state immediately prior to rebooting the system. This function + * has process state (keventd), so we can sleep. + * + * Possible "val" values here: + * SYS_RESTART - restarting system + * SYS_HALT - halting system + * SYS_POWER_OFF - powering down system + * + * We ignore all calls, unless it is a SYS_RESTART call - power down/halts + * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again. + */ +static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v) +{ + struct expansion_card *ec; + + if (val != SYS_RESTART) + return 0; + + for (ec = cards; ec; ec = ec->next) + if (ec->driver || ec->claimed) + ecard_drv_shutdown(ec); + + /* + * Disable the expansion card interrupt + */ + disable_irq(IRQ_EXPANSIONCARD); + + /* + * Finally, reset the expansion card interrupt mask to + * all enable (RISC OS doesn't set this) + */ +#ifdef HAS_EXPMASK + have_expmask = ~0; + __raw_writeb(have_expmask, EXPMASK_ENABLE); +#endif + return 0; +} + +static struct notifier_block ecard_reboot_notifier = { + .notifier_call = ecard_reboot, +}; + +static int ecard_bus_init(void) +{ + register_reboot_notifier(&ecard_reboot_notifier); + return 0; +} + +__initcall(ecard_bus_init); + EXPORT_SYMBOL(ecard_startfind); EXPORT_SYMBOL(ecard_find); EXPORT_SYMBOL(ecard_readchunk); EXPORT_SYMBOL(ecard_address); +EXPORT_SYMBOL(ecard_register_driver); +EXPORT_SYMBOL(ecard_remove_driver); diff -urN linux-2.4.21/arch/arm/kernel/entry-armv.S linux-2.4.22/arch/arm/kernel/entry-armv.S --- linux-2.4.21/arch/arm/kernel/entry-armv.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/entry-armv.S 2003-08-25 04:44:39.000000000 -0700 @@ -187,11 +187,10 @@ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov r4, #0xe0000000 - orr r4, r4, #0x20 mov \irqstat, #0x0C - strb \irqstat, [r4] @outb(0x0C, 0x20) /* Poll command */ - ldrb \irqnr, [r4] @irq = inb(0x20) & 7 + strb \irqstat, [r4, #0x20] @outb(0x0C, 0x20) /* Poll command */ + ldrb \irqnr, [r4, #0x20] @irq = inb(0x20) & 7 and \irqstat, \irqnr, #0x80 teq \irqstat, #0 beq 43f @@ -199,8 +198,8 @@ teq \irqnr, #2 bne 44f 43: mov \irqstat, #0x0C - strb \irqstat, [r4, #0x80] @outb(0x0C, 0xA0) /* Poll command */ - ldrb \irqnr, [r4, #0x80] @irq = (inb(0xA0) & 7) + 8 + strb \irqstat, [r4, #0xa0] @outb(0x0C, 0xA0) /* Poll command */ + ldrb \irqnr, [r4, #0xa0] @irq = (inb(0xA0) & 7) + 8 and \irqstat, \irqnr, #0x80 teq \irqstat, #0 beq 44f @@ -454,6 +453,23 @@ .macro irq_prio_table .endm +#elif defined(CONFIG_ARCH_AT91RM9200) +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, =(AT91C_VA_BASE_SYS) @ base virtual address of SYS peripherals + ldr \irqnr, [\base, #AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) + ldr \irqstat, [\base, #AIC_ISR] @ read interrupt source number + teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt + streq \tmp, [\base, #AIC_EOICR] @ not going to be handled further, then ACK it now. + .endm + + .macro irq_prio_table + .endm + #elif defined(CONFIG_ARCH_MX1ADS) .macro disable_fiq @@ -479,6 +495,32 @@ .macro irq_prio_table .endm +#elif defined(CONFIG_ARCH_OMAHA) + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + /* Read all interrupts pending... */ + ldr \irqnr, =IO_ADDRESS(PLAT_PERIPHERAL_BASE) + OMAHA_INTPND + ldr \irqstat, [\irqnr] /* INTPND */ + + /* All pending irqs are now in \irqstat */ + mov \irqnr, #0 +1001: tst \irqstat, #1 + bne 1002f + add \irqnr, \irqnr, #1 + mov \irqstat, \irqstat, lsr #1 + cmp \irqnr, #MAXIRQNUM + bcc 1001b +1002: /* EQ will be set if we reach MAXIRQNUM */ + + .endm + + .macro irq_prio_table + .endm + #elif defined(CONFIG_ARCH_CLPS711X) #include @@ -611,16 +653,6 @@ and r2, r6, #31 @ int mode b SYMBOL_NAME(bad_mode) -#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE - /* The FPE is always present */ - .equ fpe_not_present, 0 -#else -wfs_mask_data: .word 0x0e200110 @ WFS/RFS - .word 0x0fef0fff - .word 0x0d000100 @ LDF [sp]/STF [sp] - .word 0x0d000100 @ LDF [fp]/STF [fp] - .word 0x0f000f00 - /* We get here if an undefined instruction happens and the floating * point emulator is not present. If the offending instruction was * a WFS, we just perform a normal return as if we had emulated the @@ -628,30 +660,7 @@ * to run so that the emulator module proper can be loaded. --philb */ fpe_not_present: - adr r10, wfs_mask_data - ldmia r10, {r4, r5, r6, r7, r8} - ldr r10, [sp, #S_PC] @ Load PC - sub r10, r10, #4 - mask_pc r10, r10 - ldrt r10, [r10] @ get instruction - and r5, r10, r5 - teq r5, r4 @ Is it WFS? - moveq pc, r9 - and r5, r10, r8 - teq r5, r6 @ Is it LDF/STF on sp or fp? - teqne r5, r7 - movne pc, lr - tst r10, #0x00200000 @ Does it have WB - moveq pc, r9 - and r4, r10, #255 @ get offset - and r6, r10, #0x000f0000 - tst r10, #0x00800000 @ +/- - ldr r5, [sp, r6, lsr #14] @ Load reg - rsbeq r4, r4, #0 - add r5, r5, r4, lsl #2 - str r5, [sp, r6, lsr #14] @ Save reg - mov pc, r9 -#endif + mov pc, lr /* * SVC mode handlers @@ -703,11 +712,13 @@ @ routine called with r0 = irq number, r1 = struct pt_regs * @ adrsvc ne, lr, 1b - bne do_IRQ + bne asm_do_IRQ ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr + .ltorg + .align 5 __und_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 @@ -807,11 +818,13 @@ @ @ routine called with r0 = irq number, r1 = struct pt_regs * @ - bne do_IRQ + bne asm_do_IRQ mov why, #0 get_current_task tsk b ret_to_user + .ltorg + .align 5 __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ Save r0 - r12 @@ -822,6 +835,8 @@ stmdb r8, {sp, lr}^ @ Save user sp, lr alignment_trap r4, r7, __temp_und zero_fp + tst r6, #T_BIT @ Thumb mode + bne fpundefinstr adrsvc al, r9, ret_from_exception @ r9 = normal FP return adrsvc al, lr, fpundefinstr @ lr = undefined instr return @@ -859,8 +874,9 @@ * This is the return code to user mode for abort handlers */ ENTRY(ret_from_exception) - get_current_task tsk + disable_irq r1 mov why, #0 + get_current_task tsk b ret_to_user .data @@ -909,7 +925,9 @@ @ @ now branch to the relevent MODE handling routine @ - mov r13, #I_BIT | MODE_SVC + mrs r13, cpsr + bic r13, r13, #MODE_MASK + orr r13, r13, #I_BIT | MODE_SVC msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 @@ -950,7 +968,9 @@ @ @ now branch to the relevent MODE handling routine @ - mov r13, #I_BIT | MODE_SVC + mrs r13, cpsr + bic r13, r13, #MODE_MASK + orr r13, r13, #I_BIT | MODE_SVC msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 @@ -992,7 +1012,9 @@ @ @ now branch to the relevent MODE handling routine @ - mov r13, #I_BIT | MODE_SVC + mrs r13, cpsr + bic r13, r13, #MODE_MASK + orr r13, r13, #I_BIT | MODE_SVC msr spsr_c, r13 @ switch to SVC_32 mode ands lr, lr, #15 @@ -1033,7 +1055,9 @@ @ @ now branch to the relevent MODE handling routine @ - mov r13, #I_BIT | MODE_SVC + mrs r13, cpsr + bic r13, r13, #MODE_MASK + orr r13, r13, #I_BIT | MODE_SVC msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 diff -urN linux-2.4.21/arch/arm/kernel/entry-common.S linux-2.4.22/arch/arm/kernel/entry-common.S --- linux-2.4.21/arch/arm/kernel/entry-common.S 2002-02-25 11:37:52.000000000 -0800 +++ linux-2.4.22/arch/arm/kernel/entry-common.S 2003-08-25 04:44:39.000000000 -0700 @@ -34,6 +34,7 @@ * stack. */ ret_fast_syscall: + disable_irq r1 @ ensure IRQs are disabled ldr r1, [tsk, #TSK_NEED_RESCHED] ldr r2, [tsk, #TSK_SIGPENDING] teq r1, #0 @ need_resched || sigpending @@ -45,28 +46,35 @@ * Ok, we need to do extra processing, enter the slow path. */ slow: str r0, [sp, #S_R0+S_OFF]! @ returned r0 - b 1f + teq r1, #0 + beq 1f /* * "slow" syscall return path. "why" tells us if this was a real syscall. */ reschedule: bl SYMBOL_NAME(schedule) +ret_disable_irq: + disable_irq r1 @ ensure IRQs are disabled ENTRY(ret_to_user) ret_slow_syscall: ldr r1, [tsk, #TSK_NEED_RESCHED] ldr r2, [tsk, #TSK_SIGPENDING] -1: teq r1, #0 @ need_resched => schedule() + teq r1, #0 @ need_resched => schedule() bne reschedule - teq r2, #0 @ sigpending => do_signal() - blne __do_signal +1: teq r2, #0 @ sigpending => do_signal() + bne __do_signal +restore: restore_user_regs __do_signal: + enable_irq r1 mov r0, #0 @ NULL 'oldset' mov r1, sp @ 'regs' mov r2, why @ 'syscall' - b SYMBOL_NAME(do_signal) @ note the bl above sets lr + bl SYMBOL_NAME(do_signal) @ note the bl above sets lr + disable_irq r1 @ ensure IRQs are disabled + b restore /* * This is how we return from a fork. __switch_to will be calling us @@ -79,11 +87,11 @@ ldr ip, [tsk, #TSK_PTRACE] @ check for syscall tracing mov why, #1 tst ip, #PT_TRACESYS @ are we tracing syscalls? - beq ret_slow_syscall + beq ret_disable_irq mov r1, sp mov r0, #1 @ trace exit [IP = 1] bl SYMBOL_NAME(syscall_trace) - b ret_slow_syscall + b ret_disable_irq #include "calls.S" @@ -130,7 +138,7 @@ ldr ip, [ip] mcr p15, 0, ip, c1, c0 @ update control register #endif - enable_irqs ip + enable_irq ip str r4, [sp, #-S_OFF]! @ push fifth arg @@ -174,7 +182,7 @@ mov r1, sp mov r0, #1 @ trace exit [IP = 1] bl SYMBOL_NAME(syscall_trace) - b ret_slow_syscall + b ret_disable_irq .align 5 #ifdef CONFIG_ALIGNMENT_TRAP diff -urN linux-2.4.21/arch/arm/kernel/entry-header.S linux-2.4.22/arch/arm/kernel/entry-header.S --- linux-2.4.21/arch/arm/kernel/entry-header.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/entry-header.S 2003-08-25 04:44:39.000000000 -0700 @@ -41,14 +41,14 @@ @ @ Stack format (ensured by USER_* and SVC_*) @ -#define S_FRAME_SIZE 72 #ifdef CONFIG_CPU_32 +#define S_FRAME_SIZE 72 #define S_OLD_R0 68 #define S_PSR 64 #else +#define S_FRAME_SIZE 68 #define S_OLD_R0 64 #define S_PSR 60 -#define S_PC 60 #endif #define S_PC 60 @@ -70,6 +70,24 @@ #define S_OFF 8 #ifdef CONFIG_CPU_32 + .macro set_cpsr_c, reg, mode +#if 1 + /* broken binutils */ + mov \reg, \mode + msr cpsr_c, \reg +#else + msr cpsr_c, \mode +#endif + .endm + + .macro disable_irq, temp + set_cpsr_c \temp, #I_BIT | MODE_SVC + .endm + + .macro enable_irq, temp + set_cpsr_c \temp, #MODE_SVC + .endm + .macro save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0 - r12 @@ -81,21 +99,23 @@ str r0, [sp, #S_OLD_R0] @ Save OLD_R0 .endm +/* + * Must be called with IRQs already disabled. + */ .macro restore_user_regs - ldr r0, [sp, #S_PSR] @ Get calling cpsr - mov ip, #I_BIT | MODE_SVC - msr cpsr_c, ip @ disable IRQs - msr spsr, r0 @ save in spsr_svc - ldr lr, [sp, #S_PC] @ Get PC - ldmia sp, {r0 - lr}^ @ Get calling r0 - lr + ldr r1, [sp, #S_PSR] @ Get calling cpsr + ldr lr, [sp, #S_PC]! @ Get PC + msr spsr, r1 @ save in spsr_svc + ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr mov r0, r0 - add sp, sp, #S_FRAME_SIZE + add sp, sp, #S_FRAME_SIZE - S_PC movs pc, lr @ return & move spsr_svc into cpsr .endm +/* + * Must be called with IRQs already disabled. + */ .macro fast_restore_user_regs - mov ip, #I_BIT | MODE_SVC - msr cpsr_c, ip @ disable IRQs ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr ldr lr, [sp, #S_OFF + S_PC]! @ get pc msr spsr, r1 @ save in spsr_svc @@ -108,11 +128,6 @@ .macro mask_pc, rd, rm .endm - .macro enable_irqs, temp - mov \temp, #MODE_SVC - msr cpsr_c, \temp - .endm - .macro get_current_task, rd mov \rd, sp, lsr #13 mov \rd, \rd, lsl #13 @@ -136,9 +151,9 @@ #else .macro save_user_regs - str r0, [sp, #-4]! - str lr, [sp, #-4]! - sub sp, sp, #15*4 + sub sp, sp, #S_FRAME_SIZE + str r0, [sp, #S_OLD_R0] + str lr, [sp, #S_PC] stmia sp, {r0 - lr}^ mov r0, r0 .endm @@ -146,17 +161,16 @@ .macro restore_user_regs ldmia sp, {r0 - lr}^ mov r0, r0 - ldr lr, [sp, #15*4] - add sp, sp, #15*4+8 + ldr lr, [sp, #S_PC] + add sp, sp, #S_FRAME_SIZE movs pc, lr .endm .macro fast_restore_user_regs - add sp, sp, #S_OFF - ldmib sp, {r1 - lr}^ + add sp, sp, #S_OFF + S_PC + ldmdb sp, {r1 - lr}^ mov r0, r0 - ldr lr, [sp, #15*4] - add sp, sp, #15*4+8 + ldr lr, [sp], #S_FRAME_SIZE - S_PC movs pc, lr .endm @@ -164,7 +178,11 @@ bic \rd, \rm, #PCMASK .endm - .macro enable_irqs, temp + .macro disable_irq, temp + teqp pc, #0x08000003 + .endm + + .macro enable_irq, temp teqp pc, #0x00000003 .endm diff -urN linux-2.4.21/arch/arm/kernel/head-armv.S linux-2.4.22/arch/arm/kernel/head-armv.S --- linux-2.4.21/arch/arm/kernel/head-armv.S 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/head-armv.S 2003-08-25 04:44:39.000000000 -0700 @@ -52,17 +52,22 @@ .endm /* - * Kernel startup entry point. + * Kernel startup entry point. + * --------------------------- * - * The rules are: - * r0 - should be 0 - * r1 - unique architecture number - * MMU - off - * I-cache - on or off - * D-cache - off + * This is normally called from the decompressor code. The requirements + * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, + * r1 = machine nr. * - * See linux/arch/arm/tools/mach-types for the complete list of numbers - * for r1. + * This code is mostly position independent, so if you link the kernel at + * 0xc0008000, you call this at __pa(0xc0008000). + * + * See linux/arch/arm/tools/mach-types for the complete list of machine + * numbers for r1. + * + * We're trying to keep crap to a minimum; DO NOT add any machine specific + * crap here - that's what the boot loader (or in extreme, well justified + * circumstances, zImage) is for. */ .section ".text.init",#alloc,#execinstr .type stext, #function @@ -143,7 +148,6 @@ .type __switch_data, %object __switch_data: .long __mmap_switched - .long SYMBOL_NAME(compat) .long SYMBOL_NAME(__bss_start) .long SYMBOL_NAME(_end) .long SYMBOL_NAME(processor_id) @@ -151,28 +155,33 @@ .long SYMBOL_NAME(cr_alignment) .long SYMBOL_NAME(init_task_union)+8192 +/* + * Enable the MMU. This completely changes the structure of the visible + * memory space. You will not be able to trace execution through this. + * If you have an enquiry about this, *please* check the linux-arm-kernel + * mailing list archives BEFORE sending another post to the list. + */ .type __ret, %function __ret: ldr lr, __switch_data mcr p15, 0, r0, c1, c0 - mov r0, r0 + mrc p15, 0, r0, c1, c0, 0 @ read it back. mov r0, r0 mov r0, r0 mov pc, lr - /* - * This code follows on after the page - * table switch and jump above. - * - * r0 = processor control register - * r1 = machine ID - * r9 = processor ID - */ +/* + * The following fragment of code is executed with the MMU on, and uses + * absolute addresses; this is not position independent. + * + * r0 = processor control register + * r1 = machine ID + * r9 = processor ID + */ .align 5 __mmap_switched: adr r3, __switch_data + 4 - ldmia r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat + ldmia r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat @ sp = stack pointer - str r12, [r2] mov fp, #0 @ Clear BSS (and zero fp) 1: cmp r4, r5 diff -urN linux-2.4.21/arch/arm/kernel/irq-arch.c linux-2.4.22/arch/arm/kernel/irq-arch.c --- linux-2.4.21/arch/arm/kernel/irq-arch.c 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/irq-arch.c 2003-08-25 04:44:39.000000000 -0700 @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/kernel/irq.c linux-2.4.22/arch/arm/kernel/irq.c --- linux-2.4.21/arch/arm/kernel/irq.c 2001-07-04 14:56:44.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -46,6 +48,7 @@ static volatile unsigned long irq_err_count; static spinlock_t irq_controller_lock; +static LIST_HEAD(irq_pending); struct irqdesc irq_desc[NR_IRQS]; void (*init_arch_irq)(void) __initdata = NULL; @@ -57,21 +60,32 @@ { } +/* + * No architecture-specific irq_finish function defined in arm/arch/irq.h. + */ +#ifndef irq_finish +#define irq_finish(irq) do { } while (0) +#endif + /** * disable_irq - disable an irq and wait for completion * @irq: Interrupt to disable * - * Disable the selected interrupt line. + * Disable the selected interrupt line. We do this lazily. * - * This function may be called - with care - from IRQ context. + * This function may be called from IRQ context. */ void disable_irq(unsigned int irq) { + struct irqdesc *desc = irq_desc + irq; unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); - irq_desc[irq].enabled = 0; - irq_desc[irq].mask(irq); + if (!desc->disable_depth++) { +#ifndef CONFIG_CPU_SA1100 + desc->mask(irq); +#endif + } spin_unlock_irqrestore(&irq_controller_lock, flags); } @@ -79,19 +93,37 @@ * enable_irq - enable interrupt handling on an irq * @irq: Interrupt to enable * - * Re-enables the processing of interrupts on this IRQ line + * Re-enables the processing of interrupts on this IRQ line. + * Note that this may call the interrupt handler, so you may + * get unexpected results if you hold IRQs disabled. * * This function may be called from IRQ context. */ void enable_irq(unsigned int irq) { + struct irqdesc *desc = irq_desc + irq; unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); - irq_desc[irq].probing = 0; - irq_desc[irq].triggered = 0; - irq_desc[irq].enabled = 1; - irq_desc[irq].unmask(irq); + if (!desc->disable_depth) { + printk("enable_irq(%u) unbalanced from %p\n", irq, + __builtin_return_address(0)); + } else if (!--desc->disable_depth) { + desc->probing = 0; + desc->unmask(irq); + + /* + * If the interrupt is waiting to be processed, + * try to re-run it. We can't directly run it + * from here since the caller might be in an + * interrupt-protected region. + */ + if (desc->pending) { + desc->pending = 0; + if (list_empty(&desc->pend)) + list_add(&desc->pend, &irq_pending); + } + } spin_unlock_irqrestore(&irq_controller_lock, flags); } @@ -128,7 +160,7 @@ * a large number if IRQs to appear in the same jiffie with the * same instruction pointer (or within 2 instructions). */ -static void check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs) +static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs) { unsigned long instr_ptr = instruction_pointer(regs); @@ -137,95 +169,202 @@ desc->lck_cnt += 1; if (desc->lck_cnt > MAX_IRQ_CNT) { - printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq); - disable_irq(irq); + if (!desc->lck_warned++) + printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq); + mod_timer(&desc->lck_timer, jiffies + 10*HZ); + return 1; } } else { desc->lck_cnt = 0; desc->lck_pc = instruction_pointer(regs); desc->lck_jif = jiffies; + if (desc->lck_warned < 0) + desc->lck_warned ++; } + return 0; +} + +static void +__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) +{ + unsigned int status; + + spin_unlock(&irq_controller_lock); + + if (!(action->flags & SA_INTERRUPT)) + local_irq_enable(); + + status = 0; + do { + status |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + + spin_lock_irq(&irq_controller_lock); } /* * do_IRQ handles all normal device IRQ's */ -asmlinkage void do_IRQ(int irq, struct pt_regs * regs) +void do_IRQ(int irq, struct pt_regs * regs) { - struct irqdesc * desc; - struct irqaction * action; - int cpu; + struct irqdesc *desc = irq_desc + irq; - irq = fixup_irq(irq); + desc->triggered = 1; /* - * Some hardware gives randomly wrong interrupts. Rather - * than crashing, do something sensible. + * Acknowledge and clear the IRQ, but (if its + * a level-based IRQ, don't mask it) */ - if (irq >= NR_IRQS) - goto bad_irq; + desc->mask_ack(irq); - desc = irq_desc + irq; + /* + * If we're currently running this IRQ, or its disabled, + * we shouldn't process the IRQ. Instead, turn on the + * hardware masks. + */ + if (desc->running || desc->disable_depth) + goto running; - spin_lock(&irq_controller_lock); - desc->mask_ack(irq); - spin_unlock(&irq_controller_lock); + /* + * Mark the IRQ currently in progress. + */ + desc->running = 1; - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; - desc->triggered = 1; + kstat.irqs[smp_processor_id()][irq]++; - /* Return with this interrupt masked if no action */ - action = desc->action; + do { + struct irqaction *action; - if (action) { - int status = 0; + action = desc->action; + if (!action) + break; - if (desc->nomask) { - spin_lock(&irq_controller_lock); + if (desc->pending && desc->disable_depth == 0) { + desc->pending = 0; desc->unmask(irq); - spin_unlock(&irq_controller_lock); } - if (!(action->flags & SA_INTERRUPT)) - __sti(); + __do_irq(irq, action, regs); + } while (desc->pending && desc->disable_depth == 0); - do { - status |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); + desc->running = 0; - if (status & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - __cli(); + /* + * If we are disabled or freed, shut down the handler. + */ + if (desc->action && !check_irq_lock(desc, irq, regs)) + desc->unmask(irq); + return; - if (!desc->nomask && desc->enabled) { - spin_lock(&irq_controller_lock); - desc->unmask(irq); - spin_unlock(&irq_controller_lock); + running: + /* + * We got another IRQ while this one was masked or + * currently running. Delay it. + */ + desc->pending = 1; +} + +static void do_pending_irqs(struct pt_regs *regs) +{ + struct list_head head, *l, *n; + + do { + struct irqdesc *desc; + + /* + * First, take the pending interrupts off the list. + * The act of calling the handlers may add some IRQs + * back onto the list. + */ + head = irq_pending; + INIT_LIST_HEAD(&irq_pending); + head.next->prev = &head; + head.prev->next = &head; + + /* + * Now run each entry. We must delete it from our + * list before calling the handler. + */ + list_for_each_safe(l, n, &head) { + desc = list_entry(l, struct irqdesc, pend); + list_del_init(&desc->pend); + do_IRQ(desc - irq_desc, regs); } - } + + /* + * The list must be empty. + */ + BUG_ON(!list_empty(&head)); + } while (!list_empty(&irq_pending)); +} + +/* + * do_IRQ handles all hardware IRQ's. Decoded IRQs should not + * come via this function. Instead, they should provide their + * own 'handler' + */ +asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs) +{ + irq = fixup_irq(irq); /* - * Debug measure - hopefully we can continue if an - * IRQ lockup problem occurs... + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. */ - check_irq_lock(desc, irq, regs); + if (irq < NR_IRQS) { + int cpu = smp_processor_id(); - irq_exit(cpu, irq); + irq_enter(cpu, irq); + spin_lock(&irq_controller_lock); + do_IRQ(irq, regs); - if (softirq_pending(cpu)) - do_softirq(); - return; + /* + * Now re-run any pending interrupts. + */ + if (!list_empty(&irq_pending)) + do_pending_irqs(regs); + + spin_unlock(&irq_controller_lock); + irq_exit(cpu, irq); + + if (softirq_pending(cpu)) + do_softirq(); + + irq_finish(irq); + return; + } -bad_irq: irq_err_count += 1; printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); + + irq_finish(irq); return; } +static void irqlck_timeout(unsigned long _data) +{ + struct irqdesc *desc = (struct irqdesc *)_data; + + spin_lock(&irq_controller_lock); + + del_timer(&desc->lck_timer); + + desc->lck_cnt = 0; + desc->lck_pc = 0; + desc->lck_jif = 0; + desc->lck_warned = -10; + + if (desc->disable_depth == 0) + desc->unmask(desc - irq_desc); + + spin_unlock(&irq_controller_lock); +} + #ifdef CONFIG_ARCH_ACORN void do_ecard_IRQ(int irq, struct pt_regs *regs) { @@ -302,10 +441,12 @@ *p = new; if (!shared) { - desc->nomask = (new->flags & SA_IRQNOMASK) ? 1 : 0; desc->probing = 0; + desc->running = 0; + desc->pending = 0; + desc->disable_depth = 1; if (!desc->noautoenable) { - desc->enabled = 1; + desc->disable_depth = 0; desc->unmask(irq); } } @@ -383,7 +524,7 @@ * On a shared IRQ the caller must ensure the interrupt is disabled * on the card it drives before calling this function. * - * This function may be called from interrupt context. + * This function must not be called from interrupt context. */ void free_irq(unsigned int irq, void *dev_id) { @@ -416,6 +557,8 @@ spin_unlock_irqrestore(&irq_controller_lock, flags); } +static DECLARE_MUTEX(probe_sem); + /* Start the interrupt probing. Unlike other architectures, * we don't return a mask of interrupts from probe_irq_on, * but return the number of interrupts enabled for the probe. @@ -427,15 +570,15 @@ unsigned int i, irqs = 0; unsigned long delay; + down(&probe_sem); + /* * first snaffle up any unassigned but * probe-able interrupts */ spin_lock_irq(&irq_controller_lock); for (i = 0; i < NR_IRQS; i++) { - if (!irq_desc[i].valid || - !irq_desc[i].probe_ok || - irq_desc[i].action) + if (!irq_desc[i].probe_ok || irq_desc[i].action) continue; irq_desc[i].probing = 1; @@ -456,18 +599,31 @@ */ spin_lock_irq(&irq_controller_lock); for (i = 0; i < NR_IRQS; i++) { - if (irq_desc[i].probing && - irq_desc[i].triggered) { + if (irq_desc[i].probing && irq_desc[i].triggered) { irq_desc[i].probing = 0; irqs -= 1; } } spin_unlock_irq(&irq_controller_lock); - /* now filter out any obviously spurious interrupts */ return irqs; } +unsigned int probe_irq_mask(unsigned long irqs) +{ + unsigned int mask = 0, i; + + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < 16 && i < NR_IRQS; i++) + if (irq_desc[i].probing && irq_desc[i].triggered) + mask |= 1 << i; + spin_unlock_irq(&irq_controller_lock); + + up(&probe_sem); + + return mask; +} + /* * Possible return values: * >= 0 - interrupt number @@ -499,6 +655,8 @@ out: spin_unlock_irq(&irq_controller_lock); + up(&probe_sem); + return irq_found; } @@ -512,12 +670,17 @@ int irq; for (irq = 0; irq < NR_IRQS; irq++) { + irq_desc[irq].disable_depth = 1; irq_desc[irq].probe_ok = 0; irq_desc[irq].valid = 0; irq_desc[irq].noautoenable = 0; irq_desc[irq].mask_ack = dummy_mask_unmask_irq; irq_desc[irq].mask = dummy_mask_unmask_irq; irq_desc[irq].unmask = dummy_mask_unmask_irq; + INIT_LIST_HEAD(&irq_desc[irq].pend); + init_timer(&irq_desc[irq].lck_timer); + irq_desc[irq].lck_timer.data = (unsigned long)&irq_desc[irq]; + irq_desc[irq].lck_timer.function = irqlck_timeout; } init_arch_irq(); diff -urN linux-2.4.21/arch/arm/kernel/oldlatches.c linux-2.4.22/arch/arm/kernel/oldlatches.c --- linux-2.4.21/arch/arm/kernel/oldlatches.c 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/oldlatches.c 2003-08-25 04:44:39.000000000 -0700 @@ -29,10 +29,10 @@ if (machine_is_archimedes()) { unsigned long flags; - local_save_flags(flags); + local_irq_save(flags); latch_a_copy = (latch_a_copy & ~mask) | newdata; __raw_writeb(latch_a_copy, LATCHA_BASE); - local_restore_flags(flags); + local_irq_restore(flags); printk("Latch: A = 0x%02x\n", latch_a_copy); } else @@ -46,10 +46,10 @@ if (machine_is_archimedes()) { unsigned long flags; - local_save_flags(flags); + local_irq_save(flags); latch_b_copy = (latch_b_copy & ~mask) | newdata; __raw_writeb(latch_b_copy, LATCHB_BASE); - local_restore_flags(flags); + local_irq_restore(flags); printk("Latch: B = 0x%02x\n", latch_b_copy); } else diff -urN linux-2.4.21/arch/arm/kernel/process.c linux-2.4.22/arch/arm/kernel/process.c --- linux-2.4.21/arch/arm/kernel/process.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/process.c 2003-08-25 04:44:39.000000000 -0700 @@ -24,18 +24,10 @@ #include #include -#include #include +#include #include -/* - * Values for cpu_do_idle() - */ -#define IDLE_WAIT_SLOW 0 -#define IDLE_WAIT_FAST 1 -#define IDLE_CLOCK_SLOW 2 -#define IDLE_CLOCK_FAST 3 - extern const char *processor_modes[]; extern void setup_mm_for_reboot(char mode); @@ -75,6 +67,18 @@ void (*pm_power_off)(void); /* + * This is our default idle handler. We need to disable + * interrupts here to ensure we don't miss a wakeup call. + */ +void default_idle(void) +{ + local_irq_disable(); + if (!current->need_resched && !hlt_counter) + arch_idle(); + local_irq_enable(); +} + +/* * The idle thread. We try to conserve power, while trying to keep * overall latency low. The architecture specific idle is passed * a value to indicate the level of "idleness" of the system. @@ -89,7 +93,7 @@ while (1) { void (*idle)(void) = pm_idle; if (!idle) - idle = arch_idle; + idle = default_idle; leds_event(led_idle_start); while (!current->need_resched) idle(); @@ -176,15 +180,15 @@ flags & CC_Z_BIT ? 'Z' : 'z', flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); - printk(" IRQs %s FIQs %s Mode %s%s Segment %s\n", - interrupts_enabled(regs) ? "on" : "off", - fast_interrupts_enabled(regs) ? "on" : "off", + printk(" IRQs o%s FIQs o%s Mode %s%s Segment %s\n", + interrupts_enabled(regs) ? "n" : "ff", + fast_interrupts_enabled(regs) ? "n" : "ff", processor_modes[processor_mode(regs)], thumb_mode(regs) ? " (T)" : "", get_fs() == get_ds() ? "kernel" : "user"); #if defined(CONFIG_CPU_32) { - int ctrl, transbase, dac; + unsigned int ctrl, transbase, dac; __asm__ ( " mrc p15, 0, %0, c1, c0\n" " mrc p15, 0, %1, c2, c0\n" @@ -282,12 +286,22 @@ { } +static void default_fp_init(union fp_state *fp) +{ + memset(fp, 0, sizeof(union fp_state)); +} + +void (*fp_init)(union fp_state *) = default_fp_init; + void flush_thread(void) { - memset(¤t->thread.debug, 0, sizeof(struct debug_info)); - memset(¤t->thread.fpstate, 0, sizeof(union fp_state)); - current->used_math = 0; - current->flags &= ~PF_USEDFPU; + struct task_struct *tsk = current; + + tsk->flags &= ~PF_USEDFPU; + tsk->used_math = 0; + + memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); + fp_init(&tsk->thread.fpstate); } void release_thread(struct task_struct *dead_task) @@ -296,16 +310,16 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, - unsigned long unused, - struct task_struct * p, struct pt_regs * regs) +int +copy_thread(int nr, unsigned long clone_flags, unsigned long esp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { - struct pt_regs * childregs; + struct pt_regs *childregs; struct context_save_struct * save; atomic_set(&p->thread.refcount, 1); - childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1; + childregs = ((struct pt_regs *)((unsigned long)p + 8192 - 8)) - 1; *childregs = *regs; childregs->ARM_r0 = 0; childregs->ARM_sp = esp; @@ -324,10 +338,12 @@ */ int dump_fpu (struct pt_regs *regs, struct user_fp *fp) { - if (current->used_math) + int used_math = current->used_math; + + if (used_math) memcpy(fp, ¤t->thread.fpstate.soft, sizeof (*fp)); - return current->used_math; + return used_math; } /* @@ -347,8 +363,8 @@ dump->u_debugreg[0] = tsk->thread.debug.bp[0].address; dump->u_debugreg[1] = tsk->thread.debug.bp[1].address; - dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn; - dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn; + dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn.arm; + dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn.arm; dump->u_debugreg[4] = tsk->thread.debug.nsaved; if (dump->start_stack < 0x04000000) @@ -371,18 +387,18 @@ pid_t __ret; __asm__ __volatile__( - "orr r0, %1, %2 @ kernel_thread sys_clone - mov r1, #0 - "__syscall(clone)" - movs %0, r0 @ if we are the child - bne 1f - mov fp, #0 @ ensure that fp is zero - mov r0, %4 - mov lr, pc - mov pc, %3 - b sys_exit + "orr r0, %1, %2 @ kernel_thread sys_clone \n\ + mov r1, #0 \n\ + "__syscall(clone)" \n\ + movs %0, r0 @ if we are the child \n\ + bne 1f \n\ + mov fp, #0 @ ensure that fp is zero \n\ + mov r0, %4 \n\ + mov lr, pc \n\ + mov pc, %3 \n\ + b sys_exit \n\ 1: " - : "=r" (__ret) + : "=&r" (__ret) : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg) : "r0", "r1", "lr"); return __ret; @@ -405,7 +421,7 @@ return 0; stack_page = 4096 + (unsigned long)p; - fp = get_css_fp(&p->thread); + fp = thread_saved_fp(&p->thread); do { if (fp < stack_page || fp > 4092+stack_page) return 0; diff -urN linux-2.4.21/arch/arm/kernel/ptrace.c linux-2.4.22/arch/arm/kernel/ptrace.c --- linux-2.4.21/arch/arm/kernel/ptrace.c 2001-09-18 17:03:51.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/ptrace.c 2003-08-25 04:44:39.000000000 -0700 @@ -9,6 +9,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #include @@ -33,18 +35,24 @@ /* * Breakpoint SWI instruction: SWI &9F0001 */ -#define BREAKINST 0xef9f0001 +#define BREAKINST_ARM 0xef9f0001 +/* fill this in later */ +#define BREAKINST_THUMB 0xdf00 /* * Get the address of the live pt_regs for the specified task. * These are saved onto the top kernel stack when the process * is not running. + * + * Note: if a user thread is execve'd from kernel space, the + * kernel stack will not be empty on entry to the kernel, so + * ptracing these tasks will fail. */ static inline struct pt_regs * get_user_regs(struct task_struct *task) { return (struct pt_regs *) - ((unsigned long)task + 8192 - sizeof(struct pt_regs)); + ((unsigned long)task + 8192 - 8 - sizeof(struct pt_regs)); } /* @@ -53,7 +61,7 @@ * this routine assumes that all the privileged stacks are in our * data space. */ -static inline long get_stack_long(struct task_struct *task, int offset) +static inline long get_user_reg(struct task_struct *task, int offset) { return get_user_regs(task)->uregs[offset]; } @@ -65,14 +73,14 @@ * data space. */ static inline int -put_stack_long(struct task_struct *task, int offset, long data) +put_user_reg(struct task_struct *task, int offset, long data) { struct pt_regs newregs, *regs = get_user_regs(task); int ret = -EINVAL; newregs = *regs; newregs.uregs[offset] = data; - + if (valid_user_regs(&newregs)) { regs->uregs[offset] = data; ret = 0; @@ -82,23 +90,32 @@ } static inline int -read_tsk_long(struct task_struct *child, unsigned long addr, unsigned long *res) +read_u32(struct task_struct *task, unsigned long addr, u32 *res) { - int copied; + int ret; - copied = access_process_vm(child, addr, res, sizeof(*res), 0); + ret = access_process_vm(task, addr, res, sizeof(*res), 0); - return copied != sizeof(*res) ? -EIO : 0; + return ret == sizeof(*res) ? 0 : -EIO; } static inline int -write_tsk_long(struct task_struct *child, unsigned long addr, unsigned long val) +read_instr(struct task_struct *task, unsigned long addr, u32 *res) { - int copied; - - copied = access_process_vm(child, addr, &val, sizeof(val), 1); + int ret; - return copied != sizeof(val) ? -EIO : 0; + if (addr & 1) { + u16 val; + ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0); + ret = ret == sizeof(val) ? 0 : -EIO; + *res = val; + } else { + u32 val; + ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0); + ret = ret == sizeof(val) ? 0 : -EIO; + *res = val; + } + return ret; } /* @@ -110,7 +127,7 @@ unsigned int reg = (insn >> 16) & 15; unsigned long val; - val = get_stack_long(child, reg); + val = get_user_reg(child, reg); if (reg == 15) val = pc_pointer(val + 8); @@ -132,10 +149,10 @@ shift = (insn >> 8) & 15; type = 3; } else { - val = get_stack_long (child, insn & 15); + val = get_user_reg (child, insn & 15); if (insn & (1 << 4)) - shift = (int)get_stack_long (child, (insn >> 8) & 15); + shift = (int)get_user_reg (child, (insn >> 8) & 15); else shift = (insn >> 7) & 31; @@ -165,7 +182,7 @@ int shift; int type; - val = get_stack_long(child, insn & 15); + val = get_user_reg(child, insn & 15); shift = (insn >> 7) & 31; type = (insn >> 5) & 3; @@ -182,10 +199,24 @@ return val; } +#define OP_MASK 0x01e00000 +#define OP_AND 0x00000000 +#define OP_EOR 0x00200000 +#define OP_SUB 0x00400000 +#define OP_RSB 0x00600000 +#define OP_ADD 0x00800000 +#define OP_ADC 0x00a00000 +#define OP_SBC 0x00c00000 +#define OP_RSC 0x00e00000 +#define OP_ORR 0x01800000 +#define OP_MOV 0x01a00000 +#define OP_BIC 0x01c00000 +#define OP_MVN 0x01e00000 + static unsigned long get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn) { - unsigned long alt = 0; + u32 alt = 0; switch (insn & 0x0e000000) { case 0x00000000: @@ -200,21 +231,21 @@ aluop1 = ptrace_getrn(child, insn); aluop2 = ptrace_getaluop2(child, insn); - ccbit = get_stack_long(child, REG_PSR) & CC_C_BIT ? 1 : 0; + ccbit = get_user_reg(child, REG_PSR) & CC_C_BIT ? 1 : 0; - switch (insn & 0x01e00000) { - case 0x00000000: alt = aluop1 & aluop2; break; - case 0x00200000: alt = aluop1 ^ aluop2; break; - case 0x00400000: alt = aluop1 - aluop2; break; - case 0x00600000: alt = aluop2 - aluop1; break; - case 0x00800000: alt = aluop1 + aluop2; break; - case 0x00a00000: alt = aluop1 + aluop2 + ccbit; break; - case 0x00c00000: alt = aluop1 - aluop2 + ccbit; break; - case 0x00e00000: alt = aluop2 - aluop1 + ccbit; break; - case 0x01800000: alt = aluop1 | aluop2; break; - case 0x01a00000: alt = aluop2; break; - case 0x01c00000: alt = aluop1 & ~aluop2; break; - case 0x01e00000: alt = ~aluop2; break; + switch (insn & OP_MASK) { + case OP_AND: alt = aluop1 & aluop2; break; + case OP_EOR: alt = aluop1 ^ aluop2; break; + case OP_SUB: alt = aluop1 - aluop2; break; + case OP_RSB: alt = aluop2 - aluop1; break; + case OP_ADD: alt = aluop1 + aluop2; break; + case OP_ADC: alt = aluop1 + aluop2 + ccbit; break; + case OP_SBC: alt = aluop1 - aluop2 + ccbit; break; + case OP_RSC: alt = aluop2 - aluop1 + ccbit; break; + case OP_ORR: alt = aluop1 | aluop2; break; + case OP_MOV: alt = aluop2; break; + case OP_BIC: alt = aluop1 & ~aluop2; break; + case OP_MVN: alt = ~aluop2; break; } break; } @@ -241,7 +272,7 @@ else base -= aluop2; } - if (read_tsk_long(child, base, &alt) == 0) + if (read_u32(child, base, &alt) == 0) alt = pc_pointer(alt); } break; @@ -255,13 +286,7 @@ unsigned int nr_regs; if (insn & (1 << 23)) { - nr_regs = insn & 65535; - - nr_regs = (nr_regs & 0x5555) + ((nr_regs & 0xaaaa) >> 1); - nr_regs = (nr_regs & 0x3333) + ((nr_regs & 0xcccc) >> 2); - nr_regs = (nr_regs & 0x0707) + ((nr_regs & 0x7070) >> 4); - nr_regs = (nr_regs & 0x000f) + ((nr_regs & 0x0f00) >> 8); - nr_regs <<= 2; + nr_regs = hweight16(insn & 65535) << 2; if (!(insn & (1 << 24))) nr_regs -= 4; @@ -274,8 +299,8 @@ base = ptrace_getrn(child, insn); - if (read_tsk_long(child, base + nr_regs, &alt) == 0) - alt = pc_pointer (alt); + if (read_u32(child, base + nr_regs, &alt) == 0) + alt = pc_pointer(alt); break; } break; @@ -304,36 +329,82 @@ } static int -add_breakpoint(struct task_struct *child, struct debug_info *dbg, unsigned long addr) +swap_insn(struct task_struct *task, unsigned long addr, + void *old_insn, void *new_insn, int size) +{ + int ret; + + ret = access_process_vm(task, addr, old_insn, size, 0); + if (ret == size) + ret = access_process_vm(task, addr, new_insn, size, 1); + return ret; +} + +static void +add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr) { int nr = dbg->nsaved; - int res = -EINVAL; if (nr < 2) { - res = read_tsk_long(child, addr, &dbg->bp[nr].insn); - if (res == 0) - res = write_tsk_long(child, addr, BREAKINST); + u32 new_insn = BREAKINST_ARM; + int res; - if (res == 0) { + res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4); + + if (res == 4) { dbg->bp[nr].address = addr; dbg->nsaved += 1; } } else printk(KERN_ERR "ptrace: too many breakpoints\n"); +} + +/* + * Clear one breakpoint in the user program. We copy what the hardware + * does and use bit 0 of the address to indicate whether this is a Thumb + * breakpoint or an ARM breakpoint. + */ +static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp) +{ + unsigned long addr = bp->address; + union debug_insn old_insn; + int ret; + + if (addr & 1) { + ret = swap_insn(task, addr & ~1, &old_insn.thumb, + &bp->insn.thumb, 2); + + if (ret != 2 || old_insn.thumb != BREAKINST_THUMB) + printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at " + "0x%08lx (0x%04x)\n", task->comm, task->pid, + addr, old_insn.thumb); + } else { + ret = swap_insn(task, addr & ~3, &old_insn.thumb, + &bp->insn.thumb, 4); - return res; + if (ret != 4 || old_insn.arm != BREAKINST_ARM) + printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at " + "0x%08lx (0x%08x)\n", task->comm, task->pid, + addr, old_insn.arm); + } } -int ptrace_set_bpt(struct task_struct *child) +void ptrace_set_bpt(struct task_struct *child) { struct pt_regs *regs; - unsigned long pc, insn; + unsigned long pc; + u32 insn; int res; regs = get_user_regs(child); pc = instruction_pointer(regs); - res = read_tsk_long(child, pc, &insn); + if (thumb_mode(regs)) { + printk(KERN_WARNING "ptrace: can't handle thumb mode\n"); + return; + } + + res = read_instr(child, pc, &insn); if (!res) { struct debug_info *dbg = &child->thread.debug; unsigned long alt; @@ -342,7 +413,7 @@ alt = get_branch_address(child, pc, insn); if (alt) - res = add_breakpoint(child, dbg, alt); + add_breakpoint(child, dbg, alt); /* * Note that we ignore the result of setting the above @@ -354,10 +425,8 @@ * loose control of the thread during single stepping. */ if (!alt || predicate(insn) != PREDICATE_ALWAYS) - res = add_breakpoint(child, dbg, pc + 4); + add_breakpoint(child, dbg, pc + 4); } - - return res; } /* @@ -366,24 +435,17 @@ */ void __ptrace_cancel_bpt(struct task_struct *child) { - struct debug_info *dbg = &child->thread.debug; - int i, nsaved = dbg->nsaved; + int i, nsaved = child->thread.debug.nsaved; - dbg->nsaved = 0; + child->thread.debug.nsaved = 0; if (nsaved > 2) { printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); nsaved = 2; } - for (i = 0; i < nsaved; i++) { - unsigned long tmp; - - read_tsk_long(child, dbg->bp[i].address, &tmp); - write_tsk_long(child, dbg->bp[i].address, dbg->bp[i].insn); - if (tmp != BREAKINST) - printk(KERN_ERR "ptrace_cancel_bpt: weirdness\n"); - } + for (i = 0; i < nsaved; i++) + clear_breakpoint(child, &child->thread.debug.bp[i]); } /* @@ -396,6 +458,114 @@ __ptrace_cancel_bpt(child); } +/* + * Handle hitting a breakpoint. regs points at the instruction. + */ +void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) +{ + siginfo_t info; + + /* + * The PC is pointing at the next instruction. Fix this. + */ + regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; + + __ptrace_cancel_bpt(tsk); + + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_BRKPT; + info.si_addr = (void *)instruction_pointer(regs); + + force_sig_info(SIGTRAP, &info, tsk); +} + +/* + * Read the word at offset "off" into the "struct user". We + * actually access the pt_regs stored on the kernel stack. + */ +static int ptrace_read_user(struct task_struct *tsk, unsigned long off, + unsigned long *ret) +{ + unsigned long tmp; + + if (off & 3 || off >= sizeof(struct user)) + return -EIO; + + tmp = 0; + if (off < sizeof(struct pt_regs)) + tmp = get_user_reg(tsk, off >> 2); + + return put_user(tmp, ret); +} + +/* + * Write the word at offset "off" into "struct user". We + * actually access the pt_regs stored on the kernel stack. + */ +static int ptrace_write_user(struct task_struct *tsk, unsigned long off, + unsigned long val) +{ + if (off & 3 || off >= sizeof(struct user)) + return -EIO; + + if (off >= sizeof(struct pt_regs)) + return 0; + + return put_user_reg(tsk, off >> 2, val); +} + +/* + * Get all user integer registers. + */ +static int ptrace_getregs(struct task_struct *tsk, void *uregs) +{ + struct pt_regs *regs = get_user_regs(tsk); + + return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; +} + +/* + * Set all user integer registers. + */ +static int ptrace_setregs(struct task_struct *tsk, void *uregs) +{ + struct pt_regs newregs; + int ret; + + ret = -EFAULT; + if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { + struct pt_regs *regs = get_user_regs(tsk); + + ret = -EINVAL; + if (valid_user_regs(&newregs)) { + *regs = newregs; + ret = 0; + } + } + + return ret; +} + +/* + * Get the child FPU state. + */ +static int ptrace_getfpregs(struct task_struct *tsk, void *ufp) +{ + return copy_to_user(ufp, &tsk->thread.fpstate, + sizeof(struct user_fp)) ? -EFAULT : 0; +} + +/* + * Set the child FPU state. + */ +static int ptrace_setfpregs(struct task_struct *tsk, void *ufp) +{ + tsk->used_math = 1; + return copy_from_user(&tsk->thread.fpstate, ufp, + sizeof(struct user_fp)) ? -EFAULT : 0; +} + static int do_ptrace(int request, struct task_struct *child, long addr, long data) { unsigned long tmp; @@ -407,23 +577,16 @@ */ case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: - ret = read_tsk_long(child, addr, &tmp); - if (!ret) + ret = access_process_vm(child, addr, &tmp, + sizeof(unsigned long), 0); + if (ret == sizeof(unsigned long)) ret = put_user(tmp, (unsigned long *) data); + else + ret = -EIO; break; - /* - * read the word at location "addr" in the user registers. - */ case PTRACE_PEEKUSR: - ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) - break; - - tmp = 0; /* Default return condition */ - if (addr < sizeof(struct pt_regs)) - tmp = get_stack_long(child, (int)addr >> 2); - ret = put_user(tmp, (unsigned long *)data); + ret = ptrace_read_user(child, addr, (unsigned long *)data); break; /* @@ -431,19 +594,16 @@ */ case PTRACE_POKETEXT: case PTRACE_POKEDATA: - ret = write_tsk_long(child, addr, data); + ret = access_process_vm(child, addr, &data, + sizeof(unsigned long), 1); + if (ret == sizeof(unsigned long)) + ret = 0; + else + ret = -EIO; break; - /* - * write the word at location addr in the user registers. - */ case PTRACE_POKEUSR: - ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) - break; - - if (addr < sizeof(struct pt_regs)) - ret = put_stack_long(child, (int)addr >> 2, data); + ret = ptrace_write_user(child, addr, data); break; /* @@ -471,14 +631,12 @@ * exit. */ case PTRACE_KILL: - /* already dead */ - ret = 0; - if (child->state == TASK_ZOMBIE) - break; - child->exit_code = SIGKILL; /* make sure single-step breakpoint is gone. */ __ptrace_cancel_bpt(child); - wake_up_process(child); + if (child->state != TASK_ZOMBIE) { + child->exit_code = SIGKILL; + wake_up_process(child); + } ret = 0; break; @@ -497,71 +655,32 @@ ret = 0; break; - /* - * detach a process that was attached. - */ case PTRACE_DETACH: ret = ptrace_detach(child, data); break; - /* - * Get all gp regs from the child. - */ - case PTRACE_GETREGS: { - struct pt_regs *regs = get_user_regs(child); - - ret = 0; - if (copy_to_user((void *)data, regs, - sizeof(struct pt_regs))) - ret = -EFAULT; - + case PTRACE_GETREGS: + ret = ptrace_getregs(child, (void *)data); break; - } - - /* - * Set all gp regs in the child. - */ - case PTRACE_SETREGS: { - struct pt_regs newregs; - ret = -EFAULT; - if (copy_from_user(&newregs, (void *)data, - sizeof(struct pt_regs)) == 0) { - struct pt_regs *regs = get_user_regs(child); - - ret = -EINVAL; - if (valid_user_regs(&newregs)) { - *regs = newregs; - ret = 0; - } - } + case PTRACE_SETREGS: + ret = ptrace_setregs(child, (void *)data); break; - } - /* - * Get the child FPU state. - */ case PTRACE_GETFPREGS: - ret = -EIO; - if (!access_ok(VERIFY_WRITE, (void *)data, sizeof(struct user_fp))) - break; - - /* we should check child->used_math here */ - ret = __copy_to_user((void *)data, &child->thread.fpstate, - sizeof(struct user_fp)) ? -EFAULT : 0; + ret = ptrace_getfpregs(child, (void *)data); break; - /* - * Set the child FPU state. - */ case PTRACE_SETFPREGS: - ret = -EIO; - if (!access_ok(VERIFY_READ, (void *)data, sizeof(struct user_fp))) - break; + ret = ptrace_setfpregs(child, (void *)data); + break; - child->used_math = 1; - ret = __copy_from_user(&child->thread.fpstate, (void *)data, - sizeof(struct user_fp)) ? -EFAULT : 0; + case PTRACE_SETOPTIONS: + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; break; default: diff -urN linux-2.4.21/arch/arm/kernel/ptrace.h linux-2.4.22/arch/arm/kernel/ptrace.h --- linux-2.4.21/arch/arm/kernel/ptrace.h 2000-09-18 15:15:25.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/ptrace.h 2003-08-25 04:44:39.000000000 -0700 @@ -1,14 +1,15 @@ /* * linux/arch/arm/kernel/ptrace.h * - * Copyright (C) 2000 Russell King + * Copyright (C) 2000-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ extern void __ptrace_cancel_bpt(struct task_struct *); -extern int ptrace_set_bpt(struct task_struct *); +extern void ptrace_set_bpt(struct task_struct *); +extern void ptrace_break(struct task_struct *, struct pt_regs *); /* * Clear a breakpoint, if one exists. diff -urN linux-2.4.21/arch/arm/kernel/semaphore.c linux-2.4.22/arch/arm/kernel/semaphore.c --- linux-2.4.21/arch/arm/kernel/semaphore.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/semaphore.c 2003-08-25 04:44:39.000000000 -0700 @@ -177,76 +177,76 @@ * value in some cases.. */ #ifdef CONFIG_CPU_26 -asm(" .align 5 - .globl __down_failed -__down_failed: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __down - ldmfd sp!, {r0 - r3, pc}^ - - .align 5 - .globl __down_interruptible_failed -__down_interruptible_failed: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __down_interruptible - mov ip, r0 - ldmfd sp!, {r0 - r3, pc}^ - - .align 5 - .globl __down_trylock_failed -__down_trylock_failed: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __down_trylock - mov ip, r0 - ldmfd sp!, {r0 - r3, pc}^ - - .align 5 - .globl __up_wakeup -__up_wakeup: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __up - ldmfd sp!, {r0 - r3, pc}^ +asm(" .align 5 \n\ + .globl __down_failed \n\ +__down_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down \n\ + ldmfd sp!, {r0 - r3, pc}^ \n\ + \n\ + .align 5 \n\ + .globl __down_interruptible_failed \n\ +__down_interruptible_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down_interruptible \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r3, pc}^ \n\ + + .align 5 \n\ + .globl __down_trylock_failed \n\ +__down_trylock_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down_trylock \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r3, pc}^ \n\ + \n\ + .align 5 \n\ + .globl __up_wakeup \n\ +__up_wakeup: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __up \n\ + ldmfd sp!, {r0 - r3, pc}^ \n\ "); #else /* 32 bit version */ -asm(" .align 5 - .globl __down_failed -__down_failed: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __down - ldmfd sp!, {r0 - r3, pc} - - .align 5 - .globl __down_interruptible_failed -__down_interruptible_failed: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __down_interruptible - mov ip, r0 - ldmfd sp!, {r0 - r3, pc} - - .align 5 - .globl __down_trylock_failed -__down_trylock_failed: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __down_trylock - mov ip, r0 - ldmfd sp!, {r0 - r3, pc} - - .align 5 - .globl __up_wakeup -__up_wakeup: - stmfd sp!, {r0 - r3, lr} - mov r0, ip - bl __up - ldmfd sp!, {r0 - r3, pc} +asm(" .align 5 \n\ + .globl __down_failed \n\ +__down_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down \n\ + ldmfd sp!, {r0 - r3, pc} \n\ + \n\ + .align 5 \n\ + .globl __down_interruptible_failed \n\ +__down_interruptible_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down_interruptible \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r3, pc} \n\ + \n\ + .align 5 \n\ + .globl __down_trylock_failed \n\ +__down_trylock_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down_trylock \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r3, pc} \n\ + \n\ + .align 5 \n\ + .globl __up_wakeup \n\ +__up_wakeup: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __up \n\ + ldmfd sp!, {r0 - r3, pc} \n\ "); #endif diff -urN linux-2.4.21/arch/arm/kernel/setup.c linux-2.4.22/arch/arm/kernel/setup.c --- linux-2.4.21/arch/arm/kernel/setup.c 2001-11-16 10:07:47.000000000 -0800 +++ linux-2.4.22/arch/arm/kernel/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -33,10 +35,6 @@ #define MEM_SIZE (16*1024*1024) #endif -#ifndef CONFIG_CMDLINE -#define CONFIG_CMDLINE "" -#endif - #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) char fpe_type[8]; @@ -51,14 +49,14 @@ extern unsigned int mem_fclk_21285; extern void paging_init(struct meminfo *, struct machine_desc *desc); -extern void convert_to_tag_list(struct param_struct *params, int mem_init); +extern void convert_to_tag_list(struct tag *tags); +extern void squash_mem_tags(struct tag *tag); extern void bootmem_init(struct meminfo *); extern void reboot_setup(char *str); extern int root_mountflags; extern int _stext, _text, _etext, _edata, _end; unsigned int processor_id; -unsigned int compat; unsigned int __machine_arch_type; unsigned int system_rev; unsigned int system_serial_low; @@ -72,9 +70,11 @@ unsigned char aux_device_present; char elf_platform[ELF_PLATFORM_SIZE]; char saved_command_line[COMMAND_LINE_SIZE]; +unsigned long phys_initrd_start __initdata = 0; +unsigned long phys_initrd_size __initdata = 0; static struct meminfo meminfo __initdata = { 0, }; -static struct proc_info_item proc_info; +static const char *cpu_name; static const char *machine_name; static char command_line[COMMAND_LINE_SIZE]; @@ -129,15 +129,13 @@ while (1); } - proc_info = *list->info; + cpu_name = list->info->cpu_name; #ifdef MULTI_CPU processor = *list->proc; #endif - printk("Processor: %s %s revision %d\n", - proc_info.manufacturer, proc_info.cpu_name, - (int)processor_id & 15); + printk("CPU: %s revision %d\n", cpu_name, (int)processor_id & 15); sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); @@ -146,7 +144,7 @@ cpu_proc_init(); } -static struct machine_desc * __init setup_architecture(unsigned int nr) +static struct machine_desc * __init setup_machine(unsigned int nr) { extern struct machine_desc __arch_info_begin, __arch_info_end; struct machine_desc *list; @@ -168,12 +166,7 @@ while (1); } - printk("Architecture: %s\n", list->name); - if (compat) - printk(KERN_WARNING "Using compatibility code " - "scheduled for removal in v%d.%d.%d\n", - compat >> 24, (compat >> 12) & 0x3ff, - compat & 0x3ff); + printk("Machine: %s\n", list->name); return list; } @@ -215,6 +208,22 @@ mi->bank[mi->nr_banks].size = size; mi->bank[mi->nr_banks].node = PHYS_TO_NID(start); mi->nr_banks += 1; + } else if (c == ' ' && !memcmp(from, "initrd=", 7)) { + unsigned long start, size; + + /* + * Remove space character + */ + if (to != command_line) + to -= 1; + + start = memparse(from + 7, &from); + if (*from == ',') { + size = memparse(from + 1, &from); + + phys_initrd_start = start; + phys_initrd_size = size; + } } c = *from++; if (!c) @@ -231,7 +240,7 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) { #ifdef CONFIG_BLK_DEV_RAM - extern int rd_size; + extern int rd_size, rd_image_start, rd_prompt, rd_doload; rd_image_start = image_start; rd_prompt = prompt; @@ -250,8 +259,8 @@ #ifdef CONFIG_BLK_DEV_INITRD if (start == 0) size = 0; - initrd_start = start; - initrd_end = start + size; + phys_initrd_start = __virt_to_phys(start); + phys_initrd_size = size; #endif } @@ -351,12 +360,12 @@ #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) struct screen_info screen_info = { - orig_video_lines: 30, - orig_video_cols: 80, - orig_video_mode: 0, - orig_video_ega_bx: 0, - orig_video_isVGA: 1, - orig_video_points: 8 + .orig_video_lines = 30, + .orig_video_cols = 80, + .orig_video_mode = 0, + .orig_video_ega_bx = 0, + .orig_video_isVGA = 1, + .orig_video_points = 8 }; static int __init parse_tag_videotext(const struct tag *tag) @@ -388,12 +397,22 @@ static int __init parse_tag_initrd(const struct tag *tag) { - setup_initrd(tag->u.initrd.start, tag->u.initrd.size); + phys_initrd_start = __virt_to_phys(tag->u.initrd.start); + phys_initrd_size = tag->u.initrd.size; return 0; } __tagtable(ATAG_INITRD, parse_tag_initrd); +static int __init parse_tag_initrd2(const struct tag *tag) +{ + phys_initrd_start = tag->u.initrd.start; + phys_initrd_size = tag->u.initrd.size; + return 0; +} + +__tagtable(ATAG_INITRD2, parse_tag_initrd2); + static int __init parse_tag_serialnr(const struct tag *tag) { system_serial_low = tag->u.serialnr.low; @@ -452,16 +471,30 @@ t->hdr.tag); } +static struct init_tags { + struct tag_header hdr1; + struct tag_core core; + struct tag_header hdr2; + struct tag_mem32 mem; + struct tag_header hdr3; +} init_tags __initdata = { + { tag_size(tag_core), ATAG_CORE }, + { 1, PAGE_SIZE, 0xff }, + { tag_size(tag_mem32), ATAG_MEM }, + { MEM_SIZE, PHYS_OFFSET }, + { 0, ATAG_NONE } +}; + void __init setup_arch(char **cmdline_p) { - struct tag *tags = NULL; + struct tag *tags = (struct tag *)&init_tags; struct machine_desc *mdesc; char *from = default_command_line; ROOT_DEV = MKDEV(0, 255); setup_processor(); - mdesc = setup_architecture(machine_arch_type); + mdesc = setup_machine(machine_arch_type); machine_name = mdesc->name; if (mdesc->soft_reboot) @@ -480,14 +513,16 @@ /* * If we have the old style parameters, convert them to - * a tag list before. + * a tag list. */ - if (tags && tags->hdr.tag != ATAG_CORE) - convert_to_tag_list((struct param_struct *)tags, - meminfo.nr_banks == 0); + if (tags->hdr.tag != ATAG_CORE) + convert_to_tag_list(tags); - if (tags && tags->hdr.tag == ATAG_CORE) + if (tags->hdr.tag == ATAG_CORE) { + if (meminfo.nr_banks != 0) + squash_mem_tags(tags); parse_tags(tags); + } if (meminfo.nr_banks == 0) { meminfo.nr_banks = 1; @@ -537,9 +572,8 @@ { int i; - seq_printf(m, "Processor\t: %s %s rev %d (%s)\n", - proc_info.manufacturer, proc_info.cpu_name, - (int)processor_id & 15, elf_platform); + seq_printf(m, "Processor\t: %s rev %d (%s)\n", + cpu_name, (int)processor_id & 15, elf_platform); seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000/HZ), @@ -578,8 +612,8 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: c_show + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show }; diff -urN linux-2.4.21/arch/arm/kernel/signal.c linux-2.4.22/arch/arm/kernel/signal.c --- linux-2.4.21/arch/arm/kernel/signal.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/signal.c 2003-08-25 04:44:39.000000000 -0700 @@ -405,7 +405,7 @@ regs->ARM_r0 = usig; regs->ARM_sp = (unsigned long)frame; regs->ARM_lr = retcode; - regs->ARM_pc = handler & (thumb ? ~1 : ~3); + regs->ARM_pc = handler; #ifdef CONFIG_CPU_32 regs->ARM_cpsr = cpsr; @@ -466,8 +466,8 @@ * arguments for the signal handler. * -- Peter Maydell 2000-12-06 */ - regs->ARM_r1 = (unsigned long)frame->pinfo; - regs->ARM_r2 = (unsigned long)frame->puc; + regs->ARM_r1 = (unsigned long)&frame->info; + regs->ARM_r2 = (unsigned long)&frame->uc; } return err; @@ -613,7 +613,7 @@ continue; switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: + case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: continue; case SIGTSTP: case SIGTTIN: case SIGTTOU: @@ -621,13 +621,17 @@ continue; /* FALLTHRU */ - case SIGSTOP: + case SIGSTOP: { + struct signal_struct *sig; current->state = TASK_STOPPED; current->exit_code = signr; - if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) + sig = current->p_pptr->sig; + if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); schedule(); + single_stepping |= ptrace_cancel_bpt(current); continue; + } case SIGQUIT: case SIGILL: case SIGTRAP: case SIGABRT: case SIGFPE: case SIGSEGV: diff -urN linux-2.4.21/arch/arm/kernel/time.c linux-2.4.22/arch/arm/kernel/time.c --- linux-2.4.21/arch/arm/kernel/time.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -203,6 +203,7 @@ static struct irqaction timer_irq = { .name = "timer", + .flags = SA_INTERRUPT, }; /* diff -urN linux-2.4.21/arch/arm/kernel/traps.c linux-2.4.22/arch/arm/kernel/traps.c --- linux-2.4.21/arch/arm/kernel/traps.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/kernel/traps.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/arm/kernel/traps.c * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995-2002 Russell King * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds * * This program is free software; you can redistribute it and/or modify @@ -63,8 +63,17 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) { unsigned long p = bottom & ~31; + mm_segment_t fs; int i; + /* + * We need to switch to kernel mode so that we can use __get_user + * to safely read from kernel space. Note that we now dump the + * code first, just in case the backtrace kills us. + */ + fs = get_fs(); + set_fs(KERNEL_DS); + printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); for (p = bottom & ~31; p < top;) { @@ -82,6 +91,8 @@ } printk ("\n"); } + + set_fs(fs); } static void dump_instr(struct pt_regs *regs) @@ -89,8 +100,17 @@ unsigned long addr = instruction_pointer(regs); const int thumb = thumb_mode(regs); const int width = thumb ? 4 : 8; + mm_segment_t fs; int i; + /* + * We need to switch to kernel mode so that we can use __get_user + * to safely read from kernel space. Note that we now dump the + * code first, just in case the backtrace kills us. + */ + fs = get_fs(); + set_fs(KERNEL_DS); + printk("Code: "); for (i = -4; i < 1; i++) { unsigned int val, bad; @@ -108,29 +128,36 @@ } } printk("\n"); + + set_fs(fs); } -static void dump_stack(struct task_struct *tsk, unsigned long sp) +static void I_really_mean_dump_stack_so_dont_mess_with_me(struct task_struct *tsk, unsigned long sp) { - dump_mem("Stack: ", sp - 16, 8192+(unsigned long)tsk); + dump_mem("Stack: ", sp, 8192+(unsigned long)tsk); } static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { - unsigned int fp; + unsigned int fp = regs->ARM_fp; + char *msg = ""; int ok = 1; - printk("Backtrace: "); - fp = regs->ARM_fp; +#ifdef CONFIG_FRAME_POINTER if (!fp) { - printk("no frame pointer"); + msg = "no frame pointer"; ok = 0; } else if (verify_stack(fp)) { - printk("invalid frame pointer 0x%08x", fp); + msg = "invalid frame pointer"; ok = 0; } else if (fp < 4096+(unsigned long)tsk) - printk("frame pointer underflow"); - printk("\n"); + msg = "frame pointer underflow"; +#else + msg = "not available"; + ok = 0; +#endif + + printk("Backtrace: %s\n", msg); if (ok) c_backtrace(fp, processor_mode(regs)); @@ -143,7 +170,7 @@ void show_trace_task(struct task_struct *tsk) { if (tsk != current) { - unsigned int fp = tsk->thread.save->fp; + unsigned int fp = thread_saved_fp(&tsk->thread); c_backtrace(fp, 0x10); } } @@ -163,26 +190,13 @@ printk("Internal error: %s: %x\n", str, err); printk("CPU: %d\n", smp_processor_id()); show_regs(regs); - printk("Process %s (pid: %d, stackpage=%08lx)\n", - current->comm, current->pid, 4096+(unsigned long)tsk); + printk("Process %s (pid: %d, stack limit = 0x%p)\n", + current->comm, current->pid, tsk + 1); if (!user_mode(regs) || in_interrupt()) { - mm_segment_t fs; - - /* - * We need to switch to kernel mode so that we can - * use __get_user to safely read from kernel space. - * Note that we now dump the code first, just in case - * the backtrace kills us. - */ - fs = get_fs(); - set_fs(KERNEL_DS); - - dump_stack(tsk, (unsigned long)(regs + 1)); + I_really_mean_dump_stack_so_dont_mess_with_me(tsk, (unsigned long)(regs + 1)); dump_backtrace(regs, tsk); dump_instr(regs); - - set_fs(fs); } spin_unlock_irq(&die_lock); @@ -270,7 +284,6 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) { unsigned int vectors = vectors_base(); - mm_segment_t fs; console_verbose(); @@ -278,24 +291,14 @@ handler[reason], processor_modes[proc_mode]); /* - * We need to switch to kernel mode so that we can use __get_user - * to safely read from kernel space. Note that we now dump the - * code first, just in case the backtrace kills us. - */ - fs = get_fs(); - set_fs(KERNEL_DS); - - /* * Dump out the vectors and stub routines. Maybe a better solution * would be to dump them out only if we detect that they are corrupted. */ dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40); dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8); - set_fs(fs); - die("Oops", regs, 0); - cli(); + local_irq_disable(); panic("bad mode"); } @@ -356,20 +359,7 @@ return 0; case NR(breakpoint): /* SWI BREAK_POINT */ - /* - * The PC is always left pointing at the next - * instruction. Fix this. - */ - regs->ARM_pc -= 4; - __ptrace_cancel_bpt(current); - - info.si_signo = SIGTRAP; - info.si_errno = 0; - info.si_code = TRAP_BRKPT; - info.si_addr = (void *)instruction_pointer(regs) - - (thumb_mode(regs) ? 2 : 4); - - force_sig_info(SIGTRAP, &info, current); + ptrace_break(current, regs); return regs->ARM_r0; #ifdef CONFIG_CPU_32 @@ -522,12 +512,13 @@ void __init trap_init(void) { - extern void __trap_init(void *); + extern void __trap_init(unsigned long); + unsigned long base = vectors_base(); - __trap_init((void *)vectors_base()); - if (vectors_base() != 0) - printk(KERN_DEBUG "Relocating machine vectors to 0x%08x\n", - vectors_base()); + __trap_init(base); + if (base != 0) + printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n", + base); #ifdef CONFIG_CPU_32 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); #endif diff -urN linux-2.4.21/arch/arm/lib/Makefile linux-2.4.22/arch/arm/lib/Makefile --- linux-2.4.21/arch/arm/lib/Makefile 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -27,15 +27,16 @@ obj-l7200 := io-acorn.o obj-shark := io-shark.o obj-edb7211 := io-acorn.o +obj-riscstation := io-acorn.o floppydma.o obj-y += $(obj-$(MACHINE)) -ifeq ($(CONFIG_CPU_32v4),y) - v3 := n - v4 := y -else +ifeq ($(CONFIG_CPU_32v3),y) v3 := y v4 := n +else + v3 := n + v4 := y endif obj-y += io-readsb.o io-writesb.o @@ -51,4 +52,3 @@ csumpartialcopy.o: csumpartialcopygeneric.S csumpartialcopyuser.o: csumpartialcopygeneric.S - diff -urN linux-2.4.21/arch/arm/lib/backtrace.S linux-2.4.22/arch/arm/lib/backtrace.S --- linux-2.4.21/arch/arm/lib/backtrace.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/backtrace.S 2003-08-25 04:44:39.000000000 -0700 @@ -52,25 +52,32 @@ 3: tst frame, mask @ Check for address exceptions... bne 1b -1001: ldmda frame, {r0, r1, r2, r3} @ fp, sp, lr, pc - mov next, r0 - +1001: ldr next, [frame, #-12] @ get fp +1002: ldr r2, [frame, #-4] @ get lr +1003: ldr r3, [frame, #0] @ get pc sub save, r3, offset @ Correct PC for prefetching bic save, save, mask +1004: ldr r1, [save, #0] @ get instruction at function + mov r1, r1, lsr #10 + ldr r3, .Ldsi+4 + teq r1, r3 + subeq save, save, #4 adr r0, .Lfe mov r1, save bic r2, r2, mask - bl SYMBOL_NAME(printk) @ print pc and link register + bl printk @ print pc and link register - sub r0, frame, #16 -1002: ldr r1, [save, #4] @ get instruction at function+4 + ldr r0, [frame, #-8] @ get sp + sub r0, r0, #4 +1005: ldr r1, [save, #4] @ get instruction at function+4 mov r3, r1, lsr #10 ldr r2, .Ldsi+4 teq r3, r2 @ Check for stmia sp!, {args} addeq save, save, #4 @ next instruction bleq .Ldumpstm -1003: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction + sub r0, frame, #16 +1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction mov r3, r1, lsr #10 ldr r2, .Ldsi teq r3, r2 @@ -87,18 +94,21 @@ */ .section .fixup,"ax" .align 0 -1004: ldr r0, =.Lbad +1007: ldr r0, =.Lbad mov r1, frame - bl SYMBOL_NAME(printk) + bl printk LOADREGS(fd, sp!, {r4 - r8, pc}) .ltorg .previous .section __ex_table,"a" .align 3 - .long 1001b, 1004b - .long 1002b, 1004b - .long 1003b, 1004b + .long 1001b, 1007b + .long 1002b, 1007b + .long 1003b, 1007b + .long 1004b, 1007b + .long 1005b, 1007b + .long 1006b, 1007b .previous #define instr r4 @@ -121,12 +131,12 @@ ldr r2, [stack], #-4 mov r1, reg adr r0, .Lfp - bl SYMBOL_NAME(printk) + bl printk 2: subs reg, reg, #1 bpl 1b teq r7, #0 adrne r0, .Lcr - blne SYMBOL_NAME(printk) + blne printk mov r0, stack LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) diff -urN linux-2.4.21/arch/arm/lib/csumpartial.S linux-2.4.22/arch/arm/lib/csumpartial.S --- linux-2.4.21/arch/arm/lib/csumpartial.S 2001-05-16 15:25:16.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/csumpartial.S 2003-08-25 04:44:39.000000000 -0700 @@ -49,8 +49,9 @@ /* we are now half-word aligned */ .less8_wordlp: -#ifdef __ARM_ARCH_4__ - ldrh td0, [buf], #2 +#if __LINUX_ARM_ARCH__ >= 4 + ldrh td0, [buf] + add buf, buf, #2 sub len, len, #2 #else ldrb td0, [buf], #1 @@ -79,8 +80,9 @@ adcnes sum, sum, td0, lsl #8 @ update checksum tst buf, #2 @ 32-bit aligned? -#ifdef __ARM_ARCH_4__ - ldrneh td0, [buf], #2 @ make 32-bit aligned +#if __LINUX_ARM_ARCH__ >= 4 + ldrneh td0, [buf] @ make 32-bit aligned + add buf, buf, #2 subne len, len, #2 #else ldrneb td0, [buf], #1 diff -urN linux-2.4.21/arch/arm/lib/delay.S linux-2.4.22/arch/arm/lib/delay.S --- linux-2.4.21/arch/arm/lib/delay.S 2001-04-12 12:20:31.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/delay.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/arm/lib/delay.S * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995-2003 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,45 +9,52 @@ */ #include #include - .text +#include -LC0: .word SYMBOL_NAME(loops_per_jiffy) + .text /* - * 0 <= r0 <= 2000 + * See linux/include/asm-arm/delay.h for a description of the maths. */ -ENTRY(udelay) - mov r2, #0x6800 - orr r2, r2, #0x00db + +#if NDELAY_FACTOR > 255 +#error NDELAY_FACTOR out of range +#endif +#if UDELAY_FACTOR > 65535 +#error UDELAY_FACTOR out of range +#endif + +LC0: .word SYMBOL_NAME(loops_per_jiffy) + +ENTRY(__const_delay) + ldr r3, LC0 + mov r1, r0, lsr #11 + ldr r2, [r3, #0] + b 2f + +ENTRY(__ndelay) + mov r2, #NDELAY_FACTOR + b 1f + +ENTRY(__udelay) + mov r2, #UDELAY_FACTOR & 0xff00 + orr r2, r2, #UDELAY_FACTOR & 0x00ff +1: ldr r3, LC0 mul r1, r0, r2 - ldr r2, LC0 - ldr r2, [r2] + ldr r2, [r3, #0] mov r1, r1, lsr #11 - mov r2, r2, lsr #11 +2: mov r2, r2, lsr #12 mul r0, r1, r2 - movs r0, r0, lsr #6 + movs r0, r0, lsr #5 RETINSTR(moveq,pc,lr) /* - * loops = (r0 * 0x10c6 * 100 * loops_per_jiffie) / 2^32 + * loops = (r0 * 0x10c6 * HZ * loops_per_jiffy) / 2^32 + * + * Oh, if only we had a cycle counter... */ -@ Delay routine ENTRY(__delay) subs r0, r0, #1 - RETINSTR(movcc,pc,lr) - subs r0, r0, #1 - RETINSTR(movcc,pc,lr) - subs r0, r0, #1 - RETINSTR(movcc,pc,lr) - subs r0, r0, #1 - RETINSTR(movcc,pc,lr) - subs r0, r0, #1 - RETINSTR(movcc,pc,lr) - subs r0, r0, #1 - RETINSTR(movcc,pc,lr) - subs r0, r0, #1 - RETINSTR(movcc,pc,lr) - subs r0, r0, #1 bcs SYMBOL_NAME(__delay) RETINSTR(mov,pc,lr) diff -urN linux-2.4.21/arch/arm/lib/longlong.h linux-2.4.22/arch/arm/lib/longlong.h --- linux-2.4.21/arch/arm/lib/longlong.h 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/longlong.h 2003-08-25 04:44:39.000000000 -0700 @@ -75,7 +75,7 @@ #if defined (__arm__) #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("adds %1, %4, %5 + __asm__ ("adds %1, %4, %5 \n\ adc %0, %2, %3" \ : "=r" ((USItype) (sh)), \ "=&r" ((USItype) (sl)) \ @@ -84,7 +84,7 @@ "%r" ((USItype) (al)), \ "rI" ((USItype) (bl))) #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subs %1, %4, %5 + __asm__ ("subs %1, %4, %5 \n\ sbc %0, %2, %3" \ : "=r" ((USItype) (sh)), \ "=&r" ((USItype) (sl)) \ @@ -94,18 +94,18 @@ "rI" ((USItype) (bl))) #define umul_ppmm(xh, xl, a, b) \ {register USItype __t0, __t1, __t2; \ - __asm__ ("%@ Inlined umul_ppmm - mov %2, %5, lsr #16 - mov %0, %6, lsr #16 - bic %3, %5, %2, lsl #16 - bic %4, %6, %0, lsl #16 - mul %1, %3, %4 - mul %4, %2, %4 - mul %3, %0, %3 - mul %0, %2, %0 - adds %3, %4, %3 - addcs %0, %0, #65536 - adds %1, %1, %3, lsl #16 + __asm__ ("%@ Inlined umul_ppmm \n\ + mov %2, %5, lsr #16 \n\ + mov %0, %6, lsr #16 \n\ + bic %3, %5, %2, lsl #16 \n\ + bic %4, %6, %0, lsl #16 \n\ + mul %1, %3, %4 \n\ + mul %4, %2, %4 \n\ + mul %3, %0, %3 \n\ + mul %0, %2, %0 \n\ + adds %3, %4, %3 \n\ + addcs %0, %0, #65536 \n\ + adds %1, %1, %3, lsl #16 \n\ adc %0, %0, %3, lsr #16" \ : "=&r" ((USItype) (xh)), \ "=r" ((USItype) (xl)), \ diff -urN linux-2.4.21/arch/arm/lib/memchr.S linux-2.4.22/arch/arm/lib/memchr.S --- linux-2.4.21/arch/arm/lib/memchr.S 2000-09-18 15:15:25.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/memchr.S 2003-08-25 04:44:39.000000000 -0700 @@ -15,11 +15,11 @@ .text .align 5 ENTRY(memchr) -1: ldrb r3, [r0], #1 +1: subs r2, r2, #1 + bmi 2f + ldrb r3, [r0], #1 teq r3, r1 - beq 2f - subs r2, r2, #1 - bpl 1b + bne 1b + sub r0, r0, #1 2: movne r0, #0 - subeq r0, r0, #1 RETINSTR(mov,pc,lr) diff -urN linux-2.4.21/arch/arm/lib/muldi3.c linux-2.4.22/arch/arm/lib/muldi3.c --- linux-2.4.21/arch/arm/lib/muldi3.c 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/muldi3.c 2003-08-25 04:44:39.000000000 -0700 @@ -33,18 +33,18 @@ #define umul_ppmm(xh, xl, a, b) \ {register USItype __t0, __t1, __t2; \ - __asm__ ("%@ Inlined umul_ppmm - mov %2, %5, lsr #16 - mov %0, %6, lsr #16 - bic %3, %5, %2, lsl #16 - bic %4, %6, %0, lsl #16 - mul %1, %3, %4 - mul %4, %2, %4 - mul %3, %0, %3 - mul %0, %2, %0 - adds %3, %4, %3 - addcs %0, %0, #65536 - adds %1, %1, %3, lsl #16 + __asm__ ("%@ Inlined umul_ppmm \n\ + mov %2, %5, lsr #16 \n\ + mov %0, %6, lsr #16 \n\ + bic %3, %5, %2, lsl #16 \n\ + bic %4, %6, %0, lsl #16 \n\ + mul %1, %3, %4 \n\ + mul %4, %2, %4 \n\ + mul %3, %0, %3 \n\ + mul %0, %2, %0 \n\ + adds %3, %4, %3 \n\ + addcs %0, %0, #65536 \n\ + adds %1, %1, %3, lsl #16 \n\ adc %0, %0, %3, lsr #16" \ : "=&r" ((USItype) (xh)), \ "=r" ((USItype) (xl)), \ diff -urN linux-2.4.21/arch/arm/lib/strchr.S linux-2.4.22/arch/arm/lib/strchr.S --- linux-2.4.21/arch/arm/lib/strchr.S 2000-09-18 15:15:25.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/strchr.S 2003-08-25 04:44:39.000000000 -0700 @@ -15,11 +15,12 @@ .text .align 5 ENTRY(strchr) + and r1, r1, #0xff 1: ldrb r2, [r0], #1 teq r2, r1 teqne r2, #0 bne 1b - teq r2, #0 - moveq r0, #0 - subne r0, r0, #1 + teq r2, r1 + movne r0, #0 + subeq r0, r0, #1 RETINSTR(mov,pc,lr) diff -urN linux-2.4.21/arch/arm/lib/udivdi3.c linux-2.4.22/arch/arm/lib/udivdi3.c --- linux-2.4.21/arch/arm/lib/udivdi3.c 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/lib/udivdi3.c 2003-08-25 04:44:39.000000000 -0700 @@ -229,3 +229,14 @@ { return __udivmoddi4 (n, d, (UDItype *) 0); } + +UDItype +__umoddi3 (UDItype u, UDItype v) +{ + UDItype w; + + (void) __udivmoddi4 (u ,v, &w); + + return w; +} + diff -urN linux-2.4.21/arch/arm/mach-anakin/irq.c linux-2.4.22/arch/arm/mach-anakin/irq.c --- linux-2.4.21/arch/arm/mach-anakin/irq.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-anakin/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/mach-at91rm9200/Makefile linux-2.4.22/arch/arm/mach-at91rm9200/Makefile --- linux-2.4.21/arch/arm/mach-at91rm9200/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-at91rm9200/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,21 @@ +# +# Makefile for the linux kernel. +# +# 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). + +USE_STANDARD_AS_RULE := true + +O_TARGET := at91rm9200.o + +# Object file lists. + +obj-y := core.o +obj-m := +obj-n := +obj- := + +export-objs := + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/arm/mach-at91rm9200/core.c linux-2.4.22/arch/arm/mach-at91rm9200/core.c --- linux-2.4.21/arch/arm/mach-at91rm9200/core.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-at91rm9200/core.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,183 @@ +/* + * linux/arch/arm/mach-at91rm9200/core.c + * + * Copyright (c) 2003 SAN People + * Copyright (c) 2003 ATMEL + * Copyright (c) Rick Bronson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* + * System peripheral registers mapped at virtual address. + */ +AT91PS_SYS AT91_SYS = (AT91PS_SYS) AT91C_VA_BASE_SYS; + +static struct map_desc at91rm9200_io_desc[] __initdata = { + /* virtual, physical, length, domain, r, w, c, b */ + { AT91C_VA_BASE_SYS, AT91C_BASE_SYS, SZ_4K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_SPI, AT91C_BASE_SPI, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_SSC2, AT91C_BASE_SSC2, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_SSC1, AT91C_BASE_SSC1, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_SSC0, AT91C_BASE_SSC0, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_US3, AT91C_BASE_US3, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_US2, AT91C_BASE_US2, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_US1, AT91C_BASE_US1, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_US0, AT91C_BASE_US0, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_EMAC, AT91C_BASE_EMAC, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_TWI, AT91C_BASE_TWI, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_MCI, AT91C_BASE_MCI, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_UDP, AT91C_BASE_UDP, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_TCB1, AT91C_BASE_TCB1, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + { AT91C_VA_BASE_TCB0, AT91C_BASE_TCB0, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, + LAST_DESC +}; + +/* Interrupt configuration */ +static AT91_REG at91rm9200_irq_smr[] __initdata = { + (AT91_SMR_FIQ), /* FIQ */ + (AT91_SMR_SYS), /* System Peripherals */ + (AT91_SMR_PIOA), /* PIO A */ + (AT91_SMR_PIOB), /* PIO B */ + (AT91_SMR_PIOC), /* PIO C */ + (AT91_SMR_PIOD), /* PIO D */ + (AT91_SMR_US0), /* USART 0 */ + (AT91_SMR_US1), /* USART 1 */ + (AT91_SMR_US2), /* USART 2 */ + (AT91_SMR_US3), /* USART 3 */ + (AT91_SMR_MCI), /* Multimedia Card */ + (AT91_SMR_UDP), /* USB Device */ + (AT91_SMR_TWI), /* Two-wire interface */ + (AT91_SMR_SPI), /* SPI */ + (AT91_SMR_SSC0), /* Sync Serial 0 */ + (AT91_SMR_SSC1), /* Sync Serial 1 */ + (AT91_SMR_SSC2), /* Sync Serial 2 */ + (AT91_SMR_TC0), /* TC 0 */ + (AT91_SMR_TC1), /* TC 1 */ + (AT91_SMR_TC2), /* TC 2 */ + (AT91_SMR_TC3), /* TC 3 */ + (AT91_SMR_TC4), /* TC 4 */ + (AT91_SMR_TC5), /* TC 5 */ + (AT91_SMR_UHP), /* USB Host */ + (AT91_SMR_EMAC), /* Ethernet */ + (AT91_SMR_IRQ0), /* IRQ 0 */ + (AT91_SMR_IRQ1), /* IRQ 1 */ + (AT91_SMR_IRQ2), /* IRQ 2 */ + (AT91_SMR_IRQ3), /* IRQ 3 */ + (AT91_SMR_IRQ4), /* IRQ 4 */ + (AT91_SMR_IRQ5), /* IRQ 5 */ + (AT91_SMR_IRQ6) /* IRQ 6 */ +}; + +/* Architecture-specific fixups */ +static void __init at91rm9200_fixup(struct machine_desc *desc, struct param_struct *unused, + char **cmdline, struct meminfo *mi) +{ +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE); +// setup_initrd(0xc0100000, 3*1024*1024); +#endif +} + +extern void at91_register_uart(int idx, int port); + +void __init at91rm9200_map_io(void) +{ + int serial[AT91C_NR_UART] = AT91C_UART_MAP; + int i; + + iotable_init(at91rm9200_io_desc); + + /* Register UARTs */ + for (i = 0; i < AT91C_NR_UART; i++) { + if (serial[i] >= 0) + at91_register_uart(i, serial[i]); + } +} + +static void at91rm9200_mask_irq(unsigned int irq) +{ + /* Disable interrupt on AIC */ + AT91_SYS->AIC_IDCR = 1 << irq; +} + +static void at91rm9200_unmask_irq(unsigned int irq) +{ + /* Enable interrupt on AIC */ + AT91_SYS->AIC_IECR = 1 << irq; +} + +void __init at91rm9200_init_irq(void) +{ + unsigned int i; + + /* + * The IVR is used by macro get_irqnr_and_base to read and verify. + * The irq number is NR_IRQS when a spurious interrupt has occured. + */ + for (i = 0; i < NR_IRQS; i++) { + /* Put irq number in Source Vector Register: */ + AT91_SYS->AIC_SVR[i] = i; + /* Store the Source Mode Register as defined in table above */ + AT91_SYS->AIC_SMR[i] = at91rm9200_irq_smr[i]; + + irq_desc[i].valid = 1; + irq_desc[i].mask_ack = at91rm9200_mask_irq; + irq_desc[i].mask = at91rm9200_mask_irq; + irq_desc[i].unmask = at91rm9200_unmask_irq; + + /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ + if (i < 8) + AT91_SYS->AIC_EOICR = AT91_SYS->AIC_EOICR; + } + + /* Spurious Interrupt ID in Spurious Vector Register is NR_IRQS + * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU + */ + AT91_SYS->AIC_SPU = NR_IRQS; + + /* No debugging in AIC: Debug (Protect) Control Register */ + AT91_SYS->AIC_DCR = 0; + + /* Disable and clear all interrupts initially */ + AT91_SYS->AIC_IDCR = 0xFFFFFFFF; + AT91_SYS->AIC_ICCR = 0xFFFFFFFF; +} + +MACHINE_START(AT91RM9200, "ATMEL AT91RM9200") + MAINTAINER("SAN People / ATMEL") + BOOT_MEM(AT91_SDRAM_BASE, AT91C_BASE_SYS, AT91C_VA_BASE_SYS) + BOOT_PARAMS(AT91_SDRAM_BASE + 0x100) + FIXUP(at91rm9200_fixup) + MAPIO(at91rm9200_map_io) + INITIRQ(at91rm9200_init_irq) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-clps711x/Makefile linux-2.4.22/arch/arm/mach-clps711x/Makefile --- linux-2.4.21/arch/arm/mach-clps711x/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-clps711x/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -16,12 +16,13 @@ obj-n := obj- := -export-objs := leds-p720t.o +export-objs := p720t-leds.o obj-$(CONFIG_ARCH_AUTCPU12) += autcpu12.o obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o +obj-$(CONFIG_ARCH_GUIDEA07) += guide-a07.o obj-$(CONFIG_ARCH_P720T) += p720t.o obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o leds-$(CONFIG_ARCH_P720T) += p720t-leds.o diff -urN linux-2.4.21/arch/arm/mach-clps711x/fortunet.c linux-2.4.22/arch/arm/mach-clps711x/fortunet.c --- linux-2.4.21/arch/arm/mach-clps711x/fortunet.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-clps711x/fortunet.c 2003-08-25 04:44:39.000000000 -0700 @@ -31,6 +31,10 @@ #include #include +#include +#include +#include + #include #include @@ -48,9 +52,11 @@ int extra_param_type; int extra_param_ptr; int command_line; + int extra_ram_start; + int extra_ram_size; } IMAGE_PARAMS; -#define IMAGE_PARAMS_PHYS 0xC01F0000 +#define IMAGE_PARAMS_PHYS 0xC0200000 static void __init fortunet_fixup(struct machine_desc *desc, struct param_struct *params, @@ -67,14 +73,23 @@ } #endif memmap.bank[0].size = ip->ram_size; + memmap.bank[0].node = PHYS_TO_NID(0xC0000000); + if(ip->extra_ram_size) + { + memmap.bank[1].start = ip->extra_ram_start; + memmap.bank[1].size = ip->extra_ram_size; + memmap.bank[1].node = PHYS_TO_NID(ip->extra_ram_start); + mi->nr_banks=2; + } memmap.end = ip->ram_size+0xC0000000; *mi = memmap; } MACHINE_START(FORTUNET, "ARM-FortuNet") MAINTAINER("FortuNet Inc.") - BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000) + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) BOOT_PARAMS(0x00000000) + VIDEO(0xC0000000,0xC00020000) FIXUP(fortunet_fixup) MAPIO(clps711x_map_io) INITIRQ(clps711x_init_irq) diff -urN linux-2.4.21/arch/arm/mach-clps711x/guide-a07.c linux-2.4.22/arch/arm/mach-clps711x/guide-a07.c --- linux-2.4.21/arch/arm/mach-clps711x/guide-a07.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-clps711x/guide-a07.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,92 @@ +/* + * linux/arch/arm/mach-clps711x/guide-a07.c + * + * Copyright (C) 2003 Iders Incorporated + * Copyright (C) 2000-2001 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern void clps711x_init_irq(void); +extern void clps711x_map_io(void); + +#ifndef CONFIG_I2C_GUIDE +#error Config error - The Guide A07 requires I2C Guide GPIO support. Please enable it. +#endif + +/* + * Map the CS89712 Ethernet port. That should be moved to the + * ethernet driver, perhaps. + * also map the Guide FPGA and persistance locations + */ +static struct map_desc guide_a07_io_desc[] __initdata = { + { ETHER_BASE, ETHER_START, ETHER_SIZE, + DOMAIN_IO, 0, 1, 0, 0 }, + { GD_A07_FPGA_BASE, GD_A07_FPGA_START, GD_A07_FPGA_SIZE, + DOMAIN_IO, 0, 1, 0, 0 }, + { GD_A07_PERSISTANCE_BASE, GD_A07_PERSISTANCE_START, GD_A07_PERSISTANCE_SIZE, + DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC +}; + +static void __init +fixup_guide_a07(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ +} + +static void __init guide_a07_map_io(void) +{ + clps711x_map_io(); + iotable_init(guide_a07_io_desc); +} + +MACHINE_START(GUIDEA07, "Guide A07 (cs89712 core)") + MAINTAINER("Cam Mayor") + VIDEO(0x60000000, 0x6000bfff) + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_guide_a07) + MAPIO(guide_a07_map_io) + INITIRQ(clps711x_init_irq) +MACHINE_END + +static int guide_a07_hw_init(void) +{ + /* in cs[1] (the FPGA), set zero wait states, clkenb, and sqaen */ + u32 memcfg1 = 0xfc << 8; + memcfg1 |= clps_readl(MEMCFG1); + clps_writel(memcfg1, MEMCFG1); + + return 0; +} + +__initcall(guide_a07_hw_init); + diff -urN linux-2.4.21/arch/arm/mach-clps711x/irq.c linux-2.4.22/arch/arm/mach-clps711x/irq.c --- linux-2.4.21/arch/arm/mach-clps711x/irq.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-clps711x/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -18,6 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/mach-ebsa110/irq.c linux-2.4.22/arch/arm/mach-ebsa110/irq.c --- linux-2.4.21/arch/arm/mach-ebsa110/irq.c 2001-04-12 12:20:31.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-ebsa110/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -11,6 +11,9 @@ * 22-08-1998 RMK Restructured IRQ routines */ #include +#include +#include +#include #include #include @@ -35,14 +38,14 @@ unsigned long flags; int irq; - save_flags_cli (flags); + local_irq_save(flags); __raw_writeb(0xff, IRQ_MCLR); __raw_writeb(0x55, IRQ_MSET); __raw_writeb(0x00, IRQ_MSET); if (__raw_readb(IRQ_MASK) != 0x55) while (1); __raw_writeb(0xff, IRQ_MCLR); /* clear all interrupt enables */ - restore_flags (flags); + local_irq_restore(flags); for (irq = 0; irq < NR_IRQS; irq++) { irq_desc[irq].valid = 1; diff -urN linux-2.4.21/arch/arm/mach-epxa/Makefile linux-2.4.22/arch/arm/mach-epxa/Makefile --- linux-2.4.21/arch/arm/mach-epxa/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,24 @@ +# +# Makefile for the linux kernel. +# +# 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). + +USE_STANDARD_AS_RULE := true + +O_TARGET := epxa.o + +# Object file lists. + +obj-y := irq.o mm.o time.o +obj-m := +obj-n := +obj- := + +export-objs := + +obj-$(CONFIG_EPXA1DB) += arch-epxa1db.o +obj-$(CONFIG_EPXA10DB) += arch-epxa10db.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/arm/mach-epxa/arch-epxa10db.c linux-2.4.22/arch/arm/mach-epxa/arch-epxa10db.c --- linux-2.4.21/arch/arm/mach-epxa/arch-epxa10db.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa/arch-epxa10db.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,60 @@ +/* + * linux/arch/arm/mach-epxa/arch-epxa10db.c + * + * Copyright (C) 2001 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void epxa_map_io(void); +extern void epxa_init_irq(void); + + +static void __init +epxa10db_fixup(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + + mi->nr_banks = 1; + mi->bank[0].start = 0; + mi->bank[0].size = (128*1024*1024); + mi->bank[0].node = 0; + +/* + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd(0xc0200000, 6*1024*1024); +*/ +} + +MACHINE_START(CAMELOT, "Altera Epxa10db") + MAINTAINER("Altera Corporation") + BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) + FIXUP(epxa10db_fixup) + MAPIO(epxa_map_io) + INITIRQ(epxa_init_irq) + BOOT_PARAMS(0x100) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-epxa/arch-epxa1db.c linux-2.4.22/arch/arm/mach-epxa/arch-epxa1db.c --- linux-2.4.21/arch/arm/mach-epxa/arch-epxa1db.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa/arch-epxa1db.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,59 @@ +/* + * linux/arch/arm/mach-epxa/arch-epxa10db.c + * + * Copyright (C) 2001 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void epxa_map_io(void); +extern void epxa_init_irq(void); + +static void __init +epxa1db_fixup(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + + mi->nr_banks = 1; + mi->bank[0].start = 0; + mi->bank[0].size = (32*1024*1024); + mi->bank[0].node = 0; + +/* + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd(0xc0200000, 6*1024*1024); +*/ +} + +MACHINE_START(CAMELOT, "Altera Epxa1db") + MAINTAINER("Altera Corporation") + BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) + FIXUP(epxa1db_fixup) + MAPIO(epxa_map_io) + INITIRQ(epxa_init_irq) + BOOT_PARAMS(0x100) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-epxa/dma.c linux-2.4.22/arch/arm/mach-epxa/dma.c --- linux-2.4.21/arch/arm/mach-epxa/dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa/dma.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/mach-epxa10db/dma.c + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +void __init arch_dma_init(dma_t *dma) +{ +} diff -urN linux-2.4.21/arch/arm/mach-epxa/irq.c linux-2.4.22/arch/arm/mach-epxa/irq.c --- linux-2.4.21/arch/arm/mach-epxa/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,74 @@ +/* + * linux/arch/arm/mach-epxa10db/irq.c + * + * Copyright (C) 2001 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +static void mask_irq(unsigned int irq) +{ + __raw_writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); +} + +static void unmask_irq(unsigned int irq) +{ + __raw_writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE))); +} + +void __init epxa_init_irq(void) +{ + unsigned int i; + + /* + * This bit sets up the interrupt controller using + * the 6 PLD interrupts mode (the default) each + * irqs is assigned a priority which is the same + * as its interrupt number. This scheme is used because + * its easy, but you may want to change it depending + * on the contents of your PLD + */ + + __raw_writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE))); + for (i = 0; i < NR_IRQS; i++){ + __raw_writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i)); + } + + + for (i = 0; i < NR_IRQS; i++) { + + irq_desc[i].valid = 1; + irq_desc[i].probe_ok = 1; + irq_desc[i].mask_ack = mask_irq; + irq_desc[i].mask = mask_irq; + irq_desc[i].unmask = unmask_irq; + } + + /* Disable all interrupt */ + __raw_writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); + +} diff -urN linux-2.4.21/arch/arm/mach-epxa/mm.c linux-2.4.22/arch/arm/mach-epxa/mm.c --- linux-2.4.21/arch/arm/mach-epxa/mm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa/mm.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,43 @@ +/* + * linux/arch/arm/mach-epxa10db/mm.c + * + * MM routines for Altera'a Epxa10db board + * + * Copyright (C) 2001 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* Page table mapping for I/O region */ + +static struct map_desc epxa_io_desc[] __initdata = { + { IO_ADDRESS(EXC_REGISTERS_BASE), EXC_REGISTERS_BASE, SZ_4K , DOMAIN_IO, 0, 1}, LAST_DESC +}; + +void __init epxa_map_io(void) +{ + iotable_init(epxa_io_desc); +} diff -urN linux-2.4.21/arch/arm/mach-epxa/time.c linux-2.4.22/arch/arm/mach-epxa/time.c --- linux-2.4.21/arch/arm/mach-epxa/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,33 @@ +/* + * linux/arch/arm/mach-epxa10db/time.c + * + * Copyright (C) 2000 Deep Blue Solutions + * Copyright (C) 2001 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include + +#include + + + +extern int (*set_rtc)(void); + +static int epxa10db_set_rtc(void) +{ + return 1; +} + +static int epxa10db_rtc_init(void) +{ + set_rtc = epxa10db_set_rtc; + + return 0; +} + +__initcall(epxa10db_rtc_init); diff -urN linux-2.4.21/arch/arm/mach-epxa10db/Makefile linux-2.4.22/arch/arm/mach-epxa10db/Makefile --- linux-2.4.21/arch/arm/mach-epxa10db/Makefile 2001-10-25 13:53:45.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-epxa10db/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,22 +0,0 @@ -# -# Makefile for the linux kernel. -# -# 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). - -USE_STANDARD_AS_RULE := true - -O_TARGET := epxa10db.o - -# Object file lists. - -obj-y := arch.o irq.o mm.o time.o -obj-m := -obj-n := -obj- := - -export-objs := - - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/arm/mach-epxa10db/arch.c linux-2.4.22/arch/arm/mach-epxa10db/arch.c --- linux-2.4.21/arch/arm/mach-epxa10db/arch.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-epxa10db/arch.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,61 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/arch.c - * - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright (C) 2001 Altera Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -extern void epxa10db_map_io(void); -extern void epxa10db_init_irq(void); - - -static void __init -epxa10db_fixup(struct machine_desc *desc, struct param_struct *params, - char **cmdline, struct meminfo *mi) -{ - - mi->nr_banks = 1; - mi->bank[0].start = 0; - mi->bank[0].size = (32*1024*1024); - mi->bank[0].node = 0; - -/* - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd(0xc0200000, 6*1024*1024); -*/ -} - -MACHINE_START(CAMELOT, "Altera Epxa10db") - MAINTAINER("Altera Corporation") - BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) - FIXUP(epxa10db_fixup) - MAPIO(epxa10db_map_io) - INITIRQ(epxa10db_init_irq) - -MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-epxa10db/dma.c linux-2.4.22/arch/arm/mach-epxa10db/dma.c --- linux-2.4.21/arch/arm/mach-epxa10db/dma.c 2001-11-22 10:41:14.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-epxa10db/dma.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,36 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/dma.c - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -void __init arch_dma_init(dma_t *dma) -{ -} diff -urN linux-2.4.21/arch/arm/mach-epxa10db/irq.c linux-2.4.22/arch/arm/mach-epxa10db/irq.c --- linux-2.4.21/arch/arm/mach-epxa10db/irq.c 2001-10-25 13:53:45.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-epxa10db/irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,70 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/irq.c - * - * Copyright (C) 2001 Altera Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include - - -static void mask_irq(unsigned int irq) -{ - __raw_writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); -} - -static void unmask_irq(unsigned int irq) -{ - __raw_writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE))); -} - -void __init epxa10db_init_irq(void) -{ - unsigned int i; - - /* - * This bit sets up the interrupt controller using - * the 6 PLD interrupts mode (the default) each - * irqs is assigned a priority which is the same - * as its interrupt number. This scheme is used because - * its easy, but you may want to change it depending - * on the contents of your PLD - */ - - __raw_writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE))); - for (i = 0; i < NR_IRQS; i++){ - __raw_writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i)); - } - - - for (i = 0; i < NR_IRQS; i++) { - - irq_desc[i].valid = 1; - irq_desc[i].probe_ok = 1; - irq_desc[i].mask_ack = mask_irq; - irq_desc[i].mask = mask_irq; - irq_desc[i].unmask = unmask_irq; - } - - /* Disable all interrupt */ - __raw_writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); - -} diff -urN linux-2.4.21/arch/arm/mach-epxa10db/mm.c linux-2.4.22/arch/arm/mach-epxa10db/mm.c --- linux-2.4.21/arch/arm/mach-epxa10db/mm.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-epxa10db/mm.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,49 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/mm.c - * - * MM routines for Altera'a Epxa10db board - * - * Copyright (C) 2001 Altera Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -/* Page table mapping for I/O region */ - -static struct map_desc epxa10db_io_desc[] __initdata = { - { IO_ADDRESS(EXC_REGISTERS_BASE), EXC_REGISTERS_BASE, SZ_16K , DOMAIN_IO, 0, 1}, -{IO_ADDRESS(EXC_PLD_BLOCK0_BASE), EXC_PLD_BLOCK0_BASE, SZ_16K , DOMAIN_IO, 0, 1}, -{IO_ADDRESS(EXC_PLD_BLOCK1_BASE), EXC_PLD_BLOCK1_BASE, SZ_16K , DOMAIN_IO, 0, 1}, -{IO_ADDRESS(EXC_PLD_BLOCK2_BASE), EXC_PLD_BLOCK2_BASE, SZ_16K , DOMAIN_IO, 0, 1}, -{IO_ADDRESS(EXC_PLD_BLOCK3_BASE), EXC_PLD_BLOCK3_BASE, SZ_16K , DOMAIN_IO, 0, 1}, -{ FLASH_VADDR(EXC_EBI_BLOCK0_BASE), EXC_EBI_BLOCK0_BASE, SZ_16M , DOMAIN_IO, 0, 1}, - LAST_DESC -}; - -void __init epxa10db_map_io(void) -{ - iotable_init(epxa10db_io_desc); -} diff -urN linux-2.4.21/arch/arm/mach-epxa10db/time.c linux-2.4.22/arch/arm/mach-epxa10db/time.c --- linux-2.4.21/arch/arm/mach-epxa10db/time.c 2001-10-25 13:53:45.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-epxa10db/time.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,33 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/time.c - * - * Copyright (C) 2000 Deep Blue Solutions - * Copyright (C) 2001 Altera Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -#include - - - -extern int (*set_rtc)(void); - -static int epxa10db_set_rtc(void) -{ - return 1; -} - -static int epxa10db_rtc_init(void) -{ - set_rtc = epxa10db_set_rtc; - - return 0; -} - -__initcall(epxa10db_rtc_init); diff -urN linux-2.4.21/arch/arm/mach-footbridge/arch.c linux-2.4.22/arch/arm/mach-footbridge/arch.c --- linux-2.4.21/arch/arm/mach-footbridge/arch.c 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-footbridge/arch.c 2003-08-25 04:44:39.000000000 -0700 @@ -41,10 +41,12 @@ fixup_ebsa285(struct machine_desc *desc, struct param_struct *params, char **cmdline, struct meminfo *mi) { +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) ORIG_X = params->u1.s.video_x; ORIG_Y = params->u1.s.video_y; ORIG_VIDEO_COLS = params->u1.s.video_num_cols; ORIG_VIDEO_LINES = params->u1.s.video_num_rows; +#endif } MACHINE_START(EBSA285, "EBSA285") diff -urN linux-2.4.21/arch/arm/mach-footbridge/irq.c linux-2.4.22/arch/arm/mach-footbridge/irq.c --- linux-2.4.21/arch/arm/mach-footbridge/irq.c 2001-04-12 12:20:31.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-footbridge/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include diff -urN linux-2.4.21/arch/arm/mach-integrator/cpu.c linux-2.4.22/arch/arm/mach-integrator/cpu.c --- linux-2.4.21/arch/arm/mach-integrator/cpu.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-integrator/cpu.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ * * Copyright (C) 2001 Deep Blue Solutions Ltd. * - * $Id: cpu.c,v 1.2 2001/09/22 12:11:17 rmk Exp $ + * $Id: cpu.c,v 1.2.2.1 2002/05/30 15:08:03 db Exp $ * * 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 diff -urN linux-2.4.21/arch/arm/mach-integrator/irq.c linux-2.4.22/arch/arm/mach-integrator/irq.c --- linux-2.4.21/arch/arm/mach-integrator/irq.c 2001-03-02 18:38:39.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-integrator/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -18,6 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/mach-mx1ads/irq.c linux-2.4.22/arch/arm/mach-mx1ads/irq.c --- linux-2.4.21/arch/arm/mach-mx1ads/irq.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-mx1ads/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -19,6 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/mach-omaha/Makefile linux-2.4.22/arch/arm/mach-omaha/Makefile --- linux-2.4.21/arch/arm/mach-omaha/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-omaha/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,21 @@ +# +# Makefile for the linux kernel. +# +# 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). + +USE_STANDARD_AS_RULE := true + +O_TARGET := omaha.o + +# Object file lists. + +obj-y := core.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_LEDS) += leds.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/arm/mach-omaha/core.c linux-2.4.22/arch/arm/mach-omaha/core.c --- linux-2.4.21/arch/arm/mach-omaha/core.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-omaha/core.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,130 @@ +/* + * linux/arch/arm/mach-omaha/core.c + * + * Copyright (C) ARM Limited 2002. + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern void omaha_map_io(void); + +/* + * All IO addresses are mapped onto VA 0xExxx.xxxx, where x.xxxx + * is the (PA + 0xE0000000). + * + * Setup a VA for the Omaha interrupt controller. + */ + +#define VA_IC_BASE IO_ADDRESS(PLAT_PERIPHERAL_BASE) + +static void sc_mask_and_ack_irq(unsigned int irq) +{ + unsigned int tmp; + + // Mask this interrupt + tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK); + tmp = tmp | (1 << irq); + __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK); + + // Clear the source pending register + tmp = __raw_readl(VA_IC_BASE + OMAHA_SRCPND); + tmp = tmp | (1 << irq); + __raw_writel(tmp, VA_IC_BASE + OMAHA_SRCPND); + + // Clear the interrupt pending register + tmp = __raw_readl(VA_IC_BASE + OMAHA_INTPND); + tmp = tmp | (1 << irq); + __raw_writel(tmp, VA_IC_BASE + OMAHA_INTPND); + +} + +static void sc_mask_irq(unsigned int irq) +{ + unsigned int tmp; + + // Mask this interrupt + tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK); + tmp = tmp | (1 << irq); + __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK); +} + +static void sc_unmask_irq(unsigned int irq) +{ + unsigned int tmp; + + tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK); + tmp = tmp & ~(1 << irq); + __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK); +} + +static void __init omaha_init_irq(void) +{ + unsigned int i; + + /* bootloader disables interrupt hardware, + * so we just set up linux data structures... + */ + + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].valid = 1; + irq_desc[i].probe_ok = 1; + irq_desc[i].mask_ack = sc_mask_and_ack_irq; + irq_desc[i].mask = sc_mask_irq; + irq_desc[i].unmask = sc_unmask_irq; + } +} + +/* Notes + * + * IO space has been mapped into the top of virtual memory at 0xExxx xxxx + * See IO_ACCESS macro for details. + */ + +/* Logical Physical + * Start 0xE0000000 0x00000000 + * End 0xFAFFFFFC 0x1AFFFFFC + */ + +/* Map the bottom 2Gb of IO space into the top of memory, but leave + * space for the high vector table. + */ +static struct map_desc omaha_io_desc[] __initdata = { + { IO_ADDRESS(0x00000000), 0x00000000, 0x1B000000, DOMAIN_IO, 0, 1 }, + LAST_DESC +}; + +static void __init omaha_map_io(void) +{ diff -urN linux-2.4.21/arch/arm/mach-omaha/leds.c linux-2.4.22/arch/arm/mach-omaha/leds.c --- linux-2.4.21/arch/arm/mach-omaha/leds.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-omaha/leds.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,89 @@ +/* + * linux/arch/arm/mach-omaha/leds.c + * + * Omaha LED control routines + * + * Copyright (C) 1999-2002 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 + +static int saved_leds; + +static void omaha_leds_event(led_event_t ledevt) +{ + unsigned long flags; + unsigned int ctrl = IO_ADDRESS(PLAT_DBG_LEDS); + unsigned int leds; + + // yup, change the LEDs + local_irq_save(flags); + + switch(ledevt) { + case led_idle_start: + leds = __raw_readl(ctrl); + leds |= GREEN_LED; + __raw_writel(leds,ctrl); + break; + + case led_idle_end: + leds = __raw_readl(ctrl); + leds &= ~GREEN_LED; + __raw_writel(leds,ctrl); + break; + + case led_timer: + leds = __raw_readl(ctrl); + leds ^= YELLOW_LED; + __raw_writel(leds,ctrl); + break; + + case led_red_on: + leds = __raw_readl(ctrl); + leds |= RED_LED; + __raw_writel(leds,ctrl); + break; + + case led_red_off: + leds = __raw_readl(ctrl); + leds &= ~RED_LED; + __raw_writel(leds,ctrl); + break; + + default: + break; + } + + local_irq_restore(flags); +} + +static int __init leds_init(void) +{ + if (machine_is_omaha()) + leds_event = omaha_leds_event; + + return 0; +} + +__initcall(leds_init); diff -urN linux-2.4.21/arch/arm/mach-sa1100/Makefile linux-2.4.22/arch/arm/mach-sa1100/Makefile --- linux-2.4.21/arch/arm/mach-sa1100/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -15,10 +15,10 @@ obj-n := obj- := -export-objs := assabet.o dma-sa1100.o dma-sa1111.o \ - flexanet.o freebird.o generic.o h3600.o \ - huw_webpanel.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \ - system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o +export-objs := assabet.o consus.o badge4.o dma-sa1100.o dma-sa1111.o \ + flexanet.o freebird.o frodo.o generic.o h3600.o \ + huw_webpanel.o irq.o sa1111.o sa1111-pcibuf.o \ + system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o # These aren't present yet, and prevents a plain -ac kernel building. # hwtimer.o @@ -29,22 +29,30 @@ # We link the CPU support next, so that RAM timings can be tuned. ifeq ($(CONFIG_CPU_FREQ),y) obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o +obj-$(CONFIG_SA1100_CEP) += cpu-sa1110.o +obj-$(CONFIG_SA1100_CONSUS) += cpu-sa1110.o obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o +obj-$(CONFIG_SA1100_HACKKIT) += cpu-sa1110.o obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o +obj-$(CONFIG_SA1100_SIMPUTER) += cpu-sa1110.o obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o endif # Next, the SA1111 stuff. obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o -obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o +obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o # Specific board support +obj-$(CONFIG_SA1100_ADSAGC) += adsagc.o obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o +obj-$(CONFIG_SA1100_ADSBITSYPLUS) += adsbitsyplus.o obj-$(CONFIG_SA1100_ASSABET) += assabet.o obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o obj-$(CONFIG_SA1100_BADGE4) += badge4.o obj-$(CONFIG_SA1100_BRUTUS) += brutus.o +obj-$(CONFIG_SA1100_CEP) += cep.o obj-$(CONFIG_SA1100_CERF) += cerf.o +obj-$(CONFIG_SA1100_CONSUS) += consus.o obj-$(CONFIG_SA1100_EMPEG) += empeg.o obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o @@ -52,6 +60,7 @@ obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o obj-$(CONFIG_SA1100_H3600) += h3600.o +obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o obj-$(CONFIG_SA1100_ITSY) += itsy.o obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o @@ -65,20 +74,25 @@ obj-$(CONFIG_SA1100_SHANNON) += shannon.o obj-$(CONFIG_SA1100_SHERMAN) += sherman.o obj-$(CONFIG_SA1100_SIMPAD) += simpad.o +obj-$(CONFIG_SA1100_SIMPUTER) += simputer.o obj-$(CONFIG_SA1100_VICTOR) += victor.o obj-$(CONFIG_SA1100_XP860) += xp860.o obj-$(CONFIG_SA1100_YOPY) += yopy.o # LEDs support leds-y := leds.o +leds-$(CONFIG_SA1100_ADSAGC) += leds-adsagc.o leds-$(CONFIG_SA1100_ADSBITSY) += leds-adsbitsy.o +leds-$(CONFIG_SA1100_ADSBITSYPLUS) += leds-adsbitsyplus.o leds-$(CONFIG_SA1100_ASSABET) += leds-assabet.o leds-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o leds-$(CONFIG_SA1100_CERF) += leds-cerf.o +leds-$(CONFIG_SA1100_CONSUS) += leds-consus.o leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o leds-$(CONFIG_SA1100_FRODO) += leds-frodo.o leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o +leds-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o leds-$(CONFIG_SA1100_LART) += leds-lart.o leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o leds-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o @@ -95,6 +109,8 @@ # Miscelaneous functions obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_SA1100_SSP) += ssp.o + include $(TOPDIR)/Rules.make sa1100usb_core.o: $(sa1100usb_core-objs) diff -urN linux-2.4.21/arch/arm/mach-sa1100/adsagc.c linux-2.4.22/arch/arm/mach-sa1100/adsagc.c --- linux-2.4.21/arch/arm/mach-sa1100/adsagc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/adsagc.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,360 @@ +/* + * linux/arch/arm/mach-sa1100/adsagc.c + * + * Pieces specific to the ADS Advanced Graphics Client board + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "generic.h" +#include "sa1111.h" + +static int __init adsagc_init(void) +{ + int ret; + + if (!machine_is_adsagc()) + return -ENODEV; + + /* + * Ensure that the memory bus request/grant signals are setup, + * and the grant is held in its inactive state + */ + sa1110_mb_disable(); + + /* Adsagc uses GPIO pins for SPI interface to AVR + * AGC uses the standard pins instead. AGC also has controls + * SA1111 and Smartio reset with GPIO. + */ + + // Set RTS low during sleep + PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19; + + // Reset SA1111 + GPDR |= GPIO_GPIO12; + GPCR = GPIO_GPIO12; + udelay(1000); + GPSR = GPIO_GPIO12; + + /* use the regular SSP pins */ + PPAR &= ~PPAR_SSPGPIO; + /* + * Probe for SA1111. + */ + ret = sa1111_probe(ADS_SA1111_BASE); + if (ret < 0) + return ret; + + /* + * We found it. Wake the chip up. + */ + sa1111_wake(); + + /* + * The SDRAM configuration of the SA1110 and the SA1111 must + * match. This is very important to ensure that SA1111 accesses + * don't corrupt the SDRAM. Note that this ungates the SA1111's + * MBGNT signal, so we must have called sa1110_mb_disable() + * beforehand. + */ + sa1111_configure_smc(1, + FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), + FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); + + /* + * Enable PWM control for LCD + */ + SKPCR |= SKPCR_PWMCLKEN; + SACR1 &= ~SACR1_L3EN; + ADS_CR3 |= ADS_CR3_BLON; // Enable the backlight + SKPWM1 = 0x7F; // Backlight PWM + SKPEN1 = 1; + SKPWM0 = 0x7F; // VEE + SKPEN0 = 1; + + /* + * We only need to turn on DCLK whenever we want to use the + * DMA. It can otherwise be held firmly in the off position. + */ + SKPCR |= SKPCR_DCLKEN; + + /* + * Enable the SA1110 memory bus request and grant signals. + */ + sa1110_mb_enable(); + + set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE); + sa1111_init_irq(IRQ_GPIO0); + + return 0; +} + +__initcall(adsagc_init); + +/* + * Handlers for Adsagc's external IRQ logic + */ + +#define ADSAGC_N_IRQ (IRQ_ADSAGC_END - IRQ_ADSAGC_START) + +static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs ) +{ + int i; + + while( (irq = ADS_INT_ST1 ) ){ + for( i = 0; i < ADSAGC_N_IRQ; i++ ) + if( irq & (1<mapbase == _Ser1UTCR0) { + Ser1SDCR0 |= SDCR0_UART; + } + else if (port->mapbase == _Ser2UTCR0) { + Ser2UTCR4 = Ser2HSCR0 = 0; + } + return ret; +} + +static u_int adsagc_get_mctrl(struct uart_port *port) +{ + u_int result = TIOCM_CD | TIOCM_DSR; + + if (port->mapbase == _Ser1UTCR0) { + if (!(GPLR & GPIO_GPIO14)) + result |= TIOCM_CTS; + } else if (port->mapbase == _Ser2UTCR0) { + if (!(GPLR & GPIO_GPIO16)) + result |= TIOCM_CTS; + } else if (port->mapbase == _Ser3UTCR0) { + if (!(GPLR & GPIO_GPIO18)) + result |= TIOCM_CTS; + } else { + result = TIOCM_CTS; + } + + return result; +} + +static void adsagc_set_mctrl(struct uart_port *port, u_int mctrl) +{ + if (port->mapbase == _Ser1UTCR0) { + if (mctrl & TIOCM_RTS) + GPCR = GPIO_GPIO15; + else + GPSR = GPIO_GPIO15; + } else if (port->mapbase == _Ser2UTCR0) { + if (mctrl & TIOCM_RTS) + GPCR = GPIO_GPIO17; + else + GPSR = GPIO_GPIO17; + } else if (port->mapbase == _Ser3UTCR0) { + if (mctrl & TIOCM_RTS) + GPCR = GPIO_GPIO19; + else + GPSR = GPIO_GPIO19; + } +} + +static void +adsagc_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + // state has ACPI D0-D3 + // ACPI D0 : resume from suspend + // ACPI D1-D3 : enter to a suspend state + if (port->mapbase == _Ser1UTCR0) { + if (state) { + // disable uart + Ser1UTCR3 = 0; + } + } + else if (port->mapbase == _Ser2UTCR0) { + if (state) { + // disable uart + Ser2UTCR3 = 0; + Ser2HSCR0 = 0; + } + } + else if (port->mapbase == _Ser3UTCR0) { + if (state) { + // disable uart + Ser3UTCR3 = 0; + } + } +} + +static struct sa1100_port_fns adsagc_port_fns __initdata = { + .open = adsagc_uart_open, + .get_mctrl = adsagc_get_mctrl, + .set_mctrl = adsagc_set_mctrl, + .pm = adsagc_uart_pm, +}; + +static void __init adsagc_map_io(void) +{ + sa1100_map_io(); + iotable_init(adsagc_io_desc); + + sa1100_register_uart_fns(&adsagc_port_fns); + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); + // don't register if you want to use IRDA +#ifndef CONFIG_SA1100_FIR + sa1100_register_uart(2, 2); +#endif + + /* set GPDR now */ + GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19; + GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18); +} + +MACHINE_START(ADSAGC, "ADS Advanced GraphicsClient") + BOOT_PARAMS(0xc000003c) + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + MAPIO(adsagc_map_io) + INITIRQ(adsagc_init_irq) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/adsbitsy.c linux-2.4.22/arch/arm/mach-sa1100/adsbitsy.c --- linux-2.4.21/arch/arm/mach-sa1100/adsbitsy.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/adsbitsy.c 2003-08-25 04:44:39.000000000 -0700 @@ -14,9 +14,13 @@ #include #include #include +#include #include +#include +#include #include +#include #include #include @@ -30,6 +34,7 @@ #include "generic.h" #include "sa1111.h" + static int __init adsbitsy_init(void) { int ret; @@ -43,6 +48,13 @@ */ sa1110_mb_disable(); + /* Bitsy uses GPIO pins for SPI interface to AVR + * Bitsy Plus uses the standard pins instead. + * it also needs to reset the AVR when booting + */ + + PPAR |= PPAR_SSPGPIO; + /* * Reset SA1111 */ @@ -50,6 +62,19 @@ udelay(1000); GPSR |= GPIO_GPIO26; + +#ifndef CONFIG_LEDS_TIMER + // Set Serial port 1 RTS and DTR Low during sleep + PGSR |= GPIO_GPIO15 | GPIO_GPIO20; +#else + // only RTS (because DTR is also the LED + // which should be off during sleep); + PGSR |= GPIO_GPIO15; +#endif + + // Set Serial port 3RTS Low during sleep + PGSR |= GPIO_GPIO19; + /* * Probe for SA1111. */ @@ -74,15 +99,6 @@ FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); /* - * Enable PWM control for LCD - */ - SKPCR |= SKPCR_PWMCLKEN; - SKPWM0 = 0x7F; // VEE - SKPEN0 = 1; - SKPWM1 = 0x01; // Backlight - SKPEN1 = 1; - - /* * We only need to turn on DCLK whenever we want to use the * DMA. It can otherwise be held firmly in the off position. */ @@ -108,48 +124,135 @@ } -/* - * Initialization fixup - */ - -static void __init -fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params, - char **cmdline, struct meminfo *mi) -{ - SET_BANK( 0, 0xc0000000, 32*1024*1024 ); - mi->nr_banks = 1; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); -} - static struct map_desc adsbitsy_io_desc[] __initdata = { /* virtual physical length domain r w c b */ - { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */ + { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */ + { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */ { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */ LAST_DESC }; +/* Use this to see when all uarts are shutdown. Or all are closed. + * We can only turn off RS232 chip if either of these are true. + */ + +static int uart_wake_count[3] = {1, 1, 1}; + +enum {UART_SHUTDOWN, UART_WAKEUP}; + +static void update_uart_counts(int line, int state) +{ + switch (state) { + case UART_WAKEUP: + uart_wake_count[line]++; + break; + case UART_SHUTDOWN: + uart_wake_count[line]--; + break; + } +} + static int adsbitsy_uart_open(struct uart_port *port, struct uart_info *info) { if (port->mapbase == _Ser1UTCR0) { Ser1SDCR0 |= SDCR0_UART; -#error Fixme // Set RTS High (should be done in the set_mctrl fn) - GPCR = GPIO_GPIO15; } else if (port->mapbase == _Ser2UTCR0) { Ser2UTCR4 = Ser2HSCR0 = 0; -#error Fixme // Set RTS High (should be done in the set_mctrl fn) - GPCR = GPIO_GPIO17; - } else if (port->mapbase == _Ser2UTCR0) { -#error Fixme // Set RTS High (should be done in the set_mctrl fn) - GPCR = GPIO_GPIO19; } return 0; } +void adsbitsy_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + // state has ACPI D0-D3 + // ACPI D0 : resume from suspend + // ACPI D1-D3 : enter to a suspend state + if (port->mapbase == _Ser1UTCR0) { + if (state) { + update_uart_counts(1, UART_SHUTDOWN); + // disable uart + Ser1UTCR3 = 0; + } + else { + update_uart_counts(1, UART_WAKEUP); + } + } + else if (port->mapbase == _Ser2UTCR0) { + if (state) { + update_uart_counts(2, UART_SHUTDOWN); + // disable uart + Ser2UTCR3 = 0; + Ser2HSCR0 = 0; + } + else { + update_uart_counts(2, UART_WAKEUP); + } + } + else if (port->mapbase == _Ser3UTCR0) { + if (state) { + update_uart_counts(0, UART_SHUTDOWN); + // disable uart + Ser3UTCR3 = 0; + } + else { + update_uart_counts(0, UART_WAKEUP); + } + } +} + +static void adsbitsy_set_mctrl(struct uart_port *port, u_int mctrl) +{ + // note: only ports 1 and 3 have modem control + if (port->mapbase == _Ser1UTCR0) { + if (mctrl & TIOCM_RTS) + // Set RTS High + GPCR = GPIO_GPIO15; + else + // Set RTS LOW + GPSR = GPIO_GPIO15; + if (mctrl & TIOCM_DTR) + // Set DTR High + GPCR = GPIO_GPIO20; + else + // Set DTR Low + GPSR = GPIO_GPIO20; + } else if (port->mapbase == _Ser3UTCR0) { + if (mctrl & TIOCM_RTS) + // Set RTS High + GPCR = GPIO_GPIO19; + else + // Set RTS LOW + GPSR = GPIO_GPIO19; + } +} + +static u_int adsbitsy_get_mctrl(struct uart_port *port) +{ + u_int ret = 0; + + // note: only ports 1 and 3 have modem control + if (port->mapbase == _Ser1UTCR0) { + if (!(GPLR & GPIO_GPIO14)) + ret |= TIOCM_CTS; + if (!(GPLR & GPIO_GPIO24)) + ret |= TIOCM_DSR; + if (!(GPLR & GPIO_GPIO16)) + ret |= TIOCM_RI; + if (!(GPLR & GPIO_GPIO17)) + ret |= TIOCM_CD; + } else if (port->mapbase == _Ser3UTCR0) { + if (!(GPLR & GPIO_GPIO18)) + ret |= TIOCM_CTS; + } + + return ret; +} + static struct sa1100_port_fns adsbitsy_port_fns __initdata = { - .open = adsbitsy_uart_open, + .set_mctrl = adsbitsy_set_mctrl, + .get_mctrl = adsbitsy_get_mctrl, + .open = adsbitsy_uart_open, + .pm = adsbitsy_uart_pm, }; static void __init adsbitsy_map_io(void) @@ -160,14 +263,27 @@ sa1100_register_uart_fns(&adsbitsy_port_fns); sa1100_register_uart(0, 3); sa1100_register_uart(1, 1); + + // don't register if you want to use IRDA +#ifndef CONFIG_SA1100_FIR sa1100_register_uart(2, 2); - GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19; - GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18); +#endif + + // COM1 Set RTS and DTR Output + GPDR |= GPIO_GPIO15 | GPIO_GPIO20; + // Set CTS, DSR, RI and CD Input + GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17); + + // COM3 Set RTS Output + GPDR |= GPIO_GPIO19; + // Set CTS Input + GPDR &= ~GPIO_GPIO18; } + MACHINE_START(ADSBITSY, "ADS Bitsy") + BOOT_PARAMS(0xc000003c) BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_adsbitsy) MAPIO(adsbitsy_map_io) INITIRQ(adsbitsy_init_irq) MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/adsbitsyplus.c linux-2.4.22/arch/arm/mach-sa1100/adsbitsyplus.c --- linux-2.4.21/arch/arm/mach-sa1100/adsbitsyplus.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/adsbitsyplus.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,395 @@ +/* + * linux/arch/arm/mach-sa1100/adsbitsyplus.c + * + * Author: Robert Whaley + * + * This file comes from adsbitsy.c of Woojung Huh + * + * Pieces specific to the ADS Bitsy Plus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "generic.h" +#include "sa1111.h" + +/* unfortunately, we can't detect the difference between REV 2 and REV A + connector boards. So by convention, the registers.txt file is used + to set a byte to either 0x02 or 0x0a to make this distinction. The + bootloader must detect this by default we assume rev A since most boards + will be rev A */ + +static int adsbitsyplus_connector_board_rev_number = 0xA; + +static int __init adsbitsyplus_connector_board_rev_setup(char *str) +{ + adsbitsyplus_connector_board_rev_number = simple_strtol(str,NULL,0); + return 1; +} + +int adsbitsyplus_connector_board_rev(void) +{ + static int only_once = 1; + if (only_once) { + printk(KERN_INFO "Bitsy Connector Board REV: %#x\n", adsbitsyplus_connector_board_rev_number); + only_once = 0; + } + return adsbitsyplus_connector_board_rev_number; +} + +static int __init adsbitsyplus_init(void) +{ + int ret; + + if (!machine_is_adsbitsyplus()) + return -ENODEV; + + /* + * Ensure that the memory bus request/grant signals are setup, + * and the grant is held in its inactive state + */ + sa1110_mb_disable(); + + /* Bitsy uses GPIO pins for SPI interface to AVR + * Bitsy Plus uses the standard pins instead. + * it also needs to reset the AVR when booting + */ + + PPAR &= ~PPAR_SSPGPIO; + ADS_CPLD_SUPPC |= ADS_SUPPC_AVR_WKP; + mdelay(100); + ADS_CPLD_SUPPC &= ~ADS_SUPPC_AVR_WKP; + + /* + * Reset SA1111 + */ + GPCR |= GPIO_GPIO26; + udelay(1000); + GPSR |= GPIO_GPIO26; + +#ifndef CONFIG_LEDS_TIMER + // Set Serial port 1 RTS and DTR Low during sleep + PGSR |= GPIO_GPIO15 | GPIO_GPIO20; +#else + // only RTS (because DTR is also the LED + // which should be off during sleep); + PGSR |= GPIO_GPIO15; +#endif + + // Set Serial port 3RTS Low during sleep + PGSR |= GPIO_GPIO19; + + /* + * Probe for SA1111. + */ + ret = sa1111_probe(ADSBITSYPLUS_SA1111_BASE); + if (ret < 0) + return ret; + + /* + * We found it. Wake the chip up. + */ + sa1111_wake(); + + /* + * The SDRAM configuration of the SA1110 and the SA1111 must + * match. This is very important to ensure that SA1111 accesses + * don't corrupt the SDRAM. Note that this ungates the SA1111's + * MBGNT signal, so we must have called sa1110_mb_disable() + * beforehand. + */ + sa1111_configure_smc(1, + FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), + FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); + + /* + * We only need to turn on DCLK whenever we want to use the + * DMA. It can otherwise be held firmly in the off position. + */ + SKPCR |= SKPCR_DCLKEN; + + /* + * Enable the SA1110 memory bus request and grant signals. + */ + sa1110_mb_enable(); + + set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE); + sa1111_init_irq(IRQ_GPIO0); + + return 0; +} + +__initcall(adsbitsyplus_init); + +static void __init adsbitsyplus_init_irq(void) +{ + /* First the standard SA1100 IRQs */ + sa1100_init_irq(); +} + +/* + * Resume SA1111 when system wakes up + */ +void adsbitsyplus_sa1111_wake(unsigned long pa_dwr) +{ + // Turn ON SA1111 + GPCR |= GPIO_GPIO26; + mdelay(1); + GPSR |= GPIO_GPIO26; + + GAFR |= GPIO_32_768kHz; + GPDR |= GPIO_32_768kHz; + TUCR = TUCR_3_6864MHz; + + SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN; + udelay(100); + SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN; + + GAFR |= (GPIO_MBGNT | GPIO_MBREQ); + GPDR |= GPIO_MBGNT; + GPDR &= ~GPIO_MBREQ; + TUCR |= TUCR_MR; + + sa1111_configure_smc(1, + FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), + FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); + SKPCR |= SKPCR_DCLKEN; + + // Reset PCMCIA + PCCR = 0xFF; + mdelay(100); + PA_DDR = 0x00; + // PA_DWR = GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3; + // PA_DWR = GPIO_GPIO0 | GPIO_GPIO2 | GPIO_GPIO3; + PA_DWR = pa_dwr; + PCCR = ~(PCCR_S0_RST | PCCR_S1_RST); + +#ifdef CONFIG_USB_OHCI_SA1111 + // Turn ON clock + SKPCR |= SKPCR_UCLKEN; + udelay(100); + + // force a RESET + USB_RESET = 0x01; + USB_RESET |= 0x02; + udelay(100); + + // Set Power Sense and Control Line + USB_RESET = 0; + USB_RESET = USB_RESET_PWRSENSELOW; + USB_STATUS = 0; + udelay(10); +#endif +} + + +static struct map_desc adsbitsyplus_io_desc[] __initdata = { + /* virtual physical length domain r w c b */ + { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */ + { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */ + { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */ + { 0xf1000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD Controller */ + LAST_DESC +}; + +/* Use this to see when all uarts are shutdown. Or all are closed. + * We can only turn off RS232 chip if either of these are true. + */ + +static int uart_wake_count[3] = {1, 1, 1}; + +enum {UART_SHUTDOWN, UART_WAKEUP}; + +static void update_uart_counts(int line, int state) +{ + switch (state) { + case UART_WAKEUP: + uart_wake_count[line]++; + break; + case UART_SHUTDOWN: + uart_wake_count[line]--; + break; + } +} + +static int adsbitsyplus_uart_open(struct uart_port *port, struct uart_info *info) +{ + if (port->mapbase == _Ser1UTCR0) { + Ser1SDCR0 |= SDCR0_UART; + } else if (port->mapbase == _Ser2UTCR0) { + Ser2UTCR4 = Ser2HSCR0 = 0; + } + return 0; +} + +void adsbitsyplus_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + // state has ACPI D0-D3 + // ACPI D0 : resume from suspend + // ACPI D1-D3 : enter to a suspend state + if (port->mapbase == _Ser1UTCR0) { + if (state) { + update_uart_counts(1, UART_SHUTDOWN); + // disable uart + Ser1UTCR3 = 0; + } + else { + update_uart_counts(1, UART_WAKEUP); + } + } + else if (port->mapbase == _Ser2UTCR0) { + if (state) { + update_uart_counts(2, UART_SHUTDOWN); + // disable uart + Ser2UTCR3 = 0; + Ser2HSCR0 = 0; + } + else { + update_uart_counts(2, UART_WAKEUP); + } + } + else if (port->mapbase == _Ser3UTCR0) { + if (state) { + update_uart_counts(0, UART_SHUTDOWN); + // disable uart + Ser3UTCR3 = 0; + } + else { + update_uart_counts(0, UART_WAKEUP); + } + } + if (state == 0) { + // Turn power on if uarts are awake + if (uart_wake_count[0] + uart_wake_count[1] != 0) { + // make sure RS-232 is turned on if 1 or 3 are open + ADS_CPLD_PCON |= ADS_PCON_COM1_3_ON; + } + if (uart_wake_count[2] != 0) { + if (adsbitsyplus_connector_board_rev() >= 0x0a) + ADS_CPLD_PCON |= ADS_PCON_CONN_B_PE2; + } + } + else { + // Turn power off if uarts are asleep + if (uart_wake_count[0] + uart_wake_count[1] == 0) { + // save power if we are sleeping + ADS_CPLD_PCON &= ~ADS_PCON_COM1_3_ON; + GAFR &= ~(GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20); + GPDR |= GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20; + } + if (uart_wake_count[2] == 0) { + if (adsbitsyplus_connector_board_rev() >= 0x0a) + ADS_CPLD_PCON &= ~ADS_PCON_CONN_B_PE2; + } + } +} + +static void adsbitsyplus_set_mctrl(struct uart_port *port, u_int mctrl) +{ + // note: only ports 1 and 3 have modem control + if (port->mapbase == _Ser1UTCR0) { + if (mctrl & TIOCM_RTS) + // Set RTS High + GPCR = GPIO_GPIO15; + else + // Set RTS LOW + GPSR = GPIO_GPIO15; + if (mctrl & TIOCM_DTR) + // Set DTR High + GPCR = GPIO_GPIO20; + else + // Set DTR Low + GPSR = GPIO_GPIO20; + } else if (port->mapbase == _Ser3UTCR0) { + if (mctrl & TIOCM_RTS) + // Set RTS High + GPCR = GPIO_GPIO19; + else + // Set RTS LOW + GPSR = GPIO_GPIO19; + } +} + +static u_int adsbitsyplus_get_mctrl(struct uart_port *port) +{ + u_int ret = 0; + + // note: only ports 1 and 3 have modem control + if (port->mapbase == _Ser1UTCR0) { + if (!(GPLR & GPIO_GPIO14)) + ret |= TIOCM_CTS; + if (!(GPLR & GPIO_GPIO24)) + ret |= TIOCM_DSR; + if (!(GPLR & GPIO_GPIO16)) + ret |= TIOCM_RI; + if (!(GPLR & GPIO_GPIO17)) + ret |= TIOCM_CD; + } else if (port->mapbase == _Ser3UTCR0) { + if (!(GPLR & GPIO_GPIO18)) + ret |= TIOCM_CTS; + } + + return ret; +} + +static struct sa1100_port_fns adsbitsyplus_port_fns __initdata = { + .set_mctrl = adsbitsyplus_set_mctrl, + .get_mctrl = adsbitsyplus_get_mctrl, + .open = adsbitsyplus_uart_open, + .pm = adsbitsyplus_uart_pm, +}; + +static void __init adsbitsyplus_map_io(void) +{ + sa1100_map_io(); + iotable_init(adsbitsyplus_io_desc); + + sa1100_register_uart_fns(&adsbitsyplus_port_fns); + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); + + // don't register if you want to use IRDA +#ifndef CONFIG_SA1100_FIR + sa1100_register_uart(2, 2); +#endif + + // COM1 Set RTS and DTR Output + GPDR |= GPIO_GPIO15 | GPIO_GPIO20; + // Set CTS, DSR, RI and CD Input + GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17); + + // COM3 Set RTS Output + GPDR |= GPIO_GPIO19; + // Set CTS Input + GPDR &= ~GPIO_GPIO18; +} + +__setup("adsbitsyplus_conn_board_rev=", adsbitsyplus_connector_board_rev_setup); + +MACHINE_START(ADSBITSYPLUS, "ADS Bitsy Plus") + BOOT_PARAMS(0xc000003c) + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + MAPIO(adsbitsyplus_map_io) + INITIRQ(adsbitsyplus_init_irq) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/assabet.c linux-2.4.22/arch/arm/mach-sa1100/assabet.c --- linux-2.4.21/arch/arm/mach-sa1100/assabet.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/assabet.c 2003-08-25 04:44:39.000000000 -0700 @@ -42,7 +42,8 @@ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ - ASSABET_BCR_IRDA_MD0 | ASSABET_BCR_CF_RST) + ASSABET_BCR_IRDA_MD0 | ASSABET_BCR_CF_RST | \ + ASSABET_BCR_CODEC_RST ) unsigned long SCR_value = ASSABET_SCR_INIT; EXPORT_SYMBOL(SCR_value); diff -urN linux-2.4.21/arch/arm/mach-sa1100/cep.c linux-2.4.22/arch/arm/mach-sa1100/cep.c --- linux-2.4.21/arch/arm/mach-sa1100/cep.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/cep.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,123 @@ +/* + * linux/arch/arm/mach-sa1100/cep.c + * + * Author: Matthias Gorjup + * + * This file contains all Cep - specific tweaks. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + + +extern void convert_to_tag_list(struct param_struct *params, int mem_init); + +static void __init +fixup_cep(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + struct tag *t = (struct tag *)params; + + + /* + * Apparantly bootldr uses a param_struct. Groan. + */ + if (t->hdr.tag != ATAG_CORE) + convert_to_tag_list(params, 1); + + if (t->hdr.tag != ATAG_CORE) { + t->hdr.tag = ATAG_CORE; + t->hdr.size = tag_size(tag_core); + t->u.core.flags = 0; + t->u.core.pagesize = PAGE_SIZE; + t->u.core.rootdev = RAMDISK_MAJOR << 8 | 0; + t = tag_next(t); + + t->hdr.tag = ATAG_MEM; + t->hdr.size = tag_size(tag_mem32); + t->u.mem.start = 0xc0000000; + t->u.mem.size = 32 * 1024 * 1024; + t = tag_next(t); + + + t->hdr.tag = ATAG_RAMDISK; + t->hdr.size = tag_size(tag_ramdisk); + t->u.ramdisk.flags = 1; + t->u.ramdisk.size = 8192; + t->u.ramdisk.start = 0; + t = tag_next(t); + + t->hdr.tag = ATAG_INITRD; + t->hdr.size = tag_size(tag_initrd); + t->u.initrd.start = 0xc0800000; + t->u.initrd.size = 3 * 1024 * 1024; + t = tag_next(t); + + t->hdr.tag = ATAG_NONE; + t->hdr.size = 0; + } +} + + +static struct map_desc cep_io_desc[] __initdata = { + /* virtual physical length domain r w c b */ + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */ + LAST_DESC +}; + +static void __init cep_map_io(void) +{ + + sa1100_map_io(); + iotable_init(cep_io_desc); + + sa1100_register_uart(0, 1); /* com port */ + sa1100_register_uart(2, 3); /* radio module */ + + /* + * Ensure that these pins are set as outputs and are driving + * logic 0. This ensures that we won't inadvertently toggle + * the WS latch in the CPLD, and we don't float causing + * excessive power drain. --rmk + */ + GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; + GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; + + /* + * Set up registers for sleep mode. + */ + PWER = PWER_GPIO0; + PGSR = 0; + PCFR = 0; + PSDR = 0; +} + + +MACHINE_START(CEP, "Iskratel Cep") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_cep) + MAPIO(cep_map_io) + INITIRQ(sa1100_init_irq) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/cpu-sa1110.c linux-2.4.22/arch/arm/mach-sa1100/cpu-sa1110.c --- linux-2.4.21/arch/arm/mach-sa1100/cpu-sa1110.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/cpu-sa1110.c 2003-08-25 04:44:39.000000000 -0700 @@ -49,33 +49,33 @@ }; static struct sdram_params tc59sm716_cl2_params __initdata = { - rows: 12, - tck: 10, - trcd: 20, - trp: 20, - twr: 10, - refresh: 64000, - cas_latency: 2, + .rows = 12, + .tck = 10, + .trcd = 20, + .trp = 20, + .twr = 10, + .refresh = 64000, + .cas_latency = 2, }; static struct sdram_params tc59sm716_cl3_params __initdata = { - rows: 12, - tck: 8, - trcd: 20, - trp: 20, - twr: 8, - refresh: 64000, - cas_latency: 3, + .rows = 12, + .tck = 8, + .trcd = 20, + .trp = 20, + .twr = 8, + .refresh = 64000, + .cas_latency = 3, }; static struct sdram_params samsung_k4s641632d_tc75 __initdata = { - rows: 14, - tck: 9, - trcd: 27, - trp: 20, - twr: 9, - refresh: 64000, - cas_latency: 3, + .rows = 14, + .tck = 9, + .trcd = 27, + .trp = 20, + .twr = 9, + .refresh = 64000, + .cas_latency = 3, }; static struct sdram_params sdram_params; @@ -235,21 +235,21 @@ * the programming. */ local_irq_save(flags); - asm("mcr p15, 0, %0, c10, c4" : : "r" (0)); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); udelay(10); - __asm__ __volatile__(" - b 2f - .align 5 -1: str %3, [%1, #0] @ MDCNFG - str %4, [%1, #28] @ MDREFR - str %5, [%1, #4] @ MDCAS0 - str %6, [%1, #8] @ MDCAS1 - str %7, [%1, #12] @ MDCAS2 - str %8, [%2, #0] @ PPCR - ldr %0, [%1, #0] - b 3f -2: b 1b -3: nop + __asm__ __volatile__(" \n\ + b 2f \n\ + .align 5 \n\ +1: str %3, [%1, #0] @ MDCNFG \n\ + str %4, [%1, #28] @ MDREFR \n\ + str %5, [%1, #4] @ MDCAS0 \n\ + str %6, [%1, #8] @ MDCAS1 \n\ + str %7, [%1, #12] @ MDCAS2 \n\ + str %8, [%2, #0] @ PPCR \n\ + ldr %0, [%1, #0] \n\ + b 3f \n\ +2: b 1b \n\ +3: nop \n\ nop" : "=&r" (unused) : "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg), diff -urN linux-2.4.21/arch/arm/mach-sa1100/dma-sa1100.c linux-2.4.22/arch/arm/mach-sa1100/dma-sa1100.c --- linux-2.4.21/arch/arm/mach-sa1100/dma-sa1100.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/dma-sa1100.c 2003-08-25 04:44:39.000000000 -0700 @@ -477,11 +477,11 @@ return sa1111_dma_resume(channel); if (dma->stopped) { - int flags; - save_flags_cli(flags); + unsigned long flags; + local_irq_save(flags); dma->stopped = 0; process_dma(dma); - restore_flags(flags); + local_irq_restore(flags); } return 0; } diff -urN linux-2.4.21/arch/arm/mach-sa1100/dma-sa1111.c linux-2.4.22/arch/arm/mach-sa1100/dma-sa1111.c --- linux-2.4.21/arch/arm/mach-sa1100/dma-sa1111.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/dma-sa1111.c 2003-08-25 04:44:39.000000000 -0700 @@ -305,7 +305,8 @@ * SDRAM bank 1 on Neponset). The default configuration selects * Assabet, so any address in bank 1 is necessarily invalid. */ - if((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000) + if((machine_is_assabet() || machine_is_pfs168() || + machine_is_graphicsmaster() || machine_is_adsagc()) && addr >= 0xc8000000) return -1; /* The bug only applies to buffers located more than one megabyte diff -urN linux-2.4.21/arch/arm/mach-sa1100/flexanet.c linux-2.4.22/arch/arm/mach-sa1100/flexanet.c --- linux-2.4.21/arch/arm/mach-sa1100/flexanet.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/flexanet.c 2003-08-25 04:44:39.000000000 -0700 @@ -26,6 +26,7 @@ #include #include #include +#include #include "generic.h" @@ -145,6 +146,11 @@ static int __init flexanet_init(void) { + /* Set IRQ edges */ + set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE); + + /* deassert the GUI reset */ + FLEXANET_BCR_set(FHH_BCR_GUI_NRST); return 0; } @@ -155,10 +161,6 @@ fixup_flexanet(struct machine_desc *desc, struct param_struct *params, char **cmdline, struct meminfo *mi) { - int status; - unsigned long now; - - /* fixed RAM size, by now (64MB) */ SET_BANK( 0, 0xc0000000, 64*1024*1024 ); mi->nr_banks = 1; @@ -175,7 +177,7 @@ { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */ { 0xf0000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Board Control Register */ { 0xf1000000, 0x18000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Ethernet controller */ - { 0xD0000000, 0x40000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Instrument boards */ + { 0xD0000000, 0x40000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Instrument boards */ { 0xD8000000, 0x48000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* External peripherals */ LAST_DESC }; @@ -198,13 +200,6 @@ */ PCFR = PCFR_OPDE | PCFR_FP | PCFR_FS; - /* deassert the GUI reset */ - FLEXANET_BCR_set(FHH_BCR_GUI_NRST); - - /* - * Set IRQ edges - */ - set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE); } diff -urN linux-2.4.21/arch/arm/mach-sa1100/frodo.c linux-2.4.22/arch/arm/mach-sa1100/frodo.c --- linux-2.4.21/arch/arm/mach-sa1100/frodo.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/frodo.c 2003-08-25 04:44:39.000000000 -0700 @@ -12,15 +12,22 @@ * * History: * + * 2002/05/27 Setup GPIOs for all the onboard peripherals so + * that we don't have to do it in each driver + * * 2002/01/31 Initial version */ #include #include +#include #include +#include -#include #include +#include +#include +#include #include #include @@ -28,30 +35,108 @@ #include "generic.h" -static struct map_desc frodo_io_desc[] __initdata = -{ - /* virtual physical length domain r w c b */ - { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* flash memory */ - { 0xf0000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* 16-bit on-board devices (including CPLDs) */ - { 0xf1000000, 0x18000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* 32-bit daughter card */ - LAST_DESC +static struct map_desc frodo_io_desc[] __initdata = { + /* virtual physical length domain r w c b */ + { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* flash memory */ + { 0xf0000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* 16-bit on-board devices (including CPLDs) */ + { 0xf1000000, 0x18000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* 32-bit daughter card */ + LAST_DESC }; +static spinlock_t frodo_cpld_lock = SPIN_LOCK_UNLOCKED; +static volatile u16 *frodo_cpld_memory = (u16 *) 0xf0000000; + static void __init frodo_map_io (void) { - sa1100_map_io (); - iotable_init (frodo_io_desc); + sa1100_map_io (); + iotable_init (frodo_io_desc); + + sa1100_register_uart (0,2); /* UART2 (serial console) */ + sa1100_register_uart (1,1); /* UART1 (big kahuna flow control serial port) */ + + /* + * Set SUS bit in SDCR0 so serial port 1 acts as a UART. + * See Intel SA-1110 Developers Manual Section 11.9.2.1 (GPCLK/UART Select) + */ + Ser1SDCR0 |= SDCR0_SUS; +} + +static int __init frodo_init_irq(void) +{ + int i,gpio[] = { + FRODO_IDE_GPIO, + FRODO_ETH_GPIO, + FRODO_USB_DC_GPIO, + FRODO_USB_HC_GPIO, + FRODO_RTC_GPIO, + FRODO_UART1_GPIO, + FRODO_UART2_GPIO, + FRODO_PCMCIA_STATUS_GPIO, + FRODO_PCMCIA_RDYBSY_GPIO + }; + + for (i = 0; i < sizeof (gpio) / sizeof (gpio[0]); i++) + set_GPIO_IRQ_edge (gpio[i],GPIO_RISING_EDGE); + + return (0); +} + +__initcall(frodo_init_irq); +#if 0 +static int __init frodo_init_cpld(void) +{ + if ((frodo_cpld_memory = ioremap (FRODO_CPLD_BASE,FRODO_CPLD_LENGTH)) == NULL) + panic ("Couldn't map CPLD memory to a virtual address. We're screwed!\n"); + + return (0); +} + +__initcall(frodo_init_cpld); +#endif +u16 frodo_cpld_read (u32 reg) +{ + unsigned long flags; + u16 value; + + spin_lock_irqsave (&frodo_cpld_lock,flags); + value = frodo_cpld_memory[reg / 2]; + spin_unlock_irqrestore (&frodo_cpld_lock,flags); + + return (value); +} + +void frodo_cpld_write (u32 reg,u16 value) +{ + unsigned long flags; - sa1100_register_uart (0,2); /* UART2 (serial console) */ - sa1100_register_uart (1,1); /* UART1 (big kahuna flow control serial port) */ + spin_lock_irqsave (&frodo_cpld_lock,flags); + frodo_cpld_memory[reg / 2] = value; + spin_unlock_irqrestore (&frodo_cpld_lock,flags); +} + +void frodo_cpld_set (u32 reg,u16 mask) +{ + unsigned long flags; + + spin_lock_irqsave (&frodo_cpld_lock,flags); + frodo_cpld_memory[reg / 2] |= mask; + spin_unlock_irqrestore (&frodo_cpld_lock,flags); +} + +void frodo_cpld_clear (u32 reg,u16 mask) +{ + unsigned long flags; - /* - * Set SUS bit in SDCR0 so serial port 1 acts as a UART. - * See Intel SA-1110 Developers Manual Section 11.9.2.1 (GPCLK/UART Select) - */ - Ser1SDCR0 |= SDCR0_SUS; + spin_lock_irqsave (&frodo_cpld_lock,flags); + frodo_cpld_memory[reg / 2] &= ~mask; + spin_unlock_irqrestore (&frodo_cpld_lock,flags); } +EXPORT_SYMBOL (frodo_cpld_read); +EXPORT_SYMBOL (frodo_cpld_write); +EXPORT_SYMBOL (frodo_cpld_set); +EXPORT_SYMBOL (frodo_cpld_clear); + MACHINE_START (FRODO,"2d3D, Inc. SA-1110 Development Board") BOOT_MEM (0xc0000000,0x80000000,0xf8000000) BOOT_PARAMS (0xc0000100) diff -urN linux-2.4.21/arch/arm/mach-sa1100/generic.c linux-2.4.22/arch/arm/mach-sa1100/generic.c --- linux-2.4.21/arch/arm/mach-sa1100/generic.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/generic.c 2003-08-25 04:44:39.000000000 -0700 @@ -86,7 +86,7 @@ static int __init sa11x0_init_clock(void) { - cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 0, 0); + cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 59000, 287000); return 0; } diff -urN linux-2.4.21/arch/arm/mach-sa1100/graphicsclient.c linux-2.4.22/arch/arm/mach-sa1100/graphicsclient.c --- linux-2.4.21/arch/arm/mach-sa1100/graphicsclient.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/graphicsclient.c 2003-08-25 04:44:39.000000000 -0700 @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -34,55 +36,58 @@ * Handlers for GraphicsClient's external IRQ logic */ +#define GRAPHICSCLIENT_N_IRQ (IRQ_GRAPHICSCLIENT_END - IRQ_GRAPHICSCLIENT_START) +#define GRAPHICSCLIENT_FIRST_IRQ (IRQ_GRAPHICSCLIENT_CAN - IRQ_GRAPHICSCLIENT_START) + static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs ) { int i; while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){ - for( i = 0; i < 16; i++ ) + for( i = GRAPHICSCLIENT_FIRST_IRQ; i < GRAPHICSCLIENT_N_IRQ; i++ ) if( irq & (1<nr_banks = 2; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); -} - static struct map_desc graphicsclient_io_desc[] __initdata = { /* virtual physical length domain r w c b */ { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */ @@ -143,120 +133,31 @@ LAST_DESC }; -static struct gc_uart_ctrl_data_t gc_uart_ctrl_data[] = { - { GPIO_GC_UART0_CTS, 0, NULL,NULL }, - { GPIO_GC_UART1_CTS, 0, NULL,NULL }, - { GPIO_GC_UART2_CTS, 0, NULL,NULL } -}; - -static void -graphicsclient_cts_intr(int irq, void *dev_id, struct pt_regs *regs) -{ - struct gc_uart_ctrl_data_t * uart_data = (struct gc_uart_ctrl_data_t *)dev_id; - int cts = !(GPLR & uart_data->cts_gpio); - - /* NOTE: I supose that we will no get any interrupt - if the GPIO is not changed, so maybe - the cts_prev_state can be removed ... */ - if (cts != uart_data->cts_prev_state) { - uart_data->cts_prev_state = cts; - - uart_handle_cts_change(uart_data->info, cts); - } -} - -static int -graphicsclient_register_cts_intr(int gpio, int irq, - struct gc_uart_ctrl_data_t *uart_data) -{ - int ret = 0; - - set_GPIO_IRQ_edge(gpio, GPIO_BOTH_EDGES); - - ret = request_irq(irq, graphicsclient_cts_intr, - 0, "GC RS232 CTS", uart_data); - if (ret) { - printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n", - ret); - free_irq(irq, uart_data); - } - - return ret; -} - -static int -graphicsclient_uart_open(struct uart_port *port, struct uart_info *info) +static int graphicsclient_uart_open(struct uart_port *port, struct uart_info *info) { - int ret = 0; + int ret = 0; if (port->mapbase == _Ser1UTCR0) { Ser1SDCR0 |= SDCR0_UART; - /* Set RTS Output */ - GPSR = GPIO_GC_UART0_RTS; - - gc_uart_ctrl_data[0].cts_prev_state = 0; - gc_uart_ctrl_data[0].info = info; - gc_uart_ctrl_data[0].port = port; - - /* register uart0 CTS irq */ - ret = graphicsclient_register_cts_intr(GPIO_GC_UART0_CTS, - IRQ_GC_UART0_CTS, - &gc_uart_ctrl_data[0]); - } else if (port->mapbase == _Ser2UTCR0) { + } + else if (port->mapbase == _Ser2UTCR0) { Ser2UTCR4 = Ser2HSCR0 = 0; - /* Set RTS Output */ - GPSR = GPIO_GC_UART1_RTS; - - gc_uart_ctrl_data[1].cts_prev_state = 0; - gc_uart_ctrl_data[1].info = info; - gc_uart_ctrl_data[1].port = port; - - /* register uart1 CTS irq */ - ret = graphicsclient_register_cts_intr(GPIO_GC_UART1_CTS, - IRQ_GC_UART1_CTS, - &gc_uart_ctrl_data[1]); - } else if (port->mapbase == _Ser3UTCR0) { - /* Set RTS Output */ - GPSR = GPIO_GC_UART2_RTS; - - gc_uart_ctrl_data[2].cts_prev_state = 0; - gc_uart_ctrl_data[2].info = info; - gc_uart_ctrl_data[2].port = port; - - /* register uart2 CTS irq */ - ret = graphicsclient_register_cts_intr(GPIO_GC_UART2_CTS, - IRQ_GC_UART2_CTS, - &gc_uart_ctrl_data[2]); } return ret; } -static int -graphicsclient_uart_close(struct uart_port *port, struct uart_info *info) -{ - if (port->mapbase == _Ser1UTCR0) { - free_irq(IRQ_GC_UART0_CTS, &gc_uart_ctrl_data[0]); - } else if (port->mapbase == _Ser2UTCR0) { - free_irq(IRQ_GC_UART1_CTS, &gc_uart_ctrl_data[1]); - } else if (port->mapbase == _Ser3UTCR0) { - free_irq(IRQ_GC_UART2_CTS, &gc_uart_ctrl_data[2]); - } - - return 0; -} - static u_int graphicsclient_get_mctrl(struct uart_port *port) { u_int result = TIOCM_CD | TIOCM_DSR; if (port->mapbase == _Ser1UTCR0) { - if (!(GPLR & GPIO_GC_UART0_CTS)) + if (!(GPLR & GPIO_GPIO14)) result |= TIOCM_CTS; } else if (port->mapbase == _Ser2UTCR0) { - if (!(GPLR & GPIO_GC_UART1_CTS)) + if (!(GPLR & GPIO_GPIO16)) result |= TIOCM_CTS; } else if (port->mapbase == _Ser3UTCR0) { - if (!(GPLR & GPIO_GC_UART2_CTS)) + if (!(GPLR & GPIO_GPIO18)) result |= TIOCM_CTS; } else { result = TIOCM_CTS; @@ -269,39 +170,54 @@ { if (port->mapbase == _Ser1UTCR0) { if (mctrl & TIOCM_RTS) - GPCR = GPIO_GC_UART0_RTS; + GPCR = GPIO_GPIO15; else - GPSR = GPIO_GC_UART0_RTS; + GPSR = GPIO_GPIO15; } else if (port->mapbase == _Ser2UTCR0) { if (mctrl & TIOCM_RTS) - GPCR = GPIO_GC_UART1_RTS; + GPCR = GPIO_GPIO17; else - GPSR = GPIO_GC_UART1_RTS; + GPSR = GPIO_GPIO17; } else if (port->mapbase == _Ser3UTCR0) { if (mctrl & TIOCM_RTS) - GPCR = GPIO_GC_UART2_RTS; + GPCR = GPIO_GPIO19; else - GPSR = GPIO_GC_UART2_RTS; + GPSR = GPIO_GPIO19; } } static void graphicsclient_uart_pm(struct uart_port *port, u_int state, u_int oldstate) { - if (!state) { - /* make serial ports work ... */ - Ser2UTCR4 = 0; - Ser2HSCR0 = 0; - Ser1SDCR0 |= SDCR0_UART; + // state has ACPI D0-D3 + // ACPI D0 : resume from suspend + // ACPI D1-D3 : enter to a suspend state + if (port->mapbase == _Ser1UTCR0) { + if (state) { + // disable uart + Ser1UTCR3 = 0; + } + } + else if (port->mapbase == _Ser2UTCR0) { + if (state) { + // disable uart + Ser2UTCR3 = 0; + Ser2HSCR0 = 0; + } + } + else if (port->mapbase == _Ser3UTCR0) { + if (state) { + // disable uart + Ser3UTCR3 = 0; + } } } static struct sa1100_port_fns graphicsclient_port_fns __initdata = { - open: graphicsclient_uart_open, - close: graphicsclient_uart_close, - get_mctrl: graphicsclient_get_mctrl, - set_mctrl: graphicsclient_set_mctrl, - pm: graphicsclient_uart_pm, + .open = graphicsclient_uart_open, + .get_mctrl = graphicsclient_get_mctrl, + .set_mctrl = graphicsclient_set_mctrl, + .pm = graphicsclient_uart_pm, }; static void __init graphicsclient_map_io(void) @@ -312,14 +228,20 @@ sa1100_register_uart_fns(&graphicsclient_port_fns); sa1100_register_uart(0, 3); sa1100_register_uart(1, 1); + + // don't register if you want to use IRDA +#ifndef CONFIG_SA1100_FIR sa1100_register_uart(2, 2); - GPDR |= GPIO_GC_UART0_RTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS; - GPDR &= ~(GPIO_GC_UART0_CTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS); +#endif + + /* set GPDR now */ + GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19; + GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18); } MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient") + BOOT_PARAMS(0xc000003c) BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_graphicsclient) MAPIO(graphicsclient_map_io) INITIRQ(graphicsclient_init_irq) MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/graphicsmaster.c linux-2.4.22/arch/arm/mach-sa1100/graphicsmaster.c --- linux-2.4.21/arch/arm/mach-sa1100/graphicsmaster.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/graphicsmaster.c 2003-08-25 04:44:39.000000000 -0700 @@ -12,8 +12,13 @@ #include #include #include +#include +#include +#include +#include #include +#include #include #include @@ -40,6 +45,15 @@ */ sa1110_mb_disable(); + /* GraphicsMaster uses GPIO pins for SPI interface to AVR + */ + + /* use the alternate SSP pins */ + PPAR |= PPAR_SSPGPIO; + + // Set RTS low during sleep + PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19; + /* * Probe for SA1111. */ @@ -67,9 +81,11 @@ * Enable PWM control for LCD */ SKPCR |= SKPCR_PWMCLKEN; - SKPWM0 = 0x7F; // VEE + SACR1 &= ~SACR1_L3EN; + ADS_DCR |= DCR_BACKLITE_ON; + SKPWM0 = 0x01; // Backlight SKPEN0 = 1; - SKPWM1 = 0x01; // Backlight + SKPWM1 = 0x7F; // VEE SKPEN1 = 1; /* @@ -83,7 +99,7 @@ */ sa1110_mb_enable(); - sa1111_init_irq(ADS_EXT_IRQ(0)); + sa1111_init_irq(IRQ_GRAPHICSMASTER_SA1111); return 0; } @@ -94,56 +110,58 @@ * Handlers for GraphicsMaster's external IRQ logic */ +#define GRAPHICSMASTER_N_IRQ (IRQ_GRAPHICSMASTER_END - IRQ_GRAPHICSMASTER_START) + static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs ) { int i; while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){ - for( i = 0; i < 16; i++ ) + for( i = 0; i < GRAPHICSMASTER_N_IRQ; i++ ) if( irq & (1<nr_banks = 1; - SET_BANK( 1, 0xc8000000, 16*1024*1024 ); - mi->nr_banks = 2; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); -} - static struct map_desc graphicsmaster_io_desc[] __initdata = { /* virtual physical length domain r w c b */ { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */ @@ -212,17 +214,9 @@ if (port->mapbase == _Ser1UTCR0) { Ser1SDCR0 |= SDCR0_UART; - /* Set RTS Output */ - GPSR = GPIO_GPIO15; } else if (port->mapbase == _Ser2UTCR0) { Ser2UTCR4 = Ser2HSCR0 = 0; - /* Set RTS Output */ - GPSR = GPIO_GPIO17; - } - else if (port->mapbase == _Ser3UTCR0) { - /* Set RTS Output */ - GPSR = GPIO_GPIO19; } return ret; } @@ -238,7 +232,7 @@ if (!(GPLR & GPIO_GPIO16)) result |= TIOCM_CTS; } else if (port->mapbase == _Ser3UTCR0) { - if (!(GPLR & GPIO_GPIO17)) + if (!(GPLR & GPIO_GPIO18)) result |= TIOCM_CTS; } else { result = TIOCM_CTS; @@ -270,19 +264,35 @@ static void graphicsmaster_uart_pm(struct uart_port *port, u_int state, u_int oldstate) { - if (!state) { - /* make serial ports work ... */ - Ser2UTCR4 = 0; - Ser2HSCR0 = 0; - Ser1SDCR0 |= SDCR0_UART; + // state has ACPI D0-D3 + // ACPI D0 : resume from suspend + // ACPI D1-D3 : enter to a suspend state + if (port->mapbase == _Ser1UTCR0) { + if (state) { + // disable uart + Ser1UTCR3 = 0; + } + } + else if (port->mapbase == _Ser2UTCR0) { + if (state) { + // disable uart + Ser2UTCR3 = 0; + Ser2HSCR0 = 0; + } + } + else if (port->mapbase == _Ser3UTCR0) { + if (state) { + // disable uart + Ser3UTCR3 = 0; + } } } static struct sa1100_port_fns graphicsmaster_port_fns __initdata = { - open: graphicsmaster_uart_open, - get_mctrl: graphicsmaster_get_mctrl, - set_mctrl: graphicsmaster_set_mctrl, - pm: graphicsmaster_uart_pm, + .open = graphicsmaster_uart_open, + .get_mctrl = graphicsmaster_get_mctrl, + .set_mctrl = graphicsmaster_set_mctrl, + .pm = graphicsmaster_uart_pm, }; static void __init graphicsmaster_map_io(void) @@ -293,7 +303,10 @@ sa1100_register_uart_fns(&graphicsmaster_port_fns); sa1100_register_uart(0, 3); sa1100_register_uart(1, 1); + // don't register if you want to use IRDA +#ifndef CONFIG_SA1100_FIR sa1100_register_uart(2, 2); +#endif /* set GPDR now */ GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19; @@ -301,8 +314,8 @@ } MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster") + BOOT_PARAMS(0xc000003c) BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_graphicsmaster) MAPIO(graphicsmaster_map_io) INITIRQ(graphicsmaster_init_irq) MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/h3600.c linux-2.4.22/arch/arm/mach-sa1100/h3600.c --- linux-2.4.21/arch/arm/mach-sa1100/h3600.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/h3600.c 2003-08-25 04:44:39.000000000 -0700 @@ -394,16 +394,16 @@ static void h3600_dcd_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct uart_info *info = dev_id; + struct uart_port *port = dev_id; /* Note: should only call this if something has changed */ - uart_handle_dcd_change(info, !(GPLR & GPIO_H3600_COM_DCD)); + uart_handle_dcd_change(port, !(GPLR & GPIO_H3600_COM_DCD)); } static void h3600_cts_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct uart_info *info = dev_id; + struct uart_port *port = dev_id; /* Note: should only call this if something has changed */ - uart_handle_cts_change(info, !(GPLR & GPIO_H3600_COM_CTS)); + uart_handle_cts_change(port, !(GPLR & GPIO_H3600_COM_CTS)); } static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate) @@ -433,7 +433,7 @@ return err; } -static int h3600_uart_open(struct uart_port *port, struct uart_info *info) +static int h3600_uart_open(struct uart_port *port) { int ret = 0; @@ -447,23 +447,23 @@ GPIO_BOTH_EDGES); ret = request_irq(IRQ_GPIO_H3600_COM_DCD, h3600_dcd_intr, - 0, "RS232 DCD", info); + 0, "RS232 DCD", port); if (ret) return ret; ret = request_irq(IRQ_GPIO_H3600_COM_CTS, h3600_cts_intr, - 0, "RS232 CTS", info); + 0, "RS232 CTS", port); if (ret) - free_irq(IRQ_GPIO_H3600_COM_DCD, info); + free_irq(IRQ_GPIO_H3600_COM_DCD, port); } return ret; } -static void h3600_uart_close(struct uart_port *port, struct uart_info *info) +static void h3600_uart_close(struct uart_port *port) { if (port->mapbase == _Ser3UTCR0) { - free_irq(IRQ_GPIO_H3600_COM_DCD, info); - free_irq(IRQ_GPIO_H3600_COM_CTS, info); + free_irq(IRQ_GPIO_H3600_COM_DCD, port); + free_irq(IRQ_GPIO_H3600_COM_CTS, port); } } diff -urN linux-2.4.21/arch/arm/mach-sa1100/hackkit.c linux-2.4.22/arch/arm/mach-sa1100/hackkit.c --- linux-2.4.21/arch/arm/mach-sa1100/hackkit.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/hackkit.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,221 @@ +/* + * linux/arch/arm/mach-sa1100/hackkit.c + * + * Copyright (C) 2002 Stefan Eletzhofer + * + * This file contains all HackKit tweaks. Based on original work from + * Nicolas Pitre's assabet fixes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include "generic.h" + +#define DEBUG 1 + +#ifdef DEBUG +# define DPRINTK( x, args... ) printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args ); +#else +# define DPRINTK( x, args... ) /* nix */ +#endif + +/********************************************************************** + * prototypes + */ + +/* init funcs */ +static void __init fixup_hackkit(struct machine_desc *desc, + struct param_struct *params, char **cmdline, struct meminfo *mi); +static void __init get_hackkit_scr(void); +static int __init hackkit_init(void); +static void __init hackkit_init_irq(void); +static void __init hackkit_map_io(void); + +static int hackkit_get_mctrl(struct uart_port *port); +static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl); +static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate); + +extern void convert_to_tag_list(struct param_struct *params, int mem_init); + + +/********************************************************************** + * global data + */ + +/********************************************************************** + * static data + */ + +static struct map_desc hackkit_io_desc[] __initdata = { + /* virtual physical length domain r w c b */ + { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */ + LAST_DESC +}; + +static struct sa1100_port_fns hackkit_port_fns __initdata = { + .set_mctrl = hackkit_set_mctrl, + .get_mctrl = hackkit_get_mctrl, + .pm = hackkit_uart_pm, +}; + +/********************************************************************** + * Static functions + */ + +static void __init hackkit_map_io(void) +{ + DPRINTK( "%s\n", "START" ); + sa1100_map_io(); + iotable_init(hackkit_io_desc); + + sa1100_register_uart_fns(&hackkit_port_fns); + sa1100_register_uart(0, 1); /* com port */ + sa1100_register_uart(1, 2); + sa1100_register_uart(2, 3); /* radio module */ + + Ser1SDCR0 |= SDCR0_SUS; +} + +static void __init hackkit_init_irq(void) +{ + /* none used yet */ +} + +/** + * fixup_hackkit - fixup function for system 3 board + * @desc: machine description + * @param: kernel params + * @cmdline: kernel cmdline + * @mi: memory info struct + * + */ +static void __init fixup_hackkit(struct machine_desc *desc, + struct param_struct *params, char **cmdline, struct meminfo *mi) +{ + DPRINTK( "%s\n", "START" ); + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( 0xc0800000, 8*1024*1024 ); +} + + +/** + * hackkit_uart_pm - powermgmt callback function for system 3 UART + * @port: uart port structure + * @state: pm state + * @oldstate: old pm state + * + */ +static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + /* TODO: switch on/off uart in powersave mode */ +} + +/* + * Note! this can be called from IRQ context. + * FIXME: No modem ctrl lines yet. + */ +static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl) +{ +#if 0 + if (port->mapbase == _Ser1UTCR0) { + u_int set = 0, clear = 0; + + if (mctrl & TIOCM_RTS) + set |= PT_CTRL2_RS1_RTS; + else + clear |= PT_CTRL2_RS1_RTS; + + if (mctrl & TIOCM_DTR) + set |= PT_CTRL2_RS1_DTR; + else + clear |= PT_CTRL2_RS1_DTR; + + PTCTRL2_clear(clear); + PTCTRL2_set(set); + } +#endif +} + +static int hackkit_get_mctrl(struct uart_port *port) +{ + u_int ret = 0; +#if 0 + u_int irqsr = PT_IRQSR; + + /* need 2 reads to read current value */ + irqsr = PT_IRQSR; + + /* TODO: check IRQ source register for modem/com + status lines and set them correctly. */ +#endif + + ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; + + return ret; +} + +static int __init hackkit_init(void) +{ + int ret = 0; + DPRINTK( "%s\n", "START" ); + + if ( !machine_is_hackkit() ) { + ret = -EINVAL; + goto DONE; + } + + hackkit_init_irq(); + + ret = 0; +DONE: + DPRINTK( "ret=%d\n", ret ); + return ret; +} + +/********************************************************************** + * Exported Functions + */ + +/********************************************************************** + * kernel magic macros + */ +__initcall(hackkit_init); + +MACHINE_START(HACKKIT, "HackKit Cpu Board") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_hackkit) + MAPIO(hackkit_map_io) + INITIRQ(sa1100_init_irq) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/irq.c linux-2.4.22/arch/arm/mach-sa1100/irq.c --- linux-2.4.21/arch/arm/mach-sa1100/irq.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -30,9 +32,9 @@ * This must be called *before* the appropriate IRQ is registered. * Use this instead of directly setting GRER/GFER. */ - static int GPIO_IRQ_rising_edge; static int GPIO_IRQ_falling_edge; +static int GPIO_IRQ_mask = (1 << 11) - 1; void set_GPIO_IRQ_edge(int gpio_mask, int edge) { @@ -51,6 +53,8 @@ GPIO_IRQ_rising_edge &= ~gpio_mask; GPDR &= ~gpio_mask; GAFR &= ~gpio_mask; + GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; + GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; while (gpio_mask) { if (irq == 11) irq = IRQ_GPIO11; @@ -86,8 +90,10 @@ static void sa1100_mask_and_ack_GPIO0_10_irq(unsigned int irq) { - ICMR &= ~(1 << irq); - GEDR = (1 << irq); + unsigned int mask = 1 << irq; + + ICMR &= ~mask; + GEDR = mask; } static void sa1100_mask_GPIO0_10_irq(unsigned int irq) @@ -97,16 +103,13 @@ static void sa1100_unmask_GPIO0_10_irq(unsigned int irq) { - GRER = (GRER & ~(1 << irq)) | (GPIO_IRQ_rising_edge & (1 << irq)); - GFER = (GFER & ~(1 << irq)) | (GPIO_IRQ_falling_edge & (1 << irq)); - ICMR |= (1 << irq); + ICMR |= 1 << irq; } /* * Install handler for GPIO 11-27 edge detect interrupts */ -static int GPIO_11_27_enabled; /* enabled i.e. unmasked GPIO IRQs */ static int GPIO_11_27_spurious; /* GPIOs that triggered when masked */ static void sa1100_GPIO11_27_demux(int irq, void *dev_id, @@ -124,7 +127,7 @@ * enabled at this point are considered spurious. Those * are cleared but only de-activated if they happen twice. */ - spurious = irq & ~GPIO_11_27_enabled; + spurious = irq & ~GPIO_IRQ_mask; if (spurious) { GEDR = spurious; GRER &= ~(spurious & GPIO_11_27_spurious); @@ -143,29 +146,29 @@ } static struct irqaction GPIO11_27_irq = { - name: "GPIO 11-27", - handler: sa1100_GPIO11_27_demux, - flags: SA_INTERRUPT + .name = "GPIO 11-27", + .handler = sa1100_GPIO11_27_demux, + .flags = SA_INTERRUPT }; static void sa1100_mask_and_ack_GPIO11_27_irq(unsigned int irq) { - int mask = (1 << GPIO_11_27_IRQ(irq)); + unsigned int mask = (1 << GPIO_11_27_IRQ(irq)); GPIO_11_27_spurious &= ~mask; - GPIO_11_27_enabled &= ~mask; + GPIO_IRQ_mask &= ~mask; GEDR = mask; } static void sa1100_mask_GPIO11_27_irq(unsigned int irq) { - int mask = (1 << GPIO_11_27_IRQ(irq)); + unsigned int mask = (1 << GPIO_11_27_IRQ(irq)); GPIO_11_27_spurious &= ~mask; - GPIO_11_27_enabled &= ~mask; + GPIO_IRQ_mask &= ~mask; } static void sa1100_unmask_GPIO11_27_irq(unsigned int irq) { - int mask = (1 << GPIO_11_27_IRQ(irq)); + unsigned int mask = (1 << GPIO_11_27_IRQ(irq)); if (GPIO_11_27_spurious & mask) { /* * We don't want to miss an interrupt that would have occurred @@ -185,15 +188,17 @@ return; } } - GPIO_11_27_enabled |= mask; - GRER = (GRER & ~mask) | (GPIO_IRQ_rising_edge & mask); - GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask); + + GPIO_IRQ_mask |= mask; + + GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; + GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; } static struct resource irq_resource = { - name: "irqs", - start: 0x90050000, - end: 0x9005ffff, + .name = "irqs", + .start = 0x90050000, + .end = 0x9005ffff, }; void __init sa1100_init_irq(void) @@ -248,10 +253,4 @@ irq_desc[irq].unmask = sa1100_unmask_GPIO11_27_irq; } setup_arm_irq( IRQ_GPIO11_27, &GPIO11_27_irq ); - - /* - * We generally don't want the LCD IRQ being - * enabled as soon as we request it. - */ - irq_desc[IRQ_LCD].noautoenable = 1; } diff -urN linux-2.4.21/arch/arm/mach-sa1100/jornada720.c linux-2.4.22/arch/arm/mach-sa1100/jornada720.c --- linux-2.4.21/arch/arm/mach-sa1100/jornada720.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/jornada720.c 2003-08-25 04:44:39.000000000 -0700 @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include @@ -34,7 +36,7 @@ udelay(1); GPSR = GPIO_GPIO20; udelay(20); - SKCR = JORSKCR_INIT; /* Turn on the PLL, enable Ready and enable nOE assertion from DC */ + SBI_SKCR = JORSKCR_INIT;/* Turn on the PLL, enable Ready and enable nOE assertion from DC */ mdelay(100); SBI_SKCR = JORSKCR_RCLK;/* turn on the RCLOCK */ diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds-adsagc.c linux-2.4.22/arch/arm/mach-sa1100/leds-adsagc.c --- linux-2.4.21/arch/arm/mach-sa1100/leds-adsagc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/leds-adsagc.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,107 @@ +/* + * linux/arch/arm/mach-sa1100/leds-adsagc.c + * + * ADS Advanced Graphics Client LEDs support + * Robert Whaley, Feb 7, 2003 + */ +#include +#include + +#include +#include +#include + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_TIMER ADS_LED0 /* green heartbeat */ +#define LED_USER ADS_LED1 /* amber, boots to on */ +#define LED_IDLE ADS_LED2 /* red has the idle led, if any */ + +#define LED_MASK (ADS_LED0|ADS_LED1|ADS_LED2) + +void adsagc_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = 0; /* gc leds are positive logic */ + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_TIMER; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_IDLE; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_IDLE; + break; +#endif + + case led_green_on: + break; + + case led_green_off: + break; + + case led_amber_on: + hw_led_state |= LED_USER; + break; + + case led_amber_off: + hw_led_state &= ~LED_USER; + break; + + case led_red_on: + break; + + case led_red_off: + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) { + + unsigned char ads_cr3 = ADS_CR3; + ads_cr3 &= ~LED_MASK; + ads_cr3 |= hw_led_state; + ADS_CR3 = ads_cr3; + } + + local_irq_restore(flags); +} diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsy.c linux-2.4.22/arch/arm/mach-sa1100/leds-adsbitsy.c --- linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsy.c 2001-10-25 13:53:46.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/leds-adsbitsy.c 2003-08-25 04:44:39.000000000 -0700 @@ -28,7 +28,7 @@ { unsigned long flags; - save_flags_cli(flags); + local_irq_save(flags); switch (evt) { case led_start: @@ -92,5 +92,5 @@ GPCR = hw_led_state ^ LED_MASK; } - restore_flags(flags); + local_irq_restore(flags); } diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsyplus.c linux-2.4.22/arch/arm/mach-sa1100/leds-adsbitsyplus.c --- linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsyplus.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/leds-adsbitsyplus.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,97 @@ +/* + * linux/arch/arm/mach-sa1100/leds-adsbitsy.c + * + * ADS Bitsy LED + * 2/7/2003 Robert Whaley + * This file comes from leds-adsbitsy.c of Woojung Huh + */ +#include +#include + +#include +#include +#include + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_TIMER GPIO_GPIO20 /* green heartbeat */ + +#define LED_MASK (LED_TIMER) + +void adsbitsyplus_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = 0; /* gc leds are positive logic */ + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_TIMER; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + break; + + case led_idle_end: + break; +#endif + + case led_green_on: + break; + + case led_green_off: + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + break; + + case led_red_off: + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + local_irq_restore(flags); +} diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds-frodo.c linux-2.4.22/arch/arm/mach-sa1100/leds-frodo.c --- linux-2.4.21/arch/arm/mach-sa1100/leds-frodo.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/leds-frodo.c 2003-08-25 04:44:39.000000000 -0700 @@ -22,22 +22,22 @@ #include "leds.h" -#define led6_on() FRODO_CPLD_GENERAL |= FRODO_LED2 -#define led6_off() FRODO_CPLD_GENERAL &= ~FRODO_LED2 -#define led6_invert() do { \ - if ((FRODO_CPLD_GENERAL & FRODO_LED2)) \ - led6_off (); \ - else \ - led6_on (); \ +#define led6_on() frodo_cpld_set (FRODO_CPLD_GENERAL,FRODO_LED2) +#define led6_off() frodo_cpld_clear (FRODO_CPLD_GENERAL,FRODO_LED2) +#define led6_invert() do { \ + if ((frodo_cpld_read (FRODO_CPLD_GENERAL) & FRODO_LED2)) \ + led6_off (); \ + else \ + led6_on (); \ } while (0) -#define led7_on() FRODO_CPLD_GENERAL |= FRODO_LED1 -#define led7_off() FRODO_CPLD_GENERAL &= ~FRODO_LED1 +#define led7_on() frodo_cpld_set (FRODO_CPLD_GENERAL,FRODO_LED1) +#define led7_off() frodo_cpld_clear (FRODO_CPLD_GENERAL,FRODO_LED1) #define led7_invert() do { \ - if ((FRODO_CPLD_GENERAL & FRODO_LED1)) \ - led7_off (); \ - else \ - led7_on (); \ + if ((frodo_cpld_read (FRODO_CPLD_GENERAL) & FRODO_LED1)) \ + led7_off (); \ + else \ + led7_on (); \ } while (0) static int claimed; diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsclient.c linux-2.4.22/arch/arm/mach-sa1100/leds-graphicsclient.c --- linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsclient.c 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/leds-graphicsclient.c 2003-08-25 04:44:39.000000000 -0700 @@ -30,7 +30,7 @@ { unsigned long flags; - save_flags_cli(flags); + local_irq_save(flags); switch (evt) { case led_start: @@ -100,5 +100,5 @@ GPCR = hw_led_state ^ LED_MASK; } - restore_flags(flags); + local_irq_restore(flags); } diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsmaster.c linux-2.4.22/arch/arm/mach-sa1100/leds-graphicsmaster.c --- linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsmaster.c 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/leds-graphicsmaster.c 2003-08-25 04:44:39.000000000 -0700 @@ -30,7 +30,7 @@ { unsigned long flags; - save_flags_cli(flags); + local_irq_save(flags); switch (evt) { case led_start: @@ -100,5 +100,5 @@ GPCR = hw_led_state ^ LED_MASK; } - restore_flags(flags); + local_irq_restore(flags); } diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds-hackkit.c linux-2.4.22/arch/arm/mach-sa1100/leds-hackkit.c --- linux-2.4.21/arch/arm/mach-sa1100/leds-hackkit.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/leds-hackkit.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,113 @@ +/* + * linux/arch/arm/mach-sa1100/leds-hackkit.c + * + * based on leds-lart.c + * + * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000 + * (C) Stefan Eletzhofer , 2002 + * + * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used + * as cpu led, the green one is used as timer led. + */ +#include +#include + +#include +#include +#include + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_GREEN GPIO_GPIO23 +#define LED_RED GPIO_GPIO22 +#define LED_MASK (LED_RED | LED_GREEN) + +void hackkit_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch(evt) { + case led_start: + /* pin 22/23 are outputs */ + GPDR |= LED_MASK; + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + /* The LART people like the LED to be off when the + system is idle... */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + /* ... and on if the system is not idle */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; +#endif + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + default: + break; + } + + /* Now set the GPIO state, or nothing will happen at all */ + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + local_irq_restore(flags); +} diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds.c linux-2.4.22/arch/arm/mach-sa1100/leds.c --- linux-2.4.21/arch/arm/mach-sa1100/leds.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/leds.c 2003-08-25 04:44:39.000000000 -0700 @@ -15,8 +15,12 @@ static int __init sa1100_leds_init(void) { + if (machine_is_adsagc()) + leds_event = adsagc_leds_event; if (machine_is_adsbitsy()) leds_event = adsbitsy_leds_event; + if (machine_is_adsbitsyplus()) + leds_event = adsbitsyplus_leds_event; if (machine_is_assabet()) leds_event = assabet_leds_event; if (machine_is_consus()) @@ -33,6 +37,8 @@ leds_event = graphicsclient_leds_event; if (machine_is_graphicsmaster()) leds_event = graphicsmaster_leds_event; + if (machine_is_hackkit()) + leds_event = hackkit_leds_event; if (machine_is_lart()) leds_event = lart_leds_event; if (machine_is_pfs168()) diff -urN linux-2.4.21/arch/arm/mach-sa1100/leds.h linux-2.4.22/arch/arm/mach-sa1100/leds.h --- linux-2.4.21/arch/arm/mach-sa1100/leds.h 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/leds.h 2003-08-25 04:44:39.000000000 -0700 @@ -1,12 +1,15 @@ +extern void adsagc_leds_event(led_event_t evt); +extern void adsbitsy_leds_event(led_event_t evt); +extern void adsbitsyplus_leds_event(led_event_t evt); extern void assabet_leds_event(led_event_t evt); extern void consus_leds_event(led_event_t evt); extern void brutus_leds_event(led_event_t evt); extern void cerf_leds_event(led_event_t evt); extern void flexanet_leds_event(led_event_t evt); +extern void frodo_leds_event(led_event_t evt); extern void graphicsclient_leds_event(led_event_t evt); +extern void graphicsmaster_leds_event(led_event_t evt); +extern void hackkit_leds_event(led_event_t evt); extern void lart_leds_event(led_event_t evt); extern void pfs168_leds_event(led_event_t evt); -extern void graphicsmaster_leds_event(led_event_t evt); -extern void adsbitsy_leds_event(led_event_t evt); extern void system3_leds_event(led_event_t evt); -extern void frodo_leds_event(led_event_t evt); diff -urN linux-2.4.21/arch/arm/mach-sa1100/nanoengine.c linux-2.4.22/arch/arm/mach-sa1100/nanoengine.c --- linux-2.4.21/arch/arm/mach-sa1100/nanoengine.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/nanoengine.c 2003-08-25 04:44:39.000000000 -0700 @@ -16,22 +16,6 @@ #include "generic.h" -static void __init -fixup_nanoengine(struct machine_desc *desc, struct param_struct *params, - char **cmdline, struct meminfo *mi) -{ - SET_BANK( 0, 0xc0000000, 32*1024*1024 ); - mi->nr_banks = 1; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); - - /* Get command line parameters passed from the loader (if any) */ - if( *((char*)0xc0000100) ) - *cmdline = ((char *)0xc0000100); -} - static struct map_desc nanoengine_io_desc[] __initdata = { /* virtual physical length domain r w c b */ { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */ @@ -56,7 +40,7 @@ MACHINE_START(NANOENGINE, "BSE nanoEngine") BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_nanoengine) + BOOT_PARAMS(0xc0000100) MAPIO(nanoengine_map_io) INITIRQ(sa1100_init_irq) MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/neponset.c linux-2.4.22/arch/arm/mach-sa1100/neponset.c --- linux-2.4.21/arch/arm/mach-sa1100/neponset.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/neponset.c 2003-08-25 04:44:39.000000000 -0700 @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/mach-sa1100/pcipool.c linux-2.4.22/arch/arm/mach-sa1100/pcipool.c --- linux-2.4.21/arch/arm/mach-sa1100/pcipool.c 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/pcipool.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,377 +0,0 @@ -/* - NOTE: - - this code was lifted straight out of drivers/pci/pci.c; - when compiling for the Intel StrongARM SA-1110/SA-1111 the - usb-ohci.c driver needs these routines even when the architecture - has no pci bus... -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "pcipool.h" - -/* - * Pool allocator ... wraps the pci_alloc_consistent page allocator, so - * small blocks are easily used by drivers for bus mastering controllers. - * This should probably be sharing the guts of the slab allocator. - */ - -struct pci_pool { /* the pool */ - struct list_head page_list; - spinlock_t lock; - size_t blocks_per_page; - size_t size; - int flags; - struct pci_dev *dev; - size_t allocation; - char name [32]; - wait_queue_head_t waitq; -}; - -struct pci_page { /* cacheable header for 'allocation' bytes */ - struct list_head page_list; - void *vaddr; - dma_addr_t dma; - unsigned long bitmap [0]; -}; - -#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) -#define POOL_POISON_BYTE 0xa7 - -// #define CONFIG_PCIPOOL_DEBUG - - -/** - * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma. - * @name: name of pool, for diagnostics - * @pdev: pci device that will be doing the DMA - * @size: size of the blocks in this pool. - * @align: alignment requirement for blocks; must be a power of two - * @allocation: returned blocks won't cross this boundary (or zero) - * @flags: SLAB_* flags (not all are supported). - * - * Returns a pci allocation pool with the requested characteristics, or - * null if one can't be created. Given one of these pools, pci_pool_alloc() - * may be used to allocate memory. Such memory will all have "consistent" - * DMA mappings, accessible by the device and its driver without using - * cache flushing primitives. The actual size of blocks allocated may be - * larger than requested because of alignment. - * - * If allocation is nonzero, objects returned from pci_pool_alloc() won't - * cross that size boundary. This is useful for devices which have - * addressing restrictions on individual DMA transfers, such as not crossing - * boundaries of 4KBytes. - */ -struct pci_pool * -pci_pool_create (const char *name, struct pci_dev *pdev, - size_t size, size_t align, size_t allocation, int flags) -{ - struct pci_pool *retval; - - if (align == 0) - align = 1; - if (size == 0) - return 0; - else if (size < align) - size = align; - else if ((size % align) != 0) { - size += align + 1; - size &= ~(align - 1); - } - - if (allocation == 0) { - if (PAGE_SIZE < size) - allocation = size; - else - allocation = PAGE_SIZE; - // FIXME: round up for less fragmentation - } else if (allocation < size) - return 0; - - if (!(retval = kmalloc (sizeof *retval, flags))) - return retval; - -#ifdef CONFIG_PCIPOOL_DEBUG - flags |= SLAB_POISON; -#endif - - strncpy (retval->name, name, sizeof retval->name); - retval->name [sizeof retval->name - 1] = 0; - - retval->dev = pdev; - INIT_LIST_HEAD (&retval->page_list); - spin_lock_init (&retval->lock); - retval->size = size; - retval->flags = flags; - retval->allocation = allocation; - retval->blocks_per_page = allocation / size; - init_waitqueue_head (&retval->waitq); - -#ifdef CONFIG_PCIPOOL_DEBUG - printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n", - pdev ? pdev->slot_name : NULL, retval->name, size, - retval->blocks_per_page, allocation); -#endif - - return retval; -} - - -static struct pci_page * -pool_alloc_page (struct pci_pool *pool, int mem_flags) -{ - struct pci_page *page; - int mapsize; - - mapsize = pool->blocks_per_page; - mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG; - mapsize *= sizeof (long); - - page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags); - if (!page) - return 0; - page->vaddr = pci_alloc_consistent (pool->dev, - pool->allocation, &page->dma); - if (page->vaddr) { - memset (page->bitmap, 0xff, mapsize); // bit set == free - if (pool->flags & SLAB_POISON) - memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); - list_add (&page->page_list, &pool->page_list); - } else { - kfree (page); - page = 0; - } - return page; -} - - -static inline int -is_page_busy (int blocks, unsigned long *bitmap) -{ - while (blocks > 0) { - if (*bitmap++ != ~0UL) - return 1; - blocks -= BITS_PER_LONG; - } - return 0; -} - -static void -pool_free_page (struct pci_pool *pool, struct pci_page *page) -{ - dma_addr_t dma = page->dma; - - if (pool->flags & SLAB_POISON) - memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); - pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma); - list_del (&page->page_list); - kfree (page); -} - - -/** - * pci_pool_destroy - destroys a pool of pci memory blocks. - * @pool: pci pool that will be destroyed - * - * Caller guarantees that no more memory from the pool is in use, - * and that nothing will try to use the pool after this call. - */ -void -pci_pool_destroy (struct pci_pool *pool) -{ - unsigned long flags; - -#ifdef CONFIG_PCIPOOL_DEBUG - printk (KERN_DEBUG "pcipool destroy %s/%s\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name); -#endif - - spin_lock_irqsave (&pool->lock, flags); - while (!list_empty (&pool->page_list)) { - struct pci_page *page; - page = list_entry (pool->page_list.next, - struct pci_page, page_list); - if (is_page_busy (pool->blocks_per_page, page->bitmap)) { - printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name, page->vaddr); - /* leak the still-in-use consistent memory */ - list_del (&page->page_list); - kfree (page); - } else - pool_free_page (pool, page); - } - spin_unlock_irqrestore (&pool->lock, flags); - kfree (pool); -} - - -/** - * pci_pool_alloc - get a block of consistent memory - * @pool: pci pool that will produce the block - * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC - * @handle: pointer to dma address of block - * - * This returns the kernel virtual address of a currently unused block, - * and reports its dma address through the handle. - * If such a memory block can't be allocated, null is returned. - */ -void * -pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle) -{ - unsigned long flags; - struct list_head *entry; - struct pci_page *page; - int map, block; - size_t offset; - void *retval; - -restart: - spin_lock_irqsave (&pool->lock, flags); - list_for_each (entry, &pool->page_list) { - int i; - page = list_entry (entry, struct pci_page, page_list); - /* only cachable accesses here ... */ - for (map = 0, i = 0; - i < pool->blocks_per_page; - i += BITS_PER_LONG, map++) { - if (page->bitmap [map] == 0) - continue; - block = ffz (~ page->bitmap [map]); - if ((i + block) < pool->blocks_per_page) { - clear_bit (block, &page->bitmap [map]); - offset = (BITS_PER_LONG * map) + block; - offset *= pool->size; - goto ready; - } - } - } - if (!(page = pool_alloc_page (pool, mem_flags))) { - if (mem_flags == SLAB_KERNEL) { - DECLARE_WAITQUEUE (wait, current); - - current->state = TASK_INTERRUPTIBLE; - add_wait_queue (&pool->waitq, &wait); - spin_unlock_irqrestore (&pool->lock, flags); - - schedule_timeout (POOL_TIMEOUT_JIFFIES); - - current->state = TASK_RUNNING; - remove_wait_queue (&pool->waitq, &wait); - goto restart; - } - retval = 0; - goto done; - } - - clear_bit (0, &page->bitmap [0]); - offset = 0; -ready: - retval = offset + page->vaddr; - *handle = offset + page->dma; -done: - spin_unlock_irqrestore (&pool->lock, flags); - return retval; -} - - -static struct pci_page * -pool_find_page (struct pci_pool *pool, dma_addr_t dma) -{ - unsigned long flags; - struct list_head *entry; - struct pci_page *page; - - spin_lock_irqsave (&pool->lock, flags); - list_for_each (entry, &pool->page_list) { - page = list_entry (entry, struct pci_page, page_list); - if (dma < page->dma) - continue; - if (dma < (page->dma + pool->allocation)) - goto done; - } - page = 0; -done: - spin_unlock_irqrestore (&pool->lock, flags); - return page; -} - - -/** - * pci_pool_free - put block back into pci pool - * @pool: the pci pool holding the block - * @vaddr: virtual address of block - * @dma: dma address of block - * - * Caller promises neither device nor driver will again touch this block - * unless it is first re-allocated. - */ -void -pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) -{ - struct pci_page *page; - unsigned long flags; - int map, block; - - if ((page = pool_find_page (pool, dma)) == 0) { - printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name, vaddr, dma); - return; - } -#ifdef CONFIG_PCIPOOL_DEBUG - if (((dma - page->dma) + (void *)page->vaddr) != vaddr) { - printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name, vaddr, dma); - return; - } -#endif - - block = dma - page->dma; - block /= pool->size; - map = block / BITS_PER_LONG; - block %= BITS_PER_LONG; - -#ifdef CONFIG_PCIPOOL_DEBUG - if (page->bitmap [map] & (1UL << block)) { - printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name, dma); - return; - } -#endif - if (pool->flags & SLAB_POISON) - memset (vaddr, POOL_POISON_BYTE, pool->size); - - spin_lock_irqsave (&pool->lock, flags); - set_bit (block, &page->bitmap [map]); - if (waitqueue_active (&pool->waitq)) - wake_up (&pool->waitq); - /* - * Resist a temptation to do - * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page); - * it is not interrupt safe. Better have empty pages hang around. - */ - spin_unlock_irqrestore (&pool->lock, flags); -} - - -EXPORT_SYMBOL (pci_pool_create); -EXPORT_SYMBOL (pci_pool_destroy); -EXPORT_SYMBOL (pci_pool_alloc); -EXPORT_SYMBOL (pci_pool_free); - diff -urN linux-2.4.21/arch/arm/mach-sa1100/pcipool.h linux-2.4.22/arch/arm/mach-sa1100/pcipool.h --- linux-2.4.21/arch/arm/mach-sa1100/pcipool.h 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/pcipool.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,8 +0,0 @@ - -struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev, - size_t size, size_t align, size_t allocation, int flags); -void pci_pool_destroy (struct pci_pool *pool); - -void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle); -void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr); - diff -urN linux-2.4.21/arch/arm/mach-sa1100/pm.c linux-2.4.22/arch/arm/mach-sa1100/pm.c --- linux-2.4.21/arch/arm/mach-sa1100/pm.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/pm.c 2003-08-25 04:44:39.000000000 -0700 @@ -18,11 +18,13 @@ * 2001-08-29: Nicolas Pitre * Cleaned up, pushed platform dependent stuff * in the platform specific files. + * + * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array. + * Storage is local on the stack now. */ #include #include #include -#include #include #include #include @@ -33,7 +35,6 @@ #include #include -#include "sleep.h" /* * Debug macros @@ -43,20 +44,32 @@ extern void sa1100_cpu_suspend(void); extern void sa1100_cpu_resume(void); -extern unsigned long *sleep_save; /* virtual address */ -extern unsigned long sleep_save_p; /* physical address */ - #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] +/* + * List of global SA11x0 peripheral registers to preserve. + * More ones like CP and general purpose register values are preserved + * with the stack location in sleep.S. + */ +enum { SLEEP_SAVE_START = 0, + + SLEEP_SAVE_OSCR, SLEEP_SAVE_OIER, + SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3, + + SLEEP_SAVE_GPDR, SLEEP_SAVE_GRER, SLEEP_SAVE_GFER, SLEEP_SAVE_GAFR, + SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR, + + SLEEP_SAVE_ICMR, + SLEEP_SAVE_Ser1SDCR0, + + SLEEP_SAVE_SIZE +}; + + int pm_do_suspend(void) { - /* set up pointer to sleep parameters */ - sleep_save = kmalloc(SLEEP_SAVE_SIZE*sizeof(long), GFP_ATOMIC); - if (!sleep_save) - return -ENOMEM; - - sleep_save_p = virt_to_phys(sleep_save); + unsigned long sleep_save[SLEEP_SAVE_SIZE]; cli(); @@ -144,8 +157,6 @@ sti(); - kfree (sleep_save); - /* * Restore the CPU frequency settings. */ @@ -156,6 +167,11 @@ return 0; } +unsigned long sleep_phys_sp(void *sp) +{ + return virt_to_phys(sp); +} + #ifdef CONFIG_SYSCTL /* * ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than diff -urN linux-2.4.21/arch/arm/mach-sa1100/sa1111-pcibuf.c linux-2.4.22/arch/arm/mach-sa1100/sa1111-pcibuf.c --- linux-2.4.21/arch/arm/mach-sa1100/sa1111-pcibuf.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/sa1111-pcibuf.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,272 +1,400 @@ /* * linux/arch/arm/mach-sa1100/pci-sa1111.c * - * Special pci_map/unmap_single routines for SA-1111. These functions - * compensate for a bug in the SA-1111 hardware which don't allow DMA - * to/from addresses above 1MB. + * Special pci_{map/unmap/dma_sync}_* routines for SA-1111. * - * Brad Parker (brad@heeltoe.com) + * These functions utilize bouncer buffers to compensate for a bug in + * the SA-1111 hardware which don't allow DMA to/from addresses + * certain addresses above 1MB. * - * 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. + * Re-written by Christopher Hoover + * Original version by Brad Parker (brad@heeltoe.com) * - * 06/13/2001 - created. - */ + * Copyright (C) 2002 Hewlett Packard Company. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * */ + #include #include #include #include +#include +#include +//#define DEBUG +#ifdef DEBUG +#define DPRINTK(...) do { printk(KERN_DEBUG __VA_ARGS__); } while (0) +#else +#define DPRINTK(...) do { } while (0) +#endif + +struct safe_buffer { + struct list_head node; + + /* original request */ + void *ptr; + size_t size; + int direction; -#include "pcipool.h" + /* safe buffer info */ + struct pci_pool *pool; + void *safe; + dma_addr_t safe_dma_addr; +}; -/* - * simple buffer allocator for copying of unsafe to safe buffers - * uses __alloc/__free for actual buffers - * keeps track of safe buffers we've allocated so we can recover the - * unsafe buffers. - */ +LIST_HEAD(safe_buffers); -#define MAX_SAFE 32 #define SIZE_SMALL 1024 #define SIZE_LARGE (16*1024) -static long mapped_alloc_size; -static char *safe_buffers[MAX_SAFE][2]; - - -static struct pci_pool *small_buffer_cache, *large_buffer_cache; +static struct pci_pool *small_buffer_pool, *large_buffer_pool; -static int -init_safe_buffers(struct pci_dev *dev) +static int __init +create_safe_buffer_pools(void) { - small_buffer_cache = pci_pool_create("pci_small_buffer", - dev, + small_buffer_pool = pci_pool_create("sa1111_small_dma_buffer", + SA1111_FAKE_PCIDEV, SIZE_SMALL, 0 /* byte alignment */, 0 /* no page-crossing issues */, - GFP_KERNEL | GFP_DMA); - - if (small_buffer_cache == 0) + SLAB_KERNEL); + if (0 == small_buffer_pool) { + printk(KERN_ERR + "sa1111_pcibuf: could not allocate small pci pool\n"); return -1; + } - large_buffer_cache = pci_pool_create("pci_large_buffer", - dev, + large_buffer_pool = pci_pool_create("sa1111_large_dma_buffer", + SA1111_FAKE_PCIDEV, SIZE_LARGE, 0 /* byte alignment */, 0 /* no page-crossing issues */, - GFP_KERNEL | GFP_DMA); - if (large_buffer_cache == 0) + SLAB_KERNEL); + if (0 == large_buffer_pool) { + printk(KERN_ERR + "sa1111_pcibuf: could not allocate large pci pool\n"); + pci_pool_destroy(small_buffer_pool); + small_buffer_pool = 0; return -1; + } return 0; } +static void __exit +destroy_safe_buffer_pools(void) +{ + if (small_buffer_pool) + pci_pool_destroy(small_buffer_pool); + if (large_buffer_pool) + pci_pool_destroy(large_buffer_pool); + + small_buffer_pool = large_buffer_pool = 0; +} + + /* allocate a 'safe' buffer and keep track of it */ -static char * -alloc_safe_buffer(char *unsafe, int size, dma_addr_t *pbus) +static struct safe_buffer * +alloc_safe_buffer(void *ptr, size_t size, int direction) { - char *safe; - dma_addr_t busptr; + struct safe_buffer *buf; struct pci_pool *pool; - int i; - - if (0) printk("alloc_safe_buffer(size=%d)\n", size); + void *safe; + dma_addr_t safe_dma_addr; - if (size <= SIZE_SMALL) - pool = small_buffer_cache; - else - if (size < SIZE_LARGE) - pool = large_buffer_cache; - else - return 0; + DPRINTK("%s(ptr=%p, size=%d, direction=%d)\n", + __func__, ptr, size, direction); - safe = pci_pool_alloc(pool, SLAB_ATOMIC, &busptr); - if (safe == 0) + buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); + if (buf == 0) { + printk(KERN_WARNING "%s: kmalloc failed\n", __func__); return 0; + } - for (i = 0; i < MAX_SAFE; i++) - if (safe_buffers[i][0] == 0) { - break; - } - - if (i == MAX_SAFE) { - panic(__FILE__ ": exceeded MAX_SAFE buffers"); + if (size <= SIZE_SMALL) { + pool = small_buffer_pool; + safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); + } else if (size <= SIZE_LARGE) { + pool = large_buffer_pool; + safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); + } else { + printk(KERN_DEBUG + "sa111_pcibuf: resorting to pci_alloc_consistent\n"); + pool = 0; + safe = pci_alloc_consistent(SA1111_FAKE_PCIDEV, size, + &safe_dma_addr); } - /* place the size index and the old buffer ptr in the first 8 bytes - * and return a ptr + 12 to caller - */ - ((int *)safe)[0] = i; - ((char **)safe)[1] = (char *)pool; - ((char **)safe)[2] = unsafe; + if (safe == 0) { + printk(KERN_WARNING + "%s: could not alloc dma memory (size=%d)\n", + __func__, size); + kfree(buf); + return 0; + } - busptr += sizeof(int) + sizeof(char *) + sizeof(char *); + BUG_ON(sa1111_check_dma_bug(safe_dma_addr)); // paranoia - safe_buffers[i][0] = (void *)busptr; - safe_buffers[i][1] = (void *)safe; + buf->ptr = ptr; + buf->size = size; + buf->direction = direction; + buf->pool = pool; + buf->safe = safe; + buf->safe_dma_addr = safe_dma_addr; - safe += sizeof(int) + sizeof(char *) + sizeof(char *); + MOD_INC_USE_COUNT; + list_add(&buf->node, &safe_buffers); - *pbus = busptr; - return safe; + return buf; } /* determine if a buffer is from our "safe" pool */ -static char * -find_safe_buffer(char *busptr, char **unsafe) +static struct safe_buffer * +find_safe_buffer(dma_addr_t safe_dma_addr) { - int i; - char *buf; + struct list_head *entry; - for (i = 0; i < MAX_SAFE; i++) { - if (safe_buffers[i][0] == busptr) { - if (0) printk("find_safe_buffer(%p) found @ %d\n", busptr, i); - buf = safe_buffers[i][1]; - *unsafe = ((char **)buf)[2]; - return buf + sizeof(int) + sizeof(char *) + sizeof(char *); + list_for_each(entry, &safe_buffers) { + struct safe_buffer *b = + list_entry(entry, struct safe_buffer, node); + + if (b->safe_dma_addr == safe_dma_addr) { + return b; } } - return (char *)0; + return 0; } static void -free_safe_buffer(char *buf) +free_safe_buffer(struct safe_buffer *buf) { - int index; - struct pci_pool *pool; - char *dma; + DPRINTK("%s(buf=%p)\n", __func__, buf); - if (0) printk("free_safe_buffer(buf=%p)\n", buf); + list_del(&buf->node); - /* retrieve the buffer size index */ - buf -= sizeof(int) + sizeof(char*) + sizeof(char*); - index = ((int *)buf)[0]; - pool = (struct pci_pool *)((char **)buf)[1]; + if (buf->pool) + pci_pool_free(buf->pool, buf->safe, buf->safe_dma_addr); + else + pci_free_consistent(SA1111_FAKE_PCIDEV, buf->size, buf->safe, + buf->safe_dma_addr); + kfree(buf); - if (0) printk("free_safe_buffer(%p) index %d\n", - buf, index); + MOD_DEC_USE_COUNT; +} - if (index < 0 || index >= MAX_SAFE) { - printk(__FILE__ ": free_safe_buffer() corrupt buffer\n"); - return; - } +static inline int +dma_range_is_safe(dma_addr_t addr, size_t size) +{ + unsigned int physaddr = SA1111_DMA_ADDR((unsigned int) addr); - dma = safe_buffers[index][0]; - safe_buffers[index][0] = 0; + /* Any address within one megabyte of the start of the target + * bank will be OK. This is an overly conservative test: + * other addresses can be OK depending on the dram + * configuration. (See sa1111.c:sa1111_check_dma_bug() * for + * details.) + * + * We take care to ensure the entire dma region is within + * the safe range. + */ - pci_pool_free(pool, buf, (u32)dma); + return ((physaddr + size - 1) < (1<<20)); } /* - NOTE: - replace pci_map/unmap_single with local routines which will - do buffer copies if buffer is above 1mb... -*/ - -/* * see if a buffer address is in an 'unsafe' range. if it is * allocate a 'safe' buffer and copy the unsafe buffer into it. * substitute the safe buffer for the unsafe one. * (basically move the buffer from an unsafe area to a safe one) - * - * we assume calls to map_single are symmetric with calls to unmap_single... */ dma_addr_t -sa1111_map_single(struct pci_dev *hwdev, void *virtptr, - size_t size, int direction) +sa1111_map_single(void *ptr, size_t size, int direction) { - dma_addr_t busptr; + unsigned long flags; + dma_addr_t dma_addr; - mapped_alloc_size += size; + DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", + __func__, ptr, size, direction); - if (0) printk("pci_map_single(hwdev=%p,ptr=%p,size=%d,dir=%x) " - "alloced=%ld\n", - hwdev, virtptr, size, direction, mapped_alloc_size); + BUG_ON(direction == PCI_DMA_NONE); - busptr = virt_to_bus(virtptr); + local_irq_save(flags); - /* we assume here that a buffer will never be >=64k */ - if ( (((unsigned long)busptr) & 0x100000) || - ((((unsigned long)busptr)+size) & 0x100000) ) - { - char *safe; + dma_addr = virt_to_bus(ptr); - safe = alloc_safe_buffer(virtptr, size, &busptr); - if (safe == 0) { - printk("unable to map unsafe buffer %p!\n", virtptr); + if (!dma_range_is_safe(dma_addr, size)) { + struct safe_buffer *buf; + + buf = alloc_safe_buffer(ptr, size, direction); + if (buf == 0) { + printk(KERN_ERR + "%s: unable to map unsafe buffer %p!\n", + __func__, ptr); + local_irq_restore(flags); return 0; } - if (0) printk("unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", - virtptr, (void *)virt_to_bus(virtptr), - safe, (void *)busptr); - - memcpy(safe, virtptr, size); - consistent_sync(safe, size, direction); + DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, + buf->ptr, (void *) virt_to_bus(buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + if ((direction == PCI_DMA_TODEVICE) || + (direction == PCI_DMA_BIDIRECTIONAL)) { + DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n", + __func__, ptr, buf->safe, size); + memcpy(buf->safe, ptr, size); + } + consistent_sync(buf->safe, size, direction); - return busptr; + dma_addr = buf->safe_dma_addr; + } else { + consistent_sync(ptr, size, direction); } - consistent_sync(virtptr, size, direction); - return busptr; + local_irq_restore(flags); + return dma_addr; } /* - * see if a mapped address was really a "safe" buffer and if so, - * copy the data from the safe buffer back to the unsafe buffer - * and free up the safe buffer. - * (basically return things back to the way they should be) + * see if a mapped address was really a "safe" buffer and if so, copy + * the data from the safe buffer back to the unsafe buffer and free up + * the safe buffer. (basically return things back to the way they + * should be) */ + void -sa1111_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, - size_t size, int direction) +sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction) { - char *safe, *unsafe; - void *buf; + unsigned long flags; + struct safe_buffer *buf; - /* hack; usb-ohci.c never sends hwdev==NULL, all others do */ - if (hwdev == NULL) { - return; + DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", + __func__, (void *) dma_addr, size, direction); + + BUG_ON(direction == PCI_DMA_NONE); + + local_irq_save(flags); + + buf = find_safe_buffer(dma_addr); + if (buf) { + BUG_ON(buf->size != size); + BUG_ON(buf->direction != direction); + + DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, + buf->ptr, (void *) virt_to_bus(buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + if ((direction == PCI_DMA_FROMDEVICE) || + (direction == PCI_DMA_BIDIRECTIONAL)) { + DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n", + __func__, buf->safe, buf->ptr, size); + memcpy(buf->ptr, buf->safe, size); + } + free_safe_buffer(buf); } - mapped_alloc_size -= size; + local_irq_restore(flags); +} + +int +sa1111_map_sg(struct scatterlist *sg, int nents, int direction) +{ + BUG(); /* Not implemented. */ + + return -1; +} + +void +sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction) +{ + BUG(); /* Not implemented. */ +} + +void +sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction) +{ + unsigned long flags; + struct safe_buffer *buf; + + DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", + __func__, (void *) dma_addr, size, direction); - if (0) printk("pci_unmap_single(hwdev=%p,ptr=%p,size=%d,dir=%x) " - "alloced=%ld\n", - hwdev, (void *)dma_addr, size, direction, - mapped_alloc_size); - - if ((safe = find_safe_buffer((void *)dma_addr, &unsafe))) { - if (0) printk("copyback unsafe %p, safe %p, size %d\n", - unsafe, safe, size); - - consistent_sync(safe, size, PCI_DMA_FROMDEVICE); - memcpy(unsafe, safe, size); - free_safe_buffer(safe); + local_irq_save(flags); + + buf = find_safe_buffer(dma_addr); + if (buf) { + BUG_ON(buf->size != size); + BUG_ON(buf->direction != direction); + + DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, + buf->ptr, (void *) virt_to_bus(buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + switch (direction) { + case PCI_DMA_FROMDEVICE: + DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n", + __func__, buf->safe, buf->ptr, size); + memcpy(buf->ptr, buf->safe, size); + break; + case PCI_DMA_TODEVICE: + DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n", + __func__,buf->ptr, buf->safe, size); + memcpy(buf->safe, buf->ptr, size); + break; + case PCI_DMA_BIDIRECTIONAL: + BUG(); /* is this allowed? what does it mean? */ + default: + BUG(); + } + consistent_sync(buf->safe, size, direction); } else { - /* assume this is normal memory */ - buf = bus_to_virt(dma_addr); - consistent_sync(buf, size, PCI_DMA_FROMDEVICE); + consistent_sync(bus_to_virt(dma_addr), size, direction); } + + local_irq_restore(flags); +} + +void +sa1111_dma_sync_sg(struct scatterlist *sg, int nelems, int direction) +{ + BUG(); /* Not implemented. */ } EXPORT_SYMBOL(sa1111_map_single); EXPORT_SYMBOL(sa1111_unmap_single); +EXPORT_SYMBOL(sa1111_map_sg); +EXPORT_SYMBOL(sa1111_unmap_sg); +EXPORT_SYMBOL(sa1111_dma_sync_single); +EXPORT_SYMBOL(sa1111_dma_sync_sg); -static int __init sa1111_init_safe_buffers(void) +/* **************************************** */ + +static int __init sa1111_pcibuf_init(void) { - printk("Initializing SA1111 buffer pool for DMA workaround\n"); - init_safe_buffers(NULL); - return 0; + int ret; + + printk(KERN_DEBUG + "sa1111_pcibuf: initializing SA-1111 DMA workaround\n"); + + ret = create_safe_buffer_pools(); + + return ret; } +module_init(sa1111_pcibuf_init); -static void free_safe_buffers(void) +static void __exit sa1111_pcibuf_exit(void) { - pci_pool_destroy(small_buffer_cache); - pci_pool_destroy(large_buffer_cache); + BUG_ON(!list_empty(&safe_buffers)); + + destroy_safe_buffer_pools(); } +module_exit(sa1111_pcibuf_exit); -module_init(sa1111_init_safe_buffers); -module_exit(free_safe_buffers); +MODULE_AUTHOR("Christopher Hoover "); +MODULE_DESCRIPTION("Special pci_{map/unmap/dma_sync}_* routines for SA-1111."); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/arch/arm/mach-sa1100/sa1111.c linux-2.4.22/arch/arm/mach-sa1100/sa1111.c --- linux-2.4.21/arch/arm/mach-sa1100/sa1111.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/sa1111.c 2003-08-25 04:44:39.000000000 -0700 @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/mach-sa1100/simputer.c linux-2.4.22/arch/arm/mach-sa1100/simputer.c --- linux-2.4.21/arch/arm/mach-sa1100/simputer.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/simputer.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,78 @@ +/* + * linux/arch/arm/mach-sa1100/simputer.c + * + * Author: Vivek K S (modified from Nicolas Pitre's Assabet file) + * + * This file contains all Simputer-specific tweaks. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "generic.h" + +static void __init +fixup_simputer(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ +} + + +static struct map_desc simputer_io_desc[] __initdata = { + /* virtual physical length domain r w c b */ + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf2800000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Simputer Modem */ + { 0xf3800000, 0x48000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* USB */ + LAST_DESC +}; + +static void __init simputer_map_io(void) +{ + sa1100_map_io(); + iotable_init(simputer_io_desc); + + sa1100_register_uart(1, 2); + sa1100_register_uart(0, 1); /* com port */ + sa1100_register_uart(2, 3); /* radio module */ + + /* + * Set up registers for sleep mode. + */ + PWER = PWER_GPIO0; + PGSR = 0; + PCFR = 0; + + /* + * Clear all possible wakeup reasons. + */ + RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; +} + + +MACHINE_START(SIMPUTER, "Picopeta-Simputer") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_simputer) + MAPIO(simputer_map_io) + INITIRQ(sa1100_init_irq) +MACHINE_END diff -urN linux-2.4.21/arch/arm/mach-sa1100/sleep.S linux-2.4.22/arch/arm/mach-sa1100/sleep.S --- linux-2.4.21/arch/arm/mach-sa1100/sleep.S 2001-10-25 13:53:46.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/sleep.S 2003-08-25 04:44:39.000000000 -0700 @@ -11,12 +11,17 @@ * 2001-02-06: Cliff Brake Initial code * * 2001-08-29: Nicolas Pitre Simplified. + * + * 2002-05-27: Nicolas Pitre Revisited, more cleanup and simplification. + * Storage is on the stack now. */ #include #include #include -#include "sleep.h" + + + .text /* * sa1100_cpu_suspend() @@ -25,35 +30,25 @@ * */ - .text - -ENTRY(sleep_save) .word 0 @ virtual address of parameter array -ENTRY(sleep_save_p) .word 0 @ physical address of parameter array - ENTRY(sa1100_cpu_suspend) - @ save registers on stack - stmfd sp!, {r4 - r12, lr} - - @ load virtual address for sleep_save array - ldr r4, sleep_save + stmfd sp!, {r4 - r12, lr} @ save registers on stack - @ save stack pointer - str sp, [r4, #(SLEEP_SAVE_SP*4)] - - @ save coprocessor registers - mrc p15, 0, r1, c1, c0, 0 - str r1, [r4, #(SLEEP_SAVE_CP15_R1*4)] - mrc p15, 0, r1, c2, c0, 0 - str r1, [r4, #(SLEEP_SAVE_CP15_R2*4)] - mrc p15, 0, r1, c3, c0, 0 - str r1, [r4, #(SLEEP_SAVE_CP15_R3*4)] - mrc p15, 0, r1, c5, c0, 0 - str r1, [r4, #(SLEEP_SAVE_CP15_R5*4)] - mrc p15, 0, r1, c6, c0, 0 - str r1, [r4, #(SLEEP_SAVE_CP15_R6*4)] - mrc p15, 0, r1, c13, c0, 0 - str r1, [r4, #(SLEEP_SAVE_CP15_R13*4)] + @ get coprocessor registers + mrc p15, 0, r4, c3, c0, 0 @ domain ID + mrc p15, 0, r5, c2, c0, 0 @ translation table base addr + mrc p15, 0, r6, c13, c0, 0 @ PID + mrc p15, 0, r7, c1, c0, 0 @ control reg + + @ store them plus current virtual stack ptr on stack + mov r8, sp + stmfd sp!, {r4 - r8} + + @ preserve phys address of stack + mov r0, sp + bl sleep_phys_sp + ldr r1, =sleep_save_sp + str r0, [r1] @ clean data cache and invalidate WB bl cpu_sa1100_cache_clean_invalidate_all @@ -72,32 +67,31 @@ @ delay 90us and set CPU PLL to lowest speed @ fixes resume problem on high speed SA1110 mov r0, #90 - bl SYMBOL_NAME(udelay) + bl SYMBOL_NAME(__udelay) ldr r0, =PPCR mov r1, #0 str r1, [r0] mov r0, #90 - bl SYMBOL_NAME(udelay) + bl SYMBOL_NAME(__udelay) - -/* setup up register contents for jump to page containing SA1110 SDRAM controller bug fix suspend code - * - * r0 points to MSC0 register - * r1 points to MSC1 register - * r2 points to MSC2 register - * r3 is MSC0 value - * r4 is MSC1 value - * r5 is MSC2 value - * r6 points to MDREFR register - * r7 is first MDREFR value - * r8 is second MDREFR value - * r9 is pointer to MDCNFG register - * r10 is MDCNFG value - * r11 is third MDREFR value - * r12 is pointer to PMCR register - * r13 is PMCR value (1) - * - */ + /* + * SA1110 SDRAM controller workaround. register values: + * + * r0 = &MSC0 + * r1 = &MSC1 + * r2 = &MSC2 + * r3 = MSC0 value + * r4 = MSC1 value + * r5 = MSC2 value + * r6 = &MDREFR + * r7 = first MDREFR value + * r8 = second MDREFR value + * r9 = &MDCNFG + * r10 = MDCNFG value + * r11 = third MDREFR value + * r12 = &PMCR + * r13 = PMCR value (1) + */ ldr r0, =MSC0 ldr r1, =MSC1 @@ -170,69 +164,49 @@ * * entry point from bootloader into kernel during resume * + * Note: Yes, part of the following code is located into the .data section. + * This is to allow sleep_save_sp to be accessed with a relative load + * while we can't rely on any MMU translation. We could have put + * sleep_save_sp in the .text section as well, but some setups might + * insist on .text to be truely read-only. */ + .data .align 5 ENTRY(sa1100_cpu_resume) - - @ set SVC, irqs off - mov r0, #I_BIT | MODE_SVC + mov r0, #I_BIT | F_BIT | MODE_SVC @ set SVC, irqs off msr cpsr_c, r0 - @ load physical address of sleep_save - ldr r4, sleep_save_p - - @ restore cp15_r3, domain id - ldr r1, [r4, #(SLEEP_SAVE_CP15_R3*4)] - mcr p15, 0, r1, c3, c0 ,0 - - @ restore cp15_r2, translation table base address - ldr r1, [r4, #(SLEEP_SAVE_CP15_R2*4)] - mcr p15, 0, r1, c2, c0 ,0 + ldr r0, sleep_save_sp @ stack phys addr + ldr r2, =resume_after_mmu @ its absolute virtual address + ldmfd r0, {r4 - r7, sp} @ CP regs + virt stack ptr mov r1, #0 mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache + mcr p15, 0, r1, c9, c0, 0 @ invalidate RB + mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB - @ get saved cp15 r1 (control register) - ldr r1, [r4, #(SLEEP_SAVE_CP15_R1*4)] - - @ get address to jump to after turning on MMU - ldr r2, =resume_after_mmu - - cmp r2, #0 - - b resume_turn_on_mmu + mcr p15, 0, r4, c3, c0, 0 @ domain ID + mcr p15, 0, r5, c2, c0, 0 @ translation table base addr + mcr p15, 0, r6, c13, c0, 0 @ PID + b resume_turn_on_mmu @ cache align execution .align 5 resume_turn_on_mmu: - - @ turn on mmu - mcr p15, 0, r1, c1, c0 ,0 - - @ jump to resume_after_mmu - mov pc, r2 + mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, caches, etc. + nop + mov pc, r2 @ jump to virtual addr + nop nop nop - .align 5 -resume_after_mmu: - - @ load virtual address for sleep_save array - ldr r4, sleep_save - - @ restore the rest of CPU state - ldr r1, [r4, #(SLEEP_SAVE_CP15_R13*4)] - mcr p15, 0, r1, c13, c0, 0 - ldr r1, [r4, #(SLEEP_SAVE_CP15_R5*4)] - mcr p15, 0, r1, c5, c0 ,0 - ldr r1, [r4, #(SLEEP_SAVE_CP15_R6*4)] - mcr p15, 0, r1, c6, c0 ,0 - - @ restore stack pointer - ldr sp, [r4, #(SLEEP_SAVE_SP*4)] +sleep_save_sp: + .word 0 @ preserve stack phys ptr here - @ return to caller - ldmfd sp!, {r4 - r12, pc} + .text +resume_after_mmu: + mcr p15, 0, r1, c15, c1, 2 @ enable clock switching + ldmfd sp!, {r4 - r12, pc} @ return to caller diff -urN linux-2.4.21/arch/arm/mach-sa1100/sleep.h linux-2.4.22/arch/arm/mach-sa1100/sleep.h --- linux-2.4.21/arch/arm/mach-sa1100/sleep.h 2001-10-25 13:53:46.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/sleep.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,30 +0,0 @@ -/* - * Offsets for register values preserved in RAM while in sleep mode - */ - -#define SLEEP_SAVE_OSCR 0 -#define SLEEP_SAVE_OSMR0 1 -#define SLEEP_SAVE_OSMR1 2 -#define SLEEP_SAVE_OSMR2 3 -#define SLEEP_SAVE_OSMR3 4 -#define SLEEP_SAVE_OIER 5 -#define SLEEP_SAVE_GPDR 6 -#define SLEEP_SAVE_GRER 7 -#define SLEEP_SAVE_GFER 8 -#define SLEEP_SAVE_GAFR 9 -#define SLEEP_SAVE_PPDR 10 -#define SLEEP_SAVE_PPSR 11 -#define SLEEP_SAVE_PPAR 12 -#define SLEEP_SAVE_PSDR 13 -#define SLEEP_SAVE_Ser1SDCR0 14 -#define SLEEP_SAVE_ICMR 15 -#define SLEEP_SAVE_SP 16 -#define SLEEP_SAVE_CP15_R1 17 -#define SLEEP_SAVE_CP15_R2 18 -#define SLEEP_SAVE_CP15_R3 19 -#define SLEEP_SAVE_CP15_R5 20 -#define SLEEP_SAVE_CP15_R6 21 -#define SLEEP_SAVE_CP15_R13 22 - -#define SLEEP_SAVE_SIZE 23 - diff -urN linux-2.4.21/arch/arm/mach-sa1100/ssp.c linux-2.4.22/arch/arm/mach-sa1100/ssp.c --- linux-2.4.21/arch/arm/mach-sa1100/ssp.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mach-sa1100/ssp.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,208 @@ +/* + * linux/arch/arm/mach-sa1100/ssp.c + * + * Copyright (C) 2003 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Generic SSP driver. This provides the generic core for simple + * IO-based SSP applications. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int status = Ser4SSSR; + + if (status & SSSR_ROR) { + printk(KERN_WARNING "SSP: receiver overrun\n"); + } + + Ser4SSSR = SSSR_ROR; +} + +/** + * ssp_write_word - write a word to the SSP port + * @data: 16-bit, MSB justified data to write. + * + * Wait for a free entry in the SSP transmit FIFO, and write a data + * word to the SSP port. + * + * The caller is expected to perform the necessary locking. + * + * Returns: + * %-ETIMEDOUT timeout occurred (for future) + * 0 success + */ +int ssp_write_word(u16 data) +{ + while (!(Ser4SSSR & SSSR_TNF)) + cpu_relax(); + + Ser4SSDR = data; + + return 0; +} + +/** + * ssp_read_word - read a word from the SSP port + * + * Wait for a data word in the SSP receive FIFO, and return the + * received data. Data is LSB justified. + * + * Note: Currently, if data is not expected to be received, this + * function will wait for ever. + * + * The caller is expected to perform the necessary locking. + * + * Returns: + * %-ETIMEDOUT timeout occurred (for future) + * 16-bit data success + */ +int ssp_read_word(void) +{ + while (!(Ser4SSSR & SSSR_RNE)) + cpu_relax(); + + return Ser4SSDR; +} + +/** + * ssp_flush - flush the transmit and receive FIFOs + * + * Wait for the SSP to idle, and ensure that the receive FIFO + * is empty. + * + * The caller is expected to perform the necessary locking. + */ +void ssp_flush(void) +{ + do { + while (Ser4SSSR & SSSR_RNE) { + (void) Ser4SSDR; + } + } while (Ser4SSSR & SSSR_BSY); +} + +/** + * ssp_enable - enable the SSP port + * + * Turn on the SSP port. + */ +void ssp_enable(void) +{ + Ser4SSCR0 |= SSCR0_SSE; +} + +/** + * ssp_disable - shut down the SSP port + * + * Turn off the SSP port, optionally powering it down. + */ +void ssp_disable(void) +{ + Ser4SSCR0 &= ~SSCR0_SSE; +} + +/** + * ssp_save_state - save the SSP configuration + * @ssp: pointer to structure to save SSP configuration + * + * Save the configured SSP state for suspend. + */ +void ssp_save_state(struct ssp_state *ssp) +{ + ssp->cr0 = Ser4SSCR0; + ssp->cr1 = Ser4SSCR1; + + Ser4SSCR0 &= ~SSCR0_SSE; +} + +/** + * ssp_restore_state - restore a previously saved SSP configuration + * @ssp: pointer to configuration saved by ssp_save_state + * + * Restore the SSP configuration saved previously by ssp_save_state. + */ +void ssp_restore_state(struct ssp_state *ssp) +{ + Ser4SSSR = SSSR_ROR; + + Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE; + Ser4SSCR1 = ssp->cr1; + Ser4SSCR0 = ssp->cr0; +} + +/** + * ssp_init - setup the SSP port + * + * initialise and claim resources for the SSP port. + * + * Returns: + * %-ENODEV if the SSP port is unavailable + * %-EBUSY if the resources are already in use + * %0 on success + */ +int ssp_init(void) +{ + int ret; + + if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE)) + return -ENODEV; + + if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) { + return -EBUSY; + } + + Ser4SSSR = SSSR_ROR; + + ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL); + if (ret) + goto out_region; + + return 0; + + out_region: + release_mem_region(__PREG(Ser4SSCR0), 0x18); + return ret; +} + +/** + * ssp_exit - undo the effects of ssp_init + * + * release and free resources for the SSP port. + */ +void ssp_exit(void) +{ + Ser4SSCR0 &= ~SSCR0_SSE; + + free_irq(IRQ_Ser4SSP, NULL); + release_mem_region(__PREG(Ser4SSCR0), 0x18); +} + +MODULE_AUTHOR("Russell King"); +MODULE_DESCRIPTION("SA11x0 SSP PIO driver"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(ssp_write_word); +EXPORT_SYMBOL(ssp_read_word); +EXPORT_SYMBOL(ssp_flush); +EXPORT_SYMBOL(ssp_enable); +EXPORT_SYMBOL(ssp_disable); +EXPORT_SYMBOL(ssp_save_state); +EXPORT_SYMBOL(ssp_restore_state); +EXPORT_SYMBOL(ssp_init); +EXPORT_SYMBOL(ssp_exit); diff -urN linux-2.4.21/arch/arm/mach-sa1100/system3.c linux-2.4.22/arch/arm/mach-sa1100/system3.c --- linux-2.4.21/arch/arm/mach-sa1100/system3.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/arm/mach-sa1100/system3.c 2003-08-25 04:44:39.000000000 -0700 @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include diff -urN linux-2.4.21/arch/arm/mm/Makefile linux-2.4.22/arch/arm/mm/Makefile --- linux-2.4.21/arch/arm/mm/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -36,8 +36,10 @@ p-$(CONFIG_CPU_ARM720T) += proc-arm720.o p-$(CONFIG_CPU_ARM920T) += proc-arm920.o p-$(CONFIG_CPU_ARM922T) += proc-arm922.o +p-$(CONFIG_CPU_ARM925T) += proc-arm925.o p-$(CONFIG_CPU_ARM926T) += proc-arm926.o p-$(CONFIG_CPU_ARM1020) += proc-arm1020.o +p-$(CONFIG_CPU_ARM1026) += proc-arm1026.o p-$(CONFIG_CPU_SA110) += proc-sa110.o p-$(CONFIG_CPU_SA1100) += proc-sa110.o diff -urN linux-2.4.21/arch/arm/mm/alignment.c linux-2.4.22/arch/arm/mm/alignment.c --- linux-2.4.21/arch/arm/mm/alignment.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/alignment.c 2003-08-25 04:44:39.000000000 -0700 @@ -426,13 +426,13 @@ eaddr += 4; /* - * For alignment faults on the ARM922T the MMU makes + * For alignment faults on the ARM922T/ARM920T the MMU makes * the FSR (and hence addr) equal to the updated base address * of the multiple access rather than the restored value. - * Switch this messsage off if we've got a ARM922, otherwise + * Switch this messsage off if we've got a ARM92[02], otherwise * [ls]dm alignment faults are noisy! */ -#if !(defined CONFIG_CPU_ARM922T) +#if !(defined CONFIG_CPU_ARM922T) && !(defined CONFIG_CPU_ARM920T) /* * This is a "hint" - we already have eaddr worked out by the * processor for us. diff -urN linux-2.4.21/arch/arm/mm/consistent.c linux-2.4.22/arch/arm/mm/consistent.c --- linux-2.4.21/arch/arm/mm/consistent.c 2001-06-27 14:12:04.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/consistent.c 2003-08-25 04:44:39.000000000 -0700 @@ -30,14 +30,20 @@ * now, we expressly forbid it, especially as some of the stuff we do * here is not interrupt context safe. * + * We should allow this function to be called from interrupt context. + * However, we call ioremap, which needs to fiddle around with various + * things (like the vmlist_lock, and allocating page tables). These + * things aren't interrupt safe (yet). + * * Note that this does *not* zero the allocated area! */ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) { struct page *page, *end, *free; unsigned long order; - void *ret, *virt; + void *ret; + /* FIXME */ if (in_interrupt()) BUG(); @@ -48,22 +54,22 @@ if (!page) goto no_page; - /* - * We could do with a page_to_phys and page_to_bus here. - */ - virt = page_address(page); - *dma_handle = virt_to_bus(virt); - ret = __ioremap(virt_to_phys(virt), size, 0); + *dma_handle = page_to_bus(page); + ret = __ioremap(page_to_pfn(page) << PAGE_SHIFT, size, 0); if (!ret) goto no_remap; #if 0 /* ioremap_does_flush_cache_all */ - /* - * we need to ensure that there are no cachelines in use, or - * worse dirty in this area. Really, we don't need to do - * this since __ioremap does a flush_cache_all() anyway. --rmk - */ - invalidate_dcache_range(virt, virt + size); + { + void *virt = page_address(page); + + /* + * we need to ensure that there are no cachelines in use, or + * worse dirty in this area. Really, we don't need to do + * this since __ioremap does a flush_cache_all() anyway. --rmk + */ + invalidate_dcache_range(virt, virt + size); + } #endif /* @@ -72,7 +78,6 @@ * We also mark the pages in use as reserved so that * remap_page_range works. */ - page = virt_to_page(virt); free = page + (size >> PAGE_SHIFT); end = page + (1 << order); @@ -93,18 +98,15 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle) { - void *__ret; - int __gfp = GFP_KERNEL; + int gfp = GFP_KERNEL; -#ifdef CONFIG_PCI - if ((hwdev) == NULL || +#if defined(CONFIG_PCI) || defined(CONFIG_SA1111) + if ((hwdev) == NULL || dev_is_sa1111(hwdev) || (hwdev)->dma_mask != 0xffffffff) #endif - __gfp |= GFP_DMA; + gfp |= GFP_DMA; - __ret = consistent_alloc(__gfp, (size), - (handle)); - return __ret; + return consistent_alloc(gfp, size, handle); } /* @@ -114,19 +116,16 @@ void consistent_free(void *vaddr, size_t size, dma_addr_t handle) { struct page *page, *end; - void *virt; if (in_interrupt()) BUG(); - virt = bus_to_virt(handle); - /* * More messing around with the MM internals. This is * sick, but then so is remap_page_range(). */ size = PAGE_ALIGN(size); - page = virt_to_page(virt); + page = virt_to_page(bus_to_virt(handle)); end = page + (size >> PAGE_SHIFT); for (; page < end; page++) diff -urN linux-2.4.21/arch/arm/mm/fault-armv.c linux-2.4.22/arch/arm/mm/fault-armv.c --- linux-2.4.21/arch/arm/mm/fault-armv.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/fault-armv.c 2003-08-25 04:44:39.000000000 -0700 @@ -28,7 +28,6 @@ #include #include -extern void die_if_kernel(const char *str, struct pt_regs *regs, int err); extern void show_pte(struct mm_struct *mm, unsigned long addr); extern int do_page_fault(unsigned long addr, int error_code, struct pt_regs *regs); @@ -236,9 +235,13 @@ */ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) { - struct page *page = pte_page(pte); + unsigned long pfn = pte_pfn(pte); + struct page *page; - if (VALID_PAGE(page) && page->mapping) { + if (!pfn_valid(pfn)) + return; + page = pfn_to_page(pfn); + if (page->mapping) { if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) { unsigned long kvirt = (unsigned long)page_address(page); cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0); diff -urN linux-2.4.21/arch/arm/mm/fault-common.c linux-2.4.22/arch/arm/mm/fault-common.c --- linux-2.4.21/arch/arm/mm/fault-common.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/arm/mm/fault-common.c 2003-08-25 04:44:39.000000000 -0700 @@ -43,52 +43,77 @@ #define READ_FAULT(m) (!(m)) #endif -NORET_TYPE void die(const char *msg, struct pt_regs *regs, int err) ATTRIB_NORET; - /* * This is useful to dump out the page tables associated with * 'addr' in mm 'mm'. */ void show_pte(struct mm_struct *mm, unsigned long addr) { - pgd_t *pgd; + mm_segment_t fs; if (!mm) mm = &init_mm; - printk(KERN_ALERT "pgd = %p\n", mm->pgd); - pgd = pgd_offset(mm, addr); - printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd)); + printk(KERN_ALERT "mm = %p pgd = %p\n", mm, mm->pgd); + fs = get_fs(); + set_fs(get_ds()); do { - pmd_t *pmd; - pte_t *pte; + pgd_t pg, *pgd = pgd_offset(mm, addr); + pmd_t pm, *pmd; + pte_t pt, *pte; + + printk(KERN_ALERT "*pgd = "); - if (pgd_none(*pgd)) + if (__get_user(pgd_val(pg), (unsigned long *)pgd)) { + printk("(faulted)"); break; + } - if (pgd_bad(*pgd)) { + printk("%08lx", pgd_val(pg)); + + if (pgd_none(pg)) + break; + + if (pgd_bad(pg)) { printk("(bad)"); break; } pmd = pmd_offset(pgd, addr); - printk(", *pmd = %08lx", pmd_val(*pmd)); - if (pmd_none(*pmd)) + printk(", *pmd = "); + + if (__get_user(pmd_val(pm), (unsigned long *)pmd)) { + printk("(faulted)"); + break; + } + + printk("%08lx", pmd_val(pm)); + + if (pmd_none(pm)) break; - if (pmd_bad(*pmd)) { + if (pmd_bad(pm)) { printk("(bad)"); break; } pte = pte_offset(pmd, addr); - printk(", *pte = %08lx", pte_val(*pte)); + + printk(", *pte = "); + + if (__get_user(pte_val(pt), (unsigned long *)pte)) { + printk("(faulted)"); + break; + } + + printk("%08lx", pte_val(pt)); #ifdef CONFIG_CPU_32 printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE])); #endif } while(0); + set_fs(fs); printk("\n"); } @@ -345,6 +370,9 @@ offset = __pgd_offset(addr); + /* + * FIXME: CP15 C1 is write only on ARMv3 architectures. + */ pgd = cpu_get_pgd() + offset; pgd_k = init_mm.pgd + offset; diff -urN linux-2.4.21/arch/arm/mm/init.c linux-2.4.22/arch/arm/mm/init.c --- linux-2.4.21/arch/arm/mm/init.c 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/arm/mm/init.c * - * Copyright (C) 1995-2000 Russell King + * Copyright (C) 1995-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -46,11 +46,13 @@ #define TABLE_OFFSET 0 #endif -#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *)) +#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(pte_t)) static unsigned long totalram_pages; extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern char _stext, _text, _etext, _end, __init_begin, __init_end; +extern unsigned long phys_initrd_start; +extern unsigned long phys_initrd_size; /* * The sole use of this is to pass memory configuration @@ -292,6 +294,7 @@ * also get rid of some of the stuff above as well. */ max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET); +// max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET); mi->end = memend_pfn << PAGE_SHIFT; return bootmem_pages; @@ -302,16 +305,16 @@ int initrd_node = -2; #ifdef CONFIG_BLK_DEV_INITRD + unsigned long end = phys_initrd_start + phys_initrd_size; + /* * Make sure that the initrd is within a valid area of * memory. */ - if (initrd_start) { - unsigned long phys_initrd_start, phys_initrd_end; + if (phys_initrd_size) { unsigned int i; - phys_initrd_start = __pa(initrd_start); - phys_initrd_end = __pa(initrd_end); + initrd_node = -1; for (i = 0; i < mi->nr_banks; i++) { unsigned long bank_end; @@ -319,7 +322,7 @@ bank_end = mi->bank[i].start + mi->bank[i].size; if (mi->bank[i].start <= phys_initrd_start && - phys_initrd_end <= bank_end) + end <= bank_end) initrd_node = mi->bank[i].node; } } @@ -327,8 +330,8 @@ if (initrd_node == -1) { printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond " "physical memory - disabling initrd\n", - initrd_start, initrd_end); - initrd_start = initrd_end = 0; + phys_initrd_start, end); + phys_initrd_start = phys_initrd_size = 0; } #endif @@ -354,7 +357,7 @@ * and can only be in node 0. */ reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), - PTRS_PER_PGD * sizeof(void *)); + PTRS_PER_PGD * sizeof(pgd_t)); #endif /* * And don't forget to reserve the allocator bitmap, @@ -378,7 +381,7 @@ */ if (machine_is_archimedes() || machine_is_a5k()) reserve_bootmem_node(pgdat, 0x02000000, 0x00080000); - if (machine_is_edb7211()) + if (machine_is_edb7211() || machine_is_fortunet()) reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000); if (machine_is_p720t()) reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000); @@ -469,9 +472,12 @@ #ifdef CONFIG_BLK_DEV_INITRD - if (initrd_node >= 0) - reserve_bootmem_node(NODE_DATA(initrd_node), __pa(initrd_start), - initrd_end - initrd_start); + if (phys_initrd_size && initrd_node >= 0) { + reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start, + phys_initrd_size); + initrd_start = __phys_to_virt(phys_initrd_start); + initrd_end = initrd_start + phys_initrd_size; + } #endif if (map_pg != bootmap_pfn + bootmap_pages) @@ -501,6 +507,7 @@ memtable_init(mi); if (mdesc->map_io) mdesc->map_io(); + flush_cache_all(); flush_tlb_all(); /* @@ -583,7 +590,7 @@ } if (size && s) - printk("Freeing %s memory: %dK\n", s, size); + printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); } /* diff -urN linux-2.4.21/arch/arm/mm/ioremap.c linux-2.4.22/arch/arm/mm/ioremap.c --- linux-2.4.21/arch/arm/mm/ioremap.c 2001-04-12 12:20:31.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/ioremap.c 2003-08-25 04:44:39.000000000 -0700 @@ -8,24 +8,19 @@ * Hacked for ARM by Phil Blundell * Hacked to allow all architectures to build, and various cleanups * by Russell King - */ - -/* + * * This allows a driver to remap an arbitrary region of bus memory into * virtual space. One should *only* use readl, writel, memcpy_toio and * so on with such remapped areas. * - * Because the ARM only has a 32-bit address space we can't address the - * whole of the (physical) PCI space at once. PCI huge-mode addressing - * allows us to circumvent this restriction by splitting PCI space into - * two 2GB chunks and mapping only one at a time into processor memory. - * We use MMU protection domains to trap any attempt to access the bank - * that is not currently mapped. (This isn't fully implemented yet.) - * - * DC21285 currently has a bug in that the PCI address extension - * register affects the address of any writes waiting in the outbound - * FIFO. Unfortunately, it is not possible to tell the DC21285 to - * flush this - flushing the area causes the bus to lock. + * ioremap support tweaked to allow support for large page mappings. We + * have several issues that needs to be resolved first however: + * + * 1. We need set_pte, or something like set_pte to understand large + * page mappings. + * + * 2. we need the unmap_* functions to likewise understand large page + * mappings. */ #include #include @@ -35,8 +30,9 @@ #include #include -static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr, pgprot_t pgprot) +static inline void +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long pfn, pgprot_t pgprot) { unsigned long end; @@ -44,22 +40,26 @@ end = address + size; if (end > PMD_SIZE) end = PMD_SIZE; - if (address >= end) - BUG(); + BUG_ON(address >= end); do { - if (!pte_none(*pte)) { - printk("remap_area_pte: page already exists\n"); - BUG(); - } - set_pte(pte, mk_pte_phys(phys_addr, pgprot)); + if (!pte_none(*pte)) + goto bad; + + set_pte(pte, pfn_pte(pfn, pgprot)); address += PAGE_SIZE; - phys_addr += PAGE_SIZE; + pfn++; pte++; } while (address && (address < end)); + return; + + bad: + printk("remap_area_pte: page already exists\n"); + BUG(); } -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) +static inline int +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long pfn, unsigned long flags) { unsigned long end; pgprot_t pgprot; @@ -70,34 +70,33 @@ if (end > PGDIR_SIZE) end = PGDIR_SIZE; - phys_addr -= address; - if (address >= end) - BUG(); + pfn -= address >> PAGE_SHIFT; + BUG_ON(address >= end); pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags); do { pte_t * pte = pte_alloc(&init_mm, pmd, address); if (!pte) return -ENOMEM; - remap_area_pte(pte, address, end - address, address + phys_addr, pgprot); + remap_area_pte(pte, address, end - address, pfn + (address >> PAGE_SHIFT), pgprot); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address && (address < end)); return 0; } -static int remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) +static int +remap_area_pages(unsigned long address, unsigned long pfn, + unsigned long size, unsigned long flags) { int error; pgd_t * dir; unsigned long end = address + size; - phys_addr -= address; + pfn -= address >> PAGE_SHIFT; dir = pgd_offset(&init_mm, address); flush_cache_all(); - if (address >= end) - BUG(); + BUG_ON(address >= end); spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; @@ -106,7 +105,7 @@ if (!pmd) break; if (remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) + pfn + (address >> PAGE_SHIFT), flags)) break; error = 0; address = (address + PGDIR_SIZE) & PGDIR_MASK; @@ -154,7 +153,7 @@ if (!area) return NULL; addr = area->addr; - if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) { + if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr >> PAGE_SHIFT, size, flags)) { vfree(addr); return NULL; } diff -urN linux-2.4.21/arch/arm/mm/mm-armv.c linux-2.4.22/arch/arm/mm/mm-armv.c --- linux-2.4.21/arch/arm/mm/mm-armv.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/mm-armv.c 2003-08-25 04:44:39.000000000 -0700 @@ -200,7 +200,7 @@ } ptep = pte_offset(pmdp, virt); - set_pte(ptep, mk_pte_phys(phys, __pgprot(prot))); + set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, __pgprot(prot))); } /* @@ -388,8 +388,6 @@ init_maps->bufferable = 0; create_mapping(init_maps); - - flush_cache_all(); } /* diff -urN linux-2.4.21/arch/arm/mm/mm-riscstation.c linux-2.4.22/arch/arm/mm/mm-riscstation.c --- linux-2.4.21/arch/arm/mm/mm-riscstation.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mm/mm-riscstation.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,35 @@ +/* + * linux/arch/arm/mm/mm-rpc.c + * linux/arch/arm/mm/mm-riscstation.c + * + * Copyright (C) 1998-1999 Russell King + * Copyright (C) 2002 Simtec Electronics / Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Extra MM routines for RiscStation + */ +#include +#include + +#include +#include +#include +#include + +#include + +/* map the EASI space to use for the ISA slot */ + +static struct map_desc riscstation_io_desc[] __initdata = { + { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, /* IO space */ + { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, /* EASI space */ + LAST_DESC +}; + +void __init riscstation_map_io(void) +{ + iotable_init(riscstation_io_desc); +} diff -urN linux-2.4.21/arch/arm/mm/proc-arm1020.S linux-2.4.22/arch/arm/mm/proc-arm1020.S --- linux-2.4.21/arch/arm/mm/proc-arm1020.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/proc-arm1020.S 2003-08-25 04:44:39.000000000 -0700 @@ -135,7 +135,7 @@ .align 5 ENTRY(cpu_arm1020_do_idle) mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -156,7 +156,7 @@ ENTRY(cpu_arm1020_cache_clean_invalidate_all) mov r2, #1 cpu_arm1020_cache_clean_invalidate_all_r2: -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, ip, c7, c10, 4 mov r1, #0xf @ 16 segments @@ -165,7 +165,7 @@ orr ip, ip, r1, LSL #5 @ shift in/up index mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov ip, ip #endif subs r3, r3, #1 @@ -176,12 +176,12 @@ bge 1b @ segments 7 to 0 #endif -#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE teq r2, #0 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache #endif mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov ip, ip mov ip, ip #endif @@ -203,13 +203,13 @@ cmp r3, #MAX_AREA_SIZE bgt cpu_arm1020_cache_clean_invalidate_all_r2 mcr p15, 0, r3, c7, c10, 4 -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry mcr p15, 0, r3, c7, c10, 4 @ drain WB add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry mcr p15, 0, r3, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 #endif add r0, r0, #DCACHELINESIZE @@ -217,11 +217,11 @@ blt 1b #endif -#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE teq r2, #0 movne r0, #0 mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -238,14 +238,14 @@ .align 5 ENTRY(cpu_arm1020_flush_ram_page) mcr p15, 0, r1, c7, c10, 4 -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE mov r1, #PAGESIZE 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -254,7 +254,7 @@ mov r0, #0 #endif -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -275,14 +275,14 @@ */ .align 5 ENTRY(cpu_arm1020_dcache_invalidate_range) -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE /* D cache are on */ tst r0, #DCACHELINESIZE - 1 bic r0, r0, #DCACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 4 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry at start mcrne p15, 0, r0, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -290,14 +290,14 @@ mcrne p15, 0, r1, c7, c10, 4 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry at end mcrne p15, 0, r1, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r1, r1 mov r1, r1 mov r1, r1 #endif 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 #endif add r0, r0, #DCACHELINESIZE @@ -306,7 +306,7 @@ #else /* D cache off, but still drain the write buffer */ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -330,13 +330,13 @@ cmp r3, #MAX_AREA_SIZE bgt cpu_arm1020_cache_clean_invalidate_all_r2 mcr p15, 0, r3, c7, c10, 4 -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry mcr p15, 0, r3, c7, c10, 4 @ drain WB add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry mcr p15, 0, r3, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 #endif add r0, r0, #DCACHELINESIZE @@ -344,7 +344,7 @@ blt 1b #endif -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -367,23 +367,23 @@ ENTRY(cpu_arm1020_dcache_clean_page) mov r1, #PAGESIZE mcr p15, 0, r0, c7, c10, 4 -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns) mcr p15, 0, r0, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 #endif add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 #endif add r0, r0, #DCACHELINESIZE subs r1, r1, #2 * DCACHELINESIZE bhi 1b #endif -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -401,14 +401,14 @@ ENTRY(cpu_arm1020_dcache_clean_entry) mov r1, #0 mcr p15, 0, r1, c7, c10, 4 -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean single D entry mcr p15, 0, r1, c7, c10, 4 @ drain WB #endif -#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE mcr p15, 0, r1, c7, c5, 1 @ invalidate I entry #endif -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r1, r1 mov r1, r1 #endif @@ -427,14 +427,14 @@ .align 5 ENTRY(cpu_arm1020_icache_invalidate_range) 1: mcr p15, 0, r0, c7, c10, 4 -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ Clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c10, 1 @ Clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB #endif -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 #endif add r0, r0, #DCACHELINESIZE @@ -442,7 +442,7 @@ blo 1b ENTRY(cpu_arm1020_icache_invalidate_page) mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -460,7 +460,7 @@ mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain WB mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D tlbs -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -476,12 +476,15 @@ */ .align 5 ENTRY(cpu_arm1020_tlb_invalidate_range) + sub r3, r1, r0 + cmp r3, #256 * PAGESIZE + bhi cpu_arm1020_tlb_invalidate_all mov r3, #0 mcr p15, 0, r3, c7, c10, 4 @ drain WB 1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry add r0, r0, #PAGESIZE -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 #endif cmp r0, r1 @@ -500,14 +503,14 @@ ENTRY(cpu_arm1020_tlb_invalidate_page) mov r3, #0 mcr p15, 0, r3, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif teq r1, #0 mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -524,7 +527,7 @@ */ .align 5 ENTRY(cpu_arm1020_set_pgd) -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r3, c7, c10, 4 mov r1, #0xF @ 16 segments 1: mov r3, #0x3F @ 64 entries @@ -533,7 +536,7 @@ mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry mov ip, #0 mcr p15, 0, ip, c7, c10, 4 -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov ip, ip #endif subs r3, r3, #1 @@ -545,13 +548,13 @@ #endif mov r1, #0 -#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache #endif mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov ip, ip mov ip, ip #endif @@ -568,18 +571,18 @@ */ .align 5 ENTRY(cpu_arm1020_set_pmd) -#ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r2, r1, #0x0a @ C & Section tst r2, #0x0b biceq r1, r1, #4 @ clear bufferable bit #endif str r1, [r0] -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 4 mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns) #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif @@ -609,47 +612,42 @@ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? movne r2, #0 -#ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r3, r1, #0x0a @ C & small page? tst r3, #0x0b biceq r2, r2, #4 #endif str r2, [r0] @ hardware version mov r0, r0 -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 4 mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE mov r0, r0 mov r0, r0 #endif mov pc, lr -cpu_manu_name: - .asciz "ARM/VLSI" ENTRY(cpu_arm1020_name) .ascii "Arm1020" -#if defined(CONFIG_CPU_ARM1020_CPU_IDLE) - .ascii "s" -#endif -#if defined(CONFIG_CPU_ARM1020_I_CACHE_ON) +#ifndef CONFIG_CPU_ICACHE_DISABLE .ascii "i" #endif -#if defined(CONFIG_CPU_ARM1020_D_CACHE_ON) +#ifndef CONFIG_CPU_DCACHE_DISABLE .ascii "d" -#if defined(CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH) +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH .ascii "(wt)" #else .ascii "(wb)" #endif #endif -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE .ascii "B" #endif -#ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN .ascii "RR" #endif .ascii "\0" @@ -679,16 +677,16 @@ orr r0, r0, #0x0031 @ ..........DP...M orr r0, r0, #0x0100 @ .......S........ -#ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN orr r0, r0, #0x4000 @ .R.............. #endif -#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION +#ifndef CONFIG_CPU_BPREDICT_DISABLE orr r0, r0, #0x0800 @ ....Z........... #endif -#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE orr r0, r0, #0x0004 @ Enable D cache #endif -#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE orr r0, r0, #0x1000 @ I Cache on #endif mov pc, lr @@ -736,7 +734,7 @@ .type cpu_arm1020_info, #object cpu_arm1020_info: - .long cpu_manu_name + .long 0 .long cpu_arm1020_name .size cpu_arm1020_info, . - cpu_arm1020_info @@ -761,7 +759,7 @@ b __arm1020_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB .long cpu_arm1020_info .long arm1020_processor_functions .size __arm1020_proc_info, . - __arm1020_proc_info diff -urN linux-2.4.21/arch/arm/mm/proc-arm1026.S linux-2.4.22/arch/arm/mm/proc-arm1026.S --- linux-2.4.21/arch/arm/mm/proc-arm1026.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mm/proc-arm1026.S 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,660 @@ +/* + * linux/arch/arm/mm/arm1026.S: MMU functions for ARM1026EJ-S + * + * Copyright (C) 2002 ARM Limited + * Copyright (C) 2002 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm1026. + */ +#include +#include +#include +#include +#include +#include + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE 16384 + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 32 +#define ICACHELINESIZE 32 + +/* + * and the page size + */ +#define PAGESIZE 4096 + + .text + +/* + * cpu_arm1026_data_abort() + * + * obtain information about current aborted instruction + * Note: we read user space. This means we might cause a data + * abort here if the I-TLB and D-TLB aren't seeing the same + * picture. Unfortunately, this does happen. We live with it. + * + * Inputs: + * r2 = address of abort + * r3 = cpsr of abort + * + * Returns: + * r0 = address of abort + * r1 != 0 if writing + * r3 = FSR + * r4 = corrupted + */ + .align 5 +ENTRY(cpu_arm1026_data_abort) + mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r2, r3, #0b1101 @ Check for translation error + sub r1, r2, #0b0101 + + and r3, r3, #255 + mrc p15, 0, r0, c6, c0, 0 @ get FAR + + mov pc, lr + +/* + * cpu_arm1026_check_bugs() + */ +ENTRY(cpu_arm1026_check_bugs) + mrs ip, cpsr + bic ip, ip, #F_BIT + msr cpsr, ip + mov pc, lr + +/* + * cpu_arm1026_proc_init() + */ +ENTRY(cpu_arm1026_proc_init) + mov pc, lr + +/* + * cpu_arm1026_proc_fin() + */ +ENTRY(cpu_arm1026_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_arm1026_cache_clean_invalidate_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm1026_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm1026_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm1026_do_idle() + */ + .align 5 +ENTRY(cpu_arm1026_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* ================================= CACHE ================================ */ + + +/* + * cpu_arm1026_cache_clean_invalidate_all() + * + * clean and invalidate all cache lines + * + * Note: + * 1. we should preserve r0 at all times + */ + .align 5 +ENTRY(cpu_arm1026_cache_clean_invalidate_all) + mov r2, #1 +cpu_arm1026_cache_clean_invalidate_all_r2: + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate + bne 1b +#endif + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm1026_cache_clean_invalidate_range(start, end, flags) + * + * clean and invalidate all cache lines associated with this area of memory + * + * This is a little misleading, it is not intended to clean out + * the i-cache but to make sure that any data written to the + * range is made consistant. This means that when we execute code + * in that region, everything works as we expect. + * + * This generally means writing back data in the Dcache and + * write buffer and flushing the Icache over that region + * start: Area start address + * end: Area end address + * flags: nonzero for I cache as well + */ + .align 5 +ENTRY(cpu_arm1026_cache_clean_invalidate_range) + bic r0, r0, #DCACHELINESIZE - 1 @ && added by PGM + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bhi cpu_arm1026_cache_clean_invalidate_all_r2 + +1: teq r2, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE +#else + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE +#endif + + cmp r0, r1 + blo 1b + + mcr p15, 0, r1, c7, c10, 4 @ drain WB + + mov pc, lr + +/* + * cpu_arm1026_flush_ram_page(page) + * + * clean and invalidate all cache lines associated with this area of memory + * + * page: page to clean and invalidate + */ + .align 5 +ENTRY(cpu_arm1026_flush_ram_page) + mov r1, #PAGESIZE +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE +#else +1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE +#endif + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ D-CACHE =============================== */ + +/* + * cpu_arm1026_dcache_invalidate_range(start, end) + * + * throw away all D-cached data in specified region without an obligation + * to write them back. Note however that we must clean the D-cached entries + * around the boundaries if the start and/or end address are not cache + * aligned. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm1026_dcache_invalidate_range) +#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH + tst r0, #DCACHELINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #DCACHELINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +#endif + bic r0, r0, #DCACHELINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blo 1b + mov pc, lr + +/* + * cpu_arm1026_dcache_clean_range(start, end) + * + * For the specified virtual address range, ensure that all caches contain + * clean data, such that peripheral accesses to the physical RAM fetch + * correct data. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm1026_dcache_clean_range) +#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH + bic r0, r0, #DCACHELINESIZE - 1 + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + mov r2, #0 + bhi cpu_arm1026_cache_clean_invalidate_all_r2 + +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, r2, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm1026_dcache_clean_page(page) + * + * Cleans a single page of dcache so that if we have any future aliased + * mappings, they will be consistent at the time that they are created. + * + * page: virtual address of page to clean from dcache + * + * Note: + * 1. we don't need to flush the write buffer in this case. + * 2. we don't invalidate the entries since when we write the page + * out to disk, the entries may get reloaded into the cache. + */ + .align 5 +ENTRY(cpu_arm1026_dcache_clean_page) +#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b +#endif + mov pc, lr + +/* + * cpu_arm1026_dcache_clean_entry(addr) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address + */ + .align 5 +ENTRY(cpu_arm1026_dcache_clean_entry) +#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ I-CACHE =============================== */ + +/* + * cpu_arm1026_icache_invalidate_range(start, end) + * + * This *is not* just icache. It is to make data written to memory + * consistent such that instructions fetched from the region are what + * we expect. + * + * This is typically used after we have copied a module into kernel space, + * and we're about to start executing code from that module. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm1026_icache_invalidate_range) + bic r0, r0, #DCACHELINESIZE - 1 @ Safety check + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bhi cpu_arm1026_cache_clean_invalidate_all_r2 + +1: mcr p15, 0, r0, c7, c5, 1 @ clean I entries + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blo 1b + + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(cpu_arm1026_icache_invalidate_page) + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr + + +/* ================================== TLB ================================= */ + +/* + * cpu_arm1026_tlb_invalidate_all() + * + * Invalidate all TLB entries + */ + .align 5 +ENTRY(cpu_arm1026_tlb_invalidate_all) + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm1026_tlb_invalidate_range(start, end) + * + * invalidate TLB entries covering the specified range + * + * start: range start address + * end: range end address + */ + .align 5 +ENTRY(cpu_arm1026_tlb_invalidate_range) + sub r3, r1, r0 + cmp r3, #256 * PAGESIZE @ arbitary, should be tuned + bhi cpu_arm1026_tlb_invalidate_all + + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + + bic r0, r0, #(PAGESIZE - 1) & 0x00ff + bic r0, r0, #(PAGESIZE - 1) & 0xff00 + +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + add r0, r0, #PAGESIZE + cmp r0, r1 + blo 1b + mov pc, lr + +/* + * cpu_arm1026_tlb_invalidate_page(page, flags) + * + * invalidate the TLB entries for the specified page. + * + * page: page to invalidate + * flags: non-zero if we include the I TLB + */ + .align 5 +ENTRY(cpu_arm1026_tlb_invalidate_page) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + teq r1, #0 + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm1026_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm1026_set_pgd) + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */ + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +@ && 'Clean & Invalidate whole DCache' +1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate + bne 1b +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm1026_set_pmd(pmdp, pmd) + * + * Set a level 1 translation table entry, and clean it out of + * any caches such that the MMUs can load it correctly. + * + * pmdp: pointer to PMD entry + * pmd: PMD value to store + */ + .align 5 +ENTRY(cpu_arm1026_set_pmd) +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r2, r1, #0x0a @ C & Section + tst r2, #0x0b + biceq r1, r1, #4 @ clear bufferable bit +#endif + str r1, [r0] +#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm1026_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm1026_set_pte) + str r1, [r0], #-1024 @ linux version + + eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY + + bic r2, r1, #0xff0 + bic r2, r2, #3 + orr r2, r2, #HPTE_TYPE_SMALL + + tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? + orrne r2, r2, #HPTE_AP_READ + + tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? + orreq r2, r2, #HPTE_AP_WRITE + + tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r2, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + +ENTRY(cpu_arm1026_name) + .ascii "ARM1026EJ-S" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#ifndef CONFIG_CPU_BPREDICT_DISABLE + .ascii "B" +#endif +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + .ascii "RR" +#endif +#endif + .ascii "\0" + .align + + .section ".text.init", #alloc, #execinstr + +__arm1026_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mcr p15, 0, r4, c2, c0 @ load page table pointer + + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #4 @ disable write-back on caches explicitly + mcr p15, 7, r0, c15, c0, 0 +#endif + + mov r0, #0x1f @ Domains 0, 1 = client + mcr p15, 0, r0, c3, c0 @ load domain access register + mrc p15, 0, r0, c1, c0 @ get control register v4 +/* + * Clear out 'unwanted' bits (then put them in if we need them) + */ + @ VI ZFRS BLDP WCAM + bic r0, r0, #0x0e00 + bic r0, r0, #0x0002 + bic r0, r0, #0x000c + bic r0, r0, #0x1000 @ ...0 000. .... 000. +/* + * Turn on what we want + */ + orr r0, r0, #0x0031 + orr r0, r0, #0x2100 @ ..1. ...1 ..11 ...1 + +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .1.. .... .... .... +#endif +#ifndef CONFIG_CPU_BPREDICT_DISABLE + orr r0, r0, #0x0800 @ ....Z........... +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + orr r0, r0, #0x0004 @ .... .... .... .1.. +#endif +#ifndef CONFIG_CPU_ICACHE_DISABLE + orr r0, r0, #0x1000 @ ...1 .... .... .... +#endif + mov pc, lr + + .text + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm1026_processor_functions, #object +arm1026_processor_functions: + .word cpu_arm1026_data_abort + .word cpu_arm1026_check_bugs + .word cpu_arm1026_proc_init + .word cpu_arm1026_proc_fin + .word cpu_arm1026_reset + .word cpu_arm1026_do_idle + + /* cache */ + .word cpu_arm1026_cache_clean_invalidate_all + .word cpu_arm1026_cache_clean_invalidate_range + .word cpu_arm1026_flush_ram_page + + /* dcache */ + .word cpu_arm1026_dcache_invalidate_range + .word cpu_arm1026_dcache_clean_range + .word cpu_arm1026_dcache_clean_page + .word cpu_arm1026_dcache_clean_entry + + /* icache */ + .word cpu_arm1026_icache_invalidate_range + .word cpu_arm1026_icache_invalidate_page + + /* tlb */ + .word cpu_arm1026_tlb_invalidate_all + .word cpu_arm1026_tlb_invalidate_range + .word cpu_arm1026_tlb_invalidate_page + + /* pgtable */ + .word cpu_arm1026_set_pgd + .word cpu_arm1026_set_pmd + .word cpu_arm1026_set_pte + .size arm1026_processor_functions, . - arm1026_processor_functions + + .type cpu_arm1026_info, #object +cpu_arm1026_info: + .long 0 + .long cpu_arm1026_name + .size cpu_arm1026_info, . - cpu_arm1026_info + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5EJ" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5EJ" + .size cpu_elf_name, . - cpu_elf_name + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm1026_proc_info,#object +__arm1026_proc_info: + .long 0x4100a260 + .long 0xff00fff0 + .long 0x00000c1e @ mmuflags + b __arm1026_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | \ + HWCAP_FAST_MULT + .long cpu_arm1026_info + .long arm1026_processor_functions + .size __arm1026_proc_info, . - __arm1026_proc_info diff -urN linux-2.4.21/arch/arm/mm/proc-arm2,3.S linux-2.4.22/arch/arm/mm/proc-arm2,3.S --- linux-2.4.21/arch/arm/mm/proc-arm2,3.S 2001-03-06 19:44:35.000000000 -0800 +++ linux-2.4.22/arch/arm/mm/proc-arm2,3.S 2003-08-25 04:44:39.000000000 -0700 @@ -275,7 +275,6 @@ _arm2_3_check_bugs: bics pc, lr, #0x04000000 @ Clear FIQ disable bit -armvlsi_name: .asciz "ARM/VLSI" _arm2_name: .asciz "ARM 2" _arm250_name: .asciz "ARM 250" _arm3_name: .asciz "ARM 3" @@ -295,7 +294,7 @@ .word _arm2_xchg_4 cpu_arm2_info: - .long armvlsi_name + .long 0 .long _arm2_name .globl SYMBOL_NAME(arm250_processor_functions) @@ -308,7 +307,7 @@ .word _arm3_xchg_4 cpu_arm250_info: - .long armvlsi_name + .long 0 .long _arm250_name .globl SYMBOL_NAME(arm3_processor_functions) @@ -321,7 +320,7 @@ .word _arm3_xchg_4 cpu_arm3_info: - .long armvlsi_name + .long 0 .long _arm3_name arm2_arch_name: .asciz "armv1" diff -urN linux-2.4.21/arch/arm/mm/proc-arm6,7.S linux-2.4.22/arch/arm/mm/proc-arm6,7.S --- linux-2.4.21/arch/arm/mm/proc-arm6,7.S 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/proc-arm6,7.S 2003-08-25 04:44:39.000000000 -0700 @@ -68,13 +68,27 @@ * Purpose : flush a TLB entry */ ENTRY(cpu_arm6_tlb_invalidate_range) -ENTRY(cpu_arm7_tlb_invalidate_range) -1: mcr p15, 0, r0, c6, c0, 0 @ flush TLB + @ arm 6 tbl purge reg is bits 12 - 31 +1: mcr p15, 0, r0, c6, c0, 0 @ purge TLB add r0, r0, #4096 cmp r0, r1 blt 1b mov pc, lr +ENTRY(cpu_arm7_tlb_invalidate_range) +#if defined(CONFIG_ARCH_RISCSTATION) + mov r0, #0 + mcr p15, 0, r0, c5, c0, 0 @ flush TLB + mov pc, lr +#else + @ arm 7 tbl purge reg is bits 14 - 31 +1: mcr p15, 0, r0, c6, c0, 0 @ purge TLB + add r0, r0, #0x4000 + cmp r0, r1 + blt 1b + mov pc, lr +#endif + /* * Function: arm6_7_tlb_invalidate_page (unsigned long address, int flags) * @@ -143,7 +157,7 @@ movs pc, lr b Ldata_unknown - b Ldata_unknown + b Ldata_simple @ swp b Ldata_unknown b Ldata_unknown b Ldata_lateldrpostconst @ ldr rd, [rn], #m @@ -160,7 +174,7 @@ Ldata_unknown: @ Part of jumptable mov r0, r2 mov r1, r4 - mov r2, r3 + mov r2, r5 bl baddataabort b ret_from_exception @@ -258,7 +272,6 @@ ENTRY(cpu_arm6_do_idle) ENTRY(cpu_arm7_do_idle) - mov r0, #-EINVAL mov pc, lr /* @@ -349,8 +362,6 @@ mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc mov pc, r0 -cpu_armvlsi_name: - .asciz "ARM/VLSI" cpu_arm6_name: .asciz "ARM 6" cpu_arm610_name: .asciz "ARM 610" @@ -461,25 +472,25 @@ .type cpu_arm6_info, #object cpu_arm6_info: - .long cpu_armvlsi_name + .long 0 .long cpu_arm6_name .size cpu_arm6_info, . - cpu_arm6_info .type cpu_arm610_info, #object cpu_arm610_info: - .long cpu_armvlsi_name + .long 0 .long cpu_arm610_name .size cpu_arm610_info, . - cpu_Arm610_info .type cpu_arm7_info, #object cpu_arm7_info: - .long cpu_armvlsi_name + .long 0 .long cpu_arm7_name .size cpu_arm7_info, . - cpu_arm7_info .type cpu_arm710_info, #object cpu_arm710_info: - .long cpu_armvlsi_name + .long 0 .long cpu_arm710_name .size cpu_arm710_info, . - cpu_arm710_info diff -urN linux-2.4.21/arch/arm/mm/proc-arm720.S linux-2.4.22/arch/arm/mm/proc-arm720.S --- linux-2.4.21/arch/arm/mm/proc-arm720.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/proc-arm720.S 2003-08-25 04:44:39.000000000 -0700 @@ -37,6 +37,11 @@ #include /* + * and the page size + */ +#define PAGESIZE 4096 + +/* * Function: arm720_cache_clean_invalidate_all (void) * : arm720_cache_clean_invalidate_page (unsigned long address, int size, * int flags) @@ -86,8 +91,11 @@ * Purpose : flush a TLB entry */ ENTRY(cpu_arm720_tlb_invalidate_range) + sub r3, r1, r0 + cmp r3, #256 * PAGESIZE @ arbitary, should be tuned + bhi cpu_arm720_tlb_invalidate_all 1: mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4) - add r0, r0, #4096 + add r0, r0, #PAGESIZE cmp r0, r1 blt 1b mov pc, lr @@ -438,8 +446,6 @@ mov pc, r0 -cpu_armvlsi_name: - .asciz "ARM" cpu_arm720_name: .asciz "ARM720T" .align @@ -500,7 +506,7 @@ .type cpu_arm720_info, #object cpu_arm720_info: - .long cpu_armvlsi_name + .long 0 .long cpu_arm720_name .size cpu_arm720_info, . - cpu_arm720_info @@ -527,7 +533,7 @@ b __arm720_setup @ cpu_flush .long cpu_arch_name @ arch_name .long cpu_elf_name @ elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT @ elf_hwcap + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap .long cpu_arm720_info @ info .long arm720_processor_functions .size __arm720_proc_info, . - __arm720_proc_info diff -urN linux-2.4.21/arch/arm/mm/proc-arm920.S linux-2.4.22/arch/arm/mm/proc-arm920.S --- linux-2.4.21/arch/arm/mm/proc-arm920.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/proc-arm920.S 2003-08-25 04:44:39.000000000 -0700 @@ -134,9 +134,7 @@ */ .align 5 ENTRY(cpu_arm920_do_idle) -#if defined(CONFIG_CPU_ARM920_CPU_IDLE) mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt -#endif mov pc, lr /* ================================= CACHE ================================ */ @@ -155,7 +153,7 @@ mov r2, #1 cpu_arm920_cache_clean_invalidate_all_r2: mov ip, #0 -#ifdef CONFIG_CPU_ARM920_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else /* @@ -193,7 +191,7 @@ cmp r3, #MAX_AREA_SIZE bgt cpu_arm920_cache_clean_invalidate_all_r2 1: teq r2, #0 -#ifdef CONFIG_CPU_ARM920_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry add r0, r0, #DCACHELINESIZE @@ -224,7 +222,7 @@ .align 5 ENTRY(cpu_arm920_flush_ram_page) mov r1, #PAGESIZE -#ifdef CONFIG_CPU_ARM920_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry @@ -410,6 +408,10 @@ */ .align 5 ENTRY(cpu_arm920_tlb_invalidate_range) + sub r3, r1, r0 + cmp r3, #256 * PAGESIZE @ arbitary, should be tuned + bhi cpu_arm920_tlb_invalidate_all + mov r3, #0 mcr p15, 0, r3, c7, c10, 4 @ drain WB @@ -454,7 +456,7 @@ .align 5 ENTRY(cpu_arm920_set_pgd) mov ip, #0 -#ifdef CONFIG_CPU_ARM920_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else @@ -487,7 +489,7 @@ */ .align 5 ENTRY(cpu_arm920_set_pmd) -#ifdef CONFIG_CPU_ARM920_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r2, r1, #0x0a @ C & Section tst r2, #0x0b biceq r1, r1, #4 @ clear bufferable bit @@ -521,7 +523,7 @@ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? movne r2, #0 -#ifdef CONFIG_CPU_ARM920_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r3, r2, #0x0a @ C & small page? tst r3, #0x0b biceq r2, r2, #4 @@ -533,19 +535,14 @@ mov pc, lr -cpu_manu_name: - .asciz "ARM/CIRRUS" ENTRY(cpu_arm920_name) .ascii "Arm920T" -#if defined(CONFIG_CPU_ARM920_CPU_IDLE) - .ascii "s" -#endif -#if defined(CONFIG_CPU_ARM920_I_CACHE_ON) +#ifndef CONFIG_CPU_ICACHE_DISABLE .ascii "i" #endif -#if defined(CONFIG_CPU_ARM920_D_CACHE_ON) +#ifndef CONFIG_CPU_DCACHE_DISABLE .ascii "d" -#if defined(CONFIG_CPU_ARM920_WRITETHROUGH) +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH .ascii "(wt)" #else .ascii "(wb)" @@ -579,10 +576,10 @@ orr r0, r0, #0x0031 orr r0, r0, #0x2100 @ ..1. ...1 ..11 ...1 -#ifdef CONFIG_CPU_ARM920_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE orr r0, r0, #0x0004 @ .... .... .... .1.. #endif -#ifdef CONFIG_CPU_ARM920_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE orr r0, r0, #0x1000 @ ...1 .... .... .... #endif mov pc, lr @@ -630,7 +627,7 @@ .type cpu_arm920_info, #object cpu_arm920_info: - .long cpu_manu_name + .long 0 .long cpu_arm920_name .size cpu_arm920_info, . - cpu_arm920_info @@ -655,7 +652,7 @@ b __arm920_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB .long cpu_arm920_info .long arm920_processor_functions .size __arm920_proc_info, . - __arm920_proc_info diff -urN linux-2.4.21/arch/arm/mm/proc-arm922.S linux-2.4.22/arch/arm/mm/proc-arm922.S --- linux-2.4.21/arch/arm/mm/proc-arm922.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/proc-arm922.S 2003-08-25 04:44:39.000000000 -0700 @@ -130,9 +130,7 @@ */ .align 5 ENTRY(cpu_arm922_do_idle) -#if defined(CONFIG_CPU_ARM922_CPU_IDLE) mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt -#endif mov pc, lr /* ================================= CACHE ================================ */ @@ -151,7 +149,7 @@ mov r2, #1 cpu_arm922_cache_clean_invalidate_all_r2: mov ip, #0 -#ifdef CONFIG_CPU_ARM922_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else /* @@ -189,7 +187,7 @@ cmp r3, #MAX_AREA_SIZE bgt cpu_arm922_cache_clean_invalidate_all_r2 1: teq r2, #0 -#ifdef CONFIG_CPU_ARM922_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry add r0, r0, #DCACHELINESIZE @@ -220,7 +218,7 @@ .align 5 ENTRY(cpu_arm922_flush_ram_page) mov r1, #PAGESIZE -#ifdef CONFIG_CPU_ARM922_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry @@ -406,6 +404,10 @@ */ .align 5 ENTRY(cpu_arm922_tlb_invalidate_range) + sub r3, r1, r0 + cmp r3, #256 * PAGESIZE @ arbitary, should be tuned + bhi cpu_arm922_tlb_invalidate_all + mov r3, #0 mcr p15, 0, r3, c7, c10, 4 @ drain WB @@ -450,7 +452,7 @@ .align 5 ENTRY(cpu_arm922_set_pgd) mov ip, #0 -#ifdef CONFIG_CPU_ARM922_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else @@ -483,7 +485,7 @@ */ .align 5 ENTRY(cpu_arm922_set_pmd) -#ifdef CONFIG_CPU_ARM922_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r2, r1, #0x0a @ C & Section tst r2, #0x0b biceq r1, r1, #4 @ clear bufferable bit @@ -517,7 +519,7 @@ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? movne r2, #0 -#ifdef CONFIG_CPU_ARM922_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r3, r2, #0x0a @ C & small page? tst r3, #0x0b biceq r2, r2, #4 @@ -529,19 +531,14 @@ mov pc, lr -cpu_manu_name: - .asciz "ARM/ALTERA" ENTRY(cpu_arm922_name) .ascii "Arm922T" -#if defined(CONFIG_CPU_ARM922_CPU_IDLE) - .ascii "s" -#endif -#if defined(CONFIG_CPU_ARM922_I_CACHE_ON) +#ifndef CONFIG_CPU_ICACHE_DISABLE .ascii "i" #endif -#if defined(CONFIG_CPU_ARM922_D_CACHE_ON) +#ifndef CONFIG_CPU_DCACHE_DISABLE .ascii "d" -#if defined(CONFIG_CPU_ARM922_WRITETHROUGH) +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH .ascii "(wt)" #else .ascii "(wb)" @@ -575,10 +572,10 @@ orr r0, r0, #0x0031 orr r0, r0, #0x2100 @ ..1. ...1 ..11 ...1 -#ifdef CONFIG_CPU_ARM922_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE orr r0, r0, #0x0004 @ .... .... .... .1.. #endif -#ifdef CONFIG_CPU_ARM922_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE orr r0, r0, #0x1000 @ ...1 .... .... .... #endif mov pc, lr @@ -626,7 +623,7 @@ .type cpu_arm922_info, #object cpu_arm922_info: - .long cpu_manu_name + .long 0 .long cpu_arm922_name .size cpu_arm922_info, . - cpu_arm922_info @@ -651,7 +648,7 @@ b __arm922_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB .long cpu_arm922_info .long arm922_processor_functions .size __arm922_proc_info, . - __arm922_proc_info diff -urN linux-2.4.21/arch/arm/mm/proc-arm925.S linux-2.4.22/arch/arm/mm/proc-arm925.S --- linux-2.4.21/arch/arm/mm/proc-arm925.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/arm/mm/proc-arm925.S 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,732 @@ +/* + * linux/arch/arm/mm/arm925.S: MMU functions for ARM925 + * + * Copyright (C) 1999-2001 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * Copyright (C) 2002 RidgeRun, Inc. + * Copyright (C) 2002 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm925. + */ +#include +#include +#include +#include +#include +#include + + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE (2 * 1024) + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 16 +#define ICACHELINESIZE 16 + +/* + * and the page size + */ +#define PAGESIZE 4096 + + .text + +/* + * cpu_arm925_data_abort() + * + * obtain information about current aborted instruction + * Note: we read user space. This means we might cause a data + * abort here if the I-TLB and D-TLB aren't seeing the same + * picture. Unfortunately, this does happen. We live with it. + * + * Inputs: + * r2 = address of abort + * r3 = cpsr of abort + * + * Returns: + * r0 = address of abort + * r1 != 0 if writing + * r3 = FSR + * r4 = corrupted + */ + .align 5 +ENTRY(cpu_arm925_data_abort) + mrc p15, 0, r0, c6, c0, 0 @ get FAR + mrc p15, 0, r4, c5, c0, 0 @ get FSR + + tst r3, #1<<5 @ Check for Thumb-bit (NE -> found) + ldrneh r1, [r2] @ Read aborted Thumb instruction + tstne r1, r1, lsr #12 @ C = bit 11 + + ldreq r1, [r2] @ Read aborted ARM instruction + tsteq r1, r1, lsr #21 @ C = bit 20 + + sbc r1, r1, r1 @ r1 = C - 1 + and r3, r4, #255 + mov pc, lr + +/* + * cpu_arm925_check_bugs() + */ +ENTRY(cpu_arm925_check_bugs) + mrs ip, cpsr + bic ip, ip, #F_BIT + msr cpsr, ip + mov pc, lr + +/* + * cpu_arm925_proc_init() + */ +ENTRY(cpu_arm925_proc_init) + mov pc, lr + +/* + * cpu_arm925_proc_fin() + */ +ENTRY(cpu_arm925_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_arm925_cache_clean_invalidate_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm925_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm925_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm925_do_idle() + */ + .align 5 +ENTRY(cpu_arm925_do_idle) +#if defined(CONFIG_CPU_ARM925_CPU_IDLE) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt +#endif + mov pc, lr + +/* ================================= CACHE ================================ */ + + +/* + * cpu_arm925_cache_clean_invalidate_all() + * + * clean and invalidate all cache lines + * + * Note: + * 1. we should preserve r0 at all times + */ + .align 5 +ENTRY(cpu_arm925_cache_clean_invalidate_all) + mov r2, #1 +cpu_arm925_cache_clean_invalidate_all_r2: + mov ip, #0 +#ifdef CONFIG_CPU_ARM925_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +/* + * 'Clean & Invalidate whole DCache' + * Re-written to use Index Ops. + * NOTE: Requires TI925T Configuration Register C bit <- 0 + * for clean and invalidate of both D-Cache sets. + */ + mov r3, #255 << 4 @ 256 entries/set + @ ((NSETS - 1) << (CIR[13-12] + 3)) +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 4 + bcs 2b @ entries 255 to 0 +#endif + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm925_cache_clean_invalidate_range(start, end, flags) + * + * clean and invalidate all cache lines associated with this area of memory + * + * This is a little misleading, it is not intended to clean out + * the i-cache but to make sure that any data written to the + * range is made consistant. This means that when we execute code + * in that region, everything works as we expect. + * + * This generally means writing back data in the Dcache and + * write buffer and flushing the Icache over that region + * start: Area start address + * end: Area end address + * flags: nonzero for I cache as well + */ + .align 5 +ENTRY(cpu_arm925_cache_clean_invalidate_range) + bic r0, r0, #DCACHELINESIZE - 1 @ && added by PGM + bic r1, r1, #DCACHELINESIZE - 1 @ && added by DHM + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bgt cpu_arm925_cache_clean_invalidate_all_r2 +1: teq r2, #0 +#ifdef CONFIG_CPU_ARM925_WRITETHROUGH + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE +#else + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #DCACHELINESIZE +#endif + cmp r0, r1 + blt 1b + + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm925_flush_ram_page(page) + * + * clean and invalidate all cache lines associated with this area of memory + * + * page: page to clean and invalidate + */ + .align 5 +ENTRY(cpu_arm925_flush_ram_page) + mov r1, #PAGESIZE +#ifdef CONFIG_CPU_ARM925_WRITETHROUGH +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE +#else +1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE +#endif + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ D-CACHE =============================== */ + +/* + * cpu_arm925_dcache_invalidate_range(start, end) + * + * throw away all D-cached data in specified region without an obligation + * to write them back. Note however that we must clean the D-cached entries + * around the boundaries if the start and/or end address are not cache + * aligned. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm925_dcache_invalidate_range) +#ifndef CONFIG_CPU_ARM925_WRITETHROUGH + tst r0, #DCACHELINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #DCACHELINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +#endif + bic r0, r0, #DCACHELINESIZE - 1 + bic r1, r1, #DCACHELINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + mov pc, lr + +/* + * cpu_arm925_dcache_clean_range(start, end) + * + * For the specified virtual address range, ensure that all caches contain + * clean data, such that peripheral accesses to the physical RAM fetch + * correct data. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm925_dcache_clean_range) +#ifndef CONFIG_CPU_ARM925_WRITETHROUGH + bic r0, r0, #DCACHELINESIZE - 1 + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + mov r2, #0 + bgt cpu_arm925_cache_clean_invalidate_all_r2 + + bic r1, r1, #DCACHELINESIZE -1 + add r1, r1, #DCACHELINESIZE + +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #DCACHELINESIZE + bpl 1b +#endif + mcr p15, 0, r2, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm925_dcache_clean_page(page) + * + * Cleans a single page of dcache so that if we have any future aliased + * mappings, they will be consistent at the time that they are created. + * + * page: virtual address of page to clean from dcache + * + * Note: + * 1. we don't need to flush the write buffer in this case. + * 2. we don't invalidate the entries since when we write the page + * out to disk, the entries may get reloaded into the cache. + */ + .align 5 +ENTRY(cpu_arm925_dcache_clean_page) +#ifndef CONFIG_CPU_ARM925_WRITETHROUGH + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b +#endif + mov pc, lr + +/* + * cpu_arm925_dcache_clean_entry(addr) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address + */ + .align 5 +ENTRY(cpu_arm925_dcache_clean_entry) +#ifndef CONFIG_CPU_ARM925_WRITETHROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ I-CACHE =============================== */ + +/* + * cpu_arm925_icache_invalidate_range(start, end) + * + * invalidate a range of virtual addresses from the Icache + * + * This is a little misleading, it is not intended to clean out + * the i-cache but to make sure that any data written to the + * range is made consistant. This means that when we execute code + * in that region, everything works as we expect. + * + * This generally means writing back data in the Dcache and + * write buffer and flushing the Icache over that region + * + * start: virtual start address + * end: virtual end address + * + * NOTE: ICACHELINESIZE == DCACHELINESIZE (so we don't need to + * loop twice, once for i-cache, once for d-cache) + */ + .align 5 +ENTRY(cpu_arm925_icache_invalidate_range) + bic r0, r0, #ICACHELINESIZE - 1 @ Safety check + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + bgt cpu_arm925_cache_clean_invalidate_all_r2 + + bic r1, r1, #ICACHELINESIZE - 1 + add r1, r1, #ICACHELINESIZE + +1: mcr p15, 0, r0, c7, c5, 1 @ Clean I entry + mcr p15, 0, r0, c7, c10, 1 @ Clean D entry + add r0, r0, #ICACHELINESIZE + subs r1, r1, #ICACHELINESIZE + bne 1b + + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + +ENTRY(cpu_arm925_icache_invalidate_page) + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + nop + nop + nop + nop + mov pc, lr + +/* ================================== TLB ================================= */ + +/* + * cpu_arm925_tlb_invalidate_all() + * + * Invalidate all TLB entries + */ + .align 5 +ENTRY(cpu_arm925_tlb_invalidate_all) + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm925_tlb_invalidate_range(start, end) + * + * invalidate TLB entries covering the specified range + * + * start: range start address + * end: range end address + */ + .align 5 +ENTRY(cpu_arm925_tlb_invalidate_range) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + + mov r3, #PAGESIZE + sub r3, r3, #1 + bic r0, r0, r3 + bic r1, r1, r3 + +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + add r0, r0, #PAGESIZE + cmp r0, r1 + blt 1b + mov pc, lr + +/* + * cpu_arm925_tlb_invalidate_page(page, flags) + * + * invalidate the TLB entries for the specified page. + * + * page: page to invalidate + * flags: non-zero if we include the I TLB + */ + .align 5 +ENTRY(cpu_arm925_tlb_invalidate_page) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + teq r1, #0 + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm925_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm925_set_pgd) + mov ip, #0 +#ifdef CONFIG_CPU_ARM925_WRITETHROUGH + mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D cache +#else +/* + * 'Clean & Invalidate whole DCache' + * Re-written to use Index Ops. + * NOTE: Requires TI925T Configuration Register C bit <- 0 + * for clean and invalidate of both D-Cache sets. + */ + mov r3, #255 << 4 @ 256 entries/set + @ ((NSETS - 1) << (CIR[13-12] + 3)) +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 4 + bcs 2b @ entries 255 to 0 +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm925_set_pmd(pmdp, pmd) + * + * Set a level 1 translation table entry, and clean it out of + * any caches such that the MMUs can load it correctly. + * + * pmdp: pointer to PMD entry + * pmd: PMD value to store + */ + .align 5 +ENTRY(cpu_arm925_set_pmd) +#ifdef CONFIG_CPU_ARM925_WRITETHROUGH + eor r2, r1, #0x0a @ C & Section + tst r2, #0x0b + biceq r1, r1, #4 @ clear bufferable bit +#endif + str r1, [r0] + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm925_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm925_set_pte) + str r1, [r0], #-1024 @ linux version + + eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY + + bic r2, r1, #0xff0 + bic r2, r2, #3 + orr r2, r2, #HPTE_TYPE_SMALL + + tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? + orrne r2, r2, #HPTE_AP_READ + + tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? + orreq r2, r2, #HPTE_AP_WRITE + + tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_ARM925_WRITETHROUGH + eor r3, r2, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + +ENTRY(cpu_arm925_name) + .ascii "Arm925T" +#if defined(CONFIG_CPU_ARM925_CPU_IDLE) + .ascii "s" +#endif +#if defined(CONFIG_CPU_ARM925_I_CACHE_ON) + .ascii "i" +#endif +#if defined(CONFIG_CPU_ARM925_D_CACHE_ON) + .ascii "d" +#if defined(CONFIG_CPU_ARM925_WRITETHROUGH) + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif + .ascii "\0" + +ENTRY(cpu_arm915_name) + .ascii "Arm915T" +#if defined(CONFIG_CPU_ARM925_CPU_IDLE) + .ascii "s" +#endif +#if defined(CONFIG_CPU_ARM925_I_CACHE_ON) + .ascii "i" +#endif +#if defined(CONFIG_CPU_ARM925_D_CACHE_ON) + .ascii "d" +#if defined(CONFIG_CPU_ARM925_WRITETHROUGH) + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif + .ascii "\0" + .align + + .section ".text.init", #alloc, #execinstr + +__arm925_setup: + mov r0, #0 +#if defined(CONFIG_CPU_ARM925_NON_STREAMING_ON) + orr r0,r0,#0x80 +#endif +#if defined(CONFIG_CPU_ARM925_TRANSPARENT_ON) + orr r0,r0,#0x2 +#endif + mcr p15, 0, r0, c15, c1, 0 @ write TI config register + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mcr p15, 0, r4, c2, c0 @ load page table pointer + mov r0, #0x1f @ Domains 0, 1 = client + mcr p15, 0, r0, c3, c0 @ load domain access register + mrc p15, 0, r0, c1, c0 @ get control register v4 +/* + * Clear out 'unwanted' bits (then put them in if we need them) + */ + @ VI ZFRS BLDP WCAM + bic r0, r0, #0x0e00 + bic r0, r0, #0x0002 + bic r0, r0, #0x000c + bic r0, r0, #0x1000 @ ...0 000. .... 000. +/* + * Turn on what we want + */ + orr r0, r0, #0x0031 + orr r0, r0, #0x2100 @ ..1. ...1 ..11 ...1 + +#ifdef CONFIG_CPU_ARM925_WRITEBUFFER_ON + orr r0, r0, #0x0008 @ .... .... .... 1... +#endif +#ifdef CONFIG_CPU_ARM925_D_CACHE_ON + orr r0, r0, #0x0004 @ .... .... .... .1.. +#endif +#ifdef CONFIG_CPU_ARM925_I_CACHE_ON + orr r0, r0, #0x1000 @ ...1 .... .... .... +#endif + mov pc, lr + + .text + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm925_processor_functions, #object +arm925_processor_functions: + .word cpu_arm925_data_abort + .word cpu_arm925_check_bugs + .word cpu_arm925_proc_init + .word cpu_arm925_proc_fin + .word cpu_arm925_reset + .word cpu_arm925_do_idle + + /* cache */ + .word cpu_arm925_cache_clean_invalidate_all + .word cpu_arm925_cache_clean_invalidate_range + .word cpu_arm925_flush_ram_page + + /* dcache */ + .word cpu_arm925_dcache_invalidate_range + .word cpu_arm925_dcache_clean_range + .word cpu_arm925_dcache_clean_page + .word cpu_arm925_dcache_clean_entry + + /* icache */ + .word cpu_arm925_icache_invalidate_range + .word cpu_arm925_icache_invalidate_page + + /* tlb */ + .word cpu_arm925_tlb_invalidate_all + .word cpu_arm925_tlb_invalidate_range + .word cpu_arm925_tlb_invalidate_page + + /* pgtable */ + .word cpu_arm925_set_pgd + .word cpu_arm925_set_pmd + .word cpu_arm925_set_pte + .size arm925_processor_functions, . - arm925_processor_functions + + .type cpu_arm925_info, #object +cpu_arm925_info: + .long 0 + .long cpu_arm925_name + .size cpu_arm925_info, . - cpu_arm925_info + + .type cpu_arm915_info, #object +cpu_arm915_info: + .long cpu_manu_name + .long cpu_arm915_name + .size cpu_arm915_info, . - cpu_arm915_info + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + .align + +#if defined(CONFIG_CPU_ARM925_WRITETHROUGH) +# define MMU_FLAGS 0x00000c1a +#else +# define MMU_FLAGS 0x00000c1e +#endif + .section ".proc.info", #alloc, #execinstr + + .type __arm925_proc_info,#object +__arm925_proc_info: + .long 0x54029252 + .long 0xffffffff + .long MMU_FLAGS + b __arm925_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm925_info + .long arm925_processor_functions + .size __arm925_proc_info, . - __arm925_proc_info + + .type __arm915_proc_info,#object +__arm915_proc_info: + .long 0x54029152 + .long 0xffffffff + .long MMU_FLAGS + b __arm925_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm915_info + .long arm925_processor_functions + .size __arm925_proc_info, . - __arm925_proc_info diff -urN linux-2.4.21/arch/arm/mm/proc-arm926.S linux-2.4.22/arch/arm/mm/proc-arm926.S --- linux-2.4.21/arch/arm/mm/proc-arm926.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/proc-arm926.S 2003-08-25 04:44:39.000000000 -0700 @@ -81,9 +81,8 @@ tst r3, #1<<5 @ Check for Thumb-bit (NE -> found) ldrneh r1, [r2] @ Read aborted Thumb instruction - tstne r1, r1, lsr #12 @ C = bit 11 - ldreq r1, [r2] @ Read aborted ARM instruction + movne r1, r1, lsl #(20-12) @ shift thumb bit 10 to ARM bit 20 tsteq r1, r1, lsr #21 @ C = bit 20 sbc r1, r1, r1 @ r1 = C - 1 @@ -146,9 +145,7 @@ */ .align 5 ENTRY(cpu_arm926_do_idle) -#if defined(CONFIG_CPU_ARM926_CPU_IDLE) mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt -#endif mov pc, lr /* ================================= CACHE ================================ */ @@ -167,7 +164,7 @@ mov r2, #1 cpu_arm926_cache_clean_invalidate_all_r2: mov ip, #0 -#ifdef CONFIG_CPU_ARM926_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate @@ -202,7 +199,7 @@ bhi cpu_arm926_cache_clean_invalidate_all_r2 1: teq r2, #0 -#ifdef CONFIG_CPU_ARM926_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry add r0, r0, #DCACHELINESIZE @@ -235,7 +232,7 @@ .align 5 ENTRY(cpu_arm926_flush_ram_page) mov r1, #PAGESIZE -#ifdef CONFIG_CPU_ARM926_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #DCACHELINESIZE mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry @@ -408,6 +405,10 @@ */ .align 5 ENTRY(cpu_arm926_tlb_invalidate_range) + sub r3, r1, r0 + cmp r3, #256 * PAGESIZE @ arbitary, should be tuned + bhi cpu_arm926_tlb_invalidate_all + mov r3, #0 mcr p15, 0, r3, c7, c10, 4 @ drain WB @@ -450,7 +451,7 @@ .align 5 ENTRY(cpu_arm926_set_pgd) mov ip, #0 -#ifdef CONFIG_CPU_ARM926_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else @@ -475,7 +476,7 @@ */ .align 5 ENTRY(cpu_arm926_set_pmd) -#ifdef CONFIG_CPU_ARM926_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r2, r1, #0x0a @ C & Section tst r2, #0x0b biceq r1, r1, #4 @ clear bufferable bit @@ -511,38 +512,33 @@ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? movne r2, #0 -#ifdef CONFIG_CPU_ARM926_WRITETHROUGH +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH eor r3, r2, #0x0a @ C & small page? tst r3, #0x0b biceq r2, r2, #4 #endif str r2, [r0] @ hardware version mov r0, r0 -#ifndef CONFIG_CPU_ARM926_WRITETHROUGH +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr -cpu_manu_name: - .asciz "ARM" ENTRY(cpu_arm926_name) .ascii "ARM926EJ-S" -#if defined(CONFIG_CPU_ARM926_CPU_IDLE) - .ascii "s" -#endif -#if defined(CONFIG_CPU_ARM926_I_CACHE_ON) +#ifndef CONFIG_CPU_ICACHE_DISABLE .ascii "i" #endif -#if defined(CONFIG_CPU_ARM926_D_CACHE_ON) +#ifndef CONFIG_CPU_DCACHE_DISABLE .ascii "d" -#if defined(CONFIG_CPU_ARM926_WRITETHROUGH) +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH .ascii "(wt)" #else .ascii "(wb)" #endif -#ifdef CONFIG_CPU_ARM926_ROUND_ROBIN +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN .ascii "RR" #endif #endif @@ -559,7 +555,7 @@ mcr p15, 0, r4, c2, c0 @ load page table pointer -#if defined(CONFIG_CPU_ARM926_WRITETHROUGH) +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ disable write-back on caches explicitly mcr p15, 7, r0, c15, c0, 0 #endif @@ -581,13 +577,13 @@ orr r0, r0, #0x0031 orr r0, r0, #0x2100 @ ..1. ...1 ..11 ...1 -#ifdef CONFIG_CPU_ARM926_ROUND_ROBIN +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN orr r0, r0, #0x4000 @ .1.. .... .... .... #endif -#ifdef CONFIG_CPU_ARM926_D_CACHE_ON +#ifndef CONFIG_CPU_DCACHE_DISABLE orr r0, r0, #0x0004 @ .... .... .... .1.. #endif -#ifdef CONFIG_CPU_ARM926_I_CACHE_ON +#ifndef CONFIG_CPU_ICACHE_DISABLE orr r0, r0, #0x1000 @ ...1 .... .... .... #endif mov pc, lr @@ -635,7 +631,7 @@ .type cpu_arm926_info, #object cpu_arm926_info: - .long cpu_manu_name + .long 0 .long cpu_arm926_name .size cpu_arm926_info, . - cpu_arm926_info @@ -660,7 +656,8 @@ b __arm926_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | \ + HWCAP_FAST_MULT .long cpu_arm926_info .long arm926_processor_functions .size __arm926_proc_info, . - __arm926_proc_info diff -urN linux-2.4.21/arch/arm/mm/proc-sa110.S linux-2.4.22/arch/arm/mm/proc-sa110.S --- linux-2.4.21/arch/arm/mm/proc-sa110.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/proc-sa110.S 2003-08-25 04:44:39.000000000 -0700 @@ -159,43 +159,12 @@ mov pc, r0 /* - * cpu_sa110_do_idle(type) + * cpu_sa110_do_idle() * * Cause the processor to idle - * - * type: call type: - * 0 = slow idle - * 1 = fast idle - * 2 = switch to slow processor clock - * 3 = switch to fast processor clock */ .align 5 -idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned - mov r0, r0 @ safety - mov pc, lr - ENTRY(cpu_sa110_do_idle) - mov ip, #0 - cmp r0, #4 - addcc pc, pc, r0, lsl #2 - mov pc, lr - - b idle - b idle - b slow_clock - b fast_clock - -fast_clock: - mcr p15, 0, ip, c15, c1, 2 @ enable clock switching - mov pc, lr - -slow_clock: - mcr p15, 0, ip, c15, c2, 2 @ disable clock switching - ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc - ldr r1, [r1, #0] @ force switch to MCLK - mov pc, lr - - .align 5 ENTRY(cpu_sa1100_do_idle) mov r0, r0 @ 4 nop padding mov r0, r0 @@ -468,6 +437,9 @@ ENTRY(cpu_sa1100_tlb_invalidate_range) bic r0, r0, #0x0ff bic r0, r0, #0xf00 + sub r3, r1, r0 + cmp r3, #256 * PAGESIZE @ arbitary, should be tuned + bhi cpu_sa110_tlb_invalidate_all mov r3, #0 mcr p15, 0, r3, c7, c10, 4 @ drain WB 1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry @@ -595,8 +567,6 @@ mov pc, lr -cpu_manu_name: - .asciz "Intel" cpu_sa110_name: .asciz "StrongARM-110" cpu_sa1100_name: @@ -676,7 +646,7 @@ .type cpu_sa110_info, #object cpu_sa110_info: - .long cpu_manu_name + .long 0 .long cpu_sa110_name .size cpu_sa110_info, . - cpu_sa110_info @@ -720,12 +690,12 @@ .size sa1100_processor_functions, . - sa1100_processor_functions cpu_sa1100_info: - .long cpu_manu_name + .long 0 .long cpu_sa1100_name .size cpu_sa1100_info, . - cpu_sa1100_info cpu_sa1110_info: - .long cpu_manu_name + .long 0 .long cpu_sa1110_name .size cpu_sa1110_info, . - cpu_sa1110_info diff -urN linux-2.4.21/arch/arm/mm/small_page.c linux-2.4.22/arch/arm/mm/small_page.c --- linux-2.4.21/arch/arm/mm/small_page.c 2001-04-12 12:20:31.000000000 -0700 +++ linux-2.4.22/arch/arm/mm/small_page.c 2003-08-25 04:44:39.000000000 -0700 @@ -150,8 +150,8 @@ unsigned long flags; struct page *page; - page = virt_to_page(spage); - if (VALID_PAGE(page)) { + if (virt_addr_valid(spage)) { + page = virt_to_page(spage); /* * The container-page must be marked Reserved diff -urN linux-2.4.21/arch/arm/nwfpe/ChangeLog linux-2.4.22/arch/arm/nwfpe/ChangeLog --- linux-2.4.21/arch/arm/nwfpe/ChangeLog 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/ChangeLog 2003-08-25 04:44:39.000000000 -0700 @@ -1,3 +1,11 @@ +2003-03-22 Ralph Siemsen + * Reformat all but softfloat files to get a consistent coding style. + Used "indent -kr -i8 -ts8 -sob -l132 -ss" and a few manual fixups. + * Removed dead code and fixed function protypes to match definitions. + * Consolidated use of (opcode && MASK_ARITHMETIC_OPCODE) >> 20. + * Make 80-bit precision a compile-time option. (1%) + * Only initialize FPE state once in repeat-FP situations. (6%) + 2002-01-19 Russell King * fpa11.h - Add documentation diff -urN linux-2.4.21/arch/arm/nwfpe/Makefile linux-2.4.22/arch/arm/nwfpe/Makefile --- linux-2.4.21/arch/arm/nwfpe/Makefile 2001-04-11 19:02:27.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -18,7 +18,11 @@ nwfpe-objs := fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \ fpmodule.o fpopcode.o softfloat.o \ - single_cpdo.o double_cpdo.o extended_cpdo.o + single_cpdo.o double_cpdo.o + +ifeq ($(CONFIG_FPE_NWFPE_XP),y) +nwfpe-objs += extended_cpdo.o +endif ifeq ($(CONFIG_CPU_26),y) nwfpe-objs += entry26.o diff -urN linux-2.4.21/arch/arm/nwfpe/double_cpdo.c linux-2.4.22/arch/arm/nwfpe/double_cpdo.c --- linux-2.4.21/arch/arm/nwfpe/double_cpdo.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/double_cpdo.c 2003-08-25 04:44:39.000000000 -0700 @@ -23,6 +23,11 @@ #include "softfloat.h" #include "fpopcode.h" +union float64_components { + float64 f64; + unsigned int i[2]; +}; + float64 float64_exp(float64 Fm); float64 float64_ln(float64 Fm); float64 float64_sin(float64 rFm); @@ -32,257 +37,123 @@ float64 float64_log(float64 rFm); float64 float64_tan(float64 rFm); float64 float64_arccos(float64 rFm); -float64 float64_pow(float64 rFn,float64 rFm); -float64 float64_pol(float64 rFn,float64 rFm); +float64 float64_pow(float64 rFn, float64 rFm); +float64 float64_pol(float64 rFn, float64 rFm); -unsigned int DoubleCPDO(const unsigned int opcode) +static float64 float64_rsf(float64 rFn, float64 rFm) { - FPA11 *fpa11 = GET_FPA11(); - float64 rFm, rFn; - unsigned int Fd, Fm, Fn, nRc = 1; - - //printk("DoubleCPDO(0x%08x)\n",opcode); - - Fm = getFm(opcode); - if (CONSTANT_FM(opcode)) - { - rFm = getDoubleConstant(Fm); - } - else - { - switch (fpa11->fType[Fm]) - { - case typeSingle: - rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle); - break; - - case typeDouble: - rFm = fpa11->fpreg[Fm].fDouble; - break; - - case typeExtended: - // !! patb - //printk("not implemented! why not?\n"); - //!! ScottB - // should never get here, if extended involved - // then other operand should be promoted then - // ExtendedCPDO called. - break; - - default: return 0; - } - } - - if (!MONADIC_INSTRUCTION(opcode)) - { - Fn = getFn(opcode); - switch (fpa11->fType[Fn]) - { - case typeSingle: - rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle); - break; - - case typeDouble: - rFn = fpa11->fpreg[Fn].fDouble; - break; - - default: return 0; - } - } - - Fd = getFd(opcode); - /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */ - switch (opcode & MASK_ARITHMETIC_OPCODE) - { - /* dyadic opcodes */ - case ADF_CODE: - fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm); - break; - - case MUF_CODE: - case FML_CODE: - fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm); - break; - - case SUF_CODE: - fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm); - break; - - case RSF_CODE: - fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn); - break; - - case DVF_CODE: - case FDV_CODE: - fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm); - break; - - case RDF_CODE: - case FRD_CODE: - fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn); - break; - -#if 0 - case POW_CODE: - fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm); - break; - - case RPW_CODE: - fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn); - break; -#endif - - case RMF_CODE: - fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm); - break; - -#if 0 - case POL_CODE: - fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm); - break; -#endif - - /* monadic opcodes */ - case MVF_CODE: - fpa11->fpreg[Fd].fDouble = rFm; - break; - - case MNF_CODE: - { - unsigned int *p = (unsigned int*)&rFm; - p[1] ^= 0x80000000; - fpa11->fpreg[Fd].fDouble = rFm; - } - break; - - case ABS_CODE: - { - unsigned int *p = (unsigned int*)&rFm; - p[1] &= 0x7fffffff; - fpa11->fpreg[Fd].fDouble = rFm; - } - break; - - case RND_CODE: - case URD_CODE: - fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm); - break; - - case SQT_CODE: - fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm); - break; - -#if 0 - case LOG_CODE: - fpa11->fpreg[Fd].fDouble = float64_log(rFm); - break; - - case LGN_CODE: - fpa11->fpreg[Fd].fDouble = float64_ln(rFm); - break; - - case EXP_CODE: - fpa11->fpreg[Fd].fDouble = float64_exp(rFm); - break; - - case SIN_CODE: - fpa11->fpreg[Fd].fDouble = float64_sin(rFm); - break; - - case COS_CODE: - fpa11->fpreg[Fd].fDouble = float64_cos(rFm); - break; - - case TAN_CODE: - fpa11->fpreg[Fd].fDouble = float64_tan(rFm); - break; - - case ASN_CODE: - fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm); - break; - - case ACS_CODE: - fpa11->fpreg[Fd].fDouble = float64_arccos(rFm); - break; - - case ATN_CODE: - fpa11->fpreg[Fd].fDouble = float64_arctan(rFm); - break; -#endif - - case NRM_CODE: - break; - - default: - { - nRc = 0; - } - } - - if (0 != nRc) fpa11->fType[Fd] = typeDouble; - return nRc; + return float64_sub(rFm, rFn); } -#if 0 -float64 float64_exp(float64 rFm) +static float64 float64_rdv(float64 rFn, float64 rFm) { - return rFm; -//series + return float64_div(rFm, rFn); } -float64 float64_ln(float64 rFm) -{ - return rFm; -//series -} +static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = { + [ADF_CODE >> 20] = float64_add, + [MUF_CODE >> 20] = float64_mul, + [SUF_CODE >> 20] = float64_sub, + [RSF_CODE >> 20] = float64_rsf, + [DVF_CODE >> 20] = float64_div, + [RDF_CODE >> 20] = float64_rdv, + [RMF_CODE >> 20] = float64_rem, -float64 float64_sin(float64 rFm) -{ - return rFm; -//series -} + /* strictly, these opcodes should not be implemented */ + [FML_CODE >> 20] = float64_mul, + [FDV_CODE >> 20] = float64_div, + [FRD_CODE >> 20] = float64_rdv, +}; -float64 float64_cos(float64 rFm) +static float64 float64_mvf(float64 rFm) { - return rFm; - //series + return rFm; } -#if 0 -float64 float64_arcsin(float64 rFm) +static float64 float64_mnf(float64 rFm) { -//series -} + union float64_components u; -float64 float64_arctan(float64 rFm) -{ - //series -} -#endif + u.f64 = rFm; + u.i[1] ^= 0x80000000; -float64 float64_log(float64 rFm) -{ - return float64_div(float64_ln(rFm),getDoubleConstant(7)); + return u.f64; } -float64 float64_tan(float64 rFm) +static float64 float64_abs(float64 rFm) { - return float64_div(float64_sin(rFm),float64_cos(rFm)); -} + union float64_components u; -float64 float64_arccos(float64 rFm) -{ -return rFm; - //return float64_sub(halfPi,float64_arcsin(rFm)); -} + u.f64 = rFm; + u.i[1] &= 0x7fffffff; -float64 float64_pow(float64 rFn,float64 rFm) -{ - return float64_exp(float64_mul(rFm,float64_ln(rFn))); + return u.f64; } -float64 float64_pol(float64 rFn,float64 rFm) +static float64 (*const monadic_double[16])(float64 rFm) = { + [MVF_CODE >> 20] = float64_mvf, + [MNF_CODE >> 20] = float64_mnf, + [ABS_CODE >> 20] = float64_abs, + [RND_CODE >> 20] = float64_round_to_int, + [URD_CODE >> 20] = float64_round_to_int, + [SQT_CODE >> 20] = float64_sqrt, + [NRM_CODE >> 20] = float64_mvf, +}; + +unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd) { - return float64_arctan(float64_div(rFn,rFm)); + FPA11 *fpa11 = GET_FPA11(); + float64 rFm; + unsigned int Fm, opc_mask_shift; + + Fm = getFm(opcode); + if (CONSTANT_FM(opcode)) { + rFm = getDoubleConstant(Fm); + } else { + switch (fpa11->fType[Fm]) { + case typeSingle: + rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle); + break; + + case typeDouble: + rFm = fpa11->fpreg[Fm].fDouble; + break; + + default: + return 0; + } + } + + opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; + if (!MONADIC_INSTRUCTION(opcode)) { + unsigned int Fn = getFn(opcode); + float64 rFn; + + switch (fpa11->fType[Fn]) { + case typeSingle: + rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + rFn = fpa11->fpreg[Fn].fDouble; + break; + + default: + return 0; + } + + if (dyadic_double[opc_mask_shift]) { + rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm); + } else { + return 0; + } + } else { + if (monadic_double[opc_mask_shift]) { + rFd->fDouble = monadic_double[opc_mask_shift](rFm); + } else { + return 0; + } + } + + return 1; } -#endif diff -urN linux-2.4.21/arch/arm/nwfpe/entry.S linux-2.4.22/arch/arm/nwfpe/entry.S --- linux-2.4.21/arch/arm/nwfpe/entry.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/entry.S 2003-08-25 04:44:39.000000000 -0700 @@ -70,39 +70,42 @@ .globl nwfpe_enter nwfpe_enter: - mov r4, lr @ save the failure-return addresses - mov sl, sp @ we access the registers via 'sl' - - ldr r5, [sp, #60] @ get contents of PC; - sub r8, r5, #4 -.Lx2: ldrt r0, [r8] @ get actual instruction into r0 + mov r4, lr @ save the failure-return addresses + ldr ip, [r10, #112] @ get init_flag + mov sl, sp @ we access the registers via 'sl' + + ldr r5, [sp, #60] @ get contents of PC; + cmp ip, #0 + bleq nwfpe_init_fpa + sub r8, r5, #4 +.Lx1: ldrt r0, [r8] @ get actual instruction into r0 emulate: - bl EmulateAll @ emulate the instruction - cmp r0, #0 @ was emulation successful - moveq pc, r4 @ no, return failure + bl EmulateAll @ emulate the instruction + cmp r0, #0 @ was emulation successful + moveq pc, r4 @ no, return failure next: -.Lx1: ldrt r6, [r5], #4 @ get the next instruction and +.Lx2: ldrt r6, [r5], #4 @ get the next instruction and @ increment PC - and r2, r6, #0x0F000000 @ test for FP insns - teq r2, #0x0C000000 - teqne r2, #0x0D000000 - teqne r2, #0x0E000000 - movne pc, r9 @ return ok if not a fp insn - - str r5, [sp, #60] @ update PC copy in regs - - mov r0, r6 @ save a copy - ldr r1, [sp, #64] @ fetch the condition codes - bl checkCondition @ check the condition - cmp r0, #0 @ r0 = 0 ==> condition failed - - @ if condition code failed to match, next insn - beq next @ get the next instruction; - - mov r0, r6 @ prepare for EmulateAll() - b emulate @ if r0 != 0, goto EmulateAll + and r2, r6, #0x0F000000 @ test for FP insns + teq r2, #0x0C000000 + teqne r2, #0x0D000000 + teqne r2, #0x0E000000 + movne pc, r9 @ return ok if not a fp insn + + str r5, [sp, #60] @ update PC copy in regs + + mov r0, r6 @ save a copy + ldr r1, [sp, #64] @ fetch the condition codes + bl checkCondition @ check the condition + cmp r0, #0 @ r0 = 0 ==> condition failed + + @ if condition code failed to match, next insn + beq next @ get the next instruction; + + mov r0, r6 @ prepare for EmulateAll() + b emulate @ if r0 != 0, goto EmulateAll @ We need to be prepared for the instructions at .Lx1 and .Lx2 @ to fault. Emit the appropriate exception gunk to fix things up. diff -urN linux-2.4.21/arch/arm/nwfpe/entry26.S linux-2.4.22/arch/arm/nwfpe/entry26.S --- linux-2.4.21/arch/arm/nwfpe/entry26.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/entry26.S 2003-08-25 04:44:39.000000000 -0700 @@ -95,7 +95,7 @@ @ if condition code failed to match, next insn beq next @ get the next instruction; - + mov r0, r6 @ prepare for EmulateAll() adr lr, 1b orr lr, lr, #3 diff -urN linux-2.4.21/arch/arm/nwfpe/extended_cpdo.c linux-2.4.22/arch/arm/nwfpe/extended_cpdo.c --- linux-2.4.21/arch/arm/nwfpe/extended_cpdo.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/extended_cpdo.c 2003-08-25 04:44:39.000000000 -0700 @@ -32,242 +32,123 @@ floatx80 floatx80_log(floatx80 rFm); floatx80 floatx80_tan(floatx80 rFm); floatx80 floatx80_arccos(floatx80 rFm); -floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm); -floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm); +floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm); +floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm); -unsigned int ExtendedCPDO(const unsigned int opcode) +static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm) { - FPA11 *fpa11 = GET_FPA11(); - floatx80 rFm, rFn; - unsigned int Fd, Fm, Fn, nRc = 1; - - //printk("ExtendedCPDO(0x%08x)\n",opcode); - - Fm = getFm(opcode); - if (CONSTANT_FM(opcode)) - { - rFm = getExtendedConstant(Fm); - } - else - { - switch (fpa11->fType[Fm]) - { - case typeSingle: - rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); - break; - - case typeDouble: - rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); - break; - - case typeExtended: - rFm = fpa11->fpreg[Fm].fExtended; - break; - - default: return 0; - } - } - - if (!MONADIC_INSTRUCTION(opcode)) - { - Fn = getFn(opcode); - switch (fpa11->fType[Fn]) - { - case typeSingle: - rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); - break; - - case typeDouble: - rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); - break; - - case typeExtended: - rFn = fpa11->fpreg[Fn].fExtended; - break; - - default: return 0; - } - } - - Fd = getFd(opcode); - switch (opcode & MASK_ARITHMETIC_OPCODE) - { - /* dyadic opcodes */ - case ADF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm); - break; - - case MUF_CODE: - case FML_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm); - break; - - case SUF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm); - break; - - case RSF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn); - break; - - case DVF_CODE: - case FDV_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm); - break; - - case RDF_CODE: - case FRD_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn); - break; - -#if 0 - case POW_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm); - break; - - case RPW_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn); - break; -#endif - - case RMF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm); - break; - -#if 0 - case POL_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm); - break; -#endif - - /* monadic opcodes */ - case MVF_CODE: - fpa11->fpreg[Fd].fExtended = rFm; - break; - - case MNF_CODE: - rFm.high ^= 0x8000; - fpa11->fpreg[Fd].fExtended = rFm; - break; - - case ABS_CODE: - rFm.high &= 0x7fff; - fpa11->fpreg[Fd].fExtended = rFm; - break; - - case RND_CODE: - case URD_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm); - break; - - case SQT_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm); - break; - -#if 0 - case LOG_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_log(rFm); - break; - - case LGN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm); - break; - - case EXP_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm); - break; - - case SIN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm); - break; - - case COS_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm); - break; - - case TAN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm); - break; - - case ASN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm); - break; - - case ACS_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm); - break; - - case ATN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm); - break; -#endif - - case NRM_CODE: - break; - - default: - { - nRc = 0; - } - } - - if (0 != nRc) fpa11->fType[Fd] = typeExtended; - return nRc; + return floatx80_sub(rFm, rFn); } -#if 0 -floatx80 floatx80_exp(floatx80 Fm) +static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm) { -//series + return floatx80_div(rFm, rFn); } -floatx80 floatx80_ln(floatx80 Fm) -{ -//series -} +static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = { + [ADF_CODE >> 20] = floatx80_add, + [MUF_CODE >> 20] = floatx80_mul, + [SUF_CODE >> 20] = floatx80_sub, + [RSF_CODE >> 20] = floatx80_rsf, + [DVF_CODE >> 20] = floatx80_div, + [RDF_CODE >> 20] = floatx80_rdv, + [RMF_CODE >> 20] = floatx80_rem, -floatx80 floatx80_sin(floatx80 rFm) -{ -//series -} + /* strictly, these opcodes should not be implemented */ + [FML_CODE >> 20] = floatx80_mul, + [FDV_CODE >> 20] = floatx80_div, + [FRD_CODE >> 20] = floatx80_rdv, +}; -floatx80 floatx80_cos(floatx80 rFm) +static floatx80 floatx80_mvf(floatx80 rFm) { -//series + return rFm; } -floatx80 floatx80_arcsin(floatx80 rFm) +static floatx80 floatx80_mnf(floatx80 rFm) { -//series + rFm.high ^= 0x8000; + return rFm; } -floatx80 floatx80_arctan(floatx80 rFm) +static floatx80 floatx80_abs(floatx80 rFm) { - //series + rFm.high &= 0x7fff; + return rFm; } -floatx80 floatx80_log(floatx80 rFm) -{ - return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7)); -} +static floatx80 (*const monadic_extended[16])(floatx80 rFm) = { + [MVF_CODE >> 20] = floatx80_mvf, + [MNF_CODE >> 20] = floatx80_mnf, + [ABS_CODE >> 20] = floatx80_abs, + [RND_CODE >> 20] = floatx80_round_to_int, + [URD_CODE >> 20] = floatx80_round_to_int, + [SQT_CODE >> 20] = floatx80_sqrt, + [NRM_CODE >> 20] = floatx80_mvf, +}; -floatx80 floatx80_tan(floatx80 rFm) +unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd) { - return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm)); -} + FPA11 *fpa11 = GET_FPA11(); + floatx80 rFm; + unsigned int Fm, opc_mask_shift; -floatx80 floatx80_arccos(floatx80 rFm) -{ - //return floatx80_sub(halfPi,floatx80_arcsin(rFm)); -} + Fm = getFm(opcode); + if (CONSTANT_FM(opcode)) { + rFm = getExtendedConstant(Fm); + } else { + switch (fpa11->fType[Fm]) { + case typeSingle: + rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); + break; -floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm) -{ - return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn))); -} + case typeDouble: + rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); + break; -floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm) -{ - return floatx80_arctan(floatx80_div(rFn,rFm)); + case typeExtended: + rFm = fpa11->fpreg[Fm].fExtended; + break; + + default: + return 0; + } + } + + opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; + if (!MONADIC_INSTRUCTION(opcode)) { + unsigned int Fn = getFn(opcode); + floatx80 rFn; + + switch (fpa11->fType[Fn]) { + case typeSingle: + rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); + break; + + case typeExtended: + rFn = fpa11->fpreg[Fn].fExtended; + break; + + default: + return 0; + } + + if (dyadic_extended[opc_mask_shift]) { + rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm); + } else { + return 0; + } + } else { + if (monadic_extended[opc_mask_shift]) { + rFd->fExtended = monadic_extended[opc_mask_shift](rFm); + } else { + return 0; + } + } + + return 1; } -#endif diff -urN linux-2.4.21/arch/arm/nwfpe/fpa11.c linux-2.4.22/arch/arm/nwfpe/fpa11.c --- linux-2.4.21/arch/arm/nwfpe/fpa11.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpa11.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,7 @@ /* NetWinder Floating Point Emulator (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 Direct questions, comments to Scott Bambrough @@ -20,7 +21,6 @@ */ #include "fpa11.h" - #include "fpopcode.h" #include "fpmodule.h" @@ -36,180 +36,96 @@ /* Reset the FPA11 chip. Called to initialize and reset the emulator. */ void resetFPA11(void) { - int i; - FPA11 *fpa11 = GET_FPA11(); - - /* initialize the register type array */ - for (i=0;i<=7;i++) - { - fpa11->fType[i] = typeNone; - } - - /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */ - fpa11->fpsr = FP_EMULATOR | BIT_AC; - - /* FPCR: set SB, AB and DA bits, clear all others */ -#if MAINTAIN_FPCR - fpa11->fpcr = MASK_RESET; -#endif + int i; + FPA11 *fpa11 = GET_FPA11(); + + /* initialize the register type array */ + for (i = 0; i <= 7; i++) { + fpa11->fType[i] = typeNone; + } + + /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */ + fpa11->fpsr = FP_EMULATOR | BIT_AC; } void SetRoundingMode(const unsigned int opcode) { -#if MAINTAIN_FPCR - FPA11 *fpa11 = GET_FPA11(); - fpa11->fpcr &= ~MASK_ROUNDING_MODE; -#endif - switch (opcode & MASK_ROUNDING_MODE) - { - default: - case ROUND_TO_NEAREST: - float_rounding_mode = float_round_nearest_even; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_NEAREST; -#endif - break; - - case ROUND_TO_PLUS_INFINITY: - float_rounding_mode = float_round_up; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_PLUS_INFINITY; -#endif - break; - - case ROUND_TO_MINUS_INFINITY: - float_rounding_mode = float_round_down; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_MINUS_INFINITY; -#endif - break; - - case ROUND_TO_ZERO: - float_rounding_mode = float_round_to_zero; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_ZERO; -#endif - break; - } + switch (opcode & MASK_ROUNDING_MODE) { + default: + case ROUND_TO_NEAREST: + float_rounding_mode = float_round_nearest_even; + break; + + case ROUND_TO_PLUS_INFINITY: + float_rounding_mode = float_round_up; + break; + + case ROUND_TO_MINUS_INFINITY: + float_rounding_mode = float_round_down; + break; + + case ROUND_TO_ZERO: + float_rounding_mode = float_round_to_zero; + break; + } } void SetRoundingPrecision(const unsigned int opcode) { -#if MAINTAIN_FPCR - FPA11 *fpa11 = GET_FPA11(); - fpa11->fpcr &= ~MASK_ROUNDING_PRECISION; -#endif - switch (opcode & MASK_ROUNDING_PRECISION) - { - case ROUND_SINGLE: - floatx80_rounding_precision = 32; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_SINGLE; -#endif - break; - - case ROUND_DOUBLE: - floatx80_rounding_precision = 64; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_DOUBLE; -#endif - break; - - case ROUND_EXTENDED: - floatx80_rounding_precision = 80; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_EXTENDED; -#endif - break; - - default: floatx80_rounding_precision = 80; - } +#ifdef CONFIG_FPE_NWFPE_XP + switch (opcode & MASK_ROUNDING_PRECISION) { + case ROUND_SINGLE: + floatx80_rounding_precision = 32; + break; + + case ROUND_DOUBLE: + floatx80_rounding_precision = 64; + break; + + case ROUND_EXTENDED: + floatx80_rounding_precision = 80; + break; + + default: + floatx80_rounding_precision = 80; + } +#endif } -/* Emulate the instruction in the opcode. */ -unsigned int EmulateAll(unsigned int opcode) +void nwfpe_init_fpa(void) { - unsigned int nRc = 0; - unsigned long flags; - FPA11 *fpa11; - save_flags(flags); sti(); - - fpa11 = GET_FPA11(); - - if (fpa11->initflag == 0) /* good place for __builtin_expect */ - { - resetFPA11(); - SetRoundingMode(ROUND_TO_NEAREST); - SetRoundingPrecision(ROUND_EXTENDED); - fpa11->initflag = 1; - } - - if (TEST_OPCODE(opcode,MASK_CPRT)) - { - /* Emulate conversion opcodes. */ - /* Emulate register transfer opcodes. */ - /* Emulate comparison opcodes. */ - nRc = EmulateCPRT(opcode); - } - else if (TEST_OPCODE(opcode,MASK_CPDO)) - { - /* Emulate monadic arithmetic opcodes. */ - /* Emulate dyadic arithmetic opcodes. */ - nRc = EmulateCPDO(opcode); - } - else if (TEST_OPCODE(opcode,MASK_CPDT)) - { - /* Emulate load/store opcodes. */ - /* Emulate load/store multiple opcodes. */ - nRc = EmulateCPDT(opcode); - } - else - { - /* Invalid instruction detected. Return FALSE. */ - nRc = 0; - } - - restore_flags(flags); - - return(nRc); + FPA11 *fpa11 = GET_FPA11(); +#ifdef NWFPE_DEBUG + printk("NWFPE: setting up state.\n"); +#endif + resetFPA11(); + SetRoundingMode(ROUND_TO_NEAREST); + SetRoundingPrecision(ROUND_EXTENDED); + fpa11->initflag = 1; } -#if 0 -unsigned int EmulateAll1(unsigned int opcode) +/* Emulate the instruction in the opcode. */ +unsigned int EmulateAll(const unsigned int opcode) { - switch ((opcode >> 24) & 0xf) - { - case 0xc: - case 0xd: - if ((opcode >> 20) & 0x1) - { - switch ((opcode >> 8) & 0xf) - { - case 0x1: return PerformLDF(opcode); break; - case 0x2: return PerformLFM(opcode); break; - default: return 0; - } - } - else - { - switch ((opcode >> 8) & 0xf) - { - case 0x1: return PerformSTF(opcode); break; - case 0x2: return PerformSFM(opcode); break; - default: return 0; - } - } - break; - - case 0xe: - if (opcode & 0x10) - return EmulateCPDO(opcode); - else - return EmulateCPRT(opcode); - break; - - default: return 0; - } -} +#ifdef NWFPE_DEBUG + printk("NWFPE: emulating opcode %08x\n", opcode); #endif + if (TEST_OPCODE(opcode, MASK_CPRT)) { + /* Emulate conversion opcodes. */ + /* Emulate register transfer opcodes. */ + /* Emulate comparison opcodes. */ + return EmulateCPRT(opcode); + } else if (TEST_OPCODE(opcode, MASK_CPDO)) { + /* Emulate monadic arithmetic opcodes. */ + /* Emulate dyadic arithmetic opcodes. */ + return EmulateCPDO(opcode); + } else if (TEST_OPCODE(opcode, MASK_CPDT)) { + /* Emulate load/store opcodes. */ + /* Emulate load/store multiple opcodes. */ + return EmulateCPDT(opcode); + } + + /* Invalid instruction detected. Return FALSE. */ + return 0; +} diff -urN linux-2.4.21/arch/arm/nwfpe/fpa11.h linux-2.4.22/arch/arm/nwfpe/fpa11.h --- linux-2.4.21/arch/arm/nwfpe/fpa11.h 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpa11.h 2003-08-25 04:44:39.000000000 -0700 @@ -38,6 +38,7 @@ /* includes */ #include "fpsr.h" /* FP control and status register definitions */ +#include "milieu.h" #include "softfloat.h" #define typeNone 0x00 @@ -49,9 +50,13 @@ * This must be no more and no less than 12 bytes. */ typedef union tagFPREG { - floatx80 fExtended; - float64 fDouble; - float32 fSingle; + float32 fSingle; + float64 fDouble; +#ifdef CONFIG_FPE_NWFPE_XP + floatx80 fExtended; +#else + int padding[3]; +#endif } FPREG; /* @@ -68,17 +73,17 @@ * not initialise. */ typedef struct tagFPA11 { -/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ -/* 96 */ FPSR fpsr; /* floating point status register */ -/* 100 */ FPCR fpcr; /* floating point control register */ -/* 104 */ unsigned char fType[8]; /* type of floating point value held in - floating point registers. One of none - single, double or extended. */ -/* 112 */ int initflag; /* this is special. The kernel guarantees - to set it to 0 when a thread is launched, - so we can use it to detect whether this - instance of the emulator needs to be - initialised. */ +/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ +/* 96 */ FPSR fpsr; /* floating point status register */ +/* 100 */ FPCR fpcr; /* floating point control register */ +/* 104 */ unsigned char fType[8]; /* type of floating point value held in + floating point registers. One of + none, single, double or extended. */ +/* 112 */ int initflag; /* this is special. The kernel guarantees + to set it to 0 when a thread is launched, + so we can use it to detect whether this + instance of the emulator needs to be + initialised. */ } FPA11; extern void resetFPA11(void); diff -urN linux-2.4.21/arch/arm/nwfpe/fpa11.inl linux-2.4.22/arch/arm/nwfpe/fpa11.inl --- linux-2.4.21/arch/arm/nwfpe/fpa11.inl 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpa11.inl 2003-08-25 04:44:39.000000000 -0700 @@ -24,28 +24,28 @@ /* Read and write floating point status register */ extern __inline__ unsigned int readFPSR(void) { - FPA11 *fpa11 = GET_FPA11(); - return(fpa11->fpsr); + FPA11 *fpa11 = GET_FPA11(); + return (fpa11->fpsr); } extern __inline__ void writeFPSR(FPSR reg) { - FPA11 *fpa11 = GET_FPA11(); - /* the sysid byte in the status register is readonly */ - fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID); + FPA11 *fpa11 = GET_FPA11(); + /* the sysid byte in the status register is readonly */ + fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID); } /* Read and write floating point control register */ extern __inline__ FPCR readFPCR(void) { - FPA11 *fpa11 = GET_FPA11(); - /* clear SB, AB and DA bits before returning FPCR */ - return(fpa11->fpcr & ~MASK_RFC); + FPA11 *fpa11 = GET_FPA11(); + /* clear SB, AB and DA bits before returning FPCR */ + return (fpa11->fpcr & ~MASK_RFC); } extern __inline__ void writeFPCR(FPCR reg) { - FPA11 *fpa11 = GET_FPA11(); - fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ - fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */ + FPA11 *fpa11 = GET_FPA11(); + fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ + fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */ } diff -urN linux-2.4.21/arch/arm/nwfpe/fpa11_cpdo.c linux-2.4.22/arch/arm/nwfpe/fpa11_cpdo.c --- linux-2.4.21/arch/arm/nwfpe/fpa11_cpdo.c 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpa11_cpdo.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,7 @@ /* NetWinder Floating Point Emulator (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 Direct questions, comments to Scott Bambrough @@ -22,96 +23,109 @@ #include "fpa11.h" #include "fpopcode.h" -unsigned int SingleCPDO(const unsigned int opcode); -unsigned int DoubleCPDO(const unsigned int opcode); -unsigned int ExtendedCPDO(const unsigned int opcode); +unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd); +unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd); +unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd); unsigned int EmulateCPDO(const unsigned int opcode) { - FPA11 *fpa11 = GET_FPA11(); - unsigned int Fd, nType, nDest, nRc = 1; - - //printk("EmulateCPDO(0x%08x)\n",opcode); - - /* Get the destination size. If not valid let Linux perform - an invalid instruction trap. */ - nDest = getDestinationSize(opcode); - if (typeNone == nDest) return 0; - - SetRoundingMode(opcode); - - /* Compare the size of the operands in Fn and Fm. - Choose the largest size and perform operations in that size, - in order to make use of all the precision of the operands. - If Fm is a constant, we just grab a constant of a size - matching the size of the operand in Fn. */ - if (MONADIC_INSTRUCTION(opcode)) - nType = nDest; - else - nType = fpa11->fType[getFn(opcode)]; - - if (!CONSTANT_FM(opcode)) - { - register unsigned int Fm = getFm(opcode); - if (nType < fpa11->fType[Fm]) - { - nType = fpa11->fType[Fm]; - } - } - - switch (nType) - { - case typeSingle : nRc = SingleCPDO(opcode); break; - case typeDouble : nRc = DoubleCPDO(opcode); break; - case typeExtended : nRc = ExtendedCPDO(opcode); break; - default : nRc = 0; - } - - /* If the operation succeeded, check to see if the result in the - destination register is the correct size. If not force it - to be. */ - Fd = getFd(opcode); - nType = fpa11->fType[Fd]; - if ((0 != nRc) && (nDest != nType)) - { - switch (nDest) - { - case typeSingle: - { - if (typeDouble == nType) - fpa11->fpreg[Fd].fSingle = - float64_to_float32(fpa11->fpreg[Fd].fDouble); - else - fpa11->fpreg[Fd].fSingle = - floatx80_to_float32(fpa11->fpreg[Fd].fExtended); - } - break; - - case typeDouble: - { - if (typeSingle == nType) - fpa11->fpreg[Fd].fDouble = - float32_to_float64(fpa11->fpreg[Fd].fSingle); - else - fpa11->fpreg[Fd].fDouble = - floatx80_to_float64(fpa11->fpreg[Fd].fExtended); - } - break; - - case typeExtended: - { - if (typeSingle == nType) - fpa11->fpreg[Fd].fExtended = - float32_to_floatx80(fpa11->fpreg[Fd].fSingle); - else - fpa11->fpreg[Fd].fExtended = - float64_to_floatx80(fpa11->fpreg[Fd].fDouble); - } - break; - } - - fpa11->fType[Fd] = nDest; - } - - return nRc; + FPA11 *fpa11 = GET_FPA11(); + FPREG *rFd; + unsigned int nType, nDest, nRc; + + /* Get the destination size. If not valid let Linux perform + an invalid instruction trap. */ + nDest = getDestinationSize(opcode); + if (typeNone == nDest) + return 0; + + SetRoundingMode(opcode); + + /* Compare the size of the operands in Fn and Fm. + Choose the largest size and perform operations in that size, + in order to make use of all the precision of the operands. + If Fm is a constant, we just grab a constant of a size + matching the size of the operand in Fn. */ + if (MONADIC_INSTRUCTION(opcode)) + nType = nDest; + else + nType = fpa11->fType[getFn(opcode)]; + + if (!CONSTANT_FM(opcode)) { + register unsigned int Fm = getFm(opcode); + if (nType < fpa11->fType[Fm]) { + nType = fpa11->fType[Fm]; + } + } + + rFd = &fpa11->fpreg[getFd(opcode)]; + + switch (nType) { + case typeSingle: + nRc = SingleCPDO(opcode, rFd); + break; + case typeDouble: + nRc = DoubleCPDO(opcode, rFd); + break; +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + nRc = ExtendedCPDO(opcode, rFd); + break; +#endif + default: + nRc = 0; + } + + /* The CPDO functions used to always set the destination type + to be the same as their working size. */ + + if (nRc != 0) { + /* If the operation succeeded, check to see if the result in the + destination register is the correct size. If not force it + to be. */ + + fpa11->fType[getFd(opcode)] = nDest; + +#ifdef CONFIG_FPE_NWFPE_XP + if (nDest != nType) { + switch (nDest) { + case typeSingle: + { + if (typeDouble == nType) + rFd->fSingle = float64_to_float32(rFd->fDouble); + else + rFd->fSingle = floatx80_to_float32(rFd->fExtended); + } + break; + + case typeDouble: + { + if (typeSingle == nType) + rFd->fDouble = float32_to_float64(rFd->fSingle); + else + rFd->fDouble = floatx80_to_float64(rFd->fExtended); + } + break; + + case typeExtended: + { + if (typeSingle == nType) + rFd->fExtended = float32_to_floatx80(rFd->fSingle); + else + rFd->fExtended = float64_to_floatx80(rFd->fDouble); + } + break; + } + } +#else + if (nDest != nType) { + if (nDest == typeSingle) + rFd->fSingle = float64_to_float32(rFd->fDouble); + else + rFd->fDouble = float32_to_float64(rFd->fSingle); + } +#endif + } + + return nRc; } diff -urN linux-2.4.21/arch/arm/nwfpe/fpa11_cpdt.c linux-2.4.22/arch/arm/nwfpe/fpa11_cpdt.c --- linux-2.4.21/arch/arm/nwfpe/fpa11_cpdt.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpa11_cpdt.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* NetWinder Floating Point Emulator (c) Rebel.com, 1998-1999 - (c) Philip Blundell, 1998 + (c) Philip Blundell, 1998, 2001 Direct questions, comments to Scott Bambrough @@ -28,331 +28,347 @@ #include -static inline -void loadSingle(const unsigned int Fn,const unsigned int *pMem) +static inline void loadSingle(const unsigned int Fn, const unsigned int *pMem) { - FPA11 *fpa11 = GET_FPA11(); - fpa11->fType[Fn] = typeSingle; - get_user(fpa11->fpreg[Fn].fSingle, pMem); -} - -static inline -void loadDouble(const unsigned int Fn,const unsigned int *pMem) -{ - FPA11 *fpa11 = GET_FPA11(); - unsigned int *p; - p = (unsigned int*)&fpa11->fpreg[Fn].fDouble; - fpa11->fType[Fn] = typeDouble; - get_user(p[0], &pMem[1]); - get_user(p[1], &pMem[0]); /* sign & exponent */ -} - -static inline -void loadExtended(const unsigned int Fn,const unsigned int *pMem) -{ - FPA11 *fpa11 = GET_FPA11(); - unsigned int *p; - p = (unsigned int*)&fpa11->fpreg[Fn].fExtended; - fpa11->fType[Fn] = typeExtended; - get_user(p[0], &pMem[0]); /* sign & exponent */ - get_user(p[1], &pMem[2]); /* ls bits */ - get_user(p[2], &pMem[1]); /* ms bits */ -} - -static inline -void loadMultiple(const unsigned int Fn,const unsigned int *pMem) -{ - FPA11 *fpa11 = GET_FPA11(); - register unsigned int *p; - unsigned long x; - - p = (unsigned int*)&(fpa11->fpreg[Fn]); - get_user(x, &pMem[0]); - fpa11->fType[Fn] = (x >> 14) & 0x00000003; - - switch (fpa11->fType[Fn]) - { - case typeSingle: - case typeDouble: - { - get_user(p[0], &pMem[2]); /* Single */ - get_user(p[1], &pMem[1]); /* double msw */ - p[2] = 0; /* empty */ - } - break; - - case typeExtended: - { - get_user(p[1], &pMem[2]); - get_user(p[2], &pMem[1]); /* msw */ - p[0] = (x & 0x80003fff); - } - break; - } -} - -static inline -void storeSingle(const unsigned int Fn,unsigned int *pMem) -{ - FPA11 *fpa11 = GET_FPA11(); - float32 val; - register unsigned int *p = (unsigned int*)&val; - - switch (fpa11->fType[Fn]) - { - case typeDouble: - val = float64_to_float32(fpa11->fpreg[Fn].fDouble); - break; - - case typeExtended: - val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended); - break; - - default: val = fpa11->fpreg[Fn].fSingle; - } - - put_user(p[0], pMem); -} - -static inline -void storeDouble(const unsigned int Fn,unsigned int *pMem) -{ - FPA11 *fpa11 = GET_FPA11(); - float64 val; - register unsigned int *p = (unsigned int*)&val; - - switch (fpa11->fType[Fn]) - { - case typeSingle: - val = float32_to_float64(fpa11->fpreg[Fn].fSingle); - break; - - case typeExtended: - val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended); - break; - - default: val = fpa11->fpreg[Fn].fDouble; - } - put_user(p[1], &pMem[0]); /* msw */ - put_user(p[0], &pMem[1]); /* lsw */ -} - -static inline -void storeExtended(const unsigned int Fn,unsigned int *pMem) -{ - FPA11 *fpa11 = GET_FPA11(); - floatx80 val; - register unsigned int *p = (unsigned int*)&val; - - switch (fpa11->fType[Fn]) - { - case typeSingle: - val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); - break; - - case typeDouble: - val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); - break; - - default: val = fpa11->fpreg[Fn].fExtended; - } - - put_user(p[0], &pMem[0]); /* sign & exp */ - put_user(p[1], &pMem[2]); - put_user(p[2], &pMem[1]); /* msw */ -} - -static inline -void storeMultiple(const unsigned int Fn,unsigned int *pMem) -{ - FPA11 *fpa11 = GET_FPA11(); - register unsigned int nType, *p; - - p = (unsigned int*)&(fpa11->fpreg[Fn]); - nType = fpa11->fType[Fn]; - - switch (nType) - { - case typeSingle: - case typeDouble: - { - put_user(p[0], &pMem[2]); /* single */ - put_user(p[1], &pMem[1]); /* double msw */ - put_user(nType << 14, &pMem[0]); - } - break; - - case typeExtended: - { - put_user(p[2], &pMem[1]); /* msw */ - put_user(p[1], &pMem[2]); - put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]); - } - break; - } + FPA11 *fpa11 = GET_FPA11(); + fpa11->fType[Fn] = typeSingle; + get_user(fpa11->fpreg[Fn].fSingle, pMem); } -unsigned int PerformLDF(const unsigned int opcode) +static inline void loadDouble(const unsigned int Fn, const unsigned int *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + unsigned int *p; + p = (unsigned int *) &fpa11->fpreg[Fn].fDouble; + fpa11->fType[Fn] = typeDouble; + get_user(p[0], &pMem[1]); + get_user(p[1], &pMem[0]); /* sign & exponent */ +} + +#ifdef CONFIG_FPE_NWFPE_XP +static inline void loadExtended(const unsigned int Fn, const unsigned int *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + unsigned int *p; + p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; + fpa11->fType[Fn] = typeExtended; + get_user(p[0], &pMem[0]); /* sign & exponent */ + get_user(p[1], &pMem[2]); /* ls bits */ + get_user(p[2], &pMem[1]); /* ms bits */ +} +#endif + +static inline void loadMultiple(const unsigned int Fn, const unsigned int *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + register unsigned int *p; + unsigned long x; + + p = (unsigned int *) &(fpa11->fpreg[Fn]); + get_user(x, &pMem[0]); + fpa11->fType[Fn] = (x >> 14) & 0x00000003; + + switch (fpa11->fType[Fn]) { + case typeSingle: + case typeDouble: + { + get_user(p[0], &pMem[2]); /* Single */ + get_user(p[1], &pMem[1]); /* double msw */ + p[2] = 0; /* empty */ + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + { + get_user(p[1], &pMem[2]); + get_user(p[2], &pMem[1]); /* msw */ + p[0] = (x & 0x80003fff); + } + break; +#endif + } +} + +static inline void storeSingle(const unsigned int Fn, unsigned int *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + float32 val; + register unsigned int *p = (unsigned int *) &val; + + switch (fpa11->fType[Fn]) { + case typeDouble: + val = float64_to_float32(fpa11->fpreg[Fn].fDouble); + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended); + break; +#endif + + default: + val = fpa11->fpreg[Fn].fSingle; + } + + put_user(p[0], pMem); +} + +static inline void storeDouble(const unsigned int Fn, unsigned int *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + float64 val; + register unsigned int *p = (unsigned int *) &val; + + switch (fpa11->fType[Fn]) { + case typeSingle: + val = float32_to_float64(fpa11->fpreg[Fn].fSingle); + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended); + break; +#endif + + default: + val = fpa11->fpreg[Fn].fDouble; + } + put_user(p[1], &pMem[0]); /* msw */ + put_user(p[0], &pMem[1]); /* lsw */ +} + +#ifdef CONFIG_FPE_NWFPE_XP +static inline void storeExtended(const unsigned int Fn, unsigned int *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + floatx80 val; + register unsigned int *p = (unsigned int *) &val; + + switch (fpa11->fType[Fn]) { + case typeSingle: + val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); + break; + + default: + val = fpa11->fpreg[Fn].fExtended; + } + + put_user(p[0], &pMem[0]); /* sign & exp */ + put_user(p[1], &pMem[2]); + put_user(p[2], &pMem[1]); /* msw */ +} +#endif + +static inline void storeMultiple(const unsigned int Fn, unsigned int *pMem) { - unsigned int *pBase, *pAddress, *pFinal, nRc = 1, - write_back = WRITE_BACK(opcode); + FPA11 *fpa11 = GET_FPA11(); + register unsigned int nType, *p; + + p = (unsigned int *) &(fpa11->fpreg[Fn]); + nType = fpa11->fType[Fn]; + + switch (nType) { + case typeSingle: + case typeDouble: + { + put_user(p[0], &pMem[2]); /* single */ + put_user(p[1], &pMem[1]); /* double msw */ + put_user(nType << 14, &pMem[0]); + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + { + put_user(p[2], &pMem[1]); /* msw */ + put_user(p[1], &pMem[2]); + put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]); + } + break; +#endif + } +} - //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); +unsigned int PerformLDF(const unsigned int opcode) +{ + unsigned int *pBase, *pAddress, *pFinal, nRc = 1, + write_back = WRITE_BACK(opcode); - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - switch (opcode & MASK_TRANSFER_LENGTH) - { - case TRANSFER_SINGLE : loadSingle(getFd(opcode),pAddress); break; - case TRANSFER_DOUBLE : loadDouble(getFd(opcode),pAddress); break; - case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break; - default: nRc = 0; - } - - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return nRc; + pBase = (unsigned int *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + switch (opcode & MASK_TRANSFER_LENGTH) { + case TRANSFER_SINGLE: + loadSingle(getFd(opcode), pAddress); + break; + case TRANSFER_DOUBLE: + loadDouble(getFd(opcode), pAddress); + break; +#ifdef CONFIG_FPE_NWFPE_XP + case TRANSFER_EXTENDED: + loadExtended(getFd(opcode), pAddress); + break; +#endif + default: + nRc = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned int) pFinal); + return nRc; } unsigned int PerformSTF(const unsigned int opcode) { - unsigned int *pBase, *pAddress, *pFinal, nRc = 1, - write_back = WRITE_BACK(opcode); - - //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); - SetRoundingMode(ROUND_TO_NEAREST); - - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - switch (opcode & MASK_TRANSFER_LENGTH) - { - case TRANSFER_SINGLE : storeSingle(getFd(opcode),pAddress); break; - case TRANSFER_DOUBLE : storeDouble(getFd(opcode),pAddress); break; - case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break; - default: nRc = 0; - } - - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return nRc; + unsigned int *pBase, *pAddress, *pFinal, nRc = 1, + write_back = WRITE_BACK(opcode); + + SetRoundingMode(ROUND_TO_NEAREST); + + pBase = (unsigned int *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + switch (opcode & MASK_TRANSFER_LENGTH) { + case TRANSFER_SINGLE: + storeSingle(getFd(opcode), pAddress); + break; + case TRANSFER_DOUBLE: + storeDouble(getFd(opcode), pAddress); + break; +#ifdef CONFIG_FPE_NWFPE_XP + case TRANSFER_EXTENDED: + storeExtended(getFd(opcode), pAddress); + break; +#endif + default: + nRc = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned int) pFinal); + return nRc; } unsigned int PerformLFM(const unsigned int opcode) { - unsigned int i, Fd, *pBase, *pAddress, *pFinal, - write_back = WRITE_BACK(opcode); - - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - Fd = getFd(opcode); - for (i=getRegisterCount(opcode);i>0;i--) - { - loadMultiple(Fd,pAddress); - pAddress += 3; Fd++; - if (Fd == 8) Fd = 0; - } + unsigned int i, Fd, *pBase, *pAddress, *pFinal, + write_back = WRITE_BACK(opcode); - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return 1; + pBase = (unsigned int *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + Fd = getFd(opcode); + for (i = getRegisterCount(opcode); i > 0; i--) { + loadMultiple(Fd, pAddress); + pAddress += 3; + Fd++; + if (Fd == 8) + Fd = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned int) pFinal); + return 1; } unsigned int PerformSFM(const unsigned int opcode) { - unsigned int i, Fd, *pBase, *pAddress, *pFinal, - write_back = WRITE_BACK(opcode); - - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - Fd = getFd(opcode); - for (i=getRegisterCount(opcode);i>0;i--) - { - storeMultiple(Fd,pAddress); - pAddress += 3; Fd++; - if (Fd == 8) Fd = 0; - } + unsigned int i, Fd, *pBase, *pAddress, *pFinal, + write_back = WRITE_BACK(opcode); - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return 1; + pBase = (unsigned int *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + Fd = getFd(opcode); + for (i = getRegisterCount(opcode); i > 0; i--) { + storeMultiple(Fd, pAddress); + pAddress += 3; + Fd++; + if (Fd == 8) + Fd = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned int) pFinal); + return 1; } -#if 1 unsigned int EmulateCPDT(const unsigned int opcode) { - unsigned int nRc = 0; + unsigned int nRc = 0; - //printk("EmulateCPDT(0x%08x)\n",opcode); - - if (LDF_OP(opcode)) - { - nRc = PerformLDF(opcode); - } - else if (LFM_OP(opcode)) - { - nRc = PerformLFM(opcode); - } - else if (STF_OP(opcode)) - { - nRc = PerformSTF(opcode); - } - else if (SFM_OP(opcode)) - { - nRc = PerformSFM(opcode); - } - else - { - nRc = 0; - } - - return nRc; + if (LDF_OP(opcode)) { + nRc = PerformLDF(opcode); + } else if (LFM_OP(opcode)) { + nRc = PerformLFM(opcode); + } else if (STF_OP(opcode)) { + nRc = PerformSTF(opcode); + } else if (SFM_OP(opcode)) { + nRc = PerformSFM(opcode); + } else { + nRc = 0; + } + + return nRc; } -#endif diff -urN linux-2.4.21/arch/arm/nwfpe/fpa11_cprt.c linux-2.4.22/arch/arm/nwfpe/fpa11_cprt.c --- linux-2.4.21/arch/arm/nwfpe/fpa11_cprt.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpa11_cprt.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* NetWinder Floating Point Emulator (c) Rebel.COM, 1998,1999 - (c) Philip Blundell, 1999 + (c) Philip Blundell, 1999, 2001 Direct questions, comments to Scott Bambrough @@ -21,269 +21,348 @@ */ #include "fpa11.h" -#include "milieu.h" -#include "softfloat.h" #include "fpopcode.h" #include "fpa11.inl" #include "fpmodule.h" #include "fpmodule.inl" +#ifdef CONFIG_FPE_NWFPE_XP extern flag floatx80_is_nan(floatx80); -extern flag float64_is_nan( float64); -extern flag float32_is_nan( float32); +#endif +extern flag float64_is_nan(float64); +extern flag float32_is_nan(float32); void SetRoundingMode(const unsigned int opcode); unsigned int PerformFLT(const unsigned int opcode); unsigned int PerformFIX(const unsigned int opcode); -static unsigned int -PerformComparison(const unsigned int opcode); +static unsigned int PerformComparison(const unsigned int opcode); unsigned int EmulateCPRT(const unsigned int opcode) { - unsigned int nRc = 1; - - //printk("EmulateCPRT(0x%08x)\n",opcode); - if (opcode & 0x800000) - { - /* This is some variant of a comparison (PerformComparison will - sort out which one). Since most of the other CPRT - instructions are oddball cases of some sort or other it makes - sense to pull this out into a fast path. */ - return PerformComparison(opcode); - } - - /* Hint to GCC that we'd like a jump table rather than a load of CMPs */ - switch ((opcode & 0x700000) >> 20) - { - case FLT_CODE >> 20: nRc = PerformFLT(opcode); break; - case FIX_CODE >> 20: nRc = PerformFIX(opcode); break; - - case WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break; - case RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break; - -#if 0 /* We currently have no use for the FPCR, so there's no point - in emulating it. */ - case WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode))); - case RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break; -#endif + if (opcode & 0x800000) { + /* This is some variant of a comparison (PerformComparison + will sort out which one). Since most of the other CPRT + instructions are oddball cases of some sort or other it + makes sense to pull this out into a fast path. */ + return PerformComparison(opcode); + } + + /* Hint to GCC that we'd like a jump table rather than a load of CMPs */ + switch ((opcode & 0x700000) >> 20) { + case FLT_CODE >> 20: + return PerformFLT(opcode); + break; + case FIX_CODE >> 20: + return PerformFIX(opcode); + break; + + case WFS_CODE >> 20: + writeFPSR(readRegister(getRd(opcode))); + break; + case RFS_CODE >> 20: + writeRegister(getRd(opcode), readFPSR()); + break; + + default: + return 0; + } - default: nRc = 0; - } - - return nRc; + return 1; } unsigned int PerformFLT(const unsigned int opcode) { - FPA11 *fpa11 = GET_FPA11(); - - unsigned int nRc = 1; - SetRoundingMode(opcode); - - switch (opcode & MASK_ROUNDING_PRECISION) - { - case ROUND_SINGLE: - { - fpa11->fType[getFn(opcode)] = typeSingle; - fpa11->fpreg[getFn(opcode)].fSingle = - int32_to_float32(readRegister(getRd(opcode))); - } - break; - - case ROUND_DOUBLE: - { - fpa11->fType[getFn(opcode)] = typeDouble; - fpa11->fpreg[getFn(opcode)].fDouble = - int32_to_float64(readRegister(getRd(opcode))); - } - break; - - case ROUND_EXTENDED: - { - fpa11->fType[getFn(opcode)] = typeExtended; - fpa11->fpreg[getFn(opcode)].fExtended = - int32_to_floatx80(readRegister(getRd(opcode))); - } - break; - - default: nRc = 0; - } - - return nRc; + FPA11 *fpa11 = GET_FPA11(); + SetRoundingMode(opcode); + SetRoundingPrecision(opcode); + + switch (opcode & MASK_ROUNDING_PRECISION) { + case ROUND_SINGLE: + { + fpa11->fType[getFn(opcode)] = typeSingle; + fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode))); + } + break; + + case ROUND_DOUBLE: + { + fpa11->fType[getFn(opcode)] = typeDouble; + fpa11->fpreg[getFn(opcode)].fDouble = int32_to_float64(readRegister(getRd(opcode))); + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case ROUND_EXTENDED: + { + fpa11->fType[getFn(opcode)] = typeExtended; + fpa11->fpreg[getFn(opcode)].fExtended = int32_to_floatx80(readRegister(getRd(opcode))); + } + break; +#endif + + default: + return 0; + } + + return 1; } unsigned int PerformFIX(const unsigned int opcode) { - FPA11 *fpa11 = GET_FPA11(); - unsigned int nRc = 1; - unsigned int Fn = getFm(opcode); - - SetRoundingMode(opcode); - - switch (fpa11->fType[Fn]) - { - case typeSingle: - { - writeRegister(getRd(opcode), - float32_to_int32(fpa11->fpreg[Fn].fSingle)); - } - break; - - case typeDouble: - { - writeRegister(getRd(opcode), - float64_to_int32(fpa11->fpreg[Fn].fDouble)); - } - break; - - case typeExtended: - { - writeRegister(getRd(opcode), - floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); - } - break; - - default: nRc = 0; - } - - return nRc; -} + FPA11 *fpa11 = GET_FPA11(); + unsigned int Fn = getFm(opcode); - -static unsigned int __inline__ -PerformComparisonOperation(floatx80 Fn, floatx80 Fm) -{ - unsigned int flags = 0; + SetRoundingMode(opcode); - /* test for less than condition */ - if (floatx80_lt(Fn,Fm)) - { - flags |= CC_NEGATIVE; - } - - /* test for equal condition */ - if (floatx80_eq(Fn,Fm)) - { - flags |= CC_ZERO; - } - - /* test for greater than or equal condition */ - if (floatx80_lt(Fm,Fn)) - { - flags |= CC_CARRY; - } - - writeConditionCodes(flags); - return 1; + switch (fpa11->fType[Fn]) { + case typeSingle: + { + writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle)); + } + break; + + case typeDouble: + { + writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble)); + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + { + writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); + } + break; +#endif + + default: + return 0; + } + + return 1; } /* This instruction sets the flags N, Z, C, V in the FPSR. */ - static unsigned int PerformComparison(const unsigned int opcode) { - FPA11 *fpa11 = GET_FPA11(); - unsigned int Fn, Fm; - floatx80 rFn, rFm; - int e_flag = opcode & 0x400000; /* 1 if CxFE */ - int n_flag = opcode & 0x200000; /* 1 if CNxx */ - unsigned int flags = 0; - - //printk("PerformComparison(0x%08x)\n",opcode); - - Fn = getFn(opcode); - Fm = getFm(opcode); - - /* Check for unordered condition and convert all operands to 80-bit - format. - ?? Might be some mileage in avoiding this conversion if possible. - Eg, if both operands are 32-bit, detect this and do a 32-bit - comparison (cheaper than an 80-bit one). */ - switch (fpa11->fType[Fn]) - { - case typeSingle: - //printk("single.\n"); - if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) - goto unordered; - rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); - break; - - case typeDouble: - //printk("double.\n"); - if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) - goto unordered; - rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); - break; - - case typeExtended: - //printk("extended.\n"); - if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended)) - goto unordered; - rFn = fpa11->fpreg[Fn].fExtended; - break; - - default: return 0; - } - - if (CONSTANT_FM(opcode)) - { - //printk("Fm is a constant: #%d.\n",Fm); - rFm = getExtendedConstant(Fm); - if (floatx80_is_nan(rFm)) - goto unordered; - } - else - { - //printk("Fm = r%d which contains a ",Fm); - switch (fpa11->fType[Fm]) - { - case typeSingle: - //printk("single.\n"); - if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) - goto unordered; - rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); - break; - - case typeDouble: - //printk("double.\n"); - if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) - goto unordered; - rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); - break; - - case typeExtended: - //printk("extended.\n"); - if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended)) - goto unordered; - rFm = fpa11->fpreg[Fm].fExtended; - break; - - default: return 0; - } - } - - if (n_flag) - { - rFm.high ^= 0x8000; - } - - return PerformComparisonOperation(rFn,rFm); - - unordered: - /* ?? The FPA data sheet is pretty vague about this, in particular - about whether the non-E comparisons can ever raise exceptions. - This implementation is based on a combination of what it says in - the data sheet, observation of how the Acorn emulator actually - behaves (and how programs expect it to) and guesswork. */ - flags |= CC_OVERFLOW; - flags &= ~(CC_ZERO | CC_NEGATIVE); + FPA11 *fpa11 = GET_FPA11(); + unsigned int Fn = getFn(opcode), Fm = getFm(opcode); + int e_flag = opcode & 0x400000; /* 1 if CxFE */ + int n_flag = opcode & 0x200000; /* 1 if CNxx */ + unsigned int flags = 0; + +#ifdef CONFIG_FPE_NWFPE_XP + floatx80 rFn, rFm; + + /* Check for unordered condition and convert all operands to 80-bit + format. + ?? Might be some mileage in avoiding this conversion if possible. + Eg, if both operands are 32-bit, detect this and do a 32-bit + comparison (cheaper than an 80-bit one). */ + switch (fpa11->fType[Fn]) { + case typeSingle: + //printk("single.\n"); + if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) + goto unordered; + rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + //printk("double.\n"); + if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) + goto unordered; + rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); + break; + + case typeExtended: + //printk("extended.\n"); + if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended)) + goto unordered; + rFn = fpa11->fpreg[Fn].fExtended; + break; + + default: + return 0; + } + + if (CONSTANT_FM(opcode)) { + //printk("Fm is a constant: #%d.\n",Fm); + rFm = getExtendedConstant(Fm); + if (floatx80_is_nan(rFm)) + goto unordered; + } else { + //printk("Fm = r%d which contains a ",Fm); + switch (fpa11->fType[Fm]) { + case typeSingle: + //printk("single.\n"); + if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) + goto unordered; + rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); + break; + + case typeDouble: + //printk("double.\n"); + if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) + goto unordered; + rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); + break; + + case typeExtended: + //printk("extended.\n"); + if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended)) + goto unordered; + rFm = fpa11->fpreg[Fm].fExtended; + break; + + default: + return 0; + } + } + + if (n_flag) + rFm.high ^= 0x8000; + + /* test for less than condition */ + if (floatx80_lt(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (floatx80_eq(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (floatx80_lt(rFm, rFn)) + flags |= CC_CARRY; + +#else + if (CONSTANT_FM(opcode)) { + /* Fm is a constant. Do the comparison in whatever precision + Fn happens to be stored in. */ + if (fpa11->fType[Fn] == typeSingle) { + float32 rFm = getSingleConstant(Fm); + float32 rFn = fpa11->fpreg[Fn].fSingle; + + if (float32_is_nan(rFn)) + goto unordered; + + if (n_flag) + rFm ^= 0x80000000; + + /* test for less than condition */ + if (float32_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float32_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float32_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } else { + float64 rFm = getDoubleConstant(Fm); + float64 rFn = fpa11->fpreg[Fn].fDouble; + + if (float64_is_nan(rFn)) + goto unordered; + + if (n_flag) + rFm ^= 0x8000000000000000ULL; + + /* test for less than condition */ + if (float64_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float64_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float64_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } + } else { + /* Both operands are in registers. */ + if (fpa11->fType[Fn] == typeSingle + && fpa11->fType[Fm] == typeSingle) { + float32 rFm = fpa11->fpreg[Fm].fSingle; + float32 rFn = fpa11->fpreg[Fn].fSingle; + + if (float32_is_nan(rFn) + || float32_is_nan(rFm)) + goto unordered; + + if (n_flag) + rFm ^= 0x80000000; + + /* test for less than condition */ + if (float32_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float32_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float32_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } else { + /* Promote 32-bit operand to 64 bits. */ + float64 rFm, rFn; + + rFm = (fpa11->fType[Fm] == typeSingle) ? + float32_to_float64(fpa11->fpreg[Fm].fSingle) + : fpa11->fpreg[Fm].fDouble; + + rFn = (fpa11->fType[Fn] == typeSingle) ? + float32_to_float64(fpa11->fpreg[Fn].fSingle) + : fpa11->fpreg[Fn].fDouble; + + if (float64_is_nan(rFn) + || float64_is_nan(rFm)) + goto unordered; + + if (n_flag) + rFm ^= 0x8000000000000000ULL; + + /* test for less than condition */ + if (float64_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float64_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float64_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } + } + +#endif + + writeConditionCodes(flags); + + return 1; + + unordered: + /* ?? The FPA data sheet is pretty vague about this, in particular + about whether the non-E comparisons can ever raise exceptions. + This implementation is based on a combination of what it says in + the data sheet, observation of how the Acorn emulator actually + behaves (and how programs expect it to) and guesswork. */ + flags |= CC_OVERFLOW; + flags &= ~(CC_ZERO | CC_NEGATIVE); - if (BIT_AC & readFPSR()) flags |= CC_CARRY; + if (BIT_AC & readFPSR()) + flags |= CC_CARRY; - if (e_flag) float_raise(float_flag_invalid); + if (e_flag) + float_raise(float_flag_invalid); - writeConditionCodes(flags); - return 1; + writeConditionCodes(flags); + return 1; } diff -urN linux-2.4.21/arch/arm/nwfpe/fpmodule.c linux-2.4.22/arch/arm/nwfpe/fpmodule.c --- linux-2.4.21/arch/arm/nwfpe/fpmodule.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpmodule.c 2003-08-25 04:44:39.000000000 -0700 @@ -41,13 +41,19 @@ #include "fpa11.inl" /* kernel symbols required for signal handling */ -typedef struct task_struct* PTASK; +typedef struct task_struct *PTASK; + +#ifdef CONFIG_FPE_NWFPE_XP +#define NWFPE_BITS "extended" +#else +#define NWFPE_BITS "double" +#endif #ifdef MODULE void fp_send_sig(unsigned long sig, PTASK p, int priv); #if LINUX_VERSION_CODE > 0x20115 MODULE_AUTHOR("Scott Bambrough "); -MODULE_DESCRIPTION("NWFPE floating point emulator"); +MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)"); #endif #else @@ -63,7 +69,7 @@ /* external declarations for saved kernel symbols */ extern void (*kern_fp_enter)(void); -/* Original value of fp_enter from kernel before patched by fpe_init. */ +/* Original value of fp_enter from kernel before patched by fpe_init. */ static void (*orig_fp_enter)(void); /* forward declarations */ @@ -76,46 +82,45 @@ */ static int fpe_unload(void) { - return (kern_fp_enter == nwfpe_enter) ? 0 : 1; + return (kern_fp_enter == nwfpe_enter) ? 0 : 1; } #endif static int __init fpe_init(void) { - if (sizeof(FPA11) > sizeof(union fp_state)) { - printk(KERN_ERR "nwfpe: bad structure size\n"); - return -EINVAL; - } - - if (sizeof(FPREG) != 12) { - printk(KERN_ERR "nwfpe: bad register size\n"); - return -EINVAL; - } - + if (sizeof(FPA11) > sizeof(union fp_state)) { + printk(KERN_ERR "nwfpe: bad structure size\n"); + return -EINVAL; + } + + if (sizeof(FPREG) != 12) { + printk(KERN_ERR "nwfpe: bad register size\n"); + return -EINVAL; + } #ifdef MODULE - if (!mod_member_present(&__this_module, can_unload)) - return -EINVAL; - __this_module.can_unload = fpe_unload; + if (!mod_member_present(&__this_module, can_unload)) + return -EINVAL; + __this_module.can_unload = fpe_unload; #else - if (fpe_type[0] && strcmp(fpe_type, "nwfpe")) - return 0; + if (fpe_type[0] && strcmp(fpe_type, "nwfpe")) + return 0; #endif - /* Display title, version and copyright information. */ - printk(KERN_WARNING "NetWinder Floating Point Emulator V0.95 " - "(c) 1998-1999 Rebel.com\n"); - - /* Save pointer to the old FP handler and then patch ourselves in */ - orig_fp_enter = kern_fp_enter; - kern_fp_enter = nwfpe_enter; + /* Display title, version and copyright information. */ + printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 (" + NWFPE_BITS " precision)\n"); + + /* Save pointer to the old FP handler and then patch ourselves in */ + orig_fp_enter = kern_fp_enter; + kern_fp_enter = nwfpe_enter; - return 0; + return 0; } static void __exit fpe_exit(void) { - /* Restore the values we saved earlier. */ - kern_fp_enter = orig_fp_enter; + /* Restore the values we saved earlier. */ + kern_fp_enter = orig_fp_enter; } /* @@ -140,41 +145,42 @@ void float_raise(signed char flags) { - register unsigned int fpsr, cumulativeTraps; - + register unsigned int fpsr, cumulativeTraps; + #ifdef CONFIG_DEBUG_USER - printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08x\n", - current->comm, current->pid, flags, - __builtin_return_address(0), GET_USERREG()[15]); -#endif - - /* Keep SoftFloat exception flags up to date. */ - float_exception_flags |= flags; - - /* Read fpsr and initialize the cumulativeTraps. */ - fpsr = readFPSR(); - cumulativeTraps = 0; - - /* For each type of exception, the cumulative trap exception bit is only - set if the corresponding trap enable bit is not set. */ - if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC)) - cumulativeTraps |= BIT_IXC; - if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC)) - cumulativeTraps |= BIT_UFC; - if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC)) - cumulativeTraps |= BIT_OFC; - if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC)) - cumulativeTraps |= BIT_DZC; - if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC)) - cumulativeTraps |= BIT_IOC; - - /* Set the cumulative exceptions flags. */ - if (cumulativeTraps) - writeFPSR(fpsr | cumulativeTraps); - - /* Raise an exception if necessary. */ - if (fpsr & (flags << 16)) - fp_send_sig(SIGFPE, current, 1); + printk(KERN_DEBUG + "NWFPE: %s[%d] takes exception %08x at %p from %08x\n", + current->comm, current->pid, flags, + __builtin_return_address(0), GET_USERREG()[15]); +#endif + + /* Keep SoftFloat exception flags up to date. */ + float_exception_flags |= flags; + + /* Read fpsr and initialize the cumulativeTraps. */ + fpsr = readFPSR(); + cumulativeTraps = 0; + + /* For each type of exception, the cumulative trap exception bit is only + set if the corresponding trap enable bit is not set. */ + if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC)) + cumulativeTraps |= BIT_IXC; + if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC)) + cumulativeTraps |= BIT_UFC; + if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC)) + cumulativeTraps |= BIT_OFC; + if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC)) + cumulativeTraps |= BIT_DZC; + if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC)) + cumulativeTraps |= BIT_IOC; + + /* Set the cumulative exceptions flags. */ + if (cumulativeTraps) + writeFPSR(fpsr | cumulativeTraps); + + /* Raise an exception if necessary. */ + if (fpsr & (flags << 16)) + fp_send_sig(SIGFPE, current, 1); } module_init(fpe_init); diff -urN linux-2.4.21/arch/arm/nwfpe/fpmodule.inl linux-2.4.22/arch/arm/nwfpe/fpmodule.inl --- linux-2.4.21/arch/arm/nwfpe/fpmodule.inl 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpmodule.inl 2003-08-25 04:44:39.000000000 -0700 @@ -22,63 +22,64 @@ extern __inline__ unsigned int readRegister(const unsigned int nReg) { - /* Note: The CPU thinks it has dealt with the current instruction. As - a result the program counter has been advanced to the next - instruction, and points 4 bytes beyond the actual instruction - that caused the invalid instruction trap to occur. We adjust - for this in this routine. LDF/STF instructions with Rn = PC - depend on the PC being correct, as they use PC+8 in their - address calculations. */ - unsigned int *userRegisters = GET_USERREG(); - unsigned int val = userRegisters[nReg]; - if (REG_PC == nReg) val -= 4; - return val; + /* Note: The CPU thinks it has dealt with the current instruction. + As a result the program counter has been advanced to the next + instruction, and points 4 bytes beyond the actual instruction + that caused the invalid instruction trap to occur. We adjust + for this in this routine. LDF/STF instructions with Rn = PC + depend on the PC being correct, as they use PC+8 in their + address calculations. */ + unsigned int *userRegisters = GET_USERREG(); + unsigned int val = userRegisters[nReg]; + if (REG_PC == nReg) + val -= 4; + return val; } extern __inline__ void writeRegister(const unsigned int nReg, const unsigned int val) { - unsigned int *userRegisters = GET_USERREG(); - userRegisters[nReg] = val; + unsigned int *userRegisters = GET_USERREG(); + userRegisters[nReg] = val; } extern __inline__ unsigned int readCPSR(void) { - return(readRegister(REG_CPSR)); + return (readRegister(REG_CPSR)); } extern __inline__ void writeCPSR(const unsigned int val) { - writeRegister(REG_CPSR,val); + writeRegister(REG_CPSR, val); } extern __inline__ unsigned int readConditionCodes(void) { #ifdef __FPEM_TEST__ - return(0); + return (0); #else - return(readCPSR() & CC_MASK); + return (readCPSR() & CC_MASK); #endif } extern __inline__ void writeConditionCodes(const unsigned int val) { - unsigned int *userRegisters = GET_USERREG(); - unsigned int rval; - /* - * Operate directly on userRegisters since - * the CPSR may be the PC register itself. - */ - rval = userRegisters[REG_CPSR] & ~CC_MASK; - userRegisters[REG_CPSR] = rval | (val & CC_MASK); + unsigned int *userRegisters = GET_USERREG(); + unsigned int rval; + /* + * Operate directly on userRegisters since + * the CPSR may be the PC register itself. + */ + rval = userRegisters[REG_CPSR] & ~CC_MASK; + userRegisters[REG_CPSR] = rval | (val & CC_MASK); } extern __inline__ unsigned int readMemoryInt(unsigned int *pMem) { - return *pMem; + return *pMem; } diff -urN linux-2.4.21/arch/arm/nwfpe/fpopcode.c linux-2.4.22/arch/arm/nwfpe/fpopcode.c --- linux-2.4.21/arch/arm/nwfpe/fpopcode.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpopcode.c 2003-08-25 04:44:39.000000000 -0700 @@ -26,123 +26,64 @@ #include "fpmodule.h" #include "fpmodule.inl" +#ifdef CONFIG_FPE_NWFPE_XP const floatx80 floatx80Constant[] = { - { 0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ - { 0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ - { 0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ - { 0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ - { 0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ - { 0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ - { 0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ - { 0x4002, 0xa000000000000000ULL} /* extended 10.0 */ -}; + {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ + {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ + {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ + {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ + {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ + {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ + {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ + {0x4002, 0xa000000000000000ULL} /* extended 10.0 */ +}; +#endif const float64 float64Constant[] = { - 0x0000000000000000ULL, /* double 0.0 */ - 0x3ff0000000000000ULL, /* double 1.0 */ - 0x4000000000000000ULL, /* double 2.0 */ - 0x4008000000000000ULL, /* double 3.0 */ - 0x4010000000000000ULL, /* double 4.0 */ - 0x4014000000000000ULL, /* double 5.0 */ - 0x3fe0000000000000ULL, /* double 0.5 */ - 0x4024000000000000ULL /* double 10.0 */ -}; + 0x0000000000000000ULL, /* double 0.0 */ + 0x3ff0000000000000ULL, /* double 1.0 */ + 0x4000000000000000ULL, /* double 2.0 */ + 0x4008000000000000ULL, /* double 3.0 */ + 0x4010000000000000ULL, /* double 4.0 */ + 0x4014000000000000ULL, /* double 5.0 */ + 0x3fe0000000000000ULL, /* double 0.5 */ + 0x4024000000000000ULL /* double 10.0 */ +}; const float32 float32Constant[] = { - 0x00000000, /* single 0.0 */ - 0x3f800000, /* single 1.0 */ - 0x40000000, /* single 2.0 */ - 0x40400000, /* single 3.0 */ - 0x40800000, /* single 4.0 */ - 0x40a00000, /* single 5.0 */ - 0x3f000000, /* single 0.5 */ - 0x41200000 /* single 10.0 */ -}; - -unsigned int getTransferLength(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_TRANSFER_LENGTH) - { - case 0x00000000: nRc = 1; break; /* single precision */ - case 0x00008000: nRc = 2; break; /* double precision */ - case 0x00400000: nRc = 3; break; /* extended precision */ - default: nRc = 0; - } - - return(nRc); -} - -unsigned int getRegisterCount(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_REGISTER_COUNT) - { - case 0x00000000: nRc = 4; break; - case 0x00008000: nRc = 1; break; - case 0x00400000: nRc = 2; break; - case 0x00408000: nRc = 3; break; - default: nRc = 0; - } - - return(nRc); -} - -unsigned int getRoundingPrecision(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_ROUNDING_PRECISION) - { - case 0x00000000: nRc = 1; break; - case 0x00000080: nRc = 2; break; - case 0x00080000: nRc = 3; break; - default: nRc = 0; - } - - return(nRc); -} - -unsigned int getDestinationSize(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_DESTINATION_SIZE) - { - case 0x00000000: nRc = typeSingle; break; - case 0x00000080: nRc = typeDouble; break; - case 0x00080000: nRc = typeExtended; break; - default: nRc = typeNone; - } - - return(nRc); -} + 0x00000000, /* single 0.0 */ + 0x3f800000, /* single 1.0 */ + 0x40000000, /* single 2.0 */ + 0x40400000, /* single 3.0 */ + 0x40800000, /* single 4.0 */ + 0x40a00000, /* single 5.0 */ + 0x3f000000, /* single 0.5 */ + 0x41200000 /* single 10.0 */ +}; /* condition code lookup table index into the table is test code: EQ, NE, ... LT, GT, AL, NV bit position in short is condition code: NZCV */ static const unsigned short aCC[16] = { - 0xF0F0, // EQ == Z set - 0x0F0F, // NE - 0xCCCC, // CS == C set - 0x3333, // CC - 0xFF00, // MI == N set - 0x00FF, // PL - 0xAAAA, // VS == V set - 0x5555, // VC - 0x0C0C, // HI == C set && Z clear - 0xF3F3, // LS == C clear || Z set - 0xAA55, // GE == (N==V) - 0x55AA, // LT == (N!=V) - 0x0A05, // GT == (!Z && (N==V)) - 0xF5FA, // LE == (Z || (N!=V)) - 0xFFFF, // AL always - 0 // NV + 0xF0F0, // EQ == Z set + 0x0F0F, // NE + 0xCCCC, // CS == C set + 0x3333, // CC + 0xFF00, // MI == N set + 0x00FF, // PL + 0xAAAA, // VS == V set + 0x5555, // VC + 0x0C0C, // HI == C set && Z clear + 0xF3F3, // LS == C clear || Z set + 0xAA55, // GE == (N==V) + 0x55AA, // LT == (N!=V) + 0x0A05, // GT == (!Z && (N==V)) + 0xF5FA, // LE == (Z || (N!=V)) + 0xFFFF, // AL always + 0 // NV }; unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes) { - return (aCC[opcode>>28] >> (ccodes>>28)) & 1; + return (aCC[opcode >> 28] >> (ccodes >> 28)) & 1; } diff -urN linux-2.4.21/arch/arm/nwfpe/fpopcode.h linux-2.4.22/arch/arm/nwfpe/fpopcode.h --- linux-2.4.21/arch/arm/nwfpe/fpopcode.h 2001-04-11 19:02:27.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/fpopcode.h 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,7 @@ /* NetWinder Floating Point Emulator (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 Direct questions, comments to Scott Bambrough @@ -26,7 +27,7 @@ ARM Floating Point Instruction Classes | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT -|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|0|1| o f f s e t | CPDT +|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|1|0| o f f s e t | CPDT (copro 2) | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO |c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT @@ -34,7 +35,7 @@ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | CPDT data transfer instructions - LDF, STF, LFM, SFM + LDF, STF, LFM (copro 2), SFM (copro 2) CPDO dyadic arithmetic instructions ADF, MUF, SUF, RSF, DVF, RDF, @@ -186,7 +187,7 @@ #define BIT_LOAD 0x00100000 /* masks for load/store */ -#define MASK_CPDT 0x0c000000 /* data processing opcode */ +#define MASK_CPDT 0x0c000000 /* data processing opcode */ #define MASK_OFFSET 0x000000ff #define MASK_TRANSFER_LENGTH 0x00408000 #define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH @@ -236,7 +237,7 @@ #define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0) /* instruction identification masks */ -#define MASK_CPDO 0x0e000000 /* arithmetic opcode */ +#define MASK_CPDO 0x0e000000 /* arithmetic opcode */ #define MASK_ARITHMETIC_OPCODE 0x00f08000 #define MASK_DESTINATION_SIZE 0x00080080 @@ -282,7 +283,7 @@ === */ -#define MASK_CPRT 0x0e000010 /* register transfer opcode */ +#define MASK_CPRT 0x0e000010 /* register transfer opcode */ #define MASK_CPRT_CODE 0x00f00000 #define FLT_CODE 0x00000000 #define FIX_CODE 0x00100000 @@ -366,25 +367,111 @@ /* Get the rounding mode from the opcode. */ #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) +#ifdef CONFIG_FPE_NWFPE_XP static inline const floatx80 getExtendedConstant(const unsigned int nIndex) { - extern const floatx80 floatx80Constant[]; - return floatx80Constant[nIndex]; -} + extern const floatx80 floatx80Constant[]; + return floatx80Constant[nIndex]; +} +#endif static inline const float64 getDoubleConstant(const unsigned int nIndex) { - extern const float64 float64Constant[]; - return float64Constant[nIndex]; -} + extern const float64 float64Constant[]; + return float64Constant[nIndex]; +} static inline const float32 getSingleConstant(const unsigned int nIndex) { - extern const float32 float32Constant[]; - return float32Constant[nIndex]; -} + extern const float32 float32Constant[]; + return float32Constant[nIndex]; +} + +static inline unsigned int getTransferLength(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_TRANSFER_LENGTH) { + case 0x00000000: + nRc = 1; + break; /* single precision */ + case 0x00008000: + nRc = 2; + break; /* double precision */ + case 0x00400000: + nRc = 3; + break; /* extended precision */ + default: + nRc = 0; + } + + return (nRc); +} + +static inline unsigned int getRegisterCount(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_REGISTER_COUNT) { + case 0x00000000: + nRc = 4; + break; + case 0x00008000: + nRc = 1; + break; + case 0x00400000: + nRc = 2; + break; + case 0x00408000: + nRc = 3; + break; + default: + nRc = 0; + } + + return (nRc); +} + +static inline unsigned int getRoundingPrecision(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_ROUNDING_PRECISION) { + case 0x00000000: + nRc = 1; + break; + case 0x00000080: + nRc = 2; + break; + case 0x00080000: + nRc = 3; + break; + default: + nRc = 0; + } + + return (nRc); +} + +static inline unsigned int getDestinationSize(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_DESTINATION_SIZE) { + case 0x00000000: + nRc = typeSingle; + break; + case 0x00000080: + nRc = typeDouble; + break; + case 0x00080000: + nRc = typeExtended; + break; + default: + nRc = typeNone; + } -extern unsigned int getRegisterCount(const unsigned int opcode); -extern unsigned int getDestinationSize(const unsigned int opcode); + return (nRc); +} #endif diff -urN linux-2.4.21/arch/arm/nwfpe/fpsr.h linux-2.4.22/arch/arm/nwfpe/fpsr.h --- linux-2.4.21/arch/arm/nwfpe/fpsr.h 2000-02-13 10:47:01.000000000 -0800 +++ linux-2.4.22/arch/arm/nwfpe/fpsr.h 2003-08-25 04:44:39.000000000 -0700 @@ -38,12 +38,12 @@ ------------ Note: the system id byte is read only */ -typedef unsigned int FPSR; /* type for floating point status register */ -typedef unsigned int FPCR; /* type for floating point control register */ +typedef unsigned int FPSR; /* type for floating point status register */ +typedef unsigned int FPCR; /* type for floating point control register */ #define MASK_SYSID 0xff000000 #define BIT_HARDWARE 0x80000000 -#define FP_EMULATOR 0x01000000 /* System ID for emulator */ +#define FP_EMULATOR 0x01000000 /* System ID for emulator */ #define FP_ACCELERATOR 0x81000000 /* System ID for FPA11 */ /* EXCEPTION TRAP ENABLE BYTE @@ -51,11 +51,11 @@ #define MASK_TRAP_ENABLE 0x00ff0000 #define MASK_TRAP_ENABLE_STRICT 0x001f0000 -#define BIT_IXE 0x00100000 /* inexact exception enable */ -#define BIT_UFE 0x00080000 /* underflow exception enable */ -#define BIT_OFE 0x00040000 /* overflow exception enable */ -#define BIT_DZE 0x00020000 /* divide by zero exception enable */ -#define BIT_IOE 0x00010000 /* invalid operation exception enable */ +#define BIT_IXE 0x00100000 /* inexact exception enable */ +#define BIT_UFE 0x00080000 /* underflow exception enable */ +#define BIT_OFE 0x00040000 /* overflow exception enable */ +#define BIT_DZE 0x00020000 /* divide by zero exception enable */ +#define BIT_IOE 0x00010000 /* invalid operation exception enable */ /* SYSTEM CONTROL BYTE ---------------------- */ diff -urN linux-2.4.21/arch/arm/nwfpe/single_cpdo.c linux-2.4.22/arch/arm/nwfpe/single_cpdo.c --- linux-2.4.21/arch/arm/nwfpe/single_cpdo.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/single_cpdo.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,7 @@ /* NetWinder Floating Point Emulator (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 Direct questions, comments to Scott Bambrough @@ -32,224 +33,92 @@ float32 float32_log(float32 rFm); float32 float32_tan(float32 rFm); float32 float32_arccos(float32 rFm); -float32 float32_pow(float32 rFn,float32 rFm); -float32 float32_pol(float32 rFn,float32 rFm); +float32 float32_pow(float32 rFn, float32 rFm); +float32 float32_pol(float32 rFn, float32 rFm); -unsigned int SingleCPDO(const unsigned int opcode) +static float32 float32_rsf(float32 rFn, float32 rFm) { - FPA11 *fpa11 = GET_FPA11(); - float32 rFm, rFn; - unsigned int Fd, Fm, Fn, nRc = 1; - - Fm = getFm(opcode); - if (CONSTANT_FM(opcode)) - { - rFm = getSingleConstant(Fm); - } - else - { - switch (fpa11->fType[Fm]) - { - case typeSingle: - rFm = fpa11->fpreg[Fm].fSingle; - break; - - default: return 0; - } - } - - if (!MONADIC_INSTRUCTION(opcode)) - { - Fn = getFn(opcode); - switch (fpa11->fType[Fn]) - { - case typeSingle: - rFn = fpa11->fpreg[Fn].fSingle; - break; - - default: return 0; - } - } - - Fd = getFd(opcode); - switch (opcode & MASK_ARITHMETIC_OPCODE) - { - /* dyadic opcodes */ - case ADF_CODE: - fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm); - break; - - case MUF_CODE: - case FML_CODE: - fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm); - break; - - case SUF_CODE: - fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm); - break; - - case RSF_CODE: - fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn); - break; - - case DVF_CODE: - case FDV_CODE: - fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm); - break; - - case RDF_CODE: - case FRD_CODE: - fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn); - break; - -#if 0 - case POW_CODE: - fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm); - break; - - case RPW_CODE: - fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn); - break; -#endif - - case RMF_CODE: - fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm); - break; - -#if 0 - case POL_CODE: - fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm); - break; -#endif - - /* monadic opcodes */ - case MVF_CODE: - fpa11->fpreg[Fd].fSingle = rFm; - break; - - case MNF_CODE: - rFm ^= 0x80000000; - fpa11->fpreg[Fd].fSingle = rFm; - break; - - case ABS_CODE: - rFm &= 0x7fffffff; - fpa11->fpreg[Fd].fSingle = rFm; - break; - - case RND_CODE: - case URD_CODE: - fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm); - break; - - case SQT_CODE: - fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm); - break; - -#if 0 - case LOG_CODE: - fpa11->fpreg[Fd].fSingle = float32_log(rFm); - break; - - case LGN_CODE: - fpa11->fpreg[Fd].fSingle = float32_ln(rFm); - break; - - case EXP_CODE: - fpa11->fpreg[Fd].fSingle = float32_exp(rFm); - break; - - case SIN_CODE: - fpa11->fpreg[Fd].fSingle = float32_sin(rFm); - break; - - case COS_CODE: - fpa11->fpreg[Fd].fSingle = float32_cos(rFm); - break; - - case TAN_CODE: - fpa11->fpreg[Fd].fSingle = float32_tan(rFm); - break; - - case ASN_CODE: - fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm); - break; - - case ACS_CODE: - fpa11->fpreg[Fd].fSingle = float32_arccos(rFm); - break; - - case ATN_CODE: - fpa11->fpreg[Fd].fSingle = float32_arctan(rFm); - break; -#endif - - case NRM_CODE: - break; - - default: - { - nRc = 0; - } - } - - if (0 != nRc) fpa11->fType[Fd] = typeSingle; - return nRc; + return float32_sub(rFm, rFn); } -#if 0 -float32 float32_exp(float32 Fm) +static float32 float32_rdv(float32 rFn, float32 rFm) { -//series + return float32_div(rFm, rFn); } -float32 float32_ln(float32 Fm) -{ -//series -} +static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { + [ADF_CODE >> 20] = float32_add, + [MUF_CODE >> 20] = float32_mul, + [SUF_CODE >> 20] = float32_sub, + [RSF_CODE >> 20] = float32_rsf, + [DVF_CODE >> 20] = float32_div, + [RDF_CODE >> 20] = float32_rdv, + [RMF_CODE >> 20] = float32_rem, -float32 float32_sin(float32 rFm) -{ -//series -} + [FML_CODE >> 20] = float32_mul, + [FDV_CODE >> 20] = float32_div, + [FRD_CODE >> 20] = float32_rdv, +}; -float32 float32_cos(float32 rFm) +static float32 float32_mvf(float32 rFm) { -//series + return rFm; } -float32 float32_arcsin(float32 rFm) +static float32 float32_mnf(float32 rFm) { -//series + return rFm ^ 0x80000000; } -float32 float32_arctan(float32 rFm) +static float32 float32_abs(float32 rFm) { - //series + return rFm & 0x7fffffff; } -float32 float32_arccos(float32 rFm) -{ - //return float32_sub(halfPi,float32_arcsin(rFm)); -} +static float32 (*const monadic_single[16])(float32 rFm) = { + [MVF_CODE >> 20] = float32_mvf, + [MNF_CODE >> 20] = float32_mnf, + [ABS_CODE >> 20] = float32_abs, + [RND_CODE >> 20] = float32_round_to_int, + [URD_CODE >> 20] = float32_round_to_int, + [SQT_CODE >> 20] = float32_sqrt, + [NRM_CODE >> 20] = float32_mvf, +}; -float32 float32_log(float32 rFm) +unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) { - return float32_div(float32_ln(rFm),getSingleConstant(7)); -} + FPA11 *fpa11 = GET_FPA11(); + float32 rFm; + unsigned int Fm, opc_mask_shift; -float32 float32_tan(float32 rFm) -{ - return float32_div(float32_sin(rFm),float32_cos(rFm)); -} + Fm = getFm(opcode); + if (CONSTANT_FM(opcode)) { + rFm = getSingleConstant(Fm); + } else if (fpa11->fType[Fm] == typeSingle) { + rFm = fpa11->fpreg[Fm].fSingle; + } else { + return 0; + } -float32 float32_pow(float32 rFn,float32 rFm) -{ - return float32_exp(float32_mul(rFm,float32_ln(rFn))); -} + opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; + if (!MONADIC_INSTRUCTION(opcode)) { + unsigned int Fn = getFn(opcode); + float32 rFn; -float32 float32_pol(float32 rFn,float32 rFm) -{ - return float32_arctan(float32_div(rFn,rFm)); + if (fpa11->fType[Fn] == typeSingle && + dyadic_single[opc_mask_shift]) { + rFn = fpa11->fpreg[Fn].fSingle; + rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm); + } else { + return 0; + } + } else { + if (monadic_single[opc_mask_shift]) { + rFd->fSingle = monadic_single[opc_mask_shift](rFm); + } else { + return 0; + } + } + + return 1; } -#endif diff -urN linux-2.4.21/arch/arm/nwfpe/softfloat.c linux-2.4.22/arch/arm/nwfpe/softfloat.c --- linux-2.4.21/arch/arm/nwfpe/softfloat.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/softfloat.c 2003-08-25 04:44:39.000000000 -0700 @@ -29,8 +29,8 @@ */ #include "fpa11.h" -#include "milieu.h" -#include "softfloat.h" +//#include "milieu.h" +//#include "softfloat.h" /* ------------------------------------------------------------------------------- @@ -142,12 +142,14 @@ Returns the sign bit of the single-precision floating-point value `a'. ------------------------------------------------------------------------------- */ +#if 0 /* in softfloat.h */ INLINE flag extractFloat32Sign( float32 a ) { return a>>31; } +#endif /* ------------------------------------------------------------------------------- @@ -184,9 +186,9 @@ { #if 0 float32 f; - __asm__("@ packFloat32; - mov %0, %1, asl #31; - orr %0, %2, asl #23; + __asm__("@ packFloat32 \n\ + mov %0, %1, asl #31 \n\ + orr %0, %2, asl #23 \n\ orr %0, %3" : /* no outputs */ : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig) @@ -321,12 +323,14 @@ Returns the sign bit of the double-precision floating-point value `a'. ------------------------------------------------------------------------------- */ +#if 0 /* in softfloat.h */ INLINE flag extractFloat64Sign( float64 a ) { return a>>63; } +#endif /* ------------------------------------------------------------------------------- diff -urN linux-2.4.21/arch/arm/nwfpe/softfloat.h linux-2.4.22/arch/arm/nwfpe/softfloat.h --- linux-2.4.21/arch/arm/nwfpe/softfloat.h 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/nwfpe/softfloat.h 2003-08-25 04:44:39.000000000 -0700 @@ -40,7 +40,9 @@ input or output the `floatx80' type will be defined. ------------------------------------------------------------------------------- */ +#ifdef CONFIG_FPE_NWFPE_XP #define FLOATX80 +#endif /* ------------------------------------------------------------------------------- @@ -229,4 +231,46 @@ #endif +static inline flag extractFloat32Sign(float32 a) +{ + return a >> 31; +} + +static inline flag float32_eq_nocheck(float32 a, float32 b) +{ + return (a == b) || ((bits32) ((a | b) << 1) == 0); +} + +static inline flag float32_lt_nocheck(float32 a, float32 b) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign(a); + bSign = extractFloat32Sign(b); + if (aSign != bSign) + return aSign && ((bits32) ((a | b) << 1) != 0); + return (a != b) && (aSign ^ (a < b)); +} + +static inline flag extractFloat64Sign(float64 a) +{ + return a >> 63; +} + +static inline flag float64_eq_nocheck(float64 a, float64 b) +{ + return (a == b) || ((bits64) ((a | b) << 1) == 0); +} + +static inline flag float64_lt_nocheck(float64 a, float64 b) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign(a); + bSign = extractFloat64Sign(b); + if (aSign != bSign) + return aSign && ((bits64) ((a | b) << 1) != 0); + return (a != b) && (aSign ^ (a < b)); +} + #endif diff -urN linux-2.4.21/arch/arm/tools/mach-types linux-2.4.22/arch/arm/tools/mach-types --- linux-2.4.21/arch/arm/tools/mach-types 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/arm/tools/mach-types 2003-08-25 04:44:39.000000000 -0700 @@ -6,7 +6,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Sat Mar 16 15:56:27 2002 +# Last update: Sat Jun 28 12:10:54 2003 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -71,7 +71,7 @@ jupiter SA1100_JUPITER JUPITER 59 psionw ARCH_PSIONW PSIONW 60 aln SA1100_ALN ALN 61 -epxa10db ARCH_CAMELOT CAMELOT 62 +epxa ARCH_CAMELOT CAMELOT 62 gds2200 SA1100_GDS2200 GDS2200 63 psion_series7 SA1100_PSION_SERIES7 PSION_SERIES7 64 xfile SA1100_XFILE XFILE 65 @@ -149,12 +149,12 @@ blue_v1 ARCH_BLUE_V1 BLUE_V1 138 pxa_cerf ARCH_PXA_CERF PXA_CERF 139 arm7tevb ARCH_ARM7TEVB ARM7TEVB 140 -d7400 ARCH_D7400 D7400 141 +d7400 SA1100_D7400 D7400 141 piranha ARCH_PIRANHA PIRANHA 142 sbcamelot SA1100_SBCAMELOT SBCAMELOT 143 kings SA1100_KINGS KINGS 144 smdk2400 ARCH_SMDK2400 SMDK2400 145 -collie ARCH_COLLIE COLLIE 146 +collie SA1100_COLLIE COLLIE 146 idr ARCH_IDR IDR 147 badge4 SA1100_BADGE4 BADGE4 148 webnet ARCH_WEBNET WEBNET 149 @@ -175,6 +175,184 @@ iam SA1100_IAM IAM 164 tt530 SA1100_TT530 TT530 165 sam2400 ARCH_SAM2400 SAM2400 166 -jornada56x ARCH_JORNADA56X JORNADA56X 167 +jornada56x SA1100_JORNADA56X JORNADA56X 167 active SA1100_ACTIVE ACTIVE 168 iq80321 ARCH_IQ80321 IQ80321 169 +wid SA1100_WID WID 170 +sabinal ARCH_SABINAL SABINAL 171 +ixp425_matacumbe ARCH_IXP425_MATACUMBE IXP425_MATACUMBE 172 +miniprint SA1100_MINIPRINT MINIPRINT 173 +adm510x ARCH_ADM510X ADM510X 174 +svs200 SA1100_SVS200 SVS200 175 +atg_tcu ARCH_ATG_TCU ATG_TCU 176 +jornada820 SA1100_JORNADA820 JORNADA820 177 +s3c44b0 ARCH_S3C44B0 S3C44B0 178 +margis2 ARCH_MARGIS2 MARGIS2 179 +ks8695 ARCH_KS8695 KS8695 180 +brh ARCH_BRH BRH 181 +s3c2410 ARCH_S3C2410 S3C2410 182 +possio_px30 ARCH_POSSIO_PX30 POSSIO_PX30 183 +s3c2800 ARCH_S3C2800 S3C2800 184 +fleetwood SA1100_FLEETWOOD FLEETWOOD 185 +omaha ARCH_OMAHA OMAHA 186 +ta7 ARCH_TA7 TA7 187 +nova SA1100_NOVA NOVA 188 +hmk ARCH_HMK HMK 189 +karo ARCH_KARO KARO 190 +fester SA1100_FESTER FESTER 191 +gpi ARCH_GPI GPI 192 +smdk2410 ARCH_SMDK2410 SMDK2410 193 +premium ARCH_PREMIUM PREMIUM 194 +nexio SA1100_NEXIO NEXIO 195 +bitbox SA1100_BITBOX BITBOX 196 +g200 SA1100_G200 G200 197 +gill SA1100_GILL GILL 198 +pxa_mercury ARCH_PXA_MERCURY PXA_MERCURY 199 +ceiva ARCH_CEIVA CEIVA 200 +fret SA1100_FRET FRET 201 +emailphone SA1100_EMAILPHONE EMAILPHONE 202 +h3900 ARCH_H3900 H3900 203 +pxa1 ARCH_PXA1 PXA1 204 +koan369 SA1100_KOAN369 KOAN369 205 +cogent ARCH_COGENT COGENT 206 +esl_simputer ARCH_ESL_SIMPUTER ESL_SIMPUTER 207 +esl_simputer_clr ARCH_ESL_SIMPUTER_CLR ESL_SIMPUTER_CLR 208 +esl_simputer_bw ARCH_ESL_SIMPUTER_BW ESL_SIMPUTER_BW 209 +hhp_cradle ARCH_HHP_CRADLE HHP_CRADLE 210 +he500 ARCH_HE500 HE500 211 +inhandelf2 SA1100_INHANDELF2 INHANDELF2 212 +inhandftip SA1100_INHANDFTIP INHANDFTIP 213 +dnp1110 SA1100_DNP1110 DNP1110 214 +pnp1110 SA1100_PNP1110 PNP1110 215 +csb226 ARCH_CSB226 CSB226 216 +arnold SA1100_ARNOLD ARNOLD 217 +psiboard SA1100_PSIBOARD PSIBOARD 218 +jz8028 ARCH_JZ8028 JZ8028 219 +h5400 ARCH_IPAQ3 IPAQ3 220 +forte SA1100_FORTE FORTE 221 +acam SA1100_ACAM ACAM 222 +abox SA1100_ABOX ABOX 223 +atmel ARCH_ATMEL ATMEL 224 +sitsang ARCH_SITSANG SITSANG 225 +cpu1110lcdnet SA1100_CPU1110LCDNET CPU1110LCDNET 226 +mpl_vcma9 ARCH_MPL_VCMA9 MPL_VCMA9 227 +opus_a1 ARCH_OPUS_A1 OPUS_A1 228 +daytona ARCH_DAYTONA DAYTONA 229 +killbear SA1100_KILLBEAR KILLBEAR 230 +yoho ARCH_YOHO YOHO 231 +jasper ARCH_JASPER JASPER 232 +dsc25 ARCH_DSC25 DSC25 233 +innovator ARCH_INNOVATOR INNOVATOR 234 +ramses ARCH_RAMSES RAMSES 235 +s28x ARCH_S28X S28X 236 +mport3 ARCH_MPORT3 MPORT3 237 +pxa_eagle250 ARCH_PXA_EAGLE250 PXA_EAGLE250 238 +pdb ARCH_PDB PDB 239 +blue_2g SA1100_BLUE_2G BLUE_2G 240 +bluearch SA1100_BLUEARCH BLUEARCH 241 +ixdp2400 ARCH_IXMB2400 IXMB2400 242 +ixdp2800 ARCH_IXMB2800 IXMB2800 243 +explorer SA1100_EXPLORER EXPLORER 244 +ixdp425 ARCH_IXDP425 IXDP425 245 +chimp ARCH_CHIMP CHIMP 246 +stork_nest ARCH_STORK_NEST STORK_NEST 247 +stork_egg ARCH_STORK_EGG STORK_EGG 248 +wismo SA1100_WISMO WISMO 249 +ezlinx ARCH_EZLINX EZLINX 250 +at91rm9200 ARCH_AT91 AT91 251 +orion ARCH_ORION ORION 252 +neptune ARCH_NEPTUNE NEPTUNE 253 +hackkit SA1100_HACKKIT HACKKIT 254 +pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255 +lavinna SA1100_LAVINNA LAVINNA 256 +pxa_uengine ARCH_PXA_UENGINE PXA_UENGINE 257 +innokom ARCH_INNOKOM INNOKOM 258 +bms ARCH_BMS BMS 259 +ixcdp1100 ARCH_IXCDP1100 IXCDP1100 260 +prpmc1100 ARCH_PRPMC1100 PRPMC1100 261 +at91rm9200dk ARCH_AT91RM9200DK AT91RM9200DK 262 +armstick ARCH_ARMSTICK ARMSTICK 263 +armonie ARCH_ARMONIE ARMONIE 264 +mport1 ARCH_MPORT1 MPORT1 265 +s3c5410 ARCH_S3C5410 S3C5410 266 +zcp320a ARCH_ZCP320A ZCP320A 267 +i_box ARCH_I_BOX I_BOX 268 +stlc1502 ARCH_STLC1502 STLC1502 269 +siren ARCH_SIREN SIREN 270 +greenlake ARCH_GREENLAKE GREENLAKE 271 +argus ARCH_ARGUS ARGUS 272 +combadge SA1100_COMBADGE COMBADGE 273 +rokepxa ARCH_ROKEPXA ROKEPXA 274 +cintegrator ARCH_CINTEGRATOR CINTEGRATOR 275 +guidea07 ARCH_GUIDEA07 GUIDEA07 276 +tat257 ARCH_TAT257 TAT257 277 +igp2425 ARCH_IGP2425 IGP2425 278 +bluegrama ARCH_BLUEGRAMMA BLUEGRAMMA 279 +ipod ARCH_IPOD IPOD 280 +adsbitsyx ARCH_ADSBITSYX ADSBITSYX 281 +trizeps2 ARCH_TRIZEPS2 TRIZEPS2 282 +viper ARCH_VIPER VIPER 283 +adsbitsyplus SA1100_ADSBITSYPLUS ADSBITSYPLUS 284 +adsagc SA1100_ADSAGC ADSAGC 285 +stp7312 ARCH_STP7312 STP7312 286 +nx_phnx ARCH_PXA255 PXA255 287 +wep_ep250 ARCH_WEP_EP250 WEP_EP250 288 +inhandelf3 ARCH_INHANDELF3 INHANDELF3 289 +adi_coyote ARCH_ADI_COYOTE ADI_COYOTE 290 +iyonix ARCH_IYONIX IYONIX 291 +damicam_sa1110 ARCH_DAMICAM_SA1110 DAMICAM_SA1110 292 +meg03 ARCH_MEG03 MEG03 293 +pxa_whitechapel ARCH_PXA_WHITECHAPEL PXA_WHITECHAPEL 294 +nwsc ARCH_NWSC NWSC 295 +nwlarm ARCH_NWLARM NWLARM 296 +ixp425_mguard ARCH_IXP425_MGUARD IXP425_MGUARD 297 +pxa_netdcu4 ARCH_PXA_NETDCU4 PXA_NETDCU4 298 +ixdp2401 ARCH_IXDP2401 IXDP2401 299 +ixdp2801 ARCH_IXDP2801 IXDP2801 300 +zodiac ARCH_ZODIAC ZODIAC 301 +armmodul ARCH_ARMMODUL ARMMODUL 302 +ketop SA1100_KETOP KETOP 303 +av7200 ARCH_AV7200 AV7200 304 +arch_ti925 ARCH_ARCH_TI925 ARCH_TI925 305 +acq200 ARCH_ACQ200 ACQ200 306 +pt_dafit SA1100_PT_DAFIT PT_DAFIT 307 +ihba ARCH_IHBA IHBA 308 +quinque ARCH_QUINQUE QUINQUE 309 +nimbraone ARCH_NIMBRAONE NIMBRAONE 310 +nimbra29x ARCH_NIMBRA29X NIMBRA29X 311 +nimbra210 ARCH_NIMBRA210 NIMBRA210 312 +hhp_d95xx ARCH_HHP_D95XX HHP_D95XX 313 +labarm ARCH_LABARM LABARM 314 +m825xx ARCH_M825XX M825XX 315 +m7100 SA1100_M7100 M7100 316 +nipc2 ARCH_NIPC2 NIPC2 317 +fu7202 ARCH_FU7202 FU7202 318 +adsagx ARCH_ADSAGX ADSAGX 319 +pxa_pooh ARCH_PXA_POOH PXA_POOH 320 +bandon ARCH_BANDON BANDON 321 +pcm7210 ARCH_PCM7210 PCM7210 322 +nms9200 ARCH_NMS9200 NMS9200 323 +logodl ARCH_LOGODL LOGODL 324 +m7140 SA1100_M7140 M7140 325 +korebot ARCH_KOREBOT KOREBOT 326 +iq31244 ARCH_IQ31244 IQ31244 327 +koan393 SA1100_KOAN393 KOAN393 328 +inhandftip3 ARCH_INHANDFTIP3 INHANDFTIP3 329 +gonzo ARCH_GONZO GONZO 330 +bast ARCH_BAST BAST 331 +scanpass ARCH_SCANPASS SCANPASS 332 +ep7312_pooh ARCH_EP7312_POOH EP7312_POOH 333 +ta7s ARCH_TA7S TA7S 334 +ta7v ARCH_TA7V TA7V 335 +icarus SA1100_ICARUS ICARUS 336 +h1900 ARCH_H1900 H1900 337 +gemini SA1100_GEMINI GEMINI 338 +axim ARCH_AXIM AXIM 339 +audiotron ARCH_AUDIOTRON AUDIOTRON 340 +h2200 ARCH_H2200 H2200 341 +loox600 ARCH_LOOX600 LOOX600 342 +niop ARCH_NIOP NIOP 343 +dm310 ARCH_DM310 DM310 344 +seedpxa_c2 ARCH_SEEDPXA_C2 SEEDPXA_C2 345 +ixp4xx_mguardpci ARCH_IXP4XX_MGUARD_PCI IXP4XX_MGUARD_PCI 346 +h1940 ARCH_H1940 H1940 347 diff -urN linux-2.4.21/arch/cris/Makefile linux-2.4.22/arch/cris/Makefile --- linux-2.4.21/arch/cris/Makefile 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/cris/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.27 2002/03/08 13:08:50 bjornw Exp $ +# # cris/Makefile # # This file is included by the global makefile so that you can add your own @@ -56,6 +56,10 @@ # each others config options SUBDIRS += arch/cris/boot/rescue endif + +# Note that the order of .o files below is important is some cases +# (because initcalls are executed in the order they are linked) +# Never add any driver before mm.o! CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o DRIVERS += arch/cris/drivers/drivers.o LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a) diff -urN linux-2.4.21/arch/cris/boot/compressed/README linux-2.4.22/arch/cris/boot/compressed/README --- linux-2.4.21/arch/cris/boot/compressed/README 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.22/arch/cris/boot/compressed/README 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,5 @@ Creation of the self-extracting compressed kernel image (vmlinuz) ----------------------------------------------------------------- -$Id: README,v 1.1 2000/11/22 17:20:46 bjornw Exp $ This can be slightly confusing because it's a process with many steps. diff -urN linux-2.4.21/arch/cris/boot/compressed/misc.c linux-2.4.22/arch/cris/boot/compressed/misc.c --- linux-2.4.21/arch/cris/boot/compressed/misc.c 2001-05-01 16:04:56.000000000 -0700 +++ linux-2.4.22/arch/cris/boot/compressed/misc.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,19 +1,17 @@ /* * misc.c * - * $Id: misc.c,v 1.6 2001/04/09 10:00:21 starvik Exp $ - * - * This is a collection of several routines from gzip-1.0.3 + * This is a collection of several routines from gzip-1.0.3 * adapted for Linux. * * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 * puts by Nick Holloway 1993, better puts by Martin Mares 1995 * adoptation for Linux/CRIS Axis Communications AB, 1999 - * + * */ /* where the piggybacked kernel image expects itself to live. - * it is the same adress we use when we network load an uncompressed + * it is the same address we use when we network load an uncompressed * image into DRAM, and it is the address the kernel is linked to live * at by etrax100.ld. */ @@ -65,8 +63,8 @@ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ -#define get_byte() inbuf[inptr++] - +#define get_byte() inbuf[inptr++] + /* Diagnostic functions */ #ifdef DEBUG # define Assert(cond,msg) {if(!(cond)) error(msg);} @@ -95,20 +93,20 @@ static long bytes_out = 0; static uch *output_data; static unsigned long output_ptr = 0; - + static void *malloc(int size); static void free(void *where); static void error(char *m); static void gzip_mark(void **); static void gzip_release(void **); - + static void puts(const char *); /* the "heap" is put directly after the BSS ends, at end */ - + extern int end; static long free_mem_ptr = (long)&end; - + #include "../../../../lib/inflate.c" static void *malloc(int size) @@ -196,9 +194,9 @@ ulg c = crc; /* temporary variable */ unsigned n; uch *in, *out, ch; - + in = window; - out = &output_data[output_ptr]; + out = &output_data[output_ptr]; for (n = 0; n < outcnt; n++) { ch = *out++ = *in++; c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); @@ -229,7 +227,7 @@ decompress_kernel() { char revision; - + /* input_data is set in head.S */ inbuf = input_data; diff -urN linux-2.4.21/arch/cris/boot/rescue/head.S linux-2.4.22/arch/cris/boot/rescue/head.S --- linux-2.4.21/arch/cris/boot/rescue/head.S 2002-02-25 11:37:52.000000000 -0800 +++ linux-2.4.22/arch/cris/boot/rescue/head.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: head.S,v 1.10 2001/11/08 15:10:16 starvik Exp $ - * +/* * Rescue code, made to reside at the beginning of the * flash-memory. when it starts, it checks a partition * table at the first sector after the rescue sector. @@ -52,7 +51,7 @@ * * Bit 0 in flags signifies RW or RO. The rescue code only bothers * to check the checksum for RO partitions, since the others will - * change its data without updating the checksums. A 1 in bit 0 + * change their data without updating the checksums. A 1 in bit 0 * means RO, 0 means RW. That way, it is possible to set a partition * in RO mode initially, and later mark it as RW, since you can always * write 0's to the flash. @@ -60,7 +59,7 @@ * During the wait for serial input, the status LED will flash so the * user knows something went wrong. * - * Copyright (C) 1999,2001 Axis Communications AB + * Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB */ #include @@ -130,7 +129,7 @@ ;; first put a jump test to give a possibility of upgrading the rescue code ;; without erasing/reflashing the sector. we put a longword of -1 here and if - ;; its not -1, we jump using the value as jump target. since we can always + ;; it is not -1, we jump using the value as jump target. since we can always ;; change 1's to 0's without erasing the sector, it is possible to add new ;; code after this and altering the jumptarget in an upgrade. @@ -150,7 +149,20 @@ move.d 0x3, $r0 ; enable = on, phy = mii_clk move.d $r0, [R_NETWORK_GEN_CONFIG] #endif + + ;; Setup port PA and PB default initial directions and data + ;; (so we can flash LEDs, and so that DTR and others are set) + + move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 + move.b $r0, [R_PORT_PA_DIR] + move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 + move.b $r0, [R_PORT_PA_DATA] + move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 + move.b $r0, [R_PORT_PB_DIR] + move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 + move.b $r0, [R_PORT_PB_DATA] + ;; We need to setup the bus registers before we start using the DRAM #include "../../lib/dram_init.S" @@ -192,7 +204,7 @@ moveq -1, $r7 ploop: move.d [$r3+], $r1 ; partition offset (from ptable start) - bne notfirst ; check if its the partition containing ptable + bne notfirst ; check if it is the partition containing ptable nop ; yes.. move.d $r8, $r1 ; for its checksum check, skip the ptable move.d [$r3+], $r2 ; partition length @@ -226,18 +238,6 @@ ;; otherwise fall through to the rescue code. do_rescue: - ;; setup port PA and PB default initial directions and data - ;; (so we can flash LEDs, and so that DTR and others are set) - - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 - move.b $r0, [R_PORT_PA_DIR] - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 - move.b $r0, [R_PORT_PA_DATA] - - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 - move.b $r0, [R_PORT_PB_DIR] - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 - move.b $r0, [R_PORT_PB_DATA] ;; setup the serial port at 115200 baud diff -urN linux-2.4.21/arch/cris/boot/rescue/kimagerescue.S linux-2.4.22/arch/cris/boot/rescue/kimagerescue.S --- linux-2.4.21/arch/cris/boot/rescue/kimagerescue.S 2001-10-08 11:43:54.000000000 -0700 +++ linux-2.4.22/arch/cris/boot/rescue/kimagerescue.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: kimagerescue.S,v 1.5 2001/10/03 17:15:15 bjornw Exp $ - * +/* * Rescue code to be prepended on a kimage and copied to the * rescue serial port. * This is called from the rescue code, it will copy received data to diff -urN linux-2.4.21/arch/cris/boot/rescue/testrescue.S linux-2.4.22/arch/cris/boot/rescue/testrescue.S --- linux-2.4.21/arch/cris/boot/rescue/testrescue.S 2001-10-08 11:43:54.000000000 -0700 +++ linux-2.4.22/arch/cris/boot/rescue/testrescue.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,9 +1,8 @@ -/* $Id: testrescue.S,v 1.3 2001/10/03 17:15:15 bjornw Exp $ - * +/* * Simple testcode to download by the rescue block. * Just lits some LEDs to show it was downloaded correctly. - * - * Copyright (C) 1999 Axis Communications AB + * + * Copyright (C) 1999-2003 Axis Communications AB */ #define ASSEMBLER_MACROS_ONLY @@ -16,11 +15,9 @@ moveq -1, $r2 move.b $r2, [R_PORT_PA_DIR] moveq 0, $r2 - move.b $r2, [R_PORT_PA_DATA] + move.b $r2, [R_PORT_PA_DATA] endless: nop ba endless nop - - diff -urN linux-2.4.21/arch/cris/config.in linux-2.4.22/arch/cris/config.in --- linux-2.4.21/arch/cris/config.in 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/config.in 2003-08-25 04:44:39.000000000 -0700 @@ -32,14 +32,27 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF +string 'Kernel command line' CONFIG_ETRAX_CMDLINE "root=/dev/mtdblock3" + bool 'Use kernel gdb debugger' CONFIG_ETRAX_KGDB -bool 'Enable Etrax100 watchdog' CONFIG_ETRAX_WATCHDOG +bool 'Use Artpec gdb debugger' CONFIG_ETRAX_AGDB + +bool 'Enable ETRAX watchdog' CONFIG_ETRAX_WATCHDOG if [ "$CONFIG_ETRAX_WATCHDOG" = "y" ]; then - bool 'Disable watchdog during Oops printouts' CONFIG_ETRAX_WATCHDOG_NICE_DOGGY + bool ' Disable watchdog during Oops printouts' CONFIG_ETRAX_WATCHDOG_NICE_DOGGY fi +bool 'Enable ETRAX interrupt debugging' CONFIG_ETRAX_DEBUG_INTERRUPT + bool 'Enable ETRAX fast timer API' CONFIG_ETRAX_FAST_TIMER +if [ "$CONFIG_ETRAX_FAST_TIMER" = "y" ]; then + bool ' Enable fast timer logging' CONFIG_ETRAX_FAST_TIMER_LOGGING + bool ' Enable fast timer debug' CONFIG_ETRAX_FAST_TIMER_DEBUG + bool ' Enable fast timer sanity checks' CONFIG_ETRAX_FAST_TIMER_SANITY_CHECKS +fi + +bool 'Enable reboot at out of memory' CONFIG_OOM_REBOOT endmenu @@ -51,7 +64,7 @@ Etrax-100-LX-v2 CONFIG_ETRAX100LX_V2 \ Etrax-100-LX-for-xsim-simulator CONFIG_SVINTO_SIM" Etrax-100-LX-v1 -# Etrax100 LX v1 has a MMU "feature" requiring a low mapping +# ETRAX 100LX v1 has a MMU "feature" requiring a low mapping if [ "$CONFIG_ETRAX100LX" = "y" ]; then define_bool CONFIG_CRIS_LOW_MAP y @@ -64,8 +77,6 @@ int 'Buswidth of flash in bytes' CONFIG_ETRAX_FLASH_BUSWIDTH 2 -string 'Root device name' CONFIG_ETRAX_ROOT_DEVICE "/dev/mtdblock3" - choice 'Product LED port' \ "Port-PA-LEDs CONFIG_ETRAX_PA_LEDS \ Port-PB-LEDs CONFIG_ETRAX_PB_LEDS \ @@ -73,36 +84,36 @@ None CONFIG_ETRAX_NO_LEDS" Port-PA-LEDs if [ "$CONFIG_ETRAX_NO_LEDS" != "y" ]; then - int ' First green LED bit' CONFIG_ETRAX_LED1G 2 - int ' First red LED bit' CONFIG_ETRAX_LED1R 3 - int ' Second green LED bit' CONFIG_ETRAX_LED2G 4 - int ' Second red LED bit' CONFIG_ETRAX_LED2R 5 - int ' Third green LED bit' CONFIG_ETRAX_LED3G 2 - int ' Third red LED bit' CONFIG_ETRAX_LED3R 2 + int ' First green LED bit' CONFIG_ETRAX_LED1G 2 + int ' First red LED bit' CONFIG_ETRAX_LED1R 3 + int ' Second green LED bit' CONFIG_ETRAX_LED2G 4 + int ' Second red LED bit' CONFIG_ETRAX_LED2R 5 + int ' Third green LED bit' CONFIG_ETRAX_LED3G 2 + int ' Third red LED bit' CONFIG_ETRAX_LED3R 2 fi if [ "$CONFIG_ETRAX_CSP0_LEDS" = "y" ]; then - int ' Fourth red LED bit' CONFIG_ETRAX_LED4R 2 - int ' Fourth green LED bit' CONFIG_ETRAX_LED4G 2 - int ' Fifth red LED bit' CONFIG_ETRAX_LED5R 2 - int ' Fifth green LED bit' CONFIG_ETRAX_LED5G 2 - int ' Sixth red LED bit' CONFIG_ETRAX_LED6R 2 - int ' Sixth green LED bit' CONFIG_ETRAX_LED6G 2 - int ' Seventh red LED bit' CONFIG_ETRAX_LED7R 2 - int ' Seventh green LED bit' CONFIG_ETRAX_LED7G 2 - int ' Eigth yellow LED bit' CONFIG_ETRAX_LED8Y 2 - int ' Ninth yellow LED bit' CONFIG_ETRAX_LED9Y 2 - int ' Tenth yellow LED bit' CONFIG_ETRAX_LED10Y 2 - int ' Eleventh yellow LED bit' CONFIG_ETRAX_LED11Y 2 - int ' Twelfth red LED bit' CONFIG_ETRAX_LED12R 2 -fi + int ' Fourth red LED bit' CONFIG_ETRAX_LED4R 2 + int ' Fourth green LED bit' CONFIG_ETRAX_LED4G 2 + int ' Fifth red LED bit' CONFIG_ETRAX_LED5R 2 + int ' Fifth green LED bit' CONFIG_ETRAX_LED5G 2 + int ' Sixth red LED bit' CONFIG_ETRAX_LED6R 2 + int ' Sixth green LED bit' CONFIG_ETRAX_LED6G 2 + int ' Seventh red LED bit' CONFIG_ETRAX_LED7R 2 + int ' Seventh green LED bit' CONFIG_ETRAX_LED7G 2 + int ' Eigth yellow LED bit' CONFIG_ETRAX_LED8Y 2 + int ' Ninth yellow LED bit' CONFIG_ETRAX_LED9Y 2 + int ' Tenth yellow LED bit' CONFIG_ETRAX_LED10Y 2 + int ' Eleventh yellow LED bit' CONFIG_ETRAX_LED11Y 2 + int ' Twelfth red LED bit' CONFIG_ETRAX_LED12R 2 +fi choice 'Product debug-port' \ "Serial-0 CONFIG_ETRAX_DEBUG_PORT0 \ Serial-1 CONFIG_ETRAX_DEBUG_PORT1 \ Serial-2 CONFIG_ETRAX_DEBUG_PORT2 \ Serial-3 CONFIG_ETRAX_DEBUG_PORT3 \ - disabled CONFIG_ETRAX_DEBUG_PORT_NULL" Serial-0 + disabled CONFIG_ETRAX_DEBUG_PORT_NULL" Serial-0 choice 'Product rescue-port' \ "Serial-0 CONFIG_ETRAX_RESCUE_SER0 \ @@ -115,13 +126,13 @@ bool 'SDRAM support' CONFIG_ETRAX_SDRAM if [ "$CONFIG_ETRAX_SDRAM" = "n" ]; then - hex 'R_DRAM_CONFIG' CONFIG_ETRAX_DEF_R_DRAM_CONFIG 1a200040 - hex 'R_DRAM_TIMING' CONFIG_ETRAX_DEF_R_DRAM_TIMING 5611 + hex ' R_DRAM_CONFIG' CONFIG_ETRAX_DEF_R_DRAM_CONFIG 1a200040 + hex ' R_DRAM_TIMING' CONFIG_ETRAX_DEF_R_DRAM_TIMING 5611 fi if [ "$CONFIG_ETRAX_SDRAM" = "y" ]; then - hex 'R_SDRAM_CONFIG' CONFIG_ETRAX_DEF_R_SDRAM_CONFIG d2fa7878 - hex 'R_SDRAM_TIMING' CONFIG_ETRAX_DEF_R_SDRAM_TIMING 80004801 + hex ' R_SDRAM_CONFIG' CONFIG_ETRAX_DEF_R_SDRAM_CONFIG d2fa7878 + hex ' R_SDRAM_TIMING' CONFIG_ETRAX_DEF_R_SDRAM_TIMING 80004801 fi hex 'R_PORT_PA_DIR' CONFIG_ETRAX_DEF_R_PORT_PA_DIR 1c @@ -132,13 +143,13 @@ bool 'Software Shutdown Support' CONFIG_ETRAX_SOFT_SHUTDOWN if [ "$CONFIG_ETRAX_SOFT_SHUTDOWN" = "y" ]; then - int 'Shutdown bit on port CSP0' CONFIG_ETRAX_SHUTDOWN_BIT 12 - int 'Power button bit on port G' CONFIG_ETRAX_POWERBUTTON_BIT 25 + int ' Shutdown bit on port CSP0' CONFIG_ETRAX_SHUTDOWN_BIT 12 + int ' Power button bit on port G' CONFIG_ETRAX_POWERBUTTON_BIT 25 fi endmenu -# bring in Etrax built-in drivers +# bring in ETRAX built-in drivers source arch/cris/drivers/Config.in @@ -199,7 +210,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -258,8 +269,9 @@ #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC bool 'Kernel profiling support' CONFIG_PROFILE if [ "$CONFIG_PROFILE" = "y" ]; then - int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 + int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 fi +source crypto/Config.in source lib/Config.in endmenu diff -urN linux-2.4.21/arch/cris/defconfig linux-2.4.22/arch/cris/defconfig --- linux-2.4.21/arch/cris/defconfig 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/cris/defconfig 2003-08-25 04:44:39.000000000 -0700 @@ -85,8 +85,12 @@ # CONFIG_ETRAX_ETHERNET_LPSLAVE is not set CONFIG_ETRAX_SERIAL=y CONFIG_ETRAX_SERIAL_PORT0=y +CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT=y +CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN=y # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set CONFIG_ETRAX_SERIAL_PORT1=y +CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT=y +CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN=y # CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB is not set # CONFIG_ETRAX_SERIAL_PORT2 is not set # CONFIG_ETRAX_SERIAL_PORT3 is not set diff -urN linux-2.4.21/arch/cris/drivers/Config.in linux-2.4.22/arch/cris/drivers/Config.in --- linux-2.4.21/arch/cris/drivers/Config.in 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/Config.in 2003-08-25 04:44:39.000000000 -0700 @@ -23,15 +23,21 @@ bool 'Serial-port support' CONFIG_ETRAX_SERIAL if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then - bool ' Use fast timers for serial DMA flush (experimental)' CONFIG_ETRAX_SERIAL_FAST_TIMER + bool ' Use fast timers for serial DMA flush' CONFIG_ETRAX_SERIAL_FAST_TIMER if [ "$CONFIG_ETRAX_SERIAL_FAST_TIMER" = "n" ]; then bool ' Fast serial port DMA flush' CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST if [ "$CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST" = "n" ]; then int ' Receive flush timeout (ticks) ' CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5 fi fi + bool ' Enable external clock on PB6' CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED + if [ "$CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED" = "y" ]; then + int ' Extern clock frequency (baudrate=clk/8) (Hz)' CONFIG_ETRAX_EXTERN_PB6CLK_FREQ + fi bool ' Serial port 0 enabled' CONFIG_ETRAX_SERIAL_PORT0 if [ "$CONFIG_ETRAX_SERIAL_PORT0" = "y" ]; then + bool ' Serial port 0 uses DMA6 out' CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT + bool ' Serial port 0 uses DMA7 in' CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN choice 'Ser0 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA \ @@ -67,6 +73,8 @@ bool ' Serial port 1 enabled' CONFIG_ETRAX_SERIAL_PORT1 if [ "$CONFIG_ETRAX_SERIAL_PORT1" = "y" ]; then + bool ' Serial port 1 uses DMA8 out' CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT + bool ' Serial port 1 uses DMA9 in' CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN choice 'Ser1 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PA \ @@ -106,6 +114,8 @@ fi bool ' Serial port 2 enabled' CONFIG_ETRAX_SERIAL_PORT2 if [ "$CONFIG_ETRAX_SERIAL_PORT2" = "y" ]; then + bool ' Serial port 2 uses DMA2 out' CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT + bool ' Serial port 2 uses DMA3 in' CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN choice 'Ser2 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA \ @@ -139,6 +149,8 @@ fi bool ' Serial port 3 enabled' CONFIG_ETRAX_SERIAL_PORT3 if [ "$CONFIG_ETRAX_SERIAL_PORT3" = "y" ]; then + bool ' Serial port 3 uses DMA4 out' CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT + bool ' Serial port 3 uses DMA5 in' CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN choice 'Ser3 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PA \ @@ -303,6 +315,7 @@ bool 'Real Time Clock support' CONFIG_ETRAX_RTC if [ "$CONFIG_ETRAX_RTC" = "y" ]; then + bool ' Enable RTC read only mode' CONFIG_ETRAX_RTC_READONLY choice ' RTC chip' \ "DS1302 CONFIG_ETRAX_DS1302 \ PCF8563 CONFIG_ETRAX_PCF8563" DS1302 diff -urN linux-2.4.21/arch/cris/drivers/axisflashmap.c linux-2.4.22/arch/cris/drivers/axisflashmap.c --- linux-2.4.21/arch/cris/drivers/axisflashmap.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/axisflashmap.c 2003-08-25 04:44:39.000000000 -0700 @@ -11,6 +11,9 @@ * partition split defined below. * * $Log: axisflashmap.c,v $ + * Revision 1.29 2003/04/01 14:12:06 starvik + * Added loglevel for lots of printks + * * Revision 1.28 2002/10/01 08:08:43 jonashg * The first partition ends at the start of the partition table. * @@ -300,7 +303,8 @@ { struct mtd_info *mtd_cs = NULL; - printk("%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", + printk(KERN_INFO + "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", map_cs->name, map_cs->size, map_cs->map_priv_1); #ifdef CONFIG_MTD_AMDSTD @@ -387,7 +391,7 @@ struct partitiontable_head *ptable_head; struct partitiontable_entry *ptable; int use_default_ptable = 1; /* Until proven otherwise. */ - const char *pmsg = " /dev/flash%d at 0x%08x, size 0x%08x\n"; + const char *pmsg = KERN_INFO " /dev/flash%d at 0x%08x, size 0x%08x\n"; if (!(mymtd = flash_probe())) { /* There's no reason to use this module if no flash chip can @@ -396,7 +400,7 @@ panic("axisflashmap found no flash chip!\n"); } - printk("%s: 0x%08x bytes of flash memory.\n", + printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", mymtd->name, mymtd->size); mymtd->module = THIS_MODULE; @@ -440,7 +444,7 @@ ptable_ok = (csum == ptable_head->checksum); /* Read the entries and use/show the info. */ - printk(" Found a%s partition table at 0x%p-0x%p.\n", + printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", (ptable_ok ? " valid" : "n invalid"), ptable_head, max_addr); @@ -472,14 +476,14 @@ axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; - printk(" Adding readonly flash partition for romfs image:\n"); + printk(KERN_INFO " Adding readonly flash partition for romfs image:\n"); printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; } if (use_default_ptable) { - printk(" Using default partition table.\n"); + printk(KERN_INFO " Using default partition table.\n"); err = add_mtd_partitions(mymtd, axis_default_partitions, NUM_DEFAULT_PARTITIONS); } else { @@ -508,7 +512,7 @@ "mtd_info!\n"); } - printk(" Adding RAM partition for romfs image:\n"); + printk(KERN_INFO " Adding RAM partition for romfs image:\n"); printk(pmsg, pidx, romfs_start, romfs_length); err = mtdram_init_device(mtd_ram, (void*)romfs_start, diff -urN linux-2.4.21/arch/cris/drivers/ds1302.c linux-2.4.22/arch/cris/drivers/ds1302.c --- linux-2.4.21/arch/cris/drivers/ds1302.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/ds1302.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,9 +4,22 @@ *! *! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O *! -*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status +*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init *! *! $Log: ds1302.c,v $ +*! Revision 1.19 2003/06/12 08:02:05 johana +*! Removed faulty comma from printk. +*! Fixed warning () -> (void) +*! +*! Revision 1.18 2003/04/16 09:02:28 oskarp +*! * Merged change_branch--rtc_readonly to main. +*! +*! Revision 1.17 2003/04/01 14:12:06 starvik +*! Added loglevel for lots of printks +*! +*! Revision 1.16 2003/02/19 15:51:16 cedric +*! Start the clock from ds1302_init() +*! *! Revision 1.15 2002/10/11 16:14:33 johana *! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the *! trcklecharge register. @@ -95,7 +108,7 @@ *! *! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN *! -*! $Id: ds1302.c,v 1.15 2002/10/11 16:14:33 johana Exp $ +*! $Id: ds1302.c,v 1.19 2003/06/12 08:02:05 johana Exp $ *! *!***************************************************************************/ @@ -263,12 +276,23 @@ void ds1302_writereg(int reg, unsigned char val) { - ds1302_wenable(); - start(); - out_byte(0x80 | (reg << 1)); /* write register */ - out_byte(val); - stop(); - ds1302_wdisable(); +#ifndef CONFIG_ETRAX_RTC_READONLY + int do_writereg = 1; +#else + int do_writereg = 0; + + if (reg == RTC_TRICKLECHARGER) + do_writereg = 1; +#endif + + if (do_writereg) { + ds1302_wenable(); + start(); + out_byte(0x80 | (reg << 1)); /* write register */ + out_byte(val); + stop(); + ds1302_wdisable(); + } } void @@ -405,20 +429,33 @@ tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F); ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); return 0; - } + } + case RTC_VLOW_RD: + { + /* TODO: + * Implement voltage low detection support + */ + printk(KERN_WARNING "DS1302: RTC Voltage Low detection" + " is not supported\n"); + return 0; + } + case RTC_VLOW_SET: + { + /* TODO: + * Nothing to do since Voltage Low detection is not supported + */ + return 0; + } default: return -ENOIOCTLCMD; } } -int -get_rtc_status(char *buf) +static void +print_rtc_status(void) { - char *p; struct rtc_time tm; - p = buf; - get_rtc_time(&tm); /* @@ -426,13 +463,10 @@ * time or for Universal Standard Time (GMT). Probably local though. */ - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - - return p - buf; + printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n", + tm.tm_hour, tm.tm_min, tm.tm_sec); + printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); } @@ -466,11 +500,10 @@ out_byte(0xc1); /* read RAM byte 0 */ if((res = in_byte()) == MAGIC_PATTERN) { - char buf[100]; stop(); ds1302_wdisable(); - printk("%s: RTC found.\n", ds1302_name); - printk("%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n", + printk(KERN_INFO "%s: RTC found.\n", ds1302_name); + printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n", ds1302_name, CONFIG_ETRAX_DS1302_SDABIT, CONFIG_ETRAX_DS1302_SCLBIT, @@ -480,12 +513,10 @@ "PB", #endif CONFIG_ETRAX_DS1302_RSTBIT); - get_rtc_status(buf); - printk(buf); + print_rtc_status(); retval = 1; } else { stop(); - printk("%s: RTC not found.\n", ds1302_name); retval = 0; } @@ -518,9 +549,12 @@ (IO_STATE(R_GEN_CONFIG, g0dir, out))); *R_GEN_CONFIG = genconfig_shadow; #endif - if (!ds1302_probe()) + if (!ds1302_probe()) { + printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); return -1; + } #else + printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); return -1; #endif } @@ -533,5 +567,7 @@ /* Initialise trickle charger */ ds1302_writereg(RTC_TRICKLECHARGER, RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F)); + // Start clock by resetting CLOCK_HALT + ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F)); return 0; } diff -urN linux-2.4.21/arch/cris/drivers/eeprom.c linux-2.4.22/arch/cris/drivers/eeprom.c --- linux-2.4.21/arch/cris/drivers/eeprom.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/eeprom.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/*!***************************************************************************** +/****************************************************************************** *! *! Implements an interface for i2c compatible eeproms to run under linux. *! Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by @@ -20,6 +20,18 @@ *! in the spin-lock. *! *! $Log: eeprom.c,v $ +*! Revision 1.12 2003/04/09 08:31:14 pkj +*! Typo correction (taken from Linux 2.5). +*! +*! Revision 1.11 2003/02/12 20:43:46 johana +*! Previous checkin removed beginning of comment. +*! +*! Revision 1.10 2003/02/10 07:18:20 starvik +*! Removed misplaced ; +*! +*! Revision 1.9 2003/01/22 06:54:46 starvik +*! Fixed warnings issued by GCC 3.2.1 +*! *! Revision 1.8 2001/06/15 13:24:29 jonashg *! * Added verification of pointers from userspace in read and write. *! * Made busy counter volatile. @@ -203,7 +215,7 @@ * it will mirror the address space: * 1. We read two locations (that are mirrored), * if the content differs * it's a 16kB EEPROM. - * 2. if it doesn't differ - write diferent value to one of the locations, + * 2. if it doesn't differ - write different value to one of the locations, * check the other - if content still is the same it's a 2k EEPROM, * restore original data. */ @@ -493,7 +505,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off) { - int i, read=0; + int read=0; unsigned long p = file->f_pos; unsigned char page; @@ -519,7 +531,7 @@ if(!eeprom_address(p)) { printk(KERN_INFO "%s: Read failed to address the eeprom: " - "0x%08X (%i) page: %i\n", eeprom_name, p, p, page); + "0x%08lX (%li) page: %i\n", eeprom_name, p, p, page); i2c_stop(); /* don't forget to wake them up */ @@ -602,7 +614,7 @@ if(!eeprom_address(p)) { printk(KERN_INFO "%s: Write failed to address the eeprom: " - "0x%08X (%i) \n", eeprom_name, p, p); + "0x%08lX (%li) \n", eeprom_name, p, p); i2c_stop(); /* don't forget to wake them up */ @@ -740,7 +752,7 @@ static int eeprom_address(unsigned long addr) { - int i, j; + int i; unsigned char page, offset; page = (unsigned char) (addr >> 8); @@ -795,7 +807,7 @@ return 1; } -/* Reads from current adress. */ +/* Reads from current address. */ static int read_from_eeprom(char * buf, int count) { diff -urN linux-2.4.21/arch/cris/drivers/ethernet.c linux-2.4.22/arch/cris/drivers/ethernet.c --- linux-2.4.21/arch/cris/drivers/ethernet.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/ethernet.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: ethernet.c,v 1.34 2002/12/13 07:17:44 starvik Exp $ +/* $Id: ethernet.c,v 1.44 2003/07/01 10:55:07 starvik Exp $ * * e100net.c: A network driver for the ETRAX 100LX network controller. * @@ -7,9 +7,52 @@ * The outline of this driver comes from skeleton.c. * * $Log: ethernet.c,v $ - * Revision 1.34 2002/12/13 07:17:44 starvik - * Basic ethtool and MII ioctls - * Handle out of memory when allocating new buffers + * Revision 1.44 2003/07/01 10:55:07 starvik + * Never bring down link to make stupid POE equipment happy + * + * Revision 1.43 2003/04/24 08:26:50 starvik + * New LED behaviour: LED off when no link + * + * Revision 1.42 2003/04/10 07:14:58 starvik + * Merge of changes from todo list + * + * Revision 1.41 2003/04/09 08:31:14 pkj + * Typo correction (taken from Linux 2.5). + * + * Revision 1.40 2003/04/01 14:12:06 starvik + * Added loglevel for lots of printks + * + * Revision 1.39.2.3 2003/04/01 07:51:14 starvik + * Default Ethernet Stations Address can be specified with command line option. + * + * Revision 1.39.2.2 2003/03/31 15:41:07 starvik + * Only communicate with transciever when ETRAX is properly configured. + * + * Revision 1.39.2.1 2003/03/31 14:12:46 starvik + * Transmit interrupt always enabled. This has two side effects: + * 1. UDP (and possibly other protocols) works on quiet networks + * 2. Slightly lower transmit performance + * + * Revision 1.39 2003/03/06 15:45:39 henriken + * Off by one error in group address register setting. + * + * Revision 1.38 2003/02/27 17:23:07 starvik + * Corrected Rev to Revision + * + * Revision 1.37 2003/02/27 10:52:59 magnusmn + * More generic transceiver support. + * + * Revision 1.33.2.4 2003/02/24 16:51:26 magnusmn + * TDK specific registers to check speed/duplex + * + * Revision 1.33.2.3 2003/02/24 09:16:31 magnusmn + * ethernet.c + * + * Revision 1.33.2.2 2003/02/21 11:57:27 magnusmn + * Merging differences between 1.36 and 1.33 into ethernet.c (needed ethtool ioctl) + * + * Revision 1.33.2.1 2002/12/04 07:54:49 starvik + * First attempt to get more generic transceiver support * * Revision 1.33 2002/10/02 20:16:17 hp * SETF, SETS: Use underscored IO_x_ macros rather than incorrect token concatenation @@ -220,6 +263,16 @@ struct sk_buff* skb; } etrax_eth_descr; +/* Some transceivers requires special handling */ +struct transceiver_ops +{ + unsigned int oui; + void (*check_speed)(void); + void (*check_duplex)(void); +}; + +struct transceiver_ops* transceiver; + /* Duplex settings */ enum duplex { @@ -240,10 +293,17 @@ */ #define MDIO_BASE_STATUS_REG 0x1 #define MDIO_BASE_CONTROL_REG 0x0 +#define MDIO_PHY_ID_HIGH_REG 0x2 +#define MDIO_PHY_ID_LOW_REG 0x3 #define MDIO_BC_NEGOTIATE 0x0200 #define MDIO_BC_FULL_DUPLEX_MASK 0x0100 #define MDIO_BC_AUTO_NEG_MASK 0x1000 #define MDIO_BC_SPEED_SELECT_MASK 0x2000 +#define MDIO_STATUS_100_FD 0x4000 +#define MDIO_STATUS_100_HD 0x2000 +#define MDIO_STATUS_10_FD 0x1000 +#define MDIO_STATUS_10_HD 0x0800 +#define MDIO_STATUS_SPEED_DUPLEX_MASK 0x7800 #define MDIO_ADVERTISMENT_REG 0x4 #define MDIO_ADVERT_100_FD 0x100 #define MDIO_ADVERT_100_HD 0x080 @@ -257,9 +317,13 @@ /* Broadcom specific */ #define MDIO_AUX_CTRL_STATUS_REG 0x18 -#define MDIO_FULL_DUPLEX_IND 0x1 -#define MDIO_SPEED 0x2 -#define MDIO_PHYS_ADDR 0x0 +#define MDIO_BC_FULL_DUPLEX_IND 0x1 +#define MDIO_BC_SPEED 0x2 + +/* TDK specific */ +#define MDIO_TDK_DIAGNOSTIC_REG 18 +#define MDIO_TDK_DIAGNOSTIC_RATE 0x400 +#define MDIO_TDK_DIAGNOSTIC_DPLX 0x800 /* Network flash constants */ #define NET_FLASH_TIME (HZ/50) /* 20 ms */ @@ -303,11 +367,12 @@ static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32))); static unsigned int network_rec_config_shadow = 0; +static unsigned int mdio_phy_addr; /* Transciever address */ /* Network speed indication. */ static struct timer_list speed_timer; static struct timer_list clear_led_timer; -static int current_speed; /* Speed read from tranceiver */ +static int current_speed; /* Speed read from transceiver */ static int current_speed_selection; /* Speed selected by user */ static int led_next_time; static int led_active; @@ -337,6 +402,7 @@ static void e100_hardware_send_packet(char *buf, int length); static void update_rx_stats(struct net_device_stats *); static void update_tx_stats(struct net_device_stats *); +static int e100_probe_transceiver(void); static void e100_check_speed(unsigned long dummy); static void e100_set_speed(unsigned long speed); @@ -349,11 +415,25 @@ static void e100_send_mdio_cmd(unsigned short cmd, int write_cmd); static void e100_send_mdio_bit(unsigned char bit); static unsigned char e100_receive_mdio_bit(void); -static void e100_reset_tranceiver(void); +static void e100_reset_transceiver(void); static void e100_clear_network_leds(unsigned long dummy); static void e100_set_network_leds(int active); +static void broadcom_check_speed(void); +static void broadcom_check_duplex(void); +static void tdk_check_speed(void); +static void tdk_check_duplex(void); +static void generic_check_speed(void); +static void generic_check_duplex(void); + +struct transceiver_ops transceivers[] = +{ + {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ + {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK */ + {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ +}; + #define tx_done(dev) (*R_DMA_CH0_CMD == 0) /* @@ -369,11 +449,12 @@ { int i; - printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2001 Axis Communications AB\n"); + printk(KERN_INFO + "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2001 Axis Communications AB\n"); dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */ - printk("%s initialized\n", dev->name); + printk(KERN_INFO "%s initialized\n", dev->name); /* make Linux aware of the new hardware */ @@ -468,7 +549,6 @@ current_speed_selection = 0; /* Auto */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; speed_timer.function = e100_check_speed; - add_timer(&speed_timer); clear_led_timer.function = e100_clear_network_leds; @@ -476,8 +556,11 @@ current_duplex = autoneg; duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; duplex_timer.function = e100_check_duplex; - add_timer(&duplex_timer); + /* Initialize group address registers to make sure that no */ + /* unwanted addresses are matched */ + *R_NETWORK_GA_0 = 0x00000000; + *R_NETWORK_GA_1 = 0x00000000; return 0; } @@ -508,8 +591,7 @@ /* show it in the log as well */ - printk("%s: changed MAC to ", dev->name); - + printk(KERN_INFO "%s: changed MAC to ", dev->name); for (i = 0; i < 5; i++) printk("%02X:", dev->dev_addr[i]); @@ -532,12 +614,6 @@ { unsigned long flags; - /* disable the ethernet interface while we configure it */ - - *R_NETWORK_GEN_CONFIG = - IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | - IO_STATE(R_NETWORK_GEN_CONFIG, enable, off); - /* enable the MDIO output pin */ *R_NETWORK_MGM_CTRL = IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable); @@ -636,7 +712,8 @@ /* enable the irq's for ethernet DMA */ *R_IRQ_MASK2_SET = - IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); + IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) | + IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, overrun, set) | @@ -665,6 +742,14 @@ restore_flags(flags); + /* Probe for transceiver */ + if (e100_probe_transceiver()) + goto grace_exit4; + + /* Start duplex/speed timers */ + add_timer(&speed_timer); + add_timer(&duplex_timer); + /* We are now ready to accept transmit requeusts from * the queueing layer of the networking. */ @@ -684,6 +769,33 @@ return -EAGAIN; } +static void +generic_check_speed(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG); + if ((data & MDIO_ADVERT_100_FD) || + (data & MDIO_ADVERT_100_HD)) + current_speed = 100; + else + current_speed = 10; +} + +static void +tdk_check_speed(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG); + current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10); +} + +static void +broadcom_check_speed(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); + current_speed = (data & MDIO_BC_SPEED ? 100 : 10); +} static void e100_check_speed(unsigned long dummy) @@ -695,8 +807,7 @@ if (!(data & MDIO_LINK_UP_MASK)) { current_speed = 0; } else { - data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); - current_speed = (data & MDIO_SPEED ? 100 : 10); + transceiver->check_speed(); } if (old_speed != current_speed) @@ -761,29 +872,21 @@ static void e100_set_speed(unsigned long speed) { - current_speed_selection = speed; - e100_negotiate(); + if (speed != current_speed_selection) { + current_speed_selection = speed; + e100_negotiate(); + } } static void e100_check_duplex(unsigned long dummy) { - unsigned long data; - - data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); - - if (data & MDIO_FULL_DUPLEX_IND) { - if (!full_duplex) { /* Duplex changed to full? */ - full_duplex = 1; - SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); - *R_NETWORK_REC_CONFIG = network_rec_config_shadow; - } - } else { /* half */ - if (full_duplex) { /* Duplex changed to half? */ - full_duplex = 0; - SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); - *R_NETWORK_REC_CONFIG = network_rec_config_shadow; - } + int old_duplex = full_duplex; + transceiver->check_duplex(); + if (old_duplex != full_duplex) { + /* Duplex changed */ + SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); + *R_NETWORK_REC_CONFIG = network_rec_config_shadow; } /* Reinitialize the timer. */ @@ -791,13 +894,71 @@ add_timer(&duplex_timer); } +static void +generic_check_duplex(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG); + if ((data & MDIO_ADVERT_100_FD) || + (data & MDIO_ADVERT_10_FD)) + full_duplex = 1; + else + full_duplex = 0; +} + +static void +tdk_check_duplex(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG); + full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0; +} + +static void +broadcom_check_duplex(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); + full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0; +} + static void e100_set_duplex(enum duplex new_duplex) { - current_duplex = new_duplex; - e100_negotiate(); + if (new_duplex != current_duplex) { + current_duplex = new_duplex; + e100_negotiate(); + } } +static int +e100_probe_transceiver(void) +{ + unsigned int phyid_high; + unsigned int phyid_low; + unsigned int oui; + struct transceiver_ops* ops = NULL; + + /* Probe MDIO physical address */ + for (mdio_phy_addr = 0; mdio_phy_addr <= 31; mdio_phy_addr++) { + if (e100_get_mdio_reg(MDIO_BASE_STATUS_REG) != 0xffff) + break; + } + if (mdio_phy_addr == 32) + return -ENODEV; + + /* Get manufacturer */ + phyid_high = e100_get_mdio_reg(MDIO_PHY_ID_HIGH_REG); + phyid_low = e100_get_mdio_reg(MDIO_PHY_ID_LOW_REG); + oui = (phyid_high << 6) | (phyid_low >> 10); + + for (ops = &transceivers[0]; ops->oui; ops++) { + if (ops->oui == oui) + break; + } + transceiver = ops; + return 0; +} static unsigned short e100_get_mdio_reg(unsigned char reg_num) @@ -807,7 +968,7 @@ int bitCounter; /* Start of frame, OP Code, Physical Address, Register Address */ - cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (MDIO_PHYS_ADDR << 7) | + cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (mdio_phy_addr << 7) | (reg_num << 2); e100_send_mdio_cmd(cmd, 0); @@ -828,7 +989,7 @@ int bitCounter; unsigned short cmd; - cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | + cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (reg << 2); e100_send_mdio_cmd(cmd, 1); @@ -888,7 +1049,7 @@ } static void -e100_reset_tranceiver(void) +e100_reset_transceiver(void) { unsigned short cmd; unsigned short data; @@ -896,7 +1057,7 @@ data = e100_get_mdio_reg(MDIO_BASE_CONTROL_REG); - cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | (MDIO_BASE_CONTROL_REG << 2); + cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MDIO_BASE_CONTROL_REG << 2); e100_send_mdio_cmd(cmd, 1); @@ -928,9 +1089,9 @@ RESET_DMA(NETWORK_TX_DMA_NBR); WAIT_DMA(NETWORK_TX_DMA_NBR); - /* Reset the tranceiver. */ + /* Reset the transceiver. */ - e100_reset_tranceiver(); + e100_reset_transceiver(); /* and get rid of the packets that never got an interrupt */ while (myFirstTxDesc != myNextTxDesc) @@ -978,9 +1139,6 @@ /* Stop queue if full */ if (myNextTxDesc == myFirstTxDesc) { - /* Enable transmit interrupt to wake up queue */ - *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); - *R_IRQ_MASK2_SET = IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set); netif_stop_queue(dev); } @@ -1001,6 +1159,11 @@ struct net_local *np = (struct net_local *)dev->priv; unsigned long irqbits = *R_IRQ_MASK2_RD; + /* Disable RX/TX IRQs to avoid reentrancy */ + *R_IRQ_MASK2_CLR = + IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) | + IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr); + /* Handle received packets */ if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) { /* acknowledge the eop interrupt */ @@ -1044,9 +1207,13 @@ if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { /* acknowledge the eop interrupt and wake up queue */ *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); - *R_IRQ_MASK2_CLR = IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr); netif_wake_queue(dev); } + + /* Enable RX/TX IRQs again */ + *R_IRQ_MASK2_SET = + IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) | + IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); } static void @@ -1183,14 +1350,10 @@ { struct net_local *np = (struct net_local *)dev->priv; - printk("Closing %s.\n", dev->name); + printk(KERN_INFO "Closing %s.\n", dev->name); netif_stop_queue(dev); - *R_NETWORK_GEN_CONFIG = - IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | - IO_STATE(R_NETWORK_GEN_CONFIG, enable, off); - *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) | IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) | @@ -1221,6 +1384,9 @@ update_rx_stats(&np->stats); update_tx_stats(&np->stats); + /* Stop speed/duplex timers */ + del_timer(&speed_timer); + del_timer(&duplex_timer); return 0; } @@ -1233,7 +1399,7 @@ case SIOCETHTOOL: return e100_ethtool_ioctl(dev,ifr); case SIOCGMIIPHY: /* Get PHY address */ - data->phy_id = MDIO_PHYS_ADDR; + data->phy_id = mdio_phy_addr; break; case SIOCGMIIREG: /* Read MII register */ data->val_out = e100_get_mdio_reg(data->reg_num); @@ -1252,7 +1418,7 @@ case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */ e100_set_speed(0); break; - case SET_ETH_DUPLEX_HALF: /* Hhalf duplex. */ + case SET_ETH_DUPLEX_HALF: /* Half duplex. */ e100_set_duplex(half); break; case SET_ETH_DUPLEX_FULL: /* Full duplex. */ @@ -1285,7 +1451,7 @@ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; ecmd.port = PORT_TP; ecmd.transceiver = XCVR_EXTERNAL; - ecmd.phy_address = MDIO_PHYS_ADDR; + ecmd.phy_address = mdio_phy_addr; ecmd.speed = current_speed; ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; ecmd.advertising = ADVERTISED_TP; @@ -1328,7 +1494,7 @@ struct ethtool_drvinfo info; memset((void *) &info, 0, sizeof (info)); strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1); - strncpy(info.version, "$Rev$", sizeof(info.version) - 1); + strncpy(info.version, "$Revision: 1.44 $", sizeof(info.version) - 1); strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1); strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1); info.regdump_len = 0; @@ -1457,7 +1623,7 @@ hash_ix &= 0x3f; - if (hash_ix > 32) { + if (hash_ix >= 32) { hi_bits |= (1 << (hash_ix-32)); } else { @@ -1526,7 +1692,7 @@ if (!current_speed) { /* Make LED red, link is down */ - LED_NETWORK_SET(LED_RED); + LED_NETWORK_SET(LED_OFF); } else if (light_leds) { if (current_speed == 10) { @@ -1555,4 +1721,26 @@ return -ENODEV; } +static int __init +e100_boot_setup(char* str) +{ + struct sockaddr sa = {0}; + int i; + + /* Parse the colon separated Ethernet station address */ + for (i = 0; i < ETH_ALEN; i++) { + unsigned int tmp; + if (sscanf(str + 3*i, "%2x", &tmp) != 1) { + printk(KERN_WARNING "Malformed station address"); + return 0; + } + sa.sa_data[i] = (char)tmp; + } + + default_mac = sa; + return 1; +} + +__setup("etrax100_eth=", e100_boot_setup); + module_init(etrax_init_module); diff -urN linux-2.4.21/arch/cris/drivers/examples/kiobuftest.c linux-2.4.22/arch/cris/drivers/examples/kiobuftest.c --- linux-2.4.21/arch/cris/drivers/examples/kiobuftest.c 2001-04-06 10:42:55.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/examples/kiobuftest.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,18 +4,12 @@ * * It is necessary because the pages the virtual pointers reference, might * not exist in memory (could be mapped to the zero-page, filemapped etc) - * and DMA cannot trigger the MMU to force them in (and would have time + * and DMA cannot trigger the MMU to force them in (and would have time * contraints making it impossible to wait for it anyway). * - * Author: Bjorn Wesen - * - * $Log: kiobuftest.c,v $ - * Revision 1.2 2001/02/27 13:52:50 bjornw - * malloc.h -> slab.h - * - * Revision 1.1 2001/01/19 15:57:49 bjornw - * Example of how to do direct HW -> user-mode DMA + * Copyright (c) 2001, 2002, 2003 Axis Communications AB * + * Author: Bjorn Wesen * */ @@ -32,55 +26,55 @@ #define KIOBUFTEST_MAJOR 124 /* in the local range, experimental */ - static ssize_t kiobuf_read(struct file *filp, char *buf, size_t len, loff_t *ppos) { + struct kiobuf *iobuf; + int res, i; - struct kiobuf *iobuf; - int res, i; - - /* Make a kiobuf that maps the entire length the reader has given - * us - */ - - res = alloc_kiovec(1, &iobuf); - if (res) - return res; - - if((res = map_user_kiobuf(READ, iobuf, (unsigned long)buf, len))) { - printk("map_user_kiobuf failed, return %d\n", res); - return res; - } - - /* At this point, the virtual area buf[0] -> buf[len-1] will - * have corresponding pages mapped in physical memory and locked - * until we unmap the kiobuf. They cannot be swapped out or moved - * around. - */ - - printk("nr_pages == %d\noffset == %d\nlength == %d\n", - iobuf->nr_pages, iobuf->offset, iobuf->length); - - for(i = 0; i < iobuf->nr_pages; i++) { - printk("page_add(maplist[%d]) == 0x%x\n", i, - page_address(iobuf->maplist[i])); - } - - /* This is the place to create the necessary scatter-gather vector - * for the DMA using the iobuf->maplist array and page_address - * (don't forget __pa if the DMA needs the actual physical DRAM address) - * and run it. - */ + /* + * Make a kiobuf that maps the entire length the reader has given us. + */ + res = alloc_kiovec(1, &iobuf); + if (res) + return res; + + if ((res = map_user_kiobuf(READ, iobuf, (unsigned long)buf, len))) { + printk("map_user_kiobuf failed, return %d\n", res); + free_kiovec(1, &iobuf); + return res; + } + + /* + * At this point, the virtual area buf[0] -> buf[len-1] will have + * corresponding pages mapped in physical memory and locked until + * we unmap the kiobuf. They cannot be swapped out or moved around. + */ + + printk("nr_pages == %d\noffset == %d\nlength == %d\n", + iobuf->nr_pages, iobuf->offset, iobuf->length); + + for (i = 0; i < iobuf->nr_pages; i++) { + printk("page_add(maplist[%d]) == 0x%x\n", i, + page_address(iobuf->maplist[i])); + } + + /* + * This is the place to create the necessary scatter-gather vector + * for the DMA using the iobuf->maplist array and page_address (don't + * forget __pa if the DMA needs the actual physical DRAM address) + * and run it. + */ - /* Release the mapping and exit */ + /* Release the mapping and exit */ - unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */ + unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */ + free_kiovec(1, &iobuf); - return len; + return len; } @@ -97,7 +91,7 @@ /* register char device */ res = register_chrdev(KIOBUFTEST_MAJOR, "kiobuftest", &kiobuf_fops); - if(res < 0) { + if (res < 0) { printk(KERN_ERR "kiobuftest: couldn't get a major number.\n"); return res; } @@ -105,4 +99,11 @@ printk("Initializing kiobuf-test device\n"); } +static void __exit +kiobuftest_exit(void) +{ + unregister_chrdev(KIOBUFTEST_MAJOR, "kiobuftest"); +} + module_init(kiobuftest_init); +module_exit(kiobuftest_exit); diff -urN linux-2.4.21/arch/cris/drivers/gpio.c linux-2.4.22/arch/cris/drivers/gpio.c --- linux-2.4.21/arch/cris/drivers/gpio.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/gpio.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: gpio.c,v 1.21 2002/12/02 08:11:41 starvik Exp $ +/* $Id: gpio.c,v 1.25 2003/06/24 07:24:31 johana Exp $ * * Etrax general port I/O device * @@ -9,6 +9,22 @@ * Johan Adolfsson (read/set directions, write, port G) * * $Log: gpio.c,v $ + * Revision 1.25 2003/06/24 07:24:31 johana + * Added gpio_pa_irq_enabled_mask to keep track of what interrupts we have + * enabled so we anly clear those that we have enabled and let bits/pins + * used by other drivers alone. + * Update gpio_some_alarms in IO_CLRALARM ioctl(). + * + * Revision 1.24 2003/06/19 08:58:25 johana + * Turn off interrupts while fiddling with genconfig_shadow. + * Put some printk within D() macro. + * + * Revision 1.23 2003/04/01 14:12:06 starvik + * Added loglevel for lots of printks + * + * Revision 1.22 2003/01/09 18:03:47 starvik + * init_ioremap is now called by kernel before device drivers are initialized + * * Revision 1.21 2002/12/02 08:11:41 starvik * Merge of Linux 2.4.20 * @@ -169,6 +185,7 @@ static struct gpio_private *alarmlist = 0; static int gpio_some_alarms = 0; /* Set if someone uses alarm */ +static unsigned long gpio_pa_irq_enabled_mask = 0; /* Port A and B use 8 bit access, but Port G is 32 bit */ #define NUM_PORTS (GPIO_MINOR_B+1) @@ -238,13 +255,19 @@ unsigned long data; poll_wait(file, &priv->alarm_wq, wait); if (priv->minor == GPIO_MINOR_A) { + unsigned long flags; unsigned long tmp; data = *R_PORT_PA_DATA; /* PA has support for high level interrupt - * lets activate for those low and with highalarm set */ tmp = ~data & priv->highalarm & 0xFF; - *R_IRQ_MASK1_SET = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); + tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); + save_flags(flags); cli(); + gpio_pa_irq_enabled_mask |= tmp; + *R_IRQ_MASK1_SET = tmp; + restore_flags(flags); + } else if (priv->minor == GPIO_MINOR_B) data = *R_PORT_PB_DATA; else if (priv->minor == GPIO_MINOR_G) @@ -293,12 +316,15 @@ { unsigned long tmp; /* Find what PA interrupts are active */ - tmp = (*R_IRQ_READ1 >> R_IRQ_READ1__pa0__BITNR) & 0xFF; + tmp = (*R_IRQ_READ1); + + /* Find those that we have enabled */ + tmp &= gpio_pa_irq_enabled_mask; + /* Clear them.. */ - /* NOTE: Maybe we need to be more careful here if some other - * driver uses PA interrupt as well? - */ - *R_IRQ_MASK1_CLR = (tmp << R_IRQ_MASK1_CLR__pa0__BITNR); + *R_IRQ_MASK1_CLR = tmp; + gpio_pa_irq_enabled_mask &= ~tmp; + if (gpio_some_alarms) { etrax_gpio_wake_up_check(); } @@ -437,7 +463,7 @@ p = p->next; } gpio_some_alarms = 0; - + return 0; } @@ -459,6 +485,7 @@ return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ } else if (priv->minor == GPIO_MINOR_G) { /* We must fiddle with R_GEN_CONFIG to change dir */ + save_flags(flags); cli(); if (((arg & dir_g_in_bits) != arg) && (arg & changeable_dir_g)) { arg &= changeable_dir_g; @@ -483,16 +510,17 @@ dir_g_in_bits |= (1<<24); dir_g_out_bits &= ~(1<<24); } - printk("gpio: SETINPUT on port G set " - "genconfig to 0x%08lX " - "in_bits: 0x%08lX " - "out_bits: 0x%08lX\n", - (unsigned long)genconfig_shadow, - dir_g_in_bits, dir_g_out_bits); + D(printk(KERN_INFO "gpio: SETINPUT on port G set " + "genconfig to 0x%08lX " + "in_bits: 0x%08lX " + "out_bits: 0x%08lX\n", + (unsigned long)genconfig_shadow, + dir_g_in_bits, dir_g_out_bits)); *R_GEN_CONFIG = genconfig_shadow; /* Must be a >120 ns delay before writing this again */ } + restore_flags(flags); return dir_g_in_bits; } return 0; @@ -508,7 +536,8 @@ restore_flags(flags); return *priv->dir_shadow; } else if (priv->minor == GPIO_MINOR_G) { - /* We must fiddle with R_GEN_CONFIG to change dir */ + /* We must fiddle with R_GEN_CONFIG to change dir */ + save_flags(flags); cli(); if (((arg & dir_g_out_bits) != arg) && (arg & changeable_dir_g)) { /* Set bits in genconfig to set to output */ @@ -532,15 +561,16 @@ dir_g_out_bits |= (1<<24); dir_g_in_bits &= ~(1<<24); } - printk("gpio: SETOUTPUT on port G set " - "genconfig to 0x%08lX " - "in_bits: 0x%08lX " - "out_bits: 0x%08lX\n", - (unsigned long)genconfig_shadow, - dir_g_in_bits, dir_g_out_bits); + D(printk(KERN_INFO "gpio: SETOUTPUT on port G set " + "genconfig to 0x%08lX " + "in_bits: 0x%08lX " + "out_bits: 0x%08lX\n", + (unsigned long)genconfig_shadow, + dir_g_in_bits, dir_g_out_bits)); *R_GEN_CONFIG = genconfig_shadow; /* Must be a >120 ns delay before writing this again */ } + restore_flags(flags); return dir_g_out_bits & 0x7FFFFFFF; } return 0; @@ -605,6 +635,20 @@ // clear alarm for bits with 1 in arg priv->highalarm &= ~arg; priv->lowalarm &= ~arg; + { + /* Must update gpio_some_alarms */ + struct gpio_private *p = alarmlist; + int some_alarms; + some_alarms = 0; + while (p) { + if (p->highalarm | p->lowalarm) { + some_alarms = 1; + break; + } + p = p->next; + } + gpio_some_alarms = some_alarms; + } break; case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ /* Read direction 0=input 1=output */ @@ -824,9 +868,11 @@ dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g); - printk("GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", + printk(KERN_INFO + "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); - printk("GPIO port G: dir: %08lX changeable: %08lX\n", + printk(KERN_INFO + "GPIO port G: dir: %08lX changeable: %08lX\n", dir_g_shadow, changeable_dir_g); } @@ -835,7 +881,6 @@ static __init int gpio_init(void) { - extern void init_ioremap(void); int res; #if defined (CONFIG_ETRAX_CSP0_LEDS) int i; @@ -850,8 +895,7 @@ } /* Clear all leds */ -#if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS) - init_ioremap(); +#if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS) LED_NETWORK_SET(0); LED_ACTIVE_SET(0); LED_DISK_READ(0); @@ -865,7 +909,8 @@ #endif gpio_init_port_g(); - printk("ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n"); + printk(KERN_INFO + "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n"); /* We call etrax_gpio_wake_up_check() from timer interrupt and * from cpu_idle() in kernel/process.c * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms @@ -873,11 +918,11 @@ */ if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt, SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) { - printk("err: timer0 irq for gpio\n"); + printk(KERN_CRIT "err: timer0 irq for gpio\n"); } if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt, SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) { - printk("err: PA irq for gpio\n"); + printk(KERN_CRIT "err: PA irq for gpio\n"); } return res; diff -urN linux-2.4.21/arch/cris/drivers/i2c.c linux-2.4.22/arch/cris/drivers/i2c.c --- linux-2.4.21/arch/cris/drivers/i2c.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/i2c.c 2003-08-25 04:44:39.000000000 -0700 @@ -11,7 +11,26 @@ *! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff - *! don't use PB_I2C if DS1302 uses same bits, *! use PB. +*| June 23 2003 Pieter Grimmerink Added 'i2c_sendnack'. i2c_readreg now +*| generates nack on last received byte, +*| instead of ack. +*| i2c_getack changed data level while clock +*| was high, causing DS75 to see a stop condition +*| *! $Log: i2c.c,v $ +*! Revision 1.12 2003/06/23 14:43:47 oskarp +*! * i2c_sendnack is added. +*! - i2c_readreg now generates nack on last received byte, instead of ack. +*! i2c_getack changed data level while clock was high, causing DS75 to +*! see a stop condition. +*! +*! Revision 1.11 2003/05/23 09:37:23 oskarp +*! * Made i2c_init() visible. +*! - e.g. pcf856.c uses i2c_init(). +*! +*! Revision 1.10 2003/04/01 14:12:06 starvik +*! Added loglevel for lots of printks +*! *! Revision 1.9 2002/10/31 15:32:26 starvik *! Update Port B register and shadow even when running with hardware support *! to avoid glitches when reading bits @@ -53,7 +72,7 @@ *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN *! *!***************************************************************************/ -/* $Id: i2c.c,v 1.9 2002/10/31 15:32:26 starvik Exp $ */ +/* $Id: i2c.c,v 1.12 2003/06/23 14:43:47 oskarp Exp $ */ /****************** INCLUDE FILES SECTION ***********************************/ #include @@ -133,7 +152,7 @@ #define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT) -#else +#else /* !CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C */ /* enable or disable the i2c interface */ #define i2c_enable() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_en)) @@ -163,7 +182,8 @@ /* read a bit from the i2c interface */ #define i2c_getbit() (*R_PORT_PB_READ & 0x1) -#endif + +#endif /* CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C */ /* use the kernels delay routine */ @@ -299,6 +319,12 @@ } i2c_clk(I2C_CLOCK_HIGH); i2c_delay(CLOCK_HIGH_TIME); + + /* + * we leave the clock low, getbyte is usually followed + * by sendack/nack, they assume the clock to be low + */ + i2c_clk(I2C_CLOCK_LOW); return aBitByte; } @@ -360,6 +386,13 @@ i2c_delay(CLOCK_HIGH_TIME/2); } + /* + * our clock is high now, make sure data is low + * before we enable our output. If we keep data high + * and enable output, we would generate a stop condition. + */ + i2c_data(I2C_DATA_LOW); + /* * end clock pulse */ @@ -417,6 +450,37 @@ /*#--------------------------------------------------------------------------- *# +*# FUNCTION NAME: i2c_sendnack +*# +*# DESCRIPTION : Sends NACK on received data +*# +*#--------------------------------------------------------------------------*/ +void +i2c_sendnack(void) +{ + /* + * enable output + */ + i2c_delay(CLOCK_LOW_TIME); + i2c_dir_out(); + /* + * set data high + */ + i2c_data(I2C_DATA_HIGH); + /* + * generate clock pulse + */ + i2c_delay(CLOCK_HIGH_TIME/6); + i2c_clk(I2C_CLOCK_HIGH); + i2c_delay(CLOCK_HIGH_TIME); + i2c_clk(I2C_CLOCK_LOW); + i2c_delay(CLOCK_LOW_TIME); + + i2c_dir_in(); +} + +/*#--------------------------------------------------------------------------- +*# *# FUNCTION NAME: i2c_writereg *# *# DESCRIPTION : Writes a value to an I2C device @@ -546,9 +610,10 @@ */ b = i2c_inbyte(); /* - * send Ack + * last received byte needs to be nacked + * instead of acked */ - i2c_sendack(); + i2c_sendnack(); /* * end sequence */ @@ -623,7 +688,7 @@ release: i2c_release, }; -static int __init +int __init i2c_init(void) { int res; @@ -653,7 +718,7 @@ return res; } - printk("I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); + printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); return 0; } diff -urN linux-2.4.21/arch/cris/drivers/i2c.h linux-2.4.22/arch/cris/drivers/i2c.h --- linux-2.4.21/arch/cris/drivers/i2c.h 2001-05-19 17:43:05.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/i2c.h 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,8 @@ -/* $Id: i2c.h,v 1.3 2001/03/19 12:43:01 markusl Exp $ */ + +#include /* High level I2C actions */ +int __init i2c_init(void); int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg); @@ -11,6 +13,3 @@ unsigned char i2c_inbyte(void); int i2c_getack(void); void i2c_sendack(void); - - - diff -urN linux-2.4.21/arch/cris/drivers/ide.c linux-2.4.22/arch/cris/drivers/ide.c --- linux-2.4.21/arch/cris/drivers/ide.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/ide.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: ide.c,v 1.26 2002/09/17 12:16:59 bjornw Exp $ +/* $Id: ide.c,v 1.30 2003/07/08 07:24:47 pkj Exp $ * * Etrax specific IDE functions, like init and PIO-mode setting etc. * Almost the entire ide.c is used for the rest of the Etrax ATA driver. @@ -8,6 +8,19 @@ * Mikael Starvik (pio setup stuff) * * $Log: ide.c,v $ + * Revision 1.30 2003/07/08 07:24:47 pkj + * Corrected spelling mistakes originally found in 2.5.x + * + * Revision 1.29 2003/06/17 13:57:49 starvik + * Merge of Linux 2.4.21 + * + * Revision 1.28 2003/01/22 12:41:12 starvik + * Added LBA48 support + * Fixed typo in e100_ideproc + * + * Revision 1.27 2003/01/09 18:03:47 starvik + * init_ioremap is now called by kernel before device drivers are initialized + * * Revision 1.26 2002/09/17 12:16:59 bjornw * Removed unnecessary cli/sti pair * @@ -151,6 +164,8 @@ static volatile unsigned long *reset_addr; #endif +static int e100_read_command = 0; + #define LOWDB(x) #define D(x) @@ -186,14 +201,9 @@ IO_MASK(R_ATA_STATUS_DATA, tr_rdy))) timeleft--; } -unsigned char -IN_BYTE(ide_ioreg_t reg) { - /* data was in the lower 16 bits in the status reg */ - return (unsigned char)(IN_WORD(reg)); -} unsigned short -IN_WORD(ide_ioreg_t reg) { +IN_BYTE(ide_ioreg_t reg) { int status; int timeleft; @@ -237,7 +247,7 @@ LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg)); - return (unsigned short)status; + return (unsigned char)status; } /* PIO timing (in R_ATA_CONFIG) @@ -292,9 +302,15 @@ #define ATA_PIO0_STROBE 19 #define ATA_PIO0_HOLD 4 -static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive); -static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive, - void *buffer, unsigned int length); +static int e100_dma_check (ide_drive_t *drive); +static int e100_dma_begin (ide_drive_t *drive); +static int e100_dma_end (ide_drive_t *drive); +static int e100_dma_read (ide_drive_t *drive); +static int e100_dma_write (ide_drive_t *drive); +static void e100_ide_input_data (ide_drive_t *drive, void *, unsigned int); +static void e100_ide_output_data (ide_drive_t *drive, void *, unsigned int); +static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); +static void e100_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); /* * good_dma_drives() lists the model names (from "hdparm -i") @@ -309,8 +325,6 @@ static void tune_e100_ide(ide_drive_t *drive, byte pio) { - unsigned long flags; - pio = 4; /* pio = ide_get_best_pio_mode(drive, pio, 4, NULL); */ @@ -374,8 +388,15 @@ ide_hwif_t *hwif = &ide_hwifs[h]; hwif->chipset = ide_etrax100; hwif->tuneproc = &tune_e100_ide; - hwif->dmaproc = &e100_dmaproc; - hwif->ideproc = &e100_ideproc; + hwif->ata_input_data = &e100_ide_input_data; + hwif->ata_output_data = &e100_ide_output_data; + hwif->atapi_input_bytes = &e100_atapi_input_bytes; + hwif->atapi_output_bytes = &e100_atapi_output_bytes; + hwif->ide_dma_check = &e100_dma_check; + hwif->ide_dma_end = &e100_dma_end; + hwif->ide_dma_write = &e100_dma_write; + hwif->ide_dma_read = &e100_dma_read; + hwif->ide_dma_begin = &e100_dma_begin; } /* actually reset and configure the etrax100 ide/ata interface */ @@ -400,11 +421,9 @@ REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 0); #endif #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET - init_ioremap(); REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 0); #endif #ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET - init_ioremap(); REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 0); #endif #ifdef CONFIG_ETRAX_IDE_PB7_RESET @@ -618,7 +637,7 @@ LED_DISK_WRITE(1); /* Etrax will set busy = 1 until the multi pio transfer has finished - * and tr_rdy = 1 after each succesful word transfer. + * and tr_rdy = 1 after each successful word transfer. * When the last byte has been transferred Etrax will first set tr_tdy = 1 * and then busy = 0 (not in the same cycle). If we read busy before it * has been set to 0 we will think that we should transfer more bytes @@ -655,32 +674,6 @@ e100_atapi_output_bytes(drive, buffer, wcount << 2); } -/* - * The multiplexor for ide_xxxput_data and atapi calls - */ -static void -e100_ideproc (ide_ide_action_t func, ide_drive_t *drive, - void *buffer, unsigned int length) -{ - switch (func) { - case ideproc_ide_input_data: - e100_ide_input_data(drive, buffer, length); - break; - case ideproc_ide_output_data: - e100_ide_input_data(drive, buffer, length); - break; - case ideproc_atapi_input_bytes: - e100_atapi_input_bytes(drive, buffer, length); - break; - case ideproc_atapi_output_bytes: - e100_atapi_output_bytes(drive, buffer, length); - break; - default: - printk("e100_ideproc: unsupported func %d!\n", func); - break; - } -} - /* we only have one DMA channel on the chip for ATA, so we can keep these statically */ static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS]; static unsigned int ata_tot_size; @@ -815,8 +808,8 @@ LED_DISK_READ(0); LED_DISK_WRITE(0); - dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive); - stat = GET_STAT(); /* get drive status */ + dma_stat = HWIF(drive)->ide_dma_end(drive); + stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */ if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { if (!dma_stat) { struct request *rq; @@ -833,7 +826,7 @@ } /* - * e100_dmaproc() initiates/aborts DMA read/write operations on a drive. + * Functions below initiates/aborts DMA read/write operations on a drive. * * The caller is assumed to have selected the drive and programmed the drive's * sector address using CHS or LBA. All that remains is to prepare for DMA @@ -848,59 +841,19 @@ * the caller should revert to PIO for the current request. */ -static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive) +static int e100_dma_check(ide_drive_t *drive) { - static unsigned int reading; /* static to support ide_dma_begin semantics */ - int atapi = 0; - - D(printk("e100_dmaproc func %d\n", func)); - - switch (func) { - case ide_dma_verbose: - return 0; - case ide_dma_check: - return config_drive_for_dma (drive); - case ide_dma_off: - case ide_dma_off_quietly: - /* ok.. we don't really need to do anything I think. */ - return 0; - case ide_dma_write: - reading = 0; - break; - case ide_dma_read: - reading = 1; - break; - case ide_dma_begin: - /* begin DMA, used by ATAPI devices which want to issue the - * appropriate IDE command themselves. - * - * they have already called ide_dma_read/write to set the - * static reading flag, now they call ide_dma_begin to do - * the real stuff. we tell our code below not to issue - * any IDE commands itself and jump into it. - */ - atapi++; - goto dma_begin; - case ide_dma_end: /* returns 1 on error, 0 otherwise */ - /* TODO: check if something went wrong with the DMA */ - return 0; - - default: - printk("e100_dmaproc: unsupported func %d\n", func); - return 1; - } - - /* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction - * then they call ide_dma_begin after they have issued the appropriate drive command - * themselves to actually start the chipset DMA. so we just return here if we're - * not a diskdrive. - */ - - if (drive->media != ide_disk) - return 0; + return config_drive_for_dma (drive); +} - dma_begin: +static int e100_dma_end(ide_drive_t *drive) +{ + /* TODO: check if something went wrong with the DMA */ + return 0; +} +static int e100_start_dma(ide_drive_t *drive, int atapi, int reading) +{ if(reading) { RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */ @@ -917,8 +870,15 @@ ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ - - OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG); + 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(WIN_READDMA_EXT, IDE_COMMAND_REG); + } else { + OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG); + } } /* begin DMA */ @@ -968,8 +928,15 @@ ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ - - OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG); + 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(WIN_WRITEDMA_EXT, IDE_COMMAND_REG); + } else { + OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG); + } } /* begin DMA */ @@ -994,14 +961,44 @@ D(printk("dma write of %d bytes.\n", ata_tot_size)); } - - /* DMA started successfully */ return 0; } -/* ide.c calls this, but we don't need to do anything particular */ +static int e100_dma_write(ide_drive_t *drive) +{ + e100_read_command = 0; + /* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction + * then they call ide_dma_begin after they have issued the appropriate drive command + * themselves to actually start the chipset DMA. so we just return here if we're + * not a diskdrive. + */ + if (drive->media != ide_disk) + return 0; + return e100_start_dma(drive, 0, 0); +} + +static int e100_dma_read(ide_drive_t *drive) +{ + e100_read_command = 1; + /* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction + * then they call ide_dma_begin after they have issued the appropriate drive command + * themselves to actually start the chipset DMA. so we just return here if we're + * not a diskdrive. + */ + if (drive->media != ide_disk) + return 0; + return e100_start_dma(drive, 0, 1); +} -int ide_release_dma (ide_hwif_t *hwif) +static int e100_dma_begin(ide_drive_t *drive) { - return 1; + /* begin DMA, used by ATAPI devices which want to issue the + * appropriate IDE command themselves. + * + * they have already called ide_dma_read/write to set the + * static reading flag, now they call ide_dma_begin to do + * the real stuff. we tell our code below not to issue + * any IDE commands itself and jump into it. + */ + return e100_start_dma(drive, 1, e100_read_command); } diff -urN linux-2.4.21/arch/cris/drivers/lpslave/bintocarr.pl linux-2.4.22/arch/cris/drivers/lpslave/bintocarr.pl --- linux-2.4.21/arch/cris/drivers/lpslave/bintocarr.pl 2001-10-08 11:43:54.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/lpslave/bintocarr.pl 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# $Id: bintocarr.pl,v 1.4 2001/08/08 08:18:13 bjarne Exp $ + # Copy of mkjulbin.pl made by Olof # convert a binary stdin to a C-file containing a char array of the input # first argument is the symbol name @@ -27,4 +27,3 @@ $lensymb = ("_" . ($symbol . "_length")); print "__asm__(\"\\t.globl $lensymb\\n$lensymb = $bcount\\n\");\n"; - diff -urN linux-2.4.21/arch/cris/drivers/lpslave/e100lpslave.S linux-2.4.22/arch/cris/drivers/lpslave/e100lpslave.S --- linux-2.4.21/arch/cris/drivers/lpslave/e100lpslave.S 2001-07-26 15:10:06.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/lpslave/e100lpslave.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,12 +1,11 @@ - ;; $Id: e100lpslave.S,v 1.3 2001/06/21 16:55:26 olof Exp $ - ;; - ;; Etrax100 slave network<->parport forwarder - ;; - ;; Copyright (c) 1999 Bjorn Wesen, Axis Communications AB - ;; - ;; We got 784 bytes (par loader size) to do DMA forwarding - ;; between DMA0/1 (ethernet) and DMA3/4 (par port 0 RX/1 TX) - ;; +;; +;; Etrax100 slave network<->parport forwarder +;; +;; Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB +;; +;; We got 784 bytes (par loader size) to do DMA forwarding +;; between DMA0/1 (ethernet) and DMA3/4 (par port 0 RX/1 TX) +;; #include #if 0 diff -urN linux-2.4.21/arch/cris/drivers/parport.c linux-2.4.22/arch/cris/drivers/parport.c --- linux-2.4.21/arch/cris/drivers/parport.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/parport.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,13 +1,13 @@ -/* $Id: parport.c,v 1.10 2002/10/03 05:54:24 starvik Exp $ - * - * Elinux parallel port driver +/* + * Parallel port driver for ETRAX. + * * NOTE! * Since par0 shares DMA with ser2 and par 1 shares DMA with ser3 * this should be handled if both are enabled at the same time. * THIS IS NOT HANDLED YET! * - * Copyright (c) 2001 Axis Communications AB - * + * Copyright (c) 2001, 2002, 2003 Axis Communications AB + * * Author: Fredrik Hugosson * */ @@ -406,7 +406,7 @@ static void __init parport_etrax_show_parallel_version(void) { - printk("ETRAX 100LX parallel port driver v1.0, (c) 2001 Axis Communications AB\n"); + printk("ETRAX 100LX parallel port driver v1.0, (c) 2001-2003 Axis Communications AB\n"); } #ifdef CONFIG_ETRAX_PAR0_DMA diff -urN linux-2.4.21/arch/cris/drivers/pcf8563.c linux-2.4.22/arch/cris/drivers/pcf8563.c --- linux-2.4.21/arch/cris/drivers/pcf8563.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/pcf8563.c 2003-08-25 04:44:39.000000000 -0700 @@ -8,14 +8,13 @@ * low detector are also provided. All address and data are transferred * serially via two-line bidirectional I2C-bus. Maximum bus speed is * 400 kbits/s. The built-in word address register is incremented - * automatically after each written or read bute. + * automatically after each written or read byte. * - * Copyright (c) 2002, Axis Communications AB + * Copyright (c) 2002-2003, Axis Communications AB * All rights reserved. * * Author: Tobias Anderberg . * - * $Id: pcf8563.c,v 1.4 2002/10/15 09:22:42 tobiasa Exp $ */ #include @@ -36,19 +35,15 @@ #include #include "i2c.h" -#define PCF8563_MAJOR 121 /* Local major number. */ -#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ -#define PCF8563_NAME "PCF8563" -#define DRIVER_VERSION "$Revision: 1.4 $" - -/* I2C bus slave registers. */ -#define RTC_I2C_READ 0xa3 -#define RTC_I2C_WRITE 0xa2 +#define PCF8563_MAJOR 121 /* Local major number. */ +#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ +#define PCF8563_NAME "PCF8563" +#define DRIVER_VERSION "$Revision: 1.15 $" /* Two simple wrapper macros, saves a few keystrokes. */ #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) - + static const unsigned char days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; @@ -64,53 +59,73 @@ }; unsigned char -pcf8563_readreg(int reg) +pcf8563_readreg(int reg) { - unsigned char res = i2c_readreg(RTC_I2C_READ, reg); + unsigned char res = rtc_read(reg); /* The PCF8563 does not return 0 for unimplemented bits */ - switch(reg) - { + switch (reg) { case RTC_SECONDS: case RTC_MINUTES: - res &= 0x7f; - break; + res &= 0x7F; + break; case RTC_HOURS: case RTC_DAY_OF_MONTH: - res &= 0x3f; - break; + res &= 0x3F; + break; + case RTC_WEEKDAY: + res &= 0x07; + break; case RTC_MONTH: - res = (res & 0x1f) - 1; /* PCF8563 returns month in range 1-12 */ - break; + res &= 0x1F; + break; + case RTC_CONTROL1: + res &= 0xA8; + break; + case RTC_CONTROL2: + res &= 0x1F; + break; + case RTC_CLOCKOUT_FREQ: + case RTC_TIMER_CONTROL: + res &= 0x83; + break; } return res; } void -pcf8563_writereg(int reg, unsigned char val) +pcf8563_writereg(int reg, unsigned char val) { - i2c_writereg(RTC_I2C_WRITE,reg,val); +#ifdef CONFIG_ETRAX_RTC_READONLY + if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR)) + return; +#endif + + rtc_write(reg, val); } void get_rtc_time(struct rtc_time *tm) { - tm->tm_sec = rtc_read(RTC_SECONDS); - tm->tm_min = rtc_read(RTC_MINUTES); + tm->tm_sec = rtc_read(RTC_SECONDS); + tm->tm_min = rtc_read(RTC_MINUTES); tm->tm_hour = rtc_read(RTC_HOURS); tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH); - tm->tm_mon = rtc_read(RTC_MONTH); + tm->tm_wday = rtc_read(RTC_WEEKDAY); + tm->tm_mon = rtc_read(RTC_MONTH); tm->tm_year = rtc_read(RTC_YEAR); if (tm->tm_sec & 0x80) - printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME); + printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " + "information is no longer guaranteed!\n", PCF8563_NAME); - tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0); - tm->tm_sec &= 0x7f; - tm->tm_min &= 0x7f; - tm->tm_hour &= 0x3f; - tm->tm_mday &= 0x3f; - tm->tm_mon &= 0x1f; + tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0); + tm->tm_sec &= 0x7F; + tm->tm_min &= 0x7F; + tm->tm_hour &= 0x3F; + tm->tm_mday &= 0x3F; + tm->tm_wday &= 0x07; /* Not coded in BCD. */ + tm->tm_mon &= 0x1F; BCD_TO_BIN(tm->tm_sec); BCD_TO_BIN(tm->tm_min); @@ -124,10 +139,14 @@ pcf8563_init(void) { unsigned char ret; + + /* Initiate the i2c protocol. */ + i2c_init(); + /* * First of all we need to reset the chip. This is done by - * clearing control1, control2 and clk freq, clear the - * Voltage Low bit, and resetting all alarms. + * clearing control1, control2 and clk freq and resetting + * all alarms. */ if (rtc_write(RTC_CONTROL1, 0x00) < 0) goto err; @@ -138,37 +157,35 @@ if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0) goto err; - /* Clear the VL bit in the seconds register. */ - ret = rtc_read(RTC_SECONDS); - - if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0) + if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0) goto err; - + /* Reset the alarms. */ - if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0) + if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0) goto err; - - if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0) + + if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0) goto err; - - if (rtc_write(RTC_DAY_ALARM, 0x00) < 0) + + if (rtc_write(RTC_DAY_ALARM, 0x80) < 0) goto err; - - if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0) + + if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) goto err; if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { - printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", + printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", PCF8563_NAME, PCF8563_MAJOR); return -1; } printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); - + /* Check for low voltage, and warn about it.. */ if (rtc_read(RTC_SECONDS) & 0x80) - printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME); - + printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " + "information is no longer guaranteed!\n", PCF8563_NAME); + return 0; err: @@ -200,75 +217,113 @@ switch (cmd) { case RTC_RD_TIME: - { - struct rtc_time tm; + { + struct rtc_time tm; - get_rtc_time(&tm); + get_rtc_time(&tm); - if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { - return -EFAULT; - } - - return 0; + if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) { + return -EFAULT; } - break; - case RTC_SET_TIME: - { - int leap; - int century; - unsigned long flags; - struct rtc_time tm; - - if (!capable(CAP_SYS_TIME)) - return -EPERM; - - if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time))) - return -EFAULT; - - /* Convert from struct tm to struct rtc_time. */ - tm.tm_year += 1900; - tm.tm_mon += 1; - - leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0; - - /* Perform some sanity checks. */ - if ((tm.tm_year < 1970) || - (tm.tm_mon > 12) || - (tm.tm_mday == 0) || - (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || - (tm.tm_hour >= 24) || - (tm.tm_min >= 60) || - (tm.tm_sec >= 60)) - return -EINVAL; - - century = (tm.tm_year >= 2000) ? 0x80 : 0; - tm.tm_year = tm.tm_year % 100; - - BIN_TO_BCD(tm.tm_year); - BIN_TO_BCD(tm.tm_mday); - BIN_TO_BCD(tm.tm_hour); - BIN_TO_BCD(tm.tm_min); - BIN_TO_BCD(tm.tm_sec); - tm.tm_mon |= century; - - rtc_write(RTC_YEAR, tm.tm_year); - rtc_write(RTC_MONTH, tm.tm_mon); - rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); - rtc_write(RTC_HOURS, tm.tm_hour); - rtc_write(RTC_MINUTES, tm.tm_min); - rtc_write(RTC_SECONDS, tm.tm_sec); - return 0; + return 0; + } + + case RTC_SET_TIME: + { +#ifdef CONFIG_ETRAX_RTC_READONLY + return -EPERM; +#else + int leap; + int year; + int century; + struct rtc_time tm; + + if (!capable(CAP_SYS_TIME)) + return -EPERM; + + if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm)) + return -EFAULT; + + /* Convert from struct tm to struct rtc_time. */ + tm.tm_year += 1900; + tm.tm_mon += 1; + + /* + * Check if tm.tm_year is a leap year. A year is a leap + * year if it is divisible by 4 but not 100, except + * that years divisible by 400 _are_ leap years. + */ + year = tm.tm_year; + leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); + + /* Perform some sanity checks. */ + if ((tm.tm_year < 1970) || + (tm.tm_mon > 12) || + (tm.tm_mday == 0) || + (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || + (tm.tm_wday >= 7) || + (tm.tm_hour >= 24) || + (tm.tm_min >= 60) || + (tm.tm_sec >= 60)) + return -EINVAL; + + century = (tm.tm_year >= 2000) ? 0x80 : 0; + tm.tm_year = tm.tm_year % 100; + + BIN_TO_BCD(tm.tm_year); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_sec); + tm.tm_mon |= century; + + rtc_write(RTC_YEAR, tm.tm_year); + rtc_write(RTC_MONTH, tm.tm_mon); + rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */ + rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); + rtc_write(RTC_HOURS, tm.tm_hour); + rtc_write(RTC_MINUTES, tm.tm_min); + rtc_write(RTC_SECONDS, tm.tm_sec); + + return 0; +#endif /* !CONFIG_ETRAX_RTC_READONLY */ + } + + case RTC_VLOW_RD: + { + int vl_bit = 0; + + if (rtc_read(RTC_SECONDS) & 0x80) { + vl_bit = 1; + printk(KERN_WARNING "%s: RTC Voltage Low - reliable " + "date/time information is no longer guaranteed!\n", + PCF8563_NAME); } - break; + if (copy_to_user((int *) arg, &vl_bit, sizeof(int))) + return -EFAULT; + + return 0; + } + + case RTC_VLOW_SET: + { + /* Clear the VL bit in the seconds register */ + int ret = rtc_read(RTC_SECONDS); + + rtc_write(RTC_SECONDS, (ret & 0x7F)); + + return 0; + } + default: - return -ENOTTY; + return -ENOTTY; } return 0; } -int +int pcf8563_open(struct inode *inode, struct file *filp) { MOD_INC_USE_COUNT; diff -urN linux-2.4.21/arch/cris/drivers/serial.c linux-2.4.22/arch/cris/drivers/serial.c --- linux-2.4.21/arch/cris/drivers/serial.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/serial.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,12 +1,92 @@ -/* $Id: serial.c,v 1.44 2002/11/21 04:28:06 hp Exp $ +/* $Id: serial.c,v 1.54 2003/07/08 12:42:19 johana Exp $ * * Serial port driver for the ETRAX 100LX chip * - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Axis Communications AB + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Axis Communications AB * - * Many, many authors. Based once upon a time on serial.c for 16x50. + * Many, many authors. Based once upon a time on serial.c for 16x50. * * $Log: serial.c,v $ + * Revision 1.54 2003/07/08 12:42:19 johana + * Removed some test defines within #if 0. + * Moved a comment to correct place. + * + * Revision 1.53 2003/07/08 09:48:28 starvik + * Removed test code + * + * Revision 1.52 2003/07/08 07:24:47 pkj + * Corrected spelling mistakes originally found in 2.5.x + * + * Revision 1.51 2003/07/07 09:17:12 johana + * Config.in: + * Don't consider ETRAX_FAST_TIMER experimental. + * Add CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED + * Add CONFIG_ETRAX_EXTERN_PB6CLK_FREQ + * Add CONFIG_ETRAX_SERIAL_PORTx_DMAy_OUT/IN + * + * serial.h: + * Support for with and without DMA. + * Added baud_base and custom_divisor for flexible baudrate. + * Added flush_time_usec. + * Removed unused DMA register pointers. + * + * serial.c: + * Use C99 style initialisation of rs_table, some fields added, some removed. + * Always disable interrupts when fiddling with shadow variables. + * Support for flexible baudrate using prescaler or external clock. + * Only disable the DMA channel if we own it. + * Support for either using DMA or char-by-char interrupt. + * + * DMA changes: + * o When transmitting with DMA, don't put all in one descriptor, split + * it so that we can wake up the application before everything is sent. + * o When starting a fast timer to flip later, use a longer, fixed time. + * o Use flush_time_usec and have a minimum value to prevent excessive load + * on high baudrates. + * o Do force_eop_if_needed() after processing to reduce load. + * o All DMA interrupts uses SA_SHIRQ | SA_INTERRUPT + * + * Only have interrupts disabled while processing rx interrupts, + * unmask just tx interrupts and unblock serial interrupt and keep + * global interrupts enabled while processing tx interrupts to make + * char-by-char interrupts usable. + * + * Flow control: + * o Use normal tx interrupt when sending x_char. + * o Use throttling within the driver when using DMA. + * + * Improved debugging with DEBUG_LOG macro. + * + * Revision 1.50 2003/06/13 10:04:12 johana + * Help the user to avoid trouble by: + * Preventing FAST_TIMER and FAST_DMA_FLUSH at the same time. + * Forcing mixed mode for status/control lines if not all pins are used. + * + * Som minor changes to reduce diff to os/lx25 version. + * + * Revision 1.49 2003/05/30 11:31:54 johana + * Merged in change-branch--serial9bit that adds CMSPAR support for sticky + * parity (mark/space) + * + * Revision 1.48 2003/05/30 11:03:57 johana + * Implemented rs_send_xchar() by disabling the DMA and writing manually. + * Added e100_disable_txdma_channel() and e100_enable_txdma_channel(). + * Fixed rs_throttle() and rs_unthrottle() to properly call rs_send_xchar + * instead of setting info->x_char and check the CRTSCTS flag before + * controlling the rts pin. + * + * Revision 1.47 2003/04/09 08:31:14 pkj + * Typo correction (taken from Linux 2.5). + * + * Revision 1.46 2003/04/01 14:12:06 starvik + * Added loglevel for lots of printks + * + * Revision 1.45 2003/01/22 06:54:46 starvik + * Fixed warnings issued by GCC 3.2.1 + * + * Revision 1.44.4.1 2003/01/08 06:47:12 starvik + * Added mark/space parity (for 9-bit serial) + * * Revision 1.44 2002/11/21 04:28:06 hp * Change static inline to extern inline where otherwise outlined with gcc-3.2 * @@ -206,7 +286,7 @@ * Items worth noticing: * * No Etrax100 port 1 workarounds (does only compile on 2.4 anyway now) - * RS485 is not ported (why cant it be done in userspace as on x86 ?) + * RS485 is not ported (why can't it be done in userspace as on x86 ?) * Statistics done through async_icount - if any more stats are needed, * that's the place to put them or in an arch-dep version of it. * timeout_interrupt and the other fast timeout stuff not ported yet @@ -357,7 +437,7 @@ * */ -static char *serial_version = "$Revision: 1.44 $"; +static char *serial_version = "$Revision: 1.54 $"; #include #include @@ -392,7 +472,7 @@ #include -/* non-arch dependant serial structures are in linux/serial.h */ +/* non-arch dependent serial structures are in linux/serial.h */ #include /* while we keep our own stuff (struct e100_serial) in a local .h file */ #include "serial.h" @@ -406,6 +486,11 @@ #error "Enable FAST_TIMER to use SERIAL_FAST_TIMER" #endif #endif + +#if defined(CONFIG_ETRAX_FAST_TIMER) && defined(CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST) +#error "Disable either ETRAX_SERIAL_FLUSH_DMA_FAST or ETRAX_FAST_TIMER" +#endif + /* * All of the compatibilty code so we can compile serial.c against * older kernels is hidden in serial_compat.h @@ -414,8 +499,11 @@ #include "serial_compat.h" #endif +#if 1 /* Set to 0 to avoid inlining - easier to see how size of parts */ #define _INLINE_ inline - +#else +#define _INLINE_ +#endif static DECLARE_TASK_QUEUE(tq_serial); struct tty_driver serial_driver, callout_driver; @@ -436,7 +524,7 @@ //#define SERIAL_DEBUG_DATA //#define SERIAL_DEBUG_THROTTLE //#define SERIAL_DEBUG_IO /* Debug for Extra control and status pins */ -#define SERIAL_DEBUG_LINE 0 /* What serport we want to debug */ +#define SERIAL_DEBUG_LINE 3 /* What serport we want to debug */ /* Enable this to use serial interrupts to handle when you expect the first received event on the serial port to @@ -444,14 +532,78 @@ from eLinux */ #define SERIAL_HANDLE_EARLY_ERRORS -#define TTY_THROTTLE_LIMIT (TTY_FLIPBUF_SIZE/10) +/* Defined and used in n_tty.c, but we need it here as well */ +#define TTY_THRESHOLD_THROTTLE 128 +/* Due to buffersizes and threshold values, our SERIAL_DESCR_BUF_SIZE + * must not be to high or flow control won't work if we leave it to the tty + * layer so we have our own throttling in flush_to_flip + * TTY_FLIPBUF_SIZE=512, + * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128 + * BUF_SIZE can't be > 128 + */ +/* Currently 16 descriptors x 128 bytes = 2048 bytes */ #define SERIAL_DESCR_BUF_SIZE 256 +#define SERIAL_PRESCALE_BASE 3125000 /* 3.125MHz */ +#define DEF_BAUD_BASE SERIAL_PRESCALE_BASE + +/* We don't want to load the system with massive fast timer interrupt + * on high baudrates so limit it to 250 us (4kHz) */ +#define MIN_FLUSH_TIME_USEC 250 + /* Add an x here to log a lot of timer stuff */ #define TIMERD(x) +/* Debug details of interrupt handling */ +#define DINTR1(x) /* irq on/off, errors */ +#define DINTR2(x) /* tx and rx */ +/* Debug flip buffer stuff */ +#define DFLIP(x) +/* Debug flow control and overview of data flow */ +#define DFLOW(x) +#define DBAUD(x) +#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT +#define DLOG_INT_TRIG(x) +#else +#define DLOG_INT_TRIG(x) +#endif +//#define DEBUG_LOG_INCLUDED +#ifndef DEBUG_LOG_INCLUDED #define DEBUG_LOG(line, string, value) +#else +struct debug_log_info +{ + unsigned long time; + unsigned long timer_data; +// int line; + const char *string; + int value; +}; +#define DEBUG_LOG_SIZE 4096 + +struct debug_log_info debug_log[DEBUG_LOG_SIZE]; +int debug_log_pos = 0; + +#define DEBUG_LOG(_line, _string, _value) do { \ + if ((_line) == SERIAL_DEBUG_LINE) {\ + debug_log_func(_line, _string, _value); \ + }\ +}while(0) + +void debug_log_func(int line, const char *string, int value) +{ + if (debug_log_pos < DEBUG_LOG_SIZE) { + debug_log[debug_log_pos].time = jiffies; + debug_log[debug_log_pos].timer_data = *R_TIMER_DATA; +// debug_log[debug_log_pos].line = line; + debug_log[debug_log_pos].string = string; + debug_log[debug_log_pos].value = value; + debug_log_pos++; + } + /*printk(string, value);*/ +} +#endif #ifndef CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS /* Default number of timer ticks before flushing rx fifo @@ -461,21 +613,23 @@ #define CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5 #endif +unsigned long timer_data_to_ns(unsigned long timer_data); + static void change_speed(struct e100_serial *info); +static void rs_throttle(struct tty_struct * tty); static void rs_wait_until_sent(struct tty_struct *tty, int timeout); static int rs_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count); -extern inline int raw_write(struct tty_struct * tty, int from_user, +extern _INLINE_ int rs_raw_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count); #ifdef CONFIG_ETRAX_RS485 static int e100_write_rs485(struct tty_struct * tty, int from_user, const unsigned char *buf, int count); #endif -static int -get_lsr_info(struct e100_serial * info, unsigned int *value); +static int get_lsr_info(struct e100_serial * info, unsigned int *value); -#define DEF_BAUD 0x99 /* 115.2 kbit/s */ +#define DEF_BAUD 115200 /* 115.2 kbit/s */ #define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) #define DEF_RX 0x20 /* or SERIAL_CTRL_W >> 8 */ /* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */ @@ -484,6 +638,7 @@ /* offsets from R_SERIALx_CTRL */ #define REG_DATA 0 +#define REG_DATA_STATUS32 0 /* this is the 32 bit register R_SERIALx_READ */ #define REG_TR_DATA 0 #define REG_STATUS 1 #define REG_TR_CTRL 1 @@ -519,60 +674,162 @@ */ +/* Mask for the irqs possibly enabled in R_IRQ_MASK1_RD etc. */ +static const unsigned long e100_ser_int_mask = 0 +#ifdef CONFIG_ETRAX_SERIAL_PORT0 +| IO_MASK(R_IRQ_MASK1_RD, ser0_data) | IO_MASK(R_IRQ_MASK1_RD, ser0_ready) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT1 +| IO_MASK(R_IRQ_MASK1_RD, ser1_data) | IO_MASK(R_IRQ_MASK1_RD, ser1_ready) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2 +| IO_MASK(R_IRQ_MASK1_RD, ser2_data) | IO_MASK(R_IRQ_MASK1_RD, ser2_ready) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3 +| IO_MASK(R_IRQ_MASK1_RD, ser3_data) | IO_MASK(R_IRQ_MASK1_RD, ser3_ready) +#endif +; +unsigned long r_alt_ser_baudrate_shadow = 0; + /* this is the data for the four serial ports in the etrax100 */ /* DMA2(ser2), DMA4(ser3), DMA6(ser0) or DMA8(ser1) */ /* R_DMA_CHx_CLR_INTR, R_DMA_CHx_FIRST, R_DMA_CHx_CMD */ static struct e100_serial rs_table[] = { - { DEF_BAUD, (unsigned char *)R_SERIAL0_CTRL, 1U << 12, /* uses DMA 6 and 7 */ - R_DMA_CH6_CLR_INTR, R_DMA_CH6_FIRST, R_DMA_CH6_CMD, - R_DMA_CH6_STATUS, R_DMA_CH6_HWSW, R_DMA_CH6_DESCR, - R_DMA_CH7_CLR_INTR, R_DMA_CH7_FIRST, R_DMA_CH7_CMD, - R_DMA_CH7_STATUS, R_DMA_CH7_HWSW, R_DMA_CH7_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 2, + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL0_CTRL, + .irq = 1U << 12, /* uses DMA 6 and 7 */ + .oclrintradr = R_DMA_CH6_CLR_INTR, + .ofirstadr = R_DMA_CH6_FIRST, + .ocmdadr = R_DMA_CH6_CMD, + .ostatusadr = R_DMA_CH6_STATUS, + .iclrintradr = R_DMA_CH7_CLR_INTR, + .ifirstadr = R_DMA_CH7_FIRST, + .icmdadr = R_DMA_CH7_CMD, + .idescradr = R_DMA_CH7_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 2, #ifdef CONFIG_ETRAX_SERIAL_PORT0 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT + .dma_out_enabled = 1, +#else + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN + .dma_in_enabled = 1, +#else + .dma_in_enabled = 0 +#endif #else - 0 + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif + }, /* ttyS0 */ #ifndef CONFIG_SVINTO_SIM - { DEF_BAUD, (unsigned char *)R_SERIAL1_CTRL, 1U << 16, /* uses DMA 8 and 9 */ - R_DMA_CH8_CLR_INTR, R_DMA_CH8_FIRST, R_DMA_CH8_CMD, - R_DMA_CH8_STATUS, R_DMA_CH8_HWSW, R_DMA_CH8_DESCR, - R_DMA_CH9_CLR_INTR, R_DMA_CH9_FIRST, R_DMA_CH9_CMD, - R_DMA_CH9_STATUS, R_DMA_CH9_HWSW, R_DMA_CH9_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 3 , + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL1_CTRL, + .irq = 1U << 16, /* uses DMA 8 and 9 */ + .oclrintradr = R_DMA_CH8_CLR_INTR, + .ofirstadr = R_DMA_CH8_FIRST, + .ocmdadr = R_DMA_CH8_CMD, + .ostatusadr = R_DMA_CH8_STATUS, + .iclrintradr = R_DMA_CH9_CLR_INTR, + .ifirstadr = R_DMA_CH9_FIRST, + .icmdadr = R_DMA_CH9_CMD, + .idescradr = R_DMA_CH9_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 3, #ifdef CONFIG_ETRAX_SERIAL_PORT1 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT + .dma_out_enabled = 1, +#else + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN + .dma_in_enabled = 1, #else - 0 + .dma_in_enabled = 0 +#endif +#else + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif }, /* ttyS1 */ - { DEF_BAUD, (unsigned char *)R_SERIAL2_CTRL, 1U << 4, /* uses DMA 2 and 3 */ - R_DMA_CH2_CLR_INTR, R_DMA_CH2_FIRST, R_DMA_CH2_CMD, - R_DMA_CH2_STATUS, R_DMA_CH2_HWSW, R_DMA_CH2_DESCR, - R_DMA_CH3_CLR_INTR, R_DMA_CH3_FIRST, R_DMA_CH3_CMD, - R_DMA_CH3_STATUS, R_DMA_CH3_HWSW, R_DMA_CH3_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 0, + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL2_CTRL, + .irq = 1U << 4, /* uses DMA 2 and 3 */ + .oclrintradr = R_DMA_CH2_CLR_INTR, + .ofirstadr = R_DMA_CH2_FIRST, + .ocmdadr = R_DMA_CH2_CMD, + .ostatusadr = R_DMA_CH2_STATUS, + .iclrintradr = R_DMA_CH3_CLR_INTR, + .ifirstadr = R_DMA_CH3_FIRST, + .icmdadr = R_DMA_CH3_CMD, + .idescradr = R_DMA_CH3_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 0, #ifdef CONFIG_ETRAX_SERIAL_PORT2 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT + .dma_out_enabled = 1, +#else + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + .dma_in_enabled = 1, #else - 0 + .dma_in_enabled = 0 +#endif +#else + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif }, /* ttyS2 */ - { DEF_BAUD, (unsigned char *)R_SERIAL3_CTRL, 1U << 8, /* uses DMA 4 and 5 */ - R_DMA_CH4_CLR_INTR, R_DMA_CH4_FIRST, R_DMA_CH4_CMD, - R_DMA_CH4_STATUS, R_DMA_CH4_HWSW, R_DMA_CH4_DESCR, - R_DMA_CH5_CLR_INTR, R_DMA_CH5_FIRST, R_DMA_CH5_CMD, - R_DMA_CH5_STATUS, R_DMA_CH5_HWSW, R_DMA_CH5_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 1, + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL3_CTRL, + .irq = 1U << 8, /* uses DMA 4 and 5 */ + .oclrintradr = R_DMA_CH4_CLR_INTR, + .ofirstadr = R_DMA_CH4_FIRST, + .ocmdadr = R_DMA_CH4_CMD, + .ostatusadr = R_DMA_CH4_STATUS, + .iclrintradr = R_DMA_CH5_CLR_INTR, + .ifirstadr = R_DMA_CH5_FIRST, + .icmdadr = R_DMA_CH5_CMD, + .idescradr = R_DMA_CH5_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 1, #ifdef CONFIG_ETRAX_SERIAL_PORT3 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT + .dma_out_enabled = 1, +#else + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + .dma_in_enabled = 1, #else - 0 + .dma_in_enabled = 0 +#endif +#else + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif } /* ttyS3 */ #endif @@ -627,7 +884,7 @@ ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \ (R_PORT_PA_DATA): ( \ (CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT >= 0)? \ - (R_PORT_PB_DATA):&dummy_ser[##line##])) + (R_PORT_PB_DATA):&dummy_ser[line])) #define E100_STRUCT_SHADOW(line, pinname) \ ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \ @@ -646,6 +903,225 @@ #define DUMMY_CD_MASK 8 static unsigned char dummy_ser[NR_PORTS] = {0xFF, 0xFF, 0xFF,0xFF}; +/* If not all status pins are used or disabled, use mixed mode */ +#ifdef CONFIG_ETRAX_SERIAL_PORT0 + +#define SER0_PA_BITSUM (CONFIG_ETRAX_SER0_DTR_ON_PA_BIT+CONFIG_ETRAX_SER0_RI_ON_PA_BIT+CONFIG_ETRAX_SER0_DSR_ON_PA_BIT+CONFIG_ETRAX_SER0_CD_ON_PA_BIT) + +#if SER0_PA_BITSUM != -4 +# if CONFIG_ETRAX_SER0_DTR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER0_RI_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER0_DSR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER0_CD_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#define SER0_PB_BITSUM (CONFIG_ETRAX_SER0_DTR_ON_PB_BIT+CONFIG_ETRAX_SER0_RI_ON_PB_BIT+CONFIG_ETRAX_SER0_DSR_ON_PB_BIT+CONFIG_ETRAX_SER0_CD_ON_PB_BIT) + +#if SER0_PB_BITSUM != -4 +# if CONFIG_ETRAX_SER0_DTR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER0_RI_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER0_DSR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER0_CD_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#endif /* PORT0 */ + + +#ifdef CONFIG_ETRAX_SERIAL_PORT1 + +#define SER1_PA_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PA_BIT+CONFIG_ETRAX_SER1_RI_ON_PA_BIT+CONFIG_ETRAX_SER1_DSR_ON_PA_BIT+CONFIG_ETRAX_SER1_CD_ON_PA_BIT) + +#if SER1_PA_BITSUM != -4 +# if CONFIG_ETRAX_SER1_DTR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER1_RI_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER1_DSR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER1_CD_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#define SER1_PB_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PB_BIT+CONFIG_ETRAX_SER1_RI_ON_PB_BIT+CONFIG_ETRAX_SER1_DSR_ON_PB_BIT+CONFIG_ETRAX_SER1_CD_ON_PB_BIT) + +#if SER1_PB_BITSUM != -4 +# if CONFIG_ETRAX_SER1_DTR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER1_RI_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER1_DSR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER1_CD_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#endif /* PORT1 */ + +#ifdef CONFIG_ETRAX_SERIAL_PORT2 + +#define SER2_PA_BITSUM (CONFIG_ETRAX_SER2_DTR_ON_PA_BIT+CONFIG_ETRAX_SER2_RI_ON_PA_BIT+CONFIG_ETRAX_SER2_DSR_ON_PA_BIT+CONFIG_ETRAX_SER2_CD_ON_PA_BIT) + +#if SER2_PA_BITSUM != -4 +# if CONFIG_ETRAX_SER2_DTR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER2_RI_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER2_DSR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER2_CD_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#define SER2_PB_BITSUM (CONFIG_ETRAX_SER2_DTR_ON_PB_BIT+CONFIG_ETRAX_SER2_RI_ON_PB_BIT+CONFIG_ETRAX_SER2_DSR_ON_PB_BIT+CONFIG_ETRAX_SER2_CD_ON_PB_BIT) + +#if SER2_PB_BITSUM != -4 +# if CONFIG_ETRAX_SER2_DTR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER2_RI_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER2_DSR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER2_CD_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#endif /* PORT2 */ + +#ifdef CONFIG_ETRAX_SERIAL_PORT3 + +#define SER3_PA_BITSUM (CONFIG_ETRAX_SER3_DTR_ON_PA_BIT+CONFIG_ETRAX_SER3_RI_ON_PA_BIT+CONFIG_ETRAX_SER3_DSR_ON_PA_BIT+CONFIG_ETRAX_SER3_CD_ON_PA_BIT) + +#if SER3_PA_BITSUM != -4 +# if CONFIG_ETRAX_SER3_DTR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER3_RI_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER3_DSR_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER3_CD_ON_PA_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#define SER3_PB_BITSUM (CONFIG_ETRAX_SER3_DTR_ON_PB_BIT+CONFIG_ETRAX_SER3_RI_ON_PB_BIT+CONFIG_ETRAX_SER3_DSR_ON_PB_BIT+CONFIG_ETRAX_SER3_CD_ON_PB_BIT) + +#if SER3_PB_BITSUM != -4 +# if CONFIG_ETRAX_SER3_DTR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER3_RI_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER3_DSR_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +# if CONFIG_ETRAX_SER3_CD_ON_PB_BIT == -1 +# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED +# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1 +# endif +# endif +#endif + +#endif /* PORT3 */ + + #if defined(CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED) || \ defined(CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED) || \ defined(CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED) || \ @@ -653,6 +1129,7 @@ #define CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED #endif + #ifdef CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED /* The pins can be mixed on PA and PB */ #define CONTROL_PINS_PORT_NOT_USED(line) \ @@ -838,7 +1315,6 @@ #define E100_RTS_MASK 0x20 #define E100_CTS_MASK 0x40 - /* All serial port signals are active low: * active = 0 -> 3.3V to RS-232 driver -> -12V on RS-232 level * inactive = 1 -> 0V to RS-232 driver -> +12V on RS-232 level @@ -937,6 +1413,9 @@ /* calc timeout */ info->char_time_usec = ((bits * 1000000) / info->baud) + 1; + info->flush_time_usec = 4*info->char_time_usec; + if (info->flush_time_usec < MIN_FLUSH_TIME_USEC) + info->flush_time_usec = MIN_FLUSH_TIME_USEC; } /* @@ -980,7 +1459,7 @@ retval = baud_table[cflag & CBAUD]; if (retval < 0) { - printk("serdriver tried setting invalid baud rate, flags %x.\n", cflag); + printk(KERN_WARNING "serdriver tried setting invalid baud rate, flags %x.\n", cflag); retval = 5; /* choose default 9600 instead */ } @@ -1036,9 +1515,13 @@ e100_rts(struct e100_serial *info, int set) { #ifndef CONFIG_SVINTO_SIM + unsigned long flags; + save_flags(flags); + cli(); info->rx_ctrl &= ~E100_RTS_MASK; info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */ info->port[REG_REC_CTRL] = info->rx_ctrl; + restore_flags(flags); #ifdef SERIAL_DEBUG_IO printk("ser%i rts %i\n", info->line, set); #endif @@ -1112,6 +1595,7 @@ #ifdef SERIAL_DEBUG_INTR printk("rxdma_irq(%d): 0\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable_rxdma_irq %i\n", info->line)); *R_IRQ_MASK2_CLR = (info->irq << 2) | (info->irq << 3); } @@ -1121,6 +1605,7 @@ #ifdef SERIAL_DEBUG_INTR printk("rxdma_irq(%d): 1\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ enable_rxdma_irq %i\n", info->line)); *R_IRQ_MASK2_SET = (info->irq << 2) | (info->irq << 3); } @@ -1132,6 +1617,7 @@ #ifdef SERIAL_DEBUG_INTR printk("txdma_irq(%d): 0\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable_txdma_irq %i\n", info->line)); *R_IRQ_MASK2_CLR = info->irq; } @@ -1141,9 +1627,143 @@ #ifdef SERIAL_DEBUG_INTR printk("txdma_irq(%d): 1\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ enable_txdma_irq %i\n", info->line)); *R_IRQ_MASK2_SET = info->irq; } +static _INLINE_ void +e100_disable_txdma_channel(struct e100_serial *info) +{ + unsigned long flags; + + /* Disable output DMA channel for the serial port in question + * ( set to something other then serialX) + */ + save_flags(flags); + cli(); + DFLOW(DEBUG_LOG(info->line, "disable_txdma_channel %i\n", info->line)); + if (info->line == 0) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma6)) == + IO_STATE(R_GEN_CONFIG, dma6, serial0)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); + } + } else if (info->line == 1) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma8)) == + IO_STATE(R_GEN_CONFIG, dma8, serial1)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); + } + } else if (info->line == 2) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma2)) == + IO_STATE(R_GEN_CONFIG, dma2, serial2)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); + } + } else if (info->line == 3) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma4)) == + IO_STATE(R_GEN_CONFIG, dma4, serial3)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1); + } + } + *R_GEN_CONFIG = genconfig_shadow; + restore_flags(flags); +} + + +static _INLINE_ void +e100_enable_txdma_channel(struct e100_serial *info) +{ + unsigned long flags; + + save_flags(flags); + cli(); + DFLOW(DEBUG_LOG(info->line, "enable_txdma_channel %i\n", info->line)); + /* Enable output DMA channel for the serial port in question */ + if (info->line == 0) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, serial0); + } else if (info->line == 1) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, serial1); + } else if (info->line == 2) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, serial2); + } else if (info->line == 3) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, serial3); + } + *R_GEN_CONFIG = genconfig_shadow; + restore_flags(flags); +} + +static _INLINE_ void +e100_disable_rxdma_channel(struct e100_serial *info) +{ + unsigned long flags; + + /* Disable input DMA channel for the serial port in question + * ( set to something other then serialX) + */ + save_flags(flags); + cli(); + if (info->line == 0) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma7)) == + IO_STATE(R_GEN_CONFIG, dma7, serial0)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, unused); + } + } else if (info->line == 1) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma9)) == + IO_STATE(R_GEN_CONFIG, dma9, serial1)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, usb); + } + } else if (info->line == 2) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma3)) == + IO_STATE(R_GEN_CONFIG, dma3, serial2)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0); + } + } else if (info->line == 3) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma5)) == + IO_STATE(R_GEN_CONFIG, dma5, serial3)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1); + } + } + *R_GEN_CONFIG = genconfig_shadow; + restore_flags(flags); +} + + +static _INLINE_ void +e100_enable_rxdma_channel(struct e100_serial *info) +{ + unsigned long flags; + + save_flags(flags); + cli(); + /* Enable input DMA channel for the serial port in question */ + if (info->line == 0) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, serial0); + } else if (info->line == 1) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, serial1); + } else if (info->line == 2) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, serial2); + } else if (info->line == 3) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, serial3); + } + *R_GEN_CONFIG = genconfig_shadow; + restore_flags(flags); +} + + #ifdef SERIAL_HANDLE_EARLY_ERRORS /* in order to detect and fix errors on the first byte we have to use the serial interrupts as well. */ @@ -1154,6 +1774,7 @@ #ifdef SERIAL_DEBUG_INTR printk("ser_irq(%d): 0\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable data_irq %i\n", info->line)); *R_IRQ_MASK1_CLR = (1U << (8+2*info->line)); } @@ -1166,10 +1787,50 @@ (8+2*info->line), (1U << (8+2*info->line))); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ enable data_irq %i\n", info->line)); *R_IRQ_MASK1_SET = (1U << (8+2*info->line)); } #endif +static inline void +e100_disable_serial_tx_ready_irq(struct e100_serial *info) +{ +#ifdef SERIAL_DEBUG_INTR + printk("ser_tx_irq(%d): 0\n",info->line); +#endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable ready_irq %i\n", info->line)); + *R_IRQ_MASK1_CLR = (1U << (8+1+2*info->line)); +} + +static inline void +e100_enable_serial_tx_ready_irq(struct e100_serial *info) +{ +#ifdef SERIAL_DEBUG_INTR + printk("ser_tx_irq(%d): 1\n",info->line); + printk("**** %d = %d\n", + (8+1+2*info->line), + (1U << (8+1+2*info->line))); +#endif + DINTR2(DEBUG_LOG(info->line,"IRQ enable ready_irq %i\n", info->line)); + *R_IRQ_MASK1_SET = (1U << (8+1+2*info->line)); +} + +static inline void e100_enable_rx_irq(struct e100_serial *info) +{ + if (info->uses_dma_in) + e100_enable_rxdma_irq(info); + else + e100_enable_serial_data_irq(info); +} +static inline void e100_disable_rx_irq(struct e100_serial *info) +{ + if (info->uses_dma_in) + e100_disable_rxdma_irq(info); + else + e100_disable_serial_data_irq(info); +} + + #if defined(CONFIG_ETRAX_RS485) /* Enable RS-485 mode on selected port. This is UGLY. */ static int @@ -1183,7 +1844,10 @@ info->rs485.rts_on_send = 0x01 & r->rts_on_send; info->rs485.rts_after_sent = 0x01 & r->rts_after_sent; - info->rs485.delay_rts_before_send = r->delay_rts_before_send; + if (r->delay_rts_before_send >= 1000) + info->rs485.delay_rts_before_send = 1000; + else + info->rs485.delay_rts_before_send = r->delay_rts_before_send; info->rs485.enabled = r->enabled; /* printk("rts: on send = %i, after = %i, enabled = %i", info->rs485.rts_on_send, @@ -1223,7 +1887,7 @@ e100_rts(info, info->rs485.rts_after_sent); #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) e100_enable_rx(info); - e100_enable_rxdma_irq(info); + e100_enable_rx_irq(info); #endif } #endif @@ -1245,8 +1909,12 @@ if (info) { unsigned long flags; unsigned long xoff; - + save_flags(flags); cli(); + DFLOW(DEBUG_LOG(info->line, "XOFF rs_stop xmit %i\n", + CIRC_CNT(info->xmit.head, + info->xmit.tail,SERIAL_XMIT_SIZE))); + xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty)); xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); if (tty->termios->c_iflag & IXON ) { @@ -1267,6 +1935,9 @@ unsigned long xoff; save_flags(flags); cli(); + DFLOW(DEBUG_LOG(info->line, "XOFF rs_start xmit %i\n", + CIRC_CNT(info->xmit.head, + info->xmit.tail,SERIAL_XMIT_SIZE))); xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); if (tty->termios->c_iflag & IXON ) { @@ -1274,6 +1945,9 @@ } *((unsigned long *)&info->port[REG_XOFF]) = xoff; + if (!info->uses_dma_out && + info->xmit.head != info->xmit.tail && info->xmit.buf) + e100_enable_serial_tx_ready_irq(info); restore_flags(flags); } @@ -1308,6 +1982,8 @@ rs_sched_event(struct e100_serial *info, int event) { + if (info->event & (1 << event)) + return; info->event |= 1 << event; queue_task(&info->tqueue, &tq_serial); mark_bh(SERIAL_BH); @@ -1325,7 +2001,7 @@ */ static void -transmit_chars(struct e100_serial *info) +transmit_chars_dma(struct e100_serial *info) { unsigned int c, sentl; struct etrax_dma_descr *descr; @@ -1333,11 +2009,11 @@ #ifdef CONFIG_SVINTO_SIM /* This will output too little if tail is not 0 always since * we don't reloop to send the other part. Anyway this SHOULD be a - * no-op - transmit_chars would never really be called during sim + * no-op - transmit_chars_dma would never really be called during sim * since rs_write does not write into the xmit buffer then. */ if (info->xmit.tail) - printk("Error in serial.c:transmit_chars(), tail!=0\n"); + printk("Error in serial.c:transmit_chars_dma(), tail!=0\n"); if (info->xmit.head != info->xmit.tail) { SIMCOUT(info->xmit.buf + info->xmit.tail, CIRC_CNT(info->xmit.head, @@ -1359,7 +2035,7 @@ #endif if (!info->tr_running) { /* weirdo... we shouldn't get here! */ - printk("Achtung: transmit_chars with !tr_running\n"); + printk(KERN_WARNING "Achtung: transmit_chars_dma with !tr_running\n"); return; } @@ -1375,6 +2051,8 @@ /* otherwise we find the amount of data sent here */ sentl = descr->hw_len; + DFLOW(DEBUG_LOG(info->line, "TX %i done\n", sentl)); + /* update stats */ info->icount.tx += sentl; @@ -1392,6 +2070,13 @@ c = CIRC_CNT_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + /* Don't send all in one DMA transfer - divide it so we wake up + * application before all is sent + */ + + if (c >= 4*WAKEUP_CHARS) + c = c/2; + if (c <= 0) { /* our job here is done, don't schedule any new DMA transfer */ info->tr_running = 0; @@ -1411,17 +2096,17 @@ /* ok we can schedule a dma send of c chars starting at info->xmit.tail */ /* set up the descriptor correctly for output */ - + DFLOW(DEBUG_LOG(info->line, "TX %i\n", c)); descr->ctrl = d_int | d_eol | d_wait; /* Wait needed for tty_wait_until_sent() */ descr->sw_len = c; descr->buf = virt_to_phys(info->xmit.buf + info->xmit.tail); descr->status = 0; *info->ofirstadr = virt_to_phys(descr); /* write to R_DMAx_FIRST */ - *info->ocmdadr = 1; /* dma command start -> R_DMAx_CMD */ + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start); /* dma command start -> R_DMAx_CMD */ /* DMA is now running (hopefully) */ -} /* transmit_chars */ +} /* transmit_chars_dma */ static void start_transmit(struct e100_serial *info) @@ -1435,15 +2120,17 @@ info->tr_descr.hw_len = 0; info->tr_descr.status = 0; info->tr_running = 1; - - transmit_chars(info); + if (info->uses_dma_out) + transmit_chars_dma(info); + else + e100_enable_serial_tx_ready_irq(info); } /* start_transmit */ #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER static int serial_fast_timer_started = 0; static int serial_fast_timer_expired = 0; static void flush_timeout_function(unsigned long data); -#define START_FLUSH_FAST_TIMER(info, string) {\ +#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) {\ unsigned long timer_flags; \ save_flags(timer_flags); \ cli(); \ @@ -1454,7 +2141,7 @@ start_one_shot_timer(&fast_timers[info->line], \ flush_timeout_function, \ (unsigned long)info, \ - info->char_time_usec*4, \ + (usec), \ string); \ } \ else { \ @@ -1462,8 +2149,10 @@ } \ restore_flags(timer_flags); \ } +#define START_FLUSH_FAST_TIMER(info, string) START_FLUSH_FAST_TIMER_TIME(info, string, info->flush_time_usec) #else +#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) #define START_FLUSH_FAST_TIMER(info, string) #endif @@ -1508,18 +2197,27 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char flag) { struct etrax_recv_buffer *buffer; + if (info->uses_dma_in) { + if (!(buffer = alloc_recv_buffer(4))) + return 0; - if (!(buffer = alloc_recv_buffer(4))) - return 0; - - buffer->length = 1; - buffer->error = flag; - buffer->buffer[0] = data; + buffer->length = 1; + buffer->error = flag; + buffer->buffer[0] = data; - append_recv_buffer(info, buffer); - - info->icount.rx++; + append_recv_buffer(info, buffer); + info->icount.rx++; + } else { + struct tty_struct *tty = info->tty; + *tty->flip.char_buf_ptr = data; + *tty->flip.flag_buf_ptr = flag; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + info->icount.rx++; + } + return 1; } @@ -1529,7 +2227,8 @@ struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer; if (info->recv_cnt + recvl > 65536) { - printk(__FUNCTION__ ": Too much pending incoming serial data! Dropping %u bytes.\n", recvl); + printk(KERN_CRIT + "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __FUNCTION__, recvl); return 0; } @@ -1542,7 +2241,7 @@ append_recv_buffer(info, buffer); if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE))) - panic(__FUNCTION__ ": Failed to allocate memory for receive buffer!\n"); + panic("%s: Failed to allocate memory for receive buffer!\n", __FUNCTION__); descr->buf = virt_to_phys(buffer->buffer); @@ -1579,8 +2278,16 @@ /* Reset the status information */ descr->status = 0; - DEBUG_LOG(info->line, "recvl %lu\n", recvl); - + DFLOW( DEBUG_LOG(info->line, "RX %lu\n", recvl); + if (info->tty->stopped) { + unsigned char *buf = phys_to_virt(descr->buf); + DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]); + DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]); + DEBUG_LOG(info->line, "rx 0x%02X\n", buf[2]); + } + ); + + /* update stats */ info->icount.rx += recvl; @@ -1591,7 +2298,7 @@ } static _INLINE_ void -receive_chars(struct e100_serial *info) +receive_chars_dma(struct e100_serial *info) { struct tty_struct *tty; unsigned char rstat; @@ -1623,7 +2330,10 @@ /* Read the status register to detect errors */ rstat = info->port[REG_STATUS]; - + if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { + DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat)); + } + if (rstat & SER_ERROR_MASK) { /* If we got an error, we must reset it by reading the * data_in field @@ -1658,7 +2368,7 @@ /* Set up the receiving descriptors */ for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) { if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE))) - panic(__FUNCTION__ ": Failed to allocate memory for receive buffer!\n"); + panic("%s: Failed to allocate memory for receive buffer!\n", __FUNCTION__); descr[i].ctrl = d_int; descr[i].buf = virt_to_phys(buffer->buffer); @@ -1691,20 +2401,20 @@ */ return; #endif + info->tty->flip.count = 0; + if (info->uses_dma_in) { + /* reset the input dma channel to be sure it works */ + + *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); - /* reset the input dma channel to be sure it works */ - - *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == - IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); - - info->tty->flip.count = 0; - - start_recv_dma(info); + start_recv_dma(info); #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST - start_flush_timer(); + start_flush_timer(); #endif + } } @@ -1749,25 +2459,25 @@ for (i = 0; i < NR_PORTS; i++) { info = rs_table + i; - if (!info->enabled || !info->uses_dma) + if (!info->enabled || !info->uses_dma_out) continue; /* check for dma_descr (don't need to check for dma_eop in output dma for serial */ if (ireg & info->irq) { /* we can send a new dma bunch. make it so. */ - DEBUG_LOG(info->line, "tr_interrupt %i\n", i); + DINTR2(DEBUG_LOG(info->line, "tr_interrupt %i\n", i)); /* Read jiffies_usec first, * we want this time to be as late as possible */ PROCSTAT(ser_stat[info->line].tx_dma_ints++); info->last_tx_active_usec = GET_JIFFIES_USEC(); info->last_tx_active = jiffies; - transmit_chars(info); + transmit_chars_dma(info); } /* FIXME: here we should really check for a change in the status lines and if so call status_handle(info) */ } -} +} /* tr_interrupt */ /* dma input channel interrupt handler */ @@ -1795,18 +2505,18 @@ for (i = 0; i < NR_PORTS; i++) { info = rs_table + i; - if (!info->enabled || !info->uses_dma) + if (!info->enabled || !info->uses_dma_in) continue; /* check for both dma_eop and dma_descr for the input dma channel */ if (ireg & ((info->irq << 2) | (info->irq << 3))) { /* we have received something */ - receive_chars(info); + receive_chars_dma(info); } /* FIXME: here we should really check for a change in the status lines and if so call status_handle(info) */ } -} +} /* rec_interrupt */ static _INLINE_ int force_eop_if_needed(struct e100_serial *info) @@ -1846,7 +2556,7 @@ if (!info->forced_eop) { info->forced_eop = 1; PROCSTAT(ser_stat[info->line].timeout_flush_cnt++); - DEBUG_LOG(info->line, "timeout EOP %i\n", info->line); + TIMERD(DEBUG_LOG(info->line, "timeout EOP %i\n", info->line)); FORCE_EOP(info); } @@ -1860,7 +2570,8 @@ struct etrax_recv_buffer *buffer; unsigned int length; unsigned long flags; - + int max_flip_size; + if (!info->first_recv_buffer) return; @@ -1873,12 +2584,46 @@ } length = tty->flip.count; + /* Don't flip more than the ldisc has room for. + * The return value from ldisc.receive_room(tty) - might not be up to + * date, the previous flip of up to TTY_FLIPBUF_SIZE might be on the + * processed and not accounted for yet. + * Since we use DMA, 1 SERIAL_DESCR_BUF_SIZE could be on the way. + * Lets buffer data here and let flow control take care of it. + * Since we normally flip large chunks, the ldisc don't react + * with throttle until too late if we flip to much. + */ + max_flip_size = tty->ldisc.receive_room(tty); + if (max_flip_size < 0) + max_flip_size = 0; + if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */ + length + info->recv_cnt + /* We have this queued */ + 2*SERIAL_DESCR_BUF_SIZE + /* This could be on the way */ + TTY_THRESHOLD_THROTTLE)) { /* Some slack */ + /* check TTY_THROTTLED first so it indicates our state */ + if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { + DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles room %lu\n", max_flip_size)); + rs_throttle(tty); + } +#if 0 + else if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */ + length + info->recv_cnt + /* We have this queued */ + SERIAL_DESCR_BUF_SIZE + /* This could be on the way */ + TTY_THRESHOLD_THROTTLE)) { /* Some slack */ + DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles again! %lu\n", max_flip_size)); + rs_throttle(tty); + } +#endif + } - while ((buffer = info->first_recv_buffer) && length < TTY_FLIPBUF_SIZE) { + if (max_flip_size > TTY_FLIPBUF_SIZE) + max_flip_size = TTY_FLIPBUF_SIZE; + + while ((buffer = info->first_recv_buffer) && length < max_flip_size) { unsigned int count = buffer->length; - if (length + count > TTY_FLIPBUF_SIZE) - count = TTY_FLIPBUF_SIZE - length; + if (length + count > max_flip_size) + count = max_flip_size - length; memcpy(tty->flip.char_buf_ptr + length, buffer->buffer, count); memset(tty->flip.flag_buf_ptr + length, TTY_NORMAL, count); @@ -1886,7 +2631,8 @@ length += count; info->recv_cnt -= count; - + DFLIP(DEBUG_LOG(info->line,"flip: %i\n", length)); + if (count == buffer->length) { info->first_recv_buffer = buffer->next; kfree(buffer); @@ -1901,10 +2647,31 @@ info->last_recv_buffer = NULL; tty->flip.count = length; - + DFLIP(if (tty->ldisc.chars_in_buffer(tty) > 3500) { + DEBUG_LOG(info->line, "ldisc %lu\n", + tty->ldisc.chars_in_buffer(tty)); + DEBUG_LOG(info->line, "flip.count %lu\n", + tty->flip.count); + } + ); restore_flags(flags); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,66) + DFLIP( + if (1) { + + if (test_bit(TTY_DONT_FLIP, &tty->flags)) { + DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count); + DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt); + } else { + } + DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); + DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); + DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); + } + + ); + /* this includes a check for low-latency */ tty_flip_buffer_push(tty); #else @@ -1915,12 +2682,19 @@ static _INLINE_ void check_flush_timeout(struct e100_serial *info) { - force_eop_if_needed(info); - + /* Flip what we've got (if we can) */ flush_to_flip_buffer(info); - if (info->first_recv_buffer) - START_FLUSH_FAST_TIMER(info, "flip"); + /* We might need to flip later, but not to fast + * since the system is busy processing input... */ + if (info->first_recv_buffer) + START_FLUSH_FAST_TIMER_TIME(info, "flip", 2000); + + /* Force eop last, since data might have come while we're processing + * and if we started the slow timer above, we won't start a fast + * below. + */ + force_eop_if_needed(info); } #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER @@ -1960,7 +2734,7 @@ for (i = 0; i < NR_PORTS; i++) { info = rs_table + i; - if (info->enabled && info->uses_dma) + if (info->enabled && info->uses_dma_in) check_flush_timeout(info); } } /* timeout_interrupt */ @@ -1988,7 +2762,7 @@ for (i = 0; i < NR_PORTS; i++) { info = rs_table + i; - if (info->uses_dma) + if (info->uses_dma_in) check_flush_timeout(info); } @@ -2017,7 +2791,7 @@ B= Break character (0x00) with framing error. E= Error byte with parity error received after B characters. -F= "Faked" valid byte received immediatly after B characters. +F= "Faked" valid byte received immediately after B characters. V= Valid byte 1. @@ -2054,7 +2828,7 @@ To distinguish a V byte in 1. from an F byte in 2. we keep a timestamp of the last faulty char (B) and compares it with the current time: -If the time elapsed time is less then 2*char_time_usec we will assume +If the time elapsed time is less than 2*char_time_usec we will assume it's a faked F char and not a Valid char and set info->errorcode = ERRCODE_SET_BREAK. @@ -2066,15 +2840,159 @@ TODO: The break will be delayed until an F or V character is received. */ + +extern _INLINE_ +struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) +{ + unsigned long data_read; + struct tty_struct *tty = info->tty; + + if (!tty) { + printk("!NO TTY!\n"); + return info; + } + if (tty->flip.count >= TTY_FLIPBUF_SIZE - TTY_THRESHOLD_THROTTLE) { + /* check TTY_THROTTLED first so it indicates our state */ + if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { + DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count)); + rs_throttle(tty); + } + } + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count); + tty->flip.tqueue.routine((void *) tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count); + return info; /* if TTY_DONT_FLIP is set */ + } + } + /* Read data and status at the same time */ + data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); +more_data: + if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) { + DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); + } + DINTR2(DEBUG_LOG(info->line, "ser_rx %c\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read))); + + if (data_read & ( IO_MASK(R_SERIAL0_READ, framing_err) | + IO_MASK(R_SERIAL0_READ, par_err) | + IO_MASK(R_SERIAL0_READ, overrun) )) { + /* An error */ + info->last_rx_active_usec = GET_JIFFIES_USEC(); + info->last_rx_active = jiffies; + DINTR1(DEBUG_LOG(info->line, "ser_rx err stat_data %04X\n", data_read)); + DLOG_INT_TRIG( + if (!log_int_trig1_pos) { + log_int_trig1_pos = log_int_pos; + log_int(rdpc(), 0, 0); + } + ); + + + if ( ((data_read & IO_MASK(R_SERIAL0_READ, data_in)) == 0) && + (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) ) { + /* Most likely a break, but we get interrupts over and + * over again. + */ -extern void _INLINE_ handle_ser_interrupt(struct e100_serial *info) + if (!info->break_detected_cnt) { + DEBUG_LOG(info->line, "#BRK start\n", 0); + } + if (data_read & IO_MASK(R_SERIAL0_READ, rxd)) { + /* The RX pin is high now, so the break + * must be over, but.... + * we can't really know if we will get another + * last byte ending the break or not. + * And we don't know if the byte (if any) will + * have an error or look valid. + */ + DEBUG_LOG(info->line, "# BL BRK\n", 0); + info->errorcode = ERRCODE_INSERT_BREAK; + } + info->break_detected_cnt++; + } else { + /* The error does not look like a break, but could be + * the end of one + */ + if (info->break_detected_cnt) { + DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt); + info->errorcode = ERRCODE_INSERT_BREAK; + } else { + if (info->errorcode == ERRCODE_INSERT_BREAK) { + info->icount.brk++; + *tty->flip.char_buf_ptr = 0; + *tty->flip.flag_buf_ptr = TTY_BREAK; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + info->icount.rx++; + } + *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read); + + if (data_read & IO_MASK(R_SERIAL0_READ, par_err)) { + info->icount.parity++; + *tty->flip.flag_buf_ptr = TTY_PARITY; + } else if (data_read & IO_MASK(R_SERIAL0_READ, overrun)) { + info->icount.overrun++; + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + } else if (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) { + info->icount.frame++; + *tty->flip.flag_buf_ptr = TTY_FRAME; + } + info->errorcode = 0; + } + info->break_detected_cnt = 0; + } + } else if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { + /* No error */ + DLOG_INT_TRIG( + if (!log_int_trig1_pos) { + if (log_int_pos >= log_int_size) { + log_int_pos = 0; + } + log_int_trig0_pos = log_int_pos; + log_int(rdpc(), 0, 0); + } + ); + *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read); + *tty->flip.flag_buf_ptr = 0; + } else { + DEBUG_LOG(info->line, "ser_rx int but no data_avail %08lX\n", data_read); + } + + + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + info->icount.rx++; + data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); + if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { + DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read)); + goto more_data; + } + + tty_flip_buffer_push(info->tty); + return info; +} + +extern _INLINE_ +struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) { - unsigned char rstat = info->port[REG_STATUS]; + unsigned char rstat; #ifdef SERIAL_DEBUG_INTR printk("Interrupt from serport %d\n", i); #endif /* DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */ + if (!info->uses_dma_in) { + return handle_ser_rx_interrupt_no_dma(info); + } + /* DMA is used */ + rstat = info->port[REG_STATUS]; + if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { + DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); + } + if (rstat & SER_ERROR_MASK) { unsigned char data; @@ -2084,7 +3002,8 @@ * data_in field */ data = info->port[REG_DATA]; - + DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data)); + DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat)); if (!data && (rstat & SER_FRAMING_ERR_MASK)) { /* Most likely a break, but we get interrupts over and * over again. @@ -2113,15 +3032,22 @@ DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt); info->errorcode = ERRCODE_INSERT_BREAK; } else { - if (info->errorcode == ERRCODE_INSERT_BREAK) + if (info->errorcode == ERRCODE_INSERT_BREAK) { + info->icount.brk++; add_char_and_flag(info, '\0', TTY_BREAK); + } - if (rstat & SER_PAR_ERR_MASK) + if (rstat & SER_PAR_ERR_MASK) { + info->icount.parity++; add_char_and_flag(info, data, TTY_PARITY); - else if (rstat & SER_OVERRUN_MASK) + } else if (rstat & SER_OVERRUN_MASK) { + info->icount.overrun++; add_char_and_flag(info, data, TTY_OVERRUN); - else if (rstat & SER_FRAMING_ERR_MASK) + } else if (rstat & SER_FRAMING_ERR_MASK) { + info->icount.frame++; add_char_and_flag(info, data, TTY_FRAME); + } + info->errorcode = 0; } info->break_detected_cnt = 0; @@ -2145,7 +3071,7 @@ if (elapsed_usec < 2*info->char_time_usec) { DEBUG_LOG(info->line, "FBRK %i\n", info->line); /* Report as BREAK (error) and let - * receive_chars() handle it + * receive_chars_dma() handle it */ info->errorcode = ERRCODE_SET_BREAK; } else { @@ -2155,38 +3081,195 @@ } #ifdef SERIAL_DEBUG_INTR - printk("** OK, disabling ser_interupts\n"); + printk("** OK, disabling ser_interrupts\n"); #endif e100_disable_serial_data_irq(info); - + DINTR2(DEBUG_LOG(info->line, "ser_rx OK %d\n", info->line)); info->break_detected_cnt = 0; PROCSTAT(ser_stat[info->line].ser_ints_ok_cnt++); - DEBUG_LOG(info->line, "ser_int OK %d\n", info->line); } - /* Restarting the DMA never hurts */ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); START_FLUSH_FAST_TIMER(info, "ser_int"); -} /* handle_ser_interrupt */ + return info; +} /* handle_ser_rx_interrupt */ + +extern _INLINE_ void handle_ser_tx_interrupt(struct e100_serial *info) +{ + unsigned long flags; + + if (info->x_char) { + unsigned char rstat; + DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char)); + save_flags(flags); cli(); + rstat = info->port[REG_STATUS]; + DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); + + info->port[REG_TR_DATA] = info->x_char; + info->icount.tx++; + info->x_char = 0; + /* We must enable since it is disabled in ser_interrupt */ + e100_enable_serial_tx_ready_irq(info); + restore_flags(flags); + return; + } + if (info->uses_dma_out) { + unsigned char rstat; + int i; + /* We only use normal tx interrupt when sending x_char */ + DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0)); + save_flags(flags); cli(); + rstat = info->port[REG_STATUS]; + DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); + e100_disable_serial_tx_ready_irq(info); + if (info->tty->stopped) + rs_stop(info->tty); + /* Enable the DMA channel and tell it to continue */ + e100_enable_txdma_channel(info); + /* Wait 12 cycles before doing the DMA command */ + for(i = 6; i > 0; i--) + nop(); + + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, continue); + restore_flags(flags); + return; + } + /* Normal char-by-char interrupt */ + if (info->xmit.head == info->xmit.tail + || info->tty->stopped + || info->tty->hw_stopped) { + DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", info->tty->stopped)); + e100_disable_serial_tx_ready_irq(info); + info->tr_running = 0; + return; + } + DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail])); + /* Send a byte, rs485 timing is critical so turn of ints */ + save_flags(flags); cli(); + info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail]; + info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); + info->icount.tx++; + if (info->xmit.head == info->xmit.tail) { +#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) + if (info->rs485.enabled) { + /* Set a short timer to toggle RTS */ + start_one_shot_timer(&fast_timers_rs485[info->line], + rs485_toggle_rts_timer_function, + (unsigned long)info, + info->char_time_usec*2, + "RS-485"); + } +#endif /* RS485 */ + info->last_tx_active_usec = GET_JIFFIES_USEC(); + info->last_tx_active = jiffies; + e100_disable_serial_tx_ready_irq(info); + DFLOW(DEBUG_LOG(info->line, "tx_int: stop2\n", 0)); + } else { + /* We must enable since it is disabled in ser_interrupt */ + e100_enable_serial_tx_ready_irq(info); + } + restore_flags(flags); + + if (CIRC_CNT(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); +} /* handle_ser_tx_interrupt */ + +/* result of time measurements: + * RX duration 54-60 us when doing something, otherwise 6-9 us + * ser_int duration: just sending: 8-15 us normally, up to 73 us + */ static void ser_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + static volatile int tx_started = 0; struct e100_serial *info; int i; - + unsigned long flags; + unsigned long irq_mask1_rd; + unsigned long data_mask = (1 << (8+2*0)); /* ser0 data_avail */ + static volatile unsigned long reentered_ready_mask = 0; + + save_flags(flags); cli(); + irq_mask1_rd = *R_IRQ_MASK1_RD; + /* First handle all rx interrupts with ints disabled */ + info = rs_table; + irq_mask1_rd &= e100_ser_int_mask; for (i = 0; i < NR_PORTS; i++) { - info = rs_table + i; - - if (!info->enabled || !info->uses_dma) - continue; - - /* Which line caused the irq? */ - if (*R_IRQ_MASK1_RD & (1U << (8+2*info->line))) { - handle_ser_interrupt(info); + /* Which line caused the data irq? */ + if (irq_mask1_rd & data_mask) { + handle_ser_rx_interrupt(info); } + info += 1; + data_mask <<= 2; } + /* Handle tx interrupts with interrupts enabled so we + * can take care of new data interrupts while transmitting + * We protect the tx part with the tx_started flag. + * We disable the tr_ready interrupts we are about to handle and + * unblock the serial interrupt so new serial interrupts may come. + * + * If we get a new interrupt: + * - it migth be due to synchronous serial ports. + * - serial irq will be blocked by general irq handler. + * - async data will be handled above (sync will be ignored). + * - tx_started flag will prevent us from trying to send again and + * we will exit fast - no need to unblock serial irq. + * - Next (sync) serial interrupt handler will be runned with + * disabled interrupt due to restore_flags() at end of function, + * so sync handler will not be preempted or reentered. + */ + if (!tx_started) { + unsigned long ready_mask; + unsigned long + tx_started = 1; + /* Only the tr_ready interrupts left */ + irq_mask1_rd &= (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser1_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser2_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser3_ready)); + while (irq_mask1_rd) { + /* Disable those we are about to handle */ + *R_IRQ_MASK1_CLR = irq_mask1_rd; + /* Unblock the serial interrupt */ + *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); + + sti(); + ready_mask = (1 << (8+1+2*0)); /* ser0 tr_ready */ + info = rs_table; + for (i = 0; i < NR_PORTS; i++) { + /* Which line caused the ready irq? */ + if (irq_mask1_rd & ready_mask) { + handle_ser_tx_interrupt(info); + } + info += 1; + ready_mask <<= 2; + } + /* handle_ser_tx_interrupt enables tr_ready interrupts */ + cli(); + /* Handle reentered TX interrupt */ + irq_mask1_rd = reentered_ready_mask; + } + cli(); + tx_started = 0; + } else { + unsigned long ready_mask; + ready_mask = irq_mask1_rd & (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser1_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser2_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser3_ready)); + if (ready_mask) { + reentered_ready_mask |= ready_mask; + /* Disable those we are about to handle */ + *R_IRQ_MASK1_CLR = ready_mask; + DFLOW(DEBUG_LOG(SERIAL_DEBUG_LINE, "ser_int reentered with TX %X\n", ready_mask)); + } + } + + restore_flags(flags); } /* ser_interrupt */ #endif @@ -2288,25 +3371,40 @@ * Reset the DMA channels and make sure their interrupts are cleared */ - info->uses_dma = 1; - *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - - /* Wait until reset cycle is complete */ - while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == - IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); - - while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) == - IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); + if (info->dma_in_enabled) { + info->uses_dma_in = 1; + e100_enable_rxdma_channel(info); + + *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - /* Make sure the irqs are cleared */ - *info->iclrintradr = - IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | - IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); - *info->oclrintradr = - IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | - IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); + /* Wait until reset cycle is complete */ + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); + + /* Make sure the irqs are cleared */ + *info->iclrintradr = + IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | + IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); + } else { + e100_disable_rxdma_channel(info); + } + + if (info->dma_out_enabled) { + info->uses_dma_out = 1; + e100_enable_txdma_channel(info); + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) == + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); + /* Make sure the irqs are cleared */ + *info->oclrintradr = + IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | + IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); + } else { + e100_disable_txdma_channel(info); + } + if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); @@ -2321,8 +3419,10 @@ * and set the speed and other flags of the serial port * this will start the rx/tx as well */ + #ifdef SERIAL_HANDLE_EARLY_ERRORS - e100_enable_serial_data_irq(info); + if (info->uses_dma_in) + e100_enable_serial_data_irq(info); #endif change_speed(info); @@ -2331,9 +3431,10 @@ (void)info->port[REG_DATA]; /* enable the interrupts */ + if (info->uses_dma_out) + e100_enable_txdma_irq(info); - e100_enable_txdma_irq(info); - e100_enable_rxdma_irq(info); + e100_enable_rx_irq(info); info->tr_running = 0; /* to be sure we don't lock up the transmitter */ @@ -2342,10 +3443,10 @@ start_receive(info); /* for safety, make sure the descriptors last result is 0 bytes written */ - info->tr_descr.sw_len = 0; info->tr_descr.hw_len = 0; info->tr_descr.status = 0; + /* enable RTS/DTR last */ @@ -2374,20 +3475,28 @@ #ifndef CONFIG_SVINTO_SIM /* shut down the transmitter and receiver */ - + DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line)); e100_disable_rx(info); info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40); - e100_disable_rxdma_irq(info); - e100_disable_txdma_irq(info); - - info->tr_running = 0; - - /* reset both dma channels */ - - *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - info->uses_dma = 0; + /* disable interrupts, reset dma channels */ + if (info->uses_dma_in) { + e100_disable_rxdma_irq(info); + *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + info->uses_dma_in = 0; + } else { + e100_disable_serial_data_irq(info); + } + + if (info->uses_dma_out) { + e100_disable_txdma_irq(info); + info->tr_running = 0; + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + info->uses_dma_out = 0; + } else { + e100_disable_serial_tx_ready_irq(info); + info->tr_running = 0; + } #endif /* CONFIG_SVINTO_SIM */ @@ -2435,7 +3544,7 @@ { unsigned int cflag; unsigned long xoff; - + unsigned long flags; /* first some safety checks */ if (!info->tty || !info->tty->termios) @@ -2444,17 +3553,80 @@ return; cflag = info->tty->termios->c_cflag; - + /* possibly, the tx/rx should be disabled first to do this safely */ /* change baud-rate and write it to the hardware */ - - info->baud = cflag_to_baud(cflag); + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { + /* Special baudrate */ + u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ + unsigned long alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal); + /* R_ALT_SER_BAUDRATE selects the source */ + DBAUD(printk("Custom baudrate: baud_base/divisor %lu/%i\n", + (unsigned long)info->baud_base, info->custom_divisor)); + if (info->baud_base == SERIAL_PRESCALE_BASE) { + /* 0, 2-65535 (0=65536) */ + u16 divisor = info->custom_divisor; + /* R_SERIAL_PRESCALE (upper 16 bits of R_CLOCK_PRESCALE) */ + /* baudrate is 3.125MHz/custom_divisor */ + alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, prescale) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, prescale); + alt_source = 0x11; + DBAUD(printk("Writing SERIAL_PRESCALE: divisor %i\n", divisor)); + *R_SERIAL_PRESCALE = divisor; + info->baud = SERIAL_PRESCALE_BASE/divisor; + } +#ifdef CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED + else if ((info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8 && + info->custom_divisor == 1) || + (info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ && + info->custom_divisor == 8)) { + /* ext_clk selected */ + alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, extern) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, extern); + DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8)); + info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8; + } + } +#endif + else + { + /* Bad baudbase, we don't support using timer0 + * for baudrate. + */ + printk(KERN_WARNING "Bad baud_base/custom_divisor: %lu/%i\n", + (unsigned long)info->baud_base, info->custom_divisor); + } + r_alt_ser_baudrate_shadow &= ~mask; + r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8)); + *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow; + } else { + /* Normal baudrate */ + /* Make sure we use normal baudrate */ + u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ + unsigned long alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal); + r_alt_ser_baudrate_shadow &= ~mask; + r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8)); +#ifndef CONFIG_SVINTO_SIM + *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow; +#endif /* CONFIG_SVINTO_SIM */ + + info->baud = cflag_to_baud(cflag); +#ifndef CONFIG_SVINTO_SIM + info->port[REG_BAUD] = cflag_to_etrax_baud(cflag); +#endif /* CONFIG_SVINTO_SIM */ + } #ifndef CONFIG_SVINTO_SIM - info->port[REG_BAUD] = cflag_to_etrax_baud(cflag); /* start with default settings and then fill in changes */ - + save_flags(flags); + cli(); /* 8 bit, no/even parity */ info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) | IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) | @@ -2484,14 +3656,26 @@ info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); } - if (cflag & PARODD) { - /* set odd parity */ - info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); - info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); + if (cflag & CMSPAR) { + /* enable stick parity */ + info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, stick); + info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, stick); + if (!(cflag & PARODD)) { + /* set mark parity */ + info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); + info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); + } + } else { + if (cflag & PARODD) { + /* set odd parity */ + info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); + info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); + } } if (cflag & CRTSCTS) { /* enable automatic CTS handling */ + DFLOW(DEBUG_LOG(info->line, "FLOW auto_cts enabled\n", 0)); info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, active); } @@ -2507,10 +3691,12 @@ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty)); xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); if (info->tty->termios->c_iflag & IXON ) { + DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", STOP_CHAR(info->tty))); xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); } *((unsigned long *)&info->port[REG_XOFF]) = xoff; + restore_flags(flags); #endif /* !CONFIG_SVINTO_SIM */ update_char_time(info); @@ -2543,8 +3729,8 @@ restore_flags(flags); } -extern inline int -raw_write(struct tty_struct * tty, int from_user, +extern _INLINE_ int +rs_raw_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { int c, ret = 0; @@ -2558,7 +3744,7 @@ #ifdef SERIAL_DEBUG_DATA if (info->line == SERIAL_DEBUG_LINE) - printk("raw_write (%d), status %d\n", + printk("rs_raw_write (%d), status %d\n", count, info->port[REG_STATUS]); #endif @@ -2568,6 +3754,9 @@ return count; #endif save_flags(flags); + + DFLOW(DEBUG_LOG(info->line, "write count %i ", count)); + DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty))); /* the cli/restore_flags pairs below are needed because the * DMA interrupt handler moves the info->xmit values. the memcpy @@ -2635,6 +3824,7 @@ * this does not need IRQ protection since if tr_running == 0 * the IRQ's are not running anyway for this port. */ + DFLOW(DEBUG_LOG(info->line, "write ret %i\n", ret)); if (info->xmit.head != info->xmit.tail && !tty->stopped && @@ -2644,7 +3834,7 @@ } return ret; -} /* raw_write() */ +} /* rs_raw_write() */ static int rs_write(struct tty_struct * tty, int from_user, @@ -2666,7 +3856,7 @@ e100_rts(info, info->rs485.rts_on_send); #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) e100_disable_rx(info); - e100_disable_rxdma_irq(info); + e100_disable_rx_irq(info); #endif if (info->rs485.delay_rts_before_send > 0) { @@ -2676,7 +3866,7 @@ } #endif /* CONFIG_ETRAX_RS485 */ - count = raw_write(tty, from_user, buf, count); + count = rs_raw_write(tty, from_user, buf, count); #if defined(CONFIG_ETRAX_RS485) if (info->rs485.enabled) @@ -2704,7 +3894,7 @@ #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) e100_enable_rx(info); - e100_enable_rxdma_irq(info); + e100_enable_rx_irq(info); #endif } #endif /* CONFIG_ETRAX_RS485 */ @@ -2760,20 +3950,33 @@ * This function is used to send a high-priority XON/XOFF character to * the device * - * Since we don't bother to check for info->x_char in transmit_chars yet, - * we don't really implement this function yet. + * Since we use DMA we don't check for info->x_char in transmit_chars_dma(), + * but we do it in handle_ser_tx_interrupt(). + * We disable DMA channel and enable tx ready interrupt and write the + * character when possible. */ static void rs_send_xchar(struct tty_struct *tty, char ch) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; + unsigned long flags; + save_flags(flags); cli(); + if (info->uses_dma_out) { + /* Put the DMA on hold and disable the channel */ + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, hold); + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) != + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, hold)); + e100_disable_txdma_channel(info); + } + + /* Must make sure transmitter is not stopped before we can transmit */ + if (tty->stopped) + rs_start(tty); - printk("serial.c:rs_send_xchar not implemented!\n"); - + /* Enable manual transmit interrupt and send from there */ + DFLOW(DEBUG_LOG(info->line, "rs_send_xchar 0x%02X\n", ch)); info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - /* TODO. */ - } + e100_enable_serial_tx_ready_irq(info); + restore_flags(flags); } /* @@ -2788,50 +3991,49 @@ rs_throttle(struct tty_struct * tty) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; - unsigned long flags; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - printk("throttle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); + printk("throttle %s: %lu....\n", tty_name(tty, buf), + (unsigned long)tty->ldisc.chars_in_buffer(tty)); #endif - + DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); + + /* Do RTS before XOFF since XOFF might take some time */ + if (tty->termios->c_cflag & CRTSCTS) { + /* Turn off RTS line */ + e100_rts(info, 0); + } if (I_IXOFF(tty)) - info->x_char = STOP_CHAR(tty); + rs_send_xchar(tty, STOP_CHAR(tty)); - /* Turn off RTS line (do this atomic) should here be an else ?? */ - - save_flags(flags); - cli(); - e100_rts(info, 0); - restore_flags(flags); } static void rs_unthrottle(struct tty_struct * tty) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; - unsigned long flags; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - printk("unthrottle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); + printk("unthrottle %s: %lu....\n", tty_name(tty, buf), + (unsigned long)tty->ldisc.chars_in_buffer(tty)); #endif + DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); + DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); + /* Do RTS before XOFF since XOFF might take some time */ + if (tty->termios->c_cflag & CRTSCTS) { + /* Assert RTS line */ + e100_rts(info, 1); + } if (I_IXOFF(tty)) { if (info->x_char) info->x_char = 0; else - info->x_char = START_CHAR(tty); + rs_send_xchar(tty, START_CHAR(tty)); } - /* Assert RTS line (do this atomic) */ - - save_flags(flags); - cli(); - e100_rts(info, 1); - restore_flags(flags); } /* @@ -2859,8 +4061,10 @@ tmp.port = (int)info->port; tmp.irq = info->irq; tmp.flags = info->flags; + tmp.baud_base = info->baud_base; tmp.close_delay = info->close_delay; tmp.closing_wait = info->closing_wait; + tmp.custom_divisor = info->custom_divisor; if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) return -EFAULT; return 0; @@ -2897,9 +4101,11 @@ * OK, past this point, all the error checking has been done. * At this point, we start making changes..... */ - + + info->baud_base = new_serial.baud_base; info->flags = ((info->flags & ~ASYNC_FLAGS) | (new_serial.flags & ASYNC_FLAGS)); + info->custom_divisor = new_serial.custom_divisor; info->type = new_serial.type; info->close_delay = new_serial.close_delay; info->closing_wait = new_serial.closing_wait; @@ -3098,18 +4304,20 @@ info->tx_ctrl &= 0x3F; /* Clear bit 7 (txd) and 6 (tr_enable) */ info->port[REG_TR_CTRL] = info->tx_ctrl; - + restore_flags(flags); /* wait for "duration" jiffies */ schedule(); + cli(); info->tx_ctrl |= (0x80 | 0x40); /* Set bit 7 (txd) and 6 (tr_enable) */ info->port[REG_TR_CTRL] = info->tx_ctrl; /* the DMA gets awfully confused if we toggle the tranceiver like this * so we need to reset it */ - *info->ocmdadr = 4; + if (info->uses_dma_out) + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); restore_flags(flags); } @@ -3252,6 +4460,7 @@ change_speed(info); + /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { tty->hw_stopped = 0; @@ -3301,12 +4510,13 @@ * one, we've got real problems, since it means the * serial port won't be shutdown. */ - printk("rs_close: bad serial port count; tty->count is 1, " + printk(KERN_CRIT + "rs_close: bad serial port count; tty->count is 1, " "info->count is %d\n", info->count); info->count = 1; } if (--info->count < 0) { - printk("rs_close: bad serial port count for ttyS%d: %d\n", + printk(KERN_CRIT "rs_close: bad serial port count for ttyS%d: %d\n", info->line, info->count); info->count = 0; } @@ -3340,7 +4550,7 @@ #ifndef CONFIG_SVINTO_SIM e100_disable_rx(info); - e100_disable_rxdma_irq(info); + e100_disable_rx_irq(info); if (info->flags & ASYNC_INITIALIZED) { /* @@ -3676,6 +4886,12 @@ #ifdef SERIAL_DEBUG_OPEN printk("rs_open ttyS%d successful...\n", info->line); #endif + DLOG_INT_TRIG( log_int_pos = 0); + + DFLIP( if (info->line == SERIAL_DEBUG_LINE) { + info->icount.rx = 0; + } ); + return 0; } @@ -3683,11 +4899,12 @@ * /proc fs routines.... */ -extern inline int line_info(char *buf, struct e100_serial *info) +extern _INLINE_ int line_info(char *buf, struct e100_serial *info) { char stat_buf[30]; int ret; - + unsigned long tmp; + ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d", info->line, (unsigned long)info->port, info->irq); @@ -3716,11 +4933,39 @@ ret += sprintf(buf+ret, " tx:%lu rx:%lu", (unsigned long)info->icount.tx, (unsigned long)info->icount.rx); - + tmp = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + if (tmp) { + ret += sprintf(buf+ret, " tx_pend:%lu/%lu", + (unsigned long)tmp, + (unsigned long)SERIAL_XMIT_SIZE); + } + ret += sprintf(buf+ret, " rx_pend:%lu/%lu", (unsigned long)info->recv_cnt, (unsigned long)info->max_recv_cnt); +#if 1 + if (info->tty) { + + if (info->tty->stopped) + ret += sprintf(buf+ret, " stopped:%i", + (int)info->tty->stopped); + if (info->tty->hw_stopped) + ret += sprintf(buf+ret, " hw_stopped:%i", + (int)info->tty->hw_stopped); + } + + { + unsigned char rstat = info->port[REG_STATUS]; + if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) + ret += sprintf(buf+ret, " xoff_detect:1"); + } + +#endif + + + + if (info->icount.frame) ret += sprintf(buf+ret, " fe:%lu", (unsigned long)info->icount.frame); @@ -3744,12 +4989,14 @@ return ret; } + + int rs_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { int i, len = 0, l; off_t begin = 0; - + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); for (i = 0; i < NR_PORTS && len < 4000; i++) { @@ -3764,6 +5011,22 @@ len = 0; } } +#ifdef DEBUG_LOG_INCLUDED + for (i = 0; i < debug_log_pos; i++) { + len += sprintf(page + len, "%-4i %lu.%lu ", i, debug_log[i].time, timer_data_to_ns(debug_log[i].timer_data)); + len += sprintf(page + len, debug_log[i].string, debug_log[i].value); + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + len += sprintf(page + len, "debug_log %i/%i %li bytes\n", + i, DEBUG_LOG_SIZE, begin+len); + debug_log_pos = 0; +#endif + *eof = 1; done: if (off >= len+begin) @@ -3777,7 +5040,8 @@ static void show_serial_version(void) { - printk("ETRAX 100LX serial-driver %s, (c) 2000-2002 Axis Communications AB\r\n", + printk(KERN_INFO + "ETRAX 100LX serial-driver %s, (c) 2000-2003 Axis Communications AB\r\n", &serial_version[11]); /* "$Revision: x.yy" */ } @@ -3794,7 +5058,7 @@ init_bh(SERIAL_BH, do_serial_bh); /* Setup the timed flush handler system */ - + #if !defined(CONFIG_ETRAX_SERIAL_FAST_TIMER) && !defined(CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST) init_timer(&flush_timer); flush_timer.function = timed_flush_handler; @@ -3868,12 +5132,15 @@ /* do some initializing for the separate ports */ for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { - info->uses_dma = 0; + info->uses_dma_in = 0; + info->uses_dma_out = 0; info->line = i; info->tty = 0; info->type = PORT_ETRAX; info->tr_running = 0; info->forced_eop = 0; + info->baud_base = DEF_BAUD_BASE; + info->custom_divisor = 0; info->flags = 0; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; @@ -3920,41 +5187,58 @@ #ifndef CONFIG_SVINTO_SIM /* Not needed in simulator. May only complicate stuff. */ /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */ + + if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL)) + panic("irq8"); + #ifdef CONFIG_ETRAX_SERIAL_PORT0 +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT if (request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL)) panic("irq22"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN if (request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL)) panic("irq23"); #endif -#ifdef SERIAL_HANDLE_EARLY_ERRORS - if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL)) - panic("irq8"); #endif + #ifdef CONFIG_ETRAX_SERIAL_PORT1 +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT if (request_irq(SER1_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL)) panic("irq24"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN if (request_irq(SER1_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL)) panic("irq25"); #endif +#endif #ifdef CONFIG_ETRAX_SERIAL_PORT2 /* DMA Shared with par0 (and SCSI0 and ATA) */ - if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL)) +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT + if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 2 dma tr", NULL)) panic("irq18"); - if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL)) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 2 dma rec", NULL)) panic("irq19"); #endif +#endif #ifdef CONFIG_ETRAX_SERIAL_PORT3 /* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */ - if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL)) +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT + if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 3 dma tr", NULL)) panic("irq20"); - if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL)) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 3 dma rec", NULL)) panic("irq21"); #endif +#endif #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST if (request_irq(TIMER1_IRQ_NBR, timeout_interrupt, SA_SHIRQ | SA_INTERRUPT, "fast serial dma timeout", NULL)) { - printk("err: timer1 irq\n"); + printk(KERN_CRIT "err: timer1 irq\n"); } #endif #endif /* CONFIG_SVINTO_SIM */ diff -urN linux-2.4.21/arch/cris/drivers/serial.h linux-2.4.22/arch/cris/drivers/serial.h --- linux-2.4.21/arch/cris/drivers/serial.h 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/serial.h 2003-08-25 04:44:39.000000000 -0700 @@ -23,7 +23,7 @@ * For definitions of the flags field, see tty.h */ -#define SERIAL_RECV_DESCRIPTORS 8 +#define SERIAL_RECV_DESCRIPTORS 16 struct etrax_recv_buffer { struct etrax_recv_buffer *next; @@ -44,30 +44,29 @@ volatile u32 *ofirstadr; /* adr to R_DMA_CHx_FIRST */ volatile u8 *ocmdadr; /* adr to R_DMA_CHx_CMD */ const volatile u8 *ostatusadr; /* adr to R_DMA_CHx_STATUS */ - volatile u32 *ohwswadr; /* adr to R_DMA_CHx_HWSW */ - volatile u32 *odescradr; /* adr to R_DMA_CHx_DESCR */ /* Input registers */ volatile u8 *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ volatile u32 *ifirstadr; /* adr to R_DMA_CHx_FIRST */ volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ - const volatile u8 *istatusadr; /* adr to R_DMA_CHx_STATUS */ - volatile u32 *ihwswadr; /* adr to R_DMA_CHx_HWSW */ volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ int flags; /* defined in tty.h */ - u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ - u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ - u8 iseteop; /* bit number for R_SET_EOP for the input dma */ - - int enabled; /* Set to 1 if the port is enabled in HW config */ - + u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ + u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ + u8 iseteop; /* bit number for R_SET_EOP for the input dma */ + u8 enabled; /* Set to 1 if the port is enabled in HW config */ + + u8 dma_out_enabled:1; /* Set to 1 if DMA should be used */ + u8 dma_in_enabled:1; /* Set to 1 if DMA should be used */ + /* end of fields defined in rs_table[] in .c-file */ - - int uses_dma; /* Set to 1 if DMA should be used */ - unsigned char forced_eop; /* a fifo eop has been forced */ - + u8 uses_dma_in; /* Set to 1 if DMA is used */ + u8 uses_dma_out; /* Set to 1 if DMA is used */ + u8 forced_eop; /* a fifo eop has been forced */ + int baud_base; /* For special baudrates */ + int custom_divisor; /* For special baudrates */ struct etrax_dma_descr tr_descr; struct etrax_dma_descr rec_descr[SERIAL_RECV_DESCRIPTORS]; int cur_rec_descr; @@ -108,6 +107,7 @@ #endif unsigned long char_time_usec; /* The time for 1 char, in usecs */ + unsigned long flush_time_usec; /* How often we should flush */ unsigned long last_tx_active_usec; /* Last tx usec in the jiffies */ unsigned long last_tx_active; /* Last tx time in jiffies */ unsigned long last_rx_active_usec; /* Last rx usec in the jiffies */ diff -urN linux-2.4.21/arch/cris/drivers/sync_serial.c linux-2.4.22/arch/cris/drivers/sync_serial.c --- linux-2.4.21/arch/cris/drivers/sync_serial.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/sync_serial.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * Simple synchronous serial port driver for ETRAX 100LX. * - * Synchronous serial ports are used for continous streamed data like audio. + * Synchronous serial ports are used for continuous streamed data like audio. * The default setting for this driver is compatible with the STA 013 MP3 * decoder. The driver can easily be tuned to fit other audio encoder/decoders * and SPI @@ -29,7 +29,7 @@ #include #include -/* The receiver is a bit tricky beacuse of the continous stream of data. */ +/* The receiver is a bit tricky beacuse of the continuous stream of data.*/ /* */ /* Two DMA descriptors are linked together. Each DMA descriptor is */ /* responsible for one half of a common buffer. */ @@ -256,7 +256,7 @@ initialize_port(1); if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */ { - if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1])) + if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1])) panic("Can't allocate sync serial manual irq"); } #endif diff -urN linux-2.4.21/arch/cris/drivers/usb-host.c linux-2.4.22/arch/cris/drivers/usb-host.c --- linux-2.4.21/arch/cris/drivers/usb-host.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/cris/drivers/usb-host.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,10 +1,7 @@ /* * usb-host.c: ETRAX 100LX USB Host Controller Driver (HCD) * - * Copyright (c) 2001 Axis Communications AB. - * - * $Id: usb-host.c,v 1.13 2001/11/13 12:06:17 pkj Exp $ - * + * Copyright (c) 2002, 2003 Axis Communications AB. */ #include @@ -19,6 +16,7 @@ #include #include #include +#include #include #include @@ -28,24 +26,37 @@ #include #include +/* Ugly include because we don't live with the other host drivers. */ +#include <../drivers/usb/hcd.h> + +#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 4, 20) +typedef struct urb urb_t, *purb_t; +typedef struct iso_packet_descriptor iso_packet_descriptor_t; +typedef struct usb_ctrlrequest devrequest; +#endif + #include "usb-host.h" #define ETRAX_USB_HC_IRQ USB_HC_IRQ_NBR #define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR #define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR -static const char *usb_hcd_version = "$Revision: 1.13 $"; +static const char *usb_hcd_version = "$Revision: 1.18 $"; #undef KERN_DEBUG #define KERN_DEBUG "" + #undef USB_DEBUG_RH -#undef USB_DEBUG_EP +#undef USB_DEBUG_EPID +#undef USB_DEBUG_SB #undef USB_DEBUG_DESC +#undef USB_DEBUG_URB #undef USB_DEBUG_TRACE -#undef USB_DEBUG_CTRL #undef USB_DEBUG_BULK +#undef USB_DEBUG_CTRL #undef USB_DEBUG_INTR +#undef USB_DEBUG_ISOC #ifdef USB_DEBUG_RH #define dbg_rh(format, arg...) printk(KERN_DEBUG __FILE__ ": (RH) " format "\n" , ## arg) @@ -53,10 +64,16 @@ #define dbg_rh(format, arg...) do {} while (0) #endif -#ifdef USB_DEBUG_EP -#define dbg_ep(format, arg...) printk(KERN_DEBUG __FILE__ ": (EP) " format "\n" , ## arg) +#ifdef USB_DEBUG_EPID +#define dbg_epid(format, arg...) printk(KERN_DEBUG __FILE__ ": (EPID) " format "\n" , ## arg) #else -#define dbg_ep(format, arg...) do {} while (0) +#define dbg_epid(format, arg...) do {} while (0) +#endif + +#ifdef USB_DEBUG_SB +#define dbg_sb(format, arg...) printk(KERN_DEBUG __FILE__ ": (SB) " format "\n" , ## arg) +#else +#define dbg_sb(format, arg...) do {} while (0) #endif #ifdef USB_DEBUG_CTRL @@ -77,6 +94,12 @@ #define dbg_intr(format, arg...) do {} while (0) #endif +#ifdef USB_DEBUG_ISOC +#define dbg_isoc(format, arg...) printk(KERN_DEBUG __FILE__ ": (ISOC) " format "\n" , ## arg) +#else +#define dbg_isoc(format, arg...) do {} while (0) +#endif + #ifdef USB_DEBUG_TRACE #define DBFENTER (printk(KERN_DEBUG __FILE__ ": Entering: " __FUNCTION__ "\n")) #define DBFEXIT (printk(KERN_DEBUG __FILE__ ": Exiting: " __FUNCTION__ "\n")) @@ -85,6 +108,7 @@ #define DBFEXIT do {} while (0) #endif + /*------------------------------------------------------------------- Virtual Root Hub -------------------------------------------------------------------*/ @@ -158,78 +182,262 @@ 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ }; +static struct timer_list bulk_start_timer; +static struct timer_list bulk_eot_timer; +/* We want the start timer to expire before the eot timer, because the former might start + traffic, thus making it unnecessary for the latter to time out. */ +#define BULK_START_TIMER_INTERVAL (HZ/10) /* 100 ms */ +#define BULK_EOT_TIMER_INTERVAL (HZ/10+2) /* 120 ms */ #define OK(x) len = (x); dbg_rh("OK(%d): line: %d", x, __LINE__); break #define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \ {panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);} -static unsigned long submit_urb_count = 0; +#define SLAB_FLAG (in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL) +#define KMALLOC_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) + +/* Most helpful debugging aid */ +#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__)))) -//#define ETRAX_USB_INTR_IRQ -//#define ETRAX_USB_INTR_ERROR_FATAL +/* Alternative assert define which stops after a failed assert. */ +/* +#define assert(expr) \ +{ \ + if (!(expr)) { \ + err("assert failed at line %d",__LINE__); \ + while (1); \ + } \ +} +*/ -#define RX_BUF_SIZE 32768 -#define RX_DESC_BUF_SIZE 64 -#define NBR_OF_RX_DESC (RX_BUF_SIZE / RX_DESC_BUF_SIZE) -#define NBR_OF_EP_DESC 32 +/* FIXME: Should RX_BUF_SIZE be a config option, or maybe we should adjust it dynamically? + To adjust it dynamically we would have to get an interrupt when we reach the end + of the rx descriptor list, or when we get close to the end, and then allocate more + descriptors. */ + +#define NBR_OF_RX_DESC 512 +#define RX_DESC_BUF_SIZE 1024 +#define RX_BUF_SIZE (NBR_OF_RX_DESC * RX_DESC_BUF_SIZE) + +/* The number of epids is, among other things, used for pre-allocating + ctrl, bulk and isoc EP descriptors (one for each epid). + Assumed to be > 1 when initiating the DMA lists. */ +#define NBR_OF_EPIDS 32 +/* Support interrupt traffic intervals up to 128 ms. */ #define MAX_INTR_INTERVAL 128 -static __u32 ep_usage_bitmask; -static __u32 ep_really_active; -static __u32 ep_out_traffic; - -static unsigned char RxBuf[RX_BUF_SIZE]; -static USB_IN_Desc_t RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4))); +/* If periodic traffic (intr or isoc) is to be used, then one entry in the EP table + must be "invalid". By this we mean that we shouldn't care about epid attentions + for this epid, or at least handle them differently from epid attentions for "valid" + epids. This define determines which one to use (don't change it). */ +#define INVALID_EPID 31 +/* A special epid for the bulk dummys. */ +#define DUMMY_EPID 30 + +/* This is just a software cache for the valid entries in R_USB_EPT_DATA. */ +static __u32 epid_usage_bitmask; + +/* A bitfield to keep information on in/out traffic is needed to uniquely identify + an endpoint on a device, since the most significant bit which indicates traffic + direction is lacking in the ep_id field (ETRAX epids can handle both in and + out traffic on endpoints that are otherwise identical). The USB framework, however, + relies on them to be handled separately. For example, bulk IN and OUT urbs cannot + be queued in the same list, since they would block each other. */ +static __u32 epid_out_traffic; + +/* DMA IN cache bug. Align the DMA IN buffers to 32 bytes, i.e. a cache line. + Since RX_DESC_BUF_SIZE is 1024 is a multiple of 32, all rx buffers will be cache aligned. */ +static volatile unsigned char RxBuf[RX_BUF_SIZE] __attribute__ ((aligned (32))); +static volatile USB_IN_Desc_t RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4))); +/* Pointers into RxDescList. */ static volatile USB_IN_Desc_t *myNextRxDesc; static volatile USB_IN_Desc_t *myLastRxDesc; static volatile USB_IN_Desc_t *myPrevRxDesc; -static USB_EP_Desc_t TxCtrlEPList[NBR_OF_EP_DESC] __attribute__ ((aligned (4))); -static USB_EP_Desc_t TxBulkEPList[NBR_OF_EP_DESC] __attribute__ ((aligned (4))); +/* EP descriptors must be 32-bit aligned. */ +static volatile USB_EP_Desc_t TxCtrlEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4))); +static volatile USB_EP_Desc_t TxBulkEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4))); +/* After each enabled bulk EP (IN or OUT) we put two disabled EP descriptors with the eol flag set, + causing the DMA to stop the DMA channel. The first of these two has the intr flag set, which + gives us a dma8_sub0_descr interrupt. When we receive this, we advance the DMA one step in the + EP list and then restart the bulk channel, thus forcing a switch between bulk EP descriptors + in each frame. */ +static volatile USB_EP_Desc_t TxBulkDummyEPList[NBR_OF_EPIDS][2] __attribute__ ((aligned (4))); + +static volatile USB_EP_Desc_t TxIsocEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4))); +static volatile USB_SB_Desc_t TxIsocSB_zout __attribute__ ((aligned (4))); + +static volatile USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4))); +static volatile USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4))); + +/* A zout transfer makes a memory access at the address of its buf pointer, which means that setting + this buf pointer to 0 will cause an access to the flash. In addition to this, setting sw_len to 0 + results in a 16/32 bytes (depending on DMA burst size) transfer. Instead, we set it to 1, and point + it to this buffer. */ +static int zout_buffer[4] __attribute__ ((aligned (4))); -static USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4))); -static USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4))); - -static struct urb *URB_List[NBR_OF_EP_DESC]; +/* Cache for allocating new EP and SB descriptors. */ static kmem_cache_t *usb_desc_cache; + +/* Cache for the registers allocated in the top half. */ +static kmem_cache_t *top_half_reg_cache; + static struct usb_bus *etrax_usb_bus; -#ifdef USB_DEBUG_DESC -static void dump_urb (struct urb *urb); -#endif +/* This is a circular (double-linked) list of the active urbs for each epid. + The head is never removed, and new urbs are linked onto the list as + urb_entry_t elements. Don't reference urb_list directly; use the wrapper + functions instead. Note that working with these lists might require spinlock + protection. */ +static struct list_head urb_list[NBR_OF_EPIDS]; + +/* Read about the need and usage of this lock in submit_ctrl_urb. */ +static spinlock_t urb_list_lock; + +/* Used when unlinking asynchronously. */ +static struct list_head urb_unlink_list; + +/* Wrappers around the list functions (include/linux/list.h). */ + +static inline int urb_list_empty(int epid) +{ + return list_empty(&urb_list[epid]); +} + +/* Returns first urb for this epid, or NULL if list is empty. */ +static inline urb_t *urb_list_first(int epid) +{ + urb_t *first_urb = 0; + + if (!urb_list_empty(epid)) { + /* Get the first urb (i.e. head->next). */ + urb_entry_t *urb_entry = list_entry((&urb_list[epid])->next, urb_entry_t, list); + first_urb = urb_entry->urb; + } + return first_urb; +} + +/* Adds an urb_entry last in the list for this epid. */ +static inline void urb_list_add(urb_t *urb, int epid) +{ + urb_entry_t *urb_entry = (urb_entry_t *)kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG); + assert(urb_entry); + + urb_entry->urb = urb; + list_add_tail(&urb_entry->list, &urb_list[epid]); +} + +/* Search through the list for an element that contains this urb. (The list + is expected to be short and the one we are about to delete will often be + the first in the list.) */ +static inline urb_entry_t *__urb_list_entry(urb_t *urb, int epid) +{ + struct list_head *entry; + struct list_head *tmp; + urb_entry_t *urb_entry; + + list_for_each_safe(entry, tmp, &urb_list[epid]) { + urb_entry = list_entry(entry, urb_entry_t, list); + assert(urb_entry); + assert(urb_entry->urb); + + if (urb_entry->urb == urb) { + return urb_entry; + } + } + return 0; +} + +/* Delete an urb from the list. */ +static inline void urb_list_del(urb_t *urb, int epid) +{ + urb_entry_t *urb_entry = __urb_list_entry(urb, epid); + assert(urb_entry); + + /* Delete entry and free. */ + list_del(&urb_entry->list); + kfree(urb_entry); +} + +/* Move an urb to the end of the list. */ +static inline void urb_list_move_last(urb_t *urb, int epid) +{ + urb_entry_t *urb_entry = __urb_list_entry(urb, epid); + assert(urb_entry); + + list_del(&urb_entry->list); + list_add_tail(&urb_entry->list, &urb_list[epid]); +} + +/* For debug purposes only. */ +static inline void urb_list_dump(int epid) +{ + struct list_head *entry; + struct list_head *tmp; + urb_entry_t *urb_entry; + int i = 0; + + info("Dumping urb list for epid %d", epid); + + list_for_each_safe(entry, tmp, &urb_list[epid]) { + urb_entry = list_entry(entry, urb_entry_t, list); + info(" entry %d, urb = 0x%lx", i, (unsigned long)urb_entry->urb); + } +} + static void init_rx_buffers(void); -static int etrax_rh_unlink_urb (struct urb *urb); -static void etrax_rh_send_irq(struct urb *urb); -static void etrax_rh_init_int_timer(struct urb *urb); +static int etrax_rh_unlink_urb(urb_t *urb); +static void etrax_rh_send_irq(urb_t *urb); +static void etrax_rh_init_int_timer(urb_t *urb); static void etrax_rh_int_timer_do(unsigned long ptr); -static void etrax_usb_setup_epid(int epid, char devnum, char endpoint, - char packsize, char slow, char out_traffic); -static int etrax_usb_lookup_epid(unsigned char devnum, char endpoint, - char slow, int maxp, char out_traffic); +static int etrax_usb_setup_epid(urb_t *urb); +static int etrax_usb_lookup_epid(urb_t *urb); static int etrax_usb_allocate_epid(void); static void etrax_usb_free_epid(int epid); -static void cleanup_sb(USB_SB_Desc_t *sb); -static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen); -static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen); +static int etrax_remove_from_sb_list(urb_t *urb); -static int etrax_usb_submit_ctrl_urb(struct urb *urb); +static void etrax_usb_add_to_bulk_sb_list(urb_t *urb, int epid); +static void etrax_usb_add_to_ctrl_sb_list(urb_t *urb, int epid); +static void etrax_usb_add_to_intr_sb_list(urb_t *urb, int epid); +static void etrax_usb_add_to_isoc_sb_list(urb_t *urb, int epid); + +static int etrax_usb_submit_bulk_urb(urb_t *urb); +static int etrax_usb_submit_ctrl_urb(urb_t *urb); +static int etrax_usb_submit_intr_urb(urb_t *urb); +static int etrax_usb_submit_isoc_urb(urb_t *urb); -static int etrax_usb_submit_urb(struct urb *urb); -static int etrax_usb_unlink_urb(struct urb *urb); +static int etrax_usb_submit_urb(urb_t *urb); +static int etrax_usb_unlink_urb(urb_t *urb); static int etrax_usb_get_frame_number(struct usb_device *usb_dev); static int etrax_usb_allocate_dev(struct usb_device *usb_dev); static int etrax_usb_deallocate_dev(struct usb_device *usb_dev); static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs); static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs); -static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs); +static void etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs); +static void etrax_usb_hc_interrupt_bottom_half(void *data); -static int etrax_rh_submit_urb (struct urb *urb); +/* The following is a list of interrupt handlers for the host controller interrupts we use. + They are called from etrax_usb_hc_interrupt_bottom_half. */ +static void etrax_usb_hc_isoc_eof_interrupt(void); +static void etrax_usb_hc_bulk_eot_interrupt(int timer_induced); +static void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg); +static void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg); +static void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg); + +static int etrax_rh_submit_urb (urb_t *urb); + +/* Forward declaration needed because they are used in the rx interrupt routine. */ +static void etrax_usb_complete_urb(urb_t *urb, int status); +static void etrax_usb_complete_bulk_urb(urb_t *urb, int status); +static void etrax_usb_complete_ctrl_urb(urb_t *urb, int status); +static void etrax_usb_complete_intr_urb(urb_t *urb, int status); +static void etrax_usb_complete_isoc_urb(urb_t *urb, int status); static int etrax_usb_hc_init(void); static void etrax_usb_hc_cleanup(void); @@ -243,65 +451,193 @@ etrax_usb_unlink_urb }; -#ifdef USB_DEBUG_DESC -static void dump_urb(struct urb *urb) -{ - printk("\nurb :0x%08X\n", urb); - printk("next :0x%08X\n", urb->next); - printk("dev :0x%08X\n", urb->dev); - printk("pipe :0x%08X\n", urb->pipe); - printk("status :%d\n", urb->status); - printk("transfer_flags :0x%08X\n", urb->transfer_flags); - printk("transfer_buffer :0x%08X\n", urb->transfer_buffer); - printk("transfer_buffer_length:%d\n", urb->transfer_buffer_length); - printk("actual_length :%d\n", urb->actual_length); - printk("setup_packet :0x%08X\n", urb->setup_packet); - printk("start_frame :%d\n", urb->start_frame); - printk("number_of_packets :%d\n", urb->number_of_packets); - printk("interval :%d\n", urb->interval); - printk("error_count :%d\n", urb->error_count); - printk("context :0x%08X\n", urb->context); - printk("complete :0x%08X\n\n", urb->complete); -} - -static void dump_in_desc(USB_IN_Desc_t *in) -{ - printk("\nUSB_IN_Desc at 0x%08X\n", in); - printk(" sw_len : 0x%04X (%d)\n", in->sw_len, in->sw_len); - printk(" command : 0x%04X\n", in->command); - printk(" next : 0x%08X\n", in->next); - printk(" buf : 0x%08X\n", in->buf); - printk(" hw_len : 0x%04X (%d)\n", in->hw_len, in->hw_len); - printk(" status : 0x%04X\n\n", in->status); -} - -static void dump_sb_desc(USB_SB_Desc_t *sb) -{ - printk("\nUSB_SB_Desc at 0x%08X\n", sb); - printk(" sw_len : 0x%04X (%d)\n", sb->sw_len, sb->sw_len); - printk(" command : 0x%04X\n", sb->command); - printk(" next : 0x%08X\n", sb->next); - printk(" buf : 0x%08X\n\n", sb->buf); +/* Note that these functions are always available in their "__" variants, for use in + error situations. The "__" missing variants are controlled by the USB_DEBUG_DESC/ + USB_DEBUG_URB macros. */ +static void __dump_urb(purb_t purb) +{ + printk("\nurb :0x%08lx\n", (unsigned long)purb); + printk("next :0x%08lx\n", (unsigned long)purb->next); + printk("dev :0x%08lx\n", (unsigned long)purb->dev); + printk("pipe :0x%08x\n", purb->pipe); + printk("status :%d\n", purb->status); + printk("transfer_flags :0x%08x\n", purb->transfer_flags); + printk("transfer_buffer :0x%08lx\n", (unsigned long)purb->transfer_buffer); + printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length); + printk("actual_length :%d\n", purb->actual_length); + printk("setup_packet :0x%08lx\n", (unsigned long)purb->setup_packet); + printk("start_frame :%d\n", purb->start_frame); + printk("number_of_packets :%d\n", purb->number_of_packets); + printk("interval :%d\n", purb->interval); + printk("error_count :%d\n", purb->error_count); + printk("context :0x%08lx\n", (unsigned long)purb->context); + printk("complete :0x%08lx\n\n", (unsigned long)purb->complete); +} + +static void __dump_in_desc(volatile USB_IN_Desc_t *in) +{ + printk("\nUSB_IN_Desc at 0x%08lx\n", (unsigned long)in); + printk(" sw_len : 0x%04x (%d)\n", in->sw_len, in->sw_len); + printk(" command : 0x%04x\n", in->command); + printk(" next : 0x%08lx\n", in->next); + printk(" buf : 0x%08lx\n", in->buf); + printk(" hw_len : 0x%04x (%d)\n", in->hw_len, in->hw_len); + printk(" status : 0x%04x\n\n", in->status); +} + +static void __dump_sb_desc(volatile USB_SB_Desc_t *sb) +{ + char tt = (sb->command & 0x30) >> 4; + char *tt_string; + + switch (tt) { + case 0: + tt_string = "zout"; + break; + case 1: + tt_string = "in"; + break; + case 2: + tt_string = "out"; + break; + case 3: + tt_string = "setup"; + break; + default: + tt_string = "unknown (weird)"; + } + + printk("\n USB_SB_Desc at 0x%08lx\n", (unsigned long)sb); + printk(" command : 0x%04x\n", sb->command); + printk(" rem : %d\n", (sb->command & 0x3f00) >> 8); + printk(" full : %d\n", (sb->command & 0x40) >> 6); + printk(" tt : %d (%s)\n", tt, tt_string); + printk(" intr : %d\n", (sb->command & 0x8) >> 3); + printk(" eot : %d\n", (sb->command & 0x2) >> 1); + printk(" eol : %d\n", sb->command & 0x1); + printk(" sw_len : 0x%04x (%d)\n", sb->sw_len, sb->sw_len); + printk(" next : 0x%08lx\n", sb->next); + printk(" buf : 0x%08lx\n\n", sb->buf); } -static void dump_ep_desc(USB_EP_Desc_t *ep) -{ - printk("\nUSB_EP_Desc at 0x%08X\n", ep); - printk(" hw_len : 0x%04X (%d)\n", ep->hw_len, ep->hw_len); - printk(" command : 0x%08X\n", ep->command); - printk(" sub : 0x%08X\n", ep->sub); - printk(" nep : 0x%08X\n\n", ep->nep); +static void __dump_ep_desc(volatile USB_EP_Desc_t *ep) +{ + printk("\nUSB_EP_Desc at 0x%08lx\n", (unsigned long)ep); + printk(" command : 0x%04x\n", ep->command); + printk(" ep_id : %d\n", (ep->command & 0x1f00) >> 8); + printk(" enable : %d\n", (ep->command & 0x10) >> 4); + printk(" intr : %d\n", (ep->command & 0x8) >> 3); + printk(" eof : %d\n", (ep->command & 0x2) >> 1); + printk(" eol : %d\n", ep->command & 0x1); + printk(" hw_len : 0x%04x (%d)\n", ep->hw_len, ep->hw_len); + printk(" next : 0x%08lx\n", ep->next); + printk(" sub : 0x%08lx\n\n", ep->sub); +} + +static inline void __dump_ep_list(int pipe_type) +{ + volatile USB_EP_Desc_t *ep; + volatile USB_EP_Desc_t *first_ep; + volatile USB_SB_Desc_t *sb; + + switch (pipe_type) + { + case PIPE_BULK: + first_ep = &TxBulkEPList[0]; + break; + case PIPE_CONTROL: + first_ep = &TxCtrlEPList[0]; + break; + case PIPE_INTERRUPT: + first_ep = &TxIntrEPList[0]; + break; + case PIPE_ISOCHRONOUS: + first_ep = &TxIsocEPList[0]; + break; + default: + warn("Cannot dump unknown traffic type"); + return; + } + ep = first_ep; + + printk("\n\nDumping EP list...\n\n"); + + do { + __dump_ep_desc(ep); + /* Cannot phys_to_virt on 0 as it turns into 80000000, which is != 0. */ + sb = ep->sub ? phys_to_virt(ep->sub) : 0; + while (sb) { + __dump_sb_desc(sb); + sb = sb->next ? phys_to_virt(sb->next) : 0; + } + ep = (volatile USB_EP_Desc_t *)(phys_to_virt(ep->next)); + + } while (ep != first_ep); +} + +static inline void __dump_ept_data(int epid) +{ + unsigned long flags; + __u32 r_usb_ept_data; + + if (epid < 0 || epid > 31) { + printk("Cannot dump ept data for invalid epid %d\n", epid); + return; + } + + save_flags(flags); + cli(); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + r_usb_ept_data = *R_USB_EPT_DATA; + restore_flags(flags); + + printk("\nR_USB_EPT_DATA = 0x%x for epid %d :\n", r_usb_ept_data, epid); + if (r_usb_ept_data == 0) { + /* No need for more detailed printing. */ + return; + } + printk(" valid : %d\n", (r_usb_ept_data & 0x80000000) >> 31); + printk(" hold : %d\n", (r_usb_ept_data & 0x40000000) >> 30); + printk(" error_count_in : %d\n", (r_usb_ept_data & 0x30000000) >> 28); + printk(" t_in : %d\n", (r_usb_ept_data & 0x08000000) >> 27); + printk(" low_speed : %d\n", (r_usb_ept_data & 0x04000000) >> 26); + printk(" port : %d\n", (r_usb_ept_data & 0x03000000) >> 24); + printk(" error_code : %d\n", (r_usb_ept_data & 0x00c00000) >> 22); + printk(" t_out : %d\n", (r_usb_ept_data & 0x00200000) >> 21); + printk(" error_count_out : %d\n", (r_usb_ept_data & 0x00180000) >> 19); + printk(" max_len : %d\n", (r_usb_ept_data & 0x0003f800) >> 11); + printk(" ep : %d\n", (r_usb_ept_data & 0x00000780) >> 7); + printk(" dev : %d\n", (r_usb_ept_data & 0x0000003f)); } +static inline void __dump_ept_data_list(void) +{ + int i; + printk("Dumping the whole R_USB_EPT_DATA list\n"); + + for (i = 0; i < 32; i++) { + __dump_ept_data(i); + } +} +#ifdef USB_DEBUG_DESC +#define dump_in_desc(...) __dump_in_desc(...) +#define dump_sb_desc(...) __dump_sb_desc(...) +#define dump_ep_desc(...) __dump_ep_desc(...) #else -#define dump_urb(...) do {} while (0) #define dump_in_desc(...) do {} while (0) #define dump_sb_desc(...) do {} while (0) #define dump_ep_desc(...) do {} while (0) #endif +#ifdef USB_DEBUG_URB +#define dump_urb(x) __dump_urb(x) +#else +#define dump_urb(x) do {} while (0) +#endif + static void init_rx_buffers(void) { int i; @@ -315,6 +651,11 @@ RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE)); RxDescList[i].hw_len = 0; RxDescList[i].status = 0; + + /* DMA IN cache bug. (struct etrax_dma_descr has the same layout as USB_IN_Desc + for the relevant fields.) */ + prepare_rx_descriptor((struct etrax_dma_descr*)&RxDescList[i]); + } RxDescList[i].sw_len = RX_DESC_BUF_SIZE; @@ -334,367 +675,254 @@ DBFEXIT; } -static void init_tx_ctrl_ep(void) +static void init_tx_bulk_ep(void) { int i; DBFENTER; - for (i = 0; i < (NBR_OF_EP_DESC - 1); i++) { - TxCtrlEPList[i].hw_len = 0; - TxCtrlEPList[i].command = IO_FIELD(USB_EP_command, epid, i); - TxCtrlEPList[i].sub = 0; - TxCtrlEPList[i].nep = virt_to_phys(&TxCtrlEPList[i + 1]); + for (i = 0; i < (NBR_OF_EPIDS - 1); i++) { + CHECK_ALIGN(&TxBulkEPList[i]); + TxBulkEPList[i].hw_len = 0; + TxBulkEPList[i].command = IO_FIELD(USB_EP_command, epid, i); + TxBulkEPList[i].sub = 0; + TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[i + 1]); + + /* Initiate two EPs, disabled and with the eol flag set. No need for any + preserved epid. */ + + /* The first one has the intr flag set so we get an interrupt when the DMA + channel is about to become disabled. */ + CHECK_ALIGN(&TxBulkDummyEPList[i][0]); + TxBulkDummyEPList[i][0].hw_len = 0; + TxBulkDummyEPList[i][0].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) | + IO_STATE(USB_EP_command, eol, yes) | + IO_STATE(USB_EP_command, intr, yes)); + TxBulkDummyEPList[i][0].sub = 0; + TxBulkDummyEPList[i][0].next = virt_to_phys(&TxBulkDummyEPList[i][1]); + + /* The second one. */ + CHECK_ALIGN(&TxBulkDummyEPList[i][1]); + TxBulkDummyEPList[i][1].hw_len = 0; + TxBulkDummyEPList[i][1].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) | + IO_STATE(USB_EP_command, eol, yes)); + TxBulkDummyEPList[i][1].sub = 0; + /* The last dummy's next pointer is the same as the current EP's next pointer. */ + TxBulkDummyEPList[i][1].next = virt_to_phys(&TxBulkEPList[i + 1]); } - - TxCtrlEPList[i].hw_len = 0; - TxCtrlEPList[i].command = IO_STATE(USB_EP_command, eol, yes) | - IO_FIELD(USB_EP_command, epid, i); - TxCtrlEPList[i].sub = 0; - TxCtrlEPList[i].nep = virt_to_phys(&TxCtrlEPList[0]); - - *R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[0]); - *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start); - + /* Configure the last one. */ + CHECK_ALIGN(&TxBulkEPList[i]); + TxBulkEPList[i].hw_len = 0; + TxBulkEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) | + IO_FIELD(USB_EP_command, epid, i)); + TxBulkEPList[i].sub = 0; + TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[0]); + + /* No need configuring dummy EPs for the last one as it will never be used for + bulk traffic (i == INVALD_EPID at this point). */ + + /* Set up to start on the last EP so we will enable it when inserting traffic + for the first time (imitating the situation where the DMA has stopped + because there was no more traffic). */ + *R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[i]); + /* No point in starting the bulk channel yet. + *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); */ DBFEXIT; } -static void init_tx_bulk_ep(void) +static void init_tx_ctrl_ep(void) { int i; DBFENTER; - for (i = 0; i < (NBR_OF_EP_DESC - 1); i++) { - TxBulkEPList[i].hw_len = 0; - TxBulkEPList[i].command = IO_FIELD(USB_EP_command, epid, i); - TxBulkEPList[i].sub = 0; - TxBulkEPList[i].nep = virt_to_phys(&TxBulkEPList[i + 1]); + for (i = 0; i < (NBR_OF_EPIDS - 1); i++) { + CHECK_ALIGN(&TxCtrlEPList[i]); + TxCtrlEPList[i].hw_len = 0; + TxCtrlEPList[i].command = IO_FIELD(USB_EP_command, epid, i); + TxCtrlEPList[i].sub = 0; + TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[i + 1]); } - TxBulkEPList[i].hw_len = 0; - TxBulkEPList[i].command = IO_STATE(USB_EP_command, eol, yes) | - IO_FIELD(USB_EP_command, epid, i); + CHECK_ALIGN(&TxCtrlEPList[i]); + TxCtrlEPList[i].hw_len = 0; + TxCtrlEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) | + IO_FIELD(USB_EP_command, epid, i)); - TxBulkEPList[i].sub = 0; - TxBulkEPList[i].nep = virt_to_phys(&TxBulkEPList[0]); + TxCtrlEPList[i].sub = 0; + TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[0]); - *R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[0]); - *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); + *R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[0]); + *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start); DBFEXIT; } + static void init_tx_intr_ep(void) { int i; DBFENTER; - TxIntrSB_zout.sw_len = 0; + /* Read comment at zout_buffer declaration for an explanation to this. */ + TxIntrSB_zout.sw_len = 1; TxIntrSB_zout.next = 0; - TxIntrSB_zout.buf = 0; - TxIntrSB_zout.command = IO_FIELD(USB_SB_command, rem, 0) | - IO_STATE(USB_SB_command, tt, zout) | - IO_STATE(USB_SB_command, full, yes) | - IO_STATE(USB_SB_command, eot, yes) | - IO_STATE(USB_SB_command, eol, yes); + TxIntrSB_zout.buf = virt_to_phys(&zout_buffer[0]); + TxIntrSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) | + IO_STATE(USB_SB_command, tt, zout) | + IO_STATE(USB_SB_command, full, yes) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); for (i = 0; i < (MAX_INTR_INTERVAL - 1); i++) { + CHECK_ALIGN(&TxIntrEPList[i]); TxIntrEPList[i].hw_len = 0; - TxIntrEPList[i].command = IO_STATE(USB_EP_command, eof, yes) | - IO_STATE(USB_EP_command, enable, yes) | - IO_FIELD(USB_EP_command, epid, 0); + TxIntrEPList[i].command = + (IO_STATE(USB_EP_command, eof, yes) | + IO_STATE(USB_EP_command, enable, yes) | + IO_FIELD(USB_EP_command, epid, INVALID_EPID)); TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout); - TxIntrEPList[i].nep = virt_to_phys(&TxIntrEPList[i + 1]); + TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[i + 1]); } + CHECK_ALIGN(&TxIntrEPList[i]); TxIntrEPList[i].hw_len = 0; TxIntrEPList[i].command = - IO_STATE(USB_EP_command, eof, yes) | - IO_STATE(USB_EP_command, enable, yes) | - IO_FIELD(USB_EP_command, epid, 0); + (IO_STATE(USB_EP_command, eof, yes) | + IO_STATE(USB_EP_command, eol, yes) | + IO_STATE(USB_EP_command, enable, yes) | + IO_FIELD(USB_EP_command, epid, INVALID_EPID)); TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout); - TxIntrEPList[i].nep = virt_to_phys(&TxIntrEPList[0]); + TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[0]); *R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]); *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start); - DBFEXIT; } - -static int etrax_usb_unlink_intr_urb(struct urb *urb) +static void init_tx_isoc_ep(void) { - USB_EP_Desc_t *tmp_ep; - USB_EP_Desc_t *first_ep; - - USB_EP_Desc_t *ep_desc; - - int epid; - char devnum; - char endpoint; - char slow; - int maxlen; - char out_traffic; int i; DBFENTER; - - devnum = usb_pipedevice(urb->pipe); - endpoint = usb_pipeendpoint(urb->pipe); - slow = usb_pipeslow(urb->pipe); - maxlen = usb_maxpacket(urb->dev, urb->pipe, - usb_pipeout(urb->pipe)); - out_traffic = usb_pipeout(urb->pipe); - - epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic); - if (epid == -1) { - err("Trying to unlink urb that is not in traffic queue!!"); - return -1; /* fix this */ - } - - *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, stop); - /* Somehow wait for the DMA to finish current activities */ - i = jiffies + 100; - while (jiffies < i); - first_ep = &TxIntrEPList[0]; - tmp_ep = first_ep; + /* Read comment at zout_buffer declaration for an explanation to this. */ + TxIsocSB_zout.sw_len = 1; + TxIsocSB_zout.next = 0; + TxIsocSB_zout.buf = virt_to_phys(&zout_buffer[0]); + TxIsocSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) | + IO_STATE(USB_SB_command, tt, zout) | + IO_STATE(USB_SB_command, full, yes) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); - do { - if (IO_EXTRACT(USB_EP_command, epid, ((USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep))->command) - == epid) { - /* Unlink it !!! */ - dbg_intr("Found urb to unlink for epid %d", epid); - - ep_desc = phys_to_virt(tmp_ep->nep); - tmp_ep->nep = ep_desc->nep; - kmem_cache_free(usb_desc_cache, phys_to_virt(ep_desc->sub)); - kmem_cache_free(usb_desc_cache, ep_desc); - } + /* The last isochronous EP descriptor is a dummy. */ + + for (i = 0; i < (NBR_OF_EPIDS - 1); i++) { + CHECK_ALIGN(&TxIsocEPList[i]); + TxIsocEPList[i].hw_len = 0; + TxIsocEPList[i].command = IO_FIELD(USB_EP_command, epid, i); + TxIsocEPList[i].sub = 0; + TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[i + 1]); + } - tmp_ep = phys_to_virt(tmp_ep->nep); - - } while (tmp_ep != first_ep); + CHECK_ALIGN(&TxIsocEPList[i]); + TxIsocEPList[i].hw_len = 0; - /* We should really try to move the EP register to an EP that is not removed - instead of restarting, but this will work too */ - *R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]); - *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start); + /* Must enable the last EP descr to get eof interrupt. */ + TxIsocEPList[i].command = (IO_STATE(USB_EP_command, enable, yes) | + IO_STATE(USB_EP_command, eof, yes) | + IO_STATE(USB_EP_command, eol, yes) | + IO_FIELD(USB_EP_command, epid, INVALID_EPID)); + TxIsocEPList[i].sub = virt_to_phys(&TxIsocSB_zout); + TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[0]); - clear_bit(epid, (void *)&ep_really_active); - URB_List[epid] = NULL; - etrax_usb_free_epid(epid); + *R_DMA_CH8_SUB3_EP = virt_to_phys(&TxIsocEPList[0]); + *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start); DBFEXIT; - - return 0; } -void etrax_usb_do_intr_recover(int epid) +static void etrax_usb_unlink_intr_urb(urb_t *urb) { - USB_EP_Desc_t *first_ep, *tmp_ep; - - first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP); - tmp_ep = first_ep; - - do { - if (IO_EXTRACT(USB_EP_command, epid, tmp_ep->command) == epid && - !(tmp_ep->command & IO_MASK(USB_EP_command, enable))) { - tmp_ep->command |= IO_STATE(USB_EP_command, enable, yes); - } - - tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep); - - } while (tmp_ep != first_ep); -} + volatile USB_EP_Desc_t *first_ep; /* First EP in the list. */ + volatile USB_EP_Desc_t *curr_ep; /* Current EP, the iterator. */ + volatile USB_EP_Desc_t *next_ep; /* The EP after current. */ + volatile USB_EP_Desc_t *unlink_ep; /* The one we should remove from the list. */ -static int etrax_usb_submit_intr_urb(struct urb *urb) -{ - USB_EP_Desc_t *tmp_ep; - USB_EP_Desc_t *first_ep; - int epid; - char devnum; - char endpoint; - char maxlen; - char out_traffic; - char slow; - int interval; - int i; - - etrax_urb_priv_t *urb_priv; - - DBFENTER; - - devnum = usb_pipedevice(urb->pipe); - endpoint = usb_pipeendpoint(urb->pipe); - maxlen = usb_maxpacket(urb->dev, urb->pipe, - usb_pipeout(urb->pipe)); - out_traffic = usb_pipeout(urb->pipe); - slow = usb_pipeslow(urb->pipe); - interval = urb->interval; + /* Read 8.8.4 in Designer's Reference, "Removing an EP Descriptor from the List". */ - dbg_intr("Intr traffic for dev %d, endpoint %d, maxlen %d, slow %d", - devnum, endpoint, maxlen, slow); - - epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic); - if (epid == -1) { - epid = etrax_usb_allocate_epid(); - if (epid == -1) { - /* We're out of endpoints, return some error */ - err("We're out of endpoints"); - return -ENOMEM; - } - /* Now we have to fill in this ep */ - etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow, out_traffic); - } - /* Ok, now we got valid endpoint, lets insert some traffic */ + DBFENTER; - urb_priv = (etrax_urb_priv_t *)kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL); - urb_priv->first_sb = 0; - urb_priv->rx_offset = 0; - urb_priv->eot = 0; - INIT_LIST_HEAD(&urb_priv->ep_in_list); - urb->hcpriv = urb_priv; + epid = ((etrax_urb_priv_t *)urb->hcpriv)->epid; - /* This is safe since there cannot be any other URB's for this epid */ - URB_List[epid] = urb; -#if 0 - first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP); -#else first_ep = &TxIntrEPList[0]; -#endif + curr_ep = first_ep; + - /* Round of the interval to 2^n, it is obvious that this code favours - smaller numbers, but that is actually a good thing */ - for (i = 0; interval; i++) { - interval = interval >> 1; - } + /* Note that this loop removes all EP descriptors with this epid. This assumes + that all EP descriptors belong to the one and only urb for this epid. */ - urb->interval = interval = 1 << (i - 1); + do { + next_ep = (USB_EP_Desc_t *)phys_to_virt(curr_ep->next); - dbg_intr("Interval rounded to %d", interval); + if (IO_EXTRACT(USB_EP_command, epid, next_ep->command) == epid) { - tmp_ep = first_ep; - i = 0; - do { - if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) { - if ((i % interval) == 0) { - /* Insert the traffic ep after tmp_ep */ - USB_EP_Desc_t *traffic_ep; - USB_SB_Desc_t *traffic_sb; + dbg_intr("Found EP to unlink for epid %d", epid); + + /* This is the one we should unlink. */ + unlink_ep = next_ep; - traffic_ep = (USB_EP_Desc_t *) - kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); - traffic_sb = (USB_SB_Desc_t *) - kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); - - traffic_ep->hw_len = 0; - traffic_ep->command = IO_FIELD(USB_EP_command, epid, epid) | - IO_STATE(USB_EP_command, enable, yes); - traffic_ep->sub = virt_to_phys(traffic_sb); - - if (usb_pipein(urb->pipe)) { - traffic_sb->sw_len = urb->transfer_buffer_length ? - (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; - traffic_sb->next = 0; - traffic_sb->buf = 0; - traffic_sb->command = IO_FIELD(USB_SB_command, rem, - urb->transfer_buffer_length % maxlen) | - IO_STATE(USB_SB_command, tt, in) | - IO_STATE(USB_SB_command, eot, yes) | - IO_STATE(USB_SB_command, eol, yes); - - } else if (usb_pipeout(urb->pipe)) { - traffic_sb->sw_len = urb->transfer_buffer_length; - traffic_sb->next = 0; - traffic_sb->buf = virt_to_phys(urb->transfer_buffer); - traffic_sb->command = IO_FIELD(USB_SB_command, rem, 0) | - IO_STATE(USB_SB_command, tt, out) | - IO_STATE(USB_SB_command, eot, yes) | - IO_STATE(USB_SB_command, eol, yes) | - IO_STATE(USB_SB_command, full, yes); - } + /* Actually unlink the EP from the DMA list. */ + curr_ep->next = unlink_ep->next; - traffic_ep->nep = tmp_ep->nep; - tmp_ep->nep = virt_to_phys(traffic_ep); - dbg_intr("One ep sucessfully inserted"); - } - i++; + /* Wait until the DMA is no longer at this descriptor. */ + while (*R_DMA_CH8_SUB2_EP == virt_to_phys(unlink_ep)); + + /* Now we are free to remove it and its SB descriptor. + Note that it is assumed here that there is only one sb in the + sb list for this ep. */ + kmem_cache_free(usb_desc_cache, phys_to_virt(unlink_ep->sub)); + kmem_cache_free(usb_desc_cache, (USB_EP_Desc_t *)unlink_ep); } - tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep); - } while (tmp_ep != first_ep); - set_bit(epid, (void *)&ep_really_active); - - *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start); + curr_ep = phys_to_virt(curr_ep->next); + + } while (curr_ep != first_ep); - DBFEXIT; - - return 0; } - -static void handle_intr_transfer_attn(int epid, int status) +void etrax_usb_do_intr_recover(int epid) { - struct urb *old_urb; + USB_EP_Desc_t *first_ep, *tmp_ep; DBFENTER; + + first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP); + tmp_ep = first_ep; - old_urb = URB_List[epid]; - - /* if (status == 0 && IN) find data and copy to urb */ - if (status == 0 && usb_pipein(old_urb->pipe)) { - unsigned long flags; - etrax_urb_priv_t *urb_priv; - struct list_head *entry; - struct in_chunk *in; - - urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv; + /* What this does is simply to walk the list of interrupt + ep descriptors and enable those that are disabled. */ + + do { + if (IO_EXTRACT(USB_EP_command, epid, tmp_ep->command) == epid && + !(tmp_ep->command & IO_MASK(USB_EP_command, enable))) { + tmp_ep->command |= IO_STATE(USB_EP_command, enable, yes); + } - save_flags(flags); - cli(); + tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next); + + } while (tmp_ep != first_ep); - list_for_each(entry, &urb_priv->ep_in_list) { - in = list_entry(entry, struct in_chunk, list); - memcpy(old_urb->transfer_buffer, in->data, in->length); - old_urb->actual_length = in->length; - old_urb->status = status; - - if (old_urb->complete) { - old_urb->complete(old_urb); - } - - list_del(entry); - kfree(in->data); - kfree(in); - } - - restore_flags(flags); - - } else if (status != 0) { - warn("Some sort of error for INTR EP !!!!"); -#ifdef ETRAX_USB_INTR_ERROR_FATAL - /* This means that an INTR error is fatal for that endpoint */ - etrax_usb_unlink_intr_urb(old_urb); - old_urb->status = status; - if (old_urb->complete) { - old_urb->complete(old_urb); - } -#else - /* In this case we reenable the disabled endpoint(s) */ - etrax_usb_do_intr_recover(epid); -#endif - } - - DBFEXIT; + + DBFEXIT; } -static int etrax_rh_unlink_urb (struct urb *urb) +static int etrax_rh_unlink_urb (urb_t *urb) { etrax_hc_t *hc; @@ -711,16 +939,12 @@ return 0; } -static void etrax_rh_send_irq(struct urb *urb) +static void etrax_rh_send_irq(urb_t *urb) { __u16 data = 0; etrax_hc_t *hc = urb->dev->bus->hcpriv; -// static prev_wPortStatus_1 = 0; -// static prev_wPortStatus_2 = 0; - /* DBFENTER; */ - - + /* dbg_rh("R_USB_FM_NUMBER : 0x%08X", *R_USB_FM_NUMBER); dbg_rh("R_USB_FM_REMAINING: 0x%08X", *R_USB_FM_REMAINING); @@ -730,6 +954,8 @@ data |= (hc->rh.wPortChange_2) ? (1 << 2) : 0; *((__u16 *)urb->transfer_buffer) = cpu_to_le16(data); + /* FIXME: Why is actual_length set to 1 when data is 2 bytes? + Since only 1 byte is used, why not declare data as __u8? */ urb->actual_length = 1; urb->status = 0; @@ -744,7 +970,7 @@ /* DBFEXIT; */ } -static void etrax_rh_init_int_timer(struct urb *urb) +static void etrax_rh_init_int_timer(urb_t *urb) { etrax_hc_t *hc; @@ -755,6 +981,8 @@ init_timer(&hc->rh.rh_int_timer); hc->rh.rh_int_timer.function = etrax_rh_int_timer_do; hc->rh.rh_int_timer.data = (unsigned long)urb; + /* FIXME: Is the jiffies resolution enough? All intervals < 10 ms will be mapped + to 0, and the rest to the nearest lower 10 ms. */ hc->rh.rh_int_timer.expires = jiffies + ((HZ * hc->rh.interval) / 1000); add_timer(&hc->rh.rh_int_timer); @@ -763,12 +991,12 @@ static void etrax_rh_int_timer_do(unsigned long ptr) { - struct urb *urb; + urb_t *urb; etrax_hc_t *hc; /* DBFENTER; */ - urb = (struct urb*)ptr; + urb = (urb_t*)ptr; hc = urb->dev->bus->hcpriv; if (hc->rh.send) { @@ -780,44 +1008,81 @@ /* DBFEXIT; */ } -static void etrax_usb_setup_epid(int epid, char devnum, char endpoint, char packsize, char slow, char out_traffic) +static int etrax_usb_setup_epid(urb_t *urb) { + int epid; + char devnum, endpoint, out_traffic, slow; + int maxlen; unsigned long flags; - - DBFENTER; - save_flags(flags); - cli(); + DBFENTER; - if (test_bit(epid, (void *)&ep_usage_bitmask)) { - restore_flags(flags); - - warn("Trying to setup used epid %d", epid); + epid = etrax_usb_lookup_epid(urb); + if ((epid != -1)){ + /* An epid that fits this urb has been found. */ DBFEXIT; - return; + return epid; } - set_bit(epid, (void *)&ep_usage_bitmask); + /* We must find and initiate a new epid for this urb. */ + epid = etrax_usb_allocate_epid(); + + if (epid == -1) { + /* Failed to allocate a new epid. */ + DBFEXIT; + return epid; + } + + /* We now have a new epid to use. Initiate it. */ + set_bit(epid, (void *)&epid_usage_bitmask); + devnum = usb_pipedevice(urb->pipe); + endpoint = usb_pipeendpoint(urb->pipe); + slow = usb_pipeslow(urb->pipe); + maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { + /* We want both IN and OUT control traffic to be put on the same EP/SB list. */ + out_traffic = 1; + } else { + out_traffic = usb_pipeout(urb->pipe); + } + + save_flags(flags); + cli(); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop(); - *R_USB_EPT_DATA = IO_STATE(R_USB_EPT_DATA, valid, yes) | - IO_FIELD(R_USB_EPT_DATA, ep, endpoint) | - IO_FIELD(R_USB_EPT_DATA, dev, devnum) | - IO_FIELD(R_USB_EPT_DATA, max_len, packsize) | - IO_FIELD(R_USB_EPT_DATA, low_speed, slow); - - if (out_traffic) - set_bit(epid, (void *)&ep_out_traffic); - else - clear_bit(epid, (void *)&ep_out_traffic); + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + *R_USB_EPT_DATA_ISO = IO_STATE(R_USB_EPT_DATA_ISO, valid, yes) | + /* FIXME: Change any to the actual port? */ + IO_STATE(R_USB_EPT_DATA_ISO, port, any) | + IO_FIELD(R_USB_EPT_DATA_ISO, max_len, maxlen) | + IO_FIELD(R_USB_EPT_DATA_ISO, ep, endpoint) | + IO_FIELD(R_USB_EPT_DATA_ISO, dev, devnum); + } else { + *R_USB_EPT_DATA = IO_STATE(R_USB_EPT_DATA, valid, yes) | + IO_FIELD(R_USB_EPT_DATA, low_speed, slow) | + /* FIXME: Change any to the actual port? */ + IO_STATE(R_USB_EPT_DATA, port, any) | + IO_FIELD(R_USB_EPT_DATA, max_len, maxlen) | + IO_FIELD(R_USB_EPT_DATA, ep, endpoint) | + IO_FIELD(R_USB_EPT_DATA, dev, devnum); + } + restore_flags(flags); - dbg_ep("Setting up ep_id %d with devnum %d, endpoint %d and max_len %d (%s)", - epid, devnum, endpoint, packsize, out_traffic ? "OUT" : "IN"); + if (out_traffic) { + set_bit(epid, (void *)&epid_out_traffic); + } else { + clear_bit(epid, (void *)&epid_out_traffic); + } + + dbg_epid("Setting up epid %d with devnum %d, endpoint %d and max_len %d (%s)", + epid, devnum, endpoint, maxlen, out_traffic ? "OUT" : "IN"); DBFEXIT; + return epid; } static void etrax_usb_free_epid(int epid) @@ -826,7 +1091,7 @@ DBFENTER; - if (!test_bit(epid, (void *)&ep_usage_bitmask)) { + if (!test_bit(epid, (void *)&epid_usage_bitmask)) { warn("Trying to free unused epid %d", epid); DBFEXIT; return; @@ -837,56 +1102,81 @@ *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop(); - while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) - printk("+"); + while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)); + /* This will, among other things, set the valid field to 0. */ *R_USB_EPT_DATA = 0; - clear_bit(epid, (void *)&ep_usage_bitmask); - restore_flags(flags); - dbg_ep("epid: %d freed", epid); + clear_bit(epid, (void *)&epid_usage_bitmask); + + + dbg_epid("Freed epid %d", epid); DBFEXIT; } - -static int etrax_usb_lookup_epid(unsigned char devnum, char endpoint, char slow, int maxp, char out_traffic) +static int etrax_usb_lookup_epid(urb_t *urb) { int i; - unsigned long flags; __u32 data; - + char devnum, endpoint, slow, out_traffic; + int maxlen; + unsigned long flags; + DBFENTER; - save_flags(flags); - cli(); + devnum = usb_pipedevice(urb->pipe); + endpoint = usb_pipeendpoint(urb->pipe); + slow = usb_pipeslow(urb->pipe); + maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { + /* We want both IN and OUT control traffic to be put on the same EP/SB list. */ + out_traffic = 1; + } else { + out_traffic = usb_pipeout(urb->pipe); + } + + /* Step through att epids. */ + for (i = 0; i < NBR_OF_EPIDS; i++) { + if (test_bit(i, (void *)&epid_usage_bitmask) && + test_bit(i, (void *)&epid_out_traffic) == out_traffic) { - /* Skip first ep_id since it is reserved when intr. or iso traffic is used */ - for (i = 0; i < NBR_OF_EP_DESC; i++) { - if (test_bit(i, (void *)&ep_usage_bitmask) && - test_bit(i, (void *)&ep_out_traffic) == out_traffic) { + save_flags(flags); + cli(); *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, i); nop(); - data = *R_USB_EPT_DATA; - if ((IO_MASK(R_USB_EPT_DATA, valid) & data) && - (IO_EXTRACT(R_USB_EPT_DATA, dev, data) == devnum) && - (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) && - (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) && - (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxp)) { + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + data = *R_USB_EPT_DATA_ISO; restore_flags(flags); - - dbg_ep("Found ep_id %d for devnum %d, endpoint %d (%s)", - i, devnum, endpoint, out_traffic ? "OUT" : "IN"); - DBFEXIT; - return i; + + if ((IO_MASK(R_USB_EPT_DATA_ISO, valid) & data) && + (IO_EXTRACT(R_USB_EPT_DATA_ISO, dev, data) == devnum) && + (IO_EXTRACT(R_USB_EPT_DATA_ISO, ep, data) == endpoint) && + (IO_EXTRACT(R_USB_EPT_DATA_ISO, max_len, data) == maxlen)) { + dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)", + i, devnum, endpoint, out_traffic ? "OUT" : "IN"); + DBFEXIT; + return i; + } + } else { + data = *R_USB_EPT_DATA; + restore_flags(flags); + + if ((IO_MASK(R_USB_EPT_DATA, valid) & data) && + (IO_EXTRACT(R_USB_EPT_DATA, dev, data) == devnum) && + (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) && + (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) && + (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxlen)) { + dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)", + i, devnum, endpoint, out_traffic ? "OUT" : "IN"); + DBFEXIT; + return i; + } } } } - restore_flags(flags); - - dbg_ep("Found no ep_id for devnum %d, endpoint %d (%s)", - devnum, endpoint, out_traffic ? "OUT" : "IN"); DBFEXIT; return -1; } @@ -897,434 +1187,993 @@ DBFENTER; - for (i = 0; i < NBR_OF_EP_DESC; i++) { - if (!test_bit(i, (void *)&ep_usage_bitmask)) { - dbg_ep("Found free ep_id at %d", i); + for (i = 0; i < NBR_OF_EPIDS; i++) { + if (!test_bit(i, (void *)&epid_usage_bitmask)) { + dbg_epid("Found free epid %d", i); DBFEXIT; return i; } } - dbg_ep("Found no free ep_id's"); + dbg_epid("Found no free epids"); DBFEXIT; return -1; } -static int etrax_usb_submit_bulk_urb(struct urb *urb) +static int etrax_usb_submit_urb(urb_t *urb) { - int epid; - char devnum; - char endpoint; - char maxlen; - char out_traffic; - char slow; - - struct urb *tmp_urb; - - unsigned long flags; + etrax_hc_t *hc; + int ret = -EINVAL; DBFENTER; - devnum = usb_pipedevice(urb->pipe); - endpoint = usb_pipeendpoint(urb->pipe); - maxlen = usb_maxpacket(urb->dev, urb->pipe, - usb_pipeout(urb->pipe)); - out_traffic = usb_pipeout(urb->pipe); - slow = usb_pipeslow(urb->pipe); + if (!urb->dev || !urb->dev->bus) { + return -ENODEV; + } + if (urb->next != NULL) { + /* Is it possible for urb to be the head of a list of urbs (via the urb's + next pointer), used for example in drivers for isochronous traffic. + I haven't seen a device driver that relies on it being used for submit + or unlink, so we warn about it and ignore it. */ + warn("Urbs are linked, ignoring."); + } + if (urb->timeout) { + /* FIXME. */ + warn("urb->timeout specified, ignoring."); + } + + hc = (etrax_hc_t*)urb->dev->bus->hcpriv; - epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic); - if (epid == -1) { - epid = etrax_usb_allocate_epid(); - if (epid == -1) { - /* We're out of endpoints, return some error */ - err("We're out of endpoints"); - return -ENOMEM; + if (usb_pipedevice(urb->pipe) == hc->rh.devnum) { + /* This request is for the Virtual Root Hub. */ + ret = etrax_rh_submit_urb(urb); + + } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { + + ret = etrax_usb_submit_bulk_urb(urb); + + } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { + + ret = etrax_usb_submit_ctrl_urb(urb); + + } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { + int bustime; + + if (urb->bandwidth == 0) { + bustime = usb_check_bandwidth(urb->dev, urb); + if (bustime < 0) { + ret = bustime; + } else { + ret = etrax_usb_submit_intr_urb(urb); + if (ret == 0) + usb_claim_bandwidth(urb->dev, urb, bustime, 0); + } + } else { + /* Bandwidth already set. */ + ret = etrax_usb_submit_intr_urb(urb); + } + + } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + int bustime; + + if (urb->bandwidth == 0) { + bustime = usb_check_bandwidth(urb->dev, urb); + if (bustime < 0) { + ret = bustime; + } else { + ret = etrax_usb_submit_isoc_urb(urb); + if (ret == 0) + usb_claim_bandwidth(urb->dev, urb, bustime, 0); + } + } else { + /* Bandwidth already set. */ + ret = etrax_usb_submit_isoc_urb(urb); } - /* Now we have to fill in this ep */ - etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow, out_traffic); } - /* Ok, now we got valid endpoint, lets insert some traffic */ - urb->status = -EINPROGRESS; + DBFEXIT; - save_flags(flags); - cli(); - - if (URB_List[epid]) { - /* Find end of list and add */ - for (tmp_urb = URB_List[epid]; tmp_urb->next; tmp_urb = tmp_urb->next) - dump_urb(tmp_urb); + return ret; +} + +static int etrax_usb_unlink_urb(urb_t *urb) +{ + etrax_hc_t *hc; + etrax_urb_priv_t *urb_priv; + int epid; + + DBFENTER; + + if (!urb) { + return -EINVAL; + } + if (!urb->dev || !urb->dev->bus) { + return -ENODEV; + } + if (!urb->hcpriv) { + /* This happens if a device driver calls unlink on an urb that + was never submitted (lazy driver). */ + return 0; + } + if (urb->transfer_flags & USB_ASYNC_UNLINK) { + /* FIXME. */ + /* If USB_ASYNC_UNLINK is set: + unlink + move to a separate urb list + call complete at next sof with ECONNRESET + + If not: + wait 1 ms + unlink + call complete with ENOENT + */ + warn("USB_ASYNC_UNLINK set, ignoring."); + } + + /* One might think that urb->status = -EINPROGRESS would be a requirement for unlinking, + but that doesn't work for interrupt and isochronous traffic since they are completed + repeatedly, and urb->status is set then. That may in itself be a bug though. */ + + hc = urb->dev->bus->hcpriv; + urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + epid = urb_priv->epid; + + /* Set the urb status (synchronous unlink). */ + urb->status = -ENOENT; + urb_priv->urb_state = UNLINK; + + if (usb_pipedevice(urb->pipe) == hc->rh.devnum) { + int ret; + ret = etrax_rh_unlink_urb(urb); + DBFEXIT; + return ret; - tmp_urb->next = urb; - restore_flags(flags); - } else { - /* If this is the first URB, add the URB and do HW add */ - URB_List[epid] = urb; - restore_flags(flags); - etrax_usb_do_bulk_hw_add(urb, epid, maxlen); - } + } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { + + dbg_bulk("Unlink of bulk urb (0x%lx)", (unsigned long)urb); + + if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) { + /* The EP was enabled, disable it and wait. */ + TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); + + /* Ah, the luxury of busy-wait. */ + while (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[epid])); + } + /* Kicking dummy list out of the party. */ + TxBulkEPList[epid].next = virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]); + + } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { + + dbg_ctrl("Unlink of ctrl urb (0x%lx)", (unsigned long)urb); + + if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) { + /* The EP was enabled, disable it and wait. */ + TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); + + /* Ah, the luxury of busy-wait. */ + while (*R_DMA_CH8_SUB1_EP == virt_to_phys(&TxCtrlEPList[epid])); + } + + } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { + + dbg_intr("Unlink of intr urb (0x%lx)", (unsigned long)urb); + + /* Separate function because it's a tad more complicated. */ + etrax_usb_unlink_intr_urb(urb); + + } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + dbg_isoc("Unlink of isoc urb (0x%lx)", (unsigned long)urb); + + if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) { + /* The EP was enabled, disable it and wait. */ + TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); + + /* Ah, the luxury of busy-wait. */ + while (*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid])); + } + } + + /* Note that we need to remove the urb from the urb list *before* removing its SB + descriptors. (This means that the isoc eof handler might get a null urb when we + are unlinking the last urb.) */ + + urb_list_del(urb, epid); + + if (usb_pipetype(urb->pipe) == PIPE_BULK) { + + TxBulkEPList[epid].sub = 0; + etrax_remove_from_sb_list(urb); + + } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { + + TxCtrlEPList[epid].sub = 0; + etrax_remove_from_sb_list(urb); + + } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { + + /* Sanity check (should never happen). */ + assert(urb_list_empty(epid)); + + /* Release allocated bandwidth. */ + usb_release_bandwidth(urb->dev, urb, 0); + + } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + + if (usb_pipeout(urb->pipe)) { + /* FIXME: If the SB list isn't empty at this point, we need to set up + the EP descriptor again. */ + } else { + /* For in traffic there is only one SB descriptor for each EP even + though there may be several urbs (all urbs point at the same SB). */ + if (urb_list_empty(epid)) { + /* No more urbs, remove the SB. */ + TxIsocEPList[epid].sub = 0; + etrax_remove_from_sb_list(urb); + } + } + /* Release allocated bandwidth. */ + usb_release_bandwidth(urb->dev, urb, 1); + } + + /* Must be done before calling completion handler. */ + kfree(urb_priv); + urb->hcpriv = 0; + + if (urb->complete) { + urb->complete(urb); + } + + /* Free the epid if urb list is empty. */ + if (urb_list_empty(epid)) { + etrax_usb_free_epid(epid); + } + + DBFEXIT; + return 0; +} + +static int etrax_usb_get_frame_number(struct usb_device *usb_dev) +{ + DBFENTER; DBFEXIT; + return (*R_USB_FM_NUMBER & 0x7ff); +} +static int etrax_usb_allocate_dev(struct usb_device *usb_dev) +{ + DBFENTER; + DBFEXIT; return 0; } -static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen) +static int etrax_usb_deallocate_dev(struct usb_device *usb_dev) { - USB_SB_Desc_t *sb_desc_1; + DBFENTER; + DBFEXIT; + return 0; +} + +static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs) +{ + DBFENTER; + + /* This interrupt handler could be used when unlinking EP descriptors. */ + + if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) { + USB_EP_Desc_t *ep; + + //dbg_bulk("dma8_sub0_descr (BULK) intr."); + + /* It should be safe clearing the interrupt here, since we don't expect to get a new + one until we restart the bulk channel. */ + *R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do); + /* Wait while the DMA is running (though we don't expect it to be). */ + while (*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd)); + + /* Advance the DMA to the next EP descriptor. */ + ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP); + + //dbg_bulk("descr intr: DMA is at 0x%lx", (unsigned long)ep); + + /* ep->next is already a physical address; no need for a virt_to_phys. */ + *R_DMA_CH8_SUB0_EP = ep->next; + + /* Start the DMA bulk channel again. */ + *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); + } + if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) { + dbg_ctrl("dma8_sub1_descr (CTRL) intr."); + *R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do); + } + if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) { + dbg_intr("dma8_sub2_descr (INTR) intr."); + *R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do); + } + if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) { + dbg_isoc("dma8_sub3_descr (ISOC) intr."); + *R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do); + } + + DBFEXIT; +} + +static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs) +{ + urb_t *urb; etrax_urb_priv_t *urb_priv; + int epid = 0; + unsigned long flags; - unsigned long flags; + /* Isoc diagnostics. */ + static int curr_fm = 0; + static int prev_fm = 0; + + DBFENTER; + + /* Clear this interrupt. */ + *R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do); + + /* Note that this while loop assumes that all packets span only + one rx descriptor. */ + + /* The reason we cli here is that we call the driver's callback functions. */ + save_flags(flags); + cli(); + + + while (myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) { + + epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status); + urb = urb_list_first(epid); + + //printk("eop for epid %d, first urb 0x%lx\n", epid, (unsigned long)urb); + + if (!urb) { + err("No urb for epid %d in rx interrupt", epid); + __dump_ept_data(epid); + goto skip_out; + } + + /* Note that we cannot indescriminately assert(usb_pipein(urb->pipe)) since + ctrl pipes are not. */ + + if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) { + warn("error in rx desc->status, epid %d, first urb = 0x%lx", + epid, (unsigned long)urb); + __dump_in_desc(myNextRxDesc); + etrax_usb_complete_urb(urb, -EPROTO); + goto skip_out; + } + + urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + assert(urb_priv); + + if ((usb_pipetype(urb->pipe) == PIPE_BULK) || + (usb_pipetype(urb->pipe) == PIPE_CONTROL) || + (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) { + + if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) { + /* We get nodata for empty data transactions, and the rx descriptor's + hw_len field is not valid in that case. No data to copy in other + words. */ + } else { + /* Make sure the data fits in the buffer. */ + assert(urb_priv->rx_offset + myNextRxDesc->hw_len + <= urb->transfer_buffer_length); + + memcpy(urb->transfer_buffer + urb_priv->rx_offset, + phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len); + urb_priv->rx_offset += myNextRxDesc->hw_len; + } + + if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) { + etrax_usb_complete_urb(urb, 0); + } + + } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + + iso_packet_descriptor_t *packet; + + if (urb_priv->urb_state == UNLINK) { + info("Ignoring rx data for urb being unlinked."); + goto skip_out; + } else if (urb_priv->urb_state == NOT_STARTED) { + info("What? Got rx data for urb that isn't started?"); + goto skip_out; + } + + packet = &urb->iso_frame_desc[urb_priv->isoc_packet_counter]; + packet->status = 0; + + if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) { + /* We get nodata for empty data transactions, and the rx descriptor's + hw_len field is not valid in that case. We copy 0 bytes however to + stay in synch. */ + packet->actual_length = 0; + } else { + packet->actual_length = myNextRxDesc->hw_len; + /* Make sure the data fits in the buffer. */ + assert(packet->actual_length <= packet->length); + + memcpy(urb->transfer_buffer + packet->offset, + phys_to_virt(myNextRxDesc->buf), packet->actual_length); + } + + /* Increment the packet counter. */ + urb_priv->isoc_packet_counter++; + + /* Note that we don't care about the eot field in the rx descriptor's status. + It will always be set for isoc traffic. */ + if (urb->number_of_packets == urb_priv->isoc_packet_counter) { + + /* Out-of-synch diagnostics. */ + curr_fm = (*R_USB_FM_NUMBER & 0x7ff); + if (((prev_fm + urb_priv->isoc_packet_counter) % (0x7ff + 1)) != curr_fm) { + warn("Out of synch? Previous frame = %d, current frame = %d", + prev_fm, curr_fm); + } + prev_fm = curr_fm; + + /* Complete the urb with status OK. */ + etrax_usb_complete_isoc_urb(urb, 0); + + /* Must set this to 0 since this urb is still active after + completion. */ + urb_priv->isoc_packet_counter = 0; + } + } + + skip_out: + + /* DMA IN cache bug. Flush the DMA IN buffer from the cache. (struct etrax_dma_descr + has the same layout as USB_IN_Desc for the relevant fields.) */ + prepare_rx_descriptor((struct etrax_dma_descr*)myNextRxDesc); + + myPrevRxDesc = myNextRxDesc; + myPrevRxDesc->command |= IO_MASK(USB_IN_command, eol); + myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol); + myLastRxDesc = myPrevRxDesc; + + myNextRxDesc->status = 0; + myNextRxDesc = phys_to_virt(myNextRxDesc->next); + } + + restore_flags(flags); + + DBFEXIT; + +} + + +/* This function will unlink the SB descriptors associated with this urb. */ +static int etrax_remove_from_sb_list(urb_t *urb) +{ + USB_SB_Desc_t *next_sb, *first_sb, *last_sb; + etrax_urb_priv_t *urb_priv; + int i = 0; DBFENTER; - urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL); - sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + assert(urb_priv); - if (usb_pipeout(urb->pipe)) { + /* Just a sanity check. Since we don't fiddle with the DMA list the EP descriptor + doesn't really need to be disabled, it's just that we expect it to be. */ + if (usb_pipetype(urb->pipe) == PIPE_BULK) { + assert(!(TxBulkEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable))); + } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { + assert(!(TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable))); + } - dbg_bulk("Bulk transfer for epid %d is OUT", epid); - dbg_bulk("transfer_buffer_length == %d", urb->transfer_buffer_length); - dbg_bulk("actual_length == %d", urb->actual_length); + first_sb = urb_priv->first_sb; + last_sb = urb_priv->last_sb; + assert(first_sb); + assert(last_sb); + + while (first_sb != last_sb) { + next_sb = (USB_SB_Desc_t *)phys_to_virt(first_sb->next); + kmem_cache_free(usb_desc_cache, first_sb); + first_sb = next_sb; + i++; + } + kmem_cache_free(usb_desc_cache, last_sb); + i++; + dbg_sb("%d SB descriptors freed", i); + /* Compare i with urb->number_of_packets for Isoc traffic. + Should be same when calling unlink_urb */ + + DBFEXIT; + + return i; +} + +static int etrax_usb_submit_bulk_urb(urb_t *urb) +{ + int epid; + int empty; + unsigned long flags; + + DBFENTER; + + /* Epid allocation, empty check and list add must be protected. + Read about this in etrax_usb_submit_ctrl_urb. */ + + spin_lock_irqsave(&urb_list_lock, flags); + epid = etrax_usb_setup_epid(urb); + if (epid == -1) { + DBFEXIT; + spin_unlock_irqrestore(&urb_list_lock, flags); + return -ENOMEM; + } + empty = urb_list_empty(epid); + urb_list_add(urb, epid); + spin_unlock_irqrestore(&urb_list_lock, flags); + + /* USB_QUEUE_BULK is UHCI-specific, but we warn anyway. */ + if (!(urb->transfer_flags & USB_QUEUE_BULK) && !empty) { + warn("USB_QUEUE_BULK is not set and urb queue is not empty, ignoring."); + } + + dbg_bulk("Adding bulk %s urb 0x%lx to %s list, epid %d", + usb_pipein(urb->pipe) ? "IN" : "OUT", (unsigned long)urb, empty ? "empty" : "", epid); + + /* Mark the urb as being in progress. */ + urb->status = -EINPROGRESS; + + if (empty) { + etrax_usb_add_to_bulk_sb_list(urb, epid); + } + + DBFEXIT; + + return 0; +} + +static void etrax_usb_add_to_bulk_sb_list(urb_t *urb, int epid) +{ + USB_SB_Desc_t *sb_desc; + etrax_urb_priv_t *urb_priv; + unsigned long flags; + char maxlen; + + DBFENTER; + + dbg_bulk("etrax_usb_add_to_bulk_sb_list, urb 0x%lx", (unsigned long)urb); + + maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + assert(urb_priv != NULL); + /* This sets rx_offset to 0. */ + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); + + sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(sb_desc != NULL); + memset(sb_desc, 0, sizeof(USB_SB_Desc_t)); + + + if (usb_pipeout(urb->pipe)) { + + dbg_bulk("Grabbing bulk OUT, urb 0x%lx, epid %d", (unsigned long)urb, epid); + + /* This is probably a sanity check of the bulk transaction length + not being larger than 64 kB. */ if (urb->transfer_buffer_length > 0xffff) { - panic(__FILE__ __FUNCTION__ ":urb->transfer_buffer_length > 0xffff\n"); + panic("urb->transfer_buffer_length > 0xffff"); } - sb_desc_1->sw_len = urb->transfer_buffer_length; /* was actual_length */ - sb_desc_1->command = IO_FIELD(USB_SB_command, rem, 0) | - IO_STATE(USB_SB_command, tt, out) | + sb_desc->sw_len = urb->transfer_buffer_length; -#if 0 - IO_STATE(USB_SB_command, full, no) | -#else - IO_STATE(USB_SB_command, full, yes) | -#endif + /* The rem field is don't care if it's not a full-length transfer, so setting + it shouldn't hurt. Also, rem isn't used for OUT traffic. */ + sb_desc->command = (IO_FIELD(USB_SB_command, rem, 0) | + IO_STATE(USB_SB_command, tt, out) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); + + /* The full field is set to yes, even if we don't actually check that this is + a full-length transfer (i.e., that transfer_buffer_length % maxlen = 0). + Setting full prevents the USB controller from sending an empty packet in + that case. However, if USB_ZERO_PACKET was set we want that. */ + if (!(urb->transfer_flags & USB_ZERO_PACKET)) { + sb_desc->command |= IO_STATE(USB_SB_command, full, yes); + } - IO_STATE(USB_SB_command, eot, yes) | - IO_STATE(USB_SB_command, eol, yes); - - dbg_bulk("transfer_buffer is at 0x%08X", urb->transfer_buffer); - - sb_desc_1->buf = virt_to_phys(urb->transfer_buffer); - sb_desc_1->next = 0; + sb_desc->buf = virt_to_phys(urb->transfer_buffer); + sb_desc->next = 0; } else if (usb_pipein(urb->pipe)) { - dbg_bulk("Transfer for epid %d is IN", epid); - dbg_bulk("transfer_buffer_length = %d", urb->transfer_buffer_length); - dbg_bulk("rem is calculated to %d", urb->transfer_buffer_length % maxlen); - - sb_desc_1->sw_len = urb->transfer_buffer_length ? + dbg_bulk("Grabbing bulk IN, urb 0x%lx, epid %d", (unsigned long)urb, epid); + + sb_desc->sw_len = urb->transfer_buffer_length ? (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; - dbg_bulk("sw_len got %d", sb_desc_1->sw_len); - dbg_bulk("transfer_buffer is at 0x%08X", urb->transfer_buffer); - - sb_desc_1->command = - IO_FIELD(USB_SB_command, rem, - urb->transfer_buffer_length % maxlen) | - IO_STATE(USB_SB_command, tt, in) | - IO_STATE(USB_SB_command, eot, yes) | - IO_STATE(USB_SB_command, eol, yes); - sb_desc_1->buf = 0; - sb_desc_1->next = 0; + /* The rem field is don't care if it's not a full-length transfer, so setting + it shouldn't hurt. */ + sb_desc->command = + (IO_FIELD(USB_SB_command, rem, + urb->transfer_buffer_length % maxlen) | + IO_STATE(USB_SB_command, tt, in) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); + + sb_desc->buf = 0; + sb_desc->next = 0; + } + + urb_priv->first_sb = sb_desc; + urb_priv->last_sb = sb_desc; + urb_priv->epid = epid; - urb_priv->rx_offset = 0; - urb_priv->eot = 0; - } - - urb_priv->first_sb = sb_desc_1; - - urb->hcpriv = (void *)urb_priv; + urb->hcpriv = urb_priv; - /* Reset toggle bits and reset error count, remeber to di and ei */ - /* Warning: it is possible that this locking doesn't work with bottom-halves */ - + /* Reset toggle bits and reset error count. */ save_flags(flags); cli(); - *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop(); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + + /* FIXME: Is this a special case since the hold field is checked, + or should we check hold in a lot of other cases as well? */ if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) { - panic("Hold was set in %s\n", __FUNCTION__); + panic("Hold was set in %s", __FUNCTION__); } + /* Reset error counters (regardless of which direction this traffic is). */ *R_USB_EPT_DATA &= ~(IO_MASK(R_USB_EPT_DATA, error_count_in) | IO_MASK(R_USB_EPT_DATA, error_count_out)); + /* Software must preset the toggle bits. */ if (usb_pipeout(urb->pipe)) { char toggle = - usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); + usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_out); *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_out, toggle); } else { char toggle = - usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); + usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_in); *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_in, toggle); } - - /* Enable the EP descr. */ - - set_bit(epid, (void *)&ep_really_active); - - TxBulkEPList[epid].sub = virt_to_phys(sb_desc_1); + + /* Assert that the EP descriptor is disabled. */ + assert(!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable))); + + /* The reason we set the EP's sub pointer directly instead of + walking the SB list and linking it last in the list is that we only + have one active urb at a time (the rest are queued). */ + + /* Note that we cannot have interrupts running when we have set the SB descriptor + but the EP is not yet enabled. If a bulk eot happens for another EP, we will + find this EP disabled and with a SB != 0, which will make us think that it's done. */ + TxBulkEPList[epid].sub = virt_to_phys(sb_desc); TxBulkEPList[epid].hw_len = 0; - TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); + /* Note that we don't have to fill in the ep_id field since this + was done when we allocated the EP descriptors in init_tx_bulk_ep. */ + + /* Check if the dummy list is already with us (if several urbs were queued). */ + if (TxBulkEPList[epid].next != virt_to_phys(&TxBulkDummyEPList[epid][0])) { + + dbg_bulk("Inviting dummy list to the party for urb 0x%lx, epid %d", + (unsigned long)urb, epid); + + /* The last EP in the dummy list already has its next pointer set to + TxBulkEPList[epid].next. */ + /* We don't need to check if the DMA is at this EP or not before changing the + next pointer, since we will do it in one 32-bit write (EP descriptors are + 32-bit aligned). */ + TxBulkEPList[epid].next = virt_to_phys(&TxBulkDummyEPList[epid][0]); + } + /* Enable the EP descr. */ + dbg_bulk("Enabling bulk EP for urb 0x%lx, epid %d", (unsigned long)urb, epid); + TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); + + /* Everything is set up, safe to enable interrupts again. */ restore_flags(flags); + /* If the DMA bulk channel isn't running, we need to restart it if it + has stopped at the last EP descriptor (DMA stopped because there was + no more traffic) or if it has stopped at a dummy EP with the intr flag + set (DMA stopped because we were too slow in inserting new traffic). */ if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) { - *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); - - } + USB_EP_Desc_t *ep; + ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP); + dbg_bulk("DMA channel not running in add"); + dbg_bulk("DMA is at 0x%lx", (unsigned long)ep); + + if (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[NBR_OF_EPIDS - 1]) || + (ep->command & 0x8) >> 3) { + *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); + /* Update/restart the bulk start timer since we just started the channel. */ + mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL); + /* Update/restart the bulk eot timer since we just inserted traffic. */ + mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL); + } + } + DBFEXIT; } -static void handle_bulk_transfer_attn(int epid, int status) +static void etrax_usb_complete_bulk_urb(urb_t *urb, int status) { - struct urb *old_urb; - etrax_urb_priv_t *hc_priv; - unsigned long flags; - + etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + int epid = urb_priv->epid; + unsigned long flags; + DBFENTER; - clear_bit(epid, (void *)&ep_really_active); - - old_urb = URB_List[epid]; - URB_List[epid] = old_urb->next; + if (status) + warn("Completing bulk urb with status %d.", status); + + dbg_bulk("Completing bulk urb 0x%lx for epid %d", (unsigned long)urb, epid); + + /* Update the urb list. */ + urb_list_del(urb, epid); - /* if (status == 0 && IN) find data and copy to urb */ - if (status == 0 && usb_pipein(old_urb->pipe)) { - etrax_urb_priv_t *urb_priv; - - urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv; - save_flags(flags); - cli(); - if (urb_priv->eot == 1) { - old_urb->actual_length = urb_priv->rx_offset; + /* For an IN pipe, we always set the actual length, regardless of whether there was + an error or not (which means the device driver can use the data if it wants to). */ + if (usb_pipein(urb->pipe)) { + urb->actual_length = urb_priv->rx_offset; + } else { + /* Set actual_length for OUT urbs also; the USB mass storage driver seems + to want that. We wouldn't know of any partial writes if there was an error. */ + if (status == 0) { + urb->actual_length = urb->transfer_buffer_length; } else { - if (urb_priv->rx_offset == 0) { - status = 0; - } else { - status = -EPROTO; - } - - old_urb->actual_length = 0; - err("(BULK) No eot set in IN data!!! rx_offset is: %d", urb_priv->rx_offset); + urb->actual_length = 0; } - - restore_flags(flags); } + /* FIXME: Is there something of the things below we shouldn't do if there was an error? + Like, maybe we shouldn't toggle the toggle bits, or maybe we shouldn't insert more traffic. */ + save_flags(flags); cli(); - *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop(); - if (usb_pipeout(old_urb->pipe)) { + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + + /* We need to fiddle with the toggle bits because the hardware doesn't do it for us. */ + if (usb_pipeout(urb->pipe)) { char toggle = - IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA); - usb_settoggle(old_urb->dev, usb_pipeendpoint(old_urb->pipe), - usb_pipeout(old_urb->pipe), toggle); + IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA); + usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe), toggle); } else { char toggle = - IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA); - usb_settoggle(old_urb->dev, usb_pipeendpoint(old_urb->pipe), - usb_pipeout(old_urb->pipe), toggle); + IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA); + usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe), toggle); + } + restore_flags(flags); + + /* Remember to free the SBs. */ + etrax_remove_from_sb_list(urb); + kfree(urb_priv); + urb->hcpriv = 0; + + /* If there are any more urb's in the list we'd better start sending */ + if (!urb_list_empty(epid)) { + + urb_t *new_urb; + + /* Get the first urb. */ + new_urb = urb_list_first(epid); + assert(new_urb); + + dbg_bulk("More bulk for epid %d", epid); + + etrax_usb_add_to_bulk_sb_list(new_urb, epid); + } + + urb->status = status; + + /* We let any non-zero status from the layer above have precedence. */ + if (status == 0) { + /* USB_DISABLE_SPD means that short reads (shorter than the endpoint's max length) + is to be treated as an error. */ + if (urb->transfer_flags & USB_DISABLE_SPD) { + if (usb_pipein(urb->pipe) && + (urb->actual_length != + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) { + urb->status = -EREMOTEIO; + } + } + } + + if (urb->complete) { + urb->complete(urb); } - restore_flags(flags); - - /* If there are any more URB's in the list we'd better start sending */ - if (URB_List[epid]) { - etrax_usb_do_bulk_hw_add(URB_List[epid], epid, - usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe, - usb_pipeout(URB_List[epid]->pipe))); - } -#if 1 - else { - /* This means that this EP is now free, deconfigure it */ + if (urb_list_empty(epid)) { + /* This means that this EP is now free, deconfigure it. */ etrax_usb_free_epid(epid); - } -#endif - - /* Remember to free the SB's */ - hc_priv = (etrax_urb_priv_t *)old_urb->hcpriv; - cleanup_sb(hc_priv->first_sb); - kfree(hc_priv); + + /* No more traffic; time to clean up. + Must set sub pointer to 0, since we look at the sub pointer when handling + the bulk eot interrupt. */ + + dbg_bulk("No bulk for epid %d", epid); + + TxBulkEPList[epid].sub = 0; + + /* Unlink the dummy list. */ - old_urb->status = status; - if (old_urb->complete) { - old_urb->complete(old_urb); + dbg_bulk("Kicking dummy list out of party for urb 0x%lx, epid %d", + (unsigned long)urb, epid); + + /* No need to wait for the DMA before changing the next pointer. + The modulo NBR_OF_EPIDS isn't actually necessary, since we will never use + the last one (INVALID_EPID) for actual traffic. */ + TxBulkEPList[epid].next = + virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]); } DBFEXIT; } -/* ---------------------------------------------------------------------------- */ - -static int etrax_usb_submit_ctrl_urb(struct urb *urb) +static int etrax_usb_submit_ctrl_urb(urb_t *urb) { int epid; - char devnum; - char endpoint; - char maxlen; - char out_traffic; - char slow; - - struct urb *tmp_urb; - - unsigned long flags; - + int empty; + unsigned long flags; + DBFENTER; - devnum = usb_pipedevice(urb->pipe); - endpoint = usb_pipeendpoint(urb->pipe); - maxlen = usb_maxpacket(urb->dev, urb->pipe, - usb_pipeout(urb->pipe)); - out_traffic = usb_pipeout(urb->pipe); - slow = usb_pipeslow(urb->pipe); - - epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic); + /* FIXME: Return -ENXIO if there is already a queued urb for this endpoint? */ + + /* Epid allocation, empty check and list add must be protected. + + Epid allocation because if we find an existing epid for this endpoint an urb might be + completed (emptying the list) before we add the new urb to the list, causing the epid + to be de-allocated. We would then start the transfer with an invalid epid -> epid attn. + + Empty check and add because otherwise we might conclude that the list is not empty, + after which it becomes empty before we add the new urb to the list, causing us not to + insert the new traffic into the SB list. */ + + spin_lock_irqsave(&urb_list_lock, flags); + epid = etrax_usb_setup_epid(urb); if (epid == -1) { - epid = etrax_usb_allocate_epid(); - if (epid == -1) { - /* We're out of endpoints, return some error */ - err("We're out of endpoints"); - return -ENOMEM; - } - /* Now we have to fill in this ep */ - etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow, out_traffic); + spin_unlock_irqrestore(&urb_list_lock, flags); + DBFEXIT; + return -ENOMEM; } - /* Ok, now we got valid endpoint, lets insert some traffic */ + empty = urb_list_empty(epid); + urb_list_add(urb, epid); + spin_unlock_irqrestore(&urb_list_lock, flags); + dbg_ctrl("Adding ctrl urb 0x%lx to %s list, epid %d", + (unsigned long)urb, empty ? "empty" : "", epid); + + /* Mark the urb as being in progress. */ urb->status = -EINPROGRESS; - save_flags(flags); - cli(); - - if (URB_List[epid]) { - /* Find end of list and add */ - for (tmp_urb = URB_List[epid]; tmp_urb->next; tmp_urb = tmp_urb->next) - dump_urb(tmp_urb); - - tmp_urb->next = urb; - restore_flags(flags); - } else { - /* If this is the first URB, add the URB and do HW add */ - URB_List[epid] = urb; - restore_flags(flags); - etrax_usb_do_ctrl_hw_add(urb, epid, maxlen); - } + if (empty) { + etrax_usb_add_to_ctrl_sb_list(urb, epid); + } DBFEXIT; return 0; } -static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen) +static void etrax_usb_add_to_ctrl_sb_list(urb_t *urb, int epid) { - USB_SB_Desc_t *sb_desc_1; - USB_SB_Desc_t *sb_desc_2; - USB_SB_Desc_t *sb_desc_3; + USB_SB_Desc_t *sb_desc_setup; + USB_SB_Desc_t *sb_desc_data; + USB_SB_Desc_t *sb_desc_status; etrax_urb_priv_t *urb_priv; unsigned long flags; - + char maxlen; + DBFENTER; - urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL); - sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); - sb_desc_2 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); - - if (!(sb_desc_1 && sb_desc_2)) { - panic("kmem_cache_alloc in ctrl_hw_add gave NULL pointers !!!\n"); - } - - sb_desc_1->sw_len = 8; - sb_desc_1->command = IO_FIELD(USB_SB_command, rem, 0) | - IO_STATE(USB_SB_command, tt, setup) | - IO_STATE(USB_SB_command, full, yes) | - IO_STATE(USB_SB_command, eot, yes); - - sb_desc_1->buf = virt_to_phys(urb->setup_packet); - sb_desc_1->next = virt_to_phys(sb_desc_2); - dump_sb_desc(sb_desc_1); + maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + assert(urb_priv != NULL); + /* This sets rx_offset to 0. */ + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); + + sb_desc_setup = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(sb_desc_setup != NULL); + sb_desc_status = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(sb_desc_status != NULL); + + /* Initialize the mandatory setup SB descriptor (used only in control transfers) */ + sb_desc_setup->sw_len = 8; + sb_desc_setup->command = (IO_FIELD(USB_SB_command, rem, 0) | + IO_STATE(USB_SB_command, tt, setup) | + IO_STATE(USB_SB_command, full, yes) | + IO_STATE(USB_SB_command, eot, yes)); + + sb_desc_setup->buf = virt_to_phys(urb->setup_packet); if (usb_pipeout(urb->pipe)) { - dbg_ctrl("Transfer for epid %d is OUT", epid); + dbg_ctrl("Transfer for epid %d is OUT", epid); /* If this Control OUT transfer has an optional data stage we add an OUT token before the mandatory IN (status) token, hence the reordered SB list */ + sb_desc_setup->next = virt_to_phys(sb_desc_status); if (urb->transfer_buffer) { - dbg_ctrl("This OUT transfer has an extra data stage"); - sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); - sb_desc_1->next = virt_to_phys(sb_desc_3); + dbg_ctrl("This OUT transfer has an extra data stage"); - sb_desc_3->sw_len = urb->transfer_buffer_length; - sb_desc_3->command = IO_STATE(USB_SB_command, tt, out) | - IO_STATE(USB_SB_command, full, yes) | - IO_STATE(USB_SB_command, eot, yes); - sb_desc_3->buf = virt_to_phys(urb->transfer_buffer); - sb_desc_3->next = virt_to_phys(sb_desc_2); - } - - sb_desc_2->sw_len = 1; - sb_desc_2->command = IO_FIELD(USB_SB_command, rem, 0) | - IO_STATE(USB_SB_command, tt, in) | - IO_STATE(USB_SB_command, eot, yes) | - IO_STATE(USB_SB_command, eol, yes); - - sb_desc_2->buf = 0; - sb_desc_2->next = 0; - dump_sb_desc(sb_desc_2); - + sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(sb_desc_data != NULL); + + sb_desc_setup->next = virt_to_phys(sb_desc_data); + + sb_desc_data->sw_len = urb->transfer_buffer_length; + sb_desc_data->command = (IO_STATE(USB_SB_command, tt, out) | + IO_STATE(USB_SB_command, full, yes) | + IO_STATE(USB_SB_command, eot, yes)); + sb_desc_data->buf = virt_to_phys(urb->transfer_buffer); + sb_desc_data->next = virt_to_phys(sb_desc_status); + } + + sb_desc_status->sw_len = 1; + sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) | + IO_STATE(USB_SB_command, tt, in) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); + + sb_desc_status->buf = 0; + sb_desc_status->next = 0; + } else if (usb_pipein(urb->pipe)) { dbg_ctrl("Transfer for epid %d is IN", epid); dbg_ctrl("transfer_buffer_length = %d", urb->transfer_buffer_length); dbg_ctrl("rem is calculated to %d", urb->transfer_buffer_length % maxlen); - sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(sb_desc_data != NULL); - sb_desc_2->sw_len = urb->transfer_buffer_length ? + sb_desc_setup->next = virt_to_phys(sb_desc_data); + + sb_desc_data->sw_len = urb->transfer_buffer_length ? (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; - dbg_ctrl("sw_len got %d", sb_desc_2->sw_len); + dbg_ctrl("sw_len got %d", sb_desc_data->sw_len); - sb_desc_2->command = - IO_FIELD(USB_SB_command, rem, - urb->transfer_buffer_length % maxlen) | - IO_STATE(USB_SB_command, tt, in) | - IO_STATE(USB_SB_command, eot, yes); - - sb_desc_2->buf = 0; - sb_desc_2->next = virt_to_phys(sb_desc_3); - dump_sb_desc(sb_desc_2); - - sb_desc_3->sw_len = 1; - sb_desc_3->command = IO_FIELD(USB_SB_command, rem, 0) | - IO_STATE(USB_SB_command, tt, zout) | - IO_STATE(USB_SB_command, full, yes) | - IO_STATE(USB_SB_command, eot, yes) | - IO_STATE(USB_SB_command, eol, yes); + sb_desc_data->command = + (IO_FIELD(USB_SB_command, rem, + urb->transfer_buffer_length % maxlen) | + IO_STATE(USB_SB_command, tt, in) | + IO_STATE(USB_SB_command, eot, yes)); + + sb_desc_data->buf = 0; + sb_desc_data->next = virt_to_phys(sb_desc_status); + + /* Read comment at zout_buffer declaration for an explanation to this. */ + sb_desc_status->sw_len = 1; + sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) | + IO_STATE(USB_SB_command, tt, zout) | + IO_STATE(USB_SB_command, full, yes) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); - sb_desc_3->buf = 0; - sb_desc_3->next = 0; - dump_sb_desc(sb_desc_3); - - urb_priv->rx_offset = 0; - urb_priv->eot = 0; + sb_desc_status->buf = virt_to_phys(&zout_buffer[0]); + sb_desc_status->next = 0; } - urb_priv->first_sb = sb_desc_1; - - urb->hcpriv = (void *)urb_priv; + urb_priv->first_sb = sb_desc_setup; + urb_priv->last_sb = sb_desc_status; + urb_priv->epid = epid; + + urb->hcpriv = urb_priv; /* Reset toggle bits and reset error count, remeber to di and ei */ /* Warning: it is possible that this locking doesn't work with bottom-halves */ @@ -1332,661 +2181,1059 @@ save_flags(flags); cli(); - *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop(); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) { - panic("Hold was set in %s\n", __FUNCTION__); + panic("Hold was set in %s", __FUNCTION__); } + /* FIXME: Compare with etrax_usb_add_to_bulk_sb_list where the toggle bits + are set to a specific value. Why the difference? Read "Transfer and Toggle Bits + in Designer's Reference, p. 8 - 11. */ *R_USB_EPT_DATA &= ~(IO_MASK(R_USB_EPT_DATA, error_count_in) | IO_MASK(R_USB_EPT_DATA, error_count_out) | IO_MASK(R_USB_EPT_DATA, t_in) | IO_MASK(R_USB_EPT_DATA, t_out)); - /* Enable the EP descr. */ + /* Since we use the rx interrupt to complete ctrl urbs, we can enable interrupts now + (i.e. we don't check the sub pointer on an eot interrupt like we do for bulk traffic). */ + restore_flags(flags); - set_bit(epid, (void *)&ep_really_active); - - TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_1); + /* Assert that the EP descriptor is disabled. */ + assert(!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable))); + + /* Set up and enable the EP descriptor. */ + TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_setup); TxCtrlEPList[epid].hw_len = 0; TxCtrlEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); - restore_flags(flags); - - dump_ep_desc(&TxCtrlEPList[epid]); - - if (!(*R_DMA_CH8_SUB1_CMD & IO_MASK(R_DMA_CH8_SUB1_CMD, cmd))) { - *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start); - - } + /* We start the DMA sub channel without checking if it's running or not, because: + 1) If it's already running, issuing the start command is a nop. + 2) We avoid a test-and-set race condition. */ + *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start); DBFEXIT; } -static int etrax_usb_submit_urb(struct urb *urb) +static void etrax_usb_complete_ctrl_urb(urb_t *urb, int status) { - etrax_hc_t *hc; - int rval = -EINVAL; - - DBFENTER; + etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + int epid = urb_priv->epid; - urb->next = NULL; + DBFENTER; - dump_urb(urb); - submit_urb_count++; - - hc = (etrax_hc_t*) urb->dev->bus->hcpriv; - - if (usb_pipedevice(urb->pipe) == hc->rh.devnum) { - /* This request if for the Virtual Root Hub */ - rval = etrax_rh_submit_urb(urb); - - } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { - rval = etrax_usb_submit_ctrl_urb(urb); + if (status) + warn("Completing ctrl urb with status %d.", status); - } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { - rval = etrax_usb_submit_bulk_urb(urb); + dbg_ctrl("Completing ctrl epid %d, urb 0x%lx", epid, (unsigned long)urb); - } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { - int bustime; + /* Remove this urb from the list. */ + urb_list_del(urb, epid); - if (urb->bandwidth == 0) { - bustime = usb_check_bandwidth(urb->dev, urb); - if (bustime < 0) { - rval = bustime; - } else { - usb_claim_bandwidth(urb->dev, urb, bustime, 0); - rval = etrax_usb_submit_intr_urb(urb); - } - - } - } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { - warn("Isochronous traffic is not supported !!!"); - rval = -EINVAL; + /* For an IN pipe, we always set the actual length, regardless of whether there was + an error or not (which means the device driver can use the data if it wants to). */ + if (usb_pipein(urb->pipe)) { + urb->actual_length = urb_priv->rx_offset; } - DBFEXIT; + /* FIXME: Is there something of the things below we shouldn't do if there was an error? + Like, maybe we shouldn't insert more traffic. */ - return rval; -} + /* Remember to free the SBs. */ + etrax_remove_from_sb_list(urb); + kfree(urb_priv); + urb->hcpriv = 0; + + /* If there are any more urbs in the list we'd better start sending. */ + if (!urb_list_empty(epid)) { + urb_t *new_urb; + + /* Get the first urb. */ + new_urb = urb_list_first(epid); + assert(new_urb); -static int etrax_usb_unlink_urb(struct urb *urb) -{ - etrax_hc_t *hc = urb->dev->bus->hcpriv; - int epid; - int devnum, endpoint, slow, maxlen, out_traffic; - etrax_urb_priv_t *hc_priv; - unsigned long flags; - - DBFENTER; - dump_urb(urb); - devnum = usb_pipedevice(urb->pipe); - endpoint = usb_pipeendpoint(urb->pipe); - slow = usb_pipeslow(urb->pipe); - maxlen = usb_maxpacket(urb->dev, urb->pipe, - usb_pipeout(urb->pipe)); - out_traffic = usb_pipeout(urb->pipe); - - epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic); + dbg_ctrl("More ctrl for epid %d, first urb = 0x%lx", epid, (unsigned long)new_urb); - if (epid == -1) - return 0; - - if (usb_pipedevice(urb->pipe) == hc->rh.devnum) { - int ret; - ret = etrax_rh_unlink_urb(urb); - DBFEXIT; - return ret; - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) { - int ret; - ret = etrax_usb_unlink_intr_urb(urb); - urb->status = -ENOENT; - if (urb->complete) { - urb->complete(urb); - } - DBFEXIT; - return ret; + etrax_usb_add_to_ctrl_sb_list(new_urb, epid); } - - info("Unlink of BULK or CTRL"); - - save_flags(flags); - cli(); - for (epid = 0; epid < 32; epid++) { - struct urb *u = URB_List[epid]; - struct urb *prev = NULL; - int pos = 0; - - for (; u; u = u->next) { - pos++; - if (u == urb) { - if (!prev) { - URB_List[epid] = u->next; - } else { - prev->next = u->next; - } + urb->status = status; - restore_flags(flags); - - if (!prev) { - if (usb_pipetype(u->pipe) == PIPE_CONTROL) { - if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) { - /* The EP was enabled, disable it and wait */ - TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); - while (*R_DMA_CH8_SUB1_EP == virt_to_phys(&TxCtrlEPList[epid])); - } - } else if (usb_pipetype(u->pipe) == PIPE_BULK) { - if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) { - TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); - while (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[epid])); - } - } - } - - info("Found urb at epid %d, pos %d", epid, pos); - - u->status = -ENOENT; - if (u->complete) { - u->complete(u); - } - - hc_priv = (etrax_urb_priv_t *)u->hcpriv; - cleanup_sb(hc_priv->first_sb); - kfree(hc_priv); + /* We let any non-zero status from the layer above have precedence. */ + if (status == 0) { + /* USB_DISABLE_SPD means that short reads (shorter than the endpoint's max length) + is to be treated as an error. */ + if (urb->transfer_flags & USB_DISABLE_SPD) { + if (usb_pipein(urb->pipe) && + (urb->actual_length != + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) { + urb->status = -EREMOTEIO; + } + } + } + + if (urb->complete) { + urb->complete(urb); + } - DBFEXIT; - return 0; - } - prev = u; - } + if (urb_list_empty(epid)) { + /* No more traffic. Time to clean up. */ + etrax_usb_free_epid(epid); + /* Must set sub pointer to 0. */ + dbg_ctrl("No ctrl for epid %d", epid); + TxCtrlEPList[epid].sub = 0; } - restore_flags(flags); - DBFEXIT; - return 0; } -static int etrax_usb_get_frame_number(struct usb_device *usb_dev) +static int etrax_usb_submit_intr_urb(urb_t *urb) { + + int epid; + DBFENTER; - DBFEXIT; - return (*R_USB_FM_NUMBER); -} + + if (usb_pipeout(urb->pipe)) { + /* Unsupported transfer type. + We don't support interrupt out traffic. (If we do, we can't support + intervals for neither in or out traffic, but are forced to schedule all + interrupt traffic in one frame.) */ + return -EINVAL; + } -static int etrax_usb_allocate_dev(struct usb_device *usb_dev) -{ - DBFENTER; - DBFEXIT; - return 0; -} + epid = etrax_usb_setup_epid(urb); + if (epid == -1) { + DBFEXIT; + return -ENOMEM; + } -static int etrax_usb_deallocate_dev(struct usb_device *usb_dev) -{ - DBFENTER; - DBFEXIT; - return 0; -} + if (!urb_list_empty(epid)) { + /* There is already a queued urb for this endpoint. */ + etrax_usb_free_epid(epid); + return -ENXIO; + } + + urb->status = -EINPROGRESS; -static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs) -{ - DBFENTER; + dbg_intr("Add intr urb 0x%lx, to list, epid %d", (unsigned long)urb, epid); - if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) { - info("dma8_sub0_descr (BULK) intr."); - *R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do); - } - if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) { - info("dma8_sub1_descr (CTRL) intr."); - *R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do); - } - if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) { - info("dma8_sub2_descr (INT) intr."); - *R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do); - } - if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) { - info("dma8_sub3_descr (ISO) intr."); - *R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do); - } + urb_list_add(urb, epid); + etrax_usb_add_to_intr_sb_list(urb, epid); + + return 0; DBFEXIT; } -static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs) +static void etrax_usb_add_to_intr_sb_list(urb_t *urb, int epid) { - int epid = 0; - struct urb *urb; + + volatile USB_EP_Desc_t *tmp_ep; + volatile USB_EP_Desc_t *first_ep; + + char maxlen; + int interval; + int i; + etrax_urb_priv_t *urb_priv; - - *R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do); + + DBFENTER; - while (myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) { - if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) { + maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + interval = urb->interval; - goto skip_out; - } + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + assert(urb_priv != NULL); + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); + urb->hcpriv = urb_priv; - if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) { - - goto skip_out; - } - - epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status); + first_ep = &TxIntrEPList[0]; - urb = URB_List[epid]; + /* Round of the interval to 2^n, it is obvious that this code favours + smaller numbers, but that is actually a good thing */ + /* FIXME: The "rounding error" for larger intervals will be quite + large. For in traffic this shouldn't be a problem since it will only + mean that we "poll" more often. */ + for (i = 0; interval; i++) { + interval = interval >> 1; + } + interval = 1 << (i - 1); - if (urb && usb_pipein(urb->pipe)) { - urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + dbg_intr("Interval rounded to %d", interval); - if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { - struct in_chunk *in; - dbg_intr("Packet for epid %d in rx buffers", epid); - in = kmalloc(sizeof(struct in_chunk), GFP_ATOMIC); - in->length = myNextRxDesc->hw_len; - in->data = kmalloc(in->length, GFP_ATOMIC); - memcpy(in->data, phys_to_virt(myNextRxDesc->buf), in->length); - list_add_tail(&in->list, &urb_priv->ep_in_list); -#ifndef ETRAX_USB_INTR_IRQ - etrax_usb_hc_intr_top_half(irq, vhc, regs); -#endif - - } else { - if ((urb_priv->rx_offset + myNextRxDesc->hw_len) > - urb->transfer_buffer_length) { - err("Packet (epid: %d) in RX buffer (%d) was bigger " - "than the URB has room for (%d)!!!", epid, urb_priv->rx_offset + myNextRxDesc->hw_len, urb->transfer_buffer_length); - goto skip_out; - } + tmp_ep = first_ep; + i = 0; + do { + if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) { + if ((i % interval) == 0) { + /* Insert the traffic ep after tmp_ep */ + USB_EP_Desc_t *ep_desc; + USB_SB_Desc_t *sb_desc; + + dbg_intr("Inserting EP for epid %d", epid); + + ep_desc = (USB_EP_Desc_t *) + kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + sb_desc = (USB_SB_Desc_t *) + kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(ep_desc != NULL); + CHECK_ALIGN(ep_desc); + assert(sb_desc != NULL); - memcpy(urb->transfer_buffer + urb_priv->rx_offset, - phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len); + ep_desc->sub = virt_to_phys(sb_desc); + ep_desc->hw_len = 0; + ep_desc->command = (IO_FIELD(USB_EP_command, epid, epid) | + IO_STATE(USB_EP_command, enable, yes)); + + + /* Round upwards the number of packets of size maxlen + that this SB descriptor should receive. */ + sb_desc->sw_len = urb->transfer_buffer_length ? + (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; + sb_desc->next = 0; + sb_desc->buf = 0; + sb_desc->command = + (IO_FIELD(USB_SB_command, rem, urb->transfer_buffer_length % maxlen) | + IO_STATE(USB_SB_command, tt, in) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); - urb_priv->rx_offset += myNextRxDesc->hw_len; - } - - if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) { - urb_priv->eot = 1; + ep_desc->next = tmp_ep->next; + tmp_ep->next = virt_to_phys(ep_desc); } - - } else { - err("This is almost fatal, inpacket for epid %d which does not exist " - " or is out!!!\nURB was at 0x%08lX", epid, (unsigned long)urb); - - goto skip_out; + i++; } + tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next); + } while (tmp_ep != first_ep); - skip_out: - myPrevRxDesc = myNextRxDesc; - myPrevRxDesc->command |= IO_MASK(USB_IN_command, eol); - myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol); - myLastRxDesc = myPrevRxDesc; - myNextRxDesc->status = 0; - myNextRxDesc = phys_to_virt(myNextRxDesc->next); - } + /* Note that first_sb/last_sb doesn't apply to interrupt traffic. */ + urb_priv->epid = epid; + + /* We start the DMA sub channel without checking if it's running or not, because: + 1) If it's already running, issuing the start command is a nop. + 2) We avoid a test-and-set race condition. */ + *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start); + + DBFEXIT; } -static void cleanup_sb(USB_SB_Desc_t *sb) +static void etrax_usb_complete_intr_urb(urb_t *urb, int status) { - USB_SB_Desc_t *next_sb; - + etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + int epid = urb_priv->epid; + DBFENTER; - if (sb == NULL) { - err("cleanup_sb was given a NULL pointer"); - return; - } + if (status) + warn("Completing intr urb with status %d.", status); - while (!(sb->command & IO_MASK(USB_SB_command, eol))) { - next_sb = (USB_SB_Desc_t *)phys_to_virt(sb->next); - kmem_cache_free(usb_desc_cache, sb); - sb = next_sb; - } + dbg_intr("Completing intr epid %d, urb 0x%lx", epid, (unsigned long)urb); - kmem_cache_free(usb_desc_cache, sb); + urb->status = status; + urb->actual_length = urb_priv->rx_offset; - DBFEXIT; + dbg_intr("interrupt urb->actual_length = %d", urb->actual_length); + /* We let any non-zero status from the layer above have precedence. */ + if (status == 0) { + /* USB_DISABLE_SPD means that short reads (shorter than the endpoint's max length) + is to be treated as an error. */ + if (urb->transfer_flags & USB_DISABLE_SPD) { + if (urb->actual_length != + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) { + urb->status = -EREMOTEIO; + } + } + } + + if (urb->complete) { + urb->complete(urb); + } + + /* Device driver has taken care of the data now. */ + urb_priv->rx_offset = 0; + + DBFEXIT; } -static void handle_control_transfer_attn(int epid, int status) + +static int etrax_usb_submit_isoc_urb(urb_t *urb) { - struct urb *old_urb; - etrax_urb_priv_t *hc_priv; + int epid; DBFENTER; - clear_bit(epid, (void *)&ep_really_active); - - old_urb = URB_List[epid]; - URB_List[epid] = old_urb->next; - - /* if (status == 0 && IN) find data and copy to urb */ - if (status == 0 && usb_pipein(old_urb->pipe)) { - unsigned long flags; - etrax_urb_priv_t *urb_priv; - - urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv; - save_flags(flags); - cli(); - if (urb_priv->eot == 1) { - old_urb->actual_length = urb_priv->rx_offset; - dbg_ctrl("urb_priv->rx_offset: %d in handle_control_attn", urb_priv->rx_offset); - } else { - status = -EPROTO; - old_urb->actual_length = 0; - err("(CTRL) No eot set in IN data!!! rx_offset: %d", urb_priv->rx_offset); - } - - restore_flags(flags); - } - - /* If there are any more URB's in the list we'd better start sending */ - if (URB_List[epid]) { - etrax_usb_do_ctrl_hw_add(URB_List[epid], epid, - usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe, - usb_pipeout(URB_List[epid]->pipe))); - } -#if 1 - else { - /* This means that this EP is now free, deconfigure it */ - etrax_usb_free_epid(epid); + /* Is there an active epid for this urb ? */ + epid = etrax_usb_setup_epid(urb); + if (epid == -1) { + DBFEXIT; + return -ENOMEM; } -#endif - /* Remember to free the SB's */ - hc_priv = (etrax_urb_priv_t *)old_urb->hcpriv; - cleanup_sb(hc_priv->first_sb); - kfree(hc_priv); + dbg_isoc("Submitting isoc urb = 0x%lx", (unsigned long)urb); - old_urb->status = status; - if (old_urb->complete) { - old_urb->complete(old_urb); - } + /* Ok, now we got valid endpoint, lets insert some traffic */ - DBFEXIT; -} + urb->status = -EINPROGRESS; + /* Find the last urb in the URB_List and add this urb after that one. + Also add the traffic, that is do an isoc_hw_add. This is important + to make this in "real time" since isochronous traffic is time sensitive. */ + + dbg_isoc("Adding isoc urb to (possibly empty) list"); + urb_list_add(urb, epid); + etrax_usb_add_to_isoc_sb_list(urb, epid); + + DBFEXIT; + return 0; +} -static void etrax_usb_hc_intr_bottom_half(void *data) +static void etrax_usb_add_to_isoc_sb_list(urb_t *urb, int epid) { - struct usb_reg_context *reg = (struct usb_reg_context *)data; + + int i = 0; - int error_code; - int epid; + etrax_urb_priv_t *urb_priv; + USB_SB_Desc_t *prev_sb_desc, *next_sb_desc, *temp_sb_desc; - __u32 r_usb_ept_data; + DBFENTER; - etrax_hc_t *hc = reg->hc; - __u16 r_usb_rh_port_status_1; - __u16 r_usb_rh_port_status_2; + prev_sb_desc = next_sb_desc = temp_sb_desc = NULL; - DBFENTER; + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + assert(urb_priv != NULL); + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); - if (reg->r_usb_irq_mask_read & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) { + urb->hcpriv = urb_priv; + urb_priv->epid = epid; + + if (usb_pipeout(urb->pipe)) { - /* - The Etrax RH does not include a wPortChange register, so this has - to be handled in software. See section 11.16.2.6.2 in USB 1.1 spec - for details. - */ + /* Not implemented yet! */ + dbg_isoc("Transfer for epid %d is OUT", epid); - r_usb_rh_port_status_1 = reg->r_usb_rh_port_status_1; - r_usb_rh_port_status_2 = reg->r_usb_rh_port_status_2; + /* Create one SB descriptor for each packet and link them together. */ + for (i = 0; i < urb->number_of_packets; i++) { - dbg_rh("port_status pending"); - dbg_rh("r_usb_rh_port_status_1: 0x%04X", r_usb_rh_port_status_1); - dbg_rh("r_usb_rh_port_status_2: 0x%04X", r_usb_rh_port_status_2); + next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(next_sb_desc != NULL); + + next_sb_desc->command = (IO_STATE(USB_SB_command, tt, out) | + IO_STATE(USB_SB_command, eot, yes)); + + next_sb_desc->sw_len = urb->iso_frame_desc[i].length; + next_sb_desc->buf = virt_to_phys(urb->transfer_buffer + urb->iso_frame_desc[i].offset); + + /* First SB descriptor that belongs to this urb */ + if (i == 0) + urb_priv->first_sb = next_sb_desc; + else + prev_sb_desc->next = virt_to_phys(next_sb_desc); + + prev_sb_desc = next_sb_desc; + } + /* Check if full length transfer. */ + if (urb->iso_frame_desc[urb->number_of_packets - 1].length == + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) { + next_sb_desc->command |= IO_STATE(USB_SB_command, full, yes); + } - /* C_PORT_CONNECTION is set on any transition */ - hc->rh.wPortChange_1 |= - ((r_usb_rh_port_status_1 & (1 << RH_PORT_CONNECTION)) != - (hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_CONNECTION))) ? - (1 << RH_PORT_CONNECTION) : 0; - - hc->rh.wPortChange_2 |= - ((r_usb_rh_port_status_2 & (1 << RH_PORT_CONNECTION)) != - (hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_CONNECTION))) ? - (1 << RH_PORT_CONNECTION) : 0; + next_sb_desc->command |= IO_STATE(USB_SB_command, eol, yes); + next_sb_desc->next = 0; + urb_priv->last_sb = next_sb_desc; + + } else if (usb_pipein(urb->pipe)) { - /* C_PORT_ENABLE is _only_ set on a one to zero transition */ - hc->rh.wPortChange_1 |= - ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_ENABLE)) - && !(r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ? - (1 << RH_PORT_ENABLE) : 0; - - hc->rh.wPortChange_2 |= - ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_ENABLE)) - && !(r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ? - (1 << RH_PORT_ENABLE) : 0; - - /* C_PORT_SUSPEND seems difficult, lets ignore it.. (for now) */ - - /* C_PORT_RESET is _only_ set on a transition from the resetting state - to the enabled state */ - hc->rh.wPortChange_1 |= - ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_RESET)) - && (r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ? - (1 << RH_PORT_RESET) : 0; - - hc->rh.wPortChange_2 |= - ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_RESET)) - && (r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ? - (1 << RH_PORT_RESET) : 0; - - hc->rh.prev_wPortStatus_1 = r_usb_rh_port_status_1; - hc->rh.prev_wPortStatus_2 = r_usb_rh_port_status_2; + dbg_isoc("Transfer for epid %d is IN", epid); + dbg_isoc("transfer_buffer_length = %d", urb->transfer_buffer_length); + dbg_isoc("rem is calculated to %d", urb->iso_frame_desc[urb->number_of_packets - 1].length); + + /* Note that in descriptors for periodic traffic are not consumed. This means that + the USB controller never propagates in the SB list. In other words, if there already + is an SB descriptor in the list for this EP we don't have to do anything. */ + if (TxIsocEPList[epid].sub == 0) { + dbg_isoc("Isoc traffic not already running, allocating SB"); + + next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + assert(next_sb_desc != NULL); + + next_sb_desc->command = (IO_STATE(USB_SB_command, tt, in) | + IO_STATE(USB_SB_command, eot, yes) | + IO_STATE(USB_SB_command, eol, yes)); + + next_sb_desc->sw_len = urb->number_of_packets; + next_sb_desc->buf = 0; + + /* The rem field is don't care for isoc traffic, so we don't set it. */ + + /* Only one SB descriptor that belongs to this urb. */ + urb_priv->first_sb = next_sb_desc; + urb_priv->last_sb = next_sb_desc; + + } else { + + dbg_isoc("Isoc traffic already running, just setting first/last_sb"); + + /* Each EP for isoc in will have only one SB descriptor, setup when submitting the + already active urb. Note that even though we may have several first_sb/last_sb + pointing at the same SB descriptor, they are freed only once (when the list has + become empty). */ + urb_priv->first_sb = phys_to_virt(TxIsocEPList[epid].sub); + urb_priv->last_sb = phys_to_virt(TxIsocEPList[epid].sub); + return; + } + + } + + /* Find the spot to insert this urb and add it. */ + if (TxIsocEPList[epid].sub == 0) { + /* First SB descriptor inserted in this list (in or out). */ + dbg_isoc("Inserting SB desc first in list"); + TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb); + } else { + /* Isochronous traffic is already running, insert new traffic last (only out). */ + dbg_isoc("Inserting SB desc last in list"); + temp_sb_desc = phys_to_virt(TxIsocEPList[epid].sub); + while (!(temp_sb_desc->command & IO_MASK(USB_SB_command, eol))) { + temp_sb_desc = phys_to_virt(temp_sb_desc->next); + } + /* Next pointer must be set before eol is removed. */ + temp_sb_desc->next = virt_to_phys(urb_priv->first_sb); + /* Clear the previous end of list flag since there is a new in the + added SB descriptor list. */ + temp_sb_desc->command &= ~IO_MASK(USB_SB_command, eol); + } + + if (urb->transfer_flags & USB_ISO_ASAP) { + /* The isoc transfer should be started as soon as possible. The start_frame + field is a return value if URB_ISO_ASAP was set. Comparing R_USB_FM_NUMBER + with a USB Chief trace shows that the first isoc IN token is sent 2 frames + later. I'm not sure how this affects usage of the start_frame field by the + device driver, or how it affects things when USB_ISO_ASAP is not set, so + therefore there's no compensation for the 2 frame "lag" here. */ + urb->start_frame = (*R_USB_FM_NUMBER & 0x7ff); + TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); + urb_priv->urb_state = STARTED; + dbg_isoc("URB_ISO_ASAP set, urb->start_frame set to %d", urb->start_frame); + } else { + /* Not started yet. */ + urb_priv->urb_state = NOT_STARTED; + } + + /* We start the DMA sub channel without checking if it's running or not, because: + 1) If it's already running, issuing the start command is a nop. + 2) We avoid a test-and-set race condition. */ + *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start); + + DBFEXIT; +} + +static void etrax_usb_complete_isoc_urb(urb_t *urb, int status) +{ + etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + int epid = urb_priv->epid; + + DBFENTER; + + if (status) + warn("Completing isoc urb with status %d.", status); + + if (usb_pipein(urb->pipe)) { + + /* Move this one down the list. */ + urb_list_move_last(urb, epid); + + /* Mark the now first urb as started (may already be). */ + ((etrax_urb_priv_t *)(urb_list_first(epid)->hcpriv))->urb_state = STARTED; } - for (epid = 0; epid < 32; epid++) { + urb->status = status; + if (urb->complete) { + urb->complete(urb); + } - unsigned long flags; + DBFEXIT; +} - save_flags(flags); - cli(); +static void etrax_usb_complete_urb(urb_t *urb, int status) +{ + switch (usb_pipetype(urb->pipe)) { + case PIPE_BULK: + etrax_usb_complete_bulk_urb(urb, status); + break; + case PIPE_CONTROL: + etrax_usb_complete_ctrl_urb(urb, status); + break; + case PIPE_INTERRUPT: + etrax_usb_complete_intr_urb(urb, status); + break; + case PIPE_ISOCHRONOUS: + etrax_usb_complete_isoc_urb(urb, status); + break; + default: + err("Unknown pipetype"); + } +} - *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop(); - r_usb_ept_data = *R_USB_EPT_DATA; - restore_flags(flags); - if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) { - warn("Was hold for epid %d", epid); - continue; - } +static void etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs) +{ + usb_interrupt_registers_t *reg; + unsigned long flags; + __u32 irq_mask; + __u8 status; + __u32 epid_attn; + __u16 port_status_1; + __u16 port_status_2; + __u32 fm_number; - if (!(r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, valid))) { - continue; - } - - - if (test_bit(epid, (void *)®->r_usb_epid_attn)) { + DBFENTER; - if (URB_List[epid] == NULL) { - err("R_USB_EPT_DATA is 0x%08X", r_usb_ept_data); - err("submit urb has been called %lu times..", submit_urb_count); - err("EPID_ATTN for epid %d, with NULL entry in list", epid); - return; - } - - dbg_ep("r_usb_ept_data [%d] == 0x%08X", epid, - r_usb_ept_data); - - error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code, - r_usb_ept_data); - - if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) { - /* no_error means that this urb was sucessfully sent or that we have - some undefinde error*/ - - if (IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3 || - IO_EXTRACT(R_USB_EPT_DATA, error_count_in, r_usb_ept_data) == 3) { - /* Actually there were transmission errors */ - warn("Undefined error for epid %d", epid); - if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) { - handle_control_transfer_attn(epid, -EPROTO); - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) { - handle_bulk_transfer_attn(epid, -EPROTO); - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) { - handle_intr_transfer_attn(epid, -EPROTO); - } - - } else { - - if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) { - if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) { - etrax_usb_do_intr_recover(epid); - } else { - panic("Epid attention for epid %d (none INTR), with no errors and no " - "exessive retry r_usb_status is 0x%02X\n", - epid, reg->r_usb_status); - } - - } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) { - panic("Epid attention for epid %d, with no errors and no " - "exessive retry r_usb_status is 0x%02X\n", - epid, reg->r_usb_status); - - } - - warn("Epid attention for epid %d, with no errors and no " - "exessive retry r_usb_status is 0x%02X", - epid, reg->r_usb_status); - warn("OUT error count: %d", IO_EXTRACT(R_USB_EPT_DATA, error_count_out, - r_usb_ept_data)); - warn("IN error count: %d", IO_EXTRACT(R_USB_EPT_DATA, error_count_in, - r_usb_ept_data)); - + /* Read critical registers into local variables, do kmalloc afterwards. */ + save_flags(flags); + cli(); + + irq_mask = *R_USB_IRQ_MASK_READ; + /* Reading R_USB_STATUS clears the ctl_status interrupt. Note that R_USB_STATUS + must be read before R_USB_EPID_ATTN since reading the latter clears the + ourun and perror fields of R_USB_STATUS. */ + status = *R_USB_STATUS; + + /* Reading R_USB_EPID_ATTN clears the iso_eof, bulk_eot and epid_attn interrupts. */ + epid_attn = *R_USB_EPID_ATTN; + + /* Reading R_USB_RH_PORT_STATUS_1 and R_USB_RH_PORT_STATUS_2 clears the + port_status interrupt. */ + port_status_1 = *R_USB_RH_PORT_STATUS_1; + port_status_2 = *R_USB_RH_PORT_STATUS_2; + + /* Reading R_USB_FM_NUMBER clears the sof interrupt. */ + /* Note: the lower 11 bits contain the actual frame number, sent with each sof. */ + fm_number = *R_USB_FM_NUMBER; - } - - } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, stall)) { - warn("Stall for epid %d", epid); - if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) { - handle_control_transfer_attn(epid, -EPIPE); - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) { - handle_bulk_transfer_attn(epid, -EPIPE); - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) { - handle_intr_transfer_attn(epid, -EPIPE); - } - - - } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, bus_error)) { - panic("USB bus error for epid %d\n", epid); - - } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) { - warn("Buffer error for epid %d", epid); + restore_flags(flags); - if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) { - handle_control_transfer_attn(epid, -EPROTO); - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) { - handle_bulk_transfer_attn(epid, -EPROTO); - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) { - handle_intr_transfer_attn(epid, -EPROTO); - } + reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, SLAB_ATOMIC); - } - } else if (test_bit(epid, (void *)&ep_really_active)) { - /* Should really be else if (testbit(really active)) */ + assert(reg != NULL); - if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) { + reg->hc = (etrax_hc_t *)vhc; - if (!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable))) { - /* Now we have to verify that this CTRL endpoint got disabled - cause it reached end of list with no error */ - - if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) == - IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) { - /* - This means that the endpoint has no error, is disabled - and had inserted traffic, - i.e. transfer sucessfully completed - */ - dbg_ctrl("Last SB for CTRL %d sent sucessfully", epid); - handle_control_transfer_attn(epid, 0); - } - } - - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) { - if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable))) { - /* Now we have to verify that this BULK endpoint go disabled - cause it reached end of list with no error */ - - if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) == - IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) { - /* - This means that the endpoint has no error, is disabled - and had inserted traffic, - i.e. transfer sucessfully completed - */ - dbg_bulk("Last SB for BULK %d sent sucessfully", epid); - handle_bulk_transfer_attn(epid, 0); - } - } - } else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) { - handle_intr_transfer_attn(epid, 0); - } - } - - } + /* Now put register values into kmalloc'd area. */ + reg->r_usb_irq_mask_read = irq_mask; + reg->r_usb_status = status; + reg->r_usb_epid_attn = epid_attn; + reg->r_usb_rh_port_status_1 = port_status_1; + reg->r_usb_rh_port_status_2 = port_status_2; + reg->r_usb_fm_number = fm_number; + + reg->usb_bh.sync = 0; + reg->usb_bh.routine = etrax_usb_hc_interrupt_bottom_half; + reg->usb_bh.data = reg; + + queue_task(®->usb_bh, &tq_immediate); + mark_bh(IMMEDIATE_BH); + + DBFEXIT; +} + +static void etrax_usb_hc_interrupt_bottom_half(void *data) +{ + usb_interrupt_registers_t *reg = (usb_interrupt_registers_t *)data; + __u32 irq_mask = reg->r_usb_irq_mask_read; + + DBFENTER; - kfree(reg); + /* Interrupts are handled in order of priority. */ + if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, epid_attn)) { + etrax_usb_hc_epid_attn_interrupt(reg); + } + if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) { + etrax_usb_hc_port_status_interrupt(reg); + } + if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, ctl_status)) { + etrax_usb_hc_ctl_status_interrupt(reg); + } + if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, iso_eof)) { + etrax_usb_hc_isoc_eof_interrupt(); + } + if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, bulk_eot)) { + /* Update/restart the bulk start timer since obviously the channel is running. */ + mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL); + /* Update/restart the bulk eot timer since we just received an bulk eot interrupt. */ + mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL); + + etrax_usb_hc_bulk_eot_interrupt(0); + } + + kmem_cache_free(top_half_reg_cache, reg); DBFEXIT; } -static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs) +void etrax_usb_hc_isoc_eof_interrupt(void) { - struct usb_reg_context *reg; + urb_t *urb; + etrax_urb_priv_t *urb_priv; + int epid; DBFENTER; - reg = (struct usb_reg_context *)kmalloc(sizeof(struct usb_reg_context), GFP_ATOMIC); + /* Do not check the invalid epid (it has a valid sub pointer). */ + for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) { + + if (TxIsocEPList[epid].sub == 0) { + /* Nothing here to see. */ + continue; + } - if (!(reg)) { - panic("kmalloc failed in top_half\n"); - } + /* Get the first urb (if any). */ + urb = urb_list_first(epid); + if (urb == 0) { + warn("Ignoring NULL urb"); + continue; + } + + /* Sanity check. */ + assert(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS); + + urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + assert(urb_priv); + + if (urb_priv->urb_state == NOT_STARTED) { + + /* If ASAP is not set and urb->start_frame is the current frame, + start the transfer. */ + if (!(urb->transfer_flags & USB_ISO_ASAP) && + (urb->start_frame == (*R_USB_FM_NUMBER & 0x7ff))) { + + dbg_isoc("Enabling isoc IN EP descr for epid %d", epid); + TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); + + /* This urb is now active. */ + urb_priv->urb_state = STARTED; + continue; + } + } + } + + DBFEXIT; - reg->hc = (etrax_hc_t *)vhc; - reg->r_usb_irq_mask_read = *R_USB_IRQ_MASK_READ; - reg->r_usb_status = *R_USB_STATUS; +} -#if 0 - if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) { - panic("r_usb_status said perror\n"); - } - if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) { - panic("r_usb_status said ourun !!!\n"); - } -#endif - - reg->r_usb_epid_attn = *R_USB_EPID_ATTN; +void etrax_usb_hc_bulk_eot_interrupt(int timer_induced) +{ + int epid; + + /* The technique is to run one urb at a time, wait for the eot interrupt at which + point the EP descriptor has been disabled. */ + + DBFENTER; + dbg_bulk("bulk eot%s", timer_induced ? ", called by timer" : ""); + + for (epid = 0; epid < NBR_OF_EPIDS; epid++) { + + if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) && + (TxBulkEPList[epid].sub != 0)) { + + urb_t *urb; + etrax_urb_priv_t *urb_priv; + unsigned long flags; + __u32 r_usb_ept_data; + + /* Found a disabled EP descriptor which has a non-null sub pointer. + Verify that this ctrl EP descriptor got disabled no errors. + FIXME: Necessary to check error_code? */ + dbg_bulk("for epid %d?", epid); + + /* Get the first urb. */ + urb = urb_list_first(epid); + + /* FIXME: Could this happen for valid reasons? Why did it disappear? Because of + wrong unlinking? */ + if (!urb) { + warn("NULL urb for epid %d", epid); + continue; + } + + assert(urb); + urb_priv = (etrax_urb_priv_t *)urb->hcpriv; + assert(urb_priv); + + /* Sanity checks. */ + assert(usb_pipetype(urb->pipe) == PIPE_BULK); + if (phys_to_virt(TxBulkEPList[epid].sub) != urb_priv->last_sb) { + err("bulk endpoint got disabled before reaching last sb"); + } + + /* For bulk IN traffic, there seems to be a race condition between + between the bulk eot and eop interrupts, or rather an uncertainty regarding + the order in which they happen. Normally we expect the eop interrupt from + DMA channel 9 to happen before the eot interrupt. + + Therefore, we complete the bulk IN urb in the rx interrupt handler instead. */ + + if (usb_pipein(urb->pipe)) { + dbg_bulk("in urb, continuing"); + continue; + } + + save_flags(flags); + cli(); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + r_usb_ept_data = *R_USB_EPT_DATA; + restore_flags(flags); + + if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) == + IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) { + /* This means that the endpoint has no error, is disabled + and had inserted traffic, i.e. transfer successfully completed. */ + etrax_usb_complete_bulk_urb(urb, 0); + } else { + /* Shouldn't happen. We expect errors to be caught by epid attention. */ + err("Found disabled bulk EP desc, error_code != no_error"); + } + } + } + + /* Normally, we should find (at least) one disabled EP descriptor with a valid sub pointer. + However, because of the uncertainty in the deliverance of the eop/eot interrupts, we may + not. Also, we might find two disabled EPs when handling an eot interrupt, and then find + none the next time. */ + + DBFEXIT; + +} + +void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg) +{ + /* This function handles the epid attention interrupt. There are a variety of reasons + for this interrupt to happen (Designer's Reference, p. 8 - 22 for the details): + + invalid ep_id - Invalid epid in an EP (EP disabled). + stall - Not strictly an error condition (EP disabled). + 3rd error - Three successive transaction errors (EP disabled). + buffer ourun - Buffer overrun or underrun (EP disabled). + past eof1 - Intr or isoc transaction proceeds past EOF1. + near eof - Intr or isoc transaction would not fit inside the frame. + zout transfer - If zout transfer for a bulk endpoint (EP disabled). + setup transfer - If setup transfer for a non-ctrl endpoint (EP disabled). */ + + int epid; + + + DBFENTER; + + /* Note that we loop through all epids. We still want to catch errors for + the invalid one, even though we might handle them differently. */ + for (epid = 0; epid < NBR_OF_EPIDS; epid++) { - reg->r_usb_rh_port_status_1 = *R_USB_RH_PORT_STATUS_1; - reg->r_usb_rh_port_status_2 = *R_USB_RH_PORT_STATUS_2; + if (test_bit(epid, (void *)®->r_usb_epid_attn)) { + + urb_t *urb; + __u32 r_usb_ept_data; + unsigned long flags; + int error_code; + + save_flags(flags); + cli(); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + /* Note that although there are separate R_USB_EPT_DATA and R_USB_EPT_DATA_ISO + registers, they are located at the same address and are of the same size. + In other words, this read should be ok for isoc also. */ + r_usb_ept_data = *R_USB_EPT_DATA; + restore_flags(flags); + + /* First some sanity checks. */ + if (epid == INVALID_EPID) { + /* FIXME: What if it became disabled? Could seriously hurt interrupt + traffic. (Use do_intr_recover.) */ + warn("Got epid_attn for INVALID_EPID (%d).", epid); + err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data); + err("R_USB_STATUS = 0x%x", reg->r_usb_status); + continue; + } else if (epid == DUMMY_EPID) { + /* We definitely don't care about these ones. Besides, they are + always disabled, so any possible disabling caused by the + epid attention interrupt is irrelevant. */ + warn("Got epid_attn for DUMMY_EPID (%d).", epid); + continue; + } + + /* Get the first urb in the urb list for this epid. We blatantly assume + that only the first urb could have caused the epid attention. + (For bulk and ctrl, only one urb is active at any one time. For intr + and isoc we remove them once they are completed.) */ + urb = urb_list_first(epid); + + if (urb == NULL) { + err("Got epid_attn for epid %i with no urb.", epid); + err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data); + err("R_USB_STATUS = 0x%x", reg->r_usb_status); + continue; + } + + switch (usb_pipetype(urb->pipe)) { + case PIPE_BULK: + warn("Got epid attn for bulk endpoint, epid %d", epid); + break; + case PIPE_CONTROL: + warn("Got epid attn for control endpoint, epid %d", epid); + break; + case PIPE_INTERRUPT: + warn("Got epid attn for interrupt endpoint, epid %d", epid); + break; + case PIPE_ISOCHRONOUS: + warn("Got epid attn for isochronous endpoint, epid %d", epid); + break; + } + + if (usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) { + if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) { + warn("Hold was set for epid %d.", epid); + continue; + } + } + + /* Even though error_code occupies bits 22 - 23 in both R_USB_EPT_DATA and + R_USB_EPT_DATA_ISOC, we separate them here so we don't forget in other places. */ + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + error_code = IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data); + } else { + error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data); + } + + /* Using IO_STATE_VALUE on R_USB_EPT_DATA should be ok for isoc also. */ + if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) { - reg->usb_bh.sync = 0; - reg->usb_bh.routine = etrax_usb_hc_intr_bottom_half; - reg->usb_bh.data = reg; + /* Isoc traffic doesn't have error_count_in/error_count_out. */ + if ((usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) && + (IO_EXTRACT(R_USB_EPT_DATA, error_count_in, r_usb_ept_data) == 3 || + IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3)) { + /* 3rd error. */ + warn("3rd error for epid %i", epid); + etrax_usb_complete_urb(urb, -EPROTO); + + } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) { + + warn("Perror for epid %d", epid); + + if (!(r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, valid))) { + /* invalid ep_id */ + panic("Perror because of invalid epid." + " Deconfigured too early?"); + } else { + /* past eof1, near eof, zout transfer, setup transfer */ + + /* Dump the urb and the relevant EP descriptor list. */ + + __dump_urb(urb); + __dump_ept_data(epid); + __dump_ep_list(usb_pipetype(urb->pipe)); + + panic("Something wrong with DMA descriptor contents." + " Too much traffic inserted?"); + } + } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) { + /* buffer ourun */ + panic("Buffer overrun/underrun for epid %d. DMA too busy?", epid); + } - queue_task(®->usb_bh, &tq_immediate); - mark_bh(IMMEDIATE_BH); + } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, stall)) { + /* Not really a protocol error, just says that the endpoint gave + a stall response. Note that error_code cannot be stall for isoc. */ + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + panic("Isoc traffic cannot stall"); + } + + warn("Stall for epid %d", epid); + etrax_usb_complete_urb(urb, -EPIPE); + + } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, bus_error)) { + /* Two devices responded to a transaction request. Must be resolved + by software. FIXME: Reset ports? */ + panic("Bus error for epid %d." + " Two devices responded to transaction request", + epid); + + } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) { + /* DMA overrun or underrun. */ + warn("Buffer overrun/underrun for epid %d. DMA too busy?", epid); - DBFEXIT; + /* It seems that error_code = buffer_error in + R_USB_EPT_DATA/R_USB_EPT_DATA_ISO and ourun = yes in R_USB_STATUS + are the same error. */ + etrax_usb_complete_urb(urb, -EPROTO); + } + } + } + + DBFEXIT; + +} + +void etrax_usb_bulk_start_timer_func(unsigned long dummy) +{ + + /* We might enable an EP descriptor behind the current DMA position when it's about + to decide that there are no more bulk traffic and it should stop the bulk channel. + Therefore we periodically check if the bulk channel is stopped and there is an + enabled bulk EP descriptor, in which case we start the bulk channel. */ + dbg_bulk("bulk_start_timer timed out."); + + if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) { + int epid; + + dbg_bulk("Bulk DMA channel not running."); + + for (epid = 0; epid < NBR_OF_EPIDS; epid++) { + if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) { + printk("Found enabled EP for epid %d, starting bulk channel.\n", + epid); + *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); + + /* Restart the bulk eot timer since we just started the bulk channel. */ + mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL); + + /* No need to search any further. */ + break; + } + } + } else { + dbg_bulk("Bulk DMA channel running."); + } +} + +void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg) +{ + etrax_hc_t *hc = reg->hc; + __u16 r_usb_rh_port_status_1 = reg->r_usb_rh_port_status_1; + __u16 r_usb_rh_port_status_2 = reg->r_usb_rh_port_status_2; + + DBFENTER; + + /* The Etrax RH does not include a wPortChange register, so this has to be handled in software + (by saving the old port status value for comparison when the port status interrupt happens). + See section 11.16.2.6.2 in the USB 1.1 spec for details. */ + + dbg_rh("hc->rh.prev_wPortStatus_1 = 0x%x", hc->rh.prev_wPortStatus_1); + dbg_rh("hc->rh.prev_wPortStatus_2 = 0x%x", hc->rh.prev_wPortStatus_2); + dbg_rh("r_usb_rh_port_status_1 = 0x%x", r_usb_rh_port_status_1); + dbg_rh("r_usb_rh_port_status_2 = 0x%x", r_usb_rh_port_status_2); + + /* C_PORT_CONNECTION is set on any transition. */ + hc->rh.wPortChange_1 |= + ((r_usb_rh_port_status_1 & (1 << RH_PORT_CONNECTION)) != + (hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_CONNECTION))) ? + (1 << RH_PORT_CONNECTION) : 0; + + hc->rh.wPortChange_2 |= + ((r_usb_rh_port_status_2 & (1 << RH_PORT_CONNECTION)) != + (hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_CONNECTION))) ? + (1 << RH_PORT_CONNECTION) : 0; + + /* C_PORT_ENABLE is _only_ set on a one to zero transition, i.e. when + the port is disabled, not when it's enabled. */ + hc->rh.wPortChange_1 |= + ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_ENABLE)) + && !(r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ? + (1 << RH_PORT_ENABLE) : 0; + + hc->rh.wPortChange_2 |= + ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_ENABLE)) + && !(r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ? + (1 << RH_PORT_ENABLE) : 0; + + /* C_PORT_SUSPEND is set to one when the device has transitioned out + of the suspended state, i.e. when suspend goes from one to zero. */ + hc->rh.wPortChange_1 |= + ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_SUSPEND)) + && !(r_usb_rh_port_status_1 & (1 << RH_PORT_SUSPEND))) ? + (1 << RH_PORT_SUSPEND) : 0; + + hc->rh.wPortChange_2 |= + ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_SUSPEND)) + && !(r_usb_rh_port_status_2 & (1 << RH_PORT_SUSPEND))) ? + (1 << RH_PORT_SUSPEND) : 0; + + + /* C_PORT_RESET is set when reset processing on this port is complete. */ + hc->rh.wPortChange_1 |= + ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_RESET)) + && !(r_usb_rh_port_status_1 & (1 << RH_PORT_RESET))) ? + (1 << RH_PORT_RESET) : 0; + + hc->rh.wPortChange_2 |= + ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_RESET)) + && !(r_usb_rh_port_status_2 & (1 << RH_PORT_RESET))) ? + (1 << RH_PORT_RESET) : 0; + + /* Save the new values for next port status change. */ + hc->rh.prev_wPortStatus_1 = r_usb_rh_port_status_1; + hc->rh.prev_wPortStatus_2 = r_usb_rh_port_status_2; + + dbg_rh("hc->rh.wPortChange_1 set to 0x%x", hc->rh.wPortChange_1); + dbg_rh("hc->rh.wPortChange_2 set to 0x%x", hc->rh.wPortChange_2); + + DBFEXIT; + +} + +void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg) +{ + DBFENTER; + + /* FIXME: What should we do if we get ourun or perror? Dump the EP and SB + list for the corresponding epid? */ + if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) { + panic("USB controller got ourun."); + } + if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) { + + /* Before, etrax_usb_do_intr_recover was called on this epid if it was + an interrupt pipe. I don't see how re-enabling all EP descriptors + will help if there was a programming error. */ + panic("USB controller got perror."); + } + + if (reg->r_usb_status & IO_MASK(R_USB_STATUS, device_mode)) { + /* We should never operate in device mode. */ + panic("USB controller in device mode."); + } + + /* These if-statements could probably be nested. */ + if (reg->r_usb_status & IO_MASK(R_USB_STATUS, host_mode)) { + //info("USB controller in host mode."); + } + if (reg->r_usb_status & IO_MASK(R_USB_STATUS, started)) { + //info("USB controller started."); + } + if (reg->r_usb_status & IO_MASK(R_USB_STATUS, running)) { + info("USB controller running."); + } + + DBFEXIT; + } -static int etrax_rh_submit_urb(struct urb *urb) + +static int etrax_rh_submit_urb(urb_t *urb) { struct usb_device *usb_dev = urb->dev; etrax_hc_t *hc = usb_dev->bus->hcpriv; unsigned int pipe = urb->pipe; - struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet; + devrequest *cmd = (devrequest *) urb->setup_packet; void *data = urb->transfer_buffer; int leni = urb->transfer_buffer_length; int len = 0; @@ -1999,10 +3246,14 @@ DBFENTER; + /* FIXME: What is this interrupt urb that is sent to the root hub? */ if (usb_pipetype (pipe) == PIPE_INTERRUPT) { dbg_rh("Root-Hub submit IRQ: every %d ms", urb->interval); hc->rh.urb = urb; hc->rh.send = 1; + /* FIXME: We could probably remove this line since it's done + in etrax_rh_init_int_timer. (Don't remove it from + etrax_rh_init_int_timer though.) */ hc->rh.interval = urb->interval; etrax_rh_init_int_timer(urb); DBFEXIT; @@ -2010,15 +3261,22 @@ return 0; } - bmRType_bReq = cmd->bRequestType | cmd->bRequest << 8; - wValue = le16_to_cpu(cmd->wValue); - wIndex = le16_to_cpu(cmd->wIndex); - wLength = le16_to_cpu(cmd->wLength); - - dbg_rh("bmRType_bReq : 0x%04X (%d)", bmRType_bReq, bmRType_bReq); - dbg_rh("wValue : 0x%04X (%d)", wValue, wValue); - dbg_rh("wIndex : 0x%04X (%d)", wIndex, wIndex); - dbg_rh("wLength : 0x%04X (%d)", wLength, wLength); +#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 4, 20) + bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8); + wValue = le16_to_cpu(cmd->wValue); + wIndex = le16_to_cpu(cmd->wIndex); + wLength = le16_to_cpu(cmd->wLength); +#else + bmRType_bReq = cmd->requesttype | (cmd->request << 8); + wValue = le16_to_cpu(cmd->value); + wIndex = le16_to_cpu(cmd->index); + wLength = le16_to_cpu(cmd->length); +#endif + + dbg_rh("bmRType_bReq : 0x%04x (%d)", bmRType_bReq, bmRType_bReq); + dbg_rh("wValue : 0x%04x (%d)", wValue, wValue); + dbg_rh("wIndex : 0x%04x (%d)", wIndex, wIndex); + dbg_rh("wLength : 0x%04x (%d)", wLength, wLength); switch (bmRType_bReq) { @@ -2050,13 +3308,11 @@ if (wIndex == 1) { *((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_1); *((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_1); - } - else if (wIndex == 2) { + } else if (wIndex == 2) { *((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_2); *((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_2); - } - else { - dbg_rh("RH_GET_STATUS whith invalid wIndex !!"); + } else { + dbg_rh("RH_GET_STATUS whith invalid wIndex!"); OK(0); } @@ -2081,9 +3337,10 @@ case (RH_PORT_ENABLE): if (wIndex == 1) { - dbg_rh("trying to do disable of port 1"); + dbg_rh("trying to do disable port 1"); *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, yes); + while (hc->rh.prev_wPortStatus_1 & IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes)); *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no); @@ -2091,9 +3348,10 @@ } else if (wIndex == 2) { - dbg_rh("trying to do disable of port 2"); + dbg_rh("trying to do disable port 2"); *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, yes); + while (hc->rh.prev_wPortStatus_2 & IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes)); *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no); @@ -2101,25 +3359,35 @@ } else { dbg_rh("RH_CLEAR_FEATURE->RH_PORT_ENABLE " - "with invalid wIndex == %d!!", wIndex); + "with invalid wIndex == %d!", wIndex); } OK (0); case (RH_PORT_SUSPEND): - /* Opposite to suspend should be resume, so well do a resume */ + /* Opposite to suspend should be resume, so we'll do a resume. */ + /* FIXME: USB 1.1, 11.16.2.2 says: + "Clearing the PORT_SUSPEND feature causes a host-initiated resume + on the specified port. If the port is not in the Suspended state, + the hub should treat this request as a functional no-operation." + Shouldn't we check if the port is in a suspended state before + resuming? */ + + /* Make sure the controller isn't busy. */ + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + if (wIndex == 1) { *R_USB_COMMAND = IO_STATE(R_USB_COMMAND, port_sel, port1) | - IO_STATE(R_USB_COMMAND, port_cmd, resume)| + IO_STATE(R_USB_COMMAND, port_cmd, resume) | IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); } else if (wIndex == 2) { *R_USB_COMMAND = IO_STATE(R_USB_COMMAND, port_sel, port2) | - IO_STATE(R_USB_COMMAND, port_cmd, resume)| + IO_STATE(R_USB_COMMAND, port_cmd, resume) | IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); } else { dbg_rh("RH_CLEAR_FEATURE->RH_PORT_SUSPEND " - "with invalid wIndex == %d!!", wIndex); + "with invalid wIndex == %d!", wIndex); } OK (0); @@ -2129,26 +3397,22 @@ if (wIndex == 1) { hc->rh.wPortChange_1 &= ~(1 << RH_PORT_CONNECTION); - } - else if (wIndex == 2) { + } else if (wIndex == 2) { hc->rh.wPortChange_2 &= ~(1 << RH_PORT_CONNECTION); - } - else { + } else { dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_CONNECTION " - "with invalid wIndex == %d!!", wIndex); + "with invalid wIndex == %d!", wIndex); } OK (0); case (RH_C_PORT_ENABLE): if (wIndex == 1) { hc->rh.wPortChange_1 &= ~(1 << RH_PORT_ENABLE); - } - else if (wIndex == 2) { + } else if (wIndex == 2) { hc->rh.wPortChange_2 &= ~(1 << RH_PORT_ENABLE); - } - else { + } else { dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_ENABLE " - "with invalid wIndex == %d!!", wIndex); + "with invalid wIndex == %d!", wIndex); } OK (0); case (RH_C_PORT_SUSPEND): @@ -2159,15 +3423,11 @@ case (RH_C_PORT_RESET): if (wIndex == 1) { hc->rh.wPortChange_1 &= ~(1 << RH_PORT_RESET); - } - else if (wIndex == 2) { - dbg_rh("This is wPortChange before clear: 0x%04X", hc->rh.wPortChange_2); - + } else if (wIndex == 2) { hc->rh.wPortChange_2 &= ~(1 << RH_PORT_RESET); - dbg_rh("This is wPortChange after clear: 0x%04X", hc->rh.wPortChange_2); } else { dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_RESET " - "with invalid index == %d!!", wIndex); + "with invalid index == %d!", wIndex); } OK (0); @@ -2178,6 +3438,10 @@ case RH_SET_FEATURE | RH_OTHER | RH_CLASS: switch (wValue) { case (RH_PORT_SUSPEND): + + /* Make sure the controller isn't busy. */ + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + if (wIndex == 1) { *R_USB_COMMAND = IO_STATE(R_USB_COMMAND, port_sel, port1) | @@ -2189,76 +3453,150 @@ IO_STATE(R_USB_COMMAND, port_cmd, suspend) | IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); } else { - dbg_rh("RH_SET_FEATURE->RH_C_PORT_SUSPEND " - "with invalid wIndex == %d!!", wIndex); + dbg_rh("RH_SET_FEATURE->RH_PORT_SUSPEND " + "with invalid wIndex == %d!", wIndex); } OK (0); case (RH_PORT_RESET): if (wIndex == 1) { - int port1_retry; - port1_redo: + port_1_reset: dbg_rh("Doing reset of port 1"); + + /* Make sure the controller isn't busy. */ + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); *R_USB_COMMAND = + IO_STATE(R_USB_COMMAND, port_sel, port1) | IO_STATE(R_USB_COMMAND, port_cmd, reset) | - IO_STATE(R_USB_COMMAND, port_sel, port1); - - /* We must once again wait at least 10ms for the device to recover */ + IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); - port1_retry = 0; - while (!((*((volatile __u16 *)&hc->rh.prev_wPortStatus_1)) & - IO_STATE(R_USB_RH_PORT_STATUS_1, - enabled, yes))) { - printk(""); if (port1_retry++ >= 10000) {goto port1_redo;} - } - - /* This only seems to work if we use printk, - not even schedule() works !!! WHY ?? */ + /* We must wait at least 10 ms for the device to recover. + 15 ms should be enough. */ + udelay(15000); + + /* Wait for reset bit to go low (should be done by now). */ + while (hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, reset, yes)); + + /* If the port status is + 1) connected and enabled then there is a device and everything is fine + 2) neither connected nor enabled then there is no device, also fine + 3) connected and not enabled then we try again + (Yes, there are other port status combinations besides these.) */ + + if ((hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) && + (hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) { + dbg_rh("Connected device on port 1, but port not enabled?" + " Trying reset again."); + goto port_2_reset; + } + + /* Diagnostic printouts. */ + if ((hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, connected, no)) && + (hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) { + dbg_rh("No connected device on port 1"); + } else if ((hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) && + (hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes))) { + dbg_rh("Connected device on port 1, port 1 enabled"); + } - udelay(15000); - } - else if (wIndex == 2) { - int port2_retry; - - port2_redo: + } else if (wIndex == 2) { + + port_2_reset: dbg_rh("Doing reset of port 2"); + /* Make sure the controller isn't busy. */ + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + + /* Issue the reset command. */ *R_USB_COMMAND = + IO_STATE(R_USB_COMMAND, port_sel, port2) | IO_STATE(R_USB_COMMAND, port_cmd, reset) | - IO_STATE(R_USB_COMMAND, port_sel, port2); - - /* We must once again wait at least 10ms for the device to recover */ + IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); - port2_retry = 0; - while (!((*((volatile __u16 *)&hc->rh.prev_wPortStatus_2)) & - IO_STATE(R_USB_RH_PORT_STATUS_2, - enabled, yes))) { - printk(""); if (port2_retry++ >= 10000) {goto port2_redo;} - } - - /* This only seems to work if we use printk, - not even schedule() works !!! WHY ?? */ + /* We must wait at least 10 ms for the device to recover. + 15 ms should be enough. */ + udelay(15000); + + /* Wait for reset bit to go low (should be done by now). */ + while (hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, reset, yes)); + + /* If the port status is + 1) connected and enabled then there is a device and everything is fine + 2) neither connected nor enabled then there is no device, also fine + 3) connected and not enabled then we try again + (Yes, there are other port status combinations besides these.) */ + + if ((hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) && + (hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) { + dbg_rh("Connected device on port 2, but port not enabled?" + " Trying reset again."); + goto port_2_reset; + } + + /* Diagnostic printouts. */ + if ((hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, connected, no)) && + (hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) { + dbg_rh("No connected device on port 2"); + } else if ((hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) && + (hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes))) { + dbg_rh("Connected device on port 2, port 2 enabled"); + } - udelay(15000); - } + } else { + dbg_rh("RH_SET_FEATURE->RH_PORT_RESET with invalid wIndex = %d", wIndex); + } + + /* Make sure the controller isn't busy. */ + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + + /* If all enabled ports were disabled the host controller goes down into + started mode, so we need to bring it back into the running state. + (This is safe even if it's already in the running state.) */ + *R_USB_COMMAND = + IO_STATE(R_USB_COMMAND, port_sel, nop) | + IO_STATE(R_USB_COMMAND, port_cmd, reset) | + IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run); - /* Try to bring the HC into running state */ - *R_USB_COMMAND = - IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run); - - nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); - dbg_rh("...Done"); OK(0); case (RH_PORT_POWER): OK (0); /* port power ** */ case (RH_PORT_ENABLE): - /* There is no rh port enable command in the Etrax USB interface!!!! */ + /* There is no port enable command in the host controller, so if the + port is already enabled, we do nothing. If not, we reset the port + (with an ugly goto). */ + + if (wIndex == 1) { + if (hc->rh.prev_wPortStatus_1 & + IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no)) { + goto port_1_reset; + } + } else if (wIndex == 2) { + if (hc->rh.prev_wPortStatus_2 & + IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no)) { + goto port_2_reset; + } + } else { + dbg_rh("RH_SET_FEATURE->RH_GET_STATUS with invalid wIndex = %d", wIndex); + } OK (0); - } break; @@ -2283,8 +3621,10 @@ data, wLength); if (len > 0) { OK(min(leni, len)); - } else + } else { stat = -EPIPE; + } + } break; @@ -2309,33 +3649,56 @@ urb->status = stat; urb->dev = NULL; if (urb->complete) { - urb->complete (urb); + urb->complete(urb); } DBFEXIT; return 0; } +static void +etrax_usb_bulk_eot_timer_func(unsigned long dummy) +{ + /* Because of a race condition in the top half, we might miss a bulk eot. + This timer "simulates" a bulk eot if we don't get one for a while, hopefully + correcting the situation. */ + dbg_bulk("bulk_eot_timer timed out."); + etrax_usb_hc_bulk_eot_interrupt(1); +} + static int __init etrax_usb_hc_init(void) { static etrax_hc_t *hc; struct usb_bus *bus; struct usb_device *usb_rh; - + int i; + DBFENTER; - info("ETRAX 100LX USB-HCD %s (c) 2001 Axis Communications AB\n", usb_hcd_version); - - hc = kmalloc(sizeof(etrax_hc_t), GFP_KERNEL); + info("ETRAX 100LX USB-HCD %s (c) 2001-2003 Axis Communications AB\n", usb_hcd_version); + + hc = kmalloc(sizeof(etrax_hc_t), GFP_KERNEL); + assert(hc != NULL); /* We use kmem_cache_* to make sure that all DMA desc. are dword aligned */ - usb_desc_cache = kmem_cache_create("usb_desc_cache", sizeof(USB_EP_Desc_t), 0, 0, 0, 0); - if (!usb_desc_cache) { - panic("USB Desc Cache allocation failed !!!\n"); - } - + /* Note that we specify sizeof(USB_EP_Desc_t) as the size, but also allocate + SB descriptors from this cache. This is ok since sizeof(USB_EP_Desc_t) == + sizeof(USB_SB_Desc_t). */ + + usb_desc_cache = kmem_cache_create("usb_desc_cache", sizeof(USB_EP_Desc_t), 0, + SLAB_HWCACHE_ALIGN, 0, 0); + assert(usb_desc_cache != NULL); + + top_half_reg_cache = kmem_cache_create("top_half_reg_cache", + sizeof(usb_interrupt_registers_t), + 0, SLAB_HWCACHE_ALIGN, 0, 0); + assert(top_half_reg_cache != NULL); + etrax_usb_bus = bus = usb_alloc_bus(&etrax_usb_device_operations); hc->bus = bus; +#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 4, 20) + bus->bus_name="ETRAX 100LX"; +#endif bus->hcpriv = hc; /* Initalize RH to the default address. @@ -2350,17 +3713,50 @@ hc->rh.prev_wPortStatus_2 = 0; /* Initialize the intr-traffic flags */ + /* FIXME: This isn't used. (Besides, the error field isn't initialized.) */ hc->intr.sleeping = 0; hc->intr.wq = NULL; - /* Initially all ep's are free except ep 0 */ - ep_usage_bitmask = 0; - set_bit(0, (void *)&ep_usage_bitmask); - ep_really_active = 0; - ep_out_traffic = 0; - - memset(URB_List, 0, sizeof(URB_List)); + epid_usage_bitmask = 0; + epid_out_traffic = 0; + /* Mark the invalid epid as being used. */ + set_bit(INVALID_EPID, (void *)&epid_usage_bitmask); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, INVALID_EPID); + nop(); + /* The valid bit should still be set ('invalid' is in our world; not the hardware's). */ + *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, yes) | + IO_FIELD(R_USB_EPT_DATA, max_len, 1)); + + /* Mark the dummy epid as being used. */ + set_bit(DUMMY_EPID, (void *)&epid_usage_bitmask); + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, DUMMY_EPID); + nop(); + *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, no) | + IO_FIELD(R_USB_EPT_DATA, max_len, 1)); + + /* Initialize the urb list by initiating a head for each list. */ + for (i = 0; i < NBR_OF_EPIDS; i++) { + INIT_LIST_HEAD(&urb_list[i]); + } + spin_lock_init(&urb_list_lock); + + INIT_LIST_HEAD(&urb_unlink_list); + + + /* Initiate the bulk start timer. */ + init_timer(&bulk_start_timer); + bulk_start_timer.expires = jiffies + BULK_START_TIMER_INTERVAL; + bulk_start_timer.function = etrax_usb_bulk_start_timer_func; + add_timer(&bulk_start_timer); + + + /* Initiate the bulk eot timer. */ + init_timer(&bulk_eot_timer); + bulk_eot_timer.expires = jiffies + BULK_EOT_TIMER_INTERVAL; + bulk_eot_timer.function = etrax_usb_bulk_eot_timer_func; + add_timer(&bulk_eot_timer); + /* This code should really be moved */ if (request_dma(USB_TX_DMA_NBR, "ETRAX 100LX built-in USB (Tx)")) { @@ -2375,48 +3771,41 @@ etrax_usb_hc_cleanup(); DBFEXIT; return -1; - } -#if 0 /* Moved to head.S */ - *R_GEN_CONFIG = genconfig_shadow = - (genconfig_shadow & ~(IO_MASK(R_GEN_CONFIG, usb1) | - IO_MASK(R_GEN_CONFIG, usb2) | - IO_MASK(R_GEN_CONFIG, dma8) | - IO_MASK(R_GEN_CONFIG, dma9))) | - IO_STATE(R_GEN_CONFIG, dma8, usb) | - IO_STATE(R_GEN_CONFIG, dma9, usb) -#ifdef CONFIG_ETRAX_USB_HOST_PORT1 - | IO_STATE(R_GEN_CONFIG, usb1, select) -#endif -#ifdef CONFIG_ETRAX_USB_HOST_PORT2 - | IO_STATE(R_GEN_CONFIG, usb2, select) -#endif - ; -#endif + } + + /* Set up the data structures for USB traffic. Note that this must be done before + any interrupt that relies on sane DMA list occurrs. */ + init_rx_buffers(); + init_tx_bulk_ep(); + init_tx_ctrl_ep(); + init_tx_intr_ep(); + init_tx_isoc_ep(); + usb_register_bus(hc->bus); - /* We may have to set more bits, but these are the obvious ones */ + /* Note that these interrupts are not used. */ *R_IRQ_MASK2_SET = IO_STATE(R_IRQ_MASK2_SET, dma8_sub0_descr, set) | IO_STATE(R_IRQ_MASK2_SET, dma8_sub1_descr, set) | IO_STATE(R_IRQ_MASK2_SET, dma8_sub2_descr, set) | IO_STATE(R_IRQ_MASK2_SET, dma8_sub3_descr, set); + /* Note that the dma9_descr interrupt is not used. */ *R_IRQ_MASK2_SET = IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) | IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set); + /* FIXME: Enable iso_eof only when isoc traffic is running. */ *R_USB_IRQ_MASK_SET = - IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set) | - IO_STATE(R_USB_IRQ_MASK_SET, ctl_eot, set) | + IO_STATE(R_USB_IRQ_MASK_SET, iso_eof, set) | IO_STATE(R_USB_IRQ_MASK_SET, bulk_eot, set) | -#ifdef ETRAX_USB_INTR_IRQ - IO_STATE(R_USB_IRQ_MASK_SET, intr_eot, set) | -#endif IO_STATE(R_USB_IRQ_MASK_SET, epid_attn, set) | - IO_STATE(R_USB_IRQ_MASK_SET, port_status, set); + IO_STATE(R_USB_IRQ_MASK_SET, port_status, set) | + IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set); + - if (request_irq(ETRAX_USB_HC_IRQ, etrax_usb_hc_intr_top_half, 0, + if (request_irq(ETRAX_USB_HC_IRQ, etrax_usb_hc_interrupt_top_half, 0, "ETRAX 100LX built-in USB (HC)", hc)) { err("Could not allocate IRQ %d for USB", ETRAX_USB_HC_IRQ); etrax_usb_hc_cleanup(); @@ -2440,16 +3829,50 @@ return -1; } - /* Reset the USB interface (configures as HC) */ + /* R_USB_COMMAND: + USB commands in host mode. The fields in this register should all be + written to in one write. Do not read-modify-write one field at a time. A + write to this register will trigger events in the USB controller and an + incomplete command may lead to unpredictable results, and in worst case + even to a deadlock in the controller. + (Note however that the busy field is read-only, so no need to write to it.) */ + + /* Check the busy bit before writing to R_USB_COMMAND. */ + + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + + /* Reset the USB interface. */ *R_USB_COMMAND = - IO_STATE(R_USB_COMMAND, ctrl_cmd, reset) | - IO_STATE(R_USB_COMMAND, port_cmd, reset); - - nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -#if 1 - /* Initate PSTART to all unallocatable bit times */ - *R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 10000); -#endif + IO_STATE(R_USB_COMMAND, port_sel, nop) | + IO_STATE(R_USB_COMMAND, port_cmd, reset) | + IO_STATE(R_USB_COMMAND, ctrl_cmd, reset); + + /* Designer's Reference, p. 8 - 10 says we should Initate R_USB_FM_PSTART to 0x2A30 (10800), + to guarantee that control traffic gets 10% of the bandwidth, and periodic transfer may + allocate the rest (90%). This doesn't work though. Read on for a lenghty explanation. + + While there is a difference between rev. 2 and rev. 3 of the ETRAX 100LX regarding the NAK + behaviour, it doesn't solve this problem. What happens is that a control transfer will not + be interrupted in its data stage when PSTART happens (the point at which periodic traffic + is started). Thus, if PSTART is set to 10800 and its IN or OUT token is NAKed until just before + PSTART happens, it will continue the IN/OUT transfer as long as it's ACKed. After it's done, + there may be too little time left for an isochronous transfer, causing an epid attention + interrupt due to perror. The work-around for this is to let the control transfers run at the + end of the frame instead of at the beginning, and will be interrupted just fine if it doesn't + fit into the frame. However, since there will *always* be a control transfer at the beginning + of the frame, regardless of what we set PSTART to, that transfer might be a 64-byte transfer + which consumes up to 15% of the frame, leaving only 85% for periodic traffic. The solution to + this would be to 'dummy allocate' 5% of the frame with the usb_claim_bandwidth function to make + sure that the periodic transfers that are inserted will always fit in the frame. + + The idea was suggested that a control transfer could be split up into several 8 byte transfers, + so that it would be interrupted by PSTART, but since this can't be done for an IN transfer this + hasn't been implemented. + + The value 11960 is chosen to be just after the SOF token, with a couple of bit times extra + for possible bit stuffing. */ + + *R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 11960); #ifdef CONFIG_ETRAX_USB_HOST_PORT1 *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no); @@ -2459,32 +3882,28 @@ *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no); #endif - *R_USB_COMMAND = - IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config) | - IO_STATE(R_USB_COMMAND, port_cmd, reset); - - nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + /* Configure the USB interface as a host controller. */ *R_USB_COMMAND = - IO_STATE(R_USB_COMMAND, port_sel, port1) | - IO_STATE(R_USB_COMMAND, port_cmd, reset); - - nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + IO_STATE(R_USB_COMMAND, port_sel, nop) | + IO_STATE(R_USB_COMMAND, port_cmd, reset) | + IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config); + + /* Note: Do not reset any ports here. Await the port status interrupts, to have a controlled + sequence of resetting the ports. If we reset both ports now, and there are devices + on both ports, we will get a bus error because both devices will answer the set address + request. */ - /* Here we must wait at least 10ms so the device has time to recover */ - udelay(15000); + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); - init_rx_buffers(); - init_tx_bulk_ep(); - init_tx_ctrl_ep(); - init_tx_intr_ep(); - - /* This works. It seems like the host_run command only has effect when a device is connected, - i.e. it has to be done when a interrup */ + /* Start processing of USB traffic. */ *R_USB_COMMAND = + IO_STATE(R_USB_COMMAND, port_sel, nop) | + IO_STATE(R_USB_COMMAND, port_cmd, reset) | IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run); - - nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); + + while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); usb_rh = usb_alloc_dev(NULL, hc->bus); hc->bus->root_hub = usb_rh; @@ -2508,6 +3927,8 @@ free_dma(USB_RX_DMA_NBR); usb_deregister_bus(etrax_usb_bus); + /* FIXME: call kmem_cache_destroy here? */ + DBFEXIT; } diff -urN linux-2.4.21/arch/cris/drivers/usb-host.h linux-2.4.22/arch/cris/drivers/usb-host.h --- linux-2.4.21/arch/cris/drivers/usb-host.h 2001-08-15 01:22:15.000000000 -0700 +++ linux-2.4.22/arch/cris/drivers/usb-host.h 2003-08-25 04:44:39.000000000 -0700 @@ -5,27 +5,27 @@ #include typedef struct USB_IN_Desc { - __u16 sw_len; - __u16 command; - unsigned long next; - unsigned long buf; - __u16 hw_len; - __u16 status; + volatile __u16 sw_len; + volatile __u16 command; + volatile unsigned long next; + volatile unsigned long buf; + volatile __u16 hw_len; + volatile __u16 status; } USB_IN_Desc_t; typedef struct USB_SB_Desc { - __u16 sw_len; - __u16 command; - unsigned long next; - unsigned long buf; + volatile __u16 sw_len; + volatile __u16 command; + volatile unsigned long next; + volatile unsigned long buf; __u32 dummy; } USB_SB_Desc_t; typedef struct USB_EP_Desc { - __u16 hw_len; - __u16 command; - unsigned long sub; - unsigned long nep; + volatile __u16 hw_len; + volatile __u16 command; + volatile unsigned long sub; + volatile unsigned long next; __u32 dummy; } USB_EP_Desc_t; @@ -37,10 +37,10 @@ int interval; int numports; struct timer_list rh_int_timer; - __u16 wPortChange_1; - __u16 wPortChange_2; - __u16 prev_wPortStatus_1; - __u16 prev_wPortStatus_2; + volatile __u16 wPortChange_1; + volatile __u16 wPortChange_2; + volatile __u16 prev_wPortStatus_1; + volatile __u16 prev_wPortStatus_2; }; struct etrax_usb_intr_traffic { @@ -55,40 +55,77 @@ struct etrax_usb_intr_traffic intr; } etrax_hc_t; -typedef enum {idle, eot, nodata} etrax_usb_rx_state_t; +typedef enum { + STARTED, + NOT_STARTED, + UNLINK +} etrax_usb_urb_state_t; + + typedef struct etrax_usb_urb_priv { + /* The first_sb field is used for freeing all SB descriptors belonging + to an urb. The corresponding ep descriptor's sub pointer cannot be + used for this since the DMA advances the sub pointer as it processes + the sb list. */ USB_SB_Desc_t *first_sb; + /* The last_sb field referes to the last SB descriptor that belongs to + this urb. This is important to know so we can free the SB descriptors + that ranges between first_sb and last_sb. */ + USB_SB_Desc_t *last_sb; + + /* The rx_offset field is used in ctrl and bulk traffic to keep track + of the offset in the urb's transfer_buffer where incoming data should be + copied to. */ __u32 rx_offset; - etrax_usb_rx_state_t rx_state; - __u8 eot; - struct list_head ep_in_list; -} etrax_urb_priv_t; + /* Counter used in isochronous transfers to keep track of the + number of packets received/transmitted. */ + __u32 isoc_packet_counter; + + /* This field is used to pass information about the urb's current state between + the various interrupt handlers (thus marked volatile). */ + volatile etrax_usb_urb_state_t urb_state; + + /* Connection between the submitted urb and ETRAX epid number */ + __u8 epid; + + /* The rx_data_list field is used for periodic traffic, to hold + received data for later processing in the the complete_urb functions, + where the data us copied to the urb's transfer_buffer. Basically, we + use this intermediate storage because we don't know when it's safe to + reuse the transfer_buffer (FIXME?). */ + struct list_head rx_data_list; +} etrax_urb_priv_t; -struct usb_reg_context +/* This struct is for passing data from the top half to the bottom half. */ +typedef struct usb_interrupt_registers { etrax_hc_t *hc; __u32 r_usb_epid_attn; __u8 r_usb_status; - __u32 r_usb_rh_port_status_1; - __u32 r_usb_rh_port_status_2; + __u16 r_usb_rh_port_status_1; + __u16 r_usb_rh_port_status_2; __u32 r_usb_irq_mask_read; + __u32 r_usb_fm_number; struct tq_struct usb_bh; -#if 0 - __u32 r_usb_ept_data[32]; -#endif -}; +} usb_interrupt_registers_t; -struct in_chunk +/* This struct holds data we get from the rx descriptors for DMA channel 9 + for periodic traffic (intr and isoc). */ +typedef struct rx_data { void *data; int length; - char epid; struct list_head list; -}; +} rx_data_t; + +typedef struct urb_entry +{ + urb_t *urb; + struct list_head list; +} urb_entry_t; - /* --------------------------------------------------------------------------- Virtual Root HUB ------------------------------------------------------------------------- */ diff -urN linux-2.4.21/arch/cris/drivers/virtex.c linux-2.4.22/arch/cris/drivers/virtex.c --- linux-2.4.21/arch/cris/drivers/virtex.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/cris/drivers/virtex.c 2003-08-25 04:44:39.000000000 -0700 @@ -7,7 +7,7 @@ *! *! The FPGA can be programmed by copying the bit-file to /dev/fpga. *! -*! cp fpga.bit > /dev/fpga +*! cat fpga.bit > /dev/fpga *! *! Kernel log should look like: *! 69900 bytes written @@ -31,6 +31,9 @@ *! *! Jul 19 2002 Stefan Lundberg Initial version. *! $Log: virtex.c,v $ +*! Revision 1.2 2003/02/24 07:50:30 fredriko +*! Bugfixes and cleanups. +*! *! Revision 1.1 2002/06/25 09:58:58 stefanl *! New FPGA driver for Platoon *! @@ -40,7 +43,7 @@ *! (C) Copyright 2002 Axis Communications AB, LUND, SWEDEN *! *!***************************************************************************/ -/* $Id: virtex.c,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */ +/* $Id: virtex.c,v 1.2 2003/02/24 07:50:30 fredriko Exp $ */ /****************** INCLUDE FILES SECTION ***********************************/ #include @@ -127,14 +130,20 @@ void start_virtex_program(void) { + volatile unsigned int i=0; unsigned short reg_data=0; printk("Start writing to FPGA\n"); - reg_data = SET_CS_BIT(reg_data); // FPGA unselected + reg_data = SET_CS_BIT(reg_data); // FPGA unselected, PROGRAM bit not set + WRITE_FPGA_PROG_REG(reg_data); + for(i=0;i<10;i++) { } // at least 300 ns loop + reg_data = SET_PROGRAM_BIT(reg_data); WRITE_FPGA_PROG_REG(reg_data); + for(i=0;i<10;i++) { } // at least 300 ns loop + while(!READ_INIT); // Wait for init reg_data = SET_WRITE_BIT(reg_data); @@ -304,6 +313,7 @@ } if(copy_from_user(ptr, buf, count)) { printk("copy_from_user failed\n"); + kfree(ptr); return -EFAULT; } @@ -339,7 +349,7 @@ switch (_IOC_NR(cmd)) { case VIRTEX_FPGA_WRITEREG: /* write to an FPGA register */ - VIRTEX_DEBUG(printk("virtex wr %d %d\n", + VIRTEX_DEBUG(printk("virtex wr 0x%x = 0x%x\n", VIRTEX_FPGA_ARGREG(arg), VIRTEX_FPGA_ARGVALUE(arg))); @@ -347,12 +357,12 @@ VIRTEX_FPGA_ARGVALUE(arg)); case VIRTEX_FPGA_READREG: { - unsigned char val; + unsigned short val; /* read from an FPGA register */ - VIRTEX_DEBUG(printk("virtex rd %d ", + VIRTEX_DEBUG(printk("virtex rd 0x%x ", VIRTEX_FPGA_ARGREG(arg))); val = virtex_readreg(VIRTEX_FPGA_ARGREG(arg)); - VIRTEX_DEBUG(printk("= %d\n", val)); + VIRTEX_DEBUG(printk("= 0x%x\n", val)); return val; } default: diff -urN linux-2.4.21/arch/cris/drivers/virtex.h linux-2.4.22/arch/cris/drivers/virtex.h --- linux-2.4.21/arch/cris/drivers/virtex.h 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/cris/drivers/virtex.h 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,2 @@ -/* $Id: virtex.h,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */ - int virtex_writereg(unsigned short theReg, unsigned short theValue); unsigned short virtex_readreg(unsigned short theReg); - - - diff -urN linux-2.4.21/arch/cris/kernel/Makefile linux-2.4.22/arch/cris/kernel/Makefile --- linux-2.4.21/arch/cris/kernel/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/cris/kernel/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.10 2002/05/27 15:41:40 johana Exp $ # # Makefile for the linux kernel. # @@ -17,21 +16,24 @@ O_TARGET := kernel.o -export-objs := ksyms.o +export-objs := crisksyms.o obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o setup.o time.o sys_cris.o shadows.o \ debugport.o semaphore.o -obj-$(CONFIG_MODULES) += ksyms.o +obj-$(CONFIG_MODULES) += crisksyms.o obj-$(CONFIG_ETRAX_KGDB) += kgdb.o obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o +obj-$(CONFIG_ETRAX_DEBUG_INTERRUPT) += debug.o # This dependency isn't caught by mkdep. See entry.S. entry.o: entryoffsets.s +# We don't want debug info for the dummy entryoffsets functions, and the +# assembler gets confused when file directives are .if 0:d out. entryoffsets.s: entryoffsets.c - $(CC) $(CFLAGS) -S -c $< + $(CC) $(subst -g,,$(CFLAGS)) -S -c $< clean: diff -urN linux-2.4.21/arch/cris/kernel/crisksyms.c linux-2.4.22/arch/cris/kernel/crisksyms.c --- linux-2.4.21/arch/cris/kernel/crisksyms.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/cris/kernel/crisksyms.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void dump_thread(struct pt_regs *, struct user *); +extern unsigned long get_cmos_time(void); +extern void __Div(void); +extern void __Mod(void); +extern void __Udiv(void); +extern void __Umod(void); +extern void __ashrdi3(void); +extern void iounmap(void *addr); + +/* Platform dependent support */ +EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(kernel_thread); +EXPORT_SYMBOL(get_cmos_time); +EXPORT_SYMBOL(loops_per_usec); + +/* String functions */ +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(strtok); +EXPORT_SYMBOL(strpbrk); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strncpy); + +/* Math functions */ +EXPORT_SYMBOL_NOVERS(__Div); +EXPORT_SYMBOL_NOVERS(__Mod); +EXPORT_SYMBOL_NOVERS(__Udiv); +EXPORT_SYMBOL_NOVERS(__Umod); +EXPORT_SYMBOL_NOVERS(__ashrdi3); + +/* Memory functions */ +EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(iounmap); + +/* Semaphore functions */ +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_interruptible); +EXPORT_SYMBOL(__down_trylock); + +/* Export shadow registers for the CPU I/O pins */ +EXPORT_SYMBOL(genconfig_shadow); +EXPORT_SYMBOL(port_pa_data_shadow); +EXPORT_SYMBOL(port_pa_dir_shadow); +EXPORT_SYMBOL(port_pb_data_shadow); +EXPORT_SYMBOL(port_pb_dir_shadow); +EXPORT_SYMBOL(port_pb_config_shadow); +EXPORT_SYMBOL(port_g_data_shadow); + +/* Userspace access functions */ +EXPORT_SYMBOL(__copy_user_zeroing); +EXPORT_SYMBOL(__copy_user); + +/* Cache flush functions */ +EXPORT_SYMBOL(flush_etrax_cache); +EXPORT_SYMBOL(prepare_rx_descriptor); + +#undef memcpy +#undef memset +extern void * memset(void *, int, __kernel_size_t); +extern void * memcpy(void *, const void *, __kernel_size_t); +EXPORT_SYMBOL_NOVERS(memcpy); +EXPORT_SYMBOL_NOVERS(memset); + +#ifdef CONFIG_ETRAX_FAST_TIMER +/* Fast timer functions */ +EXPORT_SYMBOL(fast_timer_list); +EXPORT_SYMBOL(start_one_shot_timer); +EXPORT_SYMBOL(del_fast_timer); +EXPORT_SYMBOL(schedule_usleep); +#endif diff -urN linux-2.4.21/arch/cris/kernel/debug.c linux-2.4.22/arch/cris/kernel/debug.c --- linux-2.4.21/arch/cris/kernel/debug.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/cris/kernel/debug.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,213 @@ +/* + * arch/cris/kernel/debug.c + * Various debug routines: + * o Logging of interrupt enabling/disabling. /proc/debug_interrupt + * gives result and toggles if it is enabled or not. + * + * Copyright (C) 2003 Axis Communications AB + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT +#define LOG_INT_SIZE 8192 +#define DEBUG_INT_PROC_FILE "debug_interrupt" +#define LOG_INT_SHOW_MIN_USEC 45000 + +/* These are global and can be used to trig certain events. */ +int log_int_pos = 0; +int log_int_size = LOG_INT_SIZE; +int log_int_trig0_pos = 0; +int log_int_trig1_pos = 0; + +int log_int_enable = 0; /* toggled every read of /proc/debug_interrupt */ + +struct log_int_struct +{ + unsigned long pc; + unsigned long ev_timer_data; +}; + +static struct log_int_struct log_ints[LOG_INT_SIZE]; + +//static unsigned long prev_log_int_t = 0; +static unsigned long prev_logged_ccr = 0; +static unsigned long prev_ei_timer_data = 0; +static unsigned long prev_di_timer_data = 0; + +#define CCR_EI_BIT 5 +enum { + INT_OLD_MASK = 0x01, INT_OLD_BIT = 0, + INT_NEW_MASK = 0x02, INT_NEW_BIT = 1, + INT_EI_CHANGE_MASK = 0x04, INT_EI_CHANGE_BIT = 2, + INT_ACTION_RESTORE = 0x08, INT_ACTION_RESTORE_BIT = 3, + INT_ACTION_MISSED = 0x10, INT_ACTION_MISSED_BIT = 4, + INT_ACTION_LONG = 0x20, INT_ACTION_LONG_BIT = 5, + + INT_OLD_EI = INT_OLD_MASK, INT_OLD_EI_BIT = INT_OLD_BIT, + INT_NEW_EI = INT_NEW_MASK, INT_NEW_EI_BIT = INT_NEW_BIT, + INT_EV_DI = INT_OLD_EI | INT_EI_CHANGE_MASK, + INT_EV_NOP_DI = 0, + INT_EV_EI = INT_NEW_EI | INT_EI_CHANGE_MASK, + INT_EV_NOP_EI = INT_OLD_EI | INT_NEW_EI, + INT_EV_RESTORE_DI= INT_EV_DI | INT_EI_CHANGE_MASK | INT_ACTION_RESTORE, + INT_EV_RESTORE_EI= INT_EV_EI | INT_EI_CHANGE_MASK | INT_ACTION_RESTORE, + INT_EV_RESTORE_NOP_DI = INT_EV_NOP_DI | INT_ACTION_RESTORE, + INT_EV_RESTORE_NOP_EI = INT_EV_NOP_EI | INT_ACTION_RESTORE, +}; + +void log_int(unsigned long pc, unsigned long curr_ccr, unsigned long next_ccr) +{ + unsigned long t; + int ev; + static int no_change_cnt = 0; + + /* Just disable interrupts without logging here, + * the caller will either do ei, di or restore + */ + __asm__ __volatile__ ("di" : : :"memory"); + t = *R_TIMER_DATA; + + if (curr_ccr & CCR_EI_MASK) { + prev_ei_timer_data = t; + ev = INT_OLD_EI; + } else { + prev_di_timer_data = t; + if ( (((prev_ei_timer_data >> 8) & 0x000000FF) - + ((prev_di_timer_data >> 8) & 0x000000FF)) & ~0x03) + ev = INT_ACTION_LONG; + else + ev = 0; + } + if ((curr_ccr ^ prev_logged_ccr) & CCR_EI_MASK) + ev |= INT_ACTION_MISSED; + if (next_ccr & CCR_EI_MASK) + ev |= INT_NEW_EI; + if ((curr_ccr ^ next_ccr) & CCR_EI_MASK) { + ev |= INT_EI_CHANGE_MASK; + no_change_cnt = 0; + } else + no_change_cnt++; + + prev_logged_ccr = next_ccr; + + if (log_int_enable && + ((ev & (INT_EI_CHANGE_MASK | INT_ACTION_MISSED | INT_ACTION_LONG)) + || (no_change_cnt < 40)) && + log_int_pos < LOG_INT_SIZE) { + int i; + i = log_int_pos; + log_int_pos++; + log_ints[i].pc = pc; + log_ints[i].ev_timer_data = (t & 0x00FFFFFF) | + ((ev & 0xFF) << 24); + + } +// __asm__ __volatile__ ("move %0,$ccr" : : "rm" (curr_ccr) : "memory"); +} +void log_int_di(void) +{ + unsigned long pc; + unsigned long flags; + __asm__ __volatile__ ("move $srp,%0" : "=rm" (pc) : : "memory"); + __asm__ __volatile__ ("move $ccr,%0" : "=rm" (flags) : : "memory"); + log_int(pc, flags, 0); +} + +void log_int_ei(void) +{ + unsigned long pc; + unsigned long flags; + __asm__ __volatile__ ("move $srp,%0" : "=rm" (pc) : : "memory"); + __asm__ __volatile__ ("move $ccr,%0" : "=rm" (flags) : : "memory"); + log_int(pc, flags, CCR_EI_MASK); +} + + +static int log_int_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0; + off_t begin = 0; + int j, t0, t1, t, thigh, tlow, tdi0; + int di0, ei1; + len += sprintf(page + len, "trig0: %i trig1: %i\n", log_int_trig0_pos, log_int_trig1_pos); + for (i = 0; i < log_int_pos-1; i++) { + + if (((log_ints[i].ev_timer_data >> 24) & INT_NEW_EI)) { + di0 = i; + while (di0 < log_int_pos-1 && (((log_ints[di0].ev_timer_data >> 24) & INT_NEW_EI))) + di0++; + ei1 = di0+1; + while (ei1 < log_int_pos-1 && (((log_ints[ei1].ev_timer_data >> 24) & INT_NEW_EI) == 0)) + ei1++; + thigh = timer_data_to_ns(log_ints[ei1].ev_timer_data); + tlow = timer_data_to_ns(log_ints[di0].ev_timer_data); + tdi0 = timer_data_to_ns(log_ints[di0].ev_timer_data); + + t = thigh-tlow; + j = di0-1; + if ((t > LOG_INT_SHOW_MIN_USEC) || (log_int_trig0_pos-30 < j && j < log_int_trig1_pos+30)) { + + for (; j <= ei1; j++) { + t0 = ((log_ints[j+1].ev_timer_data & 0xFF) - + (log_ints[j].ev_timer_data & 0xFF)); + t1 = (((log_ints[j+1].ev_timer_data >> 8) & 0xFF) - + ((log_ints[j].ev_timer_data >> 8) & 0xFF)); + if (t1 == 0 || t1 == 1) { + if (t0 < 0) + t0 += 256; + } else { + if (t1 < 0) + t1 += 256; + } + thigh = timer_data_to_ns(log_ints[j+1].ev_timer_data); + tlow = timer_data_to_ns(log_ints[j].ev_timer_data); + t = thigh-tlow; + len += sprintf(page + len, "%4i PC %08lX-%08lX %08lX-%08lX %s high %i in %-6i ns %-7i to %-7i = %-5i ns, from first di %i ns %s\n", + j, log_ints[j].pc, log_ints[j+1].pc, + log_ints[j].ev_timer_data, log_ints[j+1].ev_timer_data, + ((log_ints[j].ev_timer_data >> 24) & INT_NEW_EI)!= 0?"ei":"di", t1, t, + tlow, thigh, thigh-tlow, thigh-tdi0, + j==log_int_trig0_pos?"TRIG0":(j==log_int_trig1_pos?"TRIG1":"")); + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + + len += sprintf(page + len,"\n"); + i = ei1-2; + } + + } + + } + log_int_enable = 1; + log_int_pos = 0; + log_int_trig0_pos = 0; + log_int_trig1_pos = 0; + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); +} + +static int __init +log_int_init(void) +{ + create_proc_read_entry (DEBUG_INT_PROC_FILE, 0, 0, log_int_read_proc, NULL); + printk(KERN_INFO "/proc/" DEBUG_INT_PROC_FILE " size %i.\r\n", + LOG_INT_SIZE); + return 0; +} +module_init(log_int_init); +#endif /* CONFIG_ETRAX_DEBUG_INTERRUPT */ diff -urN linux-2.4.21/arch/cris/kernel/debugport.c linux-2.4.22/arch/cris/kernel/debugport.c --- linux-2.4.21/arch/cris/kernel/debugport.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/debugport.c 2003-08-25 04:44:39.000000000 -0700 @@ -12,6 +12,17 @@ * init_etrax_debug() * * $Log: debugport.c,v $ + * Revision 1.9 2003/02/17 07:10:34 starvik + * Last merge was incomplete + * + * Revision 1.8 2003/02/17 06:59:00 starvik + * Merged printk corruption fix + * + * Revision 1.7.4.1 2003/01/27 10:21:57 starvik + * Solved the problem with corrupted debug output + * * Wait until DMA, FIFO and pipe is empty before and after transmissions + * * Buffer data until a FIFO flush can be triggered. + * * Revision 1.7 2002/04/23 15:35:50 bjornw * Cleaned up sercons struct and removed the waitkey ptr (2.4.19-pre) * @@ -31,6 +42,7 @@ #include #include #include +#include #include #include @@ -94,6 +106,8 @@ #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma4_descr, clr) #endif +#define MIN_SIZE 32 /* Size that triggers the FIFO to flush characters to interface */ + /* Write a string of count length to the console (debug port) using DMA, polled * for completion. Interrupts are disabled during the whole process. Some * caution needs to be taken to not interfere with ttyS business on this port. @@ -103,8 +117,11 @@ console_write(struct console *co, const char *buf, unsigned int len) { static struct etrax_dma_descr descr; + static struct etrax_dma_descr descr2; + static char tmp_buf[MIN_SIZE]; + static int tmp_size = 0; + unsigned long flags; - int in_progress; #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL /* no debug printout at all */ @@ -126,6 +143,37 @@ restore_flags(flags); return; #endif + /* To make this work together with the real serial port driver + * we have to make sure that everything is flushed when we leave + * here. The following steps are made to assure this: + * 1. Wait until DMA stops, FIFO is empty and serial port pipeline empty. + * 2. Write at least half the FIFO to trigger flush to serial port. + * 3. Wait until DMA stops, FIFO is empty and serial port pipeline empty. + */ + + /* Do we have enough characters to make the DMA/FIFO happy? */ + if (tmp_size + len < MIN_SIZE) + { + int size = min((int)(MIN_SIZE - tmp_size),(int)len); + memcpy(&tmp_buf[tmp_size], buf, size); + tmp_size += size; + len -= size; + + /* Pad with space if complete line */ + if (tmp_buf[tmp_size-1] == '\n') + { + memset(&tmp_buf[tmp_size-1], ' ', MIN_SIZE - tmp_size); + tmp_buf[MIN_SIZE - 1] = '\n'; + tmp_size = MIN_SIZE; + len = 0; + } + else + { + /* Wait for more characters */ + restore_flags(flags); + return; + } + } /* make sure the transmitter is enabled. * NOTE: this overrides any setting done in ttySx, to 8N1, no auto-CTS. @@ -134,37 +182,36 @@ */ *DEBUG_TR_CTRL = 0x40; + while(*DEBUG_OCMD & 7); /* Until DMA is not running */ + while(*DEBUG_STATUS & 0x7f); /* wait until output FIFO is empty as well */ + udelay(200); /* Wait for last two characters to leave the serial transmitter */ - /* if the tty has some ongoing business, remember it */ - - in_progress = *DEBUG_OCMD & 7; - - if(in_progress) { - /* wait until the output dma channel is ready */ - - while(*DEBUG_OCMD & 7) /* nothing */ ; + if (tmp_size) + { + descr.ctrl = len ? 0 : d_eop | d_wait | d_eol; + descr.sw_len = tmp_size; + descr.buf = virt_to_phys(tmp_buf); + descr.next = virt_to_phys(&descr2); + descr2.ctrl = d_eop | d_wait | d_eol; + descr2.sw_len = len; + descr2.buf = virt_to_phys((char*)buf); + } + else + { + descr.ctrl = d_eop | d_wait | d_eol; + descr.sw_len = len; + descr.buf = virt_to_phys((char*)buf); } - descr.ctrl = d_eol; - descr.sw_len = len; - descr.buf = __pa(buf); - - *DEBUG_FIRST = __pa(&descr); /* write to R_DMAx_FIRST */ + *DEBUG_FIRST = virt_to_phys(&descr); /* write to R_DMAx_FIRST */ *DEBUG_OCMD = 1; /* dma command start -> R_DMAx_CMD */ /* wait until the output dma channel is ready again */ + while(*DEBUG_OCMD & 7); + while(*DEBUG_STATUS & 0x7f); + udelay(200); - while(*DEBUG_OCMD & 7) /* nothing */; - - /* clear pending interrupts so we don't get a surprise below */ - - if(in_progress) - *DEBUG_OCLRINT = 2; /* only clear EOP, leave DESCR for the tty */ - else - *DEBUG_OCLRINT = 3; /* clear both EOP and DESCR */ - - while(*DEBUG_STATUS & 0x7f); /* wait until output FIFO is empty as well */ - + tmp_size = 0; restore_flags(flags); } diff -urN linux-2.4.21/arch/cris/kernel/entry.S linux-2.4.22/arch/cris/kernel/entry.S --- linux-2.4.21/arch/cris/kernel/entry.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/entry.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.40 2002/12/02 08:11:41 starvik Exp $ +/* $Id: entry.S,v 1.42 2003/07/07 09:00:50 johana Exp $ * * linux/arch/cris/entry.S * @@ -7,6 +7,12 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: entry.S,v $ + * Revision 1.42 2003/07/07 09:00:50 johana + * Added CONFIG_ETRAX_DEBUG_INTERRUPT support. + * + * Revision 1.41 2003/06/17 13:57:50 starvik + * Merge of Linux 2.4.21 + * * Revision 1.40 2002/12/02 08:11:41 starvik * Merge of Linux 2.4.20 * @@ -358,6 +364,12 @@ _Rexit: ;; this epilogue MUST match the prologues in multiple_interrupt, irq.h and ptregs.h +#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT + move.d $pc,$r10 + move $ccr,$r11 + move.d [$sp + LDCCR], $r12; regs->dccr + jsr log_int +#endif pop $r10 ; frametype bne _RBFexit ; was not CRIS_FRAME_NORMAL, handle otherwise addq 4, $sp ; skip orig_r10, in delayslot @@ -449,6 +461,22 @@ push $srp ; we keep the old/new PC on the stack add.d $r12, $r10 ; r10 = current tasks tss move $dccr, [$r10+LTHREAD_DCCR] ; save irq enable state +#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT + push $r9 + push $r10 + push $r11 + push $r12 + push $r13 + move.d $pc,$r10 + move $ccr,$r11 + clear.d $r12 + jsr log_int + pop $r13 + pop $r12 + pop $r11 + pop $r10 + pop $r9 +#endif di move $usp, [$r10+LTHREAD_USP] ; save user-mode stackpointer diff -urN linux-2.4.21/arch/cris/kernel/fasttimer.c linux-2.4.22/arch/cris/kernel/fasttimer.c --- linux-2.4.21/arch/cris/kernel/fasttimer.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/fasttimer.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,10 +1,16 @@ -/* $Id: fasttimer.c,v 1.5 2002/10/15 06:21:39 starvik Exp $ +/* $Id: fasttimer.c,v 1.7 2003/04/01 14:12:07 starvik Exp $ * linux/arch/cris/kernel/fasttimer.c * * Fast timers for ETRAX100/ETRAX100LX * This may be useful in other OS than Linux so use 2 space indentation... * * $Log: fasttimer.c,v $ + * Revision 1.7 2003/04/01 14:12:07 starvik + * Added loglevel for lots of printks + * + * Revision 1.6 2003/02/10 17:05:44 pkj + * Made fast_timer_pending() public. + * * Revision 1.5 2002/10/15 06:21:39 starvik * Added call to init_waitqueue_head * @@ -63,7 +69,7 @@ * Revision 1.1 2000/10/26 15:49:16 johana * Added fasttimer, highresolution timers. * - * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden + * Copyright (C) 2000,2001,2002,2003 Axis Communications AB, Lund, Sweden */ #include @@ -118,7 +124,7 @@ static int fast_timer_is_init = 0; static int fast_timer_ints = 0; -static struct fast_timer *fast_timer_list = NULL; +struct fast_timer *fast_timer_list = NULL; #ifdef DEBUG_LOG_INCLUDED #define DEBUG_LOG_MAX 128 @@ -313,7 +319,8 @@ { if (tmp == t) { - printk("timer name: %s data: 0x%08lX already in list!\n", name, data); + printk(KERN_WARNING + "timer name: %s data: 0x%08lX already in list!\n", name, data); sanity_failed++; return; } @@ -379,11 +386,6 @@ restore_flags(flags); } /* start_one_shot_timer */ -static inline int fast_timer_pending (const struct fast_timer * t) -{ - return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list); -} - static inline int detach_fast_timer (struct fast_timer *t) { struct fast_timer *next, *prev; @@ -770,7 +772,7 @@ cli(); if (t->next != nextt) { - printk("timer removed!\n"); + printk(KERN_WARNING "timer removed!\n"); } t = nextt; } @@ -951,7 +953,7 @@ int i; #endif - printk("fast_timer_init()\n"); + printk(KERN_INFO "fast_timer_init()\n"); #if 0 && defined(FAST_TIMER_TEST) for (i = 0; i <= TIMER0_DIV; i++) @@ -971,7 +973,7 @@ if(request_irq(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ, "fast timer int", NULL)) { - printk("err: timer1 irq\n"); + printk(KERN_CRIT "err: timer1 irq\n"); } fast_timer_is_init = 1; #ifdef FAST_TIMER_TEST diff -urN linux-2.4.21/arch/cris/kernel/head.S linux-2.4.22/arch/cris/kernel/head.S --- linux-2.4.21/arch/cris/kernel/head.S 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/head.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.44 2002/02/05 15:39:57 bjornw Exp $ +/* $Id: head.S,v 1.47 2003/07/08 09:53:35 starvik Exp $ * * Head of the kernel - alter with care * @@ -7,6 +7,15 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: head.S,v $ + * Revision 1.47 2003/07/08 09:53:35 starvik + * Corrected last CVS log entry + * + * Revision 1.46 2003/05/15 08:07:51 gunnard + * Removed serial port DMA when using AGDB. + * + * Revision 1.45 2003/04/28 05:31:05 starvik + * Added section attributes + * * Revision 1.44 2002/02/05 15:39:57 bjornw * Oops.. non-CRAMFS_MAGIC should jump over the copying, not into it... * @@ -311,7 +320,7 @@ ;; Put this in a suitable section where we can reclaim storage ;; after init. - .section ".text.init" + .section ".text.init", "ax" _inflash: #ifdef CONFIG_ETRAX_ETHERNET ;; Start MII clock to make sure it is running when tranceiver is reset @@ -543,14 +552,24 @@ #if (!defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT0)) \ && !defined(CONFIG_DMA_MEMCPY) ; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA +#if (defined(CONFIG_ETRAX_AGDB)) + ; agdb only wants DMA out, no dma in + or.d IO_STATE (R_GEN_CONFIG, dma6, serial0),$r0 +#else or.d IO_STATE (R_GEN_CONFIG, dma7, serial0) \ | IO_STATE (R_GEN_CONFIG, dma6, serial0),$r0 #endif +#endif #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1) ; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA +#if (defined(CONFIG_ETRAX_AGDB)) + ; agdb only wants DMA out, no dma in + or.d IO_STATE (R_GEN_CONFIG, dma8, serial1),$r0 +#else or.d IO_STATE (R_GEN_CONFIG, dma9, serial1) \ | IO_STATE (R_GEN_CONFIG, dma8, serial1),$r0 #endif +#endif #ifdef CONFIG_DMA_MEMCPY ; 6/7 memory-memory DMA or.d IO_STATE (R_GEN_CONFIG, dma7, intdma6) \ @@ -561,19 +580,29 @@ or.w IO_STATE (R_GEN_CONFIG, ser2, select),$r0 #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT2) ; DMA channels 2 and 3 to ser2, kgdb doesnt want DMA +#if (defined(CONFIG_ETRAX_AGDB)) + ; agdb only wants DMA out, no dma in + or.d IO_STATE (R_GEN_CONFIG, dma2, serial2),$r0 +#else or.d IO_STATE (R_GEN_CONFIG, dma3, serial2) \ | IO_STATE (R_GEN_CONFIG, dma2, serial2),$r0 #endif #endif +#endif #if defined(CONFIG_ETRAX_SERIAL_PORT3) || defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) ; Enable serial port 3 or.w IO_STATE (R_GEN_CONFIG, ser3, select),$r0 #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT3) ; DMA channels 4 and 5 to ser3, kgdb doesnt want DMA +#if (defined(CONFIG_ETRAX_AGDB)) + ; agdb only wants DMA out, no dma in + or.d IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0 +#else or.d IO_STATE (R_GEN_CONFIG, dma5, serial3) \ | IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0 #endif #endif +#endif #if defined(CONFIG_ETRAX_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE) ; parport 0 enabled using DMA 2/3 or.w IO_STATE (R_GEN_CONFIG, par0, select),$r0 @@ -840,5 +869,5 @@ swapper_pg_dir = 0xc0002000 #endif - .section ".data.init" + .section ".data.init", "aw" #include "../lib/hw_settings.S" diff -urN linux-2.4.21/arch/cris/kernel/irq.c linux-2.4.22/arch/cris/kernel/irq.c --- linux-2.4.21/arch/cris/kernel/irq.c 2002-02-25 11:37:52.000000000 -0800 +++ linux-2.4.22/arch/cris/kernel/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,8 +1,7 @@ -/* $Id: irq.c,v 1.18 2001/11/21 13:40:18 bjornw Exp $ - * +/* * linux/arch/cris/kernel/irq.c * - * Copyright (c) 2000,2001 Axis Communications AB + * Copyright (c) 2000, 2001, 2002, 2003 Axis Communications AB * * Authors: Bjorn Wesen (bjornw@axis.com) * @@ -59,7 +58,7 @@ disable_irq(unsigned int irq_nr) { unsigned long flags; - + save_flags(flags); cli(); mask_irq(irq_nr); @@ -70,6 +69,7 @@ enable_irq(unsigned int irq_nr) { unsigned long flags; + save_flags(flags); cli(); unmask_irq(irq_nr); @@ -88,7 +88,8 @@ return 0; } -irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */ +/* vector of shortcut jumps after the irq prologue */ +irqvectptr irq_shortcuts[NR_IRQS]; /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is * global just so that the kernel gdb can use it. @@ -104,8 +105,8 @@ etrax_irv->v[n + 0x20] = (irqvectptr)addr; } -/* the breakpoint vector is obviously not made just like the normal irq handlers - * but needs to contain _code_ to jump to addr. +/* the breakpoint vector is obviously not made just like the normal irq + * handlers but needs to contain _code_ to jump to addr. * * the BREAK n instruction jumps to IBR + n * 8 */ @@ -117,7 +118,7 @@ unsigned long *jaddr = (unsigned long *)(jinstr + 1); /* if you don't know what this does, do not touch it! */ - + *jinstr = 0x0d3f; *jaddr = (unsigned long)addr; @@ -163,18 +164,18 @@ BUILD_IRQ(25, 0x2000000) /* IRQ 26-30 are reserved */ BUILD_IRQ(31, 0x80000000) - + /* - * Pointers to the low-level handlers + * Pointers to the low-level handlers */ static void (*interrupt[NR_IRQS])(void) = { NULL, NULL, IRQ2_interrupt, IRQ3_interrupt, IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt, IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt, - IRQ12_interrupt, IRQ13_interrupt, NULL, NULL, - IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt, - IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt, + IRQ12_interrupt, IRQ13_interrupt, NULL, NULL, + IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt, + IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt, IRQ24_interrupt, IRQ25_interrupt, NULL, NULL, NULL, NULL, NULL, IRQ31_interrupt }; @@ -183,9 +184,9 @@ NULL, NULL, sIRQ2_interrupt, sIRQ3_interrupt, sIRQ4_interrupt, sIRQ5_interrupt, sIRQ6_interrupt, sIRQ7_interrupt, sIRQ8_interrupt, sIRQ9_interrupt, sIRQ10_interrupt, sIRQ11_interrupt, - sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL, - sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt, - sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt, + sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL, + sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt, + sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt, sIRQ24_interrupt, sIRQ25_interrupt, NULL, NULL, NULL, NULL, NULL, sIRQ31_interrupt }; @@ -230,7 +231,7 @@ for (i = 0; i < NR_IRQS; i++) { action = irq_action[i]; - if (!action) + if (!action) continue; len += sprintf(buf+len, "%2d: %10u %c %s", i, kstat.irqs[0][i], @@ -286,9 +287,9 @@ } /* this function links in a handler into the chain of handlers for the - given irq, and if the irq has never been registred, the appropriate - handler is entered into the interrupt vector -*/ + * given irq, and if the irq has never been registred, the appropriate + * handler is entered into the interrupt vector + */ int setup_etrax_irq(int irq, struct irqaction * new) { @@ -322,37 +323,39 @@ *p = new; if (!shared) { - /* if the irq wasn't registred before, enter it into the vector table - and unmask it physically - */ + /* if the irq wasn't registred before, enter it into the vector + * table and unmask it physically + */ set_int_vector(irq, interrupt[irq], sinterrupt[irq]); unmask_irq(irq); } - + restore_flags(flags); return 0; } /* this function is called by a driver to register an irq handler - Valid flags: - SA_INTERRUPT -> it's a fast interrupt, handler called with irq disabled and - no signal checking etc is performed upon exit - SA_SHIRQ -> the interrupt can be shared between different handlers, the handler - is required to check if the irq was "aimed" at it explicitely - SA_RANDOM -> the interrupt will add to the random generators entropy -*/ + * Valid flags: + * SA_INTERRUPT: it's a fast interrupt, handler called with irq disabled and + * no signal checking etc is performed upon exit + * SA_SHIRQ: the interrupt can be shared between different handlers, the + * handler is required to check if the irq was "aimed" at it + * explicitely + * SA_RANDOM: the interrupt will add to the random generators entropy + */ -int request_irq(unsigned int irq, +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, + unsigned long irqflags, const char * devname, void *dev_id) { int retval; struct irqaction * action; - /* interrupts 0 and 1 are hardware breakpoint and NMI and we can't support - these yet. interrupt 15 is the multiple irq, it's special. */ + /* interrupts 0 and 1 are hardware breakpoint and NMI and we can't + * support these yet. interrupt 15 is the multiple irq, it's special. + */ if(irq < 2 || irq == 15 || irq >= NR_IRQS) return -EINVAL; @@ -362,7 +365,7 @@ /* allocate and fill in a handler structure and setup the irq */ - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + action = kmalloc(sizeof *action, GFP_KERNEL); if (!action) return -ENOMEM; @@ -379,7 +382,7 @@ kfree(action); return retval; } - + void free_irq(unsigned int irq, void *dev_id) { struct irqaction * action, **p; @@ -415,9 +418,9 @@ while(1); } -/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and - setting the irq vector table to point to bad_interrupt ptrs. -*/ +/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks + * and setting the irq vector table to point to bad_interrupt ptrs. + */ void system_call(void); /* from entry.S */ void do_sigtrap(void); /* from entry.S */ @@ -442,26 +445,27 @@ for(i = 0; i < NR_IRQS; i++) irq_shortcuts[i] = NULL; - - for (i = 0; i < 256; i++) - etrax_irv->v[i] = weird_irq; - - /* the entries in the break vector contain actual code to be - executed by the associated break handler, rather than just a jump - address. therefore we need to setup a default breakpoint handler - for all breakpoints */ + + for (i = 0; i < 256; i++) + etrax_irv->v[i] = weird_irq; + + /* the entries in the break vector contain actual code to be + * executed by the associated break handler, rather than just a jump + * address. therefore we need to setup a default breakpoint handler + * for all breakpoints + */ for (i = 0; i < 16; i++) - set_break_vector(i, do_sigtrap); - + set_break_vector(i, do_sigtrap); + /* set all etrax irq's to the bad handlers */ for (i = 2; i < NR_IRQS; i++) set_int_vector(i, bad_interrupt[i], 0); - + /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */ set_int_vector(15, multiple_interrupt, 0); - + /* 0 and 1 which are special breakpoint/NMI traps */ set_int_vector(0, hwbreakpoint, 0); @@ -475,17 +479,17 @@ set_break_vector(13, system_call); - /* setup a breakpoint handler for debugging used for both user and - kernel mode debugging (which is why it is not inside an ifdef - CONFIG_ETRAX_KGDB) */ - set_break_vector(8, gdb_handle_breakpoint); + /* setup a breakpoint handler for debugging used for both user and + * kernel mode debugging (which is why it is not inside an ifdef + * CONFIG_ETRAX_KGDB) + */ + set_break_vector(8, gdb_handle_breakpoint); #ifdef CONFIG_ETRAX_KGDB /* setup kgdb if its enabled, and break into the debugger */ kgdb_init(); breakpoint(); #endif - } #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL) diff -urN linux-2.4.21/arch/cris/kernel/kgdb.c linux-2.4.22/arch/cris/kernel/kgdb.c --- linux-2.4.21/arch/cris/kernel/kgdb.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/cris/kernel/kgdb.c 2003-08-25 04:44:39.000000000 -0700 @@ -18,6 +18,9 @@ *! Jul 21 1999 Bjorn Wesen eLinux port *! *! $Log: kgdb.c,v $ +*! Revision 1.8 2003/04/09 08:31:15 pkj +*! Typo correction (taken from Linux 2.5). +*! *! Revision 1.7 2002/07/12 09:14:56 bjornw *! Corrected typo *! @@ -58,7 +61,7 @@ *! *!--------------------------------------------------------------------------- *! -*! $Id: kgdb.c,v 1.7 2002/07/12 09:14:56 bjornw Exp $ +*! $Id: kgdb.c,v 1.8 2003/04/09 08:31:15 pkj Exp $ *! *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN *! @@ -152,7 +155,7 @@ * (IPL too high, disabled, ...) * * - The gdb stub is currently not reentrant, i.e. errors that happen therein - * (e.g. accesing invalid memory) may not be caught correctly. This could + * (e.g. accessing invalid memory) may not be caught correctly. This could * be removed in future by introducing a stack of struct registers. * */ @@ -1486,7 +1489,7 @@ move.d $r0,[reg+0x62] ; Save the return address in BRP move $usp,[reg+0x66] ; USP -;; get the serial character (from debugport.c) and check if its a ctrl-c +;; get the serial character (from debugport.c) and check if it is a ctrl-c jsr getDebugChar cmp.b 3, $r10 diff -urN linux-2.4.21/arch/cris/kernel/process.c linux-2.4.22/arch/cris/kernel/process.c --- linux-2.4.21/arch/cris/kernel/process.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/process.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.23 2002/10/14 18:29:27 johana Exp $ +/* $Id: process.c,v 1.24 2003/03/06 14:19:32 pkj Exp $ * * linux/arch/cris/kernel/process.c * @@ -8,6 +8,9 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: process.c,v $ + * Revision 1.24 2003/03/06 14:19:32 pkj + * Use a cpu_idle() function identical to the one used by i386. + * * Revision 1.23 2002/10/14 18:29:27 johana * Call etrax_gpio_wake_up_check() from cpu_idle() to reduce gpio latency * from ~15 ms to ~6 ms. @@ -114,7 +117,17 @@ * region by enable_hlt/disable_hlt. */ -static int hlt_counter=0; +static int hlt_counter; + +/* + * Powermanagement idle function, if any.. + */ +void (*pm_idle)(void); + +/* + * Power off function, if any + */ +void (*pm_power_off)(void); void disable_hlt(void) { @@ -125,19 +138,42 @@ { hlt_counter--; } -#ifdef CONFIG_ETRAX_GPIO -void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */ -#endif -int cpu_idle(void *unused) +/* + * We use this if we don't have any better + * idle routine.. + */ +static void default_idle(void) { - while(1) { - current->counter = -100; #ifdef CONFIG_ETRAX_GPIO - /* This can reduce latency from 15 ms to 6 ms */ - etrax_gpio_wake_up_check(); /* drivers/gpio.c */ + extern void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */ + + /* This can reduce latency from 15 ms to 6 ms */ + etrax_gpio_wake_up_check(); /* drivers/gpio.c */ #endif +} + +/* + * The idle thread. There's no useful work to be + * done, so just try to conserve power and have a + * low exit latency (ie sit in a loop waiting for + * somebody to say that they'd like to reschedule) + */ +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) + idle(); schedule(); + check_pgt_cache(); } } @@ -191,6 +227,8 @@ void machine_power_off(void) { + if (pm_power_off) + pm_power_off(); } /* diff -urN linux-2.4.21/arch/cris/kernel/setup.c linux-2.4.22/arch/cris/kernel/setup.c --- linux-2.4.21/arch/cris/kernel/setup.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,9 +1,8 @@ -/* $Id: setup.c,v 1.27 2002/10/11 12:57:15 pkj Exp $ - * +/* * linux/arch/cris/kernel/setup.c * * Copyright (C) 1995 Linus Torvalds - * Copyright (c) 2001 Axis Communications AB + * Copyright (c) 2001, 2002, 2003 Axis Communications AB */ /* @@ -94,7 +93,8 @@ memory_start = (unsigned long) &_end; } else { /* otherwise the free area starts after the ROM filesystem */ - printk("ROM fs in RAM, size %lu bytes\n", romfs_length); + printk(KERN_INFO "ROM fs in RAM, size %lu bytes\n", + romfs_length); memory_start = romfs_start + romfs_length; } @@ -169,9 +169,14 @@ *cmdline_p = command_line; +#ifdef CONFIG_ETRAX_CMDLINE + strncpy(command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE); +#elif defined(CONFIG_ETRAX_ROOT_DEVICE) strncpy(command_line, "root=", COMMAND_LINE_SIZE); strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE, COMMAND_LINE_SIZE-5); +#endif + command_line[COMMAND_LINE_SIZE - 1] = '\0'; /* Save command line copy for /proc/cmdline */ @@ -180,7 +185,7 @@ /* give credit for the CRIS port */ - printk("Linux/CRIS port on ETRAX 100LX (c) 2001, 2002 Axis Communications AB\n"); + printk(KERN_INFO "Linux/CRIS port on ETRAX 100LX (c) 2001, 2002 Axis Communications AB\n"); } diff -urN linux-2.4.21/arch/cris/kernel/shadows.c linux-2.4.22/arch/cris/kernel/shadows.c --- linux-2.4.21/arch/cris/kernel/shadows.c 2001-05-01 16:04:56.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/shadows.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,5 @@ -/* $Id: shadows.c,v 1.2 2001/03/15 14:25:16 bjornw Exp $ - * - * Various shadow registers. Defines for these are in include/asm-etrax100/io.h +/* + * Various shadow registers. Defines for these are in include/asm-cris/io.h */ /* Shadows for internal Etrax-registers */ diff -urN linux-2.4.21/arch/cris/kernel/signal.c linux-2.4.22/arch/cris/kernel/signal.c --- linux-2.4.21/arch/cris/kernel/signal.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/signal.c 2003-08-25 04:44:39.000000000 -0700 @@ -528,7 +528,7 @@ case -ERESTARTNOHAND: /* ERESTARTNOHAND means that the syscall should only be restarted if there was no handler for the signal, and since - we only get here if there is a handler, we dont restart */ + we only get here if there is a handler, we don't restart */ regs->r10 = -EINTR; break; diff -urN linux-2.4.21/arch/cris/kernel/sys_cris.c linux-2.4.22/arch/cris/kernel/sys_cris.c --- linux-2.4.21/arch/cris/kernel/sys_cris.c 2001-07-26 15:10:06.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/sys_cris.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: sys_cris.c,v 1.10 2001/06/27 21:16:15 hp Exp $ - * +/* * linux/arch/cris/kernel/sys_cris.c * * This file contains various random system calls that diff -urN linux-2.4.21/arch/cris/kernel/time.c linux-2.4.22/arch/cris/kernel/time.c --- linux-2.4.21/arch/cris/kernel/time.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,9 +1,8 @@ -/* $Id: time.c,v 1.17 2002/11/15 14:49:24 oskarp Exp $ - * +/* * linux/arch/cris/kernel/time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds - * Copyright (C) 1999, 2000, 2001, 2002 Axis Communications AB + * Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB * * 1994-07-02 Alan Modra * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime @@ -18,15 +17,16 @@ * Linux/CRIS specific code: * * Authors: Bjorn Wesen - * Johan Adolfsson + * Johan Adolfsson + * * 2002-03-04 Johan Adolfsson - * Use prescale timer at 25000 Hz instead of the baudrate timer at - * 19200 to get rid of the 64ppm to fast timer (and we get better + * Use prescale timer at 25000 Hz instead of the baudrate timer at + * 19200 to get rid of the 64ppm to fast timer (and we get better * resolution within a jiffie as well. * 2002-03-05 Johan Adolfsson * Use prescaler in do_slow_gettimeoffset() to get 1 us resolution (40ns) * 2002-09-06 Johan Adolfsson - * Handle lost ticks by checking wall_jiffies, more efficient code + * Handle lost ticks by checking wall_jiffies, more efficient code * by using local vars and not the pointer argument. * */ @@ -103,6 +103,60 @@ } +/* Convert the clkdiv_low and clkdivb_high fiels in timer_data + * (from *R_TIMER_DATA) to nanoseconds (67 ns resolution) + */ +unsigned long timer_data_to_ns(unsigned long timer_data) +{ +/* low (clkdiv_low lsb toggles with 7.3728MHz so it counts + * with 14.7456 MHz = 67.816 ns (0-17361ns) + * high (clkdiv_high lsb toggles with 38.4kHz so it counts + * with 76.8kHz = 13020.833 ns (0-3333333 ns) + * By checking bit 9,8,7 we can now how to compensate the low value + * to get a 67 ns resolution all the way. +Example of R_TIMER_DATA values: + bit 98 7 low 9 87 offset +0289DC00 00 000 0 0 00 0 +0289DC41 00 010 64 0 01 0 +0289DC81 00 100 128 0 10 0 +0289DDC0 01 110 192 1 11 0 13020 = 192 +0289DD01 01 000 0 256 1 00 +256 +0289DD41 01 010 64 320 1 01 +256 + +0288DE80 10 100 128 384 0 10 0: -128 26040= 384 +0288DEC1 10 110 192 448 0 11 64 -128 +0288DE01 10 000 0 512 128 +128 +0288DF40 11 010 64 576 192 +128 39060 +0288DF81 11 100 128 640 256 +128 +0288DFC1 11 110 192 704 320 +128 + ..393 +*/ + + static const short timer_data_add[8] = { + 0, /* 00 0 */ + 0, /* 00 1 */ + 256, /* 01 0 */ + 0, /* 01 1 */ + 128, /* 10 0 */ + -128,/* 10 1 */ + 128, /* 11 0 */ + 128 /* 11 1 */ + }; + unsigned long ns; + unsigned long low; + unsigned long high; + + high = (((timer_data & 0x0000FE00)>>8) * 13020833)/1000; + ns = high; + + low = timer_data & 0xFF; + low += timer_data_add[(timer_data >>7) & 0x7]; + ns += (low * 67816)/1000; + return ns; +} /* timer_data_to_ns */ + + + #if CRIS_TEST_TIMERS #define NS_TEST_SIZE 4000 @@ -274,7 +328,7 @@ int retval = 0; int real_seconds, real_minutes, cmos_minutes; - printk("set_rtc_mmss(%lu)\n", nowtime); + printk(KERN_INFO "set_rtc_mmss(%lu)\n", nowtime); if(!have_rtc) return 0; @@ -460,7 +514,8 @@ mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); - printk("rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", + printk(KERN_INFO + "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", sec, min, hour, day, mon, year); BCD_TO_BIN(sec); @@ -585,7 +640,7 @@ /* enable watchdog if we should use one */ #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) - printk("Enabling watchdog...\n"); + printk(KERN_INFO "Enabling watchdog...\n"); start_watchdog(); /* If we use the hardware watchdog, we want to trap it as an NMI diff -urN linux-2.4.21/arch/cris/kernel/traps.c linux-2.4.22/arch/cris/kernel/traps.c --- linux-2.4.21/arch/cris/kernel/traps.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/kernel/traps.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,12 +1,11 @@ -/* $Id: traps.c,v 1.18 2002/12/02 08:11:41 starvik Exp $ - * +/* * linux/arch/cris/traps.c * - * Here we handle the break vectors not used by the system call - * mechanism, as well as some general stack/register dumping + * Here we handle the break vectors not used by the system call + * mechanism, as well as some general stack/register dumping * things. - * - * Copyright (C) 2000,2001 Axis Communications AB + * + * Copyright (C) 2000, 2001, 2002, 2003 Axis Communications AB * * Authors: Bjorn Wesen * Hans-Peter Nilsson @@ -216,6 +215,8 @@ * we have the nice doggy development flag set, we halt here * instead of rebooting. */ +extern void reset_watchdog(void); +extern void stop_watchdog(void); void watchdog_bite_hook(struct pt_regs *regs) @@ -239,9 +240,6 @@ void die_if_kernel(const char * str, struct pt_regs * regs, long err) { - extern void reset_watchdog(void); - extern void stop_watchdog(void); - if(user_mode(regs)) return; diff -urN linux-2.4.21/arch/cris/lib/checksum.S linux-2.4.22/arch/cris/lib/checksum.S --- linux-2.4.21/arch/cris/lib/checksum.S 2001-10-08 11:43:54.000000000 -0700 +++ linux-2.4.22/arch/cris/lib/checksum.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,6 @@ -/* $Id: checksum.S,v 1.6 2001/10/01 14:47:35 bjornw Exp $ +/* * A fast checksum routine using movem - * Copyright (c) 1998-2001 Axis Communications AB + * Copyright (c) 1998-2003 Axis Communications AB * * csum_partial(const unsigned char * buff, int len, unsigned int sum) */ diff -urN linux-2.4.21/arch/cris/lib/checksumcopy.S linux-2.4.22/arch/cris/lib/checksumcopy.S --- linux-2.4.21/arch/cris/lib/checksumcopy.S 2001-10-08 11:43:54.000000000 -0700 +++ linux-2.4.22/arch/cris/lib/checksumcopy.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,9 +1,9 @@ -/* $Id: checksumcopy.S,v 1.7 2001/10/01 14:47:35 bjornw Exp $ +/* * A fast checksum+copy routine using movem - * Copyright (c) 1998, 2001 Axis Communications AB + * Copyright (c) 1998-2003 Axis Communications AB * * Authors: Bjorn Wesen - * + * * csum_partial_copy_nocheck(const char *src, char *dst, * int len, unsigned int sum) */ diff -urN linux-2.4.21/arch/cris/lib/dmacopy.c linux-2.4.22/arch/cris/lib/dmacopy.c --- linux-2.4.21/arch/cris/lib/dmacopy.c 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.22/arch/cris/lib/dmacopy.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: dmacopy.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $ - * +/* * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax */ @@ -13,11 +12,11 @@ unsigned int pn) { static etrax_dma_descr indma, outdma; - + D(printk("dma_memcpy %d bytes... ", pn)); #if 0 - *R_GEN_CONFIG = genconfig_shadow = + *R_GEN_CONFIG = genconfig_shadow = (genconfig_shadow & ~0x3c0000) | IO_STATE(R_GEN_CONFIG, dma6, intdma7) | IO_STATE(R_GEN_CONFIG, dma7, intdma6); @@ -32,12 +31,9 @@ *R_DMA_CH7_FIRST = &outdma; *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start); *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start); - + while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ; D(printk("done\n")); } - - - diff -urN linux-2.4.21/arch/cris/lib/dram_init.S linux-2.4.22/arch/cris/lib/dram_init.S --- linux-2.4.21/arch/cris/lib/dram_init.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/lib/dram_init.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: dram_init.S,v 1.13 2002/10/30 07:42:28 starvik Exp $ +/* $Id: dram_init.S,v 1.14 2003/03/31 07:07:08 starvik Exp $ * * DRAM/SDRAM initialization - alter with care * This file is intended to be included from other assembler files @@ -11,6 +11,9 @@ * Authors: Mikael Starvik (starvik@axis.com) * * $Log: dram_init.S,v $ + * Revision 1.14 2003/03/31 07:07:08 starvik + * Corrected calculation of end of sdram init commands + * * Revision 1.13 2002/10/30 07:42:28 starvik * Always read SDRAM command sequence from flash * @@ -148,7 +151,7 @@ move.d _sdram_commands_start, $r2 and.d 0x00ffffff, $r2 ; Make sure commands are read from flash move.d _sdram_commands_end, $r3 - and.d 0x00ffffff, $r2 + and.d 0x00ffffff, $r3 1: clear.d $r4 move.b [$r2+], $r4 lslq 9, $r4 ; Command starts at bit 9 diff -urN linux-2.4.21/arch/cris/lib/hw_settings.S linux-2.4.22/arch/cris/lib/hw_settings.S --- linux-2.4.21/arch/cris/lib/hw_settings.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/lib/hw_settings.S 2003-08-25 04:44:39.000000000 -0700 @@ -1,13 +1,11 @@ /* - * $Id: hw_settings.S,v 1.5 2002/08/15 09:16:06 bjornw Exp $ - * * This table is used by some tools to extract hardware parameters. * The table should be included in the kernel and the decompressor. * Don't forget to update the tools if you change this table. * - * Copyright (C) 2001, 2002 Axis Communications AB + * Copyright (C) 2001, 2002, 2003 Axis Communications AB * - * Authors: Mikael Starvik (starvik@axis.com) + * Authors: Mikael Starvik (starvik@axis.com) */ #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \ @@ -15,13 +13,13 @@ #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \ (CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \ (CONFIG_ETRAX_DEF_R_PORT_PB_DATA)) - + .ascii "HW_PARAM_MAGIC" ; Magic number .dword 0xc0004000 ; Where to load the kernel image (physical!) ; Debug port #ifdef CONFIG_ETRAX_DEBUG_PORT0 - .dword 0 + .dword 0 #elif defined(CONFIG_ETRAX_DEBUG_PORT1) .dword 1 #elif defined(CONFIG_ETRAX_DEBUG_PORT2) @@ -30,7 +28,7 @@ .dword 3 #else .dword 4 ; No debug -#endif +#endif ; SDRAM or EDO DRAM? #ifdef CONFIG_ETRAX_SDRAM @@ -39,7 +37,7 @@ .dword 0 #endif - ; Register values + ; Register values .dword R_WAITSTATES .dword CONFIG_ETRAX_DEF_R_WAITSTATES .dword R_BUS_CONFIG @@ -56,7 +54,7 @@ .dword CONFIG_ETRAX_DEF_R_DRAM_TIMING #endif .dword R_PORT_PA_SET - .dword PA_SET_VALUE + .dword PA_SET_VALUE .dword R_PORT_PB_SET .dword PB_SET_VALUE .dword 0 ; No more register values diff -urN linux-2.4.21/arch/cris/lib/old_checksum.c linux-2.4.22/arch/cris/lib/old_checksum.c --- linux-2.4.21/arch/cris/lib/old_checksum.c 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.22/arch/cris/lib/old_checksum.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: old_checksum.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $ - * +/* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. diff -urN linux-2.4.21/arch/cris/mm/fault.c linux-2.4.22/arch/cris/mm/fault.c --- linux-2.4.21/arch/cris/mm/fault.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/cris/mm/fault.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,6 +6,10 @@ * Authors: Bjorn Wesen * * $Log: fault.c,v $ + * Revision 1.22 2003/07/07 09:07:04 johana + * Added special CONFIG_ETRAX_DEBUG_INTERRUPT handling here + * to deal with a di in entry.S + * * Revision 1.21 2002/05/28 14:24:56 bjornw * Corrected typo * @@ -68,6 +72,7 @@ * */ +#include #include #include #include @@ -126,6 +131,9 @@ int errcode; unsigned long address; +#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT /* The di is actually in entry.S */ + log_int(rdpc(), regs->dccr, 0); +#endif cause = *R_MMU_CAUSE; select = *R_TLB_SELECT; diff -urN linux-2.4.21/arch/cris/mm/init.c linux-2.4.22/arch/cris/mm/init.c --- linux-2.4.21/arch/cris/mm/init.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/cris/mm/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -7,6 +7,15 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: init.c,v $ + * Revision 1.38 2003/04/01 14:12:08 starvik + * Added loglevel for lots of printks + * + * Revision 1.37 2003/01/22 06:54:47 starvik + * Fixed warnings issued by GCC 3.2.1 + * + * Revision 1.36 2003/01/09 17:59:55 starvik + * Added init_ioremap to initcalls + * * Revision 1.35 2002/05/17 05:33:59 starvik * Limit cache flush range to the size of the cache * @@ -113,6 +122,7 @@ #include #include #include +#include #include #include @@ -208,7 +218,7 @@ int i; unsigned long zones_size[MAX_NR_ZONES]; - printk("Setting up paging and the MMU.\n"); + printk(KERN_INFO "Setting up paging and the MMU.\n"); /* clear out the init_mm.pgd that will contain the kernel's mappings */ @@ -404,7 +414,8 @@ datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, " + printk(KERN_INFO + "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, " "%dk init)\n" , (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), @@ -425,47 +436,40 @@ return; } -/* Initialize remaps of some I/O-ports. This is designed to be callable - * multiple times from the drivers init-sections, because we don't know - * beforehand which driver will get initialized first. +/* Initialize remaps of some I/O-ports. It is important that this + * is called before any driver is initialized. */ -void -init_ioremap(void) +static int +__init init_ioremap(void) { /* Give the external I/O-port addresses their values */ - static int initialized = 0; - - if( !initialized ) { - initialized++; - #ifdef CONFIG_CRIS_LOW_MAP - /* Simply a linear map (see the KSEG map above in paging_init) */ - port_cse1_addr = (volatile unsigned long *)(MEM_CSE1_START | - MEM_NON_CACHEABLE); - port_csp0_addr = (volatile unsigned long *)(MEM_CSP0_START | - MEM_NON_CACHEABLE); - port_csp4_addr = (volatile unsigned long *)(MEM_CSP4_START | - MEM_NON_CACHEABLE); -#else - /* Note that nothing blows up just because we do this remapping - * it's ok even if the ports are not used or connected - * to anything (or connected to a non-I/O thing) */ - port_cse1_addr = (volatile unsigned long *) - ioremap((unsigned long)(MEM_CSE1_START | - MEM_NON_CACHEABLE), 16); - port_csp0_addr = (volatile unsigned long *) - ioremap((unsigned long)(MEM_CSP0_START | - MEM_NON_CACHEABLE), 16); - port_csp4_addr = (volatile unsigned long *) - ioremap((unsigned long)(MEM_CSP4_START | - MEM_NON_CACHEABLE), 16); -#endif - } + /* Simply a linear map (see the KSEG map above in paging_init) */ + port_cse1_addr = (volatile unsigned long *)(MEM_CSE1_START | + MEM_NON_CACHEABLE); + port_csp0_addr = (volatile unsigned long *)(MEM_CSP0_START | + MEM_NON_CACHEABLE); + port_csp4_addr = (volatile unsigned long *)(MEM_CSP4_START | + MEM_NON_CACHEABLE); +#else + /* Note that nothing blows up just because we do this remapping + * it's ok even if the ports are not used or connected + * to anything (or connected to a non-I/O thing) */ + port_cse1_addr = (volatile unsigned long *) + ioremap((unsigned long)(MEM_CSE1_START | MEM_NON_CACHEABLE), 16); + port_csp0_addr = (volatile unsigned long *) + ioremap((unsigned long)(MEM_CSP0_START | MEM_NON_CACHEABLE), 16); + port_csp4_addr = (volatile unsigned long *) + ioremap((unsigned long)(MEM_CSP4_START | MEM_NON_CACHEABLE), 16); +#endif + return 0; } +__initcall(init_ioremap); + /* Helper function for the two below */ static inline void @@ -481,7 +485,7 @@ length = length > 8192 ? 8192 : length; /* No need to flush more than cache size */ while(length > 0) { - short tmp = *flushadr; /* dummy read to flush */ + *flushadr; /* dummy read to flush */ flushadr += (32/sizeof(short)); /* a cacheline is 32 bytes */ length -= 32; } @@ -524,7 +528,7 @@ totalram_pages++; } printk (KERN_INFO "Freeing unused kernel memory: %luk freed\n", - (&__init_end - &__init_begin) >> 10); + (unsigned long)((&__init_end - &__init_begin) >> 10)); } void diff -urN linux-2.4.21/arch/cris/mm/ioremap.c linux-2.4.22/arch/cris/mm/ioremap.c --- linux-2.4.21/arch/cris/mm/ioremap.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/cris/mm/ioremap.c 2003-08-25 04:44:39.000000000 -0700 @@ -146,7 +146,7 @@ */ offset = phys_addr & ~PAGE_MASK; phys_addr &= PAGE_MASK; - size = PAGE_ALIGN(last_addr) - phys_addr; + size = PAGE_ALIGN(last_addr+1) - phys_addr; /* * Ok, go for it.. diff -urN linux-2.4.21/arch/i386/boot/bootsect.S linux-2.4.22/arch/i386/boot/bootsect.S --- linux-2.4.21/arch/i386/boot/bootsect.S 2001-11-09 13:58:02.000000000 -0800 +++ linux-2.4.22/arch/i386/boot/bootsect.S 2003-08-25 04:44:39.000000000 -0700 @@ -234,7 +234,8 @@ die: jne die # %es must be at 64kB boundary xorw %bx, %bx # %bx is starting address within segment rp_read: -#ifdef __BIG_KERNEL__ # look in setup.S for bootsect_kludge +#ifdef __BIG_KERNEL__ + # look in setup.S for bootsect_kludge bootsect_kludge = 0x220 # 0x200 + 0x20 which is the size of the lcall bootsect_kludge # bootsector + bootsect_kludge offset #else diff -urN linux-2.4.21/arch/i386/boot/compressed/misc.c linux-2.4.22/arch/i386/boot/compressed/misc.c --- linux-2.4.21/arch/i386/boot/compressed/misc.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/i386/boot/compressed/misc.c 2003-08-25 04:44:39.000000000 -0700 @@ -101,15 +101,11 @@ static uch *output_data; static unsigned long output_ptr = 0; - static void *malloc(int size); static void free(void *where); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - + static void puts(const char *); - + extern int end; static long free_mem_ptr = (long)&end; static long free_mem_end_ptr; diff -urN linux-2.4.21/arch/i386/config.in linux-2.4.22/arch/i386/config.in --- linux-2.4.21/arch/i386/config.in 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/config.in 2003-08-25 04:44:39.000000000 -0700 @@ -326,14 +326,6 @@ bool 'Power Management support' CONFIG_PM -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_bool ' ACPI support' CONFIG_ACPI $CONFIG_PM - - if [ "$CONFIG_ACPI" != "n" ]; then - source drivers/acpi/Config.in - fi -fi - dep_tristate ' Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM if [ "$CONFIG_APM" != "n" ]; then bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND @@ -345,6 +337,8 @@ bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF fi +source drivers/acpi/Config.in + endmenu source drivers/mtd/Config.in @@ -399,7 +393,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -484,4 +478,5 @@ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/i386/kernel/Makefile linux-2.4.22/arch/i386/kernel/Makefile --- linux-2.4.21/arch/i386/kernel/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/i386/kernel/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -14,7 +14,7 @@ O_TARGET := kernel.o -export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o +export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o setup.o obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ @@ -36,9 +36,12 @@ obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_APM) += apm.o +obj-$(CONFIG_ACPI_BOOT) += acpi.o +obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o +obj-$(CONFIG_ACPI_HT_ONLY) += acpitable.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o apic.o nmi.o -obj-$(CONFIG_X86_IO_APIC) += io_apic.o acpitable.o +obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/i386/kernel/acpi.c linux-2.4.22/arch/i386/kernel/acpi.c --- linux-2.4.21/arch/i386/kernel/acpi.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/i386/kernel/acpi.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,608 @@ +/* + * acpi.c - Architecture-Specific Low-Level ACPI Support + * + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2001 Jun Nakajima + * Copyright (C) 2001 Patrick Mochel + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PREFIX "ACPI: " + +int acpi_lapic = 0; +int acpi_ioapic = 0; + +/* -------------------------------------------------------------------------- + Boot-time Configuration + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_BOOT +extern int acpi_disabled; +extern int acpi_ht; + +enum acpi_irq_model_id acpi_irq_model; + + +/* + * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, + * to map the target physical address. The problem is that set_fixmap() + * provides a single page, and it is possible that the page is not + * sufficient. + * By using this area, we can map up to MAX_IO_APICS pages temporarily, + * i.e. until the next __va_range() call. + * + * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* + * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and + * count idx down while incrementing the phys address. + */ +char *__acpi_map_table(unsigned long phys, unsigned long size) +{ + unsigned long base, offset, mapped_size; + int idx; + + if (phys + size < 8*1024*1024) + return __va(phys); + + offset = phys & (PAGE_SIZE - 1); + mapped_size = PAGE_SIZE - offset; + set_fixmap(FIX_ACPI_END, phys); + base = fix_to_virt(FIX_ACPI_END); + + /* + * Most cases can be covered by the below. + */ + idx = FIX_ACPI_END; + while (mapped_size < size) { + if (--idx < FIX_ACPI_BEGIN) + return 0; /* cannot handle this */ + phys += PAGE_SIZE; + set_fixmap(idx, phys); + mapped_size += PAGE_SIZE; + } + + return ((unsigned char *) base + offset); +} + + +#ifdef CONFIG_X86_LOCAL_APIC + +static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; + + +static int __init +acpi_parse_madt ( + unsigned long phys_addr, + unsigned long size) +{ + struct acpi_table_madt *madt = NULL; + + if (!phys_addr || !size) + return -EINVAL; + + madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); + if (!madt) { + printk(KERN_WARNING PREFIX "Unable to map MADT\n"); + return -ENODEV; + } + + if (madt->lapic_address) + acpi_lapic_addr = (u64) madt->lapic_address; + + printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", + madt->lapic_address); + + detect_clustered_apic(madt->header.oem_id, madt->header.oem_table_id); + + return 0; +} + + +static int __init +acpi_parse_lapic ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic *processor = NULL; + + processor = (struct acpi_table_lapic*) header; + if (!processor) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_register_lapic ( + processor->id, /* APIC ID */ + processor->flags.enabled); /* Enabled? */ + + return 0; +} + + +static int __init +acpi_parse_lapic_addr_ovr ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; + + lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; + if (!lapic_addr_ovr) + return -EINVAL; + + acpi_lapic_addr = lapic_addr_ovr->address; + + return 0; +} + +static int __init +acpi_parse_lapic_nmi ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic_nmi *lapic_nmi = NULL; + + lapic_nmi = (struct acpi_table_lapic_nmi*) header; + if (!lapic_nmi) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + if (lapic_nmi->lint != 1) + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); + + return 0; +} + +#endif /*CONFIG_X86_LOCAL_APIC*/ + +#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) + +static int __init +acpi_parse_ioapic ( + acpi_table_entry_header *header) +{ + struct acpi_table_ioapic *ioapic = NULL; + + ioapic = (struct acpi_table_ioapic*) header; + if (!ioapic) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_register_ioapic ( + ioapic->id, + ioapic->address, + ioapic->global_irq_base); + + return 0; +} + + +static int __init +acpi_parse_int_src_ovr ( + acpi_table_entry_header *header) +{ + struct acpi_table_int_src_ovr *intsrc = NULL; + + intsrc = (struct acpi_table_int_src_ovr*) header; + if (!intsrc) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_override_legacy_irq ( + intsrc->bus_irq, + intsrc->flags.polarity, + intsrc->flags.trigger, + intsrc->global_irq); + + return 0; +} + + +static int __init +acpi_parse_nmi_src ( + acpi_table_entry_header *header) +{ + struct acpi_table_nmi_src *nmi_src = NULL; + + nmi_src = (struct acpi_table_nmi_src*) header; + if (!nmi_src) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + /* TBD: Support nimsrc entries? */ + + return 0; +} + +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ + + +static unsigned long __init +acpi_scan_rsdp ( + unsigned long start, + unsigned long length) +{ + unsigned long offset = 0; + unsigned long sig_len = sizeof("RSD PTR ") - 1; + + /* + * Scan all 16-byte boundaries of the physical memory region for the + * RSDP signature. + */ + for (offset = 0; offset < length; offset += 16) { + if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) + continue; + return (start + offset); + } + + return 0; +} + + +unsigned long __init +acpi_find_rsdp (void) +{ + unsigned long rsdp_phys = 0; + + /* + * Scan memory looking for the RSDP signature. First search EBDA (low + * memory) paragraphs and then search upper memory (E0000-FFFFF). + */ + rsdp_phys = acpi_scan_rsdp (0, 0x400); + if (!rsdp_phys) + rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); + + return rsdp_phys; +} + + +/* + * acpi_boot_init() + * called from setup_arch(), always. + * 1. maps ACPI tables for later use + * 2. enumerates lapics + * 3. enumerates io-apics + * + * side effects: + * acpi_lapic = 1 if LAPIC found + * acpi_ioapic = 1 if IOAPIC found + * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; + * if acpi_blacklisted() acpi_disabled = 1; + * acpi_irq_model=... + * ... + * + * return value: (currently ignored) + * 0: success + * !0: failure + */ +int __init +acpi_boot_init (void) +{ + int result = 0; + + if (acpi_disabled && !acpi_ht) + return(1); + + /* + * The default interrupt routing model is PIC (8259). This gets + * overriden if IOAPICs are enumerated (below). + */ + acpi_irq_model = ACPI_IRQ_MODEL_PIC; + + /* + * Initialize the ACPI boot-time table parser. + */ + result = acpi_table_init(); + if (result) + return result; + + result = acpi_blacklisted(); + if (result) { + printk(KERN_NOTICE PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); + acpi_disabled = 1; + return result; + } + +#ifdef CONFIG_X86_LOCAL_APIC + + /* + * MADT + * ---- + * Parse the Multiple APIC Description Table (MADT), if exists. + * Note that this table provides platform SMP configuration + * information -- the successor to MPS tables. + */ + + result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); + if (!result) { + printk(KERN_WARNING PREFIX "MADT not present\n"); + return 0; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing MADT\n"); + return result; + } + else if (result > 1) + printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); + + /* + * Local APIC + * ---------- + * Note that the LAPIC address is obtained from the MADT (32-bit value) + * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). + */ + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); + return result; + } + + mp_register_lapic_address(acpi_lapic_addr); + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic); + if (!result) { + printk(KERN_ERR PREFIX "No LAPIC entries present\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return -ENODEV; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + acpi_lapic = 1; + +#endif /*CONFIG_X86_LOCAL_APIC*/ + +#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) + + /* + * I/O APIC + * -------- + */ + + /* + * ACPI interpreter is required to complete interrupt setup, + * so if it is off, don't enumerate the io-apics with ACPI. + * If MPS is present, it will handle them, + * otherwise the system will stay in PIC mode + */ + if (acpi_disabled) { + return 1; + } + + /* + * if "noapic" boot option, don't look for IO-APICs + */ + if (ioapic_setup_disabled()) { + printk(KERN_INFO PREFIX "Skipping IOAPIC probe " + "due to 'noapic' option.\n"); + return 1; + } + + + result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic); + if (!result) { + printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); + return -ENODEV; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); + return result; + } + + /* Build a default routing table for legacy (ISA) interrupts. */ + mp_config_acpi_legacy_irqs(); + + result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; + + acpi_ioapic = 1; + + if (acpi_lapic && acpi_ioapic) + smp_found_config = 1; + +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ + + return 0; +} + +#endif /*CONFIG_ACPI_BOOT*/ + + +/* -------------------------------------------------------------------------- + Low-Level Sleep Support + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_SLEEP + +#define DEBUG + +#ifdef DEBUG +#include +#endif + +/* address in low memory of the wakeup routine. */ +unsigned long acpi_wakeup_address = 0; + +/* new page directory that we will be using */ +static pmd_t *pmd; + +/* saved page directory */ +static pmd_t saved_pmd; + +/* page which we'll use for the new page directory */ +static pte_t *ptep; + +extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); + +/* + * acpi_create_identity_pmd + * + * Create a new, identity mapped pmd. + * + * Do this by creating new page directory, and marking all the pages as R/W + * Then set it as the new Page Middle Directory. + * And, of course, flush the TLB so it takes effect. + * + * We save the address of the old one, for later restoration. + */ +static void acpi_create_identity_pmd (void) +{ + pgd_t *pgd; + int i; + + ptep = (pte_t*)__get_free_page(GFP_KERNEL); + + /* fill page with low mapping */ + for (i = 0; i < PTRS_PER_PTE; i++) + set_pte(ptep + i, mk_pte_phys(i << PAGE_SHIFT, PAGE_SHARED)); + + pgd = pgd_offset(current->active_mm, 0); + pmd = pmd_alloc(current->mm,pgd, 0); + + /* save the old pmd */ + saved_pmd = *pmd; + + /* set the new one */ + set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep))); + + /* flush the TLB */ + local_flush_tlb(); +} + +/* + * acpi_restore_pmd + * + * Restore the old pmd saved by acpi_create_identity_pmd and + * free the page that said function alloc'd + */ +static void acpi_restore_pmd (void) +{ + set_pmd(pmd, saved_pmd); + local_flush_tlb(); + free_page((unsigned long)ptep); +} + +/** + * acpi_save_state_mem - save kernel state + * + * Create an identity mapped page table and copy the wakeup routine to + * low memory. + */ +int acpi_save_state_mem (void) +{ + acpi_create_identity_pmd(); + acpi_copy_wakeup_routine(acpi_wakeup_address); + + return 0; +} + +/** + * acpi_save_state_disk - save kernel state to disk + * + */ +int acpi_save_state_disk (void) +{ + return 1; +} + +/* + * acpi_restore_state + */ +void acpi_restore_state_mem (void) +{ + acpi_restore_pmd(); +} + +/** + * acpi_reserve_bootmem - do _very_ early ACPI initialisation + * + * We allocate a page in low memory for the wakeup + * routine for when we come back from a sleep state. The + * runtime allocator allows specification of <16M pages, but not + * <1M pages. + */ +void __init acpi_reserve_bootmem(void) +{ + acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); + printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); +} + +void do_suspend_lowlevel_s4bios(int resume) +{ + if (!resume) { + save_processor_context(); + acpi_save_register_state((unsigned long)&&acpi_sleep_done); + acpi_enter_sleep_state_s4bios(); + return; + } +acpi_sleep_done: + restore_processor_context(); +} + + +#endif /*CONFIG_ACPI_SLEEP*/ + diff -urN linux-2.4.21/arch/i386/kernel/acpi_wakeup.S linux-2.4.22/arch/i386/kernel/acpi_wakeup.S --- linux-2.4.21/arch/i386/kernel/acpi_wakeup.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/i386/kernel/acpi_wakeup.S 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,145 @@ + +.text +#include +#include + + +ALIGN +wakeup_start: +wakeup_code: + wakeup_code_start = . + .code16 + + cli + cld + + # setup data segment + movw %cs, %ax + + addw $(wakeup_data - wakeup_code) >> 4, %ax + movw %ax, %ds + movw %ax, %ss + + # Private stack is needed for ASUS board + mov $(wakeup_stack - wakeup_data), %sp + + # set up page table + movl (real_save_cr3 - wakeup_data), %eax + movl %eax, %cr3 + + # make sure %cr4 is set correctly (features, etc) + movl (real_save_cr4 - wakeup_data), %eax + movl %eax, %cr4 + + # need a gdt + lgdt real_save_gdt - wakeup_data + + # Flush the prefetch queue + jmp 1f +1: + + movl %cr0, %eax + orl $0x80000001, %eax + movl %eax, %cr0 + + ljmpl $__KERNEL_CS,$SYMBOL_NAME(wakeup_pmode_return) + + .code32 + ALIGN + +.org 0x100 +wakeup_data: + .word 0 +real_save_gdt: .word 0 + .long 0 +real_save_cr3: .long 0 +real_save_cr4: .long 0 + +.org 0x300 +wakeup_stack: +wakeup_end: + +wakeup_pmode_return: + # restore data segment + movl $__KERNEL_DS, %eax + movw %ax, %ds + movw %ax, %es + + # and restore the stack + movw %ax, %ss + movl saved_esp, %esp + + # restore other segment registers + xorl %eax, %eax + movw %ax, %fs + movw %ax, %gs + + # reload the gdt, as we need the full 32 bit address + lgdt saved_gdt + lidt saved_idt + lldt saved_ldt + + # restore the other general registers + movl saved_ebx, %ebx + movl saved_edi, %edi + movl saved_esi, %esi + movl saved_ebp, %ebp + + # jump to place where we left off + movl saved_eip,%eax + jmp *%eax + +## +# acpi_copy_wakeup_routine +# +# Copy the above routine to low memory. +# +# Parameters: +# %eax: place to copy wakeup routine to +# +# Returned address is location of code in low memory (past data and stack) +# +ENTRY(acpi_copy_wakeup_routine) + + pushl %esi + pushl %edi + + sgdt saved_gdt + sidt saved_idt + sldt saved_ldt + str saved_tss + + movl %eax, %edi + leal wakeup_start, %esi + movl $(wakeup_end - wakeup_start) >> 2, %ecx + + rep ; movsl + + movl %cr3, %edx + movl %edx, real_save_cr3 - wakeup_start (%eax) + movl %cr4, %edx + movl %edx, real_save_cr4 - wakeup_start (%eax) + sgdt real_save_gdt - wakeup_start (%eax) + + # restore the regs we used + popl %edi + popl %esi + ret + + +.data +ALIGN +# saved registers +saved_gdt: .long 0,0 +saved_idt: .long 0,0 +saved_ldt: .long 0 +saved_tss: .long 0 +saved_cr0: .long 0 + +ENTRY(saved_ebp) .long 0 +ENTRY(saved_esi) .long 0 +ENTRY(saved_edi) .long 0 +ENTRY(saved_ebx) .long 0 + +ENTRY(saved_eip) .long 0 +ENTRY(saved_esp) .long 0 diff -urN linux-2.4.21/arch/i386/kernel/acpitable.c linux-2.4.22/arch/i386/kernel/acpitable.c --- linux-2.4.21/arch/i386/kernel/acpitable.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/acpitable.c 2003-08-25 04:44:39.000000000 -0700 @@ -45,6 +45,7 @@ static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT]; +int acpi_lapic; static unsigned char __init acpi_checksum(void *buffer, int length) @@ -94,7 +95,7 @@ static void *__init acpi_tb_scan_memory_for_rsdp(void *address, int length) { - u32 offset; + int offset; if (length <= 0) return NULL; @@ -117,7 +118,8 @@ } /* Searched entire block, no RSDP was found */ - printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.\n"); + dprintk(KERN_INFO "ACPI: Searched entire block 0x%x:0x%x, no RSDP was found.\n", + (int)address, (int)address + length); return NULL; } @@ -330,7 +332,7 @@ printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id); if (local_apic->flags.enabled) { - printk(" enabled"); + printk(" enabled\n"); ix = local_apic->id; if (ix >= MAX_APICS) { printk(KERN_WARNING @@ -360,9 +362,8 @@ proc_entry.mpc_apicver = 0x10; /* integrated APIC */ MP_processor_info(&proc_entry); } else { - printk(" disabled"); + printk(" disabled\n"); } - printk("\n"); total_cpus++; return; @@ -530,14 +531,13 @@ return 0; } -extern int enable_acpi_smp_table; /* * Configure the processor info using MADT in the ACPI tables. If we fail to * configure that, then we use the MPS tables. */ void __init -config_acpi_tables(void) +acpi_boot_init(void) { memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops)); @@ -547,8 +547,7 @@ * Only do this when requested, either because of CPU/Bios type or from the command line */ - if (enable_acpi_smp_table && !acpi_tables_init()) { - have_acpi_tables = 1; - printk("Enabling the CPU's according to the ACPI table\n"); - } + if (!acpi_tables_init()) + acpi_lapic = 1; } + diff -urN linux-2.4.21/arch/i386/kernel/acpitable.h linux-2.4.22/arch/i386/kernel/acpitable.h --- linux-2.4.21/arch/i386/kernel/acpitable.h 2001-11-11 19:04:33.000000000 -0800 +++ linux-2.4.22/arch/i386/kernel/acpitable.h 2003-08-25 04:44:39.000000000 -0700 @@ -39,7 +39,9 @@ #ifndef _HEADER_ACPITABLE_H_ #define _HEADER_ACPITABLE_H_ -#define dprintk printk +//#define dprintk(s, args...) printk(s, ## args) +#define dprintk(s, args...) + typedef unsigned int ACPI_TBLPTR; typedef struct { /* ACPI common table header */ diff -urN linux-2.4.21/arch/i386/kernel/apm.c linux-2.4.22/arch/i386/kernel/apm.c --- linux-2.4.21/arch/i386/kernel/apm.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/apm.c 2003-08-25 04:44:39.000000000 -0700 @@ -868,6 +868,8 @@ idle_percentage *= 100; idle_percentage /= jiffies_since_last_check; use_apm_idle = (idle_percentage > idle_threshold); + if (apm_info.forbid_idle) + use_apm_idle = 0; last_jiffies = jiffies; last_stime = current->times.tms_stime; } diff -urN linux-2.4.21/arch/i386/kernel/dmi_scan.c linux-2.4.22/arch/i386/kernel/dmi_scan.c --- linux-2.4.21/arch/i386/kernel/dmi_scan.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/dmi_scan.c 2003-08-25 04:44:39.000000000 -0700 @@ -23,8 +23,11 @@ u16 handle; }; +#ifdef DMI_DEBUG +#define dmi_printk(x) printk x +#else #define dmi_printk(x) -//#define dmi_printk(x) printk x +#endif static char * __init dmi_string(struct dmi_header *dm, u8 s) { @@ -297,6 +300,32 @@ return 0; } +static __init int apm_is_horked_d850md(struct dmi_blacklist *d) +{ + if (apm_info.disabled == 0) + { + apm_info.disabled = 1; + printk(KERN_ERR "%s machine detected. Disabling APM.\n", d->ident); + printk(KERN_ERR "This bug is fixed in bios P15 which is available for \n"); + printk(KERN_ERR "download from support.intel.com \n"); + } + return 0; +} + +/* + * Some APM bioses hang on APM idle calls + */ + +static __init int apm_likes_to_melt(struct dmi_blacklist *d) +{ + if (apm_info.forbid_idle == 0) + { + apm_info.forbid_idle = 1; + printk(KERN_INFO "%s machine detected. Disabling APM idle calls.\n", d->ident); + } + return 0; +} + /* * Some machines, usually laptops, can't handle an enabled local APIC. * The symptoms include hangs or reboots when suspending or resuming, @@ -414,9 +443,10 @@ * The MP1.4 table is right however and so SMP kernels tend to work. */ -extern int skip_ioapic_setup; +#ifdef CONFIG_PCI extern int broken_440gx_bios; extern unsigned int pci_probe; +#endif static __init int broken_pirq(struct dmi_blacklist *d) { printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n"); @@ -425,13 +455,26 @@ printk(KERN_INFO " *** contact your hardware vendor and ask about updates.\n"); printk(KERN_INFO " *** Building an SMP kernel may evade the bug some of the time.\n"); #ifdef CONFIG_X86_IO_APIC - skip_ioapic_setup = 0; + { + extern int skip_ioapic_setup; + skip_ioapic_setup = 0; + } #endif #ifdef CONFIG_PCI broken_440gx_bios = 1; pci_probe |= PCI_BIOS_IRQ_SCAN; #endif - + return 0; +} + +/* + * ASUS K7V-RM has broken ACPI table defining sleep modes + */ + +static __init int broken_acpi_Sx(struct dmi_blacklist *d) +{ + printk(KERN_WARNING "Detected ASUS mainboard with broken ACPI sleep table\n"); + dmi_broken |= BROKEN_ACPI_Sx; return 0; } @@ -483,6 +526,18 @@ } /* + * Exploding PnPBIOS. Don't yet know if its the BIOS or us for + * some entries + */ + +static __init int exploding_pnp_bios(struct dmi_blacklist *d) +{ + printk(KERN_WARNING "%s detected. Disabling PnPBIOS\n", d->ident); + dmi_broken |= BROKEN_PNP_BIOS; + return 0; +} + +/* * Simple "print if true" callback */ @@ -492,6 +547,47 @@ return 0; } + +#ifdef CONFIG_ACPI_BOOT +extern int acpi_disabled, use_acpi_pci, acpi_force, acpi_ht; + +static __init __attribute__((unused)) int acpi_disable(struct dmi_blacklist *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); + acpi_disabled = 1; + } else { + printk(KERN_NOTICE + "Warning: DMI blacklist says broken, but acpi forced\n"); + } + return 0; +} + + +/* + * Limit ACPI to CPU enumeration for HT + */ +static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident); + acpi_disabled = 1; + acpi_ht = 1; + } else { + printk(KERN_NOTICE + "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); + } + return 0; +} + +static __init int disable_acpi_pci(struct dmi_blacklist *d) +{ + printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident); + use_acpi_pci = 0; + return 0; +} +#endif + /* * Process the DMI blacklists */ @@ -508,17 +604,47 @@ MATCH(DMI_PRODUCT_NAME, "KT7-RAID"), NO_MATCH, NO_MATCH, NO_MATCH } }, + { disable_ide_dma, "Dell Inspiron 8100", { /* Kill DMA on Dell Inspiron 8100 laptops */ + MATCH(DMI_PRODUCT_NAME, "Inspiron 8100"), + MATCH(DMI_SYS_VENDOR,"Dell Computer Corporation"), NO_MATCH, NO_MATCH + } }, + #endif + /* Dell Laptop hall of shame */ { broken_ps2_resume, "Dell Latitude C600", { /* Handle problems with APM on the C600 */ MATCH(DMI_SYS_VENDOR, "Dell"), MATCH(DMI_PRODUCT_NAME, "Latitude C600"), NO_MATCH, NO_MATCH } }, + { apm_is_horked, "Dell Inspiron 2500", { /* APM crashes */ + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"), + MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), + MATCH(DMI_BIOS_VERSION,"A11") + } }, + { apm_is_horked, "Dell Dimension 4100", { /* APM crashes */ + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "XPS-Z"), + MATCH(DMI_BIOS_VENDOR,"Intel Corp."), + MATCH(DMI_BIOS_VERSION,"A11") + } }, + { set_apm_ints, "Dell Inspiron", { /* Allow interrupts during suspend on Dell Inspiron laptops*/ + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), + NO_MATCH, NO_MATCH + } }, + { set_apm_ints, "Dell Latitude", { /* Allow interrupts during suspend on Dell Latitude laptops*/ + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Latitude C510"), + NO_MATCH, NO_MATCH + } }, { broken_apm_power, "Dell Inspiron 5000e", { /* Handle problems with APM on Inspiron 5000e */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "A04"), MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH } }, + + /* other items */ { broken_apm_power, "Dell Inspiron 2500", { /* Handle problems with APM on Inspiron 2500 */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "A12"), @@ -539,16 +665,11 @@ MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"), NO_MATCH, NO_MATCH } }, - { set_bios_reboot, "Dell PowerEdge 2400", { /* Handle problems with rebooting on Dell 300/800's */ + { set_bios_reboot, "Dell PowerEdge 2400", { /* Handle problems with rebooting on Dell 2400's */ MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"), NO_MATCH, NO_MATCH } }, - { set_apm_ints, "Dell Inspiron", { /* Allow interrupts during suspend on Dell Inspiron laptops*/ - MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), - NO_MATCH, NO_MATCH - } }, { set_apm_ints, "Compaq 12XL125", { /* Allow interrupts during suspend on Compaq Laptops*/ MATCH(DMI_SYS_VENDOR, "Compaq"), MATCH(DMI_PRODUCT_NAME, "Compaq PC"), @@ -560,6 +681,11 @@ MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), NO_MATCH, NO_MATCH } }, + { apm_is_horked, "ABIT KX7-333[R]", { /* APM blows on shutdown */ + MATCH(DMI_BOARD_VENDOR, "ABIT"), + MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), + NO_MATCH, NO_MATCH, + } }, { apm_is_horked, "Trigem Delhi3", { /* APM crashes */ MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"), MATCH(DMI_PRODUCT_NAME, "Delhi3"), @@ -570,7 +696,7 @@ MATCH(DMI_BIOS_VERSION, "Version1.01"), NO_MATCH, NO_MATCH, } }, - { apm_is_horked, "Intel D850MD", { /* APM crashes */ + { apm_is_horked_d850md, "Intel D850MD", { /* APM crashes */ MATCH(DMI_BIOS_VENDOR, "Intel Corp."), MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), NO_MATCH, NO_MATCH, @@ -598,6 +724,22 @@ MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION,"A11") } }, + { apm_likes_to_melt, "Jabil AMD", { /* APM idle hangs */ + MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), + MATCH(DMI_BIOS_VERSION, "0AASNP06"), + NO_MATCH, NO_MATCH, + } }, + { apm_likes_to_melt, "AMI Bios", { /* APM idle hangs */ + MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), + MATCH(DMI_BIOS_VERSION, "0AASNP05"), + NO_MATCH, NO_MATCH, + } }, + { apm_likes_to_melt, "Dell Inspiron 7500", { /* APM idle hangs */ + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Inspiron 7500"), + NO_MATCH, NO_MATCH, + } }, + { sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */ MATCH(DMI_SYS_VENDOR, "Sony Corporation"), MATCH(DMI_PRODUCT_NAME, "PCG-"), @@ -692,6 +834,13 @@ NO_MATCH, NO_MATCH } }, + { exploding_pnp_bios, "Higraded P14H", { /* BIOSPnP problem */ + MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), + MATCH(DMI_BIOS_VERSION, "07.00T"), + MATCH(DMI_SYS_VENDOR, "Higraded"), + MATCH(DMI_PRODUCT_NAME, "P14H") + } }, + /* Machines which have problems handling enabled local APICs */ { local_apic_kills_bios, "Dell Inspiron", { @@ -731,11 +880,26 @@ } }, { broken_pirq, "l44GX Bios", { /* Bad $PIR */ MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), + MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07"), + NO_MATCH, NO_MATCH + } }, + { broken_pirq, "IBM xseries 370", { /* Bad $PIR */ + MATCH(DMI_BIOS_VENDOR, "IBM"), + MATCH(DMI_BIOS_VERSION,"MMKT33AUS"), + NO_MATCH, NO_MATCH + } }, + { broken_pirq, "l44GX Bios", { /* Bad $PIR */ + MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0094.P10"), NO_MATCH, NO_MATCH } }, { broken_pirq, "l44GX Bios", { /* Bad $PIR */ MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), + MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0115.P12"), + NO_MATCH, NO_MATCH + } }, + { broken_pirq, "l44GX Bios", { /* Bad $PIR */ + MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0120.P12"), NO_MATCH, NO_MATCH } }, @@ -746,7 +910,17 @@ } }, { broken_pirq, "l44GX Bios", { /* Bad $PIR */ MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), - MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07.9906041405"), + MATCH(DMI_BIOS_VERSION,"C440GX0.86B"), + NO_MATCH, NO_MATCH + } }, + { broken_pirq, "l44GX Bios", { /* Bad $PIR */ + MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), + MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0133.P14"), + NO_MATCH, NO_MATCH + } }, + { broken_pirq, "l44GX Bios", { /* Bad $PIR */ + MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), + MATCH(DMI_BIOS_VERSION,"L440GX0"), NO_MATCH, NO_MATCH } }, @@ -757,6 +931,12 @@ NO_MATCH, NO_MATCH, NO_MATCH } }, + { broken_acpi_Sx, "ASUS K7V-RM", { /* Bad ACPI Sx table */ + MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"), + MATCH(DMI_BOARD_NAME, ""), + NO_MATCH, NO_MATCH + } }, + { init_ints_after_s1, "Toshiba Satellite 4030cdt", { /* Reinitialization of 8259 is needed after S1 resume */ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), NO_MATCH, NO_MATCH, NO_MATCH @@ -774,7 +954,6 @@ MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"), MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736") } }, - /* * Generic per vendor APM settings @@ -785,6 +964,115 @@ NO_MATCH, NO_MATCH, NO_MATCH } }, +#ifdef CONFIG_ACPI_BOOT + /* + * If your system is blacklisted here, but you find that acpi=force + * works for you, please contact acpi-devel@sourceforge.net + */ + + /* + * Boxes that need ACPI disabled + */ + + { acpi_disable, "IBM Thinkpad", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "2629H1G"), + NO_MATCH, NO_MATCH }}, + + /* + * Boxes that need acpi=ht + */ + + { force_acpi_ht, "FSC Primergy T850", { + MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "DELL GX240", { + MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "HP VISUALIZE NT Workstation", { + MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq ProLiant DL380 G2", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "ProLiant DL380 G2"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq ProLiant ML530 G2", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "ProLiant ML530 G2"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq ProLiant ML350 G3", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "ProLiant ML350 G3"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq Workstation W8000", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS P4B266", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + MATCH(DMI_BOARD_NAME, "P4B266"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS P2B-DS", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + MATCH(DMI_BOARD_NAME, "P2B-DS"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS CUR-DLS", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + MATCH(DMI_BOARD_NAME, "CUR-DLS"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS A7V", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), + MATCH(DMI_BOARD_NAME, ""), + MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1011"), NO_MATCH }}, + + { force_acpi_ht, "ABIT i440BX-W83977", { + MATCH(DMI_BOARD_VENDOR, "ABIT "), + MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM Bladecenter", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM eServer xSeries 360", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM eserver xSeries 330", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM eserver xSeries 440", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), + NO_MATCH, NO_MATCH }}, + + /* + * Boxes that need ACPI PCI IRQ routing disabled + */ + + { disable_acpi_pci, "ASUS A7V", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), + MATCH(DMI_BOARD_NAME, ""), + MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), NO_MATCH }}, +#endif // CONFIG_ACPI_BOOT + { NULL, } }; @@ -794,11 +1082,34 @@ * returns 1 or we hit the end. */ + static __init void dmi_check_blacklist(void) { struct dmi_blacklist *d; int i; +#ifdef CONFIG_ACPI_BOOT +#define ACPI_BLACKLIST_CUTOFF_YEAR 2001 + + if (dmi_ident[DMI_BIOS_DATE]) { + char *s = strrchr(dmi_ident[DMI_BIOS_DATE], '/'); + if (s) { + int year, disable = 0; + s++; + year = simple_strtoul(s,NULL,0); + if (year >= 1000) + disable = year < ACPI_BLACKLIST_CUTOFF_YEAR; + else if (year < 1 || (year > 90 && year <= 99)) + disable = 1; + if (disable && !acpi_force) { + printk(KERN_NOTICE "ACPI disabled because your bios is from %s and too old\n", s); + printk(KERN_NOTICE "You can enable it with acpi=force\n"); + acpi_disabled = 1; + } + } + } +#endif + d=&dmi_blacklist[0]; while(d->callback) { @@ -829,8 +1140,9 @@ static void __init dmi_decode(struct dmi_header *dm) { +#ifdef DMI_DEBUG u8 *data = (u8 *)dm; - +#endif switch(dm->type) { case 0: @@ -876,4 +1188,7 @@ int err = dmi_iterate(dmi_decode); if(err == 0) dmi_check_blacklist(); + else + printk(KERN_INFO "DMI not present.\n"); } + diff -urN linux-2.4.21/arch/i386/kernel/i387.c linux-2.4.22/arch/i386/kernel/i387.c --- linux-2.4.21/arch/i386/kernel/i387.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/i387.c 2003-08-25 04:44:39.000000000 -0700 @@ -373,14 +373,14 @@ static inline int restore_i387_fxsave( struct _fpstate *buf ) { + int err; struct task_struct *tsk = current; clear_fpu( tsk ); - if ( __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0], - sizeof(struct i387_fxsave_struct) ) ) - return 1; + err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0], + sizeof(struct i387_fxsave_struct) ); /* mxcsr bit 6 and 31-16 must be zero for security reasons */ tsk->thread.i387.fxsave.mxcsr &= 0xffbf; - return convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf ); + return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf ); } int restore_i387( struct _fpstate *buf ) diff -urN linux-2.4.21/arch/i386/kernel/io_apic.c linux-2.4.22/arch/i386/kernel/io_apic.c --- linux-2.4.21/arch/i386/kernel/io_apic.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/io_apic.c 2003-08-25 04:44:39.000000000 -0700 @@ -17,6 +17,7 @@ * thanks to Eric Gilmore * and Rolf G. Tews * for testing these extensively + * Paul Diefenbaugh : Added full ACPI support */ #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include @@ -123,7 +125,7 @@ break; \ reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ reg ACTION; \ - io_apic_modify(entry->apic, reg); \ + io_apic_write(entry->apic, 0x10 + R + pin*2, reg); \ if (!entry->next) \ break; \ entry = irq_2_pin + entry->next; \ @@ -750,6 +752,7 @@ struct IO_APIC_reg_00 reg_00; struct IO_APIC_reg_01 reg_01; struct IO_APIC_reg_02 reg_02; + struct IO_APIC_reg_03 reg_03; unsigned long flags; printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); @@ -770,6 +773,8 @@ *(int *)®_01 = io_apic_read(apic, 1); if (reg_01.version >= 0x10) *(int *)®_02 = io_apic_read(apic, 2); + if (reg_01.version >= 0x20) + *(int *)®_03 = io_apic_read(apic, 3); spin_unlock_irqrestore(&ioapic_lock, flags); printk("\n"); @@ -807,13 +812,31 @@ if (reg_01.__reserved_1 || reg_01.__reserved_2) UNEXPECTED_IO_APIC(); - if (reg_01.version >= 0x10) { + /* + * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, + * but the value of reg_02 is read as the previous read register + * value, so ignore it if reg_02 == reg_01. + */ + if (reg_01.version >= 0x10 && *(int *)®_02 != *(int *)®_01) { printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)®_02); printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.arbitration); if (reg_02.__reserved_1 || reg_02.__reserved_2) UNEXPECTED_IO_APIC(); } + /* + * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 + * or reg_03, but the value of reg_0[23] is read as the previous read + * register value, so ignore it if reg_03 == reg_0[12]. + */ + if (reg_01.version >= 0x20 && *(int *)®_03 != *(int *)®_02 && + *(int *)®_03 != *(int *)®_01) { + printk(KERN_DEBUG ".... register #03: %08X\n", *(int *)®_03); + printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.boot_DT); + if (reg_03.__reserved_1) + UNEXPECTED_IO_APIC(); + } + printk(KERN_DEBUG ".... IRQ redirection table:\n"); printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol" @@ -1057,6 +1080,10 @@ unsigned char old_id; unsigned long flags; + if (acpi_ioapic) + /* This gets done during IOAPIC enumeration for ACPI. */ + return; + if (clustered_apic_mode) /* We don't have a good way to do this yet - hack */ phys_id_present_map = (u_long) 0xf; @@ -1316,6 +1343,25 @@ static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ } +#ifndef CONFIG_SMP + +void send_IPI_self(int vector) +{ + unsigned int cfg; + + /* + * Wait for idle. + */ + apic_wait_icr_idle(); + cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL; + /* + * Send the IPI. The write to APIC_ICR fires this off. + */ + apic_write_around(APIC_ICR, cfg); +} + +#endif /* CONFIG_SMP */ + static void set_ioapic_affinity (unsigned int irq, unsigned long mask) { unsigned long flags; @@ -1657,8 +1703,7 @@ printk("ENABLING IO-APIC IRQs\n"); /* - * Set up the IO-APIC IRQ routing table by parsing the MP-BIOS - * mptable: + * Set up IO-APIC IRQ routing. */ setup_ioapic_ids_from_mpc(); sync_Arb_IDs(); @@ -1667,3 +1712,170 @@ check_timer(); print_IO_APIC(); } + + +/* -------------------------------------------------------------------------- + ACPI-based IOAPIC Configuration + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_BOOT + +#define IO_APIC_MAX_ID 15 + +int __init io_apic_get_unique_id (int ioapic, int apic_id) +{ + struct IO_APIC_reg_00 reg_00; + static unsigned long apic_id_map = 0; + unsigned long flags; + int i = 0; + + /* + * The P4 platform supports up to 256 APIC IDs on two separate APIC + * buses (one for LAPICs, one for IOAPICs), where predecessors only + * supports up to 16 on one shared APIC bus. + * + * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full + * advantage of new APIC bus architecture. + */ + + if (!apic_id_map) + apic_id_map = phys_cpu_present_map; + + spin_lock_irqsave(&ioapic_lock, flags); + *(int *)®_00 = io_apic_read(ioapic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + if (apic_id >= IO_APIC_MAX_ID) { + printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " + "%d\n", ioapic, apic_id, reg_00.ID); + apic_id = reg_00.ID; + } + + /* XAPICs do not need unique IDs */ + if (clustered_apic_mode == CLUSTERED_APIC_XAPIC){ + printk(KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", + ioapic, apic_id); + return apic_id; + } + + /* + * Every APIC in a system must have a unique ID or we get lots of nice + * 'stuck on smp_invalidate_needed IPI wait' messages. + */ + if (apic_id_map & (1 << apic_id)) { + + for (i = 0; i < IO_APIC_MAX_ID; i++) { + if (!(apic_id_map & (1 << i))) + break; + } + + if (i == IO_APIC_MAX_ID) + panic("Max apic_id exceeded!\n"); + + printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " + "trying %d\n", ioapic, apic_id, i); + + apic_id = i; + } + + apic_id_map |= (1 << apic_id); + + if (reg_00.ID != apic_id) { + reg_00.ID = apic_id; + + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic, 0, *(int *)®_00); + *(int *)®_00 = io_apic_read(ioapic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + /* Sanity check */ + if (reg_00.ID != apic_id) + panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); + } + + printk(KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); + + return apic_id; +} + + +int __init io_apic_get_version (int ioapic) +{ + struct IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + *(int *)®_01 = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.version; +} + + +int __init io_apic_get_redir_entries (int ioapic) +{ + struct IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + *(int *)®_01 = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.entries; +} + + +int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low) +{ + struct IO_APIC_route_entry entry; + unsigned long flags; + + if (!IO_APIC_IRQ(irq)) { + printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0/n", + ioapic); + return -EINVAL; + } + + /* + * Generate a PCI IRQ routing entry and program the IOAPIC accordingly. + * Note that we mask (disable) IRQs now -- these get enabled when the + * corresponding device driver registers for this IRQ. + */ + + memset(&entry,0,sizeof(entry)); + + entry.delivery_mode = dest_LowestPrio; + entry.dest_mode = INT_DELIVERY_MODE; + entry.dest.logical.logical_dest = target_cpus(); + entry.mask = 1; /* Disabled (masked) */ + entry.trigger = edge_level; + entry.polarity = active_high_low; + + add_pin_to_irq(irq, ioapic, pin); + + entry.vector = assign_irq_vector(irq); + + printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> " + "IRQ %d Mode:%i Active:%i)\n", ioapic, + mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low); + + if (edge_level) { + irq_desc[irq].handler = &ioapic_level_irq_type; + } else { + irq_desc[irq].handler = &ioapic_edge_irq_type; + } + + set_intr_gate(entry.vector, interrupt[irq]); + + if (!ioapic && (irq < 16)) + disable_8259A_irq(irq); + + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return 0; +} + +#endif /*CONFIG_ACPI_BOOT*/ diff -urN linux-2.4.21/arch/i386/kernel/mpparse.c linux-2.4.22/arch/i386/kernel/mpparse.c --- linux-2.4.21/arch/i386/kernel/mpparse.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/mpparse.c 2003-08-25 04:44:39.000000000 -0700 @@ -9,12 +9,14 @@ * Erich Boleyn : MP v1.4 and additional changes. * Alan Cox : Added EBDA scanning * Ingo Molnar : various cleanups and rewrites - * Maciej W. Rozycki : Bits for default MP configurations + * Maciej W. Rozycki: Bits for default MP configurations + * Paul Diefenbaugh: Added full ACPI support */ #include #include #include +#include #include #include #include @@ -23,10 +25,12 @@ #include #include +#include #include #include #include #include +#include /* Have we found an MP table */ int smp_found_config; @@ -137,12 +141,6 @@ return n; } -#ifdef CONFIG_X86_IO_APIC -extern int have_acpi_tables; /* set by acpitable.c */ -#else -#define have_acpi_tables (0) -#endif - /* * Have to match translation table entries to main table entries by counter * hence the mpc_record variable .... can't see a less disgusting way of @@ -447,10 +445,11 @@ printk("APIC at: 0x%lX\n",mpc->mpc_lapic); - /* save the local APIC address, it might be non-default, - * but only if we're not using the ACPI tables + /* + * Save the local APIC address (it might be non-default) -- but only + * if we're not using ACPI. */ - if (!have_acpi_tables) + if (!acpi_lapic) mp_lapic_addr = mpc->mpc_lapic; if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && mpc->mpc_oemptr) { @@ -517,7 +516,7 @@ 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); + memset(mp_bus_id_to_pci_bus, -1, max_mp_busses * sizeof(int)); /* * Now process the configuration blocks. @@ -530,9 +529,8 @@ { struct mpc_config_processor *m= (struct mpc_config_processor *)mpt; - - /* ACPI may already have provided this one for us */ - if (!have_acpi_tables) + /* ACPI may have already provided this data */ + if (!acpi_lapic) MP_processor_info(m); mpt += sizeof(*m); count += sizeof(*m); @@ -761,7 +759,6 @@ } static struct intel_mp_floating *mpf_found; -extern void config_acpi_tables(void); /* * Scan the memory blocks for an SMP configuration block. @@ -770,17 +767,19 @@ { struct intel_mp_floating *mpf = mpf_found; -#ifdef CONFIG_X86_IO_APIC /* - * Check if the ACPI tables are provided. Use them only to get - * the processor information, mainly because it provides - * the info on the logical processor(s), rather than the physical - * processor(s) that are provided by the MPS. We attempt to - * check only if the user provided a commandline override + * ACPI may be used to obtain the entire SMP configuration or just to + * enumerate/configure processors (CONFIG_ACPI_HT_ONLY). Note that + * ACPI supports both logical (e.g. Hyper-Threading) and physical + * processors, where MPS only supports physical. */ - config_acpi_tables(); -#endif - + if (acpi_lapic && acpi_ioapic) { + printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n"); + return; + } + else if (acpi_lapic) + printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); + printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); if (mpf->mpf_feature2 & (1<<7)) { printk(" IMCR and PIC compatibility mode.\n"); @@ -939,3 +938,401 @@ #endif } + +/* -------------------------------------------------------------------------- + ACPI-based MP Configuration + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_BOOT + +void __init mp_register_lapic_address ( + u64 address) +{ + mp_lapic_addr = (unsigned long) address; + + set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); + + if (boot_cpu_physical_apicid == -1U) + boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); + + Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); +} + + +void __init mp_register_lapic ( + u8 id, + u8 enabled) +{ + struct mpc_config_processor processor; + int boot_cpu = 0; + + if (id >= MAX_APICS) { + printk(KERN_WARNING "Processor #%d invalid (max %d)\n", + id, MAX_APICS); + return; + } + + if (id == boot_cpu_physical_apicid) + boot_cpu = 1; + + processor.mpc_type = MP_PROCESSOR; + processor.mpc_apicid = id; + processor.mpc_apicver = 0x10; /* TBD: lapic version */ + processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); + processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | + (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; + processor.mpc_reserved[0] = 0; + processor.mpc_reserved[1] = 0; + + MP_processor_info(&processor); +} + +#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) + +#define MP_ISA_BUS 0 +#define MP_MAX_IOAPIC_PIN 127 + +struct mp_ioapic_routing { + int apic_id; + int irq_start; + int irq_end; + u32 pin_programmed[4]; +} mp_ioapic_routing[MAX_IO_APICS]; + + +static int __init mp_find_ioapic ( + int irq) +{ + int i = 0; + + /* Find the IOAPIC that manages this IRQ. */ + for (i = 0; i < nr_ioapics; i++) { + if ((irq >= mp_ioapic_routing[i].irq_start) + && (irq <= mp_ioapic_routing[i].irq_end)) + return i; + } + + printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d/n", irq); + + return -1; +} + + +void __init mp_register_ioapic ( + u8 id, + u32 address, + u32 irq_base) +{ + int idx = 0; + + if (nr_ioapics >= MAX_IO_APICS) { + printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " + "(found %d)\n", MAX_IO_APICS, nr_ioapics); + panic("Recompile kernel with bigger MAX_IO_APICS!\n"); + } + if (!address) { + printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" + " found in MADT table, skipping!\n"); + return; + } + + idx = nr_ioapics++; + + mp_ioapics[idx].mpc_type = MP_IOAPIC; + mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; + mp_ioapics[idx].mpc_apicaddr = address; + + set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); + mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); + mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); + + /* + * Build basic IRQ lookup table to facilitate irq->io_apic lookups + * and to prevent reprogramming of IOAPIC pins (PCI IRQs). + */ + mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid; + mp_ioapic_routing[idx].irq_start = irq_base; + mp_ioapic_routing[idx].irq_end = irq_base + + io_apic_get_redir_entries(idx); + + printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " + "IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, + mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, + mp_ioapic_routing[idx].irq_start, + mp_ioapic_routing[idx].irq_end); + + return; +} + + +void __init mp_override_legacy_irq ( + u8 bus_irq, + u8 polarity, + u8 trigger, + u32 global_irq) +{ + struct mpc_config_intsrc intsrc; + int i = 0; + int found = 0; + int ioapic = -1; + int pin = -1; + + /* + * Convert 'global_irq' to 'ioapic.pin'. + */ + ioapic = mp_find_ioapic(global_irq); + if (ioapic < 0) + return; + pin = global_irq - mp_ioapic_routing[ioapic].irq_start; + + /* + * TBD: This check is for faulty timer entries, where the override + * erroneously sets the trigger to level, resulting in a HUGE + * increase of timer interrupts! + */ + if ((bus_irq == 0) && (global_irq == 2) && (trigger == 3)) + trigger = 1; + + intsrc.mpc_type = MP_INTSRC; + intsrc.mpc_irqtype = mp_INT; + intsrc.mpc_irqflag = (trigger << 2) | polarity; + intsrc.mpc_srcbus = MP_ISA_BUS; + intsrc.mpc_srcbusirq = bus_irq; /* IRQ */ + intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; /* APIC ID */ + intsrc.mpc_dstirq = pin; /* INTIN# */ + + Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", + intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, + (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, + intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq); + + /* + * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it. + * Otherwise create a new entry (e.g. global_irq == 2). + */ + for (i = 0; i < mp_irq_entries; i++) { + if ((mp_irqs[i].mpc_dstapic == intsrc.mpc_dstapic) + && (mp_irqs[i].mpc_dstirq == intsrc.mpc_dstirq)) { + mp_irqs[i] = intsrc; + found = 1; + break; + } + } + if (!found) { + mp_irqs[mp_irq_entries] = intsrc; + if (++mp_irq_entries == MAX_IRQ_SOURCES) + panic("Max # of irq sources exceeded!\n"); + } + + return; +} + + +void __init mp_config_acpi_legacy_irqs (void) +{ + int i = 0; + int ioapic = -1; + + /* + * Initialize mp_irqs for IRQ configuration. + */ + unsigned char *bus_data; + int count; + + count = (MAX_MP_BUSSES * sizeof(int)) * 4; + count += (MAX_IRQ_SOURCES * sizeof(int)) * 4; + bus_data = alloc_bootmem(count); + if (!bus_data) { + panic("Fatal: can't allocate bus memory for ACPI legacy IRQ!"); + } + 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]; + for (i = 0; i < MAX_MP_BUSSES; ++i) + mp_bus_id_to_pci_bus[i] = -1; + + /* + * Fabricate the legacy ISA bus (bus #31). + */ + mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; + Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); + + /* + * Locate the IOAPIC that manages the ISA IRQs (0-15). + */ + ioapic = mp_find_ioapic(0); + if (ioapic < 0) + return; + + /* + * Use the default configuration for the IRQs 0-15. These may be + * overriden by (MADT) interrupt source override entries. + */ + for (i = 0; i < 16; i++) { + + if (i == 2) continue; /* Don't connect IRQ2 */ + + mp_irqs[mp_irq_entries].mpc_type = MP_INTSRC; + mp_irqs[mp_irq_entries].mpc_irqflag = 0; /* Conforming */ + mp_irqs[mp_irq_entries].mpc_srcbus = MP_ISA_BUS; + mp_irqs[mp_irq_entries].mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; + mp_irqs[mp_irq_entries].mpc_irqtype = i ? mp_INT : mp_ExtINT; /* 8259A to #0 */ + mp_irqs[mp_irq_entries].mpc_srcbusirq = i; /* Identity mapped */ + mp_irqs[mp_irq_entries].mpc_dstirq = i; + + Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, " + "%d-%d\n", + mp_irqs[mp_irq_entries].mpc_irqtype, + mp_irqs[mp_irq_entries].mpc_irqflag & 3, + (mp_irqs[mp_irq_entries].mpc_irqflag >> 2) & 3, + mp_irqs[mp_irq_entries].mpc_srcbus, + mp_irqs[mp_irq_entries].mpc_srcbusirq, + mp_irqs[mp_irq_entries].mpc_dstapic, + mp_irqs[mp_irq_entries].mpc_dstirq); + + if (++mp_irq_entries == MAX_IRQ_SOURCES) + panic("Max # of irq sources exceeded!\n"); + } +} + +/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */ + +extern FADT_DESCRIPTOR acpi_fadt; + +void __init mp_config_ioapic_for_sci(int irq) +{ + int ioapic; + int ioapic_pin; + struct acpi_table_madt* madt; + struct acpi_table_int_src_ovr *entry = NULL; + void *madt_end; + acpi_status status; + + /* + * Ensure that if there is an interrupt source override entry + * for the ACPI SCI, we leave it as is. Unfortunately this involves + * walking the MADT again. + */ + status = acpi_get_firmware_table("APIC", 1, ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) &madt); + if (ACPI_SUCCESS(status)) { + madt_end = (void *) (unsigned long)madt + madt->header.length; + + entry = (struct acpi_table_int_src_ovr *) + ((unsigned long) madt + sizeof(struct acpi_table_madt)); + + while ((void *) entry < madt_end) { + if (entry->header.type == ACPI_MADT_INT_SRC_OVR && + acpi_fadt.sci_int == entry->bus_irq) { + /* + * See the note at the end of ACPI 2.0b section + * 5.2.10.8 for what this is about. + */ + if (entry->bus_irq != entry->global_irq) { + acpi_fadt.sci_int = entry->global_irq; + irq = entry->global_irq; + break; + } + else + return; + } + + entry = (struct acpi_table_int_src_ovr *) + ((unsigned long) entry + entry->header.length); + } + } + + ioapic = mp_find_ioapic(irq); + + ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; + + io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered +} + + +#ifdef CONFIG_ACPI_PCI + +void __init mp_parse_prt (void) +{ + struct list_head *node = NULL; + struct acpi_prt_entry *entry = NULL; + int ioapic = -1; + int ioapic_pin = 0; + int irq = 0; + int idx, bit = 0; + int edge_level = 0; + int active_high_low = 0; + + /* + * Parsing through the PCI Interrupt Routing Table (PRT) and program + * routing for all entries. + */ + list_for_each(node, &acpi_prt.entries) { + entry = list_entry(node, struct acpi_prt_entry, node); + + /* Need to get irq for dynamic entry */ + if (entry->link.handle) { + irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); + if (!irq) + continue; + } + else { + /* Hardwired IRQ. Assume PCI standard settings */ + irq = entry->link.index; + edge_level = 1; + active_high_low = 1; + } + + /* Don't set up the ACPI SCI because it's already set up */ + if (acpi_fadt.sci_int == irq) + continue; + + ioapic = mp_find_ioapic(irq); + if (ioapic < 0) + continue; + ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; + + /* + * Avoid pin reprogramming. PRTs typically include entries + * with redundant pin->irq mappings (but unique PCI devices); + * we only only program the IOAPIC on the first. + */ + bit = ioapic_pin % 32; + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); + if (idx > 3) { + printk(KERN_ERR "Invalid reference to IOAPIC pin " + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, + ioapic_pin); + continue; + } + if ((1<irq = irq; + continue; + } + + mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq = irq; + + printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", + entry->id.segment, entry->id.bus, + entry->id.device, ('A' + entry->pin), + mp_ioapic_routing[ioapic].apic_id, ioapic_pin, + entry->irq); + } + + return; +} + +#endif /*CONFIG_ACPI_PCI*/ + +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ + +#endif /*CONFIG_ACPI*/ diff -urN linux-2.4.21/arch/i386/kernel/pci-irq.c linux-2.4.22/arch/i386/kernel/pci-irq.c --- linux-2.4.21/arch/i386/kernel/pci-irq.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/pci-irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -116,7 +116,7 @@ * Code for querying and setting of IRQ routes on various interrupt routers. */ -static void eisa_set_level_irq(unsigned int irq) +void eisa_set_level_irq(unsigned int irq) { unsigned char mask = 1 << (irq & 7); unsigned int port = 0x4d0 + (irq >> 3); @@ -196,15 +196,16 @@ /* * The VIA pirq rules are nibble-based, like ALI, * but without the ugly irq number munging. + * However, PIRQD is in the upper instead of lower nibble. */ static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - return read_config_nybble(router, 0x55, pirq); + return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq); } static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - write_config_nybble(router, 0x55, pirq, irq); + write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq); return 1; } @@ -472,6 +473,8 @@ { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, pirq_piix_get, pirq_piix_set }, { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, pirq_piix_get, pirq_piix_set }, { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, pirq_piix_get, pirq_piix_set }, + { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, pirq_piix_get, pirq_piix_set }, + { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_0, pirq_piix_get, pirq_piix_set }, { "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set }, diff -urN linux-2.4.21/arch/i386/kernel/pci-pc.c linux-2.4.22/arch/i386/kernel/pci-pc.c --- linux-2.4.21/arch/i386/kernel/pci-pc.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/i386/kernel/pci-pc.c 2003-08-25 04:44:39.000000000 -0700 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,8 @@ int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL; int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL; +static int pci_using_acpi_prt = 0; + #ifdef CONFIG_MULTIQUAD #define BUS2QUAD(global) (mp_bus_id_to_node[global]) #define BUS2LOCAL(global) (mp_bus_id_to_local[global]) @@ -1353,6 +1356,23 @@ pci_read_bridge_bases(b); } +struct pci_bus * __devinit pcibios_scan_root(int busnum) +{ + struct list_head *list; + struct pci_bus *bus; + + list_for_each(list, &pci_root_buses) { + bus = pci_bus_b(list); + if (bus->number == busnum) { + /* Already scanned */ + return bus; + } + } + + printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); + + return pci_scan_bus(busnum, pci_root_ops, NULL); +} void __devinit pcibios_config_init(void) { @@ -1394,6 +1414,8 @@ return; } +int use_acpi_pci __initdata = 1; + void __init pcibios_init(void) { int quad; @@ -1406,7 +1428,19 @@ } printk(KERN_INFO "PCI: Probing PCI hardware\n"); - pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL); +#ifdef CONFIG_ACPI_PCI + if (use_acpi_pci && !acpi_pci_irq_init()) { + pci_using_acpi_prt = 1; + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); + printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi' or even 'acpi=off'\n"); + } +#endif + if (!pci_using_acpi_prt) { + pci_root_bus = pcibios_scan_root(0); + pcibios_irq_init(); + pcibios_fixup_peer_bridges(); + pcibios_fixup_irqs(); + } if (clustered_apic_mode && (numnodes > 1)) { for (quad = 1; quad < numnodes; ++quad) { printk("Scanning PCI bus %d for quad %d\n", @@ -1416,9 +1450,6 @@ } } - pcibios_irq_init(); - pcibios_fixup_peer_bridges(); - pcibios_fixup_irqs(); pcibios_resource_survey(); #ifdef CONFIG_PCI_BIOS @@ -1470,6 +1501,9 @@ } else if (!strncmp(str, "lastbus=", 8)) { pcibios_last_bus = simple_strtol(str+8, NULL, 0); return NULL; + } else if (!strncmp(str, "noacpi", 6)) { + use_acpi_pci = 0; + return NULL; } return str; } @@ -1485,6 +1519,15 @@ if ((err = pcibios_enable_resources(dev, mask)) < 0) return err; + +#ifdef CONFIG_ACPI_PCI + if (pci_using_acpi_prt) { + acpi_pci_irq_enable(dev); + return 0; + } +#endif + pcibios_enable_irq(dev); + return 0; } diff -urN linux-2.4.21/arch/i386/kernel/process.c linux-2.4.22/arch/i386/kernel/process.c --- linux-2.4.21/arch/i386/kernel/process.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/process.c 2003-08-25 04:44:39.000000000 -0700 @@ -253,7 +253,7 @@ 0x66, 0x0f, 0x20, 0xc3, /* movl %cr0,%ebx */ 0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60, /* andl $0x60000000,%ebx */ 0x74, 0x02, /* jz f */ - 0x0f, 0x08, /* invd */ + 0x0f, 0x09, /* wbinvd */ 0x24, 0x10, /* f: andb $0x10,al */ 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */ }; diff -urN linux-2.4.21/arch/i386/kernel/setup.c linux-2.4.22/arch/i386/kernel/setup.c --- linux-2.4.21/arch/i386/kernel/setup.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -95,6 +95,7 @@ #include #include #include +#include #include #ifdef CONFIG_BLK_DEV_RAM #include @@ -106,6 +107,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +128,7 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; unsigned long mmu_cr4_features; +EXPORT_SYMBOL(mmu_cr4_features); /* * Bus types .. @@ -170,11 +173,23 @@ static int have_cpuid_p(void) __init; static int disable_x86_serial_nr __initdata = 1; -static int disable_x86_ht __initdata = 0; static u32 disabled_x86_caps[NCAPINTS] __initdata = { 0 }; -extern int blk_nohighio; -int enable_acpi_smp_table; +#ifdef CONFIG_ACPI_INTERPRETER + int acpi_disabled __initdata = 0; +#else + int acpi_disabled __initdata = 1; +#endif +EXPORT_SYMBOL(acpi_disabled); + +#ifdef CONFIG_ACPI_BOOT + int acpi_ht __initdata = 1; /* enable HT */ +#endif + + +int acpi_force __initdata = 0; + +extern int blk_nohighio; /* * This is set up by the setup-routine at boot-time @@ -782,6 +797,12 @@ if (*from == '@') { start_at = memparse(from+1, &from); add_memory_region(start_at, mem_size, E820_RAM); + } else if (*from == '#') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_ACPI); + } else if (*from == '$') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_RESERVED); } else { limit_regions(mem_size); userdef=1; @@ -789,16 +810,30 @@ } } - /* "noht" disables HyperThreading (2 logical cpus per Xeon) */ - else if (!memcmp(from, "noht", 4)) { - disable_x86_ht = 1; - set_bit(X86_FEATURE_HT, disabled_x86_caps); - } - - /* "acpismp=force" forces parsing and use of the ACPI SMP table */ - else if (!memcmp(from, "acpismp=force", 13)) - enable_acpi_smp_table = 1; - +#ifdef CONFIG_ACPI_BOOT + /* "acpi=off" disables both ACPI table parsing and interpreter */ + else if (!memcmp(from, "acpi=off", 8)) { + acpi_ht = 0; + acpi_disabled = 1; + } + + /* acpi=force to over-ride black-list */ + else if (!memcmp(from, "acpi=force", 10)) { + acpi_force = 1; + acpi_ht=1; + acpi_disabled = 0; + } + + /* Limit ACPI to boot-time only, still enabled HT */ + else if (!memcmp(from, "acpi=ht", 7)) { + acpi_ht = 1; + if (!acpi_force) acpi_disabled = 1; + } + + /* disable IO-APIC */ + else if (!memcmp(from, "noapic", 6)) + disable_ioapic_setup(); +#endif /* * highmem=size forces highmem to be exactly 'size' bytes. * This works even on boxes that have no highmem otherwise. @@ -1007,10 +1042,15 @@ */ reserve_bootmem(PAGE_SIZE, PAGE_SIZE); #endif - +#ifdef CONFIG_ACPI_SLEEP + /* + * Reserve low memory region for sleep support. + */ + acpi_reserve_bootmem(); +#endif #ifdef CONFIG_X86_LOCAL_APIC /* - * Find and reserve possible boot-time SMP configuration: + * Find and reserve possible boot-time SMP configuration. */ find_smp_config(); #endif @@ -1043,7 +1083,6 @@ { unsigned long low_mem_size; int i; - probe_roms(); for (i = 0; i < e820.nr_map; i++) { struct resource *res; @@ -1130,22 +1169,6 @@ max_low_pfn = setup_memory(); /* - * If enable_acpi_smp_table and HT feature present, acpitable.c - * will find all logical cpus despite disable_x86_ht: so if both - * "noht" and "acpismp=force" are specified, let "noht" override - * "acpismp=force" cleanly. Why retain "acpismp=force"? because - * parsing ACPI SMP table might prove useful on some non-HT cpu. - */ - if (disable_x86_ht) { - clear_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]); - set_bit(X86_FEATURE_HT, disabled_x86_caps); - enable_acpi_smp_table = 0; - } - 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. */ @@ -1154,6 +1177,14 @@ smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ #endif paging_init(); + + dmi_scan_machine(); + + /* + * Parse the ACPI tables for possible boot-time SMP configuration. + */ + acpi_boot_init(); + #ifdef CONFIG_X86_LOCAL_APIC /* * get boot-time SMP configuration: @@ -1171,7 +1202,6 @@ conswitchp = &dummy_con; #endif #endif - dmi_scan_machine(); } static int cachesize_override __initdata = -1; @@ -2387,7 +2417,7 @@ strcpy(c->x86_model_id, p); #ifdef CONFIG_SMP - if (test_bit(X86_FEATURE_HT, &c->x86_capability) && !disable_x86_ht) { + if (test_bit(X86_FEATURE_HT, &c->x86_capability)) { extern int phys_proc_id[NR_CPUS]; u32 eax, ebx, ecx, edx; diff -urN linux-2.4.21/arch/i386/kernel/smpboot.c linux-2.4.22/arch/i386/kernel/smpboot.c --- linux-2.4.21/arch/i386/kernel/smpboot.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/smpboot.c 2003-08-25 04:44:39.000000000 -0700 @@ -1034,7 +1034,7 @@ * If we couldnt find an SMP configuration at boot time, * get out of here now! */ - if (!smp_found_config) { + if (!smp_found_config && !acpi_lapic) { printk(KERN_NOTICE "SMP motherboard not detected.\n"); #ifndef CONFIG_VISWS io_apic_irqs = 0; diff -urN linux-2.4.21/arch/i386/kernel/sys_i386.c linux-2.4.22/arch/i386/kernel/sys_i386.c --- linux-2.4.21/arch/i386/kernel/sys_i386.c 2001-03-19 12:35:09.000000000 -0800 +++ linux-2.4.22/arch/i386/kernel/sys_i386.c 2003-08-25 04:44:39.000000000 -0700 @@ -139,7 +139,10 @@ switch (call) { case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); + return sys_semtimedop (first, (struct sembuf *)ptr, second, NULL); + case SEMTIMEDOP: + return sys_semtimedop (first, (struct sembuf *)ptr, second, + (const struct timespec *)fifth); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { @@ -200,7 +203,7 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } diff -urN linux-2.4.21/arch/i386/kernel/vm86.c linux-2.4.22/arch/i386/kernel/vm86.c --- linux-2.4.21/arch/i386/kernel/vm86.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/i386/kernel/vm86.c 2003-08-25 04:44:39.000000000 -0700 @@ -362,6 +362,9 @@ if (VEFLAGS & VIF_MASK) flags |= IF_MASK; + else + flags &= ~IF_MASK; + flags |= IOPL_MASK; return flags | (VEFLAGS & current->thread.v86mask); } diff -urN linux-2.4.21/arch/i386/math-emu/fpu_trig.c linux-2.4.22/arch/i386/math-emu/fpu_trig.c --- linux-2.4.21/arch/i386/math-emu/fpu_trig.c 2001-06-12 11:06:54.000000000 -0700 +++ linux-2.4.22/arch/i386/math-emu/fpu_trig.c 2003-08-25 04:44:39.000000000 -0700 @@ -1058,7 +1058,7 @@ return; goto fprem_valid; } - else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) ) + else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) ) { FPU_stack_underflow(); return; diff -urN linux-2.4.21/arch/i386/math-emu/poly.h linux-2.4.22/arch/i386/math-emu/poly.h --- linux-2.4.21/arch/i386/math-emu/poly.h 2001-07-26 13:37:38.000000000 -0700 +++ linux-2.4.22/arch/i386/math-emu/poly.h 2003-08-25 04:44:39.000000000 -0700 @@ -64,7 +64,7 @@ const unsigned long arg2) { int retval; - asm volatile ("mull %2; movl %%edx,%%eax" \ + asm volatile ("mull %2; movl %%edx,%%eax; " \ :"=a" (retval) \ :"0" (arg1), "g" (arg2) \ :"dx"); @@ -75,11 +75,11 @@ /* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */ static inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2) { - asm volatile ("movl %1,%%edi; movl %2,%%esi; - movl (%%esi),%%eax; addl %%eax,(%%edi); - movl 4(%%esi),%%eax; adcl %%eax,4(%%edi); - movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);" - :"=g" (*dest):"g" (dest), "g" (x2) + asm volatile ("movl %1,%%edi; movl %2,%%esi; " \ + "movl (%%esi),%%eax; addl %%eax,(%%edi); " \ + "movl 4(%%esi),%%eax; adcl %%eax,4(%%edi); " \ + "movl 8(%%esi),%%eax; adcl %%eax,8(%%edi); " \ + :"=g" (*dest):"g" (dest), "g" (x2) \ :"ax","si","di"); } @@ -90,19 +90,19 @@ problem, but keep fingers crossed! */ static inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp) { - asm volatile ("movl %2,%%ecx; movl %3,%%esi; - movl (%%esi),%%eax; addl %%eax,(%%ecx); - movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx); - movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx); - jnc 0f; - rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx) - movl %4,%%ecx; incl (%%ecx) - movl $1,%%eax; jmp 1f; - 0: xorl %%eax,%%eax; - 1:" - :"=g" (*exp), "=g" (*dest) - :"g" (dest), "g" (x2), "g" (exp) - :"cx","si","ax"); + asm volatile ("movl %2,%%ecx; movl %3,%%esi; " \ + "movl (%%esi),%%eax; addl %%eax,(%%ecx); " \ + "movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx); " \ + "movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx); " \ + "jnc 0f; " \ + "rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx); " \ + "movl %4,%%ecx; incl (%%ecx); " \ + "movl $1,%%eax; jmp 1f; " \ + "0: xorl %%eax,%%eax; " \ + "1: " \ + :"=g" (*exp), "=g" (*dest) \ + :"g" (dest), "g" (x2), "g" (exp) \ + :"cx","si","ax"); } @@ -110,11 +110,11 @@ /* This is faster in a loop on my 386 than using the "neg" instruction. */ static inline void negate_Xsig(Xsig *x) { - asm volatile("movl %1,%%esi; " - "xorl %%ecx,%%ecx; " - "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); " - "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); " - "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); " + asm volatile("movl %1,%%esi; " \ + "xorl %%ecx,%%ecx; " \ + "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); " \ + "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); " \ + "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); " \ :"=g" (*x):"g" (x):"si","ax","cx"); } diff -urN linux-2.4.21/arch/ia64/Makefile linux-2.4.22/arch/ia64/Makefile --- linux-2.4.21/arch/ia64/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -132,6 +132,9 @@ archclean: @$(MAKEBOOT) clean +check: vmlinux + arch/ia64/scripts/unwcheck.sh vmlinux + archmrproper: rm -f arch/$(ARCH)/vmlinux.lds @$(MAKE) -C arch/$(ARCH)/tools mrproper diff -urN linux-2.4.21/arch/ia64/config.in linux-2.4.22/arch/ia64/config.in --- linux-2.4.21/arch/ia64/config.in 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/config.in 2003-08-25 04:44:39.000000000 -0700 @@ -23,8 +23,8 @@ define_bool CONFIG_EISA n define_bool CONFIG_MCA n define_bool CONFIG_SBUS n -define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y -define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n +define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y choice 'IA-64 processor type' \ "Itanium CONFIG_ITANIUM \ @@ -179,7 +179,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -242,6 +242,7 @@ source drivers/usb/Config.in + source crypto/Config.in source lib/Config.in if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then diff -urN linux-2.4.21/arch/ia64/configs/dig linux-2.4.22/arch/ia64/configs/dig --- linux-2.4.21/arch/ia64/configs/dig 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/configs/dig 2003-08-25 04:44:39.000000000 -0700 @@ -22,8 +22,8 @@ # CONFIG_EISA is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ITANIUM=y # CONFIG_MCKINLEY is not set # CONFIG_IA64_GENERIC is not set @@ -41,6 +41,14 @@ CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_HUGETLB_PAGE_SIZE_16MB=y +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_SMP=y CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y @@ -243,7 +251,7 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set @@ -257,7 +265,6 @@ # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -322,6 +329,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set @@ -623,6 +631,7 @@ # # Video Adapters # +# CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5249 is not set @@ -672,6 +681,7 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -874,6 +884,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # diff -urN linux-2.4.21/arch/ia64/configs/generic linux-2.4.22/arch/ia64/configs/generic --- linux-2.4.21/arch/ia64/configs/generic 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/configs/generic 2003-08-25 04:44:39.000000000 -0700 @@ -22,8 +22,8 @@ # CONFIG_EISA is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ITANIUM=y # CONFIG_MCKINLEY is not set CONFIG_IA64_GENERIC=y @@ -41,6 +41,14 @@ CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_HUGETLB_PAGE_SIZE_16MB=y +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_SMP=y CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y @@ -243,13 +251,13 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set -# CONFIG_BLK_DEV_CMD64X is not set +CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set @@ -257,7 +265,6 @@ # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -322,6 +329,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set @@ -628,6 +636,7 @@ # # Video Adapters # +# CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5249 is not set @@ -677,6 +686,7 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -879,6 +889,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # diff -urN linux-2.4.21/arch/ia64/configs/ski linux-2.4.22/arch/ia64/configs/ski --- linux-2.4.21/arch/ia64/configs/ski 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/configs/ski 2003-08-25 04:44:39.000000000 -0700 @@ -22,8 +22,8 @@ # CONFIG_EISA is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ITANIUM=y # CONFIG_MCKINLEY is not set # CONFIG_IA64_GENERIC is not set @@ -39,6 +39,14 @@ # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set CONFIG_IA64_L1_CACHE_SHIFT=6 CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_HUGETLB_PAGE_SIZE_16MB=y +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_SMP=y CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y @@ -149,6 +157,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set @@ -274,6 +283,7 @@ # # Video Adapters # +# CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_BWQCAM is not set # CONFIG_VIDEO_CQCAM is not set @@ -326,6 +336,7 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set diff -urN linux-2.4.21/arch/ia64/configs/zx1 linux-2.4.22/arch/ia64/configs/zx1 --- linux-2.4.21/arch/ia64/configs/zx1 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/configs/zx1 2003-08-25 04:44:39.000000000 -0700 @@ -22,8 +22,8 @@ # CONFIG_EISA is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ITANIUM is not set CONFIG_MCKINLEY=y # CONFIG_IA64_GENERIC is not set @@ -40,6 +40,16 @@ CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLB_PAGE_SIZE_4GB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1GB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_HUGETLB_PAGE_SIZE_16MB=y +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_SMP=y CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y @@ -242,7 +252,7 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set @@ -256,7 +266,6 @@ # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -321,6 +330,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set @@ -622,6 +632,7 @@ # # Video Adapters # +# CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5249 is not set @@ -671,6 +682,7 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -873,6 +885,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # diff -urN linux-2.4.21/arch/ia64/defconfig linux-2.4.22/arch/ia64/defconfig --- linux-2.4.21/arch/ia64/defconfig 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/defconfig 2003-08-25 04:44:39.000000000 -0700 @@ -22,8 +22,8 @@ # CONFIG_EISA is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ITANIUM=y # CONFIG_MCKINLEY is not set CONFIG_IA64_GENERIC=y @@ -41,6 +41,14 @@ CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_KCORE_ELF=y +CONFIG_FORCE_MAX_ZONEORDER=19 +CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_HUGETLB_PAGE_SIZE_16MB=y +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_SMP=y CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y @@ -243,13 +251,13 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set -# CONFIG_BLK_DEV_CMD64X is not set +CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set @@ -257,7 +265,6 @@ # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -322,6 +329,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set @@ -628,6 +636,7 @@ # # Video Adapters # +# CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5249 is not set @@ -677,6 +686,7 @@ # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set CONFIG_RAMFS=y +CONFIG_HUGETLBFS=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -879,6 +889,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # diff -urN linux-2.4.21/arch/ia64/dig/machvec.c linux-2.4.22/arch/ia64/dig/machvec.c --- linux-2.4.21/arch/ia64/dig/machvec.c 2000-08-11 19:09:06.000000000 -0700 +++ linux-2.4.22/arch/ia64/dig/machvec.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,2 +1,3 @@ -#define MACHVEC_PLATFORM_NAME dig +#define MACHVEC_PLATFORM_NAME dig +#define MACHVEC_PLATFORM_HEADER #include diff -urN linux-2.4.21/arch/ia64/dig/setup.c linux-2.4.22/arch/ia64/dig/setup.c --- linux-2.4.21/arch/ia64/dig/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/dig/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ * * Copyright (C) 1999 Intel Corp. * Copyright (C) 1999, 2001 Hewlett-Packard Co - * Copyright (C) 1999, 2001 David Mosberger-Tang + * Copyright (C) 1999, 2001, 2003 David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond * Copyright (C) 1999 Vijay Chander @@ -56,7 +56,7 @@ if (!ia64_boot_param->console_info.num_rows || !ia64_boot_param->console_info.num_cols) { - printk("dig_setup: warning: invalid screen-info, guessing 80x25\n"); + printk(KERN_WARNING "dig_setup: warning: invalid screen-info, guessing 80x25\n"); orig_x = 0; orig_y = 0; num_cols = 80; diff -urN linux-2.4.21/arch/ia64/hp/common/sba_iommu.c linux-2.4.22/arch/ia64/hp/common/sba_iommu.c --- linux-2.4.21/arch/ia64/hp/common/sba_iommu.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/hp/common/sba_iommu.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,8 +1,9 @@ /* ** IA64 System Bus Adapter (SBA) I/O MMU manager ** -** (c) Copyright 2002 Alex Williamson -** (c) Copyright 2002 Hewlett-Packard Company +** (c) Copyright 2002-2003 Alex Williamson +** (c) Copyright 2002-2003 Grant Grundler +** (c) Copyright 2002-2003 Hewlett-Packard Company ** ** Portions (c) 2000 Grant Grundler (from parisc I/O MMU code) ** Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code) @@ -29,12 +30,14 @@ #include #include #include +#include #include #include #include /* ia64_get_itc() */ #include #include /* PAGE_OFFSET */ +#include /* wmb() */ #define PFX "IOC: " @@ -206,7 +209,7 @@ /* Stuff we don't need in performance path */ struct ioc *next; /* list of IOC's in system */ acpi_handle handle; /* for multiple IOC's */ - const char *name; + char *name; unsigned int func_id; unsigned int rev; /* HW revision of chip */ u32 iov_size; @@ -217,11 +220,15 @@ static struct ioc *ioc_list; static int reserve_sba_gart = 1; -#define sba_sg_address(sg) (sg->address ? sg->address : \ - page_address((sg)->page) + (sg)->offset) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#define sba_sg_address(sg) (page_address((sg)->page) + (sg)->offset) +#else +#define sba_sg_address(sg) ((sg)->address ? (sg)->address : \ + page_address((sg)->page) + (sg)->offset) +#endif #ifdef FULL_VALID_PDIR -static void* prefetch_spill_page; +static u64 prefetch_spill_page; #endif #define GET_IOC(dev) ((struct ioc *) PCI_CONTROLLER(dev)->iommu) @@ -282,24 +289,23 @@ sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide) { /* start printing from lowest pde in rval */ - u64 *ptr = &(ioc->pdir_base[pide & ~(BITS_PER_LONG - 1)]); - unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]); + u64 *ptr = &ioc->pdir_base[pide & ~(BITS_PER_LONG - 1)]; + unsigned long *rptr = (unsigned long *) &ioc->res_map[(pide >>3) & -sizeof(unsigned long)]; uint rcnt; - /* printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", */ - printk("SBA: %s rp %p bit %d rval 0x%lx\n", + printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", msg, rptr, pide & (BITS_PER_LONG - 1), *rptr); rcnt = 0; while (rcnt < BITS_PER_LONG) { - printk("%s %2d %p %016Lx\n", - (rcnt == (pide & (BITS_PER_LONG - 1))) - ? " -->" : " ", - rcnt, ptr, *ptr ); + printk(KERN_DEBUG "%s %2d %p %016Lx\n", + (rcnt == (pide & (BITS_PER_LONG - 1))) + ? " -->" : " ", + rcnt, ptr, (unsigned long long) *ptr ); rcnt++; ptr++; } - printk("%s", msg); + printk(KERN_DEBUG "%s", msg); } @@ -361,12 +367,13 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) { while (nents-- > 0) { - printk(" %d : %08lx/%05x %p\n", - nents, startsg->dma_address, - startsg->dma_length, sba_sg_address(startsg)); + printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents, + startsg->dma_address, startsg->dma_length, + sba_sg_address(startsg)); startsg++; } } + static void sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) { @@ -397,7 +404,8 @@ #define PAGES_PER_RANGE 1 /* could increase this to 4 or 8 if needed */ /* Convert from IOVP to IOVA and vice versa. */ -#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset) | ((hint_reg)<<(ioc->hint_shift_pdir))) +#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset) | \ + ((hint_reg)<<(ioc->hint_shift_pdir))) #define SBA_IOVP(ioc,iova) (((iova) & ioc->hint_mask_pdir) & ~(ioc->ibase)) /* FIXME : review these macros to verify correctness and usage */ @@ -520,7 +528,8 @@ if (pide >= (ioc->res_size << 3)) { pide = sba_search_bitmap(ioc, pages_needed); if (pide >= (ioc->res_size << 3)) - panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa); + panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", + ioc->ioc_hpa); } #ifdef ASSERT_PDIR_SANITY @@ -625,7 +634,8 @@ */ #if 1 -#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x8000000000000000ULL) +#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) \ + | 0x8000000000000000ULL) #else void SBA_INLINE sba_io_pdir_entry(u64 *pdir_ptr, unsigned long vba) @@ -709,7 +719,7 @@ ** the spill page so devices prefetching won't ** cause a hard fail. */ - ioc->pdir_base[off] = (0x80000000000000FFULL | (u64)prefetch_spill_page); + ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page); #endif } else { u32 t = get_order(byte_cnt) + PAGE_SHIFT; @@ -724,7 +734,7 @@ /* clear I/O Pdir entry "valid" bit first */ ioc->pdir_base[off] &= ~(0x80000000000000FFULL); #else - ioc->pdir_base[off] = (0x80000000000000FFULL | (u64)prefetch_spill_page); + ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page); #endif off++; byte_cnt -= IOVP_SIZE; @@ -747,7 +757,7 @@ sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction) { struct ioc *ioc; - unsigned long flags; + unsigned long flags; dma_addr_t iovp; dma_addr_t offset; u64 *pdir_start; @@ -816,6 +826,9 @@ size -= IOVP_SIZE; pdir_start++; } + /* force pdir update */ + wmb(); + /* form complete address */ #ifdef ASSERT_PDIR_SANITY sba_check_pdir(ioc,"Check after sba_map_single()"); @@ -840,7 +853,7 @@ #if DELAYED_RESOURCE_CNT > 0 struct sba_dma_pair *d; #endif - unsigned long flags; + unsigned long flags; dma_addr_t offset; ioc = GET_IOC(dev); @@ -932,7 +945,7 @@ ** we don't need the syncdma. The issue here is I/O MMU cachelines ** are *not* coherent in all cases. May be hwrev dependent. ** Need to investigate more. - asm volatile("syncdma"); + asm volatile("syncdma"); */ } @@ -1078,6 +1091,9 @@ } startsg++; } + /* force pdir update */ + wmb(); + #ifdef DEBUG_LARGE_SG_ENTRIES dump_run_sg = 0; #endif @@ -1122,7 +1138,7 @@ int n_mappings = 0; while (nents > 0) { - unsigned long vaddr = (unsigned long) sba_sg_address(startsg); + unsigned long vaddr = (unsigned long) sba_sg_address(startsg); /* ** Prepare for first/next DMA stream @@ -1155,7 +1171,8 @@ ** exceed DMA_CHUNK_SIZE if we coalesce the ** next entry. */ - if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE) + if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) + > DMA_CHUNK_SIZE) break; /* @@ -1214,7 +1231,7 @@ vcontig_sg->dma_length = vcontig_len; dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK; ASSERT(dma_len <= DMA_CHUNK_SIZE); - dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG + dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG | (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT) | dma_offset); n_mappings++; @@ -1233,8 +1250,7 @@ * * See Documentation/DMA-mapping.txt */ -int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, - int direction) +int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction) { struct ioc *ioc; int coalesced, filled = 0; @@ -1299,13 +1315,13 @@ ** Access to the virtual address is what forces a two pass algorithm. */ coalesced = sba_coalesce_chunks(ioc, sglist, nents); - + /* ** Program the I/O Pdir ** ** map the virtual addresses to the I/O Pdir ** o dma_address will contain the pdir index - ** o dma_len will contain the number of bytes to map + ** o dma_len will contain the number of bytes to map ** o address contains the virtual address. */ filled = sba_fill_pdir(ioc, sglist, nents); @@ -1371,7 +1387,8 @@ ** were coalesced to a single entry. The stats are fun, ** but speed is more important. */ - ioc->usg_pages += ((sglist->dma_address & ~IOVP_MASK) + sglist->dma_length + IOVP_SIZE - 1) >> PAGE_SHIFT; + ioc->usg_pages += ((sglist->dma_address & ~IOVP_MASK) + sglist->dma_length + + IOVP_SIZE - 1) >> PAGE_SHIFT; #endif sglist++; nents--; @@ -1387,12 +1404,6 @@ } -int -sba_dma_supported (struct pci_dev *dev, u64 mask) -{ - return 1; -} - /************************************************************** * * Initialization and claim @@ -1418,19 +1429,6 @@ ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1UL; ioc->iov_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1; - if (ioc->ibase == 0) { - if (((unsigned long) ioc->ioc_hpa & 0x3000UL) == 0x2000) - ioc->ibase = 0xc0000000; - else - ioc->ibase = 0x80000000; - printk("WARNING: IBASE is zero; setting to 0x%lx\n", ioc->ibase); - } - - if (ioc->ibase < 0xfed00000UL && ioc->ibase + ioc->iov_size >= 0xfee00000UL) { - printk("WARNING: IOV space overlaps local config and interrupt message, truncating\n"); - ioc->iov_size /= 2; - } - /* ** iov_order is always based on a 1GB IOVA space since we want to ** turn on the other half for AGP GART. @@ -1438,9 +1436,9 @@ iov_order = get_order(ioc->iov_size >> (IOVP_SHIFT - PAGE_SHIFT)); ioc->pdir_size = (ioc->iov_size / IOVP_SIZE) * sizeof(u64); - DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits) PDIR size 0x%0x\n", - __FUNCTION__, ioc->ioc_hpa, ioc->iov_size >> 20, - iov_order + PAGE_SHIFT, ioc->pdir_size); + DBG_INIT("%s() hpa %p IOV %dMB (%d bits) PDIR size 0x%x\n", + __FUNCTION__, ioc->ioc_hpa, ioc->iov_size >> 20, + iov_order + PAGE_SHIFT, ioc->pdir_size); /* FIXME : DMA HINTs not used */ ioc->hint_shift_pdir = iov_order + PAGE_SHIFT; @@ -1520,7 +1518,8 @@ agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP); if (agp_found && reserve_sba_gart) { - DBG_INIT("%s: AGP device found, reserving half of IOVA for GART support\n", __FUNCTION__); + DBG_INIT("%s: AGP device found, reserving half of IOVA for GART support\n", + __FUNCTION__); ioc->pdir_size /= 2; ((u64 *)ioc->pdir_base)[PDIR_INDEX(ioc->iov_size/2)] = ZX1_SBA_IOMMU_COOKIE; } @@ -1532,26 +1531,27 @@ if (!prefetch_spill_page) { char *spill_poison = "SBAIOMMU POISON"; int poison_size = 16; - void *poison_addr; - - prefetch_spill_page = (void *)__get_free_pages(GFP_KERNEL, get_order(IOVP_SIZE)); - if (!prefetch_spill_page) + void *poison_addr, *addr; + + addr = (void *)__get_free_pages(GFP_KERNEL, get_order(IOVP_SIZE)); + if (!addr) panic(PFX "Couldn't allocate PDIR spill page\n"); - poison_addr = prefetch_spill_page; - for (; (u64)poison_addr < (u64)prefetch_spill_page + IOVP_SIZE ; poison_addr += poison_size) - (void)memcpy(poison_addr,spill_poison,poison_size); + poison_addr = addr; + for ( ; (u64) poison_addr < addr + IOVP_SIZE; poison_addr += poison_size) + memcpy(poison_addr, spill_poison, poison_size); - prefetch_spill_page = (void *)virt_to_phys(prefetch_spill_page); + prefetch_spill_page = virt_to_phys(addr); - DBG_INIT("%s() prefetch spill addr: %p\n", __FUNCTION__, prefetch_spill_page); + DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __FUNCTION__, prefetch_spill_page); } /* ** Set all the PDIR entries valid w/ the spill page as the target */ for (index = 0 ; index < (ioc->pdir_size / sizeof(u64)) ; index++) - ((u64 *)ioc->pdir_base)[index] = (0x80000000000000FFULL | (u64)prefetch_spill_page); + ((u64 *)ioc->pdir_base)[index] = (0x80000000000000FF | prefetch_spill_page); #endif + } static void __init @@ -1581,7 +1581,8 @@ #ifdef FULL_VALID_PDIR /* Mark the last resource used so we don't prefetch beyond IOVA space */ ioc->res_map[ioc->res_size - 1] |= 0x80UL; /* res_map is chars */ - ioc->pdir_base[(ioc->pdir_size / sizeof(u64)) - 1] = (0x80000000000000FFULL | (u64)prefetch_spill_page); + ioc->pdir_base[(ioc->pdir_size / sizeof(u64)) - 1] = (0x80000000000000FF + | prefetch_spill_page); #endif DBG_INIT("%s() res_map %x %p\n", __FUNCTION__, @@ -1701,25 +1702,52 @@ **************************************************************************/ #ifdef CONFIG_PROC_FS +static void * +ioc_start(struct seq_file *s, loff_t *pos) +{ + struct ioc *ioc; + loff_t n = *pos; + + for (ioc = ioc_list; ioc; ioc = ioc->next) + if (!n--) + return ioc; + + return NULL; +} + +static void * +ioc_next(struct seq_file *s, void *v, loff_t *pos) +{ + struct ioc *ioc = v; + + ++*pos; + return ioc->next; +} + +static void +ioc_stop(struct seq_file *s, void *v) +{ +} + static int -sba_proc_info_one(char *buf, struct ioc *ioc) +ioc_show(struct seq_file *s, void *v) { + struct ioc *ioc = v; int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ unsigned long i = 0, avg = 0, min, max; - sprintf(buf, "Hewlett Packard %s IOC rev %d.%d\n", + seq_printf(s, "Hewlett Packard %s IOC rev %d.%d\n", ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF)); - sprintf(buf, "%sIO PDIR size : %d bytes (%d entries)\n", - buf, + seq_printf(s, "IO PDIR size : %d bytes (%d entries)\n", (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ total_pages); - sprintf(buf, "%sIO PDIR entries : %ld free %ld used (%d%%)\n", buf, + seq_printf(s, "IO PDIR entries : %ld free %ld used (%d%%)\n", total_pages - ioc->used_pages, ioc->used_pages, (int) (ioc->used_pages * 100 / total_pages)); - - sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", - buf, ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ + + seq_printf(s, "Resource bitmap : %d bytes (%d pages)\n", + ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ min = max = ioc->avg_search[0]; for (i = 0; i < SBA_SEARCH_SAMPLE; i++) { @@ -1728,81 +1756,106 @@ if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; } avg /= SBA_SEARCH_SAMPLE; - sprintf(buf, "%s Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", - buf, min, avg, max); + seq_printf(s, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", + min, avg, max); - sprintf(buf, "%spci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->msingle_calls, ioc->msingle_pages, + seq_printf(s, "pci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", + ioc->msingle_calls, ioc->msingle_pages, (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); #ifdef ALLOW_IOV_BYPASS - sprintf(buf, "%spci_map_single(): %12ld bypasses\n", - buf, ioc->msingle_bypass); + seq_printf(s, "pci_map_single(): %12ld bypasses\n", ioc->msingle_bypass); #endif - sprintf(buf, "%spci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->usingle_calls, ioc->usingle_pages, + seq_printf(s, "pci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", + ioc->usingle_calls, ioc->usingle_pages, (int) ((ioc->usingle_pages * 1000)/ioc->usingle_calls)); #ifdef ALLOW_IOV_BYPASS - sprintf(buf, "%spci_unmap_single: %12ld bypasses\n", - buf, ioc->usingle_bypass); + seq_printf(s, "pci_unmap_single: %12ld bypasses\n", ioc->usingle_bypass); #endif - sprintf(buf, "%spci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->msg_calls, ioc->msg_pages, + seq_printf(s, "pci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", + ioc->msg_calls, ioc->msg_pages, (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); #ifdef ALLOW_IOV_BYPASS - sprintf(buf, "%spci_map_sg() : %12ld bypasses\n", - buf, ioc->msg_bypass); + seq_printf(s, "pci_map_sg() : %12ld bypasses\n", ioc->msg_bypass); #endif - sprintf(buf, "%spci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->usg_calls, ioc->usg_pages, + seq_printf(s, "pci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", + ioc->usg_calls, ioc->usg_pages, (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); - return strlen(buf); + return 0; } +static struct seq_operations ioc_seq_ops = { + .start = ioc_start, + .next = ioc_next, + .stop = ioc_stop, + .show = ioc_show +}; + static int -sba_proc_info(char *buf, char **start, off_t offset, int len) +ioc_open(struct inode *inode, struct file *file) { - struct ioc *ioc; - char *base = buf; - - for (ioc = ioc_list; ioc; ioc = ioc->next) { - buf += sba_proc_info_one(buf, ioc); - } - - return strlen(base); + return seq_open(file, &ioc_seq_ops); } +static struct file_operations ioc_fops = { + .open = ioc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + static int -sba_resource_map_one(char *buf, struct ioc *ioc) +ioc_map_show(struct seq_file *s, void *v) { + struct ioc *ioc = v; unsigned int *res_ptr = (unsigned int *)ioc->res_map; int i; - buf[0] = '\0'; - for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) { - if ((i & 7) == 0) - strcat(buf,"\n "); - sprintf(buf, "%s %08x", buf, *res_ptr); - } - strcat(buf, "\n"); + for (i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) + seq_printf(s, "%s%08x", (i & 7) ? " " : "\n ", *res_ptr); + seq_printf(s, "\n"); - return strlen(buf); + return 0; } +static struct seq_operations ioc_map_ops = { + .start = ioc_start, + .next = ioc_next, + .stop = ioc_stop, + .show = ioc_map_show +}; + static int -sba_resource_map(char *buf, char **start, off_t offset, int len) +ioc_map_open(struct inode *inode, struct file *file) { - struct ioc *ioc; - char *base = buf; + return seq_open(file, &ioc_map_ops); +} - for (ioc = ioc_list; ioc; ioc = ioc->next) { - buf += sba_resource_map_one(buf, ioc); - } +static struct file_operations ioc_map_fops = { + .open = ioc_map_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; - return strlen(base); +static void __init +ioc_proc_init(void) +{ + if (ioc_list) { + struct proc_dir_entry *dir, *entry; + + dir = proc_mkdir("bus/mckinley", 0); + entry = create_proc_entry(ioc_list->name, 0, dir); + if (entry) + entry->proc_fops = &ioc_fops; + + entry = create_proc_entry("bitmap", 0, dir); + if (entry) + entry->proc_fops = &ioc_map_fops; + } } #endif @@ -1833,7 +1886,7 @@ handle = parent; } while (ACPI_SUCCESS(status)); - printk("No IOC for %s in ACPI\n", dev->slot_name); + printk(KERN_WARNING "No IOC for %s in ACPI\n", dev->slot_name); } static int __init @@ -1842,31 +1895,23 @@ struct ioc *ioc; acpi_status status; u64 hpa, length; + acpi_device_info dev_info; - /* - * Only SBA appears in ACPI namespace. It encloses the PCI - * root bridges, and its CSR space includes the IOC function. - */ status = acpi_hp_csr_space(device->handle, &hpa, &length); if (ACPI_FAILURE(status)) return 1; - ioc = ioc_init(hpa + ZX1_IOC_OFFSET, device->handle); - if (!ioc) - return 1; - - return 0; -} - -static int __init -acpi_ioc_add(struct acpi_device *device) -{ - struct ioc *ioc; - acpi_status status; - u64 hpa, length; - status = acpi_hp_csr_space(device->handle, &hpa, &length); + status = acpi_get_object_info(device->handle, &dev_info); if (ACPI_FAILURE(status)) return 1; + + /* + * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI + * root bridges, and its CSR space includes the IOC function. + */ + if (strncmp("HWP0001", dev_info.hardware_id, 7) == 0) + hpa += ZX1_IOC_OFFSET; + ioc = ioc_init(hpa, device->handle); if (!ioc) return 1; @@ -1876,40 +1921,19 @@ static struct acpi_driver acpi_sba_ioc_driver = { name: "IOC IOMMU Driver", - ids: "HWP0001", + ids: "HWP0001,HWP0004", ops: { add: acpi_sba_ioc_add, }, }; -static struct acpi_driver acpi_ioc_driver = { - name: "IOC IOMMU Driver", - ids: "HWP0004", - ops: { - add: acpi_ioc_add, - }, -}; - -void __init -ioc_acpi_init(void) -{ - acpi_bus_register_driver(&acpi_sba_ioc_driver); - acpi_bus_register_driver(&acpi_ioc_driver); -} - void __init sba_init(void) { - ioc_acpi_init(); + acpi_bus_register_driver(&acpi_sba_ioc_driver); #ifdef CONFIG_PROC_FS - if (ioc_list) { - struct proc_dir_entry * proc_mckinley_root; - - proc_mckinley_root = proc_mkdir("bus/mckinley",0); - create_proc_info_entry(ioc_list->name, 0, proc_mckinley_root, sba_proc_info); - create_proc_info_entry("bitmap", 0, proc_mckinley_root, sba_resource_map); - } + ioc_proc_init(); #endif } @@ -1920,6 +1944,13 @@ return 1; } +int +sba_dma_supported (struct pci_dev *dev, u64 mask) +{ + /* make sure it's at least 32bit capable */ + return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL); +} + __setup("nosbagart", nosbagart); EXPORT_SYMBOL(sba_init); diff -urN linux-2.4.21/arch/ia64/hp/sim/hpsim_console.c linux-2.4.22/arch/ia64/hp/sim/hpsim_console.c --- linux-2.4.21/arch/ia64/hp/sim/hpsim_console.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/hp/sim/hpsim_console.c 2003-08-25 04:44:39.000000000 -0700 @@ -28,12 +28,12 @@ static kdev_t simcons_console_device (struct console *); struct console hpsim_cons = { - name: "simcons", - write: simcons_write, - device: simcons_console_device, - setup: simcons_init, - flags: CON_PRINTBUFFER, - index: -1, + .name = "simcons", + .write = simcons_write, + .device = simcons_console_device, + .setup = simcons_init, + .flags = CON_PRINTBUFFER, + .index = -1, }; static int diff -urN linux-2.4.21/arch/ia64/hp/sim/hpsim_irq.c linux-2.4.22/arch/ia64/hp/sim/hpsim_irq.c --- linux-2.4.21/arch/ia64/hp/sim/hpsim_irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/hp/sim/hpsim_irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -22,14 +22,14 @@ } static struct hw_interrupt_type irq_type_hp_sim = { - typename: "hpsim", - startup: hpsim_irq_startup, - shutdown: hpsim_irq_noop, - enable: hpsim_irq_noop, - disable: hpsim_irq_noop, - ack: hpsim_irq_noop, - end: hpsim_irq_noop, - set_affinity: (void (*)(unsigned int, unsigned long)) hpsim_irq_noop, + .typename = "hpsim", + .startup = hpsim_irq_startup, + .shutdown = hpsim_irq_noop, + .enable = hpsim_irq_noop, + .disable = hpsim_irq_noop, + .ack = hpsim_irq_noop, + .end = hpsim_irq_noop, + .set_affinity = (void (*)(unsigned int, unsigned long)) hpsim_irq_noop, }; void __init diff -urN linux-2.4.21/arch/ia64/hp/sim/hpsim_machvec.c linux-2.4.22/arch/ia64/hp/sim/hpsim_machvec.c --- linux-2.4.21/arch/ia64/hp/sim/hpsim_machvec.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/hp/sim/hpsim_machvec.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,2 +1,3 @@ -#define MACHVEC_PLATFORM_NAME hpsim +#define MACHVEC_PLATFORM_NAME hpsim +#define MACHVEC_PLATFORM_HEADER #include diff -urN linux-2.4.21/arch/ia64/hp/zx1/hpzx1_machvec.c linux-2.4.22/arch/ia64/hp/zx1/hpzx1_machvec.c --- linux-2.4.21/arch/ia64/hp/zx1/hpzx1_machvec.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/hp/zx1/hpzx1_machvec.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,2 +1,3 @@ -#define MACHVEC_PLATFORM_NAME hpzx1 +#define MACHVEC_PLATFORM_NAME hpzx1 +#define MACHVEC_PLATFORM_HEADER #include diff -urN linux-2.4.21/arch/ia64/ia32/binfmt_elf32.c linux-2.4.22/arch/ia64/ia32/binfmt_elf32.c --- linux-2.4.21/arch/ia64/ia32/binfmt_elf32.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/ia32/binfmt_elf32.c 2003-08-25 04:44:39.000000000 -0700 @@ -67,7 +67,7 @@ } static struct vm_operations_struct ia32_shared_page_vm_ops = { - nopage: ia32_install_shared_page + .nopage =ia32_install_shared_page }; void diff -urN linux-2.4.21/arch/ia64/ia32/ia32_entry.S linux-2.4.22/arch/ia64/ia32/ia32_entry.S --- linux-2.4.21/arch/ia64/ia32/ia32_entry.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/ia32/ia32_entry.S 2003-08-25 04:44:39.000000000 -0700 @@ -87,12 +87,19 @@ GLOBAL_ENTRY(ia32_ret_from_clone) PT_REGS_UNWIND_INFO(0) +{ /* + * Some versions of gas generate bad unwind info if the first instruction of a + * procedure doesn't go into the first slot of a bundle. This is a workaround. + */ + nop.m 0 + nop.i 0 /* * We need to call schedule_tail() to complete the scheduling process. * Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the * address of the previously executing task. */ br.call.sptk.many rp=ia64_invoke_schedule_tail +} .ret1: adds r2=IA64_TASK_PTRACE_OFFSET,r13 ;; ld8 r2=[r2] diff -urN linux-2.4.21/arch/ia64/ia32/ia32_ioctl.c linux-2.4.22/arch/ia64/ia32/ia32_ioctl.c --- linux-2.4.21/arch/ia64/ia32/ia32_ioctl.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/ia32/ia32_ioctl.c 2003-08-25 04:44:39.000000000 -0700 @@ -268,6 +268,6 @@ return sys_ioctl(fd, cmd, (unsigned long)arg); } - printk("%x:unimplemented IA32 ioctl system call\n", cmd); + printk(KERN_ERR "%x:unimplemented IA32 ioctl system call\n", cmd); return -EINVAL; } diff -urN linux-2.4.21/arch/ia64/ia32/sys_ia32.c linux-2.4.22/arch/ia64/ia32/sys_ia32.c --- linux-2.4.21/arch/ia64/ia32/sys_ia32.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/ia32/sys_ia32.c 2003-08-25 04:44:39.000000000 -0700 @@ -250,9 +250,8 @@ static int -get_page_prot (unsigned long addr) +get_page_prot (struct vm_area_struct *vma, unsigned long addr) { - struct vm_area_struct *vma = find_vma(current->mm, addr); int prot = 0; if (!vma || vma->vm_start > addr) @@ -275,14 +274,26 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags, loff_t off) { - void *page = (void *) get_zeroed_page(GFP_KERNEL); + void *page = NULL; struct inode *inode; - unsigned long ret; - int old_prot = get_page_prot(start); + unsigned long ret = 0; + struct vm_area_struct *vma = find_vma(current->mm, start); + int old_prot = get_page_prot(vma, start); DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n", file, start, end, prot, flags, off); + + /* Optimize the case where the old mmap and the new mmap are both anonymous */ + if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) { + if (clear_user((void *) start, end - start)) { + ret = -EFAULT; + goto out; + } + goto skip_mmap; + } + + page = (void *) get_zeroed_page(GFP_KERNEL); if (!page) return -ENOMEM; @@ -307,6 +318,7 @@ copy_to_user((void *) end, page + PAGE_OFF(end), PAGE_SIZE - PAGE_OFF(end)); } + if (!(flags & MAP_ANONYMOUS)) { /* read the file contents */ inode = file->f_dentry->d_inode; @@ -317,10 +329,13 @@ goto out; } } + + skip_mmap: if (!(prot & PROT_WRITE)) ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot); out: - free_page((unsigned long) page); + if (page) + free_page((unsigned long) page); return ret; } @@ -448,7 +463,12 @@ return addr; if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len) + { + if (flags & MAP_FIXED) + return -ENOMEM; + else return -EINVAL; + } if (OFFSET4K(offset)) return -EINVAL; @@ -547,7 +567,7 @@ #if PAGE_SHIFT <= IA32_PAGE_SHIFT ret = sys_munmap(start, end - start); #else - if (start > end) + if (start >= end) return -EINVAL; start = PAGE_ALIGN(start); @@ -576,11 +596,12 @@ mprotect_subpage (unsigned long address, int new_prot) { int old_prot; + struct vm_area_struct *vma; if (new_prot == PROT_NONE) return 0; /* optimize case where nothing changes... */ - - old_prot = get_page_prot(address); + vma = find_vma(current->mm, address); + old_prot = get_page_prot(vma, address); return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot); } @@ -1230,8 +1251,8 @@ #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) struct rlimit32 { - int rlim_cur; - int rlim_max; + unsigned int rlim_cur; + unsigned int rlim_max; }; extern asmlinkage long sys_getrlimit (unsigned int resource, struct rlimit *rlim); @@ -2085,7 +2106,7 @@ }; struct shmid64_ds32 { - struct ipc64_perm shm_perm; + struct ipc64_perm32 shm_perm; __kernel_size_t32 shm_segsz; __kernel_time_t32 shm_atime; unsigned int __unused1; @@ -2126,6 +2147,7 @@ #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 @@ -2167,6 +2189,10 @@ else fourth.__pad = (void *)A(pad); switch (third) { + default: + err = -EINVAL; + break; + case IPC_INFO: case IPC_RMID: case IPC_SET: @@ -2234,7 +2260,7 @@ static int do_sys32_msgsnd (int first, int second, int third, void *uptr) { - struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER); + struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf), GFP_USER); struct msgbuf32 *up = (struct msgbuf32 *)uptr; mm_segment_t old_fs; int err; @@ -2276,12 +2302,12 @@ msgtyp = ipck.msgtyp; } err = -ENOMEM; - p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER); + p = kmalloc(second + sizeof(struct msgbuf), GFP_USER); if (!p) goto out; old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_msgrcv(first, p, second + 4, msgtyp, third); + err = sys_msgrcv(first, p, second, msgtyp, third); set_fs(old_fs); if (err < 0) goto free_then_out; @@ -2314,21 +2340,21 @@ case IPC_SET: if (version == IPC_64) { - err = get_user(m.msg_perm.uid, &up64->msg_perm.uid); - err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid); - err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode); - err |= get_user(m.msg_qbytes, &up64->msg_qbytes); + err = get_user(m64.msg_perm.uid, &up64->msg_perm.uid); + err |= get_user(m64.msg_perm.gid, &up64->msg_perm.gid); + err |= get_user(m64.msg_perm.mode, &up64->msg_perm.mode); + err |= get_user(m64.msg_qbytes, &up64->msg_qbytes); } else { - err = get_user(m.msg_perm.uid, &up32->msg_perm.uid); - err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid); - err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode); - err |= get_user(m.msg_qbytes, &up32->msg_qbytes); + err = get_user(m64.msg_perm.uid, &up32->msg_perm.uid); + err |= get_user(m64.msg_perm.gid, &up32->msg_perm.gid); + err |= get_user(m64.msg_perm.mode, &up32->msg_perm.mode); + err |= get_user(m64.msg_qbytes, &up32->msg_qbytes); } if (err) break; old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_msgctl(first, second, &m); + err = sys_msgctl(first, second, &m64); set_fs(old_fs); break; @@ -2408,7 +2434,7 @@ shmctl32 (int first, int second, void *uptr) { int err = -EFAULT, err2; - struct shmid_ds s; + struct shmid64_ds s64; struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; @@ -2460,19 +2486,19 @@ case IPC_SET: if (version == IPC_64) { - err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); + err = get_user(s64.shm_perm.uid, &up64->shm_perm.uid); + err |= get_user(s64.shm_perm.gid, &up64->shm_perm.gid); + err |= get_user(s64.shm_perm.mode, &up64->shm_perm.mode); } else { - err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); + err = get_user(s64.shm_perm.uid, &up32->shm_perm.uid); + err |= get_user(s64.shm_perm.gid, &up32->shm_perm.gid); + err |= get_user(s64.shm_perm.mode, &up32->shm_perm.mode); } if (err) break; old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_shmctl(first, second, &s); + err = sys_shmctl(first, second, &s64); set_fs(old_fs); break; @@ -2553,6 +2579,17 @@ return err; } +static long +semtimedop32(int semid, struct sembuf *tsems, int nsems, + const struct timespec32 *timeout32) +{ + struct timespec t; + if (get_user (t.tv_sec, &timeout32->tv_sec) || + get_user (t.tv_nsec, &timeout32->tv_nsec)) + return -EFAULT; + return sys_semtimedop(semid, tsems, nsems, &t); +} + asmlinkage long sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { @@ -2564,7 +2601,11 @@ switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - return sys_semop(first, (struct sembuf *)AA(ptr), second); + return sys_semtimedop(first, (struct sembuf *)AA(ptr), second, + NULL); + case SEMTIMEDOP: + return semtimedop32(first, (struct sembuf *)AA(ptr), second, + (const struct timespec32 *)AA(fifth)); case SEMGET: return sys_semget(first, second, third); case SEMCTL: @@ -2590,7 +2631,7 @@ return shmctl32(first, second, (void *)AA(ptr)); default: - return -EINVAL; + return -ENOSYS; } return -EINVAL; } @@ -2924,7 +2965,7 @@ ptp = ia64_task_regs(tsk); tos = (tsk->thread.fsr >> 11) & 7; for (i = 0; i < 8; i++) - put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos); + put_fpreg(i, &save->st_space[i], ptp, swp, tos); return 0; } @@ -2957,7 +2998,7 @@ ptp = ia64_task_regs(tsk); tos = (tsk->thread.fsr >> 11) & 7; for (i = 0; i < 8; i++) - get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos); + get_fpreg(i, &save->st_space[i], ptp, swp, tos); return 0; } @@ -3076,26 +3117,23 @@ ret = -ESRCH; read_lock(&tasklist_lock); child = find_task_by_pid(pid); + if (child) + get_task_struct(child); read_unlock(&tasklist_lock); if (!child) goto out; ret = -EPERM; if (pid == 1) /* no messing around with init! */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack); - goto out; - } - ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out; + goto out_tsk; } - if (child->p_pptr != current) - goto out; + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) + goto out_tsk; switch (request) { case PTRACE_PEEKTEXT: @@ -3105,12 +3143,12 @@ ret = put_user(value, (unsigned int *) A(data)); else ret = -EIO; - goto out; + goto out_tsk; case PTRACE_POKETEXT: case PTRACE_POKEDATA: /* write the word at location addr */ ret = ia32_poke(regs, child, addr, data); - goto out; + goto out_tsk; case PTRACE_PEEKUSR: /* read word at addr in USER area */ ret = -EIO; @@ -3185,6 +3223,8 @@ break; } + out_tsk: + free_task_struct(child); out: unlock_kernel(); return ret; @@ -3407,6 +3447,7 @@ asmlinkage long sys32_sysctl (struct sysctl32 *args) { +#ifdef CONFIG_SYSCTL struct sysctl32 a32; mm_segment_t old_fs = get_fs (); void *oldvalp, *newvalp; @@ -3444,6 +3485,9 @@ return -EFAULT; return ret; +#else + return -ENOSYS; +#endif } asmlinkage long @@ -3707,21 +3751,43 @@ u32 bufferram; u32 totalswap; u32 freeswap; - unsigned short procs; - char _f[22]; + u16 procs; + u16 pad; + u32 totalhigh; + u32 freehigh; + u32 mem_unit; + char _f[8]; }; asmlinkage long sys32_sysinfo (struct sysinfo32 *info) { extern asmlinkage long sys_sysinfo (struct sysinfo *); - mm_segment_t old_fs = get_fs(); struct sysinfo s; long ret, err; + int bitcount = 0; + mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); ret = sys_sysinfo(&s); set_fs(old_fs); + /* Check to see if any memory value is too large for 32-bit and + * scale down if needed. + */ + if ((s.totalram >> 32) || (s.totalswap >> 32)) { + while (s.mem_unit < PAGE_SIZE) { + s.mem_unit <<= 1; + bitcount++; + } + s.totalram >>= bitcount; + s.freeram >>= bitcount; + s.sharedram >>= bitcount; + s.bufferram >>= bitcount; + s.totalswap >>= bitcount; + s.freeswap >>= bitcount; + s.totalhigh >>= bitcount; + s.freehigh >>= bitcount; + } if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) return -EFAULT; @@ -3737,6 +3803,9 @@ err |= __put_user(s.totalswap, &info->totalswap); err |= __put_user(s.freeswap, &info->freeswap); err |= __put_user(s.procs, &info->procs); + err |= __put_user(s.totalhigh, &info->totalhigh); + err |= __put_user(s.freehigh, &info->freehigh); + err |= __put_user(s.mem_unit, &info->mem_unit); if (err) return -EFAULT; return ret; @@ -3783,7 +3852,7 @@ return result; } -struct dqblk32 { +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -3795,43 +3864,43 @@ }; asmlinkage long -sys32_quotactl (int cmd, unsigned int special, int id, struct dqblk32 *addr) +sys32_quotactl(int cmd, unsigned int special, int id, caddr_t addr) { extern asmlinkage long sys_quotactl (int, const char *, int, caddr_t); int cmds = cmd >> SUBCMDSHIFT; mm_segment_t old_fs; - struct dqblk d; + struct v1c_mem_dqblk d; char *spec; long err; switch (cmds) { - case Q_GETQUOTA: + case Q_V1_GETQUOTA: break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, addr, sizeof(struct dqblk32))) + case Q_V1_SETQUOTA: + case Q_V1_SETUSE: + case Q_V1_SETQLIM: + if (copy_from_user(&d, addr, sizeof(struct user_dqblk32))) return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; + d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime; break; - default: - return sys_quotactl(cmd, (void *) A(special), id, (caddr_t) addr); + default: + return sys_quotactl(cmd, (void *)A(special), id, addr); } spec = getname32((void *) A(special)); err = PTR_ERR(spec); if (IS_ERR(spec)) return err; - old_fs = get_fs (); + old_fs = get_fs(); set_fs(KERNEL_DS); err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); set_fs(old_fs); putname(spec); - if (cmds == Q_GETQUOTA) { + if (cmds == Q_V1_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))) + ((struct user_dqblk32 *)&d)->dqb_itime = i; + ((struct user_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user(addr, &d, sizeof(struct user_dqblk32))) return -EFAULT; } return err; diff -urN linux-2.4.21/arch/ia64/kernel/acpi.c linux-2.4.22/arch/ia64/kernel/acpi.c --- linux-2.4.21/arch/ia64/kernel/acpi.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/acpi.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ * * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999,2000 Walt Drummond - * Copyright (C) 2000, 2002 Hewlett-Packard Co. + * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co. * David Mosberger-Tang * Copyright (C) 2000 Intel Corp. * Copyright (C) 2000,2001 J.I. Lee @@ -51,6 +51,7 @@ asm (".weak iosapic_override_isa_irq"); asm (".weak iosapic_register_platform_intr"); asm (".weak iosapic_init"); +asm (".weak iosapic_system_init"); asm (".weak iosapic_version"); void (*pm_idle) (void); @@ -69,20 +70,20 @@ rsdp_phys = acpi_find_rsdp(); if (!rsdp_phys) { - printk("ACPI 2.0 RSDP not found, default to \"dig\"\n"); + printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n"); return "dig"; } rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys); if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) { - printk("ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n"); + printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n"); return "dig"; } xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address); hdr = &xsdt->header; if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) { - printk("ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n"); + printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n"); return "dig"; } @@ -110,165 +111,88 @@ #ifdef CONFIG_ACPI -static acpi_resource * -acpi_get_crs_next (acpi_buffer *buf, int *offset) -{ - acpi_resource *res; - - if (*offset >= buf->length) - return NULL; +struct acpi_vendor_descriptor { + u8 guid_id; + efi_guid_t guid; +}; + +struct acpi_vendor_info { + struct acpi_vendor_descriptor *descriptor; + u8 *data; + u32 length; +}; - res = (acpi_resource *)((char *) buf->pointer + *offset); - *offset += res->length; - return res; -} - -static acpi_resource_data * -acpi_get_crs_type (acpi_buffer *buf, int *offset, int type) -{ - for (;;) { - acpi_resource *res = acpi_get_crs_next(buf, offset); - if (!res) - return NULL; - if (res->id == type) - return &res->data; - } -} - -static void -acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, u64 *tra) -{ - int offset = 0; - acpi_resource_address16 *addr16; - acpi_resource_address32 *addr32; - acpi_resource_address64 *addr64; - - for (;;) { - acpi_resource *res = acpi_get_crs_next(buf, &offset); - if (!res) - return; - switch (res->id) { - case ACPI_RSTYPE_ADDRESS16: - addr16 = (acpi_resource_address16 *) &res->data; - - if (type == addr16->resource_type) { - *base = addr16->min_address_range; - *length = addr16->address_length; - *tra = addr16->address_translation_offset; - return; - } - break; - case ACPI_RSTYPE_ADDRESS32: - addr32 = (acpi_resource_address32 *) &res->data; - if (type == addr32->resource_type) { - *base = addr32->min_address_range; - *length = addr32->address_length; - *tra = addr32->address_translation_offset; - return; - } - break; - case ACPI_RSTYPE_ADDRESS64: - addr64 = (acpi_resource_address64 *) &res->data; - if (type == addr64->resource_type) { - *base = addr64->min_address_range; - *length = addr64->address_length; - *tra = addr64->address_translation_offset; - return; - } - break; - case ACPI_RSTYPE_END_TAG: - return; - break; - } - } +acpi_status +acpi_vendor_resource_match(acpi_resource *resource, void *context) +{ + struct acpi_vendor_info *info = (struct acpi_vendor_info *) context; + acpi_resource_vendor *vendor; + struct acpi_vendor_descriptor *descriptor; + u32 length; + + if (resource->id != ACPI_RSTYPE_VENDOR) + return AE_OK; + + vendor = (acpi_resource_vendor *) &resource->data; + descriptor = (struct acpi_vendor_descriptor *) vendor->reserved; + if (vendor->length <= sizeof(*info->descriptor) || + descriptor->guid_id != info->descriptor->guid_id || + efi_guidcmp(descriptor->guid, info->descriptor->guid)) + return AE_OK; + + length = vendor->length - sizeof(struct acpi_vendor_descriptor); + info->data = acpi_os_allocate(length); + if (!info->data) + return AE_NO_MEMORY; + + memcpy(info->data, vendor->reserved + sizeof(struct acpi_vendor_descriptor), length); + info->length = length; + return AE_CTRL_TERMINATE; } acpi_status -acpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra) +acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor *id, + u8 **data, u32 *length) { - acpi_status status; - acpi_buffer buf = { .length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL }; + struct acpi_vendor_info info; - *base = 0; - *length = 0; - *tra = 0; + info.descriptor = id; + info.data = 0; - status = acpi_get_current_resources(obj, &buf); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n"); - return status; - } - - acpi_get_crs_addr(&buf, type, base, length, tra); - - acpi_os_free(buf.pointer); + acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, &info); + if (!info.data) + return AE_NOT_FOUND; + *data = info.data; + *length = info.length; return AE_OK; } -typedef struct { - u8 guid_id; - u8 guid[16]; - u8 csr_base[8]; - u8 csr_length[8]; -} acpi_hp_vendor_long; - -#define HP_CCSR_LENGTH 0x21 -#define HP_CCSR_TYPE 0x2 -#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \ - 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad) +struct acpi_vendor_descriptor hp_ccsr_descriptor = { + .guid_id = 2, + .guid = EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad) +}; acpi_status acpi_hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length) { - int i, offset = 0; acpi_status status; - acpi_buffer buf = { .length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL }; - acpi_resource_vendor *res; - acpi_hp_vendor_long *hp_res; - efi_guid_t vendor_guid; - - *csr_base = 0; - *csr_length = 0; + u8 *data; + u32 length; + int i; + + status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); + + if (ACPI_FAILURE(status) || length != 16) + return AE_NOT_FOUND; + + memcpy(csr_base, data, sizeof(*csr_base)); + memcpy(csr_length, data + 8, sizeof(*csr_length)); + acpi_os_free(data); - status = acpi_get_current_resources(obj, &buf); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n"); - return status; - } - - status = AE_NOT_FOUND; - res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR); - if (!res) { - printk(KERN_ERR PREFIX "Failed to find config space for device\n"); - goto out; - } - - status = AE_TYPE; /* Revisit error? */ - hp_res = (acpi_hp_vendor_long *)(res->reserved); - - if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) { - printk(KERN_ERR PREFIX "Unknown Vendor data\n"); - goto out; - } - - memcpy(&vendor_guid, hp_res->guid, sizeof(efi_guid_t)); - if (efi_guidcmp(vendor_guid, HP_CCSR_GUID) != 0) { - printk(KERN_ERR PREFIX "Vendor GUID does not match\n"); - goto out; - } - - /* It's probably unaligned, so use memcpy */ - memcpy(csr_base, hp_res->csr_base, 8); - memcpy(csr_length, hp_res->csr_length, 8); - status = AE_OK; - - out: - acpi_os_free(buf.pointer); - return status; + return AE_OK; } + #endif /* CONFIG_ACPI */ #ifdef CONFIG_ACPI_BOOT @@ -293,8 +217,7 @@ /* correctable platform error interrupt */ vector = platform_intr_list[int_type]; } else - printk("acpi_request_vector(): invalid interrupt type\n"); - + printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n"); return vector; } @@ -354,7 +277,7 @@ return 0; } - printk("CPU %d (0x%04x)", total_cpus, phys_id); + printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, phys_id); if (lsapic->flags.enabled) { available_cpus++; @@ -397,40 +320,6 @@ static int __init -acpi_find_iosapic (unsigned int gsi, u32 *gsi_base, char **iosapic_address) -{ - struct acpi_table_iosapic *iosapic; - int ver; - int max_pin; - char *p; - char *end; - - if (!gsi_base || !iosapic_address) - return -ENODEV; - - p = (char *) (acpi_madt + 1); - end = p + (acpi_madt->header.length - sizeof(struct acpi_table_madt)); - - while (p < end) { - if (*p == ACPI_MADT_IOSAPIC) { - iosapic = (struct acpi_table_iosapic *) p; - - *gsi_base = iosapic->global_irq_base; - *iosapic_address = ioremap(iosapic->address, 0); - - ver = iosapic_version(*iosapic_address); - max_pin = (ver >> 16) & 0xff; - - if ((gsi - *gsi_base) <= max_pin) - return 0; /* Found it! */ - } - p += p[1]; - } - return -ENODEV; -} - - -static int __init acpi_parse_iosapic (acpi_table_entry_header *header) { struct acpi_table_iosapic *iosapic; @@ -441,15 +330,9 @@ acpi_table_print_madt_entry(header); - if (iosapic_init) { -#ifndef CONFIG_ITANIUM - iosapic_init(iosapic->address, iosapic->global_irq_base, - has_8259); -#else - /* Firmware on old Itanium systems is broken */ - iosapic_init(iosapic->address, iosapic->global_irq_base, 1); -#endif - } + if (iosapic_init) + iosapic_init(iosapic->address, iosapic->global_irq_base); + return 0; } @@ -459,8 +342,6 @@ { struct acpi_table_plat_int_src *plintsrc; int vector; - u32 gsi_base; - char *iosapic_address; plintsrc = (struct acpi_table_plat_int_src *) header; if (!plintsrc) @@ -473,11 +354,6 @@ return -ENODEV; } - if (acpi_find_iosapic(plintsrc->global_irq, &gsi_base, &iosapic_address)) { - printk(KERN_WARNING PREFIX "IOSAPIC not found\n"); - return -ENODEV; - } - /* * Get vector assignment for this interrupt, set attributes, * and program the IOSAPIC routing table. @@ -487,10 +363,8 @@ plintsrc->iosapic_vector, plintsrc->eid, plintsrc->id, - (plintsrc->flags.polarity == 1) ? 1 : 0, - (plintsrc->flags.trigger == 1) ? 1 : 0, - gsi_base, - iosapic_address); + (plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); platform_intr_list[plintsrc->type] = vector; return 0; @@ -513,9 +387,8 @@ return 0; iosapic_override_isa_irq(p->bus_irq, p->global_irq, - (p->flags.polarity == 1) ? 1 : 0, - (p->flags.trigger == 1) ? 1 : 0); - + (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); return 0; } @@ -546,7 +419,13 @@ acpi_madt = (struct acpi_table_madt *) __va(phys_addr); /* remember the value for reference after free_initmem() */ +#ifdef CONFIG_ITANIUM + has_8259 = 1; /* Firmware on old Itanium systems is broken */ +#else has_8259 = acpi_madt->flags.pcat_compat; +#endif + if (iosapic_system_init) + iosapic_system_init(has_8259); /* Get base address of IPI Message Block */ @@ -563,8 +442,7 @@ { struct acpi_table_header *fadt_header; fadt_descriptor_rev2 *fadt; - u32 sci_irq, gsi_base; - char *iosapic_address; + u32 sci_irq; if (!phys_addr || !size) return -EINVAL; @@ -587,9 +465,7 @@ if (!iosapic_register_intr) return -ENODEV; - if (!acpi_find_iosapic(sci_irq, &gsi_base, &iosapic_address)) - iosapic_register_intr(sci_irq, 0, 0, gsi_base, iosapic_address); - + iosapic_register_intr(sci_irq, IOSAPIC_POL_LOW, IOSAPIC_LEVEL); return 0; } @@ -676,13 +552,13 @@ #ifdef CONFIG_SMP if (available_cpus == 0) { - printk("ACPI: Found 0 CPUS; assuming 1\n"); + printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n"); available_cpus = 1; /* We've got at least one of these, no? */ } smp_boot_data.cpu_count = total_cpus; #endif /* Make boot-up look pretty */ - printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); + printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); return 0; } @@ -690,6 +566,7 @@ /* -------------------------------------------------------------------------- PCI Interrupt Routing -------------------------------------------------------------------------- */ +#ifdef CONFIG_PCI int __init acpi_get_prt (struct pci_vector_struct **vectors, int *count) @@ -732,7 +609,7 @@ *count = acpi_prt.count; return 0; } - +#endif /* Assume IA64 always use I/O SAPIC */ int __init diff -urN linux-2.4.21/arch/ia64/kernel/brl_emu.c linux-2.4.22/arch/ia64/kernel/brl_emu.c --- linux-2.4.21/arch/ia64/kernel/brl_emu.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/brl_emu.c 2003-08-25 04:44:39.000000000 -0700 @@ -55,11 +55,11 @@ ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec) { unsigned long bundle[2]; - unsigned long opcode, btype, qp, offset; + unsigned long opcode, btype, qp, offset, cpl; unsigned long next_ip; struct siginfo siginfo; struct illegal_op_return rv; - int tmp_taken, unimplemented_address; + long tmp_taken, unimplemented_address; rv.fkt = (unsigned long) -1; @@ -158,9 +158,9 @@ * AR[PFS].pec = AR[EC] * AR[PFS].ppl = PSR.cpl */ + cpl = ia64_psr(regs)->cpl; regs->ar_pfs = ((regs->cr_ifs & 0x3fffffffff) - | (ar_ec << 52) - | ((unsigned long) ia64_psr(regs)->cpl << 62)); + | (ar_ec << 52) | (cpl << 62)); /* * CFM.sof -= CFM.sol @@ -195,7 +195,7 @@ /* * The target address contains unimplemented bits. */ - printk("Woah! Unimplemented Instruction Address Trap!\n"); + printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n"); siginfo.si_signo = SIGILL; siginfo.si_errno = 0; siginfo.si_flags = 0; diff -urN linux-2.4.21/arch/ia64/kernel/efi.c linux-2.4.22/arch/ia64/kernel/efi.c --- linux-2.4.21/arch/ia64/kernel/efi.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/efi.c 2003-08-25 04:44:39.000000000 -0700 @@ -5,7 +5,7 @@ * * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond - * Copyright (C) 1999-2002 Hewlett-Packard Co. + * Copyright (C) 1999-2003 Hewlett-Packard Co. * David Mosberger-Tang * Stephane Eranian * @@ -365,7 +365,7 @@ prev_valid = 1; } else { if (curr.start < prev.start) - printk("Oops: EFI memory table not ordered!\n"); + printk(KERN_ERR "Oops: EFI memory table not ordered!\n"); if (prev.end == curr.start) { /* merge two consecutive memory ranges */ @@ -437,7 +437,8 @@ * dedicated ITR for the PAL code. */ if ((vaddr & mask) == (KERNEL_START & mask)) { - printk("%s: no need to install ITR for PAL code\n", __FUNCTION__); + printk(KERN_INFO "%s: no need to install ITR for PAL code\n", + __FUNCTION__); continue; } @@ -445,7 +446,7 @@ panic("Woah! PAL code size bigger than a granule!"); mask = ~((1 << IA64_GRANULE_SHIFT) - 1); - printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", + printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE); @@ -488,7 +489,7 @@ } } if (mem_limit != ~0UL) - printk("Ignoring memory above %luMB\n", mem_limit >> 20); + printk(KERN_INFO "Ignoring memory above %luMB\n", mem_limit >> 20); efi.systab = __va(ia64_boot_param->efi_systab); @@ -500,7 +501,7 @@ if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) panic("Woah! EFI system table signature incorrect\n"); if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0) - printk("Warning: EFI system table major version mismatch: " + printk(KERN_WARNING "Warning: EFI system table major version mismatch: " "got %d.%02d, expected %d.%02d\n", efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff); @@ -515,7 +516,7 @@ vendor[i] = '\0'; } - printk("EFI v%u.%.02u by %s:", + printk(KERN_INFO "EFI v%u.%.02u by %s:", efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); for (i = 0; i < efi.systab->nr_tables; i++) { @@ -607,7 +608,7 @@ | _PAGE_PL_0 | _PAGE_AR_RW)); #else - printk("EFI_MEMORY_WC mapping\n"); + printk(KERN_INFO "EFI_MEMORY_WC mapping\n"); md->virt_addr = (u64) ioremap(md->phys_addr, 0); #endif } else if (md->attribute & EFI_MEMORY_WT) { @@ -617,7 +618,7 @@ | _PAGE_PL_0 | _PAGE_AR_RW)); #else - printk("EFI_MEMORY_WT mapping\n"); + printk(KERN_INFO "EFI_MEMORY_WT mapping\n"); md->virt_addr = (u64) ioremap(md->phys_addr, 0); #endif } @@ -629,7 +630,7 @@ efi_desc_size, ia64_boot_param->efi_memdesc_version, ia64_boot_param->efi_memmap); if (status != EFI_SUCCESS) { - printk("Warning: unable to switch EFI into virtual mode (status=0x%lx)\n", status); + printk(KERN_WARNING "warning: unable to switch EFI into virtual mode (status=0x%lx)\n", status); return; } diff -urN linux-2.4.21/arch/ia64/kernel/efivars.c linux-2.4.22/arch/ia64/kernel/efivars.c --- linux-2.4.21/arch/ia64/kernel/efivars.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/kernel/efivars.c 2003-08-25 04:44:39.000000000 -0700 @@ -29,6 +29,9 @@ * * Changelog: * + * 10 Dec 2002 - Matt Domsch + * fix locking per Peter Chubb's findings + * * 25 Mar 2002 - Matt Domsch * move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse() * @@ -73,7 +76,7 @@ MODULE_DESCRIPTION("/proc interface to EFI Variables"); MODULE_LICENSE("GPL"); -#define EFIVARS_VERSION "0.05 2002-Mar-26" +#define EFIVARS_VERSION "0.06 2002-Dec-10" static int efivar_read(char *page, char **start, off_t off, @@ -106,6 +109,14 @@ struct list_head list; } efivar_entry_t; +/* + efivars_lock protects two things: + 1) efivar_list - adds, removals, reads, writes + 2) efi.[gs]et_variable() calls. + It must not be held when creating proc entries or calling kmalloc. + efi.get_next_variable() is only called from efivars_init(), + which is protected by the BKL, so that path is safe. +*/ static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(efivar_list); static struct proc_dir_entry *efi_vars_dir = NULL; @@ -150,6 +161,7 @@ * variable_name_size = number of bytes required to hold * variable_name (not counting the NULL * character at the end. + * efivars_lock is not held on entry or exit. * Returns 1 on failure, 0 on success */ static int @@ -157,13 +169,14 @@ efi_char16_t *variable_name, efi_guid_t *vendor_guid) { - int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; - char *short_name = kmalloc(short_name_size+1, - GFP_KERNEL); - efivar_entry_t *new_efivar = kmalloc(sizeof(efivar_entry_t), - GFP_KERNEL); + char *short_name; + efivar_entry_t *new_efivar; + + short_name = kmalloc(short_name_size+1, GFP_KERNEL); + new_efivar = kmalloc(sizeof(efivar_entry_t), GFP_KERNEL); + if (!short_name || !new_efivar) { if (short_name) kfree(short_name); if (new_efivar) kfree(new_efivar); @@ -188,19 +201,18 @@ *(short_name + strlen(short_name)) = '-'; efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); - /* Create the entry in proc */ new_efivar->entry = create_proc_entry(short_name, 0600, efi_vars_dir); kfree(short_name); short_name = NULL; if (!new_efivar->entry) return 1; - new_efivar->entry->data = new_efivar; new_efivar->entry->read_proc = efivar_read; new_efivar->entry->write_proc = efivar_write; + spin_lock(&efivars_lock); list_add(&new_efivar->list, &efivar_list); - + spin_unlock(&efivars_lock); return 0; } @@ -326,6 +338,8 @@ kfree(efivar); } + spin_unlock(&efivars_lock); + /* If this is a new variable, set up the proc entry for it. */ if (!found) { efivar_create_proc_entry(utf8_strsize(var_data->VariableName, @@ -336,36 +350,96 @@ kfree(var_data); MOD_DEC_USE_COUNT; - spin_unlock(&efivars_lock); return size; } +/* + * The EFI system table contains pointers to the SAL system table, + * HCDP, ACPI, SMBIOS, etc, that may be useful to applications. + */ +static ssize_t +efi_systab_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + void *data; + u8 *proc_buffer; + ssize_t size, length; + int ret; + const int max_nr_entries = 7; /* num ptrs to tables we could expose */ + const int max_line_len = 80; + + if (!efi.systab) + return 0; + + proc_buffer = kmalloc(max_nr_entries * max_line_len, GFP_KERNEL); + if (!proc_buffer) + return -ENOMEM; + + length = 0; + if (efi.mps) + length += sprintf(proc_buffer + length, "MPS=0x%lx\n", __pa(efi.mps)); + if (efi.acpi20) + length += sprintf(proc_buffer + length, "ACPI20=0x%lx\n", __pa(efi.acpi20)); + if (efi.acpi) + length += sprintf(proc_buffer + length, "ACPI=0x%lx\n", __pa(efi.acpi)); + if (efi.smbios) + length += sprintf(proc_buffer + length, "SMBIOS=0x%lx\n", __pa(efi.smbios)); + if (efi.sal_systab) + length += sprintf(proc_buffer + length, "SAL=0x%lx\n", __pa(efi.sal_systab)); + if (efi.hcdp) + length += sprintf(proc_buffer + length, "HCDP=0x%lx\n", __pa(efi.hcdp)); + if (efi.boot_info) + length += sprintf(proc_buffer + length, "BOOTINFO=0x%lx\n", __pa(efi.boot_info)); + + if (*ppos >= length) { + ret = 0; + goto out; + } + data = proc_buffer + file->f_pos; + size = length - file->f_pos; + if (size > count) + size = count; + if (copy_to_user(buffer, data, size)) { + ret = -EFAULT; + goto out; + } + + *ppos += size; + ret = size; + +out: + kfree(proc_buffer); + return ret; +} + +static struct proc_dir_entry *efi_systab_entry; +static struct file_operations efi_systab_fops = { + .read = efi_systab_read, +}; static int __init efivars_init(void) { - efi_status_t status; efi_guid_t vendor_guid; efi_char16_t *variable_name = kmalloc(1024, GFP_KERNEL); unsigned long variable_name_size = 1024; - spin_lock(&efivars_lock); - printk(KERN_INFO "EFI Variables Facility v%s\n", EFIVARS_VERSION); - /* Since efi.c happens before procfs is available, - we create the directory here if it doesn't - already exist. There's probably a better way - to do this. - */ - if (!efi_dir) + /* Since efi.c happens before procfs is available, + we create the directory here if it doesn't + already exist. There's probably a better way + to do this. + */ + if (!efi_dir) efi_dir = proc_mkdir("efi", NULL); - efi_vars_dir = proc_mkdir("vars", efi_dir); - + efi_systab_entry = create_proc_entry("systab", S_IRUSR | S_IRGRP, efi_dir); + if (efi_systab_entry) + efi_systab_entry->proc_fops = &efi_systab_fops; + efi_vars_dir = proc_mkdir("vars", efi_dir); /* Per EFI spec, the maximum storage allocated for both the variable name and variable data is 1024 bytes. @@ -398,7 +472,6 @@ } while (status != EFI_NOT_FOUND); kfree(variable_name); - spin_unlock(&efivars_lock); return 0; } @@ -409,16 +482,17 @@ efivar_entry_t *efivar; spin_lock(&efivars_lock); - + if (efi_systab_entry) + remove_proc_entry(efi_systab_entry->name, efi_dir); list_for_each_safe(pos, n, &efivar_list) { efivar = efivar_entry(pos); remove_proc_entry(efivar->entry->name, efi_vars_dir); list_del(&efivar->list); kfree(efivar); } - remove_proc_entry(efi_vars_dir->name, efi_dir); spin_unlock(&efivars_lock); + remove_proc_entry(efi_vars_dir->name, efi_dir); } module_init(efivars_init); diff -urN linux-2.4.21/arch/ia64/kernel/entry.S linux-2.4.22/arch/ia64/kernel/entry.S --- linux-2.4.21/arch/ia64/kernel/entry.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/entry.S 2003-08-25 04:44:39.000000000 -0700 @@ -161,7 +161,7 @@ mov r8=r13 // return pointer to previously running task mov r13=in0 // set "current" pointer ;; -(p6) ssm psr.i // renable psr.i AFTER the ic bit is serialized + ssm psr.i // renable psr.i AFTER the ic bit is serialized DO_LOAD_SWITCH_STACK #ifdef CONFIG_SMP @@ -454,7 +454,14 @@ GLOBAL_ENTRY(ia64_trace_syscall) PT_REGS_UNWIND_INFO(0) +{ /* + * Some versions of gas generate bad unwind info if the first instruction of a + * procedure doesn't go into the first slot of a bundle. This is a workaround. + */ + nop.m 0 + nop.i 0 br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch syscall args +} .ret6: br.call.sptk.many rp=b6 // do the syscall strace_check_retval: cmp.lt p6,p0=r8,r0 // syscall failed? @@ -484,12 +491,19 @@ GLOBAL_ENTRY(ia64_ret_from_clone) PT_REGS_UNWIND_INFO(0) +{ /* + * Some versions of gas generate bad unwind info if the first instruction of a + * procedure doesn't go into the first slot of a bundle. This is a workaround. + */ + nop.m 0 + nop.i 0 /* * We need to call schedule_tail() to complete the scheduling process. * Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the * address of the previously executing task. */ br.call.sptk.many rp=ia64_invoke_schedule_tail +} .ret8: adds r2=IA64_TASK_PTRACE_OFFSET,r13 ;; @@ -652,7 +666,7 @@ * NOTE: alloc, loadrs, and cover can't be predicated. */ (pNonSys) br.cond.dpnt dont_preserve_current_frame - cover // add current frame into dirty partition + cover // add current frame into dirty partition and set cr.ifs ;; mov r19=ar.bsp // get new backing store pointer sub r16=r16,r18 // krbs = old bsp - size of dirty partition @@ -678,24 +692,12 @@ # define Nregs 14 #endif alloc loc0=ar.pfs,2,Nregs-2,2,0 - shr.u loc1=r18,9 // RNaTslots <= dirtySize / (64*8) + 1 + shr.u loc1=r18,9 // RNaTslots <= floor(dirtySize / (64*8)) sub r17=r17,r18 // r17 = (physStackedSize + 8) - dirtySize ;; -#if 1 - .align 32 // see comment below about gas bug... -#endif mov ar.rsc=r19 // load ar.rsc to be used for "loadrs" shladd in0=loc1,3,r17 mov in1=0 -#if 0 - // gas-2.11.90 is unable to generate a stop bit after .align, which is bad, - // because alloc must be at the beginning of an insn-group. - .align 32 -#else - nop 0 - nop 0 - nop 0 -#endif ;; rse_clear_invalid: #ifdef CONFIG_ITANIUM @@ -737,13 +739,13 @@ ;; mov loc3=0 mov loc4=0 - mov loc9=0 mov loc5=0 mov loc6=0 + mov loc7=0 (pRecurse) br.call.sptk.many b6=rse_clear_invalid ;; - mov loc7=0 mov loc8=0 + mov loc9=0 cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret mov loc10=0 mov loc11=0 @@ -848,13 +850,14 @@ mov r9=ar.unat mov loc0=rp // save return address mov out0=0 // there is no "oldset" - adds out1=0,sp // out1=&sigscratch + adds out1=8,sp // out1=&sigscratch->ar_pfs (pSys) mov out2=1 // out2==1 => we're in a syscall ;; (pNonSys) mov out2=0 // out2==0 => not a syscall .fframe 16 .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) st8 [sp]=r9,-16 // allocate space for ar.unat and save it + st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch .body br.call.sptk.many rp=ia64_do_signal .ret15: .restore sp @@ -875,11 +878,12 @@ mov loc0=rp // save return address mov out0=in0 // mask mov out1=in1 // sigsetsize - adds out2=0,sp // out2=&sigscratch + adds out2=8,sp // out2=&sigscratch->ar_pfs ;; .fframe 16 .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) st8 [sp]=r9,-16 // allocate space for ar.unat and save it + st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch .body br.call.sptk.many rp=ia64_rt_sigsuspend .ret17: .restore sp @@ -915,17 +919,16 @@ END(sys_rt_sigreturn) GLOBAL_ENTRY(ia64_prepare_handle_unaligned) - // - // r16 = fake ar.pfs, we simply need to make sure - // privilege is still 0 - // - mov r16=r0 .prologue + /* + * r16 = fake ar.pfs, we simply need to make sure privilege is still 0 + */ + mov r16=r0 DO_SAVE_SWITCH_STACK - br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt + br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt .ret21: .body DO_LOAD_SWITCH_STACK - br.cond.sptk.many rp // goes to ia64_leave_kernel + br.cond.sptk.many rp // goes to ia64_leave_kernel END(ia64_prepare_handle_unaligned) // diff -urN linux-2.4.21/arch/ia64/kernel/gate.S linux-2.4.22/arch/ia64/kernel/gate.S --- linux-2.4.21/arch/ia64/kernel/gate.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/gate.S 2003-08-25 04:44:39.000000000 -0700 @@ -63,15 +63,19 @@ * call stack. */ +#define SIGTRAMP_SAVES \ + .unwabi @svr4, 's'; /* mark this as a sigtramp handler (saves scratch regs) */ \ + .savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF; \ + .savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF; \ + .savesp pr, PR_OFF+SIGCONTEXT_OFF; \ + .savesp rp, RP_OFF+SIGCONTEXT_OFF; \ + .savesp ar.pfs, CFM_OFF+SIGCONTEXT_OFF; \ + .vframesp SP_OFF+SIGCONTEXT_OFF + GLOBAL_ENTRY(ia64_sigtramp) // describe the state that is active when we get here: .prologue - .unwabi @svr4, 's' // mark this as a sigtramp handler (saves scratch regs) - .savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF - .savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF - .savesp pr, PR_OFF+SIGCONTEXT_OFF - .savesp rp, RP_OFF+SIGCONTEXT_OFF - .vframesp SP_OFF+SIGCONTEXT_OFF + SIGTRAMP_SAVES .body .label_state 1 @@ -89,9 +93,7 @@ .spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF (p8) br.cond.spnt setup_rbs // yup -> (clobbers r14, r15, and r16) back_from_setup_rbs: - - .spillreg ar.pfs, r8 - alloc r8=ar.pfs,0,0,3,0 // get CFM0, EC0, and CPL0 into r8 + alloc r8=ar.pfs,0,0,3,0 ld8 out0=[base0],16 // load arg0 (signum) adds base1=(ARG1_OFF-(RBS_BASE_OFF+SIGCONTEXT_OFF)),base1 ;; @@ -100,17 +102,12 @@ ;; ld8 out2=[base0] // load arg2 (sigcontextp) ld8 gp=[r17] // get signal handler's global pointer - adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp ;; .spillsp ar.bsp, BSP_OFF+SIGCONTEXT_OFF - st8 [base0]=r9,(CFM_OFF-BSP_OFF) // save sc_ar_bsp - dep r8=0,r8,38,26 // clear EC0, CPL0 and reserved bits - adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp - ;; - .spillsp ar.pfs, CFM_OFF+SIGCONTEXT_OFF - st8 [base0]=r8 // save CFM0 + st8 [base0]=r9 // save sc_ar_bsp adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp + adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp ;; stf.spill [base0]=f6,32 stf.spill [base1]=f7,32 @@ -133,7 +130,6 @@ ld8 r15=[base0],(CFM_OFF-BSP_OFF) // fetch sc_ar_bsp and advance to CFM_OFF mov r14=ar.bsp ;; - ld8 r8=[base0] // restore (perhaps modified) CFM0, EC0, and CPL0 cmp.ne p8,p0=r14,r15 // do we need to restore the rbs? (p8) br.cond.spnt restore_rbs // yup -> (clobbers r14-r18, f6 & f7) ;; @@ -156,10 +152,11 @@ ldf.fill f14=[base0],32 ldf.fill f15=[base1],32 mov r15=__NR_rt_sigreturn + .restore sp // pop .prologue break __BREAK_SYSCALL - .body - .copy_state 1 + .prologue + SIGTRAMP_SAVES setup_rbs: mov ar.rsc=0 // put RSE into enforced lazy mode ;; @@ -171,6 +168,7 @@ ;; .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF st8 [r14]=r16 // save sc_ar_rnat + .body adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16 @@ -182,10 +180,11 @@ ;; st8 [r14]=r15 // save sc_loadrs mov ar.rsc=0xf // set RSE into eager mode, pl 3 + .restore sp // pop .prologue br.cond.sptk back_from_setup_rbs .prologue - .copy_state 1 + SIGTRAMP_SAVES .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF .body restore_rbs: diff -urN linux-2.4.21/arch/ia64/kernel/ia64_ksyms.c linux-2.4.22/arch/ia64/kernel/ia64_ksyms.c --- linux-2.4.21/arch/ia64/kernel/ia64_ksyms.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/ia64_ksyms.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,6 +4,9 @@ #include #include +#include +EXPORT_SYMBOL(pm_idle); + #include EXPORT_SYMBOL_NOVERS(memset); @@ -47,6 +50,7 @@ EXPORT_SYMBOL(__ia64_memcpy_fromio); EXPORT_SYMBOL(__ia64_memcpy_toio); EXPORT_SYMBOL(__ia64_memset_c_io); +EXPORT_SYMBOL(io_space); #include EXPORT_SYMBOL_NOVERS(__down); diff -urN linux-2.4.21/arch/ia64/kernel/iosapic.c linux-2.4.22/arch/ia64/kernel/iosapic.c --- linux-2.4.21/arch/ia64/kernel/iosapic.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/iosapic.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * Copyright (C) 1999 Intel Corp. * Copyright (C) 1999 Asit Mallick * Copyright (C) 2000-2002 J.I. Lee - * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co. + * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co. * David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999,2000 Walt Drummond @@ -28,6 +28,9 @@ * 02/07/29 T. Kochi Allocate interrupt vectors dynamically * 02/08/04 T. Kochi Cleaned up terminology (irq, global system interrupt, vector, etc.) * 02/08/13 B. Helgaas Support PCI segments + * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC. + * Remove iosapic_address & gsi_base from external interfaces. + * Rationalize __init/__devinit attributes. */ /* * Here is what the interrupt logic between a PCI device and the CPU looks like: @@ -63,14 +66,14 @@ */ #include -#include +#include #include +#include +#include #include #include #include #include -#include -#include #include #include @@ -83,7 +86,6 @@ #undef DEBUG_INTERRUPT_ROUTING -#undef OVERRIDE_DEBUG #ifdef DEBUG_INTERRUPT_ROUTING #define DBG(fmt...) printk(fmt) @@ -115,23 +117,26 @@ char *addr; /* base address of IOSAPIC */ unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ unsigned short num_rte; /* number of RTE in this IOSAPIC */ - unsigned char pcat_compat; /* 8259 compatibility flag */ -} iosapic_lists[256] __devinitdata; +} iosapic_lists[256]; -static int __devinitdata num_iosapic = 0; +static int num_iosapic; + +static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */ /* * Find an IOSAPIC associated with a GSI */ -static inline int __devinit +static inline int find_iosapic (unsigned int gsi) { int i; - for (i = 0; i < num_iosapic; i++) + for (i = 0; i < num_iosapic; i++) { if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) return i; + } + return -1; } @@ -159,6 +164,8 @@ int rte_index; char redir; + DBG(KERN_DEBUG "IOSAPIC: routing vector %d to 0x%x\n", vector, dest); + rte_index = iosapic_intr_info[vector].rte_index; if (rte_index < 0) return; /* not an IOSAPIC interrupt */ @@ -171,7 +178,7 @@ redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0; #ifdef CONFIG_SMP { - int irq; + unsigned int irq; for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vector) { @@ -333,14 +340,14 @@ #define iosapic_ack_level_irq nop struct hw_interrupt_type irq_type_iosapic_level = { - typename: "IO-SAPIC-level", - startup: iosapic_startup_level_irq, - shutdown: iosapic_shutdown_level_irq, - enable: iosapic_enable_level_irq, - disable: iosapic_disable_level_irq, - ack: iosapic_ack_level_irq, - end: iosapic_end_level_irq, - set_affinity: iosapic_set_affinity + .typename = "IO-SAPIC-level", + .startup = iosapic_startup_level_irq, + .shutdown = iosapic_shutdown_level_irq, + .enable = iosapic_enable_level_irq, + .disable = iosapic_disable_level_irq, + .ack = iosapic_ack_level_irq, + .end = iosapic_end_level_irq, + .set_affinity = iosapic_set_affinity }; /* @@ -377,14 +384,14 @@ #define iosapic_end_edge_irq nop struct hw_interrupt_type irq_type_iosapic_edge = { - typename: "IO-SAPIC-edge", - startup: iosapic_startup_edge_irq, - shutdown: iosapic_disable_edge_irq, - enable: iosapic_enable_edge_irq, - disable: iosapic_disable_edge_irq, - ack: iosapic_ack_edge_irq, - end: iosapic_end_edge_irq, - set_affinity: iosapic_set_affinity + .typename = "IO-SAPIC-edge", + .startup = iosapic_startup_edge_irq, + .shutdown = iosapic_disable_edge_irq, + .enable = iosapic_enable_edge_irq, + .disable = iosapic_disable_edge_irq, + .ack = iosapic_ack_edge_irq, + .end = iosapic_end_edge_irq, + .set_affinity = iosapic_set_affinity }; unsigned int @@ -407,7 +414,7 @@ * if the given vector is already owned by other, * assign a new vector for the other and make the vector available */ -static void +static void __init iosapic_reassign_vector (int vector) { int new_vector; @@ -417,67 +424,52 @@ || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger) { new_vector = ia64_alloc_vector(); - printk("Reassigning Vector %d to %d\n", vector, new_vector); - memcpy (&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], - sizeof(struct iosapic_intr_info)); - memset (&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); + printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); + memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], + sizeof(struct iosapic_intr_info)); + memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); iosapic_intr_info[vector].rte_index = -1; } } static void register_intr (unsigned int gsi, int vector, unsigned char delivery, - unsigned long polarity, unsigned long edge_triggered, - unsigned int gsi_base, char *iosapic_address) + unsigned long polarity, unsigned long trigger) { irq_desc_t *idesc; struct hw_interrupt_type *irq_type; int rte_index; + int index; + unsigned long gsi_base; + char *iosapic_address; + + index = find_iosapic(gsi); + if (index < 0) { + printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi); + return; + } + + iosapic_address = iosapic_lists[index].addr; + gsi_base = iosapic_lists[index].gsi_base; rte_index = gsi - gsi_base; iosapic_intr_info[vector].rte_index = rte_index; - iosapic_intr_info[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW; + iosapic_intr_info[vector].polarity = polarity; iosapic_intr_info[vector].dmode = delivery; + iosapic_intr_info[vector].addr = iosapic_address; + iosapic_intr_info[vector].gsi_base = gsi_base; + iosapic_intr_info[vector].trigger = trigger; - /* - * In override, it may not provide addr/gsi_base. GSI is enough to - * locate iosapic addr, gsi_base and rte_index by examining - * gsi_base and num_rte of registered iosapics (tbd) - */ -#ifndef OVERRIDE_DEBUG - if (iosapic_address) { - iosapic_intr_info[vector].addr = iosapic_address; - iosapic_intr_info[vector].gsi_base = gsi_base; - } -#else - if (iosapic_address) { - if (iosapic_intr_info[vector].addr && (iosapic_intr_info[vector].addr != iosapic_address)) - printk("WARN: %s: diff IOSAPIC ADDRESS for GSI 0x%x, vector %d\n", - __FUNCTION__, gsi, vector); - iosapic_intr_info[vector].addr = iosapic_address; - if (iosapic_intr_info[vector].gsi_base && (iosapic_intr_info[vector].gsi_base != gsi_base)) { - printk("WARN: %s: diff GSI base 0x%x for GSI 0x%x, vector %d\n", - __FUNCTION__, gsi_base, gsi, vector); - } - iosapic_intr_info[vector].gsi_base = gsi_base; - } else if (!iosapic_intr_info[vector].addr) - printk("WARN: %s: invalid override for GSI 0x%x, vector %d\n", - __FUNCTION__, gsi, vector); -#endif - if (edge_triggered) { - iosapic_intr_info[vector].trigger = IOSAPIC_EDGE; + if (trigger == IOSAPIC_EDGE) irq_type = &irq_type_iosapic_edge; - } else { - iosapic_intr_info[vector].trigger = IOSAPIC_LEVEL; + else irq_type = &irq_type_iosapic_level; - } idesc = irq_desc(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) - printk("%s: changing vector %d from %s to %s\n", - __FUNCTION__, vector, idesc->handler->typename, - irq_type->typename); + printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", + __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); idesc->handler = irq_type; } } @@ -489,8 +481,7 @@ */ int iosapic_register_intr (unsigned int gsi, - unsigned long polarity, unsigned long edge_triggered, - unsigned int gsi_base, char *iosapic_address) + unsigned long polarity, unsigned long trigger) { int vector; unsigned int dest = (ia64_get_lid() >> 16) & 0xffff; @@ -500,11 +491,11 @@ vector = ia64_alloc_vector(); register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, - polarity, edge_triggered, gsi_base, iosapic_address); + polarity, trigger); - printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", - gsi, (polarity ? "high" : "low"), - (edge_triggered ? "edge" : "level"), dest, vector); + printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", + gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), + (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector); /* program the IOSAPIC routing table */ set_rte(vector, dest); @@ -515,11 +506,10 @@ * ACPI calls this when it finds an entry for a platform interrupt. * Note that the irq_base and IOSAPIC address must be set in iosapic_init(). */ -int +int __init iosapic_register_platform_intr (u32 int_type, unsigned int gsi, int iosapic_vector, u16 eid, u16 id, - unsigned long polarity, unsigned long edge_triggered, - unsigned int gsi_base, char *iosapic_address) + unsigned long polarity, unsigned long trigger) { unsigned char delivery; int vector; @@ -544,17 +534,16 @@ delivery = IOSAPIC_LOWEST_PRIORITY; break; default: - printk("%s: invalid interrupt type (%d)\n", __FUNCTION__, + printk(KERN_ERR "%s: invalid interrupt type (%d)\n", __FUNCTION__, int_type); return -1; } - register_intr(gsi, vector, delivery, polarity, - edge_triggered, gsi_base, iosapic_address); + register_intr(gsi, vector, delivery, polarity, trigger); - printk("PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", - int_type, gsi, (polarity ? "high" : "low"), - (edge_triggered ? "edge" : "level"), dest, vector); + printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", + int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), + (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector); /* program the IOSAPIC routing table */ set_rte(vector, dest); @@ -566,32 +555,20 @@ * ACPI calls this when it finds an entry for a legacy ISA IRQ override. * Note that the gsi_base and IOSAPIC address must be set in iosapic_init(). */ -void +void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, - unsigned long polarity, unsigned long edge_triggered) + unsigned long polarity, unsigned long trigger) { - int index, vector; - unsigned int gsi_base; - char *addr; + int vector; unsigned int dest = (ia64_get_lid() >> 16) & 0xffff; - index = find_iosapic(gsi); - - if (index < 0) { - printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", isa_irq, gsi); - return; - } - vector = isa_irq_to_vector(isa_irq); - addr = iosapic_lists[index].addr; - gsi_base = iosapic_lists[index].gsi_base; - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered, - gsi_base, addr); + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); - DBG("ISA: IRQ %u -> GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", + DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n", isa_irq, gsi, - polarity ? "high" : "low", edge_triggered ? "edge" : "level", + polarity == IOSAPIC_POL_HIGH ? "high" : "low", trigger == IOSAPIC_EDGE ? "edge" : "level", dest, vector); /* program the IOSAPIC routing table */ @@ -624,13 +601,11 @@ static int pci_pin_to_vector (int segment, int bus, int slot, int pci_pin) { - int index, vector; - int gsi_base, pcat_compat; - char *addr; + int vector; unsigned int gsi; if (pci_pin_to_gsi(segment, bus, slot, pci_pin, &gsi) < 0) { - printk("PCI: no interrupt route for %02x:%02x:%02x pin %c\n", + printk(KERN_ERR "PCI: no interrupt route for %02x:%02x:%02x pin %c\n", segment, bus, slot, 'A' + pci_pin); return -1; } @@ -638,19 +613,7 @@ vector = gsi_to_vector(gsi); if (vector < 0) { - /* we should allocate a vector for this interrupt line */ - - index = find_iosapic(gsi); - - if (index < 0) { - printk("PCI: GSI 0x%x has no IOSAPIC mapping\n", gsi); - return -1; - } - - addr = iosapic_lists[index].addr; - gsi_base = iosapic_lists[index].gsi_base; - pcat_compat = iosapic_lists[index].pcat_compat; - + /* allocate a vector for this interrupt line */ if (pcat_compat && (gsi < 16)) vector = isa_irq_to_vector(gsi); else { @@ -658,8 +621,7 @@ vector = ia64_alloc_vector(); } - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, - 0, 0, gsi_base, addr); + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, IOSAPIC_LEVEL); DBG("PCI: (%02x:%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n", segment, bus, slot, 'A' + pci_pin, gsi, vector); @@ -668,29 +630,32 @@ return vector; } -void __devinit -iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat) +void __init +iosapic_system_init (int system_pcat_compat) { - int num_rte, vector; - unsigned int isa_irq, ver; - char *addr; - static int first_time = 1; + int vector; - if (first_time) { - first_time = 0; - for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) - iosapic_intr_info[vector].rte_index = -1; /* mark as unused */ - } + for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) + iosapic_intr_info[vector].rte_index = -1; /* mark as unused */ + pcat_compat = system_pcat_compat; if (pcat_compat) { /* * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support * enabled. */ - printk("%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); + printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); outb(0xff, 0xA1); outb(0xff, 0x21); } +} + +void __init +iosapic_init (unsigned long phys_addr, unsigned int gsi_base) +{ + int num_rte; + unsigned int isa_irq, ver; + char *addr; addr = ioremap(phys_addr, 0); ver = iosapic_version(addr); @@ -703,35 +668,22 @@ num_rte = ((ver >> 16) & 0xff) + 1; iosapic_lists[num_iosapic].addr = addr; - iosapic_lists[num_iosapic].pcat_compat = pcat_compat; iosapic_lists[num_iosapic].gsi_base = gsi_base; iosapic_lists[num_iosapic].num_rte = num_rte; num_iosapic++; - printk("IOSAPIC: version %x.%x, address 0x%lx, GSIs 0x%x-0x%x\n", + printk(KERN_INFO " IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n", (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1); if ((gsi_base == 0) && pcat_compat) { - unsigned int dest = (ia64_get_lid() >> 16) & 0xffff; /* * Map the legacy ISA devices into the IOSAPIC data. Some of these may * get reprogrammed later on with data from the ACPI Interrupt Source * Override table. */ - for (isa_irq = 0; isa_irq < 16; ++isa_irq) { - vector = isa_irq_to_vector(isa_irq); - - register_intr(isa_irq, vector, IOSAPIC_LOWEST_PRIORITY, - /* IOSAPIC_POL_HIGH, IOSAPIC_EDGE */ - 1, 1, gsi_base, addr); - - DBG("ISA: IRQ %u -> GSI 0x%x (high,edge) -> CPU 0x%04x vector %d\n", - isa_irq, isa_irq, dest, vector); - - /* program the IOSAPIC routing table: */ - set_rte(vector, dest); - } + for (isa_irq = 0; isa_irq < 16; ++isa_irq) + iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } } @@ -790,7 +742,7 @@ idesc = irq_desc(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) - printk("%s: changing vector %d from %s to %s\n", + printk(KERN_INFO "%s: changing vector %d from %s to %s\n", __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); @@ -822,7 +774,7 @@ dest = (ia64_get_lid() >> 16) & 0xffff; #endif - printk("PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n", + printk(KERN_INFO "PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n", dev->slot_name, 'A' + pci_pin, dest, vector); set_rte(vector, dest); } @@ -837,7 +789,7 @@ if (phase == 0) { if (0 != acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) { - printk("%s: acpi_get_prt failed\n", __FUNCTION__); + printk(KERN_ERR "%s: acpi_get_prt failed\n", __FUNCTION__); } return; } diff -urN linux-2.4.21/arch/ia64/kernel/irq.c linux-2.4.22/arch/ia64/kernel/irq.c --- linux-2.4.21/arch/ia64/kernel/irq.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -111,7 +111,7 @@ * a generic callback i think. */ #if CONFIG_X86 - printk("unexpected IRQ trap at vector %02x\n", irq); + printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq); #ifdef CONFIG_X86_LOCAL_APIC /* * Currently unexpected vectors happen only on SMP and APIC. @@ -125,7 +125,7 @@ #endif #endif #if CONFIG_IA64 - printk("Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id()); + printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id()); #endif } @@ -591,7 +591,7 @@ desc->depth--; break; case 0: - printk("enable_irq(%u) unbalanced from %p\n", + printk(KERN_ERR "enable_irq(%u) unbalanced from %p\n", irq, (void *) __builtin_return_address(0)); } spin_unlock_irqrestore(&desc->lock, flags); @@ -738,7 +738,7 @@ */ if (irqflags & SA_SHIRQ) { if (!dev_id) - printk("Bad boy: %s called us without a dev_id!\n", devname); + printk(KERN_ERR "Bad boy: %s called us without a dev_id!\n", devname); } #endif @@ -819,7 +819,7 @@ kfree(action); return; } - printk("Trying to free free IRQ%d\n",irq); + printk(KERN_ERR "Trying to free free IRQ%d\n",irq); spin_unlock_irqrestore(&desc->lock,flags); return; } diff -urN linux-2.4.21/arch/ia64/kernel/irq_ia64.c linux-2.4.22/arch/ia64/kernel/irq_ia64.c --- linux-2.4.21/arch/ia64/kernel/irq_ia64.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/irq_ia64.c 2003-08-25 04:44:39.000000000 -0700 @@ -148,9 +148,9 @@ extern void handle_IPI (int irq, void *dev_id, struct pt_regs *regs); static struct irqaction ipi_irqaction = { - handler: handle_IPI, - flags: SA_INTERRUPT, - name: "IPI" + .handler = handle_IPI, + .flags = SA_INTERRUPT, + .name = "IPI" }; #endif diff -urN linux-2.4.21/arch/ia64/kernel/irq_lsapic.c linux-2.4.22/arch/ia64/kernel/irq_lsapic.c --- linux-2.4.21/arch/ia64/kernel/irq_lsapic.c 2001-07-31 10:30:08.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/irq_lsapic.c 2003-08-25 04:44:39.000000000 -0700 @@ -27,12 +27,12 @@ } struct hw_interrupt_type irq_type_ia64_lsapic = { - typename: "LSAPIC", - startup: lsapic_noop_startup, - shutdown: lsapic_noop, - enable: lsapic_noop, - disable: lsapic_noop, - ack: lsapic_noop, - end: lsapic_noop, - set_affinity: (void (*)(unsigned int, unsigned long)) lsapic_noop + .typename = "LSAPIC", + .startup = lsapic_noop_startup, + .shutdown = lsapic_noop, + .enable = lsapic_noop, + .disable = lsapic_noop, + .ack = lsapic_noop, + .end = lsapic_noop, + .set_affinity = (void (*)(unsigned int, unsigned long)) lsapic_noop }; diff -urN linux-2.4.21/arch/ia64/kernel/machvec.c linux-2.4.22/arch/ia64/kernel/machvec.c --- linux-2.4.21/arch/ia64/kernel/machvec.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/machvec.c 2003-08-25 04:44:39.000000000 -0700 @@ -44,7 +44,7 @@ panic("generic kernel failed to find machine vector for platform %s!", name); } ia64_mv = *mv; - printk("booting generic kernel on platform %s\n", name); + printk(KERN_INFO "booting generic kernel on platform %s\n", name); } #endif /* CONFIG_IA64_GENERIC */ diff -urN linux-2.4.21/arch/ia64/kernel/mca.c linux-2.4.22/arch/ia64/kernel/mca.c --- linux-2.4.21/arch/ia64/kernel/mca.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/mca.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,9 @@ * Purpose: Generic MCA handling layer * * Updated for latest kernel + * Copyright (C) 2003 Hewlett-Packard Co + * David Mosberger-Tang + * * Copyright (C) 2002 Dell Computer Corporation * Copyright (C) Matt Domsch (Matt_Domsch@dell.com) * @@ -18,6 +21,7 @@ * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) Vijay Chander(vijay@engr.sgi.com) * + * 03/04/15 D. Mosberger Added INIT backtrace support. * 02/03/25 M. Domsch GUID cleanups * * 02/01/04 J. Hall Aligned MCA stack to 16 bytes, added platform vs. CPU @@ -45,7 +49,9 @@ #include #include #include +#include +#include #include #include #include @@ -53,11 +59,14 @@ #include #include +#include #include #include #undef MCA_PRT_XTRA_DATA +#define print_symbol(fmt, addr) printk(fmt, ""); + typedef struct ia64_fptr { unsigned long fp; unsigned long gp; @@ -70,7 +79,7 @@ u64 ia64_mca_stack[1024] __attribute__((aligned(16))); u64 ia64_mca_stackframe[32]; u64 ia64_mca_bspstore[1024]; -u64 ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16))); +u64 ia64_init_stack[INIT_TASK_SIZE/8] __attribute__((aligned(16))); u64 ia64_mca_sal_data_area[1356]; u64 ia64_tlb_functional; u64 ia64_os_mca_recovery_successful; @@ -85,40 +94,50 @@ extern struct hw_interrupt_type irq_type_iosapic_level; static struct irqaction cmci_irqaction = { - handler: ia64_mca_cmc_int_handler, - flags: SA_INTERRUPT, - name: "cmc_hndlr" + .handler = ia64_mca_cmc_int_handler, + .flags = SA_INTERRUPT, + .name = "cmc_hndlr" }; static struct irqaction mca_rdzv_irqaction = { - handler: ia64_mca_rendez_int_handler, - flags: SA_INTERRUPT, - name: "mca_rdzv" + .handler = ia64_mca_rendez_int_handler, + .flags = SA_INTERRUPT, + .name = "mca_rdzv" }; static struct irqaction mca_wkup_irqaction = { - handler: ia64_mca_wakeup_int_handler, - flags: SA_INTERRUPT, - name: "mca_wkup" + .handler = ia64_mca_wakeup_int_handler, + .flags = SA_INTERRUPT, + .name = "mca_wkup" }; static struct irqaction mca_cpe_irqaction = { - handler: ia64_mca_cpe_int_handler, - flags: SA_INTERRUPT, - name: "cpe_hndlr" + .handler = ia64_mca_cpe_int_handler, + .flags = SA_INTERRUPT, + .name = "cpe_hndlr" }; #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */ #define MIN_CPE_POLL_INTERVAL (2*60*HZ) /* 2 minutes */ +#define CMC_POLL_INTERVAL (1*60*HZ) /* 1 minute */ +#define CMC_HISTORY_LENGTH 5 static struct timer_list cpe_poll_timer; +static struct timer_list cmc_poll_timer; +/* + * Start with this in the wrong state so we won't play w/ timers + * before the system is ready. + */ +static int cmc_polling_enabled = 1; + +extern void salinfo_log_wakeup(int); /* * ia64_mca_log_sal_error_record * - * This function retrieves a specified error record type from SAL, sends it to - * the system log, and notifies SALs to clear the record from its non-volatile - * memory. + * This function retrieves a specified error record type from SAL, + * wakes up any processes waiting for error records, and sends it to + * the system log. * * Inputs : sal_info_type (Type of error record MCA/CMC/CPE/INIT) * Outputs : platform error status @@ -130,7 +149,7 @@ /* Get the MCA error record */ if (!ia64_log_get(sal_info_type, (prfunc_t)printk)) - return platform_err; // no record retrieved + return platform_err; /* no record retrieved */ /* TODO: * 1. analyze error logs to determine recoverability @@ -138,11 +157,8 @@ * 3. set ia64_os_mca_recovery_successful flag, if applicable */ + salinfo_log_wakeup(sal_info_type); platform_err = ia64_log_print(sal_info_type, (prfunc_t)printk); - /* temporary: only clear SAL logs on hardware-corrected errors - or if we're logging an error after an MCA-initiated reboot */ - if ((sal_info_type > 1) || (called_from_init)) - ia64_sal_clear_state_info(sal_info_type); return platform_err; } @@ -160,24 +176,174 @@ void ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) { - IA64_MCA_DEBUG("ia64_mca_cpe_int_handler: received interrupt. vector = %#x\n", cpe_irq); + IA64_MCA_DEBUG("ia64_mca_cpe_int_handler: received interrupt. CPU:%d vector = %#x\n", + smp_processor_id(), cpe_irq); /* Get the CMC error record and log it */ ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE, 0); } -/* - * This routine will be used to deal with platform specific handling - * of the init, i.e. drop into the kernel debugger on server machine, - * or if the processor is part of some parallel machine without a - * console, then we would call the appropriate debug hooks here. - */ +static void +show_min_state (pal_min_state_area_t *minstate) +{ + u64 iip = minstate->pmsa_iip + ((struct ia64_psr *)(&minstate->pmsa_ipsr))->ri; + u64 xip = minstate->pmsa_xip + ((struct ia64_psr *)(&minstate->pmsa_xpsr))->ri; + + printk("NaT bits\t%016lx\n", minstate->pmsa_nat_bits); + printk("pr\t\t%016lx\n", minstate->pmsa_pr); + printk("b0\t\t%016lx ", minstate->pmsa_br0); print_symbol("%s\n", minstate->pmsa_br0); + printk("ar.rsc\t\t%016lx\n", minstate->pmsa_rsc); + printk("cr.iip\t\t%016lx ", iip); print_symbol("%s\n", iip); + printk("cr.ipsr\t\t%016lx\n", minstate->pmsa_ipsr); + printk("cr.ifs\t\t%016lx\n", minstate->pmsa_ifs); + printk("xip\t\t%016lx ", xip); print_symbol("%s\n", xip); + printk("xpsr\t\t%016lx\n", minstate->pmsa_xpsr); + printk("xfs\t\t%016lx\n", minstate->pmsa_xfs); + printk("b1\t\t%016lx ", minstate->pmsa_br1); + print_symbol("%s\n", minstate->pmsa_br1); + + printk("\nstatic registers r0-r15:\n"); + printk(" r0- 3 %016lx %016lx %016lx %016lx\n", + 0UL, minstate->pmsa_gr[0], minstate->pmsa_gr[1], minstate->pmsa_gr[2]); + printk(" r4- 7 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_gr[3], minstate->pmsa_gr[4], + minstate->pmsa_gr[5], minstate->pmsa_gr[6]); + printk(" r8-11 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_gr[7], minstate->pmsa_gr[8], + minstate->pmsa_gr[9], minstate->pmsa_gr[10]); + printk("r12-15 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_gr[11], minstate->pmsa_gr[12], + minstate->pmsa_gr[13], minstate->pmsa_gr[14]); + + printk("\nbank 0:\n"); + printk("r16-19 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank0_gr[0], minstate->pmsa_bank0_gr[1], + minstate->pmsa_bank0_gr[2], minstate->pmsa_bank0_gr[3]); + printk("r20-23 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank0_gr[4], minstate->pmsa_bank0_gr[5], + minstate->pmsa_bank0_gr[6], minstate->pmsa_bank0_gr[7]); + printk("r24-27 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank0_gr[8], minstate->pmsa_bank0_gr[9], + minstate->pmsa_bank0_gr[10], minstate->pmsa_bank0_gr[11]); + printk("r28-31 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank0_gr[12], minstate->pmsa_bank0_gr[13], + minstate->pmsa_bank0_gr[14], minstate->pmsa_bank0_gr[15]); + + printk("\nbank 1:\n"); + printk("r16-19 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank1_gr[0], minstate->pmsa_bank1_gr[1], + minstate->pmsa_bank1_gr[2], minstate->pmsa_bank1_gr[3]); + printk("r20-23 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank1_gr[4], minstate->pmsa_bank1_gr[5], + minstate->pmsa_bank1_gr[6], minstate->pmsa_bank1_gr[7]); + printk("r24-27 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank1_gr[8], minstate->pmsa_bank1_gr[9], + minstate->pmsa_bank1_gr[10], minstate->pmsa_bank1_gr[11]); + printk("r28-31 %016lx %016lx %016lx %016lx\n", + minstate->pmsa_bank1_gr[12], minstate->pmsa_bank1_gr[13], + minstate->pmsa_bank1_gr[14], minstate->pmsa_bank1_gr[15]); +} + +static void +fetch_min_state (pal_min_state_area_t *ms, struct pt_regs *pt, struct switch_stack *sw) +{ + u64 *dst_banked, *src_banked, bit, shift, nat_bits; + int i; + + /* + * First, update the pt-regs and switch-stack structures with the contents stored + * in the min-state area: + */ + if (((struct ia64_psr *) &ms->pmsa_ipsr)->ic == 0) { + pt->cr_ipsr = ms->pmsa_xpsr; + pt->cr_iip = ms->pmsa_xip; + pt->cr_ifs = ms->pmsa_xfs; + } else { + pt->cr_ipsr = ms->pmsa_ipsr; + pt->cr_iip = ms->pmsa_iip; + pt->cr_ifs = ms->pmsa_ifs; + } + pt->ar_rsc = ms->pmsa_rsc; + pt->pr = ms->pmsa_pr; + pt->r1 = ms->pmsa_gr[0]; + pt->r2 = ms->pmsa_gr[1]; + pt->r3 = ms->pmsa_gr[2]; + sw->r4 = ms->pmsa_gr[3]; + sw->r5 = ms->pmsa_gr[4]; + sw->r6 = ms->pmsa_gr[5]; + sw->r7 = ms->pmsa_gr[6]; + pt->r8 = ms->pmsa_gr[7]; + pt->r9 = ms->pmsa_gr[8]; + pt->r10 = ms->pmsa_gr[9]; + pt->r11 = ms->pmsa_gr[10]; + pt->r12 = ms->pmsa_gr[11]; + pt->r13 = ms->pmsa_gr[12]; + pt->r14 = ms->pmsa_gr[13]; + pt->r15 = ms->pmsa_gr[14]; + dst_banked = &pt->r16; /* r16-r31 are contiguous in struct pt_regs */ + src_banked = ms->pmsa_bank1_gr; + for (i = 0; i < 16; ++i) + dst_banked[i] = src_banked[i]; + pt->b0 = ms->pmsa_br0; + sw->b1 = ms->pmsa_br1; + + /* construct the NaT bits for the pt-regs structure: */ +# define PUT_NAT_BIT(dst, addr) \ + do { \ + bit = nat_bits & 1; nat_bits >>= 1; \ + shift = ((unsigned long) addr >> 3) & 0x3f; \ + dst = ((dst) & ~(1UL << shift)) | (bit << shift); \ + } while (0) + + /* Rotate the saved NaT bits such that bit 0 corresponds to pmsa_gr[0]: */ + shift = ((unsigned long) &ms->pmsa_gr[0] >> 3) & 0x3f; + nat_bits = (ms->pmsa_nat_bits >> shift) | (ms->pmsa_nat_bits << (64 - shift)); + + PUT_NAT_BIT(sw->caller_unat, &pt->r1); + PUT_NAT_BIT(sw->caller_unat, &pt->r2); + PUT_NAT_BIT(sw->caller_unat, &pt->r3); + PUT_NAT_BIT(sw->ar_unat, &sw->r4); + PUT_NAT_BIT(sw->ar_unat, &sw->r5); + PUT_NAT_BIT(sw->ar_unat, &sw->r6); + PUT_NAT_BIT(sw->ar_unat, &sw->r7); + PUT_NAT_BIT(sw->caller_unat, &pt->r8); PUT_NAT_BIT(sw->caller_unat, &pt->r9); + PUT_NAT_BIT(sw->caller_unat, &pt->r10); PUT_NAT_BIT(sw->caller_unat, &pt->r11); + PUT_NAT_BIT(sw->caller_unat, &pt->r12); PUT_NAT_BIT(sw->caller_unat, &pt->r13); + PUT_NAT_BIT(sw->caller_unat, &pt->r14); PUT_NAT_BIT(sw->caller_unat, &pt->r15); + nat_bits >>= 16; /* skip over bank0 NaT bits */ + PUT_NAT_BIT(sw->caller_unat, &pt->r16); PUT_NAT_BIT(sw->caller_unat, &pt->r17); + PUT_NAT_BIT(sw->caller_unat, &pt->r18); PUT_NAT_BIT(sw->caller_unat, &pt->r19); + PUT_NAT_BIT(sw->caller_unat, &pt->r20); PUT_NAT_BIT(sw->caller_unat, &pt->r21); + PUT_NAT_BIT(sw->caller_unat, &pt->r22); PUT_NAT_BIT(sw->caller_unat, &pt->r23); + PUT_NAT_BIT(sw->caller_unat, &pt->r24); PUT_NAT_BIT(sw->caller_unat, &pt->r25); + PUT_NAT_BIT(sw->caller_unat, &pt->r26); PUT_NAT_BIT(sw->caller_unat, &pt->r27); + PUT_NAT_BIT(sw->caller_unat, &pt->r28); PUT_NAT_BIT(sw->caller_unat, &pt->r29); + PUT_NAT_BIT(sw->caller_unat, &pt->r30); PUT_NAT_BIT(sw->caller_unat, &pt->r31); +} + void -init_handler_platform (struct pt_regs *regs) +init_handler_platform (sal_log_processor_info_t *proc_ptr, + struct pt_regs *pt, struct switch_stack *sw) { + struct unw_frame_info info; + /* if a kernel debugger is available call it here else just dump the registers */ - show_regs(regs); /* dump the state info */ + /* + * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be + * generated via the BMC's command-line interface, but since the console is on the + * same serial line, the user will need some time to switch out of the BMC before + * the dump begins. + */ + printk("Delaying for 5 seconds...\n"); + udelay(5*1000000); + show_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area); + + fetch_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area, pt, sw); + unw_init_from_interruption(&info, current, pt, sw); + ia64_do_show_stack(&info, NULL); + + printk("\nINIT dump complete. Please reboot now.\n"); while (1); /* hang city if no debugger */ } @@ -202,21 +368,22 @@ * ia64_mca_check_errors * * External entry to check for error records which may have been posted by SAL - * for a prior failure which resulted in a machine shutdown before an the - * error could be logged. This function must be called after the filesystem - * is initialized. + * for a prior failure. * * Inputs : None * * Outputs : None */ -void +int ia64_mca_check_errors (void) { /* * If there is an MCA error record pending, get it and log it. */ + printk("CPU %d: checking for saved MCA error records\n", smp_processor_id()); ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA, 1); + + return 0; } /* @@ -234,8 +401,11 @@ ia64_mca_register_cpev (int cpev) { /* Register the CPE interrupt vector with SAL */ - if (ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0)) { - printk("ia64_mca_platform_init: failed to register Corrected " + struct ia64_sal_retval isrv; + + isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0); + if (isrv.status) { + printk(KERN_ERR "ia64_mca_platform_init: failed to register Corrected " "Platform Error interrupt vector with SAL.\n"); return; } @@ -246,26 +416,9 @@ #endif /* PLATFORM_MCA_HANDLERS */ -static char *min_state_labels[] = { - "nat", - "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", - "r9", "r10","r11", "r12","r13","r14", "r15", - "b0r16","b0r17", "b0r18", "b0r19", "b0r20", - "b0r21", "b0r22","b0r23", "b0r24", "b0r25", - "b0r26", "b0r27", "b0r28","b0r29", "b0r30", "b0r31", - "r16", "r17", "r18","r19", "r20", "r21","r22", - "r23", "r24","r25", "r26", "r27","r28", "r29", "r30","r31", - "preds", "br0", "rsc", - "iip", "ipsr", "ifs", - "xip", "xpsr", "xfs" -}; - -int ia64_pmss_dump_bank0=0; /* dump bank 0 ? */ - /* * routine to process and prepare to dump min_state_save * information for debugging purposes. - * */ void ia64_process_min_state_save (pal_min_state_area_t *pmss) @@ -274,30 +427,12 @@ u64 *tpmss_ptr = (u64 *)pmss; u64 *return_min_state_ptr = ia64_mca_min_state_save_info; - /* dump out the min_state_area information */ - for (i=0;i= CMC_HISTORY_LENGTH) { + /* + * CMC threshold exceeded, clear the history + * so we have a fresh start when we return + */ + for (index = 0 ; index < CMC_HISTORY_LENGTH; index++) + cmc_history[index] = 0; + index = 0; + + /* Switch to polling mode */ + cmc_polling_enabled = 1; + + /* + * Unlock & enable interrupts before + * smp_call_function or risk deadlock + */ + spin_unlock(&cmc_history_lock); + ia64_mca_cmc_vector_disable(NULL); + + local_irq_enable(); + smp_call_function(ia64_mca_cmc_vector_disable, NULL, 1, 1); + + /* + * Corrected errors will still be corrected, but + * make sure there's a log somewhere that indicates + * something is generating more than we can handle. + */ + printk(KERN_WARNING "ia64_mca_cmc_int_handler: WARNING: Switching to polling CMC handler, error records may be lost\n"); + + + mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL); + + /* lock already released, get out now */ + return; + } else { + cmc_history[index++] = now; + if (index == CMC_HISTORY_LENGTH) + index = 0; + } + } + spin_unlock(&cmc_history_lock); } /* @@ -797,6 +1054,7 @@ { spinlock_t isl_lock; int isl_index; + unsigned long isl_count; ia64_err_rec_t *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */ } ia64_state_log_t; @@ -813,11 +1071,78 @@ #define IA64_LOG_NEXT_INDEX(it) ia64_state_log[it].isl_index #define IA64_LOG_CURR_INDEX(it) 1 - ia64_state_log[it].isl_index #define IA64_LOG_INDEX_INC(it) \ - ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index + {ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index; \ + ia64_state_log[it].isl_count++;} #define IA64_LOG_INDEX_DEC(it) \ ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index #define IA64_LOG_NEXT_BUFFER(it) (void *)((ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)])) #define IA64_LOG_CURR_BUFFER(it) (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)])) +#define IA64_LOG_COUNT(it) ia64_state_log[it].isl_count + +/* + * ia64_mca_cmc_int_caller + * + * Call CMC interrupt handler, only purpose is to have a + * smp_call_function callable entry. + * + * Inputs : dummy(unused) + * Outputs : None + * */ +static void +ia64_mca_cmc_int_caller(void *dummy) +{ + ia64_mca_cmc_int_handler(0, NULL, NULL); +} + +/* + * ia64_mca_cmc_poll + * + * Poll for Corrected Machine Checks (CMCs) + * + * Inputs : dummy(unused) + * Outputs : None + * + */ +static void +ia64_mca_cmc_poll (unsigned long dummy) +{ + int start_count; + + start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC); + + /* Call the interrupt handler */ + smp_call_function(ia64_mca_cmc_int_caller, NULL, 1, 1); + local_irq_disable(); + ia64_mca_cmc_int_caller(NULL); + local_irq_enable(); + + /* + * If no log recored, switch out of polling mode. + */ + if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) { + printk(KERN_WARNING "ia64_mca_cmc_poll: Returning to interrupt driven CMC handler\n"); + cmc_polling_enabled = 0; + smp_call_function(ia64_mca_cmc_vector_enable, NULL, 1, 1); + ia64_mca_cmc_vector_enable(NULL); + } else { + mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL); + } +} + +/* + * ia64_mca_cpe_int_caller + * + * Call CPE interrupt handler, only purpose is to have a + * smp_call_function callable entry. + * + * Inputs : dummy(unused) + * Outputs : None + * */ +static void +ia64_mca_cpe_int_caller(void *dummy) +{ + ia64_mca_cpe_int_handler(0, NULL, NULL); +} /* * ia64_mca_cpe_poll @@ -832,19 +1157,22 @@ static void ia64_mca_cpe_poll (unsigned long dummy) { - int start_index; + int start_count; static int poll_time = MAX_CPE_POLL_INTERVAL; - start_index = IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE); + start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE); /* Call the interrupt handler */ - ia64_mca_cpe_int_handler(0, NULL, NULL); + smp_call_function(ia64_mca_cpe_int_caller, NULL, 1, 1); + local_irq_disable(); + ia64_mca_cpe_int_caller(NULL); + local_irq_enable(); /* * If a log was recorded, increase our polling frequency, * otherwise, backoff. */ - if (start_index != IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE)) { + if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) { poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time/2); } else { poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2); @@ -865,11 +1193,19 @@ static int __init ia64_mca_late_init(void) { - if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0) { - init_timer(&cpe_poll_timer); - cpe_poll_timer.function = ia64_mca_cpe_poll; - ia64_mca_cpe_poll(0); - } + init_timer(&cmc_poll_timer); + cmc_poll_timer.function = ia64_mca_cmc_poll; + + /* Reset to the correct state */ + cmc_polling_enabled = 0; + + init_timer(&cpe_poll_timer); + cpe_poll_timer.function = ia64_mca_cpe_poll; + + /* If platform doesn't support CPEI, get the timer going. */ + if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0) + ia64_mca_cpe_poll(0UL); + return 0; } @@ -888,12 +1224,12 @@ * */ void -ia64_init_handler (struct pt_regs *regs) +ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw) { sal_log_processor_info_t *proc_ptr; ia64_err_rec_t *plog_ptr; - printk("Entered OS INIT handler\n"); + printk(KERN_INFO "Entered OS INIT handler\n"); /* Get the INIT processor log */ if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk)) @@ -910,12 +1246,9 @@ plog_ptr=(ia64_err_rec_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT); proc_ptr = &plog_ptr->proc_err; - ia64_process_min_state_save(&proc_ptr->processor_static_info.min_state_area); - - /* Clear the INIT SAL logs now that they have been saved in the OS buffer */ - ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT); + ia64_process_min_state_save(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area); - init_handler_platform(regs); /* call platform specific routines */ + init_handler_platform(proc_ptr, pt, sw); /* call platform specific routines */ } /* @@ -1076,12 +1409,12 @@ ia64_log_rec_header_print (sal_log_record_header_t *lh, prfunc_t prfunc) { prfunc("+Err Record ID: %d SAL Rev: %2x.%02x\n", lh->id, - lh->revision.major, lh->revision.minor); - prfunc("+Time: %02x/%02x/%02x%02x %02d:%02d:%02d Severity %d\n", - lh->timestamp.slh_month, lh->timestamp.slh_day, - lh->timestamp.slh_century, lh->timestamp.slh_year, - lh->timestamp.slh_hour, lh->timestamp.slh_minute, - lh->timestamp.slh_second, lh->severity); + lh->revision.major, lh->revision.minor); + prfunc("+Time: %02x/%02x/%02x%02x %02x:%02x:%02x Severity %d\n", + lh->timestamp.slh_month, lh->timestamp.slh_day, + lh->timestamp.slh_century, lh->timestamp.slh_year, + lh->timestamp.slh_hour, lh->timestamp.slh_minute, + lh->timestamp.slh_second, lh->severity); } /* @@ -1704,7 +2037,7 @@ * absent. Also, current implementations only allocate space for number of * elements used. So we walk the data pointer from here on. */ - p_data = &slpi->cache_check_info[0]; + p_data = &slpi->info[0]; /* Print the cache check information if any*/ for (i = 0 ; i < slpi->valid.num_cache_check; i++, p_data++) @@ -1821,8 +2154,7 @@ /* * Now process processor device error record section */ - ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, - printk); + ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, printk); } IA64_MCA_DEBUG("ia64_mca_log_print: " @@ -1965,9 +2297,8 @@ switch(sal_info_type) { case SAL_INFO_TYPE_MCA: - prfunc("+BEGIN HARDWARE ERROR STATE AT MCA\n"); - platform_err = ia64_log_platform_info_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); - prfunc("+END HARDWARE ERROR STATE AT MCA\n"); + prfunc("+CPU %d: SAL log contains MCA error record\n", smp_processor_id()); + ia64_log_rec_header_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); break; case SAL_INFO_TYPE_INIT: prfunc("+MCA INIT ERROR LOG (UNIMPLEMENTED)\n"); diff -urN linux-2.4.21/arch/ia64/kernel/mca_asm.S linux-2.4.22/arch/ia64/kernel/mca_asm.S --- linux-2.4.21/arch/ia64/kernel/mca_asm.S 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/kernel/mca_asm.S 2003-08-25 04:44:39.000000000 -0700 @@ -766,8 +766,6 @@ // stash the information the SAL passed to os SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2) ;; - -// now we want to save information so we can dump registers SAVE_MIN_WITH_COVER ;; mov r8=cr.ifa @@ -798,10 +796,12 @@ // // Let's call the C handler to get the rest of the state info // - alloc r14=ar.pfs,0,0,1,0 // now it's safe (must be first in insn group!) - ;; // + alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!) + ;; adds out0=16,sp // out0 = pointer to pt_regs ;; + DO_SAVE_SWITCH_STACK + adds out1=16,sp // out0 = pointer to switch_stack br.call.sptk.many rp=ia64_init_handler .ret1: diff -urN linux-2.4.21/arch/ia64/kernel/palinfo.c linux-2.4.22/arch/ia64/kernel/palinfo.c --- linux-2.4.21/arch/ia64/kernel/palinfo.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/kernel/palinfo.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,7 +6,7 @@ * Intel IA-64 Architecture Software Developer's Manual v1.0. * * - * Copyright (C) 2000-2001 Hewlett-Packard Co + * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co * Stephane Eranian * * 05/26/2000 S.Eranian initial release @@ -27,9 +27,7 @@ #include #include #include -#ifdef CONFIG_SMP #include -#endif MODULE_AUTHOR("Stephane Eranian "); MODULE_DESCRIPTION("/proc interface to IA-64 PAL"); @@ -37,12 +35,6 @@ #define PALINFO_VERSION "0.5" -#ifdef CONFIG_SMP -#define cpu_is_online(i) (cpu_online_map & (1UL << i)) -#else -#define cpu_is_online(i) 1 -#endif - typedef int (*palinfo_func_t)(char*); typedef struct { @@ -101,26 +93,15 @@ #define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *)) -/* - * The current revision of the Volume 2 (July 2000) of - * IA-64 Architecture Software Developer's Manual is wrong. - * Table 4-10 has invalid information concerning the ma field: - * Correct table is: - * bit 0 - 001 - UC - * bit 4 - 100 - UC - * bit 5 - 101 - UCE - * bit 6 - 110 - WC - * bit 7 - 111 - NatPage - */ static const char *mem_attrib[]={ - "Write Back (WB)", /* 000 */ - "Uncacheable (UC)", /* 001 */ - "Reserved", /* 010 */ - "Reserved", /* 011 */ - "Uncacheable (UC)", /* 100 */ - "Uncacheable Exported (UCE)", /* 101 */ - "Write Coalescing (WC)", /* 110 */ - "NaTPage" /* 111 */ + "WB", /* 000 */ + "SW", /* 001 */ + "010", /* 010 */ + "011", /* 011 */ + "UC", /* 100 */ + "UCE", /* 101 */ + "WC", /* 110 */ + "NaTPage" /* 111 */ }; /* @@ -236,15 +217,12 @@ int i,j, k; s64 status; - if ((status=ia64_pal_cache_summary(&levels, &unique_caches)) != 0) { - printk("ia64_pal_cache_summary=%ld\n", status); - return 0; + if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) { + printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status); + return 0; } - p += sprintf(p, "Cache levels : %ld\n" \ - "Unique caches : %ld\n\n", - levels, - unique_caches); + p += sprintf(p, "Cache levels : %ld\nUnique caches : %ld\n\n", levels, unique_caches); for (i=0; i < levels; i++) { @@ -315,11 +293,12 @@ pal_vm_info_2_u_t vm_info_2; pal_tc_info_u_t tc_info; ia64_ptce_info_t ptce; + const char *sep; int i, j; s64 status; - if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { - printk("ia64_pal_vm_summary=%ld\n", status); + if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { + printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); return 0; } @@ -339,18 +318,26 @@ if (ia64_pal_mem_attrib(&attrib) != 0) return 0; - p += sprintf(p, "Supported memory attributes : %s\n", mem_attrib[attrib&0x7]); + p += sprintf(p, "Supported memory attributes : "); + sep = ""; + for (i = 0; i < 8; i++) { + if (attrib & (1 << i)) { + p += sprintf(p, "%s%s", sep, mem_attrib[i]); + sep = ", "; + } + } + p += sprintf(p, "\n"); - if ((status=ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { - printk("ia64_pal_vm_page_size=%ld\n", status); + if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { + printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status); return 0; } - p += sprintf(p, "\nTLB walker : %s implemented\n" \ + p += sprintf(p, "\nTLB walker : %simplemented\n" \ "Number of DTR : %d\n" \ "Number of ITR : %d\n" \ "TLB insertable page sizes : ", - vm_info_1.pal_vm_info_1_s.vw ? "\b":"not", + vm_info_1.pal_vm_info_1_s.vw ? "" : "not ", vm_info_1.pal_vm_info_1_s.max_dtr_entry+1, vm_info_1.pal_vm_info_1_s.max_itr_entry+1); @@ -362,7 +349,7 @@ p = bitvector_process(p, vw_pages); if ((status=ia64_get_ptce(&ptce)) != 0) { - printk("ia64_get_ptce=%ld\n",status); + printk(KERN_ERR "ia64_get_ptce=%ld\n", status); return 0; } @@ -712,8 +699,8 @@ u64 rv2:32; } *rid_reg; - if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { - printk("ia64_pal_vm_summary=%ld\n", status); + if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { + printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); return 0; } max[0] = vm_info_1.pal_vm_info_1_s.max_itr_entry+1; @@ -724,7 +711,8 @@ status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid); if (status != 0) { - printk("palinfo: pal call failed on tr[%d:%d]=%ld\n", i, j, status); + printk(KERN_ERR "palinfo: pal call failed on tr[%d:%d]=%ld\n", + i, j, status); continue; } @@ -843,7 +831,7 @@ { palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; if (data == NULL) { - printk("%s palinfo: data pointer is NULL\n", KERN_ERR); + printk(KERN_ERR "palinfo: data pointer is NULL\n"); data->ret = 0; /* no output */ return; } @@ -870,7 +858,8 @@ /* will send IPI to other CPU and wait for completion of remote call */ if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 0, 1))) { - printk("palinfo: remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret); + printk(KERN_ERR "palinfo: remote CPU call from %d to %d on function %d: " + "error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret); return 0; } return ptr.ret; @@ -879,7 +868,7 @@ static int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) { - printk("palinfo: should not be called with non SMP kernel\n"); + printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n"); return 0; } #endif /* CONFIG_SMP */ @@ -937,7 +926,7 @@ */ for (i=0; i < NR_CPUS; i++) { - if (!cpu_is_online(i)) continue; + if (!cpu_online(i)) continue; sprintf(cpustr,CPUSTR, i); @@ -947,8 +936,10 @@ for (j=0; j < NR_PALINFO_ENTRIES; j++) { f.func_id = j; - *pdir++ = create_proc_read_entry (palinfo_entries[j].name, 0, cpu_dir, - palinfo_read_entry, (void *)f.value); + *pdir = create_proc_read_entry( + palinfo_entries[j].name, 0, cpu_dir, + palinfo_read_entry, (void *)f.value); + pdir++; } *pdir++ = cpu_dir; } diff -urN linux-2.4.21/arch/ia64/kernel/pci.c linux-2.4.22/arch/ia64/kernel/pci.c --- linux-2.4.21/arch/ia64/kernel/pci.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -2,9 +2,15 @@ * pci.c - Low-Level PCI Access in IA-64 * * Derived from bios32.c of i386 tree. + * Copyright (C) 2002, 2003 Hewlett-Packard Co + * David Mosberger-Tang + * Bjorn Helgaas + * + * Note: Above list of copyright holders is incomplete... */ #include +#include #include #include #include @@ -13,9 +19,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -39,12 +45,6 @@ #define DBG(x...) #endif -#ifdef CONFIG_IA64_MCA -extern void ia64_mca_check_errors( void ); -#endif - -static unsigned int acpi_root_bridges; - struct pci_fixup pcibios_fixups[1]; struct pci_ops *pci_root_ops; @@ -213,14 +213,14 @@ return b; } -static void +static int alloc_resource (char *name, struct resource *root, unsigned long start, unsigned long end, unsigned long flags) { struct resource *res; res = kmalloc(sizeof(*res), GFP_KERNEL); if (!res) - return; + return -ENOMEM; memset(res, 0, sizeof(*res)); res->name = name; @@ -228,7 +228,10 @@ res->end = end; res->flags = flags; - request_resource(root, res); + if (request_resource(root, res)) + return -EBUSY; + + return 0; } static u64 @@ -308,14 +311,24 @@ } else return AE_OK; + if (addr.min_address_range == addr.max_address_range) { + printk(KERN_INFO "ACPI reports bogus %s %s range 0x%lx-0x%lx; ignoring it\n", + info->name, root->name, addr.min_address_range + offset, + addr.max_address_range + offset); + return AE_OK; + } + window = &info->controller->window[info->controller->windows++]; window->resource.flags |= flags; window->resource.start = addr.min_address_range; window->resource.end = addr.max_address_range; window->offset = offset; - alloc_resource(info->name, root, addr.min_address_range + offset, - addr.max_address_range + offset, flags); + if (alloc_resource(info->name, root, addr.min_address_range + offset, + addr.max_address_range + offset, flags)) + printk(KERN_ERR "alloc 0x%lx-0x%lx from %s for %s failed\n", + addr.min_address_range + offset, addr.max_address_range + offset, + root->name, info->name); } return AE_OK; @@ -329,8 +342,6 @@ unsigned int windows = 0; char *name; - acpi_root_bridges++; - controller = alloc_pci_controller(seg); if (!controller) goto out1; @@ -379,7 +390,6 @@ void __init pcibios_init (void) { -# define PCI_BUSES_TO_SCAN 256 int i = 0; struct pci_controller *controller; @@ -391,15 +401,6 @@ platform_pci_fixup(0); /* phase 0 fixups (before buses scanned) */ - /* Only probe blindly if ACPI didn't tell us about root bridges */ - if (!acpi_root_bridges) { - printk("PCI: Probing PCI hardware\n"); - controller = alloc_pci_controller(0); - if (controller) - for (i = 0; i < PCI_BUSES_TO_SCAN; i++) - pci_scan_bus(i, pci_root_ops, controller); - } - platform_pci_fixup(1); /* phase 1 fixups (after buses scanned) */ return; @@ -576,9 +577,81 @@ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) + vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; } + +/** + * pci_cacheline_size - determine cacheline size for PCI devices + * @dev: void + * + * We want to use the line-size of the outer-most cache. We assume + * that this line-size is the same for all CPUs. + * + * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). + * + * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. + */ +static unsigned long +pci_cacheline_size (void) +{ + u64 levels, unique_caches; + s64 status; + pal_cache_config_info_t cci; + static u8 cacheline_size; + + if (cacheline_size) + return cacheline_size; + + status = ia64_pal_cache_summary(&levels, &unique_caches); + if (status != 0) { + printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", + __FUNCTION__, status); + return SMP_CACHE_BYTES; + } + + status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2, + &cci); + if (status != 0) { + printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n", + __FUNCTION__, status); + return SMP_CACHE_BYTES; + } + cacheline_size = 1 << cci.pcci_line_size; + return cacheline_size; +} + +/** + * pcibios_prep_mwi - helper function for drivers/pci/pci.c:pci_set_mwi() + * @dev: the PCI device for which MWI is enabled + * + * For ia64, we can get the cacheline sizes from PAL. + * + * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. + */ +int +pcibios_set_mwi (struct pci_dev *dev) +{ + unsigned long desired_linesize, current_linesize; + int rc = 0; + u8 pci_linesize; + + desired_linesize = pci_cacheline_size(); + + pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_linesize); + current_linesize = 4 * pci_linesize; + if (desired_linesize != current_linesize) { + printk(KERN_WARNING "PCI: slot %s has incorrect PCI cache line size of %lu bytes,", + dev->slot_name, current_linesize); + if (current_linesize > desired_linesize) { + printk(" expected %lu bytes instead\n", desired_linesize); + rc = -EINVAL; + } else { + printk(" correcting to %lu\n", desired_linesize); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, desired_linesize / 4); + } + } + return rc; +} diff -urN linux-2.4.21/arch/ia64/kernel/perfmon.c linux-2.4.22/arch/ia64/kernel/perfmon.c --- linux-2.4.21/arch/ia64/kernel/perfmon.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/perfmon.c 2003-08-25 04:44:39.000000000 -0700 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -120,8 +121,22 @@ #define CTX_USED_DBR(ctx,n) (ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64) #define CTX_USES_DBREGS(ctx) (((pfm_context_t *)(ctx))->ctx_fl_using_dbreg==1) -#define LOCK_CTX(ctx) spin_lock(&(ctx)->ctx_lock) -#define UNLOCK_CTX(ctx) spin_unlock(&(ctx)->ctx_lock) +#ifdef CONFIG_SMP +#define GET_ACTIVATION() pmu_owners[smp_processor_id()].activation_number +#define INC_ACTIVATION() pmu_owners[smp_processor_id()].activation_number++ +#define SET_ACTIVATION(c) (c)->ctx_last_activation = GET_ACTIVATION() +#define SET_LAST_CPU(ctx, v) (ctx)->ctx_last_cpu = (v) +#define GET_LAST_CPU(ctx) (ctx)->ctx_last_cpu +#else /* !CONFIG_SMP */ +#define SET_ACTIVATION(t) do {} while(0) +#define GET_ACTIVATION(t) do {} while(0) +#define INC_ACTIVATION(t) do {} while(0) +#define SET_LAST_CPU(ctx, v) do {} while(0) +#define GET_LAST_CPU(ctx) do {} while(0) +#endif /* CONFIG_SMP */ + + +#define PFM_INVALID_ACTIVATION (~0UL) #define SET_PMU_OWNER(t) do { pmu_owners[smp_processor_id()].owner = (t); } while(0) #define PMU_OWNER() pmu_owners[smp_processor_id()].owner @@ -131,14 +146,13 @@ #define PFM_REG_RETFLAG_SET(flags, val) do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0) -#define PFM_CPUINFO_CLEAR(v) local_cpu_data->pfm_syst_info &= ~(v) -#define PFM_CPUINFO_SET(v) local_cpu_data->pfm_syst_info |= (v) +#define TASK_PTREGS(t) (((struct pt_regs *)((unsigned long) (t) + IA64_STK_OFFSET))-1) + +/* + * cmp0 must be the value of pmc0 + */ +#define PMC0_HAS_OVFL(cmp0) (cmp0 & ~0x1UL) -#ifdef CONFIG_SMP -#define cpu_is_online(i) (cpu_online_map & (1UL << i)) -#else -#define cpu_is_online(i) (i==0) -#endif /* * debugging @@ -230,7 +244,8 @@ unsigned int protected:1; /* allow access to creator of context only */ unsigned int using_dbreg:1; /* using range restrictions (debug registers) */ unsigned int excl_idle:1; /* exclude idle task in system wide session */ - unsigned int reserved:23; + unsigned int unsecure:1; /* sp = 0 for non self-monitored task */ + unsigned int reserved:22; } pfm_context_flags_t; /* @@ -265,13 +280,17 @@ u64 ctx_saved_psr; /* copy of psr used for lazy ctxsw */ unsigned long ctx_saved_cpus_allowed; /* copy of the task cpus_allowed (system wide) */ + unsigned long ctx_last_activation; /* context last activation number for last_cpu */ + unsigned int ctx_last_cpu; /* CPU id of current or last CPU used (SMP only) */ unsigned int ctx_cpu; /* cpu to which perfmon is applied (system wide) */ - atomic_t ctx_saving_in_progress; /* flag indicating actual save in progress */ - atomic_t ctx_is_busy; /* context accessed by overflow handler */ - atomic_t ctx_last_cpu; /* CPU id of current or last CPU used */ + struct tasklet_struct ctx_tasklet; /* used for sending signal-based notifications */ } pfm_context_t; +#define PFM_GET_CTX(t) ((pfm_context_t *)(t)->thread.pfm_context) +#define LOCK_CTX(ctx) spin_lock(&(ctx)->ctx_lock) +#define UNLOCK_CTX(ctx) spin_unlock(&(ctx)->ctx_lock) + #define ctx_fl_inherit ctx_flags.inherit #define ctx_fl_block ctx_flags.block #define ctx_fl_system ctx_flags.system @@ -279,6 +298,7 @@ #define ctx_fl_protected ctx_flags.protected #define ctx_fl_using_dbreg ctx_flags.using_dbreg #define ctx_fl_excl_idle ctx_flags.excl_idle +#define ctx_fl_unsecure ctx_flags.unsecure /* * global information about all sessions @@ -335,17 +355,6 @@ } pmu_config_t; /* - * structure used to pass argument to/from remote CPU - * using IPI to check and possibly save the PMU context on SMP systems. - * - * not used in UP kernels - */ -typedef struct { - struct task_struct *task; /* which task we are interested in */ - int retval; /* return value of the call: 0=you can proceed, 1=need to wait for completion */ -} pfm_smp_ipi_arg_t; - -/* * perfmon command descriptions */ typedef struct { @@ -428,7 +437,8 @@ */ static struct { struct task_struct *owner; - char pad[SMP_CACHE_BYTES] ____cacheline_aligned; + unsigned long activation_number; + char pad[SMP_CACHE_BYTES] ____cacheline_aligned; } pmu_owners[NR_CPUS]; @@ -437,10 +447,7 @@ * forward declarations */ static void pfm_reset_pmu(struct task_struct *); -#ifdef CONFIG_SMP -static void pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx); -#endif -static void pfm_lazy_save_regs (struct task_struct *ta); +static unsigned long pfm_lazy_save_regs (struct task_struct *ta); #if defined(CONFIG_ITANIUM) #include "perfmon_itanium.h" @@ -504,6 +511,69 @@ ia64_srlz_d(); } +static inline void +pfm_restore_ibrs(unsigned long *ibrs, unsigned int nibrs) +{ + int i; + + for (i=0; i < nibrs; i++) { + ia64_set_ibr(i, ibrs[i]); + } + ia64_srlz_i(); +} + +static inline void +pfm_restore_dbrs(unsigned long *dbrs, unsigned int ndbrs) +{ + int i; + + for (i=0; i < ndbrs; i++) { + ia64_set_dbr(i, dbrs[i]); + } + ia64_srlz_d(); +} + +static inline void +pfm_restore_pmcs(unsigned long *pmcs, unsigned long mask) +{ + int i; + + DBprintk(("mask=0x%lx\n", mask)); + for (i=0; mask; i++, mask>>=1) { + if ((mask & 0x1) == 0) continue; + ia64_set_pmc(i, pmcs[i]); + DBprintk(("pmc[%d]=0x%lx\n", i, pmcs[i])); + } + ia64_srlz_d(); +} + +static inline void +pfm_restore_pmds(unsigned long *pmds, unsigned long mask) +{ + int i; + unsigned long val, ovfl_val = pmu_conf.ovfl_val; + + DBprintk(("mask=0x%lx\n", mask)); + for (i=0; mask; i++, mask>>=1) { + if ((mask & 0x1) == 0) continue; + val = PMD_IS_COUNTING(i) ? pmds[i] & ovfl_val : pmds[i]; + ia64_set_pmd(i, val); + DBprintk(("pmd[%d]=0x%lx\n", i, val)); + } + ia64_srlz_d(); +} + +static inline void +pfm_save_pmds(unsigned long *pmds, unsigned long mask) +{ + int i; + + ia64_srlz_d(); + + for (i=0; mask; i++, mask>>=1) { + if (mask & 0x1) pmds[i] = ia64_get_pmd(i); + } +} static inline unsigned long pfm_read_soft_counter(pfm_context_t *ctx, int i) @@ -600,7 +670,7 @@ pfm_smpl_buffer_desc_t *psb = (pfm_smpl_buffer_desc_t *)vma->vm_private_data; if (psb == NULL) { - printk("perfmon: psb is null in [%d]\n", current->pid); + printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid); return; } /* @@ -665,7 +735,7 @@ * some sanity checks first */ if (ctx == NULL || task->mm == NULL || ctx->ctx_smpl_vaddr == 0 || ctx->ctx_psb == NULL) { - printk("perfmon: invalid context mm=%p\n", task->mm); + printk(KERN_DEBUG "perfmon: invalid context mm=%p\n", task->mm); return -1; } psb = ctx->ctx_psb; @@ -676,11 +746,11 @@ up_write(&task->mm->mmap_sem); if (r !=0) { - printk("perfmon: pid %d unable to unmap sampling buffer @0x%lx size=%ld\n", - task->pid, ctx->ctx_smpl_vaddr, psb->psb_size); + printk(KERN_DEBUG "perfmon: pid %d unable to unmap sampling buffer " + "@0x%lx size=%ld\n", task->pid, ctx->ctx_smpl_vaddr, psb->psb_size); } - DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", + DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r, psb->psb_refcnt, psb->psb_flags)); return 0; @@ -701,7 +771,14 @@ static void pfm_context_free(pfm_context_t *ctx) { - if (ctx) kfree(ctx); + if (ctx) { + DBprintk(("kill tasklet for ctx %p\n", ctx)); + + tasklet_kill(&ctx->ctx_tasklet); + + DBprintk(("free ctx @%p\n", ctx)); + kfree(ctx); + } } static int @@ -715,7 +792,7 @@ page = pfm_kvirt_to_pa(buf); if (remap_page_range(addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM; - + addr += PAGE_SIZE; buf += PAGE_SIZE; size -= PAGE_SIZE; @@ -873,7 +950,7 @@ vma->vm_end = vma->vm_start + size; DBprintk(("entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, vma->vm_start)); - + /* can only be applied to current, need to have the mm semaphore held when called */ if (pfm_remap_buffer((unsigned long)smpl_buf, vma->vm_start, size)) { DBprintk(("Can't remap buffer\n")); @@ -991,7 +1068,7 @@ pfm_sessions.pfs_sys_use_dbregs, is_syswide, cpu_mask)); - + if (is_syswide) { m = cpu_mask; n = 0; @@ -1005,7 +1082,8 @@ */ if (ctx && ctx->ctx_fl_using_dbreg) { if (pfm_sessions.pfs_sys_use_dbregs == 0) { - printk("perfmon: invalid release for [%d] sys_use_dbregs=0\n", task->pid); + printk(KERN_DEBUG "perfmon: invalid release for [%d] " + "sys_use_dbregs=0\n", task->pid); } else { pfm_sessions.pfs_sys_use_dbregs--; } @@ -1025,7 +1103,44 @@ return 0; } +static void +pfm_send_notification_signal(unsigned long data) +{ + pfm_context_t *ctx = (pfm_context_t *)data; + struct siginfo si; + int ret; + + DBprintk(("[%d] tasklet called\n", current->pid)); + + LOCK_CTX(ctx); + + if (ctx->ctx_notify_task == NULL) { + printk(KERN_INFO "perfmon: tasklet lost notify_task\n"); + goto nothing_to_do; + } + /* no leak */ + memset(&si,0, sizeof(si)); + si.si_addr = NULL; + si.si_pid = current->pid; /* irrelevant */ + si.si_signo = SIGPROF; + si.si_code = PROF_OVFL; /* indicates a perfmon SIGPROF signal */ + si.si_pfm_ovfl[0] = ctx->ctx_ovfl_regs[0]; + + if (ctx->ctx_notify_task != current) read_lock(&tasklist_lock); + + DBprintk_ovfl(("[%d] tasklet sending notification to [%d]\n", current->pid, ctx->ctx_notify_task->pid)); + + ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task); + if (ret != 0) printk(KERN_ERR "send_sig_info(process %d, SIGPROF)=%d\n", ctx->ctx_notify_task->pid, ret); + + /* + * now undo the protections in order + */ + if (ctx->ctx_notify_task != current) read_unlock(&tasklist_lock); +nothing_to_do: + UNLOCK_CTX(ctx); +} /* * XXX: do something better here @@ -1080,7 +1195,7 @@ * and it must be a valid CPU */ cpu = ffz(~pfx->ctx_cpu_mask); - if (cpu_is_online(cpu) == 0) { + if (cpu_online(cpu) == 0) { DBprintk(("CPU%d is not online\n", cpu)); return -EINVAL; } @@ -1229,6 +1344,7 @@ ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; + ctx->ctx_fl_unsecure = (ctx_flags & PFM_FL_UNSECURE) ? 1: 0; ctx->ctx_fl_frozen = 0; /* * setting this flag to 0 here means, that the creator or the task that the @@ -1242,14 +1358,20 @@ ctx->ctx_cpu = ffz(~tmp.ctx_cpu_mask); /* SMP only, means no CPU */ - atomic_set(&ctx->ctx_last_cpu,-1); - - /* may be redudant with memset() but at least it's easier to remember */ - atomic_set(&ctx->ctx_saving_in_progress, 0); - atomic_set(&ctx->ctx_is_busy, 0); + ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; + SET_LAST_CPU(ctx, -1); sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */ + /* + * initialize tasklet for signal notifications + * + * ALL signal-based (or any notification using data structures + * external to perfmon) MUST use tasklets to avoid lock contentions + * when a signal has to be sent for overflow interrupt handler. + */ + tasklet_init(&ctx->ctx_tasklet, pfm_send_notification_signal, (unsigned long)ctx); + if (__copy_to_user(req, &tmp, sizeof(tmp))) { ret = -EFAULT; goto buffer_error; @@ -1258,9 +1380,11 @@ DBprintk(("context=%p, pid=%d notify_task=%p\n", (void *)ctx, task->pid, ctx->ctx_notify_task)); - DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d\n", + DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d unsecure=%d\n", (void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, - ctx->ctx_fl_block, ctx->ctx_fl_system, ctx->ctx_fl_excl_idle)); + ctx->ctx_fl_block, ctx->ctx_fl_system, + ctx->ctx_fl_excl_idle, + ctx->ctx_fl_unsecure)); /* * when no notification is required, we can make this visible at the last moment @@ -1362,8 +1486,9 @@ pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg; unsigned long value, reset_pmds; unsigned int cnum, reg_flags, flags; - int i; - int ret = -EINVAL; + int is_monitor, is_counting; + int i, ret = -EINVAL; +#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z)) /* we don't quite support this right now */ if (task != current) return -EINVAL; @@ -1383,6 +1508,9 @@ reset_pmds = tmp.reg_reset_pmds[0]; flags = 0; + is_counting = PMC_IS_COUNTING(cnum); + is_monitor = PMC_IS_MONITOR(cnum); + /* * we reject all non implemented PMC as well * as attempts to modify PMC[0-3] which are used @@ -1393,21 +1521,19 @@ goto error; } /* - * A PMC used to configure monitors must be: - * - system-wide session: privileged monitor - * - per-task : user monitor - * any other configuration is rejected. - */ - if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) { - DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, value))); - - if (ctx->ctx_fl_system ^ PMC_PM(cnum, value)) { - DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, value), ctx->ctx_fl_system)); - goto error; - } + * If the PMC is a monitor, then if the value is not the default: + * - system-wide session: PMCx.pm=1 (privileged monitor) + * - per-task : PMCx.pm=0 (user monitor) + */ + if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) { + DBprintk(("pmc%u pmc_pm=%ld fl_system=%d\n", + cnum, + PMC_PM(cnum, value), + ctx->ctx_fl_system)); + goto error; } - if (PMC_IS_COUNTING(cnum)) { + if (is_counting) { pfm_monitor_t *p = (pfm_monitor_t *)&value; /* * enforce generation of overflow interrupt. Necessary on all @@ -1470,7 +1596,7 @@ */ ctx->ctx_soft_pmds[cnum].flags = flags; - if (PMC_IS_COUNTING(cnum)) { + if (is_counting) { ctx->ctx_soft_pmds[cnum].reset_pmds[0] = reset_pmds; /* mark all PMDS to be accessed as used */ @@ -1591,7 +1717,7 @@ ia64_srlz_d(); DBprintk(("[%d] pmd[%u]: value=0x%lx hw_value=0x%lx soft_pmd=0x%lx short_reset=0x%lx " - "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx\n", + "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx psr=%d\n", task->pid, cnum, value, hw_value, ctx->ctx_soft_pmds[cnum].val, @@ -1600,7 +1726,7 @@ ia64_get_pmd(cnum) & pmu_conf.ovfl_val, PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N', ctx->ctx_used_pmds[0], - ctx->ctx_soft_pmds[cnum].reset_pmds[0])); + ctx->ctx_soft_pmds[cnum].reset_pmds[0], ia64_psr(regs)->sp)); } return 0; @@ -1635,7 +1761,10 @@ int foo; #endif - if (!CTX_IS_ENABLED(ctx)) return -EINVAL; + if (!CTX_IS_ENABLED(ctx)) { + DBprintk(("context for [%d] is disabled\n", task->pid)); + return -EINVAL; + } /* * XXX: MUST MAKE SURE WE DON"T HAVE ANY PENDING OVERFLOW BEFORE READING @@ -1646,7 +1775,10 @@ /* XXX: ctx locking may be required here */ - DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid)); + /* + * should we need to access the PMU, serialization is needed + */ + ia64_srlz_d(); for (i = 0; i < count; i++, req++) { @@ -1673,36 +1805,20 @@ if (!CTX_IS_USED_PMD(ctx, cnum)) goto abort_mission; /* - * If the task is not the current one, then we check if the - * PMU state is still in the local live register due to lazy ctxsw. - * If true, then we read directly from the registers. + * we can access the registers directly only when task + * is the OWNER of the local PMU. In SMP, this can + * happen only when task == current. In addition + * this can happen when task != currrent but + * only in UP mode. */ - if (atomic_read(&ctx->ctx_last_cpu) == smp_processor_id()){ - ia64_srlz_d(); + if (task == PMU_OWNER()) { val = ia64_get_pmd(cnum); DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val)); } else { -#ifdef CONFIG_SMP - int cpu; - /* - * for SMP system, the context may still be live on another - * CPU so we need to fetch it before proceeding with the read - * This call we only be made once for the whole loop because - * of ctx_last_cpu becoming == -1. - * - * We cannot reuse ctx_last_cpu as it may change before we get to the - * actual IPI call. In this case, we will do the call for nothing but - * there is no way around it. The receiving side will simply do nothing. - */ - cpu = atomic_read(&ctx->ctx_last_cpu); - if (cpu != -1) { - DBprintk(("must fetch on CPU%d for [%d]\n", cpu, task->pid)); - pfm_fetch_regs(cpu, task, ctx); - } -#endif /* context has been saved */ val = th->pmd[cnum]; } + if (PMD_IS_COUNTING(cnum)) { /* * XXX: need to check for overflow @@ -1814,7 +1930,8 @@ LOCK_PFS(); if (pfm_sessions.pfs_ptrace_use_dbregs == 0) { - printk("perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid); + printk(KERN_DEBUG "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", + task->pid); ret = -1; } else { pfm_sessions.pfs_ptrace_use_dbregs--; @@ -2051,7 +2168,6 @@ pfm_protect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { - DBprintk(("context from [%d] is protected\n", task->pid)); /* * from now on, only the creator of the context has access to it */ @@ -2060,7 +2176,9 @@ /* * reinforce secure monitoring: cannot toggle psr.up */ - ia64_psr(regs)->sp = 1; + if (ctx->ctx_fl_unsecure == 0) ia64_psr(regs)->sp = 1; + + DBprintk(("[%d] protected psr.sp=%d\n", task->pid, ia64_psr(regs)->sp)); return 0; } @@ -2073,7 +2191,7 @@ pfm_sysctl.debug = mode == 0 ? 0 : 1; - printk("perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off"); + printk(KERN_INFO "perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off"); return 0; } @@ -2338,7 +2456,7 @@ current)); if (PMU_OWNER() != task) { - printk("perfmon: pfm_start task [%d] not pmu owner\n", task->pid); + printk(KERN_DEBUG "perfmon: pfm_start task [%d] not pmu owner\n", task->pid); return -EINVAL; } @@ -2359,7 +2477,8 @@ } else { if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) { - printk("perfmon: pfm_start task flag not set for [%d]\n", task->pid); + printk(KERN_DEBUG "perfmon: pfm_start task flag not set for [%d]\n", + task->pid); return -EINVAL; } /* set user level psr.up */ @@ -2384,8 +2503,10 @@ return -EINVAL; } +#ifndef CONFIG_SMP if (ctx->ctx_fl_system == 0 && PMU_OWNER() && PMU_OWNER() != current) pfm_lazy_save_regs(PMU_OWNER()); +#endif /* reset all registers to stable quiet state */ pfm_reset_pmu(task); @@ -2427,7 +2548,9 @@ SET_PMU_OWNER(task); ctx->ctx_flags.state = PFM_CTX_ENABLED; - atomic_set(&ctx->ctx_last_cpu, smp_processor_id()); + SET_LAST_CPU(ctx, smp_processor_id()); + INC_ACTIVATION(); + SET_ACTIVATION(ctx); /* simply unfreeze */ pfm_unfreeze_pmu(); @@ -2599,12 +2722,15 @@ if (PFM_CMD_CHK(cmd)) { ret = check_task_state(task); - if (ret != 0) goto abort_call; + if (ret != 0) { + DBprintk(("check_task_state=%ld for [%d]\n", ret, task->pid)); + goto abort_call; + } } } } - ctx = task->thread.pfm_context; + ctx = PFM_GET_CTX(task); if (PFM_CMD_USE_CTX(cmd)) { ret = -EINVAL; @@ -2612,6 +2738,8 @@ DBprintk(("no context for task %d\n", task->pid)); goto abort_call; } + + ret = -EPERM; /* * we only grant access to the context if: @@ -2651,7 +2779,7 @@ * do some sanity checks first */ if (!ctx) { - printk("perfmon: [%d] has no PFM context\n", current->pid); + printk(KERN_DEBUG "perfmon: [%d] has no PFM context\n", current->pid); return; } @@ -2701,6 +2829,8 @@ /* * This function will record an entry in the sampling if it is not full already. + * Input: + * ovfl_mask: mask of overflowed PMD. MUST NEVER be 0. * Return: * 0 : buffer is not full (did not BECOME full: still space or was already full) * 1 : buffer is full (recorded the last entry) @@ -2713,8 +2843,6 @@ perfmon_smpl_entry_t *h; int j; - - idx = ia64_fetch_and_add(1, &psb->psb_index); DBprintk_ovfl(("recording index=%ld entries=%ld\n", idx-1, psb->psb_entries)); @@ -2736,7 +2864,7 @@ /* * initialize entry header */ - h->pid = current->pid; + h->pid = ctx->ctx_fl_system ? current->pid : task->pid; h->cpu = smp_processor_id(); h->last_reset_value = ovfl_mask ? ctx->ctx_soft_pmds[ffz(~ovfl_mask)].lval : 0UL; h->ip = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL; @@ -2802,7 +2930,6 @@ unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL; int i; int ret = 1; - struct siginfo si; /* * It is never safe to access the task for which the overflow interrupt is destinated * using the current variable as the interrupt may occur in the middle of a context switch @@ -2823,16 +2950,16 @@ * Don't think this could happen given upfront tests */ if ((t->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) { - printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", - task->pid); + printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d not " + "using perfmon\n", task->pid); return 0x1; } /* * sanity test. Should never happen */ if ((pmc0 & 0x1) == 0) { - printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", - task->pid, pmc0); + printk(KERN_DEBUG "perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", + task->pid, pmc0); return 0x0; } @@ -2863,7 +2990,7 @@ * taken into consideration here but will be with any read of the pmd via * pfm_read_pmds(). */ - old_val = ctx->ctx_soft_pmds[i].val; + old_val = ctx->ctx_soft_pmds[i].val; ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val; /* @@ -2876,6 +3003,11 @@ if (PMC_OVFL_NOTIFY(ctx, i)) { ovfl_notify |= 1UL << i; } + } else { + /* + * clear top bits (maintain counts in lower part, may not always be zero) + */ + ia64_set_pmd(i, ia64_get_pmd(i) & pmu_conf.ovfl_val); } DBprintk_ovfl(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", i, ctx->ctx_soft_pmds[i].val, old_val, @@ -2885,10 +3017,10 @@ /* * check for sampling buffer * - * if present, record sample. We propagate notification ONLY when buffer - * becomes full. + * if present, record sample only when a 64-bit counter has overflowed. + * We propagate notification ONLY when buffer becomes full. */ - if(CTX_HAS_SMPL(ctx)) { + if(CTX_HAS_SMPL(ctx) && ovfl_pmds) { ret = pfm_record_sample(task, ctx, ovfl_pmds, regs); if (ret == 1) { /* @@ -2924,136 +3056,40 @@ ctx->ctx_ovfl_regs[0] = ovfl_pmds; /* + * As a consequence of the overflow, we always resume + * with monitoring turned off. pfm_restart() will + * reactivate. + */ + ctx->ctx_fl_frozen = 1; + + /* * we have come to this point because there was an overflow and that notification * was requested. The notify_task may have disappeared, in which case notify_task * is NULL. */ - if (ctx->ctx_notify_task) { - - si.si_errno = 0; - si.si_addr = NULL; - si.si_pid = task->pid; /* who is sending */ - - si.si_signo = SIGPROF; - si.si_code = PROF_OVFL; /* indicates a perfmon SIGPROF signal */ - /* - * Shift the bitvector such that the user sees bit 4 for PMD4 and so on. - * We only use smpl_ovfl[0] for now. It should be fine for quite a while - * until we have more than 61 PMD available. - */ - si.si_pfm_ovfl[0] = ovfl_notify; - - /* - * when the target of the signal is not ourself, we have to be more - * careful. The notify_task may being cleared by the target task itself - * in release_thread(). We must ensure mutual exclusion here such that - * the signal is delivered (even to a dying task) safely. - */ - - if (ctx->ctx_notify_task != current) { - /* - * grab the notification lock for this task - * This guarantees that the sequence: test + send_signal - * is atomic with regards to the ctx_notify_task field. - * - * We need a spinlock and not just an atomic variable for this. - * - */ - spin_lock(&ctx->ctx_lock); - - /* - * now notify_task cannot be modified until we're done - * if NULL, they it got modified while we were in the handler - */ - if (ctx->ctx_notify_task == NULL) { - - spin_unlock(&ctx->ctx_lock); + LOCK_CTX(ctx); - /* - * If we've lost the notified task, then we will run - * to completion wbut keep the PMU frozen. Results - * will be incorrect anyway. We do not kill task - * to leave it possible to attach perfmon context - * to already running task. - */ - goto lost_notify; - } - /* - * required by send_sig_info() to make sure the target - * task does not disappear on us. - */ - read_lock(&tasklist_lock); + if (ctx->ctx_notify_task) { + if (CTX_OVFL_NOBLOCK(ctx) == 0 && ctx->ctx_notify_task != task) { + t->pfm_ovfl_block_reset = 1; /* will cause blocking */ + } else { + t->pfm_ovfl_block_reset = 0; } - /* - * in this case, we don't stop the task, we let it go on. It will - * necessarily go to the signal handler (if any) when it goes back to - * user mode. - */ - DBprintk_ovfl(("[%d] sending notification to [%d]\n", - task->pid, ctx->ctx_notify_task->pid)); - - /* - * this call is safe in an interrupt handler, so does read_lock() on tasklist_lock - */ - ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task); - if (ret != 0) - printk("send_sig_info(process %d, SIGPROF)=%d\n", - ctx->ctx_notify_task->pid, ret); - /* - * now undo the protections in order - */ - if (ctx->ctx_notify_task != current) { - read_unlock(&tasklist_lock); - spin_unlock(&ctx->ctx_lock); - } + DBprintk_ovfl(("[%d] scheduling tasklet\n", current->pid)); /* - * if we block set the pfm_must_block bit - * when in block mode, we can effectively block only when the notified - * task is not self, otherwise we would deadlock. - * in this configuration, the notification is sent, the task will not - * block on the way back to user mode, but the PMU will be kept frozen - * until PFM_RESTART. - * Note that here there is still a race condition with notify_task - * possibly being nullified behind our back, but this is fine because - * it can only be changed to NULL which by construction, can only be - * done when notify_task != current. So if it was already different - * before, changing it to NULL will still maintain this invariant. - * Of course, when it is equal to current it cannot change at this point. - */ - DBprintk_ovfl(("block=%d notify [%d] current [%d]\n", - ctx->ctx_fl_block, - ctx->ctx_notify_task ? ctx->ctx_notify_task->pid: -1, - current->pid )); + * the tasklet is responsible for sending the notification + * not the PMU owner nor the current task. + */ + tasklet_schedule(&ctx->ctx_tasklet); - if (!CTX_OVFL_NOBLOCK(ctx) && ctx->ctx_notify_task != task) { - t->pfm_ovfl_block_reset = 1; /* will cause blocking */ - } } else { -lost_notify: /* XXX: more to do here, to convert to non-blocking (reset values) */ - DBprintk_ovfl(("notification task has disappeared !\n")); - /* - * for a non-blocking context, we make sure we do not fall into the - * pfm_overflow_notify() trap. Also in the case of a blocking context with lost - * notify process, then we do not want to block either (even though it is - * interruptible). In this case, the PMU will be kept frozen and the process will - * run to completion without monitoring enabled. - * - * Of course, we cannot loose notify process when self-monitoring. - */ - t->pfm_ovfl_block_reset = 0; - + t->pfm_ovfl_block_reset = 0; } - /* - * If notification was successful, then we rely on the pfm_restart() - * call to unfreeze and reset (in both blocking or non-blocking mode). - * - * If notification failed, then we will keep the PMU frozen and run - * the task to completion - */ - ctx->ctx_fl_frozen = 1; + + UNLOCK_CTX(ctx); DBprintk_ovfl(("return pmc0=0x%x must_block=%ld\n", ctx->ctx_fl_frozen ? 0x1 : 0x0, t->pfm_ovfl_block_reset)); @@ -3084,37 +3120,23 @@ * This is slow */ pmc0 = ia64_get_pmc(0); - + task = PMU_OWNER(); /* * if we have some pending bits set * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1 */ - if ((pmc0 & ~0x1UL)!=0UL && (task=PMU_OWNER())!= NULL) { + if (PMC0_HAS_OVFL(pmc0) && task) { /* * we assume that pmc0.fr is always set here */ - ctx = task->thread.pfm_context; + ctx = PFM_GET_CTX(task); /* sanity check */ if (!ctx) { - printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", - task->pid); + printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d has " + "no PFM context\n", task->pid); return; } -#ifdef CONFIG_SMP - /* - * Because an IPI has higher priority than the PMU overflow interrupt, it is - * possible that the handler be interrupted by a request from another CPU to fetch - * the PMU state of the currently active context. The task may have just been - * migrated to another CPU which is trying to restore the context. If there was - * a pending overflow interrupt when the task left this CPU, it is possible for - * the handler to get interrupt by the IPI. In which case, we fetch request - * MUST be postponed until the interrupt handler is done. The ctx_is_busy - * flag indicates such a condition. The other CPU must busy wait until it's cleared. - */ - atomic_set(&ctx->ctx_is_busy, 1); -#endif - /* * assume PMC[0].fr = 1 at this point */ @@ -3122,26 +3144,21 @@ /* * we can only update pmc0 when the overflow - * is for the current context. In UP the current - * task may not be the one owning the PMU + * is for the current context or we are in system + * wide mode. In UP (per-task) the current + * task may not be the one owning the PMU, + * same thing for system-wide. */ - if (task == current) { + if (task == current || ctx->ctx_fl_system) { /* - * We always clear the overflow status bits and either unfreeze - * or keep the PMU frozen. - */ + * We always clear the overflow status bits and either unfreeze + * or keep the PMU frozen. + */ ia64_set_pmc(0, pmc0); ia64_srlz_d(); } else { task->thread.pmc[0] = pmc0; } - -#ifdef CONFIG_SMP - /* - * announce that we are doing with the context - */ - atomic_set(&ctx->ctx_is_busy, 0); -#endif } else { pfm_stats[smp_processor_id()].pfm_spurious_ovfl_intr_count++; } @@ -3158,7 +3175,7 @@ p += sprintf(p, "ovfl_mask : 0x%lx\n", pmu_conf.ovfl_val); for(i=0; i < NR_CPUS; i++) { - if (cpu_is_online(i) == 0) continue; + if (cpu_online(i) == 0) continue; p += sprintf(p, "CPU%-2d overflow intrs : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count); p += sprintf(p, "CPU%-2d spurious intrs : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count); p += sprintf(p, "CPU%-2d recorded samples : %lu\n", i, pfm_stats[i].pfm_recorded_samples_count); @@ -3167,6 +3184,7 @@ p += sprintf(p, "CPU%-2d dcr_pp : %d\n", i, cpu_data(i)->pfm_syst_info & PFM_CPUINFO_DCR_PP ? 1 : 0); p += sprintf(p, "CPU%-2d exclude idle : %d\n", i, cpu_data(i)->pfm_syst_info & PFM_CPUINFO_EXCL_IDLE ? 1 : 0); p += sprintf(p, "CPU%-2d owner : %d\n", i, pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1); + p += sprintf(p, "CPU%-2d activations : %lu\n", i, pmu_owners[i].activation_number); } LOCK_PFS(); @@ -3257,13 +3275,26 @@ } } +#ifdef CONFIG_SMP void -pfm_save_regs (struct task_struct *task) +pfm_save_regs(struct task_struct *task) { pfm_context_t *ctx; + struct thread_struct *t; u64 psr; - ctx = task->thread.pfm_context; + ctx = PFM_GET_CTX(task); + if (ctx == NULL) goto save_error; + t = &task->thread; + + /* + * sanity check + */ + if (ctx->ctx_last_activation != GET_ACTIVATION()) { + DBprintk(("ctx_activation=%lu activation=%lu: no save\n", + ctx->ctx_last_activation, GET_ACTIVATION())); + return; + } /* * save current PSR: needed because we modify it @@ -3272,229 +3303,258 @@ /* * stop monitoring: - * This is the last instruction which can generate an overflow + * This is the last instruction which may generate an overflow * * We do not need to set psr.sp because, it is irrelevant in kernel. * It will be restored from ipsr when going back to user level */ pfm_clear_psr_up(); - ia64_srlz_i(); + /* + * keep a copy of the saved psr (for reload) + */ ctx->ctx_saved_psr = psr; - //ctx->ctx_last_cpu = smp_processor_id(); + /* + * release ownership of this PMU. + */ + SET_PMU_OWNER(NULL); + + /* + * we systematically save the PMD as we have no + * guarantee we will be schedule at that same + * CPU again. + */ + pfm_save_pmds(t->pmd, ctx->ctx_used_pmds[0]); + + /* + * save pmc0 ia64_srlz_d() done in pfm_save_pmds() + * we will need it on the restore path to check + * for pending overflow. + */ + t->pmc[0] = ia64_get_pmc(0); + + return; +save_error: + printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n", + smp_processor_id(), task->pid, + task->thread.flags & IA64_THREAD_PM_VALID); } -static void -pfm_lazy_save_regs (struct task_struct *task) +#else /* !CONFIG_SMP */ + +void +pfm_save_regs(struct task_struct *task) { pfm_context_t *ctx; - struct thread_struct *t; - unsigned long mask; - int i; - - DBprintk(("on [%d] by [%d]\n", task->pid, current->pid)); + u64 psr; - t = &task->thread; - ctx = task->thread.pfm_context; + ctx = PFM_GET_CTX(task); + if (ctx == NULL) goto save_error; + /* + * save current PSR: needed because we modify it + */ + psr = pfm_get_psr(); -#ifdef CONFIG_SMP - /* - * announce we are saving this PMU state - * This will cause other CPU, to wait until we're done - * before using the context.h + /* + * stop monitoring: + * This is the last instruction which may generate an overflow * - * must be an atomic operation + * We do not need to set psr.sp because, it is irrelevant in kernel. + * It will be restored from ipsr when going back to user level */ - atomic_set(&ctx->ctx_saving_in_progress, 1); - - /* - * if owner is NULL, it means that the other CPU won the race - * and the IPI has caused the context to be saved in pfm_handle_fectch_regs() - * instead of here. We have nothing to do - * - * note that this is safe, because the other CPU NEVER modifies saving_in_progress. - */ - if (PMU_OWNER() == NULL) goto do_nothing; -#endif + pfm_clear_psr_up(); /* - * do not own the PMU + * keep a copy of the saved psr (for reload) */ - SET_PMU_OWNER(NULL); + ctx->ctx_saved_psr = psr; - ia64_srlz_d(); + return; +save_error: + printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n", + smp_processor_id(), task->pid, + task->thread.flags & IA64_THREAD_PM_VALID); +} - /* - * XXX needs further optimization. - * Also must take holes into account - */ - mask = ctx->ctx_used_pmds[0]; - for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i); - } +static unsigned long +pfm_lazy_save_regs (struct task_struct *task) +{ + pfm_context_t *ctx; + struct thread_struct *t; - /* save pmc0 */ - t->pmc[0] = ia64_get_pmc(0); + ctx = PFM_GET_CTX(task); + t = &task->thread; - /* not owned by this CPU */ - atomic_set(&ctx->ctx_last_cpu, -1); + DBprintk(("on [%d] used_pmds=0x%lx\n", task->pid, ctx->ctx_used_pmds[0])); -#ifdef CONFIG_SMP -do_nothing: -#endif /* - * declare we are done saving this context + * release ownership of this PMU. + * must be done before we save the registers. * - * must be an atomic operation + * after this call any PMU interrupt is treated + * as spurious. */ - atomic_set(&ctx->ctx_saving_in_progress,0); + SET_PMU_OWNER(NULL); + /* + * save all the pmds we use + */ + pfm_save_pmds(t->pmd, ctx->ctx_used_pmds[0]); + + /* + * save pmc0 ia64_srlz_d() done in pfm_save_pmds() + * it is needed to check for pended overflow + * on the restore path + */ + t->pmc[0] = ia64_get_pmc(0); + + return t->pmc[0]; } +#endif /* CONFIG_SMP */ #ifdef CONFIG_SMP -/* - * Handles request coming from other CPUs - */ -static void -pfm_handle_fetch_regs(void *info) +void +pfm_load_regs (struct task_struct *task) { - pfm_smp_ipi_arg_t *arg = info; - struct thread_struct *t; pfm_context_t *ctx; - unsigned long mask; - int i; - - ctx = arg->task->thread.pfm_context; - t = &arg->task->thread; + struct thread_struct *t; + struct task_struct *owner; + unsigned long pmc_mask = 0UL, pmd_mask = 0UL; + u64 psr; - DBprintk(("task=%d owner=%d saving=%d\n", - arg->task->pid, - PMU_OWNER() ? PMU_OWNER()->pid: -1, - atomic_read(&ctx->ctx_saving_in_progress))); - - /* must wait until not busy before retrying whole request */ - if (atomic_read(&ctx->ctx_is_busy)) { - arg->retval = 2; + ctx = PFM_GET_CTX(task); + if (unlikely(ctx == NULL)) { + printk(KERN_ERR "perfmon: pfm_load_regs() null context\n"); return; } - /* must wait if saving was interrupted */ - if (atomic_read(&ctx->ctx_saving_in_progress)) { - arg->retval = 1; - return; - } + owner = PMU_OWNER(); + t = &task->thread; - /* can proceed, done with context */ - if (PMU_OWNER() != arg->task) { - arg->retval = 0; + /* + * possible on unload + */ + if ((t->flags & IA64_THREAD_PM_VALID) == 0) { + DBprintk(("[%d] PM_VALID=0, nothing to do\n", task->pid)); return; } - DBprintk(("saving state for [%d] used_pmcs=0x%lx reload_pmcs=0x%lx used_pmds=0x%lx\n", - arg->task->pid, - ctx->ctx_used_pmcs[0], - ctx->ctx_reload_pmcs[0], - ctx->ctx_used_pmds[0])); - /* - * XXX: will be replaced with pure assembly call + * we restore ALL the debug registers to avoid picking up + * stale state. + * + * This must be done even when the task is still the owner + * as the registers may have been modified via ptrace() + * (not perfmon) by the previous task. */ - SET_PMU_OWNER(NULL); - - ia64_srlz_d(); + if (ctx->ctx_fl_using_dbreg) { + pfm_restore_ibrs(t->ibr, pmu_conf.num_ibrs); + pfm_restore_dbrs(t->dbr, pmu_conf.num_dbrs); + } /* - * XXX needs further optimization. + * retrieve saved psr */ - mask = ctx->ctx_used_pmds[0]; - for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) t->pmd[i] = ia64_get_pmd(i); - } - - /* save pmc0 */ - t->pmc[0] = ia64_get_pmc(0); - - /* not owned by this CPU */ - atomic_set(&ctx->ctx_last_cpu, -1); + psr = ctx->ctx_saved_psr; - /* can proceed */ - arg->retval = 0; -} + /* + * if we were the last user of the PMU on that CPU, + * then nothing to do except restore psr + */ + if (GET_LAST_CPU(ctx) == smp_processor_id() && ctx->ctx_last_activation == GET_ACTIVATION()) { + /* + * retrieve partial reload masks (due to user modifications) + */ + pmc_mask = 0UL; + pmd_mask = 0UL; -/* - * Function call to fetch PMU state from another CPU identified by 'cpu'. - * If the context is being saved on the remote CPU, then we busy wait until - * the saving is done and then we return. In this case, non IPI is sent. - * Otherwise, we send an IPI to the remote CPU, potentially interrupting - * pfm_lazy_save_regs() over there. - * - * If the retval==1, then it means that we interrupted remote save and that we must - * wait until the saving is over before proceeding. - * Otherwise, we did the saving on the remote CPU, and it was done by the time we got there. - * in either case, we can proceed. - */ -static void -pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx) -{ - pfm_smp_ipi_arg_t arg; - int ret; + if (pmc_mask || pmd_mask) DBprintk(("partial reload [%d] pmd_mask=0x%lx pmc_mask=0x%lx\n", task->pid, pmd_mask, pmc_mask)); + } else { + /* + * To avoid leaking information to the user level when psr.sp=0, + * we must reload ALL implemented pmds (even the ones we don't use). + * In the kernel we only allow PFM_READ_PMDS on registers which + * we initialized or requested (sampling) so there is no risk there. + */ + pmd_mask = pfm_sysctl.fastctxsw ? ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0]; - arg.task = task; - arg.retval = -1; + /* + * ALL accessible PMCs are systematically reloaded, unused registers + * get their default (from pfm_reset_pmu_state()) values to avoid picking + * up stale configuration. + * + * PMC0 is never in the mask. It is always restored separately. + */ + pmc_mask = ctx->ctx_reload_pmcs[0]; + + DBprintk(("full reload for [%d] owner=%d activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n", + task->pid, owner ? owner->pid : -1, + GET_ACTIVATION(), ctx->ctx_last_activation, + GET_LAST_CPU(ctx), pmd_mask, pmc_mask)); - if (atomic_read(&ctx->ctx_is_busy)) { -must_wait_busy: - while (atomic_read(&ctx->ctx_is_busy)); } + + if (pmd_mask) pfm_restore_pmds(t->pmd, pmd_mask); + if (pmc_mask) pfm_restore_pmcs(t->pmc, pmc_mask); - if (atomic_read(&ctx->ctx_saving_in_progress)) { - DBprintk(("no IPI, must wait for [%d] to be saved on [%d]\n", task->pid, cpu)); -must_wait_saving: - /* busy wait */ - while (atomic_read(&ctx->ctx_saving_in_progress)); - DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu)); - return; + /* + * check for pending overflow at the time the state + * was saved. + */ + if (PMC0_HAS_OVFL(t->pmc[0])) { + struct pt_regs *regs = TASK_PTREGS(task); + pfm_overflow_handler(task, ctx, t->pmc[0], regs); } - DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id())); - if (cpu == -1) { - printk("refusing to use -1 for [%d]\n", task->pid); - return; + /* + * fl_frozen==1 when we are in blocking mode waiting for restart + */ + if (ctx->ctx_fl_frozen == 0) { + pfm_unfreeze_pmu(); } - /* will send IPI to other CPU and wait for completion of remote call */ - if ((ret=smp_call_function_single(cpu, pfm_handle_fetch_regs, &arg, 0, 1))) { - printk("perfmon: remote CPU call from %d to %d error %d\n", smp_processor_id(), cpu, ret); - return; - } + SET_LAST_CPU(ctx, smp_processor_id()); + /* - * we must wait until saving is over on the other CPU - * This is the case, where we interrupted the saving which started just at the time we sent the - * IPI. + * dump activation value for this PMU */ - if (arg.retval == 1) goto must_wait_saving; - if (arg.retval == 2) goto must_wait_busy; -} -#endif /* CONFIG_SMP */ + INC_ACTIVATION(); + /* + * record current activation for this context + */ + SET_ACTIVATION(ctx); + /* + * establish new ownership. Interrupts + * are still masked at this point. + */ + SET_PMU_OWNER(task); + + /* + * restore the psr we changed + */ + pfm_set_psr_l(psr); + +} +#else /* !CONFIG_SMP */ +/* + * reload PMU state for UP kernels + */ void pfm_load_regs (struct task_struct *task) { struct thread_struct *t; pfm_context_t *ctx; struct task_struct *owner; - unsigned long mask; + unsigned long pmd_mask, pmc_mask; + unsigned long prev_pmc0 = ~0UL; u64 psr; - int i; -#ifdef CONFIG_SMP - int cpu; -#endif - owner = PMU_OWNER(); - ctx = task->thread.pfm_context; - t = &task->thread; + owner = PMU_OWNER(); + ctx = PFM_GET_CTX(task); + t = &task->thread; /* * we restore ALL the debug registers to avoid picking up @@ -3503,105 +3563,112 @@ * This must be done even when the task is still the owner * as the registers may have been modified via ptrace() * (not perfmon) by the previous task. - * - * XXX: dealing with this in a lazy fashion requires modifications - * to the way the the debug registers are managed. This is will done - * in the next version of perfmon. */ if (ctx->ctx_fl_using_dbreg) { - for (i=0; i < pmu_conf.num_ibrs; i++) { - ia64_set_ibr(i, t->ibr[i]); - } - ia64_srlz_i(); - for (i=0; i < pmu_conf.num_dbrs; i++) { - ia64_set_dbr(i, t->dbr[i]); - } - ia64_srlz_d(); + pfm_restore_ibrs(t->ibr, pmu_conf.num_ibrs); + pfm_restore_dbrs(t->dbr, pmu_conf.num_dbrs); } /* - * if we were the last user, then nothing to do except restore psr + * retrieved save psr */ - if (owner == task) { - if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) - DBprintk(("invalid last_cpu=%d for [%d]\n", - atomic_read(&ctx->ctx_last_cpu), task->pid)); + psr = ctx->ctx_saved_psr; - psr = ctx->ctx_saved_psr; + /* + * short path, our state is still there, just + * need to restore psr and we go + * + * we do not touch either PMC nor PMD. the psr is not touched + * by the overflow_handler. So we are safe w.r.t. to interrupt + * concurrency even without interrupt masking. + */ + if (owner == task) { pfm_set_psr_l(psr); - return; } - DBprintk(("load_regs: must reload for [%d] owner=%d\n", - task->pid, owner ? owner->pid : -1 )); + + DBprintk(("reload for [%d] owner=%d\n", task->pid, owner ? owner->pid : -1)); + /* * someone else is still using the PMU, first push it out and * then we'll be able to install our stuff ! + * + * Upon return, there will be no owner for the current PMU */ - if (owner) pfm_lazy_save_regs(owner); - -#ifdef CONFIG_SMP - /* - * check if context on another CPU (-1 means saved) - * We MUST use the variable, as last_cpu may change behind our - * back. If it changes to -1 (not on a CPU anymore), then in cpu - * we have the last CPU the context was on. We may be sending the - * IPI for nothing, but we have no way of verifying this. - */ - cpu = atomic_read(&ctx->ctx_last_cpu); - if (cpu != -1) { - pfm_fetch_regs(cpu, task, ctx); - } -#endif - + if (owner) prev_pmc0 = pfm_lazy_save_regs(owner); /* * To avoid leaking information to the user level when psr.sp=0, * we must reload ALL implemented pmds (even the ones we don't use). * In the kernel we only allow PFM_READ_PMDS on registers which * we initialized or requested (sampling) so there is no risk there. - * - * As an optimization, we will only reload the PMD that we use when - * the context is in protected mode, i.e. psr.sp=1 because then there - * is no leak possible. */ - mask = pfm_sysctl.fastctxsw || ctx->ctx_fl_protected ? ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0]; - for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.ovfl_val); - } - + pmd_mask = pfm_sysctl.fastctxsw ? ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0]; + /* - * PMC0 is never set in the mask because it is always restored - * separately. + * ALL accessible PMCs are systematically reloaded, unused registers + * get their default (from pfm_reset_pmu_state()) values to avoid picking + * up stale configuration. * - * ALL PMCs are systematically reloaded, unused registers - * get their default (PAL reset) values to avoid picking up - * stale configuration. + * PMC0 is never in the mask. It is always restored separately. */ - mask = ctx->ctx_reload_pmcs[0]; - for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) ia64_set_pmc(i, t->pmc[i]); - } + pmc_mask = ctx->ctx_reload_pmcs[0]; + + pfm_restore_pmds(t->pmd, pmd_mask); + pfm_restore_pmcs(t->pmc, pmc_mask); - if (t->pmc[0] & ~0x1) { - pfm_overflow_handler(task, ctx, t->pmc[0], NULL); + /* + * Check for pending overflow when state was last saved. + * invoked handler is overflow status bits set. + * + * Any PMU overflow in flight at this point, will still + * be treated as spurious because we have no declared + * owner. Note that the first level interrupt handler + * DOES NOT TOUCH any PMC except PMC0 for which we have + * a copy already. + */ + if (PMC0_HAS_OVFL(t->pmc[0])) { + struct pt_regs *regs = TASK_PTREGS(task); + pfm_overflow_handler(task, ctx, t->pmc[0], regs); } + + /* * fl_frozen==1 when we are in blocking mode waiting for restart */ if (ctx->ctx_fl_frozen == 0) { pfm_unfreeze_pmu(); + } else if (prev_pmc0 == 0UL && ctx->ctx_fl_frozen) { + /* + * owner is still NULL at this point. + * + * if the previous owner (from lazy_save_regs()) + * was not in frozen state, then we need to freeze + * the PMU if the new context is frozen. + * + * on McKinley this will generate a spurious interrupt + * but we have no other way. + */ + pfm_freeze_pmu(); } - atomic_set(&ctx->ctx_last_cpu, smp_processor_id()); + /* + * establish new ownership. If there was an in-flight + * overflow interrupt, it will be treated as spurious + * before and after the call, because no overflow + * status bit can possibly be set. No new overflow + * can be generated because, at this point, psr.up + * is still cleared. + */ SET_PMU_OWNER(task); /* - * restore the psr we changed in pfm_save_regs() + * restore the psr. This is the point at which + * new overflow interrupts can be generated again. */ - psr = ctx->ctx_saved_psr; pfm_set_psr_l(psr); } +#endif /* CONFIG_SMP */ /* * XXX: make this routine able to work with non current context @@ -3798,9 +3865,11 @@ * waitpid(). * */ - - if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) - printk("perfmon: [%d] last_cpu=%d\n", task->pid, atomic_read(&ctx->ctx_last_cpu)); +#ifdef CONFIG_SMP + if (GET_LAST_CPU(ctx) != smp_processor_id()) + printk(KERN_DEBUG "perfmon: [%d] last_cpu=%d\n", + task->pid, GET_LAST_CPU(ctx)); +#endif /* * we save all the used pmds @@ -3847,11 +3916,7 @@ task->thread.pmd[i] = val; } } - /* - * indicates that context has been saved - */ - atomic_set(&ctx->ctx_last_cpu, -1); - + SET_LAST_CPU(ctx, -1); } @@ -3875,10 +3940,15 @@ thread = &task->thread; /* - * make sure child cannot mess up the monitoring session + * for secure sessions, make sure child cannot mess up + * the monitoring session. */ - ia64_psr(regs)->sp = 1; - DBprintk(("enabling psr.sp for [%d]\n", task->pid)); + if (ctx->ctx_fl_unsecure == 0) { + ia64_psr(regs)->sp = 1; + DBprintk(("enabling psr.sp for [%d]\n", task->pid)); + } else { + DBprintk(("psr.sp=%d [%d]\n", ia64_psr(regs)->sp, task->pid)); + } /* @@ -3938,7 +4008,6 @@ /* copy content */ *nctx = *ctx; - if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) { nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE; DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid)); @@ -3978,7 +4047,7 @@ nctx->ctx_fl_frozen = 0; nctx->ctx_ovfl_regs[0] = 0UL; - atomic_set(&nctx->ctx_last_cpu, -1); + SET_LAST_CPU(nctx, -1); /* * here nctx->ctx_psb == ctx->ctx_psb @@ -4014,6 +4083,21 @@ */ nctx->ctx_saved_psr = pfm_get_psr(); + /* + * force a full reload on ctxsw in + */ + nctx->ctx_last_activation = PFM_INVALID_ACTIVATION; + SET_LAST_CPU(nctx, -1); + + /* + * initialize tasklet for signal notifications + * + * ALL signal-based (or any notification using data structures + * external to perfmon) MUST use tasklets to avoid lock contentions + * when a signal has to be sent for overflow interrupt handler. + */ + tasklet_init(&nctx->ctx_tasklet, pfm_send_notification_signal, (unsigned long)nctx); + /* link with new task */ thread->pfm_context = nctx; @@ -4027,7 +4111,6 @@ DBprintk(("setting PM_VALID for [%d]\n", task->pid)); thread->flags |= IA64_THREAD_PM_VALID; } - return 0; } @@ -4171,7 +4254,7 @@ pfm_smpl_buffer_desc_t *tmp, *psb = task->thread.pfm_smpl_buf_list; if (psb == NULL) { - printk("perfmon: psb is null in [%d]\n", current->pid); + printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid); return -1; } /* @@ -4331,7 +4414,8 @@ if (ret) return ret; if (pfm_alternate_intr_handler) { - printk("perfmon: install_alternate, intr_handler not NULL after reserve\n"); + printk(KERN_DEBUG "perfmon: install_alternate, intr_handler not NULL " + "after reserve\n"); return -EINVAL; } @@ -4368,10 +4452,8 @@ pmu_conf.disabled = 1; - printk("perfmon: version %u.%u IRQ %u\n", - PFM_VERSION_MAJ, - PFM_VERSION_MIN, - IA64_PERFMON_VECTOR); + printk(KERN_INFO "perfmon: version %u.%u IRQ %u\n", PFM_VERSION_MAJ, PFM_VERSION_MIN, + IA64_PERFMON_VECTOR); /* * compute the number of implemented PMD/PMC from the @@ -4395,8 +4477,8 @@ pmu_conf.num_pmds = n; pmu_conf.num_counters = n_counters; - printk("perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n", - pmu_conf.num_pmcs, + printk(KERN_INFO "perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n", + pmu_conf.num_pmcs, pmu_conf.num_pmds, pmu_conf.num_counters, ffz(pmu_conf.ovfl_val)); @@ -4413,7 +4495,7 @@ perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL); if (perfmon_dir == NULL) { printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n"); - return -1; + return -1; } /* diff -urN linux-2.4.21/arch/ia64/kernel/perfmon_mckinley.h linux-2.4.22/arch/ia64/kernel/perfmon_mckinley.h --- linux-2.4.21/arch/ia64/kernel/perfmon_mckinley.h 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/perfmon_mckinley.h 2003-08-25 04:44:39.000000000 -0700 @@ -25,8 +25,8 @@ /* pmc5 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_reserved, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc6 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_reserved, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc7 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_reserved, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc8 */ { PFM_REG_CONFIG , 0, 0xffffffff3fffffffUL, 0xffffffff9fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc9 */ { PFM_REG_CONFIG , 0, 0xffffffff3ffffffcUL, 0xffffffff9fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, +/* pmc8 */ { PFM_REG_CONFIG , 0, 0xffffffff3fffffffUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, +/* pmc9 */ { PFM_REG_CONFIG , 0, 0xffffffff3ffffffcUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_reserved, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc11 */ { PFM_REG_MONITOR , 6, 0x0UL, 0x30f01cf, NULL, pfm_mck_reserved, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, 0xffffUL, NULL, pfm_mck_reserved, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, @@ -143,11 +143,8 @@ case 8: val8 = *val; val13 = th->pmc[13]; val14 = th->pmc[14]; - *val |= 1UL << 2; /* bit 2 must always be 1 */ check_case1 = 1; break; - case 9: *val |= 1UL << 2; /* bit 2 must always be 1 */ - break; case 13: val8 = th->pmc[8]; val13 = *val; val14 = th->pmc[14]; @@ -163,12 +160,12 @@ * i-side events in L1D and L2 caches */ if (check_case1) { - ret = ((val13 >> 45) & 0xf) == 0 + ret = ((val13 >> 45) & 0xf) == 0 && ((val8 & 0x1) == 0) && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0) ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0)); - if (ret) printk("perfmon: failure check_case1\n"); + if (ret) printk(KERN_DEBUG "perfmon: failure check_case1\n"); } return ret ? -EINVAL : 0; diff -urN linux-2.4.21/arch/ia64/kernel/process.c linux-2.4.22/arch/ia64/kernel/process.c --- linux-2.4.21/arch/ia64/kernel/process.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/process.c 2003-08-25 04:44:39.000000000 -0700 @@ -33,10 +33,13 @@ #include #endif -static void -do_show_stack (struct unw_frame_info *info, void *arg) +#define print_symbol(fmt, addr) printk(fmt, ""); + +void +ia64_do_show_stack (struct unw_frame_info *info, void *arg) { unsigned long ip, sp, bsp; + char buf[80]; /* don't make it so big that it overflows the stack! */ printk("\nCall Trace: "); do { @@ -46,29 +49,28 @@ unw_get_sp(info, &sp); unw_get_bsp(info, &bsp); - printk("[<%016lx>] sp=0x%016lx bsp=0x%016lx\n", ip, sp, bsp); + snprintf(buf, sizeof(buf), " [<%016lx>] %%s\n\t\t\t\tsp=%016lx bsp=%016lx\n", + ip, sp, bsp); + print_symbol(buf, ip); } while (unw_unwind(info) >= 0); } void show_trace_task (struct task_struct *task) { - struct unw_frame_info info; - - unw_init_from_blocked_task(&info, task); - do_show_stack(&info, 0); + show_stack(task); } void show_stack (struct task_struct *task) { if (!task) - unw_init_running(do_show_stack, 0); + unw_init_running(ia64_do_show_stack, 0); else { struct unw_frame_info info; unw_init_from_blocked_task(&info, task); - do_show_stack(&info, 0); + ia64_do_show_stack(&info, 0); } } @@ -119,7 +121,7 @@ } } if (!user_mode(regs)) - show_stack(0); + show_stack(NULL); } void __attribute__((noreturn)) @@ -331,6 +333,7 @@ # define THREAD_FLAGS_TO_SET 0 p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR) | THREAD_FLAGS_TO_SET); + ia64_drop_fpu(p); /* don't pick up stale state from a CPU's fph */ #ifdef CONFIG_IA32_SUPPORT /* * If we're cloning an IA32 task then save the IA32 extra @@ -492,6 +495,15 @@ tid = clone(flags | CLONE_VM, 0); if (parent != current) { +#ifdef CONFIG_IA32_SUPPORT + if (IS_IA32_PROCESS(ia64_task_regs(current))) { + /* A kernel thread is always a 64-bit process. */ + current->thread.map_base = DEFAULT_MAP_BASE; + current->thread.task_size = DEFAULT_TASK_SIZE; + ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob); + ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1); + } +#endif result = (*fn)(arg); _exit(result); } @@ -506,11 +518,7 @@ { /* drop floating-point and debug-register state if it exists: */ current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); - -#ifndef CONFIG_SMP - if (ia64_get_fpu_owner() == current) - ia64_set_fpu_owner(0); -#endif + ia64_drop_fpu(current); } #ifdef CONFIG_PERFMON @@ -548,10 +556,7 @@ void exit_thread (void) { -#ifndef CONFIG_SMP - if (ia64_get_fpu_owner() == current) - ia64_set_fpu_owner(0); -#endif + ia64_drop_fpu(current); #ifdef CONFIG_PERFMON /* stop monitoring */ if (current->thread.pfm_context) diff -urN linux-2.4.21/arch/ia64/kernel/ptrace.c linux-2.4.22/arch/ia64/kernel/ptrace.c --- linux-2.4.21/arch/ia64/kernel/ptrace.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/ptrace.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * Kernel support for the ptrace() and syscall tracing interfaces. * - * Copyright (C) 1999-2002 Hewlett-Packard Co + * Copyright (C) 1999-2003 Hewlett-Packard Co * David Mosberger-Tang * * Derived from the x86 and Alpha versions. Most of the code in here @@ -25,7 +25,7 @@ #include #include #ifdef CONFIG_PERFMON -# include +#include #endif /* @@ -198,20 +198,27 @@ * rnat0/rnat1 gets its value from sw->ar_rnat. */ static unsigned long -get_rnat (struct pt_regs *pt, struct switch_stack *sw, - unsigned long *krbs, unsigned long *urnat_addr) +get_rnat (struct task_struct *task, struct switch_stack *sw, + unsigned long *krbs, unsigned long *urnat_addr, unsigned long *urbs_end) { - unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, kmask = ~0UL; + unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, umask = 0, mask, m; unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift; - long num_regs; + long num_regs, nbits; + struct pt_regs *pt; + pt = ia64_task_regs(task); kbsp = (unsigned long *) sw->ar_bspstore; ubspstore = (unsigned long *) pt->ar_bspstore; + + if (urbs_end < urnat_addr) + nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_end); + else + nbits = 63; + mask = (1UL << nbits) - 1; /* - * First, figure out which bit number slot 0 in user-land maps - * to in the kernel rnat. Do this by figuring out how many - * register slots we're beyond the user's backingstore and - * then computing the equivalent address in kernel space. + * First, figure out which bit number slot 0 in user-land maps to in the kernel + * rnat. Do this by figuring out how many register slots we're beyond the user's + * backingstore and then computing the equivalent address in kernel space. */ num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1); slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs); @@ -221,20 +228,26 @@ if (ubspstore + 63 > urnat_addr) { /* some bits need to be merged in from pt->ar_rnat */ - kmask = ~((1UL << ia64_rse_slot_num(ubspstore)) - 1); - urnat = (pt->ar_rnat & ~kmask); + umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask; + urnat = (pt->ar_rnat & umask); + mask &= ~umask; + if (!mask) + return urnat; } - if (rnat0_kaddr >= kbsp) { + + m = mask << shift; + if (rnat0_kaddr >= kbsp) rnat0 = sw->ar_rnat; - } else if (rnat0_kaddr > krbs) { + else if (rnat0_kaddr > krbs) rnat0 = *rnat0_kaddr; - } - if (rnat1_kaddr >= kbsp) { + urnat |= (rnat0 & m) >> shift; + + m = mask >> (63 - shift); + if (rnat1_kaddr >= kbsp) rnat1 = sw->ar_rnat; - } else if (rnat1_kaddr > krbs) { + else if (rnat1_kaddr > krbs) rnat1 = *rnat1_kaddr; - } - urnat |= ((rnat1 << (63 - shift)) | (rnat0 >> shift)) & kmask; + urnat |= (rnat1 & m) << (63 - shift); return urnat; } @@ -242,22 +255,49 @@ * The reverse of get_rnat. */ static void -put_rnat (struct pt_regs *pt, struct switch_stack *sw, - unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat) +put_rnat (struct task_struct *task, struct switch_stack *sw, + unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat, + unsigned long *urbs_end) { - unsigned long rnat0 = 0, rnat1 = 0, rnat = 0, *slot0_kaddr, kmask = ~0UL, mask; + unsigned long rnat0 = 0, rnat1 = 0, *slot0_kaddr, umask = 0, mask, m; unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift; - long num_regs; + long num_regs, nbits; + struct pt_regs *pt; + unsigned long cfm, *urbs_kargs; + struct unw_frame_info info; + pt = ia64_task_regs(task); kbsp = (unsigned long *) sw->ar_bspstore; ubspstore = (unsigned long *) pt->ar_bspstore; + + urbs_kargs = urbs_end; + if ((long)pt->cr_ifs >= 0) { + /* + * If entered via syscall, don't allow user to set rnat bits + * for syscall args. + */ + unw_init_from_blocked_task(&info,task); + if (unw_unwind_to_user(&info) == 0) { + unw_get_cfm(&info,&cfm); + urbs_kargs = ia64_rse_skip_regs(urbs_end,-(cfm & 0x7f)); + } + } + + if (urbs_kargs >= urnat_addr) + nbits = 63; + else { + if ((urnat_addr - 63) >= urbs_kargs) + return; + nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_kargs); + } + mask = (1UL << nbits) - 1; + /* - * First, figure out which bit number slot 0 in user-land maps - * to in the kernel rnat. Do this by figuring out how many - * register slots we're beyond the user's backingstore and - * then computing the equivalent address in kernel space. + * First, figure out which bit number slot 0 in user-land maps to in the kernel + * rnat. Do this by figuring out how many register slots we're beyond the user's + * backingstore and then computing the equivalent address in kernel space. */ - num_regs = (long) ia64_rse_num_regs(ubspstore, urnat_addr + 1); + num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1); slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs); shift = ia64_rse_slot_num(slot0_kaddr); rnat1_kaddr = ia64_rse_rnat_addr(slot0_kaddr); @@ -265,28 +305,29 @@ if (ubspstore + 63 > urnat_addr) { /* some bits need to be place in pt->ar_rnat: */ - kmask = ~((1UL << ia64_rse_slot_num(ubspstore)) - 1); - pt->ar_rnat = (pt->ar_rnat & kmask) | (rnat & ~kmask); + umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask; + pt->ar_rnat = (pt->ar_rnat & ~umask) | (urnat & umask); + mask &= ~umask; + if (!mask) + return; } /* * Note: Section 11.1 of the EAS guarantees that bit 63 of an * rnat slot is ignored. so we don't have to clear it here. */ rnat0 = (urnat << shift); - mask = ~0UL << shift; - if (rnat0_kaddr >= kbsp) { - sw->ar_rnat = (sw->ar_rnat & ~mask) | (rnat0 & mask); - } else if (rnat0_kaddr > krbs) { - *rnat0_kaddr = ((*rnat0_kaddr & ~mask) | (rnat0 & mask)); - } + m = mask << shift; + if (rnat0_kaddr >= kbsp) + sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat0 & m); + else if (rnat0_kaddr > krbs) + *rnat0_kaddr = ((*rnat0_kaddr & ~m) | (rnat0 & m)); rnat1 = (urnat >> (63 - shift)); - mask = ~0UL >> (63 - shift); - if (rnat1_kaddr >= kbsp) { - sw->ar_rnat = (sw->ar_rnat & ~mask) | (rnat1 & mask); - } else if (rnat1_kaddr > krbs) { - *rnat1_kaddr = ((*rnat1_kaddr & ~mask) | (rnat1 & mask)); - } + m = mask >> (63 - shift); + if (rnat1_kaddr >= kbsp) + sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat1 & m); + else if (rnat1_kaddr > krbs) + *rnat1_kaddr = ((*rnat1_kaddr & ~m) | (rnat1 & m)); } /* @@ -319,7 +360,7 @@ * read the corresponding bits in the kernel RBS. */ rnat_addr = ia64_rse_rnat_addr(laddr); - ret = get_rnat(child_regs, child_stack, krbs, rnat_addr); + ret = get_rnat(child, child_stack, krbs, rnat_addr, urbs_end); if (laddr == rnat_addr) { /* return NaT collection word itself */ @@ -370,7 +411,7 @@ * => write the corresponding bits in the kernel RBS. */ if (ia64_rse_is_rnat_slot(laddr)) - put_rnat(child_regs, child_stack, krbs, laddr, val); + put_rnat(child, child_stack, krbs, laddr, val, urbs_end); else { if (laddr < urbs_end) { regnum = ia64_rse_num_regs(bspstore, laddr); @@ -578,16 +619,11 @@ ia64_flush_fph (struct task_struct *task) { struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); -#ifdef CONFIG_SMP - struct task_struct *fpu_owner = current; -#else - struct task_struct *fpu_owner = ia64_get_fpu_owner(); -#endif - if (task == fpu_owner && psr->mfh) { + if (ia64_is_local_fpu_owner(task) && psr->mfh) { psr->mfh = 0; - ia64_save_fpu(&task->thread.fph[0]); task->thread.flags |= IA64_THREAD_FPH_VALID; + ia64_save_fpu(&task->thread.fph[0]); } } @@ -609,10 +645,7 @@ task->thread.flags |= IA64_THREAD_FPH_VALID; memset(&task->thread.fph, 0, sizeof(task->thread.fph)); } -#ifndef CONFIG_SMP - if (ia64_get_fpu_owner() == task) - ia64_set_fpu_owner(0); -#endif + ia64_drop_fpu(task); psr->dfh = 1; } @@ -701,7 +734,9 @@ case PT_R4: case PT_R5: case PT_R6: case PT_R7: if (write_access) { /* read NaT bit first: */ - ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4, data, &nat); + unsigned long dummy; + + ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4, &dummy, &nat); if (ret < 0) return ret; } @@ -846,8 +881,7 @@ * IA64_THREAD_DBG_VALID. The registers are restored by the PMU context * switch code. */ - if (pfm_use_debug_registers(child)) - return -1; + if (pfm_use_debug_registers(child)) return -1; #endif if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) { @@ -1344,10 +1378,11 @@ set_current_state(TASK_STOPPED); notify_parent(current, SIGCHLD); schedule(); + /* - * This isn't the same as continuing with a signal, but it - * will do for normal use. strace only continues with a - * signal if the stopping signal is not SIGTRAP. -brl + * This isn't the same as continuing with a signal, but it will do for normal use. + * strace only continues with a signal if the stopping signal is not SIGTRAP. + * -brl */ if (current->exit_code) { send_sig(current->exit_code, current, 1); diff -urN linux-2.4.21/arch/ia64/kernel/sal.c linux-2.4.22/arch/ia64/kernel/sal.c --- linux-2.4.21/arch/ia64/kernel/sal.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/sal.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * System Abstraction Layer (SAL) interface routines. * - * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co + * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond @@ -77,7 +77,7 @@ return str; } -static void __init +void __init ia64_sal_handler_init (void *entry_point, void *gpval) { /* fill in the SAL procedure descriptor and point ia64_sal to it: */ @@ -96,17 +96,17 @@ int i; if (!systab) { - printk("Hmm, no SAL System Table.\n"); + printk(KERN_WARNING "Hmm, no SAL System Table.\n"); return; } if (strncmp(systab->signature, "SST_", 4) != 0) - printk("bad signature in system table!"); + printk(KERN_ERR "bad signature in system table!"); /* * revisions are coded in BCD, so %x does the job for us */ - printk("SAL v%x.%02x: oem=%.32s, product=%.32s\n", + printk(KERN_INFO "SAL v%x.%02x: oem=%.32s, product=%.32s\n", systab->sal_rev_major, systab->sal_rev_minor, systab->oem_id, systab->product_id); @@ -121,7 +121,7 @@ switch (*p) { case SAL_DESC_ENTRY_POINT: ep = (struct ia64_sal_desc_entry_point *) p; - printk("SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n", + printk(KERN_INFO "SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n", ep->pal_proc, ep->sal_proc); ia64_pal_handler_init(__va(ep->pal_proc)); ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp)); @@ -139,12 +139,12 @@ switch (ap->mechanism) { case IA64_SAL_AP_EXTERNAL_INT: ap_wakeup_vector = ap->vector; - printk("SAL: AP wakeup using external interrupt " + printk(KERN_INFO "SAL: AP wakeup using external interrupt " "vector 0x%lx\n", ap_wakeup_vector); break; default: - printk("SAL: AP wakeup mechanism unsupported!\n"); + printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n"); break; } break; @@ -154,7 +154,7 @@ { struct ia64_sal_desc_platform_feature *pf = (void *) p; sal_platform_features = pf->feature_mask; - printk("SAL: Platform features "); + printk(KERN_INFO "SAL: Platform features "); if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK) printk("BusLock "); diff -urN linux-2.4.21/arch/ia64/kernel/salinfo.c linux-2.4.22/arch/ia64/kernel/salinfo.c --- linux-2.4.21/arch/ia64/kernel/salinfo.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/kernel/salinfo.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,6 +4,8 @@ * Creates entries in /proc/sal for various system features. * * Copyright (c) 2001 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2003 Hewlett-Packard Co + * Bjorn Helgaas * * 10/30/2001 jbarnes@sgi.com copied much of Stephane's palinfo * code to create this file @@ -12,8 +14,10 @@ #include #include #include +#include #include +#include MODULE_AUTHOR("Jesse Barnes "); MODULE_DESCRIPTION("/proc interface to IA-64 SAL features"); @@ -40,25 +44,325 @@ #define NR_SALINFO_ENTRIES (sizeof(salinfo_entries)/sizeof(salinfo_entry_t)) -/* - * One for each feature and one more for the directory entry... - */ -static struct proc_dir_entry *salinfo_proc_entries[NR_SALINFO_ENTRIES + 1]; +static char *salinfo_log_name[] = { + "mca", + "init", + "cmc", + "cpe", +}; + +static struct proc_dir_entry *salinfo_proc_entries[ + ARRAY_SIZE(salinfo_entries) + /* /proc/sal/bus_lock */ + ARRAY_SIZE(salinfo_log_name) + /* /proc/sal/{mca,...} */ + (2 * ARRAY_SIZE(salinfo_log_name)) + /* /proc/sal/mca/{event,data} */ + 1]; /* /proc/sal */ + +struct salinfo_log_data { + int type; + u8 *log_buffer; + u64 log_size; +}; + +struct salinfo_event { + int type; + int cpu; /* next CPU to check */ + volatile unsigned long cpu_mask; + wait_queue_head_t queue; +}; + +static struct salinfo_event *salinfo_event[ARRAY_SIZE(salinfo_log_name)]; + +struct salinfo_data { + int open; /* single-open to prevent races */ + int type; + int cpu; /* "current" cpu for reads */ +}; + +static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)]; + +static spinlock_t data_lock; + +void +salinfo_log_wakeup(int type) +{ + if (type < ARRAY_SIZE(salinfo_log_name)) { + struct salinfo_event *event = salinfo_event[type]; + + if (event) { + set_bit(smp_processor_id(), &event->cpu_mask); + wake_up_interruptible(&event->queue); + } + } +} + +static int +salinfo_event_open(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct salinfo_event *event = entry->data; + + if (!suser()) + return -EPERM; + return 0; +} + +static ssize_t +salinfo_event_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct inode *inode = file->f_dentry->d_inode; + struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct salinfo_event *event = entry->data; + char cmd[32]; + size_t size; + int i, n, cpu = -1; + +retry: + if (!event->cpu_mask) { + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + interruptible_sleep_on(&event->queue); + if (signal_pending(current)) + return -EINTR; + } + + n = event->cpu; + for (i = 0; i < NR_CPUS; i++) { + if (event->cpu_mask & 1UL << n) { + cpu = n; + break; + } + if (++n == NR_CPUS) + n = 0; + } + + if (cpu == -1) + goto retry; + + /* for next read, start checking at next CPU */ + event->cpu = cpu; + if (++event->cpu == NR_CPUS) + event->cpu = 0; + + snprintf(cmd, sizeof(cmd), "read %d\n", cpu); + + size = strlen(cmd); + if (size > count) + size = count; + if (copy_to_user(buffer, cmd, size)) + return -EFAULT; + + return size; +} + +static struct file_operations salinfo_event_fops = { + .open = salinfo_event_open, + .read = salinfo_event_read, +}; + +static int +salinfo_log_open(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct salinfo_data *data = entry->data; + + if (!suser()) + return -EPERM; + + spin_lock(&data_lock); + if (data->open) { + spin_unlock(&data_lock); + return -EBUSY; + } + data->open = 1; + spin_unlock(&data_lock); + + return 0; +} + +static int +salinfo_log_release(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct salinfo_data *data = entry->data; + + spin_lock(&data_lock); + data->open = 0; + spin_unlock(&data_lock); + return 0; +} + +static void +call_on_cpu(int cpu, void (*fn)(void *), void *arg) +{ + if (cpu == smp_processor_id()) + (*fn)(arg); +#ifdef CONFIG_SMP + else if (cpu_online(cpu)) /* cpu may not have been validated */ + smp_call_function_single(cpu, fn, arg, 0, 1); +#endif +} + +static void +salinfo_log_read_cpu(void *context) +{ + struct salinfo_log_data *info = context; + struct salinfo_event *event = salinfo_event[info->type]; + u64 size; + + size = ia64_sal_get_state_info_size(info->type); + info->log_buffer = kmalloc(size, GFP_ATOMIC); + if (!info->log_buffer) + return; + + clear_bit(smp_processor_id(), &event->cpu_mask); + info->log_size = ia64_sal_get_state_info(info->type, (u64 *) info->log_buffer); + if (info->log_size) + salinfo_log_wakeup(info->type); +} + +static ssize_t +salinfo_log_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct inode *inode = file->f_dentry->d_inode; + struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct salinfo_data *data = entry->data; + struct salinfo_log_data info; + int ret; + void *saldata; + size_t size; + + info.type = data->type; + info.log_buffer = 0; + call_on_cpu(data->cpu, salinfo_log_read_cpu, &info); + if (!info.log_buffer || *ppos >= info.log_size) { + ret = 0; + goto out; + } + + saldata = info.log_buffer + file->f_pos; + size = info.log_size - file->f_pos; + if (size > count) + size = count; + if (copy_to_user(buffer, saldata, size)) { + ret = -EFAULT; + goto out; + } + + *ppos += size; + ret = size; + +out: + kfree(info.log_buffer); + return ret; +} + +static void +salinfo_log_clear_cpu(void *context) +{ + struct salinfo_data *data = context; + struct salinfo_event *event = salinfo_event[data->type]; + struct salinfo_log_data info; + + clear_bit(smp_processor_id(), &event->cpu_mask); + ia64_sal_clear_state_info(data->type); + + /* clearing one record may make another visible */ + info.type = data->type; + salinfo_log_read_cpu(&info); + if (info.log_buffer && info.log_size) + salinfo_log_wakeup(data->type); + + kfree(info.log_buffer); +} + +static ssize_t +salinfo_log_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct inode *inode = file->f_dentry->d_inode; + struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct salinfo_data *data = entry->data; + char cmd[32]; + size_t size; + int cpu; + + size = sizeof(cmd); + if (count < size) + size = count; + if (copy_from_user(cmd, buffer, size)) + return -EFAULT; + + if (sscanf(cmd, "read %d", &cpu) == 1) + data->cpu = cpu; + else if (sscanf(cmd, "clear %d", &cpu) == 1) + call_on_cpu(cpu, salinfo_log_clear_cpu, data); + + return count; +} + +static struct file_operations salinfo_data_fops = { + .open = salinfo_log_open, + .release = salinfo_log_release, + .read = salinfo_log_read, + .write = salinfo_log_write, +}; static int __init salinfo_init(void) { struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */ struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */ - int i; + struct proc_dir_entry *dir, *entry; + struct salinfo_event *event; + struct salinfo_data *data; + int i, j; salinfo_dir = proc_mkdir("sal", NULL); + if (!salinfo_dir) + return 0; for (i=0; i < NR_SALINFO_ENTRIES; i++) { /* pass the feature bit in question as misc data */ *sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir, salinfo_read, (void *)salinfo_entries[i].feature); } + + for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { + dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); + if (!dir) + continue; + + entry = create_proc_entry("event", S_IRUSR, dir); + if (!entry) + continue; + + event = kmalloc(sizeof(*event), GFP_KERNEL); + if (!event) + continue; + memset(event, 0, sizeof(*event)); + event->type = i; + init_waitqueue_head(&event->queue); + salinfo_event[i] = event; + /* we missed any events before now */ + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + set_bit(j, &event->cpu_mask); + entry->data = event; + entry->proc_fops = &salinfo_event_fops; + *sdir++ = entry; + + entry = create_proc_entry("data", S_IRUSR | S_IWUSR, dir); + if (!entry) + continue; + + data = &salinfo_data[i]; + data->type = i; + entry->data = data; + entry->proc_fops = &salinfo_data_fops; + *sdir++ = entry; + + *sdir++ = dir; + } + *sdir++ = salinfo_dir; return 0; @@ -69,7 +373,7 @@ { int i = 0; - for (i = 0; i < NR_SALINFO_ENTRIES ; i++) { + for (i = 0; i < ARRAY_SIZE(salinfo_proc_entries); i++) { if (salinfo_proc_entries[i]) remove_proc_entry (salinfo_proc_entries[i]->name, NULL); } diff -urN linux-2.4.21/arch/ia64/kernel/setup.c linux-2.4.22/arch/ia64/kernel/setup.c --- linux-2.4.21/arch/ia64/kernel/setup.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -125,7 +125,7 @@ #if IGNORE_PFN0 if (start == PAGE_OFFSET) { - printk("warning: skipping physical page 0\n"); + printk(KERN_WARNING "warning: skipping physical page 0\n"); start += PAGE_SIZE; if (start >= end) return 0; } @@ -278,7 +278,7 @@ initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start); initrd_end = initrd_start+ia64_boot_param->initrd_size; - printk("Initial ramdisk at: 0x%lx (%lu bytes)\n", + printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", initrd_start, ia64_boot_param->initrd_size); } #endif @@ -335,8 +335,9 @@ ia64_set_kr(IA64_KR_IO_BASE, phys_iobase); else { phys_iobase = ia64_get_kr(IA64_KR_IO_BASE); - printk("No I/O port range found in EFI memory map, falling back to AR.KR0\n"); - printk("I/O port base = 0x%lx\n", phys_iobase); + printk(KERN_INFO "No I/O port range found in EFI memory map, falling back " + "to AR.KR0\n"); + printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase); } ia64_iobase = (unsigned long) ioremap(phys_iobase, 0); @@ -470,10 +471,10 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo + .start =c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo }; void @@ -526,7 +527,7 @@ impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb; phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size; } - printk("CPU %d: %lu virtual and %lu physical address bits\n", + printk(KERN_INFO "CPU %d: %lu virtual and %lu physical address bits\n", smp_processor_id(), impl_va_msb + 1, phys_addr_size); c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1)); c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1)); @@ -609,6 +610,8 @@ /* Clear the stack memory reserved for pt_regs: */ memset(ia64_task_regs(current), 0, sizeof(struct pt_regs)); + ia64_set_kr(IA64_KR_FPU_OWNER, 0); + /* * Initialize default control register to defer all speculative faults. The * kernel MUST NOT depend on a particular setting of these bits (in other words, @@ -619,10 +622,6 @@ */ ia64_set_dcr( IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC); -#ifndef CONFIG_SMP - ia64_set_fpu_owner(0); -#endif - atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; @@ -650,7 +649,7 @@ if (ia64_pal_vm_summary(NULL, &vmi) == 0) max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1; else { - printk("cpu_init: PAL VM summary failed, assuming 18 RID bits\n"); + printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n"); max_ctx = (1U << 15) - 1; /* use architected minimum */ } while (max_ctx < ia64_ctx.max_ctx) { @@ -660,7 +659,7 @@ } if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) { - printk ("cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n"); + printk(KERN_WARNING "cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n"); num_phys_stacked = 96; } local_cpu_data->phys_stacked_size_p8 = num_phys_stacked*8 + 8; diff -urN linux-2.4.21/arch/ia64/kernel/sigframe.h linux-2.4.22/arch/ia64/kernel/sigframe.h --- linux-2.4.21/arch/ia64/kernel/sigframe.h 2001-11-09 14:26:17.000000000 -0800 +++ linux-2.4.22/arch/ia64/kernel/sigframe.h 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,6 @@ struct sigscratch { unsigned long scratch_unat; /* ar.unat for the general registers saved in pt */ - unsigned long pad; + unsigned long ar_pfs; /* for syscalls, the user-level function-state */ struct pt_regs pt; }; diff -urN linux-2.4.21/arch/ia64/kernel/signal.c linux-2.4.22/arch/ia64/kernel/signal.c --- linux-2.4.21/arch/ia64/kernel/signal.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/signal.c 2003-08-25 04:44:39.000000000 -0700 @@ -142,8 +142,13 @@ __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16); psr->mfh = 0; /* drop signal handler's fph contents... */ - if (!psr->dfh) + if (psr->dfh) + ia64_drop_fpu(current); + else { + /* We already own the local fph, otherwise psr->dfh wouldn't be 0. */ __ia64_load_fpu(current->thread.fph); + ia64_set_local_fpu_owner(current); + } } return err; } @@ -315,7 +320,7 @@ static long setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct sigscratch *scr) { - unsigned long flags = 0, ifs, nat; + unsigned long flags = 0, ifs, cfm, nat; long err; ifs = scr->pt.cr_ifs; @@ -325,7 +330,9 @@ if ((ifs & (1UL << 63)) == 0) { /* if cr_ifs isn't valid, we got here through a syscall */ flags |= IA64_SC_FLAG_IN_SYSCALL; - } + cfm = scr->ar_pfs & ((1UL << 38) - 1); + } else + cfm = ifs & ((1UL << 38) - 1); ia64_flush_fph(current); if ((current->thread.flags & IA64_THREAD_FPH_VALID)) { flags |= IA64_SC_FLAG_FPH_VALID; @@ -344,6 +351,7 @@ err |= __put_user(nat, &sc->sc_nat); err |= PUT_SIGSET(mask, &sc->sc_mask); + err |= __put_user(cfm, &sc->sc_cfm); err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um); err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); @@ -422,6 +430,15 @@ scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */ scr->pt.cr_iip = tramp_addr; ia64_psr(&scr->pt)->ri = 0; /* start executing in first slot */ + /* + * Force the interruption function mask to zero. This has no effect when a + * system-call got interrupted by a signal (since, in that case, scr->pt_cr_ifs is + * ignored), but it has the desirable effect of making it possible to deliver a + * signal with an incomplete register frame (which happens when a mandatory RSE + * load faults). Furthermore, it has no negative effect on the getting the user's + * dirty partition preserved, because that's governed by scr->pt.loadrs. + */ + scr->pt.cr_ifs = (1UL << 63); /* * Note: this affects only the NaT bits of the scratch regs (the ones saved in diff -urN linux-2.4.21/arch/ia64/kernel/smpboot.c linux-2.4.22/arch/ia64/kernel/smpboot.c --- linux-2.4.21/arch/ia64/kernel/smpboot.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/smpboot.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,8 @@ /* * SMP boot-related support * - * Copyright (C) 2001 David Mosberger-Tang + * Copyright (C) 1998-2003 Hewlett-Packard Co + * David Mosberger-Tang * * 01/05/16 Rohit Seth Moved SMP booting functions from smp.c to here. * 01/04/27 David Mosberger Added ITC synching code. @@ -66,8 +67,8 @@ #define DEBUG_ITC_SYNC 0 -extern void __init calibrate_delay(void); -extern void start_ap(void); +extern void __init calibrate_delay (void); +extern void start_ap (void); extern unsigned long ia64_iobase; int cpucount; @@ -235,7 +236,7 @@ go[MASTER] = 1; if (smp_call_function_single(master, sync_master, NULL, 1, 0) < 0) { - printk("sync_itc: failed to get attention of CPU %u!\n", master); + printk(KERN_ERR "sync_itc: failed to get attention of CPU %u!\n", master); return; } @@ -275,8 +276,8 @@ t[i].rt, t[i].master, t[i].diff, t[i].lat); #endif - printk("CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, maxerr %lu cycles)\n", - smp_processor_id(), master, delta, rt); + printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, " + "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt); } /* @@ -328,19 +329,14 @@ phys_id = hard_smp_processor_id(); if (test_and_set_bit(cpuid, &cpu_online_map)) { - printk("huh, phys CPU#0x%x, CPU#0x%x already present??\n", phys_id, cpuid); + printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n", + phys_id, cpuid); BUG(); } smp_setup_percpu_timer(); /* - * Synchronize the ITC with the BP - */ - Dprintk("Going to syncup ITC with BP.\n"); - - ia64_sync_itc(0); - /* * Get our bogomips. */ ia64_init_itm(); @@ -362,6 +358,27 @@ local_irq_enable(); calibrate_delay(); local_cpu_data->loops_per_jiffy = loops_per_jiffy; + + if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) { + /* + * Synchronize the ITC with the BP. Need to do this after irqs are + * enabled because ia64_sync_itc() calls smp_call_function_single(), which + * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls + * local_bh_enable(), which bugs out if irqs are not enabled... + */ + Dprintk("Going to syncup ITC with BP.\n"); + ia64_sync_itc(0); + + /* + * Make sure we didn't sync the itc ahead of the next + * timer interrupt, if so, just reset it. + */ + if (time_after(ia64_get_itc(),local_cpu_data->itm_next)) { + Dprintk("oops, jumped a timer.\n"); + ia64_cpu_local_tick(); + } + } + /* * Allow the master to continue. */ @@ -394,8 +411,8 @@ fork_by_hand (void) { /* - * don't care about the eip and regs settings since - * we'll never reschedule the forked task. + * don't care about the eip and regs settings since we'll never reschedule the + * forked task. */ return do_fork(CLONE_VM|CLONE_PID, 0, 0, 0); } @@ -430,7 +447,7 @@ unhash_process(idle); init_tasks[cpu] = idle; - Dprintk("Sending wakeup vector %u to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid); + Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid); platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0); @@ -447,9 +464,7 @@ if (test_bit(cpu, &cpu_callin_map)) { /* number CPUs logically, starting from 1 (BSP is 0) */ - printk("CPU%d: ", cpu); - /*print_cpu_info(&cpu_data[cpu]); */ - printk("CPU has booted.\n"); + printk(KERN_INFO "CPU%d: CPU has booted.\n", cpu); } else { printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid); ia64_cpu_to_sapicid[cpu] = -1; @@ -476,15 +491,15 @@ smp_setup_percpu_timer(); /* - * We have the boot CPU online for sure. - */ + * We have the boot CPU online for sure. + */ set_bit(0, &cpu_online_map); set_bit(0, &cpu_callin_map); local_cpu_data->loops_per_jiffy = loops_per_jiffy; ia64_cpu_to_sapicid[0] = boot_cpu_id; - printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id); + printk(KERN_INFO "Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id); global_irq_holder = 0; current->processor = 0; @@ -500,7 +515,7 @@ goto smp_done; } if (max_cpus != -1) - printk (KERN_INFO "Limiting CPUs to %d\n", max_cpus); + printk(KERN_INFO "Limiting CPUs to %d\n", max_cpus); if (smp_boot_data.cpu_count > 1) { @@ -518,12 +533,6 @@ break; do_boot_cpu(sapicid); - - /* - * Make sure we unmap all failed CPUs - */ - if (ia64_cpu_to_sapicid[cpu] == -1) - printk("phys CPU#%d not responding - cannot use it.\n", cpu); } smp_num_cpus = cpucount + 1; @@ -541,7 +550,7 @@ if (cpu_online_map & (1UL << cpu)) bogosum += cpu_data(cpu)->loops_per_jiffy; - printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n", + printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); } } @@ -550,7 +559,7 @@ } /* - * Assume that CPU's have been discovered by some platform-dependant interface. For + * Assume that CPU's have been discovered by some platform-dependent interface. For * SoftSDV/Lion, that would be ACPI. * * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP(). @@ -569,7 +578,7 @@ sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ, __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0); if (sal_ret < 0) { - printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n Forcing UP mode\n", + printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n Forcing UP mode\n", ia64_sal_strerror(sal_ret)); max_cpus = 0; smp_num_cpus = 1; diff -urN linux-2.4.21/arch/ia64/kernel/sys_ia64.c linux-2.4.22/arch/ia64/kernel/sys_ia64.c --- linux-2.4.21/arch/ia64/kernel/sys_ia64.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/sys_ia64.c 2003-08-25 04:44:39.000000000 -0700 @@ -56,16 +56,14 @@ } asmlinkage long -ia64_getpriority (int which, int who, long arg2, long arg3, long arg4, long arg5, long arg6, - long arg7, long stack) +ia64_getpriority (int which, int who) { - struct pt_regs *regs = (struct pt_regs *) &stack; extern long sys_getpriority (int, int); long prio; prio = sys_getpriority(which, who); if (prio >= 0) { - regs->r8 = 0; /* ensure negative priority is not mistaken as error code */ + force_successful_syscall_return(); prio = 20 - prio; } return prio; @@ -79,11 +77,9 @@ } asmlinkage unsigned long -ia64_shmat (int shmid, void *shmaddr, int shmflg, long arg3, long arg4, long arg5, long arg6, - long arg7, long stack) +ia64_shmat (int shmid, void *shmaddr, int shmflg) { extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr); - struct pt_regs *regs = (struct pt_regs *) &stack; unsigned long raddr; int retval; @@ -91,16 +87,14 @@ if (retval < 0) return retval; - regs->r8 = 0; /* ensure negative addresses are not mistaken as an error code */ + force_successful_syscall_return(); return raddr; } asmlinkage unsigned long -ia64_brk (unsigned long brk, long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6, long arg7, long stack) +ia64_brk (unsigned long brk) { extern int vm_enough_memory (long pages); - struct pt_regs *regs = (struct pt_regs *) &stack; unsigned long rlim, retval, newbrk, oldbrk; struct mm_struct *mm = current->mm; @@ -150,7 +144,7 @@ out: retval = mm->brk; up_write(&mm->mmap_sem); - regs->r8 = 0; /* ensure large retval isn't mistaken as error code */ + force_successful_syscall_return(); return retval; } @@ -227,29 +221,23 @@ * of) files that are larger than the address space of the CPU. */ asmlinkage unsigned long -sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff, - long arg6, long arg7, long stack) +sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff) { - struct pt_regs *regs = (struct pt_regs *) &stack; - addr = do_mmap2(addr, len, prot, flags, fd, pgoff); if (!IS_ERR((void *) addr)) - regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */ + force_successful_syscall_return(); return addr; } asmlinkage unsigned long -sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, - int fd, long off, long arg6, long arg7, long stack) +sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off) { - struct pt_regs *regs = (struct pt_regs *) &stack; - if ((off & ~PAGE_MASK) != 0) return -EINVAL; addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); if (!IS_ERR((void *) addr)) - regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */ + force_successful_syscall_return(); return addr; } diff -urN linux-2.4.21/arch/ia64/kernel/time.c linux-2.4.22/arch/ia64/kernel/time.c --- linux-2.4.21/arch/ia64/kernel/time.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/kernel/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -73,10 +73,8 @@ now = ia64_get_itc(); if ((long) (now - last_tick) < 0) { -# if 1 - printk("CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n", + printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n", smp_processor_id(), now, last_tick); -# endif return last_time_offset; } elapsed_cycles = now - last_tick; @@ -154,7 +152,7 @@ new_itm = local_cpu_data->itm_next; if (!time_after(ia64_get_itc(), new_itm)) - printk("Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", + printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", ia64_get_itc(), new_itm); while (1) { @@ -243,21 +241,22 @@ */ status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_base_freq, &drift); if (status != 0) { - printk("SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status)); + printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status)); } else { status = ia64_pal_freq_ratios(&proc_ratio, 0, &itc_ratio); if (status != 0) - printk("PAL_FREQ_RATIOS failed with status=%ld\n", status); + printk(KERN_ERR "PAL_FREQ_RATIOS failed with status=%ld\n", status); } if (status != 0) { /* invent "random" values */ - printk("SAL/PAL failed to obtain frequency info---inventing reasonably values\n"); + printk(KERN_ERR + "SAL/PAL failed to obtain frequency info---inventing reasonably values\n"); platform_base_freq = 100000000; itc_ratio.num = 3; itc_ratio.den = 1; } if (platform_base_freq < 40000000) { - printk("Platform base frequency %lu bogus---resetting to 75MHz!\n", + printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n", platform_base_freq); platform_base_freq = 75000000; } @@ -268,8 +267,8 @@ itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; - printk("CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, ITC freq=%lu.%03luMHz\n", - smp_processor_id(), + printk(KERN_INFO "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, " + "ITC freq=%lu.%03luMHz\n", smp_processor_id(), platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000); @@ -284,9 +283,9 @@ } static struct irqaction timer_irqaction = { - handler: timer_interrupt, - flags: SA_INTERRUPT, - name: "timer" + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer" }; void __init diff -urN linux-2.4.21/arch/ia64/kernel/traps.c linux-2.4.22/arch/ia64/kernel/traps.c --- linux-2.4.21/arch/ia64/kernel/traps.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/traps.c 2003-08-25 04:44:39.000000000 -0700 @@ -51,12 +51,12 @@ if (ia64_boot_param->fpswa) { /* FPSWA fixup: make the interface pointer a kernel virtual address: */ fpswa_interface = __va(ia64_boot_param->fpswa); - printk("FPSWA interface at 0x%lx, revision %d.%d\n", + printk(KERN_INFO "FPSWA interface at 0x%lx, revision %d.%d\n", ia64_boot_param->fpswa, fpswa_interface->revision >> 16, fpswa_interface->revision & 0xffff); } else - printk("No FPSWA interface\n"); + printk(KERN_INFO "No FPSWA interface\n"); } /* @@ -97,9 +97,9 @@ int lock_owner; int lock_owner_depth; } die = { - lock: SPIN_LOCK_UNLOCKED, - lock_owner: -1, - lock_owner_depth: 0 + .lock = SPIN_LOCK_UNLOCKED, + .lock_owner = -1, + .lock_owner_depth = 0 }; if (die.lock_owner != smp_processor_id()) { @@ -223,7 +223,7 @@ { struct pt_regs *regs = (struct pt_regs *) &stack; - printk("%s(%d): \n", current->comm, current->pid, + printk(KERN_DEBUG "%s(%d): \n", current->comm, current->pid, regs->r15, arg0, arg1, arg2, arg3); return -ENOSYS; } @@ -245,17 +245,17 @@ psr->dfh = 0; #ifndef CONFIG_SMP { - struct task_struct *fpu_owner = ia64_get_fpu_owner(); + struct task_struct *fpu_owner + = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); - if (fpu_owner == current) + if (ia64_is_local_fpu_owner(current)) return; if (fpu_owner) ia64_flush_fph(fpu_owner); - } #endif /* !CONFIG_SMP */ - ia64_set_fpu_owner(current); + ia64_set_local_fpu_owner(current); if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) { __ia64_load_fpu(current->thread.fph); psr->mfh = 0; @@ -337,8 +337,8 @@ fpu_swa_count = 0; if ((++fpu_swa_count < 5) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) { last_time = jiffies; - printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx\n", - current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri); + printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n", + current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr); } exception = fp_emulate(fp_fault, bundle, ®s->cr_ipsr, ®s->ar_fpsr, &isr, ®s->pr, @@ -348,7 +348,7 @@ /* emulation was successful */ ia64_increment_ip(regs); } else if (exception == -1) { - printk("handle_fpu_swa: fp_emulate() returned -1\n"); + printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); return -1; } else { /* is next instruction a trap? */ @@ -371,7 +371,7 @@ } } else { if (exception == -1) { - printk("handle_fpu_swa: fp_emulate() returned -1\n"); + printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); return -1; } else if (exception != 0) { /* raise exception */ @@ -469,7 +469,9 @@ ? " (RSE access)" : " (data access)") : ""); if (code == 8) { # ifdef CONFIG_IA64_PRINT_HAZARDS - printk("%016lx:possible hazard, pr = %016lx\n", regs->cr_iip, regs->pr); + printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n", + current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, + regs->pr); # endif return; } @@ -485,19 +487,23 @@ case 26: /* NaT Consumption */ if (user_mode(regs)) { + void *addr; + if (((isr >> 4) & 0xf) == 2) { /* NaT page consumption */ sig = SIGSEGV; code = SEGV_ACCERR; + addr = (void *) ifa; } else { /* register NaT consumption */ sig = SIGILL; code = ILL_ILLOPN; + addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); } siginfo.si_signo = sig; siginfo.si_code = code; siginfo.si_errno = 0; - siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); + siginfo.si_addr = addr; siginfo.si_imm = vector; siginfo.si_flags = __ISR_VALID; siginfo.si_isr = isr; @@ -585,8 +591,9 @@ if (ia32_exception(regs, isr) == 0) return; #endif - printk("Unexpected IA-32 exception (Trap 45)\n"); - printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr); + printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n"); + printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", + regs->cr_iip, ifa, isr); force_sig(SIGSEGV, current); break; @@ -595,8 +602,8 @@ if (ia32_intercept(regs, isr) == 0) return; #endif - printk("Unexpected IA-32 intercept trap (Trap 46)\n"); - printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n", + printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n"); + printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n", regs->cr_iip, ifa, isr, iim); force_sig(SIGSEGV, current); return; diff -urN linux-2.4.21/arch/ia64/kernel/unwind.c linux-2.4.22/arch/ia64/kernel/unwind.c --- linux-2.4.21/arch/ia64/kernel/unwind.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/kernel/unwind.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999-2002 Hewlett-Packard Co + * Copyright (C) 1999-2003 Hewlett-Packard Co * David Mosberger-Tang */ /* @@ -51,18 +51,24 @@ #define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1) #define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE) -#define UNW_DEBUG 0 #define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */ -#if UNW_DEBUG - static long unw_debug_level = 255; -# define debug(level,format...) if (unw_debug_level > level) printk(format) -# define dprintk(format...) printk(format) -# define inline -#else -# define debug(level,format...) -# define dprintk(format...) -#endif +#ifdef UNW_DEBUG + static unsigned int unw_debug_level = UNW_DEBUG; +# ifdef CONFIG_KDB +# include +# define UNW_DEBUG_ON(n) (unw_debug_level >= n && !KDB_IS_RUNNING()) +# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) kdb_printf(__VA_ARGS__) +# else /* !CONFIG_KDB */ +# define UNW_DEBUG_ON(n) unw_debug_level >= n + /* Do not code a printk level, not all debug lines end in newline */ +# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__) +# endif /* CONFIG_KDB */ +# define inline +#else /* !UNW_DEBUG */ +# define UNW_DEBUG_ON(n) 0 +# define UNW_DPRINT(n, ...) +#endif /* UNW_DEBUG */ #if UNW_STATS # define STAT(x...) x @@ -111,7 +117,7 @@ /* script cache: */ struct unw_script cache[UNW_CACHE_SIZE]; -# if UNW_DEBUG +# ifdef UNW_DEBUG const char *preg_name[UNW_NUM_REGS]; # endif # if UNW_STATS @@ -140,13 +146,13 @@ } stat; # endif } unw = { - tables: &unw.kernel_table, - lock: SPIN_LOCK_UNLOCKED, - save_order: { + .tables = &unw.kernel_table, + .lock = SPIN_LOCK_UNLOCKED, + .save_order = { UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR }, - preg_index: { + .preg_index = { struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */ struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */ struct_offset(struct unw_frame_info, bsp_loc)/8, @@ -189,9 +195,9 @@ struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8, struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8, }, - hash : { [0 ... UNW_HASH_SIZE - 1] = -1 }, -#if UNW_DEBUG - preg_name: { + .hash = { [0 ... UNW_HASH_SIZE - 1] = -1 }, +#ifdef UNW_DEBUG + .preg_name = { "pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp", "r4", "r5", "r6", "r7", "ar.unat", "pr", "ar.lc", "ar.fpsr", @@ -223,10 +229,25 @@ else if (reg <= 31) off = struct_offset(struct pt_regs, r16) + 8*(reg - 16); else - dprintk("unwind: bad scratch reg r%lu\n", reg); + UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg); return off; } +static inline struct pt_regs * +get_scratch_regs (struct unw_frame_info *info) +{ + if (!info->pt) { + /* This should not happen with valid unwind info. */ + UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__); + if (info->flags & UNW_FLAG_INTERRUPT_FRAME) + info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1); + else + info->pt = info->sp - 16; + } + UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt); + return (struct pt_regs *) info->pt; +} + int unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write) { @@ -235,7 +256,13 @@ struct pt_regs *pt; if ((unsigned) regnum - 1 >= 127) { - dprintk("unwind: trying to access non-existent r%u\n", regnum); + if (regnum == 0 && !write) { + *val = 0; /* read r0 always returns 0 */ + *nat = 0; + return 0; + } + UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n", + __FUNCTION__, regnum); return -1; } @@ -280,8 +307,9 @@ if ((unsigned long) addr < info->regstk.limit || (unsigned long) addr >= info->regstk.top) { - dprintk("unwind: %p outside of regstk " - "[0x%lx-0x%lx)\n", (void *) addr, + UNW_DPRINT(0, "unwind.%s: %p outside of regstk " + "[0x%lx-0x%lx)\n", + __FUNCTION__, (void *) addr, info->regstk.limit, info->regstk.top); return -1; @@ -298,11 +326,8 @@ } } else { /* access a scratch register */ - if (info->flags & UNW_FLAG_INTERRUPT_FRAME) - pt = (struct pt_regs *) info->psp - 1; - else - pt = (struct pt_regs *) info->sp - 1; - addr = (unsigned long *) ((long) pt + pt_regs_off(regnum)); + pt = get_scratch_regs(info); + addr = (unsigned long *) ((unsigned long)pt + pt_regs_off(regnum)); if (info->pri_unat_loc) nat_addr = info->pri_unat_loc; else @@ -316,7 +341,8 @@ if ((unsigned long) addr < info->regstk.limit || (unsigned long) addr >= info->regstk.top) { - dprintk("unwind: ignoring attempt to access register outside of rbs\n"); + UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside " + "of rbs\n", __FUNCTION__); return -1; } if ((unsigned long) nat_addr >= info->regstk.top) @@ -348,15 +374,11 @@ unsigned long *addr; struct pt_regs *pt; - if (info->flags & UNW_FLAG_INTERRUPT_FRAME) - pt = (struct pt_regs *) info->psp - 1; - else - pt = (struct pt_regs *) info->sp - 1; switch (regnum) { /* scratch: */ - case 0: addr = &pt->b0; break; - case 6: addr = &pt->b6; break; - case 7: addr = &pt->b7; break; + case 0: pt = get_scratch_regs(info); addr = &pt->b0; break; + case 6: pt = get_scratch_regs(info); addr = &pt->b6; break; + case 7: pt = get_scratch_regs(info); addr = &pt->b7; break; /* preserved: */ case 1: case 2: case 3: case 4: case 5: @@ -366,7 +388,8 @@ break; default: - dprintk("unwind: trying to access non-existent b%u\n", regnum); + UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n", + __FUNCTION__, regnum); return -1; } if (write) @@ -383,22 +406,20 @@ struct pt_regs *pt; if ((unsigned) (regnum - 2) >= 126) { - dprintk("unwind: trying to access non-existent f%u\n", regnum); + UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n", + __FUNCTION__, regnum); return -1; } - if (info->flags & UNW_FLAG_INTERRUPT_FRAME) - pt = (struct pt_regs *) info->psp - 1; - else - pt = (struct pt_regs *) info->sp - 1; - if (regnum <= 5) { addr = *(&info->f2_loc + (regnum - 2)); if (!addr) addr = &info->sw->f2 + (regnum - 2); } else if (regnum <= 15) { - if (regnum <= 9) + if (regnum <= 9) { + pt = get_scratch_regs(info); addr = &pt->f6 + (regnum - 6); + } else addr = &info->sw->f10 + (regnum - 10); } else if (regnum <= 31) { @@ -428,11 +449,6 @@ unsigned long *addr; struct pt_regs *pt; - if (info->flags & UNW_FLAG_INTERRUPT_FRAME) - pt = (struct pt_regs *) info->psp - 1; - else - pt = (struct pt_regs *) info->sp - 1; - switch (regnum) { case UNW_AR_BSP: addr = info->bsp_loc; @@ -487,15 +503,18 @@ break; case UNW_AR_RSC: + pt = get_scratch_regs(info); addr = &pt->ar_rsc; break; case UNW_AR_CCV: + pt = get_scratch_regs(info); addr = &pt->ar_ccv; break; default: - dprintk("unwind: trying to access non-existent ar%u\n", regnum); + UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n", + __FUNCTION__, regnum); return -1; } @@ -532,7 +551,7 @@ rs = alloc_reg_state(); if (!rs) { - printk("unwind: cannot stack reg state!\n"); + printk(KERN_ERR "unwind: cannot stack reg state!\n"); return; } memcpy(rs, &sr->curr, sizeof(*rs)); @@ -545,7 +564,7 @@ struct unw_reg_state *rs = sr->curr.next; if (!rs) { - printk("unwind: stack underflow!\n"); + printk(KERN_ERR "unwind: stack underflow!\n"); return; } memcpy(&sr->curr, rs, sizeof(*rs)); @@ -561,7 +580,7 @@ while (rs) { copy = alloc_reg_state(); if (!copy) { - printk ("unwind.dup_state_stack: out of memory\n"); + printk(KERN_ERR "unwind.dup_state_stack: out of memory\n"); return NULL; } memcpy(copy, rs, sizeof(*copy)); @@ -612,7 +631,7 @@ default: break; } - dprintk("unwind: bad abreg=0x%x\n", abreg); + UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __FUNCTION__, abreg); return UNW_REG_LC; } @@ -652,7 +671,7 @@ return; } } - dprintk("unwind: excess spill!\n"); + UNW_DPRINT(0, "unwind.%s: excess spill!\n", __FUNCTION__); } static inline void @@ -720,7 +739,7 @@ desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave, struct unw_state_record *sr) { - int i; + int i, region_start; if (!(sr->in_body || sr->first_region)) finish_prologue(sr); @@ -732,19 +751,20 @@ return; } + region_start = sr->region_start + sr->region_len; + for (i = 0; i < sr->epilogue_count; ++i) pop(sr); sr->epilogue_count = 0; sr->epilogue_start = UNW_WHEN_NEVER; - if (!body) - push(sr); - - sr->region_start += sr->region_len; + sr->region_start = region_start; sr->region_len = rlen; sr->in_body = body; if (!body) { + push(sr); + for (i = 0; i < 4; ++i) { if (mask & 0x8) set_reg(sr->curr.reg + unw.save_order[i], UNW_WHERE_GR, @@ -765,10 +785,13 @@ static inline void desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr) { - if (abi == 0 && context == 'i') + if (abi == 0 && context == 'i') { sr->flags |= UNW_FLAG_INTERRUPT_FRAME; + UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __FUNCTION__); + } else - dprintk("unwind: ignoring unwabi(abi=0x%x,context=0x%x)\n", abi, context); + UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n", + __FUNCTION__, abi, context); } static inline void @@ -951,7 +974,7 @@ return; } } - printk("unwind: failed to find state labeled 0x%lx\n", label); + printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label); } static inline void @@ -961,7 +984,7 @@ ls = alloc_labeled_state(); if (!ls) { - printk("unwind.desc_label_state(): out of memory\n"); + printk(KERN_ERR "unwind.desc_label_state(): out of memory\n"); return; } ls->label = label; @@ -1055,7 +1078,8 @@ r->val = 4*spoff; } -#define UNW_DEC_BAD_CODE(code) printk("unwind: unknown code 0x%02x\n", code); +#define UNW_DEC_BAD_CODE(code) printk(KERN_ERR "unwind: unknown code 0x%02x\n", \ + code); /* * region headers: @@ -1135,6 +1159,9 @@ unsigned short index; unsigned long ip, pr; + if (UNW_DEBUG_ON(0)) + return 0; /* Always regenerate scripts in debug mode */ + STAT(++unw.stat.cache.lookups); ip = info->ip; @@ -1259,8 +1286,8 @@ script_emit (struct unw_script *script, struct unw_insn insn) { if (script->count >= UNW_MAX_SCRIPT_LEN) { - dprintk("unwind: script exceeds maximum size of %u instructions!\n", - UNW_MAX_SCRIPT_LEN); + UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n", + __FUNCTION__, UNW_MAX_SCRIPT_LEN); return; } script->insn[script->count++] = insn; @@ -1301,7 +1328,8 @@ break; default: - dprintk("unwind: don't know how to emit nat info for where = %u\n", r->where); + UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n", + __FUNCTION__, r->where); return; } insn.opc = opc; @@ -1338,8 +1366,9 @@ } val = unw.preg_index[UNW_REG_R4 + (rval - 4)]; } else { - opc = UNW_INSN_ADD_SP; - val = -sizeof(struct pt_regs) + pt_regs_off(rval); + /* register got spilled to a scratch register */ + opc = UNW_INSN_MOVE_SCRATCH; + val = pt_regs_off(rval); } break; @@ -1349,12 +1378,12 @@ else if (rval >= 16 && rval <= 31) val = unw.preg_index[UNW_REG_F16 + (rval - 16)]; else { - opc = UNW_INSN_ADD_SP; - val = -sizeof(struct pt_regs); + opc = UNW_INSN_MOVE_SCRATCH; if (rval <= 9) - val += struct_offset(struct pt_regs, f6) + 16*(rval - 6); + val = struct_offset(struct pt_regs, f6) + 16*(rval - 6); else - dprintk("unwind: kernel may not touch f%lu\n", rval); + UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n", + __FUNCTION__, rval); } break; @@ -1362,14 +1391,13 @@ if (rval >= 1 && rval <= 5) val = unw.preg_index[UNW_REG_B1 + (rval - 1)]; else { - opc = UNW_INSN_ADD_SP; - val = -sizeof(struct pt_regs); + opc = UNW_INSN_MOVE_SCRATCH; if (rval == 0) - val += struct_offset(struct pt_regs, b0); + val = struct_offset(struct pt_regs, b0); else if (rval == 6) - val += struct_offset(struct pt_regs, b6); + val = struct_offset(struct pt_regs, b6); else - val += struct_offset(struct pt_regs, b7); + val = struct_offset(struct pt_regs, b7); } break; @@ -1382,7 +1410,8 @@ break; default: - dprintk("unwind: register %u has unexpected `where' value of %u\n", i, r->where); + UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n", + __FUNCTION__, i, r->where); break; } insn.opc = opc; @@ -1455,9 +1484,10 @@ r->when = UNW_WHEN_NEVER; sr.pr_val = info->pr; + UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __FUNCTION__, ip); script = script_new(ip); if (!script) { - dprintk("unwind: failed to create unwind script\n"); + UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __FUNCTION__); STAT(unw.stat.script.build_time += ia64_get_itc() - start); return 0; } @@ -1475,8 +1505,8 @@ } if (!e) { /* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */ - dprintk("unwind: no unwind info for ip=0x%lx (prev ip=0x%lx)\n", ip, - unw.cache[info->prev_script].ip); + UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n", + __FUNCTION__, ip, unw.cache[info->prev_script].ip); sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; sr.curr.reg[UNW_REG_RP].when = -1; sr.curr.reg[UNW_REG_RP].val = 0; @@ -1524,26 +1554,32 @@ sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; sr.curr.reg[UNW_REG_RP].when = -1; sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg; + UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n", + __FUNCTION__, ip, sr.curr.reg[UNW_REG_RP].where, + sr.curr.reg[UNW_REG_RP].val); } -#if UNW_DEBUG - printk("unwind: state record for func 0x%lx, t=%u:\n", - table->segment_base + e->start_offset, sr.when_target); +#ifdef UNW_DEBUG + UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n", + __FUNCTION__, table->segment_base + e->start_offset, sr.when_target); for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) { if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) { - printk(" %s <- ", unw.preg_name[r - sr.curr.reg]); + UNW_DPRINT(1, " %s <- ", unw.preg_name[r - sr.curr.reg]); switch (r->where) { - case UNW_WHERE_GR: printk("r%lu", r->val); break; - case UNW_WHERE_FR: printk("f%lu", r->val); break; - case UNW_WHERE_BR: printk("b%lu", r->val); break; - case UNW_WHERE_SPREL: printk("[sp+0x%lx]", r->val); break; - case UNW_WHERE_PSPREL: printk("[psp+0x%lx]", r->val); break; + case UNW_WHERE_GR: UNW_DPRINT(1, "r%lu", r->val); break; + case UNW_WHERE_FR: UNW_DPRINT(1, "f%lu", r->val); break; + case UNW_WHERE_BR: UNW_DPRINT(1, "b%lu", r->val); break; + case UNW_WHERE_SPREL: UNW_DPRINT(1, "[sp+0x%lx]", r->val); break; + case UNW_WHERE_PSPREL: UNW_DPRINT(1, "[psp+0x%lx]", r->val); break; case UNW_WHERE_NONE: - printk("%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val); + UNW_DPRINT(1, "%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val); + break; + + default: + UNW_DPRINT(1, "BADWHERE(%d)", r->where); break; - default: printk("BADWHERE(%d)", r->where); break; } - printk("\t\t%d\n", r->when); + UNW_DPRINT(1, "\t\t%d\n", r->when); } } #endif @@ -1641,6 +1677,16 @@ s[dst] = s[val]; break; + case UNW_INSN_MOVE_SCRATCH: + if (state->pt) { + s[dst] = (unsigned long) get_scratch_regs(state) + val; + } else { + s[dst] = 0; + UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n", + __FUNCTION__, dst, val); + } + break; + case UNW_INSN_MOVE_STACKED: s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp, val); @@ -1666,11 +1712,12 @@ break; case UNW_INSN_LOAD: -#if UNW_DEBUG +#ifdef UNW_DEBUG if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0 || s[val] < TASK_SIZE) { - debug(1, "unwind: rejecting bad psp=0x%lx\n", s[val]); + UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n", + __FUNCTION__, s[val]); break; } #endif @@ -1703,7 +1750,8 @@ if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) { /* don't let obviously bad addresses pollute the cache */ - debug(1, "unwind: rejecting bad ip=0x%lx\n", info->ip); + /* FIXME: should really be level 0 but it occurs too often. KAO */ + UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip); info->rp_loc = 0; return -1; } @@ -1712,8 +1760,9 @@ if (!scr) { scr = build_script(info); if (!scr) { - dprintk("unwind: failed to locate/build unwind script for ip %lx\n", - info->ip); + UNW_DPRINT(0, + "unwind.%s: failed to locate/build unwind script for ip %lx\n", + __FUNCTION__, info->ip); return -1; } have_write_lock = 1; @@ -1746,7 +1795,9 @@ /* restore the ip */ if (!info->rp_loc) { - debug(1, "unwind: failed to locate return link (ip=0x%lx)!\n", info->ip); + /* FIXME: should really be level 0 but it occurs too often. KAO */ + UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", + __FUNCTION__, info->ip); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1756,14 +1807,14 @@ * We don't have unwind info for the gate page, so we consider that part * of user-space for the purpose of unwinding. */ - debug(1, "unwind: reached user-space (ip=0x%lx)\n", ip); + UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } /* restore the cfm: */ if (!info->pfs_loc) { - dprintk("unwind: failed to locate ar.pfs!\n"); + UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1773,16 +1824,18 @@ pr = info->pr; num_regs = 0; if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) { + info->pt = info->sp + 16; if ((pr & (1UL << pNonSys)) != 0) num_regs = *info->cfm_loc & 0x7f; /* size of frame */ info->pfs_loc = - (unsigned long *) (info->sp + 16 + struct_offset(struct pt_regs, ar_pfs)); + (unsigned long *) (info->pt + struct_offset(struct pt_regs, ar_pfs)); + UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt); } else num_regs = (*info->cfm_loc >> 7) & 0x7f; /* size of locals */ info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs); if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) { - dprintk("unwind: bsp (0x%lx) out of range [0x%lx-0x%lx]\n", - info->bsp, info->regstk.limit, info->regstk.top); + UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n", + __FUNCTION__, info->bsp, info->regstk.limit, info->regstk.top); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1790,14 +1843,15 @@ /* restore the sp: */ info->sp = info->psp; if (info->sp < info->memstk.top || info->sp > info->memstk.limit) { - dprintk("unwind: sp (0x%lx) out of range [0x%lx-0x%lx]\n", - info->sp, info->memstk.top, info->memstk.limit); + UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n", + __FUNCTION__, info->sp, info->memstk.top, info->memstk.limit); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) { - dprintk("unwind: ip, sp, bsp remain unchanged; stopping here (ip=0x%lx)\n", ip); + UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n", + __FUNCTION__, ip); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1821,7 +1875,8 @@ while (unw_unwind(info) >= 0) { if (unw_get_rp(info, &ip) < 0) { unw_get_ip(info, &ip); - dprintk("unwind: failed to read return pointer (ip=0x%lx)\n", ip); + UNW_DPRINT(0, "unwind.%s: failed to read return pointer (ip=0x%lx)\n", + __FUNCTION__, ip); return -1; } /* @@ -1832,26 +1887,25 @@ return 0; } unw_get_ip(info, &ip); - dprintk("unwind: failed to unwind to user-level (ip=0x%lx)\n", ip); + UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", __FUNCTION__, ip); return -1; } -void -unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw) +static void +init_frame_info (struct unw_frame_info *info, struct task_struct *t, + struct switch_stack *sw, unsigned long stktop) { - unsigned long rbslimit, rbstop, stklimit, stktop, sol; + unsigned long rbslimit, rbstop, stklimit; STAT(unsigned long start, flags;) STAT(local_irq_save(flags); ++unw.stat.api.inits; start = ia64_get_itc()); /* - * Subtle stuff here: we _could_ unwind through the - * switch_stack frame but we don't want to do that because it - * would be slow as each preserved register would have to be - * processed. Instead, what we do here is zero out the frame - * info and start the unwind process at the function that - * created the switch_stack frame. When a preserved value in - * switch_stack needs to be accessed, run_script() will + * Subtle stuff here: we _could_ unwind through the switch_stack frame but we + * don't want to do that because it would be slow as each preserved register would + * have to be processed. Instead, what we do here is zero out the frame info and + * start the unwind process at the function that created the switch_stack frame. + * When a preserved value in switch_stack needs to be accessed, run_script() will * initialize the appropriate pointer on demand. */ memset(info, 0, sizeof(*info)); @@ -1862,7 +1916,6 @@ rbstop = rbslimit; stklimit = (unsigned long) t + IA64_STK_OFFSET; - stktop = (unsigned long) sw - 16; if (stktop <= rbstop) stktop = rbstop; @@ -1872,15 +1925,56 @@ info->memstk.top = stktop; info->task = t; info->sw = sw; - info->sp = info->psp = (unsigned long) (sw + 1) - 16; + info->sp = info->psp = stktop; + info->pr = sw->pr; + UNW_DPRINT(3, "unwind.%s:\n" + " task 0x%lx\n" + " rbs = [0x%lx-0x%lx)\n" + " stk = [0x%lx-0x%lx)\n" + " pr 0x%lx\n" + " sw 0x%lx\n" + " sp 0x%lx\n", + __FUNCTION__, (unsigned long) task, rbslimit, rbstop, stktop, stklimit, + info->pr, (unsigned long) info->sw, info->sp); + STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags)); +} + +void +unw_init_from_interruption (struct unw_frame_info *info, struct task_struct *t, + struct pt_regs *pt, struct switch_stack *sw) +{ + unsigned long sof; + + init_frame_info(info, t, sw, pt->r12); + info->cfm_loc = &pt->cr_ifs; + sof = *info->cfm_loc & 0x7f; + info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sof); + info->ip = pt->cr_iip + ia64_psr(pt)->ri; + info->pt = (unsigned long) pt; + UNW_DPRINT(3, "unwind.%s:\n" + " bsp 0x%lx\n" + " sof 0x%lx\n" + " ip 0x%lx\n", + info->bsp, sof, info->ip); + find_save_locs(info); +} + +void +unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw) +{ + unsigned long sol; + + init_frame_info(info, t, sw, (unsigned long) (sw + 1) - 16); info->cfm_loc = &sw->ar_pfs; sol = (*info->cfm_loc >> 7) & 0x7f; info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol); info->ip = sw->b0; - info->pr = sw->pr; - + UNW_DPRINT(3, "unwind.%s:\n" + " bsp 0x%lx\n" + " sol 0x%lx\n" + " ip 0x%lx\n", + info->bsp, sol, info->ip); find_save_locs(info); - STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags)); } void @@ -1888,6 +1982,7 @@ { struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16); + UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__); unw_init_frame_info(info, t, sw); } @@ -1915,7 +2010,8 @@ unsigned long flags; if (end - start <= 0) { - dprintk("unwind: ignoring attempt to insert empty unwind table\n"); + UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n", + __FUNCTION__); return 0; } @@ -1945,13 +2041,15 @@ long index; if (!handle) { - dprintk("unwind: ignoring attempt to remove non-existent unwind table\n"); + UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n", + __FUNCTION__); return; } table = handle; if (table == &unw.kernel_table) { - dprintk("unwind: sorry, freeing the kernel's unwind table is a no-can-do!\n"); + UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a " + "no-can-do!\n", __FUNCTION__); return; } @@ -1963,7 +2061,8 @@ if (prev->next == table) break; if (!prev) { - dprintk("unwind: failed to find unwind table %p\n", (void *) table); + UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n", + __FUNCTION__, (void *) table); spin_unlock_irqrestore(&unw.lock, flags); return; } @@ -2015,7 +2114,7 @@ unw.gate_table = alloc_bootmem(size); if (!unw.gate_table) { unw.gate_table_size = 0; - printk("unwind: unable to create unwind data for gate page!\n"); + printk(KERN_ERR "unwind: unable to create unwind data for gate page!\n"); return; } unw.gate_table_size = size; diff -urN linux-2.4.21/arch/ia64/kernel/unwind_i.h linux-2.4.22/arch/ia64/kernel/unwind_i.h --- linux-2.4.21/arch/ia64/kernel/unwind_i.h 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/kernel/unwind_i.h 2003-08-25 04:44:39.000000000 -0700 @@ -137,7 +137,8 @@ UNW_INSN_SETNAT_MEMSTK, /* s[dst+1].nat.type = MEMSTK; s[dst+1].nat.off = *s.pri_unat - s[dst] */ UNW_INSN_SETNAT_TYPE, /* s[dst+1].nat.type = val */ - UNW_INSN_LOAD /* s[dst] = *s[val] */ + UNW_INSN_LOAD, /* s[dst] = *s[val] */ + UNW_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */ }; struct unw_insn { diff -urN linux-2.4.21/arch/ia64/lib/memcpy_mck.S linux-2.4.22/arch/ia64/lib/memcpy_mck.S --- linux-2.4.21/arch/ia64/lib/memcpy_mck.S 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/lib/memcpy_mck.S 2003-08-25 04:44:39.000000000 -0700 @@ -163,7 +163,7 @@ mov ar.ec=2 (p10) br.dpnt.few .aligned_src_tail ;; - .align 32 +// .align 32 1: EX(.ex_handler, (p16) ld8 r34=[src0],16) EK(.ex_handler, (p16) ld8 r38=[src1],16) @@ -320,7 +320,7 @@ (p7) mov ar.lc = r21 (p8) mov ar.lc = r0 ;; - .align 32 +// .align 32 1: lfetch [src_pre_mem], 128 lfetch.excl [dst_pre_mem], 128 br.cloop.dptk.few 1b @@ -526,7 +526,7 @@ shrp r21=r22,r38,shift; /* speculative work */ \ br.sptk.few .unaligned_src_tail /* branch out of jump table */ \ ;; - .align 32 +// .align 32 .jump_table: COPYU(8) // unaligned cases .jmp1: diff -urN linux-2.4.21/arch/ia64/lib/memset.S linux-2.4.22/arch/ia64/lib/memset.S --- linux-2.4.21/arch/ia64/lib/memset.S 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/lib/memset.S 2003-08-25 04:44:39.000000000 -0700 @@ -125,7 +125,7 @@ (p_zr) br.cond.dptk.many .l1b // Jump to use stf.spill ;; } - .align 32 // -------------------------- // L1A: store ahead into cache lines; fill later +// .align 32 // -------------------------- // L1A: store ahead into cache lines; fill later { .mmi and tmp = -(LINE_SIZE), cnt // compute end of range mov ptr9 = ptr1 // used for prefetching @@ -194,7 +194,7 @@ br.cond.dpnt.many .move_bytes_from_alignment // Branch no. 3 ;; } - .align 32 +// .align 32 .l1b: // ------------------------------------ // L1B: store ahead into cache lines; fill later { .mmi and tmp = -(LINE_SIZE), cnt // compute end of range @@ -261,7 +261,7 @@ and cnt = 0x1f, cnt // compute the remaining cnt mov.i ar.lc = loopcnt ;; } - .align 32 +// .align 32 .l2: // ------------------------------------ // L2A: store 32B in 2 cycles { .mmb stf8 [ptr1] = fvalue, 8 diff -urN linux-2.4.21/arch/ia64/lib/swiotlb.c linux-2.4.22/arch/ia64/lib/swiotlb.c --- linux-2.4.21/arch/ia64/lib/swiotlb.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/lib/swiotlb.c 2003-08-25 04:44:39.000000000 -0700 @@ -116,7 +116,7 @@ io_tlb_index = 0; io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); - printk("Placing software IO TLB between 0x%p - 0x%p\n", + printk(KERN_INFO "Placing software IO TLB between 0x%p - 0x%p\n", (void *) io_tlb_start, (void *) io_tlb_end); } diff -urN linux-2.4.21/arch/ia64/mm/extable.c linux-2.4.22/arch/ia64/mm/extable.c --- linux-2.4.21/arch/ia64/mm/extable.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/mm/extable.c 2003-08-25 04:44:39.000000000 -0700 @@ -38,6 +38,8 @@ register unsigned long main_gp __asm__("gp"); #endif +extern spinlock_t modlist_lock; + struct exception_fixup search_exception_table (unsigned long addr) { @@ -52,9 +54,11 @@ return fix; #else struct archdata *archdata; + unsigned long flags; struct module *mp; /* The kernel is the last "module" -- no need to treat it special. */ + spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp; mp = mp->next) { if (!mp->ex_table_start) continue; @@ -65,9 +69,10 @@ addr, (unsigned long) archdata->gp); if (entry) { fix.cont = entry->cont + (unsigned long) archdata->gp; - return fix; + break; } } + spin_unlock_irqrestore(&modlist_lock, flags); #endif return fix; } diff -urN linux-2.4.21/arch/ia64/mm/fault.c linux-2.4.22/arch/ia64/mm/fault.c --- linux-2.4.21/arch/ia64/mm/fault.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/mm/fault.c 2003-08-25 04:44:39.000000000 -0700 @@ -43,6 +43,33 @@ return 0; } +/* + * Return TRUE if ADDRESS points at a page in the kernel's mapped segment + * (inside region 5, on ia64) and that page is present. + */ +static int +mapped_kernel_page_is_present (unsigned long address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset_k(address); + if (pgd_none(*pgd) || pgd_bad(*pgd)) + return 0; + + pmd = pmd_offset(pgd,address); + if (pmd_none(*pmd) || pmd_bad(*pmd)) + return 0; + + ptep = pte_offset(pmd, address); + if (!ptep) + return 0; + + pte = *ptep; + return pte_present(pte); +} + void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs) { @@ -183,6 +210,16 @@ return; /* + * Since we have no vma's for region 5, we might get here even if the address is + * valid, due to the VHPT walker inserting a non present translation that becomes + * stale. If that happens, the non present fault handler already purged the stale + * translation, which fixed the problem. So, we check to see if the translation is + * valid, and return if it is. + */ + if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address)) + return; + + /* * Oops. The kernel tried to access some bad page. We'll have to terminate things * with extreme prejudice. */ @@ -204,7 +241,7 @@ goto survive; } up_read(&mm->mmap_sem); - printk("VM: killing process %s\n", current->comm); + printk(KERN_CRIT "VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); goto no_context; diff -urN linux-2.4.21/arch/ia64/mm/init.c linux-2.4.22/arch/ia64/mm/init.c --- linux-2.4.21/arch/ia64/mm/init.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/mm/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -255,7 +255,7 @@ pte_t *pte; if (!PageReserved(page)) - printk("put_gate_page: gate page at 0x%p not in reserved memory\n", + printk(KERN_ERR "put_gate_page: gate page at 0x%p not in reserved memory\n", page_address(page)); pgd = pgd_offset_k(address); /* note: this is NOT pgd_offset()! */ @@ -560,7 +560,7 @@ efi_memmap_walk(create_mem_map_page_table, 0); free_area_init_node(0, NULL, vmem_map, zones_size, 0, zholes_size); - printk("Virtual mem_map starts at 0x%p\n", mem_map); + printk(KERN_INFO "Virtual mem_map starts at 0x%p\n", mem_map); } #endif } diff -urN linux-2.4.21/arch/ia64/mm/tlb.c linux-2.4.22/arch/ia64/mm/tlb.c --- linux-2.4.21/arch/ia64/mm/tlb.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.22/arch/ia64/mm/tlb.c 2003-08-25 04:44:39.000000000 -0700 @@ -34,10 +34,10 @@ 1 << _PAGE_SIZE_4K ) struct ia64_ctx ia64_ctx = { - lock: SPIN_LOCK_UNLOCKED, - next: 1, - limit: (1 << 15) - 1, /* start out with the safe (architected) limit */ - max_ctx: ~0U + .lock = SPIN_LOCK_UNLOCKED, + .next = 1, + .limit =(1 << 15) - 1, /* start out with the safe (architected) limit */ + .max_ctx = ~0U }; /* @@ -48,6 +48,7 @@ { unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx; struct task_struct *tsk; + int i; if (ia64_ctx.next > max_ctx) ia64_ctx.next = 300; /* skip daemons */ @@ -76,7 +77,14 @@ ia64_ctx.limit = tsk_context; } read_unlock(&tasklist_lock); - flush_tlb_all(); + /* + * Can't call flush_tlb_all() here because of race condition with scheduler [EF] + * and because interrupts are disabled during context switch. + */ + for (i = 0; i < NR_CPUS; ++i) + if (i != smp_processor_id()) + cpu_data(i)->need_tlb_flush = 1; + local_flush_tlb_all(); } void diff -urN linux-2.4.21/arch/ia64/scripts/unwcheck.sh linux-2.4.22/arch/ia64/scripts/unwcheck.sh --- linux-2.4.21/arch/ia64/scripts/unwcheck.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/scripts/unwcheck.sh 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,109 @@ +#!/bin/sh +# Usage: unwcheck.sh +# Pre-requisite: readelf [from Gnu binutils package] +# Purpose: Check the following invariant +# For each code range in the input binary: +# Sum[ lengths of unwind regions] = Number of slots in code range. +# Author : Harish Patil +# First version: January 2002 +# Modified : 2/13/2002 +# Modified : 3/15/2002: duplicate detection +readelf -u $1 | gawk '\ + function todec(hexstr){ + dec = 0; + l = length(hexstr); + for (i = 1; i <= l; i++) + { + c = substr(hexstr, i, 1); + if (c == "A") + dec = dec*16 + 10; + else if (c == "B") + dec = dec*16 + 11; + else if (c == "C") + dec = dec*16 + 12; + else if (c == "D") + dec = dec*16 + 13; + else if (c == "E") + dec = dec*16 + 14; + else if (c == "F") + dec = dec*16 + 15; + else + dec = dec*16 + c; + } + return dec; + } + BEGIN { first = 1; sum_rlen = 0; no_slots = 0; errors=0; no_code_ranges=0; } + { + if (NF==5 && $3=="info") + { + no_code_ranges += 1; + if (first == 0) + { + if (sum_rlen != no_slots) + { + print full_code_range; + print " ", "lo = ", lo, " hi =", hi; + print " ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots; + print " "," ", "*******ERROR ***********"; + print " "," ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots; + errors += 1; + } + sum_rlen = 0; + } + full_code_range = $0; + code_range = $2; + gsub("..$", "", code_range); + gsub("^.", "", code_range); + split(code_range, addr, "-"); + lo = toupper(addr[1]); + + code_range_lo[no_code_ranges] = addr[1]; + occurs[addr[1]] += 1; + full_range[addr[1]] = $0; + + gsub("0X.[0]*", "", lo); + hi = toupper(addr[2]); + gsub("0X.[0]*", "", hi); + no_slots = (todec(hi) - todec(lo))/ 16*3 + first = 0; + } + if (index($0,"rlen") > 0 ) + { + rlen_str = substr($0, index($0,"rlen")); + rlen = rlen_str; + gsub("rlen=", "", rlen); + gsub(")", "", rlen); + sum_rlen = sum_rlen + rlen; + } + } + END { + if (first == 0) + { + if (sum_rlen != no_slots) + { + print "code_range=", code_range; + print " ", "lo = ", lo, " hi =", hi; + print " ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots; + print " "," ", "*******ERROR ***********"; + print " "," ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots; + errors += 1; + } + } + no_duplicates = 0; + for (i=1; i<=no_code_ranges; i++) + { + cr = code_range_lo[i]; + if (reported_cr[cr]==1) continue; + if ( occurs[cr] > 1) + { + reported_cr[cr] = 1; + print "Code range low ", code_range_lo[i], ":", full_range[cr], " occurs: ", occurs[cr], " times."; + print " "; + no_duplicates++; + } + } + print "======================================" + print "Total errors:", errors, "/", no_code_ranges, " duplicates:", no_duplicates; + print "======================================" + } + ' diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/Makefile linux-2.4.22/arch/ia64/sn/fakeprom/Makefile --- linux-2.4.21/arch/ia64/sn/fakeprom/Makefile 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (c) 2000-2002 Silicon Graphics, Inc. All rights reserved. +# Copyright (c) 2000-2003 Silicon Graphics, Inc. All rights reserved. # TOPDIR=../../../.. @@ -13,14 +13,15 @@ OBJ=fpromasm.o main.o fw-emu.o fpmem.o klgraph_init.o obj-y=fprom +EXTRA_CFLAGS += -DSGI_SN2 +EXTRA_AFLAGS += -DSGI_SN2 +AFLAGS += -DSGI_SN2 fprom: $(OBJ) $(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB) .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< clean: rm -f *.o fprom diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/README linux-2.4.22/arch/ia64/sn/fakeprom/README --- linux-2.4.21/arch/ia64/sn/fakeprom/README 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/README 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/fpmem.c linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.c --- linux-2.4.21/arch/ia64/sn/fakeprom/fpmem.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. */ @@ -13,7 +13,7 @@ * FPROM EFI memory descriptor build routines * * - Routines to build the EFI memory descriptor map - * - Should also be usable by the SGI SN1 prom to convert + * - Should also be usable by the SGI prom to convert * klconfig to efi_memmap */ @@ -53,10 +53,7 @@ #define KERNEL_SIZE (4*MB) #define PROMRESERVED_SIZE (1*MB) -#ifdef CONFIG_IA64_SGI_SN1 -#define PHYS_ADDRESS(_n, _x) (((long)_n<<33) | (long)_x) -#define MD_BANK_SHFT 30 -#else +#ifdef SGI_SN2 #define PHYS_ADDRESS(_n, _x) (((long)_n<<38) | (long)_x | 0x3000000000UL) #define MD_BANK_SHFT 34 #endif @@ -77,7 +74,7 @@ return sn_config->cpus; } -/* For SN1, get the index th nasid */ +/* For SN, get the index th nasid */ int GetNasid(int index) @@ -104,40 +101,7 @@ * actually disabled etc. */ -#ifdef CONFIG_IA64_SGI_SN1 -int -IsBankPresent(int index, node_memmap_t nmemmap) -{ - switch (index) { - case 0:return nmemmap.b0; - case 1:return nmemmap.b1; - case 2:return nmemmap.b2; - case 3:return nmemmap.b3; - case 4:return nmemmap.b4; - case 5:return nmemmap.b5; - case 6:return nmemmap.b6; - case 7:return nmemmap.b7; - default:return -1 ; - } -} - -int -GetBankSize(int index, node_memmap_t nmemmap) -{ - switch (index) { - case 0: - case 1:return nmemmap.b01size; - case 2: - case 3:return nmemmap.b23size; - case 4: - case 5:return nmemmap.b45size; - case 6: - case 7:return nmemmap.b67size; - default:return -1 ; - } -} - -#else +#ifdef SGI_SN2 int IsBankPresent(int index, node_memmap_t nmemmap) { @@ -168,13 +132,13 @@ #endif void -build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes) +build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes, long attr) { md->type = type; md->phys_addr = paddr; md->virt_addr = 0; md->num_pages = numbytes >> 12; - md->attribute = EFI_MEMORY_WB; + md->attribute = attr; } int @@ -192,12 +156,12 @@ for (cnode=0;cnode /* - * Structure of the mem config of the node as a SN1 MI reg + * Structure of the mem config of the node as a SN MI reg * Medusa supports this reg config. * * BankSize nibble to bank size mapping @@ -24,32 +24,7 @@ #define MBSHIFT 20 -#ifdef CONFIG_IA64_SGI_SN1 -typedef struct node_memmap_s -{ - unsigned int b0 :1, /* 0 bank 0 present */ - b1 :1, /* 1 bank 1 present */ - r01 :2, /* 2-3 reserved */ - b01size :4, /* 4-7 Size of bank 0 and 1 */ - b2 :1, /* 8 bank 2 present */ - b3 :1, /* 9 bank 3 present */ - r23 :2, /* 10-11 reserved */ - b23size :4, /* 12-15 Size of bank 2 and 3 */ - b4 :1, /* 16 bank 4 present */ - b5 :1, /* 17 bank 5 present */ - r45 :2, /* 18-19 reserved */ - b45size :4, /* 20-23 Size of bank 4 and 5 */ - b6 :1, /* 24 bank 6 present */ - b7 :1, /* 25 bank 7 present */ - r67 :2, /* 26-27 reserved */ - b67size :4; /* 28-31 Size of bank 6 and 7 */ -} node_memmap_t ; - -/* Support the medusa hack for 8M/16M/32M nodes */ -#define SN1_BANK_SIZE_SHIFT (MBSHIFT+6) /* 64 MB */ -#define BankSizeBytes(bsize) ((bsize<6) ? (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) :\ - (1<<((bsize-9)+MBSHIFT))) -#else +#ifdef SGI_SN2 typedef struct node_memmap_s { unsigned int b0size :3, /* 0-2 bank 0 size */ @@ -73,6 +48,8 @@ #define SN2_BANK_SIZE_SHIFT (MBSHIFT+6) /* 64 MB */ #define BankPresent(bsize) (bsize<6) #define BankSizeBytes(bsize) (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0) +#define MD_BANKS_PER_NODE 4 +#define MD_BANKSIZE (1UL << 34) #endif typedef struct sn_memmap_s diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/fprom.lds linux-2.4.22/arch/ia64/sn/fakeprom/fprom.lds --- linux-2.4.21/arch/ia64/sn/fakeprom/fprom.lds 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/fprom.lds 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/fpromasm.S linux-2.4.22/arch/ia64/sn/fakeprom/fpromasm.S --- linux-2.4.21/arch/ia64/sn/fakeprom/fpromasm.S 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/fpromasm.S 2003-08-25 04:44:39.000000000 -0700 @@ -8,7 +8,7 @@ * Copyright (C) 1998-2000 Hewlett-Packard Co * Copyright (C) 1998-2000 David Mosberger-Tang * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. */ @@ -57,9 +57,7 @@ * be 0x00000ffffc000000, but on snia we use the (inverse swizzled) * IOSPEC_BASE value */ -#ifdef CONFIG_IA64_SGI_SN1 -#define IOPB_PA 0xc0000FFFFC000000 -#else +#ifdef SGI_SN2 #define IOPB_PA 0xc000000fcc000000 #endif @@ -84,10 +82,7 @@ // Isolate node number we are running on. mov r6 = ip;; -#ifdef CONFIG_IA64_SGI_SN1 - shr r5 = r6,33;; // r5 = node number - shl r6 = r5,33 // r6 = base memory address of node -#else +#ifdef SGI_SN2 shr r5 = r6,38 // r5 = node number dep r6 = 0,r6,0,36 // r6 = base memory address of node @@ -99,7 +94,7 @@ or r1 = r1,r6 // Relocate to boot node // Lets figure out who we are & put it in the LID register. -#ifdef CONFIG_IA64_SGI_SN2 +#ifdef SGI_SN2 // On SN2, we (currently) pass the cpu number in r10 at boot and r25=3,r10;; movl r16=0x8000008110000400 // Allow IPIs @@ -324,10 +319,7 @@ 1: cmp.eq p6,p7=8,r28 /* PAL_VM_SUMMARY */ (p7) br.cond.sptk.few 1f movl r8=0 -#ifdef CONFIG_IA64_SGI_SN1 - movl r9=0x0203083001151059 - movl r10=0x1232 -#else +#ifdef SGI_SN2 movl r9=0x0203083001151065 movl r10=0x183f #endif diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/fw-emu.c linux-2.4.22/arch/ia64/sn/fakeprom/fw-emu.c --- linux-2.4.21/arch/ia64/sn/fakeprom/fw-emu.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/fw-emu.c 2003-08-25 04:44:39.000000000 -0700 @@ -5,7 +5,7 @@ * Copyright (C) 1998-2000 David Mosberger-Tang * * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -42,7 +42,7 @@ #include #include #include -#ifdef CONFIG_IA64_SGI_SN2 +#ifdef SGI_SN2 #include #include #endif @@ -68,10 +68,7 @@ #define ACPI_SLIT_REVISION 1 #define OEMID "SGI" -#ifdef CONFIG_IA64_SGI_SN1 -#define PRODUCT "SN1" -#define PROXIMITY_DOMAIN(nasid) (nasid) -#else +#ifdef SGI_SN2 #define PRODUCT "SN2" #define PROXIMITY_DOMAIN(nasid) (((nasid)>>1) & 255) #endif @@ -99,12 +96,7 @@ typedef union ia64_nasid_va { struct { -#if defined(CONFIG_IA64_SGI_SN1) - unsigned long off : 33; /* intra-region offset */ - unsigned long nasid : 7; /* NASID */ - unsigned long off2 : 21; /* fill */ - unsigned long reg : 3; /* region number */ -#elif defined(CONFIG_IA64_SGI_SN2) +#if defined(SGI_SN2) unsigned long off : 36; /* intra-region offset */ unsigned long attr : 2; unsigned long nasid : 11; /* NASID */ @@ -124,9 +116,7 @@ #define IS_VIRTUAL_MODE() ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;}) #define ADDR_OF(p) (IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p))) -#if defined(CONFIG_IA64_SGI_SN1) -#define __fwtab_pa(n,x) ({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;}) -#elif defined(CONFIG_IA64_SGI_SN2) +#if defined(SGI_SN2) #define __fwtab_pa(n,x) ({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.f.attr = 3; _v.l;}) #endif @@ -207,7 +197,7 @@ return EFI_UNSUPPORTED; } -#ifdef CONFIG_IA64_SGI_SN2 +#ifdef SGI_SN2 #undef cpu_physical_id #define cpu_physical_id(cpuid) ((ia64_get_lid() >> 16) & 0xffff) @@ -300,7 +290,7 @@ ; } else if (index == SAL_UPDATE_PAL) { ; -#ifdef CONFIG_IA64_SGI_SN2 +#ifdef SGI_SN2 } else if (index == SN_SAL_LOG_CE) { #ifdef ajmtestcpei fprom_send_cpei(); @@ -500,9 +490,7 @@ /* * Pass the parameter base address to the build_efi_xxx routines. */ -#if defined(CONFIG_IA64_SGI_SN1) - build_init(8LL*GB*base_nasid); -#else +#if defined(SGI_SN2) build_init(0x3000000000UL | ((long)base_nasid<<38)); #endif @@ -624,10 +612,7 @@ lsapic20->header.length = sizeof(struct acpi_table_lsapic); lsapic20->acpi_id = cnode*4+cpu; lsapic20->flags.enabled = 1; -#if defined(CONFIG_IA64_SGI_SN1) - lsapic20->eid = cpu; - lsapic20->id = nasid; -#else +#if defined(SGI_SN2) lsapic20->eid = nasid&0xffff; lsapic20->id = (cpu<<4) | (nasid>>16); #endif @@ -648,12 +633,9 @@ srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid); srat_memory_affinity->base_addr_lo = 0; srat_memory_affinity->length_lo = 0; -#if defined(CONFIG_IA64_SGI_SN1) - srat_memory_affinity->base_addr_hi = nasid<<1; - srat_memory_affinity->length_hi = SN1_NODE_SIZE>>32; -#else +#if defined(SGI_SN2) srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4); - srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32; + srat_memory_affinity->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32; #endif srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY; srat_memory_affinity->flags.enabled = 1; @@ -670,10 +652,7 @@ srat_cpu_affinity->header.length = sizeof(struct acpi_table_processor_affinity); srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid); srat_cpu_affinity->flags.enabled = 1; -#if defined(CONFIG_IA64_SGI_SN1) - srat_cpu_affinity->apic_id = nasid; - srat_cpu_affinity->lsapic_eid = cpu; -#else +#if defined(SGI_SN2) srat_cpu_affinity->lsapic_eid = nasid&0xffff; srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16); #endif @@ -707,7 +686,7 @@ sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */ strcpy(sal_systab->oem_id, "SGI"); - strcpy(sal_systab->product_id, "SN1"); + strcpy(sal_systab->product_id, "SN2"); /* fill in an entry point: */ sal_ed->type = SAL_DESC_ENTRY_POINT; @@ -785,9 +764,7 @@ for(cpu=0; cpu 0) diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/klgraph_init.c linux-2.4.22/arch/ia64/sn/fakeprom/klgraph_init.c --- linux-2.4.21/arch/ia64/sn/fakeprom/klgraph_init.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/klgraph_init.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ @@ -49,41 +49,13 @@ klgraph_init(void) { -#ifdef CONFIG_IA64_SGI_SN1 u64 *temp; -#endif /* * Initialize some hub/xbow registers that allows access to * Xbridge etc. These are normally done in PROM. */ /* Write IOERR clear to clear the CRAZY bit in the status */ -#ifdef CONFIG_IA64_SGI_SN1 - *(volatile uint64_t *)0xc0000a0001c001f8 = (uint64_t)0xffffffff; - - /* set widget control register...setting bedrock widget id to b */ - *(volatile uint64_t *)0xc0000a0001c00020 = (uint64_t)0x801b; - - /* set io outbound widget access...allow all */ - *(volatile uint64_t *)0xc0000a0001c00110 = (uint64_t)0xff01; - - /* set io inbound widget access...allow all */ - *(volatile uint64_t *)0xc0000a0001c00118 = (uint64_t)0xff01; - - /* set io crb timeout to max */ - *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff; - *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff; - - /* set local block io permission...allow all */ - *(volatile uint64_t *)0xc0000a0001e04010 = (uint64_t)0xfffffffffffffff; - - /* clear any errors */ - /* clear_ii_error(); medusa should have cleared these */ - - /* set default read response buffers in bridge */ - *(volatile u32 *)0xc0000a000f000280L = 0xba98; - *(volatile u32 *)0xc0000a000f000288L = 0xba98; -#elif CONFIG_IA64_SGI_SN2 *(volatile uint64_t *)0xc000000801c001f8 = (uint64_t)0xffffffff; /* set widget control register...setting bedrock widget id to a */ @@ -108,184 +80,126 @@ /* set default read response buffers in bridge */ // [PI] *(volatile u32 *)0xc00000080f000280L = 0xba98; // [PI] *(volatile u32 *)0xc00000080f000288L = 0xba98; -#endif /* CONFIG_IA64_SGI_SN1 */ - -#ifdef CONFIG_IA64_SGI_SN1 - - /* - * kldir entries initialization - mankato - */ - convert(0x8000000000002000, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002010, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002020, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002030, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002040, 0x434d5f53505f5357, 0x0000000000030000); - convert(0x8000000000002050, 0x0000000000000000, 0x0000000000010000); - convert(0x8000000000002060, 0x0000000000000001, 0x0000000000000000); - convert(0x8000000000002070, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002080, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002090, 0x0000000000000000, 0x0000000000000000); - convert(0x80000000000020a0, 0x0000000000000000, 0x0000000000000000); - convert(0x80000000000020b0, 0x0000000000000000, 0x0000000000000000); - convert(0x80000000000020c0, 0x434d5f53505f5357, 0x0000000000000000); - convert(0x80000000000020d0, 0x0000000000002400, 0x0000000000000400); - convert(0x80000000000020e0, 0x0000000000000001, 0x0000000000000000); - convert(0x80000000000020f0, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002100, 0x434d5f53505f5357, 0x0000000000040000); - convert(0x8000000000002110, 0x0000000000000000, 0xffffffffffffffff); - convert(0x8000000000002120, 0x0000000000000001, 0x0000000000000000); - convert(0x8000000000002130, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002140, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002150, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002160, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002170, 0x0000000000000000, 0x0000000000000000); - convert(0x8000000000002180, 0x434d5f53505f5357, 0x0000000000020000); - convert(0x8000000000002190, 0x0000000000000000, 0x0000000000010000); - convert(0x80000000000021a0, 0x0000000000000001, 0x0000000000000000); - /* - * klconfig entries initialization - mankato - */ - convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000); - convert(0x0000000000030010, 0x0003007000000018, 0x800002000f820178); - convert(0x0000000000030020, 0x80000a000f024000, 0x800002000f800000); - convert(0x0000000000030030, 0x0300fafa00012580, 0x00000000040f0000); - convert(0x0000000000030040, 0x0000000000000000, 0x0003097000030070); - convert(0x0000000000030050, 0x00030970000303b0, 0x0003181000033f70); - convert(0x0000000000030060, 0x0003d51000037570, 0x0000000000038330); - convert(0x0000000000030070, 0x0203110100030140, 0x0001000000000101); - convert(0x0000000000030080, 0x0900000000000000, 0x000000004e465e67); - convert(0x0000000000030090, 0x0003097000000000, 0x00030b1000030a40); - convert(0x00000000000300a0, 0x00030cb000030be0, 0x000315a0000314d0); - convert(0x00000000000300b0, 0x0003174000031670, 0x0000000000000000); - convert(0x0000000000030100, 0x000000000000001a, 0x3350490000000000); - convert(0x0000000000030110, 0x0000000000000037, 0x0000000000000000); - convert(0x0000000000030140, 0x0002420100030210, 0x0001000000000101); - convert(0x0000000000030150, 0x0100000000000000, 0xffffffffffffffff); - convert(0x0000000000030160, 0x00030d8000000000, 0x0000000000030e50); - convert(0x00000000000301c0, 0x0000000000000000, 0x0000000000030070); - convert(0x00000000000301d0, 0x0000000000000025, 0x424f490000000000); - convert(0x00000000000301e0, 0x000000004b434952, 0x0000000000000000); - convert(0x0000000000030210, 0x00027101000302e0, 0x00010000000e4101); - convert(0x0000000000030220, 0x0200000000000000, 0xffffffffffffffff); - convert(0x0000000000030230, 0x00030f2000000000, 0x0000000000030ff0); - convert(0x0000000000030290, 0x0000000000000000, 0x0000000000030140); - convert(0x00000000000302a0, 0x0000000000000026, 0x7262490000000000); - convert(0x00000000000302b0, 0x00000000006b6369, 0x0000000000000000); - convert(0x00000000000302e0, 0x0002710100000000, 0x00010000000f3101); - convert(0x00000000000302f0, 0x0500000000000000, 0xffffffffffffffff); - convert(0x0000000000030300, 0x000310c000000000, 0x0003126000031190); - convert(0x0000000000030310, 0x0003140000031330, 0x0000000000000000); - convert(0x0000000000030360, 0x0000000000000000, 0x0000000000030140); - convert(0x0000000000030370, 0x0000000000000029, 0x7262490000000000); - convert(0x0000000000030380, 0x00000000006b6369, 0x0000000000000000); - convert(0x0000000000030970, 0x0000000002010102, 0x0000000000000000); - convert(0x0000000000030980, 0x000000004e465e67, 0xffffffff00000000); - /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */ - convert(0x00000000000309a0, 0x0000000000037570, 0xffffffff00000000); - convert(0x00000000000309b0, 0x0000000000030070, 0x0000000000000000); - convert(0x00000000000309c0, 0x000000000003f420, 0x0000000000000000); - convert(0x0000000000030a40, 0x0000000002010125, 0x0000000000000000); - convert(0x0000000000030a50, 0xffffffffffffffff, 0xffffffff00000000); - convert(0x0000000000030a70, 0x0000000000037b78, 0x0000000000000000); - convert(0x0000000000030b10, 0x0000000002010125, 0x0000000000000000); - convert(0x0000000000030b20, 0xffffffffffffffff, 0xffffffff00000000); - convert(0x0000000000030b40, 0x0000000000037d30, 0x0000000000000001); - convert(0x0000000000030be0, 0x00000000ff010203, 0x0000000000000000); - convert(0x0000000000030bf0, 0xffffffffffffffff, 0xffffffff000000ff); - convert(0x0000000000030c10, 0x0000000000037ee8, 0x0100010000000200); - convert(0x0000000000030cb0, 0x00000000ff310111, 0x0000000000000000); - convert(0x0000000000030cc0, 0xffffffffffffffff, 0x0000000000000000); - convert(0x0000000000030d80, 0x0000000002010104, 0x0000000000000000); - convert(0x0000000000030d90, 0xffffffffffffffff, 0x00000000000000ff); - convert(0x0000000000030db0, 0x0000000000037f18, 0x0000000000000000); - convert(0x0000000000030dc0, 0x0000000000000000, 0x0003007000060000); - convert(0x0000000000030de0, 0x0000000000000000, 0x0003021000050000); - convert(0x0000000000030df0, 0x000302e000050000, 0x0000000000000000); - convert(0x0000000000030e30, 0x0000000000000000, 0x000000000000000a); - convert(0x0000000000030e50, 0x00000000ff00011a, 0x0000000000000000); - convert(0x0000000000030e60, 0xffffffffffffffff, 0x0000000000000000); - convert(0x0000000000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e); - convert(0x0000000000030e90, 0x000000000000bc6e, 0x0000000000000000); - convert(0x0000000000030f20, 0x0000000002010205, 0x00000000d0020000); - convert(0x0000000000030f30, 0xffffffffffffffff, 0x0000000e0000000e); - convert(0x0000000000030f40, 0x000000000000000e, 0x0000000000000000); - convert(0x0000000000030f50, 0x0000000000038010, 0x00000000000007ff); - convert(0x0000000000030f70, 0x0000000000000000, 0x0000000022001077); - convert(0x0000000000030fa0, 0x0000000000000000, 0x000000000003f4a8); - convert(0x0000000000030ff0, 0x0000000000310120, 0x0000000000000000); - convert(0x0000000000031000, 0xffffffffffffffff, 0xffffffff00000002); - convert(0x0000000000031010, 0x000000000000000e, 0x0000000000000000); - convert(0x0000000000031020, 0x0000000000038088, 0x0000000000000000); - convert(0x00000000000310c0, 0x0000000002010205, 0x00000000d0020000); - convert(0x00000000000310d0, 0xffffffffffffffff, 0x0000000f0000000f); - convert(0x00000000000310e0, 0x000000000000000f, 0x0000000000000000); - convert(0x00000000000310f0, 0x00000000000380b8, 0x00000000000007ff); - convert(0x0000000000031120, 0x0000000022001077, 0x00000000000310a9); - convert(0x0000000000031130, 0x00000000580211c1, 0x000000008009104c); - convert(0x0000000000031140, 0x0000000000000000, 0x000000000003f4c0); - convert(0x0000000000031190, 0x0000000000310120, 0x0000000000000000); - convert(0x00000000000311a0, 0xffffffffffffffff, 0xffffffff00000003); - convert(0x00000000000311b0, 0x000000000000000f, 0x0000000000000000); - convert(0x00000000000311c0, 0x0000000000038130, 0x0000000000000000); - convert(0x0000000000031260, 0x0000000000110106, 0x0000000000000000); - convert(0x0000000000031270, 0xffffffffffffffff, 0xffffffff00000004); - convert(0x0000000000031280, 0x000000000000000f, 0x0000000000000000); - convert(0x00000000000312a0, 0x00000000ff110013, 0x0000000000000000); - convert(0x00000000000312b0, 0xffffffffffffffff, 0xffffffff00000000); - convert(0x00000000000312c0, 0x000000000000000f, 0x0000000000000000); - convert(0x00000000000312e0, 0x0000000000110012, 0x0000000000000000); - convert(0x00000000000312f0, 0xffffffffffffffff, 0xffffffff00000000); - convert(0x0000000000031300, 0x000000000000000f, 0x0000000000000000); - convert(0x0000000000031310, 0x0000000000038160, 0x0000000000000000); - convert(0x0000000000031330, 0x00000000ff310122, 0x0000000000000000); - convert(0x0000000000031340, 0xffffffffffffffff, 0xffffffff00000005); - convert(0x0000000000031350, 0x000000000000000f, 0x0000000000000000); - convert(0x0000000000031360, 0x0000000000038190, 0x0000000000000000); - convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000); - convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000); - convert(0x0000000000031410, 0xffffffffffffffff, 0xffffffff00000006); - convert(0x0000000000031420, 0x000000000000000f, 0x0000000000000000); - convert(0x0000000000031430, 0x00000000000381c0, 0x0000000000000000); - convert(0x00000000000314d0, 0x00000000ff010201, 0x0000000000000000); - convert(0x00000000000314e0, 0xffffffffffffffff, 0xffffffff00000000); - convert(0x0000000000031500, 0x00000000000381f0, 0x000030430000ffff); - convert(0x0000000000031510, 0x000000000000ffff, 0x0000000000000000); - convert(0x00000000000315a0, 0x00000020ff000201, 0x0000000000000000); - convert(0x00000000000315b0, 0xffffffffffffffff, 0xffffffff00000001); - convert(0x00000000000315d0, 0x0000000000038240, 0x00003f3f0000ffff); - convert(0x00000000000315e0, 0x000000000000ffff, 0x0000000000000000); - convert(0x0000000000031670, 0x00000000ff010201, 0x0000000000000000); - convert(0x0000000000031680, 0xffffffffffffffff, 0x0000000100000002); - convert(0x00000000000316a0, 0x0000000000038290, 0x000030430000ffff); - convert(0x00000000000316b0, 0x000000000000ffff, 0x0000000000000000); - convert(0x0000000000031740, 0x00000020ff000201, 0x0000000000000000); - convert(0x0000000000031750, 0xffffffffffffffff, 0x0000000500000003); - convert(0x0000000000031770, 0x00000000000382e0, 0x00003f3f0000ffff); - convert(0x0000000000031780, 0x000000000000ffff, 0x0000000000000000); - - /* - * GDA initialization - mankato - */ - convert(0x8000000000002400, 0x0000000258464552, 0x000000000ead0000); - convert(0x8000000000002480, 0xffffffff00010000, 0xffffffffffffffff); - convert(0x8000000000002490, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x80000000000024a0, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x80000000000024b0, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x80000000000024c0, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x80000000000024d0, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x80000000000024e0, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x80000000000024f0, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002500, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002510, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002520, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002530, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002540, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002550, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002560, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002570, 0xffffffffffffffff, 0xffffffffffffffff); - convert(0x8000000000002580, 0x000000000000ffff, 0x0000000000000000); -#endif - + /* + * klconfig entries initialization - mankato + */ + convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000); + convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178); + convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000); + convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000); + convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070); + convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70); + convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330); + convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101); + convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67); + convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40); + convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0); + convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000); + convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000); + convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000); + convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101); + convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff); + convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50); + convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070); + convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000); + convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000); + convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101); + convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff); + convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0); + convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140); + convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000); + convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000); + convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101); + convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff); + convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190); + convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000); + convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140); + convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000); + convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000); + convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000); + convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000); + /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */ + convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000); + convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000); + convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000); + convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000); + convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000); + convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000); + convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000); + convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000); + convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001); + convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000); + convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff); + convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200); + convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000); + convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000); + convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000); + convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff); + convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000); + convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000); + convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000); + convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000); + convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a); + convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000); + convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000); + convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e); + convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000); + convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000); + convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e); + convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000); + convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff); + convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077); + convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8); + convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000); + convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002); + convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000); + convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000); + convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000); + convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f); + convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000); + convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff); + convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9); + convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c); + convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0); + convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000); + convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003); + convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000); + convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000); + convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000); + convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004); + convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004); + convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000); + convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000); + convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000); + convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000); + convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000); + convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000); + convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000); + convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000); + convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000); + convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005); + convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000); + convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000); + convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000); + convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000); + convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006); + convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000); + convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000); + convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000); + convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000); + convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff); + convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000); + convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000); + convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001); + convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff); + convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000); + convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000); + convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002); + convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff); + convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000); + convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000); + convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003); + convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff); + convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000); } - diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/main.c linux-2.4.22/arch/ia64/sn/fakeprom/main.c --- linux-2.4.21/arch/ia64/sn/fakeprom/main.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/main.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. */ @@ -33,25 +33,9 @@ * First lets figure out who we are. This is done from the * LID passed to us. */ - -#ifdef CONFIG_IA64_SGI_SN1 - nasid = (lid>>24); - syn = (lid>>17)&1; - cpu = (lid>>16)&1; - - /* - * Now pick a synergy master to initialize synergy registers. - */ - if (test_and_set_bit(syn, &nasidmaster[nasid]) == 0) { - synergy_init(nasid, syn); - test_and_set_bit(syn+2, &nasidmaster[nasid]); - } else - while (get_bit(syn+2, &nasidmaster[nasid]) == 0); -#else nasid = (lid>>16)&0xfff; cpu = (lid>>28)&3; syn = 0; -#endif /* * Now pick a nasid master to initialize Bedrock registers. diff -urN linux-2.4.21/arch/ia64/sn/fakeprom/runsim linux-2.4.22/arch/ia64/sn/fakeprom/runsim --- linux-2.4.21/arch/ia64/sn/fakeprom/runsim 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/fakeprom/runsim 1969-12-31 16:00:00.000000000 -0800 @@ -1,387 +0,0 @@ -#!/bin/sh - -# Script for running PROMs and LINUX kernwls on medusa. -# Type "sim -H" for instructions. - -MEDUSA=${MEDUSA:-/home/rickc/official_medusa/medusa} - -# ------------------ err ----------------------- -err() { - echo "ERROR - $1" - exit 1 -} - -# ---------------- help ---------------------- -help() { -cat <] <-p> | <-k> [] - -p Create PROM control file & links - -k Create LINUX control file & links - -c Control file name [Default: cf] - Path to directory that contains the linux or PROM files. - The directory can be any of the following: - (linux simulations) - worktree - worktree/linux - any directory with vmlinux, vmlinux.sym & fprom files - (prom simulations) - worktree - worktree/stand/arcs/IP37prom/dev - any directory with fw.bin & fw.sim files - - Simulations: - sim [-X ] [-o ] [-M] [] - -c Control file name [Default: cf] - -M Pipe output thru fmtmedusa - -o Output filename (copy of all commands/output) [Default: simout] - -X Specifies number of instructions to execute [Default: 0] - (Used only in auto test mode - not described here) - -Examples: - sim -p # create control file (cf) & links for prom simulations - sim -k # create control file (cf) & links for linux simulations - sim -p -c cfprom # create a prom control file (cfprom) only. No links are made. - - sim # run medusa using previously created links & - # control file (cf). -END -exit 1 -} - -# ----------------------- create control file header -------------------- -create_cf_header() { -cat <>$CF -# -# Template for a control file for running linux kernels under medusa. -# You probably want to make mods here but this is a good starting point. -# - -# Preferences -setenv cpu_stepping A -setenv exceptionPrint off -setenv interrupt_messages off -setenv lastPCsize 100000 -setenv low_power_mode on -setenv partialIntelChipSet on -setenv printIntelMessages off -setenv prom_write_action halt -setenv prom_write_messages on -setenv step_quantum 100 -setenv swizzling on -setenv tsconsole on -setenv uart_echo on -symbols on - -# IDE disk params -setenv diskCylinders 611 -setenv bootDrive C -setenv diskHeads 16 -setenv diskPath idedisk -setenv diskPresent 1 -setenv diskSpt 63 - -# Hardware config -setenv coherency_type nasid -setenv cpu_cache_type default -setenv synergy_cache_type syn_cac_64m_8w -setenv l4_uc_snoop off - -# Numalink config -setenv route_enable on -setenv network_type router # Select [xbar|router] -setenv network_warning 0xff - -END -} - - -# ------------------ create control file entries for linux simulations ------------- -create_cf_linux() { -cat <>$CF -# Kernel specific options -setenv calias_size 0 -setenv mca_on_memory_failure off -setenv LOADPC 0x00100000 # FPROM load address/entry point (8 digits!) -setenv symbol_table vmlinux.sym -load fprom -load vmlinux - -# Useful breakpoints to always have set. Add more if desired. -break 0xe000000000505e00 all # dispatch_to_fault_handler -break panic all # stop on panic -break die_if_kernel all # may as well stop - -END -} - -# ------------------ create control file entries for prom simulations --------------- -create_cf_prom() { - SYM2="" - ADDR="0x80000000ff800000" - [ "$EMBEDDED_LINUX" != "0" ] || SYM2="setenv symbol_table2 vmlinux.sym" - [ "$SIZE" = "8MB" ] || ADDR="0x80000000ffc00000" - cat <>$CF -# PROM specific options -setenv mca_on_memory_failure on -setenv LOADPC 0x80000000ffffffb0 -setenv promFile fw.bin -setenv promAddr $ADDR -setenv symbol_table fw.sym -$SYM2 - -# Useful breakpoints to always have set. Add more if desired. -break ivt_gexx all -break ivt_brk all -break PROM_Panic_Spin all -break PROM_Panic all -break PROM_C_Panic all -break fled_die all -break ResetNow all -break zzzbkpt all - -END -} - - -# ------------------ create control file entries for memory configuration ------------- -create_cf_memory() { -cat <>$CF -# CPU/Memory map format: -# setenv nodeN_memory_config 0xBSBSBSBS -# B=banksize (0=unused, 1=64M, 2=128M, .., 5-1G, c=8M, d=16M, e=32M) -# S=bank enable (0=both disable, 3=both enable, 2=bank1 enable, 1=bank0 enable) -# rightmost digits are for bank 0, the lowest address. -# setenv nodeN_nasid -# specifies the NASID for the node. This is used ONLY if booting the kernel. -# On PROM configurations, set to 0 - PROM will change it later. -# setenv nodeN_cpu_config -# Set bit number N to 1 to enable cpu N. Ex., a value of 5 enables cpu 0 & 2. -# -# Repeat the above 3 commands for each node. -# -# For kernel, default to 32MB. Although this is not a valid hardware configuration, -# it runs faster on medusa. For PROM, 64MB is smallest allowed value. - -setenv node0_cpu_config 0x1 # Enable only cpu 0 on the node -END - -if [ $LINUX -eq 1 ] ; then -cat <>$CF -setenv node0_nasid 0 # cnode 0 has NASID 0 -setenv node0_memory_config 0xe1 # 32MB -END -else -cat <>$CF -setenv node0_memory_config 0x31 # 256MB -END -fi -} - -# -------------------- set links to linux files ------------------------- -set_linux_links() { - if [ -d $D/linux/arch ] ; then - D=$D/linux - elif [ -d $D/arch -o -e vmlinux.sym -o -e $D/vmlinux ] ; then - D=$D - else - err "cant determine directory for linux binaries" - fi - rm -rf vmlinux vmlinux.sym fprom - ln -s $D/vmlinux vmlinux - if [ -f $D/vmlinux.sym ] ; then - ln -s $D/vmlinux.sym vmlinux.sym - elif [ -f $D/System.map ] ; then - ln -s $D/System.map vmlinux.sym - fi - if [ -d $D/arch ] ; then - ln -s $D/arch/ia64/sn/fprom/fprom fprom - else - ln -s $D/fprom fprom - fi - echo " .. Created links to linux files" -} - -# -------------------- set links to prom files ------------------------- -set_prom_links() { - if [ -d $D/stand ] ; then - D=$D/stand/arcs/IP37prom/dev - elif [ -d $D/sal ] ; then - D=$D - else - err "cant determine directory for PROM binaries" - fi - SETUP="/tmp/tmp.$$" - rm -r -f $SETUP - sed 's/export/setenv/' < $D/../../../../.setup | sed 's/=/ /' >$SETUP - egrep -q '^ *setenv *PROMSIZE *8MB|^ *export' $SETUP - if [ $? -eq 0 ] ; then - SIZE="8MB" - else - SIZE="4MB" - fi - grep -q '^ *setenv *LAUNCH_VMLINUX' $SETUP - EMBEDDED_LINUX=$? - PRODUCT=`grep '^ *setenv *PRODUCT' $SETUP | cut -d" " -f3` - rm -f fw.bin fw.map fw.sym vmlinux vmlinux.sym fprom $SETUP - SDIR="${PRODUCT}${SIZE}.O" - BIN="${PRODUCT}ip37prom${SIZE}" - ln -s $D/$SDIR/$BIN.bin fw.bin - ln -s $D/$SDIR/$BIN.map fw.map - ln -s $D/$SDIR/$BIN.sym fw.sym - echo " .. Created links to $SIZE prom files" - if [ $EMBEDDED_LINUX -eq 0 ] ; then - ln -s $D/linux/vmlinux vmlinux - ln -s $D/linux/vmlinux.sym vmlinux.sym - if [ -d linux/arch ] ; then - ln -s $D/linux/arch/ia64/sn/fprom/fprom fprom - else - ln -s $D/linux/fprom fprom - fi - echo " .. Created links to embedded linux files in prom tree" - fi -} - -# --------------- start of shell script -------------------------------- -OUT="simout" -FMTMED=0 -STEPCNT=0 -PROM=0 -LINUX=0 -NCF="cf" -while getopts "HMX:c:o:pk" c ; do - case ${c} in - H) help;; - M) FMTMED=1;; - X) STEPCNT=${OPTARG};; - c) NCF=${OPTARG};; - k) PROM=0;LINUX=1;; - p) PROM=1;LINUX=0;; - o) OUT=${OPTARG};; - \?) exit 1;; - esac -done -shift `expr ${OPTIND} - 1` - -# Check if command is for creating control file and/or links to images. -if [ $PROM -eq 1 -o $LINUX -eq 1 ] ; then - CF=$NCF - [ ! -f $CF ] || err "wont overwrite an existing control file ($CF)" - if [ $# -gt 0 ] ; then - D=$1 - [ -d $D ] || err "cannot find directory $D" - [ $PROM -eq 0 ] || set_prom_links - [ $LINUX -eq 0 ] || set_linux_links - fi - create_cf_header - [ $PROM -eq 0 ] || create_cf_prom - [ $LINUX -eq 0 ] || create_cf_linux - [ ! -f ../idedisk ] || ln -s ../idedisk . - create_cf_memory - echo " .. Basic control file created (in $CF). You might want to edit" - echo " this file (at least, look at it)." - exit 0 -fi - -# Verify that the control file exists -CF=${1:-$NCF} -[ -f $CF ] || err "No control file exists. For help, type: $0 -H" - -# Build the .cf files from the user control file. The .cf file is -# identical except that the actual start & load addresses are inserted -# into the file. In addition, the FPROM commands for configuring memory -# and LIDs are generated. - -rm -f .cf .cf1 .cf2 -awk ' -function strtonum(n) { - if (substr(n,1,2) != "0x") - return int(n) - n = substr(n,3) - r=0 - while (length(n) > 0) { - r = r*16+(index("0123456789abcdef", substr(n,1,1))-1) - n = substr(n,2) - } - return r - } -/^#/ {next} -/^$/ {next} -/^setenv *LOADPC/ {loadpc = $3; next} -/^setenv *node.._cpu_config/ {n=int(substr($2,5,2)); cpuconf[n] = strtonum($3); print; next} -/^setenv *node.._memory_config/ {n=int(substr($2,5,2)); memconf[n] = strtonum($3); print; next} -/^setenv *node.._nasid/ {n=int(substr($2,5,2)); nasid[n] = strtonum($3); print; next} -/^setenv *node._cpu_config/ {n=int(substr($2,5,1)); cpuconf[n] = strtonum($3); print; next} -/^setenv *node._memory_config/ {n=int(substr($2,5,1)); memconf[n] = strtonum($3); print; next} -/^setenv *node._nasid/ {n=int(substr($2,5,1)); nasid[n] = strtonum($3); print; next} - {print} -END { - # Generate the memmap info that starts at the beginning of - # the node the kernel was loaded on. - loadnasid = nasid[0] - cnode = 0 - for (i=0; i<128; i++) { - if (memconf[i] != "") { - printf "sm 0x%x%08x 0x%x%04x%04x\n", - 2*loadnasid, 8*cnodes+8, memconf[i], cpuconf[i], nasid[i] - cnodes++ - cpus += substr("0112122312232334", cpuconf[i]+1,1) - } - } - printf "sm 0x%x00000000 0x%x%08x\n", 2*loadnasid, cnodes, cpus - printf "setenv number_of_nodes %d\n", cnodes - - # Now set the starting PC for each cpu. - cnode = 0 - lowcpu=-1 - for (i=0; i<128; i++) { - if (memconf[i] != "") { - printf "setnode %d\n", cnode - conf = cpuconf[i] - for (j=0; j<4; j++) { - if (conf != int(conf/2)*2) { - printf "setcpu %d\n", j - if (length(loadpc) == 18) - printf "sr pc %s\n", loadpc - else - printf "sr pc 0x%x%s\n", 2*loadnasid, substr(loadpc,3) - if (lowcpu == -1) - lowcpu = j - } - conf = int(conf/2) - } - cnode++ - } - } - printf "setnode 0\n" - printf "setcpu %d\n", lowcpu - } -' <$CF >.cf - -# Now build the .cf1 & .cf2 control files. -CF2_LINES="^sm |^break |^run |^si |^quit |^symbols " -egrep "$CF2_LINES" .cf >.cf2 -egrep -v "$CF2_LINES" .cf >.cf1 -if [ $STEPCNT -ne 0 ] ; then - echo "s $STEPCNT" >>.cf2 - echo "lastpc 1000" >>.cf2 - echo "q" >>.cf2 -fi -if [ -f vmlinux.sym ] ; then - awk '/ _start$/ {print "sr g 9 0x" $3}' < vmlinux.sym >> .cf2 -fi -echo "script-on $OUT" >>.cf2 - -# Now start medusa.... -if [ $FMTMED -ne 0 ] ; then - $MEDUSA -system mpsn1 -c .cf1 -i .cf2 | fmtmedusa -elif [ $STEPCNT -eq 0 ] ; then - $MEDUSA -system mpsn1 -c .cf1 -i .cf2 -else - $MEDUSA -system mpsn1 -c .cf1 -i .cf2 2>&1 -fi diff -urN linux-2.4.21/arch/ia64/sn/io/Makefile linux-2.4.22/arch/ia64/sn/io/Makefile --- linux-2.4.21/arch/ia64/sn/io/Makefile 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -3,31 +3,34 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (C) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. # # Makefile for the sn kernel routines. EXTRA_CFLAGS := -DLITTLE_ENDIAN -ifdef CONFIG_IA64_SGI_SN2 EXTRA_CFLAGS += -DSHUB_SWAP_WAR -endif O_TARGET := sgiio.o -export-objs := hcl.o pci_dma.o +obj-y := sgi_if.o xswitch.o sgi_io_sim.o \ + cdl.o io.o + +obj-y += sn2/snio.o machvec/snio.o \ + drivers/snio.o platform_init/snio.o -obj-y := stubs.o sgi_if.o xswitch.o klgraph_hack.o \ - hcl.o labelcl.o invent.o sgi_io_sim.o \ - klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \ - alenlist.o pci.o pci_dma.o ate_utils.o \ - ifconfig_net.o io.o ifconfig_bus.o - -obj-$(CONFIG_IA64_SGI_SN1) += sn1/snio.o -obj-$(CONFIG_IA64_SGI_SN2) += sn2/snio.o -obj-$(CONFIG_PCIBA) += pciba.o +ifdef CONFIG_HWGFS_FS +obj-$(CONFIG_HWGFS_FS) += hwgfs/snio.o +else +obj-$(CONFIG_DEVFS_FS) += hwgdfs/snio.o +endif -subdir-$(CONFIG_IA64_SGI_SN1) += sn1 -subdir-$(CONFIG_IA64_SGI_SN2) += sn2 +subdir-y += sn2 machvec drivers platform_init + +ifdef CONFIG_HWGFS_FS +subdir-$(CONFIG_HWGFS_FS) += hwgfs +else +subdir-$(CONFIG_DEVFS_FS) += hwgdfs +endif include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/alenlist.c linux-2.4.22/arch/ia64/sn/io/alenlist.c --- linux-2.4.21/arch/ia64/sn/io/alenlist.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/alenlist.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,899 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* Implementation of Address/Length Lists. */ - - -#include -#include -#include -#include -#include - -/* - * Logically, an Address/Length List is a list of Pairs, where each pair - * holds an Address and a Length, all in some Address Space. In this - * context, "Address Space" is a particular Crosstalk Widget address - * space, a PCI device address space, a VME bus address space, a - * physical memory address space, etc. - * - * The main use for these Lists is to provide a single mechanism that - * describes where in an address space a DMA occurs. This allows the - * various I/O Bus support layers to provide a single interface for - * DMA mapping and DMA translation without regard to how the DMA target - * was specified by upper layers. The upper layers commonly specify a - * DMA target via a buf structure page list, a kernel virtual address, - * a user virtual address, a vector of addresses (a la uio and iov), - * or possibly a pfn list. - * - * Address/Length Lists also enable drivers to take advantage of their - * inate scatter/gather capabilities in systems where some address - * translation may be required between bus adapters. The driver forms - * a List that represents physical memory targets. This list is passed - * to the various adapters, which apply various translations. The final - * list that's returned to the driver is in terms of its local address - * address space -- addresses which can be passed off to a scatter/gather - * capable DMA controller. - * - * The current implementation is intended to be useful both in kernels - * that support interrupt threads (INTR_KTHREAD) and in systems that do - * not support interrupt threads. Of course, in the latter case, some - * interfaces can be called only within a suspendable context. - * - * Basic operations on Address/Length Lists include: - * alenlist_create Create a list - * alenlist_clear Clear a list - * alenlist_destroy Destroy a list - * alenlist_append Append a Pair to the end of a list - * alenlist_replace Replace a Pair in the middle of a list - * alenlist_get Get an Address/Length Pair from a list - * alenlist_size Return the number of Pairs in a list - * alenlist_concat Append one list to the end of another - * alenlist_clone Create a new copy of a list - * - * Operations that convert from upper-level specifications to Address/ - * Length Lists currently include: - * kvaddr_to_alenlist Convert from a kernel virtual address - * uvaddr_to_alenlist Convert from a user virtual address - * buf_to_alenlist Convert from a buf structure - * alenlist_done Tell system that we're done with an alenlist - * obtained from a conversion. - * Additional convenience operations: - * alenpair_init Create a list and initialize it with a Pair - * alenpair_get Peek at the first pair on a List - * - * A supporting type for Address/Length Lists is an alenlist_cursor_t. A - * cursor marks a position in a List, and determines which Pair is fetched - * by alenlist_get. - * alenlist_cursor_create Allocate and initialize a cursor - * alenlist_cursor_destroy Free space consumed by a cursor - * alenlist_cursor_init (Re-)Initialize a cursor to point - * to the start of a list - * alenlist_cursor_clone Clone a cursor (at the current offset) - * alenlist_cursor_offset Return the number of bytes into - * a list that this cursor marks - * Multiple cursors can point at various points into a List. Also, each - * list maintains one "internal cursor" which may be updated by alenlist_clear - * and alenlist_get. If calling code simply wishes to scan sequentially - * through a list starting at the beginning, and if it is the only user of - * a list, it can rely on this internal cursor rather than managing a - * separate explicit cursor. - * - * The current implementation allows callers to allocate both cursors and - * the lists as local stack (structure) variables. This allows for some - * extra efficiency at the expense of forward binary compatibility. It - * is recommended that customer drivers refrain from local allocation. - * In fact, we likely will choose to move the structures out of the public - * header file into a private place in order to discourage this usage. - * - * Currently, no locking is provided by the alenlist implementation. - * - * Implementation notes: - * For efficiency, Pairs are grouped into "chunks" of, say, 32 Pairs - * and a List consists of some number of these chunks. Chunks are completely - * invisible to calling code. Chunks should be large enough to hold most - * standard-sized DMA's, but not so large that they consume excessive space. - * - * It is generally expected that Lists will be constructed at one time and - * scanned at a later time. It is NOT expected that drivers will scan - * a List while the List is simultaneously extended, although this is - * theoretically possible with sufficient upper-level locking. - * - * In order to support demands of Real-Time drivers and in order to support - * swapping under low-memory conditions, we support the concept of a - * "pre-allocated fixed-sized List". After creating a List with - * alenlist_create, a driver may explicitly grow the list (via "alenlist_grow") - * to a specific number of Address/Length pairs. It is guaranteed that future - * operations involving this list will never automatically grow the list - * (i.e. if growth is ever required, the operation will fail). Additionally, - * operations that use alenlist's (e.g. DMA operations) accept a flag which - * causes processing to take place "in-situ"; that is, the input alenlist - * entries are replaced with output alenlist entries. The combination of - * pre-allocated Lists and in-situ processing allows us to avoid the - * potential deadlock scenario where we sleep (waiting for memory) in the - * swap out path. - * - * For debugging, we track the number of allocated Lists in alenlist_count - * the number of allocated chunks in alenlist_chunk_count, and the number - * of allocate cursors in alenlist_cursor_count. We also provide a debug - * routine, alenlist_show, which dumps the contents of an Address/Length List. - * - * Currently, Lists are formed by drivers on-demand. Eventually, we may - * associate an alenlist with a buf structure and keep it up to date as - * we go along. In that case, buf_to_alenlist simply returns a pointer - * to the existing List, and increments the Lists's reference count. - * alenlist_done would decrement the reference count and destroys the List - * if it was the last reference. - * - * Eventually alenlist's may allow better support for user-level scatter/ - * gather operations (e.g. via readv/writev): With proper support, we - * could potentially handle a vector of reads with a single scatter/gather - * DMA operation. This could be especially useful on NUMA systems where - * there's more of a reason for users to use vector I/O operations. - * - * Eventually, alenlist's may replace kaio lists, vhand page lists, - * buffer cache pfdat lists, DMA page lists, etc. - */ - -/* Opaque data types */ - -/* An Address/Length pair. */ -typedef struct alen_s { - alenaddr_t al_addr; - size_t al_length; -} alen_t; - -/* - * Number of elements in one chunk of an Address/Length List. - * - * This size should be sufficient to hold at least an "average" size - * DMA request. Must be at least 1, and should be a power of 2, - * for efficiency. - */ -#define ALEN_CHUNK_SZ ((512*1024)/NBPP) - -/* - * A fixed-size set of Address/Length Pairs. Chunks of Pairs are strung together - * to form a complete Address/Length List. Chunking is entirely hidden within the - * alenlist implementation, and it simply makes allocation and growth of lists more - * efficient. - */ -typedef struct alenlist_chunk_s { - alen_t alc_pair[ALEN_CHUNK_SZ];/* list of addr/len pairs */ - struct alenlist_chunk_s *alc_next; /* point to next chunk of pairs */ -} *alenlist_chunk_t; - -/* - * An Address/Length List. An Address/Length List is allocated with alenlist_create. - * Alternatively, a list can be allocated on the stack (local variable of type - * alenlist_t) and initialized with alenpair_init or with a combination of - * alenlist_clear and alenlist_append, etc. Code which statically allocates these - * structures loses forward binary compatibility! - * - * A statically allocated List is sufficiently large to hold ALEN_CHUNK_SZ pairs. - */ -struct alenlist_s { - unsigned short al_flags; - unsigned short al_logical_size; /* logical size of list, in pairs */ - unsigned short al_actual_size; /* actual size of list, in pairs */ - struct alenlist_chunk_s *al_last_chunk; /* pointer to last logical chunk */ - struct alenlist_cursor_s al_cursor; /* internal cursor */ - struct alenlist_chunk_s al_chunk; /* initial set of pairs */ - alenaddr_t al_compaction_address; /* used to compact pairs */ -}; - -/* al_flags field */ -#define AL_FIXED_SIZE 0x1 /* List is pre-allocated, and of fixed size */ - - -zone_t *alenlist_zone = NULL; -zone_t *alenlist_chunk_zone = NULL; -zone_t *alenlist_cursor_zone = NULL; - -#if DEBUG -int alenlist_count=0; /* Currently allocated Lists */ -int alenlist_chunk_count = 0; /* Currently allocated chunks */ -int alenlist_cursor_count = 0; /* Currently allocate cursors */ -#define INCR_COUNT(ptr) atomic_inc((ptr)); -#define DECR_COUNT(ptr) atomic_dec((ptr)); -#else -#define INCR_COUNT(ptr) -#define DECR_COUNT(ptr) -#endif /* DEBUG */ - -#if DEBUG -static void alenlist_show(alenlist_t); -#endif /* DEBUG */ - -/* - * Initialize Address/Length List management. One time initialization. - */ -void -alenlist_init(void) -{ - alenlist_zone = snia_kmem_zone_init(sizeof(struct alenlist_s), "alenlist"); - alenlist_chunk_zone = snia_kmem_zone_init(sizeof(struct alenlist_chunk_s), "alchunk"); - alenlist_cursor_zone = snia_kmem_zone_init(sizeof(struct alenlist_cursor_s), "alcursor"); -#if DEBUG - idbg_addfunc("alenshow", alenlist_show); -#endif /* DEBUG */ -} - - -/* - * Initialize an Address/Length List cursor. - */ -static void -do_cursor_init(alenlist_t alenlist, alenlist_cursor_t cursorp) -{ - cursorp->al_alenlist = alenlist; - cursorp->al_offset = 0; - cursorp->al_chunk = &alenlist->al_chunk; - cursorp->al_index = 0; - cursorp->al_bcount = 0; -} - - -/* - * Create an Address/Length List, and clear it. - * Set the cursor to the beginning. - */ -alenlist_t -alenlist_create(unsigned flags) -{ - alenlist_t alenlist; - - alenlist = snia_kmem_zone_alloc(alenlist_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0); - if (alenlist) { - INCR_COUNT(&alenlist_count); - - alenlist->al_flags = 0; - alenlist->al_logical_size = 0; - alenlist->al_actual_size = ALEN_CHUNK_SZ; - alenlist->al_last_chunk = &alenlist->al_chunk; - alenlist->al_chunk.alc_next = NULL; - do_cursor_init(alenlist, &alenlist->al_cursor); - } - - return(alenlist); -} - - -/* - * Grow an Address/Length List so that all resources needed to contain - * the specified number of Pairs are pre-allocated. An Address/Length - * List that has been explicitly "grown" will never *automatically* - * grow, shrink, or be destroyed. - * - * Pre-allocation is useful for Real-Time drivers and for drivers that - * may be used along the swap-out path and therefore cannot afford to - * sleep until memory is freed. - * - * The cursor is set to the beginning of the list. - */ -int -alenlist_grow(alenlist_t alenlist, size_t npairs) -{ - /* - * This interface should be used relatively rarely, so - * the implementation is kept simple: We clear the List, - * then append npairs bogus entries. Finally, we mark - * the list as FIXED_SIZE and re-initialize the internal - * cursor. - */ - - /* - * Temporarily mark as non-fixed size, since we're about - * to shrink and expand it. - */ - alenlist->al_flags &= ~AL_FIXED_SIZE; - - /* Free whatever was in the alenlist. */ - alenlist_clear(alenlist); - - /* Allocate everything that we need via automatic expansion. */ - while (npairs--) - if (alenlist_append(alenlist, 0, 0, AL_NOCOMPACT) == ALENLIST_FAILURE) - return(ALENLIST_FAILURE); - - /* Now, mark as FIXED_SIZE */ - alenlist->al_flags |= AL_FIXED_SIZE; - - /* Clear out bogus entries */ - alenlist_clear(alenlist); - - /* Initialize internal cursor to the beginning */ - do_cursor_init(alenlist, &alenlist->al_cursor); - - return(ALENLIST_SUCCESS); -} - - -/* - * Clear an Address/Length List so that it holds no pairs. - */ -void -alenlist_clear(alenlist_t alenlist) -{ - alenlist_chunk_t chunk, freechunk; - - /* - * If this List is not FIXED_SIZE, free all the - * extra chunks. - */ - if (!(alenlist->al_flags & AL_FIXED_SIZE)) { - /* First, free any extension alenlist chunks */ - chunk = alenlist->al_chunk.alc_next; - while (chunk) { - freechunk = chunk; - chunk = chunk->alc_next; - snia_kmem_zone_free(alenlist_chunk_zone, freechunk); - DECR_COUNT(&alenlist_chunk_count); - } - alenlist->al_actual_size = ALEN_CHUNK_SZ; - alenlist->al_chunk.alc_next = NULL; - } - - alenlist->al_logical_size = 0; - alenlist->al_last_chunk = &alenlist->al_chunk; - do_cursor_init(alenlist, &alenlist->al_cursor); -} - - -/* - * Create and initialize an Address/Length Pair. - * This is intended for degenerate lists, consisting of a single - * address/length pair. - */ -alenlist_t -alenpair_init( alenaddr_t address, - size_t length) -{ - alenlist_t alenlist; - - alenlist = alenlist_create(0); - - alenlist->al_logical_size = 1; - ASSERT(alenlist->al_last_chunk == &alenlist->al_chunk); - alenlist->al_chunk.alc_pair[0].al_length = length; - alenlist->al_chunk.alc_pair[0].al_addr = address; - - return(alenlist); -} - -/* - * Return address/length from a degenerate (1-pair) List, or - * first pair from a larger list. Does NOT update the internal cursor, - * so this is an easy way to peek at a start address. - */ -int -alenpair_get( alenlist_t alenlist, - alenaddr_t *address, - size_t *length) -{ - if (alenlist->al_logical_size == 0) - return(ALENLIST_FAILURE); - - *length = alenlist->al_chunk.alc_pair[0].al_length; - *address = alenlist->al_chunk.alc_pair[0].al_addr; - return(ALENLIST_SUCCESS); -} - - -/* - * Destroy an Address/Length List. - */ -void -alenlist_destroy(alenlist_t alenlist) -{ - if (alenlist == NULL) - return; - - /* - * Turn off FIXED_SIZE so this List can be - * automatically shrunk. - */ - alenlist->al_flags &= ~AL_FIXED_SIZE; - - /* Free extension chunks first */ - if (alenlist->al_chunk.alc_next) - alenlist_clear(alenlist); - - /* Now, free the alenlist itself */ - snia_kmem_zone_free(alenlist_zone, alenlist); - DECR_COUNT(&alenlist_count); -} - -/* - * Release an Address/Length List. - * This is in preparation for a day when alenlist's may be longer-lived, and - * perhaps associated with a buf structure. We'd add a reference count, and - * this routine would decrement the count. For now, we create alenlist's on - * on demand and free them when done. If the driver is not explicitly managing - * a List for its own use, it should call alenlist_done rather than alenlist_destroy. - */ -void -alenlist_done(alenlist_t alenlist) -{ - alenlist_destroy(alenlist); -} - - -/* - * Append another address/length to the end of an Address/Length List, - * growing the list if permitted and necessary. - * - * Returns: SUCCESS/FAILURE - */ -int -alenlist_append( alenlist_t alenlist, /* append to this list */ - alenaddr_t address, /* address to append */ - size_t length, /* length to append */ - unsigned flags) -{ - alen_t *alenp; - int index, last_index; - - index = alenlist->al_logical_size % ALEN_CHUNK_SZ; - - if ((alenlist->al_logical_size > 0)) { - /* - * See if we can compact this new pair in with the previous entry. - * al_compaction_address holds that value that we'd need to see - * in order to compact. - */ - if (!(flags & AL_NOCOMPACT) && - (alenlist->al_compaction_address == address)) { - last_index = (alenlist->al_logical_size-1) % ALEN_CHUNK_SZ; - alenp = &(alenlist->al_last_chunk->alc_pair[last_index]); - alenp->al_length += length; - alenlist->al_compaction_address += length; - return(ALENLIST_SUCCESS); - } - - /* - * If we're out of room in this chunk, move to a new chunk. - */ - if (index == 0) { - if (alenlist->al_flags & AL_FIXED_SIZE) { - alenlist->al_last_chunk = alenlist->al_last_chunk->alc_next; - - /* If we're out of space in a FIXED_SIZE List, quit. */ - if (alenlist->al_last_chunk == NULL) { - ASSERT(alenlist->al_logical_size == alenlist->al_actual_size); - return(ALENLIST_FAILURE); - } - } else { - alenlist_chunk_t new_chunk; - - new_chunk = snia_kmem_zone_alloc(alenlist_chunk_zone, - flags & AL_NOSLEEP ? VM_NOSLEEP : 0); - - if (new_chunk == NULL) - return(ALENLIST_FAILURE); - - alenlist->al_last_chunk->alc_next = new_chunk; - new_chunk->alc_next = NULL; - alenlist->al_last_chunk = new_chunk; - alenlist->al_actual_size += ALEN_CHUNK_SZ; - INCR_COUNT(&alenlist_chunk_count); - } - } - } - - alenp = &(alenlist->al_last_chunk->alc_pair[index]); - alenp->al_addr = address; - alenp->al_length = length; - - alenlist->al_logical_size++; - alenlist->al_compaction_address = address + length; - - return(ALENLIST_SUCCESS); -} - - -/* - * Replace an item in an Address/Length List. Cursor is updated so - * that alenlist_get will get the next item in the list. This interface - * is not very useful for drivers; but it is useful to bus providers - * that need to translate between address spaced in situ. The old Address - * and Length are returned. - */ -/* ARGSUSED */ -int -alenlist_replace( alenlist_t alenlist, /* in: replace in this list */ - alenlist_cursor_t cursorp, /* inout: which item to replace */ - alenaddr_t *addrp, /* inout: address */ - size_t *lengthp, /* inout: length */ - unsigned flags) -{ - alen_t *alenp; - alenlist_chunk_t chunk; - unsigned int index; - size_t length; - alenaddr_t addr; - - if ((addrp == NULL) || (lengthp == NULL)) - return(ALENLIST_FAILURE); - - if (alenlist->al_logical_size == 0) - return(ALENLIST_FAILURE); - - addr = *addrp; - length = *lengthp; - - /* - * If no cursor explicitly specified, use the Address/Length List's - * internal cursor. - */ - if (cursorp == NULL) - cursorp = &alenlist->al_cursor; - - chunk = cursorp->al_chunk; - index = cursorp->al_index; - - ASSERT(cursorp->al_alenlist == alenlist); - if (cursorp->al_alenlist != alenlist) - return(ALENLIST_FAILURE); - - alenp = &chunk->alc_pair[index]; - - /* Return old values */ - *addrp = alenp->al_length; - *lengthp = alenp->al_addr; - - /* Set up new values */ - alenp->al_length = length; - alenp->al_addr = addr; - - /* Update cursor to point to next item */ - cursorp->al_bcount = length; - - return(ALENLIST_SUCCESS); -} - - -/* - * Initialize a cursor in order to walk an alenlist. - * An alenlist_cursor always points to the last thing that was obtained - * from the list. If al_chunk is NULL, then nothing has yet been obtained. - * - * Note: There is an "internal cursor" associated with every Address/Length List. - * For users that scan sequentially through a List, it is more efficient to - * simply use the internal cursor. The caller must insure that no other users - * will simultaneously scan the List. The caller can reposition the internal - * cursor by calling alenlist_cursor_init with a NULL cursorp. - */ -int -alenlist_cursor_init(alenlist_t alenlist, size_t offset, alenlist_cursor_t cursorp) -{ - size_t byte_count; - - if (cursorp == NULL) - cursorp = &alenlist->al_cursor; - - /* Get internal cursor's byte count for use as a hint. - * - * If the internal cursor points passed the point that we're interested in, - * we need to seek forward from the beginning. Otherwise, we can seek forward - * from the internal cursor. - */ - if ((offset > 0) && - ((byte_count = alenlist_cursor_offset(alenlist, (alenlist_cursor_t)NULL)) <= offset)) { - offset -= byte_count; - alenlist_cursor_clone(alenlist, NULL, cursorp); - } else - do_cursor_init(alenlist, cursorp); - - /* We could easily speed this up, but it shouldn't be used very often. */ - while (offset != 0) { - alenaddr_t addr; - size_t length; - - if (alenlist_get(alenlist, cursorp, offset, &addr, &length, 0) != ALENLIST_SUCCESS) - return(ALENLIST_FAILURE); - offset -= length; - } - return(ALENLIST_SUCCESS); -} - - -/* - * Copy a cursor. The source cursor is either an internal alenlist cursor - * or an explicit cursor. - */ -int -alenlist_cursor_clone( alenlist_t alenlist, - alenlist_cursor_t cursorp_in, - alenlist_cursor_t cursorp_out) -{ - ASSERT(cursorp_out); - - if (alenlist && cursorp_in) - if (alenlist != cursorp_in->al_alenlist) - return(ALENLIST_FAILURE); - - if (alenlist) - *cursorp_out = alenlist->al_cursor; /* small structure copy */ - else if (cursorp_in) - *cursorp_out = *cursorp_in; /* small structure copy */ - else - return(ALENLIST_FAILURE); /* no source */ - - return(ALENLIST_SUCCESS); -} - -/* - * Return the number of bytes passed so far according to the specified cursor. - * If cursorp is NULL, use the alenlist's internal cursor. - */ -size_t -alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp) -{ - ASSERT(!alenlist || !cursorp || (alenlist == cursorp->al_alenlist)); - - if (cursorp == NULL) { - ASSERT(alenlist); - cursorp = &alenlist->al_cursor; - } - - return(cursorp->al_offset); -} - -/* - * Allocate and initialize an Address/Length List cursor. - */ -alenlist_cursor_t -alenlist_cursor_create(alenlist_t alenlist, unsigned flags) -{ - alenlist_cursor_t cursorp; - - ASSERT(alenlist != NULL); - cursorp = snia_kmem_zone_alloc(alenlist_cursor_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0); - if (cursorp) { - INCR_COUNT(&alenlist_cursor_count); - alenlist_cursor_init(alenlist, 0, cursorp); - } - return(cursorp); -} - -/* - * Free an Address/Length List cursor. - */ -void -alenlist_cursor_destroy(alenlist_cursor_t cursorp) -{ - DECR_COUNT(&alenlist_cursor_count); - snia_kmem_zone_free(alenlist_cursor_zone, cursorp); -} - - -/* - * Fetch an address/length pair from an Address/Length List. Update - * the "cursor" so that next time this routine is called, we'll get - * the next address range. Never return a length that exceeds maxlength - * (if non-zero). If maxlength is a power of 2, never return a length - * that crosses a maxlength boundary. [This may seem strange at first, - * but it's what many drivers want.] - * - * Returns: SUCCESS/FAILURE - */ -int -alenlist_get( alenlist_t alenlist, /* in: get from this list */ - alenlist_cursor_t cursorp, /* inout: which item to get */ - size_t maxlength, /* in: at most this length */ - alenaddr_t *addrp, /* out: address */ - size_t *lengthp, /* out: length */ - unsigned flags) -{ - alen_t *alenp; - alenlist_chunk_t chunk; - unsigned int index; - size_t bcount; - size_t length; - - /* - * If no cursor explicitly specified, use the Address/Length List's - * internal cursor. - */ - if (cursorp == NULL) { - if (alenlist->al_logical_size == 0) - return(ALENLIST_FAILURE); - cursorp = &alenlist->al_cursor; - } - - chunk = cursorp->al_chunk; - index = cursorp->al_index; - bcount = cursorp->al_bcount; - - ASSERT(cursorp->al_alenlist == alenlist); - if (cursorp->al_alenlist != alenlist) - return(ALENLIST_FAILURE); - - alenp = &chunk->alc_pair[index]; - length = alenp->al_length - bcount; - - /* Bump up to next pair, if we're done with this pair. */ - if (length == 0) { - cursorp->al_bcount = bcount = 0; - cursorp->al_index = index = (index + 1) % ALEN_CHUNK_SZ; - - /* Bump up to next chunk, if we're done with this chunk. */ - if (index == 0) { - if (cursorp->al_chunk == alenlist->al_last_chunk) - return(ALENLIST_FAILURE); - chunk = chunk->alc_next; - ASSERT(chunk != NULL); - } else { - /* If in last chunk, don't go beyond end. */ - if (cursorp->al_chunk == alenlist->al_last_chunk) { - int last_size = alenlist->al_logical_size % ALEN_CHUNK_SZ; - if (last_size && (index >= last_size)) - return(ALENLIST_FAILURE); - } - } - - alenp = &chunk->alc_pair[index]; - length = alenp->al_length; - } - - /* Constrain what we return according to maxlength */ - if (maxlength) { - size_t maxlen1 = maxlength - 1; - - if ((maxlength & maxlen1) == 0) /* power of 2 */ - maxlength -= - ((alenp->al_addr + cursorp->al_bcount) & maxlen1); - - length = min(maxlength, length); - } - - /* Update the cursor, if desired. */ - if (!(flags & AL_LEAVE_CURSOR)) { - cursorp->al_bcount += length; - cursorp->al_chunk = chunk; - } - - *lengthp = length; - *addrp = alenp->al_addr + bcount; - - return(ALENLIST_SUCCESS); -} - - -/* - * Return the number of pairs in the specified Address/Length List. - * (For FIXED_SIZE Lists, this returns the logical size of the List, - * not the actual capacity of the List.) - */ -int -alenlist_size(alenlist_t alenlist) -{ - return(alenlist->al_logical_size); -} - - -/* - * Concatenate two Address/Length Lists. - */ -void -alenlist_concat(alenlist_t from, - alenlist_t to) -{ - struct alenlist_cursor_s cursor; - alenaddr_t addr; - size_t length; - - alenlist_cursor_init(from, 0, &cursor); - - while(alenlist_get(from, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS) - alenlist_append(to, addr, length, 0); -} - -/* - * Create a copy of a list. - * (Not all attributes of the old list are cloned. For instance, if - * a FIXED_SIZE list is cloned, the resulting list is NOT FIXED_SIZE.) - */ -alenlist_t -alenlist_clone(alenlist_t old_list, unsigned flags) -{ - alenlist_t new_list; - - new_list = alenlist_create(flags); - if (new_list != NULL) - alenlist_concat(old_list, new_list); - - return(new_list); -} - - -/* - * Convert a kernel virtual address to a Physical Address/Length List. - */ -alenlist_t -kvaddr_to_alenlist(alenlist_t alenlist, caddr_t kvaddr, size_t length, unsigned flags) -{ - alenaddr_t paddr; - long offset; - size_t piece_length; - int created_alenlist; - - if (length <=0) - return(NULL); - - /* If caller supplied a List, use it. Otherwise, allocate one. */ - if (alenlist == NULL) { - alenlist = alenlist_create(0); - created_alenlist = 1; - } else { - alenlist_clear(alenlist); - created_alenlist = 0; - } - - paddr = kvtophys(kvaddr); - offset = poff(kvaddr); - - /* Handle first page */ - piece_length = min((size_t)(NBPP - offset), length); - if (alenlist_append(alenlist, paddr, piece_length, flags) == ALENLIST_FAILURE) - goto failure; - length -= piece_length; - kvaddr += piece_length; - - /* Handle middle pages */ - while (length >= NBPP) { - paddr = kvtophys(kvaddr); - if (alenlist_append(alenlist, paddr, NBPP, flags) == ALENLIST_FAILURE) - goto failure; - length -= NBPP; - kvaddr += NBPP; - } - - /* Handle last page */ - if (length) { - ASSERT(length < NBPP); - paddr = kvtophys(kvaddr); - if (alenlist_append(alenlist, paddr, length, flags) == ALENLIST_FAILURE) - goto failure; - } - - alenlist_cursor_init(alenlist, 0, NULL); - return(alenlist); - -failure: - if (created_alenlist) - alenlist_destroy(alenlist); - return(NULL); -} - - -#if DEBUG -static void -alenlist_show(alenlist_t alenlist) -{ - struct alenlist_cursor_s cursor; - alenaddr_t addr; - size_t length; - int i = 0; - - alenlist_cursor_init(alenlist, 0, &cursor); - - qprintf("Address/Length List@0x%x:\n", alenlist); - qprintf("logical size=0x%x actual size=0x%x last_chunk at 0x%x\n", - alenlist->al_logical_size, alenlist->al_actual_size, - alenlist->al_last_chunk); - qprintf("cursor: chunk=0x%x index=%d offset=0x%x\n", - alenlist->al_cursor.al_chunk, - alenlist->al_cursor.al_index, - alenlist->al_cursor.al_bcount); - while(alenlist_get(alenlist, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS) - qprintf("%d:\t0x%lx 0x%lx\n", ++i, addr, length); -} -#endif /* DEBUG */ diff -urN linux-2.4.21/arch/ia64/sn/io/ate_utils.c linux-2.4.22/arch/ia64/sn/io/ate_utils.c --- linux-2.4.21/arch/ia64/sn/io/ate_utils.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/ate_utils.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,205 +0,0 @@ -/* $Id: ate_utils.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * Allocate the map needed to allocate the ATE entries. - */ -struct map * -atemapalloc(ulong_t mapsiz) -{ - struct map *mp; - ulong_t size; - struct a { - spinlock_t lock; - sv_t sema; - } *sync; - - if (mapsiz == 0) - return(NULL); - size = sizeof(struct map) * (mapsiz + 2); - if ((mp = (struct map *) kmalloc(size, GFP_KERNEL)) == NULL) - return(NULL); - memset(mp, 0x0, size); - - sync = kmalloc(sizeof(struct a), GFP_KERNEL); - if (sync == NULL) { - kfree(mp); - return(NULL); - } - memset(sync, 0x0, sizeof(struct a)); - - mutex_spinlock_init(&sync->lock); - sv_init( &(sync->sema), &(sync->lock), SV_MON_SPIN | SV_ORDER_FIFO /*| SV_INTS*/); - mp[1].m_size = (unsigned long) &sync->lock; - mp[1].m_addr = (unsigned long) &sync->sema; - mapsize(mp) = mapsiz - 1; - return(mp); -} - -/* - * free a map structure previously allocated via rmallocmap(). - */ -void -atemapfree(struct map *mp) -{ - struct a { - spinlock_t lock; - sv_t sema; - }; - /* ASSERT(sv_waitq(mapout(mp)) == 0); */ - /* sv_destroy(mapout(mp)); */ - spin_lock_destroy(maplock(mp)); - kfree((void *)mp[1].m_size); - kfree(mp); -} - -/* - * Allocate 'size' units from the given map. - * Return the base of the allocated space. - * In a map, the addresses are increasing and the - * list is terminated by a 0 size. - * Algorithm is first-fit. - */ - -ulong_t -atealloc( - struct map *mp, - size_t size) -{ - register unsigned int a; - register struct map *bp; - register unsigned long s; - - ASSERT(size >= 0); - - if (size == 0) - return((ulong_t) NULL); - - s = mutex_spinlock(maplock(mp)); - - for (bp = mapstart(mp); bp->m_size; bp++) { - if (bp->m_size >= size) { - a = bp->m_addr; - bp->m_addr += size; - if ((bp->m_size -= size) == 0) { - do { - bp++; - (bp-1)->m_addr = bp->m_addr; - } while ((((bp-1)->m_size) = (bp->m_size))); - mapsize(mp)++; - } - - ASSERT(bp->m_size < 0x80000000); - mutex_spinunlock(maplock(mp), s); - return(a); - } - } - - /* - * We did not get what we need .. we cannot sleep .. - */ - mutex_spinunlock(maplock(mp), s); - return(0); -} - -/* - * Free the previously allocated space a of size units into the specified map. - * Sort ``a'' into map and combine on one or both ends if possible. - * Returns 0 on success, 1 on failure. - */ -void -atefree(struct map *mp, size_t size, ulong_t a) -{ - register struct map *bp; - register unsigned int t; - register unsigned long s; - - ASSERT(size >= 0); - - if (size == 0) - return; - - bp = mapstart(mp); - s = mutex_spinlock(maplock(mp)); - - for ( ; bp->m_addr<=a && bp->m_size!=0; bp++) - ; - if (bp>mapstart(mp) && (bp-1)->m_addr+(bp-1)->m_size == a) { - (bp-1)->m_size += size; - if (bp->m_addr) { - /* m_addr==0 end of map table */ - ASSERT(a+size <= bp->m_addr); - if (a+size == bp->m_addr) { - - /* compress adjacent map addr entries */ - (bp-1)->m_size += bp->m_size; - while (bp->m_size) { - bp++; - (bp-1)->m_addr = bp->m_addr; - (bp-1)->m_size = bp->m_size; - } - mapsize(mp)++; - } - } - } else { - if (a+size == bp->m_addr && bp->m_size) { - bp->m_addr -= size; - bp->m_size += size; - } else { - ASSERT(size); - if (mapsize(mp) == 0) { - mutex_spinunlock(maplock(mp), s); - printk("atefree : map overflow 0x%p Lost 0x%lx items at 0x%lx", - (void *)mp, size, a) ; - return ; - } - do { - t = bp->m_addr; - bp->m_addr = a; - a = t; - t = bp->m_size; - bp->m_size = size; - bp++; - } while ((size = t)); - mapsize(mp)--; - } - } - mutex_spinunlock(maplock(mp), s); - /* - * wake up everyone waiting for space - */ - if (mapout(mp)) - ; - /* sv_broadcast(mapout(mp)); */ -} diff -urN linux-2.4.21/arch/ia64/sn/io/cdl.c linux-2.4.22/arch/ia64/sn/io/cdl.c --- linux-2.4.21/arch/ia64/sn/io/cdl.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/cdl.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -18,9 +18,9 @@ #include /* these get called directly in cdl_add_connpt in fops bypass hack */ -extern int pcibr_attach(devfs_handle_t); -extern int xbow_attach(devfs_handle_t); -extern int pic_attach(devfs_handle_t); +extern int pcibr_attach(vertex_hdl_t); +extern int xbow_attach(vertex_hdl_t); +extern int pic_attach(vertex_hdl_t); /* @@ -32,75 +32,20 @@ * IO Infrastructure Drivers e.g. pcibr. */ -struct cdl { - int part_num; - int mfg_num; - int (*attach) (devfs_handle_t); -} dummy_reg; - -#ifdef CONFIG_IA64_SGI_SN1 -#define MAX_SGI_IO_INFRA_DRVR 4 -#else #define MAX_SGI_IO_INFRA_DRVR 7 -#endif + static struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] = { { XBRIDGE_WIDGET_PART_NUM, XBRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */}, { BRIDGE_WIDGET_PART_NUM, BRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */}, -#ifndef CONFIG_IA64_SGI_SN1 { PIC_WIDGET_PART_NUM_BUS0, PIC_WIDGET_MFGR_NUM, pic_attach /* &pic_fops */}, { PIC_WIDGET_PART_NUM_BUS1, PIC_WIDGET_MFGR_NUM, pic_attach /* &pic_fops */}, -#endif { XXBOW_WIDGET_PART_NUM, XXBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */}, { XBOW_WIDGET_PART_NUM, XBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */}, -#ifndef CONFIG_IA64_SGI_SN1 { PXBOW_WIDGET_PART_NUM, XXBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */}, -#endif }; /* - * cdl_new: Called by pciio and xtalk. - */ -cdl_p -cdl_new(char *name, char *k1str, char *k2str) -{ - /* - * Just return a dummy pointer. - */ - return((cdl_p)&dummy_reg); -} - -/* - * cdl_del: Do nothing. - */ -void -cdl_del(cdl_p reg) -{ - return; -} - -/* - * cdl_add_driver: The driver part number and manufacturers number - * are statically initialized above. - * - Do nothing. - */ -int -cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags, cdl_drv_f *func) -{ - return 0; -} - -/* - * cdl_del_driver: Not supported. - */ -void -cdl_del_driver(cdl_p reg, char *prefix, cdl_drv_f *func) -{ - return; -} - -/* * cdl_add_connpt: We found a device and it's connect point. Call the * attach routine of that driver. * @@ -112,8 +57,8 @@ * vertices. */ int -cdl_add_connpt(cdl_p reg, int part_num, int mfg_num, - devfs_handle_t connpt, int drv_flags) +cdl_add_connpt(int part_num, int mfg_num, + vertex_hdl_t connpt, int drv_flags) { int i; @@ -121,7 +66,6 @@ * Find the driver entry point and call the attach routine. */ for (i = 0; i < MAX_SGI_IO_INFRA_DRVR; i++) { - if ( (part_num == sgi_infrastructure_drivers[i].part_num) && ( mfg_num == sgi_infrastructure_drivers[i].mfg_num) ) { /* @@ -139,73 +83,3 @@ return (0); } - -/* - * cdl_del_connpt: Not implemented. - */ -int -cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t connpt, int drv_flags) -{ - - return(0); -} - -/* - * cdl_iterate: Not Implemented. - */ -void -cdl_iterate(cdl_p reg, - char *prefix, - cdl_iter_f * func) -{ - return; -} - -async_attach_t -async_attach_new(void) -{ - - return(0); -} - -void -async_attach_free(async_attach_t aa) -{ - return; -} - -async_attach_t -async_attach_get_info(devfs_handle_t vhdl) -{ - - return(0); -} - -void -async_attach_add_info(devfs_handle_t vhdl, async_attach_t aa) -{ - return; - -} - -void -async_attach_del_info(devfs_handle_t vhdl) -{ - return; -} - -void async_attach_signal_start(async_attach_t aa) -{ - return; -} - -void async_attach_signal_done(async_attach_t aa) -{ - return; -} - -void async_attach_waitall(async_attach_t aa) -{ - return; -} - diff -urN linux-2.4.21/arch/ia64/sn/io/drivers/Makefile linux-2.4.22/arch/ia64/sn/io/drivers/Makefile --- linux-2.4.21/arch/ia64/sn/io/drivers/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/drivers/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,18 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. +# +# Makefile for the sn2 io routines. + +EXTRA_CFLAGS := -DLITTLE_ENDIAN + +O_TARGET := snio.o + +obj-y += hubdev.o ioconfig_bus.o ifconfig_net.o + +obj-$(CONFIG_PCIBA) += pciba.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/drivers/hubdev.c linux-2.4.22/arch/ia64/sn/io/drivers/hubdev.c --- linux-2.4.21/arch/ia64/sn/io/drivers/hubdev.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/drivers/hubdev.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,100 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct hubdev_callout { + int (*attach_method)(vertex_hdl_t); + struct hubdev_callout *fp; +}; + +typedef struct hubdev_callout hubdev_callout_t; + +mutex_t hubdev_callout_mutex; +static hubdev_callout_t *hubdev_callout_list; + +void +hubdev_init(void) +{ + mutex_init(&hubdev_callout_mutex); + hubdev_callout_list = NULL; +} + +void +hubdev_register(int (*attach_method)(vertex_hdl_t)) +{ + hubdev_callout_t *callout; + + ASSERT(attach_method); + + callout = (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP); + ASSERT(callout); + + mutex_lock(&hubdev_callout_mutex); + /* + * Insert at the end of the list + */ + callout->fp = hubdev_callout_list; + hubdev_callout_list = callout; + callout->attach_method = attach_method; + mutex_unlock(&hubdev_callout_mutex); +} + +int +hubdev_unregister(int (*attach_method)(vertex_hdl_t)) +{ + hubdev_callout_t **p; + + ASSERT(attach_method); + + mutex_lock(&hubdev_callout_mutex); + /* + * Remove registry element containing attach_method + */ + for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) { + if ((*p)->attach_method == attach_method) { + hubdev_callout_t* victim = *p; + *p = (*p)->fp; + kfree(victim); + mutex_unlock(&hubdev_callout_mutex); + return (0); + } + } + mutex_unlock(&hubdev_callout_mutex); + return (ENOENT); +} + + +int +hubdev_docallouts(vertex_hdl_t hub) +{ + hubdev_callout_t *p; + int errcode; + + mutex_lock(&hubdev_callout_mutex); + + for (p = hubdev_callout_list; p != NULL; p = p->fp) { + ASSERT(p->attach_method); + errcode = (*p->attach_method)(hub); + if (errcode != 0) { + mutex_unlock(&hubdev_callout_mutex); + return (errcode); + } + } + mutex_unlock(&hubdev_callout_mutex); + return (0); +} diff -urN linux-2.4.21/arch/ia64/sn/io/drivers/ifconfig_net.c linux-2.4.22/arch/ia64/sn/io/drivers/ifconfig_net.c --- linux-2.4.21/arch/ia64/sn/io/drivers/ifconfig_net.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/drivers/ifconfig_net.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,298 @@ +/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * ifconfig_net - SGI's Persistent Network Device names. + * + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER" +#define SGI_IFCONFIG_NET_VERSION "1.0" + +/* + * Some Global definitions. + */ +static devfs_handle_t ifconfig_net_handle; +static unsigned long ifconfig_net_debug; + +/* + * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net". + */ +static int ifconfig_net_open(struct inode * inode, struct file * filp) +{ + if (ifconfig_net_debug) { + printk("ifconfig_net_open called.\n"); + } + + return(0); + +} + +/* + * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net". + */ +static int ifconfig_net_close(struct inode * inode, struct file * filp) +{ + + if (ifconfig_net_debug) { + printk("ifconfig_net_close called.\n"); + } + + return(0); +} + +/* + * assign_ifname - Assign the next available interface name from the persistent list. + */ +void +assign_ifname(struct net_device *dev, + struct ifname_num *ifname_num) + +{ + + /* + * Handle eth devices. + */ + if ( (memcmp(dev->name, "eth", 3) == 0) ) { + if (ifname_num->next_eth != -1) { + /* + * Assign it the next available eth interface number. + */ + memset(dev->name, 0, strlen(dev->name)); + sprintf(dev->name, "eth%d", (int)ifname_num->next_eth); + ifname_num->next_eth++; + } + + return; + } + + /* + * Handle fddi devices. + */ + if ( (memcmp(dev->name, "fddi", 4) == 0) ) { + if (ifname_num->next_fddi != -1) { + /* + * Assign it the next available fddi interface number. + */ + memset(dev->name, 0, strlen(dev->name)); + sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi); + ifname_num->next_fddi++; + } + + return; + } + + /* + * Handle hip devices. + */ + if ( (memcmp(dev->name, "hip", 3) == 0) ) { + if (ifname_num->next_hip != -1) { + /* + * Assign it the next available hip interface number. + */ + memset(dev->name, 0, strlen(dev->name)); + sprintf(dev->name, "hip%d", (int)ifname_num->next_hip); + ifname_num->next_hip++; + } + + return; + } + + /* + * Handle tr devices. + */ + if ( (memcmp(dev->name, "tr", 2) == 0) ) { + if (ifname_num->next_tr != -1) { + /* + * Assign it the next available tr interface number. + */ + memset(dev->name, 0, strlen(dev->name)); + sprintf(dev->name, "tr%d", (int)ifname_num->next_tr); + ifname_num->next_tr++; + } + + return; + } + + /* + * Handle fc devices. + */ + if ( (memcmp(dev->name, "fc", 2) == 0) ) { + if (ifname_num->next_fc != -1) { + /* + * Assign it the next available fc interface number. + */ + memset(dev->name, 0, strlen(dev->name)); + sprintf(dev->name, "fc%d", (int)ifname_num->next_fc); + ifname_num->next_fc++; + } + + return; + } +} + +/* + * find_persistent_ifname: Returns the entry that was seen in previous boot. + */ +struct ifname_MAC * +find_persistent_ifname(struct net_device *dev, + struct ifname_MAC *ifname_MAC) + +{ + + while (ifname_MAC->addr_len) { + if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0) + return(ifname_MAC); + + ifname_MAC++; + } + + return(NULL); +} + +/* + * ifconfig_net_ioctl: ifconfig_net driver ioctl interface. + */ +static int ifconfig_net_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + + extern struct net_device *__dev_get_by_name(const char *); +#ifdef CONFIG_NET + struct net_device *dev; + struct ifname_MAC *found; + char temp[64]; +#endif + struct ifname_MAC *ifname_MAC; + struct ifname_MAC *new_devices, *temp_new_devices; + struct ifname_num *ifname_num; + unsigned long size; + + + if (ifconfig_net_debug) { + printk("HCL: hcl_ioctl called.\n"); + } + + /* + * Read in the header and see how big of a buffer we really need to + * allocate. + */ + ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), + GFP_KERNEL); + copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num)); + size = ifname_num->size; + kfree(ifname_num); + ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL); + ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) ); + + copy_from_user( ifname_num, (char *) arg, size); + new_devices = kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL); + temp_new_devices = new_devices; + + memset(new_devices, 0, size - sizeof(struct ifname_num)); + +#ifdef CONFIG_NET + /* + * Go through the net device entries and make them persistent! + */ + for (dev = dev_base; dev != NULL; dev = dev->next) { + /* + * Skip NULL entries or "lo" + */ + if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){ + continue; + } + + /* + * See if we have a persistent interface name for this device. + */ + found = NULL; + found = find_persistent_ifname(dev, ifname_MAC); + if (found) { + strcpy(dev->name, found->name); + } else { + /* Never seen this before .. */ + assign_ifname(dev, ifname_num); + + /* + * Save the information for the next boot. + */ + sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, + dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + strcpy(temp_new_devices->name, dev->name); + temp_new_devices->addr_len = dev->addr_len; + memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len); + temp_new_devices++; + } + + } +#endif + + /* + * Copy back to the User Buffer area any new devices encountered. + */ + copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, + size - sizeof(struct ifname_num)); + + return(0); + +} + +struct file_operations ifconfig_net_fops = { + ioctl:ifconfig_net_ioctl, /* ioctl */ + open:ifconfig_net_open, /* open */ + release:ifconfig_net_close /* release */ +}; + + +/* + * init_ifconfig_net() - Boot time initialization. Ensure that it is called + * after devfs has been initialized. + * + */ +#ifdef MODULE +int init_module (void) +#else +int __init init_ifconfig_net(void) +#endif +{ + ifconfig_net_handle = NULL; + ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net", + 0, DEVFS_FL_AUTO_DEVNUM, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + &ifconfig_net_fops, NULL); + + if (ifconfig_net_handle == NULL) { + panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n"); + } + + return(0); + +} diff -urN linux-2.4.21/arch/ia64/sn/io/drivers/ioconfig_bus.c linux-2.4.22/arch/ia64/sn/io/drivers/ioconfig_bus.c --- linux-2.4.21/arch/ia64/sn/io/drivers/ioconfig_bus.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/drivers/ioconfig_bus.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,401 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * ioconfig_bus - SGI's Persistent PCI Bus Numbering. + * + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SGI_IOCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING" +#define SGI_IOCONFIG_BUS_VERSION "1.0" + +/* + * Some Global definitions. + */ +static vertex_hdl_t ioconfig_bus_handle; +static unsigned long ioconfig_bus_debug; + +#ifdef IOCONFIG_BUS_DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static u64 ioconfig_file; +static u64 ioconfig_file_size; +static u64 ioconfig_activated; +static char ioconfig_kernopts[128]; + +/* + * For debugging purpose .. hardcode a table .. + */ +struct ascii_moduleid *ioconfig_bus_table; +u64 ioconfig_bus_table_size; + + +static int free_entry; +static int new_entry; + +int next_basebus_number; + +void +ioconfig_get_busnum(char *io_moduleid, int *bus_num) +{ + struct ascii_moduleid *temp; + int index; + + DBG("ioconfig_get_busnum io_moduleid %s\n", io_moduleid); + + *bus_num = -1; + temp = ioconfig_bus_table; + for (index = 0; index < free_entry; temp++, index++) { + if ( (io_moduleid[0] == temp->io_moduleid[0]) && + (io_moduleid[1] == temp->io_moduleid[1]) && + (io_moduleid[2] == temp->io_moduleid[2]) && + (io_moduleid[4] == temp->io_moduleid[4]) && + (io_moduleid[5] == temp->io_moduleid[5]) ) { + *bus_num = index * 0x10; + return; + } + } + + /* + * New IO Brick encountered. + */ + if (((int)io_moduleid[0]) == 0) { + DBG("ioconfig_get_busnum: Invalid Module Id given %s\n", io_moduleid); + return; + } + + io_moduleid[3] = '#'; + strcpy((char *)&(ioconfig_bus_table[free_entry].io_moduleid), io_moduleid); + *bus_num = free_entry * 0x10; + free_entry++; +} + +static void +dump_ioconfig_table(void) +{ + + int index = 0; + struct ascii_moduleid *temp; + + temp = ioconfig_bus_table; + while (index < free_entry) { + DBG("ASSCI Module ID %s\n", temp->io_moduleid); + temp++; + index++; + } +} + +/* + * nextline + * This routine returns the nextline in the buffer. + */ +int nextline(char *buffer, char **next, char *line) +{ + + char *temp; + + if (buffer[0] == 0x0) { + return(0); + } + + temp = buffer; + while (*temp != 0) { + *line = *temp; + if (*temp != '\n'){ + *line = *temp; + temp++; line++; + } else + break; + } + + if (*temp == 0) + *next = temp; + else + *next = ++temp; + + return(1); +} + +/* + * build_pcibus_name + * This routine parses the ioconfig contents read into + * memory by ioconfig command in EFI and builds the + * persistent pci bus naming table. + */ +void +build_moduleid_table(char *file_contents, struct ascii_moduleid *table) +{ + /* + * Read the whole file into memory. + */ + int rc; + char *name; + char *temp; + char *next; + char *current; + char *line; + struct ascii_moduleid *moduleid; + + line = kmalloc(256, GFP_KERNEL); + memset(line, 0,256); + name = kmalloc(125, GFP_KERNEL); + memset(name, 0, 125); + moduleid = table; + current = file_contents; + while (nextline(current, &next, line)){ + + DBG("current 0x%lx next 0x%lx\n", current, next); + + temp = line; + /* + * Skip all leading Blank lines .. + */ + while (isspace(*temp)) + if (*temp != '\n') + temp++; + else + break; + + if (*temp == '\n') { + current = next; + memset(line, 0, 256); + continue; + } + + /* + * Skip comment lines + */ + if (*temp == '#') { + current = next; + memset(line, 0, 256); + continue; + } + + /* + * Get the next free entry in the table. + */ + rc = sscanf(temp, "%s", name); + strcpy(&moduleid->io_moduleid[0], name); + DBG("Found %s\n", name); + moduleid++; + free_entry++; + current = next; + memset(line, 0, 256); + } + + new_entry = free_entry; + kfree(line); + kfree(name); + + return; +} + +void +ioconfig_bus_init(void) +{ + + struct ia64_sal_retval ret_stuff; + u64 *temp; + int cnode; + + DBG("ioconfig_bus_init called.\n"); + + for (cnode = 0; cnode < numnodes; cnode++) { + nasid_t nasid; + /* + * Make SAL call to get the address of the bus configuration table. + */ + ret_stuff.status = (uint64_t)0; + ret_stuff.v0 = (uint64_t)0; + ret_stuff.v1 = (uint64_t)0; + ret_stuff.v2 = (uint64_t)0; + nasid = COMPACT_TO_NASID_NODEID(cnode); + SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, nasid, 0, 0, 0, 0, 0); + temp = (u64 *)TO_NODE_CAC(nasid, ret_stuff.v0); + ioconfig_file = *temp; + DBG("ioconfig_bus_init: Nasid %d ret_stuff.v0 0x%lx\n", nasid, + ret_stuff.v0); + if (ioconfig_file) { + ioconfig_file_size = ret_stuff.v1; + ioconfig_file = (ioconfig_file | CACHEABLE_MEM_SPACE); + ioconfig_activated = 1; + break; + } + } + + DBG("ioconfig_bus_init: ret_stuff.v0 %p ioconfig_file %p %d\n", + ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size); + + ioconfig_bus_table = kmalloc( 512, GFP_KERNEL ); + memset(ioconfig_bus_table, 0, 512); + + /* + * If ioconfig options are given on the bootline .. take it. + */ + if (*ioconfig_kernopts != '\0') { + /* + * ioconfig="..." kernel options given. + */ + DBG("ioconfig_bus_init: Kernel Options given.\n"); + (void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table); + (void) dump_ioconfig_table(); + return; + } + + if (ioconfig_activated) { + DBG("ioconfig_bus_init: ioconfig file given.\n"); + (void) build_moduleid_table((char *)ioconfig_file, ioconfig_bus_table); + (void) dump_ioconfig_table(); + } else { + DBG("ioconfig_bus_init: ioconfig command not executed in prom\n"); + } + +} + +void +ioconfig_bus_new_entries(void) +{ + + + int index = 0; + struct ascii_moduleid *temp; + + if ((ioconfig_activated) && (free_entry > new_entry)) { + printk("### Please add the following new IO Bricks Module ID \n"); + printk("### to your Persistent Bus Numbering Config File\n"); + } else + return; + + index = new_entry; + temp = &ioconfig_bus_table[index]; + while (index < free_entry) { + printk("%s\n", (char *)temp); + temp++; + index++; + } + printk("### End\n"); + +} +static int ioconfig_bus_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + + struct ioconfig_parm parm; + + /* + * Copy in the parameters. + */ + copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm)); + parm.number = free_entry - new_entry; + parm.ioconfig_activated = ioconfig_activated; + copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm)); + copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct ascii_moduleid) * (free_entry - new_entry)); + + return 0; +} + +/* + * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus". + */ +static int ioconfig_bus_open(struct inode * inode, struct file * filp) +{ + if (ioconfig_bus_debug) { + DBG("ioconfig_bus_open called.\n"); + } + + return(0); + +} + +/* + * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus". + */ +static int ioconfig_bus_close(struct inode * inode, struct file * filp) +{ + + if (ioconfig_bus_debug) { + DBG("ioconfig_bus_close called.\n"); + } + + return(0); +} + +struct file_operations ioconfig_bus_fops = { + ioctl:ioconfig_bus_ioctl, + open:ioconfig_bus_open, /* open */ + release:ioconfig_bus_close /* release */ +}; + + +/* + * init_ifconfig_bus() - Boot time initialization. Ensure that it is called + * after devfs has been initialized. + * + */ +int init_ioconfig_bus(void) +{ + ioconfig_bus_handle = NULL; + ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus", + 0, DEVFS_FL_AUTO_DEVNUM, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + &ioconfig_bus_fops, NULL); + + if (ioconfig_bus_handle == NULL) { + panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n"); + } + + return(0); + +} + +static int __init ioconfig_bus_setup (char *str) +{ + + char *temp; + + DBG("ioconfig_bus_setup: Kernel Options %s\n", str); + + temp = (char *)ioconfig_kernopts; + memset(temp, 0, 128); + while ( (*str != '\0') && !isspace (*str) ) { + if (*str == ',') { + *temp = '\n'; + temp++; + str++; + continue; + } + *temp = *str; + temp++; + str++; + } + + return(0); + +} +__setup("ioconfig=", ioconfig_bus_setup); diff -urN linux-2.4.21/arch/ia64/sn/io/drivers/pciba.c linux-2.4.22/arch/ia64/sn/io/drivers/pciba.c --- linux-2.4.21/arch/ia64/sn/io/drivers/pciba.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/drivers/pciba.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,945 @@ +/* + * arch/ia64/sn/io/pciba.c + * + * IRIX PCIBA-inspired user mode PCI interface + * + * requires: devfs + * + * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the + * device is on, SS is the slot the device is in, and F is the + * device's function on a multi-function card). + * + * when compiled into the kernel, it will only be initialized by the + * sgi sn1 specific initialization code. in this case, device nodes + * are under /dev/hw/..../ + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of + * this archive for more details. + * + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. + * + * 03262001 - Initial version by Chad Talbott + */ + + +/* jesse's beefs: + + register_pci_device should be documented + + grossness with do_swap should be documented + + big, gross union'ized node_data should be replaced with independent + structures + + replace global list of nodes with global lists of resources. could + use object oriented approach of allocating and cleaning up + resources. + +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + + +MODULE_DESCRIPTION("User mode PCI interface"); +MODULE_AUTHOR("Chad Talbott"); + + +#undef DEBUG_PCIBA +/* #define DEBUG_PCIBA */ + +#undef TRACE_PCIBA +/* #define TRACE_PCIBA */ + +#if defined(DEBUG_PCIBA) +# define DPRINTF(x...) printk(KERN_DEBUG x) +#else +# define DPRINTF(x...) +#endif + +#if defined(TRACE_PCIBA) +# if defined(__GNUC__) +# define TRACE() printk(KERN_DEBUG "%s:%d:%s\n", \ + __FILE__, __LINE__, __FUNCTION__) +# else +# define TRACE() printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__) +# endif +#else +# define TRACE() +#endif + + +typedef enum { failure, success } status; +typedef enum { false, true } boolean; + + +/* major data structures: + + struct node_data - + + one for each file registered with devfs. contains everything + that any file's fops would need to know about. + + struct dma_allocation - + + a single DMA allocation. only the 'dma' nodes care about + these. they are there primarily to allow the driver to look + up the kernel virtual address of dma buffers allocated by + pci_alloc_consistent, as the application is only given the + physical address (to program the device's dma, presumably) and + cannot supply the kernel virtual address when freeing the + buffer. + + it's also useful to maintain a list of buffers allocated + through a specific node to allow some sanity checking by this + driver. this prevents (for example) a broken application from + freeing buffers that it didn't allocate, or buffers allocated + on another node. + + global_node_list - + + a list of all nodes allocated. this allows the driver to free + all the memory it has 'kmalloc'd in case of an error, or on + module removal. + + global_dma_list - + + a list of all dma buffers allocated by this driver. this + allows the driver to 'pci_free_consistent' all buffers on + module removal or error. + +*/ + + +struct node_data { + /* flat list of all the device nodes. makes it easy to free + them all when we're unregistered */ + struct list_head global_node_list; + vertex_hdl_t devfs_handle; + + void (* cleanup)(struct node_data *); + + union { + struct { + struct pci_dev * dev; + struct list_head dma_allocs; + boolean mmapped; + } dma; + struct { + struct pci_dev * dev; + u32 saved_rom_base_reg; + boolean mmapped; + } rom; + struct { + struct resource * res; + } base; + struct { + struct pci_dev * dev; + } config; + } u; +}; + +struct dma_allocation { + struct list_head list; + + dma_addr_t handle; + void * va; + size_t size; +}; + + +static LIST_HEAD(global_node_list); +static LIST_HEAD(global_dma_list); + + +/* module entry points */ +int __init pciba_init(void); +void __exit pciba_exit(void); + +static status __init register_with_devfs(void); +static void __exit unregister_with_devfs(void); + +static status __init register_pci_device(vertex_hdl_t device_dir_handle, + struct pci_dev * dev); + +/* file operations */ +static int generic_open(struct inode * inode, struct file * file); +static int rom_mmap(struct file * file, struct vm_area_struct * vma); +static int rom_release(struct inode * inode, struct file * file); +static int base_mmap(struct file * file, struct vm_area_struct * vma); +static int config_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, + unsigned long arg); +static int dma_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, + unsigned long arg); +static int dma_mmap(struct file * file, struct vm_area_struct * vma); + +/* support routines */ +static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va); +static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va); + +#ifdef DEBUG_PCIBA +static void dump_nodes(struct list_head * nodes); +static void dump_allocations(struct list_head * dalp); +#endif + +/* file operations for each type of node */ +static struct file_operations rom_fops = { + owner: THIS_MODULE, + mmap: rom_mmap, + open: generic_open, + release: rom_release +}; + + +static struct file_operations base_fops = { + owner: THIS_MODULE, + mmap: base_mmap, + open: generic_open +}; + + +static struct file_operations config_fops = { + owner: THIS_MODULE, + ioctl: config_ioctl, + open: generic_open +}; + +static struct file_operations dma_fops = { + owner: THIS_MODULE, + ioctl: dma_ioctl, + mmap: dma_mmap, + open: generic_open +}; + + +module_init(pciba_init); +module_exit(pciba_exit); + + +int __init +pciba_init(void) +{ + if (!ia64_platform_is("sn2")) + return -ENODEV; + + TRACE(); + + if (register_with_devfs() == failure) + return 1; /* failure */ + + printk("PCIBA (a user mode PCI interface) initialized.\n"); + + return 0; /* success */ +} + + +void __exit +pciba_exit(void) +{ + TRACE(); + + /* FIXME: should also free all that memory that we allocated + ;) */ + unregister_with_devfs(); +} + + +# if 0 +static void __exit +free_nodes(void) +{ + struct node_data * nd; + + TRACE(); + + list_for_each(nd, &node_list) { + kfree(list_entry(nd, struct nd, node_list)); + } +} +#endif + + +static vertex_hdl_t pciba_devfs_handle; + + +extern vertex_hdl_t +devfn_to_vertex(unsigned char busnum, unsigned int devfn); + +static status __init +register_with_devfs(void) +{ + struct pci_dev * dev; + vertex_hdl_t device_dir_handle; + + TRACE(); + + /* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */ + + pci_for_each_dev(dev) { + device_dir_handle = devfn_to_vertex(dev->bus->number, + dev->devfn); + if (device_dir_handle == NULL) + return failure; + + if (register_pci_device(device_dir_handle, dev) == failure) { + hwgraph_vertex_destroy(pciba_devfs_handle); + return failure; + } + } + + return success; +} + +static void __exit +unregister_with_devfs(void) +{ + struct list_head * lhp; + struct node_data * nd; + + TRACE(); + + list_for_each(lhp, &global_node_list) { + nd = list_entry(lhp, struct node_data, global_node_list); + hwgraph_vertex_destroy(nd->devfs_handle); + } + +} + + +struct node_data * new_node(void) +{ + struct node_data * node; + + TRACE(); + + node = kmalloc(sizeof(struct node_data), GFP_KERNEL); + if (node == NULL) + return NULL; + list_add(&node->global_node_list, &global_node_list); + return node; +} + + +void dma_cleanup(struct node_data * dma_node) +{ + TRACE(); + + /* FIXME: should free these allocations */ +#ifdef DEBUG_PCIBA + dump_allocations(&dma_node->u.dma.dma_allocs); +#endif + hwgraph_vertex_destroy(dma_node->devfs_handle); +} + + +void init_dma_node(struct node_data * node, + struct pci_dev * dev, vertex_hdl_t dh) +{ + TRACE(); + + node->devfs_handle = dh; + node->u.dma.dev = dev; + node->cleanup = dma_cleanup; + INIT_LIST_HEAD(&node->u.dma.dma_allocs); +} + + +void rom_cleanup(struct node_data * rom_node) +{ + TRACE(); + + if (rom_node->u.rom.mmapped) + pci_write_config_dword(rom_node->u.rom.dev, + PCI_ROM_ADDRESS, + rom_node->u.rom.saved_rom_base_reg); + hwgraph_vertex_destroy(rom_node->devfs_handle); +} + + +void init_rom_node(struct node_data * node, + struct pci_dev * dev, vertex_hdl_t dh) +{ + TRACE(); + + node->devfs_handle = dh; + node->u.rom.dev = dev; + node->cleanup = rom_cleanup; + node->u.rom.mmapped = false; +} + + +static status __init +register_pci_device(vertex_hdl_t device_dir_handle, struct pci_dev * dev) +{ + struct node_data * nd; + char devfs_path[20]; + vertex_hdl_t node_devfs_handle; + int ri; + + TRACE(); + + + /* register nodes for all the device's base address registers */ + for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) { + if (pci_resource_len(dev, ri) != 0) { + sprintf(devfs_path, "base/%d", ri); + if (hwgraph_register(device_dir_handle, devfs_path, + 0, DEVFS_FL_NONE, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR, 0, 0, + &base_fops, + &dev->resource[ri]) == NULL) + return failure; + } + } + + /* register a node corresponding to the first MEM resource on + the device */ + for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) { + if (dev->resource[ri].flags & IORESOURCE_MEM && + pci_resource_len(dev, ri) != 0) { + if (hwgraph_register(device_dir_handle, "mem", + 0, DEVFS_FL_NONE, 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR, 0, 0, + &base_fops, + &dev->resource[ri]) == NULL) + return failure; + break; + } + } + + /* also register a node corresponding to the first IO resource + on the device */ + for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) { + if (dev->resource[ri].flags & IORESOURCE_IO && + pci_resource_len(dev, ri) != 0) { + if (hwgraph_register(device_dir_handle, "io", + 0, DEVFS_FL_NONE, 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR, 0, 0, + &base_fops, + &dev->resource[ri]) == NULL) + return failure; + break; + } + } + + /* register a node corresponding to the device's ROM resource, + if present */ + if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) { + nd = new_node(); + if (nd == NULL) + return failure; + node_devfs_handle = hwgraph_register(device_dir_handle, "rom", + 0, DEVFS_FL_NONE, 0, 0, + S_IFCHR | S_IRUSR, 0, 0, + &rom_fops, nd); + if (node_devfs_handle == NULL) + return failure; + init_rom_node(nd, dev, node_devfs_handle); + } + + /* register a node that allows ioctl's to read and write to + the device's config space */ + if (hwgraph_register(device_dir_handle, "config", 0, DEVFS_FL_NONE, + 0, 0, S_IFCHR | S_IRUSR | S_IWUSR, 0, 0, + &config_fops, dev) == NULL) + return failure; + + + /* finally, register a node that allows ioctl's to allocate + and free DMA buffers, as well as memory map those + buffers. */ + nd = new_node(); + if (nd == NULL) + return failure; + node_devfs_handle = + hwgraph_register(device_dir_handle, "dma", 0, DEVFS_FL_NONE, + 0, 0, S_IFCHR | S_IRUSR | S_IWUSR, 0, 0, + &dma_fops, nd); + if (node_devfs_handle == NULL) + return failure; + init_dma_node(nd, dev, node_devfs_handle); + +#ifdef DEBUG_PCIBA + dump_nodes(&global_node_list); +#endif + + return success; +} + + +static int +generic_open(struct inode * inode, struct file * file) +{ + TRACE(); + + /* FIXME: should check that they're not trying to open the ROM + writable */ + + return 0; /* success */ +} + + +static int +rom_mmap(struct file * file, struct vm_area_struct * vma) +{ + unsigned long pci_pa; + struct node_data * nd; + + TRACE(); + +#ifdef CONFIG_HWGFS_FS + nd = (struct node_data * )file->f_dentry->d_fsdata; +#else + nd = (struct node_data * )file->private_data; +#endif + + pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE); + + if (!nd->u.rom.mmapped) { + nd->u.rom.mmapped = true; + DPRINTF("Enabling ROM address decoder.\n"); + DPRINTF( +"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n" +"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n"); + pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS, + &nd->u.rom.saved_rom_base_reg); + DPRINTF("ROM base address contains %x\n", + nd->u.rom.saved_rom_base_reg); + pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS, + nd->u.rom.saved_rom_base_reg | + PCI_ROM_ADDRESS_ENABLE); + } + + return mmap_pci_address(vma, pci_pa); +} + + +static int +rom_release(struct inode * inode, struct file * file) +{ + struct node_data * nd; + + TRACE(); + +#ifdef CONFIG_HWGFS_FS + nd = (struct node_data * )file->f_dentry->d_fsdata; +#else + nd = (struct node_data * )file->private_data; +#endif + + if (nd->u.rom.mmapped) { + nd->u.rom.mmapped = false; + DPRINTF("Disabling ROM address decoder.\n"); + pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS, + nd->u.rom.saved_rom_base_reg); + } + return 0; /* indicate success */ +} + + +static int +base_mmap(struct file * file, struct vm_area_struct * vma) +{ + struct resource * resource; + + TRACE(); + +#ifdef CONFIG_HWGFS_FS + resource = (struct resource *)file->f_dentry->d_fsdata; +#else + resource = (struct resource *)file->private_data; +#endif + + return mmap_pci_address(vma, resource->start); +} + + +static int +config_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, + unsigned long arg) +{ + struct pci_dev * dev; + + union cfg_data { + uint8_t byte; + uint16_t word; + uint32_t dword; + } read_data, write_data; + + int dir, size, offset; + + TRACE(); + + DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", + cmd, + _IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd)); + DPRINTF("arg = %lx\n", arg); + +#ifdef CONFIG_HWGFS_FS + dev = (struct pci_dev *)file->f_dentry->d_fsdata; +#else + dev = (struct pci_dev *)file->private_data; +#endif + + /* PCIIOCCFG{RD,WR}: read and/or write PCI configuration + space. If both, the read happens first (this becomes a swap + operation, atomic with respect to other updates through + this path). */ + + dir = _IOC_DIR(cmd); + +#define do_swap(suffix, type) \ + do { \ + if (dir & _IOC_READ) { \ + pci_read_config_##suffix(dev, _IOC_NR(cmd), \ + &read_data.suffix); \ + } \ + if (dir & _IOC_WRITE) { \ + get_user(write_data.suffix, (type)arg); \ + pci_write_config_##suffix(dev, _IOC_NR(cmd), \ + write_data.suffix); \ + } \ + if (dir & _IOC_READ) { \ + put_user(read_data.suffix, (type)arg); \ + } \ + } while (0) + + size = _IOC_SIZE(cmd); + offset = _IOC_NR(cmd); + + DPRINTF("sanity check\n"); + if (((size > 0) || (size <= 4)) && + ((offset + size) <= 256) && + (dir & (_IOC_READ | _IOC_WRITE))) { + + switch (size) + { + case 1: + do_swap(byte, uint8_t *); + break; + case 2: + do_swap(word, uint16_t *); + break; + case 4: + do_swap(dword, uint32_t *); + break; + default: + DPRINTF("invalid ioctl\n"); + return -EINVAL; + } + } else + return -EINVAL; + + return 0; +} + + +#ifdef DEBUG_PCIBA +static void +dump_allocations(struct list_head * dalp) +{ + struct dma_allocation * dap; + struct list_head * p; + + printk("{\n"); + list_for_each(p, dalp) { + dap = list_entry(p, struct dma_allocation, + list); + printk(" handle = %lx, va = %p\n", + dap->handle, dap->va); + } + printk("}\n"); +} + +static void +dump_nodes(struct list_head * nodes) +{ + struct node_data * ndp; + struct list_head * p; + + printk("{\n"); + list_for_each(p, nodes) { + ndp = list_entry(p, struct node_data, + global_node_list); + printk(" %p\n", (void *)ndp); + } + printk("}\n"); +} + + +#if 0 +#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) + +static void +test_list(void) +{ + u64 i; + LIST_HEAD(the_list); + + for (i = 0; i < 5; i++) { + struct dma_allocation * new_alloc; + NEW(new_alloc); + new_alloc->va = (void *)i; + new_alloc->handle = 5*i; + printk("%d - the_list->next = %lx\n", i, the_list.next); + list_add(&new_alloc->list, &the_list); + } + dump_allocations(&the_list); +} +#endif +#endif + + +static LIST_HEAD(dma_buffer_list); + + +static int +dma_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, + unsigned long arg) +{ + struct node_data * nd; + uint64_t argv; + int result; + struct dma_allocation * dma_alloc; + struct list_head * iterp; + + TRACE(); + + DPRINTF("cmd = %x\n", cmd); + DPRINTF("arg = %lx\n", arg); + +#ifdef CONFIG_HWGFS_FS + nd = (struct node_data *)file->f_dentry->d_fsdata; +#else + nd = (struct node_data *)file->private_data; +#endif + +#ifdef DEBUG_PCIBA + DPRINTF("at dma_ioctl entry\n"); + dump_allocations(&nd->u.dma.dma_allocs); +#endif + + switch (cmd) { + case PCIIOCDMAALLOC: + /* PCIIOCDMAALLOC: allocate a chunk of physical memory + and set it up for DMA. Return the PCI address that + gets to it. */ + DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC); + + if ( (result = get_user(argv, (uint64_t *)arg)) ) + return result; + DPRINTF("argv (size of buffer) = %lx\n", argv); + + dma_alloc = (struct dma_allocation *) + kmalloc(sizeof(struct dma_allocation), GFP_KERNEL); + if (dma_alloc == NULL) + return -ENOMEM; + + dma_alloc->size = (size_t)argv; + dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev, + dma_alloc->size, + &dma_alloc->handle); + DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n", + dma_alloc->va, dma_alloc->handle); + if (dma_alloc->va == NULL) { + kfree(dma_alloc); + return -ENOMEM; + } + + list_add(&dma_alloc->list, &nd->u.dma.dma_allocs); + if ( (result = put_user((uint64_t)dma_alloc->handle, + (uint64_t *)arg)) ) { + DPRINTF("put_user failed\n"); + pci_free_consistent(nd->u.dma.dev, (size_t)argv, + dma_alloc->va, dma_alloc->handle); + kfree(dma_alloc); + return result; + } + +#ifdef DEBUG_PCIBA + DPRINTF("after insertion\n"); + dump_allocations(&nd->u.dma.dma_allocs); +#endif + break; + + case PCIIOCDMAFREE: + DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE); + + if ( (result = get_user(argv, (uint64_t *)arg)) ) { + DPRINTF("get_user failed\n"); + return result; + } + + DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv); + list_for_each(iterp, &nd->u.dma.dma_allocs) { + struct dma_allocation * da = + list_entry(iterp, struct dma_allocation, list); + if (da->handle == argv) { + pci_free_consistent(nd->u.dma.dev, da->size, + da->va, da->handle); + list_del(&da->list); + kfree(da); +#ifdef DEBUG_PCIBA + DPRINTF("after deletion\n"); + dump_allocations(&nd->u.dma.dma_allocs); +#endif + return 0; /* success */ + } + } + /* previously allocated dma buffer wasn't found */ + DPRINTF("attempt to free invalid dma handle\n"); + return -EINVAL; + + default: + DPRINTF("undefined ioctl\n"); + return -EINVAL; + } + + DPRINTF("success\n"); + return 0; +} + + +static int +dma_mmap(struct file * file, struct vm_area_struct * vma) +{ + struct node_data * nd; + struct list_head * iterp; + int result; + + TRACE(); + +#ifdef CONFIG_HWGFS_FS + nd = (struct node_data *)file->f_dentry->d_fsdata; +#else + nd = (struct node_data *)file->private_data; +#endif + + DPRINTF("vma->vm_start is %lx\n", vma->vm_start); + DPRINTF("vma->vm_end is %lx\n", vma->vm_end); + DPRINTF("offset = %lx\n", vma->vm_pgoff); + + /* get kernel virtual address for the dma buffer (necessary + * for the mmap). */ + list_for_each(iterp, &nd->u.dma.dma_allocs) { + struct dma_allocation * da = + list_entry(iterp, struct dma_allocation, list); + /* why does mmap shift its offset argument? */ + if (da->handle == vma->vm_pgoff << PAGE_SHIFT) { + DPRINTF("found dma handle\n"); + if ( (result = mmap_kernel_address(vma, + da->va)) ) { + return result; /* failure */ + } else { + /* it seems like at least one of these + should show up in user land.... + I'm missing something */ + *(char *)da->va = 0xaa; + strncpy(da->va, " Toastie!", da->size); + if (put_user(0x18badbeeful, + (u64 *)vma->vm_start)) + DPRINTF("put_user failed?!\n"); + return 0; /* success */ + } + + } + } + DPRINTF("attempt to mmap an invalid dma handle\n"); + return -EINVAL; +} + + +static int +mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va) +{ + unsigned long pci_pa; + + TRACE(); + + DPRINTF("vma->vm_start is %lx\n", vma->vm_start); + DPRINTF("vma->vm_end is %lx\n", vma->vm_end); + + /* the size of the vma doesn't necessarily correspond to the + size specified in the mmap call. So we can't really do any + kind of sanity check here. This is a dangerous driver, and + it's very easy for a user process to kill the machine. */ + + DPRINTF("PCI base at virtual address %lx\n", pci_va); + /* the __pa macro is intended for region 7 on IA64, so it + doesn't work for region 6 */ + /* pci_pa = __pa(pci_va); */ + /* should be replaced by __tpa or equivalent (preferably a + generic equivalent) */ + pci_pa = pci_va & ~0xe000000000000000ul; + DPRINTF("PCI base at physical address %lx\n", pci_pa); + + /* there are various arch-specific versions of this function + defined in linux/drivers/char/mem.c, but it would be nice + if all architectures put it in pgtable.h. it's defined + there for ia64.... */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO; + + return io_remap_page_range(vma->vm_start, pci_pa, + vma->vm_end-vma->vm_start, + vma->vm_page_prot); +} + + +static int +mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va) +{ + unsigned long kernel_pa; + + TRACE(); + + DPRINTF("vma->vm_start is %lx\n", vma->vm_start); + DPRINTF("vma->vm_end is %lx\n", vma->vm_end); + + /* the size of the vma doesn't necessarily correspond to the + size specified in the mmap call. So we can't really do any + kind of sanity check here. This is a dangerous driver, and + it's very easy for a user process to kill the machine. */ + + DPRINTF("mapping virtual address %p\n", kernel_va); + kernel_pa = __pa(kernel_va); + DPRINTF("mapping physical address %lx\n", kernel_pa); + + vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO; + + return remap_page_range(vma->vm_start, kernel_pa, + vma->vm_end-vma->vm_start, + vma->vm_page_prot); +} diff -urN linux-2.4.21/arch/ia64/sn/io/eeprom.c linux-2.4.22/arch/ia64/sn/io/eeprom.c --- linux-2.4.21/arch/ia64/sn/io/eeprom.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/eeprom.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1422 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * WARNING: There is more than one copy of this file in different isms. - * All copies must be kept exactly in sync. - * Do not modify this file without also updating the following: - * - * irix/kern/io/eeprom.c - * stand/arcs/lib/libsk/ml/eeprom.c - * stand/arcs/lib/libkl/io/eeprom.c - * - * (from time to time they might not be in sync but that's due to bringup - * activity - this comment is to remind us that they eventually have to - * get back together) - * - * eeprom.c - * - * access to board-mounted EEPROMs via the L1 system controllers - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(EEPROM_DEBUG) -#define db_printf(x) printk x -#else -#define db_printf(x) printk x -#endif - -#define BCOPY(x,y,z) memcpy(y,x,z) - -#define UNDERSCORE 0 /* don't convert underscores to hyphens */ -#define HYPHEN 1 /* convert underscores to hyphens */ - -void copy_ascii_field( char *to, char *from, int length, - int change_underscore ); -uint64_t generate_unique_id( char *sn, int sn_len ); -uchar_t char_to_base36( char c ); -int nicify( char *dst, eeprom_brd_record_t *src ); -static void int64_to_hex_string( char *out, uint64_t val ); - -// extern int router_lock( net_vec_t, int, int ); -// extern int router_unlock( net_vec_t ); -#define ROUTER_LOCK(p) // router_lock(p, 10000, 3000000) -#define ROUTER_UNLOCK(p) // router_unlock(p) - -#define IP27LOG_OVNIC "OverrideNIC" - - -/* the following function converts an EEPROM record to a close facsimile - * of the string returned by reading a Dallas Semiconductor NIC (see - * one of the many incarnations of nic.c for details on that driver) - */ -int nicify( char *dst, eeprom_brd_record_t *src ) -{ - int field_len; - uint64_t unique_id; - char *cur_dst = dst; - eeprom_board_ia_t *board; - - board = src->board_ia; - ASSERT( board ); /* there should always be a board info area */ - - /* copy part number */ - strcpy( cur_dst, "Part:" ); - cur_dst += strlen( cur_dst ); - ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK) - == FIELD_FORMAT_ASCII ); - field_len = board->part_num_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN ); - cur_dst += field_len; - - /* copy product name */ - strcpy( cur_dst, ";Name:" ); - cur_dst += strlen( cur_dst ); - ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII ); - field_len = board->product_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE ); - cur_dst += field_len; - - /* copy serial number */ - strcpy( cur_dst, ";Serial:" ); - cur_dst += strlen( cur_dst ); - ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK) - == FIELD_FORMAT_ASCII ); - field_len = board->serial_num_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->serial_num, field_len, - HYPHEN); - - cur_dst += field_len; - - /* copy revision */ - strcpy( cur_dst, ";Revision:"); - cur_dst += strlen( cur_dst ); - ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK) - == FIELD_FORMAT_ASCII ); - field_len = board->board_rev_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN ); - cur_dst += field_len; - - /* EEPROMs don't have equivalents for the Group, Capability and - * Variety fields, so we pad these with 0's - */ - strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" ); - cur_dst += strlen( cur_dst ); - - /* use the board serial number to "fake" a laser id */ - strcpy( cur_dst, ";Laser:" ); - cur_dst += strlen( cur_dst ); - unique_id = generate_unique_id( board->serial_num, - board->serial_num_tl & FIELD_LENGTH_MASK ); - int64_to_hex_string( cur_dst, unique_id ); - strcat( dst, ";" ); - - return 1; -} - - -/* These functions borrow heavily from chars2* in nic.c - */ -void copy_ascii_field( char *to, char *from, int length, - int change_underscore ) -{ - int i; - for( i = 0; i < length; i++ ) { - - /* change underscores to hyphens if requested */ - if( from[i] == '_' && change_underscore == HYPHEN ) - to[i] = '-'; - - /* ; and ; are separators, so mustn't appear within - * a field */ - else if( from[i] == ':' || from[i] == ';' ) - to[i] = '?'; - - /* I'm not sure why or if ASCII character 0xff would - * show up in an EEPROM field, but the NIC parsing - * routines wouldn't like it if it did... so we - * get rid of it, just in case. */ - else if( (unsigned char)from[i] == (unsigned char)0xff ) - to[i] = ' '; - - /* unprintable characters are replaced with . */ - else if( from[i] < ' ' || from[i] >= 0x7f ) - to[i] = '.'; - - /* otherwise, just copy the character */ - else - to[i] = from[i]; - } - - if( i == 0 ) { - to[i] = ' '; /* return at least a space... */ - i++; - } - to[i] = 0; /* terminating null */ -} - -/* Note that int64_to_hex_string currently only has a big-endian - * implementation. - */ -#ifdef _MIPSEB -static void int64_to_hex_string( char *out, uint64_t val ) -{ - int i; - uchar_t table[] = "0123456789abcdef"; - uchar_t *byte_ptr = (uchar_t *)&val; - for( i = 0; i < sizeof(uint64_t); i++ ) { - out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ]; - out[i*2+1] = table[ (*byte_ptr) & 0x0f ]; - byte_ptr++; - } - out[i*2] = '\0'; -} - -#else /* little endian */ - -static void int64_to_hex_string( char *out, uint64_t val ) -{ - - - printk("int64_to_hex_string needs a little-endian implementation.\n"); -} -#endif /* _MIPSEB */ - -/* Convert a standard ASCII serial number to a unique integer - * id number by treating the serial number string as though - * it were a base 36 number - */ -uint64_t generate_unique_id( char *sn, int sn_len ) -{ - int uid = 0; - int i; - - #define VALID_BASE36(c) ((c >= '0' && c <='9') \ - || (c >= 'A' && c <='Z') \ - || (c >= 'a' && c <='z')) - - for( i = 0; i < sn_len; i++ ) { - if( !VALID_BASE36(sn[i]) ) - continue; - uid *= 36; - uid += char_to_base36( sn[i] ); - } - - if( uid == 0 ) - return rtc_time(); - - return uid; -} - -uchar_t char_to_base36( char c ) -{ - uchar_t val; - - if( c >= '0' && c <= '9' ) - val = (c - '0'); - - else if( c >= 'A' && c <= 'Z' ) - val = (c - 'A' + 10); - - else if( c >= 'a' && c <= 'z' ) - val = (c - 'a' + 10); - - else val = 0; - - return val; -} - - -/* given a pointer to the three-byte little-endian EEPROM representation - * of date-of-manufacture, this function translates to a big-endian - * integer format - */ -int eeprom_xlate_board_mfr_date( uchar_t *src ) -{ - int rval = 0; - rval += *src; src++; - rval += ((int)(*src) << 8); src ++; - rval += ((int)(*src) << 16); - return rval; -} - - -int eeprom_str( char *nic_str, nasid_t nasid, int component ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - - if( (component & C_DIMM) == C_DIMM ) { - /* this function isn't applicable to DIMMs */ - return EEP_PARAM; - } - else { - eep.board_ia = &board; - eep.spd = NULL; - if( !(component & SUBORD_MASK) ) - eep.chassis_ia = &chassis; /* only main boards have a chassis - * info area */ - else - eep.chassis_ia = NULL; - } - - switch( component & BRICK_MASK ) { - case C_BRICK: - r = cbrick_eeprom_read( &eep, nasid, component ); - break; - case IO_BRICK: - r = iobrick_eeprom_read( &eep, nasid, component ); - break; - default: - return EEP_PARAM; /* must be an invalid component */ - } - if( r ) - return r; - if( !nicify( nic_str, &eep ) ) - return EEP_NICIFY; - - return EEP_OK; -} - -int vector_eeprom_str( char *nic_str, nasid_t nasid, - int component, net_vec_t path ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - - eep.board_ia = &board; - if( !(component & SUBORD_MASK) ) - eep.chassis_ia = &chassis; /* only main boards have a chassis - * info area */ - else - eep.chassis_ia = NULL; - - if( !(component & VECTOR) ) - return EEP_PARAM; - - if( (r = vector_eeprom_read( &eep, nasid, path, component )) ) - return r; - - if( !nicify( nic_str, &eep ) ) - return EEP_NICIFY; - - return EEP_OK; -} - - -int is_iobrick( int nasid, int widget_num ) -{ - uint32_t wid_reg; - int part_num, mfg_num; - - /* Read the widget's WIDGET_ID register to get - * its part number and mfg number - */ - wid_reg = *(volatile int32_t *) - (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID); - - part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; - mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT; - - /* Is this the "xbow part" of an XBridge? If so, this - * widget is definitely part of an I/O brick. - */ - if( part_num == XXBOW_WIDGET_PART_NUM && - mfg_num == XXBOW_WIDGET_MFGR_NUM ) - - return 1; - - /* Is this a "bridge part" of an XBridge? If so, once - * again, we know this widget is part of an I/O brick. - */ - if( part_num == XBRIDGE_WIDGET_PART_NUM && - mfg_num == XBRIDGE_WIDGET_MFGR_NUM ) - - return 1; - - return 0; -} - - -int cbrick_uid_get( nasid_t nasid, uint64_t *uid ) -{ - char uid_str[32]; - char msg[BRL1_QSIZE]; - int subch, len; - l1sc_t sc; - l1sc_t *scp; - int local = (nasid == get_nasid()); - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* If the promlog variable pointed to by IP27LOG_OVNIC is set, - * use that value for the cbrick UID rather than the EEPROM - * serial number. - */ -#ifdef LOG_GETENV - if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 ) - { - /* We successfully read IP27LOG_OVNIC, so return it as the UID. */ - db_printf(( "cbrick_uid_get:" - "Overriding UID with environment variable %s\n", - IP27LOG_OVNIC )); - *uid = strtoull( uid_str, NULL, 0 ); - return EEP_OK; - } -#endif - - /* If this brick is retrieving its own uid, use the local l1sc_t to - * arbitrate access to the l1; otherwise, set up a new one. - */ - if( local ) { - scp = get_l1sc(); - } - else { - scp = ≻ - sc_init( &sc, nasid, BRL1_LOCALHUB_UART ); - } - - /* fill in msg with the opcode & params */ - BZERO( msg, BRL1_QSIZE ); - if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 ) - return EEP_L1; - - if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_SER_NUM, 0 )) < 0 ) - { - sc_close( scp, subch ); - return( EEP_L1 ); - } - - /* send the request to the L1 */ - if( sc_command( scp, subch, msg, msg, &len ) ) { - sc_close( scp, subch ); - return( EEP_L1 ); - } - - /* free up subchannel */ - sc_close(scp, subch); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 ) - { - return( EEP_L1 ); - } - - *uid = generate_unique_id( uid_str, strlen( uid_str ) ); - - return EEP_OK; -} - - -int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid ) -{ - char uid_str[32]; - char msg[BRL1_QSIZE]; - int subch, len; - l1sc_t sc; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - -#define FAIL \ - { \ - *uid = rtc_time(); \ - printk( "rbrick_uid_get failed; using current time as uid\n" ); \ - return EEP_OK; \ - } - - ROUTER_LOCK(path); - sc_init( &sc, nasid, path ); - - /* fill in msg with the opcode & params */ - BZERO( msg, BRL1_QSIZE ); - if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) { - ROUTER_UNLOCK(path); - FAIL; - } - - if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_SER_NUM, 0 )) < 0 ) - { - ROUTER_UNLOCK(path); - sc_close( &sc, subch ); - FAIL; - } - - /* send the request to the L1 */ - if( sc_command( &sc, subch, msg, msg, &len ) ) { - ROUTER_UNLOCK(path); - sc_close( &sc, subch ); - FAIL; - } - - /* free up subchannel */ - ROUTER_UNLOCK(path); - sc_close(&sc, subch); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 ) - { - FAIL; - } - - *uid = generate_unique_id( uid_str, strlen( uid_str ) ); - - return EEP_OK; -} - -int iobrick_uid_get( nasid_t nasid, uint64_t *uid ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - - eep.board_ia = &board; - eep.chassis_ia = &chassis; - eep.spd = NULL; - - r = iobrick_eeprom_read( &eep, nasid, IO_BRICK ); - if( r != EEP_OK ) { - *uid = rtc_time(); - return r; - } - - *uid = generate_unique_id( board.serial_num, - board.serial_num_tl & FIELD_LENGTH_MASK ); - - return EEP_OK; -} - - -int ibrick_mac_addr_get( nasid_t nasid, char *eaddr ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - char *tmp; - - eep.board_ia = &board; - eep.chassis_ia = &chassis; - eep.spd = NULL; - - r = iobrick_eeprom_read( &eep, nasid, IO_BRICK ); - if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) { - db_printf(( "ibrick_mac_addr_get: " - "Couldn't read MAC address from EEPROM\n" )); - return EEP_L1; - } - else { - /* successfully read info area */ - int ix; - tmp = board.mac_addr; - for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ ) - { - *eaddr++ = *tmp++; - } - *eaddr = '\0'; - } - - return EEP_OK; -} - - -/* - * eeprom_vertex_info_set - * - * Given a vertex handle, a component designation, a starting nasid - * and (in the case of a router) a vector path to the component, this - * function will read the EEPROM and attach the resulting information - * to the vertex in the same string format as that provided by the - * Dallas Semiconductor NIC drivers. If the vertex already has the - * string, this function just returns the string. - */ - -extern char *nic_vertex_info_get( devfs_handle_t ); -extern void nic_vmc_check( devfs_handle_t, char * ); -/* the following were lifted from nic.c - change later? */ -#define MAX_INFO 2048 -#define NEWSZ(ptr,sz) ((ptr) = kern_malloc((sz))) -#define DEL(ptr) (kern_free((ptr))) - -char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v, - net_vec_t path ) -{ - char *info_tmp; - int info_len; - char *info; - - /* see if this vertex is already marked */ - info_tmp = nic_vertex_info_get(v); - if (info_tmp) return info_tmp; - - /* get a temporary place for the data */ - NEWSZ(info_tmp, MAX_INFO); - if (!info_tmp) return NULL; - - /* read the EEPROM */ - if( component & R_BRICK ) { - if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK ) - return NULL; - } - else { - if( eeprom_str( info_tmp, nasid, component ) != EEP_OK ) - return NULL; - } - - /* allocate a smaller final place */ - info_len = strlen(info_tmp)+1; - NEWSZ(info, info_len); - if (info) { - strcpy(info, info_tmp); - DEL(info_tmp); - } else { - info = info_tmp; - } - - /* add info to the vertex */ - hwgraph_info_add_LBL(v, INFO_LBL_NIC, - (arbitrary_info_t) info); - - /* see if someone else got there first */ - info_tmp = nic_vertex_info_get(v); - if (info != info_tmp) { - DEL(info); - return info_tmp; - } - - /* export the data */ - hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len); - - /* trigger all matching callbacks */ - nic_vmc_check(v, info); - - return info; -} - - -/********************************************************************* - * - * stubs for use until the Bedrock/L1 link is available - * - */ - -#include - -/* #define EEPROM_TEST */ - -/* fake eeprom reading functions (replace when the BR/L1 communication - * channel is in working order) - */ - - -/* generate a charater in [0-9A-Z]; if an "extra" character is - * specified (such as '_'), include it as one of the possibilities. - */ -char random_eeprom_ch( char extra ) -{ - char ch; - int modval = 36; - if( extra ) - modval++; - - ch = rtc_time() % modval; - - if( ch < 10 ) - ch += '0'; - else if( ch >= 10 && ch < 36 ) - ch += ('A' - 10); - else - ch = extra; - - return ch; -} - -/* create a part number of the form xxx-xxxx-xxx. - * It may be important later to generate different - * part numbers depending on the component we're - * supposed to be "reading" from, so the component - * paramter is provided. - */ -void fake_a_part_number( char *buf, int component ) -{ - int i; - switch( component ) { - - /* insert component-specific routines here */ - - case C_BRICK: - strcpy( buf, "030-1266-001" ); - break; - default: - for( i = 0; i < 12; i++ ) { - if( i == 3 || i == 8 ) - buf[i] = '-'; - else - buf[i] = random_eeprom_ch(0); - } - } -} - - -/* create a six-character serial number */ -void fake_a_serial_number( char *buf, uint64_t ser ) -{ - int i; - static const char hexchars[] = "0123456789ABCDEF"; - - if (ser) { - for( i = 5; i >=0; i-- ) { - buf[i] = hexchars[ser & 0xf]; - ser >>= 4; - } - } - else { - for( i = 0; i < 6; i++ ) - buf[i] = random_eeprom_ch(0); - } -} - - -void fake_a_product_name( uchar_t *format, char* buf, int component ) -{ - switch( component & BRICK_MASK ) { - - case C_BRICK: - if( component & SUBORD_MASK ) { - strcpy( buf, "C_BRICK_SUB" ); - *format = 0xCB; - } - else { - strcpy( buf, "IP35" ); - *format = 0xC4; - } - break; - - case R_BRICK: - if( component & SUBORD_MASK ) { - strcpy( buf, "R_BRICK_SUB" ); - *format = 0xCB; - } - else { - strcpy( buf, "R_BRICK" ); - *format = 0xC7; - } - break; - - case IO_BRICK: - if( component & SUBORD_MASK ) { - strcpy( buf, "IO_BRICK_SUB" ); - *format = 0xCC; - } - else { - strcpy( buf, "IO_BRICK" ); - *format = 0xC8; - } - break; - - default: - strcpy( buf, "UNK_DEVICE" ); - *format = 0xCA; - } -} - - - -int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, - uint64_t ser ) -{ - eeprom_board_ia_t *board; - eeprom_chassis_ia_t *chassis; - int i, cs; - - board = buf->board_ia; - chassis = buf->chassis_ia; - - if( !(component & SUBORD_MASK) ) { - if( !chassis ) - return EEP_PARAM; - chassis->format = 0; - chassis->length = 5; - chassis->type = 0x17; - - chassis->part_num_tl = 0xCC; - fake_a_part_number( chassis->part_num, component ); - chassis->serial_num_tl = 0xC6; - fake_a_serial_number( chassis->serial_num, ser ); - - cs = chassis->format + chassis->length + chassis->type - + chassis->part_num_tl + chassis->serial_num_tl; - for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += chassis->part_num[i]; - for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += chassis->serial_num[i]; - chassis->checksum = 256 - (cs % 256); - } - - if( !board ) - return EEP_PARAM; - board->format = 0; - board->length = 10; - board->language = 0; - board->mfg_date = 1789200; /* noon, 5/26/99 */ - board->manuf_tl = 0xC3; - strcpy( board->manuf, "SGI" ); - - fake_a_product_name( &(board->product_tl), board->product, component ); - - board->serial_num_tl = 0xC6; - fake_a_serial_number( board->serial_num, ser ); - - board->part_num_tl = 0xCC; - fake_a_part_number( board->part_num, component ); - - board->board_rev_tl = 0xC2; - board->board_rev[0] = '0'; - board->board_rev[1] = '1'; - - board->eeprom_size_tl = 0x01; - board->eeprom_size = 1; - - board->temp_waiver_tl = 0xC2; - board->temp_waiver[0] = '0'; - board->temp_waiver[1] = '1'; - - cs = board->format + board->length + board->language - + (board->mfg_date & 0xFF) - + (board->mfg_date & 0xFF00) - + (board->mfg_date & 0xFF0000) - + board->manuf_tl + board->product_tl + board->serial_num_tl - + board->part_num_tl + board->board_rev_tl - + board->board_rev[0] + board->board_rev[1] - + board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl - + board->temp_waiver[0] + board->temp_waiver[1]; - for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->manuf[i]; - for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->product[i]; - for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->serial_num[i]; - for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->part_num[i]; - - board->checksum = 256 - (cs % 256); - - return EEP_OK; -} - -#define EEPROM_CHUNKSIZE 64 - -#if defined(EEPROM_DEBUG) -#define RETURN_ERROR \ -{ \ - printk( "read_ia error return, component 0x%x, line %d" \ - ", address 0x%x, ia code 0x%x\n", \ - l1_compt, __LINE__, sc->subch[subch].target, ia_code ); \ - return EEP_L1; \ -} - -#else -#define RETURN_ERROR return(EEP_L1) -#endif - -int read_ia( l1sc_t *sc, int subch, int l1_compt, - int ia_code, char *eep_record ) -{ - char msg[BRL1_QSIZE]; /* message buffer */ - int len; /* number of bytes used in message buffer */ - int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */ - int offset = 0; /* current offset into info area */ - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - BZERO( msg, BRL1_QSIZE ); - - /* retrieve EEPROM data in 64-byte chunks - */ - - while( ia_len ) - { - /* fill in msg with opcode & params */ - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_EEPROM, 8, - L1_ARG_INT, l1_compt, - L1_ARG_INT, ia_code, - L1_ARG_INT, offset, - L1_ARG_INT, ia_len )) < 0 ) - { - RETURN_ERROR; - } - - /* send the request to the L1 */ - - if( sc_command( sc, subch, msg, msg, &len ) ) { - RETURN_ERROR; - } - - /* check response */ - if( sc_interpret_resp( msg, 5, - L1_ARG_INT, &ia_len, - L1_ARG_UNKNOWN, &len, eep_record ) < 0 ) - { - RETURN_ERROR; - } - - if( ia_len > EEPROM_CHUNKSIZE ) - ia_len = EEPROM_CHUNKSIZE; - - eep_record += EEPROM_CHUNKSIZE; - offset += EEPROM_CHUNKSIZE; - } - - return EEP_OK; -} - - -int read_spd( l1sc_t *sc, int subch, int l1_compt, - eeprom_spd_u *spd ) -{ - char msg[BRL1_QSIZE]; /* message buffer */ - int len; /* number of bytes used in message buffer */ - int resp; /* l1 response code */ - int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */ - int offset = 0; /* current offset into spd record */ - char *spd_p = spd->bytes; /* "thumb" for writing to spd */ - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - BZERO( msg, BRL1_QSIZE ); - - /* retrieve EEPROM data in 64-byte chunks - */ - - while( spd_len ) - { - /* fill in msg with opcode & params */ - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_EEPROM, 8, - L1_ARG_INT, l1_compt, - L1_ARG_INT, L1_EEP_SPD, - L1_ARG_INT, offset, - L1_ARG_INT, spd_len )) < 0 ) - { - return( EEP_L1 ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) ) { - return( EEP_L1 ); - } - - /* check response */ - if( (resp = sc_interpret_resp( msg, 5, - L1_ARG_INT, &spd_len, - L1_ARG_UNKNOWN, &len, spd_p )) < 0 ) - { - /* - * translate l1 response code to eeprom.c error codes: - * The L1 response will be L1_RESP_NAVAIL if the spd - * can't be read (i.e. the spd isn't physically there). It will - * return L1_RESP_INVAL if the spd exists, but fails the checksum - * test because the eeprom wasn't programmed, programmed incorrectly, - * or corrupted. L1_RESP_NAVAIL indicates the eeprom is likely not present, - * whereas L1_RESP_INVAL indicates the eeprom is present, but the data is - * invalid. - */ - if(resp == L1_RESP_INVAL) { - resp = EEP_BAD_CHECKSUM; - } else { - resp = EEP_L1; - } - return( resp ); - } - - if( spd_len > EEPROM_CHUNKSIZE ) - spd_len = EEPROM_CHUNKSIZE; - - spd_p += EEPROM_CHUNKSIZE; - offset += EEPROM_CHUNKSIZE; - } - return EEP_OK; -} - - -int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt, - eeprom_chassis_ia_t *ia ) -{ - char eep_record[512]; /* scratch area for building up info area */ - char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ - int checksum = 0; /* use to verify eeprom record checksum */ - int i; - - /* Read in info area record from the L1. - */ - if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record ) - != EEP_OK ) - { - return EEP_L1; - } - - /* Now we've got the whole info area. Transfer it to the data structure. - */ - - eep_rec_p = eep_record; - ia->format = *eep_rec_p++; - ia->length = *eep_rec_p++; - if( ia->length == 0 ) { - /* since we're using 8*ia->length-1 as an array index later, make - * sure it's sane. - */ - db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" )); - return EEP_L1; - } - ia->type = *eep_rec_p++; - - ia->part_num_tl = *eep_rec_p++; - - (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); - - ia->serial_num_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->serial_num, - (ia->serial_num_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); - - ia->checksum = eep_record[(8 * ia->length) - 1]; - - /* verify checksum */ - eep_rec_p = eep_record; - checksum = 0; - for( i = 0; i < (8 * ia->length); i++ ) { - checksum += *eep_rec_p++; - } - - if( (checksum & 0xff) != 0 ) - { - db_printf(( "read_chassis_ia: bad checksum\n" )); - db_printf(( "read_chassis_ia: target 0x%x uart 0x%lx\n", - sc->subch[subch].target, sc->uart )); - return EEP_BAD_CHECKSUM; - } - - return EEP_OK; -} - - -int read_board_ia( l1sc_t *sc, int subch, int l1_compt, - eeprom_board_ia_t *ia ) -{ - char eep_record[512]; /* scratch area for building up info area */ - char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ - int checksum = 0; /* running checksum total */ - int i; - - BZERO( ia, sizeof( eeprom_board_ia_t ) ); - - /* Read in info area record from the L1. - */ - if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record ) - != EEP_OK ) - { - db_printf(( "read_board_ia: error reading info area from L1\n" )); - return EEP_L1; - } - - /* Now we've got the whole info area. Transfer it to the data structure. - */ - - eep_rec_p = eep_record; - ia->format = *eep_rec_p++; - ia->length = *eep_rec_p++; - if( ia->length == 0 ) { - /* since we're using 8*ia->length-1 as an array index later, make - * sure it's sane. - */ - db_printf(( "read_board_ia: eeprom length byte of ZERO\n" )); - return EEP_L1; - } - ia->language = *eep_rec_p++; - - ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p ); - eep_rec_p += 3; - - ia->manuf_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK); - - ia->product_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK); - - ia->serial_num_tl = *eep_rec_p++; - - BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK)); - eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); - - ia->part_num_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); - - eep_rec_p++; /* we do not use the FRU file id */ - - ia->board_rev_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK); - - ia->eeprom_size_tl = *eep_rec_p++; - ia->eeprom_size = *eep_rec_p++; - - ia->temp_waiver_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->temp_waiver, - (ia->temp_waiver_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK); - - /* if there's more, we must be reading a main board; get - * additional fields - */ - if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { - - ia->ekey_G_tl = *eep_rec_p++; - BCOPY( eep_rec_p, (char *)&ia->ekey_G, - ia->ekey_G_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK); - - ia->ekey_P_tl = *eep_rec_p++; - BCOPY( eep_rec_p, (char *)&ia->ekey_P, - ia->ekey_P_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK); - - ia->ekey_Y_tl = *eep_rec_p++; - BCOPY( eep_rec_p, (char *)&ia->ekey_Y, - ia->ekey_Y_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK); - - /* - * need to get a couple more fields if this is an I brick - */ - if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { - - ia->mac_addr_tl = *eep_rec_p++; - BCOPY( eep_rec_p, ia->mac_addr, - ia->mac_addr_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK); - - ia->ieee1394_cfg_tl = *eep_rec_p++; - BCOPY( eep_rec_p, ia->ieee1394_cfg, - ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK ); - - } - } - - ia->checksum = eep_record[(ia->length * 8) - 1]; - - /* verify checksum */ - eep_rec_p = eep_record; - checksum = 0; - for( i = 0; i < (8 * ia->length); i++ ) { - checksum += *eep_rec_p++; - } - - if( (checksum & 0xff) != 0 ) - { - db_printf(( "read_board_ia: bad checksum\n" )); - db_printf(( "read_board_ia: target 0x%x uart 0x%lx\n", - sc->subch[subch].target, sc->uart )); - return EEP_BAD_CHECKSUM; - } - - return EEP_OK; -} - - -int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp, - int component ) -{ - int r; - uint64_t uid = 0; -#ifdef LOG_GETENV - char uid_str[32]; -#endif - int l1_compt, subch; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* make sure we're targeting a cbrick */ - if( !(component & C_BRICK) ) - return EEP_PARAM; - - /* If the promlog variable pointed to by IP27LOG_OVNIC is set, - * use that value for the cbrick UID rather than the EEPROM - * serial number. - */ -#ifdef LOG_GETENV - if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 ) - { - db_printf(( "_cbrick_eeprom_read: " - "Overriding UID with environment variable %s\n", - IP27LOG_OVNIC )); - uid = strtoull( uid_str, NULL, 0 ); - } -#endif - - if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 ) - return EEP_L1; - - if((component & C_DIMM) == C_DIMM) { - l1_compt = L1_EEP_DIMM(component & COMPT_MASK); - r = read_spd(scp,subch,l1_compt, buf->spd); - sc_close(scp,subch); - return(r); - } - - switch( component ) - { - case C_BRICK: - /* c-brick motherboard */ - l1_compt = L1_EEP_NODE; - r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); - if( r != EEP_OK ) { - sc_close( scp, subch ); - db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); - return fake_an_eeprom_record( buf, component, uid ); - } - if( uid ) { - /* If IP27LOG_OVNIC is set, we want to put that value - * in as our UID. */ - fake_a_serial_number( buf->chassis_ia->serial_num, uid ); - buf->chassis_ia->serial_num_tl = 6; - } - break; - - case C_PIMM: - /* one of the PIMM boards */ - l1_compt = L1_EEP_PIMM( component & COMPT_MASK ); - break; - - default: - /* unsupported board type */ - sc_close( scp, subch ); - return EEP_PARAM; - } - - r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); - sc_close( scp, subch ); - if( r != EEP_OK ) - { - db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); - return fake_an_eeprom_record( buf, component, uid ); - } - return EEP_OK; -} - - -int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, - int component ) -{ - l1sc_t *scp; - int local = (nasid == get_nasid()); - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* If this brick is retrieving its own uid, use the local l1sc_t to - * arbitrate access to the l1; otherwise, set up a new one (prom) or - * use an existing remote l1sc_t (kernel) - */ - if( local ) { - scp = get_l1sc(); - } - else { - scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc; - } - - return _cbrick_eeprom_read( buf, scp, component ); -} - - -int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, - int component ) -{ - int r; - int l1_compt, subch; - l1sc_t *scp; - int local = (nasid == get_nasid()); - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* make sure we're talking to an applicable brick */ - if( !(component & IO_BRICK) ) { - return EEP_PARAM; - } - - /* If we're talking to this c-brick's attached io brick, use - * the local l1sc_t; otherwise, set up a new one (prom) or - * use an existing remote l1sc_t (kernel) - */ - if( local ) { - scp = get_l1sc(); - } - else { - scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc; - } - - if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 ) - return EEP_L1; - - - switch( component ) - { - case IO_BRICK: - /* IO brick motherboard */ - l1_compt = L1_EEP_LOGIC; - r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); - - if( r != EEP_OK ) { - sc_close( scp, subch ); - /* - * Whenever we no longer need to test on hardware - * that does not have EEPROMS, then this can be removed. - */ - r = fake_an_eeprom_record( buf, component, rtc_time() ); - return r; - } - break; - - case IO_POWER: - /* IO brick power board */ - l1_compt = L1_EEP_POWER; - break; - - default: - /* unsupported board type */ - sc_close( scp, subch ); - return EEP_PARAM; - } - - r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); - sc_close( scp, subch ); - if( r != EEP_OK ) { - return r; - } - return EEP_OK; -} - - -int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, - net_vec_t path, int component ) -{ - int r; - uint64_t uid = 0; - int l1_compt, subch; - l1sc_t sc; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* make sure we're targeting an applicable brick */ - if( !(component & VECTOR) ) - return EEP_PARAM; - - switch( component & BRICK_MASK ) - { - case R_BRICK: - ROUTER_LOCK( path ); - sc_init( &sc, nasid, path ); - - if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) - { - db_printf(( "vector_eeprom_read: couldn't open subch\n" )); - ROUTER_UNLOCK(path); - return EEP_L1; - } - switch( component ) - { - case R_BRICK: - /* r-brick motherboard */ - l1_compt = L1_EEP_LOGIC; - r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia ); - if( r != EEP_OK ) { - sc_close( &sc, subch ); - ROUTER_UNLOCK( path ); - printk( "vector_eeprom_read: couldn't get rbrick eeprom info;" - " using current time as uid\n" ); - uid = rtc_time(); - db_printf(("vector_eeprom_read: using a fake eeprom record\n")); - return fake_an_eeprom_record( buf, component, uid ); - } - break; - - case R_POWER: - /* r-brick power board */ - l1_compt = L1_EEP_POWER; - break; - - default: - /* unsupported board type */ - sc_close( &sc, subch ); - ROUTER_UNLOCK( path ); - return EEP_PARAM; - } - r = read_board_ia( &sc, subch, l1_compt, buf->board_ia ); - sc_close( &sc, subch ); - ROUTER_UNLOCK( path ); - if( r != EEP_OK ) { - db_printf(( "vector_eeprom_read: using a fake eeprom record\n" )); - return fake_an_eeprom_record( buf, component, uid ); - } - return EEP_OK; - - case C_BRICK: - sc_init( &sc, nasid, path ); - return _cbrick_eeprom_read( buf, &sc, component ); - - default: - /* unsupported brick type */ - return EEP_PARAM; - } -} diff -urN linux-2.4.21/arch/ia64/sn/io/efi-rtc.c linux-2.4.22/arch/ia64/sn/io/efi-rtc.c --- linux-2.4.21/arch/ia64/sn/io/efi-rtc.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/efi-rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,185 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 Silicon Graphics, Inc. - * Copyright (C) 2001 by Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * No locking necessary when this is called from efirtc which protects us - * from racing by efi_rtc_lock. - */ -#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3)) -#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr)) -#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data)) - -#define TOD_SGS_M48T35 1 -#define TOD_DALLAS_DS1386 2 - -static unsigned long nvram_base = 0; -static int tod_chip_type; - -static int -get_tod_chip_type(void) -{ - unsigned char testval; - - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - write_io_port(RTC_DAL_DAY_ADDR, 0xff); - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - - testval = read_io_port(RTC_DAL_DAY_ADDR); - if (testval == 0xff) - return TOD_SGS_M48T35; - - return TOD_DALLAS_DS1386; -} - -efi_status_t -ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps) -{ - if (!nvram_base) { - printk(KERN_CRIT "nvram_base is zero\n"); - return EFI_UNSUPPORTED; - } - - memset(time, 0, sizeof(*time)); - - switch (tod_chip_type) { - case TOD_SGS_M48T35: - write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT); - - time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF; - time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR)); - time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR)); - time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR)); - time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR)); - time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR)); - time->nanosecond = 0; - - write_io_port(RTC_SGS_CONTROL_ADDR, 0); - break; - - case TOD_DALLAS_DS1386: - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - - time->nanosecond = 0; - time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR)); - time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR)); - time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR)); - time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR)); - time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR)); - time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF; - - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - break; - - default: - break; - } - - if (caps) { - caps->resolution = 50000000; /* 50PPM */ - caps->accuracy = 1000; /* 1ms */ - caps->sets_to_zero = 0; - } - - return EFI_SUCCESS; -} - -static efi_status_t ioc3_set_time (efi_time_t *t) -{ - if (!nvram_base) { - printk(KERN_CRIT "nvram_base is zero\n"); - return EFI_UNSUPPORTED; - } - - switch (tod_chip_type) { - case TOD_SGS_M48T35: - write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE); - write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF))); - write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month)); - write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day)); - write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour)); - write_io_port(RTC_SGS_MIN_ADDR, INT_TO_BCD(t->minute)); - write_io_port(RTC_SGS_SEC_ADDR, INT_TO_BCD(t->second)); - write_io_port(RTC_SGS_CONTROL_ADDR, 0); - break; - - case TOD_DALLAS_DS1386: - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - write_io_port(RTC_DAL_SEC_ADDR, INT_TO_BCD(t->second)); - write_io_port(RTC_DAL_MIN_ADDR, INT_TO_BCD(t->minute)); - write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour)); - write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day)); - write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month)); - write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF))); - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - break; - - default: - break; - } - - return EFI_SUCCESS; -} - -/* The following two are not supported atm. */ -static efi_status_t -ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm) -{ - return EFI_UNSUPPORTED; -} - -static efi_status_t -ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm) -{ - return EFI_UNSUPPORTED; -} - -/* - * It looks like the master IOC3 is usually on bus 0, device 4. Hope - * that's right - */ -static __init int efi_ioc3_time_init(void) -{ - struct pci_dev *dev; - static struct ioc3 *ioc3; - - dev = pci_find_slot(0, PCI_DEVFN(4, 0)); - if (!dev) { - printk(KERN_CRIT "Couldn't find master IOC3\n"); - - return -ENODEV; - } - - ioc3 = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0)); - nvram_base = (unsigned long) ioc3 + IOC3_BYTEBUS_DEV0; - - tod_chip_type = get_tod_chip_type(); - if (tod_chip_type == 1) - printk(KERN_NOTICE "TOD type is SGS M48T35\n"); - else if (tod_chip_type == 2) - printk(KERN_NOTICE "TOD type is Dallas DS1386\n"); - else - printk(KERN_CRIT "No or unknown TOD\n"); - - efi.get_time = ioc3_get_time; - efi.set_time = ioc3_set_time; - efi.get_wakeup_time = ioc3_get_wakeup_time; - efi.set_wakeup_time = ioc3_set_wakeup_time; - - return 0; -} - -module_init(efi_ioc3_time_init); diff -urN linux-2.4.21/arch/ia64/sn/io/hcl.c linux-2.4.22/arch/ia64/sn/io/hcl.c --- linux-2.4.21/arch/ia64/sn/io/hcl.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/hcl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1531 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * hcl - SGI's Hardware Graph compatibility layer. - * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER" -#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE" -#define HCL_TEMP_NAME_LEN 44 -#define HCL_VERSION "1.0" -devfs_handle_t hwgraph_root = NULL; -devfs_handle_t linux_busnum = NULL; - -/* - * Debug flag definition. - */ -#define OPTION_NONE 0x00 -#define HCL_DEBUG_NONE 0x00000 -#define HCL_DEBUG_ALL 0x0ffff -#if defined(CONFIG_HCL_DEBUG) -static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE; -#endif -static unsigned int hcl_debug = HCL_DEBUG_NONE; -#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE) -static unsigned int boot_options = OPTION_NONE; -#endif - -/* - * Some Global definitions. - */ -devfs_handle_t hcl_handle = NULL; - -invplace_t invplace_none = { - GRAPH_VERTEX_NONE, - GRAPH_VERTEX_PLACE_NONE, - NULL -}; - -/* - * HCL device driver. - * The purpose of this device driver is to provide a facility - * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path - * to manipulate label entries without having to implement - * system call interfaces. This methodology will enable us to - * make this feature module loadable. - */ -static int hcl_open(struct inode * inode, struct file * filp) -{ - if (hcl_debug) { - printk("HCL: hcl_open called.\n"); - } - - return(0); - -} - -static int hcl_close(struct inode * inode, struct file * filp) -{ - - if (hcl_debug) { - printk("HCL: hcl_close called.\n"); - } - - return(0); - -} - -static int hcl_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - - if (hcl_debug) { - printk("HCL: hcl_ioctl called.\n"); - } - - switch (cmd) { - default: - if (hcl_debug) { - printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd); - } - } - - return(0); - -} - -struct file_operations hcl_fops = { - (struct module *)0, - NULL, /* lseek - default */ - NULL, /* read - general block-dev read */ - NULL, /* write - general block-dev write */ - NULL, /* readdir - bad */ - NULL, /* poll */ - hcl_ioctl, /* ioctl */ - NULL, /* mmap */ - hcl_open, /* open */ - NULL, /* flush */ - hcl_close, /* release */ - NULL, /* fsync */ - NULL, /* fasync */ - NULL, /* lock */ - NULL, /* readv */ - NULL, /* writev */ -}; - - -/* - * init_hcl() - Boot time initialization. Ensure that it is called - * after devfs has been initialized. - * - * For now this routine is being called out of devfs/base.c. Actually - * Not a bad place to be .. - * - */ -#ifdef MODULE -int init_module (void) -#else -int __init init_hcl(void) -#endif -{ - extern void string_table_init(struct string_table *); - extern struct string_table label_string_table; - extern int init_ifconfig_net(void); - int rv = 0; - -#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE) - printk ("\n%s: v%s Colin Ngam (cngam@sgi.com)\n", - HCL_NAME, HCL_VERSION); - - hcl_debug = hcl_debug_init; - printk ("%s: hcl_debug: 0x%0x\n", HCL_NAME, hcl_debug); - printk ("\n%s: boot_options: 0x%0x\n", HCL_NAME, boot_options); -#endif - - /* - * Create the hwgraph_root on devfs. - */ - rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root); - if (rv) - printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv); - - /* - * Create the hcl driver to support inventory entry manipulations. - * By default, it is expected that devfs is mounted on /dev. - * - */ - hcl_handle = hwgraph_register(hwgraph_root, ".hcl", - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &hcl_fops, NULL); - - if (hcl_handle == NULL) { - panic("HCL: Unable to create HCL Driver in init_hcl().\n"); - return(0); - } - - /* - * Initialize the HCL string table. - */ - string_table_init(&label_string_table); - - /* - * Create the directory that links Linux bus numbers to our Xwidget. - */ - rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum); - if (linux_busnum == NULL) { - panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS); - return(0); - } - - /* - * Initialize the ifconfgi_net driver that does network devices - * Persistent Naming. - */ - init_ifconfig_net(); - - return(0); - -} - - -/* - * hcl_setup() - Process boot time parameters if given. - * "hcl=" - * This routine gets called only if "hcl=" is given in the - * boot line and before init_hcl(). - * - * We currently do not have any boot options .. when we do, - * functionalities can be added here. - * - */ -static int __init hcl_setup(char *str) -{ - while ( (*str != '\0') && !isspace (*str) ) - { -#ifdef CONFIG_HCL_DEBUG - if (strncmp (str, "all", 3) == 0) { - hcl_debug_init |= HCL_DEBUG_ALL; - str += 3; - } else - return 0; -#endif - if (*str != ',') return 0; - ++str; - } - - return 1; - -} - -__setup("hcl=", hcl_setup); - - -/* - * Set device specific "fast information". - * - */ -void -hwgraph_fastinfo_set(devfs_handle_t de, arbitrary_info_t fastinfo) -{ - - if (hcl_debug) { - printk("HCL: hwgraph_fastinfo_set handle 0x%p fastinfo %ld\n", (void *)de, fastinfo); - } - - labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL); - -} - - -/* - * Get device specific "fast information". - * - */ -arbitrary_info_t -hwgraph_fastinfo_get(devfs_handle_t de) -{ - arbitrary_info_t fastinfo; - int rv; - - if (!de) { - printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n"); - return(-1); - } - - rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo); - if (rv == 0) - return(fastinfo); - - return(0); -} - - -/* - * hwgraph_connectpt_set - Sets the connect point handle in de to the - * given connect_de handle. By default, the connect point of the - * devfs node is the parent. This effectively changes this assumption. - */ -int -hwgraph_connectpt_set(devfs_handle_t de, devfs_handle_t connect_de) -{ - int rv; - - if (!de) - return(-1); - - rv = labelcl_info_connectpt_set(de, connect_de); - - return(rv); -} - - -/* - * hwgraph_connectpt_get: Returns the entry's connect point in the devfs - * tree. - */ -devfs_handle_t -hwgraph_connectpt_get(devfs_handle_t de) -{ - int rv; - arbitrary_info_t info; - devfs_handle_t connect; - - rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); - if (rv != 0) { - return(NULL); - } - - connect = (devfs_handle_t)info; - return(connect); - -} - - -/* - * hwgraph_mk_dir - Creates a directory entry with devfs. - * Note that a directory entry in devfs can have children - * but it cannot be a char|block special file. - */ -devfs_handle_t -hwgraph_mk_dir(devfs_handle_t de, const char *name, - unsigned int namelen, void *info) -{ - - int rv; - labelcl_info_t *labelcl_info = NULL; - devfs_handle_t new_devfs_handle = NULL; - devfs_handle_t parent = NULL; - - /* - * Create the device info structure for hwgraph compatiblity support. - */ - labelcl_info = labelcl_info_create(); - if (!labelcl_info) - return(NULL); - - /* - * Create a devfs entry. - */ - new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info); - if (!new_devfs_handle) { - labelcl_info_destroy(labelcl_info); - return(NULL); - } - - /* - * Get the parent handle. - */ - parent = devfs_get_parent (new_devfs_handle); - - /* - * To provide the same semantics as the hwgraph, set the connect point. - */ - rv = hwgraph_connectpt_set(new_devfs_handle, parent); - if (!rv) { - /* - * We need to clean up! - */ - } - - /* - * If the caller provides a private data pointer, save it in the - * labelcl info structure(fastinfo). This can be retrieved via - * hwgraph_fastinfo_get() - */ - if (info) - hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); - - return(new_devfs_handle); - -} - -/* - * hwgraph_vertex_create - Create a vertex by giving it a temp name. - */ - -/* - * hwgraph_path_add - Create a directory node with the given path starting - * from the given devfs_handle_t. - */ -extern char * dev_to_name(devfs_handle_t, char *, uint); -int -hwgraph_path_add(devfs_handle_t fromv, - char *path, - devfs_handle_t *new_de) -{ - - unsigned int namelen = strlen(path); - int rv; - - /* - * We need to handle the case when fromv is NULL .. - * in this case we need to create the path from the - * hwgraph root! - */ - if (fromv == NULL) - fromv = hwgraph_root; - - /* - * check the entry doesn't already exist, if it does - * then we simply want new_de to point to it (otherwise - * we'll overwrite the existing labelcl_info struct) - */ - rv = hwgraph_edge_get(fromv, path, new_de); - if (rv) { /* couldn't find entry so we create it */ - *new_de = hwgraph_mk_dir(fromv, path, namelen, NULL); - if (new_de == NULL) - return(-1); - else - return(0); - } - else - return(0); - -} - -/* - * hwgraph_register - Creates a file entry with devfs. - * Note that a file entry cannot have children .. it is like a - * char|block special vertex in hwgraph. - */ -devfs_handle_t -hwgraph_register(devfs_handle_t de, const char *name, - unsigned int namelen, unsigned int flags, - unsigned int major, unsigned int minor, - umode_t mode, uid_t uid, gid_t gid, - struct file_operations *fops, - void *info) -{ - - int rv; - void *labelcl_info = NULL; - devfs_handle_t new_devfs_handle = NULL; - devfs_handle_t parent = NULL; - - /* - * Create the labelcl info structure for hwgraph compatiblity support. - */ - labelcl_info = labelcl_info_create(); - if (!labelcl_info) - return(NULL); - - /* - * Create a devfs entry. - */ - new_devfs_handle = devfs_register(de, name, flags, major, - minor, mode, fops, labelcl_info); - if (!new_devfs_handle) { - labelcl_info_destroy((labelcl_info_t *)labelcl_info); - return(NULL); - } - - /* - * Get the parent handle. - */ - if (de == NULL) - parent = devfs_get_parent (new_devfs_handle); - else - parent = de; - - /* - * To provide the same semantics as the hwgraph, set the connect point. - */ - rv = hwgraph_connectpt_set(new_devfs_handle, parent); - if (rv) { - /* - * We need to clean up! - */ - printk(KERN_WARNING "HCL: Unable to set the connect point to it's parent 0x%p\n", - (void *)new_devfs_handle); - } - - /* - * If the caller provides a private data pointer, save it in the - * labelcl info structure(fastinfo). This can be retrieved via - * hwgraph_fastinfo_get() - */ - if (info) - hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); - - return(new_devfs_handle); - -} - - -/* - * hwgraph_mk_symlink - Create a symbolic link. - */ -int -hwgraph_mk_symlink(devfs_handle_t de, const char *name, unsigned int namelen, - unsigned int flags, const char *link, unsigned int linklen, - devfs_handle_t *handle, void *info) -{ - - void *labelcl_info = NULL; - int status = 0; - devfs_handle_t new_devfs_handle = NULL; - - /* - * Create the labelcl info structure for hwgraph compatiblity support. - */ - labelcl_info = labelcl_info_create(); - if (!labelcl_info) - return(-1); - - /* - * Create a symbolic link devfs entry. - */ - status = devfs_mk_symlink(de, name, flags, link, - &new_devfs_handle, labelcl_info); - if ( (!new_devfs_handle) || (!status) ){ - labelcl_info_destroy((labelcl_info_t *)labelcl_info); - return(-1); - } - - /* - * If the caller provides a private data pointer, save it in the - * labelcl info structure(fastinfo). This can be retrieved via - * hwgraph_fastinfo_get() - */ - if (info) - hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); - - *handle = new_devfs_handle; - return(0); - -} - -/* - * hwgraph_vertex_get_next - this routine returns the next sibbling for the - * device entry given in de. If there are no more sibbling, NULL - * is returned in next_sibbling. - * - * Currently we do not have any protection against de being deleted - * while it's handle is being held. - */ -int -hwgraph_vertex_get_next(devfs_handle_t *next_sibbling, devfs_handle_t *de) -{ - *next_sibbling = devfs_get_next_sibling (*de); - - if (*next_sibbling != NULL) - *de = *next_sibbling; - return (0); -} - - -/* - * hwgraph_vertex_destroy - Destroy the devfs entry - */ -int -hwgraph_vertex_destroy(devfs_handle_t de) -{ - - void *labelcl_info = NULL; - - labelcl_info = devfs_get_info(de); - devfs_unregister(de); - - if (labelcl_info) - labelcl_info_destroy((labelcl_info_t *)labelcl_info); - - return(0); -} - -/* -** See if a vertex has an outgoing edge with a specified name. -** Vertices in the hwgraph *implicitly* contain these edges: -** "." refers to "current vertex" -** ".." refers to "connect point vertex" -** "char" refers to current vertex (character device access) -** "block" refers to current vertex (block device access) -*/ - -/* - * hwgraph_edge_add - This routines has changed from the original conext. - * All it does now is to create a symbolic link from "from" to "to". - */ -/* ARGSUSED */ -int -hwgraph_edge_add(devfs_handle_t from, devfs_handle_t to, char *name) -{ - - char *path; - char *s1; - char *index; - int name_start; - devfs_handle_t handle = NULL; - int rv; - int i, count; - - path = kmalloc(1024, GFP_KERNEL); - memset(path, 0x0, 1024); - name_start = devfs_generate_path (from, path, 1024); - s1 = &path[name_start]; - count = 0; - while (1) { - index = strstr (s1, "/"); - if (index) { - count++; - s1 = ++index; - } else { - count++; - break; - } - } - - memset(path, 0x0, 1024); - name_start = devfs_generate_path (to, path, 1024); - - for (i = 0; i < count; i++) { - strcat(path,"../"); - } - - strcat(path, &path[name_start]); - - /* - * Otherwise, just create a symlink to the vertex. - * In this case the vertex was previous created with a REAL pathname. - */ - rv = devfs_mk_symlink (from, (const char *)name, - DEVFS_FL_DEFAULT, path, - &handle, NULL); - - name_start = devfs_generate_path (handle, path, 1024); - return(rv); - - -} -/* ARGSUSED */ -int -hwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr) -{ - - int namelen = 0; - devfs_handle_t target_handle = NULL; - - if (name == NULL) - return(-1); - - if (toptr == NULL) - return(-1); - - /* - * If the name is "." just return the current devfs entry handle. - */ - if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) { - if (toptr) { - *toptr = from; - } - } else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) { - /* - * Hmmm .. should we return the connect point or parent .. - * see in hwgraph, the concept of parent is the connectpt! - * - * Maybe we should see whether the connectpt is set .. if - * not just return the parent! - */ - target_handle = hwgraph_connectpt_get(from); - if (target_handle) { - /* - * Just return the connect point. - */ - *toptr = target_handle; - return(0); - } - target_handle = devfs_get_parent(from); - *toptr = target_handle; - - } else { - /* - * Call devfs to get the devfs entry. - */ - namelen = (int) strlen(name); - target_handle = devfs_find_handle (from, name, 0, 0, - 0, 1); /* Yes traverse symbolic links */ - if (target_handle == NULL) - return(-1); - else - *toptr = target_handle; - } - - return(0); -} - - -/* - * hwgraph_edge_get_next - Retrieves the next sibbling given the current - * entry number "placeptr". - * - * Allow the caller to retrieve walk through the sibblings of "source" - * devfs_handle_t. The implicit edges "." and ".." is returned first - * followed by each of the real children. - * - * We may end up returning garbage if another thread perform any deletion - * in this directory before "placeptr". - * - */ -/* ARGSUSED */ -int -hwgraph_edge_get_next(devfs_handle_t source, char *name, devfs_handle_t *target, - uint *placeptr) - -{ - - uint which_place; - unsigned int namelen = 0; - const char *tempname = NULL; - - if (placeptr == NULL) - return(-1); - - which_place = *placeptr; - -again: - if (which_place <= HWGRAPH_RESERVED_PLACES) { - if (which_place == EDGE_PLACE_WANT_CURRENT) { - /* - * Looking for "." - * Return the current devfs handle. - */ - if (name != NULL) - strcpy(name, HWGRAPH_EDGELBL_DOT); - - if (target != NULL) { - *target = source; - /* XXX should incr "source" ref count here if we - * ever implement ref counts */ - } - - } else if (which_place == EDGE_PLACE_WANT_CONNECTPT) { - /* - * Looking for the connect point or parent. - * If the connect point is set .. it returns the connect point. - * Otherwise, it returns the parent .. will we support - * connect point? - */ - devfs_handle_t connect_point = hwgraph_connectpt_get(source); - - if (connect_point == NULL) { - /* - * No connectpoint set .. either the User - * explicitly NULL it or this node was not - * created via hcl. - */ - which_place++; - goto again; - } - - if (name != NULL) - strcpy(name, HWGRAPH_EDGELBL_DOTDOT); - - if (target != NULL) - *target = connect_point; - - } else if (which_place == EDGE_PLACE_WANT_REAL_EDGES) { - /* - * return first "real" entry in directory, and increment - * placeptr. Next time around we should have - * which_place > HWGRAPH_RESERVED_EDGES so we'll fall through - * this nested if block. - */ - *target = devfs_get_first_child(source); - if (*target && name) { - tempname = devfs_get_name(*target, &namelen); - if (tempname && namelen) - strcpy(name, tempname); - } - - *placeptr = which_place + 1; - return (0); - } - - *placeptr = which_place+1; - return(0); - } - - /* - * walk linked list, (which_place - HWGRAPH_RESERVED_PLACES) times - */ - { - devfs_handle_t curr; - int i = 0; - - for (curr=devfs_get_first_child(source), i= i+HWGRAPH_RESERVED_PLACES; - curr!=NULL && iinv_next) { - if ((int)class != -1 && old_pinv->inv_class != class) - continue; - if ((int)type != -1 && old_pinv->inv_type != type) - continue; - if ((int)state != -1 && old_pinv->inv_state != state) - continue; - if ((int)controller != -1 - && old_pinv->inv_controller != controller) - continue; - if ((int)unit != -1 && old_pinv->inv_unit != unit) - continue; - - /* exact duplicate of previously-added inventory item */ - rv = LABELCL_DUP; - goto failure; - } - - /* Not a duplicate, so we know that we need to add something. */ - if (pinv == NULL) { - /* Release lock while we wait for memory. */ - /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ - pinv = (inventory_t *)kmalloc(sizeof(inventory_t), GFP_KERNEL); - replace_in_inventory(pinv, class, type, controller, unit, state); - goto again; - } - - pinv->inv_next = NULL; - if (last_pinv) { - last_pinv->inv_next = pinv; - } else { - rv = labelcl_info_add_LBL(de, INFO_LBL_INVENT, - sizeof(inventory_t), (arbitrary_info_t)pinv); - - if (!rv) - goto failure; - } - - /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ - return(0); - -failure: - /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ - if (pinv) - kfree(pinv); - return(rv); -} - - -/* - * hwgraph_inventory_remove - Removes an inventory entry. - * - * Remove an inventory item associated with a vertex. It is the caller's - * responsibility to make sure that there are no races between removing - * inventory from a vertex and simultaneously removing that vertex. -*/ -int -hwgraph_inventory_remove( devfs_handle_t de, - int class, - int type, - major_t controller, - minor_t unit, - int state) -{ - inventory_t *pinv = NULL, *last_pinv = NULL, *next_pinv = NULL; - labelcl_error_t rv; - - /* - * We never remove stuff from ".invent" .. - */ - if (!de) - return (-1); - - /* - * Remove our inventory data to the list of inventory data - * associated with this vertex. - */ - /* GRAPH_LOCK_UPDATE(&invent_lock); */ - rv = labelcl_info_get_LBL(de, - INFO_LBL_INVENT, - NULL, (arbitrary_info_t *)&pinv); - if (rv != LABELCL_SUCCESS) - goto failure; - - /* - * Search through inventory items associated with this - * vertex, looking for a match. - */ - for (;pinv; pinv = next_pinv) { - next_pinv = pinv->inv_next; - - if(((int)class == -1 || pinv->inv_class == class) && - ((int)type == -1 || pinv->inv_type == type) && - ((int)state == -1 || pinv->inv_state == state) && - ((int)controller == -1 || pinv->inv_controller == controller) && - ((int)unit == -1 || pinv->inv_unit == unit)) { - - /* Found a matching inventory item. Remove it. */ - if (last_pinv) { - last_pinv->inv_next = pinv->inv_next; - } else { - rv = hwgraph_info_replace_LBL(de, INFO_LBL_INVENT, (arbitrary_info_t)pinv->inv_next, NULL); - if (rv != LABELCL_SUCCESS) - goto failure; - } - - pinv->inv_next = NULL; /* sanity */ - kfree(pinv); - } else - last_pinv = pinv; - } - - if (last_pinv == NULL) { - rv = hwgraph_info_remove_LBL(de, INFO_LBL_INVENT, NULL); - if (rv != LABELCL_SUCCESS) - goto failure; - } - - rv = LABELCL_SUCCESS; - -failure: - /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ - return(rv); -} - -/* - * hwgraph_inventory_get_next - Get next inventory item associated with the - * specified vertex. - * - * No locking is really needed. We don't yet have the ability - * to remove inventory items, and new items are always added to - * the end of a vertex' inventory list. - * - * However, a devfs entry can be removed! -*/ -int -hwgraph_inventory_get_next(devfs_handle_t de, invplace_t *place, inventory_t **ppinv) -{ - inventory_t *pinv; - labelcl_error_t rv; - - if (de == NULL) - return(LABELCL_BAD_PARAM); - - if (place->invplace_vhdl == NULL) { - place->invplace_vhdl = de; - place->invplace_inv = NULL; - } - - if (de != place->invplace_vhdl) - return(LABELCL_BAD_PARAM); - - if (place->invplace_inv == NULL) { - /* Just starting on this vertex */ - rv = labelcl_info_get_LBL(de, INFO_LBL_INVENT, - NULL, (arbitrary_info_t *)&pinv); - if (rv != LABELCL_SUCCESS) - return(LABELCL_NOT_FOUND); - - } else { - /* Advance to next item on this vertex */ - pinv = place->invplace_inv->inv_next; - } - place->invplace_inv = pinv; - *ppinv = pinv; - - return(LABELCL_SUCCESS); -} - -/* - * hwgraph_controller_num_get - Returns the controller number in the inventory - * entry. - */ -int -hwgraph_controller_num_get(devfs_handle_t device) -{ - inventory_t *pinv; - invplace_t invplace = { NULL, NULL, NULL }; - int val = -1; - if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) { - val = (pinv->inv_class == INV_NETWORK)? pinv->inv_unit: pinv->inv_controller; - } -#ifdef DEBUG - /* - * It does not make any sense to call this on vertexes with multiple - * inventory structs chained together - */ - if ( device_inventory_get_next(device, &invplace) != NULL ) { - printk("Should panic here ... !\n"); -#endif - return (val); -} - -/* - * hwgraph_controller_num_set - Sets the controller number in the inventory - * entry. - */ -void -hwgraph_controller_num_set(devfs_handle_t device, int contr_num) -{ - inventory_t *pinv; - invplace_t invplace = { NULL, NULL, NULL }; - if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) { - if (pinv->inv_class == INV_NETWORK) - pinv->inv_unit = contr_num; - else { - if (pinv->inv_class == INV_FCNODE) - pinv = device_inventory_get_next(device, &invplace); - if (pinv != NULL) - pinv->inv_controller = contr_num; - } - } -#ifdef DEBUG - /* - * It does not make any sense to call this on vertexes with multiple - * inventory structs chained together - */ - if(pinv != NULL) - ASSERT(device_inventory_get_next(device, &invplace) == NULL); -#endif -} - -/* - * Find the canonical name for a given vertex by walking back through - * connectpt's until we hit the hwgraph root vertex (or until we run - * out of buffer space or until something goes wrong). - * - * COMPATIBILITY FUNCTIONALITY - * Walks back through 'parents', not necessarily the same as connectpts. - * - * Need to resolve the fact that devfs does not return the path from - * "/" but rather it just stops right before /dev .. - */ -int -hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen) -{ - char *locbuf; - int pos; - - if (buflen < 1) - return(-1); /* XXX should be GRAPH_BAD_PARAM ? */ - - locbuf = kmalloc(buflen, GFP_KERNEL); - - pos = devfs_generate_path(vhdl, locbuf, buflen); - if (pos < 0) { - kfree(locbuf); - return pos; - } - - strcpy(buf, &locbuf[pos]); - kfree(locbuf); - return 0; -} - -/* -** vertex_to_name converts a vertex into a canonical name by walking -** back through connect points until we hit the hwgraph root (or until -** we run out of buffer space). -** -** Usually returns a pointer to the original buffer, filled in as -** appropriate. If the buffer is too small to hold the entire name, -** or if anything goes wrong while determining the name, vertex_to_name -** returns "UnknownDevice". -*/ - -#define DEVNAME_UNKNOWN "UnknownDevice" - -char * -vertex_to_name(devfs_handle_t vhdl, char *buf, uint buflen) -{ - if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS) - return(buf); - else - return(DEVNAME_UNKNOWN); -} - -#ifdef LATER -/* -** Return the compact node id of the node that ultimately "owns" the specified -** vertex. In order to do this, we walk back through masters and connect points -** until we reach a vertex that represents a node. -*/ -cnodeid_t -master_node_get(devfs_handle_t vhdl) -{ - cnodeid_t cnodeid; - devfs_handle_t master; - - for (;;) { - cnodeid = nodevertex_to_cnodeid(vhdl); - if (cnodeid != CNODEID_NONE) - return(cnodeid); - - master = device_master_get(vhdl); - - /* Check for exceptional cases */ - if (master == vhdl) { - /* Since we got a reference to the "master" thru - * device_master_get() we should decrement - * its reference count by 1 - */ - hwgraph_vertex_unref(master); - return(CNODEID_NONE); - } - - if (master == GRAPH_VERTEX_NONE) { - master = hwgraph_connectpt_get(vhdl); - if ((master == GRAPH_VERTEX_NONE) || - (master == vhdl)) { - if (master == vhdl) - /* Since we got a reference to the - * "master" thru - * hwgraph_connectpt_get() we should - * decrement its reference count by 1 - */ - hwgraph_vertex_unref(master); - return(CNODEID_NONE); - } - } - - vhdl = master; - /* Decrement the reference to "master" which was got - * either thru device_master_get() or hwgraph_connectpt_get() - * above. - */ - hwgraph_vertex_unref(master); - } -} - -/* - * Using the canonical path name to get hold of the desired vertex handle will - * not work on multi-hub sn0 nodes. Hence, we use the following (slightly - * convoluted) algorithm. - * - * - Start at the vertex corresponding to the driver (provided as input parameter) - * - Loop till you reach a vertex which has EDGE_LBL_MEMORY - * - If EDGE_LBL_CONN exists, follow that up. - * else if EDGE_LBL_MASTER exists, follow that up. - * else follow EDGE_LBL_DOTDOT up. - * - * * We should be at desired hub/heart vertex now * - * - Follow EDGE_LBL_CONN to the widget vertex. - * - * - return vertex handle of this widget. - */ -devfs_handle_t -mem_vhdl_get(devfs_handle_t drv_vhdl) -{ -devfs_handle_t cur_vhdl, cur_upper_vhdl; -devfs_handle_t tmp_mem_vhdl, mem_vhdl; -graph_error_t loop_rv; - - /* Initializations */ - cur_vhdl = drv_vhdl; - loop_rv = ~GRAPH_SUCCESS; - - /* Loop till current vertex has EDGE_LBL_MEMORY */ - while (loop_rv != GRAPH_SUCCESS) { - - if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &cur_upper_vhdl)) == GRAPH_SUCCESS) { - - } else if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_MASTER, &cur_upper_vhdl)) == GRAPH_SUCCESS) { - } else { /* Follow HWGRAPH_EDGELBL_DOTDOT up */ - (void) hwgraph_edge_get(cur_vhdl, HWGRAPH_EDGELBL_DOTDOT, &cur_upper_vhdl); - } - - cur_vhdl = cur_upper_vhdl; - -#if DEBUG && HWG_DEBUG - printf("Current vhdl %d \n", cur_vhdl); -#endif /* DEBUG */ - - loop_rv = hwgraph_edge_get(cur_vhdl, EDGE_LBL_MEMORY, &tmp_mem_vhdl); - } - - /* We should be at desired hub/heart vertex now */ - if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &mem_vhdl)) != GRAPH_SUCCESS) - return (GRAPH_VERTEX_NONE); - - return (mem_vhdl); -} -#endif /* LATER */ - - -/* -** Add a char device -- if the driver supports it -- at a specified vertex. -*/ -graph_error_t -hwgraph_char_device_add( devfs_handle_t from, - char *path, - char *prefix, - devfs_handle_t *devhdl) -{ - devfs_handle_t xx = NULL; - - printk("WARNING: hwgraph_char_device_add() not supported .. use hwgraph_register.\n"); - *devhdl = xx; // Must set devhdl - return(GRAPH_SUCCESS); -} - -graph_error_t -hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr) -{ - printk("WARNING: hwgraph_edge_remove NOT supported.\n"); - return(GRAPH_ILLEGAL_REQUEST); -} - -graph_error_t -hwgraph_vertex_unref(devfs_handle_t vhdl) -{ - return(GRAPH_ILLEGAL_REQUEST); -} - - -EXPORT_SYMBOL(hwgraph_mk_dir); -EXPORT_SYMBOL(hwgraph_path_add); -EXPORT_SYMBOL(hwgraph_char_device_add); -EXPORT_SYMBOL(hwgraph_register); -EXPORT_SYMBOL(hwgraph_vertex_destroy); - -EXPORT_SYMBOL(hwgraph_fastinfo_get); -EXPORT_SYMBOL(hwgraph_edge_get); - -EXPORT_SYMBOL(hwgraph_fastinfo_set); -EXPORT_SYMBOL(hwgraph_connectpt_set); -EXPORT_SYMBOL(hwgraph_connectpt_get); -EXPORT_SYMBOL(hwgraph_edge_get_next); -EXPORT_SYMBOL(hwgraph_info_add_LBL); -EXPORT_SYMBOL(hwgraph_info_remove_LBL); -EXPORT_SYMBOL(hwgraph_info_replace_LBL); -EXPORT_SYMBOL(hwgraph_info_get_LBL); -EXPORT_SYMBOL(hwgraph_info_get_exported_LBL); -EXPORT_SYMBOL(hwgraph_info_get_next_LBL); -EXPORT_SYMBOL(hwgraph_info_export_LBL); -EXPORT_SYMBOL(hwgraph_info_unexport_LBL); -EXPORT_SYMBOL(hwgraph_path_lookup); -EXPORT_SYMBOL(hwgraph_traverse); -EXPORT_SYMBOL(hwgraph_path_to_vertex); -EXPORT_SYMBOL(hwgraph_path_to_dev); -EXPORT_SYMBOL(hwgraph_block_device_get); -EXPORT_SYMBOL(hwgraph_char_device_get); -EXPORT_SYMBOL(hwgraph_vertex_name_get); diff -urN linux-2.4.21/arch/ia64/sn/io/hcl_util.c linux-2.4.22/arch/ia64/sn/io/hcl_util.c --- linux-2.4.21/arch/ia64/sn/io/hcl_util.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/hcl_util.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,200 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static devfs_handle_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE; -extern devfs_handle_t hwgraph_root; - - -/* -** Return the "master" for a given vertex. A master vertex is a -** controller or adapter or other piece of hardware that the given -** vertex passes through on the way to the rest of the system. -*/ -devfs_handle_t -device_master_get(devfs_handle_t vhdl) -{ - graph_error_t rc; - devfs_handle_t master; - - rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master); - if (rc == GRAPH_SUCCESS) - return(master); - else - return(GRAPH_VERTEX_NONE); -} - -/* -** Set the master for a given vertex. -** Returns 0 on success, non-0 indicates failure -*/ -int -device_master_set(devfs_handle_t vhdl, devfs_handle_t master) -{ - graph_error_t rc; - - rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER); - return(rc != GRAPH_SUCCESS); -} - - -/* -** Return the compact node id of the node that ultimately "owns" the specified -** vertex. In order to do this, we walk back through masters and connect points -** until we reach a vertex that represents a node. -*/ -cnodeid_t -master_node_get(devfs_handle_t vhdl) -{ - cnodeid_t cnodeid; - devfs_handle_t master; - - for (;;) { - cnodeid = nodevertex_to_cnodeid(vhdl); - if (cnodeid != CNODEID_NONE) - return(cnodeid); - - master = device_master_get(vhdl); - - /* Check for exceptional cases */ - if (master == vhdl) { - /* Since we got a reference to the "master" thru - * device_master_get() we should decrement - * its reference count by 1 - */ - return(CNODEID_NONE); - } - - if (master == GRAPH_VERTEX_NONE) { - master = hwgraph_connectpt_get(vhdl); - if ((master == GRAPH_VERTEX_NONE) || - (master == vhdl)) { - return(CNODEID_NONE); - } - } - - vhdl = master; - } -} - -static devfs_handle_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE; -extern int maxcpus; - -void -mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid) -{ - if (cpuid == CPU_NONE) - return; - - (void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT, - (arbitrary_info_t)cpuid); - { - char cpuid_buffer[10]; - - if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) { - (void)hwgraph_path_add( hwgraph_root, - EDGE_LBL_CPUNUM, - &hwgraph_all_cpuids); - } - - sprintf(cpuid_buffer, "%ld", cpuid); - (void)hwgraph_edge_add( hwgraph_all_cpuids, - vhdl, - cpuid_buffer); - } -} - -/* -** If the specified device represents a node, return its -** compact node ID; otherwise, return CNODEID_NONE. -*/ -cnodeid_t -nodevertex_to_cnodeid(devfs_handle_t vhdl) -{ - int rv = 0; - arbitrary_info_t cnodeid = CNODEID_NONE; - - rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid); - - return((cnodeid_t)cnodeid); -} - -void -mark_nodevertex_as_node(devfs_handle_t vhdl, cnodeid_t cnodeid) -{ - if (cnodeid == CNODEID_NONE) - return; - - cnodeid_to_vertex(cnodeid) = vhdl; - labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, - (arbitrary_info_t)cnodeid); - - { - char cnodeid_buffer[10]; - - if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) { - (void)hwgraph_path_add( hwgraph_root, - EDGE_LBL_NODENUM, - &hwgraph_all_cnodes); - } - - sprintf(cnodeid_buffer, "%d", cnodeid); - (void)hwgraph_edge_add( hwgraph_all_cnodes, - vhdl, - cnodeid_buffer); - } -} - -/* -** If the specified device represents a CPU, return its cpuid; -** otherwise, return CPU_NONE. -*/ -cpuid_t -cpuvertex_to_cpuid(devfs_handle_t vhdl) -{ - arbitrary_info_t cpuid = CPU_NONE; - - (void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid); - - return((cpuid_t)cpuid); -} - - -/* -** dev_to_name converts a devfs_handle_t into a canonical name. If the devfs_handle_t -** represents a vertex in the hardware graph, it is converted in the -** normal way for vertices. If the devfs_handle_t is an old devfs_handle_t (one which -** does not represent a hwgraph vertex), we synthesize a name based -** on major/minor number. -** -** Usually returns a pointer to the original buffer, filled in as -** appropriate. If the buffer is too small to hold the entire name, -** or if anything goes wrong while determining the name, dev_to_name -** returns "UnknownDevice". -*/ -char * -dev_to_name(devfs_handle_t dev, char *buf, uint buflen) -{ - return(vertex_to_name(dev, buf, buflen)); -} - - diff -urN linux-2.4.21/arch/ia64/sn/io/hubdev.c linux-2.4.22/arch/ia64/sn/io/hubdev.c --- linux-2.4.21/arch/ia64/sn/io/hubdev.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/hubdev.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,132 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct hubdev_callout { - int (*attach_method)(devfs_handle_t); - struct hubdev_callout *fp; -}; - -typedef struct hubdev_callout hubdev_callout_t; - -mutex_t hubdev_callout_mutex; -hubdev_callout_t *hubdev_callout_list = NULL; - -void -hubdev_init(void) -{ - mutex_init(&hubdev_callout_mutex); - hubdev_callout_list = NULL; -} - -void -hubdev_register(int (*attach_method)(devfs_handle_t)) -{ - hubdev_callout_t *callout; - - ASSERT(attach_method); - - callout = (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP); - ASSERT(callout); - - mutex_lock(&hubdev_callout_mutex); - /* - * Insert at the end of the list - */ - callout->fp = hubdev_callout_list; - hubdev_callout_list = callout; - callout->attach_method = attach_method; - mutex_unlock(&hubdev_callout_mutex); -} - -int -hubdev_unregister(int (*attach_method)(devfs_handle_t)) -{ - hubdev_callout_t **p; - - ASSERT(attach_method); - - mutex_lock(&hubdev_callout_mutex); - /* - * Remove registry element containing attach_method - */ - for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) { - if ((*p)->attach_method == attach_method) { - hubdev_callout_t* victim = *p; - *p = (*p)->fp; - kfree(victim); - mutex_unlock(&hubdev_callout_mutex); - return (0); - } - } - mutex_unlock(&hubdev_callout_mutex); - return (ENOENT); -} - - -int -hubdev_docallouts(devfs_handle_t hub) -{ - hubdev_callout_t *p; - int errcode; - - mutex_lock(&hubdev_callout_mutex); - - for (p = hubdev_callout_list; p != NULL; p = p->fp) { - ASSERT(p->attach_method); - errcode = (*p->attach_method)(hub); - if (errcode != 0) { - mutex_unlock(&hubdev_callout_mutex); - return (errcode); - } - } - mutex_unlock(&hubdev_callout_mutex); - return (0); -} - -/* - * Given a hub vertex, return the base address of the Hspec space - * for that hub. - */ - -#if defined(CONFIG_IA64_SGI_SN1) - -caddr_t -hubdev_prombase_get(devfs_handle_t hub) -{ - hubinfo_t hinfo = NULL; - - hubinfo_get(hub, &hinfo); - ASSERT(hinfo); - - return ((caddr_t)NODE_RBOOT_BASE(hinfo->h_nasid)); -} - -cnodeid_t -hubdev_cnodeid_get(devfs_handle_t hub) -{ - hubinfo_t hinfo = NULL; - hubinfo_get(hub, &hinfo); - ASSERT(hinfo); - - return hinfo->h_cnodeid; -} - -#endif /* CONFIG_IA64_SGI_SN1 */ diff -urN linux-2.4.21/arch/ia64/sn/io/hubspc.c linux-2.4.22/arch/ia64/sn/io/hubspc.c --- linux-2.4.21/arch/ia64/sn/io/hubspc.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/hubspc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,251 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * hubspc.c - Hub Memory Space Management Driver - * This driver implements the managers for the following - * memory resources: - * 1) reference counters - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Uncomment the following line for tracing */ -/* #define HUBSPC_DEBUG 1 */ - -int hubspc_devflag = D_MP; - - -/***********************************************************************/ -/* CPU Prom Space */ -/***********************************************************************/ - -typedef struct cpuprom_info { - devfs_handle_t prom_dev; - devfs_handle_t nodevrtx; - struct cpuprom_info *next; -}cpuprom_info_t; - -static cpuprom_info_t *cpuprom_head; -static spinlock_t cpuprom_spinlock; -#define PROM_LOCK() mutex_spinlock(&cpuprom_spinlock) -#define PROM_UNLOCK(s) mutex_spinunlock(&cpuprom_spinlock, (s)) - -/* - * Add prominfo to the linked list maintained. - */ -void -prominfo_add(devfs_handle_t hub, devfs_handle_t prom) -{ - cpuprom_info_t *info; - unsigned long s; - - info = kmalloc(sizeof(cpuprom_info_t), GFP_KERNEL); - ASSERT(info); - info->prom_dev = prom; - info->nodevrtx = hub; - - - s = PROM_LOCK(); - info->next = cpuprom_head; - cpuprom_head = info; - PROM_UNLOCK(s); -} - -void -prominfo_del(devfs_handle_t prom) -{ - unsigned long s; - cpuprom_info_t *info; - cpuprom_info_t **prev; - - s = PROM_LOCK(); - prev = &cpuprom_head; - while ( (info = *prev) ) { - if (info->prom_dev == prom) { - *prev = info->next; - PROM_UNLOCK(s); - return; - } - - prev = &info->next; - } - PROM_UNLOCK(s); - ASSERT(0); -} - -devfs_handle_t -prominfo_nodeget(devfs_handle_t prom) -{ - unsigned long s; - cpuprom_info_t *info; - - s = PROM_LOCK(); - info = cpuprom_head; - while (info) { - if(info->prom_dev == prom) { - PROM_UNLOCK(s); - return info->nodevrtx; - } - info = info->next; - } - PROM_UNLOCK(s); - return 0; -} - -#if defined(CONFIG_IA64_SGI_SN1) -#define SN_PROMVERSION INV_IP35PROM - -/* Add "detailed" labelled inventory information to the - * prom vertex - */ -void -cpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node) -{ - invent_miscinfo_t *cpuprom_inventory_info; - extern invent_generic_t *klhwg_invent_alloc(cnodeid_t cnode, - int class, int size); - cnodeid_t cnode = hubdev_cnodeid_get(node); - - /* Allocate memory for the extra inventory information - * for the prom - */ - cpuprom_inventory_info = (invent_miscinfo_t *) - klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t)); - - ASSERT(cpuprom_inventory_info); - - /* Set the enabled flag so that the hinv interprets this - * information - */ - cpuprom_inventory_info->im_gen.ig_flag = INVENT_ENABLED; - cpuprom_inventory_info->im_type = SN_PROMVERSION; - /* Store prom revision into inventory information */ - cpuprom_inventory_info->im_rev = IP27CONFIG.pvers_rev; - cpuprom_inventory_info->im_version = IP27CONFIG.pvers_vers; - - /* Store this info as labelled information hanging off the - * prom device vertex - */ - hwgraph_info_add_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, - (arbitrary_info_t) cpuprom_inventory_info); - /* Export this information so that user programs can get to - * this by using attr_get() - */ - hwgraph_info_export_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, - sizeof(invent_miscinfo_t)); -} - -#endif /* CONFIG_IA64_SGI_SN1 */ - - -/***********************************************************************/ -/* Base Hub Space Driver */ -/***********************************************************************/ - -/* - * hubspc_init - * Registration of the hubspc devices with the hub manager - */ -void -hubspc_init(void) -{ - /* - * Register with the hub manager - */ - - /* The reference counters */ -#if defined(CONFIG_IA64_SGI_SN1) - hubdev_register(mem_refcnt_attach); -#endif - -#ifdef CONFIG_IA64_SGI_SN1 - /* L1 system controller link */ - if ( !IS_RUNNING_ON_SIMULATOR() ) { - /* initialize the L1 link */ - extern void l1_init(void); - l1_init(); - } -#endif /* CONFIG_IA64_SGI_SN1 */ -#ifdef HUBSPC_DEBUG - printk("hubspc_init: Completed\n"); -#endif /* HUBSPC_DEBUG */ - /* Initialize spinlocks */ - mutex_spinlock_init(&cpuprom_spinlock); -} - -/* ARGSUSED */ -int -hubspc_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp) -{ - return (0); -} - - -/* ARGSUSED */ -int -hubspc_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) -{ - return (0); -} - -/* ARGSUSED */ -int -hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) -{ - /*REFERENCED*/ - int errcode = 0; - - /* check validity of request */ - if( len == 0 ) { - return -ENXIO; - } - - return errcode; -} - -/* ARGSUSED */ -int -hubspc_unmap(devfs_handle_t dev, vhandl_t *vt) -{ - return (0); - -} - -/* ARGSUSED */ -int -hubspc_ioctl(devfs_handle_t dev, - int cmd, - void *arg, - int mode, - cred_t *cred_p, - int *rvalp) -{ - return (0); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/hwgdfs/Makefile linux-2.4.22/arch/ia64/sn/io/hwgdfs/Makefile --- linux-2.4.21/arch/ia64/sn/io/hwgdfs/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgdfs/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,18 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. +# +# Makefile for the sn2 io routines. + +EXTRA_CFLAGS := -DLITTLE_ENDIAN + +O_TARGET := snio.o + +export-objs := hcl.o + +obj-y += hcl.o labelcl.o hcl_util.o invent_stub.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl.c linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl.c --- linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,916 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * hcl - SGI's Hardware Graph compatibility layer. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER" +#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE" +#define HCL_TEMP_NAME_LEN 44 +#define HCL_VERSION "1.0" +vertex_hdl_t hwgraph_root; +vertex_hdl_t linux_busnum; + +extern void pci_bus_cvlink_init(void); + +/* + * Debug flag definition. + */ +#define OPTION_NONE 0x00 +#define HCL_DEBUG_NONE 0x00000 +#define HCL_DEBUG_ALL 0x0ffff +#if defined(CONFIG_HCL_DEBUG) +static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE; +#endif +static unsigned int hcl_debug = HCL_DEBUG_NONE; +#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE) +static unsigned int boot_options = OPTION_NONE; +#endif + +/* + * Some Global definitions. + */ +static vertex_hdl_t hcl_handle; + +invplace_t invplace_none = { + GRAPH_VERTEX_NONE, + GRAPH_VERTEX_PLACE_NONE, + NULL +}; + +/* + * HCL device driver. + * The purpose of this device driver is to provide a facility + * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path + * to manipulate label entries without having to implement + * system call interfaces. This methodology will enable us to + * make this feature module loadable. + */ +static int hcl_open(struct inode * inode, struct file * filp) +{ + if (hcl_debug) { + printk("HCL: hcl_open called.\n"); + } + + return(0); + +} + +static int hcl_close(struct inode * inode, struct file * filp) +{ + + if (hcl_debug) { + printk("HCL: hcl_close called.\n"); + } + + return(0); + +} + +static int hcl_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + + if (hcl_debug) { + printk("HCL: hcl_ioctl called.\n"); + } + + switch (cmd) { + default: + if (hcl_debug) { + printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd); + } + } + + return(0); + +} + +struct file_operations hcl_fops = { + (struct module *)0, + NULL, /* lseek - default */ + NULL, /* read - general block-dev read */ + NULL, /* write - general block-dev write */ + NULL, /* readdir - bad */ + NULL, /* poll */ + hcl_ioctl, /* ioctl */ + NULL, /* mmap */ + hcl_open, /* open */ + NULL, /* flush */ + hcl_close, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* lock */ + NULL, /* readv */ + NULL, /* writev */ +}; + + +/* + * init_hcl() - Boot time initialization. Ensure that it is called + * after devfs has been initialized. + * + * For now this routine is being called out of devfs/base.c. Actually + * Not a bad place to be .. + * + */ +int __init init_hcl(void) +{ + extern void string_table_init(struct string_table *); + extern struct string_table label_string_table; + extern int init_ifconfig_net(void); + extern int init_ioconfig_bus(void); + int status = 0; + int rv = 0; + + if (IS_RUNNING_ON_SIMULATOR()) { + extern u64 klgraph_addr[]; + klgraph_addr[0] = 0xe000003000030000; + } + + /* + * Create the hwgraph_root on devfs. + */ + rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root); + if (rv) + printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv); + + status = devfs_set_flags (hwgraph_root, DEVFS_FL_HIDE); + + /* + * Create the hcl driver to support inventory entry manipulations. + * By default, it is expected that devfs is mounted on /dev. + * + */ + hcl_handle = hwgraph_register(hwgraph_root, ".hcl", + 0, DEVFS_FL_AUTO_DEVNUM, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + &hcl_fops, NULL); + + if (hcl_handle == NULL) { + panic("HCL: Unable to create HCL Driver in init_hcl().\n"); + return(0); + } + + /* + * Initialize the HCL string table. + */ + string_table_init(&label_string_table); + + /* + * Create the directory that links Linux bus numbers to our Xwidget. + */ + rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum); + if (linux_busnum == NULL) { + panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS); + return(0); + } + + pci_bus_cvlink_init(); + + /* + * Initialize the ifconfgi_net driver that does network devices + * Persistent Naming. + */ + init_ifconfig_net(); + init_ioconfig_bus(); + + return(0); + +} + + +/* + * hcl_setup() - Process boot time parameters if given. + * "hcl=" + * This routine gets called only if "hcl=" is given in the + * boot line and before init_hcl(). + * + * We currently do not have any boot options .. when we do, + * functionalities can be added here. + * + */ +static int __init hcl_setup(char *str) +{ + while ( (*str != '\0') && !isspace (*str) ) + { +#ifdef CONFIG_HCL_DEBUG + if (strncmp (str, "all", 3) == 0) { + hcl_debug_init |= HCL_DEBUG_ALL; + str += 3; + } else + return 0; +#endif + if (*str != ',') return 0; + ++str; + } + + return 1; + +} + +__setup("hcl=", hcl_setup); + + +/* + * Set device specific "fast information". + * + */ +void +hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo) +{ + labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL); +} + + +/* + * Get device specific "fast information". + * + */ +arbitrary_info_t +hwgraph_fastinfo_get(vertex_hdl_t de) +{ + arbitrary_info_t fastinfo; + int rv; + + if (!de) { + printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n"); + return(-1); + } + + rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo); + if (rv == 0) + return(fastinfo); + + return(0); +} + + +/* + * hwgraph_connectpt_set - Sets the connect point handle in de to the + * given connect_de handle. By default, the connect point of the + * devfs node is the parent. This effectively changes this assumption. + */ +int +hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de) +{ + int rv; + + if (!de) + return(-1); + + rv = labelcl_info_connectpt_set(de, connect_de); + + return(rv); +} + + +/* + * hwgraph_connectpt_get: Returns the entry's connect point in the devfs + * tree. + */ +vertex_hdl_t +hwgraph_connectpt_get(vertex_hdl_t de) +{ + int rv; + arbitrary_info_t info; + vertex_hdl_t connect; + + rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); + if (rv != 0) { + return(NULL); + } + + connect = (vertex_hdl_t)info; + return(connect); + +} + + +/* + * hwgraph_mk_dir - Creates a directory entry with devfs. + * Note that a directory entry in devfs can have children + * but it cannot be a char|block special file. + */ +vertex_hdl_t +hwgraph_mk_dir(vertex_hdl_t de, const char *name, + unsigned int namelen, void *info) +{ + + int rv; + labelcl_info_t *labelcl_info = NULL; + vertex_hdl_t new_devfs_handle = NULL; + vertex_hdl_t parent = NULL; + + /* + * Create the device info structure for hwgraph compatiblity support. + */ + labelcl_info = labelcl_info_create(); + if (!labelcl_info) + return(NULL); + + /* + * Create a devfs entry. + */ + new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info); + if (!new_devfs_handle) { + labelcl_info_destroy(labelcl_info); + return(NULL); + } + + /* + * Get the parent handle. + */ + parent = devfs_get_parent (new_devfs_handle); + + /* + * To provide the same semantics as the hwgraph, set the connect point. + */ + rv = hwgraph_connectpt_set(new_devfs_handle, parent); + if (!rv) { + /* + * We need to clean up! + */ + } + + /* + * If the caller provides a private data pointer, save it in the + * labelcl info structure(fastinfo). This can be retrieved via + * hwgraph_fastinfo_get() + */ + if (info) + hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); + + return(new_devfs_handle); + +} + +/* + * hwgraph_path_add - Create a directory node with the given path starting + * from the given vertex_hdl_t. + */ +int +hwgraph_path_add(vertex_hdl_t fromv, + char *path, + vertex_hdl_t *new_de) +{ + + unsigned int namelen = strlen(path); + int rv; + + /* + * We need to handle the case when fromv is NULL .. + * in this case we need to create the path from the + * hwgraph root! + */ + if (fromv == NULL) + fromv = hwgraph_root; + + /* + * check the entry doesn't already exist, if it does + * then we simply want new_de to point to it (otherwise + * we'll overwrite the existing labelcl_info struct) + */ + rv = hwgraph_edge_get(fromv, path, new_de); + if (rv) { /* couldn't find entry so we create it */ + *new_de = hwgraph_mk_dir(fromv, path, namelen, NULL); + if (new_de == NULL) + return(-1); + else + return(0); + } + else + return(0); + +} + +/* + * hwgraph_register - Creates a file entry with devfs. + * Note that a file entry cannot have children .. it is like a + * char|block special vertex in hwgraph. + */ +vertex_hdl_t +hwgraph_register(vertex_hdl_t de, const char *name, + unsigned int namelen, unsigned int flags, + unsigned int major, unsigned int minor, + umode_t mode, uid_t uid, gid_t gid, + struct file_operations *fops, + void *info) +{ + + vertex_hdl_t new_devfs_handle = NULL; + + /* + * Create a devfs entry. + */ + new_devfs_handle = devfs_register(de, name, flags, major, + minor, mode, fops, info); + if (!new_devfs_handle) { + return(NULL); + } + + return(new_devfs_handle); + +} + + +/* + * hwgraph_mk_symlink - Create a symbolic link. + */ +int +hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen, + unsigned int flags, const char *link, unsigned int linklen, + vertex_hdl_t *handle, void *info) +{ + + void *labelcl_info = NULL; + int status = 0; + vertex_hdl_t new_devfs_handle = NULL; + + /* + * Create the labelcl info structure for hwgraph compatiblity support. + */ + labelcl_info = labelcl_info_create(); + if (!labelcl_info) + return(-1); + + /* + * Create a symbolic link devfs entry. + */ + status = devfs_mk_symlink(de, name, flags, link, + &new_devfs_handle, labelcl_info); + if ( (!new_devfs_handle) || (!status) ){ + labelcl_info_destroy((labelcl_info_t *)labelcl_info); + return(-1); + } + + /* + * If the caller provides a private data pointer, save it in the + * labelcl info structure(fastinfo). This can be retrieved via + * hwgraph_fastinfo_get() + */ + if (info) + hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); + + *handle = new_devfs_handle; + return(0); + +} + +/* + * hwgraph_vertex_destroy - Destroy the devfs entry + */ +int +hwgraph_vertex_destroy(vertex_hdl_t de) +{ + + void *labelcl_info = NULL; + + labelcl_info = devfs_get_info(de); + devfs_unregister(de); + + if (labelcl_info) + labelcl_info_destroy((labelcl_info_t *)labelcl_info); + + return(0); +} + +/* + * hwgraph_edge_add - This routines has changed from the original conext. + * All it does now is to create a symbolic link from "from" to "to". + */ +/* ARGSUSED */ +int +hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name) +{ + + char *path; + char *s1; + char *index; + int name_start; + vertex_hdl_t handle = NULL; + int rv; + int i, count; + + path = kmalloc(1024, GFP_KERNEL); + memset(path, 0x0, 1024); + name_start = devfs_generate_path (from, path, 1024); + s1 = &path[name_start]; + count = 0; + while (1) { + index = strstr (s1, "/"); + if (index) { + count++; + s1 = ++index; + } else { + count++; + break; + } + } + + memset(path, 0x0, 1024); + name_start = devfs_generate_path (to, path, 1024); + + for (i = 0; i < count; i++) { + strcat(path,"../"); + } + + strcat(path, &path[name_start]); + + /* + * Otherwise, just create a symlink to the vertex. + * In this case the vertex was previous created with a REAL pathname. + */ + rv = devfs_mk_symlink (from, (const char *)name, + DEVFS_FL_DEFAULT, path, + &handle, NULL); + + name_start = devfs_generate_path (handle, path, 1024); + return(rv); + + +} +/* ARGSUSED */ +int +hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr) +{ + + int namelen = 0; + vertex_hdl_t target_handle = NULL; + + if (name == NULL) + return(-1); + + if (toptr == NULL) + return(-1); + + /* + * If the name is "." just return the current devfs entry handle. + */ + if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) { + if (toptr) { + *toptr = from; + } + } else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) { + /* + * Hmmm .. should we return the connect point or parent .. + * see in hwgraph, the concept of parent is the connectpt! + * + * Maybe we should see whether the connectpt is set .. if + * not just return the parent! + */ + target_handle = hwgraph_connectpt_get(from); + if (target_handle) { + /* + * Just return the connect point. + */ + *toptr = target_handle; + return(0); + } + target_handle = devfs_get_parent(from); + *toptr = target_handle; + + } else { + /* + * Call devfs to get the devfs entry. + */ + namelen = (int) strlen(name); + target_handle = devfs_find_handle (from, name, 0, 0, + 0, 1); /* Yes traverse symbolic links */ + if (target_handle == NULL) + return(-1); + else + *toptr = target_handle; + } + + return(0); +} + +/* + * hwgraph_info_add_LBL - Adds a new label for the device. Mark the info_desc + * of the label as INFO_DESC_PRIVATE and store the info in the label. + */ +/* ARGSUSED */ +int +hwgraph_info_add_LBL( vertex_hdl_t de, + char *name, + arbitrary_info_t info) +{ + return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info)); +} + +/* + * hwgraph_info_remove_LBL - Remove the label entry for the device. + */ +/* ARGSUSED */ +int +hwgraph_info_remove_LBL( vertex_hdl_t de, + char *name, + arbitrary_info_t *old_info) +{ + return(labelcl_info_remove_LBL(de, name, NULL, old_info)); +} + +/* + * hwgraph_info_replace_LBL - replaces an existing label with + * a new label info value. + */ +/* ARGSUSED */ +int +hwgraph_info_replace_LBL( vertex_hdl_t de, + char *name, + arbitrary_info_t info, + arbitrary_info_t *old_info) +{ + return(labelcl_info_replace_LBL(de, name, + INFO_DESC_PRIVATE, info, + NULL, old_info)); +} +/* + * hwgraph_info_get_LBL - Get and return the info value in the label of the + * device. + */ +/* ARGSUSED */ +int +hwgraph_info_get_LBL( vertex_hdl_t de, + char *name, + arbitrary_info_t *infop) +{ + return(labelcl_info_get_LBL(de, name, NULL, infop)); +} + +/* + * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer + * of the given label for the device. The weird thing is that the label + * that matches the name is return irrespective of the info_desc value! + * Do not understand why the word "exported" is used! + */ +/* ARGSUSED */ +int +hwgraph_info_get_exported_LBL( vertex_hdl_t de, + char *name, + int *export_info, + arbitrary_info_t *infop) +{ + int rc; + arb_info_desc_t info_desc; + + rc = labelcl_info_get_LBL(de, name, &info_desc, infop); + if (rc == 0) + *export_info = (int)info_desc; + + return(rc); +} + +/* + * hwgraph_info_get_next_LBL - Returns the next label info given the + * current label entry in place. + * + * Once again this has no locking or reference count for protection. + * + */ +/* ARGSUSED */ +int +hwgraph_info_get_next_LBL( vertex_hdl_t de, + char *buf, + arbitrary_info_t *infop, + labelcl_info_place_t *place) +{ + return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place)); +} + +/* + * hwgraph_info_export_LBL - Retrieve the specified label entry and modify + * the info_desc field with the given value in nbytes. + */ +/* ARGSUSED */ +int +hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes) +{ + arbitrary_info_t info; + int rc; + + if (nbytes == 0) + nbytes = INFO_DESC_EXPORT; + + if (nbytes < 0) + return(-1); + + rc = labelcl_info_get_LBL(de, name, NULL, &info); + if (rc != 0) + return(rc); + + rc = labelcl_info_replace_LBL(de, name, + nbytes, info, NULL, NULL); + + return(rc); +} + +/* + * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the + * label info_descr filed to INFO_DESC_PRIVATE. + */ +/* ARGSUSED */ +int +hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name) +{ + arbitrary_info_t info; + int rc; + + rc = labelcl_info_get_LBL(de, name, NULL, &info); + if (rc != 0) + return(rc); + + rc = labelcl_info_replace_LBL(de, name, + INFO_DESC_PRIVATE, info, NULL, NULL); + + return(rc); +} + +/* + * hwgraph_path_lookup - return the handle for the given path. + * + */ +int +hwgraph_path_lookup( vertex_hdl_t start_vertex_handle, + char *lookup_path, + vertex_hdl_t *vertex_handle_ptr, + char **remainder) +{ + *vertex_handle_ptr = devfs_find_handle(start_vertex_handle, /* start dir */ + lookup_path, /* path */ + 0, /* major */ + 0, /* minor */ + 0, /* char | block */ + 1); /* traverse symlinks */ + if (*vertex_handle_ptr == NULL) + return(-1); + else + return(0); +} + +/* + * hwgraph_traverse - Find and return the devfs handle starting from de. + * + */ +graph_error_t +hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found) +{ + /* + * get the directory entry (path should end in a directory) + */ + + *found = devfs_find_handle(de, /* start dir */ + path, /* path */ + 0, /* major */ + 0, /* minor */ + 0, /* char | block */ + 1); /* traverse symlinks */ + if (*found == NULL) + return(GRAPH_NOT_FOUND); + else + return(GRAPH_SUCCESS); +} + +/* + * hwgraph_path_to_vertex - Return the devfs entry handle for the given + * pathname .. assume traverse symlinks too!. + */ +vertex_hdl_t +hwgraph_path_to_vertex(char *path) +{ + return(devfs_find_handle(NULL, /* start dir */ + path, /* path */ + 0, /* major */ + 0, /* minor */ + 0, /* char | block */ + 1)); /* traverse symlinks */ +} + +/* + * hwgraph_inventory_remove - Removes an inventory entry. + * + * Remove an inventory item associated with a vertex. It is the caller's + * responsibility to make sure that there are no races between removing + * inventory from a vertex and simultaneously removing that vertex. +*/ +int +hwgraph_inventory_remove( vertex_hdl_t de, + int class, + int type, + major_t controller, + minor_t unit, + int state) +{ + return(0); /* Just a Stub for IRIX code. */ +} + +/* + * Find the canonical name for a given vertex by walking back through + * connectpt's until we hit the hwgraph root vertex (or until we run + * out of buffer space or until something goes wrong). + * + * COMPATIBILITY FUNCTIONALITY + * Walks back through 'parents', not necessarily the same as connectpts. + * + * Need to resolve the fact that devfs does not return the path from + * "/" but rather it just stops right before /dev .. + */ +int +hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen) +{ + char *locbuf; + int pos; + + if (buflen < 1) + return(-1); /* XXX should be GRAPH_BAD_PARAM ? */ + + locbuf = kmalloc(buflen, GFP_KERNEL); + + pos = devfs_generate_path(vhdl, locbuf, buflen); + if (pos < 0) { + kfree(locbuf); + return pos; + } + + strcpy(buf, &locbuf[pos]); + kfree(locbuf); + return 0; +} + +/* +** vertex_to_name converts a vertex into a canonical name by walking +** back through connect points until we hit the hwgraph root (or until +** we run out of buffer space). +** +** Usually returns a pointer to the original buffer, filled in as +** appropriate. If the buffer is too small to hold the entire name, +** or if anything goes wrong while determining the name, vertex_to_name +** returns "UnknownDevice". +*/ + +#define DEVNAME_UNKNOWN "UnknownDevice" + +char * +vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen) +{ + if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS) + return(buf); + else + return(DEVNAME_UNKNOWN); +} + +graph_error_t +hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr) +{ + printk("WARNING: hwgraph_edge_remove NOT supported.\n"); + return(GRAPH_ILLEGAL_REQUEST); +} + +graph_error_t +hwgraph_vertex_unref(vertex_hdl_t vhdl) +{ + return(GRAPH_ILLEGAL_REQUEST); +} + + +EXPORT_SYMBOL(hwgraph_mk_dir); +EXPORT_SYMBOL(hwgraph_path_add); +EXPORT_SYMBOL(hwgraph_register); +EXPORT_SYMBOL(hwgraph_vertex_destroy); +EXPORT_SYMBOL(hwgraph_fastinfo_get); +EXPORT_SYMBOL(hwgraph_fastinfo_set); +EXPORT_SYMBOL(hwgraph_connectpt_set); +EXPORT_SYMBOL(hwgraph_connectpt_get); +EXPORT_SYMBOL(hwgraph_info_add_LBL); +EXPORT_SYMBOL(hwgraph_info_remove_LBL); +EXPORT_SYMBOL(hwgraph_info_replace_LBL); +EXPORT_SYMBOL(hwgraph_info_get_LBL); +EXPORT_SYMBOL(hwgraph_info_get_exported_LBL); +EXPORT_SYMBOL(hwgraph_info_get_next_LBL); +EXPORT_SYMBOL(hwgraph_info_export_LBL); +EXPORT_SYMBOL(hwgraph_info_unexport_LBL); +EXPORT_SYMBOL(hwgraph_path_lookup); +EXPORT_SYMBOL(hwgraph_traverse); +EXPORT_SYMBOL(hwgraph_vertex_name_get); diff -urN linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl_util.c linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl_util.c --- linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl_util.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl_util.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,200 @@ +/* $Id: hcl_util.c,v 1.3 2003/04/24 13:59:39 pfg Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE; +extern vertex_hdl_t hwgraph_root; + + +/* +** Return the "master" for a given vertex. A master vertex is a +** controller or adapter or other piece of hardware that the given +** vertex passes through on the way to the rest of the system. +*/ +vertex_hdl_t +device_master_get(vertex_hdl_t vhdl) +{ + graph_error_t rc; + vertex_hdl_t master; + + rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master); + if (rc == GRAPH_SUCCESS) + return(master); + else + return(GRAPH_VERTEX_NONE); +} + +/* +** Set the master for a given vertex. +** Returns 0 on success, non-0 indicates failure +*/ +int +device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master) +{ + graph_error_t rc; + + rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER); + return(rc != GRAPH_SUCCESS); +} + + +/* +** Return the compact node id of the node that ultimately "owns" the specified +** vertex. In order to do this, we walk back through masters and connect points +** until we reach a vertex that represents a node. +*/ +cnodeid_t +master_node_get(vertex_hdl_t vhdl) +{ + cnodeid_t cnodeid; + vertex_hdl_t master; + + for (;;) { + cnodeid = nodevertex_to_cnodeid(vhdl); + if (cnodeid != CNODEID_NONE) + return(cnodeid); + + master = device_master_get(vhdl); + + /* Check for exceptional cases */ + if (master == vhdl) { + /* Since we got a reference to the "master" thru + * device_master_get() we should decrement + * its reference count by 1 + */ + return(CNODEID_NONE); + } + + if (master == GRAPH_VERTEX_NONE) { + master = hwgraph_connectpt_get(vhdl); + if ((master == GRAPH_VERTEX_NONE) || + (master == vhdl)) { + return(CNODEID_NONE); + } + } + + vhdl = master; + } +} + +static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE; +extern int maxcpus; + +void +mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid) +{ + if (cpuid == CPU_NONE) + return; + + (void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT, + (arbitrary_info_t)cpuid); + { + char cpuid_buffer[10]; + + if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) { + (void)hwgraph_path_add( hwgraph_root, + EDGE_LBL_CPUNUM, + &hwgraph_all_cpuids); + } + + sprintf(cpuid_buffer, "%ld", cpuid); + (void)hwgraph_edge_add( hwgraph_all_cpuids, + vhdl, + cpuid_buffer); + } +} + +/* +** If the specified device represents a node, return its +** compact node ID; otherwise, return CNODEID_NONE. +*/ +cnodeid_t +nodevertex_to_cnodeid(vertex_hdl_t vhdl) +{ + int rv = 0; + arbitrary_info_t cnodeid = CNODEID_NONE; + + rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid); + + return((cnodeid_t)cnodeid); +} + +void +mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid) +{ + if (cnodeid == CNODEID_NONE) + return; + + cnodeid_to_vertex(cnodeid) = vhdl; + labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, + (arbitrary_info_t)cnodeid); + + { + char cnodeid_buffer[10]; + + if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) { + (void)hwgraph_path_add( hwgraph_root, + EDGE_LBL_NODENUM, + &hwgraph_all_cnodes); + } + + sprintf(cnodeid_buffer, "%d", cnodeid); + (void)hwgraph_edge_add( hwgraph_all_cnodes, + vhdl, + cnodeid_buffer); + } +} + +/* +** If the specified device represents a CPU, return its cpuid; +** otherwise, return CPU_NONE. +*/ +cpuid_t +cpuvertex_to_cpuid(vertex_hdl_t vhdl) +{ + arbitrary_info_t cpuid = CPU_NONE; + + (void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid); + + return((cpuid_t)cpuid); +} + + +/* +** dev_to_name converts a vertex_hdl_t into a canonical name. If the vertex_hdl_t +** represents a vertex in the hardware graph, it is converted in the +** normal way for vertices. If the vertex_hdl_t is an old vertex_hdl_t (one which +** does not represent a hwgraph vertex), we synthesize a name based +** on major/minor number. +** +** Usually returns a pointer to the original buffer, filled in as +** appropriate. If the buffer is too small to hold the entire name, +** or if anything goes wrong while determining the name, dev_to_name +** returns "UnknownDevice". +*/ +char * +dev_to_name(vertex_hdl_t dev, char *buf, uint buflen) +{ + return(vertex_to_name(dev, buf, buflen)); +} + + diff -urN linux-2.4.21/arch/ia64/sn/io/hwgdfs/invent_stub.c linux-2.4.22/arch/ia64/sn/io/hwgdfs/invent_stub.c --- linux-2.4.21/arch/ia64/sn/io/hwgdfs/invent_stub.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgdfs/invent_stub.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,146 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +/* + * Hardware Inventory + * + * See sys/sn/invent.h for an explanation of the hardware inventory contents. + * + */ +#include +#include +#include +#include +#include + +void +inventinit(void) +{ +} + +/* + * For initializing/updating an inventory entry. + */ +void +replace_in_inventory( + inventory_t *pinv, int class, int type, + int controller, int unit, int state) +{ +} + +/* + * Inventory addition + * + * XXX NOTE: Currently must be called after dynamic memory allocator is + * initialized. + * + */ +void +add_to_inventory(int class, int type, int controller, int unit, int state) +{ +} + + +/* + * Inventory retrieval + * + * These two routines are intended to prevent the caller from having to know + * the internal structure of the inventory table. + * + * The caller of get_next_inventory is supposed to call start_scan_invent + * before the irst call to get_next_inventory, and the caller is required + * to call end_scan_invent after the last call to get_next_inventory. + */ +inventory_t * +get_next_inventory(invplace_t *place) +{ + return((inventory_t *) NULL); +} + +/* ARGSUSED */ +int +get_sizeof_inventory(int abi) +{ + return sizeof(inventory_t); +} + +/* Must be called prior to first call to get_next_inventory */ +void +start_scan_inventory(invplace_t *iplace) +{ +} + +/* Must be called after last call to get_next_inventory */ +void +end_scan_inventory(invplace_t *iplace) +{ +} + +/* + * Hardware inventory scanner. + * + * Calls fun() for every entry in inventory list unless fun() returns something + * other than 0. + */ +int +scaninvent(int (*fun)(inventory_t *, void *), void *arg) +{ + return 0; +} + +/* + * Find a particular inventory object + * + * pinv can be a pointer to an inventory entry and the search will begin from + * there, or it can be 0 in which case the search starts at the beginning. + * A -1 for any of the other arguments is a wildcard (i.e. it always matches). + */ +inventory_t * +find_inventory(inventory_t *pinv, int class, int type, int controller, + int unit, int state) +{ + return((inventory_t *) NULL); +} + + +/* +** Retrieve inventory data associated with a device. +*/ +inventory_t * +device_inventory_get_next( vertex_hdl_t device, + invplace_t *invplace) +{ + return((inventory_t *) NULL); +} + + +/* +** Associate canonical inventory information with a device (and +** add it to the general inventory). +*/ +void +device_inventory_add( vertex_hdl_t device, + int class, + int type, + major_t controller, + minor_t unit, + int state) +{ +} + +int +device_controller_num_get(vertex_hdl_t device) +{ + return (0); +} + +void +device_controller_num_set(vertex_hdl_t device, int contr_num) +{ +} diff -urN linux-2.4.21/arch/ia64/sn/io/hwgdfs/labelcl.c linux-2.4.22/arch/ia64/sn/io/hwgdfs/labelcl.c --- linux-2.4.21/arch/ia64/sn/io/hwgdfs/labelcl.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgdfs/labelcl.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,653 @@ +/* labelcl - SGI's Hwgraph Compatibility Layer. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2001-2003 Silicon Graphics, Inc. All rights reserved. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* +** Very simple and dumb string table that supports only find/insert. +** In practice, if this table gets too large, we may need a more +** efficient data structure. Also note that currently there is no +** way to delete an item once it's added. Therefore, name collision +** will return an error. +*/ + +struct string_table label_string_table; + + + +/* + * string_table_init - Initialize the given string table. + */ +void +string_table_init(struct string_table *string_table) +{ + string_table->string_table_head = NULL; + string_table->string_table_generation = 0; + + /* + * We nedd to initialize locks here! + */ + + return; +} + + +/* + * string_table_destroy - Destroy the given string table. + */ +void +string_table_destroy(struct string_table *string_table) +{ + struct string_table_item *item, *next_item; + + item = string_table->string_table_head; + while (item) { + next_item = item->next; + + STRTBL_FREE(item); + item = next_item; + } + + /* + * We need to destroy whatever lock we have here + */ + + return; +} + + + +/* + * string_table_insert - Insert an entry in the string table .. duplicate + * names are not allowed. + */ +char * +string_table_insert(struct string_table *string_table, char *name) +{ + struct string_table_item *item, *new_item = NULL, *last_item = NULL; + +again: + /* + * Need to lock the table .. + */ + item = string_table->string_table_head; + last_item = NULL; + + while (item) { + if (!strcmp(item->string, name)) { + /* + * If we allocated space for the string and the found that + * someone else already entered it into the string table, + * free the space we just allocated. + */ + if (new_item) + STRTBL_FREE(new_item); + + + /* + * Search optimization: move the found item to the head + * of the list. + */ + if (last_item != NULL) { + last_item->next = item->next; + item->next = string_table->string_table_head; + string_table->string_table_head = item; + } + goto out; + } + last_item = item; + item=item->next; + } + + /* + * name was not found, so add it to the string table. + */ + if (new_item == NULL) { + long old_generation = string_table->string_table_generation; + + new_item = STRTBL_ALLOC(strlen(name)); + + strcpy(new_item->string, name); + + /* + * While we allocated memory for the new string, someone else + * changed the string table. + */ + if (old_generation != string_table->string_table_generation) { + goto again; + } + } else { + /* At this we only have the string table lock in access mode. + * Promote the access lock to an update lock for the string + * table insertion below. + */ + long old_generation = + string_table->string_table_generation; + + /* + * After we did the unlock and wer waiting for update + * lock someone could have potentially updated + * the string table. Check the generation number + * for this case. If it is the case we have to + * try all over again. + */ + if (old_generation != + string_table->string_table_generation) { + goto again; + } + } + + /* + * At this point, we're committed to adding new_item to the string table. + */ + new_item->next = string_table->string_table_head; + item = string_table->string_table_head = new_item; + string_table->string_table_generation++; + +out: + /* + * Need to unlock here. + */ + return(item->string); +} + +/* + * labelcl_info_create - Creates the data structure that will hold the + * device private information asscoiated with a devfs entry. + * The pointer to this structure is what gets stored in the devfs + * (void * info). + */ +labelcl_info_t * +labelcl_info_create() +{ + + labelcl_info_t *new = NULL; + + /* Initial allocation does not include any area for labels */ + if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL ) + return NULL; + + memset (new, 0, sizeof(labelcl_info_t)); + new->hwcl_magic = LABELCL_MAGIC; + return( new); + +} + +/* + * labelcl_info_destroy - Frees the data structure that holds the + * device private information asscoiated with a devfs entry. This + * data structure was created by device_info_create(). + * + * The caller is responsible for nulling the (void *info) in the + * corresponding devfs entry. + */ +int +labelcl_info_destroy(labelcl_info_t *labelcl_info) +{ + + if (labelcl_info == NULL) + return(0); + + /* Free the label list */ + if (labelcl_info->label_list) + kfree(labelcl_info->label_list); + + /* Now free the label info area */ + labelcl_info->hwcl_magic = 0; + kfree(labelcl_info); + + return(0); +} + +/* + * labelcl_info_add_LBL - Adds a new label entry in the labelcl info + * structure. + * + * Error is returned if we find another label with the same name. + */ +int +labelcl_info_add_LBL(vertex_hdl_t de, + char *info_name, + arb_info_desc_t info_desc, + arbitrary_info_t info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + int new_label_list_size; + label_info_t *old_label_list, *new_label_list = NULL; + char *name; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if (info_name == NULL) + return(-1); + + if (strlen(info_name) >= LABEL_LENGTH_MAX) + return(-1); + + name = string_table_insert(&label_string_table, info_name); + + num_labels = labelcl_info->num_labels; + new_label_list_size = sizeof(label_info_t) * (num_labels+1); + + /* + * Create a new label info area. + */ + if (new_label_list_size != 0) { + new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); + + if (new_label_list == NULL) + return(-1); + } + + /* + * At this point, we are committed to adding the labelled info, + * if there isn't already information there with the same name. + */ + old_label_list = labelcl_info->label_list; + + /* + * Look for matching info name. + */ + for (i=0; inum_labels = num_labels+1; + labelcl_info->label_list = new_label_list; + + if (old_label_list != NULL) + kfree(old_label_list); + + return(0); +} + +/* + * labelcl_info_remove_LBL - Remove a label entry. + */ +int +labelcl_info_remove_LBL(vertex_hdl_t de, + char *info_name, + arb_info_desc_t *info_desc, + arbitrary_info_t *info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + int new_label_list_size; + label_info_t *old_label_list, *new_label_list = NULL; + arb_info_desc_t label_desc_found; + arbitrary_info_t label_info_found; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + /* + * Create a new info area. + */ + new_label_list_size = sizeof(label_info_t) * (num_labels-1); + if (new_label_list_size) { + new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); + if (new_label_list == NULL) + return(-1); + } + + /* + * At this point, we are committed to removing the labelled info, + * if it still exists. + */ + old_label_list = labelcl_info->label_list; + + /* + * Find matching info name. + */ + for (i=0; inum_labels = num_labels+1; + labelcl_info->label_list = new_label_list; + + kfree(old_label_list); + + if (info != NULL) + *info = label_info_found; + + if (info_desc != NULL) + *info_desc = label_desc_found; + + return(0); +} + + +/* + * labelcl_info_replace_LBL - Replace an existing label entry with the + * given new information. + * + * Label entry must exist. + */ +int +labelcl_info_replace_LBL(vertex_hdl_t de, + char *info_name, + arb_info_desc_t info_desc, + arbitrary_info_t info, + arb_info_desc_t *old_info_desc, + arbitrary_info_t *old_info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + label_info_t *label_list; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + if (info_name == NULL) + return(-1); + + label_list = labelcl_info->label_list; + + /* + * Verify that information under info_name already exists. + */ + for (i=0; ihwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + label_list = labelcl_info->label_list; + + /* + * Find information under info_name. + */ + for (i=0; ihwcl_magic != LABELCL_MAGIC) + return(-1); + + which_info = *placeptr; + + if (which_info >= labelcl_info->num_labels) { + return(-1); + } + + label_list = (label_info_t *) labelcl_info->label_list; + + if (buffer != NULL) + strcpy(buffer, label_list[which_info].name); + + if (infop) + *infop = label_list[which_info].info; + + if (info_descp) + *info_descp = label_list[which_info].desc; + + *placeptr = which_info + 1; + + return(0); +} + + +int +labelcl_info_replace_IDX(vertex_hdl_t de, + int index, + arbitrary_info_t info, + arbitrary_info_t *old_info) +{ + arbitrary_info_t *info_list_IDX; + labelcl_info_t *labelcl_info = NULL; + + if (de == NULL) { + printk(KERN_ALERT "labelcl: NULL devfs handle given.\n"); + return(-1); + } + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) { + printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n"); + return(-1); + } + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) + return(-1); + + /* + * Replace information at the appropriate index in this vertex with + * the new info. + */ + info_list_IDX = labelcl_info->IDX_list; + if (old_info != NULL) + *old_info = info_list_IDX[index]; + info_list_IDX[index] = info; + + return(0); + +} + +/* + * labelcl_info_connectpt_set - Sets the connectpt. + */ +int +labelcl_info_connectpt_set(struct devfs_entry *de, + struct devfs_entry *connect_de) +{ + arbitrary_info_t old_info; + int rv; + + rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, + (arbitrary_info_t) connect_de, &old_info); + + if (rv) { + return(rv); + } + + return(0); +} + + +/* + * labelcl_info_get_IDX - Returns the information pointed at by index. + * + */ +int +labelcl_info_get_IDX(vertex_hdl_t de, + int index, + arbitrary_info_t *info) +{ + arbitrary_info_t *info_list_IDX; + labelcl_info_t *labelcl_info = NULL; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) + return(-1); + + /* + * Return information at the appropriate index in this vertex. + */ + info_list_IDX = labelcl_info->IDX_list; + if (info != NULL) + *info = info_list_IDX[index]; + + return(0); +} + +/* + * labelcl_info_connectpt_get - Retrieve the connect point for a device entry. + */ +struct devfs_entry * +labelcl_info_connectpt_get(struct devfs_entry *de) +{ + int rv; + arbitrary_info_t info; + + rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); + if (rv) + return(NULL); + + return((struct devfs_entry *)info); +} diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/Makefile linux-2.4.22/arch/ia64/sn/io/hwgfs/Makefile --- linux-2.4.21/arch/ia64/sn/io/hwgfs/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,19 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. +# +# Makefile for the sn2 io routines. + +EXTRA_CFLAGS := -DLITTLE_ENDIAN + +O_TARGET := snio.o + +export-objs := hcl.o ramfs.o interface.o + +obj-y += hcl.o labelcl.o hcl_util.o invent_stub.o \ + ramfs.o interface.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl.c linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl.c --- linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,938 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * hcl - SGI's Hardware Graph compatibility layer. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* needed for smp_lock.h :( */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER" +#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE" +#define HCL_TEMP_NAME_LEN 44 +#define HCL_VERSION "1.0" + +#define vertex_hdl_t hwgfs_handle_t +vertex_hdl_t hwgraph_root; +vertex_hdl_t linux_busnum; + +extern void pci_bus_cvlink_init(void); + +/* + * Debug flag definition. + */ +#define OPTION_NONE 0x00 +#define HCL_DEBUG_NONE 0x00000 +#define HCL_DEBUG_ALL 0x0ffff +#if defined(CONFIG_HCL_DEBUG) +static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE; +#endif +static unsigned int hcl_debug = HCL_DEBUG_NONE; +#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE) +static unsigned int boot_options = OPTION_NONE; +#endif + +/* + * Some Global definitions. + */ +vertex_hdl_t hcl_handle; + +invplace_t invplace_none = { + GRAPH_VERTEX_NONE, + GRAPH_VERTEX_PLACE_NONE, + NULL +}; + +/* + * HCL device driver. + * The purpose of this device driver is to provide a facility + * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path + * to manipulate label entries without having to implement + * system call interfaces. This methodology will enable us to + * make this feature module loadable. + */ +static int hcl_open(struct inode * inode, struct file * filp) +{ + if (hcl_debug) { + printk("HCL: hcl_open called.\n"); + } + + return(0); + +} + +static int hcl_close(struct inode * inode, struct file * filp) +{ + + if (hcl_debug) { + printk("HCL: hcl_close called.\n"); + } + + return(0); + +} + +static int hcl_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + + if (hcl_debug) { + printk("HCL: hcl_ioctl called.\n"); + } + + switch (cmd) { + default: + if (hcl_debug) { + printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd); + } + } + + return(0); + +} + +struct file_operations hcl_fops = { + (struct module *)0, + NULL, /* lseek - default */ + NULL, /* read - general block-dev read */ + NULL, /* write - general block-dev write */ + NULL, /* readdir - bad */ + NULL, /* poll */ + hcl_ioctl, /* ioctl */ + NULL, /* mmap */ + hcl_open, /* open */ + NULL, /* flush */ + hcl_close, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* lock */ + NULL, /* readv */ + NULL, /* writev */ +}; + + +/* + * init_hcl() - Boot time initialization. + * + */ +int __init init_hcl(void) +{ + extern void string_table_init(struct string_table *); + extern struct string_table label_string_table; + extern int init_ifconfig_net(void); + extern int init_ioconfig_bus(void); + extern int init_hwgfs_fs(void); + int rv = 0; + + if (IS_RUNNING_ON_SIMULATOR()) { + extern u64 klgraph_addr[]; + klgraph_addr[0] = 0xe000003000030000; + } + + init_hwgfs_fs(); + + /* + * Create the hwgraph_root. + */ + rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root); + if (rv) + printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv); + + /* + * Create the hcl driver to support inventory entry manipulations. + * + */ + hcl_handle = hwgraph_register(hwgraph_root, ".hcl", + 0, DEVFS_FL_AUTO_DEVNUM, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + &hcl_fops, NULL); + + if (hcl_handle == NULL) { + panic("HCL: Unable to create HCL Driver in init_hcl().\n"); + return(0); + } + + /* + * Initialize the HCL string table. + */ + + string_table_init(&label_string_table); + + /* + * Create the directory that links Linux bus numbers to our Xwidget. + */ + rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum); + if (linux_busnum == NULL) { + panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS); + return(0); + } + + pci_bus_cvlink_init(); + + /* + * Initialize the ifconfgi_net driver that does network devices + * Persistent Naming. + */ + init_ifconfig_net(); + init_ioconfig_bus(); + + return(0); + +} + + +/* + * hcl_setup() - Process boot time parameters if given. + * "hcl=" + * This routine gets called only if "hcl=" is given in the + * boot line and before init_hcl(). + * + * We currently do not have any boot options .. when we do, + * functionalities can be added here. + * + */ +static int __init hcl_setup(char *str) +{ + while ( (*str != '\0') && !isspace (*str) ) + { +#ifdef CONFIG_HCL_DEBUG + if (strncmp (str, "all", 3) == 0) { + hcl_debug_init |= HCL_DEBUG_ALL; + str += 3; + } else + return 0; +#endif + if (*str != ',') return 0; + ++str; + } + + return 1; + +} + +__setup("hcl=", hcl_setup); + + +/* + * Set device specific "fast information". + * + */ +void +hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo) +{ + labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL); +} + + +/* + * Get device specific "fast information". + * + */ +arbitrary_info_t +hwgraph_fastinfo_get(vertex_hdl_t de) +{ + arbitrary_info_t fastinfo; + int rv; + + if (!de) { + printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n"); + return(-1); + } + + rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo); + if (rv == 0) + return(fastinfo); + + return(0); +} + + +/* + * hwgraph_connectpt_set - Sets the connect point handle in de to the + * given connect_de handle. By default, the connect point of the + * node is the parent. This effectively changes this assumption. + */ +int +hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de) +{ + int rv; + + if (!de) + return(-1); + + rv = labelcl_info_connectpt_set(de, connect_de); + + return(rv); +} + + +/* + * hwgraph_connectpt_get: Returns the entry's connect point. + * + */ +vertex_hdl_t +hwgraph_connectpt_get(vertex_hdl_t de) +{ + int rv; + arbitrary_info_t info; + vertex_hdl_t connect; + + rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); + if (rv != 0) { + return(NULL); + } + + connect = (vertex_hdl_t)info; + return(connect); + +} + + +/* + * hwgraph_mk_dir - Creates a directory entry. + */ +vertex_hdl_t +hwgraph_mk_dir(vertex_hdl_t de, const char *name, + unsigned int namelen, void *info) +{ + + int rv; + labelcl_info_t *labelcl_info = NULL; + vertex_hdl_t new_handle = NULL; + vertex_hdl_t parent = NULL; + + /* + * Create the device info structure for hwgraph compatiblity support. + */ + labelcl_info = labelcl_info_create(); + if (!labelcl_info) + return(NULL); + + /* + * Create an entry. + */ + new_handle = hwgfs_mk_dir(de, name, (void *)labelcl_info); + if (!new_handle) { + labelcl_info_destroy(labelcl_info); + return(NULL); + } + + /* + * Get the parent handle. + */ + parent = hwgfs_get_parent (new_handle); + + /* + * To provide the same semantics as the hwgraph, set the connect point. + */ + rv = hwgraph_connectpt_set(new_handle, parent); + if (!rv) { + /* + * We need to clean up! + */ + } + + /* + * If the caller provides a private data pointer, save it in the + * labelcl info structure(fastinfo). This can be retrieved via + * hwgraph_fastinfo_get() + */ + if (info) + hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info); + + return(new_handle); + +} + +/* + * hwgraph_path_add - Create a directory node with the given path starting + * from the given fromv. + */ +int +hwgraph_path_add(vertex_hdl_t fromv, + char *path, + vertex_hdl_t *new_de) +{ + + unsigned int namelen = strlen(path); + int rv; + + /* + * We need to handle the case when fromv is NULL .. + * in this case we need to create the path from the + * hwgraph root! + */ + if (fromv == NULL) + fromv = hwgraph_root; + + /* + * check the entry doesn't already exist, if it does + * then we simply want new_de to point to it (otherwise + * we'll overwrite the existing labelcl_info struct) + */ + rv = hwgraph_edge_get(fromv, path, new_de); + if (rv) { /* couldn't find entry so we create it */ + *new_de = hwgraph_mk_dir(fromv, path, namelen, NULL); + if (new_de == NULL) + return(-1); + else + return(0); + } + else + return(0); + +} + +/* + * hwgraph_register - Creates a special device file. + * + */ +vertex_hdl_t +hwgraph_register(vertex_hdl_t de, const char *name, + unsigned int namelen, unsigned int flags, + unsigned int major, unsigned int minor, + umode_t mode, uid_t uid, gid_t gid, + struct file_operations *fops, + void *info) +{ + + vertex_hdl_t new_handle = NULL; + + /* + * Create an entry. + */ + new_handle = hwgfs_register(de, name, flags, major, + minor, mode, fops, info); + + return(new_handle); + +} + + +/* + * hwgraph_mk_symlink - Create a symbolic link. + */ +int +hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen, + unsigned int flags, const char *link, unsigned int linklen, + vertex_hdl_t *handle, void *info) +{ + + void *labelcl_info = NULL; + int status = 0; + vertex_hdl_t new_handle = NULL; + + /* + * Create the labelcl info structure for hwgraph compatiblity support. + */ + labelcl_info = labelcl_info_create(); + if (!labelcl_info) + return(-1); + + /* + * Create a symbolic link. + */ + status = hwgfs_mk_symlink(de, name, flags, link, + &new_handle, labelcl_info); + if ( (!new_handle) || (!status) ){ + labelcl_info_destroy((labelcl_info_t *)labelcl_info); + return(-1); + } + + /* + * If the caller provides a private data pointer, save it in the + * labelcl info structure(fastinfo). This can be retrieved via + * hwgraph_fastinfo_get() + */ + if (info) + hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info); + + *handle = new_handle; + return(0); + +} + +/* + * hwgraph_vertex_destroy - Destroy the entry + */ +int +hwgraph_vertex_destroy(vertex_hdl_t de) +{ + + void *labelcl_info = NULL; + + labelcl_info = hwgfs_get_info(de); + hwgfs_unregister(de); + + if (labelcl_info) + labelcl_info_destroy((labelcl_info_t *)labelcl_info); + + return(0); +} + +#if 0 +/* + * hwgraph_edge_add - This routines has changed from the original conext. + * All it does now is to create a symbolic link from "from" to "to". + */ +/* ARGSUSED */ +int +hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name) +{ + + char *path, *link; + vertex_hdl_t handle = NULL; + int rv, i; + + handle = hwgfs_find_handle(from, name, 0, 0, 0, 1); + if (handle) { + return(0); + } + + path = kmalloc(1024, GFP_KERNEL); + memset(path, 0x0, 1024); + link = kmalloc(1024, GFP_KERNEL); + memset(path, 0x0, 1024); + i = hwgfs_generate_path (to, link, 1024); + rv = hwgfs_mk_symlink (from, (const char *)name, + DEVFS_FL_DEFAULT, link, + &handle, NULL); + return(0); + + +} +#endif + +int +hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name) +{ + + char *path, *link; + char *s1; + char *index; + vertex_hdl_t handle = NULL; + int rv; + int i, count; + + path = kmalloc(1024, GFP_KERNEL); + memset((char *)path, 0x0, 1024); + link = kmalloc(1024, GFP_KERNEL); + memset((char *)link, 0x0, 1024); + + i = hwgfs_generate_path (from, path, 1024); + s1 = (char *)path; + count = 0; + while (1) { + index = strstr (s1, "/"); + if (index) { + count++; + s1 = ++index; + } else { + count++; + break; + } + } + + for (i = 0; i < count; i++) { + strcat((char *)link,"../"); + } + + memset(path, 0x0, 1024); + i = hwgfs_generate_path (to, path, 1024); + strcat((char *)link, (char *)path); + + /* + * Otherwise, just create a symlink to the vertex. + * In this case the vertex was previous created with a REAL pathname. + */ + rv = hwgfs_mk_symlink (from, (const char *)name, + DEVFS_FL_DEFAULT, link, + &handle, NULL); + kfree(path); + kfree(link); + + return(rv); + + +} + +/* ARGSUSED */ +int +hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr) +{ + + vertex_hdl_t target_handle = NULL; + + if (name == NULL) + return(-1); + + if (toptr == NULL) + return(-1); + + /* + * If the name is "." just return the current entry handle. + */ + if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) { + if (toptr) { + *toptr = from; + } + } else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) { + /* + * Hmmm .. should we return the connect point or parent .. + * see in hwgraph, the concept of parent is the connectpt! + * + * Maybe we should see whether the connectpt is set .. if + * not just return the parent! + */ + target_handle = hwgraph_connectpt_get(from); + if (target_handle) { + /* + * Just return the connect point. + */ + *toptr = target_handle; + return(0); + } + target_handle = hwgfs_get_parent(from); + *toptr = target_handle; + + } else { + target_handle = hwgfs_find_handle (from, name, 0, 0, + 0, 1); /* Yes traverse symbolic links */ + } + + if (target_handle == NULL) + return(-1); + else + *toptr = target_handle; + + return(0); +} + +/* + * hwgraph_info_add_LBL - Adds a new label for the device. Mark the info_desc + * of the label as INFO_DESC_PRIVATE and store the info in the label. + */ +/* ARGSUSED */ +int +hwgraph_info_add_LBL( vertex_hdl_t de, + char *name, + arbitrary_info_t info) +{ + return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info)); +} + +/* + * hwgraph_info_remove_LBL - Remove the label entry for the device. + */ +/* ARGSUSED */ +int +hwgraph_info_remove_LBL( vertex_hdl_t de, + char *name, + arbitrary_info_t *old_info) +{ + return(labelcl_info_remove_LBL(de, name, NULL, old_info)); +} + +/* + * hwgraph_info_replace_LBL - replaces an existing label with + * a new label info value. + */ +/* ARGSUSED */ +int +hwgraph_info_replace_LBL( vertex_hdl_t de, + char *name, + arbitrary_info_t info, + arbitrary_info_t *old_info) +{ + return(labelcl_info_replace_LBL(de, name, + INFO_DESC_PRIVATE, info, + NULL, old_info)); +} +/* + * hwgraph_info_get_LBL - Get and return the info value in the label of the + * device. + */ +/* ARGSUSED */ +int +hwgraph_info_get_LBL(vertex_hdl_t de, + char *name, + arbitrary_info_t *infop) +{ + return(labelcl_info_get_LBL(de, name, NULL, infop)); +} + +/* + * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer + * of the given label for the device. The weird thing is that the label + * that matches the name is return irrespective of the info_desc value! + * Do not understand why the word "exported" is used! + */ +/* ARGSUSED */ +int +hwgraph_info_get_exported_LBL(vertex_hdl_t de, + char *name, + int *export_info, + arbitrary_info_t *infop) +{ + int rc; + arb_info_desc_t info_desc; + + rc = labelcl_info_get_LBL(de, name, &info_desc, infop); + if (rc == 0) + *export_info = (int)info_desc; + + return(rc); +} + +/* + * hwgraph_info_get_next_LBL - Returns the next label info given the + * current label entry in place. + * + * Once again this has no locking or reference count for protection. + * + */ +/* ARGSUSED */ +int +hwgraph_info_get_next_LBL(vertex_hdl_t de, + char *buf, + arbitrary_info_t *infop, + labelcl_info_place_t *place) +{ + return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place)); +} + +/* + * hwgraph_info_export_LBL - Retrieve the specified label entry and modify + * the info_desc field with the given value in nbytes. + */ +/* ARGSUSED */ +int +hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes) +{ + arbitrary_info_t info; + int rc; + + if (nbytes == 0) + nbytes = INFO_DESC_EXPORT; + + if (nbytes < 0) + return(-1); + + rc = labelcl_info_get_LBL(de, name, NULL, &info); + if (rc != 0) + return(rc); + + rc = labelcl_info_replace_LBL(de, name, + nbytes, info, NULL, NULL); + + return(rc); +} + +/* + * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the + * label info_descr filed to INFO_DESC_PRIVATE. + */ +/* ARGSUSED */ +int +hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name) +{ + arbitrary_info_t info; + int rc; + + rc = labelcl_info_get_LBL(de, name, NULL, &info); + if (rc != 0) + return(rc); + + rc = labelcl_info_replace_LBL(de, name, + INFO_DESC_PRIVATE, info, NULL, NULL); + + return(rc); +} + +/* + * hwgraph_path_lookup - return the handle for the given path. + * + */ +int +hwgraph_path_lookup(vertex_hdl_t start_vertex_handle, + char *lookup_path, + vertex_hdl_t *vertex_handle_ptr, + char **remainder) +{ + *vertex_handle_ptr = hwgfs_find_handle(start_vertex_handle, /* start dir */ + lookup_path, /* path */ + 0, /* major */ + 0, /* minor */ + 0, /* char | block */ + 1); /* traverse symlinks */ + if (*vertex_handle_ptr == NULL) + return(-1); + else + return(0); +} + +/* + * hwgraph_traverse - Find and return the handle starting from de. + * + */ +graph_error_t +hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found) +{ + /* + * get the directory entry (path should end in a directory) + */ + + *found = hwgfs_find_handle(de, /* start dir */ + path, /* path */ + 0, /* major */ + 0, /* minor */ + 0, /* char | block */ + 1); /* traverse symlinks */ + if (*found == NULL) + return(GRAPH_NOT_FOUND); + else + return(GRAPH_SUCCESS); +} + +/* + * hwgraph_path_to_vertex - Return the entry handle for the given + * pathname .. assume traverse symlinks too!. + */ +vertex_hdl_t +hwgraph_path_to_vertex(char *path) +{ + return(hwgfs_find_handle(NULL, /* start dir */ + path, /* path */ + 0, /* major */ + 0, /* minor */ + 0, /* char | block */ + 1)); /* traverse symlinks */ +} + +/* + * hwgraph_inventory_remove - Removes an inventory entry. + * + * Remove an inventory item associated with a vertex. It is the caller's + * responsibility to make sure that there are no races between removing + * inventory from a vertex and simultaneously removing that vertex. +*/ +int +hwgraph_inventory_remove( vertex_hdl_t de, + int class, + int type, + major_t controller, + minor_t unit, + int state) +{ + return(0); /* Just a Stub for IRIX code. */ +} + +/* + * Find the canonical name for a given vertex by walking back through + * connectpt's until we hit the hwgraph root vertex (or until we run + * out of buffer space or until something goes wrong). + * + * COMPATIBILITY FUNCTIONALITY + * Walks back through 'parents', not necessarily the same as connectpts. + * + * Need to resolve the fact that does not return the path from + * "/" but rather it just stops right before /dev .. + */ +int +hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen) +{ + char *locbuf; + int pos; + + if (buflen < 1) + return(-1); /* XXX should be GRAPH_BAD_PARAM ? */ + + locbuf = kmalloc(buflen, GFP_KERNEL); + + pos = hwgfs_generate_path(vhdl, locbuf, buflen); + if (pos < 0) { + kfree(locbuf); + return pos; + } + + strcpy(buf, &locbuf[pos]); + kfree(locbuf); + return 0; +} + +/* +** vertex_to_name converts a vertex into a canonical name by walking +** back through connect points until we hit the hwgraph root (or until +** we run out of buffer space). +** +** Usually returns a pointer to the original buffer, filled in as +** appropriate. If the buffer is too small to hold the entire name, +** or if anything goes wrong while determining the name, vertex_to_name +** returns "UnknownDevice". +*/ + +#define DEVNAME_UNKNOWN "UnknownDevice" + +char * +vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen) +{ + if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS) + return(buf); + else + return(DEVNAME_UNKNOWN); +} + +graph_error_t +hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr) +{ + return(GRAPH_ILLEGAL_REQUEST); +} + +graph_error_t +hwgraph_vertex_unref(vertex_hdl_t vhdl) +{ + return(GRAPH_ILLEGAL_REQUEST); +} + + +EXPORT_SYMBOL(hwgraph_mk_dir); +EXPORT_SYMBOL(hwgraph_path_add); +EXPORT_SYMBOL(hwgraph_register); +EXPORT_SYMBOL(hwgraph_vertex_destroy); +EXPORT_SYMBOL(hwgraph_fastinfo_get); +EXPORT_SYMBOL(hwgraph_fastinfo_set); +EXPORT_SYMBOL(hwgraph_connectpt_set); +EXPORT_SYMBOL(hwgraph_connectpt_get); +EXPORT_SYMBOL(hwgraph_info_add_LBL); +EXPORT_SYMBOL(hwgraph_info_remove_LBL); +EXPORT_SYMBOL(hwgraph_info_replace_LBL); +EXPORT_SYMBOL(hwgraph_info_get_LBL); +EXPORT_SYMBOL(hwgraph_info_get_exported_LBL); +EXPORT_SYMBOL(hwgraph_info_get_next_LBL); +EXPORT_SYMBOL(hwgraph_info_export_LBL); +EXPORT_SYMBOL(hwgraph_info_unexport_LBL); +EXPORT_SYMBOL(hwgraph_path_lookup); +EXPORT_SYMBOL(hwgraph_traverse); +EXPORT_SYMBOL(hwgraph_vertex_name_get); diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl_util.c linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl_util.c --- linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl_util.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl_util.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,200 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE; +extern vertex_hdl_t hwgraph_root; + + +/* +** Return the "master" for a given vertex. A master vertex is a +** controller or adapter or other piece of hardware that the given +** vertex passes through on the way to the rest of the system. +*/ +vertex_hdl_t +device_master_get(vertex_hdl_t vhdl) +{ + graph_error_t rc; + vertex_hdl_t master; + + rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master); + if (rc == GRAPH_SUCCESS) + return(master); + else + return(GRAPH_VERTEX_NONE); +} + +/* +** Set the master for a given vertex. +** Returns 0 on success, non-0 indicates failure +*/ +int +device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master) +{ + graph_error_t rc; + + rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER); + return(rc != GRAPH_SUCCESS); +} + + +/* +** Return the compact node id of the node that ultimately "owns" the specified +** vertex. In order to do this, we walk back through masters and connect points +** until we reach a vertex that represents a node. +*/ +cnodeid_t +master_node_get(vertex_hdl_t vhdl) +{ + cnodeid_t cnodeid; + vertex_hdl_t master; + + for (;;) { + cnodeid = nodevertex_to_cnodeid(vhdl); + if (cnodeid != CNODEID_NONE) + return(cnodeid); + + master = device_master_get(vhdl); + + /* Check for exceptional cases */ + if (master == vhdl) { + /* Since we got a reference to the "master" thru + * device_master_get() we should decrement + * its reference count by 1 + */ + return(CNODEID_NONE); + } + + if (master == GRAPH_VERTEX_NONE) { + master = hwgraph_connectpt_get(vhdl); + if ((master == GRAPH_VERTEX_NONE) || + (master == vhdl)) { + return(CNODEID_NONE); + } + } + + vhdl = master; + } +} + +static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE; +extern int maxcpus; + +void +mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid) +{ + if (cpuid == CPU_NONE) + return; + + (void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT, + (arbitrary_info_t)cpuid); + { + char cpuid_buffer[10]; + + if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) { + (void)hwgraph_path_add( hwgraph_root, + EDGE_LBL_CPUNUM, + &hwgraph_all_cpuids); + } + + sprintf(cpuid_buffer, "%ld", cpuid); + (void)hwgraph_edge_add( hwgraph_all_cpuids, + vhdl, + cpuid_buffer); + } +} + +/* +** If the specified device represents a node, return its +** compact node ID; otherwise, return CNODEID_NONE. +*/ +cnodeid_t +nodevertex_to_cnodeid(vertex_hdl_t vhdl) +{ + int rv = 0; + arbitrary_info_t cnodeid = CNODEID_NONE; + + rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid); + + return((cnodeid_t)cnodeid); +} + +void +mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid) +{ + if (cnodeid == CNODEID_NONE) + return; + + cnodeid_to_vertex(cnodeid) = vhdl; + labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, + (arbitrary_info_t)cnodeid); + + { + char cnodeid_buffer[10]; + + if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) { + (void)hwgraph_path_add( hwgraph_root, + EDGE_LBL_NODENUM, + &hwgraph_all_cnodes); + } + + sprintf(cnodeid_buffer, "%d", cnodeid); + (void)hwgraph_edge_add( hwgraph_all_cnodes, + vhdl, + cnodeid_buffer); + } +} + +/* +** If the specified device represents a CPU, return its cpuid; +** otherwise, return CPU_NONE. +*/ +cpuid_t +cpuvertex_to_cpuid(vertex_hdl_t vhdl) +{ + arbitrary_info_t cpuid = CPU_NONE; + + (void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid); + + return((cpuid_t)cpuid); +} + + +/* +** dev_to_name converts a vertex_hdl_t into a canonical name. If the vertex_hdl_t +** represents a vertex in the hardware graph, it is converted in the +** normal way for vertices. If the vertex_hdl_t is an old vertex_hdl_t (one which +** does not represent a hwgraph vertex), we synthesize a name based +** on major/minor number. +** +** Usually returns a pointer to the original buffer, filled in as +** appropriate. If the buffer is too small to hold the entire name, +** or if anything goes wrong while determining the name, dev_to_name +** returns "UnknownDevice". +*/ +char * +dev_to_name(vertex_hdl_t dev, char *buf, uint buflen) +{ + return(vertex_to_name(dev, buf, buflen)); +} + + diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/hwgfs.h linux-2.4.22/arch/ia64/sn/io/hwgfs/hwgfs.h --- linux-2.4.21/arch/ia64/sn/io/hwgfs/hwgfs.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/hwgfs.h 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,23 @@ + +typedef struct dentry *hwgfs_handle_t; + +extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name, + unsigned int flags, + unsigned int major, unsigned int minor, + umode_t mode, void *ops, void *info); +extern int hwgfs_mk_symlink(hwgfs_handle_t dir, const char *name, + unsigned int flags, const char *link, + hwgfs_handle_t *handle, void *info); +extern hwgfs_handle_t hwgfs_mk_dir(hwgfs_handle_t dir, const char *name, + void *info); +extern void hwgfs_unregister(hwgfs_handle_t de); + +extern hwgfs_handle_t hwgfs_find_handle(hwgfs_handle_t dir, const char *name, + unsigned int major,unsigned int minor, + char type, int traverse_symlinks); +extern hwgfs_handle_t hwgfs_get_parent(hwgfs_handle_t de); +extern int hwgfs_generate_path(hwgfs_handle_t de, char *path, int buflen); + +extern void *hwgfs_get_info(hwgfs_handle_t de); +extern int hwgfs_set_info(hwgfs_handle_t de, void *info); + diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/interface.c linux-2.4.22/arch/ia64/sn/io/hwgfs/interface.c --- linux-2.4.21/arch/ia64/sn/io/hwgfs/interface.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/interface.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,326 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ +#include +#include +#include +#include +#include /* needed for smp_lock.h :( */ +#include + +#include + +#include + +extern struct vfsmount *hwgfs_vfsmount; + +/* TODO: Move this to some .h file or, more likely, use a slightly + different interface from lookup_create. */ +extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); + +static int +walk_parents_mkdir( + const char **path, + struct nameidata *nd, + int is_dir) +{ + char *slash; + char buf[strlen(*path)+1]; + int error; + + while ((slash = strchr(*path, '/')) != NULL) { + int len = slash - *path; + memcpy(buf, *path, len); + buf[len] = '\0'; + + error = link_path_walk(buf, nd); + if (unlikely(error)) + return error; + + nd->dentry = lookup_create(nd, is_dir); + if (unlikely(IS_ERR(nd->dentry))) + return PTR_ERR(nd->dentry); + + if (!nd->dentry->d_inode) + error = vfs_mkdir(nd->dentry->d_parent->d_inode, + nd->dentry, 0755); + + up(&nd->dentry->d_parent->d_inode->i_sem); + if (unlikely(error)) + return error; + + *path += len + 1; + } + + return 0; +} + +/* On success, returns with parent_inode->i_sem taken. */ +static int +hwgfs_decode( + hwgfs_handle_t dir, + const char *name, + int is_dir, + struct inode **parent_inode, + struct dentry **dentry) +{ + struct nameidata nd; + int error; + + if (!dir) + dir = hwgfs_vfsmount->mnt_sb->s_root; + + memset(&nd, 0, sizeof(nd)); + nd.flags = LOOKUP_PARENT; + nd.mnt = mntget(hwgfs_vfsmount); + nd.dentry = dget(dir); + + error = walk_parents_mkdir(&name, &nd, is_dir); + if (unlikely(error)) + return error; + + error = link_path_walk(name, &nd); + if (unlikely(error)) + return error; + + *dentry = lookup_create(&nd, is_dir); + + if (unlikely(IS_ERR(*dentry))) + return PTR_ERR(*dentry); + *parent_inode = (*dentry)->d_parent->d_inode; + return 0; +} + +static int +path_len( + struct dentry *de, + struct dentry *root) +{ + int len = 0; + + while (de != root) { + len += de->d_name.len + 1; /* count the '/' */ + de = de->d_parent; + } + return len; /* -1 because we omit the leading '/', + +1 because we include trailing '\0' */ +} + +int +hwgfs_generate_path( + hwgfs_handle_t de, + char *path, + int buflen) +{ + struct dentry *hwgfs_root; + int len; + char *path_orig = path; + + if (unlikely(de == NULL)) + return -EINVAL; + + hwgfs_root = hwgfs_vfsmount->mnt_sb->s_root; + if (unlikely(de == hwgfs_root)) + return -EINVAL; + + spin_lock(&dcache_lock); + len = path_len(de, hwgfs_root); + if (len > buflen) { + spin_unlock(&dcache_lock); + return -ENAMETOOLONG; + } + + path += len - 1; + *path = '\0'; + + for (;;) { + path -= de->d_name.len; + memcpy(path, de->d_name.name, de->d_name.len); + de = de->d_parent; + if (de == hwgfs_root) + break; + *(--path) = '/'; + } + + spin_unlock(&dcache_lock); + BUG_ON(path != path_orig); + return 0; +} + +hwgfs_handle_t +hwgfs_register( + hwgfs_handle_t dir, + const char *name, + unsigned int flags, + unsigned int major, + unsigned int minor, + umode_t mode, + void *ops, + void *info) +{ + dev_t devnum = MKDEV(major, minor); + struct inode *parent_inode; + struct dentry *dentry; + int error; + + error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry); + if (likely(!error)) { + error = vfs_mknod(parent_inode, dentry, mode, devnum); + if (likely(!error)) { + /* + * Do this inside parents i_sem to avoid racing + * with lookups. + */ + if (S_ISCHR(mode)) + dentry->d_inode->i_fop = ops; + dentry->d_fsdata = info; + up(&parent_inode->i_sem); + } else { + up(&parent_inode->i_sem); + dput(dentry); + dentry = NULL; + } + } + + return dentry; +} + +int +hwgfs_mk_symlink( + hwgfs_handle_t dir, + const char *name, + unsigned int flags, + const char *link, + hwgfs_handle_t *handle, + void *info) +{ + struct inode *parent_inode; + struct dentry *dentry; + int error; + + error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry); + if (likely(!error)) { + error = vfs_symlink(parent_inode, dentry, link); + dentry->d_fsdata = info; + if (handle) + *handle = dentry; + up(&parent_inode->i_sem); + /* dput(dentry); */ + } + return error; +} + +hwgfs_handle_t +hwgfs_mk_dir( + hwgfs_handle_t dir, + const char *name, + void *info) +{ + struct inode *parent_inode; + struct dentry *dentry; + int error; + + error = hwgfs_decode(dir, name, 1, &parent_inode, &dentry); + if (likely(!error)) { + error = vfs_mkdir(parent_inode, dentry, 0755); + up(&parent_inode->i_sem); + + if (unlikely(error)) { + dput(dentry); + dentry = NULL; + } else { + dentry->d_fsdata = info; + } + } + return dentry; +} + +void +hwgfs_unregister( + hwgfs_handle_t de) +{ + struct inode *parent_inode = de->d_parent->d_inode; + + if (S_ISDIR(de->d_inode->i_mode)) + vfs_rmdir(parent_inode, de); + else + vfs_unlink(parent_inode, de); +} + +/* XXX: this function is utterly bogus. Every use of it is racy and the + prototype is stupid. You have been warned. --hch. */ +hwgfs_handle_t +hwgfs_find_handle( + hwgfs_handle_t base, + const char *name, + unsigned int major, /* IGNORED */ + unsigned int minor, /* IGNORED */ + char type, /* IGNORED */ + int traverse_symlinks) +{ + struct dentry *dentry = NULL; + struct nameidata nd; + int error; + + BUG_ON(*name=='/'); + + memset(&nd, 0, sizeof(nd)); + + nd.mnt = mntget(hwgfs_vfsmount); + nd.dentry = dget(base ? base : hwgfs_vfsmount->mnt_sb->s_root); + nd.flags = LOOKUP_POSITIVE | (traverse_symlinks ? LOOKUP_FOLLOW : 0); + + error = link_path_walk(name, &nd); + if (likely(!error)) { + dentry = nd.dentry; + path_release(&nd); /* stale data from here! */ + } + + return dentry; +} + +hwgfs_handle_t +hwgfs_get_parent( + hwgfs_handle_t de) +{ + struct dentry *parent; + + lock_kernel(); /* XXX: for LBS this must be dparent_lock */ + parent = de->d_parent; + unlock_kernel(); + + return parent; +} + +int +hwgfs_set_info( + hwgfs_handle_t de, + void *info) +{ + if (unlikely(de == NULL)) + return -EINVAL; + de->d_fsdata = info; + return 0; +} + +void * +hwgfs_get_info( + hwgfs_handle_t de) +{ + return de->d_fsdata; +} + +EXPORT_SYMBOL(hwgfs_generate_path); +EXPORT_SYMBOL(hwgfs_register); +EXPORT_SYMBOL(hwgfs_unregister); +EXPORT_SYMBOL(hwgfs_mk_symlink); +EXPORT_SYMBOL(hwgfs_mk_dir); +EXPORT_SYMBOL(hwgfs_find_handle); +EXPORT_SYMBOL(hwgfs_get_parent); +EXPORT_SYMBOL(hwgfs_set_info); +EXPORT_SYMBOL(hwgfs_get_info); diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/invent_stub.c linux-2.4.22/arch/ia64/sn/io/hwgfs/invent_stub.c --- linux-2.4.21/arch/ia64/sn/io/hwgfs/invent_stub.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/invent_stub.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,148 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +/* + * Hardware Inventory + * + * See sys/sn/invent.h for an explanation of the hardware inventory contents. + * + */ +#include +#include +#include +#include +#include +#include +#include + +void +inventinit(void) +{ +} + +/* + * For initializing/updating an inventory entry. + */ +void +replace_in_inventory( + inventory_t *pinv, int class, int type, + int controller, int unit, int state) +{ +} + +/* + * Inventory addition + * + * XXX NOTE: Currently must be called after dynamic memory allocator is + * initialized. + * + */ +void +add_to_inventory(int class, int type, int controller, int unit, int state) +{ +} + + +/* + * Inventory retrieval + * + * These two routines are intended to prevent the caller from having to know + * the internal structure of the inventory table. + * + * The caller of get_next_inventory is supposed to call start_scan_invent + * before the irst call to get_next_inventory, and the caller is required + * to call end_scan_invent after the last call to get_next_inventory. + */ +inventory_t * +get_next_inventory(invplace_t *place) +{ + return((inventory_t *) NULL); +} + +/* ARGSUSED */ +int +get_sizeof_inventory(int abi) +{ + return sizeof(inventory_t); +} + +/* Must be called prior to first call to get_next_inventory */ +void +start_scan_inventory(invplace_t *iplace) +{ +} + +/* Must be called after last call to get_next_inventory */ +void +end_scan_inventory(invplace_t *iplace) +{ +} + +/* + * Hardware inventory scanner. + * + * Calls fun() for every entry in inventory list unless fun() returns something + * other than 0. + */ +int +scaninvent(int (*fun)(inventory_t *, void *), void *arg) +{ + return 0; +} + +/* + * Find a particular inventory object + * + * pinv can be a pointer to an inventory entry and the search will begin from + * there, or it can be 0 in which case the search starts at the beginning. + * A -1 for any of the other arguments is a wildcard (i.e. it always matches). + */ +inventory_t * +find_inventory(inventory_t *pinv, int class, int type, int controller, + int unit, int state) +{ + return((inventory_t *) NULL); +} + + +/* +** Retrieve inventory data associated with a device. +*/ +inventory_t * +device_inventory_get_next( vertex_hdl_t device, + invplace_t *invplace) +{ + return((inventory_t *) NULL); +} + + +/* +** Associate canonical inventory information with a device (and +** add it to the general inventory). +*/ +void +device_inventory_add( vertex_hdl_t device, + int class, + int type, + major_t controller, + minor_t unit, + int state) +{ +} + +int +device_controller_num_get(vertex_hdl_t device) +{ + return (0); +} + +void +device_controller_num_set(vertex_hdl_t device, int contr_num) +{ +} diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/labelcl.c linux-2.4.22/arch/ia64/sn/io/hwgfs/labelcl.c --- linux-2.4.21/arch/ia64/sn/io/hwgfs/labelcl.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/labelcl.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,657 @@ +/* labelcl - SGI's Hwgraph Compatibility Layer. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2001-2003 Silicon Graphics, Inc. All rights reserved. +*/ + +#include +#include +#include +#include +#include +#include /* needed for smp_lock.h :( */ +#include +#include +#include +#include +#include +#include + +/* +** Very simple and dumb string table that supports only find/insert. +** In practice, if this table gets too large, we may need a more +** efficient data structure. Also note that currently there is no +** way to delete an item once it's added. Therefore, name collision +** will return an error. +*/ + +struct string_table label_string_table; + + + +/* + * string_table_init - Initialize the given string table. + */ +void +string_table_init(struct string_table *string_table) +{ + string_table->string_table_head = NULL; + string_table->string_table_generation = 0; + + /* + * We nedd to initialize locks here! + */ + + return; +} + + +/* + * string_table_destroy - Destroy the given string table. + */ +void +string_table_destroy(struct string_table *string_table) +{ + struct string_table_item *item, *next_item; + + item = string_table->string_table_head; + while (item) { + next_item = item->next; + + STRTBL_FREE(item); + item = next_item; + } + + /* + * We need to destroy whatever lock we have here + */ + + return; +} + + + +/* + * string_table_insert - Insert an entry in the string table .. duplicate + * names are not allowed. + */ +char * +string_table_insert(struct string_table *string_table, char *name) +{ + struct string_table_item *item, *new_item = NULL, *last_item = NULL; + +again: + /* + * Need to lock the table .. + */ + item = string_table->string_table_head; + last_item = NULL; + + while (item) { + if (!strcmp(item->string, name)) { + /* + * If we allocated space for the string and the found that + * someone else already entered it into the string table, + * free the space we just allocated. + */ + if (new_item) + STRTBL_FREE(new_item); + + + /* + * Search optimization: move the found item to the head + * of the list. + */ + if (last_item != NULL) { + last_item->next = item->next; + item->next = string_table->string_table_head; + string_table->string_table_head = item; + } + goto out; + } + last_item = item; + item=item->next; + } + + /* + * name was not found, so add it to the string table. + */ + if (new_item == NULL) { + long old_generation = string_table->string_table_generation; + + new_item = STRTBL_ALLOC(strlen(name)); + + strcpy(new_item->string, name); + + /* + * While we allocated memory for the new string, someone else + * changed the string table. + */ + if (old_generation != string_table->string_table_generation) { + goto again; + } + } else { + /* At this we only have the string table lock in access mode. + * Promote the access lock to an update lock for the string + * table insertion below. + */ + long old_generation = + string_table->string_table_generation; + + /* + * After we did the unlock and wer waiting for update + * lock someone could have potentially updated + * the string table. Check the generation number + * for this case. If it is the case we have to + * try all over again. + */ + if (old_generation != + string_table->string_table_generation) { + goto again; + } + } + + /* + * At this point, we're committed to adding new_item to the string table. + */ + new_item->next = string_table->string_table_head; + item = string_table->string_table_head = new_item; + string_table->string_table_generation++; + +out: + /* + * Need to unlock here. + */ + return(item->string); +} + +/* + * labelcl_info_create - Creates the data structure that will hold the + * device private information asscoiated with a entry. + * The pointer to this structure is what gets stored in the + * (void * info). + */ +labelcl_info_t * +labelcl_info_create() +{ + + labelcl_info_t *new = NULL; + + /* Initial allocation does not include any area for labels */ + if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL ) + return NULL; + + memset (new, 0, sizeof(labelcl_info_t)); + new->hwcl_magic = LABELCL_MAGIC; + return( new); + +} + +/* + * labelcl_info_destroy - Frees the data structure that holds the + * device private information asscoiated with a entry. This + * data structure was created by device_info_create(). + * + * The caller is responsible for nulling the (void *info) in the + * corresponding entry. + */ +int +labelcl_info_destroy(labelcl_info_t *labelcl_info) +{ + + if (labelcl_info == NULL) + return(0); + + /* Free the label list */ + if (labelcl_info->label_list) + kfree(labelcl_info->label_list); + + /* Now free the label info area */ + labelcl_info->hwcl_magic = 0; + kfree(labelcl_info); + + return(0); +} + +/* + * labelcl_info_add_LBL - Adds a new label entry in the labelcl info + * structure. + * + * Error is returned if we find another label with the same name. + */ +int +labelcl_info_add_LBL(vertex_hdl_t de, + char *info_name, + arb_info_desc_t info_desc, + arbitrary_info_t info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + int new_label_list_size; + label_info_t *old_label_list, *new_label_list = NULL; + char *name; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = hwgfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if (info_name == NULL) + return(-1); + + if (strlen(info_name) >= LABEL_LENGTH_MAX) + return(-1); + + name = string_table_insert(&label_string_table, info_name); + + num_labels = labelcl_info->num_labels; + new_label_list_size = sizeof(label_info_t) * (num_labels+1); + + /* + * Create a new label info area. + */ + if (new_label_list_size != 0) { + new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); + + if (new_label_list == NULL) + return(-1); + } + + /* + * At this point, we are committed to adding the labelled info, + * if there isn't already information there with the same name. + */ + old_label_list = labelcl_info->label_list; + + /* + * Look for matching info name. + */ + for (i=0; inum_labels = num_labels+1; + labelcl_info->label_list = new_label_list; + + if (old_label_list != NULL) + kfree(old_label_list); + + return(0); +} + +/* + * labelcl_info_remove_LBL - Remove a label entry. + */ +int +labelcl_info_remove_LBL(vertex_hdl_t de, + char *info_name, + arb_info_desc_t *info_desc, + arbitrary_info_t *info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + int new_label_list_size; + label_info_t *old_label_list, *new_label_list = NULL; + arb_info_desc_t label_desc_found; + arbitrary_info_t label_info_found; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = hwgfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + /* + * Create a new info area. + */ + new_label_list_size = sizeof(label_info_t) * (num_labels-1); + if (new_label_list_size) { + new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); + if (new_label_list == NULL) + return(-1); + } + + /* + * At this point, we are committed to removing the labelled info, + * if it still exists. + */ + old_label_list = labelcl_info->label_list; + + /* + * Find matching info name. + */ + for (i=0; inum_labels = num_labels+1; + labelcl_info->label_list = new_label_list; + + kfree(old_label_list); + + if (info != NULL) + *info = label_info_found; + + if (info_desc != NULL) + *info_desc = label_desc_found; + + return(0); +} + + +/* + * labelcl_info_replace_LBL - Replace an existing label entry with the + * given new information. + * + * Label entry must exist. + */ +int +labelcl_info_replace_LBL(vertex_hdl_t de, + char *info_name, + arb_info_desc_t info_desc, + arbitrary_info_t info, + arb_info_desc_t *old_info_desc, + arbitrary_info_t *old_info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + label_info_t *label_list; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = hwgfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + if (info_name == NULL) + return(-1); + + label_list = labelcl_info->label_list; + + /* + * Verify that information under info_name already exists. + */ + for (i=0; ihwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + label_list = labelcl_info->label_list; + + /* + * Find information under info_name. + */ + for (i=0; ihwcl_magic != LABELCL_MAGIC) + return(-1); + + which_info = *placeptr; + + if (which_info >= labelcl_info->num_labels) { + return(-1); + } + + label_list = (label_info_t *) labelcl_info->label_list; + + if (buffer != NULL) + strcpy(buffer, label_list[which_info].name); + + if (infop) + *infop = label_list[which_info].info; + + if (info_descp) + *info_descp = label_list[which_info].desc; + + *placeptr = which_info + 1; + + return(0); +} + + +int +labelcl_info_replace_IDX(vertex_hdl_t de, + int index, + arbitrary_info_t info, + arbitrary_info_t *old_info) +{ + arbitrary_info_t *info_list_IDX; + labelcl_info_t *labelcl_info = NULL; + + if (de == NULL) { + printk(KERN_ALERT "labelcl: NULL handle given.\n"); + return(-1); + } + + labelcl_info = hwgfs_get_info(de); + if (labelcl_info == NULL) { + printk(KERN_ALERT "labelcl: Entry %p does not have info pointer.\n", (void *)de); + return(-1); + } + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) + return(-1); + + /* + * Replace information at the appropriate index in this vertex with + * the new info. + */ + info_list_IDX = labelcl_info->IDX_list; + if (old_info != NULL) + *old_info = info_list_IDX[index]; + info_list_IDX[index] = info; + + return(0); + +} + +/* + * labelcl_info_connectpt_set - Sets the connectpt. + */ +int +labelcl_info_connectpt_set(hwgfs_handle_t de, + hwgfs_handle_t connect_de) +{ + arbitrary_info_t old_info; + int rv; + + rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, + (arbitrary_info_t) connect_de, &old_info); + + if (rv) { + return(rv); + } + + return(0); +} + + +/* + * labelcl_info_get_IDX - Returns the information pointed at by index. + * + */ +int +labelcl_info_get_IDX(vertex_hdl_t de, + int index, + arbitrary_info_t *info) +{ + arbitrary_info_t *info_list_IDX; + labelcl_info_t *labelcl_info = NULL; + + if (de == NULL) + return(-1); + + labelcl_info = hwgfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) + return(-1); + + /* + * Return information at the appropriate index in this vertex. + */ + info_list_IDX = labelcl_info->IDX_list; + if (info != NULL) + *info = info_list_IDX[index]; + + return(0); +} + +/* + * labelcl_info_connectpt_get - Retrieve the connect point for a device entry. + */ +hwgfs_handle_t +labelcl_info_connectpt_get(hwgfs_handle_t de) +{ + int rv; + arbitrary_info_t info; + + rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); + if (rv) + return(NULL); + + return((hwgfs_handle_t) info); +} diff -urN linux-2.4.21/arch/ia64/sn/io/hwgfs/ramfs.c linux-2.4.22/arch/ia64/sn/io/hwgfs/ramfs.c --- linux-2.4.21/arch/ia64/sn/io/hwgfs/ramfs.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/hwgfs/ramfs.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,341 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* some random number */ +#define HWGFS_MAGIC 0x12061983 + +static struct super_operations hwgfs_ops; +static struct address_space_operations hwgfs_aops; +static struct file_operations hwgfs_file_operations; +static struct inode_operations hwgfs_dir_inode_operations; + +static int hwgfs_statfs(struct super_block *sb, struct statfs *buf) +{ + buf->f_type = HWGFS_MAGIC; + buf->f_bsize = PAGE_CACHE_SIZE; + buf->f_namelen = 255; + return 0; +} + +/* + * Lookup the data. This is trivial - if the dentry didn't already + * exist, we know it is negative. + */ +static struct dentry * hwgfs_lookup(struct inode *dir, struct dentry *dentry) +{ + d_add(dentry, NULL); + return NULL; +} + +/* + * Read a page. Again trivial. If it didn't already exist + * in the page cache, it is zero-filled. + */ +static int hwgfs_readpage(struct file *file, struct page * page) +{ + if (!Page_Uptodate(page)) { + memset(kmap(page), 0, PAGE_CACHE_SIZE); + kunmap(page); + flush_dcache_page(page); + SetPageUptodate(page); + } + UnlockPage(page); + return 0; +} + +static int hwgfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) +{ + void *addr = kmap(page); + if (!Page_Uptodate(page)) { + memset(addr, 0, PAGE_CACHE_SIZE); + flush_dcache_page(page); + SetPageUptodate(page); + } + SetPageDirty(page); + return 0; +} + +static int hwgfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) +{ + struct inode *inode = page->mapping->host; + loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; + + kunmap(page); + if (pos > inode->i_size) + inode->i_size = pos; + return 0; +} + +struct inode *hwgfs_get_inode(struct super_block *sb, int mode, int dev) +{ + struct inode * inode = new_inode(sb); + + if (inode) { + inode->i_mode = mode; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_blksize = PAGE_CACHE_SIZE; + inode->i_blocks = 0; + inode->i_rdev = NODEV; + inode->i_mapping->a_ops = &hwgfs_aops; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + switch (mode & S_IFMT) { + default: + init_special_inode(inode, mode, dev); + break; + case S_IFREG: + inode->i_fop = &hwgfs_file_operations; + break; + case S_IFDIR: + inode->i_op = &hwgfs_dir_inode_operations; + inode->i_fop = &dcache_dir_ops; + break; + case S_IFLNK: + inode->i_op = &page_symlink_inode_operations; + break; + } + } + return inode; +} + +/* + * File creation. Allocate an inode, and we're done.. + */ +static int hwgfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) +{ + struct inode * inode = hwgfs_get_inode(dir->i_sb, mode, dev); + int error = -ENOSPC; + + if (inode) { + d_instantiate(dentry, inode); + dget(dentry); /* Extra count - pin the dentry in core */ + error = 0; + } + return error; +} + +static int hwgfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) +{ + return hwgfs_mknod(dir, dentry, mode | S_IFDIR, 0); +} + +static int hwgfs_create(struct inode *dir, struct dentry *dentry, int mode) +{ + return hwgfs_mknod(dir, dentry, mode | S_IFREG, 0); +} + +/* + * Link a file.. + */ +static int hwgfs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry) +{ + struct inode *inode = old_dentry->d_inode; + + if (S_ISDIR(inode->i_mode)) + return -EPERM; + + inode->i_nlink++; + atomic_inc(&inode->i_count); /* New dentry reference */ + dget(dentry); /* Extra pinning count for the created dentry */ + d_instantiate(dentry, inode); + return 0; +} + +static inline int hwgfs_positive(struct dentry *dentry) +{ + return dentry->d_inode && !d_unhashed(dentry); +} + +/* + * Check that a directory is empty (this works + * for regular files too, they'll just always be + * considered empty..). + * + * Note that an empty directory can still have + * children, they just all have to be negative.. + */ +static int hwgfs_empty(struct dentry *dentry) +{ + struct list_head *list; + + spin_lock(&dcache_lock); + list = dentry->d_subdirs.next; + + while (list != &dentry->d_subdirs) { + struct dentry *de = list_entry(list, struct dentry, d_child); + + if (hwgfs_positive(de)) { + spin_unlock(&dcache_lock); + return 0; + } + list = list->next; + } + spin_unlock(&dcache_lock); + return 1; +} + +/* + * This works for both directories and regular files. + * (non-directories will always have empty subdirs) + */ +static int hwgfs_unlink(struct inode * dir, struct dentry *dentry) +{ + int retval = -ENOTEMPTY; + + if (hwgfs_empty(dentry)) { + struct inode *inode = dentry->d_inode; + + inode->i_nlink--; + dput(dentry); /* Undo the count from "create" - this does all the work */ + retval = 0; + } + return retval; +} + +#define hwgfs_rmdir hwgfs_unlink + +/* + * The VFS layer already does all the dentry stuff for rename, + * we just have to decrement the usage count for the target if + * it exists so that the VFS layer correctly free's it when it + * gets overwritten. + */ +static int hwgfs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry) +{ + int error = -ENOTEMPTY; + + if (hwgfs_empty(new_dentry)) { + struct inode *inode = new_dentry->d_inode; + if (inode) { + inode->i_nlink--; + dput(new_dentry); + } + error = 0; + } + return error; +} + +static int hwgfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) +{ + int error; + + error = hwgfs_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0); + if (!error) { + int l = strlen(symname)+1; + struct inode *inode = dentry->d_inode; + error = block_symlink(inode, symname, l); + } + return error; +} + +static int hwgfs_sync_file(struct file * file, struct dentry *dentry, int datasync) +{ + return 0; +} + +static struct address_space_operations hwgfs_aops = { + .readpage = hwgfs_readpage, + .writepage = fail_writepage, + .prepare_write = hwgfs_prepare_write, + .commit_write = hwgfs_commit_write +}; + +static struct file_operations hwgfs_file_operations = { + .read = generic_file_read, + .write = generic_file_write, + .mmap = generic_file_mmap, + .fsync = hwgfs_sync_file, +}; + +static struct inode_operations hwgfs_dir_inode_operations = { + .create = hwgfs_create, + .lookup = hwgfs_lookup, + .link = hwgfs_link, + .unlink = hwgfs_unlink, + .symlink = hwgfs_symlink, + .mkdir = hwgfs_mkdir, + .rmdir = hwgfs_rmdir, + .mknod = hwgfs_mknod, + .rename = hwgfs_rename, +}; + +static struct super_operations hwgfs_ops = { + .statfs = hwgfs_statfs, + .put_inode = force_delete, +}; + +static struct super_block *hwgfs_read_super(struct super_block * sb, void * data, int silent) +{ + struct inode * inode; + struct dentry * root; + + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + sb->s_magic = HWGFS_MAGIC; + sb->s_op = &hwgfs_ops; + inode = hwgfs_get_inode(sb, S_IFDIR | 0755, 0); + if (!inode) + return NULL; + + root = d_alloc_root(inode); + if (!root) { + iput(inode); + return NULL; + } + sb->s_root = root; + return sb; +} + +static struct file_system_type hwgfs_fs_type = { + .owner = THIS_MODULE, + .name = "hwgfs", + .read_super = hwgfs_read_super, + .fs_flags = FS_SINGLE|FS_LITTER, +}; + +struct vfsmount *hwgfs_vfsmount; + +int __init init_hwgfs_fs(void) +{ + int error; + + if (!ia64_platform_is("sn2")) + return -ENODEV; + + error = register_filesystem(&hwgfs_fs_type); + if (error) + return error; + + hwgfs_vfsmount = kern_mount(&hwgfs_fs_type); + if (IS_ERR(hwgfs_vfsmount)) + goto fail; + return 0; + +fail: + unregister_filesystem(&hwgfs_fs_type); + return PTR_ERR(hwgfs_vfsmount); +} + +static void __exit exit_hwgfs_fs(void) +{ + unregister_filesystem(&hwgfs_fs_type); +} + +MODULE_LICENSE("GPL"); + +module_init(init_hwgfs_fs) +module_exit(exit_hwgfs_fs) diff -urN linux-2.4.21/arch/ia64/sn/io/ifconfig_bus.c linux-2.4.22/arch/ia64/sn/io/ifconfig_bus.c --- linux-2.4.21/arch/ia64/sn/io/ifconfig_bus.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/ifconfig_bus.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,345 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * ifconfig_bus - SGI's Persistent PCI Bus Numbering. - * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SGI_IFCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING" -#define SGI_IFCONFIG_BUS_VERSION "1.0" - -/* - * Some Global definitions. - */ -devfs_handle_t ioconfig_bus_handle = NULL; -unsigned long ioconfig_bus_debug = 0; - -#define IFCONFIG_BUS_DEBUG 1 -#ifdef IFCONFIG_BUS_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -u64 ioconfig_file = 0; -u64 ioconfig_file_size = 0; - - -/* - * PCI Bus Name for PCI - * module/001c02/Ibrick/xtalk/14/pci - only 1 bus per widget - * - * PCI Bus Name for PCI-X - * module/001c02/Ibrick/xtalk/14/pci-x/0 - PCI bus 0 on Widget 14 - * module/001c02/Ibrick/xtalk/14/pci-x/1 - PCI bus 1 on Widget 14 - */ - -struct pcipath_to_busnum{ - unsigned int num; /* persistent bus number */ - unsigned int len; /* pci path length */ - unsigned char path[120]; /* pci path name */ -}; - -struct pcipath_to_busnum *ioconfig_bus_table; -u64 ioconfig_bus_table_size = 0; - - -struct pcipath_to_busnum pcibus_names[256]; - -/* - * highest_pcibus_num : The highest PCI bus number allocated. Use for next - * PCI Bus Number to be assigned. - * pcibus_names_index : The starting entry of any new configuration. It also - * tracks the number of old config in the table. - * current_index : Next free index in the table for new config. - * current_index - pcibus_names_index = number new config. - */ - -int highest_pcibus_num = 0; -int pcibus_names_index = 0; /* Start of new config */ -int current_index = 0; /* Next entry for new config */ - -/* - * ioconfig_get_busnum(): - * ioconfig_get_busnum() returns the bus number given a pci path name. - * If the pci path name exist in the persistent naming table, the - * corresponding bun number is returned. If the pci path name does not - * exist, the next bus number is assigned to that path, added to the - * persistent naming table and the new bus num returned. - */ -void -ioconfig_get_busnum(char *pci_path, int *bus_num) -{ - struct pcipath_to_busnum *temp; - int index; - - *bus_num = -1; - temp = ioconfig_bus_table; - for (index = 0; index < current_index; ioconfig_bus_table++, index++) { - if ( (strncmp(pci_path, ioconfig_bus_table->path, strlen(pci_path) == 0)) ){ - *bus_num = ioconfig_bus_table->num; - return; - } - } - - /* - * This is a new path and it is not in the config table. - * Add it to the end. - */ - *bus_num = highest_pcibus_num; - highest_pcibus_num++; - ioconfig_bus_table->num = *bus_num; - strcpy((char *)&(ioconfig_bus_table->path), pci_path); - ioconfig_bus_table->len = strlen(pci_path); - current_index++; - -} - -void -dump_ioconfig_table(struct pcipath_to_busnum *ioconfig_bus_table) -{ - - int index = 0; - struct pcipath_to_busnum *temp; - - temp = ioconfig_bus_table; - while (index < pcibus_names_index) { - printk("Bus Number %d PCI path %s\n", temp->num, temp->path); - temp++; - index++; - } - -} -/* - * nextline - * This routine returns the nextline in the buffer. - */ -int nextline(char *buffer, char **next, char *line) -{ - - char *temp; - - if (buffer[0] == 0x0) { - return(0); - } - - temp = buffer; - while (*temp != 0) { - *line = *temp; - if (*temp != '\n'){ - *line = *temp; - temp++; line++; - } else - break; - } - - if (*temp == 0) - *next = temp; - else - *next = ++temp; - - return(1); -} - -/* - * build_pcibus_name - * This routine parses the ioconfig contents read into - * memory by ioconfig command in EFI and builds the - * persistent pci bus naming table. - */ -void -build_pcibus_name(char *file_contents, struct pcipath_to_busnum *table) -{ - /* - * Read the whole file into memory. - */ - int busnum; - int rc; - char *name; - char *temp; - char *next; - char *current; - char *line; - struct pcipath_to_busnum *pcibus; - - line = kmalloc(256, GFP_KERNEL); - memset(line, 0,256); - name = kmalloc(125, GFP_KERNEL); - memset(name, 0, 125); - pcibus = table; - current = file_contents; - while (nextline(current, &next, line)){ -printk("current 0x%lx next 0x%lx\n", current, next); - temp = line; - /* - * Skip all leading Blank lines .. - */ - while (isspace(*temp)) - if (*temp != '\n') - temp++; - else - break; - - if (*temp == '\n') { - current = next; - memset(line, 0, 256); - continue; - } - - /* - * Skip comment lines - */ - if (*temp == '#') { - current = next; - memset(line, 0, 256); - continue; - } - - /* - * Get the next free entry in the table. - */ - rc = sscanf(temp, "%d %s", &busnum, name); - pcibus->num = busnum; - pcibus->len = strlen(name); - strcpy(&pcibus->path[0], name); - DBG("pci number = %d pci path = %s\n", pcibus->num, pcibus->path); - if (busnum > highest_pcibus_num) - highest_pcibus_num = busnum; - else - highest_pcibus_num = busnum; - - pcibus_names_index++; - pcibus++; - current = next; - memset(line, 0, 256); - } - - DBG("highest_pcibus_num %d pcibus_names_index %d\n", highest_pcibus_num, pcibus_names_index); - - current_index = pcibus_names_index; - kfree(line); - kfree(name); - - return; -} - -void -ioconfig_bus_init(void) -{ - - struct ia64_sal_retval ret_stuff; - - DBG("ioconfig_bus_init called.\n"); - - /* - * Make SAL call to get the address of the bus configuration table. - */ - ret_stuff.status = (uint64_t)0; - ret_stuff.v0 = (uint64_t)0; - ret_stuff.v1 = (uint64_t)0; - ret_stuff.v2 = (uint64_t)0; - SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, get_nasid(), 0, 0, 0, 0, 0); - if (ret_stuff.status != 0) { - DBG("ifconfig_bus_init: No Address given\n"); - } - - ioconfig_file = ret_stuff.v0; - ioconfig_file_size = ret_stuff.v1; - DBG("ioconfig_bus_init: ioconfig_file %p %d\n", - (void *)ioconfig_file, (int)ioconfig_file_size); - - /* - * Convert the address to a Cache Address. - */ - ioconfig_file = (CACHEABLE_MEM_SPACE | - (ioconfig_file & TO_PHYS_MASK)); - - ioconfig_bus_table = kmalloc( 512*sizeof(struct pcipath_to_busnum), - GFP_KERNEL ); - - DBG("ioconfig_bus_init: Kernel virtual ioconfig_file %p ioconfig_bus_table %p\n", - (void *)ioconfig_file, (void *)ioconfig_bus_table); - - (void) build_pcibus_name((char *)ioconfig_file, ioconfig_bus_table); - - (void) dump_ioconfig_table(ioconfig_bus_table); - -} - -/* - * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus". - */ -static int ioconfig_bus_open(struct inode * inode, struct file * filp) -{ - if (ioconfig_bus_debug) { - printk("ioconfig_bus_open called.\n"); - } - - return(0); - -} - -/* - * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus". - */ -static int ioconfig_bus_close(struct inode * inode, struct file * filp) -{ - - if (ioconfig_bus_debug) { - printk("ioconfig_bus_close called.\n"); - } - - return(0); -} - -struct file_operations ioconfig_bus_fops = { - /* ioctl:ioconfig_bus_ioctl, ioctl */ - open:ioconfig_bus_open, /* open */ - release:ioconfig_bus_close /* release */ -}; - - -/* - * init_ifconfig_net() - Boot time initialization. Ensure that it is called - * after devfs has been initialized. - * - */ -int init_ioconfig_bus(void) -{ - ioconfig_bus_handle = NULL; - ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus", - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &ioconfig_bus_fops, NULL); - - if (ioconfig_bus_handle == NULL) { - panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n"); - } - - return(0); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/ifconfig_net.c linux-2.4.22/arch/ia64/sn/io/ifconfig_net.c --- linux-2.4.21/arch/ia64/sn/io/ifconfig_net.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/ifconfig_net.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,298 +0,0 @@ -/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * ifconfig_net - SGI's Persistent Network Device names. - * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER" -#define SGI_IFCONFIG_NET_VERSION "1.0" - -/* - * Some Global definitions. - */ -devfs_handle_t ifconfig_net_handle = NULL; -unsigned long ifconfig_net_debug = 0; - -/* - * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net". - */ -static int ifconfig_net_open(struct inode * inode, struct file * filp) -{ - if (ifconfig_net_debug) { - printk("ifconfig_net_open called.\n"); - } - - return(0); - -} - -/* - * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net". - */ -static int ifconfig_net_close(struct inode * inode, struct file * filp) -{ - - if (ifconfig_net_debug) { - printk("ifconfig_net_close called.\n"); - } - - return(0); -} - -/* - * assign_ifname - Assign the next available interface name from the persistent list. - */ -void -assign_ifname(struct net_device *dev, - struct ifname_num *ifname_num) - -{ - - /* - * Handle eth devices. - */ - if ( (memcmp(dev->name, "eth", 3) == 0) ) { - if (ifname_num->next_eth != -1) { - /* - * Assign it the next available eth interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "eth%d", (int)ifname_num->next_eth); - ifname_num->next_eth++; - } - - return; - } - - /* - * Handle fddi devices. - */ - if ( (memcmp(dev->name, "fddi", 4) == 0) ) { - if (ifname_num->next_fddi != -1) { - /* - * Assign it the next available fddi interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi); - ifname_num->next_fddi++; - } - - return; - } - - /* - * Handle hip devices. - */ - if ( (memcmp(dev->name, "hip", 3) == 0) ) { - if (ifname_num->next_hip != -1) { - /* - * Assign it the next available hip interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "hip%d", (int)ifname_num->next_hip); - ifname_num->next_hip++; - } - - return; - } - - /* - * Handle tr devices. - */ - if ( (memcmp(dev->name, "tr", 2) == 0) ) { - if (ifname_num->next_tr != -1) { - /* - * Assign it the next available tr interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "tr%d", (int)ifname_num->next_tr); - ifname_num->next_tr++; - } - - return; - } - - /* - * Handle fc devices. - */ - if ( (memcmp(dev->name, "fc", 2) == 0) ) { - if (ifname_num->next_fc != -1) { - /* - * Assign it the next available fc interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "fc%d", (int)ifname_num->next_fc); - ifname_num->next_fc++; - } - - return; - } -} - -/* - * find_persistent_ifname: Returns the entry that was seen in previous boot. - */ -struct ifname_MAC * -find_persistent_ifname(struct net_device *dev, - struct ifname_MAC *ifname_MAC) - -{ - - while (ifname_MAC->addr_len) { - if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0) - return(ifname_MAC); - - ifname_MAC++; - } - - return(NULL); -} - -/* - * ifconfig_net_ioctl: ifconfig_net driver ioctl interface. - */ -static int ifconfig_net_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - - extern struct net_device *__dev_get_by_name(const char *); -#ifdef CONFIG_NET - struct net_device *dev; - struct ifname_MAC *found; - char temp[64]; -#endif - struct ifname_MAC *ifname_MAC; - struct ifname_MAC *new_devices, *temp_new_devices; - struct ifname_num *ifname_num; - unsigned long size; - - - if (ifconfig_net_debug) { - printk("HCL: hcl_ioctl called.\n"); - } - - /* - * Read in the header and see how big of a buffer we really need to - * allocate. - */ - ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), - GFP_KERNEL); - copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num)); - size = ifname_num->size; - kfree(ifname_num); - ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL); - ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) ); - - copy_from_user( ifname_num, (char *) arg, size); - new_devices = kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL); - temp_new_devices = new_devices; - - memset(new_devices, 0, size - sizeof(struct ifname_num)); - -#ifdef CONFIG_NET - /* - * Go through the net device entries and make them persistent! - */ - for (dev = dev_base; dev != NULL; dev = dev->next) { - /* - * Skip NULL entries or "lo" - */ - if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){ - continue; - } - - /* - * See if we have a persistent interface name for this device. - */ - found = NULL; - found = find_persistent_ifname(dev, ifname_MAC); - if (found) { - strcpy(dev->name, found->name); - } else { - /* Never seen this before .. */ - assign_ifname(dev, ifname_num); - - /* - * Save the information for the next boot. - */ - sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - strcpy(temp_new_devices->name, dev->name); - temp_new_devices->addr_len = dev->addr_len; - memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len); - temp_new_devices++; - } - - } -#endif - - /* - * Copy back to the User Buffer area any new devices encountered. - */ - copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, - size - sizeof(struct ifname_num)); - - return(0); - -} - -struct file_operations ifconfig_net_fops = { - ioctl:ifconfig_net_ioctl, /* ioctl */ - open:ifconfig_net_open, /* open */ - release:ifconfig_net_close /* release */ -}; - - -/* - * init_ifconfig_net() - Boot time initialization. Ensure that it is called - * after devfs has been initialized. - * - */ -#ifdef MODULE -int init_module (void) -#else -int __init init_ifconfig_net(void) -#endif -{ - ifconfig_net_handle = NULL; - ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net", - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &ifconfig_net_fops, NULL); - - if (ifconfig_net_handle == NULL) { - panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n"); - } - - return(0); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/invent.c linux-2.4.22/arch/ia64/sn/io/invent.c --- linux-2.4.21/arch/ia64/sn/io/invent.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/invent.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,224 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * Hardware Inventory - * - * See sys/sn/invent.h for an explanation of the hardware inventory contents. - * - */ -#include -#include -#include -#include -#include - -void -inventinit(void) -{ -} - -/* - * For initializing/updating an inventory entry. - */ -void -replace_in_inventory( - inventory_t *pinv, int class, int type, - int controller, int unit, int state) -{ - pinv->inv_class = class; - pinv->inv_type = type; - pinv->inv_controller = controller; - pinv->inv_unit = unit; - pinv->inv_state = state; -} - -/* - * Inventory addition - * - * XXX NOTE: Currently must be called after dynamic memory allocator is - * initialized. - * - */ -void -add_to_inventory(int class, int type, int controller, int unit, int state) -{ - (void)device_inventory_add((devfs_handle_t)GRAPH_VERTEX_NONE, class, type, - controller, unit, state); -} - - -/* - * Inventory retrieval - * - * These two routines are intended to prevent the caller from having to know - * the internal structure of the inventory table. - * - * The caller of get_next_inventory is supposed to call start_scan_invent - * before the irst call to get_next_inventory, and the caller is required - * to call end_scan_invent after the last call to get_next_inventory. - */ -inventory_t * -get_next_inventory(invplace_t *place) -{ - inventory_t *pinv; - devfs_handle_t device = place->invplace_vhdl; - int rv; - - while ((pinv = device_inventory_get_next(device, place)) == NULL) { - /* - * We've exhausted inventory items on the last device. - * Advance to next device. - */ - place->invplace_inv = NULL; /* Start from beginning invent on this device */ - rv = hwgraph_vertex_get_next(&device, &place->invplace_vplace); - if (rv == LABELCL_SUCCESS) { - place->invplace_vhdl = device; - } - else { - place->invplace_vhdl = GRAPH_VERTEX_NONE; - return(NULL); - } - } - - return(pinv); -} - -/* ARGSUSED */ -int -get_sizeof_inventory(int abi) -{ - return sizeof(inventory_t); -} - -/* Must be called prior to first call to get_next_inventory */ -void -start_scan_inventory(invplace_t *iplace) -{ - *iplace = INVPLACE_NONE; -} - -/* Must be called after last call to get_next_inventory */ -void -end_scan_inventory(invplace_t *iplace) -{ - devfs_handle_t vhdl = iplace->invplace_vhdl; - if (vhdl != GRAPH_VERTEX_NONE) - hwgraph_vertex_unref(vhdl); - *iplace = INVPLACE_NONE; /* paranoia */ -} - -/* - * Hardware inventory scanner. - * - * Calls fun() for every entry in inventory list unless fun() returns something - * other than 0. - */ -int -scaninvent(int (*fun)(inventory_t *, void *), void *arg) -{ - inventory_t *ie; - invplace_t iplace = { NULL,NULL, NULL }; - int rc; - - ie = 0; - rc = 0; - start_scan_inventory(&iplace); - while ((ie = (inventory_t *)get_next_inventory(&iplace))) { - rc = (*fun)(ie, arg); - if (rc) - break; - } - end_scan_inventory(&iplace); - return rc; -} - -/* - * Find a particular inventory object - * - * pinv can be a pointer to an inventory entry and the search will begin from - * there, or it can be 0 in which case the search starts at the beginning. - * A -1 for any of the other arguments is a wildcard (i.e. it always matches). - */ -inventory_t * -find_inventory(inventory_t *pinv, int class, int type, int controller, - int unit, int state) -{ - invplace_t iplace = { NULL,NULL, NULL }; - - start_scan_inventory(&iplace); - while ((pinv = (inventory_t *)get_next_inventory(&iplace)) != NULL) { - if (class != -1 && pinv->inv_class != class) - continue; - if (type != -1 && pinv->inv_type != type) - continue; - - /* XXXX - perhaps the "state" entry should be ignored so an - * an existing entry can be updated. See vino_init() and - * ml/IP22.c:add_ioboard() for an example. - */ - if (state != -1 && pinv->inv_state != state) - continue; - if (controller != -1 - && pinv->inv_controller != controller) - continue; - if (unit != -1 && pinv->inv_unit != unit) - continue; - break; - } - end_scan_inventory(&iplace); - - return(pinv); -} - - -/* -** Retrieve inventory data associated with a device. -*/ -inventory_t * -device_inventory_get_next( devfs_handle_t device, - invplace_t *invplace) -{ - inventory_t *pinv; - int rv; - - rv = hwgraph_inventory_get_next(device, invplace, &pinv); - if (rv == LABELCL_SUCCESS) - return(pinv); - else - return(NULL); -} - - -/* -** Associate canonical inventory information with a device (and -** add it to the general inventory). -*/ -void -device_inventory_add( devfs_handle_t device, - int class, - int type, - major_t controller, - minor_t unit, - int state) -{ - hwgraph_inventory_add(device, class, type, controller, unit, state); -} - -int -device_controller_num_get(devfs_handle_t device) -{ - return (hwgraph_controller_num_get(device)); -} - -void -device_controller_num_set(devfs_handle_t device, int contr_num) -{ - hwgraph_controller_num_set(device, contr_num); -} diff -urN linux-2.4.21/arch/ia64/sn/io/io.c linux-2.4.22/arch/ia64/sn/io/io.c --- linux-2.4.21/arch/ia64/sn/io/io.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/io.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ #include @@ -29,17 +29,11 @@ #include extern xtalk_provider_t hub_provider; -extern void hub_intr_init(devfs_handle_t hubv); +extern void hub_intr_init(vertex_hdl_t hubv); +static int force_fire_and_forget = 1; +static int ignore_conveyor_override; -/* - * Perform any initializations needed to support hub-based I/O. - * Called once during startup. - */ -void -hubio_init(void) -{ -} /* * Implementation of hub iobus operations. @@ -58,8 +52,8 @@ /* * Setup pio structures needed for a particular hub. */ -void -hub_pio_init(devfs_handle_t hubv) +static void +hub_pio_init(vertex_hdl_t hubv) { xwidgetnum_t widget; hubinfo_t hubinfo; @@ -114,7 +108,7 @@ */ /* ARGSUSED */ hub_piomap_t -hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ +hub_piomap_alloc(vertex_hdl_t dev, /* set up mapping for this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ size_t byte_count, @@ -123,7 +117,7 @@ { xwidget_info_t widget_info = xwidget_info_get(dev); xwidgetnum_t widget = xwidget_info_id_get(widget_info); - devfs_handle_t hubv = xwidget_info_master_get(widget_info); + vertex_hdl_t hubv = xwidget_info_master_get(widget_info); hubinfo_t hubinfo; hub_piomap_t bw_piomap; int bigwin, free_bw_index; @@ -288,7 +282,7 @@ void hub_piomap_free(hub_piomap_t hub_piomap) { - devfs_handle_t hubv; + vertex_hdl_t hubv; hubinfo_t hubinfo; nasid_t nasid; unsigned long s; @@ -371,7 +365,7 @@ */ /* ARGSUSED */ caddr_t -hub_piotrans_addr( devfs_handle_t dev, /* translate to this device */ +hub_piotrans_addr( vertex_hdl_t dev, /* translate to this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t xtalk_addr, /* Crosstalk address */ size_t byte_count, /* map this many bytes */ @@ -379,7 +373,7 @@ { xwidget_info_t widget_info = xwidget_info_get(dev); xwidgetnum_t widget = xwidget_info_id_get(widget_info); - devfs_handle_t hubv = xwidget_info_master_get(widget_info); + vertex_hdl_t hubv = xwidget_info_master_get(widget_info); hub_piomap_t hub_piomap; hubinfo_t hubinfo; caddr_t addr; @@ -416,7 +410,7 @@ */ /* ARGSUSED */ hub_dmamap_t -hub_dmamap_alloc( devfs_handle_t dev, /* set up mappings for this device */ +hub_dmamap_alloc( vertex_hdl_t dev, /* set up mappings for this device */ device_desc_t dev_desc, /* device descriptor */ size_t byte_count_max, /* max size of a mapping */ unsigned flags) /* defined in dma.h */ @@ -424,7 +418,7 @@ hub_dmamap_t dmamap; xwidget_info_t widget_info = xwidget_info_get(dev); xwidgetnum_t widget = xwidget_info_id_get(widget_info); - devfs_handle_t hubv = xwidget_info_master_get(widget_info); + vertex_hdl_t hubv = xwidget_info_master_get(widget_info); dmamap = kmalloc(sizeof(struct hub_dmamap_s), GFP_ATOMIC); dmamap->hdma_xtalk_info.xd_dev = dev; @@ -460,7 +454,7 @@ paddr_t paddr, /* map for this address */ size_t byte_count) /* map this many bytes */ { - devfs_handle_t vhdl; + vertex_hdl_t vhdl; ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID); @@ -479,12 +473,7 @@ } /* There isn't actually any DMA mapping hardware on the hub. */ -#ifdef CONFIG_IA64_SGI_SN2 return( (PHYS_TO_DMA(paddr)) ); -#else - /* no translation needed */ - return(paddr); -#endif } /* @@ -498,7 +487,7 @@ alenlist_t palenlist, /* map this area of memory */ unsigned flags) { - devfs_handle_t vhdl; + vertex_hdl_t vhdl; ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID); @@ -527,7 +516,7 @@ void hub_dmamap_done(hub_dmamap_t hub_dmamap) /* done with these mapping resources */ { - devfs_handle_t vhdl; + vertex_hdl_t vhdl; if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) { hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED; @@ -549,18 +538,13 @@ */ /* ARGSUSED */ iopaddr_t -hub_dmatrans_addr( devfs_handle_t dev, /* translate for this device */ +hub_dmatrans_addr( vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ paddr_t paddr, /* system physical address */ size_t byte_count, /* length */ unsigned flags) /* defined in dma.h */ { -#ifdef CONFIG_IA64_SGI_SN2 return( (PHYS_TO_DMA(paddr)) ); -#else - /* no translation needed */ - return(paddr); -#endif } /* @@ -570,7 +554,7 @@ */ /* ARGSUSED */ alenlist_t -hub_dmatrans_list( devfs_handle_t dev, /* translate for this device */ +hub_dmatrans_list( vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ alenlist_t palenlist, /* system address/length list */ unsigned flags) /* defined in dma.h */ @@ -589,7 +573,7 @@ /*ARGSUSED*/ void -hub_dmaaddr_drain( devfs_handle_t vhdl, +hub_dmaaddr_drain( vertex_hdl_t vhdl, paddr_t addr, size_t bytes) { @@ -598,7 +582,7 @@ /*ARGSUSED*/ void -hub_dmalist_drain( devfs_handle_t vhdl, +hub_dmalist_drain( vertex_hdl_t vhdl, alenlist_t list) { /* XXX- flush caches, if cache coherency WAR is needed */ @@ -612,10 +596,8 @@ * Perform initializations that allow this hub to start crosstalk support. */ void -hub_provider_startup(devfs_handle_t hubv) +hub_provider_startup(vertex_hdl_t hubv) { - extern void hub_pio_init(devfs_handle_t hubv); - hub_pio_init(hubv); hub_intr_init(hubv); } @@ -624,14 +606,14 @@ * Shutdown crosstalk support from a hub. */ void -hub_provider_shutdown(devfs_handle_t hub) +hub_provider_shutdown(vertex_hdl_t hub) { /* TBD */ xtalk_provider_unregister(hub); } /* - * Check that an address is in teh real small window widget 0 space + * Check that an address is in the real small window widget 0 space * or else in the big window we're using to emulate small window 0 * in the kernel. */ @@ -666,49 +648,9 @@ /* - * Determine whether two PCI addresses actually refer to the same device. - * This only works if both addresses are in small windows. It's used to - * determine whether prom addresses refer to particular PCI devices. - */ -/* - * XXX - This won't work as written if we ever have more than two nodes - * on a crossbow. In that case, we'll need an array or partners. - */ -int -hub_check_pci_equiv(void *addra, void *addrb) -{ - nasid_t nasida, nasidb; - - /* - * This is for a permanent workaround that causes us to use a - * big window in place of small window 0. - */ - if (!hub_check_window_equiv(addra, addrb)) - return 0; - - /* If the offsets aren't the same, forget it. */ - if (SWIN_WIDGETADDR((__psunsigned_t)addra) != - (SWIN_WIDGETADDR((__psunsigned_t)addrb))) - return 0; - - /* Now, check the nasids */ - nasida = NASID_GET(addra); - nasidb = NASID_GET(addrb); - - ASSERT(NASID_TO_COMPACT_NODEID(nasida) != INVALID_NASID); - ASSERT(NASID_TO_COMPACT_NODEID(nasidb) != INVALID_NASID); - - /* - * Either the NASIDs must be the same or they must be crossbow - * partners (on the same crossbow). - */ - return (check_nasid_equiv(nasida, nasidb)); -} - -/* * hub_setup_prb(nasid, prbnum, credits, conveyor) * - * Put a PRB into fire-and-forget mode if conveyor isn't set. Otehrwise, + * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise, * put it into conveyor belt mode with the specified number of credits. */ void @@ -716,8 +658,6 @@ { iprb_t prb; int prb_offset; - extern int force_fire_and_forget; - extern volatile int ignore_conveyor_override; if (force_fire_and_forget && !ignore_conveyor_override) if (conveyor == HUB_PIO_CONVEYOR) @@ -776,13 +716,8 @@ int direct_connect; hubii_wcr_t ii_wcr; int prbnum; - int cons_lock = 0; ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID); - if (nasid == get_console_nasid()) { - PUTBUF_LOCK(s); - cons_lock = 1; - } ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS); REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0); @@ -812,9 +747,6 @@ } REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa); - - if (cons_lock) - PUTBUF_UNLOCK(s); } /* Interface to allow special drivers to set hub specific * device flags. @@ -842,90 +774,6 @@ return 1; } -/* Interface to allow special drivers to set hub specific - * device flags. - * Return 0 on failure , 1 on success - */ -int -hub_device_flags_set(devfs_handle_t widget_vhdl, - hub_widget_flags_t flags) -{ - xwidget_info_t widget_info = xwidget_info_get(widget_vhdl); - xwidgetnum_t widget_num = xwidget_info_id_get(widget_info); - devfs_handle_t hub_vhdl = xwidget_info_master_get(widget_info); - hubinfo_t hub_info = 0; - nasid_t nasid; - unsigned long s; - int rv; - - /* Use the nasid from the hub info hanging off the hub vertex - * and widget number from the widget vertex - */ - hubinfo_get(hub_vhdl, &hub_info); - /* Being over cautious by grabbing a lock */ - s = mutex_spinlock(&hub_info->h_bwlock); - nasid = hub_info->h_nasid; - rv = hub_widget_flags_set(nasid,widget_num,flags); - mutex_spinunlock(&hub_info->h_bwlock, s); - - return rv; -} - -/* - * hub_device_inquiry - * Find out the xtalk widget related information stored in this - * hub's II. - */ -void -hub_device_inquiry(devfs_handle_t xbus_vhdl, xwidgetnum_t widget) -{ - devfs_handle_t xconn, hub_vhdl; - char widget_name[8]; - hubreg_t ii_iidem,ii_iiwa, ii_iowa; - hubinfo_t hubinfo; - nasid_t nasid; - int d; - - sprintf(widget_name, "%d", widget); - if (hwgraph_traverse(xbus_vhdl, widget_name, &xconn) - != GRAPH_SUCCESS) - return; - - hub_vhdl = device_master_get(xconn); - if (hub_vhdl == GRAPH_VERTEX_NONE) - return; - - hubinfo_get(hub_vhdl, &hubinfo); - if (!hubinfo) - return; - - nasid = hubinfo->h_nasid; - - ii_iidem = REMOTE_HUB_L(nasid, IIO_IIDEM); - ii_iiwa = REMOTE_HUB_L(nasid, IIO_IIWA); - ii_iowa = REMOTE_HUB_L(nasid, IIO_IOWA); - -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk("Inquiry Info for %v\n", xconn); -#else - printk("Inquiry Info for %p\n", (void *)xconn); -#endif - - printk("\tDevices shutdown [ "); - - for (d = 0 ; d <= 7 ; d++) - if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d)))) - printk(" %d", d); - - printk("]\n"); - - printk("\tInbound access ? %s\n", - ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no"); - - printk("\tOutbound access ? %s\n", - ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no"); - -} /* * A pointer to this structure hangs off of every hub hwgraph vertex. @@ -955,8 +803,6 @@ (xtalk_intr_free_f *) hub_intr_free, (xtalk_intr_connect_f *) hub_intr_connect, (xtalk_intr_disconnect_f *) hub_intr_disconnect, - (xtalk_intr_cpu_get_f *) hub_intr_cpu_get, - (xtalk_provider_startup_f *) hub_provider_startup, (xtalk_provider_shutdown_f *) hub_provider_shutdown, }; diff -urN linux-2.4.21/arch/ia64/sn/io/klconflib.c linux-2.4.22/arch/ia64/sn/io/klconflib.c --- linux-2.4.21/arch/ia64/sn/io/klconflib.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/klconflib.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1046 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define printf printk -int hasmetarouter; - -#define LDEBUG 0 -#define NIC_UNKNOWN ((nic_t) -1) - -#undef DEBUG_KLGRAPH -#ifdef DEBUG_KLGRAPH -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* DEBUG_KLGRAPH */ - -static void sort_nic_names(lboard_t *) ; - -u64 klgraph_addr[MAX_COMPACT_NODES]; -int module_number = 0; - -lboard_t * -find_lboard(lboard_t *start, unsigned char brd_type) -{ - /* Search all boards stored on this node. */ - while (start) { - if (start->brd_type == brd_type) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -lboard_t * -find_lboard_class(lboard_t *start, unsigned char brd_type) -{ - /* Search all boards stored on this node. */ - while (start) { - if (KLCLASS(start->brd_type) == KLCLASS(brd_type)) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -klinfo_t * -find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type) -{ - int index, j; - - if (kli == (klinfo_t *)NULL) { - index = 0; - } else { - for (j = 0; j < KLCF_NUM_COMPS(brd); j++) { - if (kli == KLCF_COMP(brd, j)) - break; - } - index = j; - if (index == KLCF_NUM_COMPS(brd)) { - DBG("find_component: Bad pointer: 0x%p\n", kli); - return (klinfo_t *)NULL; - } - index++; /* next component */ - } - - for (; index < KLCF_NUM_COMPS(brd); index++) { - kli = KLCF_COMP(brd, index); - DBG("find_component: brd %p kli %p request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli)); - if (KLCF_COMP_TYPE(kli) == struct_type) - return kli; - } - - /* Didn't find it. */ - return (klinfo_t *)NULL; -} - -klinfo_t * -find_first_component(lboard_t *brd, unsigned char struct_type) -{ - return find_component(brd, (klinfo_t *)NULL, struct_type); -} - -lboard_t * -find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot) -{ - /* Search all boards stored on this node. */ - while (start) { - if (MODULE_MATCH(start->brd_module, mod) && - (start->brd_slot == slot)) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -lboard_t * -find_lboard_module(lboard_t *start, moduleid_t mod) -{ - /* Search all boards stored on this node. */ - while (start) { - if (MODULE_MATCH(start->brd_module, mod)) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -lboard_t * -find_lboard_module_class(lboard_t *start, moduleid_t mod, - unsigned char brd_type) -{ - while (start) { - - DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type); - - if (MODULE_MATCH(start->brd_module, mod) && - (KLCLASS(start->brd_type) == KLCLASS(brd_type))) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - - -/* - * Convert a NIC name to a name for use in the hardware graph. - */ -void -nic_name_convert(char *old_name, char *new_name) -{ - int i; - char c; - char *compare_ptr; - - if ((old_name[0] == '\0') || (old_name[1] == '\0')) { - strcpy(new_name, EDGE_LBL_XWIDGET); - } else { - for (i = 0; i < strlen(old_name); i++) { - c = old_name[i]; - - if (isalpha(c)) - new_name[i] = tolower(c); - else if (isdigit(c)) - new_name[i] = c; - else - new_name[i] = '_'; - } - new_name[i] = '\0'; - } - - /* XXX - - * Since a bunch of boards made it out with weird names like - * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and - * replace it with "baseio" to avoid confusion in the field. - * We also have to make sure we don't report media_io instead of - * baseio. - */ - - /* Skip underscores at the beginning of the name */ - for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++) - ; - - /* - * Check for some names we need to replace. Early boards - * had junk following the name so check only the first - * characters. - */ - if (!strncmp(new_name, "io6", 3) || - !strncmp(new_name, "mio", 3) || - !strncmp(new_name, "media_io", 8)) - strcpy(new_name, "baseio"); - else if (!strncmp(new_name, "divo", 4)) - strcpy(new_name, "divo") ; - -} - -/* Check if the given board corresponds to the global - * master io6 - */ -int -is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot) -{ - lboard_t *board; - -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) -/* If this works then look for callers of is_master_baseio() - * (e.g. iograph.c) and let them pass in a slot if they want - */ - board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module); -#else - board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), module, slot); -#endif - -#ifndef _STANDALONE - { - cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); - - if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) - board = find_lboard_module((lboard_t *) - KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), - module); -#else - board = find_lboard_modslot((lboard_t *) - KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), - module, slot); -#endif - } -#endif - if (!board) - return(0); - return(board->brd_flags & GLOBAL_MASTER_IO6); -} -/* - * Find the lboard structure and get the board name. - * If we can't find the structure or it's too low a revision, - * use default name. - */ -lboard_t * -get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name) -{ - lboard_t *brd; - - brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), - mod, slot); - -#ifndef _STANDALONE - { - cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); - - if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) - brd = find_lboard_modslot((lboard_t *) - KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), - mod, slot); - } -#endif - - if (!brd || (brd->brd_sversion < 2)) { - strcpy(name, EDGE_LBL_XWIDGET); - } else { - nic_name_convert(brd->brd_name, name); - } - - /* - * PV # 540860 - * If the name is not 'baseio' - * get the lowest of all the names in the nic string. - * This is needed for boards like divo, which can have - * a bunch of daughter cards, but would like to be called - * divo. We could do this for baseio - * but it has some special case names that we would not - * like to disturb at this point. - */ - - /* gfx boards don't need any of this name scrambling */ - if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) { - return(brd); - } - - if (!(!strcmp(name, "baseio") )) { - if (brd) { - sort_nic_names(brd) ; - /* Convert to small case, '-' to '_' etc */ - nic_name_convert(brd->brd_name, name) ; - } - } - - return(brd); -} - -/* - * get_actual_nasid - * - * Completely disabled brds have their klconfig on - * some other nasid as they have no memory. But their - * actual nasid is hidden in the klconfig. Use this - * routine to get it. Works for normal boards too. - */ -nasid_t -get_actual_nasid(lboard_t *brd) -{ - klhub_t *hub ; - - if (!brd) - return INVALID_NASID ; - - /* find out if we are a completely disabled brd. */ - - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); - if (!hub) - return INVALID_NASID ; - if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */ - return hub->hub_info.physid ; - else - return brd->brd_nasid ; -} - -int -xbow_port_io_enabled(nasid_t nasid, int link) -{ - lboard_t *brd; - klxbow_t *xbow_p; - - /* - * look for boards that might contain an xbow or xbridge - */ - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW); - if (brd == NULL) return 0; - - if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) - == NULL) - return 0; - - if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link)) - return 0; - - DBG("xbow_port_io_enabled: brd 0x%p xbow_p 0x%p \n", brd, xbow_p); - - return 1; -} - -void -board_to_path(lboard_t *brd, char *path) -{ - moduleid_t modnum; - char *board_name; - - ASSERT(brd); - - switch (KLCLASS(brd->brd_type)) { - - case KLCLASS_NODE: - board_name = EDGE_LBL_NODE; - break; - case KLCLASS_ROUTER: - if (brd->brd_type == KLTYPE_META_ROUTER) { - board_name = EDGE_LBL_META_ROUTER; - hasmetarouter++; - } else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) { - board_name = EDGE_LBL_REPEATER_ROUTER; - hasmetarouter++; - } else - board_name = EDGE_LBL_ROUTER; - break; - case KLCLASS_MIDPLANE: - board_name = EDGE_LBL_MIDPLANE; - break; - case KLCLASS_IO: - board_name = EDGE_LBL_IO; - break; - case KLCLASS_IOBRICK: - if (brd->brd_type == KLTYPE_PBRICK) - board_name = EDGE_LBL_PBRICK; - else if (brd->brd_type == KLTYPE_IBRICK) - board_name = EDGE_LBL_IBRICK; - else if (brd->brd_type == KLTYPE_XBRICK) - board_name = EDGE_LBL_XBRICK; - else - board_name = EDGE_LBL_IOBRICK; - break; - default: - board_name = EDGE_LBL_UNKNOWN; - } - - modnum = brd->brd_module; - - /* ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); */ -if ((modnum == MODULE_UNKNOWN) || (modnum == INVALID_MODULE)) { - modnum = ++module_number; -} -#ifdef __ia64 - { - char buffer[16]; - memset(buffer, 0, 16); - format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF); - sprintf(path, EDGE_LBL_MODULE "/%s/%s", buffer, board_name); - } -#else - sprintf(path, "%H/%s", modnum, board_name); -#endif -} - -/* - * Get the module number for a NASID. - */ -moduleid_t -get_module_id(nasid_t nasid) -{ - lboard_t *brd; - - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - - if (!brd) - return INVALID_MODULE; - else - return brd->brd_module; -} - - -#define MHZ 1000000 - - -/* Get the canonical hardware graph name for the given pci component - * on the given io board. - */ -void -device_component_canonical_name_get(lboard_t *brd, - klinfo_t *component, - char *name) -{ - moduleid_t modnum; - slotid_t slot; - char board_name[20]; - - ASSERT(brd); - - /* Get the module number of this board */ - modnum = brd->brd_module; - - /* Convert the [ CLASS | TYPE ] kind of slotid - * into a string - */ - slot = brd->brd_slot; - ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); - - /* Get the io board name */ - if (!brd || (brd->brd_sversion < 2)) { - strcpy(name, EDGE_LBL_XWIDGET); - } else { - nic_name_convert(brd->brd_name, board_name); - } - - /* Give out the canonical name of the pci device*/ - sprintf(name, - "/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/" - EDGE_LBL_PCI"/%d", - modnum, board_name,KLCF_BRIDGE_W_ID(component)); -} - -/* - * Get the serial number of the main component of a board - * Returns 0 if a valid serial number is found - * 1 otherwise. - * Assumptions: Nic manufacturing string has the following format - * *Serial:;* - */ -static int -component_serial_number_get(lboard_t *board, - klconf_off_t mfg_nic_offset, - char *serial_number, - char *key_pattern) -{ - - char *mfg_nic_string; - char *serial_string,*str; - int i; - char *serial_pattern = "Serial:"; - - /* We have an error on a null mfg nic offset */ - if (!mfg_nic_offset) - return(1); - /* Get the hub's manufacturing nic information - * which is in the form of a pre-formatted string - */ - mfg_nic_string = - (char *)NODE_OFFSET_TO_K0(NASID_GET(board), - mfg_nic_offset); - /* There is no manufacturing nic info */ - if (!mfg_nic_string) - return(1); - - str = mfg_nic_string; - /* Look for the key pattern first (if it is specified) - * and then print the serial number corresponding to that. - */ - if (strcmp(key_pattern,"") && - !(str = strstr(mfg_nic_string,key_pattern))) - return(1); - - /* There is no serial number info in the manufacturing - * nic info - */ - if (!(serial_string = strstr(str,serial_pattern))) - return(1); - - serial_string = serial_string + strlen(serial_pattern); - /* Copy the serial number information from the klconfig */ - i = 0; - while (serial_string[i] != ';') { - serial_number[i] = serial_string[i]; - i++; - } - serial_number[i] = 0; - - return(0); -} -/* - * Get the serial number of a board - * Returns 0 if a valid serial number is found - * 1 otherwise. - */ - -int -board_serial_number_get(lboard_t *board,char *serial_number) -{ - ASSERT(board && serial_number); - if (!board || !serial_number) - return(1); - - strcpy(serial_number,""); - switch(KLCLASS(board->brd_type)) { - case KLCLASS_CPU: { /* Node board */ - klhub_t *hub; - - /* Get the hub component information */ - hub = (klhub_t *)find_first_component(board, - KLSTRUCT_HUB); - /* If we don't have a hub component on an IP27 - * then we have a weird klconfig. - */ - if (!hub) - return(1); - /* Get the serial number information from - * the hub's manufacturing nic info - */ - if (component_serial_number_get(board, - hub->hub_mfg_nic, - serial_number, -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) - "IP37")) -#else - "IP27")) - /* Try with IP31 key if IP27 key fails */ - if (component_serial_number_get(board, - hub->hub_mfg_nic, - serial_number, - "IP31")) -#endif /* CONFIG_IA64_SGI_SN1 */ - return(1); - break; - } - case KLCLASS_IO: { /* IO board */ - if (KLTYPE(board->brd_type) == KLTYPE_TPU) { - /* Special case for TPU boards */ - kltpu_t *tpu; - - /* Get the tpu component information */ - tpu = (kltpu_t *)find_first_component(board, - KLSTRUCT_TPU); - /* If we don't have a tpu component on a tpu board - * then we have a weird klconfig. - */ - if (!tpu) - return(1); - /* Get the serial number information from - * the tpu's manufacturing nic info - */ - if (component_serial_number_get(board, - tpu->tpu_mfg_nic, - serial_number, - "")) - return(1); - break; - } else if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) || - (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) { - /* Special case for GSN boards */ - klgsn_t *gsn; - - /* Get the gsn component information */ - gsn = (klgsn_t *)find_first_component(board, - ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ? - KLSTRUCT_GSN_A : KLSTRUCT_GSN_B)); - /* If we don't have a gsn component on a gsn board - * then we have a weird klconfig. - */ - if (!gsn) - return(1); - /* Get the serial number information from - * the gsn's manufacturing nic info - */ - if (component_serial_number_get(board, - gsn->gsn_mfg_nic, - serial_number, - "")) - return(1); - break; - } else { - klbri_t *bridge; - - /* Get the bridge component information */ - bridge = (klbri_t *)find_first_component(board, - KLSTRUCT_BRI); - /* If we don't have a bridge component on an IO board - * then we have a weird klconfig. - */ - if (!bridge) - return(1); - /* Get the serial number information from - * the bridge's manufacturing nic info - */ - if (component_serial_number_get(board, - bridge->bri_mfg_nic, - serial_number, - "")) - return(1); - break; - } - } - case KLCLASS_ROUTER: { /* Router board */ - klrou_t *router; - - /* Get the router component information */ - router = (klrou_t *)find_first_component(board, - KLSTRUCT_ROU); - /* If we don't have a router component on a router board - * then we have a weird klconfig. - */ - if (!router) - return(1); - /* Get the serial number information from - * the router's manufacturing nic info - */ - if (component_serial_number_get(board, - router->rou_mfg_nic, - serial_number, - "")) - return(1); - break; - } - case KLCLASS_GFX: { /* Gfx board */ - klgfx_t *graphics; - - /* Get the graphics component information */ - graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX); - /* If we don't have a gfx component on a gfx board - * then we have a weird klconfig. - */ - if (!graphics) - return(1); - /* Get the serial number information from - * the graphics's manufacturing nic info - */ - if (component_serial_number_get(board, - graphics->gfx_mfg_nic, - serial_number, - "")) - return(1); - break; - } - default: - strcpy(serial_number,""); - break; - } - return(0); -} - -#include "asm/sn/sn_private.h" - -xwidgetnum_t -nodevertex_widgetnum_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - return(hubinfo_p->h_widgetid); -} - -devfs_handle_t -nodevertex_xbow_peer_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - nasid_t xbow_peer_nasid; - cnodeid_t xbow_peer; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer; - if(xbow_peer_nasid == INVALID_NASID) - return ( (devfs_handle_t)-1); - xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid); - return(NODEPDA(xbow_peer)->node_vertex); -} - -/* NIC Sorting Support */ - -#define MAX_NICS_PER_STRING 32 -#define MAX_NIC_NAME_LEN 32 - -static char * -get_nic_string(lboard_t *lb) -{ - int i; - klinfo_t *k = NULL ; - klconf_off_t mfg_off = 0 ; - char *mfg_nic = NULL ; - - for (i = 0; i < KLCF_NUM_COMPS(lb); i++) { - k = KLCF_COMP(lb, i) ; - switch(k->struct_type) { - case KLSTRUCT_BRI: - mfg_off = ((klbri_t *)k)->bri_mfg_nic ; - break ; - - case KLSTRUCT_HUB: - mfg_off = ((klhub_t *)k)->hub_mfg_nic ; - break ; - - case KLSTRUCT_ROU: - mfg_off = ((klrou_t *)k)->rou_mfg_nic ; - break ; - - case KLSTRUCT_GFX: - mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ; - break ; - - case KLSTRUCT_TPU: - mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ; - break ; - - case KLSTRUCT_GSN_A: - case KLSTRUCT_GSN_B: - mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ; - break ; - - case KLSTRUCT_XTHD: - mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ; - break; - - default: - mfg_off = 0 ; - break ; - } - if (mfg_off) - break ; - } - - if ((mfg_off) && (k)) - mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ; - - return mfg_nic ; -} - -char * -get_first_string(char **ptrs, int n) -{ - int i ; - char *tmpptr ; - - if ((ptrs == NULL) || (n == 0)) - return NULL ; - - tmpptr = ptrs[0] ; - - if (n == 1) - return tmpptr ; - - for (i = 0 ; i < n ; i++) { - if (strcmp(tmpptr, ptrs[i]) > 0) - tmpptr = ptrs[i] ; - } - - return tmpptr ; -} - -int -get_ptrs(char *idata, char **ptrs, int n, char *label) -{ - int i = 0 ; - char *tmp = idata ; - - if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0)) - return 0 ; - - while ( (tmp = strstr(tmp, label)) ){ - tmp += strlen(label) ; - /* check for empty name field, and last NULL ptr */ - if ((i < (n-1)) && (*tmp != ';')) { - ptrs[i++] = tmp ; - } - } - - ptrs[i] = NULL ; - - return i ; -} - -/* - * sort_nic_names - * - * Does not really do sorting. Find the alphabetically lowest - * name among all the nic names found in a nic string. - * - * Return: - * Nothing - * - * Side Effects: - * - * lb->brd_name gets the new name found - */ - -static void -sort_nic_names(lboard_t *lb) -{ - char *nic_str ; - char *ptrs[MAX_NICS_PER_STRING] ; - char name[MAX_NIC_NAME_LEN] ; - char *tmp, *tmp1 ; - - *name = 0 ; - - /* Get the nic pointer from the lb */ - - if ((nic_str = get_nic_string(lb)) == NULL) - return ; - - tmp = get_first_string(ptrs, - get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ; - - if (tmp == NULL) - return ; - - if ( (tmp1 = strchr(tmp, ';')) ){ - strncpy(name, tmp, tmp1-tmp) ; - name[tmp1-tmp] = 0 ; - } else { - strncpy(name, tmp, (sizeof(name) -1)) ; - name[sizeof(name)-1] = 0 ; - } - - strcpy(lb->brd_name, name) ; -} - - - -char brick_types[MAX_BRICK_TYPES + 1] = "crikxdp789012345"; - -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) - -/* - * Format a module id for printing. - */ -void -format_module_id(char *buffer, moduleid_t m, int fmt) -{ - int rack, position; - char brickchar; - - rack = MODULE_GET_RACK(m); - ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES); - brickchar = MODULE_GET_BTCHAR(m); - position = MODULE_GET_BPOS(m); - - if (fmt == MODULE_FORMAT_BRIEF) { - /* Brief module number format, eg. 002c15 */ - - /* Decompress the rack number */ - *buffer++ = '0' + RACK_GET_CLASS(rack); - *buffer++ = '0' + RACK_GET_GROUP(rack); - *buffer++ = '0' + RACK_GET_NUM(rack); - - /* Add the brick type */ - *buffer++ = brickchar; - } - else if (fmt == MODULE_FORMAT_LONG) { - /* Fuller hwgraph format, eg. rack/002/bay/15 */ - - strcpy(buffer, EDGE_LBL_RACK "/"); buffer += strlen(buffer); - - *buffer++ = '0' + RACK_GET_CLASS(rack); - *buffer++ = '0' + RACK_GET_GROUP(rack); - *buffer++ = '0' + RACK_GET_NUM(rack); - - strcpy(buffer, "/" EDGE_LBL_RPOS "/"); buffer += strlen(buffer); - } - - /* Add the bay position, using at least two digits */ - if (position < 10) - *buffer++ = '0'; - sprintf(buffer, "%d", position); - -} - -/* - * Parse a module id, in either brief or long form. - * Returns < 0 on error. - * The long form does not include a brick type, so it defaults to 0 (CBrick) - */ -int -parse_module_id(char *buffer) -{ - unsigned int v, rack, bay, type, form; - moduleid_t m; - char c; - - if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) { - form = MODULE_FORMAT_LONG; - buffer += strlen(EDGE_LBL_RACK "/"); - - /* A long module ID must be exactly 5 non-template chars. */ - if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5) - return -1; - } - else { - form = MODULE_FORMAT_BRIEF; - - /* A brief module id must be exactly 6 characters */ - if (strlen(buffer) != 6) - return -2; - } - - /* The rack number must be exactly 3 digits */ - if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2]))) - return -3; - - rack = 0; - v = *buffer++ - '0'; - if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) - return -4; - RACK_ADD_CLASS(rack, v); - - v = *buffer++ - '0'; - if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) - return -5; - RACK_ADD_GROUP(rack, v); - - v = *buffer++ - '0'; - /* rack numbers are 1-based */ - if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) - return -6; - RACK_ADD_NUM(rack, v); - - if (form == MODULE_FORMAT_BRIEF) { - /* Next should be a module type character. Accept ucase or lcase. */ - c = *buffer++; - if (!isalpha(c)) - return -7; - - /* strchr() returns a pointer into brick_types[], or NULL */ - type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types); - if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT) - return -8; - } - else { - /* Hardcode the module type, and skip over the boilerplate */ - type = MODULE_CBRICK; - - if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer) - return -9; - - buffer += strlen("/" EDGE_LBL_RPOS "/"); - } - - /* The bay number is last. Make sure it's exactly two digits */ - - if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2])) - return -10; - - bay = 10 * (buffer[0] - '0') + (buffer[1] - '0'); - - if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) - return -11; - - m = RBT_TO_MODULE(rack, bay, type); - - /* avoid sign extending the moduleid_t */ - return (int)(unsigned short)m; -} - -#else /* CONFIG_IA64_SGI_SN1 */ - -/* - * Format a module id for printing. - */ -void -format_module_id(char *buffer, moduleid_t m, int fmt) -{ - if (fmt == MODULE_FORMAT_BRIEF) { - sprintf(buffer, "%d", m); - } - else if (fmt == MODULE_FORMAT_LONG) { - sprintf(buffer, EDGE_LBL_MODULE "/%d", m); - } -} - -/* - * Parse a module id, in either brief or long form. - * Returns < 0 on error. - */ -int -parse_module_id(char *buffer) -{ - moduleid_t m; - char c; - - if (strstr(buffer, EDGE_LBL_MODULE "/") == buffer) - buffer += strlen(EDGE_LBL_MODULE "/"); - - for (m = 0; *buffer; buffer++) { - c = *buffer; - if (!isdigit(c)) - return -1; - m = 10 * m + (c - '0'); - } - - /* avoid sign extending the moduleid_t */ - return (int)(unsigned short)m; -} - -#endif /* CONFIG_IA64_SGI_SN1 */ - - diff -urN linux-2.4.21/arch/ia64/sn/io/klgraph.c linux-2.4.22/arch/ia64/sn/io/klgraph.c --- linux-2.4.21/arch/ia64/sn/io/klgraph.c 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/klgraph.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,795 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * klgraph.c- - * This file specifies the interface between the kernel and the PROM's - * configuration data structures. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define KLGRAPH_DEBUG 1 */ -#ifdef KLGRAPH_DEBUG -#define GRPRINTF(x) printk x -#define CE_GRPANIC CE_PANIC -#else -#define GRPRINTF(x) -#define CE_GRPANIC CE_PANIC -#endif - -#include - -extern char arg_maxnodes[]; -extern u64 klgraph_addr[]; - -/* - * Support for verbose inventory via hardware graph. - * klhwg_invent_alloc allocates the necessary size of inventory information - * and fills in the generic information. - */ -invent_generic_t * -klhwg_invent_alloc(cnodeid_t cnode, int class, int size) -{ - invent_generic_t *invent; - - invent = kern_malloc(size); - if (!invent) return NULL; - - invent->ig_module = NODE_MODULEID(cnode); - invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode)); - invent->ig_invclass = class; - - return invent; -} - -/* - * Add information about the baseio prom version number - * as a part of detailed inventory info in the hwgraph. - */ -void -klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode) -{ - invent_miscinfo_t *baseio_inventory; - unsigned char version = 0,revision = 0; - - /* Allocate memory for the "detailed inventory" info - * for the baseio - */ - baseio_inventory = (invent_miscinfo_t *) - klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t)); - baseio_inventory->im_type = INV_IO6PROM; - /* Read the io6prom revision from the nvram */ -#ifdef LATER - nvram_prom_version_get(&version,&revision); -#endif - /* Store the revision info in the inventory */ - baseio_inventory->im_version = version; - baseio_inventory->im_rev = revision; - /* Put the inventory info in the hardware graph */ - hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, - (arbitrary_info_t) baseio_inventory); - /* Make the information available to the user programs - * thru hwgfs. - */ - hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, - sizeof(invent_miscinfo_t)); -} - -char *hub_rev[] = { - "0.0", - "1.0", - "2.0", - "2.1", - "2.2", - "2.3" -}; - -/* - * Add detailed cpu inventory info to the hardware graph. - */ -void -klhwg_hub_invent_info(devfs_handle_t hubv, - cnodeid_t cnode, - klhub_t *hub) -{ - invent_miscinfo_t *hub_invent; - - hub_invent = (invent_miscinfo_t *) - klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t)); - if (!hub_invent) - return; - - if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub)) - hub_invent->im_gen.ig_flag = INVENT_ENABLED; - - hub_invent->im_type = INV_HUB; - hub_invent->im_rev = hub->hub_info.revision; - hub_invent->im_speed = hub->hub_speed; - hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, - (arbitrary_info_t) hub_invent); - hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT, - sizeof(invent_miscinfo_t)); -} - -/* ARGSUSED */ -void -klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode) -{ -#if defined(CONFIG_IA64_SGI_SN1) - devfs_handle_t myhubv; - devfs_handle_t hub_mon; - devfs_handle_t synergy; - devfs_handle_t fsb0; - devfs_handle_t fsb1; - int rc; - extern struct file_operations hub_mon_fops; - - GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB)); - - (void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv); - rc = device_master_set(myhubv, node_vertex); - - /* - * hub perf stats. - */ - rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO, - (arbitrary_info_t)(&NODEPDA(cnode)->hubstats)); - - if (rc != GRAPH_SUCCESS) { - printk(KERN_WARNING "klhwg_add_hub: Can't add hub info label 0x%p, code %d", - (void *)myhubv, rc); - } - - klhwg_hub_invent_info(myhubv, cnode, hub); - - hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &hub_mon_fops, - (void *)(long)cnode); - - init_hub_stats(cnode, NODEPDA(cnode)); - - /* - * synergy perf - */ - (void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy); - (void) hwgraph_path_add(synergy, "0", &fsb0); - (void) hwgraph_path_add(synergy, "1", &fsb1); - - fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0)); - - fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1)); -#endif /* CONFIG_IA64_SGI_SN1 */ -} - -void -klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid) -{ - lboard_t *brd; - klxbow_t *xbow_p; - nasid_t hub_nasid; - cnodeid_t hub_cnode; - int widgetnum; - devfs_handle_t xbow_v, hubv; - /*REFERENCED*/ - graph_error_t err; - - if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL) - return; - - if (KL_CONFIG_DUPLICATE_BOARD(brd)) - return; - - GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n", - cnode, nasid)); - - if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) - == NULL) - return; - -#ifdef LATER - /* - * We cannot support this function in devfs .. see below where - * we use hwgraph_path_add() to create this vertex with a known - * name. - */ - err = hwgraph_vertex_create(&xbow_v); - ASSERT(err == GRAPH_SUCCESS); - - xswitch_vertex_init(xbow_v); -#endif /* LATER */ - - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { - if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) - continue; - - hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum); - if (hub_nasid == INVALID_NASID) { - printk(KERN_WARNING "hub widget %d, skipping xbow graph\n", widgetnum); - continue; - } - - hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid); - - if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) { - continue; - } - - hubv = cnodeid_to_vertex(hub_cnode); - - err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v); - if (err != GRAPH_SUCCESS) { - if (err == GRAPH_DUP) - printk(KERN_WARNING "klhwg_add_xbow: Check for " - "working routers and router links!"); - - PRINT_PANIC("klhwg_add_xbow: Failed to add " - "edge: vertex 0x%p to vertex 0x%p," - "error %d\n", - (void *)hubv, (void *)xbow_v, err); - } - xswitch_vertex_init(xbow_v); - - NODEPDA(hub_cnode)->xbow_vhdl = xbow_v; - - /* - * XXX - This won't work is we ever hook up two hubs - * by crosstown through a crossbow. - */ - if (hub_nasid != nasid) { - NODEPDA(hub_cnode)->xbow_peer = nasid; - NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer = - hub_nasid; - } - - GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n", - hub_nasid, EDGE_LBL_XTALK, hubv)); - -#ifdef LATER - err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK); - if (err != GRAPH_SUCCESS) { - if (err == GRAPH_DUP) - printk(KERN_WARNING "klhwg_add_xbow: Check for " - "working routers and router links!"); - - PRINT_PANIC("klhwg_add_xbow: Failed to add " - "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), " - "error %d\n", - hubv, hubv, xbow_v, xbow_v, err); - } -#endif - } -} - - -/* ARGSUSED */ -void -klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) -{ - nasid_t nasid; - lboard_t *brd; - klhub_t *hub; - devfs_handle_t node_vertex = NULL; - char path_buffer[100]; - int rv; - char *s; - int board_disabled = 0; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n", - cnode, nasid, brd)); - ASSERT(brd); - - do { - - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n", - path_buffer, hwgraph_root)); - rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); - - if (rv != GRAPH_SUCCESS) - PRINT_PANIC("Node vertex creation failed. " - "Path == %s", - path_buffer); - - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); - ASSERT(hub); - if(hub->hub_info.flags & KLINFO_ENABLE) - board_disabled = 0; - else - board_disabled = 1; - - if(!board_disabled) { - mark_nodevertex_as_node(node_vertex, - cnode + board_disabled * numnodes); - - s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer)); - NODEPDA(cnode)->hwg_node_name = - kmalloc(strlen(s) + 1, - GFP_KERNEL); - ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL); - strcpy(NODEPDA(cnode)->hwg_node_name, s); - - hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo); - - /* Set up node board's slot */ - NODEPDA(cnode)->slotdesc = brd->brd_slot; - - /* Set up the module we're in */ - NODEPDA(cnode)->module_id = brd->brd_module; - NODEPDA(cnode)->module = module_lookup(brd->brd_module); - } - - if(!board_disabled) - klhwg_add_hub(node_vertex, hub, cnode); - - brd = KLCF_NEXT(brd); - if (brd) - brd = find_lboard(brd, KLTYPE_SNIA); - else - break; - } while(brd); -} - - -/* ARGSUSED */ -void -klhwg_add_all_routers(devfs_handle_t hwgraph_root) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd; - devfs_handle_t node_vertex; - char path_buffer[100]; - int rv; - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n", - cnode)); - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - /* No routers stored in this node's memory */ - continue; - - do { - ASSERT(brd); - GRPRINTF(("Router board struct is %p\n", brd)); - - /* Don't add duplicate boards. */ - if (brd->brd_flags & DUPLICATE_BOARD) - continue; - - GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module)); - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - GRPRINTF(("Router path is %s\n", path_buffer)); - - /* Add the router */ - GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n", - path_buffer, hwgraph_root)); - rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); - - if (rv != GRAPH_SUCCESS) - PRINT_PANIC("Router vertex creation " - "failed. Path == %s", - path_buffer); - - GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n", - brd)); - /* Find the rest of the routers stored on this node. */ - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), - KLTYPE_ROUTER)) ); - - GRPRINTF(("klhwg_add_all_routers: Done.\n")); - } - -} - -/* ARGSUSED */ -void -klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd, - cnodeid_t cnode, nasid_t nasid) -{ - klrou_t *router; - char path_buffer[50]; - char dest_path[50]; - devfs_handle_t router_hndl; - devfs_handle_t dest_hndl; - int rc; - int port; - lboard_t *dest_brd; - - GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n", - cnode)); - - /* Don't add duplicate boards. */ - if (brd->brd_flags & DUPLICATE_BOARD) { - GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n", - brd, cnode)); - return; - } - - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl); - - if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes)) - return; - - if (rc != GRAPH_SUCCESS) - printk(KERN_WARNING "Can't find router: %s", path_buffer); - - /* We don't know what to do with multiple router components */ - if (brd->brd_numcompts != 1) { - PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n", - brd->brd_numcompts); - return; - } - - - /* Convert component 0 to klrou_t ptr */ - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), - brd->brd_compts[0]); - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - /* See if the port's active */ - if (router->rou_port[port].port_nasid == INVALID_NASID) { - GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n", - port)); - continue; - } - if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) - == INVALID_CNODEID) { - continue; - } - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - router->rou_port[port].port_nasid, - router->rou_port[port].port_offset); - - /* Generate a hardware graph path for this board. */ - board_to_path(dest_brd, dest_path); - - rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); - - if (rc != GRAPH_SUCCESS) { - if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd)) - continue; - PRINT_PANIC("Can't find router: %s", dest_path); - } - GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n", - path_buffer, port, dest_path)); - - sprintf(dest_path, "%d", port); - - rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path); - - if (rc == GRAPH_DUP) { - GRPRINTF(("Skipping port %d. nasid %d %s/%s\n", - port, router->rou_port[port].port_nasid, - path_buffer, dest_path)); - continue; - } - - if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes)) - PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n", - path_buffer, dest_path, (void *)dest_hndl, rc); - - } -} - - -void -klhwg_connect_routers(devfs_handle_t hwgraph_root) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd; - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n", - cnode)); - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - continue; - - do { - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - klhwg_connect_one_router(hwgraph_root, brd, - cnode, nasid); - - /* Find the rest of the routers stored on this node. */ - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); - } -} - - - -void -klhwg_connect_hubs(devfs_handle_t hwgraph_root) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd; - klhub_t *hub; - lboard_t *dest_brd; - devfs_handle_t hub_hndl; - devfs_handle_t dest_hndl; - char path_buffer[50]; - char dest_path[50]; - graph_error_t rc; - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n", - cnode)); - - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - ASSERT(brd); - - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); - ASSERT(hub); - - /* See if the port's active */ - if (hub->hub_port.port_nasid == INVALID_NASID) { - GRPRINTF(("klhwg_connect_hubs: port inactive.\n")); - continue; - } - - if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID) - continue; - - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer)); - rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl); - - if (rc != GRAPH_SUCCESS) - printk(KERN_WARNING "Can't find hub: %s", path_buffer); - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - hub->hub_port.port_nasid, - hub->hub_port.port_offset); - - /* Generate a hardware graph path for this board. */ - board_to_path(dest_brd, dest_path); - - rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); - - if (rc != GRAPH_SUCCESS) { - if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd)) - continue; - PRINT_PANIC("Can't find board: %s", dest_path); - } else { - - - GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n", - path_buffer, dest_path)); - - rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT); - - if (rc != GRAPH_SUCCESS) - PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n", - path_buffer, dest_path, (void *)dest_hndl, rc); - - } - } -} - -/* Store the pci/vme disabled board information as extended administrative - * hints which can later be used by the drivers using the device/driver - * admin interface. - */ -void -klhwg_device_disable_hints_add(void) -{ - cnodeid_t cnode; /* node we are looking at */ - nasid_t nasid; /* nasid of the node */ - lboard_t *board; /* board we are looking at */ - int comp_index; /* component index */ - klinfo_t *component; /* component in the board we are - * looking at - */ - char device_name[MAXDEVNAME]; - -#ifdef LATER - device_admin_table_init(); -#endif - for(cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - board = (lboard_t *)KL_CONFIG_INFO(nasid); - /* Check out all the board info stored on a node */ - while(board) { - /* No need to look at duplicate boards or non-io - * boards - */ - if (KL_CONFIG_DUPLICATE_BOARD(board) || - KLCLASS(board->brd_type) != KLCLASS_IO) { - board = KLCF_NEXT(board); - continue; - } - /* Check out all the components of a board */ - for (comp_index = 0; - comp_index < KLCF_NUM_COMPS(board); - comp_index++) { - component = KLCF_COMP(board,comp_index); - /* If the component is enabled move on to - * the next component - */ - if (KLCONFIG_INFO_ENABLED(component)) - continue; - /* NOTE : Since the prom only supports - * the disabling of pci devices the following - * piece of code makes sense. - * Make sure that this assumption is valid - */ - /* This component is disabled. Store this - * hint in the extended device admin table - */ - /* Get the canonical name of the pci device */ - device_component_canonical_name_get(board, - component, - device_name); -#ifdef LATER - device_admin_table_update(device_name, - ADMIN_LBL_DISABLED, - "yes"); -#endif -#ifdef DEBUG - printf("%s DISABLED\n",device_name); -#endif - } - /* go to the next board info stored on this - * node - */ - board = KLCF_NEXT(board); - } - } -} - -void -klhwg_add_all_modules(devfs_handle_t hwgraph_root) -{ - cmoduleid_t cm; - char name[128]; - devfs_handle_t vhdl; - int rc; - char buffer[16]; - - /* Add devices under each module */ - - for (cm = 0; cm < nummodules; cm++) { - /* Use module as module vertex fastinfo */ - -#ifdef __ia64 - memset(buffer, 0, 16); - format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF); - sprintf(name, EDGE_LBL_MODULE "/%s", buffer); -#else - sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id); -#endif - - rc = hwgraph_path_add(hwgraph_root, name, &vhdl); - ASSERT(rc == GRAPH_SUCCESS); - rc = rc; - - hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]); - - /* Add system controller */ - -#ifdef __ia64 - sprintf(name, - EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1, - buffer); -#else - sprintf(name, - EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1, - modules[cm]->id); -#endif - - rc = hwgraph_path_add(hwgraph_root, name, &vhdl); - ASSERT_ALWAYS(rc == GRAPH_SUCCESS); - rc = rc; - - hwgraph_info_add_LBL(vhdl, - INFO_LBL_ELSC, - (arbitrary_info_t) (__psint_t) 1); - -#ifdef LATER - sndrv_attach(vhdl); -#else - /* - * We need to call the drivers attach routine .. - */ - FIXME("klhwg_add_all_modules: Need code to call driver attach.\n"); -#endif - } -} - -void -klhwg_add_all_nodes(devfs_handle_t hwgraph_root) -{ - cnodeid_t cnode; - - for (cnode = 0; cnode < numnodes; cnode++) { - klhwg_add_node(hwgraph_root, cnode, NULL); - } - - for (cnode = 0; cnode < numnodes; cnode++) { - klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode)); - } - - /* - * As for router hardware inventory information, we set this - * up in router.c. - */ - - klhwg_add_all_routers(hwgraph_root); - klhwg_connect_routers(hwgraph_root); - klhwg_connect_hubs(hwgraph_root); - - /* Assign guardian nodes to each of the - * routers in the system. - */ - -#ifdef LATER - router_guardians_set(hwgraph_root); -#endif - - /* Go through the entire system's klconfig - * to figure out which pci components have been disabled - */ - klhwg_device_disable_hints_add(); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/klgraph_hack.c linux-2.4.22/arch/ia64/sn/io/klgraph_hack.c --- linux-2.4.21/arch/ia64/sn/io/klgraph_hack.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/klgraph_hack.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,341 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - - -/* - * This is a temporary file that statically initializes the expected - * initial klgraph information that is normally provided by prom. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -extern u64 klgraph_addr[]; -void * real_port; -void * real_io_base; -void * real_addr; - -char *BW0 = NULL; - -kl_config_hdr_t *linux_klcfg; - -#ifdef DEFINE_DUMP_RTNS -/* forward declarations */ -static void dump_ii(void), dump_crossbow(void); -static void clear_ii_error(void); -#endif /* DEFINE_DUMP_RTNS */ - -#define SYNERGY_WIDGET ((char *)0xc0000e0000000000) -#define SYNERGY_SWIZZLE ((char *)0xc0000e0000000400) -#define HUBREG ((char *)0xc0000a0001e00000) -#define WIDGET0 ((char *)0xc0000a0000000000) -#define WIDGET4 ((char *)0xc0000a0000000004) - -#define SYNERGY_WIDGET ((char *)0xc0000e0000000000) -#define SYNERGY_SWIZZLE ((char *)0xc0000e0000000400) -#define HUBREG ((char *)0xc0000a0001e00000) -#define WIDGET0 ((char *)0xc0000a0000000000) - -#define convert(a,b,c) temp = (u64 *)a; *temp = b; temp++; *temp = c - -void -klgraph_hack_init(void) -{ - - u64 *temp; - -#ifdef CONFIG_IA64_SGI_SN1 - /* - * We need to know whether we are booting from PROM or - * boot from disk. - */ - linux_klcfg = (kl_config_hdr_t *)0xe000000000030000; - if (linux_klcfg->ch_magic == 0xbeedbabe) { - return; - } else { - panic("klgraph_hack_init: Unable to locate KLCONFIG TABLE\n"); - } - - convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000); - -#else - - if (IS_RUNNING_ON_SIMULATOR()) { - printk("Creating FAKE Klconfig Structure for Embeded Kernel\n"); - klgraph_addr[0] = 0xe000003000030000; - - /* - * klconfig entries initialization - mankato - */ - convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000); - convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178); - convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000); - convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000); - convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070); - convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70); - convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330); - convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101); - convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67); - convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40); - convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0); - convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000); - convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000); - convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000); - convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101); - convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff); - convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50); - convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070); - convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000); - convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000); - convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101); - convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff); - convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0); - convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140); - convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000); - convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000); - convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101); - convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff); - convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190); - convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000); - convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140); - convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000); - convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000); - convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000); - convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000); - /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */ - convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000); - convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000); - convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000); - convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000); - convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000); - convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000); - convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000); - convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000); - convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001); - convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000); - convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff); - convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200); - convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000); - convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000); - convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000); - convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff); - convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000); - convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000); - convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000); - convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000); - convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a); - convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000); - convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000); - convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e); - convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000); - convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000); - convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e); - convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000); - convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff); - convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077); - convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8); - convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000); - convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002); - convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000); - convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000); - convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000); - convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f); - convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000); - convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff); - convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9); - convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c); - convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0); - convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000); - convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003); - convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000); - convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000); - convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000); - convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004); - convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004); - convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000); - convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000); - convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000); - convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000); - convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000); - convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000); - convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000); - convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000); - convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000); - convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005); - convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000); - convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000); - convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000); - convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000); - convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006); - convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000); - convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000); - convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000); - convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000); - convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff); - convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000); - convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000); - convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001); - convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff); - convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000); - convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000); - convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002); - convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff); - convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000); - convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000); - convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003); - convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff); - convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000); -} - -#endif - -} - - - - - -#ifdef DEFINE_DUMP_RTNS -/* - * these were useful for printing out registers etc - * during bringup - */ - -static void -xdump(long long *addr, int count) -{ - int ii; - volatile long long *xx = addr; - - for ( ii = 0; ii < count; ii++, xx++ ) { - printk("0x%p : 0x%p\n", (void *)xx, (void *)*xx); - } -} - -static void -xdump32(unsigned int *addr, int count) -{ - int ii; - volatile unsigned int *xx = addr; - - for ( ii = 0; ii < count; ii++, xx++ ) { - printk("0x%p : 0x%0x\n", (void *)xx, (int)*xx); - } -} - -static void -clear_ii_error(void) -{ - volatile long long *tmp; - - printk("... WSTAT "); - xdump((long long *)0xc0000a0001c00008, 1); - printk("... WCTRL "); - xdump((long long *)0xc0000a0001c00020, 1); - printk("... WLCSR "); - xdump((long long *)0xc0000a0001c00128, 1); - printk("... IIDSR "); - xdump((long long *)0xc0000a0001c00138, 1); - printk("... IOPRBs "); - xdump((long long *)0xc0000a0001c00198, 9); - printk("... IXSS "); - xdump((long long *)0xc0000a0001c00210, 1); - printk("... IBLS0 "); - xdump((long long *)0xc0000a0001c10000, 1); - printk("... IBLS1 "); - xdump((long long *)0xc0000a0001c20000, 1); - - /* Write IOERR clear to clear the CRAZY bit in the status */ - tmp = (long long *)0xc0000a0001c001f8; *tmp = (long long)0xffffffff; - - /* dump out local block error registers */ - printk("... "); - xdump((long long *)0xc0000a0001e04040, 1); /* LB_ERROR_BITS */ - printk("... "); - xdump((long long *)0xc0000a0001e04050, 1); /* LB_ERROR_HDR1 */ - printk("... "); - xdump((long long *)0xc0000a0001e04058, 1); /* LB_ERROR_HDR2 */ - /* and clear the LB_ERROR_BITS */ - tmp = (long long *)0xc0000a0001e04040; *tmp = 0x0; - printk("clr: "); - xdump((long long *)0xc0000a0001e04040, 1); /* LB_ERROR_BITS */ - tmp = (long long *)0xc0000a0001e04050; *tmp = 0x0; - tmp = (long long *)0xc0000a0001e04058; *tmp = 0x0; -} - - -static void -dump_ii(void) -{ - printk("===== Dump the II regs =====\n"); - xdump((long long *)0xc0000a0001c00000, 2); - xdump((long long *)0xc0000a0001c00020, 1); - xdump((long long *)0xc0000a0001c00100, 37); - xdump((long long *)0xc0000a0001c00300, 98); - xdump((long long *)0xc0000a0001c10000, 6); - xdump((long long *)0xc0000a0001c20000, 6); - xdump((long long *)0xc0000a0001c30000, 2); - - xdump((long long *)0xc0000a0000000000, 1); - xdump((long long *)0xc0000a0001000000, 1); - xdump((long long *)0xc0000a0002000000, 1); - xdump((long long *)0xc0000a0003000000, 1); - xdump((long long *)0xc0000a0004000000, 1); - xdump((long long *)0xc0000a0005000000, 1); - xdump((long long *)0xc0000a0006000000, 1); - xdump((long long *)0xc0000a0007000000, 1); - xdump((long long *)0xc0000a0008000000, 1); - xdump((long long *)0xc0000a0009000000, 1); - xdump((long long *)0xc0000a000a000000, 1); - xdump((long long *)0xc0000a000b000000, 1); - xdump((long long *)0xc0000a000c000000, 1); - xdump((long long *)0xc0000a000d000000, 1); - xdump((long long *)0xc0000a000e000000, 1); - xdump((long long *)0xc0000a000f000000, 1); -} - -static void -dump_crossbow(void) -{ - printk("===== Dump the Crossbow regs =====\n"); - clear_ii_error(); - xdump32((unsigned int *)0xc0000a0000000004, 1); - clear_ii_error(); - xdump32((unsigned int *)0xc0000a0000000000, 1); - printk("and again..\n"); - xdump32((unsigned int *)0xc0000a0000000000, 1); - xdump32((unsigned int *)0xc0000a0000000000, 1); - - - clear_ii_error(); - - xdump32((unsigned int *)0xc000020000000004, 1); - clear_ii_error(); - xdump32((unsigned int *)0xc000020000000000, 1); - clear_ii_error(); - - xdump32((unsigned int *)0xc0000a0000800004, 1); - clear_ii_error(); - xdump32((unsigned int *)0xc0000a0000800000, 1); - clear_ii_error(); - - xdump32((unsigned int *)0xc000020000800004, 1); - clear_ii_error(); - xdump32((unsigned int *)0xc000020000800000, 1); - clear_ii_error(); - - -} -#endif /* DEFINE_DUMP_RTNS */ diff -urN linux-2.4.21/arch/ia64/sn/io/l1.c linux-2.4.22/arch/ia64/sn/io/l1.c --- linux-2.4.21/arch/ia64/sn/io/l1.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/l1.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,3143 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* In general, this file is organized in a hierarchy from lower-level - * to higher-level layers, as follows: - * - * UART routines - * Bedrock/L1 "PPP-like" protocol implementation - * System controller "message" interface (allows multiplexing - * of various kinds of requests and responses with - * console I/O) - * Console interface: - * "l1_cons", the glue that allows the L1 to act - * as the system console for the stdio libraries - * - * Routines making use of the system controller "message"-style interface - * can be found in l1_command.c. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_IA64_SGI_SN2) -#define USE_SAL_CONSOLE_IO 1 /* DON'T un-def this for the simulator... */ -#endif - -/* Make all console writes atomic */ -#define SYNC_CONSOLE_WRITE 1 - - -/********************************************************************* - * Hardware-level (UART) driver routines. - */ - -/* macros for reading/writing registers */ - -#define LD(x) (*(volatile uint64_t *)(x)) -#define SD(x, v) (LD(x) = (uint64_t) (v)) - -/* location of uart receive/xmit data register */ -#if defined(CONFIG_IA64_SGI_SN1) -#define L1_UART_BASE(n) ((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080)) -#define LOCK_HUB REMOTE_HUB_ADDR -#elif defined(CONFIG_IA64_SGI_SN2) -#define L1_UART_BASE(n) ((ulong)REMOTE_HUB((n), SH_JUNK_BUS_UART0)) -#define LOCK_HUB REMOTE_HUB -typedef u64 rtc_time_t; -#endif - - -#define ADDR_L1_REG(n, r) ( L1_UART_BASE(n) | ( (r) << 3 ) ) -#define READ_L1_UART_REG(n, r) ( LD(ADDR_L1_REG((n), (r))) ) -#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) ) - -/* upper layer interface calling methods */ -#define SERIAL_INTERRUPT_MODE 0 -#define SERIAL_POLLED_MODE 1 - - -/* UART-related #defines */ - -#define UART_BAUD_RATE 57600 -#define UART_FIFO_DEPTH 16 -#define UART_DELAY_SPAN 10 -#define UART_PUTC_TIMEOUT 50000 -#define UART_INIT_TIMEOUT 100000 - -/* error codes */ -#define UART_SUCCESS 0 -#define UART_TIMEOUT (-1) -#define UART_LINK (-2) -#define UART_NO_CHAR (-3) -#define UART_VECTOR (-4) - -#define UART_DELAY(x) udelay(x) - -/* Some debug counters */ -#define L1C_INTERRUPTS 0 -#define L1C_OUR_R_INTERRUPTS 1 -#define L1C_OUR_X_INTERRUPTS 2 -#define L1C_SEND_CALLUPS 3 -#define L1C_RECEIVE_CALLUPS 4 -#define L1C_SET_BAUD 5 -#define L1C_ALREADY_LOCKED L1C_SET_BAUD -#define L1C_R_IRQ 6 -#define L1C_R_IRQ_RET 7 -#define L1C_LOCK_TIMEOUTS 8 -#define L1C_LOCK_COUNTER 9 -#define L1C_UNLOCK_COUNTER 10 -#define L1C_REC_STALLS 11 -#define L1C_CONNECT_CALLS 12 -#define L1C_SIZE L1C_CONNECT_CALLS /* Set to the last one */ - -uint64_t L1_collectibles[L1C_SIZE + 1]; - - -/* - * Some macros for handling Endian-ness - */ - -#define COPY_INT_TO_BUFFER(_b, _i, _n) \ - { \ - _b[_i++] = (_n >> 24) & 0xff; \ - _b[_i++] = (_n >> 16) & 0xff; \ - _b[_i++] = (_n >> 8) & 0xff; \ - _b[_i++] = _n & 0xff; \ - } - -#define COPY_BUFFER_TO_INT(_b, _i, _n) \ - { \ - _n = (_b[_i++] << 24) & 0xff; \ - _n |= (_b[_i++] << 16) & 0xff; \ - _n |= (_b[_i++] << 8) & 0xff; \ - _n |= _b[_i++] & 0xff; \ - } - -#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn) \ - { \ - char *_xyz = (char *)_bn; \ - _xyz[3] = _b[_i++]; \ - _xyz[2] = _b[_i++]; \ - _xyz[1] = _b[_i++]; \ - _xyz[0] = _b[_i++]; \ - } - -void snia_kmem_free(void *where, int size); - -#define ALREADY_LOCKED 1 -#define NOT_LOCKED 0 -static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ ); - -#define BCOPY(x,y,z) memcpy(y,x,z) - -uint8_t L1_interrupts_connected; /* Non-zero when we are in interrupt mode */ - - -/* - * Console locking defines and functions. - * - */ - -uint8_t L1_cons_is_inited = 0; /* non-zero when console is init'd */ -nasid_t Master_console_nasid = (nasid_t)-1; -extern nasid_t console_nasid; - -#if defined(CONFIG_IA64_SGI_SN1) -u64 ia64_sn_get_console_nasid(void); -#endif - -inline nasid_t -get_master_nasid(void) -{ -#if defined(CONFIG_IA64_SGI_SN1) - nasid_t nasid = Master_console_nasid; - - if ( nasid == (nasid_t)-1 ) { - nasid = (nasid_t)ia64_sn_get_console_nasid(); - if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) { - /* Out of bounds, use local */ - console_nasid = nasid = get_nasid(); - } - else { - /* Got a valid nasid, set the console_nasid */ - char xx[100]; -/* zzzzzz - force nasid to 0 for now */ - sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid); -nasid = 0; -/* end zzzzzz */ - xx[99] = (char)0; - early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED); - Master_console_nasid = console_nasid = nasid; - } - } - return(nasid); -#else - return((nasid_t)0); -#endif /* CONFIG_IA64_SGI_SN1 */ -} - - -#if defined(CONFIG_IA64_SGI_SN1) - -#define HUB_LOCK 16 - -#define PRIMARY_LOCK_TIMEOUT 10000000 -#define HUB_LOCK_REG(n) LOCK_HUB(n, MD_PERF_CNT0) - -#define SET_BITS(reg, bits) SD(reg, LD(reg) | (bits)) -#define CLR_BITS(reg, bits) SD(reg, LD(reg) & ~(bits)) -#define TST_BITS(reg, bits) ((LD(reg) & (bits)) != 0) - -#define HUB_TEST_AND_SET(n) LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ)) -#define HUB_CLEAR(n) SD(LOCK_HUB(n,LB_SCRATCH_REG3),0) - -#define RTC_TIME_MAX ((rtc_time_t) ~0ULL) - -/* - * primary_lock - * - * Allows CPU's 0-3 to mutually exclude the hub from one another by - * obtaining a blocking lock. Does nothing if only one CPU is active. - * - * This lock should be held just long enough to set or clear a global - * lock bit. After a relatively short timeout period, this routine - * figures something is wrong, and steals the lock. It does not set - * any other CPU to "dead". - */ -inline void -primary_lock(nasid_t nasid) -{ - rtc_time_t expire; - - expire = rtc_time() + PRIMARY_LOCK_TIMEOUT; - - while (HUB_TEST_AND_SET(nasid)) { - if (rtc_time() > expire) { - HUB_CLEAR(nasid); - } - } -} - -/* - * primary_unlock (internal) - * - * Counterpart to primary_lock - */ - -inline void -primary_unlock(nasid_t nasid) -{ - HUB_CLEAR(nasid); -} - -/* - * hub_unlock - * - * Counterpart to hub_lock_timeout and hub_lock - */ - -inline void -hub_unlock(nasid_t nasid, int level) -{ - uint64_t mask = 1ULL << level; - - primary_lock(nasid); - CLR_BITS(HUB_LOCK_REG(nasid), mask); - primary_unlock(nasid); -} - -/* - * hub_lock_timeout - * - * Uses primary_lock to implement multiple lock levels. - * - * There are 20 lock levels from 0 to 19 (limited by the number of bits - * in HUB_LOCK_REG). To prevent deadlock, multiple locks should be - * obtained in order of increasingly higher level, and released in the - * reverse order. - * - * A timeout value of 0 may be used for no timeout. - * - * Returns 0 if successful, -1 if lock times out. - */ - -inline int -hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout) -{ - uint64_t mask = 1ULL << level; - rtc_time_t expire = (timeout ? rtc_time() + timeout : RTC_TIME_MAX); - int done = 0; - - while (! done) { - while (TST_BITS(HUB_LOCK_REG(nasid), mask)) { - if (rtc_time() > expire) - return -1; - } - - primary_lock(nasid); - - if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) { - SET_BITS(HUB_LOCK_REG(nasid), mask); - done = 1; - } - primary_unlock(nasid); - } - return 0; -} - - -#define LOCK_TIMEOUT (0x1500000 * 1) /* 0x1500000 is ~30 sec */ - -void -lock_console(nasid_t nasid) -{ - int ret; - - /* If we already have it locked, just return */ - L1_collectibles[L1C_LOCK_COUNTER]++; - - ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT); - if ( ret != 0 ) { - L1_collectibles[L1C_LOCK_TIMEOUTS]++; - /* timeout */ - hub_unlock(nasid, HUB_LOCK); - /* If the 2nd lock fails, just pile ahead.... */ - hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT); - L1_collectibles[L1C_LOCK_TIMEOUTS]++; - } -} - -inline void -unlock_console(nasid_t nasid) -{ - L1_collectibles[L1C_UNLOCK_COUNTER]++; - hub_unlock(nasid, HUB_LOCK); -} - -#else /* SN2 */ -inline void lock_console(nasid_t n) {} -inline void unlock_console(nasid_t n) {} - -#endif /* CONFIG_IA64_SGI_SN1 */ - -int -get_L1_baud(void) -{ - return UART_BAUD_RATE; -} - - -/* uart driver functions */ - -static inline void -uart_delay( rtc_time_t delay_span ) -{ - UART_DELAY( delay_span ); -} - -#define UART_PUTC_READY(n) (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE) - -static int -uart_putc( l1sc_t *sc ) -{ - WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] ); - return UART_SUCCESS; -} - - -static int -uart_getc( l1sc_t *sc ) -{ - u_char lsr_reg = 0; - nasid_t nasid = sc->nasid; - - if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & - (LSR_RCA | LSR_PARERR | LSR_FRMERR) ) - { - if( lsr_reg & LSR_RCA ) - return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) ); - else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) { - return UART_LINK; - } - } - - return UART_NO_CHAR; -} - - -#define PROM_SER_CLK_SPEED 12000000 -#define PROM_SER_DIVISOR(x) (PROM_SER_CLK_SPEED / ((x) * 16)) - -static void -uart_init( l1sc_t *sc, int baud ) -{ - rtc_time_t expire; - int clkdiv; - nasid_t nasid; - - clkdiv = PROM_SER_DIVISOR(baud); - expire = rtc_time() + UART_INIT_TIMEOUT; - nasid = sc->nasid; - - /* make sure the transmit FIFO is empty */ - while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) { - uart_delay( UART_DELAY_SPAN ); - if( rtc_time() > expire ) { - break; - } - } - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(nasid); - - /* Setup for the proper baud rate */ - WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff ); - uart_delay( UART_DELAY_SPAN ); - - /* set operating parameters and set DLAB to 0 */ - - /* 8bit, one stop, clear request to send, auto flow control */ - WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE ); - uart_delay( UART_DELAY_SPAN ); - - /* disable interrupts */ - WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 ); - uart_delay( UART_DELAY_SPAN ); - - /* enable FIFO mode and reset both FIFOs, trigger on 1 */ - WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0); - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(nasid); -} - -/* This requires the console lock */ - -#if defined(CONFIG_IA64_SGI_SN1) - -static void -uart_intr_enable( l1sc_t *sc, u_char mask ) -{ - u_char lcr_reg, icr_reg; - nasid_t nasid = sc->nasid; - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(nasid); - - /* make sure that the DLAB bit in the LCR register is 0 - */ - lcr_reg = READ_L1_UART_REG( nasid, REG_LCR ); - lcr_reg &= ~(LCR_DLAB); - WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg ); - - /* enable indicated interrupts - */ - icr_reg = READ_L1_UART_REG( nasid, REG_ICR ); - icr_reg |= mask; - WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ ); - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(nasid); -} - -/* This requires the console lock */ -static void -uart_intr_disable( l1sc_t *sc, u_char mask ) -{ - u_char lcr_reg, icr_reg; - nasid_t nasid = sc->nasid; - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(nasid); - - /* make sure that the DLAB bit in the LCR register is 0 - */ - lcr_reg = READ_L1_UART_REG( nasid, REG_LCR ); - lcr_reg &= ~(LCR_DLAB); - WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg ); - - /* enable indicated interrupts - */ - icr_reg = READ_L1_UART_REG( nasid, REG_ICR ); - icr_reg &= mask; - WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ ); - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(nasid); -} -#endif /* CONFIG_IA64_SGI_SN1 */ - -#define uart_enable_xmit_intr(sc) \ - uart_intr_enable((sc), ICR_TIEN) - -#define uart_disable_xmit_intr(sc) \ - uart_intr_disable((sc), ~(ICR_TIEN)) - -#define uart_enable_recv_intr(sc) \ - uart_intr_enable((sc), ICR_RIEN) - -#define uart_disable_recv_intr(sc) \ - uart_intr_disable((sc), ~(ICR_RIEN)) - - -/********************************************************************* - * Routines for accessing a remote (router) UART - */ - -#define READ_RTR_L1_UART_REG(p, n, r, v) \ - { \ - if( vector_read_node( (p), (n), 0, \ - RR_JBUS1(r), (v) ) ) { \ - return UART_VECTOR; \ - } \ - } - -#define WRITE_RTR_L1_UART_REG(p, n, r, v) \ - { \ - if( vector_write_node( (p), (n), 0, \ - RR_JBUS1(r), (v) ) ) { \ - return UART_VECTOR; \ - } \ - } - -#define RTR_UART_PUTC_TIMEOUT UART_PUTC_TIMEOUT*10 -#define RTR_UART_DELAY_SPAN UART_DELAY_SPAN -#define RTR_UART_INIT_TIMEOUT UART_INIT_TIMEOUT*10 - -static int -rtr_uart_putc( l1sc_t *sc ) -{ - uint64_t regval, c; - nasid_t nasid = sc->nasid; - net_vec_t path = sc->uart; - rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT; - - c = (sc->send[sc->sent] & 0xffULL); - - while( 1 ) - { - /* Check for "tx hold reg empty" bit. */ - READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); - if( regval & LSR_XHRE ) - { - WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c ); - return UART_SUCCESS; - } - - if( rtc_time() >= expire ) - { - return UART_TIMEOUT; - } - uart_delay( RTR_UART_DELAY_SPAN ); - } -} - - -static int -rtr_uart_getc( l1sc_t *sc ) -{ - uint64_t regval; - nasid_t nasid = sc->nasid; - net_vec_t path = sc->uart; - - READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); - if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) ) - { - if( regval & LSR_RCA ) - { - READ_RTR_L1_UART_REG( path, nasid, REG_DAT, ®val ); - return( (int)regval ); - } - else - { - return UART_LINK; - } - } - - return UART_NO_CHAR; -} - - -static int -rtr_uart_init( l1sc_t *sc, int baud ) -{ - rtc_time_t expire; - int clkdiv; - nasid_t nasid; - net_vec_t path; - uint64_t regval; - - clkdiv = PROM_SER_DIVISOR(baud); - expire = rtc_time() + RTR_UART_INIT_TIMEOUT; - nasid = sc->nasid; - path = sc->uart; - - /* make sure the transmit FIFO is empty */ - while(1) { - READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); - if( regval & LSR_XSRE ) { - break; - } - if( rtc_time() > expire ) { - break; - } - uart_delay( RTR_UART_DELAY_SPAN ); - } - - WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff ); - uart_delay( UART_DELAY_SPAN ); - - /* set operating parameters and set DLAB to 0 */ - WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE ); - uart_delay( UART_DELAY_SPAN ); - - /* disable interrupts */ - WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0 ); - uart_delay( UART_DELAY_SPAN ); - - /* enable FIFO mode and reset both FIFOs */ - WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, - FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO ); - - return 0; -} - -/********************************************************************* - * locking macros - */ - -#define L1SC_SEND_LOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); } -#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); } -#define L1SC_RECV_LOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } -#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); } - - -/********************************************************************* - * subchannel manipulation - * - * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel - * allocation. SUBCH_DATA_[UN]LOCK control access to data structures - * associated with particular subchannels (e.g., receive queues). - * - */ -#define SUBCH_LOCK(sc, p) spin_lock_irqsave( &((sc)->subch_lock), p ) -#define SUBCH_UNLOCK(sc, p) spin_unlock_irqrestore( &((sc)->subch_lock), p ) -#define SUBCH_DATA_LOCK(sbch, p) spin_lock_irqsave( &((sbch)->data_lock), p ) -#define SUBCH_DATA_UNLOCK(sbch, p) spin_unlock_irqrestore( &((sbch)->data_lock), p ) - - -/* - * set a function to be called for subchannel ch in the event of - * a transmission low-water interrupt from the uart - */ -void -subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func ) -{ - unsigned long pl = 0; - - L1SC_SEND_LOCK( sc, pl ); -#if !defined(SYNC_CONSOLE_WRITE) - if ( func && !sc->send_in_use ) - uart_enable_xmit_intr( sc ); -#endif - sc->subch[ch].tx_notify = func; - L1SC_SEND_UNLOCK(sc, pl ); -} - -/* - * set a function to be called for subchannel ch when data is received - */ -void -subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func ) -{ - unsigned long pl = 0; - brl1_sch_t *subch = &(sc->subch[ch]); - - SUBCH_DATA_LOCK( subch, pl ); - sc->subch[ch].rx_notify = func; - SUBCH_DATA_UNLOCK( subch, pl ); -} - -/********************************************************************* - * Queue manipulation macros - * - * - */ -#define NEXT(p) (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */ - -#define cq_init(q) bzero((q), sizeof (*(q))) -#define cq_empty(q) ((q)->ipos == (q)->opos) -#define cq_full(q) (NEXT((q)->ipos) == (q)->opos) -#define cq_used(q) ((q)->opos <= (q)->ipos ? \ - (q)->ipos - (q)->opos : \ - BRL1_QSIZE + (q)->ipos - (q)->opos) -#define cq_room(q) ((q)->opos <= (q)->ipos ? \ - BRL1_QSIZE - 1 + (q)->opos - (q)->ipos : \ - (q)->opos - (q)->ipos - 1) -#define cq_add(q, c) ((q)->buf[(q)->ipos] = (u_char) (c), \ - (q)->ipos = NEXT((q)->ipos)) -#define cq_rem(q, c) ((c) = (q)->buf[(q)->opos], \ - (q)->opos = NEXT((q)->opos)) -#define cq_discard(q) ((q)->opos = NEXT((q)->opos)) - -#define cq_tent_full(q) (NEXT((q)->tent_next) == (q)->opos) -#define cq_tent_len(q) ((q)->ipos <= (q)->tent_next ? \ - (q)->tent_next - (q)->ipos : \ - BRL1_QSIZE + (q)->tent_next - (q)->ipos) -#define cq_tent_add(q, c) \ - ((q)->buf[(q)->tent_next] = (u_char) (c), \ - (q)->tent_next = NEXT((q)->tent_next)) -#define cq_commit_tent(q) \ - ((q)->ipos = (q)->tent_next) -#define cq_discard_tent(q) \ - ((q)->tent_next = (q)->ipos) - - - - -/********************************************************************* - * CRC-16 (for checking bedrock/L1 packets). - * - * These are based on RFC 1662 ("PPP in HDLC-like framing"). - */ - -static unsigned short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -#define INIT_CRC 0xFFFF /* initial CRC value */ -#define GOOD_CRC 0xF0B8 /* "good" final CRC value */ - -static unsigned short crc16_calc( unsigned short crc, u_char c ) -{ - return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] ); -} - - -/*********************************************************************** - * The following functions implement the PPP-like bedrock/L1 protocol - * layer. - * - */ - -#define BRL1_FLAG_CH 0x7e -#define BRL1_ESC_CH 0x7d -#define BRL1_XOR_CH 0x20 - -/* L1<->Bedrock packet types */ -#define BRL1_REQUEST 0x00 -#define BRL1_RESPONSE 0x20 -#define BRL1_EVENT 0x40 - -#define BRL1_PKT_TYPE_MASK 0xE0 -#define BRL1_SUBCH_MASK 0x1F - -#define PKT_TYPE(tsb) ((tsb) & BRL1_PKT_TYPE_MASK) -#define SUBCH(tsb) ((tsb) & BRL1_SUBCH_MASK) - -/* timeouts */ -#define BRL1_INIT_TIMEOUT 500000 - -/* - * brl1_discard_packet is a dummy "receive callback" used to get rid - * of packets we don't want - */ -void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch ) -{ - unsigned long pl = 0; - brl1_sch_t *subch = &sc->subch[ch]; - - sc_cq_t *q = subch->iqp; - SUBCH_DATA_LOCK( subch, pl ); - q->opos = q->ipos; - atomic_set(&(subch->packet_arrived), 0); - SUBCH_DATA_UNLOCK( subch, pl ); -} - - -/* - * brl1_send_chars sends the send buffer in the l1sc_t structure - * out through the uart. Assumes that the caller has locked the - * UART (or send buffer in the kernel). - * - * This routine doesn't block-- if you want it to, call it in - * a loop. - */ -static int -brl1_send_chars( l1sc_t *sc ) -{ - /* We track the depth of the C brick's UART's - * fifo in software, and only check if the UART is accepting - * characters when our count indicates that the fifo should - * be full. - * - * For remote (router) UARTs, we check with the UART before sending every - * character. - */ - if( sc->uart == BRL1_LOCALHUB_UART ) { - if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) ) - sc->fifo_space = UART_FIFO_DEPTH; - - while( (sc->sent < sc->send_len) && (sc->fifo_space) ) { - uart_putc( sc ); - sc->fifo_space--; - sc->sent++; - } - } - else { - - /* remote (router) UARTs */ - - int result; - int tries = 0; - - while( sc->sent < sc->send_len ) { - result = sc->putc_f( sc ); - if( result >= 0 ) { - (sc->sent)++; - continue; - } - if( result == UART_TIMEOUT ) { - tries++; - /* send this character in TIMEOUT_RETRIES... */ - if( tries < 30 /* TIMEOUT_RETRIES */ ) { - continue; - } - /* ...or else... */ - else { - /* ...drop the packet. */ - sc->sent = sc->send_len; - return sc->send_len; - } - } - if( result < 0 ) { - return result; - } - } - } - return sc->sent; -} - - -/* brl1_send formats up a packet and (at least begins to) send it - * to the uart. If the send buffer is in use when this routine obtains - * the lock, it will behave differently depending on the "wait" parameter. - * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"), - * hopefully encouraging the caller to back off (unlock any high-level - * spinlocks) and allow the buffer some time to drain. For wait==1 (high- - * priority I/O along the lines of kernel error messages), we will flush - * the current contents of the send buffer and beat on the uart - * until our message has been completely transmitted. - */ - -static int -brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait ) -{ - unsigned long pl = 0; - int index; - int pkt_len = 0; - unsigned short crc = INIT_CRC; - char *send_ptr = sc->send; - - - if( sc->send_in_use && !(wait) ) { - /* We are in the middle of sending, but can wait until done */ - return 0; - } - else if( sc->send_in_use ) { - /* buffer's in use, but we're synchronous I/O, so we're going - * to send whatever's in there right now and take the buffer - */ - int counter = 0; - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(sc->nasid); - L1SC_SEND_LOCK(sc, pl); - while( sc->sent < sc->send_len ) { - brl1_send_chars( sc ); - if ( counter++ > 0xfffff ) { - char *str = "Looping waiting for uart to clear (1)\n"; - early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED); - break; - } - } - } - else { - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(sc->nasid); - L1SC_SEND_LOCK(sc, pl); - sc->send_in_use = 1; - } - *send_ptr++ = BRL1_FLAG_CH; - *send_ptr++ = type_and_subch; - pkt_len += 2; - crc = crc16_calc( crc, type_and_subch ); - - /* limit number of characters accepted to max payload size */ - if( len > (BRL1_QSIZE - 1) ) - len = (BRL1_QSIZE - 1); - - /* copy in the message buffer (inserting PPP - * framing info where necessary) - */ - for( index = 0; index < len; index++ ) { - - switch( *msg ) { - - case BRL1_FLAG_CH: - *send_ptr++ = BRL1_ESC_CH; - *send_ptr++ = (*msg) ^ BRL1_XOR_CH; - pkt_len += 2; - break; - - case BRL1_ESC_CH: - *send_ptr++ = BRL1_ESC_CH; - *send_ptr++ = (*msg) ^ BRL1_XOR_CH; - pkt_len += 2; - break; - - default: - *send_ptr++ = *msg; - pkt_len++; - } - crc = crc16_calc( crc, *msg ); - msg++; - } - crc ^= 0xffff; - - for( index = 0; index < sizeof(crc); index++ ) { - char crc_char = (char)(crc & 0x00FF); - if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { - *send_ptr++ = BRL1_ESC_CH; - pkt_len++; - crc_char ^= BRL1_XOR_CH; - } - *send_ptr++ = crc_char; - pkt_len++; - crc >>= 8; - } - - *send_ptr++ = BRL1_FLAG_CH; - pkt_len++; - - sc->send_len = pkt_len; - sc->sent = 0; - - { - int counter = 0; - do { - brl1_send_chars( sc ); - if ( counter++ > 0xfffff ) { - char *str = "Looping waiting for uart to clear (2)\n"; - early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED); - break; - } - } while( (sc->sent < sc->send_len) && wait ); - } - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(sc->nasid); - - if( sc->sent == sc->send_len ) { - /* success! release the send buffer and call the callup */ -#if !defined(SYNC_CONSOLE_WRITE) - brl1_notif_t callup; -#endif - - sc->send_in_use = 0; - /* call any upper layer that's asked for notification */ -#if defined(XX_SYNC_CONSOLE_WRITE) - /* - * This is probably not a good idea - since the l1_ write func can be called multiple - * time within the callup function. - */ - callup = subch->tx_notify; - if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) { - L1_collectibles[L1C_SEND_CALLUPS]++; - (*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq, - sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id, - sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch)); - } -#endif /* SYNC_CONSOLE_WRITE */ - } -#if !defined(SYNC_CONSOLE_WRITE) - else if ( !wait ) { - /* enable low-water interrupts so buffer will be drained */ - uart_enable_xmit_intr(sc); - } -#endif - - L1SC_SEND_UNLOCK(sc, pl); - - return len; -} - -/* brl1_send_cont is intended to be called as an interrupt service - * routine. It sends until the UART won't accept any more characters, - * or until an error is encountered (in which case we surrender the - * send buffer and give up trying to send the packet). Once the - * last character in the packet has been sent, this routine releases - * the send buffer and calls any previously-registered "low-water" - * output routines. - */ - -#if !defined(SYNC_CONSOLE_WRITE) - -int -brl1_send_cont( l1sc_t *sc ) -{ - unsigned long pl = 0; - int done = 0; - brl1_notif_t callups[BRL1_NUM_SUBCHANS]; - brl1_notif_t *callup; - brl1_sch_t *subch; - int index; - - /* - * I'm not sure how I think this is to be handled - whether the lock is held - * over the interrupt - but it seems like it is a bad idea.... - */ - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(sc->nasid); - L1SC_SEND_LOCK(sc, pl); - brl1_send_chars( sc ); - done = (sc->sent == sc->send_len); - if( done ) { - sc->send_in_use = 0; -#if !defined(SYNC_CONSOLE_WRITE) - uart_disable_xmit_intr(sc); -#endif - } - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(sc->nasid); - /* Release the lock */ - L1SC_SEND_UNLOCK(sc, pl); - - return 0; -} -#endif /* SYNC_CONSOLE_WRITE */ - -/* internal function -- used by brl1_receive to read a character - * from the uart and check whether errors occurred in the process. - */ -static int -read_uart( l1sc_t *sc, int *c, int *result ) -{ - *c = sc->getc_f( sc ); - - /* no character is available */ - if( *c == UART_NO_CHAR ) { - *result = BRL1_NO_MESSAGE; - return 0; - } - - /* some error in UART */ - if( *c < 0 ) { - *result = BRL1_LINK; - return 0; - } - - /* everything's fine */ - *result = BRL1_VALID; - return 1; -} - - -/* - * brl1_receive - * - * This function reads a Bedrock-L1 protocol packet into the l1sc_t - * response buffer. - * - * The operation of this function can be expressed as a finite state - * machine: - * - -START STATE INPUT TRANSITION -========================================================== -BRL1_IDLE (reset or error) flag BRL1_FLAG - other BRL1_IDLE@ - -BRL1_FLAG (saw a flag (0x7e)) flag BRL1_FLAG - escape BRL1_IDLE@ - header byte BRL1_HDR - other BRL1_IDLE@ - -BRL1_HDR (saw a type/subch byte)(see below) BRL1_BODY - BRL1_HDR - -BRL1_BODY (reading packet body) flag BRL1_FLAG - escape BRL1_ESC - other BRL1_BODY - -BRL1_ESC (saw an escape (0x7d)) flag BRL1_FLAG@ - escape BRL1_IDLE@ - other BRL1_BODY -========================================================== - -"@" denotes an error transition. - - * The BRL1_HDR state is a transient state which doesn't read input, - * but just provides a way in to code which decides to whom an - * incoming packet should be directed. - * - * brl1_receive can be used to poll for input from the L1, or as - * an interrupt service routine. It reads as much data as is - * ready from the junk bus UART and places into the appropriate - * input queues according to subchannel. The header byte is - * stripped from console-type data, but is retained for message- - * type data (L1 responses). A length byte will also be - * prepended to message-type packets. - * - * This routine is non-blocking; if the caller needs to block - * for input, it must call brl1_receive in a loop. - * - * brl1_receive returns when there is no more input, the queue - * for the current incoming message is full, or there is an - * error (parity error, bad header, bad CRC, etc.). - */ - -#define STATE_SET(l,s) ((l)->brl1_state = (s)) -#define STATE_GET(l) ((l)->brl1_state) - -#define LAST_HDR_SET(l,h) ((l)->brl1_last_hdr = (h)) -#define LAST_HDR_GET(l) ((l)->brl1_last_hdr) - -#define VALID_HDR(c) \ - ( SUBCH((c)) <= SC_CONS_SYSTEM \ - ? PKT_TYPE((c)) == BRL1_REQUEST \ - : ( PKT_TYPE((c)) == BRL1_RESPONSE || \ - PKT_TYPE((c)) == BRL1_EVENT ) ) - -#define IS_TTY_PKT(l) ( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 ) - - -int -brl1_receive( l1sc_t *sc, int mode ) -{ - int result; /* value to be returned by brl1_receive */ - int c; /* most-recently-read character */ - int done; /* set done to break out of recv loop */ - unsigned long pl = 0, cpl = 0; - sc_cq_t *q; /* pointer to queue we're working with */ - - result = BRL1_NO_MESSAGE; - - L1SC_RECV_LOCK(sc, cpl); - - done = 0; - while( !done ) - { - switch( STATE_GET(sc) ) - { - - case BRL1_IDLE: - /* Initial or error state. Waiting for a flag character - * to resynchronize with the L1. - */ - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - done = 1; - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* saw a flag character */ - STATE_SET( sc, BRL1_FLAG ); - continue; - } - break; - - case BRL1_FLAG: - /* One or more flag characters have been read; look for - * the beginning of a packet (header byte). - */ - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - if( c != UART_NO_CHAR ) - STATE_SET( sc, BRL1_IDLE ); - - done = 1; - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* multiple flags are OK */ - continue; - } - - if( !VALID_HDR( c ) ) { - /* if c isn't a flag it should have been - * a valid header, so we have an error - */ - result = BRL1_PROTOCOL; - STATE_SET( sc, BRL1_IDLE ); - done = 1; - continue; - } - - /* we have a valid header byte */ - LAST_HDR_SET( sc, c ); - STATE_SET( sc, BRL1_HDR ); - - break; - - case BRL1_HDR: - /* A header byte has been read. Do some bookkeeping. */ - q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; - ASSERT(q); - - if( !IS_TTY_PKT(sc) ) { - /* if this is an event or command response rather - * than console I/O, we need to reserve a couple - * of extra spaces in the queue for the header - * byte and a length byte; if we can't, stay in - * the BRL1_HDR state. - */ - if( cq_room( q ) < 2 ) { - result = BRL1_FULL_Q; - done = 1; - continue; - } - cq_tent_add( q, 0 ); /* reserve length byte */ - cq_tent_add( q, LAST_HDR_GET( sc ) ); /* record header byte */ - } - STATE_SET( sc, BRL1_BODY ); - - break; - - case BRL1_BODY: - /* A header byte has been read. We are now attempting - * to receive the packet body. - */ - - q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; - ASSERT(q); - - /* if the queue we want to write into is full, don't read from - * the uart (this provides backpressure to the L1 side) - */ - if( cq_tent_full( q ) ) { - result = BRL1_FULL_Q; - done = 1; - continue; - } - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - if( c != UART_NO_CHAR ) - STATE_SET( sc, BRL1_IDLE ); - done = 1; - continue; - } - - if( c == BRL1_ESC_CH ) { - /* prepare to unescape the next character */ - STATE_SET( sc, BRL1_ESC ); - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* flag signifies the end of a packet */ - - unsigned short crc; /* holds the crc as we calculate it */ - int i; /* index variable */ - brl1_sch_t *subch; /* subchannel for received packet */ - brl1_notif_t callup; /* "data ready" callup */ - - /* whatever else may happen, we've seen a flag and we're - * starting a new packet - */ - STATE_SET( sc, BRL1_FLAG ); - - /* if the packet body has less than 2 characters, - * it can't be a well-formed packet. Discard it. - */ - if( cq_tent_len( q ) < /* 2 + possible length byte */ - (2 + (IS_TTY_PKT(sc) ? 0 : 1)) ) - { - result = BRL1_PROTOCOL; - cq_discard_tent( q ); - STATE_SET( sc, BRL1_FLAG ); - done = 1; - continue; - } - - /* check CRC */ - - /* accumulate CRC, starting with the header byte and - * ending with the transmitted CRC. This should - * result in a known good value. - */ - crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) ); - for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE; - i != q->tent_next; - i = (i + 1) % BRL1_QSIZE ) - { - crc = crc16_calc( crc, q->buf[i] ); - } - - /* verify the caclulated crc against the "good" crc value; - * if we fail, discard the bad packet and return an error. - */ - if( crc != (unsigned short)GOOD_CRC ) { - result = BRL1_CRC; - cq_discard_tent( q ); - STATE_SET( sc, BRL1_FLAG ); - done = 1; - continue; - } - - /* so the crc check was ok. Now we discard the CRC - * from the end of the received bytes. - */ - q->tent_next += (BRL1_QSIZE - 2); - q->tent_next %= BRL1_QSIZE; - - /* get the subchannel and lock it */ - subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]); - SUBCH_DATA_LOCK( subch, pl ); - - /* if this isn't a console packet, we need to record - * a length byte - */ - if( !IS_TTY_PKT(sc) ) { - q->buf[q->ipos] = cq_tent_len( q ) - 1; - } - - /* record packet for posterity */ - cq_commit_tent( q ); - result = BRL1_VALID; - - /* notify subchannel owner that there's something - * on the queue for them - */ - atomic_inc(&(subch->packet_arrived)); - callup = subch->rx_notify; - SUBCH_DATA_UNLOCK( subch, pl ); - - if( callup && (mode == SERIAL_INTERRUPT_MODE) ) { - L1SC_RECV_UNLOCK( sc, cpl ); - L1_collectibles[L1C_RECEIVE_CALLUPS]++; - (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq, - sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id, - sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs, - sc, SUBCH(LAST_HDR_GET(sc)) ); - L1SC_RECV_LOCK( sc, cpl ); - } - continue; /* go back for more! */ - } - - /* none of the special cases applied; we've got a normal - * body character - */ - cq_tent_add( q, c ); - - break; - - case BRL1_ESC: - /* saw an escape character. The next character will need - * to be unescaped. - */ - - q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; - ASSERT(q); - - /* if the queue we want to write into is full, don't read from - * the uart (this provides backpressure to the L1 side) - */ - if( cq_tent_full( q ) ) { - result = BRL1_FULL_Q; - done = 1; - continue; - } - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - if( c != UART_NO_CHAR ) { - cq_discard_tent( q ); - STATE_SET( sc, BRL1_IDLE ); - } - done = 1; - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* flag after escape is an error */ - STATE_SET( sc, BRL1_FLAG ); - cq_discard_tent( q ); - result = BRL1_PROTOCOL; - done = 1; - continue; - } - - if( c == BRL1_ESC_CH ) { - /* two consecutive escapes is an error */ - STATE_SET( sc, BRL1_IDLE ); - cq_discard_tent( q ); - result = BRL1_PROTOCOL; - done = 1; - continue; - } - - /* otherwise, we've got a character that needs - * to be unescaped - */ - cq_tent_add( q, (c ^ BRL1_XOR_CH) ); - STATE_SET( sc, BRL1_BODY ); - - break; - - } /* end of switch( STATE_GET(sc) ) */ - } /* end of while(!done) */ - - L1SC_RECV_UNLOCK( sc, cpl ); - - return result; -} - - -/* brl1_init initializes the Bedrock/L1 protocol layer. This includes - * zeroing out the send and receive state information. - */ - -void -brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) -{ - int i; - brl1_sch_t *subch; - - bzero( sc, sizeof( *sc ) ); - sc->nasid = nasid; - sc->uart = uart; - sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc); - sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc); - sc->sol = 1; - subch = sc->subch; - - /* initialize L1 subchannels - */ - - /* assign processor TTY channels */ - for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) { - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ ); - subch->tx_notify = NULL; - /* (for now, drop elscuart packets in the kernel) */ - subch->rx_notify = brl1_discard_packet; - subch->iqp = &sc->garbage_q; - } - - /* assign system TTY channel (first free subchannel after each - * processor's individual TTY channel has been assigned) - */ - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ ); - subch->tx_notify = NULL; - if( sc->uart == BRL1_LOCALHUB_UART ) { - subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) ); - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - subch->rx_notify = NULL; - } - else { - /* we shouldn't be getting console input from remote UARTs */ - subch->iqp = &sc->garbage_q; - subch->rx_notify = brl1_discard_packet; - } - subch++; i++; - - /* "reserved" subchannels (0x05-0x0F); for now, throw away - * incoming packets - */ - for( ; i < 0x10; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = brl1_discard_packet; - subch->iqp = &sc->garbage_q; - } - - /* remaining subchannels are free */ - for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = brl1_discard_packet; - subch->iqp = &sc->garbage_q; - } - - /* initialize synchronization structures - */ - spin_lock_init( &(sc->subch_lock) ); - spin_lock_init( &(sc->send_lock) ); - spin_lock_init( &(sc->recv_lock) ); - - if( sc->uart == BRL1_LOCALHUB_UART ) { - uart_init( sc, UART_BAUD_RATE ); - } - else { - rtr_uart_init( sc, UART_BAUD_RATE ); - } - - /* Set up remaining fields using L1 command functions-- elsc_module_get - * to read the module id, elsc_debug_get to see whether or not we're - * in verbose mode. - */ - { - extern int elsc_module_get(l1sc_t *); - - sc->modid = elsc_module_get( sc ); - sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid); - sc->verbose = 1; - } -} - -/********************************************************************* - * These are interrupt-related functions used in the kernel to service - * the L1. - */ - -/* - * brl1_intrd is the function which is called on a console interrupt. - */ - -#if defined(CONFIG_IA64_SGI_SN1) - -static void -brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff) -{ - u_char isr_reg; - l1sc_t *sc = get_elsc(); - int ret; - - L1_collectibles[L1C_INTERRUPTS]++; - isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR); - - /* Save for callup args in console */ - sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq; - sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id; - sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff; - -#if defined(SYNC_CONSOLE_WRITE) - while( isr_reg & ISR_RxRDY ) -#else - while( isr_reg & (ISR_RxRDY | ISR_TxRDY) ) -#endif - { - if( isr_reg & ISR_RxRDY ) { - L1_collectibles[L1C_OUR_R_INTERRUPTS]++; - ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE); - if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) ) - L1_collectibles[L1C_REC_STALLS] = ret; - } -#if !defined(SYNC_CONSOLE_WRITE) - if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) { - L1_collectibles[L1C_OUR_X_INTERRUPTS]++; - brl1_send_cont(sc); - } -#endif /* SYNC_CONSOLE_WRITE */ - isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR); - } -} -#endif /* CONFIG_IA64_SGI_SN1 */ - - -/* - * Install a callback function for the system console subchannel - * to allow an upper layer to be notified when the send buffer - * has been emptied. - */ -static inline void -l1_tx_notif( brl1_notif_t func ) -{ - subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc, - SC_CONS_SYSTEM, func ); -} - - -/* - * Install a callback function for the system console subchannel - * to allow an upper layer to be notified when a packet has been - * received. - */ -static inline void -l1_rx_notif( brl1_notif_t func ) -{ - subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc, - SC_CONS_SYSTEM, func ); -} - - -/* brl1_intr is called directly from the uart interrupt; after it runs, the - * interrupt "daemon" xthread is signalled to continue. - */ -void -brl1_intr( void ) -{ -} - -#define BRL1_INTERRUPT_LEVEL 65 /* linux request_irq() value */ - -/* Return the current interrupt level */ - -//#define CONSOLE_POLLING_ALSO - -int -l1_get_intr_value( void ) -{ -#if defined(USE_SAL_CONSOLE_IO) - return(0); -#else -#if defined(CONSOLE_POLLING_ALSO) - return(0); -#else - return(BRL1_INTERRUPT_LEVEL); -#endif /* CONSOLE_POLLING_ALSO */ -#endif /* USE_SAL_CONSOLE_IO */ -} - -/* Disconnect the callup functions - throw away interrupts */ - -void -l1_unconnect_intr(void) -{ -#if !defined(USE_SAL_CONSOLE_IO) - /* UnRegister the upper-level callup functions */ - l1_rx_notif((brl1_notif_t)NULL); - l1_tx_notif((brl1_notif_t)NULL); - /* We do NOT unregister the interrupts */ -#endif /* !USE_SAL_CONSOLE_IO */ -} - -/* Set up uart interrupt handling for this node's uart */ - -void -l1_connect_intr(void *rx_notify, void *tx_notify) -{ -#if defined(USE_SAL_CONSOLE_IO) -#if 0 - // Will need code here for sn2 - something like this - console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()); - intr_connect_level(console_nodepda->node_first_cpu, - SGI_UART_VECTOR, INTPEND0_MAXMASK, - dummy_intr_func); - request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8), - intr_func, SA_INTERRUPT | SA_SHIRQ, - "l1_protocol_driver", (void *)sc); -#endif -#else - l1sc_t *sc; - nasid_t nasid; -#if defined(CONFIG_IA64_SGI_SN1) - int tmp; -#endif - nodepda_t *console_nodepda; - int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t); - - if ( L1_interrupts_connected ) { - /* Interrupts are connected, so just register the callups */ - l1_rx_notif((brl1_notif_t)rx_notify); - l1_tx_notif((brl1_notif_t)tx_notify); - - L1_collectibles[L1C_CONNECT_CALLS]++; - return; - } - else - L1_interrupts_connected = 1; - - nasid = get_master_nasid(); - console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid)); - sc = &console_nodepda->module->elsc; - sc->intr_cpu = console_nodepda->node_first_cpu; - -#if defined(CONFIG_IA64_SGI_SN1) - if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) { - L1_interrupts_connected = 0; /* FAILS !! */ - } - else { - void synergy_intr_connect(int, int); - - synergy_intr_connect(UART_INTR, sc->intr_cpu); - L1_collectibles[L1C_R_IRQ]++; - tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc); - L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp; - if ( tmp ) { - L1_interrupts_connected = 0; /* FAILS !! */ - } - else { - /* Register the upper-level callup functions */ - l1_rx_notif((brl1_notif_t)rx_notify); - l1_tx_notif((brl1_notif_t)tx_notify); - - /* Set the uarts the way we like it */ - uart_enable_recv_intr( sc ); - uart_disable_xmit_intr( sc ); - } - } -#endif /* CONFIG_IA64_SGI_SN1 */ -#endif /* USE_SAL_CONSOLE_IO */ -} - - -/* These are functions to use from serial_in/out when in protocol - * mode to send and receive uart control regs. These are external - * interfaces into the protocol driver. - */ - -void -l1_control_out(int offset, int value) -{ -#if defined(USE_SAL_CONSOLE_IO) - /* quietly ignore unless simulator */ - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - if ( master_node_bedrock_address != (u64)0 ) { - writeb(value, (unsigned long)master_node_bedrock_address + - (offset<< 3)); - } - return; - } -#else - nasid_t nasid = get_master_nasid(); - WRITE_L1_UART_REG(nasid, offset, value); -#endif -} - -/* Console input exported interface. Return a register value. */ - -int -l1_control_in_polled(int offset) -{ - static int l1_control_in_local(int, int); - - return(l1_control_in_local(offset, SERIAL_POLLED_MODE)); -} - -int -l1_control_in(int offset) -{ - static int l1_control_in_local(int, int); - - return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE)); -} - -static int -l1_control_in_local(int offset, int mode) -{ -#if defined(USE_SAL_CONSOLE_IO) - int sal_call_status = 0, input; - int ret = 0; - - if ( offset == REG_LSR ) { - ret = (LSR_XHRE | LSR_XSRE); /* can send anytime */ - sal_call_status = ia64_sn_console_check(&input); - if ( !sal_call_status && input ) { - /* input pending */ - ret |= LSR_RCA; - } - } - - /* If the sal call failed, do it the old-fashioned way */ - if ( sal_call_status ) { - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - ret = readb((unsigned long)master_node_bedrock_address + - (offset<< 3)); - } - else { -#endif /* USE_SAL_CONSOLE_IO */ - nasid_t nasid; - int ret, input; - static int l1_poll(l1sc_t *, int); - - nasid = get_master_nasid(); - ret = READ_L1_UART_REG(nasid, offset); - - if ( offset == REG_LSR ) { - ret |= (LSR_XHRE | LSR_XSRE); /* can send anytime */ - if ( L1_cons_is_inited ) { - if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) { - input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode); - if ( input ) { - ret |= LSR_RCA; - } - } - } - } -#if defined(USE_SAL_CONSOLE_IO) - } - } -#endif - return(ret); -} - -/* - * Console input exported interface. Return a character (if one is available) - */ - -int -l1_serial_in_polled(void) -{ - static int l1_serial_in_local(int mode); - - return(l1_serial_in_local(SERIAL_POLLED_MODE)); -} - -int -l1_serial_in(void) -{ - static int l1_serial_in_local(int mode); - - return(l1_serial_in_local(SERIAL_INTERRUPT_MODE)); -} - -static int -l1_serial_in_local(int mode) -{ -#if defined(USE_SAL_CONSOLE_IO) - int sal_call_status; - int ch; - - sal_call_status = ia64_sn_console_getc(&ch); - if ( !sal_call_status ) { - return(ch); - } - else { - /* If the sal called failed - do it the old-fashioned way */ - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3))); - } - else { -#endif /* USE_SAL_CONSOLE_IO */ - nasid_t nasid; - l1sc_t *sc; - int value; - static int l1_getc( l1sc_t *, int ); - static inline l1sc_t *early_sc_init(nasid_t); - - nasid = get_master_nasid(); - sc = early_sc_init(nasid); - if ( L1_cons_is_inited ) { - if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) { - sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc; - } - } - value = l1_getc(sc, mode); - return(value); -#if defined(USE_SAL_CONSOLE_IO) - } - } -#endif -} - -/* Console output exported interface. Write message to the console. */ - -int -l1_serial_out( char *str, int len ) -{ -#if defined(USE_SAL_CONSOLE_IO) - int sal_call_status = 0; - int counter = len; - - /* Attempt to write things out thru the sal */ - while ( counter > 0 ) { - if ( (sal_call_status = ia64_sn_console_putc(*str)) ) { - break; - } - counter--; - str++; - } - if ( sal_call_status ) { - /* If the sal called failed - do it the old-fashioned way */ - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - if (!master_node_bedrock_address) - early_sn_setup(); - if ( master_node_bedrock_address != (u64)0 ) { -#ifdef FLAG_DIRECT_CONSOLE_WRITES - /* This is an easy way to pre-pend the output to know whether the output - * was done via sal or directly */ - writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); -#endif /* FLAG_DIRECT_CONSOLE_WRITES */ - while ( counter > 0 ) { - writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - counter--; - str++; - } - } - } - else { -#endif /* USE_SAL_CONSOLE_IO */ - nasid_t nasid = get_master_nasid(); - int l1_write(l1sc_t *, char *, int, int); - - if ( L1_cons_is_inited ) { - if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) - return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len, -#if defined(SYNC_CONSOLE_WRITE) - 1 -#else - !L1_interrupts_connected -#endif - )); - } - return(early_l1_serial_out(nasid, str, len, NOT_LOCKED)); -#if defined(USE_SAL_CONSOLE_IO) - } - } - return((counter <= 0) ? 0 : (len - counter)); -#endif -} - - -/* - * These are the 'early' functions - when we need to do things before we have - * all the structs setup. - */ - - -static l1sc_t Early_console; /* fake l1sc_t */ -static int Early_console_inited = 0; - -static void -early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) -{ - int i; - brl1_sch_t *subch; - - bzero( sc, sizeof( *sc ) ); - sc->nasid = nasid; - sc->uart = uart; - sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc); - sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc); - sc->sol = 1; - subch = sc->subch; - - /* initialize L1 subchannels - */ - - /* assign processor TTY channels */ - for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) { - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - subch->iqp = &sc->garbage_q; - } - - /* assign system TTY channel (first free subchannel after each - * processor's individual TTY channel has been assigned) - */ - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - if( sc->uart == BRL1_LOCALHUB_UART ) { - static sc_cq_t x_iqp; - - subch->iqp = &x_iqp; - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - } - else { - /* we shouldn't be getting console input from remote UARTs */ - subch->iqp = &sc->garbage_q; - } - subch++; i++; - - /* "reserved" subchannels (0x05-0x0F); for now, throw away - * incoming packets - */ - for( ; i < 0x10; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - subch->iqp = &sc->garbage_q; - } - - /* remaining subchannels are free */ - for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - subch->iqp = &sc->garbage_q; - } -} - -static inline l1sc_t * -early_sc_init(nasid_t nasid) -{ - /* This is for early I/O */ - if ( Early_console_inited == 0 ) { - early_brl1_init(&Early_console, nasid, BRL1_LOCALHUB_UART); - Early_console_inited = 1; - } - return(&Early_console); -} - -#define PUTCHAR(ch) \ - { \ - while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \ - (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \ - WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \ - } - -static int -early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state ) -{ - int ret, sent = 0; - char *msg = str; - static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state ); - - while ( sent < len ) { - ret = early_l1_send(nasid, msg, len - sent, lock_state); - sent += ret; - msg += ret; - } - return(len); -} - -static inline int -early_l1_send( nasid_t nasid, char *str, int len, int lock_state ) -{ - int sent; - char crc_char; - unsigned short crc = INIT_CRC; - - if( len > (BRL1_QSIZE - 1) ) - len = (BRL1_QSIZE - 1); - - sent = len; - if ( lock_state == NOT_LOCKED ) - lock_console(nasid); - - PUTCHAR( BRL1_FLAG_CH ); - PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM ); - crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) ); - - while( len ) { - - if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) { - PUTCHAR( BRL1_ESC_CH ); - PUTCHAR( (*str) ^ BRL1_XOR_CH ); - } - else { - PUTCHAR( *str ); - } - - crc = crc16_calc( crc, *str ); - - str++; len--; - } - - crc ^= 0xffff; - crc_char = crc & 0xff; - if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { - crc_char ^= BRL1_XOR_CH; - PUTCHAR( BRL1_ESC_CH ); - } - PUTCHAR( crc_char ); - crc_char = (crc >> 8) & 0xff; - if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { - crc_char ^= BRL1_XOR_CH; - PUTCHAR( BRL1_ESC_CH ); - } - PUTCHAR( crc_char ); - PUTCHAR( BRL1_FLAG_CH ); - - if ( lock_state == NOT_LOCKED ) - unlock_console(nasid); - return sent; -} - -/********************************************************************* - * l1_cons functions - * - * These allow the L1 to act as the system console. They're intended - * to abstract away most of the br/l1 internal details from the - * _L1_cons_* functions (in the prom-- see "l1_console.c") and - * l1_* functions (in the kernel-- see "sio_l1.c") that they support. - * - */ - -static int -l1_poll( l1sc_t *sc, int mode ) -{ - int ret; - - /* in case this gets called before the l1sc_t structure for the module_t - * struct for this node is initialized (i.e., if we're called with a - * zero l1sc_t pointer)... - */ - - - if( !sc ) { - return 0; - } - - if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) { - return 1; - } - - ret = brl1_receive( sc, mode ); - if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) ) - L1_collectibles[L1C_REC_STALLS] = ret; - - if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) { - return 1; - } - return 0; -} - - -/* pull a character off of the system console queue (if one is available) - */ -static int -l1_getc( l1sc_t *sc, int mode ) -{ - unsigned long pl = 0; - int c; - - brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]); - sc_cq_t *q = subch->iqp; - - if( !l1_poll( sc, mode ) ) { - return 0; - } - - SUBCH_DATA_LOCK( subch, pl ); - if( cq_empty( q ) ) { - atomic_set(&subch->packet_arrived, 0); - SUBCH_DATA_UNLOCK( subch, pl ); - return 0; - } - cq_rem( q, c ); - if( cq_empty( q ) ) - atomic_set(&subch->packet_arrived, 0); - SUBCH_DATA_UNLOCK( subch, pl ); - - return c; -} - -/* - * Write a message to the L1 on the system console subchannel. - * - * Danger: don't use a non-zero value for the wait parameter unless you're - * someone important (like a kernel error message). - */ - -int -l1_write( l1sc_t *sc, char *msg, int len, int wait ) -{ - int sent = 0, ret = 0; - - if ( wait ) { - while ( sent < len ) { - ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait ); - sent += ret; - msg += ret; - } - ret = len; - } - else { - ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait ); - } - return(ret); -} - -/* initialize the system console subchannel - */ -void -l1_init(void) -{ - /* All we do now is remember that we have been called */ - L1_cons_is_inited = 1; -} - - -/********************************************************************* - * The following functions and definitions implement the "message"- - * style interface to the L1 system controller. - * - * Note that throughout this file, "sc" generally stands for "system - * controller", while "subchannels" tend to be represented by - * variables with names like subch or ch. - * - */ - -#ifdef L1_DEBUG -#define L1_DBG_PRF(x) printf x -#else -#define L1_DBG_PRF(x) -#endif - -/* - * sc_data_ready is called to signal threads that are blocked on l1 input. - */ -void -sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch ) -{ - unsigned long pl = 0; - - brl1_sch_t *subch = &(sc->subch[ch]); - SUBCH_DATA_LOCK( subch, pl ); - sv_signal( &(subch->arrive_sv) ); - SUBCH_DATA_UNLOCK( subch, pl ); -} - -/* sc_open reserves a subchannel to send a request to the L1 (the - * L1's response will arrive on the same channel). The number - * returned by sc_open is the system controller subchannel - * acquired. - */ -int -sc_open( l1sc_t *sc, uint target ) -{ - /* The kernel version implements a locking scheme to arbitrate - * subchannel assignment. - */ - int ch; - unsigned long pl = 0; - brl1_sch_t *subch; - - SUBCH_LOCK( sc, pl ); - - /* Look for a free subchannel. Subchannels 0-15 are reserved - * for other purposes. - */ - for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; - ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) { - if( subch->use == BRL1_SUBCH_FREE ) - break; - } - - if( ch == BRL1_NUM_SUBCHANS ) { - /* there were no subchannels available! */ - SUBCH_UNLOCK( sc, pl ); - return SC_NSUBCH; - } - - subch->use = BRL1_SUBCH_RSVD; - SUBCH_UNLOCK( sc, pl ); - - atomic_set(&subch->packet_arrived, 0); - subch->target = target; - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */); - subch->tx_notify = NULL; - subch->rx_notify = sc_data_ready; - subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, - NASID_TO_COMPACT_NODEID(sc->nasid) ); - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - - return ch; -} - - -/* sc_close frees a Bedrock<->L1 subchannel. - */ -int -sc_close( l1sc_t *sc, int ch ) -{ - unsigned long pl = 0; - brl1_sch_t *subch; - - SUBCH_LOCK( sc, pl ); - subch = &(sc->subch[ch]); - if( subch->use != BRL1_SUBCH_RSVD ) { - /* we're trying to close a subchannel that's not open */ - SUBCH_UNLOCK( sc, pl ); - return SC_NOPEN; - } - - atomic_set(&subch->packet_arrived, 0); - subch->use = BRL1_SUBCH_FREE; - - sv_broadcast( &(subch->arrive_sv) ); - sv_destroy( &(subch->arrive_sv) ); - spin_lock_destroy( &(subch->data_lock) ); - - ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) ); - snia_kmem_free( subch->iqp, sizeof(sc_cq_t) ); - subch->iqp = &sc->garbage_q; - subch->tx_notify = NULL; - subch->rx_notify = brl1_discard_packet; - - SUBCH_UNLOCK( sc, pl ); - - return SC_SUCCESS; -} - - -/* sc_construct_msg builds a bedrock-to-L1 request in the supplied - * buffer. Returns the length of the message. The - * safest course when passing a buffer to be filled in is to use - * BRL1_QSIZE as the buffer size. - * - * Command arguments are passed as type/argument pairs, i.e., to - * pass the number 5 as an argument to an L1 command, call - * sc_construct_msg as follows: - * - * char msg[BRL1_QSIZE]; - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 2, - * L1_ARG_INT, 5 ); - * - * To pass an additional ASCII argument, you'd do the following: - * - * char *str; - * ... str points to a null-terminated ascii string ... - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 4, - * L1_ARG_INT, 5, - * L1_ARG_ASCII, str ); - * - * Finally, arbitrary data of unknown type is passed using the argtype - * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g. - * - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 3, - * L1_ARG_UNKNOWN, 32, bufptr ); - * - * ...passes 32 bytes of data starting at bufptr. Note that no string or - * "unknown"-type argument should be long enough to overflow the message - * buffer. - * - * To construct a message for an L1 command that requires no arguments, - * you'd use the following: - * - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 0 ); - * - * The final 0 means "no varargs". Notice that this parameter is used to hold - * the number of additional arguments to sc_construct_msg, _not_ the actual - * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII] - * type argument, and 3 per L1_ARG_UNKOWN type argument). A call to construct - * an L1 command which required three integer arguments and two arguments of - * some arbitrary (unknown) type would pass 12 as the value for this parameter. - * - * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth - * between byte arrays and four-byte big-endian integers. Depending on the - * system controller connection and endianness of future architectures, some - * rewriting might be necessary. - */ -int -sc_construct_msg( l1sc_t *sc, /* system controller struct */ - int ch, /* subchannel for this message */ - char *msg, /* message buffer */ - int msg_len, /* size of message buffer */ - l1addr_t addr_task, /* target system controller task */ - short req_code, /* 16-bit request code */ - int req_nargs, /* # of arguments (varargs) passed */ - ... ) /* any additional parameters */ -{ - uint32_t buf32; /* 32-bit buffer used to bounce things around */ - void *bufptr; /* used to hold command argument addresses */ - va_list al; /* variable argument list */ - int index; /* current index into msg buffer */ - int argno; /* current position in varargs list */ - int l1_argno; /* running total of arguments to l1 */ - int l1_arg_t; /* argument type/length */ - int l1_argno_byte; /* offset of argument count byte */ - - index = argno = 0; - - /* set up destination address */ - if( (msg_len -= sizeof( buf32 )) < 0 ) - return -1; - L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task ); - COPY_INT_TO_BUFFER(msg, index, buf32); - - /* copy request code */ - if( (msg_len -= 2) < 0 ) - return( -1 ); - msg[index++] = ((req_code >> 8) & 0xff); - msg[index++] = (req_code & 0xff); - - if( !req_nargs ) { - return index; - } - - /* reserve a byte for the argument count */ - if( (msg_len -= 1) < 0 ) - return( -1 ); - l1_argno_byte = index++; - l1_argno = 0; - - /* copy additional arguments */ - va_start( al, req_nargs ); - while( argno < req_nargs ) { - l1_argno++; - l1_arg_t = va_arg( al, int ); argno++; - switch( l1_arg_t ) - { - case L1_ARG_INT: - if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 ) - return( -1 ); - msg[index++] = L1_ARG_INT; - buf32 = (unsigned)va_arg( al, int ); argno++; - COPY_INT_TO_BUFFER(msg, index, buf32); - break; - - case L1_ARG_ASCII: - bufptr = va_arg( al, char* ); argno++; - if( (msg_len -= (strlen( bufptr ) + 2)) < 0 ) - return( -1 ); - msg[index++] = L1_ARG_ASCII; - strcpy( (char *)&(msg[index]), (char *)bufptr ); - index += (strlen( bufptr ) + 1); /* include terminating null */ - break; - - case L1_ARG_UNKNOWN: - { - int arglen; - - arglen = va_arg( al, int ); argno++; - bufptr = va_arg( al, void* ); argno++; - if( (msg_len -= (arglen + 1)) < 0 ) - return( -1 ); - msg[index++] = L1_ARG_UNKNOWN | arglen; - BCOPY( bufptr, &(msg[index]), arglen ); - index += arglen; - break; - } - - default: /* unhandled argument type */ - return -1; - } - } - - va_end( al ); - msg[l1_argno_byte] = l1_argno; - - return index; -} - - - -/* sc_interpret_resp verifies an L1 response to a bedrock request, and - * breaks the response data up into the constituent parts. If the - * response message indicates error, or if a mismatch is found in the - * expected number and type of arguments, an error is returned. The - * arguments to this function work very much like the arguments to - * sc_construct_msg, above, except that L1_ARG_INTs must be followed - * by a _pointer_ to an integer that can be filled in by this function. - */ -int -sc_interpret_resp( char *resp, /* buffer received from L1 */ - int resp_nargs, /* number of _varargs_ passed in */ - ... ) -{ - uint32_t buf32; /* 32-bit buffer used to bounce things around */ - void *bufptr; /* used to hold response field addresses */ - va_list al; /* variable argument list */ - int index; /* current index into response buffer */ - int argno; /* current position in varargs list */ - int l1_fldno; /* number of resp fields received from l1 */ - int l1_fld_t; /* field type/length */ - - index = argno = 0; - -#if defined(L1_DEBUG) -#define DUMP_RESP \ - { \ - int ix; \ - char outbuf[512]; \ - sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \ - for( ix = 0; ix < 16; ix++ ) { \ - sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] ); \ - } \ - printk( "%s\n", outbuf ); \ - } -#else -#define DUMP_RESP -#endif /* L1_DEBUG */ - - /* check response code */ - COPY_BUFFER_TO_INT(resp, index, buf32); - if( buf32 != L1_RESP_OK ) { - DUMP_RESP; - return buf32; - } - - /* get number of response fields */ - l1_fldno = resp[index++]; - - va_start( al, resp_nargs ); - - /* copy out response fields */ - while( argno < resp_nargs ) { - l1_fldno--; - l1_fld_t = va_arg( al, int ); argno++; - switch( l1_fld_t ) - { - case L1_ARG_INT: - if( resp[index++] != L1_ARG_INT ) { - /* type mismatch */ - va_end( al ); - DUMP_RESP; - return -1; - } - bufptr = va_arg( al, int* ); argno++; - COPY_BUFFER_TO_BUFFER(resp, index, bufptr); - break; - - case L1_ARG_ASCII: - if( resp[index++] != L1_ARG_ASCII ) { - /* type mismatch */ - va_end( al ); - DUMP_RESP; - return -1; - } - bufptr = va_arg( al, char* ); argno++; - strcpy( (char *)bufptr, (char *)&(resp[index]) ); - /* include terminating null */ - index += (strlen( &(resp[index]) ) + 1); - break; - - default: - if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN ) - { - int *arglen; - - arglen = va_arg( al, int* ); argno++; - bufptr = va_arg( al, void* ); argno++; - *arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff); - BCOPY( &(resp[index]), bufptr, *arglen ); - index += (*arglen); - } - - else { - /* unhandled type */ - va_end( al ); - DUMP_RESP; - return -1; - } - } - } - va_end( al ); - - if( (l1_fldno != 0) || (argno != resp_nargs) ) { - /* wrong number of arguments */ - DUMP_RESP; - return -1; - } - return 0; -} - -/* sc_send takes as arguments a system controller struct, a - * buffer which contains a Bedrock<->L1 "request" message, - * the message length, and the subchannel (presumably obtained - * from an earlier invocation of sc_open) over which the - * message is to be sent. The final argument ("wait") indicates - * whether the send is to be performed synchronously or not. - * - * sc_send returns either zero or an error value. Synchronous sends - * (wait != 0) will not return until the data has actually been sent - * to the UART. Synchronous sends generally receive privileged - * treatment. The intent is that they be used sparingly, for such - * purposes as kernel printf's (the "ducons" routines). Run-of-the-mill - * console output and L1 requests should NOT use a non-zero value - * for wait. - */ -int -sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait ) -{ - char type_and_subch; - int result; - - if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) { - return SC_BADSUBCH; - } - - /* Verify that this is an open subchannel - */ - if( sc->subch[ch].use == BRL1_SUBCH_FREE ) { - return SC_NOPEN; - } - - type_and_subch = (BRL1_REQUEST | ((u_char)ch)); - result = brl1_send( sc, msg, len, type_and_subch, wait ); - - /* If we sent as much as we asked to, return "ok". */ - if( result == len ) - return( SC_SUCCESS ); - - /* Or, if we sent less, than either the UART is busy or - * we're trying to send too large a packet anyway. - */ - else if( result >= 0 && result < len ) - return( SC_BUSY ); - - /* Or, if something else went wrong (result < 0), then - * return that error value. - */ - else - return( result ); -} - -/* subch_pull_msg pulls a message off the receive queue for subch - * and places it the buffer pointed to by msg. This routine should only - * be called when the caller already knows a message is available on the - * receive queue (and, in the kernel, only when the subchannel data lock - * is held by the caller). - */ -static void -subch_pull_msg( brl1_sch_t *subch, char *msg, int *len ) -{ - sc_cq_t *q; /* receive queue */ - int before_wrap, /* packet may be split into two different */ - after_wrap; /* pieces to acommodate queue wraparound */ - - /* pull message off the receive queue */ - q = subch->iqp; - - cq_rem( q, *len ); /* remove length byte and store */ - cq_discard( q ); /* remove type/subch byte and discard */ - - if ( *len > 0 ) - (*len)--; /* don't count type/subch byte in length returned */ - - if( (q->opos + (*len)) > BRL1_QSIZE ) { - before_wrap = BRL1_QSIZE - q->opos; - after_wrap = (*len) - before_wrap; - } - else { - before_wrap = (*len); - after_wrap = 0; - } - - BCOPY( q->buf + q->opos, msg, before_wrap ); - if( after_wrap ) { - BCOPY( q->buf, msg + before_wrap, after_wrap ); - q->opos = after_wrap; - } - else { - q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1)); - } - atomic_dec(&(subch->packet_arrived)); -} - - -/* sc_recv_poll can be called as a blocking or non-blocking function; - * it attempts to pull a message off of the subchannel specified - * in the argument list (ch). - * - * The "block" argument, if non-zero, is interpreted as a timeout - * delay (to avoid permanent waiting). - */ - -int -sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block ) -{ - int is_msg = 0; - unsigned long pl = 0; - brl1_sch_t *subch = &(sc->subch[ch]); - - rtc_time_t exp_time = rtc_time() + block; - - /* sanity check-- make sure this is an open subchannel */ - if( subch->use == BRL1_SUBCH_FREE ) - return( SC_NOPEN ); - - do { - - /* kick the next lower layer and see if it pulls anything in - */ - brl1_receive( sc, SERIAL_POLLED_MODE ); - is_msg = atomic_read(&subch->packet_arrived); - - } while( block && !is_msg && (rtc_time() < exp_time) ); - - if( !is_msg ) { - /* no message and we didn't care to wait for one */ - return( SC_NMSG ); - } - - SUBCH_DATA_LOCK( subch, pl ); - subch_pull_msg( subch, msg, len ); - SUBCH_DATA_UNLOCK( subch, pl ); - - return( SC_SUCCESS ); -} - - -/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking - * or non-blocking mode. Rather than polling until an appointed timeout, - * however, sc_recv_intr sleeps on a syncrhonization variable until a - * signal from the lower layer tells us that a packet has arrived. - * - * sc_recv_intr can't be used with remote (router) L1s. - */ -int -sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block ) -{ - int is_msg = 0; - unsigned long pl = 0; - brl1_sch_t *subch = &(sc->subch[ch]); - - do { - SUBCH_DATA_LOCK(subch, pl); - is_msg = atomic_read(&subch->packet_arrived); - if( !is_msg && block ) { - /* wake me when you've got something */ - subch->rx_notify = sc_data_ready; - sv_wait( &(subch->arrive_sv), 0, 0); - if( subch->use == BRL1_SUBCH_FREE ) { - /* oops-- somebody closed our subchannel while we were - * sleeping! - */ - - /* no need to unlock since the channel's closed anyhow */ - return( SC_NOPEN ); - } - } - } while( !is_msg && block ); - - if( !is_msg ) { - /* no message and we didn't care to wait for one */ - SUBCH_DATA_UNLOCK( subch, pl ); - return( SC_NMSG ); - } - - subch_pull_msg( subch, msg, len ); - SUBCH_DATA_UNLOCK( subch, pl ); - - return( SC_SUCCESS ); -} - -/* sc_command implements a (blocking) combination of sc_send and sc_recv. - * It is intended to be the SN1 equivalent of SN0's "elsc_command", which - * issued a system controller command and then waited for a response from - * the system controller before returning. - * - * cmd points to the outgoing command; resp points to the buffer in - * which the response is to be stored. Both buffers are assumed to - * be the same length; if there is any doubt as to whether the - * response buffer is long enough to hold the L1's response, then - * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any - * bigger. - * - * Be careful using the same buffer for both cmd and resp; it could get - * hairy if there were ever an L1 command reqeuest that spanned multiple - * packets. (On the other hand, that would require some additional - * rewriting of the L1 command interface anyway.) - */ -#define __RETRIES 50 -#define __WAIT_SEND 1 // ( sc->uart != BRL1_LOCALHUB_UART ) -#define __WAIT_RECV 10000000 - - -int -sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ) -{ - int result; - int retries; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return SC_NMSG; - - retries = __RETRIES; - - while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) { - if( result == SC_BUSY ) { - retries--; - if( retries <= 0 ) - return result; - uart_delay(500); - } - else { - return result; - } - } - - /* block on sc_recv_* */ - if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) { - return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) ); - } - else { - return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) ); - } -} - -/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command - * used in situations where the kernel has a command that shouldn't be - * delayed until the send buffer clears. sc_command should be used instead - * under most circumstances. - */ - -int -sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ) -{ - int result; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return SC_NMSG; - - if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) { - return result; - } - - return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) ); -} - - - -/* sc_poll checks the queue corresponding to the given - * subchannel to see if there's anything available. If - * not, it kicks the brl1 layer and then checks again. - * - * Returns 1 if input is available on the given queue, - * 0 otherwise. - */ - -int -sc_poll( l1sc_t *sc, int ch ) -{ - brl1_sch_t *subch = &(sc->subch[ch]); - - if( atomic_read(&subch->packet_arrived) ) - return 1; - - brl1_receive( sc, SERIAL_POLLED_MODE ); - - if( atomic_read(&subch->packet_arrived) ) - return 1; - - return 0; -} - -/* for now, sc_init just calls brl1_init */ - -void -sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) -{ - if ( !IS_RUNNING_ON_SIMULATOR() ) - brl1_init( sc, nasid, uart ); -} - -/* sc_dispatch_env_event handles events sent from the system control - * network's environmental monitor tasks. - */ - -#if defined(LINUX_KERNEL_THREADS) - -static void -sc_dispatch_env_event( uint code, int argc, char *args, int maxlen ) -{ - int j, i = 0; - uint32_t ESPcode; - - switch( code ) { - /* for now, all codes do the same thing: grab two arguments - * and print a cmn_err_tag message */ - default: - /* check number of arguments */ - if( argc != 2 ) { - L1_DBG_PRF(( "sc_dispatch_env_event: " - "expected 2 arguments, got %d\n", argc )); - return; - } - - /* get ESP code (integer argument) */ - if( args[i++] != L1_ARG_INT ) { - L1_DBG_PRF(( "sc_dispatch_env_event: " - "expected integer argument\n" )); - return; - } - /* WARNING: highly endian */ - COPY_BUFFER_TO_INT(args, i, ESPcode); - - /* verify string argument */ - if( args[i++] != L1_ARG_ASCII ) { - L1_DBG_PRF(( "sc_dispatch_env_event: " - "expected an ASCII string\n" )); - return; - } - for( j = i; j < maxlen; j++ ) { - if( args[j] == '\0' ) break; /* found string termination */ - } - if( j == maxlen ) { - j--; - L1_DBG_PRF(( "sc_dispatch_env_event: " - "message too long-- truncating\n" )); - } - - /* strip out trailing cr/lf */ - for( ; - j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); - j-- ); - args[j] = '\0'; - - /* strip out leading cr/lf */ - for( ; - i < j && ((args[i] == 0xd) || (args[i] == 0xa)); - i++ ); - } -} - - -/* sc_event waits for events to arrive from the system controller, and - * prints appropriate messages to the syslog. - */ - -static void -sc_event( l1sc_t *sc, int ch ) -{ - char event[BRL1_QSIZE]; - int i; - int result; - int event_len; - uint32_t ev_src; - uint32_t ev_code; - int ev_argc; - - while(1) { - - bzero( event, BRL1_QSIZE ); - - /* - * wait for an event - */ - result = sc_recv_intr( sc, ch, event, &event_len, 1 ); - if( result != SC_SUCCESS ) { - printk(KERN_WARNING "Error receiving sysctl event on nasid %d\n", - sc->nasid ); - } - else { - /* - * an event arrived; break it down into useful pieces - */ -#if defined(L1_DEBUG) && 0 - int ix; - printf( "Event packet received:\n" ); - for (ix = 0; ix < 64; ix++) { - printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)), - (event[ix] & ((uint64_t)0xf)) ); - if( (ix % 16) == 0xf ) printf( "\n" ); - } -#endif /* L1_DEBUG */ - - i = 0; - - /* get event source */ - COPY_BUFFER_TO_INT(event, i, ev_src); - COPY_BUFFER_TO_INT(event, i, ev_code); - - /* get arg count */ - ev_argc = (event[i++] & 0xffUL); - - /* dispatch events by task */ - switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT ) - { - case L1_ADDR_TASK_ENV: /* environmental monitor event */ - sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), - BRL1_QSIZE - i ); - break; - - default: /* unhandled task type */ - L1_DBG_PRF(( "Unhandled event type received from system " - "controllers: source task %x\n", - (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT - )); - } - } - - } -} - -/* sc_listen sets up a service thread to listen for incoming events. - */ - -void -sc_listen( l1sc_t *sc ) -{ - int result; - unsigned long pl = 0; - brl1_sch_t *subch; - - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int ch; /* system controller subchannel used */ - - extern int msc_shutdown_pri; - - /* grab the designated "event subchannel" */ - SUBCH_LOCK( sc, pl ); - subch = &(sc->subch[BRL1_EVENT_SUBCH]); - if( subch->use != BRL1_SUBCH_FREE ) { - SUBCH_UNLOCK( sc, pl ); - printk(KERN_WARNING "sysctl event subchannel in use! " - "Not monitoring sysctl events.\n" ); - return; - } - subch->use = BRL1_SUBCH_RSVD; - SUBCH_UNLOCK( sc, pl ); - - atomic_set(&subch->packet_arrived, 0); - subch->target = BRL1_LOCALHUB_UART; - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */); - subch->tx_notify = NULL; - subch->rx_notify = sc_data_ready; - subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, - NASID_TO_COMPACT_NODEID(sc->nasid) ); - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - - /* set up a thread to listen for events */ - sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri, - KT_PS, (st_func_t *) sc_event, - (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 ); - - /* signal the L1 to begin sending events */ - bzero( msg, BRL1_QSIZE ); - ch = sc_open( sc, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_EVENT_SUBCH, 2, - L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 ) - { - sc_close( sc, ch ); - L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len )); - goto err_return; - } - - result = sc_command_kern( sc, ch, msg, msg, &len ); - if( result < 0 ) - { - sc_close( sc, ch ); - L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result )); - goto err_return; - } - - sc_close( sc, ch ); - - result = sc_interpret_resp( msg, 0 ); - if( result < 0 ) - { - L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result )); - goto err_return; - } - - /* everything went fine; just return */ - return; - -err_return: - /* there was a problem; complain */ - printk(KERN_WARNING "failed to set sysctl event-monitoring subchannel. " - "Sysctl events will not be monitored.\n" ); -} - -#endif /* LINUX_KERNEL_THREADS */ diff -urN linux-2.4.21/arch/ia64/sn/io/l1_command.c linux-2.4.22/arch/ia64/sn/io/l1_command.c --- linux-2.4.21/arch/ia64/sn/io/l1_command.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/l1_command.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1378 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000 - 2001 Silicon Graphics, Inc. - * All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ELSC_TIMEOUT 1000000 /* ELSC response timeout (usec) */ -#define LOCK_TIMEOUT 5000000 /* Hub lock timeout (usec) */ - -#define LD(x) (*(volatile uint64_t *)(x)) -#define SD(x, v) (LD(x) = (uint64_t) (v)) - -#define hub_cpu_get() 0 - -#define LBYTE(caddr) (*(char *) caddr) - -extern char *bcopy(const char * src, char * dest, int count); - -#define LDEBUG 0 - -/* - * ELSC data is in NVRAM page 7 at the following offsets. - */ - -#define NVRAM_MAGIC_AD 0x700 /* magic number used for init */ -#define NVRAM_PASS_WD 0x701 /* password (4 bytes in length) */ -#define NVRAM_DBG1 0x705 /* virtual XOR debug switches */ -#define NVRAM_DBG2 0x706 /* physical XOR debug switches */ -#define NVRAM_CFG 0x707 /* ELSC Configuration info */ -#define NVRAM_MODULE 0x708 /* system module number */ -#define NVRAM_BIST_FLG 0x709 /* BIST flags (2 bits per nodeboard) */ -#define NVRAM_PARTITION 0x70a /* module's partition id */ -#define NVRAM_DOMAIN 0x70b /* module's domain id */ -#define NVRAM_CLUSTER 0x70c /* module's cluster id */ -#define NVRAM_CELL 0x70d /* module's cellid */ - -#define NVRAM_MAGIC_NO 0x37 /* value of magic number */ -#define NVRAM_SIZE 16 /* 16 bytes in nvram */ - -/* - * Declare a static ELSC NVRAM buffer to hold all data read from - * and written to NVRAM. This nvram "cache" will be used only during the - * IP27prom execution. - */ -static char elsc_nvram_buffer[NVRAM_SIZE]; - -#define SC_COMMAND sc_command - -/* - * elsc_init - * - * Initialize ELSC structure - */ - -void elsc_init(elsc_t *e, nasid_t nasid) -{ - sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART); -} - - -/* - * elsc_errmsg - * - * Given a negative error code, - * returns a corresponding static error string. - */ - -char *elsc_errmsg(int code) -{ - switch (code) { - case ELSC_ERROR_CMD_SEND: - return "Command send error"; - case ELSC_ERROR_CMD_CHECKSUM: - return "Command packet checksum error"; - case ELSC_ERROR_CMD_UNKNOWN: - return "Unknown command"; - case ELSC_ERROR_CMD_ARGS: - return "Invalid command argument(s)"; - case ELSC_ERROR_CMD_PERM: - return "Permission denied"; - case ELSC_ERROR_RESP_TIMEOUT: - return "System controller response timeout"; - case ELSC_ERROR_RESP_CHECKSUM: - return "Response packet checksum error"; - case ELSC_ERROR_RESP_FORMAT: - return "Response format error"; - case ELSC_ERROR_RESP_DIR: - return "Response direction error"; - case ELSC_ERROR_MSG_LOST: - return "Message lost because queue is full"; - case ELSC_ERROR_LOCK_TIMEOUT: - return "Timed out getting ELSC lock"; - case ELSC_ERROR_DATA_SEND: - return "Error sending data"; - case ELSC_ERROR_NIC: - return "NIC protocol error"; - case ELSC_ERROR_NVMAGIC: - return "Bad magic number in NVRAM"; - case ELSC_ERROR_MODULE: - return "Module location protocol error"; - default: - return "Unknown error"; - } -} - -/* - * elsc_nvram_init - * - * Initializes reads and writes to NVRAM. This will perform a single - * read to NVRAM, getting all data at once. When the PROM tries to - * read NVRAM, it returns the data from the buffer being read. If the - * PROM tries to write out to NVRAM, the write is done, and the internal - * buffer is updated. - */ - -void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data) -{ - /* This might require implementation of multiple-packet request/responses - * if it's to provide the same behavior that was available in SN0. - */ - nasid = nasid; - elsc_nvram_data = elsc_nvram_data; -} - -/* - * elsc_nvram_copy - * - * Copies the content of a buffer into the static buffer in this library. - */ - -void elsc_nvram_copy(uchar_t *elsc_nvram_data) -{ - memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE); -} - -/* - * elsc_nvram_write - * - * Copies bytes from 'buf' into NVRAM, starting at NVRAM address - * 'addr' which must be between 0 and 2047. - * - * If 'len' is non-negative, the routine copies 'len' bytes. - * - * If 'len' is negative, the routine treats the data as a string and - * copies bytes up to and including a NUL-terminating zero, but not - * to exceed '-len' bytes. - */ - -int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len) -{ - /* Here again, we might need to work out the details of a - * multiple-packet protocol. - */ - - /* For now, pretend it worked. */ - e = e; - addr = addr; - buf = buf; - return (len < 0 ? -len : len); -} - -/* - * elsc_nvram_read - * - * Copies bytes from NVRAM into 'buf', starting at NVRAM address - * 'addr' which must be between 0 and 2047. - * - * If 'len' is non-negative, the routine copies 'len' bytes. - * - * If 'len' is negative, the routine treats the data as a string and - * copies bytes up to and including a NUL-terminating zero, but not - * to exceed '-len' bytes. NOTE: This method is no longer supported. - * It was never used in the first place. - */ - -int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len) -{ - /* multiple packets? */ - e = e; - addr = addr; - buf = buf; - len = len; - return -1; -} - - -/* - * Command Set - */ - -int elsc_version(elsc_t *e, char *result) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - int major, /* major rev number */ - minor, /* minor rev number */ - bugfix; /* bugfix rev number */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_FW_REV, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( (l1sc_t *)e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major, - L1_ARG_INT, &minor, L1_ARG_INT, &bugfix ) - < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - sprintf( result, "%d.%d.%d", major, minor, bugfix ); - - return 0; -} - -int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2) -{ - /* shush compiler */ - e = e; - byte1 = byte1; - byte2 = byte2; - - /* fill in a buffer with the opcode & params; call sc_command */ - - return 0; -} - -int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2) -{ - char msg[BRL1_QSIZE]; - int subch; /* system controller subchannel used */ - int dbg_sw; /* holds debug switch settings */ - int len; /* number of msg buffer bytes used */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RDBG, 0 ) ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( (l1sc_t *)e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* copy out debug switch settings (last two bytes of the - * integer response) - */ - *byte1 = ((dbg_sw >> 8) & 0xFF); - *byte2 = (dbg_sw & 0xFF); - - return 0; -} - - -/* - * elsc_rack_bay_get fills in the two int * arguments with the - * rack number and bay number of the L1 being addressed - */ -int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t buf32; /* used to copy 32-bit rack/bay out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RRACK, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - - /* send the request to the L1 */ - if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close(e, subch); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* extract rack/bay info - * - * note that the 32-bit value returned by the L1 actually - * only uses the low-order sixteen bits for rack and bay - * information. A "normal" L1 address puts rack and bay - * information in bit positions 12 through 28. So if - * we initially shift the value returned 12 bits to the left, - * we can use the L1 addressing #define's to extract the - * values we need (see ksys/l1.h for a complete list of the - * various fields of an L1 address). - */ - buf32 <<= L1_ADDR_BAY_SHFT; - - *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - - return 0; -} - - -/* elsc_rack_bay_type_get fills in the three int * arguments with the - * rack number, bay number and brick type of the L1 being addressed. Note - * that if the L1 operation fails and this function returns an error value, - * garbage may be written to brick_type. - */ -int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, - uint *bay, uint *brick_type ) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t buf32; /* used to copy 32-bit rack & bay out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RRBT, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( sc, subch, msg, msg, &len ) ) { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, - L1_ARG_INT, brick_type ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* extract rack/bay info - * - * note that the 32-bit value returned by the L1 actually - * only uses the low-order sixteen bits for rack and bay - * information. A "normal" L1 address puts rack and bay - * information in bit positions 12 through 28. So if - * we initially shift the value returned 12 bits to the left, - * we can use the L1 addressing #define's to extract the - * values we need (see ksys/l1.h for a complete list of the - * various fields of an L1 address). - */ - buf32 <<= L1_ADDR_BAY_SHFT; - - *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - - /* convert brick_type to lower case */ - *brick_type = *brick_type - 'A' + 'a'; - - return 0; -} - - -int elsc_module_get(elsc_t *e) -{ - extern char brick_types[]; - uint rnum, rack, bay, bricktype, t; - int ret; - - /* construct module ID from rack and slot info */ - - if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) { - return ret; - } - - /* report unset location info. with a special, otherwise invalid modid */ - if (rnum == 0 && bay == 0) - return MODULE_NOT_SET; - - if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) - return ELSC_ERROR_MODULE; - - /* Build a moduleid_t-compatible rack number */ - - rack = 0; - t = rnum / 100; /* rack class (CPU/IO) */ - if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_CLASS(rack, t); - rnum %= 100; - - t = rnum / 10; /* rack group */ - if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_GROUP(rack, t); - - t = rnum % 10; /* rack number (one-based) */ - if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_NUM(rack, t); - - for( t = 0; t < MAX_BRICK_TYPES; t++ ) { - if( brick_types[t] == bricktype ) - return RBT_TO_MODULE(rack, bay, t); - } - - return ELSC_ERROR_MODULE; -} - -int elsc_partition_set(elsc_t *e, int partition) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_PARTITION_SET, 2, - L1_ARG_INT, partition )) < 0 ) - { - - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return( 0 ); -} - -int elsc_partition_get(elsc_t *e) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t partition_id; /* used to copy partition id out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_PARTITION_GET, 0 )) < 0 ) - - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return( partition_id ); -} - - -/* - * elsc_cons_subch selects the "active" console subchannel for this node - * (i.e., the one that will currently receive input) - */ -int elsc_cons_subch(elsc_t *e, uint ch) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_CONS_SUBCH, 2, - L1_ARG_INT, ch)) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -/* - * elsc_cons_node should only be executed by one node. It declares to - * the system controller that the node from which it is called will be - * the owner of the system console. - */ -int elsc_cons_node(elsc_t *e) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_CONS_NODE, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -/* elsc_display_line writes up to 12 characters to either the top or bottom - * line of the L1 display. line points to a buffer containing the message - * to be displayed. The zero-based line number is specified by lnum (so - * lnum == 0 specifies the top line and lnum == 1 specifies the bottom). - * Lines longer than 12 characters, or line numbers not less than - * L1_DISPLAY_LINES, cause elsc_display_line to return an error. - */ -int elsc_display_line(elsc_t *e, char *line, int lnum) -{ - char msg[BRL1_QSIZE]; - int subch; /* system controller subchannel used */ - int len; /* number of msg buffer bytes used */ - - /* argument sanity checking */ - if( !(lnum < L1_DISPLAY_LINES) ) - return( ELSC_ERROR_CMD_ARGS ); - if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) ) - return( ELSC_ERROR_CMD_ARGS ); - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - (L1_REQ_DISP1+lnum), 2, - L1_ARG_ASCII, line )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( (l1sc_t *)e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -/* elsc_display_mesg silently drops message characters beyond the 12th. - */ -int elsc_display_mesg(elsc_t *e, char *chr) -{ - - char line[L1_DISPLAY_LINE_LENGTH+1]; - int numlines, i; - int result; - - numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) / - L1_DISPLAY_LINE_LENGTH; - - if( numlines > L1_DISPLAY_LINES ) - numlines = L1_DISPLAY_LINES; - - for( i = 0; i < numlines; i++ ) - { - strncpy( line, chr, L1_DISPLAY_LINE_LENGTH ); - line[L1_DISPLAY_LINE_LENGTH] = '\0'; - - /* generally we want to leave the first line of the L1 display - * alone (so the L1 can manipulate it). If you need to be able - * to display to both lines (for debugging purposes), define - * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES - * to your 'defs file. - */ -#if defined(L1_DISP_2LINES) - if( (result = elsc_display_line( e, line, i )) < 0 ) -#else - if( (result = elsc_display_line( e, line, i+1 )) < 0 ) -#endif - - return result; - - chr += L1_DISPLAY_LINE_LENGTH; - } - - return 0; -} - - -int elsc_password_set(elsc_t *e, char *password) -{ - /* shush compiler */ - e = e; - password = password; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - -int elsc_password_get(elsc_t *e, char *password) -{ - /* shush compiler */ - e = e; - password = password; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - - -/* - * sc_portspeed_get - * - * retrieve the current portspeed setting for the bedrock II - */ -int sc_portspeed_get(l1sc_t *sc) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - int portspeed_a, portspeed_b; - /* ioport clock rates */ - - bzero( msg, BRL1_QSIZE ); - subch = sc_open( sc, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_PORTSPEED, - 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 4, - L1_ARG_INT, &portspeed_a, - L1_ARG_INT, &portspeed_b ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* for the c-brick, we ignore the portspeed_b value */ - return (portspeed_a ? 600 : 400); -} - -/* - * elsc_power_query - * - * To be used after system reset, this command returns 1 if the reset - * was the result of a power-on, 0 otherwise. - * - * The power query status is cleared to 0 after it is read. - */ - -int elsc_power_query(elsc_t *e) -{ - e = e; /* shush the compiler */ - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 1; -} - -int elsc_rpwr_query(elsc_t *e, int is_master) -{ - /* shush the compiler */ - e = e; - is_master = is_master; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - -/* - * elsc_power_down - * - * Sets up system to shut down in "sec" seconds (or modifies the - * shutdown time if one is already in effect). Use 0 to power - * down immediately. - */ - -int elsc_power_down(elsc_t *e, int sec) -{ - /* shush compiler */ - e = e; - sec = sec; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - - -int elsc_system_reset(elsc_t *e) -{ - char msg[BRL1_QSIZE]; - int subch; /* system controller subchannel used */ - int len; /* number of msg buffer bytes used */ - int result; - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RESET, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( (result = sc_command( e, subch, msg, msg, &len )) ) { - sc_close( e, subch ); - if( result == SC_NMSG ) { - /* timeout is OK. We've sent the reset. Now it's just - * a matter of time... - */ - return( 0 ); - } - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -int elsc_power_cycle(elsc_t *e) -{ - /* shush compiler */ - e = e; - - /* fill in buffer with the opcode & params; call sc_command */ - - return 0; -} - - -/* - * L1 Support for reading - * cbrick uid. - */ - -int elsc_nic_get(elsc_t *e, uint64_t *nic, int verbose) -{ - /* this parameter included only for SN0 compatibility */ - verbose = verbose; - - /* We don't go straight to the bedrock/L1 protocol on this one, but let - * the eeprom layer prepare the eeprom data as we would like it to - * appear to the caller - */ - return cbrick_uid_get( e->nasid, nic ); -} - - -int _elsc_hbt(elsc_t *e, int ival, int rdly) -{ - e = e; - ival = ival; - rdly = rdly; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - - -/* send a command string to an L1 */ -int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay, - char *cmd ) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - l1addr_t target; /* target system controller for command */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - - L1_BUILD_ADDR( &target, compt, rack, bay, 0 ); - subch = sc_open( sc, target ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2, - L1_ARG_ASCII, cmd )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - -/* - * sc_power_down - * - * Shuts down the c-brick associated with sc, and any attached I/O bricks - * or other c-bricks (won't go through r-bricks). - */ - -int sc_power_down(l1sc_t *sc) -{ - return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, - L1_ADDR_BAY_LOCAL, "* pwr d" ); -} - - -/* - * sc_power_down_all - * - * Works similarly to sc_power_down, except that the request is sent to the - * closest L2 and EVERYBODY gets turned off. - */ - -int sc_power_down_all(l1sc_t *sc) -{ - if( nodepda->num_routers > 0 ) { - return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, - L1_ADDR_BAY_LOCAL, "* pwr d" ); - } - else { - return sc_power_down( sc ); - } -} - - -/* - * Routines for reading the R-brick's L1 - */ - -int router_module_get( nasid_t nasid, net_vec_t path ) -{ - uint rnum, rack, bay, t; - int ret; - l1sc_t sc; - - /* prepare l1sc_t struct */ - sc_init( &sc, nasid, path ); - - /* construct module ID from rack and slot info */ - - if ((ret = elsc_rack_bay_get(&sc, &rnum, &bay)) < 0) - return ret; - - /* report unset location info. with a special, otherwise invalid modid */ - if (rnum == 0 && bay == 0) - return MODULE_NOT_SET; - - if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) - return ELSC_ERROR_MODULE; - - /* Build a moduleid_t-compatible rack number */ - - rack = 0; - t = rnum / 100; /* rack class (CPU/IO) */ - if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_CLASS(rack, t); - rnum %= 100; - - t = rnum / 10; /* rack group */ - if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_GROUP(rack, t); - - t = rnum % 10; /* rack number (one-based) */ - if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_NUM(rack, t); - - ret = RBT_TO_MODULE(rack, bay, MODULE_RBRICK); - return ret; -} - - -/* - * iobrick routines - */ - -/* iobrick_rack_bay_type_get fills in the three int * arguments with the - * rack number, bay number and brick type of the L1 being addressed. Note - * that if the L1 operation fails and this function returns an error value, - * garbage may be written to brick_type. - */ -int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, - uint *bay, uint *brick_type ) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t buf32; /* used to copy 32-bit rack & bay out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RRBT, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) ) { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, - L1_ARG_INT, brick_type ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* extract rack/bay info - * - * note that the 32-bit value returned by the L1 actually - * only uses the low-order sixteen bits for rack and bay - * information. A "normal" L1 address puts rack and bay - * information in bit positions 12 through 28. So if - * we initially shift the value returned 12 bits to the left, - * we can use the L1 addressing #define's to extract the - * values we need (see ksys/l1.h for a complete list of the - * various fields of an L1 address). - */ - buf32 <<= L1_ADDR_BAY_SHFT; - - *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - - return 0; -} - - -int iobrick_module_get(l1sc_t *sc) -{ - uint rnum, rack, bay, brick_type, t; - int ret; - - /* construct module ID from rack and slot info */ - - if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0) - return ret; - - if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) - return ELSC_ERROR_MODULE; - - /* Build a moduleid_t-compatible rack number */ - - rack = 0; - t = rnum / 100; /* rack class (CPU/IO) */ - if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_CLASS(rack, t); - rnum %= 100; - - t = rnum / 10; /* rack group */ - if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_GROUP(rack, t); - - t = rnum % 10; /* rack number (one-based) */ - if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_NUM(rack, t); - - switch( brick_type ) { - case 'I': - brick_type = MODULE_IBRICK; break; - case 'P': - brick_type = MODULE_PBRICK; break; - case 'X': - brick_type = MODULE_XBRICK; break; - } - - ret = RBT_TO_MODULE(rack, bay, brick_type); - - return ret; -} - -/* iobrick_get_sys_snum asks the attached iobrick for the system - * serial number. This function will only be relevant to the master - * cbrick (the one attached to the bootmaster ibrick); other nodes - * may call the function, but the value returned to the master node - * will be the one used as the system serial number by the kernel. - */ - -int -iobrick_get_sys_snum( l1sc_t *sc, char *snum_str ) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_SYS_SERIAL, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) ) { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) ); -} - - -/* - * The following functions apply (or cut off) power to the specified - * pci bus or slot. - */ - -int -iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code ) -{ -#if 0 /* The "bedrock request" method of performing this function - * seems to be broken in the L1, so for now use the command- - * interpreter method - */ - - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( sc, L1_ADDR_LOCALIO ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - req_code, 4, - L1_ARG_INT, bus, - L1_ARG_INT, slot )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; - -#else - char cmd[64]; - char *fxn; - - switch( req_code ) - { - case L1_REQ_PCI_UP: - fxn = "u"; - break; - case L1_REQ_PCI_DOWN: - fxn = "d"; - break; - case L1_REQ_PCI_RESET: - fxn = "rst"; - break; - default: - return( ELSC_ERROR_CMD_ARGS ); - } - - if( slot == -1 ) - sprintf( cmd, "pci %d %s", bus, fxn ); - else - sprintf( cmd, "pci %d %d %s", bus, slot, fxn ); - - return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK, - L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd ); -#endif -} - -int -iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up ) -{ - return iobrick_pci_pwr( sc, bus, slot, up ); -} - -int -iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up ) -{ - return iobrick_pci_pwr( sc, bus, -1, up ); -} - - -int -iobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot ) -{ - return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET ); -} - -int -iobrick_pci_bus_rst( l1sc_t *sc, int bus ) -{ - return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET ); -} - - -/* get the L1 firmware version for an iobrick */ -int -iobrick_sc_version( l1sc_t *sc, char *result ) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - int major, /* major rev number */ - minor, /* minor rev number */ - bugfix; /* bugfix rev number */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( sc, L1_ADDR_LOCALIO ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_FW_REV, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major, - L1_ARG_INT, &minor, L1_ARG_INT, &bugfix ) - < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - sprintf( result, "%d.%d.%d", major, minor, bugfix ); - - return 0; -} diff -urN linux-2.4.21/arch/ia64/sn/io/labelcl.c linux-2.4.22/arch/ia64/sn/io/labelcl.c --- linux-2.4.21/arch/ia64/sn/io/labelcl.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/labelcl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,654 +0,0 @@ -/* labelcl - SGI's Hwgraph Compatibility Layer. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (c) 2001-2002 Silicon Graphics, Inc. All rights reserved. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* -** Very simple and dumb string table that supports only find/insert. -** In practice, if this table gets too large, we may need a more -** efficient data structure. Also note that currently there is no -** way to delete an item once it's added. Therefore, name collision -** will return an error. -*/ - -struct string_table label_string_table; - - - -/* - * string_table_init - Initialize the given string table. - */ -void -string_table_init(struct string_table *string_table) -{ - string_table->string_table_head = NULL; - string_table->string_table_generation = 0; - - /* - * We nedd to initialize locks here! - */ - - return; -} - - -/* - * string_table_destroy - Destroy the given string table. - */ -void -string_table_destroy(struct string_table *string_table) -{ - struct string_table_item *item, *next_item; - - item = string_table->string_table_head; - while (item) { - next_item = item->next; - - STRTBL_FREE(item); - item = next_item; - } - - /* - * We need to destroy whatever lock we have here - */ - - return; -} - - - -/* - * string_table_insert - Insert an entry in the string table .. duplicate - * names are not allowed. - */ -char * -string_table_insert(struct string_table *string_table, char *name) -{ - struct string_table_item *item, *new_item = NULL, *last_item = NULL; - -again: - /* - * Need to lock the table .. - */ - item = string_table->string_table_head; - last_item = NULL; - - while (item) { - if (!strcmp(item->string, name)) { - /* - * If we allocated space for the string and the found that - * someone else already entered it into the string table, - * free the space we just allocated. - */ - if (new_item) - STRTBL_FREE(new_item); - - - /* - * Search optimization: move the found item to the head - * of the list. - */ - if (last_item != NULL) { - last_item->next = item->next; - item->next = string_table->string_table_head; - string_table->string_table_head = item; - } - goto out; - } - last_item = item; - item=item->next; - } - - /* - * name was not found, so add it to the string table. - */ - if (new_item == NULL) { - long old_generation = string_table->string_table_generation; - - new_item = STRTBL_ALLOC(strlen(name)); - - strcpy(new_item->string, name); - - /* - * While we allocated memory for the new string, someone else - * changed the string table. - */ - if (old_generation != string_table->string_table_generation) { - goto again; - } - } else { - /* At this we only have the string table lock in access mode. - * Promote the access lock to an update lock for the string - * table insertion below. - */ - long old_generation = - string_table->string_table_generation; - - /* - * After we did the unlock and wer waiting for update - * lock someone could have potentially updated - * the string table. Check the generation number - * for this case. If it is the case we have to - * try all over again. - */ - if (old_generation != - string_table->string_table_generation) { - goto again; - } - } - - /* - * At this point, we're committed to adding new_item to the string table. - */ - new_item->next = string_table->string_table_head; - item = string_table->string_table_head = new_item; - string_table->string_table_generation++; - -out: - /* - * Need to unlock here. - */ - return(item->string); -} - -/* - * labelcl_info_create - Creates the data structure that will hold the - * device private information asscoiated with a devfs entry. - * The pointer to this structure is what gets stored in the devfs - * (void * info). - */ -labelcl_info_t * -labelcl_info_create() -{ - - labelcl_info_t *new = NULL; - - /* Initial allocation does not include any area for labels */ - if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL ) - return NULL; - - memset (new, 0, sizeof(labelcl_info_t)); - new->hwcl_magic = LABELCL_MAGIC; - return( new); - -} - -/* - * labelcl_info_destroy - Frees the data structure that holds the - * device private information asscoiated with a devfs entry. This - * data structure was created by device_info_create(). - * - * The caller is responsible for nulling the (void *info) in the - * corresponding devfs entry. - */ -int -labelcl_info_destroy(labelcl_info_t *labelcl_info) -{ - - if (labelcl_info == NULL) - return(0); - - /* Free the label list */ - if (labelcl_info->label_list) - kfree(labelcl_info->label_list); - - /* Now free the label info area */ - labelcl_info->hwcl_magic = 0; - kfree(labelcl_info); - - return(0); -} - -/* - * labelcl_info_add_LBL - Adds a new label entry in the labelcl info - * structure. - * - * Error is returned if we find another label with the same name. - */ -int -labelcl_info_add_LBL(devfs_handle_t de, - char *info_name, - arb_info_desc_t info_desc, - arbitrary_info_t info) -{ - labelcl_info_t *labelcl_info = NULL; - int num_labels; - int new_label_list_size; - label_info_t *old_label_list, *new_label_list = NULL; - char *name; - int i; - - if (de == NULL) - return(-1); - - labelcl_info = devfs_get_info(de); - if (labelcl_info == NULL) - return(-1); - - if (labelcl_info->hwcl_magic != LABELCL_MAGIC) - return(-1); - - if (info_name == NULL) - return(-1); - - if (strlen(info_name) >= LABEL_LENGTH_MAX) - return(-1); - - name = string_table_insert(&label_string_table, info_name); - - num_labels = labelcl_info->num_labels; - new_label_list_size = sizeof(label_info_t) * (num_labels+1); - - /* - * Create a new label info area. - */ - if (new_label_list_size != 0) { - new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); - - if (new_label_list == NULL) - return(-1); - } - - /* - * At this point, we are committed to adding the labelled info, - * if there isn't already information there with the same name. - */ - old_label_list = labelcl_info->label_list; - - /* - * Look for matching info name. - */ - for (i=0; inum_labels = num_labels+1; - labelcl_info->label_list = new_label_list; - - if (old_label_list != NULL) - kfree(old_label_list); - - return(0); -} - -/* - * labelcl_info_remove_LBL - Remove a label entry. - */ -int -labelcl_info_remove_LBL(devfs_handle_t de, - char *info_name, - arb_info_desc_t *info_desc, - arbitrary_info_t *info) -{ - labelcl_info_t *labelcl_info = NULL; - int num_labels; - int new_label_list_size; - label_info_t *old_label_list, *new_label_list = NULL; - arb_info_desc_t label_desc_found; - arbitrary_info_t label_info_found; - int i; - - if (de == NULL) - return(-1); - - labelcl_info = devfs_get_info(de); - if (labelcl_info == NULL) - return(-1); - - if (labelcl_info->hwcl_magic != LABELCL_MAGIC) - return(-1); - - num_labels = labelcl_info->num_labels; - if (num_labels == 0) { - return(-1); - } - - /* - * Create a new info area. - */ - new_label_list_size = sizeof(label_info_t) * (num_labels-1); - if (new_label_list_size) { - new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); - if (new_label_list == NULL) - return(-1); - } - - /* - * At this point, we are committed to removing the labelled info, - * if it still exists. - */ - old_label_list = labelcl_info->label_list; - - /* - * Find matching info name. - */ - for (i=0; inum_labels = num_labels+1; - labelcl_info->label_list = new_label_list; - - kfree(old_label_list); - - if (info != NULL) - *info = label_info_found; - - if (info_desc != NULL) - *info_desc = label_desc_found; - - return(0); -} - - -/* - * labelcl_info_replace_LBL - Replace an existing label entry with the - * given new information. - * - * Label entry must exist. - */ -int -labelcl_info_replace_LBL(devfs_handle_t de, - char *info_name, - arb_info_desc_t info_desc, - arbitrary_info_t info, - arb_info_desc_t *old_info_desc, - arbitrary_info_t *old_info) -{ - labelcl_info_t *labelcl_info = NULL; - int num_labels; - label_info_t *label_list; - int i; - - if (de == NULL) - return(-1); - - labelcl_info = devfs_get_info(de); - if (labelcl_info == NULL) - return(-1); - - if (labelcl_info->hwcl_magic != LABELCL_MAGIC) - return(-1); - - num_labels = labelcl_info->num_labels; - if (num_labels == 0) { - return(-1); - } - - if (info_name == NULL) - return(-1); - - label_list = labelcl_info->label_list; - - /* - * Verify that information under info_name already exists. - */ - for (i=0; ihwcl_magic != LABELCL_MAGIC) - return(-1); - - num_labels = labelcl_info->num_labels; - if (num_labels == 0) { - return(-1); - } - - label_list = labelcl_info->label_list; - - /* - * Find information under info_name. - */ - for (i=0; ihwcl_magic != LABELCL_MAGIC) - return(-1); - - which_info = *placeptr; - - if (which_info >= labelcl_info->num_labels) { - return(-1); - } - - label_list = (label_info_t *) labelcl_info->label_list; - - if (buffer != NULL) - strcpy(buffer, label_list[which_info].name); - - if (infop) - *infop = label_list[which_info].info; - - if (info_descp) - *info_descp = label_list[which_info].desc; - - *placeptr = which_info + 1; - - return(0); -} - - -int -labelcl_info_replace_IDX(devfs_handle_t de, - int index, - arbitrary_info_t info, - arbitrary_info_t *old_info) -{ - arbitrary_info_t *info_list_IDX; - labelcl_info_t *labelcl_info = NULL; - - if (de == NULL) { - printk(KERN_ALERT "labelcl: NULL devfs handle given.\n"); - return(-1); - } - - labelcl_info = devfs_get_info(de); - if (labelcl_info == NULL) { - printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n"); - return(-1); - } - - if (labelcl_info->hwcl_magic != LABELCL_MAGIC) - return(-1); - - if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) - return(-1); - - /* - * Replace information at the appropriate index in this vertex with - * the new info. - */ - info_list_IDX = labelcl_info->IDX_list; - if (old_info != NULL) - *old_info = info_list_IDX[index]; - info_list_IDX[index] = info; - - return(0); - -} - -/* - * labelcl_info_connectpt_set - Sets the connectpt. - */ -int -labelcl_info_connectpt_set(struct devfs_entry *de, - struct devfs_entry *connect_de) -{ - arbitrary_info_t old_info; - int rv; - - rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, - (arbitrary_info_t) connect_de, &old_info); - - if (rv) { - return(rv); - } - - return(0); -} - - -/* - * labelcl_info_get_IDX - Returns the information pointed at by index. - * - */ -int -labelcl_info_get_IDX(devfs_handle_t de, - int index, - arbitrary_info_t *info) -{ - arbitrary_info_t *info_list_IDX; - labelcl_info_t *labelcl_info = NULL; - - if (de == NULL) - return(-1); - - labelcl_info = devfs_get_info(de); - if (labelcl_info == NULL) - return(-1); - - if (labelcl_info->hwcl_magic != LABELCL_MAGIC) - return(-1); - - if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) - return(-1); - - /* - * Return information at the appropriate index in this vertex. - */ - info_list_IDX = labelcl_info->IDX_list; - if (info != NULL) - *info = info_list_IDX[index]; - - return(0); -} - -/* - * labelcl_info_connectpt_get - Retrieve the connect point for a device entry. - */ -struct devfs_entry * -labelcl_info_connectpt_get(struct devfs_entry *de) -{ - int rv; - arbitrary_info_t info; - - rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); - if (rv) - return(NULL); - - return((struct devfs_entry *)info); -} diff -urN linux-2.4.21/arch/ia64/sn/io/machvec/Makefile linux-2.4.22/arch/ia64/sn/io/machvec/Makefile --- linux-2.4.21/arch/ia64/sn/io/machvec/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/machvec/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,18 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. +# +# Makefile for the sn2 io routines. + +EXTRA_CFLAGS := -DLITTLE_ENDIAN + +O_TARGET := snio.o + +export-objs := pci_dma.o iomv.o + +obj-y += pci.o pci_dma.o pci_bus_cvlink.o iomv.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/machvec/iomv.c linux-2.4.22/arch/ia64/sn/io/machvec/iomv.c --- linux-2.4.21/arch/ia64/sn/io/machvec/iomv.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/machvec/iomv.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,75 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * sn_io_addr - convert an in/out port to an i/o address + * @port: port to convert + * + * Legacy in/out instructions are converted to ld/st instructions + * on IA64. This routine will convert a port number into a valid + * SN i/o address. Used by sn_in*() and sn_out*(). + */ +void * +sn_io_addr(unsigned long port) +{ + if (!IS_RUNNING_ON_SIMULATOR()) { + /* On sn2, legacy I/O ports don't point at anything */ + if (port < 64*1024) + return 0; + return( (void *) (port | __IA64_UNCACHED_OFFSET)); + } else { + /* but the simulator uses them... */ + unsigned long io_base; + unsigned long addr; + + /* + * word align port, but need more than 10 bits + * for accessing registers in bedrock local block + * (so we don't do port&0xfff) + */ + if ((port >= 0x1f0 && port <= 0x1f7) || + port == 0x3f6 || port == 0x3f7) { + io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38)); + addr = io_base | ((port >> 2) << 12) | (port & 0xfff); + } else { + addr = __ia64_get_io_port_base() | ((port >> 2) << 2); + } + return(void *) addr; + } +} + +EXPORT_SYMBOL(sn_io_addr); + +/** + * sn_mmiob - I/O space memory barrier + * + * Acts as a memory mapped I/O barrier for platforms that queue writes to + * I/O space. This ensures that subsequent writes to I/O space arrive after + * all previous writes. For most ia64 platforms, this is a simple + * 'mf.a' instruction. For other platforms, mmiob() may have to read + * a chipset register to ensure ordering. + * + * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear. + * See PV 871084 for details about the WAR about zero value. + * + */ +void +sn_mmiob (void) +{ + while ((((volatile unsigned long) (*pda.pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != + SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) + udelay(1); +} diff -urN linux-2.4.21/arch/ia64/sn/io/machvec/pci.c linux-2.4.22/arch/ia64/sn/io/machvec/pci.c --- linux-2.4.21/arch/ia64/sn/io/machvec/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/machvec/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,291 @@ +/* + * + * SNI64 specific PCI support for SNI IO. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1997, 1998, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG_CONFIG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + + + +#ifdef CONFIG_PCI + +extern vertex_hdl_t pci_bus_to_vertex(unsigned char); +extern vertex_hdl_t devfn_to_vertex(unsigned char bus, unsigned char devfn); + +/* + * snia64_read_config_byte - Read a byte from the config area of the device. + */ +static int snia64_read_config_byte (struct pci_dev *dev, + int where, unsigned char *val) +{ + unsigned long res = 0; + unsigned size = 1; + vertex_hdl_t device_vertex; + + if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + res = pciio_config_get(device_vertex, (unsigned) where, size); + *val = (unsigned char) res; + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_read_config_word - Read 2 bytes from the config area of the device. + */ +static int snia64_read_config_word (struct pci_dev *dev, + int where, unsigned short *val) +{ + unsigned long res = 0; + unsigned size = 2; /* 2 bytes */ + vertex_hdl_t device_vertex; + + if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + res = pciio_config_get(device_vertex, (unsigned) where, size); + *val = (unsigned short) res; + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_read_config_dword - Read 4 bytes from the config area of the device. + */ +static int snia64_read_config_dword (struct pci_dev *dev, + int where, unsigned int *val) +{ + unsigned long res = 0; + unsigned size = 4; /* 4 bytes */ + vertex_hdl_t device_vertex; + + if (where & 3) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + res = pciio_config_get(device_vertex, (unsigned) where, size); + *val = (unsigned int) res; + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_write_config_byte - Writes 1 byte to the config area of the device. + */ +static int snia64_write_config_byte (struct pci_dev *dev, + int where, unsigned char val) +{ + vertex_hdl_t device_vertex; + + if ( dev == (struct pci_dev *)0 ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + /* + * if it's an IOC3 then we bail out, we special + * case them with pci_fixup_ioc3 + */ + if (dev->vendor == PCI_VENDOR_ID_SGI && + dev->device == PCI_DEVICE_ID_SGI_IOC3 ) + return PCIBIOS_SUCCESSFUL; + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_write_config_word - Writes 2 bytes to the config area of the device. + */ +static int snia64_write_config_word (struct pci_dev *dev, + int where, unsigned short val) +{ + vertex_hdl_t device_vertex = NULL; + + if (where & 1) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + if ( dev == (struct pci_dev *)0 ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + /* + * if it's an IOC3 then we bail out, we special + * case them with pci_fixup_ioc3 + */ + if (dev->vendor == PCI_VENDOR_ID_SGI && + dev->device == PCI_DEVICE_ID_SGI_IOC3) + return PCIBIOS_SUCCESSFUL; + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_write_config_dword - Writes 4 bytes to the config area of the device. + */ +static int snia64_write_config_dword (struct pci_dev *dev, + int where, unsigned int val) +{ + vertex_hdl_t device_vertex; + + if (where & 3) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + if ( dev == (struct pci_dev *)0 ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + /* + * if it's an IOC3 then we bail out, we special + * case them with pci_fixup_ioc3 + */ + if (dev->vendor == PCI_VENDOR_ID_SGI && + dev->device == PCI_DEVICE_ID_SGI_IOC3) + return PCIBIOS_SUCCESSFUL; + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops snia64_pci_ops = { + snia64_read_config_byte, + snia64_read_config_word, + snia64_read_config_dword, + snia64_write_config_byte, + snia64_write_config_word, + snia64_write_config_dword +}; + +/* + * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code. + */ +void __init +sn_pci_find_bios(void) +{ + extern struct pci_ops *pci_root_ops; + /* + * Go initialize our IO Infrastructure .. + */ + extern void sgi_master_io_infr_init(void); + + sgi_master_io_infr_init(); + + /* sn_io_infrastructure_init(); */ + pci_root_ops = &snia64_pci_ops; +} + +void +pci_fixup_ioc3(struct pci_dev *d) +{ + int i; + unsigned int size; + + /* IOC3 only decodes 0x20 bytes of the config space, reading + * beyond that is relatively benign but writing beyond that + * (especially the base address registers) will shut down the + * pci bus...so avoid doing so. + * NOTE: this means we can't program the intr_pin into the device, + * currently we hack this with special code in + * sgi_pci_intr_support() + */ + DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name); + + /* I happen to know from the spec that the ioc3 needs only 0xfffff + * The standard pci trick of writing ~0 to the baddr and seeing + * what comes back doesn't work with the ioc3 + */ + size = 0xfffff; + d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size; + + /* + * Zero out the resource structure .. because we did not go through + * the normal PCI Infrastructure Init, garbbage are left in these + * fileds. + */ + for (i = 1; i <= PCI_ROM_RESOURCE; i++) { + d->resource[i].start = 0UL; + d->resource[i].end = 0UL; + d->resource[i].flags = 0UL; + } + + d->subsystem_vendor = 0; + d->subsystem_device = 0; + +} + +#else +void sn_pci_find_bios(void) {} +void pci_fixup_ioc3(struct pci_dev *d) {} +struct list_head pci_root_buses; +struct list_head pci_root_buses; +struct list_head pci_devices; + +#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/ia64/sn/io/machvec/pci_bus_cvlink.c linux-2.4.22/arch/ia64/sn/io/machvec/pci_bus_cvlink.c --- linux-2.4.21/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,930 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int bridge_rev_b_data_check_disable; + +vertex_hdl_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET]; +nasid_t busnum_to_nid[MAX_PCI_XWIDGET]; +void * busnum_to_atedmamaps[MAX_PCI_XWIDGET]; +unsigned char num_bridges; +static int done_probing; +extern irqpda_t *irqpdaindr; + +static int pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid); +vertex_hdl_t devfn_to_vertex(unsigned char busnum, unsigned int devfn); + +extern void register_pcibr_intr(int irq, pcibr_intr_t intr); + +void sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot); + + +/* + * For the given device, initialize whether it is a PIC device. + */ +static void +set_isPIC(struct sn_device_sysdata *device_sysdata) +{ + pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + + device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);; +} + +/* + * pci_bus_cvlink_init() - To be called once during initialization before + * SGI IO Infrastructure init is called. + */ +void +pci_bus_cvlink_init(void) +{ + + extern void ioconfig_bus_init(void); + + memset(busnum_to_pcibr_vhdl, 0x0, sizeof(vertex_hdl_t) * MAX_PCI_XWIDGET); + memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET); + + memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET); + + num_bridges = 0; + + ioconfig_bus_init(); +} + +/* + * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated + * pci bus vertex from the SGI IO Infrastructure. + */ +vertex_hdl_t +pci_bus_to_vertex(unsigned char busnum) +{ + + vertex_hdl_t pci_bus = NULL; + + + /* + * First get the xwidget vertex. + */ + pci_bus = busnum_to_pcibr_vhdl[busnum]; + return(pci_bus); +} + +/* + * devfn_to_vertex() - returns the vertex of the device given the bus, slot, + * and function numbers. + */ +vertex_hdl_t +devfn_to_vertex(unsigned char busnum, unsigned int devfn) +{ + + int slot = 0; + int func = 0; + char name[16]; + vertex_hdl_t pci_bus = NULL; + vertex_hdl_t device_vertex = (vertex_hdl_t)NULL; + + /* + * Go get the pci bus vertex. + */ + pci_bus = pci_bus_to_vertex(busnum); + if (!pci_bus) { + /* + * During probing, the Linux pci code invents non-existent + * bus numbers and pci_dev structures and tries to access + * them to determine existence. Don't crib during probing. + */ + if (done_probing) + printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum); + return(NULL); + } + + + /* + * Go get the slot&function vertex. + * Should call pciio_slot_func_to_name() when ready. + */ + slot = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + /* + * For a NON Multi-function card the name of the device looks like: + * ../pci/1, ../pci/2 .. + */ + if (func == 0) { + sprintf(name, "%d", slot); + if (hwgraph_traverse(pci_bus, name, &device_vertex) == + GRAPH_SUCCESS) { + if (device_vertex) { + return(device_vertex); + } + } + } + + /* + * This maybe a multifunction card. It's names look like: + * ../pci/1a, ../pci/1b, etc. + */ + sprintf(name, "%d%c", slot, 'a'+func); + if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) { + if (!device_vertex) { + return(NULL); + } + } + + return(device_vertex); +} + +/* + * For the given device, initialize the addresses for both the Device(x) Flush + * Write Buffer register and the Xbow Flush Register for the port the PCI bus + * is connected. + */ +static void +set_flush_addresses(struct pci_dev *device_dev, + struct sn_device_sysdata *device_sysdata) +{ + pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + bridge_t *bridge = pcibr_soft->bs_base; + nasid_t nasid; + + /* + * Get the nasid from the bridge. + */ + nasid = NASID_GET(device_sysdata->dma_buf_sync); + if (IS_PIC_DEVICE(device_dev)) { + device_sysdata->dma_buf_sync = (volatile unsigned int *) + &bridge->b_wr_req_buf[pciio_slot].reg; + device_sysdata->xbow_buf_sync = (volatile unsigned int *) + XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0), + pcibr_soft->bs_xid); + } else { + /* + * Accessing Xbridge and Xbow register when SHUB swapoper is on!. + */ + device_sysdata->dma_buf_sync = (volatile unsigned int *) + ((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4); + device_sysdata->xbow_buf_sync = (volatile unsigned int *) + ((uint64_t)(XBOW_PRIO_LINKREGS_PTR( + NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4); + } + +#ifdef DEBUG + printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", + device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync); + +printk("set_flush_addresses: dma_buf_sync\n"); + while((volatile unsigned int )*device_sysdata->dma_buf_sync); +printk("set_flush_addresses: xbow_buf_sync\n"); + while((volatile unsigned int )*device_sysdata->xbow_buf_sync); +#endif + +} + +struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS]; + +// Initialize the data structures for flushing write buffers after a PIO read. +// The theory is: +// Take an unused int. pin and associate it with a pin that is in use. +// After a PIO read, force an interrupt on the unused pin, forcing a write buffer flush +// on the in use pin. This will prevent the race condition between PIO read responses and +// DMA writes. +void +sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot) { + nasid_t nasid; + unsigned long dnasid; + int wid_num; + int bus; + struct sn_flush_device_list *p; + bridge_t *b; + bridgereg_t dev_sel; + extern int isIO9(int); + int bwin; + int i; + + nasid = NASID_GET(start); + wid_num = SWIN_WIDGETNUM(start); + bus = (start >> 23) & 0x1; + bwin = BWIN_WINDOWNUM(start); + + if (flush_nasid_list[nasid].widget_p == NULL) { + flush_nasid_list[nasid].widget_p = (struct sn_flush_device_list **)kmalloc((HUB_WIDGET_ID_MAX+1) * + sizeof(struct sn_flush_device_list *), GFP_KERNEL); + memset(flush_nasid_list[nasid].widget_p, 0, (HUB_WIDGET_ID_MAX+1) * sizeof(struct sn_flush_device_list *)); + } + if (bwin > 0) { + bwin--; + switch (bwin) { + case 0: + flush_nasid_list[nasid].iio_itte1 = HUB_L(IIO_ITTE_GET(nasid, 0)); + wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf; + bus = flush_nasid_list[nasid].iio_itte1 & 0xf; + if (bus == 0x4 || bus == 0x8) + bus = 0; + else + bus = 1; + break; + case 1: + flush_nasid_list[nasid].iio_itte2 = HUB_L(IIO_ITTE_GET(nasid, 1)); + wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf; + bus = flush_nasid_list[nasid].iio_itte2 & 0xf; + if (bus == 0x4 || bus == 0x8) + bus = 0; + else + bus = 1; + break; + case 2: + flush_nasid_list[nasid].iio_itte3 = HUB_L(IIO_ITTE_GET(nasid, 2)); + wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf; + bus = flush_nasid_list[nasid].iio_itte3 & 0xf; + if (bus == 0x4 || bus == 0x8) + bus = 0; + else + bus = 1; + break; + case 3: + flush_nasid_list[nasid].iio_itte4 = HUB_L(IIO_ITTE_GET(nasid, 3)); + wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf; + bus = flush_nasid_list[nasid].iio_itte4 & 0xf; + if (bus == 0x4 || bus == 0x8) + bus = 0; + else + bus = 1; + break; + case 4: + flush_nasid_list[nasid].iio_itte5 = HUB_L(IIO_ITTE_GET(nasid, 4)); + wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf; + bus = flush_nasid_list[nasid].iio_itte5 & 0xf; + if (bus == 0x4 || bus == 0x8) + bus = 0; + else + bus = 1; + break; + case 5: + flush_nasid_list[nasid].iio_itte6 = HUB_L(IIO_ITTE_GET(nasid, 5)); + wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf; + bus = flush_nasid_list[nasid].iio_itte6 & 0xf; + if (bus == 0x4 || bus == 0x8) + bus = 0; + else + bus = 1; + break; + case 6: + flush_nasid_list[nasid].iio_itte7 = HUB_L(IIO_ITTE_GET(nasid, 6)); + wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf; + bus = flush_nasid_list[nasid].iio_itte7 & 0xf; + if (bus == 0x4 || bus == 0x8) + bus = 0; + else + bus = 1; + break; + } + } + + // if it's IO9, bus 1, we don't care about slots 1, 3, and 4. This is + // because these are the IOC4 slots and we don't flush them. + if (isIO9(nasid) && bus == 0 && (slot == 1 || slot == 4)) { + return; + } + if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) { + flush_nasid_list[nasid].widget_p[wid_num] = (struct sn_flush_device_list *)kmalloc( + DEV_PER_WIDGET * sizeof (struct sn_flush_device_list), GFP_KERNEL); + memset(flush_nasid_list[nasid].widget_p[wid_num], 0, + DEV_PER_WIDGET * sizeof (struct sn_flush_device_list)); + p = &flush_nasid_list[nasid].widget_p[wid_num][0]; + for (i=0; ibus = -1; + p->pin = -1; + p++; + } + } + + p = &flush_nasid_list[nasid].widget_p[wid_num][0]; + for (i=0;ipin == pin && p->bus == bus) break; + if (p->pin < 0) { + p->pin = pin; + p->bus = bus; + break; + } + p++; + } + + for (i=0; ibar_list[i].start == 0) { + p->bar_list[i].start = start; + p->bar_list[i].end = end; + break; + } + } + b = (bridge_t *)(NODE_SWIN_BASE(nasid, wid_num) | (bus << 23) ); + + // If it's IO9, then slot 2 maps to slot 7 and slot 6 maps to slot 8. + // To see this is non-trivial. By drawing pictures and reading manuals and talking + // to HW guys, we can see that on IO9 bus 1, slots 7 and 8 are always unused. + // Further, since we short-circuit slots 1, 3, and 4 above, we only have to worry + // about the case when there is a card in slot 2. A multifunction card will appear + // to be in slot 6 (from an interrupt point of view) also. That's the most we'll + // have to worry about. A four function card will overload the interrupt lines in + // slot 2 and 6. + // We also need to special case the 12160 device in slot 3. Fortunately, we have + // a spare intr. line for pin 4, so we'll use that for the 12160. + // All other buses have slot 3 and 4 and slots 7 and 8 unused. Since we can only + // see slots 1 and 2 and slots 5 and 6 coming through here for those buses (this + // is true only on Pxbricks with 2 physical slots per bus), we just need to add + // 2 to the slot number to find an unused slot. + // We have convinced ourselves that we will never see a case where two different cards + // in two different slots will ever share an interrupt line, so there is no need to + // special case this. + + if (isIO9(nasid) && wid_num == 0xc && bus == 0) { + if (slot == 2) { + p->force_int_addr = (unsigned long)&b->b_force_always[6].intr; + dev_sel = b->b_int_device; + dev_sel |= (1<<18); + b->b_int_device = dev_sel; + dnasid = NASID_GET(virt_to_phys(&p->flush_addr)); + b->p_int_addr_64[6] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | + (dnasid << 36) | (0xfUL << 48); + } else if (slot == 3) { /* 12160 SCSI device in IO9 */ + p->force_int_addr = (unsigned long)&b->b_force_always[4].intr; + dev_sel = b->b_int_device; + dev_sel |= (2<<12); + b->b_int_device = dev_sel; + dnasid = NASID_GET(virt_to_phys(&p->flush_addr)); + b->p_int_addr_64[4] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | + (dnasid << 36) | (0xfUL << 48); + } else { /* slot == 6 */ + p->force_int_addr = (unsigned long)&b->b_force_always[7].intr; + dev_sel = b->b_int_device; + dev_sel |= (5<<21); + b->b_int_device = dev_sel; + dnasid = NASID_GET(virt_to_phys(&p->flush_addr)); + b->p_int_addr_64[7] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | + (dnasid << 36) | (0xfUL << 48); + } + } else { + p->force_int_addr = (unsigned long)&b->b_force_always[pin + 2].intr; + dev_sel = b->b_int_device; + dev_sel |= ((slot - 1) << ( pin * 3) ); + b->b_int_device = dev_sel; + dnasid = NASID_GET(virt_to_phys(&p->flush_addr)); + b->p_int_addr_64[pin + 2] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | + (dnasid << 36) | (0xfUL << 48); + } +} + +/* + * Most drivers currently do not properly tell the arch specific pci dma + * interfaces whether they can handle A64. Here is where we privately + * keep track of this. + */ +static void __init +set_sn_pci64(struct pci_dev *dev) +{ + unsigned short vendor = dev->vendor; + unsigned short device = dev->device; + + if (vendor == PCI_VENDOR_ID_QLOGIC) { + if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) || + (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) { + SET_PCIA64(dev); + return; + } + } + + if (vendor == PCI_VENDOR_ID_SGI) { + if (device == PCI_DEVICE_ID_SGI_IOC3) { + SET_PCIA64(dev); + return; + } + } + +} + +/* + * sn_pci_fixup() - This routine is called when platform_pci_fixup() is + * invoked at the end of pcibios_init() to link the Linux pci + * infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c + * + * Other platform specific fixup can also be done here. + */ +void +sn_pci_fixup(int arg) +{ + struct list_head *ln; + struct pci_bus *pci_bus = NULL; + struct pci_dev *device_dev = NULL; + struct sn_widget_sysdata *widget_sysdata; + struct sn_device_sysdata *device_sysdata; + pciio_intr_t intr_handle; + int cpuid, bit; + vertex_hdl_t device_vertex; + pciio_intr_line_t lines; + extern void sn_pci_find_bios(void); + extern int numnodes; + int cnode; + + if (arg == 0) { +#ifdef CONFIG_PROC_FS + extern void register_sn_procfs(void); +#endif + + sn_pci_find_bios(); + for (cnode = 0; cnode < numnodes; cnode++) { + extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int); + intr_init_vecblk(NODEPDA(cnode), cnode, 0); + } +#ifdef CONFIG_PROC_FS + register_sn_procfs(); +#endif + return; + } + + + done_probing = 1; + + /* + * Initialize the pci bus vertex in the pci_bus struct. + */ + for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { + pci_bus = pci_bus_b(ln); + widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), + GFP_KERNEL); + widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number); + pci_bus->sysdata = (void *)widget_sysdata; + } + + /* + * set the root start and end so that drivers calling check_region() + * won't see a conflict + */ + ioport_resource.start = 0xc000000000000000; + ioport_resource.end = 0xcfffffffffffffff; + + /* + * Set the root start and end for Mem Resource. + */ + iomem_resource.start = 0; + iomem_resource.end = 0xffffffffffffffff; + + /* + * Initialize the device vertex in the pci_dev struct. + */ + pci_for_each_dev(device_dev) { + unsigned int irq; + int idx; + u16 cmd; + vertex_hdl_t vhdl; + unsigned long size; + extern int bit_pos_to_irq(int); + + if (device_dev->vendor == PCI_VENDOR_ID_SGI && + device_dev->device == PCI_DEVICE_ID_SGI_IOC3) { + extern void pci_fixup_ioc3(struct pci_dev *d); + pci_fixup_ioc3(device_dev); + } + + /* Set the device vertex */ + + device_sysdata = kmalloc(sizeof(struct sn_device_sysdata), + GFP_KERNEL); + device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn); + device_sysdata->isa64 = 0; + /* + * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush + * register addresses. + */ + (void) set_flush_addresses(device_dev, device_sysdata); + + device_dev->sysdata = (void *) device_sysdata; + set_sn_pci64(device_dev); + set_isPIC(device_sysdata); + + pci_read_config_word(device_dev, PCI_COMMAND, &cmd); + + /* + * Set the resources address correctly. The assumption here + * is that the addresses in the resource structure has been + * read from the card and it was set in the card by our + * Infrastructure .. + */ + vhdl = device_sysdata->vhdl; + for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { + size = 0; + size = device_dev->resource[idx].end - + device_dev->resource[idx].start; + if (size) { + device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); + device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET; + } + else + continue; + + device_dev->resource[idx].end = + device_dev->resource[idx].start + size; + + if (device_dev->resource[idx].flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + + if (device_dev->resource[idx].flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } +#if 0 + /* + * Software WAR for a Software BUG. + * This is only temporary. + * See PV 872791 + */ + + /* + * Now handle the ROM resource .. + */ + size = device_dev->resource[PCI_ROM_RESOURCE].end - + device_dev->resource[PCI_ROM_RESOURCE].start; + + if (size) { + device_dev->resource[PCI_ROM_RESOURCE].start = + (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, + size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); + device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET; + device_dev->resource[PCI_ROM_RESOURCE].end = + device_dev->resource[PCI_ROM_RESOURCE].start + size; + } +#endif + + /* + * Update the Command Word on the Card. + */ + cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */ + /* bit gets dropped .. no harm */ + pci_write_config_word(device_dev, PCI_COMMAND, cmd); + + pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines); + if (device_dev->vendor == PCI_VENDOR_ID_SGI && + device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { + lines = 1; + } + + device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata; + device_vertex = device_sysdata->vhdl; + + irqpdaindr->current = device_dev; + intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex); + + irq = intr_handle->pi_irq; + irqpdaindr->device_dev[irq] = device_dev; + cpuid = intr_handle->pi_cpu; + pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0); + device_dev->irq = irq; + register_pcibr_intr(irq, (pcibr_intr_t)intr_handle); + + for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { + int ibits = ((pcibr_intr_t)intr_handle)->bi_ibits; + int i; + + size = device_dev->resource[idx].end - + device_dev->resource[idx].start; + if (size == 0) continue; + + for (i=0; i<8; i++) { + if (ibits & (1 << i) ) { + sn_dma_flush_init(device_dev->resource[idx].start, + device_dev->resource[idx].end, + idx, + i, + PCI_SLOT(device_dev->devfn)); + } + } + } + + } +#ifdef ajmtestintr + { + int slot = PCI_SLOT(device_dev->devfn); + static int timer_set = 0; + pcibr_intr_t pcibr_intr = (pcibr_intr_t)intr_handle; + pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; + extern void intr_test_handle_intr(int, void*, struct pt_regs *); + + if (!timer_set) { + intr_test_set_timer(); + timer_set = 1; + } + intr_test_register_irq(irq, pcibr_soft, slot); + request_irq(irq, intr_test_handle_intr,0,NULL, NULL); + } +#endif +} + +/* + * linux_bus_cvlink() Creates a link between the Linux PCI Bus number + * to the actual hardware component that it represents: + * /dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci + * + * The bus vertex, when called to devfs_generate_path() returns: + * hw/module/001c01/slab/0/Ibrick/xtalk/15/pci + * hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/0 + * hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/1 + */ +void +linux_bus_cvlink(void) +{ + char name[8]; + int index; + + for (index=0; index < MAX_PCI_XWIDGET; index++) { + if (!busnum_to_pcibr_vhdl[index]) + continue; + + sprintf(name, "%x", index); + (void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], + name); + } +} + +/* + * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. + * + * Linux PCI Bus numbers are assigned from lowest module_id numbers + * (rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to + * HUB_WIDGET_ID_MIN: + * widgetnum 15 gets lower Bus Number than widgetnum 14 etc. + * + * Given 2 modules 001c01 and 001c02 we get the following mappings: + * 001c01, widgetnum 15 = Bus number 0 + * 001c01, widgetnum 14 = Bus number 1 + * 001c02, widgetnum 15 = Bus number 3 + * 001c02, widgetnum 14 = Bus number 4 + * etc. + * + * The rational for starting Bus Number 0 with Widget number 15 is because + * the system boot disks are always connected via Widget 15 Slot 0 of the + * I-brick. Linux creates /dev/sd* devices(naming) strating from Bus Number 0 + * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest + * module id(Master Cnode) of the system. + * + */ +static int +pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid) +{ + + vertex_hdl_t master_node_vertex = NULL; + vertex_hdl_t xwidget = NULL; + vertex_hdl_t pci_bus = NULL; + hubinfo_t hubinfo = NULL; + xwidgetnum_t widgetnum; + char pathname[128]; + graph_error_t rv; + int bus; + int basebus_num; + extern void ioconfig_get_busnum(char *, int *); + + int bus_number; + + /* + * Loop throught this vertex and get the Xwidgets .. + */ + + + /* PCI devices */ + + for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) { + sprintf(pathname, "%d", widgetnum); + xwidget = NULL; + + /* + * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget + * /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device + */ + rv = hwgraph_traverse(xtalk, pathname, &xwidget); + if ( (rv != GRAPH_SUCCESS) ) { + if (!xwidget) { + continue; + } + } + + sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); + pci_bus = NULL; + if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) + if (!pci_bus) { + continue; +} + + /* + * Assign the correct bus number and also the nasid of this + * pci Xwidget. + * + * Should not be any race here ... + */ + num_bridges++; + busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus; + + /* + * Get the master node and from there get the NASID. + */ + master_node_vertex = device_master_get(xwidget); + if (!master_node_vertex) { + printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget); + } + + hubinfo_get(master_node_vertex, &hubinfo); + if (!hubinfo) { + printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex); + return(1); + } else { + busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; + } + + /* + * Pre assign DMA maps needed for 32 Bits Page Map DMA. + */ + busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc( + sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); + if (!busnum_to_atedmamaps[num_bridges - 1]) + printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); + + memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, + sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); + + } + + /* + * PCIX devices + * We number busses differently for PCI-X devices. + * We start from Lowest Widget on up .. + */ + + (void) ioconfig_get_busnum((char *)io_moduleid, &basebus_num); + + for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { + + /* Do both buses */ + for ( bus = 0; bus < 2; bus++ ) { + sprintf(pathname, "%d", widgetnum); + xwidget = NULL; + + /* + * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget + * /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus + * /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device + */ + rv = hwgraph_traverse(xtalk, pathname, &xwidget); + if ( (rv != GRAPH_SUCCESS) ) { + if (!xwidget) { + continue; + } + } + + if ( bus == 0 ) + sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum); + else + sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum); + pci_bus = NULL; + if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) + if (!pci_bus) { + continue; + } + + /* + * Assign the correct bus number and also the nasid of this + * pci Xwidget. + * + * Should not be any race here ... + */ + bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum); +#ifdef DEBUG + printk("bus_number %d basebus_num %d bus %d io %d\n", + bus_number, basebus_num, bus, + io_brick_map_widget(MODULE_PXBRICK, widgetnum)); +#endif + busnum_to_pcibr_vhdl[bus_number] = pci_bus; + + /* + * Pre assign DMA maps needed for 32 Bits Page Map DMA. + */ + busnum_to_atedmamaps[bus_number] = (void *) kmalloc( + sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); + if (!busnum_to_atedmamaps[bus_number]) + printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); + + memset(busnum_to_atedmamaps[bus_number], 0x0, + sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); + } + } + + return(0); +} + +/* + * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure + * initialization has completed to set up the mappings between Xbridge + * and logical pci bus numbers. We also set up the NASID for each of these + * xbridges. + * + * Must be called before pci_init() is invoked. + */ +int +pci_bus_to_hcl_cvlink(void) +{ + + vertex_hdl_t devfs_hdl = NULL; + vertex_hdl_t xtalk = NULL; + int rv = 0; + char name[256]; + char tmp_name[256]; + int i, ii, j; + char *brick_name; + extern void ioconfig_bus_new_entries(void); + + /* + * Figure out which IO Brick is connected to the Compute Bricks. + */ + for (i = 0; i < nummodules; i++) { + extern int iomoduleid_get(nasid_t); + moduleid_t iobrick_id; + nasid_t nasid = -1; + int nodecnt; + int n = 0; + + nodecnt = modules[i]->nodecnt; + for ( n = 0; n < nodecnt; n++ ) { + nasid = cnodeid_to_nasid(modules[i]->nodes[n]); + iobrick_id = iomoduleid_get(nasid); + if ((int)iobrick_id > 0) { /* Valid module id */ + char name[12]; + memset(name, 0, 12); + format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF); + } + } + } + + devfs_hdl = hwgraph_path_to_vertex("hw/module"); + for (i = 0; i < nummodules ; i++) { + for ( j = 0; j < 3; j++ ) { + if ( j == 0 ) + brick_name = EDGE_LBL_PBRICK; + else if ( j == 1 ) + brick_name = EDGE_LBL_PXBRICK; + else + brick_name = EDGE_LBL_IXBRICK; + + for ( ii = 0; ii < 2 ; ii++ ) { + memset(name, 0, 256); + memset(tmp_name, 0, 256); + format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF); + sprintf(tmp_name, "/slab/%d/%s/xtalk", geo_slab(modules[i]->geoid[ii]), brick_name); + strcat(name, tmp_name); + xtalk = NULL; + rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); + if ( rv == 0 ) + pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid)); + } + } + } + + /* + * Create the Linux PCI bus number vertex link. + */ + (void)linux_bus_cvlink(); + (void)ioconfig_bus_new_entries(); + + return(0); +} diff -urN linux-2.4.21/arch/ia64/sn/io/machvec/pci_dma.c linux-2.4.22/arch/ia64/sn/io/machvec/pci_dma.c --- linux-2.4.21/arch/ia64/sn/io/machvec/pci_dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/machvec/pci_dma.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,584 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000,2002-2003 Silicon Graphics, Inc. All rights reserved. + * + * Routines for PCI DMA mapping. See Documentation/DMA-mapping.txt for + * a description of how these routines should be used. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * For ATE allocations + */ +pciio_dmamap_t get_free_pciio_dmamap(vertex_hdl_t); +void free_pciio_dmamap(pcibr_dmamap_t); +static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char); +void sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction); + +/* + * Toplogy stuff + */ +extern vertex_hdl_t busnum_to_pcibr_vhdl[]; +extern nasid_t busnum_to_nid[]; +extern void * busnum_to_atedmamaps[]; + +/** + * get_free_pciio_dmamap - find and allocate an ATE + * @pci_bus: PCI bus to get an entry for + * + * Finds and allocates an ATE on the PCI bus specified + * by @pci_bus. + */ +pciio_dmamap_t +get_free_pciio_dmamap(vertex_hdl_t pci_bus) +{ + int i; + struct sn_dma_maps_s *sn_dma_map = NULL; + + /* + * Darn, we need to get the maps allocated for this bus. + */ + for (i = 0; i < MAX_PCI_XWIDGET; i++) { + if (busnum_to_pcibr_vhdl[i] == pci_bus) { + sn_dma_map = busnum_to_atedmamaps[i]; + } + } + + /* + * Now get a free dmamap entry from this list. + */ + for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) { + if (!sn_dma_map->dma_addr) { + sn_dma_map->dma_addr = -1; + return( (pciio_dmamap_t) sn_dma_map ); + } + } + + return NULL; +} + +/** + * free_pciio_dmamap - free an ATE + * @dma_map: ATE to free + * + * Frees the ATE specified by @dma_map. + */ +void +free_pciio_dmamap(pcibr_dmamap_t dma_map) +{ + struct sn_dma_maps_s *sn_dma_map; + + sn_dma_map = (struct sn_dma_maps_s *) dma_map; + sn_dma_map->dma_addr = 0; +} + +/** + * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum + * @dma_addr: DMA address to look for + * @busnum: PCI bus to look on + * + * Finds the ATE associated with @dma_addr and @busnum. + */ +static struct sn_dma_maps_s * +find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum) +{ + + struct sn_dma_maps_s *sn_dma_map = NULL; + int i; + + sn_dma_map = busnum_to_atedmamaps[busnum]; + + for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) { + if (sn_dma_map->dma_addr == dma_addr) { + return sn_dma_map; + } + } + + return NULL; +} + +/** + * sn_pci_alloc_consistent - allocate memory for coherent DMA + * @hwdev: device to allocate for + * @size: size of the region + * @dma_handle: DMA (bus) address + * + * pci_alloc_consistent() returns a pointer to a memory region suitable for + * coherent DMA traffic to/from a PCI device. On SN platforms, this means + * that @dma_handle will have the %PCIIO_DMA_CMD flag set. + * + * This interface is usually used for "command" streams (e.g. the command + * queue for a SCSI controller). See Documentation/DMA-mapping.txt for + * more information. Note that this routine will always put a 32 bit + * DMA address into @dma_handle. This is because most devices + * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_ + * DMAs, and unfortunately this interface has to cater to the LCD. Oh well. + * + * Also known as platform_pci_alloc_consistent() by the IA64 machvec code. + */ +void * +sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) +{ + void *cpuaddr; + vertex_hdl_t vhdl; + struct sn_device_sysdata *device_sysdata; + unsigned long phys_addr; + pciio_dmamap_t dma_map = 0; + struct sn_dma_maps_s *sn_dma_map; + + *dma_handle = 0; + + if (hwdev->dma_mask < 0xffffffffUL) + return NULL; + + /* + * Get hwgraph vertex for the device + */ + device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata; + vhdl = device_sysdata->vhdl; + + /* + * Allocate the memory. FIXME: if we're allocating for + * two devices on the same bus, we should at least try to + * allocate memory in the same 2 GB window to avoid using + * ATEs for the translation. See the comment above about the + * 32 bit requirement for this function. + */ + if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)))) + return NULL; + + /* physical addr. of the memory we just got */ + phys_addr = __pa(cpuaddr); + + /* + * This will try to use a Direct Map register to do the + * 32 bit DMA mapping, but it may not succeed if another + * device on the same bus is already mapped with different + * attributes or to a different memory region. + */ + *dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_CMD); + + /* + * If this device is in PCI-X mode, the system would have + * automatically allocated a 64Bits DMA Address. Error out if the + * device cannot support DAC. + */ + if (*dma_handle > hwdev->consistent_dma_mask) { + free_pages((unsigned long) cpuaddr, get_order(size)); + return NULL; + } + + /* + * It is a 32 bit card and we cannot do direct mapping, + * so we try to use an ATE. + */ + if (!(*dma_handle)) { + dma_map = pciio_dmamap_alloc(vhdl, NULL, size, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_CMD); + if (!dma_map) { + printk(KERN_ERR "sn_pci_alloc_consistent: Unable to " + "allocate anymore 32 bit page map entries.\n"); + return 0; + } + *dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr, + size); + sn_dma_map = (struct sn_dma_maps_s *)dma_map; + sn_dma_map->dma_addr = *dma_handle; + } + + return cpuaddr; +} + +/** + * sn_pci_free_consistent - free memory associated with coherent DMAable region + * @hwdev: device to free for + * @size: size to free + * @vaddr: kernel virtual address to free + * @dma_handle: DMA address associated with this region + * + * Frees the memory allocated by pci_alloc_consistent(). Also known + * as platform_pci_free_consistent() by the IA64 machvec code. + */ +void +sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) +{ + struct sn_dma_maps_s *sn_dma_map = NULL; + + /* + * Get the sn_dma_map entry. + */ + if (IS_PCI32_MAPPED(dma_handle)) + sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number); + + /* + * and free it if necessary... + */ + if (sn_dma_map) { + pciio_dmamap_done((pciio_dmamap_t)sn_dma_map); + pciio_dmamap_free((pciio_dmamap_t)sn_dma_map); + sn_dma_map->dma_addr = (dma_addr_t)NULL; + } + free_pages((unsigned long) vaddr, get_order(size)); +} + +/** + * sn_pci_map_sg - map a scatter-gather list for DMA + * @hwdev: device to map for + * @sg: scatterlist to map + * @nents: number of entries + * @direction: direction of the DMA transaction + * + * Maps each entry of @sg for DMA. Also known as platform_pci_map_sg by the + * IA64 machvec code. + */ +int +sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + + int i; + vertex_hdl_t vhdl; + unsigned long phys_addr; + struct sn_device_sysdata *device_sysdata; + pciio_dmamap_t dma_map; + struct sn_dma_maps_s *sn_dma_map; + struct scatterlist *saved_sg = sg; + + /* can't go anywhere w/o a direction in life */ + if (direction == PCI_DMA_NONE) + BUG(); + + /* + * Get the hwgraph vertex for the device + */ + device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata; + vhdl = device_sysdata->vhdl; + + /* + * Setup a DMA address for each entry in the + * scatterlist. + */ + for (i = 0; i < nents; i++, sg++) { + phys_addr = __pa(sg->address ? sg->address : + page_address(sg->page) + sg->offset); + + /* + * Handle the most common case: 64 bit cards. This + * call should always succeed. + */ + if (IS_PCIA64(hwdev)) { + sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr, + sg->length, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_DATA | + PCIIO_DMA_A64); + sg->dma_length = sg->length; + continue; + } + + /* + * Handle 32-63 bit cards via direct mapping + */ + if (IS_PCI32G(hwdev)) { + sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr, + sg->length, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_DATA); + sg->dma_length = sg->length; + /* + * See if we got a direct map entry + */ + if (sg->dma_address) { + continue; + } + + } + + /* + * It is a 32 bit card and we cannot do direct mapping, + * so we use an ATE. + */ + dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_DATA); + if (!dma_map) { + printk(KERN_ERR "sn_pci_map_sg: Unable to allocate " + "anymore 32 bit page map entries.\n"); + /* + * We will need to free all previously allocated entries. + */ + if (i > 0) { + sn_pci_unmap_sg(hwdev, saved_sg, i, direction); + } + return (0); + } + + sg->dma_address = pciio_dmamap_addr(dma_map, phys_addr, sg->length); + sg->dma_length = sg->length; + sn_dma_map = (struct sn_dma_maps_s *)dma_map; + sn_dma_map->dma_addr = sg->dma_address; + } + + return nents; + +} + +/** + * sn_pci_unmap_sg - unmap a scatter-gather list + * @hwdev: device to unmap + * @sg: scatterlist to unmap + * @nents: number of scatterlist entries + * @direction: DMA direction + * + * Unmap a set of streaming mode DMA translations. Again, cpu read rules + * concerning calls here are the same as for pci_unmap_single() below. Also + * known as sn_pci_unmap_sg() by the IA64 machvec code. + */ +void +sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + int i; + struct sn_dma_maps_s *sn_dma_map; + + /* can't go anywhere w/o a direction in life */ + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nents; i++, sg++){ + + if (IS_PCI32_MAPPED(sg->dma_address)) { + sn_dma_map = NULL; + sn_dma_map = find_sn_dma_map(sg->dma_address, hwdev->bus->number); + if (sn_dma_map) { + pciio_dmamap_done((pciio_dmamap_t)sn_dma_map); + pciio_dmamap_free((pciio_dmamap_t)sn_dma_map); + sn_dma_map->dma_addr = (dma_addr_t)NULL; + } + } + + sg->dma_address = (dma_addr_t)NULL; + sg->dma_length = 0; + } +} + +/** + * sn_pci_map_single - map a single region for DMA + * @hwdev: device to map for + * @ptr: kernel virtual address of the region to map + * @size: size of the region + * @direction: DMA direction + * + * Map the region pointed to by @ptr for DMA and return the + * DMA address. Also known as platform_pci_map_single() by + * the IA64 machvec code. + * + * We map this to the one step pciio_dmamap_trans interface rather than + * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have + * no way of saving the dmamap handle from the alloc to later free + * (which is pretty much unacceptable). + * + * TODO: simplify our interface; + * get rid of dev_desc and vhdl (seems redundant given a pci_dev); + * figure out how to save dmamap handle so can use two step. + */ +dma_addr_t +sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + vertex_hdl_t vhdl; + dma_addr_t dma_addr; + unsigned long phys_addr; + struct sn_device_sysdata *device_sysdata; + pciio_dmamap_t dma_map = NULL; + struct sn_dma_maps_s *sn_dma_map; + + if (direction == PCI_DMA_NONE) + BUG(); + + /* SN cannot support DMA addresses smaller than 32 bits. */ + if (IS_PCI32L(hwdev)) + return 0; + + /* + * find vertex for the device + */ + device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata; + vhdl = device_sysdata->vhdl; + + /* + * Call our dmamap interface + */ + dma_addr = 0; + phys_addr = __pa(ptr); + + if (IS_PCIA64(hwdev)) { + /* This device supports 64 bit DMA addresses. */ + dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_DATA | + PCIIO_DMA_A64); + return dma_addr; + } + + /* + * Devices that support 32 bit to 63 bit DMA addresses get + * 32 bit DMA addresses. + * + * First try to get a 32 bit direct map register. + */ + if (IS_PCI32G(hwdev)) { + dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_DATA); + if (dma_addr) + return dma_addr; + } + + /* + * It's a 32 bit card and we cannot do direct mapping so + * let's use the PMU instead. + */ + dma_map = NULL; + dma_map = pciio_dmamap_alloc(vhdl, NULL, size, + ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | + PCIIO_DMA_DATA); + + if (!dma_map) { + printk(KERN_ERR "pci_map_single: Unable to allocate anymore " + "32 bit page map entries.\n"); + return 0; + } + + dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size); + sn_dma_map = (struct sn_dma_maps_s *)dma_map; + sn_dma_map->dma_addr = dma_addr; + + return ((dma_addr_t)dma_addr); +} + +/** + * sn_pci_unmap_single - unmap a region used for DMA + * @hwdev: device to unmap + * @dma_addr: DMA address to unmap + * @size: size of region + * @direction: DMA direction + * + * Unmaps the region pointed to by @dma_addr. Also known as + * platform_pci_unmap_single() by the IA64 machvec code. + */ +void +sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) +{ + struct sn_dma_maps_s *sn_dma_map = NULL; + + if (direction == PCI_DMA_NONE) + BUG(); + + /* + * Get the sn_dma_map entry. + */ + if (IS_PCI32_MAPPED(dma_addr)) + sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number); + + /* + * and free it if necessary... + */ + if (sn_dma_map) { + pciio_dmamap_done((pciio_dmamap_t)sn_dma_map); + pciio_dmamap_free((pciio_dmamap_t)sn_dma_map); + sn_dma_map->dma_addr = (dma_addr_t)NULL; + } +} + +/** + * sn_pci_dma_sync_single - make sure all DMAs have completed + * @hwdev: device to sync + * @dma_handle: DMA address to sync + * @size: size of region + * @direction: DMA direction + * + * This routine is supposed to sync the DMA region specified + * by @dma_handle into the 'coherence domain'. We do not need to do + * anything on our platform. + */ +void +sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) +{ + return; + +} + +/** + * sn_pci_dma_sync_sg - make sure all DMAs have completed + * @hwdev: device to sync + * @sg: scatterlist to sync + * @nents: number of entries in the scatterlist + * @direction: DMA direction + * + * This routine is supposed to sync the DMA regions specified + * by @sg into the 'coherence domain'. We do not need to do anything + * on our platform. + */ +void +sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + return; + +} + +/** + * sn_dma_supported - test a DMA mask + * @hwdev: device to test + * @mask: DMA mask to test + * + * Return whether the given PCI device DMA address mask can be supported + * properly. For example, if your device can only drive the low 24-bits + * during PCI bus mastering, then you would pass 0x00ffffff as the mask to + * this function. Of course, SN only supports devices that have 32 or more + * address bits when using the PMU. We could theoretically support <32 bit + * cards using direct mapping, but we'll worry about that later--on the off + * chance that someone actually wants to use such a card. + */ +int +sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask) +{ + if (mask < 0xffffffff) + return 0; + return 1; +} + +EXPORT_SYMBOL(sn_pci_unmap_single); +EXPORT_SYMBOL(sn_pci_map_single); +EXPORT_SYMBOL(sn_pci_dma_sync_single); +EXPORT_SYMBOL(sn_pci_map_sg); +EXPORT_SYMBOL(sn_pci_unmap_sg); +EXPORT_SYMBOL(sn_pci_alloc_consistent); +EXPORT_SYMBOL(sn_pci_free_consistent); +EXPORT_SYMBOL(sn_pci_dma_supported); + diff -urN linux-2.4.21/arch/ia64/sn/io/ml_SN_init.c linux-2.4.22/arch/ia64/sn/io/ml_SN_init.c --- linux-2.4.21/arch/ia64/sn/io/ml_SN_init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/ml_SN_init.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,235 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int numcpus; -extern char arg_maxnodes[]; -extern cpuid_t master_procid; -#if defined(CONFIG_IA64_SGI_SN1) -extern synergy_da_t *Synergy_da_indr[]; -#endif - -extern int hasmetarouter; - -int maxcpus; -cpumask_t boot_cpumask; -hubreg_t region_mask = 0; - - -extern xwidgetnum_t hub_widget_id(nasid_t); - -extern int valid_icache_reasons; /* Reasons to flush the icache */ -extern int valid_dcache_reasons; /* Reasons to flush the dcache */ -extern u_char miniroot; -extern volatile int need_utlbmiss_patch; -extern void iograph_early_init(void); - -nasid_t master_nasid = INVALID_NASID; - - -/* - * mlreset(int slave) - * very early machine reset - at this point NO interrupts have been - * enabled; nor is memory, tlb, p0, etc setup. - * - * slave is zero when mlreset is called for the master processor and - * is nonzero thereafter. - */ - - -void -mlreset(int slave) -{ - if (!slave) { - /* - * We are the master cpu and node. - */ - master_nasid = get_nasid(); - set_master_bridge_base(); - - /* We're the master processor */ - master_procid = smp_processor_id(); - master_nasid = cpuid_to_nasid(master_procid); - - /* - * master_nasid we get back better be same as one from - * get_nasid() - */ - ASSERT_ALWAYS(master_nasid == get_nasid()); - - /* early initialization of iograph */ - iograph_early_init(); - - /* Initialize Hub Pseudodriver Management */ - hubdev_init(); - - } else { /* slave != 0 */ - /* - * This code is performed ONLY by slave processors. - */ - - } -} - - -/* XXX - Move the meat of this to intr.c ? */ -/* - * Set up the platform-dependent fields in the nodepda. - */ -void init_platform_nodepda(nodepda_t *npda, cnodeid_t node) -{ - hubinfo_t hubinfo; -#ifdef CONFIG_IA64_SGI_SN1 - int sn; -#endif - - extern void router_map_init(nodepda_t *); - extern void router_queue_init(nodepda_t *,cnodeid_t); - extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int); - - /* Allocate per-node platform-dependent data */ - hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s)); - - npda->pdinfo = (void *)hubinfo; - hubinfo->h_nodepda = npda; - hubinfo->h_cnodeid = node; - hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node); - - spin_lock_init(&hubinfo->h_crblock); - - hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid); - npda->xbow_peer = INVALID_NASID; - - /* - * Initialize the linked list of - * router info pointers to the dependent routers - */ - npda->npda_rip_first = NULL; - - /* - * npda_rip_last always points to the place - * where the next element is to be inserted - * into the list - */ - npda->npda_rip_last = &npda->npda_rip_first; - npda->module_id = INVALID_MODULE; - -#ifdef CONFIG_IA64_SGI_SN1 - /* - * Initialize the interrupts. - * On sn2, this is done at pci init time, - * because sn2 needs the cpus checked in - * when it initializes interrupts. This is - * so we don't see all the nodes as headless. - */ - for (sn=0; snxbow_sema); /* init it locked? */ - -#ifdef LATER - - /* Setup the (module,slot) --> nic mapping for all the routers - * in the system. This is useful during error handling when - * there is no shared memory. - */ - router_map_init(npda); - - /* Allocate memory for the per-node router traversal queue */ - router_queue_init(npda,node); - npda->sbe_info = alloc_bootmem_node(NODE_DATA(node), sizeof (sbe_info_t)); - ASSERT(npda->sbe_info); - -#endif /* LATER */ -} - -/* XXX - Move the interrupt stuff to intr.c ? */ -/* - * Set up the platform-dependent fields in the processor pda. - * Must be done _after_ init_platform_nodepda(). - * If we need a lock here, something else is wrong! - */ -void init_platform_pda(cpuid_t cpu) -{ -#if defined(CONFIG_IA64_SGI_SN1) - hub_intmasks_t *intmasks; - int i, subnode; - cnodeid_t cnode; - synergy_da_t *sda; - int which_synergy; - - - cnode = cpuid_to_cnodeid(cpu); - which_synergy = cpuid_to_synergy(cpu); - - sda = Synergy_da_indr[(cnode * 2) + which_synergy]; - intmasks = &sda->s_intmasks; - - /* Clear INT_PEND0 masks. */ - for (i = 0; i < N_INTPEND0_MASKS; i++) - intmasks->intpend0_masks[i] = 0; - - /* Set up pointer to the vector block in the nodepda. */ - /* (Cant use SUBNODEPDA - not working yet) */ - subnode = cpuid_to_subnode(cpu); - intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0; - intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1; - if (intmasks->dispatch0 != &SUBNODEPDA(cnode, subnode)->intr_dispatch0 || - intmasks->dispatch1 != &SUBNODEPDA(cnode, subnode)->intr_dispatch1) - panic("xxx"); - intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0; - intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1; - - /* Clear INT_PEND1 masks. */ - for (i = 0; i < N_INTPEND1_MASKS; i++) - intmasks->intpend1_masks[i] = 0; -#endif /* CONFIG_IA64_SGI_SN1 */ -} - -void -update_node_information(cnodeid_t cnodeid) -{ - nodepda_t *npda = NODEPDA(cnodeid); - nodepda_router_info_t *npda_rip; - - /* Go through the list of router info - * structures and copy some frequently - * accessed info from the info hanging - * off the corresponding router vertices - */ - npda_rip = npda->npda_rip_first; - while(npda_rip) { - if (npda_rip->router_infop) { - npda_rip->router_portmask = - npda_rip->router_infop->ri_portmask; - npda_rip->router_slot = - npda_rip->router_infop->ri_slotnum; - } else { - /* No router, no ports. */ - npda_rip->router_portmask = 0; - } - npda_rip = npda_rip->router_next; - } -} diff -urN linux-2.4.21/arch/ia64/sn/io/ml_iograph.c linux-2.4.22/arch/ia64/sn/io/ml_iograph.c --- linux-2.4.21/arch/ia64/sn/io/ml_iograph.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/ml_iograph.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1570 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define IOGRAPH_DEBUG */ -#ifdef IOGRAPH_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* IOGRAPH_DEBUG */ - -/* #define PROBE_TEST */ - -/* At most 2 hubs can be connected to an xswitch */ -#define NUM_XSWITCH_VOLUNTEER 2 - -/* - * Track which hubs have volunteered to manage devices hanging off of - * a Crosstalk Switch (e.g. xbow). This structure is allocated, - * initialized, and hung off the xswitch vertex early on when the - * xswitch vertex is created. - */ -typedef struct xswitch_vol_s { - mutex_t xswitch_volunteer_mutex; - int xswitch_volunteer_count; - devfs_handle_t xswitch_volunteer[NUM_XSWITCH_VOLUNTEER]; -} *xswitch_vol_t; - -void -xswitch_vertex_init(devfs_handle_t xswitch) -{ - xswitch_vol_t xvolinfo; - int rc; - - xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL); - mutex_init(&xvolinfo->xswitch_volunteer_mutex); - xvolinfo->xswitch_volunteer_count = 0; - rc = hwgraph_info_add_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t)xvolinfo); - ASSERT(rc == GRAPH_SUCCESS); rc = rc; -} - - -/* - * When assignment of hubs to widgets is complete, we no longer need the - * xswitch volunteer structure hanging around. Destroy it. - */ -static void -xswitch_volunteer_delete(devfs_handle_t xswitch) -{ - xswitch_vol_t xvolinfo; - int rc; - - rc = hwgraph_info_remove_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t *)&xvolinfo); -#ifdef LATER - ASSERT(rc == GRAPH_SUCCESS); rc = rc; -#endif - - kfree(xvolinfo); -} -/* - * A Crosstalk master volunteers to manage xwidgets on the specified xswitch. - */ -/* ARGSUSED */ -static void -volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master) -{ - xswitch_vol_t xvolinfo = NULL; - - (void)hwgraph_info_get_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t *)&xvolinfo); - if (xvolinfo == NULL) { -#ifdef LATER - if (!is_headless_node_vertex(master)) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "volunteer for widgets: vertex %v has no info label", - xswitch); -#else - printk(KERN_WARNING "volunteer for widgets: vertex 0x%x has no info label", - xswitch); -#endif - } -#endif /* LATER */ - return; - } - - mutex_lock(&xvolinfo->xswitch_volunteer_mutex); - ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER); - xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master; - xvolinfo->xswitch_volunteer_count++; - mutex_unlock(&xvolinfo->xswitch_volunteer_mutex); -} - -extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum); - -/* - * Assign all the xwidgets hanging off the specified xswitch to the - * Crosstalk masters that have volunteered for xswitch duty. - */ -/* ARGSUSED */ -static void -assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv) -{ - int curr_volunteer, num_volunteer; - xwidgetnum_t widgetnum; - xswitch_info_t xswitch_info; - xswitch_vol_t xvolinfo = NULL; - nasid_t nasid; - hubinfo_t hubinfo; - - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - - xswitch_info = xswitch_info_get(xswitch); - ASSERT(xswitch_info != NULL); - - (void)hwgraph_info_get_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t *)&xvolinfo); - if (xvolinfo == NULL) { -#ifdef LATER - if (!is_headless_node_vertex(hubv)) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "assign_widgets_to_volunteers:vertex %v has " - " no info label", - xswitch); -#else - printk(KERN_WARNING "assign_widgets_to_volunteers:vertex 0x%x has " - " no info label", - xswitch); -#endif - } -#endif /* LATER */ - return; - } - - num_volunteer = xvolinfo->xswitch_volunteer_count; - ASSERT(num_volunteer > 0); - curr_volunteer = 0; - - /* Assign master hub for xswitch itself. */ - if (HUB_WIDGET_ID_MIN > 0) { - hubv = xvolinfo->xswitch_volunteer[0]; - xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv); - } - - /* - * TBD: Use administrative information to alter assignment of - * widgets to hubs. - */ - for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { - - /* - * Ignore disabled/empty ports. - */ - if (!xbow_port_io_enabled(nasid, widgetnum)) - continue; - - /* - * If this is the master IO board, assign it to the same - * hub that owned it in the prom. - */ - if (is_master_nasid_widget(nasid, widgetnum)) { - int i; - - for (i=0; ixswitch_volunteer[i]; - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - if (nasid == get_console_nasid()) - goto do_assignment; - } -#ifdef LATER - PRINT_PANIC("Nasid == %d, console nasid == %d", - nasid, get_console_nasid()); -#endif - } - - - /* - * Do a round-robin assignment among the volunteer nodes. - */ - hubv = xvolinfo->xswitch_volunteer[curr_volunteer]; - curr_volunteer = (curr_volunteer + 1) % num_volunteer; - /* fall through */ - -do_assignment: - /* - * At this point, we want to make hubv the master of widgetnum. - */ - xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv); - } - - xswitch_volunteer_delete(xswitch); -} - -/* - * Early iograph initialization. Called by master CPU in mlreset(). - * Useful for including iograph.o in kernel.o. - */ -void -iograph_early_init(void) -{ -/* - * Need new way to get this information .. - */ - cnodeid_t cnode; - nasid_t nasid; - lboard_t *board; - - /* - * Init. the board-to-hwgraph link early, so FRU analyzer - * doesn't trip on leftover values if we panic early on. - */ - for(cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - board = (lboard_t *)KL_CONFIG_INFO(nasid); - DBG("iograph_early_init: Found board 0x%p\n", board); - - /* Check out all the board info stored on a node */ - while(board) { - board->brd_graph_link = GRAPH_VERTEX_NONE; - board = KLCF_NEXT(board); - DBG("iograph_early_init: Found board 0x%p\n", board); - - - } - } - - hubio_init(); -} - -#ifdef LINUX_KERNEL_THREADS -static struct semaphore io_init_sema; -#endif - -/* - * Let boot processor know that we're done initializing our node's IO - * and then exit. - */ -/* ARGSUSED */ -static void -io_init_done(cnodeid_t cnodeid,cpu_cookie_t c) -{ - /* Let boot processor know that we're done. */ -#ifdef LINUX_KERNEL_THREADS - up(&io_init_sema); -#endif -#ifdef LATER - /* This is for the setnoderun done when the io_init thread - * started - */ - restorenoderun(c); - sthread_exit(); -#endif -} - -/* - * Probe to see if this hub's xtalk link is active. If so, - * return the Crosstalk Identification of the widget that we talk to. - * This is called before any of the Crosstalk infrastructure for - * this hub is set up. It's usually called on the node that we're - * probing, but not always. - * - * TBD: Prom code should actually do this work, and pass through - * hwid for our use. - */ -static void -early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid) -{ - hubreg_t llp_csr_reg; - nasid_t nasid; - hubinfo_t hubinfo; - - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - - llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); - /* - * If link is up, read the widget's part number. - * A direct connect widget must respond to widgetnum=0. - */ - if (llp_csr_reg & IIO_LLP_CSR_IS_UP) { - /* TBD: Put hub into "indirect" mode */ - /* - * We're able to read from a widget because our hub's - * WIDGET_ID was set up earlier. - */ - widgetreg_t widget_id = *(volatile widgetreg_t *) - (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); - - DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id, - (volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) ); - - hwid->part_num = XWIDGET_PART_NUM(widget_id); - hwid->rev_num = XWIDGET_REV_NUM(widget_id); - hwid->mfg_num = XWIDGET_MFG_NUM(widget_id); - - /* TBD: link reset */ - } else { - - hwid->part_num = XWIDGET_PART_NUM_NONE; - hwid->rev_num = XWIDGET_REV_NUM_NONE; - hwid->mfg_num = XWIDGET_MFG_NUM_NONE; - } - -} - -/* Add inventory information to the widget vertex - * Right now (module,slot,revision) is being - * added as inventory information. - */ -static void -xwidget_inventory_add(devfs_handle_t widgetv, - lboard_t *board, - struct xwidget_hwid_s hwid) -{ - if (!board) - return; - /* Donot add inventory information for the baseio - * on a speedo with an xbox. It has already been - * taken care of in SN00_vmc. - * Speedo with xbox's baseio comes in at slot io1 (widget 9) - */ - device_inventory_add(widgetv,INV_IOBD,board->brd_type, - board->brd_module, - SLOTNUM_GETSLOT(board->brd_slot), - hwid.rev_num); -} - -/* - * io_xswitch_widget_init - * - */ - -/* defined in include/linux/ctype.h */ -/* #define toupper(c) (islower(c) ? (c) - 'a' + 'A' : (c)) */ - -void -io_xswitch_widget_init(devfs_handle_t xswitchv, - devfs_handle_t hubv, - xwidgetnum_t widgetnum, - async_attach_t aa) -{ - xswitch_info_t xswitch_info; - xwidgetnum_t hub_widgetid; - devfs_handle_t widgetv; - cnodeid_t cnode; - widgetreg_t widget_id; - nasid_t nasid, peer_nasid; - struct xwidget_hwid_s hwid; - hubinfo_t hubinfo; - /*REFERENCED*/ - int rc; - char slotname[SLOTNUM_MAXLENGTH]; - char pathname[128]; - char new_name[64]; - moduleid_t module; - slotid_t slot; - lboard_t *board = NULL; - char buffer[16]; - slotid_t get_widget_slotnum(int xbow, int widget); - - DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum); - /* - * Verify that xswitchv is indeed an attached xswitch. - */ - xswitch_info = xswitch_info_get(xswitchv); - ASSERT(xswitch_info != NULL); - - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - cnode = NASID_TO_COMPACT_NODEID(nasid); - hub_widgetid = hubinfo->h_widgetid; - - - /* Who's the other guy on out crossbow (if anyone) */ - peer_nasid = NODEPDA(cnode)->xbow_peer; - if (peer_nasid == INVALID_NASID) - /* If I don't have a peer, use myself. */ - peer_nasid = nasid; - - - /* Check my xbow structure and my peer's */ - if (!xbow_port_io_enabled(nasid, widgetnum) && - !xbow_port_io_enabled(peer_nasid, widgetnum)) { - return; - } - - if (xswitch_info_link_ok(xswitch_info, widgetnum)) { - char name[4]; - /* - * If the current hub is not supposed to be the master - * for this widgetnum, then skip this widget. - */ - if (xswitch_info_master_assignment_get(xswitch_info, - widgetnum) != hubv) { - return; - } - - module = NODEPDA(cnode)->module_id; -#ifdef XBRIDGE_REGS_SIM - /* hardwire for now...could do this with something like: - * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl); - * xbow_t xbow = soft->base; - * xbowreg_t xwidget_id = xbow->xb_wid_id; - * but I don't feel like figuring out vhdl right now.. - * and I know for a fact the answer is 0x2d000049 - */ - DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); - DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049)); - if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) { -#else - if (nasid_has_xbridge(nasid)) { -#endif /* XBRIDGE_REGS_SIM */ - board = find_lboard_module_class( - (lboard_t *)KL_CONFIG_INFO(nasid), - module, - KLTYPE_IOBRICK); - -DBG("io_xswitch_widget_init: Board 0x%p\n", board); -{ - lboard_t dummy; - - - if (board) { - DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type); - } else { - DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n"); - board = &dummy; - } - -} - - /* - * Make sure we really want to say xbrick, pbrick, - * etc. rather than XIO, graphics, etc. - */ - -#ifdef SUPPORT_PRINTING_M_FORMAT - sprintf(pathname, EDGE_LBL_MODULE "/%M/" - "%cbrick" "/%s/%d", - NODEPDA(cnode)->module_id, - -#else - memset(buffer, 0, 16); - format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); - sprintf(pathname, EDGE_LBL_MODULE "/%s/" - "%cbrick" "/%s/%d", - buffer, -#endif - - (board->brd_type == KLTYPE_IBRICK) ? 'I' : - (board->brd_type == KLTYPE_PBRICK) ? 'P' : - (board->brd_type == KLTYPE_XBRICK) ? 'X' : '?', - EDGE_LBL_XTALK, widgetnum); - } - - DBG("io_xswitch_widget_init: path= %s\n", pathname); - rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); - - ASSERT(rc == GRAPH_SUCCESS); - - /* This is needed to let the user programs to map the - * module,slot numbers to the corresponding widget numbers - * on the crossbow. - */ - rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); - - /* If we are looking at the global master io6 - * then add information about the version of - * the io6prom as a part of "detailed inventory" - * information. - */ - if (is_master_baseio(nasid, - NODEPDA(cnode)->module_id, - get_widget_slotnum(0,widgetnum))) { - extern void klhwg_baseio_inventory_add(devfs_handle_t, - cnodeid_t); - module = NODEPDA(cnode)->module_id; - -#ifdef XBRIDGE_REGS_SIM - DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); - if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) { -#else - if (nasid_has_xbridge(nasid)) { -#endif /* XBRIDGE_REGS_SIM */ - board = find_lboard_module( - (lboard_t *)KL_CONFIG_INFO(nasid), - module); - /* - * Change iobrick to correct i/o brick - */ -#ifdef SUPPORT_PRINTING_M_FORMAT - sprintf(pathname, EDGE_LBL_MODULE "/%M/" -#else - sprintf(pathname, EDGE_LBL_MODULE "/%x/" -#endif - "iobrick" "/%s/%d", - NODEPDA(cnode)->module_id, - EDGE_LBL_XTALK, widgetnum); - } else { - slot = get_widget_slotnum(0, widgetnum); - board = get_board_name(nasid, module, slot, - new_name); - /* - * Create the vertex for the widget, - * using the decimal - * widgetnum as the name of the primary edge. - */ -#ifdef SUPPORT_PRINTING_M_FORMAT - sprintf(pathname, EDGE_LBL_MODULE "/%M/" - EDGE_LBL_SLOT "/%s/%s", - NODEPDA(cnode)->module_id, - slotname, new_name); -#else - memset(buffer, 0, 16); - format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); - sprintf(pathname, EDGE_LBL_MODULE "/%s/" - EDGE_LBL_SLOT "/%s/%s", - buffer, - slotname, new_name); -#endif - } - - rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); - DBG("io_xswitch_widget_init: (2) path= %s\n", pathname); - /* - * This is a weird ass code needed for error injection - * purposes. - */ - rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); - - klhwg_baseio_inventory_add(widgetv,cnode); - } - sprintf(name, "%d", widgetnum); - DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv); - rc = hwgraph_edge_add(xswitchv, widgetv, name); - - /* - * crosstalk switch code tracks which - * widget is attached to each link. - */ - xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv); - - /* - * Peek at the widget to get its crosstalk part and - * mfgr numbers, then present it to the generic xtalk - * bus provider to have its driver attach routine - * called (or not). - */ -#ifdef XBRIDGE_REGS_SIM - widget_id = 0x2d000049; - DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n"); -#else - widget_id = XWIDGET_ID_READ(nasid, widgetnum); -#endif /* XBRIDGE_REGS_SIM */ - hwid.part_num = XWIDGET_PART_NUM(widget_id); - hwid.rev_num = XWIDGET_REV_NUM(widget_id); - hwid.mfg_num = XWIDGET_MFG_NUM(widget_id); - /* Store some inventory information about - * the xwidget in the hardware graph. - */ - xwidget_inventory_add(widgetv,board,hwid); - - (void)xwidget_register(&hwid, widgetv, widgetnum, - hubv, hub_widgetid, - aa); - -#ifdef SN0_USE_BTE - bte_bpush_war(cnode, (void *)board); -#endif - } - -} - - -static void -io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode) -{ - xwidgetnum_t widgetnum; - async_attach_t aa; - - aa = async_attach_new(); - - DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode); - - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; - widgetnum++) { - io_xswitch_widget_init(xswitchv, - cnodeid_to_vertex(cnode), - widgetnum, aa); - } - /* - * Wait for parallel attach threads, if any, to complete. - */ - async_attach_waitall(aa); - async_attach_free(aa); -} - -/* - * For each PCI bridge connected to the xswitch, add a link from the - * board's klconfig info to the bridge's hwgraph vertex. This lets - * the FRU analyzer find the bridge without traversing the hardware - * graph and risking hangs. - */ -static void -io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) -{ - xwidgetnum_t widgetnum; - char pathname[128]; - devfs_handle_t vhdl; - nasid_t nasid, peer_nasid; - lboard_t *board; - - - - /* And its connected hub's nasids */ - nasid = COMPACT_TO_NASID_NODEID(cnodeid); - peer_nasid = NODEPDA(cnodeid)->xbow_peer; - - /* - * Look for paths matching "/pci" under xswitchv. - * For every widget, init. its lboard's hwgraph link. If the - * board has a PCI bridge, point the link to it. - */ - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; - widgetnum++) { - sprintf(pathname, "%d", widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) != - GRAPH_SUCCESS) - continue; - - board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), - NODEPDA(cnodeid)->module_id); - if (board == NULL && peer_nasid != INVALID_NASID) { - /* - * Try to find the board on our peer - */ - board = find_lboard_module( - (lboard_t *)KL_CONFIG_INFO(peer_nasid), - NODEPDA(cnodeid)->module_id); - } - if (board == NULL) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "Could not find PROM info for vertex %v, " - "FRU analyzer may fail", - vhdl); -#else - printk(KERN_WARNING "Could not find PROM info for vertex 0x%p, " - "FRU analyzer may fail", - (void *)vhdl); -#endif - return; - } - - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) == - GRAPH_SUCCESS) - board->brd_graph_link = vhdl; - else - board->brd_graph_link = GRAPH_VERTEX_NONE; - } -} - -/* - * Initialize all I/O on the specified node. - */ -static void -io_init_node(cnodeid_t cnodeid) -{ - /*REFERENCED*/ - devfs_handle_t hubv, switchv, widgetv; - struct xwidget_hwid_s hwid; - hubinfo_t hubinfo; - int is_xswitch; - nodepda_t *npdap; - struct semaphore *peer_sema = 0; - uint32_t widget_partnum; - nodepda_router_info_t *npda_rip; - cpu_cookie_t c = 0; - extern int hubdev_docallouts(devfs_handle_t); - -#ifdef LATER - /* Try to execute on the node that we're initializing. */ - c = setnoderun(cnodeid); -#endif - npdap = NODEPDA(cnodeid); - - /* - * Get the "top" vertex for this node's hardware - * graph; it will carry the per-hub hub-specific - * data, and act as the crosstalk provider master. - * It's canonical path is probably something of the - * form /hw/module/%M/slot/%d/node - */ - hubv = cnodeid_to_vertex(cnodeid); - DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap); - - ASSERT(hubv != GRAPH_VERTEX_NONE); - - hubdev_docallouts(hubv); - - /* - * Set up the dependent routers if we have any. - */ - npda_rip = npdap->npda_rip_first; - - while(npda_rip) { - /* If the router info has not been initialized - * then we need to do the router initialization - */ - if (!npda_rip->router_infop) { - router_init(cnodeid,0,npda_rip); - } - npda_rip = npda_rip->router_next; - } - - /* - * Read mfg info on this hub - */ -#ifdef LATER - printk("io_init_node: FIXME need to implement HUB_VERTEX_MFG_INFO\n"); - HUB_VERTEX_MFG_INFO(hubv); -#endif /* LATER */ - - /* - * If nothing connected to this hub's xtalk port, we're done. - */ - early_probe_for_widget(hubv, &hwid); - if (hwid.part_num == XWIDGET_PART_NUM_NONE) { -#ifdef PROBE_TEST - if ((cnodeid == 1) || (cnodeid == 2)) { - int index; - - for (index = 0; index < 600; index++) - DBG("Interfering with device probing!!!\n"); - } -#endif - /* io_init_done takes cpu cookie as 2nd argument - * to do a restorenoderun for the setnoderun done - * at the start of this thread - */ - - DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv); - return; - /* NOTREACHED */ - } - - /* - * attach our hub_provider information to hubv, - * so we can use it as a crosstalk provider "master" - * vertex. - */ - xtalk_provider_register(hubv, &hub_provider); - xtalk_provider_startup(hubv); - - /* - * Create a vertex to represent the crosstalk bus - * attached to this hub, and a vertex to be used - * as the connect point for whatever is out there - * on the other side of our crosstalk connection. - * - * Crosstalk Switch drivers "climb up" from their - * connection point to try and take over the switch - * point. - * - * Of course, the edges and verticies may already - * exist, in which case our net effect is just to - * associate the "xtalk_" driver with the connection - * point for the device. - */ - - (void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv); - - DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv); - - ASSERT(switchv != GRAPH_VERTEX_NONE); - - (void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO); - - DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n"); - - /* - * We need to find the widget id and update the basew_id field - * accordingly. In particular, SN00 has direct connected bridge, - * and hence widget id is Not 0. - */ - - widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; - - if (widget_partnum == BRIDGE_WIDGET_PART_NUM || - widget_partnum == XBRIDGE_WIDGET_PART_NUM){ - npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); - - DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum); - - } else if (widget_partnum == XBOW_WIDGET_PART_NUM || - widget_partnum == XXBOW_WIDGET_PART_NUM) { - /* - * Xbow control register does not have the widget ID field. - * So, hard code the widget ID to be zero. - */ - DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum); - npdap->basew_id = 0; - - } else if (widget_partnum == XG_WIDGET_PART_NUM) { - /* - * OK, WTF do we do here if we have an XG direct connected to a HUB/Bedrock??? - * So, hard code the widget ID to be zero? - */ - npdap->basew_id = 0; - npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); - } else { - npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); - - panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv); - - /*NOTREACHED*/ - } - { - char widname[10]; - sprintf(widname, "%x", npdap->basew_id); - (void)hwgraph_path_add(switchv, widname, &widgetv); - DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv); - ASSERT(widgetv != GRAPH_VERTEX_NONE); - } - - nodepda->basew_xc = widgetv; - - is_xswitch = xwidget_hwid_is_xswitch(&hwid); - - /* - * Try to become the master of the widget. If this is an xswitch - * with multiple hubs connected, only one will succeed. Mastership - * of an xswitch is used only when touching registers on that xswitch. - * The slave xwidgets connected to the xswitch can be owned by various - * masters. - */ - if (device_master_set(widgetv, hubv) == 0) { - - /* Only one hub (thread) per Crosstalk device or switch makes - * it to here. - */ - - /* - * Initialize whatever xwidget is hanging off our hub. - * Whatever it is, it's accessible through widgetnum 0. - */ - hubinfo_get(hubv, &hubinfo); - - (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL); - - if (!is_xswitch) { - /* io_init_done takes cpu cookie as 2nd argument - * to do a restorenoderun for the setnoderun done - * at the start of this thread - */ - io_init_done(cnodeid,c); - /* NOTREACHED */ - } - - /* - * Special handling for Crosstalk Switches (e.g. xbow). - * We need to do things in roughly the following order: - * 1) Initialize xswitch hardware (done above) - * 2) Determine which hubs are available to be widget masters - * 3) Discover which links are active from the xswitch - * 4) Assign xwidgets hanging off the xswitch to hubs - * 5) Initialize all xwidgets on the xswitch - */ - - volunteer_for_widgets(switchv, hubv); - - /* If there's someone else on this crossbow, recognize him */ - if (npdap->xbow_peer != INVALID_NASID) { - nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer)); - peer_sema = &peer_npdap->xbow_sema; - volunteer_for_widgets(switchv, peer_npdap->node_vertex); - } - - assign_widgets_to_volunteers(switchv, hubv); - - /* Signal that we're done */ - if (peer_sema) { - mutex_unlock(peer_sema); - } - - } - else { - /* Wait 'til master is done assigning widgets. */ - mutex_lock(&npdap->xbow_sema); - } - -#ifdef PROBE_TEST - if ((cnodeid == 1) || (cnodeid == 2)) { - int index; - - for (index = 0; index < 500; index++) - DBG("Interfering with device probing!!!\n"); - } -#endif - /* Now both nodes can safely inititialize widgets */ - io_init_xswitch_widgets(switchv, cnodeid); - io_link_xswitch_widgets(switchv, cnodeid); - - /* io_init_done takes cpu cookie as 2nd argument - * to do a restorenoderun for the setnoderun done - * at the start of this thread - */ - io_init_done(cnodeid,c); - - DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid); -} - - -#define IOINIT_STKSZ (16 * 1024) - -#define __DEVSTR1 "/../.master/" -#define __DEVSTR2 "/target/" -#define __DEVSTR3 "/lun/0/disk/partition/" -#define __DEVSTR4 "/../ef" - -#if defined(CONFIG_IA64_SGI_SN1) -/* - * Currently, we need to allow for 5 IBrick slots with 1 FC each - * plus an internal 1394. - * - * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR. - */ -#define NUM_BASE_IO_SCSI_CTLR 6 -#else -#define NUM_BASE_IO_SCSI_CTLR 6 -#endif -/* - * This tells ioconfig where it can start numbering scsi controllers. - * Below this base number, platform-specific handles the numbering. - * XXX Irix legacy..controller numbering should be part of devfsd's job - */ -int num_base_io_scsi_ctlr = 2; /* used by syssgi */ -devfs_handle_t base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR]; -static devfs_handle_t baseio_enet_vhdl,baseio_console_vhdl; - -/* - * Put the logical controller number information in the - * scsi controller vertices for each scsi controller that - * is in a "fixed position". - */ -static void -scsi_ctlr_nums_add(devfs_handle_t pci_vhdl) -{ - { - int i; - - num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR; - - /* Initialize base_io_scsi_ctlr_vhdl array */ - for (i=0; i -devfs_handle_t sys_critical_graph_root = GRAPH_VERTEX_NONE; - -/* Define the system critical vertices and connect them through - * a canonical parent-child relationships for easy traversal - * during io error handling. - */ -static void -sys_critical_graph_init(void) -{ - devfs_handle_t bridge_vhdl,master_node_vhdl; - devfs_handle_t xbow_vhdl = GRAPH_VERTEX_NONE; - extern devfs_handle_t hwgraph_root; - devfs_handle_t pci_slot_conn; - int slot; - devfs_handle_t baseio_console_conn; - - DBG("sys_critical_graph_init: FIXME.\n"); - baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl); - - if (baseio_console_conn == NULL) { - return; - } - - /* Get the vertex handle for the baseio bridge */ - bridge_vhdl = device_master_get(baseio_console_conn); - - /* Get the master node of the baseio card */ - master_node_vhdl = cnodeid_to_vertex( - master_node_get(baseio_console_vhdl)); - - /* Add the "root->node" part of the system critical graph */ - - sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl); - - /* Check if we have a crossbow */ - if (hwgraph_traverse(master_node_vhdl, - EDGE_LBL_XTALK"/0", - &xbow_vhdl) == GRAPH_SUCCESS) { - /* We have a crossbow.Add "node->xbow" part of the system - * critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl); - - /* Add "xbow->baseio bridge" of the system critical graph */ - sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl); - - hwgraph_vertex_unref(xbow_vhdl); - } else - /* We donot have a crossbow. Add "node->baseio_bridge" - * part of the system critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl); - - /* Add all the populated PCI slot vertices to the system critical - * graph with the bridge vertex as the parent. - */ - for (slot = 0 ; slot < 8; slot++) { - char slot_edge[10]; - - sprintf(slot_edge,"%d",slot); - if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn) - != GRAPH_SUCCESS) - continue; - sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn); - hwgraph_vertex_unref(pci_slot_conn); - } - - hwgraph_vertex_unref(bridge_vhdl); - - /* Add the "ioc3 pci connection point -> console ioc3" part - * of the system critical graph - */ - - if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_console_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "ethernet pci connection point -> base ethernet" part of - * the system critical graph - */ - if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_enet_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "scsi controller pci connection point -> base scsi - * controller" part of the system critical graph - */ - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[0]); - hwgraph_vertex_unref(pci_slot_conn); - } - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[1]); - hwgraph_vertex_unref(pci_slot_conn); - } - hwgraph_vertex_unref(baseio_console_conn); - -} - -static void -baseio_ctlr_num_set(void) -{ - char name[MAXDEVNAME]; - devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; - devfs_handle_t ioc3_console_vhdl_get(void); - - - DBG("baseio_ctlr_num_set; FIXME\n"); - console_vhdl = ioc3_console_vhdl_get(); - if (console_vhdl == GRAPH_VERTEX_NONE) - return; - /* Useful for setting up the system critical graph */ - baseio_console_vhdl = console_vhdl; - - vertex_to_name(console_vhdl,name,MAXDEVNAME); - - strcat(name,__DEVSTR1); - pci_vhdl = hwgraph_path_to_vertex(name); - scsi_ctlr_nums_add(pci_vhdl); - /* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(pci_vhdl); - - vertex_to_name(console_vhdl, name, MAXDEVNAME); - strcat(name, __DEVSTR4); - enet_vhdl = hwgraph_path_to_vertex(name); - - /* Useful for setting up the system critical graph */ - baseio_enet_vhdl = enet_vhdl; - - device_controller_num_set(enet_vhdl, 0); - /* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(enet_vhdl); -} -/* #endif */ - -void -sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list) -{ - /* REFERENCED */ - int rtn_val; - - /* - ** sn00 population: errb orrb - ** 0- ql 3+? - ** 1- ql 2 - ** 2- ioc3 ethernet 2+? - ** 3- ioc3 secondary 1 - ** 4- 0 - ** 5- PCI slot - ** 6- PCI slot - ** 7- PCI slot - */ - - /* The following code implements this heuristic for getting - * maximum usage out of the rrbs - * - * constraints: - * 8 bit ql1 needs 1+1 - * ql0 or ql5,6,7 wants 1+2 - * ethernet wants 2 or more - * - * rules for even rrbs: - * if nothing in slot 6 - * 4 rrbs to 0 and 2 (0xc8889999) - * else - * 3 2 3 to slots 0 2 6 (0xc8899bbb) - * - * rules for odd rrbs - * if nothing in slot 5 or 7 (0xc8889999) - * 4 rrbs to 1 and 3 - * else if 1 thing in 5 or 7 (0xc8899aaa) or (0xc8899bbb) - * 3 2 3 to slots 1 3 5|7 - * else - * 2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this - * (0xc89aaabb) may short what it wants therefore the - * rule should be to plug pci slots in order) - */ - - - if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) { - /* something in slot 6 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0); - } - else { - rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0); - } - if (rtn_val) - printk(KERN_WARNING "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed"); - - if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && - (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) { - /* soemthing in slot 5 and 7 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0); - } - else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) { - /* soemthing in slot 5 but not 7 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0); - } - else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) { - /* soemthing in slot 7 but not 5 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0); - } - else { - /* nothing in slot 5 or 7 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0); - } - if (rtn_val) - printk(KERN_WARNING "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed"); -} - - -/* - * Initialize all I/O devices. Starting closest to nodes, probe and - * initialize outward. - */ -void -init_all_devices(void) -{ - /* Governor on init threads..bump up when safe - * (beware many devfs races) - */ -#ifdef LATER - int io_init_node_threads = 2; -#endif - cnodeid_t cnodeid, active; - -#ifdef LINUX_KERNEL_THREADS - sema_init(&io_init_sema, 0); -#endif - - active = 0; - for (cnodeid = 0; cnodeid < numnodes; cnodeid++) { -#ifdef LINUX_KERNEL_THREADS - char thread_name[16]; - extern int io_init_pri; - - /* - * Spawn a service thread for each node to initialize all - * I/O on that node. Each thread attempts to bind itself - * to the node whose I/O it's initializing. - */ - sprintf(thread_name, "IO_init[%d]", cnodeid); - - (void)sthread_create(thread_name, 0, IOINIT_STKSZ, 0, - io_init_pri, KT_PS, (st_func_t *)io_init_node, - (void *)(long)cnodeid, 0, 0, 0); -#else - DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid); - io_init_node(cnodeid); - - DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid); - -#endif /* LINUX_KERNEL_THREADS */ - -#ifdef LINUX_KERNEL_THREADS - /* Limit how many nodes go at once, to not overload hwgraph */ - /* TBD: Should timeout */ - DBG("started thread for cnode %d\n", cnodeid); - active++; - if (io_init_node_threads && - active >= io_init_node_threads) { - down(&io_init_sema); - active--; - } -#endif /* LINUX_KERNEL_THREADS */ - } - -#ifdef LINUX_KERNEL_THREADS - /* Wait until all IO_init threads are done */ - - while (active > 0) { -#ifdef AA_DEBUG - DBG("waiting, %d still active\n", active); -#endif - down(&io_init_sema); - active--; - } - -#endif /* LINUX_KERNEL_THREADS */ - - for (cnodeid = 0; cnodeid < numnodes; cnodeid++) - /* - * Update information generated by IO init. - */ - update_node_information(cnodeid); - - baseio_ctlr_num_set(); - /* Setup the system critical graph (which is a subgraph of the - * main hwgraph). This information is useful during io error - * handling. - */ - sys_critical_graph_init(); - -#if HWG_PRINT - hwgraph_print(); -#endif - -} - -#define toint(x) ((int)(x) - (int)('0')) - -void -devnamefromarcs(char *devnm) -{ - int val; - char tmpnm[MAXDEVNAME]; - char *tmp1, *tmp2; - - val = strncmp(devnm, "dks", 3); - if (val != 0) - return; - tmp1 = devnm + 3; - if (!isdigit(*tmp1)) - return; - - val = 0; - while (isdigit(*tmp1)) { - val = 10*val+toint(*tmp1); - tmp1++; - } - - if(*tmp1 != 'd') - return; - else - tmp1++; - - if ((val < 0) || (val >= NUM_BASE_IO_SCSI_CTLR)) { - int i; - int viable_found = 0; - - DBG("Only controller numbers 0..%d are supported for\n", NUM_BASE_IO_SCSI_CTLR-1); - DBG("prom \"root\" variables of the form dksXdXsX.\n"); - DBG("To use another disk you must use the full hardware graph path\n\n"); - DBG("Possible controller numbers for use in 'dksXdXsX' on this system: "); - for (i=0; i XBOW_PORT_F) - return 0; - - /* Find "brick" in the path name */ - bp = strstr(hw_path_name, "brick"); - if (bp == NULL) - return 0; - - /* Find preceding slash */ - sp = bp; - while (sp > hw_path_name) { - sp--; - if (*sp == '/') - break; - } - - /* Invalid if no preceding slash */ - if (!sp) - return 0; - - /* Bump slash pointer to "brick" prefix */ - sp++; - /* - * Verify "brick" prefix length; valid exaples: - * 'I' from "/Ibrick" - * 'P' from "/Pbrick" - * 'X' from "/Xbrick" - */ - if ((bp - sp) != 1) - return 0; - - return (io_brick_map_widget(*sp, widget_num)); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/module.c linux-2.4.22/arch/ia64/sn/io/module.c --- linux-2.4.21/arch/ia64/sn/io/module.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/module.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,312 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* #define LDEBUG 1 */ - -#ifdef LDEBUG -#define DPRINTF printk -#define printf printk -#else -#define DPRINTF(x...) -#endif - -module_t *modules[MODULE_MAX]; -int nummodules; - -#define SN00_SERIAL_FUDGE 0x3b1af409d513c2 -#define SN0_SERIAL_FUDGE 0x6e - -void -encode_int_serial(uint64_t src,uint64_t *dest) -{ - uint64_t val; - int i; - - val = src + SN00_SERIAL_FUDGE; - - - for (i = 0; i < sizeof(long long); i++) { - ((char*)dest)[i] = - ((char*)&val)[sizeof(long long)/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))]; - } -} - - -void -decode_int_serial(uint64_t src, uint64_t *dest) -{ - uint64_t val; - int i; - - for (i = 0; i < sizeof(long long); i++) { - ((char*)&val)[sizeof(long long)/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = - ((char*)&src)[i]; - } - - *dest = val - SN00_SERIAL_FUDGE; -} - - -void -encode_str_serial(const char *src, char *dest) -{ - int i; - - for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) { - - dest[i] = src[MAX_SERIAL_NUM_SIZE/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))] + - SN0_SERIAL_FUDGE; - } -} - -void -decode_str_serial(const char *src, char *dest) -{ - int i; - - for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) { - dest[MAX_SERIAL_NUM_SIZE/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] - - SN0_SERIAL_FUDGE; - } -} - - -module_t *module_lookup(moduleid_t id) -{ - int i; - - for (i = 0; i < nummodules; i++) - if (modules[i]->id == id) { - DPRINTF("module_lookup: found m=0x%p\n", modules[i]); - return modules[i]; - } - - return NULL; -} - -/* - * module_add_node - * - * The first time a new module number is seen, a module structure is - * inserted into the module list in order sorted by module number - * and the structure is initialized. - * - * The node number is added to the list of nodes in the module. - */ - -module_t *module_add_node(moduleid_t id, cnodeid_t n) -{ - module_t *m; - int i; - char buffer[16]; - -#ifdef __ia64 - memset(buffer, 0, 16); - format_module_id(buffer, id, MODULE_FORMAT_BRIEF); - DPRINTF("module_add_node: id=%s node=%d\n", buffer, n); -#endif - - if ((m = module_lookup(id)) == 0) { -#ifdef LATER - m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n); -#else - m = kmalloc(sizeof (module_t), GFP_KERNEL); - memset(m, 0 , sizeof(module_t)); -#endif - ASSERT_ALWAYS(m); - - m->id = id; - spin_lock_init(&m->lock); - - mutex_init_locked(&m->thdcnt); - -// set_elsc(&m->elsc); - elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n)); - spin_lock_init(&m->elsclock); - - /* Insert in sorted order by module number */ - - for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--) - modules[i] = modules[i - 1]; - - modules[i] = m; - nummodules++; - } - - m->nodes[m->nodecnt++] = n; - - DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt); - - return m; -} - -int module_probe_snum(module_t *m, nasid_t nasid) -{ - lboard_t *board; - klmod_serial_num_t *comp; - char * bcopy(const char * src, char * dest, int count); - char serial_number[16]; - - /* - * record brick serial number - */ - board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - - if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) - { -#if LDEBUG - printf ("module_probe_snum: no IP35 board found!\n"); -#endif - return 0; - } - - board_serial_number_get( board, serial_number ); - if( serial_number[0] != '\0' ) { - encode_str_serial( serial_number, m->snum.snum_str ); - m->snum_valid = 1; - } -#if LDEBUG - else { - printf("module_probe_snum: brick serial number is null!\n"); - } - printf("module_probe_snum: brick serial number == %s\n", serial_number); -#endif /* DEBUG */ - - board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), - KLTYPE_IOBRICK_XBOW); - - if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) - return 0; - - comp = GET_SNUM_COMP(board); - - if (comp) { -#if LDEBUG - int i; - - printf("********found module with id %x and string", m->id); - - for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) - printf(" %x ", comp->snum.snum_str[i]); - - printf("\n"); /* Fudged string is not ASCII */ -#endif - - if (comp->snum.snum_str[0] != '\0') { - bcopy(comp->snum.snum_str, - m->sys_snum, - MAX_SERIAL_NUM_SIZE); - m->sys_snum_valid = 1; - } - } - - if (m->sys_snum_valid) - return 1; - else { - DPRINTF("Invalid serial number for module %d, " - "possible missing or invalid NIC.", m->id); - return 0; - } -} - -void -io_module_init(void) -{ - cnodeid_t node; - lboard_t *board; - nasid_t nasid; - int nserial; - module_t *m; - - DPRINTF("*******module_init\n"); - - nserial = 0; - - for (node = 0; node < numnodes; node++) { - nasid = COMPACT_TO_NASID_NODEID(node); - - board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - ASSERT(board); - - m = module_add_node(board->brd_module, node); - - if (! m->snum_valid && module_probe_snum(m, nasid)) - nserial++; - } - - DPRINTF("********found total of %d serial numbers in the system\n", - nserial); - - if (nserial == 0) - printk(KERN_WARNING "io_module_init: No serial number found.\n"); -} - -elsc_t *get_elsc(void) -{ - return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc; -} - -int -get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info) -{ - int i; - - if (cmod < 0 || cmod >= nummodules) - return EINVAL; - - if (! modules[cmod]->snum_valid) - return ENXIO; - - mod_info->mod_num = modules[cmod]->id; - { - char temp[MAX_SERIAL_NUM_SIZE]; - - decode_str_serial(modules[cmod]->snum.snum_str, temp); - - /* if this is an invalid serial number return an error */ - if (temp[0] != 'K') - return ENXIO; - - mod_info->serial_num = 0; - - for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) { - mod_info->serial_num <<= 4; - mod_info->serial_num |= (temp[i] & 0xf); - - mod_info->serial_str[i] = temp[i]; - } - - mod_info->serial_str[i] = '\0'; - } - - return 0; -} diff -urN linux-2.4.21/arch/ia64/sn/io/pci.c linux-2.4.22/arch/ia64/sn/io/pci.c --- linux-2.4.21/arch/ia64/sn/io/pci.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,294 +0,0 @@ -/* - * - * SNI64 specific PCI support for SNI IO. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (c) 1997, 1998, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG_CONFIG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - - - -#ifdef CONFIG_PCI - -extern devfs_handle_t pci_bus_to_vertex(unsigned char); -extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn); - -/* - * snia64_read_config_byte - Read a byte from the config area of the device. - */ -static int snia64_read_config_byte (struct pci_dev *dev, - int where, unsigned char *val) -{ - unsigned long res = 0; - unsigned size = 1; - devfs_handle_t device_vertex; - - if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); - if (!device_vertex) { - DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", - __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - return(-1); - } - res = pciio_config_get(device_vertex, (unsigned) where, size); - *val = (unsigned char) res; - return PCIBIOS_SUCCESSFUL; -} - -/* - * snia64_read_config_word - Read 2 bytes from the config area of the device. - */ -static int snia64_read_config_word (struct pci_dev *dev, - int where, unsigned short *val) -{ - unsigned long res = 0; - unsigned size = 2; /* 2 bytes */ - devfs_handle_t device_vertex; - - if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); - if (!device_vertex) { - DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", - __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - return(-1); - } - res = pciio_config_get(device_vertex, (unsigned) where, size); - *val = (unsigned short) res; - return PCIBIOS_SUCCESSFUL; -} - -/* - * snia64_read_config_dword - Read 4 bytes from the config area of the device. - */ -static int snia64_read_config_dword (struct pci_dev *dev, - int where, unsigned int *val) -{ - unsigned long res = 0; - unsigned size = 4; /* 4 bytes */ - devfs_handle_t device_vertex; - - if (where & 3) { - return PCIBIOS_BAD_REGISTER_NUMBER; - } - if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - - device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); - if (!device_vertex) { - DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", - __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - return(-1); - } - res = pciio_config_get(device_vertex, (unsigned) where, size); - *val = (unsigned int) res; - return PCIBIOS_SUCCESSFUL; -} - -/* - * snia64_write_config_byte - Writes 1 byte to the config area of the device. - */ -static int snia64_write_config_byte (struct pci_dev *dev, - int where, unsigned char val) -{ - devfs_handle_t device_vertex; - - if ( dev == (struct pci_dev *)0 ) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - /* - * if it's an IOC3 then we bail out, we special - * case them with pci_fixup_ioc3 - */ - if (dev->vendor == PCI_VENDOR_ID_SGI && - dev->device == PCI_DEVICE_ID_SGI_IOC3 ) - return PCIBIOS_SUCCESSFUL; - - device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); - if (!device_vertex) { - DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", - __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - return(-1); - } - pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val); - - return PCIBIOS_SUCCESSFUL; -} - -/* - * snia64_write_config_word - Writes 2 bytes to the config area of the device. - */ -static int snia64_write_config_word (struct pci_dev *dev, - int where, unsigned short val) -{ - devfs_handle_t device_vertex = NULL; - - if (where & 1) { - return PCIBIOS_BAD_REGISTER_NUMBER; - } - if ( dev == (struct pci_dev *)0 ) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - /* - * if it's an IOC3 then we bail out, we special - * case them with pci_fixup_ioc3 - */ - if (dev->vendor == PCI_VENDOR_ID_SGI && - dev->device == PCI_DEVICE_ID_SGI_IOC3) - return PCIBIOS_SUCCESSFUL; - - device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); - if (!device_vertex) { - DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", - __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - return(-1); - } - pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val); - - return PCIBIOS_SUCCESSFUL; -} - -/* - * snia64_write_config_dword - Writes 4 bytes to the config area of the device. - */ -static int snia64_write_config_dword (struct pci_dev *dev, - int where, unsigned int val) -{ - devfs_handle_t device_vertex; - - if (where & 3) { - return PCIBIOS_BAD_REGISTER_NUMBER; - } - if ( dev == (struct pci_dev *)0 ) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - /* - * if it's an IOC3 then we bail out, we special - * case them with pci_fixup_ioc3 - */ - if (dev->vendor == PCI_VENDOR_ID_SGI && - dev->device == PCI_DEVICE_ID_SGI_IOC3) - return PCIBIOS_SUCCESSFUL; - - device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); - if (!device_vertex) { - DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", - __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - return(-1); - } - pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val); - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops snia64_pci_ops = { - snia64_read_config_byte, - snia64_read_config_word, - snia64_read_config_dword, - snia64_write_config_byte, - snia64_write_config_word, - snia64_write_config_dword -}; - -/* - * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code. - */ -void __init -sn_pci_find_bios(void) -{ - extern struct pci_ops *pci_root_ops; - /* - * Go initialize our IO Infrastructure .. - */ - extern void sgi_master_io_infr_init(void); - - sgi_master_io_infr_init(); - - /* sn_io_infrastructure_init(); */ - pci_root_ops = &snia64_pci_ops; -} - -void -pci_fixup_ioc3(struct pci_dev *d) -{ - int i; - unsigned int size; - - /* IOC3 only decodes 0x20 bytes of the config space, reading - * beyond that is relatively benign but writing beyond that - * (especially the base address registers) will shut down the - * pci bus...so avoid doing so. - * NOTE: this means we can't program the intr_pin into the device, - * currently we hack this with special code in - * sgi_pci_intr_support() - */ - DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name); - - /* I happen to know from the spec that the ioc3 needs only 0xfffff - * The standard pci trick of writing ~0 to the baddr and seeing - * what comes back doesn't work with the ioc3 - */ - size = 0xfffff; - d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size; - - /* - * Zero out the resource structure .. because we did not go through - * the normal PCI Infrastructure Init, garbbage are left in these - * fileds. - */ - for (i = 1; i <= PCI_ROM_RESOURCE; i++) { - d->resource[i].start = 0UL; - d->resource[i].end = 0UL; - d->resource[i].flags = 0UL; - } - -#ifdef CONFIG_IA64_SGI_SN1 - *(volatile u32 *)0xc0000a000f000220 |= 0x90000; -#endif - d->subsystem_vendor = 0; - d->subsystem_device = 0; - -} - -#else -void sn_pci_find_bios(void) {} -void pci_fixup_ioc3(struct pci_dev *d) {} -struct list_head pci_root_buses; -struct list_head pci_root_buses; -struct list_head pci_devices; - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/ia64/sn/io/pci_bus_cvlink.c linux-2.4.22/arch/ia64/sn/io/pci_bus_cvlink.c --- linux-2.4.21/arch/ia64/sn/io/pci_bus_cvlink.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/pci_bus_cvlink.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,743 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int bridge_rev_b_data_check_disable; - -devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET]; -nasid_t busnum_to_nid[MAX_PCI_XWIDGET]; -void * busnum_to_atedmamaps[MAX_PCI_XWIDGET]; -unsigned char num_bridges; -static int done_probing = 0; - -static int pci_bus_map_create(devfs_handle_t xtalk); -devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn); - -#define SN_IOPORTS_UNIT 256 -#define MAX_IOPORTS 0xffff -#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN_IOPORTS_UNIT) -struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS]; -unsigned long sn_allocate_ioports(unsigned long pci_address); - -extern void sn_init_irq_desc(void); - - - -/* - * pci_bus_cvlink_init() - To be called once during initialization before - * SGI IO Infrastructure init is called. - */ -void -pci_bus_cvlink_init(void) -{ - memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET); - memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET); - - memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET); - - memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs)); - - num_bridges = 0; -} - -/* - * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated - * pci bus vertex from the SGI IO Infrastructure. - */ -devfs_handle_t -pci_bus_to_vertex(unsigned char busnum) -{ - - devfs_handle_t pci_bus = NULL; - - - /* - * First get the xwidget vertex. - */ - pci_bus = busnum_to_pcibr_vhdl[busnum]; - return(pci_bus); -} - -/* - * devfn_to_vertex() - returns the vertex of the device given the bus, slot, - * and function numbers. - */ -devfs_handle_t -devfn_to_vertex(unsigned char busnum, unsigned int devfn) -{ - - int slot = 0; - int func = 0; - char name[16]; - devfs_handle_t pci_bus = NULL; - devfs_handle_t device_vertex = (devfs_handle_t)NULL; - - /* - * Go get the pci bus vertex. - */ - pci_bus = pci_bus_to_vertex(busnum); - if (!pci_bus) { - /* - * During probing, the Linux pci code invents non-existent - * bus numbers and pci_dev structures and tries to access - * them to determine existence. Don't crib during probing. - */ - if (done_probing) - printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum); - return(NULL); - } - - - /* - * Go get the slot&function vertex. - * Should call pciio_slot_func_to_name() when ready. - */ - slot = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* - * For a NON Multi-function card the name of the device looks like: - * ../pci/1, ../pci/2 .. - */ - if (func == 0) { - sprintf(name, "%d", slot); - if (hwgraph_traverse(pci_bus, name, &device_vertex) == - GRAPH_SUCCESS) { - if (device_vertex) { - return(device_vertex); - } - } - } - - /* - * This maybe a multifunction card. It's names look like: - * ../pci/1a, ../pci/1b, etc. - */ - sprintf(name, "%d%c", slot, 'a'+func); - if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) { - if (!device_vertex) { - return(NULL); - } - } - - return(device_vertex); -} - -/* - * For the given device, initialize the addresses for both the Device(x) Flush - * Write Buffer register and the Xbow Flush Register for the port the PCI bus - * is connected. - */ -static void -set_flush_addresses(struct pci_dev *device_dev, - struct sn_device_sysdata *device_sysdata) -{ - pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - - device_sysdata->dma_buf_sync = (volatile unsigned int *) - &(bridge->b_wr_req_buf[pciio_slot].reg); - device_sysdata->xbow_buf_sync = (volatile unsigned int *) - XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), - pcibr_soft->bs_xid); -#ifdef DEBUG - - printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", - device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync); - - while((volatile unsigned int )*device_sysdata->dma_buf_sync); - while((volatile unsigned int )*device_sysdata->xbow_buf_sync); -#endif - -} - -/* - * Most drivers currently do not properly tell the arch specific pci dma - * interfaces whether they can handle A64. Here is where we privately - * keep track of this. - */ -static void __init -set_sn_pci64(struct pci_dev *dev) -{ - unsigned short vendor = dev->vendor; - unsigned short device = dev->device; - - if (vendor == PCI_VENDOR_ID_QLOGIC) { - if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) || - (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) { - SET_PCIA64(dev); - return; - } - } - - if (vendor == PCI_VENDOR_ID_SGI) { - if (device == PCI_DEVICE_ID_SGI_IOC3) { - SET_PCIA64(dev); - return; - } - } - -} - -/* - * sn_allocate_ioports() - This routine provides the allocation and - * mappings between Linux style IOPORTs management. - * - * For simplicity sake, SN1 will allocate IOPORTs in chunks of - * 256bytes .. irrespective of what the card desires. This may - * have to change when we understand how to deal with legacy ioports - * which are hardcoded in some drivers e.g. SVGA. - * - * Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers. - * It will remain so. The IO Infrastructure will continue to map - * IO Resource just like IRIX. When this is done, we map IOPORT - * chunks to these resources. The Linux drivers will see and use real - * IOPORT numbers. The various IOPORT access macros e.g. inb/outb etc. - * does the munging of these IOPORT numbers to make a Uncache Virtual - * Address. This address via the tlb entries generates the PCI Address - * allocated by the SN1 IO Infrastructure Layer. - */ -static unsigned long sn_ioport_num = 0x1000; /* Reserve room for Legacy stuff */ -unsigned long -sn_allocate_ioports(unsigned long pci_address) -{ - - unsigned long ioport_index; - - /* - * Just some idiot checking .. - */ - if ( sn_ioport_num > 0xffff ) { - printk("sn_allocate_ioports: No more IO PORTS available\n"); - return(-1); - } - - /* - * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's - * Manual for details. - */ - ioport_index = sn_ioport_num / SN_IOPORTS_UNIT; - - ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */ - ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */ - ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/ - ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/ - ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */ - ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/ - ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/ - ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */ - ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */ - ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */ - - /* printk("sn_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */ - - sn_ioport_num += SN_IOPORTS_UNIT; - - return(sn_ioport_num - SN_IOPORTS_UNIT); -} - -/* - * sn_pci_fixup() - This routine is called when platform_pci_fixup() is - * invoked at the end of pcibios_init() to link the Linux pci - * infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c - * - * Other platform specific fixup can also be done here. - */ -void -sn_pci_fixup(int arg) -{ - struct list_head *ln; - struct pci_bus *pci_bus = NULL; - struct pci_dev *device_dev = NULL; - struct sn_widget_sysdata *widget_sysdata; - struct sn_device_sysdata *device_sysdata; -#ifdef SN_IOPORTS - unsigned long ioport; -#endif - pciio_intr_t intr_handle; - int cpuid, bit; - devfs_handle_t device_vertex; - pciio_intr_line_t lines; - extern void sn_pci_find_bios(void); -#ifdef CONFIG_IA64_SGI_SN2 - extern int numnodes; - int cnode; -#endif /* CONFIG_IA64_SGI_SN2 */ - - - if (arg == 0) { - sn_init_irq_desc(); - sn_pci_find_bios(); -#ifdef CONFIG_IA64_SGI_SN2 - for (cnode = 0; cnode < numnodes; cnode++) { - extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int); - intr_init_vecblk(NODEPDA(cnode), cnode, 0); - } -#endif /* CONFIG_IA64_SGI_SN2 */ - return; - } - -#if 0 -{ - devfs_handle_t bridge_vhdl = pci_bus_to_vertex(0); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl); - bridge_t *bridge = pcibr_soft->bs_base; - printk("pci_fixup_ioc3: Before devreg fixup\n"); - printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg); - printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg); - printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg); - printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg); - printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg); - printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg); - printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg); - printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg); -} -#endif - done_probing = 1; - - /* - * Initialize the pci bus vertex in the pci_bus struct. - */ - for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { - pci_bus = pci_bus_b(ln); - widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), - GFP_KERNEL); - widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number); - pci_bus->sysdata = (void *)widget_sysdata; - } - - /* - * set the root start and end so that drivers calling check_region() - * won't see a conflict - */ -#ifdef SN_IOPORTS - ioport_resource.start = sn_ioport_num; - ioport_resource.end = 0xffff; -#else -#if defined(CONFIG_IA64_SGI_SN1) - if ( IS_RUNNING_ON_SIMULATOR() ) { - /* - * IDE legacy IO PORTs are supported in Medusa. - * Just open up IO PORTs from 0 .. ioport_resource.end. - */ - ioport_resource.start = 0; - } else { - /* - * We do not support Legacy IO PORT numbers. - */ - ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET; - } - ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET; -#else - // Need something here for sn2.... ZXZXZX -#endif -#endif - - /* - * Set the root start and end for Mem Resource. - */ - iomem_resource.start = 0; - iomem_resource.end = 0xffffffffffffffff; - - /* - * Initialize the device vertex in the pci_dev struct. - */ - pci_for_each_dev(device_dev) { - unsigned int irq; - int idx; - u16 cmd; - devfs_handle_t vhdl; - unsigned long size; - extern int bit_pos_to_irq(int); - - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3) { - extern void pci_fixup_ioc3(struct pci_dev *d); - pci_fixup_ioc3(device_dev); - } - - /* Set the device vertex */ - - device_sysdata = kmalloc(sizeof(struct sn_device_sysdata), - GFP_KERNEL); - device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn); - device_sysdata->isa64 = 0; - /* - * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush - * register addresses. - */ - (void) set_flush_addresses(device_dev, device_sysdata); - - device_dev->sysdata = (void *) device_sysdata; - set_sn_pci64(device_dev); - pci_read_config_word(device_dev, PCI_COMMAND, &cmd); - - /* - * Set the resources address correctly. The assumption here - * is that the addresses in the resource structure has been - * read from the card and it was set in the card by our - * Infrastructure .. - */ - vhdl = device_sysdata->vhdl; - for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { - size = 0; - size = device_dev->resource[idx].end - - device_dev->resource[idx].start; - if (size) { - device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM); - device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET; - } - else - continue; - - device_dev->resource[idx].end = - device_dev->resource[idx].start + size; - -#ifdef CONFIG_IA64_SGI_SN1 - /* - * Adjust the addresses to go to the SWIZZLE .. - */ - device_dev->resource[idx].start = - device_dev->resource[idx].start & 0xfffff7ffffffffff; - device_dev->resource[idx].end = - device_dev->resource[idx].end & 0xfffff7ffffffffff; -#endif - - if (device_dev->resource[idx].flags & IORESOURCE_IO) { - cmd |= PCI_COMMAND_IO; -#ifdef SN_IOPORTS - ioport = sn_allocate_ioports(device_dev->resource[idx].start); - if (ioport < 0) { - printk("sn_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number); - continue; - } - pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff))); - -printk("sn_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff))); - - device_dev->resource[idx].start = ioport; - device_dev->resource[idx].end = ioport + SN_IOPORTS_UNIT; -#endif - } - if (device_dev->resource[idx].flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - /* - * Now handle the ROM resource .. - */ - size = device_dev->resource[PCI_ROM_RESOURCE].end - - device_dev->resource[PCI_ROM_RESOURCE].start; - - if (size) { - device_dev->resource[PCI_ROM_RESOURCE].start = - (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, - size, 0, PCIIO_BYTE_STREAM); - device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET; - device_dev->resource[PCI_ROM_RESOURCE].end = - device_dev->resource[PCI_ROM_RESOURCE].start + size; - -#ifdef CONFIG_IA64_SGI_SN1 - /* - * go through synergy swizzled space - */ - device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL; - device_dev->resource[PCI_ROM_RESOURCE].end &= 0xfffff7ffffffffffUL; -#endif - - } - - /* - * Update the Command Word on the Card. - */ - cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */ - /* bit gets dropped .. no harm */ - pci_write_config_word(device_dev, PCI_COMMAND, cmd); - - pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines); - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { - lines = 1; - } - - device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata; - device_vertex = device_sysdata->vhdl; - - intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex); - - bit = intr_handle->pi_irq; - cpuid = intr_handle->pi_cpu; -#ifdef CONFIG_IA64_SGI_SN1 - irq = bit_pos_to_irq(bit); -#else /* SN2 */ - irq = bit; -#endif - irq = irq + (cpuid << 8); - pciio_intr_connect(intr_handle); - device_dev->irq = irq; -#ifdef ajmtestintr - { - int slot = PCI_SLOT(device_dev->devfn); - static int timer_set = 0; - pcibr_intr_t pcibr_intr = (pcibr_intr_t)intr_handle; - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - extern void intr_test_handle_intr(int, void*, struct pt_regs *); - - if (!timer_set) { - intr_test_set_timer(); - timer_set = 1; - } - intr_test_register_irq(irq, pcibr_soft, slot); - request_irq(irq, intr_test_handle_intr,0,NULL, NULL); - } -#endif - - } - -#if 0 - -{ - devfs_handle_t bridge_vhdl = pci_bus_to_vertex(0); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl); - bridge_t *bridge = pcibr_soft->bs_base; - - printk("pci_fixup_ioc3: Before devreg fixup\n"); - printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg); - printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg); - printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg); - printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg); - printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg); - printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg); - printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg); - printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg); -} - -printk("testing Big Window: 0xC0000200c0000000 %p\n", *( (volatile uint64_t *)0xc0000200a0000000)); -printk("testing Big Window: 0xC0000200c0000008 %p\n", *( (volatile uint64_t *)0xc0000200a0000008)); - -#endif - -} - -/* - * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. - * - * Linux PCI Bus numbers are assigned from lowest module_id numbers - * (rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to - * HUB_WIDGET_ID_MIN: - * widgetnum 15 gets lower Bus Number than widgetnum 14 etc. - * - * Given 2 modules 001c01 and 001c02 we get the following mappings: - * 001c01, widgetnum 15 = Bus number 0 - * 001c01, widgetnum 14 = Bus number 1 - * 001c02, widgetnum 15 = Bus number 3 - * 001c02, widgetnum 14 = Bus number 4 - * etc. - * - * The rational for starting Bus Number 0 with Widget number 15 is because - * the system boot disks are always connected via Widget 15 Slot 0 of the - * I-brick. Linux creates /dev/sd* devices(naming) strating from Bus Number 0 - * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest - * module id(Master Cnode) of the system. - * - */ -static int -pci_bus_map_create(devfs_handle_t xtalk) -{ - - devfs_handle_t master_node_vertex = NULL; - devfs_handle_t xwidget = NULL; - devfs_handle_t pci_bus = NULL; - hubinfo_t hubinfo = NULL; - xwidgetnum_t widgetnum; - char pathname[128]; - graph_error_t rv; - - /* - * Loop throught this vertex and get the Xwidgets .. - */ - for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) { -#if 0 - { - int pos; - char dname[256]; - pos = devfs_generate_path(xtalk, dname, 256); - printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); - } -#endif - - sprintf(pathname, "%d", widgetnum); - xwidget = NULL; - - /* - * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget - * /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device - */ - rv = hwgraph_traverse(xtalk, pathname, &xwidget); - if ( (rv != GRAPH_SUCCESS) ) { - if (!xwidget) - continue; - } - - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); - pci_bus = NULL; - if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) - if (!pci_bus) - continue; - - /* - * Assign the correct bus number and also the nasid of this - * pci Xwidget. - * - * Should not be any race here ... - */ - num_bridges++; - busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus; - - /* - * Get the master node and from there get the NASID. - */ - master_node_vertex = device_master_get(xwidget); - if (!master_node_vertex) { - printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget); - } - - hubinfo_get(master_node_vertex, &hubinfo); - if (!hubinfo) { - printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex); - return(1); - } else { - busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; - } - - /* - * Pre assign DMA maps needed for 32 Bits Page Map DMA. - */ - busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc( - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); - if (!busnum_to_atedmamaps[num_bridges - 1]) - printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); - - memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); - - } - - return(0); -} - -/* - * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure - * initialization has completed to set up the mappings between Xbridge - * and logical pci bus numbers. We also set up the NASID for each of these - * xbridges. - * - * Must be called before pci_init() is invoked. - */ -int -pci_bus_to_hcl_cvlink(void) -{ - - devfs_handle_t devfs_hdl = NULL; - devfs_handle_t xtalk = NULL; - int rv = 0; - char name[256]; - int master_iobrick; - int i; - - /* - * Iterate throught each xtalk links in the system .. - * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 - * - * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15 - * - * What if it is not pci? - */ - devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module"); - - /* - * To provide consistent(not persistent) device naming, we need to start - * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 - * with an attached I-Brick. Find the master_iobrick. - */ - master_iobrick = -1; - for (i = 0; i < nummodules; i++) { - moduleid_t iobrick_id; - iobrick_id = iobrick_module_get(&modules[i]->elsc); - if (iobrick_id > 0) { /* Valid module id */ - if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) { - master_iobrick = i; - break; - } - } - } - - /* - * The master_iobrick gets bus 0 and 1. - */ - if (master_iobrick >= 0) { - memset(name, 0, 256); - format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF); - strcat(name, "/node/xtalk"); - xtalk = NULL; - rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); - pci_bus_map_create(xtalk); - } - - /* - * Now go do the rest of the modules, starting from the C-Brick with the lowest - * module id, remembering to skip the master_iobrick, which was done above. - */ - for (i = 0; i < nummodules; i++) { - if (i == master_iobrick) { - continue; /* Did the master_iobrick already. */ - } - - memset(name, 0, 256); - format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF); - strcat(name, "/node/xtalk"); - xtalk = NULL; - rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); - pci_bus_map_create(xtalk); - } - - return(0); -} diff -urN linux-2.4.21/arch/ia64/sn/io/pci_dma.c linux-2.4.22/arch/ia64/sn/io/pci_dma.c --- linux-2.4.21/arch/ia64/sn/io/pci_dma.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/pci_dma.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,700 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000,2002 Silicon Graphics, Inc. All rights reserved. - * - * Routines for PCI DMA mapping. See Documentation/DMA-mapping.txt for - * a description of how these routines should be used. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * For ATE allocations - */ -pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t); -void free_pciio_dmamap(pcibr_dmamap_t); -static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char); - -/* - * Toplogy stuff - */ -extern devfs_handle_t busnum_to_pcibr_vhdl[]; -extern nasid_t busnum_to_nid[]; -extern void * busnum_to_atedmamaps[]; - -/** - * get_free_pciio_dmamap - find and allocate an ATE - * @pci_bus: PCI bus to get an entry for - * - * Finds and allocates an ATE on the PCI bus specified - * by @pci_bus. - */ -pciio_dmamap_t -get_free_pciio_dmamap(devfs_handle_t pci_bus) -{ - int i; - struct sn_dma_maps_s *sn_dma_map = NULL; - - /* - * Darn, we need to get the maps allocated for this bus. - */ - for (i = 0; i < MAX_PCI_XWIDGET; i++) { - if (busnum_to_pcibr_vhdl[i] == pci_bus) { - sn_dma_map = busnum_to_atedmamaps[i]; - } - } - - /* - * Now get a free dmamap entry from this list. - */ - for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) { - if (!sn_dma_map->dma_addr) { - sn_dma_map->dma_addr = -1; - return( (pciio_dmamap_t) sn_dma_map ); - } - } - - return NULL; -} - -/** - * free_pciio_dmamap - free an ATE - * @dma_map: ATE to free - * - * Frees the ATE specified by @dma_map. - */ -void -free_pciio_dmamap(pcibr_dmamap_t dma_map) -{ - struct sn_dma_maps_s *sn_dma_map; - - sn_dma_map = (struct sn_dma_maps_s *) dma_map; - sn_dma_map->dma_addr = 0; -} - -/** - * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum - * @dma_addr: DMA address to look for - * @busnum: PCI bus to look on - * - * Finds the ATE associated with @dma_addr and @busnum. - */ -static struct sn_dma_maps_s * -find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum) -{ - - struct sn_dma_maps_s *sn_dma_map = NULL; - int i; - - sn_dma_map = busnum_to_atedmamaps[busnum]; - - for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) { - if (sn_dma_map->dma_addr == dma_addr) { - return sn_dma_map; - } - } - - return NULL; -} - -/** - * sn_dma_sync - try to flush DMA buffers into the coherence domain - * @hwdev: device to flush - * - * This routine flushes all DMA buffers for the device into the II of - * the destination hub. - * - * NOTE!: this does not mean that the data is in the "coherence domain", - * but it is very close. In other words, this routine *does not work* - * as advertised due to hardware bugs. That said, it should be good enough for - * most situations. - */ -void -sn_dma_sync(struct pci_dev *hwdev) -{ - -#ifdef SN_DMA_SYNC - - struct sn_device_sysdata *device_sysdata; - volatile unsigned long dummy; - - /* - * A DMA sync is supposed to ensure that - * all the DMA from a particular device - * is complete and coherent. We - * try to do this by - * 1. flushing the write wuffers from Bridge - * 2. flushing the Xbow port. - * Unfortunately, this only gets the DMA transactions 'very close' to - * the coherence domain, but not quite in it. - */ - device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata; - dummy = (volatile unsigned long ) *device_sysdata->dma_buf_sync; - - /* - * For the Xbow port flush, we may be denied the request because - * someone else may be flushing the port .. try again. - */ - while((volatile unsigned long ) *device_sysdata->xbow_buf_sync) { - udelay(2); - } -#endif -} - -/** - * sn_pci_alloc_consistent - allocate memory for coherent DMA - * @hwdev: device to allocate for - * @size: size of the region - * @dma_handle: DMA (bus) address - * - * pci_alloc_consistent() returns a pointer to a memory region suitable for - * coherent DMA traffic to/from a PCI device. On SN platforms, this means - * that @dma_handle will have the %PCIIO_DMA_CMD flag set. - * - * This interface is usually used for "command" streams (e.g. the command - * queue for a SCSI controller). See Documentation/DMA-mapping.txt for - * more information. Note that this routine will always put a 32 bit - * DMA address into @dma_handle. This is because most devices - * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_ - * DMAs, and unfortunately this interface has to cater to the LCD. Oh well. - * - * Also known as platform_pci_alloc_consistent() by the IA64 machvec code. - */ -void * -sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) -{ - void *cpuaddr; - devfs_handle_t vhdl; - struct sn_device_sysdata *device_sysdata; - unsigned long phys_addr; - pciio_dmamap_t dma_map = 0; - struct sn_dma_maps_s *sn_dma_map; - - *dma_handle = 0; - - /* We can't easily support < 32 bit devices */ - if (IS_PCI32L(hwdev)) - return NULL; - - /* - * Get hwgraph vertex for the device - */ - device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata; - vhdl = device_sysdata->vhdl; - - /* - * Allocate the memory. FIXME: if we're allocating for - * two devices on the same bus, we should at least try to - * allocate memory in the same 2 GB window to avoid using - * ATEs for the translation. See the comment above about the - * 32 bit requirement for this function. - */ - if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)))) - return NULL; - - memset(cpuaddr, 0, size); /* have to zero it out */ - - /* physical addr. of the memory we just got */ - phys_addr = __pa(cpuaddr); - - /* - * This will try to use a Direct Map register to do the - * 32 bit DMA mapping, but it may not succeed if another - * device on the same bus is already mapped with different - * attributes or to a different memory region. - */ -#ifdef CONFIG_IA64_SGI_SN1 - *dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, - PCIIO_BYTE_STREAM | - PCIIO_DMA_CMD); -#elif defined(CONFIG_IA64_SGI_SN2) - *dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_CMD); -#else -#error unsupported platform -#endif - - /* - * It is a 32 bit card and we cannot do direct mapping, - * so we try to use an ATE. - */ - if (!(*dma_handle)) { -#ifdef CONFIG_IA64_SGI_SN1 - dma_map = pciio_dmamap_alloc(vhdl, NULL, size, - PCIIO_BYTE_STREAM | - PCIIO_DMA_CMD); -#elif defined(CONFIG_IA64_SGI_SN2) - dma_map = pciio_dmamap_alloc(vhdl, NULL, size, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_CMD); -#else -#error unsupported platform -#endif - if (!dma_map) { - printk(KERN_ERR "sn_pci_alloc_consistent: Unable to " - "allocate anymore 32 bit page map entries.\n"); - BUG(); - } - *dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr, - size); - sn_dma_map = (struct sn_dma_maps_s *)dma_map; - sn_dma_map->dma_addr = *dma_handle; - } - - return cpuaddr; -} - -/** - * sn_pci_free_consistent - free memory associated with coherent DMAable region - * @hwdev: device to free for - * @size: size to free - * @vaddr: kernel virtual address to free - * @dma_handle: DMA address associated with this region - * - * Frees the memory allocated by pci_alloc_consistent(). Also known - * as platform_pci_free_consistent() by the IA64 machvec code. - */ -void -sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) -{ - struct sn_dma_maps_s *sn_dma_map = NULL; - - /* - * Get the sn_dma_map entry. - */ - if (IS_PCI32_MAPPED(dma_handle)) - sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number); - - /* - * and free it if necessary... - */ - if (sn_dma_map) { - pciio_dmamap_done((pciio_dmamap_t)sn_dma_map); - pciio_dmamap_free((pciio_dmamap_t)sn_dma_map); - sn_dma_map->dma_addr = (dma_addr_t)NULL; - } - free_pages((unsigned long) vaddr, get_order(size)); -} - -/** - * sn_pci_map_sg - map a scatter-gather list for DMA - * @hwdev: device to map for - * @sg: scatterlist to map - * @nents: number of entries - * @direction: direction of the DMA transaction - * - * Maps each entry of @sg for DMA. Also known as platform_pci_map_sg by the - * IA64 machvec code. - */ -int -sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) -{ - - int i; - devfs_handle_t vhdl; - dma_addr_t dma_addr; - unsigned long phys_addr; - struct sn_device_sysdata *device_sysdata; - pciio_dmamap_t dma_map; - - /* can't go anywhere w/o a direction in life */ - if (direction == PCI_DMA_NONE) - BUG(); - - /* - * Get the hwgraph vertex for the device - */ - device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata; - vhdl = device_sysdata->vhdl; - - /* - * Setup a DMA address for each entry in the - * scatterlist. - */ - for (i = 0; i < nents; i++, sg++) { - /* this catches incorrectly written drivers that - attempt to map scatterlists that they have - previously mapped. we print a warning and - continue, but the driver should be fixed */ - switch (((u64)sg->address) >> 60) { - case 0xa: - case 0xb: -#ifdef DEBUG -/* This needs to be cleaned up at some point. */ - NAG("A PCI driver (for device at%8s) has attempted to " - "map a scatterlist that was previously mapped at " - "%p - this is currently being worked around.\n", - hwdev->slot_name, (void *)sg->address); -#endif - phys_addr = (u64)sg->address & TO_PHYS_MASK; - break; - default: /* not previously mapped, get the phys. addr */ - phys_addr = __pa(sg->address); - break; - } - sg->page = NULL; - dma_addr = 0; - - /* - * Handle the most common case: 64 bit cards. This - * call should always succeed. - */ - if (IS_PCIA64(hwdev)) { - dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, - sg->length, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_DATA | - PCIIO_DMA_A64); - sg->address = (char *)dma_addr; - continue; - } - - /* - * Handle 32-63 bit cards via direct mapping - */ - if (IS_PCI32G(hwdev)) { -#ifdef CONFIG_IA64_SGI_SN1 - dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, - sg->length, - PCIIO_BYTE_STREAM | - PCIIO_DMA_DATA); -#elif defined(CONFIG_IA64_SGI_SN2) - dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, - sg->length, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_DATA); -#else -#error unsupported platform -#endif - /* - * See if we got a direct map entry - */ - if (dma_addr) { - sg->address = (char *)dma_addr; - continue; - } - - } - - /* - * It is a 32 bit card and we cannot do direct mapping, - * so we use an ATE. - */ - dma_map = 0; -#ifdef CONFIG_IA64_SGI_SN1 - dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, - PCIIO_BYTE_STREAM | - PCIIO_DMA_DATA); -#elif defined(CONFIG_IA64_SGI_SN2) - dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_DATA); -#else -#error unsupported platform -#endif - if (!dma_map) { - printk(KERN_ERR "sn_pci_map_sg: Unable to allocate " - "anymore 32 bit page map entries.\n"); - BUG(); - } - dma_addr = pciio_dmamap_addr(dma_map, phys_addr, sg->length); - sg->address = (char *)dma_addr; - sg->page = (struct page *)dma_map; - - } - - return nents; - -} - -/** - * sn_pci_unmap_sg - unmap a scatter-gather list - * @hwdev: device to unmap - * @sg: scatterlist to unmap - * @nents: number of scatterlist entries - * @direction: DMA direction - * - * Unmap a set of streaming mode DMA translations. Again, cpu read rules - * concerning calls here are the same as for pci_unmap_single() below. Also - * known as sn_pci_unmap_sg() by the IA64 machvec code. - */ -void -sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) -{ - int i; - struct sn_dma_maps_s *sn_dma_map; - - /* can't go anywhere w/o a direction in life */ - if (direction == PCI_DMA_NONE) - BUG(); - - for (i = 0; i < nents; i++, sg++) - if (sg->page) { - /* - * We maintain the DMA Map pointer in sg->page if - * it is ever allocated. - */ - sg->address = 0; - sn_dma_map = (struct sn_dma_maps_s *)sg->page; - pciio_dmamap_done((pciio_dmamap_t)sn_dma_map); - pciio_dmamap_free((pciio_dmamap_t)sn_dma_map); - sn_dma_map->dma_addr = 0; - sg->page = 0; - } - -} - -/** - * sn_pci_map_single - map a single region for DMA - * @hwdev: device to map for - * @ptr: kernel virtual address of the region to map - * @size: size of the region - * @direction: DMA direction - * - * Map the region pointed to by @ptr for DMA and return the - * DMA address. Also known as platform_pci_map_single() by - * the IA64 machvec code. - * - * We map this to the one step pciio_dmamap_trans interface rather than - * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have - * no way of saving the dmamap handle from the alloc to later free - * (which is pretty much unacceptable). - * - * TODO: simplify our interface; - * get rid of dev_desc and vhdl (seems redundant given a pci_dev); - * figure out how to save dmamap handle so can use two step. - */ -dma_addr_t -sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) -{ - devfs_handle_t vhdl; - dma_addr_t dma_addr; - unsigned long phys_addr; - struct sn_device_sysdata *device_sysdata; - pciio_dmamap_t dma_map = NULL; - struct sn_dma_maps_s *sn_dma_map; - - if (direction == PCI_DMA_NONE) - BUG(); - - /* SN cannot support DMA addresses smaller than 32 bits. */ - if (IS_PCI32L(hwdev)) - return 0; - - /* - * find vertex for the device - */ - device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata; - vhdl = device_sysdata->vhdl; - - /* - * Call our dmamap interface - */ - dma_addr = 0; - phys_addr = __pa(ptr); - - if (IS_PCIA64(hwdev)) { - /* This device supports 64 bit DMA addresses. */ - dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_DATA | - PCIIO_DMA_A64); - return dma_addr; - } - - /* - * Devices that support 32 bit to 63 bit DMA addresses get - * 32 bit DMA addresses. - * - * First try to get a 32 bit direct map register. - */ - if (IS_PCI32G(hwdev)) { -#ifdef CONFIG_IA64_SGI_SN1 - dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, - PCIIO_BYTE_STREAM | - PCIIO_DMA_DATA); -#elif defined(CONFIG_IA64_SGI_SN2) - dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_DATA); -#else -#error unsupported platform -#endif - if (dma_addr) - return dma_addr; - } - - /* - * It's a 32 bit card and we cannot do direct mapping so - * let's use the PMU instead. - */ - dma_map = NULL; -#ifdef CONFIG_IA64_SGI_SN1 - dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_BYTE_STREAM | - PCIIO_DMA_DATA); -#elif defined(CONFIG_IA64_SGI_SN2) - dma_map = pciio_dmamap_alloc(vhdl, NULL, size, - ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) | - PCIIO_DMA_DATA); -#else -#error unsupported platform -#endif - - if (!dma_map) { - printk(KERN_ERR "pci_map_single: Unable to allocate anymore " - "32 bit page map entries.\n"); - BUG(); - } - - dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size); - sn_dma_map = (struct sn_dma_maps_s *)dma_map; - sn_dma_map->dma_addr = dma_addr; - - return ((dma_addr_t)dma_addr); -} - -/** - * sn_pci_unmap_single - unmap a region used for DMA - * @hwdev: device to unmap - * @dma_addr: DMA address to unmap - * @size: size of region - * @direction: DMA direction - * - * Unmaps the region pointed to by @dma_addr. Also known as - * platform_pci_unmap_single() by the IA64 machvec code. - */ -void -sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) -{ - struct sn_dma_maps_s *sn_dma_map = NULL; - - if (direction == PCI_DMA_NONE) - BUG(); - - /* - * Get the sn_dma_map entry. - */ - if (IS_PCI32_MAPPED(dma_addr)) - sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number); - - /* - * and free it if necessary... - */ - if (sn_dma_map) { - pciio_dmamap_done((pciio_dmamap_t)sn_dma_map); - pciio_dmamap_free((pciio_dmamap_t)sn_dma_map); - sn_dma_map->dma_addr = (dma_addr_t)NULL; - } -} - -/** - * sn_pci_dma_sync_single - make sure all DMAs have completed - * @hwdev: device to sync - * @dma_handle: DMA address to sync - * @size: size of region - * @direction: DMA direction - * - * This routine is supposed to sync the DMA region specified - * by @dma_handle into the 'coherence domain'. See sn_dma_sync() - * above for more information. Also known as - * platform_pci_dma_sync_single() by the IA64 machvec code. - */ -void -sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - sn_dma_sync(hwdev); -} - -/** - * sn_pci_dma_sync_sg - make sure all DMAs have completed - * @hwdev: device to sync - * @sg: scatterlist to sync - * @nents: number of entries in the scatterlist - * @direction: DMA direction - * - * This routine is supposed to sync the DMA regions specified - * by @sg into the 'coherence domain'. See sn_dma_sync() - * above for more information. Also known as - * platform_pci_dma_sync_sg() by the IA64 machvec code. - */ -void -sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - sn_dma_sync(hwdev); -} - -/** - * sn_dma_address - get the DMA address for the first entry of a scatterlist - * @sg: sg to look at - * - * Gets the DMA address for the scatterlist @sg. Also known as - * platform_dma_address() by the IA64 machvec code. - */ -unsigned long -sn_dma_address(struct scatterlist *sg) -{ - return ((unsigned long)sg->address); -} - -/** - * sn_dma_supported - test a DMA mask - * @hwdev: device to test - * @mask: DMA mask to test - * - * Return whether the given PCI device DMA address mask can be supported - * properly. For example, if your device can only drive the low 24-bits - * during PCI bus mastering, then you would pass 0x00ffffff as the mask to - * this function. Of course, SN only supports devices that have 32 or more - * address bits when using the PMU. We could theoretically support <32 bit - * cards using direct mapping, but we'll worry about that later--on the off - * chance that someone actually wants to use such a card. - */ -int -sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask) -{ - if (mask < 0xffffffff) - return 0; - return 1; -} - -EXPORT_SYMBOL(sn_pci_unmap_single); -EXPORT_SYMBOL(sn_pci_map_single); -EXPORT_SYMBOL(sn_pci_dma_sync_single); -EXPORT_SYMBOL(sn_pci_map_sg); -EXPORT_SYMBOL(sn_pci_unmap_sg); -EXPORT_SYMBOL(sn_pci_alloc_consistent); -EXPORT_SYMBOL(sn_pci_free_consistent); -EXPORT_SYMBOL(sn_dma_address); -EXPORT_SYMBOL(sn_pci_dma_supported); - diff -urN linux-2.4.21/arch/ia64/sn/io/pciba.c linux-2.4.22/arch/ia64/sn/io/pciba.c --- linux-2.4.21/arch/ia64/sn/io/pciba.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/pciba.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,916 +0,0 @@ -/* - * arch/ia64/sn/io/pciba.c - * - * IRIX PCIBA-inspired user mode PCI interface - * - * requires: devfs - * - * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the - * device is on, SS is the slot the device is in, and F is the - * device's function on a multi-function card). - * - * when compiled into the kernel, it will only be initialized by the - * sgi sn1 specific initialization code. in this case, device nodes - * are under /dev/hw/..../ - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file "COPYING" in the main directory of - * this archive for more details. - * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. - * - * 03262001 - Initial version by Chad Talbott - */ - - -/* jesse's beefs: - - register_pci_device should be documented - - grossness with do_swap should be documented - - big, gross union'ized node_data should be replaced with independent - structures - - replace global list of nodes with global lists of resources. could - use object oriented approach of allocating and cleaning up - resources. - -*/ - - -#include -#ifndef CONFIG_DEVFS_FS -# error PCIBA requires devfs -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -MODULE_DESCRIPTION("User mode PCI interface"); -MODULE_AUTHOR("Chad Talbott"); - - -#undef DEBUG_PCIBA -/* #define DEBUG_PCIBA */ - -#undef TRACE_PCIBA -/* #define TRACE_PCIBA */ - -#if defined(DEBUG_PCIBA) -# define DPRINTF(x...) printk(KERN_DEBUG x) -#else -# define DPRINTF(x...) -#endif - -#if defined(TRACE_PCIBA) -# if defined(__GNUC__) -# define TRACE() printk(KERN_DEBUG "%s:%d:%s\n", \ - __FILE__, __LINE__, __FUNCTION__) -# else -# define TRACE() printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__) -# endif -#else -# define TRACE() -#endif - - -typedef enum { failure, success } status; -typedef enum { false, true } boolean; - - -/* major data structures: - - struct node_data - - - one for each file registered with devfs. contains everything - that any file's fops would need to know about. - - struct dma_allocation - - - a single DMA allocation. only the 'dma' nodes care about - these. they are there primarily to allow the driver to look - up the kernel virtual address of dma buffers allocated by - pci_alloc_consistent, as the application is only given the - physical address (to program the device's dma, presumably) and - cannot supply the kernel virtual address when freeing the - buffer. - - it's also useful to maintain a list of buffers allocated - through a specific node to allow some sanity checking by this - driver. this prevents (for example) a broken application from - freeing buffers that it didn't allocate, or buffers allocated - on another node. - - global_node_list - - - a list of all nodes allocated. this allows the driver to free - all the memory it has 'kmalloc'd in case of an error, or on - module removal. - - global_dma_list - - - a list of all dma buffers allocated by this driver. this - allows the driver to 'pci_free_consistent' all buffers on - module removal or error. - -*/ - - -struct node_data { - /* flat list of all the device nodes. makes it easy to free - them all when we're unregistered */ - struct list_head global_node_list; - devfs_handle_t devfs_handle; - - void (* cleanup)(struct node_data *); - - union { - struct { - struct pci_dev * dev; - struct list_head dma_allocs; - boolean mmapped; - } dma; - struct { - struct pci_dev * dev; - u32 saved_rom_base_reg; - boolean mmapped; - } rom; - struct { - struct resource * res; - } base; - struct { - struct pci_dev * dev; - } config; - } u; -}; - -struct dma_allocation { - struct list_head list; - - dma_addr_t handle; - void * va; - size_t size; -}; - - -static LIST_HEAD(global_node_list); -static LIST_HEAD(global_dma_list); - - -/* module entry points */ -int __init pciba_init(void); -void __exit pciba_exit(void); - -static status __init register_with_devfs(void); -static void __exit unregister_with_devfs(void); - -static status __init register_pci_device(devfs_handle_t device_dir_handle, - struct pci_dev * dev); - -/* file operations */ -static int generic_open(struct inode * inode, struct file * file); -static int rom_mmap(struct file * file, struct vm_area_struct * vma); -static int rom_release(struct inode * inode, struct file * file); -static int base_mmap(struct file * file, struct vm_area_struct * vma); -static int config_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, - unsigned long arg); -static int dma_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, - unsigned long arg); -static int dma_mmap(struct file * file, struct vm_area_struct * vma); - -/* support routines */ -static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va); -static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va); - -#ifdef DEBUG_PCIBA -static void dump_nodes(struct list_head * nodes); -static void dump_allocations(struct list_head * dalp); -#endif - -/* file operations for each type of node */ -static struct file_operations rom_fops = { - owner: THIS_MODULE, - mmap: rom_mmap, - open: generic_open, - release: rom_release -}; - - -static struct file_operations base_fops = { - owner: THIS_MODULE, - mmap: base_mmap, - open: generic_open -}; - - -static struct file_operations config_fops = { - owner: THIS_MODULE, - ioctl: config_ioctl, - open: generic_open -}; - -static struct file_operations dma_fops = { - owner: THIS_MODULE, - ioctl: dma_ioctl, - mmap: dma_mmap, - open: generic_open -}; - - -module_init(pciba_init); -module_exit(pciba_exit); - - -int __init -pciba_init(void) -{ - TRACE(); - - if (register_with_devfs() == failure) - return 1; /* failure */ - - printk("PCIBA (a user mode PCI interface) initialized.\n"); - - return 0; /* success */ -} - - -void __exit -pciba_exit(void) -{ - TRACE(); - - /* FIXME: should also free all that memory that we allocated - ;) */ - unregister_with_devfs(); -} - - -# if 0 -static void __exit -free_nodes(void) -{ - struct node_data * nd; - - TRACE(); - - list_for_each(nd, &node_list) { - kfree(list_entry(nd, struct nd, node_list)); - } -} -#endif - - -static devfs_handle_t pciba_devfs_handle; - - -extern devfs_handle_t -devfn_to_vertex(unsigned char busnum, unsigned int devfn); - -static status __init -register_with_devfs(void) -{ - struct pci_dev * dev; - devfs_handle_t device_dir_handle; - - TRACE(); - - /* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */ - - pci_for_each_dev(dev) { - device_dir_handle = devfn_to_vertex(dev->bus->number, - dev->devfn); - if (device_dir_handle == NULL) - return failure; - - if (register_pci_device(device_dir_handle, dev) == failure) { - devfs_unregister(pciba_devfs_handle); - return failure; - } - } - - return success; -} - -static void __exit -unregister_with_devfs(void) -{ - struct list_head * lhp; - struct node_data * nd; - - TRACE(); - - list_for_each(lhp, &global_node_list) { - nd = list_entry(lhp, struct node_data, global_node_list); - devfs_unregister(nd->devfs_handle); - } - -} - - -struct node_data * new_node(void) -{ - struct node_data * node; - - TRACE(); - - node = kmalloc(sizeof(struct node_data), GFP_KERNEL); - if (node == NULL) - return NULL; - list_add(&node->global_node_list, &global_node_list); - return node; -} - - -void dma_cleanup(struct node_data * dma_node) -{ - TRACE(); - - /* FIXME: should free these allocations */ -#ifdef DEBUG_PCIBA - dump_allocations(&dma_node->u.dma.dma_allocs); -#endif - devfs_unregister(dma_node->devfs_handle); -} - - -void init_dma_node(struct node_data * node, - struct pci_dev * dev, devfs_handle_t dh) -{ - TRACE(); - - node->devfs_handle = dh; - node->u.dma.dev = dev; - node->cleanup = dma_cleanup; - INIT_LIST_HEAD(&node->u.dma.dma_allocs); -} - - -void rom_cleanup(struct node_data * rom_node) -{ - TRACE(); - - if (rom_node->u.rom.mmapped) - pci_write_config_dword(rom_node->u.rom.dev, - PCI_ROM_ADDRESS, - rom_node->u.rom.saved_rom_base_reg); - devfs_unregister(rom_node->devfs_handle); -} - - -void init_rom_node(struct node_data * node, - struct pci_dev * dev, devfs_handle_t dh) -{ - TRACE(); - - node->devfs_handle = dh; - node->u.rom.dev = dev; - node->cleanup = rom_cleanup; - node->u.rom.mmapped = false; -} - - -static status __init -register_pci_device(devfs_handle_t device_dir_handle, struct pci_dev * dev) -{ - struct node_data * nd; - char devfs_path[20]; - devfs_handle_t node_devfs_handle; - int ri; - - TRACE(); - - - /* register nodes for all the device's base address registers */ - for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) { - if (pci_resource_len(dev, ri) != 0) { - sprintf(devfs_path, "base/%d", ri); - if (devfs_register(device_dir_handle, devfs_path, - DEVFS_FL_NONE, - 0, 0, - S_IFREG | S_IRUSR | S_IWUSR, - &base_fops, - &dev->resource[ri]) == NULL) - return failure; - } - } - - /* register a node corresponding to the first MEM resource on - the device */ - for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) { - if (dev->resource[ri].flags & IORESOURCE_MEM && - pci_resource_len(dev, ri) != 0) { - if (devfs_register(device_dir_handle, "mem", - DEVFS_FL_NONE, 0, 0, - S_IFREG | S_IRUSR | S_IWUSR, - &base_fops, - &dev->resource[ri]) == NULL) - return failure; - break; - } - } - - /* also register a node corresponding to the first IO resource - on the device */ - for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) { - if (dev->resource[ri].flags & IORESOURCE_IO && - pci_resource_len(dev, ri) != 0) { - if (devfs_register(device_dir_handle, "io", - DEVFS_FL_NONE, 0, 0, - S_IFREG | S_IRUSR | S_IWUSR, - &base_fops, - &dev->resource[ri]) == NULL) - return failure; - break; - } - } - - /* register a node corresponding to the device's ROM resource, - if present */ - if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) { - nd = new_node(); - if (nd == NULL) - return failure; - node_devfs_handle = devfs_register(device_dir_handle, "rom", - DEVFS_FL_NONE, 0, 0, - S_IFREG | S_IRUSR, - &rom_fops, nd); - if (node_devfs_handle == NULL) - return failure; - init_rom_node(nd, dev, node_devfs_handle); - } - - /* register a node that allows ioctl's to read and write to - the device's config space */ - if (devfs_register(device_dir_handle, "config", DEVFS_FL_NONE, - 0, 0, S_IFREG | S_IRUSR | S_IWUSR, - &config_fops, dev) == NULL) - return failure; - - - /* finally, register a node that allows ioctl's to allocate - and free DMA buffers, as well as memory map those - buffers. */ - nd = new_node(); - if (nd == NULL) - return failure; - node_devfs_handle = - devfs_register(device_dir_handle, "dma", DEVFS_FL_NONE, - 0, 0, S_IFREG | S_IRUSR | S_IWUSR, - &dma_fops, nd); - if (node_devfs_handle == NULL) - return failure; - init_dma_node(nd, dev, node_devfs_handle); - -#ifdef DEBUG_PCIBA - dump_nodes(&global_node_list); -#endif - - return success; -} - - -static int -generic_open(struct inode * inode, struct file * file) -{ - TRACE(); - - /* FIXME: should check that they're not trying to open the ROM - writable */ - - return 0; /* success */ -} - - -static int -rom_mmap(struct file * file, struct vm_area_struct * vma) -{ - unsigned long pci_pa; - struct node_data * nd; - - TRACE(); - - nd = (struct node_data * )file->private_data; - - pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE); - - if (!nd->u.rom.mmapped) { - nd->u.rom.mmapped = true; - DPRINTF("Enabling ROM address decoder.\n"); - DPRINTF( -"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n" -"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n"); - pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS, - &nd->u.rom.saved_rom_base_reg); - DPRINTF("ROM base address contains %x\n", - nd->u.rom.saved_rom_base_reg); - pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS, - nd->u.rom.saved_rom_base_reg | - PCI_ROM_ADDRESS_ENABLE); - } - - return mmap_pci_address(vma, pci_pa); -} - - -static int -rom_release(struct inode * inode, struct file * file) -{ - struct node_data * nd; - - TRACE(); - - nd = (struct node_data * )file->private_data; - - if (nd->u.rom.mmapped) { - nd->u.rom.mmapped = false; - DPRINTF("Disabling ROM address decoder.\n"); - pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS, - nd->u.rom.saved_rom_base_reg); - } - return 0; /* indicate success */ -} - - -static int -base_mmap(struct file * file, struct vm_area_struct * vma) -{ - struct resource * resource; - - TRACE(); - - resource = (struct resource *)file->private_data; - - return mmap_pci_address(vma, resource->start); -} - - -static int -config_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, - unsigned long arg) -{ - struct pci_dev * dev; - - union cfg_data { - uint8_t byte; - uint16_t word; - uint32_t dword; - } read_data, write_data; - - int dir, size, offset; - - TRACE(); - - DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", - cmd, - _IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd)); - DPRINTF("arg = %lx\n", arg); - - dev = (struct pci_dev *)file->private_data; - - /* PCIIOCCFG{RD,WR}: read and/or write PCI configuration - space. If both, the read happens first (this becomes a swap - operation, atomic with respect to other updates through - this path). */ - - dir = _IOC_DIR(cmd); - -#define do_swap(suffix, type) \ - do { \ - if (dir & _IOC_READ) { \ - pci_read_config_##suffix(dev, _IOC_NR(cmd), \ - &read_data.suffix); \ - } \ - if (dir & _IOC_WRITE) { \ - get_user(write_data.suffix, (type)arg); \ - pci_write_config_##suffix(dev, _IOC_NR(cmd), \ - write_data.suffix); \ - } \ - if (dir & _IOC_READ) { \ - put_user(read_data.suffix, (type)arg); \ - } \ - } while (0) - - size = _IOC_SIZE(cmd); - offset = _IOC_NR(cmd); - - DPRINTF("sanity check\n"); - if (((size > 0) || (size <= 4)) && - ((offset + size) <= 256) && - (dir & (_IOC_READ | _IOC_WRITE))) { - - switch (size) - { - case 1: - do_swap(byte, uint8_t *); - break; - case 2: - do_swap(word, uint16_t *); - break; - case 4: - do_swap(dword, uint32_t *); - break; - default: - DPRINTF("invalid ioctl\n"); - return -EINVAL; - } - } else - return -EINVAL; - - return 0; -} - - -#ifdef DEBUG_PCIBA -static void -dump_allocations(struct list_head * dalp) -{ - struct dma_allocation * dap; - struct list_head * p; - - printk("{\n"); - list_for_each(p, dalp) { - dap = list_entry(p, struct dma_allocation, - list); - printk(" handle = %lx, va = %p\n", - dap->handle, dap->va); - } - printk("}\n"); -} - -static void -dump_nodes(struct list_head * nodes) -{ - struct node_data * ndp; - struct list_head * p; - - printk("{\n"); - list_for_each(p, nodes) { - ndp = list_entry(p, struct node_data, - global_node_list); - printk(" %p\n", (void *)ndp); - } - printk("}\n"); -} - - -#if 0 -#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) - -static void -test_list(void) -{ - u64 i; - LIST_HEAD(the_list); - - for (i = 0; i < 5; i++) { - struct dma_allocation * new_alloc; - NEW(new_alloc); - new_alloc->va = (void *)i; - new_alloc->handle = 5*i; - printk("%d - the_list->next = %lx\n", i, the_list.next); - list_add(&new_alloc->list, &the_list); - } - dump_allocations(&the_list); -} -#endif -#endif - - -static LIST_HEAD(dma_buffer_list); - - -static int -dma_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, - unsigned long arg) -{ - struct node_data * nd; - uint64_t argv; - int result; - struct dma_allocation * dma_alloc; - struct list_head * iterp; - - TRACE(); - - DPRINTF("cmd = %x\n", cmd); - DPRINTF("arg = %lx\n", arg); - - nd = (struct node_data *)file->private_data; - -#ifdef DEBUG_PCIBA - DPRINTF("at dma_ioctl entry\n"); - dump_allocations(&nd->u.dma.dma_allocs); -#endif - - switch (cmd) { - case PCIIOCDMAALLOC: - /* PCIIOCDMAALLOC: allocate a chunk of physical memory - and set it up for DMA. Return the PCI address that - gets to it. */ - DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC); - - if ( (result = get_user(argv, (uint64_t *)arg)) ) - return result; - DPRINTF("argv (size of buffer) = %lx\n", argv); - - dma_alloc = (struct dma_allocation *) - kmalloc(sizeof(struct dma_allocation), GFP_KERNEL); - if (dma_alloc == NULL) - return -ENOMEM; - - dma_alloc->size = (size_t)argv; - dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev, - dma_alloc->size, - &dma_alloc->handle); - DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n", - dma_alloc->va, dma_alloc->handle); - if (dma_alloc->va == NULL) { - kfree(dma_alloc); - return -ENOMEM; - } - - list_add(&dma_alloc->list, &nd->u.dma.dma_allocs); - if ( (result = put_user((uint64_t)dma_alloc->handle, - (uint64_t *)arg)) ) { - DPRINTF("put_user failed\n"); - pci_free_consistent(nd->u.dma.dev, (size_t)argv, - dma_alloc->va, dma_alloc->handle); - kfree(dma_alloc); - return result; - } - -#ifdef DEBUG_PCIBA - DPRINTF("after insertion\n"); - dump_allocations(&nd->u.dma.dma_allocs); -#endif - break; - - case PCIIOCDMAFREE: - DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE); - - if ( (result = get_user(argv, (uint64_t *)arg)) ) { - DPRINTF("get_user failed\n"); - return result; - } - - DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv); - list_for_each(iterp, &nd->u.dma.dma_allocs) { - struct dma_allocation * da = - list_entry(iterp, struct dma_allocation, list); - if (da->handle == argv) { - pci_free_consistent(nd->u.dma.dev, da->size, - da->va, da->handle); - list_del(&da->list); - kfree(da); -#ifdef DEBUG_PCIBA - DPRINTF("after deletion\n"); - dump_allocations(&nd->u.dma.dma_allocs); -#endif - return 0; /* success */ - } - } - /* previously allocated dma buffer wasn't found */ - DPRINTF("attempt to free invalid dma handle\n"); - return -EINVAL; - - default: - DPRINTF("undefined ioctl\n"); - return -EINVAL; - } - - DPRINTF("success\n"); - return 0; -} - - -static int -dma_mmap(struct file * file, struct vm_area_struct * vma) -{ - struct node_data * nd; - struct list_head * iterp; - int result; - - TRACE(); - - nd = (struct node_data *)file->private_data; - - DPRINTF("vma->vm_start is %lx\n", vma->vm_start); - DPRINTF("vma->vm_end is %lx\n", vma->vm_end); - DPRINTF("offset = %lx\n", vma->vm_pgoff); - - /* get kernel virtual address for the dma buffer (necessary - * for the mmap). */ - list_for_each(iterp, &nd->u.dma.dma_allocs) { - struct dma_allocation * da = - list_entry(iterp, struct dma_allocation, list); - /* why does mmap shift its offset argument? */ - if (da->handle == vma->vm_pgoff << PAGE_SHIFT) { - DPRINTF("found dma handle\n"); - if ( (result = mmap_kernel_address(vma, - da->va)) ) { - return result; /* failure */ - } else { - /* it seems like at least one of these - should show up in user land.... - I'm missing something */ - *(char *)da->va = 0xaa; - strncpy(da->va, " Toastie!", da->size); - if (put_user(0x18badbeeful, - (u64 *)vma->vm_start)) - DPRINTF("put_user failed?!\n"); - return 0; /* success */ - } - - } - } - DPRINTF("attempt to mmap an invalid dma handle\n"); - return -EINVAL; -} - - -static int -mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va) -{ - unsigned long pci_pa; - - TRACE(); - - DPRINTF("vma->vm_start is %lx\n", vma->vm_start); - DPRINTF("vma->vm_end is %lx\n", vma->vm_end); - - /* the size of the vma doesn't necessarily correspond to the - size specified in the mmap call. So we can't really do any - kind of sanity check here. This is a dangerous driver, and - it's very easy for a user process to kill the machine. */ - - DPRINTF("PCI base at virtual address %lx\n", pci_va); - /* the __pa macro is intended for region 7 on IA64, so it - doesn't work for region 6 */ - /* pci_pa = __pa(pci_va); */ - /* should be replaced by __tpa or equivalent (preferably a - generic equivalent) */ - pci_pa = pci_va & ~0xe000000000000000ul; - DPRINTF("PCI base at physical address %lx\n", pci_pa); - - /* there are various arch-specific versions of this function - defined in linux/drivers/char/mem.c, but it would be nice - if all architectures put it in pgtable.h. it's defined - there for ia64.... */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO; - - return io_remap_page_range(vma->vm_start, pci_pa, - vma->vm_end-vma->vm_start, - vma->vm_page_prot); -} - - -static int -mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va) -{ - unsigned long kernel_pa; - - TRACE(); - - DPRINTF("vma->vm_start is %lx\n", vma->vm_start); - DPRINTF("vma->vm_end is %lx\n", vma->vm_end); - - /* the size of the vma doesn't necessarily correspond to the - size specified in the mmap call. So we can't really do any - kind of sanity check here. This is a dangerous driver, and - it's very easy for a user process to kill the machine. */ - - DPRINTF("mapping virtual address %p\n", kernel_va); - kernel_pa = __pa(kernel_va); - DPRINTF("mapping physical address %lx\n", kernel_pa); - - vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO; - - return remap_page_range(vma->vm_start, kernel_pa, - vma->vm_end-vma->vm_start, - vma->vm_page_prot); -} diff -urN linux-2.4.21/arch/ia64/sn/io/pciio.c linux-2.4.22/arch/ia64/sn/io/pciio.c --- linux-2.4.21/arch/ia64/sn/io/pciio.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/pciio.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1511 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#define USRPCI 0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* Must be before iograph.h to get MAX_PORT_NUM */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_PCIIO -#undef DEBUG_PCIIO /* turn this on for yet more console output */ - - -#define GET_NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DO_DEL(ptr) (kfree(ptr)) - -char pciio_info_fingerprint[] = "pciio_info"; - -cdl_p pciio_registry = NULL; - -int -badaddr_val(volatile void *addr, int len, volatile void *ptr) -{ - int ret = 0; - volatile void *new_addr; - - switch (len) { - case 4: -#ifdef CONFIG_IA64_SGI_SN1 - new_addr = (void *)(((u64) addr)^4); -#else - new_addr = (void *) addr; -#endif - ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr); - break; - default: - printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len); - } - - if (ret < 0) - panic("badaddr_val: unexpected status (%d) in probing", ret); - return(ret); - -} - - -nasid_t -get_console_nasid(void) -{ - extern nasid_t console_nasid; - if (console_nasid < 0) { - console_nasid = ia64_sn_get_console_nasid(); - if (console_nasid < 0) { -// ZZZ What do we do if we don't get a console nasid on the hardware???? - if (IS_RUNNING_ON_SIMULATOR() ) - console_nasid = master_nasid; - } - } - return console_nasid; -} - -int -hub_dma_enabled(devfs_handle_t xconn_vhdl) -{ - return(0); -} - -int -hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) -{ - return(0); -} - -void -ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror) -{ -} - -/****** - ****** end hack defines ...... - ******/ - - - - -/* ===================================================================== - * PCI Generic Bus Provider - * Implement PCI provider operations. The pciio* layer provides a - * platform-independent interface for PCI devices. This layer - * switches among the possible implementations of a PCI adapter. - */ - -/* ===================================================================== - * Provider Function Location SHORTCUT - * - * On platforms with only one possible PCI provider, macros can be - * set up at the top that cause the table lookups and indirections to - * completely disappear. - */ - -#if defined(CONFIG_IA64_SGI_SN1) -/* - * For the moment, we will assume that IP27 - * only use Bridge ASICs to provide PCI support. - */ -#include -#define DEV_FUNC(dev,func) pcibr_##func -#define CAST_PIOMAP(x) ((pcibr_piomap_t)(x)) -#define CAST_DMAMAP(x) ((pcibr_dmamap_t)(x)) -#define CAST_INTR(x) ((pcibr_intr_t)(x)) -#endif /* CONFIG_IA64_SGI_SN1 */ - -/* ===================================================================== - * Function Table of Contents - */ - -#if !defined(DEV_FUNC) -static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev); -#endif - -pciio_piomap_t pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); -void pciio_piomap_free(pciio_piomap_t); -caddr_t pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t); - -void pciio_piomap_done(pciio_piomap_t); -caddr_t pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); -caddr_t pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned); - -iopaddr_t pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); -void pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); - -pciio_dmamap_t pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); -void pciio_dmamap_free(pciio_dmamap_t); -iopaddr_t pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t); -alenlist_t pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned); -void pciio_dmamap_done(pciio_dmamap_t); -iopaddr_t pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); -void pciio_dmamap_drain(pciio_dmamap_t); -void pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); -void pciio_dmalist_drain(devfs_handle_t, alenlist_t); -iopaddr_t pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned); - -pciio_intr_t pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); -void pciio_intr_free(pciio_intr_t); -int pciio_intr_connect(pciio_intr_t); -void pciio_intr_disconnect(pciio_intr_t); -devfs_handle_t pciio_intr_cpu_get(pciio_intr_t); - -void pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t); - -void pciio_provider_startup(devfs_handle_t); -void pciio_provider_shutdown(devfs_handle_t); - -pciio_endian_t pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); -pciio_priority_t pciio_priority_set(devfs_handle_t, pciio_priority_t); -devfs_handle_t pciio_intr_dev_get(pciio_intr_t); - -devfs_handle_t pciio_pio_dev_get(pciio_piomap_t); -pciio_slot_t pciio_pio_slot_get(pciio_piomap_t); -pciio_space_t pciio_pio_space_get(pciio_piomap_t); -iopaddr_t pciio_pio_pciaddr_get(pciio_piomap_t); -ulong pciio_pio_mapsz_get(pciio_piomap_t); -caddr_t pciio_pio_kvaddr_get(pciio_piomap_t); - -devfs_handle_t pciio_dma_dev_get(pciio_dmamap_t); -pciio_slot_t pciio_dma_slot_get(pciio_dmamap_t); - -pciio_info_t pciio_info_chk(devfs_handle_t); -pciio_info_t pciio_info_get(devfs_handle_t); -void pciio_info_set(devfs_handle_t, pciio_info_t); -devfs_handle_t pciio_info_dev_get(pciio_info_t); -pciio_slot_t pciio_info_slot_get(pciio_info_t); -pciio_function_t pciio_info_function_get(pciio_info_t); -pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t); -pciio_device_id_t pciio_info_device_id_get(pciio_info_t); -devfs_handle_t pciio_info_master_get(pciio_info_t); -arbitrary_info_t pciio_info_mfast_get(pciio_info_t); -pciio_provider_t *pciio_info_pops_get(pciio_info_t); -error_handler_f *pciio_info_efunc_get(pciio_info_t); -error_handler_arg_t *pciio_info_einfo_get(pciio_info_t); -pciio_space_t pciio_info_bar_space_get(pciio_info_t, int); -iopaddr_t pciio_info_bar_base_get(pciio_info_t, int); -size_t pciio_info_bar_size_get(pciio_info_t, int); -iopaddr_t pciio_info_rom_base_get(pciio_info_t); -size_t pciio_info_rom_size_get(pciio_info_t); - -void pciio_init(void); -int pciio_attach(devfs_handle_t); - -void pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns); -void pciio_provider_unregister(devfs_handle_t); -pciio_provider_t *pciio_provider_fns_get(devfs_handle_t); - -int pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned); -void pciio_driver_unregister(char *driver_prefix); - -devfs_handle_t pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); - -void pciio_device_unregister(devfs_handle_t); -pciio_info_t pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); -void pciio_device_info_free(pciio_info_t); -devfs_handle_t pciio_device_info_register(devfs_handle_t, pciio_info_t); -void pciio_device_info_unregister(devfs_handle_t, pciio_info_t); -int pciio_device_attach(devfs_handle_t, int); -int pciio_device_detach(devfs_handle_t, int); -void pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t); - -int pciio_reset(devfs_handle_t); -int pciio_write_gather_flush(devfs_handle_t); -int pciio_slot_inuse(devfs_handle_t); - -/* ===================================================================== - * Provider Function Location - * - * If there is more than one possible provider for - * this platform, we need to examine the master - * vertex of the current vertex for a provider - * function structure, and indirect through the - * appropriately named member. - */ - -#if !defined(DEV_FUNC) - -static pciio_provider_t * -pciio_to_provider_fns(devfs_handle_t dev) -{ - pciio_info_t card_info; - pciio_provider_t *provider_fns; - - /* - * We're called with two types of vertices, one is - * the bridge vertex (ends with "pci") and the other is the - * pci slot vertex (ends with "pci/[0-8]"). For the first type - * we need to get the provider from the PFUNCS label. For - * the second we get it from fastinfo/c_pops. - */ - provider_fns = pciio_provider_fns_get(dev); - if (provider_fns == NULL) { - card_info = pciio_info_get(dev); - if (card_info != NULL) { - provider_fns = pciio_info_pops_get(card_info); - } - } - - if (provider_fns == NULL) -#if defined(SUPPORT_PRINTING_V_FORMAT) - PRINT_PANIC("%v: provider_fns == NULL", dev); -#else - PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev); -#endif - - return provider_fns; - -} - -#define DEV_FUNC(dev,func) pciio_to_provider_fns(dev)->func -#define CAST_PIOMAP(x) ((pciio_piomap_t)(x)) -#define CAST_DMAMAP(x) ((pciio_dmamap_t)(x)) -#define CAST_INTR(x) ((pciio_intr_t)(x)) -#endif - -/* - * Many functions are not passed their vertex - * information directly; rather, they must - * dive through a resource map. These macros - * are available to coordinate this detail. - */ -#define PIOMAP_FUNC(map,func) DEV_FUNC((map)->pp_dev,func) -#define DMAMAP_FUNC(map,func) DEV_FUNC((map)->pd_dev,func) -#define INTR_FUNC(intr_hdl,func) DEV_FUNC((intr_hdl)->pi_dev,func) - -/* ===================================================================== - * PIO MANAGEMENT - * - * For mapping system virtual address space to - * pciio space on a specified card - */ - -pciio_piomap_t -pciio_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ - iopaddr_t addr, /* lowest address (or offset in window) */ - size_t byte_count, /* size of region containing our mappings */ - size_t byte_count_max, /* maximum size of a mapping */ - unsigned flags) -{ /* defined in sys/pio.h */ - return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc) - (dev, dev_desc, space, addr, byte_count, byte_count_max, flags); -} - -void -pciio_piomap_free(pciio_piomap_t pciio_piomap) -{ - PIOMAP_FUNC(pciio_piomap, piomap_free) - (CAST_PIOMAP(pciio_piomap)); -} - -caddr_t -pciio_piomap_addr(pciio_piomap_t pciio_piomap, /* mapping resources */ - iopaddr_t pciio_addr, /* map for this pciio address */ - size_t byte_count) -{ /* map this many bytes */ - pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr) - (CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count); - - return pciio_piomap->pp_kvaddr; -} - -void -pciio_piomap_done(pciio_piomap_t pciio_piomap) -{ - PIOMAP_FUNC(pciio_piomap, piomap_done) - (CAST_PIOMAP(pciio_piomap)); -} - -caddr_t -pciio_piotrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ - iopaddr_t addr, /* starting address (or offset in window) */ - size_t byte_count, /* map this many bytes */ - unsigned flags) -{ /* (currently unused) */ - return DEV_FUNC(dev, piotrans_addr) - (dev, dev_desc, space, addr, byte_count, flags); -} - -caddr_t -pciio_pio_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ - iopaddr_t addr, /* starting address (or offset in window) */ - size_t byte_count, /* map this many bytes */ - pciio_piomap_t *mapp, /* where to return the map pointer */ - unsigned flags) -{ /* PIO flags */ - pciio_piomap_t map = 0; - int errfree = 0; - caddr_t res; - - if (mapp) { - map = *mapp; /* possible pre-allocated map */ - *mapp = 0; /* record "no map used" */ - } - - res = pciio_piotrans_addr - (dev, dev_desc, space, addr, byte_count, flags); - if (res) - return res; /* pciio_piotrans worked */ - - if (!map) { - map = pciio_piomap_alloc - (dev, dev_desc, space, addr, byte_count, byte_count, flags); - if (!map) - return res; /* pciio_piomap_alloc failed */ - errfree = 1; - } - - res = pciio_piomap_addr - (map, addr, byte_count); - if (!res) { - if (errfree) - pciio_piomap_free(map); - return res; /* pciio_piomap_addr failed */ - } - if (mapp) - *mapp = map; /* pass back map used */ - - return res; /* pciio_piomap_addr succeeded */ -} - -iopaddr_t -pciio_piospace_alloc(devfs_handle_t dev, /* Device requiring space */ - device_desc_t dev_desc, /* Device descriptor */ - pciio_space_t space, /* MEM32/MEM64/IO */ - size_t byte_count, /* Size of mapping */ - size_t align) -{ /* Alignment needed */ - if (align < NBPP) - align = NBPP; - return DEV_FUNC(dev, piospace_alloc) - (dev, dev_desc, space, byte_count, align); -} - -void -pciio_piospace_free(devfs_handle_t dev, /* Device freeing space */ - pciio_space_t space, /* Type of space */ - iopaddr_t pciaddr, /* starting address */ - size_t byte_count) -{ /* Range of address */ - DEV_FUNC(dev, piospace_free) - (dev, space, pciaddr, byte_count); -} - -/* ===================================================================== - * DMA MANAGEMENT - * - * For mapping from pci space to system - * physical space. - */ - -pciio_dmamap_t -pciio_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ - device_desc_t dev_desc, /* device descriptor */ - size_t byte_count_max, /* max size of a mapping */ - unsigned flags) -{ /* defined in dma.h */ - return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc) - (dev, dev_desc, byte_count_max, flags); -} - -void -pciio_dmamap_free(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_free) - (CAST_DMAMAP(pciio_dmamap)); -} - -iopaddr_t -pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - paddr_t paddr, /* map for this address */ - size_t byte_count) -{ /* map this many bytes */ - return DMAMAP_FUNC(pciio_dmamap, dmamap_addr) - (CAST_DMAMAP(pciio_dmamap), paddr, byte_count); -} - -alenlist_t -pciio_dmamap_list(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - alenlist_t alenlist, /* map this Address/Length List */ - unsigned flags) -{ - return DMAMAP_FUNC(pciio_dmamap, dmamap_list) - (CAST_DMAMAP(pciio_dmamap), alenlist, flags); -} - -void -pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_done) - (CAST_DMAMAP(pciio_dmamap)); -} - -iopaddr_t -pciio_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_addr) - (dev, dev_desc, paddr, byte_count, flags); -} - -alenlist_t -pciio_dmatrans_list(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - alenlist_t palenlist, /* system address/length list */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_list) - (dev, dev_desc, palenlist, flags); -} - -iopaddr_t -pciio_dma_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - pciio_dmamap_t *mapp, /* map to use, then map we used */ - unsigned flags) -{ /* PIO flags */ - pciio_dmamap_t map = 0; - int errfree = 0; - iopaddr_t res; - - if (mapp) { - map = *mapp; /* possible pre-allocated map */ - *mapp = 0; /* record "no map used" */ - } - - res = pciio_dmatrans_addr - (dev, dev_desc, paddr, byte_count, flags); - if (res) - return res; /* pciio_dmatrans worked */ - - if (!map) { - map = pciio_dmamap_alloc - (dev, dev_desc, byte_count, flags); - if (!map) - return res; /* pciio_dmamap_alloc failed */ - errfree = 1; - } - - res = pciio_dmamap_addr - (map, paddr, byte_count); - if (!res) { - if (errfree) - pciio_dmamap_free(map); - return res; /* pciio_dmamap_addr failed */ - } - if (mapp) - *mapp = map; /* pass back map used */ - - return res; /* pciio_dmamap_addr succeeded */ -} - -void -pciio_dmamap_drain(pciio_dmamap_t map) -{ - DMAMAP_FUNC(map, dmamap_drain) - (CAST_DMAMAP(map)); -} - -void -pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) -{ - DEV_FUNC(dev, dmaaddr_drain) - (dev, addr, size); -} - -void -pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list) -{ - DEV_FUNC(dev, dmalist_drain) - (dev, list); -} - -/* ===================================================================== - * INTERRUPT MANAGEMENT - * - * Allow crosstalk devices to establish interrupts - */ - -/* - * Allocate resources required for an interrupt as specified in intr_desc. - * Return resource handle in intr_hdl. - */ -pciio_intr_t -pciio_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_intr_line_t lines, /* INTR line(s) to attach */ - devfs_handle_t owner_dev) -{ /* owner of this interrupt */ - return (pciio_intr_t) DEV_FUNC(dev, intr_alloc) - (dev, dev_desc, lines, owner_dev); -} - -/* - * Free resources consumed by intr_alloc. - */ -void -pciio_intr_free(pciio_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_free) - (CAST_INTR(intr_hdl)); -} - -/* - * Associate resources allocated with a previous pciio_intr_alloc call with the - * described handler, arg, name, etc. - * - * Returns 0 on success, returns <0 on failure. - */ -int -pciio_intr_connect(pciio_intr_t intr_hdl) /* pciio intr resource handle */ -{ - return INTR_FUNC(intr_hdl, intr_connect) - (CAST_INTR(intr_hdl)); -} - -/* - * Disassociate handler with the specified interrupt. - */ -void -pciio_intr_disconnect(pciio_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_disconnect) - (CAST_INTR(intr_hdl)); -} - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. - */ -devfs_handle_t -pciio_intr_cpu_get(pciio_intr_t intr_hdl) -{ - return INTR_FUNC(intr_hdl, intr_cpu_get) - (CAST_INTR(intr_hdl)); -} - -void -pciio_slot_func_to_name(char *name, - pciio_slot_t slot, - pciio_function_t func) -{ - /* - * standard connection points: - * - * PCIIO_SLOT_NONE: .../pci/direct - * PCIIO_FUNC_NONE: .../pci/ ie. .../pci/3 - * multifunction: .../pci/ ie. .../pci/3c - */ - - if (slot == PCIIO_SLOT_NONE) - sprintf(name, "direct"); - else if (func == PCIIO_FUNC_NONE) - sprintf(name, "%d", slot); - else - sprintf(name, "%d%c", slot, 'a'+func); -} - -/* ===================================================================== - * CONFIGURATION MANAGEMENT - */ - -/* - * Startup a crosstalk provider - */ -void -pciio_provider_startup(devfs_handle_t pciio_provider) -{ - DEV_FUNC(pciio_provider, provider_startup) - (pciio_provider); -} - -/* - * Shutdown a crosstalk provider - */ -void -pciio_provider_shutdown(devfs_handle_t pciio_provider) -{ - DEV_FUNC(pciio_provider, provider_shutdown) - (pciio_provider); -} - -/* - * Specify endianness constraints. The driver tells us what the device - * does and how it would like to see things in memory. We reply with - * how things will actually appear in memory. - */ -pciio_endian_t -pciio_endian_set(devfs_handle_t dev, - pciio_endian_t device_end, - pciio_endian_t desired_end) -{ - ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE)); - ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE)); - -#if DEBUG -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_ALERT "%v: pciio_endian_set is going away.\n" - "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n" - "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n", - dev); -#else - printk(KERN_ALERT "0x%x: pciio_endian_set is going away.\n" - "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n" - "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n", - dev); -#endif -#endif - - return DEV_FUNC(dev, endian_set) - (dev, device_end, desired_end); -} - -/* - * Specify PCI arbitration priority. - */ -pciio_priority_t -pciio_priority_set(devfs_handle_t dev, - pciio_priority_t device_prio) -{ - ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW)); - - return DEV_FUNC(dev, priority_set) - (dev, device_prio); -} - -/* - * Read value of configuration register - */ -uint64_t -pciio_config_get(devfs_handle_t dev, - unsigned reg, - unsigned size) -{ - uint64_t value = 0; - unsigned shift = 0; - - /* handle accesses that cross words here, - * since that's common code between all - * possible providers. - */ - while (size > 0) { - unsigned biw = 4 - (reg&3); - if (biw > size) - biw = size; - - value |= DEV_FUNC(dev, config_get) - (dev, reg, biw) << shift; - - shift += 8*biw; - reg += biw; - size -= biw; - } - return value; -} - -/* - * Change value of configuration register - */ -void -pciio_config_set(devfs_handle_t dev, - unsigned reg, - unsigned size, - uint64_t value) -{ - /* handle accesses that cross words here, - * since that's common code between all - * possible providers. - */ - while (size > 0) { - unsigned biw = 4 - (reg&3); - if (biw > size) - biw = size; - - DEV_FUNC(dev, config_set) - (dev, reg, biw, value); - reg += biw; - size -= biw; - value >>= biw * 8; - } -} - -/* ===================================================================== - * GENERIC PCI SUPPORT FUNCTIONS - */ - -/* - * Issue a hardware reset to a card. - */ -int -pciio_reset(devfs_handle_t dev) -{ - return DEV_FUNC(dev, reset) (dev); -} - -/* - * flush write gather buffers - */ -int -pciio_write_gather_flush(devfs_handle_t dev) -{ - return DEV_FUNC(dev, write_gather_flush) (dev); -} - -devfs_handle_t -pciio_intr_dev_get(pciio_intr_t pciio_intr) -{ - return (pciio_intr->pi_dev); -} - -/****** Generic crosstalk pio interfaces ******/ -devfs_handle_t -pciio_pio_dev_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_dev); -} - -pciio_slot_t -pciio_pio_slot_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_slot); -} - -pciio_space_t -pciio_pio_space_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_space); -} - -iopaddr_t -pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_pciaddr); -} - -ulong -pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_mapsz); -} - -caddr_t -pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_kvaddr); -} - -/****** Generic crosstalk dma interfaces ******/ -devfs_handle_t -pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap) -{ - return (pciio_dmamap->pd_dev); -} - -pciio_slot_t -pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap) -{ - return (pciio_dmamap->pd_slot); -} - -/****** Generic pci slot information interfaces ******/ - -pciio_info_t -pciio_info_chk(devfs_handle_t pciio) -{ - arbitrary_info_t ainfo = 0; - - hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo); - return (pciio_info_t) ainfo; -} - -pciio_info_t -pciio_info_get(devfs_handle_t pciio) -{ - pciio_info_t pciio_info; - - pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio); - -#ifdef DEBUG_PCIIO - { - int pos; - char dname[256]; - pos = devfs_generate_path(pciio, dname, 256); - printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); - } -#endif /* DEBUG_PCIIO */ - - if ((pciio_info != NULL) && - (pciio_info->c_fingerprint != pciio_info_fingerprint) - && (pciio_info->c_fingerprint != NULL)) { - - return((pciio_info_t)-1); /* Should panic .. */ - } - - - return pciio_info; -} - -void -pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info) -{ - if (pciio_info != NULL) - pciio_info->c_fingerprint = pciio_info_fingerprint; - hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info); - - /* Also, mark this vertex as a PCI slot - * and use the pciio_info, so pciio_info_chk - * can work (and be fairly efficient). - */ - hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO, - (arbitrary_info_t) pciio_info); -} - -devfs_handle_t -pciio_info_dev_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_vertex); -} - -/*ARGSUSED*/ -pciio_bus_t -pciio_info_bus_get(pciio_info_t pciio_info) -{ - /* XXX for now O2 always gets back bus 0 */ - return (pciio_bus_t)0; -} - -pciio_slot_t -pciio_info_slot_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_slot); -} - -pciio_function_t -pciio_info_function_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_func); -} - -pciio_vendor_id_t -pciio_info_vendor_id_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_vendor); -} - -pciio_device_id_t -pciio_info_device_id_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_device); -} - -devfs_handle_t -pciio_info_master_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_master); -} - -arbitrary_info_t -pciio_info_mfast_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_mfast); -} - -pciio_provider_t * -pciio_info_pops_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_pops); -} - -error_handler_f * -pciio_info_efunc_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_efunc); -} - -error_handler_arg_t * -pciio_info_einfo_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_einfo); -} - -pciio_space_t -pciio_info_bar_space_get(pciio_info_t info, int win) -{ - return info->c_window[win].w_space; -} - -iopaddr_t -pciio_info_bar_base_get(pciio_info_t info, int win) -{ - return info->c_window[win].w_base; -} - -size_t -pciio_info_bar_size_get(pciio_info_t info, int win) -{ - return info->c_window[win].w_size; -} - -iopaddr_t -pciio_info_rom_base_get(pciio_info_t info) -{ - return info->c_rbase; -} - -size_t -pciio_info_rom_size_get(pciio_info_t info) -{ - return info->c_rsize; -} - - -/* ===================================================================== - * GENERIC PCI INITIALIZATION FUNCTIONS - */ - -/* - * pciioinit: called once during device driver - * initializtion if this driver is configured into - * the system. - */ -void -pciio_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("pciio_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (pciio_registry == NULL) { - cp = cdl_new(EDGE_LBL_PCI, "vendor", "device"); - if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(pciio_registry != NULL); -} - -/* - * pciioattach: called for each vertex in the graph - * that is a PCI provider. - */ -/*ARGSUSED */ -int -pciio_attach(devfs_handle_t pciio) -{ -#if DEBUG && ATTACH_DEBUG -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk("%v: pciio_attach\n", pciio); -#else - printk("0x%x: pciio_attach\n", pciio); -#endif -#endif - return 0; -} - -/* - * Associate a set of pciio_provider functions with a vertex. - */ -void -pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns) -{ - hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns); -} - -/* - * Disassociate a set of pciio_provider functions with a vertex. - */ -void -pciio_provider_unregister(devfs_handle_t provider) -{ - arbitrary_info_t ainfo; - - hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo); -} - -/* - * Obtain a pointer to the pciio_provider functions for a specified Crosstalk - * provider. - */ -pciio_provider_t * -pciio_provider_fns_get(devfs_handle_t provider) -{ - arbitrary_info_t ainfo = 0; - - (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo); - return (pciio_provider_t *) ainfo; -} - -/*ARGSUSED4 */ -int -pciio_driver_register( - pciio_vendor_id_t vendor_id, - pciio_device_id_t device_id, - char *driver_prefix, - unsigned flags) -{ - /* a driver's init routine might call - * pciio_driver_register before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - return cdl_add_driver(pciio_registry, - vendor_id, device_id, - driver_prefix, flags, NULL); -} - -/* - * Remove an initialization function. - */ -void -pciio_driver_unregister( - char *driver_prefix) -{ - /* before a driver calls unregister, - * it must have called register; so - * we can assume we have a registry here. - */ - ASSERT(pciio_registry != NULL); - - cdl_del_driver(pciio_registry, driver_prefix, NULL); -} - -/* - * Set the slot status for a device supported by the - * driver being registered. - */ -void -pciio_driver_reg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Set the slot status for a device supported by the - * driver being unregistered. - */ -void -pciio_driver_unreg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Call some function with each vertex that - * might be one of this driver's attach points. - */ -void -pciio_iterate(char *driver_prefix, - pciio_iter_f * func) -{ - /* a driver's init routine might call - * pciio_iterate before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - ASSERT(pciio_registry != NULL); - - cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func); -} - -devfs_handle_t -pciio_device_register( - devfs_handle_t connectpt, /* vertex for /hw/.../pciio/%d */ - devfs_handle_t master, /* card's master ASIC (PCI provider) */ - pciio_slot_t slot, /* card's slot */ - pciio_function_t func, /* card's func */ - pciio_vendor_id_t vendor_id, - pciio_device_id_t device_id) -{ - return pciio_device_info_register - (connectpt, pciio_device_info_new (NULL, master, slot, func, - vendor_id, device_id)); -} - -void -pciio_device_unregister(devfs_handle_t pconn) -{ - DEV_FUNC(pconn,device_unregister)(pconn); -} - -pciio_info_t -pciio_device_info_new( - pciio_info_t pciio_info, - devfs_handle_t master, - pciio_slot_t slot, - pciio_function_t func, - pciio_vendor_id_t vendor_id, - pciio_device_id_t device_id) -{ - if (!pciio_info) - GET_NEW(pciio_info); - ASSERT(pciio_info != NULL); - - pciio_info->c_slot = slot; - pciio_info->c_func = func; - pciio_info->c_vendor = vendor_id; - pciio_info->c_device = device_id; - pciio_info->c_master = master; - pciio_info->c_mfast = hwgraph_fastinfo_get(master); - pciio_info->c_pops = pciio_provider_fns_get(master); - pciio_info->c_efunc = 0; - pciio_info->c_einfo = 0; - - return pciio_info; -} - -void -pciio_device_info_free(pciio_info_t pciio_info) -{ - /* NOTE : pciio_info is a structure within the pcibr_info - * and not a pointer to memory allocated on the heap !! - */ - BZERO((char *)pciio_info,sizeof(pciio_info)); -} - -devfs_handle_t -pciio_device_info_register( - devfs_handle_t connectpt, /* vertex at center of bus */ - pciio_info_t pciio_info) /* details about the connectpt */ -{ - char name[32]; - devfs_handle_t pconn; - int device_master_set(devfs_handle_t, devfs_handle_t); - - pciio_slot_func_to_name(name, - pciio_info->c_slot, - pciio_info->c_func); - - if (GRAPH_SUCCESS != - hwgraph_path_add(connectpt, name, &pconn)) - return pconn; - - pciio_info->c_vertex = pconn; - pciio_info_set(pconn, pciio_info); -#ifdef DEBUG_PCIIO - { - int pos; - char dname[256]; - pos = devfs_generate_path(pconn, dname, 256); - printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]); - } -#endif /* DEBUG_PCIIO */ - - /* - * create link to our pci provider - */ - - device_master_set(pconn, pciio_info->c_master); - -#if USRPCI - /* - * Call into usrpci provider to let it initialize for - * the given slot. - */ - if (pciio_info->c_slot != PCIIO_SLOT_NONE) - usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot); -#endif - - return pconn; -} - -void -pciio_device_info_unregister(devfs_handle_t connectpt, - pciio_info_t pciio_info) -{ - char name[32]; - devfs_handle_t pconn; - - if (!pciio_info) - return; - - pciio_slot_func_to_name(name, - pciio_info->c_slot, - pciio_info->c_func); - - hwgraph_edge_remove(connectpt,name,&pconn); - pciio_info_set(pconn,0); - - /* Remove the link to our pci provider */ - hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL); - - - hwgraph_vertex_unref(pconn); - hwgraph_vertex_destroy(pconn); - -} -/* Add the pci card inventory information to the hwgraph - */ -static void -pciio_device_inventory_add(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - - ASSERT(pciio_info); - ASSERT(pciio_info->c_vertex == pconn_vhdl); - - /* Donot add inventory for non-existent devices */ - if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE) || - (pciio_info->c_device == PCIIO_DEVICE_ID_NONE)) - return; - device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP, - pciio_info->c_vendor,pciio_info->c_device, - pciio_info->c_slot); -} - -static void -pciio_device_inventory_remove(devfs_handle_t pconn_vhdl) -{ -#ifdef LATER - hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1); -#endif -} - -/*ARGSUSED */ -int -pciio_device_attach(devfs_handle_t pconn, - int drv_flags) -{ - pciio_info_t pciio_info; - pciio_vendor_id_t vendor_id; - pciio_device_id_t device_id; - - - pciio_device_inventory_add(pconn); - pciio_info = pciio_info_get(pconn); - - vendor_id = pciio_info->c_vendor; - device_id = pciio_info->c_device; - - /* we don't start attaching things until - * all the driver init routines (including - * pciio_init) have been called; so we - * can assume here that we have a registry. - */ - ASSERT(pciio_registry != NULL); - - return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags)); -} - -int -pciio_device_detach(devfs_handle_t pconn, - int drv_flags) -{ - pciio_info_t pciio_info; - pciio_vendor_id_t vendor_id; - pciio_device_id_t device_id; - - pciio_device_inventory_remove(pconn); - pciio_info = pciio_info_get(pconn); - - vendor_id = pciio_info->c_vendor; - device_id = pciio_info->c_device; - - /* we don't start attaching things until - * all the driver init routines (including - * pciio_init) have been called; so we - * can assume here that we have a registry. - */ - ASSERT(pciio_registry != NULL); - - return(cdl_del_connpt(pciio_registry, vendor_id, device_id, - pconn, drv_flags)); - -} - -/* - * pciio_error_register: - * arrange for a function to be called with - * a specified first parameter plus other - * information when an error is encountered - * and traced to the pci slot corresponding - * to the connection point pconn. - * - * may also be called with a null function - * pointer to "unregister" the error handler. - * - * NOTE: subsequent calls silently overwrite - * previous data for this vertex. We assume that - * cooperating drivers, well, cooperate ... - */ -void -pciio_error_register(devfs_handle_t pconn, - error_handler_f *efunc, - error_handler_arg_t einfo) -{ - pciio_info_t pciio_info; - - pciio_info = pciio_info_get(pconn); - ASSERT(pciio_info != NULL); - pciio_info->c_efunc = efunc; - pciio_info->c_einfo = einfo; -} - -/* - * Check if any device has been found in this slot, and return - * true or false - * vhdl is the vertex for the slot - */ -int -pciio_slot_inuse(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - - ASSERT(pciio_info); - ASSERT(pciio_info->c_vertex == pconn_vhdl); - if (pciio_info->c_vendor) { - /* - * Non-zero value for vendor indicate - * a board being found in this slot. - */ - return 1; - } - return 0; -} - -int -pciio_dma_enabled(devfs_handle_t pconn_vhdl) -{ - return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl); -} - -/* - * These are complementary Linux interfaces that takes in a pci_dev * as the - * first arguement instead of devfs_handle_t. - */ -iopaddr_t snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned); -pciio_dmamap_t snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned); -void snia_pciio_dmamap_free(pciio_dmamap_t); -iopaddr_t snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t); -void snia_pciio_dmamap_done(pciio_dmamap_t); -pciio_endian_t snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end, - pciio_endian_t desired_end); - -#include -EXPORT_SYMBOL(snia_pciio_dmatrans_addr); -EXPORT_SYMBOL(snia_pciio_dmamap_alloc); -EXPORT_SYMBOL(snia_pciio_dmamap_free); -EXPORT_SYMBOL(snia_pciio_dmamap_addr); -EXPORT_SYMBOL(snia_pciio_dmamap_done); -EXPORT_SYMBOL(snia_pciio_endian_set); - -pciio_endian_t -snia_pciio_endian_set(struct pci_dev *pci_dev, - pciio_endian_t device_end, - pciio_endian_t desired_end) -{ - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); - - return DEV_FUNC(dev, endian_set) - (dev, device_end, desired_end); -} - -iopaddr_t -snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - unsigned flags) -{ /* defined in dma.h */ - - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); - - return DEV_FUNC(dev, dmatrans_addr) - (dev, dev_desc, paddr, byte_count, flags); -} - -pciio_dmamap_t -snia_pciio_dmamap_alloc(struct pci_dev *pci_dev, /* set up mappings for this device */ - device_desc_t dev_desc, /* device descriptor */ - size_t byte_count_max, /* max size of a mapping */ - unsigned flags) -{ /* defined in dma.h */ - - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); - - return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc) - (dev, dev_desc, byte_count_max, flags); -} - -void -snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_free) - (CAST_DMAMAP(pciio_dmamap)); -} - -iopaddr_t -snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - paddr_t paddr, /* map for this address */ - size_t byte_count) -{ /* map this many bytes */ - return DMAMAP_FUNC(pciio_dmamap, dmamap_addr) - (CAST_DMAMAP(pciio_dmamap), paddr, byte_count); -} - -void -snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_done) - (CAST_DMAMAP(pciio_dmamap)); -} - diff -urN linux-2.4.21/arch/ia64/sn/io/platform_init/Makefile linux-2.4.22/arch/ia64/sn/io/platform_init/Makefile --- linux-2.4.21/arch/ia64/sn/io/platform_init/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/platform_init/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,16 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. +# +# Makefile for the sn2 io routines. + +EXTRA_CFLAGS := -DLITTLE_ENDIAN + +O_TARGET := snio.o + +obj-y += sgi_io_init.o irix_io_init.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/platform_init/irix_io_init.c linux-2.4.22/arch/ia64/sn/io/platform_init/irix_io_init.c --- linux-2.4.21/arch/ia64/sn/io/platform_init/irix_io_init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/platform_init/irix_io_init.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,89 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void init_all_devices(void); +extern void klhwg_add_all_modules(vertex_hdl_t); +extern void klhwg_add_all_nodes(vertex_hdl_t); + +extern vertex_hdl_t hwgraph_root; +extern void io_module_init(void); +extern int pci_bus_to_hcl_cvlink(void); +extern void mlreset(void); + +/* #define DEBUG_IO_INIT 1 */ +#ifdef DEBUG_IO_INIT +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG_IO_INIT */ + +/* + * This routine is responsible for the setup of all the IRIX hwgraph style + * stuff that's been pulled into linux. It's called by sn_pci_find_bios which + * is called just before the generic Linux PCI layer does its probing (by + * platform_pci_fixup aka sn_pci_fixup). + * + * It is very IMPORTANT that this call is only made by the Master CPU! + * + */ + +void +irix_io_init(void) +{ + cnodeid_t cnode; + + /* + * This is the Master CPU. Emulate mlsetup and main.c in Irix. + */ + mlreset(); + + /* + * Initialize platform-dependent vertices in the hwgraph: + * module + * node + * cpu + * memory + * slot + * hub + * router + * xbow + */ + + io_module_init(); /* Use to be called module_init() .. */ + klhwg_add_all_modules(hwgraph_root); + klhwg_add_all_nodes(hwgraph_root); + + for (cnode = 0; cnode < numnodes; cnode++) { + extern void per_hub_init(cnodeid_t); + per_hub_init(cnode); + } + + /* We can do headless hub cnodes here .. */ + + /* + * + * Our IO Infrastructure drivers are in place .. + * Initialize the whole IO Infrastructure .. xwidget/device probes. + * + */ + init_all_devices(); + pci_bus_to_hcl_cvlink(); +} diff -urN linux-2.4.21/arch/ia64/sn/io/platform_init/sgi_io_init.c linux-2.4.22/arch/ia64/sn/io/platform_init/sgi_io_init.c --- linux-2.4.21/arch/ia64/sn/io/platform_init/sgi_io_init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/platform_init/sgi_io_init.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,109 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int init_hcl(void); + +/* + * per_hub_init + * + * This code is executed once for each Hub chip. + */ +void +per_hub_init(cnodeid_t cnode) +{ + nasid_t nasid; + nodepda_t *npdap; + ii_icmr_u_t ii_icmr; + ii_ibcr_u_t ii_ibcr; + ii_ilcsr_u_t ii_ilcsr; + + nasid = COMPACT_TO_NASID_NODEID(cnode); + + ASSERT(nasid != INVALID_NASID); + ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode); + + npdap = NODEPDA(cnode); + + /* Disable the request and reply errors. */ + REMOTE_HUB_S(nasid, IIO_IWEIM, 0xC000); + + /* + * Set the total number of CRBs that can be used. + */ + ii_icmr.ii_icmr_regval= 0x0; + ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf; + if (enable_shub_wars_1_1() ) { + // Set bit one of ICMR to prevent II from sending interrupt for II bug. + ii_icmr.ii_icmr_regval |= 0x1; + } + REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval); + + /* + * Set the number of CRBs that both of the BTEs combined + * can use minus 1. + */ + ii_ibcr.ii_ibcr_regval= 0x0; + ii_ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(nasid, IIO_LLP_CSR); + if (ii_ilcsr.ii_ilcsr_fld_s.i_llp_stat & LNK_STAT_WORKING) { + ii_ibcr.ii_ibcr_fld_s.i_count = 0x8; + } else { + /* + * if the LLP is down, there is no attached I/O, so + * give BTE all the CRBs. + */ + ii_ibcr.ii_ibcr_fld_s.i_count = 0x14; + } + REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval); + + /* + * Set CRB timeout to be 10ms. + */ + REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff ); + REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); + + /* Initialize error interrupts for this hub. */ + hub_error_init(cnode); +} + +/* + * This routine is responsible for the setup of all the IRIX hwgraph style + * stuff that's been pulled into linux. It's called by sn_pci_find_bios which + * is called just before the generic Linux PCI layer does its probing (by + * platform_pci_fixup aka sn_pci_fixup). + * + * It is very IMPORTANT that this call is only made by the Master CPU! + * + */ + +void +sgi_master_io_infr_init(void) +{ + extern void irix_io_init(void); + + init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */ + irix_io_init(); /* Do IRIX Compatibility IO Init */ + +#ifdef CONFIG_KDB + { + extern void kdba_io_init(void); + kdba_io_init(); + } +#endif + +} diff -urN linux-2.4.21/arch/ia64/sn/io/sgi_if.c linux-2.4.22/arch/ia64/sn/io/sgi_if.c --- linux-2.4.21/arch/ia64/sn/io/sgi_if.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sgi_if.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -20,8 +20,6 @@ #include #include -unsigned char Is_pic_on_this_nasid[512]; /* non-0 when this is a pic shub */ - void * snia_kmem_zalloc(size_t size, int flag) { @@ -37,13 +35,6 @@ kfree(ptr); } -int -nic_vertex_info_match(devfs_handle_t v, char *s) -{ - /* we don't support this */ - return(0); -} - /* * the alloc/free_node routines do a simple kmalloc for now .. */ @@ -64,74 +55,6 @@ } -#define xtod(c) ((c) <= '9' ? '0' - (c) : 'a' - (c) - 10) -long -atoi(register char *p) -{ - register long n; - register int c, neg = 0; - - if (p == NULL) - return 0; - - if (!isdigit(c = *p)) { - while (isspace(c)) - c = *++p; - switch (c) { - case '-': - neg++; - case '+': /* fall-through */ - c = *++p; - } - if (!isdigit(c)) - return (0); - } - if (c == '0' && *(p + 1) == 'x') { - p += 2; - c = *p; - n = xtod(c); - while ((c = *++p) && isxdigit(c)) { - n *= 16; /* two steps to avoid unnecessary overflow */ - n += xtod(c); /* accum neg to avoid surprises at MAX */ - } - } else { - n = '0' - c; - while ((c = *++p) && isdigit(c)) { - n *= 10; /* two steps to avoid unnecessary overflow */ - n += '0' - c; /* accum neg to avoid surprises at MAX */ - } - } - return (neg ? n : -n); -} - -char * -strtok_r(char *string, const char *sepset, char **lasts) -{ - register char *q, *r; - - /*first or subsequent call*/ - if (string == NULL) - string = *lasts; - - if(string == 0) /* return if no tokens remaining */ - return(NULL); - - q = string + strspn(string, sepset); /* skip leading separators */ - - if(*q == '\0') { /* return if no tokens remaining */ - *lasts = 0; /* indicate this is last token */ - return(NULL); - } - - if((r = strpbrk(q, sepset)) == NULL) /* move past token */ - *lasts = 0; /* indicate this is last token */ - else { - *r = '\0'; - *lasts = r+1; - } - return(q); -} - /* * print_register() allows formatted printing of bit fields. individual * bit fields are described by a struct reg_desc, multiple bit fields within diff -urN linux-2.4.21/arch/ia64/sn/io/sgi_io_init.c linux-2.4.22/arch/ia64/sn/io/sgi_io_init.c --- linux-2.4.21/arch/ia64/sn/io/sgi_io_init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sgi_io_init.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,336 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void mlreset(int ); -extern int init_hcl(void); -extern void klgraph_hack_init(void); -extern void hubspc_init(void); -extern void pciio_init(void); -extern void pcibr_init(void); -extern void xtalk_init(void); -extern void xbow_init(void); -extern void xbmon_init(void); -extern void pciiox_init(void); -extern void usrpci_init(void); -extern void ioc3_init(void); -extern void initialize_io(void); -#if defined(CONFIG_IA64_SGI_SN1) -extern void intr_clear_all(nasid_t); -#endif -extern void klhwg_add_all_modules(devfs_handle_t); -extern void klhwg_add_all_nodes(devfs_handle_t); - -void sn_mp_setup(void); -extern devfs_handle_t hwgraph_root; -extern void io_module_init(void); -extern void pci_bus_cvlink_init(void); -extern void temp_hack(void); - -extern int pci_bus_to_hcl_cvlink(void); - -/* #define DEBUG_IO_INIT 1 */ -#ifdef DEBUG_IO_INIT -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* DEBUG_IO_INIT */ - -/* - * per_hub_init - * - * This code is executed once for each Hub chip. - */ -static void -per_hub_init(cnodeid_t cnode) -{ - nasid_t nasid; - nodepda_t *npdap; - ii_icmr_u_t ii_icmr; - ii_ibcr_u_t ii_ibcr; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - ASSERT(nasid != INVALID_NASID); - ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode); - - npdap = NODEPDA(cnode); - -#if defined(CONFIG_IA64_SGI_SN1) - /* initialize per-node synergy perf instrumentation */ - npdap->synergy_perf_enabled = 0; /* off by default */ - npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED; - npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT; - npdap->synergy_inactive_intervals = 0; - npdap->synergy_active_intervals = 0; - npdap->synergy_perf_data = NULL; - npdap->synergy_perf_first = NULL; -#endif /* CONFIG_IA64_SGI_SN1 */ - - - /* - * Set the total number of CRBs that can be used. - */ - ii_icmr.ii_icmr_regval= 0x0; - ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF; - REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval); - - /* - * Set the number of CRBs that both of the BTEs combined - * can use minus 1. - */ - ii_ibcr.ii_ibcr_regval= 0x0; - ii_ibcr.ii_ibcr_fld_s.i_count = 0x8; - REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval); - - /* - * Set CRB timeout to be 10ms. - */ - REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 ); - REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); - - -#if defined(CONFIG_IA64_SGI_SN1) - /* Reserve all of the hardwired interrupt levels. */ - intr_reserve_hardwired(cnode); -#endif - - /* Initialize error interrupts for this hub. */ - hub_error_init(cnode); -} - -/* - * This routine is responsible for the setup of all the IRIX hwgraph style - * stuff that's been pulled into linux. It's called by sn_pci_find_bios which - * is called just before the generic Linux PCI layer does its probing (by - * platform_pci_fixup aka sn_pci_fixup). - * - * It is very IMPORTANT that this call is only made by the Master CPU! - * - */ - -void -sgi_master_io_infr_init(void) -{ - int cnode; - - /* - * Do any early init stuff .. einit_tbl[] etc. - */ - DBG("--> sgi_master_io_infr_init: calling init_hcl().\n"); - init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */ - -#ifdef Colin - -printk("Testing out Xbridge Access .. if it hangs Xbridge is not init yet.\n"); -printk(" Reading Xbridge WID at address 0xc00000080f000000 0x%p\n", (* (volatile uint32_t *)(0xc00000080f000000))); - -printk("Testing out PCI Address Space Accesses\n"); -printk(" Testing PCI Config Read Byte: address 0xc00000080f020000 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020000))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020001 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020001))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020002 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020002))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020003 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020003))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020004))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020005 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020005))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020006 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020006))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020007 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020007))); - -printk(" Testing PCI Config Word: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020004))); - -printk(" Testing PCI Config Word: address 0xc00000080f020008 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020008))); - -#endif - - /* - * initialize the Linux PCI to xwidget vertexes .. - */ - DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n"); - pci_bus_cvlink_init(); - -#ifdef BRINGUP -#ifdef CONFIG_IA64_SGI_SN1 - /* - * Hack to provide statically initialzed klgraph entries. - */ - DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n"); - klgraph_hack_init(); -#endif /* CONFIG_IA64_SGI_SN1 */ -#endif /* BRINGUP */ - - /* - * This is the Master CPU. Emulate mlsetup and main.c in Irix. - */ - DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n"); - mlreset(0); /* Master .. */ - - /* - * allowboot() is called by kern/os/main.c in main() - * Emulate allowboot() ... - * per_cpu_init() - only need per_hub_init() - * cpu_io_setup() - Nothing to do. - * - */ - DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n"); - sn_mp_setup(); - - DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n"); - for (cnode = 0; cnode < numnodes; cnode++) { - per_hub_init(cnode); - } - - /* We can do headless hub cnodes here .. */ - - /* - * io_init[] stuff. - * - * Get SGI IO Infrastructure drivers to init and register with - * each other etc. - */ - - DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n"); - hubspc_init(); - - DBG("--> sgi_master_io_infr_init: calling pciio_init()\n"); - pciio_init(); - - DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n"); - pcibr_init(); - - DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n"); - xtalk_init(); - - DBG("--> sgi_master_io_infr_init: calling xbow_init()\n"); - xbow_init(); - - DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n"); - xbmon_init(); - - DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n"); - pciiox_init(); - - DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n"); - usrpci_init(); - - DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n"); - ioc3_init(); - - /* - * - * Our IO Infrastructure drivers are in place .. - * Initialize the whole IO Infrastructure .. xwidget/device probes. - * - */ - DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n"); - initialize_io(); - - DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n"); - pci_bus_to_hcl_cvlink(); - -#ifdef CONFIG_PCIBA - DBG("--> sgi_master_io_infr_init: calling pciba_init()\n"); - pciba_init(); -#endif - - DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n"); -} - -/* - * sgi_slave_io_infr_init - This routine must be called on all cpus except - * the Master CPU. - */ -void -sgi_slave_io_infr_init(void) -{ - /* Emulate cboot() .. */ - mlreset(1); /* This is a slave cpu */ - - // per_hub_init(0); /* Need to get and send in actual cnode number */ - - /* Done */ -} - -/* - * One-time setup for MP SN. - * Allocate per-node data, slurp prom klconfig information and - * convert it to hwgraph information. - */ -void -sn_mp_setup(void) -{ - cnodeid_t cnode; - cpuid_t cpu; - - for (cpu = 0; cpu < smp_num_cpus; cpu++) { - /* Skip holes in CPU space */ - if (cpu_enabled(cpu)) { - init_platform_pda(cpu); - } - } - - /* - * Initialize platform-dependent vertices in the hwgraph: - * module - * node - * cpu - * memory - * slot - * hub - * router - * xbow - */ - - DBG("sn_mp_io_setup: calling io_module_init()\n"); - io_module_init(); /* Use to be called module_init() .. */ - - DBG("sn_mp_setup: calling klhwg_add_all_modules()\n"); - klhwg_add_all_modules(hwgraph_root); - DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n"); - klhwg_add_all_nodes(hwgraph_root); - - - for (cnode = 0; cnode < numnodes; cnode++) { - - /* - * This routine clears the Hub's Interrupt registers. - */ - /* - * We need to move this intr_clear_all() routine - * from SN/intr.c to a more appropriate file. - * Talk to Al Mayer. - */ -#if defined(CONFIG_IA64_SGI_SN1) - intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); -#endif - /* now init the hub */ - // per_hub_init(cnode); - - } - -#if defined(CONFIG_IA64_SGI_SN1) - synergy_perf_init(); -#endif - -} diff -urN linux-2.4.21/arch/ia64/sn/io/sgi_io_sim.c linux-2.4.22/arch/ia64/sn/io/sgi_io_sim.c --- linux-2.4.21/arch/ia64/sn/io/sgi_io_sim.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sgi_io_sim.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -15,18 +15,11 @@ #include #include #include -#include #include -cpuid_t master_procid = 0; +cpuid_t master_procid; char arg_maxnodes[4]; -extern void init_all_devices(void); - -#if defined(CONFIG_IA64_SGI_SN1) -synergy_da_t *Synergy_da_indr[MAX_COMPACT_NODES * 2]; -#endif - /* * Return non-zero if the given variable was specified */ @@ -36,44 +29,12 @@ return (strlen(s) != 0); } -void xbmon_init(void) -{ - FIXME("xbmon_init : no-op\n"); - -} - -void pciiox_init(void) -{ - FIXME("pciiox_init : no-op\n"); - -} - -void usrpci_init(void) -{ - FIXME("usrpci_init : no-op\n"); - -} - -void ioc3_init(void) -{ - FIXME("ioc3_init : no-op\n"); - -} - -void initialize_io(void) -{ - - init_all_devices(); -} - /* * Routines provided by ml/SN/promif.c. */ -static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL; +static __psunsigned_t master_bridge_base; nasid_t console_nasid = (nasid_t)-1; -#if !defined(CONFIG_IA64_SGI_SN1) char master_baseio_wid; -#endif static char console_wid; static char console_pcislot; @@ -95,27 +56,6 @@ return 0; } -#if defined(CONFIG_IA64_SGI_SN1) -int -is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid) -{ - - /* - * If the widget numbers are different, we're not the master. - */ - if (test_wid != (xwidgetnum_t)console_wid) - return 0; - - /* - * If the NASIDs are the same or equivalent, we're the master. - */ - if (check_nasid_equiv(test_nasid, console_nasid)) { - return 1; - } else { - return 0; - } -} -#else int is_master_baseio_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid) { @@ -137,14 +77,3 @@ return 0; } } -#endif /* CONFIG_IA64_SGI_SN1 */ - -/* - * Routines provided by ml/SN/nvram.c - */ -void -nvram_baseinit(void) -{ - FIXME("nvram_baseinit : no-op\n"); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/Makefile linux-2.4.22/arch/ia64/sn/io/sn1/Makefile --- linux-2.4.21/arch/ia64/sn/io/sn1/Makefile 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,25 +0,0 @@ -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 2002 Silicon Graphics, Inc. All Rights Reserved. -# -# Makefile for the sn1 io routines. - -EXTRA_CFLAGS := -DLITTLE_ENDIAN - -O_TARGET := snio.o - -export-objs := pciio.o - -obj-$(CONFIG_IA64_SGI_SN1) += ml_SN_intr.o mem_refcnt.o hubcounters.o \ - ip37.o huberror.o hub_intr.o pcibr.o \ - eeprom.o l1.o l1_command.o pciio.o \ - klconflib.o klgraph.o \ - efi-rtc.o xbow.o xtalk.o \ - ml_SN_init.o ml_iograph.o module.o \ - pci_bus_cvlink.o sgi_io_init.o - - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/eeprom.c linux-2.4.22/arch/ia64/sn/io/sn1/eeprom.c --- linux-2.4.21/arch/ia64/sn/io/sn1/eeprom.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/eeprom.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1421 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * WARNING: There is more than one copy of this file in different isms. - * All copies must be kept exactly in sync. - * Do not modify this file without also updating the following: - * - * irix/kern/io/eeprom.c - * stand/arcs/lib/libsk/ml/eeprom.c - * stand/arcs/lib/libkl/io/eeprom.c - * - * (from time to time they might not be in sync but that's due to bringup - * activity - this comment is to remind us that they eventually have to - * get back together) - * - * eeprom.c - * - * access to board-mounted EEPROMs via the L1 system controllers - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(EEPROM_DEBUG) -#define db_printf(x) printk x -#else -#define db_printf(x) printk x -#endif - -#define BCOPY(x,y,z) memcpy(y,x,z) - -#define UNDERSCORE 0 /* don't convert underscores to hyphens */ -#define HYPHEN 1 /* convert underscores to hyphens */ - -void copy_ascii_field( char *to, char *from, int length, - int change_underscore ); -uint64_t generate_unique_id( char *sn, int sn_len ); -uchar_t char_to_base36( char c ); -int nicify( char *dst, eeprom_brd_record_t *src ); -static void int64_to_hex_string( char *out, uint64_t val ); - -// extern int router_lock( net_vec_t, int, int ); -// extern int router_unlock( net_vec_t ); -#define ROUTER_LOCK(p) // router_lock(p, 10000, 3000000) -#define ROUTER_UNLOCK(p) // router_unlock(p) - -#define IP27LOG_OVNIC "OverrideNIC" - - -/* the following function converts an EEPROM record to a close facsimile - * of the string returned by reading a Dallas Semiconductor NIC (see - * one of the many incarnations of nic.c for details on that driver) - */ -int nicify( char *dst, eeprom_brd_record_t *src ) -{ - int field_len; - uint64_t unique_id; - char *cur_dst = dst; - eeprom_board_ia_t *board; - - board = src->board_ia; - ASSERT( board ); /* there should always be a board info area */ - - /* copy part number */ - strcpy( cur_dst, "Part:" ); - cur_dst += strlen( cur_dst ); - ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK) - == FIELD_FORMAT_ASCII ); - field_len = board->part_num_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN ); - cur_dst += field_len; - - /* copy product name */ - strcpy( cur_dst, ";Name:" ); - cur_dst += strlen( cur_dst ); - ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII ); - field_len = board->product_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE ); - cur_dst += field_len; - - /* copy serial number */ - strcpy( cur_dst, ";Serial:" ); - cur_dst += strlen( cur_dst ); - ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK) - == FIELD_FORMAT_ASCII ); - field_len = board->serial_num_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->serial_num, field_len, - HYPHEN); - - cur_dst += field_len; - - /* copy revision */ - strcpy( cur_dst, ";Revision:"); - cur_dst += strlen( cur_dst ); - ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK) - == FIELD_FORMAT_ASCII ); - field_len = board->board_rev_tl & FIELD_LENGTH_MASK; - copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN ); - cur_dst += field_len; - - /* EEPROMs don't have equivalents for the Group, Capability and - * Variety fields, so we pad these with 0's - */ - strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" ); - cur_dst += strlen( cur_dst ); - - /* use the board serial number to "fake" a laser id */ - strcpy( cur_dst, ";Laser:" ); - cur_dst += strlen( cur_dst ); - unique_id = generate_unique_id( board->serial_num, - board->serial_num_tl & FIELD_LENGTH_MASK ); - int64_to_hex_string( cur_dst, unique_id ); - strcat( dst, ";" ); - - return 1; -} - - -/* These functions borrow heavily from chars2* in nic.c - */ -void copy_ascii_field( char *to, char *from, int length, - int change_underscore ) -{ - int i; - for( i = 0; i < length; i++ ) { - - /* change underscores to hyphens if requested */ - if( from[i] == '_' && change_underscore == HYPHEN ) - to[i] = '-'; - - /* ; and ; are separators, so mustn't appear within - * a field */ - else if( from[i] == ':' || from[i] == ';' ) - to[i] = '?'; - - /* I'm not sure why or if ASCII character 0xff would - * show up in an EEPROM field, but the NIC parsing - * routines wouldn't like it if it did... so we - * get rid of it, just in case. */ - else if( (unsigned char)from[i] == (unsigned char)0xff ) - to[i] = ' '; - - /* unprintable characters are replaced with . */ - else if( from[i] < ' ' || from[i] >= 0x7f ) - to[i] = '.'; - - /* otherwise, just copy the character */ - else - to[i] = from[i]; - } - - if( i == 0 ) { - to[i] = ' '; /* return at least a space... */ - i++; - } - to[i] = 0; /* terminating null */ -} - -/* Note that int64_to_hex_string currently only has a big-endian - * implementation. - */ -#ifdef _MIPSEB -static void int64_to_hex_string( char *out, uint64_t val ) -{ - int i; - uchar_t table[] = "0123456789abcdef"; - uchar_t *byte_ptr = (uchar_t *)&val; - for( i = 0; i < sizeof(uint64_t); i++ ) { - out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ]; - out[i*2+1] = table[ (*byte_ptr) & 0x0f ]; - byte_ptr++; - } - out[i*2] = '\0'; -} - -#else /* little endian */ - -static void int64_to_hex_string( char *out, uint64_t val ) -{ - - - printk("int64_to_hex_string needs a little-endian implementation.\n"); -} -#endif /* _MIPSEB */ - -/* Convert a standard ASCII serial number to a unique integer - * id number by treating the serial number string as though - * it were a base 36 number - */ -uint64_t generate_unique_id( char *sn, int sn_len ) -{ - int uid = 0; - int i; - - #define VALID_BASE36(c) ((c >= '0' && c <='9') \ - || (c >= 'A' && c <='Z') \ - || (c >= 'a' && c <='z')) - - for( i = 0; i < sn_len; i++ ) { - if( !VALID_BASE36(sn[i]) ) - continue; - uid *= 36; - uid += char_to_base36( sn[i] ); - } - - if( uid == 0 ) - return rtc_time(); - - return uid; -} - -uchar_t char_to_base36( char c ) -{ - uchar_t val; - - if( c >= '0' && c <= '9' ) - val = (c - '0'); - - else if( c >= 'A' && c <= 'Z' ) - val = (c - 'A' + 10); - - else if( c >= 'a' && c <= 'z' ) - val = (c - 'a' + 10); - - else val = 0; - - return val; -} - - -/* given a pointer to the three-byte little-endian EEPROM representation - * of date-of-manufacture, this function translates to a big-endian - * integer format - */ -int eeprom_xlate_board_mfr_date( uchar_t *src ) -{ - int rval = 0; - rval += *src; src++; - rval += ((int)(*src) << 8); src ++; - rval += ((int)(*src) << 16); - return rval; -} - - -int eeprom_str( char *nic_str, nasid_t nasid, int component ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - - if( (component & C_DIMM) == C_DIMM ) { - /* this function isn't applicable to DIMMs */ - return EEP_PARAM; - } - else { - eep.board_ia = &board; - eep.spd = NULL; - if( !(component & SUBORD_MASK) ) - eep.chassis_ia = &chassis; /* only main boards have a chassis - * info area */ - else - eep.chassis_ia = NULL; - } - - switch( component & BRICK_MASK ) { - case C_BRICK: - r = cbrick_eeprom_read( &eep, nasid, component ); - break; - case IO_BRICK: - r = iobrick_eeprom_read( &eep, nasid, component ); - break; - default: - return EEP_PARAM; /* must be an invalid component */ - } - if( r ) - return r; - if( !nicify( nic_str, &eep ) ) - return EEP_NICIFY; - - return EEP_OK; -} - -int vector_eeprom_str( char *nic_str, nasid_t nasid, - int component, net_vec_t path ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - - eep.board_ia = &board; - if( !(component & SUBORD_MASK) ) - eep.chassis_ia = &chassis; /* only main boards have a chassis - * info area */ - else - eep.chassis_ia = NULL; - - if( !(component & VECTOR) ) - return EEP_PARAM; - - if( (r = vector_eeprom_read( &eep, nasid, path, component )) ) - return r; - - if( !nicify( nic_str, &eep ) ) - return EEP_NICIFY; - - return EEP_OK; -} - - -int is_iobrick( int nasid, int widget_num ) -{ - uint32_t wid_reg; - int part_num, mfg_num; - - /* Read the widget's WIDGET_ID register to get - * its part number and mfg number - */ - wid_reg = *(volatile int32_t *) - (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID); - - part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; - mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT; - - /* Is this the "xbow part" of an XBridge? If so, this - * widget is definitely part of an I/O brick. - */ - if( part_num == XXBOW_WIDGET_PART_NUM && - mfg_num == XXBOW_WIDGET_MFGR_NUM ) - - return 1; - - /* Is this a "bridge part" of an XBridge? If so, once - * again, we know this widget is part of an I/O brick. - */ - if( part_num == XBRIDGE_WIDGET_PART_NUM && - mfg_num == XBRIDGE_WIDGET_MFGR_NUM ) - - return 1; - - return 0; -} - - -int cbrick_uid_get( nasid_t nasid, uint64_t *uid ) -{ - char uid_str[32]; - char msg[BRL1_QSIZE]; - int subch, len; - l1sc_t sc; - l1sc_t *scp; - int local = (nasid == get_nasid()); - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* If the promlog variable pointed to by IP27LOG_OVNIC is set, - * use that value for the cbrick UID rather than the EEPROM - * serial number. - */ -#ifdef LOG_GETENV - if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 ) - { - /* We successfully read IP27LOG_OVNIC, so return it as the UID. */ - db_printf(( "cbrick_uid_get:" - "Overriding UID with environment variable %s\n", - IP27LOG_OVNIC )); - *uid = strtoull( uid_str, NULL, 0 ); - return EEP_OK; - } -#endif - - /* If this brick is retrieving its own uid, use the local l1sc_t to - * arbitrate access to the l1; otherwise, set up a new one. - */ - if( local ) { - scp = get_l1sc(); - } - else { - scp = ≻ - sc_init( &sc, nasid, BRL1_LOCALHUB_UART ); - } - - /* fill in msg with the opcode & params */ - BZERO( msg, BRL1_QSIZE ); - if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 ) - return EEP_L1; - - if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_SER_NUM, 0 )) < 0 ) - { - sc_close( scp, subch ); - return( EEP_L1 ); - } - - /* send the request to the L1 */ - if( sc_command( scp, subch, msg, msg, &len ) ) { - sc_close( scp, subch ); - return( EEP_L1 ); - } - - /* free up subchannel */ - sc_close(scp, subch); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 ) - { - return( EEP_L1 ); - } - - *uid = generate_unique_id( uid_str, strlen( uid_str ) ); - - return EEP_OK; -} - - -int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid ) -{ - char uid_str[32]; - char msg[BRL1_QSIZE]; - int subch, len; - l1sc_t sc; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - -#define FAIL \ - { \ - *uid = rtc_time(); \ - printk( "rbrick_uid_get failed; using current time as uid\n" ); \ - return EEP_OK; \ - } - - ROUTER_LOCK(path); - sc_init( &sc, nasid, path ); - - /* fill in msg with the opcode & params */ - BZERO( msg, BRL1_QSIZE ); - if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) { - ROUTER_UNLOCK(path); - FAIL; - } - - if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_SER_NUM, 0 )) < 0 ) - { - ROUTER_UNLOCK(path); - sc_close( &sc, subch ); - FAIL; - } - - /* send the request to the L1 */ - if( sc_command( &sc, subch, msg, msg, &len ) ) { - ROUTER_UNLOCK(path); - sc_close( &sc, subch ); - FAIL; - } - - /* free up subchannel */ - ROUTER_UNLOCK(path); - sc_close(&sc, subch); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 ) - { - FAIL; - } - - *uid = generate_unique_id( uid_str, strlen( uid_str ) ); - - return EEP_OK; -} - -int iobrick_uid_get( nasid_t nasid, uint64_t *uid ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - - eep.board_ia = &board; - eep.chassis_ia = &chassis; - eep.spd = NULL; - - r = iobrick_eeprom_read( &eep, nasid, IO_BRICK ); - if( r != EEP_OK ) { - *uid = rtc_time(); - return r; - } - - *uid = generate_unique_id( board.serial_num, - board.serial_num_tl & FIELD_LENGTH_MASK ); - - return EEP_OK; -} - - -int ibrick_mac_addr_get( nasid_t nasid, char *eaddr ) -{ - eeprom_brd_record_t eep; - eeprom_board_ia_t board; - eeprom_chassis_ia_t chassis; - int r; - char *tmp; - - eep.board_ia = &board; - eep.chassis_ia = &chassis; - eep.spd = NULL; - - r = iobrick_eeprom_read( &eep, nasid, IO_BRICK ); - if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) { - db_printf(( "ibrick_mac_addr_get: " - "Couldn't read MAC address from EEPROM\n" )); - return EEP_L1; - } - else { - /* successfully read info area */ - int ix; - tmp = board.mac_addr; - for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ ) - { - *eaddr++ = *tmp++; - } - *eaddr = '\0'; - } - - return EEP_OK; -} - - -/* - * eeprom_vertex_info_set - * - * Given a vertex handle, a component designation, a starting nasid - * and (in the case of a router) a vector path to the component, this - * function will read the EEPROM and attach the resulting information - * to the vertex in the same string format as that provided by the - * Dallas Semiconductor NIC drivers. If the vertex already has the - * string, this function just returns the string. - */ - -extern char *nic_vertex_info_get( devfs_handle_t ); -extern void nic_vmc_check( devfs_handle_t, char * ); -/* the following were lifted from nic.c - change later? */ -#define MAX_INFO 2048 -#define NEWSZ(ptr,sz) ((ptr) = kern_malloc((sz))) -#define DEL(ptr) (kern_free((ptr))) - -char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v, - net_vec_t path ) -{ - char *info_tmp; - int info_len; - char *info; - - /* see if this vertex is already marked */ - info_tmp = nic_vertex_info_get(v); - if (info_tmp) return info_tmp; - - /* get a temporary place for the data */ - NEWSZ(info_tmp, MAX_INFO); - if (!info_tmp) return NULL; - - /* read the EEPROM */ - if( component & R_BRICK ) { - if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK ) - return NULL; - } - else { - if( eeprom_str( info_tmp, nasid, component ) != EEP_OK ) - return NULL; - } - - /* allocate a smaller final place */ - info_len = strlen(info_tmp)+1; - NEWSZ(info, info_len); - if (info) { - strcpy(info, info_tmp); - DEL(info_tmp); - } else { - info = info_tmp; - } - - /* add info to the vertex */ - hwgraph_info_add_LBL(v, INFO_LBL_NIC, - (arbitrary_info_t) info); - - /* see if someone else got there first */ - info_tmp = nic_vertex_info_get(v); - if (info != info_tmp) { - DEL(info); - return info_tmp; - } - - /* export the data */ - hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len); - - /* trigger all matching callbacks */ - nic_vmc_check(v, info); - - return info; -} - - -/********************************************************************* - * - * stubs for use until the Bedrock/L1 link is available - * - */ - -#include - -/* #define EEPROM_TEST */ - -/* fake eeprom reading functions (replace when the BR/L1 communication - * channel is in working order) - */ - - -/* generate a charater in [0-9A-Z]; if an "extra" character is - * specified (such as '_'), include it as one of the possibilities. - */ -char random_eeprom_ch( char extra ) -{ - char ch; - int modval = 36; - if( extra ) - modval++; - - ch = rtc_time() % modval; - - if( ch < 10 ) - ch += '0'; - else if( ch >= 10 && ch < 36 ) - ch += ('A' - 10); - else - ch = extra; - - return ch; -} - -/* create a part number of the form xxx-xxxx-xxx. - * It may be important later to generate different - * part numbers depending on the component we're - * supposed to be "reading" from, so the component - * paramter is provided. - */ -void fake_a_part_number( char *buf, int component ) -{ - int i; - switch( component ) { - - /* insert component-specific routines here */ - - case C_BRICK: - strcpy( buf, "030-1266-001" ); - break; - default: - for( i = 0; i < 12; i++ ) { - if( i == 3 || i == 8 ) - buf[i] = '-'; - else - buf[i] = random_eeprom_ch(0); - } - } -} - - -/* create a six-character serial number */ -void fake_a_serial_number( char *buf, uint64_t ser ) -{ - int i; - static const char hexchars[] = "0123456789ABCDEF"; - - if (ser) { - for( i = 5; i >=0; i-- ) { - buf[i] = hexchars[ser & 0xf]; - ser >>= 4; - } - } - else { - for( i = 0; i < 6; i++ ) - buf[i] = random_eeprom_ch(0); - } -} - - -void fake_a_product_name( uchar_t *format, char* buf, int component ) -{ - switch( component & BRICK_MASK ) { - - case C_BRICK: - if( component & SUBORD_MASK ) { - strcpy( buf, "C_BRICK_SUB" ); - *format = 0xCB; - } - else { - strcpy( buf, "IP35" ); - *format = 0xC4; - } - break; - - case R_BRICK: - if( component & SUBORD_MASK ) { - strcpy( buf, "R_BRICK_SUB" ); - *format = 0xCB; - } - else { - strcpy( buf, "R_BRICK" ); - *format = 0xC7; - } - break; - - case IO_BRICK: - if( component & SUBORD_MASK ) { - strcpy( buf, "IO_BRICK_SUB" ); - *format = 0xCC; - } - else { - strcpy( buf, "IO_BRICK" ); - *format = 0xC8; - } - break; - - default: - strcpy( buf, "UNK_DEVICE" ); - *format = 0xCA; - } -} - - - -int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, - uint64_t ser ) -{ - eeprom_board_ia_t *board; - eeprom_chassis_ia_t *chassis; - int i, cs; - - board = buf->board_ia; - chassis = buf->chassis_ia; - - if( !(component & SUBORD_MASK) ) { - if( !chassis ) - return EEP_PARAM; - chassis->format = 0; - chassis->length = 5; - chassis->type = 0x17; - - chassis->part_num_tl = 0xCC; - fake_a_part_number( chassis->part_num, component ); - chassis->serial_num_tl = 0xC6; - fake_a_serial_number( chassis->serial_num, ser ); - - cs = chassis->format + chassis->length + chassis->type - + chassis->part_num_tl + chassis->serial_num_tl; - for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += chassis->part_num[i]; - for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += chassis->serial_num[i]; - chassis->checksum = 256 - (cs % 256); - } - - if( !board ) - return EEP_PARAM; - board->format = 0; - board->length = 10; - board->language = 0; - board->mfg_date = 1789200; /* noon, 5/26/99 */ - board->manuf_tl = 0xC3; - strcpy( board->manuf, "SGI" ); - - fake_a_product_name( &(board->product_tl), board->product, component ); - - board->serial_num_tl = 0xC6; - fake_a_serial_number( board->serial_num, ser ); - - board->part_num_tl = 0xCC; - fake_a_part_number( board->part_num, component ); - - board->board_rev_tl = 0xC2; - board->board_rev[0] = '0'; - board->board_rev[1] = '1'; - - board->eeprom_size_tl = 0x01; - board->eeprom_size = 1; - - board->temp_waiver_tl = 0xC2; - board->temp_waiver[0] = '0'; - board->temp_waiver[1] = '1'; - - cs = board->format + board->length + board->language - + (board->mfg_date & 0xFF) - + (board->mfg_date & 0xFF00) - + (board->mfg_date & 0xFF0000) - + board->manuf_tl + board->product_tl + board->serial_num_tl - + board->part_num_tl + board->board_rev_tl - + board->board_rev[0] + board->board_rev[1] - + board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl - + board->temp_waiver[0] + board->temp_waiver[1]; - for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->manuf[i]; - for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->product[i]; - for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->serial_num[i]; - for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ ) - cs += board->part_num[i]; - - board->checksum = 256 - (cs % 256); - - return EEP_OK; -} - -#define EEPROM_CHUNKSIZE 64 - -#if defined(EEPROM_DEBUG) -#define RETURN_ERROR \ -{ \ - printk( "read_ia error return, component 0x%x, line %d" \ - ", address 0x%x, ia code 0x%x\n", \ - l1_compt, __LINE__, sc->subch[subch].target, ia_code ); \ - return EEP_L1; \ -} - -#else -#define RETURN_ERROR return(EEP_L1) -#endif - -int read_ia( l1sc_t *sc, int subch, int l1_compt, - int ia_code, char *eep_record ) -{ - char msg[BRL1_QSIZE]; /* message buffer */ - int len; /* number of bytes used in message buffer */ - int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */ - int offset = 0; /* current offset into info area */ - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - BZERO( msg, BRL1_QSIZE ); - - /* retrieve EEPROM data in 64-byte chunks - */ - - while( ia_len ) - { - /* fill in msg with opcode & params */ - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_EEPROM, 8, - L1_ARG_INT, l1_compt, - L1_ARG_INT, ia_code, - L1_ARG_INT, offset, - L1_ARG_INT, ia_len )) < 0 ) - { - RETURN_ERROR; - } - - /* send the request to the L1 */ - - if( sc_command( sc, subch, msg, msg, &len ) ) { - RETURN_ERROR; - } - - /* check response */ - if( sc_interpret_resp( msg, 5, - L1_ARG_INT, &ia_len, - L1_ARG_UNKNOWN, &len, eep_record ) < 0 ) - { - RETURN_ERROR; - } - - if( ia_len > EEPROM_CHUNKSIZE ) - ia_len = EEPROM_CHUNKSIZE; - - eep_record += EEPROM_CHUNKSIZE; - offset += EEPROM_CHUNKSIZE; - } - - return EEP_OK; -} - - -int read_spd( l1sc_t *sc, int subch, int l1_compt, - eeprom_spd_u *spd ) -{ - char msg[BRL1_QSIZE]; /* message buffer */ - int len; /* number of bytes used in message buffer */ - int resp; /* l1 response code */ - int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */ - int offset = 0; /* current offset into spd record */ - char *spd_p = spd->bytes; /* "thumb" for writing to spd */ - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - BZERO( msg, BRL1_QSIZE ); - - /* retrieve EEPROM data in 64-byte chunks - */ - - while( spd_len ) - { - /* fill in msg with opcode & params */ - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_EEPROM, 8, - L1_ARG_INT, l1_compt, - L1_ARG_INT, L1_EEP_SPD, - L1_ARG_INT, offset, - L1_ARG_INT, spd_len )) < 0 ) - { - return( EEP_L1 ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) ) { - return( EEP_L1 ); - } - - /* check response */ - if( (resp = sc_interpret_resp( msg, 5, - L1_ARG_INT, &spd_len, - L1_ARG_UNKNOWN, &len, spd_p )) < 0 ) - { - /* - * translate l1 response code to eeprom.c error codes: - * The L1 response will be L1_RESP_NAVAIL if the spd - * can't be read (i.e. the spd isn't physically there). It will - * return L1_RESP_INVAL if the spd exists, but fails the checksum - * test because the eeprom wasn't programmed, programmed incorrectly, - * or corrupted. L1_RESP_NAVAIL indicates the eeprom is likely not present, - * whereas L1_RESP_INVAL indicates the eeprom is present, but the data is - * invalid. - */ - if(resp == L1_RESP_INVAL) { - resp = EEP_BAD_CHECKSUM; - } else { - resp = EEP_L1; - } - return( resp ); - } - - if( spd_len > EEPROM_CHUNKSIZE ) - spd_len = EEPROM_CHUNKSIZE; - - spd_p += EEPROM_CHUNKSIZE; - offset += EEPROM_CHUNKSIZE; - } - return EEP_OK; -} - - -int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt, - eeprom_chassis_ia_t *ia ) -{ - char eep_record[512]; /* scratch area for building up info area */ - char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ - int checksum = 0; /* use to verify eeprom record checksum */ - int i; - - /* Read in info area record from the L1. - */ - if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record ) - != EEP_OK ) - { - return EEP_L1; - } - - /* Now we've got the whole info area. Transfer it to the data structure. - */ - - eep_rec_p = eep_record; - ia->format = *eep_rec_p++; - ia->length = *eep_rec_p++; - if( ia->length == 0 ) { - /* since we're using 8*ia->length-1 as an array index later, make - * sure it's sane. - */ - db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" )); - return EEP_L1; - } - ia->type = *eep_rec_p++; - - ia->part_num_tl = *eep_rec_p++; - - (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); - - ia->serial_num_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->serial_num, - (ia->serial_num_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); - - ia->checksum = eep_record[(8 * ia->length) - 1]; - - /* verify checksum */ - eep_rec_p = eep_record; - checksum = 0; - for( i = 0; i < (8 * ia->length); i++ ) { - checksum += *eep_rec_p++; - } - - if( (checksum & 0xff) != 0 ) - { - db_printf(( "read_chassis_ia: bad checksum\n" )); - db_printf(( "read_chassis_ia: target 0x%x uart 0x%lx\n", - sc->subch[subch].target, sc->uart )); - return EEP_BAD_CHECKSUM; - } - - return EEP_OK; -} - - -int read_board_ia( l1sc_t *sc, int subch, int l1_compt, - eeprom_board_ia_t *ia ) -{ - char eep_record[512]; /* scratch area for building up info area */ - char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ - int checksum = 0; /* running checksum total */ - int i; - - BZERO( ia, sizeof( eeprom_board_ia_t ) ); - - /* Read in info area record from the L1. - */ - if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record ) - != EEP_OK ) - { - db_printf(( "read_board_ia: error reading info area from L1\n" )); - return EEP_L1; - } - - /* Now we've got the whole info area. Transfer it to the data structure. - */ - - eep_rec_p = eep_record; - ia->format = *eep_rec_p++; - ia->length = *eep_rec_p++; - if( ia->length == 0 ) { - /* since we're using 8*ia->length-1 as an array index later, make - * sure it's sane. - */ - db_printf(( "read_board_ia: eeprom length byte of ZERO\n" )); - return EEP_L1; - } - ia->language = *eep_rec_p++; - - ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p ); - eep_rec_p += 3; - - ia->manuf_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK); - - ia->product_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK); - - ia->serial_num_tl = *eep_rec_p++; - - BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK)); - eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); - - ia->part_num_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); - - eep_rec_p++; /* we do not use the FRU file id */ - - ia->board_rev_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK); - - ia->eeprom_size_tl = *eep_rec_p++; - ia->eeprom_size = *eep_rec_p++; - - ia->temp_waiver_tl = *eep_rec_p++; - - BCOPY( eep_rec_p, ia->temp_waiver, - (ia->temp_waiver_tl & FIELD_LENGTH_MASK) ); - eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK); - - /* if there's more, we must be reading a main board; get - * additional fields - */ - if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { - - ia->ekey_G_tl = *eep_rec_p++; - BCOPY( eep_rec_p, (char *)&ia->ekey_G, - ia->ekey_G_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK); - - ia->ekey_P_tl = *eep_rec_p++; - BCOPY( eep_rec_p, (char *)&ia->ekey_P, - ia->ekey_P_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK); - - ia->ekey_Y_tl = *eep_rec_p++; - BCOPY( eep_rec_p, (char *)&ia->ekey_Y, - ia->ekey_Y_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK); - - /* - * need to get a couple more fields if this is an I brick - */ - if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { - - ia->mac_addr_tl = *eep_rec_p++; - BCOPY( eep_rec_p, ia->mac_addr, - ia->mac_addr_tl & FIELD_LENGTH_MASK ); - eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK); - - ia->ieee1394_cfg_tl = *eep_rec_p++; - BCOPY( eep_rec_p, ia->ieee1394_cfg, - ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK ); - - } - } - - ia->checksum = eep_record[(ia->length * 8) - 1]; - - /* verify checksum */ - eep_rec_p = eep_record; - checksum = 0; - for( i = 0; i < (8 * ia->length); i++ ) { - checksum += *eep_rec_p++; - } - - if( (checksum & 0xff) != 0 ) - { - db_printf(( "read_board_ia: bad checksum\n" )); - db_printf(( "read_board_ia: target 0x%x uart 0x%lx\n", - sc->subch[subch].target, sc->uart )); - return EEP_BAD_CHECKSUM; - } - - return EEP_OK; -} - - -int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp, - int component ) -{ - int r; - uint64_t uid = 0; -#ifdef LOG_GETENV - char uid_str[32]; -#endif - int l1_compt, subch; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* make sure we're targeting a cbrick */ - if( !(component & C_BRICK) ) - return EEP_PARAM; - - /* If the promlog variable pointed to by IP27LOG_OVNIC is set, - * use that value for the cbrick UID rather than the EEPROM - * serial number. - */ -#ifdef LOG_GETENV - if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 ) - { - db_printf(( "_cbrick_eeprom_read: " - "Overriding UID with environment variable %s\n", - IP27LOG_OVNIC )); - uid = strtoull( uid_str, NULL, 0 ); - } -#endif - - if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 ) - return EEP_L1; - - if((component & C_DIMM) == C_DIMM) { - l1_compt = L1_EEP_DIMM(component & COMPT_MASK); - r = read_spd(scp,subch,l1_compt, buf->spd); - sc_close(scp,subch); - return(r); - } - - switch( component ) - { - case C_BRICK: - /* c-brick motherboard */ - l1_compt = L1_EEP_NODE; - r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); - if( r != EEP_OK ) { - sc_close( scp, subch ); - db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); - return fake_an_eeprom_record( buf, component, uid ); - } - if( uid ) { - /* If IP27LOG_OVNIC is set, we want to put that value - * in as our UID. */ - fake_a_serial_number( buf->chassis_ia->serial_num, uid ); - buf->chassis_ia->serial_num_tl = 6; - } - break; - - case C_PIMM: - /* one of the PIMM boards */ - l1_compt = L1_EEP_PIMM( component & COMPT_MASK ); - break; - - default: - /* unsupported board type */ - sc_close( scp, subch ); - return EEP_PARAM; - } - - r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); - sc_close( scp, subch ); - if( r != EEP_OK ) - { - db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); - return fake_an_eeprom_record( buf, component, uid ); - } - return EEP_OK; -} - - -int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, - int component ) -{ - l1sc_t *scp; - int local = (nasid == get_nasid()); - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* If this brick is retrieving its own uid, use the local l1sc_t to - * arbitrate access to the l1; otherwise, set up a new one (prom) or - * use an existing remote l1sc_t (kernel) - */ - if( local ) { - scp = get_l1sc(); - } - else { - scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc; - } - - return _cbrick_eeprom_read( buf, scp, component ); -} - - -int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, - int component ) -{ - int r; - int l1_compt, subch; - l1sc_t *scp; - int local = (nasid == get_nasid()); - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* make sure we're talking to an applicable brick */ - if( !(component & IO_BRICK) ) { - return EEP_PARAM; - } - - /* If we're talking to this c-brick's attached io brick, use - * the local l1sc_t; otherwise, set up a new one (prom) or - * use an existing remote l1sc_t (kernel) - */ - if( local ) { - scp = get_l1sc(); - } - else { - scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc; - } - - if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 ) - return EEP_L1; - - - switch( component ) - { - case IO_BRICK: - /* IO brick motherboard */ - l1_compt = L1_EEP_LOGIC; - r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); - - if( r != EEP_OK ) { - sc_close( scp, subch ); - /* - * Whenever we no longer need to test on hardware - * that does not have EEPROMS, then this can be removed. - */ - r = fake_an_eeprom_record( buf, component, rtc_time() ); - return r; - } - break; - - case IO_POWER: - /* IO brick power board */ - l1_compt = L1_EEP_POWER; - break; - - default: - /* unsupported board type */ - sc_close( scp, subch ); - return EEP_PARAM; - } - - r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); - sc_close( scp, subch ); - if( r != EEP_OK ) { - return r; - } - return EEP_OK; -} - - -int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, - net_vec_t path, int component ) -{ - int r; - uint64_t uid = 0; - int l1_compt, subch; - l1sc_t sc; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return EEP_L1; - - /* make sure we're targeting an applicable brick */ - if( !(component & VECTOR) ) - return EEP_PARAM; - - switch( component & BRICK_MASK ) - { - case R_BRICK: - ROUTER_LOCK( path ); - sc_init( &sc, nasid, path ); - - if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) - { - db_printf(( "vector_eeprom_read: couldn't open subch\n" )); - ROUTER_UNLOCK(path); - return EEP_L1; - } - switch( component ) - { - case R_BRICK: - /* r-brick motherboard */ - l1_compt = L1_EEP_LOGIC; - r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia ); - if( r != EEP_OK ) { - sc_close( &sc, subch ); - ROUTER_UNLOCK( path ); - printk( "vector_eeprom_read: couldn't get rbrick eeprom info;" - " using current time as uid\n" ); - uid = rtc_time(); - db_printf(("vector_eeprom_read: using a fake eeprom record\n")); - return fake_an_eeprom_record( buf, component, uid ); - } - break; - - case R_POWER: - /* r-brick power board */ - l1_compt = L1_EEP_POWER; - break; - - default: - /* unsupported board type */ - sc_close( &sc, subch ); - ROUTER_UNLOCK( path ); - return EEP_PARAM; - } - r = read_board_ia( &sc, subch, l1_compt, buf->board_ia ); - sc_close( &sc, subch ); - ROUTER_UNLOCK( path ); - if( r != EEP_OK ) { - db_printf(( "vector_eeprom_read: using a fake eeprom record\n" )); - return fake_an_eeprom_record( buf, component, uid ); - } - return EEP_OK; - - case C_BRICK: - sc_init( &sc, nasid, path ); - return _cbrick_eeprom_read( buf, &sc, component ); - - default: - /* unsupported brick type */ - return EEP_PARAM; - } -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/efi-rtc.c linux-2.4.22/arch/ia64/sn/io/sn1/efi-rtc.c --- linux-2.4.21/arch/ia64/sn/io/sn1/efi-rtc.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/efi-rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,202 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (C) 2001 by Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * No locking necessary when this is called from efirtc which protects us - * from racing by efi_rtc_lock. - */ -#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3)) -#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr)) -#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data)) - -#define TOD_SGS_M48T35 1 -#define TOD_DALLAS_DS1386 2 - -#define TYPE_IOC3 1 -#define TYPE_IOC4 2 - -static unsigned long nvram_base = 0; -static int tod_chip_type; -static int ioc_type; - -static int -get_tod_chip_type(void) -{ - unsigned char testval; - - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - write_io_port(RTC_DAL_DAY_ADDR, 0xff); - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - - testval = read_io_port(RTC_DAL_DAY_ADDR); - if (testval == 0xff) - return TOD_SGS_M48T35; - - return TOD_DALLAS_DS1386; -} - -efi_status_t -ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps) -{ - if (!nvram_base) { - printk(KERN_CRIT "nvram_base is zero\n"); - return EFI_UNSUPPORTED; - } - - memset(time, 0, sizeof(*time)); - - switch (tod_chip_type) { - case TOD_SGS_M48T35: - write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT); - - time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF; - time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR)); - time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR)); - time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR)); - time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR)); - time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR)); - time->nanosecond = 0; - - write_io_port(RTC_SGS_CONTROL_ADDR, 0); - break; - - case TOD_DALLAS_DS1386: - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - - time->nanosecond = 0; - time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR)); - time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR)); - time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR)); - time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR)); - time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR)); - time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF; - - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - break; - - default: - break; - } - - if (caps) { - caps->resolution = 50000000; /* 50PPM */ - caps->accuracy = 1000; /* 1ms */ - caps->sets_to_zero = 0; - } - - return EFI_SUCCESS; -} - -static efi_status_t ioc3_set_time (efi_time_t *t) -{ - if (!nvram_base) { - printk(KERN_CRIT "nvram_base is zero\n"); - return EFI_UNSUPPORTED; - } - - switch (tod_chip_type) { - case TOD_SGS_M48T35: - write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE); - write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF))); - write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month)); - write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day)); - write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour)); - write_io_port(RTC_SGS_MIN_ADDR, INT_TO_BCD(t->minute)); - write_io_port(RTC_SGS_SEC_ADDR, INT_TO_BCD(t->second)); - write_io_port(RTC_SGS_CONTROL_ADDR, 0); - break; - - case TOD_DALLAS_DS1386: - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - write_io_port(RTC_DAL_SEC_ADDR, INT_TO_BCD(t->second)); - write_io_port(RTC_DAL_MIN_ADDR, INT_TO_BCD(t->minute)); - write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour)); - write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day)); - write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month)); - write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF))); - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - break; - - default: - break; - } - - return EFI_SUCCESS; -} - -/* The following two are not supported atm. */ -static efi_status_t -ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm) -{ - return EFI_UNSUPPORTED; -} - -static efi_status_t -ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm) -{ - return EFI_UNSUPPORTED; -} - -static __init int efi_ioc_time_init(void) -{ - struct pci_dev *dev = NULL; - static void *ioc_base; - - while ( (dev = pci_find_subsys(PCI_VENDOR_ID_SGI, - PCI_ANY_ID, - PCI_ANY_ID, - PCI_ANY_ID, dev))) { - if ( dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { - ioc_type = TYPE_IOC3; - break; - } - else if ( dev->device == PCI_DEVICE_ID_SGI_IOC4 ) { - ioc_type = TYPE_IOC4; - break; - } - else - ;; // keep looking - } - - if ( !dev ) { - printk(KERN_CRIT "Couldn't find master IOC\n"); - return -ENODEV; - } - - ioc_base = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0)); - if ( ioc_type == TYPE_IOC3 ) - nvram_base = (unsigned long) ioc_base + IOC3_BYTEBUS_DEV0; - if ( ioc_type == TYPE_IOC4 ) - nvram_base = (unsigned long) ioc_base + IOC4_BYTEBUS_DEV0; - - tod_chip_type = get_tod_chip_type(); - if (tod_chip_type == 1) - printk(KERN_NOTICE "TOD type is SGS M48T35\n"); - else if (tod_chip_type == 2) - printk(KERN_NOTICE "TOD type is Dallas DS1386\n"); - else - printk(KERN_CRIT "No or unknown TOD\n"); - - efi.get_time = ioc3_get_time; - efi.set_time = ioc3_set_time; - efi.get_wakeup_time = ioc3_get_wakeup_time; - efi.set_wakeup_time = ioc3_set_wakeup_time; - - return 0; -} - -module_init(efi_ioc_time_init); diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/hub_intr.c linux-2.4.22/arch/ia64/sn/io/sn1/hub_intr.c --- linux-2.4.21/arch/ia64/sn/io/sn1/hub_intr.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/hub_intr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,307 +0,0 @@ -/* $Id: hub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern xtalk_provider_t hub_provider; - -/* ARGSUSED */ -void -hub_intr_init(devfs_handle_t hubv) -{ -} - -/* - * hub_device_desc_update - * Update the passed in device descriptor with the actual the - * target cpu number and interrupt priority level. - * NOTE : These might be the same as the ones passed in thru - * the descriptor. - */ -static void -hub_device_desc_update(device_desc_t dev_desc, - ilvl_t intr_swlevel, - cpuid_t cpu) -{ -} - -int allocate_my_bit = INTRCONNECT_ANYBIT; - -/* - * Allocate resources required for an interrupt as specified in dev_desc. - * Returns a hub interrupt handle on success, or 0 on failure. - */ -static hub_intr_t -do_hub_intr_alloc(devfs_handle_t dev, /* which crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev, /* owner of this interrupt, if known */ - int uncond_nothread) /* unconditionally non-threaded */ -{ - cpuid_t cpu = (cpuid_t)0; /* cpu to receive interrupt */ - int cpupicked = 0; - int bit; /* interrupt vector */ - /*REFERENCED*/ - int intr_resflags = 0; - hub_intr_t intr_hdl; - cnodeid_t nodeid; /* node to receive interrupt */ - /*REFERENCED*/ - nasid_t nasid; /* nasid to receive interrupt */ - struct xtalk_intr_s *xtalk_info; - iopaddr_t xtalk_addr; /* xtalk addr on hub to set intr */ - xwidget_info_t xwidget_info; /* standard crosstalk widget info handle */ - char *intr_name = NULL; - ilvl_t intr_swlevel = (ilvl_t)0; - extern int default_intr_pri; - extern void synergy_intr_alloc(int, int); - - - if (dev_desc) { - if (dev_desc->flags & D_INTR_ISERR) { - intr_resflags = II_ERRORINT; - } else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) { - intr_resflags = II_THREADED; - } else { - /* Neither an error nor a thread. */ - intr_resflags = 0; - } - } else { - intr_swlevel = default_intr_pri; - if (!uncond_nothread) - intr_resflags = II_THREADED; - } - - /* XXX - Need to determine if the interrupt should be threaded. */ - - /* If the cpu has not been picked already then choose a candidate - * interrupt target and reserve the interrupt bit - */ - if (!cpupicked) { - cpu = intr_heuristic(dev,dev_desc,allocate_my_bit, - intr_resflags,owner_dev, - intr_name,&bit); - } - - /* At this point we SHOULD have a valid cpu */ - if (cpu == CPU_NONE) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "%v hub_intr_alloc could not allocate interrupt\n", - owner_dev); -#else - printk(KERN_WARNING "%p hub_intr_alloc could not allocate interrupt\n", - (void *)owner_dev); -#endif - return(0); - - } - - /* If the cpu has been picked already (due to the bridge data - * corruption bug) then try to reserve an interrupt bit . - */ - if (cpupicked) { - bit = intr_reserve_level(cpu, allocate_my_bit, - intr_resflags, - owner_dev, intr_name); - if (bit < 0) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "Could not reserve an interrupt bit for cpu " - " %d and dev %v\n", - cpu,owner_dev); -#else - printk(KERN_WARNING "Could not reserve an interrupt bit for cpu " - " %d and dev %p\n", - (int)cpu, (void *)owner_dev); -#endif - - return(0); - } - } - - nodeid = cpuid_to_cnodeid(cpu); - nasid = cpuid_to_nasid(cpu); - xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu))); - - /* - * Allocate an interrupt handle, and fill it in. There are two - * pieces to an interrupt handle: the piece needed by generic - * xtalk code which is used by crosstalk device drivers, and - * the piece needed by low-level IP27 hardware code. - */ - intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid); - ASSERT_ALWAYS(intr_hdl); - - /* - * Fill in xtalk information for generic xtalk interfaces that - * operate on xtalk_intr_hdl's. - */ - xtalk_info = &intr_hdl->i_xtalk_info; - xtalk_info->xi_dev = dev; - xtalk_info->xi_vector = bit; - xtalk_info->xi_addr = xtalk_addr; - - /* - * Regardless of which CPU we ultimately interrupt, a given crosstalk - * widget always handles interrupts (and PIO and DMA) through its - * designated "master" crosstalk provider. - */ - xwidget_info = xwidget_info_get(dev); - if (xwidget_info) - xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info); - - /* Fill in low level hub information for hub_* interrupt interface */ - intr_hdl->i_swlevel = intr_swlevel; - intr_hdl->i_cpuid = cpu; - intr_hdl->i_bit = bit; - intr_hdl->i_flags = HUB_INTR_IS_ALLOCED; - - /* Store the actual interrupt priority level & interrupt target - * cpu back in the device descriptor. - */ - hub_device_desc_update(dev_desc, intr_swlevel, cpu); - synergy_intr_alloc((int)bit, (int)cpu); - return(intr_hdl); -} - -/* - * Allocate resources required for an interrupt as specified in dev_desc. - * Returns a hub interrupt handle on success, or 0 on failure. - */ -hub_intr_t -hub_intr_alloc( devfs_handle_t dev, /* which crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) /* owner of this interrupt, if known */ -{ - return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0)); -} - -/* - * Allocate resources required for an interrupt as specified in dev_desc. - * Uncondtionally request non-threaded, regardless of what the device - * descriptor might say. - * Returns a hub interrupt handle on success, or 0 on failure. - */ -hub_intr_t -hub_intr_alloc_nothd(devfs_handle_t dev, /* which crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) /* owner of this interrupt, if known */ -{ - return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1)); -} - -/* - * Free resources consumed by intr_alloc. - */ -void -hub_intr_free(hub_intr_t intr_hdl) -{ - cpuid_t cpu = intr_hdl->i_cpuid; - int bit = intr_hdl->i_bit; - xtalk_intr_t xtalk_info; - - if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) { - /* Setting the following fields in the xtalk interrupt info - * clears the interrupt target register in the xtalk user - */ - xtalk_info = &intr_hdl->i_xtalk_info; - xtalk_info->xi_dev = NODEV; - xtalk_info->xi_vector = 0; - xtalk_info->xi_addr = 0; - hub_intr_disconnect(intr_hdl); - } - - if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED) - kfree(intr_hdl); - - intr_unreserve_level(cpu, bit); -} - - -/* - * Associate resources allocated with a previous hub_intr_alloc call with the - * described handler, arg, name, etc. - */ -/*ARGSUSED*/ -int -hub_intr_connect( hub_intr_t intr_hdl, /* xtalk intr resource handle */ - xtalk_intr_setfunc_t setfunc, /* func to set intr hw */ - void *setfunc_arg) /* arg to setfunc */ -{ - int rv; - cpuid_t cpu = intr_hdl->i_cpuid; - int bit = intr_hdl->i_bit; - extern int synergy_intr_connect(int, int); - - ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED); - - rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, NULL); - if (rv < 0) - return(rv); - - intr_hdl->i_xtalk_info.xi_setfunc = setfunc; - intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg; - - if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl); - - intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED; - return(synergy_intr_connect((int)bit, (int)cpu)); -} - - -/* - * Disassociate handler with the specified interrupt. - */ -void -hub_intr_disconnect(hub_intr_t intr_hdl) -{ - /*REFERENCED*/ - int rv; - cpuid_t cpu = intr_hdl->i_cpuid; - int bit = intr_hdl->i_bit; - xtalk_intr_setfunc_t setfunc; - - setfunc = intr_hdl->i_xtalk_info.xi_setfunc; - - /* TBD: send disconnected interrupts somewhere harmless */ - if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl); - - rv = intr_disconnect_level(cpu, bit); - ASSERT(rv == 0); - intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED; -} - - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. - */ -devfs_handle_t -hub_intr_cpu_get(hub_intr_t intr_hdl) -{ - cpuid_t cpuid = intr_hdl->i_cpuid; - ASSERT(cpuid != CPU_NONE); - - return(cpuid_to_vertex(cpuid)); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/hubcounters.c linux-2.4.22/arch/ia64/sn/io/sn1/hubcounters.c --- linux-2.4.21/arch/ia64/sn/io/sn1/hubcounters.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/hubcounters.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,282 +0,0 @@ -/* $Id: hubcounters.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All Rights Reserved. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void hubni_error_handler(char *, int); /* huberror.c */ - -static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -struct file_operations hub_mon_fops = { - ioctl: hubstats_ioctl, -}; - -#define HUB_CAPTURE_TICKS (2 * HZ) - -#define HUB_ERR_THRESH 500 -#define USEC_PER_SEC 1000000 -#define NSEC_PER_SEC USEC_PER_SEC*1000 - -volatile int hub_print_usecs = 600 * USEC_PER_SEC; - -/* Return success if the hub's crosstalk link is working */ -int -hub_xtalk_link_up(nasid_t nasid) -{ - hubreg_t llp_csr_reg; - - /* Read the IO LLP control status register */ - llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); - - /* Check if the xtalk link is working */ - if (llp_csr_reg & IIO_LLP_CSR_IS_UP) - return(1); - - return(0); - - -} - -static char *error_flag_to_type(unsigned char error_flag) -{ - switch(error_flag) { - case 0x1: return ("NI retries"); - case 0x2: return ("NI SN errors"); - case 0x4: return ("NI CB errors"); - case 0x8: return ("II CB errors"); - case 0x10: return ("II SN errors"); - default: return ("Errors"); - } -} - -int -print_hub_error(hubstat_t *hsp, hubreg_t reg, - int64_t delta, unsigned char error_flag) -{ - int64_t rate; - - reg *= hsp->hs_per_minute; /* Convert to minutes */ - rate = reg / delta; - - if (rate > HUB_ERR_THRESH) { - - if(hsp->hs_maint & error_flag) - { - printk( "Excessive %s (%ld/min) on %s", - error_flag_to_type(error_flag), rate, hsp->hs_name); - } - else - { - hsp->hs_maint |= error_flag; - printk( "Excessive %s (%ld/min) on %s", - error_flag_to_type(error_flag), rate, hsp->hs_name); - } - return 1; - } else { - return 0; - } -} - - -int -check_hub_error_rates(hubstat_t *hsp) -{ - int64_t delta = hsp->hs_timestamp - hsp->hs_timebase; - int printed = 0; - - printed += print_hub_error(hsp, hsp->hs_ni_retry_errors, - delta, 0x1); - -#if 0 - printed += print_hub_error(hsp, hsp->hs_ni_sn_errors, - delta, 0x2); -#endif - - printed += print_hub_error(hsp, hsp->hs_ni_cb_errors, - delta, 0x4); - - - /* If the hub's xtalk link is not working there is - * no need to print the "Excessive..." warning - * messages - */ - if (!hub_xtalk_link_up(hsp->hs_nasid)) - return(printed); - - - printed += print_hub_error(hsp, hsp->hs_ii_cb_errors, - delta, 0x8); - - printed += print_hub_error(hsp, hsp->hs_ii_sn_errors, - delta, 0x10); - - return printed; -} - - -void -capture_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda) -{ - nasid_t nasid; - hubstat_t *hsp = &(npda->hubstats); - hubreg_t port_error; - ii_illr_u_t illr; - int count; - int overflow = 0; - - /* - * If our link wasn't up at boot time, don't worry about error rates. - */ - if (!(hsp->hs_ni_port_status & NPS_LINKUP_MASK)) { - printk("capture_hub_stats: cnode=%d hs_ni_port_status=0x%016lx : link is not up\n", - cnodeid, hsp->hs_ni_port_status); - return; - } - - nasid = COMPACT_TO_NASID_NODEID(cnodeid); - - hsp->hs_timestamp = GET_RTC_COUNTER(); - - port_error = REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR); - count = ((port_error & NPE_RETRYCOUNT_MASK) >> NPE_RETRYCOUNT_SHFT); - hsp->hs_ni_retry_errors += count; - if (count == NPE_COUNT_MAX) - overflow = 1; - count = ((port_error & NPE_SNERRCOUNT_MASK) >> NPE_SNERRCOUNT_SHFT); - hsp->hs_ni_sn_errors += count; - if (count == NPE_COUNT_MAX) - overflow = 1; - count = ((port_error & NPE_CBERRCOUNT_MASK) >> NPE_CBERRCOUNT_SHFT); - hsp->hs_ni_cb_errors += count; - if (overflow || count == NPE_COUNT_MAX) - hsp->hs_ni_overflows++; - - if (port_error & NPE_FATAL_ERRORS) { -#ifdef ajm - hubni_error_handler("capture_hub_stats", 1); -#else - printk("Error: hubni_error_handler in capture_hub_stats"); -#endif - } - - illr.ii_illr_regval = REMOTE_HUB_L(nasid, IIO_LLP_LOG); - REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0); - - hsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt; - hsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt; - if ((illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) || - (illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX)) - hsp->hs_ii_overflows++; - - if (hsp->hs_print) { - if (check_hub_error_rates(hsp)) { - hsp->hs_last_print = GET_RTC_COUNTER(); - hsp->hs_print = 0; - } - } else { - if ((GET_RTC_COUNTER() - - hsp->hs_last_print) > hub_print_usecs) - hsp->hs_print = 1; - } - - npda->hubticks = HUB_CAPTURE_TICKS; -} - - -void -init_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda) -{ - hubstat_t *hsp = &(npda->hubstats); - nasid_t nasid = cnodeid_to_nasid(cnodeid); - bzero(&(npda->hubstats), sizeof(hubstat_t)); - - hsp->hs_version = HUBSTAT_VERSION; - hsp->hs_cnode = cnodeid; - hsp->hs_nasid = nasid; - hsp->hs_timebase = GET_RTC_COUNTER(); - hsp->hs_ni_port_status = REMOTE_HUB_L(nasid, NI_PORT_STATUS); - - /* Clear the II error counts. */ - REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0); - - /* Clear the NI counts. */ - REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR); - - hsp->hs_per_minute = (long long)RTC_CYCLES_PER_SEC * 60LL; - - npda->hubticks = HUB_CAPTURE_TICKS; - - /* XX should use kmem_alloc_node */ - hsp->hs_name = (char *)kmalloc(MAX_HUB_PATH, GFP_KERNEL); - ASSERT_ALWAYS(hsp->hs_name); - - sprintf(hsp->hs_name, "/dev/hw/" EDGE_LBL_MODULE "/%03d/" - EDGE_LBL_NODE "/" EDGE_LBL_HUB, - npda->module_id); - - hsp->hs_last_print = 0; - hsp->hs_print = 1; - - hub_print_usecs = hub_print_usecs; - -#if 0 - printk("init_hub_stats: cnode=%d nasid=%d hs_version=%d hs_ni_port_status=0x%016lx\n", - cnodeid, nasid, hsp->hs_version, hsp->hs_ni_port_status); -#endif -} - -static int -hubstats_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - cnodeid_t cnode; - nodepda_t *npdap; - uint64_t longarg; - devfs_handle_t d; - - if ((d = devfs_get_handle_from_inode(inode)) == NULL) - return -ENODEV; - cnode = (cnodeid_t)hwgraph_fastinfo_get(d); - npdap = NODEPDA(cnode); - - if (npdap->hubstats.hs_version != HUBSTAT_VERSION) { - init_hub_stats(cnode, npdap); - } - - switch (cmd) { - case SNDRV_GET_INFOSIZE: - longarg = sizeof(hubstat_t); - if (copy_to_user((void *)arg, &longarg, sizeof(longarg))) { - return -EFAULT; - } - break; - - case SNDRV_GET_HUBINFO: - /* refresh npda->hubstats */ - capture_hub_stats(cnode, npdap); - if (copy_to_user((void *)arg, &npdap->hubstats, sizeof(hubstat_t))) { - return -EFAULT; - } - break; - - default: - return -EINVAL; - } - - return 0; -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/huberror.c linux-2.4.22/arch/ia64/sn/io/sn1/huberror.c --- linux-2.4.21/arch/ia64/sn/io/sn1/huberror.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/huberror.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,228 +0,0 @@ -/* $Id: huberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void hubni_eint_init(cnodeid_t cnode); -extern void hubii_eint_init(cnodeid_t cnode); -extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep); -extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs); - -extern int maxcpus; - -#define HUB_ERROR_PERIOD (120 * HZ) /* 2 minutes */ - - -void -hub_error_clear(nasid_t nasid) -{ - int i; - hubreg_t idsr; - int sn; - - for(sn=0; snh_cnodeid == cnode); - - ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR); - - if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) { - /* - * HUB II link is not up. - * Just disable LLP, and don't connect any interrupts. - */ - ilcsr.ii_ilcsr_fld_s.i_llp_en = 0; - REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval); - return; - } - /* Select a possible interrupt target where there is a free interrupt - * bit and also reserve the interrupt bit for this IO error interrupt - */ - intr_cpu = intr_heuristic(hub_v,0,INTRCONNECT_ANYBIT,II_ERRORINT,hub_v, - "HUB IO error interrupt",&bit); - if (intr_cpu == CPU_NONE) { - printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode); - return; - } - - rv = intr_connect_level(intr_cpu, bit, 0, NULL); - synergy_intr_connect(bit, intr_cpu); - request_irq(bit_pos_to_irq(bit) + (intr_cpu << 8), hubii_eint_handler, 0, "SN hub error", (void *)hub_v); - ASSERT_ALWAYS(rv >= 0); - hubio_eint.ii_iidsr_regval = 0; - hubio_eint.ii_iidsr_fld_s.i_enable = 1; - hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/ - hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode); - hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu); - REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval); - -} - -void -hubni_eint_init(cnodeid_t cnode) -{ - int intr_bit; - cpuid_t targ; - - - if ((targ = cnodeid_to_cpuid(cnode)) == CPU_NONE) - return; - - /* The prom chooses which cpu gets these interrupts, but we - * don't know which one it chose. We will register all of the - * cpus to be sure. This only costs us an irqaction per cpu. - */ - for (; targ < CPUS_PER_NODE; targ++) { - if (!cpu_enabled(targ) ) continue; - /* connect the INTEND1 bits. */ - for (intr_bit = XB_ERROR; intr_bit <= MSC_PANIC_INTR; intr_bit++) { - intr_connect_level(targ, intr_bit, II_ERRORINT, NULL); - } - request_irq(SGI_HUB_ERROR_IRQ + (targ << 8), snia_error_intr_handler, 0, "SN hub error", NULL); - /* synergy masks are initialized in the prom to enable all interrupts. */ - /* We'll just leave them that way, here, for these interrupts. */ - } -} - - -/*ARGSUSED*/ -void -hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) -{ - - panic("Hubii interrupt\n"); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/ip37.c linux-2.4.22/arch/ia64/sn/io/sn1/ip37.c --- linux-2.4.21/arch/ia64/sn/io/sn1/ip37.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/ip37.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,47 +0,0 @@ -/* - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * ip37.c - * Support for IP35/IP37 machines - */ - -#include - -#include -#include -#include -#include /* for bridge_t */ - - -xwidgetnum_t -hub_widget_id(nasid_t nasid) -{ - hubii_wcr_t ii_wcr; /* the control status register */ - - ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR); - - return ii_wcr.wcr_fields_s.wcr_widget_id; -} - -int -is_fine_dirmode(void) -{ - return (((LOCAL_HUB_L(LB_REV_ID) & LRI_SYSTEM_SIZE_MASK) - >> LRI_SYSTEM_SIZE_SHFT) == SYSTEM_SIZE_SMALL); - -} - - -void -ni_reset_port(void) -{ - LOCAL_HUB_S(NI_RESET_ENABLE, NRE_RESETOK); - LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/klconflib.c linux-2.4.22/arch/ia64/sn/io/sn1/klconflib.c --- linux-2.4.21/arch/ia64/sn/io/sn1/klconflib.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/klconflib.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,979 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define printf printk -int hasmetarouter; - -#define LDEBUG 0 -#define NIC_UNKNOWN ((nic_t) -1) - -#undef DEBUG_KLGRAPH -#ifdef DEBUG_KLGRAPH -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* DEBUG_KLGRAPH */ - -static void sort_nic_names(lboard_t *) ; - -u64 klgraph_addr[MAX_COMPACT_NODES]; -int module_number = 0; - -lboard_t * -find_lboard(lboard_t *start, unsigned char brd_type) -{ - /* Search all boards stored on this node. */ - while (start) { - if (start->brd_type == brd_type) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -lboard_t * -find_lboard_class(lboard_t *start, unsigned char brd_type) -{ - /* Search all boards stored on this node. */ - while (start) { - if (KLCLASS(start->brd_type) == KLCLASS(brd_type)) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -klinfo_t * -find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type) -{ - int index, j; - - if (kli == (klinfo_t *)NULL) { - index = 0; - } else { - for (j = 0; j < KLCF_NUM_COMPS(brd); j++) { - if (kli == KLCF_COMP(brd, j)) - break; - } - index = j; - if (index == KLCF_NUM_COMPS(brd)) { - DBG("find_component: Bad pointer: 0x%p\n", kli); - return (klinfo_t *)NULL; - } - index++; /* next component */ - } - - for (; index < KLCF_NUM_COMPS(brd); index++) { - kli = KLCF_COMP(brd, index); - DBG("find_component: brd %p kli %p request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli)); - if (KLCF_COMP_TYPE(kli) == struct_type) - return kli; - } - - /* Didn't find it. */ - return (klinfo_t *)NULL; -} - -klinfo_t * -find_first_component(lboard_t *brd, unsigned char struct_type) -{ - return find_component(brd, (klinfo_t *)NULL, struct_type); -} - -lboard_t * -find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot) -{ - /* Search all boards stored on this node. */ - while (start) { - if (MODULE_MATCH(start->brd_module, mod) && - (start->brd_slot == slot)) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -lboard_t * -find_lboard_module(lboard_t *start, moduleid_t mod) -{ - /* Search all boards stored on this node. */ - while (start) { - if (MODULE_MATCH(start->brd_module, mod)) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -lboard_t * -find_lboard_module_class(lboard_t *start, moduleid_t mod, - unsigned char brd_type) -{ - while (start) { - DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type); - - if (MODULE_MATCH(start->brd_module, mod) && - (KLCLASS(start->brd_type) == KLCLASS(brd_type))) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - - -/* - * Convert a NIC name to a name for use in the hardware graph. - */ -void -nic_name_convert(char *old_name, char *new_name) -{ - int i; - char c; - char *compare_ptr; - - if ((old_name[0] == '\0') || (old_name[1] == '\0')) { - strcpy(new_name, EDGE_LBL_XWIDGET); - } else { - for (i = 0; i < strlen(old_name); i++) { - c = old_name[i]; - - if (isalpha(c)) - new_name[i] = tolower(c); - else if (isdigit(c)) - new_name[i] = c; - else - new_name[i] = '_'; - } - new_name[i] = '\0'; - } - - /* XXX - - * Since a bunch of boards made it out with weird names like - * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and - * replace it with "baseio" to avoid confusion in the field. - * We also have to make sure we don't report media_io instead of - * baseio. - */ - - /* Skip underscores at the beginning of the name */ - for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++) - ; - - /* - * Check for some names we need to replace. Early boards - * had junk following the name so check only the first - * characters. - */ - if (!strncmp(new_name, "io6", 3) || - !strncmp(new_name, "mio", 3) || - !strncmp(new_name, "media_io", 8)) - strcpy(new_name, "baseio"); - else if (!strncmp(new_name, "divo", 4)) - strcpy(new_name, "divo") ; - -} - -/* Check if the given board corresponds to the global - * master io6 - */ -int -is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot) -{ - lboard_t *board; - -/* If this works then look for callers of is_master_baseio() - * (e.g. iograph.c) and let them pass in a slot if they want - */ - board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module); - -#ifndef _STANDALONE - { - cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); - - if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) - board = find_lboard_module((lboard_t *) - KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), - module); - } -#endif - if (!board) - return(0); - return(board->brd_flags & GLOBAL_MASTER_IO6); -} -/* - * Find the lboard structure and get the board name. - * If we can't find the structure or it's too low a revision, - * use default name. - */ -lboard_t * -get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name) -{ - lboard_t *brd; - - brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), - mod, slot); - -#ifndef _STANDALONE - { - cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); - - if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) - brd = find_lboard_modslot((lboard_t *) - KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), - mod, slot); - } -#endif - - if (!brd || (brd->brd_sversion < 2)) { - strcpy(name, EDGE_LBL_XWIDGET); - } else { - nic_name_convert(brd->brd_name, name); - } - - /* - * PV # 540860 - * If the name is not 'baseio' - * get the lowest of all the names in the nic string. - * This is needed for boards like divo, which can have - * a bunch of daughter cards, but would like to be called - * divo. We could do this for baseio - * but it has some special case names that we would not - * like to disturb at this point. - */ - - /* gfx boards don't need any of this name scrambling */ - if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) { - return(brd); - } - - if (!(!strcmp(name, "baseio") )) { - if (brd) { - sort_nic_names(brd) ; - /* Convert to small case, '-' to '_' etc */ - nic_name_convert(brd->brd_name, name) ; - } - } - - return(brd); -} - -/* - * get_actual_nasid - * - * Completely disabled brds have their klconfig on - * some other nasid as they have no memory. But their - * actual nasid is hidden in the klconfig. Use this - * routine to get it. Works for normal boards too. - */ -nasid_t -get_actual_nasid(lboard_t *brd) -{ - klhub_t *hub ; - - if (!brd) - return INVALID_NASID ; - - /* find out if we are a completely disabled brd. */ - - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); - if (!hub) - return INVALID_NASID ; - if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */ - return hub->hub_info.physid ; - else - return brd->brd_nasid ; -} - -int -xbow_port_io_enabled(nasid_t nasid, int link) -{ - lboard_t *brd; - klxbow_t *xbow_p; - - /* - * look for boards that might contain an xbow or xbridge - */ - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW); - if (brd == NULL) return 0; - - if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) - == NULL) - return 0; - - if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link)) - return 0; - - return 1; -} - -void -board_to_path(lboard_t *brd, char *path) -{ - moduleid_t modnum; - char *board_name; - - ASSERT(brd); - - switch (KLCLASS(brd->brd_type)) { - - case KLCLASS_NODE: - board_name = EDGE_LBL_NODE; - break; - case KLCLASS_ROUTER: - if (brd->brd_type == KLTYPE_META_ROUTER) { - board_name = EDGE_LBL_META_ROUTER; - hasmetarouter++; - } else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) { - board_name = EDGE_LBL_REPEATER_ROUTER; - hasmetarouter++; - } else - board_name = EDGE_LBL_ROUTER; - break; - case KLCLASS_MIDPLANE: - board_name = EDGE_LBL_MIDPLANE; - break; - case KLCLASS_IO: - board_name = EDGE_LBL_IO; - break; - case KLCLASS_IOBRICK: - if (brd->brd_type == KLTYPE_PBRICK) - board_name = EDGE_LBL_PBRICK; - else if (brd->brd_type == KLTYPE_IBRICK) - board_name = EDGE_LBL_IBRICK; - else if (brd->brd_type == KLTYPE_XBRICK) - board_name = EDGE_LBL_XBRICK; - else - board_name = EDGE_LBL_IOBRICK; - break; - default: - board_name = EDGE_LBL_UNKNOWN; - } - - modnum = brd->brd_module; - - /* ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); */ -if ((modnum == MODULE_UNKNOWN) || (modnum == INVALID_MODULE)) { - modnum = ++module_number; -} -#ifdef __ia64 - { - char buffer[16]; - memset(buffer, 0, 16); - format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF); - sprintf(path, EDGE_LBL_MODULE "/%s/%s", buffer, board_name); - } -#else - sprintf(path, "%H/%s", modnum, board_name); -#endif -} - -/* - * Get the module number for a NASID. - */ -moduleid_t -get_module_id(nasid_t nasid) -{ - lboard_t *brd; - - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - - if (!brd) - return INVALID_MODULE; - else - return brd->brd_module; -} - - -#define MHZ 1000000 - - -/* Get the canonical hardware graph name for the given pci component - * on the given io board. - */ -void -device_component_canonical_name_get(lboard_t *brd, - klinfo_t *component, - char *name) -{ - moduleid_t modnum; - slotid_t slot; - char board_name[20]; - - ASSERT(brd); - - /* Get the module number of this board */ - modnum = brd->brd_module; - - /* Convert the [ CLASS | TYPE ] kind of slotid - * into a string - */ - slot = brd->brd_slot; - ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); - - /* Get the io board name */ - if (!brd || (brd->brd_sversion < 2)) { - strcpy(name, EDGE_LBL_XWIDGET); - } else { - nic_name_convert(brd->brd_name, board_name); - } - - /* Give out the canonical name of the pci device*/ - sprintf(name, - "/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/" - EDGE_LBL_PCI"/%d", - modnum, board_name,KLCF_BRIDGE_W_ID(component)); -} - -/* - * Get the serial number of the main component of a board - * Returns 0 if a valid serial number is found - * 1 otherwise. - * Assumptions: Nic manufacturing string has the following format - * *Serial:;* - */ -static int -component_serial_number_get(lboard_t *board, - klconf_off_t mfg_nic_offset, - char *serial_number, - char *key_pattern) -{ - - char *mfg_nic_string; - char *serial_string,*str; - int i; - char *serial_pattern = "Serial:"; - - /* We have an error on a null mfg nic offset */ - if (!mfg_nic_offset) - return(1); - /* Get the hub's manufacturing nic information - * which is in the form of a pre-formatted string - */ - mfg_nic_string = - (char *)NODE_OFFSET_TO_K0(NASID_GET(board), - mfg_nic_offset); - /* There is no manufacturing nic info */ - if (!mfg_nic_string) - return(1); - - str = mfg_nic_string; - /* Look for the key pattern first (if it is specified) - * and then print the serial number corresponding to that. - */ - if (strcmp(key_pattern,"") && - !(str = strstr(mfg_nic_string,key_pattern))) - return(1); - - /* There is no serial number info in the manufacturing - * nic info - */ - if (!(serial_string = strstr(str,serial_pattern))) - return(1); - - serial_string = serial_string + strlen(serial_pattern); - /* Copy the serial number information from the klconfig */ - i = 0; - while (serial_string[i] != ';') { - serial_number[i] = serial_string[i]; - i++; - } - serial_number[i] = 0; - - return(0); -} -/* - * Get the serial number of a board - * Returns 0 if a valid serial number is found - * 1 otherwise. - */ - -int -board_serial_number_get(lboard_t *board,char *serial_number) -{ - ASSERT(board && serial_number); - if (!board || !serial_number) - return(1); - - strcpy(serial_number,""); - switch(KLCLASS(board->brd_type)) { - case KLCLASS_CPU: { /* Node board */ - klhub_t *hub; - - /* Get the hub component information */ - hub = (klhub_t *)find_first_component(board, - KLSTRUCT_HUB); - /* If we don't have a hub component on an IP27 - * then we have a weird klconfig. - */ - if (!hub) - return(1); - /* Get the serial number information from - * the hub's manufacturing nic info - */ - if (component_serial_number_get(board, - hub->hub_mfg_nic, - serial_number, - "IP37")) - return(1); - break; - } - case KLCLASS_IO: { /* IO board */ - if (KLTYPE(board->brd_type) == KLTYPE_TPU) { - /* Special case for TPU boards */ - kltpu_t *tpu; - - /* Get the tpu component information */ - tpu = (kltpu_t *)find_first_component(board, - KLSTRUCT_TPU); - /* If we don't have a tpu component on a tpu board - * then we have a weird klconfig. - */ - if (!tpu) - return(1); - /* Get the serial number information from - * the tpu's manufacturing nic info - */ - if (component_serial_number_get(board, - tpu->tpu_mfg_nic, - serial_number, - "")) - return(1); - break; - } else if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) || - (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) { - /* Special case for GSN boards */ - klgsn_t *gsn; - - /* Get the gsn component information */ - gsn = (klgsn_t *)find_first_component(board, - ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ? - KLSTRUCT_GSN_A : KLSTRUCT_GSN_B)); - /* If we don't have a gsn component on a gsn board - * then we have a weird klconfig. - */ - if (!gsn) - return(1); - /* Get the serial number information from - * the gsn's manufacturing nic info - */ - if (component_serial_number_get(board, - gsn->gsn_mfg_nic, - serial_number, - "")) - return(1); - break; - } else { - klbri_t *bridge; - - /* Get the bridge component information */ - bridge = (klbri_t *)find_first_component(board, - KLSTRUCT_BRI); - /* If we don't have a bridge component on an IO board - * then we have a weird klconfig. - */ - if (!bridge) - return(1); - /* Get the serial number information from - * the bridge's manufacturing nic info - */ - if (component_serial_number_get(board, - bridge->bri_mfg_nic, - serial_number, - "")) - return(1); - break; - } - } - case KLCLASS_ROUTER: { /* Router board */ - klrou_t *router; - - /* Get the router component information */ - router = (klrou_t *)find_first_component(board, - KLSTRUCT_ROU); - /* If we don't have a router component on a router board - * then we have a weird klconfig. - */ - if (!router) - return(1); - /* Get the serial number information from - * the router's manufacturing nic info - */ - if (component_serial_number_get(board, - router->rou_mfg_nic, - serial_number, - "")) - return(1); - break; - } - case KLCLASS_GFX: { /* Gfx board */ - klgfx_t *graphics; - - /* Get the graphics component information */ - graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX); - /* If we don't have a gfx component on a gfx board - * then we have a weird klconfig. - */ - if (!graphics) - return(1); - /* Get the serial number information from - * the graphics's manufacturing nic info - */ - if (component_serial_number_get(board, - graphics->gfx_mfg_nic, - serial_number, - "")) - return(1); - break; - } - default: - strcpy(serial_number,""); - break; - } - return(0); -} - -#include "asm/sn/sn_private.h" - -xwidgetnum_t -nodevertex_widgetnum_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - return(hubinfo_p->h_widgetid); -} - -devfs_handle_t -nodevertex_xbow_peer_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - nasid_t xbow_peer_nasid; - cnodeid_t xbow_peer; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer; - if(xbow_peer_nasid == INVALID_NASID) - return ( (devfs_handle_t)-1); - xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid); - return(NODEPDA(xbow_peer)->node_vertex); -} - -/* NIC Sorting Support */ - -#define MAX_NICS_PER_STRING 32 -#define MAX_NIC_NAME_LEN 32 - -static char * -get_nic_string(lboard_t *lb) -{ - int i; - klinfo_t *k = NULL ; - klconf_off_t mfg_off = 0 ; - char *mfg_nic = NULL ; - - for (i = 0; i < KLCF_NUM_COMPS(lb); i++) { - k = KLCF_COMP(lb, i) ; - switch(k->struct_type) { - case KLSTRUCT_BRI: - mfg_off = ((klbri_t *)k)->bri_mfg_nic ; - break ; - - case KLSTRUCT_HUB: - mfg_off = ((klhub_t *)k)->hub_mfg_nic ; - break ; - - case KLSTRUCT_ROU: - mfg_off = ((klrou_t *)k)->rou_mfg_nic ; - break ; - - case KLSTRUCT_GFX: - mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ; - break ; - - case KLSTRUCT_TPU: - mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ; - break ; - - case KLSTRUCT_GSN_A: - case KLSTRUCT_GSN_B: - mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ; - break ; - - case KLSTRUCT_XTHD: - mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ; - break; - - default: - mfg_off = 0 ; - break ; - } - if (mfg_off) - break ; - } - - if ((mfg_off) && (k)) - mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ; - - return mfg_nic ; -} - -char * -get_first_string(char **ptrs, int n) -{ - int i ; - char *tmpptr ; - - if ((ptrs == NULL) || (n == 0)) - return NULL ; - - tmpptr = ptrs[0] ; - - if (n == 1) - return tmpptr ; - - for (i = 0 ; i < n ; i++) { - if (strcmp(tmpptr, ptrs[i]) > 0) - tmpptr = ptrs[i] ; - } - - return tmpptr ; -} - -int -get_ptrs(char *idata, char **ptrs, int n, char *label) -{ - int i = 0 ; - char *tmp = idata ; - - if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0)) - return 0 ; - - while ( (tmp = strstr(tmp, label)) ){ - tmp += strlen(label) ; - /* check for empty name field, and last NULL ptr */ - if ((i < (n-1)) && (*tmp != ';')) { - ptrs[i++] = tmp ; - } - } - - ptrs[i] = NULL ; - - return i ; -} - -/* - * sort_nic_names - * - * Does not really do sorting. Find the alphabetically lowest - * name among all the nic names found in a nic string. - * - * Return: - * Nothing - * - * Side Effects: - * - * lb->brd_name gets the new name found - */ - -static void -sort_nic_names(lboard_t *lb) -{ - char *nic_str ; - char *ptrs[MAX_NICS_PER_STRING] ; - char name[MAX_NIC_NAME_LEN] ; - char *tmp, *tmp1 ; - - *name = 0 ; - - /* Get the nic pointer from the lb */ - - if ((nic_str = get_nic_string(lb)) == NULL) - return ; - - tmp = get_first_string(ptrs, - get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ; - - if (tmp == NULL) - return ; - - if ( (tmp1 = strchr(tmp, ';')) ){ - strncpy(name, tmp, tmp1-tmp) ; - name[tmp1-tmp] = 0 ; - } else { - strncpy(name, tmp, (sizeof(name) -1)) ; - name[sizeof(name)-1] = 0 ; - } - - strcpy(lb->brd_name, name) ; -} - - - -char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345"; - - -/* - * Format a module id for printing. - */ -void -format_module_id(char *buffer, moduleid_t m, int fmt) -{ - int rack, position; - char brickchar; - - rack = MODULE_GET_RACK(m); - ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES); - brickchar = MODULE_GET_BTCHAR(m); - position = MODULE_GET_BPOS(m); - - if (fmt == MODULE_FORMAT_BRIEF) { - /* Brief module number format, eg. 002c15 */ - - /* Decompress the rack number */ - *buffer++ = '0' + RACK_GET_CLASS(rack); - *buffer++ = '0' + RACK_GET_GROUP(rack); - *buffer++ = '0' + RACK_GET_NUM(rack); - - /* Add the brick type */ - *buffer++ = brickchar; - } - else if (fmt == MODULE_FORMAT_LONG) { - /* Fuller hwgraph format, eg. rack/002/bay/15 */ - - strcpy(buffer, EDGE_LBL_RACK "/"); buffer += strlen(buffer); - - *buffer++ = '0' + RACK_GET_CLASS(rack); - *buffer++ = '0' + RACK_GET_GROUP(rack); - *buffer++ = '0' + RACK_GET_NUM(rack); - - strcpy(buffer, "/" EDGE_LBL_RPOS "/"); buffer += strlen(buffer); - } - - /* Add the bay position, using at least two digits */ - if (position < 10) - *buffer++ = '0'; - sprintf(buffer, "%d", position); - -} - -/* - * Parse a module id, in either brief or long form. - * Returns < 0 on error. - * The long form does not include a brick type, so it defaults to 0 (CBrick) - */ -int -parse_module_id(char *buffer) -{ - unsigned int v, rack, bay, type, form; - moduleid_t m; - char c; - - if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) { - form = MODULE_FORMAT_LONG; - buffer += strlen(EDGE_LBL_RACK "/"); - - /* A long module ID must be exactly 5 non-template chars. */ - if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5) - return -1; - } - else { - form = MODULE_FORMAT_BRIEF; - - /* A brief module id must be exactly 6 characters */ - if (strlen(buffer) != 6) - return -2; - } - - /* The rack number must be exactly 3 digits */ - if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2]))) - return -3; - - rack = 0; - v = *buffer++ - '0'; - if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) - return -4; - RACK_ADD_CLASS(rack, v); - - v = *buffer++ - '0'; - if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) - return -5; - RACK_ADD_GROUP(rack, v); - - v = *buffer++ - '0'; - /* rack numbers are 1-based */ - if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) - return -6; - RACK_ADD_NUM(rack, v); - - if (form == MODULE_FORMAT_BRIEF) { - /* Next should be a module type character. Accept ucase or lcase. */ - c = *buffer++; - if (!isalpha(c)) - return -7; - - /* strchr() returns a pointer into brick_types[], or NULL */ - type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types); - if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT) - return -8; - } - else { - /* Hardcode the module type, and skip over the boilerplate */ - type = MODULE_CBRICK; - - if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer) - return -9; - - buffer += strlen("/" EDGE_LBL_RPOS "/"); - } - - /* The bay number is last. Make sure it's exactly two digits */ - - if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2])) - return -10; - - bay = 10 * (buffer[0] - '0') + (buffer[1] - '0'); - - if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) - return -11; - - m = RBT_TO_MODULE(rack, bay, type); - - /* avoid sign extending the moduleid_t */ - return (int)(unsigned short)m; -} - diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/klgraph.c linux-2.4.22/arch/ia64/sn/io/sn1/klgraph.c --- linux-2.4.21/arch/ia64/sn/io/sn1/klgraph.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/klgraph.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,940 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * klgraph.c- - * This file specifies the interface between the kernel and the PROM's - * configuration data structures. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define KLGRAPH_DEBUG 1 */ -#ifdef KLGRAPH_DEBUG -#define GRPRINTF(x) printk x -#define CE_GRPANIC CE_PANIC -#else -#define GRPRINTF(x) -#define CE_GRPANIC CE_PANIC -#endif - -#include - -extern char arg_maxnodes[]; -extern u64 klgraph_addr[]; - -/* - * Support for verbose inventory via hardware graph. - * klhwg_invent_alloc allocates the necessary size of inventory information - * and fills in the generic information. - */ -invent_generic_t * -klhwg_invent_alloc(cnodeid_t cnode, int class, int size) -{ - invent_generic_t *invent; - - invent = kern_malloc(size); - if (!invent) return NULL; - - invent->ig_module = NODE_MODULEID(cnode); - invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode)); - invent->ig_invclass = class; - - return invent; -} - -/* - * Add detailed disabled cpu inventory info to the hardware graph. - */ -void -klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv, - cnodeid_t cnode, - klcpu_t *cpu, slotid_t slot) -{ - invent_cpuinfo_t *cpu_invent; - diag_inv_t *diag_invent; - - cpu_invent = (invent_cpuinfo_t *) - klhwg_invent_alloc(cnode, INV_PROCESSOR, sizeof(invent_cpuinfo_t)); - if (!cpu_invent) - return; - - /* Diag information on this processor */ - diag_invent = (diag_inv_t *) - klhwg_invent_alloc(cnode, INV_CPUDIAGVAL, sizeof(diag_inv_t)); - - if (!diag_invent) - return; - - - /* Disabled CPU */ - cpu_invent->ic_gen.ig_flag = 0x0; - cpu_invent->ic_gen.ig_slot = slot; - cpu_invent->ic_cpu_info.cpuflavor = cpu->cpu_prid; - cpu_invent->ic_cpu_info.cpufq = cpu->cpu_speed; - cpu_invent->ic_cpu_info.sdfreq = cpu->cpu_scachespeed; - - cpu_invent->ic_cpu_info.sdsize = cpu->cpu_scachesz; - cpu_invent->ic_cpuid = cpu->cpu_info.virtid; - cpu_invent->ic_slice = cpu->cpu_info.physid; - - /* Disabled CPU label */ - hwgraph_info_add_LBL(cpuv, INFO_LBL_DETAIL_INVENT, - (arbitrary_info_t) cpu_invent); - hwgraph_info_export_LBL(cpuv, INFO_LBL_DETAIL_INVENT, - sizeof(invent_cpuinfo_t)); - - /* Diagval label - stores reason for disable +{virt,phys}id +diagval*/ - hwgraph_info_add_LBL(cpuv, INFO_LBL_DIAGVAL, - (arbitrary_info_t) diag_invent); - - hwgraph_info_export_LBL(cpuv, INFO_LBL_DIAGVAL, - sizeof(diag_inv_t)); -} - -/* - * Add detailed cpu inventory info to the hardware graph. - */ -void -klhwg_cpu_invent_info(devfs_handle_t cpuv, - cnodeid_t cnode, - klcpu_t *cpu) -{ - invent_cpuinfo_t *cpu_invent; - - cpu_invent = (invent_cpuinfo_t *) - klhwg_invent_alloc(cnode, INV_PROCESSOR, sizeof(invent_cpuinfo_t)); - if (!cpu_invent) - return; - - if (KLCONFIG_INFO_ENABLED((klinfo_t *)cpu)) - cpu_invent->ic_gen.ig_flag = INVENT_ENABLED; - else - cpu_invent->ic_gen.ig_flag = 0x0; - - cpu_invent->ic_cpu_info.cpuflavor = cpu->cpu_prid; - cpu_invent->ic_cpu_info.cpufq = cpu->cpu_speed; - cpu_invent->ic_cpu_info.sdfreq = cpu->cpu_scachespeed; - - cpu_invent->ic_cpu_info.sdsize = cpu->cpu_scachesz; - cpu_invent->ic_cpuid = cpu->cpu_info.virtid; - cpu_invent->ic_slice = cpu_physical_id_to_slice(cpu->cpu_info.virtid); - - hwgraph_info_add_LBL(cpuv, INFO_LBL_DETAIL_INVENT, - (arbitrary_info_t) cpu_invent); - hwgraph_info_export_LBL(cpuv, INFO_LBL_DETAIL_INVENT, - sizeof(invent_cpuinfo_t)); -} - -/* - * Add information about the baseio prom version number - * as a part of detailed inventory info in the hwgraph. - */ -void -klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode) -{ - invent_miscinfo_t *baseio_inventory; - unsigned char version = 0,revision = 0; - - /* Allocate memory for the "detailed inventory" info - * for the baseio - */ - baseio_inventory = (invent_miscinfo_t *) - klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t)); - baseio_inventory->im_type = INV_IO6PROM; - /* Store the revision info in the inventory */ - baseio_inventory->im_version = version; - baseio_inventory->im_rev = revision; - /* Put the inventory info in the hardware graph */ - hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, - (arbitrary_info_t) baseio_inventory); - /* Make the information available to the user programs - * thru hwgfs. - */ - hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, - sizeof(invent_miscinfo_t)); -} - -char *hub_rev[] = { - "0.0", - "1.0", - "2.0", - "2.1", - "2.2", - "2.3" -}; - -/* - * Add detailed cpu inventory info to the hardware graph. - */ -void -klhwg_hub_invent_info(devfs_handle_t hubv, - cnodeid_t cnode, - klhub_t *hub) -{ - invent_miscinfo_t *hub_invent; - - hub_invent = (invent_miscinfo_t *) - klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t)); - if (!hub_invent) - return; - - if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub)) - hub_invent->im_gen.ig_flag = INVENT_ENABLED; - - hub_invent->im_type = INV_HUB; - hub_invent->im_rev = hub->hub_info.revision; - hub_invent->im_speed = hub->hub_speed; - hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, - (arbitrary_info_t) hub_invent); - hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT, - sizeof(invent_miscinfo_t)); -} - -/* ARGSUSED */ -void -klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode) -{ - devfs_handle_t myhubv; - devfs_handle_t hub_mon; - devfs_handle_t synergy; - devfs_handle_t fsb0; - devfs_handle_t fsb1; - int rc; - extern struct file_operations hub_mon_fops; - - GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB)); - - (void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv); - rc = device_master_set(myhubv, node_vertex); - - /* - * hub perf stats. - */ - rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO, - (arbitrary_info_t)(&NODEPDA(cnode)->hubstats)); - - if (rc != GRAPH_SUCCESS) { - printk(KERN_WARNING "klhwg_add_hub: Can't add hub info label 0x%p, code %d", - (void *)myhubv, rc); - } - - klhwg_hub_invent_info(myhubv, cnode, hub); - - hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &hub_mon_fops, - (void *)(long)cnode); - - init_hub_stats(cnode, NODEPDA(cnode)); - - /* - * synergy perf - */ - (void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy); - (void) hwgraph_path_add(synergy, "0", &fsb0); - (void) hwgraph_path_add(synergy, "1", &fsb1); - - fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0)); - - fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1)); -} - -/* ARGSUSED */ -void -klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot) -{ - devfs_handle_t my_cpu; - char name[120]; - cpuid_t cpu_id; - nasid_t nasid; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid); - if(cpu_id != -1){ - sprintf(name, "%s/%s/%c", EDGE_LBL_DISABLED, EDGE_LBL_CPU, 'a' + cpu->cpu_info.physid); - (void) hwgraph_path_add(node_vertex, name, &my_cpu); - - mark_cpuvertex_as_cpu(my_cpu, cpu_id); - device_master_set(my_cpu, node_vertex); - - klhwg_disabled_cpu_invent_info(my_cpu, cnode, cpu, slot); - return; - } -} - -/* ARGSUSED */ -void -klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu) -{ - devfs_handle_t my_cpu, cpu_dir; - char name[120]; - cpuid_t cpu_id; - nasid_t nasid; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid); - - sprintf(name, "%s/%d/%c", - EDGE_LBL_CPUBUS, - 0, - 'a' + cpu->cpu_info.physid); - - GRPRINTF(("klhwg_add_cpu: adding %s to vertex 0x%x\n", name, node_vertex)); - (void) hwgraph_path_add(node_vertex, name, &my_cpu); - mark_cpuvertex_as_cpu(my_cpu, cpu_id); - device_master_set(my_cpu, node_vertex); - - /* Add an alias under the node's CPU directory */ - if (hwgraph_edge_get(node_vertex, EDGE_LBL_CPU, &cpu_dir) == GRAPH_SUCCESS) { - sprintf(name, "%c", 'a' + cpu->cpu_info.physid); - (void) hwgraph_edge_add(cpu_dir, my_cpu, name); - } - - klhwg_cpu_invent_info(my_cpu, cnode, cpu); -} - - -void -klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid) -{ - lboard_t *brd; - klxbow_t *xbow_p; - nasid_t hub_nasid; - cnodeid_t hub_cnode; - int widgetnum; - devfs_handle_t xbow_v, hubv; - /*REFERENCED*/ - graph_error_t err; - - if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL) - return; - - if (KL_CONFIG_DUPLICATE_BOARD(brd)) - return; - - GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n", - cnode, nasid)); - - if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) - == NULL) - return; - -#ifdef LATER - /* - * We cannot support this function in devfs .. see below where - * we use hwgraph_path_add() to create this vertex with a known - * name. - */ - err = hwgraph_vertex_create(&xbow_v); - ASSERT(err == GRAPH_SUCCESS); - - xswitch_vertex_init(xbow_v); -#endif /* LATER */ - - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { - if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) - continue; - - hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum); - if (hub_nasid == INVALID_NASID) { - printk(KERN_WARNING "hub widget %d, skipping xbow graph\n", widgetnum); - continue; - } - - hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid); - - if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) { - continue; - } - - hubv = cnodeid_to_vertex(hub_cnode); - - err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v); - if (err != GRAPH_SUCCESS) { - if (err == GRAPH_DUP) - printk(KERN_WARNING "klhwg_add_xbow: Check for " - "working routers and router links!"); - - PRINT_PANIC("klhwg_add_xbow: Failed to add " - "edge: vertex 0x%p to vertex 0x%p," - "error %d\n", - (void *)hubv, (void *)xbow_v, err); - } - xswitch_vertex_init(xbow_v); - - NODEPDA(hub_cnode)->xbow_vhdl = xbow_v; - - /* - * XXX - This won't work is we ever hook up two hubs - * by crosstown through a crossbow. - */ - if (hub_nasid != nasid) { - NODEPDA(hub_cnode)->xbow_peer = nasid; - NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer = - hub_nasid; - } - - GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n", - hub_nasid, EDGE_LBL_XTALK, hubv)); - -#ifdef LATER - err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK); - if (err != GRAPH_SUCCESS) { - if (err == GRAPH_DUP) - printk(KERN_WARNING "klhwg_add_xbow: Check for " - "working routers and router links!"); - - PRINT_PANIC("klhwg_add_xbow: Failed to add " - "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), " - "error %d\n", - hubv, hubv, xbow_v, xbow_v, err); - } -#endif - } -} - - -/* ARGSUSED */ -void -klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) -{ - nasid_t nasid; - lboard_t *brd; - klhub_t *hub; - devfs_handle_t node_vertex = NULL; - char path_buffer[100]; - int rv; - char *s; - int board_disabled = 0; - klcpu_t *cpu; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n", - cnode, nasid, brd)); - ASSERT(brd); - - do { - devfs_handle_t cpu_dir; - - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n", - path_buffer, hwgraph_root)); - rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); - - if (rv != GRAPH_SUCCESS) - PRINT_PANIC("Node vertex creation failed. " - "Path == %s", - path_buffer); - - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); - ASSERT(hub); - if(hub->hub_info.flags & KLINFO_ENABLE) - board_disabled = 0; - else - board_disabled = 1; - - if(!board_disabled) { - mark_nodevertex_as_node(node_vertex, - cnode + board_disabled * numnodes); - - s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer)); - NODEPDA(cnode)->hwg_node_name = - kmalloc(strlen(s) + 1, - GFP_KERNEL); - ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL); - strcpy(NODEPDA(cnode)->hwg_node_name, s); - - hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo); - - /* Set up node board's slot */ - NODEPDA(cnode)->slotdesc = brd->brd_slot; - - /* Set up the module we're in */ - NODEPDA(cnode)->module_id = brd->brd_module; - NODEPDA(cnode)->module = module_lookup(brd->brd_module); - } - - - /* Get the first CPU structure */ - cpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU); - - /* - * If there's at least 1 CPU, add a "cpu" directory to represent - * the collection of all CPUs attached to this node. - */ - if (cpu) { - graph_error_t rv; - - rv = hwgraph_path_add(node_vertex, EDGE_LBL_CPU, &cpu_dir); - if (rv != GRAPH_SUCCESS) - panic("klhwg_add_node: Cannot create CPU directory\n"); - } - - /* Add each CPU */ - while (cpu) { - cpuid_t cpu_id; - cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid); - if (cpu_enabled(cpu_id)) - klhwg_add_cpu(node_vertex, cnode, cpu); - else - klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot); - - cpu = (klcpu_t *) - find_component(brd, (klinfo_t *)cpu, KLSTRUCT_CPU); - } /* while */ - - if(!board_disabled) - klhwg_add_hub(node_vertex, hub, cnode); - - brd = KLCF_NEXT(brd); - if (brd) - brd = find_lboard(brd, KLTYPE_SNIA); - else - break; - } while(brd); -} - - -/* ARGSUSED */ -void -klhwg_add_all_routers(devfs_handle_t hwgraph_root) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd; - devfs_handle_t node_vertex; - char path_buffer[100]; - int rv; - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n", - cnode)); - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - /* No routers stored in this node's memory */ - continue; - - do { - ASSERT(brd); - GRPRINTF(("Router board struct is %p\n", brd)); - - /* Don't add duplicate boards. */ - if (brd->brd_flags & DUPLICATE_BOARD) - continue; - - GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module)); - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - GRPRINTF(("Router path is %s\n", path_buffer)); - - /* Add the router */ - GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n", - path_buffer, hwgraph_root)); - rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); - - if (rv != GRAPH_SUCCESS) - PRINT_PANIC("Router vertex creation " - "failed. Path == %s", - path_buffer); - - GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n", - brd)); - /* Find the rest of the routers stored on this node. */ - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), - KLTYPE_ROUTER)) ); - - GRPRINTF(("klhwg_add_all_routers: Done.\n")); - } - -} - -/* ARGSUSED */ -void -klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd, - cnodeid_t cnode, nasid_t nasid) -{ - klrou_t *router; - char path_buffer[50]; - char dest_path[50]; - devfs_handle_t router_hndl; - devfs_handle_t dest_hndl; - int rc; - int port; - lboard_t *dest_brd; - - GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n", - cnode)); - - /* Don't add duplicate boards. */ - if (brd->brd_flags & DUPLICATE_BOARD) { - GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n", - brd, cnode)); - return; - } - - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl); - - if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes)) - return; - - if (rc != GRAPH_SUCCESS) - printk(KERN_WARNING "Can't find router: %s", path_buffer); - - /* We don't know what to do with multiple router components */ - if (brd->brd_numcompts != 1) { - PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n", - brd->brd_numcompts); - return; - } - - - /* Convert component 0 to klrou_t ptr */ - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), - brd->brd_compts[0]); - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - /* See if the port's active */ - if (router->rou_port[port].port_nasid == INVALID_NASID) { - GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n", - port)); - continue; - } - if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) - == INVALID_CNODEID) { - continue; - } - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - router->rou_port[port].port_nasid, - router->rou_port[port].port_offset); - - /* Generate a hardware graph path for this board. */ - board_to_path(dest_brd, dest_path); - - rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); - - if (rc != GRAPH_SUCCESS) { - if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd)) - continue; - PRINT_PANIC("Can't find router: %s", dest_path); - } - GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n", - path_buffer, port, dest_path)); - - sprintf(dest_path, "%d", port); - - rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path); - - if (rc == GRAPH_DUP) { - GRPRINTF(("Skipping port %d. nasid %d %s/%s\n", - port, router->rou_port[port].port_nasid, - path_buffer, dest_path)); - continue; - } - - if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes)) - PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n", - path_buffer, dest_path, (void *)dest_hndl, rc); - - } -} - - -void -klhwg_connect_routers(devfs_handle_t hwgraph_root) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd; - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n", - cnode)); - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - continue; - - do { - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - klhwg_connect_one_router(hwgraph_root, brd, - cnode, nasid); - - /* Find the rest of the routers stored on this node. */ - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); - } -} - - - -void -klhwg_connect_hubs(devfs_handle_t hwgraph_root) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd; - klhub_t *hub; - lboard_t *dest_brd; - devfs_handle_t hub_hndl; - devfs_handle_t dest_hndl; - char path_buffer[50]; - char dest_path[50]; - graph_error_t rc; - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n", - cnode)); - - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - ASSERT(brd); - - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); - ASSERT(hub); - - /* See if the port's active */ - if (hub->hub_port.port_nasid == INVALID_NASID) { - GRPRINTF(("klhwg_connect_hubs: port inactive.\n")); - continue; - } - - if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID) - continue; - - /* Generate a hardware graph path for this board. */ - board_to_path(brd, path_buffer); - - GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer)); - rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl); - - if (rc != GRAPH_SUCCESS) - printk(KERN_WARNING "Can't find hub: %s", path_buffer); - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - hub->hub_port.port_nasid, - hub->hub_port.port_offset); - - /* Generate a hardware graph path for this board. */ - board_to_path(dest_brd, dest_path); - - rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); - - if (rc != GRAPH_SUCCESS) { - if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd)) - continue; - PRINT_PANIC("Can't find board: %s", dest_path); - } else { - - - GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n", - path_buffer, dest_path)); - - rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT); - - if (rc != GRAPH_SUCCESS) - PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n", - path_buffer, dest_path, (void *)dest_hndl, rc); - - } - } -} - -/* Store the pci/vme disabled board information as extended administrative - * hints which can later be used by the drivers using the device/driver - * admin interface. - */ -void -klhwg_device_disable_hints_add(void) -{ - cnodeid_t cnode; /* node we are looking at */ - nasid_t nasid; /* nasid of the node */ - lboard_t *board; /* board we are looking at */ - int comp_index; /* component index */ - klinfo_t *component; /* component in the board we are - * looking at - */ - char device_name[MAXDEVNAME]; - - for(cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - board = (lboard_t *)KL_CONFIG_INFO(nasid); - /* Check out all the board info stored on a node */ - while(board) { - /* No need to look at duplicate boards or non-io - * boards - */ - if (KL_CONFIG_DUPLICATE_BOARD(board) || - KLCLASS(board->brd_type) != KLCLASS_IO) { - board = KLCF_NEXT(board); - continue; - } - /* Check out all the components of a board */ - for (comp_index = 0; - comp_index < KLCF_NUM_COMPS(board); - comp_index++) { - component = KLCF_COMP(board,comp_index); - /* If the component is enabled move on to - * the next component - */ - if (KLCONFIG_INFO_ENABLED(component)) - continue; - /* NOTE : Since the prom only supports - * the disabling of pci devices the following - * piece of code makes sense. - * Make sure that this assumption is valid - */ - /* This component is disabled. Store this - * hint in the extended device admin table - */ - /* Get the canonical name of the pci device */ - device_component_canonical_name_get(board, - component, - device_name); -#ifdef DEBUG - printf("%s DISABLED\n",device_name); -#endif - } - /* go to the next board info stored on this - * node - */ - board = KLCF_NEXT(board); - } - } -} - -void -klhwg_add_all_modules(devfs_handle_t hwgraph_root) -{ - cmoduleid_t cm; - char name[128]; - devfs_handle_t vhdl; - int rc; - char buffer[16]; - - /* Add devices under each module */ - - for (cm = 0; cm < nummodules; cm++) { - /* Use module as module vertex fastinfo */ - -#ifdef __ia64 - memset(buffer, 0, 16); - format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF); - sprintf(name, EDGE_LBL_MODULE "/%s", buffer); -#else - sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id); -#endif - - rc = hwgraph_path_add(hwgraph_root, name, &vhdl); - ASSERT(rc == GRAPH_SUCCESS); - rc = rc; - - hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]); - - /* Add system controller */ - -#ifdef __ia64 - sprintf(name, - EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1, - buffer); -#else - sprintf(name, - EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1, - modules[cm]->id); -#endif - - rc = hwgraph_path_add(hwgraph_root, name, &vhdl); - ASSERT_ALWAYS(rc == GRAPH_SUCCESS); - rc = rc; - - hwgraph_info_add_LBL(vhdl, - INFO_LBL_ELSC, - (arbitrary_info_t) (__psint_t) 1); - -#ifdef LATER - sndrv_attach(vhdl); - /* - * We need to call the drivers attach routine .. - */ - FIXME("klhwg_add_all_modules: Need code to call driver attach.\n"); -#endif - } -} - -void -klhwg_add_all_nodes(devfs_handle_t hwgraph_root) -{ - cnodeid_t cnode; - - for (cnode = 0; cnode < numnodes; cnode++) { - klhwg_add_node(hwgraph_root, cnode, NULL); - } - - for (cnode = 0; cnode < numnodes; cnode++) { - klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode)); - } - - /* - * As for router hardware inventory information, we set this - * up in router.c. - */ - - klhwg_add_all_routers(hwgraph_root); - klhwg_connect_routers(hwgraph_root); - klhwg_connect_hubs(hwgraph_root); - - /* Go through the entire system's klconfig - * to figure out which pci components have been disabled - */ - klhwg_device_disable_hints_add(); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/l1.c linux-2.4.22/arch/ia64/sn/io/sn1/l1.c --- linux-2.4.21/arch/ia64/sn/io/sn1/l1.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/l1.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,3124 +0,0 @@ -/* $Id: l1.c,v 1.2 2002/11/16 02:23:19 steiner Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* In general, this file is organized in a hierarchy from lower-level - * to higher-level layers, as follows: - * - * UART routines - * Bedrock/L1 "PPP-like" protocol implementation - * System controller "message" interface (allows multiplexing - * of various kinds of requests and responses with - * console I/O) - * Console interface: - * "l1_cons", the glue that allows the L1 to act - * as the system console for the stdio libraries - * - * Routines making use of the system controller "message"-style interface - * can be found in l1_command.c. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Make all console writes atomic */ -#define SYNC_CONSOLE_WRITE 1 - - -/********************************************************************* - * Hardware-level (UART) driver routines. - */ - -/* macros for reading/writing registers */ - -/* USLD and USSD are needed for SN2 - but since we moving this code out soon ... */ -#define LD(x) (*(volatile uint64_t *)(x)) -#define USLD(x) LD(x) // (*(volatile ushort *)(x)) -#define SD(x, v) (LD(x) = (uint64_t) (v)) -#define USSD(x, v) SD(x,v) // (USLD(x) = (ushort) (v)) - -/* location of uart receive/xmit data register */ -#define L1_UART_BASE(n) ((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080)) -#define LOCK_HUB REMOTE_HUB_ADDR - -#define ADDR_L1_REG(n, r) ( L1_UART_BASE(n) | ( (r) << 3 ) ) -#define READ_L1_UART_REG(n, r) ( LD(ADDR_L1_REG((n), (r))) ) - -#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) ) - -/* upper layer interface calling methods */ -#define SERIAL_INTERRUPT_MODE 0 -#define SERIAL_POLLED_MODE 1 - - -/* UART-related #defines */ - -#define UART_BAUD_RATE 57600 -#define UART_FIFO_DEPTH 16 -#define UART_DELAY_SPAN 10 -#define UART_PUTC_TIMEOUT 50000 -#define UART_INIT_TIMEOUT 100000 - -/* error codes */ -#define UART_SUCCESS 0 -#define UART_TIMEOUT (-1) -#define UART_LINK (-2) -#define UART_NO_CHAR (-3) -#define UART_VECTOR (-4) - -#define UART_DELAY(x) udelay(x) - -/* Some debug counters */ -#define L1C_INTERRUPTS 0 -#define L1C_OUR_R_INTERRUPTS 1 -#define L1C_OUR_X_INTERRUPTS 2 -#define L1C_SEND_CALLUPS 3 -#define L1C_RECEIVE_CALLUPS 4 -#define L1C_SET_BAUD 5 -#define L1C_ALREADY_LOCKED L1C_SET_BAUD -#define L1C_R_IRQ 6 -#define L1C_R_IRQ_RET 7 -#define L1C_LOCK_TIMEOUTS 8 -#define L1C_LOCK_COUNTER 9 -#define L1C_UNLOCK_COUNTER 10 -#define L1C_REC_STALLS 11 -#define L1C_CONNECT_CALLS 12 -#define L1C_SIZE L1C_CONNECT_CALLS /* Set to the last one */ - -uint64_t L1_collectibles[L1C_SIZE + 1]; - - -/* - * Some macros for handling Endian-ness - */ - -#define COPY_INT_TO_BUFFER(_b, _i, _n) \ - { \ - _b[_i++] = (_n >> 24) & 0xff; \ - _b[_i++] = (_n >> 16) & 0xff; \ - _b[_i++] = (_n >> 8) & 0xff; \ - _b[_i++] = _n & 0xff; \ - } - -#define COPY_BUFFER_TO_INT(_b, _i, _n) \ - { \ - _n = (_b[_i++] << 24) & 0xff; \ - _n |= (_b[_i++] << 16) & 0xff; \ - _n |= (_b[_i++] << 8) & 0xff; \ - _n |= _b[_i++] & 0xff; \ - } - -#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn) \ - { \ - char *_xyz = (char *)_bn; \ - _xyz[3] = _b[_i++]; \ - _xyz[2] = _b[_i++]; \ - _xyz[1] = _b[_i++]; \ - _xyz[0] = _b[_i++]; \ - } - -void snia_kmem_free(void *where, int size); - -#define ALREADY_LOCKED 1 -#define NOT_LOCKED 0 -static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ ); - -#define BCOPY(x,y,z) memcpy(y,x,z) - -uint8_t L1_interrupts_connected; /* Non-zero when we are in interrupt mode */ - - -/* - * Console locking defines and functions. - * - */ - -uint8_t L1_cons_is_inited = 0; /* non-zero when console is init'd */ -nasid_t Master_console_nasid = (nasid_t)-1; -extern nasid_t console_nasid; - -u64 ia64_sn_get_console_nasid(void); - -inline nasid_t -get_master_nasid(void) -{ - nasid_t nasid = Master_console_nasid; - - master_nasid = Master_console_nasid = nasid = 0; - if ( nasid == (nasid_t)-1 ) { - nasid = (nasid_t)ia64_sn_get_console_nasid(); - if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) { - /* Out of bounds, use local */ - console_nasid = nasid = get_nasid(); - } - else { - /* Got a valid nasid, set the console_nasid */ - char xx[100]; -/* zzzzzz - force nasid to 0 for now */ - sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid); -nasid = 0; -/* end zzzzzz */ - xx[99] = (char)0; - early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED); - Master_console_nasid = console_nasid = nasid; - } - } - return(nasid); -} - - - -#define HUB_LOCK 16 - -#define PRIMARY_LOCK_TIMEOUT 10000000 -#define HUB_LOCK_REG(n) LOCK_HUB(n, MD_PERF_CNT0) - -#define SET_BITS(reg, bits) SD(reg, LD(reg) | (bits)) -#define CLR_BITS(reg, bits) SD(reg, LD(reg) & ~(bits)) -#define TST_BITS(reg, bits) ((LD(reg) & (bits)) != 0) - -#define HUB_TEST_AND_SET(n) LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ)) -#define HUB_CLEAR(n) SD(LOCK_HUB(n,LB_SCRATCH_REG3),0) - -#define RTC_TIME_MAX ((rtc_time_t) ~0ULL) - -/* - * primary_lock - * - * Allows CPU's 0-3 to mutually exclude the hub from one another by - * obtaining a blocking lock. Does nothing if only one CPU is active. - * - * This lock should be held just long enough to set or clear a global - * lock bit. After a relatively short timeout period, this routine - * figures something is wrong, and steals the lock. It does not set - * any other CPU to "dead". - */ -inline void -primary_lock(nasid_t nasid) -{ - rtc_time_t expire; - - expire = rtc_time() + PRIMARY_LOCK_TIMEOUT; - - while (HUB_TEST_AND_SET(nasid)) { - if (rtc_time() > expire) { - HUB_CLEAR(nasid); - } - } -} - -/* - * primary_unlock (internal) - * - * Counterpart to primary_lock - */ - -inline void -primary_unlock(nasid_t nasid) -{ - HUB_CLEAR(nasid); -} - -/* - * hub_unlock - * - * Counterpart to hub_lock_timeout and hub_lock - */ - -inline void -hub_unlock(nasid_t nasid, int level) -{ - uint64_t mask = 1ULL << level; - - primary_lock(nasid); - CLR_BITS(HUB_LOCK_REG(nasid), mask); - primary_unlock(nasid); -} - -/* - * hub_lock_timeout - * - * Uses primary_lock to implement multiple lock levels. - * - * There are 20 lock levels from 0 to 19 (limited by the number of bits - * in HUB_LOCK_REG). To prevent deadlock, multiple locks should be - * obtained in order of increasingly higher level, and released in the - * reverse order. - * - * A timeout value of 0 may be used for no timeout. - * - * Returns 0 if successful, -1 if lock times out. - */ - -inline int -hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout) -{ - uint64_t mask = 1ULL << level; - rtc_time_t expire = (timeout ? rtc_time() + timeout : RTC_TIME_MAX); - int done = 0; - - while (! done) { - while (TST_BITS(HUB_LOCK_REG(nasid), mask)) { - if (rtc_time() > expire) - return -1; - } - - primary_lock(nasid); - - if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) { - SET_BITS(HUB_LOCK_REG(nasid), mask); - done = 1; - } - primary_unlock(nasid); - } - return 0; -} - - -#define LOCK_TIMEOUT (0x1500000 * 1) /* 0x1500000 is ~30 sec */ - -void -lock_console(nasid_t nasid) -{ - int ret; - - /* If we already have it locked, just return */ - L1_collectibles[L1C_LOCK_COUNTER]++; - - ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT); - if ( ret != 0 ) { - L1_collectibles[L1C_LOCK_TIMEOUTS]++; - /* timeout */ - hub_unlock(nasid, HUB_LOCK); - /* If the 2nd lock fails, just pile ahead.... */ - hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT); - L1_collectibles[L1C_LOCK_TIMEOUTS]++; - } -} - -inline void -unlock_console(nasid_t nasid) -{ - L1_collectibles[L1C_UNLOCK_COUNTER]++; - hub_unlock(nasid, HUB_LOCK); -} - - -int -get_L1_baud(void) -{ - return UART_BAUD_RATE; -} - - -/* uart driver functions */ - -static inline void -uart_delay( rtc_time_t delay_span ) -{ - UART_DELAY( delay_span ); -} - -#define UART_PUTC_READY(n) (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE) - -static int -uart_putc( l1sc_t *sc ) -{ - WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] ); - return UART_SUCCESS; -} - - -static int -uart_getc( l1sc_t *sc ) -{ - u_char lsr_reg = 0; - nasid_t nasid = sc->nasid; - - if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & - (LSR_RCA | LSR_PARERR | LSR_FRMERR) ) - { - if( lsr_reg & LSR_RCA ) - return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) ); - else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) { - return UART_LINK; - } - } - return UART_NO_CHAR; -} - - -#define PROM_SER_CLK_SPEED 12000000 -#define PROM_SER_DIVISOR(x) (PROM_SER_CLK_SPEED / ((x) * 16)) - -static void -uart_init( l1sc_t *sc, int baud ) -{ -#if !defined(USE_SAL_CONSOLE_IO) - rtc_time_t expire; - int clkdiv; - nasid_t nasid; - - clkdiv = PROM_SER_DIVISOR(baud); - expire = rtc_time() + UART_INIT_TIMEOUT; - nasid = sc->nasid; - - /* make sure the transmit FIFO is empty */ - while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) { - uart_delay( UART_DELAY_SPAN ); - if( rtc_time() > expire ) { - break; - } - } - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(nasid); - - /* Setup for the proper baud rate */ - WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff ); - uart_delay( UART_DELAY_SPAN ); - - /* set operating parameters and set DLAB to 0 */ - - /* 8bit, one stop, clear request to send, auto flow control */ - WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE ); - uart_delay( UART_DELAY_SPAN ); - - /* disable interrupts */ - WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 ); - uart_delay( UART_DELAY_SPAN ); - - /* enable FIFO mode and reset both FIFOs, trigger on 1 */ - WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN ); - uart_delay( UART_DELAY_SPAN ); - WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0); - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(nasid); -#endif /* !USE_SAL_CONSOLE_IO */ -} - -/* This requires the console lock */ - - -static void -uart_intr_enable( l1sc_t *sc, u_char mask ) -{ - u_char lcr_reg, icr_reg; - nasid_t nasid = sc->nasid; - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(nasid); - - /* make sure that the DLAB bit in the LCR register is 0 - */ - lcr_reg = READ_L1_UART_REG( nasid, REG_LCR ); - lcr_reg &= ~(LCR_DLAB); - WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg ); - - /* enable indicated interrupts - */ - icr_reg = READ_L1_UART_REG( nasid, REG_ICR ); - icr_reg |= mask; - WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ ); - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(nasid); -} - -/* This requires the console lock */ -static void -uart_intr_disable( l1sc_t *sc, u_char mask ) -{ - u_char lcr_reg, icr_reg; - nasid_t nasid = sc->nasid; - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(nasid); - - /* make sure that the DLAB bit in the LCR register is 0 - */ - lcr_reg = READ_L1_UART_REG( nasid, REG_LCR ); - lcr_reg &= ~(LCR_DLAB); - WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg ); - - /* enable indicated interrupts - */ - icr_reg = READ_L1_UART_REG( nasid, REG_ICR ); - icr_reg &= mask; - WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ ); - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(nasid); -} - -#define uart_enable_xmit_intr(sc) \ - uart_intr_enable((sc), ICR_TIEN) - -#define uart_disable_xmit_intr(sc) \ - uart_intr_disable((sc), ~(ICR_TIEN)) - -#define uart_enable_recv_intr(sc) \ - uart_intr_enable((sc), ICR_RIEN) - -#define uart_disable_recv_intr(sc) \ - uart_intr_disable((sc), ~(ICR_RIEN)) - - -/********************************************************************* - * Routines for accessing a remote (router) UART - */ - -#define READ_RTR_L1_UART_REG(p, n, r, v) \ - { \ - if( vector_read_node( (p), (n), 0, \ - RR_JBUS1(r), (v) ) ) { \ - return UART_VECTOR; \ - } \ - } - -#define WRITE_RTR_L1_UART_REG(p, n, r, v) \ - { \ - if( vector_write_node( (p), (n), 0, \ - RR_JBUS1(r), (v) ) ) { \ - return UART_VECTOR; \ - } \ - } - -#define RTR_UART_PUTC_TIMEOUT UART_PUTC_TIMEOUT*10 -#define RTR_UART_DELAY_SPAN UART_DELAY_SPAN -#define RTR_UART_INIT_TIMEOUT UART_INIT_TIMEOUT*10 - -static int -rtr_uart_putc( l1sc_t *sc ) -{ - uint64_t regval, c; - nasid_t nasid = sc->nasid; - net_vec_t path = sc->uart; - rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT; - - c = (sc->send[sc->sent] & 0xffULL); - - while( 1 ) - { - /* Check for "tx hold reg empty" bit. */ - READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); - if( regval & LSR_XHRE ) - { - WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c ); - return UART_SUCCESS; - } - - if( rtc_time() >= expire ) - { - return UART_TIMEOUT; - } - uart_delay( RTR_UART_DELAY_SPAN ); - } -} - - -static int -rtr_uart_getc( l1sc_t *sc ) -{ - uint64_t regval; - nasid_t nasid = sc->nasid; - net_vec_t path = sc->uart; - - READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); - if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) ) - { - if( regval & LSR_RCA ) - { - READ_RTR_L1_UART_REG( path, nasid, REG_DAT, ®val ); - return( (int)regval ); - } - else - { - return UART_LINK; - } - } - - return UART_NO_CHAR; -} - - -static int -rtr_uart_init( l1sc_t *sc, int baud ) -{ - rtc_time_t expire; - int clkdiv; - nasid_t nasid; - net_vec_t path; - uint64_t regval; - - clkdiv = PROM_SER_DIVISOR(baud); - expire = rtc_time() + RTR_UART_INIT_TIMEOUT; - nasid = sc->nasid; - path = sc->uart; - - /* make sure the transmit FIFO is empty */ - while(1) { - READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); - if( regval & LSR_XSRE ) { - break; - } - if( rtc_time() > expire ) { - break; - } - uart_delay( RTR_UART_DELAY_SPAN ); - } - - WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff ); - uart_delay( UART_DELAY_SPAN ); - - /* set operating parameters and set DLAB to 0 */ - WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE ); - uart_delay( UART_DELAY_SPAN ); - - /* disable interrupts */ - WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0 ); - uart_delay( UART_DELAY_SPAN ); - - /* enable FIFO mode and reset both FIFOs */ - WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN ); - uart_delay( UART_DELAY_SPAN ); - WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, - FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO ); - - return 0; -} - -/********************************************************************* - * locking macros - */ - -#define L1SC_SEND_LOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); } -#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); } -#define L1SC_RECV_LOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } -#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); } - - -/********************************************************************* - * subchannel manipulation - * - * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel - * allocation. SUBCH_DATA_[UN]LOCK control access to data structures - * associated with particular subchannels (e.g., receive queues). - * - */ -#define SUBCH_LOCK(sc, p) spin_lock_irqsave( &((sc)->subch_lock), p ) -#define SUBCH_UNLOCK(sc, p) spin_unlock_irqrestore( &((sc)->subch_lock), p ) -#define SUBCH_DATA_LOCK(sbch, p) spin_lock_irqsave( &((sbch)->data_lock), p ) -#define SUBCH_DATA_UNLOCK(sbch, p) spin_unlock_irqrestore( &((sbch)->data_lock), p ) - - -/* - * set a function to be called for subchannel ch in the event of - * a transmission low-water interrupt from the uart - */ -void -subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func ) -{ - unsigned long pl = 0; - - L1SC_SEND_LOCK( sc, pl ); -#if !defined(SYNC_CONSOLE_WRITE) - if ( func && !sc->send_in_use ) - uart_enable_xmit_intr( sc ); -#endif - sc->subch[ch].tx_notify = func; - L1SC_SEND_UNLOCK(sc, pl ); -} - -/* - * set a function to be called for subchannel ch when data is received - */ -void -subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func ) -{ - unsigned long pl = 0; - brl1_sch_t *subch = &(sc->subch[ch]); - - SUBCH_DATA_LOCK( subch, pl ); - sc->subch[ch].rx_notify = func; - SUBCH_DATA_UNLOCK( subch, pl ); -} - -/********************************************************************* - * Queue manipulation macros - * - * - */ -#define NEXT(p) (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */ - -#define cq_init(q) bzero((q), sizeof (*(q))) -#define cq_empty(q) ((q)->ipos == (q)->opos) -#define cq_full(q) (NEXT((q)->ipos) == (q)->opos) -#define cq_used(q) ((q)->opos <= (q)->ipos ? \ - (q)->ipos - (q)->opos : \ - BRL1_QSIZE + (q)->ipos - (q)->opos) -#define cq_room(q) ((q)->opos <= (q)->ipos ? \ - BRL1_QSIZE - 1 + (q)->opos - (q)->ipos : \ - (q)->opos - (q)->ipos - 1) -#define cq_add(q, c) ((q)->buf[(q)->ipos] = (u_char) (c), \ - (q)->ipos = NEXT((q)->ipos)) -#define cq_rem(q, c) ((c) = (q)->buf[(q)->opos], \ - (q)->opos = NEXT((q)->opos)) -#define cq_discard(q) ((q)->opos = NEXT((q)->opos)) - -#define cq_tent_full(q) (NEXT((q)->tent_next) == (q)->opos) -#define cq_tent_len(q) ((q)->ipos <= (q)->tent_next ? \ - (q)->tent_next - (q)->ipos : \ - BRL1_QSIZE + (q)->tent_next - (q)->ipos) -#define cq_tent_add(q, c) \ - ((q)->buf[(q)->tent_next] = (u_char) (c), \ - (q)->tent_next = NEXT((q)->tent_next)) -#define cq_commit_tent(q) \ - ((q)->ipos = (q)->tent_next) -#define cq_discard_tent(q) \ - ((q)->tent_next = (q)->ipos) - - - - -/********************************************************************* - * CRC-16 (for checking bedrock/L1 packets). - * - * These are based on RFC 1662 ("PPP in HDLC-like framing"). - */ - -static unsigned short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -#define INIT_CRC 0xFFFF /* initial CRC value */ -#define GOOD_CRC 0xF0B8 /* "good" final CRC value */ - -static unsigned short crc16_calc( unsigned short crc, u_char c ) -{ - return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] ); -} - - -/*********************************************************************** - * The following functions implement the PPP-like bedrock/L1 protocol - * layer. - * - */ - -#define BRL1_FLAG_CH 0x7e -#define BRL1_ESC_CH 0x7d -#define BRL1_XOR_CH 0x20 - -/* L1<->Bedrock packet types */ -#define BRL1_REQUEST 0x00 -#define BRL1_RESPONSE 0x20 -#define BRL1_EVENT 0x40 - -#define BRL1_PKT_TYPE_MASK 0xE0 -#define BRL1_SUBCH_MASK 0x1F - -#define PKT_TYPE(tsb) ((tsb) & BRL1_PKT_TYPE_MASK) -#define SUBCH(tsb) ((tsb) & BRL1_SUBCH_MASK) - -/* timeouts */ -#define BRL1_INIT_TIMEOUT 500000 - -/* - * brl1_discard_packet is a dummy "receive callback" used to get rid - * of packets we don't want - */ -void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch ) -{ - unsigned long pl = 0; - brl1_sch_t *subch = &sc->subch[ch]; - - sc_cq_t *q = subch->iqp; - SUBCH_DATA_LOCK( subch, pl ); - q->opos = q->ipos; - atomic_set(&(subch->packet_arrived), 0); - SUBCH_DATA_UNLOCK( subch, pl ); -} - - -/* - * brl1_send_chars sends the send buffer in the l1sc_t structure - * out through the uart. Assumes that the caller has locked the - * UART (or send buffer in the kernel). - * - * This routine doesn't block-- if you want it to, call it in - * a loop. - */ -static int -brl1_send_chars( l1sc_t *sc ) -{ - /* We track the depth of the C brick's UART's - * fifo in software, and only check if the UART is accepting - * characters when our count indicates that the fifo should - * be full. - * - * For remote (router) UARTs, we check with the UART before sending every - * character. - */ - if( sc->uart == BRL1_LOCALHUB_UART ) { - if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) ) - sc->fifo_space = UART_FIFO_DEPTH; - - while( (sc->sent < sc->send_len) && (sc->fifo_space) ) { - uart_putc( sc ); - sc->fifo_space--; - sc->sent++; - } - } - else { - - /* remote (router) UARTs */ - - int result; - int tries = 0; - - while( sc->sent < sc->send_len ) { - result = sc->putc_f( sc ); - if( result >= 0 ) { - (sc->sent)++; - continue; - } - if( result == UART_TIMEOUT ) { - tries++; - /* send this character in TIMEOUT_RETRIES... */ - if( tries < 30 /* TIMEOUT_RETRIES */ ) { - continue; - } - /* ...or else... */ - else { - /* ...drop the packet. */ - sc->sent = sc->send_len; - return sc->send_len; - } - } - if( result < 0 ) { - return result; - } - } - } - return sc->sent; -} - - -/* brl1_send formats up a packet and (at least begins to) send it - * to the uart. If the send buffer is in use when this routine obtains - * the lock, it will behave differently depending on the "wait" parameter. - * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"), - * hopefully encouraging the caller to back off (unlock any high-level - * spinlocks) and allow the buffer some time to drain. For wait==1 (high- - * priority I/O along the lines of kernel error messages), we will flush - * the current contents of the send buffer and beat on the uart - * until our message has been completely transmitted. - */ - -static int -brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait ) -{ - unsigned long pl = 0; - int index; - int pkt_len = 0; - unsigned short crc = INIT_CRC; - char *send_ptr = sc->send; - - - if( sc->send_in_use && !(wait) ) { - /* We are in the middle of sending, but can wait until done */ - return 0; - } - else if( sc->send_in_use ) { - /* buffer's in use, but we're synchronous I/O, so we're going - * to send whatever's in there right now and take the buffer - */ - int counter = 0; - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(sc->nasid); - L1SC_SEND_LOCK(sc, pl); - while( sc->sent < sc->send_len ) { - brl1_send_chars( sc ); - if ( counter++ > 0xfffff ) { - char *str = "Looping waiting for uart to clear (1)\n"; - early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED); - break; - } - } - } - else { - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(sc->nasid); - L1SC_SEND_LOCK(sc, pl); - sc->send_in_use = 1; - } - *send_ptr++ = BRL1_FLAG_CH; - *send_ptr++ = type_and_subch; - pkt_len += 2; - crc = crc16_calc( crc, type_and_subch ); - - /* limit number of characters accepted to max payload size */ - if( len > (BRL1_QSIZE - 1) ) - len = (BRL1_QSIZE - 1); - - /* copy in the message buffer (inserting PPP - * framing info where necessary) - */ - for( index = 0; index < len; index++ ) { - - switch( *msg ) { - - case BRL1_FLAG_CH: - *send_ptr++ = BRL1_ESC_CH; - *send_ptr++ = (*msg) ^ BRL1_XOR_CH; - pkt_len += 2; - break; - - case BRL1_ESC_CH: - *send_ptr++ = BRL1_ESC_CH; - *send_ptr++ = (*msg) ^ BRL1_XOR_CH; - pkt_len += 2; - break; - - default: - *send_ptr++ = *msg; - pkt_len++; - } - crc = crc16_calc( crc, *msg ); - msg++; - } - crc ^= 0xffff; - - for( index = 0; index < sizeof(crc); index++ ) { - char crc_char = (char)(crc & 0x00FF); - if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { - *send_ptr++ = BRL1_ESC_CH; - pkt_len++; - crc_char ^= BRL1_XOR_CH; - } - *send_ptr++ = crc_char; - pkt_len++; - crc >>= 8; - } - - *send_ptr++ = BRL1_FLAG_CH; - pkt_len++; - - sc->send_len = pkt_len; - sc->sent = 0; - - { - int counter = 0; - do { - brl1_send_chars( sc ); - if ( counter++ > 0xfffff ) { - char *str = "Looping waiting for uart to clear (2)\n"; - early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED); - break; - } - } while( (sc->sent < sc->send_len) && wait ); - } - - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(sc->nasid); - - if( sc->sent == sc->send_len ) { - /* success! release the send buffer and call the callup */ -#if !defined(SYNC_CONSOLE_WRITE) - brl1_notif_t callup; -#endif - - sc->send_in_use = 0; - /* call any upper layer that's asked for notification */ -#if defined(XX_SYNC_CONSOLE_WRITE) - /* - * This is probably not a good idea - since the l1_ write func can be called multiple - * time within the callup function. - */ - callup = subch->tx_notify; - if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) { - L1_collectibles[L1C_SEND_CALLUPS]++; - (*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq, - sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id, - sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch)); - } -#endif /* SYNC_CONSOLE_WRITE */ - } -#if !defined(SYNC_CONSOLE_WRITE) - else if ( !wait ) { - /* enable low-water interrupts so buffer will be drained */ - uart_enable_xmit_intr(sc); - } -#endif - - L1SC_SEND_UNLOCK(sc, pl); - - return len; -} - -/* brl1_send_cont is intended to be called as an interrupt service - * routine. It sends until the UART won't accept any more characters, - * or until an error is encountered (in which case we surrender the - * send buffer and give up trying to send the packet). Once the - * last character in the packet has been sent, this routine releases - * the send buffer and calls any previously-registered "low-water" - * output routines. - */ - -#if !defined(SYNC_CONSOLE_WRITE) - -int -brl1_send_cont( l1sc_t *sc ) -{ - unsigned long pl = 0; - int done = 0; - brl1_notif_t callups[BRL1_NUM_SUBCHANS]; - brl1_notif_t *callup; - brl1_sch_t *subch; - int index; - - /* - * I'm not sure how I think this is to be handled - whether the lock is held - * over the interrupt - but it seems like it is a bad idea.... - */ - - if ( sc->uart == BRL1_LOCALHUB_UART ) - lock_console(sc->nasid); - L1SC_SEND_LOCK(sc, pl); - brl1_send_chars( sc ); - done = (sc->sent == sc->send_len); - if( done ) { - sc->send_in_use = 0; -#if !defined(SYNC_CONSOLE_WRITE) - uart_disable_xmit_intr(sc); -#endif - } - if ( sc->uart == BRL1_LOCALHUB_UART ) - unlock_console(sc->nasid); - /* Release the lock */ - L1SC_SEND_UNLOCK(sc, pl); - - return 0; -} -#endif /* SYNC_CONSOLE_WRITE */ - -/* internal function -- used by brl1_receive to read a character - * from the uart and check whether errors occurred in the process. - */ -static int -read_uart( l1sc_t *sc, int *c, int *result ) -{ - *c = sc->getc_f( sc ); - - /* no character is available */ - if( *c == UART_NO_CHAR ) { - *result = BRL1_NO_MESSAGE; - return 0; - } - - /* some error in UART */ - if( *c < 0 ) { - *result = BRL1_LINK; - return 0; - } - - /* everything's fine */ - *result = BRL1_VALID; - return 1; -} - - -/* - * brl1_receive - * - * This function reads a Bedrock-L1 protocol packet into the l1sc_t - * response buffer. - * - * The operation of this function can be expressed as a finite state - * machine: - * - -START STATE INPUT TRANSITION -========================================================== -BRL1_IDLE (reset or error) flag BRL1_FLAG - other BRL1_IDLE@ - -BRL1_FLAG (saw a flag (0x7e)) flag BRL1_FLAG - escape BRL1_IDLE@ - header byte BRL1_HDR - other BRL1_IDLE@ - -BRL1_HDR (saw a type/subch byte)(see below) BRL1_BODY - BRL1_HDR - -BRL1_BODY (reading packet body) flag BRL1_FLAG - escape BRL1_ESC - other BRL1_BODY - -BRL1_ESC (saw an escape (0x7d)) flag BRL1_FLAG@ - escape BRL1_IDLE@ - other BRL1_BODY -========================================================== - -"@" denotes an error transition. - - * The BRL1_HDR state is a transient state which doesn't read input, - * but just provides a way in to code which decides to whom an - * incoming packet should be directed. - * - * brl1_receive can be used to poll for input from the L1, or as - * an interrupt service routine. It reads as much data as is - * ready from the junk bus UART and places into the appropriate - * input queues according to subchannel. The header byte is - * stripped from console-type data, but is retained for message- - * type data (L1 responses). A length byte will also be - * prepended to message-type packets. - * - * This routine is non-blocking; if the caller needs to block - * for input, it must call brl1_receive in a loop. - * - * brl1_receive returns when there is no more input, the queue - * for the current incoming message is full, or there is an - * error (parity error, bad header, bad CRC, etc.). - */ - -#define STATE_SET(l,s) ((l)->brl1_state = (s)) -#define STATE_GET(l) ((l)->brl1_state) - -#define LAST_HDR_SET(l,h) ((l)->brl1_last_hdr = (h)) -#define LAST_HDR_GET(l) ((l)->brl1_last_hdr) - -#define VALID_HDR(c) \ - ( SUBCH((c)) <= SC_CONS_SYSTEM \ - ? PKT_TYPE((c)) == BRL1_REQUEST \ - : ( PKT_TYPE((c)) == BRL1_RESPONSE || \ - PKT_TYPE((c)) == BRL1_EVENT ) ) - -#define IS_TTY_PKT(l) ( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 ) - - -int -brl1_receive( l1sc_t *sc, int mode ) -{ - int result; /* value to be returned by brl1_receive */ - int c; /* most-recently-read character */ - int done; /* set done to break out of recv loop */ - unsigned long pl = 0, cpl = 0; - sc_cq_t *q; /* pointer to queue we're working with */ - - result = BRL1_NO_MESSAGE; - - L1SC_RECV_LOCK(sc, cpl); - - done = 0; - while( !done ) - { - switch( STATE_GET(sc) ) - { - - case BRL1_IDLE: - /* Initial or error state. Waiting for a flag character - * to resynchronize with the L1. - */ - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - done = 1; - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* saw a flag character */ - STATE_SET( sc, BRL1_FLAG ); - continue; - } - break; - - case BRL1_FLAG: - /* One or more flag characters have been read; look for - * the beginning of a packet (header byte). - */ - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - if( c != UART_NO_CHAR ) - STATE_SET( sc, BRL1_IDLE ); - - done = 1; - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* multiple flags are OK */ - continue; - } - - if( !VALID_HDR( c ) ) { - /* if c isn't a flag it should have been - * a valid header, so we have an error - */ - result = BRL1_PROTOCOL; - STATE_SET( sc, BRL1_IDLE ); - done = 1; - continue; - } - - /* we have a valid header byte */ - LAST_HDR_SET( sc, c ); - STATE_SET( sc, BRL1_HDR ); - - break; - - case BRL1_HDR: - /* A header byte has been read. Do some bookkeeping. */ - q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; - ASSERT(q); - - if( !IS_TTY_PKT(sc) ) { - /* if this is an event or command response rather - * than console I/O, we need to reserve a couple - * of extra spaces in the queue for the header - * byte and a length byte; if we can't, stay in - * the BRL1_HDR state. - */ - if( cq_room( q ) < 2 ) { - result = BRL1_FULL_Q; - done = 1; - continue; - } - cq_tent_add( q, 0 ); /* reserve length byte */ - cq_tent_add( q, LAST_HDR_GET( sc ) ); /* record header byte */ - } - STATE_SET( sc, BRL1_BODY ); - - break; - - case BRL1_BODY: - /* A header byte has been read. We are now attempting - * to receive the packet body. - */ - - q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; - ASSERT(q); - - /* if the queue we want to write into is full, don't read from - * the uart (this provides backpressure to the L1 side) - */ - if( cq_tent_full( q ) ) { - result = BRL1_FULL_Q; - done = 1; - continue; - } - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - if( c != UART_NO_CHAR ) - STATE_SET( sc, BRL1_IDLE ); - done = 1; - continue; - } - - if( c == BRL1_ESC_CH ) { - /* prepare to unescape the next character */ - STATE_SET( sc, BRL1_ESC ); - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* flag signifies the end of a packet */ - - unsigned short crc; /* holds the crc as we calculate it */ - int i; /* index variable */ - brl1_sch_t *subch; /* subchannel for received packet */ - brl1_notif_t callup; /* "data ready" callup */ - - /* whatever else may happen, we've seen a flag and we're - * starting a new packet - */ - STATE_SET( sc, BRL1_FLAG ); - - /* if the packet body has less than 2 characters, - * it can't be a well-formed packet. Discard it. - */ - if( cq_tent_len( q ) < /* 2 + possible length byte */ - (2 + (IS_TTY_PKT(sc) ? 0 : 1)) ) - { - result = BRL1_PROTOCOL; - cq_discard_tent( q ); - STATE_SET( sc, BRL1_FLAG ); - done = 1; - continue; - } - - /* check CRC */ - - /* accumulate CRC, starting with the header byte and - * ending with the transmitted CRC. This should - * result in a known good value. - */ - crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) ); - for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE; - i != q->tent_next; - i = (i + 1) % BRL1_QSIZE ) - { - crc = crc16_calc( crc, q->buf[i] ); - } - - /* verify the caclulated crc against the "good" crc value; - * if we fail, discard the bad packet and return an error. - */ - if( crc != (unsigned short)GOOD_CRC ) { - result = BRL1_CRC; - cq_discard_tent( q ); - STATE_SET( sc, BRL1_FLAG ); - done = 1; - continue; - } - - /* so the crc check was ok. Now we discard the CRC - * from the end of the received bytes. - */ - q->tent_next += (BRL1_QSIZE - 2); - q->tent_next %= BRL1_QSIZE; - - /* get the subchannel and lock it */ - subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]); - SUBCH_DATA_LOCK( subch, pl ); - - /* if this isn't a console packet, we need to record - * a length byte - */ - if( !IS_TTY_PKT(sc) ) { - q->buf[q->ipos] = cq_tent_len( q ) - 1; - } - - /* record packet for posterity */ - cq_commit_tent( q ); - result = BRL1_VALID; - - /* notify subchannel owner that there's something - * on the queue for them - */ - atomic_inc(&(subch->packet_arrived)); - callup = subch->rx_notify; - SUBCH_DATA_UNLOCK( subch, pl ); - - if( callup && (mode == SERIAL_INTERRUPT_MODE) ) { - L1SC_RECV_UNLOCK( sc, cpl ); - L1_collectibles[L1C_RECEIVE_CALLUPS]++; - (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq, - sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id, - sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs, - sc, SUBCH(LAST_HDR_GET(sc)) ); - L1SC_RECV_LOCK( sc, cpl ); - } - continue; /* go back for more! */ - } - - /* none of the special cases applied; we've got a normal - * body character - */ - cq_tent_add( q, c ); - - break; - - case BRL1_ESC: - /* saw an escape character. The next character will need - * to be unescaped. - */ - - q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; - ASSERT(q); - - /* if the queue we want to write into is full, don't read from - * the uart (this provides backpressure to the L1 side) - */ - if( cq_tent_full( q ) ) { - result = BRL1_FULL_Q; - done = 1; - continue; - } - - if( !read_uart( sc, &c, &result ) ) { - - /* error reading uart */ - if( c != UART_NO_CHAR ) { - cq_discard_tent( q ); - STATE_SET( sc, BRL1_IDLE ); - } - done = 1; - continue; - } - - if( c == BRL1_FLAG_CH ) { - /* flag after escape is an error */ - STATE_SET( sc, BRL1_FLAG ); - cq_discard_tent( q ); - result = BRL1_PROTOCOL; - done = 1; - continue; - } - - if( c == BRL1_ESC_CH ) { - /* two consecutive escapes is an error */ - STATE_SET( sc, BRL1_IDLE ); - cq_discard_tent( q ); - result = BRL1_PROTOCOL; - done = 1; - continue; - } - - /* otherwise, we've got a character that needs - * to be unescaped - */ - cq_tent_add( q, (c ^ BRL1_XOR_CH) ); - STATE_SET( sc, BRL1_BODY ); - - break; - - } /* end of switch( STATE_GET(sc) ) */ - } /* end of while(!done) */ - - L1SC_RECV_UNLOCK( sc, cpl ); - - return result; -} - - -/* brl1_init initializes the Bedrock/L1 protocol layer. This includes - * zeroing out the send and receive state information. - */ - -void -brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) -{ - int i; - brl1_sch_t *subch; - - bzero( sc, sizeof( *sc ) ); - sc->nasid = nasid; - sc->uart = uart; - sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc); - sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc); - sc->sol = 1; - subch = sc->subch; - - /* initialize L1 subchannels - */ - - /* assign processor TTY channels */ - for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) { - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ ); - subch->tx_notify = NULL; - /* (for now, drop elscuart packets in the kernel) */ - subch->rx_notify = brl1_discard_packet; - subch->iqp = &sc->garbage_q; - } - - /* assign system TTY channel (first free subchannel after each - * processor's individual TTY channel has been assigned) - */ - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ ); - subch->tx_notify = NULL; - if( sc->uart == BRL1_LOCALHUB_UART ) { - subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) ); - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - subch->rx_notify = NULL; - } - else { - /* we shouldn't be getting console input from remote UARTs */ - subch->iqp = &sc->garbage_q; - subch->rx_notify = brl1_discard_packet; - } - subch++; i++; - - /* "reserved" subchannels (0x05-0x0F); for now, throw away - * incoming packets - */ - for( ; i < 0x10; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = brl1_discard_packet; - subch->iqp = &sc->garbage_q; - } - - /* remaining subchannels are free */ - for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = brl1_discard_packet; - subch->iqp = &sc->garbage_q; - } - - /* initialize synchronization structures - */ - spin_lock_init( &(sc->subch_lock) ); - spin_lock_init( &(sc->send_lock) ); - spin_lock_init( &(sc->recv_lock) ); - - if( sc->uart == BRL1_LOCALHUB_UART ) { - uart_init( sc, UART_BAUD_RATE ); - } - else { - rtr_uart_init( sc, UART_BAUD_RATE ); - } - - /* Set up remaining fields using L1 command functions-- elsc_module_get - * to read the module id, elsc_debug_get to see whether or not we're - * in verbose mode. - */ - { - extern int elsc_module_get(l1sc_t *); - - sc->modid = elsc_module_get( sc ); - sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid); - sc->verbose = 1; - } -} - -/********************************************************************* - * These are interrupt-related functions used in the kernel to service - * the L1. - */ - -/* - * brl1_intrd is the function which is called on a console interrupt. - */ - - -static void -brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff) -{ - u_char isr_reg; - l1sc_t *sc = get_elsc(); - int ret; - - L1_collectibles[L1C_INTERRUPTS]++; - isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR); - - /* Save for callup args in console */ - sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq; - sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id; - sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff; - -#if defined(SYNC_CONSOLE_WRITE) - while( isr_reg & ISR_RxRDY ) -#else - while( isr_reg & (ISR_RxRDY | ISR_TxRDY) ) -#endif - { - if( isr_reg & ISR_RxRDY ) { - L1_collectibles[L1C_OUR_R_INTERRUPTS]++; - ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE); - if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) ) - L1_collectibles[L1C_REC_STALLS] = ret; - } -#if !defined(SYNC_CONSOLE_WRITE) - if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) { - L1_collectibles[L1C_OUR_X_INTERRUPTS]++; - brl1_send_cont(sc); - } -#endif /* SYNC_CONSOLE_WRITE */ - isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR); - } -} - - -/* - * Install a callback function for the system console subchannel - * to allow an upper layer to be notified when the send buffer - * has been emptied. - */ -static inline void -l1_tx_notif( brl1_notif_t func ) -{ - subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc, - SC_CONS_SYSTEM, func ); -} - - -/* - * Install a callback function for the system console subchannel - * to allow an upper layer to be notified when a packet has been - * received. - */ -static inline void -l1_rx_notif( brl1_notif_t func ) -{ - subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc, - SC_CONS_SYSTEM, func ); -} - - -/* brl1_intr is called directly from the uart interrupt; after it runs, the - * interrupt "daemon" xthread is signalled to continue. - */ -void -brl1_intr( void ) -{ -} - -#define BRL1_INTERRUPT_LEVEL 65 /* linux request_irq() value */ - -/* Return the current interrupt level */ - -//#define CONSOLE_POLLING_ALSO - -int -l1_get_intr_value( void ) -{ -#if defined(USE_SAL_CONSOLE_IO) - return(0); -#else -#if defined(CONSOLE_POLLING_ALSO) - return(0); -#else - return(BRL1_INTERRUPT_LEVEL); -#endif /* CONSOLE_POLLING_ALSO */ -#endif /* USE_SAL_CONSOLE_IO */ -} - -/* Disconnect the callup functions - throw away interrupts */ - -void -l1_unconnect_intr(void) -{ -#if !defined(USE_SAL_CONSOLE_IO) - /* UnRegister the upper-level callup functions */ - l1_rx_notif((brl1_notif_t)NULL); - l1_tx_notif((brl1_notif_t)NULL); - /* We do NOT unregister the interrupts */ -#endif /* !USE_SAL_CONSOLE_IO */ -} - -/* Set up uart interrupt handling for this node's uart */ - -void -l1_connect_intr(void *rx_notify, void *tx_notify) -{ -#if defined(USE_SAL_CONSOLE_IO) -#if 0 - // Will need code here for sn2 - something like this - console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()); - intr_connect_level(console_nodepda->node_first_cpu, - SGI_UART_VECTOR, INTPEND0_MAXMASK, - dummy_intr_func); - request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8), - intr_func, SA_INTERRUPT | SA_SHIRQ, - "l1_protocol_driver", (void *)sc); -#endif -#else - l1sc_t *sc; - nasid_t nasid; - int tmp; - nodepda_t *console_nodepda; - int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t); - - if ( L1_interrupts_connected ) { - /* Interrupts are connected, so just register the callups */ - l1_rx_notif((brl1_notif_t)rx_notify); - l1_tx_notif((brl1_notif_t)tx_notify); - - L1_collectibles[L1C_CONNECT_CALLS]++; - return; - } - else - L1_interrupts_connected = 1; - - nasid = get_master_nasid(); - console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid)); - sc = &console_nodepda->module->elsc; - sc->intr_cpu = console_nodepda->node_first_cpu; - - if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) { - L1_interrupts_connected = 0; /* FAILS !! */ - } - else { - void synergy_intr_connect(int, int); - - synergy_intr_connect(UART_INTR, sc->intr_cpu); - L1_collectibles[L1C_R_IRQ]++; - tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc); - L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp; - if ( tmp ) { - L1_interrupts_connected = 0; /* FAILS !! */ - } - else { - /* Register the upper-level callup functions */ - l1_rx_notif((brl1_notif_t)rx_notify); - l1_tx_notif((brl1_notif_t)tx_notify); - - /* Set the uarts the way we like it */ - uart_enable_recv_intr( sc ); - uart_disable_xmit_intr( sc ); - } - } -#endif /* USE_SAL_CONSOLE_IO */ -} - - -/* These are functions to use from serial_in/out when in protocol - * mode to send and receive uart control regs. These are external - * interfaces into the protocol driver. - */ - -void -l1_control_out(int offset, int value) -{ -#if defined(USE_SAL_CONSOLE_IO) - /* quietly ignore unless simulator */ - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - if ( master_node_bedrock_address != (u64)0 ) { - writeb(value, (unsigned long)master_node_bedrock_address + - (offset<< 3)); - } - return; - } -#else - nasid_t nasid = get_master_nasid(); - WRITE_L1_UART_REG(nasid, offset, value); -#endif -} - -/* Console input exported interface. Return a register value. */ - -int -l1_control_in_polled(int offset) -{ - static int l1_control_in_local(int, int); - - return(l1_control_in_local(offset, SERIAL_POLLED_MODE)); -} - -int -l1_control_in(int offset) -{ - static int l1_control_in_local(int, int); - - return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE)); -} - -static int -l1_control_in_local(int offset, int mode) -{ -#if defined(USE_SAL_CONSOLE_IO) - int sal_call_status = 0, input; - int ret = 0; - - if ( offset == REG_LSR ) { - ret = (LSR_XHRE | LSR_XSRE); /* can send anytime */ - sal_call_status = ia64_sn_console_check(&input); - if ( !sal_call_status && input ) { - /* input pending */ - ret |= LSR_RCA; - } - } - - /* If the sal call failed, do it the old-fashioned way */ - if ( sal_call_status ) { - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - ret = readb((unsigned long)master_node_bedrock_address + - (offset<< 3)); - } - else { -#endif /* USE_SAL_CONSOLE_IO */ - nasid_t nasid; - int ret, input; - static int l1_poll(l1sc_t *, int); - - nasid = get_master_nasid(); - ret = READ_L1_UART_REG(nasid, offset); - - if ( offset == REG_LSR ) { - ret |= (LSR_XHRE | LSR_XSRE); /* can send anytime */ - if ( L1_cons_is_inited ) { - if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) { - input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode); - if ( input ) { - ret |= LSR_RCA; - } - } - } - } -#if defined(USE_SAL_CONSOLE_IO) - } - } -#endif - return(ret); -} - -/* - * Console input exported interface. Return a character (if one is available) - */ - -int -l1_serial_in_polled(void) -{ - static int l1_serial_in_local(int mode); - - return(l1_serial_in_local(SERIAL_POLLED_MODE)); -} - -int -l1_serial_in(void) -{ - static int l1_serial_in_local(int mode); - - return(l1_serial_in_local(SERIAL_INTERRUPT_MODE)); -} - -static int -l1_serial_in_local(int mode) -{ -#if defined(USE_SAL_CONSOLE_IO) - int sal_call_status; - int ch; - - sal_call_status = ia64_sn_console_getc(&ch); - if ( !sal_call_status ) { - return(ch); - } - else { - /* If the sal called failed - do it the old-fashioned way */ - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3))); - } - else { -#endif /* USE_SAL_CONSOLE_IO */ - nasid_t nasid; - l1sc_t *sc; - int value; - static int l1_getc( l1sc_t *, int ); - static inline l1sc_t *early_sc_init(nasid_t); - - nasid = get_master_nasid(); - sc = early_sc_init(nasid); - if ( L1_cons_is_inited ) { - if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) { - sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc; - } - } - value = l1_getc(sc, mode); - return(value); -#if defined(USE_SAL_CONSOLE_IO) - } - } -#endif -} - -/* Console output exported interface. Write message to the console. */ - -int -l1_serial_out( char *str, int len ) -{ -#if defined(USE_SAL_CONSOLE_IO) - void early_sn_setup(void); - int sal_call_status = 0; - int counter = len; - -#if defined(CONFIG_IA64_EARLY_PRINTK) - { - static int inited; - if(!inited) { - inited=1; - early_sn_setup(); - } - } -#endif - - /* Attempt to write things out thru the sal */ - sal_call_status = ia64_sn_console_putb(str, len); - if ( sal_call_status ) { - /* If the sal called failed - do it the old-fashioned way */ - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - if (!master_node_bedrock_address) - early_sn_setup(); - if ( master_node_bedrock_address != (u64)0 ) { -#ifdef FLAG_DIRECT_CONSOLE_WRITES - /* This is an easy way to pre-pend the output to know whether the output - * was done via sal or directly */ - writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); -#endif /* FLAG_DIRECT_CONSOLE_WRITES */ - while ( counter > 0 ) { - writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - counter--; - str++; - } - } - } - else { -#endif /* USE_SAL_CONSOLE_IO */ - nasid_t nasid = get_master_nasid(); - int l1_write(l1sc_t *, char *, int, int); - - if ( L1_cons_is_inited ) { - if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) - return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len, -#if defined(SYNC_CONSOLE_WRITE) - 1 -#else - !L1_interrupts_connected -#endif - )); - } - return(early_l1_serial_out(nasid, str, len, NOT_LOCKED)); -#if defined(USE_SAL_CONSOLE_IO) - } - } - return((counter <= 0) ? 0 : (len - counter)); -#endif -} - - -/* - * These are the 'early' functions - when we need to do things before we have - * all the structs setup. - */ - - -static l1sc_t Early_console; /* fake l1sc_t */ -static int Early_console_inited = 0; - -static void -early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) -{ - int i; - brl1_sch_t *subch; - - bzero( sc, sizeof( *sc ) ); - sc->nasid = nasid; - sc->uart = uart; - sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc); - sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc); - sc->sol = 1; - subch = sc->subch; - - /* initialize L1 subchannels - */ - - /* assign processor TTY channels */ - for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) { - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - subch->iqp = &sc->garbage_q; - } - - /* assign system TTY channel (first free subchannel after each - * processor's individual TTY channel has been assigned) - */ - subch->use = BRL1_SUBCH_RSVD; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - if( sc->uart == BRL1_LOCALHUB_UART ) { - static sc_cq_t x_iqp; - - subch->iqp = &x_iqp; - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - } - else { - /* we shouldn't be getting console input from remote UARTs */ - subch->iqp = &sc->garbage_q; - } - subch++; i++; - - /* "reserved" subchannels (0x05-0x0F); for now, throw away - * incoming packets - */ - for( ; i < 0x10; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - subch->iqp = &sc->garbage_q; - } - - /* remaining subchannels are free */ - for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) { - subch->use = BRL1_SUBCH_FREE; - subch->packet_arrived = ATOMIC_INIT(0); - subch->tx_notify = NULL; - subch->rx_notify = NULL; - subch->iqp = &sc->garbage_q; - } -} - -static inline l1sc_t * -early_sc_init(nasid_t nasid) -{ - /* This is for early I/O */ - if ( Early_console_inited == 0 ) { - early_brl1_init(&Early_console, nasid, BRL1_LOCALHUB_UART); - Early_console_inited = 1; - } - return(&Early_console); -} - -#define PUTCHAR(ch) \ - { \ - while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \ - (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \ - WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \ - } - -static int -early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state ) -{ - int ret, sent = 0; - char *msg = str; - static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state ); - - while ( sent < len ) { - ret = early_l1_send(nasid, msg, len - sent, lock_state); - sent += ret; - msg += ret; - } - return(len); -} - -static inline int -early_l1_send( nasid_t nasid, char *str, int len, int lock_state ) -{ - int sent; - char crc_char; - unsigned short crc = INIT_CRC; - - if( len > (BRL1_QSIZE - 1) ) - len = (BRL1_QSIZE - 1); - - sent = len; - if ( lock_state == NOT_LOCKED ) - lock_console(nasid); - - PUTCHAR( BRL1_FLAG_CH ); - PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM ); - crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) ); - - while( len ) { - - if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) { - PUTCHAR( BRL1_ESC_CH ); - PUTCHAR( (*str) ^ BRL1_XOR_CH ); - } - else { - PUTCHAR( *str ); - } - - crc = crc16_calc( crc, *str ); - - str++; len--; - } - - crc ^= 0xffff; - crc_char = crc & 0xff; - if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { - crc_char ^= BRL1_XOR_CH; - PUTCHAR( BRL1_ESC_CH ); - } - PUTCHAR( crc_char ); - crc_char = (crc >> 8) & 0xff; - if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { - crc_char ^= BRL1_XOR_CH; - PUTCHAR( BRL1_ESC_CH ); - } - PUTCHAR( crc_char ); - PUTCHAR( BRL1_FLAG_CH ); - - if ( lock_state == NOT_LOCKED ) - unlock_console(nasid); - return sent; -} - -/********************************************************************* - * l1_cons functions - * - * These allow the L1 to act as the system console. They're intended - * to abstract away most of the br/l1 internal details from the - * _L1_cons_* functions (in the prom-- see "l1_console.c") and - * l1_* functions (in the kernel-- see "sio_l1.c") that they support. - * - */ - -static int -l1_poll( l1sc_t *sc, int mode ) -{ - int ret; - - /* in case this gets called before the l1sc_t structure for the module_t - * struct for this node is initialized (i.e., if we're called with a - * zero l1sc_t pointer)... - */ - - - if( !sc ) { - return 0; - } - - if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) { - return 1; - } - - ret = brl1_receive( sc, mode ); - if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) ) - L1_collectibles[L1C_REC_STALLS] = ret; - - if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) { - return 1; - } - return 0; -} - - -/* pull a character off of the system console queue (if one is available) - */ -static int -l1_getc( l1sc_t *sc, int mode ) -{ - unsigned long pl = 0; - int c; - - brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]); - sc_cq_t *q = subch->iqp; - - if( !l1_poll( sc, mode ) ) { - return 0; - } - - SUBCH_DATA_LOCK( subch, pl ); - if( cq_empty( q ) ) { - atomic_set(&subch->packet_arrived, 0); - SUBCH_DATA_UNLOCK( subch, pl ); - return 0; - } - cq_rem( q, c ); - if( cq_empty( q ) ) - atomic_set(&subch->packet_arrived, 0); - SUBCH_DATA_UNLOCK( subch, pl ); - - return c; -} - -/* - * Write a message to the L1 on the system console subchannel. - * - * Danger: don't use a non-zero value for the wait parameter unless you're - * someone important (like a kernel error message). - */ - -int -l1_write( l1sc_t *sc, char *msg, int len, int wait ) -{ - int sent = 0, ret = 0; - - if ( wait ) { - while ( sent < len ) { - ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait ); - sent += ret; - msg += ret; - } - ret = len; - } - else { - ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait ); - } - return(ret); -} - -/* initialize the system console subchannel - */ -void -l1_init(void) -{ - /* All we do now is remember that we have been called */ - L1_cons_is_inited = 1; -} - - -/********************************************************************* - * The following functions and definitions implement the "message"- - * style interface to the L1 system controller. - * - * Note that throughout this file, "sc" generally stands for "system - * controller", while "subchannels" tend to be represented by - * variables with names like subch or ch. - * - */ - -#ifdef L1_DEBUG -#define L1_DBG_PRF(x) printf x -#else -#define L1_DBG_PRF(x) -#endif - -/* - * sc_data_ready is called to signal threads that are blocked on l1 input. - */ -void -sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch ) -{ - unsigned long pl = 0; - - brl1_sch_t *subch = &(sc->subch[ch]); - SUBCH_DATA_LOCK( subch, pl ); - sv_signal( &(subch->arrive_sv) ); - SUBCH_DATA_UNLOCK( subch, pl ); -} - -/* sc_open reserves a subchannel to send a request to the L1 (the - * L1's response will arrive on the same channel). The number - * returned by sc_open is the system controller subchannel - * acquired. - */ -int -sc_open( l1sc_t *sc, uint target ) -{ - /* The kernel version implements a locking scheme to arbitrate - * subchannel assignment. - */ - int ch; - unsigned long pl = 0; - brl1_sch_t *subch; - - SUBCH_LOCK( sc, pl ); - - /* Look for a free subchannel. Subchannels 0-15 are reserved - * for other purposes. - */ - for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; - ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) { - if( subch->use == BRL1_SUBCH_FREE ) - break; - } - - if( ch == BRL1_NUM_SUBCHANS ) { - /* there were no subchannels available! */ - SUBCH_UNLOCK( sc, pl ); - return SC_NSUBCH; - } - - subch->use = BRL1_SUBCH_RSVD; - SUBCH_UNLOCK( sc, pl ); - - atomic_set(&subch->packet_arrived, 0); - subch->target = target; - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */); - subch->tx_notify = NULL; - subch->rx_notify = sc_data_ready; - subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, - NASID_TO_COMPACT_NODEID(sc->nasid) ); - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - - return ch; -} - - -/* sc_close frees a Bedrock<->L1 subchannel. - */ -int -sc_close( l1sc_t *sc, int ch ) -{ - unsigned long pl = 0; - brl1_sch_t *subch; - - SUBCH_LOCK( sc, pl ); - subch = &(sc->subch[ch]); - if( subch->use != BRL1_SUBCH_RSVD ) { - /* we're trying to close a subchannel that's not open */ - SUBCH_UNLOCK( sc, pl ); - return SC_NOPEN; - } - - atomic_set(&subch->packet_arrived, 0); - subch->use = BRL1_SUBCH_FREE; - - sv_broadcast( &(subch->arrive_sv) ); - sv_destroy( &(subch->arrive_sv) ); - spin_lock_destroy( &(subch->data_lock) ); - - ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) ); - snia_kmem_free( subch->iqp, sizeof(sc_cq_t) ); - subch->iqp = &sc->garbage_q; - subch->tx_notify = NULL; - subch->rx_notify = brl1_discard_packet; - - SUBCH_UNLOCK( sc, pl ); - - return SC_SUCCESS; -} - - -/* sc_construct_msg builds a bedrock-to-L1 request in the supplied - * buffer. Returns the length of the message. The - * safest course when passing a buffer to be filled in is to use - * BRL1_QSIZE as the buffer size. - * - * Command arguments are passed as type/argument pairs, i.e., to - * pass the number 5 as an argument to an L1 command, call - * sc_construct_msg as follows: - * - * char msg[BRL1_QSIZE]; - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 2, - * L1_ARG_INT, 5 ); - * - * To pass an additional ASCII argument, you'd do the following: - * - * char *str; - * ... str points to a null-terminated ascii string ... - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 4, - * L1_ARG_INT, 5, - * L1_ARG_ASCII, str ); - * - * Finally, arbitrary data of unknown type is passed using the argtype - * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g. - * - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 3, - * L1_ARG_UNKNOWN, 32, bufptr ); - * - * ...passes 32 bytes of data starting at bufptr. Note that no string or - * "unknown"-type argument should be long enough to overflow the message - * buffer. - * - * To construct a message for an L1 command that requires no arguments, - * you'd use the following: - * - * msg_len = sc_construct_msg( msg, - * BRL1_QSIZE, - * target_component, - * L1_ADDR_TASK_BOGUSTASK, - * L1_BOGUSTASK_REQ_BOGUSREQ, - * 0 ); - * - * The final 0 means "no varargs". Notice that this parameter is used to hold - * the number of additional arguments to sc_construct_msg, _not_ the actual - * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII] - * type argument, and 3 per L1_ARG_UNKOWN type argument). A call to construct - * an L1 command which required three integer arguments and two arguments of - * some arbitrary (unknown) type would pass 12 as the value for this parameter. - * - * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth - * between byte arrays and four-byte big-endian integers. Depending on the - * system controller connection and endianness of future architectures, some - * rewriting might be necessary. - */ -int -sc_construct_msg( l1sc_t *sc, /* system controller struct */ - int ch, /* subchannel for this message */ - char *msg, /* message buffer */ - int msg_len, /* size of message buffer */ - l1addr_t addr_task, /* target system controller task */ - short req_code, /* 16-bit request code */ - int req_nargs, /* # of arguments (varargs) passed */ - ... ) /* any additional parameters */ -{ - uint32_t buf32; /* 32-bit buffer used to bounce things around */ - void *bufptr; /* used to hold command argument addresses */ - va_list al; /* variable argument list */ - int index; /* current index into msg buffer */ - int argno; /* current position in varargs list */ - int l1_argno; /* running total of arguments to l1 */ - int l1_arg_t; /* argument type/length */ - int l1_argno_byte; /* offset of argument count byte */ - - index = argno = 0; - - /* set up destination address */ - if( (msg_len -= sizeof( buf32 )) < 0 ) - return -1; - L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task ); - COPY_INT_TO_BUFFER(msg, index, buf32); - - /* copy request code */ - if( (msg_len -= 2) < 0 ) - return( -1 ); - msg[index++] = ((req_code >> 8) & 0xff); - msg[index++] = (req_code & 0xff); - - if( !req_nargs ) { - return index; - } - - /* reserve a byte for the argument count */ - if( (msg_len -= 1) < 0 ) - return( -1 ); - l1_argno_byte = index++; - l1_argno = 0; - - /* copy additional arguments */ - va_start( al, req_nargs ); - while( argno < req_nargs ) { - l1_argno++; - l1_arg_t = va_arg( al, int ); argno++; - switch( l1_arg_t ) - { - case L1_ARG_INT: - if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 ) - return( -1 ); - msg[index++] = L1_ARG_INT; - buf32 = (unsigned)va_arg( al, int ); argno++; - COPY_INT_TO_BUFFER(msg, index, buf32); - break; - - case L1_ARG_ASCII: - bufptr = va_arg( al, char* ); argno++; - if( (msg_len -= (strlen( bufptr ) + 2)) < 0 ) - return( -1 ); - msg[index++] = L1_ARG_ASCII; - strcpy( (char *)&(msg[index]), (char *)bufptr ); - index += (strlen( bufptr ) + 1); /* include terminating null */ - break; - - case L1_ARG_UNKNOWN: - { - int arglen; - - arglen = va_arg( al, int ); argno++; - bufptr = va_arg( al, void* ); argno++; - if( (msg_len -= (arglen + 1)) < 0 ) - return( -1 ); - msg[index++] = L1_ARG_UNKNOWN | arglen; - BCOPY( bufptr, &(msg[index]), arglen ); - index += arglen; - break; - } - - default: /* unhandled argument type */ - return -1; - } - } - - va_end( al ); - msg[l1_argno_byte] = l1_argno; - - return index; -} - - - -/* sc_interpret_resp verifies an L1 response to a bedrock request, and - * breaks the response data up into the constituent parts. If the - * response message indicates error, or if a mismatch is found in the - * expected number and type of arguments, an error is returned. The - * arguments to this function work very much like the arguments to - * sc_construct_msg, above, except that L1_ARG_INTs must be followed - * by a _pointer_ to an integer that can be filled in by this function. - */ -int -sc_interpret_resp( char *resp, /* buffer received from L1 */ - int resp_nargs, /* number of _varargs_ passed in */ - ... ) -{ - uint32_t buf32; /* 32-bit buffer used to bounce things around */ - void *bufptr; /* used to hold response field addresses */ - va_list al; /* variable argument list */ - int index; /* current index into response buffer */ - int argno; /* current position in varargs list */ - int l1_fldno; /* number of resp fields received from l1 */ - int l1_fld_t; /* field type/length */ - - index = argno = 0; - -#if defined(L1_DEBUG) -#define DUMP_RESP \ - { \ - int ix; \ - char outbuf[512]; \ - sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \ - for( ix = 0; ix < 16; ix++ ) { \ - sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] ); \ - } \ - printk( "%s\n", outbuf ); \ - } -#else -#define DUMP_RESP -#endif /* L1_DEBUG */ - - /* check response code */ - COPY_BUFFER_TO_INT(resp, index, buf32); - if( buf32 != L1_RESP_OK ) { - DUMP_RESP; - return buf32; - } - - /* get number of response fields */ - l1_fldno = resp[index++]; - - va_start( al, resp_nargs ); - - /* copy out response fields */ - while( argno < resp_nargs ) { - l1_fldno--; - l1_fld_t = va_arg( al, int ); argno++; - switch( l1_fld_t ) - { - case L1_ARG_INT: - if( resp[index++] != L1_ARG_INT ) { - /* type mismatch */ - va_end( al ); - DUMP_RESP; - return -1; - } - bufptr = va_arg( al, int* ); argno++; - COPY_BUFFER_TO_BUFFER(resp, index, bufptr); - break; - - case L1_ARG_ASCII: - if( resp[index++] != L1_ARG_ASCII ) { - /* type mismatch */ - va_end( al ); - DUMP_RESP; - return -1; - } - bufptr = va_arg( al, char* ); argno++; - strcpy( (char *)bufptr, (char *)&(resp[index]) ); - /* include terminating null */ - index += (strlen( &(resp[index]) ) + 1); - break; - - default: - if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN ) - { - int *arglen; - - arglen = va_arg( al, int* ); argno++; - bufptr = va_arg( al, void* ); argno++; - *arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff); - BCOPY( &(resp[index]), bufptr, *arglen ); - index += (*arglen); - } - - else { - /* unhandled type */ - va_end( al ); - DUMP_RESP; - return -1; - } - } - } - va_end( al ); - - if( (l1_fldno != 0) || (argno != resp_nargs) ) { - /* wrong number of arguments */ - DUMP_RESP; - return -1; - } - return 0; -} - -/* sc_send takes as arguments a system controller struct, a - * buffer which contains a Bedrock<->L1 "request" message, - * the message length, and the subchannel (presumably obtained - * from an earlier invocation of sc_open) over which the - * message is to be sent. The final argument ("wait") indicates - * whether the send is to be performed synchronously or not. - * - * sc_send returns either zero or an error value. Synchronous sends - * (wait != 0) will not return until the data has actually been sent - * to the UART. Synchronous sends generally receive privileged - * treatment. The intent is that they be used sparingly, for such - * purposes as kernel printf's (the "ducons" routines). Run-of-the-mill - * console output and L1 requests should NOT use a non-zero value - * for wait. - */ -int -sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait ) -{ - char type_and_subch; - int result; - - if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) { - return SC_BADSUBCH; - } - - /* Verify that this is an open subchannel - */ - if( sc->subch[ch].use == BRL1_SUBCH_FREE ) { - return SC_NOPEN; - } - - type_and_subch = (BRL1_REQUEST | ((u_char)ch)); - result = brl1_send( sc, msg, len, type_and_subch, wait ); - - /* If we sent as much as we asked to, return "ok". */ - if( result == len ) - return( SC_SUCCESS ); - - /* Or, if we sent less, than either the UART is busy or - * we're trying to send too large a packet anyway. - */ - else if( result >= 0 && result < len ) - return( SC_BUSY ); - - /* Or, if something else went wrong (result < 0), then - * return that error value. - */ - else - return( result ); -} - -/* subch_pull_msg pulls a message off the receive queue for subch - * and places it the buffer pointed to by msg. This routine should only - * be called when the caller already knows a message is available on the - * receive queue (and, in the kernel, only when the subchannel data lock - * is held by the caller). - */ -static void -subch_pull_msg( brl1_sch_t *subch, char *msg, int *len ) -{ - sc_cq_t *q; /* receive queue */ - int before_wrap, /* packet may be split into two different */ - after_wrap; /* pieces to acommodate queue wraparound */ - - /* pull message off the receive queue */ - q = subch->iqp; - - cq_rem( q, *len ); /* remove length byte and store */ - cq_discard( q ); /* remove type/subch byte and discard */ - - if ( *len > 0 ) - (*len)--; /* don't count type/subch byte in length returned */ - - if( (q->opos + (*len)) > BRL1_QSIZE ) { - before_wrap = BRL1_QSIZE - q->opos; - after_wrap = (*len) - before_wrap; - } - else { - before_wrap = (*len); - after_wrap = 0; - } - - BCOPY( q->buf + q->opos, msg, before_wrap ); - if( after_wrap ) { - BCOPY( q->buf, msg + before_wrap, after_wrap ); - q->opos = after_wrap; - } - else { - q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1)); - } - atomic_dec(&(subch->packet_arrived)); -} - - -/* sc_recv_poll can be called as a blocking or non-blocking function; - * it attempts to pull a message off of the subchannel specified - * in the argument list (ch). - * - * The "block" argument, if non-zero, is interpreted as a timeout - * delay (to avoid permanent waiting). - */ - -int -sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block ) -{ - int is_msg = 0; - unsigned long pl = 0; - brl1_sch_t *subch = &(sc->subch[ch]); - - rtc_time_t exp_time = rtc_time() + block; - - /* sanity check-- make sure this is an open subchannel */ - if( subch->use == BRL1_SUBCH_FREE ) - return( SC_NOPEN ); - - do { - - /* kick the next lower layer and see if it pulls anything in - */ - brl1_receive( sc, SERIAL_POLLED_MODE ); - is_msg = atomic_read(&subch->packet_arrived); - - } while( block && !is_msg && (rtc_time() < exp_time) ); - - if( !is_msg ) { - /* no message and we didn't care to wait for one */ - return( SC_NMSG ); - } - - SUBCH_DATA_LOCK( subch, pl ); - subch_pull_msg( subch, msg, len ); - SUBCH_DATA_UNLOCK( subch, pl ); - - return( SC_SUCCESS ); -} - - -/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking - * or non-blocking mode. Rather than polling until an appointed timeout, - * however, sc_recv_intr sleeps on a syncrhonization variable until a - * signal from the lower layer tells us that a packet has arrived. - * - * sc_recv_intr can't be used with remote (router) L1s. - */ -int -sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block ) -{ - int is_msg = 0; - unsigned long pl = 0; - brl1_sch_t *subch = &(sc->subch[ch]); - - do { - SUBCH_DATA_LOCK(subch, pl); - is_msg = atomic_read(&subch->packet_arrived); - if( !is_msg && block ) { - /* wake me when you've got something */ - subch->rx_notify = sc_data_ready; - sv_wait( &(subch->arrive_sv), 0, 0); - if( subch->use == BRL1_SUBCH_FREE ) { - /* oops-- somebody closed our subchannel while we were - * sleeping! - */ - - /* no need to unlock since the channel's closed anyhow */ - return( SC_NOPEN ); - } - } - } while( !is_msg && block ); - - if( !is_msg ) { - /* no message and we didn't care to wait for one */ - SUBCH_DATA_UNLOCK( subch, pl ); - return( SC_NMSG ); - } - - subch_pull_msg( subch, msg, len ); - SUBCH_DATA_UNLOCK( subch, pl ); - - return( SC_SUCCESS ); -} - -/* sc_command implements a (blocking) combination of sc_send and sc_recv. - * It is intended to be the SN1 equivalent of SN0's "elsc_command", which - * issued a system controller command and then waited for a response from - * the system controller before returning. - * - * cmd points to the outgoing command; resp points to the buffer in - * which the response is to be stored. Both buffers are assumed to - * be the same length; if there is any doubt as to whether the - * response buffer is long enough to hold the L1's response, then - * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any - * bigger. - * - * Be careful using the same buffer for both cmd and resp; it could get - * hairy if there were ever an L1 command reqeuest that spanned multiple - * packets. (On the other hand, that would require some additional - * rewriting of the L1 command interface anyway.) - */ -#define __RETRIES 50 -#define __WAIT_SEND 1 // ( sc->uart != BRL1_LOCALHUB_UART ) -#define __WAIT_RECV 10000000 - - -int -sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ) -{ - int result; - int retries; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return SC_NMSG; - - retries = __RETRIES; - - while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) { - if( result == SC_BUSY ) { - retries--; - if( retries <= 0 ) - return result; - uart_delay(500); - } - else { - return result; - } - } - - /* block on sc_recv_* */ - if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) { - return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) ); - } - else { - return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) ); - } -} - -/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command - * used in situations where the kernel has a command that shouldn't be - * delayed until the send buffer clears. sc_command should be used instead - * under most circumstances. - */ - -int -sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ) -{ - int result; - - if ( IS_RUNNING_ON_SIMULATOR() ) - return SC_NMSG; - - if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) { - return result; - } - - return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) ); -} - - - -/* sc_poll checks the queue corresponding to the given - * subchannel to see if there's anything available. If - * not, it kicks the brl1 layer and then checks again. - * - * Returns 1 if input is available on the given queue, - * 0 otherwise. - */ - -int -sc_poll( l1sc_t *sc, int ch ) -{ - brl1_sch_t *subch = &(sc->subch[ch]); - - if( atomic_read(&subch->packet_arrived) ) - return 1; - - brl1_receive( sc, SERIAL_POLLED_MODE ); - - if( atomic_read(&subch->packet_arrived) ) - return 1; - - return 0; -} - -/* for now, sc_init just calls brl1_init */ - -void -sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) -{ - if ( !IS_RUNNING_ON_SIMULATOR() ) - brl1_init( sc, nasid, uart ); -} - -/* sc_dispatch_env_event handles events sent from the system control - * network's environmental monitor tasks. - */ - -#if defined(LINUX_KERNEL_THREADS) - -static void -sc_dispatch_env_event( uint code, int argc, char *args, int maxlen ) -{ - int j, i = 0; - uint32_t ESPcode; - - switch( code ) { - /* for now, all codes do the same thing: grab two arguments - * and print a cmn_err_tag message */ - default: - /* check number of arguments */ - if( argc != 2 ) { - L1_DBG_PRF(( "sc_dispatch_env_event: " - "expected 2 arguments, got %d\n", argc )); - return; - } - - /* get ESP code (integer argument) */ - if( args[i++] != L1_ARG_INT ) { - L1_DBG_PRF(( "sc_dispatch_env_event: " - "expected integer argument\n" )); - return; - } - /* WARNING: highly endian */ - COPY_BUFFER_TO_INT(args, i, ESPcode); - - /* verify string argument */ - if( args[i++] != L1_ARG_ASCII ) { - L1_DBG_PRF(( "sc_dispatch_env_event: " - "expected an ASCII string\n" )); - return; - } - for( j = i; j < maxlen; j++ ) { - if( args[j] == '\0' ) break; /* found string termination */ - } - if( j == maxlen ) { - j--; - L1_DBG_PRF(( "sc_dispatch_env_event: " - "message too long-- truncating\n" )); - } - - /* strip out trailing cr/lf */ - for( ; - j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); - j-- ); - args[j] = '\0'; - - /* strip out leading cr/lf */ - for( ; - i < j && ((args[i] == 0xd) || (args[i] == 0xa)); - i++ ); - } -} - - -/* sc_event waits for events to arrive from the system controller, and - * prints appropriate messages to the syslog. - */ - -static void -sc_event( l1sc_t *sc, int ch ) -{ - char event[BRL1_QSIZE]; - int i; - int result; - int event_len; - uint32_t ev_src; - uint32_t ev_code; - int ev_argc; - - while(1) { - - bzero( event, BRL1_QSIZE ); - - /* - * wait for an event - */ - result = sc_recv_intr( sc, ch, event, &event_len, 1 ); - if( result != SC_SUCCESS ) { - printk(KERN_WARNING "Error receiving sysctl event on nasid %d\n", - sc->nasid ); - } - else { - /* - * an event arrived; break it down into useful pieces - */ -#if defined(L1_DEBUG) && 0 - int ix; - printf( "Event packet received:\n" ); - for (ix = 0; ix < 64; ix++) { - printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)), - (event[ix] & ((uint64_t)0xf)) ); - if( (ix % 16) == 0xf ) printf( "\n" ); - } -#endif /* L1_DEBUG */ - - i = 0; - - /* get event source */ - COPY_BUFFER_TO_INT(event, i, ev_src); - COPY_BUFFER_TO_INT(event, i, ev_code); - - /* get arg count */ - ev_argc = (event[i++] & 0xffUL); - - /* dispatch events by task */ - switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT ) - { - case L1_ADDR_TASK_ENV: /* environmental monitor event */ - sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), - BRL1_QSIZE - i ); - break; - - default: /* unhandled task type */ - L1_DBG_PRF(( "Unhandled event type received from system " - "controllers: source task %x\n", - (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT - )); - } - } - - } -} - -/* sc_listen sets up a service thread to listen for incoming events. - */ - -void -sc_listen( l1sc_t *sc ) -{ - int result; - unsigned long pl = 0; - brl1_sch_t *subch; - - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int ch; /* system controller subchannel used */ - - extern int msc_shutdown_pri; - - /* grab the designated "event subchannel" */ - SUBCH_LOCK( sc, pl ); - subch = &(sc->subch[BRL1_EVENT_SUBCH]); - if( subch->use != BRL1_SUBCH_FREE ) { - SUBCH_UNLOCK( sc, pl ); - printk(KERN_WARNING "sysctl event subchannel in use! " - "Not monitoring sysctl events.\n" ); - return; - } - subch->use = BRL1_SUBCH_RSVD; - SUBCH_UNLOCK( sc, pl ); - - atomic_set(&subch->packet_arrived, 0); - subch->target = BRL1_LOCALHUB_UART; - spin_lock_init( &(subch->data_lock) ); - sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */); - subch->tx_notify = NULL; - subch->rx_notify = sc_data_ready; - subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, - NASID_TO_COMPACT_NODEID(sc->nasid) ); - ASSERT( subch->iqp ); - cq_init( subch->iqp ); - - /* set up a thread to listen for events */ - sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri, - KT_PS, (st_func_t *) sc_event, - (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 ); - - /* signal the L1 to begin sending events */ - bzero( msg, BRL1_QSIZE ); - ch = sc_open( sc, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_EVENT_SUBCH, 2, - L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 ) - { - sc_close( sc, ch ); - L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len )); - goto err_return; - } - - result = sc_command_kern( sc, ch, msg, msg, &len ); - if( result < 0 ) - { - sc_close( sc, ch ); - L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result )); - goto err_return; - } - - sc_close( sc, ch ); - - result = sc_interpret_resp( msg, 0 ); - if( result < 0 ) - { - L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result )); - goto err_return; - } - - /* everything went fine; just return */ - return; - -err_return: - /* there was a problem; complain */ - printk(KERN_WARNING "failed to set sysctl event-monitoring subchannel. " - "Sysctl events will not be monitored.\n" ); -} - -#endif /* LINUX_KERNEL_THREADS */ diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/l1_command.c linux-2.4.22/arch/ia64/sn/io/sn1/l1_command.c --- linux-2.4.21/arch/ia64/sn/io/sn1/l1_command.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/l1_command.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1409 +0,0 @@ -/* $Id: l1_command.c,v 1.2 2002/11/21 17:51:57 jh Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ELSC_TIMEOUT 1000000 /* ELSC response timeout (usec) */ -#define LOCK_TIMEOUT 5000000 /* Hub lock timeout (usec) */ - -#define LD(x) (*(volatile uint64_t *)(x)) -#define SD(x, v) (LD(x) = (uint64_t) (v)) - -#define hub_cpu_get() 0 - -#define LBYTE(caddr) (*(char *) caddr) - -extern char *bcopy(const char * src, char * dest, int count); - -#define LDEBUG 0 - -/* - * ELSC data is in NVRAM page 7 at the following offsets. - */ - -#define NVRAM_MAGIC_AD 0x700 /* magic number used for init */ -#define NVRAM_PASS_WD 0x701 /* password (4 bytes in length) */ -#define NVRAM_DBG1 0x705 /* virtual XOR debug switches */ -#define NVRAM_DBG2 0x706 /* physical XOR debug switches */ -#define NVRAM_CFG 0x707 /* ELSC Configuration info */ -#define NVRAM_MODULE 0x708 /* system module number */ -#define NVRAM_BIST_FLG 0x709 /* BIST flags (2 bits per nodeboard) */ -#define NVRAM_PARTITION 0x70a /* module's partition id */ -#define NVRAM_DOMAIN 0x70b /* module's domain id */ -#define NVRAM_CLUSTER 0x70c /* module's cluster id */ -#define NVRAM_CELL 0x70d /* module's cellid */ - -#define NVRAM_MAGIC_NO 0x37 /* value of magic number */ -#define NVRAM_SIZE 16 /* 16 bytes in nvram */ - -/* - * Declare a static ELSC NVRAM buffer to hold all data read from - * and written to NVRAM. This nvram "cache" will be used only during the - * IP27prom execution. - */ -static char elsc_nvram_buffer[NVRAM_SIZE]; - -#define SC_COMMAND sc_command - -/* - * elsc_init - * - * Initialize ELSC structure - */ - -void elsc_init(elsc_t *e, nasid_t nasid) -{ - sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART); -} - - -/* - * elsc_errmsg - * - * Given a negative error code, - * returns a corresponding static error string. - */ - -char *elsc_errmsg(int code) -{ - switch (code) { - case ELSC_ERROR_CMD_SEND: - return "Command send error"; - case ELSC_ERROR_CMD_CHECKSUM: - return "Command packet checksum error"; - case ELSC_ERROR_CMD_UNKNOWN: - return "Unknown command"; - case ELSC_ERROR_CMD_ARGS: - return "Invalid command argument(s)"; - case ELSC_ERROR_CMD_PERM: - return "Permission denied"; - case ELSC_ERROR_RESP_TIMEOUT: - return "System controller response timeout"; - case ELSC_ERROR_RESP_CHECKSUM: - return "Response packet checksum error"; - case ELSC_ERROR_RESP_FORMAT: - return "Response format error"; - case ELSC_ERROR_RESP_DIR: - return "Response direction error"; - case ELSC_ERROR_MSG_LOST: - return "Message lost because queue is full"; - case ELSC_ERROR_LOCK_TIMEOUT: - return "Timed out getting ELSC lock"; - case ELSC_ERROR_DATA_SEND: - return "Error sending data"; - case ELSC_ERROR_NIC: - return "NIC protocol error"; - case ELSC_ERROR_NVMAGIC: - return "Bad magic number in NVRAM"; - case ELSC_ERROR_MODULE: - return "Module location protocol error"; - default: - return "Unknown error"; - } -} - -/* - * elsc_nvram_init - * - * Initializes reads and writes to NVRAM. This will perform a single - * read to NVRAM, getting all data at once. When the PROM tries to - * read NVRAM, it returns the data from the buffer being read. If the - * PROM tries to write out to NVRAM, the write is done, and the internal - * buffer is updated. - */ - -void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data) -{ - /* This might require implementation of multiple-packet request/responses - * if it's to provide the same behavior that was available in SN0. - */ - nasid = nasid; - elsc_nvram_data = elsc_nvram_data; -} - -/* - * elsc_nvram_copy - * - * Copies the content of a buffer into the static buffer in this library. - */ - -void elsc_nvram_copy(uchar_t *elsc_nvram_data) -{ - memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE); -} - -/* - * elsc_nvram_write - * - * Copies bytes from 'buf' into NVRAM, starting at NVRAM address - * 'addr' which must be between 0 and 2047. - * - * If 'len' is non-negative, the routine copies 'len' bytes. - * - * If 'len' is negative, the routine treats the data as a string and - * copies bytes up to and including a NUL-terminating zero, but not - * to exceed '-len' bytes. - */ - -int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len) -{ - /* Here again, we might need to work out the details of a - * multiple-packet protocol. - */ - - /* For now, pretend it worked. */ - e = e; - addr = addr; - buf = buf; - return (len < 0 ? -len : len); -} - -/* - * elsc_nvram_read - * - * Copies bytes from NVRAM into 'buf', starting at NVRAM address - * 'addr' which must be between 0 and 2047. - * - * If 'len' is non-negative, the routine copies 'len' bytes. - * - * If 'len' is negative, the routine treats the data as a string and - * copies bytes up to and including a NUL-terminating zero, but not - * to exceed '-len' bytes. NOTE: This method is no longer supported. - * It was never used in the first place. - */ - -int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len) -{ - /* multiple packets? */ - e = e; - addr = addr; - buf = buf; - len = len; - return -1; -} - - -/* - * Command Set - */ - -int elsc_version(elsc_t *e, char *result) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - int major, /* major rev number */ - minor, /* minor rev number */ - bugfix; /* bugfix rev number */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_FW_REV, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( (l1sc_t *)e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major, - L1_ARG_INT, &minor, L1_ARG_INT, &bugfix ) - < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - sprintf( result, "%d.%d.%d", major, minor, bugfix ); - - return 0; -} - -int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2) -{ - /* shush compiler */ - e = e; - byte1 = byte1; - byte2 = byte2; - - /* fill in a buffer with the opcode & params; call sc_command */ - - return 0; -} - -int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2) -{ - char msg[BRL1_QSIZE]; - int subch; /* system controller subchannel used */ - int dbg_sw; /* holds debug switch settings */ - int len; /* number of msg buffer bytes used */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RDBG, 0 ) ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( (l1sc_t *)e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* copy out debug switch settings (last two bytes of the - * integer response) - */ - *byte1 = ((dbg_sw >> 8) & 0xFF); - *byte2 = (dbg_sw & 0xFF); - - return 0; -} - - -/* - * elsc_rack_bay_get fills in the two int * arguments with the - * rack number and bay number of the L1 being addressed - */ -int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t buf32; /* used to copy 32-bit rack/bay out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RRACK, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - - /* send the request to the L1 */ - if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close(e, subch); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* extract rack/bay info - * - * note that the 32-bit value returned by the L1 actually - * only uses the low-order sixteen bits for rack and bay - * information. A "normal" L1 address puts rack and bay - * information in bit positions 12 through 28. So if - * we initially shift the value returned 12 bits to the left, - * we can use the L1 addressing #define's to extract the - * values we need (see ksys/l1.h for a complete list of the - * various fields of an L1 address). - */ - buf32 <<= L1_ADDR_BAY_SHFT; - - *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - - return 0; -} - - -/* elsc_rack_bay_type_get fills in the three int * arguments with the - * rack number, bay number and brick type of the L1 being addressed. Note - * that if the L1 operation fails and this function returns an error value, - * garbage may be written to brick_type. - */ -int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, - uint *bay, uint *brick_type ) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t buf32; /* used to copy 32-bit rack & bay out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RRBT, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( sc, subch, msg, msg, &len ) ) { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, - L1_ARG_INT, brick_type ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* extract rack/bay info - * - * note that the 32-bit value returned by the L1 actually - * only uses the low-order sixteen bits for rack and bay - * information. A "normal" L1 address puts rack and bay - * information in bit positions 12 through 28. So if - * we initially shift the value returned 12 bits to the left, - * we can use the L1 addressing #define's to extract the - * values we need (see ksys/l1.h for a complete list of the - * various fields of an L1 address). - */ - buf32 <<= L1_ADDR_BAY_SHFT; - - *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - - /* convert brick_type to lower case */ - *brick_type = *brick_type - 'A' + 'a'; - - return 0; -} - - -int elsc_module_get(elsc_t *e) -{ - extern char brick_types[]; - uint rnum, rack, bay, bricktype, t; - int ret; - - /* construct module ID from rack and slot info */ - - if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) { - return ret; - } - - /* report unset location info. with a special, otherwise invalid modid */ - if (rnum == 0 && bay == 0) - return MODULE_NOT_SET; - - if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) - return ELSC_ERROR_MODULE; - - /* Build a moduleid_t-compatible rack number */ - - rack = 0; - t = rnum / 100; /* rack class (CPU/IO) */ - if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_CLASS(rack, t); - rnum %= 100; - - t = rnum / 10; /* rack group */ - if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_GROUP(rack, t); - - t = rnum % 10; /* rack number (one-based) */ - if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_NUM(rack, t); - - for( t = 0; t < MAX_BRICK_TYPES; t++ ) { - if( brick_types[t] == bricktype ) - return RBT_TO_MODULE(rack, bay, t); - } - - return ELSC_ERROR_MODULE; -} - -int elsc_partition_set(elsc_t *e, int partition) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_PARTITION_SET, 2, - L1_ARG_INT, partition )) < 0 ) - { - - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return( 0 ); -} - -int elsc_partition_get(elsc_t *e) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t partition_id; /* used to copy partition id out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_PARTITION_GET, 0 )) < 0 ) - - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return( partition_id ); -} - - -/* - * elsc_cons_subch selects the "active" console subchannel for this node - * (i.e., the one that will currently receive input) - */ -int elsc_cons_subch(elsc_t *e, uint ch) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_CONS_SUBCH, 2, - L1_ARG_INT, ch)) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -/* - * elsc_cons_node should only be executed by one node. It declares to - * the system controller that the node from which it is called will be - * the owner of the system console. - */ -int elsc_cons_node(elsc_t *e) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_CONS_NODE, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( e, subch, msg, msg, &len ) ) { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -/* elsc_display_line writes up to 12 characters to either the top or bottom - * line of the L1 display. line points to a buffer containing the message - * to be displayed. The zero-based line number is specified by lnum (so - * lnum == 0 specifies the top line and lnum == 1 specifies the bottom). - * Lines longer than 12 characters, or line numbers not less than - * L1_DISPLAY_LINES, cause elsc_display_line to return an error. - */ -int elsc_display_line(elsc_t *e, char *line, int lnum) -{ - char msg[BRL1_QSIZE]; - int subch; /* system controller subchannel used */ - int len; /* number of msg buffer bytes used */ - - /* argument sanity checking */ - if( !(lnum < L1_DISPLAY_LINES) ) - return( ELSC_ERROR_CMD_ARGS ); - if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) ) - return( ELSC_ERROR_CMD_ARGS ); - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - (L1_REQ_DISP1+lnum), 2, - L1_ARG_ASCII, line )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( (l1sc_t *)e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -/* elsc_display_mesg silently drops message characters beyond the 12th. - */ -int elsc_display_mesg(elsc_t *e, char *chr) -{ - - char line[L1_DISPLAY_LINE_LENGTH+1]; - int numlines, i; - int result; - - numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) / - L1_DISPLAY_LINE_LENGTH; - - if( numlines > L1_DISPLAY_LINES ) - numlines = L1_DISPLAY_LINES; - - for( i = 0; i < numlines; i++ ) - { - strncpy( line, chr, L1_DISPLAY_LINE_LENGTH ); - line[L1_DISPLAY_LINE_LENGTH] = '\0'; - - /* generally we want to leave the first line of the L1 display - * alone (so the L1 can manipulate it). If you need to be able - * to display to both lines (for debugging purposes), define - * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES - * to your 'defs file. - */ -#if defined(L1_DISP_2LINES) - if( (result = elsc_display_line( e, line, i )) < 0 ) -#else - if( (result = elsc_display_line( e, line, i+1 )) < 0 ) -#endif - - return result; - - chr += L1_DISPLAY_LINE_LENGTH; - } - - return 0; -} - - -int elsc_password_set(elsc_t *e, char *password) -{ - /* shush compiler */ - e = e; - password = password; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - -int elsc_password_get(elsc_t *e, char *password) -{ - /* shush compiler */ - e = e; - password = password; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - - -/* - * sc_portspeed_get - * - * retrieve the current portspeed setting for the bedrock II - */ -int sc_portspeed_get(l1sc_t *sc) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - int portspeed_a, portspeed_b; - /* ioport clock rates */ - - bzero( msg, BRL1_QSIZE ); - subch = sc_open( sc, L1_ADDR_LOCAL ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_PORTSPEED, - 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 4, - L1_ARG_INT, &portspeed_a, - L1_ARG_INT, &portspeed_b ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* for the c-brick, we ignore the portspeed_b value */ - return (portspeed_a ? 600 : 400); -} - -/* - * elsc_power_query - * - * To be used after system reset, this command returns 1 if the reset - * was the result of a power-on, 0 otherwise. - * - * The power query status is cleared to 0 after it is read. - */ - -int elsc_power_query(elsc_t *e) -{ - e = e; /* shush the compiler */ - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 1; -} - -int elsc_rpwr_query(elsc_t *e, int is_master) -{ - /* shush the compiler */ - e = e; - is_master = is_master; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - -/* - * elsc_power_down - * - * Sets up system to shut down in "sec" seconds (or modifies the - * shutdown time if one is already in effect). Use 0 to power - * down immediately. - */ - -int elsc_power_down(elsc_t *e, int sec) -{ - /* shush compiler */ - e = e; - sec = sec; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - - -int elsc_system_reset(elsc_t *e) -{ - char msg[BRL1_QSIZE]; - int subch; /* system controller subchannel used */ - int len; /* number of msg buffer bytes used */ - int result; - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { - return ELSC_ERROR_CMD_SEND; - } - - if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RESET, 0 )) < 0 ) - { - sc_close( e, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( (result = sc_command( e, subch, msg, msg, &len )) ) { - sc_close( e, subch ); - if( result == SC_NMSG ) { - /* timeout is OK. We've sent the reset. Now it's just - * a matter of time... - */ - return( 0 ); - } - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( e, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - - -int elsc_power_cycle(elsc_t *e) -{ - /* shush compiler */ - e = e; - - /* fill in buffer with the opcode & params; call sc_command */ - - return 0; -} - - -int _elsc_hbt(elsc_t *e, int ival, int rdly) -{ - e = e; - ival = ival; - rdly = rdly; - - /* fill in buffer with the opcode & params; call elsc_command */ - - return 0; -} - - -/* send a command string to an L1 */ -int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay, - char *cmd ) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - l1addr_t target; /* target system controller for command */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - - L1_BUILD_ADDR( &target, compt, rack, bay, 0 ); - subch = sc_open( sc, target ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2, - L1_ARG_ASCII, cmd )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; -} - -/* - * sc_power_down - * - * Shuts down the c-brick associated with sc, and any attached I/O bricks - * or other c-bricks (won't go through r-bricks). - */ - -int sc_power_down(l1sc_t *sc) -{ - return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, - L1_ADDR_BAY_LOCAL, "* pwr d" ); -} - - -/* - * sc_power_down_all - * - * Works similarly to sc_power_down, except that the request is sent to the - * closest L2 and EVERYBODY gets turned off. - */ - -int sc_power_down_all(l1sc_t *sc) -{ - if( nodepda->num_routers > 0 ) { - return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, - L1_ADDR_BAY_LOCAL, "* pwr d" ); - } - else { - return sc_power_down( sc ); - } -} - - -/* - * iobrick routines - */ - -/* iobrick_rack_bay_type_get fills in the three int * arguments with the - * rack number, bay number and brick type of the L1 being addressed. Note - * that if the L1 operation fails and this function returns an error value, - * garbage may be written to brick_type. - */ -int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, - uint *bay, uint *brick_type ) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - uint32_t buf32; /* used to copy 32-bit rack & bay out of msg */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_RRBT, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) ) { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, - L1_ARG_INT, brick_type ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - /* extract rack/bay info - * - * note that the 32-bit value returned by the L1 actually - * only uses the low-order sixteen bits for rack and bay - * information. A "normal" L1 address puts rack and bay - * information in bit positions 12 through 28. So if - * we initially shift the value returned 12 bits to the left, - * we can use the L1 addressing #define's to extract the - * values we need (see ksys/l1.h for a complete list of the - * various fields of an L1 address). - */ - buf32 <<= L1_ADDR_BAY_SHFT; - - *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - - return 0; -} - - -int iobrick_module_get(l1sc_t *sc) -{ - uint rnum, rack, bay, brick_type, t; - int ret; - - /* construct module ID from rack and slot info */ - - if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0) - return ret; - - if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) - return ELSC_ERROR_MODULE; - - /* Build a moduleid_t-compatible rack number */ - - rack = 0; - t = rnum / 100; /* rack class (CPU/IO) */ - if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_CLASS(rack, t); - rnum %= 100; - - t = rnum / 10; /* rack group */ - if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_GROUP(rack, t); - - t = rnum % 10; /* rack number (one-based) */ - if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) - return ELSC_ERROR_MODULE; - RACK_ADD_NUM(rack, t); - - switch( brick_type ) { - case 'I': - brick_type = MODULE_IBRICK; break; - case 'P': - brick_type = MODULE_PBRICK; break; - case 'X': - brick_type = MODULE_XBRICK; break; - } - - ret = RBT_TO_MODULE(rack, bay, brick_type); - - return ret; -} - -/* - * iobrick_module_get_nasid() returns a module_id which has the brick - * type encoded in bits 15-12, but this is not the true brick type... - * The module_id returned by iobrick_module_get_nasid() is modified - * to make a PEBRICKs & PXBRICKs look like a PBRICK. So this routine - * iobrick_type_get_nasid() returns the true unmodified brick type. - */ -int -iobrick_type_get_nasid(nasid_t nasid) -{ - l1sc_t *sc = get_elsc(); - elsc_t tmp_sc; - uint rack, bay, type; - int t, ret; - -#ifdef PIC_LATER - if (PEBRICK_NODE(nasid)) { - if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) { - printf("Could not read rack and bay location " - "of PEBrick at nasid %d\n", nasid); - } - if ((ret = peer_iobrick_type_get(sc, rack, bay, &type)) < 0) - return ret; - } - else -#endif /* PIC_LATER */ - if (nasid != get_nasid()) { /* get the io_moduleid from remote node */ - elsc_init(&tmp_sc, nasid); - if ((ret = iobrick_rack_bay_type_get(&tmp_sc, &rack, &bay, &type)) < 0) - return ret; - } - else { - if ((ret = iobrick_rack_bay_type_get(sc, &rack, &bay, &type)) < 0) - return ret; - } - - /* - * Some brick_types need special treatment. NOTE: This switch is - * duplicated in iobrick_module_get(), so if you change this switch - * you must also change it there. - */ - switch (type) - { - case L1_BRICKTYPE_IP45: - /* treat speedo2 like Ibrick for moduleid purposes */ - type = L1_BRICKTYPE_I; - break; - case L1_BRICKTYPE_X2: - /* give X2 bricks the same moduleid as earlier models */ - type = L1_BRICKTYPE_X; - break; - } - - /* convert brick_type to lower case */ - if ((type >= 'A') && (type <= 'Z')) - type = type - 'A' + 'a'; - - /* convert to a module.h brick type */ - for( t = 0; t < MAX_BRICK_TYPES; t++ ) { - if( brick_types[t] == type ) - return t; - } - - return -1; /* unknown brick */ -} - -int iobrick_module_get_nasid(nasid_t nasid) -{ - int io_moduleid; - l1sc_t *sc = get_elsc(); - elsc_t tmp_sc; - -#ifdef PIC_LATER - uint rack, bay; - - if (PEBRICK_NODE(nasid)) { - if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) { - printf("Could not read rack and bay location " - "of PEBrick at nasid %d\n", nasid); - } - - io_moduleid = peer_iobrick_module_get(sc, rack, bay); - } - else -#endif /* PIC_LATER */ - if (nasid != get_nasid()) { /* get the io_moduleid from remote node */ - elsc_init(&tmp_sc, nasid); - - io_moduleid = iobrick_module_get(&tmp_sc); - } - else { - io_moduleid = iobrick_module_get(sc); - } - - return io_moduleid; -} - - -/* iobrick_get_sys_snum asks the attached iobrick for the system - * serial number. This function will only be relevant to the master - * cbrick (the one attached to the bootmaster ibrick); other nodes - * may call the function, but the value returned to the master node - * will be the one used as the system serial number by the kernel. - */ - -int -iobrick_get_sys_snum( l1sc_t *sc, char *snum_str ) -{ - char msg[BRL1_QSIZE]; /* L1 request/response info */ - int subch; /* system controller subchannel used */ - int len; /* length of message */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) { - return( ELSC_ERROR_CMD_SEND ); - } - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_SYS_SERIAL, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( sc_command( sc, subch, msg, msg, &len ) ) { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) ); -} - - -/* - * The following functions apply (or cut off) power to the specified - * pci bus or slot. - */ - -int -iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code ) -{ -#if 0 /* The "bedrock request" method of performing this function - * seems to be broken in the L1, so for now use the command- - * interpreter method - */ - - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( sc, L1_ADDR_LOCALIO ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - req_code, 4, - L1_ARG_INT, bus, - L1_ARG_INT, slot )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 0 ) < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - return 0; - -#else - char cmd[64]; - char *fxn; - - switch( req_code ) - { - case L1_REQ_PCI_UP: - fxn = "u"; - break; - case L1_REQ_PCI_DOWN: - fxn = "d"; - break; - case L1_REQ_PCI_RESET: - fxn = "rst"; - break; - default: - return( ELSC_ERROR_CMD_ARGS ); - } - - if( slot == -1 ) - sprintf( cmd, "pci %d %s", bus, fxn ); - else - sprintf( cmd, "pci %d %d %s", bus, slot, fxn ); - - return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK, - L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd ); -#endif -} - -int -iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up ) -{ - return iobrick_pci_pwr( sc, bus, slot, up ); -} - -int -iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up ) -{ - return iobrick_pci_pwr( sc, bus, -1, up ); -} - - -int -iobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot ) -{ - return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET ); -} - -int -iobrick_pci_bus_rst( l1sc_t *sc, int bus ) -{ - return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET ); -} - - -/* get the L1 firmware version for an iobrick */ -int -iobrick_sc_version( l1sc_t *sc, char *result ) -{ - char msg[BRL1_QSIZE]; - int len; /* length of message being sent */ - int subch; /* system controller subchannel used */ - int major, /* major rev number */ - minor, /* minor rev number */ - bugfix; /* bugfix rev number */ - - /* fill in msg with the opcode & params */ - bzero( msg, BRL1_QSIZE ); - subch = sc_open( sc, L1_ADDR_LOCALIO ); - - if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, - L1_ADDR_TASK_GENERAL, - L1_REQ_FW_REV, 0 )) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_ARGS ); - } - - /* send the request to the L1 */ - if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 ) - { - sc_close( sc, subch ); - return( ELSC_ERROR_CMD_SEND ); - } - - /* free up subchannel */ - sc_close( sc, subch ); - - /* check response */ - if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major, - L1_ARG_INT, &minor, L1_ARG_INT, &bugfix ) - < 0 ) - { - return( ELSC_ERROR_RESP_FORMAT ); - } - - sprintf( result, "%d.%d.%d", major, minor, bugfix ); - - return 0; -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/mem_refcnt.c linux-2.4.22/arch/ia64/sn/io/sn1/mem_refcnt.c --- linux-2.4.21/arch/ia64/sn/io/sn1/mem_refcnt.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/mem_refcnt.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,220 +0,0 @@ -/* $Id: mem_refcnt.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// From numa_hw.h - -#define MIGR_COUNTER_MAX_GET(nodeid) \ - (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference) -/* - * Get the Absolute Theshold - */ -#define MIGR_THRESHOLD_ABS_GET(nodeid) ( \ - MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid))) -/* - * Get the current Differential Threshold - */ -#define MIGR_THRESHOLD_DIFF_GET(nodeid) \ - (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold) - -#define NUM_OF_HW_PAGES_PER_SW_PAGE() (NBPP / MD_PAGE_SIZE) - -// #include "migr_control.h" - -int -mem_refcnt_attach(devfs_handle_t hub) -{ -#if 0 - devfs_handle_t refcnt_dev; - - hwgraph_char_device_add(hub, - "refcnt", - "hubspc_", - &refcnt_dev); - device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS); -#endif - - return (0); -} - - -/*ARGSUSED*/ -int -mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp) -{ - cnodeid_t node; - - node = master_node_get(*devp); - - ASSERT( (node >= 0) && (node < numnodes) ); - - if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) { - return (ENODEV); - } - - ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); - ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 ); - - return (0); -} - -/*ARGSUSED*/ -int -mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) -{ - return 0; -} - -/*ARGSUSED*/ -int -mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) -{ - cnodeid_t node; - int errcode; - char* buffer; - size_t blen; - - node = master_node_get(dev); - - ASSERT( (node >= 0) && (node < numnodes) ); - - ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL); - ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); - ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 ); - - /* - * XXXX deal with prot's somewhere around here.... - */ - - buffer = NODEPDA(node)->migr_refcnt_counterbuffer; - blen = NODEPDA(node)->migr_refcnt_cbsize; - - /* - * Force offset to be a multiple of sizeof(refcnt_t) - * We round up. - */ - - off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t); - - if ( ((buffer + blen) - (buffer + off + len)) < 0 ) { - return (EPERM); - } - - errcode = v_mapphys(vt, - buffer + off, - len); - - return errcode; -} - -/*ARGSUSED*/ -int -mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt) -{ - return 0; -} - -/* ARGSUSED */ -int -mem_refcnt_ioctl(devfs_handle_t dev, - int cmd, - void *arg, - int mode, - cred_t *cred_p, - int *rvalp) -{ - cnodeid_t node; - int errcode; - extern int numnodes; - - node = master_node_get(dev); - - ASSERT( (node >= 0) && (node < numnodes) ); - - ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL); - ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); - ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 ); - - errcode = 0; - - switch (cmd) { - case RCB_INFO_GET: - { - rcb_info_t rcb; - - rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize; - - rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets; - rcb.rcb_sw_counters_per_set = numnodes; - rcb.rcb_sw_counter_size = sizeof(refcnt_t); - - rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets / - NUM_OF_HW_PAGES_PER_SW_PAGE(); - rcb.rcb_base_page_size = NBPP; - rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0)); - - rcb.rcb_cnodeid = node; - rcb.rcb_granularity = MD_PAGE_SIZE; -#ifdef LATER - rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node); - rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node); -#endif - rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node); - rcb.rcb_num_slots = MAX_MEM_SLOTS; - - if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) { - errcode = EFAULT; - } - - break; - } - case RCB_SLOT_GET: - { - rcb_slot_t slot[MAX_MEM_SLOTS]; - int s; - int nslots; - - nslots = MAX_MEM_SLOTS; - ASSERT(nslots <= MAX_MEM_SLOTS); - for (s = 0; s < nslots; s++) { - slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s)); -#ifdef LATER - slot[s].size = (uint64_t)ctob(slot_getsize(node, s)); -#else - slot[s].size = (uint64_t)1; -#endif - } - if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) { - errcode = EFAULT; - } - - *rvalp = nslots; - break; - } - - default: - errcode = EINVAL; - break; - - } - - return errcode; -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_init.c linux-2.4.22/arch/ia64/sn/io/sn1/ml_SN_init.c --- linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_init.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/ml_SN_init.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,211 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int numcpus; -extern char arg_maxnodes[]; -extern cpuid_t master_procid; -extern synergy_da_t *Synergy_da_indr[]; - -extern int hasmetarouter; - -int maxcpus; -cpumask_t boot_cpumask; -hubreg_t region_mask = 0; - - -extern xwidgetnum_t hub_widget_id(nasid_t); - -extern int valid_icache_reasons; /* Reasons to flush the icache */ -extern int valid_dcache_reasons; /* Reasons to flush the dcache */ -extern u_char miniroot; -extern volatile int need_utlbmiss_patch; -extern void iograph_early_init(void); - -nasid_t master_nasid = INVALID_NASID; - - -/* - * mlreset(int slave) - * very early machine reset - at this point NO interrupts have been - * enabled; nor is memory, tlb, p0, etc setup. - * - * slave is zero when mlreset is called for the master processor and - * is nonzero thereafter. - */ - - -void -mlreset(int slave) -{ - if (!slave) { - /* - * We are the master cpu and node. - */ - master_nasid = get_nasid(); - set_master_bridge_base(); - - /* We're the master processor */ - master_procid = smp_processor_id(); - master_nasid = cpuid_to_nasid(master_procid); - - /* - * master_nasid we get back better be same as one from - * get_nasid() - */ - ASSERT_ALWAYS(master_nasid == get_nasid()); - - /* early initialization of iograph */ - iograph_early_init(); - - /* Initialize Hub Pseudodriver Management */ - hubdev_init(); - - } else { /* slave != 0 */ - /* - * This code is performed ONLY by slave processors. - */ - - } -} - - -/* XXX - Move the meat of this to intr.c ? */ -/* - * Set up the platform-dependent fields in the nodepda. - */ -void init_platform_nodepda(nodepda_t *npda, cnodeid_t node) -{ - hubinfo_t hubinfo; - int sn; - - extern void router_map_init(nodepda_t *); - extern void router_queue_init(nodepda_t *,cnodeid_t); - extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int); - - /* Allocate per-node platform-dependent data */ - hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s)); - - npda->pdinfo = (void *)hubinfo; - hubinfo->h_nodepda = npda; - hubinfo->h_cnodeid = node; - hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node); - - spin_lock_init(&hubinfo->h_crblock); - - hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid); - npda->xbow_peer = INVALID_NASID; - - /* - * Initialize the linked list of - * router info pointers to the dependent routers - */ - npda->npda_rip_first = NULL; - - /* - * npda_rip_last always points to the place - * where the next element is to be inserted - * into the list - */ - npda->npda_rip_last = &npda->npda_rip_first; - npda->module_id = INVALID_MODULE; - - /* - * Initialize the interrupts. - * On sn2, this is done at pci init time, - * because sn2 needs the cpus checked in - * when it initializes interrupts. This is - * so we don't see all the nodes as headless. - */ - for (sn=0; snxbow_sema); /* init it locked? */ -} - -/* XXX - Move the interrupt stuff to intr.c ? */ -/* - * Set up the platform-dependent fields in the processor pda. - * Must be done _after_ init_platform_nodepda(). - * If we need a lock here, something else is wrong! - */ -void init_platform_pda(cpuid_t cpu) -{ - hub_intmasks_t *intmasks; - int i, subnode; - cnodeid_t cnode; - synergy_da_t *sda; - int which_synergy; - - - cnode = cpuid_to_cnodeid(cpu); - which_synergy = cpuid_to_synergy(cpu); - - sda = Synergy_da_indr[(cnode * 2) + which_synergy]; - intmasks = &sda->s_intmasks; - - /* Clear INT_PEND0 masks. */ - for (i = 0; i < N_INTPEND0_MASKS; i++) - intmasks->intpend0_masks[i] = 0; - - /* Set up pointer to the vector block in the nodepda. */ - /* (Cant use SUBNODEPDA - not working yet) */ - subnode = cpuid_to_subnode(cpu); - intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0; - intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1; - if (intmasks->dispatch0 != &SUBNODEPDA(cnode, subnode)->intr_dispatch0 || - intmasks->dispatch1 != &SUBNODEPDA(cnode, subnode)->intr_dispatch1) - panic("xxx"); - intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0; - intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1; - - /* Clear INT_PEND1 masks. */ - for (i = 0; i < N_INTPEND1_MASKS; i++) - intmasks->intpend1_masks[i] = 0; -} - -void -update_node_information(cnodeid_t cnodeid) -{ - nodepda_t *npda = NODEPDA(cnodeid); - nodepda_router_info_t *npda_rip; - - /* Go through the list of router info - * structures and copy some frequently - * accessed info from the info hanging - * off the corresponding router vertices - */ - npda_rip = npda->npda_rip_first; - while(npda_rip) { - if (npda_rip->router_infop) { - npda_rip->router_portmask = - npda_rip->router_infop->ri_portmask; - npda_rip->router_slot = - npda_rip->router_infop->ri_slotnum; - } else { - /* No router, no ports. */ - npda_rip->router_portmask = 0; - } - npda_rip = npda_rip->router_next; - } -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_intr.c linux-2.4.22/arch/ia64/sn/io/sn1/ml_SN_intr.c --- linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_intr.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/ml_SN_intr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1154 +0,0 @@ -/* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* - * intr.c- - * This file contains all of the routines necessary to set up and - * handle interrupts on an IP27 board. - */ - -#ident "$Revision: 1.1 $" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#if DEBUG_INTR_TSTAMP_DEBUG -#include -#include -#include -void do_splx_log(int, int); -void spldebug_log_event(int); -#endif - -#ifdef CONFIG_SMP -extern unsigned long cpu_online_map; -#endif -#define cpu_allows_intr(cpu) (1) -// If I understand what's going on with this, 32 should work. -// physmem_maxradius seems to be the maximum number of router -// hops to get from one end of the system to the other. With -// a maximally configured machine, with the dumbest possible -// topology, we would make 32 router hops. For what we're using -// it for, the dumbest possible should suffice. -#define physmem_maxradius() 32 - -#define SUBNODE_ANY (-1) - -extern int nmied; -extern int hub_intr_wakeup_cnt; -extern synergy_da_t *Synergy_da_indr[]; -extern cpuid_t master_procid; - -extern cnodeid_t master_node_get(devfs_handle_t vhdl); - -extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs); - - -#define INTR_LOCK(vecblk) \ - (s = mutex_spinlock(&(vecblk)->vector_lock)) -#define INTR_UNLOCK(vecblk) \ - mutex_spinunlock(&(vecblk)->vector_lock, s) - -/* - * REACT/Pro - */ - - - -/* - * Find first bit set - * Used outside this file also - */ -int ms1bit(unsigned long x) -{ - int b; - - if (x >> 32) b = 32, x >>= 32; - else b = 0; - if (x >> 16) b += 16, x >>= 16; - if (x >> 8) b += 8, x >>= 8; - if (x >> 4) b += 4, x >>= 4; - if (x >> 2) b += 2, x >>= 2; - - return b + (int) (x >> 1); -} - -/* ARGSUSED */ -void -intr_stray(void *lvl) -{ - printk(KERN_WARNING "Stray Interrupt - level %ld to cpu %d", (long)lvl, smp_processor_id()); -} - -#if defined(DEBUG) - -/* Infrastructure to gather the device - target cpu mapping info */ -#define MAX_DEVICES 1000 /* Reasonable large number . Need not be - * the exact maximum # devices possible. - */ -#define MAX_NAME 100 -typedef struct { - dev_t dev; /* device */ - cpuid_t cpuid; /* target cpu */ - cnodeid_t cnodeid;/* node on which the target cpu is present */ - int bit; /* intr bit reserved */ - char intr_name[MAX_NAME]; /* name of the interrupt */ -} intr_dev_targ_map_t; - -intr_dev_targ_map_t intr_dev_targ_map[MAX_DEVICES]; -uint64_t intr_dev_targ_map_size; -spinlock_t intr_dev_targ_map_lock; - -/* Print out the device - target cpu mapping. - * This routine is used only in the idbg command - * "intrmap" - */ -void -intr_dev_targ_map_print(cnodeid_t cnodeid) -{ - int i,j,size = 0; - int print_flag = 0,verbose = 0; - char node_name[10]; - - if (cnodeid != CNODEID_NONE) { - nodepda_t *npda; - - npda = NODEPDA(cnodeid); - for (j=0; jintr_dispatch0.info[i].ii_flags); - qprintf("\n INT_PEND1: "); - for(i = 0 ; i < N_INTPEND_BITS ; i++) - qprintf("%d",SNPDA(npda,j)->intr_dispatch1.info[i].ii_flags); - } - verbose = 1; - } - qprintf("\n Device - Target Map [Interrupts: %s Node%s]\n\n", - (verbose ? "All" : "Non-hardwired"), - (cnodeid == CNODEID_NONE) ? "s: All" : node_name); - - qprintf("Device\tCpu\tCnode\tIntr_bit\tIntr_name\n"); - for (i = 0 ; i < intr_dev_targ_map_size ; i++) { - - print_flag = 0; - if (verbose) { - if (cnodeid != CNODEID_NONE) { - if (cnodeid == intr_dev_targ_map[i].cnodeid) - print_flag = 1; - } else { - print_flag = 1; - } - } else { - if (intr_dev_targ_map[i].dev != 0) { - if (cnodeid != CNODEID_NONE) { - if (cnodeid == - intr_dev_targ_map[i].cnodeid) - print_flag = 1; - } else { - print_flag = 1; - } - } - } - if (print_flag) { - size++; - qprintf("%d\t%d\t%d\t%d\t%s\n", - intr_dev_targ_map[i].dev, - intr_dev_targ_map[i].cpuid, - intr_dev_targ_map[i].cnodeid, - intr_dev_targ_map[i].bit, - intr_dev_targ_map[i].intr_name); - } - - } - qprintf("\nTotal : %d\n",size); -} -#endif /* DEBUG */ - -/* - * The spinlocks have already been initialized. Now initialize the interrupt - * vectors. One processor on each hub does the work. - */ -void -intr_init_vecblk(nodepda_t *npda, cnodeid_t node, int sn) -{ - int i, ip=0; - intr_vecblk_t *vecblk; - subnode_pda_t *snpda; - - - snpda = SNPDA(npda,sn); - do { - if (ip == 0) { - vecblk = &snpda->intr_dispatch0; - } else { - vecblk = &snpda->intr_dispatch1; - } - - /* Initialize this vector. */ - for (i = 0; i < N_INTPEND_BITS; i++) { - vecblk->vectors[i].iv_func = intr_stray; - vecblk->vectors[i].iv_prefunc = NULL; - vecblk->vectors[i].iv_arg = (void *)(__psint_t)(ip * N_INTPEND_BITS + i); - - vecblk->info[i].ii_owner_dev = 0; - strcpy(vecblk->info[i].ii_name, "Unused"); - vecblk->info[i].ii_flags = 0; /* No flags */ - vecblk->vectors[i].iv_mustruncpu = -1; /* No CPU yet. */ - - } - - mutex_spinlock_init(&vecblk->vector_lock); - - vecblk->vector_count = 0; - for (i = 0; i < CPUS_PER_SUBNODE; i++) - vecblk->cpu_count[i] = 0; - - vecblk->vector_state = VECTOR_UNINITED; - - } while (++ip < 2); - -} - - -/* - * do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, - * devfs_handle_t owner_dev, char *name) - * Internal work routine to reserve or unreserve an interrupt level. - * cpu is the CPU to which the interrupt will be sent. - * bit is the level bit to reserve. -1 means any level - * resflags should include II_ERRORINT if this is an - * error interrupt, II_THREADED if the interrupt handler - * will be threaded, or 0 otherwise. - * reserve should be set to II_RESERVE or II_UNRESERVE - * to get or clear a reservation. - * owner_dev is the device that "owns" this interrupt, if supplied - * name is a human-readable name for this interrupt, if supplied - * intr_reserve_level returns the bit reserved or -1 to indicate an error - */ -static int -do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, - devfs_handle_t owner_dev, char *name) -{ - intr_vecblk_t *vecblk; - hub_intmasks_t *hub_intmasks; - unsigned long s; - int rv = 0; - int ip; - synergy_da_t *sda; - int which_synergy; - cnodeid_t cnode; - - ASSERT(bit < N_INTPEND_BITS * 2); - - cnode = cpuid_to_cnodeid(cpu); - which_synergy = cpuid_to_synergy(cpu); - sda = Synergy_da_indr[(cnode * 2) + which_synergy]; - hub_intmasks = &sda->s_intmasks; - // hub_intmasks = &pdaindr[cpu].pda->p_intmasks; - - // if (pdaindr[cpu].pda == NULL) return -1; - if ((bit < N_INTPEND_BITS) && !(resflags & II_ERRORINT)) { - vecblk = hub_intmasks->dispatch0; - ip = 0; - } else { - ASSERT((bit >= N_INTPEND_BITS) || (bit == -1)); - bit -= N_INTPEND_BITS; /* Get position relative to INT_PEND1 reg. */ - vecblk = hub_intmasks->dispatch1; - ip = 1; - } - - INTR_LOCK(vecblk); - - if (bit <= -1) { - bit = 0; - ASSERT(reserve == II_RESERVE); - /* Choose any available level */ - for (; bit < N_INTPEND_BITS; bit++) { - if (!(vecblk->info[bit].ii_flags & II_RESERVE)) { - rv = bit; - break; - } - } - - /* Return -1 if all interrupt levels int this register are taken. */ - if (bit == N_INTPEND_BITS) - rv = -1; - - } else { - /* Reserve a particular level if it's available. */ - if ((vecblk->info[bit].ii_flags & II_RESERVE) == reserve) { - /* Can't (un)reserve a level that's already (un)reserved. */ - rv = -1; - } else { - rv = bit; - } - } - - /* Reserve the level and bump the count. */ - if (rv != -1) { - if (reserve) { - int maxlen = sizeof(vecblk->info[bit].ii_name) - 1; - int namelen; - vecblk->info[bit].ii_flags |= (II_RESERVE | resflags); - vecblk->info[bit].ii_owner_dev = owner_dev; - /* Copy in the name. */ - namelen = name ? strlen(name) : 0; - strncpy(vecblk->info[bit].ii_name, name, min(namelen, maxlen)); - vecblk->info[bit].ii_name[maxlen] = '\0'; - vecblk->vector_count++; - } else { - vecblk->info[bit].ii_flags = 0; /* Clear all the flags */ - vecblk->info[bit].ii_owner_dev = 0; - /* Clear the name. */ - vecblk->info[bit].ii_name[0] = '\0'; - vecblk->vector_count--; - } - } - - INTR_UNLOCK(vecblk); - -#if defined(DEBUG) - if (rv >= 0) { - int namelen = name ? strlen(name) : 0; - /* Gather this device - target cpu mapping information - * in a table which can be used later by the idbg "intrmap" - * command - */ - s = mutex_spinlock(&intr_dev_targ_map_lock); - if (intr_dev_targ_map_size < MAX_DEVICES) { - intr_dev_targ_map_t *p; - - p = &intr_dev_targ_map[intr_dev_targ_map_size]; - p->dev = owner_dev; - p->cpuid = cpu; - p->cnodeid = cpuid_to_cnodeid(cpu); - p->bit = ip * N_INTPEND_BITS + rv; - strncpy(p->intr_name, - name, - min(MAX_NAME,namelen)); - intr_dev_targ_map_size++; - } - mutex_spinunlock(&intr_dev_targ_map_lock,s); - } -#endif /* DEBUG */ - - return (((rv == -1) ? rv : (ip * N_INTPEND_BITS) + rv)) ; -} - - -/* - * WARNING: This routine should only be called from within ml/SN. - * Reserve an interrupt level. - */ -int -intr_reserve_level(cpuid_t cpu, int bit, int resflags, devfs_handle_t owner_dev, char *name) -{ - return(do_intr_reserve_level(cpu, bit, resflags, II_RESERVE, owner_dev, name)); -} - - -/* - * WARNING: This routine should only be called from within ml/SN. - * Unreserve an interrupt level. - */ -void -intr_unreserve_level(cpuid_t cpu, int bit) -{ - (void)do_intr_reserve_level(cpu, bit, 0, II_UNRESERVE, 0, NULL); -} - -/* - * Get values that vary depending on which CPU and bit we're operating on - */ -static hub_intmasks_t * -intr_get_ptrs(cpuid_t cpu, int bit, - int *new_bit, /* Bit relative to the register */ - hubreg_t **intpend_masks, /* Masks for this register */ - intr_vecblk_t **vecblk, /* Vecblock for this interrupt */ - int *ip) /* Which intpend register */ -{ - hub_intmasks_t *hub_intmasks; - synergy_da_t *sda; - int which_synergy; - cnodeid_t cnode; - - ASSERT(bit < N_INTPEND_BITS * 2); - - cnode = cpuid_to_cnodeid(cpu); - which_synergy = cpuid_to_synergy(cpu); - sda = Synergy_da_indr[(cnode * 2) + which_synergy]; - hub_intmasks = &sda->s_intmasks; - - // hub_intmasks = &pdaindr[cpu].pda->p_intmasks; - - if (bit < N_INTPEND_BITS) { - *intpend_masks = hub_intmasks->intpend0_masks; - *vecblk = hub_intmasks->dispatch0; - *ip = 0; - *new_bit = bit; - } else { - *intpend_masks = hub_intmasks->intpend1_masks; - *vecblk = hub_intmasks->dispatch1; - *ip = 1; - *new_bit = bit - N_INTPEND_BITS; - } - - return hub_intmasks; -} - - -/* - * intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, - * intr_func_t intr_func, void *intr_arg); - * This is the lowest-level interface to the interrupt code. It shouldn't - * be called from outside the ml/SN directory. - * intr_connect_level hooks up an interrupt to a particular bit in - * the INT_PEND0/1 masks. Returns 0 on success. - * cpu is the CPU to which the interrupt will be sent. - * bit is the level bit to connect to - * intr_swlevel tells which software level to use - * intr_func is the interrupt handler - * intr_arg is an arbitrary argument interpreted by the handler - * intr_prefunc is a prologue function, to be called - * with interrupts disabled, to disable - * the interrupt at source. It is called - * with the same argument. Should be NULL for - * typical interrupts, which can be masked - * by the infrastructure at the level bit. - * intr_connect_level returns 0 on success or nonzero on an error - */ -/* ARGSUSED */ -int -intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, intr_func_t intr_prefunc) -{ - intr_vecblk_t *vecblk; - hubreg_t *intpend_masks; - int rv = 0; - int ip; - unsigned long s; - - ASSERT(bit < N_INTPEND_BITS * 2); - - (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, - &vecblk, &ip); - - INTR_LOCK(vecblk); - - if ((vecblk->info[bit].ii_flags & II_INUSE) || - (!(vecblk->info[bit].ii_flags & II_RESERVE))) { - /* Can't assign to a level that's in use or isn't reserved. */ - rv = -1; - } else { - /* Stuff parameters into vector and info */ - vecblk->vectors[bit].iv_prefunc = intr_prefunc; - vecblk->info[bit].ii_flags |= II_INUSE; - } - - /* Now stuff the masks if everything's okay. */ - if (!rv) { - int lslice; - volatile hubreg_t *mask_reg; - // nasid_t nasid = COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)); - nasid_t nasid = cpuid_to_nasid(cpu); - int subnode = cpuid_to_subnode(cpu); - - /* Make sure it's not already pending when we connect it. */ - REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit + ip * N_INTPEND_BITS); - - if (bit >= GFX_INTR_A && bit <= CC_PEND_B) { - intpend_masks[0] |= (1ULL << (uint64_t)bit); - } - - lslice = cpuid_to_localslice(cpu); - vecblk->cpu_count[lslice]++; -#if SN1 - /* - * On SN1, there are 8 interrupt mask registers per node: - * PI_0 MASK_0 A - * PI_0 MASK_1 A - * PI_0 MASK_0 B - * PI_0 MASK_1 B - * PI_1 MASK_0 A - * PI_1 MASK_1 A - * PI_1 MASK_0 B - * PI_1 MASK_1 B - */ -#endif - if (ip == 0) { - mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, - PI_INT_MASK0_A + PI_INT_MASK_OFFSET * lslice); - } else { - mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, - PI_INT_MASK1_A + PI_INT_MASK_OFFSET * lslice); - } - - HUB_S(mask_reg, intpend_masks[0]); - } - - INTR_UNLOCK(vecblk); - - return rv; -} - - -/* - * intr_disconnect_level(cpuid_t cpu, int bit) - * - * This is the lowest-level interface to the interrupt code. It should - * not be called from outside the ml/SN directory. - * intr_disconnect_level removes a particular bit from an interrupt in - * the INT_PEND0/1 masks. Returns 0 on success or nonzero on failure. - */ -int -intr_disconnect_level(cpuid_t cpu, int bit) -{ - intr_vecblk_t *vecblk; - hubreg_t *intpend_masks; - unsigned long s; - int rv = 0; - int ip; - - (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, - &vecblk, &ip); - - INTR_LOCK(vecblk); - - if ((vecblk->info[bit].ii_flags & (II_RESERVE | II_INUSE)) != - ((II_RESERVE | II_INUSE))) { - /* Can't remove a level that's not in use or isn't reserved. */ - rv = -1; - } else { - /* Stuff parameters into vector and info */ - vecblk->vectors[bit].iv_func = (intr_func_t)NULL; - vecblk->vectors[bit].iv_prefunc = (intr_func_t)NULL; - vecblk->vectors[bit].iv_arg = 0; - vecblk->info[bit].ii_flags &= ~II_INUSE; -#ifdef BASE_ITHRTEAD - vecblk->vectors[bit].iv_mustruncpu = -1; /* No mustrun CPU any more. */ -#endif - } - - /* Now clear the masks if everything's okay. */ - if (!rv) { - int lslice; - volatile hubreg_t *mask_reg; - - intpend_masks[0] &= ~(1ULL << (uint64_t)bit); - lslice = cpuid_to_localslice(cpu); - vecblk->cpu_count[lslice]--; - mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), - cpuid_to_subnode(cpu), - ip == 0 ? PI_INT_MASK0_A : PI_INT_MASK1_A); - mask_reg = (volatile hubreg_t *)((__psunsigned_t)mask_reg + - (PI_INT_MASK_OFFSET * lslice)); - *mask_reg = intpend_masks[0]; - } - - INTR_UNLOCK(vecblk); - - return rv; -} - -/* - * Actually block or unblock an interrupt - */ -void -do_intr_block_bit(cpuid_t cpu, int bit, int block) -{ - intr_vecblk_t *vecblk; - int ip; - unsigned long s; - hubreg_t *intpend_masks; - volatile hubreg_t mask_value; - volatile hubreg_t *mask_reg; - - intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &vecblk, &ip); - - INTR_LOCK(vecblk); - - if (block) - /* Block */ - intpend_masks[0] &= ~(1ULL << (uint64_t)bit); - else - /* Unblock */ - intpend_masks[0] |= (1ULL << (uint64_t)bit); - - if (ip == 0) { - mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), - cpuid_to_subnode(cpu), PI_INT_MASK0_A); - } else { - mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), - cpuid_to_subnode(cpu), PI_INT_MASK1_A); - } - - HUB_S(mask_reg, intpend_masks[0]); - - /* - * Wait for it to take effect. (One read should suffice.) - * This is only necessary when blocking an interrupt - */ - if (block) - while ((mask_value = HUB_L(mask_reg)) != intpend_masks[0]) - ; - - INTR_UNLOCK(vecblk); -} - - -/* - * Block a particular interrupt (cpu/bit pair). - */ -/* ARGSUSED */ -void -intr_block_bit(cpuid_t cpu, int bit) -{ - do_intr_block_bit(cpu, bit, 1); -} - - -/* - * Unblock a particular interrupt (cpu/bit pair). - */ -/* ARGSUSED */ -void -intr_unblock_bit(cpuid_t cpu, int bit) -{ - do_intr_block_bit(cpu, bit, 0); -} - - -/* verifies that the specified CPUID is on the specified SUBNODE (if any) */ -#define cpu_on_subnode(cpuid, which_subnode) \ - (((which_subnode) == SUBNODE_ANY) || (cpuid_to_subnode(cpuid) == (which_subnode))) - - -/* - * Choose one of the CPUs on a specified node or subnode to receive - * interrupts. Don't pick a cpu which has been specified as a NOINTR cpu. - * - * Among all acceptable CPUs, the CPU that has the fewest total number - * of interrupts targetted towards it is chosen. Note that we never - * consider how frequent each of these interrupts might occur, so a rare - * hardware error interrupt is weighted equally with a disk interrupt. - */ -static cpuid_t -do_intr_cpu_choose(cnodeid_t cnode, int which_subnode) -{ - cpuid_t cpu, best_cpu = CPU_NONE; - int slice, min_count=1000; - - min_count = 1000; - for (slice=0; slice < CPUS_PER_NODE; slice++) { - intr_vecblk_t *vecblk0, *vecblk1; - int total_intrs_to_slice; - subnode_pda_t *snpda; - int local_cpu_num; - - cpu = cnode_slice_to_cpuid(cnode, slice); - if (cpu == CPU_NONE) - continue; - - /* If this cpu isn't enabled for interrupts, skip it */ - if (!cpu_enabled(cpu) || !cpu_allows_intr(cpu)) - continue; - - /* If this isn't the right subnode, skip it */ - if (!cpu_on_subnode(cpu, which_subnode)) - continue; - - /* OK, this one's a potential CPU for interrupts */ - snpda = SUBNODEPDA(cnode,SUBNODE(slice)); - vecblk0 = &snpda->intr_dispatch0; - vecblk1 = &snpda->intr_dispatch1; - local_cpu_num = LOCALCPU(slice); - total_intrs_to_slice = vecblk0->cpu_count[local_cpu_num] + - vecblk1->cpu_count[local_cpu_num]; - - if (min_count > total_intrs_to_slice) { - min_count = total_intrs_to_slice; - best_cpu = cpu; - } - } - return best_cpu; -} - -/* - * Choose an appropriate interrupt target CPU on a specified node. - * If which_subnode is SUBNODE_ANY, then subnode is not considered. - * Otherwise, the chosen CPU must be on the specified subnode. - */ -static cpuid_t -intr_cpu_choose_from_node(cnodeid_t cnode, int which_subnode) -{ - return(do_intr_cpu_choose(cnode, which_subnode)); -} - - -/* Make it easy to identify subnode vertices in the hwgraph */ -void -mark_subnodevertex_as_subnode(devfs_handle_t vhdl, int which_subnode) -{ - graph_error_t rv; - - ASSERT(0 <= which_subnode); - ASSERT(which_subnode < NUM_SUBNODES); - - rv = hwgraph_info_add_LBL(vhdl, INFO_LBL_CPUBUS, (arbitrary_info_t)which_subnode); - ASSERT_ALWAYS(rv == GRAPH_SUCCESS); - - rv = hwgraph_info_export_LBL(vhdl, INFO_LBL_CPUBUS, sizeof(arbitrary_info_t)); - ASSERT_ALWAYS(rv == GRAPH_SUCCESS); -} - - -/* - * Given a device descriptor, extract interrupt target information and - * choose an appropriate CPU. Return CPU_NONE if we can't make sense - * out of the target information. - * TBD: Should this be considered platform-independent code? - */ - - -/* - * intr_bit_reserve_test(cpuid,which_subnode,cnode,req_bit,intr_resflags, - * owner_dev,intr_name,*resp_bit) - * Either cpuid is not CPU_NONE or cnodeid not CNODE_NONE but - * not both. - * 1. If cpuid is specified, this routine tests if this cpu can be a valid - * interrupt target candidate. - * 2. If cnodeid is specified, this routine tests if there is a cpu on - * this node which can be a valid interrupt target candidate. - * 3. If a valid interrupt target cpu candidate is found then an attempt at - * reserving an interrupt bit on the corresponding cnode is made. - * - * If steps 1 & 2 both fail or step 3 fails then we are not able to get a valid - * interrupt target cpu then routine returns CPU_NONE (failure) - * Otherwise routine returns cpuid of interrupt target (success) - */ -static cpuid_t -intr_bit_reserve_test(cpuid_t cpuid, - int favor_subnode, - cnodeid_t cnodeid, - int req_bit, - int intr_resflags, - devfs_handle_t owner_dev, - char *intr_name, - int *resp_bit) -{ - - ASSERT((cpuid==CPU_NONE) || (cnodeid==CNODEID_NONE)); - - if (cnodeid != CNODEID_NONE) { - /* Try to choose a interrupt cpu candidate */ - cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode); - } - - if (cpuid != CPU_NONE) { - /* Try to reserve an interrupt bit on the hub - * corresponding to the canidate cnode. If we - * are successful then we got a cpu which can - * act as an interrupt target for the io device. - * Otherwise we need to continue the search - * further. - */ - *resp_bit = do_intr_reserve_level(cpuid, - req_bit, - intr_resflags, - II_RESERVE, - owner_dev, - intr_name); - - if (*resp_bit >= 0) - /* The interrupt target specified was fine */ - return(cpuid); - } - return(CPU_NONE); -} -/* - * intr_heuristic(dev_t dev,device_desc_t dev_desc, - * int req_bit,int intr_resflags,dev_t owner_dev, - * char *intr_name,int *resp_bit) - * - * Choose an interrupt destination for an interrupt. - * dev is the device for which the interrupt is being set up - * dev_desc is a description of hardware and policy that could - * help determine where this interrupt should go - * req_bit is the interrupt bit requested - * (can be INTRCONNECT_ANY_BIT in which the first available - * interrupt bit is used) - * intr_resflags indicates whether we want to (un)reserve bit - * owner_dev is the owner device - * intr_name is the readable interrupt name - * resp_bit indicates whether we succeeded in getting the required - * action { (un)reservation} done - * negative value indicates failure - * - */ -/* ARGSUSED */ -cpuid_t -intr_heuristic(devfs_handle_t dev, - device_desc_t dev_desc, - int req_bit, - int intr_resflags, - devfs_handle_t owner_dev, - char *intr_name, - int *resp_bit) -{ - cpuid_t cpuid; /* possible intr targ*/ - cnodeid_t candidate; /* possible canidate */ - int which_subnode = SUBNODE_ANY; - -/* SN1 + pcibr Addressing Limitation */ - { - devfs_handle_t pconn_vhdl; - pcibr_soft_t pcibr_soft; - - /* - * This combination of SN1 and Bridge hardware has an odd "limitation". - * Due to the choice of addresses for PI0 and PI1 registers on SN1 - * and historical limitations in Bridge, Bridge is unable to - * send interrupts to both PI0 CPUs and PI1 CPUs -- we have - * to choose one set or the other. That choice is implicitly - * made when Bridge first attaches its error interrupt. After - * that point, all subsequent interrupts are restricted to the - * same PI number (though it's possible to send interrupts to - * the same PI number on a different node). - * - * Since neither SN1 nor Bridge designers are willing to admit a - * bug, we can't really call this a "workaround". It's a permanent - * solution for an SN1-specific and Bridge-specific hardware - * limitation that won't ever be lifted. - */ - if ((hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) && - ((pcibr_soft = pcibr_soft_get(pconn_vhdl)) != NULL)) { - /* - * We "know" that the error interrupt is the first - * interrupt set up by pcibr_attach. Send all interrupts - * on this bridge to the same subnode number. - */ - if (pcibr_soft->bsi_err_intr) { - which_subnode = cpuid_to_subnode(((hub_intr_t) pcibr_soft->bsi_err_intr)->i_cpuid); - } - } - } - - /* Check if we can find a valid interrupt target candidate on - * the master node for the device. - */ - cpuid = intr_bit_reserve_test(CPU_NONE, - which_subnode, - master_node_get(dev), - req_bit, - intr_resflags, - owner_dev, - intr_name, - resp_bit); - - if (cpuid != CPU_NONE) { - if (cpu_on_subnode(cpuid, which_subnode)) - return(cpuid); /* got a valid interrupt target */ - else - intr_unreserve_level(cpuid, *resp_bit); - } - - printk(KERN_WARNING "Cannot target interrupts to closest node(%d): (0x%lx)\n", - master_node_get(dev),(unsigned long)owner_dev); - - /* Fall through into the default algorithm - * (exhaustive-search-for-the-nearest-possible-interrupt-target) - * for finding the interrupt target - */ - - { - /* - * Do a stupid round-robin assignment of the node. - * (Should do a "nearest neighbor" but not for SN1. - */ - static cnodeid_t last_node = -1; - - if (last_node >= numnodes) last_node = 0; - for (candidate = last_node + 1; candidate != last_node; candidate++) { - if (candidate == numnodes) candidate = 0; - cpuid = intr_bit_reserve_test(CPU_NONE, - which_subnode, - candidate, - req_bit, - intr_resflags, - owner_dev, - intr_name, - resp_bit); - - if (cpuid != CPU_NONE) { - if (cpu_on_subnode(cpuid, which_subnode)) { - last_node = candidate; - return(cpuid); /* got a valid interrupt target */ - } - else - intr_unreserve_level(cpuid, *resp_bit); - } - } - last_node = candidate; - } - - printk(KERN_WARNING "Cannot target interrupts to any close node: %ld (0x%lx)\n", - (long)owner_dev, (unsigned long)owner_dev); - - /* In the worst case try to allocate interrupt bits on the - * master processor's node. We may get here during error interrupt - * allocation phase when the topology matrix is not yet setup - * and hence cannot do an exhaustive search. - */ - ASSERT(cpu_allows_intr(master_procid)); - cpuid = intr_bit_reserve_test(master_procid, - which_subnode, - CNODEID_NONE, - req_bit, - intr_resflags, - owner_dev, - intr_name, - resp_bit); - - if (cpuid != CPU_NONE) { - if (cpu_on_subnode(cpuid, which_subnode)) - return(cpuid); - else - intr_unreserve_level(cpuid, *resp_bit); - } - - printk(KERN_WARNING "Cannot target interrupts: (0x%lx)\n", - (unsigned long)owner_dev); - - return(CPU_NONE); /* Should never get here */ -} - -struct hardwired_intr_s { - signed char level; - int flags; - char *name; -} const hardwired_intr[] = { - { INT_PEND0_BASELVL + RESERVED_INTR, 0, "Reserved" }, - { INT_PEND0_BASELVL + GFX_INTR_A, 0, "Gfx A" }, - { INT_PEND0_BASELVL + GFX_INTR_B, 0, "Gfx B" }, - { INT_PEND0_BASELVL + PG_MIG_INTR, II_THREADED, "Migration" }, - { INT_PEND0_BASELVL + UART_INTR, II_THREADED, "Bedrock/L1" }, - { INT_PEND0_BASELVL + CC_PEND_A, 0, "Crosscall A" }, - { INT_PEND0_BASELVL + CC_PEND_B, 0, "Crosscall B" }, - { INT_PEND1_BASELVL + CLK_ERR_INTR, II_ERRORINT, "Clock Error" }, - { INT_PEND1_BASELVL + COR_ERR_INTR_A, II_ERRORINT, "Correctable Error A" }, - { INT_PEND1_BASELVL + COR_ERR_INTR_B, II_ERRORINT, "Correctable Error B" }, - { INT_PEND1_BASELVL + MD_COR_ERR_INTR, II_ERRORINT, "MD Correct. Error" }, - { INT_PEND1_BASELVL + NI_ERROR_INTR, II_ERRORINT, "NI Error" }, - { INT_PEND1_BASELVL + NI_BRDCAST_ERR_A, II_ERRORINT, "Remote NI Error"}, - { INT_PEND1_BASELVL + NI_BRDCAST_ERR_B, II_ERRORINT, "Remote NI Error"}, - { INT_PEND1_BASELVL + MSC_PANIC_INTR, II_ERRORINT, "MSC Panic" }, - { INT_PEND1_BASELVL + LLP_PFAIL_INTR_A, II_ERRORINT, "LLP Pfail WAR" }, - { INT_PEND1_BASELVL + LLP_PFAIL_INTR_B, II_ERRORINT, "LLP Pfail WAR" }, - { INT_PEND1_BASELVL + NACK_INT_A, 0, "CPU A Nack count == NACK_CMP" }, - { INT_PEND1_BASELVL + NACK_INT_B, 0, "CPU B Nack count == NACK_CMP" }, - { INT_PEND1_BASELVL + LB_ERROR, 0, "Local Block Error" }, - { INT_PEND1_BASELVL + XB_ERROR, 0, "Local XBar Error" }, - { -1, 0, (char *)NULL}, -}; - -/* - * Reserve all of the hardwired interrupt levels so they're not used as - * general purpose bits later. - */ -void -intr_reserve_hardwired(cnodeid_t cnode) -{ - cpuid_t cpu; - int level; - int i; - char subnode_done[NUM_SUBNODES]; - - // cpu = cnodetocpu(cnode); - for (cpu = 0; cpu < smp_num_cpus; cpu++) { - if (cpuid_to_cnodeid(cpu) == cnode) { - break; - } - } - if (cpu == smp_num_cpus) cpu = CPU_NONE; - if (cpu == CPU_NONE) { - printk("Node %d has no CPUs", cnode); - return; - } - - for (i=0; iii_name, - vector->iv_func, vector->iv_arg, vector->iv_prefunc); - pf(" vertex 0x%x %s%s", - info->ii_owner_dev, - ((info->ii_flags) & II_RESERVE) ? "R" : "U", - ((info->ii_flags) & II_INUSE) ? "C" : "-"); - pf("%s%s%s%s", - ip & value ? "P" : "-", - ima & value ? "A" : "-", - imb & value ? "B" : "-", - ((info->ii_flags) & II_ERRORINT) ? "E" : "-"); - pf("\n"); -} - - -/* - * Dump information about interrupt vector assignment. - */ -void -intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...)) -{ - nodepda_t *npda; - int ip, sn, bit; - intr_vecblk_t *dispatch; - hubreg_t ipr, ima, imb; - nasid_t nasid; - - if ((cnode < 0) || (cnode >= numnodes)) { - pf("intr_dumpvec: cnodeid out of range: %d\n", cnode); - return ; - } - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - if (nasid == INVALID_NASID) { - pf("intr_dumpvec: Bad cnodeid: %d\n", cnode); - return ; - } - - - npda = NODEPDA(cnode); - - for (sn = 0; sn < NUM_SUBNODES; sn++) { - for (ip = 0; ip < 2; ip++) { - dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0); - ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0); - ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A); - imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B); - - pf("Node %d INT_PEND%d:\n", cnode, ip); - - if (dispatch->ithreads_enabled) - pf(" Ithreads enabled\n"); - else - pf(" Ithreads disabled\n"); - pf(" vector_count = %d, vector_state = %d\n", - dispatch->vector_count, - dispatch->vector_state); - pf(" CPU A count %d, CPU B count %d\n", - dispatch->cpu_count[0], - dispatch->cpu_count[1]); - pf(" &vector_lock = 0x%x\n", - &(dispatch->vector_lock)); - for (bit = 0; bit < N_INTPEND_BITS; bit++) { - if ((dispatch->info[bit].ii_flags & II_RESERVE) || - (ipr & (1L << bit))) { - dump_vector(&(dispatch->info[bit]), - &(dispatch->vectors[bit]), - bit, ipr, ima, imb, pf); - } - } - pf("\n"); - } - } -} - diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/ml_iograph.c linux-2.4.22/arch/ia64/sn/io/sn1/ml_iograph.c --- linux-2.4.21/arch/ia64/sn/io/sn1/ml_iograph.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/ml_iograph.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1505 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define IOGRAPH_DEBUG */ -#ifdef IOGRAPH_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* IOGRAPH_DEBUG */ - -/* #define PROBE_TEST */ - -/* At most 2 hubs can be connected to an xswitch */ -#define NUM_XSWITCH_VOLUNTEER 2 - -/* - * Track which hubs have volunteered to manage devices hanging off of - * a Crosstalk Switch (e.g. xbow). This structure is allocated, - * initialized, and hung off the xswitch vertex early on when the - * xswitch vertex is created. - */ -typedef struct xswitch_vol_s { - mutex_t xswitch_volunteer_mutex; - int xswitch_volunteer_count; - devfs_handle_t xswitch_volunteer[NUM_XSWITCH_VOLUNTEER]; -} *xswitch_vol_t; - -void -xswitch_vertex_init(devfs_handle_t xswitch) -{ - xswitch_vol_t xvolinfo; - int rc; - - xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL); - mutex_init(&xvolinfo->xswitch_volunteer_mutex); - xvolinfo->xswitch_volunteer_count = 0; - rc = hwgraph_info_add_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t)xvolinfo); - ASSERT(rc == GRAPH_SUCCESS); rc = rc; -} - - -/* - * When assignment of hubs to widgets is complete, we no longer need the - * xswitch volunteer structure hanging around. Destroy it. - */ -static void -xswitch_volunteer_delete(devfs_handle_t xswitch) -{ - xswitch_vol_t xvolinfo; - int rc; - - rc = hwgraph_info_remove_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t *)&xvolinfo); - kfree(xvolinfo); -} -/* - * A Crosstalk master volunteers to manage xwidgets on the specified xswitch. - */ -/* ARGSUSED */ -static void -volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master) -{ - xswitch_vol_t xvolinfo = NULL; - devfs_handle_t hubv; - hubinfo_t hubinfo; - - (void)hwgraph_info_get_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t *)&xvolinfo); - if (xvolinfo == NULL) { - return; - } - - mutex_lock(&xvolinfo->xswitch_volunteer_mutex); - ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER); - xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master; - xvolinfo->xswitch_volunteer_count++; - - /* - * if dual ported, make the lowest widgetid always be - * xswitch_volunteer[0]. - */ - if (xvolinfo->xswitch_volunteer_count == NUM_XSWITCH_VOLUNTEER) { - hubv = xvolinfo->xswitch_volunteer[0]; - hubinfo_get(hubv, &hubinfo); - if (hubinfo->h_widgetid != XBOW_HUBLINK_LOW) { - xvolinfo->xswitch_volunteer[0] = - xvolinfo->xswitch_volunteer[1]; - xvolinfo->xswitch_volunteer[1] = hubv; - } - } - mutex_unlock(&xvolinfo->xswitch_volunteer_mutex); -} - -extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum); - -/* - * Assign all the xwidgets hanging off the specified xswitch to the - * Crosstalk masters that have volunteered for xswitch duty. - */ -/* ARGSUSED */ -static void -assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv) -{ - xswitch_info_t xswitch_info; - xswitch_vol_t xvolinfo = NULL; - xwidgetnum_t widgetnum; - int num_volunteer; - nasid_t nasid; - hubinfo_t hubinfo; - extern int iobrick_type_get_nasid(nasid_t); - - - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - - xswitch_info = xswitch_info_get(xswitch); - ASSERT(xswitch_info != NULL); - - (void)hwgraph_info_get_LBL(xswitch, - INFO_LBL_XSWITCH_VOL, - (arbitrary_info_t *)&xvolinfo); - if (xvolinfo == NULL) { - return; - } - - num_volunteer = xvolinfo->xswitch_volunteer_count; - ASSERT(num_volunteer > 0); - - /* Assign master hub for xswitch itself. */ - if (HUB_WIDGET_ID_MIN > 0) { - hubv = xvolinfo->xswitch_volunteer[0]; - xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv); - } - - /* - * TBD: Use administrative information to alter assignment of - * widgets to hubs. - */ - for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { - int i; - - /* - * Ignore disabled/empty ports. - */ - if (!xbow_port_io_enabled(nasid, widgetnum)) - continue; - - /* - * If this is the master IO board, assign it to the same - * hub that owned it in the prom. - */ - if (is_master_nasid_widget(nasid, widgetnum)) { - for (i=0; ixswitch_volunteer[i]; - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - if (nasid == get_console_nasid()) - goto do_assignment; - } - } - - /* - * Assuming that we're dual-hosted and that PCI cards - * are naturally placed left-to-right, alternate PCI - * buses across both Cbricks. For Pbricks, and Ibricks, - * io_brick_map_widget() returns the PCI bus number - * associated with the given brick type and widget number. - * For Xbricks, it returns the XIO slot number. - */ - - i = 0; - if (num_volunteer > 1) { - int bt; - - bt = iobrick_type_get_nasid(nasid); - if (bt >= 0) { - /* - * PXBRICK has two busses per widget so this - * algorithm wouldn't work (all busses would - * be assigned to one volunteer). Change the - * bricktype to PBRICK whose mapping is setup - * suchthat 2 of the PICs will be assigned to - * one volunteer and the other one will be - * assigned to the other volunteer. - */ - if (bt == MODULE_PXBRICK) - bt = MODULE_PBRICK; - - i = io_brick_map_widget(bt, widgetnum) & 1; - } - } - - hubv = xvolinfo->xswitch_volunteer[i]; - -do_assignment: - /* - * At this point, we want to make hubv the master of widgetnum. - */ - xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv); - } - - xswitch_volunteer_delete(xswitch); -} - -/* - * Early iograph initialization. Called by master CPU in mlreset(). - * Useful for including iograph.o in kernel.o. - */ -void -iograph_early_init(void) -{ -/* - * Need new way to get this information .. - */ - cnodeid_t cnode; - nasid_t nasid; - lboard_t *board; - - /* - * Init. the board-to-hwgraph link early, so FRU analyzer - * doesn't trip on leftover values if we panic early on. - */ - for(cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - board = (lboard_t *)KL_CONFIG_INFO(nasid); - DBG("iograph_early_init: Found board 0x%p\n", board); - - /* Check out all the board info stored on a node */ - while(board) { - board->brd_graph_link = GRAPH_VERTEX_NONE; - board = KLCF_NEXT(board); - DBG("iograph_early_init: Found board 0x%p\n", board); - } - } - - hubio_init(); -} - -/* - * Let boot processor know that we're done initializing our node's IO - * and then exit. - */ -/* ARGSUSED */ -static void -io_init_done(cnodeid_t cnodeid,cpu_cookie_t c) -{ - /* Let boot processor know that we're done. */ -} - -/* - * Probe to see if this hub's xtalk link is active. If so, - * return the Crosstalk Identification of the widget that we talk to. - * This is called before any of the Crosstalk infrastructure for - * this hub is set up. It's usually called on the node that we're - * probing, but not always. - * - * TBD: Prom code should actually do this work, and pass through - * hwid for our use. - */ -static void -early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid) -{ - hubreg_t llp_csr_reg; - nasid_t nasid; - hubinfo_t hubinfo; - - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - - llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); - /* - * If link is up, read the widget's part number. - * A direct connect widget must respond to widgetnum=0. - */ - if (llp_csr_reg & IIO_LLP_CSR_IS_UP) { - /* TBD: Put hub into "indirect" mode */ - /* - * We're able to read from a widget because our hub's - * WIDGET_ID was set up earlier. - */ - widgetreg_t widget_id = *(volatile widgetreg_t *) - (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); - - DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id, - (volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) ); - - hwid->part_num = XWIDGET_PART_NUM(widget_id); - hwid->rev_num = XWIDGET_REV_NUM(widget_id); - hwid->mfg_num = XWIDGET_MFG_NUM(widget_id); - - /* TBD: link reset */ - } else { - - hwid->part_num = XWIDGET_PART_NUM_NONE; - hwid->rev_num = XWIDGET_REV_NUM_NONE; - hwid->mfg_num = XWIDGET_MFG_NUM_NONE; - } -} - -/* Add inventory information to the widget vertex - * Right now (module,slot,revision) is being - * added as inventory information. - */ -static void -xwidget_inventory_add(devfs_handle_t widgetv, - lboard_t *board, - struct xwidget_hwid_s hwid) -{ - if (!board) - return; - /* Donot add inventory information for the baseio - * on a speedo with an xbox. It has already been - * taken care of in SN00_vmc. - * Speedo with xbox's baseio comes in at slot io1 (widget 9) - */ - device_inventory_add(widgetv,INV_IOBD,board->brd_type, - board->brd_module, - SLOTNUM_GETSLOT(board->brd_slot), - hwid.rev_num); -} - -/* - * io_xswitch_widget_init - * - */ - -void -io_xswitch_widget_init(devfs_handle_t xswitchv, - devfs_handle_t hubv, - xwidgetnum_t widgetnum, - async_attach_t aa) -{ - xswitch_info_t xswitch_info; - xwidgetnum_t hub_widgetid; - devfs_handle_t widgetv; - cnodeid_t cnode; - widgetreg_t widget_id; - nasid_t nasid, peer_nasid; - struct xwidget_hwid_s hwid; - hubinfo_t hubinfo; - /*REFERENCED*/ - int rc; - char pathname[128]; - char new_name[64]; - moduleid_t module; - slotid_t slot; - lboard_t *board = NULL; - char buffer[16]; - slotid_t get_widget_slotnum(int xbow, int widget); - - DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum); - - /* - * Verify that xswitchv is indeed an attached xswitch. - */ - xswitch_info = xswitch_info_get(xswitchv); - ASSERT(xswitch_info != NULL); - - hubinfo_get(hubv, &hubinfo); - nasid = hubinfo->h_nasid; - cnode = NASID_TO_COMPACT_NODEID(nasid); - hub_widgetid = hubinfo->h_widgetid; - - /* - * Check that the widget is an io widget and is enabled - * on this nasid or the `peer' nasid. The peer nasid - * is the other hub/bedrock connected to the xbow. - */ - peer_nasid = NODEPDA(cnode)->xbow_peer; - if (peer_nasid == INVALID_NASID) - /* If I don't have a peer, use myself. */ - peer_nasid = nasid; - if (!xbow_port_io_enabled(nasid, widgetnum) && - !xbow_port_io_enabled(peer_nasid, widgetnum)) { - return; - } - - if (xswitch_info_link_ok(xswitch_info, widgetnum)) { - char name[4]; - - /* - * If the current hub is not supposed to be the master - * for this widgetnum, then skip this widget. - */ - if (xswitch_info_master_assignment_get(xswitch_info, - widgetnum) != hubv) { - return; - } - - module = NODEPDA(cnode)->module_id; -#ifdef XBRIDGE_REGS_SIM - /* hardwire for now...could do this with something like: - * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl); - * xbow_t xbow = soft->base; - * xbowreg_t xwidget_id = xbow->xb_wid_id; - * but I don't feel like figuring out vhdl right now.. - * and I know for a fact the answer is 0x2d000049 - */ - DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); - DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049)); - if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) -#else - if (nasid_has_xbridge(nasid)) -#endif /* XBRIDGE_REGS_SIM */ - { - board = find_lboard_module_class( - (lboard_t *)KL_CONFIG_INFO(nasid), - module, - KLTYPE_IOBRICK); - -DBG("io_xswitch_widget_init: Board 0x%p\n", board); -{ - lboard_t dummy; - - - if (board) { - DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type); - } else { - DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n"); - board = &dummy; - } - -} - - /* - * Make sure we really want to say xbrick, pbrick, - * etc. rather than XIO, graphics, etc. - */ - -#ifdef SUPPORT_PRINTING_M_FORMAT - sprintf(pathname, EDGE_LBL_MODULE "/%M/" - "%cbrick" "/%s/%d", - NODEPDA(cnode)->module_id, - -#else - memset(buffer, 0, 16); - format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); - sprintf(pathname, EDGE_LBL_MODULE "/%s/" - "%cbrick" "/%s/%d", - buffer, -#endif - - (board->brd_type == KLTYPE_IBRICK) ? 'I' : - (board->brd_type == KLTYPE_PBRICK) ? 'P' : - (board->brd_type == KLTYPE_XBRICK) ? 'X' : '?', - EDGE_LBL_XTALK, widgetnum); - } - - DBG("io_xswitch_widget_init: path= %s\n", pathname); - rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); - - ASSERT(rc == GRAPH_SUCCESS); - - /* This is needed to let the user programs to map the - * module,slot numbers to the corresponding widget numbers - * on the crossbow. - */ - rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); - - /* If we are looking at the global master io6 - * then add information about the version of - * the io6prom as a part of "detailed inventory" - * information. - */ - if (is_master_baseio(nasid, - NODEPDA(cnode)->module_id, - get_widget_slotnum(0,widgetnum))) { - extern void klhwg_baseio_inventory_add(devfs_handle_t, - cnodeid_t); - module = NODEPDA(cnode)->module_id; - -#ifdef XBRIDGE_REGS_SIM - DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); - if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) -#else - if (nasid_has_xbridge(nasid)) -#endif /* XBRIDGE_REGS_SIM */ - { - board = find_lboard_module( - (lboard_t *)KL_CONFIG_INFO(nasid), - module); - /* - * Change iobrick to correct i/o brick - */ -#ifdef SUPPORT_PRINTING_M_FORMAT - sprintf(pathname, EDGE_LBL_MODULE "/%M/" -#else - sprintf(pathname, EDGE_LBL_MODULE "/%x/" -#endif - "iobrick" "/%s/%d", - NODEPDA(cnode)->module_id, - EDGE_LBL_XTALK, widgetnum); - } else { - slot = get_widget_slotnum(0, widgetnum); - board = get_board_name(nasid, module, slot, - new_name); - /* - * Create the vertex for the widget, - * using the decimal - * widgetnum as the name of the primary edge. - */ -#ifdef SUPPORT_PRINTING_M_FORMAT - sprintf(pathname, EDGE_LBL_MODULE "/%M/" - EDGE_LBL_SLOT "/%s", - NODEPDA(cnode)->module_id, - new_name); -#else - memset(buffer, 0, 16); - format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); - sprintf(pathname, EDGE_LBL_MODULE "/%s/" - EDGE_LBL_SLOT "/%s", - buffer, - new_name); -#endif - } - - rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); - DBG("io_xswitch_widget_init: (2) path= %s\n", pathname); - /* - * This is a weird ass code needed for error injection - * purposes. - */ - rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); - - klhwg_baseio_inventory_add(widgetv,cnode); - } - sprintf(name, "%d", widgetnum); - DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv); - rc = hwgraph_edge_add(xswitchv, widgetv, name); - - /* - * crosstalk switch code tracks which - * widget is attached to each link. - */ - xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv); - - /* - * Peek at the widget to get its crosstalk part and - * mfgr numbers, then present it to the generic xtalk - * bus provider to have its driver attach routine - * called (or not). - */ -#ifdef XBRIDGE_REGS_SIM - widget_id = 0x2d000049; - DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n"); -#else - widget_id = XWIDGET_ID_READ(nasid, widgetnum); -#endif /* XBRIDGE_REGS_SIM */ - hwid.part_num = XWIDGET_PART_NUM(widget_id); - hwid.rev_num = XWIDGET_REV_NUM(widget_id); - hwid.mfg_num = XWIDGET_MFG_NUM(widget_id); - /* Store some inventory information about - * the xwidget in the hardware graph. - */ - xwidget_inventory_add(widgetv,board,hwid); - - (void)xwidget_register(&hwid, widgetv, widgetnum, - hubv, hub_widgetid, - aa); - -#ifdef SN0_USE_BTE - bte_bpush_war(cnode, (void *)board); -#endif - } -} - - -static void -io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode) -{ - xwidgetnum_t widgetnum; - async_attach_t aa; - - aa = async_attach_new(); - - DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode); - - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; - widgetnum++) { - io_xswitch_widget_init(xswitchv, - cnodeid_to_vertex(cnode), - widgetnum, aa); - } - /* - * Wait for parallel attach threads, if any, to complete. - */ - async_attach_waitall(aa); - async_attach_free(aa); -} - -/* - * For each PCI bridge connected to the xswitch, add a link from the - * board's klconfig info to the bridge's hwgraph vertex. This lets - * the FRU analyzer find the bridge without traversing the hardware - * graph and risking hangs. - */ -static void -io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) -{ - xwidgetnum_t widgetnum; - char pathname[128]; - devfs_handle_t vhdl; - nasid_t nasid, peer_nasid; - lboard_t *board; - - - - /* And its connected hub's nasids */ - nasid = COMPACT_TO_NASID_NODEID(cnodeid); - peer_nasid = NODEPDA(cnodeid)->xbow_peer; - - /* - * Look for paths matching "/pci" under xswitchv. - * For every widget, init. its lboard's hwgraph link. If the - * board has a PCI bridge, point the link to it. - */ - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; - widgetnum++) { - sprintf(pathname, "%d", widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) != - GRAPH_SUCCESS) - continue; - - board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), - NODEPDA(cnodeid)->module_id); - if (board == NULL && peer_nasid != INVALID_NASID) { - /* - * Try to find the board on our peer - */ - board = find_lboard_module( - (lboard_t *)KL_CONFIG_INFO(peer_nasid), - NODEPDA(cnodeid)->module_id); - } - if (board == NULL) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "Could not find PROM info for vertex %v, " - "FRU analyzer may fail", - vhdl); -#else - printk(KERN_WARNING "Could not find PROM info for vertex 0x%p, " - "FRU analyzer may fail", - (void *)vhdl); -#endif - return; - } - - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) == - GRAPH_SUCCESS) - board->brd_graph_link = vhdl; - else - board->brd_graph_link = GRAPH_VERTEX_NONE; - } -} - -/* - * Initialize all I/O on the specified node. - */ -static void -io_init_node(cnodeid_t cnodeid) -{ - /*REFERENCED*/ - devfs_handle_t hubv, switchv, widgetv; - struct xwidget_hwid_s hwid; - hubinfo_t hubinfo; - int is_xswitch; - nodepda_t *npdap; - struct semaphore *peer_sema = 0; - uint32_t widget_partnum; - nodepda_router_info_t *npda_rip; - cpu_cookie_t c = 0; - extern int hubdev_docallouts(devfs_handle_t); - -#ifdef LATER - /* Try to execute on the node that we're initializing. */ - c = setnoderun(cnodeid); -#endif - npdap = NODEPDA(cnodeid); - - /* - * Get the "top" vertex for this node's hardware - * graph; it will carry the per-hub hub-specific - * data, and act as the crosstalk provider master. - * It's canonical path is probably something of the - * form /hw/module/%M/slot/%d/node - */ - hubv = cnodeid_to_vertex(cnodeid); - DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap); - - ASSERT(hubv != GRAPH_VERTEX_NONE); - - hubdev_docallouts(hubv); - - /* - * Set up the dependent routers if we have any. - */ - npda_rip = npdap->npda_rip_first; - - while(npda_rip) { - /* If the router info has not been initialized - * then we need to do the router initialization - */ - if (!npda_rip->router_infop) { - router_init(cnodeid,0,npda_rip); - } - npda_rip = npda_rip->router_next; - } - - /* - * Read mfg info on this hub - */ - - /* - * If nothing connected to this hub's xtalk port, we're done. - */ - early_probe_for_widget(hubv, &hwid); - if (hwid.part_num == XWIDGET_PART_NUM_NONE) { -#ifdef PROBE_TEST - if ((cnodeid == 1) || (cnodeid == 2)) { - int index; - - for (index = 0; index < 600; index++) - DBG("Interfering with device probing!!!\n"); - } -#endif - /* io_init_done takes cpu cookie as 2nd argument - * to do a restorenoderun for the setnoderun done - * at the start of this thread - */ - - DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv); - return; - /* NOTREACHED */ - } - - /* - * attach our hub_provider information to hubv, - * so we can use it as a crosstalk provider "master" - * vertex. - */ - xtalk_provider_register(hubv, &hub_provider); - xtalk_provider_startup(hubv); - - /* - * Create a vertex to represent the crosstalk bus - * attached to this hub, and a vertex to be used - * as the connect point for whatever is out there - * on the other side of our crosstalk connection. - * - * Crosstalk Switch drivers "climb up" from their - * connection point to try and take over the switch - * point. - * - * Of course, the edges and verticies may already - * exist, in which case our net effect is just to - * associate the "xtalk_" driver with the connection - * point for the device. - */ - - (void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv); - - DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv); - - ASSERT(switchv != GRAPH_VERTEX_NONE); - - (void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO); - - DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n"); - - /* - * We need to find the widget id and update the basew_id field - * accordingly. In particular, SN00 has direct connected bridge, - * and hence widget id is Not 0. - */ - - widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; - - if (widget_partnum == BRIDGE_WIDGET_PART_NUM || - widget_partnum == XBRIDGE_WIDGET_PART_NUM){ - npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); - - DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum); - - } else if ((widget_partnum == XBOW_WIDGET_PART_NUM) || - (widget_partnum == XXBOW_WIDGET_PART_NUM) || - (widget_partnum == PXBOW_WIDGET_PART_NUM) ) { - /* - * Xbow control register does not have the widget ID field. - * So, hard code the widget ID to be zero. - */ - DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum); - npdap->basew_id = 0; - - } else { - npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); - - panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widget ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv); - - /*NOTREACHED*/ - } - { - char widname[10]; - sprintf(widname, "%x", npdap->basew_id); - (void)hwgraph_path_add(switchv, widname, &widgetv); - DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv); - ASSERT(widgetv != GRAPH_VERTEX_NONE); - } - - nodepda->basew_xc = widgetv; - - is_xswitch = xwidget_hwid_is_xswitch(&hwid); - - /* - * Try to become the master of the widget. If this is an xswitch - * with multiple hubs connected, only one will succeed. Mastership - * of an xswitch is used only when touching registers on that xswitch. - * The slave xwidgets connected to the xswitch can be owned by various - * masters. - */ - if (device_master_set(widgetv, hubv) == 0) { - - /* Only one hub (thread) per Crosstalk device or switch makes - * it to here. - */ - - /* - * Initialize whatever xwidget is hanging off our hub. - * Whatever it is, it's accessible through widgetnum 0. - */ - hubinfo_get(hubv, &hubinfo); - - (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL); - - if (!is_xswitch) { - /* io_init_done takes cpu cookie as 2nd argument - * to do a restorenoderun for the setnoderun done - * at the start of this thread - */ - io_init_done(cnodeid,c); - /* NOTREACHED */ - } - - /* - * Special handling for Crosstalk Switches (e.g. xbow). - * We need to do things in roughly the following order: - * 1) Initialize xswitch hardware (done above) - * 2) Determine which hubs are available to be widget masters - * 3) Discover which links are active from the xswitch - * 4) Assign xwidgets hanging off the xswitch to hubs - * 5) Initialize all xwidgets on the xswitch - */ - - volunteer_for_widgets(switchv, hubv); - - /* If there's someone else on this crossbow, recognize him */ - if (npdap->xbow_peer != INVALID_NASID) { - nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer)); - peer_sema = &peer_npdap->xbow_sema; - volunteer_for_widgets(switchv, peer_npdap->node_vertex); - } - - assign_widgets_to_volunteers(switchv, hubv); - - /* Signal that we're done */ - if (peer_sema) { - mutex_unlock(peer_sema); - } - - } - else { - /* Wait 'til master is done assigning widgets. */ - mutex_lock(&npdap->xbow_sema); - } - -#ifdef PROBE_TEST - if ((cnodeid == 1) || (cnodeid == 2)) { - int index; - - for (index = 0; index < 500; index++) - DBG("Interfering with device probing!!!\n"); - } -#endif - /* Now both nodes can safely inititialize widgets */ - io_init_xswitch_widgets(switchv, cnodeid); - io_link_xswitch_widgets(switchv, cnodeid); - - /* io_init_done takes cpu cookie as 2nd argument - * to do a restorenoderun for the setnoderun done - * at the start of this thread - */ - io_init_done(cnodeid,c); - - DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid); -} - - -#define IOINIT_STKSZ (16 * 1024) - -#define __DEVSTR1 "/../.master/" -#define __DEVSTR2 "/target/" -#define __DEVSTR3 "/lun/0/disk/partition/" -#define __DEVSTR4 "/../ef" - -/* - * Currently, we need to allow for 5 IBrick slots with 1 FC each - * plus an internal 1394. - * - * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR. - */ -#define NUM_BASE_IO_SCSI_CTLR 6 - -/* - * This tells ioconfig where it can start numbering scsi controllers. - * Below this base number, platform-specific handles the numbering. - * XXX Irix legacy..controller numbering should be part of devfsd's job - */ -int num_base_io_scsi_ctlr = 2; /* used by syssgi */ -devfs_handle_t base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR]; -static devfs_handle_t baseio_enet_vhdl,baseio_console_vhdl; - -/* - * Put the logical controller number information in the - * scsi controller vertices for each scsi controller that - * is in a "fixed position". - */ -static void -scsi_ctlr_nums_add(devfs_handle_t pci_vhdl) -{ - { - int i; - - num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR; - - /* Initialize base_io_scsi_ctlr_vhdl array */ - for (i=0; i -devfs_handle_t sys_critical_graph_root = GRAPH_VERTEX_NONE; - -/* Define the system critical vertices and connect them through - * a canonical parent-child relationships for easy traversal - * during io error handling. - */ -static void -sys_critical_graph_init(void) -{ - devfs_handle_t bridge_vhdl,master_node_vhdl; - devfs_handle_t xbow_vhdl = GRAPH_VERTEX_NONE; - extern devfs_handle_t hwgraph_root; - devfs_handle_t pci_slot_conn; - int slot; - devfs_handle_t baseio_console_conn; - - DBG("sys_critical_graph_init: FIXME.\n"); - baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl); - - if (baseio_console_conn == NULL) { - return; - } - - /* Get the vertex handle for the baseio bridge */ - bridge_vhdl = device_master_get(baseio_console_conn); - - /* Get the master node of the baseio card */ - master_node_vhdl = cnodeid_to_vertex( - master_node_get(baseio_console_vhdl)); - - /* Add the "root->node" part of the system critical graph */ - - sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl); - - /* Check if we have a crossbow */ - if (hwgraph_traverse(master_node_vhdl, - EDGE_LBL_XTALK"/0", - &xbow_vhdl) == GRAPH_SUCCESS) { - /* We have a crossbow.Add "node->xbow" part of the system - * critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl); - - /* Add "xbow->baseio bridge" of the system critical graph */ - sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl); - - hwgraph_vertex_unref(xbow_vhdl); - } else - /* We donot have a crossbow. Add "node->baseio_bridge" - * part of the system critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl); - - /* Add all the populated PCI slot vertices to the system critical - * graph with the bridge vertex as the parent. - */ - for (slot = 0 ; slot < 8; slot++) { - char slot_edge[10]; - - sprintf(slot_edge,"%d",slot); - if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn) - != GRAPH_SUCCESS) - continue; - sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn); - hwgraph_vertex_unref(pci_slot_conn); - } - - hwgraph_vertex_unref(bridge_vhdl); - - /* Add the "ioc3 pci connection point -> console ioc3" part - * of the system critical graph - */ - - if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_console_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "ethernet pci connection point -> base ethernet" part of - * the system critical graph - */ - if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_enet_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "scsi controller pci connection point -> base scsi - * controller" part of the system critical graph - */ - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[0]); - hwgraph_vertex_unref(pci_slot_conn); - } - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[1]); - hwgraph_vertex_unref(pci_slot_conn); - } - hwgraph_vertex_unref(baseio_console_conn); - -} - -static void -baseio_ctlr_num_set(void) -{ - char name[MAXDEVNAME]; - devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; - devfs_handle_t ioc3_console_vhdl_get(void); - - - DBG("baseio_ctlr_num_set; FIXME\n"); - console_vhdl = ioc3_console_vhdl_get(); - if (console_vhdl == GRAPH_VERTEX_NONE) - return; - /* Useful for setting up the system critical graph */ - baseio_console_vhdl = console_vhdl; - - vertex_to_name(console_vhdl,name,MAXDEVNAME); - - strcat(name,__DEVSTR1); - pci_vhdl = hwgraph_path_to_vertex(name); - scsi_ctlr_nums_add(pci_vhdl); - /* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(pci_vhdl); - - vertex_to_name(console_vhdl, name, MAXDEVNAME); - strcat(name, __DEVSTR4); - enet_vhdl = hwgraph_path_to_vertex(name); - - /* Useful for setting up the system critical graph */ - baseio_enet_vhdl = enet_vhdl; - - device_controller_num_set(enet_vhdl, 0); - /* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(enet_vhdl); -} -/* #endif */ - -void -sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list) -{ - /* REFERENCED */ - int rtn_val; - - /* - ** sn00 population: errb orrb - ** 0- ql 3+? - ** 1- ql 2 - ** 2- ioc3 ethernet 2+? - ** 3- ioc3 secondary 1 - ** 4- 0 - ** 5- PCI slot - ** 6- PCI slot - ** 7- PCI slot - */ - - /* The following code implements this heuristic for getting - * maximum usage out of the rrbs - * - * constraints: - * 8 bit ql1 needs 1+1 - * ql0 or ql5,6,7 wants 1+2 - * ethernet wants 2 or more - * - * rules for even rrbs: - * if nothing in slot 6 - * 4 rrbs to 0 and 2 (0xc8889999) - * else - * 3 2 3 to slots 0 2 6 (0xc8899bbb) - * - * rules for odd rrbs - * if nothing in slot 5 or 7 (0xc8889999) - * 4 rrbs to 1 and 3 - * else if 1 thing in 5 or 7 (0xc8899aaa) or (0xc8899bbb) - * 3 2 3 to slots 1 3 5|7 - * else - * 2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this - * (0xc89aaabb) may short what it wants therefore the - * rule should be to plug pci slots in order) - */ - - - if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) { - /* something in slot 6 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0); - } - else { - rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0); - } - if (rtn_val) - printk(KERN_WARNING "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed"); - - if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && - (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) { - /* soemthing in slot 5 and 7 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0); - } - else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) { - /* soemthing in slot 5 but not 7 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0); - } - else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) { - /* soemthing in slot 7 but not 5 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0); - } - else { - /* nothing in slot 5 or 7 */ - rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0); - } - if (rtn_val) - printk(KERN_WARNING "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed"); -} - - -/* - * Initialize all I/O devices. Starting closest to nodes, probe and - * initialize outward. - */ -void -init_all_devices(void) -{ - /* Governor on init threads..bump up when safe - * (beware many devfs races) - */ - cnodeid_t cnodeid, active; - - active = 0; - for (cnodeid = 0; cnodeid < numnodes; cnodeid++) { - DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid); - io_init_node(cnodeid); - - DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid); - } - - for (cnodeid = 0; cnodeid < numnodes; cnodeid++) - /* - * Update information generated by IO init. - */ - update_node_information(cnodeid); - - baseio_ctlr_num_set(); - /* Setup the system critical graph (which is a subgraph of the - * main hwgraph). This information is useful during io error - * handling. - */ - sys_critical_graph_init(); - -#if HWG_PRINT - hwgraph_print(); -#endif - -} - -#define toint(x) ((int)(x) - (int)('0')) - -void -devnamefromarcs(char *devnm) -{ - int val; - char tmpnm[MAXDEVNAME]; - char *tmp1, *tmp2; - - val = strncmp(devnm, "dks", 3); - if (val != 0) - return; - tmp1 = devnm + 3; - if (!isdigit(*tmp1)) - return; - - val = 0; - while (isdigit(*tmp1)) { - val = 10*val+toint(*tmp1); - tmp1++; - } - - if(*tmp1 != 'd') - return; - else - tmp1++; - - if ((val < 0) || (val >= num_base_io_scsi_ctlr)) { - int i; - int viable_found = 0; - - DBG("Only controller numbers 0..%d are supported for\n", NUM_BASE_IO_SCSI_CTLR-1); - DBG("prom \"root\" variables of the form dksXdXsX.\n"); - DBG("To use another disk you must use the full hardware graph path\n\n"); - DBG("Possible controller numbers for use in 'dksXdXsX' on this system: "); - for (i=0; i XBOW_PORT_F) - return 0; - - /* Find "brick" in the path name */ - bp = strstr(hw_path_name, "brick"); - if (bp == NULL) - return 0; - - /* Find preceding slash */ - sp = bp; - while (sp > hw_path_name) { - sp--; - if (*sp == '/') - break; - } - - /* Invalid if no preceding slash */ - if (!sp) - return 0; - - /* Bump slash pointer to "brick" prefix */ - sp++; - /* - * Verify "brick" prefix length; valid exaples: - * 'I' from "/Ibrick" - * 'P' from "/Pbrick" - * 'X' from "/Xbrick" - */ - if ((bp - sp) != 1) - return 0; - - return (io_brick_map_widget((int)*sp, widget_num)); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/module.c linux-2.4.22/arch/ia64/sn/io/sn1/module.c --- linux-2.4.21/arch/ia64/sn/io/sn1/module.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/module.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,311 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* #define LDEBUG 1 */ - -#ifdef LDEBUG -#define DPRINTF printk -#define printf printk -#else -#define DPRINTF(x...) -#endif - -module_t *modules[MODULE_MAX]; -int nummodules; - -#define SN00_SERIAL_FUDGE 0x3b1af409d513c2 -#define SN0_SERIAL_FUDGE 0x6e - -void -encode_int_serial(uint64_t src,uint64_t *dest) -{ - uint64_t val; - int i; - - val = src + SN00_SERIAL_FUDGE; - - - for (i = 0; i < sizeof(long long); i++) { - ((char*)dest)[i] = - ((char*)&val)[sizeof(long long)/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))]; - } -} - - -void -decode_int_serial(uint64_t src, uint64_t *dest) -{ - uint64_t val; - int i; - - for (i = 0; i < sizeof(long long); i++) { - ((char*)&val)[sizeof(long long)/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = - ((char*)&src)[i]; - } - - *dest = val - SN00_SERIAL_FUDGE; -} - - -void -encode_str_serial(const char *src, char *dest) -{ - int i; - - for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) { - - dest[i] = src[MAX_SERIAL_NUM_SIZE/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))] + - SN0_SERIAL_FUDGE; - } -} - -void -decode_str_serial(const char *src, char *dest) -{ - int i; - - for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) { - dest[MAX_SERIAL_NUM_SIZE/2 + - ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] - - SN0_SERIAL_FUDGE; - } -} - - -module_t *module_lookup(moduleid_t id) -{ - int i; - - for (i = 0; i < nummodules; i++) - if (modules[i]->id == id) { - DPRINTF("module_lookup: found m=0x%p\n", modules[i]); - return modules[i]; - } - - return NULL; -} - -/* - * module_add_node - * - * The first time a new module number is seen, a module structure is - * inserted into the module list in order sorted by module number - * and the structure is initialized. - * - * The node number is added to the list of nodes in the module. - */ - -module_t *module_add_node(moduleid_t id, cnodeid_t n) -{ - module_t *m; - int i; - char buffer[16]; - -#ifdef __ia64 - memset(buffer, 0, 16); - format_module_id(buffer, id, MODULE_FORMAT_BRIEF); - DPRINTF("module_add_node: id=%s node=%d\n", buffer, n); -#endif - - if ((m = module_lookup(id)) == 0) { -#ifdef LATER - m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n); -#else - m = kmalloc(sizeof (module_t), GFP_KERNEL); - memset(m, 0 , sizeof(module_t)); -#endif - ASSERT_ALWAYS(m); - - m->id = id; - spin_lock_init(&m->lock); - - mutex_init_locked(&m->thdcnt); - - elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n)); - spin_lock_init(&m->elsclock); - - /* Insert in sorted order by module number */ - - for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--) - modules[i] = modules[i - 1]; - - modules[i] = m; - nummodules++; - } - - m->nodes[m->nodecnt++] = n; - - DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt); - - return m; -} - -int module_probe_snum(module_t *m, nasid_t nasid) -{ - lboard_t *board; - klmod_serial_num_t *comp; - char * bcopy(const char * src, char * dest, int count); - char serial_number[16]; - - /* - * record brick serial number - */ - board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - - if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) - { -#if LDEBUG - printf ("module_probe_snum: no IP35 board found!\n"); -#endif - return 0; - } - - board_serial_number_get( board, serial_number ); - if( serial_number[0] != '\0' ) { - encode_str_serial( serial_number, m->snum.snum_str ); - m->snum_valid = 1; - } -#if LDEBUG - else { - printf("module_probe_snum: brick serial number is null!\n"); - } - printf("module_probe_snum: brick serial number == %s\n", serial_number); -#endif /* DEBUG */ - - board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), - KLTYPE_IOBRICK_XBOW); - - if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) - return 0; - - comp = GET_SNUM_COMP(board); - - if (comp) { -#if LDEBUG - int i; - - printf("********found module with id %x and string", m->id); - - for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) - printf(" %x ", comp->snum.snum_str[i]); - - printf("\n"); /* Fudged string is not ASCII */ -#endif - - if (comp->snum.snum_str[0] != '\0') { - bcopy(comp->snum.snum_str, - m->sys_snum, - MAX_SERIAL_NUM_SIZE); - m->sys_snum_valid = 1; - } - } - - if (m->sys_snum_valid) - return 1; - else { - DPRINTF("Invalid serial number for module %d, " - "possible missing or invalid NIC.", m->id); - return 0; - } -} - -void -io_module_init(void) -{ - cnodeid_t node; - lboard_t *board; - nasid_t nasid; - int nserial; - module_t *m; - - DPRINTF("*******module_init\n"); - - nserial = 0; - - for (node = 0; node < numnodes; node++) { - nasid = COMPACT_TO_NASID_NODEID(node); - - board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA); - ASSERT(board); - - m = module_add_node(board->brd_module, node); - - if (! m->snum_valid && module_probe_snum(m, nasid)) - nserial++; - } - - DPRINTF("********found total of %d serial numbers in the system\n", - nserial); - - if (nserial == 0) - printk(KERN_WARNING "io_module_init: No serial number found.\n"); -} - -elsc_t *get_elsc(void) -{ - return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc; -} - -int -get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info) -{ - int i; - - if (cmod < 0 || cmod >= nummodules) - return -EINVAL; - - if (! modules[cmod]->snum_valid) - return -ENXIO; - - mod_info->mod_num = modules[cmod]->id; - { - char temp[MAX_SERIAL_NUM_SIZE]; - - decode_str_serial(modules[cmod]->snum.snum_str, temp); - - /* if this is an invalid serial number return an error */ - if (temp[0] != 'K') - return -ENXIO; - - mod_info->serial_num = 0; - - for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) { - mod_info->serial_num <<= 4; - mod_info->serial_num |= (temp[i] & 0xf); - - mod_info->serial_str[i] = temp[i]; - } - - mod_info->serial_str[i] = '\0'; - } - - return 0; -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/pci_bus_cvlink.c linux-2.4.22/arch/ia64/sn/io/sn1/pci_bus_cvlink.c --- linux-2.4.21/arch/ia64/sn/io/sn1/pci_bus_cvlink.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/pci_bus_cvlink.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,696 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int bridge_rev_b_data_check_disable; - -devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET]; -nasid_t busnum_to_nid[MAX_PCI_XWIDGET]; -void * busnum_to_atedmamaps[MAX_PCI_XWIDGET]; -unsigned char num_bridges; -static int done_probing = 0; - -static int pci_bus_map_create(devfs_handle_t xtalk); -devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn); - -#define SN_IOPORTS_UNIT 256 -#define MAX_IOPORTS 0xffff -#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN_IOPORTS_UNIT) -struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS]; -unsigned long sn_allocate_ioports(unsigned long pci_address); -extern unsigned char Is_pic_on_this_nasid[512]; - -extern void sn_init_irq_desc(void); - - -/* - * For the given device, initialize whether it is a PIC device. - */ -static void -set_isPIC(struct sn_device_sysdata *device_sysdata) -{ - pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);; -} - -/* - * pci_bus_cvlink_init() - To be called once during initialization before - * SGI IO Infrastructure init is called. - */ -void -pci_bus_cvlink_init(void) -{ - memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET); - memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET); - - memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET); - - memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs)); - - num_bridges = 0; -} - -/* - * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated - * pci bus vertex from the SGI IO Infrastructure. - */ -devfs_handle_t -pci_bus_to_vertex(unsigned char busnum) -{ - - devfs_handle_t pci_bus = NULL; - - - /* - * First get the xwidget vertex. - */ - pci_bus = busnum_to_pcibr_vhdl[busnum]; - return(pci_bus); -} - -/* - * devfn_to_vertex() - returns the vertex of the device given the bus, slot, - * and function numbers. - */ -devfs_handle_t -devfn_to_vertex(unsigned char busnum, unsigned int devfn) -{ - - int slot = 0; - int func = 0; - char name[16]; - devfs_handle_t pci_bus = NULL; - devfs_handle_t device_vertex = (devfs_handle_t)NULL; - - /* - * Go get the pci bus vertex. - */ - pci_bus = pci_bus_to_vertex(busnum); - if (!pci_bus) { - /* - * During probing, the Linux pci code invents non existant - * bus numbers and pci_dev structures and tries to access - * them to determine existance. Don't crib during probing. - */ - if (done_probing) - printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum); - return(NULL); - } - - - /* - * Go get the slot&function vertex. - * Should call pciio_slot_func_to_name() when ready. - */ - slot = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* - * For a NON Multi-function card the name of the device looks like: - * ../pci/1, ../pci/2 .. - */ - if (func == 0) { - sprintf(name, "%d", slot); - if (hwgraph_traverse(pci_bus, name, &device_vertex) == - GRAPH_SUCCESS) { - if (device_vertex) { - return(device_vertex); - } - } - } - - /* - * This maybe a multifunction card. It's names look like: - * ../pci/1a, ../pci/1b, etc. - */ - sprintf(name, "%d%c", slot, 'a'+func); - if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) { - if (!device_vertex) { - return(NULL); - } - } - - return(device_vertex); -} - -/* - * For the given device, initialize the addresses for both the Device(x) Flush - * Write Buffer register and the Xbow Flush Register for the port the PCI bus - * is connected. - */ -static void -set_flush_addresses(struct pci_dev *device_dev, - struct sn_device_sysdata *device_sysdata) -{ - pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - - device_sysdata->dma_buf_sync = (volatile unsigned int *) - &(bridge->b_wr_req_buf[pciio_slot].reg); - device_sysdata->xbow_buf_sync = (volatile unsigned int *) - XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), - pcibr_soft->bs_xid); -#ifdef DEBUG - - printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", - device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync); - - while((volatile unsigned int )*device_sysdata->dma_buf_sync); - while((volatile unsigned int )*device_sysdata->xbow_buf_sync); -#endif - -} - -/* - * Most drivers currently do not properly tell the arch specific pci dma - * interfaces whether they can handle A64. Here is where we privately - * keep track of this. - */ -static void __init -set_sn_pci64(struct pci_dev *dev) -{ - unsigned short vendor = dev->vendor; - unsigned short device = dev->device; - - if (vendor == PCI_VENDOR_ID_QLOGIC) { - if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) || - (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) { - SET_PCIA64(dev); - return; - } - } - - if (vendor == PCI_VENDOR_ID_SGI) { - if (device == PCI_DEVICE_ID_SGI_IOC3) { - SET_PCIA64(dev); - return; - } - } - -} - -/* - * sn_allocate_ioports() - This routine provides the allocation and - * mappings between Linux style IOPORTs management. - * - * For simplicity sake, SN1 will allocate IOPORTs in chunks of - * 256bytes .. irrespective of what the card desires. This may - * have to change when we understand how to deal with legacy ioports - * which are hardcoded in some drivers e.g. SVGA. - * - * Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers. - * It will remain so. The IO Infrastructure will continue to map - * IO Resource just like IRIX. When this is done, we map IOPORT - * chunks to these resources. The Linux drivers will see and use real - * IOPORT numbers. The various IOPORT access macros e.g. inb/outb etc. - * does the munging of these IOPORT numbers to make a Uncache Virtual - * Address. This address via the tlb entries generates the PCI Address - * allocated by the SN1 IO Infrastructure Layer. - */ -static unsigned long sn_ioport_num = 0x1000; /* Reserve room for Legacy stuff */ -unsigned long -sn_allocate_ioports(unsigned long pci_address) -{ - - unsigned long ioport_index; - - /* - * Just some idiot checking .. - */ - if ( sn_ioport_num > 0xffff ) { - printk("sn_allocate_ioports: No more IO PORTS available\n"); - return(-1); - } - - /* - * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's - * Manual for details. - */ - ioport_index = sn_ioport_num / SN_IOPORTS_UNIT; - - ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */ - ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */ - ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/ - ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/ - ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */ - ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/ - ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/ - ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */ - ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */ - ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */ - - /* printk("sn_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */ - - sn_ioport_num += SN_IOPORTS_UNIT; - - return(sn_ioport_num - SN_IOPORTS_UNIT); -} - -/* - * sn_pci_fixup() - This routine is called when platform_pci_fixup() is - * invoked at the end of pcibios_init() to link the Linux pci - * infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c - * - * Other platform specific fixup can also be done here. - */ -void -sn_pci_fixup(int arg) -{ - struct list_head *ln; - struct pci_bus *pci_bus = NULL; - struct pci_dev *device_dev = NULL; - struct sn_widget_sysdata *widget_sysdata; - struct sn_device_sysdata *device_sysdata; -#ifdef SN_IOPORTS - unsigned long ioport; -#endif - pciio_intr_t intr_handle; - int cpuid, bit; - devfs_handle_t device_vertex; - pciio_intr_line_t lines; - extern void sn_pci_find_bios(void); - - if (arg == 0) { - sn_init_irq_desc(); - sn_pci_find_bios(); - return; - } - - done_probing = 1; - - /* - * Initialize the pci bus vertex in the pci_bus struct. - */ - for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { - pci_bus = pci_bus_b(ln); - widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), - GFP_KERNEL); - widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number); - pci_bus->sysdata = (void *)widget_sysdata; - } - - /* - * set the root start and end so that drivers calling check_region() - * won't see a conflict - */ -#ifdef SN_IOPORTS - ioport_resource.start = sn_ioport_num; - ioport_resource.end = 0xffff; -#else - if ( IS_RUNNING_ON_SIMULATOR() ) { - /* - * IDE legacy IO PORTs are supported in Medusa. - * Just open up IO PORTs from 0 .. ioport_resource.end. - */ - ioport_resource.start = 0; - } else { - /* - * We do not support Legacy IO PORT numbers. - */ - ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET; - } - ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET; -#endif - - /* - * Set the root start and end for Mem Resource. - */ - iomem_resource.start = 0; - iomem_resource.end = 0xffffffffffffffff; - - /* - * Initialize the device vertex in the pci_dev struct. - */ - pci_for_each_dev(device_dev) { - unsigned int irq; - int idx; - u16 cmd; - devfs_handle_t vhdl; - unsigned long size; - extern int bit_pos_to_irq(int); - - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3) { - extern void pci_fixup_ioc3(struct pci_dev *d); - pci_fixup_ioc3(device_dev); - } - - /* Set the device vertex */ - - device_sysdata = kmalloc(sizeof(struct sn_device_sysdata), - GFP_KERNEL); - device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn); - device_sysdata->isa64 = 0; - /* - * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush - * register addresses. - */ - (void) set_flush_addresses(device_dev, device_sysdata); - - device_dev->sysdata = (void *) device_sysdata; - set_sn_pci64(device_dev); - set_isPIC(device_sysdata); - - pci_read_config_word(device_dev, PCI_COMMAND, &cmd); - - /* - * Set the resources address correctly. The assumption here - * is that the addresses in the resource structure has been - * read from the card and it was set in the card by our - * Infrastructure .. - */ - vhdl = device_sysdata->vhdl; - for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { - size = 0; - size = device_dev->resource[idx].end - - device_dev->resource[idx].start; - if (size) { - device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); - device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET; - } - else - continue; - - device_dev->resource[idx].end = - device_dev->resource[idx].start + size; - - /* - * Adjust the addresses to go to the SWIZZLE .. - */ - device_dev->resource[idx].start = - device_dev->resource[idx].start & 0xfffff7ffffffffff; - device_dev->resource[idx].end = - device_dev->resource[idx].end & 0xfffff7ffffffffff; - - if (device_dev->resource[idx].flags & IORESOURCE_IO) { - cmd |= PCI_COMMAND_IO; -#ifdef SN_IOPORTS - ioport = sn_allocate_ioports(device_dev->resource[idx].start); - if (ioport < 0) { - printk("sn_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number); - continue; - } - pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff))); - - printk("sn_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff))); - - device_dev->resource[idx].start = ioport; - device_dev->resource[idx].end = ioport + SN_IOPORTS_UNIT; -#endif - } - if (device_dev->resource[idx].flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - /* - * Now handle the ROM resource .. - */ - size = device_dev->resource[PCI_ROM_RESOURCE].end - - device_dev->resource[PCI_ROM_RESOURCE].start; - - if (size) { - device_dev->resource[PCI_ROM_RESOURCE].start = - (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, - size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); - device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET; - device_dev->resource[PCI_ROM_RESOURCE].end = - device_dev->resource[PCI_ROM_RESOURCE].start + size; - - /* - * go through synergy swizzled space - */ - device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL; - device_dev->resource[PCI_ROM_RESOURCE].end &= 0xfffff7ffffffffffUL; - - } - - /* - * Update the Command Word on the Card. - */ - cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */ - /* bit gets dropped .. no harm */ - pci_write_config_word(device_dev, PCI_COMMAND, cmd); - - pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines); - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { - lines = 1; - } - - device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata; - device_vertex = device_sysdata->vhdl; - - intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex); - - bit = intr_handle->pi_irq; - cpuid = intr_handle->pi_cpu; - irq = bit_pos_to_irq(bit); - irq = irq + (cpuid << 8); - pciio_intr_connect(intr_handle); - device_dev->irq = irq; -#ifdef ajmtestintr - { - int slot = PCI_SLOT(device_dev->devfn); - static int timer_set = 0; - pcibr_intr_t pcibr_intr = (pcibr_intr_t)intr_handle; - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - extern void intr_test_handle_intr(int, void*, struct pt_regs *); - - if (!timer_set) { - intr_test_set_timer(); - timer_set = 1; - } - intr_test_register_irq(irq, pcibr_soft, slot); - request_irq(irq, intr_test_handle_intr,0,NULL, NULL); - } -#endif - - } -} - -/* - * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. - * - * Linux PCI Bus numbers are assigned from lowest module_id numbers - * (rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to - * HUB_WIDGET_ID_MIN: - * widgetnum 15 gets lower Bus Number than widgetnum 14 etc. - * - * Given 2 modules 001c01 and 001c02 we get the following mappings: - * 001c01, widgetnum 15 = Bus number 0 - * 001c01, widgetnum 14 = Bus number 1 - * 001c02, widgetnum 15 = Bus number 3 - * 001c02, widgetnum 14 = Bus number 4 - * etc. - * - * The rational for starting Bus Number 0 with Widget number 15 is because - * the system boot disks are always connected via Widget 15 Slot 0 of the - * I-brick. Linux creates /dev/sd* devices(naming) strating from Bus Number 0 - * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest - * module id(Master Cnode) of the system. - * - */ -static int -pci_bus_map_create(devfs_handle_t xtalk) -{ - - devfs_handle_t master_node_vertex = NULL; - devfs_handle_t xwidget = NULL; - devfs_handle_t pci_bus = NULL; - hubinfo_t hubinfo = NULL; - xwidgetnum_t widgetnum; - char pathname[128]; - graph_error_t rv; - - /* - * Loop throught this vertex and get the Xwidgets .. - */ - for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) { - -#if 0 - { - int pos; - char dname[256]; - pos = devfs_generate_path(xtalk, dname, 256); - printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); - } -#endif - - sprintf(pathname, "%d", widgetnum); - xwidget = NULL; - - /* - * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget - * /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device - */ - rv = hwgraph_traverse(xtalk, pathname, &xwidget); - if ( (rv != GRAPH_SUCCESS) ) { - if (!xwidget) { - continue; -} - } - - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); - pci_bus = NULL; - if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) - if (!pci_bus) { - continue; -} - - /* - * Assign the correct bus number and also the nasid of this - * pci Xwidget. - * - * Should not be any race here ... - */ - num_bridges++; - busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus; - - /* - * Get the master node and from there get the NASID. - */ - master_node_vertex = device_master_get(xwidget); - if (!master_node_vertex) { - printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget); - } - - hubinfo_get(master_node_vertex, &hubinfo); - if (!hubinfo) { - printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex); - return(1); - } else { - busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; - } - - /* - * Pre assign DMA maps needed for 32 Bits Page Map DMA. - */ - busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc( - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); - if (!busnum_to_atedmamaps[num_bridges - 1]) - printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); - - memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); - - } - - return(0); -} - -/* - * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure - * initialization has completed to set up the mappings between Xbridge - * and logical pci bus numbers. We also set up the NASID for each of these - * xbridges. - * - * Must be called before pci_init() is invoked. - */ -int -pci_bus_to_hcl_cvlink(void) -{ - - devfs_handle_t devfs_hdl = NULL; - devfs_handle_t xtalk = NULL; - int rv = 0; - char name[256]; - int master_iobrick; - int i; - - /* - * Iterate throught each xtalk links in the system .. - * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 - * - * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15 - * - * What if it is not pci? - */ - devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module"); - - /* - * To provide consistent(not persistent) device naming, we need to start - * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 - * with an attached I-Brick. Find the master_iobrick. - */ - master_iobrick = -1; - for (i = 0; i < nummodules; i++) { - moduleid_t iobrick_id; - iobrick_id = iobrick_module_get(&modules[i]->elsc); - if (iobrick_id > 0) { /* Valid module id */ - if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) { - master_iobrick = i; - break; - } - } - } - - /* - * The master_iobrick gets bus 0 and 1. - */ - if (master_iobrick >= 0) { - memset(name, 0, 256); - format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF); - strcat(name, "/node/xtalk"); - xtalk = NULL; - rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); - pci_bus_map_create(xtalk); - } - - /* - * Now go do the rest of the modules, starting from the C-Brick with the lowest - * module id, remembering to skip the master_iobrick, which was done above. - */ - for (i = 0; i < nummodules; i++) { - if (i == master_iobrick) { - continue; /* Did the master_iobrick already. */ - } - - memset(name, 0, 256); - format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF); - strcat(name, "/node/xtalk"); - xtalk = NULL; - rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); - pci_bus_map_create(xtalk); - } - - return(0); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/pcibr.c linux-2.4.22/arch/ia64/sn/io/sn1/pcibr.c --- linux-2.4.21/arch/ia64/sn/io/sn1/pcibr.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/pcibr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,7704 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -int NeedXbridgeSwap = 0; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - -extern boolean_t is_sys_critical_vertex(devfs_handle_t); - -#undef PCIBR_ATE_DEBUG - -#if 0 -#define DEBUG 1 /* To avoid lots of bad printk() formats leave off */ -#endif -#define PCI_DEBUG 1 -#define ATTACH_DEBUG 1 -#define PCIBR_SOFT_LIST 1 - -#ifndef LOCAL -#define LOCAL static -#endif - -/* - * Macros related to the Lucent USS 302/312 usb timeout workaround. It - * appears that if the lucent part can get into a retry loop if it sees a - * DAC on the bus during a pio read retry. The loop is broken after about - * 1ms, so we need to set up bridges holding this part to allow at least - * 1ms for pio. - */ - -#define USS302_TIMEOUT_WAR - -#ifdef USS302_TIMEOUT_WAR -#define LUCENT_USBHC_VENDOR_ID_NUM 0x11c1 -#define LUCENT_USBHC302_DEVICE_ID_NUM 0x5801 -#define LUCENT_USBHC312_DEVICE_ID_NUM 0x5802 -#define USS302_BRIDGE_TIMEOUT_HLD 4 -#endif - -#define PCIBR_LLP_CONTROL_WAR -#if defined (PCIBR_LLP_CONTROL_WAR) -int pcibr_llp_control_war_cnt; -#endif /* PCIBR_LLP_CONTROL_WAR */ - -int pcibr_devflag = D_MP; - -#ifdef LATER -#define F(s,n) { 1l<<(s),-(s), n } - -struct reg_desc bridge_int_status_desc[] = -{ - F(31, "MULTI_ERR"), - F(30, "PMU_ESIZE_EFAULT"), - F(29, "UNEXPECTED_RESP"), - F(28, "BAD_XRESP_PACKET"), - F(27, "BAD_XREQ_PACKET"), - F(26, "RESP_XTALK_ERROR"), - F(25, "REQ_XTALK_ERROR"), - F(24, "INVALID_ADDRESS"), - F(23, "UNSUPPORTED_XOP"), - F(22, "XREQ_FIFO_OFLOW"), - F(21, "LLP_REC_SNERROR"), - F(20, "LLP_REC_CBERROR"), - F(19, "LLP_RCTY"), - F(18, "LLP_TX_RETRY"), - F(17, "LLP_TCTY"), - F(16, "SSRAM_PERR"), - F(15, "PCI_ABORT"), - F(14, "PCI_PARITY"), - F(13, "PCI_SERR"), - F(12, "PCI_PERR"), - F(11, "PCI_MASTER_TOUT"), - F(10, "PCI_RETRY_CNT"), - F(9, "XREAD_REQ_TOUT"), - F(8, "GIO_BENABLE_ERR"), - F(7, "INT7"), - F(6, "INT6"), - F(5, "INT5"), - F(4, "INT4"), - F(3, "INT3"), - F(2, "INT2"), - F(1, "INT1"), - F(0, "INT0"), - {0} -}; - -struct reg_values space_v[] = -{ - {PCIIO_SPACE_NONE, "none"}, - {PCIIO_SPACE_ROM, "ROM"}, - {PCIIO_SPACE_IO, "I/O"}, - {PCIIO_SPACE_MEM, "MEM"}, - {PCIIO_SPACE_MEM32, "MEM(32)"}, - {PCIIO_SPACE_MEM64, "MEM(64)"}, - {PCIIO_SPACE_CFG, "CFG"}, - {PCIIO_SPACE_WIN(0), "WIN(0)"}, - {PCIIO_SPACE_WIN(1), "WIN(1)"}, - {PCIIO_SPACE_WIN(2), "WIN(2)"}, - {PCIIO_SPACE_WIN(3), "WIN(3)"}, - {PCIIO_SPACE_WIN(4), "WIN(4)"}, - {PCIIO_SPACE_WIN(5), "WIN(5)"}, - {PCIIO_SPACE_BAD, "BAD"}, - {0} -}; - -struct reg_desc space_desc[] = -{ - {0xFF, 0, "space", 0, space_v}, - {0} -}; - -#if DEBUG -#define device_desc device_bits -LOCAL struct reg_desc device_bits[] = -{ - {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"}, - {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"}, - {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"}, - {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"}, - {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"}, - {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"}, - {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"}, - {BRIDGE_DEV_RT, 0, "RT"}, - {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"}, - {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"}, - {BRIDGE_DEV_PREF, 0, "PREF"}, - {BRIDGE_DEV_PRECISE, 0, "PRECISE"}, - {BRIDGE_DEV_COH, 0, "COH"}, - {BRIDGE_DEV_BARRIER, 0, "BARRIER"}, - {BRIDGE_DEV_GBR, 0, "GBR"}, - {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"}, - {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"}, - {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"}, - {0} -}; -#endif /* DEBUG */ - -#ifdef SUPPORT_PRINTING_R_FORMAT -LOCAL struct reg_values xio_cmd_pactyp[] = -{ - {0x0, "RdReq"}, - {0x1, "RdResp"}, - {0x2, "WrReqWithResp"}, - {0x3, "WrResp"}, - {0x4, "WrReqNoResp"}, - {0x5, "Reserved(5)"}, - {0x6, "FetchAndOp"}, - {0x7, "Reserved(7)"}, - {0x8, "StoreAndOp"}, - {0x9, "Reserved(9)"}, - {0xa, "Reserved(a)"}, - {0xb, "Reserved(b)"}, - {0xc, "Reserved(c)"}, - {0xd, "Reserved(d)"}, - {0xe, "SpecialReq"}, - {0xf, "SpecialResp"}, - {0} -}; - -LOCAL struct reg_desc xio_cmd_bits[] = -{ - {WIDGET_DIDN, -28, "DIDN", "%x"}, - {WIDGET_SIDN, -24, "SIDN", "%x"}, - {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp}, - {WIDGET_TNUM, -15, "TNUM", "%x"}, - {WIDGET_COHERENT, 0, "COHERENT"}, - {WIDGET_DS, 0, "DS"}, - {WIDGET_GBR, 0, "GBR"}, - {WIDGET_VBPM, 0, "VBPM"}, - {WIDGET_ERROR, 0, "ERROR"}, - {WIDGET_BARRIER, 0, "BARRIER"}, - {0} -}; -#endif /* SUPPORT_PRINTING_R_FORMAT */ - -#if PCIBR_FREEZE_TIME || PCIBR_ATE_DEBUG -LOCAL struct reg_desc ate_bits[] = -{ - {0xFFFF000000000000ull, -48, "RMF", "%x"}, - {~(IOPGSIZE - 1) & /* may trim off some low bits */ - 0x0000FFFFFFFFF000ull, 0, "XIO", "%x"}, - {0x0000000000000F00ull, -8, "port", "%x"}, - {0x0000000000000010ull, 0, "Barrier"}, - {0x0000000000000008ull, 0, "Prefetch"}, - {0x0000000000000004ull, 0, "Precise"}, - {0x0000000000000002ull, 0, "Coherent"}, - {0x0000000000000001ull, 0, "Valid"}, - {0} -}; -#endif - -#if PCIBR_ATE_DEBUG -LOCAL struct reg_values ssram_sizes[] = -{ - {BRIDGE_CTRL_SSRAM_512K, "512k"}, - {BRIDGE_CTRL_SSRAM_128K, "128k"}, - {BRIDGE_CTRL_SSRAM_64K, "64k"}, - {BRIDGE_CTRL_SSRAM_1K, "1k"}, - {0} -}; - -LOCAL struct reg_desc control_bits[] = -{ - {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"}, - {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"}, - {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"}, - {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"}, - {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"}, - {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"}, - {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"}, - {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"}, - {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"}, - {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"}, - {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes}, - {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"}, - {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"}, - {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"}, - {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"}, - {BRIDGE_CTRL_SYS_END, 0, "SYS_END"}, - {BRIDGE_CTRL_MAX_TRANS_MASK, -4, "MAX_TRANS", "%d"}, - {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"}, - {0} -}; -#endif -#endif /* LATER */ - -/* kbrick widgetnum-to-bus layout */ -int p_busnum[MAX_PORT_NUM] = { /* widget# */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ - 2, /* 0x8 */ - 1, /* 0x9 */ - 0, 0, /* 0xa - 0xb */ - 5, /* 0xc */ - 6, /* 0xd */ - 4, /* 0xe */ - 3, /* 0xf */ -}; - -/* - * Additional PIO spaces per slot are - * recorded in this structure. - */ -struct pciio_piospace_s { - pciio_piospace_t next; /* another space for this device */ - char free; /* 1 if free, 0 if in use */ - pciio_space_t space; /* Which space is in use */ - iopaddr_t start; /* Starting address of the PIO space */ - size_t count; /* size of PIO space */ -}; - -#if PCIBR_SOFT_LIST -pcibr_list_p pcibr_list = 0; -#endif - -#define INFO_LBL_PCIBR_ASIC_REV "_pcibr_asic_rev" - -#define PCIBR_D64_BASE_UNSET (0xFFFFFFFFFFFFFFFF) -#define PCIBR_D32_BASE_UNSET (0xFFFFFFFF) - -#define PCIBR_VALID_SLOT(s) (s < 8) - -#ifdef SN_XXX -extern int hub_device_flags_set(devfs_handle_t widget_dev, - hub_widget_flags_t flags); -#endif -extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t); -extern void free_pciio_dmamap(pcibr_dmamap_t); - -/* - * This is the file operation table for the pcibr driver. - * As each of the functions are implemented, put the - * appropriate function name below. - */ -struct file_operations pcibr_fops = { - owner: THIS_MODULE, - llseek: NULL, - read: NULL, - write: NULL, - readdir: NULL, - poll: NULL, - ioctl: NULL, - mmap: NULL, - open: NULL, - flush: NULL, - release: NULL, - fsync: NULL, - fasync: NULL, - lock: NULL, - readv: NULL, - writev: NULL -}; - -extern devfs_handle_t hwgraph_root; -extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl); -extern int cap_able(uint64_t x); -extern uint64_t rmalloc(struct map *mp, size_t size); -extern void rmfree(struct map *mp, size_t size, uint64_t a); -extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen); -extern long atoi(register char *p); -extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen); -extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl); -extern graph_error_t hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr); -extern struct map *rmallocmap(uint64_t mapsiz); -extern void rmfreemap(struct map *mp); -extern int compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr); -extern int io_path_map_widget(devfs_handle_t vertex); - - - -/* ===================================================================== - * Function Table of Contents - * - * The order of functions in this file has stopped - * making much sense. We might want to take a look - * at it some time and bring back some sanity, or - * perhaps bust this file into smaller chunks. - */ - -LOCAL void do_pcibr_rrb_clear(bridge_t *, int); -LOCAL void do_pcibr_rrb_flush(bridge_t *, int); -LOCAL int do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t); -LOCAL int do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t); -LOCAL int do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int); -LOCAL int do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int); - -LOCAL void do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int); - -int pcibr_wrb_flush(devfs_handle_t); -int pcibr_rrb_alloc(devfs_handle_t, int *, int *); -int pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *); -int pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int); -void pcibr_rrb_flush(devfs_handle_t); - -LOCAL int pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t); -void pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t); - -LOCAL void pcibr_clearwidint(bridge_t *); -LOCAL void pcibr_setwidint(xtalk_intr_t); -LOCAL int pcibr_probe_slot(bridge_t *, cfg_p, unsigned *); - -void pcibr_init(void); -int pcibr_attach(devfs_handle_t); -int pcibr_detach(devfs_handle_t); -int pcibr_open(devfs_handle_t *, int, int, cred_t *); -int pcibr_close(devfs_handle_t, int, int, cred_t *); -int pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); -int pcibr_unmap(devfs_handle_t, vhandl_t *); -int pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); - -void pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t); - -LOCAL int pcibr_init_ext_ate_ram(bridge_t *); -LOCAL int pcibr_ate_alloc(pcibr_soft_t, int); -LOCAL void pcibr_ate_free(pcibr_soft_t, int, int); - -LOCAL pcibr_info_t pcibr_info_get(devfs_handle_t); -LOCAL pcibr_info_t pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); -LOCAL void pcibr_device_info_free(devfs_handle_t, pciio_slot_t); -LOCAL iopaddr_t pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned); - -pcibr_piomap_t pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); -void pcibr_piomap_free(pcibr_piomap_t); -caddr_t pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t); -void pcibr_piomap_done(pcibr_piomap_t); -caddr_t pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); -iopaddr_t pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); -void pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); - -LOCAL iopaddr_t pcibr_flags_to_d64(unsigned, pcibr_soft_t); -LOCAL bridge_ate_t pcibr_flags_to_ate(unsigned); - -pcibr_dmamap_t pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); -void pcibr_dmamap_free(pcibr_dmamap_t); -LOCAL bridge_ate_p pcibr_ate_addr(pcibr_soft_t, int); -LOCAL iopaddr_t pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t); -iopaddr_t pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t); -alenlist_t pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned); -void pcibr_dmamap_done(pcibr_dmamap_t); -cnodeid_t pcibr_get_dmatrans_node(devfs_handle_t); -iopaddr_t pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); -void pcibr_dmamap_drain(pcibr_dmamap_t); -void pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); -void pcibr_dmalist_drain(devfs_handle_t, alenlist_t); -iopaddr_t pcibr_dmamap_pciaddr_get(pcibr_dmamap_t); - -static unsigned pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines); -pcibr_intr_t pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); -void pcibr_intr_free(pcibr_intr_t); -LOCAL void pcibr_setpciint(xtalk_intr_t); -int pcibr_intr_connect(pcibr_intr_t); -void pcibr_intr_disconnect(pcibr_intr_t); - -devfs_handle_t pcibr_intr_cpu_get(pcibr_intr_t); -void pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); -void pcibr_intr_func(intr_arg_t); - -void pcibr_provider_startup(devfs_handle_t); -void pcibr_provider_shutdown(devfs_handle_t); - -int pcibr_reset(devfs_handle_t); -pciio_endian_t pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); -int pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t); -pciio_priority_t pcibr_priority_set(devfs_handle_t, pciio_priority_t); -int pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t); - -LOCAL cfg_p pcibr_config_addr(devfs_handle_t, unsigned); -uint64_t pcibr_config_get(devfs_handle_t, unsigned, unsigned); -LOCAL uint64_t do_pcibr_config_get(cfg_p, unsigned, unsigned); -void pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t); -LOCAL void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); - -LOCAL pcibr_hints_t pcibr_hints_get(devfs_handle_t, int); -void pcibr_hints_fix_rrbs(devfs_handle_t); -void pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t); -void pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *); -void pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t); -void pcibr_hints_handsoff(devfs_handle_t); -void pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong); - -LOCAL int pcibr_slot_info_init(devfs_handle_t,pciio_slot_t); -LOCAL int pcibr_slot_info_free(devfs_handle_t,pciio_slot_t); - -#ifdef LATER -LOCAL int pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t, - pcibr_slot_info_resp_t); -LOCAL void pcibr_slot_func_info_return(pcibr_info_h, int, - pcibr_slot_func_info_resp_t); -#endif /* LATER */ - -LOCAL int pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t); -LOCAL int pcibr_slot_device_init(devfs_handle_t, pciio_slot_t); -LOCAL int pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t); -LOCAL int pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t); -LOCAL int pcibr_slot_call_device_attach(devfs_handle_t, - pciio_slot_t, int); -LOCAL int pcibr_slot_call_device_detach(devfs_handle_t, - pciio_slot_t, int); - -LOCAL int pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int); -LOCAL int pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t); -#ifdef LATER -LOCAL int pcibr_slot_query(devfs_handle_t, pcibr_slot_info_req_t); -#endif - -/* ===================================================================== - * RRB management - */ - -#define LSBIT(word) ((word) &~ ((word)-1)) - -#define PCIBR_RRB_SLOT_VIRTUAL 8 - -LOCAL void -do_pcibr_rrb_clear(bridge_t *bridge, int rrb) -{ - bridgereg_t status; - - /* bridge_lock must be held; - * this RRB must be disabled. - */ - - /* wait until RRB has no outstanduing XIO packets. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - - /* if the RRB has data, drain it. */ - if (status & BRIDGE_RRB_VALID(rrb)) { - bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); - - /* wait until RRB is no longer valid. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - } -} - -LOCAL void -do_pcibr_rrb_flush(bridge_t *bridge, int rrbn) -{ - reg_p rrbp = &bridge->b_rrb_map[rrbn & 1].reg; - bridgereg_t rrbv; - int shft = 4 * (rrbn >> 1); - unsigned ebit = BRIDGE_RRB_EN << shft; - - rrbv = *rrbp; - if (rrbv & ebit) - *rrbp = rrbv & ~ebit; - - do_pcibr_rrb_clear(bridge, rrbn); - - if (rrbv & ebit) - *rrbp = rrbv; -} - -/* - * pcibr_rrb_count_valid: count how many RRBs are - * marked valid for the specified PCI slot on this - * bridge. - * - * NOTE: The "slot" parameter for all pcibr_rrb - * management routines must include the "virtual" - * bit; when manageing both the normal and the - * virtual channel, separate calls to these - * routines must be made. To denote the virtual - * channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot - * number. - * - * IMPL NOTE: The obvious algorithm is to iterate - * through the RRB fields, incrementing a count if - * the RRB is valid and matches the slot. However, - * it is much simpler to use an algorithm derived - * from the "partitioned add" idea. First, XOR in a - * pattern such that the fields that match this - * slot come up "all ones" and all other fields - * have zeros in the mismatching bits. Then AND - * together the bits in the field, so we end up - * with one bit turned on for each field that - * matched. Now we need to count these bits. This - * can be done either with a series of shift/add - * instructions or by using "tmp % 15"; I expect - * that the cascaded shift/add will be faster. - */ - -LOCAL int -do_pcibr_rrb_count_valid(bridge_t *bridge, - pciio_slot_t slot) -{ - bridgereg_t tmp; - - tmp = bridge->b_rrb_map[slot & 1].reg; - tmp ^= 0x11111111 * (7 - slot / 2); - tmp &= (0xCCCCCCCC & tmp) >> 2; - tmp &= (0x22222222 & tmp) >> 1; - tmp += tmp >> 4; - tmp += tmp >> 8; - tmp += tmp >> 16; - return tmp & 15; -} - -/* - * do_pcibr_rrb_count_avail: count how many RRBs are - * available to be allocated for the specified slot. - * - * IMPL NOTE: similar to the above, except we are - * just counting how many fields have the valid bit - * turned off. - */ -LOCAL int -do_pcibr_rrb_count_avail(bridge_t *bridge, - pciio_slot_t slot) -{ - bridgereg_t tmp; - - tmp = bridge->b_rrb_map[slot & 1].reg; - tmp = (0x88888888 & ~tmp) >> 3; - tmp += tmp >> 4; - tmp += tmp >> 8; - tmp += tmp >> 16; - return tmp & 15; -} - -/* - * do_pcibr_rrb_alloc: allocate some additional RRBs - * for the specified slot. Returns -1 if there were - * insufficient free RRBs to satisfy the request, - * or 0 if the request was fulfilled. - * - * Note that if a request can be partially filled, - * it will be, even if we return failure. - * - * IMPL NOTE: again we avoid iterating across all - * the RRBs; instead, we form up a word containing - * one bit for each free RRB, then peel the bits - * off from the low end. - */ -LOCAL int -do_pcibr_rrb_alloc(bridge_t *bridge, - pciio_slot_t slot, - int more) -{ - int rv = 0; - bridgereg_t reg, tmp, bit; - - reg = bridge->b_rrb_map[slot & 1].reg; - tmp = (0x88888888 & ~reg) >> 3; - while (more-- > 0) { - bit = LSBIT(tmp); - if (!bit) { - rv = -1; - break; - } - tmp &= ~bit; - reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2))); - } - bridge->b_rrb_map[slot & 1].reg = reg; - return rv; -} - -/* - * do_pcibr_rrb_free: release some of the RRBs that - * have been allocated for the specified - * slot. Returns zero for success, or negative if - * it was unable to free that many RRBs. - * - * IMPL NOTE: We form up a bit for each RRB - * allocated to the slot, aligned with the VALID - * bitfield this time; then we peel bits off one at - * a time, releasing the corresponding RRB. - */ -LOCAL int -do_pcibr_rrb_free(bridge_t *bridge, - pciio_slot_t slot, - int less) -{ - int rv = 0; - bridgereg_t reg, tmp, clr, bit; - int i; - - clr = 0; - reg = bridge->b_rrb_map[slot & 1].reg; - - /* This needs to be done otherwise the rrb's on the virtual channel - * for this slot won't be freed !! - */ - tmp = reg & 0xbbbbbbbb; - - tmp ^= (0x11111111 * (7 - slot / 2)); - tmp &= (0x33333333 & tmp) << 2; - tmp &= (0x44444444 & tmp) << 1; - while (less-- > 0) { - bit = LSBIT(tmp); - if (!bit) { - rv = -1; - break; - } - tmp &= ~bit; - reg &= ~bit; - clr |= bit; - } - bridge->b_rrb_map[slot & 1].reg = reg; - - for (i = 0; i < 8; i++) - if (clr & (8 << (4 * i))) - do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1)); - - return rv; -} - -LOCAL void -do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft, - int slot, - int more_rrbs) -{ - bridge_t *bridge = pcibr_soft->bs_base; - int got; - - for (got = 0; got < more_rrbs; ++got) { - if (pcibr_soft->bs_rrb_res[slot & 7] > 0) - pcibr_soft->bs_rrb_res[slot & 7]--; - else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0) - pcibr_soft->bs_rrb_avail[slot & 1]--; - else - break; - if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0) - break; -#if PCIBR_RRB_DEBUG - printk( "do_pcibr_rrb_autoalloc: add one to slot %d%s\n", - slot & 7, slot & 8 ? "v" : ""); -#endif - pcibr_soft->bs_rrb_valid[slot]++; - } -#if PCIBR_RRB_DEBUG - printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name, - pcibr_soft->bs_rrb_avail[0], - pcibr_soft->bs_rrb_avail[1]); - for (slot = 0; slot < 8; ++slot) - printk("\t%d+%d+%d", - 0xFFF & pcibr_soft->bs_rrb_valid[slot], - 0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], - pcibr_soft->bs_rrb_res[slot]); - printk("\n"); -#endif -} - -/* - * Device driver interface to flush the write buffers for a specified - * device hanging off the bridge. - */ -int -pcibr_wrb_flush(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - volatile bridgereg_t *wrb_flush; - - wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg); - while (*wrb_flush); - - return(0); -} -/* - * Device driver interface to request RRBs for a specified device - * hanging off a Bridge. The driver requests the total number of - * RRBs it would like for the normal channel (vchan0) and for the - * "virtual channel" (vchan1). The actual number allocated to each - * channel is returned. - * - * If we cannot allocate at least one RRB to a channel that needs - * at least one, return -1 (failure). Otherwise, satisfy the request - * as best we can and return 0. - */ -int -pcibr_rrb_alloc(devfs_handle_t pconn_vhdl, - int *count_vchan0, - int *count_vchan1) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - int desired_vchan0; - int desired_vchan1; - int orig_vchan0; - int orig_vchan1; - int delta_vchan0; - int delta_vchan1; - int final_vchan0; - int final_vchan1; - int avail_rrbs; - unsigned long s; - int error; - - /* - * TBD: temper request with admin info about RRB allocation, - * and according to demand from other devices on this Bridge. - * - * One way of doing this would be to allocate two RRBs - * for each device on the bus, before any drivers start - * asking for extras. This has the weakness that one - * driver might not give back an "extra" RRB until after - * another driver has already failed to get one that - * it wanted. - */ - - s = pcibr_lock(pcibr_soft); - - /* How many RRBs do we own? */ - orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot]; - orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL]; - - /* How many RRBs do we want? */ - desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0; - desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1; - - /* How many RRBs are free? */ - avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1] - + pcibr_soft->bs_rrb_res[pciio_slot]; - - /* Figure desired deltas */ - delta_vchan0 = desired_vchan0 - orig_vchan0; - delta_vchan1 = desired_vchan1 - orig_vchan1; - - /* Trim back deltas to something - * that we can actually meet, by - * decreasing the ending allocation - * for whichever channel wants - * more RRBs. If both want the same - * number, cut the second channel. - * NOTE: do not change the allocation for - * a channel that was passed as NULL. - */ - while ((delta_vchan0 + delta_vchan1) > avail_rrbs) { - if (count_vchan0 && - (!count_vchan1 || - ((orig_vchan0 + delta_vchan0) > - (orig_vchan1 + delta_vchan1)))) - delta_vchan0--; - else - delta_vchan1--; - } - - /* Figure final RRB allocations - */ - final_vchan0 = orig_vchan0 + delta_vchan0; - final_vchan1 = orig_vchan1 + delta_vchan1; - - /* If either channel wants RRBs but our actions - * would leave it with none, declare an error, - * but DO NOT change any RRB allocations. - */ - if ((desired_vchan0 && !final_vchan0) || - (desired_vchan1 && !final_vchan1)) { - - error = -1; - - } else { - - /* Commit the allocations: free, then alloc. - */ - if (delta_vchan0 < 0) - (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0); - if (delta_vchan1 < 0) - (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1); - - if (delta_vchan0 > 0) - (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0); - if (delta_vchan1 > 0) - (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1); - - /* Return final values to caller. - */ - if (count_vchan0) - *count_vchan0 = final_vchan0; - if (count_vchan1) - *count_vchan1 = final_vchan1; - - /* prevent automatic changes to this slot's RRBs - */ - pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot; - - /* Track the actual allocations, release - * any further reservations, and update the - * number of available RRBs. - */ - - pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0; - pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1; - pcibr_soft->bs_rrb_avail[pciio_slot & 1] = - pcibr_soft->bs_rrb_avail[pciio_slot & 1] - + pcibr_soft->bs_rrb_res[pciio_slot] - - delta_vchan0 - - delta_vchan1; - pcibr_soft->bs_rrb_res[pciio_slot] = 0; - -#if PCIBR_RRB_DEBUG - printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n", - pciio_slot, final_vchan0, final_vchan1, - pcibr_soft->bs_rrb_avail[0], - pcibr_soft->bs_rrb_avail[1]); - for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot) - printk("\t%d+%d+%d", - 0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot], - 0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL], - pcibr_soft->bs_rrb_res[pciio_slot]); - printk("\n"); -#endif - - error = 0; - } - - pcibr_unlock(pcibr_soft, s); - return error; -} - -/* - * Device driver interface to check the current state - * of the RRB allocations. - * - * pconn_vhdl is your PCI connection point (specifies which - * PCI bus and which slot). - * - * count_vchan0 points to where to return the number of RRBs - * assigned to the primary DMA channel, used by all DMA - * that does not explicitly ask for the alternate virtual - * channel. - * - * count_vchan1 points to where to return the number of RRBs - * assigned to the secondary DMA channel, used when - * PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified. - * - * count_reserved points to where to return the number of RRBs - * that have been automatically reserved for your device at - * startup, but which have not been assigned to a - * channel. RRBs must be assigned to a channel to be used; - * this can be done either with an explicit pcibr_rrb_alloc - * call, or automatically by the infrastructure when a DMA - * translation is constructed. Any call to pcibr_rrb_alloc - * will release any unassigned reserved RRBs back to the - * free pool. - * - * count_pool points to where to return the number of RRBs - * that are currently unassigned and unreserved. This - * number can (and will) change as other drivers make calls - * to pcibr_rrb_alloc, or automatically allocate RRBs for - * DMA beyond their initial reservation. - * - * NULL may be passed for any of the return value pointers - * the caller is not interested in. - * - * The return value is "0" if all went well, or "-1" if - * there is a problem. Additionally, if the wrong vertex - * is passed in, one of the subsidiary support functions - * could panic with a "bad pciio fingerprint." - */ - -int -pcibr_rrb_check(devfs_handle_t pconn_vhdl, - int *count_vchan0, - int *count_vchan1, - int *count_reserved, - int *count_pool) -{ - pciio_info_t pciio_info; - pciio_slot_t pciio_slot; - pcibr_soft_t pcibr_soft; - unsigned long s; - int error = -1; - - if ((pciio_info = pciio_info_get(pconn_vhdl)) && - (pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) && - ((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) { - - s = pcibr_lock(pcibr_soft); - - if (count_vchan0) - *count_vchan0 = - pcibr_soft->bs_rrb_valid[pciio_slot]; - - if (count_vchan1) - *count_vchan1 = - pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL]; - - if (count_reserved) - *count_reserved = - pcibr_soft->bs_rrb_res[pciio_slot]; - - if (count_pool) - *count_pool = - pcibr_soft->bs_rrb_avail[pciio_slot & 1]; - - error = 0; - - pcibr_unlock(pcibr_soft, s); - } - return error; -} - -/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities - * requested for each of the devies. The evn_odd argument indicates whether - * allcoation for the odd or even rrbs is requested and next group of four pairse - * are the amount to assign to each device (they should sum to <= 8) and - * whether to set the viritual bit for that device (1 indictaes yes, 0 indicates no) - * the devices in order are either 0, 2, 4, 6 or 1, 3, 5, 7 - * if even_odd is even we alloc even rrbs else we allocate odd rrbs - * returns 0 if no errors else returns -1 - */ - -int -pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd, - int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2, - int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4) -{ - devfs_handle_t pcibr_vhdl; - pcibr_soft_t pcibr_soft = NULL; - bridge_t *bridge = NULL; - - uint32_t rrb_setting = 0; - int rrb_shift = 7; - uint32_t cur_rrb; - int dev_rrbs[4]; - int virt[4]; - int i, j; - unsigned long s; - - if (GRAPH_SUCCESS == - hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) { - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - if (pcibr_soft) - bridge = pcibr_soft->bs_base; - hwgraph_vertex_unref(pcibr_vhdl); - } - if (bridge == NULL) - bridge = (bridge_t *) xtalk_piotrans_addr - (vhdl, NULL, 0, sizeof(bridge_t), 0); - - even_odd &= 1; - - dev_rrbs[0] = dev_1_rrbs; - dev_rrbs[1] = dev_2_rrbs; - dev_rrbs[2] = dev_3_rrbs; - dev_rrbs[3] = dev_4_rrbs; - - virt[0] = virt1; - virt[1] = virt2; - virt[2] = virt3; - virt[3] = virt4; - - if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) { - return -1; - } - if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) { - return -1; - } - /* walk through rrbs */ - for (i = 0; i < 4; i++) { - if (virt[i]) { - cur_rrb = i | 0xc; - cur_rrb = cur_rrb << (rrb_shift * 4); - rrb_shift--; - rrb_setting = rrb_setting | cur_rrb; - dev_rrbs[i] = dev_rrbs[i] - 1; - } - for (j = 0; j < dev_rrbs[i]; j++) { - cur_rrb = i | 0x8; - cur_rrb = cur_rrb << (rrb_shift * 4); - rrb_shift--; - rrb_setting = rrb_setting | cur_rrb; - } - } - - if (pcibr_soft) - s = pcibr_lock(pcibr_soft); - - bridge->b_rrb_map[even_odd].reg = rrb_setting; - - if (pcibr_soft) { - - pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd; - - /* since we've "FIXED" the allocations - * for these slots, we probably can dispense - * with tracking avail/res/valid data, but - * keeping it up to date helps debugging. - */ - - pcibr_soft->bs_rrb_avail[even_odd] = - 8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs); - - pcibr_soft->bs_rrb_res[even_odd + 0] = 0; - pcibr_soft->bs_rrb_res[even_odd + 2] = 0; - pcibr_soft->bs_rrb_res[even_odd + 4] = 0; - pcibr_soft->bs_rrb_res[even_odd + 6] = 0; - - pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1; - pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2; - pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3; - pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4; - - pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1; - pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2; - pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3; - pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4; - - pcibr_unlock(pcibr_soft, s); - } - return 0; -} - -/* - * pcibr_rrb_flush: chase down all the RRBs assigned - * to the specified connection point, and flush - * them. - */ -void -pcibr_rrb_flush(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - unsigned long s; - reg_p rrbp; - unsigned rrbm; - int i; - int rrbn; - unsigned sval; - unsigned mask; - - sval = BRIDGE_RRB_EN | (pciio_slot >> 1); - mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV; - rrbn = pciio_slot & 1; - rrbp = &bridge->b_rrb_map[rrbn].reg; - - s = pcibr_lock(pcibr_soft); - rrbm = *rrbp; - for (i = 0; i < 8; ++i) { - if ((rrbm & mask) == sval) - do_pcibr_rrb_flush(bridge, rrbn); - rrbm >>= 4; - rrbn += 2; - } - pcibr_unlock(pcibr_soft, s); -} - -/* ===================================================================== - * Device(x) register management - */ - -/* pcibr_try_set_device: attempt to modify Device(x) - * for the specified slot on the specified bridge - * as requested in flags, limited to the specified - * bits. Returns which BRIDGE bits were in conflict, - * or ZERO if everything went OK. - * - * Caller MUST hold pcibr_lock when calling this function. - */ -LOCAL int -pcibr_try_set_device(pcibr_soft_t pcibr_soft, - pciio_slot_t slot, - unsigned flags, - bridgereg_t mask) -{ - bridge_t *bridge; - pcibr_soft_slot_t slotp; - bridgereg_t old; - bridgereg_t new; - bridgereg_t chg; - bridgereg_t bad; - bridgereg_t badpmu; - bridgereg_t badd32; - bridgereg_t badd64; - bridgereg_t fix; - unsigned long s; - bridgereg_t xmask; - - xmask = mask; - if (pcibr_soft->bs_xbridge) { - if (mask == BRIDGE_DEV_PMU_BITS) - xmask = XBRIDGE_DEV_PMU_BITS; - if (mask == BRIDGE_DEV_D64_BITS) - xmask = XBRIDGE_DEV_D64_BITS; - } - - slotp = &pcibr_soft->bs_slot[slot]; - - s = pcibr_lock(pcibr_soft); - - bridge = pcibr_soft->bs_base; - - old = slotp->bss_device; - - /* figure out what the desired - * Device(x) bits are based on - * the flags specified. - */ - - new = old; - - /* Currently, we inherit anything that - * the new caller has not specified in - * one way or another, unless we take - * action here to not inherit. - * - * This is needed for the "swap" stuff, - * since it could have been set via - * pcibr_endian_set -- altho note that - * any explicit PCIBR_BYTE_STREAM or - * PCIBR_WORD_VALUES will freely override - * the effect of that call (and vice - * versa, no protection either way). - * - * I want to get rid of pcibr_endian_set - * in favor of tracking DMA endianness - * using the flags specified when DMA - * channels are created. - */ - -#define BRIDGE_DEV_WRGA_BITS (BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN) -#define BRIDGE_DEV_SWAP_BITS (BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR) - - /* Do not use Barrier, Write Gather, - * or Prefetch unless asked. - * Leave everything else as it - * was from the last time. - */ - new = new - & ~BRIDGE_DEV_BARRIER - & ~BRIDGE_DEV_WRGA_BITS - & ~BRIDGE_DEV_PREF - ; - - /* Generic macro flags - */ - if (flags & PCIIO_DMA_DATA) { - new = (new - & ~BRIDGE_DEV_BARRIER) /* barrier off */ - | BRIDGE_DEV_PREF; /* prefetch on */ - - } - if (flags & PCIIO_DMA_CMD) { - new = ((new - & ~BRIDGE_DEV_PREF) /* prefetch off */ - & ~BRIDGE_DEV_WRGA_BITS) /* write gather off */ - | BRIDGE_DEV_BARRIER; /* barrier on */ - } - /* Generic detail flags - */ - if (flags & PCIIO_WRITE_GATHER) - new |= BRIDGE_DEV_WRGA_BITS; - if (flags & PCIIO_NOWRITE_GATHER) - new &= ~BRIDGE_DEV_WRGA_BITS; - - if (flags & PCIIO_PREFETCH) - new |= BRIDGE_DEV_PREF; - if (flags & PCIIO_NOPREFETCH) - new &= ~BRIDGE_DEV_PREF; - - if (flags & PCIBR_WRITE_GATHER) - new |= BRIDGE_DEV_WRGA_BITS; - if (flags & PCIBR_NOWRITE_GATHER) - new &= ~BRIDGE_DEV_WRGA_BITS; - - if (flags & PCIIO_BYTE_STREAM) - new |= (pcibr_soft->bs_xbridge) ? - BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS; - if (flags & PCIIO_WORD_VALUES) - new &= (pcibr_soft->bs_xbridge) ? - ~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS; - - /* Provider-specific flags - */ - if (flags & PCIBR_PREFETCH) - new |= BRIDGE_DEV_PREF; - if (flags & PCIBR_NOPREFETCH) - new &= ~BRIDGE_DEV_PREF; - - if (flags & PCIBR_PRECISE) - new |= BRIDGE_DEV_PRECISE; - if (flags & PCIBR_NOPRECISE) - new &= ~BRIDGE_DEV_PRECISE; - - if (flags & PCIBR_BARRIER) - new |= BRIDGE_DEV_BARRIER; - if (flags & PCIBR_NOBARRIER) - new &= ~BRIDGE_DEV_BARRIER; - - if (flags & PCIBR_64BIT) - new |= BRIDGE_DEV_DEV_SIZE; - if (flags & PCIBR_NO64BIT) - new &= ~BRIDGE_DEV_DEV_SIZE; - - chg = old ^ new; /* what are we changing, */ - chg &= xmask; /* of the interesting bits */ - - if (chg) { - - badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0; - if (pcibr_soft->bs_xbridge) { - badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0; - badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0; - } else { - badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0; - badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0; - } - bad = badpmu | badd32 | badd64; - - if (bad) { - - /* some conflicts can be resolved by - * forcing the bit on. this may cause - * some performance degredation in - * the stream(s) that want the bit off, - * but the alternative is not allowing - * the new stream at all. - */ - if ( (fix = bad & (BRIDGE_DEV_PRECISE | - BRIDGE_DEV_BARRIER)) ){ - bad &= ~fix; - /* don't change these bits if - * they are already set in "old" - */ - chg &= ~(fix & old); - } - /* some conflicts can be resolved by - * forcing the bit off. this may cause - * some performance degredation in - * the stream(s) that want the bit on, - * but the alternative is not allowing - * the new stream at all. - */ - if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS | - BRIDGE_DEV_PREF)) ) { - bad &= ~fix; - /* don't change these bits if - * we wanted to turn them on. - */ - chg &= ~(fix & new); - } - /* conflicts in other bits mean - * we can not establish this DMA - * channel while the other(s) are - * still present. - */ - if (bad) { - pcibr_unlock(pcibr_soft, s); -#if (DEBUG && PCIBR_DEV_DEBUG) - printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits); -#endif - return bad; - } - } - } - if (mask == BRIDGE_DEV_PMU_BITS) - slotp->bss_pmu_uctr++; - if (mask == BRIDGE_DEV_D32_BITS) - slotp->bss_d32_uctr++; - if (mask == BRIDGE_DEV_D64_BITS) - slotp->bss_d64_uctr++; - - /* the value we want to write is the - * original value, with the bits for - * our selected changes flipped, and - * with any disabled features turned off. - */ - new = old ^ chg; /* only change what we want to change */ - - if (slotp->bss_device == new) { - pcibr_unlock(pcibr_soft, s); - return 0; - } - bridge->b_device[slot].reg = new; - slotp->bss_device = new; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - pcibr_unlock(pcibr_soft, s); -#if DEBUG && PCIBR_DEV_DEBUG - printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg); -#endif - - return 0; -} - -void -pcibr_release_device(pcibr_soft_t pcibr_soft, - pciio_slot_t slot, - bridgereg_t mask) -{ - pcibr_soft_slot_t slotp; - unsigned long s; - - slotp = &pcibr_soft->bs_slot[slot]; - - s = pcibr_lock(pcibr_soft); - - if (mask == BRIDGE_DEV_PMU_BITS) - slotp->bss_pmu_uctr--; - if (mask == BRIDGE_DEV_D32_BITS) - slotp->bss_d32_uctr--; - if (mask == BRIDGE_DEV_D64_BITS) - slotp->bss_d64_uctr--; - - pcibr_unlock(pcibr_soft, s); -} - -/* - * flush write gather buffer for slot - */ -LOCAL void -pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft, - pciio_slot_t slot) -{ - bridge_t *bridge; - unsigned long s; - volatile uint32_t wrf; - s = pcibr_lock(pcibr_soft); - bridge = pcibr_soft->bs_base; - wrf = bridge->b_wr_req_buf[slot].reg; - pcibr_unlock(pcibr_soft, s); -} - -/* ===================================================================== - * Bridge (pcibr) "Device Driver" entry points - */ - -/* - * pcibr_probe_slot: read a config space word - * while trapping any errors; reutrn zero if - * all went OK, or nonzero if there was an error. - * The value read, if any, is passed back - * through the valp parameter. - */ -LOCAL int -pcibr_probe_slot(bridge_t *bridge, - cfg_p cfg, - unsigned *valp) -{ - int rv; - bridgereg_t old_enable, new_enable; - int badaddr_val(volatile void *, int, volatile void *); - - - old_enable = bridge->b_int_enable; - new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - - bridge->b_int_enable = new_enable; - - /* - * The xbridge doesn't clear b_err_int_view unless - * multi-err is cleared... - */ - if (is_xbridge(bridge)) - if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) { - bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; - } - - if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) { - bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR; - (void) bridge->b_wid_tflush; /* flushbus */ - } - rv = badaddr_val((void *) cfg, 4, valp); - - /* - * The xbridge doesn't set master timeout in b_int_status - * here. Fortunately it's in error_interrupt_view. - */ - if (is_xbridge(bridge)) - if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) { - bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; - rv = 1; /* unoccupied slot */ - } - - bridge->b_int_enable = old_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - - return rv; -} - -/* - * pcibr_init: called once during system startup or - * when a loadable driver is loaded. - * - * The driver_register function should normally - * be in _reg, not _init. But the pcibr driver is - * required by devinit before the _reg routines - * are called, so this is an exception. - */ -void -pcibr_init(void) -{ -#if DEBUG && ATTACH_DEBUG - printk("pcibr_init\n"); -#endif - - xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM, - XBRIDGE_WIDGET_MFGR_NUM, - "pcibr_", - 0); - xwidget_driver_register(BRIDGE_WIDGET_PART_NUM, - BRIDGE_WIDGET_MFGR_NUM, - "pcibr_", - 0); -} - -/* - * open/close mmap/munmap interface would be used by processes - * that plan to map the PCI bridge, and muck around with the - * registers. This is dangerous to do, and will be allowed - * to a select brand of programs. Typically these are - * diagnostics programs, or some user level commands we may - * write to do some weird things. - * To start with expect them to have root priveleges. - * We will ask for more later. - */ -/* ARGSUSED */ -int -pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) -{ - return 0; -} - -/*ARGSUSED */ -int -pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) -{ - return 0; -} - -/*ARGSUSED */ -int -pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) -{ - int error; - devfs_handle_t vhdl = dev_to_vhdl(dev); - devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get(vhdl); - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge_t *bridge = pcibr_soft->bs_base; - - hwgraph_vertex_unref(pcibr_vhdl); - - ASSERT(pcibr_soft); - len = ctob(btoc(len)); /* Make len page aligned */ - error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len); - - /* - * If the offset being mapped corresponds to the flash prom - * base, and if the mapping succeeds, and if the user - * has requested the protections to be WRITE, enable the - * flash prom to be written. - * - * XXX- deprecate this in favor of using the - * real flash driver ... - */ - if (!error && - ((off == BRIDGE_EXTERNAL_FLASH) || - (len > BRIDGE_EXTERNAL_FLASH))) { - int s; - - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - s = splhi(); - bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN; - bridge->b_wid_control; /* inval addr bug war */ - splx(s); - } - return error; -} - -/*ARGSUSED */ -int -pcibr_unmap(devfs_handle_t dev, vhandl_t *vt) -{ - devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev); - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge_t *bridge = pcibr_soft->bs_base; - - hwgraph_vertex_unref(pcibr_vhdl); - - /* - * If flashprom write was enabled, disable it, as - * this is the last unmap. - */ - if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) { - int s; - - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - s = splhi(); - bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN; - bridge->b_wid_control; /* inval addr bug war */ - splx(s); - } - return 0; -} - -/* This is special case code used by grio. There are plans to make - * this a bit more general in the future, but till then this should - * be sufficient. - */ -pciio_slot_t -pcibr_device_slot_get(devfs_handle_t dev_vhdl) -{ - char devname[MAXDEVNAME]; - devfs_handle_t tdev; - pciio_info_t pciio_info; - pciio_slot_t slot = PCIIO_SLOT_NONE; - - vertex_to_name(dev_vhdl, devname, MAXDEVNAME); - - /* run back along the canonical path - * until we find a PCI connection point. - */ - tdev = hwgraph_connectpt_get(dev_vhdl); - while (tdev != GRAPH_VERTEX_NONE) { - pciio_info = pciio_info_chk(tdev); - if (pciio_info) { - slot = pciio_info_slot_get(pciio_info); - break; - } - hwgraph_vertex_unref(tdev); - tdev = hwgraph_connectpt_get(tdev); - } - hwgraph_vertex_unref(tdev); - - return slot; -} - -/*========================================================================== - * BRIDGE PCI SLOT RELATED IOCTLs - */ -char *pci_space_name[] = {"NONE", - "ROM", - "IO", - "", - "MEM", - "MEM32", - "MEM64", - "CFG", - "WIN0", - "WIN1", - "WIN2", - "WIN3", - "WIN4", - "WIN5", - "", - "BAD"}; - - -/*ARGSUSED */ -int -pcibr_ioctl(devfs_handle_t dev, - int cmd, - void *arg, - int flag, - struct cred *cr, - int *rvalp) -{ - devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev); -#ifdef LATER - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); -#endif - int error = 0; - - hwgraph_vertex_unref(pcibr_vhdl); - - switch (cmd) { -#ifdef LATER - case GIOCSETBW: - { - grio_ioctl_info_t info; - pciio_slot_t slot = 0; - - if (!cap_able((uint64_t)CAP_DEVICE_MGT)) { - error = EPERM; - break; - } - if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { - error = EFAULT; - break; - } -#ifdef GRIO_DEBUG - printk("pcibr:: prev_vhdl: %d reqbw: %lld\n", - info.prev_vhdl, info.reqbw); -#endif /* GRIO_DEBUG */ - - if ((slot = pcibr_device_slot_get(info.prev_vhdl)) == - PCIIO_SLOT_NONE) { - error = EIO; - break; - } - if (info.reqbw) - pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH); - break; - } - - case GIOCRELEASEBW: - { - grio_ioctl_info_t info; - pciio_slot_t slot = 0; - - if (!cap_able(CAP_DEVICE_MGT)) { - error = EPERM; - break; - } - if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { - error = EFAULT; - break; - } -#ifdef GRIO_DEBUG - printk("pcibr:: prev_vhdl: %d reqbw: %lld\n", - info.prev_vhdl, info.reqbw); -#endif /* GRIO_DEBUG */ - - if ((slot = pcibr_device_slot_get(info.prev_vhdl)) == - PCIIO_SLOT_NONE) { - error = EIO; - break; - } - if (info.reqbw) - pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW); - break; - } - - case PCIBR_SLOT_POWERUP: - { - pciio_slot_t slot; - - if (!cap_able(CAP_DEVICE_MGT)) { - error = EPERM; - break; - } - - slot = (pciio_slot_t)(uint64_t)arg; - error = pcibr_slot_powerup(pcibr_vhdl,slot); - break; - } - case PCIBR_SLOT_SHUTDOWN: - if (!cap_able(CAP_DEVICE_MGT)) { - error = EPERM; - break; - } - - slot = (pciio_slot_t)(uint64_t)arg; - error = pcibr_slot_powerup(pcibr_vhdl,slot); - break; - } - case PCIBR_SLOT_QUERY: - { - struct pcibr_slot_info_req_s req; - - if (!cap_able(CAP_DEVICE_MGT)) { - error = EPERM; - break; - } - - if (COPYIN(arg, &req, sizeof(req))) { - error = EFAULT; - break; - } - - error = pcibr_slot_query(pcibr_vhdl, &req); - break; - } -#endif /* LATER */ - default: - break; - - } - - return error; -} - -void -pcibr_freeblock_sub(iopaddr_t *free_basep, - iopaddr_t *free_lastp, - iopaddr_t base, - size_t size) -{ - iopaddr_t free_base = *free_basep; - iopaddr_t free_last = *free_lastp; - iopaddr_t last = base + size - 1; - - if ((last < free_base) || (base > free_last)); /* free block outside arena */ - - else if ((base <= free_base) && (last >= free_last)) - /* free block contains entire arena */ - *free_basep = *free_lastp = 0; - - else if (base <= free_base) - /* free block is head of arena */ - *free_basep = last + 1; - - else if (last >= free_last) - /* free block is tail of arena */ - *free_lastp = base - 1; - - /* - * We are left with two regions: the free area - * in the arena "below" the block, and the free - * area in the arena "above" the block. Keep - * the one that is bigger. - */ - - else if ((base - free_base) > (free_last - last)) - *free_lastp = base - 1; /* keep lower chunk */ - else - *free_basep = last + 1; /* keep upper chunk */ -} - -/* Convert from ssram_bits in control register to number of SSRAM entries */ -#define ATE_NUM_ENTRIES(n) _ate_info[n] - -/* Possible choices for number of ATE entries in Bridge's SSRAM */ -LOCAL int _ate_info[] = -{ - 0, /* 0 entries */ - 8 * 1024, /* 8K entries */ - 16 * 1024, /* 16K entries */ - 64 * 1024 /* 64K entries */ -}; - -#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int)) -#define ATE_PROBE_VALUE 0x0123456789abcdefULL - -/* - * Determine the size of this bridge's external mapping SSRAM, and set - * the control register appropriately to reflect this size, and initialize - * the external SSRAM. - */ -LOCAL int -pcibr_init_ext_ate_ram(bridge_t *bridge) -{ - int largest_working_size = 0; - int num_entries, entry; - int i, j; - bridgereg_t old_enable, new_enable; - int s; - - /* Probe SSRAM to determine its size. */ - old_enable = bridge->b_int_enable; - new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - bridge->b_int_enable = new_enable; - - for (i = 1; i < ATE_NUM_SIZES; i++) { - /* Try writing a value */ - bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE; - - /* Guard against wrap */ - for (j = 1; j < i; j++) - bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0; - - /* See if value was written */ - if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE) - largest_working_size = i; - } - bridge->b_int_enable = old_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - - s = splhi(); - bridge->b_wid_control = (bridge->b_wid_control - & ~BRIDGE_CTRL_SSRAM_SIZE_MASK) - | BRIDGE_CTRL_SSRAM_SIZE(largest_working_size); - bridge->b_wid_control; /* inval addr bug war */ - splx(s); - - num_entries = ATE_NUM_ENTRIES(largest_working_size); - -#if PCIBR_ATE_DEBUG - if (num_entries) - printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries); - else - printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge); -#endif - - /* Initialize external mapping entries */ - for (entry = 0; entry < num_entries; entry++) - bridge->b_ext_ate_ram[entry] = 0; - - return (num_entries); -} - -/* - * Allocate "count" contiguous Bridge Address Translation Entries - * on the specified bridge to be used for PCI to XTALK mappings. - * Indices in rm map range from 1..num_entries. Indicies returned - * to caller range from 0..num_entries-1. - * - * Return the start index on success, -1 on failure. - */ -LOCAL int -pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count) -{ - int index = 0; - - index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count); -/* printk("Colin: pcibr_ate_alloc - index %d count %d \n", index, count); */ - - if (!index && pcibr_soft->bs_ext_ate_map) - index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count); - - /* rmalloc manages resources in the 1..n - * range, with 0 being failure. - * pcibr_ate_alloc manages resources - * in the 0..n-1 range, with -1 being failure. - */ - return index - 1; -} - -LOCAL void -pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count) -/* Who says there's no such thing as a free meal? :-) */ -{ - /* note the "+1" since rmalloc handles 1..n but - * we start counting ATEs at zero. - */ -/* printk("Colin: pcibr_ate_free - index %d count %d\n", index, count); */ - - rmfree((index < pcibr_soft->bs_int_ate_size) - ? pcibr_soft->bs_int_ate_map - : pcibr_soft->bs_ext_ate_map, - count, index + 1); -} - -LOCAL pcibr_info_t -pcibr_info_get(devfs_handle_t vhdl) -{ - return (pcibr_info_t) pciio_info_get(vhdl); -} - -pcibr_info_t -pcibr_device_info_new( - pcibr_soft_t pcibr_soft, - pciio_slot_t slot, - pciio_function_t rfunc, - pciio_vendor_id_t vendor, - pciio_device_id_t device) -{ - pcibr_info_t pcibr_info; - pciio_function_t func; - int ibit; - - func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc; - - NEW(pcibr_info); - pciio_device_info_new(&pcibr_info->f_c, - pcibr_soft->bs_vhdl, - slot, rfunc, - vendor, device); - - if (slot != PCIIO_SLOT_NONE) { - - /* - * Currently favored mapping from PCI - * slot number and INTA/B/C/D to Bridge - * PCI Interrupt Bit Number: - * - * SLOT A B C D - * 0 0 4 0 4 - * 1 1 5 1 5 - * 2 2 6 2 6 - * 3 3 7 3 7 - * 4 4 0 4 0 - * 5 5 1 5 1 - * 6 6 2 6 2 - * 7 7 3 7 3 - * - * XXX- allow pcibr_hints to override default - * XXX- allow ADMIN to override pcibr_hints - */ - for (ibit = 0; ibit < 4; ++ibit) - pcibr_info->f_ibit[ibit] = - (slot + 4 * ibit) & 7; - - /* - * Record the info in the sparse func info space. - */ - if (func < pcibr_soft->bs_slot[slot].bss_ninfo) - pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info; - } - return pcibr_info; -} - -void -pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); - pcibr_info_t pcibr_info; - pciio_function_t func; - pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[slot]; - int nfunc = slotp->bss_ninfo; - - - for (func = 0; func < nfunc; func++) { - pcibr_info = slotp->bss_infos[func]; - - if (!pcibr_info) - continue; - - slotp->bss_infos[func] = 0; - pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c); - pciio_device_info_free(&pcibr_info->f_c); - DEL(pcibr_info); - } - - /* Clear the DEVIO(x) for this slot */ - slotp->bss_devio.bssd_space = PCIIO_SPACE_NONE; - slotp->bss_devio.bssd_base = PCIBR_D32_BASE_UNSET; - slotp->bss_device = 0; - - - /* Reset the mapping usage counters */ - slotp->bss_pmu_uctr = 0; - slotp->bss_d32_uctr = 0; - slotp->bss_d64_uctr = 0; - - /* Clear the Direct translation info */ - slotp->bss_d64_base = PCIBR_D64_BASE_UNSET; - slotp->bss_d64_flags = 0; - slotp->bss_d32_base = PCIBR_D32_BASE_UNSET; - slotp->bss_d32_flags = 0; - - /* Clear out shadow info necessary for the external SSRAM workaround */ - slotp->bss_ext_ates_active = ATOMIC_INIT(0); - slotp->bss_cmd_pointer = 0; - slotp->bss_cmd_shadow = 0; - -} - -/* - * PCI_ADDR_SPACE_LIMITS_LOAD - * Gets the current values of - * pci io base, - * pci io last, - * pci low memory base, - * pci low memory last, - * pci high memory base, - * pci high memory last - */ -#define PCI_ADDR_SPACE_LIMITS_LOAD() \ - pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base; \ - pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last; \ - pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base; \ - pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last; \ - pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base; \ - pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last; -/* - * PCI_ADDR_SPACE_LIMITS_STORE - * Sets the current values of - * pci io base, - * pci io last, - * pci low memory base, - * pci low memory last, - * pci high memory base, - * pci high memory last - */ -#define PCI_ADDR_SPACE_LIMITS_STORE() \ - pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb; \ - pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl; \ - pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb; \ - pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl; \ - pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb; \ - pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl; - -#define PCI_ADDR_SPACE_LIMITS_PRINT() \ - printf("+++++++++++++++++++++++\n" \ - "IO base 0x%x last 0x%x\n" \ - "SWIN base 0x%x last 0x%x\n" \ - "MEM base 0x%x last 0x%x\n" \ - "+++++++++++++++++++++++\n", \ - pcibr_soft->bs_spinfo.pci_io_base, \ - pcibr_soft->bs_spinfo.pci_io_last, \ - pcibr_soft->bs_spinfo.pci_swin_base, \ - pcibr_soft->bs_spinfo.pci_swin_last, \ - pcibr_soft->bs_spinfo.pci_mem_base, \ - pcibr_soft->bs_spinfo.pci_mem_last); - -/* - * pcibr_slot_info_init - * Probe for this slot and see if it is populated. - * If it is populated initialize the generic PCI infrastructural - * information associated with this particular PCI device. - */ -int -pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - bridge_t *bridge; - cfg_p cfgw; - unsigned idword; - unsigned pfail; - unsigned idwords[8]; - pciio_vendor_id_t vendor; - pciio_device_id_t device; - unsigned htype; - cfg_p wptr; - int win; - pciio_space_t space; - iopaddr_t pci_io_fb, pci_io_fl; - iopaddr_t pci_lo_fb, pci_lo_fl; - iopaddr_t pci_hi_fb, pci_hi_fl; - int nfunc; - pciio_function_t rfunc; - int func; - devfs_handle_t conn_vhdl; - pcibr_soft_slot_t slotp; - - /* Get the basic software information required to proceed */ - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - if (!pcibr_soft) - return(EINVAL); - - bridge = pcibr_soft->bs_base; - if (!PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization - * is done by the host slot then we are done. - */ - if (pcibr_soft->bs_slot[slot].has_host) { - return(0); - } - - /* Check for a slot with any system critical functions */ - if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot)) - return(EPERM); - - /* Load the current values of allocated PCI address spaces */ - PCI_ADDR_SPACE_LIMITS_LOAD(); - - /* Try to read the device-id/vendor-id from the config space */ - cfgw = bridge->b_type0_cfg_dev[slot].l; - - if (pcibr_probe_slot(bridge, cfgw, &idword)) - return(ENODEV); - - slotp = &pcibr_soft->bs_slot[slot]; - slotp->slot_status |= SLOT_POWER_UP; - - vendor = 0xFFFF & idword; - /* If the vendor id is not valid then the slot is not populated - * and we are done. - */ - if (vendor == 0xFFFF) - return(ENODEV); - - device = 0xFFFF & (idword >> 16); - htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); - - nfunc = 1; - rfunc = PCIIO_FUNC_NONE; - pfail = 0; - - /* NOTE: if a card claims to be multifunction - * but only responds to config space 0, treat - * it as a unifunction card. - */ - - if (htype & 0x80) { /* MULTIFUNCTION */ - for (func = 1; func < 8; ++func) { - cfgw = bridge->b_type0_cfg_dev[slot].f[func].l; - if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) { - pfail |= 1 << func; - continue; - } - vendor = 0xFFFF & idwords[func]; - if (vendor == 0xFFFF) { - pfail |= 1 << func; - continue; - } - nfunc = func + 1; - rfunc = 0; - } - cfgw = bridge->b_type0_cfg_dev[slot].l; - } - NEWA(pcibr_infoh, nfunc); - - pcibr_soft->bs_slot[slot].bss_ninfo = nfunc; - pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh; - - for (func = 0; func < nfunc; ++func) { - unsigned cmd_reg; - - if (func) { - if (pfail & (1 << func)) - continue; - - idword = idwords[func]; - cfgw = bridge->b_type0_cfg_dev[slot].f[func].l; - - device = 0xFFFF & (idword >> 16); - htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); - rfunc = func; - } - htype &= 0x7f; - if (htype != 0x00) { - printk(KERN_WARNING "%s pcibr: pci slot %d func %d has strange header type 0x%x\n", - pcibr_soft->bs_name, slot, func, htype); - continue; - } -#if DEBUG && ATTACH_DEBUG - printk(KERN_NOTICE - "%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x", - pcibr_soft->bs_name, slot, func, vendor, device); -#endif - - pcibr_info = pcibr_device_info_new - (pcibr_soft, slot, rfunc, vendor, device); - conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c); - if (func == 0) - slotp->slot_conn = conn_vhdl; - -#ifdef LITTLE_ENDIAN - cmd_reg = cfgw[(PCI_CFG_COMMAND ^ 4) / 4]; -#else - cmd_reg = cfgw[PCI_CFG_COMMAND / 4]; -#endif - - wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; - - for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) { - iopaddr_t base, mask, code; - size_t size; - - /* - * GET THE BASE & SIZE OF THIS WINDOW: - * - * The low two or four bits of the BASE register - * determines which address space we are in; the - * rest is a base address. BASE registers - * determine windows that are power-of-two sized - * and naturally aligned, so we can get the size - * of a window by writing all-ones to the - * register, reading it back, and seeing which - * bits are used for decode; the least - * significant nonzero bit is also the size of - * the window. - * - * WARNING: someone may already have allocated - * some PCI space to this window, and in fact - * PIO may be in process at this very moment - * from another processor (or even from this - * one, if we get interrupted)! So, if the BASE - * already has a nonzero address, be generous - * and use the LSBit of that address as the - * size; this could overstate the window size. - * Usually, when one card is set up, all are set - * up; so, since we don't bitch about - * overlapping windows, we are ok. - * - * UNFORTUNATELY, some cards do not clear their - * BASE registers on reset. I have two heuristics - * that can detect such cards: first, if the - * decode enable is turned off for the space - * that the window uses, we can disregard the - * initial value. second, if the address is - * outside the range that we use, we can disregard - * it as well. - * - * This is looking very PCI generic. Except for - * knowing how many slots and where their config - * spaces are, this window loop and the next one - * could probably be shared with other PCI host - * adapters. It would be interesting to see if - * this could be pushed up into pciio, when we - * start supporting more PCI providers. - */ -#ifdef LITTLE_ENDIAN - base = wptr[((win*4)^4)/4]; -#else - base = wptr[win]; -#endif - - if (base & PCI_BA_IO_SPACE) { - /* BASE is in I/O space. */ - space = PCIIO_SPACE_IO; - mask = -4; - code = base & 3; - base = base & mask; - if (base == 0) { - ; /* not assigned */ - } else if (!(cmd_reg & PCI_CMD_IO_SPACE)) { - base = 0; /* decode not enabled */ - } - } else { - /* BASE is in MEM space. */ - space = PCIIO_SPACE_MEM; - mask = -16; - code = base & PCI_BA_MEM_LOCATION; /* extract BAR type */ - base = base & mask; - if (base == 0) { - ; /* not assigned */ - } else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) { - base = 0; /* decode not enabled */ - } else if (base & 0xC0000000) { - base = 0; /* outside permissable range */ - } else if ((code == PCI_BA_MEM_64BIT) && -#ifdef LITTLE_ENDIAN - (wptr[(((win + 1)*4)^4)/4] != 0)) { -#else - (wptr[win + 1] != 0)) { -#endif /* LITTLE_ENDIAN */ - base = 0; /* outside permissable range */ - } - } - - if (base != 0) { /* estimate size */ - size = base & -base; - } else { /* calculate size */ -#ifdef LITTLE_ENDIAN - wptr[((win*4)^4)/4] = ~0; /* turn on all bits */ - size = wptr[((win*4)^4)/4]; /* get stored bits */ -#else - wptr[win] = ~0; /* turn on all bits */ - size = wptr[win]; /* get stored bits */ -#endif /* LITTLE_ENDIAN */ - size &= mask; /* keep addr */ - size &= -size; /* keep lsbit */ - if (size == 0) - continue; - } - - pcibr_info->f_window[win].w_space = space; - pcibr_info->f_window[win].w_base = base; - pcibr_info->f_window[win].w_size = size; - - /* - * If this window already has PCI space - * allocated for it, "subtract" that space from - * our running freeblocks. Don't worry about - * overlaps in existing allocated windows; we - * may be overstating their sizes anyway. - */ - - if (base && size) { - if (space == PCIIO_SPACE_IO) { - pcibr_freeblock_sub(&pci_io_fb, - &pci_io_fl, - base, size); - } else { - pcibr_freeblock_sub(&pci_lo_fb, - &pci_lo_fl, - base, size); - pcibr_freeblock_sub(&pci_hi_fb, - &pci_hi_fl, - base, size); - } - } -#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM) - /* - * IOC3 BASE_ADDR* BUG WORKAROUND - * - - * If we write to BASE1 on the IOC3, the - * data in BASE0 is replaced. The - * original workaround was to remember - * the value of BASE0 and restore it - * when we ran off the end of the BASE - * registers; however, a later - * workaround was added (I think it was - * rev 1.44) to avoid setting up - * anything but BASE0, with the comment - * that writing all ones to BASE1 set - * the enable-parity-error test feature - * in IOC3's SCR bit 14. - * - * So, unless we defer doing any PCI - * space allocation until drivers - * attach, and set up a way for drivers - * (the IOC3 in paricular) to tell us - * generically to keep our hands off - * BASE registers, we gotta "know" about - * the IOC3 here. - * - * Too bad the PCI folks didn't reserve the - * all-zero value for 'no BASE here' (it is a - * valid code for an uninitialized BASE in - * 32-bit PCI memory space). - */ - - if ((vendor == IOC3_VENDOR_ID_NUM) && - (device == IOC3_DEVICE_ID_NUM)) - break; -#endif - if (code == PCI_BA_MEM_64BIT) { - win++; /* skip upper half */ -#ifdef LITTLE_ENDIAN - wptr[((win*4)^4)/4] = 0; /* which must be zero */ -#else - wptr[win] = 0; /* which must be zero */ -#endif /* LITTLE_ENDIAN */ - } - } /* next win */ - } /* next func */ - - /* Store back the values for allocated PCI address spaces */ - PCI_ADDR_SPACE_LIMITS_STORE(); - return(0); -} - -/* - * pcibr_slot_info_free - * Remove all the PCI infrastructural information associated - * with a particular PCI device. - */ -int -pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - int nfunc; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; - - pcibr_device_info_free(pcibr_vhdl, slot); - - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - DELA(pcibr_infoh,nfunc); - pcibr_soft->bs_slot[slot].bss_ninfo = 0; - - return(0); -} - -int as_debug = 0; -/* - * pcibr_slot_addr_space_init - * Reserve chunks of PCI address space as required by - * the base registers in the card. - */ -int -pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - bridge_t *bridge; - iopaddr_t pci_io_fb, pci_io_fl; - iopaddr_t pci_lo_fb, pci_lo_fl; - iopaddr_t pci_hi_fb, pci_hi_fl; - size_t align; - iopaddr_t mask; - int nbars; - int nfunc; - int func; - int win; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - bridge = pcibr_soft->bs_base; - - /* Get the current values for the allocated PCI address spaces */ - PCI_ADDR_SPACE_LIMITS_LOAD(); - - if (as_debug) -#ifdef LATER - PCI_ADDR_SPACE_LIMITS_PRINT(); -#endif - /* allocate address space, - * for windows that have not been - * previously assigned. - */ - if (pcibr_soft->bs_slot[slot].has_host) { - return(0); - } - - nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; - if (nfunc < 1) - return(EINVAL); - - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - if (!pcibr_infoh) - return(EINVAL); - - /* - * Try to make the DevIO windows not - * overlap by pushing the "io" and "hi" - * allocation areas up to the next one - * or two megabyte bound. This also - * keeps them from being zero. - * - * DO NOT do this with "pci_lo" since - * the entire "lo" area is only a - * megabyte, total ... - */ - align = (slot < 2) ? 0x200000 : 0x100000; - mask = -align; - pci_io_fb = (pci_io_fb + align - 1) & mask; - pci_hi_fb = (pci_hi_fb + align - 1) & mask; - - for (func = 0; func < nfunc; ++func) { - cfg_p cfgw; - cfg_p wptr; - pciio_space_t space; - iopaddr_t base; - size_t size; - cfg_p pci_cfg_cmd_reg_p; - unsigned pci_cfg_cmd_reg; - unsigned pci_cfg_cmd_reg_add = 0; - - pcibr_info = pcibr_infoh[func]; - - if (!pcibr_info) - continue; - - if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) - continue; - - cfgw = bridge->b_type0_cfg_dev[slot].f[func].l; - wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; - - nbars = PCI_CFG_BASE_ADDRS; - - for (win = 0; win < nbars; ++win) { - - space = pcibr_info->f_window[win].w_space; - base = pcibr_info->f_window[win].w_base; - size = pcibr_info->f_window[win].w_size; - - if (size < 1) - continue; - - if (base >= size) { -#if DEBUG && PCI_DEBUG - printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n", - slot, func, win, space, base, base + size - 1); -#endif - continue; /* already allocated */ - } - align = size; /* ie. 0x00001000 */ - if (align < _PAGESZ) - align = _PAGESZ; /* ie. 0x00004000 */ - mask = -align; /* ie. 0xFFFFC000 */ - - switch (space) { - case PCIIO_SPACE_IO: - base = (pci_io_fb + align - 1) & mask; - if ((base + size) > pci_io_fl) { - base = 0; - break; - } - pci_io_fb = base + size; - break; - - case PCIIO_SPACE_MEM: -#ifdef LITTLE_ENDIAN - if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) == -#else - if ((wptr[win] & PCI_BA_MEM_LOCATION) == -#endif /* LITTLE_ENDIAN */ - PCI_BA_MEM_1MEG) { - /* allocate from 20-bit PCI space */ - base = (pci_lo_fb + align - 1) & mask; - if ((base + size) > pci_lo_fl) { - base = 0; - break; - } - pci_lo_fb = base + size; - } else { - /* allocate from 32-bit or 64-bit PCI space */ - base = (pci_hi_fb + align - 1) & mask; - if ((base + size) > pci_hi_fl) { - base = 0; - break; - } - pci_hi_fb = base + size; - } - break; - - default: - base = 0; -#if DEBUG && PCI_DEBUG - printk("pcibr: slot %d window %d had bad space code %d\n", - slot, win, space); -#endif - } - pcibr_info->f_window[win].w_base = base; -#ifdef LITTLE_ENDIAN - wptr[((win*4)^4)/4] = base; -#if DEBUG && PCI_DEBUG - printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base); -#endif -#else - wptr[win] = base; -#endif /* LITTLE_ENDIAN */ - -#if DEBUG && PCI_DEBUG - if (base >= size) - printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n", - slot, func, win, space, base, base + size - 1); - else - printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n", - slot, func, win, size, space); -#endif - } /* next base */ - - /* - * Allocate space for the EXPANSION ROM - * NOTE: DO NOT DO THIS ON AN IOC3, - * as it blows the system away. - */ - base = size = 0; - if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) || - (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) { - - wptr = cfgw + PCI_EXPANSION_ROM / 4; -#ifdef LITTLE_ENDIAN - wptr[1] = 0xFFFFF000; - mask = wptr[1]; -#else - *wptr = 0xFFFFF000; - mask = *wptr; -#endif /* LITTLE_ENDIAN */ - if (mask & 0xFFFFF000) { - size = mask & -mask; - align = size; - if (align < _PAGESZ) - align = _PAGESZ; - mask = -align; - base = (pci_hi_fb + align - 1) & mask; - if ((base + size) > pci_hi_fl) - base = size = 0; - else { - pci_hi_fb = base + size; -#ifdef LITTLE_ENDIAN - wptr[1] = base; -#else - *wptr = base; -#endif /* LITTLE_ENDIAN */ -#if DEBUG && PCI_DEBUG - printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n", - pcibr_soft->bs_name, slot, - base, base + size - 1); -#endif - } - } - } - pcibr_info->f_rbase = base; - pcibr_info->f_rsize = size; - - /* - * if necessary, update the board's - * command register to enable decoding - * in the windows we added. - * - * There are some bits we always want to - * be sure are set. - */ - pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE; - - /* - * The Adaptec 1160 FC Controller WAR #767995: - * The part incorrectly ignores the upper 32 bits of a 64 bit - * address when decoding references to it's registers so to - * keep it from responding to a bus cycle that it shouldn't - * we only use I/O space to get at it's registers. Don't - * enable memory space accesses on that PCI device. - */ - #define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */ - #define FCADP_DEVID 0x1160 /* Adaptec 1160 Device ID from fcadp.h */ - - if ((pcibr_info->f_vendor != FCADP_VENDID) || - (pcibr_info->f_device != FCADP_DEVID)) - pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE; - - pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER; - - pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4; - pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p; -#if PCI_FBBE /* XXX- check here to see if dev can do fast-back-to-back */ - if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP)) - fast_back_to_back_enable = 0; -#endif - pci_cfg_cmd_reg &= 0xFFFF; - if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg) - *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add; - - } /* next func */ - - /* Now that we have allocated new chunks of PCI address spaces to this - * card we need to update the bookkeeping values which indicate - * the current PCI address space allocations. - */ - PCI_ADDR_SPACE_LIMITS_STORE(); - return(0); -} - -/* - * pcibr_slot_device_init - * Setup the device register in the bridge for this PCI slot. - */ -int -pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - bridge_t *bridge; - bridgereg_t devreg; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - bridge = pcibr_soft->bs_base; - - /* - * Adjustments to Device(x) - * and init of bss_device shadow - */ - devreg = bridge->b_device[slot].reg; - devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS; - devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN; -#ifdef LITTLE_ENDIAN - devreg |= BRIDGE_DEV_DEV_SWAP; -#endif - pcibr_soft->bs_slot[slot].bss_device = devreg; - bridge->b_device[slot].reg = devreg; - -#if DEBUG && PCI_DEBUG - printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg); -#endif - -#if DEBUG && PCI_DEBUG - printk("pcibr: PCI space allocation done.\n"); -#endif - - return(0); -} - -/* - * pcibr_slot_guest_info_init - * Setup the host/guest relations for a PCI slot. - */ -int -pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - pcibr_soft_slot_t slotp; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - slotp = &pcibr_soft->bs_slot[slot]; - - /* create info and verticies for guest slots; - * for compatibilitiy macros, create info - * for even unpopulated slots (but do not - * build verticies for them). - */ - if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) { - NEWA(pcibr_infoh, 1); - pcibr_soft->bs_slot[slot].bss_ninfo = 1; - pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh; - - pcibr_info = pcibr_device_info_new - (pcibr_soft, slot, PCIIO_FUNC_NONE, - PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE); - - if (pcibr_soft->bs_slot[slot].has_host) { - slotp->slot_conn = pciio_device_info_register - (pcibr_vhdl, &pcibr_info->f_c); - } - } - - /* generate host/guest relations - */ - if (pcibr_soft->bs_slot[slot].has_host) { - int host = pcibr_soft->bs_slot[slot].host_slot; - pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host]; - - hwgraph_edge_add(slotp->slot_conn, - host_slotp->slot_conn, - EDGE_LBL_HOST); - - /* XXX- only gives us one guest edge per - * host. If/when we have a host with more than - * one guest, we will need to figure out how - * the host finds all its guests, and sorts - * out which one is which. - */ - hwgraph_edge_add(host_slotp->slot_conn, - slotp->slot_conn, - EDGE_LBL_GUEST); - } - - return(0); -} - -/* - * pcibr_slot_initial_rrb_alloc - * Allocate a default number of rrbs for this slot on - * the two channels. This is dictated by the rrb allocation - * strategy routine defined per platform. - */ - -int -pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - bridge_t *bridge; - int c0, c1; - int r; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - bridge = pcibr_soft->bs_base; - - /* How may RRBs are on this slot? - */ - c0 = do_pcibr_rrb_count_valid(bridge, slot); - c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL); - -#if PCIBR_RRB_DEBUG - printk("pcibr_attach: slot %d started with %d+%d\n", slot, c0, c1); -#endif - - /* Do we really need any? - */ - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - pcibr_info = pcibr_infoh[0]; - if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) && - !pcibr_soft->bs_slot[slot].has_host) { - if (c0 > 0) - do_pcibr_rrb_free(bridge, slot, c0); - if (c1 > 0) - do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1); - pcibr_soft->bs_rrb_valid[slot] = 0x1000; - pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000; - return(ENODEV); - } - - pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1; - pcibr_soft->bs_rrb_valid[slot] = c0; - pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1; - - pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0); - pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1); - - r = 3 - (c0 + c1); - - if (r > 0) { - pcibr_soft->bs_rrb_res[slot] = r; - pcibr_soft->bs_rrb_avail[slot & 1] -= r; - } - -#if PCIBR_RRB_DEBUG - printk("\t%d+%d+%d", - 0xFFF & pcibr_soft->bs_rrb_valid[slot], - 0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], - pcibr_soft->bs_rrb_res[slot]); - printk("\n"); -#endif - - return(0); -} - -/* - * pcibr_slot_call_device_attach - * This calls the associated driver attach routine for the PCI - * card in this slot. - */ -int -pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot, - int drv_flags) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - async_attach_t aa = NULL; - int func; - devfs_handle_t xconn_vhdl,conn_vhdl; - int nfunc; - int error_func; - int error_slot = 0; - int error = ENODEV; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - - if (pcibr_soft->bs_slot[slot].has_host) { - return(EPERM); - } - - xconn_vhdl = pcibr_soft->bs_conn; - aa = async_attach_get_info(xconn_vhdl); - - nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - - for (func = 0; func < nfunc; ++func) { - - pcibr_info = pcibr_infoh[func]; - - if (!pcibr_info) - continue; - - if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) - continue; - - conn_vhdl = pcibr_info->f_vertex; - -#ifdef LATER - /* - * Activate if and when we support cdl. - */ - if (aa) - async_attach_add_info(conn_vhdl, aa); -#endif /* LATER */ - - error_func = pciio_device_attach(conn_vhdl, drv_flags); - - pcibr_info->f_att_det_error = error_func; - - if (error_func) - error_slot = error_func; - - error = error_slot; - - } /* next func */ - - if (error) { - if ((error != ENODEV) && (error != EUNATCH)) - pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT; - } else { - pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT; - } - - return(error); -} - -/* - * pcibr_slot_call_device_detach - * This calls the associated driver detach routine for the PCI - * card in this slot. - */ -int -pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot, - int drv_flags) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - int func; - devfs_handle_t conn_vhdl = GRAPH_VERTEX_NONE; - int nfunc; - int error_func; - int error_slot = 0; - int error = ENODEV; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(EINVAL); - - if (pcibr_soft->bs_slot[slot].has_host) - return(EPERM); - - /* Make sure that we do not detach a system critical function vertex */ - if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot)) - return(EPERM); - - nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - - for (func = 0; func < nfunc; ++func) { - - pcibr_info = pcibr_infoh[func]; - - if (!pcibr_info) - continue; - - if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) - continue; - - conn_vhdl = pcibr_info->f_vertex; - - error_func = pciio_device_detach(conn_vhdl, drv_flags); - - pcibr_info->f_att_det_error = error_func; - - if (error_func) - error_slot = error_func; - - error = error_slot; - - } /* next func */ - - pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK; - - if (error) { - if ((error != ENODEV) && (error != EUNATCH)) - pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT; - } else { - if (conn_vhdl != GRAPH_VERTEX_NONE) - pcibr_device_unregister(conn_vhdl); - pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT; - } - - return(error); -} - -/* - * pcibr_slot_detach - * This is a place holder routine to keep track of all the - * slot-specific freeing that needs to be done. - */ -int -pcibr_slot_detach(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot, - int drv_flags) -{ - int error; - - /* Call the device detach function */ - error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags)); - return (error); - -} - -/* - * pcibr_is_slot_sys_critical - * Check slot for any functions that are system critical. - * Return 1 if any are system critical or 0 otherwise. - * - * This function will always return 0 when called by - * pcibr_attach() because the system critical vertices - * have not yet been set in the hwgraph. - */ -int -pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - devfs_handle_t conn_vhdl = GRAPH_VERTEX_NONE; - int nfunc; - int func; - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) - return(0); - - nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - - for (func = 0; func < nfunc; ++func) { - - pcibr_info = pcibr_infoh[func]; - if (!pcibr_info) - continue; - - if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) - continue; - - conn_vhdl = pcibr_info->f_vertex; - if (is_sys_critical_vertex(conn_vhdl)) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "%v is a system critical device vertex\n", conn_vhdl); -#else - printk(KERN_WARNING "%p is a system critical device vertex\n", (void *)conn_vhdl); -#endif - return(1); - } - - } - - return(0); -} - -/* - * pcibr_device_unregister - * This frees up any hardware resources reserved for this PCI device - * and removes any PCI infrastructural information setup for it. - * This is usually used at the time of shutting down of the PCI card. - */ -int -pcibr_device_unregister(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info; - devfs_handle_t pcibr_vhdl; - pciio_slot_t slot; - pcibr_soft_t pcibr_soft; - bridge_t *bridge; - int error_call; - int error = 0; - - pciio_info = pciio_info_get(pconn_vhdl); - - pcibr_vhdl = pciio_info_master_get(pciio_info); - slot = pciio_info_slot_get(pciio_info); - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge = pcibr_soft->bs_base; - - /* Clear all the hardware xtalk resources for this device */ - xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot); - - /* Flush all the rrbs */ - pcibr_rrb_flush(pconn_vhdl); - - /* Free the rrbs allocated to this slot */ - error_call = do_pcibr_rrb_free(bridge, slot, - pcibr_soft->bs_rrb_valid[slot] + - pcibr_soft->bs_rrb_valid[slot + - PCIBR_RRB_SLOT_VIRTUAL]); - - if (error_call) - error = ERANGE; - - pcibr_soft->bs_rrb_valid[slot] = 0; - pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0; - pcibr_soft->bs_rrb_res[slot] = 0; - - /* Flush the write buffers !! */ - error_call = pcibr_wrb_flush(pconn_vhdl); - - if (error_call) - error = error_call; - - /* Clear the information specific to the slot */ - error_call = pcibr_slot_info_free(pcibr_vhdl, slot); - - if (error_call) - error = error_call; - - return(error); - -} - -/* - * build a convenience link path in the - * form of "...//bus/" - * - * returns 1 on success, 0 otherwise - * - * depends on hwgraph separator == '/' - */ -int -pcibr_bus_cnvlink(devfs_handle_t f_c, int slot) -{ - char dst[MAXDEVNAME]; - char *dp = dst; - char *cp, *xp; - int widgetnum; - char pcibus[8]; - devfs_handle_t nvtx, svtx; - int rv; - -#if DEBUG - printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", - slot, f_c); - { - int pos; - char dname[256]; - pos = devfs_generate_path(f_c, dname, 256); - printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); - } -#endif - - if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME)) - return 0; - - /* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */ - - /* find the widget number */ - xp = strstr(dst, "/"EDGE_LBL_XTALK"/"); - if (xp == NULL) - return 0; - widgetnum = atoi(xp+7); - if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F) - return 0; - - /* remove "/pci/direct" from path */ - cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct"); - if (cp == NULL) - return 0; - *cp = (char)NULL; - - /* get the vertex for the widget */ - if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx)) - return 0; - - *xp = (char)NULL; /* remove "/xtalk/..." from path */ - - /* dst example now == /hw/module/001c02/Pbrick */ - - /* get the bus number */ - strcat(dst, "/bus"); - sprintf(pcibus, "%d", p_busnum[widgetnum]); - - /* link to bus to widget */ - rv = hwgraph_path_add(NULL, dp, &nvtx); - if (GRAPH_SUCCESS == rv) - rv = hwgraph_edge_add(nvtx, svtx, pcibus); - - return (rv == GRAPH_SUCCESS); -} - - -/* - * pcibr_attach: called every time the crosstalk - * infrastructure is asked to initialize a widget - * that matches the part number we handed to the - * registration routine above. - */ -/*ARGSUSED */ -int -pcibr_attach(devfs_handle_t xconn_vhdl) -{ - /* REFERENCED */ - graph_error_t rc; - devfs_handle_t pcibr_vhdl; - devfs_handle_t ctlr_vhdl; - bridge_t *bridge = NULL; - bridgereg_t id; - int rev; - pcibr_soft_t pcibr_soft; - pcibr_info_t pcibr_info; - xwidget_info_t info; - xtalk_intr_t xtalk_intr; - device_desc_t dev_desc = (device_desc_t)0; - int slot; - int ibit; - devfs_handle_t noslot_conn; - char devnm[MAXDEVNAME], *s; - pcibr_hints_t pcibr_hints; - bridgereg_t b_int_enable; - unsigned rrb_fixed = 0; - - iopaddr_t pci_io_fb, pci_io_fl; - iopaddr_t pci_lo_fb, pci_lo_fl; - iopaddr_t pci_hi_fb, pci_hi_fl; - - int spl_level; -#ifdef LATER - char *nicinfo = (char *)0; -#endif - -#if PCI_FBBE - int fast_back_to_back_enable; -#endif - l1sc_t *scp; - nasid_t nasid; - - async_attach_t aa = NULL; - - aa = async_attach_get_info(xconn_vhdl); - -#if DEBUG && ATTACH_DEBUG - printk("pcibr_attach: xconn_vhdl= %p\n", xconn_vhdl); - { - int pos; - char dname[256]; - pos = devfs_generate_path(xconn_vhdl, dname, 256); - printk("%s : path= %s \n", __FUNCTION__, &dname[pos]); - } -#endif - - /* Setup the PRB for the bridge in CONVEYOR BELT - * mode. PRBs are setup in default FIRE-AND-FORGET - * mode during the initialization. - */ - hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR); - - bridge = (bridge_t *) - xtalk_piotrans_addr(xconn_vhdl, NULL, - 0, sizeof(bridge_t), 0); - -#ifndef MEDUSA_HACK - if ((bridge->b_wid_stat & BRIDGE_STAT_PCI_GIO_N) == 0) - return -1; /* someone else handles GIO bridges. */ -#endif - - if (XWIDGET_PART_REV_NUM(bridge->b_wid_id) == XBRIDGE_PART_REV_A) - NeedXbridgeSwap = 1; - - /* - * Create the vertex for the PCI bus, which we - * will also use to hold the pcibr_soft and - * which will be the "master" vertex for all the - * pciio connection points we will hang off it. - * This needs to happen before we call nic_bridge_vertex_info - * as we are some of the *_vmc functions need access to the edges. - * - * Opening this vertex will provide access to - * the Bridge registers themselves. - */ - rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl); - ASSERT(rc == GRAPH_SUCCESS); - - ctlr_vhdl = NULL; - ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &pcibr_fops, NULL); - - ASSERT(ctlr_vhdl != NULL); - - /* - * decode the nic, and hang its stuff off our - * connection point where other drivers can get - * at it. - */ -#ifdef LATER - nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic); -#endif - - /* - * Get the hint structure; if some NIC callback - * marked this vertex as "hands-off" then we - * just return here, before doing anything else. - */ - pcibr_hints = pcibr_hints_get(xconn_vhdl, 0); - - if (pcibr_hints && pcibr_hints->ph_hands_off) - return -1; /* generic operations disabled */ - - id = bridge->b_wid_id; - rev = XWIDGET_PART_REV_NUM(id); - - hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev); - - /* - * allocate soft state structure, fill in some - * fields, and hook it up to our vertex. - */ - NEW(pcibr_soft); - BZERO(pcibr_soft, sizeof *pcibr_soft); - pcibr_soft_set(pcibr_vhdl, pcibr_soft); - - pcibr_soft->bs_conn = xconn_vhdl; - pcibr_soft->bs_vhdl = pcibr_vhdl; - pcibr_soft->bs_base = bridge; - pcibr_soft->bs_rev_num = rev; - pcibr_soft->bs_intr_bits = pcibr_intr_bits; - if (is_xbridge(bridge)) { - pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES; - pcibr_soft->bs_xbridge = 1; - } else { - pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES; - pcibr_soft->bs_xbridge = 0; - } - - nasid = NASID_GET(bridge); - scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc; - pcibr_soft->bs_l1sc = scp; - pcibr_soft->bs_moduleid = iobrick_module_get(scp); - pcibr_soft->bsi_err_intr = 0; - - /* Bridges up through REV C - * are unable to set the direct - * byteswappers to BYTE_STREAM. - */ - if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) { - pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES; - pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES; - } -#if PCIBR_SOFT_LIST - { - pcibr_list_p self; - - NEW(self); - self->bl_soft = pcibr_soft; - self->bl_vhdl = pcibr_vhdl; - self->bl_next = pcibr_list; - pcibr_list = self; - } -#endif - - /* - * get the name of this bridge vertex and keep the info. Use this - * only where it is really needed now: like error interrupts. - */ - s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME); - pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL); - strcpy(pcibr_soft->bs_name, s); - -#if SHOW_REVS || DEBUG -#if !DEBUG - if (kdebug) -#endif - printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n", - is_xbridge(bridge) ? "X" : "", - (rev == BRIDGE_PART_REV_A) ? "A" : - (rev == BRIDGE_PART_REV_B) ? "B" : - (rev == BRIDGE_PART_REV_C) ? "C" : - (rev == BRIDGE_PART_REV_D) ? "D" : - (rev == XBRIDGE_PART_REV_A) ? "A" : - (rev == XBRIDGE_PART_REV_B) ? "B" : - "unknown", - rev, pcibr_soft->bs_name); -#endif - - info = xwidget_info_get(xconn_vhdl); - pcibr_soft->bs_xid = xwidget_info_id_get(info); - pcibr_soft->bs_master = xwidget_info_master_get(info); - pcibr_soft->bs_mxid = xwidget_info_masterid_get(info); - - /* - * Init bridge lock. - */ - spin_lock_init(&pcibr_soft->bs_lock); - - /* - * If we have one, process the hints structure. - */ - if (pcibr_hints) { - rrb_fixed = pcibr_hints->ph_rrb_fixed; - - pcibr_soft->bs_rrb_fixed = rrb_fixed; - - if (pcibr_hints->ph_intr_bits) - pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits; - - for (slot = 0; slot < 8; ++slot) { - int hslot = pcibr_hints->ph_host_slot[slot] - 1; - - if (hslot < 0) { - pcibr_soft->bs_slot[slot].host_slot = slot; - } else { - pcibr_soft->bs_slot[slot].has_host = 1; - pcibr_soft->bs_slot[slot].host_slot = hslot; - } - } - } - /* - * set up initial values for state fields - */ - for (slot = 0; slot < 8; ++slot) { - pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE; - pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET; - pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET; - pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0); - } - - for (ibit = 0; ibit < 8; ++ibit) { - pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0; - pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft; - pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL; - pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = - &(bridge->b_int_status); - pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0; - pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0; - pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0; - } - - /* - * Initialize various Bridge registers. - */ - - /* - * On pre-Rev.D bridges, set the PCI_RETRY_CNT - * to zero to avoid dropping stores. (#475347) - */ - if (rev < BRIDGE_PART_REV_D) - bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK; - - /* - * Clear all pending interrupts. - */ - bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR); - - /* - * Until otherwise set up, - * assume all interrupts are - * from slot 7. - */ - bridge->b_int_device = (uint32_t) 0xffffffff; - - { - bridgereg_t dirmap; - paddr_t paddr; - iopaddr_t xbase; - xwidgetnum_t xport; - iopaddr_t offset; - int num_entries = 0; - int entry; - cnodeid_t cnodeid; - nasid_t nasid; - - /* Set the Bridge's 32-bit PCI to XTalk - * Direct Map register to the most useful - * value we can determine. Note that we - * must use a single xid for all of: - * direct-mapped 32-bit DMA accesses - * direct-mapped 64-bit DMA accesses - * DMA accesses through the PMU - * interrupts - * This is the only way to guarantee that - * completion interrupts will reach a CPU - * after all DMA data has reached memory. - * (Of course, there may be a few special - * drivers/controlers that explicitly manage - * this ordering problem.) - */ - - cnodeid = 0; /* default node id */ - /* - * Determine the base address node id to be used for all 32-bit - * Direct Mapping I/O. The default is node 0, but this can be changed - * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE - * attribute in the irix.sm config file. A device driver can obtain - * this node value via a call to pcibr_get_dmatrans_node(). - */ - nasid = COMPACT_TO_NASID_NODEID(cnodeid); - paddr = NODE_OFFSET(nasid) + 0; - - /* currently, we just assume that if we ask - * for a DMA mapping to "zero" the XIO - * host will transmute this into a request - * for the lowest hunk of memory. - */ - xbase = xtalk_dmatrans_addr(xconn_vhdl, 0, - paddr, _PAGESZ, 0); - - if (xbase != XIO_NOWHERE) { - if (XIO_PACKED(xbase)) { - xport = XIO_PORT(xbase); - xbase = XIO_ADDR(xbase); - } else - xport = pcibr_soft->bs_mxid; - - offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull); - xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT; - - dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT; - - if (xbase) - dirmap |= BRIDGE_DIRMAP_OFF & xbase; - else if (offset >= (512 << 20)) - dirmap |= BRIDGE_DIRMAP_ADD512; - - bridge->b_dir_map = dirmap; - } - /* - * Set bridge's idea of page size according to the system's - * idea of "IO page size". TBD: The idea of IO page size - * should really go away. - */ - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - spl_level = splhi(); -#if IOPGSIZE == 4096 - bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE; -#elif IOPGSIZE == 16384 - bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE; -#else - <<>>; -#endif - bridge->b_wid_control; /* inval addr bug war */ - splx(spl_level); - - /* Initialize internal mapping entries */ - for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++) - bridge->b_int_ate_ram[entry].wr = 0; - - /* - * Determine if there's external mapping SSRAM on this - * bridge. Set up Bridge control register appropriately, - * inititlize SSRAM, and set software up to manage RAM - * entries as an allocatable resource. - * - * Currently, we just use the rm* routines to manage ATE - * allocation. We should probably replace this with a - * Best Fit allocator. - * - * For now, if we have external SSRAM, avoid using - * the internal ssram: we can't turn PREFETCH on - * when we use the internal SSRAM; and besides, - * this also guarantees that no allocation will - * straddle the internal/external line, so we - * can increment ATE write addresses rather than - * recomparing against BRIDGE_INTERNAL_ATES every - * time. - */ - if (is_xbridge(bridge)) - num_entries = 0; - else - num_entries = pcibr_init_ext_ate_ram(bridge); - - /* we always have 128 ATEs (512 for Xbridge) inside the chip - * even if disabled for debugging. - */ - pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size); - pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size); -#if PCIBR_ATE_DEBUG - printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size); -#endif - - if (num_entries > pcibr_soft->bs_int_ate_size) { -#if PCIBR_ATE_NOTBOTH /* for debug -- forces us to use external ates */ - printk("pcibr_attach: disabling internal ATEs.\n"); - pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size); -#endif - pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries); - pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size, - num_entries - pcibr_soft->bs_int_ate_size); -#if PCIBR_ATE_DEBUG - printk("pcibr_attach: %d EXTERNAL ATEs\n", - num_entries - pcibr_soft->bs_int_ate_size); -#endif - } - } - - { - bridgereg_t dirmap; - iopaddr_t xbase; - - /* - * now figure the *real* xtalk base address - * that dirmap sends us to. - */ - dirmap = bridge->b_dir_map; - if (dirmap & BRIDGE_DIRMAP_OFF) - xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF) - << BRIDGE_DIRMAP_OFF_ADDRSHFT; - else if (dirmap & BRIDGE_DIRMAP_ADD512) - xbase = 512 << 20; - else - xbase = 0; - - pcibr_soft->bs_dir_xbase = xbase; - - /* it is entirely possible that we may, at this - * point, have our dirmap pointing somewhere - * other than our "master" port. - */ - pcibr_soft->bs_dir_xport = - (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT; - } - - /* pcibr sources an error interrupt; - * figure out where to send it. - * - * If any interrupts are enabled in bridge, - * then the prom set us up and our interrupt - * has already been reconnected in mlreset - * above. - * - * Need to set the D_INTR_ISERR flag - * in the dev_desc used for allocating the - * error interrupt, so our interrupt will - * be properly routed and prioritized. - * - * If our crosstalk provider wants to - * fix widget error interrupts to specific - * destinations, D_INTR_ISERR is how it - * knows to do this. - */ - - xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl); - ASSERT(xtalk_intr != NULL); - - pcibr_soft->bsi_err_intr = xtalk_intr; - - /* - * On IP35 with XBridge, we do some extra checks in pcibr_setwidint - * in order to work around some addressing limitations. In order - * for that fire wall to work properly, we need to make sure we - * start from a known clean state. - */ - pcibr_clearwidint(bridge); - - xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge); - - /* - * now we can start handling error interrupts; - * enable all of them. - * NOTE: some PCI ints may already be enabled. - */ - b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS; - - - bridge->b_int_enable = b_int_enable; - bridge->b_int_mode = 0; /* do not send "clear interrupt" packets */ - - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - - /* - * Depending on the rev of bridge, disable certain features. - * Easiest way seems to be to force the PCIBR_NOwhatever - * flag to be on for all DMA calls, which overrides any - * PCIBR_whatever flag or even the setting of whatever - * from the PCIIO_DMA_class flags (or even from the other - * PCIBR flags, since NO overrides YES). - */ - pcibr_soft->bs_dma_flags = 0; - - /* PREFETCH: - * Always completely disabled for REV.A; - * at "pcibr_prefetch_enable_rev", anyone - * asking for PCIIO_PREFETCH gets it. - * Between these two points, you have to ask - * for PCIBR_PREFETCH, which promises that - * your driver knows about known Bridge WARs. - */ - if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B) - pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH; - else if (pcibr_soft->bs_rev_num < - (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev)) - pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH; - - /* WRITE_GATHER: - * Disabled up to but not including the - * rev number in pcibr_wg_enable_rev. There - * is no "WAR range" as with prefetch. - */ - if (pcibr_soft->bs_rev_num < - (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev)) - pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER; - - pciio_provider_register(pcibr_vhdl, &pcibr_provider); - pciio_provider_startup(pcibr_vhdl); - - pci_io_fb = 0x00000004; /* I/O FreeBlock Base */ - pci_io_fl = 0xFFFFFFFF; /* I/O FreeBlock Last */ - - pci_lo_fb = 0x00000010; /* Low Memory FreeBlock Base */ - pci_lo_fl = 0x001FFFFF; /* Low Memory FreeBlock Last */ - - pci_hi_fb = 0x00200000; /* High Memory FreeBlock Base */ - pci_hi_fl = 0x3FFFFFFF; /* High Memory FreeBlock Last */ - - - PCI_ADDR_SPACE_LIMITS_STORE(); - - /* build "no-slot" connection point - */ - pcibr_info = pcibr_device_info_new - (pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE, - PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE); - noslot_conn = pciio_device_info_register - (pcibr_vhdl, &pcibr_info->f_c); - - /* Remember the no slot connection point info for tearing it - * down during detach. - */ - pcibr_soft->bs_noslot_conn = noslot_conn; - pcibr_soft->bs_noslot_info = pcibr_info; -#if PCI_FBBE - fast_back_to_back_enable = 1; -#endif - -#if PCI_FBBE - if (fast_back_to_back_enable) { - /* - * All devices on the bus are capable of fast back to back, so - * we need to set the fast back to back bit in all devices on - * the bus that are capable of doing such accesses. - */ - } -#endif - -#ifdef LATER - /* If the bridge has been reset then there is no need to reset - * the individual PCI slots. - */ - for (slot = 0; slot < 8; ++slot) - /* Reset all the slots */ - (void)pcibr_slot_reset(pcibr_vhdl, slot); -#endif - - for (slot = 0; slot < 8; ++slot) - /* Find out what is out there */ - (void)pcibr_slot_info_init(pcibr_vhdl,slot); - - for (slot = 0; slot < 8; ++slot) - /* Set up the address space for this slot in the pci land */ - (void)pcibr_slot_addr_space_init(pcibr_vhdl,slot); - - for (slot = 0; slot < 8; ++slot) - /* Setup the device register */ - (void)pcibr_slot_device_init(pcibr_vhdl, slot); - -#ifndef __ia64 - for (slot = 0; slot < 8; ++slot) - /* Set up convenience links */ - if (is_xbridge(bridge)) - if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */ - pcibr_bus_cnvlink(pcibr_info->f_vertex, slot); -#endif - - for (slot = 0; slot < 8; ++slot) - /* Setup host/guest relations */ - (void)pcibr_slot_guest_info_init(pcibr_vhdl,slot); - - for (slot = 0; slot < 8; ++slot) - /* Initial RRB management */ - (void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot); - - /* driver attach routines should be called out from generic linux code */ - for (slot = 0; slot < 8; ++slot) - /* Call the device attach */ - (void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0); - - /* - * Each Pbrick PCI bus only has slots 1 and 2. Similarly for - * widget 0xe on Ibricks. Allocate RRB's accordingly. - */ - if (pcibr_soft->bs_moduleid > 0) { - switch (MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid)) { - case 'p': /* Pbrick */ - do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8); - do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8); - break; - case 'i': /* Ibrick */ - /* port 0xe on the Ibrick only has slots 1 and 2 */ - if (pcibr_soft->bs_xid == 0xe) { - do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8); - do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8); - } - else { - /* allocate one RRB for the serial port */ - do_pcibr_rrb_autoalloc(pcibr_soft, 0, 1); - } - break; - } /* switch */ - } - -#ifdef LATER - if (strstr(nicinfo, XTALK_PCI_PART_NUM)) { - do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8); -#if PCIBR_RRB_DEBUG - printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl); - - printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n", - pcibr_vhdl, - pcibr_soft->bs_rrb_avail[0], - pcibr_soft->bs_rrb_avail[1]); - - for (slot = 0; slot < 8; ++slot) - printf("\t%d+%d+%d", - 0xFFF & pcibr_soft->bs_rrb_valid[slot], - 0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], - pcibr_soft->bs_rrb_res[slot]); - - printf("\n"); -#endif - } -#else - FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n"); -#endif - - if (aa) - async_attach_add_info(noslot_conn, aa); - - pciio_device_attach(noslot_conn, 0); - - - /* - * Tear down pointer to async attach info -- async threads for - * bridge's descendants may be running but the bridge's work is done. - */ - if (aa) - async_attach_del_info(xconn_vhdl); - - return 0; -} -/* - * pcibr_detach: - * Detach the bridge device from the hwgraph after cleaning out all the - * underlying vertices. - */ -int -pcibr_detach(devfs_handle_t xconn) -{ - pciio_slot_t slot; - devfs_handle_t pcibr_vhdl; - pcibr_soft_t pcibr_soft; - bridge_t *bridge; - - /* Get the bridge vertex from its xtalk connection point */ - if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS) - return(1); - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge = pcibr_soft->bs_base; - - /* Disable the interrupts from the bridge */ - bridge->b_int_enable = 0; - - /* Detach all the PCI devices talking to this bridge */ - for(slot = 0; slot < 8; slot++) { -#ifdef DEBUG - printk("pcibr_device_detach called for %p/%d\n", - pcibr_vhdl,slot); -#endif - pcibr_slot_detach(pcibr_vhdl, slot, 0); - } - - /* Unregister the no-slot connection point */ - pciio_device_info_unregister(pcibr_vhdl, - &(pcibr_soft->bs_noslot_info->f_c)); - - spin_lock_destroy(&pcibr_soft->bs_lock); - kfree(pcibr_soft->bs_name); - - /* Error handler gets unregistered when the widget info is - * cleaned - */ - /* Free the soft ATE maps */ - if (pcibr_soft->bs_int_ate_map) - rmfreemap(pcibr_soft->bs_int_ate_map); - if (pcibr_soft->bs_ext_ate_map) - rmfreemap(pcibr_soft->bs_ext_ate_map); - - /* Disconnect the error interrupt and free the xtalk resources - * associated with it. - */ - xtalk_intr_disconnect(pcibr_soft->bsi_err_intr); - xtalk_intr_free(pcibr_soft->bsi_err_intr); - - /* Clear the software state maintained by the bridge driver for this - * bridge. - */ - DEL(pcibr_soft); - /* Remove the Bridge revision labelled info */ - (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL); - /* Remove the character device associated with this bridge */ - (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL); - /* Remove the PCI bridge vertex */ - (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL); - - return(0); -} - -int -pcibr_asic_rev(devfs_handle_t pconn_vhdl) -{ - devfs_handle_t pcibr_vhdl; - arbitrary_info_t ainfo; - - if (GRAPH_SUCCESS != - hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl)) - return -1; - - if (GRAPH_SUCCESS != - hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo)) - return -1; - - return (int) ainfo; -} - -int -pcibr_write_gather_flush(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - pciio_slot_t slot; - slot = pciio_info_slot_get(pciio_info); - pcibr_device_write_gather_flush(pcibr_soft, slot); - return 0; -} - -/* ===================================================================== - * PIO MANAGEMENT - */ - -LOCAL iopaddr_t -pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, - pciio_slot_t slot, - pciio_space_t space, - iopaddr_t pci_addr, - size_t req_size, - unsigned flags) -{ - pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); - pciio_info_t pciio_info = &pcibr_info->f_c; - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - - unsigned bar; /* which BASE reg on device is decoding */ - iopaddr_t xio_addr = XIO_NOWHERE; - - pciio_space_t wspace; /* which space device is decoding */ - iopaddr_t wbase; /* base of device decode on PCI */ - size_t wsize; /* size of device decode on PCI */ - - int try; /* DevIO(x) window scanning order control */ - int win; /* which DevIO(x) window is being used */ - pciio_space_t mspace; /* target space for devio(x) register */ - iopaddr_t mbase; /* base of devio(x) mapped area on PCI */ - size_t msize; /* size of devio(x) mapped area on PCI */ - size_t mmask; /* addr bits stored in Device(x) */ - - unsigned long s; - - s = pcibr_lock(pcibr_soft); - - if (pcibr_soft->bs_slot[slot].has_host) { - slot = pcibr_soft->bs_slot[slot].host_slot; - pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0]; - } - if (space == PCIIO_SPACE_NONE) - goto done; - - if (space == PCIIO_SPACE_CFG) { - /* - * Usually, the first mapping - * established to a PCI device - * is to its config space. - * - * In any case, we definitely - * do NOT need to worry about - * PCI BASE registers, and - * MUST NOT attempt to point - * the DevIO(x) window at - * this access ... - */ - if (((flags & PCIIO_BYTE_STREAM) == 0) && - ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF)) - xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot); - - goto done; - } - if (space == PCIIO_SPACE_ROM) { - /* PIO to the Expansion Rom. - * Driver is responsible for - * enabling and disabling - * decodes properly. - */ - wbase = pcibr_info->f_rbase; - wsize = pcibr_info->f_rsize; - - /* - * While the driver should know better - * than to attempt to map more space - * than the device is decoding, he might - * do it; better to bail out here. - */ - if ((pci_addr + req_size) > wsize) - goto done; - - pci_addr += wbase; - space = PCIIO_SPACE_MEM; - } - /* - * reduce window mappings to raw - * space mappings (maybe allocating - * windows), and try for DevIO(x) - * usage (setting it if it is available). - */ - bar = space - PCIIO_SPACE_WIN0; - if (bar < 6) { - wspace = pcibr_info->f_window[bar].w_space; - if (wspace == PCIIO_SPACE_NONE) - goto done; - - /* get PCI base and size */ - wbase = pcibr_info->f_window[bar].w_base; - wsize = pcibr_info->f_window[bar].w_size; - - /* - * While the driver should know better - * than to attempt to map more space - * than the device is decoding, he might - * do it; better to bail out here. - */ - if ((pci_addr + req_size) > wsize) - goto done; - - /* shift from window relative to - * decoded space relative. - */ - pci_addr += wbase; - space = wspace; - } else - bar = -1; - - /* Scan all the DevIO(x) windows twice looking for one - * that can satisfy our request. The first time through, - * only look at assigned windows; the second time, also - * look at PCIIO_SPACE_NONE windows. Arrange the order - * so we always look at our own window first. - * - * We will not attempt to satisfy a single request - * by concatinating multiple windows. - */ - for (try = 0; try < 16; ++try) { - bridgereg_t devreg; - unsigned offset; - - win = (try + slot) % 8; - - /* If this DevIO(x) mapping area can provide - * a mapping to this address, use it. - */ - msize = (win < 2) ? 0x200000 : 0x100000; - mmask = -msize; - if (space != PCIIO_SPACE_IO) - mmask &= 0x3FFFFFFF; - - offset = pci_addr & (msize - 1); - - /* If this window can't possibly handle that request, - * go on to the next window. - */ - if (((pci_addr & (msize - 1)) + req_size) > msize) - continue; - - devreg = pcibr_soft->bs_slot[win].bss_device; - - /* Is this window "nailed down"? - * If not, maybe we can use it. - * (only check this the second time through) - */ - mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space; - if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) { - - /* If this is the primary DevIO(x) window - * for some other device, skip it. - */ - if ((win != slot) && - (PCIIO_VENDOR_ID_NONE != - pcibr_soft->bs_slot[win].bss_vendor_id)) - continue; - - /* It's a free window, and we fit in it. - * Set up Device(win) to our taste. - */ - mbase = pci_addr & mmask; - - /* check that we would really get from - * here to there. - */ - if ((mbase | offset) != pci_addr) - continue; - - devreg &= ~BRIDGE_DEV_OFF_MASK; - if (space != PCIIO_SPACE_IO) - devreg |= BRIDGE_DEV_DEV_IO_MEM; - else - devreg &= ~BRIDGE_DEV_DEV_IO_MEM; - devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK; - - /* default is WORD_VALUES. - * if you specify both, - * operation is undefined. - */ - if (flags & PCIIO_BYTE_STREAM) - devreg |= BRIDGE_DEV_DEV_SWAP; - else - devreg &= ~BRIDGE_DEV_DEV_SWAP; - - if (pcibr_soft->bs_slot[win].bss_device != devreg) { - bridge->b_device[win].reg = devreg; - pcibr_soft->bs_slot[win].bss_device = devreg; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - -#if DEBUG && PCI_DEBUG - printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg); -#endif - } - pcibr_soft->bs_slot[win].bss_devio.bssd_space = space; - pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase; - xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase); - -#if DEBUG && PCI_DEBUG - printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", - __FUNCTION__, __LINE__, space, space_desc, - pci_addr, pci_addr + req_size - 1, - slot, win, devreg); -#endif - - goto done; - } /* endif DevIO(x) not pointed */ - mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base; - - /* Now check for request incompat with DevIO(x) - */ - if ((mspace != space) || - (pci_addr < mbase) || - ((pci_addr + req_size) > (mbase + msize)) || - ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) || - (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP))) - continue; - - /* DevIO(x) window is pointed at PCI space - * that includes our target. Calculate the - * final XIO address, release the lock and - * return. - */ - xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase); - -#if DEBUG && PCI_DEBUG - printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n", - __FUNCTION__, __LINE__, space, pci_addr, pci_addr + req_size - 1, slot, win); -#endif - goto done; - } - - switch (space) { - /* - * Accesses to device decode - * areas that do a not fit - * within the DevIO(x) space are - * modified to be accesses via - * the direct mapping areas. - * - * If necessary, drivers can - * explicitly ask for mappings - * into these address spaces, - * but this should never be needed. - */ - case PCIIO_SPACE_MEM: /* "mem space" */ - case PCIIO_SPACE_MEM32: /* "mem, use 32-bit-wide bus" */ - if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <= - BRIDGE_PCI_MEM32_LIMIT) - xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE; - break; - - case PCIIO_SPACE_MEM64: /* "mem, use 64-bit-wide bus" */ - if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <= - BRIDGE_PCI_MEM64_LIMIT) - xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE; - break; - - case PCIIO_SPACE_IO: /* "i/o space" */ - /* Bridge Hardware Bug WAR #482741: - * The 4G area that maps directly from - * XIO space to PCI I/O space is busted - * until Bridge Rev D. - */ - if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) && - ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <= - BRIDGE_PCI_IO_LIMIT)) - xio_addr = pci_addr + BRIDGE_PCI_IO_BASE; - break; - } - - /* Check that "Direct PIO" byteswapping matches, - * try to change it if it does not. - */ - if (xio_addr != XIO_NOWHERE) { - unsigned bst; /* nonzero to set bytestream */ - unsigned *bfp; /* addr of record of how swapper is set */ - unsigned swb; /* which control bit to mung */ - unsigned bfo; /* current swapper setting */ - unsigned bfn; /* desired swapper setting */ - - bfp = ((space == PCIIO_SPACE_IO) - ? (&pcibr_soft->bs_pio_end_io) - : (&pcibr_soft->bs_pio_end_mem)); - - bfo = *bfp; - - bst = flags & PCIIO_BYTE_STREAM; - - bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES; - - if (bfn == bfo) { /* we already match. */ - ; - } else if (bfo != 0) { /* we have a conflict. */ -#if DEBUG && PCI_DEBUG - printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n", - space, - bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "", - bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "", - bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "", - bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : ""); -#endif - xio_addr = XIO_NOWHERE; - } else { /* OK to make the change. */ - bridgereg_t octl, nctl; - - swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP; - octl = bridge->b_wid_control; - nctl = bst ? octl | swb : octl & ~swb; - - if (octl != nctl) /* make the change if any */ - bridge->b_wid_control = nctl; - - *bfp = bfn; /* record the assignment */ - -#if DEBUG && PCI_DEBUG - printk("pcibr_addr_pci_to_xio: swap for space %d set to%s%s\n", - space, - bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "", - bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : ""); -#endif - } - } - done: - pcibr_unlock(pcibr_soft, s); - return xio_addr; -} - -/*ARGSUSED6 */ -pcibr_piomap_t -pcibr_piomap_alloc(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - pciio_space_t space, - iopaddr_t pci_addr, - size_t req_size, - size_t req_size_max, - unsigned flags) -{ - pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); - pciio_info_t pciio_info = &pcibr_info->f_c; - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - - pcibr_piomap_t *mapptr; - pcibr_piomap_t maplist; - pcibr_piomap_t pcibr_piomap; - iopaddr_t xio_addr; - xtalk_piomap_t xtalk_piomap; - unsigned long s; - - /* Make sure that the req sizes are non-zero */ - if ((req_size < 1) || (req_size_max < 1)) - return NULL; - - /* - * Code to translate slot/space/addr - * into xio_addr is common between - * this routine and pcibr_piotrans_addr. - */ - xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags); - - if (xio_addr == XIO_NOWHERE) - return NULL; - - /* Check the piomap list to see if there is already an allocated - * piomap entry but not in use. If so use that one. Otherwise - * allocate a new piomap entry and add it to the piomap list - */ - mapptr = &(pcibr_info->f_piomap); - - s = pcibr_lock(pcibr_soft); - for (pcibr_piomap = *mapptr; - pcibr_piomap != NULL; - pcibr_piomap = pcibr_piomap->bp_next) { - if (pcibr_piomap->bp_mapsz == 0) - break; - } - - if (pcibr_piomap) - mapptr = NULL; - else { - pcibr_unlock(pcibr_soft, s); - NEW(pcibr_piomap); - } - - pcibr_piomap->bp_dev = pconn_vhdl; - pcibr_piomap->bp_slot = pciio_slot; - pcibr_piomap->bp_flags = flags; - pcibr_piomap->bp_space = space; - pcibr_piomap->bp_pciaddr = pci_addr; - pcibr_piomap->bp_mapsz = req_size; - pcibr_piomap->bp_soft = pcibr_soft; - pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0); - - if (mapptr) { - s = pcibr_lock(pcibr_soft); - maplist = *mapptr; - pcibr_piomap->bp_next = maplist; - *mapptr = pcibr_piomap; - } - pcibr_unlock(pcibr_soft, s); - - - if (pcibr_piomap) { - xtalk_piomap = - xtalk_piomap_alloc(xconn_vhdl, 0, - xio_addr, - req_size, req_size_max, - flags & PIOMAP_FLAGS); - if (xtalk_piomap) { - pcibr_piomap->bp_xtalk_addr = xio_addr; - pcibr_piomap->bp_xtalk_pio = xtalk_piomap; - } else { - pcibr_piomap->bp_mapsz = 0; - pcibr_piomap = 0; - } - } - return pcibr_piomap; -} - -/*ARGSUSED */ -void -pcibr_piomap_free(pcibr_piomap_t pcibr_piomap) -{ - xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio); - pcibr_piomap->bp_xtalk_pio = 0; - pcibr_piomap->bp_mapsz = 0; -} - -/*ARGSUSED */ -caddr_t -pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap, - iopaddr_t pci_addr, - size_t req_size) -{ - return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio, - pcibr_piomap->bp_xtalk_addr + - pci_addr - pcibr_piomap->bp_pciaddr, - req_size); -} - -/*ARGSUSED */ -void -pcibr_piomap_done(pcibr_piomap_t pcibr_piomap) -{ - xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio); -} - -/*ARGSUSED */ -caddr_t -pcibr_piotrans_addr(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - pciio_space_t space, - iopaddr_t pci_addr, - size_t req_size, - unsigned flags) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - - iopaddr_t xio_addr; - - xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags); - - if (xio_addr == XIO_NOWHERE) - return NULL; - - return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS); -} - -/* - * PIO Space allocation and management. - * Allocate and Manage the PCI PIO space (mem and io space) - * This routine is pretty simplistic at this time, and - * does pretty trivial management of allocation and freeing.. - * The current scheme is prone for fragmentation.. - * Change the scheme to use bitmaps. - */ - -/*ARGSUSED */ -iopaddr_t -pcibr_piospace_alloc(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - pciio_space_t space, - size_t req_size, - size_t alignment) -{ - pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); - pciio_info_t pciio_info = &pcibr_info->f_c; - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - pciio_piospace_t piosp; - unsigned long s; - - iopaddr_t *pciaddr, *pcilast; - iopaddr_t start_addr; - size_t align_mask; - - /* - * Check for proper alignment - */ - ASSERT(alignment >= NBPP); - ASSERT((alignment & (alignment - 1)) == 0); - - align_mask = alignment - 1; - s = pcibr_lock(pcibr_soft); - - /* - * First look if a previously allocated chunk exists. - */ - if ((piosp = pcibr_info->f_piospace)) { - /* - * Look through the list for a right sized free chunk. - */ - do { - if (piosp->free && - (piosp->space == space) && - (piosp->count >= req_size) && - !(piosp->start & align_mask)) { - piosp->free = 0; - pcibr_unlock(pcibr_soft, s); - return piosp->start; - } - piosp = piosp->next; - } while (piosp); - } - ASSERT(!piosp); - - switch (space) { - case PCIIO_SPACE_IO: - pciaddr = &pcibr_soft->bs_spinfo.pci_io_base; - pcilast = &pcibr_soft->bs_spinfo.pci_io_last; - break; - case PCIIO_SPACE_MEM: - case PCIIO_SPACE_MEM32: - pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base; - pcilast = &pcibr_soft->bs_spinfo.pci_mem_last; - break; - default: - ASSERT(0); - pcibr_unlock(pcibr_soft, s); - return 0; - } - - start_addr = *pciaddr; - - /* - * Align start_addr. - */ - if (start_addr & align_mask) - start_addr = (start_addr + align_mask) & ~align_mask; - - if ((start_addr + req_size) > *pcilast) { - /* - * If too big a request, reject it. - */ - pcibr_unlock(pcibr_soft, s); - return 0; - } - *pciaddr = (start_addr + req_size); - - NEW(piosp); - piosp->free = 0; - piosp->space = space; - piosp->start = start_addr; - piosp->count = req_size; - piosp->next = pcibr_info->f_piospace; - pcibr_info->f_piospace = piosp; - - pcibr_unlock(pcibr_soft, s); - return start_addr; -} - -/*ARGSUSED */ -void -pcibr_piospace_free(devfs_handle_t pconn_vhdl, - pciio_space_t space, - iopaddr_t pciaddr, - size_t req_size) -{ - pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; - - pciio_piospace_t piosp; - unsigned long s; - char name[1024]; - - /* - * Look through the bridge data structures for the pciio_piospace_t - * structure corresponding to 'pciaddr' - */ - s = pcibr_lock(pcibr_soft); - piosp = pcibr_info->f_piospace; - while (piosp) { - /* - * Piospace free can only be for the complete - * chunk and not parts of it.. - */ - if (piosp->start == pciaddr) { - if (piosp->count == req_size) - break; - /* - * Improper size passed for freeing.. - * Print a message and break; - */ - hwgraph_vertex_name_get(pconn_vhdl, name, 1024); - printk(KERN_WARNING "pcibr_piospace_free: error"); - printk(KERN_WARNING "Device %s freeing size (0x%lx) different than allocated (0x%lx)", - name, req_size, piosp->count); - printk(KERN_WARNING "Freeing 0x%lx instead", piosp->count); - break; - } - piosp = piosp->next; - } - - if (!piosp) { - printk(KERN_WARNING - "pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n", - pciaddr, req_size); - pcibr_unlock(pcibr_soft, s); - return; - } - piosp->free = 1; - pcibr_unlock(pcibr_soft, s); - return; -} - -/* ===================================================================== - * DMA MANAGEMENT - * - * The Bridge ASIC provides three methods of doing - * DMA: via a "direct map" register available in - * 32-bit PCI space (which selects a contiguous 2G - * address space on some other widget), via - * "direct" addressing via 64-bit PCI space (all - * destination information comes from the PCI - * address, including transfer attributes), and via - * a "mapped" region that allows a bunch of - * different small mappings to be established with - * the PMU. - * - * For efficiency, we most prefer to use the 32-bit - * direct mapping facility, since it requires no - * resource allocations. The advantage of using the - * PMU over the 64-bit direct is that single-cycle - * PCI addressing can be used; the advantage of - * using 64-bit direct over PMU addressing is that - * we do not have to allocate entries in the PMU. - */ - -/* - * Convert PCI-generic software flags and Bridge-specific software flags - * into Bridge-specific Direct Map attribute bits. - */ -LOCAL iopaddr_t -pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft) -{ - iopaddr_t attributes = 0; - - /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */ -#ifdef LATER - ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64)); -#endif - - /* Generic macro flags - */ - if (flags & PCIIO_DMA_DATA) { /* standard data channel */ - attributes &= ~PCI64_ATTR_BAR; /* no barrier bit */ - attributes |= PCI64_ATTR_PREF; /* prefetch on */ - } - if (flags & PCIIO_DMA_CMD) { /* standard command channel */ - attributes |= PCI64_ATTR_BAR; /* barrier bit on */ - attributes &= ~PCI64_ATTR_PREF; /* disable prefetch */ - } - /* Generic detail flags - */ - if (flags & PCIIO_PREFETCH) - attributes |= PCI64_ATTR_PREF; - if (flags & PCIIO_NOPREFETCH) - attributes &= ~PCI64_ATTR_PREF; - - /* the swap bit is in the address attributes for xbridge */ - if (pcibr_soft->bs_xbridge) { - if (flags & PCIIO_BYTE_STREAM) - attributes |= PCI64_ATTR_SWAP; - if (flags & PCIIO_WORD_VALUES) - attributes &= ~PCI64_ATTR_SWAP; - } - - /* Provider-specific flags - */ - if (flags & PCIBR_BARRIER) - attributes |= PCI64_ATTR_BAR; - if (flags & PCIBR_NOBARRIER) - attributes &= ~PCI64_ATTR_BAR; - - if (flags & PCIBR_PREFETCH) - attributes |= PCI64_ATTR_PREF; - if (flags & PCIBR_NOPREFETCH) - attributes &= ~PCI64_ATTR_PREF; - - if (flags & PCIBR_PRECISE) - attributes |= PCI64_ATTR_PREC; - if (flags & PCIBR_NOPRECISE) - attributes &= ~PCI64_ATTR_PREC; - - if (flags & PCIBR_VCHAN1) - attributes |= PCI64_ATTR_VIRTUAL; - if (flags & PCIBR_VCHAN0) - attributes &= ~PCI64_ATTR_VIRTUAL; - - return (attributes); -} - -/* - * Convert PCI-generic software flags and Bridge-specific software flags - * into Bridge-specific Address Translation Entry attribute bits. - */ -LOCAL bridge_ate_t -pcibr_flags_to_ate(unsigned flags) -{ - bridge_ate_t attributes; - - /* default if nothing specified: - * NOBARRIER - * NOPREFETCH - * NOPRECISE - * COHERENT - * Plus the valid bit - */ - attributes = ATE_CO | ATE_V; - - /* Generic macro flags - */ - if (flags & PCIIO_DMA_DATA) { /* standard data channel */ - attributes &= ~ATE_BAR; /* no barrier */ - attributes |= ATE_PREF; /* prefetch on */ - } - if (flags & PCIIO_DMA_CMD) { /* standard command channel */ - attributes |= ATE_BAR; /* barrier bit on */ - attributes &= ~ATE_PREF; /* disable prefetch */ - } - /* Generic detail flags - */ - if (flags & PCIIO_PREFETCH) - attributes |= ATE_PREF; - if (flags & PCIIO_NOPREFETCH) - attributes &= ~ATE_PREF; - - /* Provider-specific flags - */ - if (flags & PCIBR_BARRIER) - attributes |= ATE_BAR; - if (flags & PCIBR_NOBARRIER) - attributes &= ~ATE_BAR; - - if (flags & PCIBR_PREFETCH) - attributes |= ATE_PREF; - if (flags & PCIBR_NOPREFETCH) - attributes &= ~ATE_PREF; - - if (flags & PCIBR_PRECISE) - attributes |= ATE_PREC; - if (flags & PCIBR_NOPRECISE) - attributes &= ~ATE_PREC; - - return (attributes); -} - -/*ARGSUSED */ -pcibr_dmamap_t -pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - size_t req_size_max, - unsigned flags) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - pciio_slot_t slot; - xwidgetnum_t xio_port; - - xtalk_dmamap_t xtalk_dmamap; - pcibr_dmamap_t pcibr_dmamap; - int ate_count; - int ate_index; - - /* merge in forced flags */ - flags |= pcibr_soft->bs_dma_flags; - -#ifdef IRIX - NEWf(pcibr_dmamap, flags); -#else - /* - * On SNIA64, these maps are pre-allocated because pcibr_dmamap_alloc() - * can be called within an interrupt thread. - */ - pcibr_dmamap = (pcibr_dmamap_t)get_free_pciio_dmamap(pcibr_soft->bs_vhdl); -#endif - - if (!pcibr_dmamap) - return 0; - - xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max, - flags & DMAMAP_FLAGS); - if (!xtalk_dmamap) { -#if PCIBR_ATE_DEBUG - printk("pcibr_attach: xtalk_dmamap_alloc failed\n"); -#endif -#ifdef IRIX - DEL(pcibr_dmamap); -#else - free_pciio_dmamap(pcibr_dmamap); -#endif - return 0; - } - xio_port = pcibr_soft->bs_mxid; - slot = pciio_info_slot_get(pciio_info); - - pcibr_dmamap->bd_dev = pconn_vhdl; - pcibr_dmamap->bd_slot = slot; - pcibr_dmamap->bd_soft = pcibr_soft; - pcibr_dmamap->bd_xtalk = xtalk_dmamap; - pcibr_dmamap->bd_max_size = req_size_max; - pcibr_dmamap->bd_xio_port = xio_port; - - if (flags & PCIIO_DMA_A64) { - if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) { - iopaddr_t pci_addr; - int have_rrbs; - int min_rrbs; - - /* Device is capable of A64 operations, - * and the attributes of the DMA are - * consistant with any previous DMA - * mappings using shared resources. - */ - - pci_addr = pcibr_flags_to_d64(flags, pcibr_soft); - - pcibr_dmamap->bd_flags = flags; - pcibr_dmamap->bd_xio_addr = 0; - pcibr_dmamap->bd_pci_addr = pci_addr; - - /* Make sure we have an RRB (or two). - */ - if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) { - if (flags & PCIBR_VCHAN1) - slot += PCIBR_RRB_SLOT_VIRTUAL; - have_rrbs = pcibr_soft->bs_rrb_valid[slot]; - if (have_rrbs < 2) { - if (pci_addr & PCI64_ATTR_PREF) - min_rrbs = 2; - else - min_rrbs = 1; - if (have_rrbs < min_rrbs) - do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs); - } - } -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_alloc: using direct64\n"); -#endif - return pcibr_dmamap; - } -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_alloc: unable to use direct64\n"); -#endif - flags &= ~PCIIO_DMA_A64; - } - if (flags & PCIIO_FIXED) { - /* warning: mappings may fail later, - * if direct32 can't get to the address. - */ - if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) { - /* User desires DIRECT A32 operations, - * and the attributes of the DMA are - * consistant with any previous DMA - * mappings using shared resources. - * Mapping calls may fail if target - * is outside the direct32 range. - */ -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_alloc: using direct32\n"); -#endif - pcibr_dmamap->bd_flags = flags; - pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase; - pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE; - return pcibr_dmamap; - } -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_alloc: unable to use direct32\n"); -#endif - /* If the user demands FIXED and we can't - * give it to him, fail. - */ - xtalk_dmamap_free(xtalk_dmamap); -#ifdef IRIX - DEL(pcibr_dmamap); -#else - free_pciio_dmamap(pcibr_dmamap); -#endif - return 0; - } - /* - * Allocate Address Translation Entries from the mapping RAM. - * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified, - * the maximum number of ATEs is based on the worst-case - * scenario, where the requested target is in the - * last byte of an ATE; thus, mapping IOPGSIZE+2 - * does end up requiring three ATEs. - */ - if (!(flags & PCIBR_NO_ATE_ROUNDUP)) { - ate_count = IOPG((IOPGSIZE - 1) /* worst case start offset */ - +req_size_max /* max mapping bytes */ - - 1) + 1; /* round UP */ - } else { /* assume requested target is page aligned */ - ate_count = IOPG(req_size_max /* max mapping bytes */ - - 1) + 1; /* round UP */ - } - - ate_index = pcibr_ate_alloc(pcibr_soft, ate_count); - - if (ate_index != -1) { - if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) { - bridge_ate_t ate_proto; - int have_rrbs; - int min_rrbs; - -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_alloc: using PMU\n"); -#endif - - ate_proto = pcibr_flags_to_ate(flags); - - pcibr_dmamap->bd_flags = flags; - pcibr_dmamap->bd_pci_addr = - PCI32_MAPPED_BASE + IOPGSIZE * ate_index; - /* - * for xbridge the byte-swap bit == bit 29 of PCI address - */ - if (pcibr_soft->bs_xbridge) { - if (flags & PCIIO_BYTE_STREAM) - ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr); - /* - * If swap was set in bss_device in pcibr_endian_set() - * we need to change the address bit. - */ - if (pcibr_soft->bs_slot[slot].bss_device & - BRIDGE_DEV_SWAP_PMU) - ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr); - if (flags & PCIIO_WORD_VALUES) - ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr); - } - pcibr_dmamap->bd_xio_addr = 0; - pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index); - pcibr_dmamap->bd_ate_index = ate_index; - pcibr_dmamap->bd_ate_count = ate_count; - pcibr_dmamap->bd_ate_proto = ate_proto; - - /* Make sure we have an RRB (or two). - */ - if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) { - have_rrbs = pcibr_soft->bs_rrb_valid[slot]; - if (have_rrbs < 2) { - if (ate_proto & ATE_PREF) - min_rrbs = 2; - else - min_rrbs = 1; - if (have_rrbs < min_rrbs) - do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs); - } - } - if (ate_index >= pcibr_soft->bs_int_ate_size && - !pcibr_soft->bs_xbridge) { - bridge_t *bridge = pcibr_soft->bs_base; - volatile unsigned *cmd_regp; - unsigned cmd_reg; - unsigned long s; - - pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM; - - s = pcibr_lock(pcibr_soft); - cmd_regp = &(bridge-> - b_type0_cfg_dev[slot]. - l[PCI_CFG_COMMAND / 4]); - cmd_reg = *cmd_regp; - pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp; - pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg; - pcibr_unlock(pcibr_soft, s); - } - return pcibr_dmamap; - } -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_alloc: unable to use PMU\n"); -#endif - pcibr_ate_free(pcibr_soft, ate_index, ate_count); - } - /* total failure: sorry, you just can't - * get from here to there that way. - */ -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_alloc: complete failure.\n"); -#endif - xtalk_dmamap_free(xtalk_dmamap); -#ifdef IRIX - DEL(pcibr_dmamap); -#else - free_pciio_dmamap(pcibr_dmamap); -#endif - return 0; -} - -/*ARGSUSED */ -void -pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap) -{ - pcibr_soft_t pcibr_soft = pcibr_dmamap->bd_soft; - pciio_slot_t slot = pcibr_dmamap->bd_slot; - - unsigned flags = pcibr_dmamap->bd_flags; - - /* Make sure that bss_ext_ates_active - * is properly kept up to date. - */ - - if (PCIBR_DMAMAP_BUSY & flags) - if (PCIBR_DMAMAP_SSRAM & flags) - atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active)); - - xtalk_dmamap_free(pcibr_dmamap->bd_xtalk); - - if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) { - pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS); - } - if (pcibr_dmamap->bd_ate_count) { - pcibr_ate_free(pcibr_dmamap->bd_soft, - pcibr_dmamap->bd_ate_index, - pcibr_dmamap->bd_ate_count); - pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS); - } -#ifdef IRIX - DEL(pcibr_dmamap); -#else - free_pciio_dmamap(pcibr_dmamap); -#endif -} - -/* - * Setup an Address Translation Entry as specified. Use either the Bridge - * internal maps or the external map RAM, as appropriate. - */ -LOCAL bridge_ate_p -pcibr_ate_addr(pcibr_soft_t pcibr_soft, - int ate_index) -{ - bridge_t *bridge = pcibr_soft->bs_base; - - return (ate_index < pcibr_soft->bs_int_ate_size) - ? &(bridge->b_int_ate_ram[ate_index].wr) - : &(bridge->b_ext_ate_ram[ate_index]); -} - -/* - * pcibr_addr_xio_to_pci: given a PIO range, hand - * back the corresponding base PCI MEM address; - * this is used to short-circuit DMA requests that - * loop back onto this PCI bus. - */ -LOCAL iopaddr_t -pcibr_addr_xio_to_pci(pcibr_soft_t soft, - iopaddr_t xio_addr, - size_t req_size) -{ - iopaddr_t xio_lim = xio_addr + req_size - 1; - iopaddr_t pci_addr; - pciio_slot_t slot; - - if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) && - (xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) { - pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE; - return pci_addr; - } - if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) && - (xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) { - pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE; - return pci_addr; - } - for (slot = 0; slot < 8; ++slot) - if ((xio_addr >= BRIDGE_DEVIO(slot)) && - (xio_lim < BRIDGE_DEVIO(slot + 1))) { - bridgereg_t dev; - - dev = soft->bs_slot[slot].bss_device; - pci_addr = dev & BRIDGE_DEV_OFF_MASK; - pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT; - pci_addr += xio_addr - BRIDGE_DEVIO(slot); - return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE; - } - return 0; -} - -/* We are starting to get more complexity - * surrounding writing ATEs, so pull - * the writing code into this new function. - */ - -#if PCIBR_FREEZE_TIME -#define ATE_FREEZE() s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs) -#else -#define ATE_FREEZE() s = ate_freeze(pcibr_dmamap, cmd_regs) -#endif - -LOCAL unsigned -ate_freeze(pcibr_dmamap_t pcibr_dmamap, -#if PCIBR_FREEZE_TIME - unsigned *freeze_time_ptr, -#endif - unsigned *cmd_regs) -{ - pcibr_soft_t pcibr_soft = pcibr_dmamap->bd_soft; -#ifdef LATER - int dma_slot = pcibr_dmamap->bd_slot; -#endif - int ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM; - int slot; - - unsigned long s; - unsigned cmd_reg; - volatile unsigned *cmd_lwa; - unsigned cmd_lwd; - - if (!ext_ates) - return 0; - - /* Bridge Hardware Bug WAR #484930: - * Bridge can't handle updating External ATEs - * while DMA is occuring that uses External ATEs, - * even if the particular ATEs involved are disjoint. - */ - - /* need to prevent anyone else from - * unfreezing the grant while we - * are working; also need to prevent - * this thread from being interrupted - * to keep PCI grant freeze time - * at an absolute minimum. - */ - s = pcibr_lock(pcibr_soft); - -#ifdef LATER - /* just in case pcibr_dmamap_done was not called */ - if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) { - pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY; - if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM) - atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active)); - xtalk_dmamap_done(pcibr_dmamap->bd_xtalk); - } -#endif /* LATER */ -#if PCIBR_FREEZE_TIME - *freeze_time_ptr = get_timestamp(); -#endif - - cmd_lwa = 0; - for (slot = 0; slot < 8; ++slot) - if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) { - cmd_reg = pcibr_soft-> - bs_slot[slot]. - bss_cmd_shadow; - if (cmd_reg & PCI_CMD_BUS_MASTER) { - cmd_lwa = pcibr_soft-> - bs_slot[slot]. - bss_cmd_pointer; - cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER; - cmd_lwa[0] = cmd_lwd; - } - cmd_regs[slot] = cmd_reg; - } else - cmd_regs[slot] = 0; - - if (cmd_lwa) { - bridge_t *bridge = pcibr_soft->bs_base; - - /* Read the last master bit that has been cleared. This PIO read - * on the PCI bus is to ensure the completion of any DMAs that - * are due to bus requests issued by PCI devices before the - * clearing of master bits. - */ - cmd_lwa[0]; - - /* Flush all the write buffers in the bridge */ - for (slot = 0; slot < 8; ++slot) - if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) { - /* Flush the write buffer associated with this - * PCI device which might be using dma map RAM. - */ - bridge->b_wr_req_buf[slot].reg; - } - } - return s; -} - -#define ATE_WRITE() ate_write(ate_ptr, ate_count, ate) - -LOCAL void -ate_write(bridge_ate_p ate_ptr, - int ate_count, - bridge_ate_t ate) -{ - while (ate_count-- > 0) { - *ate_ptr++ = ate; - ate += IOPGSIZE; - } -} - - -#if PCIBR_FREEZE_TIME -#define ATE_THAW() ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s) -#else -#define ATE_THAW() ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s) -#endif - -LOCAL void -ate_thaw(pcibr_dmamap_t pcibr_dmamap, - int ate_index, -#if PCIBR_FREEZE_TIME - bridge_ate_t ate, - int ate_total, - unsigned freeze_time_start, -#endif - unsigned *cmd_regs, - unsigned s) -{ - pcibr_soft_t pcibr_soft = pcibr_dmamap->bd_soft; - int dma_slot = pcibr_dmamap->bd_slot; - int slot; - bridge_t *bridge = pcibr_soft->bs_base; - int ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM; - - unsigned cmd_reg; - -#if PCIBR_FREEZE_TIME - unsigned freeze_time; - static unsigned max_freeze_time = 0; - static unsigned max_ate_total; -#endif - - if (!ext_ates) - return; - - /* restore cmd regs */ - for (slot = 0; slot < 8; ++slot) - if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER) - bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg; - - pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY; - atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active)); - -#if PCIBR_FREEZE_TIME - freeze_time = get_timestamp() - freeze_time_start; - - if ((max_freeze_time < freeze_time) || - (max_ate_total < ate_total)) { - if (max_freeze_time < freeze_time) - max_freeze_time = freeze_time; - if (max_ate_total < ate_total) - max_ate_total = ate_total; - pcibr_unlock(pcibr_soft, s); - printk("%s: pci freeze time %d usec for %d ATEs\n" - "\tfirst ate: %R\n", - pcibr_soft->bs_name, - freeze_time * 1000 / 1250, - ate_total, - ate, ate_bits); - } else -#endif - pcibr_unlock(pcibr_soft, s); -} - -/*ARGSUSED */ -iopaddr_t -pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap, - paddr_t paddr, - size_t req_size) -{ - pcibr_soft_t pcibr_soft; - iopaddr_t xio_addr; - xwidgetnum_t xio_port; - iopaddr_t pci_addr; - unsigned flags; - - ASSERT(pcibr_dmamap != NULL); - ASSERT(req_size > 0); - ASSERT(req_size <= pcibr_dmamap->bd_max_size); - - pcibr_soft = pcibr_dmamap->bd_soft; - - flags = pcibr_dmamap->bd_flags; - - xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size); - if (XIO_PACKED(xio_addr)) { - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - } else - xio_port = pcibr_dmamap->bd_xio_port; - - /* If this DMA is to an address that - * refers back to this Bridge chip, - * reduce it back to the correct - * PCI MEM address. - */ - if (xio_port == pcibr_soft->bs_xid) { - pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size); - } else if (flags & PCIIO_DMA_A64) { - /* A64 DMA: - * always use 64-bit direct mapping, - * which always works. - * Device(x) was set up during - * dmamap allocation. - */ - - /* attributes are already bundled up into bd_pci_addr. - */ - pci_addr = pcibr_dmamap->bd_pci_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT) - | xio_addr; - - /* Bridge Hardware WAR #482836: - * If the transfer is not cache aligned - * and the Bridge Rev is <= B, force - * prefetch to be off. - */ - if (flags & PCIBR_NOPREFETCH) - pci_addr &= ~PCI64_ATTR_PREF; - -#if DEBUG && PCIBR_DMA_DEBUG - printk("pcibr_dmamap_addr (direct64):\n" - "\twanted paddr [0x%x..0x%x]\n" - "\tXIO port 0x%x offset 0x%x\n" - "\treturning PCI 0x%x\n", - paddr, paddr + req_size - 1, - xio_port, xio_addr, pci_addr); -#endif - } else if (flags & PCIIO_FIXED) { - /* A32 direct DMA: - * always use 32-bit direct mapping, - * which may fail. - * Device(x) was set up during - * dmamap allocation. - */ - - if (xio_port != pcibr_soft->bs_dir_xport) - pci_addr = 0; /* wrong DIDN */ - else if (xio_addr < pcibr_dmamap->bd_xio_addr) - pci_addr = 0; /* out of range */ - else if ((xio_addr + req_size) > - (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE)) - pci_addr = 0; /* out of range */ - else - pci_addr = pcibr_dmamap->bd_pci_addr + - xio_addr - pcibr_dmamap->bd_xio_addr; - -#if DEBUG && PCIBR_DMA_DEBUG - printk("pcibr_dmamap_addr (direct32):\n" - "\twanted paddr [0x%x..0x%x]\n" - "\tXIO port 0x%x offset 0x%x\n" - "\treturning PCI 0x%x\n", - paddr, paddr + req_size - 1, - xio_port, xio_addr, pci_addr); -#endif - } else { - bridge_t *bridge = pcibr_soft->bs_base; - iopaddr_t offset = IOPGOFF(xio_addr); - bridge_ate_t ate_proto = pcibr_dmamap->bd_ate_proto; - int ate_count = IOPG(offset + req_size - 1) + 1; - - int ate_index = pcibr_dmamap->bd_ate_index; - unsigned cmd_regs[8]; - unsigned s; - -#if PCIBR_FREEZE_TIME - int ate_total = ate_count; - unsigned freeze_time; -#endif - -#if PCIBR_ATE_DEBUG - bridge_ate_t ate_cmp; - bridge_ate_p ate_cptr; - unsigned ate_lo, ate_hi; - int ate_bad = 0; - int ate_rbc = 0; -#endif - bridge_ate_p ate_ptr = pcibr_dmamap->bd_ate_ptr; - bridge_ate_t ate; - - /* Bridge Hardware WAR #482836: - * If the transfer is not cache aligned - * and the Bridge Rev is <= B, force - * prefetch to be off. - */ - if (flags & PCIBR_NOPREFETCH) - ate_proto &= ~ATE_PREF; - - ate = ate_proto - | (xio_port << ATE_TIDSHIFT) - | (xio_addr - offset); - - pci_addr = pcibr_dmamap->bd_pci_addr + offset; - - /* Fill in our mapping registers - * with the appropriate xtalk data, - * and hand back the PCI address. - */ - - ASSERT(ate_count > 0); - if (ate_count <= pcibr_dmamap->bd_ate_count) { - ATE_FREEZE(); - ATE_WRITE(); - ATE_THAW(); - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } else { - /* The number of ATE's required is greater than the number - * allocated for this map. One way this can happen is if - * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP - * flag, and then when that map is used (right now), the - * target address tells us we really did need to roundup. - * The other possibility is that the map is just plain too - * small to handle the requested target area. - */ -#if PCIBR_ATE_DEBUG - printk(KERN_WARNING "pcibr_dmamap_addr :\n" - "\twanted paddr [0x%x..0x%x]\n" - "\tate_count 0x%x bd_ate_count 0x%x\n" - "\tATE's required > number allocated\n", - paddr, paddr + req_size - 1, - ate_count, pcibr_dmamap->bd_ate_count); -#endif - pci_addr = 0; - } - - } - return pci_addr; -} - -/*ARGSUSED */ -alenlist_t -pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap, - alenlist_t palenlist, - unsigned flags) -{ - pcibr_soft_t pcibr_soft; - bridge_t *bridge=NULL; - - unsigned al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; - int inplace = flags & PCIIO_INPLACE; - - alenlist_t pciio_alenlist = 0; - alenlist_t xtalk_alenlist; - size_t length; - iopaddr_t offset; - unsigned direct64; - int ate_index = 0; - int ate_count = 0; - int ate_total = 0; - bridge_ate_p ate_ptr = (bridge_ate_p)0; - bridge_ate_t ate_proto = (bridge_ate_t)0; - bridge_ate_t ate_prev; - bridge_ate_t ate; - alenaddr_t xio_addr; - xwidgetnum_t xio_port; - iopaddr_t pci_addr; - alenaddr_t new_addr; - - unsigned cmd_regs[8]; - unsigned s = 0; - -#if PCIBR_FREEZE_TIME - unsigned freeze_time; -#endif - int ate_freeze_done = 0; /* To pair ATE_THAW - * with an ATE_FREEZE - */ - - pcibr_soft = pcibr_dmamap->bd_soft; - - xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist, - flags & DMAMAP_FLAGS); - if (!xtalk_alenlist) - goto fail; - - alenlist_cursor_init(xtalk_alenlist, 0, NULL); - - if (inplace) { - pciio_alenlist = xtalk_alenlist; - } else { - pciio_alenlist = alenlist_create(al_flags); - if (!pciio_alenlist) - goto fail; - } - - direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64; - if (!direct64) { - bridge = pcibr_soft->bs_base; - ate_ptr = pcibr_dmamap->bd_ate_ptr; - ate_index = pcibr_dmamap->bd_ate_index; - ate_proto = pcibr_dmamap->bd_ate_proto; - ATE_FREEZE(); - ate_freeze_done = 1; /* Remember that we need to do an ATE_THAW */ - } - pci_addr = pcibr_dmamap->bd_pci_addr; - - ate_prev = 0; /* matches no valid ATEs */ - while (ALENLIST_SUCCESS == - alenlist_get(xtalk_alenlist, NULL, 0, - &xio_addr, &length, al_flags)) { - if (XIO_PACKED(xio_addr)) { - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - } else - xio_port = pcibr_dmamap->bd_xio_port; - - if (xio_port == pcibr_soft->bs_xid) { - new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length); - if (new_addr == PCI_NOWHERE) - goto fail; - } else if (direct64) { - new_addr = pci_addr | xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - - /* Bridge Hardware WAR #482836: - * If the transfer is not cache aligned - * and the Bridge Rev is <= B, force - * prefetch to be off. - */ - if (flags & PCIBR_NOPREFETCH) - new_addr &= ~PCI64_ATTR_PREF; - - } else { - /* calculate the ate value for - * the first address. If it - * matches the previous - * ATE written (ie. we had - * multiple blocks in the - * same IOPG), then back up - * and reuse that ATE. - * - * We are NOT going to - * aggressively try to - * reuse any other ATEs. - */ - offset = IOPGOFF(xio_addr); - ate = ate_proto - | (xio_port << ATE_TIDSHIFT) - | (xio_addr - offset); - if (ate == ate_prev) { -#if PCIBR_ATE_DEBUG - printk("pcibr_dmamap_list: ATE share\n"); -#endif - ate_ptr--; - ate_index--; - pci_addr -= IOPGSIZE; - } - new_addr = pci_addr + offset; - - /* Fill in the hardware ATEs - * that contain this block. - */ - ate_count = IOPG(offset + length - 1) + 1; - ate_total += ate_count; - - /* Ensure that this map contains enough ATE's */ - if (ate_total > pcibr_dmamap->bd_ate_count) { -#if PCIBR_ATE_DEBUG - printk(KERN_WARNING "pcibr_dmamap_list :\n" - "\twanted xio_addr [0x%x..0x%x]\n" - "\tate_total 0x%x bd_ate_count 0x%x\n" - "\tATE's required > number allocated\n", - xio_addr, xio_addr + length - 1, - ate_total, pcibr_dmamap->bd_ate_count); -#endif - goto fail; - } - - ATE_WRITE(); - - ate_index += ate_count; - ate_ptr += ate_count; - - ate_count <<= IOPFNSHIFT; - ate += ate_count; - pci_addr += ate_count; - } - - /* write the PCI DMA address - * out to the scatter-gather list. - */ - if (inplace) { - if (ALENLIST_SUCCESS != - alenlist_replace(pciio_alenlist, NULL, - &new_addr, &length, al_flags)) - goto fail; - } else { - if (ALENLIST_SUCCESS != - alenlist_append(pciio_alenlist, - new_addr, length, al_flags)) - goto fail; - } - } - if (!inplace) - alenlist_done(xtalk_alenlist); - - /* Reset the internal cursor of the alenlist to be returned back - * to the caller. - */ - alenlist_cursor_init(pciio_alenlist, 0, NULL); - - - /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the - * changes that ATE_FREEZE has done to implement the external SSRAM - * bug workaround. - */ - if (ate_freeze_done) { - ATE_THAW(); - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - return pciio_alenlist; - - fail: - /* There are various points of failure after doing an ATE_FREEZE - * We need to do an ATE_THAW. Otherwise the ATEs are locked forever. - * The decision to do an ATE_THAW needs to be based on whether a - * an ATE_FREEZE was done before. - */ - if (ate_freeze_done) { - ATE_THAW(); - bridge->b_wid_tflush; - } - if (pciio_alenlist && !inplace) - alenlist_destroy(pciio_alenlist); - return 0; -} - -/*ARGSUSED */ -void -pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap) -{ - /* - * We could go through and invalidate ATEs here; - * for performance reasons, we don't. - * We also don't enforce the strict alternation - * between _addr/_list and _done, but Hub does. - */ - - if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) { - pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY; - - if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM) - atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active)); - } - - xtalk_dmamap_done(pcibr_dmamap->bd_xtalk); -} - - -/* - * For each bridge, the DIR_OFF value in the Direct Mapping Register - * determines the PCI to Crosstalk memory mapping to be used for all - * 32-bit Direct Mapping memory accesses. This mapping can be to any - * node in the system. This function will return that compact node id. - */ - -/*ARGSUSED */ -cnodeid_t -pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl) -{ - - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase))); -} - -/*ARGSUSED */ -iopaddr_t -pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - paddr_t paddr, - size_t req_size, - unsigned flags) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; - - xwidgetnum_t xio_port; - iopaddr_t xio_addr; - iopaddr_t pci_addr; - - int have_rrbs; - int min_rrbs; - - /* merge in forced flags */ - flags |= pcibr_soft->bs_dma_flags; - - xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size, - flags & DMAMAP_FLAGS); - - if (!xio_addr) { -#if PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr); -#endif - return 0; - } - /* - * find which XIO port this goes to. - */ - if (XIO_PACKED(xio_addr)) { - if (xio_addr == XIO_NOWHERE) { -#if PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr); -#endif - return 0; - } - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - - } else - xio_port = pcibr_soft->bs_mxid; - - /* - * If this DMA comes back to us, - * return the PCI MEM address on - * which it would land, or NULL - * if the target is something - * on bridge other than PCI MEM. - */ - if (xio_port == pcibr_soft->bs_xid) { - pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size); - return pci_addr; - } - /* If the caller can use A64, try to - * satisfy the request with the 64-bit - * direct map. This can fail if the - * configuration bits in Device(x) - * conflict with our flags. - */ - - if (flags & PCIIO_DMA_A64) { - pci_addr = slotp->bss_d64_base; - if (!(flags & PCIBR_VCHAN1)) - flags |= PCIBR_VCHAN0; - if ((pci_addr != PCIBR_D64_BASE_UNSET) && - (flags == slotp->bss_d64_flags)) { - - pci_addr |= xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - -#if DEBUG && PCIBR_DMA_DEBUG -#if HWG_PERF_CHECK - if (xio_addr != 0x20000000) -#endif - printk("pcibr_dmatrans_addr: [reuse]\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\tdirect 64bit address is 0x%x\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr, pci_addr); -#endif - return (pci_addr); - } - if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) { - pci_addr = pcibr_flags_to_d64(flags, pcibr_soft); - slotp->bss_d64_flags = flags; - slotp->bss_d64_base = pci_addr; - pci_addr |= xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - - /* Make sure we have an RRB (or two). - */ - if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) { - if (flags & PCIBR_VCHAN1) - pciio_slot += PCIBR_RRB_SLOT_VIRTUAL; - have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot]; - if (have_rrbs < 2) { - if (pci_addr & PCI64_ATTR_PREF) - min_rrbs = 2; - else - min_rrbs = 1; - if (have_rrbs < min_rrbs) - do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs); - } - } -#if PCIBR_DMA_DEBUG -#if HWG_PERF_CHECK - if (xio_addr != 0x20000000) -#endif - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\tdirect 64bit address is 0x%x\n" - "\tnew flags: 0x%x\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr, pci_addr, (uint64_t) flags); -#endif - return (pci_addr); - } - /* our flags conflict with Device(x). - */ - flags = flags - & ~PCIIO_DMA_A64 - & ~PCIBR_VCHAN0 - ; - -#if PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\tUnable to set Device(x) bits for Direct-64\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr); -#endif - } - /* Try to satisfy the request with the 32-bit direct - * map. This can fail if the configuration bits in - * Device(x) conflict with our flags, or if the - * target address is outside where DIR_OFF points. - */ - { - size_t map_size = 1ULL << 31; - iopaddr_t xio_base = pcibr_soft->bs_dir_xbase; - iopaddr_t offset = xio_addr - xio_base; - iopaddr_t endoff = req_size + offset; - - if ((req_size > map_size) || - (xio_addr < xio_base) || - (xio_port != pcibr_soft->bs_dir_xport) || - (endoff > map_size)) { -#if PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\txio region outside direct32 target\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr); -#endif - } else { - pci_addr = slotp->bss_d32_base; - if ((pci_addr != PCIBR_D32_BASE_UNSET) && - (flags == slotp->bss_d32_flags)) { - - pci_addr |= offset; - -#if DEBUG && PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr: [reuse]\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\tmapped via direct32 offset 0x%x\n" - "\twill DMA via pci addr 0x%x\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr, offset, pci_addr); -#endif - return (pci_addr); - } - if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) { - - pci_addr = PCI32_DIRECT_BASE; - slotp->bss_d32_flags = flags; - slotp->bss_d32_base = pci_addr; - pci_addr |= offset; - - /* Make sure we have an RRB (or two). - */ - if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) { - have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot]; - if (have_rrbs < 2) { - if (slotp->bss_device & BRIDGE_DEV_PREF) - min_rrbs = 2; - else - min_rrbs = 1; - if (have_rrbs < min_rrbs) - do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs); - } - } -#if PCIBR_DMA_DEBUG -#if HWG_PERF_CHECK - if (xio_addr != 0x20000000) -#endif - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\tmapped via direct32 offset 0x%x\n" - "\twill DMA via pci addr 0x%x\n" - "\tnew flags: 0x%x\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr, offset, pci_addr, (uint64_t) flags); -#endif - return (pci_addr); - } - /* our flags conflict with Device(x). - */ -#if PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\tUnable to set Device(x) bits for Direct-32\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr); -#endif - } - } - -#if PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n" - "\tno acceptable PCI address found or constructable\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr); -#endif - - return 0; -} - -/*ARGSUSED */ -alenlist_t -pcibr_dmatrans_list(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - alenlist_t palenlist, - unsigned flags) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; - xwidgetnum_t xio_port; - - alenlist_t pciio_alenlist = 0; - alenlist_t xtalk_alenlist = 0; - - int inplace; - unsigned direct64; - unsigned al_flags; - - iopaddr_t xio_base; - alenaddr_t xio_addr; - size_t xio_size; - - size_t map_size; - iopaddr_t pci_base; - alenaddr_t pci_addr; - - unsigned relbits = 0; - - /* merge in forced flags */ - flags |= pcibr_soft->bs_dma_flags; - - inplace = flags & PCIIO_INPLACE; - direct64 = flags & PCIIO_DMA_A64; - al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; - - if (direct64) { - map_size = 1ull << 48; - xio_base = 0; - pci_base = slotp->bss_d64_base; - if ((pci_base != PCIBR_D64_BASE_UNSET) && - (flags == slotp->bss_d64_flags)) { - /* reuse previous base info */ - } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) { - /* DMA configuration conflict */ - goto fail; - } else { - relbits = BRIDGE_DEV_D64_BITS; - pci_base = - pcibr_flags_to_d64(flags, pcibr_soft); - } - } else { - xio_base = pcibr_soft->bs_dir_xbase; - map_size = 1ull << 31; - pci_base = slotp->bss_d32_base; - if ((pci_base != PCIBR_D32_BASE_UNSET) && - (flags == slotp->bss_d32_flags)) { - /* reuse previous base info */ - } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) { - /* DMA configuration conflict */ - goto fail; - } else { - relbits = BRIDGE_DEV_D32_BITS; - pci_base = PCI32_DIRECT_BASE; - } - } - - xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist, - flags & DMAMAP_FLAGS); - if (!xtalk_alenlist) - goto fail; - - alenlist_cursor_init(xtalk_alenlist, 0, NULL); - - if (inplace) { - pciio_alenlist = xtalk_alenlist; - } else { - pciio_alenlist = alenlist_create(al_flags); - if (!pciio_alenlist) - goto fail; - } - - while (ALENLIST_SUCCESS == - alenlist_get(xtalk_alenlist, NULL, 0, - &xio_addr, &xio_size, al_flags)) { - - /* - * find which XIO port this goes to. - */ - if (XIO_PACKED(xio_addr)) { - if (xio_addr == XIO_NOWHERE) { -#if PCIBR_DMA_DEBUG - printk("pcibr_dmatrans_addr:\n" - "\tpciio connection point %v\n" - "\txtalk connection point %v\n" - "\twanted paddr [0x%x..0x%x]\n" - "\txtalk_dmatrans_addr returned 0x%x\n", - pconn_vhdl, xconn_vhdl, - paddr, paddr + req_size - 1, - xio_addr); -#endif - return 0; - } - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - } else - xio_port = pcibr_soft->bs_mxid; - - /* - * If this DMA comes back to us, - * return the PCI MEM address on - * which it would land, or NULL - * if the target is something - * on bridge other than PCI MEM. - */ - if (xio_port == pcibr_soft->bs_xid) { - pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size); - if ( (pci_addr == (alenaddr_t)NULL) ) - goto fail; - } else if (direct64) { - ASSERT(xio_port != 0); - pci_addr = pci_base | xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - } else { - iopaddr_t offset = xio_addr - xio_base; - iopaddr_t endoff = xio_size + offset; - - if ((xio_size > map_size) || - (xio_addr < xio_base) || - (xio_port != pcibr_soft->bs_dir_xport) || - (endoff > map_size)) - goto fail; - - pci_addr = pci_base + (xio_addr - xio_base); - } - - /* write the PCI DMA address - * out to the scatter-gather list. - */ - if (inplace) { - if (ALENLIST_SUCCESS != - alenlist_replace(pciio_alenlist, NULL, - &pci_addr, &xio_size, al_flags)) - goto fail; - } else { - if (ALENLIST_SUCCESS != - alenlist_append(pciio_alenlist, - pci_addr, xio_size, al_flags)) - goto fail; - } - } - - if (relbits) { - if (direct64) { - slotp->bss_d64_flags = flags; - slotp->bss_d64_base = pci_base; - } else { - slotp->bss_d32_flags = flags; - slotp->bss_d32_base = pci_base; - } - } - if (!inplace) - alenlist_done(xtalk_alenlist); - - /* Reset the internal cursor of the alenlist to be returned back - * to the caller. - */ - alenlist_cursor_init(pciio_alenlist, 0, NULL); - return pciio_alenlist; - - fail: - if (relbits) - pcibr_release_device(pcibr_soft, pciio_slot, relbits); - if (pciio_alenlist && !inplace) - alenlist_destroy(pciio_alenlist); - return 0; -} - -void -pcibr_dmamap_drain(pcibr_dmamap_t map) -{ - xtalk_dmamap_drain(map->bd_xtalk); -} - -void -pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl, - paddr_t paddr, - size_t bytes) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - - xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes); -} - -void -pcibr_dmalist_drain(devfs_handle_t pconn_vhdl, - alenlist_t list) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - - xtalk_dmalist_drain(xconn_vhdl, list); -} - -/* - * Get the starting PCIbus address out of the given DMA map. - * This function is supposed to be used by a close friend of PCI bridge - * since it relies on the fact that the starting address of the map is fixed at - * the allocation time in the current implementation of PCI bridge. - */ -iopaddr_t -pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap) -{ - return (pcibr_dmamap->bd_pci_addr); -} - -/* - * There are end cases where a deadlock can occur if interrupt - * processing completes and the Bridge b_int_status bit is still set. - * - * One scenerio is if a second PCI interrupt occurs within 60ns of - * the previous interrupt being cleared. In this case the Bridge - * does not detect the transition, the Bridge b_int_status bit - * remains set, and because no transition was detected no interrupt - * packet is sent to the Hub/Heart. - * - * A second scenerio is possible when a b_int_status bit is being - * shared by multiple devices: - * Device #1 generates interrupt - * Bridge b_int_status bit set - * Device #2 generates interrupt - * interrupt processing begins - * ISR for device #1 runs and - * clears interrupt - * Device #1 generates interrupt - * ISR for device #2 runs and - * clears interrupt - * (b_int_status bit still set) - * interrupt processing completes - * - * Interrupt processing is now complete, but an interrupt is still - * outstanding for Device #1. But because there was no transition of - * the b_int_status bit, no interrupt packet will be generated and - * a deadlock will occur. - * - * To avoid these deadlock situations, this function is used - * to check if a specific Bridge b_int_status bit is set, and if so, - * cause the setting of the corresponding interrupt bit. - * - * On a XBridge (IP35), we do this by writing the appropriate Bridge Force - * Interrupt register. - */ -void -pcibr_force_interrupt(pcibr_intr_wrap_t wrap) -{ - unsigned bit; - pcibr_soft_t pcibr_soft = wrap->iw_soft; - bridge_t *bridge = pcibr_soft->bs_base; - cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl); - - bit = wrap->iw_intr; - - if (pcibr_soft->bs_xbridge) { - bridge->b_force_pin[bit].intr = 1; - } else if ((1 << bit) & *wrap->iw_stat) { - cpuid_t cpu; - unsigned intr_bit; - xtalk_intr_t xtalk_intr = - pcibr_soft->bs_intr[bit].bsi_xtalk_intr; - - intr_bit = (short) xtalk_intr_vector_get(xtalk_intr); - cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr)); - REMOTE_CPU_SEND_INTR(cpu, intr_bit); - } -} - -/* ===================================================================== - * INTERRUPT MANAGEMENT - */ - -static unsigned -pcibr_intr_bits(pciio_info_t info, - pciio_intr_line_t lines) -{ - pciio_slot_t slot = pciio_info_slot_get(info); - unsigned bbits = 0; - - /* - * Currently favored mapping from PCI - * slot number and INTA/B/C/D to Bridge - * PCI Interrupt Bit Number: - * - * SLOT A B C D - * 0 0 4 0 4 - * 1 1 5 1 5 - * 2 2 6 2 6 - * 3 3 7 3 7 - * 4 4 0 4 0 - * 5 5 1 5 1 - * 6 6 2 6 2 - * 7 7 3 7 3 - */ - - if (slot < 8) { - if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C)) - bbits |= 1 << slot; - if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D)) - bbits |= 1 << (slot ^ 4); - } - return bbits; -} - - -/*ARGSUSED */ -pcibr_intr_t -pcibr_intr_alloc(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - pciio_intr_line_t lines, - devfs_handle_t owner_dev) -{ - pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = pcibr_info->f_slot; - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - bridge_t *bridge = pcibr_soft->bs_base; - int is_threaded = 0; - int thread_swlevel; - - xtalk_intr_t *xtalk_intr_p; - pcibr_intr_t *pcibr_intr_p; - pcibr_intr_list_t *intr_list_p; - - unsigned pcibr_int_bits; - unsigned pcibr_int_bit; - xtalk_intr_t xtalk_intr = (xtalk_intr_t)0; - hub_intr_t hub_intr; - pcibr_intr_t pcibr_intr; - pcibr_intr_list_t intr_entry; - pcibr_intr_list_t intr_list; - bridgereg_t int_dev; - -#if DEBUG && INTR_DEBUG - printk("%v: pcibr_intr_alloc\n" - "%v:%s%s%s%s%s\n", - owner_dev, pconn_vhdl, - !(lines & 15) ? " No INTs?" : "", - lines & 1 ? " INTA" : "", - lines & 2 ? " INTB" : "", - lines & 4 ? " INTC" : "", - lines & 8 ? " INTD" : ""); -#endif - - NEW(pcibr_intr); - if (!pcibr_intr) - return NULL; - - if (dev_desc) { - cpuid_t intr_target_from_desc(device_desc_t, int); - } else { - extern int default_intr_pri; - - is_threaded = 1; /* PCI interrupts are threaded, by default */ - thread_swlevel = default_intr_pri; - } - - pcibr_intr->bi_dev = pconn_vhdl; - pcibr_intr->bi_lines = lines; - pcibr_intr->bi_soft = pcibr_soft; - pcibr_intr->bi_ibits = 0; /* bits will be added below */ - pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD; - pcibr_intr->bi_mustruncpu = CPU_NONE; - mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock); - - pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines); - - - /* - * For each PCI interrupt line requested, figure - * out which Bridge PCI Interrupt Line it maps - * to, and make sure there are xtalk resources - * allocated for it. - */ -#if DEBUG && INTR_DEBUG - printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits); -#endif - for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) { - if (pcibr_int_bits & (1 << pcibr_int_bit)) { - xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr; - - xtalk_intr = *xtalk_intr_p; - - if (xtalk_intr == NULL) { - /* - * This xtalk_intr_alloc is constrained for two reasons: - * 1) Normal interrupts and error interrupts need to be delivered - * through a single xtalk target widget so that there aren't any - * ordering problems with DMA, completion interrupts, and error - * interrupts. (Use of xconn_vhdl forces this.) - * - * 2) On IP35, addressing constraints on IP35 and Bridge force - * us to use a single PI number for all interrupts from a - * single Bridge. (IP35-specific code forces this, and we - * verify in pcibr_setwidint.) - */ - - /* - * All code dealing with threaded PCI interrupt handlers - * is located at the pcibr level. Because of this, - * we always want the lower layers (hub/heart_intr_alloc, - * intr_level_connect) to treat us as non-threaded so we - * don't set up a duplicate threaded environment. We make - * this happen by calling a special xtalk interface. - */ - xtalk_intr = xtalk_intr_alloc_nothd(xconn_vhdl, dev_desc, - owner_dev); -#if DEBUG && INTR_DEBUG - printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr); -#endif - - /* both an assert and a runtime check on this: - * we need to check in non-DEBUG kernels, and - * the ASSERT gets us more information when - * we use DEBUG kernels. - */ - ASSERT(xtalk_intr != NULL); - if (xtalk_intr == NULL) { - /* it is quite possible that our - * xtalk_intr_alloc failed because - * someone else got there first, - * and we can find their results - * in xtalk_intr_p. - */ - if (!*xtalk_intr_p) { -#ifdef SUPPORT_PRINTING_V_FORMAT - printk(KERN_ALERT - "pcibr_intr_alloc %v: unable to get xtalk interrupt resources", - xconn_vhdl); -#else - printk(KERN_ALERT - "pcibr_intr_alloc 0x%p: unable to get xtalk interrupt resources", - (void *)xconn_vhdl); -#endif - /* yes, we leak resources here. */ - return 0; - } - } else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) { - /* - * now tell the bridge which slot is - * using this interrupt line. - */ - int_dev = bridge->b_int_device; - int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit); - int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit); - bridge->b_int_device = int_dev; /* XXXMP */ - -#if DEBUG && INTR_DEBUG - printk("%v: bridge intr bit %d clears my wrb\n", - pconn_vhdl, pcibr_int_bit); -#endif - } else { - /* someone else got one allocated first; - * free the one we just created, and - * retrieve the one they allocated. - */ - xtalk_intr_free(xtalk_intr); - xtalk_intr = *xtalk_intr_p; -#if PARANOID - /* once xtalk_intr is set, we never clear it, - * so if the CAS fails above, this condition - * can "never happen" ... - */ - if (!xtalk_intr) { - printk(KERN_ALERT - "pcibr_intr_alloc %v: unable to set xtalk interrupt resources", - xconn_vhdl); - /* yes, we leak resources here. */ - return 0; - } -#endif - } - } - - pcibr_intr->bi_ibits |= 1 << pcibr_int_bit; - - NEW(intr_entry); - intr_entry->il_next = NULL; - intr_entry->il_intr = pcibr_intr; - intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg); - intr_list_p = - &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list; -#if DEBUG && INTR_DEBUG -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk("0x%x: Bridge bit %d wrap=0x%x\n", - pconn_vhdl, pcibr_int_bit, - pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap); -#else - printk("%v: Bridge bit %d wrap=0x%x\n", - pconn_vhdl, pcibr_int_bit, - pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap); -#endif -#endif - - if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) { - /* we are the first interrupt on this bridge bit. - */ -#if DEBUG && INTR_DEBUG - printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n", - pconn_vhdl, pcibr_int_bits, pcibr_int_bit); -#endif - continue; - } - intr_list = *intr_list_p; - pcibr_intr_p = &intr_list->il_intr; - if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) { - /* first entry on list was erased, - * and we replaced it, so we - * don't need our intr_entry. - */ - DEL(intr_entry); -#if DEBUG && INTR_DEBUG - printk("%v INT 0x%x (bridge bit %d) replaces erased first\n", - pconn_vhdl, pcibr_int_bits, pcibr_int_bit); -#endif - continue; - } - intr_list_p = &intr_list->il_next; - if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) { - /* we are the new second interrupt on this bit. - */ - pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared = 1; -#if DEBUG && INTR_DEBUG - printk("%v INT 0x%x (bridge bit %d) is new SECOND\n", - pconn_vhdl, pcibr_int_bits, pcibr_int_bit); -#endif - continue; - } - while (1) { - pcibr_intr_p = &intr_list->il_intr; - if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) { - /* an entry on list was erased, - * and we replaced it, so we - * don't need our intr_entry. - */ - DEL(intr_entry); -#if DEBUG && INTR_DEBUG - printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n", - pconn_vhdl, pcibr_int_bits, pcibr_int_bit); -#endif - break; - } - intr_list_p = &intr_list->il_next; - if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) { - /* entry appended to share list - */ -#if DEBUG && INTR_DEBUG - printk("%v INT 0x%x (bridge bit %d) is new Nth\n", - pconn_vhdl, pcibr_int_bits, pcibr_int_bit); -#endif - break; - } - /* step to next record in chain - */ - intr_list = *intr_list_p; - } - } - } - -#if DEBUG && INTR_DEBUG - printk("%v pcibr_intr_alloc complete\n", pconn_vhdl); -#endif - hub_intr = (hub_intr_t)xtalk_intr; - pcibr_intr->bi_irq = hub_intr->i_bit; - pcibr_intr->bi_cpu = hub_intr->i_cpuid; - return pcibr_intr; -} - -/*ARGSUSED */ -void -pcibr_intr_free(pcibr_intr_t pcibr_intr) -{ - unsigned pcibr_int_bits = pcibr_intr->bi_ibits; - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - unsigned pcibr_int_bit; - pcibr_intr_list_t intr_list; - int intr_shared; - xtalk_intr_t *xtalk_intrp; - - for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) { - if (pcibr_int_bits & (1 << pcibr_int_bit)) { - for (intr_list = - pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list; - intr_list != NULL; - intr_list = intr_list->il_next) - if (compare_and_swap_ptr((void **) &intr_list->il_intr, - pcibr_intr, - NULL)) { -#if DEBUG && INTR_DEBUG - printk("%s: cleared a handler from bit %d\n", - pcibr_soft->bs_name, pcibr_int_bit); -#endif - } - /* If this interrupt line is not being shared between multiple - * devices release the xtalk interrupt resources. - */ - intr_shared = - pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared; - xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr; - - if ((!intr_shared) && (*xtalk_intrp)) { - - bridge_t *bridge = pcibr_soft->bs_base; - bridgereg_t int_dev; - - xtalk_intr_free(*xtalk_intrp); - *xtalk_intrp = 0; - - /* Clear the PCI device interrupt to bridge interrupt pin - * mapping. - */ - int_dev = bridge->b_int_device; - int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit); - bridge->b_int_device = int_dev; - - } - } - } - DEL(pcibr_intr); -} - -LOCAL void -pcibr_setpciint(xtalk_intr_t xtalk_intr) -{ - iopaddr_t addr = xtalk_intr_addr_get(xtalk_intr); - xtalk_intr_vector_t vect = xtalk_intr_vector_get(xtalk_intr); - bridgereg_t *int_addr = (bridgereg_t *) - xtalk_intr_sfarg_get(xtalk_intr); - - *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) | - (BRIDGE_INT_ADDR_FLD & vect)); -} - -/*ARGSUSED */ -int -pcibr_intr_connect(pcibr_intr_t pcibr_intr) -{ - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - bridge_t *bridge = pcibr_soft->bs_base; - unsigned pcibr_int_bits = pcibr_intr->bi_ibits; - unsigned pcibr_int_bit; - bridgereg_t b_int_enable; - unsigned long s; - - if (pcibr_intr == NULL) - return -1; - -#if DEBUG && INTR_DEBUG - printk("%v: pcibr_intr_connect\n", - pcibr_intr->bi_dev); -#endif - - *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED; - - /* - * For each PCI interrupt line requested, figure - * out which Bridge PCI Interrupt Line it maps - * to, and make sure there are xtalk resources - * allocated for it. - */ - for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) - if (pcibr_int_bits & (1 << pcibr_int_bit)) { - xtalk_intr_t xtalk_intr; - - xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr; - - /* - * If this interrupt line is being shared and the connect has - * already been done, no need to do it again. - */ - if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected) - continue; - - - /* - * Use the pcibr wrapper function to handle all Bridge interrupts - * regardless of whether the interrupt line is shared or not. - */ - xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t) pcibr_setpciint, - (void *)&(bridge->b_int_addr[pcibr_int_bit].addr)); - pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 1; - -#if DEBUG && INTR_DEBUG - printk("%v bridge bit %d wrapper connected\n", - pcibr_intr->bi_dev, pcibr_int_bit); -#endif - } - s = pcibr_lock(pcibr_soft); - b_int_enable = bridge->b_int_enable; - b_int_enable |= pcibr_int_bits; - bridge->b_int_enable = b_int_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - pcibr_unlock(pcibr_soft, s); - - return 0; -} - -/*ARGSUSED */ -void -pcibr_intr_disconnect(pcibr_intr_t pcibr_intr) -{ - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - bridge_t *bridge = pcibr_soft->bs_base; - unsigned pcibr_int_bits = pcibr_intr->bi_ibits; - unsigned pcibr_int_bit; - bridgereg_t b_int_enable; - unsigned long s; - - /* Stop calling the function. Now. - */ - *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED; - /* - * For each PCI interrupt line requested, figure - * out which Bridge PCI Interrupt Line it maps - * to, and disconnect the interrupt. - */ - - /* don't disable interrupts for lines that - * are shared between devices. - */ - for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) - if ((pcibr_int_bits & (1 << pcibr_int_bit)) && - (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)) - pcibr_int_bits &= ~(1 << pcibr_int_bit); - if (!pcibr_int_bits) - return; - - s = pcibr_lock(pcibr_soft); - b_int_enable = bridge->b_int_enable; - b_int_enable &= ~pcibr_int_bits; - bridge->b_int_enable = b_int_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - pcibr_unlock(pcibr_soft, s); - - for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) - if (pcibr_int_bits & (1 << pcibr_int_bit)) { - /* if the interrupt line is now shared, - * do not disconnect it. - */ - if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared) - continue; - - xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr); - pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 0; - -#if DEBUG && INTR_DEBUG - printk("%s: xtalk disconnect done for Bridge bit %d\n", - pcibr_soft->bs_name, pcibr_int_bit); -#endif - - /* if we are sharing the interrupt line, - * connect us up; this closes the hole - * where the another pcibr_intr_alloc() - * was in progress as we disconnected. - */ - if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared) - continue; - - xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr, - (xtalk_intr_setfunc_t)pcibr_setpciint, - (void *) &(bridge->b_int_addr[pcibr_int_bit].addr)); - } -} - -/*ARGSUSED */ -devfs_handle_t -pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr) -{ - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - unsigned pcibr_int_bits = pcibr_intr->bi_ibits; - unsigned pcibr_int_bit; - - for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) - if (pcibr_int_bits & (1 << pcibr_int_bit)) - return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr); - return 0; -} - -/* ===================================================================== - * INTERRUPT HANDLING - */ -LOCAL void -pcibr_clearwidint(bridge_t *bridge) -{ - bridge->b_wid_int_upper = 0; - bridge->b_wid_int_lower = 0; -} - -LOCAL void -pcibr_setwidint(xtalk_intr_t intr) -{ - xwidgetnum_t targ = xtalk_intr_target_get(intr); - iopaddr_t addr = xtalk_intr_addr_get(intr); - xtalk_intr_vector_t vect = xtalk_intr_vector_get(intr); - widgetreg_t NEW_b_wid_int_upper, NEW_b_wid_int_lower; - widgetreg_t OLD_b_wid_int_upper, OLD_b_wid_int_lower; - - bridge_t *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr); - - NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) | - XTALK_ADDR_TO_UPPER(addr)); - NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); - - OLD_b_wid_int_upper = bridge->b_wid_int_upper; - OLD_b_wid_int_lower = bridge->b_wid_int_lower; - - /* Verify that all interrupts from this Bridge are using a single PI */ - if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) { - /* - * Once set, these registers shouldn't change; they should - * be set multiple times with the same values. - * - * If we're attempting to change these registers, it means - * that our heuristics for allocating interrupts in a way - * appropriate for IP35 have failed, and the admin needs to - * explicitly direct some interrupts (or we need to make the - * heuristics more clever). - * - * In practice, we hope this doesn't happen very often, if - * at all. - */ - if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) || - (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) { - printk(KERN_WARNING "Interrupt allocation is too complex.\n"); - printk(KERN_WARNING "Use explicit administrative interrupt targetting.\n"); - printk(KERN_WARNING "bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ); - printk(KERN_WARNING "NEW=0x%x/0x%x OLD=0x%x/0x%x\n", - NEW_b_wid_int_upper, NEW_b_wid_int_lower, - OLD_b_wid_int_upper, OLD_b_wid_int_lower); - PRINT_PANIC("PCI Bridge interrupt targetting error\n"); - } - } - - bridge->b_wid_int_upper = NEW_b_wid_int_upper; - bridge->b_wid_int_lower = NEW_b_wid_int_lower; - bridge->b_int_host_err = vect; -} - -/* - * pcibr_intr_preset: called during mlreset time - * if the platform specific code needs to route - * one of the Bridge's xtalk interrupts before the - * xtalk infrastructure is available. - */ -void -pcibr_xintr_preset(void *which_widget, - int which_widget_intr, - xwidgetnum_t targ, - iopaddr_t addr, - xtalk_intr_vector_t vect) -{ - bridge_t *bridge = (bridge_t *) which_widget; - - if (which_widget_intr == -1) { - /* bridge widget error interrupt */ - bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) | - XTALK_ADDR_TO_UPPER(addr)); - bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); - bridge->b_int_host_err = vect; - - /* turn on all interrupts except - * the PCI interrupt requests, - * at least at heart. - */ - bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK; - - } else { - /* routing a PCI device interrupt. - * targ and low 38 bits of addr must - * be the same as the already set - * value for the widget error interrupt. - */ - bridge->b_int_addr[which_widget_intr].addr = - ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) | - (BRIDGE_INT_ADDR_FLD & vect)); - /* - * now bridge can let it through; - * NB: still should be blocked at - * xtalk provider end, until the service - * function is set. - */ - bridge->b_int_enable |= 1 << vect; - } - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ -} - - -/* - * pcibr_intr_func() - * - * This is the pcibr interrupt "wrapper" function that is called, - * in interrupt context, to initiate the interrupt handler(s) registered - * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded - * handlers will be called directly, and threaded handlers will have their - * thread woken up. - */ -void -pcibr_intr_func(intr_arg_t arg) -{ - pcibr_intr_wrap_t wrap = (pcibr_intr_wrap_t) arg; - reg_p wrbf; - pcibr_intr_t intr; - pcibr_intr_list_t list; - int clearit; - int do_nonthreaded = 1; - int is_threaded = 0; - int x = 0; - - /* - * If any handler is still running from a previous interrupt - * just return. If there's a need to call the handler(s) again, - * another interrupt will be generated either by the device or by - * pcibr_force_interrupt(). - */ - - if (wrap->iw_hdlrcnt) { - return; - } - - /* - * Call all interrupt handlers registered. - * First, the pcibr_intrd threads for any threaded handlers will be - * awoken, then any non-threaded handlers will be called sequentially. - */ - - clearit = 1; - while (do_nonthreaded) { - for (list = wrap->iw_list; list != NULL; list = list->il_next) { - if ((intr = list->il_intr) && - (intr->bi_flags & PCIIO_INTR_CONNECTED)) { - - /* - * This device may have initiated write - * requests since the bridge last saw - * an edge on this interrupt input; flushing - * the buffer prior to invoking the handler - * should help but may not be sufficient if we - * get more requests after the flush, followed - * by the card deciding it wants service, before - * the interrupt handler checks to see if things need - * to be done. - * - * There is a similar race condition if - * an interrupt handler loops around and - * notices further service is required. - * Perhaps we need to have an explicit - * call that interrupt handlers need to - * do between noticing that DMA to memory - * has completed, but before observing the - * contents of memory? - */ - - if ((do_nonthreaded) && (!is_threaded)) { - /* Non-threaded. - * Call the interrupt handler at interrupt level - */ - - /* Only need to flush write buffers if sharing */ - - if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) { - if ((x = *wrbf)) /* write request buffer flush */ -#ifdef SUPPORT_PRINTING_V_FORMAT - printk(KERN_ALERT "pcibr_intr_func %v: \n" - "write buffer flush failed, wrbf=0x%x\n", - list->il_intr->bi_dev, wrbf); -#else - printk(KERN_ALERT "pcibr_intr_func %p: \n" - "write buffer flush failed, wrbf=0x%lx\n", - (void *)list->il_intr->bi_dev, (long) wrbf); -#endif - } - } - - clearit = 0; - } - } - - do_nonthreaded = 0; - /* - * If the non-threaded handler was the last to complete, - * (i.e., no threaded handlers still running) force an - * interrupt to avoid a potential deadlock situation. - */ - if (wrap->iw_hdlrcnt == 0) { - pcibr_force_interrupt(wrap); - } - } - - /* If there were no handlers, - * disable the interrupt and return. - * It will get enabled again after - * a handler is connected. - * If we don't do this, we would - * sit here and spin through the - * list forever. - */ - if (clearit) { - pcibr_soft_t pcibr_soft = wrap->iw_soft; - bridge_t *bridge = pcibr_soft->bs_base; - bridgereg_t b_int_enable; - bridgereg_t mask = 1 << wrap->iw_intr; - unsigned long s; - - s = pcibr_lock(pcibr_soft); - b_int_enable = bridge->b_int_enable; - b_int_enable &= ~mask; - bridge->b_int_enable = b_int_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - pcibr_unlock(pcibr_soft, s); - return; - } -} - -/* ===================================================================== - * CONFIGURATION MANAGEMENT - */ -/*ARGSUSED */ -void -pcibr_provider_startup(devfs_handle_t pcibr) -{ -} - -/*ARGSUSED */ -void -pcibr_provider_shutdown(devfs_handle_t pcibr) -{ -} - -int -pcibr_reset(devfs_handle_t conn) -{ - pciio_info_t pciio_info = pciio_info_get(conn); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - bridgereg_t ctlreg; - unsigned cfgctl[8]; - unsigned long s; - int f, nf; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - int win; - - if (pcibr_soft->bs_slot[pciio_slot].has_host) { - pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot; - pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0]; - } - if (pciio_slot < 4) { - s = pcibr_lock(pcibr_soft); - nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo; - pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos; - for (f = 0; f < nf; ++f) - if (pcibr_infoh[f]) - cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4]; - - ctlreg = bridge->b_wid_control; - bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot); - /* XXX delay? */ - bridge->b_wid_control = ctlreg; - /* XXX delay? */ - - for (f = 0; f < nf; ++f) - if ((pcibr_info = pcibr_infoh[f])) - for (win = 0; win < 6; ++win) - if (pcibr_info->f_window[win].w_base != 0) - bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] = - pcibr_info->f_window[win].w_base; - for (f = 0; f < nf; ++f) - if (pcibr_infoh[f]) - bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f]; - pcibr_unlock(pcibr_soft, s); - - return 0; - } -#ifdef SUPPORT_PRINTING_V_FORMAT - printk(KERN_WARNING "%v: pcibr_reset unimplemented for slot %d\n", - conn, pciio_slot); -#endif - return -1; -} - -pciio_endian_t -pcibr_endian_set(devfs_handle_t pconn_vhdl, - pciio_endian_t device_end, - pciio_endian_t desired_end) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridgereg_t devreg; - unsigned long s; - - /* - * Bridge supports hardware swapping; so we can always - * arrange for the caller's desired endianness. - */ - - s = pcibr_lock(pcibr_soft); - devreg = pcibr_soft->bs_slot[pciio_slot].bss_device; - if (device_end != desired_end) - devreg |= BRIDGE_DEV_SWAP_BITS; - else - devreg &= ~BRIDGE_DEV_SWAP_BITS; - - /* NOTE- if we ever put SWAP bits - * onto the disabled list, we will - * have to change the logic here. - */ - if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) { - bridge_t *bridge = pcibr_soft->bs_base; - - bridge->b_device[pciio_slot].reg = devreg; - pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - pcibr_unlock(pcibr_soft, s); - -#if DEBUG && PCIBR_DEV_DEBUG - printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg); -#endif - - return desired_end; -} - -/* This (re)sets the GBR and REALTIME bits and also keeps track of how - * many sets are outstanding. Reset succeeds only if the number of outstanding - * sets == 1. - */ -int -pcibr_priority_bits_set(pcibr_soft_t pcibr_soft, - pciio_slot_t pciio_slot, - pciio_priority_t device_prio) -{ - unsigned long s; - int *counter; - bridgereg_t rtbits = 0; - bridgereg_t devreg; - int rc = PRIO_SUCCESS; - - /* in dual-slot configurations, the host and the - * guest have separate DMA resources, so they - * have separate requirements for priority bits. - */ - - counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr); - - /* - * Bridge supports PCI notions of LOW and HIGH priority - * arbitration rings via a "REAL_TIME" bit in the per-device - * Bridge register. The "GBR" bit controls access to the GBR - * ring on the xbow. These two bits are (re)set together. - * - * XXX- Bug in Rev B Bridge Si: - * Symptom: Prefetcher starts operating incorrectly. This happens - * due to corruption of the address storage ram in the prefetcher - * when a non-real time PCI request is pulled and a real-time one is - * put in it's place. Workaround: Use only a single arbitration ring - * on PCI bus. GBR and RR can still be uniquely used per - * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C. - */ - - if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B) - rtbits |= BRIDGE_DEV_RT; - - /* NOTE- if we ever put DEV_RT or DEV_GBR on - * the disabled list, we will have to take - * it into account here. - */ - - s = pcibr_lock(pcibr_soft); - devreg = pcibr_soft->bs_slot[pciio_slot].bss_device; - if (device_prio == PCI_PRIO_HIGH) { - if ((++*counter == 1)) { - if (rtbits) - devreg |= rtbits; - else - rc = PRIO_FAIL; - } - } else if (device_prio == PCI_PRIO_LOW) { - if (*counter <= 0) - rc = PRIO_FAIL; - else if (--*counter == 0) - if (rtbits) - devreg &= ~rtbits; - } - if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) { - bridge_t *bridge = pcibr_soft->bs_base; - - bridge->b_device[pciio_slot].reg = devreg; - pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - pcibr_unlock(pcibr_soft, s); - - return rc; -} - -pciio_priority_t -pcibr_priority_set(devfs_handle_t pconn_vhdl, - pciio_priority_t device_prio) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio); - - return device_prio; -} - -/* - * Interfaces to allow special (e.g. SGI) drivers to set/clear - * Bridge-specific device flags. Many flags are modified through - * PCI-generic interfaces; we don't allow them to be directly - * manipulated here. Only flags that at this point seem pretty - * Bridge-specific can be set through these special interfaces. - * We may add more flags as the need arises, or remove flags and - * create PCI-generic interfaces as the need arises. - * - * Returns 0 on failure, 1 on success - */ -int -pcibr_device_flags_set(devfs_handle_t pconn_vhdl, - pcibr_device_flags_t flags) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridgereg_t set = 0; - bridgereg_t clr = 0; - - ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags); - - if (flags & PCIBR_WRITE_GATHER) - set |= BRIDGE_DEV_PMU_WRGA_EN; - if (flags & PCIBR_NOWRITE_GATHER) - clr |= BRIDGE_DEV_PMU_WRGA_EN; - - if (flags & PCIBR_WRITE_GATHER) - set |= BRIDGE_DEV_DIR_WRGA_EN; - if (flags & PCIBR_NOWRITE_GATHER) - clr |= BRIDGE_DEV_DIR_WRGA_EN; - - if (flags & PCIBR_PREFETCH) - set |= BRIDGE_DEV_PREF; - if (flags & PCIBR_NOPREFETCH) - clr |= BRIDGE_DEV_PREF; - - if (flags & PCIBR_PRECISE) - set |= BRIDGE_DEV_PRECISE; - if (flags & PCIBR_NOPRECISE) - clr |= BRIDGE_DEV_PRECISE; - - if (flags & PCIBR_BARRIER) - set |= BRIDGE_DEV_BARRIER; - if (flags & PCIBR_NOBARRIER) - clr |= BRIDGE_DEV_BARRIER; - - if (flags & PCIBR_64BIT) - set |= BRIDGE_DEV_DEV_SIZE; - if (flags & PCIBR_NO64BIT) - clr |= BRIDGE_DEV_DEV_SIZE; - - if (set || clr) { - bridgereg_t devreg; - unsigned long s; - - s = pcibr_lock(pcibr_soft); - devreg = pcibr_soft->bs_slot[pciio_slot].bss_device; - devreg = (devreg & ~clr) | set; - if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) { - bridge_t *bridge = pcibr_soft->bs_base; - - bridge->b_device[pciio_slot].reg = devreg; - pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - pcibr_unlock(pcibr_soft, s); -#if DEBUG && PCIBR_DEV_DEBUG - printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits); -#endif - } - return (1); -} - -#ifdef LITTLE_ENDIAN -/* - * on sn-ia we need to twiddle the addresses going out - * the pci bus because we use the unswizzled synergy space - * (the alternative is to use the swizzled synergy space - * and byte swap the data) - */ -#define CB(b,r) (((volatile uint8_t *) b)[((r)^4)]) -#define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)]) -#define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)]) -#else -#define CB(b,r) (((volatile uint8_t *) cfgbase)[(r)^3]) -#define CS(b,r) (((volatile uint16_t *) cfgbase)[((r)/2)^1]) -#define CW(b,r) (((volatile uint32_t *) cfgbase)[(r)/4]) -#endif /* LITTLE_ENDIAN */ - - -LOCAL cfg_p -pcibr_config_addr(devfs_handle_t conn, - unsigned reg) -{ - pcibr_info_t pcibr_info; - pciio_slot_t pciio_slot; - pciio_function_t pciio_func; - pcibr_soft_t pcibr_soft; - bridge_t *bridge; - cfg_p cfgbase = (cfg_p)0; - - pcibr_info = pcibr_info_get(conn); - - pciio_slot = pcibr_info->f_slot; - if (pciio_slot == PCIIO_SLOT_NONE) - pciio_slot = PCI_TYPE1_SLOT(reg); - - pciio_func = pcibr_info->f_func; - if (pciio_func == PCIIO_FUNC_NONE) - pciio_func = PCI_TYPE1_FUNC(reg); - - pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; - - bridge = pcibr_soft->bs_base; - - cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l; - - return cfgbase; -} - -uint64_t -pcibr_config_get(devfs_handle_t conn, - unsigned reg, - unsigned size) -{ - return do_pcibr_config_get(pcibr_config_addr(conn, reg), - PCI_TYPE1_REG(reg), size); -} - -LOCAL uint64_t -do_pcibr_config_get( - cfg_p cfgbase, - unsigned reg, - unsigned size) -{ - unsigned value; - - - value = CW(cfgbase, reg); - - if (reg & 3) - value >>= 8 * (reg & 3); - if (size < 4) - value &= (1 << (8 * size)) - 1; - - return value; -} - -void -pcibr_config_set(devfs_handle_t conn, - unsigned reg, - unsigned size, - uint64_t value) -{ - do_pcibr_config_set(pcibr_config_addr(conn, reg), - PCI_TYPE1_REG(reg), size, value); -} - -LOCAL void -do_pcibr_config_set(cfg_p cfgbase, - unsigned reg, - unsigned size, - uint64_t value) -{ - switch (size) { - case 1: - CB(cfgbase, reg) = value; - break; - case 2: - if (reg & 1) { - CB(cfgbase, reg) = value; - CB(cfgbase, reg + 1) = value >> 8; - } else - CS(cfgbase, reg) = value; - break; - case 3: - if (reg & 1) { - CB(cfgbase, reg) = value; - CS(cfgbase, (reg + 1)) = value >> 8; - } else { - CS(cfgbase, reg) = value; - CB(cfgbase, reg + 2) = value >> 16; - } - break; - - case 4: - CW(cfgbase, reg) = value; - break; - } -} - -pciio_provider_t pcibr_provider = -{ - (pciio_piomap_alloc_f *) pcibr_piomap_alloc, - (pciio_piomap_free_f *) pcibr_piomap_free, - (pciio_piomap_addr_f *) pcibr_piomap_addr, - (pciio_piomap_done_f *) pcibr_piomap_done, - (pciio_piotrans_addr_f *) pcibr_piotrans_addr, - (pciio_piospace_alloc_f *) pcibr_piospace_alloc, - (pciio_piospace_free_f *) pcibr_piospace_free, - - (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc, - (pciio_dmamap_free_f *) pcibr_dmamap_free, - (pciio_dmamap_addr_f *) pcibr_dmamap_addr, - (pciio_dmamap_list_f *) pcibr_dmamap_list, - (pciio_dmamap_done_f *) pcibr_dmamap_done, - (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr, - (pciio_dmatrans_list_f *) pcibr_dmatrans_list, - (pciio_dmamap_drain_f *) pcibr_dmamap_drain, - (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain, - (pciio_dmalist_drain_f *) pcibr_dmalist_drain, - - (pciio_intr_alloc_f *) pcibr_intr_alloc, - (pciio_intr_free_f *) pcibr_intr_free, - (pciio_intr_connect_f *) pcibr_intr_connect, - (pciio_intr_disconnect_f *) pcibr_intr_disconnect, - (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get, - - (pciio_provider_startup_f *) pcibr_provider_startup, - (pciio_provider_shutdown_f *) pcibr_provider_shutdown, - (pciio_reset_f *) pcibr_reset, - (pciio_write_gather_flush_f *) pcibr_write_gather_flush, - (pciio_endian_set_f *) pcibr_endian_set, - (pciio_priority_set_f *) pcibr_priority_set, - (pciio_config_get_f *) pcibr_config_get, - (pciio_config_set_f *) pcibr_config_set, - - (pciio_error_devenable_f *) 0, - (pciio_error_extract_f *) 0, - -#ifdef LATER - (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback, - (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback, -#else - (pciio_driver_reg_callback_f *) 0, - (pciio_driver_unreg_callback_f *) 0, -#endif - (pciio_device_unregister_f *) pcibr_device_unregister, - (pciio_dma_enabled_f *) pcibr_dma_enabled, -}; - -LOCAL pcibr_hints_t -pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc) -{ - arbitrary_info_t ainfo = 0; - graph_error_t rv; - pcibr_hints_t hint; - - rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo); - - if (alloc && (rv != GRAPH_SUCCESS)) { - - NEW(hint); - hint->rrb_alloc_funct = NULL; - hint->ph_intr_bits = NULL; - rv = hwgraph_info_add_LBL(xconn_vhdl, - INFO_LBL_PCIBR_HINTS, - (arbitrary_info_t) hint); - if (rv != GRAPH_SUCCESS) - goto abnormal_exit; - - rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo); - - if (rv != GRAPH_SUCCESS) - goto abnormal_exit; - - if (ainfo != (arbitrary_info_t) hint) - goto abnormal_exit; - } - return (pcibr_hints_t) ainfo; - -abnormal_exit: -#ifdef LATER - printf("SHOULD NOT BE HERE\n"); -#endif - DEL(hint); - return(NULL); - -} - -void -pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask) -{ - pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); - - if (hint) - hint->ph_rrb_fixed = mask; -#if DEBUG - else - printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n" - "\t%p\n", xconn_vhdl); -#endif -} - -void -pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl) -{ - pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF); -} - -void -pcibr_hints_dualslot(devfs_handle_t xconn_vhdl, - pciio_slot_t host, - pciio_slot_t guest) -{ - pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); - - if (hint) - hint->ph_host_slot[guest] = host + 1; -#if DEBUG - else - printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n" - "\t%p\n", xconn_vhdl); -#endif -} - -void -pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl, - pcibr_intr_bits_f *xxx_intr_bits) -{ - pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); - - if (hint) - hint->ph_intr_bits = xxx_intr_bits; -#if DEBUG - else - printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n" - "\t%p\n", xconn_vhdl); -#endif -} - -void -pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct) -{ - pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); - - if (hint) - hint->rrb_alloc_funct = rrb_alloc_funct; -} - -void -pcibr_hints_handsoff(devfs_handle_t xconn_vhdl) -{ - pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); - - if (hint) - hint->ph_hands_off = 1; -#if DEBUG - else - printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n" - "\t%p\n", xconn_vhdl); -#endif -} - -void -pcibr_hints_subdevs(devfs_handle_t xconn_vhdl, - pciio_slot_t slot, - uint64_t subdevs) -{ - arbitrary_info_t ainfo = 0; - char sdname[16]; - devfs_handle_t pconn_vhdl = GRAPH_VERTEX_NONE; - - sprintf(sdname, "pci/%d", slot); - (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl); - if (pconn_vhdl == GRAPH_VERTEX_NONE) { -#if DEBUG - printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n" - "\t%p (seeking %s)\n", xconn_vhdl, sdname); -#endif - return; - } - hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo); - if (ainfo == 0) { - uint64_t *subdevp; - - NEW(subdevp); - if (!subdevp) { -#if DEBUG - printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n" - "\t%p\n", pconn_vhdl); -#endif - return; - } - *subdevp = subdevs; - hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp); - hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo); - if (ainfo == (arbitrary_info_t) subdevp) - return; - DEL(subdevp); - if (ainfo == (arbitrary_info_t) NULL) { -#if DEBUG - printk("pcibr_hints_subdevs: null subdevs ptr at\n" - "\t%p\n", pconn_vhdl); -#endif - return; - } -#if DEBUG - printk("pcibr_subdevs_get: dup subdev add_LBL at\n" - "\t%p\n", pconn_vhdl); -#endif - } - *(uint64_t *) ainfo = subdevs; -} - - -#ifdef LATER - -#include -#include - -char *pci_space[] = {"NONE", - "ROM", - "IO", - "", - "MEM", - "MEM32", - "MEM64", - "CFG", - "WIN0", - "WIN1", - "WIN2", - "WIN3", - "WIN4", - "WIN5", - "", - "BAD"}; - -void -idbg_pss_func(pcibr_info_h pcibr_infoh, int func) -{ - pcibr_info_t pcibr_info = pcibr_infoh[func]; - char name[MAXDEVNAME]; - int win; - - if (!pcibr_info) - return; - qprintf("Per-slot Function Info\n"); -#ifdef SUPPORT_PRINTING_V_FORMAT - sprintf(name, "%v", pcibr_info->f_vertex); -#endif - qprintf("\tSlot Name : %s\n",name); - qprintf("\tPCI Bus : %d ",pcibr_info->f_bus); - qprintf("Slot : %d ", pcibr_info->f_slot); - qprintf("Function : %d ", pcibr_info->f_func); - qprintf("VendorId : 0x%x " , pcibr_info->f_vendor); - qprintf("DeviceId : 0x%x\n", pcibr_info->f_device); -#ifdef SUPPORT_PRINTING_V_FORMAT - sprintf(name, "%v", pcibr_info->f_master); -#endif - qprintf("\tBus provider : %s\n",name); - qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops); - qprintf("Error Handler : 0x%x Arg 0x%x\n", - pcibr_info->f_efunc,pcibr_info->f_einfo); - for(win = 0 ; win < 6 ; win++) - qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n", - win,pci_space[pcibr_info->f_window[win].w_space], - pcibr_info->f_window[win].w_base, - pcibr_info->f_window[win].w_size); - - qprintf("\tRom base 0x%x size 0x%x\n", - pcibr_info->f_rbase,pcibr_info->f_rsize); - - qprintf("\tInterrupt Bit Map\n"); - qprintf("\t\tPCI Int#\tBridge Pin#\n"); - for (win = 0 ; win < 4; win++) - qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]); - qprintf("\n"); -} - - -void -idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot) -{ - pcibr_soft_slot_t pss; - char slot_conn_name[MAXDEVNAME]; - int func; - - pss = &pcibr_soft->bs_slot[slot]; - qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot); - qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no"); - qprintf("\tHost Slot : %d\n",pss->host_slot); - sprintf(slot_conn_name, "%v", pss->slot_conn); - qprintf("\tSlot Conn : %s\n",slot_conn_name); - qprintf("\t#Functions : %d\n",pss->bss_ninfo); - for (func = 0; func < pss->bss_ninfo; func++) - idbg_pss_func(pss->bss_infos,func); - qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]); - qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base); - qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device); - qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n", - pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr); - - qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x" - "d32_base 0x%x d32_flags 0x%x\n", - pss->bss_d64_base, pss->bss_d64_flags, - pss->bss_d32_base, pss->bss_d32_flags); - - qprintf("\tExt ATEs active ? %s", - atomic_read(&pss->bss_ext_ates_active) ? "yes" : "no"); - qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer); - qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow); - - qprintf("\tRRB Info : Valid %d+%d Reserved %d\n", - pcibr_soft->bs_rrb_valid[slot], - pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], - pcibr_soft->bs_rrb_res[slot]); - -} - -int ips = 0; - -void -idbg_pss(pcibr_soft_t pcibr_soft) -{ - pciio_slot_t slot; - - - if (ips >= 0 && ips < 8) - idbg_pss_info(pcibr_soft,ips); - else if (ips < 0) - for (slot = 0; slot < 8; slot++) - idbg_pss_info(pcibr_soft,slot); - else - qprintf("Invalid ips %d\n",ips); -} - -#endif /* LATER */ - -int -pcibr_dma_enabled(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - - return xtalk_dma_enabled(pcibr_soft->bs_conn); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/pciio.c linux-2.4.22/arch/ia64/sn/io/sn1/pciio.c --- linux-2.4.21/arch/ia64/sn/io/sn1/pciio.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/pciio.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1681 +0,0 @@ -/* $Id: pciio.c,v 1.2 2002/11/16 02:23:19 steiner Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#define USRPCI 0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include /* Must be before iograph.h to get MAX_PORT_NUM */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - -#define DEBUG_PCIIO -#undef DEBUG_PCIIO /* turn this on for yet more console output */ - - -#define GET_NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DO_DEL(ptr) (kfree(ptr)) - -char pciio_info_fingerprint[] = "pciio_info"; - -cdl_p pciio_registry = NULL; - -int -badaddr_val(volatile void *addr, int len, volatile void *ptr) -{ - int ret = 0; - volatile void *new_addr; - - switch (len) { - case 4: - new_addr = (void *)(((u64) addr)^4); - ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr); - break; - default: - printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len); - } - - if (ret < 0) - panic("badaddr_val: unexpected status (%d) in probing", ret); - return(ret); - -} - - -nasid_t -get_console_nasid(void) -{ - extern nasid_t console_nasid; - if (console_nasid < 0) { - console_nasid = ia64_sn_get_console_nasid(); - if (console_nasid < 0) { -// ZZZ What do we do if we don't get a console nasid on the hardware???? - if (IS_RUNNING_ON_SIMULATOR() ) - console_nasid = master_nasid; - } - } - return console_nasid; -} - -int -hub_dma_enabled(devfs_handle_t xconn_vhdl) -{ - return(0); -} - -int -hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) -{ - return(0); -} - -void -ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror) -{ -} - -/****** - ****** end hack defines ...... - ******/ - - - - -/* ===================================================================== - * PCI Generic Bus Provider - * Implement PCI provider operations. The pciio* layer provides a - * platform-independent interface for PCI devices. This layer - * switches among the possible implementations of a PCI adapter. - */ - -/* ===================================================================== - * Provider Function Location SHORTCUT - * - * On platforms with only one possible PCI provider, macros can be - * set up at the top that cause the table lookups and indirections to - * completely disappear. - */ - -/* - * For the moment, we will assume that IP27 - * only use Bridge ASICs to provide PCI support. - */ -#include -#define DEV_FUNC(dev,func) pcibr_##func -#define CAST_PIOMAP(x) ((pcibr_piomap_t)(x)) -#define CAST_DMAMAP(x) ((pcibr_dmamap_t)(x)) -#define CAST_INTR(x) ((pcibr_intr_t)(x)) - -/* ===================================================================== - * Function Table of Contents - */ - -#if !defined(DEV_FUNC) -static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev); -#endif - -pciio_piomap_t pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); -void pciio_piomap_free(pciio_piomap_t); -caddr_t pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t); - -void pciio_piomap_done(pciio_piomap_t); -caddr_t pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); -caddr_t pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned); - -iopaddr_t pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); -void pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); - -pciio_dmamap_t pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); -void pciio_dmamap_free(pciio_dmamap_t); -iopaddr_t pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t); -alenlist_t pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned); -void pciio_dmamap_done(pciio_dmamap_t); -iopaddr_t pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); -void pciio_dmamap_drain(pciio_dmamap_t); -void pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); -void pciio_dmalist_drain(devfs_handle_t, alenlist_t); -iopaddr_t pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned); - -pciio_intr_t pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); -void pciio_intr_free(pciio_intr_t); -int pciio_intr_connect(pciio_intr_t); -void pciio_intr_disconnect(pciio_intr_t); -devfs_handle_t pciio_intr_cpu_get(pciio_intr_t); - -void pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t); - -void pciio_provider_startup(devfs_handle_t); -void pciio_provider_shutdown(devfs_handle_t); - -pciio_endian_t pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); -pciio_priority_t pciio_priority_set(devfs_handle_t, pciio_priority_t); -devfs_handle_t pciio_intr_dev_get(pciio_intr_t); - -devfs_handle_t pciio_pio_dev_get(pciio_piomap_t); -pciio_slot_t pciio_pio_slot_get(pciio_piomap_t); -pciio_space_t pciio_pio_space_get(pciio_piomap_t); -iopaddr_t pciio_pio_pciaddr_get(pciio_piomap_t); -ulong pciio_pio_mapsz_get(pciio_piomap_t); -caddr_t pciio_pio_kvaddr_get(pciio_piomap_t); - -devfs_handle_t pciio_dma_dev_get(pciio_dmamap_t); -pciio_slot_t pciio_dma_slot_get(pciio_dmamap_t); - -pciio_info_t pciio_info_chk(devfs_handle_t); -pciio_info_t pciio_info_get(devfs_handle_t); -void pciio_info_set(devfs_handle_t, pciio_info_t); -devfs_handle_t pciio_info_dev_get(pciio_info_t); -pciio_slot_t pciio_info_slot_get(pciio_info_t); -pciio_function_t pciio_info_function_get(pciio_info_t); -pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t); -pciio_device_id_t pciio_info_device_id_get(pciio_info_t); -devfs_handle_t pciio_info_master_get(pciio_info_t); -arbitrary_info_t pciio_info_mfast_get(pciio_info_t); -pciio_provider_t *pciio_info_pops_get(pciio_info_t); -error_handler_f *pciio_info_efunc_get(pciio_info_t); -error_handler_arg_t *pciio_info_einfo_get(pciio_info_t); -pciio_space_t pciio_info_bar_space_get(pciio_info_t, int); -iopaddr_t pciio_info_bar_base_get(pciio_info_t, int); -size_t pciio_info_bar_size_get(pciio_info_t, int); -iopaddr_t pciio_info_rom_base_get(pciio_info_t); -size_t pciio_info_rom_size_get(pciio_info_t); - -void pciio_init(void); -int pciio_attach(devfs_handle_t); - -void pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns); -void pciio_provider_unregister(devfs_handle_t); -pciio_provider_t *pciio_provider_fns_get(devfs_handle_t); - -int pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned); -void pciio_driver_unregister(char *driver_prefix); - -devfs_handle_t pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); - -void pciio_device_unregister(devfs_handle_t); -pciio_info_t pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); -void pciio_device_info_free(pciio_info_t); -devfs_handle_t pciio_device_info_register(devfs_handle_t, pciio_info_t); -void pciio_device_info_unregister(devfs_handle_t, pciio_info_t); -int pciio_device_attach(devfs_handle_t, int); -int pciio_device_detach(devfs_handle_t, int); -void pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t); - -int pciio_reset(devfs_handle_t); -int pciio_write_gather_flush(devfs_handle_t); -int pciio_slot_inuse(devfs_handle_t); - -/* ===================================================================== - * Provider Function Location - * - * If there is more than one possible provider for - * this platform, we need to examine the master - * vertex of the current vertex for a provider - * function structure, and indirect through the - * appropriately named member. - */ - -#if !defined(DEV_FUNC) - -static pciio_provider_t * -pciio_to_provider_fns(devfs_handle_t dev) -{ - pciio_info_t card_info; - pciio_provider_t *provider_fns; - - /* - * We're called with two types of vertices, one is - * the bridge vertex (ends with "pci") and the other is the - * pci slot vertex (ends with "pci/[0-8]"). For the first type - * we need to get the provider from the PFUNCS label. For - * the second we get it from fastinfo/c_pops. - */ - provider_fns = pciio_provider_fns_get(dev); - if (provider_fns == NULL) { - card_info = pciio_info_get(dev); - if (card_info != NULL) { - provider_fns = pciio_info_pops_get(card_info); - } - } - - if (provider_fns == NULL) -#if defined(SUPPORT_PRINTING_V_FORMAT) - PRINT_PANIC("%v: provider_fns == NULL", dev); -#else - PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev); -#endif - - return provider_fns; - -} - -#define DEV_FUNC(dev,func) pciio_to_provider_fns(dev)->func -#define CAST_PIOMAP(x) ((pciio_piomap_t)(x)) -#define CAST_DMAMAP(x) ((pciio_dmamap_t)(x)) -#define CAST_INTR(x) ((pciio_intr_t)(x)) -#endif - -/* - * Many functions are not passed their vertex - * information directly; rather, they must - * dive through a resource map. These macros - * are available to coordinate this detail. - */ -#define PIOMAP_FUNC(map,func) DEV_FUNC((map)->pp_dev,func) -#define DMAMAP_FUNC(map,func) DEV_FUNC((map)->pd_dev,func) -#define INTR_FUNC(intr_hdl,func) DEV_FUNC((intr_hdl)->pi_dev,func) - -/* ===================================================================== - * PIO MANAGEMENT - * - * For mapping system virtual address space to - * pciio space on a specified card - */ - -pciio_piomap_t -pciio_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ - iopaddr_t addr, /* lowest address (or offset in window) */ - size_t byte_count, /* size of region containing our mappings */ - size_t byte_count_max, /* maximum size of a mapping */ - unsigned flags) -{ /* defined in sys/pio.h */ - return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc) - (dev, dev_desc, space, addr, byte_count, byte_count_max, flags); -} - -void -pciio_piomap_free(pciio_piomap_t pciio_piomap) -{ - PIOMAP_FUNC(pciio_piomap, piomap_free) - (CAST_PIOMAP(pciio_piomap)); -} - -caddr_t -pciio_piomap_addr(pciio_piomap_t pciio_piomap, /* mapping resources */ - iopaddr_t pciio_addr, /* map for this pciio address */ - size_t byte_count) -{ /* map this many bytes */ - pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr) - (CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count); - - return pciio_piomap->pp_kvaddr; -} - -void -pciio_piomap_done(pciio_piomap_t pciio_piomap) -{ - PIOMAP_FUNC(pciio_piomap, piomap_done) - (CAST_PIOMAP(pciio_piomap)); -} - -caddr_t -pciio_piotrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ - iopaddr_t addr, /* starting address (or offset in window) */ - size_t byte_count, /* map this many bytes */ - unsigned flags) -{ /* (currently unused) */ - return DEV_FUNC(dev, piotrans_addr) - (dev, dev_desc, space, addr, byte_count, flags); -} - -caddr_t -pciio_pio_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ - iopaddr_t addr, /* starting address (or offset in window) */ - size_t byte_count, /* map this many bytes */ - pciio_piomap_t *mapp, /* where to return the map pointer */ - unsigned flags) -{ /* PIO flags */ - pciio_piomap_t map = 0; - int errfree = 0; - caddr_t res; - - if (mapp) { - map = *mapp; /* possible pre-allocated map */ - *mapp = 0; /* record "no map used" */ - } - - res = pciio_piotrans_addr - (dev, dev_desc, space, addr, byte_count, flags); - if (res) - return res; /* pciio_piotrans worked */ - - if (!map) { - map = pciio_piomap_alloc - (dev, dev_desc, space, addr, byte_count, byte_count, flags); - if (!map) - return res; /* pciio_piomap_alloc failed */ - errfree = 1; - } - - res = pciio_piomap_addr - (map, addr, byte_count); - if (!res) { - if (errfree) - pciio_piomap_free(map); - return res; /* pciio_piomap_addr failed */ - } - if (mapp) - *mapp = map; /* pass back map used */ - - return res; /* pciio_piomap_addr succeeded */ -} - -iopaddr_t -pciio_piospace_alloc(devfs_handle_t dev, /* Device requiring space */ - device_desc_t dev_desc, /* Device descriptor */ - pciio_space_t space, /* MEM32/MEM64/IO */ - size_t byte_count, /* Size of mapping */ - size_t align) -{ /* Alignment needed */ - if (align < NBPP) - align = NBPP; - return DEV_FUNC(dev, piospace_alloc) - (dev, dev_desc, space, byte_count, align); -} - -void -pciio_piospace_free(devfs_handle_t dev, /* Device freeing space */ - pciio_space_t space, /* Type of space */ - iopaddr_t pciaddr, /* starting address */ - size_t byte_count) -{ /* Range of address */ - DEV_FUNC(dev, piospace_free) - (dev, space, pciaddr, byte_count); -} - -/* ===================================================================== - * DMA MANAGEMENT - * - * For mapping from pci space to system - * physical space. - */ - -pciio_dmamap_t -pciio_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ - device_desc_t dev_desc, /* device descriptor */ - size_t byte_count_max, /* max size of a mapping */ - unsigned flags) -{ /* defined in dma.h */ - return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc) - (dev, dev_desc, byte_count_max, flags); -} - -void -pciio_dmamap_free(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_free) - (CAST_DMAMAP(pciio_dmamap)); -} - -iopaddr_t -pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - paddr_t paddr, /* map for this address */ - size_t byte_count) -{ /* map this many bytes */ - return DMAMAP_FUNC(pciio_dmamap, dmamap_addr) - (CAST_DMAMAP(pciio_dmamap), paddr, byte_count); -} - -alenlist_t -pciio_dmamap_list(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - alenlist_t alenlist, /* map this Address/Length List */ - unsigned flags) -{ - return DMAMAP_FUNC(pciio_dmamap, dmamap_list) - (CAST_DMAMAP(pciio_dmamap), alenlist, flags); -} - -void -pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_done) - (CAST_DMAMAP(pciio_dmamap)); -} - -iopaddr_t -pciio_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_addr) - (dev, dev_desc, paddr, byte_count, flags); -} - -alenlist_t -pciio_dmatrans_list(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - alenlist_t palenlist, /* system address/length list */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_list) - (dev, dev_desc, palenlist, flags); -} - -iopaddr_t -pciio_dma_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - pciio_dmamap_t *mapp, /* map to use, then map we used */ - unsigned flags) -{ /* PIO flags */ - pciio_dmamap_t map = 0; - int errfree = 0; - iopaddr_t res; - - if (mapp) { - map = *mapp; /* possible pre-allocated map */ - *mapp = 0; /* record "no map used" */ - } - - res = pciio_dmatrans_addr - (dev, dev_desc, paddr, byte_count, flags); - if (res) - return res; /* pciio_dmatrans worked */ - - if (!map) { - map = pciio_dmamap_alloc - (dev, dev_desc, byte_count, flags); - if (!map) - return res; /* pciio_dmamap_alloc failed */ - errfree = 1; - } - - res = pciio_dmamap_addr - (map, paddr, byte_count); - if (!res) { - if (errfree) - pciio_dmamap_free(map); - return res; /* pciio_dmamap_addr failed */ - } - if (mapp) - *mapp = map; /* pass back map used */ - - return res; /* pciio_dmamap_addr succeeded */ -} - -void -pciio_dmamap_drain(pciio_dmamap_t map) -{ - DMAMAP_FUNC(map, dmamap_drain) - (CAST_DMAMAP(map)); -} - -void -pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) -{ - DEV_FUNC(dev, dmaaddr_drain) - (dev, addr, size); -} - -void -pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list) -{ - DEV_FUNC(dev, dmalist_drain) - (dev, list); -} - -/* ===================================================================== - * INTERRUPT MANAGEMENT - * - * Allow crosstalk devices to establish interrupts - */ - -/* - * Allocate resources required for an interrupt as specified in intr_desc. - * Return resource handle in intr_hdl. - */ -pciio_intr_t -pciio_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - pciio_intr_line_t lines, /* INTR line(s) to attach */ - devfs_handle_t owner_dev) -{ /* owner of this interrupt */ - return (pciio_intr_t) DEV_FUNC(dev, intr_alloc) - (dev, dev_desc, lines, owner_dev); -} - -/* - * Free resources consumed by intr_alloc. - */ -void -pciio_intr_free(pciio_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_free) - (CAST_INTR(intr_hdl)); -} - -/* - * Associate resources allocated with a previous pciio_intr_alloc call with the - * described handler, arg, name, etc. - * - * Returns 0 on success, returns <0 on failure. - */ -int -pciio_intr_connect(pciio_intr_t intr_hdl) /* pciio intr resource handle */ -{ - return INTR_FUNC(intr_hdl, intr_connect) - (CAST_INTR(intr_hdl)); -} - -/* - * Disassociate handler with the specified interrupt. - */ -void -pciio_intr_disconnect(pciio_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_disconnect) - (CAST_INTR(intr_hdl)); -} - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. - */ -devfs_handle_t -pciio_intr_cpu_get(pciio_intr_t intr_hdl) -{ - return INTR_FUNC(intr_hdl, intr_cpu_get) - (CAST_INTR(intr_hdl)); -} - -void -pciio_slot_func_to_name(char *name, - pciio_slot_t slot, - pciio_function_t func) -{ - /* - * standard connection points: - * - * PCIIO_SLOT_NONE: .../pci/direct - * PCIIO_FUNC_NONE: .../pci/ ie. .../pci/3 - * multifunction: .../pci/ ie. .../pci/3c - */ - - if (slot == PCIIO_SLOT_NONE) - sprintf(name, EDGE_LBL_DIRECT); - else if (func == PCIIO_FUNC_NONE) - sprintf(name, "%d", slot); - else - sprintf(name, "%d%c", slot, 'a'+func); -} - -/* ===================================================================== - * CONFIGURATION MANAGEMENT - */ - -/* - * Startup a crosstalk provider - */ -void -pciio_provider_startup(devfs_handle_t pciio_provider) -{ - DEV_FUNC(pciio_provider, provider_startup) - (pciio_provider); -} - -/* - * Shutdown a crosstalk provider - */ -void -pciio_provider_shutdown(devfs_handle_t pciio_provider) -{ - DEV_FUNC(pciio_provider, provider_shutdown) - (pciio_provider); -} - -/* - * Specify endianness constraints. The driver tells us what the device - * does and how it would like to see things in memory. We reply with - * how things will actually appear in memory. - */ -pciio_endian_t -pciio_endian_set(devfs_handle_t dev, - pciio_endian_t device_end, - pciio_endian_t desired_end) -{ - ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE)); - ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE)); - -#if DEBUG -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_ALERT "%v: pciio_endian_set is going away.\n" - "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n" - "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n", - dev); -#else - printk(KERN_ALERT "0x%x: pciio_endian_set is going away.\n" - "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n" - "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n", - dev); -#endif -#endif - - return DEV_FUNC(dev, endian_set) - (dev, device_end, desired_end); -} - -/* - * Specify PCI arbitration priority. - */ -pciio_priority_t -pciio_priority_set(devfs_handle_t dev, - pciio_priority_t device_prio) -{ - ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW)); - - return DEV_FUNC(dev, priority_set) - (dev, device_prio); -} - -/* - * Read value of configuration register - */ -uint64_t -pciio_config_get(devfs_handle_t dev, - unsigned reg, - unsigned size) -{ - uint64_t value = 0; - unsigned shift = 0; - - /* handle accesses that cross words here, - * since that's common code between all - * possible providers. - */ - while (size > 0) { - unsigned biw = 4 - (reg&3); - if (biw > size) - biw = size; - - value |= DEV_FUNC(dev, config_get) - (dev, reg, biw) << shift; - - shift += 8*biw; - reg += biw; - size -= biw; - } - return value; -} - -/* - * Change value of configuration register - */ -void -pciio_config_set(devfs_handle_t dev, - unsigned reg, - unsigned size, - uint64_t value) -{ - /* handle accesses that cross words here, - * since that's common code between all - * possible providers. - */ - while (size > 0) { - unsigned biw = 4 - (reg&3); - if (biw > size) - biw = size; - - DEV_FUNC(dev, config_set) - (dev, reg, biw, value); - reg += biw; - size -= biw; - value >>= biw * 8; - } -} - -/* ===================================================================== - * GENERIC PCI SUPPORT FUNCTIONS - */ - -/* - * Issue a hardware reset to a card. - */ -int -pciio_reset(devfs_handle_t dev) -{ - return DEV_FUNC(dev, reset) (dev); -} - -/* - * flush write gather buffers - */ -int -pciio_write_gather_flush(devfs_handle_t dev) -{ - return DEV_FUNC(dev, write_gather_flush) (dev); -} - -devfs_handle_t -pciio_intr_dev_get(pciio_intr_t pciio_intr) -{ - return (pciio_intr->pi_dev); -} - -/****** Generic crosstalk pio interfaces ******/ -devfs_handle_t -pciio_pio_dev_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_dev); -} - -pciio_slot_t -pciio_pio_slot_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_slot); -} - -pciio_space_t -pciio_pio_space_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_space); -} - -iopaddr_t -pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_pciaddr); -} - -ulong -pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_mapsz); -} - -caddr_t -pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap) -{ - return (pciio_piomap->pp_kvaddr); -} - -/****** Generic crosstalk dma interfaces ******/ -devfs_handle_t -pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap) -{ - return (pciio_dmamap->pd_dev); -} - -pciio_slot_t -pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap) -{ - return (pciio_dmamap->pd_slot); -} - -/****** Generic pci slot information interfaces ******/ - -pciio_info_t -pciio_info_chk(devfs_handle_t pciio) -{ - arbitrary_info_t ainfo = 0; - - hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo); - return (pciio_info_t) ainfo; -} - -pciio_info_t -pciio_info_get(devfs_handle_t pciio) -{ - pciio_info_t pciio_info; - - pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio); - -#ifdef DEBUG_PCIIO - { - int pos; - char dname[256]; - pos = devfs_generate_path(pciio, dname, 256); - printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); - } -#endif /* DEBUG_PCIIO */ - - if ((pciio_info != NULL) && - (pciio_info->c_fingerprint != pciio_info_fingerprint) - && (pciio_info->c_fingerprint != NULL)) { - - return((pciio_info_t)-1); /* Should panic .. */ - } - - - return pciio_info; -} - -void -pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info) -{ - if (pciio_info != NULL) - pciio_info->c_fingerprint = pciio_info_fingerprint; - hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info); - - /* Also, mark this vertex as a PCI slot - * and use the pciio_info, so pciio_info_chk - * can work (and be fairly efficient). - */ - hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO, - (arbitrary_info_t) pciio_info); -} - -devfs_handle_t -pciio_info_dev_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_vertex); -} - -pciio_slot_t -pciio_info_slot_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_slot); -} - -pciio_function_t -pciio_info_function_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_func); -} - -pciio_vendor_id_t -pciio_info_vendor_id_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_vendor); -} - -pciio_device_id_t -pciio_info_device_id_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_device); -} - -devfs_handle_t -pciio_info_master_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_master); -} - -arbitrary_info_t -pciio_info_mfast_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_mfast); -} - -pciio_provider_t * -pciio_info_pops_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_pops); -} - -error_handler_f * -pciio_info_efunc_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_efunc); -} - -error_handler_arg_t * -pciio_info_einfo_get(pciio_info_t pciio_info) -{ - return (pciio_info->c_einfo); -} - -pciio_space_t -pciio_info_bar_space_get(pciio_info_t info, int win) -{ - return info->c_window[win].w_space; -} - -iopaddr_t -pciio_info_bar_base_get(pciio_info_t info, int win) -{ - return info->c_window[win].w_base; -} - -size_t -pciio_info_bar_size_get(pciio_info_t info, int win) -{ - return info->c_window[win].w_size; -} - -iopaddr_t -pciio_info_rom_base_get(pciio_info_t info) -{ - return info->c_rbase; -} - -size_t -pciio_info_rom_size_get(pciio_info_t info) -{ - return info->c_rsize; -} - - -/* ===================================================================== - * GENERIC PCI INITIALIZATION FUNCTIONS - */ - -/* - * pciioinit: called once during device driver - * initializtion if this driver is configured into - * the system. - */ -void -pciio_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("pciio_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (pciio_registry == NULL) { - cp = cdl_new(EDGE_LBL_PCI, "vendor", "device"); - if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(pciio_registry != NULL); -} - -/* - * pciioattach: called for each vertex in the graph - * that is a PCI provider. - */ -/*ARGSUSED */ -int -pciio_attach(devfs_handle_t pciio) -{ -#if DEBUG && ATTACH_DEBUG -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk("%v: pciio_attach\n", pciio); -#else - printk("0x%x: pciio_attach\n", pciio); -#endif -#endif - return 0; -} - -/* - * Associate a set of pciio_provider functions with a vertex. - */ -void -pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns) -{ - hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns); -} - -/* - * Disassociate a set of pciio_provider functions with a vertex. - */ -void -pciio_provider_unregister(devfs_handle_t provider) -{ - arbitrary_info_t ainfo; - - hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo); -} - -/* - * Obtain a pointer to the pciio_provider functions for a specified Crosstalk - * provider. - */ -pciio_provider_t * -pciio_provider_fns_get(devfs_handle_t provider) -{ - arbitrary_info_t ainfo = 0; - - (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo); - return (pciio_provider_t *) ainfo; -} - -/*ARGSUSED4 */ -int -pciio_driver_register( - pciio_vendor_id_t vendor_id, - pciio_device_id_t device_id, - char *driver_prefix, - unsigned flags) -{ - /* a driver's init routine might call - * pciio_driver_register before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - return cdl_add_driver(pciio_registry, - vendor_id, device_id, - driver_prefix, flags, NULL); -} - -/* - * Remove an initialization function. - */ -void -pciio_driver_unregister( - char *driver_prefix) -{ - /* before a driver calls unregister, - * it must have called register; so - * we can assume we have a registry here. - */ - ASSERT(pciio_registry != NULL); - - cdl_del_driver(pciio_registry, driver_prefix, NULL); -} - -/* - * Set the slot status for a device supported by the - * driver being registered. - */ -void -pciio_driver_reg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Set the slot status for a device supported by the - * driver being unregistered. - */ -void -pciio_driver_unreg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Call some function with each vertex that - * might be one of this driver's attach points. - */ -void -pciio_iterate(char *driver_prefix, - pciio_iter_f * func) -{ - /* a driver's init routine might call - * pciio_iterate before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - ASSERT(pciio_registry != NULL); - - cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func); -} - -devfs_handle_t -pciio_device_register( - devfs_handle_t connectpt, /* vertex for /hw/.../pciio/%d */ - devfs_handle_t master, /* card's master ASIC (PCI provider) */ - pciio_slot_t slot, /* card's slot */ - pciio_function_t func, /* card's func */ - pciio_vendor_id_t vendor_id, - pciio_device_id_t device_id) -{ - return pciio_device_info_register - (connectpt, pciio_device_info_new (NULL, master, slot, func, - vendor_id, device_id)); -} - -void -pciio_device_unregister(devfs_handle_t pconn) -{ - DEV_FUNC(pconn,device_unregister)(pconn); -} - -pciio_info_t -pciio_device_info_new( - pciio_info_t pciio_info, - devfs_handle_t master, - pciio_slot_t slot, - pciio_function_t func, - pciio_vendor_id_t vendor_id, - pciio_device_id_t device_id) -{ - if (!pciio_info) - GET_NEW(pciio_info); - ASSERT(pciio_info != NULL); - - pciio_info->c_slot = slot; - pciio_info->c_func = func; - pciio_info->c_vendor = vendor_id; - pciio_info->c_device = device_id; - pciio_info->c_master = master; - pciio_info->c_mfast = hwgraph_fastinfo_get(master); - pciio_info->c_pops = pciio_provider_fns_get(master); - pciio_info->c_efunc = 0; - pciio_info->c_einfo = 0; - - return pciio_info; -} - -void -pciio_device_info_free(pciio_info_t pciio_info) -{ - /* NOTE : pciio_info is a structure within the pcibr_info - * and not a pointer to memory allocated on the heap !! - */ - BZERO((char *)pciio_info,sizeof(pciio_info)); -} - -devfs_handle_t -pciio_device_info_register( - devfs_handle_t connectpt, /* vertex at center of bus */ - pciio_info_t pciio_info) /* details about the connectpt */ -{ - char name[32]; - devfs_handle_t pconn; - int device_master_set(devfs_handle_t, devfs_handle_t); - - pciio_slot_func_to_name(name, - pciio_info->c_slot, - pciio_info->c_func); - - if (GRAPH_SUCCESS != - hwgraph_path_add(connectpt, name, &pconn)) - return pconn; - - pciio_info->c_vertex = pconn; - pciio_info_set(pconn, pciio_info); -#ifdef DEBUG_PCIIO - { - int pos; - char dname[256]; - pos = devfs_generate_path(pconn, dname, 256); - printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]); - } -#endif /* DEBUG_PCIIO */ - - /* - * create link to our pci provider - */ - - device_master_set(pconn, pciio_info->c_master); - -#if USRPCI - /* - * Call into usrpci provider to let it initialize for - * the given slot. - */ - if (pciio_info->c_slot != PCIIO_SLOT_NONE) - usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot); -#endif - - return pconn; -} - -void -pciio_device_info_unregister(devfs_handle_t connectpt, - pciio_info_t pciio_info) -{ - char name[32]; - devfs_handle_t pconn; - - if (!pciio_info) - return; - - pciio_slot_func_to_name(name, - pciio_info->c_slot, - pciio_info->c_func); - - hwgraph_edge_remove(connectpt,name,&pconn); - pciio_info_set(pconn,0); - - /* Remove the link to our pci provider */ - hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL); - - - hwgraph_vertex_unref(pconn); - hwgraph_vertex_destroy(pconn); - -} -/* Add the pci card inventory information to the hwgraph - */ -static void -pciio_device_inventory_add(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - - ASSERT(pciio_info); - ASSERT(pciio_info->c_vertex == pconn_vhdl); - - /* Donot add inventory for non-existent devices */ - if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE) || - (pciio_info->c_device == PCIIO_DEVICE_ID_NONE)) - return; - device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP, - pciio_info->c_vendor,pciio_info->c_device, - pciio_info->c_slot); -} - -/*ARGSUSED */ -int -pciio_device_attach(devfs_handle_t pconn, - int drv_flags) -{ - pciio_info_t pciio_info; - pciio_vendor_id_t vendor_id; - pciio_device_id_t device_id; - - - pciio_device_inventory_add(pconn); - pciio_info = pciio_info_get(pconn); - - vendor_id = pciio_info->c_vendor; - device_id = pciio_info->c_device; - - /* we don't start attaching things until - * all the driver init routines (including - * pciio_init) have been called; so we - * can assume here that we have a registry. - */ - ASSERT(pciio_registry != NULL); - - return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags)); -} - -int -pciio_device_detach(devfs_handle_t pconn, - int drv_flags) -{ - pciio_info_t pciio_info; - pciio_vendor_id_t vendor_id; - pciio_device_id_t device_id; - - pciio_info = pciio_info_get(pconn); - - vendor_id = pciio_info->c_vendor; - device_id = pciio_info->c_device; - - /* we don't start attaching things until - * all the driver init routines (including - * pciio_init) have been called; so we - * can assume here that we have a registry. - */ - ASSERT(pciio_registry != NULL); - - return(cdl_del_connpt(pciio_registry, vendor_id, device_id, - pconn, drv_flags)); - -} - -/* SN2 */ -/* - * Allocate (if necessary) and initialize a PCI window mapping structure. - */ -pciio_win_map_t -pciio_device_win_map_new(pciio_win_map_t win_map, - size_t region_size, - size_t page_size) -{ - ASSERT((page_size & (page_size - 1)) == 0); - ASSERT((region_size & (page_size - 1)) == 0); - - if (win_map == NULL) - NEW(win_map); - - /* - * The map array tracks the free ``pages'' in the region. The worst - * case scenario is when every other page in the region is free -- - * e.i. maximum fragmentation. This leads to (max pages + 1) / 2 + 1 - * map entries. The first "+1" handles the divide by 2 rounding; the - * second handles the need for an end marker sentinel. - */ - win_map->wm_map = rmallocmap((region_size / page_size + 1) / 2 + 1); - win_map->wm_page_size = page_size; - ASSERT(win_map->wm_map != NULL); - - return win_map; -} - -/* - * Free resources associated with a PCI window mapping structure. - */ -extern void -pciio_device_win_map_free(pciio_win_map_t win_map) -{ - rmfreemap(win_map->wm_map); - bzero(win_map, sizeof *win_map); -} - -/* - * Populate window map with specified free range. - */ -void -pciio_device_win_populate(pciio_win_map_t win_map, - iopaddr_t ioaddr, - size_t size) -{ - ASSERT((size & (win_map->wm_page_size - 1)) == 0); - ASSERT((ioaddr & (win_map->wm_page_size - 1)) == 0); - - rmfree(win_map->wm_map, - size / win_map->wm_page_size, - (unsigned long)ioaddr / win_map->wm_page_size); - -} -/* - * Allocate space from the specified PCI window mapping resource. On - * success record information about the allocation in the supplied window - * allocation cookie (if non-NULL) and return the address of the allocated - * window. On failure return NULL. - * - * The "size" parameter is usually from a PCI device's Base Address Register - * (BAR) decoder. As such, the allocation must be aligned to be a multiple of - * that. The "align" parameter acts as a ``minimum alignment'' allocation - * constraint. The alignment contraint reflects system or device addressing - * restrictions such as the inability to share higher level ``windows'' - * between devices, etc. The returned PCI address allocation will be a - * multiple of the alignment constraint both in alignment and size. Thus, the - * returned PCI address block is aligned to the maximum of the requested size - * and alignment. - */ -iopaddr_t -pciio_device_win_alloc(pciio_win_map_t win_map, - pciio_win_alloc_t win_alloc, - size_t size, size_t align) -{ - unsigned long base; - -#ifdef PIC_LATER - ASSERT((size & (size - 1)) == 0); - ASSERT((align & (align - 1)) == 0); - - /* - * Convert size and alignment to pages. If size is greated than the - * requested alignment, we bump the alignment up to size; otherwise - * convert the size into a multiple of the alignment request. - */ - size = (size + win_map->wm_page_size - 1) / win_map->wm_page_size; - align = align / win_map->wm_page_size; - if (size > align) - align = size; - else - size = (size + align - 1) & ~(align - 1); - - /* XXXX */ - base = rmalloc_align(win_map->wm_map, size, align, VM_NOSLEEP); - if (base == RMALLOC_FAIL) - return((iopaddr_t)NULL); -#else - int index_page, index_page_align; - int align_pages, size_pages; - int alloc_pages, free_pages; - int addr_align; - - /* Convert PCI bus alignment from bytes to pages */ - align_pages = align / win_map->wm_page_size; - - /* Convert PCI request from bytes to pages */ - size_pages = (size / win_map->wm_page_size) + - ((size % win_map->wm_page_size) ? 1 : 0); - - /* Align address with the larger of the size or the requested slot align */ - if (size_pages > align_pages) - align_pages = size_pages; - - /* - * Avoid wasting space by aligning - 1; this will prevent crossing - * another alignment boundary. - */ - alloc_pages = size_pages + (align_pages - 1); - - /* Allocate PCI bus space in pages */ - index_page = (int) rmalloc(win_map->wm_map, - (size_t) alloc_pages); - - /* Error if no PCI bus address space available */ - if (!index_page) - return 0; - - /* PCI bus address index starts at 0 */ - index_page--; - - /* Align the page offset as requested */ - index_page_align = (index_page + (align_pages - 1)) - - ((index_page + (align_pages - 1)) % align_pages); - - free_pages = (align_pages - 1) - (index_page_align - index_page); - - /* Free unused PCI bus pages adjusting the index to start at 1 */ - rmfree(win_map->wm_map, - free_pages, - (index_page_align + 1) + size_pages); - - /* Return aligned PCI bus space in bytes */ - addr_align = (index_page_align * win_map->wm_page_size); - base = index_page; - size = alloc_pages - free_pages; -#endif /* PIC_LATER */ - - /* - * If a window allocation cookie has been supplied, use it to keep - * track of all the allocated space assigned to this window. - */ - if (win_alloc) { - win_alloc->wa_map = win_map; - win_alloc->wa_base = base; - win_alloc->wa_pages = size; - } - - return base * win_map->wm_page_size; -} - -/* - * Free the specified window allocation back into the PCI window mapping - * resource. As noted above, we keep page addresses offset by 1 ... - */ -void -pciio_device_win_free(pciio_win_alloc_t win_alloc) -{ - if (win_alloc->wa_pages) - rmfree(win_alloc->wa_map->wm_map, - win_alloc->wa_pages, - win_alloc->wa_base); -} - -/* - * pciio_error_register: - * arrange for a function to be called with - * a specified first parameter plus other - * information when an error is encountered - * and traced to the pci slot corresponding - * to the connection point pconn. - * - * may also be called with a null function - * pointer to "unregister" the error handler. - * - * NOTE: subsequent calls silently overwrite - * previous data for this vertex. We assume that - * cooperating drivers, well, cooperate ... - */ -void -pciio_error_register(devfs_handle_t pconn, - error_handler_f *efunc, - error_handler_arg_t einfo) -{ - pciio_info_t pciio_info; - - pciio_info = pciio_info_get(pconn); - ASSERT(pciio_info != NULL); - pciio_info->c_efunc = efunc; - pciio_info->c_einfo = einfo; -} - -/* - * Check if any device has been found in this slot, and return - * true or false - * vhdl is the vertex for the slot - */ -int -pciio_slot_inuse(devfs_handle_t pconn_vhdl) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - - ASSERT(pciio_info); - ASSERT(pciio_info->c_vertex == pconn_vhdl); - if (pciio_info->c_vendor) { - /* - * Non-zero value for vendor indicate - * a board being found in this slot. - */ - return 1; - } - return 0; -} - -int -pciio_dma_enabled(devfs_handle_t pconn_vhdl) -{ - return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl); -} - -/* - * These are complementary Linux interfaces that takes in a pci_dev * as the - * first arguement instead of devfs_handle_t. - */ -iopaddr_t snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned); -pciio_dmamap_t snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned); -void snia_pciio_dmamap_free(pciio_dmamap_t); -iopaddr_t snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t); -void snia_pciio_dmamap_done(pciio_dmamap_t); -pciio_endian_t snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end, - pciio_endian_t desired_end); - -#include -EXPORT_SYMBOL(snia_pciio_dmatrans_addr); -EXPORT_SYMBOL(snia_pciio_dmamap_alloc); -EXPORT_SYMBOL(snia_pciio_dmamap_free); -EXPORT_SYMBOL(snia_pciio_dmamap_addr); -EXPORT_SYMBOL(snia_pciio_dmamap_done); -EXPORT_SYMBOL(snia_pciio_endian_set); - -int -snia_pcibr_rrb_alloc(struct pci_dev *pci_dev, - int *count_vchan0, - int *count_vchan1) -{ - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); - - return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1); -} -EXPORT_SYMBOL(snia_pcibr_rrb_alloc); - -pciio_endian_t -snia_pciio_endian_set(struct pci_dev *pci_dev, - pciio_endian_t device_end, - pciio_endian_t desired_end) -{ - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); - - return DEV_FUNC(dev, endian_set) - (dev, device_end, desired_end); -} - -iopaddr_t -snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - unsigned flags) -{ /* defined in dma.h */ - - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); - - return DEV_FUNC(dev, dmatrans_addr) - (dev, dev_desc, paddr, byte_count, flags); -} - -pciio_dmamap_t -snia_pciio_dmamap_alloc(struct pci_dev *pci_dev, /* set up mappings for this device */ - device_desc_t dev_desc, /* device descriptor */ - size_t byte_count_max, /* max size of a mapping */ - unsigned flags) -{ /* defined in dma.h */ - - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); - - return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc) - (dev, dev_desc, byte_count_max, flags); -} - -void -snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_free) - (CAST_DMAMAP(pciio_dmamap)); -} - -iopaddr_t -snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - paddr_t paddr, /* map for this address */ - size_t byte_count) -{ /* map this many bytes */ - return DMAMAP_FUNC(pciio_dmamap, dmamap_addr) - (CAST_DMAMAP(pciio_dmamap), paddr, byte_count); -} - -void -snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) -{ - DMAMAP_FUNC(pciio_dmamap, dmamap_done) - (CAST_DMAMAP(pciio_dmamap)); -} - diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/sgi_io_init.c linux-2.4.22/arch/ia64/sn/io/sn1/sgi_io_init.c --- linux-2.4.21/arch/ia64/sn/io/sn1/sgi_io_init.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/sgi_io_init.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,324 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void mlreset(int ); -extern int init_hcl(void); -extern void klgraph_hack_init(void); -extern void hubspc_init(void); -extern void pciio_init(void); -extern void pcibr_init(void); -extern void xtalk_init(void); -extern void xbow_init(void); -extern void xbmon_init(void); -extern void pciiox_init(void); -extern void usrpci_init(void); -extern void ioc3_init(void); -extern void initialize_io(void); -extern void intr_clear_all(nasid_t); -extern void klhwg_add_all_modules(devfs_handle_t); -extern void klhwg_add_all_nodes(devfs_handle_t); - -void sn_mp_setup(void); -extern devfs_handle_t hwgraph_root; -extern void io_module_init(void); -extern void pci_bus_cvlink_init(void); -extern void temp_hack(void); - -extern int pci_bus_to_hcl_cvlink(void); - -/* #define DEBUG_IO_INIT 1 */ -#ifdef DEBUG_IO_INIT -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* DEBUG_IO_INIT */ - -/* - * per_hub_init - * - * This code is executed once for each Hub chip. - */ -static void -per_hub_init(cnodeid_t cnode) -{ - nasid_t nasid; - nodepda_t *npdap; - ii_icmr_u_t ii_icmr; - ii_ibcr_u_t ii_ibcr; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - ASSERT(nasid != INVALID_NASID); - ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode); - - npdap = NODEPDA(cnode); - - /* initialize per-node synergy perf instrumentation */ - npdap->synergy_perf_enabled = 0; /* off by default */ - npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED; - npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT; - npdap->synergy_inactive_intervals = 0; - npdap->synergy_active_intervals = 0; - npdap->synergy_perf_data = NULL; - npdap->synergy_perf_first = NULL; - - - /* - * Set the total number of CRBs that can be used. - */ - ii_icmr.ii_icmr_regval= 0x0; - ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF; - REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval); - - /* - * Set the number of CRBs that both of the BTEs combined - * can use minus 1. - */ - ii_ibcr.ii_ibcr_regval= 0x0; - ii_ibcr.ii_ibcr_fld_s.i_count = 0x8; - REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval); - - /* - * Set CRB timeout to be 10ms. - */ - REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 ); - REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); - - - /* Reserve all of the hardwired interrupt levels. */ - intr_reserve_hardwired(cnode); - - /* Initialize error interrupts for this hub. */ - hub_error_init(cnode); -} - -/* - * This routine is responsible for the setup of all the IRIX hwgraph style - * stuff that's been pulled into linux. It's called by sn_pci_find_bios which - * is called just before the generic Linux PCI layer does its probing (by - * platform_pci_fixup aka sn_pci_fixup). - * - * It is very IMPORTANT that this call is only made by the Master CPU! - * - */ - -void -sgi_master_io_infr_init(void) -{ - int cnode; - - /* - * Do any early init stuff .. einit_tbl[] etc. - */ - DBG("--> sgi_master_io_infr_init: calling init_hcl().\n"); - init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */ - -#ifdef Colin - -printk("Testing out Xbridge Access .. if it hangs Xbridge is not init yet.\n"); -printk(" Reading Xbridge WID at address 0xc00000080f000000 0x%p\n", (* (volatile uint32_t *)(0xc00000080f000000))); - -printk("Testing out PCI Address Space Accesses\n"); -printk(" Testing PCI Config Read Byte: address 0xc00000080f020000 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020000))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020001 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020001))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020002 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020002))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020003 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020003))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020004))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020005 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020005))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020006 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020006))); - -printk(" Testing PCI Config Read Byte: address 0xc00000080f020007 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020007))); - -printk(" Testing PCI Config Word: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020004))); - -printk(" Testing PCI Config Word: address 0xc00000080f020008 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020008))); - -#endif - - /* - * initialize the Linux PCI to xwidget vertexes .. - */ - DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n"); - pci_bus_cvlink_init(); - -#ifdef BRINGUP - /* - * Hack to provide statically initialzed klgraph entries. - */ - DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n"); - klgraph_hack_init(); -#endif /* BRINGUP */ - - /* - * This is the Master CPU. Emulate mlsetup and main.c in Irix. - */ - DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n"); - mlreset(0); /* Master .. */ - - /* - * allowboot() is called by kern/os/main.c in main() - * Emulate allowboot() ... - * per_cpu_init() - only need per_hub_init() - * cpu_io_setup() - Nothing to do. - * - */ - DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n"); - sn_mp_setup(); - - DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n"); - for (cnode = 0; cnode < numnodes; cnode++) { - per_hub_init(cnode); - } - - /* We can do headless hub cnodes here .. */ - - /* - * io_init[] stuff. - * - * Get SGI IO Infrastructure drivers to init and register with - * each other etc. - */ - - DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n"); - hubspc_init(); - - DBG("--> sgi_master_io_infr_init: calling pciio_init()\n"); - pciio_init(); - - DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n"); - pcibr_init(); - - DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n"); - xtalk_init(); - - DBG("--> sgi_master_io_infr_init: calling xbow_init()\n"); - xbow_init(); - - DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n"); - xbmon_init(); - - DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n"); - pciiox_init(); - - DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n"); - usrpci_init(); - - DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n"); - ioc3_init(); - - /* - * - * Our IO Infrastructure drivers are in place .. - * Initialize the whole IO Infrastructure .. xwidget/device probes. - * - */ - DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n"); - initialize_io(); - - DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n"); - pci_bus_to_hcl_cvlink(); - -#ifdef CONFIG_PCIBA - DBG("--> sgi_master_io_infr_init: calling pciba_init()\n"); - pciba_init(); -#endif - - DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n"); -} - -/* - * sgi_slave_io_infr_init - This routine must be called on all cpus except - * the Master CPU. - */ -void -sgi_slave_io_infr_init(void) -{ - /* Emulate cboot() .. */ - mlreset(1); /* This is a slave cpu */ - - // per_hub_init(0); /* Need to get and send in actual cnode number */ - - /* Done */ -} - -/* - * One-time setup for MP SN. - * Allocate per-node data, slurp prom klconfig information and - * convert it to hwgraph information. - */ -void -sn_mp_setup(void) -{ - cnodeid_t cnode; - cpuid_t cpu; - - for (cpu = 0; cpu < smp_num_cpus; cpu++) { - /* Skip holes in CPU space */ - if (cpu_enabled(cpu)) { - init_platform_pda(cpu); - } - } - - /* - * Initialize platform-dependent vertices in the hwgraph: - * module - * node - * cpu - * memory - * slot - * hub - * router - * xbow - */ - - DBG("sn_mp_io_setup: calling io_module_init()\n"); - io_module_init(); /* Use to be called module_init() .. */ - - DBG("sn_mp_setup: calling klhwg_add_all_modules()\n"); - klhwg_add_all_modules(hwgraph_root); - DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n"); - klhwg_add_all_nodes(hwgraph_root); - - - for (cnode = 0; cnode < numnodes; cnode++) { - - /* - * This routine clears the Hub's Interrupt registers. - */ - /* - * We need to move this intr_clear_all() routine - * from SN/intr.c to a more appropriate file. - * Talk to Al Mayer. - */ - intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); - /* now init the hub */ - // per_hub_init(cnode); - - } - - synergy_perf_init(); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/xbow.c linux-2.4.22/arch/ia64/sn/io/sn1/xbow.c --- linux-2.4.21/arch/ia64/sn/io/sn1/xbow.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/xbow.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1086 +0,0 @@ -/* $Id: xbow.c,v 1.3 2002/11/21 17:51:57 jh Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define DEBUG 1 */ -/* #define XBOW_DEBUG 1 */ - - -/* - * Files needed to get the device driver entry points - */ - -#include -#include -#include -#include - -#include -#include - - -#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DEL(ptr) (kfree(ptr)) - -int xbow_devflag = D_MP; - -/* - * This file supports the Xbow chip. Main functions: initializtion, - * error handling, and GBR. - */ - -/* - * each vertex corresponding to an xbow chip - * has a "fastinfo" pointer pointing at one - * of these things. - */ -typedef struct xbow_soft_s *xbow_soft_t; - -struct xbow_soft_s { - devfs_handle_t conn; /* our connection point */ - devfs_handle_t vhdl; /* xbow's private vertex */ - devfs_handle_t busv; /* the xswitch vertex */ - xbow_t *base; /* PIO pointer to crossbow chip */ - char *name; /* hwgraph name */ - - xbow_perf_t xbow_perfcnt[XBOW_PERF_COUNTERS]; - xbow_perf_link_t xbow_perflink[MAX_XBOW_PORTS]; - xbow_link_status_t xbow_link_status[MAX_XBOW_PORTS]; - spinlock_t xbow_perf_lock; - int link_monitor; - widget_cfg_t *wpio[MAX_XBOW_PORTS]; /* cached PIO pointer */ - - /* Bandwidth allocation state. Bandwidth values are for the - * destination port since contention happens there. - * Implicit mapping from xbow ports (8..f) -> (0..7) array indices. - */ - spinlock_t xbow_bw_alloc_lock; /* bw allocation lock */ - unsigned long long bw_hiwm[MAX_XBOW_PORTS]; /* hiwater mark values */ - unsigned long long bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */ -}; - -#define xbow_soft_set(v,i) hwgraph_fastinfo_set((v), (arbitrary_info_t)(i)) -#define xbow_soft_get(v) ((xbow_soft_t)hwgraph_fastinfo_get((v))) - -/* - * Function Table of Contents - */ - -void xbow_mlreset(xbow_t *); -void xbow_init(void); -int xbow_attach(devfs_handle_t); - -int xbow_open(devfs_handle_t *, int, int, cred_t *); -int xbow_close(devfs_handle_t, int, int, cred_t *); - -int xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); -int xbow_unmap(devfs_handle_t, vhandl_t *); -int xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); - -int xbow_widget_present(xbow_t *, int); -static int xbow_link_alive(xbow_t *, int); -devfs_handle_t xbow_widget_lookup(devfs_handle_t, int); - -void xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); - - - -void xbow_update_perf_counters(devfs_handle_t); -xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t); -int xbow_enable_perf_counter(devfs_handle_t, int, int, int); -xbow_link_status_t *xbow_get_llp_status(devfs_handle_t); -void xbow_update_llp_status(devfs_handle_t); - -int xbow_disable_llp_monitor(devfs_handle_t); -int xbow_enable_llp_monitor(devfs_handle_t); -int xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t, - unsigned long long, unsigned long long); - -xswitch_reset_link_f xbow_reset_link; - -void idbg_xbowregs(int64_t); - -xswitch_provider_t xbow_provider = -{ - xbow_reset_link, -}; - -/* - * xbow_mlreset: called at mlreset time if the - * platform specific code determines that there is - * a crossbow in a critical path that must be - * functional before the driver would normally get - * the device properly set up. - * - * what do we need to do, that the boot prom can - * not be counted on to have already done, that is - * generic across all platforms using crossbows? - */ -/*ARGSUSED */ -void -xbow_mlreset(xbow_t * xbow) -{ -} - -/* - * xbow_init: called with the rest of the device - * driver XXX_init routines. This platform *might* - * have a Crossbow chip, or even several, but it - * might have none. Register with the crosstalk - * generic provider so when we encounter the chip - * the right magic happens. - */ -void -xbow_init(void) -{ - -#if DEBUG && ATTACH_DEBUG - printk("xbow_init\n"); -#endif - - xwidget_driver_register(PXBOW_WIDGET_PART_NUM, - 0, /* XXBOW_WIDGET_MFGR_NUM, */ - "xbow_", - CDL_PRI_HI); /* attach before friends */ - - - xwidget_driver_register(XXBOW_WIDGET_PART_NUM, - 0, /* XXBOW_WIDGET_MFGR_NUM, */ - "xbow_", - CDL_PRI_HI); /* attach before friends */ - - xwidget_driver_register(XBOW_WIDGET_PART_NUM, - XBOW_WIDGET_MFGR_NUM, - "xbow_", - CDL_PRI_HI); /* attach before friends */ -} - -#ifdef XBRIDGE_REGS_SIM -/* xbow_set_simulated_regs: sets xbow regs as needed - * for powering through the boot - */ -void -xbow_set_simulated_regs(xbow_t *xbow, int port) -{ - /* - * turn on link - */ - xbow->xb_link(port).link_status = (1<<31); - /* - * and give it a live widget too - */ - xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT; - /* - * zero the link control reg - */ - xbow->xb_link(port).link_control = 0x0; -} -#endif /* XBRIDGE_REGS_SIM */ - -/* - * xbow_attach: the crosstalk provider has - * determined that there is a crossbow widget - * present, and has handed us the connection - * point for that vertex. - * - * We not only add our own vertex, but add - * some "xtalk switch" data to the switch - * vertex (at the connect point's parent) if - * it does not have any. - */ - -/*ARGSUSED */ -int -xbow_attach(devfs_handle_t conn) -{ - /*REFERENCED */ - devfs_handle_t vhdl; - devfs_handle_t busv; - xbow_t *xbow; - xbow_soft_t soft; - int port; - xswitch_info_t info; - char devnm[MAXDEVNAME], *s; - xbowreg_t id; - int rev; - int i; - int xbow_num; - -#if DEBUG && ATTACH_DEBUG -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk("%v: xbow_attach\n", conn); -#else - printk("0x%x: xbow_attach\n", conn); -#endif -#endif - - /* - * Get a PIO pointer to the base of the crossbow - * chip. - */ -#ifdef XBRIDGE_REGS_SIM - printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t)); - xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL); - /* - * turn on ports e and f like in a real live ibrick - */ - xbow_set_simulated_regs(xbow, 0xe); - xbow_set_simulated_regs(xbow, 0xf); -#else - xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0); -#endif /* XBRIDGE_REGS_SIM */ - - /* - * Locate the "switch" vertex: it is the parent - * of our connection point. - */ - busv = hwgraph_connectpt_get(conn); -#if DEBUG && ATTACH_DEBUG - printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow); -#endif - - ASSERT(busv != GRAPH_VERTEX_NONE); - - /* - * Create our private vertex, and connect our - * driver information to it. This makes it possible - * for diagnostic drivers to open the crossbow - * vertex for access to registers. - */ - - /* - * We need to teach xbow drivers to provide the right set of - * file ops. - */ - vhdl = NULL; - vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - /* &hcl_fops */ (void *)&vhdl, NULL); - if (!vhdl) { - printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n", - (void *)conn); - } - - /* - * Allocate the soft state structure and attach - * it to the xbow's vertex - */ - NEW(soft); - soft->conn = conn; - soft->vhdl = vhdl; - soft->busv = busv; - soft->base = xbow; - /* does the universe really need another macro? */ - /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */ - hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); - -#define XBOW_NUM_SUFFIX_FORMAT "[xbow# %d]" - - /* Add xbow number as a suffix to the hwgraph name of the xbow. - * This is helpful while looking at the error/warning messages. - */ - xbow_num = 0; - - /* - * get the name of this xbow vertex and keep the info. - * This is needed during errors and interupts, but as - * long as we have it, we can use it elsewhere. - */ - s = dev_to_name(vhdl, devnm, MAXDEVNAME); - soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, - GFP_KERNEL); - sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num); - -#ifdef XBRIDGE_REGS_SIM - /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined - * as 0xd000, so I'm using that for the partnum bitfield. - */ - printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n"); - id = 0x2d000049; -#else - id = xbow->xb_wid_id; -#endif /* XBRIDGE_REGS_SIM */ - rev = XWIDGET_PART_REV_NUM(id); - - mutex_spinlock_init(&soft->xbow_perf_lock); - soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a; - soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b; - - /* Initialization for GBR bw allocation */ - mutex_spinlock_init(&soft->xbow_bw_alloc_lock); - -#define XBOW_8_BIT_PORT_BW_MAX (400 * 1000 * 1000) /* 400 MB/s */ -#define XBOW_16_BIT_PORT_BW_MAX (800 * 1000 * 1000) /* 800 MB/s */ - - /* Set bandwidth hiwatermark and current values */ - for (i = 0; i < MAX_XBOW_PORTS; i++) { - soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX; /* for now */ - soft->bw_cur_used[i] = 0; - } - - /* - * Enable xbow error interrupts - */ - xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE); - - /* - * take a census of the widgets present, - * leaving notes at the switch vertex. - */ - info = xswitch_info_new(busv); - - for (port = MAX_PORT_NUM - MAX_XBOW_PORTS; - port < MAX_PORT_NUM; ++port) { - if (!xbow_link_alive(xbow, port)) { -#if DEBUG && XBOW_DEBUG - printk(KERN_INFO "0x%p link %d is not alive\n", - busv, port); -#endif - continue; - } - if (!xbow_widget_present(xbow, port)) { -#if DEBUG && XBOW_DEBUG - printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port); -#endif - continue; - } -#if DEBUG && XBOW_DEBUG - printk(KERN_INFO "0x%p link %d has a widget\n", - busv, port); -#endif - - xswitch_info_link_is_ok(info, port); - /* - * Turn some error interrupts on - * and turn others off. The PROM has - * some things turned on we don't - * want to see (bandwidth allocation - * errors for instance); so if it - * is not listed here, it is not on. - */ - xbow->xb_link(port).link_control = - ( (xbow->xb_link(port).link_control - /* - * Turn off these bits; they are non-fatal, - * but we might want to save some statistics - * on the frequency of these errors. - * XXX FIXME XXX - */ - & ~XB_CTRL_RCV_CNT_OFLOW_IE - & ~XB_CTRL_XMT_CNT_OFLOW_IE - & ~XB_CTRL_BNDWDTH_ALLOC_IE - & ~XB_CTRL_RCV_IE) - /* - * These are the ones we want to turn on. - */ - | (XB_CTRL_ILLEGAL_DST_IE - | XB_CTRL_OALLOC_IBUF_IE - | XB_CTRL_XMT_MAX_RTRY_IE - | XB_CTRL_MAXREQ_TOUT_IE - | XB_CTRL_XMT_RTRY_IE - | XB_CTRL_SRC_TOUT_IE) ); - } - - xswitch_provider_register(busv, &xbow_provider); - - return 0; /* attach successful */ -} - -/*ARGSUSED */ -int -xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) -{ - return 0; - -} - -/*ARGSUSED */ -int -xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) -{ - return 0; -} - -/*ARGSUSED */ -int -xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) -{ - devfs_handle_t vhdl = dev_to_vhdl(dev); - xbow_soft_t soft = xbow_soft_get(vhdl); - int error; - - ASSERT(soft); - len = ctob(btoc(len)); - /* XXX- this ignores the offset!!! */ - error = v_mapphys(vt, (void *) soft->base, len); - return error; -} - -/*ARGSUSED */ -int -xbow_unmap(devfs_handle_t dev, vhandl_t *vt) -{ - return 0; -} - -/* This contains special-case code for grio. There are plans to make - * this general sometime in the future, but till then this should - * be good enough. - */ -xwidgetnum_t -xbow_widget_num_get(devfs_handle_t dev) -{ - devfs_handle_t tdev; - char devname[MAXDEVNAME]; - xwidget_info_t xwidget_info; - int i; - - vertex_to_name(dev, devname, MAXDEVNAME); - - /* If this is a pci controller vertex, traverse up using - * the ".." links to get to the widget. - */ - if (strstr(devname, EDGE_LBL_PCI) && - strstr(devname, EDGE_LBL_CONTROLLER)) { - tdev = dev; - for (i=0; i< 2; i++) { - if (hwgraph_edge_get(tdev, - HWGRAPH_EDGELBL_DOTDOT, &tdev) != - GRAPH_SUCCESS) - return XWIDGET_NONE; - } - - if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) { - return (xwidget_info_id_get(xwidget_info)); - } else { - return XWIDGET_NONE; - } - } - - return XWIDGET_NONE; -} - -int -xbow_ioctl(devfs_handle_t dev, - int cmd, - void *arg, - int flag, - struct cred *cr, - int *rvalp) -{ - devfs_handle_t vhdl; - int error = 0; - -#if defined (DEBUG) - int rc; - devfs_handle_t conn; - struct xwidget_info_s *xwidget_info; - xbow_soft_t xbow_soft; -#endif - *rvalp = 0; - - vhdl = dev_to_vhdl(dev); -#if defined (DEBUG) - xbow_soft = xbow_soft_get(vhdl); - conn = xbow_soft->conn; - - xwidget_info = xwidget_info_get(conn); - ASSERT_ALWAYS(xwidget_info != NULL); - - rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid); - ASSERT_ALWAYS(rc != 0); -#endif - switch (cmd) { - - case XBOWIOC_LLP_ERROR_ENABLE: - if ((error = xbow_enable_llp_monitor(vhdl)) != 0) - error = EINVAL; - - break; - - case XBOWIOC_LLP_ERROR_DISABLE: - - if ((error = xbow_disable_llp_monitor(vhdl)) != 0) - error = EINVAL; - - break; - - default: - break; - - } - return error; -} - -/* - * xbow_widget_present: See if a device is present - * on the specified port of this crossbow. - */ -int -xbow_widget_present(xbow_t *xbow, int port) -{ - if ( IS_RUNNING_ON_SIMULATOR() ) { - if ( (port == 14) || (port == 15) ) { - return 1; - } - else { - return 0; - } - } - else { - /* WAR: port 0xf on PIC is missing present bit */ - /* Need this for PIC */ - if (IS_PIC_XBOW(xbow->xb_wid_id) && port == 0xf) { - return 1; - } - return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT; - } -} - -static int -xbow_link_alive(xbow_t * xbow, int port) -{ - xbwX_stat_t xbow_linkstat; - - xbow_linkstat.linkstatus = xbow->xb_link(port).link_status; - return (xbow_linkstat.link_alive); -} - -/* - * xbow_widget_lookup - * Lookup the edges connected to the xbow specified, and - * retrieve the handle corresponding to the widgetnum - * specified. - * If not found, return 0. - */ -devfs_handle_t -xbow_widget_lookup(devfs_handle_t vhdl, - int widgetnum) -{ - xswitch_info_t xswitch_info; - devfs_handle_t conn; - - xswitch_info = xswitch_info_get(vhdl); - conn = xswitch_info_vhdl_get(xswitch_info, widgetnum); - return conn; -} - -/* - * xbow_intr_preset: called during mlreset time - * if the platform specific code needs to route - * an xbow interrupt before the xtalk infrastructure - * is available for use. - * - * Also called from xbow_setwidint, so we don't - * replicate the guts of the routine. - * - * XXX- probably should be renamed xbow_wid_intr_set or - * something to reduce confusion. - */ -/*ARGSUSED3 */ -void -xbow_intr_preset(void *which_widget, - int which_widget_intr, - xwidgetnum_t targ, - iopaddr_t addr, - xtalk_intr_vector_t vect) -{ - xbow_t *xbow = (xbow_t *) which_widget; - - xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) | - (0x000F0000 & (targ << 16)) | - XTALK_ADDR_TO_UPPER(addr)); - xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); - -} - -int xbow_xmit_retry_errors = 0; - -int -xbow_xmit_retry_error(xbow_soft_t soft, - int port) -{ - xswitch_info_t info; - devfs_handle_t vhdl; - widget_cfg_t *wid; - widgetreg_t id; - int part; - int mfgr; - - wid = soft->wpio[port - BASE_XBOW_PORT]; - if (wid == NULL) { - /* If we can't track down a PIO - * pointer to our widget yet, - * leave our caller knowing that - * we are interested in this - * interrupt if it occurs in - * the future. - */ - info = xswitch_info_get(soft->busv); - if (!info) - return 1; - vhdl = xswitch_info_vhdl_get(info, port); - if (vhdl == GRAPH_VERTEX_NONE) - return 1; - wid = (widget_cfg_t *) xtalk_piotrans_addr - (vhdl, 0, 0, sizeof *wid, 0); - if (!wid) - return 1; - soft->wpio[port - BASE_XBOW_PORT] = wid; - } - id = wid->w_id; - part = XWIDGET_PART_NUM(id); - mfgr = XWIDGET_MFG_NUM(id); - - /* If this thing is not a Bridge, - * do not activate the WAR, and - * tell our caller we do not need - * to be called again. - */ - if ((part != BRIDGE_WIDGET_PART_NUM) || - (mfgr != BRIDGE_WIDGET_MFGR_NUM)) { - /* FIXME: add Xbridge to the WAR. - * Shouldn't hurt anything. Later need to - * check if we can remove this. - */ - if ((part != XBRIDGE_WIDGET_PART_NUM) || - (mfgr != XBRIDGE_WIDGET_MFGR_NUM)) - return 0; - } - - /* count how many times we - * have picked up after - * LLP Transmit problems. - */ - xbow_xmit_retry_errors++; - - /* rewrite the control register - * to fix things up. - */ - wid->w_control = wid->w_control; - wid->w_control; - - return 1; -} - -void -xbow_update_perf_counters(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; - xbow_perf_link_t *xbow_plink = xbow_soft->xbow_perflink; - xbow_perfcount_t perf_reg; - unsigned long s; - int link, i; - - for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) { - if (xbow_perf->xp_mode == XBOW_MONITOR_NONE) - continue; - - s = mutex_spinlock(&xbow_soft->xbow_perf_lock); - - perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg; - - link = perf_reg.xb_perf.link_select; - - (xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] += - ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK); - xbow_perf->xp_current = perf_reg.xb_perf.count; - - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - } -} - -xbow_perf_link_t * -xbow_get_perf_counters(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_perf_link_t *xbow_perf_link = xbow_soft->xbow_perflink; - - return xbow_perf_link; -} - -int -xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; - xbow_linkctrl_t xbow_link_ctrl; - xbow_t *xbow = xbow_soft->base; - xbow_perfcount_t perf_reg; - unsigned long s; - int i; - - link -= BASE_XBOW_PORT; - if ((link < 0) || (link >= MAX_XBOW_PORTS)) - return -1; - - if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK)) - return -1; - - if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS)) - return -1; - - s = mutex_spinlock(&xbow_soft->xbow_perf_lock); - - if ((xbow_perf + counter)->xp_mode && mode) { - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - return -1; - } - for (i = 0; i < XBOW_PERF_COUNTERS; i++) { - if (i == counter) - continue; - if (((xbow_perf + i)->xp_link == link) && - ((xbow_perf + i)->xp_mode)) { - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - return -1; - } - } - xbow_perf += counter; - - xbow_perf->xp_curlink = xbow_perf->xp_link = link; - xbow_perf->xp_curmode = xbow_perf->xp_mode = mode; - - xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control; - xbow_link_ctrl.xb_linkcontrol.perf_mode = mode; - xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword; - - perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg; - perf_reg.xb_perf.link_select = link; - *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val; - xbow_perf->xp_current = perf_reg.xb_perf.count; - - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - return 0; -} - -xbow_link_status_t * -xbow_get_llp_status(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; - - return xbow_llp_status; -} - -void -xbow_update_llp_status(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; - xbow_t *xbow; - xbwX_stat_t lnk_sts; - xbow_aux_link_status_t aux_sts; - int link; - devfs_handle_t xwidget_vhdl; - char *xwidget_name; - - xbow = (xbow_t *) xbow_soft->base; - for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) { - /* Get the widget name corresponding the current link. - * Note : 0 <= link < MAX_XBOW_PORTS(8). - * BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10) - */ - xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT); - xwidget_name = xwidget_name_get(xwidget_vhdl); - aux_sts.aux_linkstatus - = xbow->xb_link_raw[link].link_aux_status; - lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr; - - if (lnk_sts.link_alive == 0) - continue; - - xbow_llp_status->rx_err_count += - aux_sts.xb_aux_linkstatus.rx_err_cnt; - - xbow_llp_status->tx_retry_count += - aux_sts.xb_aux_linkstatus.tx_retry_cnt; - - if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) { -#ifdef LATER - printk(KERN_WARNING "link %d[%s]: bad status 0x%x\n", - link, xwidget_name, lnk_sts.linkstatus); -#endif - } - } -} - -int -xbow_disable_llp_monitor(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - int port; - - for (port = 0; port < MAX_XBOW_PORTS; port++) { - xbow_soft->xbow_link_status[port].rx_err_count = 0; - xbow_soft->xbow_link_status[port].tx_retry_count = 0; - } - - xbow_soft->link_monitor = 0; - return 0; -} - -int -xbow_enable_llp_monitor(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - - xbow_soft->link_monitor = 1; - return 0; -} - - -int -xbow_reset_link(devfs_handle_t xconn_vhdl) -{ - xwidget_info_t widget_info; - xwidgetnum_t port; - xbow_t *xbow; - xbowreg_t ctrl; - xbwX_stat_t stat; - unsigned itick; - unsigned dtick; - static int ticks_per_ms = 0; - - if (!ticks_per_ms) { - itick = get_timestamp(); - us_delay(1000); - ticks_per_ms = get_timestamp() - itick; - } - widget_info = xwidget_info_get(xconn_vhdl); - port = xwidget_info_id_get(widget_info); - -#ifdef XBOW_K1PTR /* defined if we only have one xbow ... */ - xbow = XBOW_K1PTR; -#else - { - devfs_handle_t xbow_vhdl; - xbow_soft_t xbow_soft; - - hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl); - xbow_soft = xbow_soft_get(xbow_vhdl); - xbow = xbow_soft->base; - } -#endif - - /* - * This requires three PIOs (reset the link, check for the - * reset, restore the control register for the link) plus - * 10us to wait for the reset. We allow up to 1ms for the - * widget to come out of reset before giving up and - * returning a failure. - */ - ctrl = xbow->xb_link(port).link_control; - xbow->xb_link(port).link_reset = 0; - itick = get_timestamp(); - while (1) { - stat.linkstatus = xbow->xb_link(port).link_status; - if (stat.link_alive) - break; - dtick = get_timestamp() - itick; - if (dtick > ticks_per_ms) { - return -1; /* never came out of reset */ - } - DELAY(2); /* don't beat on link_status */ - } - xbow->xb_link(port).link_control = ctrl; - return 0; -} - -/* - * Dump xbow registers. - * input parameter is either a pointer to - * the xbow chip or the vertex handle for - * an xbow vertex. - */ -void -idbg_xbowregs(int64_t regs) -{ - xbow_t *xbow; - int i; - xb_linkregs_t *link; - - xbow = (xbow_t *) regs; - -#ifdef LATER - qprintf("Printing xbow registers starting at 0x%x\n", xbow); - qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n", - xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper, - xbow->xb_wid_err_lower, xbow->xb_wid_control, - xbow->xb_wid_req_timeout); - qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n", - xbow->xb_wid_int_upper, xbow->xb_wid_int_lower, - xbow->xb_wid_err_cmdword, xbow->xb_wid_llp, - xbow->xb_wid_arb_reload); -#endif - - for (i = 8; i <= 0xf; i++) { - link = &xbow->xb_link(i); -#ifdef LATER - qprintf("Link %d registers\n", i); - qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n", - link->link_control, link->link_status, - link->link_arb_upper, link->link_arb_lower, - link->link_aux_status); -#endif - } -} - - -#define XBOW_ARB_RELOAD_TICKS 25 - /* granularity: 4 MB/s, max: 124 MB/s */ -#define GRANULARITY ((100 * 1000000) / XBOW_ARB_RELOAD_TICKS) - -#define XBOW_BYTES_TO_GBR(BYTES_per_s) (int) (BYTES_per_s / GRANULARITY) - -#define XBOW_GBR_TO_BYTES(cnt) (bandwidth_t) ((cnt) * GRANULARITY) - -#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec) \ - ((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr) - -#define XBOW_ARB_GBR_MAX 31 - -#define ABS(x) ((x > 0) ? (x) : (-1 * x)) - /* absolute value */ - -int -xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec) -{ - int gbr_granted; - int new_total_gbr; - int change_gbr; - bandwidth_t new_total_bw; - -#ifdef GRIO_DEBUG - printk("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n", - old_bytes_per_sec, bytes_per_sec); -#endif /* GRIO_DEBUG */ - - gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)), - old_bytes_per_sec); - new_total_bw = old_bytes_per_sec + bytes_per_sec; - new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)), - new_total_bw); - - change_gbr = new_total_gbr - gbr_granted; - -#ifdef GRIO_DEBUG - printk("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n", - gbr_granted, new_total_gbr, change_gbr); -#endif /* GRIO_DEBUG */ - - return (change_gbr); -} - -/* Conversion from GBR to bytes */ -bandwidth_t -xbow_gbr_to_bytes(int gbr) -{ - return (XBOW_GBR_TO_BYTES(gbr)); -} - -/* Given the vhdl for the desired xbow, the src and dest. widget ids - * and the req_bw value, this xbow driver entry point accesses the - * xbow registers and allocates the desired bandwidth if available. - * - * If bandwidth allocation is successful, return success else return failure. - */ -int -xbow_prio_bw_alloc(devfs_handle_t vhdl, - xwidgetnum_t src_wid, - xwidgetnum_t dest_wid, - unsigned long long old_alloc_bw, - unsigned long long req_bw) -{ - xbow_soft_t soft = xbow_soft_get(vhdl); - volatile xbowreg_t *xreg; - xbowreg_t mask; - unsigned long s; - int error = 0; - bandwidth_t old_bw_BYTES, req_bw_BYTES; - xbowreg_t old_xreg; - int old_bw_GBR, req_bw_GBR, new_bw_GBR; - -#ifdef GRIO_DEBUG - printk("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n", - (int) vhdl, (int) src_wid, (int) dest_wid, req_bw); -#endif - - ASSERT(XBOW_WIDGET_IS_VALID(src_wid)); - ASSERT(XBOW_WIDGET_IS_VALID(dest_wid)); - - s = mutex_spinlock(&soft->xbow_bw_alloc_lock); - - /* Get pointer to the correct register */ - xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid); - - /* Get mask for GBR count value */ - mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid); - - req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw); - req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR))) - : xbow_gbr_to_bytes(req_bw_GBR); - -#ifdef GRIO_DEBUG - printk("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n", - req_bw, req_bw_BYTES, req_bw_GBR); -#endif /* GRIO_DEBUG */ - - old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS]; - old_xreg = *xreg; - old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid)); - -#ifdef GRIO_DEBUG - ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR); - - printk("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR); - - printk("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n", - req_bw_BYTES, old_bw_BYTES, - soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]); - -#endif /* GRIO_DEBUG */ - - /* Accept the request only if we don't exceed the destination - * port HIWATER_MARK *AND* the max. link GBR arbitration count - */ - if (((old_bw_BYTES + req_bw_BYTES) <= - soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) && - (req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) { - - new_bw_GBR = (old_bw_GBR + req_bw_GBR); - - /* Set this in the xbow link register */ - *xreg = (old_xreg & ~mask) | \ - (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask); - - soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] = - xbow_gbr_to_bytes(new_bw_GBR); - } else { - error = 1; - } - - mutex_spinunlock(&soft->xbow_bw_alloc_lock, s); - - return (error); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn1/xtalk.c linux-2.4.22/arch/ia64/sn/io/sn1/xtalk.c --- linux-2.4.21/arch/ia64/sn/io/sn1/xtalk.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn1/xtalk.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1003 +0,0 @@ -/* $Id: xtalk.c,v 1.2 2002/11/21 17:51:57 jh Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Implement crosstalk provider operations. The xtalk* layer provides a - * platform-independent interface for crosstalk devices. This layer - * switches among the possible implementations of a crosstalk adapter. - * - * On platforms with only one possible xtalk provider, macros can be - * set up at the top that cause the table lookups and indirections to - * completely disappear. - */ - -#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DEL(ptr) (kfree(ptr)) - -char widget_info_fingerprint[] = "widget_info"; - -cdl_p xtalk_registry = NULL; - -#define DEV_FUNC(dev,func) hub_##func -#define CAST_PIOMAP(x) ((hub_piomap_t)(x)) -#define CAST_DMAMAP(x) ((hub_dmamap_t)(x)) -#define CAST_INTR(x) ((hub_intr_t)(x)) - -/* ===================================================================== - * Function Table of Contents - */ -xtalk_piomap_t xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned); -void xtalk_piomap_free(xtalk_piomap_t); -caddr_t xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t); -void xtalk_piomap_done(xtalk_piomap_t); -caddr_t xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned); -caddr_t xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned); -void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *); -caddr_t xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); -static caddr_t null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); -xtalk_dmamap_t xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); -void xtalk_dmamap_free(xtalk_dmamap_t); -iopaddr_t xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t); -alenlist_t xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned); -void xtalk_dmamap_done(xtalk_dmamap_t); -iopaddr_t xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); -void xtalk_dmamap_drain(xtalk_dmamap_t); -void xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t); -void xtalk_dmalist_drain(devfs_handle_t, alenlist_t); -xtalk_intr_t xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t); -xtalk_intr_t xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t); -void xtalk_intr_free(xtalk_intr_t); -int xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *); -void xtalk_intr_disconnect(xtalk_intr_t); -devfs_handle_t xtalk_intr_cpu_get(xtalk_intr_t); -int xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *); -int xtalk_error_devenable(devfs_handle_t, int, int); -void xtalk_provider_startup(devfs_handle_t); -void xtalk_provider_shutdown(devfs_handle_t); -devfs_handle_t xtalk_intr_dev_get(xtalk_intr_t); -xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t); -xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t); -iopaddr_t xtalk_intr_addr_get(struct xtalk_intr_s *); -void *xtalk_intr_sfarg_get(xtalk_intr_t); -devfs_handle_t xtalk_pio_dev_get(xtalk_piomap_t); -xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t); -iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t); -ulong xtalk_pio_mapsz_get(xtalk_piomap_t); -caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t); -devfs_handle_t xtalk_dma_dev_get(xtalk_dmamap_t); -xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t); -xwidget_info_t xwidget_info_chk(devfs_handle_t); -xwidget_info_t xwidget_info_get(devfs_handle_t); -void xwidget_info_set(devfs_handle_t, xwidget_info_t); -devfs_handle_t xwidget_info_dev_get(xwidget_info_t); -xwidgetnum_t xwidget_info_id_get(xwidget_info_t); -devfs_handle_t xwidget_info_master_get(xwidget_info_t); -xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t); -xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t); -xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t); -char *xwidget_info_name_get(xwidget_info_t); -void xtalk_init(void); -void xtalk_provider_register(devfs_handle_t, xtalk_provider_t *); -void xtalk_provider_unregister(devfs_handle_t); -xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t); -int xwidget_driver_register(xwidget_part_num_t, - xwidget_mfg_num_t, - char *, unsigned); -void xwidget_driver_unregister(char *); -int xwidget_register(xwidget_hwid_t, devfs_handle_t, - xwidgetnum_t, devfs_handle_t, - xwidgetnum_t, async_attach_t); -int xwidget_unregister(devfs_handle_t); -void xwidget_reset(devfs_handle_t); -char *xwidget_name_get(devfs_handle_t); -#if !defined(DEV_FUNC) -/* - * There is more than one possible provider - * for this platform. We need to examine the - * master vertex of the current vertex for - * a provider function structure, and indirect - * through the appropriately named member. - */ -#define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func -#define CAST_PIOMAP(x) ((xtalk_piomap_t)(x)) -#define CAST_DMAMAP(x) ((xtalk_dmamap_t)(x)) -#define CAST_INTR(x) ((xtalk_intr_t)(x)) - -static xtalk_provider_t * -xwidget_to_provider_fns(devfs_handle_t xconn) -{ - xwidget_info_t widget_info; - xtalk_provider_t *provider_fns; - - widget_info = xwidget_info_get(xconn); - ASSERT(widget_info != NULL); - - provider_fns = xwidget_info_pops_get(widget_info); - ASSERT(provider_fns != NULL); - - return (provider_fns); -} -#endif - -/* - * Many functions are not passed their vertex - * information directly; rather, they must - * dive through a resource map. These macros - * are available to coordinate this detail. - */ -#define PIOMAP_FUNC(map,func) DEV_FUNC(map->xp_dev,func) -#define DMAMAP_FUNC(map,func) DEV_FUNC(map->xd_dev,func) -#define INTR_FUNC(intr,func) DEV_FUNC(intr_hdl->xi_dev,func) - -/* ===================================================================== - * PIO MANAGEMENT - * - * For mapping system virtual address space to - * xtalk space on a specified widget - */ - -xtalk_piomap_t -xtalk_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ - device_desc_t dev_desc, /* device descriptor */ - iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ - size_t byte_count, - size_t byte_count_max, /* maximum size of a mapping */ - unsigned flags) -{ /* defined in sys/pio.h */ - return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc) - (dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags); -} - - -void -xtalk_piomap_free(xtalk_piomap_t xtalk_piomap) -{ - PIOMAP_FUNC(xtalk_piomap, piomap_free) - (CAST_PIOMAP(xtalk_piomap)); -} - - -caddr_t -xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap, /* mapping resources */ - iopaddr_t xtalk_addr, /* map for this xtalk address */ - size_t byte_count) -{ /* map this many bytes */ - return PIOMAP_FUNC(xtalk_piomap, piomap_addr) - (CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count); -} - - -void -xtalk_piomap_done(xtalk_piomap_t xtalk_piomap) -{ - PIOMAP_FUNC(xtalk_piomap, piomap_done) - (CAST_PIOMAP(xtalk_piomap)); -} - - -caddr_t -xtalk_piotrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - iopaddr_t xtalk_addr, /* Crosstalk address */ - size_t byte_count, /* map this many bytes */ - unsigned flags) -{ /* (currently unused) */ - return DEV_FUNC(dev, piotrans_addr) - (dev, dev_desc, xtalk_addr, byte_count, flags); -} - -caddr_t -xtalk_pio_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - iopaddr_t addr, /* starting address (or offset in window) */ - size_t byte_count, /* map this many bytes */ - xtalk_piomap_t *mapp, /* where to return the map pointer */ - unsigned flags) -{ /* PIO flags */ - xtalk_piomap_t map = 0; - caddr_t res; - - if (mapp) - *mapp = 0; /* record "no map used" */ - - res = xtalk_piotrans_addr - (dev, dev_desc, addr, byte_count, flags); - if (res) - return res; /* xtalk_piotrans worked */ - - map = xtalk_piomap_alloc - (dev, dev_desc, addr, byte_count, byte_count, flags); - if (!map) - return res; /* xtalk_piomap_alloc failed */ - - res = xtalk_piomap_addr - (map, addr, byte_count); - if (!res) { - xtalk_piomap_free(map); - return res; /* xtalk_piomap_addr failed */ - } - if (mapp) - *mapp = map; /* pass back map used */ - - return res; /* xtalk_piomap_addr succeeded */ -} - -/* ===================================================================== - * EARLY PIOTRANS SUPPORT - * - * There are places where drivers (mgras, for instance) - * need to get PIO translations before the infrastructure - * is extended to them (setting up textports, for - * instance). These drivers should call - * xtalk_early_piotrans_addr with their xtalk ID - * information, a sequence number (so we can use the second - * mgras for instance), and the usual piotrans parameters. - * - * Machine specific code should provide an implementation - * of early_piotrans_addr, and present a pointer to this - * function to xtalk_set_early_piotrans_addr so it can be - * used by clients without the clients having to know what - * platform or what xtalk provider is in use. - */ - -static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr; - -xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr; - -/* xtalk_set_early_piotrans_addr: - * specify the early_piotrans_addr implementation function. - */ -void -xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl) -{ - impl_early_piotrans_addr = impl; -} - -/* xtalk_early_piotrans_addr: - * figure out a PIO address for the "nth" crosstalk widget that - * matches the specified part and mfgr number. Returns NULL if - * there is no such widget, or if the requested mapping can not - * be constructed. - * Limitations on which crosstalk slots (and busses) are - * checked, and definitions of the ordering of the search across - * the crosstalk slots, are defined by the platform. - */ -caddr_t -xtalk_early_piotrans_addr(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - int which, - iopaddr_t xtalk_addr, - size_t byte_count, - unsigned flags) -{ - return impl_early_piotrans_addr - (part_num, mfg_num, which, xtalk_addr, byte_count, flags); -} - -/* null_xtalk_early_piotrans_addr: - * used as the early_piotrans_addr implementation until and - * unless a real implementation is provided. In DEBUG kernels, - * we want to know who is calling before the implementation is - * registered; in non-DEBUG kernels, return NULL representing - * lack of mapping support. - */ -/*ARGSUSED */ -static caddr_t -null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - int which, - iopaddr_t xtalk_addr, - size_t byte_count, - unsigned flags) -{ -#if DEBUG - PRINT_PANIC("null_xtalk_early_piotrans_addr"); -#endif - return NULL; -} - -/* ===================================================================== - * DMA MANAGEMENT - * - * For mapping from crosstalk space to system - * physical space. - */ - -xtalk_dmamap_t -xtalk_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ - device_desc_t dev_desc, /* device descriptor */ - size_t byte_count_max, /* max size of a mapping */ - unsigned flags) -{ /* defined in dma.h */ - return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc) - (dev, dev_desc, byte_count_max, flags); -} - - -void -xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap) -{ - DMAMAP_FUNC(xtalk_dmamap, dmamap_free) - (CAST_DMAMAP(xtalk_dmamap)); -} - - -iopaddr_t -xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */ - paddr_t paddr, /* map for this address */ - size_t byte_count) -{ /* map this many bytes */ - return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr) - (CAST_DMAMAP(xtalk_dmamap), paddr, byte_count); -} - - -alenlist_t -xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */ - alenlist_t alenlist, /* map this Address/Length List */ - unsigned flags) -{ - return DMAMAP_FUNC(xtalk_dmamap, dmamap_list) - (CAST_DMAMAP(xtalk_dmamap), alenlist, flags); -} - - -void -xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap) -{ - DMAMAP_FUNC(xtalk_dmamap, dmamap_done) - (CAST_DMAMAP(xtalk_dmamap)); -} - - -iopaddr_t -xtalk_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_addr) - (dev, dev_desc, paddr, byte_count, flags); -} - - -alenlist_t -xtalk_dmatrans_list(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - alenlist_t palenlist, /* system address/length list */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_list) - (dev, dev_desc, palenlist, flags); -} - -void -xtalk_dmamap_drain(xtalk_dmamap_t map) -{ - DMAMAP_FUNC(map, dmamap_drain) - (CAST_DMAMAP(map)); -} - -void -xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) -{ - DEV_FUNC(dev, dmaaddr_drain) - (dev, addr, size); -} - -void -xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list) -{ - DEV_FUNC(dev, dmalist_drain) - (dev, list); -} - -/* ===================================================================== - * INTERRUPT MANAGEMENT - * - * Allow crosstalk devices to establish interrupts - */ - -/* - * Allocate resources required for an interrupt as specified in intr_desc. - * Return resource handle in intr_hdl. - */ -xtalk_intr_t -xtalk_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) -{ /* owner of this interrupt */ - return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc) - (dev, dev_desc, owner_dev); -} - -/* - * Allocate resources required for an interrupt as specified in dev_desc. - * Unconditionally setup resources to be non-threaded. - * Return resource handle in intr_hdl. - */ -xtalk_intr_t -xtalk_intr_alloc_nothd(devfs_handle_t dev, /* which Crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) /* owner of this interrupt */ -{ - return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd) - (dev, dev_desc, owner_dev); -} - -/* - * Free resources consumed by intr_alloc. - */ -void -xtalk_intr_free(xtalk_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_free) - (CAST_INTR(intr_hdl)); -} - - -/* - * Associate resources allocated with a previous xtalk_intr_alloc call with the - * described handler, arg, name, etc. - * - * Returns 0 on success, returns <0 on failure. - */ -int -xtalk_intr_connect(xtalk_intr_t intr_hdl, /* xtalk intr resource handle */ - xtalk_intr_setfunc_t setfunc, /* func to set intr hw */ - void *setfunc_arg) /* arg to setfunc */ -{ - return INTR_FUNC(intr_hdl, intr_connect) - (CAST_INTR(intr_hdl), setfunc, setfunc_arg); -} - - -/* - * Disassociate handler with the specified interrupt. - */ -void -xtalk_intr_disconnect(xtalk_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_disconnect) - (CAST_INTR(intr_hdl)); -} - - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. - */ -devfs_handle_t -xtalk_intr_cpu_get(xtalk_intr_t intr_hdl) -{ - return INTR_FUNC(intr_hdl, intr_cpu_get) - (CAST_INTR(intr_hdl)); -} - - -/* ===================================================================== - * CONFIGURATION MANAGEMENT - */ - -/* - * Startup a crosstalk provider - */ -void -xtalk_provider_startup(devfs_handle_t xtalk_provider) -{ - DEV_FUNC(xtalk_provider, provider_startup) - (xtalk_provider); -} - - -/* - * Shutdown a crosstalk provider - */ -void -xtalk_provider_shutdown(devfs_handle_t xtalk_provider) -{ - DEV_FUNC(xtalk_provider, provider_shutdown) - (xtalk_provider); -} - -/* - * Enable a device on a xtalk widget - */ -void -xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum) -{ - DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum); -} - -/* - * Shutdown a device on a xtalk widget - */ -void -xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum) -{ - DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum); -} - -int -xtalk_dma_enabled(devfs_handle_t xconn_vhdl) -{ - return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl); -} -/* - * Generic crosstalk functions, for use with all crosstalk providers - * and all crosstalk devices. - */ - -/****** Generic crosstalk interrupt interfaces ******/ -devfs_handle_t -xtalk_intr_dev_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_dev); -} - -xwidgetnum_t -xtalk_intr_target_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_target); -} - -xtalk_intr_vector_t -xtalk_intr_vector_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_vector); -} - -iopaddr_t -xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr) -{ - return (xtalk_intr->xi_addr); -} - -void * -xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_sfarg); -} - -/****** Generic crosstalk pio interfaces ******/ -devfs_handle_t -xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_dev); -} - -xwidgetnum_t -xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_target); -} - -iopaddr_t -xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_xtalk_addr); -} - -ulong -xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_mapsz); -} - -caddr_t -xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_kvaddr); -} - - -/****** Generic crosstalk dma interfaces ******/ -devfs_handle_t -xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap) -{ - return (xtalk_dmamap->xd_dev); -} - -xwidgetnum_t -xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap) -{ - return (xtalk_dmamap->xd_target); -} - - -/****** Generic crosstalk widget information interfaces ******/ - -/* xwidget_info_chk: - * check to see if this vertex is a widget; - * if so, return its widget_info (if any). - * if not, return NULL. - */ -xwidget_info_t -xwidget_info_chk(devfs_handle_t xwidget) -{ - arbitrary_info_t ainfo = 0; - - hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo); - return (xwidget_info_t) ainfo; -} - - -xwidget_info_t -xwidget_info_get(devfs_handle_t xwidget) -{ - xwidget_info_t widget_info; - - widget_info = (xwidget_info_t) - hwgraph_fastinfo_get(xwidget); - -#ifdef LATER - if ((widget_info != NULL) && - (widget_info->w_fingerprint != widget_info_fingerprint)) -#ifdef SUPPORT_PRINTING_V_FORMAT - PRINT_PANIC("%v bad xwidget_info", xwidget); -#else - PRINT_PANIC("%x bad xwidget_info", xwidget); -#endif -#endif /* LATER */ - - return (widget_info); -} - -void -xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info) -{ - if (widget_info != NULL) - widget_info->w_fingerprint = widget_info_fingerprint; - - hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info); - - /* Also, mark this vertex as an xwidget, - * and use the widget_info, so xwidget_info_chk - * can work (and be fairly efficient). - */ - hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET, - (arbitrary_info_t) widget_info); -} - -devfs_handle_t -xwidget_info_dev_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_vertex); -} - -xwidgetnum_t -xwidget_info_id_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_id); -} - - -devfs_handle_t -xwidget_info_master_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_master); -} - -xwidgetnum_t -xwidget_info_masterid_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_masterid); -} - -xwidget_part_num_t -xwidget_info_part_num_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_hwid.part_num); -} - -xwidget_mfg_num_t -xwidget_info_mfg_num_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_hwid.mfg_num); -} -/* Extract the widget name from the widget information - * for the xtalk widget. - */ -char * -xwidget_info_name_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget info"); - return(xwidget_info->w_name); -} -/****** Generic crosstalk initialization interfaces ******/ - -/* - * One-time initialization needed for systems that support crosstalk. - */ -void -xtalk_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("xtalk_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (xtalk_registry == NULL) { - cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr"); - if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(xtalk_registry != NULL); -} - -/* - * Associate a set of xtalk_provider functions with a vertex. - */ -void -xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns) -{ - hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns); -} - -/* - * Disassociate a set of xtalk_provider functions with a vertex. - */ -void -xtalk_provider_unregister(devfs_handle_t provider) -{ - hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL); -} - -/* - * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk - * provider. - */ -xtalk_provider_t * -xtalk_provider_fns_get(devfs_handle_t provider) -{ - return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider)); -} - -/* - * Announce a driver for a particular crosstalk part. - * Returns 0 on success or -1 on failure. Failure occurs if the - * specified hardware already has a driver. - */ -/*ARGSUSED4 */ -int -xwidget_driver_register(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - char *driver_prefix, - unsigned flags) -{ - /* a driver's init routine could call - * xwidget_driver_register before the - * system calls xtalk_init; so, we - * make the call here. - */ - if (xtalk_registry == NULL) - xtalk_init(); - - return cdl_add_driver(xtalk_registry, - part_num, mfg_num, - driver_prefix, flags, NULL); -} - -/* - * Inform xtalk infrastructure that a driver is no longer available for - * handling any widgets. - */ -void -xwidget_driver_unregister(char *driver_prefix) -{ - /* before a driver calls unregister, - * it must have called registger; so we - * can assume we have a registry here. - */ - ASSERT(xtalk_registry != NULL); - - cdl_del_driver(xtalk_registry, driver_prefix, NULL); -} - -/* - * Call some function with each vertex that - * might be one of this driver's attach points. - */ -void -xtalk_iterate(char *driver_prefix, - xtalk_iter_f *func) -{ - ASSERT(xtalk_registry != NULL); - - cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func); -} - -/* - * xwidget_register: - * Register a xtalk device (xwidget) by doing the following. - * -allocate and initialize xwidget_info data - * -allocate a hwgraph vertex with name based on widget number (id) - * -look up the widget's initialization function and call it, - * or remember the vertex for later initialization. - * - */ -int -xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ - devfs_handle_t widget, /* widget to initialize */ - xwidgetnum_t id, /* widget's target id (0..f) */ - devfs_handle_t master, /* widget's master vertex */ - xwidgetnum_t targetid, /* master's target id (9/a) */ - async_attach_t aa) -{ - xwidget_info_t widget_info; - char *s,devnm[MAXDEVNAME]; - - /* Allocate widget_info and associate it with widget vertex */ - NEW(widget_info); - - /* Initialize widget_info */ - widget_info->w_vertex = widget; - widget_info->w_id = id; - widget_info->w_master = master; - widget_info->w_masterid = targetid; - widget_info->w_hwid = *hwid; /* structure copy */ - widget_info->w_efunc = 0; - widget_info->w_einfo = 0; - /* - * get the name of this xwidget vertex and keep the info. - * This is needed during errors and interupts, but as - * long as we have it, we can use it elsewhere. - */ - s = dev_to_name(widget,devnm,MAXDEVNAME); - widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL); - strcpy(widget_info->w_name,s); - - xwidget_info_set(widget, widget_info); - - device_master_set(widget, master); - - /* All the driver init routines (including - * xtalk_init) are called before we get into - * attaching devices, so we can assume we - * have a registry here. - */ - ASSERT(xtalk_registry != NULL); - - /* - * Add pointer to async attach info -- tear down will be done when - * the particular descendant is done with the info. - */ - if (aa) - async_attach_add_info(widget, aa); - - return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, - widget, 0); -} - -/* - * xwidget_unregister : - * Unregister the xtalk device and detach all its hwgraph namespace. - */ -int -xwidget_unregister(devfs_handle_t widget) -{ - xwidget_info_t widget_info; - xwidget_hwid_t hwid; - - /* Make sure that we have valid widget information initialized */ - if (!(widget_info = xwidget_info_get(widget))) - return(1); - - /* Remove the inventory information associated - * with the widget. - */ - hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1); - - hwid = &(widget_info->w_hwid); - - cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, - widget, 0); - - /* Clean out the xwidget information */ - (void)kfree(widget_info->w_name); - BZERO((void *)widget_info, sizeof(widget_info)); - DEL(widget_info); - - return(0); -} - -/* - * Issue a link reset to a widget. - */ -void -xwidget_reset(devfs_handle_t xwidget) -{ - xswitch_reset_link(xwidget); - -} - - -void -xwidget_gfx_reset(devfs_handle_t xwidget) -{ - xwidget_info_t info; - - xswitch_reset_link(xwidget); - info = xwidget_info_get(xwidget); -#ifdef LATER - ASSERT_ALWAYS(info != NULL); -#endif - - /* - * Enable this for other architectures once we add widget_reset to the - * xtalk provider interface. - */ - DEV_FUNC(xtalk_provider, widget_reset) - (xwidget_info_master_get(info), xwidget_info_id_get(info)); -} - -#define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */ - -/* Get the canonical hwgraph name of xtalk widget */ -char * -xwidget_name_get(devfs_handle_t xwidget_vhdl) -{ - xwidget_info_t info; - - /* If we have a bogus widget handle then return - * a default anonymous widget name. - */ - if (xwidget_vhdl == GRAPH_VERTEX_NONE) - return(ANON_XWIDGET_NAME); - /* Read the widget name stored in the widget info - * for the widget setup during widget initialization. - */ - info = xwidget_info_get(xwidget_vhdl); - ASSERT(info != NULL); - return(xwidget_info_name_get(info)); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/Makefile linux-2.4.22/arch/ia64/sn/io/sn2/Makefile --- linux-2.4.21/arch/ia64/sn/io/sn2/Makefile 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 2002 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. # # Makefile for the sn2 io routines. @@ -15,13 +15,11 @@ obj-y += ml_SN_intr.o shub_intr.o shuberror.o shub.o \ bte_error.o pcibr/pcibr.o pic.o geo_op.o \ - l1.o l1_command.o klconflib.o klgraph.o \ + l1_command.o klconflib.o klgraph.o \ ml_SN_init.o ml_iograph.o module.o pciio.o \ - xbow.o xtalk.o \ - pci_bus_cvlink.o sgi_io_init.o shubio.o + xbow.o xtalk.o shubio.o +obj-$(CONFIG_KDB) += kdba_io.o subdir-y += pcibr -obj-$(CONFIG_SHUB_1_0_SPECIFIC) += efi-rtc.o - include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/bte_error.c linux-2.4.22/arch/ia64/sn/io/sn2/bte_error.c --- linux-2.4.21/arch/ia64/sn/io/sn2/bte_error.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/bte_error.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,10 +1,35 @@ -/* $Id: bte_error.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ +/* * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. * - * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/NoticeExplan */ @@ -29,121 +54,208 @@ #include #include -/************************************************************************ - * * - * BTE ERROR RECOVERY * - * * - * Given a BTE error, the node causing the error must do the following: * - * a) Clear all crbs relating to that BTE * - * 1) Read CRBA value for crb in question * - * 2) Mark CRB as VALID, store local physical * - * address known to be good in the address field * - * (bte_notification_targ is a known good local * - * address). * - * 3) Write CRBA * - * 4) Using ICCR, FLUSH the CRB, and wait for it to * - * complete. * - * ... BTE BUSY bit should now be clear (or at least * - * should be after ALL CRBs associated with the * - * transfer are complete. * - * * - * b) Re-enable BTE * - * 1) Write IMEM with BTE Enable + XXX bits - * 2) Write IECLR with BTE clear bits - * 3) Clear IIDSR INT_SENT bits. - * * - ************************************************************************/ - -/* - * >>> bte_crb_error_handler needs to be broken into two parts. The - * first should cleanup the CRB. The second should wait until all bte - * related CRB's are complete and then do the error reset. + +/* + * Bte error handling is done in two parts. The first captures + * any crb related errors. Since there can be multiple crbs per + * interface and multiple interfaces active, we need to wait until + * all active crbs are completed. This is the first job of the + * second part error handler. When all bte related CRBs are cleanly + * completed, it resets the interfaces and gets them ready for new + * transfers to be queued. */ -void -bte_crb_error_handler(devfs_handle_t hub_v, int btenum, - int crbnum, ioerror_t *ioe, int bteop) + + +void bte_error_handler(unsigned long); + + /* - * Function: bte_crb_error_handler - * Purpose: Process a CRB for a specific HUB/BTE - * Parameters: hub_v - vertex of hub in HW graph - * btenum - bte number on hub (0 == a, 1 == b) - * crbnum - crb number being processed - * Notes: - * This routine assumes serialization at a higher level. A CRB - * should not be processed more than once. The error recovery - * follows the following sequence - if you change this, be real - * sure about what you are doing. - * + * First part error handler. This is called whenever any error CRB interrupt + * is generated by the II. */ +void +bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, + int crbnum, ioerror_t * ioe, int bteop) { - hubinfo_t hinfo; - icrba_t crba; - icrbb_t crbb; - nasid_t n; - hubreg_t iidsr, imem, ieclr; + hubinfo_t hinfo; + struct bteinfo_s *bte; + hubinfo_get(hub_v, &hinfo); + bte = &hinfo->h_nodepda->bte_if[btenum]; + + /* + * The caller has already figured out the error type, we save that + * in the bte handle structure for the thread excercising the + * interface to consume. + */ + switch (ioe->ie_errortype) { + case IIO_ICRB_ECODE_PERR: + bte->bh_error = BTEFAIL_POISON; + break; + case IIO_ICRB_ECODE_WERR: + bte->bh_error = BTEFAIL_PROT; + break; + case IIO_ICRB_ECODE_AERR: + bte->bh_error = BTEFAIL_ACCESS; + break; + case IIO_ICRB_ECODE_TOUT: + bte->bh_error = BTEFAIL_TOUT; + break; + case IIO_ICRB_ECODE_XTERR: + bte->bh_error = BTEFAIL_XTERR; + break; + case IIO_ICRB_ECODE_DERR: + bte->bh_error = BTEFAIL_DIR; + break; + case IIO_ICRB_ECODE_PWERR: + case IIO_ICRB_ECODE_PRERR: + /* NO BREAK */ + default: + bte->bh_error = BTEFAIL_ERROR; + } + + bte->bte_error_count++; + BTE_PRINTK(("Got an error on cnode %d bte %d\n", + bte->bte_cnode, bte->bte_num)); + bte_error_handler((unsigned long) hinfo->h_nodepda); +} - n = hinfo->h_nasid; - +/* + * Second part error handler. Wait until all BTE related CRBs are completed + * and then reset the interfaces. + */ +void +bte_error_handler(unsigned long _nodepda) +{ + struct nodepda_s *err_nodepda = (struct nodepda_s *) _nodepda; + spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock; + struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer; + nasid_t nasid; + int i; + int valid_crbs; + unsigned long irq_flags; + volatile u64 *notify; + bte_result_t bh_error; + ii_imem_u_t imem; /* II IMEM Register */ + ii_icrb0_d_u_t icrbd; /* II CRB Register D */ + ii_ibcr_u_t ibcr; + ii_icmr_u_t icmr; + + + BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda, + smp_processor_id())); + + spin_lock_irqsave(recovery_lock, irq_flags); + + if ((err_nodepda->bte_if[0].bh_error == BTE_SUCCESS) && + (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) { + BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda, + smp_processor_id())); + spin_unlock_irqrestore(recovery_lock, irq_flags); + return; + } /* - * The following 10 lines (or so) are adapted from IRIXs - * bte_crb_error function. No clear documentation tells - * why the crb needs to complete normally in order for - * the BTE to resume normal operations. This first step - * appears vital! + * Lock all interfaces on this node to prevent new transfers + * from being queued. */ + for (i = 0; i < BTES_PER_NODE; i++) { + if (err_nodepda->bte_if[i].cleanup_active) { + continue; + } + spin_lock(&err_nodepda->bte_if[i].spinlock); + BTE_PRINTK(("eh:%p:%d locked %d\n", err_nodepda, + smp_processor_id(), i)); + err_nodepda->bte_if[i].cleanup_active = 1; + } + + /* Determine information about our hub */ + nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode); + /* - * Zero error and error code to prevent error_dump complaining - * about these CRBs. Copy the CRB to the notification line. - * The crb address is in shub format (physical address shifted - * right by cacheline size). + * A BTE transfer can use multiple CRBs. We need to make sure + * that all the BTE CRBs are complete (or timed out) before + * attempting to clean up the error. Resetting the BTE while + * there are still BTE CRBs active will hang the BTE. + * We should look at all the CRBs to see if they are allocated + * to the BTE and see if they are still active. When none + * are active, we can continue with the cleanup. + * + * We also want to make sure that the local NI port is up. + * When a router resets the NI port can go down, while it + * goes through the LLP handshake, but then comes back up. */ - crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum)); - crbb.b_error=0; - crbb.b_ecode=0; - REMOTE_HUB_S(n, IIO_ICRB_B(crbnum), crbb.ii_icrb0_b_regval); - - crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum)); - crba.a_addr = TO_PHYS((u64)&nodepda->bte_if[btenum].notify) >> 3; - crba.a_valid = 1; - REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval); - - REMOTE_HUB_S(n, IIO_ICCR, - IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum); - - while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING) - ; - - - /* Terminate the BTE. */ - /* >>> The other bte transfer will need to be restarted. */ - HUB_L((shubreg_t *)((nodepda->bte_if[btenum].bte_base_addr + - IIO_IBCT0 - IIO_IBLS0))); - - imem = REMOTE_HUB_L(n, IIO_IMEM); - ieclr = REMOTE_HUB_L(n, IIO_IECLR); - if (btenum == 0) { - imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD; - ieclr|= IECLR_BTE0; - } else { - imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD; - ieclr|= IECLR_BTE1; - } - REMOTE_HUB_S(n, IIO_IMEM, imem); - REMOTE_HUB_S(n, IIO_IECLR, ieclr); - - iidsr = REMOTE_HUB_L(n, IIO_IIDSR); - iidsr &= ~IIO_IIDSR_SENT_MASK; - iidsr |= IIO_IIDSR_ENB_MASK; - REMOTE_HUB_S(n, IIO_IIDSR, iidsr); + icmr.ii_icmr_regval = REMOTE_HUB_L(nasid, IIO_ICMR); + if (icmr.ii_icmr_fld_s.i_crb_mark != 0) { + /* + * There are errors which still need to be cleaned up by + * hubiio_crb_error_handler + */ + mod_timer(recovery_timer, HZ * 5); + BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, + smp_processor_id())); + spin_unlock_irqrestore(recovery_lock, irq_flags); + return; + } + if (icmr.ii_icmr_fld_s.i_crb_vld != 0) { + valid_crbs = icmr.ii_icmr_fld_s.i_crb_vld; - bte_reset_nasid(n); + for (i = 0; i < IIO_NUM_CRBS; i++) { + if (!((1 << i) & valid_crbs)) { + /* This crb was not marked as valid, ignore */ + continue; + } + icrbd.ii_icrb0_d_regval = + REMOTE_HUB_L(nasid, IIO_ICRB_D(i)); + if (icrbd.d_bteop) { + mod_timer(recovery_timer, HZ * 5); + BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n", + err_nodepda, smp_processor_id(), i)); + spin_unlock_irqrestore(recovery_lock, + irq_flags); + return; + } + } + } - *nodepda->bte_if[btenum].most_rcnt_na = IBLS_ERROR; -} + BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda, + smp_processor_id())); + /* Reenable both bte interfaces */ + imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM); + imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1; + REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval); + + /* Reinitialize both BTE state machines. */ + ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR); + ibcr.ii_ibcr_fld_s.i_soft_reset = 1; + REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval); + + + for (i = 0; i < BTES_PER_NODE; i++) { + bh_error = err_nodepda->bte_if[i].bh_error; + if (bh_error != BTE_SUCCESS) { + /* There is an error which needs to be notified */ + notify = err_nodepda->bte_if[i].most_rcnt_na; + BTE_PRINTK(("cnode %d bte %d error=0x%lx\n", + err_nodepda->bte_if[i].bte_cnode, + err_nodepda->bte_if[i].bte_num, + IBLS_ERROR | (u64) bh_error)); + *notify = IBLS_ERROR | bh_error; + err_nodepda->bte_if[i].bh_error = BTE_SUCCESS; + } + + err_nodepda->bte_if[i].cleanup_active = 0; + BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda, + smp_processor_id(), i)); + spin_unlock(&pda.cpu_bte_if[i]->spinlock); + } + + del_timer(recovery_timer); + + spin_unlock_irqrestore(recovery_lock, irq_flags); +} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/efi-rtc.c linux-2.4.22/arch/ia64/sn/io/sn2/efi-rtc.c --- linux-2.4.21/arch/ia64/sn/io/sn2/efi-rtc.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/efi-rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,202 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (C) 2001 by Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * No locking necessary when this is called from efirtc which protects us - * from racing by efi_rtc_lock. - */ -#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3)) -#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr)) -#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data)) - -#define TOD_SGS_M48T35 1 -#define TOD_DALLAS_DS1386 2 - -#define TYPE_IOC3 1 -#define TYPE_IOC4 2 - -static unsigned long nvram_base = 0; -static int tod_chip_type; -static int ioc_type; - -static int -get_tod_chip_type(void) -{ - unsigned char testval; - - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - write_io_port(RTC_DAL_DAY_ADDR, 0xff); - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - - testval = read_io_port(RTC_DAL_DAY_ADDR); - if (testval == 0xff) - return TOD_SGS_M48T35; - - return TOD_DALLAS_DS1386; -} - -efi_status_t -ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps) -{ - if (!nvram_base) { - printk(KERN_CRIT "nvram_base is zero\n"); - return EFI_UNSUPPORTED; - } - - memset(time, 0, sizeof(*time)); - - switch (tod_chip_type) { - case TOD_SGS_M48T35: - write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT); - - time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF; - time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR)); - time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR)); - time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR)); - time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR)); - time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR)); - time->nanosecond = 0; - - write_io_port(RTC_SGS_CONTROL_ADDR, 0); - break; - - case TOD_DALLAS_DS1386: - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - - time->nanosecond = 0; - time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR)); - time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR)); - time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR)); - time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR)); - time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR)); - time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF; - - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - break; - - default: - break; - } - - if (caps) { - caps->resolution = 50000000; /* 50PPM */ - caps->accuracy = 1000; /* 1ms */ - caps->sets_to_zero = 0; - } - - return EFI_SUCCESS; -} - -static efi_status_t ioc3_set_time (efi_time_t *t) -{ - if (!nvram_base) { - printk(KERN_CRIT "nvram_base is zero\n"); - return EFI_UNSUPPORTED; - } - - switch (tod_chip_type) { - case TOD_SGS_M48T35: - write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE); - write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF))); - write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month)); - write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day)); - write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour)); - write_io_port(RTC_SGS_MIN_ADDR, INT_TO_BCD(t->minute)); - write_io_port(RTC_SGS_SEC_ADDR, INT_TO_BCD(t->second)); - write_io_port(RTC_SGS_CONTROL_ADDR, 0); - break; - - case TOD_DALLAS_DS1386: - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE); - write_io_port(RTC_DAL_SEC_ADDR, INT_TO_BCD(t->second)); - write_io_port(RTC_DAL_MIN_ADDR, INT_TO_BCD(t->minute)); - write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour)); - write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day)); - write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month)); - write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF))); - write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE); - break; - - default: - break; - } - - return EFI_SUCCESS; -} - -/* The following two are not supported atm. */ -static efi_status_t -ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm) -{ - return EFI_UNSUPPORTED; -} - -static efi_status_t -ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm) -{ - return EFI_UNSUPPORTED; -} - -static __init int efi_ioc_time_init(void) -{ - struct pci_dev *dev = NULL; - static void *ioc_base; - - while ( (dev = pci_find_subsys(PCI_VENDOR_ID_SGI, - PCI_ANY_ID, - PCI_ANY_ID, - PCI_ANY_ID, dev))) { - if ( dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { - ioc_type = TYPE_IOC3; - break; - } - else if ( dev->device == PCI_DEVICE_ID_SGI_IOC4 ) { - ioc_type = TYPE_IOC4; - break; - } - else - ;; // keep looking - } - - if ( !dev ) { - printk(KERN_CRIT "Couldn't find master IOC\n"); - return -ENODEV; - } - - ioc_base = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0)); - if ( ioc_type == TYPE_IOC3 ) - nvram_base = (unsigned long) ioc_base + IOC3_BYTEBUS_DEV0; - if ( ioc_type == TYPE_IOC4 ) - nvram_base = (unsigned long) ioc_base + IOC4_BYTEBUS_DEV0; - - tod_chip_type = get_tod_chip_type(); - if (tod_chip_type == 1) - printk(KERN_NOTICE "TOD type is SGS M48T35\n"); - else if (tod_chip_type == 2) - printk(KERN_NOTICE "TOD type is Dallas DS1386\n"); - else - printk(KERN_CRIT "No or unknown TOD\n"); - - efi.get_time = ioc3_get_time; - efi.set_time = ioc3_set_time; - efi.get_wakeup_time = ioc3_get_wakeup_time; - efi.set_wakeup_time = ioc3_set_wakeup_time; - - return 0; -} - -module_init(efi_ioc_time_init); diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/geo_op.c linux-2.4.22/arch/ia64/sn/io/sn2/geo_op.c --- linux-2.4.21/arch/ia64/sn/io/sn2/geo_op.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/geo_op.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ /* diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/kdba_io.c linux-2.4.22/arch/ia64/sn/io/sn2/kdba_io.c --- linux-2.4.21/arch/ia64/sn/io/sn2/kdba_io.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/io/sn2/kdba_io.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,76 @@ +/* + * Kernel Debugger Architecture Dependent POD functions. + * + * Copyright (C) 1999-2003 Silicon Graphics, Inc. All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/NoticeExplan + */ + +#include +#include +//#include + +/** + * kdba_io - enter POD mode from kdb + * @argc: arg count + * @argv: arg values + * @envp: kdb env. vars + * @regs: current register state + * + * Enter POD mode from kdb using SGI SN specific SAL function call. + */ +static int +kdba_io(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + kdb_printf("kdba_io entered with addr 0x%p\n", (void *) regs); + + return(0); +} + +/** + * kdba_io_init - register 'io' command with kdb + * + * Register the 'io' command with kdb at load time. + */ +void +kdba_io_init(void) +{ + kdb_register("io", kdba_io, "", "Display IO Contents", 0); +} + +/** + * kdba_io_exit - unregister the 'io' command + * + * Tell kdb that the 'io' command is no longer available. + */ +static void __exit +kdba_exit(void) +{ + kdb_unregister("io"); +} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/klconflib.c linux-2.4.22/arch/ia64/sn/io/sn2/klconflib.c --- linux-2.4.21/arch/ia64/sn/io/sn2/klconflib.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/klconflib.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ @@ -24,8 +24,6 @@ #include #include -#define printf printk -int hasmetarouter; #define LDEBUG 0 #define NIC_UNKNOWN ((nic_t) -1) @@ -37,10 +35,11 @@ #define DBG(x...) #endif /* DEBUG_KLGRAPH */ -static void sort_nic_names(lboard_t *) ; - u64 klgraph_addr[MAX_COMPACT_NODES]; -int module_number = 0; +static int hasmetarouter; + + +char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=012345"; lboard_t * find_lboard(lboard_t *start, unsigned char brd_type) @@ -135,23 +134,6 @@ return (lboard_t *)NULL; } -lboard_t * -find_lboard_module_class(lboard_t *start, geoid_t geoid, - unsigned char brd_type) -{ - while (start) { - DBG("find_lboard_module_class: lboard 0x%p, start->brd_geoid 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_geoid, geoid, start->brd_type, brd_type); - - if (geo_cmp(start->brd_geoid, geoid) && - (KLCLASS(start->brd_type) == KLCLASS(brd_type))) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - /* * Convert a NIC name to a name for use in the hardware graph. */ @@ -205,63 +187,6 @@ } /* - * Find the lboard structure and get the board name. - * If we can't find the structure or it's too low a revision, - * use default name. - */ -lboard_t * -get_board_name(nasid_t nasid, geoid_t geoid, slotid_t slot, char *name) -{ - lboard_t *brd; - - brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), - geoid); - -#ifndef _STANDALONE - { - cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); - - if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) - brd = find_lboard_modslot((lboard_t *) - KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), - geoid); - } -#endif - - if (!brd || (brd->brd_sversion < 2)) { - strcpy(name, EDGE_LBL_XWIDGET); - } else { - nic_name_convert(brd->brd_name, name); - } - - /* - * PV # 540860 - * If the name is not 'baseio' - * get the lowest of all the names in the nic string. - * This is needed for boards like divo, which can have - * a bunch of daughter cards, but would like to be called - * divo. We could do this for baseio - * but it has some special case names that we would not - * like to disturb at this point. - */ - - /* gfx boards don't need any of this name scrambling */ - if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) { - return(brd); - } - - if (!(!strcmp(name, "baseio") )) { - if (brd) { - sort_nic_names(brd) ; - /* Convert to small case, '-' to '_' etc */ - nic_name_convert(brd->brd_name, name) ; - } - } - - return(brd); -} - -/* * get_actual_nasid * * Completely disabled brds have their klconfig on @@ -341,12 +266,20 @@ board_name = EDGE_LBL_IO; break; case KLCLASS_IOBRICK: - if (brd->brd_type == KLTYPE_PBRICK) + if (brd->brd_type == KLTYPE_PXBRICK) + board_name = EDGE_LBL_PXBRICK; + else if (brd->brd_type == KLTYPE_IXBRICK) + board_name = EDGE_LBL_IXBRICK; + else if (brd->brd_type == KLTYPE_PBRICK) board_name = EDGE_LBL_PBRICK; else if (brd->brd_type == KLTYPE_IBRICK) board_name = EDGE_LBL_IBRICK; else if (brd->brd_type == KLTYPE_XBRICK) board_name = EDGE_LBL_XBRICK; + else if (brd->brd_type == KLTYPE_PEBRICK) + board_name = EDGE_LBL_PEBRICK; + else if (brd->brd_type == KLTYPE_CGBRICK) + board_name = EDGE_LBL_CGBRICK; else board_name = EDGE_LBL_IOBRICK; break; @@ -623,185 +556,6 @@ #include "asm/sn/sn_private.h" -xwidgetnum_t -nodevertex_widgetnum_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - return(hubinfo_p->h_widgetid); -} - -devfs_handle_t -nodevertex_xbow_peer_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - nasid_t xbow_peer_nasid; - cnodeid_t xbow_peer; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer; - if(xbow_peer_nasid == INVALID_NASID) - return ( (devfs_handle_t)-1); - xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid); - return(NODEPDA(xbow_peer)->node_vertex); -} - -/* NIC Sorting Support */ - -#define MAX_NICS_PER_STRING 32 -#define MAX_NIC_NAME_LEN 32 - -static char * -get_nic_string(lboard_t *lb) -{ - int i; - klinfo_t *k = NULL ; - klconf_off_t mfg_off = 0 ; - char *mfg_nic = NULL ; - - for (i = 0; i < KLCF_NUM_COMPS(lb); i++) { - k = KLCF_COMP(lb, i) ; - switch(k->struct_type) { - case KLSTRUCT_BRI: - mfg_off = ((klbri_t *)k)->bri_mfg_nic ; - break ; - - case KLSTRUCT_HUB: - mfg_off = ((klhub_t *)k)->hub_mfg_nic ; - break ; - - case KLSTRUCT_ROU: - mfg_off = ((klrou_t *)k)->rou_mfg_nic ; - break ; - - case KLSTRUCT_GFX: - mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ; - break ; - - case KLSTRUCT_TPU: - mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ; - break ; - - case KLSTRUCT_GSN_A: - case KLSTRUCT_GSN_B: - mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ; - break ; - - case KLSTRUCT_XTHD: - mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ; - break; - - default: - mfg_off = 0 ; - break ; - } - if (mfg_off) - break ; - } - - if ((mfg_off) && (k)) - mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ; - - return mfg_nic ; -} - -char * -get_first_string(char **ptrs, int n) -{ - int i ; - char *tmpptr ; - - if ((ptrs == NULL) || (n == 0)) - return NULL ; - - tmpptr = ptrs[0] ; - - if (n == 1) - return tmpptr ; - - for (i = 0 ; i < n ; i++) { - if (strcmp(tmpptr, ptrs[i]) > 0) - tmpptr = ptrs[i] ; - } - - return tmpptr ; -} - -int -get_ptrs(char *idata, char **ptrs, int n, char *label) -{ - int i = 0 ; - char *tmp = idata ; - - if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0)) - return 0 ; - - while ( (tmp = strstr(tmp, label)) ){ - tmp += strlen(label) ; - /* check for empty name field, and last NULL ptr */ - if ((i < (n-1)) && (*tmp != ';')) { - ptrs[i++] = tmp ; - } - } - - ptrs[i] = NULL ; - - return i ; -} - -/* - * sort_nic_names - * - * Does not really do sorting. Find the alphabetically lowest - * name among all the nic names found in a nic string. - * - * Return: - * Nothing - * - * Side Effects: - * - * lb->brd_name gets the new name found - */ - -static void -sort_nic_names(lboard_t *lb) -{ - char *nic_str ; - char *ptrs[MAX_NICS_PER_STRING] ; - char name[MAX_NIC_NAME_LEN] ; - char *tmp, *tmp1 ; - - *name = 0 ; - - /* Get the nic pointer from the lb */ - - if ((nic_str = get_nic_string(lb)) == NULL) - return ; - - tmp = get_first_string(ptrs, - get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ; - - if (tmp == NULL) - return ; - - if ( (tmp1 = strchr(tmp, ';')) ){ - strncpy(name, tmp, tmp1-tmp) ; - name[tmp1-tmp] = 0 ; - } else { - strncpy(name, tmp, (sizeof(name) -1)) ; - name[sizeof(name)-1] = 0 ; - } - - strcpy(lb->brd_name, name) ; -} - - - -char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345"; - /* * Format a module id for printing. */ @@ -814,6 +568,7 @@ rack = MODULE_GET_RACK(m); ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES); brickchar = MODULE_GET_BTCHAR(m); + position = MODULE_GET_BPOS(m); if (fmt == MODULE_FORMAT_BRIEF) { diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/klgraph.c linux-2.4.22/arch/ia64/sn/io/sn2/klgraph.c --- linux-2.4.21/arch/ia64/sn/io/sn2/klgraph.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/klgraph.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ /* @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -42,7 +41,7 @@ extern char arg_maxnodes[]; extern u64 klgraph_addr[]; -void mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid); +void mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid); /* @@ -69,7 +68,7 @@ * Add detailed disabled cpu inventory info to the hardware graph. */ void -klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv, +klhwg_disabled_cpu_invent_info(vertex_hdl_t cpuv, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot) { @@ -118,7 +117,7 @@ * Add detailed cpu inventory info to the hardware graph. */ void -klhwg_cpu_invent_info(devfs_handle_t cpuv, +klhwg_cpu_invent_info(vertex_hdl_t cpuv, cnodeid_t cnode, klcpu_t *cpu) { @@ -153,7 +152,7 @@ * as a part of detailed inventory info in the hwgraph. */ void -klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode) +klhwg_baseio_inventory_add(vertex_hdl_t baseio_vhdl,cnodeid_t cnode) { invent_miscinfo_t *baseio_inventory; unsigned char version = 0,revision = 0; @@ -177,20 +176,11 @@ sizeof(invent_miscinfo_t)); } -char *hub_rev[] = { - "0.0", - "1.0", - "2.0", - "2.1", - "2.2", - "2.3" -}; - /* * Add detailed cpu inventory info to the hardware graph. */ void -klhwg_hub_invent_info(devfs_handle_t hubv, +klhwg_hub_invent_info(vertex_hdl_t hubv, cnodeid_t cnode, klhub_t *hub) { @@ -215,10 +205,10 @@ /* ARGSUSED */ void -klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode) +klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode) { - devfs_handle_t myhubv; - devfs_handle_t hub_mon; + vertex_hdl_t myhubv; + vertex_hdl_t hub_mon; int rc; extern struct file_operations shub_mon_fops; @@ -234,9 +224,9 @@ /* ARGSUSED */ void -klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot) +klhwg_add_disabled_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot) { - devfs_handle_t my_cpu; + vertex_hdl_t my_cpu; char name[120]; cpuid_t cpu_id; nasid_t nasid; @@ -257,9 +247,9 @@ /* ARGSUSED */ void -klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu) +klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu) { - devfs_handle_t my_cpu, cpu_dir; + vertex_hdl_t my_cpu, cpu_dir; char name[120]; cpuid_t cpu_id; nasid_t nasid; @@ -295,7 +285,7 @@ nasid_t hub_nasid; cnodeid_t hub_cnode; int widgetnum; - devfs_handle_t xbow_v, hubv; + vertex_hdl_t xbow_v, hubv; /*REFERENCED*/ graph_error_t err; @@ -363,12 +353,12 @@ /* ARGSUSED */ void -klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) +klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode) { nasid_t nasid; lboard_t *brd; klhub_t *hub; - devfs_handle_t node_vertex = NULL; + vertex_hdl_t node_vertex = NULL; char path_buffer[100]; int rv; char *s; @@ -382,7 +372,7 @@ ASSERT(brd); do { - devfs_handle_t cpu_dir; + vertex_hdl_t cpu_dir; /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer); @@ -443,7 +433,7 @@ while (cpu) { cpuid_t cpu_id; cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid); - if (cpu_enabled(cpu_id)) + if (cpu_online(cpu_id)) klhwg_add_cpu(node_vertex, cnode, cpu); else klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot); @@ -466,12 +456,12 @@ /* ARGSUSED */ void -klhwg_add_all_routers(devfs_handle_t hwgraph_root) +klhwg_add_all_routers(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; - devfs_handle_t node_vertex; + vertex_hdl_t node_vertex; char path_buffer[100]; int rv; @@ -525,14 +515,14 @@ /* ARGSUSED */ void -klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd, +klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd, cnodeid_t cnode, nasid_t nasid) { klrou_t *router; char path_buffer[50]; char dest_path[50]; - devfs_handle_t router_hndl; - devfs_handle_t dest_hndl; + vertex_hdl_t router_hndl; + vertex_hdl_t dest_hndl; int rc; int port; lboard_t *dest_brd; @@ -619,7 +609,7 @@ void -klhwg_connect_routers(devfs_handle_t hwgraph_root) +klhwg_connect_routers(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; @@ -652,15 +642,15 @@ void -klhwg_connect_hubs(devfs_handle_t hwgraph_root) +klhwg_connect_hubs(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; klhub_t *hub; lboard_t *dest_brd; - devfs_handle_t hub_hndl; - devfs_handle_t dest_hndl; + vertex_hdl_t hub_hndl; + vertex_hdl_t dest_hndl; char path_buffer[50]; char dest_path[50]; graph_error_t rc; @@ -796,12 +786,12 @@ } void -klhwg_add_all_modules(devfs_handle_t hwgraph_root) +klhwg_add_all_modules(vertex_hdl_t hwgraph_root) { cmoduleid_t cm; char name[128]; - devfs_handle_t vhdl; - devfs_handle_t module_vhdl; + vertex_hdl_t vhdl; + vertex_hdl_t module_vhdl; int rc; char buffer[16]; @@ -837,12 +827,12 @@ } void -klhwg_add_all_nodes(devfs_handle_t hwgraph_root) +klhwg_add_all_nodes(vertex_hdl_t hwgraph_root) { cnodeid_t cnode; for (cnode = 0; cnode < numnodes; cnode++) { - klhwg_add_node(hwgraph_root, cnode, NULL); + klhwg_add_node(hwgraph_root, cnode); } for (cnode = 0; cnode < numnodes; cnode++) { diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/l1.c linux-2.4.22/arch/ia64/sn/io/sn2/l1.c --- linux-2.4.21/arch/ia64/sn/io/sn2/l1.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/l1.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,239 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -/* In general, this file is organized in a hierarchy from lower-level - * to higher-level layers, as follows: - * - * UART routines - * Bedrock/L1 "PPP-like" protocol implementation - * System controller "message" interface (allows multiplexing - * of various kinds of requests and responses with - * console I/O) - * Console interface: - * "l1_cons", the glue that allows the L1 to act - * as the system console for the stdio libraries - * - * Routines making use of the system controller "message"-style interface - * can be found in l1_command.c. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define UART_BAUD_RATE 57600 - -int -get_L1_baud(void) -{ - return UART_BAUD_RATE; -} - - - -/* Return the current interrupt level */ -int -l1_get_intr_value( void ) -{ - return(0); -} - -/* Disconnect the callup functions - throw away interrupts */ - -void -l1_unconnect_intr(void) -{ -} - -/* Set up uart interrupt handling for this node's uart */ - -void -l1_connect_intr(void *rx_notify, void *tx_notify) -{ -#if 0 - // Will need code here for sn2 - something like this - console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()); - intr_connect_level(console_nodepda->node_first_cpu, - SGI_UART_VECTOR, INTPEND0_MAXMASK, - dummy_intr_func); - request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8), - intr_func, SA_INTERRUPT | SA_SHIRQ, - "l1_protocol_driver", (void *)sc); -#endif -} - - -/* These are functions to use from serial_in/out when in protocol - * mode to send and receive uart control regs. These are external - * interfaces into the protocol driver. - */ - -void -l1_control_out(int offset, int value) -{ - /* quietly ignore unless simulator */ - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - if ( master_node_bedrock_address != (u64)0 ) { - writeb(value, (unsigned long)master_node_bedrock_address + - (offset<< 3)); - } - return; - } -} - -/* Console input exported interface. Return a register value. */ - -int -l1_control_in_polled(int offset) -{ - static int l1_control_in_local(int); - - return(l1_control_in_local(offset)); -} - -int -l1_control_in(int offset) -{ - static int l1_control_in_local(int); - - return(l1_control_in_local(offset)); -} - -static int -l1_control_in_local(int offset) -{ - int sal_call_status = 0, input; - int ret = 0; - - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - ret = readb((unsigned long)master_node_bedrock_address + - (offset<< 3)); - return(ret); - } - if ( offset == REG_LSR ) { - ret = (LSR_XHRE | LSR_XSRE); /* can send anytime */ - sal_call_status = ia64_sn_console_check(&input); - if ( !sal_call_status && input ) { - /* input pending */ - ret |= LSR_RCA; - } - } - return(ret); -} - -/* - * Console input exported interface. Return a character (if one is available) - */ - -int -l1_serial_in_polled(void) -{ - static int l1_serial_in_local(void); - - return(l1_serial_in_local()); -} - -int -l1_serial_in(void) -{ - static int l1_serial_in_local(void); - - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3))); - } - return(l1_serial_in_local()); -} - -static int -l1_serial_in_local(void) -{ - int ch; - - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3))); - } - - if ( !(ia64_sn_console_getc(&ch)) ) - return(ch); - else - return(0); -} - -/* Console output exported interface. Write message to the console. */ - -int -l1_serial_out( char *str, int len ) -{ - int counter = len; - -#if defined(CONFIG_IA64_EARLY_PRINTK) - /* Need to setup SAL calls so the PROM calls will work */ - { - static int inited; - void early_sn_setup(void); - if(!inited) { - inited=1; - early_sn_setup(); - } - } -#endif - - if ( IS_RUNNING_ON_SIMULATOR() ) { - extern u64 master_node_bedrock_address; - void early_sn_setup(void); - if (!master_node_bedrock_address) - early_sn_setup(); - if ( master_node_bedrock_address != (u64)0 ) { -#ifdef FLAG_DIRECT_CONSOLE_WRITES - /* This is an easy way to pre-pend the output to know whether the output - * was done via sal or directly */ - writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); -#endif /* FLAG_DIRECT_CONSOLE_WRITES */ - while ( counter > 0 ) { - writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3)); - counter--; - str++; - } - } - return(len); - } - - /* Attempt to write things out thru the sal */ - if ( ia64_sn_console_putb(str, len) ) - return(0); - return((counter <= 0) ? 0 : (len - counter)); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/l1_command.c linux-2.4.22/arch/ia64/sn/io/sn2/l1_command.c --- linux-2.4.21/arch/ia64/sn/io/sn2/l1_command.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/l1_command.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -26,37 +25,6 @@ #include #include -#define ELSC_TIMEOUT 1000000 /* ELSC response timeout (usec) */ -#define LOCK_TIMEOUT 5000000 /* Hub lock timeout (usec) */ - -#define hub_cpu_get() 0 - -#define LBYTE(caddr) (*(char *) caddr) - -extern char *bcopy(const char * src, char * dest, int count); - -#define LDEBUG 0 - -/* - * ELSC data is in NVRAM page 7 at the following offsets. - */ - -#define NVRAM_MAGIC_AD 0x700 /* magic number used for init */ -#define NVRAM_PASS_WD 0x701 /* password (4 bytes in length) */ -#define NVRAM_DBG1 0x705 /* virtual XOR debug switches */ -#define NVRAM_DBG2 0x706 /* physical XOR debug switches */ -#define NVRAM_CFG 0x707 /* ELSC Configuration info */ -#define NVRAM_MODULE 0x708 /* system module number */ -#define NVRAM_BIST_FLG 0x709 /* BIST flags (2 bits per nodeboard) */ -#define NVRAM_PARTITION 0x70a /* module's partition id */ -#define NVRAM_DOMAIN 0x70b /* module's domain id */ -#define NVRAM_CLUSTER 0x70c /* module's cluster id */ -#define NVRAM_CELL 0x70d /* module's cellid */ - -#define NVRAM_MAGIC_NO 0x37 /* value of magic number */ -#define NVRAM_SIZE 16 /* 16 bytes in nvram */ - - /* elsc_display_line writes up to 12 characters to either the top or bottom * line of the L1 display. line points to a buffer containing the message * to be displayed. The zero-based line number is specified by lnum (so @@ -69,6 +37,7 @@ return 0; } + /* * iobrick routines */ @@ -88,15 +57,25 @@ if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) ) return( ELSC_ERROR_CMD_SEND ); - *rack = (result & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (result & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - *brick_type = (result & L1_ADDR_TYPE_MASK) >> L1_ADDR_TYPE_SHFT; + *rack = (result & MODULE_RACK_MASK) >> MODULE_RACK_SHFT; + *bay = (result & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT; + *brick_type = (result & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT; *brick_type = toupper(*brick_type); return 0; } +int iomoduleid_get(nasid_t nasid) +{ + int result = 0; + + if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) ) + return( ELSC_ERROR_CMD_SEND ); + + return result; +} + int iobrick_module_get(nasid_t nasid) { uint rnum, rack, bay, brick_type, t; @@ -130,11 +109,15 @@ RACK_ADD_NUM(rack, t); switch( brick_type ) { - case 'I': + case L1_BRICKTYPE_IX: + brick_type = MODULE_IXBRICK; break; + case L1_BRICKTYPE_PX: + brick_type = MODULE_PXBRICK; break; + case L1_BRICKTYPE_I: brick_type = MODULE_IBRICK; break; - case 'P': + case L1_BRICKTYPE_P: brick_type = MODULE_PBRICK; break; - case 'X': + case L1_BRICKTYPE_X: brick_type = MODULE_XBRICK; break; } @@ -167,8 +150,9 @@ /* convert to a module.h brick type */ for( t = 0; t < MAX_BRICK_TYPES; t++ ) { - if( brick_types[t] == type ) + if( brick_types[t] == type ) { return t; + } } return -1; /* unknown brick */ @@ -178,18 +162,42 @@ { int io_moduleid; -#ifdef PIC_LATER - uint rack, bay; + io_moduleid = iobrick_module_get(nasid); + return io_moduleid; +} + +/* + * given a L1 bricktype, return a bricktype string. This string is the + * string that will be used in the hwpath for I/O bricks + */ +char * +iobrick_L1bricktype_to_name(int type) +{ + switch (type) + { + default: + return("Unknown"); - if (PEBRICK_NODE(nasid)) { - if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) { - printf("Could not read rack and bay location " - "of PEBrick at nasid %d\n", nasid); - } + case L1_BRICKTYPE_X: + return("Xbrick"); - io_moduleid = peer_iobrick_module_get(sc, rack, bay); + case L1_BRICKTYPE_I: + return("Ibrick"); + + case L1_BRICKTYPE_P: + return("Pbrick"); + + case L1_BRICKTYPE_PX: + return("PXbrick"); + + case L1_BRICKTYPE_IX: + return("IXbrick"); + + case L1_BRICKTYPE_C: + return("Cbrick"); + + case L1_BRICKTYPE_R: + return("Rbrick"); } -#endif /* PIC_LATER */ - io_moduleid = iobrick_module_get(nasid); - return io_moduleid; } + diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_init.c linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_init.c --- linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_init.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_init.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -19,25 +19,12 @@ #include #include #include -#include -extern int numcpus; -extern char arg_maxnodes[]; extern cpuid_t master_procid; - -extern int hasmetarouter; - int maxcpus; -cpumask_t boot_cpumask; -hubreg_t region_mask = 0; - extern xwidgetnum_t hub_widget_id(nasid_t); -extern int valid_icache_reasons; /* Reasons to flush the icache */ -extern int valid_dcache_reasons; /* Reasons to flush the dcache */ -extern u_char miniroot; -extern volatile int need_utlbmiss_patch; extern void iograph_early_init(void); nasid_t master_nasid = INVALID_NASID; /* This is the partition master nasid */ @@ -123,16 +110,6 @@ mutex_init_locked(&npda->xbow_sema); /* init it locked? */ } -/* XXX - Move the interrupt stuff to intr.c ? */ -/* - * Set up the platform-dependent fields in the processor pda. - * Must be done _after_ init_platform_nodepda(). - * If we need a lock here, something else is wrong! - */ -void init_platform_pda(cpuid_t cpu) -{ -} - void update_node_information(cnodeid_t cnodeid) { diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_intr.c linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_intr.c --- linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_intr.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_intr.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ /* @@ -40,30 +40,13 @@ #include #include -extern irqpda_t *irqpdaindr[]; -extern cnodeid_t master_node_get(devfs_handle_t vhdl); +extern irqpda_t *irqpdaindr; +extern cnodeid_t master_node_get(vertex_hdl_t vhdl); extern nasid_t master_nasid; // Initialize some shub registers for interrupts, both IO and error. // -#ifdef BRINGUP2 -static long vec1_opt, ii0_opt; -static int __init set_vec1_opt(char *str) -{ - vec1_opt = 1; - return 1; -} - -static int __init set_ii0_opt(char *str) -{ - ii0_opt = 1; - return 1; -} - -__setup("vec1", set_vec1_opt); -__setup("ii0", set_ii0_opt); -#endif void @@ -78,6 +61,8 @@ nodepda_t *lnodepda; sh_ii_int0_enable_u_t ii_int_enable; sh_int_node_id_config_u_t node_id_config; + sh_local_int5_config_u_t local5_config; + sh_local_int5_enable_u_t local5_enable; extern void sn_init_cpei_timer(void); static int timer_added = 0; @@ -113,6 +98,19 @@ HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0); HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0); + // Config and enable UART interrupt, all nodes. + + local5_config.sh_local_int5_config_regval = 0; + local5_config.sh_local_int5_config_s.idx = SGI_UART_VECTOR; + local5_config.sh_local_int5_config_s.pid = cpu0; + HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_CONFIG), + local5_config.sh_local_int5_config_regval); + + local5_enable.sh_local_int5_enable_regval = 0; + local5_enable.sh_local_int5_enable_s.uart_int = 1; + HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE), + local5_enable.sh_local_int5_enable_regval); + // The II_INT_CONFIG register for cpu 0. ii_int_config.sh_ii_int0_config_regval = 0; @@ -139,13 +137,6 @@ // Enable interrupts for II_INT0 and 1. ii_int_enable.sh_ii_int0_enable_regval = 0; ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1; -#if defined(BUS_INT_WAR) && defined(CONFIG_SHUB_1_0_SPECIFIC) - /* Dont enable any ints from II. We will poll for interrupts. */ - ii_int_enable.sh_ii_int0_enable_s.ii_enable = 0; - - /* Enable IPIs. We use them ONLY for send INITs to hung cpus */ - *(volatile long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT_ENABLE) = 1; -#endif HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE), ii_int_enable.sh_ii_int0_enable_regval); @@ -167,24 +158,44 @@ int reserve) { int i; - irqpda_t *irqs = irqpdaindr[cpu]; - static int nextvec=IA64_SN2_FIRST_DEVICE_VECTOR; + irqpda_t *irqs = irqpdaindr; + int min_shared; if (reserve) { if (bit < 0) { - for (i = nextvec; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) { + for (i = IA64_SN2_FIRST_DEVICE_VECTOR; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) { if (irqs->irq_flags[i] == 0) { bit = i; -#ifdef BRINGUP2 - if (vec1_opt) - nextvec = i+1; -#endif break; } } } - if (bit < 0) { - return -1; + if (bit < 0) { /* ran out of irqs. Have to share. This will be rare. */ + min_shared = 256; + for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) { + /* Share with the same device class */ + if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor && + irqpdaindr->current->device == irqpdaindr->device_dev[i]->device && + irqpdaindr->share_count[i] < min_shared) { + min_shared = irqpdaindr->share_count[i]; + bit = i; + } + } + min_shared = 256; + if (bit < 0) { /* didn't find a matching device, just pick one. This will be */ + /* exceptionally rare. */ + for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) { + if (irqpdaindr->share_count[i] < min_shared) { + min_shared = irqpdaindr->share_count[i]; + bit = i; + } + } + } + irqpdaindr->share_count[bit]++; + } + if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) { + irqs->irq_flags[bit] |= SN2_IRQ_RESERVED; + return bit; } if (irqs->irq_flags[bit] & SN2_IRQ_RESERVED) { return -1; @@ -208,7 +219,7 @@ intr_reserve_level(cpuid_t cpu, int bit, int resflags, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, char *name) { return(do_intr_reserve_level(cpu, bit, 1)); @@ -228,9 +239,13 @@ int bit, int connect) { - irqpda_t *irqs = irqpdaindr[cpu]; + irqpda_t *irqs = irqpdaindr; if (connect) { + if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) { + irqs->irq_flags[bit] |= SN2_IRQ_CONNECTED; + return bit; + } if (irqs->irq_flags[bit] & SN2_IRQ_CONNECTED) { return -1; } else { @@ -273,28 +288,29 @@ int slice, min_count = 1000; irqpda_t *irqs; - for (slice = 0; slice < CPUS_PER_NODE; slice++) { + for (slice = CPUS_PER_NODE - 1; slice >= 0; slice--) { int intrs; cpu = cnode_slice_to_cpuid(cnode, slice); - if (cpu == CPU_NONE) { + if (cpu == smp_num_cpus) { continue; } - if (!cpu_enabled(cpu)) { + if (!cpu_online(cpu)) { continue; } - irqs = irqpdaindr[cpu]; + irqs = irqpdaindr; intrs = irqs->num_irq_used; if (min_count > intrs) { min_count = intrs; best_cpu = cpu; -#ifdef BRINGUP2 - if (ii0_opt) + if ( enable_shub_wars_1_1() ) { + /* Rather than finding the best cpu, always return the first cpu*/ + /* This forces all interrupts to the same cpu */ break; -#endif + } } } return best_cpu; @@ -314,7 +330,7 @@ cnodeid_t cnode, int req_bit, int resflags, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, char *name, int *resp_bit) { @@ -336,18 +352,18 @@ // Find the node to assign for this interrupt. cpuid_t -intr_heuristic(devfs_handle_t dev, +intr_heuristic(vertex_hdl_t dev, device_desc_t dev_desc, int req_bit, int resflags, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, char *name, int *resp_bit) { cpuid_t cpuid; cpuid_t candidate = CPU_NONE; cnodeid_t candidate_node; - devfs_handle_t pconn_vhdl; + vertex_hdl_t pconn_vhdl; pcibr_soft_t pcibr_soft; int bit; @@ -398,8 +414,8 @@ if (candidate != CPU_NONE) { printk("Cannot target interrupt to target node (%ld).\n",candidate); return CPU_NONE; } else { - printk("Cannot target interrupt to closest node (%d) 0x%p\n", - master_node_get(dev), (void *)owner_dev); + /* printk("Cannot target interrupt to closest node (%d) 0x%p\n", + master_node_get(dev), (void *)owner_dev); */ } // We couldn't put it on the closest node. Try to find another one. diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/ml_iograph.c linux-2.4.22/arch/ia64/sn/io/sn2/ml_iograph.c --- linux-2.4.21/arch/ia64/sn/io/sn2/ml_iograph.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/ml_iograph.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -43,8 +42,6 @@ /* At most 2 hubs can be connected to an xswitch */ #define NUM_XSWITCH_VOLUNTEER 2 -extern unsigned char Is_pic_on_this_nasid[512]; - /* * Track which hubs have volunteered to manage devices hanging off of * a Crosstalk Switch (e.g. xbow). This structure is allocated, @@ -54,11 +51,11 @@ typedef struct xswitch_vol_s { mutex_t xswitch_volunteer_mutex; int xswitch_volunteer_count; - devfs_handle_t xswitch_volunteer[NUM_XSWITCH_VOLUNTEER]; + vertex_hdl_t xswitch_volunteer[NUM_XSWITCH_VOLUNTEER]; } *xswitch_vol_t; void -xswitch_vertex_init(devfs_handle_t xswitch) +xswitch_vertex_init(vertex_hdl_t xswitch) { xswitch_vol_t xvolinfo; int rc; @@ -78,7 +75,7 @@ * xswitch volunteer structure hanging around. Destroy it. */ static void -xswitch_volunteer_delete(devfs_handle_t xswitch) +xswitch_volunteer_delete(vertex_hdl_t xswitch) { xswitch_vol_t xvolinfo; int rc; @@ -94,10 +91,10 @@ */ /* ARGSUSED */ static void -volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master) +volunteer_for_widgets(vertex_hdl_t xswitch, vertex_hdl_t master) { xswitch_vol_t xvolinfo = NULL; - devfs_handle_t hubv; + vertex_hdl_t hubv; hubinfo_t hubinfo; (void)hwgraph_info_get_LBL(xswitch, @@ -140,7 +137,7 @@ */ /* ARGSUSED */ static void -assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv) +assign_widgets_to_volunteers(vertex_hdl_t xswitch, vertex_hdl_t hubv) { xswitch_info_t xswitch_info; xswitch_vol_t xvolinfo = NULL; @@ -223,18 +220,6 @@ bt = iobrick_type_get_nasid(nasid); if (bt >= 0) { - /* - * PXBRICK has two busses per widget so this - * algorithm wouldn't work (all busses would - * be assigned to one volunteer). Change the - * bricktype to PBRICK whose mapping is setup - * suchthat 2 of the PICs will be assigned to - * one volunteer and the other one will be - * assigned to the other volunteer. - */ - if (bt == MODULE_PXBRICK) - bt = MODULE_PBRICK; - i = io_brick_map_widget(bt, widgetnum) & 1; } } @@ -281,8 +266,6 @@ DBG("iograph_early_init: Found board 0x%p\n", board); } } - - hubio_init(); } /* @@ -307,7 +290,7 @@ * hwid for our use. */ static void -early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid) +early_probe_for_widget(vertex_hdl_t hubv, xwidget_hwid_t hwid) { hubreg_t llp_csr_reg; nasid_t nasid; @@ -351,7 +334,7 @@ * added as inventory information. */ static void -xwidget_inventory_add(devfs_handle_t widgetv, +xwidget_inventory_add(vertex_hdl_t widgetv, lboard_t *board, struct xwidget_hwid_s hwid) { @@ -374,14 +357,13 @@ */ void -io_xswitch_widget_init(devfs_handle_t xswitchv, - devfs_handle_t hubv, - xwidgetnum_t widgetnum, - async_attach_t aa) +io_xswitch_widget_init(vertex_hdl_t xswitchv, + vertex_hdl_t hubv, + xwidgetnum_t widgetnum) { xswitch_info_t xswitch_info; xwidgetnum_t hub_widgetid; - devfs_handle_t widgetv; + vertex_hdl_t widgetv; cnodeid_t cnode; widgetreg_t widget_id; nasid_t nasid, peer_nasid; @@ -427,6 +409,7 @@ char name[4]; lboard_t dummy; + /* * If the current hub is not supposed to be the master * for this widgetnum, then skip this widget. @@ -470,12 +453,15 @@ memset(buffer, 0, 16); format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF); - sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%cbrick" "/%s/%d", + + sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%s" "/%s/%d", buffer, geo_slab(board->brd_geoid), - (board->brd_type == KLTYPE_IBRICK) ? 'I' : - (board->brd_type == KLTYPE_PBRICK) ? 'P' : - (board->brd_type == KLTYPE_XBRICK) ? 'X' : '?', + (board->brd_type == KLTYPE_IBRICK) ? EDGE_LBL_IBRICK : + (board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK : + (board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK : + (board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK : + (board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick", EDGE_LBL_XTALK, widgetnum); DBG("io_xswitch_widget_init: path= %s\n", pathname); @@ -514,36 +500,46 @@ xwidget_inventory_add(widgetv,board,hwid); (void)xwidget_register(&hwid, widgetv, widgetnum, - hubv, hub_widgetid, - aa); + hubv, hub_widgetid); ia64_sn_sysctl_iobrick_module_get(nasid, &io_module); if (io_module >= 0) { char buffer[16]; - devfs_handle_t to, from; + vertex_hdl_t to, from; + char *brick_name; + extern char *iobrick_L1bricktype_to_name(int type); + memset(buffer, 0, 16); format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF); - bt = toupper(MODULE_GET_BTCHAR(io_module)); + if ( islower(MODULE_GET_BTCHAR(io_module)) ) { + bt = toupper(MODULE_GET_BTCHAR(io_module)); + } + else { + bt = MODULE_GET_BTCHAR(io_module); + } + + brick_name = iobrick_L1bricktype_to_name(bt); + /* Add a helper vertex so xbow monitoring * can identify the brick type. It's simply * an edge from the widget 0 vertex to the * brick vertex. */ - sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/" + sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/" EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/" "0", buffer, geo_slab(board->brd_geoid)); from = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(from); - sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/" + sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/" - "%cbrick", - buffer, geo_slab(board->brd_geoid), bt); + "%s", + buffer, geo_slab(board->brd_geoid), brick_name); to = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(to); @@ -566,12 +562,9 @@ static void -io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode) +io_init_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnode) { xwidgetnum_t widgetnum; - async_attach_t aa; - - aa = async_attach_new(); DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode); @@ -579,13 +572,8 @@ widgetnum++) { io_xswitch_widget_init(xswitchv, cnodeid_to_vertex(cnode), - widgetnum, aa); + widgetnum); } - /* - * Wait for parallel attach threads, if any, to complete. - */ - async_attach_waitall(aa); - async_attach_free(aa); } /* @@ -595,11 +583,11 @@ * graph and risking hangs. */ static void -io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) +io_link_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnodeid) { xwidgetnum_t widgetnum; char pathname[128]; - devfs_handle_t vhdl; + vertex_hdl_t vhdl; nasid_t nasid, peer_nasid; lboard_t *board; @@ -638,21 +626,12 @@ return; } - if ( Is_pic_on_this_nasid[nasid] ) { - /* Check both buses */ - sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) - board->brd_graph_link = vhdl; - else { - sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) - board->brd_graph_link = vhdl; - else - board->brd_graph_link = GRAPH_VERTEX_NONE; - } - } + /* Check both buses */ + sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum); + if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) + board->brd_graph_link = vhdl; else { - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); + sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum); if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) board->brd_graph_link = vhdl; else @@ -668,16 +647,15 @@ io_init_node(cnodeid_t cnodeid) { /*REFERENCED*/ - devfs_handle_t hubv, switchv, widgetv; + vertex_hdl_t hubv, switchv, widgetv; struct xwidget_hwid_s hwid; hubinfo_t hubinfo; int is_xswitch; nodepda_t *npdap; struct semaphore *peer_sema = 0; uint32_t widget_partnum; - nodepda_router_info_t *npda_rip; cpu_cookie_t c = 0; - extern int hubdev_docallouts(devfs_handle_t); + extern int hubdev_docallouts(vertex_hdl_t); npdap = NODEPDA(cnodeid); @@ -696,21 +674,6 @@ hubdev_docallouts(hubv); /* - * Set up the dependent routers if we have any. - */ - npda_rip = npdap->npda_rip_first; - - while(npda_rip) { - /* If the router info has not been initialized - * then we need to do the router initialization - */ - if (!npda_rip->router_infop) { - router_init(cnodeid,0,npda_rip); - } - npda_rip = npda_rip->router_next; - } - - /* * Read mfg info on this hub */ @@ -833,7 +796,7 @@ */ hubinfo_get(hubv, &hubinfo); - (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL); + (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid); if (!is_xswitch) { /* io_init_done takes cpu cookie as 2nd argument @@ -915,231 +878,9 @@ * XXX Irix legacy..controller numbering should be part of devfsd's job */ int num_base_io_scsi_ctlr = 2; /* used by syssgi */ -devfs_handle_t base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR]; -static devfs_handle_t baseio_enet_vhdl,baseio_console_vhdl; - -/* - * Put the logical controller number information in the - * scsi controller vertices for each scsi controller that - * is in a "fixed position". - */ -static void -scsi_ctlr_nums_add(devfs_handle_t pci_vhdl) -{ - { - int i; - - num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR; - - /* Initialize base_io_scsi_ctlr_vhdl array */ - for (i=0; i -devfs_handle_t sys_critical_graph_root = GRAPH_VERTEX_NONE; - -/* Define the system critical vertices and connect them through - * a canonical parent-child relationships for easy traversal - * during io error handling. - */ -static void -sys_critical_graph_init(void) -{ - devfs_handle_t bridge_vhdl,master_node_vhdl; - devfs_handle_t xbow_vhdl = GRAPH_VERTEX_NONE; - extern devfs_handle_t hwgraph_root; - devfs_handle_t pci_slot_conn; - int slot; - devfs_handle_t baseio_console_conn; - - DBG("sys_critical_graph_init: FIXME.\n"); - baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl); - - if (baseio_console_conn == NULL) { - return; - } - - /* Get the vertex handle for the baseio bridge */ - bridge_vhdl = device_master_get(baseio_console_conn); - - /* Get the master node of the baseio card */ - master_node_vhdl = cnodeid_to_vertex( - master_node_get(baseio_console_vhdl)); - - /* Add the "root->node" part of the system critical graph */ - - sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl); - - /* Check if we have a crossbow */ - if (hwgraph_traverse(master_node_vhdl, - EDGE_LBL_XTALK"/0", - &xbow_vhdl) == GRAPH_SUCCESS) { - /* We have a crossbow.Add "node->xbow" part of the system - * critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl); - - /* Add "xbow->baseio bridge" of the system critical graph */ - sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl); - - hwgraph_vertex_unref(xbow_vhdl); - } else - /* We donot have a crossbow. Add "node->baseio_bridge" - * part of the system critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl); - - /* Add all the populated PCI slot vertices to the system critical - * graph with the bridge vertex as the parent. - */ - for (slot = 0 ; slot < 8; slot++) { - char slot_edge[10]; - - sprintf(slot_edge,"%d",slot); - if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn) - != GRAPH_SUCCESS) - continue; - sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn); - hwgraph_vertex_unref(pci_slot_conn); - } - - hwgraph_vertex_unref(bridge_vhdl); - - /* Add the "ioc3 pci connection point -> console ioc3" part - * of the system critical graph - */ - - if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_console_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "ethernet pci connection point -> base ethernet" part of - * the system critical graph - */ - if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_enet_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "scsi controller pci connection point -> base scsi - * controller" part of the system critical graph - */ - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[0]); - hwgraph_vertex_unref(pci_slot_conn); - } - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[1]); - hwgraph_vertex_unref(pci_slot_conn); - } - hwgraph_vertex_unref(baseio_console_conn); - -} - -static void -baseio_ctlr_num_set(void) -{ - char name[MAXDEVNAME]; - devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; - devfs_handle_t ioc3_console_vhdl_get(void); - - - DBG("baseio_ctlr_num_set; FIXME\n"); - console_vhdl = ioc3_console_vhdl_get(); - if (console_vhdl == GRAPH_VERTEX_NONE) - return; - /* Useful for setting up the system critical graph */ - baseio_console_vhdl = console_vhdl; - - vertex_to_name(console_vhdl,name,MAXDEVNAME); - - strcat(name,__DEVSTR1); - pci_vhdl = hwgraph_path_to_vertex(name); - scsi_ctlr_nums_add(pci_vhdl); - /* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(pci_vhdl); - - vertex_to_name(console_vhdl, name, MAXDEVNAME); - strcat(name, __DEVSTR4); - enet_vhdl = hwgraph_path_to_vertex(name); - - /* Useful for setting up the system critical graph */ - baseio_enet_vhdl = enet_vhdl; - - device_controller_num_set(enet_vhdl, 0); - /* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(enet_vhdl); -} /* #endif */ /* @@ -1168,13 +909,6 @@ */ update_node_information(cnodeid); - baseio_ctlr_num_set(); - /* Setup the system critical graph (which is a subgraph of the - * main hwgraph). This information is useful during io error - * handling. - */ - sys_critical_graph_init(); - #if HWG_PRINT hwgraph_print(); #endif @@ -1279,10 +1013,10 @@ 2, /* 0x8 */ 1, /* 0x9 */ 0, 0, /* 0xa - 0xb */ - 5, /* 0xc */ + 4, /* 0xc */ 6, /* 0xd */ - 4, /* 0xe */ - 3 /* 0xf */ + 3, /* 0xe */ + 5 /* 0xf */ } }, @@ -1300,6 +1034,20 @@ } }, +/* IXbrick widget number to PCI bus number map */ + { MODULE_IXBRICK, /* IXbrick type */ + /* PCI Bus # Widget # */ + { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ + 0, /* 0x8 */ + 0, /* 0x9 */ + 0, 0, /* 0xa - 0xb */ + 1, /* 0xc */ + 5, /* 0xd */ + 0, /* 0xe */ + 3 /* 0xf */ + } + }, + /* Xbrick widget to XIO slot map */ { MODULE_XBRICK, /* Xbrick type */ /* XIO Slot # Widget # */ @@ -1335,61 +1083,3 @@ return 0; } - -/* - * Use the device's vertex to map the device's widget to a meaningful int - */ -int -io_path_map_widget(devfs_handle_t vertex) -{ - char hw_path_name[MAXDEVNAME]; - char *wp, *bp, *sp = NULL; - int widget_num; - long atoi(char *); - int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen); - - - /* Get the full path name of the vertex */ - if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name, - MAXDEVNAME)) - return 0; - - /* Find the widget number in the path name */ - wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/"); - if (wp == NULL) - return 0; - widget_num = atoi(wp+7); - if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F) - return 0; - - /* Find "brick" in the path name */ - bp = strstr(hw_path_name, "brick"); - if (bp == NULL) - return 0; - - /* Find preceding slash */ - sp = bp; - while (sp > hw_path_name) { - sp--; - if (*sp == '/') - break; - } - - /* Invalid if no preceding slash */ - if (!sp) - return 0; - - /* Bump slash pointer to "brick" prefix */ - sp++; - /* - * Verify "brick" prefix length; valid exaples: - * 'I' from "/Ibrick" - * 'P' from "/Pbrick" - * 'X' from "/Xbrick" - */ - if ((bp - sp) != 1) - return 0; - - return (io_brick_map_widget((int)*sp, widget_num)); - -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/module.c linux-2.4.22/arch/ia64/sn/io/sn2/module.c --- linux-2.4.21/arch/ia64/sn/io/sn2/module.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/module.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -261,20 +260,5 @@ nserial); if (nserial == 0) - printk(KERN_WARNING "io_module_init: No serial number found.\n"); -} - -int -get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info) -{ - if (cmod < 0 || cmod >= nummodules) - return -EINVAL; - - mod_info->mod_num = modules[cmod]->id; - - ia64_sn_sys_serial_get(mod_info->serial_str); - - mod_info->serial_num = ia64_sn_partition_serial_get(); - - return 0; + DPRINTF(KERN_WARNING "io_module_init: No serial number found.\n"); } diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pci_bus_cvlink.c linux-2.4.22/arch/ia64/sn/io/sn2/pci_bus_cvlink.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pci_bus_cvlink.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pci_bus_cvlink.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,811 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int bridge_rev_b_data_check_disable; - -devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET]; -nasid_t busnum_to_nid[MAX_PCI_XWIDGET]; -void * busnum_to_atedmamaps[MAX_PCI_XWIDGET]; -unsigned char num_bridges; -static int done_probing = 0; - -static int pci_bus_map_create(devfs_handle_t xtalk); -devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn); - -extern unsigned char Is_pic_on_this_nasid[512]; - -extern void sn_init_irq_desc(void); - - -/* - * For the given device, initialize whether it is a PIC device. - */ -static void -set_isPIC(struct sn_device_sysdata *device_sysdata) -{ - pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);; -} - -/* - * pci_bus_cvlink_init() - To be called once during initialization before - * SGI IO Infrastructure init is called. - */ -void -pci_bus_cvlink_init(void) -{ - - extern void ioconfig_bus_init(void); - - memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET); - memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET); - - memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET); - - num_bridges = 0; - - // ioconfig_bus_init(); -} - -/* - * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated - * pci bus vertex from the SGI IO Infrastructure. - */ -devfs_handle_t -pci_bus_to_vertex(unsigned char busnum) -{ - - devfs_handle_t pci_bus = NULL; - - - /* - * First get the xwidget vertex. - */ - pci_bus = busnum_to_pcibr_vhdl[busnum]; - return(pci_bus); -} - -/* - * devfn_to_vertex() - returns the vertex of the device given the bus, slot, - * and function numbers. - */ -devfs_handle_t -devfn_to_vertex(unsigned char busnum, unsigned int devfn) -{ - - int slot = 0; - int func = 0; - char name[16]; - devfs_handle_t pci_bus = NULL; - devfs_handle_t device_vertex = (devfs_handle_t)NULL; - - /* - * Go get the pci bus vertex. - */ - pci_bus = pci_bus_to_vertex(busnum); - if (!pci_bus) { - /* - * During probing, the Linux pci code invents non existant - * bus numbers and pci_dev structures and tries to access - * them to determine existance. Don't crib during probing. - */ - if (done_probing) - printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum); - return(NULL); - } - - - /* - * Go get the slot&function vertex. - * Should call pciio_slot_func_to_name() when ready. - */ - slot = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* - * For a NON Multi-function card the name of the device looks like: - * ../pci/1, ../pci/2 .. - */ - if (func == 0) { - sprintf(name, "%d", slot); - if (hwgraph_traverse(pci_bus, name, &device_vertex) == - GRAPH_SUCCESS) { - if (device_vertex) { - return(device_vertex); - } - } - } - - /* - * This maybe a multifunction card. It's names look like: - * ../pci/1a, ../pci/1b, etc. - */ - sprintf(name, "%d%c", slot, 'a'+func); - if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) { - if (!device_vertex) { - return(NULL); - } - } - - return(device_vertex); -} - -/* - * For the given device, initialize the addresses for both the Device(x) Flush - * Write Buffer register and the Xbow Flush Register for the port the PCI bus - * is connected. - */ -static void -set_flush_addresses(struct pci_dev *device_dev, - struct sn_device_sysdata *device_sysdata) -{ - pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - nasid_t nasid; - - /* - * Get the nasid from the bridge. - */ - nasid = NASID_GET(device_sysdata->dma_buf_sync); - if (IS_PIC_DEVICE(device_dev)) { - device_sysdata->dma_buf_sync = (volatile unsigned int *) - &bridge->b_wr_req_buf[pciio_slot].reg; - device_sysdata->xbow_buf_sync = (volatile unsigned int *) - XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0), - pcibr_soft->bs_xid); - } else { - /* - * Accessing Xbridge and Xbow register when SHUB swapoper is on!. - */ - device_sysdata->dma_buf_sync = (volatile unsigned int *) - ((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4); - device_sysdata->xbow_buf_sync = (volatile unsigned int *) - ((uint64_t)(XBOW_PRIO_LINKREGS_PTR( - NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4); - } - -#ifdef DEBUG - printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", - device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync); - -printk("set_flush_addresses: dma_buf_sync\n"); - while((volatile unsigned int )*device_sysdata->dma_buf_sync); -printk("set_flush_addresses: xbow_buf_sync\n"); - while((volatile unsigned int )*device_sysdata->xbow_buf_sync); -#endif - -} - -/* - * Most drivers currently do not properly tell the arch specific pci dma - * interfaces whether they can handle A64. Here is where we privately - * keep track of this. - */ -static void __init -set_sn_pci64(struct pci_dev *dev) -{ - unsigned short vendor = dev->vendor; - unsigned short device = dev->device; - - if (vendor == PCI_VENDOR_ID_QLOGIC) { - if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) || - (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) { - SET_PCIA64(dev); - return; - } - } - - if (vendor == PCI_VENDOR_ID_SGI) { - if (device == PCI_DEVICE_ID_SGI_IOC3) { - SET_PCIA64(dev); - return; - } - } - -} - -/* - * sn_pci_fixup() - This routine is called when platform_pci_fixup() is - * invoked at the end of pcibios_init() to link the Linux pci - * infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c - * - * Other platform specific fixup can also be done here. - */ -void -sn_pci_fixup(int arg) -{ - struct list_head *ln; - struct pci_bus *pci_bus = NULL; - struct pci_dev *device_dev = NULL; - struct sn_widget_sysdata *widget_sysdata; - struct sn_device_sysdata *device_sysdata; - pciio_intr_t intr_handle; - int cpuid, bit; - devfs_handle_t device_vertex; - pciio_intr_line_t lines; - extern void sn_pci_find_bios(void); - extern int numnodes; - int cnode; - extern void io_sh_swapper(int, int); - - for (cnode = 0; cnode < numnodes; cnode++) { - if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] ) - io_sh_swapper((cnodeid_to_nasid(cnode)), 0); - } - - if (arg == 0) { -#ifdef CONFIG_PROC_FS - extern void register_sn_partition_id(void); - extern void register_sn_serial_numbers(void); -#endif - - sn_init_irq_desc(); - sn_pci_find_bios(); - for (cnode = 0; cnode < numnodes; cnode++) { - extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int); - intr_init_vecblk(NODEPDA(cnode), cnode, 0); - } - - /* - * When we return to generic Linux, Swapper is always on .. - */ - for (cnode = 0; cnode < numnodes; cnode++) { - if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] ) - io_sh_swapper((cnodeid_to_nasid(cnode)), 1); - } -#ifdef CONFIG_PROC_FS - register_sn_partition_id(); - register_sn_serial_numbers(); -#endif - return; - } - - - done_probing = 1; - - /* - * Initialize the pci bus vertex in the pci_bus struct. - */ - for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { - pci_bus = pci_bus_b(ln); - widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), - GFP_KERNEL); - widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number); - pci_bus->sysdata = (void *)widget_sysdata; - } - - /* - * set the root start and end so that drivers calling check_region() - * won't see a conflict - */ - ioport_resource.start = 0xc000000000000000; - ioport_resource.end = 0xcfffffffffffffff; - - /* - * Set the root start and end for Mem Resource. - */ - iomem_resource.start = 0; - iomem_resource.end = 0xffffffffffffffff; - - /* - * Initialize the device vertex in the pci_dev struct. - */ - pci_for_each_dev(device_dev) { - unsigned int irq; - int idx; - u16 cmd; - devfs_handle_t vhdl; - unsigned long size; - extern int bit_pos_to_irq(int); - - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3) { - extern void pci_fixup_ioc3(struct pci_dev *d); - pci_fixup_ioc3(device_dev); - } - - /* Set the device vertex */ - - device_sysdata = kmalloc(sizeof(struct sn_device_sysdata), - GFP_KERNEL); - device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn); - device_sysdata->isa64 = 0; - /* - * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush - * register addresses. - */ - (void) set_flush_addresses(device_dev, device_sysdata); - - device_dev->sysdata = (void *) device_sysdata; - set_sn_pci64(device_dev); - set_isPIC(device_sysdata); - - pci_read_config_word(device_dev, PCI_COMMAND, &cmd); - - /* - * Set the resources address correctly. The assumption here - * is that the addresses in the resource structure has been - * read from the card and it was set in the card by our - * Infrastructure .. - */ - vhdl = device_sysdata->vhdl; - for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { - size = 0; - size = device_dev->resource[idx].end - - device_dev->resource[idx].start; - if (size) { - device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); - device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET; - } - else - continue; - - device_dev->resource[idx].end = - device_dev->resource[idx].start + size; -#ifdef BRINGUP2 - printk("Device Vendor 0x%x, resource[%d] PIO Address = 0x%lx\n", device_dev->vendor, idx, (long)device_dev->resource[idx].start); -#endif - - if (device_dev->resource[idx].flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - - if (device_dev->resource[idx].flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - /* - * Now handle the ROM resource .. - */ -#if 0 - /* - * Software WAR for a Software BUG. - * This is only temporary. - * See PV 872791 - */ - size = device_dev->resource[PCI_ROM_RESOURCE].end - - device_dev->resource[PCI_ROM_RESOURCE].start; - - if (size) { - device_dev->resource[PCI_ROM_RESOURCE].start = - (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, - size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); - device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET; - device_dev->resource[PCI_ROM_RESOURCE].end = - device_dev->resource[PCI_ROM_RESOURCE].start + size; - } -#endif - - /* - * Update the Command Word on the Card. - */ - cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */ - /* bit gets dropped .. no harm */ - pci_write_config_word(device_dev, PCI_COMMAND, cmd); - - pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines); - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { - lines = 1; - } - - device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata; - device_vertex = device_sysdata->vhdl; - - intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex); - - bit = intr_handle->pi_irq; - cpuid = intr_handle->pi_cpu; - irq = bit; - irq = irq + (cpuid << 8); - pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0); - device_dev->irq = irq; -#ifdef ajmtestintr - { - int slot = PCI_SLOT(device_dev->devfn); - static int timer_set = 0; - pcibr_intr_t pcibr_intr = (pcibr_intr_t)intr_handle; - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - extern void intr_test_handle_intr(int, void*, struct pt_regs *); - - if (!timer_set) { - intr_test_set_timer(); - timer_set = 1; - } - intr_test_register_irq(irq, pcibr_soft, slot); - request_irq(irq, intr_test_handle_intr,0,NULL, NULL); - } -#endif - - } - - for (cnode = 0; cnode < numnodes; cnode++) { - if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] ) - io_sh_swapper((cnodeid_to_nasid(cnode)), 1); - } -} - -/* - * linux_bus_cvlink() Creates a link between the Linux PCI Bus number - * to the actual hardware component that it represents: - * /dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci - */ -void -linux_bus_cvlink(void) -{ - char name[8]; - int index; - - for (index=0; index < MAX_PCI_XWIDGET; index++) { - if (!busnum_to_pcibr_vhdl[index]) - continue; - - sprintf(name, "%d", index); - (void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], - name); - } -} - -/* - * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. - * - * Linux PCI Bus numbers are assigned from lowest module_id numbers - * (rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to - * HUB_WIDGET_ID_MIN: - * widgetnum 15 gets lower Bus Number than widgetnum 14 etc. - * - * Given 2 modules 001c01 and 001c02 we get the following mappings: - * 001c01, widgetnum 15 = Bus number 0 - * 001c01, widgetnum 14 = Bus number 1 - * 001c02, widgetnum 15 = Bus number 3 - * 001c02, widgetnum 14 = Bus number 4 - * etc. - * - * The rational for starting Bus Number 0 with Widget number 15 is because - * the system boot disks are always connected via Widget 15 Slot 0 of the - * I-brick. Linux creates /dev/sd* devices(naming) strating from Bus Number 0 - * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest - * module id(Master Cnode) of the system. - * - */ -static int -pci_bus_map_create(devfs_handle_t xtalk) -{ - - devfs_handle_t master_node_vertex = NULL; - devfs_handle_t xwidget = NULL; - devfs_handle_t pci_bus = NULL; - hubinfo_t hubinfo = NULL; - xwidgetnum_t widgetnum; - char pathname[128]; - graph_error_t rv; - int bus; - - /* - * Loop throught this vertex and get the Xwidgets .. - */ - - - /* PCI devices */ - - for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) { - -#if 0 - { - int pos; - char dname[256]; - pos = devfs_generate_path(xtalk, dname, 256); - printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); - } -#endif - - sprintf(pathname, "%d", widgetnum); - xwidget = NULL; - - /* - * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget - * /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device - */ - rv = hwgraph_traverse(xtalk, pathname, &xwidget); - if ( (rv != GRAPH_SUCCESS) ) { - if (!xwidget) { - continue; -} - } - - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); - pci_bus = NULL; - if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) - if (!pci_bus) { - continue; -} - - /* - * Assign the correct bus number and also the nasid of this - * pci Xwidget. - * - * Should not be any race here ... - */ - num_bridges++; - busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus; - - /* - * Get the master node and from there get the NASID. - */ - master_node_vertex = device_master_get(xwidget); - if (!master_node_vertex) { - printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget); - } - - hubinfo_get(master_node_vertex, &hubinfo); - if (!hubinfo) { - printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex); - return(1); - } else { - busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; - } - - /* - * Pre assign DMA maps needed for 32 Bits Page Map DMA. - */ - busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc( - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); - if (!busnum_to_atedmamaps[num_bridges - 1]) - printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); - - memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); - - } - - /* - * PCIX devices - * We number busses differently for PCI-X devices. - * We start from Lowest Widget on up .. - */ - - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { - - /* Do both buses */ - for ( bus = 0; bus < 2; bus++ ) { - sprintf(pathname, "%d", widgetnum); - xwidget = NULL; - - /* - * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget - * /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus - * /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device - */ - rv = hwgraph_traverse(xtalk, pathname, &xwidget); - if ( (rv != GRAPH_SUCCESS) ) { - if (!xwidget) { - continue; - } - } - - if ( bus == 0 ) - sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum); - else - sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum); - pci_bus = NULL; - if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) - if (!pci_bus) { - continue; - } - - /* - * Assign the correct bus number and also the nasid of this - * pci Xwidget. - * - * Should not be any race here ... - */ - num_bridges++; - busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus; - - /* - * Get the master node and from there get the NASID. - */ - master_node_vertex = device_master_get(xwidget); - if (!master_node_vertex) { - printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget); - } - - hubinfo_get(master_node_vertex, &hubinfo); - if (!hubinfo) { - printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex); - return(1); - } else { - busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; - } - - /* - * Pre assign DMA maps needed for 32 Bits Page Map DMA. - */ - busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc( - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); - if (!busnum_to_atedmamaps[num_bridges - 1]) - printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); - - memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); - } - } - - return(0); -} - -/* - * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure - * initialization has completed to set up the mappings between Xbridge - * and logical pci bus numbers. We also set up the NASID for each of these - * xbridges. - * - * Must be called before pci_init() is invoked. - */ -int -pci_bus_to_hcl_cvlink(void) -{ - - devfs_handle_t devfs_hdl = NULL; - devfs_handle_t xtalk = NULL; - int rv = 0; - char name[256]; - char tmp_name[256]; - int master_iobrick; - slabid_t master_slab; - int i, ii; - extern nasid_t master_baseio_nasid; - extern nasid_t get_master_baseio_nasid(void); - - /* - * Iterate throught each xtalk links in the system .. - * /hw/module/001c01/slab/0/node/xtalk/ 8|9|10|11|12|13|14|15 - * - * /hw/module/001c01/slab/0/node/xtalk/15 -> /hw/module/001c01/slab/0/Ibrick/xtalk/15 - * - * What if it is not pci? - */ - devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module"); - - /* - * To provide consistent(not persistent) device naming, we need to start - * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 - * with an attached I-Brick. Find the master_iobrick. - */ - master_baseio_nasid = get_master_baseio_nasid(); - master_iobrick = -1; - master_slab = -1; - if ( master_baseio_nasid >= 0 ) { - /* Valid nasid, need the slab ID */ - for (i = 0; i < nummodules; i++) { - extern int iobrick_module_get_nasid(nasid_t); - moduleid_t iobrick_id; - nasid_t nasid = -1; - int n = 0; - for ( n = 0; n < modules[i]->nodecnt; n++ ) { - nasid = cnodeid_to_nasid(modules[i]->nodes[n]); - iobrick_id = iobrick_module_get_nasid(nasid); - if (iobrick_id > 0) { /* Valid module id */ - if ( master_baseio_nasid == nasid ) { - master_iobrick = i; - master_slab = geo_slab(modules[i]->geoid[n]); - printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Base I/O nasid %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_baseio_nasid, master_iobrick, master_slab); - break; - } - } - } - if (master_slab >= 0) - break; - } - } - else { - /* Not sure which nasid it is - call failed, so make a guess */ - for (i = 0; i < nummodules; i++) { - extern int iobrick_module_get_nasid(nasid_t); - moduleid_t iobrick_id; - nasid_t nasid = -1; - int n = 0; - for ( n = 0; n < modules[i]->nodecnt; n++ ) { - nasid = cnodeid_to_nasid(modules[i]->nodes[n]); - iobrick_id = iobrick_module_get_nasid(nasid); - if (iobrick_id > 0) { /* Valid module id */ - if ( (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) || - (MODULE_GET_BTYPE(iobrick_id) == MODULE_PXBRICK) || - (MODULE_GET_BTYPE(iobrick_id) == MODULE_PBRICK) ) { - master_iobrick = i; - master_baseio_nasid = nasid; - master_slab = geo_slab(modules[i]->geoid[n]); - printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_iobrick, master_slab); - break; - } - } - } - if (master_iobrick >= 0) - break; - } - } - - if (master_iobrick == -1) { - panic("Unable to find the Master BaseIO PCI/PCIX Bus\n"); - } - - /* - * The master_iobrick gets bus 0 and 1. - */ - if (master_iobrick >= 0) { - memset(name, 0, 256); - memset(tmp_name, 0, 256); - format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF); - sprintf(tmp_name, "/slab/%d/node/xtalk", master_slab); - strcat(name, tmp_name); - xtalk = NULL; - rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); - pci_bus_map_create(xtalk); - } - - /* - * Now go do the rest of the modules, starting from the C-Brick with the lowest - * module id, remembering to skip the master_iobrick, which was done above. - */ - for (i = 0; i < nummodules ; i++) { - for ( ii = 0; ii < MAX_SLABS; ii++ ) { - if ((i == master_iobrick) && (master_slab == ii)) - continue; /* Did the master_iobrick/slab already. */ - memset(name, 0, 256); - memset(tmp_name, 0, 256); - format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF); - sprintf(tmp_name, "/slab/%d/node/xtalk", ii); - strcat(name, tmp_name); - xtalk = NULL; - rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); - pci_bus_map_create(xtalk); - } - } - - /* - * Create the Linux PCI bus number vertex link. - */ - (void)linux_bus_cvlink(); - - return(0); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/Makefile linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/Makefile --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/Makefile 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -3,21 +3,20 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 2002 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. # # Makefile for the sn2 io pcibr routines. EXTRA_CFLAGS := -DLITTLE_ENDIAN -ifdef CONFIG_IA64_SGI_SN2 EXTRA_CFLAGS += -DSHUB_SWAP_WAR -endif O_TARGET := pcibr.o +export-objs := pcibr_intr.o -obj-$(CONFIG_IA64_SGI_SN2) += pcibr_dvr.o pcibr_ate.o pcibr_config.o \ - pcibr_dvr.o pcibr_hints.o \ - pcibr_intr.o pcibr_rrb.o pcibr_slot.o \ - pcibr_error.o +obj-y += pcibr_ate.o pcibr_config.o \ + pcibr_dvr.o pcibr_hints.o \ + pcibr_intr.o pcibr_rrb.o pcibr_slot.o \ + pcibr_error.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c 2003-06-13 07:51:30.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -27,23 +27,9 @@ #include #include #include -#include #include #include -#ifdef __ia64 -uint64_t atealloc(struct map *mp, size_t size); -void atefree(struct map *mp, size_t size, uint64_t a); -void atemapfree(struct map *mp); -struct map *atemapalloc(uint64_t mapsiz); - -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - - #ifndef LOCAL #define LOCAL static #endif @@ -101,73 +87,26 @@ int i, j; bridgereg_t old_enable, new_enable; int s; - int this_is_pic = is_pic(bridge); /* Probe SSRAM to determine its size. */ - if ( this_is_pic ) { - old_enable = bridge->b_int_enable; - new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - bridge->b_int_enable = new_enable; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - old_enable = BRIDGE_REG_GET32((&bridge->b_int_enable)); - new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - BRIDGE_REG_SET32((&bridge->b_int_enable)) = new_enable; - } - else { - old_enable = bridge->b_int_enable; - new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - bridge->b_int_enable = new_enable; - } - } + old_enable = bridge->b_int_enable; + new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; + bridge->b_int_enable = new_enable; for (i = 1; i < ATE_NUM_SIZES; i++) { /* Try writing a value */ - if ( this_is_pic ) { - bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) - bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = __swab64(ATE_PROBE_VALUE); - else - bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE; - } + bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE; /* Guard against wrap */ for (j = 1; j < i; j++) bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0; /* See if value was written */ - if ( this_is_pic ) { - if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE) + if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE) largest_working_size = i; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == __swab64(ATE_PROBE_VALUE)) - largest_working_size = i; - else { - if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE) - largest_working_size = i; - } - } - } - } - if ( this_is_pic ) { - bridge->b_int_enable = old_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_int_enable)) = old_enable; - BRIDGE_REG_GET32((&bridge->b_wid_tflush)); /* wait until Bridge PIO complete */ - } - else { - bridge->b_int_enable = old_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } } + bridge->b_int_enable = old_enable; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ /* * ensure that we write and read without any interruption. @@ -175,26 +114,10 @@ */ s = splhi(); - if ( this_is_pic ) { - bridge->b_wid_control = (bridge->b_wid_control + bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK) | BRIDGE_CTRL_SSRAM_SIZE(largest_working_size); - bridge->b_wid_control; /* inval addr bug war */ - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&(bridge->b_wid_control))) = - __swab32((BRIDGE_REG_GET32((&bridge->b_wid_control)) - & ~BRIDGE_CTRL_SSRAM_SIZE_MASK) - | BRIDGE_CTRL_SSRAM_SIZE(largest_working_size)); - BRIDGE_REG_GET32((&bridge->b_wid_control));/* inval addr bug war */ - } - else { - bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK) - | BRIDGE_CTRL_SSRAM_SIZE(largest_working_size); - bridge->b_wid_control; /* inval addr bug war */ - } - } + bridge->b_wid_control; /* inval addr bug war */ splx(s); num_entries = ATE_NUM_ENTRIES(largest_working_size); @@ -229,32 +152,55 @@ int pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count) { - int index = 0; - - index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count); + int status = 0; + struct resource *new_res; + struct resource **allocated_res; + + new_res = (struct resource *) kmalloc( sizeof(struct resource), GFP_ATOMIC); + memset(new_res, 0, sizeof(*new_res)); + status = allocate_resource( &pcibr_soft->bs_int_ate_resource, new_res, + count, pcibr_soft->bs_int_ate_resource.start, + pcibr_soft->bs_int_ate_resource.end, 1, + NULL, NULL); + + if ( status && (pcibr_soft->bs_ext_ate_resource.end != 0) ) { + status = allocate_resource( &pcibr_soft->bs_ext_ate_resource, new_res, + count, pcibr_soft->bs_ext_ate_resource.start, + pcibr_soft->bs_ext_ate_resource.end, 1, + NULL, NULL); + if (status) { + new_res->start = -1; + } + } - if (!index && pcibr_soft->bs_ext_ate_map) - index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count); + if (status) { + /* Failed to allocate */ + kfree(new_res); + return -1; + } + + /* Save the resource for freeing */ + allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + new_res->start * sizeof( unsigned long)); + *allocated_res = new_res; - /* rmalloc manages resources in the 1..n - * range, with 0 being failure. - * pcibr_ate_alloc manages resources - * in the 0..n-1 range, with -1 being failure. - */ - return index - 1; + return new_res->start; } void pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count) /* Who says there's no such thing as a free meal? :-) */ { - /* note the "+1" since rmalloc handles 1..n but - * we start counting ATEs at zero. - */ - rmfree((index < pcibr_soft->bs_int_ate_size) - ? pcibr_soft->bs_int_ate_map - : pcibr_soft->bs_ext_ate_map, - count, index + 1); + + struct resource **allocated_res; + int status = 0; + + allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + index * sizeof(unsigned long)); + + status = release_resource(*allocated_res); + if (status) + BUG(); /* Ouch .. */ + kfree(*allocated_res); + } /* @@ -362,7 +308,7 @@ /* Bridge Hardware Bug WAR #484930: * Bridge can't handle updating External ATEs - * while DMA is occuring that uses External ATEs, + * while DMA is occurring that uses External ATEs, * even if the particular ATEs involved are disjoint. */ @@ -423,16 +369,7 @@ /* Flush the write buffer associated with this * PCI device which might be using dma map RAM. */ - if ( is_pic(bridge) ) { - bridge->b_wr_req_buf[slot].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge)) ) { - BRIDGE_REG_GET32((&bridge->b_wr_req_buf[slot].reg)); - } - else - bridge->b_wr_req_buf[slot].reg; - } + bridge->b_wr_req_buf[slot].reg; } } } diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -28,21 +28,18 @@ #include #include #include -#include #include #include -extern pcibr_info_t pcibr_info_get(devfs_handle_t); +extern pcibr_info_t pcibr_info_get(vertex_hdl_t); -uint64_t pcibr_config_get(devfs_handle_t, unsigned, unsigned); -uint64_t do_pcibr_config_get(int, cfg_p, unsigned, unsigned); -void pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t); -void do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t); -static void swap_do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); +uint64_t pcibr_config_get(vertex_hdl_t, unsigned, unsigned); +uint64_t do_pcibr_config_get(cfg_p, unsigned, unsigned); +void pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t); +void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); -#ifdef LITTLE_ENDIAN /* - * on sn-ia we need to twiddle the addresses going out + * on sn-ia we need to twiddle the the addresses going out * the pci bus because we use the unswizzled synergy space * (the alternative is to use the swizzled synergy space * and byte swap the data) @@ -51,18 +48,13 @@ #define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)]) #define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)]) -#define CBP(b,r) (((volatile uint8_t *) b)[(r)^3]) -#define CSP(b,r) (((volatile uint16_t *) b)[((r)/2)^1]) +#define CBP(b,r) (((volatile uint8_t *) b)[(r)]) +#define CSP(b,r) (((volatile uint16_t *) b)[((r)/2)]) #define CWP(b,r) (((volatile uint32_t *) b)[(r)/4]) #define SCB(b,r) (((volatile uint8_t *) b)[((r)^3)]) #define SCS(b,r) (((volatile uint16_t *) b)[((r^2)/2)]) #define SCW(b,r) (((volatile uint32_t *) b)[((r)/4)]) -#else -#define CB(b,r) (((volatile uint8_t *) cfgbase)[(r)^3]) -#define CS(b,r) (((volatile uint16_t *) cfgbase)[((r)/2)^1]) -#define CW(b,r) (((volatile uint32_t *) cfgbase)[(r)/4]) -#endif /* * Return a config space address for given slot / func / offset. Note the @@ -84,8 +76,7 @@ /* * Type 0 config space */ - if (is_pic(bridge)) - slot++; + slot++; return &bridge->b_type0_cfg_dev[slot].f[func].l[offset]; } @@ -109,7 +100,7 @@ cfg_p cfg_base; cfg_base = pcibr_slot_config_addr(bridge, slot, 0); - return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned))); + return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned))); } /* @@ -122,7 +113,7 @@ cfg_p cfg_base; cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0); - return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned))); + return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned))); } /* @@ -135,7 +126,7 @@ cfg_p cfg_base; cfg_base = pcibr_slot_config_addr(bridge, slot, 0); - do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val); + do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val); } /* @@ -148,13 +139,13 @@ cfg_p cfg_base; cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0); - do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val); + do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val); } int pcibr_config_debug = 0; cfg_p -pcibr_config_addr(devfs_handle_t conn, +pcibr_config_addr(vertex_hdl_t conn, unsigned reg) { pcibr_info_t pcibr_info; @@ -183,19 +174,6 @@ pciio_func = PCI_TYPE1_FUNC(reg); ASSERT(pciio_bus != 0); -#if 0 - } else if (conn != pciio_info_hostdev_get(pciio_info)) { - /* - * Conn is on a subordinate bus, so get bus/slot/func directly from - * its pciio_info_t structure. - */ - pciio_bus = pciio_info->c_bus; - pciio_slot = pciio_info->c_slot; - pciio_func = pciio_info->c_func; - if (pciio_func == PCIIO_FUNC_NONE) { - pciio_func = 0; - } -#endif } else { /* * Conn is directly connected to the host bus. PCI bus number is @@ -224,44 +202,23 @@ return cfgbase; } -extern unsigned char Is_pic_on_this_nasid[]; uint64_t -pcibr_config_get(devfs_handle_t conn, +pcibr_config_get(vertex_hdl_t conn, unsigned reg, unsigned size) { - if ( !Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] ) - return do_pcibr_config_get(0, pcibr_config_addr(conn, reg), - PCI_TYPE1_REG(reg), size); - else - return do_pcibr_config_get(1, pcibr_config_addr(conn, reg), + return do_pcibr_config_get(pcibr_config_addr(conn, reg), PCI_TYPE1_REG(reg), size); } uint64_t -do_pcibr_config_get( - int pic, - cfg_p cfgbase, +do_pcibr_config_get(cfg_p cfgbase, unsigned reg, unsigned size) { unsigned value; - if ( pic ) { - value = CWP(cfgbase, reg); - } - else { - if ( io_get_sh_swapper(NASID_GET(cfgbase)) ) { - /* - * Shub Swapper on - 0 returns PCI Offset 0 but byte swapped! - * Do not swizzle address and byte swap the result. - */ - value = SCW(cfgbase, reg); - value = __swab32(value); - } else { - value = CW(cfgbase, reg); - } - } + value = CWP(cfgbase, reg); if (reg & 3) value >>= 8 * (reg & 3); if (size < 4) @@ -270,108 +227,43 @@ } void -pcibr_config_set(devfs_handle_t conn, +pcibr_config_set(vertex_hdl_t conn, unsigned reg, unsigned size, uint64_t value) { - if ( Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] ) - do_pcibr_config_set(1, pcibr_config_addr(conn, reg), - PCI_TYPE1_REG(reg), size, value); - else - swap_do_pcibr_config_set(pcibr_config_addr(conn, reg), + do_pcibr_config_set(pcibr_config_addr(conn, reg), PCI_TYPE1_REG(reg), size, value); } void -do_pcibr_config_set(int pic, - cfg_p cfgbase, +do_pcibr_config_set(cfg_p cfgbase, unsigned reg, unsigned size, uint64_t value) { - if ( pic ) { - switch (size) { - case 1: + switch (size) { + case 1: + CBP(cfgbase, reg) = value; + break; + case 2: + if (reg & 1) { CBP(cfgbase, reg) = value; - break; - case 2: - if (reg & 1) { - CBP(cfgbase, reg) = value; - CBP(cfgbase, reg + 1) = value >> 8; - } else - CSP(cfgbase, reg) = value; - break; - case 3: - if (reg & 1) { - CBP(cfgbase, reg) = value; - CSP(cfgbase, (reg + 1)) = value >> 8; - } else { - CSP(cfgbase, reg) = value; - CBP(cfgbase, reg + 2) = value >> 16; - } - break; - case 4: - CWP(cfgbase, reg) = value; - break; - } - } - else { - switch (size) { - case 1: - CB(cfgbase, reg) = value; - break; - case 2: - if (reg & 1) { - CB(cfgbase, reg) = value; - CB(cfgbase, reg + 1) = value >> 8; - } else - CS(cfgbase, reg) = value; - break; - case 3: - if (reg & 1) { - CB(cfgbase, reg) = value; - CS(cfgbase, (reg + 1)) = value >> 8; - } else { - CS(cfgbase, reg) = value; - CB(cfgbase, reg + 2) = value >> 16; - } - break; - case 4: - CW(cfgbase, reg) = value; - break; - } - } -} - -void -swap_do_pcibr_config_set(cfg_p cfgbase, - unsigned reg, - unsigned size, - uint64_t value) -{ - - uint64_t temp_value = 0; - - switch (size) { - case 1: - SCB(cfgbase, reg) = value; - break; - case 2: - temp_value = __swab16(value); - if (reg & 1) { - SCB(cfgbase, reg) = temp_value; - SCB(cfgbase, reg + 1) = temp_value >> 8; - } else - SCS(cfgbase, reg) = temp_value; - break; - case 3: - BUG(); - break; - - case 4: - temp_value = __swab32(value); - SCW(cfgbase, reg) = temp_value; - break; - } + CBP(cfgbase, reg + 1) = value >> 8; + } else + CSP(cfgbase, reg) = value; + break; + case 3: + if (reg & 1) { + CBP(cfgbase, reg) = value; + CSP(cfgbase, (reg + 1)) = value >> 8; + } else { + CSP(cfgbase, reg) = value; + CBP(cfgbase, reg + 2) = value >> 16; + } + break; + case 4: + CWP(cfgbase, reg) = value; + break; + } } diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,13 +4,17 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include #include #include +#include +#include +#include #include +#include #include #include #include @@ -18,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -27,17 +32,9 @@ #include #include #include -#include #include #include -#ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - /* * global variables to toggle the different levels of pcibr debugging. * -pcibr_debug_mask is the mask of the different types of debugging @@ -74,32 +71,6 @@ #define USS302_BRIDGE_TIMEOUT_HLD 4 #endif -int pcibr_devflag = D_MP; - -/* - * This is the file operation table for the pcibr driver. - * As each of the functions are implemented, put the - * appropriate function name below. - */ -struct file_operations pcibr_fops = { - owner: THIS_MODULE, - llseek: NULL, - read: NULL, - write: NULL, - readdir: NULL, - poll: NULL, - ioctl: NULL, - mmap: NULL, - open: NULL, - flush: NULL, - release: NULL, - fsync: NULL, - fasync: NULL, - lock: NULL, - readv: NULL, - writev: NULL -}; - /* kbrick widgetnum-to-bus layout */ int p_busnum[MAX_PORT_NUM] = { /* widget# */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ @@ -116,17 +87,16 @@ pcibr_list_p pcibr_list = 0; #endif -extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen); -extern int hub_device_flags_set(devfs_handle_t widget_dev, hub_widget_flags_t flags); +extern int hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen); extern long atoi(register char *p); -extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl); -extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen); +extern cnodeid_t nodevertex_to_cnodeid(vertex_hdl_t vhdl); +extern char *dev_to_name(vertex_hdl_t dev, char *buf, uint buflen); extern struct map *atemapalloc(uint64_t); extern void atefree(struct map *, size_t, uint64_t); extern void atemapfree(struct map *); -extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t); +extern pciio_dmamap_t get_free_pciio_dmamap(vertex_hdl_t); extern void free_pciio_dmamap(pcibr_dmamap_t); -extern void xwidget_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t); +extern void xwidget_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t); #define ATE_WRITE() ate_write(pcibr_soft, ate_ptr, ate_count, ate) #if PCIBR_FREEZE_TIME @@ -153,9 +123,9 @@ extern int do_pcibr_rrb_free_all(pcibr_soft_t, bridge_t *, pciio_slot_t); extern void do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int); -extern int pcibr_wrb_flush(devfs_handle_t); -extern int pcibr_rrb_alloc(devfs_handle_t, int *, int *); -extern void pcibr_rrb_flush(devfs_handle_t); +extern int pcibr_wrb_flush(vertex_hdl_t); +extern int pcibr_rrb_alloc(vertex_hdl_t, int *, int *); +extern void pcibr_rrb_flush(vertex_hdl_t); static int pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t); void pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t); @@ -166,21 +136,15 @@ extern iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, pciio_space_t, int, int, int); -void pcibr_init(void); -int pcibr_attach(devfs_handle_t); -int pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t, +int pcibr_attach(vertex_hdl_t); +int pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t, int, pcibr_soft_t *); -int pcibr_detach(devfs_handle_t); -int pcibr_open(devfs_handle_t *, int, int, cred_t *); -int pcibr_close(devfs_handle_t, int, int, cred_t *); -int pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); -int pcibr_unmap(devfs_handle_t, vhandl_t *); -int pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); +int pcibr_detach(vertex_hdl_t); int pcibr_pcix_rbars_calc(pcibr_soft_t); extern int pcibr_init_ext_ate_ram(bridge_t *); extern int pcibr_ate_alloc(pcibr_soft_t, int); extern void pcibr_ate_free(pcibr_soft_t, int, int); -extern int pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl); +extern int pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl); extern unsigned ate_freeze(pcibr_dmamap_t pcibr_dmamap, #if PCIBR_FREEZE_TIME @@ -197,45 +161,43 @@ unsigned *cmd_regs, unsigned s); -pcibr_info_t pcibr_info_get(devfs_handle_t); +pcibr_info_t pcibr_info_get(vertex_hdl_t); -static iopaddr_t pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned); +static iopaddr_t pcibr_addr_pci_to_xio(vertex_hdl_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned); -pcibr_piomap_t pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); +pcibr_piomap_t pcibr_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); void pcibr_piomap_free(pcibr_piomap_t); caddr_t pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t); void pcibr_piomap_done(pcibr_piomap_t); -caddr_t pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); -iopaddr_t pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); -void pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); +caddr_t pcibr_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); +iopaddr_t pcibr_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t); +void pcibr_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t); static iopaddr_t pcibr_flags_to_d64(unsigned, pcibr_soft_t); extern bridge_ate_t pcibr_flags_to_ate(unsigned); -pcibr_dmamap_t pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +pcibr_dmamap_t pcibr_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned); void pcibr_dmamap_free(pcibr_dmamap_t); extern bridge_ate_p pcibr_ate_addr(pcibr_soft_t, int); static iopaddr_t pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t); iopaddr_t pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t); -alenlist_t pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned); void pcibr_dmamap_done(pcibr_dmamap_t); -cnodeid_t pcibr_get_dmatrans_node(devfs_handle_t); -iopaddr_t pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +cnodeid_t pcibr_get_dmatrans_node(vertex_hdl_t); +iopaddr_t pcibr_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned); void pcibr_dmamap_drain(pcibr_dmamap_t); -void pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); -void pcibr_dmalist_drain(devfs_handle_t, alenlist_t); +void pcibr_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t); +void pcibr_dmalist_drain(vertex_hdl_t, alenlist_t); iopaddr_t pcibr_dmamap_pciaddr_get(pcibr_dmamap_t); extern unsigned pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines, int nslots); -extern pcibr_intr_t pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +extern pcibr_intr_t pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t); extern void pcibr_intr_free(pcibr_intr_t); extern void pcibr_setpciint(xtalk_intr_t); extern int pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t); extern void pcibr_intr_disconnect(pcibr_intr_t); -extern devfs_handle_t pcibr_intr_cpu_get(pcibr_intr_t); +extern vertex_hdl_t pcibr_intr_cpu_get(pcibr_intr_t); extern void pcibr_intr_func(intr_arg_t); extern void print_bridge_errcmd(uint32_t, char *); @@ -253,51 +215,48 @@ extern int pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *); extern int pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *); extern int pcibr_error_handler_wrapper(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *); -void pcibr_provider_startup(devfs_handle_t); -void pcibr_provider_shutdown(devfs_handle_t); +void pcibr_provider_startup(vertex_hdl_t); +void pcibr_provider_shutdown(vertex_hdl_t); -int pcibr_reset(devfs_handle_t); -pciio_endian_t pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); +int pcibr_reset(vertex_hdl_t); +pciio_endian_t pcibr_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t); int pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t); -pciio_priority_t pcibr_priority_set(devfs_handle_t, pciio_priority_t); -int pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t); +pciio_priority_t pcibr_priority_set(vertex_hdl_t, pciio_priority_t); +int pcibr_device_flags_set(vertex_hdl_t, pcibr_device_flags_t); + +extern cfg_p pcibr_config_addr(vertex_hdl_t, unsigned); +extern uint64_t pcibr_config_get(vertex_hdl_t, unsigned, unsigned); +extern void pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t); + +extern pcibr_hints_t pcibr_hints_get(vertex_hdl_t, int); +extern void pcibr_hints_fix_rrbs(vertex_hdl_t); +extern void pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t); +extern void pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *); +extern void pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t); +extern void pcibr_hints_handsoff(vertex_hdl_t); +extern void pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t); -extern cfg_p pcibr_config_addr(devfs_handle_t, unsigned); -extern uint64_t pcibr_config_get(devfs_handle_t, unsigned, unsigned); -extern void pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t); - -extern pcibr_hints_t pcibr_hints_get(devfs_handle_t, int); -extern void pcibr_hints_fix_rrbs(devfs_handle_t); -extern void pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t); -extern void pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *); -extern void pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t); -extern void pcibr_hints_handsoff(devfs_handle_t); -extern void pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t); - -extern int pcibr_slot_reset(devfs_handle_t,pciio_slot_t); -extern int pcibr_slot_info_init(devfs_handle_t,pciio_slot_t); -extern int pcibr_slot_info_free(devfs_handle_t,pciio_slot_t); +extern int pcibr_slot_info_init(vertex_hdl_t,pciio_slot_t); +extern int pcibr_slot_info_free(vertex_hdl_t,pciio_slot_t); extern int pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t, pcibr_slot_info_resp_t); extern void pcibr_slot_func_info_return(pcibr_info_h, int, pcibr_slot_func_info_resp_t); -extern int pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t); +extern int pcibr_slot_addr_space_init(vertex_hdl_t,pciio_slot_t); extern int pcibr_slot_pcix_rbar_init(pcibr_soft_t, pciio_slot_t); -extern int pcibr_slot_device_init(devfs_handle_t, pciio_slot_t); -extern int pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t); -extern int pcibr_slot_call_device_attach(devfs_handle_t, +extern int pcibr_slot_device_init(vertex_hdl_t, pciio_slot_t); +extern int pcibr_slot_guest_info_init(vertex_hdl_t,pciio_slot_t); +extern int pcibr_slot_call_device_attach(vertex_hdl_t, pciio_slot_t, int); -extern int pcibr_slot_call_device_detach(devfs_handle_t, +extern int pcibr_slot_call_device_detach(vertex_hdl_t, pciio_slot_t, int); -extern int pcibr_slot_attach(devfs_handle_t, pciio_slot_t, int, +extern int pcibr_slot_attach(vertex_hdl_t, pciio_slot_t, int, char *, int *); -extern int pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int, +extern int pcibr_slot_detach(vertex_hdl_t, pciio_slot_t, int, char *, int *); -extern int pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t); - -extern int pcibr_slot_initial_rrb_alloc(devfs_handle_t, pciio_slot_t); -extern int pcibr_initial_rrb(devfs_handle_t, pciio_slot_t, pciio_slot_t); +extern int pcibr_slot_initial_rrb_alloc(vertex_hdl_t, pciio_slot_t); +extern int pcibr_initial_rrb(vertex_hdl_t, pciio_slot_t, pciio_slot_t); /* ===================================================================== * Device(x) register management @@ -623,172 +582,52 @@ */ -/* - * pcibr_init: called once during system startup or - * when a loadable driver is loaded. - * - * The driver_register function should normally - * be in _reg, not _init. But the pcibr driver is - * required by devinit before the _reg routines - * are called, so this is an exception. - */ -void -pcibr_init(void) +static int +pcibr_mmap(struct file * file, struct vm_area_struct * vma) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pcibr_init()\n")); + vertex_hdl_t pcibr_vhdl; + pcibr_soft_t pcibr_soft; + bridge_t *bridge; + unsigned long phys_addr; + int error = 0; - xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM, - XBRIDGE_WIDGET_MFGR_NUM, - "pcibr_", - 0); - xwidget_driver_register(BRIDGE_WIDGET_PART_NUM, - BRIDGE_WIDGET_MFGR_NUM, - "pcibr_", - 0); +#ifdef CONFIG_HWGFS_FS + pcibr_vhdl = (vertex_hdl_t) file->f_dentry->d_fsdata; +#else + pcibr_vhdl = (vertex_hdl_t) file->private_data; +#endif + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + bridge = pcibr_soft->bs_base; + phys_addr = (unsigned long)bridge & ~0xc000000000000000; /* Mask out the Uncache bits */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO; + error = io_remap_page_range(vma->vm_start, phys_addr, + vma->vm_end-vma->vm_start, + vma->vm_page_prot); + return(error); } /* - * open/close mmap/munmap interface would be used by processes - * that plan to map the PCI bridge, and muck around with the - * registers. This is dangerous to do, and will be allowed - * to a select brand of programs. Typically these are - * diagnostics programs, or some user level commands we may - * write to do some weird things. - * To start with expect them to have root priveleges. - * We will ask for more later. + * This is the file operation table for the pcibr driver. + * As each of the functions are implemented, put the + * appropriate function name below. */ -/* ARGSUSED */ -int -pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) -{ - return 0; -} - -/*ARGSUSED */ -int -pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) -{ - return 0; -} - -/*ARGSUSED */ -int -pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) -{ - int error; - devfs_handle_t vhdl = dev_to_vhdl(dev); - devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get(vhdl); - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge_t *bridge = pcibr_soft->bs_base; - - hwgraph_vertex_unref(pcibr_vhdl); - - ASSERT(pcibr_soft); - len = ctob(btoc(len)); /* Make len page aligned */ - error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len); - - /* - * If the offset being mapped corresponds to the flash prom - * base, and if the mapping succeeds, and if the user - * has requested the protections to be WRITE, enable the - * flash prom to be written. - * - * XXX- deprecate this in favor of using the - * real flash driver ... - */ - if (IS_BRIDGE_SOFT(pcibr_soft) && !error && - ((off == BRIDGE_EXTERNAL_FLASH) || - (len > BRIDGE_EXTERNAL_FLASH))) { - int s; - - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - s = splhi(); - - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_wid_control)) |= __swab32(BRIDGE_CTRL_FLASH_WR_EN); - BRIDGE_REG_GET32((&bridge->b_wid_control)); /* inval addr bug war */ - } else { - bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN; - bridge->b_wid_control; /* inval addr bug war */ - } - splx(s); - } - return error; -} - -/*ARGSUSED */ -int -pcibr_unmap(devfs_handle_t dev, vhandl_t *vt) -{ - devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev); - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge_t *bridge = pcibr_soft->bs_base; - - hwgraph_vertex_unref(pcibr_vhdl); - - if ( IS_PIC_SOFT(pcibr_soft) ) { - /* - * If flashprom write was enabled, disable it, as - * this is the last unmap. - */ - if (IS_BRIDGE_SOFT(pcibr_soft) && - (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN)) { - int s; - - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - s = splhi(); - bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN; - bridge->b_wid_control; /* inval addr bug war */ - splx(s); - } - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - if (BRIDGE_REG_GET32((&bridge->b_wid_control)) & BRIDGE_CTRL_FLASH_WR_EN) { - int s; - - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - s = splhi(); - BRIDGE_REG_SET32((&bridge->b_wid_control)) &= __swab32((unsigned int)~BRIDGE_CTRL_FLASH_WR_EN); - BRIDGE_REG_GET32((&bridge->b_wid_control)); /* inval addr bug war */ - splx(s); - } else { - if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) { - int s; +static int pcibr_mmap(struct file * file, struct vm_area_struct * vma); +struct file_operations pcibr_fops = { + .owner = THIS_MODULE, + .mmap = pcibr_mmap, +}; - /* - * ensure that we write and read without any interruption. - * The read following the write is required for the Bridge war - */ - s = splhi(); - bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN; - bridge->b_wid_control; /* inval addr bug war */ - splx(s); - } - } - } - } - return 0; -} /* This is special case code used by grio. There are plans to make * this a bit more general in the future, but till then this should * be sufficient. */ pciio_slot_t -pcibr_device_slot_get(devfs_handle_t dev_vhdl) +pcibr_device_slot_get(vertex_hdl_t dev_vhdl) { char devname[MAXDEVNAME]; - devfs_handle_t tdev; + vertex_hdl_t tdev; pciio_info_t pciio_info; pciio_slot_t slot = PCIIO_SLOT_NONE; @@ -812,20 +651,8 @@ return slot; } -/*ARGSUSED */ -int -pcibr_ioctl(devfs_handle_t dev, - int cmd, - void *arg, - int flag, - struct cred *cr, - int *rvalp) -{ - return 0; -} - pcibr_info_t -pcibr_info_get(devfs_handle_t vhdl) +pcibr_info_get(vertex_hdl_t vhdl) { return (pcibr_info_t) pciio_info_get(vhdl); } @@ -849,7 +676,7 @@ * will set the c_slot (which is suppose to represent the external * slot (i.e the slot number silk screened on the back of the I/O * brick)). So for PIC we need to adjust this "internal slot" num - * passed into us, into it's external representation. See comment + * passed into us, into its external representation. See comment * for the PCIBR_DEVICE_TO_SLOT macro for more information. */ NEW(pcibr_info); @@ -902,10 +729,10 @@ * This is usually used at the time of shutting down of the PCI card. */ int -pcibr_device_unregister(devfs_handle_t pconn_vhdl) +pcibr_device_unregister(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pciio_slot_t slot; pcibr_soft_t pcibr_soft; bridge_t *bridge; @@ -982,12 +809,12 @@ * slot's device status to be set. */ void -pcibr_driver_reg_callback(devfs_handle_t pconn_vhdl, +pcibr_driver_reg_callback(vertex_hdl_t pconn_vhdl, int key1, int key2, int error) { pciio_info_t pciio_info; pcibr_info_t pcibr_info; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pciio_slot_t slot; pcibr_soft_t pcibr_soft; @@ -1033,12 +860,12 @@ * slot's device status to be set. */ void -pcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl, +pcibr_driver_unreg_callback(vertex_hdl_t pconn_vhdl, int key1, int key2, int error) { pciio_info_t pciio_info; pcibr_info_t pcibr_info; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pciio_slot_t slot; pcibr_soft_t pcibr_soft; @@ -1084,14 +911,14 @@ * depends on hwgraph separator == '/' */ int -pcibr_bus_cnvlink(devfs_handle_t f_c) +pcibr_bus_cnvlink(vertex_hdl_t f_c) { char dst[MAXDEVNAME]; char *dp = dst; char *cp, *xp; int widgetnum; char pcibus[8]; - devfs_handle_t nvtx, svtx; + vertex_hdl_t nvtx, svtx; int rv; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, f_c, "pcibr_bus_cnvlink\n")); @@ -1105,7 +932,7 @@ xp = strstr(dst, "/"EDGE_LBL_XTALK"/"); if (xp == NULL) return 0; - widgetnum = atoi(xp+7); + widgetnum = simple_strtoul(xp+7, NULL, 0); if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F) return 0; @@ -1145,11 +972,11 @@ */ /*ARGSUSED */ int -pcibr_attach(devfs_handle_t xconn_vhdl) +pcibr_attach(vertex_hdl_t xconn_vhdl) { /* REFERENCED */ graph_error_t rc; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; bridge_t *bridge; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, xconn_vhdl, "pcibr_attach\n")); @@ -1180,11 +1007,11 @@ /*ARGSUSED */ int -pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, - devfs_handle_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp) +pcibr_attach2(vertex_hdl_t xconn_vhdl, bridge_t *bridge, + vertex_hdl_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp) { /* REFERENCED */ - devfs_handle_t ctlr_vhdl; + vertex_hdl_t ctlr_vhdl; bridgereg_t id; int rev; pcibr_soft_t pcibr_soft; @@ -1193,7 +1020,7 @@ xtalk_intr_t xtalk_intr; int slot; int ibit; - devfs_handle_t noslot_conn; + vertex_hdl_t noslot_conn; char devnm[MAXDEVNAME], *s; pcibr_hints_t pcibr_hints; uint64_t int_enable; @@ -1209,23 +1036,15 @@ nasid_t nasid; int iobrick_type_get_nasid(nasid_t nasid); int iobrick_module_get_nasid(nasid_t nasid); - extern unsigned char Is_pic_on_this_nasid[512]; - - - async_attach_t aa = NULL; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl, "pcibr_attach2: bridge=0x%p, busnum=%d\n", bridge, busnum)); - aa = async_attach_get_info(xconn_vhdl); - ctlr_vhdl = NULL; - ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &pcibr_fops, NULL); - + ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0, + DEVFS_FL_AUTO_DEVNUM, 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + (struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl); ASSERT(ctlr_vhdl != NULL); /* @@ -1261,13 +1080,7 @@ pcibr_soft->bs_min_slot = 0; /* lowest possible slot# */ pcibr_soft->bs_max_slot = 7; /* highest possible slot# */ pcibr_soft->bs_busnum = busnum; - if (is_xbridge(bridge)) { - pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_XBRIDGE; - } else if (is_pic(bridge)) { - pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC; - } else { - pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_BRIDGE; - } + pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC; switch(pcibr_soft->bs_bridge_type) { case PCIBR_BRIDGETYPE_BRIDGE: pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES; @@ -1367,10 +1180,6 @@ nasid = NASID_GET(bridge); - /* set whether it is a PIC or not */ - Is_pic_on_this_nasid[nasid] = (IS_PIC_SOFT(pcibr_soft)) ? 1 : 0; - - if ((pcibr_soft->bs_bricktype = iobrick_type_get_nasid(nasid)) < 0) printk(KERN_WARNING "0x%p: Unknown bricktype : 0x%x\n", (void *)xconn_vhdl, (unsigned int)pcibr_soft->bs_bricktype); @@ -1380,11 +1189,27 @@ if (pcibr_soft->bs_bricktype > 0) { switch (pcibr_soft->bs_bricktype) { case MODULE_PXBRICK: + case MODULE_IXBRICK: pcibr_soft->bs_first_slot = 0; pcibr_soft->bs_last_slot = 1; pcibr_soft->bs_last_reset = 1; + + /* If Bus 1 has IO9 then there are 4 devices in that bus. Note + * we figure this out from klconfig since the kernel has yet to + * probe + */ + if (pcibr_widget_to_bus(pcibr_vhdl) == 1) { + lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid); + + while (brd) { + if (brd->brd_flags & LOCAL_MASTER_IO6) { + pcibr_soft->bs_last_slot = 3; + pcibr_soft->bs_last_reset = 3; + } + brd = KLCF_NEXT(brd); + } + } break; - case MODULE_PEBRICK: case MODULE_PBRICK: pcibr_soft->bs_first_slot = 1; pcibr_soft->bs_last_slot = 2; @@ -1559,11 +1384,6 @@ int entry; cnodeid_t cnodeid; nasid_t nasid; -#ifdef PIC_LATER - char *node_val; - devfs_handle_t node_vhdl; - char vname[MAXDEVNAME]; -#endif /* Set the Bridge's 32-bit PCI to XTalk * Direct Map register to the most useful @@ -1582,30 +1402,6 @@ */ cnodeid = 0; /* default node id */ - /* - * Determine the base address node id to be used for all 32-bit - * Direct Mapping I/O. The default is node 0, but this can be changed - * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE - * attribute in the irix.sm config file. A device driver can obtain - * this node value via a call to pcibr_get_dmatrans_node(). - */ -#ifdef PIC_LATER -// This probably needs to be addressed - pfg - node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE); - if (node_val != NULL) { - node_vhdl = hwgraph_path_to_vertex(node_val); - if (node_vhdl != GRAPH_VERTEX_NONE) { - cnodeid = nodevertex_to_cnodeid(node_vhdl); - } - if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) { - cnodeid = 0; - vertex_to_name(pcibr_vhdl, vname, sizeof(vname)); - printk(KERN_WARNING "Invalid hwgraph node path specified:\n" - " DEVICE_ADMIN: %s %s=%s\n", - vname, ADMIN_LBL_DMATRANS_NODE, node_val); - } - } -#endif /* PIC_LATER */ nasid = COMPACT_TO_NASID_NODEID(cnodeid); paddr = NODE_OFFSET(nasid) + 0; @@ -1697,18 +1493,21 @@ /* we always have 128 ATEs (512 for Xbridge) inside the chip * even if disabled for debugging. */ - pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size); - pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size); + pcibr_soft->bs_int_ate_resource.start = 0; + pcibr_soft->bs_int_ate_resource.end = pcibr_soft->bs_int_ate_size - 1; if (num_entries > pcibr_soft->bs_int_ate_size) { #if PCIBR_ATE_NOTBOTH /* for debug -- forces us to use external ates */ printk("pcibr_attach: disabling internal ATEs.\n"); pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size); #endif - pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries); - pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size, - num_entries - pcibr_soft->bs_int_ate_size); + pcibr_soft->bs_ext_ate_resource.start = pcibr_soft->bs_int_ate_size; + pcibr_soft->bs_ext_ate_resource.end = num_entries; } + + pcibr_soft->bs_allocated_ate_res = (void *) kmalloc(pcibr_soft->bs_int_ate_size * sizeof(unsigned long), GFP_KERNEL); + memset(pcibr_soft->bs_allocated_ate_res, 0x0, pcibr_soft->bs_int_ate_size * sizeof(unsigned long)); + PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_vhdl, "pcibr_attach2: %d ATEs, %d internal & %d external\n", num_entries ? num_entries : pcibr_soft->bs_int_ate_size, @@ -1763,6 +1562,13 @@ */ xtalk_intr = xtalk_intr_alloc(xconn_vhdl, (device_desc_t)0, pcibr_vhdl); + { + int irq = ((hub_intr_t)xtalk_intr)->i_bit; + int cpu = ((hub_intr_t)xtalk_intr)->i_cpuid; + + intr_unreserve_level(cpu, irq); + ((hub_intr_t)xtalk_intr)->i_bit = SGI_PCIBR_ERROR; + } ASSERT(xtalk_intr != NULL); pcibr_soft->bsi_err_intr = xtalk_intr; @@ -1778,12 +1584,8 @@ xtalk_intr_connect(xtalk_intr, (intr_func_t) pcibr_error_intr_handler, (intr_arg_t) pcibr_soft, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge); -#ifdef BUS_INT_WAR_NOT_YET - request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid, - ((hub_intr_t)xtalk_intr)->i_bit), - (intr_func_t)pcibr_error_intr_handler, 0, "PCIBR error", + request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler, SA_SHIRQ, "PCIBR error", (intr_arg_t) pcibr_soft); -#endif PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_vhdl, "pcibr_setwidint: b_wid_int_upper=0x%x, b_wid_int_lower=0x%x\n", @@ -1801,18 +1603,16 @@ if (IS_PIC_SOFT(pcibr_soft)) { int_enable_64 = bridge->p_int_enable_64 | BRIDGE_ISR_ERRORS; int_enable = (uint64_t)int_enable_64; +#ifdef PFG_TEST + int_enable = (uint64_t)0x7ffffeff7ffffeff; +#endif } else { int_enable_32 = bridge->b_int_enable | (BRIDGE_ISR_ERRORS & 0xffffffff); int_enable = ((uint64_t)int_enable_32 & 0xffffffff); - } -#ifdef BUS_INT_WAR_NOT_YET - { - extern void sn_add_polled_interrupt(int irq, int interval); - - sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid, - ((hub_intr_t)xtalk_intr)->i_bit), 20000); - } +#ifdef PFG_TEST + int_enable = (uint64_t)0x7ffffeff; #endif + } #if BRIDGE_ERROR_INTR_WAR @@ -1849,24 +1649,6 @@ } #endif -#ifdef BRIDGE_B_DATACORR_WAR - - /* WAR panic for Rev B silent data corruption. - * PIOERR turned off here because there is a problem - * with not re-arming it in pcibr_error_intr_handler. - * We don't get LLP error interrupts if we don't - * re-arm PIOERR interrupts! Just disable them here - */ - - if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) { - int_enable |= BRIDGE_IMR_LLP_REC_CBERR; - int_enable &= ~BRIDGE_ISR_PCIBUS_PIOERR; - - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl, - "Turning on LLP_REC_CBERR for Rev B Bridge.\n")); - } -#endif - /* PIC BRINGUP WAR (PV# 856864 & 856865): allow the tnums that are * locked out to be freed up sooner (by timing out) so that the * read tnums are never completely used up. @@ -1918,16 +1700,12 @@ if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B) pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH; else if (pcibr_soft->bs_rev_num < - (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev)) + (BRIDGE_WIDGET_PART_NUM << 4)) pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH; - /* WRITE_GATHER: - * Disabled up to but not including the - * rev number in pcibr_wg_enable_rev. There - * is no "WAR range" as with prefetch. - */ + /* WRITE_GATHER: Disabled */ if (pcibr_soft->bs_rev_num < - (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev)) + (BRIDGE_WIDGET_PART_NUM << 4)) pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER; /* PIC only supports 64-bit direct mapping in PCI-X mode. Since @@ -1940,10 +1718,10 @@ { - pciio_win_map_t win_map_p; iopaddr_t prom_base_addr = pcibr_soft->bs_xid << 24; int prom_base_size = 0x1000000; - iopaddr_t prom_base_limit = prom_base_addr + prom_base_size; + int status; + struct resource *res; /* Allocate resource maps based on bus page size; for I/O and memory * space, free all pages except those in the base area and in the @@ -1953,35 +1731,38 @@ * the widget number and s is the device register offset for the slot. */ - win_map_p = &pcibr_soft->bs_io_win_map; - pciio_device_win_map_new(win_map_p, - PCIBR_BUS_IO_MAX + 1, - PCIBR_BUS_IO_PAGE); - pciio_device_win_populate(win_map_p, - PCIBR_BUS_IO_BASE, - prom_base_addr - PCIBR_BUS_IO_BASE); - pciio_device_win_populate(win_map_p, - prom_base_limit, - (PCIBR_BUS_IO_MAX + 1) - prom_base_limit); - - win_map_p = &pcibr_soft->bs_swin_map; - pciio_device_win_map_new(win_map_p, - PCIBR_BUS_SWIN_MAX + 1, - PCIBR_BUS_SWIN_PAGE); - pciio_device_win_populate(win_map_p, - PCIBR_BUS_SWIN_BASE, - (PCIBR_BUS_SWIN_MAX + 1) - PCIBR_BUS_SWIN_PAGE); - - win_map_p = &pcibr_soft->bs_mem_win_map; - pciio_device_win_map_new(win_map_p, - PCIBR_BUS_MEM_MAX + 1, - PCIBR_BUS_MEM_PAGE); - pciio_device_win_populate(win_map_p, - PCIBR_BUS_MEM_BASE, - prom_base_addr - PCIBR_BUS_MEM_BASE); - pciio_device_win_populate(win_map_p, - prom_base_limit, - (PCIBR_BUS_MEM_MAX + 1) - prom_base_limit); + /* Setup the Bus's PCI IO Root Resource. */ + pcibr_soft->bs_io_win_root_resource.start = PCIBR_BUS_IO_BASE; + pcibr_soft->bs_io_win_root_resource.end = 0xffffffff; + res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP); + if (!res) + panic("PCIBR:Unable to allocate resource structure\n"); + + /* Block off the range used by PROM. */ + res->start = prom_base_addr; + res->end = prom_base_addr + (prom_base_size - 1); + status = request_resource(&pcibr_soft->bs_io_win_root_resource, res); + if (status) + panic("PCIBR:Unable to request_resource()\n"); + + /* Setup the Small Window Root Resource */ + pcibr_soft->bs_swin_root_resource.start = _PAGESZ; + pcibr_soft->bs_swin_root_resource.end = 0x000FFFFF; + + /* Setup the Bus's PCI Memory Root Resource */ + pcibr_soft->bs_mem_win_root_resource.start = 0x200000; + pcibr_soft->bs_mem_win_root_resource.end = 0xffffffff; + res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP); + if (!res) + panic("PCIBR:Unable to allocate resource structure\n"); + + /* Block off the range used by PROM. */ + res->start = prom_base_addr; + res->end = prom_base_addr + (prom_base_size - 1);; + status = request_resource(&pcibr_soft->bs_mem_win_root_resource, res); + if (status) + panic("PCIBR:Unable to request_resource()\n"); + } /* build "no-slot" connection point @@ -2064,7 +1845,23 @@ */ if (pcibr_soft->bs_bricktype > 0) { switch (pcibr_soft->bs_bricktype) { + case MODULE_PBRICK: + do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); + do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); + break; + case MODULE_IBRICK: + /* port 0xe on the Ibrick only has slots 1 and 2 */ + if (pcibr_soft->bs_xid == 0xe) { + do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); + do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); + } + else { + /* allocate one RRB for the serial port */ + do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1); + } + break; case MODULE_PXBRICK: + case MODULE_IXBRICK: /* * If the IO9 is in the PXBrick (bus1, slot1) allocate * RRBs to all the devices @@ -2080,23 +1877,6 @@ do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 8); do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); } - - break; - case MODULE_PEBRICK: - case MODULE_PBRICK: - do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); - do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); - break; - case MODULE_IBRICK: - /* port 0xe on the Ibrick only has slots 1 and 2 */ - if (pcibr_soft->bs_xid == 0xe) { - do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); - do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); - } - else { - /* allocate one RRB for the serial port */ - do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1); - } break; } /* switch */ } @@ -2113,78 +1893,8 @@ /* Call the device attach */ (void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0); -#ifdef PIC_LATER -#if (defined(USS302_TIMEOUT_WAR)) - /* - * If this bridge holds a Lucent USS-302 or USS-312 pci/usb controller, - * increase the Bridge PCI retry backoff interval. This part seems - * to go away for long periods of time if a DAC appears on the bus during - * a read command that is being retried. - */ - -{ - ii_ixtt_u_t ixtt; - - for (slot = pcibr_soft->bs_min_slot; - slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) { - if (pcibr_soft->bs_slot[slot].bss_vendor_id == - LUCENT_USBHC_VENDOR_ID_NUM && - (pcibr_soft->bs_slot[slot].bss_device_id == - LUCENT_USBHC302_DEVICE_ID_NUM || - pcibr_soft->bs_slot[slot].bss_device_id == - LUCENT_USBHC312_DEVICE_ID_NUM)) { - printk(KERN_NOTICE - "pcibr_attach: %x Bus holds a usb part - setting" - "bridge PCI_RETRY_HLD to %d\n", - pcibr_vhdl, USS302_BRIDGE_TIMEOUT_HLD); - - bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_HLD_MASK; - bridge->b_bus_timeout |= - BRIDGE_BUS_PCI_RETRY_HLD(USS302_BRIDGE_TIMEOUT_HLD); - - /* - * Have to consider the read response timer in the hub II as well - */ - - hubii_ixtt_get(xconn_vhdl, &ixtt); - - /* - * bump rrsp_ps to allow at least 1ms for read - * responses from this widget - */ - - ixtt.ii_ixtt_fld_s.i_rrsp_ps = 20000; - hubii_ixtt_set(xconn_vhdl, &ixtt); - - /* - * print the current setting - */ - - hubii_ixtt_get(xconn_vhdl, &ixtt); - printk( "Setting hub ixtt.rrsp_ps field to 0x%x\n", - ixtt.ii_ixtt_fld_s.i_rrsp_ps); - - break; /* only need to do it once */ - } - } -} -#endif /* (defined(USS302_TIMEOUT_WAR)) */ -#else - FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n"); -#endif /* PIC_LATER */ - - if (aa) - async_attach_add_info(noslot_conn, aa); - pciio_device_attach(noslot_conn, (int)0); - /* - * Tear down pointer to async attach info -- async threads for - * bridge's descendants may be running but the bridge's work is done. - */ - if (aa) - async_attach_del_info(xconn_vhdl); - return 0; } @@ -2195,10 +1905,10 @@ */ int -pcibr_detach(devfs_handle_t xconn) +pcibr_detach(vertex_hdl_t xconn) { pciio_slot_t slot; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pcibr_soft_t pcibr_soft; bridge_t *bridge; unsigned s; @@ -2235,15 +1945,6 @@ spin_lock_destroy(&pcibr_soft->bs_lock); kfree(pcibr_soft->bs_name); - /* Error handler gets unregistered when the widget info is - * cleaned - */ - /* Free the soft ATE maps */ - if (pcibr_soft->bs_int_ate_map) - rmfreemap(pcibr_soft->bs_int_ate_map); - if (pcibr_soft->bs_ext_ate_map) - rmfreemap(pcibr_soft->bs_ext_ate_map); - /* Disconnect the error interrupt and free the xtalk resources * associated with it. */ @@ -2265,9 +1966,9 @@ } int -pcibr_asic_rev(devfs_handle_t pconn_vhdl) +pcibr_asic_rev(vertex_hdl_t pconn_vhdl) { - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; int tmp_vhdl; arbitrary_info_t ainfo; @@ -2294,7 +1995,7 @@ } int -pcibr_write_gather_flush(devfs_handle_t pconn_vhdl) +pcibr_write_gather_flush(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); @@ -2309,7 +2010,7 @@ */ static iopaddr_t -pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, +pcibr_addr_pci_to_xio(vertex_hdl_t pconn_vhdl, pciio_slot_t slot, pciio_space_t space, iopaddr_t pci_addr, @@ -2323,6 +2024,8 @@ unsigned bar; /* which BASE reg on device is decoding */ iopaddr_t xio_addr = XIO_NOWHERE; + iopaddr_t base; /* base of devio(x) mapped area on PCI */ + iopaddr_t limit; /* base of devio(x) mapped area on PCI */ pciio_space_t wspace; /* which space device is decoding */ iopaddr_t wbase; /* base of device decode on PCI */ @@ -2533,8 +2236,6 @@ PCIBR_DEBUG((PCIBR_DEBUG_DEVREG, pconn_vhdl, "pcibr_addr_pci_to_xio: Device(%d): %x\n", win, devreg, device_bits)); -#else - printk("pcibr_addr_pci_to_xio: Device(%d): %x\n", win, devreg); #endif } pcibr_soft->bs_slot[win].bss_devio.bssd_space = space; @@ -2620,18 +2321,46 @@ */ case PCIIO_SPACE_MEM: /* "mem space" */ case PCIIO_SPACE_MEM32: /* "mem, use 32-bit-wide bus" */ - if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <= - BRIDGE_PCI_MEM32_LIMIT) - xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE; + if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) { /* PIC bus 0 */ + base = PICBRIDGE0_PCI_MEM32_BASE; + limit = PICBRIDGE0_PCI_MEM32_LIMIT; + } else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) { /* PIC bus 1 */ + base = PICBRIDGE1_PCI_MEM32_BASE; + limit = PICBRIDGE1_PCI_MEM32_LIMIT; + } else { /* Bridge/Xbridge */ + base = BRIDGE_PCI_MEM32_BASE; + limit = BRIDGE_PCI_MEM32_LIMIT; + } + + if ((pci_addr + base + req_size - 1) <= limit) + xio_addr = pci_addr + base; break; case PCIIO_SPACE_MEM64: /* "mem, use 64-bit-wide bus" */ - if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <= - BRIDGE_PCI_MEM64_LIMIT) - xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE; + if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) { /* PIC bus 0 */ + base = PICBRIDGE0_PCI_MEM64_BASE; + limit = PICBRIDGE0_PCI_MEM64_LIMIT; + } else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) { /* PIC bus 1 */ + base = PICBRIDGE1_PCI_MEM64_BASE; + limit = PICBRIDGE1_PCI_MEM64_LIMIT; + } else { /* Bridge/Xbridge */ + base = BRIDGE_PCI_MEM64_BASE; + limit = BRIDGE_PCI_MEM64_LIMIT; + } + + if ((pci_addr + base + req_size - 1) <= limit) + xio_addr = pci_addr + base; break; case PCIIO_SPACE_IO: /* "i/o space" */ + /* + * PIC bridges do not support big-window aliases into PCI I/O space + */ + if (IS_PIC_SOFT(pcibr_soft)) { + xio_addr = XIO_NOWHERE; + break; + } + /* Bridge Hardware Bug WAR #482741: * The 4G area that maps directly from * XIO space to PCI I/O space is busted @@ -2725,7 +2454,7 @@ /*ARGSUSED6 */ pcibr_piomap_t -pcibr_piomap_alloc(devfs_handle_t pconn_vhdl, +pcibr_piomap_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_space_t space, iopaddr_t pci_addr, @@ -2737,7 +2466,7 @@ pciio_info_t pciio_info = &pcibr_info->f_c; pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; pcibr_piomap_t *mapptr; pcibr_piomap_t maplist; @@ -2867,7 +2596,7 @@ /*ARGSUSED */ caddr_t -pcibr_piotrans_addr(devfs_handle_t pconn_vhdl, +pcibr_piotrans_addr(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_space_t space, iopaddr_t pci_addr, @@ -2877,7 +2606,7 @@ pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; iopaddr_t xio_addr; caddr_t addr; @@ -2908,7 +2637,7 @@ /*ARGSUSED */ iopaddr_t -pcibr_piospace_alloc(devfs_handle_t pconn_vhdl, +pcibr_piospace_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_space_t space, size_t req_size, @@ -3010,7 +2739,7 @@ /*ARGSUSED */ void -pcibr_piospace_free(devfs_handle_t pconn_vhdl, +pcibr_piospace_free(vertex_hdl_t pconn_vhdl, pciio_space_t space, iopaddr_t pciaddr, size_t req_size) @@ -3161,14 +2890,14 @@ /*ARGSUSED */ pcibr_dmamap_t -pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl, +pcibr_dmamap_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, size_t req_size_max, unsigned flags) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; pciio_slot_t slot; xwidgetnum_t xio_port; @@ -3216,7 +2945,7 @@ /* Device is capable of A64 operations, * and the attributes of the DMA are - * consistant with any previous DMA + * consistent with any previous DMA * mappings using shared resources. */ @@ -3266,7 +2995,7 @@ if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) { /* User desires DIRECT A32 operations, * and the attributes of the DMA are - * consistant with any previous DMA + * consistent with any previous DMA * mappings using shared resources. * Mapping calls may fail if target * is outside the direct32 range. @@ -3454,6 +3183,29 @@ iopaddr_t pci_addr; pciio_slot_t slot; + if (IS_PIC_BUSNUM_SOFT(soft, 0)) { + if ((xio_addr >= PICBRIDGE0_PCI_MEM32_BASE) && + (xio_lim <= PICBRIDGE0_PCI_MEM32_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE0_PCI_MEM32_BASE; + return pci_addr; + } + if ((xio_addr >= PICBRIDGE0_PCI_MEM64_BASE) && + (xio_lim <= PICBRIDGE0_PCI_MEM64_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE0_PCI_MEM64_BASE; + return pci_addr; + } + } else if (IS_PIC_BUSNUM_SOFT(soft, 1)) { + if ((xio_addr >= PICBRIDGE1_PCI_MEM32_BASE) && + (xio_lim <= PICBRIDGE1_PCI_MEM32_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE1_PCI_MEM32_BASE; + return pci_addr; + } + if ((xio_addr >= PICBRIDGE1_PCI_MEM64_BASE) && + (xio_lim <= PICBRIDGE1_PCI_MEM64_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE1_PCI_MEM64_BASE; + return pci_addr; + } + } else { if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) && (xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) { pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE; @@ -3464,6 +3216,7 @@ pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE; return pci_addr; } + } for (slot = soft->bs_min_slot; slot < PCIBR_NUM_SLOTS(soft); ++slot) if ((xio_addr >= PCIBR_BRIDGE_DEVIO(soft, slot)) && (xio_lim < PCIBR_BRIDGE_DEVIO(soft, slot + 1))) { @@ -3505,7 +3258,7 @@ } else xio_port = pcibr_dmamap->bd_xio_port; - /* If this DMA is to an addres that + /* If this DMA is to an address that * refers back to this Bridge chip, * reduce it back to the correct * PCI MEM address. @@ -3644,243 +3397,6 @@ } /*ARGSUSED */ -alenlist_t -pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap, - alenlist_t palenlist, - unsigned flags) -{ - pcibr_soft_t pcibr_soft; - bridge_t *bridge=NULL; - - unsigned al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; - int inplace = flags & PCIIO_INPLACE; - - alenlist_t pciio_alenlist = 0; - alenlist_t xtalk_alenlist; - size_t length; - iopaddr_t offset; - unsigned direct64; - int ate_index = 0; - int ate_count = 0; - int ate_total = 0; - bridge_ate_p ate_ptr = (bridge_ate_p)0; - bridge_ate_t ate_proto = (bridge_ate_t)0; - bridge_ate_t ate_prev; - bridge_ate_t ate; - alenaddr_t xio_addr; - xwidgetnum_t xio_port; - iopaddr_t pci_addr; - alenaddr_t new_addr; - unsigned cmd_regs[8]; - unsigned s = 0; - -#if PCIBR_FREEZE_TIME - unsigned freeze_time; -#endif - int ate_freeze_done = 0; /* To pair ATE_THAW - * with an ATE_FREEZE - */ - - pcibr_soft = pcibr_dmamap->bd_soft; - - xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist, - flags & DMAMAP_FLAGS); - if (!xtalk_alenlist) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: xtalk_dmamap_list() failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - goto fail; - } - alenlist_cursor_init(xtalk_alenlist, 0, NULL); - - if (inplace) { - pciio_alenlist = xtalk_alenlist; - } else { - pciio_alenlist = alenlist_create(al_flags); - if (!pciio_alenlist) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: alenlist_create() failed, " - "pcibr_dmamap=0x%lx\n", (unsigned long)pcibr_dmamap)); - goto fail; - } - } - - direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64; - if (!direct64) { - bridge = pcibr_soft->bs_base; - ate_ptr = pcibr_dmamap->bd_ate_ptr; - ate_index = pcibr_dmamap->bd_ate_index; - ate_proto = pcibr_dmamap->bd_ate_proto; - ATE_FREEZE(); - ate_freeze_done = 1; /* Remember that we need to do an ATE_THAW */ - } - pci_addr = pcibr_dmamap->bd_pci_addr; - - ate_prev = 0; /* matches no valid ATEs */ - while (ALENLIST_SUCCESS == - alenlist_get(xtalk_alenlist, NULL, 0, - &xio_addr, &length, al_flags)) { - if (XIO_PACKED(xio_addr)) { - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - } else - xio_port = pcibr_dmamap->bd_xio_port; - - if (xio_port == pcibr_soft->bs_xid) { - new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length); - if (new_addr == PCI_NOWHERE) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: pcibr_addr_xio_to_pci failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - goto fail; - } - } else if (direct64) { - new_addr = pci_addr | xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - - /* Bridge Hardware WAR #482836: - * If the transfer is not cache aligned - * and the Bridge Rev is <= B, force - * prefetch to be off. - */ - if (flags & PCIBR_NOPREFETCH) - new_addr &= ~PCI64_ATTR_PREF; - - } else { - /* calculate the ate value for - * the first address. If it - * matches the previous - * ATE written (ie. we had - * multiple blocks in the - * same IOPG), then back up - * and reuse that ATE. - * - * We are NOT going to - * aggressively try to - * reuse any other ATEs. - */ - offset = IOPGOFF(xio_addr); - ate = ate_proto - | (xio_port << ATE_TIDSHIFT) - | (xio_addr - offset); - if (ate == ate_prev) { - PCIBR_DEBUG((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: ATE share\n")); - ate_ptr--; - ate_index--; - pci_addr -= IOPGSIZE; - } - new_addr = pci_addr + offset; - - /* Fill in the hardware ATEs - * that contain this block. - */ - ate_count = IOPG(offset + length - 1) + 1; - ate_total += ate_count; - - /* Ensure that this map contains enough ATE's */ - if (ate_total > pcibr_dmamap->bd_ate_count) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list :\n" - "\twanted xio_addr [0x%x..0x%x]\n" - "\tate_total 0x%x bd_ate_count 0x%x\n" - "\tATE's required > number allocated\n", - xio_addr, xio_addr + length - 1, - ate_total, pcibr_dmamap->bd_ate_count)); - goto fail; - } - - ATE_WRITE(); - - ate_index += ate_count; - ate_ptr += ate_count; - - ate_count <<= IOPFNSHIFT; - ate += ate_count; - pci_addr += ate_count; - } - - /* write the PCI DMA address - * out to the scatter-gather list. - */ - if (inplace) { - if (ALENLIST_SUCCESS != - alenlist_replace(pciio_alenlist, NULL, - &new_addr, &length, al_flags)) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: alenlist_replace() failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - - goto fail; - } - } else { - if (ALENLIST_SUCCESS != - alenlist_append(pciio_alenlist, - new_addr, length, al_flags)) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: alenlist_append() failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - goto fail; - } - } - } - if (!inplace) - alenlist_done(xtalk_alenlist); - - /* Reset the internal cursor of the alenlist to be returned back - * to the caller. - */ - alenlist_cursor_init(pciio_alenlist, 0, NULL); - - - /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the - * changes that ATE_FREEZE has done to implement the external SSRAM - * bug workaround. - */ - if (ate_freeze_done) { - ATE_THAW(); - if ( IS_PIC_SOFT(pcibr_soft) ) { - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_GET32((&bridge->b_wid_tflush)); - } else { - bridge->b_wid_tflush; - } - } - } - PCIBR_DEBUG((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: pcibr_dmamap=0x%x, pciio_alenlist=0x%x\n", - pcibr_dmamap, pciio_alenlist)); - - return pciio_alenlist; - - fail: - /* There are various points of failure after doing an ATE_FREEZE - * We need to do an ATE_THAW. Otherwise the ATEs are locked forever. - * The decision to do an ATE_THAW needs to be based on whether a - * an ATE_FREEZE was done before. - */ - if (ate_freeze_done) { - ATE_THAW(); - if ( IS_PIC_SOFT(pcibr_soft) ) { - bridge->b_wid_tflush; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_GET32((&bridge->b_wid_tflush)); - } else { - bridge->b_wid_tflush; - } - } - } - if (pciio_alenlist && !inplace) - alenlist_destroy(pciio_alenlist); - return 0; -} - -/*ARGSUSED */ void pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap) { @@ -3917,7 +3433,7 @@ /*ARGSUSED */ cnodeid_t -pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl) +pcibr_get_dmatrans_node(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -3928,7 +3444,7 @@ /*ARGSUSED */ iopaddr_t -pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl, +pcibr_dmatrans_addr(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, paddr_t paddr, size_t req_size, @@ -3936,7 +3452,7 @@ { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; @@ -4149,213 +3665,6 @@ return 0; } -/*ARGSUSED */ -alenlist_t -pcibr_dmatrans_list(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - alenlist_t palenlist, - unsigned flags) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); - pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; - xwidgetnum_t xio_port; - - alenlist_t pciio_alenlist = 0; - alenlist_t xtalk_alenlist = 0; - - int inplace; - unsigned direct64; - unsigned al_flags; - - iopaddr_t xio_base; - alenaddr_t xio_addr; - size_t xio_size; - - size_t map_size; - iopaddr_t pci_base; - alenaddr_t pci_addr; - - unsigned relbits = 0; - - /* merge in forced flags */ - flags |= pcibr_soft->bs_dma_flags; - - inplace = flags & PCIIO_INPLACE; - direct64 = flags & PCIIO_DMA_A64; - al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; - - if (direct64) { - map_size = 1ull << 48; - xio_base = 0; - pci_base = slotp->bss_d64_base; - if ((pci_base != PCIBR_D64_BASE_UNSET) && - (flags == slotp->bss_d64_flags)) { - /* reuse previous base info */ - } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) { - /* DMA configuration conflict */ - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: DMA configuration conflict " - "for direct64, flags=0x%x\n", flags)); - goto fail; - } else { - relbits = BRIDGE_DEV_D64_BITS; - pci_base = - pcibr_flags_to_d64(flags, pcibr_soft); - } - } else { - xio_base = pcibr_soft->bs_dir_xbase; - map_size = 1ull << 31; - pci_base = slotp->bss_d32_base; - if ((pci_base != PCIBR_D32_BASE_UNSET) && - (flags == slotp->bss_d32_flags)) { - /* reuse previous base info */ - } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) { - /* DMA configuration conflict */ - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: DMA configuration conflict " - "for direct32, flags=0x%x\n", flags)); - goto fail; - } else { - relbits = BRIDGE_DEV_D32_BITS; - pci_base = PCI32_DIRECT_BASE; - } - } - - xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist, - flags & DMAMAP_FLAGS); - if (!xtalk_alenlist) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: xtalk_dmatrans_list failed " - "xtalk_alenlist=0x%x\n", xtalk_alenlist)); - goto fail; - } - - alenlist_cursor_init(xtalk_alenlist, 0, NULL); - - if (inplace) { - pciio_alenlist = xtalk_alenlist; - } else { - pciio_alenlist = alenlist_create(al_flags); - if (!pciio_alenlist) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: alenlist_create failed with " - " 0x%x\n", pciio_alenlist)); - goto fail; - } - } - - while (ALENLIST_SUCCESS == - alenlist_get(xtalk_alenlist, NULL, 0, - &xio_addr, &xio_size, al_flags)) { - - /* - * find which XIO port this goes to. - */ - if (XIO_PACKED(xio_addr)) { - if (xio_addr == XIO_NOWHERE) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: xio_addr == XIO_NOWHERE\n")); - return 0; - } - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - } else - xio_port = pcibr_soft->bs_mxid; - - /* - * If this DMA comes back to us, - * return the PCI MEM address on - * which it would land, or NULL - * if the target is something - * on bridge other than PCI MEM. - */ - if (xio_port == pcibr_soft->bs_xid) { - pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size); - if (pci_addr == (alenaddr_t)NULL) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: pcibr_addr_xio_to_pci failed " - "xio_addr=0x%x, xio_size=0x%x\n", xio_addr, xio_size)); - goto fail; - } - } else if (direct64) { - ASSERT(xio_port != 0); - pci_addr = pci_base | xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - } else { - iopaddr_t offset = xio_addr - xio_base; - iopaddr_t endoff = xio_size + offset; - - if ((xio_size > map_size) || - (xio_addr < xio_base) || - (xio_port != pcibr_soft->bs_dir_xport) || - (endoff > map_size)) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: xio_size > map_size fail\n" - "xio_addr=0x%x, xio_size=0x%x. map_size=0x%x, " - "xio_port=0x%x, endoff=0x%x\n", - xio_addr, xio_size, map_size, xio_port, endoff)); - goto fail; - } - - pci_addr = pci_base + (xio_addr - xio_base); - } - - /* write the PCI DMA address - * out to the scatter-gather list. - */ - if (inplace) { - if (ALENLIST_SUCCESS != - alenlist_replace(pciio_alenlist, NULL, - &pci_addr, &xio_size, al_flags)) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: alenlist_replace failed\n")); - goto fail; - } - } else { - if (ALENLIST_SUCCESS != - alenlist_append(pciio_alenlist, - pci_addr, xio_size, al_flags)) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: alenlist_append failed\n")); - goto fail; - } - } - } - - if (relbits) { - if (direct64) { - slotp->bss_d64_flags = flags; - slotp->bss_d64_base = pci_base; - } else { - slotp->bss_d32_flags = flags; - slotp->bss_d32_base = pci_base; - } - } - if (!inplace) - alenlist_done(xtalk_alenlist); - - /* Reset the internal cursor of the alenlist to be returned back - * to the caller. - */ - alenlist_cursor_init(pciio_alenlist, 0, NULL); - - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: pciio_alenlist=0x%x\n", - pciio_alenlist)); - - return pciio_alenlist; - - fail: - if (relbits) - pcibr_release_device(pcibr_soft, pciio_slot, relbits); - if (pciio_alenlist && !inplace) - alenlist_destroy(pciio_alenlist); - return 0; -} - void pcibr_dmamap_drain(pcibr_dmamap_t map) { @@ -4363,24 +3672,24 @@ } void -pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl, +pcibr_dmaaddr_drain(vertex_hdl_t pconn_vhdl, paddr_t paddr, size_t bytes) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes); } void -pcibr_dmalist_drain(devfs_handle_t pconn_vhdl, +pcibr_dmalist_drain(vertex_hdl_t pconn_vhdl, alenlist_t list) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; xtalk_dmalist_drain(xconn_vhdl, list); } @@ -4402,18 +3711,18 @@ */ /*ARGSUSED */ void -pcibr_provider_startup(devfs_handle_t pcibr) +pcibr_provider_startup(vertex_hdl_t pcibr) { } /*ARGSUSED */ void -pcibr_provider_shutdown(devfs_handle_t pcibr) +pcibr_provider_shutdown(vertex_hdl_t pcibr) { } int -pcibr_reset(devfs_handle_t conn) +pcibr_reset(vertex_hdl_t conn) { #ifdef PIC_LATER pciio_info_t pciio_info = pciio_info_get(conn); @@ -4484,7 +3793,7 @@ } pciio_endian_t -pcibr_endian_set(devfs_handle_t pconn_vhdl, +pcibr_endian_set(vertex_hdl_t pconn_vhdl, pciio_endian_t device_end, pciio_endian_t desired_end) { @@ -4629,7 +3938,7 @@ } pciio_priority_t -pcibr_priority_set(devfs_handle_t pconn_vhdl, +pcibr_priority_set(vertex_hdl_t pconn_vhdl, pciio_priority_t device_prio) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -4653,7 +3962,7 @@ * Returns 0 on failure, 1 on success */ int -pcibr_device_flags_set(devfs_handle_t pconn_vhdl, +pcibr_device_flags_set(vertex_hdl_t pconn_vhdl, pcibr_device_flags_t flags) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -4792,10 +4101,8 @@ (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc, (pciio_dmamap_free_f *) pcibr_dmamap_free, (pciio_dmamap_addr_f *) pcibr_dmamap_addr, - (pciio_dmamap_list_f *) pcibr_dmamap_list, (pciio_dmamap_done_f *) pcibr_dmamap_done, (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr, - (pciio_dmatrans_list_f *) pcibr_dmatrans_list, (pciio_dmamap_drain_f *) pcibr_dmamap_drain, (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain, (pciio_dmalist_drain_f *) pcibr_dmalist_drain, @@ -4814,23 +4121,16 @@ (pciio_priority_set_f *) pcibr_priority_set, (pciio_config_get_f *) pcibr_config_get, (pciio_config_set_f *) pcibr_config_set, -#ifdef PIC_LATER - (pciio_error_devenable_f *) pcibr_error_devenable, - (pciio_error_extract_f *) pcibr_error_extract, - (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback, - (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback, -#else (pciio_error_devenable_f *) 0, (pciio_error_extract_f *) 0, (pciio_driver_reg_callback_f *) 0, (pciio_driver_unreg_callback_f *) 0, -#endif /* PIC_LATER */ (pciio_device_unregister_f *) pcibr_device_unregister, (pciio_dma_enabled_f *) pcibr_dma_enabled, }; int -pcibr_dma_enabled(devfs_handle_t pconn_vhdl) +pcibr_dma_enabled(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); @@ -4857,7 +4157,7 @@ * parameter 'format' is sent to the console. */ void -pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...) +pcibr_debug(uint32_t type, vertex_hdl_t vhdl, char *format, ...) { char hwpath[MAXDEVNAME] = "\0"; char copy_of_hwpath[MAXDEVNAME]; @@ -4865,7 +4165,6 @@ short widget = -1; short slot = -1; va_list ap; - char *strtok_r(char *string, const char *sepset, char **lasts); if (pcibr_debug_mask & type) { if (vhdl) { @@ -4873,27 +4172,26 @@ char *cp; if (strcmp(module, pcibr_debug_module)) { - /* strtok_r() wipes out string, use a copy */ + /* use a copy */ (void)strcpy(copy_of_hwpath, hwpath); cp = strstr(copy_of_hwpath, "/module/"); if (cp) { - char *last = NULL; cp += strlen("/module"); - module = strtok_r(cp, "/", &last); + module = strsep(&cp, "/"); } } if (pcibr_debug_widget != -1) { cp = strstr(hwpath, "/xtalk/"); if (cp) { cp += strlen("/xtalk/"); - widget = atoi(cp); + widget = simple_strtoul(cp, NULL, 0); } } if (pcibr_debug_slot != -1) { cp = strstr(hwpath, "/pci/"); if (cp) { cp += strlen("/pci/"); - slot = atoi(cp); + slot = simple_strtoul(cp, NULL, 0); } } } @@ -4912,9 +4210,38 @@ * Since we have a variable length argument list, we * need to call printk this way rather than directly */ - va_start(ap, format); - printk(format, ap); - va_end(ap); + { + char buffer[500]; + + va_start(ap, format); + vsnprintf(buffer, 500, format, ap); + va_end(ap); + buffer[499] = (char)0; /* just to be safe */ + printk("%s", buffer); + } } } } + +int +isIO9(nasid_t nasid) { + lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid); + + while (brd) { + if (brd->brd_flags & LOCAL_MASTER_IO6) { + return 1; + } + brd = KLCF_NEXT(brd); + } + /* if it's dual ported, check the peer also */ + nasid = NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer; + if (nasid < 0) return 0; + brd = (lboard_t *)KL_CONFIG_INFO(nasid); + while (brd) { + if (brd->brd_flags & LOCAL_MASTER_IO6) { + return 1; + } + brd = KLCF_NEXT(brd); + } + return 0; +} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -27,26 +27,11 @@ #include #include #include -#include #include #include -#ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - extern int hubii_check_widget_disabled(nasid_t, int); -#ifdef BRIDGE_B_DATACORR_WAR -extern int ql_bridge_rev_b_war(devfs_handle_t); -extern int bridge_rev_b_data_check_disable; -char *rev_b_datacorr_warning = -"***************************** WARNING! ******************************\n"; -char *rev_b_datacorr_mesg = -"UNRECOVERABLE IO LINK ERROR. CONTACT SERVICE PROVIDER\n"; -#endif + /* ===================================================================== * ERROR HANDLING @@ -76,13 +61,9 @@ BRIDGE_ISR_PCIBUS_PIOERR; #endif -#if defined (PCIBR_LLP_CONTROL_WAR) -int pcibr_llp_control_war_cnt; -#endif /* PCIBR_LLP_CONTROL_WAR */ +int pcibr_llp_control_war_cnt; /* PCIBR_LLP_CONTROL_WAR */ -/* FIXME: can these arrays be local ? */ - -struct reg_values xio_cmd_pactyp[] = +static struct reg_values xio_cmd_pactyp[] = { {0x0, "RdReq"}, {0x1, "RdResp"}, @@ -103,7 +84,7 @@ {0} }; -struct reg_desc xio_cmd_bits[] = +static struct reg_desc xio_cmd_bits[] = { {WIDGET_DIDN, -28, "DIDN", "%x"}, {WIDGET_SIDN, -24, "SIDN", "%x"}, @@ -120,58 +101,7 @@ #define F(s,n) { 1l<<(s),-(s), n } -struct reg_desc bridge_int_status_desc[] = -{ - F(45, "PCI_X_SPLIT_MES_PE"),/* PIC ONLY */ - F(44, "PCI_X_SPLIT_EMES"), /* PIC ONLY */ - F(43, "PCI_X_SPLIT_TO"), /* PIC ONLY */ - F(42, "PCI_X_UNEX_COMP"), /* PIC ONLY */ - F(41, "INT_RAM_PERR"), /* PIC ONLY */ - F(40, "PCI_X_ARB_ERR"), /* PIC ONLY */ - F(39, "PCI_X_REQ_TOUT"), /* PIC ONLY */ - F(38, "PCI_X_TABORT"), /* PIC ONLY */ - F(37, "PCI_X_PERR"), /* PIC ONLY */ - F(36, "PCI_X_SERR"), /* PIC ONLY */ - F(35, "PCI_X_MRETRY"), /* PIC ONLY */ - F(34, "PCI_X_MTOUT"), /* PIC ONLY */ - F(33, "PCI_X_DA_PARITY"), /* PIC ONLY */ - F(32, "PCI_X_AD_PARITY"), /* PIC ONLY */ - F(31, "MULTI_ERR"), /* BRIDGE ONLY */ - F(30, "PMU_ESIZE_EFAULT"), - F(29, "UNEXPECTED_RESP"), - F(28, "BAD_XRESP_PACKET"), - F(27, "BAD_XREQ_PACKET"), - F(26, "RESP_XTALK_ERROR"), - F(25, "REQ_XTALK_ERROR"), - F(24, "INVALID_ADDRESS"), - F(23, "UNSUPPORTED_XOP"), - F(22, "XREQ_FIFO_OFLOW"), - F(21, "LLP_REC_SNERROR"), - F(20, "LLP_REC_CBERROR"), - F(19, "LLP_RCTY"), - F(18, "LLP_TX_RETRY"), - F(17, "LLP_TCTY"), - F(16, "SSRAM_PERR"), /* BRIDGE ONLY */ - F(15, "PCI_ABORT"), - F(14, "PCI_PARITY"), - F(13, "PCI_SERR"), - F(12, "PCI_PERR"), - F(11, "PCI_MASTER_TOUT"), - F(10, "PCI_RETRY_CNT"), - F(9, "XREAD_REQ_TOUT"), - F(8, "GIO_BENABLE_ERR"), /* BRIDGE ONLY */ - F(7, "INT7"), - F(6, "INT6"), - F(5, "INT5"), - F(4, "INT4"), - F(3, "INT3"), - F(2, "INT2"), - F(1, "INT1"), - F(0, "INT0"), - {0} -}; - -struct reg_values space_v[] = +static struct reg_values space_v[] = { {PCIIO_SPACE_NONE, "none"}, {PCIIO_SPACE_ROM, "ROM"}, @@ -189,13 +119,13 @@ {PCIIO_SPACE_BAD, "BAD"}, {0} }; -struct reg_desc space_desc[] = +static struct reg_desc space_desc[] = { {0xFF, 0, "space", 0, space_v}, {0} }; #define device_desc device_bits -struct reg_desc device_bits[] = +static struct reg_desc device_bits[] = { {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"}, {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"}, @@ -218,14 +148,14 @@ {0} }; -void +static void print_bridge_errcmd(uint32_t cmdword, char *errtype) { printk("\t Bridge %s Error Command Word Register ", errtype); print_register(cmdword, xio_cmd_bits); } -char *pcibr_isr_errs[] = +static char *pcibr_isr_errs[] = { "", "", "", "", "", "", "", "", "08: GIO non-contiguous byte enable in crosstalk packet", /* BRIDGE ONLY */ @@ -279,7 +209,7 @@ /* * display memory directory state */ -void +static void pcibr_show_dir_state(paddr_t paddr, char *prefix) { #ifdef LATER @@ -428,7 +358,6 @@ break; case BRIDGE_ISR_PAGE_FAULT: /* bit30 PMU_PAGE_FAULT */ -/* case BRIDGE_ISR_PMU_ESIZE_FAULT: bit30 PMU_ESIZE_FAULT */ if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) reg_desc = "Map Fault Address"; else @@ -592,31 +521,9 @@ printk( "\t%s\n", pcibr_isr_errs[i]); } } - -#if BRIDGE_ERROR_INTR_WAR - if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_A) { /* known bridge bug */ - /* - * Should never receive interrupts for these reasons on Rev 1 bridge - * as they are not enabled. Assert for it. - */ - ASSERT((int_status & (BRIDGE_IMR_PCI_MST_TIMEOUT | - BRIDGE_ISR_RESP_XTLK_ERR | - BRIDGE_ISR_LLP_TX_RETRY)) == 0); - } - if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_C) { /* known bridge bug */ - /* - * This interrupt is turned off at init time. So, should never - * see this interrupt. - */ - ASSERT((int_status & BRIDGE_ISR_BAD_XRESP_PKT) == 0); - } -#endif } -#define PCIBR_ERRINTR_GROUP(error) \ - (( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP) - -uint32_t +static uint32_t pcibr_errintr_group(uint32_t error) { uint32_t group = BRIDGE_IRR_MULTI_CLR; @@ -741,15 +648,7 @@ picreg_t int_status_64; int number_bits; int i; - - /* REFERENCED */ uint64_t disable_errintr_mask = 0; -#ifdef EHE_ENABLE - int rv; - int error_code = IOECODE_DMA | IOECODE_READ; - ioerror_mode_t mode = MODE_DEVERROR; - ioerror_t ioe; -#endif /* EHE_ENABLE */ nasid_t nasid; @@ -806,10 +705,6 @@ pcibr_soft->bs_errinfo.bserr_toutcnt++; /* Let's go recursive */ return(pcibr_error_intr_handler(irq, arg, ep)); -#ifdef LATER - timeout(pcibr_error_intr_handler, pcibr_soft, BRIDGE_PIOERR_TIMEOUT); -#endif - return; } /* We read the INT_STATUS register as a 64bit picreg_t for PIC and a @@ -847,24 +742,6 @@ pcibr_pioerr_check(pcibr_soft); } -#ifdef BRIDGE_B_DATACORR_WAR - if ((pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) && - (err_status & BRIDGE_IMR_LLP_REC_CBERR)) { - if (bridge_rev_b_data_check_disable) - printk(KERN_WARNING "\n%s%s: %s%s\n", rev_b_datacorr_warning, - pcibr_soft->bs_name, rev_b_datacorr_mesg, - rev_b_datacorr_warning); - else { - ql_bridge_rev_b_war(pcibr_soft->bs_vhdl); - PRINT_PANIC( "\n%s%s: %s%s\n", rev_b_datacorr_warning, - pcibr_soft->bs_name, rev_b_datacorr_mesg, - rev_b_datacorr_warning); - } - - err_status &= ~BRIDGE_IMR_LLP_REC_CBERR; - } -#endif /* BRIDGE_B_DATACORR_WAR */ - if (err_status) { struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat; @@ -1024,9 +901,8 @@ (0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) { err_status &= ~BRIDGE_ISR_INVLD_ADDR; } -#if defined (PCIBR_LLP_CONTROL_WAR) /* - * The bridge bug, where the llp_config or control registers + * The bridge bug (PCIBR_LLP_CONTROL_WAR), where the llp_config or control registers * need to be read back after being written, affects an MP * system since there could be small windows between writing * the register and reading it back on one cpu while another @@ -1039,40 +915,9 @@ if ((err_status & BRIDGE_ISR_INVLD_ADDR) && ((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower)) == (BRIDGE_INT_RST_STAT & 0xff0))) { -#if 0 - if (kdebug) - printk(KERN_NOTICE "%s bridge: ignoring llp/control address interrupt", - pcibr_soft->bs_name); -#endif pcibr_llp_control_war_cnt++; err_status &= ~BRIDGE_ISR_INVLD_ADDR; } -#endif /* PCIBR_LLP_CONTROL_WAR */ - -#ifdef EHE_ENABLE - /* Check if this is the RESP_XTALK_ERROR interrupt. - * This can happen due to a failed DMA READ operation. - */ - if (err_status & BRIDGE_ISR_RESP_XTLK_ERR) { - /* Phase 1 : Look at the error state in the bridge and further - * down in the device layers. - */ - (void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP); - IOERROR_SETVALUE(&ioe, widgetnum, pcibr_soft->bs_xid); - (void)pcibr_error_handler((error_handler_arg_t)pcibr_soft, - error_code, - mode, - &ioe); - /* Phase 2 : Perform the action agreed upon in phase 1. - */ - (void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION); - rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft, - error_code, - mode, - &ioe); - } - if (rv != IOERROR_HANDLED) { -#endif /* EHE_ENABLE */ bridge_errors_to_dump |= BRIDGE_ISR_PCIBUS_PIOERR; @@ -1089,25 +934,16 @@ */ if (IS_PIC_SOFT(pcibr_soft) && PCIBR_WAR_ENABLED(PV867308, pcibr_soft) && (err_status & (BRIDGE_ISR_LLP_REC_SNERR | BRIDGE_ISR_LLP_REC_CBERR))) { - printk("BRIDGE ERR_STATUS 0x%x\n", err_status); + printk("BRIDGE ERR_STATUS 0x%lx\n", err_status); pcibr_error_dump(pcibr_soft); -#ifdef LATER - machine_error_dump(""); -#endif PRINT_PANIC("PCI Bridge Error interrupt killed the system"); } if (err_status & BRIDGE_ISR_ERROR_FATAL) { -#ifdef LATER - machine_error_dump(""); -#endif PRINT_PANIC("PCI Bridge Error interrupt killed the system"); /*NOTREACHED */ } -#ifdef EHE_ENABLE - } -#endif /* * We can't return without re-enabling the interrupt, since @@ -1137,136 +973,6 @@ pcibr_soft->bs_errinfo.bserr_intstat = 0; } -/* - * pcibr_addr_toslot - * Given the 'pciaddr' find out which slot this address is - * allocated to, and return the slot number. - * While we have the info handy, construct the - * function number, space code and offset as well. - * - * NOTE: if this routine is called, we don't know whether - * the address is in CFG, MEM, or I/O space. We have to guess. - * This will be the case on PIO stores, where the only way - * we have of getting the address is to check the Bridge, which - * stores the PCI address but not the space and not the xtalk - * address (from which we could get it). - */ -int -pcibr_addr_toslot(pcibr_soft_t pcibr_soft, - iopaddr_t pciaddr, - pciio_space_t *spacep, - iopaddr_t *offsetp, - pciio_function_t *funcp) -{ - int s, f = 0, w; - iopaddr_t base; - size_t size; - pciio_piospace_t piosp; - - /* - * Check if the address is in config space - */ - - if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) { - - if (pciaddr >= BRIDGE_CONFIG1_BASE) - pciaddr -= BRIDGE_CONFIG1_BASE; - else - pciaddr -= BRIDGE_CONFIG_BASE; - - s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE; - pciaddr %= BRIDGE_CONFIG_SLOT_SIZE; - - if (funcp) { - f = pciaddr / 0x100; - pciaddr %= 0x100; - } - if (spacep) - *spacep = PCIIO_SPACE_CFG; - if (offsetp) - *offsetp = pciaddr; - if (funcp) - *funcp = f; - - return s; - } - for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) { - int nf = pcibr_soft->bs_slot[s].bss_ninfo; - pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos; - - for (f = 0; f < nf; f++) { - pcibr_info_t pcibr_info = pcibr_infoh[f]; - - if (!pcibr_info) - continue; - for (w = 0; w < 6; w++) { - if (pcibr_info->f_window[w].w_space == PCIIO_SPACE_NONE) { - continue; - } - base = pcibr_info->f_window[w].w_base; - size = pcibr_info->f_window[w].w_size; - - if ((pciaddr >= base) && (pciaddr < (base + size))) { - if (spacep) - *spacep = PCIIO_SPACE_WIN(w); - if (offsetp) - *offsetp = pciaddr - base; - if (funcp) - *funcp = f; - return s; - } /* endif match */ - } /* next window */ - } /* next func */ - } /* next slot */ - - /* - * Check if the address was allocated as part of the - * pcibr_piospace_alloc calls. - */ - for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) { - int nf = pcibr_soft->bs_slot[s].bss_ninfo; - pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos; - - for (f = 0; f < nf; f++) { - pcibr_info_t pcibr_info = pcibr_infoh[f]; - - if (!pcibr_info) - continue; - piosp = pcibr_info->f_piospace; - while (piosp) { - if ((piosp->start <= pciaddr) && - ((piosp->count + piosp->start) > pciaddr)) { - if (spacep) - *spacep = piosp->space; - if (offsetp) - *offsetp = pciaddr - piosp->start; - return s; - } /* endif match */ - piosp = piosp->next; - } /* next piosp */ - } /* next func */ - } /* next slot */ - - /* - * Some other random address on the PCI bus ... - * we have no way of knowing whether this was - * a MEM or I/O access; so, for now, we just - * assume that the low 1G is MEM, the next - * 3G is I/O, and anything above the 4G limit - * is obviously MEM. - */ - - if (spacep) - *spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM : - (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO : - PCIIO_SPACE_MEM); - if (offsetp) - *offsetp = pciaddr; - - return PCIIO_SLOT_NONE; - -} - void pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code) { @@ -1286,59 +992,6 @@ (void) bridge->b_wid_tflush; /* flushbus */ } -/* - * pcibr_error_extract - * Given the 'pcibr vertex handle' find out which slot - * the bridge status error address (from pcibr_soft info - * hanging off the vertex) - * allocated to, and return the slot number. - * While we have the info handy, construct the - * space code and offset as well. - * - * NOTE: if this routine is called, we don't know whether - * the address is in CFG, MEM, or I/O space. We have to guess. - * This will be the case on PIO stores, where the only way - * we have of getting the address is to check the Bridge, which - * stores the PCI address but not the space and not the xtalk - * address (from which we could get it). - * - * XXX- this interface has no way to return the function - * number on a multifunction card, even though that data - * is available. - */ - -pciio_slot_t -pcibr_error_extract(devfs_handle_t pcibr_vhdl, - pciio_space_t *spacep, - iopaddr_t *offsetp) -{ - pcibr_soft_t pcibr_soft = 0; - iopaddr_t bserr_addr; - bridge_t *bridge; - pciio_slot_t slot = PCIIO_SLOT_NONE; - arbitrary_info_t rev; - - /* Do a sanity check as to whether we really got a - * bridge vertex handle. - */ - if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) != - GRAPH_SUCCESS) - return(slot); - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - if (pcibr_soft) { - bridge = pcibr_soft->bs_base; - bserr_addr = - bridge->b_pci_err_lower | - ((uint64_t) (bridge->b_pci_err_upper & - BRIDGE_ERRUPPR_ADDRMASK) << 32); - - slot = pcibr_addr_toslot(pcibr_soft, bserr_addr, - spacep, offsetp, NULL); - } - return slot; -} - /*ARGSUSED */ void pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum) @@ -1426,7 +1079,7 @@ { int retval = IOERROR_HANDLED; - devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + vertex_hdl_t pcibr_vhdl = pcibr_soft->bs_vhdl; bridge_t *bridge = pcibr_soft->bs_base; iopaddr_t bad_xaddr; @@ -1806,7 +1459,7 @@ * * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges * a group of interrupts. If while handling this error, - * some other error has occured, that would be + * some other error has occurred, that would be * implicitly cleared by this write. * Need a way to ensure we don't inadvertently clear some * other errors. @@ -1837,7 +1490,7 @@ ioerror_mode_t mode, ioerror_t *ioe) { - devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + vertex_hdl_t pcibr_vhdl = pcibr_soft->bs_vhdl; bridge_t *bridge = pcibr_soft->bs_base; bridgereg_t bus_lowaddr, bus_uppraddr; int retval = 0; @@ -1874,7 +1527,7 @@ BRIDGE_ERRUPPR_ADDRMASK) << 32))); /* - * need to ensure that the xtalk adress in ioe + * need to ensure that the xtalk address in ioe * maps to PCI error address read from bridge. * How to convert PCI address back to Xtalk address ? * (better idea: convert XTalk address to PCI address @@ -1946,7 +1599,7 @@ ioerror_mode_t mode, ioerror_t *ioe) { - devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + vertex_hdl_t pcibr_vhdl = pcibr_soft->bs_vhdl; int retval; retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe); @@ -1982,34 +1635,12 @@ pcibr_soft_t pcibr_soft; int retval = IOERROR_BADERRORCODE; -#ifdef EHE_ENABLE - devfs_handle_t xconn_vhdl,pcibr_vhdl; - error_state_t e_state; -#endif /* EHE_ENABLE */ - pcibr_soft = (pcibr_soft_t) einfo; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ERROR_HDLR, pcibr_soft->bs_conn, "pcibr_error_handler: pcibr_soft=0x%x, error_code=0x%x\n", pcibr_soft, error_code)); -#ifdef EHE_ENABLE - xconn_vhdl = pcibr_soft->bs_conn; - pcibr_vhdl = pcibr_soft->bs_vhdl; - - e_state = error_state_get(xconn_vhdl); - - if (error_state_set(pcibr_vhdl, e_state) == - ERROR_RETURN_CODE_CANNOT_SET_STATE) - return(IOERROR_UNHANDLED); - - /* If we are in the action handling phase clean out the error state - * on the xswitch. - */ - if (e_state == ERROR_STATE_ACTION) - (void)error_state_set(xconn_vhdl, ERROR_STATE_NONE); -#endif /* EHE_ENABLE */ - #if DEBUG && ERROR_DEBUG printk( "%s: pcibr_error_handler\n", pcibr_soft->bs_name); #endif @@ -2086,11 +1717,6 @@ * the error from the PIO address. */ -#if 0 - if (mode == MODE_DEVPROBE) - pio_retval = IOERROR_HANDLED; - else { -#endif if (error_code & IOECODE_PIO) { iopaddr_t bad_xaddr; /* @@ -2123,9 +1749,6 @@ pio_retval = IOERROR_UNHANDLED; } } -#if 0 - } /* MODE_DEVPROBE */ -#endif /* * If the error was a result of a DMA Write, we tell what bus on the PIC @@ -2201,37 +1824,3 @@ return IOERROR_HANDLED; } } - - -/* - * Reenable a device after handling the error. - * This is called by the lower layers when they wish to be reenabled - * after an error. - * Note that each layer would be calling the previous layer to reenable - * first, before going ahead with their own re-enabling. - */ - -int -pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - ASSERT(error_code & IOECODE_PIO); - - /* If the error is not known to be a write, - * we have to call devenable. - * write errors are isolated to the bridge. - */ - if (!(error_code & IOECODE_WRITE)) { - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - int rc; - - rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code); - if (rc != IOERROR_HANDLED) - return rc; - } - pcibr_error_cleanup(pcibr_soft, error_code); - return IOERROR_HANDLED; -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -27,20 +27,19 @@ #include #include #include -#include #include #include -pcibr_hints_t pcibr_hints_get(devfs_handle_t, int); -void pcibr_hints_fix_rrbs(devfs_handle_t); -void pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t); -void pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *); -void pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t); -void pcibr_hints_handsoff(devfs_handle_t); -void pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t); +pcibr_hints_t pcibr_hints_get(vertex_hdl_t, int); +void pcibr_hints_fix_rrbs(vertex_hdl_t); +void pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t); +void pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *); +void pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t); +void pcibr_hints_handsoff(vertex_hdl_t); +void pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t); pcibr_hints_t -pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc) +pcibr_hints_get(vertex_hdl_t xconn_vhdl, int alloc) { arbitrary_info_t ainfo = 0; graph_error_t rv; @@ -79,7 +78,7 @@ } void -pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask) +pcibr_hints_fix_some_rrbs(vertex_hdl_t xconn_vhdl, unsigned mask) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -91,13 +90,13 @@ } void -pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl) +pcibr_hints_fix_rrbs(vertex_hdl_t xconn_vhdl) { pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF); } void -pcibr_hints_dualslot(devfs_handle_t xconn_vhdl, +pcibr_hints_dualslot(vertex_hdl_t xconn_vhdl, pciio_slot_t host, pciio_slot_t guest) { @@ -111,7 +110,7 @@ } void -pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl, +pcibr_hints_intr_bits(vertex_hdl_t xconn_vhdl, pcibr_intr_bits_f *xxx_intr_bits) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -124,7 +123,7 @@ } void -pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct) +pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -133,7 +132,7 @@ } void -pcibr_hints_handsoff(devfs_handle_t xconn_vhdl) +pcibr_hints_handsoff(vertex_hdl_t xconn_vhdl) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -145,13 +144,13 @@ } void -pcibr_hints_subdevs(devfs_handle_t xconn_vhdl, +pcibr_hints_subdevs(vertex_hdl_t xconn_vhdl, pciio_slot_t slot, uint64_t subdevs) { arbitrary_info_t ainfo = 0; char sdname[16]; - devfs_handle_t pconn_vhdl = GRAPH_VERTEX_NONE; + vertex_hdl_t pconn_vhdl = GRAPH_VERTEX_NONE; sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot); (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl); diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,147 +0,0 @@ -/* - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef LATER - -char *pci_space[] = {"NONE", - "ROM", - "IO", - "", - "MEM", - "MEM32", - "MEM64", - "CFG", - "WIN0", - "WIN1", - "WIN2", - "WIN3", - "WIN4", - "WIN5", - "", - "BAD"}; - -void -idbg_pss_func(pcibr_info_h pcibr_infoh, int func) -{ - pcibr_info_t pcibr_info = pcibr_infoh[func]; - char name[MAXDEVNAME]; - int win; - - if (!pcibr_info) - return; - qprintf("Per-slot Function Info\n"); - sprintf(name, "%v", pcibr_info->f_vertex); - qprintf("\tSlot Name : %s\n",name); - qprintf("\tPCI Bus : %d ",pcibr_info->f_bus); - qprintf("Slot : %d ", pcibr_info->f_slot); - qprintf("Function : %d ", pcibr_info->f_func); - qprintf("VendorId : 0x%x " , pcibr_info->f_vendor); - qprintf("DeviceId : 0x%x\n", pcibr_info->f_device); - sprintf(name, "%v", pcibr_info->f_master); - qprintf("\tBus provider : %s\n",name); - qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops); - qprintf("Error Handler : 0x%x Arg 0x%x\n", - pcibr_info->f_efunc,pcibr_info->f_einfo); - for(win = 0 ; win < 6 ; win++) - qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n", - win,pci_space[pcibr_info->f_window[win].w_space], - pcibr_info->f_window[win].w_base, - pcibr_info->f_window[win].w_size); - - qprintf("\tRom base 0x%x size 0x%x\n", - pcibr_info->f_rbase,pcibr_info->f_rsize); - - qprintf("\tInterrupt Bit Map\n"); - qprintf("\t\tPCI Int#\tBridge Pin#\n"); - for (win = 0 ; win < 4; win++) - qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]); - qprintf("\n"); -} - - -void -idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot) -{ - pcibr_soft_slot_t pss; - char slot_conn_name[MAXDEVNAME]; - int func; - - pss = &pcibr_soft->bs_slot[slot]; - qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot); - qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no"); - qprintf("\tHost Slot : %d\n",pss->host_slot); - sprintf(slot_conn_name, "%v", pss->slot_conn); - qprintf("\tSlot Conn : %s\n",slot_conn_name); - qprintf("\t#Functions : %d\n",pss->bss_ninfo); - for (func = 0; func < pss->bss_ninfo; func++) - idbg_pss_func(pss->bss_infos,func); - qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]); - qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base); - qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device); - qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n", - pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr); - - qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x" - "d32_base 0x%x d32_flags 0x%x\n", - pss->bss_d64_base, pss->bss_d64_flags, - pss->bss_d32_base, pss->bss_d32_flags); - - qprintf("\tExt ATEs active ? %s", - pss->bss_ext_ates_active ? "yes" : "no"); - qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer); - qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow); - - qprintf("\tRRB Info : Valid %d+%d Reserved %d\n", - pcibr_soft->bs_rrb_valid[slot], - pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], - pcibr_soft->bs_rrb_res[slot]); - -} - -int ips = 0; - -void -idbg_pss(pcibr_soft_t pcibr_soft) -{ - pciio_slot_t slot; - - - if (ips >= 0 && ips < 8) - idbg_pss_info(pcibr_soft,ips); - else if (ips < 0) - for (slot = 0; slot < 8; slot++) - idbg_pss_info(pcibr_soft,slot); - else - qprintf("Invalid ips %d\n",ips); -} -#endif /* LATER */ diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -27,29 +27,35 @@ #include #include #include -#include #include #include #ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc +inline int +compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr) +{ + FIXME("compare_and_swap_ptr : NOT ATOMIC"); + if (*location == old_ptr) { + *location = new_ptr; + return(1); + } + else + return(0); +} #endif unsigned pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines, int nslots); -pcibr_intr_t pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +pcibr_intr_t pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t); void pcibr_intr_free(pcibr_intr_t); void pcibr_setpciint(xtalk_intr_t); int pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t); void pcibr_intr_disconnect(pcibr_intr_t); -devfs_handle_t pcibr_intr_cpu_get(pcibr_intr_t); +vertex_hdl_t pcibr_intr_cpu_get(pcibr_intr_t); void pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); void pcibr_intr_func(intr_arg_t); -extern pcibr_info_t pcibr_info_get(devfs_handle_t); +extern pcibr_info_t pcibr_info_get(vertex_hdl_t); /* ===================================================================== * INTERRUPT MANAGEMENT @@ -132,6 +138,102 @@ } /* + * On SN systems there is a race condition between a PIO read response + * and DMA's. In rare cases, the read response may beat the DMA, causing + * the driver to think that data in memory is complete and meaningful. + * This code eliminates that race. + * This routine is called by the PIO read routines after doing the read. + * This routine then forces a fake interrupt on another line, which + * is logically associated with the slot that the PIO is addressed to. + * (see sn_dma_flush_init() ) + * It then spins while watching the memory location that the interrupt + * is targetted to. When the interrupt response arrives, we are sure + * that the DMA has landed in memory and it is safe for the driver + * to proceed. + */ + +extern struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS]; + +void +sn_dma_flush(unsigned long addr) { + nasid_t nasid; + int wid_num; + volatile struct sn_flush_device_list *p; + int i,j; + int bwin; + unsigned long flags; + + nasid = NASID_GET(addr); + wid_num = SWIN_WIDGETNUM(addr); + bwin = BWIN_WINDOWNUM(addr); + + if (flush_nasid_list[nasid].widget_p == NULL) return; + if (bwin > 0) { + bwin--; + switch (bwin) { + case 0: + wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf; + break; + case 1: + wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf; + break; + case 2: + wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf; + break; + case 3: + wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf; + break; + case 4: + wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf; + break; + case 5: + wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf; + break; + case 6: + wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf; + break; + } + } + if (flush_nasid_list[nasid].widget_p == NULL) return; + if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) return; + p = &flush_nasid_list[nasid].widget_p[wid_num][0]; + + // find a matching BAR + + for (i=0; ibar_list[j].start == 0) break; + if (addr >= p->bar_list[j].start && addr <= p->bar_list[j].end) break; + } + if (j < PCI_ROM_RESOURCE && p->bar_list[j].start != 0) break; + p++; + } + + // if no matching BAR, return without doing anything. + + if (i == DEV_PER_WIDGET) return; + + spin_lock_irqsave(&p->flush_lock, flags); + + p->flush_addr = 0; + + // force an interrupt. + + *(bridgereg_t *)(p->force_int_addr) = 1; + + // wait for the interrupt to come back. + + while (p->flush_addr != 0x10f); + + // okay, everything is synched up. + spin_unlock_irqrestore(&p->flush_lock, flags); + + return; +} + +EXPORT_SYMBOL(sn_dma_flush); + +/* * There are end cases where a deadlock can occur if interrupt * processing completes and the Bridge b_int_status bit is still set. * @@ -164,51 +266,42 @@ * to check if a specific Bridge b_int_status bit is set, and if so, * cause the setting of the corresponding interrupt bit. * - * On a XBridge (SN1), we do this by writing the appropriate Bridge Force - * Interrupt register. On SN0, or SN1 with an older Bridge, the Bridge - * Force Interrupt register does not exist, so we write the Hub - * INT_PEND_MOD register directly. Likewise for Octane, where we write the - * Heart Set Interrupt Status register directly. + * On a XBridge (SN1) and PIC (SN2), we do this by writing the appropriate Bridge Force + * Interrupt register. */ void -pcibr_force_interrupt(pcibr_intr_wrap_t wrap) +pcibr_force_interrupt(pcibr_intr_t intr) { -#ifdef PIC_LATER unsigned bit; - pcibr_soft_t pcibr_soft = wrap->iw_soft; + unsigned bits; + pcibr_soft_t pcibr_soft = intr->bi_soft; bridge_t *bridge = pcibr_soft->bs_base; - bit = wrap->iw_ibit; + bits = intr->bi_ibits; + for (bit = 0; bit < 8; bit++) { + if (bits & (1 << bit)) { - PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl, - "pcibr_force_interrupt: bit=0x%x\n", bit)); + PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl, + "pcibr_force_interrupt: bit=0x%x\n", bit)); - if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) { - bridge->b_force_pin[bit].intr = 1; - } else if ((1 << bit) & *wrap->iw_stat) { - cpuid_t cpu; - unsigned intr_bit; - xtalk_intr_t xtalk_intr = - pcibr_soft->bs_intr[bit].bsi_xtalk_intr; - - intr_bit = (short) xtalk_intr_vector_get(xtalk_intr); - cpu = xtalk_intr_cpuid_get(xtalk_intr); - REMOTE_CPU_SEND_INTR(cpu, intr_bit); + if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) { + bridge->b_force_pin[bit].intr = 1; + } + } } -#endif /* PIC_LATER */ } /*ARGSUSED */ pcibr_intr_t -pcibr_intr_alloc(devfs_handle_t pconn_vhdl, +pcibr_intr_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_intr_line_t lines, - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pcibr_info); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; bridge_t *bridge = pcibr_soft->bs_base; int is_threaded = 0; @@ -498,25 +591,18 @@ { iopaddr_t addr; xtalk_intr_vector_t vect; - devfs_handle_t vhdl; + vertex_hdl_t vhdl; bridge_t *bridge; + picreg_t *int_addr; addr = xtalk_intr_addr_get(xtalk_intr); vect = xtalk_intr_vector_get(xtalk_intr); vhdl = xtalk_intr_dev_get(xtalk_intr); bridge = (bridge_t *)xtalk_piotrans_addr(vhdl, 0, 0, sizeof(bridge_t), 0); - if (is_pic(bridge)) { - picreg_t *int_addr; - int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr); - *int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) | + int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr); + *int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) | (PIC_INT_ADDR_HOST & addr)); - } else { - bridgereg_t *int_addr; - int_addr = (bridgereg_t *)xtalk_intr_sfarg_get(xtalk_intr); - *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) | - (BRIDGE_INT_ADDR_FLD & vect)); - } } /*ARGSUSED */ @@ -582,8 +668,7 @@ PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev, "pcibr_setpciint: int_addr=0x%x, *int_addr=0x%x, " "pcibr_int_bit=0x%x\n", int_addr, - (is_pic(bridge) ? - *(picreg_t *)int_addr : *(bridgereg_t *)int_addr), + *(picreg_t *)int_addr, pcibr_int_bit)); } @@ -699,7 +784,7 @@ xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr, pcibr_intr_func, (intr_arg_t) intr_wrap, (xtalk_intr_setfunc_t)pcibr_setpciint, - (void *)pcibr_int_bit); + (void *)(long)pcibr_int_bit); PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev, "pcibr_intr_disconnect: now-sharing int_bits=0x%x\n", pcibr_int_bit)); @@ -707,7 +792,7 @@ } /*ARGSUSED */ -devfs_handle_t +vertex_hdl_t pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr) { pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; @@ -780,9 +865,6 @@ bridge->b_wid_int_lower = NEW_b_wid_int_lower; bridge->b_int_host_err = vect; -printk("pcibr_setwidint: b_wid_int_upper 0x%x b_wid_int_lower 0x%x b_int_host_err 0x%x\n", - NEW_b_wid_int_upper, NEW_b_wid_int_lower, vect); - } /* @@ -842,7 +924,7 @@ * * This is the pcibr interrupt "wrapper" function that is called, * in interrupt context, to initiate the interrupt handler(s) registered - * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded + * (via pcibr_intr_alloc/connect) for the occurring interrupt. Non-threaded * handlers will be called directly, and threaded handlers will have their * thread woken up. */ @@ -957,7 +1039,7 @@ * interrupt to avoid a potential deadlock situation. */ if (wrap->iw_hdlrcnt == 0) { - pcibr_force_interrupt(wrap); + pcibr_force_interrupt((pcibr_intr_t) wrap); } } diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -41,11 +40,11 @@ void do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int); -int pcibr_wrb_flush(devfs_handle_t); -int pcibr_rrb_alloc(devfs_handle_t, int *, int *); -int pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *); -void pcibr_rrb_flush(devfs_handle_t); -int pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t); +int pcibr_wrb_flush(vertex_hdl_t); +int pcibr_rrb_alloc(vertex_hdl_t, int *, int *); +int pcibr_rrb_check(vertex_hdl_t, int *, int *, int *, int *); +void pcibr_rrb_flush(vertex_hdl_t); +int pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t); void pcibr_rrb_debug(char *, pcibr_soft_t); @@ -70,17 +69,15 @@ #define RRB_SIZE (4) /* sizeof rrb within reg (bits) */ #define RRB_ENABLE_BIT(bridge) (0x8) /* [BRIDGE | PIC]_RRB_EN */ -#define NUM_PDEV_BITS(bridge) (is_pic((bridge)) ? 1 : 2) -#define NUM_VDEV_BITS(bridge) (is_pic((bridge)) ? 2 : 1) -#define NUMBER_VCHANNELS(bridge) (is_pic((bridge)) ? 4 : 2) +#define NUM_PDEV_BITS(bridge) (1) +#define NUM_VDEV_BITS(bridge) (2) +#define NUMBER_VCHANNELS(bridge) (4) #define SLOT_2_PDEV(bridge, slot) ((slot) >> 1) #define SLOT_2_RRB_REG(bridge, slot) ((slot) & 0x1) /* validate that the slot and virtual channel are valid for a given bridge */ #define VALIDATE_SLOT_n_VCHAN(bridge, s, v) \ - (is_pic((bridge)) ? \ - (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0) : \ - (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)7)) && (((v) >= 0) && ((v) <= 1))) ? 1 : 0)) + (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0) /* * Count how many RRBs are marked valid for the specified PCI slot @@ -105,16 +102,7 @@ pdev_bits = SLOT_2_PDEV(bridge, slot); rrb_bits = enable_bit | vchan_bits | pdev_bits; - if ( is_pic(bridge) ) { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } + tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; for (rrb_index = 0; rrb_index < 8; rrb_index++) { if ((tmp & RRB_MASK) == rrb_bits) @@ -144,16 +132,7 @@ enable_bit = RRB_ENABLE_BIT(bridge); - if ( is_pic(bridge) ) { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } + tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; for (rrb_index = 0; rrb_index < 8; rrb_index++) { if ((tmp & enable_bit) != enable_bit) @@ -192,17 +171,8 @@ pdev_bits = SLOT_2_PDEV(bridge, slot); rrb_bits = enable_bit | vchan_bits | pdev_bits; - if ( is_pic(bridge) ) { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - reg = tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } - + reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; + for (rrb_index = 0; ((rrb_index < 8) && (more > 0)); rrb_index++) { if ((tmp & enable_bit) != enable_bit) { /* clear the rrb and OR in the new rrb into 'reg' */ @@ -213,16 +183,7 @@ tmp = (tmp >> RRB_SIZE); } - if ( is_pic(bridge) ) { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg; - } else { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - } + bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; return (more ? -1 : 0); } @@ -255,24 +216,15 @@ pdev_bits = SLOT_2_PDEV(bridge, slot); rrb_bits = enable_bit | vchan_bits | pdev_bits; - if ( is_pic(bridge) ) { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - reg = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } - + reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; + for (rrb_index = 0; ((rrb_index < 8) && (less > 0)); rrb_index++) { if ((tmp & RRB_MASK) == rrb_bits) { /* * the old do_pcibr_rrb_free() code only clears the enable bit * but I say we should clear the whole rrb (ie): * reg = reg & ~(RRB_MASK << (RRB_SIZE * rrb_index)); - * But to be compatable with old code we'll only clear enable. + * But to be compatible with old code we'll only clear enable. */ reg = reg & ~(RRB_ENABLE_BIT(bridge) << (RRB_SIZE * rrb_index)); clr = clr | (enable_bit << (RRB_SIZE * rrb_index)); @@ -281,16 +233,7 @@ tmp = (tmp >> RRB_SIZE); } - if ( is_pic(bridge) ) { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg; - } else { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - } + bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; /* call do_pcibr_rrb_clear() for all the rrbs we've freed */ for (rrb_index = 0; rrb_index < 8; rrb_index++) { @@ -337,50 +280,18 @@ * this RRB must be disabled. */ - if ( is_pic(bridge) ) { - /* wait until RRB has no outstanduing XIO packets. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - - /* if the RRB has data, drain it. */ - if (status & BRIDGE_RRB_VALID(rrb)) { - bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); - - /* wait until RRB is no longer valid. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - } + /* wait until RRB has no outstanduing XIO packets. */ + while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { + ; /* XXX- beats on bridge. bad idea? */ } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_INUSE(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - - /* if the RRB has data, drain it. */ - if (status & BRIDGE_RRB_VALID(rrb)) { - BRIDGE_REG_SET32((&bridge->b_resp_clear)) = __swab32(BRIDGE_RRB_CLEAR(rrb)); - - /* wait until RRB is no longer valid. */ - while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_VALID(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - } - } else { /* io_get_sh_swapper(NASID_GET(bridge)) */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - - /* if the RRB has data, drain it. */ - if (status & BRIDGE_RRB_VALID(rrb)) { - bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); - /* wait until RRB is no longer valid. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - } + + /* if the RRB has data, drain it. */ + if (status & BRIDGE_RRB_VALID(rrb)) { + bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); + + /* wait until RRB is no longer valid. */ + while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { + ; /* XXX- beats on bridge. bad idea? */ } } } @@ -399,43 +310,16 @@ int shft = (RRB_SIZE * (rrbn >> 1)); unsigned long ebit = RRB_ENABLE_BIT(bridge) << shft; - if ( is_pic(bridge) ) { - rrbv = *rrbp; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - rrbv = BRIDGE_REG_GET32((&rrbp)); - } else { - rrbv = *rrbp; - } - } + rrbv = *rrbp; if (rrbv & ebit) { - if ( is_pic(bridge) ) { - *rrbp = rrbv & ~ebit; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&rrbp)) = __swab32((rrbv & ~ebit)); - } else { - *rrbp = rrbv & ~ebit; - } - } + *rrbp = rrbv & ~ebit; } do_pcibr_rrb_clear(bridge, rrbn); if (rrbv & ebit) { - if ( is_pic(bridge) ) { - *rrbp = rrbv; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&rrbp)) = __swab32(rrbv); - } else { - *rrbp = rrbv; - } - } + *rrbp = rrbv; } } @@ -475,7 +359,7 @@ * Flush all the rrb's assigned to the specified connection point. */ void -pcibr_rrb_flush(devfs_handle_t pconn_vhdl) +pcibr_rrb_flush(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t)pciio_info_mfast_get(pciio_info); @@ -510,7 +394,7 @@ * device hanging off the bridge. */ int -pcibr_wrb_flush(devfs_handle_t pconn_vhdl) +pcibr_wrb_flush(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); @@ -546,7 +430,7 @@ * as best we can and return 0. */ int -pcibr_rrb_alloc(devfs_handle_t pconn_vhdl, +pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl, int *count_vchan0, int *count_vchan1) { @@ -753,7 +637,7 @@ */ int -pcibr_rrb_check(devfs_handle_t pconn_vhdl, +pcibr_rrb_check(vertex_hdl_t pconn_vhdl, int *count_vchan0, int *count_vchan1, int *count_reserved, @@ -802,7 +686,7 @@ */ int -pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl, +pcibr_slot_initial_rrb_alloc(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -816,10 +700,10 @@ pcibr_soft = pcibr_soft_get(pcibr_vhdl); if (!pcibr_soft) - return(EINVAL); + return(-EINVAL); if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) - return(EINVAL); + return(-EINVAL); bridge = pcibr_soft->bs_base; @@ -857,7 +741,13 @@ pcibr_soft->bs_rrb_valid[slot][3] = chan[3]; - return(ENODEV); + return(-ENODEV); + } + + /* Give back any assigned to empty slots */ + if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) && !pcibr_soft->bs_slot[slot].has_host) { + do_pcibr_rrb_free_all(pcibr_soft, bridge, slot); + return(-ENODEV); } for (vchan = 0; vchan < vchan_total; vchan++) @@ -889,7 +779,7 @@ */ int -pcibr_initial_rrb(devfs_handle_t pcibr_vhdl, +pcibr_initial_rrb(vertex_hdl_t pcibr_vhdl, pciio_slot_t first, pciio_slot_t last) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -28,55 +28,44 @@ #include #include #include -#include #include #include -#include -#ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - - -extern pcibr_info_t pcibr_info_get(devfs_handle_t); -extern int pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl); +extern pcibr_info_t pcibr_info_get(vertex_hdl_t); +extern int pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl); extern pcibr_info_t pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); -extern int pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t); +extern int pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t); extern int pcibr_pcix_rbars_calc(pcibr_soft_t); -int pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); int pcibr_slot_pcix_rbar_init(pcibr_soft_t pcibr_soft, pciio_slot_t slot); -int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, +int pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags); -int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, +int pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags); -int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot, +int pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, int *sub_errorp); -int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); static int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *); -void pcibr_device_info_free(devfs_handle_t, pciio_slot_t); +void pcibr_device_info_free(vertex_hdl_t, pciio_slot_t); iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, pciio_space_t, int, int, int); void pciibr_bus_addr_free(pcibr_soft_t, pciio_win_info_t); cfg_p pcibr_find_capability(cfg_p, unsigned); -extern uint64_t do_pcibr_config_get(int, cfg_p, unsigned, unsigned); -void do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t); +extern uint64_t do_pcibr_config_get(cfg_p, unsigned, unsigned); +void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); -int pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot, +int pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, int *sub_errorp); int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot, pcibr_slot_info_resp_t respp); -extern devfs_handle_t baseio_pci_vhdl; -int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t); +extern vertex_hdl_t baseio_pci_vhdl; +int scsi_ctlr_nums_add(vertex_hdl_t, vertex_hdl_t); /* For now .... */ @@ -111,7 +100,7 @@ #ifdef PIC_LATER int -pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) +pcibr_slot_startup(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); pciio_slot_t slot; @@ -127,11 +116,6 @@ /* req_slot is the 'external' slot number, convert for internal use */ slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot); - /* Do not allow start-up of a slot in a shoehorn */ - if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) { - return(PCI_SLOT_IN_SHOEHORN); - } - /* Check for the valid slot */ if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) return(PCI_NOT_A_SLOT); @@ -170,7 +154,7 @@ * Software shut-down the PCI slot */ int -pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) +pcibr_slot_shutdown(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); bridge_t *bridge; @@ -194,11 +178,6 @@ if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) return(PCI_NOT_A_SLOT); - /* Do not allow shut-down of a slot in a shoehorn */ - if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) { - return(PCI_SLOT_IN_SHOEHORN); - } - #ifdef PIC_LATER /* Acquire update access to the bus */ mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO); @@ -284,7 +263,6 @@ { pcibr_info_t pcibr_info = pcibr_infoh[func]; int win; - boolean_t is_sys_critical_vertex(devfs_handle_t); funcp->resp_f_status = 0; @@ -296,9 +274,6 @@ #if defined(SUPPORT_PRINTING_V_FORMAT) sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex); #endif - if(is_sys_critical_vertex(pcibr_info->f_vertex)) { - funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL; - } funcp->resp_f_bus = pcibr_info->f_bus; funcp->resp_f_slot = PCIBR_INFO_SLOT_GET_EXT(pcibr_info); @@ -345,7 +320,6 @@ reg_p b_respp; pcibr_slot_info_resp_t slotp; pcibr_slot_func_info_resp_t funcp; - boolean_t is_sys_critical_vertex(devfs_handle_t); extern void snia_kmem_free(void *, int); slotp = snia_kmem_zalloc(sizeof(*slotp), 0); @@ -368,11 +342,6 @@ slotp->resp_slot_status = pss->slot_status; slotp->resp_l1_bus_num = pcibr_widget_to_bus(pcibr_soft->bs_vhdl); - - if (is_sys_critical_vertex(pss->slot_conn)) { - slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL; - } - slotp->resp_bss_ninfo = pss->bss_ninfo; for (func = 0; func < pss->bss_ninfo; func++) { @@ -455,7 +424,7 @@ * External SSRAM workaround info */ int -pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) +pcibr_slot_query(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); pciio_slot_t slot; @@ -481,11 +450,6 @@ return(PCI_NOT_A_SLOT); } - /* Do not allow a query of a slot in a shoehorn */ - if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) { - return(PCI_SLOT_IN_SHOEHORN); - } - /* Return information for the requested PCI slot */ if (slot != PCIIO_SLOT_NONE) { if (size < sizeof(*respp)) { @@ -534,88 +498,6 @@ return(error); } -#if 0 -/* - * pcibr_slot_reset - * Reset the PCI device in the particular slot. - * - * The Xbridge does not comply with the PCI Specification - * when resetting an indiviaudl slot. An individual slot is - * is reset by toggling the slot's bit in the Xbridge Control - * Register. The Xbridge will assert the target slot's - * (non-bussed) RST signal, but does not assert the (bussed) - * REQ64 signal as required by the specification. As - * designed, the Xbridge cannot assert the REQ64 signal - * becuase it may interfere with a bus transaction in progress. - * The practical effects of this Xbridge implementation is - * device dependent; it probably will not adversely effect - * 32-bit cards, but may disable 64-bit data transfers by those - * cards that normally support 64-bit data transfers. - * - * The Xbridge will assert REQ64 when all four slots are reset - * by simultaneously toggling all four slot reset bits in the - * Xbridge Control Register. This is basically a PCI bus reset - * and asserting the (bussed) REQ64 signal will not interfere - * with any bus transactions in progress. - * - * The Xbridge (and the SN0 Bridge) support resetting only - * four PCI bus slots via the (X)bridge Control Register. - * - * To reset an individual slot for the PCI Hot-Plug feature - * use the L1 console commands to power-down and then - * power-up the slot, or use the kernel infrastructure - * functions to power-down/up the slot when they are - * implemented for SN1. - */ -int -pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge_t *bridge; - bridgereg_t ctrlreg,tmp; - volatile bridgereg_t *wrb_flush; - - if (!pcibr_soft) - return(EINVAL); - - if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) - return(EINVAL); - - /* Enable the DMA operations from this device of the xtalk widget - * (PCI host bridge in this case). - */ - xtalk_widgetdev_enable(pcibr_soft->bs_conn, slot); - - /* Set the reset slot bit in the bridge's wid control register - * to reset the PCI slot - */ - bridge = pcibr_soft->bs_base; - - /* Read the bridge widget control and clear out the reset pin - * bit for the corresponding slot. - */ - tmp = ctrlreg = bridge->b_wid_control; - - tmp &= ~BRIDGE_CTRL_RST_PIN(slot); - - bridge->b_wid_control = tmp; - tmp = bridge->b_wid_control; - - /* Restore the old control register back. - * NOTE : PCI card gets reset when the reset pin bit - * changes from 0 (set above) to 1 (going to be set now). - */ - - bridge->b_wid_control = ctrlreg; - - /* Flush the write buffers if any !! */ - wrb_flush = &(bridge->b_wr_req_buf[slot].reg); - while (*wrb_flush); - - return(0); -} -#endif - #define PROBE_LOCK 0 /* FIXME: we're attempting to lock around accesses * to b_int_enable. This hangs pcibr_probe_slot() */ @@ -627,7 +509,7 @@ * information associated with this particular PCI device. */ int -pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -650,7 +532,7 @@ int nfunc; pciio_function_t rfunc; int func; - devfs_handle_t conn_vhdl; + vertex_hdl_t conn_vhdl; pcibr_soft_slot_t slotp; /* Get the basic software information required to proceed */ @@ -669,10 +551,6 @@ return(0); } - /* Check for a slot with any system critical functions */ - if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot)) - return(EPERM); - /* Try to read the device-id/vendor-id from the config space */ cfgw = pcibr_slot_config_addr(bridge, slot, 0); @@ -701,7 +579,7 @@ if (vendor == 0xFFFF) return(ENODEV); - htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1); + htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); nfunc = 1; rfunc = PCIIO_FUNC_NONE; pfail = 0; @@ -750,7 +628,7 @@ cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0); device = 0xFFFF & (idword >> 16); - htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1); + htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); rfunc = func; } htype &= 0x7f; @@ -803,23 +681,17 @@ * 'min_gnt' and attempt to calculate a latency time. * * NOTE: For now if the device is on the 'real time' arbitration - * ring we dont set the latency timer. + * ring we don't set the latency timer. * * WAR: SGI's IOC3 and RAD devices target abort if you write a * single byte into their config space. So don't set the Latency * Timer for these devices */ - lt_time = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1); + lt_time = do_pcibr_config_get(cfgw, PCI_CFG_LATENCY_TIMER, 1); if ((lt_time == 0) && !(bridge->b_device[slot].reg & BRIDGE_DEV_RT) && - !((vendor == IOC3_VENDOR_ID_NUM) && - ( -#ifdef PIC_LATER - (device == IOC3_DEVICE_ID_NUM) || - (device == LINC_DEVICE_ID_NUM) || -#endif - (device == 0x5 /* RAD_DEV */)))) { + (device == 0x5 /* RAD_DEV */)) { unsigned min_gnt; unsigned min_gnt_mult; @@ -827,7 +699,7 @@ * needs in increments of 250ns. But latency timer is in * PCI clock cycles, so a conversion is needed. */ - min_gnt = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_MIN_GNT, 1); + min_gnt = do_pcibr_config_get(cfgw, PCI_MIN_GNT, 1); if (IS_133MHZ(pcibr_soft)) min_gnt_mult = 32; /* 250ns @ 133MHz in clocks */ @@ -843,7 +715,7 @@ else lt_time = 4 * min_gnt_mult; /* 1 micro second */ - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time); + do_pcibr_config_set(cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time); PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl, "pcibr_slot_info_init: set Latency Timer for slot=%d, " @@ -851,12 +723,27 @@ PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func, lt_time)); } - /* Get the PCI-X capability if running in PCI-X mode. If the func - * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE - * pcibr_info struct so the device driver for that function is not - * called. + + /* In our architecture the setting of the cacheline size isn't + * beneficial for cards in PCI mode, but in PCI-X mode devices + * can optionally use the cacheline size value for internal + * device optimizations (See 7.1.5 of the PCI-X v1.0 spec). + * NOTE: cachline size is in doubleword increments */ if (IS_PCIX(pcibr_soft)) { + if (!do_pcibr_config_get(cfgw, PCI_CFG_CACHE_LINE, 1)) { + do_pcibr_config_set(cfgw, PCI_CFG_CACHE_LINE, 1, 0x20); + PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl, + "pcibr_slot_info_init: set CacheLine for slot=%d, " + "func=%d, to 0x20\n", + PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func)); + } + + /* Get the PCI-X capability if running in PCI-X mode. If the func + * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE + * pcibr_info struct so the device driver for that function is not + * called. + */ if (!(pcix_cap = pcibr_find_capability(cfgw, PCI_CAP_PCIX))) { printk(KERN_WARNING #if defined(SUPPORT_PRINTING_V_FORMAT) @@ -898,7 +785,7 @@ if (func == 0) slotp->slot_conn = conn_vhdl; - cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4); + cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4); wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; @@ -949,7 +836,7 @@ * this could be pushed up into pciio, when we * start supporting more PCI providers. */ - base = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4); + base = do_pcibr_config_get(wptr, (win * 4), 4); if (base & PCI_BA_IO_SPACE) { /* BASE is in I/O space. */ @@ -975,7 +862,7 @@ } else if (base & 0xC0000000) { base = 0; /* outside permissable range */ } else if ((code == PCI_BA_MEM_64BIT) && - (do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, ((win + 1)*4), 4) != 0)) { + (do_pcibr_config_get(wptr, ((win + 1)*4), 4) != 0)) { base = 0; /* outside permissable range */ } } @@ -983,8 +870,8 @@ if (base != 0) { /* estimate size */ size = base & -base; } else { /* calculate size */ - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, ~0); /* write 1's */ - size = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4); /* read back */ + do_pcibr_config_set(wptr, (win * 4), 4, ~0); /* write 1's */ + size = do_pcibr_config_get(wptr, (win * 4), 4); /* read back */ size &= mask; /* keep addr */ size &= -size; /* keep lsbit */ if (size == 0) @@ -995,45 +882,9 @@ pcibr_info->f_window[win].w_base = base; pcibr_info->f_window[win].w_size = size; -#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM) - /* - * IOC3 BASE_ADDR* BUG WORKAROUND - * - - * If we write to BASE1 on the IOC3, the - * data in BASE0 is replaced. The - * original workaround was to remember - * the value of BASE0 and restore it - * when we ran off the end of the BASE - * registers; however, a later - * workaround was added (I think it was - * rev 1.44) to avoid setting up - * anything but BASE0, with the comment - * that writing all ones to BASE1 set - * the enable-parity-error test feature - * in IOC3's SCR bit 14. - * - * So, unless we defer doing any PCI - * space allocation until drivers - * attach, and set up a way for drivers - * (the IOC3 in paricular) to tell us - * generically to keep our hands off - * BASE registers, we gotta "know" about - * the IOC3 here. - * - * Too bad the PCI folks didn't reserve the - * all-zero value for 'no BASE here' (it is a - * valid code for an uninitialized BASE in - * 32-bit PCI memory space). - */ - - if ((vendor == IOC3_VENDOR_ID_NUM) && - (device == IOC3_DEVICE_ID_NUM)) - break; -#endif if (code == PCI_BA_MEM_64BIT) { win++; /* skip upper half */ - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, 0); /* must be zero */ + do_pcibr_config_set(wptr, (win * 4), 4, 0); /* must be zero */ } } /* next win */ } /* next func */ @@ -1056,7 +907,7 @@ int defend_against_circular_linkedlist = 0; /* Check to see if there is a capabilities pointer in the cfg header */ - if (!(do_pcibr_config_get(1, cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) { + if (!(do_pcibr_config_get(cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) { return (NULL); } @@ -1067,14 +918,14 @@ * significant bits of the next pointer must be ignored, so we mask * with 0xfc). */ - cap_nxt = (do_pcibr_config_get(1, cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc); + cap_nxt = (do_pcibr_config_get(cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc); while (cap_nxt && (defend_against_circular_linkedlist <= 48)) { - cap_id = do_pcibr_config_get(1, cfgw, cap_nxt, 1); + cap_id = do_pcibr_config_get(cfgw, cap_nxt, 1); if (cap_id == capability) { return ((cfg_p)((char *)cfgw + cap_nxt)); } - cap_nxt = (do_pcibr_config_get(1, cfgw, cap_nxt+1, 1) & 0xfc); + cap_nxt = (do_pcibr_config_get(cfgw, cap_nxt+1, 1) & 0xfc); defend_against_circular_linkedlist++; } @@ -1087,7 +938,7 @@ * with a particular PCI device. */ int -pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, +pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -1223,20 +1074,21 @@ * the base registers in the card. */ int -pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; pcibr_info_h pcibr_infoh; pcibr_info_t pcibr_info; bridge_t *bridge; - size_t align_slot; iopaddr_t mask; int nbars; int nfunc; int func; int win; int rc = 0; + int align; + int align_slot; pcibr_soft = pcibr_soft_get(pcibr_vhdl); @@ -1275,7 +1127,8 @@ * the entire "lo" area is only a * megabyte, total ... */ - align_slot = (slot < 2) ? 0x200000 : 0x100000; + align_slot = 0x100000; + align = align_slot; for (func = 0; func < nfunc; ++func) { cfg_p cfgw; @@ -1300,7 +1153,7 @@ cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0); wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; - if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0) + if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0) nbars = 2; else nbars = PCI_CFG_BASE_ADDRS; @@ -1333,23 +1186,24 @@ continue; /* already allocated */ } + align = (win) ? size : align_slot; + + if (align < _PAGESZ) + align = _PAGESZ; /* ie. 0x00004000 */ + switch (space) { case PCIIO_SPACE_IO: base = pcibr_bus_addr_alloc(pcibr_soft, &pcibr_info->f_window[win], PCIIO_SPACE_IO, - 0, size, align_slot); + 0, size, align); if (!base) rc = ENOSPC; break; case PCIIO_SPACE_MEM: - if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4) & + if ((do_pcibr_config_get(wptr, (win * 4), 4) & PCI_BA_MEM_LOCATION) == PCI_BA_MEM_1MEG) { - int align = size; /* ie. 0x00001000 */ - - if (align < _PAGESZ) - align = _PAGESZ; /* ie. 0x00004000 */ /* allocate from 20-bit PCI space */ base = pcibr_bus_addr_alloc(pcibr_soft, @@ -1363,7 +1217,7 @@ base = pcibr_bus_addr_alloc(pcibr_soft, &pcibr_info->f_window[win], PCIIO_SPACE_MEM32, - 0, size, align_slot); + 0, size, align); if (!base) rc = ENOSPC; } @@ -1377,7 +1231,7 @@ PCIBR_DEVICE_TO_SLOT(pcibr_soft,slot), win, space)); } pcibr_info->f_window[win].w_base = base; - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, base); + do_pcibr_config_set(wptr, (win * 4), 4, base); #if defined(SUPPORT_PRINTING_R_FORMAT) if (pcibr_debug_mask & PCIBR_DEBUG_BAR) { @@ -1405,26 +1259,22 @@ /* * Allocate space for the EXPANSION ROM - * NOTE: DO NOT DO THIS ON AN IOC3, - * as it blows the system away. */ base = size = 0; - if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) || - (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) { - + { wptr = cfgw + PCI_EXPANSION_ROM / 4; - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, 0xFFFFF000); - mask = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4); + do_pcibr_config_set(wptr, 0, 4, 0xFFFFF000); + mask = do_pcibr_config_get(wptr, 0, 4); if (mask & 0xFFFFF000) { size = mask & -mask; base = pcibr_bus_addr_alloc(pcibr_soft, &pcibr_info->f_rwindow, PCIIO_SPACE_MEM32, - 0, size, align_slot); + 0, size, align); if (!base) rc = ENOSPC; else { - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, base); + do_pcibr_config_set(wptr, 0, 4, base); PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl, "pcibr_slot_addr_space_init: slot=%d, func=%d, " "ROM in [0x%X..0x%X], allocated by pcibr\n", @@ -1435,7 +1285,7 @@ } pcibr_info->f_rbase = base; pcibr_info->f_rsize = size; - + /* * if necessary, update the board's * command register to enable decoding @@ -1449,7 +1299,7 @@ /* * The Adaptec 1160 FC Controller WAR #767995: * The part incorrectly ignores the upper 32 bits of a 64 bit - * address when decoding references to it's registers so to + * address when decoding references to its registers so to * keep it from responding to a bus cycle that it shouldn't * we only use I/O space to get at it's registers. Don't * enable memory space accesses on that PCI device. @@ -1463,7 +1313,7 @@ pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER; - pci_cfg_cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4); + pci_cfg_cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4); #if PCI_FBBE /* XXX- check here to see if dev can do fast-back-to-back */ if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP)) @@ -1471,7 +1321,7 @@ #endif pci_cfg_cmd_reg &= 0xFFFF; if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg) - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, + do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, pci_cfg_cmd_reg | pci_cfg_cmd_reg_add); } /* next func */ return(rc); @@ -1483,7 +1333,7 @@ */ int -pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -1525,8 +1375,6 @@ PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DEVREG, pcibr_vhdl, "pcibr_slot_device_init: Device(%d): %R\n", slot, devreg, device_bits)); -#else - printk("pcibr_slot_device_init: Device(%d) 0x%x\n", slot, devreg); #endif return(0); } @@ -1536,7 +1384,7 @@ * Setup the host/guest relations for a PCI slot. */ int -pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -1605,18 +1453,17 @@ * card in this slot. */ int -pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, +pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags) { pcibr_soft_t pcibr_soft; pcibr_info_h pcibr_infoh; pcibr_info_t pcibr_info; - async_attach_t aa = NULL; int func; - devfs_handle_t xconn_vhdl, conn_vhdl; + vertex_hdl_t xconn_vhdl, conn_vhdl; #ifdef PIC_LATER - devfs_handle_t scsi_vhdl; + vertex_hdl_t scsi_vhdl; #endif int nfunc; int error_func; @@ -1639,7 +1486,6 @@ } xconn_vhdl = pcibr_soft->bs_conn; - aa = async_attach_get_info(xconn_vhdl); nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; @@ -1656,13 +1502,6 @@ conn_vhdl = pcibr_info->f_vertex; -#ifdef LATER - /* - * Activate if and when we support cdl. - */ - if (aa) - async_attach_add_info(conn_vhdl, aa); -#endif /* LATER */ error_func = pciio_device_attach(conn_vhdl, drv_flags); @@ -1728,7 +1567,7 @@ * card in this slot. */ int -pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, +pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags) { @@ -1736,7 +1575,7 @@ pcibr_info_h pcibr_infoh; pcibr_info_t pcibr_info; int func; - devfs_handle_t conn_vhdl = GRAPH_VERTEX_NONE; + vertex_hdl_t conn_vhdl = GRAPH_VERTEX_NONE; int nfunc; int error_func; int error_slot = 0; @@ -1811,7 +1650,7 @@ * PCI card on the bus. */ int -pcibr_slot_attach(devfs_handle_t pcibr_vhdl, +pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, @@ -1850,7 +1689,7 @@ * slot-specific freeing that needs to be done. */ int -pcibr_slot_detach(devfs_handle_t pcibr_vhdl, +pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, @@ -1859,10 +1698,6 @@ pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); int error; - /* Make sure that we do not detach a system critical function vertex */ - if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot)) - return(PCI_IS_SYS_CRITICAL); - /* Call the device detach function */ error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags)); if (error) { @@ -1892,61 +1727,6 @@ } /* - * pcibr_is_slot_sys_critical - * Check slot for any functions that are system critical. - * Return 1 if any are system critical or 0 otherwise. - * - * This function will always return 0 when called by - * pcibr_attach() because the system critical vertices - * have not yet been set in the hwgraph. - */ -int -pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - devfs_handle_t conn_vhdl = GRAPH_VERTEX_NONE; - int nfunc; - int func; - boolean_t is_sys_critical_vertex(devfs_handle_t); - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - if (!pcibr_soft) - return(EINVAL); - - if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) - return(EINVAL); - - nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - - for (func = 0; func < nfunc; ++func) { - - pcibr_info = pcibr_infoh[func]; - if (!pcibr_info) - continue; - - if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) - continue; - - conn_vhdl = pcibr_info->f_vertex; - if (is_sys_critical_vertex(conn_vhdl)) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "%v is a system critical device vertex\n", conn_vhdl); -#else - printk(KERN_WARNING "%p is a system critical device vertex\n", (void *)conn_vhdl); -#endif - return(1); - } - - } - - return(0); -} - -/* * pcibr_probe_slot_pic: read a config space word * while trapping any errors; return zero if * all went OK, or nonzero if there was an error. @@ -1984,57 +1764,6 @@ } /* - * pcibr_probe_slot_non_pic: read a config space word - * while trapping any errors; return zero if - * all went OK, or nonzero if there was an error. - * The value read, if any, is passed back - * through the valp parameter. - */ -static int -pcibr_probe_slot_non_pic(bridge_t *bridge, - cfg_p cfg, - unsigned *valp) -{ - int rv; - bridgereg_t b_old_enable = (bridgereg_t)0, b_new_enable = (bridgereg_t)0; - extern int badaddr_val(volatile void *, int, volatile void *); - - b_old_enable = bridge->b_int_enable; - b_new_enable = b_old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - bridge->b_int_enable = b_new_enable; - - /* - * The xbridge doesn't clear b_err_int_view unless - * multi-err is cleared... - */ - if (is_xbridge(bridge)) { - if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) - bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; - } - - if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) { - bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR; - (void) bridge->b_wid_tflush; /* flushbus */ - } - rv = badaddr_val((void *) (((uint64_t)cfg) ^ 4), 4, valp); - /* - * The xbridge doesn't set master timeout in b_int_status - * here. Fortunately it's in error_interrupt_view. - */ - if (is_xbridge(bridge)) { - if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) { - bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; - rv = 1; /* unoccupied slot */ - } - } - bridge->b_int_enable = b_old_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - - return(rv); -} - - -/* * pcibr_probe_slot: read a config space word * while trapping any errors; return zero if * all went OK, or nonzero if there was an error. @@ -2046,15 +1775,12 @@ cfg_p cfg, unsigned *valp) { - if ( is_pic(bridge) ) - return(pcibr_probe_slot_pic(bridge, cfg, valp)); - else - return(pcibr_probe_slot_non_pic(bridge, cfg, valp)); + return(pcibr_probe_slot_pic(bridge, cfg, valp)); } void -pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) +pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); pcibr_info_t pcibr_info; @@ -2079,9 +1805,9 @@ /* Disable memory and I/O BARs */ cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0); - cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4); + cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4); cmd_reg &= (PCI_CMD_MEM_SPACE | PCI_CMD_IO_SPACE); - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, cmd_reg); + do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, cmd_reg); for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) { if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE) @@ -2142,30 +1868,36 @@ pciio_space_t space, int start, int size, int align) { pciio_win_map_t win_map_p; + struct resource *root_resource = NULL; + iopaddr_t iopaddr = 0; switch (space) { case PCIIO_SPACE_IO: win_map_p = &pcibr_soft->bs_io_win_map; + root_resource = &pcibr_soft->bs_io_win_root_resource; break; case PCIIO_SPACE_MEM: win_map_p = &pcibr_soft->bs_swin_map; + root_resource = &pcibr_soft->bs_swin_root_resource; break; case PCIIO_SPACE_MEM32: win_map_p = &pcibr_soft->bs_mem_win_map; + root_resource = &pcibr_soft->bs_mem_win_root_resource; break; default: return 0; } - return pciio_device_win_alloc(win_map_p, + iopaddr = pciio_device_win_alloc(root_resource, win_info_p ? &win_info_p->w_win_alloc : NULL, start, size, align); + return(iopaddr); } @@ -2181,7 +1913,7 @@ * io_brick_tab[] array defined in ml/SN/iograph.c */ int -pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl) +pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); xwidgetnum_t widget = pcibr_soft->bs_xid; diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pciio.c linux-2.4.22/arch/ia64/sn/io/sn2/pciio.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pciio.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pciio.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,11 +4,9 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ -#define USRPCI 0 - #include #include #include @@ -30,27 +28,14 @@ #include #include #include -#include #include -#ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - #define DEBUG_PCIIO #undef DEBUG_PCIIO /* turn this on for yet more console output */ -#define GET_NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DO_DEL(ptr) (kfree(ptr)) - char pciio_info_fingerprint[] = "pciio_info"; -cdl_p pciio_registry = NULL; - int badaddr_val(volatile void *addr, int len, volatile void *ptr) { @@ -97,8 +82,6 @@ extern char master_baseio_wid; if (master_baseio_nasid < 0) { - nasid_t tmp; - master_baseio_nasid = ia64_sn_get_master_baseio_nasid(); if ( master_baseio_nasid >= 0 ) { @@ -109,13 +92,13 @@ } int -hub_dma_enabled(devfs_handle_t xconn_vhdl) +hub_dma_enabled(vertex_hdl_t xconn_vhdl) { return(0); } int -hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) +hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code) { return(0); } @@ -153,66 +136,64 @@ */ #if !defined(DEV_FUNC) -static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev); +static pciio_provider_t *pciio_to_provider_fns(vertex_hdl_t dev); #endif -pciio_piomap_t pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); +pciio_piomap_t pciio_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); void pciio_piomap_free(pciio_piomap_t); caddr_t pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t); void pciio_piomap_done(pciio_piomap_t); -caddr_t pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); -caddr_t pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned); +caddr_t pciio_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); +caddr_t pciio_pio_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned); -iopaddr_t pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); -void pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); +iopaddr_t pciio_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t); +void pciio_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t); -pciio_dmamap_t pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +pciio_dmamap_t pciio_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned); void pciio_dmamap_free(pciio_dmamap_t); iopaddr_t pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t); -alenlist_t pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned); void pciio_dmamap_done(pciio_dmamap_t); -iopaddr_t pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +iopaddr_t pciio_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned); void pciio_dmamap_drain(pciio_dmamap_t); -void pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); -void pciio_dmalist_drain(devfs_handle_t, alenlist_t); -iopaddr_t pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned); +void pciio_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t); +void pciio_dmalist_drain(vertex_hdl_t, alenlist_t); +iopaddr_t pciio_dma_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned); -pciio_intr_t pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +pciio_intr_t pciio_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t); void pciio_intr_free(pciio_intr_t); int pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t); void pciio_intr_disconnect(pciio_intr_t); -devfs_handle_t pciio_intr_cpu_get(pciio_intr_t); +vertex_hdl_t pciio_intr_cpu_get(pciio_intr_t); void pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t); -void pciio_provider_startup(devfs_handle_t); -void pciio_provider_shutdown(devfs_handle_t); +void pciio_provider_startup(vertex_hdl_t); +void pciio_provider_shutdown(vertex_hdl_t); -pciio_endian_t pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); -pciio_priority_t pciio_priority_set(devfs_handle_t, pciio_priority_t); -devfs_handle_t pciio_intr_dev_get(pciio_intr_t); +pciio_endian_t pciio_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t); +pciio_priority_t pciio_priority_set(vertex_hdl_t, pciio_priority_t); +vertex_hdl_t pciio_intr_dev_get(pciio_intr_t); -devfs_handle_t pciio_pio_dev_get(pciio_piomap_t); +vertex_hdl_t pciio_pio_dev_get(pciio_piomap_t); pciio_slot_t pciio_pio_slot_get(pciio_piomap_t); pciio_space_t pciio_pio_space_get(pciio_piomap_t); iopaddr_t pciio_pio_pciaddr_get(pciio_piomap_t); ulong pciio_pio_mapsz_get(pciio_piomap_t); caddr_t pciio_pio_kvaddr_get(pciio_piomap_t); -devfs_handle_t pciio_dma_dev_get(pciio_dmamap_t); +vertex_hdl_t pciio_dma_dev_get(pciio_dmamap_t); pciio_slot_t pciio_dma_slot_get(pciio_dmamap_t); -pciio_info_t pciio_info_chk(devfs_handle_t); -pciio_info_t pciio_info_get(devfs_handle_t); -void pciio_info_set(devfs_handle_t, pciio_info_t); -devfs_handle_t pciio_info_dev_get(pciio_info_t); +pciio_info_t pciio_info_chk(vertex_hdl_t); +pciio_info_t pciio_info_get(vertex_hdl_t); +void pciio_info_set(vertex_hdl_t, pciio_info_t); +vertex_hdl_t pciio_info_dev_get(pciio_info_t); pciio_slot_t pciio_info_slot_get(pciio_info_t); pciio_function_t pciio_info_function_get(pciio_info_t); pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t); pciio_device_id_t pciio_info_device_id_get(pciio_info_t); -devfs_handle_t pciio_info_master_get(pciio_info_t); +vertex_hdl_t pciio_info_master_get(pciio_info_t); arbitrary_info_t pciio_info_mfast_get(pciio_info_t); pciio_provider_t *pciio_info_pops_get(pciio_info_t); error_handler_f *pciio_info_efunc_get(pciio_info_t); @@ -223,30 +204,28 @@ iopaddr_t pciio_info_rom_base_get(pciio_info_t); size_t pciio_info_rom_size_get(pciio_info_t); -void pciio_init(void); -int pciio_attach(devfs_handle_t); +int pciio_attach(vertex_hdl_t); -void pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns); -void pciio_provider_unregister(devfs_handle_t); -pciio_provider_t *pciio_provider_fns_get(devfs_handle_t); +void pciio_provider_register(vertex_hdl_t, pciio_provider_t *pciio_fns); +void pciio_provider_unregister(vertex_hdl_t); +pciio_provider_t *pciio_provider_fns_get(vertex_hdl_t); int pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned); -void pciio_driver_unregister(char *driver_prefix); -devfs_handle_t pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); +vertex_hdl_t pciio_device_register(vertex_hdl_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); -void pciio_device_unregister(devfs_handle_t); -pciio_info_t pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); +void pciio_device_unregister(vertex_hdl_t); +pciio_info_t pciio_device_info_new(pciio_info_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); void pciio_device_info_free(pciio_info_t); -devfs_handle_t pciio_device_info_register(devfs_handle_t, pciio_info_t); -void pciio_device_info_unregister(devfs_handle_t, pciio_info_t); -int pciio_device_attach(devfs_handle_t, int); -int pciio_device_detach(devfs_handle_t, int); -void pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t); - -int pciio_reset(devfs_handle_t); -int pciio_write_gather_flush(devfs_handle_t); -int pciio_slot_inuse(devfs_handle_t); +vertex_hdl_t pciio_device_info_register(vertex_hdl_t, pciio_info_t); +void pciio_device_info_unregister(vertex_hdl_t, pciio_info_t); +int pciio_device_attach(vertex_hdl_t, int); +int pciio_device_detach(vertex_hdl_t, int); +void pciio_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t); + +int pciio_reset(vertex_hdl_t); +int pciio_write_gather_flush(vertex_hdl_t); +int pciio_slot_inuse(vertex_hdl_t); /* ===================================================================== * Provider Function Location @@ -261,7 +240,7 @@ #if !defined(DEV_FUNC) static pciio_provider_t * -pciio_to_provider_fns(devfs_handle_t dev) +pciio_to_provider_fns(vertex_hdl_t dev) { pciio_info_t card_info; pciio_provider_t *provider_fns; @@ -316,7 +295,7 @@ */ pciio_piomap_t -pciio_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ +pciio_piomap_alloc(vertex_hdl_t dev, /* set up mapping for this device */ device_desc_t dev_desc, /* device descriptor */ pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ iopaddr_t addr, /* lowest address (or offset in window) */ @@ -354,7 +333,7 @@ } caddr_t -pciio_piotrans_addr(devfs_handle_t dev, /* translate for this device */ +pciio_piotrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ iopaddr_t addr, /* starting address (or offset in window) */ @@ -366,7 +345,7 @@ } caddr_t -pciio_pio_addr(devfs_handle_t dev, /* translate for this device */ +pciio_pio_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ iopaddr_t addr, /* starting address (or offset in window) */ @@ -410,7 +389,7 @@ } iopaddr_t -pciio_piospace_alloc(devfs_handle_t dev, /* Device requiring space */ +pciio_piospace_alloc(vertex_hdl_t dev, /* Device requiring space */ device_desc_t dev_desc, /* Device descriptor */ pciio_space_t space, /* MEM32/MEM64/IO */ size_t byte_count, /* Size of mapping */ @@ -423,7 +402,7 @@ } void -pciio_piospace_free(devfs_handle_t dev, /* Device freeing space */ +pciio_piospace_free(vertex_hdl_t dev, /* Device freeing space */ pciio_space_t space, /* Type of space */ iopaddr_t pciaddr, /* starting address */ size_t byte_count) @@ -440,7 +419,7 @@ */ pciio_dmamap_t -pciio_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ +pciio_dmamap_alloc(vertex_hdl_t dev, /* set up mappings for this device */ device_desc_t dev_desc, /* device descriptor */ size_t byte_count_max, /* max size of a mapping */ unsigned flags) @@ -465,15 +444,6 @@ (CAST_DMAMAP(pciio_dmamap), paddr, byte_count); } -alenlist_t -pciio_dmamap_list(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - alenlist_t alenlist, /* map this Address/Length List */ - unsigned flags) -{ - return DMAMAP_FUNC(pciio_dmamap, dmamap_list) - (CAST_DMAMAP(pciio_dmamap), alenlist, flags); -} - void pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) { @@ -482,7 +452,7 @@ } iopaddr_t -pciio_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ +pciio_dmatrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ paddr_t paddr, /* system physical address */ size_t byte_count, /* length */ @@ -492,18 +462,8 @@ (dev, dev_desc, paddr, byte_count, flags); } -alenlist_t -pciio_dmatrans_list(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - alenlist_t palenlist, /* system address/length list */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_list) - (dev, dev_desc, palenlist, flags); -} - iopaddr_t -pciio_dma_addr(devfs_handle_t dev, /* translate for this device */ +pciio_dma_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ paddr_t paddr, /* system physical address */ size_t byte_count, /* length */ @@ -553,14 +513,14 @@ } void -pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) +pciio_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size) { DEV_FUNC(dev, dmaaddr_drain) (dev, addr, size); } void -pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list) +pciio_dmalist_drain(vertex_hdl_t dev, alenlist_t list) { DEV_FUNC(dev, dmalist_drain) (dev, list); @@ -577,10 +537,10 @@ * Return resource handle in intr_hdl. */ pciio_intr_t -pciio_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ +pciio_intr_alloc(vertex_hdl_t dev, /* which Crosstalk device */ device_desc_t dev_desc, /* device descriptor */ pciio_intr_line_t lines, /* INTR line(s) to attach */ - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { /* owner of this interrupt */ return (pciio_intr_t) DEV_FUNC(dev, intr_alloc) (dev, dev_desc, lines, owner_dev); @@ -624,7 +584,7 @@ * Return a hwgraph vertex that represents the CPU currently * targeted by an interrupt. */ -devfs_handle_t +vertex_hdl_t pciio_intr_cpu_get(pciio_intr_t intr_hdl) { return INTR_FUNC(intr_hdl, intr_cpu_get) @@ -663,12 +623,12 @@ */ static pciio_info_t pciio_cardinfo_get( - devfs_handle_t pciio_vhdl, + vertex_hdl_t pciio_vhdl, pciio_slot_t pci_slot) { char namebuf[16]; pciio_info_t info = 0; - devfs_handle_t conn; + vertex_hdl_t conn; pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE); if (GRAPH_SUCCESS == @@ -699,22 +659,16 @@ /*ARGSUSED */ int pciio_error_handler( - devfs_handle_t pciio_vhdl, + vertex_hdl_t pciio_vhdl, int error_code, ioerror_mode_t mode, ioerror_t *ioerror) { pciio_info_t pciio_info; - devfs_handle_t pconn_vhdl; -#if USRPCI - devfs_handle_t usrpci_v; -#endif + vertex_hdl_t pconn_vhdl; pciio_slot_t slot; int retval; -#ifdef EHE_ENABLE - error_state_t e_state; -#endif /* EHE_ENABLE */ #if DEBUG && ERROR_DEBUG printk("%v: pciio_error_handler\n", pciio_vhdl); @@ -733,16 +687,6 @@ if (pciio_info && pciio_info->c_efunc) { pconn_vhdl = pciio_info_dev_get(pciio_info); -#ifdef EHE_ENABLE - e_state = error_state_get(pciio_vhdl); - - if (e_state == ERROR_STATE_ACTION) - (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); - - if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE) - return(IOERROR_UNHANDLED); -#endif - retval = pciio_info->c_efunc (pciio_info->c_einfo, error_code, mode, ioerror); if (retval != IOERROR_UNHANDLED) @@ -770,49 +714,11 @@ pconn_vhdl = pciio_info_dev_get(pciio_info); -#ifdef EHE_ENABLE - e_state = error_state_get(pciio_vhdl); - - if (e_state == ERROR_STATE_ACTION) - (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); - - if (error_state_set(pconn_vhdl,e_state) == - ERROR_RETURN_CODE_CANNOT_SET_STATE) - return(IOERROR_UNHANDLED); -#endif /* EHE_ENABLE */ - retval = pciio_info->c_efunc (pciio_info->c_einfo, error_code, mode, ioerror); if (retval != IOERROR_UNHANDLED) return retval; } - -#if USRPCI - /* If the USRPCI driver is available and - * knows about this connection point, - * deliver the error to it. - * - * OK to use pconn_vhdl here, even though we - * have already UNREF'd it, since we know that - * it is not going away. - */ - pconn_vhdl = pciio_info_dev_get(pciio_info); - if (GRAPH_SUCCESS == hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) { - iopaddr_t busaddr; - IOERROR_GETVALUE(busaddr, ioerror, busaddr); - retval = usrpci_error_handler (usrpci_v, error_code, busaddr); - hwgraph_vertex_unref(usrpci_v); - if (retval != IOERROR_UNHANDLED) { - /* - * This unref is not needed. If this code is called often enough, - * the system will crash, due to vertex reference count reaching 0, - * causing vertex to be unallocated. -jeremy - * hwgraph_vertex_unref(pconn_vhdl); - */ - return retval; - } - } -#endif } } @@ -829,7 +735,7 @@ * Startup a crosstalk provider */ void -pciio_provider_startup(devfs_handle_t pciio_provider) +pciio_provider_startup(vertex_hdl_t pciio_provider) { DEV_FUNC(pciio_provider, provider_startup) (pciio_provider); @@ -839,7 +745,7 @@ * Shutdown a crosstalk provider */ void -pciio_provider_shutdown(devfs_handle_t pciio_provider) +pciio_provider_shutdown(vertex_hdl_t pciio_provider) { DEV_FUNC(pciio_provider, provider_shutdown) (pciio_provider); @@ -851,7 +757,7 @@ * how things will actually appear in memory. */ pciio_endian_t -pciio_endian_set(devfs_handle_t dev, +pciio_endian_set(vertex_hdl_t dev, pciio_endian_t device_end, pciio_endian_t desired_end) { @@ -880,7 +786,7 @@ * Specify PCI arbitration priority. */ pciio_priority_t -pciio_priority_set(devfs_handle_t dev, +pciio_priority_set(vertex_hdl_t dev, pciio_priority_t device_prio) { ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW)); @@ -893,7 +799,7 @@ * Read value of configuration register */ uint64_t -pciio_config_get(devfs_handle_t dev, +pciio_config_get(vertex_hdl_t dev, unsigned reg, unsigned size) { @@ -923,7 +829,7 @@ * Change value of configuration register */ void -pciio_config_set(devfs_handle_t dev, +pciio_config_set(vertex_hdl_t dev, unsigned reg, unsigned size, uint64_t value) @@ -953,7 +859,7 @@ * Issue a hardware reset to a card. */ int -pciio_reset(devfs_handle_t dev) +pciio_reset(vertex_hdl_t dev) { return DEV_FUNC(dev, reset) (dev); } @@ -962,19 +868,19 @@ * flush write gather buffers */ int -pciio_write_gather_flush(devfs_handle_t dev) +pciio_write_gather_flush(vertex_hdl_t dev) { return DEV_FUNC(dev, write_gather_flush) (dev); } -devfs_handle_t +vertex_hdl_t pciio_intr_dev_get(pciio_intr_t pciio_intr) { return (pciio_intr->pi_dev); } /****** Generic crosstalk pio interfaces ******/ -devfs_handle_t +vertex_hdl_t pciio_pio_dev_get(pciio_piomap_t pciio_piomap) { return (pciio_piomap->pp_dev); @@ -1011,7 +917,7 @@ } /****** Generic crosstalk dma interfaces ******/ -devfs_handle_t +vertex_hdl_t pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap) { return (pciio_dmamap->pd_dev); @@ -1026,7 +932,7 @@ /****** Generic pci slot information interfaces ******/ pciio_info_t -pciio_info_chk(devfs_handle_t pciio) +pciio_info_chk(vertex_hdl_t pciio) { arbitrary_info_t ainfo = 0; @@ -1035,7 +941,7 @@ } pciio_info_t -pciio_info_get(devfs_handle_t pciio) +pciio_info_get(vertex_hdl_t pciio) { pciio_info_t pciio_info; @@ -1051,18 +957,17 @@ #endif /* DEBUG_PCIIO */ if ((pciio_info != NULL) && - (pciio_info->c_fingerprint != pciio_info_fingerprint) - && (pciio_info->c_fingerprint != NULL)) { + (pciio_info->c_fingerprint != pciio_info_fingerprint) + && (pciio_info->c_fingerprint != NULL)) { - return((pciio_info_t)-1); /* Should panic .. */ + return((pciio_info_t)-1); /* Should panic .. */ } - return pciio_info; } void -pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info) +pciio_info_set(vertex_hdl_t pciio, pciio_info_t pciio_info) { if (pciio_info != NULL) pciio_info->c_fingerprint = pciio_info_fingerprint; @@ -1076,7 +981,7 @@ (arbitrary_info_t) pciio_info); } -devfs_handle_t +vertex_hdl_t pciio_info_dev_get(pciio_info_t pciio_info) { return (pciio_info->c_vertex); @@ -1106,7 +1011,7 @@ return (pciio_info->c_device); } -devfs_handle_t +vertex_hdl_t pciio_info_master_get(pciio_info_t pciio_info) { return (pciio_info->c_master); @@ -1172,47 +1077,12 @@ */ /* - * pciioinit: called once during device driver - * initializtion if this driver is configured into - * the system. - */ -void -pciio_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("pciio_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (pciio_registry == NULL) { - cp = cdl_new(EDGE_LBL_PCI, "vendor", "device"); - if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(pciio_registry != NULL); -} - -/* * pciioattach: called for each vertex in the graph * that is a PCI provider. */ /*ARGSUSED */ int -pciio_attach(devfs_handle_t pciio) +pciio_attach(vertex_hdl_t pciio) { #if DEBUG && ATTACH_DEBUG #if defined(SUPPORT_PRINTING_V_FORMAT) @@ -1228,7 +1098,7 @@ * Associate a set of pciio_provider functions with a vertex. */ void -pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns) +pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns) { hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns); } @@ -1237,7 +1107,7 @@ * Disassociate a set of pciio_provider functions with a vertex. */ void -pciio_provider_unregister(devfs_handle_t provider) +pciio_provider_unregister(vertex_hdl_t provider) { arbitrary_info_t ainfo; @@ -1249,7 +1119,7 @@ * provider. */ pciio_provider_t * -pciio_provider_fns_get(devfs_handle_t provider) +pciio_provider_fns_get(vertex_hdl_t provider) { arbitrary_info_t ainfo = 0; @@ -1265,86 +1135,13 @@ char *driver_prefix, unsigned flags) { - /* a driver's init routine might call - * pciio_driver_register before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - return cdl_add_driver(pciio_registry, - vendor_id, device_id, - driver_prefix, flags, NULL); -} - -/* - * Remove an initialization function. - */ -void -pciio_driver_unregister( - char *driver_prefix) -{ - /* before a driver calls unregister, - * it must have called register; so - * we can assume we have a registry here. - */ - ASSERT(pciio_registry != NULL); - - cdl_del_driver(pciio_registry, driver_prefix, NULL); -} - -/* - * Set the slot status for a device supported by the - * driver being registered. - */ -void -pciio_driver_reg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Set the slot status for a device supported by the - * driver being unregistered. - */ -void -pciio_driver_unreg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Call some function with each vertex that - * might be one of this driver's attach points. - */ -void -pciio_iterate(char *driver_prefix, - pciio_iter_f * func) -{ - /* a driver's init routine might call - * pciio_iterate before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - ASSERT(pciio_registry != NULL); - - cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func); + return(0); } -devfs_handle_t +vertex_hdl_t pciio_device_register( - devfs_handle_t connectpt, /* vertex for /hw/.../pciio/%d */ - devfs_handle_t master, /* card's master ASIC (PCI provider) */ + vertex_hdl_t connectpt, /* vertex for /hw/.../pciio/%d */ + vertex_hdl_t master, /* card's master ASIC (PCI provider) */ pciio_slot_t slot, /* card's slot */ pciio_function_t func, /* card's func */ pciio_vendor_id_t vendor_id, @@ -1356,7 +1153,7 @@ } void -pciio_device_unregister(devfs_handle_t pconn) +pciio_device_unregister(vertex_hdl_t pconn) { DEV_FUNC(pconn,device_unregister)(pconn); } @@ -1364,14 +1161,14 @@ pciio_info_t pciio_device_info_new( pciio_info_t pciio_info, - devfs_handle_t master, + vertex_hdl_t master, pciio_slot_t slot, pciio_function_t func, pciio_vendor_id_t vendor_id, pciio_device_id_t device_id) { if (!pciio_info) - GET_NEW(pciio_info); + NEW(pciio_info); ASSERT(pciio_info != NULL); pciio_info->c_slot = slot; @@ -1396,14 +1193,14 @@ BZERO((char *)pciio_info,sizeof(pciio_info)); } -devfs_handle_t +vertex_hdl_t pciio_device_info_register( - devfs_handle_t connectpt, /* vertex at center of bus */ + vertex_hdl_t connectpt, /* vertex at center of bus */ pciio_info_t pciio_info) /* details about the connectpt */ { char name[32]; - devfs_handle_t pconn; - int device_master_set(devfs_handle_t, devfs_handle_t); + vertex_hdl_t pconn; + int device_master_set(vertex_hdl_t, vertex_hdl_t); pciio_slot_func_to_name(name, pciio_info->c_slot, @@ -1429,25 +1226,15 @@ */ device_master_set(pconn, pciio_info->c_master); - -#if USRPCI - /* - * Call into usrpci provider to let it initialize for - * the given slot. - */ - if (pciio_info->c_slot != PCIIO_SLOT_NONE) - usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot); -#endif - return pconn; } void -pciio_device_info_unregister(devfs_handle_t connectpt, +pciio_device_info_unregister(vertex_hdl_t connectpt, pciio_info_t pciio_info) { char name[32]; - devfs_handle_t pconn; + vertex_hdl_t pconn; if (!pciio_info) return; @@ -1470,7 +1257,7 @@ /* Add the pci card inventory information to the hwgraph */ static void -pciio_device_inventory_add(devfs_handle_t pconn_vhdl) +pciio_device_inventory_add(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -1488,7 +1275,7 @@ /*ARGSUSED */ int -pciio_device_attach(devfs_handle_t pconn, +pciio_device_attach(vertex_hdl_t pconn, int drv_flags) { pciio_info_t pciio_info; @@ -1507,92 +1294,18 @@ * pciio_init) have been called; so we * can assume here that we have a registry. */ - ASSERT(pciio_registry != NULL); - return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags)); + return(cdl_add_connpt(vendor_id, device_id, pconn, drv_flags)); } int -pciio_device_detach(devfs_handle_t pconn, +pciio_device_detach(vertex_hdl_t pconn, int drv_flags) { - pciio_info_t pciio_info; - pciio_vendor_id_t vendor_id; - pciio_device_id_t device_id; - - pciio_info = pciio_info_get(pconn); - - vendor_id = pciio_info->c_vendor; - device_id = pciio_info->c_device; - - /* we don't start attaching things until - * all the driver init routines (including - * pciio_init) have been called; so we - * can assume here that we have a registry. - */ - ASSERT(pciio_registry != NULL); - - return(cdl_del_connpt(pciio_registry, vendor_id, device_id, - pconn, drv_flags)); - -} - -/* SN2 */ -/* - * Allocate (if necessary) and initialize a PCI window mapping structure. - */ -pciio_win_map_t -pciio_device_win_map_new(pciio_win_map_t win_map, - size_t region_size, - size_t page_size) -{ - ASSERT((page_size & (page_size - 1)) == 0); - ASSERT((region_size & (page_size - 1)) == 0); - - if (win_map == NULL) - NEW(win_map); - - /* - * The map array tracks the free ``pages'' in the region. The worst - * case scenario is when every other page in the region is free -- - * e.i. maximum fragmentation. This leads to (max pages + 1) / 2 + 1 - * map entries. The first "+1" handles the divide by 2 rounding; the - * second handles the need for an end marker sentinel. - */ - win_map->wm_map = rmallocmap((region_size / page_size + 1) / 2 + 1); - win_map->wm_page_size = page_size; - ASSERT(win_map->wm_map != NULL); - - return win_map; -} - -/* - * Free resources associated with a PCI window mapping structure. - */ -extern void -pciio_device_win_map_free(pciio_win_map_t win_map) -{ - rmfreemap(win_map->wm_map); - bzero(win_map, sizeof *win_map); + return(0); } /* - * Populate window map with specified free range. - */ -void -pciio_device_win_populate(pciio_win_map_t win_map, - iopaddr_t ioaddr, - size_t size) -{ - ASSERT((size & (win_map->wm_page_size - 1)) == 0); - ASSERT((ioaddr & (win_map->wm_page_size - 1)) == 0); - - rmfree(win_map->wm_map, - size / win_map->wm_page_size, - (unsigned long)ioaddr / win_map->wm_page_size); - -} -/* * Allocate space from the specified PCI window mapping resource. On * success record information about the allocation in the supplied window * allocation cookie (if non-NULL) and return the address of the allocated @@ -1609,94 +1322,36 @@ * and alignment. */ iopaddr_t -pciio_device_win_alloc(pciio_win_map_t win_map, +pciio_device_win_alloc(struct resource *root_resource, pciio_win_alloc_t win_alloc, size_t start, size_t size, size_t align) { - unsigned long base; -#ifdef PIC_LATER - ASSERT((size & (size - 1)) == 0); - ASSERT((align & (align - 1)) == 0); + struct resource *new_res; + int status = 0; - /* - * Convert size and alignment to pages. If size is greated than the - * requested alignment, we bump the alignment up to size; otherwise - * convert the size into a multiple of the alignment request. - */ - size = (size + win_map->wm_page_size - 1) / win_map->wm_page_size; - align = align / win_map->wm_page_size; - if (size > align) - align = size; - else - size = (size + align - 1) & ~(align - 1); - - /* XXXX */ - base = rmalloc_align(win_map->wm_map, size, align, VM_NOSLEEP); - if (base == RMALLOC_FAIL) - return((iopaddr_t)NULL); -#else - int index_page, index_page_align; - int align_pages, size_pages; - int alloc_pages, free_pages; - int addr_align; - - /* Convert PCI bus alignment from bytes to pages */ - align_pages = align / win_map->wm_page_size; - - /* Convert PCI request from bytes to pages */ - size_pages = (size / win_map->wm_page_size) + - ((size % win_map->wm_page_size) ? 1 : 0); - - /* Align address with the larger of the size or the requested slot align */ - if (size_pages > align_pages) - align_pages = size_pages; - - /* - * Avoid wasting space by aligning - 1; this will prevent crossing - * another alignment boundary. - */ - alloc_pages = size_pages + (align_pages - 1); + new_res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP); - /* Allocate PCI bus space in pages */ - index_page = (int) rmalloc(win_map->wm_map, - (size_t) alloc_pages); - - /* Error if no PCI bus address space available */ - if (!index_page) - return 0; - - /* PCI bus address index starts at 0 */ - index_page--; - - /* Align the page offset as requested */ - index_page_align = (index_page + (align_pages - 1)) - - ((index_page + (align_pages - 1)) % align_pages); - - free_pages = (align_pages - 1) - (index_page_align - index_page); - - /* Free unused PCI bus pages adjusting the index to start at 1 */ - rmfree(win_map->wm_map, - free_pages, - (index_page_align + 1) + size_pages); - - /* Return aligned PCI bus space in bytes */ - addr_align = (index_page_align * win_map->wm_page_size); - base = index_page; - size = alloc_pages - free_pages; -#endif /* PIC_LATER */ + status = allocate_resource( root_resource, new_res, + size, align /* Min start addr. */, + root_resource->end, align, + NULL, NULL); + if (status) { + kfree(new_res); + return((iopaddr_t) NULL); + } /* * If a window allocation cookie has been supplied, use it to keep * track of all the allocated space assigned to this window. */ if (win_alloc) { - win_alloc->wa_map = win_map; - win_alloc->wa_base = base; + win_alloc->wa_resource = new_res; + win_alloc->wa_base = new_res->start; win_alloc->wa_pages = size; } - return base * win_map->wm_page_size; + return new_res->start;; } /* @@ -1706,10 +1361,16 @@ void pciio_device_win_free(pciio_win_alloc_t win_alloc) { - if (win_alloc->wa_pages) - rmfree(win_alloc->wa_map->wm_map, - win_alloc->wa_pages, - win_alloc->wa_base); + + int status = 0; + + if (win_alloc->wa_resource) { + status = release_resource(win_alloc->wa_resource); + if (!status) + kfree(win_alloc->wa_resource); + else + BUG(); + } } /* @@ -1728,7 +1389,7 @@ * cooperating drivers, well, cooperate ... */ void -pciio_error_register(devfs_handle_t pconn, +pciio_error_register(vertex_hdl_t pconn, error_handler_f *efunc, error_handler_arg_t einfo) { @@ -1746,7 +1407,7 @@ * vhdl is the vertex for the slot */ int -pciio_slot_inuse(devfs_handle_t pconn_vhdl) +pciio_slot_inuse(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -1763,7 +1424,7 @@ } int -pciio_dma_enabled(devfs_handle_t pconn_vhdl) +pciio_dma_enabled(vertex_hdl_t pconn_vhdl) { return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl); } @@ -1777,7 +1438,7 @@ /* * These are complementary Linux interfaces that takes in a pci_dev * as the - * first arguement instead of devfs_handle_t. + * first arguement instead of vertex_hdl_t. */ iopaddr_t snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned); pciio_dmamap_t snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned); @@ -1800,7 +1461,7 @@ int *count_vchan0, int *count_vchan1) { - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1); } @@ -1811,7 +1472,7 @@ pciio_endian_t device_end, pciio_endian_t desired_end) { - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); return DEV_FUNC(dev, endian_set) (dev, device_end, desired_end); @@ -1825,7 +1486,7 @@ unsigned flags) { /* defined in dma.h */ - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); /* * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be @@ -1842,7 +1503,7 @@ unsigned flags) { /* defined in dma.h */ - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); /* * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/pic.c linux-2.4.22/arch/ia64/sn/io/sn2/pic.c --- linux-2.4.21/arch/ia64/sn/io/sn2/pic.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/pic.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -27,51 +27,195 @@ #include #include #include -#include #include #include +extern char *bcopy(const char * src, char * dest, int count); + #define PCI_BUS_NO_1 1 -int pic_devflag = D_MP; +extern int pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t, int, pcibr_soft_t *); +extern void pcibr_driver_reg_callback(vertex_hdl_t, int, int, int); +extern void pcibr_driver_unreg_callback(vertex_hdl_t, int, int, int); -extern int pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t, int, pcibr_soft_t *); -extern void pcibr_driver_reg_callback(devfs_handle_t, int, int, int); -extern void pcibr_driver_unreg_callback(devfs_handle_t, int, int, int); +/* + * copy inventory_t from conn_v to peer_conn_v + */ +int +pic_bus1_inventory_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v) +{ + inventory_t *pinv, *peer_pinv; + + if (hwgraph_info_get_LBL(conn_v, INFO_LBL_INVENT, + (arbitrary_info_t *)&pinv) == GRAPH_SUCCESS) + { + NEW(peer_pinv); + bcopy((const char *)pinv, (char *)peer_pinv, sizeof(inventory_t)); + if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_INVENT, + (arbitrary_info_t)peer_pinv) != GRAPH_SUCCESS) { + DEL(peer_pinv); + return 0; + } + return 1; + } + + printk("pic_bus1_inventory_dup: cannot get INFO_LBL_INVENT from 0x%lx\n ", (uint64_t)conn_v); + return 0; +} -void -pic_init(void) +/* + * copy xwidget_info_t from conn_v to peer_conn_v + */ +int +pic_bus1_widget_info_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v, + cnodeid_t xbow_peer) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pic_init()\n")); + xwidget_info_t widget_info, peer_widget_info; + char peer_path[256]; + vertex_hdl_t peer_hubv; + hubinfo_t peer_hub_info; + + /* get the peer hub's widgetid */ + peer_hubv = NODEPDA(xbow_peer)->node_vertex; + peer_hub_info = NULL; + hubinfo_get(peer_hubv, &peer_hub_info); + if (peer_hub_info == NULL) + return 0; + + if (hwgraph_info_get_LBL(conn_v, INFO_LBL_XWIDGET, + (arbitrary_info_t *)&widget_info) == GRAPH_SUCCESS) { + NEW(peer_widget_info); + peer_widget_info->w_vertex = peer_conn_v; + peer_widget_info->w_id = widget_info->w_id; + peer_widget_info->w_master = peer_hubv; + peer_widget_info->w_masterid = peer_hub_info->h_widgetid; + /* structure copy */ + peer_widget_info->w_hwid = widget_info->w_hwid; + peer_widget_info->w_efunc = 0; + peer_widget_info->w_einfo = 0; + peer_widget_info->w_name = kmalloc(strlen(peer_path) + 1, GFP_KERNEL); + strcpy(peer_widget_info->w_name, peer_path); + + if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_XWIDGET, + (arbitrary_info_t)peer_widget_info) != GRAPH_SUCCESS) { + DEL(peer_widget_info); + return 0; + } + + xwidget_info_set(peer_conn_v, peer_widget_info); - xwidget_driver_register(PIC_WIDGET_PART_NUM_BUS0, - PIC_WIDGET_MFGR_NUM, - "pic_", - 0); + return 1; + } + + printk("pic_bus1_widget_info_dup: " + "cannot get INFO_LBL_XWIDGET from 0x%lx\n", (uint64_t)conn_v); + return 0; } +/* + * If this PIC is attached to two Cbricks ("dual-ported") then + * attach each bus to opposite Cbricks. + * + * If successful, return a new vertex suitable for attaching the PIC bus. + * If not successful, return zero and both buses will attach to the + * vertex passed into pic_attach(). + */ +vertex_hdl_t +pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v) +{ + cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); + cnodeid_t xbow_peer = -1; + char pathname[256], peer_path[256], tmpbuf[256]; + char *p; + int rc; + vertex_hdl_t peer_conn_v; + int pos; + slabid_t slab; + + if (NODEPDA(cnode)->xbow_peer >= 0) { /* if dual-ported */ + /* create a path for this widget on the peer Cbrick */ + /* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */ + /* sprintf(pathname, "%v", conn_v); */ + xbow_peer = NASID_TO_COMPACT_NODEID(NODEPDA(cnode)->xbow_peer); + pos = hwgfs_generate_path(conn_v, tmpbuf, 256); + strcpy(pathname, &tmpbuf[pos]); + p = pathname + strlen("hw/module/001c01/slab/0/"); + + memset(tmpbuf, 0, 16); + format_module_id(tmpbuf, geo_module((NODEPDA(xbow_peer))->geoid), MODULE_FORMAT_BRIEF); + slab = geo_slab((NODEPDA(xbow_peer))->geoid); + sprintf(peer_path, "module/%s/slab/%d/%s", tmpbuf, (int)slab, p); + + /* Look for vertex for this widget on the peer Cbrick. + * Expect GRAPH_NOT_FOUND. + */ + rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v); + if (GRAPH_SUCCESS == rc) + printk("pic_attach: found unexpected vertex: 0x%lx\n", + (uint64_t)peer_conn_v); + else if (GRAPH_NOT_FOUND != rc) { + printk("pic_attach: hwgraph_traverse unexpectedly" + " returned 0x%x\n", rc); + } else { + /* try to add the widget vertex to the peer Cbrick */ + rc = hwgraph_path_add(hwgraph_root, peer_path, &peer_conn_v); + + if (GRAPH_SUCCESS != rc) + printk("pic_attach: hwgraph_path_add" + " failed with 0x%x\n", rc); + else { + PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, + "pic_bus1_redist: added vertex %v\n", peer_conn_v)); + + /* Now hang appropiate stuff off of the new + * vertex. We bail out if we cannot add something. + * In that case, we don't remove the newly added + * vertex but that should be safe and we don't + * really expect the additions to fail anyway. + */ +#if 0 + if (!pic_bus1_inventory_dup(conn_v, peer_conn_v)) + return 0; + pic_bus1_device_desc_dup(conn_v, peer_conn_v); +#endif + if (!pic_bus1_widget_info_dup(conn_v, peer_conn_v, xbow_peer)) + return 0; + + return peer_conn_v; + } + } + } + return 0; +} + + int -pic_attach(devfs_handle_t conn_v) +pic_attach(vertex_hdl_t conn_v) { int rc; bridge_t *bridge0, *bridge1 = (bridge_t *)0; - devfs_handle_t pcibr_vhdl0, pcibr_vhdl1 = (devfs_handle_t)0; + vertex_hdl_t pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0; pcibr_soft_t bus0_soft, bus1_soft = (pcibr_soft_t)0; + vertex_hdl_t conn_v0, conn_v1, peer_conn_v; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n")); bridge0 = (bridge_t *) xtalk_piotrans_addr(conn_v, NULL, 0, sizeof(bridge_t), 0); -#ifdef PCI_BUS_NO_1 bridge1 = (bridge_t *)((char *)bridge0 + PIC_BUS1_OFFSET); -#endif PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach: bridge0=0x%x, bridge1=0x%x\n", bridge0, bridge1)); + conn_v0 = conn_v1 = conn_v; + + /* If dual-ported then split the two PIC buses across both Cbricks */ + if ((peer_conn_v = (pic_bus1_redist(NASID_GET(bridge0), conn_v)))) + conn_v1 = peer_conn_v; + /* * Create the vertex for the PCI buses, which we * will also use to hold the pcibr_soft and @@ -84,12 +228,10 @@ * the Bridge registers themselves. */ /* FIXME: what should the hwgraph path look like ? */ - rc = hwgraph_path_add(conn_v, EDGE_LBL_PCIX_0, &pcibr_vhdl0); + rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0); ASSERT(rc == GRAPH_SUCCESS); -#ifdef PCI_BUS_NO_1 - rc = hwgraph_path_add(conn_v, EDGE_LBL_PCIX_1, &pcibr_vhdl1); + rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1); ASSERT(rc == GRAPH_SUCCESS); -#endif PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach: pcibr_vhdl0=%v, pcibr_vhdl1=%v\n", @@ -97,27 +239,17 @@ /* register pci provider array */ pciio_provider_register(pcibr_vhdl0, &pci_pic_provider); -#ifdef PCI_BUS_NO_1 pciio_provider_register(pcibr_vhdl1, &pci_pic_provider); -#endif pciio_provider_startup(pcibr_vhdl0); -#ifdef PCI_BUS_NO_1 pciio_provider_startup(pcibr_vhdl1); -#endif - pcibr_attach2(conn_v, bridge0, pcibr_vhdl0, 0, &bus0_soft); -#ifdef PCI_BUS_NO_1 - pcibr_attach2(conn_v, bridge1, pcibr_vhdl1, 1, &bus1_soft); -#endif + pcibr_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft); + pcibr_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft); /* save a pointer to the PIC's other bus's soft struct */ -#ifdef PCI_BUS_NO_1 bus0_soft->bs_peers_soft = bus1_soft; bus1_soft->bs_peers_soft = bus0_soft; -#else - bus0_soft->bs_peers_soft = (pcibr_soft_t)0; -#endif PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach: bus0_soft=0x%x, bus1_soft=0x%x\n", @@ -145,10 +277,8 @@ (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc, (pciio_dmamap_free_f *) pcibr_dmamap_free, (pciio_dmamap_addr_f *) pcibr_dmamap_addr, - (pciio_dmamap_list_f *) pcibr_dmamap_list, (pciio_dmamap_done_f *) pcibr_dmamap_done, (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr, - (pciio_dmatrans_list_f *) pcibr_dmatrans_list, (pciio_dmamap_drain_f *) pcibr_dmamap_drain, (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain, (pciio_dmalist_drain_f *) pcibr_dmalist_drain, diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/sgi_io_init.c linux-2.4.22/arch/ia64/sn/io/sn2/sgi_io_init.c --- linux-2.4.21/arch/ia64/sn/io/sn2/sgi_io_init.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/sgi_io_init.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,230 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void mlreset(void); -extern int init_hcl(void); -extern void klgraph_hack_init(void); -extern void hubspc_init(void); -extern void pciio_init(void); -extern void pcibr_init(void); -extern void xtalk_init(void); -extern void xbow_init(void); -extern void xbmon_init(void); -extern void pciiox_init(void); -extern void pic_init(void); -extern void usrpci_init(void); -extern void ioc3_init(void); -extern void initialize_io(void); -extern void klhwg_add_all_modules(devfs_handle_t); -extern void klhwg_add_all_nodes(devfs_handle_t); - -void sn_mp_setup(void); -extern devfs_handle_t hwgraph_root; -extern void io_module_init(void); -extern void pci_bus_cvlink_init(void); -extern void temp_hack(void); - -extern int pci_bus_to_hcl_cvlink(void); - -/* #define DEBUG_IO_INIT 1 */ -#ifdef DEBUG_IO_INIT -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* DEBUG_IO_INIT */ - -/* - * per_hub_init - * - * This code is executed once for each Hub chip. - */ -static void -per_hub_init(cnodeid_t cnode) -{ - nasid_t nasid; - nodepda_t *npdap; - ii_icmr_u_t ii_icmr; - ii_ibcr_u_t ii_ibcr; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - ASSERT(nasid != INVALID_NASID); - ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode); - - npdap = NODEPDA(cnode); - -#ifdef BRINGUP2 -#if 0 - while ((REMOTE_HUB_L(nasid, IIO_IFDR)) != 0x2d2d) - REMOTE_HUB_S(nasid, IIO_IFDR, 0xadad); -#endif - printk("IIO_IFDR = 0x%x\n", REMOTE_HUB_L(nasid, IIO_IFDR)); - REMOTE_HUB_S(nasid, IIO_IWEIM, 0x8000); -#endif - /* - * Set the total number of CRBs that can be used. - */ - ii_icmr.ii_icmr_regval= 0x0; - ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF; - REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval); - - /* - * Set the number of CRBs that both of the BTEs combined - * can use minus 1. - */ - ii_ibcr.ii_ibcr_regval= 0x0; - ii_ibcr.ii_ibcr_fld_s.i_count = 0x8; - REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval); - - /* - * Set CRB timeout to be 10ms. - */ -#ifdef BRINGUP2 - REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff ); - REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); - REMOTE_HUB_S(nasid, IIO_IDBSS, 0x504); - REMOTE_HUB_S(nasid, SH_DEBUG_SELECT, 0x0002DF6D74CF2C70); -#endif - - /* Initialize error interrupts for this hub. */ - hub_error_init(cnode); -} - -/* - * This routine is responsible for the setup of all the IRIX hwgraph style - * stuff that's been pulled into linux. It's called by sn_pci_find_bios which - * is called just before the generic Linux PCI layer does its probing (by - * platform_pci_fixup aka sn_pci_fixup). - * - * It is very IMPORTANT that this call is only made by the Master CPU! - * - */ - -void -sgi_master_io_infr_init(void) -{ - int cnode; - - /* - * Do any early init stuff .. einit_tbl[] etc. - */ - init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */ - - /* - * initialize the Linux PCI to xwidget vertexes .. - */ - pci_bus_cvlink_init(); - -#ifdef BRINGUP - /* - * Hack to provide statically initialzed klgraph entries. - */ - DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n"); - klgraph_hack_init(); -#endif /* BRINGUP */ - - /* - * This is the Master CPU. Emulate mlsetup and main.c in Irix. - */ - mlreset(); - - /* - * allowboot() is called by kern/os/main.c in main() - * Emulate allowboot() ... - * per_cpu_init() - only need per_hub_init() - * cpu_io_setup() - Nothing to do. - * - */ - sn_mp_setup(); - - for (cnode = 0; cnode < numnodes; cnode++) { - per_hub_init(cnode); - } - - /* We can do headless hub cnodes here .. */ - - /* - * io_init[] stuff. - * - * Get SGI IO Infrastructure drivers to init and register with - * each other etc. - */ - - hubspc_init(); - pciio_init(); - pcibr_init(); - pic_init(); - xtalk_init(); - xbow_init(); - xbmon_init(); - pciiox_init(); - usrpci_init(); - ioc3_init(); - - /* - * - * Our IO Infrastructure drivers are in place .. - * Initialize the whole IO Infrastructure .. xwidget/device probes. - * - */ - initialize_io(); - pci_bus_to_hcl_cvlink(); - -#ifdef CONFIG_PCIBA - DBG("--> sgi_master_io_infr_init: calling pciba_init()\n"); -#ifndef BRINGUP2 - pciba_init(); -#endif -#endif -} - -/* - * One-time setup for MP SN. - * Allocate per-node data, slurp prom klconfig information and - * convert it to hwgraph information. - */ -void -sn_mp_setup(void) -{ - cpuid_t cpu; - - for (cpu = 0; cpu < smp_num_cpus; cpu++) { - /* Skip holes in CPU space */ - if (cpu_enabled(cpu)) { - init_platform_pda(cpu); - } - } - - /* - * Initialize platform-dependent vertices in the hwgraph: - * module - * node - * cpu - * memory - * slot - * hub - * router - * xbow - */ - - io_module_init(); /* Use to be called module_init() .. */ - klhwg_add_all_modules(hwgraph_root); - klhwg_add_all_nodes(hwgraph_root); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/shub.c linux-2.4.22/arch/ia64/sn/io/sn2/shub.c --- linux-2.4.21/arch/ia64/sn/io/sn2/shub.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/shub.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ #ident "$Revision: 1.167 $" @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,14 @@ } static inline void +shub_mmr_write_iospace(cnodeid_t cnode, shubreg_t reg, uint64_t val) +{ + int nasid = cnodeid_to_nasid(cnode); + + REMOTE_HUB_S(nasid, reg, val); +} + +static inline void shub_mmr_write32(cnodeid_t cnode, shubreg_t reg, uint32_t val) { int nasid = cnodeid_to_nasid(cnode); @@ -118,6 +127,14 @@ return val; } +static inline uint64_t +shub_mmr_read_iospace(cnodeid_t cnode, shubreg_t reg) +{ + int nasid = cnodeid_to_nasid(cnode); + + return REMOTE_HUB_L(nasid, reg); +} + static inline uint32_t shub_mmr_read32(cnodeid_t cnode, shubreg_t reg) { @@ -182,12 +199,15 @@ { cnodeid_t cnode; uint64_t longarg; - devfs_handle_t d; int nasid; - if ((d = devfs_get_handle_from_inode(inode)) == NULL) +#ifdef CONFIG_HWGFS_FS + cnode = (cnodeid_t)file->f_dentry->d_fsdata; +#else + cnode = (cnodeid_t)file->private_data; +#endif + if (!cnode) return -ENODEV; - cnode = (cnodeid_t)hwgraph_fastinfo_get(d); switch (cmd) { case SNDRV_SHUB_CONFIGURE: @@ -231,3 +251,255 @@ struct file_operations shub_mon_fops = { ioctl: shubstats_ioctl, }; + +/* + * "linkstatd" kernel thread to export SGI Numalink + * stats via /proc/sgi_sn/linkstats + */ +static struct s_linkstats { + uint64_t hs_ni_sn_errors[2]; + uint64_t hs_ni_cb_errors[2]; + uint64_t hs_ni_retry_errors[2]; + int hs_ii_up; + uint64_t hs_ii_sn_errors; + uint64_t hs_ii_cb_errors; + uint64_t hs_ii_retry_errors; +} *sn_linkstats; + +static spinlock_t sn_linkstats_lock; +static unsigned long sn_linkstats_starttime; +static unsigned long sn_linkstats_samples; +static unsigned long sn_linkstats_overflows; +static unsigned long sn_linkstats_update_msecs; + +void +sn_linkstats_reset(unsigned long msecs) +{ + int cnode; + uint64_t iio_wstat; + uint64_t llp_csr_reg; + + spin_lock(&sn_linkstats_lock); + memset(sn_linkstats, 0, numnodes * sizeof(struct s_linkstats)); + for (cnode=0; cnode < numnodes; cnode++) { + shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L); + shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L); + shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L); + + /* zero the II retry counter */ + iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT); + iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */ + shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat); + + /* Check if the II xtalk link is working */ + llp_csr_reg = shub_mmr_read_iospace(cnode, IIO_LLP_CSR); + if (llp_csr_reg & IIO_LLP_CSR_IS_UP) + sn_linkstats[cnode].hs_ii_up = 1; + } + + sn_linkstats_update_msecs = msecs; + sn_linkstats_samples = 0; + sn_linkstats_overflows = 0; + sn_linkstats_starttime = jiffies; + spin_unlock(&sn_linkstats_lock); +} + +int +linkstatd_thread(void *unused) +{ + int cnode; + int overflows; + uint64_t reg[2]; + uint64_t iio_wstat = 0L; + ii_illr_u_t illr; + struct s_linkstats *lsp; + struct task_struct *tsk = current; + + daemonize(); + set_user_nice(tsk, 19); + sigfillset(&tsk->blocked); + strcpy(tsk->comm, "linkstatd"); + + while(1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(sn_linkstats_update_msecs * HZ / 1000); + + spin_lock(&sn_linkstats_lock); + + overflows = 0; + for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) { + reg[0] = shub_mmr_read(cnode, SH_NI0_LLP_ERR); + reg[1] = shub_mmr_read(cnode, SH_NI1_LLP_ERR); + if (lsp->hs_ii_up) { + illr = (ii_illr_u_t)shub_mmr_read_iospace(cnode, IIO_LLP_LOG); + iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT); + } + + if (!overflows && ( + (reg[0] & SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK) == + SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK || + (reg[0] & SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK) == + SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK || + (reg[1] & SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK) == + SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK || + (reg[1] & SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK) == + SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK || + (lsp->hs_ii_up && illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) || + (lsp->hs_ii_up && illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))) { + overflows = 1; + } + +#define LINKSTAT_UPDATE(reg, cnt, mask, shift) cnt += (reg & mask) >> shift + + LINKSTAT_UPDATE(reg[0], lsp->hs_ni_sn_errors[0], + SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK, + SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[1], lsp->hs_ni_sn_errors[1], + SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK, + SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[0], lsp->hs_ni_cb_errors[0], + SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK, + SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[1], lsp->hs_ni_cb_errors[1], + SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK, + SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[0], lsp->hs_ni_retry_errors[0], + SH_NI0_LLP_ERR_RETRY_COUNT_MASK, + SH_NI0_LLP_ERR_RETRY_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[1], lsp->hs_ni_retry_errors[1], + SH_NI1_LLP_ERR_RETRY_COUNT_MASK, + SH_NI1_LLP_ERR_RETRY_COUNT_SHFT); + + if (lsp->hs_ii_up) { + /* II sn and cb errors */ + lsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt; + lsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt; + lsp->hs_ii_retry_errors += (iio_wstat & 0x0000000000ff0000) >> 16; + + shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L); + shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L); + shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L); + + /* zero the II retry counter */ + iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT); + iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */ + shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat); + } + } + + sn_linkstats_samples++; + if (overflows) + sn_linkstats_overflows++; + + spin_unlock(&sn_linkstats_lock); + } +} + +static char * +rate_per_minute(uint64_t val, uint64_t secs) +{ + static char buf[16]; + uint64_t a=0, b=0, c=0, d=0; + + if (secs) { + a = 60 * val / secs; + b = 60 * 10 * val / secs - (10 * a); + c = 60 * 100 * val / secs - (100 * a) - (10 * b); + d = 60 * 1000 * val / secs - (1000 * a) - (100 * b) - (10 * c); + } + sprintf(buf, "%4lu.%lu%lu%lu", a, b, c, d); + + return buf; +} + +int +sn_linkstats_get(char *page) +{ + int n = 0; + int cnode; + int nlport; + struct s_linkstats *lsp; + nodepda_t *npda; + uint64_t snsum = 0; + uint64_t cbsum = 0; + uint64_t retrysum = 0; + uint64_t snsum_ii = 0; + uint64_t cbsum_ii = 0; + uint64_t retrysum_ii = 0; + uint64_t secs; + + spin_lock(&sn_linkstats_lock); + secs = (jiffies - sn_linkstats_starttime) / HZ; + + n += sprintf(page, "# SGI Numalink stats v1 : %lu samples, %lu o/flows, update %lu msecs\n", + sn_linkstats_samples, sn_linkstats_overflows, sn_linkstats_update_msecs); + + n += sprintf(page+n, "%-37s %8s %8s %8s %8s\n", + "# Numalink", "sn errs", "cb errs", "cb/min", "retries"); + + for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) { + npda = NODEPDA(cnode); + + /* two NL links on each SHub */ + for (nlport=0; nlport < 2; nlport++) { + cbsum += lsp->hs_ni_cb_errors[nlport]; + snsum += lsp->hs_ni_sn_errors[nlport]; + retrysum += lsp->hs_ni_retry_errors[nlport]; + + /* avoid buffer overrun (should be using seq_read API) */ + if (numnodes > 64) + continue; + + n += sprintf(page + n, "/%s/link/%d %8lu %8lu %8s %8lu\n", + npda->hwg_node_name, nlport+1, lsp->hs_ni_sn_errors[nlport], + lsp->hs_ni_cb_errors[nlport], + rate_per_minute(lsp->hs_ni_cb_errors[nlport], secs), + lsp->hs_ni_retry_errors[nlport]); + } + + /* one II port on each SHub (may not be connected) */ + if (lsp->hs_ii_up) { + n += sprintf(page + n, "/%s/xtalk %8lu %8lu %8s %8lu\n", + npda->hwg_node_name, lsp->hs_ii_sn_errors, + lsp->hs_ii_cb_errors, rate_per_minute(lsp->hs_ii_cb_errors, secs), + lsp->hs_ii_retry_errors); + + snsum_ii += lsp->hs_ii_sn_errors; + cbsum_ii += lsp->hs_ii_cb_errors; + retrysum_ii += lsp->hs_ii_retry_errors; + } + } + + n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n", + "System wide NL totals", snsum, cbsum, + rate_per_minute(cbsum, secs), retrysum); + + n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n", + "System wide II totals", snsum_ii, cbsum_ii, + rate_per_minute(cbsum_ii, secs), retrysum_ii); + + spin_unlock(&sn_linkstats_lock); + + return n; +} + +static int __init +linkstatd_init(void) +{ + if (!ia64_platform_is("sn2")) + return -ENODEV; + + spin_lock_init(&sn_linkstats_lock); + sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL); + sn_linkstats_reset(60000UL); /* default 60 second update interval */ + kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + + return 0; +} + +__initcall(linkstatd_init); diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/shub_intr.c linux-2.4.22/arch/ia64/sn/io/sn2/shub_intr.c --- linux-2.4.21/arch/ia64/sn/io/sn2/shub_intr.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/shub_intr.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ #include @@ -30,7 +30,7 @@ /* ARGSUSED */ void -hub_intr_init(devfs_handle_t hubv) +hub_intr_init(vertex_hdl_t hubv) { } @@ -45,9 +45,9 @@ } static hub_intr_t -do_hub_intr_alloc(devfs_handle_t dev, +do_hub_intr_alloc(vertex_hdl_t dev, device_desc_t dev_desc, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, int uncond_nothread) { cpuid_t cpu = 0; @@ -101,17 +101,17 @@ } hub_intr_t -hub_intr_alloc(devfs_handle_t dev, +hub_intr_alloc(vertex_hdl_t dev, device_desc_t dev_desc, - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0)); } hub_intr_t -hub_intr_alloc_nothd(devfs_handle_t dev, +hub_intr_alloc_nothd(vertex_hdl_t dev, device_desc_t dev_desc, - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1)); } @@ -188,18 +188,3 @@ ASSERT(rv == 0); intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED; } - - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. - */ -devfs_handle_t -hub_intr_cpu_get(hub_intr_t intr_hdl) -{ - cpuid_t cpuid = intr_hdl->i_cpuid; - - ASSERT(cpuid != CPU_NONE); - - return(cpuid_to_vertex(cpuid)); -} diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/shuberror.c linux-2.4.22/arch/ia64/sn/io/sn2/shuberror.c --- linux-2.4.21/arch/ia64/sn/io/sn2/shuberror.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/shuberror.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,13 +4,14 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved. */ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -34,21 +36,18 @@ extern void hubni_eint_init(cnodeid_t cnode); extern void hubii_eint_init(cnodeid_t cnode); extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep); -int hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo); -int hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo); -extern void bte_crb_error_handler(devfs_handle_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop); +int hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo); +int hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo); +extern void bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop); +void print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba, + ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc, + ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe); extern int maxcpus; +extern error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state); #define HUB_ERROR_PERIOD (120 * HZ) /* 2 minutes */ -#ifdef BUS_INT_WAR -void sn_add_polled_interrupt(int irq, int interval); -void sn_delete_polled_interrupt(int irq); -extern int bus_int_war_ide_irq; -#endif - - void hub_error_clear(nasid_t nasid) { @@ -74,9 +73,7 @@ REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval); } - REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1); - idsr = REMOTE_HUB_L(nasid, IIO_IIDSR); - REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK))); + REMOTE_HUB_S(nasid, IIO_IECLR, -1); } @@ -117,7 +114,6 @@ * Returns : None. */ - void hubii_eint_init(cnodeid_t cnode) { @@ -125,33 +121,41 @@ ii_iidsr_u_t hubio_eint; hubinfo_t hinfo; cpuid_t intr_cpu; - devfs_handle_t hub_v; + vertex_hdl_t hub_v; int bit_pos_to_irq(int bit); + ii_ilcsr_u_t ilcsr; - hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode); + hub_v = (vertex_hdl_t)cnodeid_to_vertex(cnode); ASSERT_ALWAYS(hub_v); hubinfo_get(hub_v, &hinfo); ASSERT(hinfo); ASSERT(hinfo->h_cnodeid == cnode); + ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR); + if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) { + /* + * HUB II link is not up. Disable LLP. Clear old errors. + * Enable interrupts to handle BTE errors. + */ + ilcsr.ii_ilcsr_fld_s.i_llp_en = 0; + REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval); + } + /* Select a possible interrupt target where there is a free interrupt * bit and also reserve the interrupt bit for this IO error interrupt */ - intr_cpu = intr_heuristic(hub_v,0,-1,0,hub_v, + intr_cpu = intr_heuristic(hub_v,0,SGI_II_ERROR,0,hub_v, "HUB IO error interrupt",&bit); if (intr_cpu == CPU_NONE) { printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode); return; } - rv = intr_connect_level(intr_cpu, bit, 0, NULL); - request_irq(bit + (intr_cpu << 8), hubii_eint_handler, 0, "SN_hub_error", (void *)hub_v); - irq_desc(bit + (intr_cpu << 8))->status |= SN2_IRQ_PER_HUB; -#ifdef BUS_INT_WAR - sn_add_polled_interrupt(bit + (intr_cpu << 8), (0.01 * HZ)); -#endif + rv = intr_connect_level(intr_cpu, SGI_II_ERROR, 0, NULL); + request_irq(SGI_II_ERROR, hubii_eint_handler, SA_SHIRQ, "SN_hub_error", (void *)hub_v); + irq_desc(bit)->status |= SN2_IRQ_PER_HUB; ASSERT_ALWAYS(rv >= 0); hubio_eint.ii_iidsr_regval = 0; hubio_eint.ii_iidsr_fld_s.i_enable = 1; @@ -167,18 +171,29 @@ void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) { - devfs_handle_t hub_v; + vertex_hdl_t hub_v; hubinfo_t hinfo; ii_wstat_u_t wstat; hubreg_t idsr; + ii_ilcsr_u_t ilcsr; /* two levels of casting avoids compiler warning.!! */ - hub_v = (devfs_handle_t)(long)(arg); + hub_v = (vertex_hdl_t)(long)(arg); ASSERT(hub_v); hubinfo_get(hub_v, &hinfo); + idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICMR); +#if 0 + if (idsr & 0x1) { + /* ICMR bit is set .. we are getting into "Spurious Interrupts condition. */ + printk("Cnode %d II has seen the ICMR condition\n", hinfo->h_cnodeid); + printk("***** Please file PV with the above messages *****\n"); + /* panic("We have to panic to prevent further unknown states ..\n"); */ + } +#endif + /* * Identify the reason for error. */ @@ -218,10 +233,26 @@ * Note: we may never be able to print this, if the II talking * to Xbow which hosts the console is dead. */ - printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", - hinfo->h_cnodeid, reason); + ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR); + if (ilcsr.ii_ilcsr_fld_s.i_llp_en == 1) { /* Link is enabled */ + printk("Hub %d, cnode %d to Xtalk Link failed (II_ECRAZY) Reason: %s", + hinfo->h_nasid, hinfo->h_cnodeid, reason); + } } + + /* + * Before processing any interrupt related information, clear all + * error indication and reenable interrupts. This will prevent + * lost interrupts due to the interrupt handler scanning past a PRB/CRB + * which has not errorred yet and then the PRB/CRB goes into error. + * Note, PRB errors are cleared individually. + */ + REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xff0000); + idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK; + REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr); + + /* * It's a toss as to which one among PRB/CRB to check first. * Current decision is based on the severity of the errors. @@ -232,14 +263,6 @@ */ (void)hubiio_crb_error_handler(hub_v, hinfo); (void)hubiio_prb_error_handler(hub_v, hinfo); - /* - * If we reach here, it indicates crb/prb handlers successfully - * handled the error. So, re-enable II to send more interrupt - * and return. - */ - REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff); - idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK; - REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr); } /* @@ -295,6 +318,105 @@ "Xtalk Error Packet" }; +void +print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba, + ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc, + ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe) +{ + printk("CRB %d regA\n\t" + "a_iow 0x%x\n\t" + "valid0x%x\n\t" + "Address0x%lx\n\t" + "a_tnum 0x%x\n\t" + "a_sidn 0x%x\n", + crb_num, + icrba.a_iow, + icrba.a_valid, + icrba.a_addr, + icrba.a_tnum, + icrba.a_sidn); + printk("CRB %d regB\n\t" + "b_imsgtype 0x%x\n\t" + "b_imsg 0x%x\n" + "\tb_use_old 0x%x\n\t" + "b_initiator 0x%x\n\t" + "b_exc 0x%x\n" + "\tb_ackcnt 0x%x\n\t" + "b_resp 0x%x\n\t" + "b_ack 0x%x\n" + "\tb_hold 0x%x\n\t" + "b_wb 0x%x\n\t" + "b_intvn 0x%x\n" + "\tb_stall_ib 0x%x\n\t" + "b_stall_int 0x%x\n" + "\tb_stall_bte_0 0x%x\n\t" + "b_stall_bte_1 0x%x\n" + "\tb_error 0x%x\n\t" + "b_lnetuce 0x%x\n\t" + "b_mark 0x%x\n\t" + "b_xerr 0x%x\n", + crb_num, + icrbb.b_imsgtype, + icrbb.b_imsg, + icrbb.b_use_old, + icrbb.b_initiator, + icrbb.b_exc, + icrbb.b_ackcnt, + icrbb.b_resp, + icrbb.b_ack, + icrbb.b_hold, + icrbb.b_wb, + icrbb.b_intvn, + icrbb.b_stall_ib, + icrbb.b_stall_int, + icrbb.b_stall_bte_0, + icrbb.b_stall_bte_1, + icrbb.b_error, + icrbb.b_lnetuce, + icrbb.b_mark, + icrbb.b_xerr); + printk("CRB %d regC\n\t" + "c_source 0x%x\n\t" + "c_xtsize 0x%x\n\t" + "c_cohtrans 0x%x\n\t" + "c_btenum 0x%x\n\t" + "c_gbr 0x%x\n\t" + "c_doresp 0x%x\n\t" + "c_barrop 0x%x\n\t" + "c_suppl 0x%x\n", + crb_num, + icrbc.c_source, + icrbc.c_xtsize, + icrbc.c_cohtrans, + icrbc.c_btenum, + icrbc.c_gbr, + icrbc.c_doresp, + icrbc.c_barrop, + icrbc.c_suppl); + printk("CRB %d regD\n\t" + "d_bteaddr 0x%lx\n\t" + "d_bteop 0x%x\n\t" + "d_pripsc 0x%x\n\t" + "d_pricnt 0x%x\n\t" + "d_sleep 0x%x\n\t", + crb_num, + icrbd.d_bteaddr, + icrbd.d_bteop, + icrbd.d_pripsc, + icrbd.d_pricnt, + icrbd.d_sleep); + printk("CRB %d regE\n\t" + "icrbe_timeout 0x%x\n\t" + "icrbe_context 0x%x\n\t" + "icrbe_toutvld 0x%x\n\t" + "icrbe_ctxtvld 0x%x\n\t", + crb_num, + icrbe.icrbe_timeout, + icrbe.icrbe_context, + icrbe.icrbe_toutvld, + icrbe.icrbe_ctxtvld); +} + /* * hubiio_crb_error_handler * @@ -317,7 +439,7 @@ */ int -hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) +hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo) { cnodeid_t cnode; nasid_t nasid; @@ -335,6 +457,9 @@ cnode = NASID_TO_COMPACT_NODEID(nasid); /* + * XXX - Add locking for any recovery actions + */ + /* * Scan through all CRBs in the Hub, and handle the errors * in any of the CRBs marked. */ @@ -373,16 +498,11 @@ else /* b_initiator bit 2 gives BTE number */ bte_num = (icrbb.b_initiator & 0x4) >> 2; - /* >>> bte_crb_error_handler needs to be - * broken into two parts. The first should - * cleanup the CRB. The second should wait - * until all bte related CRB's are complete - * and then do the error reset. - */ + hubiio_crb_free(hinfo, i); + bte_crb_error_handler(hub_v, bte_num, i, &ioerror, icrbd.d_bteop); - hubiio_crb_free(hinfo, i); num_errors++; continue; } @@ -430,6 +550,86 @@ IOERROR_SETVALUE(&ioerror, tnum, icrba.a_tnum); } + if (icrbb.b_error) { + /* + * CRB 'i' has some error. Identify the type of error, + * and try to handle it. + * + */ + switch(icrbb.b_ecode) { + case IIO_ICRB_ECODE_PERR: + case IIO_ICRB_ECODE_WERR: + case IIO_ICRB_ECODE_AERR: + case IIO_ICRB_ECODE_PWERR: + case IIO_ICRB_ECODE_TOUT: + case IIO_ICRB_ECODE_XTERR: + printk("Shub II CRB %d: error %s on hub cnodeid: %d", + i, hubiio_crb_errors[icrbb.b_ecode], cnode); + /* + * Any sort of write error is mostly due + * bad programming (Note it's not a timeout.) + * So, invoke hub_iio_error_handler with + * appropriate information. + */ + IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode); + + /* Go through the error bit lookup phase */ + if (error_state_set(hub_v, ERROR_STATE_LOOKUP) == + ERROR_RETURN_CODE_CANNOT_SET_STATE) + return(IOERROR_UNHANDLED); + rc = hub_ioerror_handler( + hub_v, + DMA_WRITE_ERROR, + MODE_DEVERROR, + &ioerror); + if (rc == IOERROR_HANDLED) { + rc = hub_ioerror_handler( + hub_v, + DMA_WRITE_ERROR, + MODE_DEVREENABLE, + &ioerror); + }else { + printk("Unable to handle %s on hub %d", + hubiio_crb_errors[icrbb.b_ecode], + cnode); + /* panic; */ + } + /* Go to Next error */ + print_crb_fields(i, icrba, icrbb, icrbc, + icrbd, icrbe); + hubiio_crb_free(hinfo, i); + continue; + case IIO_ICRB_ECODE_PRERR: + case IIO_ICRB_ECODE_DERR: + printk("Shub II CRB %d: error %s on hub : %d", + i, hubiio_crb_errors[icrbb.b_ecode], cnode); + /* panic */ + default: + printk("Shub II CRB error (code : %d) on hub : %d", + icrbb.b_ecode, cnode); + /* panic */ + } + } + /* + * Error is not indicated via the errcode field + * Check other error indications in this register. + */ + if (icrbb.b_xerr) { + printk("Shub II CRB %d: Xtalk Packet with error bit set to hub %d", + i, cnode); + /* panic */ + } + if (icrbb.b_lnetuce) { + printk("Shub II CRB %d: Uncorrectable data error detected on data " + " from NUMAlink to node %d", + i, cnode); + /* panic */ + } + print_crb_fields(i, icrba, icrbb, icrbc, icrbd, icrbe); + + + + if (icrbb.b_error) { /* @@ -488,7 +688,7 @@ default: panic("Fatal error (code : %d) on hub : %d", - cnode); + icrbb.b_ecode, cnode); /*NOTREACHED*/ } @@ -568,7 +768,7 @@ * Cleanup involes freeing the PRB register */ static void -hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum) +hubii_prb_handler(vertex_hdl_t hub_v, hubinfo_t hinfo, int wnum) { nasid_t nasid; @@ -576,13 +776,13 @@ /* * Clear error bit by writing to IECLR register. */ - REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, (1 << wnum)); + REMOTE_HUB_S(nasid, IIO_IECLR, (1 << wnum)); /* * PIO Write to Widget 'i' got into an error. * Invoke hubiio_error_handler with this information. */ - printk( "Hub nasid %d got a PIO Write error from widget %d, cleaning up and continuing", - nasid, wnum); + printk( "Hub nasid %d got a PIO Write error from widget %d, " + "cleaning up and continuing", nasid, wnum); /* * XXX * It may be necessary to adjust IO PRB counter @@ -591,7 +791,7 @@ } int -hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) +hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo) { int wnum; nasid_t nasid; diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/shubio.c linux-2.4.22/arch/ia64/sn/io/sn2/shubio.c --- linux-2.4.21/arch/ia64/sn/io/sn2/shubio.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/shubio.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved. */ @@ -30,8 +30,8 @@ #include -error_state_t error_state_get(devfs_handle_t v); -error_return_code_t error_state_set(devfs_handle_t v,error_state_t new_state); +error_state_t error_state_get(vertex_hdl_t v); +error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state); /* @@ -42,7 +42,7 @@ /*ARGSUSED*/ int hub_xp_error_handler( - devfs_handle_t hub_v, + vertex_hdl_t hub_v, nasid_t nasid, int error_code, ioerror_mode_t mode, @@ -50,7 +50,7 @@ { /*REFERENCED*/ hubreg_t iio_imem; - devfs_handle_t xswitch; + vertex_hdl_t xswitch; error_state_t e_state; cnodeid_t cnode; @@ -148,7 +148,7 @@ */ int hub_ioerror_handler( - devfs_handle_t hub_v, + vertex_hdl_t hub_v, int error_code, int mode, struct io_error_s *ioerror) @@ -158,6 +158,7 @@ int retval = 0; /*REFERENCED*/ iopaddr_t p; + caddr_t cp; IOERROR_DUMP("hub_ioerror_handler", error_code, mode, ioerror); @@ -193,14 +194,14 @@ * This is typically true for user mode bus errors while * accessing I/O space. */ - IOERROR_GETVALUE(p,ioerror,vaddr); - if (p){ + IOERROR_GETVALUE(cp,ioerror,vaddr); + if (cp){ /* * If neither in small window nor in large window range, * outright reject it. */ - IOERROR_GETVALUE(p,ioerror,vaddr); - if (NODE_SWIN_ADDR(nasid, (paddr_t)p)){ + IOERROR_GETVALUE(cp,ioerror,vaddr); + if (NODE_SWIN_ADDR(nasid, (paddr_t)cp)){ iopaddr_t hubaddr; xwidgetnum_t widgetnum; iopaddr_t xtalkaddr; @@ -216,7 +217,7 @@ IOERROR_SETVALUE(ioerror,xtalkaddr,xtalkaddr); - } else if (NODE_BWIN_ADDR(nasid, (paddr_t)p)){ + } else if (NODE_BWIN_ADDR(nasid, (paddr_t)cp)){ /* * Address corresponds to large window space. * Convert it to xtalk address. @@ -428,11 +429,6 @@ return retval; } -#define L_BITSMINOR 18 -#define L_MAXMAJ 0x1ff -#define emajor(x) (int )(((unsigned )(x)>>L_BITSMINOR) & L_MAXMAJ) -#define dev_is_vertex(dev) (emajor((dev_t)(dev)) == 0) - #define INFO_LBL_ERROR_STATE "error_state" #define v_error_state_get(v,s) \ @@ -454,12 +450,12 @@ * current state otherwise */ error_state_t -error_state_get(devfs_handle_t v) +error_state_get(vertex_hdl_t v) { error_state_t s; /* Check if we have a valid hwgraph vertex */ - if (!dev_is_vertex(v)) + if ( v == (vertex_hdl_t)0 ) return(ERROR_STATE_NONE); /* Get the labelled info hanging off the vertex which corresponds @@ -479,13 +475,13 @@ * ERROR_RETURN_CODE_SUCCESS otherwise */ error_return_code_t -error_state_set(devfs_handle_t v,error_state_t new_state) +error_state_set(vertex_hdl_t v,error_state_t new_state) { error_state_t old_state; boolean_t replace = B_TRUE; /* Check if we have a valid hwgraph vertex */ - if (!dev_is_vertex(v)) + if ( v == (vertex_hdl_t)0 ) return(ERROR_RETURN_CODE_GENERAL_FAILURE); diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/xbow.c linux-2.4.22/arch/ia64/sn/io/sn2/xbow.c --- linux-2.4.21/arch/ia64/sn/io/sn2/xbow.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/xbow.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,12 +4,14 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include #include +#include #include +#include #include #include #include @@ -18,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -44,8 +45,6 @@ #define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) #define DEL(ptr) (kfree(ptr)) -int xbow_devflag = D_MP; - /* * This file supports the Xbow chip. Main functions: initializtion, * error handling, and GBR. @@ -59,9 +58,9 @@ typedef struct xbow_soft_s *xbow_soft_t; struct xbow_soft_s { - devfs_handle_t conn; /* our connection point */ - devfs_handle_t vhdl; /* xbow's private vertex */ - devfs_handle_t busv; /* the xswitch vertex */ + vertex_hdl_t conn; /* our connection point */ + vertex_hdl_t vhdl; /* xbow's private vertex */ + vertex_hdl_t busv; /* the xswitch vertex */ xbow_t *base; /* PIO pointer to crossbow chip */ char *name; /* hwgraph name */ @@ -89,36 +88,27 @@ */ void xbow_mlreset(xbow_t *); -void xbow_init(void); -int xbow_attach(devfs_handle_t); - -int xbow_open(devfs_handle_t *, int, int, cred_t *); -int xbow_close(devfs_handle_t, int, int, cred_t *); - -int xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); -int xbow_unmap(devfs_handle_t, vhandl_t *); -int xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); +int xbow_attach(vertex_hdl_t); int xbow_widget_present(xbow_t *, int); static int xbow_link_alive(xbow_t *, int); -devfs_handle_t xbow_widget_lookup(devfs_handle_t, int); +vertex_hdl_t xbow_widget_lookup(vertex_hdl_t, int); void xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); -void xbow_update_perf_counters(devfs_handle_t); -xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t); -int xbow_enable_perf_counter(devfs_handle_t, int, int, int); -xbow_link_status_t *xbow_get_llp_status(devfs_handle_t); -void xbow_update_llp_status(devfs_handle_t); - -int xbow_disable_llp_monitor(devfs_handle_t); -int xbow_enable_llp_monitor(devfs_handle_t); -int xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t, +void xbow_update_perf_counters(vertex_hdl_t); +xbow_perf_link_t *xbow_get_perf_counters(vertex_hdl_t); +int xbow_enable_perf_counter(vertex_hdl_t, int, int, int); +xbow_link_status_t *xbow_get_llp_status(vertex_hdl_t); +void xbow_update_llp_status(vertex_hdl_t); + +int xbow_disable_llp_monitor(vertex_hdl_t); +int xbow_enable_llp_monitor(vertex_hdl_t); +int xbow_prio_bw_alloc(vertex_hdl_t, xwidgetnum_t, xwidgetnum_t, unsigned long long, unsigned long long); static void xbow_setwidint(xtalk_intr_t); -void idbg_xbowregs(int64_t); xswitch_reset_link_f xbow_reset_link; @@ -127,6 +117,32 @@ xbow_reset_link, }; + +static int +xbow_mmap(struct file * file, struct vm_area_struct * vma) +{ + unsigned long phys_addr; + int error = 0; + + phys_addr = (unsigned long)file->private_data & ~0xc000000000000000; /* Mask out the Uncache bits */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO; + error = io_remap_page_range(vma->vm_start, phys_addr, + vma->vm_end-vma->vm_start, + vma->vm_page_prot); + return(error); +} + +/* + * This is the file operation table for the pcibr driver. + * As each of the functions are implemented, put the + * appropriate function name below. + */ +struct file_operations xbow_fops = { + .owner = THIS_MODULE, + .mmap = xbow_mmap, +}; + /* * xbow_mlreset: called at mlreset time if the * platform specific code determines that there is @@ -144,39 +160,6 @@ { } -/* - * xbow_init: called with the rest of the device - * driver XXX_init routines. This platform *might* - * have a Crossbow chip, or even several, but it - * might have none. Register with the crosstalk - * generic provider so when we encounter the chip - * the right magic happens. - */ -void -xbow_init(void) -{ - -#if DEBUG && ATTACH_DEBUG - printk("xbow_init\n"); -#endif - - xwidget_driver_register(PXBOW_WIDGET_PART_NUM, - 0, /* XXBOW_WIDGET_MFGR_NUM, */ - "xbow_", - CDL_PRI_HI); /* attach before friends */ - - - xwidget_driver_register(XXBOW_WIDGET_PART_NUM, - 0, /* XXBOW_WIDGET_MFGR_NUM, */ - "xbow_", - CDL_PRI_HI); /* attach before friends */ - - xwidget_driver_register(XBOW_WIDGET_PART_NUM, - XBOW_WIDGET_MFGR_NUM, - "xbow_", - CDL_PRI_HI); /* attach before friends */ -} - #ifdef XBRIDGE_REGS_SIM /* xbow_set_simulated_regs: sets xbow regs as needed * for powering through the boot @@ -213,11 +196,11 @@ /*ARGSUSED */ int -xbow_attach(devfs_handle_t conn) +xbow_attach(vertex_hdl_t conn) { /*REFERENCED */ - devfs_handle_t vhdl; - devfs_handle_t busv; + vertex_hdl_t vhdl; + vertex_hdl_t busv; xbow_t *xbow; xbow_soft_t soft; int port; @@ -274,15 +257,14 @@ */ /* - * We need to teach xbow drivers to provide the right set of + * Register a xbow driver with devfs. * file ops. */ vhdl = NULL; - vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - /* &hcl_fops */ (void *)&vhdl, NULL); + vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0, + DEVFS_FL_AUTO_DEVNUM, 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + (struct file_operations *)&xbow_fops, (void *)xbow); if (!vhdl) { printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n", (void *)conn); @@ -299,7 +281,7 @@ soft->base = xbow; /* does the universe really need another macro? */ /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */ - hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); + /* hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); */ #define XBOW_NUM_SUFFIX_FORMAT "[xbow# %d]" @@ -350,6 +332,14 @@ */ intr_hdl = xtalk_intr_alloc(conn, (device_desc_t)0, vhdl); ASSERT(intr_hdl != NULL); + + { + int irq = ((hub_intr_t)intr_hdl)->i_bit; + int cpu = ((hub_intr_t)intr_hdl)->i_cpuid; + + intr_unreserve_level(cpu, irq); + ((hub_intr_t)intr_hdl)->i_bit = SGI_XBOW_ERROR; + } xtalk_intr_connect(intr_hdl, (intr_func_t) xbow_errintr_handler, @@ -357,19 +347,9 @@ (xtalk_intr_setfunc_t) xbow_setwidint, (void *) xbow); -#ifdef BUS_INT_WAR_NOT_YET - request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid, - ((hub_intr_t)intr_hdl)->i_bit), - (intr_func_t)xbow_errintr_handler, 0, "XBOW error", + request_irq(SGI_XBOW_ERROR, (void *)xbow_errintr_handler, SA_SHIRQ, "XBOW error", (intr_arg_t) soft); - { - void sn_add_polled_interrupt(int, int); - sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid, - ((hub_intr_t)intr_hdl)->i_bit), 5000); - } -#endif - /* * Enable xbow error interrupts @@ -439,50 +419,14 @@ return 0; /* attach successful */ } -/*ARGSUSED */ -int -xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) -{ - return 0; -} - -/*ARGSUSED */ -int -xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) -{ - return 0; -} - -/*ARGSUSED */ -int -xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) -{ - devfs_handle_t vhdl = dev_to_vhdl(dev); - xbow_soft_t soft = xbow_soft_get(vhdl); - int error; - - ASSERT(soft); - len = ctob(btoc(len)); - /* XXX- this ignores the offset!!! */ - error = v_mapphys(vt, (void *) soft->base, len); - return error; -} - -/*ARGSUSED */ -int -xbow_unmap(devfs_handle_t dev, vhandl_t *vt) -{ - return 0; -} - /* This contains special-case code for grio. There are plans to make * this general sometime in the future, but till then this should * be good enough. */ xwidgetnum_t -xbow_widget_num_get(devfs_handle_t dev) +xbow_widget_num_get(vertex_hdl_t dev) { - devfs_handle_t tdev; + vertex_hdl_t tdev; char devname[MAXDEVNAME]; xwidget_info_t xwidget_info; int i; @@ -512,58 +456,6 @@ return XWIDGET_NONE; } -int -xbow_ioctl(devfs_handle_t dev, - int cmd, - void *arg, - int flag, - struct cred *cr, - int *rvalp) -{ - devfs_handle_t vhdl; - int error = 0; - -#if defined (DEBUG) - int rc; - devfs_handle_t conn; - struct xwidget_info_s *xwidget_info; - xbow_soft_t xbow_soft; -#endif - *rvalp = 0; - - vhdl = dev_to_vhdl(dev); -#if defined (DEBUG) - xbow_soft = xbow_soft_get(vhdl); - conn = xbow_soft->conn; - - xwidget_info = xwidget_info_get(conn); - ASSERT_ALWAYS(xwidget_info != NULL); - - rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid); - ASSERT_ALWAYS(rc != 0); -#endif - switch (cmd) { - - case XBOWIOC_LLP_ERROR_ENABLE: - if ((error = xbow_enable_llp_monitor(vhdl)) != 0) - error = EINVAL; - - break; - - case XBOWIOC_LLP_ERROR_DISABLE: - - if ((error = xbow_disable_llp_monitor(vhdl)) != 0) - error = EINVAL; - - break; - - default: - break; - - } - return error; -} - /* * xbow_widget_present: See if a device is present * on the specified port of this crossbow. @@ -605,12 +497,12 @@ * specified. * If not found, return 0. */ -devfs_handle_t -xbow_widget_lookup(devfs_handle_t vhdl, +vertex_hdl_t +xbow_widget_lookup(vertex_hdl_t vhdl, int widgetnum) { xswitch_info_t xswitch_info; - devfs_handle_t conn; + vertex_hdl_t conn; xswitch_info = xswitch_info_get(vhdl); conn = xswitch_info_vhdl_get(xswitch_info, widgetnum); @@ -660,10 +552,6 @@ XTALK_ADDR_TO_UPPER(addr)); xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); -#ifdef BRINGUP2 -printk("xbow_intr_preset: xb_wid_int_upper 0x%lx xb_wid_int_lower 0x%lx\n", - (long)(((0xFF000000 & (vect << 24)) | (0x000F0000 & (targ << 16)) |XTALK_ADDR_TO_UPPER(addr))), (long)XTALK_ADDR_TO_LOWER(addr)); -#endif } #define XEM_ADD_STR(s) printk("%s", (s)) @@ -674,48 +562,14 @@ XEM_ADD_NVAR("ioe." #n, p); \ } -#ifdef LATER -static void -xem_add_ioe(ioerror_t *ioe) -{ - union tmp { - ushort stmp; - unsigned long long lltmp; - cpuid_t cputmp; - cnodeid_t cntmp; - iopaddr_t iotmp; - caddr_t catmp; - paddr_t patmp; - } tmp; - - XEM_ADD_IOEF(tmp.stmp, errortype); - XEM_ADD_IOEF(tmp.stmp, widgetnum); - XEM_ADD_IOEF(tmp.stmp, widgetdev); - XEM_ADD_IOEF(tmp.cputmp, srccpu); - XEM_ADD_IOEF(tmp.cntmp, srcnode); - XEM_ADD_IOEF(tmp.cntmp, errnode); - XEM_ADD_IOEF(tmp.iotmp, sysioaddr); - XEM_ADD_IOEF(tmp.iotmp, xtalkaddr); - XEM_ADD_IOEF(tmp.iotmp, busspace); - XEM_ADD_IOEF(tmp.iotmp, busaddr); - XEM_ADD_IOEF(tmp.catmp, vaddr); - XEM_ADD_IOEF(tmp.patmp, memaddr); - XEM_ADD_IOEF(tmp.catmp, epc); - XEM_ADD_IOEF(tmp.catmp, ef); - XEM_ADD_IOEF(tmp.stmp, tnum); -} - -#define XEM_ADD_IOE() (xem_add_ioe(ioe)) -#endif /* LATER */ - -int xbow_xmit_retry_errors = 0; +int xbow_xmit_retry_errors; int xbow_xmit_retry_error(xbow_soft_t soft, int port) { xswitch_info_t info; - devfs_handle_t vhdl; + vertex_hdl_t vhdl; widget_cfg_t *wid; widgetreg_t id; int part; @@ -865,7 +719,7 @@ link_pend &= ~XB_STAT_XMT_RTRY_ERR; } if (link_pend) { - devfs_handle_t xwidget_vhdl; + vertex_hdl_t xwidget_vhdl; char *xwidget_name; /* Get the widget name corresponding to the current @@ -917,12 +771,6 @@ XEM_ADD_VAR(link_status); XEM_ADD_VAR(link_aux_status); -#ifdef LATER - if (dump_ioe) { - XEM_ADD_IOE(); - dump_ioe = 0; - } -#endif #if !DEBUG } #endif @@ -987,8 +835,8 @@ xbow_soft_t soft = (xbow_soft_t) einfo; int port; - devfs_handle_t conn; - devfs_handle_t busv; + vertex_hdl_t conn; + vertex_hdl_t busv; xbow_t *xbow = soft->base; xbowreg_t wid_stat; @@ -1240,7 +1088,7 @@ } void -xbow_update_perf_counters(devfs_handle_t vhdl) +xbow_update_perf_counters(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; @@ -1268,7 +1116,7 @@ } xbow_perf_link_t * -xbow_get_perf_counters(devfs_handle_t vhdl) +xbow_get_perf_counters(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_perf_link_t *xbow_perf_link = xbow_soft->xbow_perflink; @@ -1277,7 +1125,7 @@ } int -xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter) +xbow_enable_perf_counter(vertex_hdl_t vhdl, int link, int mode, int counter) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; @@ -1331,7 +1179,7 @@ } xbow_link_status_t * -xbow_get_llp_status(devfs_handle_t vhdl) +xbow_get_llp_status(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; @@ -1340,7 +1188,7 @@ } void -xbow_update_llp_status(devfs_handle_t vhdl) +xbow_update_llp_status(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; @@ -1348,7 +1196,7 @@ xbwX_stat_t lnk_sts; xbow_aux_link_status_t aux_sts; int link; - devfs_handle_t xwidget_vhdl; + vertex_hdl_t xwidget_vhdl; char *xwidget_name; xbow = (xbow_t *) xbow_soft->base; @@ -1382,7 +1230,7 @@ } int -xbow_disable_llp_monitor(devfs_handle_t vhdl) +xbow_disable_llp_monitor(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); int port; @@ -1397,7 +1245,7 @@ } int -xbow_enable_llp_monitor(devfs_handle_t vhdl) +xbow_enable_llp_monitor(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); @@ -1407,7 +1255,7 @@ int -xbow_reset_link(devfs_handle_t xconn_vhdl) +xbow_reset_link(vertex_hdl_t xconn_vhdl) { xwidget_info_t widget_info; xwidgetnum_t port; @@ -1430,7 +1278,7 @@ xbow = XBOW_K1PTR; #else { - devfs_handle_t xbow_vhdl; + vertex_hdl_t xbow_vhdl; xbow_soft_t xbow_soft; hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl); @@ -1463,46 +1311,6 @@ return 0; } -/* - * Dump xbow registers. - * input parameter is either a pointer to - * the xbow chip or the vertex handle for - * an xbow vertex. - */ -void -idbg_xbowregs(int64_t regs) -{ - xbow_t *xbow; - int i; - xb_linkregs_t *link; - - xbow = (xbow_t *) regs; - -#ifdef LATER - qprintf("Printing xbow registers starting at 0x%x\n", xbow); - qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n", - xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper, - xbow->xb_wid_err_lower, xbow->xb_wid_control, - xbow->xb_wid_req_timeout); - qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n", - xbow->xb_wid_int_upper, xbow->xb_wid_int_lower, - xbow->xb_wid_err_cmdword, xbow->xb_wid_llp, - xbow->xb_wid_arb_reload); -#endif - - for (i = 8; i <= 0xf; i++) { - link = &xbow->xb_link(i); -#ifdef LATER - qprintf("Link %d registers\n", i); - qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n", - link->link_control, link->link_status, - link->link_arb_upper, link->link_arb_lower, - link->link_aux_status); -#endif - } -} - - #define XBOW_ARB_RELOAD_TICKS 25 /* granularity: 4 MB/s, max: 124 MB/s */ #define GRANULARITY ((100 * 1000000) / XBOW_ARB_RELOAD_TICKS) @@ -1562,7 +1370,7 @@ * If bandwidth allocation is successful, return success else return failure. */ int -xbow_prio_bw_alloc(devfs_handle_t vhdl, +xbow_prio_bw_alloc(vertex_hdl_t vhdl, xwidgetnum_t src_wid, xwidgetnum_t dest_wid, unsigned long long old_alloc_bw, diff -urN linux-2.4.21/arch/ia64/sn/io/sn2/xtalk.c linux-2.4.22/arch/ia64/sn/io/sn2/xtalk.c --- linux-2.4.21/arch/ia64/sn/io/sn2/xtalk.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/sn2/xtalk.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -37,8 +37,6 @@ char widget_info_fingerprint[] = "widget_info"; -cdl_p xtalk_registry = NULL; - #define DEV_FUNC(dev,func) hub_##func #define CAST_PIOMAP(x) ((hub_piomap_t)(x)) #define CAST_DMAMAP(x) ((hub_dmamap_t)(x)) @@ -47,71 +45,70 @@ /* ===================================================================== * Function Table of Contents */ -xtalk_piomap_t xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned); +xtalk_piomap_t xtalk_piomap_alloc(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned); void xtalk_piomap_free(xtalk_piomap_t); caddr_t xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t); void xtalk_piomap_done(xtalk_piomap_t); -caddr_t xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned); -caddr_t xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned); +caddr_t xtalk_piotrans_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, unsigned); +caddr_t xtalk_pio_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned); void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *); caddr_t xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); static caddr_t null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); -xtalk_dmamap_t xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +xtalk_dmamap_t xtalk_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned); void xtalk_dmamap_free(xtalk_dmamap_t); iopaddr_t xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t); alenlist_t xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned); void xtalk_dmamap_done(xtalk_dmamap_t); -iopaddr_t xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +iopaddr_t xtalk_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned); +alenlist_t xtalk_dmatrans_list(vertex_hdl_t, device_desc_t, alenlist_t, unsigned); void xtalk_dmamap_drain(xtalk_dmamap_t); -void xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t); -void xtalk_dmalist_drain(devfs_handle_t, alenlist_t); -xtalk_intr_t xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t); -xtalk_intr_t xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t); +void xtalk_dmaaddr_drain(vertex_hdl_t, iopaddr_t, size_t); +void xtalk_dmalist_drain(vertex_hdl_t, alenlist_t); +xtalk_intr_t xtalk_intr_alloc(vertex_hdl_t, device_desc_t, vertex_hdl_t); +xtalk_intr_t xtalk_intr_alloc_nothd(vertex_hdl_t, device_desc_t, vertex_hdl_t); void xtalk_intr_free(xtalk_intr_t); int xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *); void xtalk_intr_disconnect(xtalk_intr_t); -devfs_handle_t xtalk_intr_cpu_get(xtalk_intr_t); -int xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *); -int xtalk_error_devenable(devfs_handle_t, int, int); -void xtalk_provider_startup(devfs_handle_t); -void xtalk_provider_shutdown(devfs_handle_t); -devfs_handle_t xtalk_intr_dev_get(xtalk_intr_t); +vertex_hdl_t xtalk_intr_cpu_get(xtalk_intr_t); +int xtalk_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *); +int xtalk_error_devenable(vertex_hdl_t, int, int); +void xtalk_provider_startup(vertex_hdl_t); +void xtalk_provider_shutdown(vertex_hdl_t); +vertex_hdl_t xtalk_intr_dev_get(xtalk_intr_t); xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t); xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t); iopaddr_t xtalk_intr_addr_get(struct xtalk_intr_s *); void *xtalk_intr_sfarg_get(xtalk_intr_t); -devfs_handle_t xtalk_pio_dev_get(xtalk_piomap_t); +vertex_hdl_t xtalk_pio_dev_get(xtalk_piomap_t); xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t); iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t); ulong xtalk_pio_mapsz_get(xtalk_piomap_t); caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t); -devfs_handle_t xtalk_dma_dev_get(xtalk_dmamap_t); +vertex_hdl_t xtalk_dma_dev_get(xtalk_dmamap_t); xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t); -xwidget_info_t xwidget_info_chk(devfs_handle_t); -xwidget_info_t xwidget_info_get(devfs_handle_t); -void xwidget_info_set(devfs_handle_t, xwidget_info_t); -devfs_handle_t xwidget_info_dev_get(xwidget_info_t); +xwidget_info_t xwidget_info_chk(vertex_hdl_t); +xwidget_info_t xwidget_info_get(vertex_hdl_t); +void xwidget_info_set(vertex_hdl_t, xwidget_info_t); +vertex_hdl_t xwidget_info_dev_get(xwidget_info_t); xwidgetnum_t xwidget_info_id_get(xwidget_info_t); -devfs_handle_t xwidget_info_master_get(xwidget_info_t); +vertex_hdl_t xwidget_info_master_get(xwidget_info_t); xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t); xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t); xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t); char *xwidget_info_name_get(xwidget_info_t); -void xtalk_init(void); -void xtalk_provider_register(devfs_handle_t, xtalk_provider_t *); -void xtalk_provider_unregister(devfs_handle_t); -xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t); +void xtalk_provider_register(vertex_hdl_t, xtalk_provider_t *); +void xtalk_provider_unregister(vertex_hdl_t); +xtalk_provider_t *xtalk_provider_fns_get(vertex_hdl_t); int xwidget_driver_register(xwidget_part_num_t, xwidget_mfg_num_t, char *, unsigned); void xwidget_driver_unregister(char *); -int xwidget_register(xwidget_hwid_t, devfs_handle_t, - xwidgetnum_t, devfs_handle_t, - xwidgetnum_t, async_attach_t); -int xwidget_unregister(devfs_handle_t); -void xwidget_reset(devfs_handle_t); -char *xwidget_name_get(devfs_handle_t); +int xwidget_register(xwidget_hwid_t, vertex_hdl_t, + xwidgetnum_t, vertex_hdl_t, + xwidgetnum_t); +int xwidget_unregister(vertex_hdl_t); +void xwidget_reset(vertex_hdl_t); +char *xwidget_name_get(vertex_hdl_t); #if !defined(DEV_FUNC) /* * There is more than one possible provider @@ -126,7 +123,7 @@ #define CAST_INTR(x) ((xtalk_intr_t)(x)) static xtalk_provider_t * -xwidget_to_provider_fns(devfs_handle_t xconn) +xwidget_to_provider_fns(vertex_hdl_t xconn) { xwidget_info_t widget_info; xtalk_provider_t *provider_fns; @@ -159,7 +156,7 @@ */ xtalk_piomap_t -xtalk_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ +xtalk_piomap_alloc(vertex_hdl_t dev, /* set up mapping for this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ size_t byte_count, @@ -198,7 +195,7 @@ caddr_t -xtalk_piotrans_addr(devfs_handle_t dev, /* translate for this device */ +xtalk_piotrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t xtalk_addr, /* Crosstalk address */ size_t byte_count, /* map this many bytes */ @@ -209,7 +206,7 @@ } caddr_t -xtalk_pio_addr(devfs_handle_t dev, /* translate for this device */ +xtalk_pio_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t addr, /* starting address (or offset in window) */ size_t byte_count, /* map this many bytes */ @@ -326,7 +323,7 @@ */ xtalk_dmamap_t -xtalk_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ +xtalk_dmamap_alloc(vertex_hdl_t dev, /* set up mappings for this device */ device_desc_t dev_desc, /* device descriptor */ size_t byte_count_max, /* max size of a mapping */ unsigned flags) @@ -373,7 +370,7 @@ iopaddr_t -xtalk_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ +xtalk_dmatrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ paddr_t paddr, /* system physical address */ size_t byte_count, /* length */ @@ -385,7 +382,7 @@ alenlist_t -xtalk_dmatrans_list(devfs_handle_t dev, /* translate for this device */ +xtalk_dmatrans_list(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ alenlist_t palenlist, /* system address/length list */ unsigned flags) @@ -402,14 +399,14 @@ } void -xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) +xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size) { DEV_FUNC(dev, dmaaddr_drain) (dev, addr, size); } void -xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list) +xtalk_dmalist_drain(vertex_hdl_t dev, alenlist_t list) { DEV_FUNC(dev, dmalist_drain) (dev, list); @@ -426,9 +423,9 @@ * Return resource handle in intr_hdl. */ xtalk_intr_t -xtalk_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ +xtalk_intr_alloc(vertex_hdl_t dev, /* which Crosstalk device */ device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { /* owner of this interrupt */ return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc) (dev, dev_desc, owner_dev); @@ -440,9 +437,9 @@ * Return resource handle in intr_hdl. */ xtalk_intr_t -xtalk_intr_alloc_nothd(devfs_handle_t dev, /* which Crosstalk device */ +xtalk_intr_alloc_nothd(vertex_hdl_t dev, /* which Crosstalk device */ device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) /* owner of this interrupt */ + vertex_hdl_t owner_dev) /* owner of this interrupt */ { return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd) (dev, dev_desc, owner_dev); @@ -492,11 +489,10 @@ * Return a hwgraph vertex that represents the CPU currently * targeted by an interrupt. */ -devfs_handle_t +vertex_hdl_t xtalk_intr_cpu_get(xtalk_intr_t intr_hdl) { - return INTR_FUNC(intr_hdl, intr_cpu_get) - (CAST_INTR(intr_hdl)); + return (vertex_hdl_t)0; } @@ -526,7 +522,7 @@ */ int xtalk_error_handler( - devfs_handle_t xconn, + vertex_hdl_t xconn, int error_code, ioerror_mode_t mode, ioerror_t *ioerror) @@ -555,7 +551,7 @@ #if defined(SUPPORT_PRINTING_V_FORMAT) printk(KERN_WARNING "Xbow at %v encountered Fatal error", xconn); #else - printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", xconn); + printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", (void *)xconn); #endif ioerror_dump("xtalk", error_code, mode, ioerror); @@ -563,7 +559,7 @@ } int -xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) +xtalk_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code) { return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code); } @@ -577,7 +573,7 @@ * Startup a crosstalk provider */ void -xtalk_provider_startup(devfs_handle_t xtalk_provider) +xtalk_provider_startup(vertex_hdl_t xtalk_provider) { DEV_FUNC(xtalk_provider, provider_startup) (xtalk_provider); @@ -588,7 +584,7 @@ * Shutdown a crosstalk provider */ void -xtalk_provider_shutdown(devfs_handle_t xtalk_provider) +xtalk_provider_shutdown(vertex_hdl_t xtalk_provider) { DEV_FUNC(xtalk_provider, provider_shutdown) (xtalk_provider); @@ -598,22 +594,22 @@ * Enable a device on a xtalk widget */ void -xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum) +xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum) { - DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum); + return; } /* * Shutdown a device on a xtalk widget */ void -xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum) +xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum) { - DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum); + return; } int -xtalk_dma_enabled(devfs_handle_t xconn_vhdl) +xtalk_dma_enabled(vertex_hdl_t xconn_vhdl) { return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl); } @@ -623,7 +619,7 @@ */ /****** Generic crosstalk interrupt interfaces ******/ -devfs_handle_t +vertex_hdl_t xtalk_intr_dev_get(xtalk_intr_t xtalk_intr) { return (xtalk_intr->xi_dev); @@ -654,7 +650,7 @@ } /****** Generic crosstalk pio interfaces ******/ -devfs_handle_t +vertex_hdl_t xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap) { return (xtalk_piomap->xp_dev); @@ -686,7 +682,7 @@ /****** Generic crosstalk dma interfaces ******/ -devfs_handle_t +vertex_hdl_t xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap) { return (xtalk_dmamap->xd_dev); @@ -707,7 +703,7 @@ * if not, return NULL. */ xwidget_info_t -xwidget_info_chk(devfs_handle_t xwidget) +xwidget_info_chk(vertex_hdl_t xwidget) { arbitrary_info_t ainfo = 0; @@ -717,28 +713,18 @@ xwidget_info_t -xwidget_info_get(devfs_handle_t xwidget) +xwidget_info_get(vertex_hdl_t xwidget) { xwidget_info_t widget_info; widget_info = (xwidget_info_t) hwgraph_fastinfo_get(xwidget); -#ifdef LATER - if ((widget_info != NULL) && - (widget_info->w_fingerprint != widget_info_fingerprint)) -#ifdef SUPPORT_PRINTING_V_FORMAT - PRINT_PANIC("%v bad xwidget_info", xwidget); -#else - PRINT_PANIC("%x bad xwidget_info", xwidget); -#endif -#endif /* LATER */ - return (widget_info); } void -xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info) +xwidget_info_set(vertex_hdl_t xwidget, xwidget_info_t widget_info) { if (widget_info != NULL) widget_info->w_fingerprint = widget_info_fingerprint; @@ -753,11 +739,11 @@ (arbitrary_info_t) widget_info); } -devfs_handle_t +vertex_hdl_t xwidget_info_dev_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_dev_get: null xwidget_info"); return (xwidget_info->w_vertex); } @@ -765,16 +751,16 @@ xwidget_info_id_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_id_get: null xwidget_info"); return (xwidget_info->w_id); } -devfs_handle_t +vertex_hdl_t xwidget_info_master_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_master_get: null xwidget_info"); return (xwidget_info->w_master); } @@ -782,7 +768,7 @@ xwidget_info_masterid_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_masterid_get: null xwidget_info"); return (xwidget_info->w_masterid); } @@ -790,7 +776,7 @@ xwidget_info_part_num_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_part_num_get: null xwidget_info"); return (xwidget_info->w_hwid.part_num); } @@ -798,7 +784,7 @@ xwidget_info_mfg_num_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_mfg_num_get: null xwidget_info"); return (xwidget_info->w_hwid.mfg_num); } /* Extract the widget name from the widget information @@ -808,49 +794,16 @@ xwidget_info_name_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget info"); + panic("xwidget_info_name_get: null xwidget_info"); return(xwidget_info->w_name); } /****** Generic crosstalk initialization interfaces ******/ /* - * One-time initialization needed for systems that support crosstalk. - */ -void -xtalk_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("xtalk_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (xtalk_registry == NULL) { - cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr"); - if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(xtalk_registry != NULL); -} - -/* * Associate a set of xtalk_provider functions with a vertex. */ void -xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns) +xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns) { hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns); } @@ -859,7 +812,7 @@ * Disassociate a set of xtalk_provider functions with a vertex. */ void -xtalk_provider_unregister(devfs_handle_t provider) +xtalk_provider_unregister(vertex_hdl_t provider) { hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL); } @@ -869,50 +822,19 @@ * provider. */ xtalk_provider_t * -xtalk_provider_fns_get(devfs_handle_t provider) +xtalk_provider_fns_get(vertex_hdl_t provider) { return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider)); } /* - * Announce a driver for a particular crosstalk part. - * Returns 0 on success or -1 on failure. Failure occurs if the - * specified hardware already has a driver. - */ -/*ARGSUSED4 */ -int -xwidget_driver_register(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - char *driver_prefix, - unsigned flags) -{ - /* a driver's init routine could call - * xwidget_driver_register before the - * system calls xtalk_init; so, we - * make the call here. - */ - if (xtalk_registry == NULL) - xtalk_init(); - - return cdl_add_driver(xtalk_registry, - part_num, mfg_num, - driver_prefix, flags, NULL); -} - -/* * Inform xtalk infrastructure that a driver is no longer available for * handling any widgets. */ void xwidget_driver_unregister(char *driver_prefix) { - /* before a driver calls unregister, - * it must have called registger; so we - * can assume we have a registry here. - */ - ASSERT(xtalk_registry != NULL); - - cdl_del_driver(xtalk_registry, driver_prefix, NULL); + return; } /* @@ -923,9 +845,6 @@ xtalk_iterate(char *driver_prefix, xtalk_iter_f *func) { - ASSERT(xtalk_registry != NULL); - - cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func); } /* @@ -939,11 +858,10 @@ */ int xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ - devfs_handle_t widget, /* widget to initialize */ + vertex_hdl_t widget, /* widget to initialize */ xwidgetnum_t id, /* widget's target id (0..f) */ - devfs_handle_t master, /* widget's master vertex */ - xwidgetnum_t targetid, /* master's target id (9/a) */ - async_attach_t aa) + vertex_hdl_t master, /* widget's master vertex */ + xwidgetnum_t targetid) /* master's target id (9/a) */ { xwidget_info_t widget_info; char *s,devnm[MAXDEVNAME]; @@ -972,21 +890,11 @@ device_master_set(widget, master); - /* All the driver init routines (including - * xtalk_init) are called before we get into - * attaching devices, so we can assume we - * have a registry here. - */ - ASSERT(xtalk_registry != NULL); - /* * Add pointer to async attach info -- tear down will be done when * the particular descendant is done with the info. */ - if (aa) - async_attach_add_info(widget, aa); - - return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, + return cdl_add_connpt(hwid->part_num, hwid->mfg_num, widget, 0); } @@ -995,7 +903,7 @@ * Unregister the xtalk device and detach all its hwgraph namespace. */ int -xwidget_unregister(devfs_handle_t widget) +xwidget_unregister(vertex_hdl_t widget) { xwidget_info_t widget_info; xwidget_hwid_t hwid; @@ -1011,9 +919,6 @@ hwid = &(widget_info->w_hwid); - cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, - widget, 0); - /* Clean out the xwidget information */ (void)kfree(widget_info->w_name); BZERO((void *)widget_info, sizeof(widget_info)); @@ -1023,7 +928,7 @@ } void -xwidget_error_register(devfs_handle_t xwidget, +xwidget_error_register(vertex_hdl_t xwidget, error_handler_f *efunc, error_handler_arg_t einfo) { @@ -1039,37 +944,23 @@ * Issue a link reset to a widget. */ void -xwidget_reset(devfs_handle_t xwidget) +xwidget_reset(vertex_hdl_t xwidget) { xswitch_reset_link(xwidget); - } void -xwidget_gfx_reset(devfs_handle_t xwidget) +xwidget_gfx_reset(vertex_hdl_t xwidget) { - xwidget_info_t info; - - xswitch_reset_link(xwidget); - info = xwidget_info_get(xwidget); -#ifdef LATER - ASSERT_ALWAYS(info != NULL); -#endif - - /* - * Enable this for other architectures once we add widget_reset to the - * xtalk provider interface. - */ - DEV_FUNC(xtalk_provider, widget_reset) - (xwidget_info_master_get(info), xwidget_info_id_get(info)); + return; } #define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */ /* Get the canonical hwgraph name of xtalk widget */ char * -xwidget_name_get(devfs_handle_t xwidget_vhdl) +xwidget_name_get(vertex_hdl_t xwidget_vhdl) { xwidget_info_t info; diff -urN linux-2.4.21/arch/ia64/sn/io/stubs.c linux-2.4.22/arch/ia64/sn/io/stubs.c --- linux-2.4.21/arch/ia64/sn/io/stubs.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/stubs.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,139 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/****** - ****** hack defines ...... - ******/ - -int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev; -int default_intr_pri; -int force_fire_and_forget = 1; -int ignore_conveyor_override = 0; - -devfs_handle_t dummy_vrtx; /* Needed for cpuid_to_vertex() in hack.h */ - - -/* ARGSUSED */ -void hub_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum) - {FIXME("hub_widgetdev_enable");} - -/* ARGSUSED */ -void hub_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum) - {FIXME("hub_widgetdev_shutdown");} - -/* ARGSUSED */ -void hub_widget_reset(devfs_handle_t hubv, xwidgetnum_t widget) - {FIXME("hub_widget_reset");} - -boolean_t -is_sys_critical_vertex(devfs_handle_t x) -{ - FIXME("is_sys_critical_vertex : returns 0"); - return(0); -} - -void * -snia_kmem_zone_alloc(register zone_t *zone, int flags) -{ - FIXME("snia_kmem_zone_alloc : return null"); - return((void *)0); -} - -void -snia_kmem_zone_free(register zone_t *zone, void *ptr) -{ - FIXME("snia_kmem_zone_free : no-op"); -} - -zone_t * -snia_kmem_zone_init(register int size, char *zone_name) -{ - FIXME("snia_kmem_zone_free : returns NULL"); - return((zone_t *)0); -} - -int -compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr) -{ - FIXME("compare_and_swap_ptr : NOT ATOMIC"); - if (*location == old_ptr) { - *location = new_ptr; - return(1); - } - else - return(0); -} - -/* For ml/SN/SN1/slots.c */ -/* ARGSUSED */ -slotid_t get_widget_slotnum(int xbow, int widget) - {FIXME("get_widget_slotnum"); return (unsigned char)NULL;} - -/* For router */ -int -router_init(cnodeid_t cnode,int writeid, void *npda_rip) - {FIXME("router_init"); return(0);} - -/* From io/ioerror_handling.c */ -error_return_code_t -sys_critical_graph_vertex_add(devfs_handle_t parent, devfs_handle_t child) - {FIXME("sys_critical_graph_vertex_add"); return(0);} - -/* From io/ioc3.c */ -devfs_handle_t -ioc3_console_vhdl_get(void) - {FIXME("ioc3_console_vhdl_get"); return( (devfs_handle_t)-1);} - -void -nic_vmc_check(devfs_handle_t vhdl, char *nicinfo) -{ - - FIXME("nic_vmc_check\n"); - -} - -char * -nic_vertex_info_get(devfs_handle_t v) -{ - FIXME("nic_vertex_info_get\n"); - return(NULL); -} - -int -vector_read_node(net_vec_t dest, nasid_t nasid, - int write_id, int address, - uint64_t *value) -{ - FIXME("vector_read_node\n"); - return(0); -} - -int -vector_write_node(net_vec_t dest, nasid_t nasid, - int write_id, int address, - uint64_t value) -{ - FIXME("vector_write_node\n"); - return(0); -} diff -urN linux-2.4.21/arch/ia64/sn/io/xbow.c linux-2.4.22/arch/ia64/sn/io/xbow.c --- linux-2.4.21/arch/ia64/sn/io/xbow.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/xbow.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1325 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define DEBUG 1 */ -/* #define XBOW_DEBUG 1 */ - - -/* - * Files needed to get the device driver entry points - */ - -#include -#include -#include -#include - -#include -#include - - -#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DEL(ptr) (kfree(ptr)) - -int xbow_devflag = D_MP; - -/* - * This file supports the Xbow chip. Main functions: initializtion, - * error handling, and GBR. - */ - -/* - * each vertex corresponding to an xbow chip - * has a "fastinfo" pointer pointing at one - * of these things. - */ -typedef struct xbow_soft_s *xbow_soft_t; - -struct xbow_soft_s { - devfs_handle_t conn; /* our connection point */ - devfs_handle_t vhdl; /* xbow's private vertex */ - devfs_handle_t busv; /* the xswitch vertex */ - xbow_t *base; /* PIO pointer to crossbow chip */ - char *name; /* hwgraph name */ - - xbow_perf_t xbow_perfcnt[XBOW_PERF_COUNTERS]; - xbow_perf_link_t xbow_perflink[MAX_XBOW_PORTS]; - xbow_link_status_t xbow_link_status[MAX_XBOW_PORTS]; - spinlock_t xbow_perf_lock; - int link_monitor; - widget_cfg_t *wpio[MAX_XBOW_PORTS]; /* cached PIO pointer */ - - /* Bandwidth allocation state. Bandwidth values are for the - * destination port since contention happens there. - * Implicit mapping from xbow ports (8..f) -> (0..7) array indices. - */ - spinlock_t xbow_bw_alloc_lock; /* bw allocation lock */ - unsigned long long bw_hiwm[MAX_XBOW_PORTS]; /* hiwater mark values */ - unsigned long long bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */ -}; - -#define xbow_soft_set(v,i) hwgraph_fastinfo_set((v), (arbitrary_info_t)(i)) -#define xbow_soft_get(v) ((xbow_soft_t)hwgraph_fastinfo_get((v))) - -/* - * Function Table of Contents - */ - -void xbow_mlreset(xbow_t *); -void xbow_init(void); -int xbow_attach(devfs_handle_t); - -int xbow_open(devfs_handle_t *, int, int, cred_t *); -int xbow_close(devfs_handle_t, int, int, cred_t *); - -int xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); -int xbow_unmap(devfs_handle_t, vhandl_t *); -int xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); - -int xbow_widget_present(xbow_t *, int); -static int xbow_link_alive(xbow_t *, int); -devfs_handle_t xbow_widget_lookup(devfs_handle_t, int); - -#ifdef LATER -static void xbow_setwidint(xtalk_intr_t); -static void xbow_errintr_handler(intr_arg_t); -#endif -void xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); - - - -void xbow_update_perf_counters(devfs_handle_t); -xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t); -int xbow_enable_perf_counter(devfs_handle_t, int, int, int); -xbow_link_status_t *xbow_get_llp_status(devfs_handle_t); -void xbow_update_llp_status(devfs_handle_t); - -int xbow_disable_llp_monitor(devfs_handle_t); -int xbow_enable_llp_monitor(devfs_handle_t); -int xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t, - unsigned long long, unsigned long long); - -xswitch_reset_link_f xbow_reset_link; - -void idbg_xbowregs(int64_t); - -xswitch_provider_t xbow_provider = -{ - xbow_reset_link, -}; - -/* - * xbow_mlreset: called at mlreset time if the - * platform specific code determines that there is - * a crossbow in a critical path that must be - * functional before the driver would normally get - * the device properly set up. - * - * what do we need to do, that the boot prom can - * not be counted on to have already done, that is - * generic across all platforms using crossbows? - */ -/*ARGSUSED */ -void -xbow_mlreset(xbow_t * xbow) -{ -} - -/* - * xbow_init: called with the rest of the device - * driver XXX_init routines. This platform *might* - * have a Crossbow chip, or even several, but it - * might have none. Register with the crosstalk - * generic provider so when we encounter the chip - * the right magic happens. - */ -void -xbow_init(void) -{ - -#if DEBUG && ATTACH_DEBUG - printf("xbow_init\n"); -#endif - - xwidget_driver_register(XXBOW_WIDGET_PART_NUM, - 0, /* XXBOW_WIDGET_MFGR_NUM, */ - "xbow_", - CDL_PRI_HI); /* attach before friends */ - - xwidget_driver_register(XBOW_WIDGET_PART_NUM, - XBOW_WIDGET_MFGR_NUM, - "xbow_", - CDL_PRI_HI); /* attach before friends */ -} - -#ifdef XBRIDGE_REGS_SIM -/* xbow_set_simulated_regs: sets xbow regs as needed - * for powering through the boot - */ -void -xbow_set_simulated_regs(xbow_t *xbow, int port) -{ - /* - * turn on link - */ - xbow->xb_link(port).link_status = (1<<31); - /* - * and give it a live widget too - */ - xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT; - /* - * zero the link control reg - */ - xbow->xb_link(port).link_control = 0x0; -} -#endif /* XBRIDGE_REGS_SIM */ - -/* - * xbow_attach: the crosstalk provider has - * determined that there is a crossbow widget - * present, and has handed us the connection - * point for that vertex. - * - * We not only add our own vertex, but add - * some "xtalk switch" data to the switch - * vertex (at the connect point's parent) if - * it does not have any. - */ - -/*ARGSUSED */ -int -xbow_attach(devfs_handle_t conn) -{ - /*REFERENCED */ - devfs_handle_t vhdl; - devfs_handle_t busv; - xbow_t *xbow; - xbow_soft_t soft; - int port; - xswitch_info_t info; -#ifdef LATER - xtalk_intr_t intr_hdl; - device_desc_t dev_desc; -#endif - char devnm[MAXDEVNAME], *s; - xbowreg_t id; - int rev; - int i; - int xbow_num; - -#if DEBUG && ATTACH_DEBUG -#if defined(SUPPORT_PRINTING_V_FORMAT - printk("%v: xbow_attach\n", conn); -#else - printk("0x%x: xbow_attach\n", conn); -#endif -#endif - - /* - * Get a PIO pointer to the base of the crossbow - * chip. - */ -#ifdef XBRIDGE_REGS_SIM - printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t)); - xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL); - /* - * turn on ports e and f like in a real live ibrick - */ - xbow_set_simulated_regs(xbow, 0xe); - xbow_set_simulated_regs(xbow, 0xf); -#else - xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0); -#endif /* XBRIDGE_REGS_SIM */ - - /* - * Locate the "switch" vertex: it is the parent - * of our connection point. - */ - busv = hwgraph_connectpt_get(conn); -#if DEBUG && ATTACH_DEBUG - printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow); -#endif - - ASSERT(busv != GRAPH_VERTEX_NONE); - - /* - * Create our private vertex, and connect our - * driver information to it. This makes it possible - * for diagnostic drivers to open the crossbow - * vertex for access to registers. - */ - - /* - * We need to teach xbow drivers to provide the right set of - * file ops. - */ - vhdl = NULL; - vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - /* &hcl_fops */ (void *)&vhdl, NULL); - if (!vhdl) { - printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n", - (void *)conn); - } - - /* - * Allocate the soft state structure and attach - * it to the xbow's vertex - */ - NEW(soft); - soft->conn = conn; - soft->vhdl = vhdl; - soft->busv = busv; - soft->base = xbow; - /* does the universe really need another macro? */ - /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */ - hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); - -#define XBOW_NUM_SUFFIX_FORMAT "[xbow# %d]" - - /* Add xbow number as a suffix to the hwgraph name of the xbow. - * This is helpful while looking at the error/warning messages. - */ - xbow_num = 0; - - /* - * get the name of this xbow vertex and keep the info. - * This is needed during errors and interupts, but as - * long as we have it, we can use it elsewhere. - */ - s = dev_to_name(vhdl, devnm, MAXDEVNAME); - soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, - GFP_KERNEL); - sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num); - -#ifdef XBRIDGE_REGS_SIM - /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined - * as 0xd000, so I'm using that for the partnum bitfield. - */ - printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n"); - id = 0x2d000049; -#else - id = xbow->xb_wid_id; -#endif /* XBRIDGE_REGS_SIM */ - rev = XWIDGET_PART_REV_NUM(id); - - /* - * Print the revision if DEBUG, or SHOW_REVS and kdebug, - * or the xbow is downrev. - * - * If xbow is downrev, make it a WARNING that the - * Crossbow is DOWNREV: these chips are not good - * to have around, and the operator should be told. - */ -#ifdef LATER -#if !DEBUG - if ( -#if SHOW_REVS - (kdebug) || -#endif /* SHOW_REVS */ - (rev < XBOW_REV_1_1)) -#endif /* !DEBUG */ - printk("%sCrossbow ASIC: rev %s (code=%d) at %s%s", - (rev < XBOW_REV_1_1) ? "DOWNREV " : "", - (rev == XBOW_REV_1_0) ? "1.0" : - (rev == XBOW_REV_1_1) ? "1.1" : - (rev == XBOW_REV_1_2) ? "1.2" : - (rev == XBOW_REV_1_3) ? "1.3" : - (rev == XBOW_REV_2_0) ? "2.0" : - (rev == XXBOW_PART_REV_1_0) ? "Xbridge 1.0" : - (rev == XXBOW_PART_REV_2_0) ? "Xbridge 2.0" : - "unknown", - rev, soft->name, - (rev < XBOW_REV_1_1) ? "" : "\n"); -#endif /* LATER */ - mutex_spinlock_init(&soft->xbow_perf_lock); - soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a; - soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b; - - /* Initialization for GBR bw allocation */ - mutex_spinlock_init(&soft->xbow_bw_alloc_lock); - -#define XBOW_8_BIT_PORT_BW_MAX (400 * 1000 * 1000) /* 400 MB/s */ -#define XBOW_16_BIT_PORT_BW_MAX (800 * 1000 * 1000) /* 800 MB/s */ - - /* Set bandwidth hiwatermark and current values */ - for (i = 0; i < MAX_XBOW_PORTS; i++) { - soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX; /* for now */ - soft->bw_cur_used[i] = 0; - } - - /* - * Enable xbow error interrupts - */ - xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE); - - /* - * take a census of the widgets present, - * leaving notes at the switch vertex. - */ - info = xswitch_info_new(busv); - - for (port = MAX_PORT_NUM - MAX_XBOW_PORTS; - port < MAX_PORT_NUM; ++port) { - if (!xbow_link_alive(xbow, port)) { -#if DEBUG && XBOW_DEBUG - printk(KERN_INFO "0x%p link %d is not alive\n", - busv, port); -#endif - continue; - } - if (!xbow_widget_present(xbow, port)) { -#if DEBUG && XBOW_DEBUG - printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port); -#endif - continue; - } -#if DEBUG && XBOW_DEBUG - printk(KERN_INFO "0x%p link %d has a widget\n", - busv, port); -#endif - - xswitch_info_link_is_ok(info, port); - /* - * Turn some error interrupts on - * and turn others off. The PROM has - * some things turned on we don't - * want to see (bandwidth allocation - * errors for instance); so if it - * is not listed here, it is not on. - */ - xbow->xb_link(port).link_control = - ( (xbow->xb_link(port).link_control - /* - * Turn off these bits; they are non-fatal, - * but we might want to save some statistics - * on the frequency of these errors. - * XXX FIXME XXX - */ - & ~XB_CTRL_RCV_CNT_OFLOW_IE - & ~XB_CTRL_XMT_CNT_OFLOW_IE - & ~XB_CTRL_BNDWDTH_ALLOC_IE - & ~XB_CTRL_RCV_IE) - /* - * These are the ones we want to turn on. - */ - | (XB_CTRL_ILLEGAL_DST_IE - | XB_CTRL_OALLOC_IBUF_IE - | XB_CTRL_XMT_MAX_RTRY_IE - | XB_CTRL_MAXREQ_TOUT_IE - | XB_CTRL_XMT_RTRY_IE - | XB_CTRL_SRC_TOUT_IE) ); - } - - xswitch_provider_register(busv, &xbow_provider); - - return 0; /* attach successful */ -} - -/*ARGSUSED */ -int -xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) -{ - return 0; - -} - -/*ARGSUSED */ -int -xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) -{ - return 0; -} - -/*ARGSUSED */ -int -xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) -{ - devfs_handle_t vhdl = dev_to_vhdl(dev); - xbow_soft_t soft = xbow_soft_get(vhdl); - int error; - - ASSERT(soft); - len = ctob(btoc(len)); - /* XXX- this ignores the offset!!! */ - error = v_mapphys(vt, (void *) soft->base, len); - return error; -} - -/*ARGSUSED */ -int -xbow_unmap(devfs_handle_t dev, vhandl_t *vt) -{ - return 0; -} - -/* This contains special-case code for grio. There are plans to make - * this general sometime in the future, but till then this should - * be good enough. - */ -xwidgetnum_t -xbow_widget_num_get(devfs_handle_t dev) -{ - devfs_handle_t tdev; - char devname[MAXDEVNAME]; - xwidget_info_t xwidget_info; - int i; - - vertex_to_name(dev, devname, MAXDEVNAME); - - /* If this is a pci controller vertex, traverse up using - * the ".." links to get to the widget. - */ - if (strstr(devname, EDGE_LBL_PCI) && - strstr(devname, EDGE_LBL_CONTROLLER)) { - tdev = dev; - for (i=0; i< 2; i++) { - if (hwgraph_edge_get(tdev, - HWGRAPH_EDGELBL_DOTDOT, &tdev) != - GRAPH_SUCCESS) - return XWIDGET_NONE; - } - - if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) { - return (xwidget_info_id_get(xwidget_info)); - } else { - return XWIDGET_NONE; - } - } - - return XWIDGET_NONE; -} - -int -xbow_ioctl(devfs_handle_t dev, - int cmd, - void *arg, - int flag, - struct cred *cr, - int *rvalp) -{ - devfs_handle_t vhdl; - int error = 0; - -#if defined (DEBUG) - int rc; - devfs_handle_t conn; - struct xwidget_info_s *xwidget_info; - xbow_soft_t xbow_soft; -#endif - *rvalp = 0; - - vhdl = dev_to_vhdl(dev); -#if defined (DEBUG) - xbow_soft = xbow_soft_get(vhdl); - conn = xbow_soft->conn; - - xwidget_info = xwidget_info_get(conn); - ASSERT_ALWAYS(xwidget_info != NULL); - - rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid); - ASSERT_ALWAYS(rc != 0); -#endif - switch (cmd) { -#ifdef LATER - case XBOWIOC_PERF_ENABLE: - case XBOWIOC_PERF_DISABLE: - { - struct xbow_perfarg_t xbow_perf_en; - - if (!_CAP_CRABLE(cr, CAP_DEVICE_MGT)) { - error = EPERM; - break; - } - if ((flag & FWRITE) == 0) { - error = EBADF; - break; - } - if (COPYIN(arg, &xbow_perf_en, sizeof(xbow_perf_en))) { - error = EFAULT; - break; - } - if (error = xbow_enable_perf_counter(vhdl, - xbow_perf_en.link, - (cmd == XBOWIOC_PERF_DISABLE) ? 0 : xbow_perf_en.mode, - xbow_perf_en.counter)) { - error = EINVAL; - break; - } - break; - } -#endif - -#ifdef LATER - case XBOWIOC_PERF_GET: - { - xbow_perf_link_t *xbow_perf_cnt; - - if ((flag & FREAD) == 0) { - error = EBADF; - break; - } - xbow_perf_cnt = xbow_get_perf_counters(vhdl); - ASSERT_ALWAYS(xbow_perf_cnt != NULL); - - if (COPYOUT((void *) xbow_perf_cnt, (void *) arg, - MAX_XBOW_PORTS * sizeof(xbow_perf_link_t))) { - error = EFAULT; - break; - } - break; - } -#endif - - case XBOWIOC_LLP_ERROR_ENABLE: - if ((error = xbow_enable_llp_monitor(vhdl)) != 0) - error = EINVAL; - - break; - - case XBOWIOC_LLP_ERROR_DISABLE: - - if ((error = xbow_disable_llp_monitor(vhdl)) != 0) - error = EINVAL; - - break; - -#ifdef LATER - case XBOWIOC_LLP_ERROR_GET: - { - xbow_link_status_t *xbow_llp_status; - - if ((flag & FREAD) == 0) { - error = EBADF; - break; - } - xbow_llp_status = xbow_get_llp_status(vhdl); - ASSERT_ALWAYS(xbow_llp_status != NULL); - - if (COPYOUT((void *) xbow_llp_status, (void *) arg, - MAX_XBOW_PORTS * sizeof(xbow_link_status_t))) { - error = EFAULT; - break; - } - break; - } -#endif - -#ifdef LATER - case GIOCSETBW: - { - grio_ioctl_info_t info; - xwidgetnum_t src_widgetnum, dest_widgetnum; - - if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { - error = EFAULT; - break; - } -#ifdef GRIO_DEBUG - printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n", - info.prev_vhdl, info.next_vhdl, info.reqbw); -#endif /* GRIO_DEBUG */ - - src_widgetnum = xbow_widget_num_get(info.prev_vhdl); - dest_widgetnum = xbow_widget_num_get(info.next_vhdl); - - /* Bandwidth allocation is bi-directional. Since bandwidth - * reservations have already been done at an earlier stage, - * we cannot fail here for lack of bandwidth. - */ - xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum, - 0, info.reqbw); - xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum, - 0, info.reqbw); - - break; - } - - case GIOCRELEASEBW: - { - grio_ioctl_info_t info; - xwidgetnum_t src_widgetnum, dest_widgetnum; - - if (!cap_able(CAP_DEVICE_MGT)) { - error = EPERM; - break; - } - - if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { - error = EFAULT; - break; - } -#ifdef GRIO_DEBUG - printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n", - info.prev_vhdl, info.next_vhdl, info.reqbw); -#endif /* GRIO_DEBUG */ - - src_widgetnum = xbow_widget_num_get(info.prev_vhdl); - dest_widgetnum = xbow_widget_num_get(info.next_vhdl); - - /* Bandwidth reservation is bi-directional. Hence, remove - * bandwidth reservations for both directions. - */ - xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum, - info.reqbw, (-1 * info.reqbw)); - xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum, - info.reqbw, (-1 * info.reqbw)); - - break; - } -#endif - - default: - break; - - } - return error; -} - -/* - * xbow_widget_present: See if a device is present - * on the specified port of this crossbow. - */ -int -xbow_widget_present(xbow_t * xbow, int port) -{ - if ( IS_RUNNING_ON_SIMULATOR() ) { - if ( (port == 14) || (port == 15) ) { - return 1; - } - else { - return 0; - } - } - else { - return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT; - } -} - -static int -xbow_link_alive(xbow_t * xbow, int port) -{ - xbwX_stat_t xbow_linkstat; - - xbow_linkstat.linkstatus = xbow->xb_link(port).link_status; - return (xbow_linkstat.link_alive); -} - -/* - * xbow_widget_lookup - * Lookup the edges connected to the xbow specified, and - * retrieve the handle corresponding to the widgetnum - * specified. - * If not found, return 0. - */ -devfs_handle_t -xbow_widget_lookup(devfs_handle_t vhdl, - int widgetnum) -{ - xswitch_info_t xswitch_info; - devfs_handle_t conn; - - xswitch_info = xswitch_info_get(vhdl); - conn = xswitch_info_vhdl_get(xswitch_info, widgetnum); - return conn; -} - -/* - * xbow_setwidint: called when xtalk - * is establishing or migrating our - * interrupt service. - */ -#ifdef LATER -static void -xbow_setwidint(xtalk_intr_t intr) -{ - xwidgetnum_t targ = xtalk_intr_target_get(intr); - iopaddr_t addr = xtalk_intr_addr_get(intr); - xtalk_intr_vector_t vect = xtalk_intr_vector_get(intr); - xbow_t *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr); - - xbow_intr_preset((void *) xbow, 0, targ, addr, vect); -} -#endif /* LATER */ - -/* - * xbow_intr_preset: called during mlreset time - * if the platform specific code needs to route - * an xbow interrupt before the xtalk infrastructure - * is available for use. - * - * Also called from xbow_setwidint, so we don't - * replicate the guts of the routine. - * - * XXX- probably should be renamed xbow_wid_intr_set or - * something to reduce confusion. - */ -/*ARGSUSED3 */ -void -xbow_intr_preset(void *which_widget, - int which_widget_intr, - xwidgetnum_t targ, - iopaddr_t addr, - xtalk_intr_vector_t vect) -{ - xbow_t *xbow = (xbow_t *) which_widget; - - xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) | - (0x000F0000 & (targ << 16)) | - XTALK_ADDR_TO_UPPER(addr)); - xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); -} - -#define XEM_ADD_STR(s) printk("%s", (s)) -#define XEM_ADD_NVAR(n,v) printk("\t%20s: 0x%x\n", (n), (v)) -#define XEM_ADD_VAR(v) XEM_ADD_NVAR(#v,(v)) -#define XEM_ADD_IOEF(n) if (IOERROR_FIELDVALID(ioe,n)) \ - XEM_ADD_NVAR("ioe." #n, \ - IOERROR_GETVALUE(ioe,n)) - -#ifdef LATER -static void -xem_add_ioe(ioerror_t *ioe) -{ - XEM_ADD_IOEF(errortype); - XEM_ADD_IOEF(widgetnum); - XEM_ADD_IOEF(widgetdev); - XEM_ADD_IOEF(srccpu); - XEM_ADD_IOEF(srcnode); - XEM_ADD_IOEF(errnode); - XEM_ADD_IOEF(sysioaddr); - XEM_ADD_IOEF(xtalkaddr); - XEM_ADD_IOEF(busspace); - XEM_ADD_IOEF(busaddr); - XEM_ADD_IOEF(vaddr); - XEM_ADD_IOEF(memaddr); - XEM_ADD_IOEF(epc); - XEM_ADD_IOEF(ef); -} - -#define XEM_ADD_IOE() (xem_add_ioe(ioe)) -#endif /* LATER */ - -int xbow_xmit_retry_errors = 0; - -int -xbow_xmit_retry_error(xbow_soft_t soft, - int port) -{ - xswitch_info_t info; - devfs_handle_t vhdl; - widget_cfg_t *wid; - widgetreg_t id; - int part; - int mfgr; - - wid = soft->wpio[port - BASE_XBOW_PORT]; - if (wid == NULL) { - /* If we can't track down a PIO - * pointer to our widget yet, - * leave our caller knowing that - * we are interested in this - * interrupt if it occurs in - * the future. - */ - info = xswitch_info_get(soft->busv); - if (!info) - return 1; - vhdl = xswitch_info_vhdl_get(info, port); - if (vhdl == GRAPH_VERTEX_NONE) - return 1; - wid = (widget_cfg_t *) xtalk_piotrans_addr - (vhdl, 0, 0, sizeof *wid, 0); - if (!wid) - return 1; - soft->wpio[port - BASE_XBOW_PORT] = wid; - } - id = wid->w_id; - part = XWIDGET_PART_NUM(id); - mfgr = XWIDGET_MFG_NUM(id); - - /* If this thing is not a Bridge, - * do not activate the WAR, and - * tell our caller we do not need - * to be called again. - */ - if ((part != BRIDGE_WIDGET_PART_NUM) || - (mfgr != BRIDGE_WIDGET_MFGR_NUM)) { - /* FIXME: add Xbridge to the WAR. - * Shouldn't hurt anything. Later need to - * check if we can remove this. - */ - if ((part != XBRIDGE_WIDGET_PART_NUM) || - (mfgr != XBRIDGE_WIDGET_MFGR_NUM)) - return 0; - } - - /* count how many times we - * have picked up after - * LLP Transmit problems. - */ - xbow_xmit_retry_errors++; - - /* rewrite the control register - * to fix things up. - */ - wid->w_control = wid->w_control; - wid->w_control; - - return 1; -} - -void -xbow_update_perf_counters(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; - xbow_perf_link_t *xbow_plink = xbow_soft->xbow_perflink; - xbow_perfcount_t perf_reg; - unsigned long s; - int link, i; - - for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) { - if (xbow_perf->xp_mode == XBOW_MONITOR_NONE) - continue; - - s = mutex_spinlock(&xbow_soft->xbow_perf_lock); - - perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg; - - link = perf_reg.xb_perf.link_select; - - (xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] += - ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK); - xbow_perf->xp_current = perf_reg.xb_perf.count; - - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - } - /* Do port /mode multiplexing here */ - -#ifdef LATER - (void) timeout(xbow_update_perf_counters, - (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT); -#endif - -} - -xbow_perf_link_t * -xbow_get_perf_counters(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_perf_link_t *xbow_perf_link = xbow_soft->xbow_perflink; - - return xbow_perf_link; -} - -int -xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; - xbow_linkctrl_t xbow_link_ctrl; - xbow_t *xbow = xbow_soft->base; - xbow_perfcount_t perf_reg; - unsigned long s; - int i; - - link -= BASE_XBOW_PORT; - if ((link < 0) || (link >= MAX_XBOW_PORTS)) - return -1; - - if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK)) - return -1; - - if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS)) - return -1; - - s = mutex_spinlock(&xbow_soft->xbow_perf_lock); - - if ((xbow_perf + counter)->xp_mode && mode) { - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - return -1; - } - for (i = 0; i < XBOW_PERF_COUNTERS; i++) { - if (i == counter) - continue; - if (((xbow_perf + i)->xp_link == link) && - ((xbow_perf + i)->xp_mode)) { - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - return -1; - } - } - xbow_perf += counter; - - xbow_perf->xp_curlink = xbow_perf->xp_link = link; - xbow_perf->xp_curmode = xbow_perf->xp_mode = mode; - - xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control; - xbow_link_ctrl.xb_linkcontrol.perf_mode = mode; - xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword; - - perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg; - perf_reg.xb_perf.link_select = link; - *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val; - xbow_perf->xp_current = perf_reg.xb_perf.count; - -#ifdef LATER - (void) timeout(xbow_update_perf_counters, - (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT); -#endif - - mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); - - return 0; -} - -xbow_link_status_t * -xbow_get_llp_status(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; - - return xbow_llp_status; -} - -void -xbow_update_llp_status(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; - xbow_t *xbow; - xbwX_stat_t lnk_sts; - xbow_aux_link_status_t aux_sts; - int link; - devfs_handle_t xwidget_vhdl; - char *xwidget_name; - - xbow = (xbow_t *) xbow_soft->base; - for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) { - /* Get the widget name corresponding the current link. - * Note : 0 <= link < MAX_XBOW_PORTS(8). - * BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10) - */ - xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT); - xwidget_name = xwidget_name_get(xwidget_vhdl); - aux_sts.aux_linkstatus - = xbow->xb_link_raw[link].link_aux_status; - lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr; - - if (lnk_sts.link_alive == 0) - continue; - - xbow_llp_status->rx_err_count += - aux_sts.xb_aux_linkstatus.rx_err_cnt; - - xbow_llp_status->tx_retry_count += - aux_sts.xb_aux_linkstatus.tx_retry_cnt; - - if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) { -#ifdef LATER - printk(KERN_WARNING "link %d[%s]: bad status 0x%x\n", - link, xwidget_name, lnk_sts.linkstatus); -#endif - } - } -#ifdef LATER - if (xbow_soft->link_monitor) - (void) timeout(xbow_update_llp_status, - (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT); -#endif -} - -int -xbow_disable_llp_monitor(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - int port; - - for (port = 0; port < MAX_XBOW_PORTS; port++) { - xbow_soft->xbow_link_status[port].rx_err_count = 0; - xbow_soft->xbow_link_status[port].tx_retry_count = 0; - } - - xbow_soft->link_monitor = 0; - return 0; -} - -int -xbow_enable_llp_monitor(devfs_handle_t vhdl) -{ - xbow_soft_t xbow_soft = xbow_soft_get(vhdl); - -#ifdef LATER - (void) timeout(xbow_update_llp_status, - (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT); -#endif - xbow_soft->link_monitor = 1; - return 0; -} - - -int -xbow_reset_link(devfs_handle_t xconn_vhdl) -{ - xwidget_info_t widget_info; - xwidgetnum_t port; - xbow_t *xbow; - xbowreg_t ctrl; - xbwX_stat_t stat; - unsigned itick; - unsigned dtick; - static int ticks_per_ms = 0; - - if (!ticks_per_ms) { - itick = get_timestamp(); - us_delay(1000); - ticks_per_ms = get_timestamp() - itick; - } - widget_info = xwidget_info_get(xconn_vhdl); - port = xwidget_info_id_get(widget_info); - -#ifdef XBOW_K1PTR /* defined if we only have one xbow ... */ - xbow = XBOW_K1PTR; -#else - { - devfs_handle_t xbow_vhdl; - xbow_soft_t xbow_soft; - - hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl); - xbow_soft = xbow_soft_get(xbow_vhdl); - xbow = xbow_soft->base; - } -#endif - - /* - * This requires three PIOs (reset the link, check for the - * reset, restore the control register for the link) plus - * 10us to wait for the reset. We allow up to 1ms for the - * widget to come out of reset before giving up and - * returning a failure. - */ - ctrl = xbow->xb_link(port).link_control; - xbow->xb_link(port).link_reset = 0; - itick = get_timestamp(); - while (1) { - stat.linkstatus = xbow->xb_link(port).link_status; - if (stat.link_alive) - break; - dtick = get_timestamp() - itick; - if (dtick > ticks_per_ms) { - return -1; /* never came out of reset */ - } - DELAY(2); /* don't beat on link_status */ - } - xbow->xb_link(port).link_control = ctrl; - return 0; -} - -/* - * Dump xbow registers. - * input parameter is either a pointer to - * the xbow chip or the vertex handle for - * an xbow vertex. - */ -void -idbg_xbowregs(int64_t regs) -{ - xbow_t *xbow; - int i; - xb_linkregs_t *link; - -#ifdef LATER - if (dev_is_vertex((devfs_handle_t) regs)) { - devfs_handle_t vhdl = (devfs_handle_t) regs; - xbow_soft_t soft = xbow_soft_get(vhdl); - - xbow = soft->base; - } else -#endif - { - xbow = (xbow_t *) regs; - } - -#ifdef LATER - qprintf("Printing xbow registers starting at 0x%x\n", xbow); - qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n", - xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper, - xbow->xb_wid_err_lower, xbow->xb_wid_control, - xbow->xb_wid_req_timeout); - qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n", - xbow->xb_wid_int_upper, xbow->xb_wid_int_lower, - xbow->xb_wid_err_cmdword, xbow->xb_wid_llp, - xbow->xb_wid_arb_reload); -#endif - - for (i = 8; i <= 0xf; i++) { - link = &xbow->xb_link(i); -#ifdef LATER - qprintf("Link %d registers\n", i); - qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n", - link->link_control, link->link_status, - link->link_arb_upper, link->link_arb_lower, - link->link_aux_status); -#endif - } -} - - -#define XBOW_ARB_RELOAD_TICKS 25 - /* granularity: 4 MB/s, max: 124 MB/s */ -#define GRANULARITY ((100 * 1000000) / XBOW_ARB_RELOAD_TICKS) - -#define XBOW_BYTES_TO_GBR(BYTES_per_s) (int) (BYTES_per_s / GRANULARITY) - -#define XBOW_GBR_TO_BYTES(cnt) (bandwidth_t) ((cnt) * GRANULARITY) - -#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec) \ - ((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr) - -#define XBOW_ARB_GBR_MAX 31 - -#define ABS(x) ((x > 0) ? (x) : (-1 * x)) - /* absolute value */ - -int -xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec) -{ - int gbr_granted; - int new_total_gbr; - int change_gbr; - bandwidth_t new_total_bw; - -#ifdef GRIO_DEBUG - printf("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n", - old_bytes_per_sec, bytes_per_sec); -#endif /* GRIO_DEBUG */ - - gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)), - old_bytes_per_sec); - new_total_bw = old_bytes_per_sec + bytes_per_sec; - new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)), - new_total_bw); - - change_gbr = new_total_gbr - gbr_granted; - -#ifdef GRIO_DEBUG - printf("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n", - gbr_granted, new_total_gbr, change_gbr); -#endif /* GRIO_DEBUG */ - - return (change_gbr); -} - -/* Conversion from GBR to bytes */ -bandwidth_t -xbow_gbr_to_bytes(int gbr) -{ - return (XBOW_GBR_TO_BYTES(gbr)); -} - -/* Given the vhdl for the desired xbow, the src and dest. widget ids - * and the req_bw value, this xbow driver entry point accesses the - * xbow registers and allocates the desired bandwidth if available. - * - * If bandwidth allocation is successful, return success else return failure. - */ -int -xbow_prio_bw_alloc(devfs_handle_t vhdl, - xwidgetnum_t src_wid, - xwidgetnum_t dest_wid, - unsigned long long old_alloc_bw, - unsigned long long req_bw) -{ - xbow_soft_t soft = xbow_soft_get(vhdl); - volatile xbowreg_t *xreg; - xbowreg_t mask; - unsigned long s; - int error = 0; - bandwidth_t old_bw_BYTES, req_bw_BYTES; - xbowreg_t old_xreg; - int old_bw_GBR, req_bw_GBR, new_bw_GBR; - -#ifdef GRIO_DEBUG - printf("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n", - (int) vhdl, (int) src_wid, (int) dest_wid, req_bw); -#endif - - ASSERT(XBOW_WIDGET_IS_VALID(src_wid)); - ASSERT(XBOW_WIDGET_IS_VALID(dest_wid)); - - s = mutex_spinlock(&soft->xbow_bw_alloc_lock); - - /* Get pointer to the correct register */ - xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid); - - /* Get mask for GBR count value */ - mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid); - - req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw); - req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR))) - : xbow_gbr_to_bytes(req_bw_GBR); - -#ifdef GRIO_DEBUG - printf("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n", - req_bw, req_bw_BYTES, req_bw_GBR); -#endif /* GRIO_DEBUG */ - - old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS]; - old_xreg = *xreg; - old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid)); - -#ifdef GRIO_DEBUG - ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR); - - printf("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR); - - printf("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n", - req_bw_BYTES, old_bw_BYTES, - soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]); - -#endif /* GRIO_DEBUG */ - - /* Accept the request only if we don't exceed the destination - * port HIWATER_MARK *AND* the max. link GBR arbitration count - */ - if (((old_bw_BYTES + req_bw_BYTES) <= - soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) && - (req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) { - - new_bw_GBR = (old_bw_GBR + req_bw_GBR); - - /* Set this in the xbow link register */ - *xreg = (old_xreg & ~mask) | \ - (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask); - - soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] = - xbow_gbr_to_bytes(new_bw_GBR); - } else { - error = 1; - } - - mutex_spinunlock(&soft->xbow_bw_alloc_lock, s); - - return (error); -} diff -urN linux-2.4.21/arch/ia64/sn/io/xswitch.c linux-2.4.22/arch/ia64/sn/io/xswitch.c --- linux-2.4.21/arch/ia64/sn/io/xswitch.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/xswitch.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -23,8 +23,6 @@ #define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) #define DEL(ptr) (kfree(ptr)) -int xswitch_devflag = D_MP; - /* * This file provides generic support for Crosstalk * Switches, in a way that insulates crosstalk providers @@ -45,9 +43,9 @@ #define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func static xswitch_provider_t * -xwidget_to_provider_fns(devfs_handle_t xconn) +xwidget_to_provider_fns(vertex_hdl_t xconn) { - devfs_handle_t busv; + vertex_hdl_t busv; xswitch_info_t xswitch_info; xswitch_provider_t provider_fns; @@ -75,27 +73,18 @@ struct xswitch_info_s { char *fingerprint; unsigned census; - devfs_handle_t vhdl[XSWITCH_CENSUS_PORTS]; - devfs_handle_t master_vhdl[XSWITCH_CENSUS_PORTS]; + vertex_hdl_t vhdl[XSWITCH_CENSUS_PORTS]; + vertex_hdl_t master_vhdl[XSWITCH_CENSUS_PORTS]; xswitch_provider_t *xswitch_fns; }; xswitch_info_t -xswitch_info_get(devfs_handle_t xwidget) +xswitch_info_get(vertex_hdl_t xwidget) { xswitch_info_t xswitch_info; xswitch_info = (xswitch_info_t) hwgraph_fastinfo_get(xwidget); -#ifdef LATER - if ((xswitch_info != NULL) && - (xswitch_info->fingerprint != xswitch_info_fingerprint)) -#ifdef SUPPORT_PRINTING_V_FORMAT - PRINT_PANIC("%v xswitch_info_get bad fingerprint", xwidget); -#else - PRINT_PANIC("%x xswitch_info_get bad fingerprint", xwidget); -#endif -#endif /* LATER */ return (xswitch_info); } @@ -103,7 +92,7 @@ void xswitch_info_vhdl_set(xswitch_info_t xswitch_info, xwidgetnum_t port, - devfs_handle_t xwidget) + vertex_hdl_t xwidget) { #if XSWITCH_CENSUS_PORT_MIN if (port < XSWITCH_CENSUS_PORT_MIN) @@ -115,15 +104,10 @@ xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN] = xwidget; } -devfs_handle_t +vertex_hdl_t xswitch_info_vhdl_get(xswitch_info_t xswitch_info, xwidgetnum_t port) { -#ifdef LATER - if (xswitch_info == NULL) - PRINT_PANIC("xswitch_info_vhdl_get: null xswitch_info"); -#endif - #if XSWITCH_CENSUS_PORT_MIN if (port < XSWITCH_CENSUS_PORT_MIN) return GRAPH_VERTEX_NONE; @@ -142,7 +126,7 @@ void xswitch_info_master_assignment_set(xswitch_info_t xswitch_info, xwidgetnum_t port, - devfs_handle_t master_vhdl) + vertex_hdl_t master_vhdl) { #if XSWITCH_CENSUS_PORT_MIN if (port < XSWITCH_CENSUS_PORT_MIN) @@ -154,7 +138,7 @@ xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN] = master_vhdl; } -devfs_handle_t +vertex_hdl_t xswitch_info_master_assignment_get(xswitch_info_t xswitch_info, xwidgetnum_t port) { @@ -169,14 +153,14 @@ } void -xswitch_info_set(devfs_handle_t xwidget, xswitch_info_t xswitch_info) +xswitch_info_set(vertex_hdl_t xwidget, xswitch_info_t xswitch_info) { xswitch_info->fingerprint = xswitch_info_fingerprint; hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info); } xswitch_info_t -xswitch_info_new(devfs_handle_t xwidget) +xswitch_info_new(vertex_hdl_t xwidget) { xswitch_info_t xswitch_info; @@ -202,7 +186,7 @@ } void -xswitch_provider_register(devfs_handle_t busv, +xswitch_provider_register(vertex_hdl_t busv, xswitch_provider_t * xswitch_fns) { xswitch_info_t xswitch_info = xswitch_info_get(busv); @@ -232,35 +216,8 @@ } int -xswitch_reset_link(devfs_handle_t xconn_vhdl) +xswitch_reset_link(vertex_hdl_t xconn_vhdl) { return DEV_FUNC(xconn_vhdl, reset_link) (xconn_vhdl); } - -/* Given a vertex handle to the xswitch get its logical - * id. - */ -int -xswitch_id_get(devfs_handle_t xconn_vhdl) -{ - arbitrary_info_t xbow_num; - graph_error_t rv; - - rv = hwgraph_info_get_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,&xbow_num); - ASSERT(rv == GRAPH_SUCCESS); - return(xbow_num); -} - -/* Given a vertex handle to the xswitch set its logical - * id. - */ -void -xswitch_id_set(devfs_handle_t xconn_vhdl,int xbow_num) -{ - graph_error_t rv; - - rv = hwgraph_info_add_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID, - (arbitrary_info_t)xbow_num); - ASSERT(rv == GRAPH_SUCCESS); -} diff -urN linux-2.4.21/arch/ia64/sn/io/xtalk.c linux-2.4.22/arch/ia64/sn/io/xtalk.c --- linux-2.4.21/arch/ia64/sn/io/xtalk.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/io/xtalk.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1024 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Implement crosstalk provider operations. The xtalk* layer provides a - * platform-independent interface for crosstalk devices. This layer - * switches among the possible implementations of a crosstalk adapter. - * - * On platforms with only one possible xtalk provider, macros can be - * set up at the top that cause the table lookups and indirections to - * completely disappear. - */ - -#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DEL(ptr) (kfree(ptr)) - -char widget_info_fingerprint[] = "widget_info"; - -cdl_p xtalk_registry = NULL; - -#define DEV_FUNC(dev,func) hub_##func -#define CAST_PIOMAP(x) ((hub_piomap_t)(x)) -#define CAST_DMAMAP(x) ((hub_dmamap_t)(x)) -#define CAST_INTR(x) ((hub_intr_t)(x)) - -/* ===================================================================== - * Function Table of Contents - */ -xtalk_piomap_t xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned); -void xtalk_piomap_free(xtalk_piomap_t); -caddr_t xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t); -void xtalk_piomap_done(xtalk_piomap_t); -caddr_t xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned); -caddr_t xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned); -void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *); -caddr_t xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); -static caddr_t null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); -xtalk_dmamap_t xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); -void xtalk_dmamap_free(xtalk_dmamap_t); -iopaddr_t xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t); -alenlist_t xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned); -void xtalk_dmamap_done(xtalk_dmamap_t); -iopaddr_t xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); -void xtalk_dmamap_drain(xtalk_dmamap_t); -void xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t); -void xtalk_dmalist_drain(devfs_handle_t, alenlist_t); -xtalk_intr_t xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t); -xtalk_intr_t xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t); -void xtalk_intr_free(xtalk_intr_t); -int xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *); -void xtalk_intr_disconnect(xtalk_intr_t); -devfs_handle_t xtalk_intr_cpu_get(xtalk_intr_t); -int xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *); -int xtalk_error_devenable(devfs_handle_t, int, int); -void xtalk_provider_startup(devfs_handle_t); -void xtalk_provider_shutdown(devfs_handle_t); -devfs_handle_t xtalk_intr_dev_get(xtalk_intr_t); -xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t); -xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t); -iopaddr_t xtalk_intr_addr_get(struct xtalk_intr_s *); -void *xtalk_intr_sfarg_get(xtalk_intr_t); -devfs_handle_t xtalk_pio_dev_get(xtalk_piomap_t); -xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t); -iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t); -ulong xtalk_pio_mapsz_get(xtalk_piomap_t); -caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t); -devfs_handle_t xtalk_dma_dev_get(xtalk_dmamap_t); -xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t); -xwidget_info_t xwidget_info_chk(devfs_handle_t); -xwidget_info_t xwidget_info_get(devfs_handle_t); -void xwidget_info_set(devfs_handle_t, xwidget_info_t); -devfs_handle_t xwidget_info_dev_get(xwidget_info_t); -xwidgetnum_t xwidget_info_id_get(xwidget_info_t); -devfs_handle_t xwidget_info_master_get(xwidget_info_t); -xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t); -xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t); -xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t); -char *xwidget_info_name_get(xwidget_info_t); -void xtalk_init(void); -void xtalk_provider_register(devfs_handle_t, xtalk_provider_t *); -void xtalk_provider_unregister(devfs_handle_t); -xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t); -int xwidget_driver_register(xwidget_part_num_t, - xwidget_mfg_num_t, - char *, unsigned); -void xwidget_driver_unregister(char *); -int xwidget_register(xwidget_hwid_t, devfs_handle_t, - xwidgetnum_t, devfs_handle_t, - xwidgetnum_t, async_attach_t); -int xwidget_unregister(devfs_handle_t); -void xwidget_reset(devfs_handle_t); -char *xwidget_name_get(devfs_handle_t); -#if !defined(DEV_FUNC) -/* - * There is more than one possible provider - * for this platform. We need to examine the - * master vertex of the current vertex for - * a provider function structure, and indirect - * through the appropriately named member. - */ -#define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func -#define CAST_PIOMAP(x) ((xtalk_piomap_t)(x)) -#define CAST_DMAMAP(x) ((xtalk_dmamap_t)(x)) -#define CAST_INTR(x) ((xtalk_intr_t)(x)) - -static xtalk_provider_t * -xwidget_to_provider_fns(devfs_handle_t xconn) -{ - xwidget_info_t widget_info; - xtalk_provider_t *provider_fns; - - widget_info = xwidget_info_get(xconn); - ASSERT(widget_info != NULL); - - provider_fns = xwidget_info_pops_get(widget_info); - ASSERT(provider_fns != NULL); - - return (provider_fns); -} -#endif - -/* - * Many functions are not passed their vertex - * information directly; rather, they must - * dive through a resource map. These macros - * are available to coordinate this detail. - */ -#define PIOMAP_FUNC(map,func) DEV_FUNC(map->xp_dev,func) -#define DMAMAP_FUNC(map,func) DEV_FUNC(map->xd_dev,func) -#define INTR_FUNC(intr,func) DEV_FUNC(intr_hdl->xi_dev,func) - -/* ===================================================================== - * PIO MANAGEMENT - * - * For mapping system virtual address space to - * xtalk space on a specified widget - */ - -xtalk_piomap_t -xtalk_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ - device_desc_t dev_desc, /* device descriptor */ - iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ - size_t byte_count, - size_t byte_count_max, /* maximum size of a mapping */ - unsigned flags) -{ /* defined in sys/pio.h */ - return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc) - (dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags); -} - - -void -xtalk_piomap_free(xtalk_piomap_t xtalk_piomap) -{ - PIOMAP_FUNC(xtalk_piomap, piomap_free) - (CAST_PIOMAP(xtalk_piomap)); -} - - -caddr_t -xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap, /* mapping resources */ - iopaddr_t xtalk_addr, /* map for this xtalk address */ - size_t byte_count) -{ /* map this many bytes */ - return PIOMAP_FUNC(xtalk_piomap, piomap_addr) - (CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count); -} - - -void -xtalk_piomap_done(xtalk_piomap_t xtalk_piomap) -{ - PIOMAP_FUNC(xtalk_piomap, piomap_done) - (CAST_PIOMAP(xtalk_piomap)); -} - - -caddr_t -xtalk_piotrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - iopaddr_t xtalk_addr, /* Crosstalk address */ - size_t byte_count, /* map this many bytes */ - unsigned flags) -{ /* (currently unused) */ - return DEV_FUNC(dev, piotrans_addr) - (dev, dev_desc, xtalk_addr, byte_count, flags); -} - -caddr_t -xtalk_pio_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - iopaddr_t addr, /* starting address (or offset in window) */ - size_t byte_count, /* map this many bytes */ - xtalk_piomap_t *mapp, /* where to return the map pointer */ - unsigned flags) -{ /* PIO flags */ - xtalk_piomap_t map = 0; - caddr_t res; - - if (mapp) - *mapp = 0; /* record "no map used" */ - - res = xtalk_piotrans_addr - (dev, dev_desc, addr, byte_count, flags); - if (res) - return res; /* xtalk_piotrans worked */ - - map = xtalk_piomap_alloc - (dev, dev_desc, addr, byte_count, byte_count, flags); - if (!map) - return res; /* xtalk_piomap_alloc failed */ - - res = xtalk_piomap_addr - (map, addr, byte_count); - if (!res) { - xtalk_piomap_free(map); - return res; /* xtalk_piomap_addr failed */ - } - if (mapp) - *mapp = map; /* pass back map used */ - - return res; /* xtalk_piomap_addr succeeded */ -} - -/* ===================================================================== - * EARLY PIOTRANS SUPPORT - * - * There are places where drivers (mgras, for instance) - * need to get PIO translations before the infrastructure - * is extended to them (setting up textports, for - * instance). These drivers should call - * xtalk_early_piotrans_addr with their xtalk ID - * information, a sequence number (so we can use the second - * mgras for instance), and the usual piotrans parameters. - * - * Machine specific code should provide an implementation - * of early_piotrans_addr, and present a pointer to this - * function to xtalk_set_early_piotrans_addr so it can be - * used by clients without the clients having to know what - * platform or what xtalk provider is in use. - */ - -static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr; - -xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr; - -/* xtalk_set_early_piotrans_addr: - * specify the early_piotrans_addr implementation function. - */ -void -xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl) -{ - impl_early_piotrans_addr = impl; -} - -/* xtalk_early_piotrans_addr: - * figure out a PIO address for the "nth" crosstalk widget that - * matches the specified part and mfgr number. Returns NULL if - * there is no such widget, or if the requested mapping can not - * be constructed. - * Limitations on which crosstalk slots (and busses) are - * checked, and definitions of the ordering of the search across - * the crosstalk slots, are defined by the platform. - */ -caddr_t -xtalk_early_piotrans_addr(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - int which, - iopaddr_t xtalk_addr, - size_t byte_count, - unsigned flags) -{ - return impl_early_piotrans_addr - (part_num, mfg_num, which, xtalk_addr, byte_count, flags); -} - -/* null_xtalk_early_piotrans_addr: - * used as the early_piotrans_addr implementation until and - * unless a real implementation is provided. In DEBUG kernels, - * we want to know who is calling before the implementation is - * registered; in non-DEBUG kernels, return NULL representing - * lack of mapping support. - */ -/*ARGSUSED */ -static caddr_t -null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - int which, - iopaddr_t xtalk_addr, - size_t byte_count, - unsigned flags) -{ -#if DEBUG - PRINT_PANIC("null_xtalk_early_piotrans_addr"); -#endif - return NULL; -} - -/* ===================================================================== - * DMA MANAGEMENT - * - * For mapping from crosstalk space to system - * physical space. - */ - -xtalk_dmamap_t -xtalk_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ - device_desc_t dev_desc, /* device descriptor */ - size_t byte_count_max, /* max size of a mapping */ - unsigned flags) -{ /* defined in dma.h */ - return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc) - (dev, dev_desc, byte_count_max, flags); -} - - -void -xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap) -{ - DMAMAP_FUNC(xtalk_dmamap, dmamap_free) - (CAST_DMAMAP(xtalk_dmamap)); -} - - -iopaddr_t -xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */ - paddr_t paddr, /* map for this address */ - size_t byte_count) -{ /* map this many bytes */ - return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr) - (CAST_DMAMAP(xtalk_dmamap), paddr, byte_count); -} - - -alenlist_t -xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */ - alenlist_t alenlist, /* map this Address/Length List */ - unsigned flags) -{ - return DMAMAP_FUNC(xtalk_dmamap, dmamap_list) - (CAST_DMAMAP(xtalk_dmamap), alenlist, flags); -} - - -void -xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap) -{ - DMAMAP_FUNC(xtalk_dmamap, dmamap_done) - (CAST_DMAMAP(xtalk_dmamap)); -} - - -iopaddr_t -xtalk_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - paddr_t paddr, /* system physical address */ - size_t byte_count, /* length */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_addr) - (dev, dev_desc, paddr, byte_count, flags); -} - - -alenlist_t -xtalk_dmatrans_list(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - alenlist_t palenlist, /* system address/length list */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_list) - (dev, dev_desc, palenlist, flags); -} - -void -xtalk_dmamap_drain(xtalk_dmamap_t map) -{ - DMAMAP_FUNC(map, dmamap_drain) - (CAST_DMAMAP(map)); -} - -void -xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) -{ - DEV_FUNC(dev, dmaaddr_drain) - (dev, addr, size); -} - -void -xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list) -{ - DEV_FUNC(dev, dmalist_drain) - (dev, list); -} - -/* ===================================================================== - * INTERRUPT MANAGEMENT - * - * Allow crosstalk devices to establish interrupts - */ - -/* - * Allocate resources required for an interrupt as specified in intr_desc. - * Return resource handle in intr_hdl. - */ -xtalk_intr_t -xtalk_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) -{ /* owner of this interrupt */ - return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc) - (dev, dev_desc, owner_dev); -} - -/* - * Allocate resources required for an interrupt as specified in dev_desc. - * Unconditionally setup resources to be non-threaded. - * Return resource handle in intr_hdl. - */ -xtalk_intr_t -xtalk_intr_alloc_nothd(devfs_handle_t dev, /* which Crosstalk device */ - device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) /* owner of this interrupt */ -{ - return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd) - (dev, dev_desc, owner_dev); -} - -/* - * Free resources consumed by intr_alloc. - */ -void -xtalk_intr_free(xtalk_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_free) - (CAST_INTR(intr_hdl)); -} - - -/* - * Associate resources allocated with a previous xtalk_intr_alloc call with the - * described handler, arg, name, etc. - * - * Returns 0 on success, returns <0 on failure. - */ -int -xtalk_intr_connect(xtalk_intr_t intr_hdl, /* xtalk intr resource handle */ - xtalk_intr_setfunc_t setfunc, /* func to set intr hw */ - void *setfunc_arg) /* arg to setfunc */ -{ - return INTR_FUNC(intr_hdl, intr_connect) - (CAST_INTR(intr_hdl), setfunc, setfunc_arg); -} - - -/* - * Disassociate handler with the specified interrupt. - */ -void -xtalk_intr_disconnect(xtalk_intr_t intr_hdl) -{ - INTR_FUNC(intr_hdl, intr_disconnect) - (CAST_INTR(intr_hdl)); -} - - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. - */ -devfs_handle_t -xtalk_intr_cpu_get(xtalk_intr_t intr_hdl) -{ - return INTR_FUNC(intr_hdl, intr_cpu_get) - (CAST_INTR(intr_hdl)); -} - - -/* ===================================================================== - * CONFIGURATION MANAGEMENT - */ - -/* - * Startup a crosstalk provider - */ -void -xtalk_provider_startup(devfs_handle_t xtalk_provider) -{ - DEV_FUNC(xtalk_provider, provider_startup) - (xtalk_provider); -} - - -/* - * Shutdown a crosstalk provider - */ -void -xtalk_provider_shutdown(devfs_handle_t xtalk_provider) -{ - DEV_FUNC(xtalk_provider, provider_shutdown) - (xtalk_provider); -} - -/* - * Enable a device on a xtalk widget - */ -void -xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum) -{ - DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum); -} - -/* - * Shutdown a device on a xtalk widget - */ -void -xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum) -{ - DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum); -} - -int -xtalk_dma_enabled(devfs_handle_t xconn_vhdl) -{ - return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl); -} -/* - * Generic crosstalk functions, for use with all crosstalk providers - * and all crosstalk devices. - */ - -/****** Generic crosstalk interrupt interfaces ******/ -devfs_handle_t -xtalk_intr_dev_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_dev); -} - -xwidgetnum_t -xtalk_intr_target_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_target); -} - -xtalk_intr_vector_t -xtalk_intr_vector_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_vector); -} - -iopaddr_t -xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr) -{ - return (xtalk_intr->xi_addr); -} - -void * -xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr) -{ - return (xtalk_intr->xi_sfarg); -} - -/****** Generic crosstalk pio interfaces ******/ -devfs_handle_t -xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_dev); -} - -xwidgetnum_t -xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_target); -} - -iopaddr_t -xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_xtalk_addr); -} - -ulong -xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_mapsz); -} - -caddr_t -xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap) -{ - return (xtalk_piomap->xp_kvaddr); -} - - -/****** Generic crosstalk dma interfaces ******/ -devfs_handle_t -xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap) -{ - return (xtalk_dmamap->xd_dev); -} - -xwidgetnum_t -xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap) -{ - return (xtalk_dmamap->xd_target); -} - - -/****** Generic crosstalk widget information interfaces ******/ - -/* xwidget_info_chk: - * check to see if this vertex is a widget; - * if so, return its widget_info (if any). - * if not, return NULL. - */ -xwidget_info_t -xwidget_info_chk(devfs_handle_t xwidget) -{ - arbitrary_info_t ainfo = 0; - - hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo); - return (xwidget_info_t) ainfo; -} - - -xwidget_info_t -xwidget_info_get(devfs_handle_t xwidget) -{ - xwidget_info_t widget_info; - - widget_info = (xwidget_info_t) - hwgraph_fastinfo_get(xwidget); - -#ifdef LATER - if ((widget_info != NULL) && - (widget_info->w_fingerprint != widget_info_fingerprint)) -#ifdef SUPPORT_PRINTING_V_FORMAT - PRINT_PANIC("%v bad xwidget_info", xwidget); -#else - PRINT_PANIC("%x bad xwidget_info", xwidget); -#endif -#endif /* LATER */ - - return (widget_info); -} - -void -xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info) -{ - if (widget_info != NULL) - widget_info->w_fingerprint = widget_info_fingerprint; - - hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info); - - /* Also, mark this vertex as an xwidget, - * and use the widget_info, so xwidget_info_chk - * can work (and be fairly efficient). - */ - hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET, - (arbitrary_info_t) widget_info); -} - -devfs_handle_t -xwidget_info_dev_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_vertex); -} - -xwidgetnum_t -xwidget_info_id_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_id); -} - - -devfs_handle_t -xwidget_info_master_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_master); -} - -xwidgetnum_t -xwidget_info_masterid_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_masterid); -} - -xwidget_part_num_t -xwidget_info_part_num_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_hwid.part_num); -} - -xwidget_mfg_num_t -xwidget_info_mfg_num_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget_info"); - return (xwidget_info->w_hwid.mfg_num); -} -/* Extract the widget name from the widget information - * for the xtalk widget. - */ -char * -xwidget_info_name_get(xwidget_info_t xwidget_info) -{ - if (xwidget_info == NULL) - panic("null xwidget info"); - return(xwidget_info->w_name); -} -/****** Generic crosstalk initialization interfaces ******/ - -/* - * One-time initialization needed for systems that support crosstalk. - */ -void -xtalk_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("xtalk_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (xtalk_registry == NULL) { - cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr"); - if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(xtalk_registry != NULL); -} - -/* - * Associate a set of xtalk_provider functions with a vertex. - */ -void -xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns) -{ - hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns); -} - -/* - * Disassociate a set of xtalk_provider functions with a vertex. - */ -void -xtalk_provider_unregister(devfs_handle_t provider) -{ - hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL); -} - -/* - * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk - * provider. - */ -xtalk_provider_t * -xtalk_provider_fns_get(devfs_handle_t provider) -{ - return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider)); -} - -/* - * Announce a driver for a particular crosstalk part. - * Returns 0 on success or -1 on failure. Failure occurs if the - * specified hardware already has a driver. - */ -/*ARGSUSED4 */ -int -xwidget_driver_register(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - char *driver_prefix, - unsigned flags) -{ - /* a driver's init routine could call - * xwidget_driver_register before the - * system calls xtalk_init; so, we - * make the call here. - */ - if (xtalk_registry == NULL) - xtalk_init(); - - return cdl_add_driver(xtalk_registry, - part_num, mfg_num, - driver_prefix, flags, NULL); -} - -/* - * Inform xtalk infrastructure that a driver is no longer available for - * handling any widgets. - */ -void -xwidget_driver_unregister(char *driver_prefix) -{ - /* before a driver calls unregister, - * it must have called registger; so we - * can assume we have a registry here. - */ - ASSERT(xtalk_registry != NULL); - - cdl_del_driver(xtalk_registry, driver_prefix, NULL); -} - -/* - * Call some function with each vertex that - * might be one of this driver's attach points. - */ -void -xtalk_iterate(char *driver_prefix, - xtalk_iter_f *func) -{ - ASSERT(xtalk_registry != NULL); - - cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func); -} - -/* - * xwidget_register: - * Register a xtalk device (xwidget) by doing the following. - * -allocate and initialize xwidget_info data - * -allocate a hwgraph vertex with name based on widget number (id) - * -look up the widget's initialization function and call it, - * or remember the vertex for later initialization. - * - */ -int -xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ - devfs_handle_t widget, /* widget to initialize */ - xwidgetnum_t id, /* widget's target id (0..f) */ - devfs_handle_t master, /* widget's master vertex */ - xwidgetnum_t targetid, /* master's target id (9/a) */ - async_attach_t aa) -{ - xwidget_info_t widget_info; - char *s,devnm[MAXDEVNAME]; - - /* Allocate widget_info and associate it with widget vertex */ - NEW(widget_info); - - /* Initialize widget_info */ - widget_info->w_vertex = widget; - widget_info->w_id = id; - widget_info->w_master = master; - widget_info->w_masterid = targetid; - widget_info->w_hwid = *hwid; /* structure copy */ - widget_info->w_efunc = 0; - widget_info->w_einfo = 0; - /* - * get the name of this xwidget vertex and keep the info. - * This is needed during errors and interupts, but as - * long as we have it, we can use it elsewhere. - */ - s = dev_to_name(widget,devnm,MAXDEVNAME); - widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL); - strcpy(widget_info->w_name,s); - - xwidget_info_set(widget, widget_info); - - device_master_set(widget, master); - - /* All the driver init routines (including - * xtalk_init) are called before we get into - * attaching devices, so we can assume we - * have a registry here. - */ - ASSERT(xtalk_registry != NULL); - - /* - * Add pointer to async attach info -- tear down will be done when - * the particular descendant is done with the info. - */ - if (aa) - async_attach_add_info(widget, aa); - - return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, - widget, 0); -} - -/* - * xwidget_unregister : - * Unregister the xtalk device and detach all its hwgraph namespace. - */ -int -xwidget_unregister(devfs_handle_t widget) -{ - xwidget_info_t widget_info; - xwidget_hwid_t hwid; - - /* Make sure that we have valid widget information initialized */ - if (!(widget_info = xwidget_info_get(widget))) - return(1); - - /* Remove the inventory information associated - * with the widget. - */ - hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1); - - hwid = &(widget_info->w_hwid); - - cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, - widget, 0); - - /* Clean out the xwidget information */ - (void)kfree(widget_info->w_name); - BZERO((void *)widget_info, sizeof(widget_info)); - DEL(widget_info); - - return(0); -} - -/* - * Issue a link reset to a widget. - */ -void -xwidget_reset(devfs_handle_t xwidget) -{ - xswitch_reset_link(xwidget); - -} - - -void -xwidget_gfx_reset(devfs_handle_t xwidget) -{ - xwidget_info_t info; - - xswitch_reset_link(xwidget); - info = xwidget_info_get(xwidget); -#ifdef LATER - ASSERT_ALWAYS(info != NULL); -#endif - - /* - * Enable this for other architectures once we add widget_reset to the - * xtalk provider interface. - */ - DEV_FUNC(xtalk_provider, widget_reset) - (xwidget_info_master_get(info), xwidget_info_id_get(info)); -} - -#define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */ - -/* Get the canonical hwgraph name of xtalk widget */ -char * -xwidget_name_get(devfs_handle_t xwidget_vhdl) -{ - xwidget_info_t info; - - /* If we have a bogus widget handle then return - * a default anonymous widget name. - */ - if (xwidget_vhdl == GRAPH_VERTEX_NONE) - return(ANON_XWIDGET_NAME); - /* Read the widget name stored in the widget info - * for the widget setup during widget initialization. - */ - info = xwidget_info_get(xwidget_vhdl); - ASSERT(info != NULL); - return(xwidget_info_name_get(info)); -} - -/* - * xtalk_device_shutdown - * Disable the specified xtalk widget and clean out all the software - * state associated with it. - */ -int -xtalk_device_shutdown(devfs_handle_t xbus_vhdl, xwidgetnum_t widget) -{ - devfs_handle_t widget_vhdl; - char edge_name[8]; - - sprintf(edge_name, "%d", widget); - if (hwgraph_traverse(xbus_vhdl, edge_name, &widget_vhdl) - != GRAPH_SUCCESS) - return(1); - - xwidget_unregister(widget_vhdl); - - return(0); -} diff -urN linux-2.4.21/arch/ia64/sn/kernel/Makefile linux-2.4.22/arch/ia64/sn/kernel/Makefile --- linux-2.4.21/arch/ia64/sn/kernel/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,6 @@ # arch/ia64/sn/kernel/Makefile # -# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of version 2 of the GNU General Public License @@ -40,21 +40,15 @@ O_TARGET = sn.o -export-objs = sn_ksyms.o iomv.o +export-objs = sn_ksyms.o -subdir-$(CONFIG_IA64_SGI_SN1) = sn1 -subdir-$(CONFIG_IA64_SGI_SN2) = sn2 +subdir-y = sn2 -obj-y = probe.o setup.o sn_asm.o sv.o bte.o iomv.o -obj-$(CONFIG_IA64_SGI_SN1) += irq.o mca.o -obj-$(CONFIG_IA64_SGI_SN2) += irq.o mca.o +obj-y = probe.o setup.o sv.o bte.o +obj-y += irq.o mca.o idle.o +obj-y += sn2/sn2.o -obj-$(CONFIG_IA64_SGI_SN1) += sn1/sn1.o -obj-$(CONFIG_IA64_SGI_SN2) += sn2/sn2.o - -obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o obj-$(CONFIG_IA64_GENERIC) += machvec.o obj-$(CONFIG_MODULES) += sn_ksyms.o -obj-$(CONFIG_IA64_SGI_SN_BRT) += bte_regr_test.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/kernel/bte.c linux-2.4.22/arch/ia64/sn/kernel/bte.c --- linux-2.4.21/arch/ia64/sn/kernel/bte.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/bte.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * * - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -38,130 +38,157 @@ #include #include #include -#ifdef CONFIG_IA64_SGI_SN2 #include -#endif #include #include #include #include -#include +#include -int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 }; /* - * bte_init_node(nodepda, cnode) + * The base address of for each set of bte registers. + */ +static int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 }; + + +/************************************************************************ + * Block Transfer Engine copy related functions. * - * Initialize the nodepda structure with BTE base addresses and - * spinlocks. + ***********************************************************************/ + + +/* + * bte_copy(src, dest, len, mode, notification) * - * NOTE: The kernel parameter btetest will cause the initialization - * code to reserve blocks of physically contiguous memory to be - * used by the bte test module. + * Use the block transfer engine to move kernel memory from src to dest + * using the assigned mode. + * + * Paramaters: + * src - physical address of the transfer source. + * dest - physical address of the transfer destination. + * len - number of bytes to transfer from source to dest. + * mode - hardware defined. See reference information + * for IBCT0/1 in the SHUB Programmers Reference + * notification - kernel virtual address of the notification cache + * line. If NULL, the default is used and + * the bte_copy is synchronous. + * + * NOTE: This function requires src, dest, and len to + * be cacheline aligned. */ -void -bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode) +bte_result_t +bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification) { - int i; + int bte_to_use; + u64 transfer_size; + struct bteinfo_s *bte; + bte_result_t bte_status; + unsigned long irq_flags; - /* - * Indicate that all the block transfer engines on this node - * are available. - */ - for (i = 0; i < BTES_PER_NODE; i++) { -#ifdef CONFIG_IA64_SGI_SN2 - /* >>> Don't know why the 0x1800000L is here. Robin */ - mynodepda->bte_if[i].bte_base_addr = - (char *)LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L); + BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n", + src, dest, len, mode, notification)); -#elif CONFIG_IA64_SGI_SN1 - mynodepda->bte_if[i].bte_base_addr = - (char *)LOCAL_HUB_ADDR(bte_offsets[i]); -#else -#error BTE Not defined for this hardware platform. -#endif + if (len == 0) { + return BTE_SUCCESS; + } - /* - * Initialize the notification and spinlock - * so the first transfer can occur. - */ - mynodepda->bte_if[i].most_rcnt_na = - &(mynodepda->bte_if[i].notify); - mynodepda->bte_if[i].notify = 0L; -#ifdef CONFIG_IA64_SGI_BTE_LOCKING - spin_lock_init(&mynodepda->bte_if[i].spinlock); -#endif /* CONFIG_IA64_SGI_BTE_LOCKING */ + ASSERT(!((len & L1_CACHE_MASK) || + (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK))); + ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT)); + + do { + local_irq_save(irq_flags); + + bte_to_use = 0; + /* Attempt to lock one of the BTE interfaces. */ + while ((bte_to_use < BTES_PER_NODE) && + BTE_LOCK_IF_AVAIL(bte_to_use)) { + bte_to_use++; + } + + if (bte_to_use < BTES_PER_NODE) { + break; + } + + local_irq_restore(irq_flags); + + if (!(mode & BTE_WACQUIRE)) { + return BTEFAIL_NOTAVAIL; + } - mynodepda->bte_if[i].bte_test_buf = - alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER); + /* Wait until a bte is available. */ + udelay(10); + } while (1); + + bte = pda.cpu_bte_if[bte_to_use]; + BTE_PRINTKV(("Got a lock on bte %d\n", bte_to_use)); + + + if (notification == NULL) { + /* User does not want to be notified. */ + bte->most_rcnt_na = &bte->notify; + } else { + bte->most_rcnt_na = notification; } -} + /* Calculate the number of cache lines to transfer. */ + transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK); + /* Initialize the notification to a known value. */ + *bte->most_rcnt_na = -1L; -/* - * bte_reset_nasid(nasid_t) - * - * Does a soft reset of the BTEs on the specified nasid. - * This is followed by a one-line transfer from each of the - * virtual interfaces. - */ -void -bte_reset_nasid(nasid_t n) -{ - ii_ibcr_u_t ibcr; + /* Set the status reg busy bit and transfer length */ + BTE_PRINTKV(("IBLS - HUB_S(0x%p, 0x%lx)\n", + BTEREG_LNSTAT_ADDR, IBLS_BUSY | transfer_size)); + HUB_S(BTEREG_LNSTAT_ADDR, (IBLS_BUSY | transfer_size)); + + /* Set the source and destination registers */ + BTE_PRINTKV(("IBSA - HUB_S(0x%p, 0x%lx)\n", BTEREG_SRC_ADDR, + (TO_PHYS(src)))); + HUB_S(BTEREG_SRC_ADDR, (TO_PHYS(src))); + BTE_PRINTKV(("IBDA - HUB_S(0x%p, 0x%lx)\n", BTEREG_DEST_ADDR, + (TO_PHYS(dest)))); + HUB_S(BTEREG_DEST_ADDR, (TO_PHYS(dest))); + + /* Set the notification register */ + BTE_PRINTKV(("IBNA - HUB_S(0x%p, 0x%lx)\n", BTEREG_NOTIF_ADDR, + (TO_PHYS(__tpa(bte->most_rcnt_na))))); + HUB_S(BTEREG_NOTIF_ADDR, (TO_PHYS(__tpa(bte->most_rcnt_na)))); + + + /* Initiate the transfer */ + BTE_PRINTK(("IBCT - HUB_S(0x%p, 0x%lx)\n", BTEREG_CTRL_ADDR, + BTE_VALID_MODE(mode))); + HUB_S(BTEREG_CTRL_ADDR, BTE_VALID_MODE(mode)); - ibcr.ii_ibcr_regval = REMOTE_HUB_L(n, IIO_IBCR); - ibcr.ii_ibcr_fld_s.i_soft_reset = 1; - REMOTE_HUB_S(n, IIO_IBCR, ibcr.ii_ibcr_regval); - - /* One line transfer on virtual interface 0 */ - REMOTE_HUB_S(n, IIO_IBLS_0, IBLS_BUSY | 1); - REMOTE_HUB_S(n, IIO_IBSA_0, TO_PHYS(__pa(&nodepda->bte_cleanup))); - REMOTE_HUB_S(n, IIO_IBDA_0, - TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES]))); - REMOTE_HUB_S(n, IIO_IBNA_0, - TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES]))); - REMOTE_HUB_S(n, IIO_IBCT_0, BTE_NOTIFY); - while (REMOTE_HUB_L(n, IIO_IBLS0)) { - /* >>> Need some way out in case of hang... */ + spin_unlock_irqrestore(&bte->spinlock, irq_flags); + + + if (notification != NULL) { + return BTE_SUCCESS; } - /* One line transfer on virtual interface 1 */ - REMOTE_HUB_S(n, IIO_IBLS_1, IBLS_BUSY | 1); - REMOTE_HUB_S(n, IIO_IBSA_1, TO_PHYS(__pa(nodepda->bte_cleanup))); - REMOTE_HUB_S(n, IIO_IBDA_1, - TO_PHYS(__pa(nodepda->bte_cleanup[4 * L1_CACHE_BYTES]))); - REMOTE_HUB_S(n, IIO_IBNA_1, - TO_PHYS(__pa(nodepda->bte_cleanup[5 * L1_CACHE_BYTES]))); - REMOTE_HUB_S(n, IIO_IBCT_1, BTE_NOTIFY); - while (REMOTE_HUB_L(n, IIO_IBLS1)) { - /* >>> Need some way out in case of hang... */ + while (*bte->most_rcnt_na == -1UL) { } -} -/* - * bte_init_cpu() - * - * Initialize the cpupda structure with pointers to the - * nodepda bte blocks. - * - */ -void -bte_init_cpu(void) -{ - /* Called by setup.c as each cpu is being added to the nodepda */ - if (local_node_data->active_cpu_count & 0x1) { - pda.cpu_bte_if[0] = &(nodepda->bte_if[0]); - pda.cpu_bte_if[1] = &(nodepda->bte_if[1]); + BTE_PRINTKV((" Delay Done. IBLS = 0x%lx, most_rcnt_na = 0x%lx\n", + HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na)); + + if (*bte->most_rcnt_na & IBLS_ERROR) { + bte_status = *bte->most_rcnt_na & ~IBLS_ERROR; + *bte->most_rcnt_na = 0L; } else { - pda.cpu_bte_if[0] = &(nodepda->bte_if[1]); - pda.cpu_bte_if[1] = &(nodepda->bte_if[0]); + bte_status = BTE_SUCCESS; } + BTE_PRINTK(("Returning status is 0x%lx and most_rcnt_na is 0x%lx\n", + HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na)); + + return bte_status; } @@ -198,15 +225,11 @@ char *bteBlock; if (len == 0) { - return (BTE_SUCCESS); + return BTE_SUCCESS; } -#ifdef CONFIG_IA64_SGI_BTE_LOCKING -#error bte_unaligned_copy() assumes single BTE selection in bte_copy(). -#else /* temporary buffer used during unaligned transfers */ - bteBlock = pda.cpu_bte_if[0]->bte_test_buf; -#endif + bteBlock = pda.cpu_bte_if[0]->scratch_buf; headBcopySrcOffset = src & L1_CACHE_MASK; destFirstCacheOffset = dest & L1_CACHE_MASK; @@ -271,15 +294,15 @@ headBteLen += footBteLen; } else if (footBcopyLen > 0) { rv = bte_copy(footBteSource, - __pa(bteBlock), + __tpa(bteBlock), footBteLen, mode, NULL); if (rv != BTE_SUCCESS) { - return (rv); + return rv; } memcpy(__va(footBcopyDest), - (char *)bteBlock, footBcopyLen); + (char *) bteBlock, footBcopyLen); } } else { footBcopyLen = 0; @@ -294,7 +317,7 @@ (len - headBcopyLen - footBcopyLen), mode, NULL); if (rv != BTE_SUCCESS) { - return (rv); + return rv; } } @@ -321,14 +344,93 @@ if (headBcopyLen > 0) { rv = bte_copy(headBteSource, - __pa(bteBlock), headBteLen, mode, NULL); + __tpa(bteBlock), headBteLen, mode, NULL); if (rv != BTE_SUCCESS) { - return (rv); + return rv; } - memcpy(__va(headBcopyDest), ((char *)bteBlock + + memcpy(__va(headBcopyDest), ((char *) bteBlock + headBcopySrcOffset), headBcopyLen); } - return (BTE_SUCCESS); + return BTE_SUCCESS; +} + + +/************************************************************************ + * Block Transfer Engine initialization functions. + * + ***********************************************************************/ + + +/* + * bte_init_node(nodepda, cnode) + * + * Initialize the nodepda structure with BTE base addresses and + * spinlocks. + */ +void +bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode) +{ + int i; + + + /* + * Indicate that all the block transfer engines on this node + * are available. + */ + + /* + * Allocate one bte_recover_t structure per node. It holds + * the recovery lock for node. All the bte interface structures + * will point at this one bte_recover structure to get the lock. + */ + spin_lock_init(&mynodepda->bte_recovery_lock); + init_timer(&mynodepda->bte_recovery_timer); + mynodepda->bte_recovery_timer.function = bte_error_handler; + mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda; + + for (i = 0; i < BTES_PER_NODE; i++) { + /* >>> Don't know why the 0x1800000L is here. Robin */ + mynodepda->bte_if[i].bte_base_addr = + (char *) LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L); + + /* + * Initialize the notification and spinlock + * so the first transfer can occur. + */ + mynodepda->bte_if[i].most_rcnt_na = + &(mynodepda->bte_if[i].notify); + mynodepda->bte_if[i].notify = 0L; + spin_lock_init(&mynodepda->bte_if[i].spinlock); + + mynodepda->bte_if[i].scratch_buf = + alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER); + mynodepda->bte_if[i].bte_cnode = cnode; + mynodepda->bte_if[i].bte_error_count = 0; + mynodepda->bte_if[i].bte_num = i; + mynodepda->bte_if[i].cleanup_active = 0; + mynodepda->bte_if[i].bh_error = 0; + } + +} + +/* + * bte_init_cpu() + * + * Initialize the cpupda structure with pointers to the + * nodepda bte blocks. + * + */ +void +bte_init_cpu(void) +{ + /* Called by setup.c as each cpu is being added to the nodepda */ + if (local_node_data->active_cpu_count & 0x1) { + pda.cpu_bte_if[0] = &(nodepda->bte_if[0]); + pda.cpu_bte_if[1] = &(nodepda->bte_if[1]); + } else { + pda.cpu_bte_if[0] = &(nodepda->bte_if[1]); + pda.cpu_bte_if[1] = &(nodepda->bte_if[0]); + } } diff -urN linux-2.4.21/arch/ia64/sn/kernel/bte_regr_test.c linux-2.4.22/arch/ia64/sn/kernel/bte_regr_test.c --- linux-2.4.21/arch/ia64/sn/kernel/bte_regr_test.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/bte_regr_test.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1062 +0,0 @@ -/* - * - * - * Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan - */ - - -/*********************************************************************** - * Block Transfer Engine regression tests. - * - * The following set of tests can be used to test for regressions. - * It is implemented as a loadable module. - * - * To enable the tests, the kernel must be booted with the - * "btetest" command line flag. If the tests are compiled into the - * kernel, additional values may be passed with - * "bte_test=t,v,ht,tn,tx,ti,ta,tc" - * where: - * t = Bitmask of tests to run. - * v = Level of verbosity. - * ht = Number of seconds to try to force a notification hang. - * hu = Number of uSecs to wait until warning of hang. - * tn = Min number of lines to rate test with (2 raised to). - * tx = Max number of lines to rate test with (2 raised to). - * ti = Number of iterations per timing. - * ta = Aternate through cpus on each pass. - * tc = Use/Don't Use memcopy - * - * When loaded as a module, each of those values has a seperate - * parameter. Just do a modinfo bte_test.o to get those names - * and valid ranges. - * - * Tests are performed in the following order. - * - * Standard Transfer Test - Just transfers a block of initialized - * data to a cleared block and ensures that memory before and after - * is untouched, but that the body has all the correct values. - * - * Transfer Rate Test - Data is transfered from node to node - * to ensure every node is able to BTE data. Timings are created - * for each node. - * - * Notification Hang Test - Attempts to force the Notification - * hang problem to arise. A hang occurs when the BTE fails - * to invalidate a processors cache line for the notification - * word, resulting in the processor not seeing the updated - * value. - * - * Invalid Transfer Test - In this test, we attempt to transfer - * data from a valid address to a nasid which does not exist. - * - **********************************************************************/ - - -#define BTE_TIME 1 /* Needed to ensure bte_copy records - * timings */ -// #define BTE_DEBUG -// #define BTE_DEBUG_VERBOSE - -#include -#include -#include -#include -#include -#include -#include - -#include - - -/*********************************************************************** - * Local defines, structs, and typedefs. - * - **********************************************************************/ - - -/* - * The following struct defines standard transfers to use while - * testing. - */ -typedef struct brt_xfer_entry_s { - int source_offset; - int dest_offset; - int length; -} brt_xfer_entry_t; - -/* - * BRT_TEST_BLOCK_SIZE needs to accomodate the largest transfer that - * is found in brt_xfer_tests. - */ -#define BRT_TEST_BLOCK_SIZE 1024 - -/* Flags for selecting tests to run. */ -#define TEST_REGRESSION 0x00000001 /* Standard Transfer */ -#define TEST_TIME 0x00000002 /* Timed Transfer */ -#define TEST_NOTIFY 0x00000004 /* Notification Hang */ -#define TEST_NONODE 0x00000008 /* Invalid Nasid Xfer */ - - -/*********************************************************************** - * Global variables. - * - **********************************************************************/ - - -/* - * bte_setup_time - Time it takes for bte_copy to get locks - * acquired and values into SHUB registers to start the - * xfer. - * - * bte_transfer_time - Time where hardware is doing the xfer. - * - * bte_tear_down_time - Time to unlock and return. - * - * bte_execute_time - Time from first call until return. - */ -volatile static u64 bte_setup_time; -volatile static u64 bte_transfer_time; -volatile static u64 bte_tear_down_time; -volatile static u64 bte_execute_time; - -/* Tests to run during standard transfer tests. */ -static brt_xfer_entry_t brt_xfer_tests[] = { - {0, 0, 2 * L1_CACHE_BYTES}, /* The ideal case. */ - - {0, 0, 35}, /* Symetrical aligned test. */ - {L1_CACHE_BYTES, L1_CACHE_BYTES, 35}, - {0, 0, L1_CACHE_BYTES + 35}, - {L1_CACHE_BYTES, L1_CACHE_BYTES, L1_CACHE_BYTES + 35}, - {0, 0, (2 * L1_CACHE_BYTES) + 35}, - {L1_CACHE_BYTES, L1_CACHE_BYTES, (2 * L1_CACHE_BYTES) + 35}, - {0, 0, (4 * L1_CACHE_BYTES) + 35}, - {L1_CACHE_BYTES, L1_CACHE_BYTES, (4 * L1_CACHE_BYTES) + 35}, - - {(0 + 25), (0 + 25), 35}, /* Symetrical unaligned test. */ - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25), 35}, - {(0 + 25), (0 + 25), L1_CACHE_BYTES + 35}, - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25), - (L1_CACHE_BYTES + 25) + 35}, - {(0 + 25), (0 + 25), (2 * L1_CACHE_BYTES) + 35}, - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25), - (2 * L1_CACHE_BYTES) + 35}, - {(0 + 25), (0 + 25), (4 * L1_CACHE_BYTES) + 35}, - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25), - (4 * L1_CACHE_BYTES) + 35}, - - {(0 + 25), (0 + 26), 35}, /* Asymetrical unaligned test. */ - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26), 35}, - {(0 + 25), (0 + 26), L1_CACHE_BYTES + 35}, - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26), - (L1_CACHE_BYTES + 25) + 35}, - {(0 + 25), (0 + 26), (2 * L1_CACHE_BYTES) + 35}, - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26), - (2 * L1_CACHE_BYTES) + 35}, - {(0 + 25), (0 + 26), (4 * L1_CACHE_BYTES) + 35}, - {(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26), - (4 * L1_CACHE_BYTES) + 35}, - - {0, 0, 0} /* Terminator */ -}; - -static atomic_t brt_thread_cnt; /* Threads in test. */ -volatile static int brt_exit_flag; /* Flag termination of hang test */ - -/* command line/module parameters */ -static int selected_tests = 0; -static int verbose = 0; -static int hang_timeout = 10; -static int hang_usec = 12; -static int tm_min_lines = 1; -static int tm_max_lines = 3; -static int tm_iterations = 1; -static int tm_alternate = 0; -static int tm_memcpy = 1; -static int ix_iterations = 1000; -static int ix_srcnasid = -1; - - -/*********************************************************************** - * Local Function Prototypes. - * - **********************************************************************/ - - -static int __init brt_test_init(void); -static void __exit brt_test_exit(void); - -/* Standard Transfer Test related functions. */ -static int brt_tst_std_xfer(void); -static int brt_std_xfer(char *, char *, int, int, int, int); -static void brt_hex_dump(char *, int); - -/* Timed Transfer Test related functions. */ -static int brt_tst_time_xfers(void); -static void brt_time_xfer(int, int, int); - -/* Notification Hang Test related functions. */ -static int brt_tst_notify_hang(void); -static int brt_notify_thrd(void *); - -/* Transfers to Invalid Nasid Test related functions. */ -static int brt_tst_invalid_xfers(void); - -#if !defined(MODULE) -/* Kernel command line handler. */ -static int __init brt_setup(char *); -#endif /* !defined(MODULE) */ - - -/*********************************************************************** - * Module Load/Unload. - * - **********************************************************************/ - - -#define brt_marker() \ - printk("**************************************************" \ - "**********************.\n"); \ - printk("\n"); \ - printk("**************************************************" \ - "**********************.\n"); \ - printk("\n"); \ - printk("**************************************************" \ - "**********************.\n"); \ - printk("\n"); - - -static int __init -brt_test_init(void) -{ - int some_tests_removed; - - if (numnodes < 2) { - printk("These tests are best run on multinode " - "systems.\n"); - } - - if (!pda.cpu_bte_if[0]->bte_test_buf) { - some_tests_removed = 0; - - /* Timed Transfers go node-to-node. */ - if (selected_tests & TEST_TIME) { - some_tests_removed = 1; - selected_tests &= ~(TEST_TIME); - } - - /* Notification Hang runs on all cpus simultaneously */ - if (selected_tests & TEST_NOTIFY) { - some_tests_removed = 1; - selected_tests &= ~(TEST_NOTIFY); - } - - /* Invalid Tests */ - if (selected_tests & TEST_NONODE) { - some_tests_removed = 1; - selected_tests &= ~(TEST_NONODE); - } - - if (some_tests_removed) { - printk("Test Buffers were not allocated.\n"); - printk("Please reboot the system and supply " - "the \"btetest\" kernel flag\n"); - printk("Some tests were removed.\n"); - } - } - - brt_marker(); - - printk("brt_test(): Starting.\n"); - - if (selected_tests & TEST_REGRESSION) { - if (brt_tst_std_xfer()) { - printk("Standard Transfers had errors.\n"); - } - - } - - if (selected_tests & TEST_TIME) { - if (tm_min_lines < 0) { - tm_min_lines = 0; - } - if (tm_max_lines < 0) { - tm_max_lines = 0; - } - - if (tm_max_lines > BTE_LEN_MASK) { - tm_max_lines = BTE_LEN_MASK; - } - if (tm_min_lines > tm_max_lines) { - tm_min_lines = tm_max_lines; - } - - if (brt_tst_time_xfers()) { - printk("Timed transfers had errors.\n"); - } - - } - - if (selected_tests & TEST_NOTIFY) { - if (hang_usec < 8) { - hang_usec = 8; - } - if (hang_usec > 256) { - hang_usec = 256; - } - - if (brt_tst_notify_hang()) { - printk("Notification Hang test had errors.\n"); - } - } - - if (selected_tests & TEST_NONODE) { - if (brt_tst_invalid_xfers()) { - printk("Invalid Nasid test had errors.\n"); - } - } - - return (1); /* Prevent module load. */ -} - - -static void __exit -brt_test_exit(void) -{ -} - - -/*********************************************************************** - * Standard Transfer Test. - * - * This test has a table of transfers defined above. For each - * transfer, it calls bte_unaligned_copy. It compares the actual - * result with the expected result. If they differ, it prints out - * information about the transfer and hex dumps the actual block - * - **********************************************************************/ - - -/* - * Allocate the needed buffers and then initiate each xfer specified - * by brt_xfer_tests. - */ -static int -brt_tst_std_xfer(void) -{ - char *block_1; - char *block_2; - int iteration = 0; - brt_xfer_entry_t *cur_test; - int cpu; - int err_cnt; - - block_1 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL); - ASSERT(!((u64) block_1 & L1_CACHE_MASK)); - block_2 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL); - ASSERT(!((u64) block_2 & L1_CACHE_MASK)); - - cur_test = brt_xfer_tests; - - err_cnt = 0; - while (cur_test->length) { - for (cpu = 0; cpu < smp_num_cpus; cpu++) { - set_cpus_allowed(current, (1UL << cpu)); - - if (verbose > 1) { - printk("Cpu %d Transfering %d from " - "%d to %d.\n", - smp_processor_id(), - cur_test->length, - cur_test->source_offset, - cur_test->dest_offset); - } - - err_cnt += brt_std_xfer(block_1, block_2, - cur_test->source_offset, - cur_test->dest_offset, - cur_test->length, - ++iteration); - - } - cur_test++; - } - - kfree(block_2); - kfree(block_1); - - return ((err_cnt ? 1 : 0)); -} - - -/* - * Perform a single transfer and ensure the result matches - * the expected. Returns the number of differences found. - * - * Testing is performed by setting the source buffer to a - * known value, and zeroing out the destination. - * - * After the copy, if the destination has only the known - * source values at the correct place, we know we had a - * good transfer. - * - */ -static int -brt_std_xfer(char *src, char *dst, - int src_offset, int dst_offset, int len, - int magic) -{ - int i, ret; - int err_cnt = 0; - - if (verbose > 3) { - printk("brt_test(src=0x%lx, dst=0x%lx, src_offset=%d, " - "dst_offset=%d, len=%d, magic=%d\n", - (u64) src, (u64) dst, src_offset, - dst_offset, len, magic); - } - - memset(src, ((magic + 1) & 0xff), BRT_TEST_BLOCK_SIZE); - memset((src + src_offset), magic, len); - if (verbose > 8) { - printk("Before transfer: Source is\n"); - brt_hex_dump(src, BRT_TEST_BLOCK_SIZE); - } - memset(dst, 0, BRT_TEST_BLOCK_SIZE); - if (verbose > 8) { - printk("Before transfer: dest is\n"); - brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE); - } - - ret = BTE_UNALIGNED_COPY(__pa(src + src_offset), - __pa(dst + dst_offset), - len, BTE_NOTIFY); - if (ret != BTE_SUCCESS) { - printk("brt_test: BTE_UNALIGNED_COPY() error: %d\n", ret); - return (1); - } - - /* Check head */ - for (i = 0; i < dst_offset; i++) { - if ((dst[i] & 0xff) != 0) { - err_cnt++; - } - } - /* Check body */ - for (i = 0; i < len; i++) { - if ((dst[dst_offset + i] & 0xff) != (magic & 0xff)) { - err_cnt++; - } - } - /* Check foot */ - for (i = (dst_offset + len); i < BRT_TEST_BLOCK_SIZE; i++) { - if ((dst[i] & 0xff) != 0) { - err_cnt++; - } - } - - if ((verbose > 3) || err_cnt) { - printk("brt_test: %d errors during basic " - "transfer test.\n", err_cnt); - brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE); - } - - return (err_cnt); -} - - -/* - * Dump a block of data to console as hex. - */ -static void -brt_hex_dump(char *block_to_dump, int block_len) -{ - int i; - char fmt_line[128]; - char *fmt_eol = fmt_line; - - for (i = 0; i < block_len; i++) { - if (!(i % 16)) { - if (i > 0) { - printk("%s\n", fmt_line); - } - sprintf(fmt_line, "0x%lx %05d ", - __pa(&block_to_dump[i]), i); - fmt_eol = fmt_line; - } - while (*fmt_eol++) { /* empty */ - }; - fmt_eol--; - sprintf(fmt_eol, "%s%02x", - (!(i % 4) ? " " : ""), (block_to_dump[i] & 0xff)); - } - printk("%s\n", fmt_line); -} - - -/*********************************************************************** - * Transfer Rate Test. - * - * This test migrates to each cpu one at a time. This is done to - * get a complete view of how each of the bte engines is performing - * and help ensure that each virtual interface is being used. - * NOTE: All virtual interfaces will not necessarily be used. - * - * Now that we have migrated to the desired cpu, we transfer from - * our node to all the other nodes (including ourself). We - * accomplish this with both a memcpy and a bte_copy. Timings - * for both are printed. - * - **********************************************************************/ - - -#define NSEC(x) ((x) * (1000000000UL / local_cpu_data->itc_freq)) - - -/* - * Migrate to each cpu. When on the desired cpu, time transfers to - * each node by calling brt_time_xfer. - */ -static int -brt_tst_time_xfers(void) -{ - int tst_cpu; - int dest_node; - int xfer_lines; - int i; - - if (tm_memcpy) { - printk("Cpu,Src,Dst,Lines,Stup,Transfr,Fin,Execute," - "Overall,Memcpy\n"); - } else { - printk("Cpu,Src,Dst,Lines,Stup,Transfr,Fin,Execute," - "Overall\n"); - } - - if (tm_alternate) { - /* Now transfer from this node to all the others. */ - for (dest_node = 0; dest_node < numnodes; dest_node++) { - for (xfer_lines = tm_min_lines; - xfer_lines <= tm_max_lines;) { - - for (i = 0; i < tm_iterations; i++) { - for (tst_cpu = 0; - tst_cpu < smp_num_cpus; - tst_cpu++) { - /* Move to the desired CPU. */ - set_cpus_allowed(current, - (1UL << tst_cpu)); - - brt_time_xfer(dest_node, - 1, - xfer_lines); - - } - } - /* Handle a min of 0 */ - if (xfer_lines < 1) { - xfer_lines = 1; - } else { - xfer_lines *= 2; - } - } - } - } else { - for (tst_cpu = 0; tst_cpu < smp_num_cpus; tst_cpu++) { - /* Move to the desired CPU. */ - set_cpus_allowed(current, (1UL << tst_cpu)); - - /* Now transfer from this node to all the others. */ - for (dest_node = 0; dest_node < numnodes; - dest_node++) { - for (xfer_lines = tm_min_lines; - xfer_lines <= tm_max_lines;) { - - brt_time_xfer(dest_node, - tm_iterations, - xfer_lines); - - /* Handle a min of 0 */ - if (xfer_lines < 1) { - xfer_lines = 1; - } else { - xfer_lines *= 2; - } - } - } - } - } - return (0); -} - - -/* - * Transfer the bte_test_buffer from our node to the specified - * destination and print out timing results. - */ -static void -brt_time_xfer(int dest_node, int iterations, int xfer_lines) -{ - int iteration; - char *src, *dst; - u64 xfer_len, src_phys, dst_phys; - u64 itc_before, itc_after, mem_intvl, bte_intvl; - - - xfer_len = xfer_lines * L1_CACHE_BYTES; - - src = nodepda->bte_if[0].bte_test_buf; - src_phys = __pa(src); - dst = NODEPDA(dest_node)->bte_if[1].bte_test_buf; - dst_phys = __pa(dst); - mem_intvl = 0; - - for (iteration = 0; iteration < iterations; iteration++) { - if (tm_memcpy) { - itc_before = ia64_get_itc(); - memcpy(dst, src, xfer_len); - itc_after = ia64_get_itc(); - mem_intvl = itc_after - itc_before; - } - - itc_before = ia64_get_itc(); - bte_copy(src_phys, dst_phys, xfer_len, BTE_NOTIFY, NULL); - itc_after = ia64_get_itc(); - bte_intvl = itc_after - itc_before; - - if (tm_memcpy) { - printk("%3d,%3d,%3d,%5d,%4ld,%7ld,%3ld," - "%7ld,%7ld,%7ld\n", - smp_processor_id(), NASID_GET(src), - NASID_GET(dst), xfer_lines, - NSEC(bte_setup_time), - NSEC(bte_transfer_time), - NSEC(bte_tear_down_time), - NSEC(bte_execute_time), NSEC(bte_intvl), - NSEC(mem_intvl)); - } else { - printk("%3d,%3d,%3d,%5d,%4ld,%7ld,%3ld," - "%7ld,%7ld\n", - smp_processor_id(), NASID_GET(src), - NASID_GET(dst), xfer_lines, - NSEC(bte_setup_time), - NSEC(bte_transfer_time), - NSEC(bte_tear_down_time), - NSEC(bte_execute_time), NSEC(bte_intvl)); - } - } - -} - - -/*********************************************************************** - * Notification Hang Test. -- NOTE: Has never actually caused a hang. - * - * The next set of code checks to see if the Notification Hang - * occurs. It does this by starting one thread per cpu, pinning - * the thread to its assigned cpu. After it is pinned, we lock - * the associated bte. Source, Dest, and Notification are - * assigned. - * - * Inside of a loop, we set the length and trigger the - * transfer. We use the ITC to determine when the transfer should - * complete. Whenever the IBLS_BUSY bit is cleared, the transfer - * has completed. We occasionally call schedule (Since all CPUs - * have a pinned process The machine will be doing nothing but - * out tranfers) and loop. - * - * If twice max normal time has passed without seeing the - * notification, we check the Length/Status register to see if - * IBLS_BUSY is still asserted and length is zero. This is an - * indication of the hang. - * - **********************************************************************/ - - -/* - * Launch one thread per cpu. When all threads are started, sleep - * the specified timeout and then notify the other threads that it - * is time to exit. - */ -static int -brt_tst_notify_hang(void) -{ - int tst_cpu; - - printk("Waiting %d seconds to complete test.\n", hang_timeout); - - atomic_set(&brt_thread_cnt, 0); - brt_exit_flag = 0; - - for (tst_cpu = 0; tst_cpu < smp_num_cpus; tst_cpu++) { - if ((kernel_thread(brt_notify_thrd, - (void *)(long)tst_cpu, 0)) < 0) { - printk("Failed to start thread.\n"); - } - } - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(hang_timeout * HZ); - set_current_state(TASK_RUNNING); - - printk("Flagging an exit.\n"); - brt_exit_flag = 1; - - while (atomic_read(&brt_thread_cnt)) { - /* Wait until everyone else is done. */ - schedule(); - } - - printk("All threads have exited.\n"); - return (0); -} - - -/* - * One of these threads is started per cpu. Each thread is responsible - * for loading that cpu's bte interface and then writing to the - * test buffer. The transfers are set in a round-robin fashion. - * The end result is that each test buffer is being written into - * by the previous node and both cpu's at the same time as the - * local bte is transferring it to the next node. - */ -static int -brt_notify_thrd(void *__bind_cpu) -{ - int bind_cpu = (long int)__bind_cpu; - int cpu = cpu_logical_map(bind_cpu); - nodepda_t *nxt_node; - long tmout_itc_intvls; - long tmout; - long passes; - long good_xfer_cnt; - u64 src_phys, dst_phys; - int i; - volatile char *src_buf; - u64 *notify; - - atomic_inc(&brt_thread_cnt); - daemonize(); - set_user_nice(current, 19); - sigfillset(¤t->blocked); - - /* Migrate to the right CPU */ - set_cpus_allowed(current, 1UL << cpu); - - /* Calculate the uSec timeout itc offset. */ - tmout_itc_intvls = local_cpu_data->cyc_per_usec * hang_usec; - - if (local_cnodeid() == (numnodes - 1)) { - nxt_node = NODEPDA(0); - } else { - nxt_node = NODEPDA(local_cnodeid() + 1); - } - - src_buf = nodepda->bte_if[0].bte_test_buf; - src_phys = __pa(src_buf); - dst_phys = __pa(nxt_node->bte_if[0].bte_test_buf); - - notify = kmalloc(L1_CACHE_BYTES, GFP_KERNEL); - ASSERT(!((u64) notify & L1_CACHE_MASK)); - - printk("BTE Hang %d xfer 0x%lx -> 0x%lx, Notify=0x%lx\n", - smp_processor_id(), src_phys, dst_phys, (u64) notify); - - passes = 0; - good_xfer_cnt = 0; - - /* Loop until signalled to exit. */ - while (!brt_exit_flag) { - /* - * A hang will prevent further transfers. - * NOTE: Sometimes, it appears like a hang occurred and - * then transfers begin again. This just means that - * there is NUMA congestion and the hang_usec param - * should be increased. - */ - if (!(*notify & IBLS_BUSY)) { - if ((bte_copy(src_phys, - dst_phys, - 4UL * L1_CACHE_BYTES, - BTE_NOTIFY, - (void *)notify)) != BTE_SUCCESS) { - printk("<0>Cpu %d Could not " - "allocate a bte.\n", - smp_processor_id()); - continue; - } - - tmout = ia64_get_itc() + tmout_itc_intvls; - - while ((*notify & IBLS_BUSY) && - (ia64_get_itc() < tmout)) { - - - /* Push data out with the processor. */ - for (i = 0; i < (4 * L1_CACHE_BYTES); - i += L1_CACHE_BYTES) { - src_buf[i] = (passes % 128); - } - }; - - if (*notify & IBLS_BUSY) { - printk("<0>Cpu %d BTE appears to have " - "hung.\n", smp_processor_id()); - } else { - good_xfer_cnt++; - } - } - - /* Every x passes, take a little break. */ - if (!(++passes % 40)) { - passes = 0; - schedule_timeout(0.01 * HZ); - } - } - - kfree(notify); - - printk("Cpu %d had %ld good passes\n", - smp_processor_id(), good_xfer_cnt); - - atomic_dec(&brt_thread_cnt); - return (0); -} - - -/*********************************************************************** - * Invalid Transfer Test. - * - * Just transfer from the local node to a nasid which does not - * exist. - * - * >>> Potential Problem: on SN1, HUB interrupt doesn't always - * occurr. - * - **********************************************************************/ - - -/* - * Locate a nasid which doesn't exist. Perform a bte_copy from that - * node to our local node. - */ -static int -brt_tst_invalid_xfers(void) -{ - int i; - int free_nasid = -1; - int cpu; - int error_cnt; - - u64 ret_code; - - if (ix_srcnasid != -1) { - free_nasid = ix_srcnasid; - } else { - /* Only looking for nasids from C-Nodes. */ - for (i = 0; i < PLAT_MAX_NODE_NUMBER; i += 2) { - if (local_node_data->physical_node_map[i] == -1) { - free_nasid = i; - break; - } - } - } - - if (free_nasid == -1) { - printk("tst_invalid_xfers: No free nodes found. " - "Exiting.\n"); - return (0); - } - - printk("tst_invalid_xfers: Using source nasid of %d\n", - free_nasid); - - error_cnt = 0; - - for (i = 0; i < ix_iterations; i++) { - if (verbose >= 1) { - printk("-------------------------------" - "-------------------------------" - "--------------\n"); - } - if ((verbose >= 1) || !(i % 10)) { - printk(" Loop %d\n", i); - } - - for (cpu = 0; cpu < smp_num_cpus; cpu++) { - set_cpus_allowed(current, (1UL << cpu)); - - if (verbose > 1) { - printk("Testing with CPU %d\n", - smp_processor_id()); - } - - /* >>> Need a better means of calculating a - * remote addr. */ - ret_code = bte_copy(TO_NODE(free_nasid, 0), - __pa(nodepda->bte_if[0]. - bte_test_buf), - 4 * L1_CACHE_BYTES, - BTE_NOTIFY, - NULL); - error_cnt += (ret_code ? 1 : 0); - } - } - - ret_code = ((error_cnt != (ix_iterations * smp_num_cpus)) ? - 1 : 0); - return (ret_code); -} - - -/*********************************************************************** - * Kernel command line handler. - * - **********************************************************************/ - - -#if !defined(MODULE) -static int __init -brt_setup(char *str) -{ - int cur_val; - - if (get_option(&str, &cur_val)) { - selected_tests = cur_val; - } - if (get_option(&str, &cur_val)) { - verbose = cur_val; - } - if (get_option(&str, &cur_val)) { - hang_timeout = cur_val; - } - if (get_option(&str, &cur_val)) { - hang_usec = cur_val; - } - if (get_option(&str, &cur_val)) { - tm_min_lines = cur_val; - } - if (get_option(&str, &cur_val)) { - tm_max_lines = cur_val; - } - if (get_option(&str, &cur_val)) { - tm_iterations = cur_val; - } - if (get_option(&str, &cur_val)) { - tm_alternate = cur_val; - } - if (get_option(&str, &cur_val)) { - tm_memcpy = cur_val; - } - if (get_option(&str, &cur_val)) { - ix_iterations = cur_val; - } - if (get_option(&str, &cur_val)) { - ix_srcnasid = cur_val; - } - - return (1); -} -#endif /* !defined(MODULE) */ - - -/*********************************************************************** - * Module parameters. - * - * The two supported cases are loadable module parms and kernel - * command line support. - * - * The loadable module options are specified below in the - * MODULE_PARM macros and have associated descriptions. - * - * The kernel command line option is btetest=x[,y[,z]] etc. The - * individual setting order is constant. NOTE: The btetest flag - * is checked for in the bte_init_node function. - * - **********************************************************************/ - - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Silicon Graphics, Inc."); -MODULE_DESCRIPTION("Test the Block Transfer Engine(BTE) " - "present on SGI machines."); - -MODULE_PARM(selected_tests, "1i"); -MODULE_PARM_DESC(selected_tests, "Bitmask of tests to run."); - -MODULE_PARM(verbose, "1i"); -MODULE_PARM_DESC(verbose, - "How much information should be " - "printed during the tests."); - -MODULE_PARM(hang_timeout, "1i"); -MODULE_PARM_DESC(hang_timeout, - "Number of seconds to wait for the Bte " - "Notification Failure."); - -MODULE_PARM(hang_usec, "1i"); -MODULE_PARM_DESC(hang_usec, - "Number of micro-seconds to wait for the 4-line Bte " - "transfer to complete."); - -MODULE_PARM(tm_min_lines, "1i"); -MODULE_PARM_DESC(tm_min_lines, "Minimum number of cache lines" - " to time with."); - -MODULE_PARM(tm_max_lines, "1i"); -MODULE_PARM_DESC(tm_max_lines, "Maximum number of cache lines" - " to time with."); - -MODULE_PARM(tm_iterations, "1i"); -MODULE_PARM_DESC(tm_iterations, "Rerun each timed transfer this " - "many times."); - -MODULE_PARM(tm_alternate, "1i"); -MODULE_PARM_DESC(tm_alternate, "Cycle across cpus between each " - "iteration"); - -MODULE_PARM(tm_memcpy, "1i"); -MODULE_PARM_DESC(tm_memcpy, "Use memcpy as a comparison to BTE"); - -MODULE_PARM(ix_iterations, "1i"); -MODULE_PARM_DESC(ix_iterations, "Rerun each transfer from an " - "invalid nasid this many times."); - -MODULE_PARM(ix_srcnasid, "1i"); -MODULE_PARM_DESC(ix_srcnasid, "Nasid to attempt xfer from."); - - -#if !defined(MODULE) -__setup("btetest=", brt_setup); -#endif /* !defined(MODULE) */ - - -module_init(brt_test_init); -module_exit(brt_test_exit); diff -urN linux-2.4.21/arch/ia64/sn/kernel/idle.c linux-2.4.22/arch/ia64/sn/kernel/idle.c --- linux-2.4.21/arch/ia64/sn/kernel/idle.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/kernel/idle.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,36 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2001-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include + +void snidle(int state) { + if (state) { + if (pda.idle_flag == 0) { + /* + * Turn the activity LED off. + */ + set_led_bits(0, LED_CPU_ACTIVITY); + } + +#ifdef CONFIG_IA64_SGI_SN_SIM + if (IS_RUNNING_ON_SIMULATOR()) + SIMULATOR_SLEEP(); +#endif + + pda.idle_flag = 1; + } else { + /* + * Turn the activity LED on. + */ + set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY); + + pda.idle_flag = 0; + } +} diff -urN linux-2.4.21/arch/ia64/sn/kernel/iomv.c linux-2.4.22/arch/ia64/sn/kernel/iomv.c --- linux-2.4.21/arch/ia64/sn/kernel/iomv.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/iomv.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,115 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include - -extern void * sn_io_addr(unsigned long port); /* defined in sn[12]/iomv.c */ - -/** - * sn_inb - read a byte from a port - * @port: port to read from - * - * Reads a byte from @port and returns it to the caller. - */ -unsigned int -sn_inb (unsigned long port) -{ - volatile unsigned char *addr = sn_io_addr(port); - unsigned char ret; - - ret = *addr; - __ia64_mf_a(); - return ret; -} - -/** - * sn_inw - read a word from a port - * @port: port to read from - * - * Reads a word from @port and returns it to the caller. - */ -unsigned int -sn_inw (unsigned long port) -{ - volatile unsigned short *addr = sn_io_addr(port); - unsigned short ret; - - ret = *addr; - __ia64_mf_a(); - return ret; -} - -/** - * sn_inl - read a word from a port - * @port: port to read from - * - * Reads a word from @port and returns it to the caller. - */ -unsigned int -sn_inl (unsigned long port) -{ - volatile unsigned int *addr = sn_io_addr(port); - unsigned int ret; - - ret = *addr; - __ia64_mf_a(); - return ret; -} - -/** - * sn_outb - write a byte to a port - * @port: port to write to - * @val: value to write - * - * Writes @val to @port. - */ -void -sn_outb (unsigned char val, unsigned long port) -{ - volatile unsigned char *addr = sn_io_addr(port); - - *addr = val; -} - -/** - * sn_outw - write a word to a port - * @port: port to write to - * @val: value to write - * - * Writes @val to @port. - */ -void -sn_outw (unsigned short val, unsigned long port) -{ - volatile unsigned short *addr = sn_io_addr(port); - - *addr = val; -} - -/** - * sn_outl - write a word to a port - * @port: port to write to - * @val: value to write - * - * Writes @val to @port. - */ -void -sn_outl (unsigned int val, unsigned long port) -{ - volatile unsigned int *addr = sn_io_addr(port); - - *addr = val; -} - -EXPORT_SYMBOL(sn_inb); -EXPORT_SYMBOL(sn_inw); -EXPORT_SYMBOL(sn_inl); -EXPORT_SYMBOL(sn_outb); -EXPORT_SYMBOL(sn_outw); -EXPORT_SYMBOL(sn_outl); diff -urN linux-2.4.21/arch/ia64/sn/kernel/irq.c linux-2.4.22/arch/ia64/sn/kernel/irq.c --- linux-2.4.21/arch/ia64/sn/kernel/irq.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* - * Platform dependent support for SGI SN1 + * Platform dependent support for SGI SN * - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -32,12 +32,13 @@ * http://oss.sgi.com/projects/GenInfo/NoticeExplan */ -#include #include #include +#include #include #include #include +#include #include #include #include @@ -49,18 +50,23 @@ #include #include #include -#ifdef ajmtestintr #include #include -#endif /* ajmtestintr */ #include #include #include #include #include #include +#include +#include +#include +#include int irq_to_bit_pos(int irq); +static void force_interrupt(int irq); +extern void pcibr_force_interrupt(pcibr_intr_t intr); +extern int sn_force_interrupt_flag; @@ -88,49 +94,11 @@ static void sn_ack_irq(unsigned int irq) { -#ifdef CONFIG_IA64_SGI_SN1 - int bit = -1; - unsigned long long intpend_val; - int subnode; -#endif -#ifdef CONFIG_IA64_SGI_SN2 unsigned long event_occurred, mask = 0; -#endif int nasid; irq = irq & 0xff; nasid = smp_physical_node_id(); -#ifdef CONFIG_IA64_SGI_SN1 - subnode = cpuid_to_subnode(smp_processor_id()); - if (irq == SGI_UART_IRQ) { - intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0); - if (intpend_val & (1L<> 8; - irq = irq & 0xff; + irq = SN_IVEC_FROM_IRQ(irq); - return(_sn_irq_desc[cpu] + irq); + return(_irq_desc + irq); } u8 sn_irq_to_vector(u8 irq) { - return(irq & 0xff); + return(irq); } unsigned int @@ -226,47 +175,24 @@ return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector)); } -void *kmalloc(size_t, int); - void sn_irq_init (void) { int i; irq_desc_t *base_desc = _irq_desc; - for (i=IA64_FIRST_DEVICE_VECTOR; i 118) bit = 118; -#ifdef CONFIG_IA64_SGI_SN1 - if (bit >= GFX_INTR_A && bit <= CC_PEND_B) { - return SGI_UART_IRQ; - } -#endif - return bit + BIT_TO_IRQ; } @@ -278,53 +204,183 @@ return bit; } -#ifdef ajmtestintr - -#include -struct timer_list intr_test_timer; -int intr_test_icount[NR_IRQS]; -struct intr_test_reg_struct { - pcibr_soft_t pcibr_soft; - int slot; +struct pcibr_intr_list_t { + struct pcibr_intr_list_t *next; + pcibr_intr_t intr; }; -struct intr_test_reg_struct intr_test_registered[NR_IRQS]; + +static struct pcibr_intr_list_t **pcibr_intr_list; void -intr_test_handle_timer(unsigned long data) { +register_pcibr_intr(int irq, pcibr_intr_t intr) { + struct pcibr_intr_list_t *p = kmalloc(sizeof(struct pcibr_intr_list_t), GFP_KERNEL); + struct pcibr_intr_list_t *list; + int cpu = SN_CPU_FROM_IRQ(irq); + + if (pcibr_intr_list == NULL) { + pcibr_intr_list = kmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS, GFP_KERNEL); + if (pcibr_intr_list == NULL) + pcibr_intr_list = vmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS); + if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n"); + memset( (void *)pcibr_intr_list, 0, sizeof(struct pcibr_intr_list_t *) * NR_IRQS); + } + if (pdacpu(cpu).sn_last_irq < irq) { + pdacpu(cpu).sn_last_irq = irq; + } + if (pdacpu(cpu).sn_first_irq > irq) pdacpu(cpu).sn_first_irq = irq; + if (!p) panic("Could not allocate memory for pcibr_intr_list_t\n"); + if ((list = pcibr_intr_list[irq])) { + while (list->next) list = list->next; + list->next = p; + p->next = NULL; + p->intr = intr; + } else { + pcibr_intr_list[irq] = p; + p->next = NULL; + p->intr = intr; + } +} + +void +force_polled_int(void) { int i; - bridge_t *bridge; + struct pcibr_intr_list_t *p; - for (i=0;ibs_intr[intr_test_registered[i].slot].bsi_xtalk_intr; - /* send interrupt */ - bridge = pcibr_soft->bs_base; - bridge->b_force_always[intr_test_registered[i].slot].intr = 1; + for (i=0; iintr){ + pcibr_force_interrupt(p->intr); + } + p = p->next; } } - del_timer(&intr_test_timer); - intr_test_timer.expires = jiffies + HZ/100; - add_timer(&intr_test_timer); } -void -intr_test_set_timer(void) { - intr_test_timer.expires = jiffies + HZ/100; - intr_test_timer.function = intr_test_handle_timer; - add_timer(&intr_test_timer); +static void +force_interrupt(int irq) { + struct pcibr_intr_list_t *p = pcibr_intr_list[irq]; + + while (p) { + if (p->intr) { + pcibr_force_interrupt(p->intr); + } + p = p->next; + } +} + +/* +Check for lost interrupts. If the PIC int_status reg. says that +an interrupt has been sent, but not handled, and the interrupt +is not pending in either the cpu irr regs or in the soft irr regs, +and the interrupt is not in service, then the interrupt may have +been lost. Force an interrupt on that pin. It is possible that +the interrupt is in flight, so we may generate a spurious interrupt, +but we should never miss a real lost interrupt. +*/ + +static void +sn_check_intr(int irq, pcibr_intr_t intr) { + unsigned long regval; + int irr_reg_num; + int irr_bit; + unsigned long irr_reg; + + + regval = intr->bi_soft->bs_base->p_int_status_64; + irr_reg_num = irq_to_vector(irq) / 64; + irr_bit = irq_to_vector(irq) % 64; + switch (irr_reg_num) { + case 0: + irr_reg = ia64_get_irr0(); + break; + case 1: + irr_reg = ia64_get_irr1(); + break; + case 2: + irr_reg = ia64_get_irr2(); + break; + case 3: + irr_reg = ia64_get_irr3(); + break; + } + if (!test_bit(irr_bit, &irr_reg) ) { + if (!test_bit(irq, pda.sn_soft_irr) ) { + if (!test_bit(irq, pda.sn_in_service_ivecs) ) { + regval &= 0xff; + if (intr->bi_ibits & regval & intr->bi_last_intr) { + regval &= ~(intr->bi_ibits & regval); + pcibr_force_interrupt(intr); + } + } + } + } + intr->bi_last_intr = regval; } void -intr_test_register_irq(int irq, pcibr_soft_t pcibr_soft, int slot) { - irq = irq & 0xff; - intr_test_registered[irq].pcibr_soft = pcibr_soft; - intr_test_registered[irq].slot = slot; +sn_lb_int_war_check(void) { + int i; + + if (pda.sn_first_irq == 0) return; + for (i=pda.sn_first_irq; + i <= pda.sn_last_irq; i++) { + struct pcibr_intr_list_t *p = pcibr_intr_list[i]; + if (p == NULL) { + continue; + } + while (p) { + sn_check_intr(i, p->intr); + p = p->next; + } + } +} + +static inline int +sn_get_next_bit(void) { + int i; + int bit; + + for (i = 3; i >= 0; i--) { + if (pda.sn_soft_irr[i] != 0) { + bit = (i * 64) + __ffs(pda.sn_soft_irr[i]); + __change_bit(bit, (volatile void *)pda.sn_soft_irr); + return(bit); + } + } + return IA64_SPURIOUS_INT_VECTOR; } void -intr_test_handle_intr(int irq, void *junk, struct pt_regs *morejunk) { - intr_test_icount[irq]++; - printk("RECEIVED %d INTERRUPTS ON IRQ %d\n",intr_test_icount[irq], irq); +sn_set_tpr(int vector) { + if (vector > IA64_LAST_DEVICE_VECTOR || vector < IA64_FIRST_DEVICE_VECTOR) { + ia64_set_tpr(vector); + } else { + ia64_set_tpr(IA64_LAST_DEVICE_VECTOR); + } +} + +static inline void +sn_get_all_ivr(void) { + int vector; + + vector = ia64_get_ivr(); + while (vector != IA64_SPURIOUS_INT_VECTOR) { + __set_bit(vector, (volatile void *)pda.sn_soft_irr); + ia64_eoi(); + if (vector > IA64_LAST_DEVICE_VECTOR) return; + vector = ia64_get_ivr(); + } +} + +int +sn_get_ivr(void) { + int vector; + + vector = sn_get_next_bit(); + if (vector == IA64_SPURIOUS_INT_VECTOR) { + sn_get_all_ivr(); + vector = sn_get_next_bit(); + } + return vector; } -#endif /* ajmtestintr */ diff -urN linux-2.4.21/arch/ia64/sn/kernel/llsc4.c linux-2.4.22/arch/ia64/sn/kernel/llsc4.c --- linux-2.4.21/arch/ia64/sn/kernel/llsc4.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/kernel/llsc4.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1044 +0,0 @@ -/* - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "llsc4.h" - - -#ifdef STANDALONE -#include "lock.h" -#endif - -#ifdef INTTEST -static int inttest=0; -#endif - -#ifdef IA64_SEMFIX_INSN -#undef IA64_SEMFIX_INSN -#endif -#ifdef IA64_SEMFIX -#undef IA64_SEMFIX -#endif -# define IA64_SEMFIX_INSN -# define IA64_SEMFIX "" - -#define NOLOCK 0xdead -#define BGUARD(linei) (0xbbbb0000 | (linei)); -#define EGUARD(linei) (0xeeee0000 | (linei)); -#define GUARDLINE(v) ((v)&0xffff) - -/* - * Test parameter table for AUTOTEST - */ -typedef struct { - int passes; - int linecount; - int linepad; -} autotest_table_t; - -autotest_table_t autotest_table[] = { - {50000000, 2, 0x2b4 }, - {50000000, 16, 0, }, - {50000000, 16, 4, }, - {50000000, 128, 0x44 }, - {50000000, 128, 0x84 }, - {50000000, 128, 0x200 }, - {50000000, 128, 0x204 }, - {50000000, 128, 0x2b4 }, - {50000000, 2, 8*MB+0x2b4 }, - {50000000, 16, 8*MB+0 }, - {50000000, 16, 8*MB+4 }, - {50000000, 128, 8*MB+0x44 }, - {50000000, 128, 8*MB+0x84 }, - {50000000, 128, 8*MB+0x200 }, - {50000000, 128, 8*MB+0x204 }, - {50000000, 128, 8*MB+0x2b4 }, - {0}}; - -/* - * Array of virtual addresses available for test purposes. - */ - -typedef struct { - long vstart; - long vend; - long nextaddr; - long nextinit; - int wrapcount; -} memmap_t; - -#define MAPCHUNKS 128 -memmap_t memmap[MAPCHUNKS]; -int memmapx=0; - -typedef struct { - void *addr; - long data[16]; - long data_fc[16]; -} capture_line_t; - -typedef struct { - int size; - void *blockaddr; - void *shadaddr; - long blockdata[48]; - long shaddata[48]; - long blockdata_fc[48]; - long shaddata_fc[48]; - long synerr; -} capture_t; - -/* - * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and - * the rest of the tables have to start at 1MB to skip PROM tables. - */ -#define THREADPRIVATESZ() ((sizeof(threadprivate_t)+511)/512*512) -#define THREADPRIVATE(t) ((threadprivate_t*)(((long)mbase)+4096+t*THREADPRIVATESZ())) - -#define k_capture mbase->sk_capture -#define k_go mbase->sk_go -#define k_linecount mbase->sk_linecount -#define k_passes mbase->sk_passes -#define k_napticks mbase->sk_napticks -#define k_stop_on_error mbase->sk_stop_on_error -#define k_verbose mbase->sk_verbose -#define k_threadprivate mbase->sk_threadprivate -#define k_blocks mbase->sk_blocks -#define k_iter_msg mbase->sk_iter_msg -#define k_vv mbase->sk_vv -#define k_linepad mbase->sk_linepad -#define k_options mbase->sk_options -#define k_testnumber mbase->sk_testnumber -#define k_currentpass mbase->sk_currentpass - -static long blocks[MAX_LINECOUNT]; /* addresses of data blocks */ -static control_t *mbase; -static vint initialized=0; - -static unsigned int ran_conf_llsc(int); -static int rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int); -static void dumpline(void *, char *, char *, void *, void *, int); -static int checkstop(int, int, uint); -static void spin(int); -static void capturedata(capture_t *, uint, void *, void *, int); -static int randn(uint max, uint *seed); -static uint zrandom (uint *zranseed); -static int set_lock(uint *, uint); -static int clr_lock(uint *, uint); -static void Speedo(void); - -int autotest_enabled=0; -static int llsctest_number=-1; -static int errstop_enabled=0; -static int fail_enabled=0; -static int l4_opt=0; -static int selective_trigger=0; -static int dump_block_addrs_opt=0; -static lock_t errlock=NOLOCK; -static private_t init_private[LLSC_MAXCPUS]; - -static int __init autotest_enable(char *str) -{ - autotest_enabled = 1; - return 1; -} -static int __init set_llscblkadr(char *str) -{ - dump_block_addrs_opt = 1; - return 1; -} -static int __init set_llscselt(char *str) -{ - selective_trigger = 1; - return 1; -} -static int __init set_llsctest(char *str) -{ - llsctest_number = simple_strtol(str, &str, 10); - if (llsctest_number < 0 || llsctest_number > 15) - llsctest_number = -1; - return 1; -} -static int __init set_llscerrstop(char *str) -{ - errstop_enabled = 1; - return 1; -} -static int __init set_llscfail(char *str) -{ - fail_enabled = 8; - return 1; -} -static int __init set_llscl4(char *str) -{ - l4_opt = 1; - return 1; -} - -static void print_params(void) -{ - printk ("********* Enter AUTOTEST facility on master cpu *************\n"); - printk (" Test options:\n"); - printk (" llsctest=\t%d\tTest number to run (all = -1)\n", llsctest_number); - printk (" llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off"); - printk (" llscfail \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off"); - printk (" llscselt \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off"); - printk (" llscblkadr \t%s\tDump data block addresses\n", dump_block_addrs_opt ? "on" : "off"); - printk (" llscl4 \t%s\tRun only tests that evict from L4\n", l4_opt ? "on" : "off"); - printk (" SEMFIX: %s\n", IA64_SEMFIX); - printk ("\n"); -} -__setup("autotest", autotest_enable); -__setup("llsctest=", set_llsctest); -__setup("llscerrstop", set_llscerrstop); -__setup("llscfail", set_llscfail); -__setup("llscselt", set_llscselt); -__setup("llscblkadr", set_llscblkadr); -__setup("llscl4", set_llscl4); - - - -static inline int -set_lock(uint *lock, uint id) -{ - uint old; - old = cmpxchg_acq(lock, NOLOCK, id); - return (old == NOLOCK); -} - -static inline int -clr_lock(uint *lock, uint id) -{ - uint old; - old = cmpxchg_rel(lock, id, NOLOCK); - return (old == id); -} - -static inline void -init_lock(uint *lock) -{ - *lock = NOLOCK; -} - -/*------------------------------------------------------------------------+ -| Routine : ran_conf_llsc - ll/sc shared data test | -| Description: This test checks the coherency of shared data | -+------------------------------------------------------------------------*/ -static unsigned int -ran_conf_llsc(int thread) -{ - private_t pval; - share_t sval, sval2; - uint vv, linei, slinei, sharei, pass; - long t; - lock_t lockpat; - share_t *sharecopy; - long verbose, napticks, passes, linecount, lcount; - dataline_t *linep, *slinep; - int s, seed; - threadprivate_t *tp; - uint iter_msg, iter_msg_i=0; - int vv_mask; - int correct_errors; - int errs=0; - int stillbad; - capture_t capdata; - private_t *privp; - share_t *sharep; - - - linecount = k_linecount; - napticks = k_napticks; - verbose = k_verbose; - passes = k_passes; - iter_msg = k_iter_msg; - seed = (thread + 1) * 647; - tp = THREADPRIVATE(thread); - vv_mask = (k_vv>>((thread%16)*4)) & 0xf; - correct_errors = k_options&0xff; - - memset (&capdata, 0, sizeof(capdata)); - for (linei=0; lineiprivate[linei] = thread; - - for (pass = 1; passes == 0 || pass < passes; pass++) { - lockpat = (pass & 0x0fffffff) + (thread <<28); - if (lockpat == NOLOCK) - continue; - tp->threadpasses = pass; - if (checkstop(thread, pass, lockpat)) - return 0; - iter_msg_i++; - if (iter_msg && iter_msg_i > iter_msg) { - printk("Thread %d, Pass %d\n", thread, pass); - iter_msg_i = 0; - } - lcount = 0; - - /* - * Select line to perform operations on. - */ - linei = randn(linecount, &seed); - sharei = randn(2, &seed); - slinei = (linei + (linecount/2))%linecount; /* I dont like this - fix later */ - - linep = (dataline_t *)blocks[linei]; - slinep = (dataline_t *)blocks[slinei]; - if (sharei == 0) - sharecopy = &slinep->share0; - else - sharecopy = &slinep->share1; - - - vv = randn(4, &seed); - if ((vv_mask & (1<private[thread]; - sharep = &linep->share[sharei]; - - switch(vv) { - case 0: - /* Read and verify private count on line. */ - pval = *privp; - if (verbose) - printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]); - if (pval != tp->private[linei]) { - capturedata(&capdata, pass, privp, NULL, sizeof(*privp)); - stillbad = (*privp != tp->private[linei]); - if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) { - return 1; - } - if (correct_errors) { - tp->private[linei] = *privp; - } - errs++; - } - break; - - case 1: - /* Read, verify, and increment private count on line. */ - pval = *privp; - if (verbose) - printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]); - if (pval != tp->private[linei]) { - capturedata(&capdata, pass, privp, NULL, sizeof(*privp)); - stillbad = (*privp != tp->private[linei]); - if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) { - return 1; - } - errs++; - } - pval = (pval==255) ? 0 : pval+1; - *privp = pval; - tp->private[linei] = pval; - break; - - case 2: - /* Lock line, read and verify shared data. */ - if (verbose) - printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy); - lcount = 0; - while (LOCK(sharei) != 1) { - if (checkstop(thread, pass, lockpat)) - return 0; - if (lcount++>1000000) { - capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t)); - stillbad = (GETLOCK(sharei) != 0); - rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad); - return 1; - } - if ((lcount&0x3fff) == 0) - udelay(1000); - } - - sval = *sharep; - sval2 = *sharecopy; - if (pass > 12 && thread == 0 && fail_enabled == 1) - sval++; - if (sval != sval2) { - capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy)); - stillbad = (*sharep != *sharecopy); - if (!stillbad && *sharep != sval && *sharecopy == sval2) - stillbad = 2; - if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) { - return 1; - } - if (correct_errors) - *sharep = *sharecopy; - errs++; - } - - - if ( (s=UNLOCK(sharei)) != 1) { - capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4); - stillbad = (GETLOCK(sharei) != lockpat); - if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad)) - return 1; - if (correct_errors) - ZEROLOCK(sharei); - errs++; - } - break; - - case 3: - /* Lock line, read and verify shared data, modify shared data. */ - if (verbose) - printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy); - lcount = 0; - while (LOCK(sharei) != 1) { - if (checkstop(thread, pass, lockpat)) - return 0; - if (lcount++>1000000) { - capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t)); - stillbad = (GETLOCK(sharei) != 0); - rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad); - return 1; - } - if ((lcount&0x3fff) == 0) - udelay(1000); - } - sval = *sharep; - sval2 = *sharecopy; - if (sval != sval2) { - capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy)); - stillbad = (*sharep != *sharecopy); - if (!stillbad && *sharep != sval && *sharecopy == sval2) - stillbad = 2; - if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) { - return 1; - } - errs++; - } - - *sharep = lockpat; - *sharecopy = lockpat; - - - if ( (s=UNLOCK(sharei)) != 1) { - capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4); - stillbad = (GETLOCK(sharei) != lockpat); - if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad)) - return 1; - if (correct_errors) - ZEROLOCK(sharei); - errs++; - } - break; - } - } - - return (errs > 0); -} - -static void -trigger_la(long val) -{ - long *p; - - p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */ - *p = val; -} - -static long -getsynerr(void) -{ - long err, *errp; - - errp = (long*)0xc0000e0000000340L; /* SYN_ERR */ - err = *errp; - if (err) - *errp = -1L; - return (err & ~0x60); -} - -static int -rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int badlinei, int exp, int found, int stillbad) -{ - int cpu, i, linei; - long synerr; - int selt; - - - selt = selective_trigger && stillbad > 1 && - memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 && - memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0; - if (selt) { - trigger_la(pass); - } else if (selective_trigger) { - k_go = ST_STOP; - return k_stop_on_error;; - } - - spin(1); - i = 100; - while (i && set_lock(&errlock, 1) != 1) { - spin(1); - i--; - } - printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n", - msg, k_testnumber, thread, badlinei, pass, pass, jiffies, exp, found); - - dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size); -#ifdef ZZZ - if (memcmp(cap->blockdata, cap->blockdata_fc, 128)) - dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size); -#endif - - if (cap->shadaddr) { - dumpline (slp, "Shadow data", "S ", cap->shadaddr, cap->shaddata, cap->size); -#ifdef ZZZ - if (memcmp(cap->shaddata, cap->shaddata_fc, 128)) - dumpline (slp, "Shadow data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size); -#endif - } - - printk("Threadpasses: "); - for (cpu=0,i=0; cputhreadpasses) { - if (i && (i%8) == 0) - printk("\n : "); - printk(" %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses); - i++; - } - printk("\n"); - - for (linei=0; lineiguard1); - g2linei = GUARDLINE(linep->guard2); - g1err = (g1linei != linei); - g2err = (g2linei != linei); - sh0err = (linep->share[0] != slinep->share0); - sh1err = (linep->share[1] != slinep->share1); - - if (g1err || g2err || sh0err || sh1err) { - printk("Line 0x%lx (%03d), %sG1 0x%lx (%03d), %sG2 0x%lx (%03d), %sSH0 %08x (%08x), %sSH1 %08x (%08x)\n", - blocks[linei], linei, - g1err ? "*" : " ", blocks[g1linei], g1linei, - g2err ? "*" : " ", blocks[g2linei], g2linei, - sh0err ? "*" : " ", linep->share[0], slinep->share0, - sh1err ? "*" : " ", linep->share[1], slinep->share1); - - - } - } - - printk("\nData was %sfixed by flushcache\n", (stillbad == 1 ? "**** NOT **** " : " ")); - synerr = getsynerr(); - if (synerr) - printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr); - spin(2); - printk("\n\n"); - clr_lock(&errlock, 1); - - if (errstop_enabled) { - local_irq_disable(); - while(1); - } - return k_stop_on_error; -} - - -static void -dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size) -{ - long *p; - int i, off; - - printk("%s at 0x%lx, size %d, block starts at 0x%lx\n", str1, (long)addr, size, (long)lp); - p = (long*) data; - for (i=0; i<48; i++, p++) { - if (i%8 == 0) printk("%2s", i==16 ? str2 : " "); - printk(" %016lx", *p); - if ((i&7)==7) printk("\n"); - } - printk(" "); - off = (((long)addr) ^ size) & 63L; - for (i=0; i=off) ? "--" : " "); - if ((i%8) == 7) - printk(" "); - } - - off = ((long)addr) & 127; - printk(" (line %d)\n", 2+off/64+1); -} - - -static int -randn(uint max, uint *seedp) -{ - if (max == 1) - return(0); - else - return((int)(zrandom(seedp)>>10) % max); -} - - -static int -checkstop(int thread, int pass, uint lockpat) -{ - long synerr; - - if (k_go == ST_RUN) - return 0; - if (k_go == ST_STOP) - return 1; - - if (errstop_enabled) { - local_irq_disable(); - while(1); - } - synerr = getsynerr(); - spin(2); - if (k_go == ST_STOP) - return 1; - if (synerr) - printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr); - return 1; -} - - -static void -spin(int j) -{ - udelay(j * 500000); -} - -static void -capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size) -{ - - if (!selective_trigger) - trigger_la (pass); - - memcpy (cap->blockdata, CACHEALIGN(blockaddr)-128, 3*128); - if (shadaddr) - memcpy (cap->shaddata, CACHEALIGN(shadaddr)-128, 3*128); - - if (k_stop_on_error) { - k_go = ST_ERRSTOP; - } - - cap->size = size; - cap->blockaddr = blockaddr; - cap->shadaddr = shadaddr; - - asm volatile ("fc %0" :: "r"(blockaddr) : "memory"); - ia64_sync_i(); - ia64_srlz_d(); - memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr)-128, 3*128); - - if (shadaddr) { - asm volatile ("fc %0" :: "r"(shadaddr) : "memory"); - ia64_sync_i(); - ia64_srlz_d(); - memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr)-128, 3*128); - } -} - -int zranmult = 0x48c27395; - -static uint -zrandom (uint *seedp) -{ - *seedp = (*seedp * zranmult) & 0x7fffffff; - return (*seedp); -} - - -void -set_autotest_params(void) -{ - static int testnumber=-1; - - if (llsctest_number >= 0) { - testnumber = llsctest_number; - } else { - testnumber++; - if (autotest_table[testnumber].passes == 0) { - testnumber = 0; - dump_block_addrs_opt = 0; - } - } - if (testnumber == 0 && l4_opt) testnumber = 9; - - k_passes = autotest_table[testnumber].passes; - k_linepad = autotest_table[testnumber].linepad; - k_linecount = autotest_table[testnumber].linecount; - k_testnumber = testnumber; - - if (IS_RUNNING_ON_SIMULATOR()) { - printk ("llsc start test %ld\n", k_testnumber); - k_passes = 1000; - } -} - - -static void -set_leds(int errs) -{ - unsigned char leds=0; - - /* - * Leds are: - * ppppeee- - * where - * pppp = test number - * eee = error count but top bit is stick - */ - - leds = ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0); - set_led_bits(leds, LED_MASK_AUTOTEST); -} - -static void -setup_block_addresses(void) -{ - int i, stride, memmapi; - dataline_t *dp; - long *ip, *ipe; - - - stride = k_linepad + sizeof(dataline_t); - memmapi = 0; - for (i=0; i= memmap[memmapi].vend) { - memmap[memmapi].wrapcount++; - memmap[memmapi].nextaddr = memmap[memmapi].vstart + - memmap[memmapi].wrapcount * sizeof(dataline_t); - } - - ip = (long*)((memmap[memmapi].nextinit+7)&~7); - ipe = (long*)(memmap[memmapi].nextaddr+2*sizeof(dataline_t)+8); - while(ip <= ipe && ip < ((long*)memmap[memmapi].vend-8)) - *ip++ = (long)ip; - memmap[memmapi].nextinit = (long) ipe; - dp->guard1 = BGUARD(i); - dp->guard2 = EGUARD(i); - dp->lock[0] = dp->lock[1] = NOLOCK; - dp->share[0] = dp->share0 = 0x1111; - dp->share[1] = dp->share1 = 0x2222; - memcpy(dp->private, init_private, LLSC_MAXCPUS*sizeof(private_t)); - - - if (stride > 16384) { - memmapi++; - if (memmapi == memmapx) - memmapi = 0; - } - } - -} - -static void -dump_block_addrs(void) -{ - int i; - - printk("LLSC TestNumber %ld\n", k_testnumber); - - for (i=0; ithreadstate == TS_KILLED) { - set_led_bits(LED_MASK_AUTOTEST, LED_MASK_AUTOTEST); - while(1); - } - k_threadprivate[cpuid]->threadstate = state; -} - -#define MINBLK (16*1024*1024) -static int -build_mem_map(unsigned long start, unsigned long end, void *arg) -{ - long lstart, lend; - long align = 8*MB; - - printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)\n", - start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE)); - - if (memmapx >= MAPCHUNKS || (end-start) < MINBLK) - return 0; - - /* - * Start in the middle of the range & find the first non-free page in both directions - * from the midpoint. This is likely to be the bigest free block. - */ - lend = lstart = start + (end-start)/2; - while (lend < end && !PageReserved(virt_to_page(lend)) && virt_to_page(lend)->count.counter == 0) - lend += PAGE_SIZE; - lend -= PAGE_SIZE; - - while (lstart >= start && !PageReserved(virt_to_page(lstart)) && virt_to_page(lstart)->count.counter == 0) - lstart -= PAGE_SIZE; - lstart += PAGE_SIZE; - - lstart = (lstart + align -1) /align * align; - end = end / align * align; - if (lstart >= end) - return 0; - printk (" memmap: start 0x%lx, end 0x%lx\n", lstart, end); - - memmap[memmapx].vstart = lstart; - memmap[memmapx].vend = end; - memmapx++; - return 0; -} - -void int_test(void); - -int -llsc_main (int cpuid) -{ - int i, cpu, is_master, repeatcnt=0; - unsigned int preverr=0, errs=0, pass=0; - int automode=0; - -#ifdef INTTEST - if (inttest) - int_test(); -#endif - - if (!autotest_enabled) - return 0; - -#ifdef CONFIG_SMP - is_master = !smp_processor_id(); -#else - is_master = 1; -#endif - - - if (is_master) { - mbase = (control_t*) __get_free_pages(GFP_KERNEL, get_order(4096+THREADPRIVATESZ()*LLSC_MAXCPUS)); - printk("LLSC: mbase 0x%lx\n", (long)mbase); - print_params(); - if(!IS_RUNNING_ON_SIMULATOR()) - spin(10); - k_currentpass = 0; - k_go = ST_IDLE; - k_passes = DEF_PASSES; - k_napticks = DEF_NAPTICKS; - k_stop_on_error = DEF_STOP_ON_ERROR; - k_verbose = DEF_VERBOSE; - k_linecount = DEF_LINECOUNT; - k_iter_msg = DEF_ITER_MSG; - k_vv = DEF_VV; - k_linepad = DEF_LINEPAD; - k_blocks = (void*)blocks; - efi_memmap_walk(build_mem_map, 0); - -#ifdef CONFIG_IA64_SGI_AUTOTEST - automode = 1; -#endif - - for (i=0; i 5) { - set_autotest_params(); - repeatcnt = 0; - } - } else { - while (k_go == ST_IDLE); - } - - k_go = ST_INIT; - if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT; - k_linecount = k_linecount & ~1; - setup_block_addresses(); - if (!preverr && dump_block_addrs_opt) - dump_block_addrs(); - - k_currentpass = pass++; - k_go = ST_RUN; - if (fail_enabled) - fail_enabled--; - - } else { - while (k_go != ST_RUN || k_currentpass != pass); - pass++; - } - - - set_leds(errs); - set_thread_state(cpuid, TS_RUNNING); - - errs += ran_conf_llsc(cpuid); - preverr = (k_go == ST_ERRSTOP); - - set_leds(errs); - set_thread_state(cpuid, TS_STOPPED); - - if (is_master) { - Speedo(); - for (i=0, cpu=0; cputhreadstate == TS_RUNNING) { - i++; - if (i == 10000) { - k_go = ST_STOP; - printk (" llsc master stopping test number %ld\n", k_testnumber); - } - if (i > 100000) { - k_threadprivate[cpu]->threadstate = TS_KILLED; - printk (" llsc: master killing cpuid %d, running test number %ld\n", - cpu, k_testnumber); - } - udelay(1000); - } - } - } - - goto loop; -} - - -static void -Speedo(void) -{ - static int i = 0; - - switch (++i%4) { - case 0: - printk("|\b"); - break; - case 1: - printk("\\\b"); - break; - case 2: - printk("-\b"); - break; - case 3: - printk("/\b"); - break; - } -} - -#ifdef INTTEST - -/* ======================================================================================================== - * - * Some test code to verify that interrupts work - * - * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback" - * if (zzzprint_resched) printk(" cpu %d got interrupt\n", smp_processor_id()); - * - * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs. - * - */ - -static int __init set_inttest(char *str) -{ - inttest = 1; - autotest_enabled = 1; - - return 1; -} - -__setup("inttest=", set_inttest); - -int zzzprint_resched=0; - -void -int_test() { - int mycpu, cpu; - static volatile int control_cpu=0; - - mycpu = smp_processor_id(); - zzzprint_resched = 2; - - printk("Testing cross interrupts\n"); - - while (control_cpu != smp_num_cpus) { - if (mycpu == cpu_logical_map(control_cpu)) { - for (cpu=0; cpulock[(i)] -#define LOCK(i) set_lock(LOCKADDR(i), lockpat) -#define UNLOCK(i) clr_lock(LOCKADDR(i), lockpat) -#define GETLOCK(i) *LOCKADDR(i) -#define ZEROLOCK(i) init_lock(LOCKADDR(i)) - -#define CACHEALIGN(a) ((char*)((long)(a) & ~127L)) - -typedef uint guard_t; -typedef uint lock_t; -typedef uint share_t; -typedef uchar private_t; - -typedef struct { - guard_t guard1; - lock_t lock[2]; - share_t share[2]; - private_t private[LLSC_MAXCPUS]; - share_t share0; - share_t share1; - guard_t guard2; -} dataline_t ; - - -#define LINEPAD k_linepad -#define LINESTRIDE (((sizeof(dataline_t)+CACHELINE-1)/CACHELINE)*CACHELINE + LINEPAD) - - -typedef struct { - vint threadstate; - uint threadpasses; - private_t private[MAX_LINECOUNT]; -} threadprivate_t; - -typedef struct { - vlong sk_go; /* 0=idle, 1=init, 2=run */ - long sk_linecount; - long sk_passes; - long sk_napticks; - long sk_stop_on_error; - long sk_verbose; - long sk_iter_msg; - long sk_vv; - long sk_linepad; - long sk_options; - long sk_testnumber; - vlong sk_currentpass; - void *sk_blocks; - threadprivate_t *sk_threadprivate[LLSC_MAXCPUS]; -} control_t; - -/* Run state (k_go) constants */ -#define ST_IDLE 0 -#define ST_INIT 1 -#define ST_RUN 2 -#define ST_STOP 3 -#define ST_ERRSTOP 4 - - -/* Threadstate constants */ -#define TS_STOPPED 0 -#define TS_RUNNING 1 -#define TS_KILLED 2 - - - -int llsc_main (int cpuid); - diff -urN linux-2.4.21/arch/ia64/sn/kernel/machvec.c linux-2.4.22/arch/ia64/sn/kernel/machvec.c --- linux-2.4.21/arch/ia64/sn/kernel/machvec.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/machvec.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -30,30 +30,5 @@ * http://oss.sgi.com/projects/GenInfo/NoticeExplan */ -#include - -#ifdef CONFIG_IA64_SGI_SN1 -#define MACHVEC_PLATFORM_NAME sn1 -#else CONFIG_IA64_SGI_SN1 #define MACHVEC_PLATFORM_NAME sn2 -#else -#error "unknown platform" -#endif - #include -#include -#include -void* -sn_mk_io_addr_MACRO - -dma_addr_t -sn_pci_map_single_MACRO - -int -sn_pci_map_sg_MACRO - -unsigned long -sn_virt_to_phys_MACRO - -void * -sn_phys_to_virt_MACRO diff -urN linux-2.4.21/arch/ia64/sn/kernel/mca.c linux-2.4.22/arch/ia64/sn/kernel/mca.c --- linux-2.4.21/arch/ia64/sn/kernel/mca.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/mca.c 2003-08-25 04:44:39.000000000 -0700 @@ -2,7 +2,7 @@ * File: mca.c * Purpose: SN specific MCA code. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -123,9 +123,7 @@ static void sn_cpei_timer_handler(unsigned long dummy) { sn_cpei_handler(-1, NULL, NULL); - del_timer(&sn_cpei_timer); - sn_cpei_timer.expires = jiffies + CPEI_INTERVAL; - add_timer(&sn_cpei_timer); + mod_timer(&sn_cpei_timer, jiffies + CPEI_INTERVAL); } void @@ -134,27 +132,3 @@ sn_cpei_timer.function = sn_cpei_timer_handler; add_timer(&sn_cpei_timer); } - - - - -#ifdef ajmtestceintr - -struct timer_list sn_ce_timer; - -void -sn_ce_timer_handler(long dummy) { - unsigned long *pi_ce_error_inject_reg = 0xc00000092fffff00; - - *pi_ce_error_inject_reg = 0x0000000000000100; - del_timer(&sn_ce_timer); - sn_ce_timer.expires = jiffies + CPEI_INTERVAL; - add_timer(&sn_ce_timer); -} - -sn_init_ce_timer() { - sn_ce_timer.expires = jiffies + CPEI_INTERVAL; - sn_ce_timer.function = sn_ce_timer_handler; - add_timer(&sn_ce_timer); -} -#endif /* ajmtestceintr */ diff -urN linux-2.4.21/arch/ia64/sn/kernel/misctest.c linux-2.4.22/arch/ia64/sn/kernel/misctest.c --- linux-2.4.21/arch/ia64/sn/kernel/misctest.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/misctest.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,371 +0,0 @@ -/* - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int autotest_enabled; -long mcatest=0, debug0, debug1, debug2, debug3; - -#define HDELAY(t) (IS_RUNNING_ON_SIMULATOR() ? udelay(1) : udelay(t)) - -/* - * mcatest - * mactest contains a decimal number (RPTT) where - * R - flag, if non zero, run forever - * - * P - identifies when to run the test - * 0 execute test at cpu 0 early init - * 1 execute test at cpu 0 idle - * 2 execute test at last (highest numbered) cpu idle - * 3 execute test on all cpus at idle - * - * TT- identifies test to run - * 01 = MCA via dup TLB dropin - * 02 = MCA via garbage address - * 03 = lfetch via garbage address - * 05 = INIT self - * 06 = INIT other cpu - * 07 = INIT non-existent cpu - * 10 = IPI stress test. Target cpu 0 - * 11 = IPI stress test. Target all cpus - * 12 = TLB stress test - * 13 = Park cpu (spinloop) - * 14 = One shot TLB test with tlb spinlock - * 15 = One shot TLB test - * 16 = One shot TLB test sync'ed with RTC - * 20 = set led to the cpuid & spin. - * 21 = Try mixed cache/uncached refs & see what happens - * 22 = Call SAL reboot - * 23 = Call PAL halt - */ -static int __init set_mcatest(char *str) -{ - int val; - get_option(&str, &val); - mcatest = val; - return 1; -} -__setup("mcatest=", set_mcatest); - -static int __init set_debug0(char *str) -{ - int val; - get_option(&str, &val); - debug0 = val; - return 1; -} -__setup("debug0=", set_debug0); - -static int __init set_debug1(char *str) -{ - int val; - get_option(&str, &val); - debug1 = val; - return 1; -} -__setup("debug1=", set_debug1); - -static int __init set_debug2(char *str) -{ - int val; - get_option(&str, &val); - debug2 = val; - return 1; -} -__setup("debug2=", set_debug2); - -static int __init set_debug3(char *str) -{ - int val; - get_option(&str, &val); - debug3 = val; - return 1; -} -__setup("debug3=", set_debug3); - -static volatile int go; - -static void -do_sync(int pos) { - if (pos != 3) - return; - else if (smp_processor_id() == 0) - go = 1; - else - while (!go); -} - -static void -sgi_mcatest_bkpt(void) -{ -} - - -/* - * Optional test - * pos - 0 called from early init - * pos - called when cpu about to go idle (fully initialized - */ -void -sgi_mcatest(int pos) -{ - long spos, test, repeat; - int cpu, curcpu, i, n; - - //if (IS_RUNNING_ON_SIMULATOR()) mcatest=1323; - repeat = mcatest/1000; - spos = (mcatest/100)%10; - test = mcatest % 100; - curcpu = smp_processor_id(); - - if ( mcatest == 0 || !((pos == 0 && spos == 0) || - (pos == 1 && spos == 3) || - (pos == 1 && spos == 1 && curcpu == 0) || - (pos == 1 && spos == 2 && curcpu == smp_num_cpus-1))) - return; - -again: - if (test == 1 || test == 2 || test == 3) { - void zzzmca(int); - printk("CPU %d: About to cause unexpected MCA\n", curcpu); - HDELAY(100000); - sgi_mcatest_bkpt(); - do_sync(spos); - - zzzmca(test-1); - - HDELAY(100000); - } - - if (test == 4) { - long result, adrs[] = {0xe0021000009821e0UL, 0xc0003f3000000000UL, 0xc0000081101c0000UL, 0xc00000180e021004UL, 0xc00000180e022004UL, 0xc00000180e023004UL }; - long size[] = {1,2,4,8}; - int r, i, j, k; - - for (k=0; k<2; k++) { - for (i=0; i<6; i++) { - for (j=0; j<4; j++) { - printk("Probing 0x%lx, size %ld\n", adrs[i], size[j]); - result = -1; - r = ia64_sn_probe_io_slot (adrs[i], size[j], &result); - printk(" status %d, val 0x%lx\n", r, result); - udelay(100000); - } - } - } - - } - - if (test == 5) { - cpu = curcpu; - printk("CPU %d: About to send INIT to self (cpu %d)\n", curcpu, cpu); - HDELAY(100000); - sgi_mcatest_bkpt(); - do_sync(spos); - - platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0); - - HDELAY(100000); - printk("CPU %d: Returned from INIT\n", curcpu); - } - - if (test == 6) { - cpu = curcpu ^ 1; - printk("CPU %d: About to send INIT to other cpu (cpu %d)\n", curcpu, cpu); - HDELAY(100000); - sgi_mcatest_bkpt(); - do_sync(spos); - - platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0); - - HDELAY(100000); - printk("CPU %d: Done\n", curcpu); - } - - if (test == 7) { - printk("CPU %d: About to send INIT to non-existent cpu\n", curcpu); - HDELAY(100000); - sgi_mcatest_bkpt(); - do_sync(spos); - - sn_send_IPI_phys(0xffff, 0, IA64_IPI_DM_INIT); - - HDELAY(100000); - printk("CPU %d: Done\n", curcpu); - } - - if (test == 10) { - n = IS_RUNNING_ON_SIMULATOR() ? 10 : 10000000; - cpu = 0; - printk("CPU %d: IPI stress test. Target cpu 0\n", curcpu); - HDELAY(100000); - sgi_mcatest_bkpt(); - do_sync(spos); - - for (i=0; i 2 && cpu != curcpu) - platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); - - HDELAY(100000); - printk("CPU %d: Done\n", curcpu); - } - - if (test == 12) { - long adr = 0xe002200000000000UL; - n = IS_RUNNING_ON_SIMULATOR() ? 1000 : 100000; - printk("CPU %d: TLB flush stress test\n", curcpu); - HDELAY(100000); - sgi_mcatest_bkpt(); - do_sync(spos); - - for (i=0; i= smp_num_cpus-2) { - printk("Parking cpu %d\n", curcpu); - local_irq_disable(); - while(1); - } else { - printk("Waiting cpu %d\n", curcpu); - HDELAY(1000000); - } - HDELAY(1000000); - inited = 1; - } - if (test == 16 || test == 17) { - unsigned long t, shift, mask; - mask = (smp_num_cpus > 16) ? 0x1f : 0xf; - shift = 25-debug1; - do { - t = get_cycles(); - if (IS_RUNNING_ON_SIMULATOR()) - t = (t>>8); - else - t = (t>>shift); - t = t & mask; - } while (t == curcpu); - do { - t = get_cycles(); - if (IS_RUNNING_ON_SIMULATOR()) - t = (t>>8); - else - t = (t>>shift); - t = t & mask; - } while (t != curcpu); - } - if(debug3) printk("CPU %d: One TLB start\n", curcpu); - if (test != 17) platform_global_tlb_purge(adr, adr+PAGE_SIZE*debug0, 14); - if(debug3) printk("CPU %d: One TLB flush done\n", curcpu); - } - if (test == 20) { - local_irq_disable(); - set_led_bits(smp_processor_id(), 0xff); - while(1); - } - if (test == 21) { - extern long ia64_mca_stack[]; - int i, n; - volatile long *p, *up; - p = (volatile long*)__imva(ia64_mca_stack); - up = (volatile long*)(__pa(p) | __IA64_UNCACHED_OFFSET); - - if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ get data in cache\n"); - for (n=0, i=0; i<100; i++) - n += *(p+i); - if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n"); - for (n=0, i=0; i<100; i++) - n += *(up+i); - if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ dirty the data via cached refs\n"); - for (n=0, i=0; i<100; i++) - *(p+i) = i; - if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n"); - for (n=0, i=0; i<100; i++) - n += *(up+i); - if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Flushing cache\n"); - for (n=0, i=0; i<100; i++) - ia64_fc((void*)(p+i)); - printk("ZZZ done\n"); - } - if (test == 21) { - int i; - volatile long tb, t[10]; - for (i=0; i<10; i++) { - tb = debug3+ia64_get_itc(); - sgi_mcatest_bkpt(); - t[i] = ia64_get_itc() - tb; - } - for (i=0; i<10; i++) { - printk("ZZZ NULL 0x%lx\n", t[i]); - } - for (i=0; i<10; i++) { - tb = debug3+ia64_get_itc(); - ia64_pal_call_static(PAL_MC_DRAIN, 0, 0, 0, 0); - t[i] = ia64_get_itc() - tb; - } - for (i=0; i<10; i++) { - printk("ZZZ DRAIN 0x%lx\n", t[i]); - } - } - if (test == 22) { - extern void machine_restart(char*); - printk("ZZZ machine_restart\n"); - machine_restart(0); - } - if (test == 23) { - printk("ZZZ ia64_pal_halt_light\n"); - ia64_pal_halt_light(); - } - if (repeat) - goto again; - -} diff -urN linux-2.4.21/arch/ia64/sn/kernel/probe.c linux-2.4.22/arch/ia64/sn/kernel/probe.c --- linux-2.4.21/arch/ia64/sn/kernel/probe.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/probe.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * Platform dependent support for IO probing. * - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License diff -urN linux-2.4.21/arch/ia64/sn/kernel/setup.c linux-2.4.22/arch/ia64/sn/kernel/setup.c --- linux-2.4.21/arch/ia64/sn/kernel/setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -69,21 +69,27 @@ #include #include #include - -#ifdef CONFIG_IA64_SGI_SN2 #include -#endif + +#define pxm_to_nasid(pxm) ((pxm)<<1) + +#define MAX_PHYS_MEMORY (1UL << 49) /* 1 TB */ extern void bte_init_node (nodepda_t *, cnodeid_t); extern void bte_init_cpu (void); +extern void sn_timer_init(void); +extern unsigned long last_time_offset; +extern void (*ia64_mark_idle)(int); +extern void snidle(int); unsigned long sn_rtc_cycles_per_second; -unsigned long sn_rtc_usec_per_cyc; partid_t sn_partid = -1; char sn_system_serial_number_string[128]; u64 sn_partition_serial_number; +short physical_node_map[MAX_PHYSNODE_ID]; + /* * This is the address of the RRegs in the HSpace of the global * master. It is used by a hack in serial.c (serial_[in|out], @@ -92,21 +98,14 @@ * early_printk won't try to access the UART before * master_node_bedrock_address is properly calculated. */ -u64 master_node_bedrock_address = 0UL; +u64 master_node_bedrock_address; static void sn_init_pdas(char **); -extern struct irq_desc *_sn_irq_desc[]; - -#if defined(CONFIG_IA64_SGI_SN1) -extern synergy_da_t *Synergy_da_indr[]; -#endif static nodepda_t *nodepdaindr[MAX_COMPACT_NODES]; -#ifdef CONFIG_IA64_SGI_SN2 -irqpda_t *irqpdaindr[NR_CPUS]; -#endif /* CONFIG_IA64_SGI_SN2 */ +irqpda_t *irqpdaindr; /* @@ -133,29 +132,19 @@ * running in the simulator. Note that passing zeroes in DRIVE_INFO * is sufficient (the IDE driver will autodetect the drive geometry). */ +#ifdef CONFIG_IA64_GENERIC +extern char drive_info[4*16]; +#else char drive_info[4*16]; - -/** - * sn_map_nr - return the mem_map entry for a given kernel address - * @addr: kernel address to query - * - * Finds the mem_map entry for the kernel address given. Used by - * virt_to_page() (asm-ia64/page.h), among other things. - */ -unsigned long -sn_map_nr (void *addr) -{ - return MAP_NR_DISCONTIG(addr); -} +#endif /** * early_sn_setup - early setup routine for SN platforms * - * Sets up an intial console to aid debugging. Intended primarily - * for bringup, it's only called if %BRINGUP and %CONFIG_IA64_EARLY_PRINTK - * are turned on. See start_kernel() in init/main.c. + * Sets up an initial console to aid debugging. Intended primarily + * for bringup. See start_kernel() in init/main.c. */ -#if defined(CONFIG_IA64_EARLY_PRINTK) +#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM) void __init early_sn_setup(void) @@ -170,7 +159,7 @@ /* * Parse enough of the SAL tables to locate the SAL entry point. Since, console - * IO on SN2 is done via SAL calls, early_printk wont work without this. + * IO on SN2 is done via SAL calls, early_printk won't work without this. * * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c. * Any changes to those file may have to be made hereas well. @@ -193,21 +182,48 @@ } if ( IS_RUNNING_ON_SIMULATOR() ) { -#if defined(CONFIG_IA64_SGI_SN1) - master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0); -#else master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0); -#endif printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address); } } -#endif /* CONFIG_IA64_SGI_SN1 */ +#endif /* CONFIG_IA64_EARLY_PRINTK_SGI_SN */ #ifdef CONFIG_IA64_MCA extern int platform_intr_list[]; #endif extern nasid_t master_nasid; +static int shub_1_1_found __initdata; + + +/* + * sn_check_for_wars + * + * Set flag for enabling shub specific wars + */ + +static inline int __init +is_shub_1_1(int nasid) +{ + unsigned long id; + int rev; + + id = REMOTE_HUB_L(nasid, SH_SHUB_ID); + rev = (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT; + return rev <= 2; +} + +static void __init +sn_check_for_wars(void) +{ + int cnode; + + for (cnode=0; cnode< numnodes; cnode++) + if (is_shub_1_1(cnodeid_to_nasid(cnode))) + shub_1_1_found = 1; +} + + /** * sn_setup - SN platform setup routine @@ -221,8 +237,18 @@ sn_setup(char **cmdline_p) { long status, ticks_per_sec, drift; - int i; + int i, pxm; int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); + extern void io_sh_swapper(int, int); + extern nasid_t get_master_baseio_nasid(void); + extern void sn_cpu_init(void); + + MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY; + + memset(physical_node_map, -1, sizeof(physical_node_map)); + for (pxm=0; pxmthread.flags |= IA64_THREAD_FPEMU_NOPRINT; + sn_timer_init(); } /** @@ -332,19 +336,16 @@ if ((PDAADDR&~PAGE_MASK)+sizeof(pda_t) > PAGE_SIZE) panic("overflow of cpu_data page"); + memset(pda.cnodeid_to_nasid_table, -1, sizeof(pda.cnodeid_to_nasid_table)); + for (cnode=0; cnodeactive_cpu_count == 1) nodepda->node_first_cpu = cpuid; -#ifdef CONFIG_IA64_SGI_SN1 - { - int synergy; - synergy = cpu_physical_id_to_synergy(cpuphyid); - pda.p_subnodepda = &nodepdaindr[cnode]->snpda[synergy]; - } -#endif -#ifdef CONFIG_IA64_SGI_SN2 /* * We must use different memory allocators for first cpu (bootmem * allocator) than for the other cpus (regular allocator). */ if (cpuid == 0) - irqpdaindr[cpuid] = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t)); - else - irqpdaindr[cpuid] = page_address(alloc_pages_node(local_cnodeid(), GFP_KERNEL, get_order(sizeof(irqpda_t)))); + irqpdaindr = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t)); - memset(irqpdaindr[cpuid], 0, sizeof(irqpda_t)); - pda.p_irqpda = irqpdaindr[cpuid]; + memset(irqpdaindr, 0, sizeof(irqpda_t)); + irqpdaindr->irq_flags[SGI_PCIBR_ERROR] = SN2_IRQ_SHARED; + irqpdaindr->irq_flags[SGI_PCIBR_ERROR] |= SN2_IRQ_RESERVED; + irqpdaindr->irq_flags[SGI_II_ERROR] = SN2_IRQ_SHARED; + irqpdaindr->irq_flags[SGI_II_ERROR] |= SN2_IRQ_RESERVED; pda.pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR((slice < 2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ) ); @@ -442,253 +438,9 @@ if (nodepda->node_first_cpu == cpuid) { int buddy_nasid; - buddy_nasid = cnodeid_to_nasid(local_cnodeid() == numnodes-1 ? 0 : local_cnodeid()+ 1); + buddy_nasid = cnodeid_to_nasid(numa_node_id() == numnodes-1 ? 0 : numa_node_id()+ 1); pda.pio_shub_war_cam_addr = (volatile unsigned long*)GLOBAL_MMR_ADDR(nasid, SH_PI_CAM_CONTROL); } -#ifdef BRINGUP2 - /* - * Zero out the counters used for counting MCAs - * ZZZZZ temp - */ - { - long *p; - p = (long*)LOCAL_MMR_ADDR(SH_XN_IILB_LB_CMP_ENABLE0); - *p = 0; - p = (long*)LOCAL_MMR_ADDR(SH_XN_IILB_LB_CMP_ENABLE1); - *p = 0; - } - -#endif -#endif - -#ifdef CONFIG_IA64_SGI_SN1 - pda.bedrock_rev_id = (volatile unsigned long *) LOCAL_HUB(LB_REV_ID); - if (cpuid_to_synergy(cpuid)) - /* CPU B */ - pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_B_ADDR; - else - /* CPU A */ - pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_A_ADDR; -#endif - - bte_init_cpu(); } - - -/** - * cnodeid_to_cpuid - convert a cnode to a cpuid of a cpu on the node. - * @cnode: node to get a cpuid from - * - * Returns -1 if no cpus exist on the node. - * NOTE:BRINGUP ZZZ This is NOT a good way to find cpus on the node. - * Need a better way!! - */ -int -cnodeid_to_cpuid(int cnode) { - int cpu; - - for (cpu = 0; cpu < smp_num_cpus; cpu++) - if (cpuid_to_cnodeid(cpu) == cnode) - break; - - if (cpu == smp_num_cpus) - cpu = -1; - - return cpu; -} - -/** - * get_cycles - return a non-decreasing timestamp - * - * On SN, we use an RTC read for this function - */ -cycles_t -get_cycles (void) -{ - return GET_RTC_COUNTER(); -} - -/** - * gettimeoffset - number of usecs elapsed since &xtime was last updated - * - * This function is used by do_gettimeofday() to determine the number - * of usecs that have elapsed since the last update to &xtime. On SN - * this is accomplished using the RTC built in to each Hub chip; each - * is guaranteed to be synchronized by the PROM, so a local read will - * suffice (get_cycles() does this for us). A snapshot of the RTC value - * is taken on every timer interrupt and this function more or less - * subtracts that snapshot value from the current value. - * - * Note that if a lot of processing was done during the last timer - * interrupt then &xtime may be some number of jiffies out of date. - * This function must account for that. - */ -unsigned long -gettimeoffset(void) -{ - unsigned long current_rtc_val, local_last_rtc_val; - unsigned long usec; - - local_last_rtc_val = last_rtc_val; - current_rtc_val = get_cycles(); - usec = last_itc_lost_usec; - - /* If the RTC has wrapped around, compensate */ - if (unlikely(current_rtc_val < local_last_rtc_val)) { - printk(KERN_NOTICE "RTC wrapped cpu:%d current:0x%lx last:0x%lx\n", - smp_processor_id(), current_rtc_val, - local_last_rtc_val); - current_rtc_val += RTC_MASK; - } - - usec += ((current_rtc_val - local_last_rtc_val)*sn_rtc_usec_per_cyc) >> - IA64_USEC_PER_CYC_SHIFT; - - /* - * usec is the number of microseconds into the current clock interval. Every - * clock tick, xtime is advanced by "tick" microseconds. If "usec" - * is allowed to get larger than "tick", the time value returned by gettimeofday - * will go backward. - */ - if (usec >= tick) - usec = tick-1; - - return usec; -} - -#ifdef II_PRTE_TLB_WAR -long iiprt_lock[16*64] __cacheline_aligned; /* allow for NASIDs up to 64 */ -#endif - -#ifdef BUS_INT_WAR - -#include -#include - -void ia64_handle_irq (ia64_vector vector, struct pt_regs *regs); - -static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; - -#define IRQCPU(irq) ((irq)>>8) - -void -sn_add_polled_interrupt(int irq, int interval) -{ - unsigned long flags, irq_cnt; - sn_poll_entry_t *irq_list; - - irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;; - - spin_lock_irqsave(&irq_lock, flags); - irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count; - irq_list[irq_cnt].irq = irq; - irq_list[irq_cnt].interval = interval; - irq_list[irq_cnt].tick = interval; - pdacpu(IRQCPU(irq)).pda_poll_entry_count++; - spin_unlock_irqrestore(&irq_lock, flags); - - -} - -void -sn_delete_polled_interrupt(int irq) -{ - unsigned long flags, i, irq_cnt; - sn_poll_entry_t *irq_list; - - irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries; - - spin_lock_irqsave(&irq_lock, flags); - irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count; - for (i=0; itick <= 0) { -#ifdef CONFIG_SHUB_1_0_SPECIFIC - irq_list->tick = irq_list->interval; -#else - irq_list->tick = sn_int_poll_ticks; -#endif - local_irq_save(flags); - ia64_handle_irq(irq_to_vector(irq_list->irq), 0); - local_irq_restore(flags); - } - } -} - -#define PROCFILENAME "sn_int_poll_ticks" - -static struct proc_dir_entry *proc_op; - - -static int -read_proc(char *buffer, char **start, off_t off, int count, int *eof, void *data) -{ - int len = 0; - - len += sprintf(buffer + len, "Poll hack: interval %ld ticks\n", sn_int_poll_ticks); - - if (len <= off+count) *eof = 1; - *start = buffer + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} - -static int -write_proc (struct file *file, const char *userbuf, unsigned long count, void *data) -{ - extern long atoi(char *); - char buf[80]; - - if (copy_from_user(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf))) - return -EFAULT; - - sn_int_poll_ticks = atoi(buf); - - return count; -} - - -int __init -sn_poll_init(void) -{ - if ((proc_op = create_proc_entry(PROCFILENAME, 0644, NULL)) == NULL) { - printk("%s: unable to create proc entry", PROCFILENAME); - return -1; - } - proc_op->read_proc = read_proc; - proc_op->write_proc = write_proc; - return 0; -} - -module_init(sn_poll_init); -#endif diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn1/Makefile linux-2.4.22/arch/ia64/sn/kernel/sn1/Makefile --- linux-2.4.21/arch/ia64/sn/kernel/sn1/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn1/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,47 +0,0 @@ -# -# arch/ia64/sn/kernel/sn1/Makefile -# -# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of version 2 of the GNU General Public License -# as published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# Further, this software is distributed without any warranty that it is -# free of the rightful claim of any third person regarding infringement -# or the like. Any license provided herein, whether implied or -# otherwise, applies only to this software file. Patent licenses, if -# any, provided herein do not apply to combinations of this program with -# other software, or any other product whatsoever. -# -# You should have received a copy of the GNU General Public -# License along with this program; if not, write the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# -# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, -# Mountain View, CA 94043, or: -# -# http://www.sgi.com -# -# For further information regarding this notice, see: -# -# http://oss.sgi.com/projects/GenInfo/NoticeExplan -# - - -EXTRA_CFLAGS := -DLITTLE_ENDIAN - -.S.s: - $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $< -.S.o: - $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< - -O_TARGET = sn1.o - -obj-y = cache.o error.o iomv.o synergy.o sn1_smp.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn1/cache.c linux-2.4.22/arch/ia64/sn/kernel/sn1/cache.c --- linux-2.4.21/arch/ia64/sn/kernel/sn1/cache.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn1/cache.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,81 +0,0 @@ -/* - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. - * - */ - -#include -#include -#include -#include -#include -#include - -#ifndef MB -#define MB (1024*1024) -#endif - -/* - * Lock for protecting SYN_TAG_DISABLE_WAY. - * Consider making this a per-FSB lock. - */ -static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED; - -/** - * sn_flush_all_caches - flush a range of addresses from all caches (incl. L4) - * @flush_addr: identity mapped region 7 address to start flushing - * @bytes: number of bytes to flush - * - * Flush a range of addresses from all caches including L4. All addresses - * fully or partially contained within @flush_addr to @flush_addr + @bytes - * are flushed from the all caches. - */ -void -sn_flush_all_caches(long flush_addr, long bytes) -{ - ulong addr, baddr, eaddr, bitbucket; - int way, alias; - - /* - * Because of the way synergy implements "fc", this flushes the - * data from all caches on all cpus & L4's on OTHER FSBs. It also - * flushes both cpus on the local FSB. It does NOT flush it from - * the local FSB. - */ - flush_icache_range(flush_addr, flush_addr+bytes); - - /* - * Memory DIMMs are a minimum of 256MB and start on 256MB - * boundaries. Convert the start address to an address - * that is between +0MB & +128 of the same DIMM. - * Then add 8MB to skip the uncached MinState areas if the address - * is on the master node. - */ - if (bytes > SYNERGY_L4_BYTES_PER_WAY) - bytes = SYNERGY_L4_BYTES_PER_WAY; - baddr = TO_NODE(smp_physical_node_id(), PAGE_OFFSET + (flush_addr & (128*MB-1)) + 8*MB); - eaddr = (baddr+bytes+SYNERGY_BLOCK_SIZE-1) & ~(SYNERGY_BLOCK_SIZE-1); - baddr = baddr & ~(SYNERGY_BLOCK_SIZE-1); - - /* - * Now flush the local synergy. - */ - spin_lock(&flush_lock); - for(way=0; way -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/** - * snia_error_intr_handler - handle SN specific error interrupts - * @irq: error interrupt received - * @devid: device causing the interrupt - * @pt_regs: saved register state - * - * This routine is called when certain interrupts occur on SN systems. - * It will either recover from the situations that caused the interrupt - * or panic. - */ -void -snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs) -{ - unsigned long long intpend_val; - unsigned long long bit; - - switch (irq) { - case SGI_UART_IRQ: - /* - * This isn't really an error interrupt. We're just - * here because we have to do something with them. - * This is probably wrong, and this code will be - * removed. - */ - intpend_val = LOCAL_HUB_L(PI_INT_PEND0); - if ( (bit = ~(1L< -#include -#include -#include -#include - -/** - * sn_io_addr - convert an in/out port to an i/o address - * @port: port to convert - * - * Legacy in/out instructions are converted to ld/st instructions - * on IA64. This routine will convert a port number into a valid - * SN i/o address. Used by sn_in*() and sn_out*(). - */ -void * -sn_io_addr(unsigned long port) -{ - if (!IS_RUNNING_ON_SIMULATOR()) { - return( (void *) (port | __IA64_UNCACHED_OFFSET)); - } else { - unsigned long io_base; - unsigned long addr; - - /* - * word align port, but need more than 10 bits - * for accessing registers in bedrock local block - * (so we don't do port&0xfff) - */ - if ((port >= 0x1f0 && port <= 0x1f7) || - port == 0x3f6 || port == 0x3f7) { - io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000; - addr = io_base | ((port >> 2) << 12) | (port & 0xfff); - } else { - addr = __ia64_get_io_port_base() | ((port >> 2) << 2); - } - return(void *) addr; - } -} - -/** - * sn1_mmiob - I/O space memory barrier - * - * Acts as a memory mapped I/O barrier for platforms that queue writes to - * I/O space. This ensures that subsequent writes to I/O space arrive after - * all previous writes. For most ia64 platforms, this is a simple - * 'mf.a' instruction. For other platforms, mmiob() may have to read - * a chipset register to ensure ordering. - * - * On SN1, we wait for the PIO_WRITE_STATUS Bedrock register to clear. - */ -void -sn1_mmiob (void) -{ - (volatile unsigned long) (*pda.bedrock_rev_id); - while (!(volatile unsigned long) (*pda.pio_write_status_addr)) - udelay(5); -} diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn1/sn1_smp.c linux-2.4.22/arch/ia64/sn/kernel/sn1/sn1_smp.c --- linux-2.4.21/arch/ia64/sn/kernel/sn1/sn1_smp.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn1/sn1_smp.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,476 +0,0 @@ -/* - * SN1 Platform specific SMP Support - * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The following structure is used to pass params thru smp_call_function - * to other cpus for flushing TLB ranges. - */ -typedef struct { - union { - struct { - unsigned long start; - unsigned long end; - unsigned long nbits; - unsigned int rid; - atomic_t unfinished_count; - } ptc; - char pad[SMP_CACHE_BYTES]; - }; -} ptc_params_t; - -#define NUMPTC 512 - -static ptc_params_t ptcParamArray[NUMPTC] __attribute__((__aligned__(128))); - -/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */ -static ptc_params_t *ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128))); -static volatile ptc_params_t *ptcParamsEmpty __cacheline_aligned; - -/*REFERENCED*/ -static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED; - -static int ptcInit = 0; -#ifdef PTCDEBUG -static int ptcParamsAllBusy = 0; /* debugging/statistics */ -static int ptcCountBacklog = 0; -static int ptcBacklog[NUMPTC+1]; -static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128))); -static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128))); -#endif - -/* - * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference, - * so that we get a clean compile with the ia64 patch without the - * actual SN1 specific code in arch/ia64/kernel/smp.c. - */ -extern void smp_send_flush_tlb (void) __attribute((weak)); - -/* - * The following table/struct is for remembering PTC coherency domains. It - * is also used to translate sapicid into cpuids. We dont want to start - * cpus unless we know their cache domain. - */ -#ifdef PTC_NOTYET -sn_sapicid_info_t sn_sapicid_info[NR_CPUS]; -#endif - -/** - * sn1_ptc_l_range - purge local translation cache - * @start: start of virtual address range - * @end: end of virtual address range - * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc)) - * - * Purges the range specified from the local processor's translation cache - * (as opposed to the translation registers). Note that more than the specified - * range *may* be cleared from the cache by some processors. - * - * This is probably not good enough, but I don't want to try to make it better - * until I get some statistics on a running system. At a minimum, we should only - * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's - * own FSB. Also, we only have to serialize per FSB, not globally. - * - * More likely, we will have to do some work to reduce the frequency of calls to - * this routine. - */ -static inline void -sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits) -{ - do { - __asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory"); - start += (1UL << nbits); - } while (start < end); - ia64_srlz_d(); -} - -/** - * sn1_received_flush_tlb - cpu tlb flush routine - * - * Flushes the TLB of a given processor. - */ -void -sn1_received_flush_tlb(void) -{ - unsigned long start, end, nbits; - unsigned int rid, saved_rid; - int cpu = smp_processor_id(); - int result; - ptc_params_t *ptcParams; - - ptcParams = ptcParamsNextByCpu[cpu*16]; - if (ptcParams == ptcParamsEmpty) - return; - - do { - start = ptcParams->ptc.start; - saved_rid = (unsigned int) ia64_get_rr(start); - end = ptcParams->ptc.end; - nbits = ptcParams->ptc.nbits; - rid = ptcParams->ptc.rid; - - if (saved_rid != rid) { - ia64_set_rr(start, (unsigned long)rid); - ia64_srlz_d(); - } - - sn1_ptc_l_range(start, end, nbits); - - if (saved_rid != rid) - ia64_set_rr(start, (unsigned long)saved_rid); - - ia64_srlz_i(); - - result = atomic_dec(&ptcParams->ptc.unfinished_count); -#ifdef PTCDEBUG - { - int i = ptcParams-&ptcParamArray[0]; - ptcParamsResults[cpu][i] = (char) result; - ptcParamsCounts[cpu][i]++; - } -#endif /* PTCDEBUG */ - - if (++ptcParams == &ptcParamArray[NUMPTC]) - ptcParams = &ptcParamArray[0]; - - } while (ptcParams != ptcParamsEmpty); - - ptcParamsNextByCpu[cpu*16] = ptcParams; -} - -/** - * sn1_global_tlb_purge - flush a translation cache range on all processors - * @start: start of virtual address range to flush - * @end: end of virtual address range - * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc)) - * - * Flushes the translation cache of all processors from @start to @end. - */ -void -sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits) -{ - ptc_params_t *params; - ptc_params_t *next; - unsigned long irqflags; -#ifdef PTCDEBUG - ptc_params_t *nextnext; - int backlog = 0; -#endif - - if (smp_num_cpus == 1) { - sn1_ptc_l_range(start, end, nbits); - return; - } - - if (in_interrupt()) { - /* - * If at interrupt level and cannot get spinlock, - * then do something useful by flushing own tlbflush queue - * so as to avoid a possible deadlock. - */ - while (!spin_trylock(&ptcParamsLock)) { - local_irq_save(irqflags); - sn1_received_flush_tlb(); - local_irq_restore(irqflags); - udelay(10); /* take it easier on the bus */ - } - } else { - spin_lock(&ptcParamsLock); - } - - if (!ptcInit) { - int cpu; - ptcInit = 1; - memset(ptcParamArray, 0, sizeof(ptcParamArray)); - ptcParamsEmpty = &ptcParamArray[0]; - for (cpu=0; cpu= &ptcParamArray[0]) { - if (atomic_read(&ptr->ptc.unfinished_count) == 0) - break; - ++backlog; - } - - if (backlog) { - /* check the end of the array */ - ptr = &ptcParamArray[NUMPTC]; - while (--ptr > params) { - if (atomic_read(&ptr->ptc.unfinished_count) == 0) - break; - ++backlog; - } - } - ptcBacklog[backlog]++; - } -#endif /* PTCDEBUG */ - - /* wait for the next entry to clear...should be rare */ - if (atomic_read(&next->ptc.unfinished_count) > 0) { -#ifdef PTCDEBUG - ptcParamsAllBusy++; - - if (atomic_read(&nextnext->ptc.unfinished_count) == 0) { - if (atomic_read(&next->ptc.unfinished_count) > 0) { - panic("\nnonzero next zero nextnext %lx %lx\n", - (long)next, (long)nextnext); - } - } -#endif - - /* it could be this cpu that is behind */ - local_irq_save(irqflags); - sn1_received_flush_tlb(); - local_irq_restore(irqflags); - - /* now we know it's not this cpu, so just wait */ - while (atomic_read(&next->ptc.unfinished_count) > 0) { - barrier(); - } - } - - params->ptc.start = start; - params->ptc.end = end; - params->ptc.nbits = nbits; - params->ptc.rid = (unsigned int) ia64_get_rr(start); - atomic_set(¶ms->ptc.unfinished_count, smp_num_cpus); - - /* The atomic_set above can hit memory *after* the update - * to ptcParamsEmpty below, which opens a timing window - * that other cpus can squeeze into! - */ - mb(); - - /* everything is ready to process: - * -- global lock is held - * -- new entry + 1 is free - * -- new entry is set up - * so now: - * -- update the global next pointer - * -- unlock the global lock - * -- send IPI to notify other cpus - * -- process the data ourselves - */ - ptcParamsEmpty = next; - spin_unlock(&ptcParamsLock); - smp_send_flush_tlb(); - - local_irq_save(irqflags); - sn1_received_flush_tlb(); - local_irq_restore(irqflags); - - /* Currently we don't think global TLB purges need to be atomic. - * All CPUs get sent IPIs, so if they haven't done the purge, - * they're busy with interrupts that are at the IPI level, which is - * priority 15. We're asserting that any code at that level - * shouldn't be using user TLB entries. To change this to wait - * for all the flushes to complete, enable the following code. - */ -#if defined(SN1_SYNCHRONOUS_GLOBAL_TLB_PURGE) || defined(BUS_INT_WAR) - /* this code is not tested */ - /* wait for the flush to complete */ - while (atomic_read(¶ms->ptc.unfinished_count) > 0) - barrier(); -#endif -} - -/** - * sn_send_IPI_phys - send an IPI to a Nasid and slice - * @physid: physical cpuid to receive the interrupt. - * @vector: command to send - * @delivery_mode: delivery mechanism - * - * Sends an IPI (interprocessor interrupt) to the processor specified by - * @physid - * - * @delivery_mode can be one of the following - * - * %IA64_IPI_DM_INT - pend an interrupt - * %IA64_IPI_DM_PMI - pend a PMI - * %IA64_IPI_DM_NMI - pend an NMI - * %IA64_IPI_DM_INIT - pend an INIT interrupt - */ -void -sn_send_IPI_phys(long physid, int vector, int delivery_mode) -{ - long *p; - long nasid, slice; - - static int off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088}; - -#ifdef BUS_INT_WAR - if (vector != ap_wakeup_vector) { - return; - } -#endif - - nasid = cpu_physical_id_to_nasid(physid); - slice = cpu_physical_id_to_slice(physid); - - p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]); - - mb(); - *p = (delivery_mode << 8) | (vector & 0xff); -} - - -/** - * sn1_send_IPI - send an IPI to a processor - * @cpuid: target of the IPI - * @vector: command to send - * @delivery_mode: delivery mechanism - * @redirect: redirect the IPI? - * - * Sends an IPI (interprocessor interrupt) to the processor specified by - * @cpuid. @delivery_mode can be one of the following - * - * %IA64_IPI_DM_INT - pend an interrupt - * %IA64_IPI_DM_PMI - pend a PMI - * %IA64_IPI_DM_NMI - pend an NMI - * %IA64_IPI_DM_INIT - pend an INIT interrupt - */ -void -sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect) -{ - long physid; - - physid = cpu_physical_id(cpuid); - - sn_send_IPI_phys(physid, vector, delivery_mode); -} -#ifdef CONFIG_SMP - -#ifdef PTC_NOTYET -static void __init -process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain) -{ - ia64_sal_ptc_domain_proc_entry_t *pe; - int i, sapicid, cpuid; - - pe = __va(di->proc_list); - for (i=0; iproc_count; i++, pe++) { - sapicid = id_eid_to_sapicid(pe->id, pe->eid); - cpuid = cpu_logical_id(sapicid); - sn_sapicid_info[cpuid].domain = domain; - sn_sapicid_info[cpuid].sapicid = sapicid; - } -} - - -static void __init -process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc) -{ - ia64_sal_ptc_domain_info_t *di; - int i; - - di = __va(ptc->domain_info); - for (i=0; inum_domains; i++, di++) { - process_sal_ptc_domain_info(di, i); - } -} -#endif /* PTC_NOTYET */ - -/** - * init_sn1_smp_config - setup PTC domains per processor - */ -void __init -init_sn1_smp_config(void) -{ - if (!ia64_ptc_domain_info) { - printk("SMP: Can't find PTC domain info. Forcing UP mode\n"); - smp_num_cpus = 1; - return; - } - -#ifdef PTC_NOTYET - memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info)); - process_sal_desc_ptc(ia64_ptc_domain_info); -#endif -} - -#else /* CONFIG_SMP */ - -void __init -init_sn1_smp_config(void) -{ - -#ifdef PTC_NOTYET - sn_sapicid_info[0].sapicid = hard_smp_processor_id(); -#endif -} - -#endif /* CONFIG_SMP */ diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn1/synergy.c linux-2.4.22/arch/ia64/sn/kernel/sn1/synergy.c --- linux-2.4.21/arch/ia64/sn/kernel/sn1/synergy.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn1/synergy.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,533 +0,0 @@ -/* - * SN1 Platform specific synergy Support - * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int bit_pos_to_irq(int bit); -void setclear_mask_b(int irq, int cpuid, int set); -void setclear_mask_a(int irq, int cpuid, int set); -void * kmalloc(size_t size, int flags); - -static int synergy_perf_initialized = 0; - -void -synergy_intr_alloc(int bit, int cpuid) { - return; -} - -int -synergy_intr_connect(int bit, - int cpuid) -{ - int irq; - unsigned is_b; - - irq = bit_pos_to_irq(bit); - - is_b = (cpuid_to_slice(cpuid)) & 1; - if (is_b) { - setclear_mask_b(irq,cpuid,1); - setclear_mask_a(irq,cpuid, 0); - } else { - setclear_mask_a(irq, cpuid, 1); - setclear_mask_b(irq, cpuid, 0); - } - return 0; -} -void -setclear_mask_a(int irq, int cpuid, int set) -{ - int synergy; - int nasid; - int reg_num; - unsigned long mask; - unsigned long addr; - unsigned long reg; - unsigned long val; - int my_cnode, my_synergy; - int target_cnode, target_synergy; - - /* - * Perform some idiot checks .. - */ - if ( (irq < 0) || (irq > 255) || - (cpuid < 0) || (cpuid > 512) ) { - printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid); - return; - } - - target_cnode = cpuid_to_cnodeid(cpuid); - target_synergy = cpuid_to_synergy(cpuid); - my_cnode = cpuid_to_cnodeid(smp_processor_id()); - my_synergy = cpuid_to_synergy(smp_processor_id()); - - reg_num = irq / 64; - mask = 1; - mask <<= (irq % 64); - switch (reg_num) { - case 0: - reg = VEC_MASK0A; - addr = VEC_MASK0A_ADDR; - break; - case 1: - reg = VEC_MASK1A; - addr = VEC_MASK1A_ADDR; - break; - case 2: - reg = VEC_MASK2A; - addr = VEC_MASK2A_ADDR; - break; - case 3: - reg = VEC_MASK3A; - addr = VEC_MASK3A_ADDR; - break; - default: - reg = addr = 0; - break; - } - if (my_cnode == target_cnode && my_synergy == target_synergy) { - // local synergy - val = READ_LOCAL_SYNERGY_REG(addr); - if (set) { - val |= mask; - } else { - val &= ~mask; - } - WRITE_LOCAL_SYNERGY_REG(addr, val); - val = READ_LOCAL_SYNERGY_REG(addr); - } else { /* remote synergy */ - synergy = cpuid_to_synergy(cpuid); - nasid = cpuid_to_nasid(cpuid); - val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg); - if (set) { - val |= mask; - } else { - val &= ~mask; - } - REMOTE_SYNERGY_STORE(nasid, synergy, reg, val); - } -} - -void -setclear_mask_b(int irq, int cpuid, int set) -{ - int synergy; - int nasid; - int reg_num; - unsigned long mask; - unsigned long addr; - unsigned long reg; - unsigned long val; - int my_cnode, my_synergy; - int target_cnode, target_synergy; - - /* - * Perform some idiot checks .. - */ - if ( (irq < 0) || (irq > 255) || - (cpuid < 0) || (cpuid > 512) ) { - printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid); - return; - } - - target_cnode = cpuid_to_cnodeid(cpuid); - target_synergy = cpuid_to_synergy(cpuid); - my_cnode = cpuid_to_cnodeid(smp_processor_id()); - my_synergy = cpuid_to_synergy(smp_processor_id()); - - reg_num = irq / 64; - mask = 1; - mask <<= (irq % 64); - switch (reg_num) { - case 0: - reg = VEC_MASK0B; - addr = VEC_MASK0B_ADDR; - break; - case 1: - reg = VEC_MASK1B; - addr = VEC_MASK1B_ADDR; - break; - case 2: - reg = VEC_MASK2B; - addr = VEC_MASK2B_ADDR; - break; - case 3: - reg = VEC_MASK3B; - addr = VEC_MASK3B_ADDR; - break; - default: - reg = addr = 0; - break; - } - if (my_cnode == target_cnode && my_synergy == target_synergy) { - // local synergy - val = READ_LOCAL_SYNERGY_REG(addr); - if (set) { - val |= mask; - } else { - val &= ~mask; - } - WRITE_LOCAL_SYNERGY_REG(addr, val); - val = READ_LOCAL_SYNERGY_REG(addr); - } else { /* remote synergy */ - synergy = cpuid_to_synergy(cpuid); - nasid = cpuid_to_nasid(cpuid); - val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg); - if (set) { - val |= mask; - } else { - val &= ~mask; - } - REMOTE_SYNERGY_STORE(nasid, synergy, reg, val); - } -} - -/* - * Synergy perf stats. Multiplexed via timer_interrupt. - */ - -static int -synergy_perf_append(uint64_t modesel) -{ - int cnode; - nodepda_t *npdap; - synergy_perf_t *p; - int checked = 0; - int err = 0; - unsigned long flags; - - /* bit 45 is enable */ - modesel |= (1UL << 45); - - for (cnode=0; cnode < numnodes; cnode++) { - /* for each node, insert a new synergy_perf entry */ - if ((npdap = NODEPDA(cnode)) == NULL) { - printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, (void *)nodepda); - continue; - } - - if (npdap->synergy_perf_enabled) { - /* user must disable counting to append new events */ - err = -EBUSY; - break; - } - - if (!checked && npdap->synergy_perf_data != NULL) { - checked = 1; - for (p = npdap->synergy_perf_first; ;) { - if (p->modesel == modesel) - return 0; /* event already registered */ - if ((p = p->next) == npdap->synergy_perf_first) - break; - } - } - - /* XX use kmem_alloc_node() when it is implemented */ - p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL); - if ((((uint64_t)p) & 7UL) != 0) - BUG(); /* bad alignment */ - if (p == NULL) { - err = -ENOMEM; - break; - } - else { - memset(p, 0, sizeof(synergy_perf_t)); - p->modesel = modesel; - - spin_lock_irqsave(&npdap->synergy_perf_lock, flags); - if (npdap->synergy_perf_data == NULL) { - /* circular list */ - p->next = p; - npdap->synergy_perf_first = p; - npdap->synergy_perf_data = p; - } - else { - p->next = npdap->synergy_perf_data->next; - npdap->synergy_perf_data->next = p; - } - spin_unlock_irqrestore(&npdap->synergy_perf_lock, flags); - } - } - - return err; -} - -static void -synergy_perf_set_freq(int freq) -{ - int cnode; - nodepda_t *npdap; - - for (cnode=0; cnode < numnodes; cnode++) { - if ((npdap = NODEPDA(cnode)) != NULL) - npdap->synergy_perf_freq = freq; - } -} - -static void -synergy_perf_set_enable(int enable) -{ - int cnode; - nodepda_t *npdap; - - for (cnode=0; cnode < numnodes; cnode++) { - if ((npdap = NODEPDA(cnode)) != NULL) - npdap->synergy_perf_enabled = enable; - } - printk("NOTICE: synergy perf counting %sabled on all nodes\n", enable ? "en" : "dis"); -} - -static int -synergy_perf_size(nodepda_t *npdap) -{ - synergy_perf_t *p; - int n; - - if (npdap->synergy_perf_enabled == 0) { - /* no stats to return */ - return 0; - } - - spin_lock_irq(&npdap->synergy_perf_lock); - for (n=0, p = npdap->synergy_perf_first; p;) { - n++; - p = p->next; - if (p == npdap->synergy_perf_first) - break; - } - spin_unlock_irq(&npdap->synergy_perf_lock); - - /* bytes == n pairs of {event,counter} */ - return n * 2 * sizeof(uint64_t); -} - -static int -synergy_perf_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int cnode; - nodepda_t *npdap; - synergy_perf_t *p; - int intarg; - int fsb; - uint64_t longarg; - uint64_t *stats; - int n; - devfs_handle_t d; - arbitrary_info_t info; - - if ((d = devfs_get_handle_from_inode(inode)) == NULL) - return -ENODEV; - info = hwgraph_fastinfo_get(d); - - cnode = SYNERGY_PERF_INFO_CNODE(info); - fsb = SYNERGY_PERF_INFO_FSB(info); - npdap = NODEPDA(cnode); - - switch (cmd) { - case SNDRV_GET_SYNERGY_VERSION: - /* return int, version of data structure for SNDRV_GET_SYNERGYINFO */ - intarg = 1; /* version 1 */ - if (copy_to_user((void *)arg, &intarg, sizeof(intarg))) - return -EFAULT; - break; - - case SNDRV_GET_INFOSIZE: - /* return int, sizeof buf needed for SYNERGY_PERF_GET_STATS */ - intarg = synergy_perf_size(npdap); - if (copy_to_user((void *)arg, &intarg, sizeof(intarg))) - return -EFAULT; - break; - - case SNDRV_GET_SYNERGYINFO: - /* return array of event/value pairs, this node only */ - if ((intarg = synergy_perf_size(npdap)) <= 0) - return -ENODATA; - if ((stats = (uint64_t *)kmalloc(intarg, GFP_KERNEL)) == NULL) - return -ENOMEM; - spin_lock_irq(&npdap->synergy_perf_lock); - for (n=0, p = npdap->synergy_perf_first; p;) { - stats[n++] = p->modesel; - if (p->intervals > 0) - stats[n++] = p->counts[fsb] * p->total_intervals / p->intervals; - else - stats[n++] = 0; - p = p->next; - if (p == npdap->synergy_perf_first) - break; - } - spin_unlock_irq(&npdap->synergy_perf_lock); - - if (copy_to_user((void *)arg, stats, intarg)) { - kfree(stats); - return -EFAULT; - } - - kfree(stats); - break; - - case SNDRV_SYNERGY_APPEND: - /* reads 64bit event, append synergy perf event to all nodes */ - if (copy_from_user(&longarg, (void *)arg, sizeof(longarg))) - return -EFAULT; - return synergy_perf_append(longarg); - break; - - case SNDRV_GET_SYNERGY_STATUS: - /* return int, 1 if enabled else 0 */ - intarg = npdap->synergy_perf_enabled; - if (copy_to_user((void *)arg, &intarg, sizeof(intarg))) - return -EFAULT; - break; - - case SNDRV_SYNERGY_ENABLE: - /* read int, if true enable counting else disable */ - if (copy_from_user(&intarg, (void *)arg, sizeof(intarg))) - return -EFAULT; - synergy_perf_set_enable(intarg); - break; - - case SNDRV_SYNERGY_FREQ: - /* read int, set jiffies per update */ - if (copy_from_user(&intarg, (void *)arg, sizeof(intarg))) - return -EFAULT; - if (intarg < 0 || intarg >= HZ) - return -EINVAL; - synergy_perf_set_freq(intarg); - break; - - default: - printk("Warning: invalid ioctl %d on synergy mon for cnode=%d fsb=%d\n", cmd, cnode, fsb); - return -EINVAL; - } - return(0); -} - -struct file_operations synergy_mon_fops = { - ioctl: synergy_perf_ioctl, -}; - -void -synergy_perf_update(int cpu) -{ - nasid_t nasid; - cnodeid_t cnode; - struct nodepda_s *npdap; - - /* - * synergy_perf_initialized is set by synergy_perf_init() - * which is called last thing by sn_mp_setup(), i.e. well - * after nodepda has been initialized. - */ - if (!synergy_perf_initialized) - return; - - cnode = cpuid_to_cnodeid(cpu); - npdap = NODEPDA(cnode); - - if (npdap == NULL || cnode < 0 || cnode >= numnodes) - /* this should not happen: still in early io init */ - return; - -#if 0 - /* use this to check nodepda initialization */ - if (((uint64_t)npdap) & 0x7) { - printk("\nERROR on cpu %d : cnode=%d, npdap == %p, not aligned\n", cpu, cnode, npdap); - BUG(); - } -#endif - - if (npdap->synergy_perf_enabled == 0 || npdap->synergy_perf_data == NULL) { - /* Not enabled, or no events to monitor */ - return; - } - - if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) { - /* don't multiplex on every timer interrupt */ - return; - } - - /* - * Read registers for last interval and increment counters. - * Hold the per-node synergy_perf_lock so concurrent readers get - * consistent values. - */ - spin_lock_irq(&npdap->synergy_perf_lock); - - nasid = cpuid_to_nasid(cpu); - npdap->synergy_active_intervals++; - npdap->synergy_perf_data->intervals++; - npdap->synergy_perf_data->total_intervals = npdap->synergy_active_intervals; - - npdap->synergy_perf_data->counts[0] += 0xffffffffffUL & - REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A); - - npdap->synergy_perf_data->counts[1] += 0xffffffffffUL & - REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B); - - /* skip to next in circular list */ - npdap->synergy_perf_data = npdap->synergy_perf_data->next; - - spin_unlock_irq(&npdap->synergy_perf_lock); - - /* set the counter 0 selection modes for both A and B */ - REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel); - REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel); - - /* and reset the counter registers to zero */ - REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL); - REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL); -} - -void -synergy_perf_init(void) -{ - printk("synergy_perf_init(), counting is initially disabled\n"); - synergy_perf_initialized++; -} diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/Makefile linux-2.4.22/arch/ia64/sn/kernel/sn2/Makefile --- linux-2.4.21/arch/ia64/sn/kernel/sn2/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ # # arch/ia64/sn/kernel/sn2/Makefile # -# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved. +# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of version 2 of the GNU General Public License @@ -41,7 +41,9 @@ $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< O_TARGET = sn2.o +export-objs := io.o -obj-y = cache.o iomv.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o +obj-y = cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \ + prominfo_proc.o timer.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/cache.c linux-2.4.22/arch/ia64/sn/kernel/sn2/cache.c --- linux-2.4.21/arch/ia64/sn/kernel/sn2/cache.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/cache.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. * */ @@ -24,6 +24,5 @@ sn_flush_all_caches(long flush_addr, long bytes) { flush_icache_range(flush_addr, flush_addr+bytes); + mb(); } - - diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/io.c linux-2.4.22/arch/ia64/sn/kernel/sn2/io.c --- linux-2.4.21/arch/ia64/sn/kernel/sn2/io.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/io.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Silicon Graphics, Inc. All rights reserved. + * + * The generic kernel requires function pointers to these routines, so + * we wrap the inlines from asm/ia64/sn/sn2/io.h here. + */ + +#include + +unsigned int +sn_inb (unsigned long port) +{ + return __sn_inb(port); +} + +unsigned int +sn_inw (unsigned long port) +{ + return __sn_inw(port); +} + +unsigned int +sn_inl (unsigned long port) +{ + return __sn_inl(port); +} + +void +sn_outb (unsigned char val, unsigned long port) +{ + __sn_outb(val, port); +} + +void +sn_outw (unsigned short val, unsigned long port) +{ + __sn_outw(val, port); +} + +void +sn_outl (unsigned int val, unsigned long port) +{ + __sn_outl(val, port); +} + +unsigned char +sn_readb (void *addr) +{ + return __sn_readb (addr); +} + +unsigned short +sn_readw (void *addr) +{ + return __sn_readw (addr); +} + +unsigned int +sn_readl (void *addr) +{ + return __sn_readl (addr); +} + +unsigned long +sn_readq (void *addr) +{ + return __sn_readq (addr); +} + + +/* define aliases: */ + +asm (".global __sn_inb, __sn_inw, __sn_inl"); +asm ("__sn_inb = sn_inb"); +asm ("__sn_inw = sn_inw"); +asm ("__sn_inl = sn_inl"); + +asm (".global __sn_outb, __sn_outw, __sn_outl"); +asm ("__sn_outb = sn_outb"); +asm ("__sn_outw = sn_outw"); +asm ("__sn_outl = sn_outl"); + +asm (".global __sn_readb, __sn_readw, __sn_readl, __sn_readq"); +asm ("__sn_readb = sn_readb"); +asm ("__sn_readw = sn_readw"); +asm ("__sn_readl = sn_readl"); +asm ("__sn_readq = sn_readq"); diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/iomv.c linux-2.4.22/arch/ia64/sn/kernel/sn2/iomv.c --- linux-2.4.21/arch/ia64/sn/kernel/sn2/iomv.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/iomv.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,68 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include - -/** - * sn_io_addr - convert an in/out port to an i/o address - * @port: port to convert - * - * Legacy in/out instructions are converted to ld/st instructions - * on IA64. This routine will convert a port number into a valid - * SN i/o address. Used by sn_in*() and sn_out*(). - */ -void * -sn_io_addr(unsigned long port) -{ - if (!IS_RUNNING_ON_SIMULATOR()) { - return( (void *) (port | __IA64_UNCACHED_OFFSET)); - } else { - unsigned long io_base; - unsigned long addr; - - /* - * word align port, but need more than 10 bits - * for accessing registers in bedrock local block - * (so we don't do port&0xfff) - */ - if ((port >= 0x1f0 && port <= 0x1f7) || - port == 0x3f6 || port == 0x3f7) { - io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38)); - addr = io_base | ((port >> 2) << 12) | (port & 0xfff); - } else { - addr = __ia64_get_io_port_base() | ((port >> 2) << 2); - } - return(void *) addr; - } -} - -/** - * sn2_mmiob - I/O space memory barrier - * - * Acts as a memory mapped I/O barrier for platforms that queue writes to - * I/O space. This ensures that subsequent writes to I/O space arrive after - * all previous writes. For most ia64 platforms, this is a simple - * 'mf.a' instruction. For other platforms, mmiob() may have to read - * a chipset register to ensure ordering. - * - * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear. - * See PV 871084 for details about the WAR about zero value. - * - */ -void -sn2_mmiob (void) -{ - while ((((volatile unsigned long) (*pda.pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != - SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) - udelay(1); -} diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/prominfo_proc.c linux-2.4.22/arch/ia64/sn/kernel/sn2/prominfo_proc.c --- linux-2.4.21/arch/ia64/sn/kernel/sn2/prominfo_proc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/prominfo_proc.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,365 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All Rights Reserved. + * + * Module to export the system's Firmware Interface Tables, including + * PROM revision numbers, in /proc + */ +#include +#include +#include +#include +#include +#include +#include + +/* to lookup nasids */ +#include + +MODULE_DESCRIPTION("PROM version reporting for /proc"); +MODULE_AUTHOR("Chad Talbott"); +MODULE_LICENSE("GPL"); + +#undef DEBUG_PROMINFO + +#define TRACE_PROMINFO + +#if defined(DEBUG_PROMINFO) +# define DPRINTK(x...) printk(KERN_DEBUG x) +#else +# define DPRINTK(x...) +#endif + +#if defined(TRACE_PROMINFO) && defined(DEBUG_PROMINFO) +# if defined(__GNUC__) +# define TRACE() printk(KERN_DEBUG "%s:%d:%s\n", \ + __FILE__, __LINE__, __FUNCTION__) +# else +# define TRACE() printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__) +# endif +#else +# define TRACE() +#endif + +/* Sub-regions determined by bits in Node Offset */ +#define LB_PROM_SPACE 0x0000000700000000ul /* Local LB PROM */ + +#define FIT_SIGNATURE 0x2020205f5449465ful +/* Standard Intel FIT entry types */ +#define FIT_ENTRY_FIT_HEADER 0x00 /* FIT header entry */ +#define FIT_ENTRY_PAL_B 0x01 /* PAL_B entry */ +/* Entries 0x02 through 0x0D reserved by Intel */ +#define FIT_ENTRY_PAL_A_PROC 0x0E /* Processor-specific PAL_A entry */ +#define FIT_ENTRY_PAL_A 0x0F /* PAL_A entry, same as... */ +#define FIT_ENTRY_PAL_A_GEN 0x0F /* ...Generic PAL_A entry */ +#define FIT_ENTRY_UNUSED 0x7F /* Unused (reserved by Intel?) */ +/* OEM-defined entries range from 0x10 to 0x7E. */ +#define FIT_ENTRY_SAL_A 0x10 /* SAL_A entry */ +#define FIT_ENTRY_SAL_B 0x11 /* SAL_B entry */ +#define FIT_ENTRY_SALRUNTIME 0x12 /* SAL runtime entry */ +#define FIT_ENTRY_EFI 0x1F /* EFI entry */ +#define FIT_ENTRY_FPSWA 0x20 /* embedded fpswa entry */ +#define FIT_ENTRY_VMLINUX 0x21 /* embedded vmlinux entry */ + +#define FIT_MAJOR_SHIFT (32 + 8) +#define FIT_MAJOR_MASK ((1 << 8) - 1) +#define FIT_MINOR_SHIFT 32 +#define FIT_MINOR_MASK ((1 << 8) - 1) + +#define FIT_MAJOR(q) \ + ((unsigned) ((q) >> FIT_MAJOR_SHIFT) & FIT_MAJOR_MASK) +#define FIT_MINOR(q) \ + ((unsigned) ((q) >> FIT_MINOR_SHIFT) & FIT_MINOR_MASK) + +#define FIT_TYPE_SHIFT (32 + 16) +#define FIT_TYPE_MASK ((1 << 7) - 1) + +#define FIT_TYPE(q) \ + ((unsigned) ((q) >> FIT_TYPE_SHIFT) & FIT_TYPE_MASK) + +#define FIT_ENTRY(type, maj, min, size) \ + ((((unsigned long)(maj) & FIT_MAJOR_MASK) << FIT_MAJOR_SHIFT) | \ + (((unsigned long)(min) & FIT_MINOR_MASK) << FIT_MINOR_SHIFT) | \ + (((unsigned long)(type) & FIT_TYPE_MASK) << FIT_TYPE_SHIFT) | \ + (size)) + +struct fit_type_map_t { + unsigned char type; + const char *name; +}; + +static const struct fit_type_map_t fit_entry_types[] = { + { FIT_ENTRY_FIT_HEADER, "FIT Header" }, + { FIT_ENTRY_PAL_A_GEN, "Generic PAL_A" }, + { FIT_ENTRY_PAL_A_PROC, "Processor-specific PAL_A" }, + { FIT_ENTRY_PAL_A, "PAL_A" }, + { FIT_ENTRY_PAL_B, "PAL_B" }, + { FIT_ENTRY_SAL_A, "SAL_A" }, + { FIT_ENTRY_SAL_B, "SAL_B" }, + { FIT_ENTRY_SALRUNTIME, "SAL runtime" }, + { FIT_ENTRY_EFI, "EFI" }, + { FIT_ENTRY_VMLINUX, "Embedded Linux" }, + { FIT_ENTRY_FPSWA, "Embedded FPSWA" }, + { FIT_ENTRY_UNUSED, "Unused" }, + { 0xff, "Error" }, +}; + +static const char * +fit_type_name(unsigned char type) +{ + struct fit_type_map_t const*mapp; + + for (mapp = fit_entry_types; mapp->type != 0xff; mapp++) + if (type == mapp->type) + return mapp->name; + + if ((type > FIT_ENTRY_PAL_A) && (type < FIT_ENTRY_UNUSED)) + return "OEM type"; + if ((type > FIT_ENTRY_PAL_B) && (type < FIT_ENTRY_PAL_A)) + return "Reserved"; + + return "Unknown type"; +} + +/* These two routines read the FIT table directly from the FLASH PROM + * on a specific node. The PROM can only be accessed using aligned 64 + * bit reads, so we do that and then shift and mask the result to get + * at each field. + */ +static int +dump_fit_entry(char *page, unsigned long *fentry) +{ + unsigned long q1, q2; + unsigned type; + + TRACE(); + + q1 = readq(fentry); + q2 = readq(fentry + 1); + type = FIT_TYPE(q2); + return sprintf(page, "%02x %-25s %x.%02x %016lx %u\n", + type, + fit_type_name(type), + FIT_MAJOR(q2), FIT_MINOR(q2), + q1, + /* mult by sixteen to get size in bytes */ + (unsigned)q2 * 16); +} + +/* We assume that the fit table will be small enough that we can print + * the whole thing into one page. (This is true for our default 16kB + * pages -- each entry is about 60 chars wide when printed.) I read + * somewhere that the maximum size of the FIT is 128 entries, so we're + * OK except for 4kB pages (and no one is going to do that on SN + * anyway). + */ +static int +dump_fit(char *page, unsigned long *fit) +{ + unsigned long qw; + int nentries; + int fentry; + char *p; + + TRACE(); + + DPRINTK("dumping fit from %p\n", (void *)fit); + + qw = readq(fit); + DPRINTK("FIT signature: %016lx (%.8s)\n", qw, (char *)&qw); + if (qw != FIT_SIGNATURE) + printk(KERN_WARNING "Unrecognized FIT signature"); + + qw = readq(fit + 1); + nentries = (unsigned)qw; + DPRINTK("number of fit entries: %u\n", nentries); + /* check that we won't overflow the page -- see comment above */ + BUG_ON(nentries * 60 > PAGE_SIZE); + + p = page; + for (fentry = 0; fentry < nentries; fentry++) + /* each FIT entry is two 64 bit words */ + p += dump_fit_entry(p, fit + 2 * fentry); + + return p - page; +} + +static int +dump_version(char *page, unsigned long *fit) +{ + int nentries; + int fentry; + unsigned long qw; + + TRACE(); + + nentries = (unsigned)readq(fit + 1); + BUG_ON(nentries * 60 > PAGE_SIZE); + + for (fentry = 0; fentry < nentries; fentry++) { + qw = readq(fit + 2 * fentry + 1); + if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A) + return sprintf(page, "%x.%02x\n", + FIT_MAJOR(qw), FIT_MINOR(qw)); + } + return 0; +} + +/* same as in proc_misc.c */ +static int +proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof, + int len) +{ + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static int +read_version_entry(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + int len = 0; + + MOD_INC_USE_COUNT; + /* data holds the pointer to this node's FIT */ + len = dump_version(page, (unsigned long *)data); + len = proc_calc_metrics(page, start, off, count, eof, len); + MOD_DEC_USE_COUNT; + return len; +} + +static int +read_fit_entry(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + int len = 0; + + MOD_INC_USE_COUNT; + /* data holds the pointer to this node's FIT */ + len = dump_fit(page, (unsigned long *)data); + len = proc_calc_metrics(page, start, off, count, eof, len); + MOD_DEC_USE_COUNT; + + return len; +} + +/* this is a fake FIT that's used on the medusa simulator which + * doesn't usually run a complete PROM. + */ +#ifdef CONFIG_IA64_SGI_SN_SIM +static unsigned long fakefit[] = { + /* this is all we need to satisfy the code below */ + FIT_SIGNATURE, + FIT_ENTRY(FIT_ENTRY_FIT_HEADER, 0x02, 0x60, 2), + /* dump something arbitrary for + * /proc/sgi_prominfo/nodeX/version */ + 0xbadbeef00fa3ef17ul, + FIT_ENTRY(FIT_ENTRY_SAL_A, 0, 0x99, 0x100) +}; +#endif + +static unsigned long * +lookup_fit(int nasid) +{ + unsigned long *fitp; + unsigned long fit_paddr; + unsigned long *fit_vaddr; + +#ifdef CONFIG_IA64_SGI_SN_SIM + if (IS_RUNNING_ON_SIMULATOR()) + return fakefit; +#endif + + fitp = (void *)GLOBAL_MMR_ADDR(nasid, LB_PROM_SPACE - 32); + DPRINTK("pointer to fit at %p\n", (void *)fitp); + fit_paddr = readq(fitp); + DPRINTK("fit pointer contains %lx\n", fit_paddr); + /* snag just the node-relative offset */ + fit_paddr &= ~0ul >> (63-35); + /* the pointer to the FIT is relative to IA-64 compatibility + * space. However, the PROM is mapped at a different offset + * in MMR space (both local and global) + */ + fit_paddr += 0x700000000; + fit_vaddr = (void *)GLOBAL_MMR_ADDR(nasid, fit_paddr); + DPRINTK("fit at %p\n", (void *)fit_vaddr); + return fit_vaddr; +} + +/* module entry points */ +int __init prominfo_init(void); +void __exit prominfo_exit(void); + +module_init(prominfo_init); +module_exit(prominfo_exit); + +static struct proc_dir_entry **proc_entries; +static struct proc_dir_entry *sgi_prominfo_entry; + +#define NODE_NAME_LEN 11 + +int __init +prominfo_init(void) +{ + struct proc_dir_entry **entp; + cnodeid_t cnodeid; + nasid_t nasid; + char name[NODE_NAME_LEN]; + + if (!ia64_platform_is("sn2")) + return 0; + + TRACE(); + + DPRINTK("running on cpu %d\n", smp_processor_id()); + DPRINTK("numnodes %d\n", numnodes); + + proc_entries = kmalloc(numnodes * sizeof(struct proc_dir_entry *), + GFP_KERNEL); + + sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL); + + for (cnodeid = 0, entp = proc_entries; + cnodeid < numnodes; + cnodeid++, entp++) { + sprintf(name, "node%d", cnodeid); + *entp = proc_mkdir(name, sgi_prominfo_entry); + nasid = cnodeid_to_nasid(cnodeid); + create_proc_read_entry( + "fit", 0, *entp, read_fit_entry, + lookup_fit(nasid)); + create_proc_read_entry( + "version", 0, *entp, read_version_entry, + lookup_fit(nasid)); + } + + return 0; +} + +void __exit +prominfo_exit(void) +{ + struct proc_dir_entry **entp; + unsigned cnodeid; + char name[NODE_NAME_LEN]; + + TRACE(); + + for (cnodeid = 0, entp = proc_entries; + cnodeid < numnodes; + cnodeid++, entp++) { + remove_proc_entry("fit", *entp); + remove_proc_entry("version", *entp); + sprintf(name, "node%d", cnodeid); + remove_proc_entry(name, sgi_prominfo_entry); + } + remove_proc_entry("sgi_prominfo", NULL); + kfree(proc_entries); +} diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/ptc_deadlock.S linux-2.4.22/arch/ia64/sn/kernel/sn2/ptc_deadlock.S --- linux-2.4.21/arch/ia64/sn/kernel/sn2/ptc_deadlock.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/ptc_deadlock.S 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include @@ -61,20 +61,22 @@ cmp.ne p6,p0=zeroval,scr2 (p6) br.cond.sptk 5b;; - tbit.nz p6,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK + tbit.nz p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK (p7) st8.rel [ptc1]=data1;; // Now write PTC1. +5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete. + extr.u scr2=scr1,WRITECOUNT,7;;// PIO count + cmp.ne p6,p0=zeroval,scr2 +(p6) br.cond.sptk 5b + + tbit.nz p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK + mov psr.l=psrsave;; // Reenable IC srlz.i;; ////////////// END PHYSICAL MODE //////////////////// -(p6) br.cond.spnt 1b;; // Repeat if DEADLOCK occurred. +(p8) br.cond.spnt 1b;; // Repeat if DEADLOCK occurred. -5: ld8.acq scr1=[piowc];; // Wait for PIOs to complete. - extr.u scr2=scr1,WRITECOUNT,7;;// PIO count - cmp.ne p6,p0=zeroval,scr2 -(p6) br.cond.sptk 5b - br.ret.sptk rp .endp sn2_ptc_deadlock_recovery_core diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/sn2_smp.c linux-2.4.22/arch/ia64/sn/kernel/sn2/sn2_smp.c --- linux-2.4.21/arch/ia64/sn/kernel/sn2/sn2_smp.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/sn2_smp.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * SN2 Platform specific SMP Support * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -79,296 +79,6 @@ return ws; } -static long use_tlb_hack; -static volatile unsigned long zz[1024] __attribute__((__aligned__(128))); -static inline long -get_itc(void) -{ - long ret; - __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret)); - return ret+1; -} - - - -#ifdef PTCG_WAR -/* - * The following structure is used to pass params thru smp_call_function - * to other cpus for flushing TLB ranges. - */ -typedef struct { - unsigned long start; - unsigned long end; - unsigned long nbits; - unsigned int rid; - atomic_t unfinished_count; - char fill[96]; -} ptc_params_t; - -#define NUMPTC 512 - -static ptc_params_t ptcParamArray[NUMPTC] __attribute__((__aligned__(128))); - -/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */ -static ptc_params_t *ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128))); -static volatile ptc_params_t *ptcParamsEmpty __cacheline_aligned; - -/*REFERENCED*/ -static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED; - -static int ptcInit = 0; -#ifdef PTCDEBUG -static int ptcParamsAllBusy = 0; /* debugging/statistics */ -static int ptcCountBacklog = 0; -static int ptcBacklog[NUMPTC+1]; -static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128))); -static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128))); -#endif - -/* - * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference, - * so that we get a clean compile with the ia64 patch without the - * actual SN1 specific code in arch/ia64/kernel/smp.c. - */ -extern void smp_send_flush_tlb (void) __attribute((weak)); - - -/** - * sn1_ptc_l_range - purge local translation cache - * @start: start of virtual address range - * @end: end of virtual address range - * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc)) - * - * Purges the range specified from the local processor's translation cache - * (as opposed to the translation registers). Note that more than the specified - * range *may* be cleared from the cache by some processors. - * - * This is probably not good enough, but I don't want to try to make it better - * until I get some statistics on a running system. At a minimum, we should only - * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's - * own FSB. Also, we only have to serialize per FSB, not globally. - * - * More likely, we will have to do some work to reduce the frequency of calls to - * this routine. - */ -static inline void -sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits) -{ - do { - __asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory"); - start += (1UL << nbits); - } while (start < end); - ia64_srlz_d(); -} - -/** - * sn1_received_flush_tlb - cpu tlb flush routine - * - * Flushes the TLB of a given processor. - */ -void -sn1_received_flush_tlb(void) -{ - unsigned long start, end, nbits; - unsigned int rid, saved_rid; - int cpu = smp_processor_id(); - int result; - ptc_params_t *ptcParams; - - ptcParams = ptcParamsNextByCpu[cpu*16]; - if (ptcParams == ptcParamsEmpty) - return; - - do { - start = ptcParams->start; - saved_rid = (unsigned int) ia64_get_rr(start); - end = ptcParams->end; - nbits = ptcParams->nbits; - rid = ptcParams->rid; - - if (saved_rid != rid) { - ia64_set_rr(start, (unsigned long)rid); - ia64_srlz_d(); - } - - sn1_ptc_l_range(start, end, nbits); - - if (saved_rid != rid) - ia64_set_rr(start, (unsigned long)saved_rid); - - ia64_srlz_i(); - - result = atomic_dec(&ptcParams->unfinished_count); -#ifdef PTCDEBUG - { - int i = ptcParams-&ptcParamArray[0]; - ptcParamsResults[cpu][i] = (char) result; - ptcParamsCounts[cpu][i]++; - } -#endif /* PTCDEBUG */ - - if (++ptcParams == &ptcParamArray[NUMPTC]) - ptcParams = &ptcParamArray[0]; - - } while (ptcParams != ptcParamsEmpty); - - ptcParamsNextByCpu[cpu*16] = ptcParams; -} - -/** - * sn1_global_tlb_purge - flush a translation cache range on all processors - * @start: start of virtual address range to flush - * @end: end of virtual address range - * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc)) - * - * Flushes the translation cache of all processors from @start to @end. - */ -void -sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits) -{ - ptc_params_t *params; - ptc_params_t *next; - unsigned long irqflags; -#ifdef PTCDEBUG - ptc_params_t *nextnext; - int backlog = 0; -#endif - - if (smp_num_cpus == 1) { - sn1_ptc_l_range(start, end, nbits); - return; - } - - if (in_interrupt()) { - /* - * If at interrupt level and cannot get spinlock, - * then do something useful by flushing own tlbflush queue - * so as to avoid a possible deadlock. - */ - while (!spin_trylock(&ptcParamsLock)) { - local_irq_save(irqflags); - sn1_received_flush_tlb(); - local_irq_restore(irqflags); - udelay(10); /* take it easier on the bus */ - } - } else { - spin_lock(&ptcParamsLock); - } - - if (!ptcInit) { - int cpu; - ptcInit = 1; - memset(ptcParamArray, 0, sizeof(ptcParamArray)); - ptcParamsEmpty = &ptcParamArray[0]; - for (cpu=0; cpu= &ptcParamArray[0]) { - if (atomic_read(&ptr->unfinished_count) == 0) - break; - ++backlog; - } - - if (backlog) { - /* check the end of the array */ - ptr = &ptcParamArray[NUMPTC]; - while (--ptr > params) { - if (atomic_read(&ptr->unfinished_count) == 0) - break; - ++backlog; - } - } - ptcBacklog[backlog]++; - } -#endif /* PTCDEBUG */ - - /* wait for the next entry to clear...should be rare */ - if (atomic_read(&next->unfinished_count) > 0) { -#ifdef PTCDEBUG - ptcParamsAllBusy++; - - if (atomic_read(&nextnext->unfinished_count) == 0) { - if (atomic_read(&next->unfinished_count) > 0) { - panic("\nnonzero next zero nextnext %lx %lx\n", - (long)next, (long)nextnext); - } - } -#endif - - /* it could be this cpu that is behind */ - local_irq_save(irqflags); - sn1_received_flush_tlb(); - local_irq_restore(irqflags); - - /* now we know it's not this cpu, so just wait */ - while (atomic_read(&next->unfinished_count) > 0) { - barrier(); - } - } - - params->start = start; - params->end = end; - params->nbits = nbits; - params->rid = (unsigned int) ia64_get_rr(start); - atomic_set(¶ms->unfinished_count, smp_num_cpus); - - /* The atomic_set above can hit memory *after* the update - * to ptcParamsEmpty below, which opens a timing window - * that other cpus can squeeze into! - */ - mb(); - - /* everything is ready to process: - * -- global lock is held - * -- new entry + 1 is free - * -- new entry is set up - * so now: - * -- update the global next pointer - * -- unlock the global lock - * -- send IPI to notify other cpus - * -- process the data ourselves - */ - ptcParamsEmpty = next; - spin_unlock(&ptcParamsLock); - smp_send_flush_tlb(); - - local_irq_save(irqflags); - sn1_received_flush_tlb(); - local_irq_restore(irqflags); - - /* - * Since IPIs are polled event (for now), we need to wait til the - * TLB flush has started. - * wait for the flush to complete - */ - while (atomic_read(¶ms->unfinished_count) > 0) - barrier(); -} - -#endif /* PTCG_WAR */ /** @@ -384,19 +94,10 @@ void sn2_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits) { - int cnode, mycnode, nasid; + int cnode, mycnode, nasid, flushed=0; volatile unsigned long *ptc0, *ptc1; unsigned long flags=0, data0, data1; - long zzbase, zztime, zztime2; - /* - * Special case 1 cpu & 1 node. Use local purges. - */ -#ifdef PTCG_WAR - sn1_global_tlb_purge(start, end, nbits); - return; -#endif /* PTCG_WAR */ - data0 = (1UL<>8)<shared_mm || test_bit(cnode, current->node_history)) { nasid = cnodeid_to_nasid(cnode); ptc0 = CHANGE_NASID(nasid, ptc0); ptc1 = CHANGE_NASID(nasid, ptc1); pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1); + flushed = 1; } } - if (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK) { - zz[zzbase+1]++; + if (flushed && (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK)) { sn2_ptc_deadlock_recovery(data0, data1); } @@ -444,20 +134,8 @@ } while (start < end); - zz[zzbase+0] -= 0xffffffff00000000UL; - zztime2 = get_itc() - zztime2; spin_unlock_irqrestore(&sn2_global_ptc_lock, flags); - zztime = get_itc() - zztime; - - zz[zzbase+6] += zztime; - if (zztime > zz[zzbase+7]) - zz[zzbase+7] = zztime; - - zz[zzbase+8] += zztime2; - if (zztime2 > zz[zzbase+9]) - zz[zzbase+9] = zztime2; - } /* @@ -480,7 +158,7 @@ ptc1 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1); piows = (long*)pda.pio_write_status_addr; - mycnode = local_cnodeid(); + mycnode = numa_node_id(); for (cnode = 0; cnode < numnodes; cnode++) { if (is_headless_node(cnode) || cnode == mycnode) @@ -511,16 +189,10 @@ void sn_send_IPI_phys(long physid, int vector, int delivery_mode) { - long nasid, slice; - long val; + long nasid, slice, val; + unsigned long flags=0; volatile long *p; -#if defined(BUS_INT_WAR) && defined(CONFIG_SHUB_1_0_SPECIFIC) - if (vector != ap_wakeup_vector && delivery_mode == IA64_IPI_DM_INT) { - return; - } -#endif - nasid = cpu_physical_id_to_nasid(physid); slice = cpu_physical_id_to_slice(physid); @@ -532,12 +204,15 @@ (0x000feeUL< - - -static struct proc_dir_entry *ptcg_stats; - -static int -ptcg_read_proc(char *buffer, char **start, off_t off, int count, int *eof, void *data) -{ - long cpu, *p, cnt; - int len = 0; - - p = (long*)LOCAL_MMR_ADDR(SH_DIAG_MSG_DATA7L); - len += sprintf(buffer + len, "PTCG Stats (option 0x%lx)\n", use_tlb_hack); - - len += sprintf(buffer + len, "%-14s", "CPU"); - for (cpu=0; cpucyc_per_usec : 0); - } - len += sprintf(buffer + len, "\n"); - - len += sprintf(buffer + len, "%-14s", "max-us"); - for (cpu=0; cpucyc_per_usec); - len += sprintf(buffer + len, "\n"); - - len += sprintf(buffer + len, "%-14s", "iaver-us"); - for (cpu=0; cpucyc_per_usec : 0); - } - len += sprintf(buffer + len, "\n"); - - len += sprintf(buffer + len, "%-14s", "imax-us"); - for (cpu=0; cpucyc_per_usec); - len += sprintf(buffer + len, "\n"); - - len += sprintf(buffer + len, "%-14s", "long-piowc"); - for (cpu=0; cpucount) len = count; - if (len<0) len = 0; - return len; -} - - -static int -ptcg_write_proc (struct file *file, const char *userbuf, unsigned long count, void *data) -{ - extern long atoi(char *); - char buf[80]; - long val; - long cpu; - long *p; - - if (copy_from_user(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf))) - return -EFAULT; - - val = atoi(buf); - if (val&4) val |= 1; - use_tlb_hack = val; - - memset((void*)zz, 0, sizeof(zz)); - - for (cpu=0; cpuread_proc = ptcg_read_proc; - ptcg_stats->write_proc = ptcg_write_proc; - return 0; -} - -#include -module_init(sn2_ptcg_stats_init); diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/sn_proc_fs.c linux-2.4.22/arch/ia64/sn/kernel/sn2/sn_proc_fs.c --- linux-2.4.21/arch/ia64/sn/kernel/sn2/sn_proc_fs.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/sn_proc_fs.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -31,6 +31,7 @@ * http://oss.sgi.com/projects/GenInfo/NoticeExplan */ #include +#include #ifdef CONFIG_PROC_FS #include @@ -43,7 +44,7 @@ return sprintf(page, "%d\n", sn_local_partid()); } -struct proc_dir_entry * sgi_proc_dir = NULL; +static struct proc_dir_entry * sgi_proc_dir; void register_sn_partition_id(void) { @@ -96,4 +97,99 @@ } } +// Disable forced interrupts, but leave the code in, just in case. +int sn_force_interrupt_flag = 0; + +static int +sn_force_interrupt_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { + if (sn_force_interrupt_flag) { + return sprintf(page, "Force interrupt is enabled\n"); + } + return sprintf(page, "Force interrupt is disabled\n"); +} + +static int +sn_force_interrupt_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + if (*buffer == '0') { + sn_force_interrupt_flag = 0; + } else { + sn_force_interrupt_flag = 1; + } + return 1; +} + +void +register_sn_force_interrupt(void) { + struct proc_dir_entry *entry; + + if (!sgi_proc_dir) { + sgi_proc_dir = proc_mkdir("sgi_sn", 0); + } + entry = create_proc_entry("sn_force_interrupt",0444, sgi_proc_dir); + if (entry) { + entry->nlink = 1; + entry->data = 0; + entry->read_proc = sn_force_interrupt_read_proc; + entry->write_proc = sn_force_interrupt_write_proc; + } +} + +extern int sn_linkstats_get(char *); +extern int sn_linkstats_reset(unsigned long); + +static int +sn_linkstats_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { + + return sn_linkstats_get(page); +} + +static int +sn_linkstats_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char s[64]; + unsigned long msecs; + int e = count; + + if (copy_from_user(s, buffer, count < sizeof(s) ? count : sizeof(s))) + e = -EFAULT; + else { + if (sscanf(s, "%lu", &msecs) != 1 || msecs < 5) + /* at least 5 milliseconds between updates */ + e = -EINVAL; + else + sn_linkstats_reset(msecs); + } + + return e; +} + +void +register_sn_linkstats(void) { + struct proc_dir_entry *entry; + + if (!sgi_proc_dir) { + sgi_proc_dir = proc_mkdir("sgi_sn", 0); + } + entry = create_proc_entry("linkstats", 0444, sgi_proc_dir); + if (entry) { + entry->nlink = 1; + entry->data = 0; + entry->read_proc = sn_linkstats_read_proc; + entry->write_proc = sn_linkstats_write_proc; + } +} + +void +register_sn_procfs(void) { + register_sn_partition_id(); + register_sn_serial_numbers(); + register_sn_force_interrupt(); + register_sn_linkstats(); +} + #endif /* CONFIG_PROC_FS */ diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn2/timer.c linux-2.4.22/arch/ia64/sn/kernel/sn2/timer.c --- linux-2.4.21/arch/ia64/sn/kernel/sn2/timer.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ia64/sn/kernel/sn2/timer.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,100 @@ +/* + * linux/arch/ia64/sn/kernel/sn2/timer.c + * + * Copyright (C) 2003 Silicon Graphics, Inc. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +extern unsigned long sn_rtc_cycles_per_second; +static volatile unsigned long last_wall_rtc; + +/** + * gettimeoffset - number of usecs elapsed since &xtime was last updated + * + * This function is used by do_gettimeofday() to determine the number + * of usecs that have elapsed since the last update to &xtime. On SN + * this is accomplished using the RTC built in to each Hub chip; each + * is guaranteed to be synchronized by the PROM, so a local read will + * suffice (GET_RTC_COUNTER() does this for us). A snapshot of the RTC + * value is taken every time wall_jiffies is updated by the + * update_wall_time_hook (sn2_update_wall_time) which means we don't + * have to adjust for lost jiffies ticks or anything like that. + */ +extern unsigned long wall_jiffies; /* from kernel/timer.c */ + +static volatile long rtc_offset; +static long rtc_cycles_per_usec; +static long rtc_per_timer_tick; + +unsigned long +sn_gettimeoffset(void) +{ + long current_rtc, elapsed_rtc, old, new_offset; + + do { + old = rtc_offset; + current_rtc = GET_RTC_COUNTER(); + + /* + * Need to address wrapping here! + */ + elapsed_rtc = (long)(current_rtc - last_wall_rtc); + + /* + * This case is non lethal as the max() will take care of it. + */ +#if 0 + if (elapsed_rtc < 0) { + printk(KERN_ERR "sn_gettimeoffset(): time goes " + "backwards!\n current_rtc 0x%016lx, " + "last_wall_rtc 0x%016lx, elapsed %08lx, " + "offset %li\n", current_rtc, last_wall_rtc, + elapsed_rtc, max(elapsed_rtc, rtc_offset)/ + rtc_cycles_per_usec); + } +#endif + + new_offset = max(elapsed_rtc, old); + } while (cmpxchg(&rtc_offset, old, new_offset) != old); + + return new_offset / rtc_cycles_per_usec; +} + + +void sn2_update_wall_time(void) +{ + rtc_offset -= min(rtc_offset, rtc_per_timer_tick); + last_wall_rtc = GET_RTC_COUNTER(); +} + + +void sn2_reset_wall_time(void) +{ + rtc_offset = 0; + last_wall_rtc = GET_RTC_COUNTER(); +} + + +void __init +sn_timer_init(void) +{ + rtc_per_timer_tick = sn_rtc_cycles_per_second / HZ; + rtc_cycles_per_usec = sn_rtc_cycles_per_second / 1000000; + + last_wall_rtc = GET_RTC_COUNTER(); + update_wall_time_hook = sn2_update_wall_time; + reset_wall_time_hook = sn2_reset_wall_time; + gettimeoffset = sn_gettimeoffset; +} diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn_asm.S linux-2.4.22/arch/ia64/sn/kernel/sn_asm.S --- linux-2.4.21/arch/ia64/sn/kernel/sn_asm.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn_asm.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan - */ - -#include -#ifdef CONFIG_IA64_SGI_AUTOTEST - -// Testing only. -// Routine will cause MCAs -// zzzmca(n) -// n=0 MCA via duplicate TLB dropin -// n=1 MCA via read of garbage address -// n=2 MCA via lfetch read of garbage address -// - -#define ITIR(key, ps) ((key<<8) | (ps<<2)) -#define TLB_PAGESIZE 28 // Use 256MB pages for now. - - .global zzzmca - .proc zzzmca -zzzmca: - alloc loc4 = ar.pfs,2,8,1,0;; - cmp.ne p6,p0=r32,r0;; - movl r2=0x2dead - movl r3=0x3dead - movl r15=0x15dead - movl r16=0x16dead - movl r31=0x31dead - movl loc0=0x34beef - movl loc1=0x35beef - movl loc2=0x36beef - movl loc3=0x37beef - movl out0=0x42beef - - movl r20=0x32feed;; - mov ar32=r20 - movl r20=0x36feed;; - mov ar36=r20 - movl r20=0x65feed;; - mov ar65=r20 - movl r20=0x66feed;; - mov ar66=r20 - -(p6) br.cond.sptk 1f - - rsm 0x2000;; - srlz.d; - mov r11 = 5 - mov r3 = ITIR(0,TLB_PAGESIZE);; - mov cr.itir = r3 - mov r10 = 0;; - itr.d dtr[r11] = r10;; - mov r11 = 6 - - itr.d dtr[r11] = r10;; - br 9f - -1: - cmp.eq p6,p7=1,r32 -#ifdef CONFIG_IA64_SGI_SN1 - movl r8=0xe00000fe00000048;; -#else - movl r8=0xe0007fb000000048;; -#endif - (p6) ld8 r9=[r8] - (p7) lfetch.fault.nt2 [r8] - ;; - mf - ;; - mf.a - ;; - srlz.d - -9: mov ar.pfs=loc4 - br.ret.sptk rp - - .endp zzzmca - -#endif diff -urN linux-2.4.21/arch/ia64/sn/kernel/sn_ksyms.c linux-2.4.22/arch/ia64/sn/kernel/sn_ksyms.c --- linux-2.4.21/arch/ia64/sn/kernel/sn_ksyms.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sn_ksyms.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. */ @@ -18,8 +18,8 @@ #include #include -#include -extern devfs_handle_t base_io_scsi_ctlr_vhdl[]; +#include +extern vertex_hdl_t base_io_scsi_ctlr_vhdl[]; #include extern cnodeid_t master_node_get(devfs_handle_t vhdl); #include @@ -31,9 +31,9 @@ * symbols referenced by the PCIBA module */ #include -#include #include #include +#include devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn); @@ -54,29 +54,26 @@ EXPORT_SYMBOL(sn_send_IPI_phys); /* symbols referenced by partitioning modules */ -#include +#include +EXPORT_SYMBOL(bte_copy); EXPORT_SYMBOL(bte_unaligned_copy); #include EXPORT_SYMBOL(ia64_sal); +EXPORT_SYMBOL(physical_node_map); -#ifdef CONFIG_IA64_SGI_SN2 #include EXPORT_SYMBOL(sal_lock); EXPORT_SYMBOL(sn_partid); EXPORT_SYMBOL(sn_local_partid); EXPORT_SYMBOL(sn_system_serial_number_string); EXPORT_SYMBOL(sn_partition_serial_number); -#endif + +EXPORT_SYMBOL(sn_mmiob); /* added by tduffy 04.08.01 to fix depmod issues */ #include -#ifdef BUS_INT_WAR -extern void sn_add_polled_interrupt(int, int); -extern void sn_delete_polled_interrupt(int); -EXPORT_SYMBOL(sn_add_polled_interrupt); -EXPORT_SYMBOL(sn_delete_polled_interrupt); -#endif - extern nasid_t master_nasid; EXPORT_SYMBOL(master_nasid); + +EXPORT_SYMBOL(sn_flush_all_caches); diff -urN linux-2.4.21/arch/ia64/sn/kernel/sv.c linux-2.4.22/arch/ia64/sn/kernel/sv.c --- linux-2.4.21/arch/ia64/sn/kernel/sv.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/kernel/sv.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This implemenation of synchronization variables is heavily based on * one done by Steve Lord diff -urN linux-2.4.21/arch/ia64/sn/tools/make_textsym linux-2.4.22/arch/ia64/sn/tools/make_textsym --- linux-2.4.21/arch/ia64/sn/tools/make_textsym 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/sn/tools/make_textsym 1969-12-31 16:00:00.000000000 -0800 @@ -1,171 +0,0 @@ -#!/bin/sh -# -# Build a textsym file for use in the Arium ITP probe. -# -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (c) 2001-2002 Silicon Graphics, Inc. All rights reserved. -# - -help() { -cat < []] - If no input file is specified, it defaults to vmlinux. - If no output file name is specified, it defaults to "textsym". -END -exit 1 -} - -err () { - echo "ERROR - $*" >&2 - exit 1 -} - - -OPTS="H" -while getopts "$OPTS" c ; do - case $c in - H) help;; - \?) help;; - esac - -done -shift `expr $OPTIND - 1` - -LINUX=${1:-vmlinux} -TEXTSYM=${2:-${LINUX}.sym} -TMPSYM=${2:-${LINUX}.sym.tmp} -trap "/bin/rm -f $TMPSYM" 0 - -[ -f $VMLINUX ] || help - -$OBJDUMP -t $LINUX | egrep -v '__ks' | sort > $TMPSYM -SN1=`egrep "dig_setup|Synergy_da_indr" $TMPSYM|wc -l` - -# Dataprefix and textprefix correspond to the VGLOBAL_BASE and VPERNODE_BASE. -# Eventually, these values should be: -# dataprefix ffffffff -# textprefix fffffffe -# but right now they're still changing, so make them dynamic. -dataprefix=`awk ' / \.data / { print substr($1, 0, 8) ; exit ; }' $TMPSYM` -textprefix=`awk ' / \.text / { print substr($1, 0, 8) ; exit ; }' $TMPSYM` - -# pipe everything thru sort -echo "TEXTSYM V1.0" -(cat < 0) { - n = n*16 + substr(s,1,1) - s = substr(s,2) - } - printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, n - } - } - if($NF == "_end") - exit - -} -' $TMPSYM ) | egrep -v " __device| __vendor" | awk -v sn1="$SN1" ' -/GLOBAL/ { - print $0 - if (sn1 != 0) { - /* 32 bits of sn1 physical addrs, */ - print substr($0,1,9) "04" substr($0,20,16) "Phy_" substr($0,36) - } else { - /* 38 bits of sn2 physical addrs, need addr space bits */ - print substr($0,1,9) "3004" substr($0,20,16) "Phy_" substr($0,36) - } - -} ' | sort -k3 - -N=`wc -l $TEXTSYM|awk '{print $1}'` -echo "Generated TEXTSYM file" >&2 -echo " $LINUX --> $TEXTSYM" >&2 -echo " Found $N symbols" >&2 diff -urN linux-2.4.21/arch/ia64/tools/print_offsets.c linux-2.4.22/arch/ia64/tools/print_offsets.c --- linux-2.4.21/arch/ia64/tools/print_offsets.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/ia64/tools/print_offsets.c 2003-08-25 04:44:39.000000000 -0700 @@ -10,7 +10,7 @@ * gets translated into an assembly file which, in turn, is processed * by awk to generate offsets.h. So if you make any changes to this * file, be sure to verify that the awk procedure still works (see - * prin_offsets.awk). + * print_offsets.awk). */ #include diff -urN linux-2.4.21/arch/ia64/vmlinux.lds.S linux-2.4.22/arch/ia64/vmlinux.lds.S --- linux-2.4.21/arch/ia64/vmlinux.lds.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ia64/vmlinux.lds.S 2003-08-25 04:44:39.000000000 -0700 @@ -27,6 +27,7 @@ _text = .; _stext = .; + .text : AT(ADDR(.text) - PAGE_OFFSET) { *(.text.ivt) @@ -47,38 +48,48 @@ /* Exception table */ . = ALIGN(16); - __start___ex_table = .; __ex_table : AT(ADDR(__ex_table) - PAGE_OFFSET) - { *(__ex_table) } - __stop___ex_table = .; + { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } #if defined(CONFIG_IA64_GENERIC) /* Machine Vector */ . = ALIGN(16); - machvec_start = .; .machvec : AT(ADDR(.machvec) - PAGE_OFFSET) - { *(.machvec) } - machvec_end = .; + { + machvec_start = .; + *(.machvec) + machvec_end = .; + } #endif - __start___ksymtab = .; /* Kernel symbol table */ __ksymtab : AT(ADDR(__ksymtab) - PAGE_OFFSET) - { *(__ksymtab) } - __stop___ksymtab = .; + { + __start___ksymtab = .; /* Kernel symbol table */ + *(__ksymtab) + __stop___ksymtab = .; + } - __start___kallsyms = .; /* All kernel symbols for debugging */ __kallsyms : AT(ADDR(__kallsyms) - PAGE_OFFSET) - { *(__kallsyms) } - __stop___kallsyms = .; + { + __start___kallsyms = .; /* All kernel symbols for debugging */ + *(__kallsyms) + __stop___kallsyms = .; + } /* Unwind info & table: */ . = ALIGN(8); .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET) { *(.IA_64.unwind_info*) } - ia64_unw_start = .; .IA_64.unwind : AT(ADDR(.IA_64.unwind) - PAGE_OFFSET) - { *(.IA_64.unwind*) } - ia64_unw_end = .; + { + ia64_unw_start = .; + *(.IA_64.unwind*) + ia64_unw_end = .; + } .rodata : AT(ADDR(.rodata) - PAGE_OFFSET) { *(.rodata) *(.rodata.*) } @@ -97,14 +108,18 @@ .data.init : AT(ADDR(.data.init) - PAGE_OFFSET) { *(.data.init) } . = ALIGN(16); - __setup_start = .; .setup.init : AT(ADDR(.setup.init) - PAGE_OFFSET) - { *(.setup.init) } - __setup_end = .; - __initcall_start = .; + { + __setup_start = .; + *(.setup.init) + __setup_end = .; + } .initcall.init : AT(ADDR(.initcall.init) - PAGE_OFFSET) - { *(.initcall.init) } - __initcall_end = .; + { + __initcall_start = .; + *(.initcall.init) + __initcall_end = .; + } . = ALIGN(PAGE_SIZE); __init_end = .; diff -urN linux-2.4.21/arch/m68k/apollo/config.c linux-2.4.22/arch/m68k/apollo/config.c --- linux-2.4.21/arch/m68k/apollo/config.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/m68k/apollo/config.c 2003-08-25 04:44:39.000000000 -0700 @@ -183,10 +183,6 @@ mach_hwclk = dn_dummy_hwclk; /* */ mach_set_clock_mmss = dn_dummy_set_clock_mmss; /* */ mach_process_int = dn_process_int; -#ifdef CONFIG_BLK_DEV_FD - mach_floppy_init = dn_dummy_floppy_init; - mach_floppy_setup = dn_dummy_floppy_setup; -#endif mach_reset = dn_dummy_reset; /* */ #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; diff -urN linux-2.4.21/arch/m68k/config.in linux-2.4.22/arch/m68k/config.in --- linux-2.4.21/arch/m68k/config.in 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/m68k/config.in 2003-08-25 04:44:39.000000000 -0700 @@ -562,4 +562,5 @@ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/m68k/kernel/m68k_ksyms.c linux-2.4.22/arch/m68k/kernel/m68k_ksyms.c --- linux-2.4.21/arch/m68k/kernel/m68k_ksyms.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/m68k/kernel/m68k_ksyms.c 2003-08-25 04:44:39.000000000 -0700 @@ -44,7 +44,6 @@ EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(mm_end_of_chunk); #endif /* !CONFIG_SINGLE_MEMORY_CHUNK */ -EXPORT_SYMBOL(mm_vtop_fallback); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(kernel_set_cachemode); diff -urN linux-2.4.21/arch/m68k/mac/config.c linux-2.4.22/arch/m68k/mac/config.c --- linux-2.4.21/arch/m68k/mac/config.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/m68k/mac/config.c 2003-08-25 04:44:39.000000000 -0700 @@ -91,7 +91,7 @@ extern void mackbd_leds(unsigned int leds); extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode); -extern void mac_hid_init_hw(void); +extern void __init mac_hid_init_hw(void); extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode); #ifdef CONFIG_MAGIC_SYSRQ @@ -202,6 +202,14 @@ restore_flags(cpu_flags); } +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) +static int __init mac_keyb_init(void) +{ + mac_hid_init_hw(); + return 0; +} +#endif + void __init config_mac(void) { if (!MACH_IS_MAC) { @@ -210,7 +218,7 @@ #ifdef CONFIG_VT #ifdef CONFIG_INPUT_ADBHID - mach_keyb_init = mac_hid_init_hw; + mach_keyb_init = mac_keyb_init; mach_kbd_translate = mac_hid_kbd_translate; #ifdef CONFIG_MAGIC_SYSRQ #ifdef CONFIG_MAC_ADBKEYCODES diff -urN linux-2.4.21/arch/m68k/mm/memory.c linux-2.4.22/arch/m68k/mm/memory.c --- linux-2.4.21/arch/m68k/mm/memory.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/m68k/mm/memory.c 2003-08-25 04:44:39.000000000 -0700 @@ -196,34 +196,6 @@ return 0; } -static unsigned long transp_transl_matches( unsigned long regval, - unsigned long vaddr ) -{ - unsigned long base, mask; - - /* enabled? */ - if (!(regval & 0x8000)) - return( 0 ); - - if (CPU_IS_030) { - /* function code match? */ - base = (regval >> 4) & 7; - mask = ~(regval & 7); - if (((SUPER_DATA ^ base) & mask) != 0) - return 0; - } - else { - /* must not be user-only */ - if ((regval & 0x6000) == 0) - return( 0 ); - } - - /* address match? */ - base = regval & 0xff000000; - mask = ~(regval << 8) & 0xff000000; - return (((unsigned long)vaddr ^ base) & mask) == 0; -} - #if DEBUG_INVALID_PTOV int mm_inv_cnt = 5; #endif @@ -253,134 +225,9 @@ if (voff == 0) return m68k_memory[i-1].addr + m68k_memory[i-1].size; - return mm_vtop_fallback(vaddr); -} -#endif - -/* Separate function to make the common case faster (needs to save less - registers) */ -unsigned long mm_vtop_fallback(unsigned long vaddr) -{ - /* not in one of the memory chunks; test for applying transparent - * translation */ - - if (CPU_IS_030) { - unsigned long ttreg; - - asm volatile( ".chip 68030\n\t" - "pmove %/tt0,%0@\n\t" - ".chip 68k" - : : "a" (&ttreg) ); - if (transp_transl_matches( ttreg, vaddr )) - return (unsigned long)vaddr; - asm volatile( ".chip 68030\n\t" - "pmove %/tt1,%0@\n\t" - ".chip 68k" - : : "a" (&ttreg) ); - if (transp_transl_matches( ttreg, vaddr )) - return (unsigned long)vaddr; - } - else if (CPU_IS_040_OR_060) { - unsigned long ttreg; - - asm volatile( ".chip 68040\n\t" - "movec %%dtt0,%0\n\t" - ".chip 68k" - : "=d" (ttreg) ); - if (transp_transl_matches( ttreg, vaddr )) - return (unsigned long)vaddr; - asm volatile( ".chip 68040\n\t" - "movec %%dtt1,%0\n\t" - ".chip 68k" - : "=d" (ttreg) ); - if (transp_transl_matches( ttreg, vaddr )) - return (unsigned long)vaddr; - } - - /* no match, too, so get the actual physical address from the MMU. */ - - if (CPU_IS_060) { - mm_segment_t fs = get_fs(); - unsigned long paddr; - - set_fs (MAKE_MM_SEG(SUPER_DATA)); - - /* The PLPAR instruction causes an access error if the translation - * is not possible. To catch this we use the same exception mechanism - * as for user space accesses in . */ - asm volatile (".chip 68060\n" - "1: plpar (%0)\n" - ".chip 68k\n" - "2:\n" - ".section .fixup,\"ax\"\n" - " .even\n" - "3: lea -1,%0\n" - " jra 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 1b,3b\n" - ".previous" - : "=a" (paddr) - : "0" (vaddr)); - set_fs (fs); - - return paddr; - - } else if (CPU_IS_040) { - unsigned long mmusr; - mm_segment_t fs = get_fs(); - - set_fs (MAKE_MM_SEG(SUPER_DATA)); - - asm volatile (".chip 68040\n\t" - "ptestr (%1)\n\t" - "movec %%mmusr, %0\n\t" - ".chip 68k" - : "=r" (mmusr) - : "a" (vaddr)); - set_fs (fs); - - if (mmusr & MMU_T_040) { - return (unsigned long)vaddr; /* Transparent translation */ - } - if (mmusr & MMU_R_040) - return (mmusr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1)); - - printk("VTOP040: bad virtual address %lx (%lx)", vaddr, mmusr); - return -1; - } else { - volatile unsigned short temp; - unsigned short mmusr; - unsigned long *descaddr; - - asm volatile ("ptestr #5,%2@,#7,%0\n\t" - "pmove %/psr,%1@" - : "=a&" (descaddr) - : "a" (&temp), "a" (vaddr)); - mmusr = temp; - - if (mmusr & (MMU_I|MMU_B|MMU_L)) - printk("VTOP030: bad virtual address %lx (%x)\n", vaddr, mmusr); - - descaddr = phys_to_virt((unsigned long)descaddr); - - switch (mmusr & MMU_NUM) { - case 1: - return (*descaddr & 0xfe000000) | ((unsigned long)vaddr & 0x01ffffff); - case 2: - return (*descaddr & 0xfffc0000) | ((unsigned long)vaddr & 0x0003ffff); - case 3: - return (*descaddr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1)); - default: - printk("VTOP: bad levels (%u) for virtual address %lx\n", - mmusr & MMU_NUM, vaddr); - } - } - - printk("VTOP: bad virtual address %lx\n", vaddr); return -1; } +#endif #ifndef CONFIG_SINGLE_MEMORY_CHUNK unsigned long mm_ptov (unsigned long paddr) @@ -406,29 +253,6 @@ paddr, __builtin_return_address(0)); } #endif - /* - * assume that the kernel virtual address is the same as the - * physical address. - * - * This should be reasonable in most situations: - * 1) They shouldn't be dereferencing the virtual address - * unless they are sure that it is valid from kernel space. - * 2) The only usage I see so far is converting a page table - * reference to some non-FASTMEM address space when freeing - * mmaped "/dev/mem" pages. These addresses are just passed - * to "free_page", which ignores addresses that aren't in - * the memory list anyway. - * - */ - -#ifdef CONFIG_AMIGA - /* - * if on an amiga and address is in first 16M, move it - * to the ZTWO_VADDR range - */ - if (MACH_IS_AMIGA && paddr < 16*1024*1024) - return ZTWO_VADDR(paddr); -#endif return -1; } #endif diff -urN linux-2.4.21/arch/m68k/mm/motorola.c linux-2.4.22/arch/m68k/mm/motorola.c --- linux-2.4.21/arch/m68k/mm/motorola.c 2001-04-06 10:42:48.000000000 -0700 +++ linux-2.4.22/arch/m68k/mm/motorola.c 2003-08-25 04:44:39.000000000 -0700 @@ -226,18 +226,6 @@ for (i = 0; i < 16; i++) pgprot_val(protection_map[i]) |= _PAGE_CACHE040; } - /* Fix the PAGE_NONE value. */ - if (CPU_IS_040_OR_060) { - /* On the 680[46]0 we can use the _PAGE_SUPER bit. */ - pgprot_val(protection_map[0]) |= _PAGE_SUPER; - pgprot_val(protection_map[VM_SHARED]) |= _PAGE_SUPER; - } else { - /* Otherwise we must fake it. */ - pgprot_val(protection_map[0]) &= ~_PAGE_PRESENT; - pgprot_val(protection_map[0]) |= _PAGE_FAKE_SUPER; - pgprot_val(protection_map[VM_SHARED]) &= ~_PAGE_PRESENT; - pgprot_val(protection_map[VM_SHARED]) |= _PAGE_FAKE_SUPER; - } /* * Map the physical memory available into the kernel virtual diff -urN linux-2.4.21/arch/mips/Makefile linux-2.4.22/arch/mips/Makefile --- linux-2.4.21/arch/mips/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -18,14 +18,19 @@ # ifdef CONFIG_CPU_LITTLE_ENDIAN tool-prefix = mipsel-linux- +ld-emul = elf32ltsmip else tool-prefix = mips-linux- +ld-emul = elf32btsmip endif ifdef CONFIG_CROSSCOMPILE CROSS_COMPILE = $(tool-prefix) endif +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + +# # # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel # code since it only slows down the whole thing. At some point we might make @@ -38,14 +43,17 @@ # GCCFLAGS := -I $(TOPDIR)/include/asm/gcc GCCFLAGS += -G 0 -mno-abicalls -fno-pic -pipe +GCCFLAGS += $(call check_gcc, -mabi=32,) LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG +ifdef CONFIG_KGDB GCCFLAGS += -g +ifdef CONFIG_SB1XXX_CORELIS +GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer +endif endif -# # CPU-dependent compiler/assembler options for optimization. # ifdef CONFIG_CPU_R3000 @@ -86,10 +94,12 @@ GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap endif ifdef CONFIG_CPU_RM7000 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call check_gcc, -march=rm7000, -mcpu=r5000) \ + -mips2 -Wa,--trap endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += -mcpu=sb1 -mips2 -Wa,--trap +GCCFLAGS += $(call check_gcc, -mcpu=sb1, -mcpu=r5000) \ + -mips2 -Wa,--trap ifdef CONFIG_SB1_PASS_1_WORKAROUNDS MODFLAGS += -msb1-pass1-workarounds endif @@ -97,6 +107,7 @@ AFLAGS += $(GCCFLAGS) CFLAGS += $(GCCFLAGS) +LDFLAGS += -m $(ld-emul) # @@ -161,6 +172,63 @@ endif # +# Au1x00 (AMD/Alchemy) eval boards +# +ifdef CONFIG_MIPS_DB1000 +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_DB1500 +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_DB1100 +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_BOSPORUS +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_MIRAGE +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_XXS1500 +LIBS += arch/mips/au1000/xxs1500/xxs1500.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/xxs1500 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_MTX1 +LIBS += arch/mips/au1000/mtx-1/mtx-1.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/mtx-1 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_PCI +CORE_FILES += arch/mips/pci/pci-core.o +SUBDIRS += arch/mips/pci +endif + +# # Algorithmics P4032 # ifdef CONFIG_ALGOR_P4032 @@ -201,8 +269,9 @@ # Galileo EV64120 Board # ifdef CONFIG_MIPS_EV64120 -LIBS += arch/mips/galileo-boards/ev64120/ev64120.o -SUBDIRS += arch/mips/galileo-boards/ev64120 +LIBS += arch/mips/gt64120/common/gt64120.o \ + arch/mips/gt64120/ev64120/ev64120.o +SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/ev64120 LOADADDR := 0x80100000 endif @@ -210,10 +279,8 @@ # Galileo EV96100 Board # ifdef CONFIG_MIPS_EV96100 -LIBS += arch/mips/galileo-boards/ev96100/ev96100.o \ - arch/mips/galileo-boards/generic/galboards.o -SUBDIRS += arch/mips/galileo-boards/generic \ - arch/mips/galileo-boards/ev96100 +LIBS += arch/mips/galileo-boards/ev96100/ev96100.o +SUBDIRS += arch/mips/galileo-boards/ev96100 LOADADDR := 0x80100000 endif @@ -300,6 +367,17 @@ endif # +# Momentum Ocelot-C and -CS boards +# +ifdef CONFIG_MOMENCO_OCELOT_C +# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/momentum/ocelot_c/ocelot_c.o +SUBDIRS += arch/mips/momentum/ocelot_c +LOADADDR := 0x80100000 +endif + +# # NEC DDB Vrc-5074 # ifdef CONFIG_DDB5074 @@ -328,6 +406,11 @@ LOADADDR := 0x80100000 endif +ifdef CONFIG_LASAT +LIBS += arch/mips/lasat/lasatkern.o +SUBDIRS += arch/mips/lasat +LOADADDR += 0x80000000 +endif # # NEC Osprey (vr4181) board # @@ -344,7 +427,7 @@ ifdef CONFIG_NEC_EAGLE SUBDIRS += arch/mips/vr41xx/common \ arch/mips/vr41xx/nec-eagle -LIBS += arch/mips/vr41xx/common/vr41xx.o \ +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ arch/mips/vr41xx/nec-eagle/eagle.o LOADADDR := 0x80000000 endif @@ -355,12 +438,67 @@ ifdef CONFIG_ZAO_CAPCELLA SUBDIRS += arch/mips/vr41xx/common \ arch/mips/vr41xx/zao-capcella -LIBS += arch/mips/vr41xx/common/vr41xx.o \ +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ arch/mips/vr41xx/zao-capcella/capcella.o LOADADDR := 0x80000000 endif # +# Victor MP-C303/304 (VR4122) +# +ifdef CONFIG_VICTOR_MPC30X +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/victor-mpc30x +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/victor-mpc30x/mpc30x.o +LOADADDR := 0x80001000 +endif + +# +# IBM WorkPad z50 (VR4121) +# +ifdef CONFIG_IBM_WORKPAD +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/ibm-workpad +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/ibm-workpad/workpad.o +LOADADDR += 0x80004000 +endif + +# +# CASIO CASSIPEIA E-55/65 (VR4111) +# +ifdef CONFIG_CASIO_E55 +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/casio-e55 +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/casio-e55/e55.o +LOADADDR += 0x80004000 +endif + +# +# TANBAC TB0226 Mbase (VR4131) +# +ifdef CONFIG_TANBAC_TB0226 +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/tanbac-tb0226 +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/tanbac-tb0226/tb0226.o +LOADADDR := 0x80000000 +endif + +# +# TANBAC TB0229 (VR4131DIMM) +# +ifdef CONFIG_TANBAC_TB0229 +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/tanbac-tb0229 +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/tanbac-tb0229/tb0229.o +LOADADDR := 0x80000000 +endif + +# # Philips Nino # ifdef CONFIG_NINO @@ -385,23 +523,30 @@ endif # -# Sibyte SB1250 SOC +# Sibyte SB1250 SOC and Broadcom (SiByte) BCM112x SOCs # -ifdef CONFIG_SIBYTE_SB1250 +ifneq ($(CONFIG_SIBYTE_SB1250)$(CONFIG_SIBYTE_BCM112X),) # This is a LIB so that it links at the end, and initcalls are later # the sequence; but it is built as an object so that modules don't get # removed (as happens, even if they have __initcall/module_init) LIBS += arch/mips/sibyte/sb1250/sb1250.o SUBDIRS += arch/mips/sibyte/sb1250 +LOADADDR := 0x80100000 endif # -# Sibyte SWARM board +# Sibyte boards: # -ifdef CONFIG_SIBYTE_SWARM +# BCM91250A (SWARM), +# BCM91250E (Sentosa), +# BCM91120C (CRhine), +# BCM91120x (Carmel), +# BCM91125C (CRhone), +# BCM91125E (Rhone). +# +ifdef CONFIG_SIBYTE_BOARD LIBS += arch/mips/sibyte/swarm/sbswarm.a SUBDIRS += arch/mips/sibyte/swarm -LOADADDR := 0x80100000 endif # @@ -413,14 +558,6 @@ endif # -# SB1 Cache Error handler -# -ifdef CONFIG_SB1_CACHE_ERROR -LIBS += arch/mips/sibyte/sb1/sb1kern.a -SUBDIRS += arch/mips/sibyte/sb1 -endif - -# # SNI RM200 PCI # ifdef CONFIG_SNI_RM200_PCI @@ -440,6 +577,19 @@ LOADADDR := 0x80050000 endif +# +# Toshiba RBTX4927 board or +# Toshiba RBTX4937 board +# +ifdef CONFIG_TOSHIBA_RBTX4927 +MIPS = arch/mips +CEC = tx4927 +COMMON = $(MIPS)/$(CEC)/common +BOARD = $(MIPS)/$(CEC)/toshiba_rbtx4927 +LIBS += $(BOARD)/toshiba_rbtx4927.o $(COMMON)/tx4927.o +SUBDIRS += $(BOARD) $(COMMON) +LOADADDR += 0x80020000 +endif # # Choosing incompatible machines durings configuration will result in @@ -468,12 +618,15 @@ endif ifdef CONFIG_MIPS_EV64120 -GALILEOBOOT = $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120 - gboot: vmlinux $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120/compressed endif +ifdef CONFIG_LASAT +rom.bin rom.sw: vmlinux + $(MAKE) -C arch/$(ARCH)/lasat/image $@ +endif + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot vmlinux.ecoff: vmlinux @@ -484,9 +637,11 @@ rm -f arch/$(ARCH)/ld.script $(MAKE) -C arch/$(ARCH)/tools clean $(MAKE) -C arch/mips/baget clean + $(MAKE) -C arch/mips/lasat clean archmrproper: @$(MAKEBOOT) mrproper + $(RM) $(TOPDIR)/include/asm-$(ARCH)/offset.h $(MAKE) -C arch/$(ARCH)/tools mrproper archdep: diff -urN linux-2.4.21/arch/mips/algor/README linux-2.4.22/arch/mips/algor/README --- linux-2.4.21/arch/mips/algor/README 1999-06-25 17:40:12.000000000 -0700 +++ linux-2.4.22/arch/mips/algor/README 1969-12-31 16:00:00.000000000 -0800 @@ -1,5 +0,0 @@ -The code for the Algorithmics P4032 evaluation board is currently under -development. I'll release it when it's up to the same strength as -the other ports. - - Ralf diff -urN linux-2.4.21/arch/mips/arc/Makefile linux-2.4.22/arch/mips/arc/Makefile --- linux-2.4.21/arch/mips/arc/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/arc/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -4,10 +4,11 @@ L_TARGET = arclib.a -obj-y += cmdline.o console.o env.o file.o \ - identify.o init.o misc.o time.o tree.o +obj-y += cmdline.o env.o file.o identify.o init.o \ + misc.o time.o tree.o obj-$(CONFIG_ARC_MEMORY) += memory.o obj-$(CONFIG_ARC_CONSOLE) += arc_con.o +obj-$(CONFIG_ARC_PROMLIB) += promlib.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/arc/arc_con.c linux-2.4.22/arch/mips/arc/arc_con.c --- linux-2.4.21/arch/mips/arc/arc_con.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/arc/arc_con.c 2003-08-25 04:44:39.000000000 -0700 @@ -32,19 +32,16 @@ static int __init prom_console_setup(struct console *co, char *options) { - if (prom_flags & PROM_FLAG_USE_AS_CONSOLE) - return 0; - else - return 1; + return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE); } static struct console arc_cons = { - name: "ttyS", - write: prom_console_write, - device: prom_console_device, - setup: prom_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "arc", + .write = prom_console_write, + .device = prom_console_device, + .setup = prom_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; /* diff -urN linux-2.4.21/arch/mips/arc/cmdline.c linux-2.4.22/arch/mips/arc/cmdline.c --- linux-2.4.21/arch/mips/arc/cmdline.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/arc/cmdline.c 2003-08-25 04:44:39.000000000 -0700 @@ -20,7 +20,7 @@ char * __init prom_getcmdline(void) { - return &(arcs_cmdline[0]); + return arcs_cmdline; } static char *ignored[] = { @@ -32,7 +32,6 @@ "OSLoadFilename=", "OSLoadOptions=" }; -#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) static char *used_arc[][2] = { { "OSLoadPartition=", "root=" }, @@ -47,7 +46,7 @@ actr = 1; /* Always ignore argv[0] */ while (actr < prom_argc) { - for(i = 0; i < NENTS(used_arc); i++) { + for(i = 0; i < ARRAY_SIZE(used_arc); i++) { int len = strlen(used_arc[i][0]); if (!strncmp(prom_argv(actr), used_arc[i][0], len)) { @@ -71,7 +70,6 @@ return cp; } - void __init prom_init_cmdline(void) { char *cp; @@ -79,7 +77,7 @@ actr = 1; /* Always ignore argv[0] */ - cp = &(arcs_cmdline[0]); + cp = arcs_cmdline; /* * Move ARC variables to the beginning to make sure they can be * overridden by later arguments. @@ -87,7 +85,7 @@ cp = move_firmware_args(cp); while (actr < prom_argc) { - for (i = 0; i < NENTS(ignored); i++) { + for (i = 0; i < ARRAY_SIZE(ignored); i++) { int len = strlen(ignored[i]); if (!strncmp(prom_argv(actr), ignored[i], len)) @@ -101,11 +99,12 @@ pic_cont: actr++; } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + + if (cp != arcs_cmdline) /* get rid of trailing space */ --cp; *cp = '\0'; #ifdef DEBUG_CMDLINE - prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0])); + printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline); #endif } diff -urN linux-2.4.21/arch/mips/arc/console.c linux-2.4.22/arch/mips/arc/console.c --- linux-2.4.21/arch/mips/arc/console.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/arc/console.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,63 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996 David S. Miller (dm@sgi.com) - * Compability with board caches, Ulf Carlsson - */ -#include -#include -#include - -/* - * IP22 boardcache is not compatible with board caches. Thus we disable it - * during romvec action. Since r4xx0.c is always compiled and linked with your - * kernel, this shouldn't cause any harm regardless what MIPS processor you - * have. - * - * The ARC write and read functions seem to interfere with the serial lines - * in some way. You should be careful with them. - */ - -void prom_putchar(char c) -{ - ULONG cnt; - CHAR it = c; - - bc_disable(); - ArcWrite(1, &it, 1, &cnt); - bc_enable(); -} - -char prom_getchar(void) -{ - ULONG cnt; - CHAR c; - - bc_disable(); - ArcRead(0, &c, 1, &cnt); - bc_enable(); - - return c; -} - -void prom_printf(char *fmt, ...) -{ - va_list args; - char ppbuf[1024]; - char *bptr; - - va_start(args, fmt); - vsprintf(ppbuf, fmt, args); - - bptr = ppbuf; - - while (*bptr != 0) { - if (*bptr == '\n') - prom_putchar('\r'); - - prom_putchar(*bptr++); - } - va_end(args); -} diff -urN linux-2.4.21/arch/mips/arc/identify.c linux-2.4.22/arch/mips/arc/identify.c --- linux-2.4.21/arch/mips/arc/identify.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/arc/identify.c 2003-08-25 04:44:39.000000000 -0700 @@ -32,7 +32,7 @@ { "SGI-IP22", "SGI Indy", MACH_GROUP_SGI, - MACH_SGI_INDY, + MACH_SGI_IP22, PROM_FLAG_ARCS }, { "SGI-IP27", "SGI Origin", diff -urN linux-2.4.21/arch/mips/arc/promlib.c linux-2.4.22/arch/mips/arc/promlib.c --- linux-2.4.21/arch/mips/arc/promlib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/arc/promlib.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,43 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 David S. Miller (dm@sgi.com) + * Compability with board caches, Ulf Carlsson + */ +#include +#include +#include + +/* + * IP22 boardcache is not compatible with board caches. Thus we disable it + * during romvec action. Since r4xx0.c is always compiled and linked with your + * kernel, this shouldn't cause any harm regardless what MIPS processor you + * have. + * + * The ARC write and read functions seem to interfere with the serial lines + * in some way. You should be careful with them. + */ + +void prom_putchar(char c) +{ + ULONG cnt; + CHAR it = c; + + bc_disable(); + ArcWrite(1, &it, 1, &cnt); + bc_enable(); +} + +char prom_getchar(void) +{ + ULONG cnt; + CHAR c; + + bc_disable(); + ArcRead(0, &c, 1, &cnt); + bc_enable(); + + return c; +} diff -urN linux-2.4.21/arch/mips/au1000/common/Makefile linux-2.4.22/arch/mips/au1000/common/Makefile --- linux-2.4.21/arch/mips/au1000/common/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -16,14 +16,14 @@ O_TARGET := au1000.o -export-objs = prom.o serial.o clocks.o power.o usbdev.o +export-objs = prom.o clocks.o power.o usbdev.o obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o \ - clocks.o power.o usbdev.o + clocks.o power.o setup.o -obj-$(CONFIG_AU1000_UART) += serial.o -obj-$(CONFIG_AU1000_USB_DEVICE) += usbdev.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o +obj-$(CONFIG_KGDB) += dbg_io.o obj-$(CONFIG_RTC) += rtc.o +obj-$(CONFIG_PCI) += pci_ops.o pci_fixup.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/au1000/common/clocks.c linux-2.4.22/arch/mips/au1000/common/clocks.c --- linux-2.4.21/arch/mips/au1000/common/clocks.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/clocks.c 2003-08-25 04:44:39.000000000 -0700 @@ -30,21 +30,21 @@ #include #include -static unsigned int au1000_clock; // Hz +static unsigned int au1x00_clock; // Hz static unsigned int lcd_clock; // KHz static unsigned long uart_baud_base; /* * Set the au1000_clock */ -void set_au1000_speed(unsigned int new_freq) +void set_au1x00_speed(unsigned int new_freq) { - au1000_clock = new_freq; + au1x00_clock = new_freq; } -unsigned int get_au1000_speed(void) +unsigned int get_au1x00_speed(void) { - return au1000_clock; + return au1x00_clock; } @@ -54,27 +54,27 @@ * we want to be able to use the same code on different * speed CPUs. */ -unsigned long get_au1000_uart_baud_base(void) +unsigned long get_au1x00_uart_baud_base(void) { return uart_baud_base; } -void set_au1000_uart_baud_base(unsigned long new_baud_base) +void set_au1x00_uart_baud_base(unsigned long new_baud_base) { uart_baud_base = new_baud_base; } /* - * Calculate the Au1000's LCD clock based on the current + * Calculate the Au1x00's LCD clock based on the current * cpu clock and the system bus clock, and try to keep it * below 40 MHz (the Pb1000 board can lock-up if the LCD * clock is over 40 MHz). */ -void set_au1000_lcd_clock(void) +void set_au1x00_lcd_clock(void) { unsigned int static_cfg0; unsigned int sys_busclk = - (get_au1000_speed()/1000) / + (get_au1x00_speed()/1000) / ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2); static_cfg0 = au_readl(MEM_STCFG0); @@ -90,9 +90,9 @@ lcd_clock); } -unsigned int get_au1000_lcd_clock(void) +unsigned int get_au1x00_lcd_clock(void) { return lcd_clock; } -EXPORT_SYMBOL(get_au1000_lcd_clock); +EXPORT_SYMBOL(get_au1x00_lcd_clock); diff -urN linux-2.4.21/arch/mips/au1000/common/dbg_io.c linux-2.4.22/arch/mips/au1000/common/dbg_io.c --- linux-2.4.21/arch/mips/au1000/common/dbg_io.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/dbg_io.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,13 +3,13 @@ #include #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* * FIXME the user should be able to select the * uart to be used for debugging. */ -#define DEBUG_BASE UART2_ADDR +#define DEBUG_BASE UART_DEBUG_BASE /**/ /* we need uint32 uint8 */ @@ -56,7 +56,7 @@ #define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff) #define UART16550_WRITE(y,z) (au_writel(z&0xff, DEBUG_BASE + y)) -extern unsigned long get_au1000_uart_baud_base(void); +extern unsigned long get_au1x00_uart_baud_base(void); extern unsigned long cal_r4koff(void); void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) @@ -75,7 +75,7 @@ uint32 divisor; /* set divisor */ - divisor = get_au1000_uart_baud_base() / baud; + divisor = get_au1x00_uart_baud_base() / baud; UART16550_WRITE(UART_CLK, divisor & 0xffff); } diff -urN linux-2.4.21/arch/mips/au1000/common/irq.c linux-2.4.22/arch/mips/au1000/common/irq.c --- linux-2.4.21/arch/mips/au1000/common/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -28,6 +28,7 @@ */ #include #include +#include #include #include #include @@ -46,15 +47,8 @@ #include #include #include - -#if defined(CONFIG_MIPS_PB1000) +#ifdef CONFIG_MIPS_PB1000 #include -#elif defined(CONFIG_MIPS_PB1500) -#include -#elif defined(CONFIG_MIPS_PB1100) -#include -#else -#error unsupported alchemy board #endif #undef DEBUG_IRQ @@ -71,7 +65,7 @@ #define EXT_INTC1_REQ1 5 /* IP 5 */ #define MIPS_TIMER_IP 7 /* IP 7 */ -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); #endif @@ -90,13 +84,13 @@ inline void local_enable_irq(unsigned int irq_nr); inline void local_disable_irq(unsigned int irq_nr); -extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void __init init_generic_irq(void); #ifdef CONFIG_PM extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs); #endif +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; static void setup_local_irq(unsigned int irq_nr, int type, int int_req) { @@ -280,10 +274,6 @@ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { local_enable_irq(irq_nr); } - else { - printk("warning: end_irq %d did not enable (%x)\n", - irq_nr, irq_desc[irq_nr].status); - } #if defined(CONFIG_MIPS_PB1000) if (irq_nr == AU1000_GPIO_15) { au_writel(0x4000, PB1000_MDR); /* enable int */ @@ -296,8 +286,8 @@ { int i; unsigned long flags, mask; - save_and_cli(flags); + spin_lock_irqsave(&irq_lock, flags); if (controller) { mask = au_readl(IC1_MASKSET); for (i=32; i<64; i++) { @@ -310,7 +300,8 @@ local_disable_irq(i); } } - restore_flags(flags); + spin_unlock_irqrestore(&irq_lock, flags); + return mask; } @@ -318,8 +309,8 @@ { int i; unsigned long flags, new_mask; - save_and_cli(flags); + spin_lock_irqsave(&irq_lock, flags); for (i=0; i<32; i++) { if (mask & (1<im_irq, imp->im_type, imp->im_request); - case AU1000_IRDA_TX_INT: - case AU1000_IRDA_RX_INT: + switch (imp->im_type) { - case AU1000_MAC0_DMA_INT: -#ifdef CONFIG_MIPS_PB1000 - case AU1000_MAC1_DMA_INT: -#endif -#ifdef CONFIG_MIPS_PB1500 - case AU1000_MAC1_DMA_INT: -#endif - case AU1500_GPIO_204: + case INTC_INT_HIGH_LEVEL: + irq_desc[imp->im_irq].handler = &level_irq_type; + break; - setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); - irq_desc[i].handler = &level_irq_type; - break; + case INTC_INT_LOW_LEVEL: + irq_desc[imp->im_irq].handler = &level_irq_type; + break; -#ifdef CONFIG_MIPS_PB1000 - case AU1000_GPIO_15: -#endif - case AU1000_USB_HOST_INT: -#ifdef CONFIG_MIPS_PB1500 - case AU1000_PCI_INTA: - case AU1000_PCI_INTB: - case AU1000_PCI_INTC: - case AU1000_PCI_INTD: - case AU1500_GPIO_201: - case AU1500_GPIO_202: - case AU1500_GPIO_203: - case AU1500_GPIO_205: - case AU1500_GPIO_207: -#endif + case INTC_INT_RISE_EDGE: + irq_desc[imp->im_irq].handler = &rise_edge_irq_type; + break; -#ifdef CONFIG_MIPS_PB1100 - case AU1000_GPIO_9: // PCMCIA Card Fully_Interted# - case AU1000_GPIO_10: // PCMCIA_STSCHG# - case AU1000_GPIO_11: // PCMCIA_IRQ# - case AU1000_GPIO_13: // DC_IRQ# - case AU1000_GPIO_23: // 2-wire SCL -#endif - setup_local_irq(i, INTC_INT_LOW_LEVEL, 0); - irq_desc[i].handler = &level_irq_type; - break; - case AU1000_ACSYNC_INT: - case AU1000_AC97C_INT: - case AU1000_TOY_INT: - case AU1000_TOY_MATCH0_INT: - case AU1000_TOY_MATCH1_INT: - case AU1000_USB_DEV_SUS_INT: - case AU1000_USB_DEV_REQ_INT: - case AU1000_RTC_INT: - case AU1000_RTC_MATCH0_INT: - case AU1000_RTC_MATCH1_INT: - case AU1000_RTC_MATCH2_INT: - setup_local_irq(i, INTC_INT_RISE_EDGE, 0); - irq_desc[i].handler = &rise_edge_irq_type; - break; - - // Careful if you change match 2 request! - // The interrupt handler is called directly - // from the low level dispatch code. - case AU1000_TOY_MATCH2_INT: - setup_local_irq(i, INTC_INT_RISE_EDGE, 1); - irq_desc[i].handler = &rise_edge_irq_type; - break; - default: /* active high, level interrupt */ - setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); - irq_desc[i].handler = &level_irq_type; - break; + default: + panic("Unknown au1xxx irq map"); + break; } + imp++; } - set_cp0_status(ALLINTS); -#ifdef CONFIG_REMOTE_DEBUG + set_c0_status(ALLINTS); +#ifdef CONFIG_KGDB /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); set_debug_traps(); @@ -508,7 +437,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs) { - int irq = 0, i; + int irq = 0; static unsigned long intc0_req0 = 0; intc0_req0 |= au_readl(IC0_REQ0INT); @@ -526,43 +455,33 @@ return; } - for (i=0; i<32; i++) { - if ((intc0_req0 & (1< + +#ifdef CONFIG_PCI + +#include +#include +#include +#include + +#include +//#include +#ifdef CONFIG_MIPS_PB1000 +#include +#endif + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static void fixup_resource(int r_num, struct pci_dev *dev) ; +#ifdef CONFIG_SOC_AU1500 +static unsigned long virt_io_addr; +#endif + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* will need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ +#ifdef CONFIG_SOC_AU1500 + int i; + struct pci_dev *dev; + + virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, + Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1); + + if (!virt_io_addr) { + printk(KERN_ERR "Unable to ioremap pci space\n"); + return; + } + +#ifdef CONFIG_NONCOHERENT_IO + /* + * Set the NC bit in controller for pre-AC silicon + */ + au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG); + printk("Non-coherent PCI accesses enabled\n"); +#endif + + set_io_port_base(virt_io_addr); +#endif + +#ifdef CONFIG_MIPS_PB1000 /* This is truly board specific */ + unsigned long pci_mem_start = (unsigned long) PCI_MEM_START; + + au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 + au_writel(0, SDRAM_MBAR); // set mbar to 0 + au_writel(0x2, SDRAM_CMD); // enable memory accesses + au_sync_delay(1); + + // set extend byte to mbar of ext slot + au_writel(((pci_mem_start >> 24) & 0xff) | + (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), PCI_BRIDGE_CONFIG); + DBG("Set bridge config to %x\n", au_readl(PCI_BRIDGE_CONFIG)); +#endif +} + +void __init pcibios_fixup_irqs(void) +{ +#ifdef CONFIG_SOC_AU1500 + unsigned int slot, func; + unsigned char pin; + struct pci_dev *dev; + + pci_for_each_dev(dev) { + if (dev->bus->number != 0) + return; + + dev->irq = 0xff; + slot = PCI_SLOT(dev->devfn); + switch (slot) { + case 12: + case 13: + default: + dev->irq = AU1000_PCI_INTA; + break; + + } + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + DBG("slot %d irq %d\n", slot, dev->irq); + } +#endif +} +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} + +static void fixup_resource(int r_num, struct pci_dev *dev) +{ +} +#endif diff -urN linux-2.4.21/arch/mips/au1000/common/pci_ops.c linux-2.4.22/arch/mips/au1000/common/pci_ops.c --- linux-2.4.21/arch/mips/au1000/common/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/pci_ops.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,285 @@ +/* + * BRIEF MODULE DESCRIPTION + * Alchemy/AMD Au1x00 pci support. + * + * Copyright 2001,2002,2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Support for all devices (greater than 16) added by David Gathright. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include + +#ifdef CONFIG_PCI + +#include +#include +#include +#include + +#include +#ifdef CONFIG_MIPS_PB1000 +#include +#endif +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* TBD */ +static struct resource pci_io_resource = { + "pci IO space", + (u32)PCI_IO_START, + (u32)PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + "pci memory space", + (u32)PCI_MEM_START, + (u32)PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops au1x_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&au1x_pci_ops, &pci_io_resource, &pci_mem_resource, + PCI_FIRST_DEVFN,PCI_LAST_DEVFN}, + {(struct pci_ops *) NULL, (struct resource *) NULL, + (struct resource *) NULL, (int) NULL, (int) NULL} +}; + + +#ifdef CONFIG_MIPS_PB1000 +/* + * "Bus 2" is really the first and only external slot on the pb1000. + * We'll call that bus 0, and limit the accesses to that single + * external slot only. The SDRAM is already initialized in setup.c. + */ +static int config_access(unsigned char access_type, struct pci_dev *dev, + unsigned char where, u32 * data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + unsigned long config; + + if (((dev_fn >> 3) != 0) || (bus != 0)) { + *data = 0xffffffff; + return -1; + } + + config = PCI_CONFIG_BASE | (where & ~0x3); + + if (access_type == PCI_ACCESS_WRITE) { + au_writel(*data, config); + } else { + *data = au_readl(config); + } + au_sync_udelay(1); + + DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", + access_type, bus, dev_fn, where, *data, config); + + DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), *data); + + if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) { + *data = 0xffffffff; + return -1; + } else { + return PCIBIOS_SUCCESSFUL; + } +} + +#else + +static int config_access(unsigned char access_type, struct pci_dev *dev, + unsigned char where, u32 * data) +{ +#ifdef CONFIG_SOC_AU1500 + unsigned char bus = dev->bus->number; + unsigned int dev_fn = dev->devfn; + unsigned int device = PCI_SLOT(dev_fn); + unsigned int function = PCI_FUNC(dev_fn); + unsigned long config, status; + unsigned long cfg_addr; + + if (device > 19) { + *data = 0xffffffff; + return -1; + } + + au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)), + Au1500_PCI_STATCMD); + //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG); + au_sync_udelay(1); + + /* setup the config window */ + if (bus == 0) { + cfg_addr = ioremap( Au1500_EXT_CFG | ((1<> 28) & 0xf) { + DBG("PCI ERR detected: status %x\n", status); + *data = 0xffffffff; + return -1; + } else { + return PCIBIOS_SUCCESSFUL; + } +#endif +} +#endif + +static int read_config_byte(struct pci_dev *dev, int where, u8 * val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, dev, where, &data); + if (where & 1) data >>= 8; + if (where & 2) data >>= 16; + *val = data & 0xff; + return ret; +} + + +static int read_config_word(struct pci_dev *dev, int where, u16 * val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, dev, where, &data); + if (where & 2) data >>= 16; + *val = data & 0xffff; + return ret; +} + +static int read_config_dword(struct pci_dev *dev, int where, u32 * val) +{ + int ret; + + ret = config_access(PCI_ACCESS_READ, dev, where, val); + return ret; +} + + +static int write_config_byte(struct pci_dev *dev, int where, u8 val) +{ + u32 data = 0; + + if (config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_word(struct pci_dev *dev, int where, u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops au1x_pci_ops = { + read_config_byte, + read_config_word, + read_config_dword, + write_config_byte, + write_config_word, + write_config_dword +}; +#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/au1000/common/power.c linux-2.4.22/arch/mips/au1000/common/power.c --- linux-2.4.21/arch/mips/au1000/common/power.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/power.c 2003-08-25 04:44:39.000000000 -0700 @@ -67,6 +67,8 @@ #ifdef CONFIG_PM +static spinlock_t pm_lock = SPIN_LOCK_UNLOCKED; + unsigned long suspend_mode; void wakeup_from_suspend(void) @@ -77,7 +79,7 @@ int au_sleep(void) { unsigned long wakeup, flags; - save_and_cli(flags); + spin_lock_irqsave(&pm_lock,flags); flush_cache_all(); /* pin 6 is gpio */ @@ -104,7 +106,7 @@ /* after a wakeup, the cpu vectors back to 0x1fc00000 so * it's up to the boot code to get us back here. */ - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return 0; } @@ -158,31 +160,31 @@ old_refresh; unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh; - save_and_cli(flags); + spin_lock_irqsave(&pm_lock, flags); if (!write) { *len = 0; } else { /* Parse the new frequency */ if (*len > TMPBUFLEN - 1) { - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } if (copy_from_user(buf, buffer, *len)) { - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } buf[*len] = 0; p = buf; val = simple_strtoul(p, &p, 0); if (val > MAX_CPU_FREQ) { - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } pll = val / 12; if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */ /* revisit this for higher speed cpus */ - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } @@ -247,7 +249,7 @@ intc0_mask = save_local_and_disable(0); intc1_mask = save_local_and_disable(1); local_enable_irq(AU1000_TOY_MATCH2_INT); - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); calibrate_delay(); restore_local_and_enable(0, intc0_mask); restore_local_and_enable(1, intc1_mask); @@ -323,4 +325,9 @@ } } +void au1k_wait(void) +{ + __asm__("nop\n\t" "nop\n\t"); +} + #endif /* CONFIG_PM */ diff -urN linux-2.4.21/arch/mips/au1000/common/prom.c linux-2.4.22/arch/mips/au1000/common/prom.c --- linux-2.4.21/arch/mips/au1000/common/prom.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/prom.c 2003-08-25 04:44:39.000000000 -0700 @@ -105,9 +105,11 @@ inline unsigned char str2hexnum(unsigned char c) { if(c >= '0' && c <= '9') - return c - '0'; + return c - '0'; if(c >= 'a' && c <= 'f') - return c - 'a' + 10; + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; return 0; /* foo */ } @@ -128,7 +130,6 @@ int get_ethernet_addr(char *ethernet_addr) { - int i; char *ethaddr_str; ethaddr_str = prom_getenv("ethaddr"); @@ -139,10 +140,14 @@ str2eaddr(ethernet_addr, ethaddr_str); #if 0 + { + int i; + printk("get_ethernet_addr: "); for (i=0; i<5; i++) printk("%02x:", (unsigned char)*(ethernet_addr+i)); printk("%02x\n", *(ethernet_addr+i)); + } #endif return 0; @@ -151,3 +156,4 @@ void prom_free_prom_memory (void) {} EXPORT_SYMBOL(prom_getcmdline); EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff -urN linux-2.4.21/arch/mips/au1000/common/puts.c linux-2.4.22/arch/mips/au1000/common/puts.c --- linux-2.4.21/arch/mips/au1000/common/puts.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/au1000/common/puts.c 2003-08-25 04:44:39.000000000 -0700 @@ -29,8 +29,9 @@ */ #include +#include -#define SERIAL_BASE 0xB1100000 /* au1000, uart 0 */ +#define SERIAL_BASE UART_BASE #define SER_CMD 0x7 #define SER_DATA 0x1 #define TX_BUSY 0x20 diff -urN linux-2.4.21/arch/mips/au1000/common/reset.c linux-2.4.22/arch/mips/au1000/common/reset.c --- linux-2.4.21/arch/mips/au1000/common/reset.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/reset.c 2003-08-25 04:44:39.000000000 -0700 @@ -42,7 +42,7 @@ void au1000_restart(char *command) { /* Set all integrated peripherals to disabled states */ - u32 prid = read_32bit_cp0_register(CP0_PRID); + u32 prid = read_c0_prid(); printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n"); switch (prid & 0xFF000000) @@ -107,10 +107,17 @@ break; } - set_cp0_status(ST0_BEV | ST0_ERL); - set_cp0_config(CONF_CM_UNCACHED); + set_c0_status(ST0_BEV | ST0_ERL); + set_c0_config(CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); + +#if defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) + /* Do a HW reset if the board can do it */ + + au_writel(0x00000000, 0xAE00001C); +#endif + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21/arch/mips/au1000/common/serial.c linux-2.4.22/arch/mips/au1000/common/serial.c --- linux-2.4.21/arch/mips/au1000/common/serial.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/serial.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,3072 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Au1000 serial port driver. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * Derived almost entirely from drivers/char/serial.c: - * - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, - * 1998, 1999 Theodore Ts'o - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You 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. - */ - -static char *serial_version = "1.01"; -static char *serial_revdate = "2001-02-08"; - - -#include -#include - -#undef SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT -#undef SERIAL_DEBUG_PCI -#undef SERIAL_DEBUG_AUTOCONF - -#ifdef MODULE -#undef CONFIG_AU1000_SERIAL_CONSOLE -#endif - -#define CONFIG_SERIAL_RSA - -#define RS_STROBE_TIME (10*HZ) -#define RS_ISR_PASS_LIMIT 256 - -/* - * End of serial driver configuration section. - */ - -#include - -#include -#ifdef LOCAL_HEADERS -#include "serial_local.h" -#else -#include -#include -#include -#include -#define LOCAL_VERSTRING "" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_AU1000_SERIAL_CONSOLE -#include -#endif -#ifdef CONFIG_MAGIC_SYSRQ -#include -#endif - -#include -#include -#include -#include - -#ifdef CONFIG_MAC_SERIAL -#define SERIAL_DEV_OFFSET 2 -#else -#define SERIAL_DEV_OFFSET 0 -#endif - -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#else -#define _INLINE_ -#endif - -static char *serial_name = "Serial driver"; - -static DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver serial_driver, callout_driver; -static int serial_refcount; - -static struct timer_list serial_timer; - -extern unsigned long get_au1000_uart_baud_base(void); - -/* serial subtype definitions */ -#ifndef SERIAL_TYPE_NORMAL -#define SERIAL_TYPE_NORMAL 1 -#define SERIAL_TYPE_CALLOUT 2 -#endif - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* - * IRQ_timeout - How long the timeout should be for each IRQ - * should be after the IRQ has been active. - */ - -static struct async_struct *IRQ_ports[NR_IRQS]; -static int IRQ_timeout[NR_IRQS]; -#ifdef CONFIG_AU1000_SERIAL_CONSOLE -static struct console sercons; -static int lsr_break_flag; -#endif -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -static unsigned long break_pressed; /* break, really ... */ -#endif - -static void autoconfig(struct serial_state * state); -static void change_speed(struct async_struct *info, struct termios *old); -static void rs_wait_until_sent(struct tty_struct *tty, int timeout); - -/* - * Here we define the default xmit fifo size used for each type of - * UART - */ -static struct serial_uart_config uart_config[] = { - { "unknown", 1, 0 }, - { "8250", 1, 0 }, - { "16450", 1, 0 }, - { "16550", 1, 0 }, - { 0, 0} -}; - - -static struct serial_state rs_table[RS_TABLE_SIZE] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -#ifndef PREPARE_FUNC -#define PREPARE_FUNC(dev) (dev->prepare) -#define ACTIVATE_FUNC(dev) (dev->activate) -#define DEACTIVATE_FUNC(dev) (dev->deactivate) -#endif - -#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) - -static struct tty_struct *serial_table[NR_PORTS]; -static struct termios *serial_termios[NR_PORTS]; -static struct termios *serial_termios_locked[NR_PORTS]; - - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ - kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the copy_from_user blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; -#ifdef DECLARE_MUTEX -static DECLARE_MUTEX(tmp_buf_sem); -#else -static struct semaphore tmp_buf_sem = MUTEX; -#endif - - -static inline int serial_paranoia_check(struct async_struct *info, - kdev_t device, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, kdevname(device), routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, kdevname(device), routine); - return 1; - } -#endif - return 0; -} - -static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) -{ - return (au_readl(info->port+offset) & 0xffff); -} - -static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) -{ - au_writel(value & 0xffff, info->port+offset); -} - - -/* - * We used to support using pause I/O for certain machines. We - * haven't supported this for a while, but just in case it's badly - * needed for certain old 386 machines, I've left these #define's - * in.... - */ -#define serial_inp(info, offset) serial_in(info, offset) -#define serial_outp(info, offset, value) serial_out(info, offset, value) - - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_stop")) - return; - - save_flags(flags); cli(); - if (info->IER & UART_IER_THRI) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - restore_flags(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_start")) - return; - - save_flags(flags); cli(); - if (info->xmit.head != info->xmit.tail - && info->xmit.buf - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - restore_flags(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(struct async_struct *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -static _INLINE_ void receive_chars(struct async_struct *info, - int *status, struct pt_regs * regs) -{ - struct tty_struct *tty = info->tty; - unsigned char ch; - int ignored = 0; - struct async_icount *icount; - - icount = &info->state->icount; - do { - ch = serial_inp(info, UART_RX); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - *tty->flip.char_buf_ptr = ch; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, *status); -#endif - *tty->flip.flag_buf_ptr = 0; - if (*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE)) { - /* - * For statistics only - */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - icount->brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (info->line == sercons.index) { - if (!break_pressed) { - break_pressed = jiffies; - goto ignore_char; - } - break_pressed = 0; - } -#endif - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (*status & UART_LSR_PE) - icount->parity++; - else if (*status & UART_LSR_FE) - icount->frame++; - if (*status & UART_LSR_OE) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - */ - if (*status & info->ignore_status_mask) { - if (++ignored > 100) - break; - goto ignore_char; - } - *status &= info->read_status_mask; - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if (info->line == sercons.index) { - /* Recover the break flag from console xmit */ - *status |= lsr_break_flag; - lsr_break_flag = 0; - } -#endif - if (*status & (UART_LSR_BI)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - } else if (*status & UART_LSR_PE) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (*status & UART_LSR_FE) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (*status & UART_LSR_OE) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - } - } -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (break_pressed && info->line == sercons.index) { - if (ch != 0 && - time_before(jiffies, break_pressed + HZ*5)) { - handle_sysrq(ch, regs, NULL, NULL); - break_pressed = 0; - goto ignore_char; - } - break_pressed = 0; - } -#endif - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - ignore_char: - *status = serial_inp(info, UART_LSR); - } while (*status & UART_LSR_DR); - tty_flip_buffer_push(tty); -} - -static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) -{ - int count; - - if (info->x_char) { - serial_outp(info, UART_TX, info->x_char); - info->state->icount.tx++; - info->x_char = 0; - if (intr_done) - *intr_done = 0; - return; - } - if (info->xmit.head == info->xmit.tail - || info->tty->stopped - || info->tty->hw_stopped) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - return; - } - - count = info->xmit_fifo_size; - do { - serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]); - info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); - info->state->icount.tx++; - if (info->xmit.head == info->xmit.tail) - break; - } while (--count > 0); - - if (CIRC_CNT(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif - if (intr_done) - *intr_done = 0; - - if (info->xmit.head == info->xmit.tail) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } -} - -static _INLINE_ void check_modem_status(struct async_struct *info) -{ - int status; - struct async_icount *icount; - - status = serial_in(info, UART_MSR); - - if (status & UART_MSR_ANY_DELTA) { - icount = &info->state->icount; - /* update input line counters */ - if (status & UART_MSR_TERI) - icount->rng++; - if (status & UART_MSR_DDSR) - icount->dsr++; - if (status & UART_MSR_DDCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - (status & UART_MSR_DCD)) - hardpps(); -#endif - } - if (status & UART_MSR_DCTS) - icount->cts++; - wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) - wake_up_interruptible(&info->open_wait); - else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_CALLOUT_NOHUP))) { -#ifdef SERIAL_DEBUG_OPEN - printk("doing serial hangup..."); -#endif - if (info->tty) - tty_hangup(info->tty); - } - } - if (info->flags & ASYNC_CTS_FLOW) { - if (info->tty->hw_stopped) { - if (status & UART_MSR_CTS) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if (!(status & UART_MSR_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - } - } -} - - - -/* - * This is the serial driver's interrupt routine for a single port - */ -static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) -{ - int status; - int pass_counter = 0; - struct async_struct * info; - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d)...", irq); -#endif - - info = IRQ_ports[irq]; - if (!info || !info->tty) - return; - - do { - status = serial_inp(info, UART_LSR); -#ifdef SERIAL_DEBUG_INTR - printk("status = %x...", status); -#endif - if (status & UART_LSR_DR) - receive_chars(info, &status, regs); - check_modem_status(info); - if (status & UART_LSR_THRE) - transmit_chars(info, 0); - if (pass_counter++ > RS_ISR_PASS_LIMIT) { -#if 0 - printk("rs_single loop break.\n"); -#endif - break; - } - } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT)); - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif -} - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); -} - -static void do_softint(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); -#ifdef SERIAL_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - } -} - -/* - * This subroutine is called when the RS_TIMER goes off. It is used - * by the serial driver to handle ports that do not have an interrupt - * (irq=0). This doesn't work very well for 16450's, but gives barely - * passable results for a 16550A. (Although at the expense of much - * CPU overhead). - */ -static void rs_timer(unsigned long dummy) -{ - static unsigned long last_strobe; - struct async_struct *info; - unsigned int i; - unsigned long flags; - - if ((jiffies - last_strobe) >= RS_STROBE_TIME) { - for (i=0; i < NR_IRQS; i++) { - info = IRQ_ports[i]; - if (!info) - continue; - save_flags(flags); cli(); - rs_interrupt_single(i, NULL, NULL); - restore_flags(flags); - } - } - last_strobe = jiffies; - mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); - -#if 0 - if (IRQ_ports[0]) { - save_flags(flags); cli(); - rs_interrupt_single(0, NULL, NULL); - restore_flags(flags); - - mod_timer(&serial_timer, jiffies + IRQ_timeout[0]); - } -#endif -} - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * --------------------------------------------------------------- - */ - -/* - * This routine figures out the correct timeout for a particular IRQ. - * It uses the smallest timeout of all of the serial ports in a - * particular interrupt chain. Now only used for IRQ 0.... - */ -static void figure_IRQ_timeout(int irq) -{ - struct async_struct *info; - int timeout = 60*HZ; /* 60 seconds === a long time :-) */ - - info = IRQ_ports[irq]; - if (!info) { - IRQ_timeout[irq] = 60*HZ; - return; - } - while (info) { - if (info->timeout < timeout) - timeout = info->timeout; - info = info->next_port; - } - if (!irq) - timeout = timeout / 2; - IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1; -} - - -static int startup(struct async_struct * info) -{ - unsigned long flags; - int retval=0; - void (*handler)(int, void *, struct pt_regs *); - struct serial_state *state= info->state; - unsigned long page; - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit.buf) - free_page(page); - else - info->xmit.buf = (unsigned char *) page; - - - if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { - au_writel(3, UART_MOD_CNTRL + state->port); - au_sync_delay(10); - } -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - - /* - * Clear the FIFO buffers and disable them - * (they will be reenabled in change_speed()) - */ - if (uart_config[state->type].flags & UART_CLEAR_FIFO) { - serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - } - - /* - * Clear the interrupt registers. - */ - (void) serial_inp(info, UART_LSR); - (void) serial_inp(info, UART_RX); - (void) serial_inp(info, UART_IIR); - (void) serial_inp(info, UART_MSR); - - /* - * At this point there's no way the LSR could still be 0xFF; - * if it is, then bail out, because there's likely no UART - * here. - */ - if (!(info->flags & ASYNC_BUGGY_UART) && - (serial_inp(info, UART_LSR) == 0xff)) { - printk("LSR safety check engaged!\n"); - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - } else - retval = -ENODEV; - goto errout; - } - - /* - * Allocate the IRQ if necessary - */ -#if 0 - /* au1000, uart0 irq is 0 */ - if (state->irq && (!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { -#endif - if ((!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - retval = -EBUSY; - goto errout; - } else - handler = rs_interrupt_single; - - retval = request_irq(state->irq, handler, SA_SHIRQ, - "serial", &IRQ_ports[state->irq]); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } - - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); - - /* - * Now, initialize the UART - */ - serial_outp(info, UART_LCR, UART_LCR_WLEN8); - - info->MCR = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; - { - if (state->irq != 0) - info->MCR |= UART_MCR_OUT2; - } - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - serial_outp(info, UART_MCR, info->MCR); - - /* - * Finally, enable interrupts - */ - info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; - serial_outp(info, UART_IER, info->IER); /* enable interrupts */ - - - /* - * And clear the interrupt registers again for luck. - */ - (void)serial_inp(info, UART_LSR); - (void)serial_inp(info, UART_RX); - (void)serial_inp(info, UART_IIR); - (void)serial_inp(info, UART_MSR); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit.head = info->xmit.tail = 0; - - /* - * Set up serial timers... - */ - mod_timer(&serial_timer, jiffies + 2*HZ/100); - - /* - * Set up the tty->alt_speed kludge - */ - if (info->tty) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - } - - /* - * and set the speed of the serial port - */ - change_speed(info, 0); - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct async_struct * info) -{ - unsigned long flags; - struct serial_state *state; - int retval; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - 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] || - if ((!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 */ - info->MCR &= ~UART_MCR_OUT2; - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - - /* disable break condition */ - serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); - - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - serial_outp(info, UART_MCR, info->MCR); - - /* disable FIFO's */ - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - - (void)serial_in(info, UART_RX); /* read data port to reset things */ - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; -#ifndef CONFIG_REMOTE_DEBUG - au_writel(0, UART_MOD_CNTRL + state->port); - au_sync_delay(10); -#endif - restore_flags(flags); -} - - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct async_struct *info, - struct termios *old_termios) -{ - int quot = 0, baud_base, baud; - unsigned cflag, cval, fcr = 0; - int bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - if (!CONFIGURED_SERIAL_PORT(info)) - return; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: cval = 0x00; bits = 7; break; - case CS6: cval = 0x01; bits = 8; break; - case CS7: cval = 0x02; bits = 9; break; - case CS8: cval = 0x03; bits = 10; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: cval = 0x00; bits = 7; break; - } - if (cflag & CSTOPB) { - cval |= 0x04; - bits++; - } - if (cflag & PARENB) { - cval |= UART_LCR_PARITY; - bits++; - } - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; -#ifdef CMSPAR - if (cflag & CMSPAR) - cval |= UART_LCR_SPAR; -#endif - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) { - baud = 9600; /* B0 transition handled in rs_set_termios */ - } - baud_base = get_au1000_uart_baud_base(); - - //if (baud == 38400 && - if (((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { - quot = info->state->custom_divisor; - } - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - /* If the quotient is zero refuse the change */ - if (!quot && old_termios) { - info->tty->termios->c_cflag &= ~CBAUD; - info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - } - /* As a last resort, if the quotient is zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - - info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - /* Set up FIFO's */ - if (uart_config[info->state->type].flags & UART_USE_FIFO) { - if ((info->state->baud_base / quot) < 2400) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_1; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8; - } - - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - if (info->flags & ASYNC_HARDPPS_CD) - info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - } else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else { - info->flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - serial_out(info, UART_IER, info->IER); - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (I_INPCK(info->tty)) - info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= UART_LSR_BI; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_OE; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->ignore_status_mask |= UART_LSR_DR; - save_flags(flags); cli(); - - serial_outp(info, UART_CLK, quot & 0xffff); - serial_outp(info, UART_LCR, cval); - info->LCR = cval; /* Save LCR */ - restore_flags(flags); -} - -static void rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_put_char")) - return; - - if (!tty || !info->xmit.buf) - return; - - save_flags(flags); cli(); - if (CIRC_SPACE(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) == 0) { - restore_flags(flags); - return; - } - - info->xmit.buf[info->xmit.head] = ch; - info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); - restore_flags(flags); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) - return; - - if (info->xmit.head == info->xmit.tail - || tty->stopped - || tty->hw_stopped - || !info->xmit.buf) - return; - - save_flags(flags); cli(); - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - restore_flags(flags); -} - -static int rs_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_write")) - return 0; - - if (!tty || !info->xmit.buf || !tmp_buf) - return 0; - - save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - int c1; - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - cli(); - c1 = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (c1 < c) - c = c1; - memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - cli(); - while (1) { - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) { - break; - } - memcpy(info->xmit.buf + info->xmit.head, buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - buf += c; - count -= c; - ret += c; - } - restore_flags(flags); - } - if (info->xmit.head != info->xmit.tail - && !tty->stopped - && !tty->hw_stopped - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_write_room")) - return 0; - return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) - return 0; - return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) - return; - save_flags(flags); cli(); - info->xmit.head = info->xmit.tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); -#ifdef SERIAL_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_send_xchar(struct tty_struct *tty, char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_send_char")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_send_xchar(tty, STOP_CHAR(tty)); - - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; - - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_send_xchar(tty, START_CHAR(tty)); - } - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct async_struct * info, - struct serial_struct * retinfo) -{ - struct serial_struct tmp; - struct serial_state *state = info->state; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = state->type; - tmp.line = state->line; - tmp.port = state->port; - if (HIGH_BITS_OFFSET) - tmp.port_high = state->port >> HIGH_BITS_OFFSET; - else - tmp.port_high = 0; - tmp.irq = state->irq; - tmp.flags = state->flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - tmp.hub6 = state->hub6; - tmp.io_type = state->io_type; - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct async_struct * info, - struct serial_struct * new_info) -{ - struct serial_struct new_serial; - struct serial_state old_state, *state; - unsigned int i,change_irq,change_port; - int retval = 0; - unsigned long new_port; - - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - state = info->state; - old_state = *state; - - new_port = new_serial.port; - if (HIGH_BITS_OFFSET) - new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; - - change_irq = new_serial.irq != state->irq; - change_port = (new_port != ((int) state->port)) || - (new_serial.hub6 != state->hub6); - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || change_port || - (new_serial.baud_base != state->baud_base) || - (new_serial.type != state->type) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - new_serial.irq = irq_cannonicalize(new_serial.irq); - - if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || - (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) || - (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || - (new_serial.type == PORT_STARTECH)) { - return -EINVAL; - } - - if ((new_serial.type != state->type) || - (new_serial.xmit_fifo_size <= 0)) - new_serial.xmit_fifo_size = - uart_config[new_serial.type].dfl_xmit_fifo_size; - - /* Make sure address is not already in use */ - if (new_serial.type) { - for (i = 0 ; i < NR_PORTS; i++) - if ((state != &rs_table[i]) && - (rs_table[i].port == new_port) && - rs_table[i].type) - return -EADDRINUSE; - } - - if ((change_port || change_irq) && (state->count > 1)) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - state->baud_base = new_serial.baud_base; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->close_delay = new_serial.close_delay * HZ/100; - state->closing_wait = new_serial.closing_wait * HZ/100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - info->xmit_fifo_size = state->xmit_fifo_size = - new_serial.xmit_fifo_size; - - if ((state->type != PORT_UNKNOWN) && state->port) { - release_region(state->port,8); - } - state->type = new_serial.type; - if (change_port || change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - shutdown(info); - state->irq = new_serial.irq; - info->port = state->port = new_port; - info->hub6 = state->hub6 = new_serial.hub6; - if (info->hub6) - info->io_type = state->io_type = SERIAL_IO_HUB6; - else if (info->io_type == SERIAL_IO_HUB6) - info->io_type = state->io_type = SERIAL_IO_PORT; - } - if ((state->type != PORT_UNKNOWN) && state->port) { - request_region(state->port,8,"serial(set)"); - } - - -check_and_exit: - if (!state->port || !state->type) - return 0; - if (info->flags & ASYNC_INITIALIZED) { - if (((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK)) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - change_speed(info, 0); - } - } else { - retval = startup(info); - } - return retval; -} - - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned char status; - unsigned int result; - unsigned long flags; - - save_flags(flags); cli(); - status = serial_in(info, UART_LSR); - restore_flags(flags); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - - /* - * If we're about to load something into the transmit - * register, we'll pretend the transmitter isn't empty to - * avoid a race condition (depending on when the transmit - * interrupt happens). - */ - if (info->x_char || - ((CIRC_CNT(info->xmit.head, info->xmit.tail, - SERIAL_XMIT_SIZE) > 0) && - !info->tty->stopped && !info->tty->hw_stopped)) - result &= TIOCSER_TEMT; - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - - -static int get_modem_info(struct async_struct * info, unsigned int *value) -{ - unsigned char control, status; - unsigned int result; - unsigned long flags; - - control = info->MCR; - save_flags(flags); cli(); - status = serial_in(info, UART_MSR); - restore_flags(flags); - result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) - | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) -#ifdef TIOCM_OUT1 - | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) - | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) -#endif - | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) - | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) - | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) - | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -static int set_modem_info(struct async_struct * info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg; - unsigned long flags; - - if (copy_from_user(&arg, value, sizeof(int))) - return -EFAULT; - - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - info->MCR |= UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR |= UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR |= UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR |= UART_MCR_OUT2; -#endif - if (arg & TIOCM_LOOP) - info->MCR |= UART_MCR_LOOP; - break; - case TIOCMBIC: - if (arg & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR &= ~UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR &= ~UART_MCR_OUT2; -#endif - if (arg & TIOCM_LOOP) - info->MCR &= ~UART_MCR_LOOP; - break; - case TIOCMSET: - info->MCR = ((info->MCR & ~(UART_MCR_RTS | -#ifdef TIOCM_OUT1 - UART_MCR_OUT1 | - UART_MCR_OUT2 | -#endif - UART_MCR_LOOP | - UART_MCR_DTR)) - | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) -#ifdef TIOCM_OUT1 - | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) - | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) -#endif - | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) - | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); - break; - default: - return -EINVAL; - } - save_flags(flags); cli(); - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - return 0; -} - -static int do_autoconfig(struct async_struct * info) -{ - int retval; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (info->state->count > 1) - return -EBUSY; - - shutdown(info); - - autoconfig(info->state); - retval = startup(info); - if (retval) - return retval; - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static void rs_break(struct tty_struct *tty, int break_state) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_break")) - return; - - if (!CONFIGURED_SERIAL_PORT(info)) - return; - save_flags(flags); cli(); - if (break_state == -1) - info->LCR |= UART_LCR_SBC; - else - info->LCR &= ~UART_LCR_SBC; - serial_out(info, UART_LCR, info->LCR); - restore_flags(flags); -} - - -static int rs_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct icount; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERCONFIG: - return do_autoconfig(info); - - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct async_struct *) arg, - info, sizeof(struct async_struct))) - return -EFAULT; - return 0; - - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - save_flags(flags); cli(); - /* note the counters on entry */ - cprev = info->state->icount; - restore_flags(flags); - /* Force modem status interrupts on */ - info->IER |= UART_IER_MSI; - serial_out(info, UART_IER, info->IER); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - save_flags(flags); cli(); - cnow = info->state->icount; /* atomic copy */ - restore_flags(flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - save_flags(flags); cli(); - cnow = info->state->icount; - restore_flags(flags); - icount.cts = cnow.cts; - icount.dsr = cnow.dsr; - icount.rng = cnow.rng; - icount.dcd = cnow.dcd; - icount.rx = cnow.rx; - icount.tx = cnow.tx; - icount.frame = cnow.frame; - icount.overrun = cnow.overrun; - icount.parity = cnow.parity; - icount.brk = cnow.brk; - icount.buf_overrun = cnow.buf_overrun; - - if (copy_to_user((void *)arg, &icount, sizeof(icount))) - return -EFAULT; - return 0; - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - unsigned int cflag = tty->termios->c_cflag; - - if ( (cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_speed(info, old_termios); - - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (cflag & CBAUD)) { - info->MCR |= UART_MCR_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->MCR |= UART_MCR_RTS; - } - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->device, "rs_close")) - return; - - state = info->state; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - restore_flags(flags); - /* - * Save the termios structure, since this port may have - * separate termios for callout and dialin. - */ - if (info->flags & ASYNC_NORMAL_ACTIVE) - info->state->normal_termios = *tty->termios; - if (info->flags & ASYNC_CALLOUT_ACTIVE) - info->state->callout_termios = *tty->termios; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->IER &= ~UART_IER_RLSI; - info->read_status_mask &= ~UART_LSR_DR; - if (info->flags & ASYNC_INITIALIZED) { - serial_out(info, UART_IER, info->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (info->blocked_open) { - if (info->close_delay) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| - ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long orig_jiffies, char_time; - int lsr; - - if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) - return; - - if (info->state->type == PORT_UNKNOWN) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout && timeout < char_time) - char_time = timeout; - /* - * If the transmitter hasn't cleared in twice the approximate - * amount of time to send the entire FIFO, it probably won't - * ever clear. This assumes the UART isn't doing flow - * control, which is currently the case. Hence, if it ever - * takes longer than info->timeout, this is probably due to a - * UART bug of some kind. So, we clamp the timeout parameter at - * 2*info->timeout. - */ - if (!timeout || timeout > 2*info->timeout) - timeout = 2*info->timeout; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - set_current_state(TASK_RUNNING); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_hangup(struct tty_struct *tty) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->device, "rs_hangup")) - return; - - state = info->state; - - rs_flush_buffer(tty); - if (info->flags & ASYNC_CLOSING) - return; - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct async_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - struct serial_state *state = info->state; - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * If this is a callout device, then just make sure the normal - * device isn't being used. - */ - if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { - if (info->flags & ASYNC_NORMAL_ACTIVE) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_SESSION_LOCKOUT) && - (info->session != current->session)) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_PGRP_LOCKOUT) && - (info->pgrp != current->pgrp)) - return -EBUSY; - info->flags |= ASYNC_CALLOUT_ACTIVE; - return 0; - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - if (info->flags & ASYNC_CALLOUT_ACTIVE) - return -EBUSY; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (info->flags & ASYNC_CALLOUT_ACTIVE) { - if (state->normal_termios.c_cflag & CLOCAL) - do_clocal = 1; - } else { - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - save_flags(flags); cli(); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - restore_flags(flags); - info->blocked_open++; - while (1) { - save_flags(flags); cli(); - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - (tty->termios->c_cflag & CBAUD)) - serial_out(info, UART_MCR, - serial_inp(info, UART_MCR) | - (UART_MCR_DTR | UART_MCR_RTS)); - restore_flags(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - !(info->flags & ASYNC_CLOSING) && - (do_clocal || (serial_in(info, UART_MSR) & - UART_MSR_DCD))) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - schedule(); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, struct async_struct **ret_info) -{ - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } - memset(info, 0, sizeof(struct async_struct)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->io_type = sstate->io_type; - info->iomem_base = sstate->iomem_base; - info->iomem_reg_shift = sstate->iomem_reg_shift; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct async_struct *info; - int retval, line; - unsigned long page; - - MOD_INC_USE_COUNT; - line = MINOR(tty->device) - tty->driver.minor_start; - if ((line < 0) || (line >= NR_PORTS)) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - retval = get_async_struct(line, &info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - tty->driver_data = info; - info->tty = tty; - if (serial_paranoia_check(info, tty->device, "rs_open")) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, - info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - if (!tmp_buf) { - page = get_zeroed_page(GFP_KERNEL); - if (!page) { - MOD_DEC_USE_COUNT; - return -ENOMEM; - } - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - MOD_DEC_USE_COUNT; -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - MOD_DEC_USE_COUNT; - return retval; - } - - if ((info->state->count == 1) && - (info->flags & ASYNC_SPLIT_TERMIOS)) { - if (tty->driver.subtype == SERIAL_TYPE_NORMAL) - *tty->termios = info->state->normal_termios; - else - *tty->termios = info->state->callout_termios; - change_speed(info, 0); - } -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if (sercons.cflag && sercons.index == line) { - tty->termios->c_cflag = sercons.cflag; - sercons.cflag = 0; - change_speed(info, 0); - } -#endif - info->session = current->session; - info->pgrp = current->pgrp; - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open ttys%d successful...", info->line); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; - int ret; - unsigned long flags; - - ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d", - state->line, uart_config[state->type].name, - state->port, state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->tty = 0; - } - save_flags(flags); cli(); - status = serial_in(info, UART_MSR); - control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR); - restore_flags(flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (control & UART_MCR_RTS) - strcat(stat_buf, "|RTS"); - if (status & UART_MSR_CTS) - strcat(stat_buf, "|CTS"); - if (control & UART_MCR_DTR) - strcat(stat_buf, "|DTR"); - if (status & UART_MSR_DSR) - strcat(stat_buf, "|DSR"); - if (status & UART_MSR_DCD) - strcat(stat_buf, "|CD"); - if (status & UART_MSR_RI) - strcat(stat_buf, "|RI"); - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - /* - * Last thing is the RS-232 status lines - */ - ret += sprintf(buf+ret, " %s\n", stat_buf+1); - return ret; -} - -int rs_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0, l; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n", - serial_version, LOCAL_VERSTRING, serial_revdate); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - l = line_info(page + len, &rs_table[i]); - len += l; - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (off-begin); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static char serial_options[] __initdata = - " no serial options enabled\n"; -#undef SERIAL_OPT - -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, - serial_version, LOCAL_VERSTRING, serial_revdate, - serial_options); -} - - -/* - * This routine is called by rs_init() to initialize a specific serial - * port. It determines what type of UART chip this serial port is - * using: 8250, 16450, 16550, 16550A. The important question is - * whether or not this UART is a 16550A or not, since this will - * determine whether or not we can use its FIFO features or not. - */ -static void autoconfig(struct serial_state * state) -{ - struct async_struct *info, scr_info; - unsigned long flags; - - -#ifdef SERIAL_DEBUG_AUTOCONF - printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line, - state->port, (unsigned) state->iomem_base); -#endif - - if (!CONFIGURED_SERIAL_PORT(state)) - return; - - if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { - au_writel(3, UART_MOD_CNTRL + state->port); - au_sync_delay(10); - } - - state->type = PORT_16550; - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->state = state; - info->port = state->port; - info->flags = state->flags; - info->io_type = state->io_type; - info->iomem_base = state->iomem_base; - info->iomem_reg_shift = state->iomem_reg_shift; - - - save_flags(flags); cli(); - state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; - - if (info->port) { - request_region(info->port,8,"serial(auto)"); - } - - /* - * Reset the UART. - */ - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - (void)serial_in(info, UART_RX); - serial_outp(info, UART_IER, 0); - restore_flags(flags); -} - -int register_serial(struct serial_struct *req); -void unregister_serial(int line); - -EXPORT_SYMBOL(register_serial); -EXPORT_SYMBOL(unregister_serial); - - -/* - * The serial driver boot-time initialization code! - */ -static int __init rs_init(void) -{ - int i; - struct serial_state * state; - - init_bh(SERIAL_BH, do_serial_bh); - init_timer(&serial_timer); - serial_timer.function = rs_timer; - mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); - - for (i = 0; i < NR_IRQS; i++) { - IRQ_ports[i] = 0; - IRQ_timeout[i] = 0; - } -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - /* - * The interrupt of the serial console port - * can't be shared. - */ - if (sercons.flags & CON_CONSDEV) { - for(i = 0; i < NR_PORTS; i++) - if (i != sercons.index && - rs_table[i].irq == rs_table[sercons.index].irq) - rs_table[i].irq = 0; - } -#endif - show_serial_version(); - - /* Initialize the tty_driver structure */ - - memset(&serial_driver, 0, sizeof(struct tty_driver)); - serial_driver.magic = TTY_DRIVER_MAGIC; - serial_driver.driver_name = "serial"; -#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) - serial_driver.name = "tts/%d"; -#else - serial_driver.name = "ttyS"; -#endif - serial_driver.major = TTY_MAJOR; - serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET; - serial_driver.num = NR_PORTS; - serial_driver.type = TTY_DRIVER_TYPE_SERIAL; - serial_driver.subtype = SERIAL_TYPE_NORMAL; - serial_driver.init_termios = tty_std_termios; - serial_driver.init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; - serial_driver.refcount = &serial_refcount; - serial_driver.table = serial_table; - serial_driver.termios = serial_termios; - serial_driver.termios_locked = serial_termios_locked; - - serial_driver.open = rs_open; - serial_driver.close = rs_close; - serial_driver.write = rs_write; - serial_driver.put_char = rs_put_char; - serial_driver.flush_chars = rs_flush_chars; - serial_driver.write_room = rs_write_room; - serial_driver.chars_in_buffer = rs_chars_in_buffer; - serial_driver.flush_buffer = rs_flush_buffer; - serial_driver.ioctl = rs_ioctl; - serial_driver.throttle = rs_throttle; - serial_driver.unthrottle = rs_unthrottle; - serial_driver.set_termios = rs_set_termios; - serial_driver.stop = rs_stop; - serial_driver.start = rs_start; - serial_driver.hangup = rs_hangup; - serial_driver.break_ctl = rs_break; - serial_driver.send_xchar = rs_send_xchar; - serial_driver.wait_until_sent = rs_wait_until_sent; - serial_driver.read_proc = rs_read_proc; - - /* - * The callout device is just like normal device except for - * major number and the subtype code. - */ - callout_driver = serial_driver; -#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) - callout_driver.name = "cua/%d"; -#else - callout_driver.name = "cua"; -#endif - callout_driver.major = TTYAUX_MAJOR; - callout_driver.subtype = SERIAL_TYPE_CALLOUT; - callout_driver.read_proc = 0; - callout_driver.proc_entry = 0; - - if (tty_register_driver(&serial_driver)) - panic("Couldn't register serial driver"); - if (tty_register_driver(&callout_driver)) - panic("Couldn't register callout driver"); - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->baud_base = get_au1000_uart_baud_base(); - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->callout_termios = callout_driver.init_termios; - state->normal_termios = serial_driver.init_termios; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - state->irq = irq_cannonicalize(state->irq); - if (state->hub6) - state->io_type = SERIAL_IO_HUB6; - if (state->port && check_region(state->port,8)) { - continue; - } - - if (state->flags & ASYNC_BOOT_AUTOCONF) { - autoconfig(state); - } - } - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - if (state->type == PORT_UNKNOWN) { - continue; - } - printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n", - state->line + SERIAL_DEV_OFFSET, - (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", - state->port, state->irq, - uart_config[state->type].name); - tty_register_devfs(&serial_driver, 0, - serial_driver.minor_start + state->line); - tty_register_devfs(&callout_driver, 0, - callout_driver.minor_start + state->line); - } - return 0; -} - -/* - * register_serial and unregister_serial allows for 16x50 serial ports to be - * configured at run-time, to support PCMCIA modems. - */ - -/** - * register_serial - configure a 16x50 serial port at runtime - * @req: request structure - * - * Configure the serial port specified by the request. If the - * port exists and is in use an error is returned. If the port - * is not currently in the table it is added. - * - * The port is then probed and if neccessary the IRQ is autodetected - * If this fails an error is returned. - * - * On success the port is ready to use and the line number is returned. - */ - -int register_serial(struct serial_struct *req) -{ - int i; - unsigned long flags; - struct serial_state *state; - struct async_struct *info; - unsigned long port; - - port = req->port; - if (HIGH_BITS_OFFSET) - port += (unsigned long) req->port_high << HIGH_BITS_OFFSET; - - save_flags(flags); cli(); - for (i = 0; i < NR_PORTS; i++) { - if ((rs_table[i].port == port) && - (rs_table[i].iomem_base == req->iomem_base)) - break; - } - if (i == NR_PORTS) { - for (i = 0; i < NR_PORTS; i++) - if ((rs_table[i].type == PORT_UNKNOWN) && - (rs_table[i].count == 0)) - break; - } - if (i == NR_PORTS) { - restore_flags(flags); - return -1; - } - state = &rs_table[i]; - if (rs_table[i].count) { - restore_flags(flags); - printk("Couldn't configure serial #%d (port=%ld,irq=%d): " - "device already open\n", i, port, req->irq); - return -1; - } - state->irq = req->irq; - state->port = port; - state->flags = req->flags; - state->io_type = req->io_type; - state->iomem_base = req->iomem_base; - state->iomem_reg_shift = req->iomem_reg_shift; - if (req->baud_base) - state->baud_base = req->baud_base; - if ((info = state->info) != NULL) { - info->port = port; - info->flags = req->flags; - info->io_type = req->io_type; - info->iomem_base = req->iomem_base; - info->iomem_reg_shift = req->iomem_reg_shift; - } - autoconfig(state); - if (state->type == PORT_UNKNOWN) { - restore_flags(flags); - printk("register_serial(): autoconfig failed\n"); - return -1; - } - restore_flags(flags); - - printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n", - state->line + SERIAL_DEV_OFFSET, - state->iomem_base ? "iomem" : "port", - state->iomem_base ? (unsigned long)state->iomem_base : - state->port, state->irq, uart_config[state->type].name); - tty_register_devfs(&serial_driver, 0, - serial_driver.minor_start + state->line); - tty_register_devfs(&callout_driver, 0, - callout_driver.minor_start + state->line); - return state->line + SERIAL_DEV_OFFSET; -} - -/** - * unregister_serial - deconfigure a 16x50 serial port - * @line: line to deconfigure - * - * The port specified is deconfigured and its resources are freed. Any - * user of the port is disconnected as if carrier was dropped. Line is - * the port number returned by register_serial(). - */ - -void unregister_serial(int line) -{ - unsigned long flags; - struct serial_state *state = &rs_table[line]; - - save_flags(flags); cli(); - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - state->type = PORT_UNKNOWN; - printk(KERN_INFO "tty%02d unloaded\n", state->line); - /* These will be hidden, because they are devices that will no longer - * be available to the system. (ie, PCMCIA modems, once ejected) - */ - tty_unregister_devfs(&serial_driver, - serial_driver.minor_start + state->line); - tty_unregister_devfs(&callout_driver, - callout_driver.minor_start + state->line); - restore_flags(flags); -} - -static void __exit rs_fini(void) -{ - unsigned long flags; - int e1, e2; - int i; - struct async_struct *info; - - /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ - del_timer_sync(&serial_timer); - save_flags(flags); cli(); - remove_bh(SERIAL_BH); - if ((e1 = tty_unregister_driver(&serial_driver))) - printk("serial: failed to unregister serial driver (%d)\n", - e1); - if ((e2 = tty_unregister_driver(&callout_driver))) - printk("serial: failed to unregister callout driver (%d)\n", - e2); - restore_flags(flags); - - for (i = 0; i < NR_PORTS; i++) { - if ((info = rs_table[i].info)) { - rs_table[i].info = NULL; - kfree(info); - } - if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) { - release_region(rs_table[i].port, 8); - } - } - if (tmp_buf) { - unsigned long pg = (unsigned long) tmp_buf; - tmp_buf = NULL; - free_page(pg); - } -} - -module_init(rs_init); -module_exit(rs_fini); -MODULE_DESCRIPTION("Au1000 serial driver"); - - -/* - * ------------------------------------------------------------ - * Serial console driver - * ------------------------------------------------------------ - */ -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -static struct async_struct async_sercons; - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct async_struct *info) -{ - unsigned int status, tmout = 0xffffff; - - do { - status = serial_in(info, UART_LSR); - - if (status & UART_LSR_BI) - lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - } while((status & BOTH_EMPTY) != BOTH_EMPTY); -} - - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void serial_console_write(struct console *co, const char *s, - unsigned count) -{ - static struct async_struct *info = &async_sercons; - int ier; - unsigned i; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(info, UART_IER); - serial_out(info, UART_IER, 0x00); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++, s++) { - wait_for_xmitr(info); - - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_out(info, UART_TX, *s); - if (*s == 10) { - wait_for_xmitr(info); - serial_out(info, UART_TX, 13); - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - wait_for_xmitr(info); - serial_out(info, UART_IER, ier); -} - -static kdev_t serial_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init serial_console_setup(struct console *co, char *options) -{ - static struct async_struct *info; - struct serial_state *state; - unsigned cval; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - int quot = 0; - char *s; - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while(*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - - /* - * Divisor, bytesize and parity - */ - state = rs_table + co->index; - info = &async_sercons; - info->magic = SERIAL_MAGIC; - info->state = state; - info->port = state->port; - info->flags = state->flags; - info->io_type = state->io_type; - info->iomem_base = state->iomem_base; - info->iomem_reg_shift = state->iomem_reg_shift; - state->baud_base = get_au1000_uart_baud_base(); - quot = state->baud_base / baud; - - cval = cflag & (CSIZE | CSTOPB); - cval >>= 4; - if (cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * Disable UART interrupts, set DTR and RTS high - * and set speed. - */ - serial_out(info, UART_CLK, quot & 0xffff); - serial_out(info, UART_IER, 0); - serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); - - /* - * If we read 0xff from the LSR, there is no UART here. - */ - if (serial_in(info, UART_LSR) == 0xff) - return -1; - - return 0; -} - -static struct console sercons = { - name: "ttyS", - write: serial_console_write, - device: serial_console_device, - setup: serial_console_setup, - flags: CON_PRINTBUFFER, - index: -1, -}; - -/* - * Register console. - */ -void __init au1000_serial_console_init(void) -{ - register_console(&sercons); -} -#endif - -/* - Local variables: - compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" - End: -*/ diff -urN linux-2.4.21/arch/mips/au1000/common/setup.c linux-2.4.22/arch/mips/au1000/common/setup.c --- linux-2.4.21/arch/mips/au1000/common/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,205 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Au1x00 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) +extern void console_setup(char *, int *); +char serial_console[20]; +#endif + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +extern struct rtc_ops no_rtc_ops; +extern char * __init prom_getcmdline(void); +extern void __init board_setup(void); +extern void au1000_restart(char *); +extern void au1000_halt(void); +extern void au1000_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) +extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); +static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size); +#endif + +void __init au1x00_setup(void) +{ + char *argptr; + + /* Various early Au1000 Errata corrected by this */ + set_c0_config(1<<19); /* Config[OD] */ + + board_setup(); /* board specific setup */ + + argptr = prom_getcmdline(); + +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + +#ifdef CONFIG_FB_AU1100 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + /* default panel */ + //strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16"); + strcat(argptr, " video=au1100fb:panel:s10,nohwcursor"); + } +#endif + +#ifdef CONFIG_FB_E1356 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=e1356fb:system:pb1500"); + } +#endif + +#ifdef CONFIG_FB_XPERT98 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=atyfb:1024x768-8@70"); + } +#endif + +#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) + // au1000 does not support vra, au1500 and au1100 do + strcat(argptr, " au1000_audio=vra"); + argptr = prom_getcmdline(); +#endif + _machine_restart = au1000_restart; + _machine_halt = au1000_halt; + _machine_power_off = au1000_power_off; +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) + fixup_bigphys_addr = au1500_fixup_bigphys_addr; +#endif + + // IO/MEM resources. + set_io_port_base(0); + ioport_resource.start = IOPORT_RESOURCE_START; + ioport_resource.end = IOPORT_RESOURCE_END; + iomem_resource.start = IOMEM_RESOURCE_START; + iomem_resource.end = IOMEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif + +#ifdef CONFIG_USB_OHCI + // enable host controller and wait for reset done + au_writel(0x08, USB_HOST_CONFIG); + udelay(1000); + au_writel(0x0E, USB_HOST_CONFIG); + udelay(1000); + au_readl(USB_HOST_CONFIG); // throw away first read + while (!(au_readl(USB_HOST_CONFIG) & 0x10)) + au_readl(USB_HOST_CONFIG); +#endif +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + +#ifdef CONFIG_FB + // Needed if PCI video card in use + conswitchp = &dummy_con; +#endif + +#ifndef CONFIG_SERIAL_NONSTANDARD + /* don't touch the default serial console */ + au_writel(0, UART0_ADDR + UART_CLK); +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); + au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); + au_writel(0, SYS_TOYTRIM); +} + +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) +/* This routine should be valid for all Au1500 based boards */ +static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + u32 pci_start = (u32)Au1500_PCI_MEM_START; + u32 pci_end = (u32)Au1500_PCI_MEM_END; + + /* Don't fixup 36 bit addresses */ + if ((phys_addr >> 32) != 0) return phys_addr; + + /* check for pci memory window */ + if ((phys_addr >= pci_start) && ((phys_addr + size) < pci_end)) { + return (phys_t)((phys_addr - pci_start) + + Au1500_PCI_MEM_START); + } + else + return phys_addr; +} +#endif diff -urN linux-2.4.21/arch/mips/au1000/common/time.c linux-2.4.22/arch/mips/au1000/common/time.c --- linux-2.4.21/arch/mips/au1000/common/time.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -45,7 +45,7 @@ #include extern void startup_match20_interrupt(void); - +extern void do_softirq(void); extern volatile unsigned long wall_jiffies; unsigned long missed_heart_beats = 0; @@ -63,9 +63,11 @@ static unsigned long last_pc0, last_match20; #endif +static spinlock_t time_lock = SPIN_LOCK_UNLOCKED; + static inline void ack_r4ktimer(unsigned long newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } /* @@ -93,7 +95,7 @@ goto null; do { - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; @@ -102,7 +104,7 @@ r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) + } while (((unsigned long)read_c0_count() - r4k_cur) < 0x7fffffff); irq_exit(cpu, irq); @@ -174,7 +176,7 @@ int trim_divide = 16; unsigned long flags; - save_and_cli(flags); + spin_lock_irqsave(&time_lock, flags); counter = au_readl(SYS_COUNTER_CNTRL); au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); @@ -193,16 +195,16 @@ while (au_readl(SYS_RTCREAD) < start); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */ while (end > au_readl(SYS_RTCREAD)); - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); cpu_speed = count * 2; mips_counter_frequency = count; - set_au1000_uart_baud_base(((cpu_speed) / 4) / 16); - restore_flags(flags); + set_au1x00_uart_baud_base(((cpu_speed) / 4) / 16); + spin_unlock_irqrestore(&time_lock, flags); return (cpu_speed / HZ); } @@ -221,11 +223,11 @@ est_freq -= est_freq%10000; printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - set_au1000_speed(est_freq); - set_au1000_lcd_clock(); // program the LCD clock - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); + set_au1x00_speed(est_freq); + set_au1x00_lcd_clock(); // program the LCD clock + r4k_cur = (read_c0_count() + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); + write_c0_compare(r4k_cur); /* no RTC on the pb1000 */ xtime.tv_sec = 0; @@ -258,7 +260,7 @@ startup_match20_interrupt(); #endif - //set_cp0_status(ALLINTS); + //set_c0_status(ALLINTS); au_sync(); } @@ -266,7 +268,7 @@ #define USECS_PER_JIFFY (1000000/HZ) #define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff) - +#ifndef CONFIG_PM static unsigned long div64_32(unsigned long v1, unsigned long v2, unsigned long v3) { @@ -274,7 +276,7 @@ do_div64_32(r0, v1, v2, v3); return r0; } - +#endif static unsigned long do_fast_gettimeoffset(void) { @@ -326,7 +328,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -350,7 +352,7 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; read_lock_irqsave (&xtime_lock, flags); *tv = xtime; @@ -376,7 +378,7 @@ write_lock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is is value at the last tick. + * However, the value in this location is value at the last tick. * Discover what correction gettimeofday would have done, and then * undo it! */ diff -urN linux-2.4.21/arch/mips/au1000/common/usbdev.c linux-2.4.22/arch/mips/au1000/common/usbdev.c --- linux-2.4.21/arch/mips/au1000/common/usbdev.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/common/usbdev.c 2003-08-25 04:44:39.000000000 -0700 @@ -199,7 +199,7 @@ #if 0 static void -dump_setup(devrequest* s) +dump_setup(struct usb_ctrlrequest* s) { dbg(__FUNCTION__ ": requesttype=%d", s->requesttype); dbg(__FUNCTION__ ": request=%d %s", s->request, @@ -635,9 +635,9 @@ */ static ep0_stage_t -do_get_status(struct usb_dev* dev, devrequest* setup) +do_get_status(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - switch (setup->requesttype) { + switch (setup->bRequestType) { case 0x80: // Device // FIXME: send device status break; @@ -657,9 +657,9 @@ } static ep0_stage_t -do_clear_feature(struct usb_dev* dev, devrequest* setup) +do_clear_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - switch (setup->requesttype) { + switch (setup->bRequestType) { case 0x00: // Device if ((le16_to_cpu(setup->wValue) & 0xff) == 1) dev->remote_wakeup_en = 0; @@ -670,7 +670,7 @@ if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { endpoint_t *ep = epaddr_to_ep(dev, - le16_to_cpu(setup->index) & 0xff); + le16_to_cpu(setup->wIndex) & 0xff); endpoint_unstall(ep); endpoint_reset_datatoggle(ep); @@ -683,7 +683,7 @@ } static ep0_stage_t -do_reserved(struct usb_dev* dev, devrequest* setup) +do_reserved(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // Invalid request, stall End Point 0 endpoint_stall(&dev->ep[0]); @@ -691,9 +691,9 @@ } static ep0_stage_t -do_set_feature(struct usb_dev* dev, devrequest* setup) +do_set_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - switch (setup->requesttype) { + switch (setup->bRequestType) { case 0x00: // Device if ((le16_to_cpu(setup->wValue) & 0xff) == 1) dev->remote_wakeup_en = 1; @@ -701,10 +701,10 @@ endpoint_stall(&dev->ep[0]); break; case 0x02: // End Point - if ((le16_to_cpu(setup->vwValue) & 0xff) == 0) { + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { endpoint_t *ep = epaddr_to_ep(dev, - le16_to_cpu(setup->index) & 0xff); + le16_to_cpu(setup->wIndex) & 0xff); endpoint_stall(ep); } else @@ -716,7 +716,7 @@ } static ep0_stage_t -do_set_address(struct usb_dev* dev, devrequest* setup) +do_set_address(struct usb_dev* dev, struct usb_ctrlrequest* setup) { int new_state = dev->state; int new_addr = le16_to_cpu(setup->wValue); @@ -743,9 +743,9 @@ } static ep0_stage_t -do_get_descriptor(struct usb_dev* dev, devrequest* setup) +do_get_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - int strnum, desc_len = le16_to_cpu(setup->length); + int strnum, desc_len = le16_to_cpu(setup->wLength); switch (le16_to_cpu(setup->wValue) >> 8) { case USB_DT_DEVICE: @@ -812,7 +812,7 @@ } static ep0_stage_t -do_set_descriptor(struct usb_dev* dev, devrequest* setup) +do_set_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // TODO: implement // there will be an OUT data stage (the descriptor to set) @@ -820,7 +820,7 @@ } static ep0_stage_t -do_get_configuration(struct usb_dev* dev, devrequest* setup) +do_get_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // send dev->configuration dbg("sending config"); @@ -830,7 +830,7 @@ } static ep0_stage_t -do_set_configuration(struct usb_dev* dev, devrequest* setup) +do_set_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // set active config to low-byte of setup->wValue dev->configuration = le16_to_cpu(setup->wValue) & 0xff; @@ -851,10 +851,10 @@ } static ep0_stage_t -do_get_interface(struct usb_dev* dev, devrequest* setup) +do_get_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // interface must be zero. - if ((le16_to_cpu(setup->index) & 0xff) || dev->state == ADDRESS) { + if ((le16_to_cpu(setup->wIndex) & 0xff) || dev->state == ADDRESS) { // FIXME: respond with "request error". how? } else if (dev->state == CONFIGURED) { // send dev->alternate_setting @@ -868,12 +868,12 @@ } static ep0_stage_t -do_set_interface(struct usb_dev* dev, devrequest* setup) +do_set_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) { if (dev->state == ADDRESS) { // FIXME: respond with "request error". how? } else if (dev->state == CONFIGURED) { - dev->interface = le16_to_cpu(setup->index) & 0xff; + dev->interface = le16_to_cpu(setup->wIndex) & 0xff; dev->alternate_setting = le16_to_cpu(setup->wValue) & 0xff; // interface and alternate_setting must be zero @@ -886,14 +886,14 @@ } static ep0_stage_t -do_synch_frame(struct usb_dev* dev, devrequest* setup) +do_synch_frame(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // TODO return SETUP_STAGE; } typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev, - devrequest* setup); + struct usb_ctrlrequest* setup); /* Table of the standard device request handlers */ @@ -916,25 +916,25 @@ // SETUP packet request dispatcher static void -do_setup (struct usb_dev* dev, devrequest* setup) +do_setup (struct usb_dev* dev, struct usb_ctrlrequest* setup) { req_method_t m; - dbg(__FUNCTION__ ": req %d %s", setup->request, - get_std_req_name(setup->request)); + dbg(__FUNCTION__ ": req %d %s", setup->bRequestType, + get_std_req_name(setup->bRequestType)); - if ((setup->requesttype & USB_TYPE_MASK) != USB_TYPE_STANDARD || - (setup->requesttype & USB_RECIP_MASK) != USB_RECIP_DEVICE) { + if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD || + (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) { err(__FUNCTION__ ": invalid requesttype 0x%02x", - setup->requesttype); + setup->bRequestType); return; } - if ((setup->requesttype & 0x80) == USB_DIR_OUT && setup->length) - dbg(__FUNCTION__ ": OUT phase! length=%d", setup->length); + if ((setup->bRequestType & 0x80) == USB_DIR_OUT && setup->wLength) + dbg(__FUNCTION__ ": OUT phase! length=%d", setup->wLength); - if (setup->request < sizeof(req_method)/sizeof(req_method_t)) - m = req_method[setup->request]; + if (setup->bRequestType < sizeof(req_method)/sizeof(req_method_t)) + m = req_method[setup->bRequestType]; else m = do_reserved; @@ -973,14 +973,14 @@ vdbg("SU bit is %s in setup stage", (pkt->status & PKT_STATUS_SU) ? "set" : "not set"); - if (pkt->size == sizeof(devrequest)) { + if (pkt->size == sizeof(struct usb_ctrlrequest)) { #ifdef VDEBUG if (pkt->status & PKT_STATUS_ACK) vdbg("received SETUP"); else vdbg("received NAK SETUP"); #endif - do_setup(dev, (devrequest*)pkt->payload); + do_setup(dev, (struct usb_ctrlrequest*)pkt->payload); } else err(__FUNCTION__ ": wrong size SETUP received"); break; diff -urN linux-2.4.21/arch/mips/au1000/db1x00/Makefile linux-2.4.22/arch/mips/au1000/db1x00/Makefile --- linux-2.4.21/arch/mips/au1000/db1x00/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/db1x00/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,22 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor PB1000 board. +# +# 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). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := db1x00.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/au1000/db1x00/board_setup.c linux-2.4.22/arch/mips/au1000/db1x00/board_setup.c --- linux-2.4.21/arch/mips/au1000/db1x00/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/db1x00/board_setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Db1x00 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +static BCSR * const bcsr = (BCSR *)0xAE000000; + +void __init board_setup(void) +{ + u32 pin_func; + + rtc_ops = &no_rtc_ops; + +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + au_writel(pin_func, SYS_PINFUNC); +#endif + +#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1000)) + /* set IRFIRSEL instead of GPIO15 */ + pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8)); + au_writel(pin_func, SYS_PINFUNC); + /* power off until the driver is in use */ + bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; + bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF; + au_sync(); +#endif + au_writel(0, 0xAE000010); /* turn off pcmcia power */ + +#ifdef CONFIG_MIPS_DB1000 + printk("AMD Alchemy Au1000/Db1000 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1500 + printk("AMD Alchemy Au1500/Db1500 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1100 + printk("AMD Alchemy Au1100/Db1100 Board\n"); +#endif +#ifdef CONFIG_MIPS_BOSPORUS + printk("AMD Alchemy Bosporus Board\n"); +#endif +#ifdef CONFIG_MIPS_MIRAGE + printk("AMD Alchemy Mirage Board\n"); +#endif +} diff -urN linux-2.4.21/arch/mips/au1000/db1x00/init.c linux-2.4.22/arch/mips/au1000/db1x00/init.c --- linux-2.4.21/arch/mips/au1000/db1x00/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/db1x00/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,77 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PB1000 board setup + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ +#ifdef CONFIG_MIPS_BOSPORUS + return "Alchemy Bosporus Gateway Reference"; +#else + return "Alchemy Db1x00"; +#endif +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_DB1000; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.21/arch/mips/au1000/db1x00/irqmap.c linux-2.4.22/arch/mips/au1000/db1x00/irqmap.c --- linux-2.4.21/arch/mips/au1000/db1x00/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/db1x00/irqmap.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,118 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_MIRAGE) + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, +#endif +#ifndef CONFIG_MIPS_MIRAGE + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, +#endif + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + +#ifdef CONFIG_SOC_AU1500 + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, +#endif + +#ifdef CONFIG_MIPS_DB1500 + { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, +#endif + +#ifndef CONFIG_MIPS_MIRAGE + { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 Fully_Interted# + { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 STSCHG# + { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ# + + { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 Fully_Interted# + { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 STSCHG# + { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ# +#endif + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21/arch/mips/au1000/mtx-1/Makefile linux-2.4.22/arch/mips/au1000/mtx-1/Makefile --- linux-2.4.21/arch/mips/au1000/mtx-1/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/mtx-1/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,23 @@ +# +# Copyright 2003 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# Bruno Randolf +# +# Makefile for 4G Systems MTX-1 board. +# +# 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). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := mtx-1.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/au1000/mtx-1/board_setup.c linux-2.4.22/arch/mips/au1000/mtx-1/board_setup.c --- linux-2.4.21/arch/mips/au1000/mtx-1/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/mtx-1/board_setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * MTX-1 board setup. + * + * Copyright 2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * Bruno Randolf + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +void __init board_setup(void) +{ + u32 pin_func; + + rtc_ops = &no_rtc_ops; + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC); +#endif + // enable USB power switch + au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR ); + au_writel( 0x100000, GPIO2_OUTPUT ); + +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) + + +#ifdef CONFIG_PCI +#if defined(__MIPSEB__) + au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); +#else + au_writel(0xf, Au1500_PCI_CFG); +#endif +#endif + + // initialize sys_pinfunc: + // disable second ethernet port (SYS_PF_NI2) + // set U3/GPIO23 to GPIO23 (SYS_PF_U3) + au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC ); + + // initialize GPIO: none used ATM + au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); + + // enable LED and set it to green + au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); + au_writel( 0x18000800, GPIO2_OUTPUT ); + + printk("4G Systems MTX-1 Board\n"); +} diff -urN linux-2.4.21/arch/mips/au1000/mtx-1/init.c linux-2.4.22/arch/mips/au1000/mtx-1/init.c --- linux-2.4.21/arch/mips/au1000/mtx-1/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/mtx-1/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,74 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * MTX-1 board setup + * + * Copyright 2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * Bruno Randolf + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "MTX-1"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_MTX1; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.21/arch/mips/au1000/mtx-1/irqmap.c linux-2.4.22/arch/mips/au1000/mtx-1/irqmap.c --- linux-2.4.21/arch/mips/au1000/mtx-1/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/mtx-1/irqmap.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,93 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21/arch/mips/au1000/pb1000/Makefile linux-2.4.22/arch/mips/au1000/pb1000/Makefile --- linux-2.4.21/arch/mips/au1000/pb1000/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1000/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -14,8 +14,6 @@ O_TARGET := pb1000.o -obj-y := init.o setup.o - -obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o +obj-y := init.o board_setup.o irqmap.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/au1000/pb1000/board_setup.c linux-2.4.22/arch/mips/au1000/pb1000/board_setup.c --- linux-2.4.21/arch/mips/au1000/pb1000/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1000/board_setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,192 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1000 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +extern struct rtc_ops no_rtc_ops; + +void __init board_setup(void) +{ + u32 pin_func, static_cfg0; + u32 sys_freqctrl, sys_clksrc; + u32 prid = read_c0_prid(); + + rtc_ops = &no_rtc_ops; + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PINSTATERD); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + switch (prid & 0x000000FF) + { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + /* CPU core freq to 48MHz to slow it way down... */ + au_writel(4, SYS_CPUPLL); + + /* + * Setup 48MHz FREQ2 from CPUPLL for USB Host + */ + /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ + sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* CPU core freq to 384MHz */ + au_writel(0x20, SYS_CPUPLL); + + printk("Au1000: 48MHz OHCI workaround enabled\n"); + break; + + default: /* HC and newer */ + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + break; + } + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ +#ifdef CONFIG_USB_OHCI + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); +#endif + au_writel(sys_clksrc, SYS_CLKSRC); + + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); + +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); + au_writel(0x2800, SYS_TRIOUTCLR); + au_writel(0x0030, SYS_OUTPUTCLR); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + // make gpio 15 an input (for interrupt line) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100); + // we don't need I2S, so make it available for GPIO[31:29] + pin_func |= (1<<5); + au_writel(pin_func, SYS_PINFUNC); + + au_writel(0x8000, SYS_TRIOUTCLR); + + static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00); + au_writel(static_cfg0, MEM_STCFG0); + + // configure RCE2* for LCD + au_writel(0x00000004, MEM_STCFG2); + + // MEM_STTIME2 + au_writel(0x09000000, MEM_STTIME2); + + // Set 32-bit base address decoding for RCE2* + au_writel(0x10003ff0, MEM_STADDR2); + + // PCI CPLD setup + // expand CE0 to cover PCI + au_writel(0x11803e40, MEM_STADDR1); + + // burst visibility on + au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0); + + au_writel(0x83, MEM_STCFG1); // ewait enabled, flash timing + au_writel(0x33030a10, MEM_STTIME1); // slower timing for FPGA + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + +#ifdef CONFIG_PCI + au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 + au_writel(0, SDRAM_MBAR); // set mbar to 0 + au_writel(0x2, SDRAM_CMD); // enable memory accesses + au_sync_delay(1); +#endif + + /* Enable Au1000 BCLK switching - note: sed1356 must not use + * its BCLK (Au1000 LCLK) for any timings */ + switch (prid & 0x000000FF) + { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + break; + default: /* HC and newer */ + au_writel(0x00000060, 0xb190003c); + break; + } +} diff -urN linux-2.4.21/arch/mips/au1000/pb1000/irqmap.c linux-2.4.22/arch/mips/au1000/pb1000/irqmap.c --- linux-2.4.21/arch/mips/au1000/pb1000/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1000/irqmap.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,96 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21/arch/mips/au1000/pb1000/pci_fixup.c linux-2.4.22/arch/mips/au1000/pb1000/pci_fixup.c --- linux-2.4.21/arch/mips/au1000/pb1000/pci_fixup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1000/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,90 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Board specific pci fixups. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -void __init pcibios_fixup_resources(struct pci_dev *dev) -{ - /* will need to fixup IO resources */ -} - -void __init pcibios_fixup(void) -{ - unsigned long pci_mem_start = (unsigned long) PCI_MEM_START; - - au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 - au_writel(0, SDRAM_MBAR); // set mbar to 0 - au_writel(0x2, SDRAM_CMD); // enable memory accesses - au_sync_delay(1); - - // set extend byte to mbar of ext slot - au_writel(((pci_mem_start >> 24) & 0xff) | - (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), PCI_BRIDGE_CONFIG); - DBG("Set bridge config to %x\n", au_readl(PCI_BRIDGE_CONFIG)); -} - -void __init pcibios_fixup_irqs(void) -{ - unsigned int slot, func; - unsigned char pin; - struct pci_dev *dev; - - pci_for_each_dev(dev) { - if (dev->bus->number != 0) - return; - - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - slot = PCI_SLOT(dev->devfn); - func = PCI_FUNC(dev->devfn); - dev->irq = AU1000_GPIO_15; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - DBG("slot %d func %d irq %d\n", slot, func, dev->irq); - } -} -unsigned int pcibios_assign_all_busses(void) -{ - return 0; -} -#endif diff -urN linux-2.4.21/arch/mips/au1000/pb1000/pci_ops.c linux-2.4.22/arch/mips/au1000/pb1000/pci_ops.c --- linux-2.4.21/arch/mips/au1000/pb1000/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1000/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,200 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * PB1000 specific pci support. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -static struct resource pci_io_resource = { - "pci IO space", - PCI_IO_START, - PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource pci_mem_resource = { - "pci memory space", - PCI_MEM_START, - PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops pb1000_pci_ops; - -struct pci_channel mips_pci_channels[] = { - {&pb1000_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 1}, - {(struct pci_ops *) NULL, (struct resource *) NULL, - (struct resource *) NULL, (int) NULL, (int) NULL} -}; - - -/* - * "Bus 2" is really the first and only external slot on the pb1000. - * We'll call that bus 0, and limit the accesses to that single - * external slot only. The SDRAM is already initialized in setup.c. - */ -static int config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 * data) -{ - unsigned char bus = dev->bus->number; - unsigned char dev_fn = dev->devfn; - unsigned long config; - - if (((dev_fn >> 3) != 0) || (bus != 0)) { - *data = 0xffffffff; - return -1; - } - - config = PCI_CONFIG_BASE | (where & ~0x3); - - if (access_type == PCI_ACCESS_WRITE) { - au_writel(*data, config); - } else { - *data = au_readl(config); - } - au_sync_udelay(1); - - DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", - access_type, bus, dev_fn, where, *data, config); - - DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), *data); - - if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) { - *data = 0xffffffff; - return -1; - } else { - return PCIBIOS_SUCCESSFUL; - } -} - - -static int read_config_byte(struct pci_dev *dev, int where, u8 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - *val = data & 0xff; - return ret; -} - - -static int read_config_word(struct pci_dev *dev, int where, u16 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - *val = data & 0xffff; - return ret; -} - -static int read_config_dword(struct pci_dev *dev, int where, u32 * val) -{ - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, val); - return ret; -} - - -static int write_config_byte(struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_word(struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops pb1000_pci_ops = { - read_config_byte, - read_config_word, - read_config_dword, - write_config_byte, - write_config_word, - write_config_dword -}; -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/au1000/pb1000/setup.c linux-2.4.22/arch/mips/au1000/pb1000/setup.c --- linux-2.4.21/arch/mips/au1000/pb1000/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1000/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,302 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Alchemy Pb1000 board setup. - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_USB_OHCI -// Enable the workaround for the OHCI DoneHead -// register corruption problem. -#define CONFIG_AU1000_OHCI_FIX -#endif - -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_BLK_DEV_INITRD -extern unsigned long initrd_start, initrd_end; -extern void * __rd_start, * __rd_end; -#endif - -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -extern struct ide_ops *ide_ops; -#endif - -extern struct rtc_ops no_rtc_ops; -extern char * __init prom_getcmdline(void); -extern void au1000_restart(char *); -extern void au1000_halt(void); -extern void au1000_power_off(void); -extern struct resource ioport_resource; -extern struct resource iomem_resource; - -void __init bus_error_init(void) { /* nothing */ } - -void __init au1000_setup(void) -{ - char *argptr; - u32 pin_func, static_cfg0; - u32 sys_freqctrl, sys_clksrc; - u32 prid = read_32bit_cp0_register(CP0_PRID); - - argptr = prom_getcmdline(); - - /* Various early Au1000 Errata corrected by this */ - set_cp0_config(1<<19); /* Config[OD] */ - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if ((argptr = strstr(argptr, "console=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " console=ttyS0,115200"); - } -#endif - - rtc_ops = &no_rtc_ops; - _machine_restart = au1000_restart; - _machine_halt = au1000_halt; - _machine_power_off = au1000_power_off; - - // IO/MEM resources. - set_io_port_base(0); - ioport_resource.start = 0x10000000; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x10000000; - iomem_resource.end = 0xffffffff; - -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); - initrd_start = (unsigned long)&__rd_start; - initrd_end = (unsigned long)&__rd_end; -#endif - - // set AUX clock to 12MHz * 8 = 96 MHz - au_writel(8, SYS_AUXPLL); - au_writel(0, SYS_PINSTATERD); - udelay(100); - -#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) -#ifdef CONFIG_USB_OHCI - if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { - char usb_args[80]; - argptr = prom_getcmdline(); - memset(usb_args, 0, sizeof(usb_args)); - sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", - USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); - strcat(argptr, usb_args); - } -#endif - - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD clocks */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - - switch (prid & 0x000000FF) - { - case 0x00: /* DA */ - case 0x01: /* HA */ - case 0x02: /* HB */ - /* CPU core freq to 48MHz to slow it way down... */ - au_writel(4, SYS_CPUPLL); - - /* - * Setup 48MHz FREQ2 from CPUPLL for USB Host - */ - /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ - sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* CPU core freq to 384MHz */ - au_writel(0x20, SYS_CPUPLL); - - printk("Au1000: 48MHz OHCI workaround enabled\n"); - break; - - default: /* HC and newer */ - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - break; - } - - /* - * Route 48MHz FREQ2 into USB Host and/or Device - */ -#ifdef CONFIG_USB_OHCI - sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); -#endif -#ifdef CONFIG_AU1000_USB_DEVICE - sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); -#endif - au_writel(sys_clksrc, SYS_CLKSRC); - -#ifdef CONFIG_USB_OHCI - // enable host controller and wait for reset done - au_writel(0x08, USB_HOST_CONFIG); - udelay(1000); - au_writel(0x0E, USB_HOST_CONFIG); - udelay(1000); - au_readl(USB_HOST_CONFIG); // throw away first read - while (!(au_readl(USB_HOST_CONFIG) & 0x10)) - au_readl(USB_HOST_CONFIG); -#endif - - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); - -#ifndef CONFIG_AU1000_USB_DEVICE - // 2nd USB port is USB host - pin_func |= 0x8000; -#endif - au_writel(pin_func, SYS_PINFUNC); - au_writel(0x2800, SYS_TRIOUTCLR); - au_writel(0x0030, SYS_OUTPUTCLR); -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) - - // make gpio 15 an input (for interrupt line) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100); - // we don't need I2S, so make it available for GPIO[31:29] - pin_func |= (1<<5); - au_writel(pin_func, SYS_PINFUNC); - - au_writel(0x8000, SYS_TRIOUTCLR); - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - - static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00); - au_writel(static_cfg0, MEM_STCFG0); - - // configure RCE2* for LCD - au_writel(0x00000004, MEM_STCFG2); - - // MEM_STTIME2 - au_writel(0x09000000, MEM_STTIME2); - - // Set 32-bit base address decoding for RCE2* - au_writel(0x10003ff0, MEM_STADDR2); - - // PCI CPLD setup - // expand CE0 to cover PCI - au_writel(0x11803e40, MEM_STADDR1); - - // burst visibility on - au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0); - - au_writel(0x83, MEM_STCFG1); // ewait enabled, flash timing - au_writel(0x33030a10, MEM_STTIME1); // slower timing for FPGA - - /* setup the static bus controller */ - au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ - au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ - au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ - -#ifdef CONFIG_FB_E1356 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1"); - } -#endif // CONFIG_FB_E1356 - - -#ifdef CONFIG_PCI - au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 - au_writel(0, SDRAM_MBAR); // set mbar to 0 - au_writel(0x2, SDRAM_CMD); // enable memory accesses - au_sync_delay(1); -#endif - -#ifndef CONFIG_SERIAL_NONSTANDARD - /* don't touch the default serial console */ - au_writel(0, UART0_ADDR + UART_CLK); -#endif - au_writel(0, UART1_ADDR + UART_CLK); - au_writel(0, UART2_ADDR + UART_CLK); - au_writel(0, UART3_ADDR + UART_CLK); - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - - // setup irda clocks - // aux clock, divide by 2, clock from 2/4 divider - au_writel(au_readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC); - pin_func = au_readl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD - au_writel(pin_func, SYS_PINFUNC); - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); - au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); - au_writel(0, SYS_TOYTRIM); - - /* Enable Au1000 BCLK switching - note: sed1356 must not use - * its BCLK (Au1000 LCLK) for any timings */ - switch (prid & 0x000000FF) - { - case 0x00: /* DA */ - case 0x01: /* HA */ - case 0x02: /* HB */ - break; - default: /* HC and newer */ - au_writel(0x00000060, 0xb190003c); - break; - } -} diff -urN linux-2.4.21/arch/mips/au1000/pb1100/Makefile linux-2.4.22/arch/mips/au1000/pb1100/Makefile --- linux-2.4.21/arch/mips/au1000/pb1100/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1100/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -10,15 +10,10 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET := pb1100.o -obj-y := init.o setup.o - -obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o +obj-y := init.o board_setup.o irqmap.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/au1000/pb1100/board_setup.c linux-2.4.22/arch/mips/au1000/pb1100/board_setup.c --- linux-2.4.21/arch/mips/au1000/pb1100/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1100/board_setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,138 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1100 board setup. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#ifdef CONFIG_RTC +extern struct rtc_ops pb1500_rtc_ops; +#endif + +void __init board_setup(void) +{ + u32 pin_func; + u32 sys_freqctrl, sys_clksrc; + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PININPUTEN); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD/IrDA clock */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USBH/USBD/IrDA + */ + sys_clksrc |= ((4<<2) | (0<<1) | 0 ); + au_writel(sys_clksrc, SYS_CLKSRC); + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + + // get USB Functionality pin state (device vs host drive pins) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + au_writel(0x00000060, 0xb190003c); + +#ifdef CONFIG_RTC + rtc_ops = &pb1500_rtc_ops; + // Enable the RTC if not already enabled + if (!(readb(0xac000028) & 0x20)) { + writeb(readb(0xac000028) | 0x20, 0xac000028); + au_sync(); + } + // Put the clock in BCD mode + if (readb(0xac00002C) & 0x4) { /* reg B */ + writeb(readb(0xac00002c) & ~0x4, 0xac00002c); + au_sync(); + } +#endif +} diff -urN linux-2.4.21/arch/mips/au1000/pb1100/irqmap.c linux-2.4.22/arch/mips/au1000/pb1100/irqmap.c --- linux-2.4.21/arch/mips/au1000/pb1100/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1100/irqmap.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,100 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted# + { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG# + { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ# + { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ# + { AU1000_GPIO_23, INTC_INT_LOW_LEVEL, 0 }, // 2-wire SCL + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21/arch/mips/au1000/pb1100/pci_fixup.c linux-2.4.22/arch/mips/au1000/pb1100/pci_fixup.c --- linux-2.4.21/arch/mips/au1000/pb1100/pci_fixup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1100/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,68 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Board specific pci fixups. - * - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -static void fixup_resource(int r_num, struct pci_dev *dev) ; -static unsigned long virt_io_addr; - -void __init pcibios_fixup_resources(struct pci_dev *dev) -{ -} - -void __init pcibios_fixup(void) -{ -} - -void __init pcibios_fixup_irqs(void) -{ -} - -unsigned int pcibios_assign_all_busses(void) -{ - return 0; -} - -#endif diff -urN linux-2.4.21/arch/mips/au1000/pb1100/pci_ops.c linux-2.4.22/arch/mips/au1000/pb1100/pci_ops.c --- linux-2.4.21/arch/mips/au1000/pb1100/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1100/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,57 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Pb1100 specific pci support. - * - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -struct pci_channel mips_pci_channels[] = { - {(struct pci_ops *) NULL, (struct resource *) NULL, - (struct resource *) NULL, (int) NULL, (int) NULL} -}; - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/au1000/pb1100/setup.c linux-2.4.22/arch/mips/au1000/pb1100/setup.c --- linux-2.4.21/arch/mips/au1000/pb1100/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1100/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,248 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Alchemy Pb1100 board setup. - * - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_USB_OHCI -// Enable the workaround for the OHCI DoneHead -// register corruption problem. -#define CONFIG_AU1000_OHCI_FIX -#endif - -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_BLK_DEV_INITRD -extern unsigned long initrd_start, initrd_end; -extern void * __rd_start, * __rd_end; -#endif - -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -extern struct ide_ops *ide_ops; -#endif - -#ifdef CONFIG_RTC -extern struct rtc_ops pb1500_rtc_ops; -#endif - -extern char * __init prom_getcmdline(void); -extern void au1000_restart(char *); -extern void au1000_halt(void); -extern void au1000_power_off(void); -extern struct resource ioport_resource; -extern struct resource iomem_resource; - - -void __init bus_error_init(void) { /* nothing */ } - -void __init au1100_setup(void) -{ - char *argptr; - u32 pin_func, static_cfg0; - u32 sys_freqctrl, sys_clksrc; - - argptr = prom_getcmdline(); - - /* NOTE: The memory map is established by YAMON 2.08+ */ - - /* Various early Au1000 Errata corrected by this */ - set_cp0_config(1<<19); /* Config[OD] */ - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if ((argptr = strstr(argptr, "console=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " console=ttyS0,115200"); - } -#endif - -#ifdef CONFIG_SOUND_AU1000 - strcat(argptr, " au1000_audio=vra"); - argptr = prom_getcmdline(); -#endif - - _machine_restart = au1000_restart; - _machine_halt = au1000_halt; - _machine_power_off = au1000_power_off; - - // IO/MEM resources. - set_io_port_base(0); - ioport_resource.start = 0x10000000; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x10000000; - iomem_resource.end = 0xffffffff; - -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); - initrd_start = (unsigned long)&__rd_start; - initrd_end = (unsigned long)&__rd_end; -#endif - - // set AUX clock to 12MHz * 8 = 96 MHz - au_writel(8, SYS_AUXPLL); - au_writel(0, SYS_PININPUTEN); - udelay(100); - -#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) -#ifdef CONFIG_USB_OHCI - if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { - char usb_args[80]; - argptr = prom_getcmdline(); - memset(usb_args, 0, sizeof(usb_args)); - sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", - USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); - strcat(argptr, usb_args); - } -#endif - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); - - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD/IrDA clock */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* - * Route 48MHz FREQ2 into USBH/USBD/IrDA - */ - sys_clksrc |= ((4<<2) | (0<<1) | 0 ); - au_writel(sys_clksrc, SYS_CLKSRC); - - /* setup the static bus controller */ - au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ - au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ - au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ - - // get USB Functionality pin state (device vs host drive pins) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); -#ifndef CONFIG_AU1000_USB_DEVICE - // 2nd USB port is USB host - pin_func |= 0x8000; -#endif - au_writel(pin_func, SYS_PINFUNC); -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) - -#ifdef CONFIG_USB_OHCI - // enable host controller and wait for reset done - au_writel(0x08, USB_HOST_CONFIG); - udelay(1000); - au_writel(0x0c, USB_HOST_CONFIG); - udelay(1000); - au_readl(USB_HOST_CONFIG); - while (!(au_readl(USB_HOST_CONFIG) & 0x10)) - ; - au_readl(USB_HOST_CONFIG); -#endif - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - -#ifdef CONFIG_FB_AU1100 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - /* default panel */ - strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16"); - } -#endif - -#ifdef CONFIG_FB_E1356 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=e1356fb:system:pb1500"); - } -#endif - -#ifndef CONFIG_SERIAL_NONSTANDARD - /* don't touch the default serial console */ - au_writel(0, UART0_ADDR + UART_CLK); -#endif - au_writel(0, UART1_ADDR + UART_CLK); - au_writel(0, UART3_ADDR + UART_CLK); - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); - au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); - au_writel(0, SYS_TOYTRIM); - - au_writel(0x00000060, 0xb190003c); - -#ifdef CONFIG_RTC - rtc_ops = &pb1500_rtc_ops; - // Enable the RTC if not already enabled - if (!(readb(0xac000028) & 0x20)) { - writeb(readb(0xac000028) | 0x20, 0xac000028); - au_sync(); - } - // Put the clock in BCD mode - if (readb(0xac00002C) & 0x4) { /* reg B */ - writeb(readb(0xac00002c) & ~0x4, 0xac00002c); - au_sync(); - } -#endif -} diff -urN linux-2.4.21/arch/mips/au1000/pb1500/Makefile linux-2.4.22/arch/mips/au1000/pb1500/Makefile --- linux-2.4.21/arch/mips/au1000/pb1500/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1500/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -14,8 +14,6 @@ O_TARGET := pb1500.o -obj-y := init.o setup.o - -obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o +obj-y := init.o board_setup.o irqmap.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/au1000/pb1500/board_setup.c linux-2.4.22/arch/mips/au1000/pb1500/board_setup.c --- linux-2.4.21/arch/mips/au1000/pb1500/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1500/board_setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,151 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1500 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#ifdef CONFIG_RTC +extern struct rtc_ops pb1500_rtc_ops; +#endif + +void __init board_setup(void) +{ + u32 pin_func; + u32 sys_freqctrl, sys_clksrc; + + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PINSTATERD); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + /* GPIO201 is input for PCMCIA card detect */ + /* GPIO203 is input for PCMCIA interrupt request */ + au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ +#ifdef CONFIG_USB_OHCI + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); +#endif + au_writel(sys_clksrc, SYS_CLKSRC); + + + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + + +#ifdef CONFIG_PCI + // Setup PCI bus controller + au_writel(0, Au1500_PCI_CMEM); + au_writel(0x00003fff, Au1500_CFG_BASE); +#if defined(__MIPSEB__) + au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); +#else + au_writel(0xf, Au1500_PCI_CFG); +#endif + au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); + au_writel(0, Au1500_PCI_MWBASE_REV_CCL); + au_writel(0x02a00356, Au1500_PCI_STATCMD); + au_writel(0x00003c04, Au1500_PCI_HDRTYPE); + au_writel(0x00000008, Au1500_PCI_MBAR); + au_sync(); +#endif + + /* Enable BCLK switching */ + au_writel(0x00000060, 0xb190003c); + +#ifdef CONFIG_RTC + rtc_ops = &pb1500_rtc_ops; + // Enable the RTC if not already enabled + if (!(au_readl(0xac000028) & 0x20)) { + printk("enabling clock ...\n"); + au_writel((au_readl(0xac000028) | 0x20), 0xac000028); + } + // Put the clock in BCD mode + if (readl(0xac00002C) & 0x4) { /* reg B */ + au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); + au_sync(); + } +#endif +} diff -urN linux-2.4.21/arch/mips/au1000/pb1500/irqmap.c linux-2.4.22/arch/mips/au1000/pb1500/irqmap.c --- linux-2.4.21/arch/mips/au1000/pb1500/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1500/irqmap.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,100 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21/arch/mips/au1000/pb1500/pci_fixup.c linux-2.4.22/arch/mips/au1000/pb1500/pci_fixup.c --- linux-2.4.21/arch/mips/au1000/pb1500/pci_fixup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1500/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,119 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Board specific pci fixups. - * - * Copyright 2001,2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -static void fixup_resource(int r_num, struct pci_dev *dev) ; -static unsigned long virt_io_addr; - -void __init pcibios_fixup_resources(struct pci_dev *dev) -{ - /* will need to fixup IO resources */ -} - -void __init pcibios_fixup(void) -{ - int i; - struct pci_dev *dev; - - virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, - Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1); - - if (!virt_io_addr) { - printk(KERN_ERR "Unable to ioremap pci space\n"); - return; - } - - pci_for_each_dev(dev) { - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start) { - fixup_resource(i, dev); - } - } - } -} - -void __init pcibios_fixup_irqs(void) -{ - unsigned int slot, func; - unsigned char pin; - struct pci_dev *dev; - - pci_for_each_dev(dev) { - if (dev->bus->number != 0) - return; - - dev->irq = 0xff; - slot = PCI_SLOT(dev->devfn); - switch (slot) { - case 12: - case 13: - dev->irq = AU1000_PCI_INTA; - break; - - } - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - DBG("slot %d irq %d\n", slot, dev->irq); - } -} -unsigned int pcibios_assign_all_busses(void) -{ - return 0; -} - -static void fixup_resource(int r_num, struct pci_dev *dev) -{ - unsigned long start, size, new_start; - - if (dev->resource[r_num].flags & IORESOURCE_IO) { - start = dev->resource[r_num].start; - size = dev->resource[r_num].end - start; - new_start = virt_io_addr + (start - Au1500_PCI_IO_START); - dev->resource[r_num].start = new_start; - dev->resource[r_num].end = new_start + size; - } -} - -#endif diff -urN linux-2.4.21/arch/mips/au1000/pb1500/pci_ops.c linux-2.4.22/arch/mips/au1000/pb1500/pci_ops.c --- linux-2.4.21/arch/mips/au1000/pb1500/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1500/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,241 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Pb1500 specific pci support. - * - * Copyright 2001,2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* TBD */ -static struct resource pci_io_resource = { - "pci IO space", - Au1500_PCI_IO_START, - Au1500_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource pci_mem_resource = { - "pci memory space", - Au1500_PCI_MEM_START, - Au1500_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops pb1500_pci_ops; - -struct pci_channel mips_pci_channels[] = { - {&pb1500_pci_ops, &pci_io_resource, &pci_mem_resource, (10<<3),(16<<3)}, - {(struct pci_ops *) NULL, (struct resource *) NULL, - (struct resource *) NULL, (int) NULL, (int) NULL} -}; - -static unsigned long cfg_addr; -static int config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 * data) -{ - unsigned char bus = dev->bus->number; - unsigned int dev_fn = dev->devfn; - unsigned int device, function; - unsigned long config, status; - static int first = 1; - - /* - * 7:3 = slot - * 2:0 = function - */ - - if (bus != 0) { - *data = 0xffffffff; - return -1; - } - - if (first) { - first = 0; - cfg_addr = ioremap(Au1500_EXT_CFG, 0x10000000); - if (!cfg_addr) - printk (KERN_ERR "PCI unable to ioremap cfg space\n"); - } - - device = (dev_fn >> 3) & 0x1f; - function = dev_fn & 0x7; - -#if 1 - //if (!cfg_addr || (device < 10) || (device > 16)) { - if (!cfg_addr || (device > 16)) { - *data = 0xffffffff; - return -1; - } -#endif - - au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)), - Au1500_PCI_STATCMD); - //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG); - au_sync_udelay(1); - - /* setup the lower 31 bits of the 36 bit address */ - config = cfg_addr | - ((1<> 28) & 0xf) { - DBG("PCI ERR detected: status %x\n", status); - *data = 0xffffffff; - return -1; - } - else { - return PCIBIOS_SUCCESSFUL; - } -} - - -static int read_config_byte(struct pci_dev *dev, int where, u8 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - if (where & 1) data >>= 8; - if (where & 2) data >>= 16; - *val = data & 0xff; - return ret; -} - - -static int read_config_word(struct pci_dev *dev, int where, u16 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - if (where & 2) data >>= 16; - *val = data & 0xffff; - return ret; -} - -static int read_config_dword(struct pci_dev *dev, int where, u32 * val) -{ - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, val); - return ret; -} - - -static int write_config_byte(struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_word(struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops pb1500_pci_ops = { - read_config_byte, - read_config_word, - read_config_dword, - write_config_byte, - write_config_word, - write_config_dword -}; -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/au1000/pb1500/setup.c linux-2.4.22/arch/mips/au1000/pb1500/setup.c --- linux-2.4.21/arch/mips/au1000/pb1500/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/pb1500/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,261 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Alchemy Pb1000 board setup. - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_USB_OHCI -// Enable the workaround for the OHCI DoneHead -// register corruption problem. -#define CONFIG_AU1000_OHCI_FIX -#endif - -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_BLK_DEV_INITRD -extern unsigned long initrd_start, initrd_end; -extern void * __rd_start, * __rd_end; -#endif - -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -extern struct ide_ops *ide_ops; -#endif - -#ifdef CONFIG_RTC -extern struct rtc_ops pb1500_rtc_ops; -#endif - -extern char * __init prom_getcmdline(void); -extern void au1000_restart(char *); -extern void au1000_halt(void); -extern void au1000_power_off(void); -extern struct resource ioport_resource; -extern struct resource iomem_resource; - - -void __init bus_error_init(void) { /* nothing */ } - -void __init au1500_setup(void) -{ - char *argptr; - u32 pin_func, static_cfg0; - u32 sys_freqctrl, sys_clksrc; - - argptr = prom_getcmdline(); - - /* NOTE: The memory map is established by YAMON 2.08+ */ - - /* Various early Au1500 Errata corrected by this */ - set_cp0_config(1<<19); /* Config[OD] */ - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if ((argptr = strstr(argptr, "console=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " console=ttyS0,115200"); - } -#endif - -#ifdef CONFIG_SOUND_AU1000 - strcat(argptr, " au1000_audio=vra"); - argptr = prom_getcmdline(); -#endif - - _machine_restart = au1000_restart; - _machine_halt = au1000_halt; - _machine_power_off = au1000_power_off; - - // IO/MEM resources. - set_io_port_base(0); - ioport_resource.start = 0x10000000; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x10000000; - iomem_resource.end = 0xffffffff; - -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); - initrd_start = (unsigned long)&__rd_start; - initrd_end = (unsigned long)&__rd_end; -#endif - - // set AUX clock to 12MHz * 8 = 96 MHz - au_writel(8, SYS_AUXPLL); - au_writel(0, SYS_PINSTATERD); - udelay(100); - -#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) -#ifdef CONFIG_USB_OHCI - if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { - char usb_args[80]; - argptr = prom_getcmdline(); - memset(usb_args, 0, sizeof(usb_args)); - sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", - USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); - strcat(argptr, usb_args); - } -#endif - - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD clocks */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* - * Route 48MHz FREQ2 into USB Host and/or Device - */ -#ifdef CONFIG_USB_OHCI - sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); -#endif -#ifdef CONFIG_AU1000_USB_DEVICE - sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); -#endif - au_writel(sys_clksrc, SYS_CLKSRC); - - - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); -#ifndef CONFIG_AU1000_USB_DEVICE - // 2nd USB port is USB host - pin_func |= 0x8000; -#endif - au_writel(pin_func, SYS_PINFUNC); -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) - - -#ifdef CONFIG_USB_OHCI - // enable host controller and wait for reset done - au_writel(0x08, USB_HOST_CONFIG); - udelay(1000); - au_writel(0x0c, USB_HOST_CONFIG); - udelay(1000); - au_readl(USB_HOST_CONFIG); - while (!(au_readl(USB_HOST_CONFIG) & 0x10)) - ; - au_readl(USB_HOST_CONFIG); -#endif - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - -#ifdef CONFIG_FB_E1356 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=e1356fb:system:pb1500"); - } -#elif defined (CONFIG_FB_XPERT98) - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=atyfb:1024x768-8@70"); - } -#endif // CONFIG_FB_E1356 - -#ifndef CONFIG_SERIAL_NONSTANDARD - /* don't touch the default serial console */ - au_writel(0, UART0_ADDR + UART_CLK); -#endif - au_writel(0, UART3_ADDR + UART_CLK); - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - -#ifdef CONFIG_PCI - // Setup PCI bus controller - au_writel(0, Au1500_PCI_CMEM); - au_writel(0x00003fff, Au1500_CFG_BASE); -#if defined(__MIPSEB__) - au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); -#else - au_writel(0xf, Au1500_PCI_CFG); -#endif - au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); - au_writel(0, Au1500_PCI_MWBASE_REV_CCL); - au_writel(0x02a00356, Au1500_PCI_STATCMD); - au_writel(0x00003c04, Au1500_PCI_HDRTYPE); - au_writel(0x00000008, Au1500_PCI_MBAR); - au_sync(); -#endif - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); - au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); - au_writel(0, SYS_TOYTRIM); - - /* Enable BCLK switching */ - au_writel(0x00000060, 0xb190003c); - -#ifdef CONFIG_RTC - rtc_ops = &pb1500_rtc_ops; - // Enable the RTC if not already enabled - if (!(au_readl(0xac000028) & 0x20)) { - printk("enabling clock ...\n"); - au_writel((au_readl(0xac000028) | 0x20), 0xac000028); - } - // Put the clock in BCD mode - if (readl(0xac00002C) & 0x4) { /* reg B */ - au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); - au_sync(); - } -#endif -} diff -urN linux-2.4.21/arch/mips/au1000/xxs1500/Makefile linux-2.4.22/arch/mips/au1000/xxs1500/Makefile --- linux-2.4.21/arch/mips/au1000/xxs1500/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/xxs1500/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,22 @@ +# +# Copyright 2003 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for MyCable XXS1500 board. +# +# 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). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := xxs1500.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/au1000/xxs1500/board_setup.c linux-2.4.22/arch/mips/au1000/xxs1500/board_setup.c --- linux-2.4.21/arch/mips/au1000/xxs1500/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/xxs1500/board_setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,94 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * MyCable XXS1500 board setup. + * + * Copyright 2000-2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +void __init board_setup(void) +{ + u32 pin_func; + + rtc_ops = &no_rtc_ops; + + // set multiple use pins (UART3/GPIO) to UART (it's used as UART too) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~SYS_PF_UR3); + pin_func |= SYS_PF_UR3; + au_writel(pin_func, SYS_PINFUNC); + + // enable UART + au_writel(0x01, UART3_ADDR+UART_MOD_CNTRL); // clock enable (CE) + mdelay(10); + au_writel(0x03, UART3_ADDR+UART_MOD_CNTRL); // CE and "enable" + mdelay(10); + + // enable DTR = USB power up + au_writel(0x01, UART3_ADDR+UART_MCR); //? UART_MCR_DTR is 0x01??? + +#ifdef CONFIG_PCMCIA_XXS1500 + /* setup pcmcia signals */ + au_writel(0, SYS_PININPUTEN); + + /* gpio 0, 1, and 4 are inputs */ + au_writel(1 | (1<<1) | (1<<4), SYS_TRIOUTCLR); + + /* enable GPIO2 if not already enabled */ + au_writel(1, GPIO2_ENABLE); + /* gpio2 208/9/10/11 are inputs */ + au_writel((1<<8) | (1<<9) | (1<<10) | (1<<11), GPIO2_DIR); + + /* turn off power */ + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), GPIO2_OUTPUT); +#endif + + +#ifdef CONFIG_PCI +#if defined(__MIPSEB__) + au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); +#else + au_writel(0xf, Au1500_PCI_CFG); +#endif +#endif +} diff -urN linux-2.4.21/arch/mips/au1000/xxs1500/init.c linux-2.4.22/arch/mips/au1000/xxs1500/init.c --- linux-2.4.21/arch/mips/au1000/xxs1500/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/xxs1500/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * XXS1500 board setup + * + * Copyright 2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "XXS1500"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_XXS1500; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.21/arch/mips/au1000/xxs1500/irqmap.c linux-2.4.22/arch/mips/au1000/xxs1500/irqmap.c --- linux-2.4.21/arch/mips/au1000/xxs1500/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/au1000/xxs1500/irqmap.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,106 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* CF interrupt */ + { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21/arch/mips/baget/Makefile linux-2.4.22/arch/mips/baget/Makefile --- linux-2.4.21/arch/mips/baget/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -8,14 +8,13 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -all: baget.a +all: baget.a O_TARGET := baget.a -export-objs := vacserial.o vacrtc.o +export-objs := vacrtc.o obj-y := baget.o print.o setup.o time.o irq.o bagetIRQ.o \ - reset.o wbflush.o -obj-$(CONFIG_SERIAL) += vacserial.o + reset.o obj-$(CONFIG_VAC_RTC) += vacrtc.o bagetIRQ.o : bagetIRQ.S @@ -39,7 +38,7 @@ dummy.o: dummy.c image.bin ramdisk.bin $(CC) $(CFLAGS) -c -o $@ $< $(OBJCOPY) --add-section=.vmlinux=image.bin \ - --add-section=.ramdisk=ramdisk.bin $@ + --add-section=.ramdisk=ramdisk.bin $@ balo.h: image $(NM) $< | awk ' \ @@ -50,13 +49,13 @@ /balo_ramdisk_size/ { printf "#define RAMDISK_SIZE 0x%s\n", $$1 } \ ' > $@ balo.o: balo.c balo.h - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< balo_supp.o: balo_supp.S $(CC) $(CFLAGS) -c $< balo: balo.o dummy.o balo_supp.o print.o - $(LD) $(LDFLAGS) -T ld.script.balo -o $@ $^ + $(LD) $(LDFLAGS) -T ld.script.balo -o $@ $^ clean: rm -f balo balo.h dummy.c image image.bin diff -urN linux-2.4.21/arch/mips/baget/baget.c linux-2.4.22/arch/mips/baget/baget.c --- linux-2.4.21/arch/mips/baget/baget.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/baget.c 2003-08-25 04:44:39.000000000 -0700 @@ -20,7 +20,7 @@ * Following code is based on routines from 'mm/vmalloc.c' * Additional parameters ioaddr is needed to iterate across real I/O address. */ -static inline int alloc_area_pte(pte_t * pte, unsigned long address, +static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size, unsigned long ioaddr) { unsigned long end; @@ -35,7 +35,7 @@ printk("kseg2_alloc_io: page already exists\n"); /* * For MIPS looks pretty to have transparent mapping - * for KSEG2 areas -- user can't access one, and no + * for KSEG2 areas -- user can't access one, and no * problems with virtual <--> physical translation. */ page = ioaddr & PAGE_MASK; @@ -49,7 +49,7 @@ return 0; } -static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, +static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, unsigned long ioaddr) { unsigned long end; diff -urN linux-2.4.21/arch/mips/baget/bagetIRQ.S linux-2.4.22/arch/mips/baget/bagetIRQ.S --- linux-2.4.21/arch/mips/baget/bagetIRQ.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/bagetIRQ.S 2003-08-25 04:44:39.000000000 -0700 @@ -24,28 +24,28 @@ .set push .set noreorder jal a1 - .set pop - move a0, sp + .set pop + move a0, sp la a1, ret_from_irq jr a1 END(bagetIRQ) - + #define DBE_HANDLER 0x1C - + NESTED(try_read, PT_SIZE, sp) mfc0 t3, CP0_STATUS # save flags and CLI # disable interrupts li t0, KSEG2 - sltu t1, t0, a0 # Is it KSEG2 address ? - beqz t1, mapped # No - already mapped ! - - move t0, a0 + sltu t1, t0, a0 # Is it KSEG2 address ? + beqz t1, mapped # No - already mapped ! + + move t0, a0 ori t0, 0xfff xori t0, 0xfff # round address to page - ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G) + ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G) mfc0 t2, CP0_ENTRYHI # save ASID value mtc0 zero, CP0_INDEX @@ -56,15 +56,15 @@ tlbwi # ... and write ones nop nop - mtc0 t2, CP0_ENTRYHI - -mapped: + mtc0 t2, CP0_ENTRYHI + +mapped: la t0, exception_handlers lw t1, DBE_HANDLER(t0) # save real handler - la t2, dbe_handler + la t2, dbe_handler sw t2, DBE_HANDLER(t0) # set temporary local handler li v0, -1 # default (failure) value - + li t2, 1 beq t2, a1, 1f li t2, 2 @@ -80,13 +80,13 @@ b out 4: lw v0, (a0) # word - -out: + +out: sw t1, DBE_HANDLER(t0) # restore real handler mtc0 t3, CP0_STATUS # restore CPU flags - jr ra - -dbe_handler: + jr ra + +dbe_handler: li v0, -1 # mark our failure .set push .set noreorder diff -urN linux-2.4.21/arch/mips/baget/balo.c linux-2.4.22/arch/mips/baget/balo.c --- linux-2.4.21/arch/mips/baget/balo.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/balo.c 2003-08-25 04:44:39.000000000 -0700 @@ -16,7 +16,7 @@ static void mem_move (long *to, long *from, long size) { - while (size > 0) { + while (size > 0) { *to++ = *from++; size -= sizeof(long); } @@ -59,7 +59,7 @@ "jr\t%1\n\t" "nop\n\t" ".set\tat\n\t" - ".set\treorder" + ".set\treorder" : "=&r" (tmp) : "Ir" (start), "Ir" (mem_upper) : "memory"); @@ -71,7 +71,7 @@ extern char _ramdisk_start, _ramdisk_end; outs( "Relocating Linux... " ); - mem_move((long*)KSEG0, (long*)&_vmlinux_start, + mem_move((long*)KSEG0, (long*)&_vmlinux_start, &_vmlinux_end-&_vmlinux_start); outs("done.\n"); @@ -86,7 +86,7 @@ outs("done.\n"); } - { + { extern void flush_cache_low(int isize, int dsize); flush_cache_low(256*1024,256*1024); } @@ -102,10 +102,10 @@ balo_state = MEM_PROBE; outs("RAM: <"); while(mem_limit < mem_limit_dbe) { - if (can_write(mem_limit) && *mem_limit != 0) + if (can_write(mem_limit) && *mem_limit != 0) break; /* cycle found */ outc('.'); - if (can_write(mem_limit)) + if (can_write(mem_limit)) *mem_limit = -1; /* mark */ mem_limit += 0x40000; } @@ -124,7 +124,7 @@ } void int_handler(struct pt_regs *regs) -{ +{ switch (balo_state) { case BALO_INIT: balo_printf("\nBALO: trap in balo itself.\n"); @@ -162,7 +162,7 @@ while(1) { *mem_limit_dbe; - if (can_write(mem_limit_dbe)) + if (can_write(mem_limit_dbe)) *mem_limit_dbe = 0; mem_limit_dbe += 0x40000; /* +1M */ @@ -174,7 +174,7 @@ { extern void except_vec3_generic(void); - cli(); + cli(); outs(banner); memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); mem_init(); diff -urN linux-2.4.21/arch/mips/baget/balo_supp.S linux-2.4.22/arch/mips/baget/balo_supp.S --- linux-2.4.21/arch/mips/baget/balo_supp.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/balo_supp.S 2003-08-25 04:44:39.000000000 -0700 @@ -8,10 +8,10 @@ #include #include #include - + .text .set mips1 - + /* General exception vector. */ NESTED(except_vec3_generic, 0, sp) .set noat @@ -20,7 +20,7 @@ END(except_vec3_generic) NESTED(except_vec3_generic_code, 0, sp) - SAVE_ALL + SAVE_ALL mfc0 k1, CP0_CAUSE la k0, int_cause sw k1, (k0) @@ -33,7 +33,7 @@ la k0, badvaddr sw k1, (k0) - la k0, int_handler + la k0, int_handler .set noreorder jal k0 .set reorder @@ -47,7 +47,7 @@ .set at .set macro .set noreorder - + move t1, a0 # ISIZE move t2, a1 # DSIZE @@ -88,7 +88,7 @@ sb zero, -8(t0) bne t0, t1, 1b sb zero, -4(t0) - + la v0, 1f or v0, KSEG1 j v0 # Run uncached diff -urN linux-2.4.21/arch/mips/baget/irq.c linux-2.4.22/arch/mips/baget/irq.c --- linux-2.4.21/arch/mips/baget/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -32,19 +32,19 @@ /* * This table is a correspondence between IRQ numbers and CPU PILs */ - -static int irq_to_pil_map[BAGET_IRQ_NR] = { + +static int irq_to_pil_map[BAGET_IRQ_NR] = { 7/*fixme: dma_err -1*/,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x00 - 0x0f */ -1,-1,-1,-1, 3,-1,-1,-1, 2, 2, 2,-1, 3,-1,-1,3/*fixme: lance*/, /* 0x10 - 0x1f */ -1,-1,-1,-1,-1,-1, 5,-1,-1,-1,-1,-1, 7,-1,-1,-1, /* 0x20 - 0x2f */ -1, 3, 2/*fixme systimer:3*/, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 /* 0x30 - 0x3f */ }; -static inline int irq_to_pil(int irq_nr) +static inline int irq_to_pil(int irq_nr) { int pil = -1; - if (irq_nr >= BAGET_IRQ_NR) + if (irq_nr >= BAGET_IRQ_NR) baget_printk("irq_to_pil: too large irq_nr = 0x%x\n", irq_nr); else { pil = irq_to_pil_map[irq_nr]; @@ -59,13 +59,13 @@ static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) { - unsigned long status = read_32bit_cp0_register(CP0_STATUS); + unsigned long status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); } -/* +/* * These two functions may be used for unconditional IRQ * masking via their PIL protection. */ @@ -91,22 +91,22 @@ static volatile unsigned int pil_in_use[BAGET_PIL_NR] = { 0, }; -void mask_irq_count(int irq_nr) +void mask_irq_count(int irq_nr) { unsigned long flags; int pil = irq_to_pil(irq_nr); - + save_and_cli(flags); if (!--pil_in_use[pil]) mask_irq(irq_nr); restore_flags(flags); } -void unmask_irq_count(int irq_nr) +void unmask_irq_count(int irq_nr) { unsigned long flags; int pil = irq_to_pil(irq_nr); - + save_and_cli(flags); if (!pil_in_use[pil]++) unmask_irq(irq_nr); @@ -148,7 +148,7 @@ for (i = 0 ; i < BAGET_IRQ_NR ; i++) { action = irq_action[i]; - if (!action) + if (!action) continue; len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.irqs[0][i], @@ -181,7 +181,7 @@ irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; - mask_irq(irq); + mask_irq(irq); action = *(irq + irq_action); if (action) { if (!(action->flags & SA_INTERRUPT)) @@ -208,14 +208,14 @@ /* * What to do in case of 'no VIC register available' for current interrupt */ -static void vic_reg_error(unsigned long address, unsigned char active_pils) +static void vic_reg_error(unsigned long address, unsigned char active_pils) { printk("\nNo VIC register found: reg=%08lx active_pils=%02x\n" - "Current interrupt mask from CP0_CAUSE: %02x\n", - address, 0xff & active_pils, - 0xff & (read_32bit_cp0_register(CP0_CAUSE)>>8)); + "Current interrupt mask from CP0_CAUSE: %02x\n", + address, 0xff & active_pils, + 0xff & (read_c0_cause()>>8)); { int i; for (i=0; i<10000; i++) udelay(1000); } -} +} static char baget_fpu_irq = BAGET_FPU_IRQ; #define BAGET_INT_FPU {(unsigned long)&baget_fpu_irq, 1} @@ -225,27 +225,27 @@ */ asmlinkage void baget_interrupt(struct pt_regs *regs) { - static struct baget_int_reg int_reg[BAGET_PIL_NR] = { + static struct baget_int_reg int_reg[BAGET_PIL_NR] = { BAGET_INT_NONE, BAGET_INT_NONE, BAGET_INT0_ACK, BAGET_INT1_ACK, - BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK + BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK }; unsigned char active_pils; - while ((active_pils = read_32bit_cp0_register(CP0_CAUSE)>>8)) { + while ((active_pils = read_c0_cause()>>8)) { int pil; struct baget_int_reg* reg; for (pil = 0; pil < BAGET_PIL_NR; pil++) { if (!(active_pils & (1<address) { extern int try_read(unsigned long,int); int irq = try_read(reg->address, reg->size); - if (irq != -1) + if (irq != -1) do_IRQ(BAGET_IRQ_MASK(irq), regs); - else + else vic_reg_error(reg->address, active_pils); } else { printk("baget_interrupt: unknown interrupt " @@ -297,9 +297,9 @@ return 0; } -int request_irq(unsigned int irq, +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, + unsigned long irqflags, const char * devname, void *dev_id) { @@ -310,12 +310,12 @@ return -EINVAL; if (!handler) return -EINVAL; - if (irq_to_pil_map[irq] < 0) + if (irq_to_pil_map[irq] < 0) return -EINVAL; action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) + if (!action) return -ENOMEM; action->handler = handler; @@ -332,13 +332,13 @@ return retval; } - + void free_irq(unsigned int irq, void *dev_id) { struct irqaction * action, **p; unsigned long flags; - if (irq >= BAGET_IRQ_NR) + if (irq >= BAGET_IRQ_NR) printk("Trying to free IRQ%d\n",irq); for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { @@ -375,7 +375,7 @@ *(volatile char*) BAGET_WRERR_ACK = 0; } -static struct irqaction irq0 = +static struct irqaction irq0 = { write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL}; void __init init_IRQ(void) @@ -388,6 +388,6 @@ /* Enable interrupts for pils 2 and 3 (lines 0 and 1) */ modify_cp0_intmask(0, (1<<2)|(1<<3)); - if (setup_baget_irq(0, &irq0) < 0) + if (setup_baget_irq(0, &irq0) < 0) printk("init_IRQ: unable to register write_err irq\n"); } diff -urN linux-2.4.21/arch/mips/baget/ld.script.balo linux-2.4.22/arch/mips/baget/ld.script.balo --- linux-2.4.21/arch/mips/baget/ld.script.balo 2001-07-02 14:40:14.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/ld.script.balo 2003-08-25 04:44:39.000000000 -0700 @@ -1,4 +1,4 @@ -OUTPUT_FORMAT("elf32-bigmips") +OUTPUT_FORMAT("elf32-tradbigmips") OUTPUT_ARCH(mips) ENTRY(balo_entry) SECTIONS @@ -42,13 +42,13 @@ /* Startup code */ . = ALIGN(4096); __init_begin = .; - *(.text.init) - *(.data.init) + *(.text.init) + *(.data.init) . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - *(.fini) - *(.reginfo) + *(.fini) + *(.reginfo) /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. It would be more correct to do this: @@ -68,18 +68,18 @@ *(.data) CONSTRUCTORS - *(.data1) + *(.data1) _gp = . + 0x8000; - *(.lit8) - *(.lit4) - *(.ctors) - *(.dtors) - *(.got.plt) *(.got) - *(.dynamic) + *(.lit8) + *(.lit4) + *(.ctors) + *(.dtors) + *(.got.plt) *(.got) + *(.dynamic) /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ - *(.sdata) + *(.sdata) _edata = .; PROVIDE (edata = .); @@ -96,21 +96,21 @@ /* These are needed for ELF backends which have not yet been converted to the new style linker. */ - *(.stab) - *(.stabstr) + *(.stab) + *(.stabstr) /* DWARF debug sections. Symbols in the .debug DWARF section are relative to the beginning of the section so we begin .debug at 0. It's not clear yet what needs to happen for the others. */ - *(.debug) - *(.debug_srcinfo) - *(.debug_aranges) - *(.debug_pubnames) - *(.debug_sfnames) - *(.line) + *(.debug) + *(.debug_srcinfo) + *(.debug_aranges) + *(.debug_pubnames) + *(.debug_sfnames) + *(.line) /* These must appear regardless of . */ - *(.gptab.data) *(.gptab.sdata) - *(.gptab.bss) *(.gptab.sbss) + *(.gptab.data) *(.gptab.sdata) + *(.gptab.bss) *(.gptab.sbss) _vmlinux_start = .; *(.vmlinux) diff -urN linux-2.4.21/arch/mips/baget/print.c linux-2.4.22/arch/mips/baget/print.c --- linux-2.4.21/arch/mips/baget/print.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/print.c 2003-08-25 04:44:39.000000000 -0700 @@ -14,7 +14,7 @@ */ // #define BAGET_PRINTK -/* +/* * This function is same for BALO and Linux baget_printk, * and normally prints characted to second (UART A) console. */ @@ -25,7 +25,7 @@ { int i; vac_outb(c, VAC_UART_B_TX); - for (i=0; i<10000; i++) + for (i=0; i<10000; i++) delay(); } @@ -36,7 +36,7 @@ outc_low(c); } -void outs(char *s) +void outs(char *s) { while(*s) outc(*s++); } @@ -77,7 +77,7 @@ void __init balo_printf( char *f, ... ) { int *arg = (int*)&f + 1; - char c; + char c; int format = 0; while((c = *f++) != 0) { @@ -110,7 +110,7 @@ } void __init balo_hungup(void) -{ +{ outs("Hunging up.\n"); - while(1); + while(1); } diff -urN linux-2.4.21/arch/mips/baget/prom/init.c linux-2.4.22/arch/mips/baget/prom/init.c --- linux-2.4.21/arch/mips/baget/prom/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/prom/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,7 +1,7 @@ /* * init.c: PROM library initialisation code. * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ #include #include diff -urN linux-2.4.21/arch/mips/baget/setup.c linux-2.4.22/arch/mips/baget/setup.c --- linux-2.4.21/arch/mips/baget/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -15,10 +15,10 @@ long int vac_memory_upper; #define CACHEABLE_STR(val) ((val) ? "not cached" : "cached") -#define MIN(a,b) (((a)<(b)) ? (a):(b)) - +#define MIN(a,b) (((a)<(b)) ? (a):(b)) + static void __init vac_show(void) -{ +{ int i; unsigned short val, decode = vac_inw(VAC_DECODE_CTRL); unsigned short a24_base = vac_inw(VAC_A24_BASE); @@ -37,7 +37,7 @@ VAC_IOSEL3_CTRL, VAC_IOSEL4_CTRL, VAC_IOSEL5_CTRL }; - + printk("[DSACKi %s, DRAMCS%s qualified, boundary%s qualified%s]\n", (decode & VAC_DECODE_DSACKI) ? "on" : "off", (decode & VAC_DECODE_QFY_DRAMCS) ? "" : " not", @@ -71,24 +71,24 @@ VAC_ICFSEL_MODULE_VAL(vac_inw(VAC_ICFSEL_BASE)))<<4, (decode & VAC_DECODE_QFY_ICFSEL) ? "qualified" : ""); - + printk("region0 at 00000000 (%dMB)\t[dram, %s, delay %d cpuclk" ", cached]\n", (vac_inw(VAC_DRAM_MASK)+1)>>4, (decode & VAC_DECODE_DSACK) ? "D32" : "3state", VAC_DECODE_CPUCLK_VAL(decode)); - + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) { - unsigned long from = + unsigned long from = ((unsigned long)vac_inw(bndr[i]))<<16; - unsigned long to = + unsigned long to = ((unsigned long) - ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ? + ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ? 0xff00 : vac_inw(bndr[i+1])))<<16; - - + + val = vac_inw(regs[i]); - printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n", + printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n", i+1, from, (unsigned int)((to - from) >> 20), @@ -96,13 +96,13 @@ asiz[VAC_REG_ASIZ_VAL(val)], ((val & VAC_REG_WORD) ? "D16" : "D32"), CACHEABLE_STR(val&VAC_A24_A24_CACHINH)); - + if (a24_addr >= from && a24_addr < to) printk("\ta24 at %08lx (%dMB)\t[vme, A24/%s, %s]\n", a24_addr, MIN((unsigned int)(a24_addr - from)>>20, 32), (a24_base & VAC_A24_DATAPATH) ? "user" : - ((a24_base & VAC_A24_D32_ENABLE) ? + ((a24_base & VAC_A24_D32_ENABLE) ? "D32" : "D16"), CACHEABLE_STR(a24_base & VAC_A24_A24_CACHINH)); } @@ -122,7 +122,7 @@ (VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "", VAC_CTRL_DELAY_IOSELI_VAL(val)/2, (VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : ""); - + printk("region5 at fff00000 (896KB)\t[local io, %s]\n", CACHEABLE_STR(vac_inw(VAC_A24_BASE) & VAC_A24_IO_CACHINH)); @@ -131,7 +131,7 @@ printk("\tio%d[ack %d cpuclk%s, %s%srecovery %d cpuclk, " "\n\t read %d%s cpuclk, write %d%s cpuclk, " "assert %d%s%s cpuclk]\n", - i, + i, VAC_CTRL_DELAY_DSACKI_VAL(val), state[val & (VAC_CTRL_IORD|VAC_CTRL_IOWR)], (val & VAC_CTRL_DSACK0) ? "dsack0*, " : "", @@ -143,15 +143,15 @@ (VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "", VAC_CTRL_DELAY_IOSELI_VAL(val)/2, (VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : "", - (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ? + (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ? ", id" : ""); } - + printk("region6 at fffe0000 (128KB)\t[vme, A16/%s, " "not cached]\n", - (a24_base & VAC_A24_A16D32_ENABLE) ? + (a24_base & VAC_A24_A16D32_ENABLE) ? ((a24_base & VAC_A24_A16D32) ? "D32" : "D16") : "user"); - + val = vac_inw(VAC_SHRCS_CTRL); printk("shared[ack %d cpuclk%s, %s%srecovery %d cpuclk, " "read %d%s, write %d%s, assert %d%s]\n", @@ -182,8 +182,8 @@ default: panic("Unknown VAC revision number"); } - - vac_outw(mem_limit-1, VAC_DRAM_MASK); + + vac_outw(mem_limit-1, VAC_DRAM_MASK); vac_outw(mem_limit, VAC_BNDR2); vac_outw(mem_limit, VAC_BNDR3); vac_outw(((BAGET_A24M_BASE>>16)&~VAC_A24_D32_ENABLE)|VAC_A24_DATAPATH, @@ -293,19 +293,19 @@ vac_outw(VAC_INT_CTRL_TIMER_PIO10| VAC_INT_CTRL_UART_B_PIO7| VAC_INT_CTRL_UART_A_PIO7,VAC_INT_CTRL); - /* + /* * Set quadro speed for both UARTs. * To do it we need use formulae from VIC/VAC manual, * keeping in mind Baget's 50MHz frequency... */ - vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV); + vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV); } static void __init vic_show(void) { unsigned char val; char *timeout[] = { "4", "16", "32", "64", "128", "256", "disabled" }; - char *deadlock[] = { "[dedlk only]", "[dedlk only]", + char *deadlock[] = { "[dedlk only]", "[dedlk only]", "[dedlk], [halt w/ rmc], [lberr]", "[dedlk], [halt w/o rmc], [lberr]" }; @@ -318,7 +318,7 @@ printk("metastability delay "); printk("%s ", deadlock[VIC_IFACE_CFG_DEADLOCK_VAL(val)]); - + printk("interrupts: "); val = vic_inb(VIC_ERR_INT); @@ -331,7 +331,7 @@ if (!(val & VIC_ERR_INT_ACFAIL)) printk("[acfail] "); printk("\n"); - + printk("timeouts: "); val = vic_inb(VIC_XFER_TIMO); printk("local %s, vme %s ", @@ -357,7 +357,7 @@ printk("[local boundary cross]"); if (val & VIC_BXFER_DEF_VME_CROSS) printk("[vme boundary cross]"); - + } static void __init vic_init(void) @@ -372,7 +372,7 @@ vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT2); vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT3); vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT4); -/* +/* vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT5); */ vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT6); @@ -387,7 +387,7 @@ VIC_INT_HIGH|VIC_INT_DISABLE, VIC_LINT3); vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_EDGE| VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT4); -/* +/* vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_LEVEL| VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT5); */ @@ -446,7 +446,7 @@ VIC_RELEASE_RWD, VIC_RELEASE); vic_outb(VIC_IC6_RUN, VIC_IC6); vic_outb(0, VIC_IC7); - + vic_show(); } @@ -470,7 +470,7 @@ extern void baget_machine_restart(char *command); extern void baget_machine_halt(void); extern void baget_machine_power_off(void); - + void __init baget_setup(void) { printk("BT23/63-201n found.\n"); diff -urN linux-2.4.21/arch/mips/baget/time.c linux-2.4.22/arch/mips/baget/time.c --- linux-2.4.21/arch/mips/baget/time.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -19,25 +19,25 @@ #include #include #include -#include +#include #include extern rwlock_t xtime_lock; -/* +/* * To have precision clock, we need to fix available clock frequency */ #define FREQ_NOM 79125 /* Baget frequency ratio */ #define FREQ_DEN 10000 -static inline int timer_intr_valid(void) +static inline int timer_intr_valid(void) { static unsigned long long ticks, valid_ticks; if (ticks++ * FREQ_DEN >= valid_ticks * FREQ_NOM) { - /* - * We need no overflow checks, + /* + * We need no overflow checks, * due baget unable to work 3000 years... * At least without reboot... */ @@ -63,10 +63,10 @@ vic_outb(ss0cr0, VIC_SS0CR0); vic_outb(VIC_INT_IPL(6)|VIC_INT_NOAUTO|VIC_INT_EDGE| - VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); + VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); } -static struct irqaction timer_irq = +static struct irqaction timer_irq = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; void __init time_init(void) diff -urN linux-2.4.21/arch/mips/baget/vacserial.c linux-2.4.22/arch/mips/baget/vacserial.c --- linux-2.4.21/arch/mips/baget/vacserial.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/baget/vacserial.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,2905 +0,0 @@ -/* - * vacserial.c: VAC UART serial driver - * This code stealed and adopted from linux/drivers/char/serial.c - * See that for author info - * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - */ - -#undef SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - -#define CONFIG_SERIAL_SHARE_IRQ - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - -#define RS_STROBE_TIME (10*HZ) -#define RS_ISR_PASS_LIMIT 2 /* Beget is not a super-computer (old=256) */ - -#define IRQ_T(state) \ - ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) - -#define SERIAL_INLINE - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) baget_printk("(%s):[%x] refc=%d, serc=%d, ttyc=%d-> %s\n", \ - kdevname(tty->device),(info->flags),serial_refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - -#define QUAD_UART_SPEED /* Useful for Baget */ - -/* - * End of serial driver configuration section. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_SERIAL_CONSOLE -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#define BAGET_VAC_UART_IRQ 0x35 - -/* - * Implementation note: - * It was descovered by means of advanced electronic tools, - * if the driver works via TX_READY interrupts then VIC generates - * strange self-eliminating traps. Thus, the driver is rewritten to work - * via TX_EMPTY - */ - -/* VAC-specific check/debug switches */ - -#undef CHECK_REG_INDEX -#undef DEBUG_IO_PORT_A - -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#endif - -static char *serial_name = "VAC Serial driver"; -static char *serial_version = "4.26"; - -static DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver serial_driver, callout_driver; -static int serial_refcount; - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* - * IRQ_timeout - How long the timeout should be for each IRQ - * should be after the IRQ has been active. - */ - -static struct async_struct *IRQ_ports[NR_IRQS]; -static int IRQ_timeout[NR_IRQS]; -#ifdef CONFIG_SERIAL_CONSOLE -static struct console sercons; -#endif - -static void autoconfig(struct serial_state * info); -static void change_speed(struct async_struct *info); -static void rs_wait_until_sent(struct tty_struct *tty, int timeout); -static void rs_timer(unsigned long dummy); - -static struct timer_list vacs_timer; - -/* - * Here we define the default xmit fifo size used for each type of - * UART - */ -static struct serial_uart_config uart_config[] = { - { "unknown", 1, 0 }, /* Must go first -- used as unasigned */ - { "VAC UART", 1, 0 } -}; -#define VAC_UART_TYPE 1 /* Just index in above array */ - -static struct serial_state rs_table[] = { -/* - * VAC has tricky layout for pair of his SIO registers, - * so we need special function to access ones. - * To identify port we use their TX offset - */ - { 0, 9600, VAC_UART_B_TX, BAGET_VAC_UART_IRQ, - STD_COM_FLAGS }, /* VAC UART B */ - { 0, 9600, VAC_UART_A_TX, BAGET_VAC_UART_IRQ, - STD_COM_FLAGS } /* VAC UART A */ -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -static struct tty_struct *serial_table[NR_PORTS]; -static struct termios *serial_termios[NR_PORTS]; -static struct termios *serial_termios_locked[NR_PORTS]; - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the copy_from_user blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; -static DECLARE_MUTEX(tmp_buf_sem); - -static inline int serial_paranoia_check(struct async_struct *info, - kdev_t device, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, kdevname(device), routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, kdevname(device), routine); - return 1; - } -#endif - return 0; -} - -/* - To unify UART A/B access we will use following function - to compute register offsets by register index. - */ - -#define VAC_UART_MODE 0 -#define VAC_UART_TX 1 -#define VAC_UART_RX 2 -#define VAC_UART_INT_MASK 3 -#define VAC_UART_INT_STATUS 4 - -#define VAC_UART_REG_NR 5 - -static inline int uart_offset_map(unsigned long port, int reg_index) -{ - static const unsigned int ind_to_reg[VAC_UART_REG_NR][NR_PORTS] = { - { VAC_UART_B_MODE, VAC_UART_A_MODE }, - { VAC_UART_B_TX, VAC_UART_A_TX }, - { VAC_UART_B_RX, VAC_UART_A_RX }, - { VAC_UART_B_INT_MASK, VAC_UART_A_INT_MASK }, - { VAC_UART_B_INT_STATUS, VAC_UART_A_INT_STATUS } - }; -#ifdef CHECK_REG_INDEX - if (reg_index > VAC_UART_REG_NR) panic("vacserial: bad reg_index"); -#endif - return ind_to_reg[reg_index][port == VAC_UART_B_TX ? 0 : 1]; -} - -static inline unsigned int serial_inw(struct async_struct *info, int offset) -{ - int val = vac_inw(uart_offset_map(info->port,offset)); -#ifdef DEBUG_IO_PORT_A - if (info->port == VAC_UART_A_TX) - printk("UART_A_IN: reg = 0x%04x, val = 0x%04x\n", - uart_offset_map(info->port,offset), val); -#endif - return val; -} - -static inline unsigned int serial_inp(struct async_struct *info, int offset) -{ - return serial_inw(info, offset); -} - -static inline unsigned int serial_in(struct async_struct *info, int offset) -{ - return serial_inw(info, offset); -} - -static inline void serial_outw(struct async_struct *info,int offset, int value) -{ -#ifdef DEBUG_IO_PORT_A - if (info->port == VAC_UART_A_TX) - printk("UART_A_OUT: offset = 0x%04x, val = 0x%04x\n", - uart_offset_map(info->port,offset), value); -#endif - vac_outw(value, uart_offset_map(info->port,offset)); -} - -static inline void serial_outp(struct async_struct *info,int offset, int value) -{ - serial_outw(info,offset,value); -} - -static inline void serial_out(struct async_struct *info,int offset, int value) -{ - serial_outw(info,offset,value); -} - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_stop")) - return; - - save_flags(flags); cli(); - if (info->IER & VAC_UART_INT_TX_EMPTY) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - restore_flags(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_start")) - return; - - save_flags(flags); cli(); - if (info->xmit_cnt && info->xmit_buf - && !(info->IER & VAC_UART_INT_TX_EMPTY)) { - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - restore_flags(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(struct async_struct *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -static _INLINE_ void receive_chars(struct async_struct *info, - int *status) -{ - struct tty_struct *tty = info->tty; - unsigned short rx; - unsigned char ch; - int ignored = 0; - struct async_icount *icount; - - icount = &info->state->icount; - do { - rx = serial_inw(info, VAC_UART_RX); - ch = VAC_UART_RX_DATA_MASK & rx; - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - *tty->flip.char_buf_ptr = ch; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - baget_printk("DR%02x:%02x...", rx, *status); -#endif - *tty->flip.flag_buf_ptr = 0; - if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE - | VAC_UART_STATUS_RX_ERR_PARITY - | VAC_UART_STATUS_RX_ERR_FRAME - | VAC_UART_STATUS_RX_ERR_OVERRUN)) { - /* - * For statistics only - */ - if (*status & VAC_UART_STATUS_RX_BREAK_CHANGE) { - *status &= ~(VAC_UART_STATUS_RX_ERR_FRAME - | VAC_UART_STATUS_RX_ERR_PARITY); - icount->brk++; - } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) - icount->parity++; - else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) - icount->frame++; - if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - */ - if (*status & info->ignore_status_mask) { - if (++ignored > 100) - break; - goto ignore_char; - } - *status &= info->read_status_mask; - - if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE)) { -#ifdef SERIAL_DEBUG_INTR - baget_printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - if (tty->flip.count < TTY_FLIPBUF_SIZE) { - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - } - } - } - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - ignore_char: - *status = serial_inw(info, VAC_UART_INT_STATUS); - } while ((*status & VAC_UART_STATUS_RX_READY)); - tty_flip_buffer_push(tty); -} - -static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) -{ - int count; - - if (info->x_char) { - serial_outw(info, VAC_UART_TX, - (((unsigned short)info->x_char)<<8)); - info->state->icount.tx++; - info->x_char = 0; - if (intr_done) - *intr_done = 0; - return; - } - if ((info->xmit_cnt <= 0) || info->tty->stopped || - info->tty->hw_stopped) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_outw(info, VAC_UART_INT_MASK, info->IER); - return; - } - count = info->xmit_fifo_size; - do { - serial_out(info, VAC_UART_TX, - (unsigned short)info->xmit_buf[info->xmit_tail++] \ - << 8); - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - info->state->icount.tx++; - if (--info->xmit_cnt <= 0) - break; - } while (--count > 0); - - if (info->xmit_cnt < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - -#ifdef SERIAL_DEBUG_INTR - baget_printk("THRE..."); -#endif - if (intr_done) - *intr_done = 0; - - if (info->xmit_cnt <= 0) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_outw(info, VAC_UART_INT_MASK, info->IER); - } -} - -static _INLINE_ void check_modem_status(struct async_struct *info) -{ -#if 0 /* VAC hasn't modem control */ - wake_up_interruptible(&info->open_wait); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); -#endif -} - -#ifdef CONFIG_SERIAL_SHARE_IRQ - - -/* - * Specific functions needed for VAC UART interrupt enter/leave - */ - -#define VAC_INT_CTRL_UART_ENABLE \ - (VAC_INT_CTRL_TIMER_PIO10|VAC_INT_CTRL_UART_B_PIO7|VAC_INT_CTRL_UART_A_PIO7) - -#define VAC_INT_CTRL_UART_DISABLE(info) \ - (VAC_INT_CTRL_TIMER_PIO10 | \ - ((info->port == VAC_UART_A_TX) ? \ - (VAC_INT_CTRL_UART_A_DISABLE|VAC_INT_CTRL_UART_B_PIO7) : \ - (VAC_INT_CTRL_UART_A_PIO7|VAC_INT_CTRL_UART_B_DISABLE))) - -/* - * Following two functions were proposed by Pavel Osipenko - * to make VAC/VIC behaviour more regular. - */ -static void intr_begin(struct async_struct* info) -{ - serial_outw(info, VAC_UART_INT_MASK, 0); -} - -static void intr_end(struct async_struct* info) -{ - vac_outw(VAC_INT_CTRL_UART_DISABLE(info), VAC_INT_CTRL); - vac_outw(VAC_INT_CTRL_UART_ENABLE, VAC_INT_CTRL); - - serial_outw(info, VAC_UART_INT_MASK, info->IER); -} - -/* - * This is the serial driver's generic interrupt routine - */ -static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - int status; - struct async_struct * info; - int pass_counter = 0; - struct async_struct *end_mark = 0; - -#ifdef SERIAL_DEBUG_INTR - baget_printk("rs_interrupt(%d)...", irq); -#endif - - info = IRQ_ports[irq]; - if (!info) - return; - - do { - intr_begin(info); /* Mark we begin port handling */ - - if (!info->tty || - (serial_inw (info, VAC_UART_INT_STATUS) - & VAC_UART_STATUS_INTS) == 0) - { - if (!end_mark) - end_mark = info; - goto next; - } - end_mark = 0; - - info->last_active = jiffies; - - status = serial_inw(info, VAC_UART_INT_STATUS); -#ifdef SERIAL_DEBUG_INTR - baget_printk("status = %x...", status); -#endif - if (status & VAC_UART_STATUS_RX_READY) { - receive_chars(info, &status); - } - check_modem_status(info); - if (status & VAC_UART_STATUS_TX_EMPTY) - transmit_chars(info, 0); - - next: - intr_end(info); /* Mark this port handled */ - - info = info->next_port; - if (!info) { - info = IRQ_ports[irq]; - if (pass_counter++ > RS_ISR_PASS_LIMIT) { - break; /* Prevent infinite loops */ - } - continue; - } - } while (end_mark != info); -#ifdef SERIAL_DEBUG_INTR - baget_printk("end.\n"); -#endif - - -} -#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */ - - -/* The original driver was simplified here: - two functions were joined to reduce code */ - -#define rs_interrupt_single rs_interrupt - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); -} - -static void do_softint(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); - } -} - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * --------------------------------------------------------------- - */ - -/* - * This routine figures out the correct timeout for a particular IRQ. - * It uses the smallest timeout of all of the serial ports in a - * particular interrupt chain. Now only used for IRQ 0.... - */ -static void figure_IRQ_timeout(int irq) -{ - struct async_struct *info; - int timeout = 60*HZ; /* 60 seconds === a long time :-) */ - - info = IRQ_ports[irq]; - if (!info) { - IRQ_timeout[irq] = 60*HZ; - return; - } - while (info) { - if (info->timeout < timeout) - timeout = info->timeout; - info = info->next_port; - } - if (!irq) - timeout = timeout / 2; - IRQ_timeout[irq] = timeout ? timeout : 1; -} - -static int startup(struct async_struct * info) -{ - unsigned long flags; - int retval=0; - void (*handler)(int, void *, struct pt_regs *); - struct serial_state *state= info->state; - unsigned long page; - - page = get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - if (!state->port || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit_buf) - free_page(page); - else - info->xmit_buf = (unsigned char *) page; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - if (uart_config[info->state->type].flags & UART_STARTECH) { - /* Wake up UART */ - serial_outp(info, VAC_UART_MODE, 0); - serial_outp(info, VAC_UART_INT_MASK, 0); - } - - /* - * Allocate the IRQ if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - - if (IRQ_ports[state->irq]) { -#ifdef CONFIG_SERIAL_SHARE_IRQ - free_irq(state->irq, NULL); - handler = rs_interrupt; -#else - retval = -EBUSY; - goto errout; -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - } else - handler = rs_interrupt_single; - - - retval = request_irq(state->irq, handler, IRQ_T(state), - "serial", NULL); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } - - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); - - /* - * Clear the interrupt registers. - */ - /* (void) serial_inw(info, VAC_UART_INT_STATUS); */ /* (see above) */ - (void) serial_inw(info, VAC_UART_RX); - - /* - * Now, initialize the UART - */ - serial_outp(info, VAC_UART_MODE, VAC_UART_MODE_INITIAL); /*reset DLAB*/ - - /* - * Finally, enable interrupts - */ - info->IER = VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS | \ - VAC_UART_INT_RX_READY; - serial_outp(info, VAC_UART_INT_MASK, info->IER); /*enable interrupts*/ - - /* - * And clear the interrupt registers again for luck. - */ - (void)serial_inp(info, VAC_UART_INT_STATUS); - (void)serial_inp(info, VAC_UART_RX); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - /* - * Set up serial timers... - */ - mod_timer(&vacs_timer, jiffies + 2*HZ/100); - - /* - * and set the speed of the serial port - */ - change_speed(info); - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct async_struct * info) -{ - unsigned long flags; - struct serial_state *state; - int retval; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - 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, NULL); - retval = request_irq(state->irq, rs_interrupt_single, - IRQ_T(state), "serial", NULL); - - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, NULL); - } - - if (info->xmit_buf) { - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = 0; - } - - info->IER = 0; - serial_outp(info, VAC_UART_INT_MASK, 0x00); /* disable all intrs */ - - /* disable break condition */ - serial_out(info, VAC_UART_MODE, serial_inp(info, VAC_UART_MODE) & \ - ~VAC_UART_MODE_SEND_BREAK); - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); -} - -/* - * When we set line mode, we call this function - * for Baget-specific adjustments. - */ - -static inline unsigned short vac_uart_mode_fixup (unsigned short cval) -{ -#ifdef QUAD_UART_SPEED - /* - * When we are using 4-x advantage in speed: - * - * Disadvantage : can't support 75, 150 bauds - * Advantage : can support 19200, 38400 bauds - */ - char speed = 7 & (cval >> 10); - cval &= ~(7 << 10); - cval |= VAC_UART_MODE_BAUD(speed-2); -#endif - - /* - * In general, we have Tx and Rx ON all time - * and use int mask flag for their disabling. - */ - cval |= VAC_UART_MODE_RX_ENABLE; - cval |= VAC_UART_MODE_TX_ENABLE; - cval |= VAC_UART_MODE_CHAR_RX_ENABLE; - cval |= VAC_UART_MODE_CHAR_TX_ENABLE; - - /* Low 4 bits are not used in UART */ - cval &= ~0xf; - - return cval; -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct async_struct *info) -{ - unsigned short port; - int quot = 0, baud_base, baud; - unsigned cflag, cval; - int bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - if (!(port = info->port)) - return; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS7: cval = 0x0; bits = 9; break; - case CS8: cval = VAC_UART_MODE_8BIT_CHAR; bits = 10; break; - /* Never happens, but GCC is too dumb to figure it out */ - case CS5: - case CS6: - default: cval = 0x0; bits = 9; break; - } - cval &= ~VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARENB) { - cval |= VAC_UART_MODE_PARITY_ENABLE; - bits++; - } - if (cflag & PARODD) - cval |= VAC_UART_MODE_PARITY_ODD; - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; /* B0 transition handled in rs_set_termios */ - baud_base = info->state->baud_base; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - /* If the quotient is ever zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - serial_out(info, VAC_UART_INT_MASK, info->IER); - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = VAC_UART_STATUS_RX_ERR_OVERRUN | \ - VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_RX_READY; - if (I_INPCK(info->tty)) - info->read_status_mask |= VAC_UART_STATUS_RX_ERR_FRAME | \ - VAC_UART_STATUS_RX_ERR_PARITY; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= VAC_UART_STATUS_RX_ERR_PARITY | \ - VAC_UART_STATUS_RX_ERR_FRAME; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= \ - VAC_UART_STATUS_RX_ERR_OVERRUN; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->ignore_status_mask |= VAC_UART_STATUS_RX_READY; - save_flags(flags); cli(); - - - switch (baud) { - default: - case 9600: - cval |= VAC_UART_MODE_BAUD(7); - break; - case 4800: - cval |= VAC_UART_MODE_BAUD(6); - break; - case 2400: - cval |= VAC_UART_MODE_BAUD(5); - break; - case 1200: - cval |= VAC_UART_MODE_BAUD(4); - break; - case 600: - cval |= VAC_UART_MODE_BAUD(3); - break; - case 300: - cval |= VAC_UART_MODE_BAUD(2); - break; -#ifndef QUAD_UART_SPEED - case 150: -#else - case 38400: -#endif - cval |= VAC_UART_MODE_BAUD(1); - break; -#ifndef QUAD_UART_SPEED - case 75: -#else - case 19200: -#endif - cval |= VAC_UART_MODE_BAUD(0); - break; - } - - /* Baget VAC need some adjustments for computed value */ - cval = vac_uart_mode_fixup(cval); - - serial_outp(info, VAC_UART_MODE, cval); - restore_flags(flags); -} - -static void rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_put_char")) - return; - - if (!tty || !info->xmit_buf) - return; - - save_flags(flags); cli(); - if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { - restore_flags(flags); - return; - } - - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= SERIAL_XMIT_SIZE-1; - info->xmit_cnt++; - restore_flags(flags); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !info->xmit_buf) - return; - - save_flags(flags); cli(); - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - restore_flags(flags); -} - -static int rs_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_write")) - return 0; - - if (!tty || !info->xmit_buf || !tmp_buf) - return 0; - - save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - c = MIN(count, - MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - cli(); - c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); - info->xmit_head = ((info->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - while (1) { - cli(); - c = MIN(count, - MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) { - restore_flags(flags); - break; - } - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = ((info->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - } - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped && - !(info->IER & VAC_UART_INT_TX_EMPTY)) { - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->device, "rs_write_room")) - return 0; - ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) - return 0; - return info->xmit_cnt; -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) - return; - - save_flags(flags); cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_send_xchar(struct tty_struct *tty, char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_send_char")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - baget_printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_send_xchar(tty, STOP_CHAR(tty)); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - baget_printk("unthrottle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_send_xchar(tty, START_CHAR(tty)); - } -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct async_struct * info, - struct serial_struct * retinfo) -{ - struct serial_struct tmp; - struct serial_state *state = info->state; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = state->type; - tmp.line = state->line; - tmp.port = state->port; - tmp.irq = state->irq; - tmp.flags = state->flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - tmp.hub6 = state->hub6; - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct async_struct * info, - struct serial_struct * new_info) -{ - struct serial_struct new_serial; - struct serial_state old_state, *state; - unsigned int i,change_irq,change_port; - int retval = 0; - - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - state = info->state; - old_state = *state; - - change_irq = new_serial.irq != state->irq; - change_port = (new_serial.port != state->port) || - (new_serial.hub6 != state->hub6); - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || change_port || - (new_serial.baud_base != state->baud_base) || - (new_serial.type != state->type) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((state->flags & ~ASYNC_USR_MASK) | - (info->flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - new_serial.irq = new_serial.irq; - - if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) || - (new_serial.baud_base == 0) || (new_serial.type < PORT_UNKNOWN) || - (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || - (new_serial.type == PORT_STARTECH)) { - return -EINVAL; - } - - if ((new_serial.type != state->type) || - (new_serial.xmit_fifo_size <= 0)) - new_serial.xmit_fifo_size = - uart_config[state->type].dfl_xmit_fifo_size; - - /* Make sure address is not already in use */ - if (new_serial.type) { - for (i = 0 ; i < NR_PORTS; i++) - if ((state != &rs_table[i]) && - (rs_table[i].port == new_serial.port) && - rs_table[i].type) - return -EADDRINUSE; - } - - if ((change_port || change_irq) && (state->count > 1)) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - state->baud_base = new_serial.baud_base; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->type = new_serial.type; - state->close_delay = new_serial.close_delay * HZ/100; - state->closing_wait = new_serial.closing_wait * HZ/100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - info->xmit_fifo_size = state->xmit_fifo_size = - new_serial.xmit_fifo_size; - - release_region(state->port,8); - if (change_port || change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - shutdown(info); - state->irq = new_serial.irq; - info->port = state->port = new_serial.port; - info->hub6 = state->hub6 = new_serial.hub6; - } - if (state->type != PORT_UNKNOWN) - request_region(state->port,8,"serial(set)"); - - -check_and_exit: - if (!state->port || !state->type) - return 0; - if (info->flags & ASYNC_INITIALIZED) { - if (((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK)) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - change_speed(info); - } - } else - retval = startup(info); - return retval; -} - - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned short status; - unsigned int result; - unsigned long flags; - - save_flags(flags); cli(); - status = serial_inw(info, VAC_UART_INT_STATUS); - restore_flags(flags); - result = ((status & VAC_UART_STATUS_TX_EMPTY) ? TIOCSER_TEMT : 0); - return put_user(result,value); -} - - -static int get_modem_info(struct async_struct * info, unsigned int *value) -{ - unsigned int result; - - result = TIOCM_CAR | TIOCM_DSR; - return put_user(result,value); -} - -static int set_modem_info(struct async_struct * info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg; - - if (get_user(arg, value)) - return -EFAULT; - switch (cmd) { - default: - return -EINVAL; - } - return 0; -} - -static int do_autoconfig(struct async_struct * info) -{ - int retval; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (info->state->count > 1) - return -EBUSY; - - shutdown(info); - - autoconfig(info->state); - - retval = startup(info); - if (retval) - return retval; - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static void rs_break(struct tty_struct *tty, int break_state) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_break")) - return; - - if (!info->port) - return; - save_flags(flags); cli(); - if (break_state == -1) - serial_outp(info, VAC_UART_MODE, - serial_inp(info, VAC_UART_MODE) | \ - VAC_UART_MODE_SEND_BREAK); - else - serial_outp(info, VAC_UART_MODE, - serial_inp(info, VAC_UART_MODE) & \ - ~VAC_UART_MODE_SEND_BREAK); - restore_flags(flags); -} - -static int rs_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - int error; - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERCONFIG: - return do_autoconfig(info); - - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct async_struct *) arg, - info, sizeof(struct async_struct))) - return -EFAULT; - return 0; - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - save_flags(flags); cli(); - /* note the counters on entry */ - cprev = info->state->icount; - restore_flags(flags); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - save_flags(flags); cli(); - cnow = info->state->icount; /* atomic copy */ - restore_flags(flags); - if (cnow.rng == cprev.rng && - cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && - cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && - (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && - (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && - (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && - (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - save_flags(flags); cli(); - cnow = info->state->icount; - restore_flags(flags); - p_cuser = (struct serial_icounter_struct *) arg; - error = put_user(cnow.cts, &p_cuser->cts); - if (error) return error; - error = put_user(cnow.dsr, &p_cuser->dsr); - if (error) return error; - error = put_user(cnow.rng, &p_cuser->rng); - if (error) return error; - error = put_user(cnow.dcd, &p_cuser->dcd); - if (error) return error; - error = put_user(cnow.rx, &p_cuser->rx); - if (error) return error; - error = put_user(cnow.tx, &p_cuser->tx); - if (error) return error; - error = put_user(cnow.frame, &p_cuser->frame); - if (error) return error; - error = put_user(cnow.overrun, &p_cuser->overrun); - if (error) return error; - error = put_user(cnow.parity, &p_cuser->parity); - if (error) return error; - error = put_user(cnow.brk, &p_cuser->brk); - if (error) return error; - error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); - - if (error) return error; - return 0; - - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned int cflag = tty->termios->c_cflag; - - if ( (cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_speed(info); - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } - -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->device, "rs_close")) - return; - - state = info->state; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_close ttys%d, count = %d\n", - info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - baget_printk("rs_close: bad serial port count; " - "tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - baget_printk("rs_close: bad serial port count for " - "ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - /* - * Save the termios structure, since this port may have - * separate termios for callout and dialin. - */ - if (info->flags & ASYNC_NORMAL_ACTIVE) - info->state->normal_termios = *tty->termios; - if (info->flags & ASYNC_CALLOUT_ACTIVE) - info->state->callout_termios = *tty->termios; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->IER &= ~(VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS); - info->read_status_mask &= ~VAC_UART_STATUS_RX_READY; - if (info->flags & ASYNC_INITIALIZED) { - serial_outw(info, VAC_UART_INT_MASK, info->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| - ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; - restore_flags(flags); -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long orig_jiffies, char_time; - int lsr; - - if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) - return; - - if (info->state->type == PORT_UNKNOWN) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout) - char_time = MIN(char_time, timeout); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("In rs_wait_until_sent(%d) check=%lu...", - timeout, char_time); - baget_printk("jiff=%lu...", jiffies); -#endif - while (!((lsr = serial_inp(info, VAC_UART_INT_STATUS)) & \ - VAC_UART_STATUS_TX_EMPTY)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - current->state = TASK_RUNNING; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_hangup(struct tty_struct *tty) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->device, "rs_hangup")) - return; - - state = info->state; - - rs_flush_buffer(tty); - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct async_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - struct serial_state *state = info->state; - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * If this is a callout device, then just make sure the normal - * device isn't being used. - */ - if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { - if (info->flags & ASYNC_NORMAL_ACTIVE) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_SESSION_LOCKOUT) && - (info->session != current->session)) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_PGRP_LOCKOUT) && - (info->pgrp != current->pgrp)) - return -EBUSY; - info->flags |= ASYNC_CALLOUT_ACTIVE; - return 0; - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - if (info->flags & ASYNC_CALLOUT_ACTIVE) - return -EBUSY; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (info->flags & ASYNC_CALLOUT_ACTIVE) { - if (state->normal_termios.c_cflag & CLOCAL) - do_clocal = 1; - } else { - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - save_flags(flags); cli(); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - restore_flags(flags); - info->blocked_open++; - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - !(info->flags & ASYNC_CLOSING)) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, struct async_struct **ret_info) -{ - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } - memset(info, 0, sizeof(struct async_struct)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct async_struct *info; - int retval, line; - unsigned long page; - - MOD_INC_USE_COUNT; - line = MINOR(tty->device) - tty->driver.minor_start; - if ((line < 0) || (line >= NR_PORTS)) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - retval = get_async_struct(line, &info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - tty->driver_data = info; - info->tty = tty; - if (serial_paranoia_check(info, tty->device, "rs_open")) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return -ENODEV; - } - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open %s%d, count = %d\n", - tty->driver.name, info->line, - info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - if (!tmp_buf) { - page = get_free_page(GFP_KERNEL); - if (!page) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return -ENOMEM; - } - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open returning after block_til_ready " - "with %d\n", - retval); -#endif - return retval; - } - - if ((info->state->count == 1) && - (info->flags & ASYNC_SPLIT_TERMIOS)) { - if (tty->driver.subtype == SERIAL_TYPE_NORMAL) - *tty->termios = info->state->normal_termios; - else - *tty->termios = info->state->callout_termios; - change_speed(info); - } -#ifdef CONFIG_SERIAL_CONSOLE - if (sercons.cflag && sercons.index == line) { - tty->termios->c_cflag = sercons.cflag; - sercons.cflag = 0; - change_speed(info); - } -#endif - info->session = current->session; - info->pgrp = current->pgrp; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open ttys%d successful...", info->line); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ - struct async_struct *info = state->info, scr_info; - int ret; - - ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", - state->line, uart_config[state->type].name, - state->port, state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->tty = 0; - } - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - return ret; -} - -int rs_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0, l; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - l = line_info(page + len, &rs_table[i]); - len += l; - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (off-begin); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s with", serial_name, serial_version); -#ifdef CONFIG_SERIAL_SHARE_IRQ - printk(" SHARE_IRQ"); -#endif -#define SERIAL_OPT -#ifdef CONFIG_SERIAL_DETECT_IRQ - printk(" DETECT_IRQ"); -#endif -#ifdef SERIAL_OPT - printk(" enabled\n"); -#else - printk(" no serial options enabled\n"); -#endif -#undef SERIAL_OPT -} - - -/* - * This routine is called by rs_init() to initialize a specific serial - * port. It determines what type of UART chip this serial port is - * using: 8250, 16450, 16550, 16550A. The important question is - * whether or not this UART is a 16550A or not, since this will - * determine whether or not we can use its FIFO features or not. - */ - -/* - * Functionality of this function is reduced: we already know we have a VAC, - * but still need to perform some important actions (see code :-). - */ -static void autoconfig(struct serial_state * state) -{ - struct async_struct *info, scr_info; - unsigned long flags; - - /* Setting up important parameters */ - state->type = VAC_UART_TYPE; - state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; - - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - - save_flags(flags); cli(); - - /* + Flush VAC input fifo */ - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - - /* Disable interrupts */ - serial_outp(info, VAC_UART_INT_MASK, 0); - - restore_flags(flags); -} - -int register_serial(struct serial_struct *req); -void unregister_serial(int line); - -EXPORT_SYMBOL(register_serial); -EXPORT_SYMBOL(unregister_serial); - -/* - * Important function for VAC UART check and reanimation. - */ - -static void rs_timer(unsigned long dummy) -{ - static unsigned long last_strobe = 0; - struct async_struct *info; - unsigned int i; - unsigned long flags; - - if ((jiffies - last_strobe) >= RS_STROBE_TIME) { - for (i=1; i < NR_IRQS; i++) { - info = IRQ_ports[i]; - if (!info) - continue; - save_flags(flags); cli(); -#ifdef CONFIG_SERIAL_SHARE_IRQ - if (info->next_port) { - do { - serial_out(info, VAC_UART_INT_MASK, 0); - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, - info->IER); - info = info->next_port; - } while (info); - rs_interrupt(i, NULL, NULL); - } else -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - rs_interrupt_single(i, NULL, NULL); - restore_flags(flags); - } - } - last_strobe = jiffies; - mod_timer(&vacs_timer, jiffies + RS_STROBE_TIME); - - /* - * It looks this code for case we share IRQ with console... - */ - - if (IRQ_ports[0]) { - save_flags(flags); cli(); -#ifdef CONFIG_SERIAL_SHARE_IRQ - rs_interrupt(0, NULL, NULL); -#else - rs_interrupt_single(0, NULL, NULL); -#endif - restore_flags(flags); - - mod_timer(&vacs_timer, jiffies + IRQ_timeout[0] - 2); - } -} - -/* - * The serial driver boot-time initialization code! - */ -int __init rs_init(void) -{ - int i; - struct serial_state * state; - extern void atomwide_serial_init (void); - extern void dualsp_serial_init (void); - -#ifdef CONFIG_ATOMWIDE_SERIAL - atomwide_serial_init (); -#endif -#ifdef CONFIG_DUALSP_SERIAL - dualsp_serial_init (); -#endif - - init_bh(SERIAL_BH, do_serial_bh); - init_timer(&vacs_timer); - vacs_timer.function = rs_timer; - vacs_timer.expires = 0; - - for (i = 0; i < NR_IRQS; i++) { - IRQ_ports[i] = 0; - IRQ_timeout[i] = 0; - } - - -/* - * It is not a good idea to share interrupts with console, - * but it looks we cannot avoid it. - */ -#if 0 - -#ifdef CONFIG_SERIAL_CONSOLE - /* - * The interrupt of the serial console port - * can't be shared. - */ - if (sercons.flags & CON_CONSDEV) { - for(i = 0; i < NR_PORTS; i++) - if (i != sercons.index && - rs_table[i].irq == rs_table[sercons.index].irq) - rs_table[i].irq = 0; - } -#endif - -#endif - show_serial_version(); - - /* Initialize the tty_driver structure */ - - memset(&serial_driver, 0, sizeof(struct tty_driver)); - serial_driver.magic = TTY_DRIVER_MAGIC; - serial_driver.driver_name = "serial"; - serial_driver.name = "ttyS"; - serial_driver.major = TTY_MAJOR; - serial_driver.minor_start = 64; - serial_driver.num = NR_PORTS; - serial_driver.type = TTY_DRIVER_TYPE_SERIAL; - serial_driver.subtype = SERIAL_TYPE_NORMAL; - serial_driver.init_termios = tty_std_termios; - serial_driver.init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver.flags = TTY_DRIVER_REAL_RAW; - serial_driver.refcount = &serial_refcount; - serial_driver.table = serial_table; - serial_driver.termios = serial_termios; - serial_driver.termios_locked = serial_termios_locked; - - serial_driver.open = rs_open; - serial_driver.close = rs_close; - serial_driver.write = rs_write; - serial_driver.put_char = rs_put_char; - serial_driver.flush_chars = rs_flush_chars; - serial_driver.write_room = rs_write_room; - serial_driver.chars_in_buffer = rs_chars_in_buffer; - serial_driver.flush_buffer = rs_flush_buffer; - serial_driver.ioctl = rs_ioctl; - serial_driver.throttle = rs_throttle; - serial_driver.unthrottle = rs_unthrottle; - serial_driver.send_xchar = rs_send_xchar; - serial_driver.set_termios = rs_set_termios; - serial_driver.stop = rs_stop; - serial_driver.start = rs_start; - serial_driver.hangup = rs_hangup; - serial_driver.break_ctl = rs_break; - serial_driver.wait_until_sent = rs_wait_until_sent; - serial_driver.read_proc = rs_read_proc; - - /* - * The callout device is just like normal device except for - * major number and the subtype code. - */ - callout_driver = serial_driver; - callout_driver.name = "cua"; - callout_driver.major = TTYAUX_MAJOR; - callout_driver.subtype = SERIAL_TYPE_CALLOUT; - callout_driver.read_proc = 0; - callout_driver.proc_entry = 0; - - if (tty_register_driver(&serial_driver)) - panic("Couldn't register serial driver"); - if (tty_register_driver(&callout_driver)) - panic("Couldn't register callout driver"); - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->callout_termios = callout_driver.init_termios; - state->normal_termios = serial_driver.init_termios; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - state->irq = state->irq; - if (check_region(state->port,8)) - continue; - if (state->flags & ASYNC_BOOT_AUTOCONF) - autoconfig(state); - } - - /* - * Detect the IRQ only once every port is initialised, - * because some 16450 do not reset to 0 the MCR register. - */ - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - if (state->type == PORT_UNKNOWN) - continue; - printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n", - state->line, - (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", - state->port, state->irq, - uart_config[state->type].name); - } - return 0; -} - -/* - * register_serial and unregister_serial allows for serial ports to be - * configured at run-time, to support PCMCIA modems. - */ -int register_serial(struct serial_struct *req) -{ - int i; - unsigned long flags; - struct serial_state *state; - - save_flags(flags); - cli(); - for (i = 0; i < NR_PORTS; i++) { - if (rs_table[i].port == req->port) - break; - } - if (i == NR_PORTS) { - for (i = 0; i < NR_PORTS; i++) - if ((rs_table[i].type == PORT_UNKNOWN) && - (rs_table[i].count == 0)) - break; - } - if (i == NR_PORTS) { - restore_flags(flags); - return -1; - } - state = &rs_table[i]; - if (rs_table[i].count) { - restore_flags(flags); - printk("Couldn't configure serial #%d (port=%d,irq=%d): " - "device already open\n", i, req->port, req->irq); - return -1; - } - state->irq = req->irq; - state->port = req->port; - state->flags = req->flags; - - autoconfig(state); - if (state->type == PORT_UNKNOWN) { - restore_flags(flags); - printk("register_serial(): autoconfig failed\n"); - return -1; - } - restore_flags(flags); - - printk(KERN_INFO "tty%02d at 0x%04x (irq = %d) is a %s\n", - state->line, state->port, state->irq, - uart_config[state->type].name); - return state->line; -} - -void unregister_serial(int line) -{ - unsigned long flags; - struct serial_state *state = &rs_table[line]; - - save_flags(flags); - cli(); - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - state->type = PORT_UNKNOWN; - printk(KERN_INFO "tty%02d unloaded\n", state->line); - restore_flags(flags); -} - -#ifdef MODULE -int init_module(void) -{ - return rs_init(); -} - -void cleanup_module(void) -{ - unsigned long flags; - int e1, e2; - int i; - - printk("Unloading %s: version %s\n", serial_name, serial_version); - save_flags(flags); - cli(); - - del_timer_sync(&vacs_timer); - remove_bh(SERIAL_BH); - - if ((e1 = tty_unregister_driver(&serial_driver))) - printk("SERIAL: failed to unregister serial driver (%d)\n", - e1); - if ((e2 = tty_unregister_driver(&callout_driver))) - printk("SERIAL: failed to unregister callout driver (%d)\n", - e2); - restore_flags(flags); - - for (i = 0; i < NR_PORTS; i++) { - if (rs_table[i].type != PORT_UNKNOWN) - release_region(rs_table[i].port, 8); - } - if (tmp_buf) { - free_page((unsigned long) tmp_buf); - tmp_buf = NULL; - } -} -#endif /* MODULE */ - - -/* - * ------------------------------------------------------------ - * Serial console driver - * ------------------------------------------------------------ - */ -#ifdef CONFIG_SERIAL_CONSOLE - -#define BOTH_EMPTY (VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_TX_EMPTY) - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct async_struct *info) -{ - int lsr; - unsigned int tmout = 1000000; - - do { - lsr = serial_inp(info, VAC_UART_INT_STATUS); - if (--tmout == 0) break; - } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - */ -static void serial_console_write(struct console *co, const char *s, - unsigned count) -{ - struct serial_state *ser; - int ier; - unsigned i; - struct async_struct scr_info; /* serial_{in,out} because HUB6 */ - - ser = rs_table + co->index; - scr_info.magic = SERIAL_MAGIC; - scr_info.port = ser->port; - scr_info.flags = ser->flags; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_inp(&scr_info, VAC_UART_INT_MASK); - serial_outw(&scr_info, VAC_UART_INT_MASK, 0x00); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++, s++) { - wait_for_xmitr(&scr_info); - - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_outp(&scr_info, VAC_UART_TX, (unsigned short)*s << 8); - if (*s == 10) { - wait_for_xmitr(&scr_info); - serial_outp(&scr_info, VAC_UART_TX, 13 << 8); - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - wait_for_xmitr(&scr_info); - serial_outp(&scr_info, VAC_UART_INT_MASK, ier); -} - -static kdev_t serial_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init serial_console_setup(struct console *co, char *options) -{ - struct serial_state *ser; - unsigned cval; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - int quot = 0; - char *s; - struct async_struct scr_info; /* serial_{in,out} because HUB6 */ - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while(*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - - /* - * Divisor, bytesize and parity - */ - ser = rs_table + co->index; - scr_info.magic = SERIAL_MAGIC; - scr_info.port = ser->port; - scr_info.flags = ser->flags; - - quot = ser->baud_base / baud; - cval = cflag & (CSIZE | CSTOPB); - - cval >>= 4; - - cval &= ~VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARENB) - cval |= VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARODD) - cval |= VAC_UART_MODE_PARITY_ODD; - - /* - * Disable UART interrupts, set DTR and RTS high - * and set speed. - */ - switch (baud) { - default: - case 9600: - cval |= VAC_UART_MODE_BAUD(7); - break; - case 4800: - cval |= VAC_UART_MODE_BAUD(6); - break; - case 2400: - cval |= VAC_UART_MODE_BAUD(5); - break; - case 1200: - cval |= VAC_UART_MODE_BAUD(4); - break; - case 600: - cval |= VAC_UART_MODE_BAUD(3); - break; - case 300: - cval |= VAC_UART_MODE_BAUD(2); - break; -#ifndef QUAD_UART_SPEED - case 150: -#else - case 38400: -#endif - cval |= VAC_UART_MODE_BAUD(1); - break; -#ifndef QUAD_UART_SPEED - case 75: -#else - case 19200: -#endif - cval |= VAC_UART_MODE_BAUD(0); - break; - } - - /* Baget VAC need some adjustments for computed value */ - cval = vac_uart_mode_fixup(cval); - - serial_outp(&scr_info, VAC_UART_MODE, cval); - serial_outp(&scr_info, VAC_UART_INT_MASK, 0); - - return 0; -} - -static struct console sercons = { - name: "ttyS", - write: serial_console_write, - device: serial_console_device, - setup: serial_console_setup, - flags: CON_PRINTBUFFER, - index: -1, -}; - -/* - * Register console. - */ -long __init serial_console_init(long kmem_start, long kmem_end) -{ - register_console(&sercons); - return kmem_start; -} -#endif - -#ifdef CONFIG_REMOTE_DEBUG -#undef PRINT_DEBUG_PORT_INFO - -/* - * This is the interface to the remote debugger stub. - * I've put that here to be able to control the serial - * device more directly. - */ - -static int initialized; - -static int rs_debug_init(struct async_struct *info) -{ - int quot; - - autoconfig(info); /* autoconfigure ttyS0, whatever that is */ - -#ifdef PRINT_DEBUG_PORT_INFO - baget_printk("kgdb debug interface:: tty%02d at 0x%04x", - info->line, info->port); - switch (info->type) { - case PORT_8250: - baget_printk(" is a 8250\n"); - break; - case PORT_16450: - baget_printk(" is a 16450\n"); - break; - case PORT_16550: - baget_printk(" is a 16550\n"); - break; - case PORT_16550A: - baget_printk(" is a 16550A\n"); - break; - case PORT_16650: - baget_printk(" is a 16650\n"); - break; - default: - baget_printk(" is of unknown type -- unusable\n"); - break; - } -#endif - - if (info->port == PORT_UNKNOWN) - return -1; - - /* - * Clear all interrupts - */ - - (void)serial_inp(info, VAC_UART_INT_STATUS); - (void)serial_inp(info, VAC_UART_RX); - - /* - * Now, initialize the UART - */ - serial_outp(info,VAC_UART_MODE,VAC_UART_MODE_INITIAL); /* reset DLAB */ - if (info->flags & ASYNC_FOURPORT) { - info->MCR = UART_MCR_DTR | UART_MCR_RTS; - info->MCR_noint = UART_MCR_DTR | UART_MCR_OUT1; - } else { - info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - info->MCR_noint = UART_MCR_DTR | UART_MCR_RTS; - } - - info->MCR = info->MCR_noint; /* no interrupts, please */ - /* - * and set the speed of the serial port - * (currently hardwired to 9600 8N1 - */ - - quot = info->baud_base / 9600; /* baud rate is fixed to 9600 */ - /* FIXME: if rs_debug interface is needed, we need to set speed here */ - - return 0; -} - -int putDebugChar(char c) -{ - struct async_struct *info = rs_table; - - if (!initialized) { /* need to init device first */ - if (rs_debug_init(info) == 0) - initialized = 1; - else - return 0; - } - - while ((serial_inw(info, VAC_UART_INT_STATUS) & \ - VAC_UART_STATUS_TX_EMPTY) == 0) - ; - serial_out(info, VAC_UART_TX, (unsigned short)c << 8); - - return 1; -} - -char getDebugChar(void) -{ - struct async_struct *info = rs_table; - - if (!initialized) { /* need to init device first */ - if (rs_debug_init(info) == 0) - initialized = 1; - else - return 0; - } - while (!(serial_inw(info, VAC_UART_INT_STATUS) & \ - VAC_UART_STATUS_RX_READY)) - ; - - return(serial_inp(info, VAC_UART_RX)); -} - -#endif /* CONFIG_REMOTE_DEBUG */ diff -urN linux-2.4.21/arch/mips/baget/wbflush.c linux-2.4.22/arch/mips/baget/wbflush.c --- linux-2.4.21/arch/mips/baget/wbflush.c 2000-02-24 22:52:30.000000000 -0800 +++ linux-2.4.22/arch/mips/baget/wbflush.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,24 +0,0 @@ -/* - * Setup the right wbflush routine for Baget/MIPS. - * - * Copyright (C) 1999 Gleb Raiko & Vladimir Roganov - */ - -#include -#include - -void (*__wbflush) (void); - -static void wbflush_baget(void); - -void __init wbflush_setup(void) -{ - __wbflush = wbflush_baget; -} - -/* - * Baget/MIPS doesnt need to write back the WB. - */ -static void wbflush_baget(void) -{ -} diff -urN linux-2.4.21/arch/mips/boot/elf2ecoff.c linux-2.4.22/arch/mips/boot/elf2ecoff.c --- linux-2.4.21/arch/mips/boot/elf2ecoff.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/boot/elf2ecoff.c 2003-08-25 04:44:39.000000000 -0700 @@ -285,7 +285,7 @@ if (argc < 3 || argc > 4) { usage: fprintf(stderr, - "usage: elf2aout [-a]\n"); + "usage: elf2ecoff [-a]\n"); exit(1); } if (argc == 4) { diff -urN linux-2.4.21/arch/mips/cobalt/Makefile linux-2.4.22/arch/mips/cobalt/Makefile --- linux-2.4.21/arch/mips/cobalt/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/cobalt/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -11,6 +11,7 @@ O_TARGET := cobalt.o -obj-y := irq.o int-handler.o pci.o reset.o setup.o via.o promcon.o +obj-y := irq.o int-handler.o reset.o setup.o via.o promcon.o +obj-$(CONFIG_PCI) += pci.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/cobalt/int-handler.S linux-2.4.22/arch/mips/cobalt/int-handler.S --- linux-2.4.21/arch/mips/cobalt/int-handler.S 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/cobalt/int-handler.S 2003-08-25 04:44:39.000000000 -0700 @@ -6,8 +6,7 @@ * for more details. * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) - * + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) */ #include #include @@ -30,7 +29,9 @@ /* * Get pending Interrupts */ - mfc0 s0,CP0_CAUSE # get irq mask + mfc0 s0,CP0_CAUSE # get raw irq status + mfc0 a0,CP0_STATUS # get irq mask + and s0,s0,a0 # compute masked irq status andi a0,s0,CAUSEF_IP2 /* Check for Galileo timer */ beq a0,zero,1f @@ -57,7 +58,7 @@ andi a0,s0,CAUSEF_IP4 /* Ethernet 0 interrupt */ - li a0,COBALT_RAQ_ETH0_IRQ + li a0,COBALT_ETH0_IRQ jal do_IRQ move a1,sp @@ -69,7 +70,7 @@ andi a0,s0,CAUSEF_IP5 /* Ethernet 1 interrupt */ - li a0,COBALT_RAQ_ETH1_IRQ + li a0,COBALT_ETH1_IRQ jal do_IRQ move a1,sp @@ -80,7 +81,7 @@ andi a0,s0,CAUSEF_IP7 /* Serial interrupt */ - li a0,7 + li a0,COBALT_SERIAL_IRQ jal do_IRQ move a1,sp @@ -91,7 +92,7 @@ nop /* PCI interrupt */ - li a0,9 + li a0,COBALT_QUBE_SLOT_IRQ jal do_IRQ move a1,sp diff -urN linux-2.4.21/arch/mips/cobalt/irq.c linux-2.4.22/arch/mips/cobalt/irq.c --- linux-2.4.21/arch/mips/cobalt/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/cobalt/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -77,7 +78,7 @@ unsigned long flags; save_and_cli(flags); - change_cp0_status(irqnr_to_type[irq], irqnr_to_type[irq]); + change_c0_status(irqnr_to_type[irq], irqnr_to_type[irq]); restore_flags(flags); } @@ -93,7 +94,7 @@ unsigned long flags; save_and_cli(flags); - change_cp0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq])); + change_c0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq])); restore_flags(flags); } @@ -133,8 +134,8 @@ /* Mask all cpu interrupts (except IE4, we already masked those at VIA level) */ - clear_cp0_status(ST0_IM); - set_cp0_status(IE_IRQ4); + clear_c0_status(ST0_IM); + set_c0_status(IE_IRQ4); cli(); diff -urN linux-2.4.21/arch/mips/cobalt/pci.c linux-2.4.22/arch/mips/cobalt/pci.c --- linux-2.4.21/arch/mips/cobalt/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/cobalt/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,8 +6,7 @@ * for more details. * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) - * + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) */ #include @@ -16,9 +15,10 @@ #include #include -#include #include #include +#include +#include #ifdef CONFIG_PCI @@ -48,7 +48,7 @@ { unsigned short pci_cmd; unsigned long ioaddr_base = 0x10108000; /* It's magic, ask Doug. */ - unsigned long memaddr_base = 0x12000000; + unsigned long memaddr_base = 0x12001000; int i; /* Enable bits in COMMAND so driver can talk to it. */ @@ -60,6 +60,9 @@ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_QUBE_SLOT_IRQ); dev->irq = COBALT_QUBE_SLOT_IRQ; + ioaddr_base += 0x2000 * PCI_FUNC(dev->devfn); + memaddr_base += 0x2000 * PCI_FUNC(dev->devfn); + /* Fixup base addresses, we only support I/O at the moment. */ for(i = 0; i <= 5; i++) { unsigned int regaddr = (PCI_BASE_ADDRESS_0 + (i * 4)); @@ -125,27 +128,18 @@ /* Fixup the first tulip located at device PCICONF_ETH0 */ if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH0) { - /* - * The IRQ of the first Tulip is different on Qube and RaQ - */ - if (cobalt_board_id == COBALT_BRD_ID_RAQ2) { - /* Setup the first Tulip on the RAQ */ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - COBALT_RAQ_ETH0_IRQ); - dev->irq = COBALT_RAQ_ETH0_IRQ; - } else { - /* All Qube's route this the same way. */ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - COBALT_QUBE_ETH_IRQ); - dev->irq = COBALT_QUBE_ETH_IRQ; - } + /* Setup the first Tulip */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + COBALT_ETH0_IRQ); + dev->irq = COBALT_ETH0_IRQ; + dev->resource[0].start = 0x100000; dev->resource[0].end = 0x10007f; - if (dev->resource[1].start < 0x10000000) { - dev->resource[1].start = 0xe9ffec00; - dev->resource[1].end = 0xe9ffefff; - pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0xe9ffec00); - } + + dev->resource[1].start = 0x12000000; + dev->resource[1].end = dev->resource[1].start + 0x3ff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start); + /* Fixup the second tulip located at device PCICONF_ETH1 */ } else if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH1) { @@ -156,14 +150,18 @@ /* Give it it's IRQ. */ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - COBALT_RAQ_ETH1_IRQ); - dev->irq = COBALT_RAQ_ETH1_IRQ; + COBALT_ETH1_IRQ); + dev->irq = COBALT_ETH1_IRQ; /* And finally, a usable I/O space allocation, right after what * the first Tulip uses. */ dev->resource[0].start = 0x101000; dev->resource[0].end = 0x10107f; + + dev->resource[1].start = 0x12000400; + dev->resource[1].end = dev->resource[1].start + 0x3ff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start); } } @@ -194,7 +192,10 @@ /* And finally, a usable I/O space allocation, right after what * the second Tulip uses. */ - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x10102001); + dev->resource[0].start = 0x102000; + dev->resource[0].end = dev->resource[0].start + 0xff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x10102000); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x00002000); pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0x00100000); } @@ -219,15 +220,15 @@ */ pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id); galileo_id &= 0xff; /* mask off class info */ - if (galileo_id == 0x10) { + if (galileo_id >= 0x10) { /* New Galileo, assumes PCI stop line to VIA is connected. */ - *((volatile unsigned int *)0xb4000c04) = 0x00004020; + GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS); } else if (galileo_id == 0x1 || galileo_id == 0x2) { signed int timeo; /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ - timeo = *((volatile unsigned int *)0xb4000c04); + timeo = GALILEO_INL(GT_PCI0_TOR_OFS); /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ - *((volatile unsigned int *)0xb4000c04) = 0x0000ffff; + GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS); } } @@ -266,12 +267,9 @@ return -1; /* NOT ok device number */ } -#define PCI_CFG_DATA ((volatile unsigned long *)0xb4000cfc) -#define PCI_CFG_CTRL ((volatile unsigned long *)0xb4000cf8) - #define PCI_CFG_SET(dev,where) \ - ((*PCI_CFG_CTRL) = (0x80000000 | (PCI_SLOT ((dev)->devfn) << 11) | \ - (PCI_FUNC ((dev)->devfn) << 8) | (where))) + GALILEO_OUTL((0x80000000 | (((dev)->devfn) << 8) | \ + (where)), GT_PCI0_CFGADDR_OFS) static int qube_pci_read_config_dword (struct pci_dev *dev, int where, @@ -284,7 +282,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; } PCI_CFG_SET(dev, where); - *val = *PCI_CFG_DATA; + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -299,7 +297,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; } PCI_CFG_SET(dev, (where & ~0x3)); - *val = *PCI_CFG_DATA >> ((where & 3) * 8); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; } @@ -312,7 +310,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; } PCI_CFG_SET(dev, (where & ~0x3)); - *val = *PCI_CFG_DATA >> ((where & 3) * 8); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; } @@ -325,7 +323,7 @@ if (pci_range_ck (dev)) return PCIBIOS_DEVICE_NOT_FOUND; PCI_CFG_SET(dev, where); - *PCI_CFG_DATA = val; + GALILEO_OUTL(val, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -341,10 +339,10 @@ if (pci_range_ck (dev)) return PCIBIOS_DEVICE_NOT_FOUND; PCI_CFG_SET(dev, (where & ~0x3)); - tmp = *PCI_CFG_DATA; + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xffff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - *PCI_CFG_DATA = tmp; + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -358,10 +356,10 @@ if (pci_range_ck (dev)) return PCIBIOS_DEVICE_NOT_FOUND; PCI_CFG_SET(dev, (where & ~0x3)); - tmp = *PCI_CFG_DATA; + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - *PCI_CFG_DATA = tmp; + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -384,7 +382,7 @@ /* Read the cobalt id register out of the PCI config space */ dev.devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0); PCI_CFG_SET(&dev, (VIA_COBALT_BRD_ID_REG & ~0x3)); - cobalt_board_id = *PCI_CFG_DATA >> ((VIA_COBALT_BRD_ID_REG & 3) * 8); + cobalt_board_id = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((VIA_COBALT_BRD_ID_REG & 3) * 8); cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id); printk("Cobalt Board ID: %d\n", cobalt_board_id); @@ -398,37 +396,6 @@ pci_scan_bus(0, &qube_pci_ops, NULL); } -char *pcibios_setup(char *str) -{ - return str; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - u16 cmd, status; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - pci_read_config_word(dev, PCI_STATUS, &status); - printk("PCI: Enabling device %s (%04x %04x)\n", dev->slot_name, cmd, status); - /* We'll sort this out when we know it isn't enabled ;) */ - - return 0; -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - - panic("Uhhoh called pcibios_align_resource\n"); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - - panic("Uhhoh called pcibios_update_resource\n"); -} - void __init pcibios_fixup_bus(struct pci_bus *bus) { /* We don't have sub-busses to fixup here */ diff -urN linux-2.4.21/arch/mips/cobalt/promcon.c linux-2.4.22/arch/mips/cobalt/promcon.c --- linux-2.4.21/arch/mips/cobalt/promcon.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/cobalt/promcon.c 2003-08-25 04:44:39.000000000 -0700 @@ -77,12 +77,12 @@ } static struct console ns16550_console = { - name: "prom", - setup: NULL, - write: ns16550_console_write, - device: ns16550_console_dev, - flags: CON_PRINTBUFFER, - index: -1, + .name = "prom", + .setup = NULL, + .write = ns16550_console_write, + .device = ns16550_console_dev, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init ns16550_setup_console(void) diff -urN linux-2.4.21/arch/mips/cobalt/reset.c linux-2.4.22/arch/mips/cobalt/reset.c --- linux-2.4.21/arch/mips/cobalt/reset.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/cobalt/reset.c 2003-08-25 04:44:39.000000000 -0700 @@ -28,10 +28,10 @@ * kernel in the flush locks up somewhen during of after the PCI * detection stuff. */ - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__( "jr\t%0" : diff -urN linux-2.4.21/arch/mips/cobalt/setup.c linux-2.4.22/arch/mips/cobalt/setup.c --- linux-2.4.21/arch/mips/cobalt/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/cobalt/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,7 +6,7 @@ * for more details. * * Copyright (C) 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) * */ @@ -21,11 +21,11 @@ #include #include #include -#include -#include #include #include -#include +#include + +#include extern void cobalt_machine_restart(char *command); extern void cobalt_machine_halt(void); @@ -53,13 +53,6 @@ } -#define GALILEO_T0_VAL 0xb4000850 -#define GALILEO_TIMER_CTRL 0xb4000864 -#define GALILEO_CPU_MASK 0xb4000c1c - -#define GALILEO_ENTC0 0x01 -#define GALILEO_SELTC0 0x02 - static void __init cobalt_time_init(void) { rtc_ops = &std_rtc_ops; @@ -68,24 +61,18 @@ static void __init cobalt_timer_setup(struct irqaction *irq) { /* Load timer value for 150 Hz */ - volatile unsigned long *timer_reg = (volatile unsigned long *)GALILEO_T0_VAL; - - *timer_reg = 500000; + GALILEO_OUTL(500000, GT_TC0_OFS); /* Register our timer interrupt */ setup_irq(COBALT_TIMER_IRQ, irq); /* Enable timer ints */ - *((volatile unsigned long *) GALILEO_TIMER_CTRL) = - (unsigned long) (GALILEO_ENTC0 | GALILEO_SELTC0); + GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS); /* Unmask timer int */ - *((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100; + GALILEO_OUTL(0x100, GT_INTRMASK_OFS); } -void __init bus_error_init(void) { /* nothing */ } - - void __init cobalt_setup(void) { @@ -99,7 +86,8 @@ #ifdef CONFIG_BLK_DEV_IDE ide_ops = &std_ide_ops; #endif - set_io_port_base(0xb0000000); + + set_io_port_base(KSEG1ADDR(0x10000000)); /* * This is a prom style console. We just poke at the diff -urN linux-2.4.21/arch/mips/cobalt/via.c linux-2.4.22/arch/mips/cobalt/via.c --- linux-2.4.21/arch/mips/cobalt/via.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/cobalt/via.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,17 +6,17 @@ * for more details. * * Copyright (C) 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) * */ +#include #include -#include + #include #include -#include - -extern void do_IRQ(int irq, struct pt_regs * regs); +#include +#include asmlinkage void via_irq(struct pt_regs *regs) { @@ -50,17 +50,16 @@ printk("Spurious master interrupt..."); } -#define GALILEO_INTCAUSE 0xb4000c18 -#define GALILEO_T0EXP 0x00000100 - asmlinkage void galileo_irq(struct pt_regs *regs) { - unsigned long irq_src = *((unsigned long *) GALILEO_INTCAUSE); + unsigned long irq_src; + + irq_src = GALILEO_INL(GT_INTRCAUSE_OFS); /* Check for timer irq ... */ if (irq_src & GALILEO_T0EXP) { /* Clear the int line */ - *((volatile unsigned long *) GALILEO_INTCAUSE) = 0; + GALILEO_OUTL(0, GT_INTRCAUSE_OFS); do_IRQ(COBALT_TIMER_IRQ, regs); } else printk("Spurious Galileo interrupt...\n"); diff -urN linux-2.4.21/arch/mips/config-shared.in linux-2.4.22/arch/mips/config-shared.in --- linux-2.4.21/arch/mips/config-shared.in 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/mips/config-shared.in 2003-08-25 04:44:39.000000000 -0700 @@ -14,19 +14,33 @@ fi endmenu +# +# Keep these alphabetically sorted +# mainmenu_option next_comment comment 'Machine selection' dep_bool 'Support for Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 $CONFIG_EXPERIMENTAL -dep_bool 'Support for Alchemy Semi PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Bosporus board' CONFIG_MIPS_BOSPORUS $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Mirage board' CONFIG_MIPS_MIRAGE $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Db1000 board' CONFIG_MIPS_DB1000 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Db1100 board' CONFIG_MIPS_DB1100 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Db1500 board' CONFIG_MIPS_DB1500 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32 if [ "$CONFIG_MIPS_PB1000" = "y" ]; then bool ' Support for PCI AUTO Config' CONFIG_PCI_AUTO fi -dep_bool 'Support for Alchemy Semi PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32 -dep_bool 'Support for Alchemy Semi PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32 -dep_bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 $CONFIG_EXPERIMENTAL +dep_bool 'Support for Alchemy PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32 +dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32 +dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32 dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL +bool 'Support for CASIO CASSIOPEIA E-10/15/55/65' CONFIG_CASIO_E55 dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL -dep_bool 'Support for DECstations' CONFIG_DECSTATION $CONFIG_MIPS32 +if [ "$CONFIG_MIPS32" = "y" ]; then + bool 'Support for DECstations' CONFIG_DECSTATION +else + dep_bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION $CONFIG_EXPERIMENTAL +fi dep_bool 'Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV64120 $CONFIG_EXPERIMENTAL if [ "$CONFIG_MIPS_EV64120" = "y" ]; then bool ' Enable Second PCI (PCI1)' CONFIG_EVB_PCI1 @@ -38,16 +52,25 @@ dep_bool 'Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV96100 $CONFIG_EXPERIMENTAL bool 'Support for Globespan IVR board' CONFIG_MIPS_IVR bool 'Support for Hewlett Packard LaserJet board' CONFIG_HP_LASERJET +bool 'Support for IBM WorkPad z50' CONFIG_IBM_WORKPAD +bool 'Support for LASAT Networks platforms' CONFIG_LASAT +if [ "$CONFIG_LASAT" = "y" ]; then + tristate ' PICVUE LCD display driver' CONFIG_PICVUE + dep_tristate ' PICVUE LCD display driver /proc interface' CONFIG_PICVUE_PROC $CONFIG_PICVUE + bool ' DS1603 RTC driver' CONFIG_DS1603 + bool ' LASAT sysctl interface' CONFIG_LASAT_SYSCTL +fi bool 'Support for ITE 8172G board' CONFIG_MIPS_ITE8172 if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then bool ' Support for older IT8172 (Rev C)' CONFIG_IT8172_REVC fi -dep_bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS $CONFIG_EXPERIMENTAL +bool 'Support for MIPS Atlas board' CONFIG_MIPS_ATLAS bool 'Support for MIPS Magnum 4000' CONFIG_MIPS_MAGNUM_4000 -dep_bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA $CONFIG_EXPERIMENTAL +bool 'Support for MIPS Malta board' CONFIG_MIPS_MALTA dep_bool 'Support for MIPS SEAD board (EXPERIMENTAL)' CONFIG_MIPS_SEAD $CONFIG_EXPERIMENTAL bool 'Support for Momentum Ocelot board' CONFIG_MOMENCO_OCELOT bool 'Support for Momentum Ocelot-G board' CONFIG_MOMENCO_OCELOT_G +bool 'Support for Momentum Ocelot-C and -CS boards' CONFIG_MOMENCO_OCELOT_C dep_bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 $CONFIG_EXPERIMENTAL bool 'Support for NEC DDB Vrc-5476' CONFIG_DDB5476 bool 'Support for NEC DDB Vrc-5477' CONFIG_DDB5477 @@ -56,6 +79,9 @@ fi bool 'Support for NEC Osprey board' CONFIG_NEC_OSPREY bool 'Support for NEC Eagle/Hawk board' CONFIG_NEC_EAGLE +if [ "$CONFIG_NEC_EAGLE" = "y" ]; then + tristate ' NEC VRC4173 support' CONFIG_VRC4173 +fi bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700 dep_bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL if [ "$CONFIG_NINO" = "y" ]; then @@ -65,7 +91,7 @@ Model-500/510 CONFIG_NINO_16MB" Model-200 fi bool 'Support for SGI IP22 (Indy/Indigo2)' CONFIG_SGI_IP22 -dep_bool 'Support for SGI-IP27 (Origin200/2000)' CONFIG_SGI_IP27 $CONFIG_MIPS64 +dep_bool 'Support for SGI IP27 (Origin200/2000)' CONFIG_SGI_IP27 $CONFIG_MIPS64 if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' IP27 N-Mode' CONFIG_SGI_SN0_N_MODE bool ' Discontiguous Memory Support' CONFIG_DISCONTIGMEM @@ -73,16 +99,72 @@ bool ' Mapped kernel support' CONFIG_MAPPED_KERNEL bool ' Kernel text replication support' CONFIG_REPLICATE_KTEXT bool ' Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS - bool ' Multi-Processing support' CONFIG_SMP + define_bool CONFIG_SMP_CAPABLE y #bool ' IP27 XXL' CONFIG_SGI_SN0_XXL fi -dep_bool 'Support for SGI-IP32 (O2) (EXPERIMENTAL)' CONFIG_SGI_IP32 $CONFIG_EXPERIMENTAL dep_bool 'Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)' CONFIG_SIBYTE_SB1xxx_SOC $CONFIG_EXPERIMENTAL if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then - choice ' BCM1xxx SOC Type' \ - "BCM1250 CONFIG_SIBYTE_SB1250" BCM1250 + choice ' BCM1xxx SOC-based board' \ + "BCM91250A-SWARM CONFIG_SIBYTE_SWARM \ + BCM91250E-Sentosa CONFIG_SIBYTE_SENTOSA \ + BCM91125E-Rhone CONFIG_SIBYTE_RHONE \ + BCM91120x-Carmel CONFIG_SIBYTE_CARMEL \ + BCM91250PT-PTSwarm CONFIG_SIBYTE_PTSWARM \ + BCM91250C2-LittleSur CONFIG_SIBYTE_LITTLESUR \ + BCM91120C-CRhine CONFIG_SIBYTE_CRHINE \ + BCM91125C-CRhone CONFIG_SIBYTE_CRHONE \ + Other CONFIG_SIBYTE_UNKNOWN" CONFIG_SIBYTE_SWARM + + if [ "$CONFIG_SIBYTE_UNKNOWN" = "y" ]; then + choice ' BCM1xxx SOC Type' \ + "BCM91250 CONFIG_SIBYTE_SB1250 \ + BCM91120 CONFIG_SIBYTE_BCM1120 \ + BCM91125 CONFIG_SIBYTE_BCM1125 \ + BCM91125H CONFIG_SIBYTE_BCM1125H" CONFIG_SIBYTE_SB1250 + unset CONFIG_SIBYTE_BOARD + else + define_bool CONFIG_SIBYTE_BOARD y + if [ "$CONFIG_SIBYTE_SWARM" = "y" -o \ + "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \ + "$CONFIG_SIBYTE_PTSWARM" = "y" -o \ + "$CONFIG_SIBYTE_SENTOSA" = "y" ]; then + define_bool CONFIG_SIBYTE_SB1250 y + unset CONFIG_SIBYTE_BCM1120 + unset CONFIG_SIBYTE_BCM1125 + unset CONFIG_SIBYTE_BCM1125H + fi + if [ "$CONFIG_SIBYTE_CRHINE" = "y" -o \ + "$CONFIG_SIBYTE_CARMEL" = "y" ]; then + define_bool CONFIG_SIBYTE_BCM1120 y + unset CONFIG_SIBYTE_SB1250 + unset CONFIG_SIBYTE_BCM1125 + unset CONFIG_SIBYTE_BCM1125H + fi + if [ "$CONFIG_SIBYTE_CRHONE" = "y" -o \ + "$CONFIG_SIBYTE_RHONE" = "y" ]; then + define_bool CONFIG_SIBYTE_BCM1125H y + unset CONFIG_SIBYTE_SB1250 + unset CONFIG_SIBYTE_BCM1120 + unset CONFIG_SIBYTE_BCM1125 + fi + fi + + if [ "$CONFIG_SIBYTE_BCM1120" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then + define_bool CONFIG_SIBYTE_BCM112X y + choice 'BCM112x Stepping' \ + "Hybrid CONFIG_CPU_SB1_PASS_2 \ + An CONFIG_CPU_SB1_PASS_3" An + else + unset CONFIG_SIBYTE_BCM112X + choice 'BCM1250 Stepping' \ + "Pass1 CONFIG_CPU_SB1_PASS_1 \ + An CONFIG_CPU_SB1_PASS_2 \ + Bn CONFIG_CPU_SB1_PASS_2_2 \ + Cn CONFIG_CPU_SB1_PASS_4" An + fi - bool ' Running under simulation' CONFIG_SIMULATION bool ' Booting from CFE' CONFIG_SIBYTE_CFE dep_bool ' Use firmware console' CONFIG_SIBYTE_CFE_CONSOLE $CONFIG_SIBYTE_CFE if [ "$CONFIG_SIBYTE_CFE" = "n" ]; then @@ -90,25 +172,48 @@ int ' Memory size (in megabytes)' CONFIG_SIBYTE_STANDALONE_RAM_SIZE 32 fi + bool ' Support for Bus Watcher statistics' CONFIG_SIBYTE_BUS_WATCHER bool ' Support for SB1/SOC profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF - bool ' Support for ZBbus profiling' CONFIG_BCM1250_TBPROF + bool ' Support for ZBbus profiling' CONFIG_SIBYTE_TBPROF - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - if [ "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then - bool ' Multi-Processing support' CONFIG_SMP + if [ "$CONFIG_SIBYTE_SB1250" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then + bool ' Support for BCM1250/BCM1125 onchip PCI controller' CONFIG_PCI + fi + + if [ "$CONFIG_SIBYTE_SB1250" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then + if [ "$CONFIG_PCI" = "y" ]; then + define_bool CONFIG_SIBYTE_HAS_LDT y fi fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - bool ' Support for BCM1250/BCM112x onchip PCI controller' CONFIG_PCI + if [ "$CONFIG_SIBYTE_SWARM" = "y" -o \ + "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \ + "$CONFIG_SIBYTE_PTSWARM" = "y" -o \ + "$CONFIG_SIBYTE_CARMEL" = "y" ]; then + define_bool CONFIG_SIBYTE_GENBUS_IDE y fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - bool ' Support for SWARM board' CONFIG_SIBYTE_SWARM + if [ "$CONFIG_SIBYTE_SB1250" = "y" -a \ + "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then + define_bool CONFIG_SMP_CAPABLE y fi fi bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI +bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 +bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 +if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then + bool ' Add TANBAC TB0219 Base board support' CONFIG_TANBAC_TB0219 +fi + dep_bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927 $CONFIG_MIPS32 +bool 'Support for Toshiba RBTX49[23]7 Reference Board' CONFIG_TOSHIBA_RBTX4927 +bool 'Support for Victor MP-C303/304' CONFIG_VICTOR_MPC30X +if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then + tristate ' NEC VRC4173 support' CONFIG_VRC4173 +fi bool 'Support for ZAO Networks Capcella' CONFIG_ZAO_CAPCELLA dep_bool 'High Memory Support' CONFIG_HIGHMEM $CONFIG_MIPS32 @@ -127,56 +232,123 @@ define_bool CONFIG_MIPS_JAZZ y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_ROTTEN_IRQ y define_bool CONFIG_OLD_TIME_C y fi +if [ "$CONFIG_CASIO_E55" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SCSI n +fi +if [ "$CONFIG_MIPS_MIRAGE" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y +fi +if [ "$CONFIG_MIPS_BOSPORUS" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y +fi if [ "$CONFIG_MIPS_PB1000" = "y" ]; then - define_bool CONFIG_MIPS_AU1000 y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1000 y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_AU1000_USB_DEVICE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_PB1100" = "y" ]; then - define_bool CONFIG_MIPS_AU1000 y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1100 y define_bool CONFIG_PCI y define_bool CONFIG_PCI_AUTO n define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_AU1000_USB_DEVICE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_PB1500" = "y" ]; then - define_bool CONFIG_MIPS_AU1000 y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_AU1000_USB_DEVICE y fi -if [ "$CONFIG_ALGOR_P4032" = "y" ]; then +if [ "$CONFIG_MIPS_DB1000" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1000 y + # CONFIG_PCI needed for USB define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO n + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_SWAP_IO_SPACE y +fi +if [ "$CONFIG_MIPS_DB1500" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y +fi +if [ "$CONFIG_MIPS_DB1100" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1100 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_SWAP_IO_SPACE y +fi +if [ "$CONFIG_MIPS_XXS1500" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y +fi +if [ "$CONFIG_MIPS_MTX1" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MIPS_COBALT" = "y" ]; then define_bool CONFIG_COBALT_LCD y define_bool CONFIG_I8259 y define_bool CONFIG_PCI y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y fi if [ "$CONFIG_DECSTATION" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y define_bool CONFIG_IRQ_CPU y - define_bool CONFIG_NEW_IRQ y + define_int CONFIG_L1_CACHE_SHIFT 4 + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y fi if [ "$CONFIG_MIPS_EV64120" = "y" ]; then @@ -187,13 +359,15 @@ define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MIPS_EV96100" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_PCI y + define_bool CONFIG_MIPS_GT64120 y define_bool CONFIG_MIPS_GT96100 y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_IVR" = "y" ]; then define_bool CONFIG_PCI y @@ -202,18 +376,34 @@ define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y define_bool CONFIG_IT8172_CIR y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y fi if [ "$CONFIG_HP_LASERJET" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI y #not yet define_bool CONFIG_PCI_AUTO y fi +if [ "$CONFIG_IBM_WORKPAD" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SCSI n +fi +if [ "$CONFIG_LASAT" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y + define_bool CONFIG_R5000_CPU_SCACHE y + define_bool CONFIG_PCI y + define_bool CONFIG_MIPS_GT64120 y + define_bool CONFIG_MIPS_NILE4 y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_NEW_TIME_C y +fi if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then define_bool CONFIG_PCI y define_bool CONFIG_IT8712 y @@ -222,17 +412,19 @@ define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y define_bool CONFIG_IT8172_CIR y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y fi if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then define_bool CONFIG_BOOT_ELF32 y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_MIPS_BONITO64 y + define_bool CONFIG_MIPS_GT64120 y + define_bool CONFIG_MIPS_MSC y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \ "$CONFIG_OLIVETTI_M700" = "y" ]; then @@ -250,37 +442,47 @@ define_bool CONFIG_BOOT_ELF32 y define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y define_bool CONFIG_I8259 y + define_bool CONFIG_MIPS_BONITO64 y + define_bool CONFIG_MIPS_GT64120 y + define_bool CONFIG_MIPS_MSC y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_PC_KEYB y define_bool CONFIG_PCI y fi if [ "$CONFIG_MIPS_SEAD" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI n fi if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_PCI y define_bool CONFIG_SYSCLK_100 y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MOMENCO_OCELOT_G" = "y" ]; then define_bool CONFIG_PCI y define_bool CONFIG_SYSCLK_100 y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y fi +if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" ]; then + define_bool CONFIG_PCI y + define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_NEW_TIME_C y +fi if [ "$CONFIG_DDB5074" = "y" ]; then define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y define_bool CONFIG_I8259 y @@ -290,7 +492,6 @@ define_bool CONFIG_PC_KEYB y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_PCI y fi @@ -298,7 +499,6 @@ define_bool CONFIG_ISA y define_bool CONFIG_PCI y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_I8259 y define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y @@ -310,19 +510,15 @@ if [ "$CONFIG_DDB5477" = "y" ]; then define_bool CONFIG_PCI y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_PC_KEYB y define_bool CONFIG_I8259 y fi if [ "$CONFIG_NEC_OSPREY" = "y" ]; then define_bool CONFIG_VR4181 y - define_bool CONFIG_SERIAL y - define_bool CONFIG_SERIAL_MANY_PORTS y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y @@ -330,8 +526,6 @@ define_bool CONFIG_SCSI n fi if [ "$CONFIG_NEC_EAGLE" = "y" ]; then - define_bool CONFIG_CPU_VR41XX y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_VR41XX_TIME_C y @@ -344,78 +538,108 @@ define_bool CONFIG_SCSI n fi if [ "$CONFIG_NINO" = "y" ]; then - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y fi if [ "$CONFIG_SGI_IP22" = "y" ]; then define_bool CONFIG_ARC32 y - define_bool CONFIG_ARC_CONSOLE y - define_bool CONFIG_ARC_MEMORY y + define_bool CONFIG_ARC_PROMLIB y define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_BOOT_ELF32 y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W n + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_IRQ_CPU y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_SGI y fi if [ "$CONFIG_SGI_IP27" = "y" ]; then define_bool CONFIG_BOOT_ELF64 y define_bool CONFIG_ARC64 y + define_int CONFIG_L1_CACHE_SHIFT 7 #define_bool CONFIG_MAPPED_PCI_IO y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_QL_ISP_A64 y - define_int CONFIG_L1_CACHE_SHIFT 7 -fi -if [ "$CONFIG_SGI_IP32" = "y" ]; then - define_bool CONFIG_ARC_MEMORY y - define_bool CONFIG_ARC32 y - #define_bool CONFIG_BOARD_SCACHE y - define_bool CONFIG_BOOT_ELF32 y - define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_PC_KEYB y - define_bool CONFIG_PCI y fi -if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - define_bool CONFIG_NEW_IRQ y +if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_DUMMY_KEYB y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_BOOT_ELF32 y fi if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then define_bool CONFIG_ARC32 y define_bool CONFIG_ARC_MEMORY y + define_bool CONFIG_ARC_PROMLIB y define_bool CONFIG_I8259 y define_bool CONFIG_ISA y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y define_bool CONFIG_PC_KEYB y define_bool CONFIG_PCI y fi +if [ "$CONFIG_TANBAC_TB0226" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA n + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SERIAL_MANY_PORTS y +fi +if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA n + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SERIAL_MANY_PORTS y +fi if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then define_bool CONFIG_TOSHIBA_BOARDS y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_PC_KEYB y fi +if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" ]; then + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y + define_bool CONFIG_ISA y + define_bool CONFIG_NONCOHERENT_IO y +fi +if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA n + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SCSI n +fi if [ "$CONFIG_ZAO_CAPCELLA" = "y" ]; then - define_bool CONFIG_CPU_VR41XX y - define_bool CONFIG_CPU_LITTLE_ENDIAN y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_VR41XX_TIME_C y @@ -454,12 +678,8 @@ RM7000 CONFIG_CPU_RM7000 \ SB1 CONFIG_CPU_SB1" R4x00 -if [ "$CONFIG_CPU_R5000" = "y" ]; then - define_bool CONFIG_BOARD_SCACHE y -fi - -if [ "$CONFIG_CPU_NEVADA" = "y" ]; then - define_bool CONFIG_BOARD_SCACHE y +if [ "$CONFIG_SMP_CAPABLE" = "y" ]; then + bool ' Multi-Processing support' CONFIG_SMP fi if [ "$CONFIG_CPU_MIPS32" = "y" ]; then @@ -477,15 +697,14 @@ fi if [ "$CONFIG_CPU_SB1" = "y" ]; then - choice 'SB1 Pass' \ - "Pass1 CONFIG_CPU_SB1_PASS_1 \ - Pass2 CONFIG_CPU_SB1_PASS_2 \ - Pass2.2 CONFIG_CPU_SB1_PASS_2_2" Pass1 + bool ' Use DMA to clear/copy pages' CONFIG_SIBYTE_DMA_PAGEOPS + # SB1 Pass-specific options if [ "$CONFIG_CPU_SB1_PASS_1" = "y" ]; then define_bool CONFIG_SB1_PASS_1_WORKAROUNDS y fi if [ "$CONFIG_CPU_SB1_PASS_2" = "y" ]; then define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y + define_bool CONFIG_SB1_PASS_2_1_WORKAROUNDS y else # Avoid prefetches on Pass 2 (before 2.2) bool ' Enable prefetches' CONFIG_CPU_HAS_PREFETCH @@ -494,9 +713,7 @@ # XXXKW for now, let 2.2 use same WORKAROUNDS flag as pre-2.2 define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y fi - bool ' Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR - dep_bool ' Ignore recoverable cache errors' CONFIG_SB1_CERR_IGNORE_RECOVERABLE $CONFIG_SB1_CACHE_ERROR - dep_bool ' Spin instead of running handler' CONFIG_SB1_CERR_SPIN $CONFIG_SB1_CACHE_ERROR + define_bool CONFIG_VTAG_ICACHE y fi @@ -547,15 +764,51 @@ fi endmenu +# +# Choose endianess of code to generate. It's a frequent trap for users so the +# config file tries it's best to choose the right endianess for those systems +# where we know about their endianess. We only ask the user for systems +# known to be bi-endian; for those systems the defconfig file should defaults +# to the common endianess used for that system. +# mainmenu_option next_comment comment 'General setup' -if [ "$CONFIG_DECSTATION" = "y" -o \ - "$CONFIG_DDB5074" = "y" -o \ - "$CONFIG_NINO" = "y" -o \ - "$CONFIG_MIPS_COBALT" = "y" ]; then +if [ "$CONFIG_ACER_PICA_61" = "y" -o \ + "$CONFIG_CASIO_E55" = "y" -o \ + "$CONFIG_DDB5074" = "y" -o \ + "$CONFIG_DDB5476" = "y" -o \ + "$CONFIG_DDB5477" = "y" -o \ + "$CONFIG_DECSTATION" = "y" -o \ + "$CONFIG_HP_LASERJET" = "y" -o \ + "$CONFIG_IBM_WORKPAD" = "y" -o \ + "$CONFIG_LASAT" = "y" -o \ + "$CONFIG_MIPS_COBALT" = "y" -o \ + "$CONFIG_MIPS_ITE8172" = "y" -o \ + "$CONFIG_MIPS_IVR" = "y" -o \ + "$CONFIG_MIPS_PB1000" = "y" -o \ + "$CONFIG_MIPS_PB1100" = "y" -o \ + "$CONFIG_MIPS_PB1500" = "y" -o \ + "$CONFIG_NEC_OSPREY" = "y" -o \ + "$CONFIG_NEC_EAGLE" = "y" -o \ + "$CONFIG_NINO" = "y" -o \ + "$CONFIG_OLIVETTI_M700" = "y" -o \ + "$CONFIG_SNI_RM200_PCI" = "y" -o \ + "$CONFIG_VICTOR_MPC30X" = "y" -o \ + "$CONFIG_ZAO_CAPCELLA" = "y" ]; then define_bool CONFIG_CPU_LITTLE_ENDIAN y else - bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN + if [ "$CONFIG_BAGET_MIPS" = "y" -o \ + "$CONFIG_MIPS_EV64120" = "y" -o \ + "$CONFIG_MIPS_EV96100" = "y" -o \ + "$CONFIG_MOMENCO_OCELOT" = "y" -o \ + "$CONFIG_MOMENCO_OCELOT_G" = "y" -o \ + "$CONFIG_SGI_IP22" = "y" -o \ + "$CONFIG_SGI_IP27" = "y" -o \ + "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then + define_bool CONFIG_CPU_LITTLE_ENDIAN n + else + bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN + fi fi if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then @@ -564,7 +817,6 @@ if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX - bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD fi if [ "$CONFIG_CPU_R10000" = "y" ]; then @@ -623,11 +875,20 @@ define_bool CONFIG_BINFMT_AOUT n tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF dep_bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT $CONFIG_MIPS64 -define_bool CONFIG_BINFMT_ELF32 $CONFIG_MIPS32_COMPAT +dep_bool 'Kernel support for o32 binaries' CONFIG_MIPS32_O32 $CONFIG_MIPS32_COMPAT +dep_bool 'Kernel support for n32 binaries' CONFIG_MIPS32_N32 $CONFIG_MIPS32_COMPAT +if [ "$CONFIG_MIPS32_O32" = "y" -o \ + "$CONFIG_MIPS32_N32" = "y" ]; then + define_bool CONFIG_BINFMT_ELF32 y +else + define_bool CONFIG_BINFMT_ELF32 n +fi tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC -dep_bool 'Power Management support (EXPERIMENTAL)' CONFIG_PM $CONFIG_EXPERIMENTAL $CONFIG_MIPS_AU1000 +if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + bool 'Power Management support' CONFIG_PM +fi endmenu source drivers/mtd/Config.in @@ -641,6 +902,9 @@ mainmenu_option next_comment comment 'MIPS initrd options' bool ' Embed root filesystem ramdisk into the kernel' CONFIG_EMBEDDED_RAMDISK + if [ "$CONFIG_EMBEDDED_RAMDISK" = "y" ]; then + string ' Filename of gziped ramdisk image' CONFIG_EMBEDDED_RAMDISK_IMAGE ramdisk.gz + fi endmenu fi @@ -675,7 +939,7 @@ fi endmenu -if [ "$CONFIG_PCI" = "y" ]; then +if [ "$CONFIG_PCI" = "y" -a "$CONFIG_MIPS32" = "y" ]; then source drivers/message/i2o/Config.in fi @@ -686,7 +950,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -727,32 +991,6 @@ #source drivers/misc/Config.in -if [ "$CONFIG_DECSTATION" = "y" ]; then - mainmenu_option next_comment - comment 'DECStation Character devices' - - tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL - dep_bool ' DZ11 Serial Support' CONFIG_DZ $CONFIG_SERIAL - dep_bool ' Z85C30 Serial Support' CONFIG_ZS $CONFIG_SERIAL $CONFIG_TC - dep_bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE $CONFIG_SERIAL -# dep_bool 'MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS - bool 'Enhanced Real Time Clock Support' CONFIG_RTC - endmenu -fi - -if [ "$CONFIG_SGI_IP22" = "y" ]; then - mainmenu_option next_comment - comment 'SGI Character devices' - if [ "$CONFIG_VT" = "y" ]; then - tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE - if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then - define_bool CONFIG_FONT_8x16 y - fi - define_bool CONFIG_DUMMY_CONSOLE y - fi - endmenu -fi - source fs/Config.in source drivers/media/Config.in @@ -761,6 +999,13 @@ mainmenu_option next_comment comment 'Console drivers' bool 'VGA text console' CONFIG_VGA_CONSOLE + if [ "$CONFIG_SGI_IP22" = "y" ]; then + tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE + if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then + define_bool CONFIG_FONT_8x16 y + fi + define_bool CONFIG_DUMMY_CONSOLE y + fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE source drivers/video/Config.in @@ -777,10 +1022,6 @@ fi endmenu -if [ "$CONFIG_SGI_IP22" = "y" ]; then - source drivers/sgi/Config.in -fi - source drivers/usb/Config.in source net/bluetooth/Config.in @@ -789,15 +1030,17 @@ comment 'Kernel hacking' bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE -if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_AU1000_UART" = "y" ]; then - bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG - dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_DEBUG +bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG +bool 'Remote GDB kernel debugging' CONFIG_KGDB +dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB +if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + bool 'Compile for Corelis Debugger' CONFIG_SB1XXX_CORELIS fi -bool 'Enable run-time debugging' CONFIG_DEBUG bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ if [ "$CONFIG_SMP" != "y" ]; then bool 'Run uncached' CONFIG_MIPS_UNCACHED fi endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/mips/ddb5074/Makefile linux-2.4.22/arch/mips/ddb5074/Makefile --- linux-2.4.21/arch/mips/ddb5074/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5074/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,18 +0,0 @@ -# -# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines -# under Linux. -# -# 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... -# - -USE_STANDARD_AS_RULE := true - -O_TARGET = ddb5074.a - -obj-y := setup.o irq.o time.o prom.o pci.o int-handler.o nile4.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/ddb5074/int-handler.S linux-2.4.22/arch/mips/ddb5074/int-handler.S --- linux-2.4.21/arch/mips/ddb5074/int-handler.S 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/arch/mips/ddb5074/int-handler.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,120 +0,0 @@ -/* - * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler - * - * Based on arch/mips/sgi/kernel/indyIRQ.S - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include - -/* A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop and moving across - * all the pending IRQ bits in the cause register is _NOT_ the answer, the - * common case is one pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register IRQ mask, that - * would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in - * between like BSD spl() brain-damage. - * - * Furthermore, the IRQs on the INDY look basically (barring software IRQs - * which we don't use at all) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Local IRQ level zero - * 3 Local IRQ level one - * 4 8254 Timer zero - * 5 8254 Timer one - * 6 Bus Error - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Local IRQ zero - * Local IRQ one - * Bus Error - * 8254 Timer zero - * Lowest ---- 8254 Timer one - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - - .text - .set noreorder - .set noat - .align 5 - NESTED(ddbIRQ, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 s0, CP0_CAUSE # get irq mask - -#if 1 - mfc0 t2,CP0_STATUS # get enabled interrupts - and s0,t2 # isolate allowed ones -#endif - /* First we check for r4k counter/timer IRQ. */ - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one - - /* Wheee, local level zero interrupt. */ - jal ddb_local0_irqdispatch - move a0, sp # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error - - /* Wheee, local level one interrupt. */ - move a0, sp - jal ddb_local1_irqdispatch - nop - - j ret_from_irq - nop - -1: - beq a0, zero, 1f - nop - - /* Wheee, an asynchronous bus error... */ - move a0, sp - jal ddb_buserror_irq - nop - - j ret_from_irq - nop - -1: - /* Here by mistake? This is possible, what can happen - * is that by the time we take the exception the IRQ - * pin goes low, so just leave if this is the case. - */ - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) - beq a0, zero, 1f - - /* Must be one of the 8254 timers... */ - move a0, sp - jal ddb_8254timer_irq - nop -1: - j ret_from_irq - nop - END(ddbIRQ) diff -urN linux-2.4.21/arch/mips/ddb5074/irq.c linux-2.4.22/arch/mips/ddb5074/irq.c --- linux-2.4.21/arch/mips/ddb5074/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5074/irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,226 +0,0 @@ -/* - * arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -extern void __init i8259_init(void); -extern void i8259_disable_irq(unsigned int irq_nr); -extern void i8259_enable_irq(unsigned int irq_nr); - -extern asmlinkage void ddbIRQ(void); -extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - - -void no_action(int cpl, void *dev_id, struct pt_regs *regs) -{ -} - - -#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ -#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ -#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */ - -#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */ -#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */ -#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */ - -#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */ -#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */ - -#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */ -#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */ - -#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */ -#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */ - - -static void m1543_irq_setup(void) -{ - /* - * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all - * the possible IO sources in the M1543 are in use by us. We will - * use the following mapping: - * - * IRQ1 - keyboard (default set by M1543) - * IRQ3 - reserved for UART B (default set by M1543) (note that - * the schematics for the DDB Vrc-5074 board seem to - * indicate that IRQ3 is connected to the DS1386 - * watchdog timer interrupt output so we might have - * a conflict) - * IRQ4 - reserved for UART A (default set by M1543) - * IRQ5 - parallel (default set by M1543) - * IRQ8 - DS1386 time of day (RTC) interrupt - * IRQ12 - mouse - */ - - /* - * Assing mouse interrupt to IRQ12 - */ - - /* Enter configuration mode */ - outb(0x51, M1543_PNP_CONFIG); - outb(0x23, M1543_PNP_CONFIG); - - /* Select logical device 7 (Keyboard) */ - outb(0x07, M1543_PNP_INDEX); - outb(0x07, M1543_PNP_DATA); - - /* Select IRQ12 */ - outb(0x72, M1543_PNP_INDEX); - outb(0x0c, M1543_PNP_DATA); - - /* Leave configration mode */ - outb(0xbb, M1543_PNP_CONFIG); - - - /* Initialize the 8259 PIC in the M1543 */ - i8259_init(); - - /* Enable the interrupt cascade */ - nile4_enable_irq(NILE4_INT_INTE); - - request_region(M1543_PNP_CONFIG, 2, "M1543 config"); - request_region(M1543_INT1_MASTER_ELCR, 2, "pic ELCR"); -} - -static void nile4_irq_setup(void) -{ - int i; - - /* Map all interrupts to CPU int #0 */ - nile4_map_irq_all(0); - - /* PCI INTA#-E# must be level triggered */ - nile4_set_pci_irq_level_or_edge(0, 1); - nile4_set_pci_irq_level_or_edge(1, 1); - nile4_set_pci_irq_level_or_edge(2, 1); - nile4_set_pci_irq_level_or_edge(3, 1); - nile4_set_pci_irq_level_or_edge(4, 1); - - /* PCI INTA#-D# must be active low, INTE# must be active high */ - nile4_set_pci_irq_polarity(0, 0); - nile4_set_pci_irq_polarity(1, 0); - nile4_set_pci_irq_polarity(2, 0); - nile4_set_pci_irq_polarity(3, 0); - nile4_set_pci_irq_polarity(4, 1); - - for (i = 0; i < 16; i++) - nile4_clear_irq(i); - - /* Enable CPU int #0 */ - nile4_enable_irq_output(0); - - request_mem_region(NILE4_BASE, NILE4_SIZE, "Nile 4"); -} - - -/* - * IRQ2 is cascade interrupt to second interrupt controller - */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL }; - - -void disable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_disable_irq(irq_nr); - else - nile4_disable_irq(irq_to_nile4(irq_nr)); -} - -void enable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_enable_irq(irq_nr); - else - nile4_enable_irq(irq_to_nile4(irq_nr)); -} - -int table[16] = { 0, }; - -void ddb_local0_irqdispatch(struct pt_regs *regs) -{ - u32 mask; - int nile4_irq; -#if 1 - volatile static int nesting = 0; - if (nesting++ == 0) - ddb5074_led_d3(1); - ddb5074_led_hex(nesting < 16 ? nesting : 15); -#endif - - mask = nile4_get_irq_stat(0); - nile4_clear_irq_mask(mask); - - /* Handle the timer interrupt first */ - if (mask & (1 << NILE4_INT_GPT)) { - nile4_disable_irq(NILE4_INT_GPT); - do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs); - nile4_enable_irq(NILE4_INT_GPT); - mask &= ~(1 << NILE4_INT_GPT); - } - for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) - if (mask & 1) { - nile4_disable_irq(nile4_irq); - if (nile4_irq == NILE4_INT_INTE) { - int i8259_irq = nile4_i8259_iack(); - i8259_do_irq(i8259_irq, regs); - } else - do_IRQ(nile4_to_irq(nile4_irq), regs); - nile4_enable_irq(nile4_irq); - } -#if 1 - if (--nesting == 0) - ddb5074_led_d3(0); - ddb5074_led_hex(nesting < 16 ? nesting : 15); -#endif -} - -void ddb_local1_irqdispatch(void) -{ - printk("ddb_local1_irqdispatch called\n"); -} - -void ddb_buserror_irq(void) -{ - printk("ddb_buserror_irq called\n"); -} - -void ddb_8254timer_irq(void) -{ - printk("ddb_8254timer_irq called\n"); -} - -void __init ddb_irq_setup(void) -{ -#ifdef CONFIG_REMOTE_DEBUG - if (remote_debug) - set_debug_traps(); - breakpoint(); /* you may move this line to whereever you want :-) */ -#endif - request_region(0x20, 0x20, "pic1"); - request_region(0xa0, 0x20, "pic2"); - i8259_setup_irq(2, &irq2); - - nile4_irq_setup(); - m1543_irq_setup(); - - set_except_vector(0, ddbIRQ); -} diff -urN linux-2.4.21/arch/mips/ddb5074/nile4.c linux-2.4.22/arch/mips/ddb5074/nile4.c --- linux-2.4.21/arch/mips/ddb5074/nile4.c 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/arch/mips/ddb5074/nile4.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,292 +0,0 @@ -/* - * arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include - -#include - - -/* - * Physical Device Address Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, - int on_memory_bus, int visible) -{ - u32 maskbits; - u32 widthbits; - - if (pdar > NILE4_BOOTCS || (pdar & 7)) { - printk("nile4_set_pdar: invalid pdar %d\n", pdar); - return; - } - if (pdar == NILE4_INTCS && size != 0x00200000) { - printk("nile4_set_pdar: INTCS size must be 2 MB\n"); - return; - } - switch (size) { -#if 0 /* We don't support 4 GB yet */ - case 0x100000000: /* 4 GB */ - maskbits = 4; - break; -#endif - case 0x80000000: /* 2 GB */ - maskbits = 5; - break; - case 0x40000000: /* 1 GB */ - maskbits = 6; - break; - case 0x20000000: /* 512 MB */ - maskbits = 7; - break; - case 0x10000000: /* 256 MB */ - maskbits = 8; - break; - case 0x08000000: /* 128 MB */ - maskbits = 9; - break; - case 0x04000000: /* 64 MB */ - maskbits = 10; - break; - case 0x02000000: /* 32 MB */ - maskbits = 11; - break; - case 0x01000000: /* 16 MB */ - maskbits = 12; - break; - case 0x00800000: /* 8 MB */ - maskbits = 13; - break; - case 0x00400000: /* 4 MB */ - maskbits = 14; - break; - case 0x00200000: /* 2 MB */ - maskbits = 15; - break; - case 0: /* OFF */ - maskbits = 0; - break; - default: - printk("nile4_set_pdar: unsupported size %p\n", (void *) size); - return; - } - switch (width) { - case 8: - widthbits = 0; - break; - case 16: - widthbits = 1; - break; - case 32: - widthbits = 2; - break; - case 64: - widthbits = 3; - break; - default: - printk("nile4_set_pdar: unsupported width %d\n", width); - return; - } - nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) | - (visible ? 0x20 : 0) | (widthbits << 6) | - (phys & 0xffe00000)); - nile4_out32(pdar + 4, 0); - /* - * When programming a PDAR, the register should be read immediately - * after writing it. This ensures that address decoders are properly - * configured. - */ - nile4_in32(pdar); - nile4_in32(pdar + 4); -} - - -/* - * PCI Master Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pmr(u32 pmr, u32 type, u32 addr) -{ - if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) { - printk("nile4_set_pmr: invalid pmr %d\n", pmr); - return; - } - switch (type) { - case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */ - case NILE4_PCICMD_IO: /* PCI I/O Space */ - case NILE4_PCICMD_MEM: /* PCI Memory Space */ - case NILE4_PCICMD_CFG: /* PCI Configuration Space */ - break; - default: - printk("nile4_set_pmr: invalid type %d\n", type); - return; - } - nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000)); - nile4_out32(pmr + 4, 0); -} - - -/* - * Interrupt Programming - */ -void nile4_map_irq(int nile4_irq, int cpu_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(7 << (nile4_irq * 4)); - t |= cpu_irq << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_map_irq_all(int cpu_irq) -{ - u32 all, t; - - all = cpu_irq; - all |= all << 4; - all |= all << 8; - all |= all << 16; - t = nile4_in32(NILE4_INTCTRL); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL, t); - t = nile4_in32(NILE4_INTCTRL + 4); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL + 4, t); -} - -void nile4_enable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t |= 8 << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_disable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(8 << (nile4_irq * 4)); - nile4_out32(offset, t); -} - -void nile4_disable_irq_all(void) -{ - nile4_out32(NILE4_INTCTRL, 0); - nile4_out32(NILE4_INTCTRL + 4, 0); -} - -u16 nile4_get_irq_stat(int cpu_irq) -{ - return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2); -} - -void nile4_enable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t |= 1 << (16 + cpu_irq); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_disable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t &= ~(1 << (16 + cpu_irq)); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_set_pci_irq_polarity(int pci_irq, int high) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (high) - t &= ~(1 << (pci_irq * 2)); - else - t |= 1 << (pci_irq * 2); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_set_pci_irq_level_or_edge(int pci_irq, int level) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (level) - t |= 2 << (pci_irq * 2); - else - t &= ~(2 << (pci_irq * 2)); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_clear_irq(int nile4_irq) -{ - nile4_out32(NILE4_INTCLR, 1 << nile4_irq); -} - -void nile4_clear_irq_mask(u32 mask) -{ - nile4_out32(NILE4_INTCLR, mask); -} - -u8 nile4_i8259_iack(void) -{ - u8 irq; - - /* Set window 0 for interrupt acknowledge */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0); - irq = *(volatile u8 *) NILE4_PCI_IACK_BASE; - /* Set window 0 for PCI I/O space */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0); - return irq; -} - -#if 0 -void nile4_dump_irq_status(void) -{ - printk("CPUSTAT = %p:%p\n", (void *) nile4_in32(NILE4_CPUSTAT + 4), - (void *) nile4_in32(NILE4_CPUSTAT)); - printk("INTCTRL = %p:%p\n", (void *) nile4_in32(NILE4_INTCTRL + 4), - (void *) nile4_in32(NILE4_INTCTRL)); - printk("INTSTAT0 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT0 + 4), - (void *) nile4_in32(NILE4_INTSTAT0)); - printk("INTSTAT1 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT1 + 4), - (void *) nile4_in32(NILE4_INTSTAT1)); - printk("INTCLR = %p:%p\n", (void *) nile4_in32(NILE4_INTCLR + 4), - (void *) nile4_in32(NILE4_INTCLR)); - printk("INTPPES = %p:%p\n", (void *) nile4_in32(NILE4_INTPPES + 4), - (void *) nile4_in32(NILE4_INTPPES)); -} -#endif diff -urN linux-2.4.21/arch/mips/ddb5074/pci.c linux-2.4.22/arch/mips/ddb5074/pci.c --- linux-2.4.21/arch/mips/ddb5074/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5074/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,425 +0,0 @@ -/* - * arch/mips/ddb5074/pci.c -- NEC DDB Vrc-5074 PCI access routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Albert Dorofeev - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include -#include -#include - -#include - - -static u32 nile4_pre_pci_access0(int slot_num) -{ - u32 pci_addr = 0; - u32 virt_addr = NILE4_PCI_CFG_BASE; - - /* Set window 1 address 8000000 - 64 bit - 2 MB (PCI config space) */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x00200000, 64, 0, - 0); - if (slot_num > 2) - pci_addr = 0x00040000 << slot_num; - else - virt_addr += 0x00040000 << slot_num; - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr); - return virt_addr; -} - -static void nile4_post_pci_access0(void) -{ - /* - * Set window 1 back to address 8000000 - 64 bit - 128 MB - * (PCI IO space) - */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE), - 0x08000000, 64, 1, 1); - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0); -} - - -static int nile4_pci_read_config_dword(struct pci_dev *dev, - int where, u32 * val) -{ - int slot_num, func_num; - u32 base; - - /* - * For starters let's do configuration cycle 0 only (one bus only) - */ - if (dev->bus->number) - return PCIBIOS_FUNC_NOT_SUPPORTED; - - slot_num = PCI_SLOT(dev->devfn); - func_num = PCI_FUNC(dev->devfn); - if (slot_num == 5) { - /* - * This is Nile 4 and it will crash if we access it like other - * devices - */ - *val = nile4_in32(NILE4_PCI_BASE + where); - return PCIBIOS_SUCCESSFUL; - } - base = nile4_pre_pci_access0(slot_num); - *val = - *((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))); - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_write_config_dword(struct pci_dev *dev, int where, - u32 val) -{ - int slot_num, func_num; - u32 base; - - /* - * For starters let's do configuration cycle 0 only (one bus only) - */ - if (dev->bus->number) - return PCIBIOS_FUNC_NOT_SUPPORTED; - - slot_num = PCI_SLOT(dev->devfn); - func_num = PCI_FUNC(dev->devfn); - if (slot_num == 5) { - /* - * This is Nile 4 and it will crash if we access it like other - * devices - */ - nile4_out32(NILE4_PCI_BASE + where, val); - return PCIBIOS_SUCCESSFUL; - } - base = nile4_pre_pci_access0(slot_num); - *((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))) = - val; - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_read_config_word(struct pci_dev *dev, int where, - u16 * val) -{ - int status; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - result >>= 16; - *val = result & 0xffff; - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_read_config_byte(struct pci_dev *dev, int where, - u8 * val) -{ - int status; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 1) - result >>= 8; - if (where & 2) - result >>= 16; - *val = result & 0xff; - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_write_config_word(struct pci_dev *dev, int where, - u16 val) -{ - int status, shift = 0; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - shift += 16; - result &= ~(0xffff << shift); - result |= val << shift; - return nile4_pci_write_config_dword(dev, where, result); -} - -static int nile4_pci_write_config_byte(struct pci_dev *dev, int where, - u8 val) -{ - int status, shift = 0; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - shift += 16; - if (where & 1) - shift += 8; - result &= ~(0xff << shift); - result |= val << shift; - return nile4_pci_write_config_dword(dev, where, result); -} - -struct pci_ops nile4_pci_ops = { - nile4_pci_read_config_byte, - nile4_pci_read_config_word, - nile4_pci_read_config_dword, - nile4_pci_write_config_byte, - nile4_pci_write_config_word, - nile4_pci_write_config_dword -}; - -struct { - struct resource ram; - struct resource flash; - struct resource isa_io; - struct resource pci_io; - struct resource isa_mem; - struct resource pci_mem; - struct resource nile4; - struct resource boot; -} ddb5074_resources = { - { "RAM", 0x00000000, 0x03ffffff, - IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64}, - { "Flash ROM", 0x04000000, 0x043fffff}, - { "Nile4 ISA I/O", 0x06000000, 0x060fffff}, - { "Nile4 PCI I/O", 0x06100000, 0x07ffffff}, - { "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM}, - { "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM}, - { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, - IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64}, - { "Boot ROM", 0x1fc00000, 0x1fffffff} -}; - -static void __init ddb5074_pci_fixup(void) -{ - struct pci_dev *dev; - - pci_for_each_dev(dev) { - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_NILE4) { - /* - * The first 64-bit PCI base register should point to - * the Nile4 control registers. Unfortunately this - * isn't the case, so we fix it ourselves. This allows - * the serial driver to find the UART. - */ - dev->resource[0] = ddb5074_resources.nile4; - request_resource(&iomem_resource, - &dev->resource[0]); - /* - * The second 64-bit PCI base register points to the - * first memory bank. Unfortunately the address is - * wrong, so we fix it (again). - */ - dev->resource[2] = ddb5074_resources.ram; - request_resource(&iomem_resource, - &dev->resource[2]); - } else if (dev->vendor == PCI_VENDOR_ID_AL - && dev->device == PCI_DEVICE_ID_AL_M7101) { - /* - * It's nice to have the LEDs on the GPIO pins - * available for debugging - */ - extern struct pci_dev *pci_pmu; - u8 t8; - - pci_pmu = dev; /* for LEDs D2 and D3 */ - /* Program the lines for LEDs D2 and D3 to output */ - nile4_pci_read_config_byte(dev, 0x7d, &t8); - t8 |= 0xc0; - nile4_pci_write_config_byte(dev, 0x7d, t8); - /* Turn LEDs D2 and D3 off */ - nile4_pci_read_config_byte(dev, 0x7e, &t8); - t8 |= 0xc0; - nile4_pci_write_config_byte(dev, 0x7e, t8); - } - } -} - -static void __init pcibios_fixup_irqs(void) -{ - struct pci_dev *dev; - int slot_num; - - pci_for_each_dev(dev) { - slot_num = PCI_SLOT(dev->devfn); - switch (slot_num) { - case 0: - dev->irq = nile4_to_irq(NILE4_INT_INTE); - break; - case 1: - dev->irq = nile4_to_irq(NILE4_INT_INTA); - break; - case 2: /* slot 1 */ - dev->irq = nile4_to_irq(NILE4_INT_INTA); - break; - case 3: /* slot 2 */ - dev->irq = nile4_to_irq(NILE4_INT_INTB); - break; - case 4: /* slot 3 */ - dev->irq = nile4_to_irq(NILE4_INT_INTC); - break; - case 5: - /* - * Fixup so the serial driver can use the UART - */ - dev->irq = nile4_to_irq(NILE4_INT_UART); - break; - case 13: - dev->irq = nile4_to_irq(NILE4_INT_INTE); - break; - default: - break; - } - } -} - -void __init pcibios_init(void) -{ - printk("PCI: Probing PCI hardware\n"); - ioport_resource.end = 0x1ffffff; /* 32 MB */ - iomem_resource.end = 0x1fffffff; /* 512 MB */ - /* `ram' and `nile4' are requested through the Nile4 pci_dev */ - request_resource(&iomem_resource, &ddb5074_resources.flash); - request_resource(&iomem_resource, &ddb5074_resources.isa_io); - request_resource(&iomem_resource, &ddb5074_resources.pci_io); - request_resource(&iomem_resource, &ddb5074_resources.isa_mem); - request_resource(&iomem_resource, &ddb5074_resources.pci_mem); - request_resource(&iomem_resource, &ddb5074_resources.boot); - - pci_scan_bus(0, &nile4_pci_ops, NULL); - ddb5074_pci_fixup(); - pci_assign_unassigned_resources(); - pcibios_fixup_irqs(); -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - bus->resource[1] = &ddb5074_resources.pci_mem; -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus, - struct pbus_set_ranges_data *ranges) -{ - ranges->io_start -= bus->resource[0]->start; - ranges->io_end -= bus->resource[0]->start; - ranges->mem_start -= bus->resource[1]->start; - ranges->mem_end -= bus->resource[1]->start; -} - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - /* - * Don't touch the Nile 4 - */ - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_NILE4) return 0; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* - * Somebody might have asked allocation of a non-standard - * resource - */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -struct pci_fixup pcibios_fixups[] = { }; diff -urN linux-2.4.21/arch/mips/ddb5074/prom.c linux-2.4.22/arch/mips/ddb5074/prom.c --- linux-2.4.21/arch/mips/ddb5074/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ddb5074/prom.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,41 +0,0 @@ -/* - * arch/mips/ddb5074/prom.c -- NEC DDB Vrc-5074 PROM routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include - -#include -#include - - -char arcs_cmdline[CL_SIZE]; - -const char *get_system_type(void) -{ - return "NEC DDB Vrc-5074"; -} - -void __init prom_init(const char *s) -{ - int i = 0; - - if (s != (void *) -1) - while (*s && i < sizeof(arcs_cmdline) - 1) - arcs_cmdline[i++] = *s++; - arcs_cmdline[i] = '\0'; - - mips_machgroup = MACH_GROUP_NEC_DDB; - mips_machtype = MACH_NEC_DDB5074; - - /* 64 MB non-upgradable */ - add_memory_region(0, 64 << 20, BOOT_MEM_RAM); -} - -void __init prom_free_prom_memory(void) -{ -} diff -urN linux-2.4.21/arch/mips/ddb5074/setup.c linux-2.4.22/arch/mips/ddb5074/setup.c --- linux-2.4.21/arch/mips/ddb5074/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5074/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,251 +0,0 @@ -/* - * arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef CONFIG_REMOTE_DEBUG -extern void rs_kgdb_hook(int); -extern void breakpoint(void); -#endif - -#if defined(CONFIG_SERIAL_CONSOLE) -extern void console_setup(char *); -#endif - -extern struct ide_ops std_ide_ops; -extern struct rtc_ops ddb_rtc_ops; - -static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000; - -static void ddb_machine_restart(char *command) -{ - u32 t; - - /* PCI cold reset */ - t = nile4_in32(NILE4_PCICTRL + 4); - t |= 0x40000000; - nile4_out32(NILE4_PCICTRL + 4, t); - /* CPU cold reset */ - t = nile4_in32(NILE4_CPUSTAT); - t |= 1; - nile4_out32(NILE4_CPUSTAT, t); - /* Call the PROM */ - back_to_prom(); -} - -static void ddb_machine_halt(void) -{ - printk("DDB Vrc-5074 halted.\n"); - do { - } while (1); -} - -static void ddb_machine_power_off(void) -{ - printk("DDB Vrc-5074 halted. Please turn off the power.\n"); - do { - } while (1); -} - -extern void ddb_irq_setup(void); - -void (*board_time_init) (struct irqaction * irq); - - -static void __init ddb_time_init(struct irqaction *irq) -{ - /* set the clock to 1 Hz */ - nile4_out32(NILE4_T2CTRL, 1000000); - /* enable the General-Purpose Timer */ - nile4_out32(NILE4_T2CTRL + 4, 0x00000001); - /* reset timer */ - nile4_out32(NILE4_T2CNTR, 0); - /* enable interrupt */ - nile4_enable_irq(NILE4_INT_GPT); - i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); - change_cp0_status(ST0_IM, - IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); -} - - -void __init bus_error_init(void) { /* nothing */ } - - -void __init ddb_setup(void) -{ - extern int panic_timeout; - - irq_setup = ddb_irq_setup; - set_io_port_base(NILE4_PCI_IO_BASE); - isa_slot_offset = NILE4_PCI_MEM_BASE; - request_region(0x00, 0x20, "dma1"); - request_region(0x40, 0x20, "timer"); - request_region(0x70, 0x10, "rtc"); - request_region(0x80, 0x10, "dma page reg"); - request_region(0xc0, 0x20, "dma2"); - board_time_init = ddb_time_init; - - _machine_restart = ddb_machine_restart; - _machine_halt = ddb_machine_halt; - _machine_power_off = ddb_machine_power_off; - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - rtc_ops = &ddb_rtc_ops; - - /* Reboot on panic */ - panic_timeout = 180; -} - - -#define USE_NILE4_SERIAL 0 - -#if USE_NILE4_SERIAL -#define ns16550_in(reg) nile4_in8((reg)*8) -#define ns16550_out(reg, val) nile4_out8((reg)*8, (val)) -#else -#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8) -static inline u8 ns16550_in(u32 reg) -{ - return *(volatile u8 *) (NS16550_BASE + reg); -} - -static inline void ns16550_out(u32 reg, u8 val) -{ - *(volatile u8 *) (NS16550_BASE + reg) = val; -} -#endif - -#define NS16550_RBR 0 -#define NS16550_THR 0 -#define NS16550_DLL 0 -#define NS16550_IER 1 -#define NS16550_DLM 1 -#define NS16550_FCR 2 -#define NS16550_IIR 2 -#define NS16550_LCR 3 -#define NS16550_MCR 4 -#define NS16550_LSR 5 -#define NS16550_MSR 6 -#define NS16550_SCR 7 - -#define NS16550_LSR_DR 0x01 /* Data ready */ -#define NS16550_LSR_OE 0x02 /* Overrun */ -#define NS16550_LSR_PE 0x04 /* Parity error */ -#define NS16550_LSR_FE 0x08 /* Framing error */ -#define NS16550_LSR_BI 0x10 /* Break */ -#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */ -#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */ -#define NS16550_LSR_ERR 0x80 /* Error */ - - -void _serinit(void) -{ -#if USE_NILE4_SERIAL - ns16550_out(NS16550_LCR, 0x80); - ns16550_out(NS16550_DLM, 0x00); - ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */ - ns16550_out(NS16550_LCR, 0x00); - ns16550_out(NS16550_LCR, 0x03); - ns16550_out(NS16550_FCR, 0x47); -#else - /* done by PMON */ -#endif -} - -void _putc(char c) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, c); - if (c == '\n') { - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, '\r'); - } -} - -void _puts(const char *s) -{ - char c; - while ((c = *s++)) - _putc(c); -} - -char _getc(void) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR)); - return ns16550_in(NS16550_RBR); -} - -int _testc(void) -{ - return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0; -} - - -/* - * Hexadecimal 7-segment LED - */ -void ddb5074_led_hex(int hex) -{ - outb(hex, 0x80); -} - - -/* - * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543 - */ -struct pci_dev *pci_pmu = NULL; - -void ddb5074_led_d2(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0x7f; - else - t |= 0x80; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} - -void ddb5074_led_d3(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0xbf; - else - t |= 0x40; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} diff -urN linux-2.4.21/arch/mips/ddb5074/time.c linux-2.4.22/arch/mips/ddb5074/time.c --- linux-2.4.21/arch/mips/ddb5074/time.c 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/arch/mips/ddb5074/time.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,32 +0,0 @@ -/* - * arch/mips/ddb5074/time.c -- Timer routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include - -static unsigned char ddb_rtc_read_data(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - - return inb_p(RTC_PORT(1)); -} - -static void ddb_rtc_write_data(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -static int ddb_rtc_bcd_mode(void) -{ - return 1; -} - -struct rtc_ops ddb_rtc_ops = { - ddb_rtc_read_data, - ddb_rtc_write_data, - ddb_rtc_bcd_mode -}; diff -urN linux-2.4.21/arch/mips/ddb5xxx/common/irq.c linux-2.4.22/arch/mips/ddb5xxx/common/irq.c --- linux-2.4.21/arch/mips/ddb5xxx/common/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/common/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -19,7 +19,7 @@ void __init init_IRQ(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern void set_debug_traps(void); diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5074/irq.c linux-2.4.22/arch/mips/ddb5xxx/ddb5074/irq.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5074/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5074/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,14 +6,15 @@ */ #include #include +#include #include #include #include #include #include +#include #include -#include #include #include #include @@ -21,14 +22,7 @@ #include -extern void __init i8259_init(void); -extern void init_i8259_irqs (void); -extern void i8259_disable_irq(unsigned int irq_nr); -extern void i8259_enable_irq(unsigned int irq_nr); - extern asmlinkage void ddbIRQ(void); -extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; @@ -142,7 +136,7 @@ void __init ddb_irq_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) set_debug_traps(); breakpoint(); /* you may move this line to whereever you want :-) */ diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5074/nile4_pic.c linux-2.4.22/arch/mips/ddb5xxx/ddb5074/nile4_pic.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5074/nile4_pic.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5074/nile4_pic.c 2003-08-25 04:44:39.000000000 -0700 @@ -260,7 +260,7 @@ } -#if defined(CONFIG_LL_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) void nile4_dump_irq_status(void) { printk(KERN_DEBUG " diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5074/pci.c linux-2.4.22/arch/mips/ddb5xxx/ddb5074/pci.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5074/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5074/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -9,22 +9,24 @@ #include static struct resource extpci_io_resource = { - "pci IO space", - 0x1000, /* leave some room for ISA bus */ - DDB_PCI_IO_SIZE -1, - IORESOURCE_IO}; + "pci IO space", + 0x1000, /* leave some room for ISA bus */ + DDB_PCI_IO_SIZE - 1, + IORESOURCE_IO +}; static struct resource extpci_mem_resource = { - "pci memory space", - DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */ - DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE -1, - IORESOURCE_MEM}; + "pci memory space", + DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */ + DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1, + IORESOURCE_MEM +}; extern struct pci_ops ddb5476_ext_pci_ops; struct pci_channel mips_pci_channels[] = { - { &ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource }, - { NULL, NULL, NULL} + {&ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource}, + {NULL, NULL, NULL} }; #define PCI_EXT_INTA 8 @@ -52,7 +54,8 @@ /* SLOT: 13 */ nile4_to_irq(PCI_EXT_INTE), }; -void __init pcibios_fixup_irqs(void) { +void __init pcibios_fixup_irqs(void) +{ struct pci_dev *dev; int slot_num; @@ -60,12 +63,12 @@ pci_for_each_dev(dev) { slot_num = PCI_SLOT(dev->devfn); db_assert(slot_num < MAX_SLOT_NUM); -printk("irq_map[%d]: %02x\n",slot_num, irq_map[slot_num]); + printk("irq_map[%d]: %02x\n", slot_num, irq_map[slot_num]); db_assert(irq_map[slot_num] != 0xff); pci_write_config_byte(dev, - PCI_INTERRUPT_LINE, - irq_map[slot_num]); + PCI_INTERRUPT_LINE, + irq_map[slot_num]); dev->irq = irq_map[slot_num]; } @@ -73,27 +76,27 @@ void __init ddb_pci_reset_bus(void) { - u32 temp; + u32 temp; - /* - * I am not sure about the "official" procedure, the following - * steps work as far as I know: - * We first set PCI cold reset bit (bit 31) in PCICTRL-H. - * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. - * The same is true for both PCI channels. - */ - temp = ddb_in32(DDB_PCICTRL+4); - temp |= 0x80000000; - ddb_out32(DDB_PCICTRL+4, temp); - temp &= ~0xc0000000; - ddb_out32(DDB_PCICTRL+4, temp); + /* + * I am not sure about the "official" procedure, the following + * steps work as far as I know: + * We first set PCI cold reset bit (bit 31) in PCICTRL-H. + * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. + * The same is true for both PCI channels. + */ + temp = ddb_in32(DDB_PCICTRL + 4); + temp |= 0x80000000; + ddb_out32(DDB_PCICTRL + 4, temp); + temp &= ~0xc0000000; + ddb_out32(DDB_PCICTRL + 4, temp); } unsigned __init int pcibios_assign_all_busses(void) { - /* we hope pci_auto has assigned the bus numbers to all buses */ - return 1; + /* we hope pci_auto has assigned the bus numbers to all buses */ + return 1; } void __init pcibios_fixup_resources(struct pci_dev *dev) @@ -106,25 +109,24 @@ pci_for_each_dev(dev) { if (dev->vendor == PCI_VENDOR_ID_AL && - dev->device == PCI_DEVICE_ID_AL_M7101) { - /* - * It's nice to have the LEDs on the GPIO pins - * available for debugging - */ - extern struct pci_dev *pci_pmu; - u8 t8; - - pci_pmu = dev; /* for LEDs D2 and D3 */ - /* Program the lines for LEDs D2 and D3 to output */ - pci_read_config_byte(dev, 0x7d, &t8); - t8 |= 0xc0; - pci_write_config_byte(dev, 0x7d, t8); - /* Turn LEDs D2 and D3 off */ - pci_read_config_byte(dev, 0x7e, &t8); - t8 |= 0xc0; - pci_write_config_byte(dev, 0x7e, t8); + dev->device == PCI_DEVICE_ID_AL_M7101) { + /* + * It's nice to have the LEDs on the GPIO pins + * available for debugging + */ + extern struct pci_dev *pci_pmu; + u8 t8; + + pci_pmu = dev; /* for LEDs D2 and D3 */ + /* Program the lines for LEDs D2 and D3 to output */ + pci_read_config_byte(dev, 0x7d, &t8); + t8 |= 0xc0; + pci_write_config_byte(dev, 0x7d, t8); + /* Turn LEDs D2 and D3 off */ + pci_read_config_byte(dev, 0x7e, &t8); + t8 |= 0xc0; + pci_write_config_byte(dev, 0x7e, t8); } } } - diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5074/pci_ops.c linux-2.4.22/arch/mips/ddb5xxx/ddb5074/pci_ops.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5074/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5074/pci_ops.c 2003-08-25 04:44:39.000000000 -0700 @@ -49,8 +49,6 @@ DDB_PCI_CONFIG_SIZE }; -static int pci_config_workaround=1; - /* * access config space */ @@ -63,12 +61,8 @@ u32 virt_addr = swap->config_base; u32 option; - if (pci_config_workaround) { - if (slot_num == 5) slot_num = 14; - } - else { - if (slot_num == 5) return DDB_BASE + DDB_PCI_BASE; - } + if (slot_num == 5) + slot_num = 14; /* minimum pdar (window) size is 2MB */ db_assert(swap->config_size >= (2 << 20)); @@ -279,64 +273,3 @@ extpci_write_config_word, extpci_write_config_dword }; - - -#if defined(CONFIG_DEBUG) -void jsun_scan_pci_bus(void) -{ - struct pci_bus bus; - struct pci_dev dev; - unsigned int devfn; - int j; - - pci_config_workaround = 0; - - bus.parent = NULL; /* we scan the top level only */ - dev.bus = &bus; - dev.sysdata = NULL; - - /* scan ext pci bus and io pci bus*/ - for (j=0; j< 1; j++) { - printk(KERN_INFO "scan ddb5476 external PCI bus:\n"); - bus.ops = &ddb5476_ext_pci_ops; - - for (devfn = 0; devfn < 0x100; devfn += 8) { - u32 temp; - u16 temp16; - u8 temp8; - int i; - - dev.devfn = devfn; - db_verify(pci_read_config_dword(&dev, 0, &temp), - == PCIBIOS_SUCCESSFUL); - if (temp == 0xffffffff) continue; - - printk(KERN_INFO "slot %d: (addr %d) \n", devfn/8, - 11+devfn/8); - - /* verify read word and byte */ - db_verify(pci_read_config_word(&dev, 2, &temp16), - == PCIBIOS_SUCCESSFUL); - db_assert(temp16 == (temp >> 16)); - db_verify(pci_read_config_byte(&dev, 3, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == (temp >> 24)); - db_verify(pci_read_config_byte(&dev, 1, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == ((temp >> 8) & 0xff)); - - for (i=0; i < 16; i++) { - if ((i%4) == 0) - printk(KERN_INFO); - db_verify(pci_read_config_dword(&dev, i*4, &temp), - == PCIBIOS_SUCCESSFUL); - printk("\t%08X", temp); - if ((i%4) == 3) - printk("\n"); - } - } - } - - pci_config_workaround = 1; -} -#endif diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5074/setup.c linux-2.4.22/arch/mips/ddb5xxx/ddb5074/setup.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5074/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5074/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -31,7 +31,7 @@ #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void breakpoint(void); #endif @@ -81,10 +81,6 @@ extern void (*board_timer_setup) (struct irqaction * irq); -void __init bus_error_init(void) -{ -} - static void __init ddb_timer_init(struct irqaction *irq) { /* set the clock to 1 Hz */ @@ -96,7 +92,7 @@ /* enable interrupt */ setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); nile4_enable_irq(nile4_to_irq(NILE4_INT_GPT)); - change_cp0_status(ST0_IM, + change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); } diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5476/Makefile linux-2.4.22/arch/mips/ddb5xxx/ddb5476/Makefile --- linux-2.4.21/arch/mips/ddb5xxx/ddb5476/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5476/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -15,6 +15,6 @@ obj-y += setup.o irq.o int-handler.o pci.o pci_ops.o \ nile4_pic.o vrc5476_irq.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_KGDB) += dbg_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5476/irq.c linux-2.4.22/arch/mips/ddb5xxx/ddb5476/irq.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5476/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5476/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -14,6 +14,7 @@ #include #include +#include #include #include diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5476/nile4_pic.c linux-2.4.22/arch/mips/ddb5xxx/ddb5476/nile4_pic.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5476/nile4_pic.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5476/nile4_pic.c 2003-08-25 04:44:39.000000000 -0700 @@ -163,7 +163,7 @@ return irq + I8259_IRQ_BASE; } -#if defined(CONFIG_LL_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) void nile4_dump_irq_status(void) { printk(KERN_DEBUG " diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5476/pci.c linux-2.4.22/arch/mips/ddb5xxx/ddb5476/pci.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5476/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5476/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -100,10 +100,6 @@ } } -#if defined(CONFIG_DEBUG) -extern void jsun_scan_pci_bus(void); -#endif - void __init ddb_pci_reset_bus(void) { u32 temp; diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5476/pci_ops.c linux-2.4.22/arch/mips/ddb5xxx/ddb5476/pci_ops.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5476/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5476/pci_ops.c 2003-08-25 04:44:39.000000000 -0700 @@ -49,8 +49,6 @@ DDB_PCI_CONFIG_SIZE }; -static int pci_config_workaround=1; - /* * access config space */ @@ -63,27 +61,11 @@ u32 virt_addr = swap->config_base; u32 option; - if (pci_config_workaround) { - /* [jsun] work around Vrc5476 controller itself, returnning - * slot 0 essentially makes vrc5476 invisible - */ - if (slot_num == 12) slot_num = 0; - -#if 0 - /* BUG : skip P2P bridge for now */ - if (slot_num == 5) slot_num = 0; -#endif - - } else { - /* now we have to be hornest, returning the true - * PCI config headers for vrc5476 - */ - if (slot_num == 12) { - swap->pdar_backup = ddb_in32(swap->pdar); - swap->pmr_backup = ddb_in32(swap->pmr); - return DDB_BASE + DDB_PCI_BASE; - } - } + /* + * BUG: skip host PCI controller. Its BARS are bogus. + */ + if (slot_num == 12) + slot_num = 0; /* minimum pdar (window) size is 2MB */ db_assert(swap->config_size >= (2 << 20)); @@ -294,64 +276,3 @@ extpci_write_config_word, extpci_write_config_dword }; - - -#if defined(CONFIG_DEBUG) -void jsun_scan_pci_bus(void) -{ - struct pci_bus bus; - struct pci_dev dev; - unsigned int devfn; - int j; - - pci_config_workaround = 0; - - bus.parent = NULL; /* we scan the top level only */ - dev.bus = &bus; - dev.sysdata = NULL; - - /* scan ext pci bus and io pci bus*/ - for (j=0; j< 1; j++) { - printk(KERN_INFO "scan ddb5476 external PCI bus:\n"); - bus.ops = &ddb5476_ext_pci_ops; - - for (devfn = 0; devfn < 0x100; devfn += 8) { - u32 temp; - u16 temp16; - u8 temp8; - int i; - - dev.devfn = devfn; - db_verify(pci_read_config_dword(&dev, 0, &temp), - == PCIBIOS_SUCCESSFUL); - if (temp == 0xffffffff) continue; - - printk(KERN_INFO "slot %d: (addr %d) \n", devfn/8, - 11+devfn/8); - - /* verify read word and byte */ - db_verify(pci_read_config_word(&dev, 2, &temp16), - == PCIBIOS_SUCCESSFUL); - db_assert(temp16 == (temp >> 16)); - db_verify(pci_read_config_byte(&dev, 3, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == (temp >> 24)); - db_verify(pci_read_config_byte(&dev, 1, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == ((temp >> 8) & 0xff)); - - for (i=0; i < 16; i++) { - if ((i%4) == 0) - printk(KERN_INFO); - db_verify(pci_read_config_dword(&dev, i*4, &temp), - == PCIBIOS_SUCCESSFUL); - printk("\t%08X", temp); - if ((i%4) == 3) - printk("\n"); - } - } - } - - pci_config_workaround = 1; -} -#endif diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5476/setup.c linux-2.4.22/arch/mips/ddb5xxx/ddb5476/setup.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5476/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5476/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -41,7 +41,7 @@ #define TIMER_IRQ (VRC5476_IRQ_BASE + VRC5476_IRQ_GPT) #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); #endif @@ -103,8 +103,8 @@ setup_irq(CPU_IRQ_BASE + 7, irq); /* to generate the first timer interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register(CP0_COMPARE, count + 1000); + count = read_c0_count(); + write_c0_compare(count + 1000); #else @@ -140,9 +140,6 @@ }; -void __init bus_error_init(void) { /* nothing */ } - - static void ddb5476_board_init(void); extern void ddb5476_irq_setup(void); extern void (*irq_setup)(void); diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c linux-2.4.22/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -12,6 +12,7 @@ */ #include #include +#include #include #include @@ -81,7 +82,6 @@ asmlinkage void vrc5476_irq_dispatch(struct pt_regs *regs) { - extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void spurious_interrupt(void); u32 mask; diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5477/Makefile linux-2.4.22/arch/mips/ddb5xxx/ddb5477/Makefile --- linux-2.4.21/arch/mips/ddb5xxx/ddb5477/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5477/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -12,8 +12,7 @@ obj-y += int-handler.o irq.o irq_5477.o setup.o pci.o pci_ops.o lcd44780.o -obj-$(CONFIG_DEBUG) += debug.o -obj-$(CONFIG_REMOTE_DEBUG) += kgdb_io.o -obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o +obj-$(CONFIG_RUNTIME_DEBUG) += debug.o +obj-$(CONFIG_KGDB) += kgdb_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5477/debug.c linux-2.4.22/arch/mips/ddb5xxx/ddb5477/debug.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5477/debug.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5477/debug.c 2003-08-25 04:44:39.000000000 -0700 @@ -56,8 +56,8 @@ void vrc5477_show_int_regs() { jsun_show_regs("interrupt registers", int_regs); - printk("CPU CAUSE = %08x\n", read_32bit_cp0_register(CP0_CAUSE)); - printk("CPU STATUS = %08x\n", read_32bit_cp0_register(CP0_STATUS)); + printk("CPU CAUSE = %08x\n", read_c0_cause()); + printk("CPU STATUS = %08x\n", read_c0_status()); } static Register pdar_regs[] = { {"DDB_SDRAM0", DDB_BASE + DDB_SDRAM0}, diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5477/int-handler.S linux-2.4.22/arch/mips/ddb5xxx/ddb5477/int-handler.S --- linux-2.4.21/arch/mips/ddb5xxx/ddb5477/int-handler.S 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5477/int-handler.S 2003-08-25 04:44:39.000000000 -0700 @@ -14,6 +14,7 @@ #include #include #include +#include /* * first level interrupt dispatcher for ocelot board - @@ -55,20 +56,20 @@ j ret_from_irq ll_cputimer_irq: - li a0, 7 + li a0, CPU_IRQ_BASE + 7 move a1, sp jal do_IRQ j ret_from_irq ll_cpu_ip0: - li a0, 0 + li a0, CPU_IRQ_BASE + 0 move a1, sp jal do_IRQ j ret_from_irq ll_cpu_ip1: - li a0, 1 + li a0, CPU_IRQ_BASE + 1 move a1, sp jal do_IRQ j ret_from_irq diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5477/irq.c linux-2.4.22/arch/mips/ddb5xxx/ddb5477/irq.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5477/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5477/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -13,9 +13,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -71,7 +73,6 @@ ddb_out32(pci, reg_value); } -extern void init_i8259_irqs (void); extern void vrc5477_irq_init(u32 base); extern void mips_cpu_irq_init(u32 base); extern asmlinkage void ddb5477_handle_int(void); @@ -90,8 +91,8 @@ ddb_out32(DDB_INTCTRL2, 0); ddb_out32(DDB_INTCTRL3, 0); - clear_cp0_status(0xff00); - set_cp0_status(0x0400); + clear_c0_status(0xff00); + set_c0_status(0x0400); /* setup PCI interrupt attributes */ set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE); @@ -164,8 +165,6 @@ asmlinkage void vrc5477_irq_dispatch(struct pt_regs *regs) { - extern unsigned int do_IRQ(int irq, struct pt_regs *regs); - u32 intStatus; u32 bitmask; u32 i; @@ -176,7 +175,7 @@ db_assert(ddb_in32(DDB_NMISTAT) == 0); if (ddb_in32(DDB_INT1STAT) != 0) { -#if defined(CONFIG_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) vrc5477_show_int_regs(); #endif panic("error interrupt has happened."); diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5477/pci.c linux-2.4.22/arch/mips/ddb5xxx/ddb5477/pci.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5477/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5477/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -166,10 +166,6 @@ } } -#if defined(CONFIG_DEBUG) -extern void jsun_scan_pci_bus(void); -extern void jsun_assign_pci_resource(void); -#endif void ddb_pci_reset_bus(void) { u32 temp; @@ -204,6 +200,33 @@ { } +/* + * fixup baseboard AMD chip so that tx does not underflow. + * bcr_18 |= 0x0800 + * This sets NOUFLO bit which makes tx not start until whole pkt + * is fetched to the chip. + */ +#define PCNET32_WIO_RDP 0x10 +#define PCNET32_WIO_RAP 0x12 +#define PCNET32_WIO_RESET 0x14 +#define PCNET32_WIO_BDP 0x16 +void __init fix_amd_lance(struct pci_dev *dev) +{ + unsigned long ioaddr; + u16 temp; + + ioaddr=pci_resource_start(dev, 0); + + inw(ioaddr + PCNET32_WIO_RESET); /* reset chip */ + + /* bcr_18 |= 0x0800 */ + outw (18, ioaddr + PCNET32_WIO_RAP); + temp = inw (ioaddr + PCNET32_WIO_BDP); + temp |= 0x0800; + outw (18, ioaddr + PCNET32_WIO_RAP); + outw (temp, ioaddr + PCNET32_WIO_BDP); +} + void __init pcibios_fixup(void) { if (mips_machtype == MACH_NEC_ROCKHOPPERII) { @@ -241,6 +264,10 @@ pci_read_config_byte(dev, 0x41, &old); pci_write_config_byte(dev, 0x41, old | 0xd0); } + + if (dev->vendor == PCI_VENDOR_ID_AMD && + dev->device == PCI_DEVICE_ID_AMD_LANCE) + fix_amd_lance(dev); } } diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5477/pci_ops.c linux-2.4.22/arch/mips/ddb5xxx/ddb5477/pci_ops.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5477/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5477/pci_ops.c 2003-08-25 04:44:39.000000000 -0700 @@ -299,4 +299,3 @@ iopci_write_config_word, iopci_write_config_dword }; - diff -urN linux-2.4.21/arch/mips/ddb5xxx/ddb5477/setup.c linux-2.4.22/arch/mips/ddb5xxx/ddb5477/setup.c --- linux-2.4.21/arch/mips/ddb5xxx/ddb5477/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/ddb5xxx/ddb5477/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -43,12 +43,10 @@ #include "lcd44780.h" -// #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ +#define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ -#ifndef USE_CPU_COUNTER_TIMER #define SP_TIMER_BASE DDB_SPT1CTRL_L #define SP_TIMER_IRQ VRC5477_IRQ_SPT1 -#endif static int bus_frequency = CONFIG_DDB5477_BUS_FREQUENCY*1000; @@ -88,38 +86,36 @@ unsigned char c; unsigned int t1, t2; unsigned i; - unsigned preset_freq[]={ - 0, 83330000, 100000000, 124000000,133300000, 0xffffffff}; ddb_out32(SP_TIMER_BASE, 0xffffffff); ddb_out32(SP_TIMER_BASE+4, 0x1); ddb_out32(SP_TIMER_BASE+8, 0xffffffff); - c= *(volatile unsigned char*)rtc_base; - for(i=0; (i<100000000) && (c == *(volatile unsigned char*)rtc_base); i++); + /* check if rtc is running */ + c= *(volatile unsigned char*)rtc_base; + for(i=0; (c == *(volatile unsigned char*)rtc_base) && (i<100000000); i++); if (c == *(volatile unsigned char*)rtc_base) { printk("Failed to detect bus frequency. Use default 83.3MHz.\n"); return 83333000; } - /* we are now at the turn of 1/100th second */ - t1 = ddb_in32(SP_TIMER_BASE+8); - c= *(volatile unsigned char*)rtc_base; while (c == *(volatile unsigned char*)rtc_base); + /* we are now at the turn of 1/100th second, if no error. */ + t1 = ddb_in32(SP_TIMER_BASE+8); - /* we are now at the turn of another 1/100th second */ - t2 = ddb_in32(SP_TIMER_BASE+8); - ddb_out32(SP_TIMER_BASE+4, 0x0); /* disable it again */ - freq = (t1 - t2)*100; + for (i=0; i< 10; i++) { + c= *(volatile unsigned char*)rtc_base; + while (c == *(volatile unsigned char*)rtc_base); + /* we are now at the turn of another 1/100th second */ + t2 = ddb_in32(SP_TIMER_BASE+8); + } - /* find the nearest preset freq */ - for (i=0; freq > preset_freq[i+1]; i++); - if ((freq - preset_freq[i]) >= (preset_freq[i+1]-freq)) - i++; + ddb_out32(SP_TIMER_BASE+4, 0x0); /* disable it again */ - printk("DDB bus frequency detection : %d -> %d\n", freq, preset_freq[i]); - return preset_freq[i]; + freq = (t1 - t2)*10; + printk("DDB bus frequency detection : %u \n", freq); + return freq; } extern void rtc_ds1386_init(unsigned long base); @@ -143,8 +139,8 @@ } /* mips_counter_frequency is 1/2 of the cpu core freq */ - i = (read_32bit_cp0_register(CP0_CONFIG) >> 28 ) & 7; - if ((mips_cpu.cputype == CPU_R5432) && (i == 3)) + i = (read_c0_config() >> 28 ) & 7; + if ((current_cpu_data.cputype == CPU_R5432) && (i == 3)) i = 4; mips_counter_frequency = bus_frequency*(i+4)/4; } @@ -158,10 +154,6 @@ /* we are using the cpu counter for timer interrupts */ setup_irq(CPU_IRQ_BASE + 7, irq); - /* to generate the first timer interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register(CP0_COMPARE, count + 1000); - #else /* if we use Special purpose timer 1 */ @@ -172,8 +164,6 @@ #endif } -void __init bus_error_init(void) { /* nothing */ } - static void ddb5477_board_init(void); extern void ddb5477_irq_setup(void); diff -urN linux-2.4.21/arch/mips/dec/Makefile linux-2.4.22/arch/mips/dec/Makefile --- linux-2.4.21/arch/mips/dec/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -12,9 +12,10 @@ all: dec.o -export-objs := setup.o wbflush.o -obj-y := int-handler.o ioasic-irq.o kn02-irq.o reset.o rtc-dec.o setup.o \ - time.o +export-objs := rtc-dec.o setup.o wbflush.o + +obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn02-irq.o reset.o \ + rtc-dec.o setup.o time.o obj-$(CONFIG_PROM_CONSOLE) += promcon.o obj-$(CONFIG_CPU_HAS_WB) += wbflush.o diff -urN linux-2.4.21/arch/mips/dec/ecc-berr.c linux-2.4.22/arch/mips/dec/ecc-berr.c --- linux-2.4.21/arch/mips/dec/ecc-berr.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/ecc-berr.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,280 @@ +/* + * linux/arch/mips/dec/ecc-berr.c + * + * Bus error event handling code for systems equipped with ECC + * handling logic, i.e. DECstation/DECsystem 5000/200 (KN02), + * 5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03), + * 5900/260 (KN05) systems. + * + * Copyright (c) 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static volatile u32 *kn0x_erraddr; +static volatile u32 *kn0x_chksyn; + +static inline void dec_ecc_be_ack(void) +{ + *kn0x_erraddr = 0; /* any write clears the IRQ */ + iob(); +} + +static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker) +{ + static const char excstr[] = "exception"; + static const char intstr[] = "interrupt"; + static const char cpustr[] = "CPU"; + static const char dmastr[] = "DMA"; + static const char readstr[] = "read"; + static const char mreadstr[] = "memory read"; + static const char writestr[] = "write"; + static const char mwritstr[] = "partial memory write"; + static const char timestr[] = "timeout"; + static const char overstr[] = "overrun"; + static const char eccstr[] = "ECC error"; + + const char *kind, *agent, *cycle, *event; + const char *status = "", *xbit = "", *fmt = ""; + dma_addr_t address; + u16 syn = 0, sngl; + + int i = 0; + + u32 erraddr = *kn0x_erraddr; + u32 chksyn = *kn0x_chksyn; + int action = MIPS_BE_FATAL; + + /* For non-ECC ack ASAP, so any subsequent errors get caught. */ + if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID) + dec_ecc_be_ack(); + + kind = invoker ? intstr : excstr; + + if (!(erraddr & KN0X_EAR_VALID)) { + /* No idea what happened. */ + printk(KERN_ALERT "Unindentified bus error %s.\n", kind); + return action; + } + + agent = (erraddr & KN0X_EAR_CPU) ? cpustr : dmastr; + + if (erraddr & KN0X_EAR_ECCERR) { + /* An ECC error on a CPU or DMA transaction. */ + cycle = (erraddr & KN0X_EAR_WRITE) ? mwritstr : mreadstr; + event = eccstr; + } else { + /* A CPU timeout or a DMA overrun. */ + cycle = (erraddr & KN0X_EAR_WRITE) ? writestr : readstr; + event = (erraddr & KN0X_EAR_CPU) ? timestr : overstr; + } + + address = erraddr & KN0X_EAR_ADDRESS; + /* For ECC errors on reads adjust for MT pipelining. */ + if ((erraddr & (KN0X_EAR_WRITE | KN0X_EAR_ECCERR)) == KN0X_EAR_ECCERR) + address = (address & ~0xfffLL) | ((address - 5) & 0xfffLL); + address <<= 2; + + /* Only CPU errors are fixable. */ + if (erraddr & KN0X_EAR_CPU && is_fixup) + action = MIPS_BE_FIXUP; + + if (erraddr & KN0X_EAR_ECCERR) { + static const u8 data_sbit[32] = { + 0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, + 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34, + 0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, + 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75, + }; + static const u8 data_mbit[25] = { + 0x07, 0x0d, 0x1f, + 0x2f, 0x32, 0x37, 0x38, 0x3b, 0x3d, 0x3e, + 0x43, 0x45, 0x46, 0x49, 0x4c, 0x51, 0x5e, + 0x61, 0x6e, 0x73, 0x76, 0x79, 0x7a, 0x7c, 0x7f, + }; + static const char sbestr[] = "corrected single"; + static const char dbestr[] = "uncorrectable double"; + static const char mbestr[] = "uncorrectable multiple"; + + if (!(address & 0x4)) + syn = chksyn; /* Low bank. */ + else + syn = chksyn >> 16; /* High bank. */ + + if (!(syn & KN0X_ESR_VLDLO)) { + /* Ack now, no rewrite will happen. */ + dec_ecc_be_ack(); + + fmt = KERN_ALERT "%s" "invalid.\n"; + } else { + sngl = syn & KN0X_ESR_SNGLO; + syn &= KN0X_ESR_SYNLO; + + /* + * Multibit errors may be tagged incorrectly; + * check the syndrome explicitly. + */ + for (i = 0; i < 25; i++) + if (syn == data_mbit[i]) + break; + + if (i < 25) { + status = mbestr; + } else if (!sngl) { + status = dbestr; + } else { + volatile u32 *ptr = (void *)KSEG1ADDR(address); + + *ptr = *ptr; /* Rewrite. */ + iob(); + + status = sbestr; + action = MIPS_BE_DISCARD; + } + + /* Ack now, now we've rewritten (or not). */ + dec_ecc_be_ack(); + + if (syn && syn == (syn & -syn)) { + if (syn == 0x01) { + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error " + "at check bit C%s.\n"; + xbit = "X"; + } else { + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error " + "at check bit C%s%u.\n"; + } + i = syn >> 2; + } else { + for (i = 0; i < 32; i++) + if (syn == data_sbit[i]) + break; + if (i < 32) + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error " + "at data bit D%s%u.\n"; + else + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error.\n"; + } + } + } + + if (action != MIPS_BE_FIXUP) + printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx.\n", + kind, agent, cycle, event, address); + + if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR) + printk(fmt, " ECC syndrome ", syn, status, xbit, i); + + return action; +} + +int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup) +{ + return dec_ecc_be_backend(regs, is_fixup, 0); +} + +void dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int action = dec_ecc_be_backend(regs, 0, 1); + + if (action == MIPS_BE_DISCARD) + return; + + /* + * FIXME: Find affected processes and kill them, otherwise we + * must die. + * + * The interrupt is asynchronously delivered thus EPC and RA + * may be irrelevant, but are printed for a reference. + */ + printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n", + regs->cp0_epc, regs->regs[31]); + die("Unrecoverable bus error", regs); +} + + +/* + * Initialization differs a bit between KN02 and KN03/KN05, so we + * need two variants. Once set up, all systems can be handled the + * same way. + */ +static inline void dec_kn02_be_init(void) +{ + volatile u32 *csr = (void *)KN02_CSR_BASE; + unsigned long flags; + + kn0x_erraddr = (void *)(KN02_SLOT_BASE + KN02_ERRADDR); + kn0x_chksyn = (void *)(KN02_SLOT_BASE + KN02_CHKSYN); + + spin_lock_irqsave(&kn02_lock, flags); + + /* Preset write-only bits of the Control Register cache. */ + cached_kn02_csr = *csr | KN03_CSR_LEDS; + + /* Set normal ECC detection and generation. */ + cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN); + /* Enable ECC correction. */ + cached_kn02_csr |= KN02_CSR_CORRECT; + *csr = cached_kn02_csr; + iob(); + + spin_unlock_irqrestore(&kn02_lock, flags); +} + +static inline void dec_kn03_be_init(void) +{ + volatile u32 *mcr = (void *)(KN03_SLOT_BASE + IOASIC_MCR); + volatile u32 *mbcs = (void *)(KN03_SLOT_BASE + KN05_MB_CSR); + + kn0x_erraddr = (void *)(KN03_SLOT_BASE + IOASIC_ERRADDR); + kn0x_chksyn = (void *)(KN03_SLOT_BASE + IOASIC_CHKSYN); + + /* + * Set normal ECC detection and generation, enable ECC correction. + * For KN05 we also need to make sure EE (?) is enabled in the MB. + * Otherwise DBE/IBE exceptions would be masked but bus error + * interrupts would still arrive, resulting in an inevitable crash + * if get_dbe() triggers one. + */ + *mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) | + KN03_MCR_CORRECT; + if (current_cpu_data.cputype == CPU_R4400SC) + *mbcs |= KN05_MB_CSR_EE; + fast_iob(); +} + +void __init dec_ecc_be_init(void) +{ + if (mips_machtype == MACH_DS5000_200) + dec_kn02_be_init(); + else + dec_kn03_be_init(); + + /* Clear any leftover errors from the firmware. */ + dec_ecc_be_ack(); +} diff -urN linux-2.4.21/arch/mips/dec/int-handler.S linux-2.4.22/arch/mips/dec/int-handler.S --- linux-2.4.21/arch/mips/dec/int-handler.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/int-handler.S 2003-08-25 04:44:39.000000000 -0700 @@ -2,7 +2,7 @@ * arch/mips/dec/int-handler.S * * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen - * Copyright (C) 2000, 2001, 2002 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki * * Written by Ralf Baechle and Andreas Busse, modified for DECStation * support by Paul Antoine and Harald Koerfgen. @@ -132,19 +132,23 @@ */ mfc0 t0,CP0_CAUSE # get pending interrupts mfc0 t1,CP0_STATUS +#ifdef CONFIG_MIPS32 lw t2,cpu_fpu_mask +#endif andi t0,ST0_IM # CAUSE.CE may be non-zero! and t0,t1 # isolate allowed ones beqz t0,spurious +#ifdef CONFIG_MIPS32 and t2,t0 bnez t2,fpu # handle FPU immediately +#endif /* * Find irq with highest priority */ - la t1,cpu_mask_nr_tbl + PTR_LA t1,cpu_mask_nr_tbl 1: lw t2,(t1) nop and t2,t0 @@ -161,14 +165,16 @@ nop jr a0 # a trick to save a branch: - lui t2,KN03_IOASIC_BASE>>16 # upper part of IOASIC Address + lui t2,(KN03_IOASIC_BASE>>16)&0xffff + # upper part of IOASIC Address /* * Handle "IRQ Controller" Interrupts * Masked Interrupts are still visible and have to be masked "by hand". */ FEXPORT(kn02_io_int) # 3max - lui t0,KN02_CSR_ADDR>>16 # get interrupt status and mask + lui t0,(KN02_CSR_BASE>>16)&0xffff + # get interrupt status and mask lw t0,(t0) nop andi t1,t0,KN02_IRQ_ALL @@ -176,11 +182,12 @@ srl t0,16 # shift interrupt mask FEXPORT(kn02xa_io_int) # 3min/maxine - lui t2,KN02XA_IOASIC_BASE>>16 # upper part of IOASIC Address + lui t2,(KN02XA_IOASIC_BASE>>16)&0xffff + # upper part of IOASIC Address FEXPORT(kn03_io_int) # 3max+ (t2 loaded earlier) - lw t0,SIR(t2) # get status: IOASIC isr - lw t1,SIMR(t2) # get mask: IOASIC isrm + lw t0,IO_REG_SIR(t2) # get status: IOASIC sir + lw t1,IO_REG_SIMR(t2) # get mask: IOASIC simr nop 1: and t0,t1 # mask out allowed ones @@ -190,7 +197,7 @@ /* * Find irq with highest priority */ - la t1,asic_mask_nr_tbl + PTR_LA t1,asic_mask_nr_tbl 2: lw t2,(t1) nop and t2,t0 @@ -263,9 +270,11 @@ j ret_from_irq nop +#ifdef CONFIG_MIPS32 fpu: j handle_fpe_int nop +#endif spurious: j spurious_interrupt diff -urN linux-2.4.21/arch/mips/dec/ioasic-irq.c linux-2.4.22/arch/mips/dec/ioasic-irq.c --- linux-2.4.21/arch/mips/dec/ioasic-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/ioasic-irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -3,7 +3,7 @@ * * DEC I/O ASIC interrupts. * - * Copyright (c) 2002 Maciej W. Rozycki + * Copyright (c) 2002, 2003 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,18 +30,18 @@ { u32 simr; - simr = ioasic_read(SIMR); + simr = ioasic_read(IO_REG_SIMR); simr |= (1 << (irq - ioasic_irq_base)); - ioasic_write(SIMR, simr); + ioasic_write(IO_REG_SIMR, simr); } static inline void mask_ioasic_irq(unsigned int irq) { u32 simr; - simr = ioasic_read(SIMR); + simr = ioasic_read(IO_REG_SIMR); simr &= ~(1 << (irq - ioasic_irq_base)); - ioasic_write(SIMR, simr); + ioasic_write(IO_REG_SIMR, simr); } static inline void clear_ioasic_irq(unsigned int irq) @@ -49,7 +49,7 @@ u32 sir; sir = ~(1 << (irq - ioasic_irq_base)); - ioasic_write(SIR, sir); + ioasic_write(IO_REG_SIR, sir); } static inline void enable_ioasic_irq(unsigned int irq) @@ -93,17 +93,14 @@ enable_ioasic_irq(irq); } -#define set_ioasic_affinity NULL - static struct hw_interrupt_type ioasic_irq_type = { - "IO-ASIC", - startup_ioasic_irq, - shutdown_ioasic_irq, - enable_ioasic_irq, - disable_ioasic_irq, - ack_ioasic_irq, - end_ioasic_irq, - set_ioasic_affinity, + .typename = "IO-ASIC", + .startup = startup_ioasic_irq, + .shutdown = shutdown_ioasic_irq, + .enable = enable_ioasic_irq, + .disable = disable_ioasic_irq, + .ack = ack_ioasic_irq, + .end = end_ioasic_irq, }; @@ -124,17 +121,14 @@ end_ioasic_irq(irq); } -#define set_ioasic_dma_affinity set_ioasic_affinity - static struct hw_interrupt_type ioasic_dma_irq_type = { - "IO-ASIC-DMA", - startup_ioasic_dma_irq, - shutdown_ioasic_dma_irq, - enable_ioasic_dma_irq, - disable_ioasic_dma_irq, - ack_ioasic_dma_irq, - end_ioasic_dma_irq, - set_ioasic_dma_affinity, + .typename = "IO-ASIC-DMA", + .startup = startup_ioasic_dma_irq, + .shutdown = shutdown_ioasic_dma_irq, + .enable = enable_ioasic_dma_irq, + .disable = disable_ioasic_dma_irq, + .ack = ack_ioasic_dma_irq, + .end = end_ioasic_dma_irq, }; @@ -143,7 +137,7 @@ int i; /* Mask interrupts. */ - ioasic_write(SIMR, 0); + ioasic_write(IO_REG_SIMR, 0); fast_iob(); for (i = base; i < base + IO_INR_DMA; i++) { diff -urN linux-2.4.21/arch/mips/dec/kn02-irq.c linux-2.4.22/arch/mips/dec/kn02-irq.c --- linux-2.4.21/arch/mips/dec/kn02-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/kn02-irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ * DECstation 5000/200 (KN02) Control and Status Register * interrupts. * - * Copyright (c) 2002 Maciej W. Rozycki + * Copyright (c) 2002, 2003 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -37,7 +37,7 @@ static inline void unmask_kn02_irq(unsigned int irq) { - volatile u32 *csr = (volatile u32 *)KN02_CSR_ADDR; + volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE; cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16)); *csr = cached_kn02_csr; @@ -45,7 +45,7 @@ static inline void mask_kn02_irq(unsigned int irq) { - volatile u32 *csr = (volatile u32 *)KN02_CSR_ADDR; + volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE; cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16)); *csr = cached_kn02_csr; @@ -92,29 +92,29 @@ enable_kn02_irq(irq); } -#define set_kn02_affinity NULL - static struct hw_interrupt_type kn02_irq_type = { - "KN02-CSR", - startup_kn02_irq, - shutdown_kn02_irq, - enable_kn02_irq, - disable_kn02_irq, - ack_kn02_irq, - end_kn02_irq, - set_kn02_affinity, + .typename = "KN02-CSR", + .startup = startup_kn02_irq, + .shutdown = shutdown_kn02_irq, + .enable = enable_kn02_irq, + .disable = disable_kn02_irq, + .ack = ack_kn02_irq, + .end = end_kn02_irq, }; void __init init_kn02_irqs(int base) { - volatile u32 *csr = (volatile u32 *)KN02_CSR_ADDR; + volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE; + unsigned long flags; int i; - /* Mask interrupts and preset write-only bits. */ - cached_kn02_csr = (*csr & ~0xff0000) | 0xff; + /* Mask interrupts. */ + spin_lock_irqsave(&kn02_lock, flags); + cached_kn02_csr &= ~KN03_CSR_IOINTEN; *csr = cached_kn02_csr; iob(); + spin_unlock_irqrestore(&kn02_lock, flags); for (i = base; i < base + KN02_IRQ_LINES; i++) { irq_desc[i].status = IRQ_DISABLED; diff -urN linux-2.4.21/arch/mips/dec/prom/Makefile linux-2.4.22/arch/mips/dec/prom/Makefile --- linux-2.4.21/arch/mips/dec/prom/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/dec/prom/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -12,6 +12,9 @@ L_TARGET = rexlib.a -obj-y += init.o memory.o cmdline.o identify.o locore.o +obj-y += init.o memory.o cmdline.o identify.o + +obj-$(CONFIG_MIPS32) += locore.o +obj-$(CONFIG_MIPS64) += call_o32.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/dec/prom/call_o32.S linux-2.4.22/arch/mips/dec/prom/call_o32.S --- linux-2.4.21/arch/mips/dec/prom/call_o32.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/prom/call_o32.S 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * arch/mips/dec/call_o32.S + * + * O32 interface for the 64 (or N32) ABI. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include + +/* Maximum number of arguments supported. Must be even! */ +#define O32_ARGC 32 +/* Number of static registers we save. */ +#define O32_STATC 11 +/* Frame size for both of the above. */ +#define O32_FRAMESZ (4 * O32_ARGC + SZREG * O32_STATC) + + .text + +/* + * O32 function call dispatcher, for interfacing 32-bit ROM routines. + * + * The standard 64 (N32) calling sequence is supported, with a0 + * holding a function pointer, a1-a7 -- its first seven arguments + * and the stack -- remaining ones (up to O32_ARGC, including a1-a7). + * Static registers, gp and fp are preserved, v0 holds a result. + * This code relies on the called o32 function for sp and ra + * restoration and thus both this dispatcher and the current stack + * have to be placed in a KSEGx (or KUSEG) address space. Any + * pointers passed have to point to addresses within one of these + * spaces as well. + */ +NESTED(call_o32, O32_FRAMESZ, ra) + REG_SUBU sp,O32_FRAMESZ + + REG_S ra,O32_FRAMESZ-1*SZREG(sp) + REG_S fp,O32_FRAMESZ-2*SZREG(sp) + REG_S gp,O32_FRAMESZ-3*SZREG(sp) + REG_S s7,O32_FRAMESZ-4*SZREG(sp) + REG_S s6,O32_FRAMESZ-5*SZREG(sp) + REG_S s5,O32_FRAMESZ-6*SZREG(sp) + REG_S s4,O32_FRAMESZ-7*SZREG(sp) + REG_S s3,O32_FRAMESZ-8*SZREG(sp) + REG_S s2,O32_FRAMESZ-9*SZREG(sp) + REG_S s1,O32_FRAMESZ-10*SZREG(sp) + REG_S s0,O32_FRAMESZ-11*SZREG(sp) + + move jp,a0 + + sll a0,a1,zero + sll a1,a2,zero + sll a2,a3,zero + sll a3,a4,zero + sw a5,0x10(sp) + sw a6,0x14(sp) + sw a7,0x18(sp) + + PTR_LA t0,O32_FRAMESZ(sp) + PTR_LA t1,0x1c(sp) + li t2,O32_ARGC-7 +1: + lw t3,(t0) + REG_ADDU t0,SZREG + sw t3,(t1) + REG_SUBU t2,1 + REG_ADDU t1,4 + bnez t2,1b + + jalr jp + + REG_L s0,O32_FRAMESZ-11*SZREG(sp) + REG_L s1,O32_FRAMESZ-10*SZREG(sp) + REG_L s2,O32_FRAMESZ-9*SZREG(sp) + REG_L s3,O32_FRAMESZ-8*SZREG(sp) + REG_L s4,O32_FRAMESZ-7*SZREG(sp) + REG_L s5,O32_FRAMESZ-6*SZREG(sp) + REG_L s6,O32_FRAMESZ-5*SZREG(sp) + REG_L s7,O32_FRAMESZ-4*SZREG(sp) + REG_L gp,O32_FRAMESZ-3*SZREG(sp) + REG_L fp,O32_FRAMESZ-2*SZREG(sp) + REG_L ra,O32_FRAMESZ-1*SZREG(sp) + + REG_ADDU sp,O32_FRAMESZ + jr ra +END(call_o32) diff -urN linux-2.4.21/arch/mips/dec/prom/cmdline.c linux-2.4.22/arch/mips/dec/prom/cmdline.c --- linux-2.4.21/arch/mips/dec/prom/cmdline.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/dec/prom/cmdline.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,32 +6,30 @@ #include #include #include +#include #include - -#include "prom.h" +#include #undef PROM_DEBUG -#ifdef PROM_DEBUG -extern int (*prom_printf)(char *, ...); -#endif - char arcs_cmdline[CL_SIZE]; -void __init prom_init_cmdline(int argc, char **argv, unsigned long magic) +void __init prom_init_cmdline(s32 argc, s32 *argv, u32 magic) { + char *arg; int start_arg, i; /* * collect args and prepare cmd_line */ - if (magic != REX_PROM_MAGIC) + if (!prom_is_rex(magic)) start_arg = 1; else start_arg = 2; for (i = start_arg; i < argc; i++) { - strcat(arcs_cmdline, argv[i]); + arg = (void *)(long)(argv[i]); + strcat(arcs_cmdline, arg); if (i < (argc - 1)) strcat(arcs_cmdline, " "); } @@ -39,6 +37,4 @@ #ifdef PROM_DEBUG prom_printf("arcs_cmdline: %s\n", &(arcs_cmdline[0])); #endif - } - diff -urN linux-2.4.21/arch/mips/dec/prom/identify.c linux-2.4.22/arch/mips/dec/prom/identify.c --- linux-2.4.21/arch/mips/dec/prom/identify.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/prom/identify.c 2003-08-25 04:44:39.000000000 -0700 @@ -2,50 +2,104 @@ * identify.c: machine identification code. * * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include #include +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "dectypes.h" -#include "prom.h" - -extern char *(*prom_getenv)(char *); -extern int (*prom_printf)(char *, ...); -extern int (*rex_getsysid)(void); extern unsigned long mips_machgroup; extern unsigned long mips_machtype; -extern unsigned long mips_machtype; +static const char *dec_system_strings[] = { + [MACH_DSUNKNOWN] "unknown DECstation", + [MACH_DS23100] "DECstation 2100/3100", + [MACH_DS5100] "DECsystem 5100", + [MACH_DS5000_200] "DECstation 5000/200", + [MACH_DS5000_1XX] "DECstation 5000/1xx", + [MACH_DS5000_XX] "Personal DECstation 5000/xx", + [MACH_DS5000_2X0] "DECstation 5000/2x0", + [MACH_DS5400] "DECsystem 5400", + [MACH_DS5500] "DECsystem 5500", + [MACH_DS5800] "DECsystem 5800", + [MACH_DS5900] "DECsystem 5900", +}; + const char *get_system_type(void) { - static char system[32]; - int called = 0; - const char *dec_system_strings[] = { "unknown", "DECstation 2100/3100", - "DECstation 5100", "DECstation 5000/200", "DECstation 5000/1xx", - "Personal DECstation 5000/xx", "DECstation 5000/2x0", - "DECstation 5400", "DECstation 5500", "DECstation 5800" - }; +#define STR_BUF_LEN 64 + static char system[STR_BUF_LEN]; + static int called = 0; if (called == 0) { called = 1; - strcpy(system, "Digital "); - strcat(system, dec_system_strings[mips_machtype]); + snprintf(system, STR_BUF_LEN, "Digital %s", + dec_system_strings[mips_machtype]); } return system; } -void __init prom_identify_arch (unsigned int magic) + +/* + * Setup essential system-specific memory addresses. We need them + * early. Semantically the functions belong to prom/init.c, but they + * are compact enough we want them inlined. --macro + */ +static inline void prom_init_kn01(void) { - unsigned char dec_cpunum, dec_firmrev, dec_etc; - int dec_systype; - unsigned long dec_sysid; + dec_rtc_base = (void *)KN01_RTC_BASE; + dec_kn_slot_size = KN01_SLOT_SIZE; +} - if (magic != REX_PROM_MAGIC) { +static inline void prom_init_kn230(void) +{ + dec_rtc_base = (void *)KN01_RTC_BASE; + dec_kn_slot_size = KN01_SLOT_SIZE; +} + +static inline void prom_init_kn02(void) +{ + dec_rtc_base = (void *)KN02_RTC_BASE; + dec_kn_slot_size = KN02_SLOT_SIZE; +} + +static inline void prom_init_kn02xa(void) +{ + ioasic_base = (void *)KN02XA_IOASIC_BASE; + dec_rtc_base = (void *)KN02XA_RTC_BASE; + dec_kn_slot_size = IOASIC_SLOT_SIZE; +} + +static inline void prom_init_kn03(void) +{ + ioasic_base = (void *)KN03_IOASIC_BASE; + dec_rtc_base = (void *)KN03_RTC_BASE; + dec_kn_slot_size = IOASIC_SLOT_SIZE; +} + + +void __init prom_identify_arch(u32 magic) +{ + unsigned char dec_cpunum, dec_firmrev, dec_etc, dec_systype; + u32 dec_sysid; + + if (!prom_is_rex(magic)) { dec_sysid = simple_strtoul(prom_getenv("systype"), (char **)0, 0); } else { dec_sysid = rex_getsysid(); @@ -67,50 +121,52 @@ * FIXME: This may not be an exhaustive list of DECStations/Servers! * Put all model-specific initialisation calls here. */ - prom_printf("This DECstation is a "); - switch (dec_systype) { case DS2100_3100: - prom_printf("DS2100/3100\n"); mips_machtype = MACH_DS23100; + prom_init_kn01(); break; case DS5100: /* DS5100 MIPSMATE */ - prom_printf("DS5100\n"); mips_machtype = MACH_DS5100; + prom_init_kn230(); break; case DS5000_200: /* DS5000 3max */ - prom_printf("DS5000/200\n"); mips_machtype = MACH_DS5000_200; + prom_init_kn02(); break; case DS5000_1XX: /* DS5000/100 3min */ - prom_printf("DS5000/1xx\n"); mips_machtype = MACH_DS5000_1XX; + prom_init_kn02xa(); break; - case DS5000_2X0: /* DS5000/240 3max+ */ - prom_printf("DS5000/2x0\n"); + case DS5000_2X0: /* DS5000/240 3max+ or DS5900 bigmax */ mips_machtype = MACH_DS5000_2X0; + prom_init_kn03(); + if (!(ioasic_read(IO_REG_SIR) & KN03_IO_INR_3MAXP)) + mips_machtype = MACH_DS5900; break; - case DS5000_XX: /* Personal DS5000/2x */ - prom_printf("Personal DS5000/xx\n"); + case DS5000_XX: /* Personal DS5000/xx maxine */ mips_machtype = MACH_DS5000_XX; + prom_init_kn02xa(); break; case DS5800: /* DS5800 Isis */ - prom_printf("DS5800\n"); mips_machtype = MACH_DS5800; break; case DS5400: /* DS5400 MIPSfair */ - prom_printf("DS5400\n"); mips_machtype = MACH_DS5400; break; case DS5500: /* DS5500 MIPSfair-2 */ - prom_printf("DS5500\n"); mips_machtype = MACH_DS5500; break; default: - prom_printf("unknown, id is %x", dec_systype); mips_machtype = MACH_DSUNKNOWN; break; } -} - + if (mips_machtype == MACH_DSUNKNOWN) + prom_printf("This is an %s, id is %x\n", + dec_system_strings[mips_machtype], + dec_systype); + else + prom_printf("This is a %s\n", + dec_system_strings[mips_machtype]); +} diff -urN linux-2.4.21/arch/mips/dec/prom/init.c linux-2.4.22/arch/mips/dec/prom/init.c --- linux-2.4.21/arch/mips/dec/prom/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/prom/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -2,98 +2,102 @@ * init.c: PROM library initialisation code. * * Copyright (C) 1998 Harald Koerfgen + * Copyright (C) 2002 Maciej W. Rozycki */ -#include #include +#include +#include + #include #include -#include "prom.h" +#include + +#include + + +int (*__rex_bootinit)(void); +int (*__rex_bootread)(void); +int (*__rex_getbitmap)(memmap *); +unsigned long *(*__rex_slot_address)(int); +void *(*__rex_gettcinfo)(void); +int (*__rex_getsysid)(void); +void (*__rex_clear_cache)(void); + +int (*__prom_getchar)(void); +char *(*__prom_getenv)(char *); +int (*__prom_printf)(char *, ...); + +int (*__pmax_open)(char*, int); +int (*__pmax_lseek)(int, long, int); +int (*__pmax_read)(int, void *, int); +int (*__pmax_close)(int); -/* - * PROM Interface (whichprom.c) - */ -typedef struct { - int pagesize; - unsigned char bitmap[0]; -} memmap; - -int (*rex_bootinit)(void); -int (*rex_bootread)(void); -int (*rex_getbitmap)(memmap *); -unsigned long *(*rex_slot_address)(int); -void *(*rex_gettcinfo)(void); -int (*rex_getsysid)(void); -void (*rex_clear_cache)(void); - -int (*prom_getchar)(void); -char *(*prom_getenv)(char *); -int (*prom_printf)(char *, ...); - -int (*pmax_open)(char*, int); -int (*pmax_lseek)(int, long, int); -int (*pmax_read)(int, void *, int); -int (*pmax_close)(int); - -extern void prom_meminit(unsigned int); -extern void prom_identify_arch(unsigned int); -extern void prom_init_cmdline(int, char **, unsigned long); /* * Detect which PROM's the DECSTATION has, and set the callback vectors * appropriately. */ -void __init which_prom(unsigned long magic, int *prom_vec) +void __init which_prom(s32 magic, s32 *prom_vec) { /* * No sign of the REX PROM's magic number means we assume a non-REX * machine (i.e. we're on a DS2100/3100, DS5100 or DS5000/2xx) */ - if (magic == REX_PROM_MAGIC) - { + if (prom_is_rex(magic)) { /* * Set up prom abstraction structure with REX entry points. */ - rex_bootinit = (int (*)(void)) *(prom_vec + REX_PROM_BOOTINIT); - rex_bootread = (int (*)(void)) *(prom_vec + REX_PROM_BOOTREAD); - rex_getbitmap = (int (*)(memmap *)) *(prom_vec + REX_PROM_GETBITMAP); - prom_getchar = (int (*)(void)) *(prom_vec + REX_PROM_GETCHAR); - prom_getenv = (char *(*)(char *)) *(prom_vec + REX_PROM_GETENV); - rex_getsysid = (int (*)(void)) *(prom_vec + REX_PROM_GETSYSID); - rex_gettcinfo = (void *(*)(void)) *(prom_vec + REX_PROM_GETTCINFO); - prom_printf = (int (*)(char *, ...)) *(prom_vec + REX_PROM_PRINTF); - rex_slot_address = (unsigned long *(*)(int)) *(prom_vec + REX_PROM_SLOTADDR); - rex_clear_cache = (void (*)(void)) * (prom_vec + REX_PROM_CLEARCACHE); - } - else - { + __rex_bootinit = + (void *)(long)*(prom_vec + REX_PROM_BOOTINIT); + __rex_bootread = + (void *)(long)*(prom_vec + REX_PROM_BOOTREAD); + __rex_getbitmap = + (void *)(long)*(prom_vec + REX_PROM_GETBITMAP); + __prom_getchar = + (void *)(long)*(prom_vec + REX_PROM_GETCHAR); + __prom_getenv = + (void *)(long)*(prom_vec + REX_PROM_GETENV); + __rex_getsysid = + (void *)(long)*(prom_vec + REX_PROM_GETSYSID); + __rex_gettcinfo = + (void *)(long)*(prom_vec + REX_PROM_GETTCINFO); + __prom_printf = + (void *)(long)*(prom_vec + REX_PROM_PRINTF); + __rex_slot_address = + (void *)(long)*(prom_vec + REX_PROM_SLOTADDR); + __rex_clear_cache = + (void *)(long)*(prom_vec + REX_PROM_CLEARCACHE); + } else { /* * Set up prom abstraction structure with non-REX entry points. */ - prom_getchar = (int (*)(void)) PMAX_PROM_GETCHAR; - prom_getenv = (char *(*)(char *)) PMAX_PROM_GETENV; - prom_printf = (int (*)(char *, ...)) PMAX_PROM_PRINTF; - pmax_open = (int (*)(char *, int)) PMAX_PROM_OPEN; - pmax_lseek = (int (*)(int, long, int)) PMAX_PROM_LSEEK; - pmax_read = (int (*)(int, void *, int)) PMAX_PROM_READ; - pmax_close = (int (*)(int)) PMAX_PROM_CLOSE; + __prom_getchar = (void *)PMAX_PROM_GETCHAR; + __prom_getenv = (void *)PMAX_PROM_GETENV; + __prom_printf = (void *)PMAX_PROM_PRINTF; + __pmax_open = (void *)PMAX_PROM_OPEN; + __pmax_lseek = (void *)PMAX_PROM_LSEEK; + __pmax_read = (void *)PMAX_PROM_READ; + __pmax_close = (void *)PMAX_PROM_CLOSE; } } -int __init prom_init(int argc, char **argv, - unsigned long magic, int *prom_vec) +int __init prom_init(s32 argc, s32 *argv, u32 magic, s32 *prom_vec) { extern void dec_machine_halt(void); - /* Determine which PROM's we have (and therefore which machine we're on!) */ + /* + * Determine which PROM's we have + * (and therefore which machine we're on!) + */ which_prom(magic, prom_vec); - if (magic == REX_PROM_MAGIC) + if (prom_is_rex(magic)) rex_clear_cache(); /* Were we compiled with the right CPU option? */ #if defined(CONFIG_CPU_R3000) - if ((mips_cpu.cputype == CPU_R4000SC) || - (mips_cpu.cputype == CPU_R4400SC)) { + if ((current_cpu_data.cputype == CPU_R4000SC) || + (current_cpu_data.cputype == CPU_R4400SC)) { prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n"); prom_printf("Please recompile with \"CONFIG_CPU_R4x00 = y\"\n"); dec_machine_halt(); @@ -101,8 +105,8 @@ #endif #if defined(CONFIG_CPU_R4X00) - if ((mips_cpu.cputype == CPU_R3000) || - (mips_cpu.cputype == CPU_R3000A)) { + if ((current_cpu_data.cputype == CPU_R3000) || + (current_cpu_data.cputype == CPU_R3000A)) { prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n"); prom_printf("Please recompile with \"CONFIG_CPU_R3000 = y\"\n"); dec_machine_halt(); @@ -115,4 +119,3 @@ return 0; } - diff -urN linux-2.4.21/arch/mips/dec/prom/locore.S linux-2.4.22/arch/mips/dec/prom/locore.S --- linux-2.4.21/arch/mips/dec/prom/locore.S 1999-06-25 17:40:12.000000000 -0700 +++ linux-2.4.22/arch/mips/dec/prom/locore.S 2003-08-25 04:44:39.000000000 -0700 @@ -19,11 +19,11 @@ mfc0 k0, CP0_STATUS la k1, mem_err - sw k0,0(k1) + sw k0, 0(k1) mfc0 k0, CP0_EPC nop - addiu k0,4 # skip the causing instruction + addiu k0, 4 # skip the causing instruction jr k0 rfe END(genexcept_early) diff -urN linux-2.4.21/arch/mips/dec/prom/memory.c linux-2.4.22/arch/mips/dec/prom/memory.c --- linux-2.4.21/arch/mips/dec/prom/memory.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/dec/prom/memory.c 2003-08-25 04:44:39.000000000 -0700 @@ -2,35 +2,21 @@ * memory.c: memory initialisation code. * * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine - * Copyright (C) 2000 Maciej W. Rozycki + * Copyright (C) 2000, 2002 Maciej W. Rozycki */ -#include #include +#include #include #include #include +#include #include -#include - #include - #include +#include +#include -#include "prom.h" - -typedef struct { - int pagesize; - unsigned char bitmap[0]; -} memmap; - -extern int (*rex_getbitmap)(memmap *); - -#undef PROM_DEBUG - -#ifdef PROM_DEBUG -extern int (*prom_printf)(char *, ...); -#endif volatile unsigned long mem_err = 0; /* So we know an error occurred */ @@ -41,10 +27,10 @@ #define CHUNK_SIZE 0x400000 -static void __init pmax_setup_memory_region(void) +static inline void pmax_setup_memory_region(void) { volatile unsigned char *memory_page, dummy; - char old_handler[0x80]; + char old_handler[0x80]; extern char genexcept_early; /* Install exception handler */ @@ -71,14 +57,14 @@ * Use the REX prom calls to get hold of the memory bitmap, and thence * determine memory size. */ -static void __init rex_setup_memory_region(void) +static inline void rex_setup_memory_region(void) { int i, bitmap_size; unsigned long mem_start = 0, mem_size = 0; memmap *bm; /* some free 64k */ - bm = (memmap *) 0x80028000; + bm = (memmap *)KSEG0ADDR(0x28000); bitmap_size = rex_getbitmap(bm); @@ -98,9 +84,9 @@ add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); } -void __init prom_meminit(unsigned int magic) +void __init prom_meminit(u32 magic) { - if (magic != REX_PROM_MAGIC) + if (!prom_is_rex(magic)) pmax_setup_memory_region(); else rex_setup_memory_region(); diff -urN linux-2.4.21/arch/mips/dec/prom/prom.h linux-2.4.22/arch/mips/dec/prom/prom.h --- linux-2.4.21/arch/mips/dec/prom/prom.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/prom/prom.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,51 +0,0 @@ -/* - * Miscellaneous definitions used to call the routines contained in the boot - * PROMs on various models of DECSTATION's. - * the rights to redistribute these changes. - */ - -#ifndef __ASM_DEC_PROM_H -#define __ASM_DEC_PROM_H - -/* - * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's. Many of - * these will work for MIPSen as well! - */ -#define VEC_RESET 0xBFC00000 /* Prom base address */ -#define PMAX_PROM_ENTRY(x) (VEC_RESET+((x)*8)) /* Prom jump table */ - -#define PMAX_PROM_HALT PMAX_PROM_ENTRY(2) /* valid on MIPSen */ -#define PMAX_PROM_AUTOBOOT PMAX_PROM_ENTRY(5) /* valid on MIPSen */ -#define PMAX_PROM_OPEN PMAX_PROM_ENTRY(6) -#define PMAX_PROM_READ PMAX_PROM_ENTRY(7) -#define PMAX_PROM_CLOSE PMAX_PROM_ENTRY(10) -#define PMAX_PROM_LSEEK PMAX_PROM_ENTRY(11) -#define PMAX_PROM_GETCHAR PMAX_PROM_ENTRY(12) -#define PMAX_PROM_PUTCHAR PMAX_PROM_ENTRY(13) /* 12 on MIPSen */ -#define PMAX_PROM_GETS PMAX_PROM_ENTRY(15) -#define PMAX_PROM_PRINTF PMAX_PROM_ENTRY(17) -#define PMAX_PROM_GETENV PMAX_PROM_ENTRY(33) /* valid on MIPSen */ - -/* - * Magic number indicating REX PROM available on DECSTATION. Found in - * register a2 on transfer of control to program from PROM. - */ -#define REX_PROM_MAGIC 0x30464354 - -/* - * 3MIN/MAXINE PROM entry points for DS5000/1xx's, DS5000/xx's, and - * DS5000/2x0. - */ -#define REX_PROM_GETBITMAP 0x84/4 /* get mem bitmap */ -#define REX_PROM_GETCHAR 0x24/4 /* getch() */ -#define REX_PROM_GETENV 0x64/4 /* get env. variable */ -#define REX_PROM_GETSYSID 0x80/4 /* get system id */ -#define REX_PROM_GETTCINFO 0xa4/4 -#define REX_PROM_PRINTF 0x30/4 /* printf() */ -#define REX_PROM_SLOTADDR 0x6c/4 /* slotaddr */ -#define REX_PROM_BOOTINIT 0x54/4 /* open() */ -#define REX_PROM_BOOTREAD 0x58/4 /* read() */ -#define REX_PROM_CLEARCACHE 0x7c/4 - -#endif /* __ASM_DEC_PROM_H */ - diff -urN linux-2.4.21/arch/mips/dec/promcon.c linux-2.4.22/arch/mips/dec/promcon.c --- linux-2.4.21/arch/mips/dec/promcon.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/promcon.c 2003-08-25 04:44:39.000000000 -0700 @@ -12,8 +12,7 @@ #include #include -extern int (*prom_getchar) (void); -extern int (*prom_printf) (char *,...); +#include static void prom_console_write(struct console *co, const char *s, unsigned count) @@ -42,12 +41,12 @@ static struct console sercons = { - name: "ttyS", - write: prom_console_write, - device: prom_console_device, - setup: prom_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "ttyS", + .write = prom_console_write, + .device = prom_console_device, + .setup = prom_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; /* diff -urN linux-2.4.21/arch/mips/dec/reset.c linux-2.4.22/arch/mips/dec/reset.c --- linux-2.4.21/arch/mips/dec/reset.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/dec/reset.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,8 +1,14 @@ /* * Reset a DECstation machine. + * + * Copyright (C) 199x the Anonymous + * Copyright (C) 2001, 2002, 2003 Maciej W. Rozycki */ -void (*back_to_prom)(void) = (void (*)(void))0xBFC00000; +#include +#include + +#define back_to_prom() (((void (*)(void))KSEG1ADDR(0x1fc00000))()) void dec_machine_restart(char *command) { diff -urN linux-2.4.21/arch/mips/dec/rtc-dec.c linux-2.4.22/arch/mips/dec/rtc-dec.c --- linux-2.4.21/arch/mips/dec/rtc-dec.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/rtc-dec.c 2003-08-25 04:44:39.000000000 -0700 @@ -11,6 +11,7 @@ */ #include +#include #include volatile u8 *dec_rtc_base; @@ -35,3 +36,5 @@ &dec_rtc_write_data, &dec_rtc_bcd_mode }; + +EXPORT_SYMBOL(dec_rtc_base); diff -urN linux-2.4.21/arch/mips/dec/setup.c linux-2.4.22/arch/mips/dec/setup.c --- linux-2.4.21/arch/mips/dec/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -6,7 +6,7 @@ * for more details. * * Copyright (C) 1998 Harald Koerfgen - * Copyright (C) 2000, 2001, 2002 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki */ #include #include @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -24,19 +25,20 @@ #include #include #include +#include #include #include #include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include extern void dec_machine_restart(char *command); @@ -46,6 +48,8 @@ extern asmlinkage void decstation_handle_int(void); +spinlock_t ioasic_ssr_lock; + volatile u32 *ioasic_base; unsigned long dec_kn_slot_size; @@ -75,53 +79,61 @@ [0 ... DEC_NR_INTS - 1] = -1 }; int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = { - { { i: ~0 }, { p: dec_intr_unimplemented } }, + { { .i = ~0 }, { .p = dec_intr_unimplemented } }, }; int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2] = { - { { i: ~0 }, { p: asic_intr_unimplemented } }, + { { .i = ~0 }, { .p = asic_intr_unimplemented } }, }; int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU); -static struct irqaction ioirq = {NULL, 0, 0, "cascade", NULL, NULL}; -static struct irqaction fpuirq = {NULL, 0, 0, "fpu", NULL, NULL}; - -static struct irqaction haltirq = {dec_intr_halt, 0, 0, "halt", NULL, NULL}; +static struct irqaction ioirq = { + .handler = no_action, + .name = "cascade", +}; +static struct irqaction fpuirq = { + .handler = no_action, + .name = "fpu", +}; +static struct irqaction busirq = { + .flags = SA_INTERRUPT, + .name = "bus error", +}; -void (*board_time_init) (struct irqaction * irq); +static struct irqaction haltirq = { + .handler = dec_intr_halt, + .name = "halt", +}; /* - * enable the periodic interrupts + * Bus error (DBE/IBE exceptions and bus interrupts) handling setup. */ -static void __init dec_time_init(struct irqaction *irq) +void __init dec_be_init(void) { - /* - * Here we go, enable periodic rtc interrupts. - */ - -#ifndef LOG_2_HZ -# define LOG_2_HZ 7 -#endif - - CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A); - CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B); - setup_irq(dec_interrupt[DEC_IRQ_RTC], irq); + switch (mips_machtype) { + case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */ + busirq.flags |= SA_SHIRQ; + break; + case MACH_DS5000_200: /* DS5000/200 3max */ + case MACH_DS5000_2X0: /* DS5000/240 3max+ */ + case MACH_DS5900: /* DS5900 bigmax */ + board_be_handler = dec_ecc_be_handler; + busirq.handler = dec_ecc_be_interrupt; + dec_ecc_be_init(); + break; + } } -/* - * Bus error (DBE/IBE exceptions and memory interrupts) handling - * setup. Nothing for now. - */ -void __init bus_error_init(void) -{ -} - +extern void dec_time_init(void); +extern void dec_timer_setup(struct irqaction *); void __init decstation_setup(void) { + board_be_init = dec_be_init; board_time_init = dec_time_init; + board_timer_setup = dec_timer_setup; wbflush_setup(); @@ -152,7 +164,7 @@ [DEC_IRQ_HALT] = -1, [DEC_IRQ_ISDN] = -1, [DEC_IRQ_LANCE] = DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE), - [DEC_IRQ_MEMORY] = DEC_CPU_IRQ_NR(KN01_CPU_INR_MEMORY), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS), [DEC_IRQ_PSU] = -1, [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC), [DEC_IRQ_SCC0] = -1, @@ -175,10 +187,10 @@ [DEC_IRQ_SCC0A_RXDMA] = -1, [DEC_IRQ_SCC0A_TXERR] = -1, [DEC_IRQ_SCC0A_TXDMA] = -1, - [DEC_IRQ_SCC0B_RXERR] = -1, - [DEC_IRQ_SCC0B_RXDMA] = -1, - [DEC_IRQ_SCC0B_TXERR] = -1, - [DEC_IRQ_SCC0B_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, [DEC_IRQ_SCC1A_RXERR] = -1, [DEC_IRQ_SCC1A_RXDMA] = -1, [DEC_IRQ_SCC1A_TXERR] = -1, @@ -186,26 +198,22 @@ }; static int_ptr kn01_cpu_mask_nr_tbl[][2] __initdata = { - { { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_MEMORY) }, - { i: DEC_CPU_IRQ_NR(KN01_CPU_INR_MEMORY) } }, - { { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_RTC) }, - { i: DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC) } }, - { { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_DZ11) }, - { i: DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11) } }, - { { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_SII) }, - { i: DEC_CPU_IRQ_NR(KN01_CPU_INR_SII) } }, - { { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_LANCE) }, - { i: DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE) } }, - { { i: DEC_CPU_IRQ_ALL }, - { p: cpu_all_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_DZ11) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_SII) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_SII) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_LANCE) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE) } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, }; void __init dec_init_kn01(void) { - /* Setup some memory addresses. */ - dec_rtc_base = (void *)KN01_RTC_BASE; - dec_kn_slot_size = KN01_SLOT_SIZE; - /* IRQ routing. */ memcpy(&dec_interrupt, &kn01_interrupt, sizeof(kn01_interrupt)); @@ -233,7 +241,7 @@ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN230_CPU_INR_HALT), [DEC_IRQ_ISDN] = -1, [DEC_IRQ_LANCE] = DEC_CPU_IRQ_NR(KN230_CPU_INR_LANCE), - [DEC_IRQ_MEMORY] = DEC_CPU_IRQ_NR(KN230_CPU_INR_MEMORY), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS), [DEC_IRQ_PSU] = -1, [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC), [DEC_IRQ_SCC0] = -1, @@ -256,10 +264,10 @@ [DEC_IRQ_SCC0A_RXDMA] = -1, [DEC_IRQ_SCC0A_TXERR] = -1, [DEC_IRQ_SCC0A_TXDMA] = -1, - [DEC_IRQ_SCC0B_RXERR] = -1, - [DEC_IRQ_SCC0B_RXDMA] = -1, - [DEC_IRQ_SCC0B_TXERR] = -1, - [DEC_IRQ_SCC0B_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, [DEC_IRQ_SCC1A_RXERR] = -1, [DEC_IRQ_SCC1A_RXDMA] = -1, [DEC_IRQ_SCC1A_TXERR] = -1, @@ -267,24 +275,20 @@ }; static int_ptr kn230_cpu_mask_nr_tbl[][2] __initdata = { - { { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_MEMORY) }, - { i: DEC_CPU_IRQ_NR(KN230_CPU_INR_MEMORY) } }, - { { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_RTC) }, - { i: DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC) } }, - { { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_DZ11) }, - { i: DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11) } }, - { { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_SII) }, - { i: DEC_CPU_IRQ_NR(KN230_CPU_INR_SII) } }, - { { i: DEC_CPU_IRQ_ALL }, - { p: cpu_all_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_DZ11) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11) } }, + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_SII) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_SII) } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, }; void __init dec_init_kn230(void) { - /* Setup some memory addresses. */ - dec_rtc_base = (void *)KN01_RTC_BASE; - dec_kn_slot_size = KN01_SLOT_SIZE; - /* IRQ routing. */ memcpy(&dec_interrupt, &kn230_interrupt, sizeof(kn230_interrupt)); @@ -312,7 +316,7 @@ [DEC_IRQ_HALT] = -1, [DEC_IRQ_ISDN] = -1, [DEC_IRQ_LANCE] = KN02_IRQ_NR(KN02_CSR_INR_LANCE), - [DEC_IRQ_MEMORY] = DEC_CPU_IRQ_NR(KN02_CPU_INR_MEMORY), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS), [DEC_IRQ_PSU] = -1, [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC), [DEC_IRQ_SCC0] = -1, @@ -335,10 +339,10 @@ [DEC_IRQ_SCC0A_RXDMA] = -1, [DEC_IRQ_SCC0A_TXERR] = -1, [DEC_IRQ_SCC0A_TXDMA] = -1, - [DEC_IRQ_SCC0B_RXERR] = -1, - [DEC_IRQ_SCC0B_RXDMA] = -1, - [DEC_IRQ_SCC0B_TXERR] = -1, - [DEC_IRQ_SCC0B_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, [DEC_IRQ_SCC1A_RXERR] = -1, [DEC_IRQ_SCC1A_RXDMA] = -1, [DEC_IRQ_SCC1A_TXERR] = -1, @@ -346,39 +350,35 @@ }; static int_ptr kn02_cpu_mask_nr_tbl[][2] __initdata = { - { { i: DEC_CPU_IRQ_MASK(KN02_CPU_INR_MEMORY) }, - { i: DEC_CPU_IRQ_NR(KN02_CPU_INR_MEMORY) } }, - { { i: DEC_CPU_IRQ_MASK(KN02_CPU_INR_RTC) }, - { i: DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC) } }, - { { i: DEC_CPU_IRQ_MASK(KN02_CPU_INR_CASCADE) }, - { p: kn02_io_int } }, - { { i: DEC_CPU_IRQ_ALL }, - { p: cpu_all_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_CASCADE) }, + { .p = kn02_io_int } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, }; static int_ptr kn02_asic_mask_nr_tbl[][2] __initdata = { - { { i: KN02_IRQ_MASK(KN02_CSR_INR_DZ11) }, - { i: KN02_IRQ_NR(KN02_CSR_INR_DZ11) } }, - { { i: KN02_IRQ_MASK(KN02_CSR_INR_ASC) }, - { i: KN02_IRQ_NR(KN02_CSR_INR_ASC) } }, - { { i: KN02_IRQ_MASK(KN02_CSR_INR_LANCE) }, - { i: KN02_IRQ_NR(KN02_CSR_INR_LANCE) } }, - { { i: KN02_IRQ_MASK(KN02_CSR_INR_TC2) }, - { i: KN02_IRQ_NR(KN02_CSR_INR_TC2) } }, - { { i: KN02_IRQ_MASK(KN02_CSR_INR_TC1) }, - { i: KN02_IRQ_NR(KN02_CSR_INR_TC1) } }, - { { i: KN02_IRQ_MASK(KN02_CSR_INR_TC0) }, - { i: KN02_IRQ_NR(KN02_CSR_INR_TC0) } }, - { { i: KN02_IRQ_ALL }, - { p: kn02_all_int } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_DZ11) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_DZ11) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_ASC) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_ASC) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_LANCE) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_LANCE) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC2) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_TC2) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC1) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_TC1) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC0) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_TC0) } }, + { { .i = KN02_IRQ_ALL }, + { .p = kn02_all_int } }, }; void __init dec_init_kn02(void) { - /* Setup some memory addresses. */ - dec_rtc_base = (void *)KN02_RTC_BASE; - dec_kn_slot_size = KN02_SLOT_SIZE; - /* IRQ routing. */ memcpy(&dec_interrupt, &kn02_interrupt, sizeof(kn02_interrupt)); @@ -413,7 +413,7 @@ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_HALT), [DEC_IRQ_ISDN] = -1, [DEC_IRQ_LANCE] = IO_IRQ_NR(KN02BA_IO_INR_LANCE), - [DEC_IRQ_MEMORY] = IO_IRQ_NR(KN02BA_IO_INR_MEMORY), + [DEC_IRQ_BUS] = IO_IRQ_NR(KN02BA_IO_INR_BUS), [DEC_IRQ_PSU] = IO_IRQ_NR(KN02BA_IO_INR_PSU), [DEC_IRQ_RTC] = IO_IRQ_NR(KN02BA_IO_INR_RTC), [DEC_IRQ_SCC0] = IO_IRQ_NR(KN02BA_IO_INR_SCC0), @@ -436,10 +436,10 @@ [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA), [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR), [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA), - [DEC_IRQ_SCC0B_RXERR] = -1, - [DEC_IRQ_SCC0B_RXDMA] = -1, - [DEC_IRQ_SCC0B_TXERR] = -1, - [DEC_IRQ_SCC0B_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, [DEC_IRQ_SCC1A_RXERR] = IO_IRQ_NR(IO_INR_SCC1A_RXERR), [DEC_IRQ_SCC1A_RXDMA] = IO_IRQ_NR(IO_INR_SCC1A_RXDMA), [DEC_IRQ_SCC1A_TXERR] = IO_IRQ_NR(IO_INR_SCC1A_TXERR), @@ -447,44 +447,39 @@ }; static int_ptr kn02ba_cpu_mask_nr_tbl[][2] __initdata = { - { { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_CASCADE) }, - { p: kn02xa_io_int } }, - { { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC2) }, - { i: DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2) } }, - { { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC1) }, - { i: DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1) } }, - { { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC0) }, - { i: DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0) } }, - { { i: DEC_CPU_IRQ_ALL }, - { p: cpu_all_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_CASCADE) }, + { .p = kn02xa_io_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC2) }, + { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC1) }, + { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC0) }, + { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0) } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, }; static int_ptr kn02ba_asic_mask_nr_tbl[][2] __initdata = { - { { i: IO_IRQ_MASK(KN02BA_IO_INR_MEMORY) }, - { i: IO_IRQ_NR(KN02BA_IO_INR_MEMORY) } }, - { { i: IO_IRQ_MASK(KN02BA_IO_INR_RTC) }, - { i: IO_IRQ_NR(KN02BA_IO_INR_RTC) } }, - { { i: IO_IRQ_DMA }, - { p: asic_dma_int } }, - { { i: IO_IRQ_MASK(KN02BA_IO_INR_SCC0) }, - { i: IO_IRQ_NR(KN02BA_IO_INR_SCC0) } }, - { { i: IO_IRQ_MASK(KN02BA_IO_INR_SCC1) }, - { i: IO_IRQ_NR(KN02BA_IO_INR_SCC1) } }, - { { i: IO_IRQ_MASK(KN02BA_IO_INR_ASC) }, - { i: IO_IRQ_NR(KN02BA_IO_INR_ASC) } }, - { { i: IO_IRQ_MASK(KN02BA_IO_INR_LANCE) }, - { i: IO_IRQ_NR(KN02BA_IO_INR_LANCE) } }, - { { i: IO_IRQ_ALL }, - { p: asic_all_int } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_BUS) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_BUS) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_RTC) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_RTC) } }, + { { .i = IO_IRQ_DMA }, + { .p = asic_dma_int } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC0) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_SCC0) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC1) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_SCC1) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_ASC) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_ASC) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_LANCE) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_LANCE) } }, + { { .i = IO_IRQ_ALL }, + { .p = asic_all_int } }, }; void __init dec_init_kn02ba(void) { - /* Setup some memory addresses. */ - ioasic_base = (void *)KN02BA_IOASIC_BASE; - dec_rtc_base = (void *)KN02BA_RTC_BASE; - dec_kn_slot_size = IOASIC_SLOT_SIZE; - /* IRQ routing. */ memcpy(&dec_interrupt, &kn02ba_interrupt, sizeof(kn02ba_interrupt)); @@ -519,7 +514,7 @@ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_HALT), [DEC_IRQ_ISDN] = IO_IRQ_NR(KN02CA_IO_INR_ISDN), [DEC_IRQ_LANCE] = IO_IRQ_NR(KN02CA_IO_INR_LANCE), - [DEC_IRQ_MEMORY] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_MEMORY), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS), [DEC_IRQ_PSU] = -1, [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC), [DEC_IRQ_SCC0] = IO_IRQ_NR(KN02CA_IO_INR_SCC0), @@ -542,10 +537,10 @@ [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA), [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR), [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA), - [DEC_IRQ_SCC0B_RXERR] = IO_IRQ_NR(IO_INR_SCC0B_RXERR), - [DEC_IRQ_SCC0B_RXDMA] = IO_IRQ_NR(IO_INR_SCC0B_RXDMA), - [DEC_IRQ_SCC0B_TXERR] = IO_IRQ_NR(IO_INR_SCC0B_TXERR), - [DEC_IRQ_SCC0B_TXDMA] = IO_IRQ_NR(IO_INR_SCC0B_TXDMA), + [DEC_IRQ_AB_RXERR] = IO_IRQ_NR(IO_INR_AB_RXERR), + [DEC_IRQ_AB_RXDMA] = IO_IRQ_NR(IO_INR_AB_RXDMA), + [DEC_IRQ_AB_TXERR] = IO_IRQ_NR(IO_INR_AB_TXERR), + [DEC_IRQ_AB_TXDMA] = IO_IRQ_NR(IO_INR_AB_TXDMA), [DEC_IRQ_SCC1A_RXERR] = -1, [DEC_IRQ_SCC1A_RXDMA] = -1, [DEC_IRQ_SCC1A_TXERR] = -1, @@ -553,40 +548,35 @@ }; static int_ptr kn02ca_cpu_mask_nr_tbl[][2] __initdata = { - { { i: DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_MEMORY) }, - { i: DEC_CPU_IRQ_NR(KN02CA_CPU_INR_MEMORY) } }, - { { i: DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_RTC) }, - { i: DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC) } }, - { { i: DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_CASCADE) }, - { p: kn02xa_io_int } }, - { { i: DEC_CPU_IRQ_ALL }, - { p: cpu_all_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_CASCADE) }, + { .p = kn02xa_io_int } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, }; static int_ptr kn02ca_asic_mask_nr_tbl[][2] __initdata = { - { { i: IO_IRQ_DMA }, - { p: asic_dma_int } }, - { { i: IO_IRQ_MASK(KN02CA_IO_INR_SCC0) }, - { i: IO_IRQ_NR(KN02CA_IO_INR_SCC0) } }, - { { i: IO_IRQ_MASK(KN02CA_IO_INR_ASC) }, - { i: IO_IRQ_NR(KN02CA_IO_INR_ASC) } }, - { { i: IO_IRQ_MASK(KN02CA_IO_INR_LANCE) }, - { i: IO_IRQ_NR(KN02CA_IO_INR_LANCE) } }, - { { i: IO_IRQ_MASK(KN02CA_IO_INR_TC1) }, - { i: IO_IRQ_NR(KN02CA_IO_INR_TC1) } }, - { { i: IO_IRQ_MASK(KN02CA_IO_INR_TC0) }, - { i: IO_IRQ_NR(KN02CA_IO_INR_TC0) } }, - { { i: IO_IRQ_ALL }, - { p: asic_all_int } }, + { { .i = IO_IRQ_DMA }, + { .p = asic_dma_int } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_SCC0) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_SCC0) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_ASC) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_ASC) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_LANCE) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_LANCE) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC1) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_TC1) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC0) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_TC0) } }, + { { .i = IO_IRQ_ALL }, + { .p = asic_all_int } }, }; void __init dec_init_kn02ca(void) { - /* Setup some memory addresses. */ - ioasic_base = (void *)KN02CA_IOASIC_BASE; - dec_rtc_base = (void *)KN02CA_RTC_BASE; - dec_kn_slot_size = IOASIC_SLOT_SIZE; - /* IRQ routing. */ memcpy(&dec_interrupt, &kn02ca_interrupt, sizeof(kn02ca_interrupt)); @@ -608,7 +598,7 @@ /* * Machine-specific initialisation for KN03, aka DS5000/240, * aka 3max+ and DS5900, aka BIGmax. Also applies to KN05, aka - * DS5000/260, aka 4max+ and DS5900-260. + * DS5000/260, aka 4max+ and DS5900/260. */ static int kn03_interrupt[DEC_NR_INTS] __initdata = { [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN03_CPU_INR_CASCADE), @@ -621,7 +611,7 @@ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN03_CPU_INR_HALT), [DEC_IRQ_ISDN] = -1, [DEC_IRQ_LANCE] = IO_IRQ_NR(KN03_IO_INR_LANCE), - [DEC_IRQ_MEMORY] = DEC_CPU_IRQ_NR(KN03_CPU_INR_MEMORY), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS), [DEC_IRQ_PSU] = IO_IRQ_NR(KN03_IO_INR_PSU), [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC), [DEC_IRQ_SCC0] = IO_IRQ_NR(KN03_IO_INR_SCC0), @@ -644,10 +634,10 @@ [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA), [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR), [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA), - [DEC_IRQ_SCC0B_RXERR] = -1, - [DEC_IRQ_SCC0B_RXDMA] = -1, - [DEC_IRQ_SCC0B_TXERR] = -1, - [DEC_IRQ_SCC0B_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, [DEC_IRQ_SCC1A_RXERR] = IO_IRQ_NR(IO_INR_SCC1A_RXERR), [DEC_IRQ_SCC1A_RXDMA] = IO_IRQ_NR(IO_INR_SCC1A_RXDMA), [DEC_IRQ_SCC1A_TXERR] = IO_IRQ_NR(IO_INR_SCC1A_TXERR), @@ -655,44 +645,39 @@ }; static int_ptr kn03_cpu_mask_nr_tbl[][2] __initdata = { - { { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_MEMORY) }, - { i: DEC_CPU_IRQ_NR(KN03_CPU_INR_MEMORY) } }, - { { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_RTC) }, - { i: DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC) } }, - { { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) }, - { p: kn03_io_int } }, - { { i: DEC_CPU_IRQ_ALL }, - { p: cpu_all_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) }, + { .p = kn03_io_int } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, }; static int_ptr kn03_asic_mask_nr_tbl[][2] __initdata = { - { { i: IO_IRQ_DMA }, - { p: asic_dma_int } }, - { { i: IO_IRQ_MASK(KN03_IO_INR_SCC0) }, - { i: IO_IRQ_NR(KN03_IO_INR_SCC0) } }, - { { i: IO_IRQ_MASK(KN03_IO_INR_SCC1) }, - { i: IO_IRQ_NR(KN03_IO_INR_SCC1) } }, - { { i: IO_IRQ_MASK(KN03_IO_INR_ASC) }, - { i: IO_IRQ_NR(KN03_IO_INR_ASC) } }, - { { i: IO_IRQ_MASK(KN03_IO_INR_LANCE) }, - { i: IO_IRQ_NR(KN03_IO_INR_LANCE) } }, - { { i: IO_IRQ_MASK(KN03_IO_INR_TC2) }, - { i: IO_IRQ_NR(KN03_IO_INR_TC2) } }, - { { i: IO_IRQ_MASK(KN03_IO_INR_TC1) }, - { i: IO_IRQ_NR(KN03_IO_INR_TC1) } }, - { { i: IO_IRQ_MASK(KN03_IO_INR_TC0) }, - { i: IO_IRQ_NR(KN03_IO_INR_TC0) } }, - { { i: IO_IRQ_ALL }, - { p: asic_all_int } }, + { { .i = IO_IRQ_DMA }, + { .p = asic_dma_int } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_SCC0) }, + { .i = IO_IRQ_NR(KN03_IO_INR_SCC0) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_SCC1) }, + { .i = IO_IRQ_NR(KN03_IO_INR_SCC1) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_ASC) }, + { .i = IO_IRQ_NR(KN03_IO_INR_ASC) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_LANCE) }, + { .i = IO_IRQ_NR(KN03_IO_INR_LANCE) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_TC2) }, + { .i = IO_IRQ_NR(KN03_IO_INR_TC2) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_TC1) }, + { .i = IO_IRQ_NR(KN03_IO_INR_TC1) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_TC0) }, + { .i = IO_IRQ_NR(KN03_IO_INR_TC0) } }, + { { .i = IO_IRQ_ALL }, + { .p = asic_all_int } }, }; void __init dec_init_kn03(void) { - /* Setup some memory addresses. */ - ioasic_base = (void *)KN03_IOASIC_BASE; - dec_rtc_base = (void *)KN03_RTC_BASE; - dec_kn_slot_size = IOASIC_SLOT_SIZE; - /* IRQ routing. */ memcpy(&dec_interrupt, &kn03_interrupt, sizeof(kn03_interrupt)); @@ -727,6 +712,7 @@ dec_init_kn02ba(); break; case MACH_DS5000_2X0: /* DS5000/240 3max+ */ + case MACH_DS5900: /* DS5900 bigmax */ dec_init_kn03(); break; case MACH_DS5000_XX: /* Personal DS5000/xx */ @@ -745,7 +731,7 @@ set_except_vector(0, decstation_handle_int); /* Free the FPU interrupt if the exception is present. */ - if (!(mips_cpu.options & MIPS_CPU_NOFPUEX)) { + if (!cpu_has_nofpuex) { cpu_fpu_mask = 0; dec_interrupt[DEC_IRQ_FPU] = -1; } @@ -756,12 +742,15 @@ if (dec_interrupt[DEC_IRQ_CASCADE] >= 0) setup_irq(dec_interrupt[DEC_IRQ_CASCADE], &ioirq); + /* Register the bus error interrupt. */ + if (dec_interrupt[DEC_IRQ_BUS] >= 0 && busirq.handler) + setup_irq(dec_interrupt[DEC_IRQ_BUS], &busirq); + /* Register the HALT interrupt. */ if (dec_interrupt[DEC_IRQ_HALT] >= 0) setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq); } EXPORT_SYMBOL(ioasic_base); -EXPORT_SYMBOL(dec_rtc_base); EXPORT_SYMBOL(dec_kn_slot_size); EXPORT_SYMBOL(dec_interrupt); diff -urN linux-2.4.21/arch/mips/dec/time.c linux-2.4.22/arch/mips/dec/time.c --- linux-2.4.21/arch/mips/dec/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -2,278 +2,103 @@ * linux/arch/mips/dec/time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds - * Copyright (C) 2000 Maciej W. Rozycki + * Copyright (C) 2000, 2003 Maciej W. Rozycki * * This file contains the time handling details for PC-style clocks as * found in some MIPS systems. * */ -#include #include #include -#include +#include #include +#include #include +#include #include -#include -#include +#include -#include #include -#include +#include +#include #include #include -#include +#include +#include + +#include #include #include +#include #include #include -#include - -extern void (*board_time_init)(struct irqaction *irq); - -extern volatile unsigned long wall_jiffies; -extern rwlock_t xtime_lock; -/* - * Change this if you have some constant time drift - */ -/* This is the value for the PC-style PICs. */ -/* #define USECS_PER_JIFFY (1000020/HZ) */ - -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) - -/* Cycle counter value at the previous timer interrupt.. */ - -static unsigned int timerhi, timerlo; - -/* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ -static unsigned long cached_quotient = 0; - -/* Last jiffy when do_fast_gettimeoffset() was called. */ -static unsigned long last_jiffies = 0; - -/* - * On MIPS only R4000 and better have a cycle counter. - * - * FIXME: Does playing with the RP bit in c0_status interfere with this code? - */ -static unsigned long do_fast_gettimeoffset(void) +static unsigned long dec_rtc_get_time(void) { - u32 count; - unsigned long res, tmp; - unsigned long quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies != 0) { - unsigned long r0; - __asm__(".set push\n\t" - ".set mips3\n\t" - "lwu %0,%3\n\t" - "dsll32 %1,%2,0\n\t" - "or %1,%1,%0\n\t" - "ddivu $0,%1,%4\n\t" - "mflo %1\n\t" - "dsll32 %0,%5,0\n\t" - "or %0,%0,%6\n\t" - "ddivu $0,%0,%1\n\t" - "mflo %0\n\t" - ".set pop" - : "=&r" (quotient), "=&r" (r0) - : "r" (timerhi), "m" (timerlo), - "r" (tmp), "r" (USECS_PER_JIFFY), - "r" (USECS_PER_JIFFY_FRAC)); - cached_quotient = quotient; - } - } - /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; -//printk("count: %08lx, %08lx:%08lx\n", count, timerhi, timerlo); - - __asm__("multu %2,%3" - : "=l" (tmp), "=h" (res) - : "r" (count), "r" (quotient)); + unsigned int year, mon, day, hour, min, sec, real_year; + int i; - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. + /* The Linux interpretation of the DS1287 clock register contents: + * When the Update-In-Progress (UIP) flag goes from 1 to 0, the + * RTC registers show the second which has precisely just started. + * Let's hope other operating systems interpret the RTC the same way. */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - -static unsigned long do_ioasic_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - unsigned long quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies != 0) { - unsigned long r0; - do_div64_32(r0, timerhi, timerlo, tmp); - do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); - cached_quotient = quotient; - } + /* read RTC exactly on falling edge of update flag */ + for (i = 0; i < 1000000; i++) /* may take up to 1 second... */ + if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) + break; + for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */ + if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + break; + /* Isn't this overkill? UIP above should guarantee consistency */ + do { + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + } while (sec != CMOS_READ(RTC_SECONDS)); + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); } - /* Get last timer tick in absolute kernel time */ - count = ioasic_read(FCTR); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; -//printk("count: %08x, %08x:%08x\n", count, timerhi, timerlo); - - __asm__("multu %2,%3" - : "=l" (tmp), "=h" (res) - : "r" (count), "r" (quotient)); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - -/* This function must be called with interrupts disabled - * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs - * - * However, the pc-audio speaker driver changes the divisor so that - * it gets interrupted rather more often - it loads 64 into the - * counter rather than 11932! This has an adverse impact on - * do_gettimeoffset() -- it stops working! What is also not - * good is that the interval that our timer function gets called - * is no longer 10.0002 ms, but 9.9767 ms. To get around this - * would require using a different timing source. Maybe someone - * could use the RTC - I know that this can interrupt at frequencies - * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix - * it so that at startup, the timer code in sched.c would select - * using either the RTC or the 8253 timer. The decision would be - * based on whether there was any other device around that needed - * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz, - * and then do some jiggery to have a version of do_timer that - * advanced the clock by 1/1024 s. Every time that reached over 1/100 - * of a second, then do all the old code. If the time was kept correct - * then do_gettimeoffset could just return 0 - there is no low order - * divider that can be accessed. - * - * Ideally, you would be able to use the RTC for the speaker driver, - * but it appears that the speaker driver really needs interrupt more - * often than every 120 us or so. - * - * Anyway, this needs more thought.... pjsg (1993-08-28) - * - * If you are really that interested, you should be reading - * comp.protocols.time.ntp! - */ - -#define TICK_SIZE tick - -static unsigned long do_slow_gettimeoffset(void) -{ /* - * This is a kludge until I find a way for the - * DECstations without bus cycle counter. HK - */ - return 0; -} - -static unsigned long (*do_gettimeoffset) (void) = do_slow_gettimeoffset; - -/* - * This version of gettimeofday has near microsecond resolution. - */ -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - - read_lock_irqsave(&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - read_unlock_irqrestore(&xtime_lock, flags); - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } -} - -void do_settimeofday(struct timeval *tv) -{ - write_lock_irq(&xtime_lock); - - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + * The PROM will reset the year to either '72 or '73. + * Therefore we store the real year separately, in one + * of unused BBU RAM locations. */ - tv->tv_usec -= do_gettimeoffset(); - - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + real_year = CMOS_READ(RTC_DEC_YEAR); + year += real_year - 72 + 2000; - write_unlock_irq(&xtime_lock); + return mktime(year, mon, day, hour, min, sec); } /* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when + * In order to set the CMOS clock precisely, dec_rtc_set_mmss has to + * be called 500 ms after the second nowtime has started, because when * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. + * jump to the next second precisely 500 ms later. Check the Dallas + * DS1287 data sheet for details. */ -static int set_rtc_mmss(unsigned long nowtime) +static int dec_rtc_set_mmss(unsigned long nowtime) { int retval = 0; int real_seconds, real_minutes, cmos_minutes; unsigned char save_control, save_freq_select; - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ + /* tell the clock it's being set */ + save_control = CMOS_READ(RTC_CONTROL); CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL); - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ + /* stop and reset prescaler */ + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT); cmos_minutes = CMOS_READ(RTC_MINUTES); @@ -307,10 +132,9 @@ } /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data + * otherwise the DS1287 will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned + * in the Dallas Semiconductor data sheets, but who believes data * sheets anyway ... -- Markus Kuhn */ CMOS_WRITE(save_control, RTC_CONTROL); @@ -319,170 +143,45 @@ return retval; } -/* last time the cmos clock got updated */ -static long last_rtc_update; -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - */ -static void inline -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void dec_timer_ack(void) { - volatile unsigned char dummy; - - dummy = CMOS_READ(RTC_REG_C); /* ACK RTC Interrupt */ - - if (!user_mode(regs)) { - if (prof_buffer && current->pid) { - extern int _stext; - unsigned long pc = regs->cp0_epc; - - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - /* - * Dont ignore out-of-bounds pc values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - if (pc > prof_len - 1) - pc = prof_len - 1; - atomic_inc((atomic_t *) & prof_buffer[pc]); - } - } - do_timer(regs); - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - read_lock(&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 - && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - tick / 2 - && xtime.tv_usec <= 500000 + tick / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } - /* As we return to user mode fire off the other CPU schedulers.. this is - basically because we don't yet share IRQ's around. This message is - rigged to be safe on the 386 - basically it's a hack, so don't look - closely for now.. */ - /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */ - read_unlock(&xtime_lock); + CMOS_READ(RTC_REG_C); /* Ack the RTC interrupt. */ } -static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static unsigned int dec_ioasic_hpt_read(void) { - unsigned int count; - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. + * The free-running counter is 32-bit which is good for about + * 2 minutes, 50 seconds at possible count rates of up to 25MHz. */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - - if (jiffies == ~0) { - /* - * If jiffies is to overflow in this timer_interrupt we must - * update the timer[hi]/[lo] to make do_fast_gettimeoffset() - * quotient calc still valid. -arca - */ - write_32bit_cp0_register(CP0_COUNT, 0); - timerhi = timerlo = 0; - } - - timer_interrupt(irq, dev_id, regs); + return ioasic_read(IO_REG_FCTR); } -static void ioasic_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void dec_ioasic_hpt_init(unsigned int count) { - unsigned int count; - - /* - * The free-running counter is 32 bit which is good for about - * 2 minutes, 50 seconds at possible count rates of upto 25MHz. - */ - count = ioasic_read(FCTR); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - - if (jiffies == ~0) { - /* - * If jiffies is to overflow in this timer_interrupt we must - * update the timer[hi]/[lo] to make do_fast_gettimeoffset() - * quotient calc still valid. -arca - */ - ioasic_write(FCTR, 0); - timerhi = timerlo = 0; - } - - timer_interrupt(irq, dev_id, regs); + ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count); } -struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, - "timer", NULL, NULL}; -void __init time_init(void) +void __init dec_time_init(void) { - unsigned int year, mon, day, hour, min, sec, real_year; - int i; + rtc_get_time = dec_rtc_get_time; + rtc_set_mmss = dec_rtc_set_mmss; - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0; i < 1000000; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); + mips_timer_ack = dec_timer_ack; + if (!cpu_has_counter && IOASIC) { + /* For pre-R4k systems we use the I/O ASIC's counter. */ + mips_hpt_read = dec_ioasic_hpt_read; + mips_hpt_init = dec_ioasic_hpt_init; } - /* - * The PROM will reset the year to either '72 or '73. - * Therefore we store the real year separately, in one - * of unused BBU RAM locations. - */ - real_year = CMOS_READ(RTC_DEC_YEAR); - year += real_year - 72 + 2000; +} + +void __init dec_timer_setup(struct irqaction *irq) +{ + /* Enable periodic DS1287 interrupts. */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A); + CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B); - write_lock_irq(&xtime_lock); - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_usec = 0; - write_unlock_irq(&xtime_lock); - - if (mips_cpu.options & MIPS_CPU_COUNTER) { - write_32bit_cp0_register(CP0_COUNT, 0); - do_gettimeoffset = do_fast_gettimeoffset; - irq0.handler = r4k_timer_interrupt; - } else if (IOASIC) { - ioasic_write(FCTR, 0); - do_gettimeoffset = do_ioasic_gettimeoffset; - irq0.handler = ioasic_timer_interrupt; - } - board_time_init(&irq0); + setup_irq(dec_interrupt[DEC_IRQ_RTC], irq); } diff -urN linux-2.4.21/arch/mips/dec/wbflush.c linux-2.4.22/arch/mips/dec/wbflush.c --- linux-2.4.21/arch/mips/dec/wbflush.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/dec/wbflush.c 2003-08-25 04:44:39.000000000 -0700 @@ -39,6 +39,7 @@ case MACH_DS5000_1XX: /* DS5000/100 3min */ case MACH_DS5000_XX: /* Personal DS5000/2x */ case MACH_DS5000_2X0: /* DS5000/240 3max+ */ + case MACH_DS5900: /* DS5900 bigmax */ default: __wbflush = wbflush_mips; break; diff -urN linux-2.4.21/arch/mips/defconfig linux-2.4.22/arch/mips/defconfig --- linux-2.4.21/arch/mips/defconfig 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +58,28 @@ # CONFIG_NINO is not set CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y -CONFIG_ARC_CONSOLE=y -CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y CONFIG_BOOT_ELF32=y -CONFIG_SWAP_IO_SPACE=y +# CONFIG_SWAP_IO_SPACE_W is not set +CONFIG_SWAP_IO_SPACE_L=y CONFIG_IRQ_CPU=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SGI=y # CONFIG_MIPS_AU1000 is not set # @@ -91,7 +101,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,7 +113,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_BINFMT_IRIX=y -CONFIG_FORWARD_KEYBOARD=y CONFIG_ARC_CONSOLE=y # CONFIG_IP22_EISA is not set CONFIG_NET=y @@ -125,9 +133,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -282,6 +291,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -310,6 +320,7 @@ # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -354,6 +365,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -443,6 +455,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -451,6 +468,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -461,6 +479,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -468,8 +487,12 @@ # CONFIG_MACHZ_WDT is not set CONFIG_INDYDOG=y # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -482,16 +505,10 @@ # CONFIG_DRM is not set # -# SGI Character devices -# -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -501,11 +518,12 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -536,7 +554,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set # CONFIG_UDF_RW is not set @@ -550,6 +568,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -599,6 +618,9 @@ # Console drivers # # CONFIG_VGA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_DUMMY_CONSOLE=y # CONFIG_MDA_CONSOLE is not set # @@ -609,15 +631,31 @@ # # Sound # -# CONFIG_SOUND is not set - -# -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_HAL2=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -633,12 +671,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-atlas linux-2.4.22/arch/mips/defconfig-atlas --- linux-2.4.21/arch/mips/defconfig-atlas 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-atlas 2003-08-25 04:44:39.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set CONFIG_MIPS_ATLAS=y # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,21 +56,27 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y # CONFIG_MIPS_AU1000 is not set # @@ -96,7 +112,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set @@ -115,9 +130,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -271,6 +287,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -313,6 +330,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -357,14 +375,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -381,8 +402,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -399,6 +420,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -484,13 +506,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -506,6 +536,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -515,6 +546,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -564,6 +596,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -629,14 +662,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-bosporus linux-2.4.22/arch/mips/defconfig-bosporus --- linux-2.4.21/arch/mips/defconfig-bosporus 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-bosporus 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,931 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +CONFIG_MIPS_BOSPORUS=y +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PC_KEYB=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +CONFIG_MTD_BOSPORUS=y +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_FTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_LIMIT is not set +# CONFIG_IP_NF_MATCH_MAC is not set +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +# CONFIG_IP_NF_MATCH_MARK is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_TCPMSS is not set +# CONFIG_IP_NF_MATCH_HELPER is not set +# CONFIG_IP_NF_MATCH_STATE is not set +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_MIRROR is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_TOS is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +# CONFIG_IP_NF_TARGET_MARK is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_PLX_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_DEBUG=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-capcella linux-2.4.22/arch/mips/defconfig-capcella --- linux-2.4.21/arch/mips/defconfig-capcella 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-capcella 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,17 +58,17 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set CONFIG_ZAO_CAPCELLA=y # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_CPU_VR41XX=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y CONFIG_VR41XX_TIME_C=y @@ -118,9 +128,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -250,15 +261,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -272,15 +274,15 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_IDEPCI is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -329,14 +331,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -353,8 +358,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -371,6 +376,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -457,6 +463,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -465,6 +476,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -475,6 +487,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -482,8 +495,11 @@ # CONFIG_MACHZ_WDT is not set # CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -499,6 +515,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -508,6 +525,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -557,6 +575,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -632,14 +651,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-cobalt linux-2.4.22/arch/mips/defconfig-cobalt --- linux-2.4.21/arch/mips/defconfig-cobalt 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-cobalt 2003-08-25 04:44:39.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set CONFIG_MIPS_COBALT=y # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,10 +56,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,7 +70,6 @@ CONFIG_COBALT_LCD=y CONFIG_I8259=y CONFIG_PCI=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_MIPS_AU1000 is not set @@ -81,7 +93,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -110,9 +121,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -238,15 +250,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -260,8 +263,8 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set @@ -270,30 +273,29 @@ # 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_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # 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_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_PIIX_TUNING is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -306,6 +308,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -354,8 +357,10 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -364,6 +369,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -380,8 +386,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -398,6 +404,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -483,13 +490,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -505,6 +520,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -514,6 +530,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -563,6 +580,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -627,14 +645,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-db1000 linux-2.4.22/arch/mips/defconfig-db1000 --- linux-2.4.21/arch/mips/defconfig-db1000 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-db1000 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,980 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +CONFIG_MIPS_DB1000=y +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1000=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +# CONFIG_PCI_AUTO is not set +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +CONFIG_MTD_DB1X00=y +CONFIG_MTD_DB1X00_BOOT=y +CONFIG_MTD_DB1X00_USER=y +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set +# CONFIG_IRPORT_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +CONFIG_AU1000_FIR=m +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-db1100 linux-2.4.22/arch/mips/defconfig-db1100 --- linux-2.4.21/arch/mips/defconfig-db1100 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-db1100 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,1019 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +CONFIG_MIPS_DB1100=y +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1100=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +CONFIG_MTD_DB1X00=y +# CONFIG_MTD_DB1X00_BOOT is not set +CONFIG_MTD_DB1X00_USER=y +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set +# CONFIG_IRPORT_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +CONFIG_AU1000_FIR=m +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set +CONFIG_FB_AU1100=y +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-db1500 linux-2.4.22/arch/mips/defconfig-db1500 --- linux-2.4.21/arch/mips/defconfig-db1500 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-db1500 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,859 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +CONFIG_MIPS_DB1500=y +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=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_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-ddb5476 linux-2.4.22/arch/mips/defconfig-ddb5476 --- linux-2.4.21/arch/mips/defconfig-ddb5476 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-ddb5476 2003-08-25 04:44:39.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set CONFIG_DDB5476=y # CONFIG_DDB5477 is not set @@ -46,10 +56,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,7 +70,6 @@ CONFIG_ISA=y CONFIG_PCI=y CONFIG_PC_KEYB=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_I8259=y CONFIG_HAVE_STD_PC_SERIAL_PORT=y @@ -113,9 +125,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -244,15 +257,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -266,8 +270,8 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_IDEDMA_PCI is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -276,30 +280,29 @@ # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_IDEDMA is not set # 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 is not set +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # 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_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_PIIX_TUNING is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -307,10 +310,11 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -361,9 +365,11 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_AC3200 is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -372,6 +378,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -388,8 +395,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -406,6 +413,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -501,13 +509,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -523,6 +539,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -532,6 +549,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -581,6 +599,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -632,6 +651,7 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set CONFIG_FB_3DFX=y @@ -667,14 +687,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +CONFIG_RUNTIME_DEBUG=y +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -CONFIG_DEBUG=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-ddb5477 linux-2.4.22/arch/mips/defconfig-ddb5477 --- linux-2.4.21/arch/mips/defconfig-ddb5477 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-ddb5477 2003-08-25 04:44:39.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set CONFIG_DDB5477=y @@ -47,22 +57,24 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_PCI=y CONFIG_NEW_TIME_C=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y -CONFIG_DUMMY_KEYB=y +CONFIG_PC_KEYB=y CONFIG_I8259=y # CONFIG_MIPS_AU1000 is not set @@ -113,9 +125,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -280,8 +293,10 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -290,6 +305,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -306,8 +322,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -324,6 +340,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -409,13 +426,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -431,6 +456,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -440,6 +466,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -489,6 +516,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -563,14 +591,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +CONFIG_RUNTIME_DEBUG=y +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -CONFIG_DEBUG=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-decstation linux-2.4.22/arch/mips/defconfig-decstation --- linux-2.4.21/arch/mips/defconfig-decstation 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-decstation 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set CONFIG_DECSTATION=y # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,16 +58,21 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y CONFIG_IRQ_CPU=y -CONFIG_NEW_IRQ=y +CONFIG_L1_CACHE_SHIFT=4 +CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_MIPS_AU1000 is not set @@ -108,9 +123,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -263,6 +279,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -291,6 +308,7 @@ # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -335,6 +353,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -389,10 +408,35 @@ # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_SERIAL_DEC=y +CONFIG_SERIAL_DEC_CONSOLE=y +CONFIG_DZ=y +CONFIG_ZS=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -420,13 +464,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -439,18 +491,10 @@ # CONFIG_DRM is not set # -# DECStation Character devices -# -CONFIG_SERIAL=y -# CONFIG_DZ is not set -CONFIG_ZS=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_RTC is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -460,6 +504,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -509,6 +554,7 @@ # CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -573,14 +619,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-e55 linux-2.4.22/arch/mips/defconfig-e55 --- linux-2.4.21/arch/mips/defconfig-e55 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-e55 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,629 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +CONFIG_CASIO_E55=y +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +CONFIG_ISA=y +CONFIG_DUMMY_KEYB=y +# CONFIG_SCSI is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI is not set +CONFIG_EISA=y +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-eagle linux-2.4.22/arch/mips/defconfig-eagle --- linux-2.4.21/arch/mips/defconfig-eagle 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-eagle 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,25 +48,28 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set CONFIG_NEC_EAGLE=y +CONFIG_VRC4173=y # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_CPU_VR41XX=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y CONFIG_VR41XX_TIME_C=y @@ -106,9 +118,24 @@ # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_VRC4173=y + +# +# PCI Hotplug Support +# # CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -117,9 +144,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -129,6 +157,7 @@ # CONFIG_MTD_PARTITIONS is not set # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -151,6 +180,7 @@ # CONFIG_MTD_CFI_GEOMETRY is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -169,15 +199,20 @@ # CONFIG_MTD_PB1000 is not set # CONFIG_MTD_PB1500 is not set # CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -303,9 +338,43 @@ # # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set # 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_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -354,14 +423,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -378,8 +450,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -396,6 +468,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -423,6 +496,22 @@ # CONFIG_WAN is not set # +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +CONFIG_PCMCIA_FMVJ18X=y +CONFIG_PCMCIA_PCNET=m +# 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_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -486,6 +575,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -494,6 +588,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -504,6 +599,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -511,8 +607,11 @@ # CONFIG_MACHZ_WDT is not set # CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -525,9 +624,16 @@ # CONFIG_DRM is not set # +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set + +# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -537,6 +643,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -589,6 +696,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -653,7 +761,110 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# Input core support is needed for USB HID input layer or HIDBP support +# +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -664,14 +875,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.21/arch/mips/defconfig-ev64120 linux-2.4.22/arch/mips/defconfig-ev64120 --- linux-2.4.21/arch/mips/defconfig-ev64120 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-ev64120 2003-08-25 04:44:39.000000000 -0700 @@ -21,11 +21,18 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set CONFIG_MIPS_EV64120=y @@ -36,6 +43,8 @@ # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -43,6 +52,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,10 +62,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -86,7 +99,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,7 +111,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set @@ -118,9 +129,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -284,14 +296,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -308,8 +323,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -326,6 +341,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -418,11 +434,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -440,6 +463,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -449,6 +473,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -498,6 +523,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -548,14 +574,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-ev96100 linux-2.4.22/arch/mips/defconfig-ev96100 --- linux-2.4.21/arch/mips/defconfig-ev96100 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-ev96100 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set CONFIG_MIPS_EV96100=y # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,21 +58,26 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOARD_SCACHE=y CONFIG_PCI=y +CONFIG_MIPS_GT64120=y CONFIG_MIPS_GT96100=y -CONFIG_NEW_IRQ=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y # CONFIG_MIPS_AU1000 is not set # @@ -97,7 +112,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set @@ -116,9 +130,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -283,8 +298,10 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -293,6 +310,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -309,8 +327,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -327,6 +345,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -412,11 +431,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -434,6 +460,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -443,6 +470,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -492,6 +520,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -542,14 +571,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-hp-lj linux-2.4.22/arch/mips/defconfig-hp-lj --- linux-2.4.21/arch/mips/defconfig-hp-lj 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-hp-lj 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,101 +11,203 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +CONFIG_HP_LASERJET=y +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -CONFIG_MIPS_MALTA=y -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_I8259=y -CONFIG_PCI=y -CONFIG_HAVE_STD_PC_SERIAL_PORT=y -CONFIG_NEW_IRQ=y +CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y +CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y -CONFIG_SWAP_IO_SPACE=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +CONFIG_PCI=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set +CONFIG_CPU_R5000=y # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS64 is not set -CONFIG_CPU_HAS_PREFETCH=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y -# CONFIG_CPU_HAS_LLDSCD is not set +CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=10040000 +CONFIG_MTD_PHYSMAP_LEN=00fc0000 +CONFIG_MTD_PHYSMAP_BUSWIDTH=4 +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=y # # Parallel port support @@ -112,19 +215,27 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # -CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # 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_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -141,7 +252,8 @@ # # Networking options # -# CONFIG_PACKET is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set @@ -150,7 +262,7 @@ # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_DHCP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set @@ -168,6 +280,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -185,6 +302,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -194,81 +316,85 @@ # # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set +CONFIG_IDE=y # -# SCSI support +# IDE, ATA and ATAPI Block devices # -CONFIG_SCSI=y +CONFIG_BLK_DEV_IDE=y # -# SCSI support type (disk, tape, CD-ROM) +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_CMD640=y +CONFIG_BLK_DEV_CMD640_ENHANCED=y +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=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_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support # -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI is not set # # I2O device support @@ -311,16 +437,21 @@ # CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y -CONFIG_PCNET32=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_TC35815 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -332,10 +463,11 @@ # 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_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set @@ -348,11 +480,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -362,7 +497,18 @@ # # Wireless LAN (non-hamradio) # -# CONFIG_NET_RADIO is not set +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_PLX_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -393,9 +539,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -405,8 +555,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_UNIX98_PTYS is not set # # I2C support @@ -432,14 +581,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set -CONFIG_RTC=y +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -452,15 +608,11 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set @@ -469,6 +621,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -477,15 +632,19 @@ # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set -CONFIG_EFS_FS=y +# CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=3 # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # 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 @@ -495,7 +654,7 @@ # CONFIG_DEVFS_FS is not set # CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set @@ -512,12 +671,15 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -529,7 +691,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 @@ -540,6 +701,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # # CONFIG_SOUND is not set @@ -550,119 +716,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers +# Bluetooth support # -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_BLUEZ is not set # -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# 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 -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# 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 -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.21/arch/mips/defconfig-ip22 linux-2.4.22/arch/mips/defconfig-ip22 --- linux-2.4.21/arch/mips/defconfig-ip22 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-ip22 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +58,28 @@ # CONFIG_NINO is not set CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y -CONFIG_ARC_CONSOLE=y -CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y CONFIG_BOOT_ELF32=y -CONFIG_SWAP_IO_SPACE=y +# CONFIG_SWAP_IO_SPACE_W is not set +CONFIG_SWAP_IO_SPACE_L=y CONFIG_IRQ_CPU=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SGI=y # CONFIG_MIPS_AU1000 is not set # @@ -91,7 +101,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,7 +113,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_BINFMT_IRIX=y -CONFIG_FORWARD_KEYBOARD=y CONFIG_ARC_CONSOLE=y # CONFIG_IP22_EISA is not set CONFIG_NET=y @@ -125,9 +133,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -282,6 +291,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -310,6 +320,7 @@ # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -354,6 +365,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -411,7 +423,30 @@ CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_IP22_SERIAL=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -443,6 +478,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -451,6 +491,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -461,6 +502,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -468,8 +510,12 @@ # CONFIG_MACHZ_WDT is not set CONFIG_INDYDOG=y # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -482,16 +528,10 @@ # CONFIG_DRM is not set # -# SGI Character devices -# -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -501,11 +541,12 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -536,7 +577,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set # CONFIG_UDF_RW is not set @@ -550,6 +591,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -599,6 +641,9 @@ # Console drivers # # CONFIG_VGA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_DUMMY_CONSOLE=y # CONFIG_MDA_CONSOLE is not set # @@ -609,15 +654,31 @@ # # Sound # -# CONFIG_SOUND is not set - -# -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_HAL2=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -633,12 +694,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-it8172 linux-2.4.22/arch/mips/defconfig-it8172 --- linux-2.4.21/arch/mips/defconfig-it8172 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-it8172 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,40 +11,65 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +CONFIG_MIPS_ITE8172=y +# CONFIG_IT8172_REVC is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -CONFIG_MIPS_ITE8172=y -# CONFIG_IT8172_REVC is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set CONFIG_PCI=y CONFIG_IT8712=y CONFIG_PC_KEYB=y @@ -51,58 +77,60 @@ CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y CONFIG_IT8172_CIR=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set CONFIG_CPU_NEVADA=y +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) @@ -110,7 +138,9 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -130,6 +160,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -147,8 +178,16 @@ CONFIG_MTD_PHYSMAP_BUSWIDTH=4 # CONFIG_MTD_PB1000 is not set # CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers @@ -177,6 +216,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -184,11 +229,14 @@ # 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_UMEM is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -233,6 +281,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -250,6 +303,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -273,20 +331,13 @@ # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set # # IDE chipset support/bugfixes @@ -294,54 +345,45 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set 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_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y -CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_IDE_CHIPSETS=y - -# -# Note: most of these also require special kernel boot parameters -# -# CONFIG_BLK_DEV_4DRIVES is not set -# CONFIG_BLK_DEV_ALI14XX is not set -# CONFIG_BLK_DEV_DTC2278 is not set -# CONFIG_BLK_DEV_HT6560B is not set -# CONFIG_BLK_DEV_PDC4030 is not set -# CONFIG_BLK_DEV_QD65XX is not set -# CONFIG_BLK_DEV_UMC8672 is not set +# CONFIG_IDE_CHIPSETS is not set CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set @@ -349,6 +391,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -397,17 +440,20 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y -# CONFIG_TC35815 is not set # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -419,10 +465,11 @@ # 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_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set @@ -435,11 +482,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -480,9 +530,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -523,14 +577,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set -CONFIG_RTC=y +# CONFIG_RTC is not set +CONFIG_MIPS_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -544,14 +605,10 @@ # CONFIG_ITE_GPIO is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -561,6 +618,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -574,10 +634,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # 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 @@ -605,9 +668,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -621,7 +686,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 @@ -632,9 +696,15 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set @@ -646,11 +716,11 @@ # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set # CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set # CONFIG_SOUND_ICH is not set CONFIG_SOUND_IT8172=y # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_HAL2 is not set CONFIG_SOUND_IT8172=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -666,123 +736,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set - -# -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Bluetooth support # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# 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 -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# 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 -# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_BLUEZ is not set # -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-ivr linux-2.4.22/arch/mips/defconfig-ivr --- linux-2.4.21/arch/mips/defconfig-ivr 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-ivr 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,31 +21,51 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set CONFIG_MIPS_IVR=y # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SIBYTE_SB1250 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set @@ -54,32 +75,33 @@ CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y CONFIG_IT8172_CIR=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y # CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set CONFIG_CPU_NEVADA=y +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup @@ -102,8 +124,11 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -136,6 +161,7 @@ # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -231,15 +257,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -253,8 +270,8 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set @@ -263,32 +280,30 @@ # 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_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # 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_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y -CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -301,6 +316,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -349,17 +365,20 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y -# CONFIG_TC35815 is not set # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -371,10 +390,11 @@ # 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_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set @@ -387,10 +407,12 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -433,6 +455,17 @@ # CONFIG_ISDN is not set # +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# # Character devices # CONFIG_VT=y @@ -493,13 +526,21 @@ # CONFIG_INPUT_GAMECON is not set # CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -512,14 +553,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -529,6 +566,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -546,6 +586,9 @@ # CONFIG_ISO9660_FS is not set # 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 @@ -573,9 +616,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -589,7 +634,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 @@ -600,6 +644,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -626,7 +675,6 @@ # # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_LONG_TIMEOUT is not set # # USB Host Controller Drivers @@ -642,6 +690,7 @@ # CONFIG_USB_AUDIO is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set # # SCSI support is needed for USB Storage @@ -654,6 +703,7 @@ # CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_HP8200e is not set # CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set @@ -664,7 +714,10 @@ CONFIG_USB_HID=y # CONFIG_USB_HIDINPUT is not set # CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set # # USB Imaging devices @@ -690,6 +743,7 @@ # CONFIG_USB_RTL8150 is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set # CONFIG_USB_CDCETHER is not set # CONFIG_USB_USBNET is not set @@ -702,39 +756,15 @@ # USB Serial Converter support # # CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# 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 -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# 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 -# CONFIG_USB_SERIAL_OMNINET is not set # # USB Miscellaneous drivers # # CONFIG_USB_RIO500 is not set # CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set # CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -742,22 +772,23 @@ # CONFIG_BLUEZ is not set # -# Input core support -# -CONFIG_INPUT=y -CONFIG_INPUT_KEYBDEV=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-jmr3927 linux-2.4.22/arch/mips/defconfig-jmr3927 --- linux-2.4.21/arch/mips/defconfig-jmr3927 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-jmr3927 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,99 +11,126 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set CONFIG_TOSHIBA_JMR3927=y -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_NONCOHERENT_IO=y CONFIG_TOSHIBA_BOARDS=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_NONCOHERENT_IO=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_PC_KEYB=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set CONFIG_CPU_TX39XX=y -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_RTC_DS1742=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) @@ -115,6 +143,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -122,11 +156,14 @@ # 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_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -171,6 +208,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -188,6 +230,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -248,15 +295,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set -CONFIG_TC35815=y # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -268,11 +318,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_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set +CONFIG_TC35815=y # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -284,11 +336,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -329,9 +384,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -350,6 +409,7 @@ # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -358,7 +418,8 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -# CONFIG_AU1000_UART is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set CONFIG_TXX927_SERIAL=y CONFIG_TXX927_SERIAL_CONSOLE=y # CONFIG_UNIX98_PTYS is not set @@ -387,14 +448,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -407,14 +475,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -424,6 +488,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -437,10 +504,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # 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 @@ -468,9 +538,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -484,7 +556,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 @@ -495,6 +566,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -508,15 +584,19 @@ # CONFIG_FB_RIVA is not set # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y CONFIG_FBCON_MFB=y @@ -551,121 +631,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers +# Bluetooth support # -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set +# CONFIG_BLUEZ is not set # -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# 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 -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# 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 -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-lasat linux-2.4.22/arch/mips/defconfig-lasat --- linux-2.4.21/arch/mips/defconfig-lasat 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-lasat 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,741 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +CONFIG_LASAT=y +CONFIG_PICVUE=y +CONFIG_PICVUE_PROC=y +CONFIG_DS1603=y +CONFIG_LASAT_SYSCTL=y +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOARD_SCACHE=y +CONFIG_R5000_CPU_SCACHE=y +CONFIG_PCI=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_NILE4=y +CONFIG_NONCOHERENT_IO=y +CONFIG_NEW_TIME_C=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +CONFIG_CPU_R5000=y +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLOCK is not set +CONFIG_MTD_BLOCK_RO=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +CONFIG_MTD_LASAT=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=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_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO 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_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-malta linux-2.4.22/arch/mips/defconfig-malta --- linux-2.4.21/arch/mips/defconfig-malta 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-malta 2003-08-25 04:44:39.000000000 -0700 @@ -13,23 +13,34 @@ # # Loadable module support # -# CONFIG_MODULES is not set +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y # # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,10 +58,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,11 +72,14 @@ CONFIG_BOOT_ELF32=y CONFIG_HAVE_STD_PC_SERIAL_PORT=y CONFIG_I8259=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_PC_KEYB=y CONFIG_PCI=y # CONFIG_MIPS_AU1000 is not set @@ -116,9 +134,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -178,8 +197,8 @@ # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -270,6 +289,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -306,6 +326,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -350,14 +371,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -374,8 +398,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -392,6 +416,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -477,13 +502,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -499,6 +532,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -508,6 +542,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -556,13 +591,15 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y # CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -607,14 +644,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-mirage linux-2.4.22/arch/mips/defconfig-mirage --- linux-2.4.21/arch/mips/defconfig-mirage 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-mirage 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,768 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +CONFIG_MIPS_MIRAGE=y +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PC_KEYB=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-mpc30x linux-2.4.22/arch/mips/defconfig-mpc30x --- linux-2.4.21/arch/mips/defconfig-mpc30x 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-mpc30x 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,684 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +CONFIG_VICTOR_MPC30X=y +CONFIG_VRC4173=y +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_ISA is not set +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_DUMMY_KEYB=y +# CONFIG_SCSI is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# Input core support is needed for USB HID input layer or HIDBP support +# +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-mtx-1 linux-2.4.22/arch/mips/defconfig-mtx-1 --- linux-2.4.21/arch/mips/defconfig-mtx-1 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-mtx-1 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,663 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +CONFIG_MIPS_MTX1=y +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +CONFIG_MTD_MTX1=y +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-nino linux-2.4.22/arch/mips/defconfig-nino --- linux-2.4.21/arch/mips/defconfig-nino 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-nino 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,95 +11,123 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -CONFIG_NINO=y -# CONFIG_NINO_4MB is not set -CONFIG_NINO_8MB=y -# CONFIG_NINO_16MB is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +CONFIG_NINO=y +# CONFIG_NINO_4MB is not set +CONFIG_NINO_8MB=y +# CONFIG_NINO_16MB is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set CONFIG_CPU_R3000=y # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set # CONFIG_CPU_HAS_WB is not set +# CONFIG_CPU_HAS_SYNC is not set # # General setup # CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) @@ -111,6 +140,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -118,12 +153,15 @@ # 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_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=512 CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set # # MIPS initrd options @@ -170,6 +208,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -187,6 +230,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -206,15 +254,6 @@ # CONFIG_SCSI is not set # -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# # Network device support # # CONFIG_NETDEVICES is not set @@ -235,9 +274,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -257,6 +300,7 @@ # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -265,7 +309,8 @@ # CONFIG_STALDRV is not set CONFIG_SERIAL_TX3912=y CONFIG_SERIAL_TX3912_CONSOLE=y -# CONFIG_AU1000_UART is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set # CONFIG_TXX927_SERIAL is not set # CONFIG_UNIX98_PTYS is not set @@ -293,14 +338,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -313,14 +365,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -330,6 +378,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -343,10 +394,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # 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 @@ -374,9 +428,11 @@ # CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set # CONFIG_SUNRPC is not set # CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set @@ -390,7 +446,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 @@ -401,6 +456,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -412,14 +472,6 @@ CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y # CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_TRIDENT is not set CONFIG_FB_TX3912=y # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y @@ -455,121 +507,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set - -# -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID +# Bluetooth support # +# CONFIG_BLUEZ is not set # -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# 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 -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# 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 -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-ocelot linux-2.4.22/arch/mips/defconfig-ocelot --- linux-2.4.21/arch/mips/defconfig-ocelot 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-ocelot 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,102 +11,205 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set CONFIG_MOMENCO_OCELOT=y +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set +CONFIG_BOARD_SCACHE=y CONFIG_PCI=y CONFIG_SYSCLK_100=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_NEW_IRQ=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_NONCOHERENT_IO=y CONFIG_OLD_TIME_C=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -CONFIG_CPU_RM7000=y +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # # CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +CONFIG_NFTL=y +CONFIG_NFTL_RW=y + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +# CONFIG_MTD_GEN_PROBE is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +CONFIG_MTD_OBSOLETE_CHIPS=y +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +CONFIG_MTD_JEDEC=y + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +CONFIG_MTD_OCELOT=y +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +CONFIG_MTD_DOC2000=y +# CONFIG_MTD_DOC2001 is not set +CONFIG_MTD_DOCPROBE=y +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_HIGH is not set +# CONFIG_MTD_DOCPROBE_55AA is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +CONFIG_MTD_NAND_IDS=y # # Parallel port support @@ -113,6 +217,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -120,11 +230,14 @@ # 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_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -168,6 +281,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -185,6 +303,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -245,15 +368,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 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 CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -265,10 +391,11 @@ # 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_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set @@ -281,11 +408,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -326,9 +456,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -365,12 +499,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -385,14 +525,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -402,6 +538,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -415,10 +554,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # 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 @@ -446,9 +588,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -462,7 +606,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 @@ -473,6 +616,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # # CONFIG_SOUND is not set @@ -483,123 +631,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set - -# -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices +# Bluetooth support # -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_BLUEZ is not set # -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# 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 -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# 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 -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-osprey linux-2.4.22/arch/mips/defconfig-osprey --- linux-2.4.21/arch/mips/defconfig-osprey 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-osprey 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,38 +21,55 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set CONFIG_NEC_OSPREY=y +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SIBYTE_SB1250 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_VR4181=y -CONFIG_SERIAL=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y @@ -62,25 +80,27 @@ # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set CONFIG_CPU_VR41XX=y # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup @@ -103,8 +123,11 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -137,6 +160,7 @@ # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -215,6 +239,13 @@ # CONFIG_PHONE_IXJ_PCMCIA is not set # +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# # SCSI support # # CONFIG_SCSI is not set @@ -256,10 +287,12 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -302,13 +335,27 @@ # CONFIG_ISDN is not set # +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# # Character devices # CONFIG_VT=y # CONFIG_VT_CONSOLE is not set CONFIG_SERIAL=y CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_EXTENDED=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -337,13 +384,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -356,14 +411,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -373,6 +424,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -390,6 +444,9 @@ # CONFIG_ISO9660_FS is not set # 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 @@ -417,9 +474,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -433,7 +492,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 @@ -444,6 +502,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -470,20 +533,23 @@ # CONFIG_BLUEZ is not set # -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-pb1000 linux-2.4.22/arch/mips/defconfig-pb1000 --- linux-2.4.21/arch/mips/defconfig-pb1000 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-pb1000 2003-08-25 04:44:39.000000000 -0700 @@ -21,18 +21,27 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set CONFIG_MIPS_PB1000=y CONFIG_PCI_AUTO=y # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -40,6 +49,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -49,22 +59,26 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_MIPS_AU1000=y -CONFIG_NEW_IRQ=y +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1000=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_AU1000_USB_DEVICE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection @@ -88,10 +102,10 @@ CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_ADVANCED=y +# CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_LLDSCD is not set -CONFIG_CPU_HAS_WB=y +# CONFIG_CPU_HAS_WB is not set CONFIG_CPU_HAS_SYNC=y # @@ -115,8 +129,11 @@ # CONFIG_TCIC is not set # CONFIG_I82092 is not set # CONFIG_I82365 is not set -CONFIG_PCMCIA_AU1000=m +CONFIG_PCMCIA_AU1X00=m CONFIG_PCMCIA_PB1X00=y +# CONFIG_PCMCIA_DB1X00 is not set +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -124,7 +141,6 @@ # CONFIG_HOTPLUG_PCI is not set # CONFIG_HOTPLUG_PCI_COMPAQ is not set # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -133,6 +149,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -145,6 +163,7 @@ CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -163,6 +182,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set # CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -178,15 +198,20 @@ CONFIG_MTD_PB1000=y # CONFIG_MTD_PB1500 is not set # CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -326,15 +351,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set CONFIG_BLK_DEV_IDECS=m # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -348,15 +364,15 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_IDEPCI is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -392,7 +408,8 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AU1000_ENET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set @@ -417,6 +434,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -505,6 +523,7 @@ # CONFIG_USB_IRDA is not set # CONFIG_NSC_FIR is not set # CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set # CONFIG_TOSHIBA_FIR is not set CONFIG_AU1000_FIR=m # CONFIG_SMC_IRCC_FIR is not set @@ -519,11 +538,13 @@ # # Input core support # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=y # # Character devices @@ -552,10 +573,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -CONFIG_AU1000_UART=y -CONFIG_AU1000_SERIAL_CONSOLE=y -# CONFIG_AU1000_USB_TTY is not set -# CONFIG_AU1000_USB_RAW is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set # CONFIG_TXX927_SERIAL is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -575,20 +598,49 @@ # Joysticks # # CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set # -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks +# Joysticks # +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -607,13 +659,14 @@ # # CONFIG_PCMCIA_SERIAL_CS is not set # CONFIG_SYNCLINK_CS is not set -CONFIG_AU1000_GPIO=y -# CONFIG_TS_AU1000_ADS7846 is not set +CONFIG_AU1X00_GPIO=m +# CONFIG_TS_AU1X00_ADS7846 is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -623,6 +676,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -673,6 +727,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -724,6 +779,7 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set @@ -776,7 +832,7 @@ # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -CONFIG_SOUND_AU1000=y +CONFIG_SOUND_AU1X00=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set @@ -788,7 +844,104 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -799,14 +952,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.21/arch/mips/defconfig-pb1100 linux-2.4.22/arch/mips/defconfig-pb1100 --- linux-2.4.21/arch/mips/defconfig-pb1100 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-pb1100 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set CONFIG_MIPS_PB1100=y # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,23 +58,27 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_MIPS_AU1000=y -CONFIG_NEW_IRQ=y +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1100=y CONFIG_PCI=y # CONFIG_PCI_AUTO is not set CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_AU1000_USB_DEVICE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection @@ -88,10 +102,10 @@ CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_ADVANCED=y +# CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_LLDSCD is not set -CONFIG_CPU_HAS_WB=y +# CONFIG_CPU_HAS_WB is not set CONFIG_CPU_HAS_SYNC=y # @@ -105,26 +119,9 @@ # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=m -# CONFIG_CARDBUS is not set -# CONFIG_TCIC is not set -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set -CONFIG_PCMCIA_AU1000=m -CONFIG_PCMCIA_PB1X00=y - -# -# PCI Hotplug Support -# +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -133,6 +130,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -145,6 +144,7 @@ CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -163,6 +163,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -177,16 +178,23 @@ # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_PB1000 is not set # CONFIG_MTD_PB1500 is not set -# CONFIG_MTD_PB1100 is not set +CONFIG_MTD_PB1100=y +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +CONFIG_MTD_PB1500_BOOT=y +CONFIG_MTD_PB1500_USER=y +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -252,7 +260,7 @@ # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set -# CONFIG_FILTER is not set +CONFIG_FILTER=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -338,16 +346,7 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -360,15 +359,15 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_IDEPCI is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -404,7 +403,8 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AU1000_ENET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set @@ -429,6 +429,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -463,22 +464,6 @@ # CONFIG_WAN is not set # -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=m -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_FMVJ18X is not set -# CONFIG_PCMCIA_PCNET is not set -# 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_ARCNET_COM20020_CS is not set -# CONFIG_PCMCIA_IBMTR is not set -# CONFIG_NET_PCMCIA_RADIO is not set - -# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -524,6 +509,7 @@ # CONFIG_USB_IRDA is not set # CONFIG_NSC_FIR is not set # CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set # CONFIG_TOSHIBA_FIR is not set CONFIG_AU1000_FIR=y # CONFIG_SMC_IRCC_FIR is not set @@ -538,11 +524,13 @@ # # Input core support # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=y # # Character devices @@ -571,10 +559,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -CONFIG_AU1000_UART=y -CONFIG_AU1000_SERIAL_CONSOLE=y -# CONFIG_AU1000_USB_TTY is not set -# CONFIG_AU1000_USB_RAW is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set # CONFIG_TXX927_SERIAL is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -594,20 +584,49 @@ # Joysticks # # CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set # -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks +# Joysticks # +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y # CONFIG_DTLK is not set @@ -620,19 +639,14 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_PCMCIA_SERIAL_CS is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_AU1000_GPIO is not set -# CONFIG_TS_AU1000_ADS7846 is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_REISERFS_FS=m @@ -642,6 +656,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -694,6 +709,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=m # CONFIG_NFSD_V3 is not set @@ -788,13 +804,14 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set -# CONFIG_FB_AU1100 is not set +CONFIG_FB_AU1100=y # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -838,7 +855,7 @@ # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -CONFIG_SOUND_AU1000=y +# CONFIG_SOUND_AU1X00 is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set @@ -850,7 +867,104 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -861,14 +975,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-pb1500 linux-2.4.22/arch/mips/defconfig-pb1500 --- linux-2.4.21/arch/mips/defconfig-pb1500 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-pb1500 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set CONFIG_MIPS_PB1500=y -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,22 +58,25 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_MIPS_AU1000=y -CONFIG_NEW_IRQ=y +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_AU1000_USB_DEVICE=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection @@ -86,11 +99,11 @@ # CONFIG_CPU_SB1 is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_ADVANCED=y +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_LLDSCD is not set -CONFIG_CPU_HAS_WB=y +# CONFIG_CPU_HAS_WB is not set CONFIG_CPU_HAS_SYNC=y # @@ -114,7 +127,11 @@ # CONFIG_TCIC is not set # CONFIG_I82092 is not set # CONFIG_I82365 is not set -# CONFIG_PCMCIA_AU1000 is not set +CONFIG_PCMCIA_AU1X00=m +CONFIG_PCMCIA_PB1X00=y +# CONFIG_PCMCIA_DB1X00 is not set +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -122,7 +139,6 @@ # CONFIG_HOTPLUG_PCI is not set # CONFIG_HOTPLUG_PCI_COMPAQ is not set # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -131,6 +147,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -143,6 +161,7 @@ CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -161,6 +180,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -176,17 +196,22 @@ # CONFIG_MTD_PB1000 is not set CONFIG_MTD_PB1500=y # CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set CONFIG_MTD_PB1500_BOOT=y # CONFIG_MTD_PB1500_USER is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -338,15 +363,6 @@ 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 -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set CONFIG_BLK_DEV_IDECS=m # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -360,8 +376,8 @@ # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_BLK_DEV_OFFBOARD=y @@ -370,30 +386,29 @@ # 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_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # 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_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_HPT34X_AUTODMA is not set CONFIG_BLK_DEV_HPT366=y # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_PIIX_TUNING is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -406,6 +421,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -441,7 +457,8 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AU1000_ENET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set @@ -455,14 +472,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -479,8 +499,8 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -497,6 +517,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -599,10 +620,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -CONFIG_AU1000_UART=y -CONFIG_AU1000_SERIAL_CONSOLE=y -# CONFIG_AU1000_USB_TTY is not set -# CONFIG_AU1000_USB_RAW is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set # CONFIG_TXX927_SERIAL is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -653,11 +676,18 @@ # CONFIG_INPUT_GAMECON is not set # CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y # CONFIG_DTLK is not set @@ -676,13 +706,14 @@ # # CONFIG_PCMCIA_SERIAL_CS is not set # CONFIG_SYNCLINK_CS is not set -# CONFIG_AU1000_GPIO is not set -# CONFIG_TS_AU1000_ADS7846 is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_REISERFS_FS=m @@ -692,6 +723,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -744,6 +776,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=m # CONFIG_NFSD_V3 is not set @@ -838,12 +871,15 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set -# CONFIG_FB_E1356 is not set +CONFIG_FB_E1356=y +CONFIG_PB1500_CRT=y +# CONFIG_PB1500_TFT is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -887,7 +923,7 @@ # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -CONFIG_SOUND_AU1000=y +CONFIG_SOUND_AU1X00=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set @@ -907,7 +943,6 @@ # # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_LONG_TIMEOUT is not set # # USB Host Controller Drivers @@ -945,10 +980,12 @@ # USB Human Interface Devices (HID) # CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT is not set +CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set # # USB Imaging devices @@ -974,6 +1011,7 @@ # CONFIG_USB_RTL8150 is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set # CONFIG_USB_CDCETHER is not set # CONFIG_USB_USBNET is not set @@ -1005,14 +1043,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-rm200 linux-2.4.22/arch/mips/defconfig-rm200 --- linux-2.4.21/arch/mips/defconfig-rm200 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/defconfig-rm200 2003-08-25 04:44:39.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,38 +21,59 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SIBYTE_SB1250 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set CONFIG_SNI_RM200_PCI=y +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y +CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_I8259=y CONFIG_ISA=y -CONFIG_NEW_IRQ=y CONFIG_NONCOHERENT_IO=y CONFIG_OLD_TIME_C=y CONFIG_PC_KEYB=y @@ -61,26 +83,28 @@ # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set CONFIG_CPU_R4X00=y # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup @@ -103,8 +127,11 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -137,6 +164,7 @@ # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -259,6 +287,15 @@ # CONFIG_CD_NO_IDESCSI is not set # +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# # Character devices # CONFIG_VT=y @@ -293,11 +330,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y # CONFIG_DTLK is not set @@ -312,14 +356,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -329,6 +369,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -346,6 +389,9 @@ # CONFIG_ISO9660_FS is not set # 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 @@ -373,9 +419,11 @@ # CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set # CONFIG_SUNRPC is not set # CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set @@ -389,7 +437,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 @@ -409,10 +456,16 @@ CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set # CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # CONFIG_VGA_CONSOLE=y @@ -439,18 +492,23 @@ # CONFIG_BLUEZ is not set # -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-sb1250-swarm linux-2.4.22/arch/mips/defconfig-sb1250-swarm --- linux-2.4.21/arch/mips/defconfig-sb1250-swarm 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-sb1250-swarm 2003-08-25 04:44:39.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,27 +58,44 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set CONFIG_SIBYTE_SB1xxx_SOC=y +CONFIG_SIBYTE_SWARM=y +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_UNKNOWN is not set +CONFIG_SIBYTE_BOARD=y CONFIG_SIBYTE_SB1250=y -# CONFIG_SIMULATION is not set +CONFIG_CPU_SB1_PASS_1=y +# CONFIG_CPU_SB1_PASS_2 is not set +# CONFIG_CPU_SB1_PASS_2_2 is not set +# CONFIG_CPU_SB1_PASS_4 is not set CONFIG_SIBYTE_CFE=y # CONFIG_SIBYTE_CFE_CONSOLE is not set +# CONFIG_SIBYTE_BUS_WATCHER is not set # CONFIG_SIBYTE_SB1250_PROF is not set -# CONFIG_BCM1250_TBPROF is not set -CONFIG_SMP=y +# CONFIG_SIBYTE_TBPROF is not set # CONFIG_PCI is not set -CONFIG_SIBYTE_SWARM=y +CONFIG_SIBYTE_GENBUS_IDE=y +CONFIG_SMP_CAPABLE=y # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_DUMMY_KEYB=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_BOOT_ELF32=y # CONFIG_MIPS_AU1000 is not set @@ -91,14 +118,10 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set CONFIG_CPU_SB1=y -CONFIG_CPU_SB1_PASS_1=y -# CONFIG_CPU_SB1_PASS_2 is not set -# CONFIG_CPU_SB1_PASS_2_2 is not set +CONFIG_SMP=y +# CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_SB1_PASS_1_WORKAROUNDS=y CONFIG_CPU_HAS_PREFETCH=y -CONFIG_SB1_CACHE_ERROR=y -CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y -# CONFIG_SB1_CERR_SPIN is not set CONFIG_VTAG_ICACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set @@ -112,7 +135,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set @@ -131,9 +153,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -183,8 +206,9 @@ # # Networking options # -# CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y @@ -243,9 +267,43 @@ # # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDE_SIBYTE=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -294,6 +352,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -370,12 +429,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set # CONFIG_TXX927_SERIAL is not set CONFIG_SIBYTE_SB1250_DUART=y CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y CONFIG_SERIAL_CONSOLE=y -CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE=1024 -# CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -403,13 +462,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -425,6 +492,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -434,6 +502,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -483,6 +552,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -534,11 +604,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-sead linux-2.4.22/arch/mips/defconfig-sead --- linux-2.4.21/arch/mips/defconfig-sead 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-sead 2003-08-25 04:44:39.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ CONFIG_MIPS_SEAD=y # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,16 +56,19 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_PCI is not set @@ -111,9 +124,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -152,7 +166,7 @@ # # MIPS initrd options # -CONFIG_EMBEDDED_RAMDISK=y +# CONFIG_EMBEDDED_RAMDISK is not set # # Multi-device support (RAID and LVM) @@ -233,13 +247,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -255,6 +277,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -264,6 +287,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -350,14 +374,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-tb0226 linux-2.4.22/arch/mips/defconfig-tb0226 --- linux-2.4.21/arch/mips/defconfig-tb0226 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-tb0226 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,806 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +CONFIG_TANBAC_TB0226=y +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_ISA is not set +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_DUMMY_KEYB=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO 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_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# Input core support is needed for USB HID input layer or HIDBP support +# +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-tb0229 linux-2.4.22/arch/mips/defconfig-tb0229 --- linux-2.4.21/arch/mips/defconfig-tb0229 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-tb0229 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,646 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +CONFIG_TANBAC_TB0229=y +CONFIG_TANBAC_TB0219=y +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_ISA is not set +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_DUMMY_KEYB=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_ELMC is not set +# CONFIG_ELMC_II is not set +CONFIG_VORTEX=y +# CONFIG_TYPHOON is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +CONFIG_8139CP=y +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO 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_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-ti1500 linux-2.4.22/arch/mips/defconfig-ti1500 --- linux-2.4.21/arch/mips/defconfig-ti1500 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-ti1500 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,988 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +CONFIG_MIPS_XXS1500=y +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +# CONFIG_PCMCIA_DB1X00 is not set +CONFIG_PCMCIA_XXS1500=y +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +CONFIG_MTD_XXS1500=y +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# 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_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +CONFIG_BCM5222_DUAL_PHY=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# 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_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=m +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/defconfig-workpad linux-2.4.22/arch/mips/defconfig-workpad --- linux-2.4.21/arch/mips/defconfig-workpad 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-workpad 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,629 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +CONFIG_IBM_WORKPAD=y +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +CONFIG_ISA=y +CONFIG_DUMMY_KEYB=y +# CONFIG_SCSI is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI is not set +CONFIG_EISA=y +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips/defconfig-xxs1500 linux-2.4.22/arch/mips/defconfig-xxs1500 --- linux-2.4.21/arch/mips/defconfig-xxs1500 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/defconfig-xxs1500 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,895 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +CONFIG_MIPS_XXS1500=y +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +# CONFIG_PCMCIA_DB1X00 is not set +CONFIG_PCMCIA_XXS1500=y +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +CONFIG_MTD_XXS1500=y +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# 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_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# 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 +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_OFFBOARD=y +# 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_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +CONFIG_BCM5222_DUAL_PHY=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO 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_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# 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_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=m +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/Makefile linux-2.4.22/arch/mips/galileo-boards/ev64120/Makefile --- linux-2.4.21/arch/mips/galileo-boards/ev64120/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,26 +0,0 @@ -# -# Copyright 2000 RidgeRun, Inc. -# Author: RidgeRun, Inc. -# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com -# -# Makefile for the Galileo EV64120 board. -# -# 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). -# - -USE_STANDARD_AS_RULE := true - -all: ev64120.o int-handler.o - -O_TARGET := ev64120.o - -export-objs = i2o.o - -obj-y := serialGT.o int-handler.o promcon.o reset.o setup.o irq.o \ - irq-handler.o i2o.o pci_bios.o - -int-handler.o: int-handler.S - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/cntmr.c linux-2.4.22/arch/mips/galileo-boards/ev64120/cntmr.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/cntmr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/cntmr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,207 +0,0 @@ -/* cntmr.c - GT counters/timers functions */ - -/* Copyright - Galileo technology. 9/3/2000 */ - -/* -DESCRIPTION -This file contains function which serves the user with a complete interface -to the GT internal counters and timers, please advise: each counter/timer unit -can function only as a counter or a timer at current time. -Counter/timer 0 is 32 bit wide. -Counters/timers 1-3 are 24 bit wide. -*/ - -/* includes */ - -#ifdef __linux__ -#include -#include -#else -#include "cntmr.h" -#include "core.h" -#endif - -/******************************************************************** -* cntTmrStart - Starts a counter/timer with given an initiate value. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* unsigned int countValue - Initial value for count down. -* CNT_TMR_OP_MODES opMode - Set Mode, Counter or Timer. -* -* RETURNS: false if one of the parameters is erroneous, true otherwise. -*********************************************************************/ - -bool cntTmrStart(CNTMR_NUM countNum, unsigned int countValue, - CNT_TMR_OP_MODES opMode) -{ - unsigned int command = 1; - unsigned int value; - - if (countNum > LAST_CNTMR) - return false; - else { - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - cntTmrDisable(countNum); - GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)), - countValue); - command = command << countNum * 2; - value = value | command; - command = command << 1; - switch (opMode) { - case TIMER: /* The Timer/Counter bit set to logic '1' */ - value = value | command; - break; - case COUNTER: /* The Timer/Counter bit set to logic '0' */ - value = value & ~command; - break; - default: - return false; - } - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return true; - } -} - -/******************************************************************** -* cntTmrDisable - Disables the timer/counter operation and return its -* value. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* RETURNS: The counter/timer value (unsigned int), if any of the arguments are -* erroneous return 0. -*********************************************************************/ - -unsigned int cntTmrDisable(CNTMR_NUM countNum) -{ - unsigned int command = 1; - unsigned int regValue; - unsigned int value; - - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return 0; - GT_REG_READ(TIMER_COUNTER0 + 4 * countNum, ®Value); - command = command << countNum * 2; /* Disable the timer/counter */ - value = value & ~command; - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return regValue; -} - -/******************************************************************** -* cntTmrRead - Reads a timer or a counter value. (This operation can be -* perform while the counter/timer is active). -* -* RETURNS: The counter/timer value. If wrong input value, return 0. -*********************************************************************/ - -unsigned int cntTmrRead(CNTMR_NUM countNum) -{ - unsigned int value; - if (countNum > LAST_CNTMR) - return 0; - else - GT_REG_READ(TIMER_COUNTER0 + countNum * 4, &value); - return value; -} - -/******************************************************************** -* cntTmrEnable - Set enable-bit of timer/counter. -* Be aware: If the counter/timer is active, this function -* will terminate with an false. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* RETURNS: false if one of the parameters is erroneous, true otherwise. -*********************************************************************/ - -bool cntTmrEnable(CNTMR_NUM countNum) -{ - unsigned int command = 1; - unsigned int value; - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return false; - else { - command = command << countNum * 2; - if ((command & value) != 0) /* ==> The counter/timer is enabled */ - return false; /* doesn't make sense to Enable an "enabled" counter */ - value = value | command; - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return true; - } -} - -/******************************************************************** -* cntTmrLoad - loading value for timer number countNum. -* Be aware: If this function try to load value to an enabled -* counter/timer it terminate with false. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* unsigned int countValue - The value for load the register. -* RETURNS: false if one of the parameters is erroneous, true otherwise. -*********************************************************************/ - -bool cntTmrLoad(unsigned int countNum, unsigned int countValue) -{ - unsigned int command = 1; - unsigned int value; - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return false; - else { - command = command << countNum * 2; - value = value & command; - if (value != 0) { /* ==> The counter/timer is enabled */ - return false; /* can't reload value when counter/timer is enabled */ - } else { - GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)), - countValue); - return true; - } - - } -} - -/******************************************************************** -* cntTmrSetMode - Configurate the Mode of the channel to work as a counter -* or as a timer. (for more details on the different between -* those two modes is written in the Data Sheet). -* NOTE: This function only set the counter/timer mode and -* don't enable it. -* Be aware: If this function try to load value to an enabled -* counter/timer it terminate with false. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* CNT_TMR_OP_MODES opMode - TIMER or COUNTER mode. -* RETURNS: false if one of the parameters is erroneous true otherwise . -*********************************************************************/ - -bool cntTmrSetMode(CNTMR_NUM countNum, CNT_TMR_OP_MODES opMode) -{ - unsigned int command = 1; - unsigned int value; - - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return false; - else { - command = command << countNum * 2; - value = value & command; - if (value != 0) { /* ==> The counter/timer is enabled */ - return false; /* can't set the Mode when counter/timer is enabled */ - } else { - command = command << 1; - switch (opMode) { - case TIMER: - value = value | command; /* The Timer/Counter bit set to logic '1' */ - break; - case COUNTER: - value = value & ~command; /*The Timer/Counter bit set to logic '0' */ - break; - default: - return false; - } - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return true; - } - } -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/dma.c linux-2.4.22/arch/mips/galileo-boards/ev64120/dma.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/dma.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/dma.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,168 +0,0 @@ -/* DMA.C - DMA functions and definitions */ - -/* Copyright Galileo Technology. */ - -/* -DESCRIPTION -This file gives the user a complete interface to the powerful DMA engines, -including functions for controling the priority mechanism. -To fully understand the capabilities of the DMA engines please spare some -time to go trough the spec. -*/ - -/* includes */ - -#ifdef __linux__ -#include -#include -#else -#include "Core.h" -#include "DMA.h" -#endif -/******************************************************************** -* dmaCommand - Write a command to a DMA channel -* -* Inputs: DMA_ENGINE channel - choosing one of the four engine. -* unsigned int command - The command to be written to the control register. -* Returns: false if one of the parameters is erroneous else returns true. -*********************************************************************/ - -bool dmaCommand(DMA_ENGINE channel, unsigned int command) -{ - if (channel > LAST_DMA_ENGINE) - return false; - GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command); - return true; -} - -/******************************************************************** -* dmaTransfer - transfer data from sourceAddr to destAddr on DMA channel -* Inputs: -* DMA_RECORED *nextRecoredPointer: If we are using chain mode DMA transfer, -* then this pointer should point to the next recored,otherwise it should be -* NULL. -* VERY IMPORTANT !!! When using chain mode, the records must be 16 Bytes -* aligned, the function will take care of that for you, but you need to -* allocate one more record for that, meaning: if you are having 3 records , -* declare 4 (see the example bellow) and start using the second one. -* Example: -* Performing a chain mode DMA transfer(Copy a 1/4 mega of data using -* chain mode DMA): -* DMA_RECORED dmaRecoredArray[4]; -* dmaRecoredArray[1].ByteCnt = _64KB; -* dmaRecoredArray[1].DestAdd = destAddress + _64KB; -* dmaRecoredArray[1].SrcAdd = sourceAddress + _64KB; -* dmaRecoredArray[1].NextRecPtr = &dmaRecoredArray[2]; -* dmaRecoredArray[2].ByteCnt = _64KB; -* dmaRecoredArray[2].DestAdd = destAddress + 2*_64KB; -* dmaRecoredArray[2].SrcAdd = sourceAddress + 2*_64KB; -* dmaRecoredArray[2].NextRecPtr = &dmaRecoredArray[3]; -* dmaRecoredArray[3].ByteCnt = _64KB; -* dmaRecoredArray[3].DestAdd = destAddress + 3*_64KB; -* dmaRecoredArray[3].SrcAdd = sourceAddress + 3*_64KB; -* dmaRecoredArray[3].NextRecPtr = NULL; -* performCmDma(0,sourceAddress,destAddress,_64KB,PLAIN,WAIT_TO_END, -* &dmaRecoredArray[1]); -* Returns: NO_SUCH_CHANNEL if channel does not exist, CHANNEL_BUSY if channel -* is active and true if the transfer ended successfully -*********************************************************************/ - -DMA_STATUS dmaTransfer(DMA_ENGINE channel, unsigned int sourceAddr, - unsigned int destAddr, unsigned int numOfBytes, - unsigned int command, - DMA_RECORED * nextRecoredPointer) -{ - unsigned int tempData, checkBits, alignmentOffset = 0; - DMA_RECORED *next = nextRecoredPointer; - - if (channel > LAST_DMA_ENGINE) - return NO_SUCH_CHANNEL; - if (numOfBytes > 0xffff) - return GENERAL_ERROR; - if (isDmaChannelActive(channel)) - return CHANNEL_BUSY; - if (next != NULL) { /* case of chain Mode */ - alignmentOffset = ((unsigned int) next % 16); - } - checkBits = command & 0x6000000; - if (checkBits == 0) { - while (next != NULL) { - WRITE_WORD((unsigned int) next - alignmentOffset, - next->ByteCnt); - tempData = (unsigned int) next->SrcAdd; - WRITE_WORD((unsigned int) next + 4 - - alignmentOffset, tempData & 0x5fffffff); - tempData = (unsigned int) next->DestAdd; - WRITE_WORD((unsigned int) next + 8 - - alignmentOffset, tempData & 0x5fffffff); - tempData = (unsigned int) next->NextRecPtr; - WRITE_WORD((unsigned int) next + 12 - - alignmentOffset, - tempData & 0x5fffffff - - alignmentOffset); - next = (DMA_RECORED *) tempData; - if (next == nextRecoredPointer) - next = NULL; - } - } - GT_REG_WRITE(CHANNEL0_DMA_BYTE_COUNT + channel * 4, numOfBytes); - tempData = sourceAddr; - GT_REG_WRITE(CHANNEL0_DMA_SOURCE_ADDRESS + channel * 4, - tempData & 0x5fffffff); - tempData = destAddr; - GT_REG_WRITE(CHANNEL0_DMA_DESTINATION_ADDRESS + channel * 4, - tempData & 0x5fffffff); - if (nextRecoredPointer != NULL) { - tempData = - (unsigned int) nextRecoredPointer - alignmentOffset; - GT_REG_WRITE(CHANNEL0NEXT_RECORD_POINTER + 4 * channel, - tempData & 0x5fffffff); - command = command | CHANNEL_ENABLE; - } else { - command = command | CHANNEL_ENABLE | NON_CHAIN_MOD; - } - /* Activate DMA engine By writting to dmaControlRegister */ - GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command); - - return DMA_OK; -} - -/******************************************************************** -* isDmaChannelActive - check if channel is busy -* -* Inputs: channel number -* RETURNS: True if the channel is busy, false otherwise. -*********************************************************************/ - -bool isDmaChannelActive(DMA_ENGINE channel) -{ - unsigned int data; - - if (channel > LAST_DMA_ENGINE) - return false; - GT_REG_READ(CHANNEL0CONTROL + 4 * channel, &data); - if (data & DMA_ACTIVITY_STATUS) - return true; - else - return false; -} - - -/******************************************************************** -* changeDmaPriority - update the arbiter`s priority for channels 0-3 -* -* Inputs: priority for channels 0-1, priority for channels 2-3, - priority for groups and other priority options -* RETURNS: false if one of the parameters is erroneous and true else -*********************************************************************/ - -bool changeDmaPriority(PRIO_CHAN_0_1 prio_01, PRIO_CHAN_2_3 prio_23, - PRIO_GROUP prioGrp, PRIO_OPT prioOpt) -{ - unsigned int prioReg = 0; - - prioReg = (prio_01 & 0x3) + ((prio_23 & 0x3) << 2) + - ((prioGrp & 0x3) << 4) + (prioOpt << 6); - GT_REG_WRITE(ARBITER_CONTROL, prioReg); - return true; -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/i2o.c linux-2.4.22/arch/mips/galileo-boards/ev64120/i2o.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/i2o.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/i2o.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,689 +0,0 @@ -/* i2o.c - Drivers for the I2O */ - -/* Copyright - Galileo technology. */ - -/*includes*/ - -#include - -#ifdef __linux__ -#include -#include -#else -#include "Core.h" -#include "i2o.h" -#endif - -/******************************************************************** -* getInBoundMessage - When the GT is configured for I2O support -* it can receive a message from an agent on the pci bus. -* This message is a 32 bit wide and can be read by -* the CPU. -* The messaging unit contains two sets of registers -* so, actually it can receive a 64 bit message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: Data received from the remote agent. -*********************************************************************/ -unsigned int getInBoundMessage(I2O_MESSAGE_REG messageRegNum) -{ - unsigned int regValue; - - GT_REG_READ(INBOUND_MESSAGE_REGISTER0_CPU_SIDE + 4 * messageRegNum, - ®Value); - return (regValue); -} - - -/******************************************************************** -* checkInboundIntAndClear - When a message is received an interrupt is -* generated, to enable polling instead the use of -* an interrupt handler the user can use this fuction. -* You will need to mask the incomming interrupt for -* proper use. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool checkInBoundIntAndClear(I2O_MESSAGE_REG messageRegNum) -{ - unsigned int regValue; - - GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Value); - /* clears bit 0 for message register 0 or bit 1 for message register 1 */ - GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, - BIT1 * messageRegNum); - switch (messageRegNum) { - case MESSAGE_REG_0: - if (regValue & BIT0) - return true; - break; - case MESSAGE_REG_1: - if (regValue & BIT1) - return true; - break; - } - return false; -} - -/******************************************************************** -* sendOutBoundMessage - When the GT is configured for I2O support -* it can send a message to an agent on the pci bus. -* This message is a 32 bit wide and can be read by -* the PCI agent. -* The messaging unit contains two sets of registers -* so, actually it can send a 64 bit message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* unsigned int message - Message to be sent. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool sendOutBoundMessage(I2O_MESSAGE_REG messageRegNum, - unsigned int message) -{ - GT_REG_WRITE(OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE + - 4 * messageRegNum, message); - return true; -} - -/******************************************************************** -* checkOutboundInt - When the CPU sends a message to the Outbound -* register it generates an interrupt which is refelcted on -* the Outbound Interrupt cause register, the interrupt can -* be cleard only by the PCI agent which read the message. -* After sending the message you can acknowledge it by -* monitoring the corresponding bit in the cause register. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool outBoundMessageAcknowledge(I2O_MESSAGE_REG messageRegNum) -{ - unsigned int regValue; - - GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Value); - switch (messageRegNum) { - case MESSAGE_REG_0: - if (regValue & BIT0) - return true; - break; - case MESSAGE_REG_1: - if (regValue & BIT1) - return true; - break; - } - return false; -} - -/******************************************************************** -* maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking -* the interrupt you can work in polling mode -* using the checkInboundIntAndClear function. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* enableInBoundMessageInterrupt - unMask the inbound interrupt. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* maskOutboundMessageInterrupt - Mask the out bound interrupt, when doing so -* the PCI agent needs to poll on the interrupt -* cause register to monitor an incoming message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* enableOutboundMessageInterrupt - Mask the out bound interrupt, when doing so -* the PCI agent needs to poll on the interrupt -* cause register to monitor an incoming message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the -* CPU generates a PCI interrupt (if it is not masked by -* the Outbound interrupt Mask register) -* Only the PCI agent which recieved the interrupt can -* clear it, only after clearing all the bits the -* interrupt will be de-asserted. -* -* INPUTS: unsigned int data - Requested interrupt bits. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool initiateOutBoundDoorBellInt(unsigned int data) -{ - GT_REG_WRITE(OUTBOUND_DOORBELL_REGISTER_CPU_SIDE, data); - return true; -} - -/******************************************************************** -* readInBoundDoorBellInt - Read the in bound door bell interrupt cause -* register. -* -* OUTPUT: N/A. -* RETURNS: The 32 bit interrupt cause register. -*********************************************************************/ -unsigned int readInBoundDoorBellInt() -{ - unsigned int regData; - GT_REG_READ(INBOUND_DOORBELL_REGISTER_CPU_SIDE, ®Data); - return regData; -} - -/******************************************************************** -* clearInBoundDoorBellInt - An interrupt generated by a PCI agent through -* the in bound door bell mechanisem can be cleared -* only by the CPU. The interrupt will be de-asserted -* only if all the bits which where set by the PCI -* agent are cleared. -* -* INPUTS: unsigned int data - Bits to be cleared. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool clearInBoundDoorBellInt(unsigned int data) -{ - GT_REG_WRITE(INBOUND_DOORBELL_REGISTER_CPU_SIDE, data); - return true; -} - -/******************************************************************** -* isInBoundDoorBellInterruptSet - Check if Inbound Doorbell Interrupt is set, -* can be used for polling mode. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool isInBoundDoorBellInterruptSet() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); - return (regData & BIT2); -} - -/******************************************************************** -* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is -* set, can be used for acknowledging interrupt -* handling by the agent who recieived the -* interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool isOutBoundDoorBellInterruptSet() -{ - unsigned int regData; - - GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); - return (regData & BIT2); -} - -/******************************************************************** -* maskInboundDoorBellInterrupt - Mask the Inbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskInBoundDoorBellInterrupt() -{ - SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* enableInboundDoorBellInterrupt - unMask the Inbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableInBoundDoorBellInterrupt() -{ - RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* maskOutboundDoorBellInterrupt - Mask the Outbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskOutBoundDoorBellInterrupt() -{ - SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* enableOutboundDoorBellInterrupt - unMask the Outbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableOutBoundDoorBellInterrupt() -{ - RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* circularQueueEnable - Initialize the I2O messaging mechanism. -* -* INPUTS: CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the: -* Queue Control Register, Offset 0x50 (0x1c50). -* Defines the queues size (refer to the data sheet -* for more information) -* unsigned int queueBaseAddr - The base address for the first queue. -* The other queues base Address will be determined as follows: -* Inbound Free = queueBaseAddr -* Inbound Post = queueBaseAddr + cirQueSize -* Outbound Post = queueBaseAddr + cirQueSize -* -* OUTPUT: N/A. -* RETURNS: true. -* -* The Circular Queue Starting Addresses as written in the spec: -* ---------------------------------------- -* | Queue | Starting Address | -* |----------------|---------------------| -* | Inbound Free | QBAR | -* | Inbound Post | QBAR + Queue Size | -* | Outbound Post | QBAR + 2*Queue Size | -* | Outbound Free | QBAR + 3*Queue Size | -* ---------------------------------------- -*********************************************************************/ -bool circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize, - unsigned int queueBaseAddr) -{ - unsigned int regData; - - regData = BIT0 | (cirQueSize << 1); - /* Enable Queue Operation */ - GT_REG_WRITE(QUEUE_CONTROL_REGISTER_CPU_SIDE, regData); - /* Writing The base Address for the 4 Queues */ - GT_REG_WRITE(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, queueBaseAddr); - /* Update The Inbound Free Queue Base Address, offset=0 */ - GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 0); - GT_REG_WRITE(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 0); - /* Update The Inbound Post Queue Base Address, offset=_16K*cirQueSize */ - GT_REG_WRITE(INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - _16K * cirQueSize); - GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - _16K * cirQueSize); - /* Update The Outbound Post Queue Base Address, offset=2*_16K*cirQueSize */ - GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - 2 * _16K * cirQueSize); - GT_REG_WRITE(OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - 2 * _16K * cirQueSize); - /* Update The Outbound Free Queue Base Address, offset=3*_16K*cirQueSize */ - GT_REG_WRITE(OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - 3 * _16K * cirQueSize); - GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - 3 * _16K * cirQueSize); - return true; -} - -/******************************************************************** -* inBoundPostQueuePop - Two actions are being taken upon pop: -* 1) Getting out the data from the Queue`s head. -* 2) Increment the tail pointer in a cyclic way (The HEAD is -* incremented automaticaly by the GT) -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: Data pointed by tail. -*********************************************************************/ -unsigned int inBoundPostQueuePop() -{ - unsigned int tailAddrPointer; - unsigned int data; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int inBoundPostQbase; - - /* Gets the Inbound Post TAIL pointer */ - GT_REG_READ(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - &tailAddrPointer); - /* Gets the Data From the pointer Address */ - READ_WORD(tailAddrPointer, &data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Inbound Post Queue Base Address */ - inBoundPostQbase = qBar + 1 * cirQueSize * _16K; - /* incrementing Inbound Post queue TAIL in a cyclic loop */ - tailAddrPointer = inBoundPostQbase + ((tailAddrPointer + 4) % - (_16K * cirQueSize)); - /* updating the pointer back to INBOUND_POST_TAIL_POINTER_REGISTER */ - GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - tailAddrPointer); - return data; -} - -/******************************************************************** -* isInBoundPostQueueInterruptSet - Check if in bound interrupt is set. -* can be used for polling mode. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool isInBoundPostQueueInterruptSet() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); - return (regData & BIT4); /* if set return '1' (true), else '0' (false) */ -} - -/******************************************************************** -* clearInBoundPostQueueInterrupt - Clears the Post queue interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool clearInBoundPostQueueInterrupt() -{ - GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, BIT4); - return true; -} - -/******************************************************************** -* maskInBoundPostQueueInterrupt - Mask the inbound interrupt, when masking -* the interrupt you can work in polling mode. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: -*********************************************************************/ -void maskInBoundPostQueueInterrupt() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); - GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - regData | BIT4); - -} - -/******************************************************************** -* enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new -* message from the PCI agent. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: -*********************************************************************/ -void enableInBoundPostQueueInterrupt() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); - GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - regData & 0xfffffffb); -} - -/******************************************************************** -* inBoundFreeQueuePush - Two actions are being taken upon push: -* 1) Place the user`s data on the Queue`s head. -* 2) Increment the haed pointer in a cyclic way (The tail is -* decremented automaticaly by the GT) -* -* INPUTS: unsigned int data - Data to be placed in the queue. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool inBoundFreeQueuePush(unsigned int data) -{ - unsigned int headPointer; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int inBoundFreeQbase; - - GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - &headPointer); - /* placing the data in the queue */ - WRITE_WORD(headPointer, data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Inbound Free Queue Base Address */ - inBoundFreeQbase = qBar; - /* incrementing Inbound Free queue HEAD in a cyclic loop */ - headPointer = - inBoundFreeQbase + ((headPointer + 4) % (_16K * cirQueSize)); - /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ - GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - headPointer); - return true; -} - -/******************************************************************** -* isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty. -* Can be used for acknowledging the messages -* being sent by us to the PCI agent. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the queue is empty , otherwise false. -*********************************************************************/ -bool isInBoundFreeQueueEmpty() -{ - unsigned int inBoundFreeQueHead; - unsigned int inBoundFreeQueTail; - - GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - &inBoundFreeQueHead); - GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - &inBoundFreeQueTail); - if (inBoundFreeQueHead == inBoundFreeQueTail) { - return true; - } else - return false; -} - -/******************************************************************** -* outBoundPostQueuePush - Two actions are being taken upon push: -* 1) Place the user`s data on the Queue`s head. -* 2) Increment the haed pointer in a cyclic way (The tail is -* decremented automaticaly by the GT when the Agent on the -* PCI have read data from the Outbound Port). -* -* INPUTS: unsigned int data - Data to be placed in the queue`s head. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool outBoundPostQueuePush(unsigned int data) -{ - unsigned int headPointer; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int outBoundPostQbase; - - GT_REG_READ(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - &headPointer); - /* placing the data in the queue (where the head point to..) */ - WRITE_WORD(headPointer, data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Outbound Post Queue Base Address */ - outBoundPostQbase = qBar + 2 * cirQueSize * _16K; - /* incrementing Outbound Post queue in a cyclic loop */ - headPointer = - outBoundPostQbase + ((headPointer + 4) % (_16K * cirQueSize)); - /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ - GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - headPointer); - return true; -} - -/******************************************************************** -* isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty. -* Can be used for acknowledging the messages -* being sent by us to the PCI agent. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the queue is empty , otherwise false. -*********************************************************************/ -bool isOutBoundPostQueueEmpty() -{ - unsigned int outBoundPostQueHead; - unsigned int outBoundPostQueTail; - - GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - &outBoundPostQueHead); - GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - &outBoundPostQueTail); - if (outBoundPostQueHead == outBoundPostQueTail) { - return true; - } else - return false; -} - -/******************************************************************** -* outBoundFreeQueuePop - Two actions are being taken upon pop: -* 1) Getting out the data from the Queue`s head. -* 2) Increment the tail pointer in a cyclic way (The HEAD is -* incremented automaticaly by the GT) -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: Data pointed by tail. -*********************************************************************/ -unsigned int outBoundFreeQueuePop() -{ - unsigned int tailAddrPointer; - unsigned int data; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int outBoundFreeQbase; - - /* Gets the Inbound Post TAIL pointer */ - GT_REG_READ(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - &tailAddrPointer); - /* Gets the Data From the pointer Address */ - READ_WORD(tailAddrPointer, &data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Inbound Post Queue Base Address */ - outBoundFreeQbase = qBar + 3 * cirQueSize * _16K; - /* incrementing Outbound Free queue TAlL in a cyclic loop */ - tailAddrPointer = outBoundFreeQbase + ((tailAddrPointer + 4) % - (_16K * cirQueSize)); - /* updating the pointer back to OUTBOUND_FREE_TAIL_POINTER_REGISTER */ - GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - tailAddrPointer); - return data; -} - - -EXPORT_SYMBOL(isInBoundDoorBellInterruptSet); -EXPORT_SYMBOL(initiateOutBoundDoorBellInt); -EXPORT_SYMBOL(clearInBoundDoorBellInt); diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/int-handler.S linux-2.4.22/arch/mips/galileo-boards/ev64120/int-handler.S --- linux-2.4.21/arch/mips/galileo-boards/ev64120/int-handler.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/int-handler.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,113 +0,0 @@ -/* - * int-handler.S - * - * Based on the cobalt handler. - */ -#include -#include -#include -#include -#include - -/* - * galileo_handle_int - - * We check for the timer first, then check PCI ints A and D. - * Then check for serial IRQ and fall through. - */ - .align 5 - .set reorder - .set noat - NESTED(galileo_handle_int, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 t0,CP0_CAUSE - mfc0 t2,CP0_STATUS - - and t0,t2 - - andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ - bnez t1,ll_galileo_irq - andi t1,t0,STATUSF_IP2 /* int0 hardware line */ - bnez t1,ll_pci_intA - andi t1,t0,STATUSF_IP5 /* int3 hardware line */ - bnez t1,ll_pci_intD - andi t1,t0,STATUSF_IP6 /* int4 hardware line */ - bnez t1,ll_serial_irq - andi t1,t0,STATUSF_IP7 /* compare int */ - bnez t1,ll_compare_irq - nop - - /* wrong alarm or masked ... */ - j spurious_interrupt - nop - END(galileo_handle_int) - - - .align 5 - .set reorder -ll_galileo_irq: - li a0,4 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_compare_irq: - li a0,7 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_pci_intA: - move a0,sp - jal pci_intA - nop - j ret_from_irq - nop - -#if 0 - .align 5 - .set reorder -ll_pci_intB: - move a0,sp - jal pci_intB - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_pci_intC: - move a0,sp - jal pci_intC - nop - j ret_from_irq - nop -#endif - - .align 5 - .set reorder -ll_pci_intD: - move a0,sp - jal pci_intD - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_serial_irq: - li a0,6 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/irq-handler.c linux-2.4.22/arch/mips/galileo-boards/ev64120/irq-handler.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/irq-handler.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/irq-handler.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,270 +0,0 @@ -/* - * Galileo Technology chip interrupt handler - * - * Modified by RidgeRun, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * These are interrupt handlers for the GT on-chip interrupts. They all come - * in to the MIPS on a single interrupt line, and have to be handled and ack'ed - * differently than other MIPS interrupts. - */ - -#if CURRENTLY_UNUSED - -struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); - -/* - * hook_irq_handler - * - * Hooks IRQ handler to the system. When the system is interrupted - * the interrupt service routine is called. - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * isr_ptr - Pointer to the interrupt service routine - * - * Outputs : - */ -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) -{ - irq_handlers[int_cause][bit_num].routine = isr_ptr; -} - - -/* - * enable_galileo_irq - * - * Enables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int enable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - return 1; -} - -/* - * disable_galileo_irq - * - * Disables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int disable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - return 1; -} - -#endif /* UNUSED */ - -/* - * galileo_irq - - * - * Interrupt handler for interrupts coming from the Galileo chip. - * It could be timer interrupt, built in ethernet ports etc... - * - * Inputs : - * - * Outputs : - * - */ -static void galileo_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int irq_src, int_high_src, irq_src_mask, - int_high_src_mask; - int handled; - unsigned int count; - static int counter = 0; - - GT_READ(GT_INTRCAUSE_OFS, &irq_src); - GT_READ(GT_INTRMASK_OFS, &irq_src_mask); - GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); - GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); - irq_src = irq_src & irq_src_mask; - int_high_src = int_high_src & int_high_src_mask; - - handled = 0; - - /* Execute all interrupt handlers */ - /* Check for timer interrupt */ - if (irq_src & 0x00000800) { - handled = 1; - irq_src &= ~0x00000800; - // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); - do_timer(regs); - } - - if (irq_src) { - printk(KERN_INFO - "Other Galileo interrupt received irq_src %x\n", - irq_src); -#if CURRENTLY_UNUSED - for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { - if (irq_src & (1 << count)) { - if (irq_handlers[INT_CAUSE_MAIN][count]. - routine) { - queue_task(&irq_handlers - [INT_CAUSE_MAIN][count], - &tq_immediate); - mark_bh(IMMEDIATE_BH); - handled = 1; - } - } - } -#endif /* UNUSED */ - } - GT_WRITE(GT_INTRCAUSE_OFS, 0); - GT_WRITE(GT_HINTRCAUSE_OFS, 0); - -#undef GALILEO_I2O -#ifdef GALILEO_I2O - /* - Future I2O support. We currently attach I2O interrupt handlers to the - Galileo interrupt (int 4) and handle them in do_IRQ. - */ - if (isInBoundDoorBellInterruptSet()) { - printk(KERN_INFO "I2O doorbell interrupt received.\n"); - handled = 1; - } - - if (isInBoundPostQueueInterruptSet()) { - printk(KERN_INFO "I2O Queue interrupt received.\n"); - handled = 1; - } - - /* - This normally would be outside of the ifdef, but since - we're handling I2O outside of this handler, this - printk shows up every time we get a valid I2O - interrupt. So turn this off for now. - */ - if (handled == 0) { - if (counter < 50) { - printk("Spurious Galileo interrupt...\n"); - counter++; - } - } -#endif -} - -/* - * galileo_time_init - - * - * Initializes timer using galileo's built in timer. - * - * - * Inputs : - * irq - number of irq to be used by the timer - * - * Outpus : - * - */ -#ifdef CONFIG_SYSCLK_100 -#define Sys_clock (100 * 1000000) // 100 MHz -#endif -#ifdef CONFIG_SYSCLK_83 -#define Sys_clock (83.333 * 1000000) // 83.333 MHz -#endif -#ifdef CONFIG_SYSCLK_75 -#define Sys_clock (75 * 1000000) // 75 MHz -#endif - -/* - * This will ignore the standard MIPS timer interrupt handler that is passed - * in as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt - * handling. - */ -void galileo_time_init(struct irqaction *irq) -{ - extern irq_desc_t irq_desc[NR_IRQS]; - static struct irqaction timer; - - /* Disable timer first */ - GT_WRITE(GT_TC_CONTROL_OFS, 0); - /* Load timer value for 100 Hz */ - GT_WRITE(GT_TC3_OFS, Sys_clock / 100); - - /* - * Create the IRQ structure entry for the timer. Since we're too early - * in the boot process to use the "request_irq()" call, we'll hard-code - * the values to the correct interrupt line. - */ - timer.handler = &galileo_irq; - timer.flags = SA_SHIRQ; - timer.name = "timer"; - timer.dev_id = NULL; - timer.next = NULL; - timer.mask = 0; - irq_desc[TIMER].action = &timer; - - /* Enable timer ints */ - GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); - /* clear Cause register first */ - GT_WRITE(GT_INTRCAUSE_OFS, 0x0); - /* Unmask timer int */ - GT_WRITE(GT_INTRMASK_OFS, 0x800); - /* Clear High int register */ - GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); - /* Mask All interrupts at High cause interrupt */ - GT_WRITE(GT_HINTRMASK_OFS, 0x0); - -} - -void galileo_irq_init(void) -{ - int i, j; - -#if CURRENTLY_UNUSED - /* Reset irq handlers pointers to NULL */ - for (i = 0; i < MAX_CAUSE_REGS; i++) { - for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) { - irq_handlers[i][j].next = NULL; - irq_handlers[i][j].sync = 0; - irq_handlers[i][j].routine = NULL; - irq_handlers[i][j].data = NULL; - } - } -#endif -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/irq.c linux-2.4.22/arch/mips/galileo-boards/ev64120/irq.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,456 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Code to handle irqs on GT64120A boards - * Derived from mips/orion and Cort - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef IRQ_DEBUG - -#ifdef IRQ_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - - -asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - -#define MAX_AGENTS_PER_INT 21 /* Random number */ -unsigned char pci_int_irq[MAX_AGENTS_PER_INT]; -static int max_interrupts = 0; - -/* Duplicate interrupt handlers. */ -/******************************************************************** - *pci_int(A/B/C/D) - - * - *Calls all the handlers connected to PCI interrupt A/B/C/D - * - *Inputs : - * - *Outpus : - * - *********************************************************************/ -asmlinkage __inline__ void pci_intA(struct pt_regs *regs) -{ - unsigned int count = 0; - DBG(KERN_INFO "pci_intA, max_interrupts %d\n", max_interrupts); - for (count = 0; count < max_interrupts; count++) { - do_IRQ(pci_int_irq[count], regs); - } -} - -asmlinkage __inline__ void pci_intD(struct pt_regs *regs) -{ - unsigned int count = 0; - DBG(KERN_INFO "pci_intD, max_interrupts %d\n", max_interrupts); - for (count = 0; count < max_interrupts; count++) { - do_IRQ(pci_int_irq[count], regs); - } -} - - -/* Function for careful CP0 interrupt mask access */ -static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) -{ - unsigned long status = read_32bit_cp0_register(CP0_STATUS); - DBG(KERN_INFO "modify_cp0_intmask clr %x, set %x\n", clr_mask, - set_mask); - DBG(KERN_INFO "modify_cp0_intmask status %x\n", status); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8; - DBG(KERN_INFO "modify_cp0_intmask status %x\n", status); - write_32bit_cp0_register(CP0_STATUS, status); -} - -static inline void mask_irq(unsigned int irq_nr) -{ - modify_cp0_intmask(irq_nr, 0); -} - -static inline void unmask_irq(unsigned int irq_nr) -{ - modify_cp0_intmask(0, irq_nr); -} - -void disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - DBG(KERN_INFO "disable_irq, irq %d\n", irq_nr); - save_and_cli(flags); - if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 - mask_irq(9 << 2); - } else { - mask_irq(1 << irq_nr); - } - restore_flags(flags); -} - -void enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - DBG(KERN_INFO "enable_irq, irq %d\n", irq_nr); - save_and_cli(flags); - if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 - DBG(KERN_INFO __FUNCTION__ " pci interrupt %d\n", irq_nr); - unmask_irq(9 << 2); - } else { - DBG(KERN_INFO __FUNCTION__ " interrupt set mask %d\n", - 1 << irq_nr); - unmask_irq(1 << irq_nr); - } - restore_flags(flags); -} - -/* - * Generic no controller code - */ - -static void no_irq_enable_disable(unsigned int irq) -{ -} -static unsigned int no_irq_startup(unsigned int irq) -{ - return 0; -} - -#if 0 -static void no_irq_ack(unsigned int irq) -{ - printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq); -} -#endif - -struct hw_interrupt_type no_irq_type = { - typename:"none", - startup:no_irq_startup, - shutdown:no_irq_enable_disable, - enable:no_irq_enable_disable, - disable:no_irq_enable_disable, - ack:NULL, - end:no_irq_enable_disable, -}; - -// ack: no_irq_ack, re-enable later -- SKJ - - -/* - * Controller mappings for all interrupt sources: - */ -irq_desc_t irq_desc[NR_IRQS]; - -atomic_t irq_err_count; - -int get_irq_list(char *buf) -{ - int i, len = 0, j; - struct irqaction *action; - - len += sprintf(buf + len, " "); - for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf + len, "CPU%d ", j); - *(char *) (buf + len++) = '\n'; - - for (i = 0; i < NR_IRQS; i++) { - action = irq_desc[i].action; - if (!action || !action->handler) - continue; - len += sprintf(buf + len, "%3d: ", i); - len += sprintf(buf + len, "%10u ", kstat_irqs(i)); - if (irq_desc[i].handler) - len += - sprintf(buf + len, " %s ", - irq_desc[i].handler->typename); - else - len += sprintf(buf + len, " None "); - len += sprintf(buf + len, " %s", action->name); - for (action = action->next; action; action = action->next) { - len += sprintf(buf + len, ", %s", action->name); - } - len += sprintf(buf + len, "\n"); - } - len += sprintf(buf + len, "BAD: %10lu\n", atomic_read(&irq_err_count)); - return len; -} - -asmlinkage void do_IRQ(int irq, struct pt_regs *regs) -{ - struct irqaction *action; - int cpu; - -#ifdef IRQ_DEBUG - if (irq != TIMER) - DBG(KERN_INFO __FUNCTION__ " irq = %d\n", irq); - if (irq != TIMER) - DBG(KERN_INFO "cause register = %x\n", - read_32bit_cp0_register(CP0_CAUSE)); - if (irq != TIMER) - DBG(KERN_INFO "status register = %x\n", - read_32bit_cp0_register(CP0_STATUS)); -#endif - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; - - if (irq_desc[irq].handler->ack) { - irq_desc[irq].handler->ack(irq); - } - - disable_irq(irq); - - action = irq_desc[irq].action; - if (action && action->handler) { -#ifdef IRQ_DEBUG - if (irq != TIMER) - DBG(KERN_INFO - "rr: irq %d action %p and handler %p\n", irq, - action, action->handler); -#endif - if (!(action->flags & SA_INTERRUPT)) - __sti(); - do { - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - __cli(); - if (irq_desc[irq].handler) { - if (irq_desc[irq].handler->end) - irq_desc[irq].handler->end(irq); - else if (irq_desc[irq].handler->enable) - irq_desc[irq].handler->enable(irq); - } - } - - enable_irq(irq); - irq_exit(cpu, irq); - - if (softirq_pending(cpu)) - do_softirq(); - - /* unmasking and bottom half handling is done magically for us. */ -} - -int request_irq(unsigned int irq, - void (*handler) (int, void *, struct pt_regs *), - unsigned long irqflags, const char *devname, void *dev_id) -{ - struct irqaction *old, **p, *action; - unsigned long flags; - - DBG(KERN_INFO "rr:dev %s irq %d handler %x\n", devname, irq, - handler); - if (irq >= NR_IRQS) - return -EINVAL; - - action = (struct irqaction *) - kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->dev_id = dev_id; - action->next = NULL; - - save_flags(flags); - cli(); - - p = &irq_desc[irq].action; - - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & action->flags & SA_SHIRQ)) - return -EBUSY; - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - } - *p = action; - - restore_flags(flags); - if (irq >= 8) { - DBG(KERN_INFO "request_irq, max_interrupts %d\n", - max_interrupts); - pci_int_irq[max_interrupts++] = irq; // NOTE: Add error-handling if > max - } - enable_irq(irq); - return 0; -} - - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction *p, *old = NULL; - unsigned long flags; - int count, tmp, removed = 0; - - for (p = irq_desc[irq].action; p != NULL; old = p, p = p->next) { - /* Found the IRQ, is it the correct dev_id? */ - if (dev_id == p->dev_id) { - save_flags(flags); - cli(); - - // remove link from list - if (old) - old->next = p->next; - else - irq_desc[irq].action = p->next; - - restore_flags(flags); - kfree(p); - removed = 1; - break; - } - } - - /* - Remove PCI interrupts from the pci_int_irq list. Make sure - that some handler was removed before decrementing max_interrupts. - */ - if ((irq >= 8) && (removed)) { - for (count = 0; count < max_interrupts; count++) { - if (pci_int_irq[count] == irq) { - for (tmp = count; tmp < max_interrupts; - tmp++) { - pci_int_irq[tmp] = - pci_int_irq[tmp + 1]; - } - } - } - max_interrupts--; - DBG(KERN_INFO "free_irq, max_interrupts %d\n", - max_interrupts); - } -} - -unsigned long probe_irq_on(void) -{ - printk(KERN_INFO "probe_irq_on\n"); - return 0; -} - -int probe_irq_off(unsigned long irqs) -{ - printk(KERN_INFO "probe_irq_off\n"); - return 0; -} - -/******************************************************************** - *galileo_irq_setup - - * - *Initializes CPU interrupts - * - * - *Inputs : - * - *Outpus : - * - *********************************************************************/ -void galileo_irq_setup(void) -{ - extern asmlinkage void galileo_handle_int(void); - extern void galileo_irq_init(void); - - DBG(KERN_INFO "rr: galileo_irq_setup entry\n"); - - galileo_irq_init(); - - /* - * Clear all of the interrupts while we change the able around a bit. - */ - clear_cp0_status(ST0_IM); - - /* Sets the exception_handler array. */ - set_except_vector(0, galileo_handle_int); - - cli(); - - /* - * Enable timer. Other interrupts will be enabled as they are - * registered. - */ - set_cp0_status(IE_IRQ2); - - -#ifdef CONFIG_REMOTE_DEBUG - { - extern int DEBUG_CHANNEL; - serial_init(DEBUG_CHANNEL); - serial_set(DEBUG_CHANNEL, 115200); - set_debug_traps(); - breakpoint(); /* you may move this line to whereever you want :-) */ - } -#endif -} - -void init_irq_proc(void) -{ - /* Nothing, for now. */ -} - -void __init init_IRQ(void) -{ - int i; - - DBG(KERN_INFO "rr:init_IRQ\n"); - - /* Let's initialize our IRQ descriptors */ - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = 0; - irq_desc[i].handler = &no_irq_type; - irq_desc[i].action = NULL; - irq_desc[i].depth = 0; - irq_desc[i].lock = SPIN_LOCK_UNLOCKED; - } - - galileo_irq_setup(); -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/pci_bios.c linux-2.4.22/arch/mips/galileo-boards/ev64120/pci_bios.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/pci_bios.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/pci_bios.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1236 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Galileo Evaluation Boards PCI support. - * - * The general-purpose functions to read/write and configure the GT64120A's - * PCI registers (function names start with pci0 or pci1) are either direct - * copies of functions written by Galileo Technology, or are modifications - * of their functions to work with Linux 2.4 vs Linux 2.2. These functions - * are Copyright - Galileo Technology. - * - * Other functions are derived from other MIPS PCI implementations, or were - * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#undef PCI_DEBUG - -#ifdef PCI_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -#ifdef CONFIG_PCI - -#define SELF 0 - -/* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. - */ - -#define MAX_PCI_DEVS 10 - -struct pci_device { - u32 slot; - u32 BARtype[6]; - u32 BARsize[6]; -}; - -static void __init scan_and_initialize_pci(void); -static u32 __init scan_pci_bus(struct pci_device *pci_devices); -static void __init allocate_pci_space(struct pci_device *pci_devices); - -static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus); - -/* - * The functions that actually read and write to the controller. - * Copied from or modified from Galileo Technology code. - */ -static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device); -static void pci0WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device); -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); - -static void pci0MapIOspace(unsigned int pci0IoBase, - unsigned int pci0IoLength); -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength); -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length); -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length); -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length); -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length); -static unsigned int pci0GetIOspaceBase(void); -static unsigned int pci0GetIOspaceSize(void); -static unsigned int pci0GetMemory0Base(void); -static unsigned int pci0GetMemory0Size(void); -static unsigned int pci0GetMemory1Base(void); -static unsigned int pci0GetMemory1Size(void); -static unsigned int pci1GetIOspaceBase(void); -static unsigned int pci1GetIOspaceSize(void); -static unsigned int pci1GetMemory0Base(void); -static unsigned int pci1GetMemory0Size(void); -static unsigned int pci1GetMemory1Base(void); -static unsigned int pci1GetMemory1Size(void); - - -/* Functions to implement "pci ops" */ -static int galileo_pcibios_read_config_word(struct pci_dev *dev, - int offset, u16 * val); -static int galileo_pcibios_read_config_byte(struct pci_dev *dev, - int offset, u8 * val); -static int galileo_pcibios_read_config_dword(struct pci_dev *dev, - int offset, u32 * val); -static int galileo_pcibios_write_config_byte(struct pci_dev *dev, - int offset, u8 val); -static int galileo_pcibios_write_config_word(struct pci_dev *dev, - int offset, u16 val); -static int galileo_pcibios_write_config_dword(struct pci_dev *dev, - int offset, u32 val); -static void galileo_pcibios_set_master(struct pci_dev *dev); - -/* - * General-purpose PCI functions. - */ - -/* - * pci0MapIOspace - Maps PCI0 IO space for the master. - * Inputs: base and length of pci0Io - */ -static void pci0MapIOspace(unsigned int pci0IoBase, unsigned int pci0IoLength) -{ - unsigned int pci0IoTop = - (unsigned int) (pci0IoBase + pci0IoLength); - - if (pci0IoLength == 0) - pci0IoTop++; - - pci0IoBase = (unsigned int) (pci0IoBase >> 21); - pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase); - GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop); -} - -/* - * pci1MapIOspace - Maps PCI1 IO space for the master. - * Inputs: base and length of pci1Io - */ - -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength) -{ - unsigned int pci1IoTop = - (unsigned int) (pci1IoBase + pci1IoLength); - - if (pci1IoLength == 0) - pci1IoTop++; - - pci1IoBase = (unsigned int) (pci1IoBase >> 21); - pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase); - GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop); -} - -/* - * pci0MapMemory0space - Maps PCI0 memory0 space for the master. - * Inputs: base and length of pci0Mem0 - */ - -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length) -{ - unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length; - - if (pci0Mem0Length == 0) - pci0Mem0Top++; - - pci0Mem0Base = pci0Mem0Base >> 21; - pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base); - GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top); -} - -/* - * pci1MapMemory0space - Maps PCI1 memory0 space for the master. - * Inputs: base and length of pci1Mem0 - */ - -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length) -{ - unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length; - - if (pci1Mem0Length == 0) - pci1Mem0Top++; - - pci1Mem0Base = pci1Mem0Base >> 21; - pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base); - GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top); -} - -/* - * pci0MapMemory1space - Maps PCI0 memory1 space for the master. - * Inputs: base and length of pci0Mem1 - */ - -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length) -{ - unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length; - - if (pci0Mem1Length == 0) - pci0Mem1Top++; - - pci0Mem1Base = pci0Mem1Base >> 21; - pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base); - GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top); - -} - -/* - * pci1MapMemory1space - Maps PCI1 memory1 space for the master. - * Inputs: base and length of pci1Mem1 - */ - -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length) -{ - unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length; - - if (pci1Mem1Length == 0) - pci1Mem1Top++; - - pci1Mem1Base = pci1Mem1Base >> 21; - pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base); - GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top); -} - -/* - * pci0GetIOspaceBase - Return PCI0 IO Base Address. - * Inputs: N/A - * Returns: PCI0 IO Base Address. - */ - -static unsigned int pci0GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetIOspaceSize - Return PCI0 IO Bar Size. - * Inputs: N/A - * Returns: PCI0 IO Bar Size. - */ -static unsigned int pci0GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 0 Base Address. - */ -static unsigned int pci0GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 0 Bar Size. - */ -static unsigned int pci0GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M0HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 1 Base Address. - */ -static unsigned int pci0GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 1 Bar Size. - */ - -static unsigned int pci0GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetIOspaceBase - Return PCI1 IO Base Address. - * Inputs: N/A - * Returns: PCI1 IO Base Address. - */ - -static unsigned int pci1GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetIOspaceSize - Return PCI1 IO Bar Size. - * Inputs: N/A - * Returns: PCI1 IO Bar Size. - */ - -static unsigned int pci1GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 0 Base Address. - */ - -static unsigned int pci1GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 0 Bar Size. - */ - -static unsigned int pci1GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 1 Base Address. - */ - -static unsigned int pci1GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 1 Bar Size. - */ - -static unsigned int pci1GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - - - -/* - * pci_range_ck - - * - * Check if the pci device that are trying to access does really exists - * on the evaluation board. - * - * Inputs : - * bus - bus number (0 for PCI 0 ; 1 for PCI 1) - * dev - number of device on the specific pci bus - * - * Outpus : - * 0 - if OK , 1 - if failure - */ -static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) -{ - //DBG(KERN_INFO "p_r_c %d %d\n",bus,dev); - if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) - return 0; // Bus/Device Number OK - return -1; // Bus/Device Number not OK -} - -/* - * pciXReadConfigReg - Read from a PCI configuration register - * - Make sure the GT is configured as a master before - * reading from another device on the PCI. - * - The function takes care of Big/Little endian conversion. - * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI - * spec) - * pciDevNum: The device number needs to be addressed. - * RETURNS: data , if the data == 0xffffffff check the master abort bit in the - * cause register to make sure the data is valid - * - * Configuration Address 0xCF8: - * - * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number - * |congif|Reserved| Bus |Device|Function|Register|00| - * |Enable| |Number|Number| Number | Number | | <=field Name - * - */ -static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device) -{ - unsigned int DataForRegCf8; - unsigned int data; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - - /* The casual observer might wonder why the READ is duplicated here, - rather than immediately following the WRITE, and just have the - swap in the "if". That's because there is a latency problem - with trying to read immediately after setting up the address - register. The "if" check gives enough time for the address - to stabilize, so the READ can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } -} - -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device) -{ - unsigned int DataForRegCf8; - unsigned int data; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* The casual observer might wonder why the READ is duplicated here, - rather than immediately following the WRITE, and just have the - swap in the "if". That's because there is a latency problem - with trying to read immediately after setting up the address - register. The "if" check gives enough time for the address - to stabilize, so the READ can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { - GT_READ(GT_PCI1_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } -} - - - -/* - * pciXWriteConfigReg - Write to a PCI configuration register - * - Make sure the GT is configured as a master before - * writingto another device on the PCI. - * - The function takes care of Big/Little endian conversion. - * Inputs: unsigned int regOffset: The register offset as it apears in the - * GT spec - * (or any other PCI device spec) - * pciDevNum: The device number needs to be addressed. - * - * Configuration Address 0xCF8: - * - * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number - * |congif|Reserved| Bus |Device|Function|Register|00| - * |Enable| |Number|Number| Number | Number | | <=field Name - * - */ -static void pci0WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data) -{ - unsigned int DataForRegCf8; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data)); - } -} - -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data) -{ - unsigned int DataForRegCf8; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* There is a latency problem - with trying to read immediately after setting up the address - register. The "if" check gives enough time for the address - to stabilize, so the WRITE can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data)); - } -} - - -/* - * galileo_pcibios_(read/write)_config_(dword/word/byte) - - * - * reads/write a dword/word/byte register from the configuration space - * of a device. - * - * Inputs : - * bus - bus number - * dev - device number - * offset - register offset in the configuration space - * val - value to be written / read - * - * Outputs : - * PCIBIOS_SUCCESSFUL when operation was succesfull - * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous - * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned - */ - -static int galileo_pcibios_read_config_dword(struct pci_dev *device, - int offset, u32 * val) -{ - int dev, bus; - //DBG(KERN_INFO "rcd entry \n",offset,val); - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - *val = pci0ReadConfigReg(offset, device); -// if (bus == 1) *val = pci1ReadConfigReg (offset,device); - DBG(KERN_INFO "rr: rcd dev %d offset %x %x\n", dev, offset, *val); - - /* - * This is so that the upper PCI layer will get the correct return - * value if we're not attached to anything. - */ - if ((offset == 0) && (*val == 0xffffffff)) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_word(struct pci_dev *device, - int offset, u16 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (bus == 0) - *val = (unsigned short) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); -// if (bus == 1) *val = (unsigned short) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8)); - - DBG(KERN_INFO "rr: rcw dev %d offset %x %x\n", dev, offset, *val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_byte(struct pci_dev *device, - int offset, u8 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - - if (bus == 0) - *val = - (unsigned char) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); -// if (bus == 1) *val = (unsigned char) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8)); - - DBG(KERN_INFO "rr: rcb dev %d offset %x %x\n", dev, offset, *val); - - /* This is so that the upper PCI layer will get the correct return value if - we're not attached to anything. */ - if ((offset == 0xe) && (*val == 0xff)) { - u32 MasterAbort; - GT_READ(GT_INTRCAUSE_OFS, &MasterAbort); - if (MasterAbort & 0x40000) { - DBG(KERN_INFO "PCI Master Abort, ICR %x\n", - MasterAbort); - GT_WRITE(GT_INTRCAUSE_OFS, - (MasterAbort & 0xfffbffff)); - return PCIBIOS_DEVICE_NOT_FOUND; - } - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_dword(struct pci_dev *device, - int offset, u32 val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - pci0WriteConfigReg(offset, device, val); -// if (bus == 1) pci1WriteConfigReg (offset,device,val); - - DBG(KERN_INFO "rr: wcd dev %d, offset %x, val %x\n", dev, offset, - val); - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_write_config_word(struct pci_dev *device, - int offset, u16 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffff0000) | (val & 0xffff); - if ((offset % 4) == 2) - tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - DBG(KERN_INFO "rr: wcw dev %d, offset %x, val %x\n", dev, offset, - val); - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_byte(struct pci_dev *device, - int offset, u8 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffffff00) | (val & 0xff); - if ((offset % 4) == 1) - tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8); - if ((offset % 4) == 2) - tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16); - if ((offset % 4) == 3) - tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - DBG(KERN_INFO "rr: wcb dev %d, offset %x, val %x\n", dev, offset, - val); - - return PCIBIOS_SUCCESSFUL; -} - -static void galileo_pcibios_set_master(struct pci_dev *dev) -{ - u16 cmd; - - DBG(KERN_INFO "rr: galileo_pcibios_set_master\n"); - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - DBG("PCI: Enabling device %s (%04x)\n", dev->slot_name, cmd); -} - -/* Externally-expected functions. Do not change function names */ - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - u16 tmp; - u8 tmp1; - int idx; - struct resource *r; - - DBG(KERN_INFO "rr: pcibios_enable_resources\n"); - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - DBG(KERN_INFO - "rr: BAR %d, start %lx, end %lx, flags %lx\n", idx, - r->start, r->end, r->flags); - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of resource collisions\n", - dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - DBG(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - } - - /* - Let's fix up the latency timer and cache line size here. Cache line size = - 32 bytes / sizeof dword (4) = 8. - Latency timer must be > 8. 32 is random but appears to work. - */ - galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); - if (tmp1 != 8) { - DBG(KERN_INFO - "rr: PCI setting cache line size to 8 from %d\n", - tmp1); - galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - 8); - } - galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); - if (tmp1 < 32) { - DBG(KERN_INFO - "rr: PCI setting latency timer to 32 from %d\n", tmp1); - galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, - 32); - } - - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - DBG(KERN_INFO "rr: pcibios_enable_device\n"); - return pcibios_enable_resources(dev); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - DBG(KERN_INFO "rr: pcibios_update_resource\n"); - return; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - DBG(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - DBG(KERN_INFO "pcibios_align_resource\n"); - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - DBG(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -/* - * structure galileo_pci_ops - * - * This structure holds the pointers for the PCI configuration space - * access, and the fixup for the interrupts. - * This structure is registered to the operating system in boot time - */ -struct pci_ops galileo_pci_ops = { - galileo_pcibios_read_config_byte, - galileo_pcibios_read_config_word, - galileo_pcibios_read_config_dword, - galileo_pcibios_write_config_byte, - galileo_pcibios_write_config_word, - galileo_pcibios_write_config_dword -}; - -/* - * galileo_pcibios_fixup_bus - - * - * After detecting all agents over the PCI , this function is called - * in order to give an interrupt number for each PCI device starting - * from IRQ 20. It does also enables master for each device. - * - * Inputs : - * mem_start , mem_end are not relevant in MIPS architecture. - * - * Outpus : - * return always mem_start - */ -static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus) -{ - unsigned int Current_IRQ = 20; - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - - list_for_each(devices_link, &(current_bus->devices)) { - devices = pci_dev_b(devices_link); - if (devices != NULL) { - devices->irq = Current_IRQ++; - - /* Assign an interrupt number for the device */ - galileo_pcibios_write_config_byte(devices, - PCI_INTERRUPT_LINE, - Current_IRQ); - galileo_pcibios_set_master(devices); - - } - } - -} - -struct pci_fixup pcibios_fixups[] = { -// { PCI_FIXUP_HEADER, 0x4620, 0x11ab, galileo_pcibios_fixup }, - {0} -}; - -void __init pcibios_fixup_bus(struct pci_bus *c) -{ - DBG(KERN_INFO "rr: pcibios_fixup_bus\n"); - galileo_pcibios_fixup_bus(c); -} - -/* - * This code was derived from Galileo Technology's example - * and significantly reworked. - * - * This is very simple. It does not scan multiple function devices. It does - * not scan behind bridges. Those would be simple to implement, but we don't - * currently need this. - */ -static void __init scan_and_initialize_pci(void) -{ - struct pci_device pci_devices[MAX_PCI_DEVS]; - - if (scan_pci_bus(pci_devices)) { - allocate_pci_space(pci_devices); - } -} - -/* - * This is your basic PCI scan. It goes through each slot and checks to - * see if there's something that responds. If so, then get the size and - * type of each of the responding BARs. Save them for later. - */ - -static u32 __init scan_pci_bus(struct pci_device *pci_devices) -{ - u32 arrayCounter = 0; - u32 memType; - u32 memSize; - u32 pci_slot, bar; - u32 id; - u32 c18RegValue; - struct pci_dev device; - - DBG(KERN_INFO "rr: scan_pci_bus\n"); - - /* - According to PCI REV 2.1 MAX agents on the bus are 21. - We don't bother scanning ourselves (slot 0). - */ - for (pci_slot = 1; pci_slot < 22; pci_slot++) { - - device.devfn = PCI_DEVFN(pci_slot, 0); - id = pci0ReadConfigReg(PCI_VENDOR_ID, &device); - - /* Check for a PCI Master Abort (nothing responds in the slot) */ - GT_READ(GT_INTRCAUSE_OFS, &c18RegValue); - /* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */ - GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff)); - if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { - DBG(KERN_INFO "rr: found device %x, slot %d\n", id, - pci_slot); - pci_devices[arrayCounter].slot = pci_slot; - for (bar = 0; bar < 6; bar++) { - memType = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - pci_devices[arrayCounter].BARtype[bar] = - memType & 1; - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device, - 0xffffffff); - memSize = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - if (memType & 1) { /* IO space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffffc) + 1; - } else { /* memory space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffff0) + 1; - } - DBG(KERN_INFO - "rr: BAR %d, type %d, size %x\n", bar, - (memType & 1), - pci_devices[arrayCounter]. - BARsize[bar]); - } /* BAR counter */ - - arrayCounter++; - } - /* found a device */ - } /* slot counter */ - - DBG(KERN_INFO "rr: found %d devices\n", arrayCounter); - if (arrayCounter < MAX_PCI_DEVS) { - pci_devices[arrayCounter].slot = -1; - } - return (arrayCounter); -} - -#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) -#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2)) - -/* - * This function goes through the list of devices and allocates the BARs in - * either IO or MEM space. It does it in order of size, which will limit the - * amount of fragmentation we have in the IO and MEM spaces. - */ - -static void __init allocate_pci_space(struct pci_device *pci_devices) -{ - u32 count, maxcount, bar; - u32 maxSize, maxDevice, maxBAR; - u32 alignto; - u32 base; - u32 pci0_mem_base = pci0GetMemory0Base(); - u32 pci0_io_base = pci0GetIOspaceBase(); - struct pci_dev device; - - DBG(KERN_INFO "rr: allocate_pci_space\n"); - - DBG(KERN_INFO "pci0_io_base %x\n", pci0_io_base); - DBG(KERN_INFO "pci0_mem_base %x\n", pci0_mem_base); - - /* How many PCI devices do we have? */ - maxcount = MAX_PCI_DEVS; - for (count = 0; count < MAX_PCI_DEVS; count++) { - if (pci_devices[count].slot == -1) { - maxcount = count; - break; - } - } - -// DBG(KERN_INFO "Found %d devices\n", maxcount); - - do { - /* Find the largest size BAR we need to allocate */ - maxSize = 0; - for (count = 0; count < maxcount; count++) { - for (bar = 0; bar < 6; bar++) { - if (pci_devices[count].BARsize[bar] > - maxSize) { - maxSize = - pci_devices[count]. - BARsize[bar]; - maxDevice = count; - maxBAR = bar; - } - } - } - - /* - We've found the largest BAR. Allocate it into IO or - mem space. We don't idiot check the bases to make - sure they haven't overflowed the current size for that aperture. - - Don't bother to enable the device's IO or MEM space here. That will - be done in pci_enable_resources if the device is activated by a driver. - */ - if (maxSize) { - device.devfn = - PCI_DEVFN(pci_devices[maxDevice].slot, 0); - if (pci_devices[maxDevice].BARtype[maxBAR] == 1) { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_io_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base | 0x1); - pci0_io_base = base + alignto; - DBG(KERN_INFO - "Device %d BAR %d address %x\n", - pci_devices[maxDevice].slot, maxBAR, - base); - DBG(KERN_INFO "New IO base %x\n", - pci0_io_base); - } else { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_mem_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base); - pci0_mem_base = base + alignto; - DBG(KERN_INFO - "Device %d BAR %d address %x\n", - pci_devices[maxDevice].slot, maxBAR, - base); - DBG(KERN_INFO "New mem base %x\n", - pci0_mem_base); - } - /* - This entry is finished. Remove it from the list we'll scan. - */ - pci_devices[maxDevice].BARsize[maxBAR] = 0; - } - } while (maxSize); -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -void __init pcibios_init(void) -{ - - u32 tmp; - struct pci_dev controller; - - controller.devfn = SELF; - - DBG(KERN_INFO "rr: pcibios_init\n"); - GT_READ(GT_PCI0_CMD_OFS, &tmp); - DBG(KERN_INFO "rr: PCI0 command - %x\n", tmp); - GT_READ(GT_PCI0_BARE_OFS, &tmp); - DBG(KERN_INFO "rr: BAR0 - %x\n", tmp); - - /* - * You have to enable bus mastering to configure any other - * card on the bus. - */ - tmp = pci0ReadConfigReg(PCI_COMMAND, &controller); - DBG(KERN_INFO "rr: command/status - %x\n", tmp); - tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; - DBG(KERN_INFO "rr: new command/status - %x\n", tmp); - pci0WriteConfigReg(PCI_COMMAND, &controller, tmp); - - /* This scans the PCI bus and sets up initial values. */ - scan_and_initialize_pci(); - - /* - * Reset PCI I/O and PCI MEM values to ones supported by EVM. - */ - ioport_resource.start = 0x10000000; - ioport_resource.end = 0x11ffffff; /* 32 MB */ - iomem_resource.start = 0x12000000; - iomem_resource.end = 0x13ffffff; /* 32 MB */ - - pci_scan_bus(0, &galileo_pci_ops, NULL); - -} - -char *pcibios_setup(char *str) -{ - printk(KERN_INFO "rr: pcibios_setup\n"); - /* Nothing to do for now. */ - - return str; -} - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/promcon.c linux-2.4.22/arch/mips/galileo-boards/ev64120/promcon.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/promcon.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/promcon.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,58 +0,0 @@ -/* - * Wrap-around code for a console using the - * SGI PROM io-routines. - * - * Copyright (c) 1999 Ulf Carlsson - * - * Derived from DECstation promcon.c - * Copyright (c) 1998 Harald Koerfgen - */ -#include -#include -#include -#include -#include -#include - -static void prom_console_write(struct console *co, const char *s, - unsigned count) -{ - extern int CONSOLE_CHANNEL; // The default serial port - unsigned i; - - for (i = 0; i < count; i++) { - if (*s == 10) - serial_putc(CONSOLE_CHANNEL, 13); - serial_putc(CONSOLE_CHANNEL, *s++); - } -} - -int prom_getchar(void) -{ - return 0; -} - -static kdev_t prom_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -static struct console sercons = { - name: "ttyS", - write: prom_console_write, - device: prom_console_device, - flags: CON_PRINTBUFFER, - index: -1, -}; - -/* - * Register console. - */ - -void gal_serial_console_init(void) -{ - // serial_init(); - //serial_set(115200); - - register_console(&sercons); -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/reset.c linux-2.4.22/arch/mips/galileo-boards/ev64120/reset.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/reset.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/reset.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,45 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1997 Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include - -void galileo_machine_restart(char *command) -{ - *(volatile char *) 0xbc000000 = 0x0f; - /* - * Ouch, we're still alive ... This time we take the silver bullet ... - * ... and find that we leave the hardware in a state in which the - * kernel in the flush locks up somewhen during of after the PCI - * detection stuff. - */ - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); -} - -void galileo_machine_halt(void) -{ - printk(KERN_NOTICE "You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); - -} - -void galileo_machine_power_off(void) -{ - galileo_machine_halt(); -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/serialGT.c linux-2.4.22/arch/mips/galileo-boards/ev64120/serialGT.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/serialGT.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/serialGT.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,212 +0,0 @@ -/* - * serialGT.c - * - * BRIEF MODULE DESCRIPTION - * Low Level Serial Port control for use - * with the Galileo EVB64120A MIPS eval board and - * its on board two channel 16552 Uart. - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You 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. - * - */ - -// Note: -// Serial CHANNELS - 0 is the bottom connector of evb64120A. -// (The one that maps to the "B" channel of the -// board's uart) -// 1 is the top connector of evb64120A. -// (The one that maps to the "A" channel of the -// board's uart) -int DEBUG_CHANNEL = 0; // See Note Above -int CONSOLE_CHANNEL = 1; // See Note Above - -#define DUART 0xBD000000 /* Base address of Uart. */ -#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA - register set of the 16552 Uart device. - DUART+0 gets you to the ChanB register set. - */ -#define DUART_DELTA 0x4 -#define FIFO_ENABLE 0x07 -#define INT_ENABLE 0x04 /* default interrupt mask */ - -#define RBR 0x00 -#define THR 0x00 -#define DLL 0x00 -#define IER 0x01 -#define DLM 0x01 -#define IIR 0x02 -#define FCR 0x02 -#define LCR 0x03 -#define MCR 0x04 -#define LSR 0x05 -#define MSR 0x06 -#define SCR 0x07 - -#define LCR_DLAB 0x80 -#define XTAL 1843200 -#define LSR_THRE 0x20 -#define LSR_BI 0x10 -#define LSR_DR 0x01 -#define MCR_LOOP 0x10 -#define ACCESS_DELAY 0x10000 - -/****************************** - Routine: - Description: - ******************************/ -int inreg(int channel, int reg) -{ - int val; - val = - *((volatile unsigned char *) DUART + - (channel * CHANNELOFFSET) + (reg * DUART_DELTA)); - return val; -} - -/****************************** - Routine: - Description: - ******************************/ -void outreg(int channel, int reg, unsigned char val) -{ - *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET) - + (reg * DUART_DELTA)) = val; -} - -/****************************** - Routine: - Description: - Initialize the device driver. - ******************************/ -void serial_init(int channel) -{ - /* - * Configure active port, (CHANNELOFFSET already set.) - * - * Set 8 bits, 1 stop bit, no parity. - * - * LCR<7> 0 divisor latch access bit - * LCR<6> 0 break control (1=send break) - * LCR<5> 0 stick parity (0=space, 1=mark) - * LCR<4> 0 parity even (0=odd, 1=even) - * LCR<3> 0 parity enable (1=enabled) - * LCR<2> 0 # stop bits (0=1, 1=1.5) - * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8) - */ - outreg(channel, LCR, 0x3); - - outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */ - - outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */ -} - -/****************************** - Routine: - Description: - Set the baud rate. - ******************************/ -void serial_set(int channel, unsigned long baud) -{ - unsigned char sav_lcr; - - /* - * Enable access to the divisor latches by setting DLAB in LCR. - * - */ - sav_lcr = inreg(channel, LCR); - -#if 0 - /* - * Set baud rate - */ - outreg(channel, LCR, LCR_DLAB | sav_lcr); - // outreg(DLL,(XTAL/(16*2*(baud))-2)); - outreg(channel, DLL, XTAL / (16 * baud)); - // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8); - outreg(channel, DLM, (XTAL / (16 * baud)) >> 8); -#else - /* - * Note: Set baud rate, hardcoded here for rate of 115200 - * since became unsure of above "buad rate" algorithm (??). - */ - outreg(channel, LCR, 0x83); - outreg(channel, DLM, 0x00); // See note above - outreg(channel, DLL, 0x02); // See note above. - outreg(channel, LCR, 0x03); -#endif - - /* - * Restore line control register - */ - outreg(channel, LCR, sav_lcr); -} - - -/****************************** - Routine: - Description: - Transmit a character. - ******************************/ -void serial_putc(int channel, int c) -{ - while ((inreg(channel, LSR) & LSR_THRE) == 0); - outreg(channel, THR, c); -} - -/****************************** - Routine: - Description: - Read a received character if one is - available. Return -1 otherwise. - ******************************/ -int serial_getc(int channel) -{ - if (inreg(channel, LSR) & LSR_DR) { - return inreg(channel, RBR); - } - return -1; -} - -/****************************** - Routine: - Description: - Used by embedded gdb client. (example; gdb-stub.c) - ******************************/ -char getDebugChar() -{ - int val; - while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in. - return (char) val; -} - -/****************************** - Routine: - Description: - Used by embedded gdb target. (example; gdb-stub.c) - ******************************/ -void putDebugChar(char c) -{ - serial_putc(DEBUG_CHANNEL, (int) c); -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev64120/setup.c linux-2.4.22/arch/mips/galileo-boards/ev64120/setup.c --- linux-2.4.21/arch/mips/galileo-boards/ev64120/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev64120/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,188 +0,0 @@ -/* - * setup.c - * - * BRIEF MODULE DESCRIPTION - * Galileo Evaluation Boards - board dependent boot routines - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct rtc_ops no_rtc_ops; - -/* These functions are used for rebooting or halting the machine*/ -extern void galileo_machine_restart(char *command); -extern void galileo_machine_halt(void); -extern void galileo_machine_power_off(void); -/* - *This structure holds pointers to the pci configuration space accesses - *and interrupts allocating routine for device over the PCI - */ -extern struct pci_ops galileo_pci_ops; - -extern unsigned long mips_machgroup; - -char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 " - "root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal " - "ip=192.168.1.211:192.168.1.1:::gt::" -}; - -//struct eeprom_parameters eeprom_param; - -/* - * This function is added because arch/mips/mm/init.c needs it - * basically it does nothing - */ -void prom_free_prom_memory(void) -{ -} - -extern void (*board_time_init) (struct irqaction * irq); - -static unsigned char galileo_rtc_read_data(unsigned long addr) -{ - return 0; -} - -static void galileo_rtc_write_data(unsigned char data, unsigned long addr) -{ -} - -static int galileo_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops galileo_rtc_ops = { - &galileo_rtc_read_data, - &galileo_rtc_write_data, - &galileo_rtc_bcd_mode -}; - - -void __init bus_error_init(void) { /* nothing */ } - - -/******************************************************************** - *ev64120_setup - - * - *Initializes basic routines and structures pointers, memory size (as - *given by the bios and saves the command line. - * - * - *Inputs : - * - *Outpus : - * - *********************************************************************/ -extern void galileo_time_init(); -void ev64120_setup(void) -{ - unsigned int i, j; - - //printk(KERN_INFO "ev64120_setup\n"); - - _machine_restart = galileo_machine_restart; - _machine_halt = galileo_machine_halt; - _machine_power_off = galileo_machine_power_off; - - rtc_ops = &galileo_rtc_ops; - - board_time_init = galileo_time_init; - set_io_port_base(KSEG1); - -#ifdef CONFIG_L2_L3_CACHE -#error "external cache not implemented yet" - config_register = read_32bit_cp0_register(CP0_CONFIG); - printk("\n\n\nchecking second level cache cp0_config = %08lx\n", - config_register); - if (config_register & CONF_SC) { // second/third level cache available - config_register = config_register & (1 << 12); - write_32bit_cp0_register(CP0_CONFIG, config_register); - printk - ("\n\n\nchecking second level cache cp0_config = %08lx\n", - config_register); - } -#endif - -} - -const char *get_system_type(void) -{ - return "Galileo EV64120A"; -} - -/* - * SetUpBootInfo - - * - * This function is called at very first stages of kernel startup. - * It specifies for the kernel the evaluation board that the linux - * is running on. Then it saves the eprom parameters that holds the - * command line, memory size etc... - * - * Inputs : - * argc - nothing - * argv - holds a pointer to the eprom parameters - * envp - nothing - */ - -void SetUpBootInfo(int argc, char **argv, char **envp) -{ - mips_machgroup = MACH_GROUP_GALILEO; - mips_machtype = MACH_EV64120A; -} - -void __init prom_init(int a, char **b, char **c, int *d) -{ - unsigned long free_start, free_end, start_pfn, bootmap_size; - - mips_machgroup = MACH_GROUP_GALILEO; - add_memory_region(0, 32 << 20, BOOT_MEM_RAM); -} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/Makefile linux-2.4.22/arch/mips/galileo-boards/ev96100/Makefile --- linux-2.4.21/arch/mips/galileo-boards/ev96100/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -12,9 +12,10 @@ USE_STANDARD_AS_RULE := true -O_TARGET:= ev96100.o +O_TARGET := ev96100.o -obj-y := init.o pci_ops.o pci_fixups.o time.o irq.o int-handler.o setup.o \ - puts.o +obj-y := init.o irq.o puts.o reset.o time.o int-handler.o \ + setup.o +obj-$(CONFIG_PCI) += pci_fixups.o pci_ops.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/init.c linux-2.4.22/arch/mips/galileo-boards/ev96100/init.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/init.c 2003-08-25 04:44:39.000000000 -0700 @@ -39,7 +39,7 @@ #include #include -#include +#include /* Environment variable */ diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/irq.c linux-2.4.22/arch/mips/galileo-boards/ev96100/irq.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/irq.c 2003-08-25 04:44:39.000000000 -0700 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -45,13 +46,10 @@ #include #include #include -#include #include #include #include -extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); - extern void mips_timer_interrupt(int irq, struct pt_regs *regs); extern asmlinkage void ev96100IRQ(void); @@ -60,7 +58,7 @@ unsigned long flags; save_and_cli(flags); - clear_cp0_status(0x100 << irq_nr); + clear_c0_status(0x100 << irq_nr); restore_flags(flags); } @@ -69,7 +67,7 @@ unsigned long flags; save_and_cli(flags); - set_cp0_status(0x100 << irq_nr); + set_c0_status(0x100 << irq_nr); restore_flags(flags); } diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/pci_fixups.c linux-2.4.22/arch/mips/galileo-boards/ev96100/pci_fixups.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/pci_fixups.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/pci_fixups.c 2003-08-25 04:44:39.000000000 -0700 @@ -27,18 +27,13 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - -#ifdef CONFIG_PCI - #include #include #include #include #include -#include -#include +#include extern unsigned short get_gt_devid(void); @@ -93,4 +88,3 @@ { return 0; } -#endif diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/pci_ops.c linux-2.4.22/arch/mips/galileo-boards/ev96100/pci_ops.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/pci_ops.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/pci_ops.c 2003-08-25 04:44:39.000000000 -0700 @@ -33,242 +33,40 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - -#ifdef CONFIG_PCI - +#include #include #include #include -#include #include -#include -#include +#include #include #define PCI_ACCESS_READ 0 #define PCI_ACCESS_WRITE 1 -#undef DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - #define GT_PCI_MEM_BASE 0x12000000 #define GT_PCI_MEM_SIZE 0x02000000 #define GT_PCI_IO_BASE 0x10000000 #define GT_PCI_IO_SIZE 0x02000000 + static struct resource pci_io_resource = { "io pci IO space", 0x10000000, 0x10000000 + 0x02000000, - IORESOURCE_IO}; + IORESOURCE_IO +}; static struct resource pci_mem_resource = { "ext pci memory space", 0x12000000, 0x12000000 + 0x02000000, - IORESOURCE_MEM}; + IORESOURCE_MEM +}; -extern struct pci_ops gt96100_pci_ops; +extern struct pci_ops gt64120_pci_ops; struct pci_channel mips_pci_channels[] = { - { >96100_pci_ops, &pci_io_resource, &pci_mem_resource, 1, 0xff }, + { >64120_pci_ops, &pci_io_resource, &pci_mem_resource, 1, 0xff }, { NULL, NULL, NULL, NULL, NULL} }; - -int -static gt96100_config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 *data) -{ - unsigned char bus = dev->bus->number; - unsigned char dev_fn = dev->devfn; - u32 intr; - - - if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) { - return -1; /* Because of a bug in the galileo (for slot 31). */ - } - - /* Clear cause register bits */ - GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - /* Setup address */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | - (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | - ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | - GT_PCI0_CFGADDR_CONFIGEN_BIT); - udelay(2); - - - if (access_type == PCI_ACCESS_WRITE) { - if (dev_fn != 0) { - *data = le32_to_cpu(*data); - } - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } - else { - GT_READ(GT_PCI0_CFGDATA_OFS, *data); - if (dev_fn != 0) { - *data = le32_to_cpu(*data); - } - } - - udelay(2); - - /* Check for master or target abort */ - GT_READ(GT_INTRCAUSE_OFS, intr); - - if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) - { - //printk("config access error: %x:%x\n", dev_fn,where); - /* Error occured */ - - /* Clear bits */ - GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT) ); - - if (access_type == PCI_ACCESS_READ) { - *data = 0xffffffff; - } - return -1; - } - return 0; -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int -read_config_byte (struct pci_dev *dev, int where, u8 *val) -{ - u32 data = 0; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { - *val = 0xff; - return -1; - } - - *val = (data >> ((where & 3) << 3)) & 0xff; - DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, *val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int -read_config_word (struct pci_dev *dev, int where, u16 *val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { - *val = 0xffff; - return -1; - } - - *val = (data >> ((where & 3) << 3)) & 0xffff; - DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, *val); - - return PCIBIOS_SUCCESSFUL; -} - -static int -read_config_dword (struct pci_dev *dev, int where, u32 *val) -{ - u32 data = 0; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { - *val = 0xffffffff; - return -1; - } - - *val = data; - DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, *val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int -write_config_byte (struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - DBG("cfg write byte: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, val); - - if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int -write_config_word (struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - DBG("cfg write word: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, val); - - if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int -write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - DBG("cfg write dword: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, val); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops gt96100_pci_ops = { - read_config_byte, - read_config_word, - read_config_dword, - write_config_byte, - write_config_word, - write_config_dword -}; - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/puts.c linux-2.4.22/arch/mips/galileo-boards/ev96100/puts.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/puts.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/puts.c 2003-08-25 04:44:39.000000000 -0700 @@ -4,7 +4,7 @@ */ #include -#include +#include //#define SERIAL_BASE EV96100_UART0_REGS_BASE @@ -22,123 +22,117 @@ #undef SLOW_DOWN static const char digits[16] = "0123456789abcdef"; -static volatile unsigned char * const com1 = (unsigned char *)SERIAL_BASE; +static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE; #ifdef SLOW_DOWN static inline void slow_down() { - int k; - for (k=0; k<10000; k++); + int k; + for (k = 0; k < 10000; k++); } #else #define slow_down() #endif -void -putch(const unsigned char c) +void putch(const unsigned char c) { - unsigned char ch; - int i = 0; + unsigned char ch; + int i = 0; - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = c; -} - -void -putchar(const unsigned char c) -{ - unsigned char ch; - int i = 0; - - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = c; -} - -void -puts(unsigned char *cp) -{ - unsigned char ch; - int i = 0; - - while (*cp) { - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = *cp++; - } - putch('\r'); - putch('\n'); -} - -void -fputs(unsigned char *cp) -{ - unsigned char ch; - int i = 0; - - while (*cp) { - - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = *cp++; - } -} - - -void -put64(uint64_t ul) -{ - int cnt; - unsigned ch; - - cnt = 16; /* 16 nibbles in a 64 bit long */ - putch('0'); - putch('x'); - do { - cnt--; - ch = (unsigned char)(ul >> cnt * 4) & 0x0F; - putch(digits[ch]); - } while (cnt > 0); -} - -void -put32(unsigned u) -{ - int cnt; - unsigned ch; - - cnt = 8; /* 8 nibbles in a 32 bit long */ - putch('0'); - putch('x'); - do { - cnt--; - ch = (unsigned char)(u >> cnt * 4) & 0x0F; - putch(digits[ch]); - } while (cnt > 0); + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void putchar(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void puts(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } + putch('\r'); + putch('\n'); +} + +void fputs(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } +} + + +void put64(uint64_t ul) +{ + int cnt; + unsigned ch; + + cnt = 16; /* 16 nibbles in a 64 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (ul >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} + +void put32(unsigned u) +{ + int cnt; + unsigned ch; + + cnt = 8; /* 8 nibbles in a 32 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (u >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); } diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/reset.c linux-2.4.22/arch/mips/galileo-boards/ev96100/reset.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/reset.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,70 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 reset routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/reset.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + +static void mips_machine_restart(char *command) +{ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); + while (1); +} + +static void mips_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void mips_reboot_setup(void) +{ + _machine_restart = mips_machine_restart; + _machine_halt = mips_machine_halt; +} diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/setup.c linux-2.4.22/arch/mips/galileo-boards/ev96100/setup.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/setup.c 2003-08-25 04:44:39.000000000 -0700 @@ -1,5 +1,4 @@ /* - * * BRIEF MODULE DESCRIPTION * Galileo EV96100 setup. * @@ -47,8 +46,7 @@ #include #include #include -#include -#include +#include #include @@ -65,17 +63,16 @@ unsigned char mac_0_1[12]; - void __init ev96100_setup(void) { - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - unsigned long status = read_32bit_cp0_register(CP0_STATUS); - unsigned long info = read_32bit_cp0_register(CP0_INFO); + unsigned int config = read_c0_config(); + unsigned int status = read_c0_status(); + unsigned int info = read_c0_info(); u32 tmp; char *argptr; - clear_cp0_status(ST0_FR); + clear_c0_status(ST0_FR); if (config & 0x8) { printk("Secondary cache is enabled\n"); @@ -164,7 +161,7 @@ GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(2); - tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR); @@ -174,7 +171,7 @@ ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(2); - *(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS) = cpu_to_le32(tmp); + GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); /* Setup address */ GT_WRITE(GT_PCI0_CFGADDR_OFS, @@ -184,7 +181,7 @@ GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(2); - tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); } unsigned short get_gt_devid() @@ -199,7 +196,7 @@ GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(4); - gt_devid = le32_to_cpu(*(volatile u32 *) - (MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); - return (unsigned short)(gt_devid>>16); + gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS); + + return gt_devid >> 16; } diff -urN linux-2.4.21/arch/mips/galileo-boards/ev96100/time.c linux-2.4.22/arch/mips/galileo-boards/ev96100/time.c --- linux-2.4.21/arch/mips/galileo-boards/ev96100/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/ev96100/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -54,7 +54,7 @@ static inline void ack_r4ktimer(unsigned long newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } static int set_rtc_mmss(unsigned long nowtime) @@ -109,12 +109,11 @@ est_freq -= est_freq%10000; printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); + r4k_cur = (read_c0_count() + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); + write_c0_compare(r4k_cur); - /* FIX ME */ - change_cp0_status(ST0_IM, IE_IRQ5); + change_c0_status(ST0_IM, IE_IRQ5); /* FIX ME */ } /* This is for machines which generate the exact clock. */ @@ -172,7 +171,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -195,7 +194,7 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; read_lock_irqsave (&xtime_lock, flags); *tv = xtime; @@ -221,7 +220,7 @@ write_lock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is is value at the last tick. + * However, the value in this location is value at the last tick. * Discover what correction gettimeofday would have done, and then * undo it! */ @@ -260,7 +259,7 @@ r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) + } while (((unsigned long)read_c0_count() - r4k_cur) < 0x7fffffff); return; diff -urN linux-2.4.21/arch/mips/galileo-boards/generic/Makefile linux-2.4.22/arch/mips/galileo-boards/generic/Makefile --- linux-2.4.21/arch/mips/galileo-boards/generic/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/generic/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,36 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# ######################################################################## -# -# This program is free software; you can distribute 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 it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You 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. -# -# ####################################################################### -# -# Makefile for the MIPS boards generic routines under Linux. -# -# 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... - -USE_STANDARD_AS_RULE := true - -O_TARGET:= galboards.o - -obj-y := reset.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/galileo-boards/generic/reset.c linux-2.4.22/arch/mips/galileo-boards/generic/reset.c --- linux-2.4.21/arch/mips/galileo-boards/generic/reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/galileo-boards/generic/reset.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,72 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Galileo EV96100 reset routines. - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This file was derived from Carsten Langgaard's - * arch/mips/mips-boards/generic/reset.c - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static void mips_machine_restart(char *command); -static void mips_machine_halt(void); - -static void mips_machine_restart(char *command) -{ - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); - while (1); -} - -static void mips_machine_halt(void) -{ - printk(KERN_NOTICE "You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); -} - -void mips_reboot_setup(void) -{ - _machine_restart = mips_machine_restart; - _machine_halt = mips_machine_halt; -} diff -urN linux-2.4.21/arch/mips/gt64120/common/Makefile linux-2.4.22/arch/mips/gt64120/common/Makefile --- linux-2.4.21/arch/mips/gt64120/common/Makefile 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/common/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -6,13 +6,11 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true -O_TARGET:= gt64120.o +O_TARGET := gt64120.o -obj-y := gt_irq.o pci.o +obj-y += time.o +obj-$(CONFIG_PCI) += pci.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/gt64120/common/gt_irq.c linux-2.4.22/arch/mips/gt64120/common/gt_irq.c --- linux-2.4.21/arch/mips/gt64120/common/gt_irq.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/common/gt_irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,250 +0,0 @@ -/* - * - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * arch/mips/gt64120/common/gt_irq.c - * Interrupt routines for gt64120. Currently it only handles timer irq. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * These are interrupt handlers for the GT on-chip interrupts. They - * all come in to the MIPS on a single interrupt line, and have to - * be handled and ack'ed differently than other MIPS interrupts. - */ - -#if CURRENTLY_UNUSED - -struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); - -/* - * Hooks IRQ handler to the system. When the system is interrupted - * the interrupt service routine is called. - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * isr_ptr - Pointer to the interrupt service routine - */ -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) -{ - irq_handlers[int_cause][bit_num].routine = isr_ptr; -} - - -/* - * Enables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int enable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - - return 1; -} - -/* - * Disables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int disable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - return 1; -} -#endif /* UNUSED */ - -/* - * Interrupt handler for interrupts coming from the Galileo chip. - * It could be timer interrupt, built in ethernet ports etc... - */ -static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int irq_src, int_high_src, irq_src_mask, - int_high_src_mask; - int handled; - - GT_READ(GT_INTRCAUSE_OFS, &irq_src); - GT_READ(GT_INTRMASK_OFS, &irq_src_mask); - GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); - GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); - irq_src = irq_src & irq_src_mask; - int_high_src = int_high_src & int_high_src_mask; - - handled = 0; - - /* Execute all interrupt handlers */ - /* Check for timer interrupt */ - if (irq_src & 0x00000800) { - handled = 1; - irq_src &= ~0x00000800; - // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); - do_timer(regs); - } - - if (irq_src) { - printk(KERN_INFO - "Other Galileo interrupt received irq_src %x\n", - irq_src); -#if CURRENTLY_UNUSED - for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { - if (irq_src & (1 << count)) { - if (irq_handlers[INT_CAUSE_MAIN][count]. - routine) { - queue_task(&irq_handlers - [INT_CAUSE_MAIN][count], - &tq_immediate); - mark_bh(IMMEDIATE_BH); - handled = 1; - } - } - } -#endif /* UNUSED */ - } - GT_WRITE(GT_INTRCAUSE_OFS, 0); - GT_WRITE(GT_HINTRCAUSE_OFS, 0); - -#undef GALILEO_I2O -#ifdef GALILEO_I2O - /* - * Future I2O support. We currently attach I2O interrupt handlers to - * the Galileo interrupt (int 4) and handle them in do_IRQ. - */ - if (isInBoundDoorBellInterruptSet()) { - printk(KERN_INFO "I2O doorbell interrupt received.\n"); - handled = 1; - } - - if (isInBoundPostQueueInterruptSet()) { - printk(KERN_INFO "I2O Queue interrupt received.\n"); - handled = 1; - } - - /* - * This normally would be outside of the ifdef, but since we're - * handling I2O outside of this handler, this printk shows up every - * time we get a valid I2O interrupt. So turn this off for now. - */ - if (handled == 0) { - if (counter < 50) { - printk("Spurious Galileo interrupt...\n"); - counter++; - } - } -#endif -} - -/* - * Initializes timer using galileo's built in timer. - */ -#ifdef CONFIG_SYSCLK_100 -#define Sys_clock (100 * 1000000) // 100 MHz -#endif -#ifdef CONFIG_SYSCLK_83 -#define Sys_clock (83.333 * 1000000) // 83.333 MHz -#endif -#ifdef CONFIG_SYSCLK_75 -#define Sys_clock (75 * 1000000) // 75 MHz -#endif - -/* - * This will ignore the standard MIPS timer interrupt handler - * that is passed in as *irq (=irq0 in ../kernel/time.c). - * We will do our own timer interrupt handling. - */ -void gt64120_time_init(void) -{ - extern irq_desc_t irq_desc[NR_IRQS]; - static struct irqaction timer; - - /* Disable timer first */ - GT_WRITE(GT_TC_CONTROL_OFS, 0); - /* Load timer value for 100 Hz */ - GT_WRITE(GT_TC3_OFS, Sys_clock / 100); - - /* - * Create the IRQ structure entry for the timer. Since we're too early - * in the boot process to use the "request_irq()" call, we'll hard-code - * the values to the correct interrupt line. - */ - timer.handler = >64120_irq; - timer.flags = SA_SHIRQ | SA_INTERRUPT; - timer.name = "timer"; - timer.dev_id = NULL; - timer.next = NULL; - timer.mask = 0; - irq_desc[TIMER].action = &timer; - - enable_irq(TIMER); - - /* Enable timer ints */ - GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); - /* clear Cause register first */ - GT_WRITE(GT_INTRCAUSE_OFS, 0x0); - /* Unmask timer int */ - GT_WRITE(GT_INTRMASK_OFS, 0x800); - /* Clear High int register */ - GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); - /* Mask All interrupts at High cause interrupt */ - GT_WRITE(GT_HINTRMASK_OFS, 0x0); -} - -void gt64120_irq_init(void) -{ -#if CURRENTLY_UNUSED - int i, j; - - /* Reset irq handlers pointers to NULL */ - for (i = 0; i < MAX_CAUSE_REGS; i++) { - for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) { - irq_handlers[i][j].next = NULL; - irq_handlers[i][j].sync = 0; - irq_handlers[i][j].routine = NULL; - irq_handlers[i][j].data = NULL; - } - } -#endif -} diff -urN linux-2.4.21/arch/mips/gt64120/common/pci.c linux-2.4.22/arch/mips/gt64120/common/pci.c --- linux-2.4.21/arch/mips/gt64120/common/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/common/pci.c 2003-08-25 04:44:39.000000000 -0700 @@ -12,9 +12,6 @@ * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc. * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com * - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -35,440 +32,23 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include #include #include #include -#include -#include -#include -#include #include -#include - -#ifdef CONFIG_PCI - #define SELF 0 /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. - */ - -#define MAX_PCI_DEVS 10 - -struct pci_device { - u32 slot; - u32 BARtype[6]; - u32 BARsize[6]; -}; - -static void __init scan_and_initialize_pci(void); -static u32 __init scan_pci_bus(struct pci_device *pci_devices); -static void __init allocate_pci_space(struct pci_device *pci_devices); - -/* - * The functions that actually read and write to the controller. - * - * Copied from or modified from Galileo Technology code. - */ -static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device); -static void pci0WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device); -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); - -static void pci0MapIOspace(unsigned int pci0IoBase, - unsigned int pci0IoLength); -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength); -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length); -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length); -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length); -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length); -static unsigned int pci0GetIOspaceBase(void); -static unsigned int pci0GetIOspaceSize(void); -static unsigned int pci0GetMemory0Base(void); -static unsigned int pci0GetMemory0Size(void); -static unsigned int pci0GetMemory1Base(void); -static unsigned int pci0GetMemory1Size(void); -static unsigned int pci1GetIOspaceBase(void); -static unsigned int pci1GetIOspaceSize(void); -static unsigned int pci1GetMemory0Base(void); -static unsigned int pci1GetMemory0Size(void); -static unsigned int pci1GetMemory1Base(void); -static unsigned int pci1GetMemory1Size(void); - - -/* Functions to implement "pci ops" */ -static int galileo_pcibios_read_config_word(struct pci_dev *dev, - int offset, u16 * val); -static int galileo_pcibios_read_config_byte(struct pci_dev *dev, - int offset, u8 * val); -static int galileo_pcibios_read_config_dword(struct pci_dev *dev, - int offset, u32 * val); -static int galileo_pcibios_write_config_byte(struct pci_dev *dev, - int offset, u8 val); -static int galileo_pcibios_write_config_word(struct pci_dev *dev, - int offset, u16 val); -static int galileo_pcibios_write_config_dword(struct pci_dev *dev, - int offset, u32 val); -static void galileo_pcibios_set_master(struct pci_dev *dev); - -/* - * General-purpose PCI functions. - */ - -/* - * pci0MapIOspace - Maps PCI0 IO space for the master. - * Inputs: base and length of pci0Io - */ - -static void pci0MapIOspace(unsigned int pci0IoBase, - unsigned int pci0IoLength) -{ - unsigned int pci0IoTop = - (unsigned int) (pci0IoBase + pci0IoLength); - - if (pci0IoLength == 0) - pci0IoTop++; - - pci0IoBase = (unsigned int) (pci0IoBase >> 21); - pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase); - GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop); -} - -/* - * pci1MapIOspace - Maps PCI1 IO space for the master. - * Inputs: base and length of pci1Io - */ - -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength) -{ - unsigned int pci1IoTop = - (unsigned int) (pci1IoBase + pci1IoLength); - - if (pci1IoLength == 0) - pci1IoTop++; - - pci1IoBase = (unsigned int) (pci1IoBase >> 21); - pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase); - GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop); -} - -/* - * pci0MapMemory0space - Maps PCI0 memory0 space for the master. - * Inputs: base and length of pci0Mem0 - */ - -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length) -{ - unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length; - - if (pci0Mem0Length == 0) - pci0Mem0Top++; - - pci0Mem0Base = pci0Mem0Base >> 21; - pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base); - GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top); -} - -/* - * pci1MapMemory0space - Maps PCI1 memory0 space for the master. - * Inputs: base and length of pci1Mem0 - */ - -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length) -{ - unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length; - - if (pci1Mem0Length == 0) - pci1Mem0Top++; - - pci1Mem0Base = pci1Mem0Base >> 21; - pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base); - GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top); -} - -/* - * pci0MapMemory1space - Maps PCI0 memory1 space for the master. - * Inputs: base and length of pci0Mem1 - */ - -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length) -{ - unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length; - - if (pci0Mem1Length == 0) - pci0Mem1Top++; - - pci0Mem1Base = pci0Mem1Base >> 21; - pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base); - GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top); - -} - -/* - * pci1MapMemory1space - Maps PCI1 memory1 space for the master. - * Inputs: base and length of pci1Mem1 - */ - -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length) -{ - unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length; - - if (pci1Mem1Length == 0) - pci1Mem1Top++; - - pci1Mem1Base = pci1Mem1Base >> 21; - pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base); - GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top); -} - -/* - * pci0GetIOspaceBase - Return PCI0 IO Base Address. - * Inputs: N/A - * Returns: PCI0 IO Base Address. - */ - -static unsigned int pci0GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetIOspaceSize - Return PCI0 IO Bar Size. - * Inputs: N/A - * Returns: PCI0 IO Bar Size. - */ - -static unsigned int pci0GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 0 Base Address. - */ - -static unsigned int pci0GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 0 Bar Size. - */ - -static unsigned int pci0GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M0HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 1 Base Address. - */ - -static unsigned int pci0GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 1 Bar Size. - */ - -static unsigned int pci0GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetIOspaceBase - Return PCI1 IO Base Address. - * Inputs: N/A - * Returns: PCI1 IO Base Address. - */ - -static unsigned int pci1GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetIOspaceSize - Return PCI1 IO Bar Size. - * Inputs: N/A - * Returns: PCI1 IO Bar Size. - */ - -static unsigned int pci1GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 0 Base Address. - */ - -static unsigned int pci1GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 0 Bar Size. - */ - -static unsigned int pci1GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 1 Base Address. - */ - -static unsigned int pci1GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 1 Bar Size. - */ - -static unsigned int pci1GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - - - -/* - * pci_range_ck - - * - * Check if the pci device that are trying to access does really exists - * on the evaluation board. - * - * Inputs : - * bus - bus number (0 for PCI 0 ; 1 for PCI 1) - * dev - number of device on the specific pci bus - * - * Outpus : - * 0 - if OK , 1 - if failure - */ -static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) -{ - /* - * We don't even pretend to handle other busses than bus 0 correctly. - * Accessing device 31 crashes the CP7000 for some reason. - */ - if ((bus == 0) && (dev != 31)) - return 0; - return -1; -} - -/* * pciXReadConfigReg - Read from a PCI configuration register - * - Make sure the GT is configured as a master before + * - Make sure the GT is configured as a master before * reading from another device on the PCI. * - The function takes care of Big/Little endian conversion. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI * spec) - * pciDevNum: The device number needs to be addressed. - * RETURNS: data , if the data == 0xffffffff check the master abort bit in the + * pciDevNum: The device number needs to be addressed. + * RETURNS: data , if the data == 0xffffffff check the master abort bit in the * cause register to make sure the data is valid * * Configuration Address 0xCF8: @@ -496,59 +76,21 @@ * check gives enough time for the address to stabilize, so the READ * can work. */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } + if (PCI_SLOT(device->devfn) == SELF) /* This board */ + return GT_READ(GT_PCI0_CFGDATA_OFS); + else /* PCI is little endian so swap the Data. */ + return __GT_READ(GT_PCI0_CFGDATA_OFS); } -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device) -{ - unsigned int DataForRegCf8; - unsigned int data; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* - * The casual observer might wonder why the READ is duplicated here, - * rather than immediately following the WRITE, and just have the - * swap in the "if". That's because there is a latency problem - * with trying to read immediately after setting up the address - * register. The "if" check gives enough time for the address - * to stabilize, so the READ can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { - GT_READ(GT_PCI1_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } -} - - - /* * pciXWriteConfigReg - Write to a PCI configuration register - * - Make sure the GT is configured as a master before + * - Make sure the GT is configured as a master before * writingto another device on the PCI. * - The function takes care of Big/Little endian conversion. * Inputs: unsigned int regOffset: The register offset as it apears in the - * GT spec + * GT spec * (or any other PCI device spec) - * pciDevNum: The device number needs to be addressed. + * pciDevNum: The device number needs to be addressed. * * Configuration Address 0xCF8: * @@ -566,356 +108,13 @@ (PCI_FUNC(device->devfn) << 8) | (offset & ~0x3)) | 0x80000000; GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data)); - } -} - -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data) -{ - unsigned int DataForRegCf8; - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* - * There is a latency problem - * with trying to read immediately after setting up the address - * register. The "if" check gives enough time for the address - * to stabilize, so the WRITE can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* - * when configurating our own PCI 1 L-unit the access is through - * the PCI 0 interface with reg number = reg number + 0x80 - */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + if (PCI_SLOT(device->devfn) == SELF) /* This board */ GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data)); - } -} - - -/* - * galileo_pcibios_(read/write)_config_(dword/word/byte) - - * - * reads/write a dword/word/byte register from the configuration space - * of a device. - * - * Inputs : - * bus - bus number - * dev - device number - * offset - register offset in the configuration space - * val - value to be written / read - * - * Outputs : - * PCIBIOS_SUCCESSFUL when operation was succesfull - * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous - * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned - */ - -static int galileo_pcibios_read_config_dword(struct pci_dev *device, - int offset, u32 * val) -{ - int dev, bus; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - *val = pci0ReadConfigReg(offset, device); - - /* This is so that the upper PCI layer will get the correct return value if - we're not attached to anything. */ - if ((offset == 0) && (*val == 0xffffffff)) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_word(struct pci_dev *device, - int offset, u16 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (bus == 0) - *val = - (unsigned short) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_byte(struct pci_dev *device, - int offset, u8 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - - if (bus == 0) - *val = - (unsigned char) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); - - /* - * This is so that the upper PCI layer will get the correct return - * value if we're not attached to anything. - */ - if ((offset == 0xe) && (*val == 0xff)) { - u32 MasterAbort; - GT_READ(GT_INTRCAUSE_OFS, &MasterAbort); - if (MasterAbort & 0x40000) { - GT_WRITE(GT_INTRCAUSE_OFS, - (MasterAbort & 0xfffbffff)); - return PCIBIOS_DEVICE_NOT_FOUND; - } - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_dword(struct pci_dev *device, - int offset, u32 val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - pci0WriteConfigReg(offset, device, val); -// if (bus == 1) pci1WriteConfigReg (offset,device,val); - - return PCIBIOS_SUCCESSFUL; + else /* configuration Transaction over the pci. */ + __GT_WRITE(GT_PCI0_CFGDATA_OFS, data); } - -static int galileo_pcibios_write_config_word(struct pci_dev *device, - int offset, u16 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffff0000) | (val & 0xffff); - if ((offset % 4) == 2) - tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_byte(struct pci_dev *device, - int offset, u8 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffffff00) | (val & 0xff); - if ((offset % 4) == 1) - tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8); - if ((offset % 4) == 2) - tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16); - if ((offset % 4) == 3) - tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - - return PCIBIOS_SUCCESSFUL; -} - -static void galileo_pcibios_set_master(struct pci_dev *dev) -{ - u16 cmd; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); -} - -/* Externally-expected functions. Do not change function names */ - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - u8 tmp1; - int idx; - struct resource *r; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of " - "resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - } - - /* - * Let's fix up the latency timer and cache line size here. Cache - * line size = 32 bytes / sizeof dword (4) = 8. - * Latency timer must be > 8. 32 is random but appears to work. - */ - galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); - if (tmp1 != 8) { - printk(KERN_WARNING "PCI setting cache line size to 8 from " - "%d\n", tmp1); - galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - 8); - } - galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); - if (tmp1 < 32) { - printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", - tmp1); - galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, - 32); - } - - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - return; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* - * Somebody might have asked allocation of a non-standard - * resource - */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -struct pci_ops galileo_pci_ops = { - galileo_pcibios_read_config_byte, - galileo_pcibios_read_config_word, - galileo_pcibios_read_config_dword, - galileo_pcibios_write_config_byte, - galileo_pcibios_write_config_word, - galileo_pcibios_write_config_dword -}; - struct pci_fixup pcibios_fixups[] = { {0} }; @@ -925,174 +124,7 @@ gt64120_board_pcibios_fixup_bus(c); } -/* - * This code was derived from Galileo Technology's example - * and significantly reworked. - * - * This is very simple. It does not scan multiple function devices. It does - * not scan behind bridges. Those would be simple to implement, but we don't - * currently need this. - */ - -static void __init scan_and_initialize_pci(void) -{ - struct pci_device pci_devices[MAX_PCI_DEVS]; - - if (scan_pci_bus(pci_devices)) { - allocate_pci_space(pci_devices); - } -} - -/* - * This is your basic PCI scan. It goes through each slot and checks to - * see if there's something that responds. If so, then get the size and - * type of each of the responding BARs. Save them for later. - */ - -static u32 __init scan_pci_bus(struct pci_device *pci_devices) -{ - u32 arrayCounter = 0; - u32 memType; - u32 memSize; - u32 pci_slot, bar; - u32 id; - u32 c18RegValue; - struct pci_dev device; - - /* - * According to PCI REV 2.1 MAX agents on the bus are 21. - * We don't bother scanning ourselves (slot 0). - */ - for (pci_slot = 1; pci_slot < 22; pci_slot++) { - - device.devfn = PCI_DEVFN(pci_slot, 0); - id = pci0ReadConfigReg(PCI_VENDOR_ID, &device); - - /* - * Check for a PCI Master Abort (nothing responds in the - * slot) - */ - GT_READ(GT_INTRCAUSE_OFS, &c18RegValue); - /* - * Clearing bit 18 of in the Cause Register 0xc18 by - * writting 0. - */ - GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff)); - if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { - pci_devices[arrayCounter].slot = pci_slot; - for (bar = 0; bar < 6; bar++) { - memType = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - pci_devices[arrayCounter].BARtype[bar] = - memType & 1; - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device, - 0xffffffff); - memSize = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - if (memType & 1) { /* IO space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffffc) + 1; - } else { /* memory space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffff0) + 1; - } - } /* BAR counter */ - - arrayCounter++; - } - /* found a device */ - } /* slot counter */ - - if (arrayCounter < MAX_PCI_DEVS) - pci_devices[arrayCounter].slot = -1; - - return arrayCounter; -} - -#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) -#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2)) - -/* - * This function goes through the list of devices and allocates the BARs in - * either IO or MEM space. It does it in order of size, which will limit the - * amount of fragmentation we have in the IO and MEM spaces. - */ - -static void __init allocate_pci_space(struct pci_device *pci_devices) -{ - u32 count, maxcount, bar; - u32 maxSize, maxDevice, maxBAR; - u32 alignto; - u32 base; - u32 pci0_mem_base = pci0GetMemory0Base(); - u32 pci0_io_base = pci0GetIOspaceBase(); - struct pci_dev device; - - /* How many PCI devices do we have? */ - maxcount = MAX_PCI_DEVS; - for (count = 0; count < MAX_PCI_DEVS; count++) { - if (pci_devices[count].slot == -1) { - maxcount = count; - break; - } - } - - do { - /* Find the largest size BAR we need to allocate */ - maxSize = 0; - for (count = 0; count < maxcount; count++) { - for (bar = 0; bar < 6; bar++) { - if (pci_devices[count].BARsize[bar] > - maxSize) { - maxSize = - pci_devices[count]. - BARsize[bar]; - maxDevice = count; - maxBAR = bar; - } - } - } - - /* - * We've found the largest BAR. Allocate it into IO or - * mem space. We don't idiot check the bases to make - * sure they haven't overflowed the current size for that - * aperture. - * Don't bother to enable the device's IO or MEM space here. - * That will be done in pci_enable_resources if the device is - * activated by a driver. - */ - if (maxSize) { - device.devfn = - PCI_DEVFN(pci_devices[maxDevice].slot, 0); - if (pci_devices[maxDevice].BARtype[maxBAR] == 1) { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_io_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base | 0x1); - pci0_io_base = base + alignto; - } else { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_mem_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base); - pci0_mem_base = base + alignto; - } - /* - * This entry is finished. Remove it from the list - * we'll scan. - */ - pci_devices[maxDevice].BARsize[maxBAR] = 0; - } - } while (maxSize); -} +extern struct pci_ops gt64120_pci_ops; void __init pcibios_init(void) { @@ -1101,8 +133,8 @@ controller.devfn = SELF; - GT_READ(GT_PCI0_CMD_OFS, &tmp); - GT_READ(GT_PCI0_BARE_OFS, &tmp); + tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */ + tmp = GT_READ(GT_PCI0_BARE_OFS); /* * You have to enable bus mastering to configure any other @@ -1112,34 +144,18 @@ tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; pci0WriteConfigReg(PCI_COMMAND, &controller, tmp); - /* This scans the PCI bus and sets up initial values. */ - scan_and_initialize_pci(); - /* * Reset PCI I/O and PCI MEM values to ones supported by EVM. */ - ioport_resource.start = GT_PCI_IO_BASE; - ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; - iomem_resource.start = GT_PCI_MEM_BASE; - iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1; + ioport_resource.start = GT_PCI_IO_BASE; + ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; + iomem_resource.start = GT_PCI_MEM_BASE; + iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1; - pci_scan_bus(0, &galileo_pci_ops, NULL); -} - -/* - * for parsing "pci=" kernel boot arguments. - */ -char *pcibios_setup(char *str) -{ - printk(KERN_INFO "rr: pcibios_setup\n"); - /* Nothing to do for now. */ - - return str; + pci_scan_bus(0, >64120_pci_ops, NULL); } unsigned __init int pcibios_assign_all_busses(void) { return 1; } - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/gt64120/common/time.c linux-2.4.22/arch/mips/gt64120/common/time.c --- linux-2.4.21/arch/mips/gt64120/common/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/common/time.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,98 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Galileo Technology chip interrupt handler + */ +#include +#include +#include +#include +#include +#include +#include + +/* + * These are interrupt handlers for the GT on-chip interrupts. They all come + * in to the MIPS on a single interrupt line, and have to be handled and ack'ed + * differently than other MIPS interrupts. + */ + +static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int irq_src, int_high_src, irq_src_mask, int_high_src_mask; + int handled = 0; + + irq_src = GT_READ(GT_INTRCAUSE_OFS); + irq_src_mask = GT_READ(GT_INTRMASK_OFS); + int_high_src = GT_READ(GT_HINTRCAUSE_OFS); + int_high_src_mask = GT_READ(GT_HINTRMASK_OFS); + irq_src = irq_src & irq_src_mask; + int_high_src = int_high_src & int_high_src_mask; + + if (irq_src & 0x00000800) { /* Check for timer interrupt */ + handled = 1; + irq_src &= ~0x00000800; + do_timer(regs); + } + + GT_WRITE(GT_INTRCAUSE_OFS, 0); + GT_WRITE(GT_HINTRCAUSE_OFS, 0); +} + +/* + * Initializes timer using galileo's built in timer. + */ +#ifdef CONFIG_SYSCLK_100 +#define Sys_clock (100 * 1000000) // 100 MHz +#endif +#ifdef CONFIG_SYSCLK_83 +#define Sys_clock (83.333 * 1000000) // 83.333 MHz +#endif +#ifdef CONFIG_SYSCLK_75 +#define Sys_clock (75 * 1000000) // 75 MHz +#endif + +/* + * This will ignore the standard MIPS timer interrupt handler that is passed in + * as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt + * handling. + */ +void gt64120_time_init(void) +{ + extern irq_desc_t irq_desc[NR_IRQS]; + static struct irqaction timer; + + /* Disable timer first */ + GT_WRITE(GT_TC_CONTROL_OFS, 0); + /* Load timer value for 100 Hz */ + GT_WRITE(GT_TC3_OFS, Sys_clock / 100); + + /* + * Create the IRQ structure entry for the timer. Since we're too early + * in the boot process to use the "request_irq()" call, we'll hard-code + * the values to the correct interrupt line. + */ + timer.handler = gt64120_irq; + timer.flags = SA_SHIRQ | SA_INTERRUPT; + timer.name = "timer"; + timer.dev_id = NULL; + timer.next = NULL; + timer.mask = 0; + irq_desc[GT_TIMER].action = &timer; + + enable_irq(GT_TIMER); + + /* Enable timer ints */ + GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); + /* clear Cause register first */ + GT_WRITE(GT_INTRCAUSE_OFS, 0x0); + /* Unmask timer int */ + GT_WRITE(GT_INTRMASK_OFS, 0x800); + /* Clear High int register */ + GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); + /* Mask All interrupts at High cause interrupt */ + GT_WRITE(GT_HINTRMASK_OFS, 0x0); +} diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/Makefile linux-2.4.22/arch/mips/gt64120/ev64120/Makefile --- linux-2.4.21/arch/mips/gt64120/ev64120/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/Makefile 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,25 @@ +# +# Copyright 2000 RidgeRun, Inc. +# Author: RidgeRun, Inc. +# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com +# +# Makefile for the Galileo EV64120 board. +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +all: ev64120.o int-handler.o + +O_TARGET := ev64120.o + +obj-y += serialGT.o int-handler.o promcon.o reset.o setup.o \ + irq.o +obj-$(CONFIG_PCI) += fixup-ev64120.o + +int-handler.o: int-handler.S + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/fixup-ev64120.c linux-2.4.22/arch/mips/gt64120/ev64120/fixup-ev64120.c --- linux-2.4.21/arch/mips/gt64120/ev64120/fixup-ev64120.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/fixup-ev64120.c 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,35 @@ +#include +#include + +int pci_range_ck(unsigned char bus, unsigned char dev) +{ + if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) + return 0; + + return -1; +} + +/* + * After detecting all agents over the PCI , this function is called + * in order to give an interrupt number for each PCI device starting + * from IRQ 20. It does also enables master for each device. + */ +void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + unsigned int irq = 20; + struct pci_bus *current_bus = bus; + struct pci_dev *dev; + struct list_head *devices_link; + + list_for_each(devices_link, &(current_bus->devices)) { + dev = pci_dev_b(devices_link); + if (dev != NULL) { + dev->irq = irq++; + + /* Assign an interrupt number for the device */ + pcibios_write_config_byte(bus, dev->devfn, + PCI_INTERRUPT_LINE, irq); + pcibios_set_master(dev); + } + } +} diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/int-handler.S linux-2.4.22/arch/mips/gt64120/ev64120/int-handler.S --- linux-2.4.21/arch/mips/gt64120/ev64120/int-handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/int-handler.S 2003-08-25 04:44:39.000000000 -0700 @@ -0,0 +1,113 @@ +/* + * int-handler.S + * + * Based on the cobalt handler. + */ +#include +#include +#include +#include +#include + +/* + * galileo_handle_int - + * We check for the timer first, then check PCI ints A and D. + * Then check for serial IRQ and fall through. + */ + .align 5 + .set reorder + .set noat + NESTED(galileo_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0,CP0_CAUSE + mfc0 t2,CP0_STATUS + + and t0,t2 + + andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ + bnez t1,ll_gt64120_irq + andi t1,t0,STATUSF_IP2 /* int0 hardware line */ + bnez t1,ll_pci_intA + andi t1,t0,STATUSF_IP5 /* int3 hardware line */ + bnez t1,ll_pci_intD + andi t1,t0,STATUSF_IP6 /* int4 hardware line */ + bnez t1,ll_serial_irq + andi t1,t0,STATUSF_IP7 /* compare int */ + bnez t1,ll_compare_irq + nop + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(galileo_handle_int) + + + .align 5 + .set reorder +ll_gt64120_irq: + li a0,4 + move a1,sp + jal do_IRQ + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_compare_irq: + li a0,7 + move a1,sp + jal do_IRQ + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_pci_intA: + move a0,sp + jal pci_intA + nop + j ret_from_irq + nop + +#if 0 + .align 5 + .set reorder +ll_pci_intB: + move a0,sp + jal pci_intB + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_pci_intC: + move a0,sp + jal pci_intC + nop + j ret_from_irq + nop +#endif + + .align 5 + .set reorder +ll_pci_intD: + move a0,sp + jal pci_intD + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_serial_irq: + li a0,6 + move a1,sp + jal do_IRQ + nop + j ret_from_irq + nop diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/irq.c linux-2.4.22/arch/mips/gt64120/ev64120/irq.c --- linux-2.4.21/arch/mips/gt64120/ev64120/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,145 @@ +/* + * BRIEF MODULE DESCRIPTION + * Code to handle irqs on GT64120A boards + * Derived from mips/orion and Cort + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +asmlinkage inline void pci_intA(struct pt_regs *regs) +{ + do_IRQ(GT_INTA, regs); +} + +asmlinkage inline void pci_intD(struct pt_regs *regs) +{ + do_IRQ(GT_INTD, regs); +} + +static void disable_ev64120_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 + clear_c0_status(9 << 10); + } else { + clear_c0_status(1 << (irq_nr + 8)); + } + local_irq_restore(flags); +} + +static void enable_ev64120_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + if (irq_nr >= 8) // All PCI interrupts are on line 5 or 2 + set_c0_status(9 << 10); + else + set_c0_status(1 << (irq_nr + 8)); + local_irq_restore(flags); +} + +static unsigned int startup_ev64120_irq(unsigned int irq) +{ + enable_ev64120_irq(irq); + return 0; /* Never anything pending */ +} + +#define shutdown_ev64120_irq disable_ev64120_irq +#define mask_and_ack_ev64120_irq disable_ev64120_irq + +static void end_ev64120_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_ev64120_irq(irq); +} + +static struct hw_interrupt_type ev64120_irq_type = { + .typename = "EV64120", + .startup = startup_ev64120_irq, + .shutdown = shutdown_ev64120_irq, + .enable = enable_ev64120_irq, + .disable = disable_ev64120_irq, + .ack = mask_and_ack_ev64120_irq, + .end = end_ev64120_irq, + .set_affinity = NULL +}; + +void gt64120_irq_setup(void) +{ + extern asmlinkage void galileo_handle_int(void); + + /* + * Clear all of the interrupts while we change the able around a bit. + */ + clear_c0_status(ST0_IM); + + /* Sets the exception_handler array. */ + set_except_vector(0, galileo_handle_int); + + cli(); + + /* + * Enable timer. Other interrupts will be enabled as they are + * registered. + */ + set_c0_status(IE_IRQ2); +} + +void __init init_IRQ(void) +{ + int i; + + /* Let's initialize our IRQ descriptors */ + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = 0; + irq_desc[i].handler = &no_irq_type; + irq_desc[i].action = NULL; + irq_desc[i].depth = 0; + irq_desc[i].lock = SPIN_LOCK_UNLOCKED; + } + + gt64120_irq_setup(); +} diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/promcon.c linux-2.4.22/arch/mips/gt64120/ev64120/promcon.c --- linux-2.4.21/arch/mips/gt64120/ev64120/promcon.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/promcon.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,58 @@ +/* + * Wrap-around code for a console using the + * SGI PROM io-routines. + * + * Copyright (c) 1999 Ulf Carlsson + * + * Derived from DECstation promcon.c + * Copyright (c) 1998 Harald Koerfgen + */ +#include +#include +#include +#include +#include +#include + +static void prom_console_write(struct console *co, const char *s, + unsigned count) +{ + extern int CONSOLE_CHANNEL; // The default serial port + unsigned i; + + for (i = 0; i < count; i++) { + if (*s == 10) + serial_putc(CONSOLE_CHANNEL, 13); + serial_putc(CONSOLE_CHANNEL, *s++); + } +} + +int prom_getchar(void) +{ + return 0; +} + +static kdev_t prom_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +static struct console sercons = { + .name = "ttyS", + .write = prom_console_write, + .device = prom_console_device, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ + +void gal_serial_console_init(void) +{ + // serial_init(); + //serial_set(115200); + + register_console(&sercons); +} diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/reset.c linux-2.4.22/arch/mips/gt64120/ev64120/reset.c --- linux-2.4.21/arch/mips/gt64120/ev64120/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,45 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997 Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include + +void galileo_machine_restart(char *command) +{ + *(volatile char *) 0xbc000000 = 0x0f; + /* + * Ouch, we're still alive ... This time we take the silver bullet ... + * ... and find that we leave the hardware in a state in which the + * kernel in the flush locks up somewhen during of after the PCI + * detection stuff. + */ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); +} + +void galileo_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); + +} + +void galileo_machine_power_off(void) +{ + galileo_machine_halt(); +} diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/serialGT.c linux-2.4.22/arch/mips/gt64120/ev64120/serialGT.c --- linux-2.4.21/arch/mips/gt64120/ev64120/serialGT.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/serialGT.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,212 @@ +/* + * serialGT.c + * + * BRIEF MODULE DESCRIPTION + * Low Level Serial Port control for use + * with the Galileo EVB64120A MIPS eval board and + * its on board two channel 16552 Uart. + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + */ + +// Note: +// Serial CHANNELS - 0 is the bottom connector of evb64120A. +// (The one that maps to the "B" channel of the +// board's uart) +// 1 is the top connector of evb64120A. +// (The one that maps to the "A" channel of the +// board's uart) +int DEBUG_CHANNEL = 0; // See Note Above +int CONSOLE_CHANNEL = 1; // See Note Above + +#define DUART 0xBD000000 /* Base address of Uart. */ +#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA + register set of the 16552 Uart device. + DUART+0 gets you to the ChanB register set. + */ +#define DUART_DELTA 0x4 +#define FIFO_ENABLE 0x07 +#define INT_ENABLE 0x04 /* default interrupt mask */ + +#define RBR 0x00 +#define THR 0x00 +#define DLL 0x00 +#define IER 0x01 +#define DLM 0x01 +#define IIR 0x02 +#define FCR 0x02 +#define LCR 0x03 +#define MCR 0x04 +#define LSR 0x05 +#define MSR 0x06 +#define SCR 0x07 + +#define LCR_DLAB 0x80 +#define XTAL 1843200 +#define LSR_THRE 0x20 +#define LSR_BI 0x10 +#define LSR_DR 0x01 +#define MCR_LOOP 0x10 +#define ACCESS_DELAY 0x10000 + +/****************************** + Routine: + Description: + ******************************/ +int inreg(int channel, int reg) +{ + int val; + val = + *((volatile unsigned char *) DUART + + (channel * CHANNELOFFSET) + (reg * DUART_DELTA)); + return val; +} + +/****************************** + Routine: + Description: + ******************************/ +void outreg(int channel, int reg, unsigned char val) +{ + *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET) + + (reg * DUART_DELTA)) = val; +} + +/****************************** + Routine: + Description: + Initialize the device driver. + ******************************/ +void serial_init(int channel) +{ + /* + * Configure active port, (CHANNELOFFSET already set.) + * + * Set 8 bits, 1 stop bit, no parity. + * + * LCR<7> 0 divisor latch access bit + * LCR<6> 0 break control (1=send break) + * LCR<5> 0 stick parity (0=space, 1=mark) + * LCR<4> 0 parity even (0=odd, 1=even) + * LCR<3> 0 parity enable (1=enabled) + * LCR<2> 0 # stop bits (0=1, 1=1.5) + * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8) + */ + outreg(channel, LCR, 0x3); + + outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */ + + outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */ +} + +/****************************** + Routine: + Description: + Set the baud rate. + ******************************/ +void serial_set(int channel, unsigned long baud) +{ + unsigned char sav_lcr; + + /* + * Enable access to the divisor latches by setting DLAB in LCR. + * + */ + sav_lcr = inreg(channel, LCR); + +#if 0 + /* + * Set baud rate + */ + outreg(channel, LCR, LCR_DLAB | sav_lcr); + // outreg(DLL,(XTAL/(16*2*(baud))-2)); + outreg(channel, DLL, XTAL / (16 * baud)); + // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8); + outreg(channel, DLM, (XTAL / (16 * baud)) >> 8); +#else + /* + * Note: Set baud rate, hardcoded here for rate of 115200 + * since became unsure of above "buad rate" algorithm (??). + */ + outreg(channel, LCR, 0x83); + outreg(channel, DLM, 0x00); // See note above + outreg(channel, DLL, 0x02); // See note above. + outreg(channel, LCR, 0x03); +#endif + + /* + * Restore line control register + */ + outreg(channel, LCR, sav_lcr); +} + + +/****************************** + Routine: + Description: + Transmit a character. + ******************************/ +void serial_putc(int channel, int c) +{ + while ((inreg(channel, LSR) & LSR_THRE) == 0); + outreg(channel, THR, c); +} + +/****************************** + Routine: + Description: + Read a received character if one is + available. Return -1 otherwise. + ******************************/ +int serial_getc(int channel) +{ + if (inreg(channel, LSR) & LSR_DR) { + return inreg(channel, RBR); + } + return -1; +} + +/****************************** + Routine: + Description: + Used by embedded gdb client. (example; gdb-stub.c) + ******************************/ +char getDebugChar() +{ + int val; + while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in. + return (char) val; +} + +/****************************** + Routine: + Description: + Used by embedded gdb target. (example; gdb-stub.c) + ******************************/ +void putDebugChar(char c) +{ + serial_putc(DEBUG_CHANNEL, (int) c); +} diff -urN linux-2.4.21/arch/mips/gt64120/ev64120/setup.c linux-2.4.22/arch/mips/gt64120/ev64120/setup.c --- linux-2.4.21/arch/mips/gt64120/ev64120/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/ev64120/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long gt64120_base = KSEG1ADDR(0x14000000); + +extern struct rtc_ops no_rtc_ops; + +/* These functions are used for rebooting or halting the machine*/ +extern void galileo_machine_restart(char *command); +extern void galileo_machine_halt(void); +extern void galileo_machine_power_off(void); +/* + *This structure holds pointers to the pci configuration space accesses + *and interrupts allocating routine for device over the PCI + */ +extern struct pci_ops galileo_pci_ops; + +char arcs_cmdline[CL_SIZE] = { + "console=ttyS0,115200 " + "root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal " + "ip=192.168.1.211:192.168.1.1:::gt::" +}; + +void prom_free_prom_memory(void) +{ +} + +static unsigned char galileo_rtc_read_data(unsigned long addr) +{ + return 0; +} + +static void galileo_rtc_write_data(unsigned char data, unsigned long addr) +{ +} + +static int galileo_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops galileo_rtc_ops = { + &galileo_rtc_read_data, + &galileo_rtc_write_data, + &galileo_rtc_bcd_mode +}; + + +/* + * Initializes basic routines and structures pointers, memory size (as + * given by the bios and saves the command line. + */ +extern void gt64120_time_init(void); + +void ev64120_setup(void) +{ + _machine_restart = galileo_machine_restart; + _machine_halt = galileo_machine_halt; + _machine_power_off = galileo_machine_power_off; + + rtc_ops = &galileo_rtc_ops; + + board_time_init = gt64120_time_init; + set_io_port_base(KSEG1); +} + +const char *get_system_type(void) +{ + return "Galileo EV64120A"; +} + +/* + * SetUpBootInfo - + * + * This function is called at very first stages of kernel startup. + * It specifies for the kernel the evaluation board that the linux + * is running on. Then it saves the eprom parameters that holds the + * command line, memory size etc... + * + * Inputs : + * argc - nothing + * argv - holds a pointer to the eprom parameters + * envp - nothing + */ + +void SetUpBootInfo(int argc, char **argv, char **envp) +{ + mips_machgroup = MACH_GROUP_GALILEO; + mips_machtype = MACH_EV64120A; +} + +void __init prom_init(int a, char **b, char **c, int *d) +{ + mips_machgroup = MACH_GROUP_GALILEO; + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/Makefile linux-2.4.22/arch/mips/gt64120/momenco_ocelot/Makefile --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/Makefile 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,15 +6,13 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= momenco_ocelot.o -obj-y += int-handler.o irq.o pci.o prom.o reset.o setup.o +obj-y += int-handler.o irq.o prom.o reset.o setup.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_KGDB) += dbg_io.o +obj-$(CONFIG_PCI) += fixup-ocelot.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/dbg_io.c linux-2.4.22/arch/mips/gt64120/momenco_ocelot/dbg_io.c --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/dbg_io.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/dbg_io.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ #include -#if defined(CONFIG_REMOTE_DEBUG) +#if defined(CONFIG_KGDB) #include /* For the serial port location and base baud */ diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c linux-2.4.22/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,87 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/gt64120/momenco_ocelot/pci.c + * Board-specific PCI routines for gt64120 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include + +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* + * We don't even pretend to handle other busses than bus 0 correctly. + * Accessing device 31 crashes the CP7000 for some reason. + */ + if ((bus == 0) && (dev != 31)) + return 0; + + return -1; +} + + +void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if (PCI_SLOT(devices->devfn) == 1) { + /* + * Slot 1 is primary ether port, i82559 + * we double-check against that assumption + */ + if ((devices->vendor != 0x8086) || + (devices->device != 0x1209) ) { + panic("gt64120_board_pcibios_fixup_bus: found " + "unexpected PCI device in slot 1."); + } + devices->irq = 2; /* irq_nr is 2 for INT0 */ + } else if (PCI_SLOT(devices->devfn) == 2) { + /* + * Slot 2 is secondary ether port, i21143 + * we double-check against that assumption + */ + if ((devices->vendor != 0x1011) || + (devices->device != 0x19) ) { + panic("gt64120_board_pcibios_fixup_bus: " + "found unexpected PCI device in slot 2."); + } + devices->irq = 3; /* irq_nr is 3 for INT1 */ + } else if (PCI_SLOT(devices->devfn) == 4) { + /* PMC Slot 1 */ + devices->irq = 8; /* irq_nr is 8 for INT6 */ + } else if (PCI_SLOT(devices->devfn) == 5) { + /* PMC Slot 1 */ + devices->irq = 9; /* irq_nr is 9 for INT7 */ + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); + + /* enable master */ + bus->ops->read_word(devices, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write_word(devices, PCI_COMMAND, cmd); + } +} diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/int-handler.S linux-2.4.22/arch/mips/gt64120/momenco_ocelot/int-handler.S --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/int-handler.S 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/int-handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -9,7 +9,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include #include #include #include @@ -26,11 +25,11 @@ SAVE_ALL CLI .set at - mfc0 t0, CP0_CAUSE + mfc0 t0, CP0_CAUSE mfc0 t2, CP0_STATUS and t0, t2 - + andi t1, t0, STATUSF_IP2 /* int0 hardware line */ bnez t1, ll_pri_enet_irq andi t1, t0, STATUSF_IP3 /* int1 hardware line */ @@ -45,7 +44,7 @@ bnez t1, ll_cputimer_irq /* now look at the extended interrupts */ - mfc0 t0, CP0_CAUSE + mfc0 t0, CP0_CAUSE cfc0 t1, CP0_S1_INTCONTROL /* shift the mask 8 bits left to line up the bits */ @@ -88,7 +87,7 @@ move a1, sp jal do_IRQ j ret_from_irq - + ll_cpci_irq: li a0, 5 move a1, sp @@ -106,7 +105,7 @@ move a1, sp jal do_IRQ j ret_from_irq - + ll_pmc1_irq: li a0, 8 move a1, sp diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/irq.c linux-2.4.22/arch/mips/gt64120/momenco_ocelot/irq.c --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -28,6 +28,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. * */ +#include #include #include #include @@ -60,18 +61,18 @@ /* do the low 8 bits first */ clr_mask = 0xff & clr_mask_in; set_mask = 0xff & set_mask_in; - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); /* do the high 8 bits */ clr_mask = 0xff & (clr_mask_in >> 8); set_mask = 0xff & (set_mask_in >> 8); - status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); + status = read_c0_intcontrol(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); + write_c0_intcontrol(status); } static inline void mask_irq(unsigned int irq) @@ -135,7 +136,6 @@ extern asmlinkage void ocelot_handle_int(void); -extern void gt64120_irq_init(void); void __init init_IRQ(void) { @@ -144,7 +144,7 @@ /* * Clear all of the interrupts while we change the able around a bit. */ - clear_cp0_status(ST0_IM); + clear_c0_status(ST0_IM); __cli(); /* Sets the first-level interrupt dispatcher. */ @@ -158,9 +158,7 @@ irq_desc[i].handler = &cp7000_hpcdma_irq_type; } - gt64120_irq_init(); - -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("start kgdb ...\n"); set_debug_traps(); breakpoint(); /* you may move this line to whereever you want :-) */ diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/pci.c linux-2.4.22/arch/mips/gt64120/momenco_ocelot/pci.c --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/pci.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,75 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/gt64120/momenco_ocelot/pci.c - * Board-specific PCI routines for gt64120 controller. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include - - -void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if (PCI_SLOT(devices->devfn) == 1) { - /* - * Slot 1 is primary ether port, i82559 - * we double-check against that assumption - */ - if ((devices->vendor != 0x8086) || - (devices->device != 0x1209) ) { - panic("gt64120_board_pcibios_fixup_bus: found " - "unexpected PCI device in slot 1."); - } - devices->irq = 2; /* irq_nr is 2 for INT0 */ - } else if (PCI_SLOT(devices->devfn) == 2) { - /* - * Slot 2 is secondary ether port, i21143 - * we double-check against that assumption - */ - if ((devices->vendor != 0x1011) || - (devices->device != 0x19) ) { - panic("galileo_pcibios_fixup_bus: " - "found unexpected PCI device in slot 2."); - } - devices->irq = 3; /* irq_nr is 3 for INT1 */ - } else if (PCI_SLOT(devices->devfn) == 4) { - /* PMC Slot 1 */ - devices->irq = 8; /* irq_nr is 8 for INT6 */ - } else if (PCI_SLOT(devices->devfn) == 5) { - /* PMC Slot 1 */ - devices->irq = 9; /* irq_nr is 9 for INT7 */ - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); - - /* enable master */ - bus->ops->read_word(devices, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write_word(devices, PCI_COMMAND, cmd); - } -} diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/prom.c linux-2.4.22/arch/mips/gt64120/momenco_ocelot/prom.c --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -15,34 +15,35 @@ #include #include -#define PLD_BASE 0xbc000000 - -#define REV 0x0 /* Board Assembly Revision */ -#define PLD1ID 0x1 /* PLD 1 ID */ -#define PLD2ID 0x2 /* PLD 2 ID */ -#define RESET_STAT 0x3 /* Reset Status Register */ -#define BOARD_STAT 0x4 /* Board Status Register */ -#define CPCI_ID 0x5 /* Compact PCI ID Register */ -#define CONTROL 0x8 /* Control Register */ -#define CPU_EEPROM 0x9 /* CPU Configuration EEPROM Register */ -#define INTMASK 0xA /* Interrupt Mask Register */ -#define INTSTAT 0xB /* Interrupt Status Register */ -#define INTSET 0xC /* Interrupt Set Register */ -#define INTCLR 0xD /* Interrupt Clear Register */ - -#define PLD_REG(x) ((uint8_t*)(PLD_BASE+(x))) +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; +struct callvectors* debug_vectors; char arcs_cmdline[CL_SIZE]; +extern unsigned long gt64120_base; + const char *get_system_type(void) { return "Momentum Ocelot"; } /* [jsun@junsun.net] PMON passes arguments in C main() style */ -void __init prom_init(int argc, const char **arg) +void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) { int i; + uint32_t tmp; + + /* save the PROM vectors for debugging use */ + debug_vectors = cv; /* arg[0] is "g", the rest is boot parameters */ arcs_cmdline[0] = '\0'; @@ -57,9 +58,16 @@ mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT; - /* turn off the Bit Error LED, which comes on automatically - * at power-up reset */ - *PLD_REG(INTCLR) = 0x80; + while (*env) { + if (strncmp("gtbase", *env, 6) == 0) { + gt64120_base = simple_strtol(*env + strlen("gtbase="), + NULL, 16); + break; + } + *env++; + } + + debug_vectors->printf("Booting Linux kernel...\n"); /* All the boards have at least 64MiB. If there's more, we detect and register it later */ diff -urN linux-2.4.21/arch/mips/gt64120/momenco_ocelot/setup.c linux-2.4.22/arch/mips/gt64120/momenco_ocelot/setup.c --- linux-2.4.21/arch/mips/gt64120/momenco_ocelot/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/gt64120/momenco_ocelot/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -83,25 +84,9 @@ static void __init setup_l3cache(unsigned long size); -void __init momenco_ocelot_setup(void) +/* setup code for a handoff from a version 1 PMON 2000 PROM */ +void PMON_v1_setup() { - void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); - unsigned int tmpword; - - board_time_init = gt64120_time_init; - - _machine_restart = momenco_ocelot_restart; - _machine_halt = momenco_ocelot_halt; - _machine_power_off = momenco_ocelot_power_off; - - /* - * initrd_start = (ulong)ocelot_initrd_start; - * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; - * initrd_below_start_ok = 1; - */ - rtc_ops = &no_rtc_ops; - - /* A wired TLB entry for the GT64120A and the serial port. The GT64120A is going to be hit on every IRQ anyway - there's absolutely no point in letting it be a random TLB entry, as @@ -122,12 +107,11 @@ Ocelot PLD (CS0) 0x2c000000 0xe0020000 NVRAM 0x2c800000 0xe0030000 */ - - add_temporary_entry(ENTRYLO(0x2C000000), ENTRYLO(0x2d000000), 0xe0020000, PM_64K); + add_temporary_entry(ENTRYLO(0x2C000000), ENTRYLO(0x2d000000), 0xe0020000, PM_64K); /* Relocate the CS3/BootCS region */ - GT_WRITE( GT_CS3BOOTLD_OFS, 0x2f000000 >> 21); + GT_WRITE(GT_CS3BOOTLD_OFS, 0x2f000000 >> 21); /* Relocate CS[012] */ GT_WRITE(GT_CS20LD_OFS, 0x2c000000 >> 21); @@ -142,19 +126,75 @@ GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000000); GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000024); GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000001); +} - /* Relocate PCI0 I/O and Mem0 */ - GT_WRITE(GT_PCI0IOLD_OFS, 0x20000000 >> 21); - GT_WRITE(GT_PCI0M0LD_OFS, 0x22000000 >> 21); +/* setup code for a handoff from a version 2 PMON 2000 PROM */ +void PMON_v2_setup() +{ + /* A wired TLB entry for the GT64120A and the serial port. The + GT64120A is going to be hit on every IRQ anyway - there's + absolutely no point in letting it be a random TLB entry, as + it'll just cause needless churning of the TLB. And we use + the other half for the serial port, which is just a PITA + otherwise :) - /* Relocate PCI0 Mem1 */ - GT_WRITE(GT_PCI0M1LD_OFS, 0x36000000 >> 21); + Device Physical Virtual + GT64120 Internal Regs 0xf4000000 0xe0000000 + UARTs (CS2) 0xfd000000 0xe0001000 + */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xfD000000), 0xe0000000, PM_4K); + + /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM + in the CS[012] region. We can't use ioremap() yet. The NVRAM + is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions. + + Ocelot PLD (CS0) 0xfc000000 0xe0020000 + NVRAM 0xfc800000 0xe0030000 + */ + add_temporary_entry(ENTRYLO(0xfC000000), ENTRYLO(0xfd000000), 0xe0020000, PM_64K); + + gt64120_base = 0xe0000000; +} + +void __init momenco_ocelot_setup(void) +{ + void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); + unsigned int tmpword; + + board_time_init = gt64120_time_init; + + _machine_restart = momenco_ocelot_restart; + _machine_halt = momenco_ocelot_halt; + _machine_power_off = momenco_ocelot_power_off; + + /* + * initrd_start = (ulong)ocelot_initrd_start; + * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; + * initrd_below_start_ok = 1; + */ + rtc_ops = &no_rtc_ops; + + /* do handoff reconfiguration */ + if (gt64120_base == KSEG1ADDR(GT_DEF_BASE)) + PMON_v1_setup(); + else + PMON_v2_setup(); + + /* Turn off the Bit-Error LED */ + OCELOT_PLD_WRITE(0x80, INTCLR); /* Relocate all the PCI1 stuff, not that we use it */ GT_WRITE(GT_PCI1IOLD_OFS, 0x30000000 >> 21); GT_WRITE(GT_PCI1M0LD_OFS, 0x32000000 >> 21); GT_WRITE(GT_PCI1M1LD_OFS, 0x34000000 >> 21); + /* Relocate PCI0 I/O and Mem0 */ + GT_WRITE(GT_PCI0IOLD_OFS, 0x20000000 >> 21); + GT_WRITE(GT_PCI0M0LD_OFS, 0x22000000 >> 21); + + /* Relocate PCI0 Mem1 */ + GT_WRITE(GT_PCI0M1LD_OFS, 0x36000000 >> 21); + /* For the initial programming, we assume 512MB configuration */ /* Relocate the CPU's view of the RAM... */ GT_WRITE(GT_SCS10LD_OFS, 0); @@ -283,19 +323,19 @@ { int register i; unsigned long tmp; - + printk("Enabling L3 cache..."); /* Enable the L3 cache in the GT64120A's CPU Configuration register */ - GT_READ(0, &tmp); + tmp = GT_READ(0); GT_WRITE(0, tmp | (1<<14)); /* Enable the L3 cache in the CPU */ - set_cp0_config(1<<12 /* CONF_TE */); + set_c0_config(1<<12 /* CONF_TE */); /* Clear the cache */ - set_taglo(0); - set_taghi(0); + write_c0_taglo(0); + write_c0_taghi(0); for (i=0; i < size; i+= 4096) { __asm__ __volatile__ ( diff -urN linux-2.4.21/arch/mips/hp-lj/Makefile linux-2.4.22/arch/mips/hp-lj/Makefile --- linux-2.4.21/arch/mips/hp-lj/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -17,7 +17,7 @@ obj-y := init.o setup.o irq.o int-handler.o pci.o utils.o asic.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o +obj-$(CONFIG_KGDB) += gdb_hook.o obj-$(CONFIG_DIRECT_PRINTK) += gdb_hook.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o diff -urN linux-2.4.21/arch/mips/hp-lj/asic.c linux-2.4.22/arch/mips/hp-lj/asic.c --- linux-2.4.21/arch/mips/hp-lj/asic.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/asic.c 2003-08-25 04:44:40.000000000 -0700 @@ -20,7 +20,7 @@ const char* const GetAsicName(void) { - static const char* const Names[] = + static const char* const Names[] = { "Illegal", "Unknown", "Andros", "Harmony" }; return Names[(int)GetAsicId()]; diff -urN linux-2.4.21/arch/mips/hp-lj/gdb_hook.c linux-2.4.22/arch/mips/hp-lj/gdb_hook.c --- linux-2.4.21/arch/mips/hp-lj/gdb_hook.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/gdb_hook.c 2003-08-25 04:44:40.000000000 -0700 @@ -77,7 +77,7 @@ while (((SERIAL_REG(HPSR_TX_STAT_OFFSET) & HPSR_TX_STAT_READY) == 0)) ; SERIAL_REG(HPSR_DATA_OFFSET) = (unsigned int) c; - } + } return 1; } @@ -87,7 +87,7 @@ while (!(((H_HPSR_STAT) & H_SER_STAT_RX_EMPTY) == 0)); return H_HPSR_DATA_RX; - + } else if (GetAsicId() == AndrosAsic) { while ((SERIAL_REG(HPSR_RX_STAT_OFFSET) & HPSR_RX_DATA_AVAIL) == 0) ; diff -urN linux-2.4.21/arch/mips/hp-lj/init.c linux-2.4.22/arch/mips/hp-lj/init.c --- linux-2.4.21/arch/mips/hp-lj/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * init.c: PROM library initialisation code. * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ #include @@ -35,7 +35,7 @@ add_memory_region(mem_size,reserve_size, BOOT_MEM_RESERVED); printk("Main Memory: %ld bytes\n", mem_size); - printk("Reserved Memory: %ld bytes at 0x%08x\n", + printk("Reserved Memory: %ld bytes at 0x%08x\n", get_reserved_buffer_size(), (ulong)get_reserved_buffer()); printk("Detected %s ASIC\n", GetAsicName()); diff -urN linux-2.4.21/arch/mips/hp-lj/int-handler.S linux-2.4.22/arch/mips/hp-lj/int-handler.S --- linux-2.4.21/arch/mips/hp-lj/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/int-handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -64,7 +64,7 @@ la a1, ret_from_irq jr a1 -*/ +*/ 3: j spurious_interrupt END(hpIRQ) diff -urN linux-2.4.21/arch/mips/hp-lj/irq.c linux-2.4.22/arch/mips/hp-lj/irq.c --- linux-2.4.21/arch/mips/hp-lj/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,8 +25,8 @@ mips_cpu_irq_init(0); set_except_vector(0, hpIRQ); -#ifdef CONFIG_REMOTE_DEBUG - { +#ifdef CONFIG_KGDB + { extern void breakpoint(void); extern int remote_debug; @@ -36,6 +36,6 @@ } } #endif - + } diff -urN linux-2.4.21/arch/mips/hp-lj/pci-dma.c linux-2.4.22/arch/mips/hp-lj/pci-dma.c --- linux-2.4.21/arch/mips/hp-lj/pci-dma.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/pci-dma.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2000 Ani Joshi - * - * - * Dynamic DMA mapping support. - * - * swiped from i386, and cloned for MIPS by Geert. - * - */ - -#include -#include -#include -#include -#include - -void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC; - - if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) - gfp |= GFP_DMA; - ret = (void *)__get_free_pages(gfp, get_order(size)); - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - - - // REVISIT this needs reviewal as mentioned in bug report - // currently we bump kseg0 allocates to kseg1 uncacheable space - - if ((((unsigned int) ret) & 0xe0000000) == 0x80000000) { - //flush the cache to eliminate coherency problems - // and assure dirty lines won't later get written over any dma, etc. - flush_cache_all(); - ret = (void*)((unsigned int)ret | 0x20000000); - } - - - } - return ret; -} - - -void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} - diff -urN linux-2.4.21/arch/mips/hp-lj/pci.c linux-2.4.22/arch/mips/hp-lj/pci.c --- linux-2.4.21/arch/mips/hp-lj/pci.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -77,7 +77,7 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; *pci_config_address_reg = cfgaddr(dev, where); - *(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = + *(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = le16_to_cpu(val); //printk("pci_write_word 0x%x = 0x%x\n", where, val); return PCIBIOS_SUCCESSFUL; @@ -158,9 +158,9 @@ case AndrosAsic: pci_regs_base_offset = 0xbff80000; break; case HarmonyAsic: pci_regs_base_offset = 0xbff70000; break; default: - printk("ERROR: PCI does not support %s Asic\n", GetAsicName()); + printk("ERROR: PCI does not support %s Asic\n", GetAsicName()); while(1); - break; + break; } // set bus stat/command reg @@ -176,7 +176,7 @@ // KLUDGE (mips_io_port_base is screwed up, we've got to work around it here) // by letting both low (illegal) and high (legal) addresses appear in pci io space - ioport_resource.start = 0x0; + ioport_resource.start = 0x0; set_io_port_base(IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET); @@ -185,7 +185,7 @@ // except that the range is outside user space // parameters: lo0, lo1, hi, pagemask // lo indicates physical page, hi indicates virtual address - add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17, + add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17, ((IO_MEM_LOGICAL_START + (16 * ONE_MEG)) >> 6) | 0x17, 0xee000000, PM_16M); @@ -203,7 +203,7 @@ int bases; printk("adjusting pci device: %s\n", dev->name); - + switch (dev->hdr_type) { case PCI_HEADER_TYPE_NORMAL: bases = 6; break; case PCI_HEADER_TYPE_BRIDGE: bases = 2; break; @@ -212,12 +212,12 @@ } for (pos=0; pos < bases; pos++) { struct resource* res = &dev->resource[pos]; - if (res->start >= IO_MEM_LOGICAL_START && + if (res->start >= IO_MEM_LOGICAL_START && res->end <= IO_MEM_LOGICAL_END) { res->start += IO_MEM_VIRTUAL_OFFSET; res->end += IO_MEM_VIRTUAL_OFFSET; } - if (res->start >= IO_PORT_LOGICAL_START && + if (res->start >= IO_PORT_LOGICAL_START && res->end <= IO_PORT_LOGICAL_END) { res->start += IO_PORT_VIRTUAL_OFFSET; res->end += IO_PORT_VIRTUAL_OFFSET; diff -urN linux-2.4.21/arch/mips/hp-lj/setup.c linux-2.4.22/arch/mips/hp-lj/setup.c --- linux-2.4.21/arch/mips/hp-lj/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -20,7 +20,7 @@ #include #include "utils.h" -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int remote_debug = 0; #endif @@ -80,8 +80,8 @@ irq->handler = andros_timer_interrupt; irq->flags |= SA_INTERRUPT | SA_SHIRQ; printk("setting up timer in hp_time_init\n"); - setup_irq(ASIC_IRQ_NUMBER, irq); - + setup_irq(ASIC_IRQ_NUMBER, irq); + // enable timer interrupt *((volatile unsigned int*)0xbfea0000) = 0x20; @@ -98,7 +98,7 @@ *((volatile unsigned int*)0xbff610a0) |= 1; // turn on timer0 - } else if (GetAsicId() == UnknownAsic) + } else if (GetAsicId() == UnknownAsic) printk("Unknown asic in hp_time_init()\n"); else printk("Unsupported asic in hp_time_init()\n"); @@ -107,7 +107,7 @@ static void hplj_restart(void) { - if (GetAsicId() == AndrosAsic) + if (GetAsicId() == AndrosAsic) *((volatile unsigned int *) 0xbfe900c0) = 0; @@ -144,7 +144,7 @@ board_timer_setup = hp_time_init; -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB { extern char CommandLine[]; remote_debug = (strstr(CommandLine, "kgdb") != NULL); diff -urN linux-2.4.21/arch/mips/hp-lj/utils.c linux-2.4.22/arch/mips/hp-lj/utils.c --- linux-2.4.21/arch/mips/hp-lj/utils.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/hp-lj/utils.c 2003-08-25 04:44:40.000000000 -0700 @@ -20,11 +20,11 @@ unsigned long cfg[10],i,total_mem=0; - for(i=0;i<10;i++) - cfg[i] = *miu_chan_cfg(i); + for(i=0;i<10;i++) + cfg[i] = *miu_chan_cfg(i); for(i=0;i<10;i++){ - if(cfg[i]==0x1fc160c2) continue; // skip empties + if(cfg[i]==0x1fc160c2) continue; // skip empties if( ( (cfg[i]>>12) & 0xf ) <= 0xb ) continue; // skip roms total_mem += mbsize[(cfg[i]>>16)&0x7] *1024*1024; } @@ -43,19 +43,19 @@ #define MIN_GEN_MEM (4 << 20) - -void reserve_buffer(const char* cl, ulong base_mem) + +void reserve_buffer(const char* cl, ulong base_mem) { char* pos = strstr(cl, "reserved_buffer="); if (pos) { - buffer_size = simple_strtol(pos+strlen("reserved_buffer="), + buffer_size = simple_strtol(pos+strlen("reserved_buffer="), 0, 10); buffer_size <<= 20; if (buffer_size + MIN_GEN_MEM > base_mem) buffer_size = base_mem - MIN_GEN_MEM; - if (buffer_size > 0) + if (buffer_size > 0) buffer_ptr = (ulong*)(base_mem - buffer_size); - else + else buffer_size = 0; } } diff -urN linux-2.4.21/arch/mips/ite-boards/generic/Makefile linux-2.4.22/arch/mips/ite-boards/generic/Makefile --- linux-2.4.21/arch/mips/ite-boards/generic/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -10,19 +10,16 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true all: it8172.o O_TARGET := it8172.o -obj-y := it8172_rtc.o it8172_setup.o irq.o int-handler.o pmon_prom.o time.o lpc.o puts.o reset.o +obj-y := it8172_setup.o irq.o int-handler.o pmon_prom.o time.o lpc.o puts.o reset.o obj-$(CONFIG_PCI) += it8172_pci.o -obj-$(CONFIG_IT8172_CIR) += it8172_cir.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_IT8172_CIR) += it8172_cir.o +obj-$(CONFIG_KGDB) += dbg_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/ite-boards/generic/dbg_io.c linux-2.4.22/arch/mips/ite-boards/generic/dbg_io.c --- linux-2.4.21/arch/mips/ite-boards/generic/dbg_io.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/dbg_io.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* --- CONFIG --- */ diff -urN linux-2.4.21/arch/mips/ite-boards/generic/int-handler.S linux-2.4.22/arch/mips/ite-boards/generic/int-handler.S --- linux-2.4.21/arch/mips/ite-boards/generic/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/int-handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -26,15 +26,17 @@ andi a0, t0, CAUSEF_IP7 beq a0, zero, 1f - move a0, sp - jal local_timer_interrupt + + li a0, 127 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1) + move a1, sp + jal ll_timer_interrupt j ret_from_irq nop - + 1: andi a0, t0, CAUSEF_IP2 # the only int we expect at this time - beq a0, zero, 3f - move a0,sp + beq a0, zero, 3f + move a0,sp jal it8172_hw0_irqdispatch mfc0 t0,CP0_STATUS # disable interrupts @@ -44,12 +46,12 @@ nop nop nop - + la a1, ret_from_irq jr a1 nop - -3: + +3: move a0, sp jal mips_spurious_interrupt nop diff -urN linux-2.4.21/arch/mips/ite-boards/generic/irq.c linux-2.4.22/arch/mips/ite-boards/generic/irq.c --- linux-2.4.21/arch/mips/ite-boards/generic/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * - * Part of this file was derived from Carsten Langgaard's + * Part of this file was derived from Carsten Langgaard's * arch/mips/mips-boards/atlas/atlas_int.c. * * Carsten Langgaard, carstenl@mips.com @@ -33,8 +33,10 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include +#include #include #include #include @@ -64,7 +66,7 @@ #define DPRINTK(fmt, args...) #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); #endif @@ -89,10 +91,10 @@ /* Function for careful CP0 interrupt mask access */ static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) { - unsigned long status = read_32bit_cp0_register(CP0_STATUS); + unsigned long status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); } static inline void mask_irq(unsigned int irq_nr) @@ -131,28 +133,28 @@ if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) { /* LPC interrupt */ DPRINTK("DB lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); - it8172_hw0_icregs->lpc_mask |= + it8172_hw0_icregs->lpc_mask |= (1 << (irq_nr - IT8172_LPC_IRQ_BASE)); DPRINTK("DA lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); } else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) { /* Local Bus interrupt */ DPRINTK("DB lb_mask %x\n", it8172_hw0_icregs->lb_mask); - it8172_hw0_icregs->lb_mask |= + it8172_hw0_icregs->lb_mask |= (1 << (irq_nr - IT8172_LB_IRQ_BASE)); DPRINTK("DA lb_mask %x\n", it8172_hw0_icregs->lb_mask); } else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) { /* PCI and other interrupts */ DPRINTK("DB pci_mask %x\n", it8172_hw0_icregs->pci_mask); - it8172_hw0_icregs->pci_mask |= + it8172_hw0_icregs->pci_mask |= (1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE)); DPRINTK("DA pci_mask %x\n", it8172_hw0_icregs->pci_mask); } else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) { /* NMI interrupts */ DPRINTK("DB nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); - it8172_hw0_icregs->nmi_mask |= + it8172_hw0_icregs->nmi_mask |= (1 << (irq_nr - IT8172_NMI_IRQ_BASE)); DPRINTK("DA nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); } @@ -167,28 +169,28 @@ if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) { /* LPC interrupt */ DPRINTK("EB before lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); - it8172_hw0_icregs->lpc_mask &= + it8172_hw0_icregs->lpc_mask &= ~(1 << (irq_nr - IT8172_LPC_IRQ_BASE)); DPRINTK("EA after lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); } else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) { /* Local Bus interrupt */ DPRINTK("EB lb_mask %x\n", it8172_hw0_icregs->lb_mask); - it8172_hw0_icregs->lb_mask &= + it8172_hw0_icregs->lb_mask &= ~(1 << (irq_nr - IT8172_LB_IRQ_BASE)); DPRINTK("EA lb_mask %x\n", it8172_hw0_icregs->lb_mask); } else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) { /* PCI and other interrupts */ DPRINTK("EB pci_mask %x\n", it8172_hw0_icregs->pci_mask); - it8172_hw0_icregs->pci_mask &= + it8172_hw0_icregs->pci_mask &= ~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE)); DPRINTK("EA pci_mask %x\n", it8172_hw0_icregs->pci_mask); } else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) { /* NMI interrupts */ DPRINTK("EB nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); - it8172_hw0_icregs->nmi_mask &= + it8172_hw0_icregs->nmi_mask &= ~(1 << (irq_nr - IT8172_NMI_IRQ_BASE)); DPRINTK("EA nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); } @@ -200,7 +202,7 @@ static unsigned int startup_ite_irq(unsigned int irq) { enable_it8172_irq(irq); - return 0; + return 0; } #define shutdown_ite_irq disable_it8172_irq @@ -282,15 +284,15 @@ it8172_hw0_icregs->lb_level |= 0x20; /* keyboard and mouse are edge triggered */ - it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000); + it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000); #if 0 // Enable this piece of code to make internal USB interrupt // edge triggered. - it8172_hw0_icregs->pci_trigger |= + it8172_hw0_icregs->pci_trigger |= (1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE)); - it8172_hw0_icregs->pci_level &= + it8172_hw0_icregs->pci_level &= ~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE)); #endif @@ -298,13 +300,13 @@ irq_desc[i].handler = &it8172_irq_type; } irq_desc[MIPS_CPU_TIMER_IRQ].handler = &cp0_irq_type; - set_cp0_status(ALLINTS_NOTIMER); + set_c0_status(ALLINTS_NOTIMER); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); set_debug_traps(); - breakpoint(); + breakpoint(); #endif } @@ -316,8 +318,8 @@ unsigned long status, cause; printk("got spurious interrupt\n"); - status = read_32bit_cp0_register(CP0_STATUS); - cause = read_32bit_cp0_register(CP0_CAUSE); + status = read_c0_status(); + cause = read_c0_cause(); printk("status %x cause %x\n", status, cause); printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr); // while(1); diff -urN linux-2.4.21/arch/mips/ite-boards/generic/it8172_pci.c linux-2.4.22/arch/mips/ite-boards/generic/it8172_pci.c --- linux-2.4.21/arch/mips/ite-boards/generic/it8172_pci.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/it8172_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -53,15 +53,15 @@ static struct resource pci_mem_resource_1; static struct resource pci_io_resource = { - "io pci IO space", - 0x14000000, + "io pci IO space", + 0x14018000, 0x17FFFFFF, IORESOURCE_IO }; static struct resource pci_mem_resource_0 = { - "ext pci memory space 0/1", - 0x0C000000, + "ext pci memory space 0/1", + 0x10101000, 0x13FFFFFF, IORESOURCE_MEM, &pci_mem_resource_0, @@ -70,7 +70,7 @@ }; static struct resource pci_mem_resource_1 = { - "ext pci memory space 2/3", + "ext pci memory space 2/3", 0x1A000000, 0x1FBFFFFF, IORESOURCE_MEM, @@ -82,7 +82,7 @@ extern struct pci_ops it8172_pci_ops; struct pci_channel mips_pci_channels[] = { - { &it8172_pci_ops, &pci_io_resource, &pci_mem_resource_0, 0, 0xff }, + { &it8172_pci_ops, &pci_io_resource, &pci_mem_resource_0, 0x10, 0xff }, { NULL, NULL, NULL, NULL, NULL} }; @@ -90,7 +90,7 @@ it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, unsigned char where, u32 *data) { - /* + /* * config cycles are on 4 byte boundary only */ unsigned char bus = dev->bus->number; @@ -100,13 +100,13 @@ access_type, dev, bus, dev_fn, *data); /* Setup address */ - IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | (where & ~0x3)); if (access_type == PCI_ACCESS_WRITE) { IT_WRITE(IT_CONFDATA, *data); - } + } else { IT_READ(IT_CONFDATA, *data); } @@ -133,7 +133,7 @@ return -1; *val = (data >> ((where & 3) << 3)) & 0xff; - DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", + DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", dev->bus->number, dev->devfn, where, *val); return PCIBIOS_SUCCESSFUL; @@ -152,7 +152,7 @@ return -1; *val = (data >> ((where & 3) << 3)) & 0xffff; - DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", + DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", dev->bus->number, dev->devfn, where, *val); return PCIBIOS_SUCCESSFUL; @@ -165,12 +165,12 @@ if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; - + if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) return -1; *val = data; - DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", + DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", dev->bus->number, dev->devfn, where, *val); return PCIBIOS_SUCCESSFUL; @@ -181,7 +181,7 @@ write_config_byte (struct pci_dev *dev, int where, u8 val) { u32 data = 0; - + if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) return -1; @@ -201,11 +201,11 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; - + if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) return -1; - data = (data & ~(0xffff << ((where & 3) << 3))) | + data = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) diff -urN linux-2.4.21/arch/mips/ite-boards/generic/it8172_rtc.c linux-2.4.22/arch/mips/ite-boards/generic/it8172_rtc.c --- linux-2.4.21/arch/mips/ite-boards/generic/it8172_rtc.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/it8172_rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,62 +0,0 @@ -/* - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute 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 it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You 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. - * - * ######################################################################## - * - * RTC routines for ITE8172 MC146818-compatible rtc chip. - * - */ -#include -#include - -#define IT8172_RTC_ADR_REG (IT8172_PCI_IO_BASE + IT_RTC_BASE) -#define IT8172_RTC_DAT_REG (IT8172_RTC_ADR_REG + 1) - -static volatile char *rtc_adr_reg = KSEG1ADDR((volatile char *)IT8172_RTC_ADR_REG); -static volatile char *rtc_dat_reg = KSEG1ADDR((volatile char *)IT8172_RTC_DAT_REG); - -unsigned char it8172_rtc_read_data(unsigned long addr) -{ - unsigned char retval; - - *rtc_adr_reg = addr; - retval = *rtc_dat_reg; - return retval; -} - -void it8172_rtc_write_data(unsigned char data, unsigned long addr) -{ - *rtc_adr_reg = addr; - *rtc_dat_reg = data; -} - -static int it8172_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops it8172_rtc_ops = { - &it8172_rtc_read_data, - &it8172_rtc_write_data, - &it8172_rtc_bcd_mode -}; diff -urN linux-2.4.21/arch/mips/ite-boards/generic/it8172_setup.c linux-2.4.22/arch/mips/ite-boards/generic/it8172_setup.c --- linux-2.4.21/arch/mips/ite-boards/generic/it8172_setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/it8172_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -32,14 +32,16 @@ #include #include #include -#include #include #include #include #include +#include +#include #include #include +#include #include #include #ifdef CONFIG_PC_KEYB @@ -51,7 +53,6 @@ char serial_console[20]; #endif -extern struct rtc_ops it8172_rtc_ops; extern struct resource ioport_resource; #ifdef CONFIG_BLK_DEV_IDE extern struct ide_ops std_ide_ops; @@ -71,11 +72,8 @@ extern void (*board_time_init)(void); extern void (*board_timer_setup)(struct irqaction *irq); -extern unsigned long (*rtc_get_time)(void); -extern int (*rtc_set_time)(unsigned long); extern void it8172_time_init(void); extern void it8172_timer_setup(struct irqaction *irq); -extern unsigned long it8172_rtc_get_time(void); #ifdef CONFIG_IT8172_REVC struct { @@ -131,22 +129,19 @@ argptr = prom_getcmdline(); strcat(argptr, " console=ttyS0,115200"); } -#endif +#endif - clear_cp0_status(ST0_FR); - rtc_ops = &it8172_rtc_ops; + clear_c0_status(ST0_FR); board_time_init = it8172_time_init; board_timer_setup = it8172_timer_setup; - rtc_get_time = it8172_rtc_get_time; - //rtc_set_time = it8172_rtc_set_time; _machine_restart = it8172_restart; _machine_halt = it8172_halt; _machine_power_off = it8172_power_off; /* - * IO/MEM resources. + * IO/MEM resources. * * revisit this area. */ @@ -173,7 +168,7 @@ dsr &= ~IT_PM_DSR_ACSB; #else dsr |= IT_PM_DSR_ACSB; -#endif +#endif #ifdef CONFIG_BLK_DEV_IT8172 dsr &= ~IT_PM_DSR_IDESB; ide_ops = &std_ide_ops; @@ -209,8 +204,8 @@ LPCSetConfig(0x4, 0x30, 0x1); LPCSetConfig(0x4, 0xf4, LPCGetConfig(0x4, 0xf4) | 0x80); - if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) || - (LPCGetConfig(LDN_MOUSE, 0x30) == 0)) + if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) || + (LPCGetConfig(LDN_MOUSE, 0x30) == 0)) printk("Error: keyboard or mouse not enabled\n"); kbd_ops = &std_kbd_ops; @@ -234,7 +229,7 @@ #endif #ifdef CONFIG_IT8172_SCR0 { - unsigned i; + unsigned i; /* Enable Smart Card Reader 0 */ /* First power it up */ IT_IO_READ16(IT_PM_DSR, i); @@ -253,7 +248,7 @@ #endif /* CONFIG_IT8172_SCR0 */ #ifdef CONFIG_IT8172_SCR1 { - unsigned i; + unsigned i; /* Enable Smart Card Reader 1 */ /* First power it up */ IT_IO_READ16(IT_PM_DSR, i); @@ -275,7 +270,7 @@ #ifdef CONFIG_PC_KEYB /* - * According to the ITE Special BIOS Note for waking up the + * According to the ITE Special BIOS Note for waking up the * keyboard controller... */ int init_8712_keyboard() diff -urN linux-2.4.21/arch/mips/ite-boards/generic/lpc.c linux-2.4.22/arch/mips/ite-boards/generic/lpc.c --- linux-2.4.21/arch/mips/ite-boards/generic/lpc.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/lpc.c 2003-08-25 04:44:40.000000000 -0700 @@ -62,7 +62,7 @@ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode outb(0x07, LPC_KEY_ADDR); outb(LdnNumber, LPC_DATA_ADDR); - outb(Index, LPC_KEY_ADDR); + outb(Index, LPC_KEY_ADDR); outb(data, LPC_DATA_ADDR); LPCExitMBPnP(); } @@ -74,7 +74,7 @@ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode outb(0x07, LPC_KEY_ADDR); outb(LdnNumber, LPC_DATA_ADDR); - outb(Index, LPC_KEY_ADDR); + outb(Index, LPC_KEY_ADDR); rtn = inb(LPC_DATA_ADDR); LPCExitMBPnP(); return rtn; @@ -92,7 +92,7 @@ Id2 = inb(LPC_DATA_ADDR); Id = (Id1 << 8) | Id2; LPCExitMBPnP(); - if (Id == 0x8712) + if (Id == 0x8712) return TRUE; else return FALSE; @@ -104,30 +104,30 @@ unsigned long data; bus = 0; - dev_fn = 1<<3 | 4; + dev_fn = 1<<3 | 4; /* pci cmd, SERR# Enable */ - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x4 / 4) << IT_REGNUM_SHF)); IT_READ(IT_CONFDATA, data); data |= 0x0100; - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x4 / 4) << IT_REGNUM_SHF)); IT_WRITE(IT_CONFDATA, data); /* setup serial irq control register */ - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x48 / 4) << IT_REGNUM_SHF)); IT_READ(IT_CONFDATA, data); data = (data & 0xffff00ff) | 0xc400; - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x48 / 4) << IT_REGNUM_SHF)); @@ -136,7 +136,7 @@ /* Enable I/O Space Subtractive Decode */ /* default 0x4C is 0x3f220000 */ - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x4C / 4) << IT_REGNUM_SHF)); diff -urN linux-2.4.21/arch/mips/ite-boards/generic/pmon_prom.c linux-2.4.22/arch/mips/ite-boards/generic/pmon_prom.c --- linux-2.4.21/arch/mips/ite-boards/generic/pmon_prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/pmon_prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,7 +8,7 @@ * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * - * This file was derived from Carsten Langgaard's + * This file was derived from Carsten Langgaard's * arch/mips/mips-boards/xx files. * * Carsten Langgaard, carstenl@mips.com @@ -128,11 +128,11 @@ memsize_str = prom_getenv("memsize"); if (!memsize_str) { #ifdef CONFIG_MIPS_ITE8172 - memsize = 32; + memsize = 32; #elif defined(CONFIG_MIPS_IVR) - memsize = 64; + memsize = 64; #else - memsize = 8; + memsize = 8; #endif printk("memsize unknown: setting to %dMB\n", memsize); } else { diff -urN linux-2.4.21/arch/mips/ite-boards/generic/reset.c linux-2.4.22/arch/mips/ite-boards/generic/reset.c --- linux-2.4.21/arch/mips/ite-boards/generic/reset.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -38,10 +38,10 @@ void it8172_restart() { - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21/arch/mips/ite-boards/generic/time.c linux-2.4.22/arch/mips/ite-boards/generic/time.c --- linux-2.4.21/arch/mips/ite-boards/generic/time.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/generic/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -2,6 +2,9 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * + * Copyright (C) 2003 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * * ######################################################################## * * This program is free software; you can distribute it and/or modify it @@ -22,108 +25,212 @@ * Setting up the clock on the MIPS boards. * */ - -#include #include #include #include #include #include -#include +#include #include #include +#include #include #include +#define IT8172_RTC_ADR_REG (IT8172_PCI_IO_BASE + IT_RTC_BASE) +#define IT8172_RTC_DAT_REG (IT8172_RTC_ADR_REG + 1) +#define IT8172_RTC_CENTURY_REG (IT8172_PCI_IO_BASE + IT_RTC_CENTURY) + +static volatile char *rtc_adr_reg = (char*)KSEG1ADDR(IT8172_RTC_ADR_REG); +static volatile char *rtc_dat_reg = (char*)KSEG1ADDR(IT8172_RTC_DAT_REG); +static volatile char *rtc_century_reg = (char*)KSEG1ADDR(IT8172_RTC_CENTURY_REG); + +unsigned char it8172_rtc_read_data(unsigned long addr) +{ + unsigned char retval; + + *rtc_adr_reg = addr; + retval = *rtc_dat_reg; + return retval; +} + +void it8172_rtc_write_data(unsigned char data, unsigned long addr) +{ + *rtc_adr_reg = addr; + *rtc_dat_reg = data; +} + +#undef CMOS_READ +#undef CMOS_WRITE +#define CMOS_READ(addr) it8172_rtc_read_data(addr) +#define CMOS_WRITE(data, addr) it8172_rtc_write_data(data, addr) + +static unsigned char saved_control; /* remember rtc control reg */ +static inline int rtc_24h(void) { return saved_control & RTC_24H; } +static inline int rtc_dm_binary(void) { return saved_control & RTC_DM_BINARY; } + +static inline unsigned char +bin_to_hw(unsigned char c) +{ + if (rtc_dm_binary()) + return c; + else + return ((c/10) << 4) + (c%10); +} + +static inline unsigned char +hw_to_bin(unsigned char c) +{ + if (rtc_dm_binary()) + return c; + else + return (c>>4)*10 + (c &0xf); +} + +/* 0x80 bit indicates pm in 12-hour format */ +static inline unsigned char +hour_bin_to_hw(unsigned char c) +{ + if (rtc_24h()) + return bin_to_hw(c); + if (c >= 12) + return 0x80 | bin_to_hw((c==12)?12:c-12); /* 12 is 12pm */ + else + return bin_to_hw((c==0)?12:c); /* 0 is 12 AM, not 0 am */ +} + +static inline unsigned char +hour_hw_to_bin(unsigned char c) +{ + unsigned char tmp = hw_to_bin(c&0x3f); + if (rtc_24h()) + return tmp; + if (c & 0x80) + return (tmp==12)?12:tmp+12; /* 12pm is 12, not 24 */ + else + return (tmp==12)?0:tmp; /* 12am is 0 */ +} + static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ extern unsigned int mips_counter_frequency; -extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); -/* +/* * Figure out the r4k offset, the amount to increment the compare - * register for each time tick. + * register for each time tick. * Use the RTC to calculate offset. */ static unsigned long __init cal_r4koff(void) { - unsigned int flags; + unsigned long flags; - __save_and_cli(flags); + local_irq_save(flags); /* Start counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - mips_counter_frequency = read_32bit_cp0_register(CP0_COUNT); + mips_counter_frequency = read_c0_count(); /* restore interrupts */ - __restore_flags(flags); - + local_irq_restore(flags); + return (mips_counter_frequency / HZ); } -unsigned long it8172_rtc_get_time(void) +static unsigned long +it8172_rtc_get_time(void) { unsigned int year, mon, day, hour, min, sec; - unsigned char save_control; - - save_control = CMOS_READ(RTC_CONTROL); + unsigned int flags; - /* Freeze it. */ - CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL); + /* avoid update-in-progress. */ + for (;;) { + local_irq_save(flags); + if (! (CMOS_READ(RTC_REG_A) & RTC_UIP)) + break; + /* don't hold intr closed all the time */ + local_irq_restore(flags); + } /* Read regs. */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - - if (!(save_control & RTC_24H)) - { - if ((hour & 0xf) == 0xc) - hour &= 0x80; - if (hour & 0x80) - hour = (hour & 0xf) + 12; + sec = hw_to_bin(CMOS_READ(RTC_SECONDS)); + min = hw_to_bin(CMOS_READ(RTC_MINUTES)); + hour = hour_hw_to_bin(CMOS_READ(RTC_HOURS)); + day = hw_to_bin(CMOS_READ(RTC_DAY_OF_MONTH)); + mon = hw_to_bin(CMOS_READ(RTC_MONTH)); + year = hw_to_bin(CMOS_READ(RTC_YEAR)) + + hw_to_bin(*rtc_century_reg) * 100; + + /* restore interrupts */ + local_irq_restore(flags); + + return mktime(year, mon, day, hour, min, sec); +} + +static int +it8172_rtc_set_time(unsigned long t) +{ + struct rtc_time tm; + unsigned int flags; + + /* convert */ + to_tm(t, &tm); + + /* avoid update-in-progress. */ + for (;;) { + local_irq_save(flags); + if (! (CMOS_READ(RTC_REG_A) & RTC_UIP)) + break; + /* don't hold intr closed all the time */ + local_irq_restore(flags); } - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - /* Unfreeze clock. */ - CMOS_WRITE(save_control, RTC_CONTROL); + *rtc_century_reg = bin_to_hw(tm.tm_year/100); + CMOS_WRITE(bin_to_hw(tm.tm_sec), RTC_SECONDS); + CMOS_WRITE(bin_to_hw(tm.tm_min), RTC_MINUTES); + CMOS_WRITE(hour_bin_to_hw(tm.tm_hour), RTC_HOURS); + CMOS_WRITE(bin_to_hw(tm.tm_mday), RTC_DAY_OF_MONTH); + CMOS_WRITE(bin_to_hw(tm.tm_mon+1), RTC_MONTH); /* tm_mon starts from 0 */ + CMOS_WRITE(bin_to_hw(tm.tm_year%100), RTC_YEAR); - if ((year += 1900) < 1970) - year += 100; + /* restore interrupts */ + local_irq_restore(flags); - return mktime(year, mon, day, hour, min, sec); + return 0; } void __init it8172_time_init(void) { - unsigned int est_freq, flags; + unsigned long flags; + unsigned int est_freq; + + local_irq_save(flags); - __save_and_cli(flags); - /* Set Data mode - binary. */ - CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); + saved_control = CMOS_READ(RTC_CONTROL); printk("calculating r4koff... "); r4k_offset = cal_r4koff(); printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); - est_freq = 2*r4k_offset*HZ; + est_freq = 2*r4k_offset*HZ; est_freq += 5000; /* round */ est_freq -= est_freq%10000; - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - __restore_flags(flags); + + local_irq_restore(flags); + + rtc_get_time = it8172_rtc_get_time; + rtc_set_time = it8172_rtc_set_time; } #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) @@ -136,12 +243,7 @@ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ALLINTS); -} - -void local_timer_interrupt(struct pt_regs *regs) -{ - do_IRQ(MIPS_CPU_TIMER_IRQ, regs); + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); } diff -urN linux-2.4.21/arch/mips/ite-boards/ivr/Makefile linux-2.4.22/arch/mips/ite-boards/ivr/Makefile --- linux-2.4.21/arch/mips/ite-boards/ivr/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/ivr/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -11,17 +11,14 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true all: ivr.o O_TARGET := ivr.o -obj-y := init.o +obj-y := init.o -obj-$(CONFIG_PCI) += pci_fixup.o +obj-$(CONFIG_PCI) += pci_fixup.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/ite-boards/ivr/README linux-2.4.22/arch/mips/ite-boards/ivr/README --- linux-2.4.21/arch/mips/ite-boards/ivr/README 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/ivr/README 2003-08-25 04:44:40.000000000 -0700 @@ -1,3 +1,3 @@ -This is not really a board made by ITE Semi, but it's very +This is not really a board made by ITE Semi, but it's very similar to the ITE QED-4N-S01B board. The IVR board is made by Globespan and it's a reference board for the PVR chip. diff -urN linux-2.4.21/arch/mips/ite-boards/ivr/init.c linux-2.4.22/arch/mips/ite-boards/ivr/init.c --- linux-2.4.21/arch/mips/ite-boards/ivr/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/ivr/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -27,14 +27,12 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include #include #include #include -#include #include #include #include @@ -81,7 +79,7 @@ * make the entire physical memory visible to pci bus masters */ IT_READ(IT_MC_PCICR, pcicr); - pcicr &= ~0x1f; + pcicr &= ~0x1f; pcicr |= (mem_size - 1) >> 22; IT_WRITE(IT_MC_PCICR, pcicr); diff -urN linux-2.4.21/arch/mips/ite-boards/ivr/pci_fixup.c linux-2.4.22/arch/mips/ite-boards/ivr/pci_fixup.c --- linux-2.4.21/arch/mips/ite-boards/ivr/pci_fixup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/ivr/pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -74,8 +74,8 @@ switch (slot) { case 0x01: /* - * Internal device 1 is actually 7 different - * internal devices on the IT8172G (multi-function + * Internal device 1 is actually 7 different + * internal devices on the IT8172G (multi-function * device). */ if (func < 7) @@ -97,7 +97,7 @@ dev->irq = IT8172_PCI_INTB_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -118,7 +118,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -139,7 +139,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } diff -urN linux-2.4.21/arch/mips/ite-boards/qed-4n-s01b/Makefile linux-2.4.22/arch/mips/ite-boards/qed-4n-s01b/Makefile --- linux-2.4.21/arch/mips/ite-boards/qed-4n-s01b/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/qed-4n-s01b/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -11,16 +11,12 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET := ite.o -obj-y := init.o +obj-y := init.o obj-$(CONFIG_PCI) += pci_fixup.o -obj-$(CONFIG_BLK_DEV_INITRD) += le_ramdisk.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/ite-boards/qed-4n-s01b/init.c linux-2.4.22/arch/mips/ite-boards/qed-4n-s01b/init.c --- linux-2.4.21/arch/mips/ite-boards/qed-4n-s01b/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/qed-4n-s01b/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -27,14 +27,12 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include #include #include #include -#include #include #include #include @@ -82,7 +80,7 @@ * make the entire physical memory visible to pci bus masters */ IT_READ(IT_MC_PCICR, pcicr); - pcicr &= ~0x1f; + pcicr &= ~0x1f; pcicr |= (mem_size - 1) >> 22; IT_WRITE(IT_MC_PCICR, pcicr); diff -urN linux-2.4.21/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c linux-2.4.22/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c --- linux-2.4.21/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -75,7 +75,7 @@ switch (slot) { case 0x01: /* - * Internal device 1 is actually 7 different + * Internal device 1 is actually 7 different * internal devices on the IT8172G (a multi- * function device). */ @@ -97,7 +97,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -117,7 +117,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -137,7 +137,7 @@ dev->irq = IT8172_PCI_INTA_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -157,7 +157,7 @@ dev->irq = IT8172_PCI_INTB_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -177,7 +177,7 @@ dev->irq = IT8172_PCI_INTC_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } diff -urN linux-2.4.21/arch/mips/jazz/Makefile linux-2.4.22/arch/mips/jazz/Makefile --- linux-2.4.21/arch/mips/jazz/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/arch/mips/jazz/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,17 +6,15 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $@ -.S.o: - $(CC) $(CFLAGS) -c $< -o $@ +USE_STANDARD_AS_RULE := true all: jazz.o O_TARGET := jazz.o -obj-y := int-handler.o irq.o jazzdma.o reset.o rtc-jazz.o setup.o \ - floppy-jazz.o kbd-jazz.o +export-syms := jazz-ksyms.o +obj-y := int-handler.o irq.o jazzdma.o jazz-ksyms.o reset.o \ + rtc-jazz.o setup.o floppy-jazz.o kbd-jazz.o int-handler.o: int-handler.S diff -urN linux-2.4.21/arch/mips/jazz/floppy-jazz.c linux-2.4.22/arch/mips/jazz/floppy-jazz.c --- linux-2.4.21/arch/mips/jazz/floppy-jazz.c 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.22/arch/mips/jazz/floppy-jazz.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: floppy-jazz.c,v 1.2 1998/10/18 13:18:25 tsbogend Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -108,9 +107,9 @@ static void jazz_fd_dma_mem_free(unsigned long addr, unsigned long size) -{ +{ vdma_free(vdma_phys2log(PHYSADDR(addr))); - free_pages(addr, get_order(size)); + free_pages(addr, get_order(size)); } static unsigned long jazz_fd_drive_type(unsigned long n) diff -urN linux-2.4.21/arch/mips/jazz/int-handler.S linux-2.4.22/arch/mips/jazz/int-handler.S --- linux-2.4.21/arch/mips/jazz/int-handler.S 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.22/arch/mips/jazz/int-handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: int-handler.S,v 1.14 1999/05/01 22:40:34 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -251,14 +250,14 @@ nor s1,zero,s1 jal do_IRQ - + /* * Reenable interrupt */ lhu t2,JAZZ_IO_IRQ_ENABLE or t2,s1 sh t2,JAZZ_IO_IRQ_ENABLE - + j ret_from_irq /* diff -urN linux-2.4.21/arch/mips/jazz/irq.c linux-2.4.22/arch/mips/jazz/irq.c --- linux-2.4.21/arch/mips/jazz/irq.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/jazz/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,11 +8,11 @@ */ #include #include -#include #include #include #include +#include #include #include @@ -20,7 +20,7 @@ /* * On systems with i8259-style interrupt controllers we assume for - * driver compatibility reasons interrupts 0 - 15 to be the i8295 + * driver compatibility reasons interrupts 0 - 15 to be the i8259 * interrupts even if the hardware uses a different interrupt numbering. */ void __init init_IRQ (void) diff -urN linux-2.4.21/arch/mips/jazz/jazz-ksyms.c linux-2.4.22/arch/mips/jazz/jazz-ksyms.c --- linux-2.4.21/arch/mips/jazz/jazz-ksyms.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/jazz/jazz-ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,16 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003 by Ralf Baechle + */ +#include + +#include +#include +#include + +EXPORT_SYMBOL(vdma_alloc); +EXPORT_SYMBOL(vdma_free); +EXPORT_SYMBOL(vdma_log2phys); diff -urN linux-2.4.21/arch/mips/jazz/kbd-jazz.c linux-2.4.22/arch/mips/jazz/kbd-jazz.c --- linux-2.4.21/arch/mips/jazz/kbd-jazz.c 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.22/arch/mips/jazz/kbd-jazz.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: kbd-jazz.c,v 1.1 1998/10/28 12:38:10 ralf Exp $ - * +/* * Low-level hardware access stuff for Jazz family machines. * * This file is subject to the terms and conditions of the GNU General Public @@ -39,20 +38,20 @@ static int jazz_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) { int ret; - + ret = request_irq(JAZZ_MOUSE_IRQ, handler, 0, "PS/2 Mouse", NULL); if (ret != 0) return ret; - r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, - r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_MOUSE); return 0; } static void jazz_aux_free_irq(void) { - r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_MOUSE); free_irq(JAZZ_MOUSE_IRQ, NULL); diff -urN linux-2.4.21/arch/mips/jazz/reset.c linux-2.4.22/arch/mips/jazz/reset.c --- linux-2.4.21/arch/mips/jazz/reset.c 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.22/arch/mips/jazz/reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,11 +1,6 @@ /* - * linux/arch/mips/jazz/process.c - * - * Reset a Jazz machine. - * - * $Id:$ + * Reset a Jazz machine. */ - #include #include #include @@ -27,7 +22,7 @@ void jazz_machine_restart(char *command) { while (1) { - kb_wait (); + kb_wait (); kbd_write_command (0xd1); kb_wait (); kbd_write_output (0x00); diff -urN linux-2.4.21/arch/mips/jazz/setup.c linux-2.4.22/arch/mips/jazz/setup.c --- linux-2.4.21/arch/mips/jazz/setup.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips/jazz/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -28,6 +28,7 @@ #include #include #include +#include /* * Initial irq handlers. @@ -72,7 +73,7 @@ JAZZ_IE_FLOPPY); r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */ - change_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); + change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); /* set the clock to 100 Hz */ r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9); request_region(0x20, 0x20, "pic1"); @@ -80,14 +81,20 @@ i8259_setup_irq(2, &irq2); } + void __init jazz_setup(void) { + /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */ add_wired_entry (0x02000017, 0x03c00017, 0xe0000000, PM_64K); + + /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */ add_wired_entry (0x02400017, 0x02440017, 0xe2000000, PM_16M); + + /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */ add_wired_entry (0x01800017, 0x01000017, 0xe4000000, PM_4M); irq_setup = jazz_irq_setup; - mips_io_port_base = JAZZ_PORT_BASE; + set_io_port_base(JAZZ_PORT_BASE); if (mips_machtype == MACH_MIPS_MAGNUM_4000) EISA_bus = 1; isa_slot_offset = 0xe3000000; diff -urN linux-2.4.21/arch/mips/jmr3927/common/Makefile linux-2.4.22/arch/mips/jmr3927/common/Makefile --- linux-2.4.21/arch/mips/jmr3927/common/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/common/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,10 +6,7 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= tx3927.o diff -urN linux-2.4.21/arch/mips/jmr3927/common/prom.c linux-2.4.22/arch/mips/jmr3927/common/prom.c --- linux-2.4.21/arch/mips/jmr3927/common/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/common/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -6,11 +6,11 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * Based on arch/mips/au1000/common/prom.c * - * This file was derived from Carsten Langgaard's + * This file was derived from Carsten Langgaard's * arch/mips/mips-boards/xx files. * * Carsten Langgaard, carstenl@mips.com @@ -36,8 +36,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include #include #include #include diff -urN linux-2.4.21/arch/mips/jmr3927/common/puts.c linux-2.4.22/arch/mips/jmr3927/common/puts.c --- linux-2.4.21/arch/mips/jmr3927/common/puts.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/common/puts.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * Author: MontaVista Software, Inc. * ahennessy@mvista.com or source@mvista.com * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * Based on arch/mips/au1000/common/puts.c * @@ -52,7 +52,7 @@ putch(const unsigned char c) { int i = 0; - + do { slow_down(); i++; @@ -69,7 +69,7 @@ int i = 0; int dicr; char c; - + /* diable RX int. */ dicr = tx3927_sioptr(1)->dicr; tx3927_sioptr(1)->dicr = 0; diff -urN linux-2.4.21/arch/mips/jmr3927/common/rtc_ds1742.c linux-2.4.22/arch/mips/jmr3927/common/rtc_ds1742.c --- linux-2.4.21/arch/mips/jmr3927/common/rtc_ds1742.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/common/rtc_ds1742.c 2003-08-25 04:44:40.000000000 -0700 @@ -2,13 +2,13 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * arch/mips/jmr3927/common/rtc_ds1742.c * Based on arch/mips/ddb5xxx/common/rtc_ds1386.c * low-level RTC hookups for s for Dallas 1742 chip. * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -82,7 +82,7 @@ } extern void to_tm(unsigned long tim, struct rtc_time * tm); -static int +static int rtc_ds1742_set_time(unsigned long t) { struct rtc_time tm; @@ -117,7 +117,7 @@ day = BIN_TO_BCD(tm.tm_mday); if (day != cmos_day) { - + CMOS_WRITE(day, RTC_DATE); } @@ -144,7 +144,7 @@ if (second != cmos_second) { CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); } - + /* RTC_CENTURY and RTC_CONTROL share same address... */ CMOS_WRITE(cmos_century, RTC_CONTROL); diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/Makefile linux-2.4.22/arch/mips/jmr3927/rbhma3100/Makefile --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,16 +6,13 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= jmr3927.o obj-y += init.o int-handler.o irq.o setup.o rtc.o pci_fixup.o pci_ops.o -obj-$(CONFIG_LL_DEBUG) += debug.o -obj-$(CONFIG_REMOTE_DEBUG) += kgdb_io.o +obj-$(CONFIG_RUNTIME_DEBUG) += debug.o +obj-$(CONFIG_KGDB) += kgdb_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/init.c linux-2.4.22/arch/mips/jmr3927/rbhma3100/init.c --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -2,11 +2,11 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * arch/mips/jmr3927/common/init.c * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -66,7 +66,7 @@ #endif prom_argc = argc; prom_argv = argv; - prom_envp = envp; + prom_envp = envp; mips_machgroup = MACH_GROUP_TOSHIBA; diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/int-handler.S linux-2.4.22/arch/mips/jmr3927/rbhma3100/int-handler.S --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/int-handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * Based on arch/mips/tsdb/kernel/int-handler.S * diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/irq.c linux-2.4.22/arch/mips/jmr3927/rbhma3100/irq.c --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -47,7 +48,6 @@ #include #include -#include #include #include @@ -137,7 +137,7 @@ db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); if (irq == JMR3927_IRQ_IRC_TMR0) { - jmr3927_tmrptr->tisr = 0; /* ack interrupt */ + jmr3927_tmrptr->tisr = 0; /* ack interrupt */ } jmr3927_irq_disable(irq); @@ -248,33 +248,33 @@ } struct tb_irq_space jmr3927_isac_irqspace = { - next: NULL, - start_irqno: JMR3927_IRQ_ISAC, + .next = NULL, + .start_irqno = JMR3927_IRQ_ISAC, nr_irqs : JMR3927_NR_IRQ_ISAC, - mask_func: mask_irq_isac, - unmask_func: unmask_irq_isac, - name: "ISAC", - space_id: 0, + .mask_func = mask_irq_isac, + .unmask_func = unmask_irq_isac, + .name = "ISAC", + .space_id = 0, can_share : 0 }; struct tb_irq_space jmr3927_ioc_irqspace = { - next: NULL, - start_irqno: JMR3927_IRQ_IOC, + .next = NULL, + .start_irqno = JMR3927_IRQ_IOC, nr_irqs : JMR3927_NR_IRQ_IOC, - mask_func: mask_irq_ioc, - unmask_func: unmask_irq_ioc, - name: "IOC", - space_id: 0, + .mask_func = mask_irq_ioc, + .unmask_func = unmask_irq_ioc, + .name = "IOC", + .space_id = 0, can_share : 1 }; struct tb_irq_space jmr3927_irc_irqspace = { - next: NULL, - start_irqno: JMR3927_IRQ_IRC, + .next = NULL, + .start_irqno = JMR3927_IRQ_IRC, nr_irqs : JMR3927_NR_IRQ_IRC, - mask_func: mask_irq_irc, - unmask_func: unmask_irq_irc, - name: "on-chip", - space_id: 0, + .mask_func = mask_irq_irc, + .unmask_func = unmask_irq_irc, + .name = "on-chip", + .space_id = 0, can_share : 0 }; @@ -287,11 +287,10 @@ regs->cp0_cause, regs->cp0_epc, regs->regs[31]); } -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); void jmr3927_irc_irqdispatch(struct pt_regs *regs) { int irq; - + #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND tx_branch_likely_bug_fixup(regs); #endif @@ -437,14 +436,14 @@ #endif /* enable all CPU interrupt bits. */ - set_cp0_status(ST0_IM); /* IE bit is still 0. */ + set_c0_status(ST0_IM); /* IE bit is still 0. */ } void (*irq_setup)(void); void __init init_IRQ(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern void set_debug_traps(void); @@ -468,7 +467,7 @@ NULL /* no affinity stuff for UP */ }; -void +void jmr3927_irq_init(u32 irq_base) { extern irq_desc_t irq_desc[]; @@ -480,7 +479,7 @@ irq_desc[i].depth = 1; irq_desc[i].handler = &jmr3927_irq_controller; } - + jmr3927_irq_base = irq_base; } diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/kgdb_io.c linux-2.4.22/arch/mips/jmr3927/rbhma3100/kgdb_io.c --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/kgdb_io.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/kgdb_io.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,7 +8,7 @@ * * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -52,7 +52,7 @@ int putDebugChar(unsigned char c) { int i = 0; - + if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(38400); @@ -75,7 +75,7 @@ int i = 0; int dicr; char c; - + if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(38400); diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/pci_fixup.c linux-2.4.22/arch/mips/jmr3927/rbhma3100/pci_fixup.c --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/pci_fixup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -42,7 +42,7 @@ #ifdef DEBUG #define DBG(x...) printk(x) #else -#define DBG(x...) +#define DBG(x...) #endif void __init pcibios_fixup_resources(struct pci_dev *dev) diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/pci_ops.c linux-2.4.22/arch/mips/jmr3927/rbhma3100/pci_ops.c --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/pci_ops.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/pci_ops.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,15 +1,15 @@ /*********************************************************************** * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c * * Define the pci_ops for JMR3927. * - * Much of the code is derived from the original DDB5074 port by + * Much of the code is derived from the original DDB5074 port by * Geert Uytterhoeven * * This program is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -45,13 +44,13 @@ #include struct resource pci_io_resource = { - "pci IO space", + "pci IO space", 0x1000, /* reserve regacy I/O space */ 0x1000 + JMR3927_PCIIO_SIZE -1, IORESOURCE_IO}; struct resource pci_mem_resource = { - "pci memory space", + "pci memory space", JMR3927_PCIMEM, JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE -1, IORESOURCE_MEM}; @@ -66,7 +65,7 @@ unsigned int pcibios_assign_all_busses(void) { return 1; -} +} static int mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, int *flagsp) @@ -107,7 +106,7 @@ unsigned char bus, func_num; db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); + db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { @@ -115,7 +114,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -135,7 +134,7 @@ return PCIBIOS_BAD_REGISTER_NUMBER; db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); + db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { @@ -143,7 +142,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -163,7 +162,7 @@ return PCIBIOS_BAD_REGISTER_NUMBER; db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); + db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { @@ -171,7 +170,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -193,7 +192,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -218,7 +217,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -243,7 +242,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -276,7 +275,7 @@ addr = PHYSADDR(addr); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)addr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -289,7 +288,7 @@ addr = PHYSADDR(addr); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)addr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ @@ -313,7 +312,7 @@ else if (offset == 3) byte = 0xe; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -341,7 +340,7 @@ byte = 0xe; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ @@ -361,7 +360,7 @@ else if (offset == 2) byte = 0xc; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -386,7 +385,7 @@ byte = 0xc; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ @@ -399,7 +398,7 @@ ioaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -414,7 +413,7 @@ ioaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/rtc.c linux-2.4.22/arch/mips/jmr3927/rbhma3100/rtc.c --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/rtc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/rtc.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * RTC routines for Dallas chip. * diff -urN linux-2.4.21/arch/mips/jmr3927/rbhma3100/setup.c linux-2.4.22/arch/mips/jmr3927/rbhma3100/setup.c --- linux-2.4.21/arch/mips/jmr3927/rbhma3100/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/jmr3927/rbhma3100/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -2,13 +2,13 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * Based on arch/mips/ddb5xxx/ddb5477/setup.c * * Setup file for JMR3927. * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -55,6 +55,7 @@ #include #include #include +#include /* Tick Timer divider */ #define JMR3927_TIMER_CCD 0 /* 1/2 */ @@ -180,11 +181,12 @@ } return res; -} +} + #if defined(CONFIG_BLK_DEV_INITRD) extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end; -#endif +#endif //#undef DO_WRITE_THROUGH #define DO_WRITE_THROUGH @@ -211,19 +213,19 @@ _machine_power_off = jmr3927_machine_power_off; /* - * IO/MEM resources. + * IO/MEM resources. */ ioport_resource.start = pci_io_resource.start; ioport_resource.end = pci_io_resource.end; iomem_resource.start = pci_mem_resource.start; iomem_resource.end = pci_mem_resource.end; - + /* Reboot on panic */ panic_timeout = 180; { unsigned int conf; - conf = read_32bit_cp0_register(CP0_CONF); + conf = read_c0_conf(); } #if 1 @@ -243,15 +245,15 @@ int mips_config_wbon = 1; #endif - conf = read_32bit_cp0_register(CP0_CONF); + conf = read_c0_conf(); conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON); conf |= mips_ic_disable ? 0 : TX39_CONF_ICE; conf |= mips_dc_disable ? 0 : TX39_CONF_DCE; conf |= mips_config_wbon ? TX39_CONF_WBON : 0; conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; - write_32bit_cp0_register(CP0_CONF, conf); - write_32bit_cp0_register(CP0_TX39_CACHE, 0); + write_c0_conf(conf); + write_c0_cache(0); } #endif @@ -275,9 +277,9 @@ argptr = prom_getcmdline(); strcat(argptr, " console=ttyS1,115200"); } -#endif +#endif } - + static void tx3927_setup(void); @@ -338,7 +340,7 @@ jmr3927_led_set(0); - if (jmr3927_have_isac()) + if (jmr3927_have_isac()) jmr3927_io_led_set(0); printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n", jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK, @@ -510,7 +512,7 @@ { unsigned int conf; - conf = read_32bit_cp0_register(CP0_CONF); + conf = read_c0_conf(); if (!(conf & TX39_CONF_ICE)) printk("TX3927 I-Cache disabled.\n"); if (!(conf & TX39_CONF_DCE)) diff -urN linux-2.4.21/arch/mips/kernel/Makefile linux-2.4.22/arch/mips/kernel/Makefile --- linux-2.4.21/arch/mips/kernel/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -12,11 +12,11 @@ O_TARGET := kernel.o -export-objs = irq.o pci-dma.o setup.o smp.o mips_ksyms.o old-irq.o +export-objs = irq.o mips_ksyms.o pci-dma.o setup.o smp.o -obj-y += branch.o cpu-probe.o process.o signal.o entry.o traps.o \ - ptrace.o vm86.o ioport.o reset.o semaphore.o setup.o \ - syscall.o sysmips.o ipc.o scall_o32.o unaligned.o +obj-y += branch.o cpu-probe.o irq.o process.o signal.o entry.o \ + traps.o ptrace.o reset.o semaphore.o setup.o syscall.o \ + sysmips.o ipc.o scall_o32.o unaligned.o obj-$(CONFIG_MODULES) += mips_ksyms.o @@ -39,9 +39,6 @@ obj-$(CONFIG_SMP) += smp.o -# Old style irq support, going to die in 2.5. -obj-$(CONFIG_NEW_IRQ) += irq.o -obj-$(CONFIG_ROTTEN_IRQ) += old-irq.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o @@ -53,11 +50,9 @@ obj-$(CONFIG_BINFMT_IRIX) += irixelf.o irixioctl.o irixsig.o sysirix.o \ irixinv.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb-low.o gdb-stub.o +obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o obj-$(CONFIG_PROC_FS) += proc.o -obj-$(CONFIG_NEW_PCI) += pci.o -obj-$(CONFIG_PCI_AUTO) += pci_auto.o ifndef CONFIG_MAPPED_PCI_IO obj-y += pci-dma.o endif diff -urN linux-2.4.21/arch/mips/kernel/branch.c linux-2.4.22/arch/mips/kernel/branch.c --- linux-2.4.21/arch/mips/kernel/branch.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/kernel/branch.c 2003-08-25 04:44:40.000000000 -0700 @@ -163,10 +163,10 @@ * And now the FPA/cp1 branch instructions. */ case cop1_op: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) fcr31 = current->thread.fpu.soft.sr; else - asm("cfc1\t%0,$31":"=r" (fcr31)); + asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; diff -urN linux-2.4.21/arch/mips/kernel/cpu-probe.c linux-2.4.22/arch/mips/kernel/cpu-probe.c --- linux-2.4.21/arch/mips/kernel/cpu-probe.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/cpu-probe.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,6 +3,7 @@ #include #include #include +#include #include /* @@ -16,14 +17,14 @@ static void r3081_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | R30XX_CONF_HALT); } static void r39xx_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); } static void r4k_wait(void) @@ -39,23 +40,29 @@ /* using the wait instruction makes CP0 counter unusable */ __asm__(".set\tmips3\n\t" "wait\n\t" - "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0"); + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\tmips0"); #else - __asm__("nop\n\t" "nop\n\t"); + __asm__("nop\n\t" + "nop"); #endif } static inline void check_wait(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; + printk("Checking for 'wait' instruction... "); - switch(mips_cpu.cputype) { + switch (c->cputype) { case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; printk(" available.\n"); break; case CPU_TX3927: - case CPU_TX39XX: cpu_wait = r39xx_wait; printk(" available.\n"); break; @@ -104,12 +111,12 @@ #ifdef CONFIG_CPU_R3000 extern unsigned long r3k_cache_size(unsigned long); unsigned long size1, size2; - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); + unsigned long cfg = read_c0_conf(); size1 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC); + write_c0_conf(cfg ^ R30XX_CONF_AC); size2 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg); + write_c0_conf(cfg); return size1 != size2; #else return 0; @@ -123,143 +130,138 @@ { unsigned long tmp, fpu_id; - tmp = read_32bit_cp0_register(CP0_STATUS); + tmp = read_c0_status(); __enable_fpu(); fpu_id = read_32bit_cp1_register(CP1_REVISION); - write_32bit_cp0_register(CP0_STATUS, tmp); + write_c0_status(tmp); return fpu_id; } /* * Check the CPU has an FPU the official way. */ -static inline int cpu_has_fpu(void) +static inline int __cpu_has_fpu(void) { return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); } -/* declaration of the global struct */ -struct mips_cpu mips_cpu = { - processor_id: PRID_IMP_UNKNOWN, - fpu_id: FPIR_IMP_NONE, - cputype: CPU_UNKNOWN -}; - -/* Shortcut for assembler access to mips_cpu.options */ -int *cpuoptions = &mips_cpu.options; - #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) __init void cpu_probe(void) { -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG); + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long config0 = read_c0_config(); unsigned long config1; + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + if (config0 & (1 << 31)) { /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC; - config1 = read_mips32_cp0_config1(); + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; + c->options |= MIPS_CPU_WATCH; if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; + c->options |= MIPS_CPU_MIPS16; if (config1 & (1 << 1)) - mips_cpu.options |= MIPS_CPU_EJTAG; + c->options |= MIPS_CPU_EJTAG; if (config1 & 1) { - mips_cpu.options |= MIPS_CPU_FPU; -#if defined(CONFIG_CPU_MIPS64) - mips_cpu.options |= MIPS_CPU_32FPR; -#endif + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; } - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; } -#endif - mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); - switch (mips_cpu.processor_id & 0xff0000) { + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { case PRID_COMP_LEGACY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_R2000: - mips_cpu.cputype = CPU_R2000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R3000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) + if ((c->processor_id & 0xff) == PRID_REV_R3000A) if (cpu_has_confreg()) - mips_cpu.cputype = CPU_R3081E; + c->cputype = CPU_R3081E; else - mips_cpu.cputype = CPU_R3000A; + c->cputype = CPU_R3000A; else - mips_cpu.cputype = CPU_R3000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R4000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) - mips_cpu.cputype = CPU_R4400SC; + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; else - mips_cpu.cputype = CPU_R4000SC; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH | - MIPS_CPU_VCE; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_VR41XX: - switch (mips_cpu.processor_id & 0xf0) { + switch (c->processor_id & 0xf0) { #ifndef CONFIG_VR4181 case PRID_REV_VR4111: - mips_cpu.cputype = CPU_VR4111; + c->cputype = CPU_VR4111; break; #else case PRID_REV_VR4181: - mips_cpu.cputype = CPU_VR4181; + c->cputype = CPU_VR4181; break; #endif case PRID_REV_VR4121: - mips_cpu.cputype = CPU_VR4121; + c->cputype = CPU_VR4121; break; case PRID_REV_VR4122: - if ((mips_cpu.processor_id & 0xf) < 0x3) - mips_cpu.cputype = CPU_VR4122; + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; else - mips_cpu.cputype = CPU_VR4181A; + c->cputype = CPU_VR4181A; break; case PRID_REV_VR4131: - mips_cpu.cputype = CPU_VR4131; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_VR4131; break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - mips_cpu.cputype = CPU_VR41XX; + c->cputype = CPU_VR41XX; break; } - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS; - mips_cpu.tlbsize = 32; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; break; case PRID_IMP_R4300: - mips_cpu.cputype = CPU_R4300; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R4600: - mips_cpu.cputype = CPU_R4600; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #if 0 case PRID_IMP_R4650: @@ -269,101 +271,97 @@ * for documentation. Commented out because it shares * it's c0_prid id number with the TX3900. */ - mips_cpu.cputype = CPU_R4650; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #endif case PRID_IMP_TX39: - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; - if ((mips_cpu.processor_id & 0xf0) == + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { - mips_cpu.cputype = CPU_TX3927; - mips_cpu.tlbsize = 64; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_TX3927; + c->tlbsize = 64; } else { - switch (mips_cpu.processor_id & 0xff) { + switch (c->processor_id & 0xff) { case PRID_REV_TX3912: - mips_cpu.cputype = CPU_TX3912; - mips_cpu.tlbsize = 32; + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; case PRID_REV_TX3922: - mips_cpu.cputype = CPU_TX3922; - mips_cpu.tlbsize = 64; + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } } break; case PRID_IMP_R4700: - mips_cpu.cputype = CPU_R4700; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_TX49: - mips_cpu.cputype = CPU_TX49XX; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 4; - mips_cpu.dcache.ways = 4; + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5000: - mips_cpu.cputype = CPU_R5000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5432: - mips_cpu.cputype = CPU_R5432; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5500: - mips_cpu.cputype = CPU_R5500; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_NEVADA: - mips_cpu.cputype = CPU_NEVADA; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_DIVEC; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R6000: - mips_cpu.cputype = CPU_R6000; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R6000A: - mips_cpu.cputype = CPU_R6000A; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_RM7000: - mips_cpu.cputype = CPU_RM7000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; /* * Undocumented RM7000: Bit 29 in the info register of * the RM7000 v2.0 indicates if the TLB has 48 or 64 @@ -372,118 +370,139 @@ * 29 1 => 64 entry JTLB * 0 => 48 entry JTLB */ - mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48; + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; break; case PRID_IMP_R8000: - mips_cpu.cputype = CPU_R8000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 384; /* has weird TLB: 3-way x 128 */ + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ break; case PRID_IMP_R10000: - mips_cpu.cputype = CPU_R10000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; case PRID_IMP_R12000: - mips_cpu.cputype = CPU_R12000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) case PRID_COMP_MIPS: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: - mips_cpu.cputype = CPU_4KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KEC: - mips_cpu.cputype = CPU_4KEC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KSC: - mips_cpu.cputype = CPU_4KSC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_5KC: - mips_cpu.cputype = CPU_5KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; break; case PRID_IMP_20KC: - mips_cpu.cputype = CPU_20KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; case PRID_COMP_ALCHEMY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: - switch ((mips_cpu.processor_id >> 24) & 0xff) { + switch ((c->processor_id >> 24) & 0xff) { case 0: - mips_cpu.cputype = CPU_AU1000; + c->cputype = CPU_AU1000; break; case 1: - mips_cpu.cputype = CPU_AU1500; + c->cputype = CPU_AU1500; break; case 2: - mips_cpu.cputype = CPU_AU1100; + c->cputype = CPU_AU1100; break; default: panic("Unknown Au Core!"); break; } - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->isa_level = MIPS_CPU_ISA_M32; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#endif /* CONFIG_CPU_MIPS32 */ case PRID_COMP_SIBYTE: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_SB1: - mips_cpu.cputype = CPU_SB1; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_MCHECK; + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS /* FPU in pass1 is known to have issues. */ - mips_cpu.options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; #endif break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; + break; + } + break; + + case PRID_COMP_SANDCRAFT: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; break; } break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; } - if (mips_cpu.options & MIPS_CPU_FPU) - mips_cpu.fpu_id = cpu_get_fpu_id(); + if (c->options & MIPS_CPU_FPU) + c->fpu_id = cpu_get_fpu_id(); } __init void cpu_report(void) { - printk("CPU revision is: %08x\n", mips_cpu.processor_id); - if (mips_cpu.options & MIPS_CPU_FPU) - printk("FPU revision is: %08x\n", mips_cpu.fpu_id); + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("CPU revision is: %08x\n", c->processor_id); + if (c->options & MIPS_CPU_FPU) + printk("FPU revision is: %08x\n", c->fpu_id); } diff -urN linux-2.4.21/arch/mips/kernel/entry.S linux-2.4.22/arch/mips/kernel/entry.S --- linux-2.4.21/arch/mips/kernel/entry.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -28,7 +28,7 @@ .text - .align 4 + .align 5 .set push .set reorder FEXPORT(ret_from_irq) @@ -100,6 +100,9 @@ * and R4400 SC and MC versions. */ NESTED(except_vec3_generic, 0, sp) +#if R5432_CP0_INTERRUPT_WAR + mfc0 k0, CP0_INDEX +#endif mfc0 k1, CP0_CAUSE la k0, exception_handlers andi k1, k1, 0x7c @@ -114,9 +117,6 @@ .set push .set mips3 .set noat -#if defined(R5432_CP0_INTERRUPT_WAR) - mfc0 k0, CP0_INDEX -#endif mfc0 k1, CP0_CAUSE li k0, 31<<2 andi k1, k1, 0x7c @@ -232,6 +232,7 @@ BUILD_HANDLER(ov,ov,sti,silent) /* #12 */ BUILD_HANDLER(tr,tr,sti,silent) /* #13 */ BUILD_HANDLER(fpe,fpe,fpe,silent) /* #15 */ + BUILD_HANDLER(mdmx,mdmx,sti,silent) /* #22 */ BUILD_HANDLER(watch,watch,sti,silent) /* #23 */ BUILD_HANDLER(mcheck,mcheck,cli,silent) /* #24 */ BUILD_HANDLER(reserved,reserved,sti,silent) /* others */ diff -urN linux-2.4.21/arch/mips/kernel/gdb-low.S linux-2.4.22/arch/mips/kernel/gdb-low.S --- linux-2.4.21/arch/mips/kernel/gdb-low.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/gdb-low.S 2003-08-25 04:44:40.000000000 -0700 @@ -14,6 +14,16 @@ #include /* + * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) + * part is used to store registers and passed to exception handler. + * The upper part is reserved for "call func" feature where gdb client + * saves some of the regs, setups call frame and passes args. + * + * A trace shows about 200 bytes are used to store about half of all regs. + * The rest should be big enough for frame setup and passing args. + */ + +/* * The low level trap handler */ .align 5 @@ -38,7 +48,7 @@ nop 1: move k0,sp - subu sp,k1,GDB_FR_SIZE + subu sp,k1,GDB_FR_SIZE*2 # see comment above sw k0,GDB_FR_REG29(sp) sw v0,GDB_FR_REG2(sp) diff -urN linux-2.4.21/arch/mips/kernel/gdb-stub.c linux-2.4.22/arch/mips/kernel/gdb-stub.c --- linux-2.4.21/arch/mips/kernel/gdb-stub.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/gdb-stub.c 2003-08-25 04:44:40.000000000 -0700 @@ -11,6 +11,9 @@ * Send complaints, suggestions etc. to * * Copyright (C) 1995 Andreas Busse + * + * Copyright (C) 2003 MontaVista Software Inc + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net */ /* @@ -99,7 +102,7 @@ * the kernel running. It will promptly halt and wait * for the host gdb session to connect. It does this * since the "Kernel Hacking" option has defined - * CONFIG_REMOTE_DEBUG which in turn enables your calls + * CONFIG_KGDB which in turn enables your calls * to: * set_debug_traps(); * breakpoint(); @@ -127,6 +130,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -135,6 +142,8 @@ #include #include +#include + /* * external low-level support routines */ @@ -148,6 +157,8 @@ */ extern void breakpoint(void); extern void breakinst(void); +extern void async_breakpoint(void); +extern void async_breakinst(void); extern void adel(void); /* @@ -163,6 +174,12 @@ void handle_exception(struct gdb_regs *regs); /* + * spin locks for smp case + */ +static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED}; + +/* * BUFMAX defines the maximum number of characters in inbound/outbound buffers * at least NUMREGBYTES*2 are needed for register packets */ @@ -171,12 +188,13 @@ static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; static int initialized; /* !0 means we've been initialized */ +static int kgdb_started; static const char hexchars[]="0123456789abcdef"; /* Used to prevent crashes in memory access. Note that they'll crash anyway if we haven't set up fault handlers yet... */ -int kgdb_read_byte(unsigned *address, unsigned *dest); -int kgdb_write_byte(unsigned val, unsigned *dest); +int kgdb_read_byte(unsigned char *address, unsigned char *dest); +int kgdb_write_byte(unsigned char val, unsigned char *dest); /* * Convert ch from a hex digit to an int @@ -394,6 +412,17 @@ restore_flags(flags); } +void restore_debug_traps(void) +{ + struct hard_trap_info *ht; + unsigned long flags; + + save_and_cli(flags); + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + set_except_vector(ht->tt, saved_vectors[ht->tt]); + restore_flags(flags); +} + /* * Convert the MIPS hardware trap type code to a Unix signal number. */ @@ -572,12 +601,39 @@ */ static struct gdb_bp_save async_bp; -void set_async_breakpoint(unsigned int epc) +/* + * Swap the interrupted EPC with our asynchronous breakpoint routine. + * This is safer than stuffing the breakpoint in-place, since no cache + * flushes (or resulting smp_call_functions) are required. The + * assumption is that only one CPU will be handling asynchronous bp's, + * and only one can be active at a time. + */ +extern spinlock_t smp_call_lock; +void set_async_breakpoint(unsigned long *epc) { - async_bp.addr = epc; - async_bp.val = *(unsigned *)epc; - *(unsigned *)epc = BP; - __flush_cache_all(); + /* skip breaking into userland */ + if ((*epc & 0x80000000) == 0) + return; + + /* avoid deadlock if someone is make IPC */ + if (spin_is_locked(&smp_call_lock)) + return; + + async_bp.addr = *epc; + *epc = (unsigned long)async_breakpoint; +} + +void kgdb_wait(void *arg) +{ + unsigned flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + + spin_lock(&kgdb_cpulock[cpu]); + spin_unlock(&kgdb_cpulock[cpu]); + + local_irq_restore(flags); } @@ -594,31 +650,45 @@ int length; char *ptr; unsigned long *stack; + int i; -#if 0 - printk("in handle_exception()\n"); - show_gdbregs(regs); -#endif + kgdb_started = 1; /* - * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1, - * the simply switch the FPU on and return since this is no error - * condition. kernel/traps.c does the same. - * FIXME: This doesn't work yet, so we don't catch CPU_UNUSABLE - * traps for now. + * acquire the big kgdb spinlock */ - trap = (regs->cp0_cause & 0x7c) >> 2; -/* printk("trap=%d\n",trap); */ - if (trap == 11) { - if (((regs->cp0_cause >> CAUSEB_CE) & 3) == 1) { - regs->cp0_status |= ST0_CU1; - return; - } + if (!spin_trylock(&kgdb_lock)) { + /* + * some other CPU has the lock, we should go back to + * receive the gdb_wait IPC + */ + return; } /* + * If we're in async_breakpoint(), restore the real EPC from + * the breakpoint. + */ + if (regs->cp0_epc == (unsigned long)async_breakinst) { + regs->cp0_epc = async_bp.addr; + async_bp.addr = 0; + } + + /* + * acquire the CPU spinlocks + */ + for (i=0; i< smp_num_cpus; i++) + db_verify(spin_trylock(&kgdb_cpulock[i]), != 0); + + /* + * force other cpus to enter kgdb + */ + smp_call_function(kgdb_wait, NULL, 0, 0); + + /* * If we're in breakpoint() increment the PC */ + trap = (regs->cp0_cause & 0x7c) >> 2; if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) regs->cp0_epc += 4; @@ -636,16 +706,6 @@ } } - /* - * If we were interrupted asynchronously by gdb, then a - * breakpoint was set at the EPC of the interrupt so - * that we'd wind up here with an interesting stack frame. - */ - if (async_bp.addr) { - *(unsigned *)async_bp.addr = async_bp.val; - async_bp.addr = 0; - } - stack = (long *)regs->reg29; /* stack ptr */ sigval = computeSignal(trap); @@ -707,6 +767,14 @@ output_buffer[3] = 0; break; + /* + * Detach debugger; let CPU run + */ + case 'D': + putpacket(output_buffer); + goto finish_kgdb; + break; + case 'd': /* toggle debug flag */ break; @@ -726,26 +794,21 @@ /* * set the value of the CPU registers - return OK - * FIXME: Needs to be written */ case 'G': { -#if 0 - unsigned long *newsp, psr; - ptr = &input_buffer[1]; - hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */ - - /* - * See if the stack pointer has moved. If so, then copy the - * saved locals and ins to the new location. - */ - - newsp = (unsigned long *)registers[SP]; - if (sp != newsp) - sp = memcpy(newsp, sp, 16 * 4); - -#endif + hex2mem(ptr, (char *)®s->reg0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp0_status, 6*4, 0); + ptr += 6*8; + hex2mem(ptr, (char *)®s->fpr0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp1_fsr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->frame_ptr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->cp0_index, 16*4, 0); strcpy(output_buffer,"OK"); } break; @@ -794,36 +857,19 @@ ptr = &input_buffer[1]; if (hexToInt(&ptr, &addr)) regs->cp0_epc = addr; - - /* - * Need to flush the instruction cache here, as we may - * have deposited a breakpoint, and the icache probably - * has no way of knowing that a data ref to some location - * may have changed something that is in the instruction - * cache. - * NB: We flush both caches, just to be sure... - */ - - __flush_cache_all(); - return; - /* NOTREACHED */ + + goto exit_kgdb_exception; break; - - /* - * kill the program - */ - case 'k' : - break; /* do nothing */ - - /* - * Reset the whole machine (FIXME: system dependent) + * kill the program; let us try to restart the machine + * Reset the whole machine. */ + case 'k': case 'r': + machine_restart("kgdb restarts machine"); break; - /* * Step to next instruction */ @@ -833,9 +879,9 @@ * use breakpoints and continue, instead. */ single_step(regs); - __flush_cache_all(); - return; + goto exit_kgdb_exception; /* NOTREACHED */ + break; /* * Set baud rate (bBB) @@ -890,6 +936,20 @@ putpacket(output_buffer); } /* while */ + + return; + +finish_kgdb: + restore_debug_traps(); + +exit_kgdb_exception: + /* release locks so other CPUs can go */ + for (i=0; i < smp_num_cpus; i++) + spin_unlock(&kgdb_cpulock[i]); + spin_unlock(&kgdb_lock); + + __flush_cache_all(); + return; } /* @@ -903,23 +963,50 @@ if (!initialized) return; - __asm__ __volatile__(" - .globl breakinst - .set noreorder - nop -breakinst: break - nop - .set reorder - "); + __asm__ __volatile__( + ".globl breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); +} + +/* Nothing but the break; don't pollute any registers */ +void async_breakpoint(void) +{ + __asm__ __volatile__( + ".globl async_breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "async_breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); } void adel(void) { - __asm__ __volatile__(" - .globl adel - la $8,0x80000001 - lw $9,0($8) - "); + __asm__ __volatile__( + ".globl\tadel\n\t" + "la\t$8,0x80000001\n\t" + "lw\t$9,0($8)\n\t" + ); +} + +/* + * malloc is needed by gdb client in "call func()", even a private one + * will make gdb happy + */ +static void *malloc(size_t size) +{ + return kmalloc(size, GFP_ATOMIC); +} + +static void free(void *where) +{ + kfree(where); } #ifdef CONFIG_GDB_CONSOLE @@ -928,6 +1015,9 @@ { char outbuf[18]; + if (!kgdb_started) + return; + outbuf[0]='O'; while(l) { @@ -951,11 +1041,11 @@ } static struct console gdb_console = { - name: "gdb", - write: gdb_console_write, - device: gdb_console_dev, - flags: CON_PRINTBUFFER, - index: -1 + .name = "gdb", + .write = gdb_console_write, + .device = gdb_console_dev, + .flags = CON_PRINTBUFFER, + .index = -1 }; __init void register_gdb_console(void) diff -urN linux-2.4.21/arch/mips/kernel/head.S linux-2.4.22/arch/mips/kernel/head.S --- linux-2.4.21/arch/mips/kernel/head.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -91,6 +91,8 @@ nop END(except_vec_ejtag_debug) + __FINIT + /* * EJTAG debug exception handler. */ @@ -114,11 +116,15 @@ ejtag_return: mfc0 k0, CP0_DESAVE - .word 0x4200001f # DERET, return from EJTAG debug exception. + .set mips32 + deret + .set mips0 nop .set at END(ejtag_debug_handler) + __INIT + /* * NMI debug exception handler for MIPS reference boards. * The NMI debug exception entry point is 0xbfc00000, which @@ -130,6 +136,8 @@ nop END(except_vec_nmi) + __FINIT + NESTED(nmi_handler, PT_SIZE, sp) .set noat .set noreorder @@ -143,6 +151,8 @@ .set mips0 END(nmi_handler) + __INIT + /* * Kernel entry point */ diff -urN linux-2.4.21/arch/mips/kernel/i8259.c linux-2.4.22/arch/mips/kernel/i8259.c --- linux-2.4.21/arch/mips/kernel/i8259.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/i8259.c 2003-08-25 04:44:40.000000000 -0700 @@ -15,6 +15,7 @@ #include #include +#include #include void enable_8259A_irq(unsigned int irq); diff -urN linux-2.4.21/arch/mips/kernel/ioport.c linux-2.4.22/arch/mips/kernel/ioport.c --- linux-2.4.21/arch/mips/kernel/ioport.c 1997-06-26 12:33:37.000000000 -0700 +++ linux-2.4.22/arch/mips/kernel/ioport.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,34 +0,0 @@ -/* - * linux/arch/mips/kernel/ioport.c - */ -#include -#include -#include -#include -#include - -/* - * This changes the io permissions bitmap in the current task. - */ -asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) -{ - return -ENOSYS; -} - -/* - * sys_iopl has to be used when you want to access the IO ports - * beyond the 0x3ff range: to get the full 65536 ports bitmapped - * you'd need 8kB of bitmaps/process, which is a bit excessive. - * - * Here we just change the eflags value on the stack: we allow - * only the super-user to do it. This depends on the stack-layout - * on system-call entry - see also fork() and the signal handling - * code. - */ -asmlinkage int sys_iopl(long ebx,long ecx,long edx, - long esi, long edi, long ebp, long eax, long ds, - long es, long fs, long gs, long orig_eax, - long eip,long cs,long eflags,long esp,long ss) -{ - return -ENOSYS; -} diff -urN linux-2.4.21/arch/mips/kernel/ipc.c linux-2.4.22/arch/mips/kernel/ipc.c --- linux-2.4.21/arch/mips/kernel/ipc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/ipc.c 2003-08-25 04:44:40.000000000 -0700 @@ -93,6 +93,6 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } diff -urN linux-2.4.21/arch/mips/kernel/irixelf.c linux-2.4.22/arch/mips/kernel/irixelf.c --- linux-2.4.21/arch/mips/kernel/irixelf.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/irixelf.c 2003-08-25 04:44:40.000000000 -0700 @@ -574,7 +574,7 @@ pp = (struct prda *) v; pp->prda_sys.t_pid = current->pid; - pp->prda_sys.t_prid = read_32bit_cp0_register (CP0_PRID); + pp->prda_sys.t_prid = read_c0_prid(); pp->prda_sys.t_rpid = current->pid; /* We leave the rest set to zero */ diff -urN linux-2.4.21/arch/mips/kernel/irixinv.c linux-2.4.22/arch/mips/kernel/irixinv.c --- linux-2.4.21/arch/mips/kernel/irixinv.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/irixinv.c 2003-08-25 04:44:40.000000000 -0700 @@ -16,8 +16,7 @@ static inventory_t inventory [MAX_INVENTORY]; -void -add_to_inventory (int class, int type, int controller, int unit, int state) +void add_to_inventory (int class, int type, int controller, int unit, int state) { inventory_t *ni = &inventory [inventory_items]; @@ -33,8 +32,7 @@ inventory_items++; } -int -dump_inventory_to_user (void *userbuf, int size) +int dump_inventory_to_user (void *userbuf, int size) { inventory_t *inv = &inventory [0]; inventory_t *user = userbuf; @@ -51,13 +49,13 @@ return inventory_items * sizeof (inventory_t); } -void __init init_inventory (void) +static int __init init_inventory(void) { - /* gross hack while we put the right bits all over the kernel + /* + * gross hack while we put the right bits all over the kernel * most likely this will not let just anyone run the X server * until we put the right values all over the place */ - add_to_inventory (10, 3, 0, 0, 16400); add_to_inventory (1, 1, 150, -1, 12); add_to_inventory (1, 3, 0, 0, 8976); @@ -76,6 +74,8 @@ add_to_inventory (2, 2, 0, 2, 0); add_to_inventory (2, 2, 0, 1, 0); add_to_inventory (7, 14, 0, 0, 6); + + return 0; } module_init(init_inventory); diff -urN linux-2.4.21/arch/mips/kernel/irixsig.c linux-2.4.22/arch/mips/kernel/irixsig.c --- linux-2.4.21/arch/mips/kernel/irixsig.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/irixsig.c 2003-08-25 04:44:40.000000000 -0700 @@ -116,7 +116,8 @@ regs->regs[5] = 0; /* XXX sigcode XXX */ regs->regs[6] = regs->regs[29] = sp; regs->regs[7] = (unsigned long) ka->sa.sa_handler; - regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa.sa_restorer; + regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; + return; segv_and_exit: @@ -407,7 +408,7 @@ * value for all invocations of sigaction. Will have to * investigate. POSIX POSIX, die die die... */ - new_ka.sa.sa_restorer = trampoline; + new_ka.sa_restorer = trampoline; } /* XXX Implement SIG_SETMASK32 for IRIX compatibility */ diff -urN linux-2.4.21/arch/mips/kernel/irq.c linux-2.4.22/arch/mips/kernel/irq.c --- linux-2.4.21/arch/mips/kernel/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -211,7 +211,7 @@ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { diff -urN linux-2.4.21/arch/mips/kernel/irq_cpu.c linux-2.4.22/arch/mips/kernel/irq_cpu.c --- linux-2.4.21/arch/mips/kernel/irq_cpu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/irq_cpu.c 2003-08-25 04:44:40.000000000 -0700 @@ -31,13 +31,13 @@ static void mips_cpu_irq_enable(unsigned int irq) { - clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8)); - set_cp0_status(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_cause( 1 << (irq - mips_cpu_irq_base + 8)); + set_c0_status(1 << (irq - mips_cpu_irq_base + 8)); } static void mips_cpu_irq_disable(unsigned int irq) { - clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_status(1 << (irq - mips_cpu_irq_base + 8)); } static unsigned int mips_cpu_irq_startup(unsigned int irq) @@ -51,10 +51,10 @@ static void mips_cpu_irq_ack(unsigned int irq) { - /* although we attemp to clear the IP bit in cause reigster, I think + /* although we attempt to clear the IP bit in cause register, I think * usually it is cleared by device (irq source) */ - clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8)); /* disable this interrupt - so that we safe proceed to the handler */ mips_cpu_irq_disable(irq); @@ -62,7 +62,7 @@ static void mips_cpu_irq_end(unsigned int irq) { - if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) mips_cpu_irq_enable(irq); } diff -urN linux-2.4.21/arch/mips/kernel/mips_ksyms.c linux-2.4.22/arch/mips/kernel/mips_ksyms.c --- linux-2.4.21/arch/mips/kernel/mips_ksyms.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/mips_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -24,11 +24,9 @@ #include #include #include -#include -#include #include #include -#ifdef CONFIG_BLK_DEV_FD +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) #include #endif @@ -86,7 +84,6 @@ /* * Functions to control caches. */ -EXPORT_SYMBOL(_flush_page_to_ram); EXPORT_SYMBOL(_flush_cache_all); EXPORT_SYMBOL(invalid_pte_table); @@ -100,21 +97,6 @@ EXPORT_SYMBOL(__up); /* - * Architecture specific stuff. - */ -#ifdef CONFIG_MIPS_JAZZ -EXPORT_SYMBOL(vdma_alloc); -EXPORT_SYMBOL(vdma_free); -EXPORT_SYMBOL(vdma_log2phys); -#endif - -#ifdef CONFIG_SGI_IP22 -EXPORT_SYMBOL(hpc3c0); -EXPORT_SYMBOL(hpc3c1); -EXPORT_SYMBOL(mcmisc_regs); -#endif - -/* * Kernel hacking ... */ #include diff -urN linux-2.4.21/arch/mips/kernel/old-irq.c linux-2.4.22/arch/mips/kernel/old-irq.c --- linux-2.4.21/arch/mips/kernel/old-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/old-irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,408 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Code to handle x86 style IRQs plus some generic interrupt stuff. - * - * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1994 - 2001 Ralf Baechle - * - * Old rotten IRQ code. To be killed as soon as everybody had converted or - * in 2.5.0, whatever comes first. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * The board specific setup routine sets irq_setup to point to a board - * specific setup routine. - */ -void (*irq_setup)(void); - -/* - * Linux has a controller-independent x86 interrupt architecture. - * every controller has a 'controller-template', that is used - * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate - * controller. Thus drivers need not be aware of the - * interrupt-controller. - * - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. - * (IO-APICs assumed to be messaging to Pentium local-APICs) - * - * the code is designed to be easily extended with new/different - * interrupt controllers, without having to do assembly magic. - */ - -/* - * This contains the irq mask for both 8259A irq controllers, it's an - * int so we can deal with the third PIC in some systems like the RM300. - * (XXX This is broken for big endian.) - */ -static unsigned int cached_irq_mask = 0xffff; - -#define __byte(x,y) (((unsigned char *)&(y))[x]) -#define __word(x,y) (((unsigned short *)&(y))[x]) -#define __long(x,y) (((unsigned int *)&(y))[x]) - -#define cached_21 (__byte(0,cached_irq_mask)) -#define cached_A1 (__byte(1,cached_irq_mask)) - -volatile unsigned long irq_err_count; - -/* - * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and - * PCI devices. Other onboard hardware needs specific routines. - */ -static inline void mask_irq(unsigned int irq) -{ - cached_irq_mask |= 1 << irq; - if (irq & 8) { - outb(cached_A1, 0xa1); - } else { - outb(cached_21, 0x21); - } -} - -static inline void unmask_irq(unsigned int irq) -{ - cached_irq_mask &= ~(1 << irq); - if (irq & 8) { - outb(cached_A1, 0xa1); - } else { - outb(cached_21, 0x21); - } -} - -void i8259_disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - mask_irq(irq_nr); - restore_flags(flags); -} - -void i8259_enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - save_and_cli(flags); - unmask_irq(irq_nr); - restore_flags(flags); -} - -static struct irqaction *irq_action[NR_IRQS] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -int get_irq_list(char *buf) -{ - int i, len = 0; - struct irqaction * action; - - for (i = 0 ; i < 32 ; i++) { - action = irq_action[i]; - if (!action) - continue; - len += sprintf(buf+len, "%2d: %8d %c %s", - i, kstat.irqs[0][i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - len += sprintf(buf+len, "\n"); - } - return len; -} - -static inline void i8259_mask_and_ack_irq(int irq) -{ - cached_irq_mask |= 1 << irq; - - if (irq & 8) { - inb(0xa1); - outb(cached_A1, 0xa1); - outb(0x62, 0x20); /* Specific EOI to cascade */ - outb(0x20, 0xa0); - } else { - inb(0x21); - outb(cached_21, 0x21); - outb(0x20, 0x20); - } -} - -asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - - if (irq >= 16) - goto out; - - i8259_mask_and_ack_irq(irq); - - kstat.irqs[cpu][irq]++; - - action = *(irq + irq_action); - if (!action) - goto out; - - if (!(action->flags & SA_INTERRUPT)) - __sti(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - __cli(); - unmask_irq (irq); - -out: - irq_exit(cpu, irq); -} - -/* - * do_IRQ handles IRQ's that have been installed without the - * SA_INTERRUPT flag: it uses the full signal-handling return - * and runs with other interrupts enabled. All relatively slow - * IRQ's should use this format: notably the keyboard/timer - * routines. - */ -asmlinkage void do_IRQ(int irq, struct pt_regs * regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; - - action = *(irq + irq_action); - if (action) { - if (!(action->flags & SA_INTERRUPT)) - __sti(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - __cli(); - } - irq_exit(cpu, irq); - - if (softirq_pending(cpu)) - do_softirq(); - - /* unmasking and bottom half handling is done magically for us. */ -} - -int i8259_setup_irq(int irq, struct irqaction * new) -{ - int shared = 0; - struct irqaction *old, **p; - unsigned long flags; - - p = irq_action + irq; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) - return -EBUSY; - - /* Can't share interrupts unless both are same type */ - if ((old->flags ^ new->flags) & SA_INTERRUPT) - return -EBUSY; - - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; - } - - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - save_and_cli(flags); - *p = new; - - if (!shared) { - if (is_i8259_irq(irq)) - unmask_irq(irq); -#if (defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476)) - else - nile4_enable_irq(irq_to_nile4(irq)); -#endif - } - restore_flags(flags); - return 0; -} - -/* - * Request_interrupt and free_interrupt ``sort of'' handle interrupts of - * non i8259 devices. They will have to be replaced by architecture - * specific variants. For now we still use this as broken as it is because - * it used to work ... - */ -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char * devname, void *dev_id) -{ - int retval; - struct irqaction * action; - - if (irq >= 32) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - - retval = i8259_setup_irq(irq, action); - - if (retval) - kfree(action); - return retval; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction * action, **p; - unsigned long flags; - - if (irq > 31) { - printk("Trying to free IRQ%d\n",irq); - return; - } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - save_and_cli(flags); - *p = action->next; - if (!irq[irq_action]) - mask_irq(irq); - restore_flags(flags); - kfree(action); - return; - } - printk("Trying to free free IRQ%d\n",irq); -} - -unsigned long probe_irq_on (void) -{ - unsigned int i, irqs = 0; - unsigned long delay; - - /* first, enable any unassigned (E)ISA irqs */ - for (i = 15; i > 0; i--) { - if (!irq_action[i]) { - i8259_enable_irq(i); - irqs |= (1 << i); - } - } - - /* wait for spurious interrupts to mask themselves out again */ - for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) - /* about 100ms delay */; - - /* now filter out any obviously spurious interrupts */ - return irqs & ~cached_irq_mask; -} - -int probe_irq_off (unsigned long irqs) -{ - unsigned int i; - -#ifdef DEBUG - printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask); -#endif - irqs &= cached_irq_mask; - if (!irqs) - return 0; - i = ffz(~irqs); - if (irqs != (irqs & (1 << i))) - i = -i; - return i; -} - -void __init i8259_init(void) -{ - /* Init master interrupt controller */ - outb(0x11, 0x20); /* Start init sequence */ - outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0x21); /* Select 8086 mode */ - outb(0xff, 0x21); /* Mask all */ - - /* Init slave interrupt controller */ - outb(0x11, 0xa0); /* Start init sequence */ - outb(0x08, 0xa1); /* Vector base */ - outb(0x02, 0xa1); /* edge triggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0xa1); /* Select 8086 mode */ - outb(0xff, 0xa1); /* Mask all */ - - outb(cached_A1, 0xa1); - outb(cached_21, 0x21); -} - -void __init init_IRQ(void) -{ - /* i8259_init(); */ - irq_setup(); -} - -EXPORT_SYMBOL(free_irq); -EXPORT_SYMBOL(request_irq); diff -urN linux-2.4.21/arch/mips/kernel/old-time.c linux-2.4.22/arch/mips/kernel/old-time.c --- linux-2.4.21/arch/mips/kernel/old-time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/old-time.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -94,7 +93,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -414,7 +413,7 @@ * The cycle counter is only 32 bit which is good for about * a minute at current count rates of upto 150MHz or so. */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; @@ -425,7 +424,7 @@ * we need only ask for the next in r4k_interval counts. On other * archs we have a real timer, so we don't want this. */ - write_32bit_cp0_register (CP0_COMPARE, + write_c0_compare( (unsigned long) (count + r4k_interval)); kstat.irqs[0][irq]++; #endif @@ -512,8 +511,8 @@ xtime.tv_usec = 0; write_unlock_irq (&xtime_lock); - if (mips_cpu.options & MIPS_CPU_COUNTER) { - write_32bit_cp0_register(CP0_COUNT, 0); + if (cpu_has_counter) { + write_c0_count(0); do_gettimeoffset = do_fast_gettimeoffset; irq0.handler = r4k_timer_interrupt; } diff -urN linux-2.4.21/arch/mips/kernel/pci-dma.c linux-2.4.22/arch/mips/kernel/pci-dma.c --- linux-2.4.21/arch/mips/kernel/pci-dma.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/pci-dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -21,6 +21,7 @@ { void *ret; int gfp = GFP_ATOMIC; + struct pci_bus *bus = NULL; #ifdef CONFIG_ISA if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) @@ -30,7 +31,9 @@ if (ret != NULL) { memset(ret, 0, size); - *dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret)); + if (hwdev) + bus = hwdev->bus; + *dma_handle = bus_to_baddr(bus, __pa(ret)); #ifdef CONFIG_NONCOHERENT_IO dma_cache_wback_inv((unsigned long) ret, size); ret = UNCAC_ADDR(ret); diff -urN linux-2.4.21/arch/mips/kernel/pci.c linux-2.4.22/arch/mips/kernel/pci.c --- linux-2.4.21/arch/mips/kernel/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,176 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * Modified to be mips generic, ppopov@mvista.com - * arch/mips/kernl/pci.c - * Common MIPS PCI routines. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -/* - * This file contains common PCI routines meant to be shared for - * all MIPS machines. - * - * Strategies: - * - * . We rely on pci_auto.c file to assign PCI resources (MEM and IO) - * TODO: this shold be optional for some machines where they do have - * a real "pcibios" that does resource assignment. - * - * . We then use pci_scan_bus() to "discover" all the resources for - * later use by Linux. - * - * . We finally reply on a board supplied function, pcibios_fixup_irq(), to - * to assign the interrupts. We may use setup-irq.c under drivers/pci - * later. - * - * . Specifically, we will *NOT* use pci_assign_unassigned_resources(), - * because we assume all PCI devices should have the resources correctly - * assigned and recorded. - * - * Limitations: - * - * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus - * into a contiguous range. - * - * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical - * address space. - * - * . In the case of IO space, it starts from 0, and the beginning address - * is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address. - * - * . These are the current MIPS limitations (by ioremap, etc). In the - * future, we may remove them. - * - * Credits: - * Most of the code are derived from the pci routines from PPC and Alpha, - * which were mostly writtne by - * Cort Dougan, cort@fsmlabs.com - * Matt Porter, mporter@mvista.com - * Dave Rusling david.rusling@reo.mts.dec.com - * David Mosberger davidm@cs.arizona.edu - */ -#include -#include -#include -#include -#include - -#include - -extern void pcibios_fixup(void); -extern void pcibios_fixup_irqs(void); - -struct pci_fixup pcibios_fixups[] = { - { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, - { 0 } -}; - -extern int pciauto_assign_resources(int busno, struct pci_channel * hose); - -void __init pcibios_init(void) -{ - struct pci_channel *p; - struct pci_bus *bus; - int busno; - -#ifdef CONFIG_PCI_AUTO - /* assign resources */ - busno=0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - busno = pciauto_assign_resources(busno, p) + 1; - } -#endif - - /* scan the buses */ - busno = 0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate+1; - } - - /* machine dependent fixups */ - pcibios_fixup(); - /* fixup irqs (board specific routines) */ - pcibios_fixup_irqs(); -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - /* pciauto_assign_resources() will enable all devices found */ - return 0; -} - -unsigned long __init pci_bridge_check_io(struct pci_dev *bridge) -{ - u16 io; - - pci_read_config_word(bridge, PCI_IO_BASE, &io); - if (!io) { - pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); - pci_read_config_word(bridge, PCI_IO_BASE, &io); - pci_write_config_word(bridge, PCI_IO_BASE, 0x0); - } - if (io) - return IORESOURCE_IO; - printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n", - bridge->name); - return 0; -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Propogate hose info into the subordinate devices. */ - - struct pci_channel *hose = bus->sysdata; - struct pci_dev *dev = bus->self; - - if (!dev) { - /* Root bus */ - bus->resource[0] = hose->io_resource; - bus->resource[1] = hose->mem_resource; - } else { - /* This is a bridge. Do not care how it's initialized, - just link its resources to the bus ones */ - int i; - - for(i=0; i<3; i++) { - bus->resource[i] = - &dev->resource[PCI_BRIDGE_RESOURCES+i]; - bus->resource[i]->name = bus->name; - } - bus->resource[0]->flags |= pci_bridge_check_io(dev); - bus->resource[1]->flags |= IORESOURCE_MEM; - /* For now, propogate hose limits to the bus; - we'll adjust them later. */ - bus->resource[0]->end = hose->io_resource->end; - bus->resource[1]->end = hose->mem_resource->end; - /* Turn off downstream PF memory address range by default */ - bus->resource[2]->start = 1024*1024; - bus->resource[2]->end = bus->resource[2]->start - 1; - } -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ - /* this should not be called */ -} - -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - /* this should not be called */ -} diff -urN linux-2.4.21/arch/mips/kernel/pci_auto.c linux-2.4.22/arch/mips/kernel/pci_auto.c --- linux-2.4.21/arch/mips/kernel/pci_auto.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/pci_auto.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,394 +0,0 @@ -/* - * PCI autoconfiguration library - * - * Author: Matt Porter - * - * Copyright 2000, 2001 MontaVista Software Inc. - * Copyright 2001 Bradley D. LaRonde - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -/* - * Modified for MIPS by Jun Sun, jsun@mvista.com - * - * . Simplify the interface between pci_auto and the rest: a single function. - * . Assign resources from low address to upper address. - * . change most int to u32. - * - * Further modified to include it as mips generic code, ppopov@mvista.com. - * - * 2001-10-26 Bradley D. LaRonde - * - Add a top_bus argument to the "early config" functions so that - * they can set a fake parent bus pointer to convince the underlying - * pci ops to use type 1 configuration for sub busses. - * - Set bridge base and limit registers correctly. - * - Align io and memory base properly before and after bridge setup. - * - Don't fall through to pci_setup_bars for bridge. - * - Reformat the debug output to look more like lspci's output. - */ - -#include -#include -#include -#include - -#include - -#define DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* - * These functions are used early on before PCI scanning is done - * and all of the pci_dev and pci_bus structures have been created. - */ -static struct pci_dev *fake_pci_dev(struct pci_channel *hose, - int top_bus, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; - - dev.bus = &bus; - dev.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - - if(busnr != top_bus) - /* Fake a parent bus structure. */ - bus.parent = &bus; - else - bus.parent = NULL; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -int early_##rw##_config_##size(struct pci_channel *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, byte, u8 *) -EARLY_PCI_OP(read, word, u16 *) -EARLY_PCI_OP(read, dword, u32 *) -EARLY_PCI_OP(write, byte, u8) -EARLY_PCI_OP(write, word, u16) -EARLY_PCI_OP(write, dword, u32) - -static struct resource *io_resource_inuse; -static struct resource *mem_resource_inuse; - -static u32 pciauto_lower_iospc; -static u32 pciauto_upper_iospc; - -static u32 pciauto_lower_memspc; -static u32 pciauto_upper_memspc; - -void __init -pciauto_setup_bars(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn) -{ - u32 bar_response, bar_size, bar_value; - u32 bar, addr_mask, bar_nr = 0; - u32 * upper_limit; - u32 * lower_limit; - int found_mem64 = 0; - - for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4) { - /* Tickle the BAR and get the response */ - early_write_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - 0xffffffff); - early_read_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - &bar_response); - - /* If BAR is not implemented go to the next BAR */ - if (!bar_response) - continue; - - /* - * Workaround for a BAR that doesn't use its upper word, - * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457). - * bdl - */ - if (!(bar_response & 0xffff0000)) - bar_response |= 0xffff0000; - -retry: - /* Check the BAR type and set our address mask */ - if (bar_response & PCI_BASE_ADDRESS_SPACE) { - addr_mask = PCI_BASE_ADDRESS_IO_MASK; - upper_limit = &pciauto_upper_iospc; - lower_limit = &pciauto_lower_iospc; - DBG(" I/O"); - } else { - if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64) - found_mem64 = 1; - - addr_mask = PCI_BASE_ADDRESS_MEM_MASK; - upper_limit = &pciauto_upper_memspc; - lower_limit = &pciauto_lower_memspc; - DBG(" Mem"); - } - - - /* Calculate requested size */ - bar_size = ~(bar_response & addr_mask) + 1; - - /* Allocate a base address */ - bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; - - if ((bar_value + bar_size) > *upper_limit) { - if (bar_response & PCI_BASE_ADDRESS_SPACE) { - if (io_resource_inuse->child) { - io_resource_inuse = - io_resource_inuse->child; - pciauto_lower_iospc = - io_resource_inuse->start; - pciauto_upper_iospc = - io_resource_inuse->end + 1; - goto retry; - } - - } else { - if (mem_resource_inuse->child) { - mem_resource_inuse = - mem_resource_inuse->child; - pciauto_lower_memspc = - mem_resource_inuse->start; - pciauto_upper_memspc = - mem_resource_inuse->end + 1; - goto retry; - } - } - DBG(" unavailable -- skipping\n"); - continue; - } - - /* Write it out and update our limit */ - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - bar, bar_value); - - *lower_limit = bar_value + bar_size; - - /* - * If we are a 64-bit decoder then increment to the - * upper 32 bits of the bar and force it to locate - * in the lower 4GB of memory. - */ - if (found_mem64) { - bar += 4; - early_write_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - 0x00000000); - } - - DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size); - - bar_nr++; - } - -} - -void __init -pciauto_prescan_setup_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_PRIMARY_BUS, current_bus); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SECONDARY_BUS, sub_bus + 1); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, 0xff); - - /* Align memory and I/O to 1MB and 4KB boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) - & ~(0x100000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) - & ~(0x1000 - 1); - - /* Set base (lower limit) of address range behind bridge. */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_MEMORY_BASE, pciauto_lower_memspc >> 16); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16); - - /* We don't support prefetchable memory for now, so disable */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_PREF_MEMORY_BASE, 0); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_PREF_MEMORY_LIMIT, 0); -} - -void __init -pciauto_postscan_setup_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - u32 temp; - - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, sub_bus); - - /* Set upper limit of address range behind bridge. */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16); - - /* Align memory and I/O to 1MB and 4KB boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) - & ~(0x100000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) - & ~(0x1000 - 1); - - /* Enable memory and I/O accesses, enable bus master */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &temp); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY - | PCI_COMMAND_MASTER); -} - -#define PCIAUTO_IDE_MODE_MASK 0x05 - -int __init -pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) -{ - int sub_bus; - u32 pci_devfn, pci_class, cmdstat, found_multi=0; - unsigned short vid, did; - unsigned char header_type; - int devfn_start = 0; - int devfn_stop = 0xff; - - sub_bus = current_bus; - - if (hose->first_devfn) - devfn_start = hose->first_devfn; - if (hose->last_devfn) - devfn_stop = hose->last_devfn; - - for (pci_devfn=devfn_start; pci_devfn> 16, vid, did); - if (pci_class & 0xff) - DBG(" (rev %.2x)", pci_class & 0xff); - DBG("\n"); - - if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { - DBG(" Bridge: primary=%.2x, secondary=%.2x\n", - current_bus, sub_bus + 1); - pciauto_prescan_setup_bridge(hose, top_bus, current_bus, - pci_devfn, sub_bus); - DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", - sub_bus + 1, - pciauto_lower_iospc, pciauto_lower_memspc); - sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); - DBG("Back to bus %.2x\n", current_bus); - pciauto_postscan_setup_bridge(hose, top_bus, current_bus, - pci_devfn, sub_bus); - continue; - } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { - - unsigned char prg_iface; - - early_read_config_byte(hose, top_bus, current_bus, - pci_devfn, PCI_CLASS_PROG, &prg_iface); - if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { - DBG("Skipping legacy mode IDE controller\n"); - continue; - } - } - - /* - * Found a peripheral, enable some standard - * settings - */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &cmdstat); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, cmdstat | PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_LATENCY_TIMER, 0x80); - - /* Allocate PCI I/O and/or memory space */ - pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn); - } - return sub_bus; -} - -int __init -pciauto_assign_resources(int busno, struct pci_channel *hose) -{ - /* setup resource limits */ - io_resource_inuse = hose->io_resource; - mem_resource_inuse = hose->mem_resource; - - pciauto_lower_iospc = io_resource_inuse->start; - pciauto_upper_iospc = io_resource_inuse->end + 1; - pciauto_lower_memspc = mem_resource_inuse->start; - pciauto_upper_memspc = mem_resource_inuse->end + 1; - DBG("Autoconfig PCI channel 0x%p\n", hose); - DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", - busno, pciauto_lower_iospc, pciauto_upper_iospc, - pciauto_lower_memspc, pciauto_upper_memspc); - - return pciauto_bus_scan(hose, busno, busno); -} diff -urN linux-2.4.21/arch/mips/kernel/proc.c linux-2.4.22/arch/mips/kernel/proc.c --- linux-2.4.21/arch/mips/kernel/proc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/proc.c 2003-08-25 04:44:40.000000000 -0700 @@ -17,10 +17,6 @@ unsigned int vced_count, vcei_count; -#ifndef CONFIG_CPU_HAS_LLSC -unsigned long ll_ops, sc_ops; -#endif - static const char *cpu_name[] = { [CPU_UNKNOWN] "unknown", [CPU_R2000] "R2000", @@ -66,21 +62,21 @@ [CPU_VR41XX] "NEC Vr41xx", [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", - [CPU_TX39XX] "TX39xx", [CPU_20KC] "MIPS 20Kc", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", [CPU_VR4181] "NEC VR4181", - [CPU_VR4181A] "NEC VR4181A" + [CPU_VR4181A] "NEC VR4181A", + [CPU_SR71000] "Sandcraft SR71000" }; static int show_cpuinfo(struct seq_file *m, void *v) { - unsigned int version = mips_cpu.processor_id; - unsigned int fp_vers = mips_cpu.fpu_id; + unsigned int version = current_cpu_data.processor_id; + unsigned int fp_vers = current_cpu_data.fpu_id; unsigned long n = (unsigned long) v - 1; char fmt [64]; @@ -97,9 +93,9 @@ seq_printf(m, "processor\t\t: %ld\n", n); sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", - (mips_cpu.options & MIPS_CPU_FPU) ? " FPU V%d.%d" : ""); - seq_printf(m, fmt, cpu_name[mips_cpu.cputype <= CPU_LAST ? - mips_cpu.cputype : CPU_UNKNOWN], + cpu_has_fpu ? " FPU V%d.%d" : ""); + seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ? + current_cpu_data.cputype : CPU_UNKNOWN], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", @@ -107,23 +103,18 @@ (loops_per_jiffy / (5000/HZ)) % 100); seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); seq_printf(m, "microsecond timers\t: %s\n", - (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no"); - seq_printf(m, "tlb_entries\t\t: %d\n", mips_cpu.tlbsize); + cpu_has_counter ? "yes" : "no"); + seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize); seq_printf(m, "extra interrupt vector\t: %s\n", - (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no"); + cpu_has_divec ? "yes" : "no"); seq_printf(m, "hardware watchpoint\t: %s\n", - watch_available ? "yes" : "no"); + cpu_has_watch ? "yes" : "no"); sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", - (mips_cpu.options & MIPS_CPU_VCE) ? "%d" : "not available"); + cpu_has_vce ? "%d" : "not available"); seq_printf(m, fmt, 'D', vced_count); seq_printf(m, fmt, 'I', vcei_count); -#ifndef CONFIG_CPU_HAS_LLSC - seq_printf(m, "ll emulations\t\t: %lu\n", ll_ops); - seq_printf(m, "sc emulations\t\t: %lu\n", sc_ops); -#endif - return 0; } @@ -145,8 +136,8 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; diff -urN linux-2.4.21/arch/mips/kernel/process.c linux-2.4.22/arch/mips/kernel/process.c --- linux-2.4.21/arch/mips/kernel/process.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/mips/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 @@ -18,9 +18,12 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -30,6 +33,7 @@ #include #include #include +#include ATTRIB_NORET void cpu_idle(void) { @@ -47,28 +51,25 @@ } } -struct task_struct *last_task_used_math = NULL; - asmlinkage void ret_from_fork(void); +void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) +{ + regs->cp0_status &= ~(ST0_CU0|ST0_KSU|ST0_CU1); + regs->cp0_status |= KU_USER; + current->used_math = 0; + lose_fpu(); + regs->cp0_epc = pc; + regs->regs[29] = sp; + current->thread.current_ds = USER_DS; +} + void exit_thread(void) { - /* Forget lazy fpu state */ - if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - last_task_used_math = NULL; - } } void flush_thread(void) { - /* Forget lazy fpu state */ - if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - last_task_used_math = NULL; - } } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, @@ -80,11 +81,10 @@ childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; - if (last_task_used_math == current) - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - save_fp(p); - } + if (is_fpu_owner()) { + save_fp(p); + } + /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; @@ -111,10 +111,10 @@ p->thread.reg31 = (unsigned long) ret_from_fork; /* - * New tasks loose permission to use the fpu. This accelerates context + * New tasks lose permission to use the fpu. This accelerates context * switching for most programs since they don't use the fpu. */ - p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & + p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1|KU_MASK); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); @@ -124,29 +124,8 @@ /* Fill in the fpu structure for a core dump.. */ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { - /* We actually store the FPU info in the task->thread - * area. - */ - if(regs->cp0_status & ST0_CU1) { - memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); - return 1; - } - return 0; /* Task didn't use the fpu at all. */ -} - -/* Fill in the user structure for a core dump.. */ -void dump_thread(struct pt_regs *regs, struct user *dump) -{ - dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; - dump->start_data = current->mm->start_data; - dump->start_stack = regs->regs[29] & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data) >> PAGE_SHIFT; - dump->u_ssize = - (current->mm->start_stack - dump->start_stack + PAGE_SIZE - 1) >> PAGE_SHIFT; - memcpy(&dump->regs[0], regs, sizeof(struct pt_regs)); - memcpy(&dump->regs[EF_SIZE/4], ¤t->thread.fpu, sizeof(current->thread.fpu)); + memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } /* @@ -157,21 +136,21 @@ long retval; __asm__ __volatile__( - ".set noreorder \n" - " move $6,$sp \n" - " move $4,%5 \n" - " li $2,%1 \n" - " syscall \n" - " beq $6,$sp,1f \n" - " subu $sp,32 \n" /* delay slot */ - " jalr %4 \n" - " move $4,%3 \n" /* delay slot */ - " move $4,$2 \n" - " li $2,%2 \n" - " syscall \n" - "1: addiu $sp,32 \n" - " move %0,$2 \n" - ".set reorder" + " .set noreorder \n" + " move $6, $sp \n" + " move $4, %5 \n" + " li $2, %1 \n" + " syscall \n" + " beq $6, $sp, 1f \n" + " subu $sp, 32 \n" + " jalr %4 \n" + " move $4, %3 \n" + " move $4, $2 \n" + " li $2, %2 \n" + " syscall \n" + "1: addiu $sp, 32 \n" + " move %0, $2 \n" + " .set reorder" : "=r" (retval) : "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), "r" (flags | CLONE_VM) @@ -180,7 +159,7 @@ * at, result, argument or temporary registers ... */ : "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + "$9","$10","$11","$12","$13","$14","$15","$24","$25", "$31"); return retval; } @@ -193,6 +172,62 @@ #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) +struct mips_frame_info schedule_frame; +static struct mips_frame_info schedule_timeout_frame; +static struct mips_frame_info sleep_on_frame; +static struct mips_frame_info sleep_on_timeout_frame; +static struct mips_frame_info wait_for_completion_frame; +static int mips_frame_info_initialized; +static int __init get_frame_info(struct mips_frame_info *info, void *func) +{ + int i; + union mips_instruction *ip = (union mips_instruction *)func; + info->pc_offset = -1; + info->frame_offset = -1; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; + if (ip->i_format.opcode == sw_op && + ip->i_format.rs == 29) { + /* sw $ra, offset($sp) */ + if (ip->i_format.rt == 31) { + if (info->pc_offset != -1) + break; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + } + /* sw $s8, offset($sp) */ + if (ip->i_format.rt == 30) { + if (info->frame_offset != -1) + break; + info->frame_offset = + ip->i_format.simmediate / sizeof(long); + } + } + } + if (info->pc_offset == -1 || info->frame_offset == -1) { + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_offset = -1; + return -1; + } + + return 0; +} +void __init frame_info_init(void) +{ + mips_frame_info_initialized = + !get_frame_info(&schedule_frame, schedule) && + !get_frame_info(&schedule_timeout_frame, schedule_timeout) && + !get_frame_info(&sleep_on_frame, sleep_on) && + !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) && + !get_frame_info(&wait_for_completion_frame, wait_for_completion); +} + /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ unsigned long get_wchan(struct task_struct *p) { @@ -201,6 +236,8 @@ if (!p || p == current || p->state == TASK_RUNNING) return 0; + if (!mips_frame_info_initialized) + return 0; pc = thread_saved_pc(&p->thread); if (pc < first_sched || pc >= last_sched) { return pc; @@ -214,29 +251,33 @@ goto schedule_timeout_caller; if (pc >= (unsigned long)interruptible_sleep_on) goto schedule_caller; - /* Fall through */ + if (pc >= (unsigned long)wait_for_completion) + goto schedule_caller; + goto schedule_timeout_caller; schedule_caller: - pc = ((unsigned long *)p->thread.reg30)[13]; - + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + if (pc >= (unsigned long) sleep_on) + pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset]; + else + pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset]; return pc; schedule_timeout_caller: /* * The schedule_timeout frame */ - frame = ((unsigned long *)p->thread.reg30)[13]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; /* * frame now points to sleep_on_timeout's frame */ - frame = ((unsigned long *)frame)[9]; - pc = ((unsigned long *)frame)[10]; + pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; if (pc >= first_sched && pc < last_sched) { - /* schedule_timeout called by interruptible_sleep_on_timeout */ - frame = ((unsigned long *)frame)[9]; - pc = ((unsigned long *)frame)[10]; + /* schedule_timeout called by [interruptible_]sleep_on_timeout */ + frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; + pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; } return pc; diff -urN linux-2.4.21/arch/mips/kernel/ptrace.c linux-2.4.22/arch/mips/kernel/ptrace.c --- linux-2.4.21/arch/mips/kernel/ptrace.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/ptrace.c 2003-08-25 04:44:40.000000000 -0700 @@ -27,6 +27,7 @@ #include #include #include +#include /* * Called by kernel/ptrace.c when detaching.. @@ -42,7 +43,6 @@ { struct task_struct *child; int ret; - extern void save_fp(struct task_struct *); lock_kernel(); #if 0 @@ -72,7 +72,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -94,8 +94,7 @@ if (copied != sizeof(tmp)) break; ret = put_user(tmp,(unsigned long *) data); - - goto out; + break; } /* Read the word at location addr in the USER area. */ @@ -113,20 +112,7 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - if(!(mips_cpu.options & MIPS_CPU_FPU)) { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } else - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } + unsigned long long *fregs = get_fpu_regs(child); /* * The odd registers are actually the high * order bits of the values stored in the even @@ -156,17 +142,16 @@ tmp = regs->lo; break; case FPC_CSR: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) tmp = child->thread.fpu.soft.sr; else tmp = child->thread.fpu.hard.control; break; case FPC_EIR: { /* implementation / version register */ - unsigned int flags; + unsigned long flags; - if (!(mips_cpu.options & MIPS_CPU_FPU)) { + if (!cpu_has_fpu) break; - } __save_flags(flags); __enable_fpu(); @@ -177,10 +162,10 @@ default: tmp = 0; ret = -EIO; - goto out; + goto out_tsk; } ret = put_user(tmp, (unsigned long *) data); - goto out; + break; } case PTRACE_POKETEXT: /* write the word at location addr. */ @@ -190,7 +175,7 @@ == sizeof(data)) break; ret = -EIO; - goto out; + break; case PTRACE_POKEUSR: { struct pt_regs *regs; @@ -204,21 +189,8 @@ break; case FPR_BASE ... FPR_BASE + 31: { unsigned long long *fregs; - fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0]; - if (child->used_math) { - if (last_task_used_math == child) { - if(!(mips_cpu.options & MIPS_CPU_FPU)) { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } else { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } - } - } else { + fregs = (unsigned long long *)get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); @@ -229,11 +201,6 @@ * of the values stored in the even registers - unless * we're using r2k_switch.S. */ -#ifdef CONFIG_CPU_R3000 - if (mips_cpu.options & MIPS_CPU_FPU) - *(unsigned long *)(fregs + addr) = data; - else -#endif if (addr & 1) { fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32; @@ -253,7 +220,7 @@ regs->lo = data; break; case FPC_CSR: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) child->thread.fpu.soft.sr = data; else child->thread.fpu.hard.control = data; @@ -308,7 +275,7 @@ default: ret = -EIO; - goto out; + break; } out_tsk: free_task_struct(child); diff -urN linux-2.4.21/arch/mips/kernel/r2300_switch.S linux-2.4.22/arch/mips/kernel/r2300_switch.S --- linux-2.4.21/arch/mips/kernel/r2300_switch.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/kernel/r2300_switch.S 2003-08-25 04:44:40.000000000 -0700 @@ -28,6 +28,19 @@ .set mips1 .align 5 +#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * [jsun] FPU context is saved if and only if the process has used FPU in + * the current run (PF_USEDFPU). In any case, the CU1 bit for user space + * STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* * task_struct *resume(task_struct *prev, * task_struct *next) @@ -41,6 +54,32 @@ CPU_SAVE_NONSCRATCH(a0) sw ra, THREAD_REG31(a0) + /* + * check if we need to save FPU registers + */ + lw t0, TASK_FLAGS(a0) + li t1, PF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + /* + * clear PF_USEDFPU bit in task flags + */ + and t0, t0, t1 + sw t0, TASK_FLAGS(a0) + + /* + * clear user-saved stack CU1 bit + */ + lw t0, ST_OFF(a0) + li t1, ~ST0_CU1 + and t0, t0, t1 + sw t0, ST_OFF(a0) + + FPU_SAVE_SINGLE(a0, t0) # clobbers t0 + +1: /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. @@ -64,59 +103,32 @@ END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, ST0_CU1 - or t0, t3 - mtc0 t0, CP0_STATUS - - .set noreorder - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - .set reorder - lw t1, ST_OFF(a0) # last thread looses fpu - and t1, t3 - sw t1, ST_OFF(a0) - FPU_SAVE_SINGLE(a0, t1) # clobbers t1 - -2: - FPU_RESTORE_SINGLE($28, t0) # clobbers t0 - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ -LEAF(save_fp) +LEAF(_save_fp) FPU_SAVE_SINGLE(a0, t1) # clobbers t1 jr ra - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) FPU_RESTORE_SINGLE(a0, t1) # clobbers t1 jr ra - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has * the property that no matter wether considered as single or as double - * precission represents signaling NANS. + * precision represents signaling NANS. * * We initialize fcr31 to rounding to nearest, no exceptions. */ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1 or t0, t1 @@ -162,4 +174,4 @@ jr ra mtc1 t0, $f31 .set reorder - END(init_fpu) + END(_init_fpu) diff -urN linux-2.4.21/arch/mips/kernel/r4k_switch.S linux-2.4.22/arch/mips/kernel/r4k_switch.S --- linux-2.4.21/arch/mips/kernel/r4k_switch.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/r4k_switch.S 2003-08-25 04:44:40.000000000 -0700 @@ -25,6 +25,19 @@ #include +#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * [jsun] FPU context is saved if and only if the process has used FPU in + * the current run (PF_USEDFPU). In any case, the CU1 bit for user space + * STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* * task_struct *r4xx0_resume(task_struct *prev, task_struct *next) */ @@ -39,6 +52,32 @@ CPU_SAVE_NONSCRATCH(a0) sw ra, THREAD_REG31(a0) + /* + * check if we need to save FPU registers + */ + lw t0, TASK_FLAGS(a0) + li t1, PF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + /* + * clear PF_USEDFPU bit in task flags + */ + and t0, t0, t1 + sw t0, TASK_FLAGS(a0) + + /* + * clear saved user stack CU1 bit + */ + lw t0, ST_OFF(a0) + li t1, ~ST0_CU1 + and t0, t0, t1 + sw t0, ST_OFF(a0) + + FPU_SAVE_DOUBLE(a0, t0) # clobbers t0 + +1: /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. @@ -69,50 +108,20 @@ END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, ST0_CU1 - or t0, t3 - mtc0 t0, CP0_STATUS - FPU_ENABLE_HAZARD - - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - - lw t1, ST_OFF(a0) # last thread looses fpu - and t1, t3 - sw t1, ST_OFF(a0) - - - FPU_SAVE_DOUBLE(a0, t1) # clobbers t1 -2: - - .set reorder - FPU_RESTORE_DOUBLE($28, t0) # clobbers t0 - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ -LEAF(save_fp) +LEAF(_save_fp) FPU_SAVE_DOUBLE(a0, t1) # clobbers t1 jr ra - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) FPU_RESTORE_DOUBLE(a0, t1) # clobbers t1 jr ra - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has @@ -124,7 +133,7 @@ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) .set mips3 mfc0 t0, CP0_STATUS li t1, ST0_CU1 @@ -156,5 +165,5 @@ jr ra dmtc1 t0, $f30 .set reorder - END(init_fpu) + END(_init_fpu) diff -urN linux-2.4.21/arch/mips/kernel/setup.c linux-2.4.22/arch/mips/kernel/setup.c --- linux-2.4.21/arch/mips/kernel/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * Copyright (C) 1995 Waldorf Electronics * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Ralf Baechle * Copyright (C) 1996 Stoned Elipot - * Copyright (C) 2000, 2001 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002 Maciej W. Rozycki */ #include #include @@ -39,9 +39,7 @@ #include #include -#ifndef CONFIG_SMP -struct cpuinfo_mips cpu_data[1]; -#endif +struct cpuinfo_mips cpu_data[NR_CPUS]; /* * There are several bus types available for MIPS machines. "RISC PC" @@ -56,8 +54,11 @@ struct screen_info screen_info; +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) +#include extern struct fd_ops no_fd_ops; struct fd_ops *fd_ops; +#endif #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) extern struct ide_ops no_ide_ops; @@ -70,7 +71,6 @@ struct rtc_ops *rtc_ops; #ifdef CONFIG_PC_KEYB -extern struct kbd_ops no_kbd_ops; struct kbd_ops *kbd_ops; #endif @@ -100,15 +100,14 @@ /* - * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped + * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. */ unsigned long isa_slot_offset; EXPORT_SYMBOL(isa_slot_offset); -extern void sgi_sysinit(void); extern void SetUpBootInfo(void); -extern void loadmmu(void); +extern void load_mmu(void); extern asmlinkage void start_kernel(void); extern void prom_init(int, char **, char **, int *); @@ -123,10 +122,6 @@ prom_init(argc, argv, envp, prom_vec); -#ifdef CONFIG_SGI_IP22 - sgi_sysinit(); -#endif - cpu_report(); /* @@ -134,11 +129,11 @@ * then flush the tlb and caches. On the r4xx0 * variants this also sets CP0_WIRED to zero. */ - loadmmu(); + load_mmu(); /* Disable coprocessors and set FPU for 16/32 FPR register model */ - clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); - set_cp0_status(ST0_CU0); + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); + set_c0_status(ST0_CU0); start_kernel(); } @@ -236,210 +231,6 @@ } } -void __init setup_arch(char **cmdline_p) -{ - void atlas_setup(void); - void baget_setup(void); - void cobalt_setup(void); - void ddb_setup(void); - void decstation_setup(void); - void deskstation_setup(void); - void jazz_setup(void); - void sni_rm200_pci_setup(void); - void ip22_setup(void); - void ev96100_setup(void); - void malta_setup(void); - void sead_setup(void); - void ikos_setup(void); - void momenco_ocelot_setup(void); - void momenco_ocelot_g_setup(void); - void nino_setup(void); - void nec_osprey_setup(void); - void nec_eagle_setup(void); - void zao_capcella_setup(void); - void jmr3927_setup(void); - void it8172_setup(void); - void swarm_setup(void); - void hp_setup(void); - - unsigned long bootmap_size; - unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn; -#ifdef CONFIG_BLK_DEV_INITRD - unsigned long tmp; - unsigned long* initrd_header; -#endif - - int i; - -#ifdef CONFIG_BLK_DEV_FD - fd_ops = &no_fd_ops; -#endif - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &no_ide_ops; -#endif - -#ifdef CONFIG_PC_KEYB - kbd_ops = &no_kbd_ops; -#endif - - rtc_ops = &no_rtc_ops; - - switch(mips_machgroup) - { -#ifdef CONFIG_BAGET_MIPS - case MACH_GROUP_BAGET: - baget_setup(); - break; -#endif -#ifdef CONFIG_MIPS_COBALT - case MACH_GROUP_COBALT: - cobalt_setup(); - break; -#endif -#ifdef CONFIG_DECSTATION - case MACH_GROUP_DEC: - decstation_setup(); - break; -#endif -#ifdef CONFIG_MIPS_ATLAS - case MACH_GROUP_UNKNOWN: - atlas_setup(); - break; -#endif -#ifdef CONFIG_MIPS_JAZZ - case MACH_GROUP_JAZZ: - jazz_setup(); - break; -#endif -#ifdef CONFIG_MIPS_MALTA - case MACH_GROUP_UNKNOWN: - malta_setup(); - break; -#endif -#ifdef CONFIG_MOMENCO_OCELOT - case MACH_GROUP_MOMENCO: - momenco_ocelot_setup(); - break; -#endif -#ifdef CONFIG_MOMENCO_OCELOT_G - case MACH_GROUP_MOMENCO: - momenco_ocelot_g_setup(); - break; -#endif -#ifdef CONFIG_MIPS_SEAD - case MACH_GROUP_UNKNOWN: - sead_setup(); - break; -#endif -#ifdef CONFIG_SGI_IP22 - /* As of now this is only IP22. */ - case MACH_GROUP_SGI: - ip22_setup(); - break; -#endif -#ifdef CONFIG_SNI_RM200_PCI - case MACH_GROUP_SNI_RM: - sni_rm200_pci_setup(); - break; -#endif -#ifdef CONFIG_DDB5074 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_DDB5476 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_DDB5477 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_CPU_VR41XX - case MACH_GROUP_NEC_VR41XX: - switch (mips_machtype) { -#ifdef CONFIG_NEC_OSPREY - case MACH_NEC_OSPREY: - nec_osprey_setup(); - break; -#endif -#ifdef CONFIG_NEC_EAGLE - case MACH_NEC_EAGLE: - nec_eagle_setup(); - break; -#endif -#ifdef CONFIG_ZAO_CAPCELLA - case MACH_ZAO_CAPCELLA: - zao_capcella_setup(); - break; -#endif - } - break; -#endif -#ifdef CONFIG_MIPS_EV96100 - case MACH_GROUP_GALILEO: - ev96100_setup(); - break; -#endif -#ifdef CONFIG_MIPS_EV64120 - case MACH_GROUP_GALILEO: - ev64120_setup(); - break; -#endif -#if defined(CONFIG_MIPS_IVR) || defined(CONFIG_MIPS_ITE8172) - case MACH_GROUP_ITE: - case MACH_GROUP_GLOBESPAN: - it8172_setup(); - break; -#endif -#ifdef CONFIG_NINO - case MACH_GROUP_PHILIPS: - nino_setup(); - break; -#endif -#ifdef CONFIG_MIPS_PB1000 - case MACH_GROUP_ALCHEMY: - au1000_setup(); - break; -#endif -#ifdef CONFIG_MIPS_PB1100 - case MACH_GROUP_ALCHEMY: - au1100_setup(); - break; -#endif -#ifdef CONFIG_MIPS_PB1500 - case MACH_GROUP_ALCHEMY: - au1500_setup(); - break; -#endif -#ifdef CONFIG_TOSHIBA_JMR3927 - case MACH_GROUP_TOSHIBA: - jmr3927_setup(); - break; -#endif -#ifdef CONFIG_SIBYTE_SWARM - case MACH_GROUP_SIBYTE: - swarm_setup(); - break; -#endif -#ifdef CONFIG_HP_LASERJET - case MACH_GROUP_HP_LJ: - hp_setup(); - break; -#endif - default: - panic("Unsupported architecture"); - } - - strncpy(command_line, arcs_cmdline, sizeof command_line); - command_line[sizeof command_line - 1] = 0; - strcpy(saved_command_line, command_line); - *cmdline_p = command_line; - - parse_mem_cmdline(); #define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) @@ -448,6 +239,16 @@ #define MAXMEM HIGHMEM_START #define MAXMEM_PFN PFN_DOWN(MAXMEM) +static inline void bootmem_init(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long tmp; + unsigned long *initrd_header; +#endif + unsigned long bootmap_size; + unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn; + int i; + #ifdef CONFIG_BLK_DEV_INITRD tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; if (tmp < (unsigned long)&_end) @@ -592,15 +393,18 @@ initrd_size); if (PHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " - "(0x%lx > 0x%p)\ndisabling initrd\n", + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", PHYSADDR(initrd_end), PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; } } #endif /* CONFIG_BLK_DEV_INITRD */ +} - paging_init(); +static inline void resource_init(void) +{ + int i; code_resource.start = virt_to_bus(&_ftext); code_resource.end = virt_to_bus(&_etext) - 1; @@ -612,7 +416,14 @@ */ for (i = 0; i < boot_mem_map.nr_map; i++) { struct resource *res; - unsigned long addr_pfn, end_pfn; + unsigned long start, end; + + start = boot_mem_map.map[i].addr; + end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; + if (start >= MAXMEM) + continue; + if (end >= MAXMEM) + end = MAXMEM - 1; res = alloc_bootmem(sizeof(struct resource)); switch (boot_mem_map.map[i].type) { @@ -624,16 +435,10 @@ default: res->name = "reserved"; } - addr_pfn = PFN_UP(boot_mem_map.map[i].addr); - end_pfn = PFN_UP(boot_mem_map.map[i].addr+boot_mem_map.map[i].size); - if (addr_pfn > max_low_pfn) - continue; - res->start = boot_mem_map.map[i].addr; - if (end_pfn < max_low_pfn) { - res->end = res->start + boot_mem_map.map[i].size - 1; - } else { - res->end = max_low_pfn - 1; - } + + res->start = start; + res->end = end; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); @@ -647,9 +452,257 @@ } } +#undef PFN_UP +#undef PFN_DOWN +#undef PFN_PHYS + +#undef MAXMEM +#undef MAXMEM_PFN + + +void __init setup_arch(char **cmdline_p) +{ + void atlas_setup(void); + void baget_setup(void); + void cobalt_setup(void); + void lasat_setup(void); + void ddb_setup(void); + void decstation_setup(void); + void deskstation_setup(void); + void jazz_setup(void); + void sni_rm200_pci_setup(void); + void ip22_setup(void); + void ev96100_setup(void); + void malta_setup(void); + void sead_setup(void); + void ikos_setup(void); + void momenco_ocelot_setup(void); + void momenco_ocelot_g_setup(void); + void momenco_ocelot_c_setup(void); + void nino_setup(void); + void nec_osprey_setup(void); + void nec_eagle_setup(void); + void zao_capcella_setup(void); + void victor_mpc30x_setup(void); + void ibm_workpad_setup(void); + void casio_e55_setup(void); + void tanbac_tb0226_setup(void); + void jmr3927_setup(void); + void tx4927_setup(void); + void it8172_setup(void); + void swarm_setup(void); + void hp_setup(void); + void au1x00_setup(void); + void frame_info_init(void); + + frame_info_init(); +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) + fd_ops = &no_fd_ops; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &no_ide_ops; +#endif + + rtc_ops = &no_rtc_ops; + + switch(mips_machgroup) + { +#ifdef CONFIG_BAGET_MIPS + case MACH_GROUP_BAGET: + baget_setup(); + break; +#endif +#ifdef CONFIG_MIPS_COBALT + case MACH_GROUP_COBALT: + cobalt_setup(); + break; +#endif +#ifdef CONFIG_DECSTATION + case MACH_GROUP_DEC: + decstation_setup(); + break; +#endif +#ifdef CONFIG_MIPS_ATLAS + case MACH_GROUP_UNKNOWN: + atlas_setup(); + break; +#endif +#ifdef CONFIG_MIPS_JAZZ + case MACH_GROUP_JAZZ: + jazz_setup(); + break; +#endif +#ifdef CONFIG_MIPS_MALTA + case MACH_GROUP_UNKNOWN: + malta_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT + case MACH_GROUP_MOMENCO: + momenco_ocelot_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT_G + case MACH_GROUP_MOMENCO: + momenco_ocelot_g_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT_C + case MACH_GROUP_MOMENCO: + momenco_ocelot_c_setup(); + break; +#endif +#ifdef CONFIG_MIPS_SEAD + case MACH_GROUP_UNKNOWN: + sead_setup(); + break; +#endif +#ifdef CONFIG_SGI_IP22 + /* As of now this is only IP22. */ + case MACH_GROUP_SGI: + ip22_setup(); + break; +#endif +#ifdef CONFIG_SNI_RM200_PCI + case MACH_GROUP_SNI_RM: + sni_rm200_pci_setup(); + break; +#endif +#ifdef CONFIG_DDB5074 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_DDB5476 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_DDB5477 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_CPU_VR41XX + case MACH_GROUP_NEC_VR41XX: + switch (mips_machtype) { +#ifdef CONFIG_NEC_OSPREY + case MACH_NEC_OSPREY: + nec_osprey_setup(); + break; +#endif +#ifdef CONFIG_NEC_EAGLE + case MACH_NEC_EAGLE: + nec_eagle_setup(); + break; +#endif +#ifdef CONFIG_ZAO_CAPCELLA + case MACH_ZAO_CAPCELLA: + zao_capcella_setup(); + break; +#endif +#ifdef CONFIG_VICTOR_MPC30X + case MACH_VICTOR_MPC30X: + victor_mpc30x_setup(); + break; +#endif +#ifdef CONFIG_IBM_WORKPAD + case MACH_IBM_WORKPAD: + ibm_workpad_setup(); + break; +#endif +#ifdef CONFIG_CASIO_E55 + case MACH_CASIO_E55: + casio_e55_setup(); + break; +#endif +#ifdef CONFIG_TANBAC_TB0226 + case MACH_TANBAC_TB0226: + tanbac_tb0226_setup(); + break; +#endif +#ifdef CONFIG_TANBAC_TB0229 + case MACH_TANBAC_TB0229: + tanbac_tb0229_setup(); + break; +#endif + } + break; +#endif +#ifdef CONFIG_MIPS_EV96100 + case MACH_GROUP_GALILEO: + ev96100_setup(); + break; +#endif +#ifdef CONFIG_MIPS_EV64120 + case MACH_GROUP_GALILEO: + ev64120_setup(); + break; +#endif +#if defined(CONFIG_MIPS_IVR) || defined(CONFIG_MIPS_ITE8172) + case MACH_GROUP_ITE: + case MACH_GROUP_GLOBESPAN: + it8172_setup(); + break; +#endif +#ifdef CONFIG_NINO + case MACH_GROUP_PHILIPS: + nino_setup(); + break; +#endif +#ifdef CONFIG_LASAT + case MACH_GROUP_LASAT: + lasat_setup(); + break; +#endif +#ifdef CONFIG_SOC_AU1X00 + case MACH_GROUP_ALCHEMY: + au1x00_setup(); + break; +#endif +#ifdef CONFIG_TOSHIBA_JMR3927 + case MACH_GROUP_TOSHIBA: + jmr3927_setup(); + break; +#endif +#ifdef CONFIG_TOSHIBA_RBTX4927 + case MACH_GROUP_TOSHIBA: + tx4927_setup(); + break; +#endif +#ifdef CONFIG_SIBYTE_BOARD + case MACH_GROUP_SIBYTE: + swarm_setup(); + break; +#endif +#ifdef CONFIG_HP_LASERJET + case MACH_GROUP_HP_LJ: + hp_setup(); + break; +#endif + default: + panic("Unsupported architecture"); + } + + strncpy(command_line, arcs_cmdline, sizeof command_line); + command_line[sizeof command_line - 1] = 0; + strcpy(saved_command_line, command_line); + *cmdline_p = command_line; + + parse_mem_cmdline(); + + bootmem_init(); + + paging_init(); + + resource_init(); +} + static int __init fpu_disable(char *s) { - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; + return 1; } __setup("nofpu", fpu_disable); diff -urN linux-2.4.21/arch/mips/kernel/signal.c linux-2.4.22/arch/mips/kernel/signal.c --- linux-2.4.21/arch/mips/kernel/signal.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -34,9 +35,6 @@ extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); - extern asmlinkage void syscall_trace(void); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) @@ -150,7 +148,6 @@ err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); if (err) return -EFAULT; @@ -168,7 +165,6 @@ err |= __put_user(0, &oact->sa_mask.sig[1]); err |= __put_user(0, &oact->sa_mask.sig[2]); err |= __put_user(0, &oact->sa_mask.sig[3]); - err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); if (err) return -EFAULT; } @@ -185,59 +181,8 @@ return do_sigaltstack(uss, uoss, usp); } -static inline int restore_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - - /* - * Copy all 32 64-bit values, for two reasons. First, the R3000 and - * R4000/MIPS32 kernels use the thread FP register storage differently, - * such that a full copy is essentially necessary to support both. - */ - -#define restore_fpr(i) \ - do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3); - restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7); - restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11); - restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15); - restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19); - restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23); - restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27); - restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31); - - err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static inline int save_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - -#define save_fpr(i) \ - do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3); - save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7); - save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11); - save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15); - save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19); - save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23); - save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27); - save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31); - - err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; u64 reg; @@ -265,25 +210,17 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); err |= __get_user(current->used_math, &sc->sc_used_math); - if (owned_fp) { - err |= restore_fp_context(sc); - goto out; - } - - if (current == last_task_used_math) { - /* Signal handler acquired FPU - give it back */ - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } if (current->used_math) { - /* Undo possible contamination of thread state */ - err |= restore_thread_fp_context(sc); + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + lose_fpu(); } -out: return err; } @@ -380,7 +317,6 @@ static int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; u64 reg; @@ -408,25 +344,20 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - owned_fp = (current == last_task_used_math); - err |= __put_user(owned_fp, &sc->sc_ownedfp); err |= __put_user(current->used_math, &sc->sc_used_math); if (!current->used_math) goto out; - /* There exists FP thread state that may be trashed by signal */ - if (owned_fp) { - /* fp is active. Save context from FPU */ - err |= save_fp_context(sc); - goto out; - } - - /* - * Someone else has FPU. - * Copy Thread context into signal context + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. */ - err |= save_thread_fp_context(sc); + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + err |= save_fp_context(sc); out: return err; @@ -467,23 +398,15 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); + err |= __put_user(0x0000000c , frame->sf_code + 1); + flush_cache_sigtramp((unsigned long) frame->sf_code); err |= setup_sigcontext(regs, &frame->sf_sc); err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); @@ -530,23 +453,15 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Create siginfo. */ err |= copy_siginfo_to_user(&frame->rs_info, info); diff -urN linux-2.4.21/arch/mips/kernel/smp.c linux-2.4.22/arch/mips/kernel/smp.c --- linux-2.4.21/arch/mips/kernel/smp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -43,9 +43,7 @@ spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; int smp_threads_ready; /* Not used */ atomic_t smp_commenced = ATOMIC_INIT(0); -struct cpuinfo_mips cpu_data[NR_CPUS]; -// static atomic_t cpus_booted = ATOMIC_INIT(0); atomic_t cpus_booted = ATOMIC_INIT(0); int smp_num_cpus = 1; /* Number that came online. */ @@ -83,10 +81,6 @@ void prom_smp_finish(void); -static void smp_tune_scheduling(void) -{ -} - void __init smp_callin(void) { #if 0 @@ -104,6 +98,7 @@ { unsigned int cpu = smp_processor_id(); + cpu_probe(); prom_init_secondary(); per_cpu_trap_init(); @@ -138,7 +133,7 @@ core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF); } -static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; +spinlock_t smp_call_lock = SPIN_LOCK_UNLOCKED; struct call_data_struct *call_data; @@ -170,7 +165,7 @@ if (wait) atomic_set(&data.finished, 0); - spin_lock(&call_lock); + spin_lock(&smp_call_lock); call_data = &data; /* Send a message to all other CPUs and wait for them to respond */ @@ -186,7 +181,7 @@ if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock(&call_lock); + spin_unlock(&smp_call_lock); return 0; } @@ -224,7 +219,7 @@ */ clear_bit(smp_processor_id(), &cpu_online_map); /* May need to service _machine_restart IPI */ - __sti(); + local_irq_enable(); /* XXXKW wait if available? */ for (;;); } @@ -282,7 +277,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_mm(mm); } @@ -314,7 +309,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_range(mm, start, end); } @@ -338,7 +333,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, vma->vm_mm) = 0; + cpu_context(i, vma->vm_mm) = 0; } local_flush_tlb_page(vma, page); } diff -urN linux-2.4.21/arch/mips/kernel/syscall.c linux-2.4.22/arch/mips/kernel/syscall.c --- linux-2.4.21/arch/mips/kernel/syscall.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/syscall.c 2003-08-25 04:44:40.000000000 -0700 @@ -55,9 +55,11 @@ return res; } -#define COLOUR_ALIGN(addr,pgoff) \ - ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ - (((pgoff)< #include #include +#include #include #include #include #include +#include #include #include @@ -28,9 +31,14 @@ #include #include -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) +/* + * The integer part of the number of usecs per jiffy is taken from tick, + * but the fractional part is not recorded, so we calculate it using the + * initial value of HZ. This aids systems where tick isn't really an + * integer (e.g. for HZ = 128). + */ +#define USECS_PER_JIFFY tick +#define USECS_PER_JIFFY_FRAC ((unsigned long)(u32)((1000000ULL << 32) / HZ)) /* * forward reference @@ -38,11 +46,14 @@ extern rwlock_t xtime_lock; extern volatile unsigned long wall_jiffies; +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + /* * whether we emulate local_timer_interrupts for SMP machines. */ int emulate_local_timer_interrupt; + /* * By default we provide the null RTC ops */ @@ -58,6 +69,85 @@ unsigned long (*rtc_get_time)(void) = null_rtc_get_time; int (*rtc_set_time)(unsigned long) = null_rtc_set_time; +int (*rtc_set_mmss)(unsigned long); + + +/* usecs per counter cycle, shifted to left by 32 bits */ +static unsigned int sll32_usecs_per_cycle; + +/* how many counter cycles in a jiffy */ +static unsigned long cycles_per_jiffy; + +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi, timerlo; + +/* expirelo is the count value for next CPU timer interrupt */ +static unsigned int expirelo; + + +/* + * Null timer ack for systems not needing one (e.g. i8254). + */ +static void null_timer_ack(void) { /* nothing */ } + +/* + * Null high precision timer functions for systems lacking one. + */ +static unsigned int null_hpt_read(void) +{ + return 0; +} + +static void null_hpt_init(unsigned int count) { /* nothing */ } + + +/* + * Timer ack for a R4k-compatible timer of a known frequency. + */ +static void c0_fixed_timer_ack(void) +{ + unsigned int count; + + /* Ack this timer interrupt and set the next one. */ + expirelo += cycles_per_jiffy; + write_c0_compare(expirelo); + + /* Check to see if we have missed any timer interrupts. */ + count = read_c0_count(); + if ((count - expirelo) < 0x7fffffff) { + /* missed_timer_count++; */ + expirelo = count + cycles_per_jiffy; + write_c0_compare(expirelo); + } +} + +/* + * High precision timer functions for a R4k-compatible timer. + */ +static unsigned int c0_hpt_read(void) +{ + return read_c0_count(); +} + +/* For unknown frequency. */ +static void c0_hpt_init(unsigned int count) +{ + write_c0_count(read_c0_count() - count); +} + +/* For a known frequency. Used as an interrupt source. */ +static void c0_fixed_hpt_init(unsigned int count) +{ + expirelo = cycles_per_jiffy; + count = read_c0_count() - count; + write_c0_count(0); + write_c0_compare(cycles_per_jiffy); + write_c0_count(count); +} + +void (*mips_timer_ack)(void); +unsigned int (*mips_hpt_read)(void); +void (*mips_hpt_init)(unsigned int); /* @@ -65,22 +155,23 @@ */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long flags, lost; + + read_lock_irqsave(&xtime_lock, flags); - read_lock_irqsave (&xtime_lock, flags); *tv = xtime; tv->tv_usec += do_gettimeoffset(); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasn't executed yet. */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + lost = jiffies - wall_jiffies; + if (lost) + tv->tv_usec += lost * USECS_PER_JIFFY; - read_unlock_irqrestore (&xtime_lock, flags); + read_unlock_irqrestore(&xtime_lock, flags); - if (tv->tv_usec >= 1000000) { + while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } @@ -88,27 +179,29 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_lock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + /* + * This is revolting. We need to set "xtime" correctly. However, + * the value in this location is the value at the most recent update + * of wall time. Discover what correction gettimeofday() would have + * made, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); + tv->tv_usec -= (jiffies - wall_jiffies) * USECS_PER_JIFFY; - if (tv->tv_usec < 0) { + while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } + xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_unlock_irq(&xtime_lock); } @@ -119,76 +212,61 @@ * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. * Otherwise use calibrate_gettimeoffset() * - * If the CPU does not have counter register all, you can either supply - * your own gettimeoffset() routine, or use null_gettimeoffset() routines, - * which gives the same resolution as HZ. + * If the CPU does not have the counter register, you can either supply + * your own gettimeoffset() routine, or use null_gettimeoffset(), which + * gives the same resolution as HZ. */ +static unsigned long null_gettimeoffset(void) +{ + return 0; +} -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) - -/* usecs per counter cycle, shifted to left by 32 bits */ -static unsigned int sll32_usecs_per_cycle=0; - -/* how many counter cycles in a jiffy */ -static unsigned long cycles_per_jiffy=0; - -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - -/* last time when xtime and rtc are sync'ed up */ -static long last_rtc_update; -/* the function pointer to one of the gettimeoffset funcs*/ +/* The function pointer to one of the gettimeoffset funcs. */ unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; -unsigned long null_gettimeoffset(void) -{ - return 0; -} -unsigned long fixed_rate_gettimeoffset(void) +static unsigned long fixed_rate_gettimeoffset(void) { u32 count; unsigned long res; /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (sll32_usecs_per_cycle)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (sll32_usecs_per_cycle) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } + /* - * Cached "1/(clocks per usec)*2^32" value. + * Cached "1/(clocks per usec) * 2^32" value. * It has to be recalculated once each jiffy. */ static unsigned long cached_quotient; /* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ -static unsigned long last_jiffies = 0; - +static unsigned long last_jiffies; /* - * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij. + * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. */ -unsigned long calibrate_div32_gettimeoffset(void) +static unsigned long calibrate_div32_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -204,20 +282,21 @@ unsigned long r0; do_div64_32(r0, timerhi, timerlo, tmp); do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); + USECS_PER_JIFFY_FRAC, r0); cached_quotient = quotient; } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu %2,%3" - : "=l" (tmp), "=h" (res) - : "r" (count), "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check @@ -229,7 +308,7 @@ return res; } -unsigned long calibrate_div64_gettimeoffset(void) +static unsigned long calibrate_div64_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -239,54 +318,56 @@ quotient = cached_quotient; - if (tmp && last_jiffies != tmp) { + if (last_jiffies != tmp) { last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY)); - cached_quotient = quotient; + if (last_jiffies) { + unsigned long r0; + __asm__(".set push\n\t" + ".set mips3\n\t" + "lwu %0,%3\n\t" + "dsll32 %1,%2,0\n\t" + "or %1,%1,%0\n\t" + "ddivu $0,%1,%4\n\t" + "dsll32 %0,%5,0\n\t" + "or %0,%0,%6\n\t" + "mflo %1\n\t" + "ddivu $0,%0,%1\n\t" + "mflo %0\n\t" + ".set pop" + : "=&r" (quotient), "=&r" (r0) + : "r" (timerhi), "m" (timerlo), + "r" (tmp), "r" (USECS_PER_JIFFY), + "r" (USECS_PER_JIFFY_FRAC) + : "hi", "lo", "accum"); + cached_quotient = quotient; + } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } +/* last time when xtime and rtc are sync'ed up */ +static long last_rtc_update; + /* * local_timer_interrupt() does profiling and process accounting * on a per-CPU basis. @@ -311,8 +392,8 @@ * put them into the last histogram slot, so if * present, they will show up as a sharp peak. */ - if (pc > prof_len-1) - pc = prof_len-1; + if (pc > prof_len - 1) + pc = prof_len - 1; atomic_inc((atomic_t *)&prof_buffer[pc]); } } @@ -324,31 +405,19 @@ } /* - * high-level timer interrupt service routines. This function + * High-level timer interrupt service routines. This function * is set as irqaction->handler and is invoked through do_IRQ. */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if (mips_cpu.options & MIPS_CPU_COUNTER) { - unsigned int count; + unsigned int count; - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; + count = mips_hpt_read(); + mips_timer_ack(); - /* - * set up for next timer interrupt - no harm if the machine - * is using another timer interrupt source. - * Note that writing to COMPARE register clears the interrupt - */ - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); - - } + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; /* * call the generic timer interrupt handling @@ -360,27 +429,28 @@ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be * called as close as possible to 500 ms before the new second starts. */ - read_lock (&xtime_lock); + read_lock(&xtime_lock); if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (rtc_set_time(xtime.tv_sec) == 0) { + if (rtc_set_mmss(xtime.tv_sec) == 0) { last_rtc_update = xtime.tv_sec; } else { - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; } } - read_unlock (&xtime_lock); + read_unlock(&xtime_lock); /* - * If jiffies has overflowed in this timer_interrupt we must + * If jiffies has overflown in this timer_interrupt, we must * update the timer[hi]/[lo] to make fast gettimeoffset funcs * quotient calc still valid. -arca */ if (!jiffies) { timerhi = timerlo = 0; + mips_hpt_init(count); } #if !defined(CONFIG_SMP) @@ -391,7 +461,7 @@ * In SMP mode, local_timer_interrupt() is invoked by appropriate * low-level local timer interrupt handler. */ - local_timer_interrupt(0, NULL, regs); + local_timer_interrupt(irq, dev_id, regs); #else /* CONFIG_SMP */ @@ -458,18 +528,15 @@ * c) enable the timer interrupt */ -void (*board_time_init)(void) = NULL; -void (*board_timer_setup)(struct irqaction *irq) = NULL; +void (*board_time_init)(void); +void (*board_timer_setup)(struct irqaction *irq); -unsigned int mips_counter_frequency = 0; +unsigned int mips_counter_frequency; static struct irqaction timer_irqaction = { - timer_interrupt, - SA_INTERRUPT, - 0, - "timer", - NULL, - NULL + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer", }; void __init time_init(void) @@ -477,55 +544,76 @@ if (board_time_init) board_time_init(); + if (!rtc_set_mmss) + rtc_set_mmss = rtc_set_time; + xtime.tv_sec = rtc_get_time(); xtime.tv_usec = 0; - /* choose appropriate gettimeoffset routine */ - if (!(mips_cpu.options & MIPS_CPU_COUNTER)) { - /* no cpu counter - sorry */ - do_gettimeoffset = null_gettimeoffset; - } else if (mips_counter_frequency != 0) { - /* we have cpu counter and know counter frequency! */ - do_gettimeoffset = fixed_rate_gettimeoffset; - } else if ((mips_cpu.isa_level == MIPS_CPU_ISA_M32) || - (mips_cpu.isa_level == MIPS_CPU_ISA_I) || - (mips_cpu.isa_level == MIPS_CPU_ISA_II) ) { - /* we need to calibrate the counter but we don't have - * 64-bit division. */ - do_gettimeoffset = calibrate_div32_gettimeoffset; + /* Choose appropriate high precision timer routines. */ + if (!cpu_has_counter && !mips_hpt_read) { + /* No high precision timer -- sorry. */ + mips_hpt_read = null_hpt_read; + mips_hpt_init = null_hpt_init; + } else if (!mips_counter_frequency) { + /* A high precision timer of unknown frequency. */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_hpt_init; + } + + if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) + /* + * We need to calibrate the counter but we don't have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div32_gettimeoffset; + else + /* + * We need to calibrate the counter but we *do* have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div64_gettimeoffset; } else { - /* we need to calibrate the counter but we *do* have - * 64-bit division. */ - do_gettimeoffset = calibrate_div64_gettimeoffset; - } + /* We know counter frequency! */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_fixed_hpt_init; + + if (!mips_timer_ack) + /* R4k timer interrupt ack. */ + mips_timer_ack = c0_fixed_timer_ack; + } - /* caclulate cache parameters */ - if (mips_counter_frequency) { - u32 count; + do_gettimeoffset = fixed_rate_gettimeoffset; + /* Calculate cache parameters. */ cycles_per_jiffy = mips_counter_frequency / HZ; - /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - /* any better way to do this? */ + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + /* Any better way to do this? */ sll32_usecs_per_cycle = mips_counter_frequency / 100000; sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; sll32_usecs_per_cycle *= 10; - - /* - * For those using cpu counter as timer, this sets up the - * first interrupt - */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); } + if (!mips_timer_ack) + /* No timer interrupt ack (e.g. i8254). */ + mips_timer_ack = null_timer_ack; + + /* This sets up the high precision timer for the first interrupt. */ + mips_hpt_init(mips_hpt_read()); + /* * Call board specific timer interrupt setup. * * this pointer must be setup in machine setup routine. * - * Even if the machine choose to use low-level timer interrupt, + * Even if a machine chooses to use a low-level timer interrupt, * it still needs to setup the timer_irqaction. * In that case, it might be better to set timer_irqaction.handler * to be NULL function so that we are sure the high-level code @@ -538,15 +626,15 @@ #define STARTOFTIME 1970 #define SECDAY 86400L #define SECYR (SECDAY * 365) -#define leapyear(year) ((year) % 4 == 0) -#define days_in_year(a) (leapyear(a) ? 366 : 365) -#define days_in_month(a) (month_days[(a) - 1]) +#define leapyear(y) ((!((y) % 4) && ((y) % 100)) || !((y) % 400)) +#define days_in_year(y) (leapyear(y) ? 366 : 365) +#define days_in_month(m) (month_days[(m) - 1]) static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -void to_tm(unsigned long tim, struct rtc_time * tm) +void to_tm(unsigned long tim, struct rtc_time *tm) { long hms, day, gday; int i; @@ -561,16 +649,16 @@ /* Number of years in days */ for (i = STARTOFTIME; day >= days_in_year(i); i++) - day -= days_in_year(i); + day -= days_in_year(i); tm->tm_year = i; /* Number of months in days left */ if (leapyear(tm->tm_year)) - days_in_month(FEBRUARY) = 29; + days_in_month(FEBRUARY) = 29; for (i = 1; day >= days_in_month(i); i++) - day -= days_in_month(i); + day -= days_in_month(i); days_in_month(FEBRUARY) = 28; - tm->tm_mon = i-1; /* tm_mon starts from 0 to 11 */ + tm->tm_mon = i - 1; /* tm_mon starts from 0 to 11 */ /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; @@ -578,5 +666,10 @@ /* * Determine the day of week */ - tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ + tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ } + +EXPORT_SYMBOL(rtc_lock); +EXPORT_SYMBOL(to_tm); +EXPORT_SYMBOL(rtc_set_time); +EXPORT_SYMBOL(rtc_get_time); diff -urN linux-2.4.21/arch/mips/kernel/traps.c linux-2.4.22/arch/mips/kernel/traps.c --- linux-2.4.21/arch/mips/kernel/traps.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -4,13 +4,12 @@ * for more details. * * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle - * Modified for R3000 by Paul M. Antoine, 1995, 1996 - * Complete output from die() by Ulf Carlsson, 1998 + * Copyright (C) 1995, 1996 Paul M. Antoine + * Copyright (C) 1998 Ulf Carlsson * Copyright (C) 1999 Silicon Graphics, Inc. - * * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000, 01 MIPS Technologies, Inc. - * Copyright (C) 2002 Maciej W. Rozycki + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include #include @@ -24,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -32,21 +32,13 @@ #include #include #include +#include #include #include #include #include #include -/* - * Machine specific interrupt handlers - */ -extern asmlinkage void acer_pica_61_handle_int(void); -extern asmlinkage void decstation_handle_int(void); -extern asmlinkage void deskstation_rpc44_handle_int(void); -extern asmlinkage void deskstation_tyne_handle_int(void); -extern asmlinkage void mips_magnum_4000_handle_int(void); - extern asmlinkage void handle_mod(void); extern asmlinkage void handle_tlbl(void); extern asmlinkage void handle_tlbs(void); @@ -61,6 +53,7 @@ extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_mdmx(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); @@ -68,9 +61,8 @@ extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx); -char watch_available = 0; - -int (*be_board_handler)(struct pt_regs *regs, int is_fixup); +void (*board_be_init)(void); +int (*board_be_handler)(struct pt_regs *regs, int is_fixup); int kstack_depth_to_print = 24; @@ -81,107 +73,6 @@ #define MODULE_RANGE (8*1024*1024) /* - * This stuff is needed for the userland ll-sc emulation for R2300 - */ - -#define OPCODE 0xfc000000 -#define BASE 0x03e00000 -#define RT 0x001f0000 -#define OFFSET 0x0000ffff -#define LL 0xc0000000 -#define SC 0xe0000000 - -/* - * The ll_bit is cleared by r*_switch.S - */ - -unsigned long ll_bit; -#ifdef CONFIG_PROC_FS -extern unsigned long ll_ops; -extern unsigned long sc_ops; -#endif - -static struct task_struct *ll_task = NULL; - -static inline void simulate_ll(struct pt_regs *regp, unsigned int opcode) -{ - unsigned long value, *vaddr; - long offset; - int signal = 0; - - /* - * analyse the ll instruction that just caused a ri exception - * and put the referenced address to addr. - */ - - /* sign extend offset */ - offset = opcode & OFFSET; - offset <<= 16; - offset >>= 16; - - vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); - -#ifdef CONFIG_PROC_FS - ll_ops++; -#endif - - if ((unsigned long)vaddr & 3) - signal = SIGBUS; - else if (get_user(value, vaddr)) - signal = SIGSEGV; - else { - if (ll_task == NULL || ll_task == current) { - ll_bit = 1; - } else { - ll_bit = 0; - } - ll_task = current; - regp->regs[(opcode & RT) >> 16] = value; - } - if (compute_return_epc(regp)) - return; - if (signal) - send_sig(signal, current, 1); -} - -static inline void simulate_sc(struct pt_regs *regp, unsigned int opcode) -{ - unsigned long *vaddr, reg; - long offset; - int signal = 0; - - /* - * analyse the sc instruction that just caused a ri exception - * and put the referenced address to addr. - */ - - /* sign extend offset */ - offset = opcode & OFFSET; - offset <<= 16; - offset >>= 16; - - vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); - reg = (opcode & RT) >> 16; - -#ifdef CONFIG_PROC_FS - sc_ops++; -#endif - - if ((unsigned long)vaddr & 3) - signal = SIGBUS; - else if (ll_bit == 0 || ll_task != current) - regp->regs[reg] = 0; - else if (put_user(regp->regs[reg], vaddr)) - signal = SIGSEGV; - else - regp->regs[reg] = 1; - if (compute_return_epc(regp)) - return; - if (signal) - send_sig(signal, current, 1); -} - -/* * If the address is either in the .text section of the * kernel, or in the vmalloc'ed module regions, it *may* * be the address of a calling routine @@ -320,7 +211,7 @@ } } -void show_regs(struct pt_regs * regs) +void show_regs(struct pt_regs *regs) { /* * Saved main processor registers @@ -330,10 +221,10 @@ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11], - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); + regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19], - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); + regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n", regs->regs[24], regs->regs[25], regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); @@ -433,7 +324,7 @@ spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp != NULL; mp = mp->next) { if (!mod_member_present(mp, archdata_end) || - !mod_archdata_member_present(mp, struct archdata, + !mod_archdata_member_present(mp, struct archdata, dbe_table_end)) continue; ap = (struct archdata *)(mp->archdata_start); @@ -464,8 +355,8 @@ if (fixup) action = MIPS_BE_FIXUP; - if (be_board_handler) - action = be_board_handler(regs, fixup != 0); + if (board_be_handler) + action = board_be_handler(regs, fixup != 0); switch (action) { case MIPS_BE_DISCARD: @@ -492,12 +383,151 @@ force_sig(SIGBUS, current); } -asmlinkage void do_ov(struct pt_regs *regs) +static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) { - siginfo_t info; + unsigned int *epc; + + epc = (unsigned int *) regs->cp0_epc + + ((regs->cp0_cause & CAUSEF_BD) != 0); + if (!get_user(*opcode, epc)) + return 0; + + force_sig(SIGSEGV, current); + return 1; +} + +/* + * ll/sc emulation + */ + +#define OPCODE 0xfc000000 +#define BASE 0x03e00000 +#define RT 0x001f0000 +#define OFFSET 0x0000ffff +#define LL 0xc0000000 +#define SC 0xe0000000 + +/* + * The ll_bit is cleared by r*_switch.S + */ + +unsigned long ll_bit; - if (compute_return_epc(regs)) +static struct task_struct *ll_task = NULL; + +static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long value, *vaddr; + long offset; + int signal = 0; + + /* + * analyse the ll instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (get_user(value, vaddr)) { + signal = SIGSEGV; + goto sig; + } + + if (ll_task == NULL || ll_task == current) { + ll_bit = 1; + } else { + ll_bit = 0; + } + ll_task = current; + + regs->regs[(opcode & RT) >> 16] = value; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long *vaddr, reg; + long offset; + int signal = 0; + + /* + * analyse the sc instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + reg = (opcode & RT) >> 16; + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (ll_bit == 0 || ll_task != current) { + regs->regs[reg] = 0; + compute_return_epc(regs); return; + } + + if (put_user(regs->regs[reg], vaddr)) { + signal = SIGSEGV; + goto sig; + } + + regs->regs[reg] = 1; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +/* + * ll uses the opcode of lwc0 and sc uses the opcode of swc0. That is both + * opcodes are supposed to result in coprocessor unusable exceptions if + * executed on ll/sc-less processors. That's the theory. In practice a + * few processors such as NEC's VR4100 throw reserved instruction exceptions + * instead, so we're doing the emulation thing in both exception handlers. + */ +static inline int simulate_llsc(struct pt_regs *regs) +{ + unsigned int opcode; + + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; + + if ((opcode & OPCODE) == LL) { + simulate_ll(regs, opcode); + return 0; + } + if ((opcode & OPCODE) == SC) { + simulate_sc(regs, opcode); + return 0; + } +} + +asmlinkage void do_ov(struct pt_regs *regs) +{ + siginfo_t info; info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; @@ -541,36 +571,14 @@ /* If something went wrong, signal */ if (sig) - { - /* - * Return EPC is not calculated in the FPU emulator, - * if a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); force_sig(sig, current); - } return; } - if (compute_return_epc(regs)) - return; force_sig(SIGFPE, current); } -static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) -{ - unsigned long *epc; - - epc = (unsigned long *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (!get_user(*opcode, epc)) - return 0; - - force_sig(SIGSEGV, current); - return 1; -} - asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; @@ -611,8 +619,8 @@ asmlinkage void do_tr(struct pt_regs *regs) { - siginfo_t info; unsigned int opcode, tcode = 0; + siginfo_t info; if (get_insn_opcode(regs, &opcode)) return; @@ -644,109 +652,67 @@ } } -/* - * userland emulation for R2300 CPUs - * needed for the multithreading part of glibc - * - * this implementation can handle only sychronization between 2 or more - * user contexts and is not SMP safe. - */ asmlinkage void do_ri(struct pt_regs *regs) { die_if_kernel("Reserved instruction in kernel code", regs); -#ifndef CONFIG_CPU_HAS_LLSC - -#ifdef CONFIG_SMP -#error "ll/sc emulation is not SMP safe" -#endif - - { - unsigned int opcode; - - if (!get_insn_opcode(regs, &opcode)) { - if ((opcode & OPCODE) == LL) { - simulate_ll(regs, opcode); - return; - } - if ((opcode & OPCODE) == SC) { - simulate_sc(regs, opcode); + if (!cpu_has_llsc) + if (!simulate_llsc(regs)) return; - } - } - } -#endif /* CONFIG_CPU_HAS_LLSC */ - if (compute_return_epc(regs)) - return; force_sig(SIGILL, current); } asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; - void fpu_emulator_init_fpu(void); - int sig; - - cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (cpid != 1) - goto bad_cid; - if (!(mips_cpu.options & MIPS_CPU_FPU)) - goto fp_emul; + die_if_kernel("do_cpu invoked from kernel context!", regs); - regs->cp0_status |= ST0_CU1; - if (last_task_used_math == current) - return; + cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (current->used_math) { /* Using the FPU again. */ - lazy_fpu_switch(last_task_used_math); - } else { /* First time FPU user. */ - if (last_task_used_math != NULL) - save_fp(last_task_used_math); - init_fpu(); - current->used_math = 1; - } - last_task_used_math = current; + switch (cpid) { + case 0: + if (cpu_has_llsc) + break; - return; + if (!simulate_llsc(regs)) + return; + break; -fp_emul: - if (last_task_used_math != current) { - if (!current->used_math) { - fpu_emulator_init_fpu(); + case 1: + own_fpu(); + if (current->used_math) { /* Using the FPU again. */ + restore_fp(current); + } else { /* First time FPU user. */ + init_fpu(); current->used_math = 1; } - } - sig = fpu_emulator_cop1Handler(0, regs, ¤t->thread.fpu.soft); - last_task_used_math = current; - if (sig) { - /* - * Return EPC is not calculated in the FPU emulator, if - * a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); - force_sig(sig, current); - } - return; -bad_cid: -#ifndef CONFIG_CPU_HAS_LLSC - switch (mips_cpu.cputype) { - case CPU_TX3927: - case CPU_TX39XX: - do_ri(regs); + if (!cpu_has_fpu) { + int sig = fpu_emulator_cop1Handler(0, regs, + ¤t->thread.fpu.soft); + if (sig) + force_sig(sig, current); + } + return; + + case 2: + case 3: + break; } -#endif - compute_return_epc(regs); + force_sig(SIGILL, current); } -asmlinkage void do_watch(struct pt_regs *regs) +asmlinkage void do_mdmx(struct pt_regs *regs) { - extern void dump_tlb_all(void); + force_sig(SIGILL, current); +} +asmlinkage void do_watch(struct pt_regs *regs) +{ /* * We use the watch exception where available to detect stack * overflows. @@ -777,15 +743,8 @@ * hard/software error. */ show_regs(regs); - panic("Caught reserved exception - should not happen."); -} - -static inline void watch_init(void) -{ - if (mips_cpu.options & MIPS_CPU_WATCH ) { - set_except_vector(23, handle_watch); - watch_available = 1; - } + panic("Caught reserved exception %ld - should not happen.", + (regs->cp0_cause & 0x7f) >> 2); } /* @@ -794,14 +753,12 @@ */ static inline void parity_protection_init(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_5KC: - /* Set the PE bit (bit 31) in the CP0_ECC register. */ + /* Set the PE bit (bit 31) in the c0_ecc register. */ printk(KERN_INFO "Enable the cache parity protection for " "MIPS 5KC CPUs.\n"); - write_32bit_cp0_register(CP0_ECC, - read_32bit_cp0_register(CP0_ECC) - | 0x80000000); + write_c0_ecc(read_c0_ecc() | 0x80000000); break; default: break; @@ -813,13 +770,12 @@ unsigned int reg_val; /* For the moment, report the problem and hang. */ - reg_val = read_32bit_cp0_register(CP0_ERROREPC); printk("Cache error exception:\n"); - printk("cp0_errorepc == %08x\n", reg_val); - reg_val = read_32bit_cp0_register(CP0_CACHEERR); - printk("cp0_cacheerr == %08x\n", reg_val); + printk("cp0_errorepc == %08lx\n", read_c0_errorepc()); + reg_val = read_c0_cacheerr(); + printk("c0_cacheerr == %08x\n", reg_val); - printk("Decoded CP0_CACHEERR: %s cache fault in %s reference.\n", + printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", reg_val & (1<<30) ? "secondary" : "primary", reg_val & (1<<31) ? "data" : "insn"); printk("Error bits: %s%s%s%s%s%s%s\n", @@ -832,13 +788,13 @@ reg_val & (1<<22) ? "E0 " : ""); printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); - if (reg_val&(1<<22)) - printk("DErrAddr0: 0x%08x\n", - read_32bit_cp0_set1_register(CP0_S1_DERRADDR0)); - - if (reg_val&(1<<23)) - printk("DErrAddr1: 0x%08x\n", - read_32bit_cp0_set1_register(CP0_S1_DERRADDR1)); +#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) + if (reg_val & (1<<22)) + printk("DErrAddr0: 0x%08lx\n", read_c0_derraddr0()); + + if (reg_val & (1<<23)) + printk("DErrAddr1: 0x%08lx\n", read_c0_derraddr1()); +#endif panic("Can't handle the cache error!"); } @@ -849,31 +805,32 @@ */ void ejtag_exception_handler(struct pt_regs *regs) { - unsigned int depc, old_epc, debug; + unsigned long depc, old_epc; + unsigned int debug; - printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); - depc = read_32bit_cp0_register(CP0_DEPC); - debug = read_32bit_cp0_register(CP0_DEBUG); - printk("DEPC = %08x, DEBUG = %08x\n", depc, debug); - if (debug & 0x80000000) { - /* - * In branch delay slot. - * We cheat a little bit here and use EPC to calculate the - * debug return address (DEPC). EPC is restored after the - * calculation. - */ - old_epc = regs->cp0_epc; - regs->cp0_epc = depc; - __compute_return_epc(regs); - depc = regs->cp0_epc; - regs->cp0_epc = old_epc; - } else - depc += 4; - write_32bit_cp0_register(CP0_DEPC, depc); + printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); + depc = read_c0_depc(); + debug = read_c0_debug(); + printk("c0_depc = %08lx, DEBUG = %08x\n", depc, debug); + if (debug & 0x80000000) { + /* + * In branch delay slot. + * We cheat a little bit here and use EPC to calculate the + * debug return address (DEPC). EPC is restored after the + * calculation. + */ + old_epc = regs->cp0_epc; + regs->cp0_epc = depc; + __compute_return_epc(regs); + depc = regs->cp0_epc; + regs->cp0_epc = old_epc; + } else + depc += 4; + write_c0_depc(depc); #if 0 printk("\n\n----- Enable EJTAG single stepping ----\n\n"); - write_32bit_cp0_register(CP0_DEBUG, debug | 0x100); + write_c0_debug(debug | 0x100); #endif } @@ -882,9 +839,9 @@ */ void nmi_exception_handler(struct pt_regs *regs) { - printk("NMI taken!!!!\n"); - die("NMI", regs); - while(1) ; /* We die here. */ + printk("NMI taken!!!!\n"); + die("NMI", regs); + while(1) ; } unsigned long exception_handlers[32]; @@ -900,7 +857,7 @@ unsigned long old_handler = exception_handlers[n]; exception_handlers[n] = handler; - if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) { + if (n == 0 && cpu_has_divec) { *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | (0x03ffffff & (handler >> 2)); flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); @@ -910,6 +867,7 @@ asmlinkage int (*save_fp_context)(struct sigcontext *sc); asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + extern asmlinkage int _save_fp_context(struct sigcontext *sc); extern asmlinkage int _restore_fp_context(struct sigcontext *sc); @@ -921,33 +879,40 @@ unsigned int cpu = smp_processor_id(); /* Some firmware leaves the BEV flag set, clear it. */ - clear_cp0_status(ST0_BEV); + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); + + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + set_c0_status(ST0_XX); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - if (mips_cpu.options & MIPS_CPU_DIVEC) - set_cp0_cause(CAUSEF_IV); + if (cpu_has_divec) + set_c0_cause(CAUSEF_IV); cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; - set_context(cpu << 23); + write_c0_context(cpu << 23); + + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + if (current->mm) + BUG(); + enter_lazy_tlb(&init_mm, current, cpu); } void __init trap_init(void) { - extern char except_vec1_generic, except_vec2_generic; + extern char except_vec1_generic; extern char except_vec3_generic, except_vec3_r4000; - extern char except_vec4; extern char except_vec_ejtag_debug; + extern char except_vec4; unsigned long i; per_cpu_trap_init(); /* Copy the generic exception handler code to it's final destination. */ memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); /* * Setup default vectors @@ -959,23 +924,22 @@ * Copy the EJTAG debug exception vector handler code to it's final * destination. */ - if (mips_cpu.options & MIPS_CPU_EJTAG) + if (cpu_has_ejtag) memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80); /* * Only some CPUs have the watch exceptions or a dedicated * interrupt vector. */ - watch_init(); + if (cpu_has_watch) + set_except_vector(23, handle_watch); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - if (mips_cpu.options & MIPS_CPU_DIVEC) { + if (cpu_has_divec) memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8); - set_cp0_cause(CAUSEF_IV); - } /* * Some CPUs can enable/disable for cache parity detection, but does @@ -988,7 +952,8 @@ * by external hardware. Therefore these two exceptions * may have board specific handlers. */ - bus_error_init(); + if (board_be_init) + board_be_init(); set_except_vector(1, handle_mod); set_except_vector(2, handle_tlbl); @@ -1005,46 +970,23 @@ set_except_vector(11, handle_cpu); set_except_vector(12, handle_ov); set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); - if ((mips_cpu.options & MIPS_CPU_FPU) && - !(mips_cpu.options & MIPS_CPU_NOFPUEX)) + if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); - if (mips_cpu.options & MIPS_CPU_MCHECK) + + if (cpu_has_mcheck) set_except_vector(24, handle_mcheck); - /* - * Handling the following exceptions depends mostly of the cpu type - */ - if ((mips_cpu.options & MIPS_CPU_4KEX) - && (mips_cpu.options & MIPS_CPU_4KTLB)) { - /* Cache error vector already set above. */ - - if (mips_cpu.options & MIPS_CPU_VCE) { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, - 0x80); - } - } else switch (mips_cpu.cputype) { - case CPU_SB1: - /* - * XXX - This should be folded in to the "cleaner" handling, - * above - */ + if (cpu_has_vce) memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80); -#ifdef CONFIG_SB1_CACHE_ERROR - { - /* Special cache error handler for SB1 */ - extern char except_vec2_sb1; - memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); - memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); - } -#endif + else if (cpu_has_4kex) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); + else + memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80); - /* Enable timer interrupt and scd mapped interrupt */ - clear_cp0_status(0xf000); - set_cp0_status(0xc00); - break; - case CPU_R6000: - case CPU_R6000A: + if (current_cpu_data.cputype == CPU_R6000 || + current_cpu_data.cputype == CPU_R6000A) { /* * The R6000 is the only R-series CPU that features a machine * check exception (similar to the R4000 cache error) and @@ -1055,29 +997,9 @@ */ //set_except_vector(14, handle_mc); //set_except_vector(15, handle_ndc); - case CPU_R2000: - case CPU_R3000: - case CPU_R3000A: - case CPU_R3041: - case CPU_R3051: - case CPU_R3052: - case CPU_R3081: - case CPU_R3081E: - case CPU_TX3912: - case CPU_TX3922: - case CPU_TX3927: - case CPU_TX39XX: - memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); - break; - - case CPU_UNKNOWN: - default: - panic("Unknown CPU type"); } - flush_icache_range(KSEG0, KSEG0 + 0x400); - - if (mips_cpu.options & MIPS_CPU_FPU) { + if (cpu_has_fpu) { save_fp_context = _save_fp_context; restore_fp_context = _restore_fp_context; } else { @@ -1085,10 +1007,9 @@ restore_fp_context = fpu_emulator_restore_context; } - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); + flush_icache_range(KSEG0, KSEG0 + 0x400); - atomic_inc(&init_mm.mm_count); /* XXX UP? */ + atomic_inc(&init_mm.mm_count); /* XXX UP? */ current->active_mm = &init_mm; /* XXX Must be done for all CPUs */ diff -urN linux-2.4.21/arch/mips/kernel/unaligned.c linux-2.4.22/arch/mips/kernel/unaligned.c --- linux-2.4.21/arch/mips/kernel/unaligned.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/kernel/unaligned.c 2003-08-25 04:44:40.000000000 -0700 @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1998, 2002 by Ralf Baechle + * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. * * This file contains exception handler for address error exception with the @@ -88,22 +88,21 @@ #define STR(x) __STR(x) #define __STR(x) #x -/* - * User code may only access USEG; kernel code may access the - * entire address space. - */ -#define check_axs(pc,a,s) \ - if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \ - goto sigbus; +#ifdef CONFIG_PROC_FS +unsigned long unaligned_instructions; +#endif static inline int emulate_load_store_insn(struct pt_regs *regs, - unsigned long addr, unsigned long pc) + void *addr, unsigned long pc, + unsigned long **regptr, unsigned long *newvalue) { union mips_instruction insn; unsigned long value, fixup; unsigned int res; regs->regs[0] = 0; + *regptr=NULL; + /* * This load never faults. */ @@ -143,8 +142,10 @@ * The remaining opcodes are the ones that are really of interest. */ case lh_op: - check_axs(pc, addr, 2); - __asm__(".set\tnoat\n" + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ (".set\tnoat\n" #ifdef __BIG_ENDIAN "1:\tlb\t%0, 0(%2)\n" "2:\tlbu\t$1, 1(%2)\n\t" @@ -169,12 +170,15 @@ : "r" (addr), "i" (-EFAULT)); if (res) goto fault; - regs->regs[insn.i_format.rt] = value; - return 0; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lw_op: - check_axs(pc, addr, 4); - __asm__( + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN "1:\tlwl\t%0, (%2)\n" "2:\tlwr\t%0, 3(%2)\n\t" @@ -196,12 +200,15 @@ : "r" (addr), "i" (-EFAULT)); if (res) goto fault; - regs->regs[insn.i_format.rt] = value; - return 0; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lhu_op: - check_axs(pc, addr, 2); - __asm__( + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ ( ".set\tnoat\n" #ifdef __BIG_ENDIAN "1:\tlbu\t%0, 0(%2)\n" @@ -227,18 +234,102 @@ : "r" (addr), "i" (-EFAULT)); if (res) goto fault; - regs->regs[insn.i_format.rt] = value; - return 0; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lwu_op: +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( +#ifdef __BIG_ENDIAN + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" +#endif +#ifdef __LITTLE_ENDIAN + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" +#endif + "dsll\t%0, %0, 32\n\t" + "dsrl\t%0, %0, 32\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" + ".section\t__ex_table,\"a\"\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" + ".previous" + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; + case ld_op: +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 8)) + goto sigbus; + + __asm__ __volatile__ ( +#ifdef __BIG_ENDIAN + "1:\tldl\t%0, (%2)\n" + "2:\tldr\t%0, 7(%2)\n\t" +#endif +#ifdef __LITTLE_ENDIAN + "1:\tldl\t%0, 7(%2)\n" + "2:\tldr\t%0, (%2)\n\t" +#endif + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" + ".section\t__ex_table,\"a\"\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" + ".previous" + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + /* Cannot handle 64-bit instructions in 32-bit kernel */ goto sigill; case sh_op: - check_axs(pc, addr, 2); + if (verify_area(VERIFY_WRITE, addr, 2)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN ".set\tnoat\n" "1:\tsb\t%1, 1(%2)\n\t" @@ -267,12 +358,14 @@ : "r" (value), "r" (addr), "i" (-EFAULT)); if (res) goto fault; - return 0; + break; case sw_op: - check_axs(pc, addr, 4); + if (verify_area(VERIFY_WRITE, addr, 4)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN "1:\tswl\t%1,(%2)\n" "2:\tswr\t%1, 3(%2)\n\t" @@ -295,9 +388,47 @@ : "r" (value), "r" (addr), "i" (-EFAULT)); if (res) goto fault; - return 0; + break; case sd_op: +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_WRITE, addr, 8)) + goto sigbus; + + value = regs->regs[insn.i_format.rt]; + __asm__ __volatile__ ( +#ifdef __BIG_ENDIAN + "1:\tsdl\t%1,(%2)\n" + "2:\tsdr\t%1, 7(%2)\n\t" +#endif +#ifdef __LITTLE_ENDIAN + "1:\tsdl\t%1, 7(%2)\n" + "2:\tsdr\t%1, (%2)\n\t" +#endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" + ".section\t__ex_table,\"a\"\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" + ".previous" + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; +#endif /* CONFIG_MIPS64 */ + /* Cannot handle 64-bit instructions in 32-bit kernel */ goto sigill; @@ -328,6 +459,11 @@ */ goto sigill; } + +#ifdef CONFIG_PROC_FS + unaligned_instructions++; +#endif + return 0; fault: @@ -356,23 +492,21 @@ sigill: die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs); send_sig(SIGILL, current, 1); + return 0; } -#ifdef CONFIG_PROC_FS -unsigned long unaligned_instructions; -#endif - asmlinkage void do_ade(struct pt_regs *regs) { - unsigned long pc; + unsigned long *regptr, newval; extern int do_dsemulret(struct pt_regs *); + mm_segment_t seg; + unsigned long pc; /* - * Address errors may be deliberately induced - * by the FPU emulator to take retake control - * of the CPU after executing the instruction - * in the delay slot of an emulated branch. + * Address errors may be deliberately induced by the FPU emulator to + * retake control of the CPU after executing the instruction in the + * delay slot of an emulated branch. */ /* Terminate if exception was recognized as a delay slot return */ if (do_dsemulret(regs)) @@ -382,13 +516,12 @@ /* * Did we catch a fault trying to load an instruction? - * This also catches attempts to activate MIPS16 code on - * CPUs which don't support it. + * Or are we running in MIPS16 mode? */ - if (regs->cp0_badvaddr == regs->cp0_epc) + if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1)) goto sigbus; - pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); + pc = exception_epc(regs); if ((current->thread.mflags & MF_FIXADE) == 0) goto sigbus; @@ -396,12 +529,20 @@ * Do branch emulation only if we didn't forward the exception. * This is all so but ugly ... */ - if (!emulate_load_store_insn(regs, regs->cp0_badvaddr, pc)) + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); + if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc, + ®ptr, &newval)) { compute_return_epc(regs); - -#ifdef CONFIG_PROC_FS - unaligned_instructions++; -#endif + /* + * Now that branch is evaluated, update the dest + * register if necessary + */ + if (regptr) + *regptr = newval; + } + set_fs(seg); return; @@ -412,6 +553,4 @@ /* * XXX On return from the signal handler we should advance the epc */ - - return; } diff -urN linux-2.4.21/arch/mips/kernel/vm86.c linux-2.4.22/arch/mips/kernel/vm86.c --- linux-2.4.21/arch/mips/kernel/vm86.c 1997-06-26 12:33:37.000000000 -0700 +++ linux-2.4.22/arch/mips/kernel/vm86.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,13 +0,0 @@ -/* - * arch/mips/vm86.c - * - * Copyright (C) 1994 Waldorf GMBH, - * written by Ralf Baechle - */ -#include -#include - -asmlinkage int sys_vm86(void *v86) -{ - return -ENOSYS; -} diff -urN linux-2.4.21/arch/mips/lasat/Makefile linux-2.4.22/arch/mips/lasat/Makefile --- linux-2.4.21/arch/mips/lasat/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,22 @@ +# +# Makefile for the LASAT specific kernel interface routines under Linux. +# +USE_STANDARD_AS_RULE := 1 + +O_TARGET := lasatkern.o +obj-y := reset.o setup.o prom.o lasat_board.o \ + crc32.o at93c.o interrupt.o lasatIRQ.o + +obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o + +obj-$(CONFIG_DS1603) += ds1603.o + +obj-$(CONFIG_PICVUE) += picvue.o +obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o + +obj-$(CONFIG_PCI) += pci.o + +include $(TOPDIR)/Rules.make + +clean: + make -C image clean diff -urN linux-2.4.21/arch/mips/lasat/at93c.c linux-2.4.22/arch/mips/lasat/at93c.c --- linux-2.4.21/arch/mips/lasat/at93c.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/at93c.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,148 @@ +/* + * Atmel AT93C46 serial eeprom driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include +#include + +#include "at93c.h" + +#define AT93C_ADDR_SHIFT 7 +#define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1) +#define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT) +#define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT) +#define AT93C_WENCMD 0x260 +#define AT93C_WDSCMD 0x200 + +struct at93c_defs *at93c; + +static void at93c_reg_write(u32 val) +{ + *at93c->reg = val; +} + +static u32 at93c_reg_read(void) +{ + u32 tmp = *at93c->reg; + return tmp; +} + +static u32 at93c_datareg_read(void) +{ + u32 tmp = *at93c->rdata_reg; + return tmp; +} + +static void at93c_cycle_clk(u32 data) +{ + at93c_reg_write(data | at93c->clk); + lasat_ndelay(250); + at93c_reg_write(data & ~at93c->clk); + lasat_ndelay(250); +} + +static void at93c_write_databit(u8 bit) +{ + u32 data = at93c_reg_read(); + if (bit) + data |= 1 << at93c->wdata_shift; + else + data &= ~(1 << at93c->wdata_shift); + + at93c_reg_write(data); + lasat_ndelay(100); + at93c_cycle_clk(data); +} + +static unsigned int at93c_read_databit(void) +{ + u32 data; + + at93c_cycle_clk(at93c_reg_read()); + data = (at93c_datareg_read() >> at93c->rdata_shift) & 1; + return data; +} + +static u8 at93c_read_byte(void) +{ + int i; + u8 data = 0; + + for (i = 0; i<=7; i++) { + data <<= 1; + data |= at93c_read_databit(); + } + return data; +} + +static void at93c_write_bits(u32 data, int size) +{ + int i; + int shift = size - 1; + u32 mask = (1 << shift); + + for (i = 0; i < size; i++) { + at93c_write_databit((data & mask) >> shift); + data <<= 1; + } +} + +static void at93c_init_op(void) +{ + at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift)); + lasat_ndelay(50); +} + +static void at93c_end_op(void) +{ + at93c_reg_write(at93c_reg_read() & ~at93c->cs); + lasat_ndelay(250); +} + +static void at93c_wait(void) +{ + at93c_init_op(); + while (!at93c_read_databit()) + ; + at93c_end_op(); +}; + +static void at93c_disable_wp(void) +{ + at93c_init_op(); + at93c_write_bits(AT93C_WENCMD, 10); + at93c_end_op(); +} + +static void at93c_enable_wp(void) +{ + at93c_init_op(); + at93c_write_bits(AT93C_WDSCMD, 10); + at93c_end_op(); +} + +u8 at93c_read(u8 addr) +{ + u8 byte; + at93c_init_op(); + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10); + byte = at93c_read_byte(); + at93c_end_op(); + return byte; +} + +void at93c_write(u8 addr, u8 data) +{ + at93c_disable_wp(); + at93c_init_op(); + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10); + at93c_write_bits(data, 8); + at93c_end_op(); + at93c_wait(); + at93c_enable_wp(); +} diff -urN linux-2.4.21/arch/mips/lasat/at93c.h linux-2.4.22/arch/mips/lasat/at93c.h --- linux-2.4.21/arch/mips/lasat/at93c.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/at93c.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,18 @@ +/* + * Atmel AT93C46 serial eeprom driver + * + * Brian Murphy + * + */ + +extern struct at93c_defs { + volatile u32 *reg; + volatile u32 *rdata_reg; + int rdata_shift; + int wdata_shift; + u32 cs; + u32 clk; +} *at93c; + +u8 at93c_read(u8 addr); +void at93c_write(u8 addr, u8 data); diff -urN linux-2.4.21/arch/mips/lasat/crc32.c linux-2.4.22/arch/mips/lasat/crc32.c --- linux-2.4.21/arch/mips/lasat/crc32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/crc32.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,87 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#undef DYNAMIC_CRC_TABLE + +#define local static + +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +const unsigned long crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +unsigned long crc32(unsigned long crc, const unsigned char * buf, unsigned int len) +{ + if (buf == 0) return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff -urN linux-2.4.21/arch/mips/lasat/ds1603.c linux-2.4.22/arch/mips/lasat/ds1603.c --- linux-2.4.21/arch/mips/lasat/ds1603.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/ds1603.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,174 @@ +/* + * Dallas Semiconductors 1603 RTC driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include + +#include "ds1603.h" + +#define READ_TIME_CMD 0x81 +#define SET_TIME_CMD 0x80 +#define TRIMMER_SET_CMD 0xC0 +#define TRIMMER_VALUE_MASK 0x38 +#define TRIMMER_SHIFT 3 + +struct ds_defs *ds1603 = NULL; + +/* HW specific register functions */ +static void rtc_reg_write(unsigned long val) +{ + *ds1603->reg = val; +} + +static unsigned long rtc_reg_read(void) +{ + unsigned long tmp = *ds1603->reg; + return tmp; +} + +static unsigned long rtc_datareg_read(void) +{ + unsigned long tmp = *ds1603->data_reg; + return tmp; +} + +static void rtc_nrst_high(void) +{ + rtc_reg_write(rtc_reg_read() | ds1603->rst); +} + +static void rtc_nrst_low(void) +{ + rtc_reg_write(rtc_reg_read() & ~ds1603->rst); +} + +static void rtc_cycle_clock(unsigned long data) +{ + data |= ds1603->clk; + rtc_reg_write(data); + ndelay(250); + if (ds1603->data_reversed) + data &= ~ds1603->data; + else + data |= ds1603->data; + data &= ~ds1603->clk; + rtc_reg_write(data); + ndelay(250 + ds1603->huge_delay); +} + +static void rtc_write_databit(unsigned int bit) +{ + unsigned long data = rtc_reg_read(); + if (ds1603->data_reversed) + bit = !bit; + if (bit) + data |= ds1603->data; + else + data &= ~ds1603->data; + + rtc_reg_write(data); + ndelay(50 + ds1603->huge_delay); + rtc_cycle_clock(data); +} + +static unsigned int rtc_read_databit(void) +{ + unsigned int data; + + data = (rtc_datareg_read() & (1 << ds1603->data_read_shift)) + >> ds1603->data_read_shift; + rtc_cycle_clock(rtc_reg_read()); + return data; +} + +static void rtc_write_byte(unsigned int byte) +{ + int i; + + for (i = 0; i<=7; i++) { + rtc_write_databit(byte & 1L); + byte >>= 1; + } +} + +static void rtc_write_word(unsigned long word) +{ + int i; + + for (i = 0; i<=31; i++) { + rtc_write_databit(word & 1L); + word >>= 1; + } +} + +static unsigned long rtc_read_word(void) +{ + int i; + unsigned long word = 0; + unsigned long shift = 0; + + for (i = 0; i<=31; i++) { + word |= rtc_read_databit() << shift; + shift++; + } + return word; +} + +static void rtc_init_op(void) +{ + rtc_nrst_high(); + + rtc_reg_write(rtc_reg_read() & ~ds1603->clk); + + ndelay(50); +} + +static void rtc_end_op(void) +{ + rtc_nrst_low(); + ndelay(1000); +} + +/* interface */ +unsigned long ds1603_read(void) +{ + unsigned long word; + rtc_init_op(); + rtc_write_byte(READ_TIME_CMD); + word = rtc_read_word(); + rtc_end_op(); + return word; +} + +int ds1603_set(unsigned long time) +{ + rtc_init_op(); + rtc_write_byte(SET_TIME_CMD); + rtc_write_word(time); + rtc_end_op(); + + return 0; +} + +void ds1603_set_trimmer(unsigned int trimval) +{ + rtc_init_op(); + rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK) + | (TRIMMER_SET_CMD)); + rtc_end_op(); +} + +void ds1603_disable(void) +{ + ds1603_set_trimmer(TRIMMER_DISABLE_RTC); +} + +void ds1603_enable(void) +{ + ds1603_set_trimmer(TRIMMER_DEFAULT); +} diff -urN linux-2.4.21/arch/mips/lasat/ds1603.h linux-2.4.22/arch/mips/lasat/ds1603.h --- linux-2.4.21/arch/mips/lasat/ds1603.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/ds1603.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,33 @@ +/* + * Dallas Semiconductors 1603 RTC driver + * + * Brian Murphy + * + */ +#ifndef __DS1603_H +#define __DS1603_H + +struct ds_defs { + volatile u32 *reg; + volatile u32 *data_reg; + u32 rst; + u32 clk; + u32 data; + u32 data_read_shift; + char data_reversed; + u32 huge_delay; +}; + +extern struct ds_defs *ds1603; + +unsigned long ds1603_read(void); +int ds1603_set(unsigned long); +void ds1603_set_trimmer(unsigned int); +void ds1603_enable(void); +void ds1603_disable(void); +void ds1603_init(struct ds_defs *); + +#define TRIMMER_DEFAULT 3 +#define TRIMMER_DISABLE_RTC 0 + +#endif diff -urN linux-2.4.21/arch/mips/lasat/image/Makefile linux-2.4.22/arch/mips/lasat/image/Makefile --- linux-2.4.21/arch/mips/lasat/image/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/image/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,59 @@ +# +# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER +# +# i-data Networks +# +# Author: Thomas Horsten +# + +ifndef Version + Version = "$(USER)-test" +endif + +MKLASATIMG = mklasatimg +MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 +ifdef CONFIG_LASAT_SERVICE +MKLASATIMG_FLAG = -s +else +MKLASATIMG_FLAG = -k +endif + +KERNEL_IMAGE = $(TOPDIR)/vmlinux +KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep _ftext | cut -f1 -d\ ) +KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ ) + +LDSCRIPT= -Tromscript.normal + +AFLAGS_head.o = -D_kernel_start=0x$(KERNEL_START) \ + -D_kernel_entry=0x$(KERNEL_ENTRY) \ + -D VERSION="\"$(Version)\"" \ + -D TIMESTAMP=$(shell date +%s) + +head.o: $(KERNEL_IMAGE) + +OBJECTS= head.o kImage.o + +rom.sw: rom.bin + $(MKLASATIMG) -o rom.sw $(MKLASATIMG_FLAG) rom.bin -m $(MKLASATIMG_ARCH) + +rom.bin: rom + $(OBJCOPY) -O binary -S rom rom.bin + +# Rule to make the bootloader +rom: $(OBJECTS) + $(LD) $(LDFLAGS) $(LDSCRIPT) -o rom $(OBJECTS) + +%.o: %.gz + $(LD) -r -o $@ -b binary $< + +%.gz: %.bin + gzip -cf -9 $< > $@ + +kImage.bin: $(KERNEL_IMAGE) + $(OBJCOPY) -O binary -S $(TOPDIR)/vmlinux kImage.bin + +clean: + rm -f rom rom.bin rom.sw kImage.bin + +USE_STANDARD_AS_RULE = 1 +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/lasat/image/head.S linux-2.4.22/arch/mips/lasat/image/head.S --- linux-2.4.21/arch/mips/lasat/image/head.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/image/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,31 @@ +#include + + .text + .section .text.start, "ax" + .set noreorder + .set mips3 + + /* Magic words identifying a software image */ + .word LASAT_K_MAGIC0_VAL + .word LASAT_K_MAGIC1_VAL + + /* Image header version */ + .word 0x00000002 + + /* image start and size */ + .word _image_start + .word _image_size + + /* start of kernel and entrypoint in uncompressed image */ + .word _kernel_start + .word _kernel_entry + + /* Here we have room for future flags */ + + .org 0x40 +reldate: + .word TIMESTAMP + + .org 0x50 +release: + .string VERSION diff -urN linux-2.4.21/arch/mips/lasat/image/romscript.normal linux-2.4.22/arch/mips/lasat/image/romscript.normal --- linux-2.4.21/arch/mips/lasat/image/romscript.normal 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/image/romscript.normal 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,22 @@ +OUTPUT_ARCH(mips) + +SECTIONS +{ + .text : + { + *(.text.start) + } + + /* Data in ROM */ + + .data ALIGN(0x10) : + { + *(.data) + } + _image_start = ADDR(.data); + _image_size = SIZEOF(.data); + + .other : { + *(.*) + } +} diff -urN linux-2.4.21/arch/mips/lasat/interrupt.c linux-2.4.22/arch/mips/lasat/interrupt.c --- linux-2.4.21/arch/mips/lasat/interrupt.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/interrupt.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,192 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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. + * + * ######################################################################## + * + * Routines for generic manipulation of the interrupts found on the + * Lasat boards. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static volatile int *lasat_int_status = NULL; +static volatile int *lasat_int_mask = NULL; +static volatile int lasat_int_mask_shift; + +extern asmlinkage void mipsIRQ(void); + +#if 0 +#define DEBUG_INT(x...) printk(x) +#else +#define DEBUG_INT(x...) +#endif + +void disable_lasat_irq(unsigned int irq_nr) +{ + unsigned long flags; + DEBUG_INT("disable_lasat_irq: %d", irq_nr); + + local_irq_save(flags); + *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); +} + +void enable_lasat_irq(unsigned int irq_nr) +{ + unsigned long flags; + DEBUG_INT("enable_lasat_irq: %d", irq_nr); + + local_irq_save(flags); + *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); +} + +static unsigned int startup_lasat_irq(unsigned int irq) +{ + enable_lasat_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_lasat_irq disable_lasat_irq + +#define mask_and_ack_lasat_irq disable_lasat_irq + +static void end_lasat_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_lasat_irq(irq); +} + +static struct hw_interrupt_type lasat_irq_type = { + "Lasat", + startup_lasat_irq, + shutdown_lasat_irq, + enable_lasat_irq, + disable_lasat_irq, + mask_and_ack_lasat_irq, + end_lasat_irq, + NULL +}; + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +static unsigned long (* get_int_status)(void); + +static unsigned long get_int_status_100(void) +{ + return (*lasat_int_status & *lasat_int_mask); +} + +static unsigned long get_int_status_200(void) +{ + unsigned long int_status; + + int_status = *lasat_int_status; + int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff; + return int_status; +} + +void lasat_hw0_irqdispatch(struct pt_regs *regs) +{ + struct irqaction *action; + unsigned long int_status; + int irq, cpu = smp_processor_id(); + + int_status = get_int_status(); + + /* if int_status == 0, then the interrupt has already been cleared */ + if (int_status == 0) + return; + + irq = ls1bit32(int_status); + action = irq_desc[irq].action; + + DEBUG_INT("lasat_hw0_irqdispatch: irq=%d\n", irq); + + /* if action == NULL, then we don't have a handler for the irq */ + if (action == NULL) { + printk("No handler for hw0 irq: %i\n", irq); + atomic_inc(&irq_err_count); + return; + } + + irq_enter(cpu, irq); + kstat.irqs[0][irq]++; + action->handler(irq, action->dev_id, regs); + irq_exit(cpu, irq); + + return; +} + +void __init init_IRQ(void) +{ + int i; + + init_generic_irq(); + + switch (mips_machtype) { + case MACH_LASAT_100: + lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; + lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; + lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; + get_int_status = get_int_status_100; + *lasat_int_mask = 0; + break; + case MACH_LASAT_200: + lasat_int_status = (void *)LASAT_INT_STATUS_REG_200; + lasat_int_mask = (void *)LASAT_INT_MASK_REG_200; + lasat_int_mask_shift = LASATINT_MASK_SHIFT_200; + get_int_status = get_int_status_200; + *lasat_int_mask &= 0xffff; + break; + default: + panic("init_IRQ: mips_machtype incorrect"); + } + + /* Now safe to set the exception vector. */ + set_except_vector(0, mipsIRQ); + + for (i = 0; i <= LASATINT_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &lasat_irq_type; + } +} diff -urN linux-2.4.21/arch/mips/lasat/lasatIRQ.S linux-2.4.22/arch/mips/lasat/lasatIRQ.S --- linux-2.4.21/arch/mips/lasat/lasatIRQ.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/lasatIRQ.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,75 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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. + * + * ######################################################################## + * + * Interrupt exception dispatch code. + * + */ +#include + +#include +#include +#include +#include + + .text + .set noreorder + .set noat + .align 5 + NESTED(mipsIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 s0, CP0_CAUSE # get irq mask + + /* First we check for r4k counter/timer IRQ. */ + andi a0, s0, CAUSEF_IP7 + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt + + /* Wheee, a timer interrupt. */ + move a0, sp + jal lasat_timer_interrupt + nop + + j ret_from_irq + nop + +1: + /* Wheee, combined hardware level zero interrupt. */ + jal lasat_hw0_irqdispatch + move a0, sp # delay slot + + j ret_from_irq + nop # delay slot + +1: + /* + * Here by mistake? This is possible, what can happen is that by the + * time we take the exception the IRQ pin goes low, so just leave if + * this is the case. + */ + move a1,s0 + mfc0 a1, CP0_EPC + + j ret_from_irq + nop + END(mipsIRQ) diff -urN linux-2.4.21/arch/mips/lasat/lasat_board.c linux-2.4.22/arch/mips/lasat/lasat_board.c --- linux-2.4.21/arch/mips/lasat/lasat_board.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/lasat_board.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,279 @@ +/* + * lasat_board.c + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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. + * + * ######################################################################## + * + * Routines specific to the LASAT boards + */ +#include +#include +#include +#include +#include +#include +#include +#include "at93c.h" +/* New model description table */ +#include "lasat_models.h" +struct lasat_info lasat_board_info; + +unsigned long crc32(unsigned long, unsigned char *, int); +void update_bcastaddr(void); + +int EEPROMRead(unsigned int pos, unsigned char *data, int len) +{ + int i; + + for (i=0; i 0x200000) { + ls[LASAT_MTD_CONFIG] = 0x100000; + ls[LASAT_MTD_FS] = 0x500000; + } + } else { + lasat_board_info.li_flash_base = KSEG1ADDR(0x10000000); + + if (lasat_board_info.li_flash_size < 0x1000000) { + lb[LASAT_MTD_BOOTLOADER] = KSEG1ADDR(0x10000000); + ls[LASAT_MTD_CONFIG] = 0x100000; + if (lasat_board_info.li_flash_size >= 0x400000) { + ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000; + } + } + } + + for (i = 1; i < LASAT_MTD_LAST; i++) + lb[i] = lb[i-1] + ls[i-1]; +} + +int lasat_init_board_info(void) +{ + int c; + unsigned long crc; + unsigned long cfg0, cfg1; + const product_info_t *ppi; + int i_n_base_models = N_BASE_MODELS; + const char * const * i_txt_base_models = txt_base_models; + int i_n_prids = N_PRIDS; + + memset(&lasat_board_info, 0, sizeof(lasat_board_info)); + + /* First read the EEPROM info */ + EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, + sizeof(struct lasat_eeprom_struct)); + + /* Check the CRC */ + crc = crc32(0x0, (unsigned char *)(&lasat_board_info.li_eeprom_info), + sizeof(struct lasat_eeprom_struct) - 4); + + if (crc != lasat_board_info.li_eeprom_info.crc32) { + prom_printf("WARNING...\nWARNING...\nEEPROM CRC does not match calculated, attempting to soldier on...\n"); + } + + if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) + { + prom_printf("WARNING...\nWARNING...\nEEPROM version %d, wanted version %d, attempting to soldier on...\n", + (unsigned int)lasat_board_info.li_eeprom_info.version, + LASAT_EEPROM_VERSION); + } + + cfg0 = lasat_board_info.li_eeprom_info.cfg[0]; + cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; + + if ( LASAT_W0_DSCTYPE(cfg0) != 1) { + prom_printf("WARNING...\nWARNING...\nInvalid configuration read from EEPROM, attempting to soldier on..."); + } + /* We have a valid configuration */ + + switch (LASAT_W0_SDRAMBANKSZ(cfg0)) { + case 0: + lasat_board_info.li_memsize = 0x0800000; + break; + case 1: + lasat_board_info.li_memsize = 0x1000000; + break; + case 2: + lasat_board_info.li_memsize = 0x2000000; + break; + case 3: + lasat_board_info.li_memsize = 0x4000000; + break; + case 4: + lasat_board_info.li_memsize = 0x8000000; + break; + default: + lasat_board_info.li_memsize = 0; + } + + switch (LASAT_W0_SDRAMBANKS(cfg0)) { + case 0: + break; + case 1: + lasat_board_info.li_memsize *= 2; + break; + default: + break; + } + + switch (LASAT_W0_BUSSPEED(cfg0)) { + case 0x0: + lasat_board_info.li_bus_hz = 60000000; + break; + case 0x1: + lasat_board_info.li_bus_hz = 66000000; + break; + case 0x2: + lasat_board_info.li_bus_hz = 66666667; + break; + case 0x3: + lasat_board_info.li_bus_hz = 80000000; + break; + case 0x4: + lasat_board_info.li_bus_hz = 83333333; + break; + case 0x5: + lasat_board_info.li_bus_hz = 100000000; + break; + } + + switch (LASAT_W0_CPUCLK(cfg0)) { + case 0x0: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz; + break; + case 0x1: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + (lasat_board_info.li_bus_hz >> 1); + break; + case 0x2: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz; + break; + case 0x3: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz + + (lasat_board_info.li_bus_hz >> 1); + break; + case 0x4: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz; + break; + } + + /* Flash size */ + switch (LASAT_W1_FLASHSIZE(cfg1)) { + case 0: + lasat_board_info.li_flash_size = 0x200000; + break; + case 1: + lasat_board_info.li_flash_size = 0x400000; + break; + case 2: + lasat_board_info.li_flash_size = 0x800000; + break; + case 3: + lasat_board_info.li_flash_size = 0x1000000; + break; + case 4: + lasat_board_info.li_flash_size = 0x2000000; + break; + } + + init_flash_sizes(); + + lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0); + lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid; + if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0) + lasat_board_info.li_prid = lasat_board_info.li_bmid; + + /* Base model stuff */ + if (lasat_board_info.li_bmid > i_n_base_models) + lasat_board_info.li_bmid = i_n_base_models; + strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]); + + /* Product ID dependent values */ + c = lasat_board_info.li_prid; + if (c >= i_n_prids) { + strcpy(lasat_board_info.li_namestr, "Unknown Model"); + strcpy(lasat_board_info.li_typestr, "Unknown Type"); + } else { + ppi = &vendor_info_table[0].vi_product_info[c]; + strcpy(lasat_board_info.li_namestr, ppi->pi_name); + if (ppi->pi_type) + strcpy(lasat_board_info.li_typestr, ppi->pi_type); + else + sprintf(lasat_board_info.li_typestr, "%d",10*c); + } + +#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL) + update_bcastaddr(); +#endif + + return 0; +} + +void lasat_write_eeprom_info(void) +{ + unsigned long crc; + + /* Generate the CRC */ + crc = crc32(0x0, (unsigned char *)(&lasat_board_info.li_eeprom_info), + sizeof(struct lasat_eeprom_struct) - 4); + lasat_board_info.li_eeprom_info.crc32 = crc; + + /* Write the EEPROM info */ + EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, + sizeof(struct lasat_eeprom_struct)); +} + diff -urN linux-2.4.21/arch/mips/lasat/lasat_models.h linux-2.4.22/arch/mips/lasat/lasat_models.h --- linux-2.4.21/arch/mips/lasat/lasat_models.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/lasat_models.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,63 @@ +/* + * Model description tables + */ + +typedef struct product_info_t { + const char *pi_name; + const char *pi_type; +} product_info_t; + +typedef struct vendor_info_t { + const char *vi_name; + const product_info_t *vi_product_info; +} vendor_info_t; + +/* + * Base models + */ +static const char * const txt_base_models[] = { + "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown" +}; +#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1) + +/* + * Eicon Networks + */ +static const char txt_en_mq[] = "Masquerade"; +static const char txt_en_sp[] = "Safepipe"; + +static const product_info_t product_info_eicon[] = { + { txt_en_mq, "II" }, /* 0 */ + { txt_en_mq, "Pro" }, /* 1 */ + { txt_en_sp, "25" }, /* 2 */ + { txt_en_sp, "50" }, /* 3 */ + { txt_en_sp, "100" }, /* 4 */ + { txt_en_sp, "5000" }, /* 5 */ + { txt_en_sp, "7000" }, /* 6 */ + { txt_en_sp, "30" }, /* 7 */ + { txt_en_sp, "5100" }, /* 8 */ + { txt_en_sp, "7100" }, /* 9 */ + { txt_en_sp, "1110" }, /* 10 */ + { txt_en_sp, "3020" }, /* 11 */ + { txt_en_sp, "3030" }, /* 12 */ + { txt_en_sp, "5020" }, /* 13 */ + { txt_en_sp, "5030" }, /* 14 */ + { txt_en_sp, "1120" }, /* 15 */ + { txt_en_sp, "1130" }, /* 16 */ + { txt_en_sp, "6010" }, /* 17 */ + { txt_en_sp, "6110" }, /* 18 */ + { txt_en_sp, "6210" }, /* 19 */ + { txt_en_sp, "1020" }, /* 20 */ + { txt_en_sp, "1040" }, /* 21 */ + { txt_en_sp, "1050" }, /* 22 */ + { txt_en_sp, "1060" }, /* 23 */ +}; +#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t)) + +/* + * The vendor table + */ +static vendor_info_t const vendor_info_table[] = { + { "Eicon Networks", product_info_eicon }, +}; +#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t)) diff -urN linux-2.4.21/arch/mips/lasat/pci.c linux-2.4.22/arch/mips/lasat/pci.c --- linux-2.4.21/arch/mips/lasat/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +extern struct pci_ops nile4_pci_ops; +extern struct pci_ops gt64120_pci_ops; + +void __init pcibios_init(void) +{ + struct pci_ops *pci_ops; + + switch (mips_machtype) { + case MACH_LASAT_100: + pci_ops = >64120_pci_ops; + break; + case MACH_LASAT_200: + pci_ops = &nile4_pci_ops; + break; + default: + panic("pcibios_init: mips_machtype incorrect"); + } + + pci_scan_bus(0, pci_ops, NULL); +} + +void __init pcibios_fixup_bus(struct pci_bus *b) +{ +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +struct pci_fixup pcibios_fixups[] = { + { 0 } +}; diff -urN linux-2.4.21/arch/mips/lasat/picvue.c linux-2.4.22/arch/mips/lasat/picvue.c --- linux-2.4.21/arch/mips/lasat/picvue.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/picvue.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,241 @@ +/* + * Picvue PVC160206 display driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "picvue.h" + +#define PVC_BUSY 0x80 +#define PVC_NLINES 2 +#define PVC_DISPMEM 80 +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES + +struct pvc_defs *picvue = NULL; + +DECLARE_MUTEX(pvc_sem); + +static void pvc_reg_write(u32 val) +{ + *picvue->reg = val; +} + +static u32 pvc_reg_read(void) +{ + u32 tmp = *picvue->reg; + return tmp; +} + +static void pvc_write_byte(u32 data, u8 byte) +{ + data |= picvue->e; + pvc_reg_write(data); + data &= ~picvue->data_mask; + data |= byte << picvue->data_shift; + pvc_reg_write(data); + ndelay(220); + pvc_reg_write(data & ~picvue->e); + ndelay(220); +} + +static u8 pvc_read_byte(u32 data) +{ + u8 byte; + + data |= picvue->e; + pvc_reg_write(data); + ndelay(220); + byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift; + data &= ~picvue->e; + pvc_reg_write(data); + ndelay(220); + return byte; +} + +static u8 pvc_read_data(void) +{ + u32 data = pvc_reg_read(); + u8 byte; + data |= picvue->rw; + data &= ~picvue->rs; + pvc_reg_write(data); + ndelay(40); + byte = pvc_read_byte(data); + data |= picvue->rs; + pvc_reg_write(data); + return byte; +} + +#define TIMEOUT 1000 +static int pvc_wait(void) +{ + int i = TIMEOUT; + int err = 0; + + while ((pvc_read_data() & PVC_BUSY) && i) + i--; + if (i == 0) + err = -ETIME; + + return err; +} + +#define MODE_INST 0 +#define MODE_DATA 1 +static void pvc_write(u8 byte, int mode) +{ + u32 data = pvc_reg_read(); + data &= ~picvue->rw; + if (mode == MODE_DATA) + data |= picvue->rs; + else + data &= ~picvue->rs; + pvc_reg_write(data); + ndelay(40); + pvc_write_byte(data, byte); + if (mode == MODE_DATA) + data &= ~picvue->rs; + else + data |= picvue->rs; + pvc_reg_write(data); + pvc_wait(); +} + +void pvc_write_string(const unsigned char *str, u8 addr, int line) +{ + int i = 0; + + if (line > 0 && (PVC_NLINES > 1)) + addr += 0x40 * line; + pvc_write(0x80 | addr, MODE_INST); + + while (*str != 0 && i < PVC_LINELEN) { + pvc_write(*str++, MODE_DATA); + i++; + } +} + +void pvc_write_string_centered(const unsigned char *str, int line) +{ + int len = strlen(str); + u8 addr; + + if (len > PVC_VISIBLE_CHARS) + addr = 0; + else + addr = (PVC_VISIBLE_CHARS - strlen(str))/2; + + pvc_write_string(str, addr, line); +} + +void pvc_dump_string(const unsigned char *str) +{ + int len = strlen(str); + + pvc_clear(); + pvc_write_string(str, 0, 0); + if (len > PVC_VISIBLE_CHARS) + pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1); +} + +#define BM_SIZE 8 +#define MAX_PROGRAMMABLE_CHARS 8 +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]) +{ + int i; + int addr; + + if (charnum > MAX_PROGRAMMABLE_CHARS) + return -ENOENT; + + addr = charnum * 8; + pvc_write(0x40 | addr, MODE_INST); + + for (i=0; i + * + */ +#include + +struct pvc_defs { + volatile u32 *reg; + u32 data_shift; + u32 data_mask; + u32 e; + u32 rw; + u32 rs; +}; + +extern struct pvc_defs *picvue; + +#define PVC_NLINES 2 +#define PVC_DISPMEM 80 +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES +#define PVC_VISIBLE_CHARS 16 + +void pvc_write_string(const unsigned char *str, u8 addr, int line); +void pvc_write_string_centered(const unsigned char *str, int line); +void pvc_dump_string(const unsigned char *str); + +#define BM_SIZE 8 +#define MAX_PROGRAMMABLE_CHARS 8 +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]); + +void pvc_dispcnt(u8 cmd); +#define DISP_OFF 0 +#define DISP_ON (1 << 2) +#define CUR_ON (1 << 1) +#define CUR_BLINK (1 << 0) + +void pvc_move(u8 cmd); +#define DISPLAY (1 << 3) +#define CURSOR 0 +#define RIGHT (1 << 2) +#define LEFT 0 + +void pvc_clear(void); +void pvc_home(void); + +extern struct semaphore pvc_sem; diff -urN linux-2.4.21/arch/mips/lasat/picvue_proc.c linux-2.4.22/arch/mips/lasat/picvue_proc.c --- linux-2.4.21/arch/mips/lasat/picvue_proc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/picvue_proc.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,186 @@ +/* + * Picvue PVC160206 display driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include + +#include +#include + +#include + +#include "picvue.h" + +static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; +static int pvc_linedata[PVC_NLINES]; +static struct proc_dir_entry *pvc_display_dir; +static char *pvc_linename[PVC_NLINES] = {"line1", "line2"}; +#define DISPLAY_DIR_NAME "display" +static int scroll_dir = 0, scroll_interval = 0; + +static struct timer_list timer; + +static void pvc_display(unsigned long data) { + int i; + + pvc_clear(); + for (i=0; i PVC_NLINES) { + printk("proc_read_line: invalid lineno %d\n", lineno); + return 0; + } + + down(&pvc_sem); + page += sprintf(page, "%s\n", pvc_lines[lineno]); + up(&pvc_sem); + + return page - origpage; +} + +static int pvc_proc_write_line(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int origcount = count; + int lineno = *(int *)data; + + if (lineno < 0 || lineno > PVC_NLINES) { + printk("proc_write_line: invalid lineno %d\n", lineno); + return origcount; + } + + if (count > PVC_LINELEN) + count = PVC_LINELEN; + + if (buffer[count-1] == '\n') + count--; + + down(&pvc_sem); + strncpy(pvc_lines[lineno], buffer, count); + pvc_lines[lineno][count] = '\0'; + up(&pvc_sem); + + tasklet_schedule(&pvc_display_tasklet); + + return origcount; +} + +static int pvc_proc_write_scroll(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int origcount = count; + int cmd = simple_strtol(buffer, NULL, 10); + + down(&pvc_sem); + if (scroll_interval != 0) + del_timer(&timer); + + if (cmd == 0) { + scroll_dir = 0; + scroll_interval = 0; + } else { + if (cmd < 0) { + scroll_dir = -1; + scroll_interval = -cmd; + } else { + scroll_dir = 1; + scroll_interval = cmd; + } + add_timer(&timer); + } + up(&pvc_sem); + + return origcount; +} + +static int pvc_proc_read_scroll(char *page, char **start, + off_t off, int count, + int *eof, void *data) +{ + char *origpage = page; + + down(&pvc_sem); + page += sprintf(page, "%d\n", scroll_dir * scroll_interval); + up(&pvc_sem); + + return page - origpage; +} + + +void pvc_proc_timerfunc(unsigned long data) +{ + if (scroll_dir < 0) + pvc_move(DISPLAY|RIGHT); + else if (scroll_dir > 0) + pvc_move(DISPLAY|LEFT); + + timer.expires = jiffies + scroll_interval; + add_timer(&timer); +} + +static void pvc_proc_cleanup(void) +{ + int i; + for (i=0; iread_proc = pvc_proc_read_line; + proc_entry->write_proc = pvc_proc_write_line; + proc_entry->data = &pvc_linedata[i]; + } + proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir); + if (proc_entry == NULL) + goto error; + proc_entry->write_proc = pvc_proc_write_scroll; + proc_entry->read_proc = pvc_proc_read_scroll; + + init_timer(&timer); + timer.function = pvc_proc_timerfunc; + + return 0; +error: + pvc_proc_cleanup(); + return -ENOMEM; +} + +module_init(pvc_proc_init); +module_exit(pvc_proc_cleanup); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/arch/mips/lasat/prom.c linux-2.4.22/arch/mips/lasat/prom.c --- linux-2.4.21/arch/mips/lasat/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,140 @@ +/* + * PROM interface routines. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "at93c.h" +#include +#include "prom.h" + +#define RESET_VECTOR 0xbfc00000 +#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n)) +#define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0) +#define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1) +#define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2) + +static void null_prom_printf(const char * fmt, ...) +{ +} + +static void null_prom_display(const char *string, int pos, int clear) +{ +} + +static void null_prom_monitor(void) +{ +} + +static void null_prom_putc(char c) +{ +} + +/* these are functions provided by the bootloader */ +static void (* prom_putc)(char c) = null_prom_putc; +void (* prom_printf)(const char * fmt, ...) = null_prom_printf; +void (* prom_display)(const char *string, int pos, int clear) = + null_prom_display; +void (* prom_monitor)(void) = null_prom_monitor; + +unsigned int lasat_ndelay_divider; + +#define PROM_PRINTFBUF_SIZE 256 +static char prom_printfbuf[PROM_PRINTFBUF_SIZE]; + +static void real_prom_printf(const char * fmt, ...) +{ + va_list ap; + int len; + char *c = prom_printfbuf; + int i; + + va_start(ap, fmt); + len = vsnprintf(prom_printfbuf, PROM_PRINTFBUF_SIZE, fmt, ap); + va_end(ap); + + /* output overflowed the buffer */ + if (len < 0 || len > PROM_PRINTFBUF_SIZE) + len = PROM_PRINTFBUF_SIZE; + + for (i=0; i < len; i++) { + if (*c == '\n') + prom_putc('\r'); + prom_putc(*c++); + } +} + +static void setup_prom_vectors(void) +{ + u32 version = *(u32 *)(RESET_VECTOR + 0x90); + + if (version == 306) { + prom_display = (void *)PROM_DISPLAY_ADDR; + prom_putc = (void *)PROM_PUTC_ADDR; + prom_printf = real_prom_printf; + prom_monitor = (void *)PROM_MONITOR_ADDR; + } + prom_printf("prom vectors set up\n"); +} + +char arcs_cmdline[CL_SIZE]; + +static struct at93c_defs at93c_defs[N_MACHTYPES] = { + {(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100, + AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100}, + {(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200, + AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200}, +}; + +void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + setup_prom_vectors(); + + if (current_cpu_data.cputype == CPU_R5000) { + mips_machtype = MACH_LASAT_200; + lasat_ndelay_divider = 8; + } else { + mips_machtype = MACH_LASAT_100; + lasat_ndelay_divider = 20; + } + + at93c = &at93c_defs[mips_machtype]; + + lasat_init_board_info(); /* Read info from EEPROM */ + + mips_machgroup = MACH_GROUP_LASAT; + + /* Get the command line */ + if (argc>0) { + strncpy(arcs_cmdline, argv[0], CL_SIZE-1); + arcs_cmdline[CL_SIZE-1] = '\0'; + } + + /* Set the I/O base address */ + set_io_port_base(KSEG1); + + /* Set memory regions */ + ioport_resource.start = 0; /* Should be KSEGx ??? */ + ioport_resource.end = 0xffffffff; /* Should be ??? */ + + add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM); +} + +void prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return lasat_board_info.li_bmstr; +} diff -urN linux-2.4.21/arch/mips/lasat/prom.h linux-2.4.22/arch/mips/lasat/prom.h --- linux-2.4.21/arch/mips/lasat/prom.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/prom.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,6 @@ +#ifndef PROM_H +#define PROM_H +extern void (* prom_display)(const char *string, int pos, int clear); +extern void (* prom_monitor)(void); +extern void (* prom_printf)(const char * fmt, ...); +#endif diff -urN linux-2.4.21/arch/mips/lasat/reset.c linux-2.4.22/arch/mips/lasat/reset.c --- linux-2.4.21/arch/mips/lasat/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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. + * + * ######################################################################## + * + * Reset the LASAT board. + * + */ + +#include +#include +#include +#include +#include "picvue.h" +#include "prom.h" + +static void lasat_machine_restart(char *command); +static void lasat_machine_halt(void); + +/* Used to set machine to boot in service mode via /proc interface */ +int lasat_boot_to_service = 0; + +static void lasat_machine_restart(char *command) +{ + local_irq_disable(); + + if (lasat_boot_to_service) { + printk("machine_restart: Rebooting to service mode\n"); + *(volatile unsigned int *)0xa0000024 = 0xdeadbeef; + *(volatile unsigned int *)0xa00000fc = 0xfedeabba; + } + *lasat_misc->reset_reg = 0xbedead; + for (;;) ; +} + +#define MESSAGE "System halted" +static void lasat_machine_halt(void) +{ + local_irq_disable(); + + /* Disable interrupts and loop forever */ + printk(KERN_NOTICE MESSAGE "\n"); +#ifdef CONFIG_PICVUE + pvc_clear(); + pvc_write_string(MESSAGE, 0, 0); +#endif + prom_monitor(); + for (;;) ; +} + +void lasat_reboot_setup(void) +{ + _machine_restart = lasat_machine_restart; + _machine_halt = lasat_machine_halt; + _machine_power_off = lasat_machine_halt; +} diff -urN linux-2.4.21/arch/mips/lasat/setup.c linux-2.4.22/arch/mips/lasat/setup.c --- linux-2.4.21/arch/mips/lasat/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,223 @@ +/* + * setup.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * Brian Murphy + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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. + * + * ######################################################################## + * + * Lasat specific setup. + */ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#if CONFIG_PICVUE +#include +#endif + +#include "ds1603.h" +#include "at93c.h" +#include +#include +#include + +#include "prom.h" + +int lasat_command_line = 0; +void lasatint_init(void); + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +extern char arcs_cmdline[CL_SIZE]; + +extern void lasat_reboot_setup(void); +extern void pcisetup(void); +extern void edhac_init(void *, void *, void *); +extern void addrflt_init(void); + +struct lasat_misc lasat_misc_info[N_MACHTYPES] = { + {(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2}, + {(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6} +}; + +struct lasat_misc *lasat_misc = NULL; + +#ifdef CONFIG_DS1603 +static struct ds_defs ds_defs[N_MACHTYPES] = { + { (void *)DS1603_REG_100, (void *)DS1603_REG_100, + DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100, + DS1603_DATA_SHIFT_100, 0, 0 }, + { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200, + DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200, + DS1603_DATA_READ_SHIFT_200, 1, 2000 } +}; +#endif + +#ifdef CONFIG_PICVUE +#include "picvue.h" +static struct pvc_defs pvc_defs[N_MACHTYPES] = { + { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100, + PVC_E_100, PVC_RW_100, PVC_RS_100 }, + { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200, + PVC_E_200, PVC_RW_200, PVC_RS_200 } +}; +#endif + +static int lasat_panic_display(struct notifier_block *this, + unsigned long event, void *ptr) +{ +#ifdef CONFIG_PICVUE + unsigned char *string = ptr; + if (string == NULL) + string = "Kernel Panic"; + pvc_dump_string(string); +#endif + return NOTIFY_DONE; +} + +static int lasat_panic_prom_monitor(struct notifier_block *this, + unsigned long event, void *ptr) +{ + prom_monitor(); + return NOTIFY_DONE; +} + +static struct notifier_block lasat_panic_block[] = +{ + { lasat_panic_display, NULL, INT_MAX }, + { lasat_panic_prom_monitor, NULL, INT_MIN } +}; + +#ifdef CONFIG_BLK_DEV_IDE +static int lasat_ide_default_irq(ide_ioreg_t base) { + return 0; +} + +static ide_ioreg_t lasat_ide_default_io_base(int index) { + return 0; +} +#endif + +static void lasat_time_init(void) +{ + mips_counter_frequency = lasat_board_info.li_cpu_hz / 2; +} + +static void lasat_timer_setup(struct irqaction *irq) +{ + + write_c0_compare( + read_c0_count() + + mips_counter_frequency / HZ); + change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); +} + +#define MIPS_CPU_TIMER_IRQ 7 +asmlinkage void lasat_timer_interrupt(struct pt_regs *regs) +{ + ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); +} + +void __init serial_init(void) +{ +#ifdef CONFIG_SERIAL + struct serial_struct s; + + memset(&s, 0, sizeof(s)); + + s.flags = STD_COM_FLAGS; + s.io_type = SERIAL_IO_MEM; + + if (mips_machtype == MACH_LASAT_100) { + s.baud_base = LASAT_BASE_BAUD_100; + s.irq = LASATINT_UART_100; + s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_100; + s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_100); + } else { + s.baud_base = LASAT_BASE_BAUD_200; + s.irq = LASATINT_UART_200; + s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_200; + s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_200); + } + + if (early_serial_setup(&s) != 0) + printk(KERN_ERR "Serial setup failed!\n"); +#endif +} + +void __init lasat_setup(void) +{ + int i; + lasat_misc = &lasat_misc_info[mips_machtype]; +#ifdef CONFIG_PICVUE + picvue = &pvc_defs[mips_machtype]; +#endif + + /* Set up panic notifier */ + for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) + notifier_chain_register(&panic_notifier_list, &lasat_panic_block[i]); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; + ide_ops->ide_default_irq = &lasat_ide_default_irq; + ide_ops->ide_default_io_base = &lasat_ide_default_io_base; +#endif + + lasat_reboot_setup(); + + board_time_init = lasat_time_init; + board_timer_setup = lasat_timer_setup; + +#ifdef CONFIG_DS1603 + ds1603 = &ds_defs[mips_machtype]; + rtc_get_time = ds1603_read; + rtc_set_time = ds1603_set; +#endif + + serial_init(); + + /* Switch from prom exception handler to normal mode */ + change_c0_status(ST0_BEV,0); + + prom_printf("Lasat specific initialization complete\n"); +} + + diff -urN linux-2.4.21/arch/mips/lasat/sysctl.c linux-2.4.22/arch/mips/lasat/sysctl.c --- linux-2.4.21/arch/mips/lasat/sysctl.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/sysctl.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,359 @@ +/* + * sysctl.c + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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. + * + * ######################################################################## + * + * Routines specific to the LASAT boards + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sysctl.h" +#include "ds1603.h" + +static DECLARE_MUTEX(lasat_info_sem); + +/* Strategy function to write EEPROM after changing string entry */ +int sysctl_lasatstring(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + r = sysctl_string(table, name, + nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + lasat_write_eeprom_info(); + } + up(&lasat_info_sem); + return 1; +} + + +/* And the same for proc */ +int proc_dolasatstring(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dostring(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +/* proc function to write EEPROM after changing int entry */ +int proc_dolasatint(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +static int rtctmp; + +#ifdef CONFIG_DS1603 +/* proc function to read/write RealTime Clock */ +int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + if (!write) { + rtctmp = ds1603_read(); + /* check for time < 0 and set to 0 */ + if (rtctmp < 0) + rtctmp = 0; + } + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + ds1603_set(rtctmp); + up(&lasat_info_sem); + return 0; +} +#endif + +/* Sysctl for setting the IP addresses */ +int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + lasat_write_eeprom_info(); + } + up(&lasat_info_sem); + return 1; +} + +#if CONFIG_DS1603 +/* Same for RTC */ +int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + rtctmp = ds1603_read(); + if (rtctmp < 0) + rtctmp = 0; + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + ds1603_set(rtctmp); + } + up(&lasat_info_sem); + return 1; +} +#endif + +#ifdef CONFIG_INET +static char lasat_bcastaddr[16]; + +void update_bcastaddr(void) +{ + unsigned int ip; + + ip = lasat_board_info.li_eeprom_info.ipaddr | + ~lasat_board_info.li_eeprom_info.netmask; + + sprintf(lasat_bcastaddr, "%d.%d.%d.%d", + (ip ) & 0xff, + (ip >> 8) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); +} + +static char proc_lasat_ipbuf[32]; +/* Parsing of IP address */ +int proc_lasat_ip(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int len; + unsigned int ip; + char *p, c; + + if (!table->data || !table->maxlen || !*lenp || + (filp->f_pos && !write)) { + *lenp = 0; + return 0; + } + + down(&lasat_info_sem); + if (write) { + len = 0; + p = buffer; + while (len < *lenp) { + if(get_user(c, p++)) { + up(&lasat_info_sem); + return -EFAULT; + } + if (c == 0 || c == '\n') + break; + len++; + } + if (len >= sizeof(proc_lasat_ipbuf)-1) + len = sizeof(proc_lasat_ipbuf) - 1; + if (copy_from_user(proc_lasat_ipbuf, buffer, len)) + { + up(&lasat_info_sem); + return -EFAULT; + } + proc_lasat_ipbuf[len] = 0; + filp->f_pos += *lenp; + /* Now see if we can convert it to a valid IP */ + ip = in_aton(proc_lasat_ipbuf); + *(unsigned int *)(table->data) = ip; + lasat_write_eeprom_info(); + } else { + ip = *(unsigned int *)(table->data); + sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", + (ip ) & 0xff, + (ip >> 8) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); + len = strlen(proc_lasat_ipbuf); + if (len > *lenp) + len = *lenp; + if (len) + if(copy_to_user(buffer, proc_lasat_ipbuf, len)) { + up(&lasat_info_sem); + return -EFAULT; + } + if (len < *lenp) { + if(put_user('\n', ((char *) buffer) + len)) { + up(&lasat_info_sem); + return -EFAULT; + } + len++; + } + *lenp = len; + filp->f_pos += len; + } + update_bcastaddr(); + up(&lasat_info_sem); + return 0; +} +#endif /* defined(CONFIG_INET) */ + +static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context) +{ + int r; + + down(&lasat_info_sem); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + + if (newval && newlen) + { + if (name && *name == LASAT_PRID) + lasat_board_info.li_eeprom_info.prid = *(int*)newval; + + lasat_write_eeprom_info(); + lasat_init_board_info(); + } + up(&lasat_info_sem); + + return 0; +} + +int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + if (filp && filp->f_dentry) + { + if (!strcmp(filp->f_dentry->d_name.name, "prid")) + lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid; + if (!strcmp(filp->f_dentry->d_name.name, "debugaccess")) + lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +extern int lasat_boot_to_service; + +#ifdef CONFIG_SYSCTL + +static ctl_table lasat_table[] = { + {LASAT_CPU_HZ, "cpu-hz", &lasat_board_info.li_cpu_hz, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_BUS_HZ, "bus-hz", &lasat_board_info.li_bus_hz, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_MODEL, "bmid", &lasat_board_info.li_bmid, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_PRID, "prid", &lasat_board_info.li_prid, sizeof(int), + 0644, NULL, &proc_lasat_eeprom_value, &sysctl_lasat_eeprom_value}, +#ifdef CONFIG_INET + {LASAT_IPADDR, "ipaddr", &lasat_board_info.li_eeprom_info.ipaddr, sizeof(int), + 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec}, + {LASAT_NETMASK, "netmask", &lasat_board_info.li_eeprom_info.netmask, sizeof(int), + 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec}, + {LASAT_BCAST, "bcastaddr", &lasat_bcastaddr, + sizeof(lasat_bcastaddr), 0600, NULL, + &proc_dostring, &sysctl_string}, +#endif + {LASAT_PASSWORD, "passwd_hash", &lasat_board_info.li_eeprom_info.passwd_hash, sizeof(lasat_board_info.li_eeprom_info.passwd_hash), + 0600, NULL, &proc_dolasatstring, &sysctl_lasatstring}, + {LASAT_SBOOT, "boot-service", &lasat_boot_to_service, sizeof(int), + 0644, NULL, &proc_dointvec, &sysctl_intvec}, +#if CONFIG_DS1603 + {LASAT_RTC, "rtc", &rtctmp, sizeof(int), + 0644, NULL, &proc_dolasatrtc, &sysctl_lasat_rtc}, +#endif + {LASAT_NAMESTR, "namestr", &lasat_board_info.li_namestr, sizeof(lasat_board_info.li_namestr), + 0444, NULL, &proc_dostring, &sysctl_string}, + {LASAT_TYPESTR, "typestr", &lasat_board_info.li_typestr, sizeof(lasat_board_info.li_typestr), + 0444, NULL, &proc_dostring, &sysctl_string}, + {0} +}; + +#define CTL_LASAT 1 // CTL_ANY ??? +static ctl_table lasat_root_table[] = { + { CTL_LASAT, "lasat", NULL, 0, 0555, lasat_table }, + { 0 } +}; + +static int __init lasat_register_sysctl(void) +{ + struct ctl_table_header *lasat_table_header; + + lasat_table_header = + register_sysctl_table(lasat_root_table, 0); + + return 0; +} + +__initcall(lasat_register_sysctl); +#endif /* CONFIG_SYSCTL */ diff -urN linux-2.4.21/arch/mips/lasat/sysctl.h linux-2.4.22/arch/mips/lasat/sysctl.h --- linux-2.4.21/arch/mips/lasat/sysctl.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lasat/sysctl.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,24 @@ +/* + * LASAT sysctl values + */ + +#ifndef _LASAT_SYSCTL_H +#define _LASAT_SYSCTL_H + +/* /proc/sys/lasat */ +enum { + LASAT_CPU_HZ=1, + LASAT_BUS_HZ, + LASAT_MODEL, + LASAT_PRID, + LASAT_IPADDR, + LASAT_NETMASK, + LASAT_BCAST, + LASAT_PASSWORD, + LASAT_SBOOT, + LASAT_RTC, + LASAT_NAMESTR, + LASAT_TYPESTR, +}; + +#endif /* _LASAT_SYSCTL_H */ diff -urN linux-2.4.21/arch/mips/ld.script.in linux-2.4.22/arch/mips/ld.script.in --- linux-2.4.21/arch/mips/ld.script.in 2001-07-02 13:56:40.000000000 -0700 +++ linux-2.4.22/arch/mips/ld.script.in 2003-08-25 04:44:40.000000000 -0700 @@ -81,8 +81,8 @@ . = ALIGN(4096); __rd_start = .; *(.initrd) - __rd_end = .; . = ALIGN(4096); + __rd_end = .; CONSTRUCTORS } diff -urN linux-2.4.21/arch/mips/lib/Makefile linux-2.4.22/arch/mips/lib/Makefile --- linux-2.4.21/arch/mips/lib/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/lib/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -7,9 +7,9 @@ L_TARGET = lib.a obj-y += csum_partial.o csum_partial_copy.o \ - rtc-std.o rtc-no.o memcpy.o memset.o \ - watch.o strlen_user.o strncpy_user.o \ - strnlen_user.o + promlib.o rtc-std.o rtc-no.o memcpy.o \ + memset.o watch.o strlen_user.o \ + strncpy_user.o strnlen_user.o ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) obj-y += r3k_dump_tlb.o @@ -18,7 +18,7 @@ endif obj-$(CONFIG_BLK_DEV_FD) += floppy-no.o floppy-std.o -obj-$(CONFIG_IDE) += ide-std.o ide-no.o -obj-$(CONFIG_PC_KEYB) += kbd-std.o kbd-no.o +obj-$(subst m,y,$(CONFIG_IDE)) += ide-std.o ide-no.o # needed for ide module +obj-$(CONFIG_PC_KEYB) += kbd-std.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/lib/dump_tlb.c linux-2.4.22/arch/mips/lib/dump_tlb.c --- linux-2.4.21/arch/mips/lib/dump_tlb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/lib/dump_tlb.c 2003-08-25 04:44:40.000000000 -0700 @@ -41,11 +41,11 @@ unsigned long long entrylo0, entrylo1; unsigned long entryhi; - asid = get_entryhi() & 0xff; + asid = read_c0_entryhi() & 0xff; printk("\n"); for(i=first;i<=last;i++) { - write_32bit_cp0_register(CP0_INDEX, i); + write_c0_index(i); __asm__ __volatile__( ".set\tmips3\n\t" ".set\tnoreorder\n\t" @@ -54,10 +54,10 @@ "nop;nop;nop;nop\n\t" ".set\treorder\n\t" ".set\tmips0\n\t"); - pagemask = read_32bit_cp0_register(CP0_PAGEMASK); - entryhi = read_32bit_cp0_register(CP0_ENTRYHI); - entrylo0 = get_entrylo0(); - entrylo1 = get_entrylo1(); + pagemask = read_c0_pagemask(); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); /* Unused entries have a virtual address in KSEG0. */ if ((entryhi & 0xf0000000) != 0x80000000 @@ -86,21 +86,21 @@ } } - set_entryhi(asid); + write_c0_entryhi(asid); } void dump_tlb_all(void) { - dump_tlb(0, mips_cpu.tlbsize - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } void dump_tlb_wired(void) { int wired; - wired = read_32bit_cp0_register(CP0_WIRED); + wired = read_c0_wired(); printk("Wired: %d", wired); - dump_tlb(0, read_32bit_cp0_register(CP0_WIRED)); + dump_tlb(0, read_c0_wired()); } #define BARRIER \ @@ -112,19 +112,19 @@ void dump_tlb_addr(unsigned long addr) { - unsigned int flags, oldpid; + unsigned long flags, oldpid; int index; - __save_and_cli(flags); - oldpid = get_entryhi() & 0xff; + local_irq_save(flags); + oldpid = read_c0_entryhi() & 0xff; BARRIER; - set_entryhi((addr & PAGE_MASK) | oldpid); + write_c0_entryhi((addr & PAGE_MASK) | oldpid); BARRIER; tlb_probe(); BARRIER; - index = get_index(); - set_entryhi(oldpid); - __restore_flags(flags); + index = read_c0_index(); + write_c0_entryhi(oldpid); + local_irq_restore(flags); if (index < 0) { printk("No entry for address 0x%08lx in TLB\n", addr); @@ -138,7 +138,7 @@ void dump_tlb_nonwired(void) { - dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_cpu.tlbsize - 1); + dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); } void @@ -153,8 +153,8 @@ addr = (unsigned int) address; printk("Addr == %08x\n", addr); - printk("task == %08p\n", t); - printk("task->mm == %08p\n", t->mm); + printk("task == %8p\n", t); + printk("task->mm == %8p\n", t->mm); //printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); if (addr > KSEG0) @@ -177,9 +177,9 @@ page = *pte; #ifdef CONFIG_64BIT_PHYS_ADDR - printk("page == %08Lx\n", (unsigned long long) pte_val(page)); + printk("page == %08Lx\n", pte_val(page)); #else - printk("page == %08lx\n", (unsigned int) pte_val(page)); + printk("page == %08lx\n", pte_val(page)); #endif val = pte_val(page); @@ -225,9 +225,7 @@ for(i=0;i<8;i++) { - printk("*%08lx == %08lx, ", - (unsigned long)p, (unsigned long)*p++); - printk("*%08lx == %08lx\n", - (unsigned long)p, (unsigned long)*p++); + printk("*%8p = %08lx, ", p, *p); p++; + printk("*%8p = %08lx\n", p, *p); p++; } } diff -urN linux-2.4.21/arch/mips/lib/ide-no.c linux-2.4.22/arch/mips/lib/ide-no.c --- linux-2.4.21/arch/mips/lib/ide-no.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/lib/ide-no.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,42 +29,8 @@ { } -static int no_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - panic("no_no_ide_request_irq called - shouldn't happen"); -} - -static void no_ide_free_irq(unsigned int irq, void *dev_id) -{ - panic("no_ide_free_irq called - shouldn't happen"); -} - -static int no_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_check_region called - shouldn't happen"); -} - -static void no_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - panic("no_ide_request_region called - shouldn't happen"); -} - -static void no_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_release_region called - shouldn't happen"); -} - struct ide_ops no_ide_ops = { &no_ide_default_irq, &no_ide_default_io_base, - &no_ide_init_hwif_ports, - &no_ide_request_irq, - &no_ide_free_irq, - &no_ide_check_region, - &no_ide_request_region, - &no_ide_release_region + &no_ide_init_hwif_ports }; diff -urN linux-2.4.21/arch/mips/lib/ide-std.c linux-2.4.22/arch/mips/lib/ide-std.c --- linux-2.4.21/arch/mips/lib/ide-std.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/lib/ide-std.c 2003-08-25 04:44:40.000000000 -0700 @@ -62,42 +62,8 @@ hw->io_ports[IDE_IRQ_OFFSET] = 0; } -static int std_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - return request_irq(irq, handler, flags, device, dev_id); -} - -static void std_ide_free_irq(unsigned int irq, void *dev_id) -{ - free_irq(irq, dev_id); -} - -static int std_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return check_region(from, extent); -} - -static void std_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - request_region(from, extent, name); -} - -static void std_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - release_region(from, extent); -} - struct ide_ops std_ide_ops = { &std_ide_default_irq, &std_ide_default_io_base, - &std_ide_init_hwif_ports, - &std_ide_request_irq, - &std_ide_free_irq, - &std_ide_check_region, - &std_ide_request_region, - &std_ide_release_region + &std_ide_init_hwif_ports }; diff -urN linux-2.4.21/arch/mips/lib/kbd-no.c linux-2.4.22/arch/mips/lib/kbd-no.c --- linux-2.4.21/arch/mips/lib/kbd-no.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/lib/kbd-no.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,62 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Stub keyboard and psaux routines to keep Linux from crashing on machines - * without a keyboard. - * - * Copyright (C) 1998 by Ralf Baechle - */ -#include -#include - -static void no_kbd_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static void no_aux_free_irq(void) -{ -} - -static unsigned char no_kbd_read_input(void) -{ - return 0; -} - -static void no_kbd_write_output(unsigned char val) -{ -} - -static void no_kbd_write_command(unsigned char val) -{ -} - -static unsigned char no_kbd_read_status(void) -{ - return 0; -} - -struct kbd_ops no_kbd_ops = { - no_kbd_request_region, - no_kbd_request_irq, - - no_aux_request_irq, - no_aux_free_irq, - - no_kbd_read_input, - no_kbd_write_output, - no_kbd_write_command, - no_kbd_read_status -}; diff -urN linux-2.4.21/arch/mips/lib/memcpy.S linux-2.4.22/arch/mips/lib/memcpy.S --- linux-2.4.21/arch/mips/lib/memcpy.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/lib/memcpy.S 2003-08-25 04:44:40.000000000 -0700 @@ -77,11 +77,13 @@ .previous /* - * In the mips (not mips64) tree, so we can't use doubles + * Only on the 64-bit kernel we can made use of 64-bit registers. */ -#undef USE_DOUBLE +#ifdef CONFIG_MIPS64 +#define USE_DOUBLE +#endif -#if defined(USE_DOUBLE) +#ifdef USE_DOUBLE #define LOAD ld #define LOADL ldl @@ -99,6 +101,24 @@ #define NBYTES 8 #define LOG_NBYTES 3 +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 + #else #define LOAD lw @@ -246,7 +266,7 @@ beq rem, len, copy_bytes nop 1: -EXC( LOAD t0, 0(src), l_exc) +EXC( LOAD t0, 0(src), l_exc) ADD src, src, NBYTES SUB len, len, NBYTES EXC( STORE t0, 0(dst), s_exc_p1u) @@ -320,10 +340,10 @@ EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) EXC( LDREST t2, REST(2)(src), l_exc_copy) EXC( LDREST t3, REST(3)(src), l_exc_copy) - PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) + PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) ADD src, src, 4*NBYTES #ifdef CONFIG_CPU_SB1 - nop # improves slotting + nop # improves slotting #endif EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) @@ -337,8 +357,9 @@ beqz len, done and rem, len, NBYTES-1 # rem = len % NBYTES beq rem, len, copy_bytes + nop 1: -EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDFIRST t0, FIRST(0)(src), l_exc) EXC( LDREST t0, REST(0)(src), l_exc_copy) ADD src, src, NBYTES SUB len, len, NBYTES @@ -385,7 +406,7 @@ * * Assumes src < THREAD_BUADDR($28) */ - lw t0, THREAD_BUADDR($28) + LOAD t0, THREAD_BUADDR($28) 1: EXC( lb t1, 0(src), l_exc) ADD src, src, 1 @@ -393,16 +414,16 @@ bne src, t0, 1b ADD dst, dst, 1 l_exc: - lw t0, THREAD_BUADDR($28) # t0 is just past last good address + LOAD t0, THREAD_BUADDR($28) # t0 is just past last good address nop - subu len, AT, t0 # len number of uncopied bytes + SUB len, AT, t0 # len number of uncopied bytes /* * Here's where we rely on src and dst being incremented in tandem, * See (3) above. * dst += (fault addr - src) to put dst at first byte to clear */ - addu dst, t0 # compute start address in a1 - subu dst, src + ADD dst, t0 # compute start address in a1 + SUB dst, src /* * Clear len bytes starting at dst. Can't call __bzero because it * might modify len. An inefficient loop for these rare times... @@ -440,8 +461,8 @@ .align 5 LEAF(memmove) - addu t0, a0, a2 - addu t1, a1, a2 + ADD t0, a0, a2 + ADD t1, a1, a2 sltu t0, a1, t0 # dst + len <= src -> memcpy sltu t1, a0, t1 # dst >= src + len -> memcpy and t0, t1 @@ -455,16 +476,16 @@ sltu t0, a1, a0 beqz t0, r_end_bytes_up # src >= dst nop - addu a0, a2 # dst = dst + len - addu a1, a2 # src = src + len + ADD a0, a2 # dst = dst + len + ADD a1, a2 # src = src + len r_end_bytes: lb t0, -1(a1) - subu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, -1(a0) - subu a1, a1, 0x1 + SUB a1, a1, 0x1 bnez a2, r_end_bytes - subu a0, a0, 0x1 + SUB a0, a0, 0x1 r_out: jr ra @@ -472,11 +493,11 @@ r_end_bytes_up: lb t0, (a1) - subu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, (a0) - addu a1, a1, 0x1 + ADD a1, a1, 0x1 bnez a2, r_end_bytes_up - addu a0, a0, 0x1 + ADD a0, a0, 0x1 jr ra move a2, zero diff -urN linux-2.4.21/arch/mips/lib/promlib.c linux-2.4.22/arch/mips/lib/promlib.c --- linux-2.4.21/arch/mips/lib/promlib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/lib/promlib.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,24 @@ +#include +#include + +extern void prom_putchar(char); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff -urN linux-2.4.21/arch/mips/lib/r3k_dump_tlb.c linux-2.4.22/arch/mips/lib/r3k_dump_tlb.c --- linux-2.4.21/arch/mips/lib/r3k_dump_tlb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/lib/r3k_dump_tlb.c 2003-08-25 04:44:40.000000000 -0700 @@ -26,18 +26,18 @@ unsigned int asid; unsigned long entryhi, entrylo0; - asid = get_entryhi() & 0xfc0; + asid = read_c0_entryhi() & 0xfc0; for(i=first;i<=last;i++) { - write_32bit_cp0_register(CP0_INDEX, i<<8); + write_c0_index(i<<8); __asm__ __volatile__( ".set\tnoreorder\n\t" "tlbr\n\t" "nop\n\t" ".set\treorder"); - entryhi = read_32bit_cp0_register(CP0_ENTRYHI); - entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); /* Unused entries have a virtual address of KSEG0. */ if ((entryhi & 0xffffe000) != 0x80000000 @@ -60,19 +60,19 @@ } printk("\n"); - set_entryhi(asid); + write_c0_entryhi(asid); } void dump_tlb_all(void) { - dump_tlb(0, mips_cpu.tlbsize - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } void dump_tlb_wired(void) { - int wired = r3k_have_wired_reg ? get_wired() : 8; + int wired = r3k_have_wired_reg ? read_c0_wired() : 8; printk("Wired: %d", wired); dump_tlb(0, wired - 1); @@ -81,16 +81,16 @@ void dump_tlb_addr(unsigned long addr) { - unsigned int flags, oldpid; + unsigned long flags, oldpid; int index; - __save_and_cli(flags); - oldpid = get_entryhi() & 0xff; - set_entryhi((addr & PAGE_MASK) | oldpid); + local_irq_save(flags); + oldpid = read_c0_entryhi() & 0xff; + write_c0_entryhi((addr & PAGE_MASK) | oldpid); tlb_probe(); - index = get_index(); - set_entryhi(oldpid); - __restore_flags(flags); + index = read_c0_index(); + write_c0_entryhi(oldpid); + local_irq_restore(flags); if (index < 0) { printk("No entry for address 0x%08lx in TLB\n", addr); @@ -104,8 +104,8 @@ void dump_tlb_nonwired(void) { - int wired = r3k_have_wired_reg ? get_wired() : 8; - dump_tlb(wired, mips_cpu.tlbsize - 1); + int wired = r3k_have_wired_reg ? read_c0_wired() : 8; + dump_tlb(wired, current_cpu_data.tlbsize - 1); } void diff -urN linux-2.4.21/arch/mips/lib/rtc-no.c linux-2.4.22/arch/mips/lib/rtc-no.c --- linux-2.4.21/arch/mips/lib/rtc-no.c 2001-07-02 13:56:40.000000000 -0700 +++ linux-2.4.22/arch/mips/lib/rtc-no.c 2003-08-25 04:44:40.000000000 -0700 @@ -24,7 +24,7 @@ } struct rtc_ops no_rtc_ops = { - rtc_read_data: (void *) &shouldnt_happen, - rtc_write_data: (void *) &shouldnt_happen, - rtc_bcd_mode: (void *) &shouldnt_happen + .rtc_read_data = (void *) &shouldnt_happen, + .rtc_write_data = (void *) &shouldnt_happen, + .rtc_bcd_mode = (void *) &shouldnt_happen }; diff -urN linux-2.4.21/arch/mips/math-emu/cp1emu.c linux-2.4.22/arch/mips/math-emu/cp1emu.c --- linux-2.4.21/arch/mips/math-emu/cp1emu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/cp1emu.c 2003-08-25 04:44:40.000000000 -0700 @@ -200,7 +200,7 @@ vaddr_t emulpc, contpc; unsigned int cond; - if (get_user(ir, (mips_instruction *) REG_TO_VA xcp->cp0_epc)) { + if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -1284,21 +1284,14 @@ struct mips_fpu_soft_struct *ctx) { gpreg_t oldepc, prevepc; - mips_instruction insn, *insnp; + mips_instruction insn; int sig = 0; oldepc = xcp->cp0_epc; do { prevepc = xcp->cp0_epc; - /* - * This is a braindead way to do it but the only sane way I - * found to keep the 64-bit egcs 1.1.2 from crashing. - */ - insnp = (mips_instruction *) REG_TO_VA xcp->cp0_epc; - - if (verify_area(VERIFY_READ, insnp, 4) || - __get_user(insn, insnp)) { + if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -1313,7 +1306,7 @@ sig = cop1Emulate(xcp, ctx); } - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) break; if (sig) break; diff -urN linux-2.4.21/arch/mips/math-emu/dp_cmp.c linux-2.4.22/arch/mips/math-emu/dp_cmp.c --- linux-2.4.21/arch/mips/math-emu/dp_cmp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/dp_cmp.c 2003-08-25 04:44:40.000000000 -0700 @@ -44,7 +44,7 @@ if (cmp & IEEE754_CUN) return 1; if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (sig && SETCX(IEEE754_INVALID_OPERATION)) + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) return ieee754si_xcpt(0, "fcmpf", x); } return 0; diff -urN linux-2.4.21/arch/mips/math-emu/dp_fint.c linux-2.4.22/arch/mips/math-emu/dp_fint.c --- linux-2.4.21/arch/mips/math-emu/dp_fint.c 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/arch/mips/math-emu/dp_fint.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754dp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21/arch/mips/math-emu/dp_flong.c linux-2.4.22/arch/mips/math-emu/dp_flong.c --- linux-2.4.21/arch/mips/math-emu/dp_flong.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/dp_flong.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754dp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21/arch/mips/math-emu/ieee754dp.c linux-2.4.22/arch/mips/math-emu/ieee754dp.c --- linux-2.4.21/arch/mips/math-emu/ieee754dp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/ieee754dp.c 2003-08-25 04:44:40.000000000 -0700 @@ -69,7 +69,7 @@ if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */ return r; - if (!SETCX(IEEE754_INVALID_OPERATION)) { + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { /* not enabled convert to a quiet NaN */ DPMANT(r) &= (~DP_MBIT(DP_MBITS-1)); if (ieee754dp_isnan(r)) diff -urN linux-2.4.21/arch/mips/math-emu/ieee754int.h linux-2.4.22/arch/mips/math-emu/ieee754int.h --- linux-2.4.21/arch/mips/math-emu/ieee754int.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/ieee754int.h 2003-08-25 04:44:40.000000000 -0700 @@ -61,7 +61,10 @@ (ieee754_csr.cx = 0) #define SETCX(x) \ - (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x),ieee754_csr.mx & (x)) + (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x)) + +#define SETANDTESTCX(x) \ + (SETCX(x),ieee754_csr.mx & (x)) #define TSTX() \ (ieee754_csr.cx & ieee754_csr.mx) diff -urN linux-2.4.21/arch/mips/math-emu/ieee754sp.c linux-2.4.22/arch/mips/math-emu/ieee754sp.c --- linux-2.4.21/arch/mips/math-emu/ieee754sp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/ieee754sp.c 2003-08-25 04:44:40.000000000 -0700 @@ -70,7 +70,7 @@ if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */ return r; - if (!SETCX(IEEE754_INVALID_OPERATION)) { + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { /* not enabled convert to a quiet NaN */ SPMANT(r) &= (~SP_MBIT(SP_MBITS-1)); if (ieee754sp_isnan(r)) diff -urN linux-2.4.21/arch/mips/math-emu/ieee754xcpt.c linux-2.4.22/arch/mips/math-emu/ieee754xcpt.c --- linux-2.4.21/arch/mips/math-emu/ieee754xcpt.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/ieee754xcpt.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,6 +29,7 @@ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. *************************************************************************/ +#include #include "ieee754.h" /* @@ -42,7 +43,7 @@ void ieee754_xcpt(struct ieee754xctx *xcp) { - printk("floating point exception in \"%s\", type=%s\n", + printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n", xcp->op, rtnames[xcp->rt]); } diff -urN linux-2.4.21/arch/mips/math-emu/kernel_linkage.c linux-2.4.22/arch/mips/math-emu/kernel_linkage.c --- linux-2.4.21/arch/mips/math-emu/kernel_linkage.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/kernel_linkage.c 2003-08-25 04:44:40.000000000 -0700 @@ -90,3 +90,40 @@ return err; } +#ifdef CONFIG_MIPS64 +/* + * This is the o32 version + */ + +int fpu_emulator_save_context32(struct sigcontext32 *sc) +{ + int i; + int err = 0; + + for (i = 0; i < 32; i+=2) { + err |= + __put_user(current->thread.fpu.soft.regs[i], + &sc->sc_fpregs[i]); + } + err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); + err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir); + + return err; +} + +int fpu_emulator_restore_context32(struct sigcontext32 *sc) +{ + int i; + int err = 0; + + for (i = 0; i < 32; i+=2) { + err |= + __get_user(current->thread.fpu.soft.regs[i], + &sc->sc_fpregs[i]); + } + err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); + err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir); + + return err; +} +#endif diff -urN linux-2.4.21/arch/mips/math-emu/sp_cmp.c linux-2.4.22/arch/mips/math-emu/sp_cmp.c --- linux-2.4.21/arch/mips/math-emu/sp_cmp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/sp_cmp.c 2003-08-25 04:44:40.000000000 -0700 @@ -44,7 +44,7 @@ if (cmp & IEEE754_CUN) return 1; if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (sig && SETCX(IEEE754_INVALID_OPERATION)) + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) return ieee754si_xcpt(0, "fcmpf", x); } return 0; diff -urN linux-2.4.21/arch/mips/math-emu/sp_fint.c linux-2.4.22/arch/mips/math-emu/sp_fint.c --- linux-2.4.21/arch/mips/math-emu/sp_fint.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/sp_fint.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754sp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21/arch/mips/math-emu/sp_flong.c linux-2.4.22/arch/mips/math-emu/sp_flong.c --- linux-2.4.21/arch/mips/math-emu/sp_flong.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/sp_flong.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754sp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21/arch/mips/math-emu/sp_sqrt.c linux-2.4.22/arch/mips/math-emu/sp_sqrt.c --- linux-2.4.21/arch/mips/math-emu/sp_sqrt.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/math-emu/sp_sqrt.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,7 +29,6 @@ ieee754sp ieee754sp_sqrt(ieee754sp x) { - int sign = (int) 0x80000000; int ix, s, q, m, t, i; unsigned int r; COMPXSP; diff -urN linux-2.4.21/arch/mips/math-emu/sp_sub.c linux-2.4.22/arch/mips/math-emu/sp_sub.c --- linux-2.4.21/arch/mips/math-emu/sp_sub.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/math-emu/sp_sub.c 2003-08-25 04:44:40.000000000 -0700 @@ -167,12 +167,12 @@ xe = xe; xs = ys; } - if (xm == 0) + if (xm == 0) { if (ieee754_csr.rm == IEEE754_RD) return ieee754sp_zero(1); /* round negative inf. => sign = -1 */ else return ieee754sp_zero(0); /* other round modes => sign = 1 */ - + } /* normalize to rounding precision */ while ((xm >> (SP_MBITS + 3)) == 0) { diff -urN linux-2.4.21/arch/mips/mips-boards/atlas/atlas_int.c linux-2.4.22/arch/mips/mips-boards/atlas/atlas_int.c --- linux-2.4.21/arch/mips/mips-boards/atlas/atlas_int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/atlas/atlas_int.c 2003-08-25 04:44:40.000000000 -0700 @@ -40,7 +40,6 @@ = (struct atlas_ictrl_regs *)ATLAS_ICTRL_REGS_BASE; extern asmlinkage void mipsIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); #if 0 #define DEBUG_INT(x...) printk(x) @@ -130,7 +129,7 @@ return; } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern int remote_debug; #endif @@ -155,7 +154,7 @@ irq_desc[i].handler = &atlas_irq_type; } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); diff -urN linux-2.4.21/arch/mips/mips-boards/atlas/atlas_setup.c linux-2.4.22/arch/mips/mips-boards/atlas/atlas_setup.c --- linux-2.4.21/arch/mips/mips-boards/atlas/atlas_setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/atlas/atlas_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include @@ -38,7 +38,7 @@ char serial_console[20]; #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void saa9730_kgdb_hook(void); extern void breakpoint(void); @@ -54,17 +54,13 @@ return "MIPS Atlas"; } -void __init bus_error_init(void) -{ -} - extern void mips_time_init(void); extern void mips_timer_setup(struct irqaction *irq); extern unsigned long mips_rtc_get_time(void); void __init atlas_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int rs_putDebugChar(char); char rs_getDebugChar(void); int saa9730_putDebugChar(char); @@ -90,7 +86,7 @@ } #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -122,7 +118,7 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; rtc_ops = &atlas_rtc_ops; board_time_init = mips_time_init; diff -urN linux-2.4.21/arch/mips/mips-boards/generic/Makefile linux-2.4.22/arch/mips/mips-boards/generic/Makefile --- linux-2.4.21/arch/mips/mips-boards/generic/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/generic/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -32,6 +32,6 @@ obj-$(CONFIG_MIPS_ATLAS) += time.o obj-$(CONFIG_MIPS_MALTA) += time.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o +obj-$(CONFIG_KGDB) += gdb_hook.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/mips-boards/generic/init.c linux-2.4.22/arch/mips/mips-boards/generic/init.c --- linux-2.4.21/arch/mips/mips-boards/generic/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/generic/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,14 +25,15 @@ #include #include #include -#include -#include +#include #include #include +#ifdef CONFIG_MIPS_MALTA +#include +#endif /* Environment variable */ -typedef struct -{ +typedef struct { char *name; char *val; } t_env_var; @@ -50,6 +51,11 @@ unsigned int mips_revision_corid; +/* + * Algorithmics Bonito64 system controller register base. + */ +char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE); + char *prom_getenv(char *envname) { /* @@ -62,21 +68,21 @@ i = strlen(envname); - while(prom_envp(index)) { + while (prom_envp(index)) { if(strncmp(envname, prom_envp(index), i) == 0) { return(prom_envp(index+1)); } index += 2; } - return(NULL); + return NULL; } static inline unsigned char str2hexnum(unsigned char c) { - if(c >= '0' && c <= '9') + if (c >= '0' && c <= '9') return c - '0'; - if(c >= 'a' && c <= 'f') + if (c >= 'a' && c <= 'f') return c - 'a' + 10; return 0; /* foo */ } @@ -85,7 +91,7 @@ { int i; - for(i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) { unsigned char num; if((*str == '.') || (*str == ':')) @@ -138,14 +144,14 @@ * Setup the North bridge to do Master byte-lane swapping * when running in bigendian. */ -#if defined(__MIPSEL__) +#ifdef CONFIG_CPU_LITTLE_ENDIAN GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | GT_PCI0_CMD_SBYTESWAP_BIT); #else GT_WRITE(GT_PCI0_CMD_OFS, 0); #endif -#if defined(CONFIG_MIPS_MALTA) +#ifdef CONFIG_MIPS_MALTA set_io_port_base(MALTA_GT_PORT_BASE); #else set_io_port_base(KSEG1); @@ -165,7 +171,7 @@ * Setup the North bridge to do Master byte-lane swapping * when running in bigendian. */ -#if defined(__MIPSEL__) +#ifdef CONFIG_CPU_LITTLE_ENDIAN BONITO_BONGENCFG = BONITO_BONGENCFG & ~(BONITO_BONGENCFG_MSTRBYTESWAP | BONITO_BONGENCFG_BYTESWAP); @@ -175,16 +181,18 @@ BONITO_BONGENCFG_BYTESWAP; #endif -#if defined(CONFIG_MIPS_MALTA) - set_io_port_base(MALTA_BONITO_PORT_BASE); +#ifdef CONFIG_MIPS_MALTA + set_io_port_base(MALTA_BONITO_PORT_BASE); #else - set_io_port_base(KSEG1); + set_io_port_base(KSEG1); #endif break; case MIPS_REVISION_CORID_CORE_MSC: - set_io_port_base(MALTA_MSC_PORT_BASE); -#if defined(__MIPSEL__) +#ifdef CONFIG_MIPS_MALTA + set_io_port_base(MALTA_MSC_PORT_BASE); +#endif +#ifdef CONFIG_CPU_LITTLE_ENDIAN MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); #else MSC_WRITE(MSC01_PCI_SWAP, @@ -199,7 +207,6 @@ while(1); /* We die here... */ } #endif - setup_prom_printf(0); prom_printf("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); diff -urN linux-2.4.21/arch/mips/mips-boards/generic/memory.c linux-2.4.22/arch/mips/mips-boards/generic/memory.c --- linux-2.4.21/arch/mips/mips-boards/generic/memory.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/generic/memory.c 2003-08-25 04:44:40.000000000 -0700 @@ -168,7 +168,7 @@ + boot_mem_map.map[i].size) { ClearPageReserved(virt_to_page(__va(addr))); set_page_count(virt_to_page(__va(addr)), 1); - free_page(__va(addr)); + free_page((unsigned long)__va(addr)); addr += PAGE_SIZE; freed += PAGE_SIZE; } diff -urN linux-2.4.21/arch/mips/mips-boards/generic/pci.c linux-2.4.22/arch/mips/mips-boards/generic/pci.c --- linux-2.4.21/arch/mips/mips-boards/generic/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/generic/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as @@ -16,442 +16,31 @@ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * MIPS boards specific PCI support. - * */ #include - -#ifdef CONFIG_PCI - #include #include #include #include #include -#include +#include #include #ifdef CONFIG_MIPS_MALTA #include #endif #include -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -/* - * PCI configuration cycle AD bus definition - */ -/* Type 0 */ -#define PCI_CFG_TYPE0_REG_SHF 0 -#define PCI_CFG_TYPE0_FUNC_SHF 8 - -/* Type 1 */ -#define PCI_CFG_TYPE1_REG_SHF 0 -#define PCI_CFG_TYPE1_FUNC_SHF 8 -#define PCI_CFG_TYPE1_DEV_SHF 11 -#define PCI_CFG_TYPE1_BUS_SHF 16 - -static int -mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 *data) -{ - unsigned char bus = dev->bus->number; - unsigned char dev_fn = dev->devfn; - unsigned char type; - u32 intr, dummy; - u64 pci_addr; - - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - /* Galileo GT64120 system controller. */ - - if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) - return -1; /* Because of a bug in the galileo (for slot 31). */ - - /* Clear cause register bits */ - GT_READ(GT_INTRCAUSE_OFS, intr); - GT_WRITE(GT_INTRCAUSE_OFS, intr & - ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - /* Setup address */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | - (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | - ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | - GT_PCI0_CFGADDR_CONFIGEN_BIT); - - if (access_type == PCI_ACCESS_WRITE) { - if (bus == 0 && dev_fn == 0) { - /* - * The Galileo system controller is acting - * differently than other devices. - */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } - } else { - if (bus == 0 && dev_fn == 0) { - /* - * The Galileo system controller is acting - * differently than other devices. - */ - GT_READ(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data); - } - } - - /* Check for master or target abort */ - GT_READ(GT_INTRCAUSE_OFS, intr); - - if (intr & (GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)) - { - /* Error occured */ - - /* Clear bits */ - GT_READ(GT_INTRCAUSE_OFS, intr); - GT_WRITE(GT_INTRCAUSE_OFS, intr & - ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - return -1; - } - - break; - - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - /* Algorithmics Bonito64 system controller. */ - - if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) { - return -1; - } - - /* Clear cause register bits */ - BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | - BONITO_PCICMD_MTABORT_CLR); - - /* - * Setup pattern to be used as PCI "address" for - * Type 0 cycle - */ - if (bus == 0) { - /* IDSEL */ - pci_addr = (u64)1 << (PCI_SLOT(dev_fn) + 10); - } else { - /* Bus number */ - pci_addr = bus << PCI_CFG_TYPE1_BUS_SHF; - - /* Device number */ - pci_addr |= PCI_SLOT(dev_fn) << PCI_CFG_TYPE1_DEV_SHF; - } - - /* Function (same for Type 0/1) */ - pci_addr |= PCI_FUNC(dev_fn) << PCI_CFG_TYPE0_FUNC_SHF; - - /* Register number (same for Type 0/1) */ - pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF; - - if (bus == 0) { - /* Type 0 */ - BONITO_PCIMAP_CFG = pci_addr >> 16; - } else { - /* Type 1 */ - BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; - } - - /* Flush Bonito register block */ - dummy = BONITO_PCIMAP_CFG; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "sync\n\t" - ".set\tat\n\t" - ".set\treorder"); - - /* Perform access */ - if (access_type == PCI_ACCESS_WRITE) { - *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + - (pci_addr & 0xffff))) = *(u32 *)data; - - /* Wait till done */ - while (BONITO_PCIMSTAT & 0xF) - ; - } else { - *(u32 *)data = - *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + - (pci_addr & 0xffff))); - } - - /* Detect Master/Target abort */ - if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | - BONITO_PCICMD_MTABORT_CLR) ) - { - /* Error occurred */ - - /* Clear bits */ - BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | - BONITO_PCICMD_MTABORT_CLR); - - return -1; - } - break; - - case MIPS_REVISION_CORID_CORE_MSC: - /* MIPS system controller. */ - - if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) { - return -1; - } - - /* Clear status register bits. */ - MSC_WRITE(MSC01_PCI_INTSTAT, - (MSC01_PCI_INTCFG_MA_BIT | - MSC01_PCI_INTCFG_TA_BIT)); - - /* Setup address */ - if (bus == 0) - type = 0; /* Type 0 */ - else - type = 1; /* Type 1 */ - - MSC_WRITE(MSC01_PCI_CFGADDR, - ((bus << MSC01_PCI_CFGADDR_BNUM_SHF) | - (PCI_SLOT(dev_fn) << MSC01_PCI_CFGADDR_DNUM_SHF) | - (PCI_FUNC(dev_fn) << MSC01_PCI_CFGADDR_FNUM_SHF) | - ((where /4 ) << MSC01_PCI_CFGADDR_RNUM_SHF) | - (type))); - - /* Perform access */ - if (access_type == PCI_ACCESS_WRITE) { - MSC_WRITE(MSC01_PCI_CFGDATA, *data); - } else { - MSC_READ(MSC01_PCI_CFGDATA, *data); - } - - /* Detect Master/Target abort */ - MSC_READ(MSC01_PCI_INTSTAT, intr); - if (intr & (MSC01_PCI_INTCFG_MA_BIT | - MSC01_PCI_INTCFG_TA_BIT)) - { - /* Error occurred */ - - /* Clear bits */ - MSC_READ(MSC01_PCI_INTSTAT, intr); - MSC_WRITE(MSC01_PCI_INTSTAT, - (MSC01_PCI_INTCFG_MA_BIT | - MSC01_PCI_INTCFG_TA_BIT)); - - return -1; - } - break; - default: - printk("Unknown Core card, don't know the system controller.\n"); - return -1; - } - - return 0; -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int -mips_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val) -{ - u32 data = 0; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = (data >> ((where & 3) << 3)) & 0xff; - - return PCIBIOS_SUCCESSFUL; -} - - -static int -mips_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = (data >> ((where & 3) << 3)) & 0xffff; +extern struct pci_ops bonito64_pci_ops; +extern struct pci_ops gt64120_pci_ops; +extern struct pci_ops msc_pci_ops; - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val) -{ - u32 data = 0; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - - -static int -mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops mips_pci_ops = { - mips_pcibios_read_config_byte, - mips_pcibios_read_config_word, - mips_pcibios_read_config_dword, - mips_pcibios_write_config_byte, - mips_pcibios_write_config_word, - mips_pcibios_write_config_dword -}; - -int mips_pcibios_iack(void) -{ - int irq; - u32 dummy; - - /* - * Determine highest priority pending interrupt by performing - * a PCI Interrupt Acknowledge cycle. - */ - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - case MIPS_REVISION_CORID_CORE_MSC: - if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC) - MSC_READ(MSC01_PCI_IACK, irq); - else - GT_READ(GT_PCI0_IACK_OFS, irq); - irq &= 0xff; - break; - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - /* The following will generate a PCI IACK cycle on the - * Bonito controller. It's a little bit kludgy, but it - * was the easiest way to implement it in hardware at - * the given time. - */ - BONITO_PCIMAP_CFG = 0x20000; - - /* Flush Bonito register block */ - dummy = BONITO_PCIMAP_CFG; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "sync\n\t" - ".set\tat\n\t" - ".set\treorder"); - - irq = *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE)); - irq &= 0xff; - BONITO_PCIMAP_CFG = 0; - break; - default: - printk("Unknown Core card, don't know the system controller.\n"); - return -1; - } - return irq; -} - -void __init pcibios_init(void) +static void __init malta_fixup(void) { #ifdef CONFIG_MIPS_MALTA struct pci_dev *pdev; unsigned char reg_val; -#endif - printk("PCI: Probing PCI hardware on host bus 0.\n"); - pci_scan_bus(0, &mips_pci_ops, NULL); - - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - /* - * Due to a bug in the Galileo system controller, we need - * to setup the PCI BAR for the Galileo internal registers. - * This should be done in the bios/bootprom and will be - * fixed in a later revision of YAMON (the MIPS boards - * boot prom). - */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ - (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ - (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ - ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ - GT_PCI0_CFGADDR_CONFIGEN_BIT ); - - /* Perform the write */ - GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); - break; - } - -#ifdef CONFIG_MIPS_MALTA pci_for_each_dev(pdev) { if ((pdev->vendor == PCI_VENDOR_ID_INTEL) && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB) @@ -497,57 +86,61 @@ #endif } -int __init -pcibios_enable_device(struct pci_dev *dev) +void __init pcibios_init(void) { - /* Not needed, since we enable all devices at startup. */ - return 0; -} + printk("PCI: Probing PCI hardware on host bus 0.\n"); -void __init -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ -} + switch (mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + /* + * Due to a bug in the Galileo system controller, we need + * to setup the PCI BAR for the Galileo internal registers. + * This should be done in the bios/bootprom and will be + * fixed in a later revision of YAMON (the MIPS boards + * boot prom). + */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ + (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ + ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ + GT_PCI0_CFGADDR_CONFIGEN_BIT ); -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ + /* Perform the write */ + GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(GT64120_BASE)); + + pci_scan_bus(0, >64120_pci_ops, NULL); + break; + + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + pci_scan_bus(0, &bonito64_pci_ops, NULL); + break; + + case MIPS_REVISION_CORID_CORE_MSC: + pci_scan_bus(0, &msc_pci_ops, NULL); + break; + } - return str; + malta_fixup(); } struct pci_fixup pcibios_fixups[] = { { 0 } }; -void __init -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - unsigned long where, size; - u32 reg; - - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - /* * Called after each bus is probed, but before its children * are examined. */ -void __init pcibios_fixup_bus(struct pci_bus *b) +void __devinit pcibios_fixup_bus(struct pci_bus *b) { pci_read_bridge_bases(b); } -unsigned __init int pcibios_assign_all_busses(void) +unsigned int pcibios_assign_all_busses(void) { return 1; } - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/mips-boards/generic/printf.c linux-2.4.22/arch/mips/mips-boards/generic/printf.c --- linux-2.4.21/arch/mips/mips-boards/generic/printf.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/generic/printf.c 2003-08-25 04:44:40.000000000 -0700 @@ -2,8 +2,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,101 +15,84 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * Putting things on the screen/serial line using YAMONs facilities. - * */ #include #include #include -#include #include -#include +#include #include -#include +#ifdef CONFIG_MIPS_ATLAS + +#include -#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD) /* * Atlas registers are memory mapped on 64-bit aligned boundaries and * only word access are allowed. * When reading the UART 8 bit registers only the LSB are valid. */ -unsigned int atlas_serial_in(struct async_struct *info, int offset) +static inline unsigned int serial_in(int offset) { - return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff); + return (*(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) & 0xff); } -void atlas_serial_out(struct async_struct *info, int offset, int value) +static inline void serial_out(int offset, int value) { - *(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value; + *(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) = value; } -#define serial_in atlas_serial_in -#define serial_out atlas_serial_out +#elif defined(CONFIG_MIPS_SEAD) -#else +#include -static unsigned int serial_in(struct async_struct *info, int offset) +/* + * SEAD registers are just like Atlas registers. + */ +static inline unsigned int serial_in(int offset) { - return inb(info->port + offset); + return (*(volatile unsigned int *)(mips_io_port_base + SEAD_UART0_REGS_BASE + offset*8) & 0xff); } -static void serial_out(struct async_struct *info, int offset, - int value) +static inline void serial_out(int offset, int value) { - outb(value, info->port + offset); + *(volatile unsigned int *)(mips_io_port_base + SEAD_UART0_REGS_BASE + offset*8) = value; } -#endif - -static struct serial_state rs_table[] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -/* - * Hooks to fake "prom" console I/O before devices - * are fully initialized. - */ -static struct async_struct prom_port_info = {0}; -void __init setup_prom_printf(int tty_no) { - struct serial_state *ser = &rs_table[tty_no]; +#else - prom_port_info.state = ser; - prom_port_info.magic = SERIAL_MAGIC; - prom_port_info.port = ser->port; - prom_port_info.flags = ser->flags; +static inline unsigned int serial_in(int offset) +{ + return inb(0x3f8 + offset); +} - /* No setup of UART - assume YAMON left in sane state */ +static inline void serial_out(int offset, int value) +{ + outb(value, 0x3f8 + offset); } +#endif int putPromChar(char c) { - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while ((serial_in(&prom_port_info, UART_LSR) & UART_LSR_THRE) == 0) + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; - serial_out(&prom_port_info, UART_TX, c); + serial_out(UART_TX, c); return 1; } char getPromChar(void) { - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while (!(serial_in(&prom_port_info, UART_LSR) & 1)) + while (!(serial_in(UART_LSR) & 1)) ; - return(serial_in(&prom_port_info, UART_RX)); + return serial_in(UART_RX); } +static spinlock_t con_lock = SPIN_LOCK_UNLOCKED; + static char buf[1024]; void __init prom_printf(char *fmt, ...) @@ -123,8 +104,7 @@ int putPromChar(char); - /* Low level, brute force, not SMP safe... */ - save_and_cli(flags); + spin_lock_irqsave(con_lock, flags); va_start(args, fmt); l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ va_end(args); @@ -133,8 +113,9 @@ for (p = buf; p < buf_end; p++) { /* Crude cr/nl handling is better than none */ - if(*p == '\n')putPromChar('\r'); + if (*p == '\n') + putPromChar('\r'); putPromChar(*p); } - restore_flags(flags); + spin_unlock_irqrestore(con_lock, flags); } diff -urN linux-2.4.21/arch/mips/mips-boards/generic/time.c linux-2.4.22/arch/mips/mips-boards/generic/time.c --- linux-2.4.21/arch/mips/mips-boards/generic/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/generic/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -65,7 +65,7 @@ static inline void ack_r4ktimer(unsigned int newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } void mips_timer_interrupt(struct pt_regs *regs) @@ -87,25 +87,25 @@ */ static unsigned int __init cal_r4koff(void) { - unsigned int flags; + unsigned long flags; - __save_and_cli(flags); + local_irq_save(flags); /* Start counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - mips_counter_frequency = read_32bit_cp0_register(CP0_COUNT); + mips_counter_frequency = read_c0_count(); /* restore interrupts */ - __restore_flags(flags); + local_irq_restore(flags); return (mips_counter_frequency / HZ); } @@ -147,9 +147,10 @@ void __init mips_time_init(void) { - unsigned int est_freq, flags; + unsigned long flags; + unsigned int est_freq; - __save_and_cli(flags); + local_irq_save(flags); /* Set Data mode - binary. */ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); @@ -158,7 +159,7 @@ r4k_offset = cal_r4koff(); printk("%08x(%d)\n", r4k_offset, r4k_offset); - if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == + if ((read_c0_prid() & 0xffff00) == (PRID_COMP_MIPS | PRID_IMP_20KC)) est_freq = r4k_offset*HZ; else @@ -169,7 +170,7 @@ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - __restore_flags(flags); + local_irq_restore(flags); } void __init mips_timer_setup(struct irqaction *irq) @@ -179,7 +180,7 @@ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ALLINTS); + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); } diff -urN linux-2.4.21/arch/mips/mips-boards/malta/malta_int.c linux-2.4.22/arch/mips/mips-boards/malta/malta_int.c --- linux-2.4.21/arch/mips/mips-boards/malta/malta_int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/malta/malta_int.c 2003-08-25 04:44:40.000000000 -0700 @@ -23,28 +23,83 @@ */ #include #include +#include #include #include #include #include #include -#include +#include #include #include #include #include -#include +#include #include #include extern asmlinkage void mipsIRQ(void); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); -extern void init_i8259_irqs (void); extern int mips_pcibios_iack(void); +#ifdef CONFIG_KGDB +extern void breakpoint(void); +extern void set_debug_traps(void); +extern int remote_debug; +#endif + static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED; +/* + * Algorithmics Bonito64 system controller register base. + */ +static char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE); + +static inline int mips_pcibios_iack(void) +{ + int irq; + u32 dummy; + + /* + * Determine highest priority pending interrupt by performing + * a PCI Interrupt Acknowledge cycle. + */ + switch(mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + case MIPS_REVISION_CORID_CORE_MSC: + if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC) + MSC_READ(MSC01_PCI_IACK, irq); + else + irq = GT_READ(GT_PCI0_IACK_OFS); + irq &= 0xff; + break; + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + /* The following will generate a PCI IACK cycle on the + * Bonito controller. It's a little bit kludgy, but it + * was the easiest way to implement it in hardware at + * the given time. + */ + BONITO_PCIMAP_CFG = 0x20000; + + /* Flush Bonito register block */ + dummy = BONITO_PCIMAP_CFG; + iob(); /* sync */ + + irq = *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE)); + iob(); /* sync */ + irq &= 0xff; + BONITO_PCIMAP_CFG = 0; + break; + default: + printk("Unknown Core card, don't know the system controller.\n"); + return -1; + } + return irq; +} + static inline int get_int(int *irq) { unsigned long flags; @@ -91,6 +146,9 @@ { unsigned int data,datahi; + /* Mask out corehi interrupt. */ + clear_c0_status(IE_IRQ3); + printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" , regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); @@ -100,10 +158,10 @@ case MIPS_REVISION_CORID_QED_RM5261: case MIPS_REVISION_CORID_CORE_LV: case MIPS_REVISION_CORID_CORE_FPGA: - GT_READ(GT_INTRCAUSE_OFS, data); + data = GT_READ(GT_INTRCAUSE_OFS); printk("GT_INTRCAUSE = %08x\n", data); - GT_READ(0x70, data); - GT_READ(0x78, datahi); + data = GT_READ(0x70); + datahi = GT_READ(0x78); printk("GT_CPU_ERR_ADDR = %0x2%08x\n", datahi,data); break; case MIPS_REVISION_CORID_BONITO64: @@ -125,7 +183,6 @@ /* We die here*/ die("CoreHi interrupt", regs); - while (1) ; } void __init init_IRQ(void) @@ -134,7 +191,7 @@ init_generic_irq(); init_i8259_irqs(); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); diff -urN linux-2.4.21/arch/mips/mips-boards/malta/malta_setup.c linux-2.4.22/arch/mips/mips-boards/malta/malta_setup.c --- linux-2.4.21/arch/mips/mips-boards/malta/malta_setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/malta/malta_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -50,11 +50,9 @@ char serial_console[20]; #endif -#ifdef CONFIG_REMOTE_DEBUG -extern void set_debug_traps(void); +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); -extern void breakpoint(void); -static int remote_debug = 0; +int remote_debug = 0; #endif extern struct ide_ops std_ide_ops; @@ -64,9 +62,6 @@ extern void mips_reboot_setup(void); -extern void (*board_time_init)(void); -extern void (*board_timer_setup)(struct irqaction *irq); -extern unsigned long (*rtc_get_time)(void); extern void mips_time_init(void); extern void mips_timer_setup(struct irqaction *irq); extern unsigned long mips_rtc_get_time(void); @@ -85,17 +80,13 @@ return "MIPS Malta"; } -void __init bus_error_init(void) -{ -} - void __init malta_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int rs_putDebugChar(char); char rs_getDebugChar(void); - extern int (*putDebugChar)(char); - extern char (*getDebugChar)(void); + extern int (*generic_putDebugChar)(char); + extern char (*generic_getDebugChar)(void); #endif char *argptr; int i; @@ -117,7 +108,7 @@ } #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -130,8 +121,8 @@ line ? 1 : 0); rs_kgdb_hook(line); - putDebugChar = rs_putDebugChar; - getDebugChar = rs_getDebugChar; + generic_putDebugChar = rs_putDebugChar; + generic_getDebugChar = rs_getDebugChar; prom_printf("KGDB: Using serial line /dev/ttyS%d for session, " "please connect your debugger\n", line ? 1 : 0); @@ -143,7 +134,7 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; rtc_ops = &malta_rtc_ops; diff -urN linux-2.4.21/arch/mips/mips-boards/sead/sead_int.c linux-2.4.22/arch/mips/mips-boards/sead/sead_int.c --- linux-2.4.21/arch/mips/mips-boards/sead/sead_int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/sead/sead_int.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,34 +25,33 @@ */ #include #include +#include #include #include #include #include -#include #include #include extern asmlinkage void mipsIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); void disable_sead_irq(unsigned int irq_nr) { if (irq_nr == SEADINT_UART0) - clear_cp0_status(0x00000400); + clear_c0_status(0x00000400); else if (irq_nr == SEADINT_UART1) - clear_cp0_status(0x00000800); + clear_c0_status(0x00000800); } void enable_sead_irq(unsigned int irq_nr) { if (irq_nr == SEADINT_UART0) - set_cp0_status(0x00000400); + set_c0_status(0x00000400); else if (irq_nr == SEADINT_UART1) - set_cp0_status(0x00000800); + set_c0_status(0x00000800); } static unsigned int startup_sead_irq(unsigned int irq) @@ -99,14 +98,14 @@ /* * Mask out all interrupt */ - clear_cp0_status(0x0000ff00); + clear_c0_status(0x0000ff00); /* Now safe to set the exception vector. */ set_except_vector(0, mipsIRQ); init_generic_irq(); - for (i = 0; i <= SEADINT_END; i++) { + for (i = 0; i < SEADINT_END; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; diff -urN linux-2.4.21/arch/mips/mips-boards/sead/sead_setup.c linux-2.4.22/arch/mips/mips-boards/sead/sead_setup.c --- linux-2.4.21/arch/mips/mips-boards/sead/sead_setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/sead/sead_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -45,10 +45,6 @@ return "MIPS SEAD"; } -void __init bus_error_init(void) -{ -} - void __init sead_setup(void) { char *argptr; @@ -72,7 +68,7 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; board_time_init = mips_time_init; board_timer_setup = mips_timer_setup; diff -urN linux-2.4.21/arch/mips/mips-boards/sead/sead_time.c linux-2.4.22/arch/mips/mips-boards/sead/sead_time.c --- linux-2.4.21/arch/mips/mips-boards/sead/sead_time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mips-boards/sead/sead_time.c 2003-08-25 04:44:40.000000000 -0700 @@ -59,7 +59,7 @@ static inline void ack_r4ktimer(unsigned long newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } /* @@ -87,7 +87,7 @@ r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) + } while (((unsigned long)read_c0_count() - r4k_cur) < 0x7fffffff); irq_exit(cpu, irq); @@ -111,18 +111,19 @@ void __init mips_time_init(void) { - unsigned int est_freq, flags; + unsigned long flags; + unsigned int est_freq; - __save_and_cli(flags); + local_irq_save(flags); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); printk("calculating r4koff... "); r4k_offset = cal_r4koff(); printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); - if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == + if ((read_c0_prid() & 0xffff00) == (PRID_COMP_MIPS | PRID_IMP_20KC)) est_freq = r4k_offset*HZ; else @@ -133,7 +134,7 @@ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - __restore_flags(flags); + local_irq_restore(flags); } void __init mips_timer_setup(struct irqaction *irq) @@ -143,7 +144,7 @@ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ALLINTS); + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); } diff -urN linux-2.4.21/arch/mips/mm/Makefile linux-2.4.22/arch/mips/mm/Makefile --- linux-2.4.21/arch/mips/mm/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -10,28 +10,29 @@ O_TARGET := mm.o -export-objs += ioremap.o loadmmu.o umap.o -obj-y += extable.o init.o ioremap.o fault.o loadmmu.o +export-objs += cache.o ioremap.o loadmmu.o remap.o +obj-y += cache.o extable.o init.o ioremap.o fault.o \ + loadmmu.o -obj-$(CONFIG_CPU_R3000) += pg-r3k.o c-r3k.o c-tx39.o tlb-r3k.o \ - tlbex-r3k.o +obj-$(CONFIG_CPU_R3000) += pg-r3k.o c-r3k.o tlb-r3k.o tlbex-r3k.o obj-$(CONFIG_CPU_TX39XX) += pg-r3k.o c-tx39.o tlb-r3k.o tlbex-r3k.o -obj-$(CONFIG_CPU_TX49XX) += pg-r4k.o c-tx49.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_TX49XX) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R4300) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R4X00) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_VR41XX) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_R5000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_NEVADA) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_R5432) += pg-r5432.o c-r5432.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_RM7000) += pg-rm7k.o c-rm7k.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_R10000) += pg-andes.o c-andes.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS32) += pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS64) += pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_SB1) += pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_NEVADA) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5432) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_RM7000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R10000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_MIPS32) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-mips32.o +obj-$(CONFIG_CPU_MIPS64) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_SB1) += pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o \ + cex-sb1.o cerr-sb1.o -obj-$(CONFIG_SGI_IP22) += umap.o -obj-$(CONFIG_BAGET_MIPS) += umap.o +obj-$(CONFIG_64BIT_PHYS_ADDR) += remap.o +obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o +obj-$(CONFIG_SGI_IP22) += sc-ip22.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/mm/c-andes.c linux-2.4.22/arch/mips/mm/c-andes.c --- linux-2.4.21/arch/mips/mm/c-andes.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-andes.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,129 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int scache_lsz64; - -static void andes_flush_cache_all(void) -{ -} - -static void andes_flush_cache_mm(struct mm_struct *mm) -{ -} - -static void andes_flush_cache_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ -} - -static void andes_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) -{ -} - -static void andes_flush_page_to_ram(struct page *page) -{ -} - -/* Cache operations. These are only used with the virtual memory system, - not for non-coherent I/O so it's ok to ignore the secondary caches. */ -static void -andes_flush_cache_l1(void) -{ - blast_dcache32(); blast_icache64(); -} - -/* - * This is only used during initialization time. vmalloc() also calls - * this, but that will be changed pretty soon. - */ -static void -andes_flush_cache_l2(void) -{ - switch (sc_lsize()) { - case 64: - blast_scache64(); - break; - case 128: - blast_scache128(); - break; - default: - printk("Unknown L2 line size\n"); - while(1); - } -} - -static void andes___flush_cache_all(void) -{ - andes_flush_cache_l1(); - andes_flush_cache_l2(); -} - -void -andes_flush_icache_page(unsigned long page) -{ - if (scache_lsz64) - blast_scache64_page(page); - else - blast_scache128_page(page); -} - -static void -andes_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -void __init ld_mmu_andes(void) -{ - printk("Primary instruction cache %dkb, linesize %d bytes\n", - icache_size >> 10, ic_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - dcache_size >> 10, dc_lsize); - printk("Secondary cache sized at %ldK, linesize %ld\n", - scache_size() >> 10, sc_lsize()); - - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - - _flush_cache_all = andes_flush_cache_all; - ___flush_cache_all = andes___flush_cache_all; - _flush_cache_mm = andes_flush_cache_mm; - _flush_cache_page = andes_flush_cache_page; - _flush_page_to_ram = andes_flush_page_to_ram; - _flush_cache_l1 = andes_flush_cache_l1; - _flush_cache_l2 = andes_flush_cache_l2; - _flush_cache_sigtramp = andes_flush_cache_sigtramp; - - switch (sc_lsize()) { - case 64: - scache_lsz64 = 1; - break; - case 128: - scache_lsz64 = 0; - break; - default: - printk("Unknown L2 line size\n"); - while(1); - } - - flush_cache_l1(); -} diff -urN linux-2.4.21/arch/mips/mm/c-mips32.c linux-2.4.22/arch/mips/mm/c-mips32.c --- linux-2.4.21/arch/mips/mm/c-mips32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-mips32.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,671 +0,0 @@ -/* - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute 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 it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You 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. - * - * MIPS32 CPU variant specific MMU/Cache routines. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -int icache_size, dcache_size; /* Size in bytes */ -int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include - -#undef DEBUG_CACHE - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - -static inline void mips32_flush_cache_all_sc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); blast_scache(); - __restore_flags(flags); -} - -static inline void mips32_flush_cache_all_pc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); -} - -static void -mips32_flush_cache_range_sc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - unsigned long flags; - - if(mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if(mm->context != current->mm->context) { - mips32_flush_cache_all_sc(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - __save_and_cli(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache_page(start); - start += PAGE_SIZE; - } - __restore_flags(flags); - } - } -} - -static void mips32_flush_cache_range_pc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void mips32_flush_cache_mm_sc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips32_flush_cache_all_sc(); - } -} - -static void mips32_flush_cache_mm_pc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips32_flush_cache_all_pc(); - } -} - -static void mips32_flush_cache_page_sc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache_page_indexed(page); - blast_scache_page_indexed(page); - } else - blast_scache_page(page); -out: - __restore_flags(flags); -} - -static void mips32_flush_cache_page_pc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since Mips32 caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache_page_indexed(page); - } -out: - __restore_flags(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void mips32_flush_page_to_ram_sc(struct page *page) -{ - blast_scache_page((unsigned long)page_address(page)); -} - -static void mips32_flush_page_to_ram_pc(struct page *page) -{ - blast_dcache_page((unsigned long)page_address(page)); -} - -static void -mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -static void -mips32_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -static void -mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - int address; - - if (!(vma->vm_flags & VM_EXEC)) - return; - - address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1)); - blast_icache_page_indexed(address); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - bc_wback_inv(addr, size); -} - -static void -mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - - bc_inv(addr, size); -} - -static void -mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips32_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("mips32_dma_cache called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void mips32_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void mips32_flush_icache_all(void) -{ - if (mips_cpu.cputype == CPU_20KC) { - blast_icache(); - } -} - -/* Detect and size the various caches. */ -static void __init probe_icache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS32 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - mips_cpu.icache.linesz = ic_lsize; - - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1; - mips_cpu.icache.sets = - (icache_size / ic_lsize) / mips_cpu.icache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 19) & 7))) - mips_cpu.icache.linesz = 2 << lsize; - else - mips_cpu.icache.linesz = lsize; - mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7); - mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7); - - ic_lsize = mips_cpu.icache.linesz; - icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * - ic_lsize; - } - printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n", - icache_size >> 10, ic_lsize, mips_cpu.icache.ways); -} - -static void __init probe_dcache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS32 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - mips_cpu.dcache.linesz = dc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1; - mips_cpu.dcache.sets = - (dcache_size / dc_lsize) / mips_cpu.dcache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 10) & 7))) - mips_cpu.dcache.linesz = 2 << lsize; - else - mips_cpu.dcache.linesz= lsize; - mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7); - mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7); - - dc_lsize = mips_cpu.dcache.linesz; - dcache_size = - mips_cpu.dcache.sets * mips_cpu.dcache.ways - * dc_lsize; - } - printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n", - dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT) - return 0; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - __save_and_cli(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 8, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 9, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 11, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 7, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - __restore_flags(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - _clear_page = (void *)mips32_clear_page_dc; - _copy_page = (void *)mips32_copy_page_dc; - _flush_cache_all = mips32_flush_cache_all_pc; - ___flush_cache_all = mips32_flush_cache_all_pc; - _flush_cache_mm = mips32_flush_cache_mm_pc; - _flush_cache_range = mips32_flush_cache_range_pc; - _flush_cache_page = mips32_flush_cache_page_pc; - _flush_page_to_ram = mips32_flush_page_to_ram_pc; - - _flush_icache_page = mips32_flush_icache_page; - - _dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc; - _dma_cache_wback = mips32_dma_cache_wback; - _dma_cache_inv = mips32_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - _flush_cache_all = mips32_flush_cache_all_sc; - ___flush_cache_all = mips32_flush_cache_all_sc; - _flush_cache_mm = mips32_flush_cache_mm_sc; - _flush_cache_range = mips32_flush_cache_range_sc; - _flush_cache_page = mips32_flush_cache_page_sc; - _flush_page_to_ram = mips32_flush_page_to_ram_sc; - _clear_page = (void *)mips32_clear_page_sc; - _copy_page = (void *)mips32_copy_page_sc; - - _flush_icache_page = mips32_flush_icache_page_s; - - _dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc; - _dma_cache_wback = mips32_dma_cache_wback; - _dma_cache_inv = mips32_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (sc_present) { - mips_cpu.scache.linesz = sc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1; - mips_cpu.scache.sets = - (scache_size / sc_lsize) / mips_cpu.scache.ways; - - setup_scache_funcs(); - return; - } - - setup_noscache_funcs(); -} - -void __init ld_mmu_mips32(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - _flush_cache_sigtramp = mips32_flush_cache_sigtramp; - _flush_icache_range = mips32_flush_icache_range; /* Ouch */ - _flush_icache_all = mips32_flush_icache_all; - - __flush_cache_all(); -} diff -urN linux-2.4.21/arch/mips/mm/c-r3k.c linux-2.4.22/arch/mips/mm/c-r3k.c --- linux-2.4.21/arch/mips/mm/c-r3k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-r3k.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,6 +7,7 @@ * Tx39XX R4k style caches added. HK * Copyright (C) 1998, 1999, 2000 Harald Koerfgen * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 2001 Maciej W. Rozycki */ #include #include @@ -22,6 +23,9 @@ #include #include +void r3k_clear_page(void * page); +void r3k_copy_page(void * to, void * from); + static unsigned long icache_size, dcache_size; /* Size in bytes */ static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */ @@ -34,14 +38,14 @@ p = (volatile unsigned long *) KSEG0; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC); + write_c0_status((ca_flags|flags)&~ST0_IEC); *p = 0xa5a55a5a; dummy = *p; - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); if (dummy != 0xa5a55a5a || (status & ST0_CM)) { size = 0; @@ -57,7 +61,7 @@ size = 0; } - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); return size * sizeof(*p); } @@ -69,24 +73,24 @@ p = (volatile unsigned long *) KSEG0; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC); + write_c0_status((ca_flags|flags)&~ST0_IEC); for (i = 0; i < 128; i++) *(p + i) = 0; *(volatile unsigned char *)p = 0; for (lsize = 1; lsize < 128; lsize <<= 1) { *(p + lsize); - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); if (!(status & ST0_CM)) break; } for (i = 0; i < 128; i += lsize) *(volatile unsigned char *)(p + i) = 0; - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); return lsize * sizeof(*p); } @@ -97,7 +101,6 @@ if (dcache_size) dcache_lsize = r3k_cache_lsize(ST0_ISC); - icache_size = r3k_cache_size(ST0_ISC|ST0_SWC); if (icache_size) icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC); @@ -115,10 +118,10 @@ } p = (char *)start; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC); + write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); for (i = 0; i < size; i += 0x080) { asm ( "sb\t$0, 0x000(%0)\n\t" @@ -157,7 +160,7 @@ p += 0x080; } - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); } static void r3k_flush_dcache_range(unsigned long start, unsigned long end) @@ -172,10 +175,10 @@ } p = (char *)start; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|flags)&~ST0_IEC); + write_c0_status((ST0_ISC|flags)&~ST0_IEC); for (i = 0; i < size; i += 0x080) { asm ( "sb\t$0, 0x000(%0)\n\t" @@ -214,7 +217,7 @@ p += 0x080; } - write_32bit_cp0_register(CP0_STATUS,flags); + write_c0_status(flags); } static inline unsigned long get_phys_page (unsigned long addr, @@ -241,6 +244,7 @@ static inline void r3k___flush_cache_all(void) { + r3k_flush_dcache_range(KSEG0, KSEG0 + dcache_size); r3k_flush_icache_range(KSEG0, KSEG0 + icache_size); } @@ -258,11 +262,8 @@ { } -static void r3k_flush_page_to_ram(struct page * page) +static void r3k_flush_data_cache_page(unsigned long addr) { - /* - * Nothing to be done - */ } static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page) @@ -270,14 +271,14 @@ struct mm_struct *mm = vma->vm_mm; unsigned long physpage; - if (mm->context == 0) + if (cpu_context(smp_processor_id(), mm) == 0) return; if (!(vma->vm_flags & VM_EXEC)) return; #ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); + printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page); #endif physpage = (unsigned long) page_address(page); @@ -293,22 +294,22 @@ printk("csigtramp[%08lx]", addr); #endif - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); - write_32bit_cp0_register(CP0_STATUS, flags&~ST0_IEC); + write_c0_status(flags&~ST0_IEC); /* Fill the TLB to avoid an exception with caches isolated. */ asm ( "lw\t$0, 0x000(%0)\n\t" "lw\t$0, 0x004(%0)\n\t" : : "r" (addr) ); - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC); + write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); asm ( "sb\t$0, 0x000(%0)\n\t" "sb\t$0, 0x004(%0)\n\t" : : "r" (addr) ); - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); } static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) @@ -331,16 +332,16 @@ _flush_cache_mm = r3k_flush_cache_mm; _flush_cache_range = r3k_flush_cache_range; _flush_cache_page = r3k_flush_cache_page; - _flush_cache_sigtramp = r3k_flush_cache_sigtramp; - _flush_page_to_ram = r3k_flush_page_to_ram; _flush_icache_page = r3k_flush_icache_page; _flush_icache_range = r3k_flush_icache_range; - _dma_cache_wback_inv = r3k_dma_cache_wback_inv; + _flush_cache_sigtramp = r3k_flush_cache_sigtramp; + _flush_data_cache_page = r3k_flush_data_cache_page; - printk("Primary instruction cache %dkb, linesize %d bytes\n", - (int) (icache_size >> 10), (int) icache_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - (int) (dcache_size >> 10), (int) dcache_lsize); + _dma_cache_wback_inv = r3k_dma_cache_wback_inv; + printk("Primary instruction cache %ldkB, linesize %ld bytes.\n", + icache_size >> 10, icache_lsize); + printk("Primary data cache %ldkB, linesize %ld bytes.\n", + dcache_size >> 10, dcache_lsize); } diff -urN linux-2.4.21/arch/mips/mm/c-r4k.c linux-2.4.22/arch/mips/mm/c-r4k.c --- linux-2.4.21/arch/mips/mm/c-r4k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-r4k.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,44 +3,51 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include #include #include #include #include +#include +#include #include +#include #include -#include #include #include #include +#include #include #include #include -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -static unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include +static unsigned long icache_size, dcache_size, scache_size; -#undef DEBUG_CACHE +extern void andes_clear_page(void * page); +extern void r4k_clear_page32_d16(void * page); +extern void r4k_clear_page32_d32(void * page); +extern void r4k_clear_page_d16(void * page); +extern void r4k_clear_page_d32(void * page); +extern void r4k_clear_page_r4600_v1(void * page); +extern void r4k_clear_page_r4600_v2(void * page); +extern void r4k_clear_page_s16(void * page); +extern void r4k_clear_page_s32(void * page); +extern void r4k_clear_page_s64(void * page); +extern void r4k_clear_page_s128(void * page); +extern void andes_copy_page(void * to, void * from); +extern void r4k_copy_page_d16(void * to, void * from); +extern void r4k_copy_page_d32(void * to, void * from); +extern void r4k_copy_page_r4600_v1(void * to, void * from); +extern void r4k_copy_page_r4600_v2(void * to, void * from); +extern void r4k_copy_page_s16(void * to, void * from); +extern void r4k_copy_page_s32(void * to, void * from); +extern void r4k_copy_page_s64(void * to, void * from); +extern void r4k_copy_page_s128(void * to, void * from); /* * Dummy cache handling routines for machines without boardcaches @@ -48,884 +55,386 @@ static void no_sc_noop(void) {} static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop + .bc_enable = (void *)no_sc_noop, + .bc_disable = (void *)no_sc_noop, + .bc_wback_inv = (void *)no_sc_noop, + .bc_inv = (void *)no_sc_noop }; struct bcache_ops *bcops = &no_sc_ops; -/* - * On processors with QED R4600 style two set assosicative cache - * this is the bit which selects the way in the cache for the - * indexed cachops. - */ -#define icache_waybit (icache_size >> 1) -#define dcache_waybit (dcache_size >> 1) +#define R4600_HIT_CACHEOP_WAR_IMPL \ +do { \ + if (R4600_V2_HIT_CACHEOP_WAR && \ + (read_c0_prid() & 0xfff0) == 0x2020) { /* R4600 V2.0 */\ + *(volatile unsigned long *)KSEG1; \ + } \ + if (R4600_V1_HIT_CACHEOP_WAR) \ + __asm__ __volatile__("nop;nop;nop;nop"); \ +} while (0) -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r4k_flush_cache_all_s16d16i16(void) +static void r4k_blast_dcache_page(unsigned long addr) { - blast_dcache16(); blast_icache16(); blast_scache16(); -} + static void *l = &&init; + unsigned long dc_lsize; -static inline void r4k_flush_cache_all_s32d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache32(); -} + goto *l; -static inline void r4k_flush_cache_all_s64d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache64(); -} +dc_16: + blast_dcache16_page(addr); + return; -static inline void r4k_flush_cache_all_s128d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache128(); -} +dc_32: + R4600_HIT_CACHEOP_WAR_IMPL; + blast_dcache32_page(addr); + return; -static inline void r4k_flush_cache_all_s32d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache32(); -} +init: + dc_lsize = current_cpu_data.dcache.linesz; -static inline void r4k_flush_cache_all_s64d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache64(); + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; } -static inline void r4k_flush_cache_all_s128d32i32(void) +static void r4k_blast_dcache_page_indexed(unsigned long addr) { - blast_dcache32(); blast_icache32(); blast_scache128(); -} + static void *l = &&init; + unsigned long dc_lsize; -static inline void r4k_flush_cache_all_d16i16(void) -{ - blast_dcache16(); blast_icache16(); -} + goto *l; -static inline void r4k_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); -} +dc_16: + blast_dcache16_page_indexed(addr); + return; -static void -r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; +dc_32: + blast_dcache32_page_indexed(addr); + return; - if (mm->context == 0) - return; +init: + dc_lsize = current_cpu_data.dcache.linesz; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s16d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while (start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache16_page(start); - start += PAGE_SIZE; - } - } - } + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; } -static void -r4k_flush_cache_range_s32d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static void r4k_blast_dcache(void) { - struct vm_area_struct *vma; + static void *l = &&init; + unsigned long dc_lsize; - if (mm->context == 0) - return; + goto *l; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s32d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } -} +dc_16: + blast_dcache16(); + return; -static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; +dc_32: + blast_dcache32(); + return; - if (mm->context == 0) - return; +init: + dc_lsize = current_cpu_data.dcache.linesz; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s64d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; } -static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (mm->context == 0) - return; +/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */ +#define JUMP_TO_ALIGN(order) \ + __asm__ __volatile__( \ + "b\t1f\n\t" \ + ".align\t" #order "\n\t" \ + "1:\n\t" \ + ) +#define CACHE32_UNROLL32_ALIGN JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */ +#define CACHE32_UNROLL32_ALIGN2 JUMP_TO_ALIGN(11) - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s128d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static inline void tx49_blast_icache32(void) { - struct vm_area_struct *vma; - - if (mm->context == 0) - return; + unsigned long start = KSEG0; + unsigned long end = start + current_cpu_data.icache.waysize; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s32d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static inline void tx49_blast_icache32_page_indexed(unsigned long page) { - struct vm_area_struct *vma; + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s64d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static void r4k_blast_icache_page(unsigned long addr) { - struct vm_area_struct *vma; + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; - if (mm->context == 0) - return; + goto *l; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s128d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} +ic_16: + blast_icache16_page(addr); + return; -static void r4k_flush_cache_range_d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache16(); blast_icache16(); - } -} +ic_32: + blast_icache32_page(addr); + return; -static void r4k_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache32(); blast_icache32(); - } -} +ic_64: + blast_icache64_page(addr); + return; -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d16i16(); - } +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; } -static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm) +static void r4k_blast_icache_page_indexed(unsigned long addr) { - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d16i16(); - } -} + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; -static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d16i16(); - } -} + goto *l; -static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d16i16(); - } -} +ic_16: + blast_icache16_page_indexed(addr); + return; -static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d32i32(); - } -} +ic_32: + blast_icache32_page_indexed(addr); + return; -static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d32i32(); - } -} +ic_64: + blast_icache64_page_indexed(addr); + return; -static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d32i32(); - } -} +ic_32_tx49: + tx49_blast_icache32_page_indexed(addr); + return; -static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d16i16(); - } -} - -static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d32i32(); - } +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; } -static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, - unsigned long page) +static void r4k_blast_icache(void) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; + goto *l; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +ic_16: + blast_icache16(); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +ic_32: + blast_icache32(); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache16_page_indexed(page); - } else - blast_scache16_page(page); -out: -} +ic_64: + blast_icache64(); + return; -static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +ic_32_tx49: + tx49_blast_icache32(); + return; - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: -} - -static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; } -static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, - unsigned long page) +static void r4k_blast_scache_page(unsigned long addr) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; + goto *l; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +sc_16: + blast_scache16_page(addr); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +sc_32: + blast_scache32_page(addr); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: -} - -static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +sc_64: + blast_scache64_page(addr); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +sc_128: + blast_scache128_page(addr); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; } -static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, - unsigned long page) +static void r4k_blast_scache(void) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: -} + goto *l; -static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; +sc_16: + blast_scache16(); + return; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; +sc_32: + blast_scache32(); + return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +sc_64: + blast_scache64(); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +sc_128: + blast_scache128(); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; } -static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) +static void r4k_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); + r4k_blast_dcache(); + r4k_blast_icache(); +} - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +static void r4k___flush_cache_all(void) +{ + r4k_blast_dcache(); + r4k_blast_icache(); - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache16_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed(page); + switch (current_cpu_data.cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R10000: + case CPU_R12000: + r4k_blast_scache(); } -out: } -static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) +static void r4k_flush_cache_range(struct mm_struct *mm, + unsigned long start, unsigned long end) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + if (!cpu_has_dc_aliases) + return; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) + if (cpu_context(smp_processor_id(), mm) != 0) { + r4k_blast_dcache(); + r4k_blast_icache(); + } +} + +static void r4k_flush_cache_mm(struct mm_struct *mm) +{ + if (!cpu_has_dc_aliases) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); + if (!cpu_context(smp_processor_id(), mm)) + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; + r4k_blast_dcache(); + r4k_blast_icache(); /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. + * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we + * only flush the primary caches but R10000 and R12000 behave sane ... */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -out: + if (current_cpu_data.cputype == CPU_R4000SC || + current_cpu_data.cputype == CPU_R4000MC || + current_cpu_data.cputype == CPU_R4400SC || + current_cpu_data.cputype == CPU_R4400MC) + r4k_blast_scache(); } -static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma, - unsigned long page) +static void r4k_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) { + int exec = vma->vm_flags & VM_EXEC; struct mm_struct *mm = vma->vm_mm; pgd_t *pgdp; pmd_t *pmdp; @@ -935,12 +444,9 @@ * If ownes no valid ASID yet, cannot possibly have gotten * this page into the cache. */ - if (mm->context == 0) + if (cpu_context(smp_processor_id(), mm) == 0) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif page &= PAGE_MASK; pgdp = pgd_offset(mm, page); pmdp = pmd_offset(pgdp, page); @@ -951,7 +457,7 @@ * in the cache. */ if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; + return; /* * Doing flushes for another ASID than the current one is @@ -960,195 +466,215 @@ * in that case, which doesn't overly flush the cache too much. */ if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - blast_dcache32_page_indexed(page ^ dcache_waybit); - } -out: -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r4k_flush_page_to_ram_s16(struct page *page) -{ - blast_scache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s32(struct page *page) -{ - blast_scache32_page((unsigned long)page_address(page)); -} + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page(page); + if (exec) + r4k_blast_icache_page(page); -static void r4k_flush_page_to_ram_s64(struct page *page) -{ - blast_scache64_page((unsigned long)page_address(page)); -} + return; + } -static void r4k_flush_page_to_ram_s128(struct page *page) -{ - blast_scache128_page((unsigned long)page_address(page)); -} + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page_indexed(page); + if (exec) { + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - blast_dcache16_page((unsigned long)page_address(page)); + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache_page_indexed(page); + } } -static void r4k_flush_page_to_ram_d32(struct page *page) +static void r4k_flush_data_cache_page(unsigned long addr) { - blast_dcache32_page((unsigned long)page_address(page)); + r4k_blast_dcache_page(addr); } -static void r4k_flush_page_to_ram_d32_r4600(struct page *page) +static void r4k_flush_icache_range(unsigned long start, unsigned long end) { -#ifdef R4600_V1_HIT_DCACHE_WAR - unsigned long flags; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; - __save_and_cli(flags); - __asm__ __volatile__("nop;nop;nop;nop"); -#endif - blast_dcache32_page((unsigned long)page_address(page)); -#ifdef R4600_V1_HIT_DCACHE_WAR - __restore_flags(flags); -#endif -} + if (!cpu_has_ic_fills_f_dc) { + if (end - start > dcache_size) + r4k_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); -static void -r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + } -static void -r4k_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); + if (end - start > icache_size) + r4k_blast_icache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } } /* * Ok, this seriously sucks. We use them to flush a user page but don't * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. */ -static void -r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page) +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) { + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ if (!(vma->vm_flags & VM_EXEC)) return; - flush_cache_all(); + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_subset_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); } -static void -r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) +#ifdef CONFIG_NONCOHERENT_IO + +static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end, a; - unsigned int flags; + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches + * explicitly + */ if (size >= dcache_size) { - flush_cache_all(); + r4k_blast_dcache(); } else { -#ifdef R4600_V2_HIT_CACHEOP_WAR - /* Workaround for R4600 bug. See comment in . */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; -#endif + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + R4600_HIT_CACHEOP_WAR_IMPL; a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; a += dc_lsize; } -#ifdef R4600_V2_HIT_CACHEOP_WAR - __restore_flags(flags); -#endif } + bc_wback_inv(addr, size); } -static void -r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) +static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) { unsigned long end, a; - if (size >= scache_size) { - flush_cache_all(); - return; - } + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} + if (size >= scache_size) { + r4k_blast_scache(); + return; + } -static void -r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } if (size >= dcache_size) { - flush_cache_all(); + r4k_blast_dcache(); } else { -#ifdef R4600_V2_HIT_CACHEOP_WAR - /* Workaround for R4600 bug. See comment above. */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; -#endif + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + R4600_HIT_CACHEOP_WAR_IMPL; a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; a += dc_lsize; } -#ifdef R4600_V2_HIT_CACHEOP_WAR - __restore_flags(flags); -#endif } bc_inv(addr, size); } - -static void -r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} +#endif /* CONFIG_NONCOHERENT_IO */ /* * While we're protected against bad userland addresses we don't care @@ -1157,170 +683,357 @@ */ static void r4k_flush_cache_sigtramp(unsigned long addr) { -#ifdef R4600_V1_HIT_DCACHE_WAR - unsigned long flags; + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; - __save_and_cli(flags); - __asm__ __volatile__("nop;nop;nop;nop"); -#endif + R4600_HIT_CACHEOP_WAR_IMPL; protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); protected_flush_icache_line(addr & ~(ic_lsize - 1)); -#ifdef R4600_V1_HIT_DCACHE_WAR - __restore_flags(flags); -#endif + if (MIPS4K_ICACHE_REFILL_WAR) { + __asm__ __volatile__ ( + ".set push\n\t" + ".set noat\n\t" + ".set mips3\n\t" +#if CONFIG_MIPS32 + "la $at,1f\n\t" +#endif +#if CONFIG_MIPS64 + "dla $at,1f\n\t" +#endif + "cache %0,($at)\n\t" + "nop; nop; nop\n" + "1:\n\t" + ".set pop" + : + : "i" (Hit_Invalidate_I)); + } + if (MIPS_CACHE_SYNC_WAR) + __asm__ __volatile__ ("sync"); +} + +static void r4k_flush_icache_all(void) +{ + if (cpu_has_vtag_icache) + r4k_blast_icache(); +} + +static inline void rm7k_erratum31(void) +{ + const unsigned long ic_lsize = 32; + unsigned long addr; + + /* RM7000 erratum #31. The icache is screwed at startup. */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + "cache\t%2, 0(%0)\n\t" + "cache\t%2, 0x1000(%0)\n\t" + "cache\t%2, 0x2000(%0)\n\t" + "cache\t%2, 0x3000(%0)\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + ".set\tmips0\n\t" + ".set\treorder\n\t" + : + : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); + } } -static void r4600v20k_flush_cache_sigtramp(unsigned long addr) +static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", + "5-way", "6-way", "7-way", "8-way" +}; + +static void __init probe_pcache(void) { - unsigned int flags; + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + unsigned int prid = read_c0_prid(); + unsigned long config1; + unsigned int lsize; -#ifdef R4600_V2_HIT_CACHEOP_WAR - __save_and_cli(flags); + switch (c->cputype) { + case CPU_R4600: /* QED style two way caches? */ + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit= ffs(dcache_size/2) - 1; + break; - /* Clear internal cache refill buffer */ - *(volatile unsigned int *)KSEG1; -#endif + case CPU_R5432: + case CPU_R5500: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); + case CPU_TX49XX: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = 0; + break; -#ifdef R4600_V2_HIT_CACHEOP_WAR - __restore_flags(flags); -#endif -} + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R4300: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - switch (mips_cpu.cputype) { - case CPU_VR41XX: - case CPU_VR4111: - case CPU_VR4121: - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4181: - case CPU_VR4181A: - icache_size = 1 << (10 + ((config >> 9) & 7)); - break; - default: - icache_size = 1 << (12 + ((config >> 9) & 7)); - break; - } - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - switch (mips_cpu.cputype) { - case CPU_VR41XX: - case CPU_VR4111: - case CPU_VR4121: - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4181: - case CPU_VR4181A: - dcache_size = 1 << (10 + ((config >> 6) & 7)); - break; - default: - dcache_size = 1 << (12 + ((config >> 6) & 7)); - break; - } - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} + case CPU_R10000: + case CPU_R12000: + icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29)); + c->icache.linesz = 64; + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26)); + c->dcache.linesz = 32; + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_VR4131: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = ffs(dcache_size/2) - 1; + break; + + case CPU_VR41XX: + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_RM7000: + rm7k_erratum31(); + + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + break; + + default: + if (!(config & MIPS_CONF_M)) + panic("Don't know how to probe P-caches on this cpu."); + + /* + * So we seem to be a MIPS32 or MIPS64 CPU + * So let's probe the I-cache ... + */ + config1 = read_c0_config1(); + + if ((lsize = ((config1 >> 19) & 7))) + c->icache.linesz = 2 << lsize; + else + c->icache.linesz = lsize; + c->icache.sets = 64 << ((config1 >> 22) & 7); + c->icache.ways = 1 + ((config1 >> 16) & 7); + + icache_size = c->icache.sets * + c->icache.ways * + c->icache.linesz; + c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + + /* + * Now probe the MIPS32 / MIPS64 data cache. + */ + c->dcache.flags = 0; + + if ((lsize = ((config1 >> 10) & 7))) + c->dcache.linesz = 2 << lsize; + else + c->dcache.linesz= lsize; + c->dcache.sets = 64 << ((config1 >> 13) & 7); + c->dcache.ways = 1 + ((config1 >> 7) & 7); + + dcache_size = c->dcache.sets * + c->dcache.ways * + c->dcache.linesz; + c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + break; + } + + /* + * Processor configuration sanity check for the R4000SC erratum + * #5. With page sizes larger than 32kB there is no possibility + * to get a VCE exception anymore so we don't care about this + * misconfiguration. The case is rather theoretical anyway; + * presumably no vendor is shipping his hardware in the "bad" + * configuration. + */ + if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && + !(config & CONF_SC) && c->icache.linesz != 16 && + PAGE_SIZE <= 0x8000) + panic("Improper R4000SC processor configuration detected"); + + /* compute a couple of other cache variables */ + c->icache.waysize = icache_size / c->icache.ways; + c->dcache.waysize = dcache_size / c->dcache.ways; + + c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); + c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); + + /* + * R10000 and R12000 P-caches are odd in a positive way. They're 32kB + * 2-way virtually indexed so normally would suffer from aliases. So + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ + if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000) + if (c->dcache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + switch (c->cputype) { + case CPU_20KC: + /* + * Some older 20Kc chips doesn't have the 'VI' bit in + * the config register. + */ + c->icache.flags |= MIPS_CACHE_VTAG; + break; + + case CPU_AU1500: + c->icache.flags |= MIPS_CACHE_IC_F_DC; + break; + } + + printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", + icache_size >> 10, + cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", + way_string[c->icache.ways], c->icache.linesz); + printk("Primary data cache %ldkB %s, linesize %d bytes.\n", + dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); +} -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. +/* + * If you even _breathe_ on this function, look at the gcc output and make sure + * it does not pop things on and off the stack for the cache sizing loop that + * executes in KSEG1 space or else you will crash and burn badly. You have + * been warned. */ -static int __init probe_scache(unsigned long config) +static int __init probe_scache(void) { extern unsigned long stext; unsigned long flags, addr, begin, end, pow2; + unsigned int config = read_c0_config(); + struct cpuinfo_mips *c = ¤t_cpu_data; int tmp; - tmp = ((config >> 17) & 1); - if(tmp) + if (config & CONF_SC) return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } begin = (unsigned long) &stext; begin &= ~((4 * 1024 * 1024) - 1); end = begin + (4 * 1024 * 1024); - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! + /* + * This is such a bitch, you'd think they would make it easy to do + * this. Away you daemons of stupidity! */ - __save_and_cli(flags); + local_irq_save(flags); /* Fill each size-multiple cache line with a valid tag. */ pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { + for (addr = begin; addr < end; addr = (begin + pow2)) { unsigned long *p = (unsigned long *) addr; __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ pow2 <<= 1; } /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); + write_c0_taglo(0); + write_c0_taghi(0); __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 8, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 9, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 11, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); + cache_op(Index_Store_Tag_I, begin); + cache_op(Index_Store_Tag_D, begin); + cache_op(Index_Store_Tag_SD, begin); /* Now search for the wrap around point. */ pow2 = (128 * 1024); tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 7, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (addr)); + for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { + cache_op(Index_Load_Tag_SD, addr); __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) + if (!read_c0_taglo()) break; pow2 <<= 1; } - __restore_flags(flags); + local_irq_restore(flags); addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); + scache_size = addr; + c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); + c->scache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + return 1; } @@ -1328,183 +1041,210 @@ { unsigned int prid; - switch(dc_lsize) { + switch (current_cpu_data.dcache.linesz) { case 16: - _clear_page = r4k_clear_page_d16; + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d16; + else + _clear_page = r4k_clear_page32_d16; _copy_page = r4k_copy_page_d16; - _flush_cache_all = r4k_flush_cache_all_d16i16; - _flush_cache_mm = r4k_flush_cache_mm_d16i16; - _flush_cache_range = r4k_flush_cache_range_d16i16; - _flush_cache_page = r4k_flush_cache_page_d16i16; - _flush_page_to_ram = r4k_flush_page_to_ram_d16; + break; case 32: - prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0; + prid = read_c0_prid() & 0xfff0; if (prid == 0x2010) { /* R4600 V1.7 */ _clear_page = r4k_clear_page_r4600_v1; _copy_page = r4k_copy_page_r4600_v1; - _flush_page_to_ram = r4k_flush_page_to_ram_d32_r4600; } else if (prid == 0x2020) { /* R4600 V2.0 */ _clear_page = r4k_clear_page_r4600_v2; _copy_page = r4k_copy_page_r4600_v2; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; } else { - _clear_page = r4k_clear_page_d32; + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d32; + else + _clear_page = r4k_clear_page32_d32; _copy_page = r4k_copy_page_d32; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; } - _flush_cache_all = r4k_flush_cache_all_d32i32; - _flush_cache_mm = r4k_flush_cache_mm_d32i32; - _flush_cache_range = r4k_flush_cache_range_d32i32; - _flush_cache_page = r4k_flush_cache_page_d32i32; break; } - ___flush_cache_all = _flush_cache_all; - - _flush_icache_page = r4k_flush_icache_page_p; - - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc; - _dma_cache_wback = r4k_dma_cache_wback_inv_pc; - _dma_cache_inv = r4k_dma_cache_inv_pc; } static void __init setup_scache_funcs(void) { - switch(sc_lsize) { + struct cpuinfo_mips *c = ¤t_cpu_data; + + if (c->dcache.linesz > c->scache.linesz) + panic("Invalid primary cache configuration detected"); + + if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) { + _clear_page = andes_clear_page; + _copy_page = andes_copy_page; + return; + } + + switch (c->scache.linesz) { case 16: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s16d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s16d16i16; - _flush_cache_range = r4k_flush_cache_range_s16d16i16; - _flush_cache_page = r4k_flush_cache_page_s16d16i16; - break; - case 32: - panic("Invalid cache configuration detected"); - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s16; _clear_page = r4k_clear_page_s16; _copy_page = r4k_copy_page_s16; break; case 32: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s32d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s32d16i16; - _flush_cache_range = r4k_flush_cache_range_s32d16i16; - _flush_cache_page = r4k_flush_cache_page_s32d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s32d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s32d32i32; - _flush_cache_range = r4k_flush_cache_range_s32d32i32; - _flush_cache_page = r4k_flush_cache_page_s32d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s32; _clear_page = r4k_clear_page_s32; _copy_page = r4k_copy_page_s32; break; case 64: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s64d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s64d16i16; - _flush_cache_range = r4k_flush_cache_range_s64d16i16; - _flush_cache_page = r4k_flush_cache_page_s64d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s64d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s64d32i32; - _flush_cache_range = r4k_flush_cache_range_s64d32i32; - _flush_cache_page = r4k_flush_cache_page_s64d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s64; _clear_page = r4k_clear_page_s64; _copy_page = r4k_copy_page_s64; break; case 128: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s128d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s128d16i16; - _flush_cache_range = r4k_flush_cache_range_s128d16i16; - _flush_cache_page = r4k_flush_cache_page_s128d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s128d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s128d32i32; - _flush_cache_range = r4k_flush_cache_range_s128d32i32; - _flush_cache_page = r4k_flush_cache_page_s128d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s128; _clear_page = r4k_clear_page_s128; _copy_page = r4k_copy_page_s128; break; } - ___flush_cache_all = _flush_cache_all; - _flush_icache_page = r4k_flush_icache_page_s; - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; - _dma_cache_wback = r4k_dma_cache_wback_inv_sc; - _dma_cache_inv = r4k_dma_cache_inv_sc; } typedef int (*probe_func_t)(unsigned long); +extern int r5k_sc_init(void); +extern int rm7k_sc_init(void); -static inline void __init setup_scache(unsigned int config) +static void __init setup_scache(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); probe_func_t probe_scache_kseg1; int sc_present = 0; - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); + /* + * Do the probing thing on R4000SC and R4400SC processors. Other + * processors don't have a S-cache that would be relevant to the + * Linux memory managment. + */ + switch (c->cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); + sc_present = probe_scache_kseg1(config); + break; - if (!sc_present) { - setup_noscache_funcs(); - return; - } + case CPU_R10000: + case CPU_R12000: + scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16); + c->scache.linesz = 64 << ((config >> 13) & 1); + c->scache.ways = 2; + c->scache.waybit= 0; + sc_present = 1; + break; - switch(mips_cpu.cputype) { case CPU_R5000: case CPU_NEVADA: - setup_noscache_funcs(); -#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA) - r5k_sc_init(); + setup_noscache_funcs(); +#ifdef CONFIG_R5000_CPU_SCACHE + r5k_sc_init(); #endif - break; + return; + + case CPU_RM7000: + setup_noscache_funcs(); +#ifdef CONFIG_RM7000_CPU_SCACHE + rm7k_sc_init(); +#endif + return; + default: - setup_scache_funcs(); + sc_present = 0; + } + + if (!sc_present) { + setup_noscache_funcs(); + return; } + if ((c->isa_level == MIPS_CPU_ISA_M32 || + c->isa_level == MIPS_CPU_ISA_M64) && + !(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) + panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); + + /* compute a couple of other cache variables */ + c->scache.waysize = scache_size / c->scache.ways; + + c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); + printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + c->options |= MIPS_CPU_SUBSET_CACHES; + setup_scache_funcs(); } -void __init ld_mmu_r4xx0(void) +static inline void coherency_setup(void) { - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT); + /* + * c0_status.cu=0 specifies that updates by the sc instruction use + * the coherency mode specified by the TLB; 1 means cachable + * coherent update on write will be used. Not all processors have + * this bit and; some wire it to zero, others like Toshiba had the + * silly idea of putting something else there ... + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + clear_c0_config(CONF_CU); + break; + } - probe_icache(config); - probe_dcache(config); - setup_scache(config); +} - switch(mips_cpu.cputype) { - case CPU_R4600: /* QED style two way caches? */ - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - _flush_cache_page = r4k_flush_cache_page_d32i32_r4600; - } +void __init ld_mmu_r4xx0(void) +{ + extern char except_vec2_generic; + struct cpuinfo_mips *c = ¤t_cpu_data; - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - _flush_icache_range = r4k_flush_icache_range; /* Ouch */ - if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) { - _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp; - } + /* Default cache error handler for R4000 and R5000 family */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80); + + probe_pcache(); + setup_scache(); + coherency_setup(); + + if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + /* + * Some MIPS32 and MIPS64 processors have physically indexed caches. + * This code supports virtually indexed processors and will be + * unnecessarily inefficient on physically indexed processors. + */ + shm_align_mask = max_t( unsigned long, + c->dcache.sets * c->dcache.linesz - 1, + PAGE_SIZE - 1); + + _flush_cache_all = r4k_flush_cache_all; + ___flush_cache_all = r4k___flush_cache_all; + _flush_cache_mm = r4k_flush_cache_mm; + _flush_cache_page = r4k_flush_cache_page; + _flush_icache_page = r4k_flush_icache_page; + _flush_cache_range = r4k_flush_cache_range; + + _flush_cache_sigtramp = r4k_flush_cache_sigtramp; + _flush_icache_all = r4k_flush_icache_all; + _flush_data_cache_page = r4k_flush_data_cache_page; + _flush_icache_range = r4k_flush_icache_range; + +#ifdef CONFIG_NONCOHERENT_IO + _dma_cache_wback_inv = r4k_dma_cache_wback_inv; + _dma_cache_wback = r4k_dma_cache_wback_inv; + _dma_cache_inv = r4k_dma_cache_inv; +#endif __flush_cache_all(); } diff -urN linux-2.4.21/arch/mips/mm/c-r5432.c linux-2.4.22/arch/mips/mm/c-r5432.c --- linux-2.4.21/arch/mips/mm/c-r5432.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-r5432.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,480 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * r5432.c: NEC Vr5432 processor. We cannot use r4xx0.c because of - * its unique way-selection method for indexed operations. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Jun Sun (jsun@mvista.com) - * - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -#include -#include - -#undef DEBUG_CACHE - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - - -/* -------------------------------------------------------------------- */ -/* #include */ - -static inline void flush_icache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - "cache %1, 1(%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Invalidate_I)); -} - -static inline void flush_dcache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - "cache %1, 1(%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_D)); -} - -static inline void flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -static inline void flush_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_D)); -} - -static inline void invalidate_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_D)); -} - - -/* - * The next two are for badland addresses like signal trampolines. - */ -static inline void protected_flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -static inline void protected_writeback_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Writeback_D)); -} - - -#define cache32_unroll32(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, 0x000(%0); cache %1, 0x020(%0); \ - cache %1, 0x040(%0); cache %1, 0x060(%0); \ - cache %1, 0x080(%0); cache %1, 0x0a0(%0); \ - cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \ - cache %1, 0x100(%0); cache %1, 0x120(%0); \ - cache %1, 0x140(%0); cache %1, 0x160(%0); \ - cache %1, 0x180(%0); cache %1, 0x1a0(%0); \ - cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \ - cache %1, 0x200(%0); cache %1, 0x220(%0); \ - cache %1, 0x240(%0); cache %1, 0x260(%0); \ - cache %1, 0x280(%0); cache %1, 0x2a0(%0); \ - cache %1, 0x2c0(%0); cache %1, 0x2e0(%0); \ - cache %1, 0x300(%0); cache %1, 0x320(%0); \ - cache %1, 0x340(%0); cache %1, 0x360(%0); \ - cache %1, 0x380(%0); cache %1, 0x3a0(%0); \ - cache %1, 0x3c0(%0); cache %1, 0x3e0(%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -static inline void blast_dcache32(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + dcache_size/2); - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - cache32_unroll32(start+1,Index_Writeback_Inv_D); - start += 0x400; - } -} - -static inline void blast_dcache32_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Hit_Writeback_Inv_D); - start += 0x400; - } -} - -static inline void blast_dcache32_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - cache32_unroll32(start+1,Index_Writeback_Inv_D); - start += 0x400; - } -} - -static inline void blast_icache32(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + icache_size/2); - - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - cache32_unroll32(start+1,Index_Invalidate_I); - start += 0x400; - } -} - -static inline void blast_icache32_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Hit_Invalidate_I); - start += 0x400; - } -} - -static inline void blast_icache32_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - cache32_unroll32(start+1,Index_Invalidate_I); - start += 0x400; - } -} - -/* -------------------------------------------------------------------- */ - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r5432_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); -} - -static void r5432_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache32(); blast_icache32(); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r5432_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r5432_flush_cache_all_d32i32(); - } -} - -static void r5432_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - return; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -} - - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r5432_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void -r5432_flush_icache_range(unsigned long start, unsigned long end) -{ - r5432_flush_cache_all_d32i32(); -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r5432_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - r5432_flush_cache_all_d32i32(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -r5432_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - } - bc_wback_inv(addr, size); -} - -static void -r5432_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - } - - bc_inv(addr, size); -} - -static void -r5432_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("r5432_dma_cache called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r5432_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} - - -void __init ld_mmu_r5432(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - - _clear_page = r5432_clear_page_d32; - _copy_page = r5432_copy_page_d32; - _flush_cache_all = r5432_flush_cache_all_d32i32; - ___flush_cache_all = r5432_flush_cache_all_d32i32; - _flush_page_to_ram = r5432_flush_page_to_ram_d32; - _flush_cache_mm = r5432_flush_cache_mm_d32i32; - _flush_cache_range = r5432_flush_cache_range_d32i32; - _flush_cache_page = r5432_flush_cache_page_d32i32; - _flush_icache_page = r5432_flush_icache_page_i32; - _dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc; - _dma_cache_wback = r5432_dma_cache_wback; - _dma_cache_inv = r5432_dma_cache_inv_pc; - - _flush_cache_sigtramp = r5432_flush_cache_sigtramp; - _flush_icache_range = r5432_flush_icache_range; /* Ouch */ - - __flush_cache_all(); -} diff -urN linux-2.4.21/arch/mips/mm/c-rm7k.c linux-2.4.22/arch/mips/mm/c-rm7k.c --- linux-2.4.21/arch/mips/mm/c-rm7k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-rm7k.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,347 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ - -#define ic_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define dc_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define sc_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define tc_pagesize (32*128) - -/* Secondary cache parameters. */ -#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ - -#include -#include - -int rm7k_tcache_enabled = 0; - -/* - * Not added to asm/r4kcache.h because it seems to be RM7000-specific. - */ -#define Page_Invalidate_T 0x16 - -static inline void invalidate_tcache_page(unsigned long addr) -{ - __asm__ __volatile__( - ".set\tnoreorder\t\t\t# invalidate_tcache_page\n\t" - ".set\tmips3\n\t" - "cache\t%1, (%0)\n\t" - ".set\tmips0\n\t" - ".set\treorder" - : - : "r" (addr), - "i" (Page_Invalidate_T)); -} - -static void __flush_cache_all_d32i32(void) -{ - blast_dcache32(); - blast_icache32(); -} - -static inline void rm7k_flush_cache_all_d32i32(void) -{ - /* Yes! Caches that don't suck ... */ -} - -static void rm7k_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_page_to_ram_d32i32(struct page * page) -{ - /* Yes! Caches that don't suck! */ -} - -static void rm7k_flush_icache_range(unsigned long start, unsigned long end) -{ - /* - * FIXME: This is overdoing things and harms performance. - */ - __flush_cache_all_d32i32(); -} - -static void rm7k_flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ - /* - * FIXME: We should not flush the entire cache but establish some - * temporary mapping and use hit_invalidate operation to flush out - * the line from the cache. - */ - __flush_cache_all_d32i32(); -} - - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * (XXX These need to be fixed ...) - */ -static void -rm7k_dma_cache_wback_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } - - if (!rm7k_tcache_enabled) - return; - - a = addr & ~(tc_pagesize - 1); - end = (addr + size) & ~(tc_pagesize - 1); - while(1) { - invalidate_tcache_page(a); /* Page_Invalidate_T */ - if (a == end) break; - a += tc_pagesize; - } -} - -static void -rm7k_dma_cache_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - invalidate_dcache_line(a); /* Hit_Invalidate_D */ - invalidate_scache_line(a); /* Hit_Invalidate_SD */ - if (a == end) break; - a += sc_lsize; - } - - if (!rm7k_tcache_enabled) - return; - - a = addr & ~(tc_pagesize - 1); - end = (addr + size) & ~(tc_pagesize - 1); - while(1) { - invalidate_tcache_page(a); /* Page_Invalidate_T */ - if (a == end) break; - a += tc_pagesize; - } -} - -static void -rm7k_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("rm7k_dma_cache_wback called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void rm7k_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* Detect and size the caches. */ -static inline void probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - - printk(KERN_INFO "Primary instruction cache %dKiB.\n", icache_size >> 10); -} - -static inline void probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - - printk(KERN_INFO "Primary data cache %dKiB.\n", dcache_size >> 10); -} - - -/* - * This function is executed in the uncached segment KSEG1. - * It must not touch the stack, because the stack pointer still points - * into KSEG0. - * - * Three options: - * - Write it in assembly and guarantee that we don't use the stack. - * - Disable caching for KSEG0 before calling it. - * - Pray that GCC doesn't randomly start using the stack. - * - * This being Linux, we obviously take the least sane of those options - - * following DaveM's lead in r4xx0.c - * - * It seems we get our kicks from relying on unguaranteed behaviour in GCC - */ -static __init void setup_scache(void) -{ - int register i; - - set_cp0_config(1<<3 /* CONF_SE */); - - set_taglo(0); - set_taghi(0); - - for (i=0; i> 31) & 1) - return; - - printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.\n", - (scache_size >> 10), sc_lsize); - - if ((config >> 3) & 1) - return; - - printk(KERN_INFO "Enabling secondary cache..."); - func(); - printk("Done\n"); -} - -static inline void probe_tcache(unsigned long config) -{ - if ((config >> 17) & 1) - return; - - /* We can't enable the L3 cache yet. There may be board-specific - * magic necessary to turn it on, and blindly asking the CPU to - * start using it would may give cache errors. - * - * Also, board-specific knowledge may allow us to use the - * CACHE Flash_Invalidate_T instruction if the tag RAM supports - * it, and may specify the size of the L3 cache so we don't have - * to probe it. - */ - printk(KERN_INFO "Tertiary cache present, %s enabled\n", - config&(1<<12) ? "already" : "not (yet)"); - - if ((config >> 12) & 1) - rm7k_tcache_enabled = 1; -} - -void __init ld_mmu_rm7k(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - unsigned long addr; - - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - - /* RM7000 erratum #31. The icache is screwed at startup. */ - set_taglo(0); - set_taghi(0); - for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { - __asm__ __volatile__ ( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache\t%1, 0(%0)\n\t" - "cache\t%1, 0x1000(%0)\n\t" - "cache\t%1, 0x2000(%0)\n\t" - "cache\t%1, 0x3000(%0)\n\t" - "cache\t%2, 0(%0)\n\t" - "cache\t%2, 0x1000(%0)\n\t" - "cache\t%2, 0x2000(%0)\n\t" - "cache\t%2, 0x3000(%0)\n\t" - "cache\t%1, 0(%0)\n\t" - "cache\t%1, 0x1000(%0)\n\t" - "cache\t%1, 0x2000(%0)\n\t" - "cache\t%1, 0x3000(%0)\n\t" - ".set\tmips0\n\t" - ".set\treorder\n\t" - : - : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); - } - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - probe_scache(config); - probe_tcache(config); - - _clear_page = rm7k_clear_page; - _copy_page = rm7k_copy_page; - - _flush_cache_all = rm7k_flush_cache_all_d32i32; - ___flush_cache_all = __flush_cache_all_d32i32; - _flush_cache_mm = rm7k_flush_cache_mm_d32i32; - _flush_cache_range = rm7k_flush_cache_range_d32i32; - _flush_cache_page = rm7k_flush_cache_page_d32i32; - _flush_page_to_ram = rm7k_flush_page_to_ram_d32i32; - _flush_cache_sigtramp = rm7k_flush_cache_sigtramp; - _flush_icache_range = rm7k_flush_icache_range; - _flush_icache_page = rm7k_flush_icache_page; - - _dma_cache_wback_inv = rm7k_dma_cache_wback_inv; - _dma_cache_wback = rm7k_dma_cache_wback; - _dma_cache_inv = rm7k_dma_cache_inv; - - __flush_cache_all_d32i32(); -} diff -urN linux-2.4.21/arch/mips/mm/c-sb1.c linux-2.4.22/arch/mips/mm/c-sb1.c --- linux-2.4.21/arch/mips/mm/c-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,21 +25,34 @@ #include #include +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +extern void sb1_dma_init(void); +extern void sb1_clear_page_dma(void * page); +extern void sb1_copy_page_dma(void * to, void * from); +#else +extern void sb1_clear_page(void * page); +extern void sb1_copy_page(void * to, void * from); +#endif + /* These are probed at ld_mmu time */ -static unsigned int icache_size; -static unsigned int dcache_size; +static unsigned long icache_size; +static unsigned long dcache_size; -static unsigned int icache_line_size; -static unsigned int dcache_line_size; +static unsigned long icache_line_size; +static unsigned long dcache_line_size; static unsigned int icache_index_mask; +static unsigned int dcache_index_mask; -static unsigned int icache_assoc; -static unsigned int dcache_assoc; +static unsigned long icache_assoc; +static unsigned long dcache_assoc; static unsigned int icache_sets; static unsigned int dcache_sets; +static unsigned int icache_range_cutoff; +static unsigned int dcache_range_cutoff; + void pgd_init(unsigned long page) { unsigned long *p = (unsigned long *) page; @@ -70,59 +83,223 @@ * to flush it */ -static void sb1_flush_cache_all(void) -{ -} - -static void local_sb1___flush_cache_all(void) +/* + * Writeback and invalidate the entire dcache + */ +static inline void __sb1_writeback_inv_dcache_all(void) { - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* WB/Invalidate this index */ + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ " addiu %1, %1, -1 \n" /* Decrement loop count */ " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address */ + " addu $1, $1, %0 \n" /* Next address */ ".set pop \n" : - : "r" (dcache_line_size), "r" (dcache_sets * dcache_assoc), - "r" (KSEG0), "i" (Index_Writeback_Inv_D)); + : "r" (dcache_line_size), "r" (dcache_sets), + "i" (Index_Writeback_Inv_D)); +} +/* + * Writeback and invalidate a range of the dcache. The addresses are + * virtual, and since we're using index ops and bit 12 is part of both + * the virtual frame and physical index, we have to clear both sets + * (bit 12 set and cleared). + */ +static inline void __sb1_writeback_inv_dcache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " xori $1, $1, 1<<12 \n" /* flip bit 12 (va/pa alias) */ + " cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. With physical + * addresseses, we don't have to worry about possible bit 12 aliasing. + * XXXKW is it worth turning on KX and using hit ops with xkphys? + */ +static inline void __sb1_writeback_inv_dcache_phys_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + + +/* + * Invalidate the entire icache + */ +static inline void __sb1_flush_icache_all(void) +{ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " addiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " addu $1, $1, %0 \n" /* Next address */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (icache_line_size), "r" (icache_sets), + "i" (Index_Invalidate_I)); +} + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr) +{ + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + + /* + * Bumping the ASID is probably cheaper than the flush ... + */ + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); +} + +#ifdef CONFIG_SMP +struct flush_cache_page_args { + struct vm_area_struct *vma; + unsigned long addr; +}; + +static void sb1_flush_cache_page_ipi(void *info) +{ + struct flush_cache_page_args *args = info; + + local_sb1_flush_cache_page(args->vma, args->addr); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +{ + struct flush_cache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.addr = addr; + smp_call_function(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_cache_page(vma, addr); +} +#else +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +asm("sb1_flush_cache_page = local_sb1_flush_cache_page"); #endif - ".set pop \n"); +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " addiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address */ + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" ".set pop \n" : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); + : "r" (start & ~(icache_line_size - 1)), + "r" ((end + icache_line_size - 1) & ~(icache_line_size - 1)), + "r" (icache_line_size), + "r" (icache_index_mask), + "i" (Index_Invalidate_I)); +} + + +/* + * Invalidate all caches on this CPU + */ +static void local_sb1___flush_cache_all(void) +{ + __sb1_writeback_inv_dcache_all(); + __sb1_flush_icache_all(); } #ifdef CONFIG_SMP @@ -139,80 +316,28 @@ asm("sb1___flush_cache_all = local_sb1___flush_cache_all"); #endif - /* * When flushing a range in the icache, we have to first writeback * the dcache for the same range, so new ifetches will see any * data that was dirty in the dcache. * - * The start/end arguments are expected to be Kseg addresses. + * The start/end arguments are Kseg addresses (possibly mapped Kseg). */ -static void local_sb1_flush_icache_range(unsigned long start, unsigned long end) +static void local_sb1_flush_icache_range(unsigned long start, + unsigned long end) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - unsigned long flags; - local_irq_save(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - "1: \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - ".align 3 \n" - " lw $0, 0($1) \n" /* Bug 1370, 1368 */ - " sync \n" -#endif - " cache %3, 0($1) \n" /* Hit-WB{,-inval} this address */ - " bne $1, %1, 1b \n" /* loop test */ - " addu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" (start & ~(dcache_line_size - 1)), - "r" ((end - 1) & ~(dcache_line_size - 1)), - "r" (dcache_line_size), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) -#else - "i" (Hit_Writeback_D) -#endif - ); - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" -#endif - ".set pop \n"); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - ".align 3 \n" - "1: cache %3, (0<<13)($1) \n" /* Index-inval this address */ - " cache %3, (1<<13)($1) \n" /* Index-inval this address */ - " cache %3, (2<<13)($1) \n" /* Index-inval this address */ - " cache %3, (3<<13)($1) \n" /* Index-inval this address */ - " bne $1, %1, 1b \n" /* loop test */ - " addu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" (start & ~(icache_line_size - 1)), - "r" ((end - 1) & ~(icache_line_size - 1)), - "r" (icache_line_size), - "i" (Index_Invalidate_I)); + /* Just wb-inv the whole dcache if the range is big enough */ + if ((end - start) > dcache_range_cutoff) + __sb1_writeback_inv_dcache_all(); + else + __sb1_writeback_inv_dcache_range(start, end); + + /* Just flush the whole icache if the range is big enough */ + if ((end - start) > icache_range_cutoff) + __sb1_flush_icache_all(); + else + __sb1_flush_icache_range(start, end); } #ifdef CONFIG_SMP @@ -243,186 +368,123 @@ #endif /* - * If there's no context yet, or the page isn't executable, no icache flush - * is needed + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. */ -static void sb1_flush_icache_page(struct vm_area_struct *vma, +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) { + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP if (!(vma->vm_flags & VM_EXEC)) return; +#endif + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); /* - * We're not sure of the virtual address(es) involved here, so - * conservatively flush the entire caches on all processors - * (ouch). + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) */ - sb1___flush_cache_all(); + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } } -static inline void protected_flush_icache_line(unsigned long addr) +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) { - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - "1: cache %1, (%0) \n" - "2: .set pop \n" - " .section __ex_table,\"a\"\n" - " .word 1b, 2b \n" - " .previous" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); } -static inline void protected_writeback_dcache_line(unsigned long addr) +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - /* Have to be sure the TLB entry exists for the cache op, - so we have to be sure that nothing happens in between the - lw and the cache op - */ - unsigned long flags; - local_irq_save(flags); -#endif - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - "1: \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - " lw $0, (%0) \n" - " sync \n" -#endif - " cache %1, 0(%0) \n" /* Hit-WB{-inval} this address */ - /* XXX: should be able to do this after both dcache cache - ops, but there's no guarantee that this will be inlined, - and the pass1 restriction checker can't detect syncs - following cache ops except in the following basic block. - */ - " sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - " sync \n" -#endif - "2: .set pop \n" - " .section __ex_table,\"a\"\n" - " .word 1b, 2b \n" - " .previous" - : - : "r" (addr), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + smp_call_function(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_icache_page(vma, page); +} #else - "i" (Hit_Writeback_D) -#endif - ); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page); +asm("sb1_flush_icache_page = local_sb1_flush_icache_page"); #endif -} /* * A signal trampoline must fit into a single cacheline. */ static void local_sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long daddr, iaddr; - - daddr = addr & ~(dcache_line_size - 1); - protected_writeback_dcache_line(daddr); - iaddr = addr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " cache %2, (0<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (1<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (2<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (3<<13)(%0) \n" /* Index-inval this address */ + " xori $1, %0, 1<<12 \n" /* Flip index bit 12 */ + " cache %2, (0<<13)($1) \n" /* Index-inval this address */ + " cache %2, (1<<13)($1) \n" /* Index-inval this address */ + " cache %2, (2<<13)($1) \n" /* Index-inval this address */ + " cache %2, (3<<13)($1) \n" /* Index-inval this address */ + " cache %3, (0<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (1<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (2<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (3<<13)(%1) \n" /* Index-inval this address */ + " bnezl $0, 1f \n" /* Force mispredict */ + " nop \n" + "1: \n" + " .set pop \n" + : + : "r" (addr & dcache_index_mask), "r" (addr & icache_index_mask), + "i" (Index_Writeback_Inv_D), "i" (Index_Invalidate_I)); } #ifdef CONFIG_SMP - static void sb1_flush_cache_sigtramp_ipi(void *info) { unsigned long iaddr = (unsigned long) info; - - iaddr = iaddr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + local_sb1_flush_cache_sigtramp(iaddr); } static void sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long tmp; - - /* - * Flush the local dcache, then load the instruction back into a - * register. That will make sure that any remote CPU also has - * written back it's data cache to memory. - */ local_sb1_flush_cache_sigtramp(addr); - __get_user(tmp, (unsigned long *)addr); - smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); } - #else void sb1_flush_cache_sigtramp(unsigned long addr); asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp"); #endif -static void sb1_flush_icache_all(void) -{ - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " addiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address */ - ".set pop \n" - : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); -} /* * Anything that just flushes dcache state can be ignored, as we're always * coherent in dcache space. This is just a dummy function that all the * nop'ed routines point to */ - static void sb1_nop(void) { } /* - * This only needs to make sure stores done up to this - * point are visible to other agents outside the CPU. Given - * the coherent nature of the ZBbus, all that's required here is - * a sync to make sure the data gets out to the caches and is - * visible to an arbitrary A Phase from an external agent - * - * Actually, I'm not even sure that's necessary; the semantics - * of this function aren't clear. If it's supposed to serve as - * a memory barrier, this is needed. If it's only meant to - * prevent data from being invisible to non-cpu memory accessors - * for some indefinite period of time (e.g. in a non-coherent - * dcache) then this function would be a complete nop. - */ -static void sb1_flush_page_to_ram(struct page *page) -{ - __asm__ __volatile__( - " sync \n" /* Short pipe */ - :::"memory"); -} - -/* * Cache set values (from the mips64 spec) * 0 - 64 * 1 - 128 @@ -481,7 +543,7 @@ { u32 config1; - config1 = read_mips32_cp0_config1(); + config1 = read_c0_config1(); icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7); dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7); icache_sets = decode_cache_sets((config1 >> 22) & 0x7); @@ -490,7 +552,17 @@ dcache_assoc = ((config1 >> 7) & 0x7) + 1; icache_size = icache_line_size * icache_sets * icache_assoc; dcache_size = dcache_line_size * dcache_sets * dcache_assoc; + /* Need to remove non-index bits for index ops */ icache_index_mask = (icache_sets - 1) * icache_line_size; + dcache_index_mask = (dcache_sets - 1) * dcache_line_size; + /* + * These are for choosing range (index ops) versus all. + * icache flushes all ways for each set, so drop icache_assoc. + * dcache flushes all ways and each setting of bit 12 for each + * index, so drop dcache_assoc and halve the dcache_sets. + */ + icache_range_cutoff = icache_sets * icache_line_size; + dcache_range_cutoff = (dcache_sets / 2) * icache_line_size; } /* @@ -500,25 +572,57 @@ */ void ld_mmu_sb1(void) { + extern char except_vec2_sb1; + unsigned long temp; + + /* Special cache error handler for SB1 */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + probe_cache_sizes(); +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + _clear_page = sb1_clear_page_dma; + _copy_page = sb1_copy_page_dma; + sb1_dma_init(); +#else _clear_page = sb1_clear_page; _copy_page = sb1_copy_page; +#endif - _flush_cache_all = sb1_flush_cache_all; - ___flush_cache_all = sb1___flush_cache_all; - _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + /* + * None of these are needed for the SB1 - the Dcache is + * physically indexed and tagged, so no virtual aliasing can + * occur + */ _flush_cache_range = (void *) sb1_nop; - _flush_page_to_ram = sb1_flush_page_to_ram; - _flush_icache_page = sb1_flush_icache_page; - _flush_icache_range = sb1_flush_icache_range; + _flush_cache_page = sb1_flush_cache_page; + _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + _flush_cache_all = sb1_nop; - /* None of these are needed for the sb1 */ - _flush_cache_page = (void *) sb1_nop; + /* These routines are for Icache coherence with the Dcache */ + _flush_icache_range = sb1_flush_icache_range; + _flush_icache_page = sb1_flush_icache_page; + _flush_icache_all = __sb1_flush_icache_all; /* local only */ _flush_cache_sigtramp = sb1_flush_cache_sigtramp; - _flush_icache_all = sb1_flush_icache_all; + _flush_data_cache_page = (void *) sb1_nop; - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* Full flush */ + ___flush_cache_all = sb1___flush_cache_all; + + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* + * This is the only way to force the update of K0 to complete + * before subsequent instruction fetch. + */ + __asm__ __volatile__ ( + " .set push \n" + " .set mips4 \n" + " la %0, 1f \n" + " mtc0 %0, $14 \n" + " eret \n" + "1: .set pop \n" + : "=r" (temp)); flush_cache_all(); } diff -urN linux-2.4.21/arch/mips/mm/c-tx39.c linux-2.4.22/arch/mips/mm/c-tx39.c --- linux-2.4.21/arch/mips/mm/c-tx39.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-tx39.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,18 +25,24 @@ /* For R3000 cores with R4000 style caches */ static unsigned long icache_size, dcache_size; /* Size in bytes */ -extern long scache_size; - -#define icache_lsize mips_cpu.icache.linesz -#define dcache_lsize mips_cpu.dcache.linesz #include +extern void r3k_clear_page(void * page); +extern void r3k_copy_page(void * to, void * from); + extern int r3k_have_wired_reg; /* in r3k-tlb.c */ -static void tx39h_flush_page_to_ram(struct page * page) -{ -} +/* This sequence is required to ensure icache is disabled immediately */ +#define TX39_STOP_STREAMING() \ +__asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "b 1f\n\t" \ + "nop\n\t" \ + "1:\n\t" \ + ".set pop" \ + ) /* TX39H-style cache flush routines. */ static void tx39h_flush_icache_all(void) @@ -46,8 +52,10 @@ unsigned long flags, config; /* disable icache (set ICE#) */ - __save_and_cli(flags); - config = read_32bit_cp0_register(CP0_CONF); + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); /* invalidate icache */ while (start < end) { @@ -55,46 +63,103 @@ start += 0x200; } - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + write_c0_conf(config); + local_irq_restore(flags); } static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end, a; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; iob(); - a = addr & ~(dcache_lsize - 1); - end = (addr + size) & ~(dcache_lsize - 1); + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { invalidate_dcache_line(a); /* Hit_Invalidate_D */ if (a == end) break; - a += dcache_lsize; + a += dc_lsize; } } /* TX39H2,TX39H3 */ -static inline void tx39_flush_cache_all(void) +static inline void tx39_blast_dcache_page(unsigned long addr) +{ + if (current_cpu_data.cputype != CPU_TX3912) + blast_dcache16_page(addr); +} + +static inline void tx39_blast_dcache_page_indexed(unsigned long addr) +{ + blast_dcache16_page_indexed(addr); +} + +static inline void tx39_blast_dcache(void) +{ + blast_dcache16(); +} + +static inline void tx39_blast_icache_page(unsigned long addr) +{ + unsigned long flags, config; + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16_page(addr); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_blast_icache_page_indexed(unsigned long addr) { unsigned long flags, config; + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16_page_indexed(addr); + write_c0_conf(config); + local_irq_restore(flags); +} - __save_and_cli(flags); - blast_dcache16_wayLSB(); +static inline void tx39_blast_icache(void) +{ + unsigned long flags, config; /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE); - blast_icache16_wayLSB(); - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16(); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) + return; + + tx39_blast_dcache(); + tx39_blast_icache(); +} + +static inline void tx39___flush_cache_all(void) +{ + tx39_blast_dcache(); + tx39_blast_icache(); } static void tx39_flush_cache_mm(struct mm_struct *mm) { - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif + if (!cpu_has_dc_aliases) + return; + + if (cpu_context(smp_processor_id(), mm) != 0) { tx39_flush_cache_all(); } } @@ -103,28 +168,20 @@ unsigned long start, unsigned long end) { - if(mm->context != 0) { - unsigned long flags, config; + if (!cpu_has_dc_aliases) + return; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache16_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE); - blast_icache16_wayLSB(); - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + if (cpu_context(smp_processor_id(), mm) != 0) { + tx39_blast_dcache(); + tx39_blast_icache(); } } static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page) { + int exec = vma->vm_flags & VM_EXEC; struct mm_struct *mm = vma->vm_mm; - unsigned long flags; pgd_t *pgdp; pmd_t *pmdp; pte_t *ptep; @@ -133,13 +190,9 @@ * If ownes no valid ASID yet, cannot possibly have gotten * this page into the cache. */ - if(mm->context == 0) + if (cpu_context(smp_processor_id(), mm) == 0) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); page &= PAGE_MASK; pgdp = pgd_offset(mm, page); pmdp = pmd_offset(pgdp, page); @@ -149,8 +202,8 @@ * If the page isn't marked valid, the page cannot possibly be * in the cache. */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; /* * Doing flushes for another ASID than the current one is @@ -158,51 +211,121 @@ * for every cache flush operation. So we do indexed flushes * in that case, which doesn't overly flush the cache too much. */ - if((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache16_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed_wayLSB(page); + if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { + if (cpu_has_dc_aliases || exec) + tx39_blast_dcache_page(page); + if (exec) + tx39_blast_icache_page(page); + + return; } -out: - __restore_flags(flags); + + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || exec) + tx39_blast_dcache_page_indexed(page); + if (exec) + tx39_blast_icache_page_indexed(page); } -static void tx39_flush_page_to_ram(struct page * page) +static void tx39_flush_data_cache_page(unsigned long addr) { - blast_dcache16_page((unsigned long)page_address(page)); + tx39_blast_dcache_page(addr); } static void tx39_flush_icache_range(unsigned long start, unsigned long end) { - flush_cache_all(); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + + if (end - start > dcache_size) + tx39_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + + if (end - start > icache_size) + tx39_blast_icache(); + else { + unsigned long flags, config; + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + write_c0_conf(config); + local_irq_restore(flags); + } } +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page) { + unsigned long addr; + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ if (!(vma->vm_flags & VM_EXEC)) return; - flush_cache_all(); + addr = (unsigned long) page_address(page); + tx39_blast_dcache_page(addr); + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + tx39_blast_icache(); } static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end, a; - if (size >= dcache_size) { - flush_cache_all(); + if (((size | addr) & (PAGE_SIZE - 1)) == 0) { + end = addr + size; + do { + tx39_blast_dcache_page(addr); + addr += PAGE_SIZE; + } while(addr != end); + } else if (size > dcache_size) { + tx39_blast_dcache(); } else { - a = addr & ~(dcache_lsize - 1); - end = (addr + size) & ~(dcache_lsize - 1); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { flush_dcache_line(a); /* Hit_Writeback_Inv_D */ if (a == end) break; - a += dcache_lsize; + a += dc_lsize; } } } @@ -211,59 +334,75 @@ { unsigned long end, a; - if (size >= dcache_size) { - flush_cache_all(); + if (((size | addr) & (PAGE_SIZE - 1)) == 0) { + end = addr + size; + do { + tx39_blast_dcache_page(addr); + addr += PAGE_SIZE; + } while(addr != end); + } else if (size > dcache_size) { + tx39_blast_dcache(); } else { - a = addr & ~(dcache_lsize - 1); - end = (addr + size) & ~(dcache_lsize - 1); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { invalidate_dcache_line(a); /* Hit_Invalidate_D */ if (a == end) break; - a += dcache_lsize; + a += dc_lsize; } } } -static void tx39_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("tx39_dma_cache called - should not happen."); -} - static void tx39_flush_cache_sigtramp(unsigned long addr) { + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; unsigned long config; - unsigned int flags; + unsigned long flags; - __save_and_cli(flags); - protected_writeback_dcache_line(addr & ~(dcache_lsize - 1)); + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE); - protected_flush_icache_line(addr & ~(icache_lsize - 1)); - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); + write_c0_conf(config); + local_irq_restore(flags); } static __init void tx39_probe_cache(void) { unsigned long config; - config = read_32bit_cp0_register(CP0_CONF); + config = read_c0_conf(); - icache_size = 1 << (10 + ((config >> 19) & 3)); - dcache_size = 1 << (10 + ((config >> 16) & 3)); + icache_size = 1 << (10 + ((config & TX39_CONF_ICS_MASK) >> + TX39_CONF_ICS_SHIFT)); + dcache_size = 1 << (10 + ((config & TX39_CONF_DCS_MASK) >> + TX39_CONF_DCS_SHIFT)); - icache_lsize = 16; - switch (mips_cpu.cputype) { + current_cpu_data.icache.linesz = 16; + switch (current_cpu_data.cputype) { case CPU_TX3912: - dcache_lsize = 4; + current_cpu_data.icache.ways = 1; + current_cpu_data.dcache.ways = 1; + current_cpu_data.dcache.linesz = 4; break; - case CPU_TX3922: + case CPU_TX3927: - case CPU_TX39XX: + current_cpu_data.icache.ways = 2; + current_cpu_data.dcache.ways = 2; + current_cpu_data.dcache.linesz = 16; + break; + + case CPU_TX3922: default: - dcache_lsize = 16; + current_cpu_data.icache.ways = 1; + current_cpu_data.dcache.ways = 1; + current_cpu_data.dcache.linesz = 16; break; } } @@ -275,13 +414,13 @@ _clear_page = r3k_clear_page; _copy_page = r3k_copy_page; - config = read_32bit_cp0_register(CP0_CONF); + config = read_c0_conf(); config &= ~TX39_CONF_WBON; - write_32bit_cp0_register(CP0_CONF, config); + write_c0_conf(config); tx39_probe_cache(); - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_TX3912: /* TX39/H core (writethru direct-map cache) */ _flush_cache_all = tx39h_flush_icache_all; @@ -289,12 +428,16 @@ _flush_cache_mm = (void *) tx39h_flush_icache_all; _flush_cache_range = (void *) tx39h_flush_icache_all; _flush_cache_page = (void *) tx39h_flush_icache_all; - _flush_cache_sigtramp = (void *) tx39h_flush_icache_all; - _flush_page_to_ram = tx39h_flush_page_to_ram; _flush_icache_page = (void *) tx39h_flush_icache_all; _flush_icache_range = (void *) tx39h_flush_icache_all; - _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; + _flush_cache_sigtramp = (void *) tx39h_flush_icache_all; + _flush_data_cache_page = (void *) tx39h_flush_icache_all; + + _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; + + shm_align_mask = PAGE_SIZE - 1; + break; case CPU_TX3922: @@ -302,37 +445,47 @@ default: /* TX39/H2,H3 core (writeback 2way-set-associative cache) */ r3k_have_wired_reg = 1; - set_wired (0); /* set 8 on reset... */ + write_c0_wired(0); /* set 8 on reset... */ /* board-dependent init code may set WBON */ _flush_cache_all = tx39_flush_cache_all; - ___flush_cache_all = tx39_flush_cache_all; + ___flush_cache_all = tx39___flush_cache_all; _flush_cache_mm = tx39_flush_cache_mm; _flush_cache_range = tx39_flush_cache_range; _flush_cache_page = tx39_flush_cache_page; - _flush_cache_sigtramp = tx39_flush_cache_sigtramp; - _flush_page_to_ram = tx39_flush_page_to_ram; _flush_icache_page = tx39_flush_icache_page; _flush_icache_range = tx39_flush_icache_range; + _flush_cache_sigtramp = tx39_flush_cache_sigtramp; + _flush_data_cache_page = tx39_flush_data_cache_page; + _dma_cache_wback_inv = tx39_dma_cache_wback_inv; - _dma_cache_wback = tx39_dma_cache_wback; + _dma_cache_wback = tx39_dma_cache_wback_inv; _dma_cache_inv = tx39_dma_cache_inv; + shm_align_mask = max_t(unsigned long, + (dcache_size / current_cpu_data.dcache.ways) - 1, + PAGE_SIZE - 1); + break; } - if (mips_cpu.icache.ways == 0) - mips_cpu.icache.ways = 1; - if (mips_cpu.dcache.ways == 0) - mips_cpu.dcache.ways = 1; - mips_cpu.icache.sets = - icache_size / mips_cpu.icache.ways / mips_cpu.icache.linesz; - mips_cpu.dcache.sets = - dcache_size / mips_cpu.dcache.ways / mips_cpu.dcache.linesz; - - printk("Primary instruction cache %dkb, linesize %d bytes\n", - (int) (icache_size >> 10), (int) icache_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - (int) (dcache_size >> 10), (int) dcache_lsize); + current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways; + current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways; + + current_cpu_data.icache.sets = + current_cpu_data.icache.waysize / current_cpu_data.icache.linesz; + current_cpu_data.dcache.sets = + current_cpu_data.dcache.waysize / current_cpu_data.dcache.linesz; + + if (current_cpu_data.dcache.waysize > PAGE_SIZE) + current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES; + + current_cpu_data.icache.waybit = 0; + current_cpu_data.dcache.waybit = 0; + + printk("Primary instruction cache %ldkb, linesize %d bytes\n", + icache_size >> 10, current_cpu_data.icache.linesz); + printk("Primary data cache %ldkb, linesize %d bytes\n", + dcache_size >> 10, current_cpu_data.dcache.linesz); } diff -urN linux-2.4.21/arch/mips/mm/c-tx49.c linux-2.4.22/arch/mips/mm/c-tx49.c --- linux-2.4.21/arch/mips/mm/c-tx49.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/c-tx49.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,435 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * r49xx.c: TX49 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - * - * Modified for R4300/TX49xx (Jun/2001) - * Copyright (C) 1999-2001 Toshiba Corporation - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -#define ic_lsize mips_cpu.icache.linesz -#define dc_lsize mips_cpu.dcache.linesz -static unsigned long scache_size; - -#include -#include - -#undef DEBUG_CACHE - -/* TX49 does can not flush the line contains the CACHE insn itself... */ -/* r4k_xxx routines are completely same as those in r4xx0.c */ - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r49_flush_cache_all_d16i32(void) -{ - unsigned long flags, config; - - __save_and_cli(flags); - blast_dcache16_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); -} - -static inline void r49_flush_cache_all_d32i32(void) -{ - unsigned long flags, config; - - __save_and_cli(flags); - blast_dcache32_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); -} - -static void r49_flush_cache_range_d16i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { - unsigned long flags, config; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache16_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); - } -} - -static void r49_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { - unsigned long flags, config; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache32_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r49_flush_cache_mm_d16i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r49_flush_cache_all_d16i32(); - } -} - -static void r49_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r49_flush_cache_all_d32i32(); - } -} - -static void r49_flush_cache_page_d16i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache16_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed_wayLSB(page); - } -out: - __restore_flags(flags); -} - -static void r49_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed_wayLSB(page); - } -out: - __restore_flags(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - blast_dcache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void -r4k_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r4k_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - flush_cache_all(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } -} - -static void -r4k_dma_cache_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } -} - -static void -r4k_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("r4k_dma_cache called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r4k_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} - -int mips_configk0 = -1; /* board-specific setup routine can override this */ -void __init ld_mmu_tx49(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - if (mips_configk0 != -1) - change_cp0_config(CONF_CM_CMASK, mips_configk0); - else - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - if (mips_cpu.icache.ways == 0) - mips_cpu.icache.ways = 1; - if (mips_cpu.dcache.ways == 0) - mips_cpu.dcache.ways = 1; - mips_cpu.icache.sets = - icache_size / mips_cpu.icache.ways / mips_cpu.icache.linesz; - mips_cpu.dcache.sets = - dcache_size / mips_cpu.dcache.ways / mips_cpu.dcache.linesz; - - switch(dc_lsize) { - case 16: - _clear_page = r4k_clear_page_d16; - _copy_page = r4k_copy_page_d16; - _flush_page_to_ram = r4k_flush_page_to_ram_d16; - _flush_cache_all = r49_flush_cache_all_d16i32; - _flush_cache_mm = r49_flush_cache_mm_d16i32; - _flush_cache_range = r49_flush_cache_range_d16i32; - _flush_cache_page = r49_flush_cache_page_d16i32; - break; - case 32: - _clear_page = r4k_clear_page_d32; - _copy_page = r4k_copy_page_d32; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; - _flush_cache_all = r49_flush_cache_all_d32i32; - _flush_cache_mm = r49_flush_cache_mm_d32i32; - _flush_cache_range = r49_flush_cache_range_d32i32; - _flush_cache_page = r49_flush_cache_page_d32i32; - break; - } - ___flush_cache_all = _flush_cache_all; - - _flush_icache_page = r4k_flush_icache_page; - - _dma_cache_wback_inv = r4k_dma_cache_wback_inv; - _dma_cache_wback = r4k_dma_cache_wback; - _dma_cache_inv = r4k_dma_cache_inv; - - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - _flush_icache_range = r4k_flush_icache_range; /* Ouch */ - - __flush_cache_all(); -} diff -urN linux-2.4.21/arch/mips/mm/cache.c linux-2.4.22/arch/mips/mm/cache.c --- linux-2.4.21/arch/mips/mm/cache.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/cache.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,67 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 2003 by Ralf Baechle + */ +#include +#include +#include +#include + +#include + +asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) +{ + /* This should flush more selectivly ... */ + __flush_cache_all(); + + return 0; +} + +void flush_dcache_page(struct page *page) +{ + unsigned long addr; + + if (!cpu_has_dc_aliases) + return; + + if (page->mapping && page->mapping->i_mmap == NULL && + page->mapping->i_mmap_shared == NULL) { + SetPageDcacheDirty(page); + + return; + } + + /* + * We could delay the flush for the !page->mapping case too. But that + * case is for exec env/arg pages and those are 99% certainly going to + * get faulted into the tlb (and thus flushed) anyways. + */ + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); +} + +void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + unsigned long addr; + struct page *page; + + if (!cpu_has_dc_aliases) + return; + + page = pte_page(pte); + if (VALID_PAGE(page) && page->mapping && + (page->flags & (1UL << PG_dcache_dirty))) { + if (pages_do_alias((unsigned long) page_address(page), address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); + } + + ClearPageDcacheDirty(page); + } +} + +EXPORT_SYMBOL(flush_dcache_page); diff -urN linux-2.4.21/arch/mips/mm/cerr-sb1.c linux-2.4.22/arch/mips/mm/cerr-sb1.c --- linux-2.4.21/arch/mips/mm/cerr-sb1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/cerr-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#ifndef CONFIG_SIBYTE_BUS_WATCHER +#include +#include +#include +#include +#endif + +/* SB1 definitions */ + +/* XXX should come from config1 XXX */ +#define SB1_CACHE_INDEX_MASK 0x1fe0 + +#define CP0_ERRCTL_RECOVERABLE (1 << 31) +#define CP0_ERRCTL_DCACHE (1 << 30) +#define CP0_ERRCTL_ICACHE (1 << 29) +#define CP0_ERRCTL_MULTIBUS (1 << 23) +#define CP0_ERRCTL_MC_TLB (1 << 15) +#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) + +#define CP0_CERRI_TAG_PARITY (1 << 29) +#define CP0_CERRI_DATA_PARITY (1 << 28) +#define CP0_CERRI_EXTERNAL (1 << 26) + +#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) +#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) + +#define CP0_CERRD_MULTIPLE (1 << 31) +#define CP0_CERRD_TAG_STATE (1 << 30) +#define CP0_CERRD_TAG_ADDRESS (1 << 29) +#define CP0_CERRD_DATA_SBE (1 << 28) +#define CP0_CERRD_DATA_DBE (1 << 27) +#define CP0_CERRD_EXTERNAL (1 << 26) +#define CP0_CERRD_LOAD (1 << 25) +#define CP0_CERRD_STORE (1 << 24) +#define CP0_CERRD_FILLWB (1 << 23) +#define CP0_CERRD_COHERENCY (1 << 22) +#define CP0_CERRD_DUPTAG (1 << 21) + +#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) +#define CP0_CERRD_IDX_VALID(c) \ + (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) +#define CP0_CERRD_CAUSES \ + (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) +#define CP0_CERRD_TYPES \ + (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) +#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) + +static uint32_t extract_ic(unsigned short addr, int data); +static uint32_t extract_dc(unsigned short addr, int data); + +static inline void breakout_errctl(unsigned int val) +{ + if (val & CP0_ERRCTL_RECOVERABLE) + prom_printf(" recoverable"); + if (val & CP0_ERRCTL_DCACHE) + prom_printf(" dcache"); + if (val & CP0_ERRCTL_ICACHE) + prom_printf(" icache"); + if (val & CP0_ERRCTL_MULTIBUS) + prom_printf(" multiple-buserr"); + prom_printf("\n"); +} + +static inline void breakout_cerri(unsigned int val) +{ + if (val & CP0_CERRI_TAG_PARITY) + prom_printf(" tag-parity"); + if (val & CP0_CERRI_DATA_PARITY) + prom_printf(" data-parity"); + if (val & CP0_CERRI_EXTERNAL) + prom_printf(" external"); + prom_printf("\n"); +} + +static inline void breakout_cerrd(unsigned int val) +{ + switch (val & CP0_CERRD_CAUSES) { + case CP0_CERRD_LOAD: + prom_printf(" load,"); + break; + case CP0_CERRD_STORE: + prom_printf(" store,"); + break; + case CP0_CERRD_FILLWB: + prom_printf(" fill/wb,"); + break; + case CP0_CERRD_COHERENCY: + prom_printf(" coherency,"); + break; + case CP0_CERRD_DUPTAG: + prom_printf(" duptags,"); + break; + default: + prom_printf(" NO CAUSE,"); + break; + } + if (!(val & CP0_CERRD_TYPES)) + prom_printf(" NO TYPE"); + else { + if (val & CP0_CERRD_MULTIPLE) + prom_printf(" multi-err"); + if (val & CP0_CERRD_TAG_STATE) + prom_printf(" tag-state"); + if (val & CP0_CERRD_TAG_ADDRESS) + prom_printf(" tag-address"); + if (val & CP0_CERRD_DATA_SBE) + prom_printf(" data-SBE"); + if (val & CP0_CERRD_DATA_DBE) + prom_printf(" data-DBE"); + if (val & CP0_CERRD_EXTERNAL) + prom_printf(" external"); + } + prom_printf("\n"); +} + +#ifndef CONFIG_SIBYTE_BUS_WATCHER + +static void check_bus_watcher(void) +{ + uint32_t status, l2_err, memio_err; + + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + /* Bit 31 is always on, but there's no #define for that */ + if (status & ~(1UL << 31)) { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + prom_printf("\nLast recorded signature:\n"); + prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); + } else { + prom_printf("Bus watcher indicates no error\n"); + } +} +#else +extern void check_bus_watcher(void); +#endif + +asmlinkage void sb1_cache_error(void) +{ + uint64_t cerr_dpa; + uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; + + prom_printf("Cache error exception on CPU %x:\n", + (read_c0_prid() >> 25) & 0x7); + + __asm__ __volatile__ ( + " .set push\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " mfc0 %0, $26\n\t" + " mfc0 %1, $27\n\t" + " mfc0 %2, $27, 1\n\t" + " dmfc0 $1, $27, 3\n\t" + " dsrl32 %3, $1, 0 \n\t" + " sll %4, $1, 0 \n\t" + " mfc0 %5, $30\n\t" + " .set pop" + : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), + "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); + + cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; + prom_printf(" cp0_errorepc == %08x\n", eepc); + prom_printf(" cp0_errctl == %08x", errctl); + breakout_errctl(errctl); + if (errctl & CP0_ERRCTL_ICACHE) { + prom_printf(" cp0_cerr_i == %08x", cerr_i); + breakout_cerri(cerr_i); + if (CP0_CERRI_IDX_VALID(cerr_i)) { + if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_i idx doesn't match eepc\n"); + else { + res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, + (cerr_i & CP0_CERRI_DATA) != 0); + if (!(res & cerr_i)) + prom_printf("...didn't see indicated icache problem\n"); + } + } + } + if (errctl & CP0_ERRCTL_DCACHE) { + prom_printf(" cp0_cerr_d == %08x", cerr_d); + breakout_cerrd(cerr_d); + if (CP0_CERRD_DPA_VALID(cerr_d)) { + prom_printf(" cp0_cerr_dpa == %010llx\n", cerr_dpa); + if (!CP0_CERRD_IDX_VALID(cerr_d)) { + res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated dcache problem\n"); + } else { + if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); + else { + res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated problem\n"); + } + } + } + } + + check_bus_watcher(); + + while (1); + /* + * This tends to make things get really ugly; let's just stall instead. + * panic("Can't handle the cache error!"); + */ +} + + +/* Parity lookup table. */ +static const uint8_t parity[256] = { + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 +}; + +/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ +static const uint64_t mask_72_64[8] = { + 0x0738C808099264FFL, + 0x38C808099264FF07L, + 0xC808099264FF0738L, + 0x08099264FF0738C8L, + 0x099264FF0738C808L, + 0x9264FF0738C80809L, + 0x64FF0738C8080992L, + 0xFF0738C808099264L +}; + +/* Calculate the parity on a range of bits */ +static char range_parity(uint64_t dword, int max, int min) +{ + char parity = 0; + int i; + dword >>= min; + for (i=max-min; i>=0; i--) { + if (dword & 0x1) + parity = !parity; + dword >>= 1; + } + return parity; +} + +/* Calculate the 4-bit even byte-parity for an instruction */ +static unsigned char inst_parity(uint32_t word) +{ + int i, j; + char parity = 0; + for (j=0; j<4; j++) { + char byte_parity = 0; + for (i=0; i<8; i++) { + if (word & 0x80000000) + byte_parity = !byte_parity; + word <<= 1; + } + parity <<= 1; + parity |= byte_parity; + } + return parity; +} + +static uint32_t extract_ic(unsigned short addr, int data) +{ + unsigned short way; + int valid; + uint64_t taglo, va, tlo_tmp; + uint32_t taghi, taglolo, taglohi; + uint8_t lru; + int res = 0; + + prom_printf("Icache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + /* Index-load-tag-I */ + __asm__ __volatile__ ( + " .set push \n\t" + " .set noreorder \n\t" + " .set mips64 \n\t" + " .set noat \n\t" + " cache 4, 0(%3) \n\t" + " mfc0 %0, $29 \n\t" + " dmfc0 $1, $28 \n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 5) & 0x3), /* bank */ + ((addr >> 7) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + va = (taglo & 0xC0000FFFFFFFE000) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) + va |= 0x3FFFF00000000000; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; + if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { + prom_printf(" ** bad parity in VTag0/G/ASID\n"); + res |= CP0_CERRI_TAG_PARITY; + } + if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { + prom_printf(" ** bad parity in R/VTag1\n"); + res |= CP0_CERRI_TAG_PARITY; + } + } + if (valid ^ ((taghi >> 27) & 1)) { + prom_printf(" ** bad parity for valid bit\n"); + res |= CP0_CERRI_TAG_PARITY; + } + prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", + way, va, valid, taghi, taglo); + + if (data) { + uint32_t datahi, insta, instb; + uint8_t predecode; + int offset; + + /* (hit all banks and ways) */ + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-I */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 6, 0(%3) \n\t" + " mfc0 %0, $29, 1\n\t" + " dmfc0 $1, $28, 1\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop \n" + : "=r" (datahi), "=r" (insta), "=r" (instb) + : "r" ((way << 13) | addr | (offset << 3))); + predecode = (datahi >> 8) & 0xff; + if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { + prom_printf(" ** bad parity in predecode\n"); + res |= CP0_CERRI_DATA_PARITY; + } + /* XXXKW should/could check predecode bits themselves */ + if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { + prom_printf(" ** bad parity in instruction a\n"); + res |= CP0_CERRI_DATA_PARITY; + } + if ((datahi & 0xf) ^ inst_parity(instb)) { + prom_printf(" ** bad parity in instruction b\n"); + res |= CP0_CERRI_DATA_PARITY; + } + prom_printf(" %05X-%08X%08X", datahi, insta, instb); + } + prom_printf("\n"); + } + } + return res; +} + +/* Compute the ECC for a data doubleword */ +static uint8_t dc_ecc(uint64_t dword) +{ + uint64_t t; + uint32_t w; + uint8_t p; + int i; + + p = 0; + for (i = 7; i >= 0; i--) + { + p <<= 1; + t = dword & mask_72_64[i]; + w = (uint32_t)(t >> 32); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + w = (uint32_t)(t & 0xFFFFFFFF); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + } + return p; +} + +struct dc_state { + unsigned char val; + char *name; +}; + +static struct dc_state dc_states[] = { + { 0x00, "INVALID" }, + { 0x0f, "COH-SHD" }, + { 0x13, "NCO-E-C" }, + { 0x19, "NCO-E-D" }, + { 0x16, "COH-E-C" }, + { 0x1c, "COH-E-D" }, + { 0xff, "*ERROR*" } +}; + +#define DC_TAG_VALID(state) \ + (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) + +static char *dc_state_str(unsigned char state) +{ + struct dc_state *dsc = dc_states; + while (dsc->val != 0xff) { + if (dsc->val == state) + break; + dsc++; + } + return dsc->name; +} + +static uint32_t extract_dc(unsigned short addr, int data) +{ + int valid, way; + unsigned char state; + uint64_t taglo, pa; + uint32_t taghi, taglolo, taglohi; + uint8_t ecc, lru; + int res = 0; + + prom_printf("Dcache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 5, 0(%3)\n\t" /* Index-load-tag-D */ + " mfc0 %0, $29, 2\n\t" + " dmfc0 $1, $28, 2\n\t" + " dsrl32 %1, $1, 0\n\t" + " sll %2, $1, 0\n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + pa = (taglo & 0xFFFFFFE000) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ + ((addr >> 6) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + state = (taghi >> 25) & 0x1f; + valid = DC_TAG_VALID(state); + prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", + way, pa, dc_state_str(state), state, taghi, taglo); + if (valid) { + if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { + prom_printf(" ** bad parity in PTag1\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { + prom_printf(" ** bad parity in PTag0\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + } else { + res |= CP0_CERRD_TAG_STATE; + } + + if (data) { + uint64_t datalo; + uint32_t datalohi, datalolo, datahi; + int offset; + + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-D */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 7, 0(%3)\n\t" /* Index-load-data-D */ + " mfc0 %0, $29, 3\n\t" + " dmfc0 $1, $28, 3\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (datahi), "=r" (datalohi), "=r" (datalolo) + : "r" ((way << 13) | addr | (offset << 3))); + datalo = ((unsigned long long)datalohi << 32) | datalolo; + ecc = dc_ecc(datalo); + if (ecc != datahi) { + int bits = 0; + prom_printf(" ** bad ECC (%02x %02x) ->", + datahi, ecc); + ecc ^= datahi; + while (ecc) { + if (ecc & 1) bits++; + ecc >>= 1; + } + res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; + } + prom_printf(" %02X-%016llX", datahi, datalo); + } + prom_printf("\n"); + } + } + return res; +} diff -urN linux-2.4.21/arch/mips/mm/cex-sb1.S linux-2.4.22/arch/mips/mm/cex-sb1.S --- linux-2.4.21/arch/mips/mm/cex-sb1.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/cex-sb1.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include + +#include +#include +#include +#include +#include + + .text + .set noat + .set mips4 + + __INIT + + /* Cache Error handler for SB1 */ + LEAF(except_vec2_sb1) + mfc0 k1, $26 + # check if error was recoverable + bltz k1, leave_cerr +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + # look for signature of spurious CErr + lui k0, 0x4000 + bne k0, k1, 1f + .word 0x401Bd801 # mfc0 k1, $27, 1 + lui k0, 0xffe0 + and k1, k0, k1 + lui k0, 0x0200 + beq k0, k1, leave_cerr +1: +#endif + j handle_vec2_sb1 + +leave_cerr: + # clear/unlock the registers + mtc0 zero, $26 + mtc0 zero, $27 + .word 0x4080d801 # mtc0 zero, $27, 1 + .word 0x4080d803 # mtc0 zero, $27, 3 + eret + END(except_vec2_sb1) + + __FINIT + + LEAF(handle_vec2_sb1) + mfc0 k0,CP0_CONFIG + li k1,~CONF_CM_CMASK + and k0,k0,k1 + ori k0,k0,CONF_CM_UNCACHED + mtc0 k0,CP0_CONFIG + + SSNOP + SSNOP + SSNOP + SSNOP + bnezl $0, 1f +1: + mfc0 k0, CP0_STATUS + sll k0, k0, 3 # check CU0 (kernel?) + bltz k0, 2f + GET_SAVED_SP + move sp, k0 # want Kseg SP (so uncached) +2: + j sb1_cache_error + + END(handle_vec2_sb1) diff -urN linux-2.4.21/arch/mips/mm/fault.c linux-2.4.22/arch/mips/mm/fault.c --- linux-2.4.21/arch/mips/mm/fault.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -159,7 +160,6 @@ bad_area: up_read(&mm->mmap_sem); -bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { tsk->thread.cp0_badvaddr = address; @@ -246,26 +246,31 @@ /* * Synchronize this task's top level page-table * with the 'reference' page table. + * + * Do _not_ use "tsk" here. We might be inside + * an interrupt in the middle of a task switch.. */ - int offset = pgd_index(address); + int offset = __pgd_offset(address); pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; + pte_t *pte_k; - pgd = tsk->active_mm->pgd + offset; + pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset; pgd_k = init_mm.pgd + offset; - if (!pgd_present(*pgd)) { - if (!pgd_present(*pgd_k)) - goto bad_area_nosemaphore; - set_pgd(pgd, *pgd_k); - return; - } + if (!pgd_present(*pgd_k)) + goto no_context; + set_pgd(pgd, *pgd_k); pmd = pmd_offset(pgd, address); pmd_k = pmd_offset(pgd_k, address); - - if (pmd_present(*pmd) || !pmd_present(*pmd_k)) - goto bad_area_nosemaphore; + if (!pmd_present(*pmd_k)) + goto no_context; set_pmd(pmd, *pmd_k); + + pte_k = pte_offset(pmd_k, address); + if (!pte_present(*pte_k)) + goto no_context; + return; } } diff -urN linux-2.4.21/arch/mips/mm/init.c linux-2.4.22/arch/mips/mm/init.c --- linux-2.4.21/arch/mips/mm/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -43,17 +43,6 @@ static unsigned long totalram_pages; static unsigned long totalhigh_pages; -extern void prom_free_prom_memory(void); - - -asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) -{ - /* This should flush more selectivly ... */ - __flush_cache_all(); - - return 0; -} - /* * We have upto 8 empty zeroed pages so we can map one of the right colour * when needed. This is necessary only on R4000 / R4400 SC and MC versions @@ -67,7 +56,8 @@ { unsigned long order, size; struct page *page; - if(mips_cpu.options & MIPS_CPU_VCE) + + if (cpu_has_vce) order = 3; else order = 0; @@ -161,6 +151,7 @@ extern char _ftext, _etext, _fdata, _edata; extern char __init_begin, __init_end; +#ifdef CONFIG_HIGHMEM static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base) { @@ -189,22 +180,25 @@ j = 0; } } +#endif void __init pagetable_init(void) { +#ifdef CONFIG_HIGHMEM unsigned long vaddr; pgd_t *pgd, *pgd_base; pmd_t *pmd; pte_t *pte; +#endif /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); pgd_init((unsigned long)swapper_pg_dir + sizeof(pgd_t ) * USER_PTRS_PER_PGD); +#ifdef CONFIG_HIGHMEM pgd_base = swapper_pg_dir; -#ifdef CONFIG_HIGHMEM /* * Fixed mappings: */ @@ -360,7 +354,7 @@ #endif extern char __init_begin, __init_end; -extern void prom_free_prom_memory(void); +extern void prom_free_prom_memory(void) __init; void free_initmem(void) { diff -urN linux-2.4.21/arch/mips/mm/ioremap.c linux-2.4.22/arch/mips/mm/ioremap.c --- linux-2.4.21/arch/mips/mm/ioremap.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/ioremap.c 2003-08-25 04:44:40.000000000 -0700 @@ -94,6 +94,17 @@ } /* + * Allow physical addresses to be fixed up to help 36 bit + * peripherals. + */ +static phys_t def_fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} + +phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size) = def_fixup_bigphys_addr; + +/* * Generic mapping function (not visible outside): */ @@ -107,7 +118,7 @@ * caller shouldn't need to know that small detail. */ -#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL)) +#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) { @@ -116,6 +127,8 @@ phys_t last_addr; void * addr; + phys_addr = fixup_bigphys_addr(phys_addr, size); + /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; if (!size || last_addr < phys_addr) diff -urN linux-2.4.21/arch/mips/mm/loadmmu.c linux-2.4.22/arch/mips/mm/loadmmu.c --- linux-2.4.21/arch/mips/mm/loadmmu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/loadmmu.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,11 @@ /* - * loadmmu.c: Setup cpu/cache specific function ptrs at boot time. + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ @@ -27,13 +31,13 @@ void (*___flush_cache_all)(void); void (*_flush_cache_mm)(struct mm_struct *mm); void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start, - unsigned long end); + unsigned long end); void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -void (*_flush_cache_sigtramp)(unsigned long addr); void (*_flush_icache_range)(unsigned long start, unsigned long end); void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page); -void (*_flush_page_to_ram)(struct page * page); +void (*_flush_cache_sigtramp)(unsigned long addr); +void (*_flush_data_cache_page)(unsigned long addr); void (*_flush_icache_all)(void); #ifdef CONFIG_NONCOHERENT_IO @@ -49,49 +53,31 @@ #endif /* CONFIG_NONCOHERENT_IO */ - extern void ld_mmu_r23000(void); extern void ld_mmu_r4xx0(void); extern void ld_mmu_tx39(void); -extern void ld_mmu_tx49(void); -extern void ld_mmu_r5432(void); extern void ld_mmu_r6000(void); -extern void ld_mmu_rm7k(void); extern void ld_mmu_tfp(void); extern void ld_mmu_andes(void); extern void ld_mmu_sb1(void); -extern void ld_mmu_mips32(void); +extern void sb1_tlb_init(void); extern void r3k_tlb_init(void); extern void r4k_tlb_init(void); extern void sb1_tlb_init(void); -void __init loadmmu(void) +void __init load_mmu(void) { - if (mips_cpu.options & MIPS_CPU_4KTLB) { -#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ - defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ - defined(CONFIG_CPU_NEVADA) + if (cpu_has_4ktlb) { +#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ + defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ + defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ + defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ + defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ + defined(CONFIG_CPU_RM7000) ld_mmu_r4xx0(); r4k_tlb_init(); #endif -#if defined(CONFIG_CPU_RM7000) - ld_mmu_rm7k(); - r4k_tlb_init(); -#endif -#if defined(CONFIG_CPU_R5432) || defined(CONFIG_CPU_R5500) - ld_mmu_r5432(); - r4k_tlb_init(); -#endif -#if defined(CONFIG_CPU_TX49XX) - ld_mmu_tx49(); - r4k_tlb_init(); -#endif - -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - ld_mmu_mips32(); - r4k_tlb_init(); -#endif - } else switch(mips_cpu.cputype) { + } else switch (current_cpu_data.cputype) { #ifdef CONFIG_CPU_R3000 case CPU_R2000: case CPU_R3000: @@ -100,19 +86,11 @@ ld_mmu_r23000(); r3k_tlb_init(); break; - case CPU_TX3912: - case CPU_TX3922: - case CPU_TX3927: - case CPU_TX39XX: - ld_mmu_tx39(); - r3k_tlb_init(); - break; #endif #ifdef CONFIG_CPU_TX39XX case CPU_TX3912: case CPU_TX3922: case CPU_TX3927: - case CPU_TX39XX: ld_mmu_tx39(); r3k_tlb_init(); break; @@ -120,8 +98,8 @@ #ifdef CONFIG_CPU_R10000 case CPU_R10000: case CPU_R12000: - ld_mmu_andes(); - r4k_tlb_init(); + ld_mmu_r4xx0(); + andes_tlb_init(); break; #endif #ifdef CONFIG_CPU_SB1 @@ -130,6 +108,11 @@ sb1_tlb_init(); break; #endif + + case CPU_R8000: + panic("R8000 is unsupported"); + break; + default: panic("Yeee, unsupported mmu/cache architecture."); } diff -urN linux-2.4.21/arch/mips/mm/pg-andes.S linux-2.4.22/arch/mips/mm/pg-andes.S --- linux-2.4.21/arch/mips/mm/pg-andes.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/mm/pg-andes.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,66 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - */ -#include -#include -#include - - .text - .set mips4 - .set noat - -/* - * This is suboptimal for 32-bit kernels; we assume that R10000 is only used - * with 64-bit kernels. The prefetch offsets have been experimentally tuned - * an Origin 200. - */ - -LEAF(andes_clear_page) - LONG_ADDIU AT, a0, _PAGE_SIZE -1: pref 7, 512(a0) - LONG_S zero, 0*SZREG(a0) - LONG_S zero, 1*SZREG(a0) - LONG_S zero, 2*SZREG(a0) - LONG_S zero, 3*SZREG(a0) - LONG_ADDIU a0, a0, 8*SZREG - LONG_S zero, -4*SZREG(a0) - LONG_S zero, -3*SZREG(a0) - LONG_S zero, -2*SZREG(a0) - LONG_S zero, -1*SZREG(a0) - bne AT, a0, 1b - j ra - .end andes_clear_page - END(andes_clear_page) - -LEAF(andes_copy_page) - LONG_ADDIU AT, a0, _PAGE_SIZE -1: pref 0, 2*128(a1) - pref 1, 2*128(a0) - LONG_L a3, 0*SZREG(a1) - LONG_L a2, 1*SZREG8(a1) - LONG_L v1, 2*SZREG(a1) - LONG_L v0, 3*SZREG(a1) - LONG_S a3, 0*SZREG(a0) - LONG_S a2, 1*SZREG(a0) - LONG_S v1, 2*SZREG(a0) - LONG_S v0, 3*SZREG(a0) - LONG_ADDIU a0, a0, 8*SZREG - LONG_ADDIU a1, a1, 8*SZREG - LONG_L a3, -4*SZREG(a1) - LONG_L a2, -3*SZREG(a1) - LONG_L v1, -2*SZREG(a1) - LONG_L v0, -1*SZREG(a1) - LONG_S a3, -4*SZREG(a0) - LONG_S a2, -3*SZREG(a0) - LONG_S v1, -2*SZREG(a0) - LONG_S v0, -1*SZREG(a0) - bne AT, a0,1b - j ra - END(andes_copy_page) diff -urN linux-2.4.21/arch/mips/mm/pg-mips32.c linux-2.4.22/arch/mips/mm/pg-mips32.c --- linux-2.4.21/arch/mips/mm/pg-mips32.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/mm/pg-mips32.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,140 +0,0 @@ -/* - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute 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 it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You 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. - * - * MIPS32 CPU variant specific MMU/Cache routines. - */ -#include -#include - -#include -#include -#include - -extern int dc_lsize, ic_lsize, sc_lsize; - -/* - * Zero an entire page. - */ - -void mips32_clear_page_dc(unsigned long page) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) { - for (i=page; i -#include - -#include - -void r5432_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "addiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -void r5432_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "addiu\t%0,64\n\t" - "addiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for(i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} diff -urN linux-2.4.21/arch/mips/mm/pg-rm7k.c linux-2.4.22/arch/mips/mm/pg-rm7k.c --- linux-2.4.21/arch/mips/mm/pg-rm7k.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/mm/pg-rm7k.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,120 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org - */ -#include -#include - -#include - -/* - * Zero an entire page. Note that while the RM7000 has a second level cache - * it doesn't have a Create_Dirty_Excl_SD operation. - */ -void rm7k_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "addiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -/* - * Copy an entire page. Note that while the RM7000 has a second level cache - * it doesn't have a Create_Dirty_Excl_SD operation. - */ -void rm7k_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "addiu\t%0,64\n\t" - "addiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - : "0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} diff -urN linux-2.4.21/arch/mips/mm/pg-sb1.c linux-2.4.22/arch/mips/mm/pg-sb1.c --- linux-2.4.21/arch/mips/mm/pg-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/pg-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,9 +1,10 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Sibyte + * Copyright (C) 2000 SiByte, Inc. * - * Written by Justin Carlson (carlson@sibyte.com) + * Written by Justin Carlson of SiByte, Inc. + * and Kip Walker of Broadcom Corp. * * * This program is free software; you can redistribute it and/or @@ -20,8 +21,16 @@ * 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 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS #define SB1_PREF_LOAD_STREAMED_HINT "0" @@ -34,13 +43,15 @@ /* These are the functions hooked by the memory management function pointers */ void sb1_clear_page(void *page) { - /* JDCXXX - This should be bottlenecked by the write buffer, but these - things tend to be mildly unpredictable...should check this on the - performance model */ - - /* We prefetch 4 lines ahead. We're also "cheating" slightly here... - since we know we're on an SB1, we force the assembler to take - 64-bit operands to speed things up */ + /* + * JDCXXX - This should be bottlenecked by the write buffer, but these + * things tend to be mildly unpredictable...should check this on the + * performance model + * + * We prefetch 4 lines ahead. We're also "cheating" slightly here... + * since we know we're on an SB1, we force the assembler to take + * 64-bit operands to speed things up + */ __asm__ __volatile__( ".set push \n" ".set noreorder \n" @@ -63,22 +74,20 @@ " bne $1, %0, 1b \n" " addiu %0, %0, 32 \n" /* Next cacheline (This instruction better be short piped!) */ ".set pop \n" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE-32) - :"$1","memory"); + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE-32) + : "memory"); } void sb1_copy_page(void *to, void *from) { - - /* This should be optimized in assembly...can't use ld/sd, though, + /* + * This should be optimized in assembly...can't use ld/sd, though, * because the top 32 bits could be nuked if we took an interrupt * during the routine. And this is not a good place to be cli()'ing - */ - - /* The pref's used here are using "streaming" hints, which cause the + * + * The pref's used here are using "streaming" hints, which cause the * copied data to be kicked out of the cache sooner. A page copy often * ends up copying a lot more data than is commonly used, so this seems * to make sense in terms of reducing cache pollution, but I've no real @@ -125,19 +134,82 @@ " bne $1, %0, 1b \n" " addiu %0, %0, 32 \n" /* Next cacheline */ ".set pop \n" - :"=r" (to), - "=r" (from) - : - "0" (from), - "1" (to), - "I" (PAGE_SIZE-32) - :"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory"); + : "=r" (to), "=r" (from) + : "0" (from), "1" (to), "I" (PAGE_SIZE-32) + : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); +} + + +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + /* - unsigned long *src = from; - unsigned long *dest = to; - unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE); - while (src != target) { - *dest++ = *src++; - } -*/ + * Pad descriptors to cacheline, since each is exclusively owned by a + * particular CPU. + */ +typedef struct dmadscr_s { + uint64_t dscr_a; + uint64_t dscr_b; + uint64_t pad_a; + uint64_t pad_b; +} dmadscr_t; + +static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES))); + +void sb1_dma_init(void) +{ + int cpu = smp_processor_id(); + uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1); + + out64(base_val, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_RESET, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_ENABL, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +void sb1_clear_page_dma(void *page) +{ + int cpu = smp_processor_id(); + + /* if the page is above Kseg0, use old way */ + if (KSEGX(page) != K0BASE) + return sb1_clear_page(page); + + page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } + +void sb1_copy_page_dma(void *to, void *from) +{ + unsigned long from_phys = PHYSADDR(from); + unsigned long to_phys = PHYSADDR(to); + int cpu = smp_processor_id(); + + /* if either page is above Kseg0, use old way */ + if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE)) + return sb1_copy_page(to, from); + + page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +#endif diff -urN linux-2.4.21/arch/mips/mm/r5k-sc.c linux-2.4.22/arch/mips/mm/r5k-sc.c --- linux-2.4.21/arch/mips/mm/r5k-sc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/r5k-sc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,115 +0,0 @@ -/* - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#define SC_LINE 32 -#define SC_PAGE (128*SC_LINE) - -#define cache_op(base,op) \ -__asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, (%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -static inline void blast_r5000_scache(void) -{ - unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache_op(start, R5K_Page_Invalidate_S); - start += SC_PAGE; - } -} - -static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_r5000_scache(); - return; - } - - /* On the R5000 secondary cache we cannot - * invalidate less than a page at a time. - * The secondary cache is physically indexed, write-through. - */ - a = addr & ~(SC_PAGE - 1); - end = (addr + size - 1) & ~(SC_PAGE - 1); - while (a <= end) { - cache_op(a, R5K_Page_Invalidate_S); - a += SC_PAGE; - } -} - -static void r5k_sc_enable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - change_cp0_config(CONF_SE, CONF_SE); - blast_r5000_scache(); - __restore_flags(flags); -} - -static void r5k_sc_disable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_r5000_scache(); - change_cp0_config(CONF_SE, 0); - __restore_flags(flags); -} - -static inline int __init r5k_sc_probe(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - if(config & CONF_SC) - return(0); - - scache_size = (512*1024) << ((config >> 20)&3); - - printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -struct bcache_ops r5k_sc_ops = { - r5k_sc_enable, - r5k_sc_disable, - r5k_dma_cache_inv_sc, - r5k_dma_cache_inv_sc -}; - -void __init r5k_sc_init(void) -{ - if (r5k_sc_probe()) { - r5k_sc_enable(); - bcops = &r5k_sc_ops; - } -} diff -urN linux-2.4.21/arch/mips/mm/remap.c linux-2.4.22/arch/mips/mm/remap.c --- linux-2.4.21/arch/mips/mm/remap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/remap.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,115 @@ +/* + * arch/mips/mm/remap.c + * A copy of mm/memory.c with modifications to handle 64 bit + * physical addresses. + */ + +/* + * maps a range of physical memory into the requested pages. the old + * mappings are removed. any references to nonexistent pages results + * in null mappings (currently treated as "copy-on-access") + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Return indicates whether a page was freed so caller can adjust rss + */ +static inline void forget_pte(pte_t page) +{ + if (!pte_none(page)) { + printk("forget_pte: old mapping existed!\n"); + BUG(); + } +} + +static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size, + phys_t phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + do { + struct page *page; + pte_t oldpage; + oldpage = ptep_get_and_clear(pte); + + page = virt_to_page(__va(phys_addr)); + if ((!VALID_PAGE(page)) || PageReserved(page)) + set_pte(pte, mk_pte_phys(phys_addr, prot)); + forget_pte(oldpage); + address += PAGE_SIZE; + phys_addr += PAGE_SIZE; + pte++; + } while (address && (address < end)); +} + +static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, + phys_t phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + do { + pte_t * pte = pte_alloc(mm, pmd, address); + if (!pte) + return -ENOMEM; + remap_pte_range(pte, address, end - address, address + phys_addr, prot); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); +/* Note: this is only safe if the mm semaphore is held when called. */ +int remap_page_range_high(unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot) +{ + int error = 0; + pgd_t * dir; + unsigned long beg = from; + unsigned long end = from + size; + struct mm_struct *mm = current->mm; + + phys_addr = fixup_bigphys_addr(phys_addr, size); + phys_addr -= from; + dir = pgd_offset(mm, from); + flush_cache_range(mm, beg, end); + if (from >= end) + BUG(); + + spin_lock(&mm->page_table_lock); + do { + pmd_t *pmd = pmd_alloc(mm, dir, from); + error = -ENOMEM; + if (!pmd) + break; + error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot); + if (error) + break; + from = (from + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (from && (from < end)); + spin_unlock(&mm->page_table_lock); + flush_tlb_range(mm, beg, end); + return error; +} diff -urN linux-2.4.21/arch/mips/mm/sc-ip22.c linux-2.4.22/arch/mips/mm/sc-ip22.c --- linux-2.4.21/arch/mips/mm/sc-ip22.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/sc-ip22.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,177 @@ +/* + * sc-ip22.c: Indy cache management functions. + * + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#undef DEBUG_CACHE + +#define SC_SIZE 0x00080000 +#define SC_LINE 32 +#define CI_MASK (SC_SIZE - SC_LINE) +#define SC_INDEX(n) ((n) & CI_MASK) + +static inline void indy_sc_wipe(unsigned long first, unsigned long last) +{ + unsigned long tmp; + + __asm__ __volatile__( + ".set\tpush\t\t\t# indy_sc_wipe\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + ".set\tnoat\n\t" + "mfc0\t%2, $12\n\t" + "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" + "mtc0\t$1, $12\n\t" + + "dli\t$1, 0x9000000080000000\n\t" + "or\t%0, $1\t\t\t# first line to flush\n\t" + "or\t%1, $1\t\t\t# last line to flush\n\t" + ".set\tat\n\t" + + "1:\tsw\t$0, 0(%0)\n\t" + "bne\t%0, %1, 1b\n\t" + " daddu\t%0, 32\n\t" + + "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (first), "=r" (last), "=&r" (tmp) + : "0" (first), "1" (last)); +} + +static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) +{ + unsigned long first_line, last_line; + unsigned long flags; + +#ifdef DEBUG_CACHE + printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); +#endif + + if (!size) + return; + + /* Which lines to flush? */ + first_line = SC_INDEX(addr); + last_line = SC_INDEX(addr + size - 1); + + local_irq_save(flags); + if (first_line <= last_line) { + indy_sc_wipe(first_line, last_line); + goto out; + } + + indy_sc_wipe(first_line, SC_SIZE - SC_LINE); + indy_sc_wipe(0, last_line); +out: + local_irq_restore(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long addr, tmp1, tmp2; + + /* This is really cool... */ +#ifdef DEBUG_CACHE + printk("Enabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "sb\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop;\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + +#ifdef DEBUG_CACHE + printk("Disabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop\n\t" + "sh\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline int __init indy_sc_probe(void) +{ + unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17); + if (size == 0) + return 0; + + size <<= PAGE_SHIFT; + printk(KERN_INFO "R4600/R5000 SCACHE size %dK, linesize 32 bytes.\n", + size >> 10); + scache_size = size; + + return 1; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + .bc_enable = indy_sc_enable, + .bc_disable = indy_sc_disable, + .bc_wback_inv = indy_sc_wback_invalidate, + .bc_inv = indy_sc_wback_invalidate +}; + +void __init indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} diff -urN linux-2.4.21/arch/mips/mm/sc-r5k.c linux-2.4.22/arch/mips/mm/sc-r5k.c --- linux-2.4.21/arch/mips/mm/sc-r5k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/sc-r5k.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#define SC_LINE 32 +#define SC_PAGE (128*SC_LINE) + +#define cache_op(base,op) \ +__asm__ __volatile__(" \ + .set noreorder; \ + .set mips3; \ + cache %1, (%0); \ + .set mips0; \ + .set reorder" \ + : \ + : "r" (base), \ + "i" (op)); + +static inline void blast_r5000_scache(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + cache_op(start, R5K_Page_Invalidate_S); + start += SC_PAGE; + } +} + +static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (size >= scache_size) { + blast_r5000_scache(); + return; + } + + /* On the R5000 secondary cache we cannot + * invalidate less than a page at a time. + * The secondary cache is physically indexed, write-through. + */ + a = addr & ~(SC_PAGE - 1); + end = (addr + size - 1) & ~(SC_PAGE - 1); + while (a <= end) { + cache_op(a, R5K_Page_Invalidate_S); + a += SC_PAGE; + } +} + +static void r5k_sc_enable(void) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_config(R5K_CONF_SE, R5K_CONF_SE); + blast_r5000_scache(); + local_irq_restore(flags); +} + +static void r5k_sc_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + blast_r5000_scache(); + change_c0_config(R5K_CONF_SE, 0); + local_irq_restore(flags); +} + +static inline int __init r5k_sc_probe(void) +{ + unsigned long config = read_c0_config(); + + if (config & CONF_SC) + return(0); + + scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); + + printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n", + scache_size >> 10); + + return 1; +} + +static struct bcache_ops r5k_sc_ops = { + .bc_enable = r5k_sc_enable, + .bc_disable = r5k_sc_disable, + .bc_wback_inv = r5k_dma_cache_inv_sc, + .bc_inv = r5k_dma_cache_inv_sc +}; + +void __init r5k_sc_init(void) +{ + if (r5k_sc_probe()) { + r5k_sc_enable(); + bcops = &r5k_sc_ops; + } +} diff -urN linux-2.4.21/arch/mips/mm/sc-rm7k.c linux-2.4.22/arch/mips/mm/sc-rm7k.c --- linux-2.4.21/arch/mips/mm/sc-rm7k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/sc-rm7k.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,193 @@ +/* + * sc-rm7k.c: RM7000 cache management functions. + * + * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org), + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Primary cache parameters. */ +#define sc_lsize 32 +#define tc_pagesize (32*128) + +static unsigned long scache_way_size = 32; /* HACKKKKK!!! */ + +/* Secondary cache parameters. */ +#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ + +extern unsigned long icache_way_size, dcache_way_size; + +#include + +int rm7k_tcache_enabled; + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * (XXX These need to be fixed ...) + */ +static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +static void rm7k_sc_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +/* + * This function is executed in the uncached segment KSEG1. + * It must not touch the stack, because the stack pointer still points + * into KSEG0. + * + * Three options: + * - Write it in assembly and guarantee that we don't use the stack. + * - Disable caching for KSEG0 before calling it. + * - Pray that GCC doesn't randomly start using the stack. + * + * This being Linux, we obviously take the least sane of those options - + * following DaveM's lead in c-r4k.c + * + * It seems we get our kicks from relying on unguaranteed behaviour in GCC + */ +static __init void rm7k_sc_enable(void) +{ + int i; + + set_c0_config(1<<3); /* CONF_SE */ + + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i> 31) & 1) + return 0; + + printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + (scache_size >> 10), sc_lsize); + + if ((config >> 3) & 1) + return; + + printk(KERN_INFO "Enabling secondary cache..."); + func(); + printk(" done\n"); + + /* + * While we're at it let's deal with the tertiary cache. + */ + if ((config >> 17) & 1) + return 1; + + /* + * We can't enable the L3 cache yet. There may be board-specific + * magic necessary to turn it on, and blindly asking the CPU to + * start using it would may give cache errors. + * + * Also, board-specific knowledge may allow us to use the + * CACHE Flash_Invalidate_T instruction if the tag RAM supports + * it, and may specify the size of the L3 cache so we don't have + * to probe it. + */ + printk(KERN_INFO "Tertiary cache present, %s enabled\n", + config&(1<<12) ? "already" : "not (yet)"); + + if ((config >> 12) & 1) + rm7k_tcache_enabled = 1; + + return 1; +} + +struct bcache_ops rm7k_sc_ops = { + .bc_enable = rm7k_sc_enable, + .bc_disable = rm7k_sc_disable, + .bc_wback_inv = rm7k_sc_wback_inv, + .bc_inv = rm7k_sc_inv +}; + +void __init rm7k_sc_init(void) +{ + if (rm7k_sc_probe()) { + rm7k_sc_enable(); + bcops = &rm7k_sc_ops; + } +} diff -urN linux-2.4.21/arch/mips/mm/tlb-r3k.c linux-2.4.22/arch/mips/mm/tlb-r3k.c --- linux-2.4.21/arch/mips/mm/tlb-r3k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/tlb-r3k.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,6 +7,8 @@ * Tx39XX R4k style caches added. HK * Copyright (C) 1998, 1999, 2000 Harald Koerfgen * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 2002 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki */ #include #include @@ -23,11 +25,19 @@ #include #include +#undef DEBUG_TLB + extern char except_vec0_r2300; -#undef DEBUG_TLB +/* CP0 hazard avoidance. */ +#define BARRIER \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "nop\n\t" \ + ".set pop\n\t") -int r3k_have_wired_reg = 0; /* should be in mips_cpu? */ +int r3k_have_wired_reg; /* should be in cpu_data? */ /* TLB operations. */ void local_flush_tlb_all(void) @@ -40,117 +50,109 @@ printk("[tlball]"); #endif - save_and_cli(flags); - old_ctx = (get_entryhi() & 0xfc0); - write_32bit_cp0_register(CP0_ENTRYLO0, 0); -#ifdef CONFIG_CPU_TX39XX - entry = r3k_have_wired_reg ? get_wired() : 8; -#else - entry = 8; -#endif - for (; entry < mips_cpu.tlbsize; entry++) { - write_32bit_cp0_register(CP0_INDEX, entry << 8); - write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12)); - __asm__ __volatile__("tlbwi"); + local_irq_save(flags); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + entry = r3k_have_wired_reg ? read_c0_wired() : 8; + for (; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry << 8); + write_c0_entryhi((entry | 0x80000) << 12); + BARRIER; + tlb_write_indexed(); } - set_entryhi(old_ctx); - restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_mm(struct mm_struct *mm) { - if (mm->context != 0) { - unsigned long flags; + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { #ifdef DEBUG_TLB - printk("[tlbmm<%lu>]", (unsigned long) mm->context); + printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm)); #endif - save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); - restore_flags(flags); + drop_mmu_context(mm, cpu); } } void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) + unsigned long end) { - if (mm->context != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { unsigned long flags; int size; #ifdef DEBUG_TLB printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", - (mm->context & 0xfc0), start, end); + cpu_asid(cpu, mm), start, end); #endif - save_and_cli(flags); + local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (size <= mips_cpu.tlbsize) { - int oldpid = (get_entryhi() & 0xfc0); - int newpid = (mm->context & 0xfc0); + if (size <= current_cpu_data.tlbsize) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= PAGE_MASK; - end += (PAGE_SIZE - 1); + end += PAGE_SIZE - 1; end &= PAGE_MASK; while (start < end) { int idx; - set_entryhi(start | newpid); - start += PAGE_SIZE; + write_c0_entryhi(start | newpid); + start += PAGE_SIZE; /* BARRIER */ tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if (idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entryhi(KSEG0); + if (idx < 0) /* BARRIER */ continue; tlb_write_indexed(); } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); + drop_mmu_context(mm, cpu); } - restore_flags(flags); + local_irq_restore(flags); } } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - if (!vma || vma->vm_mm->context != 0) { + int cpu = smp_processor_id(); + + if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { unsigned long flags; int oldpid, newpid, idx; #ifdef DEBUG_TLB - printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page); + printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); #endif - newpid = (vma->vm_mm->context & 0xfc0); + newpid = cpu_asid(cpu, vma->vm_mm); page &= PAGE_MASK; - save_and_cli(flags); - oldpid = (get_entryhi() & 0xfc0); - set_entryhi(page | newpid); + local_irq_save(flags); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); + BARRIER; tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if (idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entryhi(KSEG0); + if (idx < 0) /* BARRIER */ goto finish; tlb_write_indexed(); finish: - set_entryhi(oldpid); - restore_flags(flags); + write_c0_entryhi(oldpid); + local_irq_restore(flags); } } -void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; int idx, pid; /* @@ -159,92 +161,86 @@ if (current->active_mm != vma->vm_mm) return; - pid = get_entryhi() & 0xfc0; + pid = read_c0_entryhi() & ASID_MASK; #ifdef DEBUG_TLB - if ((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) { + if ((pid != cpu_asid(cpu, vma->vm_mm)) || (cpu_context(cpu, vma->vm_mm) == 0)) { printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", - (vma->vm_mm->context & 0xfc0), pid); + (cpu_context(cpu, vma->vm_mm)), pid); } #endif - save_and_cli(flags); + local_irq_save(flags); address &= PAGE_MASK; - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); + write_c0_entryhi(address | pid); + BARRIER; tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep)); - set_entryhi(address | (pid)); - if (idx < 0) { + idx = read_c0_index(); + write_c0_entrylo0(pte_val(pte)); + write_c0_entryhi(address | pid); + if (idx < 0) { /* BARRIER */ tlb_write_random(); -#if 0 - printk("[MISS]"); -#endif } else { tlb_write_indexed(); -#if 0 - printk("[HIT]"); -#endif } - set_entryhi(pid); - restore_flags(flags); + write_c0_entryhi(pid); + local_irq_restore(flags); } void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) + unsigned long entryhi, unsigned long pagemask) { unsigned long flags; unsigned long old_ctx; static unsigned long wired = 0; -#ifdef CONFIG_CPU_TX39XX - if (r3k_have_wired_reg) { + if (r3k_have_wired_reg) { /* TX39XX */ unsigned long old_pagemask; unsigned long w; #ifdef DEBUG_TLB - printk("[tlbwired]"); - printk("ently lo0 %8x, hi %8x\n, pagemask %8x\n", + printk("[tlbwired]\n", entrylo0, entryhi, pagemask); #endif - save_and_cli(flags); + + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - w = get_wired(); - set_wired (w + 1); - if (get_wired() != w + 1) { + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + w = read_c0_wired(); + write_c0_wired(w + 1); + if (read_c0_wired() != w + 1) { printk("[tlbwired] No WIRED reg?\n"); return; } - set_index (w << 8); - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); + write_c0_index(w << 8); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + BARRIER; tlb_write_indexed(); - set_entryhi(old_ctx); - set_pagemask (old_pagemask); + write_c0_entryhi(old_ctx); + write_c0_pagemask(old_pagemask); local_flush_tlb_all(); - restore_flags(flags); - return; - } + local_irq_restore(flags); + + } else if (wired < 8) { +#ifdef DEBUG_TLB + printk("[tlbwired]\n", + entrylo0, entryhi); #endif - if (wired < 8) { - __save_and_cli(flags); - old_ctx = get_entryhi() & 0xfc0; - set_entrylo0(entrylo0); - set_entryhi(entryhi); - set_index(wired); - wired++; + local_irq_save(flags); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(entrylo0); + write_c0_entryhi(entryhi); + write_c0_index(wired); + wired++; /* BARRIER */ tlb_write_indexed(); - set_entryhi(old_ctx); - local_flush_tlb_all(); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_flush_tlb_all(); + local_irq_restore(flags); } } diff -urN linux-2.4.21/arch/mips/mm/tlb-r4k.c linux-2.4.22/arch/mips/mm/tlb-r4k.c --- linux-2.4.21/arch/mips/mm/tlb-r4k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/tlb-r4k.c 2003-08-25 04:44:40.000000000 -0700 @@ -44,66 +44,64 @@ printk("[tlball]"); #endif - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entrylo0(0); - set_entrylo1(0); + old_ctx = (read_c0_entryhi() & 0xff); + write_c0_entrylo0(0); + write_c0_entrylo1(0); BARRIER; - entry = get_wired(); + entry = read_c0_wired(); /* Blast 'em all away. */ - while (entry < mips_cpu.tlbsize) { + while (entry < current_cpu_data.tlbsize) { /* * Make sure all entries differ. If they're not different * MIPS32 will take revenge ... */ - set_entryhi(KSEG0 + entry*0x2000); - set_index(entry); + write_c0_entryhi(KSEG0 + entry*0x2000); + write_c0_index(entry); BARRIER; tlb_write_indexed(); BARRIER; entry++; } BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_mm(struct mm_struct *mm) { - if (mm->context != 0) { - unsigned long flags; + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { #ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); + printk("[tlbmm<%d>]", cpu_context(cpu, mm)); #endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - __restore_flags(flags); + drop_mmu_context(mm,cpu); } } void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - if (mm->context != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { unsigned long flags; int size; #ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); + printk("[tlbrange<%02x,%08lx,%08lx>]", + cpu_asid(cpu, mm), start, end); #endif - __save_and_cli(flags); + local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if (size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); + if (size <= current_cpu_data.tlbsize/2) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); @@ -111,63 +109,64 @@ while (start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if (idx < 0) continue; /* Make sure all entries differ. */ - set_entryhi(KSEG0 + idx*0x2000); + write_c0_entryhi(KSEG0 + idx*0x2000); BARRIER; tlb_write_indexed(); BARRIER; } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); + drop_mmu_context(mm, cpu); } - __restore_flags(flags); + local_irq_restore(flags); } } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - if (!vma || vma->vm_mm->context != 0) { + int cpu = smp_processor_id(); + + if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { unsigned long flags; int oldpid, newpid, idx; #ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); + printk("[tlbpage<%d,%08lx>]", cpu_context(cpu, vma->vm_mm), + page); #endif - newpid = (vma->vm_mm->context & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & 0xff); + write_c0_entryhi(page | newpid); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); + write_c0_entryhi(KSEG0+idx*0x2000); BARRIER; tlb_write_indexed(); finish: BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); + write_c0_entryhi(oldpid); + local_irq_restore(flags); } } @@ -175,8 +174,7 @@ * updates the TLB with the new pte(s), and another which also checks * for the R4k "end of page" hardware bug and does the needy. */ -void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -190,29 +188,36 @@ if (current->active_mm != vma->vm_mm) return; - pid = get_entryhi() & 0xff; + pid = read_c0_entryhi() & ASID_MASK; #ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); + if ((pid != cpu_asid(cpu, vma->vm_mm)) || + (cpu_context(vma->vm_mm) == 0)) { + printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d " + "tlbpid=%d\n", (int) (cpu_asid(cpu, vma->vm_mm)), pid); } #endif - __save_and_cli(flags); + local_irq_save(flags); address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | pid); pgdp = pgd_offset(vma->vm_mm, address); BARRIER; tlb_probe(); BARRIER; pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) + write_c0_entrylo0(ptep->pte_high); + ptep++; + write_c0_entrylo1(ptep->pte_high); +#else + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); +#endif + write_c0_entryhi(address | pid); BARRIER; if (idx < 0) { tlb_write_random(); @@ -220,9 +225,9 @@ tlb_write_indexed(); } BARRIER; - set_entryhi(pid); + write_c0_entryhi(pid); BARRIER; - __restore_flags(flags); + local_irq_restore(flags); } #if 0 @@ -235,23 +240,23 @@ pte_t *ptep; int idx; - __save_and_cli(flags); + local_irq_save(flags); address &= (PAGE_MASK << 1); - set_entryhi(address | (get_entryhi() & 0xff)); + write_c0_entryhi(address | (read_c0_entryhi() & 0xff)); pgdp = pgd_offset(vma->vm_mm, address); tlb_probe(); pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); BARRIER; if (idx < 0) tlb_write_random(); else tlb_write_indexed(); BARRIER; - __restore_flags(flags); + local_irq_restore(flags); } #endif @@ -263,27 +268,27 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired(wired + 1); - set_index(wired); - BARRIER; - set_pagemask(pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask(old_pagemask); + write_c0_pagemask(old_pagemask); local_flush_tlb_all(); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -303,58 +308,60 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - old_pagemask = get_pagemask(); - wired = get_wired(); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); if (--temp_tlb_entry < wired) { printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); ret = -ENOSPC; goto out; } - set_index(temp_tlb_entry); + write_c0_index(temp_tlb_entry); BARRIER; - set_pagemask(pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask(old_pagemask); + write_c0_pagemask(old_pagemask); out: - __restore_flags(flags); + local_irq_restore(flags); return ret; } static void __init probe_tlb(unsigned long config) { - unsigned int prid, config1; + unsigned int reg; - prid = read_32bit_cp0_register(CP0_PRID) & 0xff00; - if (prid == PRID_IMP_RM7000 || !(config & (1 << 31))) + reg = read_c0_prid() & 0xff00; + if (reg == PRID_IMP_RM7000 || !(config & (1 << 31))) /* - * Not a MIPS32 complianant CPU. Config 1 register not + * Not a MIPS32 compliant CPU. Config 1 register not * supported, we assume R4k style. Cpu probing already figured * out the number of tlb entries. */ return; - config1 = read_mips32_cp0_config1(); +#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) + reg = read_c0_config1(); if (!((config >> 7) & 3)) panic("No MMU present"); else - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + current_cpu_data.tlbsize = ((reg >> 25) & 0x3f) + 1; +#endif } void __init r4k_tlb_init(void) { - u32 config = read_32bit_cp0_register(CP0_CONFIG); + u32 config = read_c0_config(); /* * You should never change this register: @@ -364,16 +371,15 @@ * be set for 4kb pages. */ probe_tlb(config); - set_pagemask(PM_4K); - write_32bit_cp0_register(CP0_WIRED, 0); - temp_tlb_entry = mips_cpu.tlbsize - 1; + write_c0_pagemask(PM_4K); + write_c0_wired(0); + temp_tlb_entry = current_cpu_data.tlbsize - 1; local_flush_tlb_all(); - if ((mips_cpu.options & MIPS_CPU_4KEX) - && (mips_cpu.options & MIPS_CPU_4KTLB)) { - if (mips_cpu.cputype == CPU_NEVADA) + if (cpu_has_4kex && cpu_has_4ktlb) { + if (current_cpu_data.cputype == CPU_NEVADA) memcpy((void *)KSEG0, &except_vec0_nevada, 0x80); - else if (mips_cpu.cputype == CPU_R4600) + else if (current_cpu_data.cputype == CPU_R4600) memcpy((void *)KSEG0, &except_vec0_r4600, 0x80); else memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); diff -urN linux-2.4.21/arch/mips/mm/tlb-sb1.c linux-2.4.22/arch/mips/mm/tlb-sb1.c --- linux-2.4.21/arch/mips/mm/tlb-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/tlb-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ #include #include -extern char except_vec0_r4000[]; +extern char except_vec0_sb1[]; /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) @@ -35,7 +35,6 @@ ".set noreorder \n" ".set mips64 \n" ".set noat \n" - " tlbr \n" " dmfc0 $1, $10 \n" " dsrl32 %0, $1, 0 \n" " sll %1, $1, 0 \n" @@ -47,13 +46,11 @@ " sll %5, $1, 0 \n" " mfc0 %6, $5 \n" ".set pop \n" - : "=r" (entryhihi), - "=r" (entryhilo), - "=r" (entrylo0hi), - "=r" (entrylo0lo), - "=r" (entrylo1hi), - "=r" (entrylo1lo), - "=r" (pagemask)); + : "=r" (entryhihi), "=r" (entryhilo), + "=r" (entrylo0hi), "=r" (entrylo0lo), + "=r" (entrylo1hi), "=r" (entrylo1lo), + "=r" (pagemask)); + printk("%08X%08X %08X%08X %08X%08X %08X", entryhihi, entryhilo, entrylo0hi, entrylo0lo, @@ -66,29 +63,25 @@ unsigned long old_ctx; unsigned long flags; int entry; - __save_and_cli(flags); - old_ctx = get_entryhi(); + local_irq_save(flags); + old_ctx = read_c0_entryhi(); printk("Current TLB registers state:\n" " EntryHi EntryLo0 EntryLo1 PageMask Index\n" "--------------------------------------------------------------------\n"); dump_cur_tlb_regs(); - printk(" %08X\n", read_32bit_cp0_register(CP0_INDEX)); + printk(" %08X\n", read_c0_index()); printk("\n\nFull TLB Dump:\n" "Idx EntryHi EntryLo0 EntryLo1 PageMask\n" "--------------------------------------------------------------\n"); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_index(entry); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry); printk("\n%02i ", entry); - __asm__ __volatile__ ( - ".set push \n" - ".set mips64 \n" - " tlbr \n" - ".set pop \n"); + tlb_read(); dump_cur_tlb_regs(); } printk("\n"); - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_all(void) @@ -97,18 +90,18 @@ unsigned long old_ctx; int entry; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); - set_index(entry); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + write_c0_index(entry); tlb_write_indexed(); } - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } @@ -126,15 +119,15 @@ long inc = 1<<24; /* 16MB */ /* Save old context and create impossible VPN2 value */ - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { do { addr += inc; - set_entryhi(addr); + write_c0_entryhi(addr); tlb_probe(); - } while ((int)(get_index()) >= 0); - set_index(entry); + } while ((int)(read_c0_index()) >= 0); + write_c0_index(entry); tlb_write_indexed(); } /* Now that we know we're safe from collisions, we can safely flush @@ -149,79 +142,66 @@ unsigned long flags; int cpu; - __save_and_cli(flags); + local_irq_save(flags); cpu = smp_processor_id(); - if(CPU_CONTEXT(cpu, mm) != 0) { + if (cpu_context(cpu, mm) != 0) { int size; size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if(size <= (mips_cpu.tlbsize/2)) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(cpu, mm) & 0xff); + if (size <= (current_cpu_data.tlbsize/2)) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); end &= (PAGE_MASK << 1); - while(start < end) { + while (start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); - if(idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + if (idx < 0) continue; tlb_write_indexed(); } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, cpu); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); + drop_mmu_context(mm, cpu); } } - __restore_flags(flags); + local_irq_restore(flags); } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { unsigned long flags; - -#ifdef CONFIG_SMP - /* - * This variable is eliminated from CPU_CONTEXT() if SMP isn't defined, - * so conditional it to get rid of silly "unused variable" compiler - * complaints - */ int cpu = smp_processor_id(); -#endif - __save_and_cli(flags); - if (CPU_CONTEXT(cpu, vma->vm_mm) != 0) { + local_irq_save(flags); + if (cpu_context(cpu, vma->vm_mm) != 0) { int oldpid, newpid, idx; -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", CPU_CONTEXT(cpu, vma->vm_mm), page); -#endif - newpid = (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - oldpid = (get_entryhi() & 0xff); - set_entryhi (page | newpid); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - if(idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); tlb_write_indexed(); finish: - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } - __restore_flags(flags); + local_irq_restore(flags); } @@ -229,23 +209,16 @@ these entries, we just bump the asid. */ void local_flush_tlb_mm(struct mm_struct *mm) { - unsigned long flags; - int cpu; - __save_and_cli(flags); - cpu = smp_processor_id(); - if (CPU_CONTEXT(cpu, mm) != 0) { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) { - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); - } + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { + drop_mmu_context(mm, cpu); } - __restore_flags(flags); } /* Stolen from mips32 routines */ -void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -259,35 +232,24 @@ if (current->active_mm != vma->vm_mm) return; - __save_and_cli(flags); - - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff)) || (CPU_CONTEXT(cpu, vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff), pid); - } -#endif + local_irq_save(flags); + pid = read_c0_entryhi() & ASID_MASK; address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | (pid)); pgdp = pgd_offset(vma->vm_mm, address); tlb_probe(); pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - if(idx < 0) { + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + if (idx < 0) { tlb_write_random(); } else { tlb_write_indexed(); } - set_entryhi(pid); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -297,10 +259,7 @@ */ void sb1_tlb_init(void) { - u32 config1; - - config1 = read_mips32_cp0_config1(); - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + write_c0_pagemask(PM_4K); /* * We don't know what state the firmware left the TLB's in, so this is @@ -309,6 +268,6 @@ */ sb1_sanitize_tlb(); - memcpy((void *)KSEG0, except_vec0_r4000, 0x80); + memcpy((void *)KSEG0, except_vec0_sb1, 0x80); flush_icache_range(KSEG0, KSEG0 + 0x80); } diff -urN linux-2.4.21/arch/mips/mm/tlbex-mips32.S linux-2.4.22/arch/mips/mm/tlbex-mips32.S --- linux-2.4.21/arch/mips/mm/tlbex-mips32.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/tlbex-mips32.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,329 @@ +/* + * TLB exception handling code for MIPS32 CPUs. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-cpu abstraction and reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * + * Pete Popov, ppopov@pacbell.net + * Added 36 bit phys address support. + * Copyright (C) 2002 MontaVista Software, Inc. + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + +#ifdef CONFIG_64BIT_PHYS_ADDR + +/* We really only support 36 bit physical addresses on MIPS32 */ +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_HALF 4 /* pte_high contains pre-shifted, ready to go entry */ +#define PTE_SIZE 8 +#define PTEP_INDX_MSK 0xff0 +#define PTE_INDX_MSK 0xff8 +#define PTE_INDX_SHIFT 9 +#define CONVERT_PTE(pte) +#define PTE_MAKEWRITE_HIGH(pte, ptr) \ + lw pte, 4(ptr); \ + ori pte, (_PAGE_VALID | _PAGE_DIRTY); \ + sw pte, 4(ptr); \ + lw pte, 0(ptr); + +#define PTE_MAKEVALID_HIGH(pte, ptr) \ + lw pte, 4(ptr); \ + ori pte, pte, _PAGE_VALID; \ + sw pte, 4(ptr); \ + lw pte, 0(ptr); + +#else + +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_HALF 0 +#define PTE_SIZE 4 +#define PTEP_INDX_MSK 0xff8 +#define PTE_INDX_MSK 0xffc +#define PTE_INDX_SHIFT 10 +#define CONVERT_PTE(pte) srl pte, pte, 6 +#define PTE_MAKEWRITE_HIGH(pte, ptr) +#define PTE_MAKEVALID_HIGH(pte, ptr) + +#endif /* CONFIG_64BIT_PHYS_ADDR */ + + __INIT + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define GET_PTE_OFF(reg) +#else +#define GET_PTE_OFF(reg) srl reg, reg, 1 +#endif + +/* + * These handlers much be written in a relocatable manner + * because based upon the cpu type an arbitrary one of the + * following pieces of code will be copied to the KSEG0 + * vector location. + */ + /* TLB refill, EXL == 0, MIPS32 version */ + .set noreorder + .set noat + LEAF(except_vec0_r4000) + .set mips3 +#ifdef CONFIG_SMP + mfc0 k1, CP0_CONTEXT + la k0, pgd_current + srl k1, 23 + sll k1, 2 # log2(sizeof(pgd_t) + addu k1, k0, k1 + lw k1, (k1) +#else + lw k1, pgd_current # get pgd pointer +#endif + nop + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, PGDIR_SHIFT # get pgd only bits + + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + + PTE_L k0, PTE_HALF(k1) # get even pte + CONVERT_PTE(k0) + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_L k1, (PTE_HALF+PTE_SIZE)(k1) # get odd pte + CONVERT_PTE(k1) + P_MTC0 k1, CP0_ENTRYLO1 # load it + b 1f + tlbwr # write random tlb entry +1: + nop + eret # return from trap + END(except_vec0_r4000) + +/* + * These are here to avoid putting ifdefs in tlb-r4k.c + */ + .set noreorder + .set noat + LEAF(except_vec0_nevada) + .set mips3 + PANIC("Nevada Exception Vec 0 called") + END(except_vec0_nevada) + + .set noreorder + .set noat + LEAF(except_vec0_r4600) + .set mips3 + PANIC("R4600 Exception Vec 0 called") + END(except_vec0_r4600) + + __FINIT + +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, (PTE_HALF+PTE_SIZE)(ptr); \ + CONVERT_PTE(tmp); \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_L ptr, PTE_HALF(ptr); \ + CONVERT_PTE(ptr); \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + STI; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + + .set noreorder + +#define R5K_HAZARD nop + + .align 5 + NESTED(handle_tlbl, PT_SIZE, sp) + .set noat +invalid_tlbl: +#ifdef TLB_OPTIMIZE + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID_HIGH(k0, k1) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbl: + DO_FAULT(0) + END(handle_tlbl) + + .align 5 + NESTED(handle_tlbs, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + li k0,0 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_MAKEWRITE_HIGH(k0, k1) + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbs: + DO_FAULT(1) + END(handle_tlbs) + + .align 5 + NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + PTE_L k0, (k1) + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + PTE_MAKEWRITE_HIGH(k0, k1) + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nowrite_mod: + DO_FAULT(1) + END(handle_mod) + diff -urN linux-2.4.21/arch/mips/mm/tlbex-r4k.S linux-2.4.22/arch/mips/mm/tlbex-r4k.S --- linux-2.4.21/arch/mips/mm/tlbex-r4k.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/tlbex-r4k.S 2003-08-25 04:44:40.000000000 -0700 @@ -23,6 +23,7 @@ #include #include #include +#include #define TLB_OPTIMIZE /* If you are paranoid, disable this. */ @@ -46,6 +47,100 @@ #define PTE_INDX_SHIFT 10 #endif +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, _PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, PTE_SIZE(ptr); \ + PTE_L ptr, 0(ptr); \ + PTE_SRL tmp, tmp, 6; \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_SRL ptr, ptr, 6; \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + __INIT #ifdef CONFIG_64BIT_PHYS_ADDR @@ -67,16 +162,7 @@ .set noat LEAF(except_vec0_r4000) .set mips3 -#ifdef CONFIG_SMP - mfc0 k1, CP0_CONTEXT - la k0, pgd_current - srl k1, 23 - sll k1, 2 # log2(sizeof(pgd_t) - addu k1, k0, k1 - lw k1, (k1) -#else - lw k1, pgd_current # get pgd pointer -#endif + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR # Get faulting address srl k0, k0, _PGDIR_SHIFT # get pgd only bits @@ -103,16 +189,14 @@ /* TLB refill, EXL == 0, R4600 version */ LEAF(except_vec0_r4600) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif + GET_PTE_OFF(k0) # get pte offset and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) @@ -148,9 +232,7 @@ addu k1, k1, k0 # add in pgd offset lw k1, (k1) mfc0 k0, CP0_CONTEXT # get context reg -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 # get pte offset -#endif + GET_PTE_OFF(k0) # get pte offset and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 # add in offset PTE_L k0, 0(k1) # get even pte @@ -166,12 +248,41 @@ eret # return from trap END(except_vec0_nevada) + /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ + LEAF(except_vec0_sb1) +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + tlbwr # write random tlb entry +1: eret # return from trap + END(except_vec0_sb1) + /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ LEAF(except_vec0_r45k_bvahwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -201,9 +312,9 @@ /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ LEAF(except_vec0_r4k_mphwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -233,9 +344,9 @@ /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ LEAF(except_vec0_r4k_250MHZhwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -264,9 +375,9 @@ /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ LEAF(except_vec0_r4k_MP250MHZhwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -295,104 +406,8 @@ END(except_vec0_r4k_MP250MHZhwbug) #endif - - __FINIT -/* - * ABUSE of CPP macros 101. - * - * After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, pgd_current;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, pgd_current; -#endif - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, PTE_INDX_SHIFT; \ - and pte, pte, PTE_INDX_MSK; \ - addu ptr, ptr, pte; \ - PTE_L pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, PTE_SIZE(ptr); \ - PTE_L ptr, 0(ptr); \ - PTE_SRL tmp, tmp, 6; \ - P_MTC0 tmp, CP0_ENTRYLO1; \ - PTE_SRL ptr, ptr, 6; \ - P_MTC0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - PTE_S pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - PTE_S pte, (ptr); - .set noreorder /* @@ -424,6 +439,18 @@ .align 5 NESTED(handle_tlbl, PT_SIZE, sp) .set noat +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + beqz k0, 1f + nop + .set mips3 + eret + .set mips0 +1: +#endif invalid_tlbl: #ifdef TLB_OPTIMIZE /* Test present bit in entry. */ diff -urN linux-2.4.21/arch/mips/mm/umap.c linux-2.4.22/arch/mips/mm/umap.c --- linux-2.4.21/arch/mips/mm/umap.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/mm/umap.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,218 +0,0 @@ -/* - * (C) Copyright 1994 Linus Torvalds - * - * Changes: - * - * Modified from Linus source to removing active mappings from any - * task. This is required for implementing the virtual graphics - * interface for direct rendering on the SGI - miguel. - * - * Added a routine to map a vmalloc()ed area into user space, this one - * is required by the /dev/shmiq driver - miguel. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static inline void -remove_mapping_pte_range (pmd_t *pmd, unsigned long address, unsigned long size) -{ - pte_t *pte; - unsigned long end; - - if (pmd_none (*pmd)) - return; - if (pmd_bad (*pmd)){ - printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", pmd_val (*pmd)); - pmd_clear (pmd); - return; - } - pte = pte_offset (pmd, address); - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t entry = *pte; - if (pte_present (entry)) - set_pte (pte, pte_modify (entry, PAGE_NONE)); - address += PAGE_SIZE; - pte++; - } while (address < end); - -} - -static inline void -remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, unsigned long size) -{ - pmd_t *pmd; - unsigned long end; - - if (pgd_none (*pgd)) - return; - - if (pgd_bad (*pgd)){ - printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", pgd_val (*pgd)); - pgd_clear (pgd); - return; - } - pmd = pmd_offset (pgd, address); - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - do { - remove_mapping_pte_range (pmd, address, end - address); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - -} - -/* - * This routine is called from the page fault handler to remove a - * range of active mappings at this point - */ -void -remove_mapping (struct task_struct *task, unsigned long start, unsigned long end) -{ - unsigned long beg = start; - pgd_t *dir; - - down_write (&task->mm->mmap_sem); - dir = pgd_offset (task->mm, start); - flush_cache_range (task->mm, beg, end); - while (start < end){ - remove_mapping_pmd_range (dir, start, end - start); - start = (start + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - local_flush_tlb_range (task->mm, beg, end); - up_write (&task->mm->mmap_sem); -} - -EXPORT_SYMBOL(remove_mapping); - -void *vmalloc_uncached (unsigned long size) -{ - return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_UNCACHED); -} - -static inline void free_pte(pte_t page) -{ - if (pte_present(page)) { - struct page *ptpage = pte_page(page); - if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage)) - return; - __free_page(ptpage); - if (current->mm->rss <= 0) - return; - current->mm->rss--; - return; - } - swap_free(pte_to_swp_entry(page)); -} - -static inline void forget_pte(pte_t page) -{ - if (!pte_none(page)) { - printk("forget_pte: old mapping existed!\n"); - free_pte(page); - } -} - -/* - * maps a range of vmalloc()ed memory into the requested pages. the old - * mappings are removed. - */ -static inline void -vmap_pte_range (pte_t *pte, unsigned long address, unsigned long size, unsigned long vaddr) -{ - unsigned long end; - pgd_t *vdir; - pmd_t *vpmd; - pte_t *vpte; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t oldpage = *pte; - struct page * page; - pte_clear(pte); - - vdir = pgd_offset_k (vaddr); - vpmd = pmd_offset (vdir, vaddr); - vpte = pte_offset (vpmd, vaddr); - page = pte_page (*vpte); - - set_pte(pte, mk_pte(page, PAGE_USERIO)); - forget_pte(oldpage); - address += PAGE_SIZE; - vaddr += PAGE_SIZE; - pte++; - } while (address < end); -} - -static inline int -vmap_pmd_range (pmd_t *pmd, unsigned long address, unsigned long size, unsigned long vaddr) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - vaddr -= address; - do { - pte_t * pte = pte_alloc(current->mm, pmd, address); - if (!pte) - return -ENOMEM; - vmap_pte_range(pte, address, end - address, address + vaddr); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - return 0; -} - -int -vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr) -{ - int error = 0; - pgd_t * dir; - unsigned long beg = from; - unsigned long end = from + size; - - vaddr -= from; - dir = pgd_offset(current->mm, from); - flush_cache_range(current->mm, beg, end); - while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); - error = -ENOMEM; - if (!pmd) - break; - error = vmap_pmd_range(pmd, from, end - from, vaddr + from); - if (error) - break; - from = (from + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - local_flush_tlb_range(current->mm, beg, end); - return error; -} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/Makefile linux-2.4.22/arch/mips/momentum/ocelot_c/Makefile --- linux-2.4.21/arch/mips/momentum/ocelot_c/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,18 @@ +# +# Makefile for Momentum Computer's Ocelot-C and -CS boards. +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET:= ocelot_c.o + +obj-y += mv-irq.o cpci-irq.o uart-irq.o int-handler.o irq.o +obj-y += pci-irq.o pci.o prom.o reset.o setup.o + +obj-$(CONFIG_KGDB) += dbg_io.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/cpci-irq.c linux-2.4.22/arch/mips/momentum/ocelot_c/cpci-irq.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/cpci-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/cpci-irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,154 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/cpci-irq.c + * Interrupt routines for cpci. Interrupt numbers are assigned from + * CPCI_IRQ_BASE to CPCI_IRQ_BASE+8 (8 interrupt sources). + * + * Note that the high-level software will need to be careful about using + * these interrupts. If this board is asserting a cPCI interrupt, it will + * also see the asserted interrupt. Care must be taken to avoid an + * interrupt flood. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +#define CPCI_IRQ_BASE 8 + +static inline int ls1bit8(unsigned int x) +{ + int b = 7, s; + + s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; + s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; + s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 0 is enable, 1 is disable */ +static inline void mask_cpci_irq(unsigned int irq) +{ + uint32_t value; + + value = OCELOT_FPGA_READ(INTMASK); + value |= 1 << (irq - CPCI_IRQ_BASE); + OCELOT_FPGA_WRITE(value, INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(INTMASK); +} + +/* unmask an interrupt -- 0 is enable, 1 is disable */ +static inline void unmask_cpci_irq(unsigned int irq) +{ + uint32_t value; + + value = OCELOT_FPGA_READ(INTMASK); + value &= ~(1 << (irq - CPCI_IRQ_BASE)); + OCELOT_FPGA_WRITE(value, INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(INTMASK); +} + +/* + * Enables the IRQ in the FPGA + */ +static void enable_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_cpci_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_cpci_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the FPGA chip. + * It could be built in ethernet ports etc... + */ +void ll_cpci_irq(struct pt_regs *regs) +{ + unsigned int irq_src, irq_mask; + + /* read the interrupt status registers */ + irq_src = OCELOT_FPGA_READ(INTSTAT); + irq_mask = OCELOT_FPGA_READ(INTMASK); + + /* mask for just the interrupts we want */ + irq_src &= ~irq_mask; + + do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE, regs); +} + +#define shutdown_cpci_irq disable_cpci_irq + +struct hw_interrupt_type cpci_irq_type = { + "CPCI/FPGA", + startup_cpci_irq, + shutdown_cpci_irq, + enable_cpci_irq, + disable_cpci_irq, + mask_and_ack_cpci_irq, + end_cpci_irq, + NULL +}; + +void cpci_irq_init(void) +{ + int i; + + /* Reset irq handlers pointers to NULL */ + for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &cpci_irq_type; + } +} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/dbg_io.c linux-2.4.22/arch/mips/momentum/ocelot_c/dbg_io.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/dbg_io.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/dbg_io.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,126 @@ +#include + +#if defined(CONFIG_KGDB) + +#include /* For the serial port location and base baud */ + +/* --- CONFIG --- */ + +typedef unsigned char uint8; +typedef unsigned int uint32; + +/* --- END OF CONFIG --- */ + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +/* === CONFIG === */ + +/* [jsun] we use the second serial port for kdb */ +#define BASE OCELOT_SERIAL1_BASE +#define MAX_BAUD OCELOT_BASE_BAUD + +/* === END OF CONFIG === */ + +#define REG_OFFSET 4 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) + +void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + uint32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +uint8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); + return UART16550_READ(OFS_RCV_BUFFER); +} + + +int putDebugChar(uint8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} + +#endif diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/int-handler.S linux-2.4.22/arch/mips/momentum/ocelot_c/int-handler.S --- linux-2.4.21/arch/mips/momentum/ocelot_c/int-handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/int-handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,104 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * First-level interrupt dispatcher for Ocelot-CS board. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#define __ASSEMBLY__ +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +/* + * First level interrupt dispatcher for Ocelot-CS board + */ + .align 5 + NESTED(ocelot_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ + bnez t1, ll_sw0_irq + andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ + bnez t1, ll_sw1_irq + andi t1, t0, STATUSF_IP2 /* int0 hardware line */ + bnez t1, ll_scsi_irq + andi t1, t0, STATUSF_IP3 /* int1 hardware line */ + bnez t1, ll_uart_decode_irq + andi t1, t0, STATUSF_IP4 /* int2 hardware line */ + bnez t1, ll_pmc_irq + andi t1, t0, STATUSF_IP5 /* int3 hardware line */ + bnez t1, ll_cpci_decode_irq + andi t1, t0, STATUSF_IP6 /* int4 hardware line */ + bnez t1, ll_mv64340_decode_irq + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cputimer_irq + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(ocelot_handle_int) + + .align 5 +ll_sw0_irq: + li a0, 0 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_sw1_irq: + li a0, 1 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_scsi_irq: + li a0, 2 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_uart_decode_irq: + move a0, sp + jal ll_uart_irq + j ret_from_irq + +ll_pmc_irq: + li a0, 4 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpci_decode_irq: + move a0, sp + jal ll_cpci_irq + j ret_from_irq + +ll_mv64340_decode_irq: + move a0, sp + jal ll_mv64340_irq + j ret_from_irq + +ll_cputimer_irq: + li a0, 7 + move a1, sp + jal do_IRQ + j ret_from_irq + diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/irq.c linux-2.4.22/arch/mips/momentum/ocelot_c/irq.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; + +/* Function for careful CP0 interrupt mask access */ +static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) +{ + unsigned long status; + unsigned clr_mask; + unsigned set_mask; + + /* do the low 8 bits first */ + clr_mask = 0xff & clr_mask_in; + set_mask = 0xff & set_mask_in; + status = read_c0_status(); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_c0_status(status); +} + +static inline void mask_irq(unsigned int irq) +{ + modify_cp0_intmask(irq, 0); +} + +static inline void unmask_irq(unsigned int irq) +{ + modify_cp0_intmask(0, irq); +} + +static void enable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(1 << irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_cp7000_irq(unsigned int irq) +{ + enable_cp7000_irq(irq); + + return 0; /* never anything pending */ +} + +static void disable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(1 << irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define shutdown_cp7000_irq disable_cp7000_irq + +static void mask_and_ack_cp7000_irq(unsigned int irq) +{ + mask_irq(1 << irq); +} + +static void end_cp7000_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_irq(1 << irq); +} + +static struct hw_interrupt_type cp7000_hpcdma_irq_type = { +#ifdef CONFIG_CPU_SR71000 + "SR71000", +#else + "RM7000", +#endif + startup_cp7000_irq, + shutdown_cp7000_irq, + enable_cp7000_irq, + disable_cp7000_irq, + mask_and_ack_cp7000_irq, + end_cp7000_irq, + NULL +}; + +extern asmlinkage void ocelot_handle_int(void); +extern void mv64340_irq_init(void); +extern void uart_irq_init(void); +extern void cpci_irq_init(void); + +static struct irqaction cascade_fpga = + { no_action, SA_INTERRUPT, 0, "cascade via FPGA", NULL, NULL }; +static struct irqaction cascade_mv64340 = + { no_action, SA_INTERRUPT, 0, "cascade via MV64340", NULL, NULL }; + +void __init init_IRQ(void) +{ + int i; + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + __cli(); + + /* Sets the first-level interrupt dispatcher. */ + set_except_vector(0, ocelot_handle_int); + init_generic_irq(); + + /* set up handler for first 8 IRQs as the CPU */ + for (i = 0; i < 8; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &cp7000_hpcdma_irq_type; + } + + /* set up the cascading interrupts */ + setup_irq(3, &cascade_fpga); + setup_irq(5, &cascade_fpga); + setup_irq(6, &cascade_mv64340); + + mv64340_irq_init(); + uart_irq_init(); + cpci_irq_init(); + +#ifdef CONFIG_KGDB + printk("start kgdb ...\n"); + set_debug_traps(); + breakpoint(); /* you may move this line to whereever you want :-) */ +#endif +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif +} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/mv-irq.c linux-2.4.22/arch/mips/momentum/ocelot_c/mv-irq.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/mv-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/mv-irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,164 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/mv-irq.c + * Interrupt routines for mv64340. Interrupt numbers are assigned from + * MV64340_IRQ_BASE to MV64340_IRQ_BASE+64. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MV64340_IRQ_BASE 16 + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 1 is enable, 0 is disable */ +static inline void mask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value &= ~(1 << (irq - MV64340_IRQ_BASE)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value &= ~(1 << (irq - (MV64340_IRQ_BASE - 32))); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* unmask an interrupt -- 1 is enable, 0 is disable */ +static inline void unmask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value |= 1 << (irq - MV64340_IRQ_BASE); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value |= 1 << (irq - (MV64340_IRQ_BASE - 32)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* + * Enables the IRQ on Marvell Chip + */ +static void enable_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); +} + +/* + * Initialize the IRQ on Marvell Chip + */ +static unsigned int startup_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); + return 0; +} + +/* + * Disables the IRQ on Marvell Chip + */ +static void disable_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_mv64340_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_mv64340_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the Marvell chip. + * It could be built in ethernet ports etc... + */ +void ll_mv64340_irq(struct pt_regs *regs) +{ + unsigned int irq_src_low, irq_src_high; + unsigned int irq_mask_low, irq_mask_high; + + /* read the interrupt status registers */ + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &irq_mask_low); + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &irq_mask_high); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW, &irq_src_low); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH, &irq_src_high); + + /* mask for just the interrupts we want */ + irq_src_low &= irq_mask_low; + irq_src_high &= irq_mask_high; + + if (irq_src_low) + do_IRQ(ls1bit32(irq_src_low) + MV64340_IRQ_BASE, regs); + else + do_IRQ(ls1bit32(irq_src_high) + MV64340_IRQ_BASE + 32, regs); +} + +#define shutdown_mv64340_irq disable_mv64340_irq + +struct hw_interrupt_type mv64340_irq_type = { + "MV-64340", + startup_mv64340_irq, + shutdown_mv64340_irq, + enable_mv64340_irq, + disable_mv64340_irq, + mask_and_ack_mv64340_irq, + end_mv64340_irq, + NULL +}; + +void mv64340_irq_init(void) +{ + int i; + + /* Reset irq handlers pointers to NULL */ + for (i = MV64340_IRQ_BASE; i < (MV64340_IRQ_BASE + 64); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &mv64340_irq_type; + } +} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h linux-2.4.22/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h --- linux-2.4.21/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,50 @@ +/* + * Ocelot-C Board Register Definitions + * + * (C) 2002 Momentum Computer Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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 __OCELOT_C_FPGA_H__ +#define __OCELOT_C_FPGA_H__ + +#define OCELOT_C_CS0_ADDR (0xfc000000) + +#define OCELOT_C_REG_BOARDREV 0x0 +#define OCELOT_C_REG_FPGA_REV 0x1 +#define OCELOT_C_REG_FPGA_TYPE 0x2 +#define OCELOT_C_REG_RESET_STATUS 0x3 +#define OCELOT_C_REG_BOARD_STATUS 0x4 +#define OCELOT_C_REG_CPCI_ID 0x5 +#define OCELOT_C_REG_SET 0x6 +#define OCELOT_C_REG_CLR 0x7 +#define OCELOT_C_REG_EEPROM_MODE 0x9 +#define OCELOT_C_REG_INTMASK 0xa +#define OCELOT_C_REG_INTSTAT 0xb +#define OCELOT_C_REG_UART_INTMASK 0xc +#define OCELOT_C_REG_UART_INTSTAT 0xd +#define OCELOT_C_REG_INTSET 0xe +#define OCELOT_C_REG_INTCLR 0xf + +#define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y) +#define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x) + +#endif diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/pci-irq.c linux-2.4.22/arch/mips/momentum/ocelot_c/pci-irq.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/pci-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/pci-irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/ocelot_g/pci.c + * Board-specific PCI routines for mv64340 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include + + +void __init mv64340_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + /* loop over all known devices on this bus */ + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1) && + (PCI_FUNC(devices->devfn) == 0)) { + /* LSI 53C10101R SCSI (A) */ + devices->irq = 2; + } else if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1) && + (PCI_FUNC(devices->devfn) == 1)) { + /* LSI 53C10101R SCSI (B) */ + devices->irq = 2; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 1)) { + /* Intel 21555 bridge */ + devices->irq = 12; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 2)) { + /* PMC Slot */ + devices->irq = 4; + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); + + /* enable master for everything but the MV-64340 */ + if (((current_bus->number != 0) && (current_bus->number != 1)) + || (PCI_SLOT(devices->devfn) != 0)) { + bus->ops->read_word(devices, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write_word(devices, PCI_COMMAND, cmd); + } + } +} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/pci.c linux-2.4.22/arch/mips/momentum/ocelot_c/pci.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,363 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_PCI + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define MAX_PCI_DEVS 10 + +void mv64340_board_pcibios_fixup_bus(struct pci_bus* c); + +/* Functions to implement "pci ops" */ +static int marvell_pcibios_read_config_word(struct pci_dev *dev, + int offset, u16 * val); +static int marvell_pcibios_read_config_byte(struct pci_dev *dev, + int offset, u8 * val); +static int marvell_pcibios_read_config_dword(struct pci_dev *dev, + int offset, u32 * val); +static int marvell_pcibios_write_config_byte(struct pci_dev *dev, + int offset, u8 val); +static int marvell_pcibios_write_config_word(struct pci_dev *dev, + int offset, u16 val); +static int marvell_pcibios_write_config_dword(struct pci_dev *dev, + int offset, u32 val); + +/* + * General-purpose PCI functions. + */ + + +/* + * pci_range_ck - + * + * Check if the pci device that are trying to access does really exists + * on the evaluation board. + * + * Inputs : + * bus - bus number (0 for PCI 0 ; 1 for PCI 1) + * dev - number of device on the specific pci bus + * + * Outpus : + * 0 - if OK , 1 - if failure + */ +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* Accessing device 31 crashes the MV-64340. */ + if (dev < 5) + return 0; + return -1; +} + +/* + * marvell_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + +static int marvell_pcibios_read_config_dword(struct pci_dev *device, + int offset, u32* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int marvell_pcibios_read_config_word(struct pci_dev *device, + int offset, u16* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_read_config_byte(struct pci_dev *device, + int offset, u8* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_READ_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_write_config_dword(struct pci_dev *device, + int offset, u32 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int marvell_pcibios_write_config_word(struct pci_dev *device, + int offset, u16 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_write_config_byte(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops marvell_pci_ops = { + marvell_pcibios_read_config_byte, + marvell_pcibios_read_config_word, + marvell_pcibios_read_config_dword, + marvell_pcibios_write_config_byte, + marvell_pcibios_write_config_word, + marvell_pcibios_write_config_dword +}; + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +void __init pcibios_fixup_bus(struct pci_bus *c) +{ + mv64340_board_pcibios_fixup_bus(c); +} + +void __init pcibios_init(void) +{ + /* Reset PCI I/O and PCI MEM values */ + ioport_resource.start = 0xe0000000; + ioport_resource.end = 0xe0000000 + 0x20000000 - 1; + iomem_resource.start = 0xc0000000; + iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + + pci_scan_bus(0, &marvell_pci_ops, NULL); + pci_scan_bus(1, &marvell_pci_ops, NULL); +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/prom.c linux-2.4.22/arch/mips/momentum/ocelot_c/prom.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,151 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ocelot_c_fpga.h" + +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; + +struct callvectors* debug_vectors; +char arcs_cmdline[CL_SIZE]; + +extern unsigned long mv64340_base; +extern unsigned long cpu_clock; + +#ifdef CONFIG_MV64340_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + +const char *get_system_type(void) +{ +#ifdef CONFIG_CPU_SR71000 + return "Momentum Ocelot-CS"; +#else + return "Momentum Ocelot-C"; +#endif +} + +#ifdef CONFIG_MV64340_ETH +static void burn_clocks(void) +{ + int i; + + /* this loop should burn at least 1us -- this should be plenty */ + for (i = 0; i < 0x10000; i++) + ; +} + +static u8 exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + burn_clocks(); + + /* turn the clock on */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + burn_clocks(); + + /* turn the clock off and read-strobe */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); +} + +void get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} +#endif + +/* [jsun@junsun.net] PMON passes arguments in C main() style */ +void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) +{ + int i; + + /* save the PROM vectors for debugging use */ + debug_vectors = cv; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, arg[i]); + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_MOMENCO; + mips_machtype = MACH_MOMENCO_OCELOT_C; + + while (*env) { + if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { + mv64340_base = simple_strtol(*env + strlen("gtbase="), + NULL, 16); + } + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { + cpu_clock = simple_strtol(*env + strlen("cpuclock="), + NULL, 10); + } + env++; + } + +#ifdef CONFIG_MV64340_ETH + /* get the base MAC address for on-board ethernet ports */ + get_mac(prom_mac_addr_base); +#endif + + debug_vectors->printf("Booting Linux kernel...\n"); +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/reset.c linux-2.4.22/arch/mips/momentum/ocelot_c/reset.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,50 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Copyright (C) 1997, 2001 Ralf Baechle + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2002 Momentum Computer Inc. + * Author: Matthew Dharm + */ +#include +#include +#include +#include +#include +#include +#include +#include + +void momenco_ocelot_restart(char *command) +{ + /* base address of timekeeper portion of part */ + void *nvram = (void*) 0xfc807000; + + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ + writeb(0x84, nvram + 0xff7); + + /* wait for the watchdog to go off */ + mdelay(100+(1000/16)); + + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); +} + +void momenco_ocelot_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void momenco_ocelot_power_off(void) +{ + momenco_ocelot_halt(); +} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/setup.c linux-2.4.22/arch/mips/momentum/ocelot_c/setup.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,330 @@ +/* + * setup.c + * + * BRIEF MODULE DESCRIPTION + * Momentum Computer Ocelot-C and -CS board dependent boot routines + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Copyright (C) 2001 Red Hat, Inc. + * Copyright (C) 2002 Momentum Computer + * + * Author: Matthew Dharm, Momentum Computer + * mdharm@momenco.com + * + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +unsigned long mv64340_base; +unsigned long cpu_clock; + +/* These functions are used for rebooting or halting the machine*/ +extern void momenco_ocelot_restart(char *command); +extern void momenco_ocelot_halt(void); +extern void momenco_ocelot_power_off(void); + +void momenco_time_init(void); + +static char reset_reason; + +#define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1) + +/* setup code for a handoff from a version 2 PMON 2000 PROM */ +void PMON_v2_setup(void) +{ + /* Some wired TLB entries for the MV64340 and perhiperals. The + MV64340 is going to be hit on every IRQ anyway - there's + absolutely no point in letting it be a random TLB entry, as + it'll just cause needless churning of the TLB. And we use + the other half for the serial port, which is just a PITA + otherwise :) + + Device Physical Virtual + MV64340 Internal Regs 0xf4000000 0xf4000000 + Ocelot-C[S] PLD (CS0) 0xfc000000 0xfc000000 + NVRAM (CS1) 0xfc800000 0xfc800000 + UARTs (CS2) 0xfd000000 0xfd000000 + Internal SRAM 0xfe000000 0xfe000000 + M-Systems DOC (CS3) 0xff000000 0xff000000 + */ + + /* marvell and extra space */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); + /* fpga, rtc, and uart */ + add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M); + /* m-sys and internal SRAM */ + add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); + + mv64340_base = 0xf4000000; +} + +#define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) +#define CONV_BIN_TO_BCD(val) (((val) % 10) + (((val) / 10) << 4)) + +unsigned long m48t37y_get_time(void) +{ + unsigned char* rtc_base = (unsigned char*)0xfc800000; + unsigned int year, month, day, hour, min, sec; + + /* stop the update */ + rtc_base[0x7ff8] = 0x40; + + year = CONV_BCD_TO_BIN(rtc_base[0x7fff]); + year += CONV_BCD_TO_BIN(rtc_base[0x7ff1]) * 100; + + month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]); + + day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]); + + hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]); + min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]); + sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]); + + /* start the update */ + rtc_base[0x7ff8] = 0x00; + + return mktime(year, month, day, hour, min, sec); +} + +int m48t37y_set_time(unsigned long sec) +{ + unsigned char* rtc_base = (unsigned char*)0xfc800000; + struct rtc_time tm; + + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; + + /* enable writing */ + rtc_base[0x7ff8] = 0x80; + + /* year */ + rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100); + + /* month */ + rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon); + + /* day */ + rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday); + + /* hour/min/sec */ + rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour); + rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min); + rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec); + + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1); + + /* disable writing */ + rtc_base[0x7ff8] = 0x00; + + return 0; +} + +void momenco_timer_setup(struct irqaction *irq) +{ + setup_irq(7, irq); +} + +void momenco_time_init(void) +{ +#ifdef CONFIG_CPU_SR71000 + mips_counter_frequency = cpu_clock; +#elif defined(CONFIG_CPU_RM7000) + mips_counter_frequency = cpu_clock / 2; +#else +#error Unknown CPU for this board +#endif + board_timer_setup = momenco_timer_setup; + + rtc_get_time = m48t37y_get_time; + rtc_set_time = m48t37y_set_time; +} + +void __init momenco_ocelot_c_setup(void) +{ + unsigned int tmpword; + + board_time_init = momenco_time_init; + + _machine_restart = momenco_ocelot_restart; + _machine_halt = momenco_ocelot_halt; + _machine_power_off = momenco_ocelot_power_off; + + /* + * initrd_start = (ulong)ocelot_initrd_start; + * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; + * initrd_below_start_ok = 1; + */ + + /* do handoff reconfiguration */ + PMON_v2_setup(); + + /* shut down ethernet ports, just to be sure our memory doesn't get + * corrupted by random ethernet traffic. + */ + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); + + /* Turn off the Bit-Error LED */ + OCELOT_FPGA_WRITE(0x80, CLR); + + tmpword = OCELOT_FPGA_READ(BOARDREV); +#ifdef CONFIG_CPU_SR71000 + if (tmpword < 26) + printk("Momenco Ocelot-CS: Board Assembly Rev. %c\n", + 'A'+tmpword); + else + printk("Momenco Ocelot-CS: Board Assembly Revision #0x%x\n", + tmpword); +#else + if (tmpword < 26) + printk("Momenco Ocelot-C: Board Assembly Rev. %c\n", + 'A'+tmpword); + else + printk("Momenco Ocelot-C: Board Assembly Revision #0x%x\n", + tmpword); +#endif + + tmpword = OCELOT_FPGA_READ(FPGA_REV); + printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15); + tmpword = OCELOT_FPGA_READ(RESET_STATUS); + printk("Reset reason: 0x%x\n", tmpword); + switch (tmpword) { + case 0x1: + printk(" - Power-up reset\n"); + break; + case 0x2: + printk(" - Push-button reset\n"); + break; + case 0x4: + printk(" - cPCI bus reset\n"); + break; + case 0x8: + printk(" - Watchdog reset\n"); + break; + case 0x10: + printk(" - Software reset\n"); + break; + default: + printk(" - Unknown reset cause\n"); + } + reset_reason = tmpword; + OCELOT_FPGA_WRITE(0xff, RESET_STATUS); + + tmpword = OCELOT_FPGA_READ(CPCI_ID); + printk("cPCI ID register: 0x%02x\n", tmpword); + printk(" - Slot number: %d\n", tmpword & 0x1f); + printk(" - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no"); + printk(" - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no"); + + tmpword = OCELOT_FPGA_READ(BOARD_STATUS); + printk("Board Status register: 0x%02x\n", tmpword); + printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); + printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); + printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1); + printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3))); + + switch(tmpword &3) { + case 3: + /* 512MiB */ + add_memory_region(0x0, 0x200<<20, BOOT_MEM_RAM); + break; + case 2: + /* 256MiB */ + add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM); + break; + case 1: + /* 128MiB */ + add_memory_region(0x0, 0x80<<20, BOOT_MEM_RAM); + break; + case 0: + /* 1GiB -- needs CONFIG_HIGHMEM */ + add_memory_region(0x0, 0x400<<20, BOOT_MEM_RAM); + break; + } +} + +/* This needs to be one of the first initcalls, because no I/O port access + can work before this */ +static int io_base_ioremap(void) +{ + /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ + void *io_remap_range = ioremap(0xc0000000, 0x30000000); + + if (!io_remap_range) { + panic("Could not ioremap I/O port range"); + } + printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); + + return 0; +} + +module_init(io_base_ioremap); diff -urN linux-2.4.21/arch/mips/momentum/ocelot_c/uart-irq.c linux-2.4.22/arch/mips/momentum/ocelot_c/uart-irq.c --- linux-2.4.21/arch/mips/momentum/ocelot_c/uart-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_c/uart-irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,148 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/uart-irq.c + * Interrupt routines for UARTs. Interrupt numbers are assigned from + * 80 to 81 (2 interrupt sources). + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +static inline int ls1bit8(unsigned int x) +{ + int b = 7, s; + + s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; + s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; + s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 0 is enable, 1 is disable */ +static inline void mask_uart_irq(unsigned int irq) +{ + uint8_t value; + + value = OCELOT_FPGA_READ(UART_INTMASK); + value |= 1 << (irq - 74); + OCELOT_FPGA_WRITE(value, UART_INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(UART_INTMASK); +} + +/* unmask an interrupt -- 0 is enable, 1 is disable */ +static inline void unmask_uart_irq(unsigned int irq) +{ + uint8_t value; + + value = OCELOT_FPGA_READ(UART_INTMASK); + value &= ~(1 << (irq - 74)); + OCELOT_FPGA_WRITE(value, UART_INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(UART_INTMASK); +} + +/* + * Enables the IRQ in the FPGA + */ +static void enable_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_uart_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_uart_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the FPGA chip. + */ +void ll_uart_irq(struct pt_regs *regs) +{ + unsigned int irq_src, irq_mask; + + /* read the interrupt status registers */ + irq_src = OCELOT_FPGA_READ(UART_INTSTAT); + irq_mask = OCELOT_FPGA_READ(UART_INTMASK); + + /* mask for just the interrupts we want */ + irq_src &= ~irq_mask; + + do_IRQ(ls1bit8(irq_src) + 74, regs); +} + +#define shutdown_uart_irq disable_uart_irq + +struct hw_interrupt_type uart_irq_type = { + "UART/FPGA", + startup_uart_irq, + shutdown_uart_irq, + enable_uart_irq, + disable_uart_irq, + mask_and_ack_uart_irq, + end_uart_irq, + NULL +}; + +void uart_irq_init(void) +{ + /* Reset irq handlers pointers to NULL */ + irq_desc[80].status = IRQ_DISABLED; + irq_desc[80].action = 0; + irq_desc[80].depth = 2; + irq_desc[80].handler = &uart_irq_type; + + irq_desc[81].status = IRQ_DISABLED; + irq_desc[81].action = 0; + irq_desc[81].depth = 2; + irq_desc[81].handler = &uart_irq_type; +} diff -urN linux-2.4.21/arch/mips/momentum/ocelot_g/Makefile linux-2.4.22/arch/mips/momentum/ocelot_g/Makefile --- linux-2.4.21/arch/mips/momentum/ocelot_g/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_g/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,15 +6,12 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= ocelot_g.o -obj-y += gt-irq.o pci-irq.o pci.o int-handler.o irq.o prom.o reset.o setup.o - -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-y += gt-irq.o pci-irq.o int-handler.o irq.o prom.o reset.o setup.o +obj-$(CONFIG_KGDB) += dbg_io.o +obj-$(CONFIG_PCI) += pci.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/momentum/ocelot_g/dbg_io.c linux-2.4.22/arch/mips/momentum/ocelot_g/dbg_io.c --- linux-2.4.21/arch/mips/momentum/ocelot_g/dbg_io.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_g/dbg_io.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ #include -#if defined(CONFIG_REMOTE_DEBUG) +#if defined(CONFIG_KGDB) #include /* For the serial port location and base baud */ diff -urN linux-2.4.21/arch/mips/momentum/ocelot_g/irq.c linux-2.4.22/arch/mips/momentum/ocelot_g/irq.c --- linux-2.4.21/arch/mips/momentum/ocelot_g/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_g/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -60,18 +60,18 @@ /* do the low 8 bits first */ clr_mask = 0xff & clr_mask_in; set_mask = 0xff & set_mask_in; - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); /* do the high 8 bits */ clr_mask = 0xff & (clr_mask_in >> 8); set_mask = 0xff & (set_mask_in >> 8); - status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); + status = read_c0_intcontrol(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); + write_c0_intrcontrol(status); } static inline void mask_irq(unsigned int irq) @@ -145,7 +145,7 @@ * Clear all of the interrupts while we change the able around a bit. * int-handler is not on bootstrap */ - clear_cp0_status(ST0_IM | ST0_BEV); + clear_c0_status(ST0_IM | ST0_BEV); __cli(); /* Sets the first-level interrupt dispatcher. */ @@ -161,7 +161,7 @@ gt64240_irq_init(); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("start kgdb ...\n"); set_debug_traps(); breakpoint(); /* you may move this line to whereever you want :-) */ diff -urN linux-2.4.21/arch/mips/momentum/ocelot_g/ocelot_pld.h linux-2.4.22/arch/mips/momentum/ocelot_g/ocelot_pld.h --- linux-2.4.21/arch/mips/momentum/ocelot_g/ocelot_pld.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_g/ocelot_pld.h 2003-08-25 04:44:40.000000000 -0700 @@ -8,11 +8,7 @@ #ifndef __MOMENCO_OCELOT_PLD_H__ #define __MOMENCO_OCELOT_PLD_H__ -#if 0 -#define OCELOT_CS0_ADDR (0xe0020000) -#else #define OCELOT_CS0_ADDR (0xfc000000) -#endif #define OCELOT_REG_BOARDREV (0) #define OCELOT_REG_PLD1_ID (1) diff -urN linux-2.4.21/arch/mips/momentum/ocelot_g/pci.c linux-2.4.22/arch/mips/momentum/ocelot_g/pci.c --- linux-2.4.21/arch/mips/momentum/ocelot_g/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_g/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -34,8 +34,6 @@ #include -#ifdef CONFIG_PCI - #define SELF 0 #define MASTER_ABORT_BIT 0x100 @@ -61,7 +59,6 @@ int offset, u16 val); static int galileo_pcibios_write_config_dword(struct pci_dev *dev, int offset, u32 val); -static void galileo_pcibios_set_master(struct pci_dev *dev); /* * General-purpose PCI functions. @@ -345,128 +342,6 @@ return PCIBIOS_SUCCESSFUL; } -static void galileo_pcibios_set_master(struct pci_dev *dev) -{ - u16 cmd; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); -} - -/* Externally-expected functions. Do not change function names */ - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - u8 tmp1; - int idx; - struct resource *r; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of " - "resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - } - - /* - * Let's fix up the latency timer and cache line size here. Cache - * line size = 32 bytes / sizeof dword (4) = 8. - * Latency timer must be > 8. 32 is random but appears to work. - */ - galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); - if (tmp1 != 8) { - printk(KERN_WARNING "PCI setting cache line size to 8 from " - "%d\n", tmp1); - galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - 8); - } - galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); - if (tmp1 < 32) { - printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", - tmp1); - galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, - 32); - } - - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - return; - -#if 0 - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* - * Somebody might have asked allocation of a non-standard - * resource - */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -#endif -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - struct pci_ops galileo_pci_ops = { galileo_pcibios_read_config_byte, galileo_pcibios_read_config_word, @@ -534,9 +409,6 @@ GT_WRITE(PCI_1P2P_CONFIGURATION, regData); } -#define PCI0_STATUS_COMMAND_REG 0x4 -#define PCI1_STATUS_COMMAND_REG 0x84 - void __init pcibios_init(void) { /* Reset PCI I/O and PCI MEM values */ @@ -549,20 +421,7 @@ pci_scan_bus(1, &galileo_pci_ops, NULL); } -/* - * for parsing "pci=" kernel boot arguments. - */ -char *pcibios_setup(char *str) -{ - printk(KERN_INFO "rr: pcibios_setup\n"); - /* Nothing to do for now. */ - - return str; -} - unsigned __init int pcibios_assign_all_busses(void) { return 1; } - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/momentum/ocelot_g/setup.c linux-2.4.22/arch/mips/momentum/ocelot_g/setup.c --- linux-2.4.21/arch/mips/momentum/ocelot_g/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/momentum/ocelot_g/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -70,6 +70,10 @@ extern struct rtc_ops no_rtc_ops; +#ifdef CONFIG_GALILLEO_GT64240_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + unsigned long gt64240_base; /* These functions are used for rebooting or halting the machine*/ @@ -86,8 +90,6 @@ static void __init setup_l3cache(unsigned long size); -void __init bus_error_init(void) { /* nothing */ } - /* setup code for a handoff from a version 2 PMON 2000 PROM */ void PMON_v2_setup(void) { @@ -139,6 +141,11 @@ /* do handoff reconfiguration */ PMON_v2_setup(); +#ifdef CONFIG_GALILLEO_GT64240_ETH + /* get the mac addr */ + memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6); +#endif + /* Turn off the Bit-Error LED */ OCELOT_PLD_WRITE(0x80, INTCLR); @@ -213,11 +220,11 @@ GT_WRITE(0, tmp | (1<<14)); /* Enable the L3 cache in the CPU */ - set_cp0_config(1<<12 /* CONF_TE */); + set_c0_config(1<<12 /* CONF_TE */); /* Clear the cache */ - set_taglo(0); - set_taghi(0); + write_c0_taglo(0); + write_c0_taghi(0); for (i=0; i < size; i+= 4096) { __asm__ __volatile__ ( diff -urN linux-2.4.21/arch/mips/pci/Makefile linux-2.4.22/arch/mips/pci/Makefile --- linux-2.4.21/arch/mips/pci/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,21 @@ +# +# Makefile for the Linux/MIPS kernel. +# +# 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). +# + +O_TARGET := pci-core.o + +export-objs = pci.o + +obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o +obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o +obj-$(CONFIG_MIPS_MSC) += ops-msc.o +obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o +obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o +obj-y += pci.o +obj-$(CONFIG_PCI_AUTO) += pci_auto.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/pci/ops-bonito64.c linux-2.4.22/arch/mips/pci/ops-bonito64.c --- linux-2.4.21/arch/mips/pci/ops-bonito64.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/ops-bonito64.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,224 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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 + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +static int bonito64_config_access(unsigned char access_type, + struct pci_dev *dev, unsigned char where, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + unsigned char type; + u32 intr, dummy; + u64 pci_addr; + + if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) + return -1; + + /* Clear cause register bits */ + BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR); + + /* + * Setup pattern to be used as PCI "address" for Type 0 cycle + */ + if (bus == 0) { + /* IDSEL */ + pci_addr = (u64)1 << (PCI_SLOT(dev_fn) + 10); + } else { + /* Bus number */ + pci_addr = bus << PCI_CFG_TYPE1_BUS_SHF; + + /* Device number */ + pci_addr |= PCI_SLOT(dev_fn) << PCI_CFG_TYPE1_DEV_SHF; + } + + /* Function (same for Type 0/1) */ + pci_addr |= PCI_FUNC(dev_fn) << PCI_CFG_TYPE0_FUNC_SHF; + + /* Register number (same for Type 0/1) */ + pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF; + + if (bus == 0) { + /* Type 0 */ + BONITO_PCIMAP_CFG = pci_addr >> 16; + } else { + /* Type 1 */ + BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; + } + + /* Flush Bonito register block */ + dummy = BONITO_PCIMAP_CFG; + iob(); /* sync */ + + /* Perform access */ + if (access_type == PCI_ACCESS_WRITE) { + *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + + (pci_addr & 0xffff))) = *(u32 *)data; + + /* Wait till done */ + while (BONITO_PCIMSTAT & 0xF) + ; + } else { + *(u32 *)data = + *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + + (pci_addr & 0xffff))); + } + + /* Detect Master/Target abort */ + if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | + BONITO_PCICMD_MTABORT_CLR)) { + /* Error occurred */ + + /* Clear bits */ + BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | + BONITO_PCICMD_MTABORT_CLR); + + return -1; + } + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int bonito64_read_config_byte (struct pci_dev *dev, int where, + u8 *val) +{ + u32 data = 0; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xff; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_read_config_word (struct pci_dev *dev, int where, + u16 *val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xffff; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_read_config_dword (struct pci_dev *dev, int where, + u32 *val) +{ + u32 data = 0; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_write_config_byte (struct pci_dev *dev, int where, + u8 val) +{ + u32 data = 0; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_write_config_word (struct pci_dev *dev, int where, + u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops bonito64_pci_ops = { + bonito64_read_config_byte, + bonito64_read_config_word, + bonito64_read_config_dword, + bonito64_write_config_byte, + bonito64_write_config_word, + bonito64_write_config_dword +}; diff -urN linux-2.4.21/arch/mips/pci/ops-gt64120.c linux-2.4.22/arch/mips/pci/ops-gt64120.c --- linux-2.4.21/arch/mips/pci/ops-gt64120.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/ops-gt64120.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,204 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include + +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +#define GT_ERR_BITS (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT) + +static int gt64120_config_access(unsigned int access_type, + struct pci_dev *dev, unsigned char where, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + u32 intr, ret; + + /* + * Because of a bug in the galileo (for slot 31) and support for the + * 2nd bus of the Galileo is broken anyway ... + */ + if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* Clear cause register bits */ + intr = GT_READ(GT_INTRCAUSE_OFS); + GT_WRITE(GT_INTRCAUSE_OFS, intr & ~GT_ERR_BITS); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + (where & ~0x3) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + if (access_type == PCI_ACCESS_WRITE) { + if (bus == 0 && PCI_SLOT(dev_fn) == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else + __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else { + if (bus == 0 && PCI_SLOT(dev_fn) == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + ret = GT_READ(GT_PCI0_CFGDATA_OFS); + } else + ret = __GT_READ(GT_PCI0_CFGDATA_OFS); + } + + /* Check for master or target abort */ + intr = GT_READ(GT_INTRCAUSE_OFS); + + if (intr & GT_ERR_BITS) { /* Error occured */ + + /* Clear bits */ + intr = GT_READ(GT_INTRCAUSE_OFS); + GT_WRITE(GT_INTRCAUSE_OFS, intr & ~GT_ERR_BITS); + + return PCIBIOS_DEVICE_NOT_FOUND; + } + + *data = ret; + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int gt64120_read_config_byte (struct pci_dev *dev, int where, u8 *val) +{ + u32 data; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + *val = data >> ((where & 3) << 3); + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_read_config_word (struct pci_dev *dev, int where, u16 *val) +{ + u32 data; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + *val = data >> ((where & 3) << 3); + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_read_config_dword (struct pci_dev *dev, int where, u32 *val) +{ + u32 data; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_write_config_byte (struct pci_dev *dev, int where, u8 val) +{ + u32 data = 0; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt64120_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_write_config_word (struct pci_dev *dev, int where, u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt64120_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops gt64120_pci_ops = { + gt64120_read_config_byte, + gt64120_read_config_word, + gt64120_read_config_dword, + gt64120_write_config_byte, + gt64120_write_config_word, + gt64120_write_config_dword +}; diff -urN linux-2.4.21/arch/mips/pci/ops-msc.c linux-2.4.22/arch/mips/pci/ops-msc.c --- linux-2.4.21/arch/mips/pci/ops-msc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/ops-msc.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,201 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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 + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +static int msc_config_access(unsigned char access_type, + struct pci_dev *dev, unsigned char where, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + unsigned char type; + u32 intr, dummy; + u64 pci_addr; + + if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) + return -1; + + /* Clear status register bits. */ + MSC_WRITE(MSC01_PCI_INTSTAT, + (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)); + + /* Setup address */ + if (bus == 0) + type = 0; /* Type 0 */ + else + type = 1; /* Type 1 */ + + MSC_WRITE(MSC01_PCI_CFGADDR, + ((bus << MSC01_PCI_CFGADDR_BNUM_SHF) | + (PCI_SLOT(dev_fn) << MSC01_PCI_CFGADDR_DNUM_SHF) | + (PCI_FUNC(dev_fn) << MSC01_PCI_CFGADDR_FNUM_SHF) | + ((where /4 ) << MSC01_PCI_CFGADDR_RNUM_SHF) | + (type))); + + /* Perform access */ + if (access_type == PCI_ACCESS_WRITE) { + MSC_WRITE(MSC01_PCI_CFGDATA, *data); + } else { + MSC_READ(MSC01_PCI_CFGDATA, *data); + } + + /* Detect Master/Target abort */ + MSC_READ(MSC01_PCI_INTSTAT, intr); + if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) { + /* Error occurred */ + + /* Clear bits */ + MSC_READ(MSC01_PCI_INTSTAT, intr); + MSC_WRITE(MSC01_PCI_INTSTAT, + (MSC01_PCI_INTCFG_MA_BIT | + MSC01_PCI_INTCFG_TA_BIT)); + + return -1; + } + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int msc_read_config_byte (struct pci_dev *dev, int where, + u8 *val) +{ + u32 data = 0; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xff; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_read_config_word (struct pci_dev *dev, int where, + u16 *val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xffff; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_read_config_dword (struct pci_dev *dev, int where, + u32 *val) +{ + u32 data = 0; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_write_config_byte (struct pci_dev *dev, int where, + u8 val) +{ + u32 data = 0; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (msc_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_write_config_word (struct pci_dev *dev, int where, + u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (msc_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops msc_pci_ops = { + msc_read_config_byte, + msc_read_config_word, + msc_read_config_dword, + msc_write_config_byte, + msc_write_config_word, + msc_write_config_dword +}; diff -urN linux-2.4.21/arch/mips/pci/ops-nile4.c linux-2.4.22/arch/mips/pci/ops-nile4.c --- linux-2.4.21/arch/mips/pci/ops-nile4.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/ops-nile4.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,213 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define LO(reg) (reg / 4) +#define HI(reg) (reg / 4 + 1) + +static volatile unsigned long * const vrc_pciregs = (void *)Vrc5074_BASE; + +static spinlock_t nile4_pci_lock; + +static int nile4_pcibios_config_access(unsigned char access_type, + struct pci_dev *dev, unsigned char reg, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + u32 adr, mask, err; + + if ((bus == 0) && (PCI_SLOT(dev_fn) > 8)) + /* The addressing scheme chosen leaves room for just + * 8 devices on the first bus (besides the PCI + * controller itself) */ + return PCIBIOS_DEVICE_NOT_FOUND; + + if ((bus == 0) && (dev_fn == PCI_DEVFN(0,0))) { + /* Access controller registers directly */ + if (access_type == PCI_ACCESS_WRITE) { + vrc_pciregs[(0x200+reg) >> 2] = *data; + } else { + *data = vrc_pciregs[(0x200+reg) >> 2]; + } + return PCIBIOS_SUCCESSFUL; + } + + /* Temporarily map PCI Window 1 to config space */ + mask = vrc_pciregs[LO(NILE4_PCIINIT1)]; + vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (bus ? 0x200 : 0); + + /* Clear PCI Error register. This also clears the Error Type + * bits in the Control register */ + vrc_pciregs[LO(NILE4_PCIERR)] = 0; + vrc_pciregs[HI(NILE4_PCIERR)] = 0; + + /* Setup address */ + if (bus == 0) + adr = KSEG1ADDR(PCI_WINDOW1) + + ((1 << (PCI_SLOT(dev_fn) + 15)) | + (PCI_FUNC(dev_fn) << 8) | (reg & ~3)); + else + adr = KSEG1ADDR(PCI_WINDOW1) | (bus << 16) | (dev_fn << 8) | + (reg & ~3); + + if (access_type == PCI_ACCESS_WRITE) + *(u32 *)adr = *data; + else + *data = *(u32 *)adr; + + /* Check for master or target abort */ + err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7; + + /* Restore PCI Window 1 */ + vrc_pciregs[LO(NILE4_PCIINIT1)] = mask; + + if (err) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int nile4_pcibios_read_config_byte(struct pci_dev *dev, int reg, u8 *val) +{ + unsigned long flags; + u32 data = 0; + int err; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return err; + + *val = (data >> ((reg & 3) << 3)) & 0xff; + + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pcibios_read_config_word(struct pci_dev *dev, int reg, u16 *val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return err; + + *val = (data >> ((reg & 3) << 3)) & 0xffff; + + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pcibios_read_config_dword(struct pci_dev *dev, int reg, u32 *val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return err; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + + +static int nile4_pcibios_write_config_byte(struct pci_dev *dev, int reg, u8 val) +{ + unsigned long flags; + u32 data = 0; + int err; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + if (err) + goto out; + + data = (data & ~(0xff << ((reg & 3) << 3))) | (val << ((reg & 3) << 3)); + err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &data); + +out: + spin_unlock_irqrestore(&nile4_pci_lock, flags); + return err; +} + +static int nile4_pcibios_write_config_word(struct pci_dev *dev, int reg, u16 val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + if (err) + goto out; + + data = (data & ~(0xffff << ((reg & 3) << 3))) | (val << ((reg&3) << 3)); + err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &data); + +out: + spin_unlock_irqrestore(&nile4_pci_lock, flags); + return err; +} + +static int nile4_pcibios_write_config_dword(struct pci_dev *dev, int reg, u32 val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &val); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return -1; + else + return PCIBIOS_SUCCESSFUL; +out: + return err; +} + +struct pci_ops nile4_pci_ops = { + nile4_pcibios_read_config_byte, + nile4_pcibios_read_config_word, + nile4_pcibios_read_config_dword, + nile4_pcibios_write_config_byte, + nile4_pcibios_write_config_word, + nile4_pcibios_write_config_dword +}; diff -urN linux-2.4.21/arch/mips/pci/ops-sni.c linux-2.4.22/arch/mips/pci/ops-sni.c --- linux-2.4.21/arch/mips/pci/ops-sni.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/ops-sni.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,113 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SNI specific PCI support for RM200/RM300. + * + * Copyright (C) 1997 - 2000, 2003 Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include + +#define mkaddr(dev, where) \ +do { \ + if ((dev)->bus->number == 0) \ + return -1; \ + *(volatile u32 *)PCIMT_CONFIG_ADDRESS = \ + ((dev->bus->number & 0xff) << 0x10) | \ + ((dev->devfn & 0xff) << 0x08) | \ + (where & 0xfc); \ +} while(0) + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int pcimt_read_config_byte (struct pci_dev *dev, + int where, unsigned char *val) +{ + u32 res; + + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_read_config_word (struct pci_dev *dev, + int where, unsigned short *val) +{ + u32 res; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_read_config_dword (struct pci_dev *dev, + int where, unsigned int *val) +{ + u32 res; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = le32_to_cpu(res); + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_byte (struct pci_dev *dev, + int where, unsigned char val) +{ + mkaddr(dev, where); + *(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_word (struct pci_dev *dev, + int where, unsigned short val) +{ + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + *(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val); + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_dword (struct pci_dev *dev, + int where, unsigned int val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + *(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops sni_pci_ops = { + pcimt_read_config_byte, + pcimt_read_config_word, + pcimt_read_config_dword, + pcimt_write_config_byte, + pcimt_write_config_word, + pcimt_write_config_dword +}; diff -urN linux-2.4.21/arch/mips/pci/pci.c linux-2.4.22/arch/mips/pci/pci.c --- linux-2.4.21/arch/mips/pci/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,272 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include + +void +pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + u32 new, check; + int reg; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4*resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + new |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* Somebody might have asked allocation of a non-standard resource */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +void +pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } +} + +/* + * If we set up a device for bus mastering, we need to check the latency + * timer as certain crappy BIOSes forget to set it properly. + */ +unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +char * __devinit pcibios_setup(char *str) +{ + return str; +} + +static int pcibios_enable_resources(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1<resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev, mask); +} + +#ifdef CONFIG_NEW_PCI +/* + * Named PCI new and about to die before it's old :-) + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Modified to be mips generic, ppopov@mvista.com + */ + +/* + * This file contains common PCI routines meant to be shared for + * all MIPS machines. + * + * Strategies: + * + * . We rely on pci_auto.c file to assign PCI resources (MEM and IO) + * TODO: this shold be optional for some machines where they do have + * a real "pcibios" that does resource assignment. + * + * . We then use pci_scan_bus() to "discover" all the resources for + * later use by Linux. + * + * . We finally reply on a board supplied function, pcibios_fixup_irq(), to + * to assign the interrupts. We may use setup-irq.c under drivers/pci + * later. + * + * . Specifically, we will *NOT* use pci_assign_unassigned_resources(), + * because we assume all PCI devices should have the resources correctly + * assigned and recorded. + * + * Limitations: + * + * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus + * into a contiguous range. + * + * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical + * address space. + * + * . In the case of IO space, it starts from 0, and the beginning address + * is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address. + * + * . These are the current MIPS limitations (by ioremap, etc). In the + * future, we may remove them. + * + * Credits: + * Most of the code are derived from the pci routines from PPC and Alpha, + * which were mostly writtne by + * Cort Dougan, cort@fsmlabs.com + * Matt Porter, mporter@mvista.com + * Dave Rusling david.rusling@reo.mts.dec.com + * David Mosberger davidm@cs.arizona.edu + */ + +extern void pcibios_fixup(void); +extern void pcibios_fixup_irqs(void); + +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, + { 0 } +}; + +extern int pciauto_assign_resources(int busno, struct pci_channel * hose); + +void __init pcibios_init(void) +{ + struct pci_channel *p; + struct pci_bus *bus; + int busno; + +#ifdef CONFIG_PCI_AUTO + /* assign resources */ + busno=0; + for (p= mips_pci_channels; p->pci_ops != NULL; p++) { + busno = pciauto_assign_resources(busno, p) + 1; + } +#endif + + /* scan the buses */ + busno = 0; + for (p= mips_pci_channels; p->pci_ops != NULL; p++) { + bus = pci_scan_bus(busno, p->pci_ops, p); + busno = bus->subordinate+1; + } + + /* machine dependent fixups */ + pcibios_fixup(); + /* fixup irqs (board specific routines) */ + pcibios_fixup_irqs(); +} + +unsigned long __init pci_bridge_check_io(struct pci_dev *bridge) +{ + u16 io; + + pci_read_config_word(bridge, PCI_IO_BASE, &io); + if (!io) { + pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); + pci_read_config_word(bridge, PCI_IO_BASE, &io); + pci_write_config_word(bridge, PCI_IO_BASE, 0x0); + } + if (io) + return IORESOURCE_IO; + printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n", + bridge->name); + return 0; +} + +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + /* Propogate hose info into the subordinate devices. */ + + struct pci_channel *hose = bus->sysdata; + struct pci_dev *dev = bus->self; + + if (!dev) { + /* Root bus */ + bus->resource[0] = hose->io_resource; + bus->resource[1] = hose->mem_resource; + } else { + /* This is a bridge. Do not care how it's initialized, + just link its resources to the bus ones */ + int i; + + for(i=0; i<3; i++) { + bus->resource[i] = + &dev->resource[PCI_BRIDGE_RESOURCES+i]; + bus->resource[i]->name = bus->name; + } + bus->resource[0]->flags |= pci_bridge_check_io(dev); + bus->resource[1]->flags |= IORESOURCE_MEM; + /* For now, propogate hose limits to the bus; + we'll adjust them later. */ + bus->resource[0]->end = hose->io_resource->end; + bus->resource[1]->end = hose->mem_resource->end; + /* Turn off downstream PF memory address range by default */ + bus->resource[2]->start = 1024*1024; + bus->resource[2]->end = bus->resource[2]->start - 1; + } +} +#endif diff -urN linux-2.4.21/arch/mips/pci/pci_auto.c linux-2.4.22/arch/mips/pci/pci_auto.c --- linux-2.4.21/arch/mips/pci/pci_auto.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/pci/pci_auto.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,508 @@ +/* + * PCI autoconfiguration library + * + * Author: Matt Porter + * + * Copyright 2000, 2001, 2002, 2003 MontaVista Software Inc. + * Copyright 2001 Bradley D. LaRonde + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * Modified for MIPS by Jun Sun, jsun@mvista.com + * + * . Simplify the interface between pci_auto and the rest: a single function. + * . Assign resources from low address to upper address. + * . change most int to u32. + * + * Further modified to include it as mips generic code, ppopov@mvista.com. + * + * 2001-10-26 Bradley D. LaRonde + * - Add a top_bus argument to the "early config" functions so that + * they can set a fake parent bus pointer to convince the underlying + * pci ops to use type 1 configuration for sub busses. + * - Set bridge base and limit registers correctly. + * - Align io and memory base properly before and after bridge setup. + * - Don't fall through to pci_setup_bars for bridge. + * - Reformat the debug output to look more like lspci's output. + * + * 2003-04-09 Yoichi Yuasa, Alice Hennessy, Jun Sun + * - Add cardbus bridge support, mostly copied from PPC + */ + +#include +#include +#include +#include + +#include + +#define DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* + * These functions are used early on before PCI scanning is done + * and all of the pci_dev and pci_bus structures have been created. + */ +static struct pci_dev *fake_pci_dev(struct pci_channel *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + + if(busnr != top_bus) + /* Fake a parent bus structure. */ + bus.parent = &bus; + else + bus.parent = NULL; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +int early_##rw##_config_##size(struct pci_channel *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) + +static struct resource *io_resource_inuse; +static struct resource *mem_resource_inuse; + +static u32 pciauto_lower_iospc; +static u32 pciauto_upper_iospc; + +static u32 pciauto_lower_memspc; +static u32 pciauto_upper_memspc; + +void __init +pciauto_setup_bars(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int bar_limit) +{ + u32 bar_response, bar_size, bar_value; + u32 bar, addr_mask, bar_nr = 0; + u32 * upper_limit; + u32 * lower_limit; + int found_mem64 = 0; + + for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { + /* Tickle the BAR and get the response */ + early_write_config_dword(hose, top_bus, + current_bus, + pci_devfn, + bar, + 0xffffffff); + early_read_config_dword(hose, top_bus, + current_bus, + pci_devfn, + bar, + &bar_response); + + /* If BAR is not implemented go to the next BAR */ + if (!bar_response) + continue; + + /* + * Workaround for a BAR that doesn't use its upper word, + * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457). + * bdl + */ + if (!(bar_response & 0xffff0000)) + bar_response |= 0xffff0000; + +retry: + /* Check the BAR type and set our address mask */ + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + addr_mask = PCI_BASE_ADDRESS_IO_MASK; + upper_limit = &pciauto_upper_iospc; + lower_limit = &pciauto_lower_iospc; + DBG(" I/O"); + } else { + if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64) + found_mem64 = 1; + + addr_mask = PCI_BASE_ADDRESS_MEM_MASK; + upper_limit = &pciauto_upper_memspc; + lower_limit = &pciauto_lower_memspc; + DBG(" Mem"); + } + + + /* Calculate requested size */ + bar_size = ~(bar_response & addr_mask) + 1; + + /* Allocate a base address */ + bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; + + if ((bar_value + bar_size) > *upper_limit) { + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + if (io_resource_inuse->child) { + io_resource_inuse = + io_resource_inuse->child; + pciauto_lower_iospc = + io_resource_inuse->start; + pciauto_upper_iospc = + io_resource_inuse->end + 1; + goto retry; + } + + } else { + if (mem_resource_inuse->child) { + mem_resource_inuse = + mem_resource_inuse->child; + pciauto_lower_memspc = + mem_resource_inuse->start; + pciauto_upper_memspc = + mem_resource_inuse->end + 1; + goto retry; + } + } + DBG(" unavailable -- skipping\n"); + continue; + } + + /* Write it out and update our limit */ + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + bar, bar_value); + + *lower_limit = bar_value + bar_size; + + /* + * If we are a 64-bit decoder then increment to the + * upper 32 bits of the bar and force it to locate + * in the lower 4GB of memory. + */ + if (found_mem64) { + bar += 4; + early_write_config_dword(hose, top_bus, + current_bus, + pci_devfn, + bar, + 0x00000000); + } + + DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size); + + bar_nr++; + } + +} + +void __init +pciauto_prescan_setup_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_PRIMARY_BUS, current_bus); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SECONDARY_BUS, sub_bus + 1); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, 0xff); + + /* Align memory and I/O to 1MB and 4KB boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) + & ~(0x100000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) + & ~(0x1000 - 1); + + /* Set base (lower limit) of address range behind bridge. */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_MEMORY_BASE, pciauto_lower_memspc >> 16); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16); + + /* We don't support prefetchable memory for now, so disable */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_PREF_MEMORY_BASE, 0); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_PREF_MEMORY_LIMIT, 0); +} + +void __init +pciauto_postscan_setup_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + u32 temp; + + /* + * [jsun] we always bump up baselines a little, so that if there + * nothing behind P2P bridge, we don't wind up overlapping IO/MEM + * spaces. + */ + pciauto_lower_memspc += 1; + pciauto_lower_iospc += 1; + + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, sub_bus); + + /* Set upper limit of address range behind bridge. */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16); + + /* Align memory and I/O to 1MB and 4KB boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) + & ~(0x100000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) + & ~(0x1000 - 1); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &temp); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY + | PCI_COMMAND_MASTER); +} + +void __init +pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_PRIMARY_BUS, current_bus); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SECONDARY_BUS, sub_bus + 1); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, 0xff); + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_BASE_0, pciauto_lower_iospc); +} + +void __init +pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + u32 temp; + + /* + * Configure subordinate bus number. The PCI subsystem + * bus scan will renumber buses (reserving three additional + * for this PCI<->CardBus bridge for the case where a CardBus + * adapter contains a P2P or CB2CB bridge. + */ + + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, sub_bus); + + /* + * Reserve an additional 4MB for mem space and 16KB for + * I/O space. This should cover any additional space + * requirement of unusual CardBus devices with + * additional bridges that can consume more address space. + * + * Although pcmcia-cs currently will reprogram bridge + * windows, the goal is to add an option to leave them + * alone and use the bridge window ranges as the regions + * that are searched for free resources upon hot-insertion + * of a device. This will allow a PCI<->CardBus bridge + * configured by this routine to happily live behind a + * P2P bridge in a system. + */ + pciauto_lower_memspc += 0x00400000; + pciauto_lower_iospc += 0x00004000; + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + /* Set up memory and I/O filter limits, assume 32-bit I/O space */ + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &temp); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY + | PCI_COMMAND_MASTER); +} + +#define PCIAUTO_IDE_MODE_MASK 0x05 + +int __init +pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) +{ + int sub_bus; + u32 pci_devfn, pci_class, cmdstat, found_multi=0; + unsigned short vid, did; + unsigned char header_type; + int devfn_start = 0; + int devfn_stop = 0xff; + + sub_bus = current_bus; + + if (hose->first_devfn) + devfn_start = hose->first_devfn; + if (hose->last_devfn) + devfn_stop = hose->last_devfn; + + for (pci_devfn=devfn_start; pci_devfn> 16, vid, did); + if (pci_class & 0xff) + DBG(" (rev %.2x)", pci_class & 0xff); + DBG("\n"); + + if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { + DBG(" Bridge: primary=%.2x, secondary=%.2x\n", + current_bus, sub_bus + 1); + pciauto_setup_bars(hose, top_bus, current_bus, + pci_devfn, PCI_BASE_ADDRESS_1); + pciauto_prescan_setup_bridge(hose, top_bus, current_bus, + pci_devfn, sub_bus); + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", + sub_bus + 1, + pciauto_lower_iospc, pciauto_lower_memspc); + sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); + DBG("Back to bus %.2x\n", current_bus); + pciauto_postscan_setup_bridge(hose, top_bus, current_bus, + pci_devfn, sub_bus); + continue; + } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { + DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n", + current_bus, sub_bus + 1); + DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); + /* Place CardBus Socket/ExCA registers */ + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); + + pciauto_prescan_setup_cardbus_bridge(hose, top_bus, + current_bus, pci_devfn, sub_bus); + + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", + sub_bus + 1, + pciauto_lower_iospc, pciauto_lower_memspc); + sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); + DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus); + pciauto_postscan_setup_cardbus_bridge(hose, top_bus, + current_bus, pci_devfn, sub_bus); + continue; + } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { + + unsigned char prg_iface; + + early_read_config_byte(hose, top_bus, current_bus, + pci_devfn, PCI_CLASS_PROG, &prg_iface); + if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { + DBG("Skipping legacy mode IDE controller\n"); + continue; + } + } + + /* + * Found a peripheral, enable some standard + * settings + */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &cmdstat); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, cmdstat | PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_LATENCY_TIMER, 0x80); + + /* Allocate PCI I/O and/or memory space */ + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5); + } + return sub_bus; +} + +int __init +pciauto_assign_resources(int busno, struct pci_channel *hose) +{ + /* setup resource limits */ + io_resource_inuse = hose->io_resource; + mem_resource_inuse = hose->mem_resource; + + pciauto_lower_iospc = io_resource_inuse->start; + pciauto_upper_iospc = io_resource_inuse->end + 1; + pciauto_lower_memspc = mem_resource_inuse->start; + pciauto_upper_memspc = mem_resource_inuse->end + 1; + DBG("Autoconfig PCI channel 0x%p\n", hose); + DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", + busno, pciauto_lower_iospc, pciauto_upper_iospc, + pciauto_lower_memspc, pciauto_upper_memspc); + + return pciauto_bus_scan(hose, busno, busno); +} diff -urN linux-2.4.21/arch/mips/philips/nino/Makefile linux-2.4.22/arch/mips/philips/nino/Makefile --- linux-2.4.21/arch/mips/philips/nino/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/philips/nino/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,10 +6,7 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(AFLAGS) $< -o $@ -.S.o: - $(CC) $(AFLAGS) -c $< -o $@ +USE_STANDARD_AS_RULE := true O_TARGET := nino.o diff -urN linux-2.4.21/arch/mips/philips/nino/irq.c linux-2.4.22/arch/mips/philips/nino/irq.c --- linux-2.4.21/arch/mips/philips/nino/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/philips/nino/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -9,7 +9,9 @@ * * Interrupt service routines for Philips Nino */ +#include #include +#include #include #include #include @@ -18,8 +20,6 @@ #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - static void enable_irq6(unsigned int irq) { if(irq == 0) { @@ -112,7 +112,7 @@ static void enable_irq4(unsigned int irq) { - set_cp0_status(STATUSF_IP4); + set_c0_status(STATUSF_IP4); if (irq == 2) { outl(inl(TX3912_INT2_CLEAR) | TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR); @@ -130,7 +130,7 @@ static void disable_irq4(unsigned int irq) { - clear_cp0_status(STATUSF_IP4); + clear_c0_status(STATUSF_IP4); } #define shutdown_irq4 disable_irq4 @@ -198,7 +198,7 @@ unsigned int i; /* Disable all hardware interrupts */ - change_cp0_status(ST0_IM, 0x00); + change_c0_status(ST0_IM, 0x00); /* Clear interrupts */ outl(0xffffffff, TX3912_INT1_CLEAR); @@ -243,14 +243,14 @@ TX3912_INT6_ENABLE); /* Enable all interrupts */ - change_cp0_status(ST0_IM, ALLINTS); + change_c0_status(ST0_IM, ALLINTS); } void (*irq_setup)(void); void __init init_IRQ(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern void set_debug_traps(void); diff -urN linux-2.4.21/arch/mips/philips/nino/power.c linux-2.4.22/arch/mips/philips/nino/power.c --- linux-2.4.21/arch/mips/philips/nino/power.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/philips/nino/power.c 2003-08-25 04:44:40.000000000 -0700 @@ -19,7 +19,7 @@ outl(inl(TX3912_POWER_CTRL) | TX3912_POWER_CTRL_STOPCPU, TX3912_POWER_CTRL); - /* + /* * We wait until an interrupt happens... */ diff -urN linux-2.4.21/arch/mips/philips/nino/prom.c linux-2.4.22/arch/mips/philips/nino/prom.c --- linux-2.4.21/arch/mips/philips/nino/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/philips/nino/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -6,7 +6,7 @@ * 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. - * + * * Early initialization code for the Philips Nino */ #include @@ -60,8 +60,8 @@ * memory and mark it as reserved. */ free_end = (mem_size - tx3912fb_size) & PAGE_MASK; - add_memory_region(0, free_end, BOOT_MEM_RAM); - add_memory_region(free_end, (mem_size - free_end), BOOT_MEM_RESERVED); + add_memory_region(0, free_end, BOOT_MEM_RAM); + add_memory_region(free_end, (mem_size - free_end), BOOT_MEM_RESERVED); /* * Calculate physical and virtual addresses for @@ -71,7 +71,7 @@ tx3912fb_vaddr = KSEG1ADDR(free_end); } #else - add_memory_region(0, mem_size, BOOT_MEM_RAM); + add_memory_region(0, mem_size, BOOT_MEM_RAM); #endif } diff -urN linux-2.4.21/arch/mips/philips/nino/setup.c linux-2.4.22/arch/mips/philips/nino/setup.c --- linux-2.4.21/arch/mips/philips/nino/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/philips/nino/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -9,6 +9,7 @@ * * Interrupt and exception initialization for Philips Nino */ +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include static void nino_machine_restart(char *command) @@ -80,6 +82,7 @@ setup_irq(0, irq); } + void __init nino_setup(void) { extern void nino_irq_setup(void); diff -urN linux-2.4.21/arch/mips/ramdisk/Makefile linux-2.4.22/arch/mips/ramdisk/Makefile --- linux-2.4.21/arch/mips/ramdisk/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/ramdisk/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -7,9 +7,9 @@ # O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) -ramdisk.o: ramdisk.gz ld.script +img = $(CONFIG_EMBEDDED_RAMDISK_IMAGE) +ramdisk.o: $(subst ",,$(img)) ld.script echo "O_FORMAT: " $(O_FORMAT) - $(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ ramdisk.gz + $(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) include $(TOPDIR)/Rules.make - diff -urN linux-2.4.21/arch/mips/sgi-ip22/Makefile linux-2.4.22/arch/mips/sgi-ip22/Makefile --- linux-2.4.21/arch/mips/sgi-ip22/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -2,11 +2,9 @@ # Makefile for the SGI specific kernel interface routines # under Linux. # -# Note! Dependencies are done automagically by 'make dep', which also +# 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... USE_STANDARD_AS_RULE := true @@ -14,11 +12,13 @@ all: ip22-kern.o ip22-irq.o -obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-time.o ip22-berr.o \ - ip22-gio.o ip22-rtc.o ip22-reset.o ip22-system.o ip22-setup.o +obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ + ip22-time.o ip22-rtc.o ip22-nvram.o ip22-reset.o \ + ip22-setup.o ip22-ksyms.o + +obj-$(CONFIG_IP22_EISA) += ip22-eisa.o -obj-$(CONFIG_BOARD_SCACHE) += ip22-sc.o -obj-$(CONFIG_IP22_EISA) += ip22-eisa.o +export-objs := ip22-ksyms.o ip22-irq.o: ip22-irq.S diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-berr.c linux-2.4.22/arch/mips/sgi-ip22/ip22-berr.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-berr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-berr.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * ip22-berr.c: Bus error handling. * - * Copyright (C) 2002 Ladislav Michl + * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org) */ #include @@ -12,25 +12,70 @@ #include #include #include -#include -#include +#include +#include +#include +#include -unsigned int cpu_err_stat; /* Status reg for CPU */ -unsigned int gio_err_stat; /* Status reg for GIO */ -unsigned int cpu_err_addr; /* Error address reg for CPU */ -unsigned int gio_err_addr; /* Error address reg for GIO */ -volatile int nofault; +static unsigned int cpu_err_stat; /* Status reg for CPU */ +static unsigned int gio_err_stat; /* Status reg for GIO */ +static unsigned int cpu_err_addr; /* Error address reg for CPU */ +static unsigned int gio_err_addr; /* Error address reg for GIO */ +static unsigned int extio_stat; +static unsigned int hpc3_berr_stat; /* Bus error interrupt status */ static void save_and_clear_buserr(void) { - /* save memory controler's error status registers */ - cpu_err_addr = mcmisc_regs->cerr; - cpu_err_stat = mcmisc_regs->cstat; - gio_err_addr = mcmisc_regs->gerr; - gio_err_stat = mcmisc_regs->gstat; + /* save status registers */ + cpu_err_addr = sgimc->cerr; + cpu_err_stat = sgimc->cstat; + gio_err_addr = sgimc->gerr; + gio_err_stat = sgimc->gstat; + extio_stat = ip22_is_fullhouse() ? sgioc->extio : (sgint->errstat << 4); + hpc3_berr_stat = hpc3c0->bestat; - mcmisc_regs->cstat = mcmisc_regs->gstat = 0; + sgimc->cstat = sgimc->gstat = 0; +} + +#define GIO_ERRMASK 0xff00 +#define CPU_ERRMASK 0x3f00 + +static void print_buserr(void) +{ + if (extio_stat & EXTIO_MC_BUSERR) + printk(KERN_ERR "MC Bus Error\n"); + if (extio_stat & EXTIO_HPC3_BUSERR) + printk(KERN_ERR "HPC3 Bus Error 0x%x:\n", + hpc3_berr_stat, + (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >> + HPC3_BESTAT_PIDSHIFT, + (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA", + hpc3_berr_stat & HPC3_BESTAT_BLMASK); + if (extio_stat & EXTIO_EISA_BUSERR) + printk(KERN_ERR "EISA Bus Error\n"); + if (cpu_err_stat & CPU_ERRMASK) + printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n", + cpu_err_stat, + cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "", + cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "", + cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "", + cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "", + cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "", + cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "", + cpu_err_addr); + if (gio_err_stat & GIO_ERRMASK) + printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x08%x\n", + gio_err_stat, + gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "", + gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "", + gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "", + gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "", + gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "", + gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "", + gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "", + gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "", + gio_err_addr); } /* @@ -40,39 +85,30 @@ * and then clear the interrupt when this happens. */ -void be_ip22_interrupt(int irq, struct pt_regs *regs) +void ip22_be_interrupt(int irq, struct pt_regs *regs) { + const int field = 2 * sizeof(unsigned long); + save_and_clear_buserr(); - printk(KERN_ALERT "Bus error, epc == %08lx, ra == %08lx\n", - regs->cp0_epc, regs->regs[31]); + print_buserr(); + printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", + (regs->cp0_cause & 4) ? "Data" : "Instruction", + field, regs->cp0_epc, field, regs->regs[31]); + /* Assume it would be too dangerous to continue ... */ die_if_kernel("Oops", regs); force_sig(SIGBUS, current); } -int be_ip22_handler(struct pt_regs *regs, int is_fixup) +static int ip22_be_handler(struct pt_regs *regs, int is_fixup) { save_and_clear_buserr(); - if (nofault) { - nofault = 0; - compute_return_epc(regs); - return MIPS_BE_DISCARD; - } - return MIPS_BE_FIXUP; -} - -int ip22_baddr(unsigned int *val, unsigned long addr) -{ - nofault = 1; - *val = *(volatile unsigned int *) addr; - __asm__ __volatile__("nop;nop;nop;nop"); - if (nofault) { - nofault = 0; - return 0; - } - return -EFAULT; + if (is_fixup) + return MIPS_BE_FIXUP; + print_buserr(); + return MIPS_BE_FATAL; } -void __init bus_error_init(void) +void __init ip22_be_init(void) { - be_board_handler = be_ip22_handler; + board_be_handler = ip22_be_handler; } diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-eisa.c linux-2.4.22/arch/mips/sgi-ip22/ip22-eisa.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-eisa.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-eisa.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -30,10 +31,10 @@ #include #include #include -#include - -extern int EISA_bus; -extern void do_IRQ(int irq, struct pt_regs *regs); +#include +#include +#include +#include #define EISA_MAX_SLOTS 4 #define EISA_MAX_IRQ 16 @@ -92,7 +93,7 @@ if (eisa_irq >= EISA_MAX_IRQ) { /* Oops, Bad Stuff Happened... */ - printk("eisa_irq %d out of bound\n", eisa_irq); + printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq); EISA_WRITE_8(EISA_INT2_CTRL, 0x20); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); @@ -153,14 +154,13 @@ } static struct hw_interrupt_type ip22_eisa1_irq_type = { - "IP22 EISA", - startup_eisa1_irq, - shutdown_eisa1_irq, - enable_eisa1_irq, - disable_eisa1_irq, - mask_and_ack_eisa1_irq, - end_eisa1_irq, - NULL + .typename = "IP22 EISA", + .startup = startup_eisa1_irq, + .shutdown = shutdown_eisa1_irq, + .enable = enable_eisa1_irq, + .disable = disable_eisa1_irq, + .ack = mask_and_ack_eisa1_irq, + .end = end_eisa1_irq, }; static void enable_eisa2_irq(unsigned int irq) @@ -217,22 +217,23 @@ } static struct hw_interrupt_type ip22_eisa2_irq_type = { - "IP22 EISA", - startup_eisa2_irq, - shutdown_eisa2_irq, - enable_eisa2_irq, - disable_eisa2_irq, - mask_and_ack_eisa2_irq, - end_eisa2_irq, - NULL + .typename = "IP22 EISA", + .startup = startup_eisa2_irq, + .shutdown = shutdown_eisa2_irq, + .enable = enable_eisa2_irq, + .disable = disable_eisa2_irq, + .ack = mask_and_ack_eisa2_irq, + .end = end_eisa2_irq, }; static struct irqaction eisa_action = { - ip22_eisa_intr, 0, 0, "EISA", NULL, NULL + .handler = ip22_eisa_intr, + .name = "EISA", }; static struct irqaction cascade_action = { - no_action, 0, 0, "EISA cascade", NULL, NULL + .handler = no_action, + .name = "EISA cascade", }; int __init ip22_eisa_init(void) @@ -240,20 +241,26 @@ int i, c; char *str; u8 *slot_addr; + + if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { + printk(KERN_INFO "EISA: bus not present.\n"); + return 1; + } - printk("EISA: Probing bus...\n"); + printk(KERN_INFO "EISA: Probing bus...\n"); for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) { slot_addr = (u8 *) EISA_TO_KSEG1((0x1000 * i) + EISA_VENDOR_ID_OFFSET); if ((str = decode_eisa_sig(slot_addr))) { - printk("EISA: slot %d : %s detected.\n", i, str); + printk(KERN_INFO "EISA: slot %d : %s detected.\n", + i, str); c++; } } - printk("EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s"); + printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s"); #ifdef CONFIG_ISA - printk("ISA support compiled in.\n"); + printk(KERN_INFO "ISA support compiled in.\n"); #endif /* Warning : BlackMagicAhead(tm). diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-gio.c linux-2.4.22/arch/mips/sgi-ip22/ip22-gio.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-gio.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-gio.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,153 +0,0 @@ -/* - * ip22-gio.c: Support for GIO64 bus (inspired by PCI code) - * - * Copyright (C) 2002 Ladislav Michl - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#define GIO_PIO_MAP_BASE 0x1f000000L -#define GIO_PIO_MAP_SIZE (16 * 1024*1024) - -#define GIO_ADDR_GFX 0x1f000000L -#define GIO_ADDR_GIO1 0x1f400000L -#define GIO_ADDR_GIO2 0x1f600000L - -#define GIO_GFX_MAP_SIZE (4 * 1024*1024) -#define GIO_GIO1_MAP_SIZE (2 * 1024*1024) -#define GIO_GIO2_MAP_SIZE (4 * 1024*1024) - -#define GIO_NO_DEVICE 0x80 - -static struct gio_dev gio_slot[GIO_NUM_SLOTS] = { - { - 0, - 0, - 0, - GIO_NO_DEVICE, - GIO_SLOT_GFX, - GIO_ADDR_GFX, - GIO_GFX_MAP_SIZE, - NULL, - "GFX" - }, - { - 0, - 0, - 0, - GIO_NO_DEVICE, - GIO_SLOT_GIO1, - GIO_ADDR_GIO1, - GIO_GIO1_MAP_SIZE, - NULL, - "EXP0" - }, - { - 0, - 0, - 0, - GIO_NO_DEVICE, - GIO_SLOT_GIO2, - GIO_ADDR_GIO2, - GIO_GIO2_MAP_SIZE, - NULL, - "EXP1" - } -}; - -static int gio_read_proc(char *buf, char **start, off_t off, - int count, int *eof, void *data) -{ - int i; - char *p = buf; - - p += sprintf(p, "GIO devices found:\n"); - for (i = 0; i < GIO_NUM_SLOTS; i++) { - if (gio_slot[i].flags & GIO_NO_DEVICE) - continue; - p += sprintf(p, " Slot %s, DeviceId 0x%02x\n", - gio_slot[i].slot_name, gio_slot[i].device); - p += sprintf(p, " BaseAddr 0x%08lx, MapSize 0x%08x\n", - gio_slot[i].base_addr, gio_slot[i].map_size); - } - - return p - buf; -} - -void create_gio_proc_entry(void) -{ - create_proc_read_entry("gio", 0, NULL, gio_read_proc, NULL); -} - -/** - * gio_find_device - begin or continue searching for a GIO device by device id - * @device: GIO device id to match, or %GIO_ANY_ID to match all device ids - * @from: Previous GIO device found in search, or %NULL for new search. - * - * Iterates through the list of known GIO devices. If a GIO device is found - * with a matching @device, a pointer to its device structure is returned. - * Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL to the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device. - */ -struct gio_dev * -gio_find_device(unsigned char device, const struct gio_dev *from) -{ - int i; - - for (i = (from) ? from->slot_number : 0; i < GIO_NUM_SLOTS; i++) - if (!(gio_slot[i].flags & GIO_NO_DEVICE) && - (device == GIO_ANY_ID || device == gio_slot[i].device)) - return &gio_slot[i]; - - return NULL; -} - -#define GIO_IDCODE(x) (x & 0x7f) -#define GIO_ALL_BITS_VALID 0x80 -#define GIO_REV(x) ((x >> 8) & 0xff) -#define GIO_GIO_SIZE_64 0x10000 -#define GIO_ROM_PRESENT 0x20000 -#define GIO_VENDOR_CODE(x) ((x >> 18) & 0x3fff) - -extern int ip22_baddr(unsigned int *val, unsigned long addr); - -/** - * sgigio_init - scan the GIO space and figure out what hardware is actually - * present. - */ -void __init sgigio_init(void) -{ - unsigned int i, id, found = 0; - - printk("GIO: Scanning for GIO cards...\n"); - for (i = 0; i < GIO_NUM_SLOTS; i++) { - if (ip22_baddr(&id, KSEG1ADDR(gio_slot[i].base_addr))) - continue; - - found = 1; - gio_slot[i].device = GIO_IDCODE(id); - if (id & GIO_ALL_BITS_VALID) { - gio_slot[i].revision = GIO_REV(id); - gio_slot[i].vendor = GIO_VENDOR_CODE(id); - gio_slot[i].flags = - (id & GIO_GIO_SIZE_64) ? GIO_IFACE_64 : 0 | - (id & GIO_ROM_PRESENT) ? GIO_HAS_ROM : 0; - } else - gio_slot[i].flags = GIO_VALID_ID_ONLY; - - printk("GIO: Card 0x%02x @ 0x%08lx\n", gio_slot[i].device, - gio_slot[i].base_addr); - } - - if (!found) - printk("GIO: No GIO cards present.\n"); -} diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-hpc.c linux-2.4.22/arch/mips/sgi-ip22/ip22-hpc.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-hpc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-hpc.c 2003-08-25 04:44:40.000000000 -0700 @@ -4,89 +4,50 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1998 Ralf Baechle */ + #include #include #include -#include -#include -#include -#include - -#if 0 -#define HPC_DEBUG(args...) printk(args) -#else -#define HPC_DEBUG(args...) -#endif +#include +#include +#include struct hpc3_regs *hpc3c0, *hpc3c1; -struct hpc3_miscregs *hpc3mregs; +struct sgioc_regs *sgioc; /* We need software copies of these because they are write only. */ -u32 sgi_hpc_write1, sgi_hpc_write2; - -/* Machine specific identifier knobs. */ -int sgi_has_ioc2 = 0; -int sgi_guiness = 0; -int sgi_boardid; +u8 sgi_ioc_reset, sgi_ioc_write; extern char *system_type; void __init sgihpc_init(void) { - unsigned int sid, crev, brev; - - hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE); - hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE); - hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE); - sid = hpc3mregs->sysid; - - sid &= 0xff; - crev = (sid & 0xe0) >> 5; - brev = (sid & 0x1e) >> 1; - - HPC_DEBUG("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev); - HPC_DEBUG("sgihpc_init: "); - - /* This test works now thanks to William J. Earl */ - if ((sid & 1) == 0 ) { - HPC_DEBUG("GUINESS "); - sgi_guiness = 1; - mips_machtype = MACH_SGI_INDY; - system_type = "SGI Indy"; - } else { - HPC_DEBUG("FULLHOUSE "); - mips_machtype = MACH_SGI_INDIGO2; - sgi_guiness = 0; + hpc3c0 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP0_BASE); + hpc3c1 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP1_BASE); + /* IOC lives in PBUS PIO channel 6 */ + sgioc = (struct sgioc_regs *)hpc3c0->pbus_extregs[6]; + + hpc3c0->pbus_piocfg[6][0] |= HPC3_PIOCFG_DS16; + if (ip22_is_fullhouse()) { + /* Full House comes with INT2 which lives in PBUS PIO + * channel 4 */ + sgint = (struct sgint_regs *)hpc3c0->pbus_extregs[4]; system_type = "SGI Indigo2"; - } - sgi_boardid = brev; - - HPC_DEBUG("sgi_boardid<%d> ", sgi_boardid); - - if(crev == 1) { - if((sid & 1) || (brev >= 2)) { - HPC_DEBUG("IOC2 "); - sgi_has_ioc2 = 1; - } else { - HPC_DEBUG("IOC1 revision 1 "); - } } else { - HPC_DEBUG("IOC1 revision 0 "); + /* Guiness comes with INT3 which is part of IOC */ + sgint = &sgioc->int3; + system_type = "SGI Indy"; } - HPC_DEBUG("\n"); - - sgi_hpc_write1 = (HPC3_WRITE1_PRESET | HPC3_WRITE1_KMRESET | - HPC3_WRITE1_ERESET | HPC3_WRITE1_LC0OFF); - - sgi_hpc_write2 = (HPC3_WRITE2_EASEL | HPC3_WRITE2_NTHRESH | - HPC3_WRITE2_TPSPEED | HPC3_WRITE2_EPSEL | - HPC3_WRITE2_U0AMODE | HPC3_WRITE2_U1AMODE); - - if(!sgi_guiness) - sgi_hpc_write1 |= HPC3_WRITE1_GRESET; - hpc3mregs->write1 = sgi_hpc_write1; - hpc3mregs->write2 = sgi_hpc_write2; + + sgi_ioc_reset = (SGIOC_RESET_PPORT | SGIOC_RESET_KBDMOUSE | + SGIOC_RESET_EISA | SGIOC_RESET_ISDN | + SGIOC_RESET_LC0OFF); + + sgi_ioc_write = (SGIOC_WRITE_EASEL | SGIOC_WRITE_NTHRESH | + SGIOC_WRITE_TPSPEED | SGIOC_WRITE_EPSEL | + SGIOC_WRITE_U0AMODE | SGIOC_WRITE_U1AMODE); - hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW; + sgioc->reset = sgi_ioc_reset; + sgioc->write = sgi_ioc_write; } diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-int.c linux-2.4.22/arch/mips/sgi-ip22/ip22-int.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-int.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) * - Indigo2 changes * - Interrupt handling fixes - * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz) + * Copyright (C) 2001, 2003 Ladislav Michl (ladis@linux-mips.org) */ #include @@ -21,17 +21,16 @@ #include #include -#include -#include +#include +#include +#include /* #define DEBUG_SGINT */ -#undef I_REALLY_NEED_THIS_IRQ -struct sgi_int2_regs *sgi_i2regs; -struct sgi_int3_regs *sgi_i3regs; -struct sgi_ioc_ints *ioc_icontrol; -struct sgi_ioc_timers *ioc_timers; -volatile unsigned char *ioc_tclear; +/* So far nothing hangs here */ +#undef USE_LIO3_IRQ + +struct sgint_regs *sgint; static char lc0msk_to_irqnr[256]; static char lc1msk_to_irqnr[256]; @@ -39,8 +38,7 @@ static char lc3msk_to_irqnr[256]; extern asmlinkage void indyIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); -extern int ip22_eisa_init (void); +extern int ip22_eisa_init(void); static void enable_local0_irq(unsigned int irq) { @@ -50,7 +48,7 @@ /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_0_IRQ) - ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0)); + sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); restore_flags(flags); } @@ -65,7 +63,7 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); + sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); restore_flags(flags); } @@ -79,14 +77,13 @@ } static struct hw_interrupt_type ip22_local0_irq_type = { - "IP22 local 0", - startup_local0_irq, - shutdown_local0_irq, - enable_local0_irq, - disable_local0_irq, - mask_and_ack_local0_irq, - end_local0_irq, - NULL + .typename = "IP22 local 0", + .startup = startup_local0_irq, + .shutdown = shutdown_local0_irq, + .enable = enable_local0_irq, + .disable = disable_local0_irq, + .ack = mask_and_ack_local0_irq, + .end = end_local0_irq, }; static void enable_local1_irq(unsigned int irq) @@ -97,7 +94,7 @@ /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_1_IRQ) - ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1)); + sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); restore_flags(flags); } @@ -112,7 +109,7 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); + sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); restore_flags(flags); } @@ -126,14 +123,13 @@ } static struct hw_interrupt_type ip22_local1_irq_type = { - "IP22 local 1", - startup_local1_irq, - shutdown_local1_irq, - enable_local1_irq, - disable_local1_irq, - mask_and_ack_local1_irq, - end_local1_irq, - NULL + .typename = "IP22 local 1", + .startup = startup_local1_irq, + .shutdown = shutdown_local1_irq, + .enable = enable_local1_irq, + .disable = disable_local1_irq, + .ack = mask_and_ack_local1_irq, + .end = end_local1_irq, }; static void enable_local2_irq(unsigned int irq) @@ -141,8 +137,8 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); - ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); + sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); + sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); restore_flags(flags); } @@ -157,9 +153,9 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); - if (!ioc_icontrol->cmeimask0) - ioc_icontrol->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); + sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); + if (!sgint->cmeimask0) + sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); restore_flags(flags); } @@ -173,28 +169,23 @@ } static struct hw_interrupt_type ip22_local2_irq_type = { - "IP22 local 2", - startup_local2_irq, - shutdown_local2_irq, - enable_local2_irq, - disable_local2_irq, - mask_and_ack_local2_irq, - end_local2_irq, - NULL + .typename = "IP22 local 2", + .startup = startup_local2_irq, + .shutdown = shutdown_local2_irq, + .enable = enable_local2_irq, + .disable = disable_local2_irq, + .ack = mask_and_ack_local2_irq, + .end = end_local2_irq, }; static void enable_local3_irq(unsigned int irq) { -#ifdef I_REALLY_NEED_THIS_IRQ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); - ioc_icontrol->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); + sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); + sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); restore_flags(flags); -#else - panic("Who need local 3 irq? see ip22-int.c"); -#endif } static unsigned int startup_local3_irq(unsigned int irq) @@ -208,9 +199,9 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); - if (!ioc_icontrol->cmeimask1) - ioc_icontrol->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); + sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); + if (!sgint->cmeimask1) + sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); restore_flags(flags); } @@ -224,30 +215,26 @@ } static struct hw_interrupt_type ip22_local3_irq_type = { - "IP22 local 3", - startup_local3_irq, - shutdown_local3_irq, - enable_local3_irq, - disable_local3_irq, - mask_and_ack_local3_irq, - end_local3_irq, - NULL + .typename = "IP22 local 3", + .startup = startup_local3_irq, + .shutdown = shutdown_local3_irq, + .enable = enable_local3_irq, + .disable = disable_local3_irq, + .ack = mask_and_ack_local3_irq, + .end = end_local3_irq, }; void indy_local0_irqdispatch(struct pt_regs *regs) { - unsigned char mask = ioc_icontrol->istat0; - unsigned char mask2 = 0; + u8 mask = sgint->istat0 & sgint->imask0; + u8 mask2; int irq; - mask &= ioc_icontrol->imask0; - if (mask & ISTAT0_LIO2) { - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask0; + if (mask & SGINT_ISTAT0_LIO2) { + mask2 = sgint->vmeistat & sgint->cmeimask0; irq = lc2msk_to_irqnr[mask2]; - } else { + } else irq = lc0msk_to_irqnr[mask]; - } /* if irq == 0, then the interrupt has already been cleared */ if (irq) @@ -257,21 +244,15 @@ void indy_local1_irqdispatch(struct pt_regs *regs) { - unsigned char mask = ioc_icontrol->istat1; - unsigned char mask2 = 0; + u8 mask = sgint->istat1 & sgint->imask1; + u8 mask2; int irq; - mask &= ioc_icontrol->imask1; - if (mask & ISTAT1_LIO3) { -#ifndef I_REALLY_NEED_THIS_IRQ - printk("Whee: Got an LIO3 irq, winging it...\n"); -#endif - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask1; + if (mask & SGINT_ISTAT1_LIO3) { + mask2 = sgint->vmeistat & sgint->cmeimask1; irq = lc3msk_to_irqnr[mask2]; - } else { + } else irq = lc1msk_to_irqnr[mask]; - } /* if irq == 0, then the interrupt has already been cleared */ if (irq) @@ -279,7 +260,7 @@ return; } -extern void be_ip22_interrupt(int irq, struct pt_regs *regs); +extern void ip22_be_interrupt(int irq, struct pt_regs *regs); void indy_buserror_irq(struct pt_regs *regs) { @@ -288,21 +269,43 @@ irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; - be_ip22_interrupt(irq, regs); + ip22_be_interrupt(irq, regs); irq_exit(cpu, irq); } -static struct irqaction local0_cascade = - { no_action, SA_INTERRUPT, 0, "local0 cascade", NULL, NULL }; -static struct irqaction local1_cascade = - { no_action, SA_INTERRUPT, 0, "local1 cascade", NULL, NULL }; -static struct irqaction buserr = - { no_action, SA_INTERRUPT, 0, "Bus Error", NULL, NULL }; -static struct irqaction map0_cascade = - { no_action, SA_INTERRUPT, 0, "mappable0 cascade", NULL, NULL }; -#ifdef I_REALLY_NEED_THIS_IRQ -static struct irqaction map1_cascade = - { no_action, SA_INTERRUPT, 0, "mappable1 cascade", NULL, NULL }; +static struct irqaction local0_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "local0 cascade", +}; + +static struct irqaction local1_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "local1 cascade", +}; + +static struct irqaction buserr = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "Bus Error", +}; + +static struct irqaction map0_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "mapable0 cascade", +}; + +#ifdef USE_LIO3_IRQ +static struct irqaction map1_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "mapable1 cascade", +}; +#define SGI_INTERRUPTS SGINT_END +#else +#define SGI_INTERRUPTS SGINT_LOCAL3 #endif extern void mips_cpu_irq_init(unsigned int irq_base); @@ -311,9 +314,6 @@ { int i; - sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE); - sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE); - /* Init local mask --> irq tables. */ for (i = 0; i < 256; i++) { if (i & 0x80) { @@ -364,22 +364,11 @@ } } - /* Indy uses an INT3, Indigo2 uses an INT2 */ - if (sgi_guiness) { - ioc_icontrol = &sgi_i3regs->ints; - ioc_timers = &sgi_i3regs->timers; - ioc_tclear = &sgi_i3regs->tclear; - } else { - ioc_icontrol = &sgi_i2regs->ints; - ioc_timers = &sgi_i2regs->timers; - ioc_tclear = &sgi_i2regs->tclear; - } - /* Mask out all interrupts. */ - ioc_icontrol->imask0 = 0; - ioc_icontrol->imask1 = 0; - ioc_icontrol->cmeimask0 = 0; - ioc_icontrol->cmeimask1 = 0; + sgint->imask0 = 0; + sgint->imask1 = 0; + sgint->cmeimask0 = 0; + sgint->cmeimask1 = 0; set_except_vector(0, indyIRQ); @@ -387,7 +376,7 @@ /* init CPU irqs */ mips_cpu_irq_init(SGINT_CPU); - for (i = SGINT_LOCAL0; i < SGINT_END; i++) { + for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) { hw_irq_controller *handler; if (i < SGINT_LOCAL1) @@ -412,11 +401,12 @@ /* cascade in cascade. i love Indy ;-) */ setup_irq(SGI_MAP_0_IRQ, &map0_cascade); -#ifdef I_REALLY_NEED_THIS_IRQ +#ifdef USE_LIO3_IRQ setup_irq(SGI_MAP_1_IRQ, &map1_cascade); #endif + #ifdef CONFIG_IP22_EISA - if (!sgi_guiness) /* Only Indigo-2 have EISA stuff */ + if (ip22_is_fullhouse()) /* Only Indigo-2 have EISA stuff */ ip22_eisa_init (); #endif } diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-ksyms.c linux-2.4.22/arch/mips/sgi-ip22/ip22-ksyms.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-ksyms.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,21 @@ +/* + * ip22-ksyms.c: IP22 specific exports + */ + +#include + +#include +#include +#include +#include + +EXPORT_SYMBOL(sgimc); +EXPORT_SYMBOL(hpc3c0); +EXPORT_SYMBOL(hpc3c1); +EXPORT_SYMBOL(sgioc); + +extern void (*indy_volume_button)(int); +EXPORT_SYMBOL(indy_volume_button); + +EXPORT_SYMBOL(ip22_eeprom_read); +EXPORT_SYMBOL(ip22_nvram_read); diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-mc.c linux-2.4.22/arch/mips/sgi-ip22/ip22-mc.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-mc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-mc.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,89 +1,115 @@ /* - * ip22-mc.c: Routines for manipulating the INDY memory controller. + * ip22-mc.c: Routines for manipulating SGI Memory Controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes + * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) */ #include #include #include +#include #include #include -#include -#include +#include +#include +#include -/* #define DEBUG_SGIMC */ +struct sgimc_regs *sgimc; -#ifdef DEBUG_SGIMC -extern void prom_printf(char *fmt, ...); -#endif - -struct sgimc_misc_ctrl *mcmisc_regs; -struct sgimc_dma_ctrl *dmactrlregs; -u32 *rpsscounter; - -#ifdef DEBUG_SGIMC -static inline char *mconfig_string(unsigned long val) +static inline unsigned long get_bank_addr(unsigned int memconfig) { - switch(val & SGIMC_MCONFIG_RMASK) { - case SGIMC_MCONFIG_FOURMB: - return "4MB"; - - case SGIMC_MCONFIG_EIGHTMB: - return "8MB"; + return ((memconfig & SGIMC_MCONFIG_BASEADDR) << + ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22)); +} - case SGIMC_MCONFIG_SXTEENMB: - return "16MB"; +static inline unsigned long get_bank_size(unsigned int memconfig) +{ + return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << + ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); +} - case SGIMC_MCONFIG_TTWOMB: - return "32MB"; +static inline unsigned int get_bank_config(int bank) +{ + unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0; + return bank % 2 ? res & 0xffff : res >> 16; +} - case SGIMC_MCONFIG_SFOURMB: - return "64MB"; +struct mem { + unsigned long addr; + unsigned long size; +}; - case SGIMC_MCONFIG_OTEIGHTMB: - return "128MB"; +/* + * Detect installed memory, do some sanity checks and notify kernel about it + */ +static void probe_memory(void) +{ + int i, j, found, cnt = 0; + struct mem bank[4]; + struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}}; + + printk(KERN_INFO "MC: Probing memory configuration:\n"); + for (i = 0; i < ARRAY_SIZE(bank); i++) { + unsigned int tmp = get_bank_config(i); + if (!(tmp & SGIMC_MCONFIG_BVALID)) + continue; + + bank[cnt].size = get_bank_size(tmp); + bank[cnt].addr = get_bank_addr(tmp); + printk(KERN_INFO " bank%d: %3ldM @ %08lx\n", + i, bank[cnt].size / 1024 / 1024, bank[cnt].addr); + cnt++; + } - default: - return "wheee, unknown"; + /* And you thought bubble sort is dead algorithm... */ + do { + unsigned long addr, size; + + found = 0; + for (i = 1; i < cnt; i++) + if (bank[i-1].addr > bank[i].addr) { + addr = bank[i].addr; + size = bank[i].size; + bank[i].addr = bank[i-1].addr; + bank[i].size = bank[i-1].size; + bank[i-1].addr = addr; + bank[i-1].size = size; + found = 1; + } + } while (found); + + /* Figure out how are memory banks mapped into spaces */ + for (i = 0; i < cnt; i++) { + found = 0; + for (j = 0; j < ARRAY_SIZE(space) && !found; j++) + if (space[j].addr + space[j].size == bank[i].addr) { + space[j].size += bank[i].size; + found = 1; + } + /* There is either hole or overlapping memory */ + if (!found) + printk(KERN_CRIT "MC: Memory configuration mismatch " + "(%08lx), expect Bus Error soon\n", + bank[i].addr); } + + for (i = 0; i < ARRAY_SIZE(space); i++) + if (space[i].size) + add_memory_region(space[i].addr, space[i].size, + BOOT_MEM_RAM); } -#endif void __init sgimc_init(void) { - unsigned long tmpreg; + u32 tmp; - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - rpsscounter = (unsigned int *)(KSEG1+0x1fa01004); - dmactrlregs = (struct sgimc_dma_ctrl *)(KSEG1+0x1fa02000); + sgimc = (struct sgimc_regs *)(KSEG1 + SGIMC_BASE); printk(KERN_INFO "MC: SGI memory controller Revision %d\n", - (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV); - -#if 0 /* XXX Until I figure out what this bit really indicates XXX */ - /* XXX Is this systemid bit reliable? */ - if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) { - EISA_bus = 1; - printk("with EISA\n"); - } else { - EISA_bus = 0; - printk("no EISA\n"); - } -#endif - -#ifdef DEBUG_SGIMC - prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n", - mconfig_string(mcmisc_regs->mconfig0), - mconfig_string(mcmisc_regs->mconfig1)); - - prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n", - mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1); - prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n", - mcmisc_regs->divider, mcmisc_regs->gioparm); -#endif + (int) sgimc->systemid & SGIMC_SYSID_MASKREV); /* Place the MC into a known state. This must be done before * interrupts are first enabled etc. @@ -93,32 +119,32 @@ * still running (which might be the case after a * soft reboot). */ - tmpreg = mcmisc_regs->cpuctrl0; - tmpreg &= ~SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = tmpreg; + tmp = sgimc->cpuctrl0; + tmp &= ~SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = tmp; /* Step 1: The CPU/GIO error status registers will not latch * up a new error status until the register has been * cleared by the cpu. These status registers are * cleared by writing any value to them. */ - mcmisc_regs->cstat = mcmisc_regs->gstat = 0; + sgimc->cstat = sgimc->gstat = 0; /* Step 2: Enable all parity checking in cpu control register * zero. */ - tmpreg = mcmisc_regs->cpuctrl0; - tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | - SGIMC_CCTRL0_R4KNOCHKPARR); - mcmisc_regs->cpuctrl0 = tmpreg; + tmp = sgimc->cpuctrl0; + tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | + SGIMC_CCTRL0_R4KNOCHKPARR); + sgimc->cpuctrl0 = tmp; /* Step 3: Setup the MC write buffer depth, this is controlled * in cpu control register 1 in the lower 4 bits. */ - tmpreg = mcmisc_regs->cpuctrl1; - tmpreg &= ~0xf; - tmpreg |= 0xd; - mcmisc_regs->cpuctrl1 = tmpreg; + tmp = sgimc->cpuctrl1; + tmp &= ~0xf; + tmp |= 0xd; + sgimc->cpuctrl1 = tmp; /* Step 4: Initialize the RPSS divider register to run as fast * as it can correctly operate. The register is laid @@ -134,38 +160,42 @@ * registers value increases at each 'tick'. Thus, * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 */ - mcmisc_regs->divider = 0x101; + sgimc->divider = 0x101; /* Step 5: Initialize GIO64 arbitrator configuration register. * - * NOTE: If you dork with startup code the HPC init code in - * sgihpc_init() must run before us because of how we - * need to know Guiness vs. FullHouse and the board - * revision on this machine. You have been warned. + * NOTE: HPC init code in sgihpc_init() must run before us because + * we need to know Guiness vs. FullHouse and the board + * revision on this machine. You have been warned. */ /* First the basic invariants across all GIO64 implementations. */ - tmpreg = SGIMC_GIOPARM_HPC64; /* All 1st HPC's interface at 64bits. */ - tmpreg |= SGIMC_GIOPARM_ONEBUS; /* Only one physical GIO bus exists. */ + tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */ + tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */ - if(sgi_guiness) { - /* Guiness specific settings. */ - tmpreg |= SGIMC_GIOPARM_EISA64; /* MC talks to EISA at 64bits */ - tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */ - } else { + if (ip22_is_fullhouse()) { /* Fullhouse specific settings. */ - if(sgi_boardid < 2) { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */ - tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */ - tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */ + if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) { + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */ + tmp |= SGIMC_GIOPAR_MASTEREXP1; /* exp1 masters */ + tmp |= SGIMC_GIOPAR_RTIMEEXP0; /* exp0 is realtime */ } else { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP1; - tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */ - tmpreg |= SGIMC_GIOPARM_GFX64; /* GFX at 64 bits */ + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */ + tmp |= SGIMC_GIOPAR_PLINEEXP1; + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */ + tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */ } + } else { + /* Guiness specific settings. */ + tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */ + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */ } - mcmisc_regs->gioparm = tmpreg; /* poof */ + sgimc->giopar = tmp; /* poof */ + + probe_memory(); } + +void __init prom_meminit(void) {} +void __init prom_free_prom_memory (void) {} diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-nvram.c linux-2.4.22/arch/mips/sgi-ip22/ip22-nvram.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-nvram.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-nvram.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,114 @@ +/* + * ip22-nvram.c: NVRAM and serial EEPROM handling. + * + * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) + */ + +#include +#include + +/* Control opcode for serial eeprom */ +#define EEPROM_READ 0xc000 /* serial memory read */ +#define EEPROM_WEN 0x9800 /* write enable before prog modes */ +#define EEPROM_WRITE 0xa000 /* serial memory write */ +#define EEPROM_WRALL 0x8800 /* write all registers */ +#define EEPROM_WDS 0x8000 /* disable all programming */ +#define EEPROM_PRREAD 0xc000 /* read protect register */ +#define EEPROM_PREN 0x9800 /* enable protect register mode */ +#define EEPROM_PRCLEAR 0xffff /* clear protect register */ +#define EEPROM_PRWRITE 0xa000 /* write protect register */ +#define EEPROM_PRDS 0x8000 /* disable protect register, forever */ + +#define EEPROM_EPROT 0x01 /* Protect register enable */ +#define EEPROM_CSEL 0x02 /* Chip select */ +#define EEPROM_ECLK 0x04 /* EEPROM clock */ +#define EEPROM_DATO 0x08 /* Data out */ +#define EEPROM_DATI 0x10 /* Data in */ + +/* We need to use this functions early... */ +#define delay() ({ \ + int x; \ + for (x=0; x<100000; x++) __asm__ __volatile__(""); }) + +#define eeprom_cs_on(ptr) ({ \ + *ptr &= ~EEPROM_DATO; \ + *ptr &= ~EEPROM_ECLK; \ + *ptr &= ~EEPROM_EPROT; \ + delay(); \ + *ptr |= EEPROM_CSEL; \ + *ptr |= EEPROM_ECLK; }) + + +#define eeprom_cs_off(ptr) ({ \ + *ptr &= ~EEPROM_ECLK; \ + *ptr &= ~EEPROM_CSEL; \ + *ptr |= EEPROM_EPROT; \ + *ptr |= EEPROM_ECLK; }) + +#define BITS_IN_COMMAND 11 +/* + * clock in the nvram command and the register number. For the + * national semiconductor nv ram chip the op code is 3 bits and + * the address is 6/8 bits. + */ +static inline void eeprom_cmd(volatile unsigned int *ctrl, unsigned cmd, + unsigned reg) +{ + unsigned short ser_cmd; + int i; + + ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND)); + for (i = 0; i < BITS_IN_COMMAND; i++) { + if (ser_cmd & (1<<15)) /* if high order bit set */ + *ctrl |= EEPROM_DATO; + else + *ctrl &= ~EEPROM_DATO; + *ctrl &= ~EEPROM_ECLK; + *ctrl |= EEPROM_ECLK; + ser_cmd <<= 1; + } + *ctrl &= ~EEPROM_DATO; /* see data sheet timing diagram */ +} + +unsigned short ip22_eeprom_read(volatile unsigned int *ctrl, int reg) +{ + unsigned short res = 0; + int i; + + *ctrl &= ~EEPROM_EPROT; + eeprom_cs_on(ctrl); + eeprom_cmd(ctrl, EEPROM_READ, reg); + + /* clock the data ouf of serial mem */ + for (i = 0; i < 16; i++) { + *ctrl &= ~EEPROM_ECLK; + delay(); + *ctrl |= EEPROM_ECLK; + delay(); + res <<= 1; + if (*ctrl & EEPROM_DATI) + res |= 1; + } + + eeprom_cs_off(ctrl); + + return res; +} + +/* + * Read specified register from main NVRAM + */ +unsigned short ip22_nvram_read(int reg) +{ + if (ip22_is_fullhouse()) + /* IP22 (Indigo2 aka FullHouse) stores env variables into + * 93CS56 Microwire Bus EEPROM 2048 Bit (128x16) */ + return ip22_eeprom_read(&hpc3c0->eeprom, reg); + else { + unsigned short tmp; + /* IP24 (Indy aka Guiness) uses DS1386 8K version */ + reg <<= 1; + tmp = hpc3c0->bbram[reg++] & 0xff; + return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff); + } +} diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-reset.c linux-2.4.22/arch/mips/sgi-ip22/ip22-reset.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,20 +3,24 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 1998, 2001 by Ralf Baechle + * Copyright (C) 1997, 1998, 2001, 2003 by Ralf Baechle */ +#include #include #include #include #include + #include #include #include #include #include #include -#include -#include +#include +#include +#include +#include /* * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds. @@ -31,49 +35,50 @@ #define POWERDOWN_FREQ (HZ / 4) #define PANIC_FREQ (HZ / 8) -static unsigned char sgi_volume; - static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; -static int shuting_down = 0, has_paniced = 0, setup_done = 0; + +#define MACHINE_PANICED 1 +#define MACHINE_SHUTTING_DOWN 2 +static int machine_state = 0; static void sgi_machine_restart(char *command) __attribute__((noreturn)); static void sgi_machine_halt(void) __attribute__((noreturn)); static void sgi_machine_power_off(void) __attribute__((noreturn)); -/* XXX How to pass the reboot command to the firmware??? */ static void sgi_machine_restart(char *command) { - if (shuting_down) + if (machine_state & MACHINE_SHUTTING_DOWN) sgi_machine_power_off(); - ArcReboot(); + sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT; + while (1); } static void sgi_machine_halt(void) { - if (shuting_down) + if (machine_state & MACHINE_SHUTTING_DOWN) sgi_machine_power_off(); ArcEnterInteractiveMode(); } static void sgi_machine_power_off(void) { - unsigned char val; + unsigned int tmp; cli(); /* Disable watchdog */ - val = CMOS_READ(RTC_CMD); - CMOS_WRITE(val|RTC_WAM, RTC_CMD); - CMOS_WRITE(0, RTC_WSEC); - CMOS_WRITE(0, RTC_WHSEC); + tmp = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = tmp | RTC_WAM; + hpc3c0->rtcregs[RTC_WSEC] = 0; + hpc3c0->rtcregs[RTC_WHSEC] = 0; - while(1) { - hpc3mregs->panel=0xfe; + while (1) { + sgioc->panel = ~SGIOC_PANEL_POWERON; /* Good bye cruel world ... */ /* If we're still running, we probably got sent an alarm interrupt. Read the flag to clear it. */ - val = CMOS_READ(RTC_HOURS_ALARM); + tmp = hpc3c0->rtcregs[RTC_HOURS_ALARM]; } } @@ -85,8 +90,8 @@ static void blink_timeout(unsigned long data) { /* XXX fix this for fullhouse */ - sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF); - hpc3mregs->write1 = sgi_hpc_write1; + sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF); + sgioc->reset = sgi_ioc_reset; mod_timer(&blink_timer, jiffies+data); } @@ -94,32 +99,35 @@ static void debounce(unsigned long data) { del_timer(&debounce_timer); - if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent. */ + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + /* Interrupt still being sent. */ debounce_timer.expires = jiffies + 5; /* 0.05s */ add_timer(&debounce_timer); - hpc3mregs->panel = 0xf3; + sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR | + SGIOC_PANEL_VOLDNINTR | SGIOC_PANEL_VOLDNHOLD | + SGIOC_PANEL_VOLUPINTR | SGIOC_PANEL_VOLUPHOLD; return; } - if (has_paniced) - ArcReboot(); + if (machine_state & MACHINE_PANICED) + sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT; enable_irq(SGI_PANEL_IRQ); } static inline void power_button(void) { - if (has_paniced) + if (machine_state & MACHINE_PANICED) return; - if (shuting_down || kill_proc(1, SIGINT, 1)) { + if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { /* No init process or button pressed twice. */ sgi_machine_power_off(); } - shuting_down = 1; + machine_state |= MACHINE_SHUTTING_DOWN; blink_timer.data = POWERDOWN_FREQ; blink_timeout(POWERDOWN_FREQ); @@ -129,47 +137,29 @@ add_timer(&power_timer); } -void inline sgi_volume_set(unsigned char volume) -{ - sgi_volume = volume; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; -} - -void inline sgi_volume_get(unsigned char *volume) -{ - *volume = sgi_volume; -} +void (*indy_volume_button)(int) = NULL; static inline void volume_up_button(unsigned long data) { del_timer(&volume_timer); - if (sgi_volume < 0xff) - sgi_volume++; + if (indy_volume_button) + indy_volume_button(1); - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; - - if (ioc_icontrol->istat1 & 2) { + if (sgint->istat1 & SGINT_ISTAT1_PWR) { volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } - } static inline void volume_down_button(unsigned long data) { del_timer(&volume_timer); - if (sgi_volume > 0) - sgi_volume--; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; + if (indy_volume_button) + indy_volume_button(-1); - if (ioc_icontrol->istat1 & 2) { + if (sgint->istat1 & SGINT_ISTAT1_PWR) { volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } @@ -179,10 +169,11 @@ { unsigned int buttons; - buttons = hpc3mregs->panel; - hpc3mregs->panel = 0x03; /* power_interrupt | power_supply_on */ + buttons = sgioc->panel; + sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR; - if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */ + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + /* Wait until interrupt goes away */ disable_irq(SGI_PANEL_IRQ); init_timer(&debounce_timer); debounce_timer.function = debounce; @@ -190,15 +181,25 @@ add_timer(&debounce_timer); } - if (!(buttons & 0x02)) /* Power button was pressed */ + /* Power button was pressed + * ioc.ps page 22: "The Panel Register is called Power Control by Full + * House. Only lowest 2 bits are used. Guiness uses upper four bits + * for volume control". This is not true, all bits are pulled high + * on fullhouse */ + if (ip22_is_fullhouse() || !(buttons & SGIOC_PANEL_POWERINTR)) { power_button(); - if (!(buttons & 0x40)) { /* Volume up button was pressed */ + return; + } + /* TODO: mute/unmute */ + /* Volume up button was pressed */ + if (!(buttons & SGIOC_PANEL_VOLUPINTR)) { init_timer(&volume_timer); volume_timer.function = volume_up_button; volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } - if (!(buttons & 0x10)) { /* Volume down button was pressed */ + /* Volume down button was pressed */ + if (!(buttons & SGIOC_PANEL_VOLDNINTR)) { init_timer(&volume_timer); volume_timer.function = volume_down_button; volume_timer.expires = jiffies + 1; @@ -209,9 +210,9 @@ static int panic_event(struct notifier_block *this, unsigned long event, void *ptr) { - if (has_paniced) + if (machine_state & MACHINE_PANICED) return NOTIFY_DONE; - has_paniced = 1; + machine_state |= MACHINE_PANICED; blink_timer.data = PANIC_FREQ; blink_timeout(PANIC_FREQ); @@ -220,17 +221,11 @@ } static struct notifier_block panic_block = { - panic_event, - NULL, - 0 + .notifier_call = panic_event, }; -void indy_reboot_setup(void) +static int __init reboot_setup(void) { - if (setup_done) - return; - setup_done = 1; - _machine_restart = sgi_machine_restart; _machine_halt = sgi_machine_halt; _machine_power_off = sgi_machine_power_off; @@ -239,4 +234,8 @@ init_timer(&blink_timer); blink_timer.function = blink_timeout; notifier_chain_register(&panic_notifier_list, &panic_block); + + return 0; } + +module_init(reboot_setup); diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-rtc.c linux-2.4.22/arch/mips/sgi-ip22/ip22-rtc.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-rtc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-rtc.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,29 +8,25 @@ * Copyright (C) 1998, 2001 by Ralf Baechle */ #include -#include +#include -static unsigned char indy_rtc_read_data(unsigned long addr) +static unsigned char ip22_rtc_read_data(unsigned long addr) { - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - return rtcregs[addr]; + return hpc3c0->rtcregs[addr]; } -static void indy_rtc_write_data(unsigned char data, unsigned long addr) +static void ip22_rtc_write_data(unsigned char data, unsigned long addr) { - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - rtcregs[addr] = data; + hpc3c0->rtcregs[addr] = data; } -static int indy_rtc_bcd_mode(void) +static int ip22_rtc_bcd_mode(void) { return 0; } -struct rtc_ops indy_rtc_ops = { - &indy_rtc_read_data, - &indy_rtc_write_data, - &indy_rtc_bcd_mode +struct rtc_ops ip22_rtc_ops = { + &ip22_rtc_read_data, + &ip22_rtc_write_data, + &ip22_rtc_bcd_mode }; diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-sc.c linux-2.4.22/arch/mips/sgi-ip22/ip22-sc.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-sc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-sc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,225 +0,0 @@ -/* - * ip22-sc.c: Indy cache management functions. - * - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#undef DEBUG_CACHE - -#define SC_SIZE 0x00080000 -#define SC_LINE 32 -#define CI_MASK (SC_SIZE - SC_LINE) -#define SC_INDEX(n) ((n) & CI_MASK) - -static inline void indy_sc_wipe(unsigned long first, unsigned long last) -{ - unsigned long tmp; - - __asm__ __volatile__( - ".set\tpush\t\t\t# indy_sc_wipe\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "mfc0\t%2, $12\n\t" - "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" - "mtc0\t$1, $12\n\t" - - "dli\t$1, 0x9000000080000000\n\t" - "or\t%0, $1\t\t\t# first line to flush\n\t" - "or\t%1, $1\t\t\t# last line to flush\n\t" - ".set\tat\n\t" - - "1:\tsw\t$0, 0(%0)\n\t" - "bne\t%0, %1, 1b\n\t" - " daddu\t%0, 32\n\t" - - "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" - "nop; nop; nop; nop;\n\t" - ".set\tpop" - : "=r" (first), "=r" (last), "=&r" (tmp) - : "0" (first), "1" (last)); -} - -static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) -{ - unsigned long first_line, last_line; - unsigned int flags; - -#ifdef DEBUG_CACHE - printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); -#endif - - if (!size) - return; - - /* Which lines to flush? */ - first_line = SC_INDEX(addr); - last_line = SC_INDEX(addr + size - 1); - - __save_and_cli(flags); - if (first_line <= last_line) { - indy_sc_wipe(first_line, last_line); - goto out; - } - - indy_sc_wipe(first_line, SC_SIZE - SC_LINE); - indy_sc_wipe(0, last_line); -out: - __restore_flags(flags); -} - -static void indy_sc_enable(void) -{ - unsigned long addr, tmp1, tmp2; - - /* This is really cool... */ -#ifdef DEBUG_CACHE - printk("Enabling R4600 SCACHE\n"); -#endif - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - "mfc0\t%2, $12\n\t" - "nop; nop; nop; nop;\n\t" - "li\t%1, 0x80\n\t" - "mtc0\t%1, $12\n\t" - "nop; nop; nop; nop;\n\t" - "li\t%0, 0x1\n\t" - "dsll\t%0, 31\n\t" - "lui\t%1, 0x9000\n\t" - "dsll32\t%1, 0\n\t" - "or\t%0, %1, %0\n\t" - "sb\t$0, 0(%0)\n\t" - "mtc0\t$0, $12\n\t" - "nop; nop; nop; nop;\n\t" - "mtc0\t%2, $12\n\t" - "nop; nop; nop; nop;\n\t" - ".set\tpop" - : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); -} - -static void indy_sc_disable(void) -{ - unsigned long tmp1, tmp2, tmp3; - -#ifdef DEBUG_CACHE - printk("Disabling R4600 SCACHE\n"); -#endif - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - "li\t%0, 0x1\n\t" - "dsll\t%0, 31\n\t" - "lui\t%1, 0x9000\n\t" - "dsll32\t%1, 0\n\t" - "or\t%0, %1, %0\n\t" - "mfc0\t%2, $12\n\t" - "nop; nop; nop; nop\n\t" - "li\t%1, 0x80\n\t" - "mtc0\t%1, $12\n\t" - "nop; nop; nop; nop\n\t" - "sh\t$0, 0(%0)\n\t" - "mtc0\t$0, $12\n\t" - "nop; nop; nop; nop\n\t" - "mtc0\t%2, $12\n\t" - "nop; nop; nop; nop\n\t" - ".set\tpop" - : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); -} - -static inline int __init indy_sc_probe(void) -{ - volatile unsigned int *cpu_control; - unsigned short cmd = 0xc220; - unsigned long data = 0; - int i, n; - -#ifdef __MIPSEB__ - cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034); -#else - cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030); -#endif -#define DEASSERT(bit) (*(cpu_control) &= (~(bit))) -#define ASSERT(bit) (*(cpu_control) |= (bit)) -#define DELAY for(n = 0; n < 100000; n++) __asm__ __volatile__("") - DEASSERT(SGIMC_EEPROM_PRE); - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_PRE); - DELAY; - ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK); - for(i = 0; i < 11; i++) { - if(cmd & (1<<15)) - ASSERT(SGIMC_EEPROM_SDATAO); - else - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - ASSERT(SGIMC_EEPROM_SECLOCK); - cmd <<= 1; - } - DEASSERT(SGIMC_EEPROM_SDATAO); - for(i = 0; i < (sizeof(unsigned short) * 8); i++) { - unsigned int tmp; - - DEASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - ASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - data <<= 1; - tmp = *cpu_control; - if(tmp & SGIMC_EEPROM_SDATAI) - data |= 1; - } - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_CSEL); - ASSERT(SGIMC_EEPROM_PRE); - ASSERT(SGIMC_EEPROM_SECLOCK); - - data <<= PAGE_SHIFT; - if (data == 0) - return 0; - - scache_size = data; - - printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -/* XXX Check with wje if the Indy caches can differenciate between - writeback + invalidate and just invalidate. */ -struct bcache_ops indy_sc_ops = { - indy_sc_enable, - indy_sc_disable, - indy_sc_wback_invalidate, - indy_sc_wback_invalidate -}; - -void __init indy_sc_init(void) -{ - if (indy_sc_probe()) { - indy_sc_enable(); - bcops = &indy_sc_ops; - } -} diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-setup.c linux-2.4.22/arch/mips/sgi-ip22/ip22-setup.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,39 +22,27 @@ #include #include #include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void breakpoint(void); static int remote_debug = 0; #endif -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_ARC_CONSOLE) -extern void console_setup(char *); -#endif - -extern void sgitime_init(void); +extern struct rtc_ops ip22_rtc_ops; -extern struct hpc3_miscregs *hpc3mregs; -extern struct rtc_ops indy_rtc_ops; -extern void indy_reboot_setup(void); -extern void sgi_volume_set(unsigned char); -extern void create_gio_proc_entry(void); - -#define sgi_kh ((struct hpc_keyb *) &(hpc3mregs->kbdmouse0)) +unsigned long sgi_gfxaddr; #define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ -unsigned long sgi_gfxaddr; - static void sgi_request_region(void) { /* No I/O ports are being used on the Indy. */ @@ -62,19 +50,6 @@ static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *)) { - /* Dirty hack, this get's called as a callback from the keyboard - * driver. We piggyback the initialization of the front panel - * button handling on it even though they're technically not - * related with the keyboard driver in any way. Doing it from - * ip22_setup wouldn't work since kmalloc isn't initialized yet. - */ - indy_reboot_setup(); - - /* Ehm, well... once David used hack above, let's add yet another. - * Register GIO bus proc entry here. - */ - create_gio_proc_entry(); - return request_irq(SGI_KEYBD_IRQ, handler, 0, "keyboard", NULL); } @@ -91,54 +66,62 @@ static unsigned char sgi_read_input(void) { - return sgi_kh->data; + return sgioc->kbdmouse.data; } static void sgi_write_output(unsigned char val) { - int status; + unsigned char status; do { - status = sgi_kh->command; + status = sgioc->kbdmouse.command; } while (status & KBD_STAT_IBF); - sgi_kh->data = val; + sgioc->kbdmouse.data = val; } static void sgi_write_command(unsigned char val) { - int status; + unsigned char status; do { - status = sgi_kh->command; + status = sgioc->kbdmouse.command; } while (status & KBD_STAT_IBF); - sgi_kh->command = val; + sgioc->kbdmouse.command = val; } static unsigned char sgi_read_status(void) { - return sgi_kh->command; + return sgioc->kbdmouse.command; } -struct kbd_ops sgi_kbd_ops = { - sgi_request_region, - sgi_request_irq, +struct kbd_ops ip22_kbd_ops = { + .kbd_request_region = sgi_request_region, + .kbd_request_irq = sgi_request_irq, - sgi_aux_request_irq, - sgi_aux_free_irq, + .aux_request_irq = sgi_aux_request_irq, + .aux_free_irq = sgi_aux_free_irq, - sgi_read_input, - sgi_write_output, - sgi_write_command, - sgi_read_status + .kbd_read_input = sgi_read_input, + .kbd_write_output = sgi_write_output, + .kbd_write_command = sgi_write_command, + .kbd_read_status = sgi_read_status, }; +extern void ip22_be_init(void) __init; +extern void ip22_time_init(void) __init; + +extern int console_setup(char *) __init; + void __init ip22_setup(void) { char *ctype; -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB char *kgdb_ttyd; #endif - sgitime_init(); + + board_be_init = ip22_be_init; + ip22_time_init(); + /* Init the INDY HPC I/O controller. Need to call this before * fucking with the memory controller because it needs to know the * boardID and whether this is a Guiness or a FullHouse machine. @@ -152,7 +135,6 @@ /* Now enable boardcaches, if any. */ indy_sc_init(); #endif - conswitchp = NULL; /* Set the IO space to some sane value */ set_io_port_base (KSEG1ADDR (0x00080000)); @@ -162,81 +144,72 @@ * line and "d2" for the second serial line. */ ctype = ArcGetEnvironmentVariable("console"); - if (*ctype == 'd') { -#ifdef CONFIG_SERIAL_CONSOLE - if(*(ctype + 1) == '2') + if (ctype && *ctype == 'd') { + if (*(ctype + 1) == '2') console_setup("ttyS1"); else console_setup("ttyS0"); -#endif - } else { -#ifdef CONFIG_ARC_CONSOLE - prom_flags &= PROM_FLAG_USE_AS_CONSOLE; - console_setup("ttyS0"); -#endif + } else if (!ctype || *ctype != 'g') { + /* Use ARC if we don't want serial ('d') or Newport ('g'). */ + prom_flags |= PROM_FLAG_USE_AS_CONSOLE; + console_setup("arc"); } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB kgdb_ttyd = prom_getcmdline(); if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) { int line; kgdb_ttyd += strlen("kgdb=ttyd"); if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2') - printk("KGDB: Uknown serial line /dev/ttyd%c, " - "falling back to /dev/ttyd1\n", *kgdb_ttyd); + printk(KERN_INFO "KGDB: Uknown serial line /dev/ttyd%c" + ", falling back to /dev/ttyd1\n", *kgdb_ttyd); line = *kgdb_ttyd == '2' ? 0 : 1; - printk("KGDB: Using serial line /dev/ttyd%d for session\n", - line ? 1 : 2); + printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for " + "session\n", line ? 1 : 2); rs_kgdb_hook(line); - printk("KGDB: Using serial line /dev/ttyd%d for session, " - "please connect your debugger\n", line ? 1 : 2); + printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for " + "session, please connect your debugger\n", line ? 1:2); remote_debug = 1; /* Breakpoints and stuff are in sgi_irq_setup() */ } #endif - sgi_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"), NULL, 10)); - #ifdef CONFIG_VT + conswitchp = &dummy_con; #ifdef CONFIG_SGI_NEWPORT_CONSOLE - { + if (ctype && *ctype == 'g'){ unsigned long *gfxinfo; - long (*__vec)(void) = (void *) *(long *)((PROMBLOCK)->pvector + 0x20); + long (*__vec)(void) = + (void *) *(long *)((PROMBLOCK)->pvector + 0x20); gfxinfo = (unsigned long *)__vec(); sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000 && gfxinfo[1] <= 0xc0000000) ? gfxinfo[1] - 0xa0000000 : 0); + + /* newport addresses? */ + if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) { + conswitchp = &newport_con; + + screen_info = (struct screen_info) { + .orig_x = 0, + .orig_y = 0, + .orig_video_page = 0, + .orig_video_mode = 0, + .orig_video_cols = 160, + .orig_video_ega_bx = 0, + .orig_video_lines = 64, + .orig_video_isVGA = 0, + .orig_video_points = 16, + }; + } } - /* newport addresses? */ - if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) { - conswitchp = &newport_con; - - screen_info = (struct screen_info) { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig_video_page */ - 0, /* orig_video_mode */ - 160, /* orig_video_cols */ - 0, 0, 0, /* unused, ega_bx, unused */ - 64, /* orig_video_lines */ - 0, /* orig_video_isVGA */ - 16 /* orig_video_points */ - }; - } else { - conswitchp = &dummy_con; - } -#else -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif #endif #endif - - rtc_ops = &indy_rtc_ops; - kbd_ops = &sgi_kbd_ops; + rtc_ops = &ip22_rtc_ops; + kbd_ops = &ip22_kbd_ops; #ifdef CONFIG_PSMOUSE aux_device_present = 0xaa; #endif diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-system.c linux-2.4.22/arch/mips/sgi-ip22/ip22-system.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-system.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-system.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,134 +0,0 @@ -/* - * ip22-system.c: Probe the system type using ARCS prom interface library. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include -#include -#include -#include - -#include -#include -#include - -enum sgi_mach sgimach; - -struct smatch { - char *name; - int type; -}; - -static struct smatch sgi_cputable[] = { - { "MIPS-R2000", CPU_R2000 }, - { "MIPS-R3000", CPU_R3000 }, - { "MIPS-R3000A", CPU_R3000A }, - { "MIPS-R4000", CPU_R4000SC }, - { "MIPS-R4400", CPU_R4400SC }, - { "MIPS-R4600", CPU_R4600 }, - { "MIPS-R8000", CPU_R8000 }, - { "MIPS-R5000", CPU_R5000 }, - { "MIPS-R5000A", CPU_R5000A }, - { "MIPS-R10000", CPU_R10000 } -}; - -static int __init string_to_cpu(char *s) -{ - ULONG cnt; - char c; - int i; - - for(i = 0; i < (sizeof(sgi_cputable) / sizeof(struct smatch)); i++) { - if(!strcmp(s, sgi_cputable[i].name)) - return sgi_cputable[i].type; - } - prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s); - prom_printf("press a key to reboot\n"); - ArcRead(0, &c, 1, &cnt); - ArcEnterInteractiveMode(); - return 0; -} - -/* - * We' call this early before loadmmu(). If we do the other way around - * the firmware will crash and burn. - */ -void __init sgi_sysinit(void) -{ - pcomponent *p, *toplev, *cpup = 0; - int cputype = -1; - ULONG cnt; - char c; - - - /* The root component tells us what machine architecture we - * have here. - */ - p = ArcGetChild(PROM_NULL_COMPONENT); - - /* Now scan for cpu(s). */ - printk(KERN_INFO); - toplev = p = ArcGetChild(p); - while(p) { - int ncpus = 0; - - if(p->type == Cpu) { - if(++ncpus > 1) { - prom_printf("\nYeee, SGI MP not ready yet\n"); - prom_printf("press a key to reboot\n"); - ArcRead(0, &c, 1, &cnt); - ArcEnterInteractiveMode(); - } - printk("CPU: %s ", (char *)p->iname); - cpup = p; - cputype = string_to_cpu((char *)cpup->iname); - } - p = ArcGetPeer(p); - } - if (cputype == -1) { - prom_printf("\nYeee, could not find cpu ARCS component\n"); - prom_printf("press a key to reboot\n"); - ArcRead(0, &c, 1, &cnt); - ArcEnterInteractiveMode(); - } - p = ArcGetChild(cpup); - while(p) { - switch(p->class) { - case processor: - switch(p->type) { - case Fpu: - printk("FPU<%s> ", (char *)p->iname); - break; - - default: - break; - }; - break; - - case cache: - switch(p->type) { - case picache: - printk("ICACHE "); - break; - - case pdcache: - printk("DCACHE "); - break; - - case sccache: - printk("SCACHE "); - break; - - default: - break; - - }; - break; - - default: - break; - }; - p = ArcGetPeer(p); - } - printk("\n"); -} diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-time.c linux-2.4.22/arch/mips/sgi-ip22/ip22-time.c --- linux-2.4.21/arch/mips/sgi-ip22/ip22-time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip22/ip22-time.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,6 +8,8 @@ * * Copyright (C) 2001 by Ladislav Michl */ + +#include #include #include #include @@ -17,11 +19,12 @@ #include #include #include +#include #include #include -#include -#include -#include +#include +#include +#include /* * note that mktime uses month from 1 to 12 while to_tm @@ -29,20 +32,20 @@ */ static unsigned long indy_rtc_get_time(void) { - unsigned char yrs, mon, day, hrs, min, sec; - unsigned char save_control; + unsigned int yrs, mon, day, hrs, min, sec; + unsigned int save_control; - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hrs = CMOS_READ(RTC_HOURS) & 0x1f; - day = CMOS_READ(RTC_DATE); - mon = CMOS_READ(RTC_MONTH) & 0x1f; - yrs = CMOS_READ(RTC_YEAR); + sec = hpc3c0->rtcregs[RTC_SECONDS] & 0xff; + min = hpc3c0->rtcregs[RTC_MINUTES] & 0xff; + hrs = hpc3c0->rtcregs[RTC_HOURS] & 0x1f; + day = hpc3c0->rtcregs[RTC_DATE] & 0xff; + mon = hpc3c0->rtcregs[RTC_MONTH] & 0x1f; + yrs = hpc3c0->rtcregs[RTC_YEAR] & 0xff; - CMOS_WRITE(save_control, RTC_CMD); + hpc3c0->rtcregs[RTC_CMD] = save_control; BCD_TO_BIN(sec); BCD_TO_BIN(min); @@ -56,13 +59,13 @@ if ((yrs += 40) < 70) yrs += 100; - return mktime((int)yrs + 1900, mon, day, hrs, min, sec); + return mktime(yrs + 1900, mon, day, hrs, min, sec); } static int indy_rtc_set_time(unsigned long tim) { struct rtc_time tm; - unsigned char save_control; + unsigned int save_control; to_tm(tim, &tm); @@ -78,53 +81,54 @@ BIN_TO_BCD(tm.tm_mon); BIN_TO_BCD(tm.tm_year); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; - CMOS_WRITE(tm.tm_year, RTC_YEAR); - CMOS_WRITE(tm.tm_mon, RTC_MONTH); - CMOS_WRITE(tm.tm_mday, RTC_DATE); - CMOS_WRITE(tm.tm_hour, RTC_HOURS); - CMOS_WRITE(tm.tm_min, RTC_MINUTES); - CMOS_WRITE(tm.tm_sec, RTC_SECONDS); - CMOS_WRITE(0, RTC_HUNDREDTH_SECOND); + hpc3c0->rtcregs[RTC_YEAR] = tm.tm_year; + hpc3c0->rtcregs[RTC_MONTH] = tm.tm_mon; + hpc3c0->rtcregs[RTC_DATE] = tm.tm_mday; + hpc3c0->rtcregs[RTC_HOURS] = tm.tm_hour; + hpc3c0->rtcregs[RTC_MINUTES] = tm.tm_min; + hpc3c0->rtcregs[RTC_SECONDS] = tm.tm_sec; + hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; - CMOS_WRITE(save_control, RTC_CMD); + hpc3c0->rtcregs[RTC_CMD] = save_control; return 0; } -static unsigned long dosample(volatile unsigned char *tcwp, - volatile unsigned char *tc2p) +static unsigned long dosample(void) { u32 ct0, ct1; volatile u8 msb, lsb; /* Start the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN); - *tc2p = (SGINT_TCSAMP_COUNTER & 0xff); - *tc2p = (SGINT_TCSAMP_COUNTER >> 8); + sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | + SGINT_TCWORD_MRGEN); + sgint->tcnt2 = SGINT_TCSAMP_COUNTER & 0xff; + sgint->tcnt2 = SGINT_TCSAMP_COUNTER >> 8; /* Get initial counter invariant */ - ct0 = read_32bit_cp0_register(CP0_COUNT); + ct0 = read_c0_count(); /* Latch and spin until top byte of counter2 is zero */ do { - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT); - lsb = *tc2p; - msb = *tc2p; - ct1 = read_32bit_cp0_register(CP0_COUNT); - } while(msb); + sgint->tcword = SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT; + lsb = sgint->tcnt2; + msb = sgint->tcnt2; + ct1 = read_c0_count(); + } while (msb); /* Stop the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST); - + sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | + SGINT_TCWORD_MSWST); /* * Return the difference, this is how far the r4k counter increments * for every 1/HZ seconds. We round off the nearest 1 MHz of master - * clock (= 1000000 / 100 / 2 = 5000 count). + * clock (= 1000000 / HZ / 2). */ - return ((ct1 - ct0) / 5000) * 5000; + //return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ); + return (ct1 - ct0) / (500000/HZ) * (500000/HZ); } /* @@ -132,62 +136,48 @@ */ void indy_time_init(void) { - struct sgi_ioc_timers *p; - volatile unsigned char *tcwp, *tc2p; unsigned long r4k_ticks[3]; unsigned long r4k_tick; - /* Figure out the r4k offset, the algorithm is very simple - * and works in _all_ cases as long as the 8254 counter - * register itself works ok (as an interrupt driving timer - * it does not because of bug, this is why we are using - * the onchip r4k counter/compare register to serve this - * purpose, but for r4k_offset calculation it will work - * ok for us). There are other very complicated ways - * of performing this calculation but this one works just - * fine so I am not going to futz around. ;-) + /* + * Figure out the r4k offset, the algorithm is very simple and works in + * _all_ cases as long as the 8254 counter register itself works ok (as + * an interrupt driving timer it does not because of bug, this is why + * we are using the onchip r4k counter/compare register to serve this + * purpose, but for r4k_offset calculation it will work ok for us). + * There are other very complicated ways of performing this calculation + * but this one works just fine so I am not going to futz around. ;-) */ - p = ioc_timers; - tcwp = &p->tcword; - tc2p = &p->tcnt2; - printk(KERN_INFO "Calibrating system timer... "); - dosample(tcwp, tc2p); /* Prime cache. */ - dosample(tcwp, tc2p); /* Prime cache. */ + dosample(); /* Prime cache. */ + dosample(); /* Prime cache. */ /* Zero is NOT an option. */ do { - r4k_ticks[0] = dosample (tcwp, tc2p); + r4k_ticks[0] = dosample(); } while (!r4k_ticks[0]); do { - r4k_ticks[1] = dosample (tcwp, tc2p); + r4k_ticks[1] = dosample(); } while (!r4k_ticks[1]); if (r4k_ticks[0] != r4k_ticks[1]) { - printk ("warning: timer counts differ, retrying..."); - r4k_ticks[2] = dosample (tcwp, tc2p); + printk("warning: timer counts differ, retrying... "); + r4k_ticks[2] = dosample(); if (r4k_ticks[2] == r4k_ticks[0] || r4k_ticks[2] == r4k_ticks[1]) r4k_tick = r4k_ticks[2]; else { - printk ("disagreement, using average..."); + printk("disagreement, using average... "); r4k_tick = (r4k_ticks[0] + r4k_ticks[1] + r4k_ticks[2]) / 3; } } else r4k_tick = r4k_ticks[0]; - printk("%d [%d.%02d MHz CPU]\n", (int) r4k_tick, - (int) (r4k_tick / 5000), (int) (r4k_tick % 5000) / 50); + printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick, + (int) (r4k_tick / (500000 / HZ)), + (int) (r4k_tick % (500000 / HZ))); mips_counter_frequency = r4k_tick * HZ; - - /* HACK ALERT! This get's called after traps initialization - * We piggyback the initialization of GIO bus here even though - * it is technically not related with the timer in any way. - * Doing it from ip22_setup wouldn't work since traps aren't - * initialized yet. - */ - sgigio_init(); } /* Generic SGI handler for (spurious) 8254 interrupts */ @@ -195,12 +185,12 @@ { int cpu = smp_processor_id(); int irq = SGI_8254_0_IRQ; - long cnt; + ULONG cnt; char c; irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; - printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n"); + printk(KERN_ALERT "Oops, got 8254 interrupt.\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); irq_exit(cpu, irq); @@ -224,21 +214,14 @@ static void indy_timer_setup(struct irqaction *irq) { - unsigned long count; - /* over-write the handler, we use our own way */ irq->handler = no_action; - /* set time for first interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - count += mips_counter_frequency / HZ; - write_32bit_cp0_register(CP0_COMPARE, count); - /* setup irqaction */ setup_irq(SGI_TIMER_IRQ, irq); } -void sgitime_init(void) +void __init ip22_time_init(void) { /* setup hookup functions */ rtc_get_time = indy_rtc_get_time; diff -urN linux-2.4.21/arch/mips/sgi-ip27/Makefile linux-2.4.22/arch/mips/sgi-ip27/Makefile --- linux-2.4.21/arch/mips/sgi-ip27/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,8 +6,6 @@ O_TARGET = ip27.o -export-objs = ip27-rtc.o - obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \ ip27-reset.o ip27-setup.o ip27-timer.o diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-berr.c linux-2.4.22/arch/mips/sgi-ip27/ip27-berr.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-berr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-berr.c 2003-08-25 04:44:40.000000000 -0700 @@ -17,9 +17,7 @@ #include #include #include - -extern void dump_tlb_addr(unsigned long addr); -extern void dump_tlb_all(void); +#include static void dump_hub_information(unsigned long errst0, unsigned long errst1) { @@ -54,7 +52,7 @@ ? : "invalid"); } -int be_ip27_handler(struct pt_regs *regs, int is_fixup) +int ip27_be_handler(struct pt_regs *regs, int is_fixup) { unsigned long errst0, errst1; int data = regs->cp0_cause & 4; @@ -76,13 +74,13 @@ force_sig(SIGBUS, current); } -void __init bus_error_init(void) +void __init ip27_be_init(void) { /* XXX Initialize all the Hub & Bridge error handling here. */ int cpu = LOCAL_HUB_L(PI_CPU_NUM); int cpuoff = cpu << 8; - be_board_handler = be_ip27_handler; + board_be_handler = ip27_be_handler; LOCAL_HUB_S(PI_ERR_INT_PEND, cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A); diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-console.c linux-2.4.22/arch/mips/sgi-ip27/ip27-console.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-console.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-console.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,25 +3,35 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 Ralf Baechle + * Copyright (C) 2001, 2002 Ralf Baechle */ #include #include #include #include +#include +#include #include #include #include #include #include -void prom_putchar(char c) +#define IOC3_BAUD (22000000 / (3*16)) +#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + +static inline struct ioc3_uartregs *console_uart(void) { struct ioc3 *ioc3; - struct ioc3_uartregs *uart; - ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base; - uart = &ioc3->sregs.uarta; + ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base; + + return &ioc3->sregs.uarta; +} + +void prom_putchar(char c) +{ + struct ioc3_uartregs *uart = console_uart(); while ((uart->iu_lsr & 0x20) == 0); uart->iu_thr = c; @@ -32,27 +42,24 @@ return 0; } -static void -ip27prom_console_write(struct console *con, const char *s, unsigned n) +static void inline ioc3_console_probe(void) { - prom_printf("%s", s); -} + struct serial_struct req; -static kdev_t -ip27prom_console_dev(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} + /* Register to interrupt zero because we share the interrupt with + the serial driver which we don't properly support yet. */ + memset(&req, 0, sizeof(req)); + req.irq = 0; + req.flags = IOC3_COM_FLAGS; + req.io_type = SERIAL_IO_MEM; + req.iomem_reg_shift = 0; + req.baud_base = IOC3_BAUD; -static struct console ip27_prom_console = { - name: "prom", - write: ip27prom_console_write, - device: ip27prom_console_dev, - flags: CON_PRINTBUFFER, - index: -1, -}; + req.iomem_base = (unsigned char *) console_uart(); + register_serial(&req); +} __init void ip27_setup_console(void) { - register_console(&ip27_prom_console); + ioc3_console_probe(); } diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-init.c linux-2.4.22/arch/mips/sgi-ip27/ip27-init.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-init.c 2003-08-25 04:44:40.000000000 -0700 @@ -193,7 +193,6 @@ void init_topology_matrix(void); void dump_topology(void); - master_nasid = get_nasid(); fine_mode = is_fine_dirmode(); @@ -203,7 +202,7 @@ */ CPUMASK_CLRALL(boot_cpumask); maxcpus = cpu_node_probe(&boot_cpumask, &numnodes); - printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes); + printk(KERN_INFO "Discovered %d cpus on %d nodes\n", maxcpus, numnodes); init_topology_matrix(); dump_topology(); @@ -333,8 +332,7 @@ memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80); memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x100); - flush_cache_l1(); - flush_cache_l2(); + __flush_cache_all(); } #endif } @@ -364,7 +362,7 @@ #if 0 intr_init(); #endif - clear_cp0_status(ST0_IM); + clear_c0_status(ST0_IM); per_hub_init(cnode); cpu_time_init(); if (smp_processor_id()) /* master can't do this early, no kmalloc */ @@ -374,13 +372,8 @@ #if 0 install_tlbintr(cpu); #endif - set_cp0_status(SRB_DEV0 | SRB_DEV1); + set_c0_status(SRB_DEV0 | SRB_DEV1); if (is_slave) { - clear_cp0_status(ST0_BEV); - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); - set_cp0_status(ST0_KX|ST0_SX|ST0_UX); - sti(); load_mmu(); atomic_inc(&numstarted); } else { @@ -422,9 +415,15 @@ static volatile cpumask_t boot_barrier; +extern atomic_t cpus_booted; + void __init start_secondary(void) { + unsigned int cpu = smp_processor_id(); + extern atomic_t smp_commenced; + CPUMASK_CLRB(boot_barrier, getcpuid()); /* needs atomicity */ + cpu_probe(); per_cpu_init(); per_cpu_trap_init(); #if 0 @@ -433,9 +432,33 @@ init_mfhi_war(); #endif local_flush_tlb_all(); - flush_cache_l1(); - flush_cache_l2(); - start_secondary(); + __flush_cache_all(); + + local_irq_enable(); +#if 0 + /* + * Get our bogomips. + */ + calibrate_delay(); + smp_store_cpu_info(cpuid); + prom_smp_finish(); +#endif + printk("Slave cpu booted successfully\n"); + CPUMASK_SETB(cpu_online_map, cpu); + atomic_inc(&cpus_booted); + + while (!atomic_read(&smp_commenced)); + return cpu_idle(); +} + +static int __init fork_by_hand(void) +{ + struct pt_regs regs; + /* + * don't care about the epc and regs settings since + * we'll never reschedule the forked task. + */ + return do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0); } __init void allowboot(void) @@ -457,68 +480,79 @@ boot_barrier = boot_cpumask; /* Launch slaves. */ for (cpu = 0; cpu < maxcpus; cpu++) { + struct task_struct *idle; + if (cpu == mycpuid) { alloc_cpupda(cpu, num_cpus); num_cpus++; /* We're already started, clear our bit */ + CPUMASK_SETB(cpu_online_map, cpu); CPUMASK_CLRB(boot_barrier, cpu); continue; } /* Skip holes in CPU space */ - if (CPUMASK_TSTB(boot_cpumask, cpu)) { - struct task_struct *p; + if (!CPUMASK_TSTB(boot_cpumask, cpu)) + continue; - /* - * The following code is purely to make sure - * Linux can schedule processes on this slave. - */ - kernel_thread(0, NULL, CLONE_PID); - p = init_task.prev_task; - sprintf(p->comm, "%s%d", "Idle", num_cpus); - init_tasks[num_cpus] = p; - alloc_cpupda(cpu, num_cpus); - del_from_runqueue(p); - p->processor = num_cpus; - p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */ - unhash_process(p); - /* Attach to the address space of init_task. */ - atomic_inc(&init_mm.mm_count); - p->active_mm = &init_mm; - - /* - * Launch a slave into smp_bootstrap(). - * It doesn't take an argument, and we - * set sp to the kernel stack of the newly - * created idle process, gp to the proc struct - * (so that current-> works). - */ - LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), - (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), - 0, (void *)((unsigned long)p + - KERNEL_STACK_SIZE - 32), (void *)p); - - /* - * Now optimistically set the mapping arrays. We - * need to wait here, verify the cpu booted up, then - * fire up the next cpu. - */ - __cpu_number_map[cpu] = num_cpus; - __cpu_logical_map[num_cpus] = cpu; - CPUMASK_SETB(cpu_online_map, cpu); - num_cpus++; - /* - * Wait this cpu to start up and initialize its hub, - * and discover the io devices it will control. - * - * XXX: We really want to fire up launch all the CPUs - * at once. We have to preserve the order of the - * devices on the bridges first though. - */ - while(atomic_read(&numstarted) != num_cpus); - } - } + /* + * We can't use kernel_thread since we must avoid to + * reschedule the child. + */ + if (fork_by_hand() < 0) + panic("failed fork for CPU %d", num_cpus); + + /* + * We remove it from the pidhash and the runqueue + * once we got the process: + */ + idle = init_task.prev_task; + if (!idle) + panic("No idle process for CPU %d", num_cpus); + + idle->processor = num_cpus; + idle->cpus_runnable = 1 << cpu; /* we schedule the first task manually */ + + alloc_cpupda(cpu, num_cpus); + + idle->thread.reg31 = (unsigned long) start_secondary; + del_from_runqueue(idle); + unhash_process(idle); + init_tasks[num_cpus] = idle; + + /* + * Launch a slave into smp_bootstrap(). + * It doesn't take an argument, and we + * set sp to the kernel stack of the newly + * created idle process, gp to the proc struct + * (so that current-> works). + */ + LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), + (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), + 0, (void *)((unsigned long)idle + + KERNEL_STACK_SIZE - 32), (void *)idle); + + /* + * Now optimistically set the mapping arrays. We + * need to wait here, verify the cpu booted up, then + * fire up the next cpu. + */ + __cpu_number_map[cpu] = num_cpus; + __cpu_logical_map[num_cpus] = cpu; + CPUMASK_SETB(cpu_online_map, cpu); + num_cpus++; + + /* + * Wait this cpu to start up and initialize its hub, + * and discover the io devices it will control. + * + * XXX: We really want to fire up launch all the CPUs + * at once. We have to preserve the order of the + * devices on the bridges first though. + */ + while (atomic_read(&numstarted) != num_cpus); + } #ifdef LATER Wait logic goes here. @@ -545,7 +579,7 @@ init_new_context(current, &init_mm); current->processor = 0; init_idle(); - smp_tune_scheduling(); + /* smp_tune_scheduling(); XXX */ allowboot(); } diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-irq.c linux-2.4.22/arch/mips/sgi-ip27/ip27-irq.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,6 +7,7 @@ */ #include #include +#include #include #include #include @@ -25,7 +26,6 @@ #include #include #include -#include #include #include @@ -68,7 +68,6 @@ */ extern asmlinkage void ip27_irq(void); -extern void do_IRQ(int irq, struct pt_regs *regs); extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[]; int intr_connect_level(int cpu, int bit); diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-pci.c linux-2.4.22/arch/mips/sgi-ip27/ip27-pci.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -70,20 +70,20 @@ return PCIBIOS_SUCCESSFUL; \ } while (0) -static int -pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value) +static int pci_conf0_read_config_byte(struct pci_dev *dev, int where, + u8 *value) { CF0_READ_PCI_CFG(dev,where,value,3,0xff); } -static int -pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value) +static int pci_conf0_read_config_word(struct pci_dev *dev, int where, + u16 *value) { CF0_READ_PCI_CFG(dev,where,value,2,0xffff); } -static int -pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value) +static int pci_conf0_read_config_dword(struct pci_dev *dev, int where, + u32 *value) { CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff); } @@ -115,20 +115,20 @@ return PCIBIOS_SUCCESSFUL; \ } while (0) -static int -pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value) +static int pci_conf0_write_config_byte(struct pci_dev *dev, int where, + u8 value) { CF0_WRITE_PCI_CFG(dev,where,value,3,0xff); } -static int -pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value) +static int pci_conf0_write_config_word(struct pci_dev *dev, int where, + u16 value) { CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff); } -static int -pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value) +static int pci_conf0_write_config_dword(struct pci_dev *dev, int where, + u32 value) { CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff); } @@ -157,14 +157,12 @@ } } -static inline u8 -bridge_swizzle(u8 pin, u8 slot) +static inline u8 bridge_swizzle(u8 pin, u8 slot) { return (((pin-1) + slot) % 4) + 1; } -static u8 __init -pci_swizzle(struct pci_dev *dev, u8 *pinp) +static u8 __devinit pci_swizzle(struct pci_dev *dev, u8 *pinp) { u8 pin = *pinp; @@ -186,8 +184,7 @@ * A given PCI device, in general, should be able to intr any of the cpus * on any one of the hubs connected to its xbow. */ -static int __init -pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __devinit pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { if ((dev->bus->number >= MAX_PCI_BUSSES) || (pin != 1) @@ -208,35 +205,18 @@ return lastirq - 1; } -void __init -pcibios_update_irq(struct pci_dev *dev, int irq) +void __init pcibios_update_irq(struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -void __init -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - unsigned long where, size; - u32 reg; - - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - -void __init -pcibios_fixup_bus(struct pci_bus *b) +void __devinit pcibios_fixup_bus(struct pci_bus *b) { pci_fixup_irqs(pci_swizzle, pci_map_irq); } -void __init -pcibios_fixup_pbus_ranges(struct pci_bus * bus, - struct pbus_set_ranges_data * ranges) +void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus, + struct pbus_set_ranges_data * ranges) { ranges->io_start -= bus->resource[0]->start; ranges->io_end -= bus->resource[0]->start; @@ -244,32 +224,11 @@ ranges->mem_end -= bus->resource[1]->start; } -int __init -pcibios_enable_device(struct pci_dev *dev) +unsigned int pcibios_assign_all_busses(void) { - /* Not needed, since we enable all devices at startup. */ return 0; } -void __init -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 0; -} - -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - /* * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses * to find the slot number in sense of the bridge device register. @@ -277,8 +236,7 @@ * settings. */ -static void __init -pci_disable_swapping(struct pci_dev *dev) +static void __init pci_disable_swapping(struct pci_dev *dev) { unsigned int bus_id = (unsigned) dev->bus->number; bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], @@ -290,8 +248,7 @@ bridge->b_widget.w_tflush; /* Flush */ } -static void __init -pci_enable_swapping(struct pci_dev *dev) +static void __init pci_enable_swapping(struct pci_dev *dev) { unsigned int bus_id = (unsigned) dev->bus->number; bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], @@ -303,8 +260,7 @@ bridge->b_widget.w_tflush; /* Flush */ } -static void __init -pci_fixup_ioc3(struct pci_dev *d) +static void __init pci_fixup_ioc3(struct pci_dev *d) { unsigned long bus_id = (unsigned) d->bus->number; @@ -316,8 +272,7 @@ pci_disable_swapping(d); } -static void __init -pci_fixup_isp1020(struct pci_dev *d) +static void __init pci_fixup_isp1020(struct pci_dev *d) { unsigned short command; @@ -341,8 +296,7 @@ pci_enable_swapping(d); } -static void __init -pci_fixup_isp2x00(struct pci_dev *d) +static void __init pci_fixup_isp2x00(struct pci_dev *d) { unsigned int bus_id = (unsigned) d->bus->number; bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-rtc.c linux-2.4.22/arch/mips/sgi-ip27/ip27-rtc.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-rtc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,334 +0,0 @@ -/* - * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip - * - * Real Time Clock interface for Linux - * - * TODO: Implement periodic interrupts. - * - * Copyright (C) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * - * Based on code written by Paul Gortmaker. - * - * This driver allows use of the real time clock (built into - * nearly all computers) from user space. It exports the /dev/rtc - * interface supporting various ioctl() and also the /proc/rtc - * pseudo-file for status information. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#define RTC_VERSION "1.09b" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static int rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -static void get_rtc_time(struct rtc_time *rtc_tm); - -/* - * Bits in rtc_status. (6 bits of room for future expansion) - */ - -#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ -#define RTC_TIMER_ON 0x02 /* missed irq timer active */ - -static unsigned char rtc_status; /* bitmapped status byte. */ -static spinlock_t rtc_status_lock = SPIN_LOCK_UNLOCKED; -static unsigned long rtc_freq; /* Current periodic IRQ rate */ -static struct m48t35_rtc *rtc; - -/* - * If this driver ever becomes modularised, it will be really nice - * to make the epoch retain its value across module reload... - */ - -static unsigned long epoch = 1970; /* year corresponding to 0x00 */ - -static const unsigned char days_in_mo[] = -{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - - struct rtc_time wtime; - - switch (cmd) { - case RTC_RD_TIME: /* Read the time/date from RTC */ - { - get_rtc_time(&wtime); - break; - } - case RTC_SET_TIME: /* Set the RTC */ - { - struct rtc_time rtc_tm; - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned int yrs; - unsigned long flags; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - yrs = rtc_tm.tm_year + 1900; - mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm.tm_mday; - hrs = rtc_tm.tm_hour; - min = rtc_tm.tm_min; - sec = rtc_tm.tm_sec; - - if (yrs < 1970) - return -EINVAL; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if ((yrs -= epoch) > 255) /* They are unsigned */ - return -EINVAL; - - save_flags(flags); - cli(); - if (yrs > 169) { - restore_flags(flags); - return -EINVAL; - } - if (yrs >= 100) - yrs -= 100; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(yrs); - - rtc->control &= ~M48T35_RTC_SET; - rtc->year = yrs; - rtc->month = mon; - rtc->date = day; - rtc->hour = hrs; - rtc->min = min; - rtc->sec = sec; - rtc->control &= ~M48T35_RTC_SET; - - restore_flags(flags); - return 0; - } - default: - return -EINVAL; - } - return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; -} - -/* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. - */ - -static int rtc_open(struct inode *inode, struct file *file) -{ - spin_lock(rtc_status_lock); - - if (rtc_status & RTC_IS_OPEN) { - spin_unlock(rtc_status_lock); - return -EBUSY; - } - - rtc_status |= RTC_IS_OPEN; - spin_unlock(rtc_status_lock); - - return 0; -} - -static int rtc_release(struct inode *inode, struct file *file) -{ - /* - * Turn off all interrupts once the device is no longer - * in use, and clear the data. - */ - - spin_lock(rtc_status_lock); - rtc_status &= ~RTC_IS_OPEN; - spin_unlock(rtc_status_lock); - - return 0; -} - -/* - * The various file operations we support. - */ - -static struct file_operations rtc_fops = { - owner: THIS_MODULE, - ioctl: rtc_ioctl, - open: rtc_open, - release: rtc_release, -}; - -static struct miscdevice rtc_dev= -{ - RTC_MINOR, - "rtc", - &rtc_fops -}; - -static int __init rtc_init(void) -{ - unsigned long flags; - nasid_t nid; - - nid = get_nasid(); - rtc = (struct m48t35_rtc *) - KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0; - - printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); - if (misc_register(&rtc_dev)) - return -ENODEV; - create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL); - - save_flags(flags); - cli(); - restore_flags(flags); - rtc_freq = 1024; - return 0; -} - -static void __exit rtc_exit (void) -{ - /* interrupts and timer disabled at this point by rtc_release */ - - remove_proc_entry ("rtc", NULL); - misc_deregister(&rtc_dev); -} - -module_init(rtc_init); -module_exit(rtc_exit); -EXPORT_NO_SYMBOLS; - -/* - * Info exported via "/proc/rtc". - */ - -static int rtc_get_status(char *buf) -{ - char *p; - struct rtc_time tm; - - /* - * Just emulate the standard /proc/rtc - */ - - p = buf; - - get_rtc_time(&tm); - - /* - * There is no way to tell if the luser has the RTC set for local - * time or for Universal Standard Time (GMT). Probably local though. - */ - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" - "rtc_epoch\t: %04lu\n" - "24hr\t\t: yes\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); - - return p - buf; -} - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = rtc_get_status(page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} - -static void get_rtc_time(struct rtc_time *rtc_tm) -{ - - unsigned long flags; - - /* - * Do we need to wait for the last update to finish? - */ - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - save_flags(flags); - cli(); - rtc->control |= M48T35_RTC_READ; - rtc_tm->tm_sec = rtc->sec; - rtc_tm->tm_min = rtc->min; - rtc_tm->tm_hour = rtc->hour; - rtc_tm->tm_mday = rtc->date; - rtc_tm->tm_mon = rtc->month; - rtc_tm->tm_year = rtc->year; - rtc->control &= ~M48T35_RTC_READ; - restore_flags(flags); - - BCD_TO_BIN(rtc_tm->tm_sec); - BCD_TO_BIN(rtc_tm->tm_min); - BCD_TO_BIN(rtc_tm->tm_hour); - BCD_TO_BIN(rtc_tm->tm_mday); - BCD_TO_BIN(rtc_tm->tm_mon); - BCD_TO_BIN(rtc_tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-setup.c linux-2.4.22/arch/mips/sgi-ip27/ip27-setup.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,6 +29,7 @@ #include #include #include +#include /* Check against user dumbness. */ #ifdef CONFIG_VT @@ -42,6 +43,8 @@ #define DBG(x...) #endif +extern void ip27_be_init(void) __init; + /* * get_nasid() returns the physical node id number of the caller. */ @@ -276,6 +279,7 @@ extern void ip27_setup_console(void); extern void ip27_time_init(void); +extern void ip27_reboot_setup(void); void __init ip27_setup(void) { @@ -283,6 +287,7 @@ hubreg_t p, e; ip27_setup_console(); + ip27_reboot_setup(); num_bridges = 0; /* @@ -309,6 +314,8 @@ ioc3_eth_init(); per_cpu_init(); - mips_io_port_base = IO_BASE; + set_io_port_base(IO_BASE); + + board_be_init = ip27_be_init; board_time_init = ip27_time_init; } diff -urN linux-2.4.21/arch/mips/sgi-ip27/ip27-timer.c linux-2.4.22/arch/mips/sgi-ip27/ip27-timer.c --- linux-2.4.21/arch/mips/sgi-ip27/ip27-timer.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip27/ip27-timer.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copytight (C) 1999, 2000, 2002 Ralf Baechle (ralf@gnu.org) * Copytight (C) 1999, 2000 Silicon Graphics, Inc. */ #include @@ -55,6 +55,7 @@ rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); + spin_lock(&rtc_lock); rtc->control |= M48T35_RTC_READ; cmos_minutes = rtc->min; BCD_TO_BIN(cmos_minutes); @@ -84,15 +85,18 @@ cmos_minutes, real_minutes); retval = -1; } + spin_unlock(&rtc_lock); return retval; } +#define IP27_TIMER_IRQ 9 /* XXX Assign number */ + void rt_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); int cpuA = ((cputoslice(cpu)) == 0); - int irq = 9; /* XXX Assign number */ + int irq = IP27_TIMER_IRQ; irq_enter(cpu, irq); write_lock(&xtime_lock); @@ -157,7 +161,7 @@ static __init unsigned long get_m48t35_time(void) { - unsigned int year, month, date, hour, min, sec; + unsigned int year, month, date, hour, min, sec; struct m48t35_rtc *rtc; nasid_t nid; @@ -165,6 +169,7 @@ rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); + spin_lock(&rtc_lock); rtc->control |= M48T35_RTC_READ; sec = rtc->sec; min = rtc->min; @@ -173,17 +178,27 @@ month = rtc->month; year = rtc->year; rtc->control &= ~M48T35_RTC_READ; + spin_unlock(&rtc_lock); + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(date); + BCD_TO_BIN(month); + BCD_TO_BIN(year); + + year += 1970; - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(date); - BCD_TO_BIN(month); - BCD_TO_BIN(year); + return mktime(year, month, date, hour, min, sec); +} - year += 1970; +static void ip27_timer_setup(struct irqaction *irq) +{ + /* over-write the handler, we use our own way */ + irq->handler = no_action; - return mktime(year, month, date, hour, min, sec); + /* setup irqaction */ +// setup_irq(IP27_TIMER_IRQ, irq); /* XXX Can't do this yet. */ } void __init ip27_time_init(void) @@ -192,6 +207,9 @@ xtime.tv_usec = 0; do_gettimeoffset = ip27_do_gettimeoffset; + + // board_time_init = ip27_time_init; + board_timer_setup = ip27_timer_setup; } void __init cpu_time_init(void) @@ -212,7 +230,7 @@ printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); - set_cp0_status(SRB_TIMOCLK); + set_c0_status(SRB_TIMOCLK); } void __init hub_rtc_init(cnodeid_t cnode) diff -urN linux-2.4.21/arch/mips/sgi-ip32/Makefile linux-2.4.22/arch/mips/sgi-ip32/Makefile --- linux-2.4.21/arch/mips/sgi-ip32/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,22 +0,0 @@ -# -# Makefile for the SGI specific kernel interface routines -# under Linux. -# -# 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... - -USE_STANDARD_AS_RULE := true - -O_TARGET := ip32-kern.a - -all: ip32-kern.a ip32-irq-glue.o - -obj-y += ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \ - ip32-timer.o crime.o ip32-reset.o - -obj-$(CONFIG_PCI) += ip32-pci.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/sgi-ip32/crime.c linux-2.4.22/arch/mips/sgi-ip32/crime.c --- linux-2.4.21/arch/mips/sgi-ip32/crime.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/crime.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,49 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include - -void __init crime_init (void) -{ - u64 id = crime_read_64 (CRIME_ID); - u64 rev = id & CRIME_ID_REV; - - id = (id & CRIME_ID_IDBITS) >> 4; - - printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev, - (unsigned long) CRIME_BASE); -} - -/* XXX Like on Sun, these give us various useful information to printk. */ -void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) -{ - u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT); - u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR); - memerr &= CRIME_MEM_ERROR_STAT_MASK; - - printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n", - addr << 2, memerr); - - crime_write_64 (CRIME_MEM_ERROR_STAT, 0); -} - -void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) -{ - u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT); - u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR); - cpuerr &= CRIME_CPU_ERROR_MASK; - addr <<= 2UL; - - printk ("CRIME CPU interface error detected at %09lx status %08lx\n", - addr, cpuerr); - - crime_write_64 (CRIME_CPU_ERROR_STAT, 0); -} diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-berr.c linux-2.4.22/arch/mips/sgi-ip32/ip32-berr.c --- linux-2.4.21/arch/mips/sgi-ip32/ip32-berr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-berr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,36 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle - * Copyright (C) 1999, 2000 by Silicon Graphics - * Copyright (C) 2002 Maciej W. Rozycki - */ -#include -#include -#include -#include -#include -#include - -int -be_ip32_handler(struct pt_regs *regs, int is_fixup) -{ - int data = regs->cp0_cause & 4; - - if (is_fixup) - return MIPS_BE_FIXUP; - - printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc); - show_regs(regs); - dump_tlb_all(); - while(1); - force_sig(SIGBUS, current); -} - -void __init -bus_error_init(void) -{ - be_board_handler = be_ip32_handler; -} diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-irq-glue.S linux-2.4.22/arch/mips/sgi-ip32/ip32-irq-glue.S --- linux-2.4.21/arch/mips/sgi-ip32/ip32-irq-glue.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-irq-glue.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,87 +0,0 @@ -/* - * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Harald Koerfgen - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include - - .text - .set noreorder - .set noat - .align 5 - NESTED(ip32_handle_int, PT_SIZE, ra) - .set noat - SAVE_ALL - CLI # TEST: interrupts should be off - .set at - .set noreorder - - mfc0 s0,CP0_CAUSE - - andi t1, s0, IE_IRQ0 - bnez t1, handle_irq0 - andi t1, s0, IE_IRQ1 - bnez t1, handle_irq1 - andi t1, s0, IE_IRQ2 - bnez t1, handle_irq2 - andi t1, s0, IE_IRQ3 - bnez t1, handle_irq3 - andi t1, s0, IE_IRQ4 - bnez t1, handle_irq4 - andi t1, s0, IE_IRQ5 - bnez t1, handle_irq5 - nop - - /* Either someone has triggered the "software interrupts" - * or we lost an interrupt somehow. Ignore it. - */ - j ret_from_irq - nop - -handle_irq0: - jal ip32_irq0 - move a0, sp - j ret_from_irq - nop - -handle_irq1: - jal ip32_irq1 - move a0, sp - j ret_from_irq - nop - -handle_irq2: - jal ip32_irq2 - move a0, sp - j ret_from_irq - nop - -handle_irq3: - jal ip32_irq3 - move a0, sp - j ret_from_irq - nop - -handle_irq4: - jal ip32_irq4 - move a0, sp - j ret_from_irq - nop - -handle_irq5: - jal ip32_irq5 - move a0, sp - j ret_from_irq - nop - - END(ip32_handle_int) diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-irq.c linux-2.4.22/arch/mips/sgi-ip32/ip32-irq.c --- linux-2.4.21/arch/mips/sgi-ip32/ip32-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,584 +0,0 @@ -/* - * Code to handle IP32 IRQs - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Harald Koerfgen - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG_IRQ -#ifdef DEBUG_IRQ -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* O2 irq map - * - * IP0 -> software (ignored) - * IP1 -> software (ignored) - * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ??? - * IP3 -> (irq1) X unknown - * IP4 -> (irq2) X unknown - * IP5 -> (irq3) X unknown - * IP6 -> (irq4) X unknown - * IP7 -> (irq5) 0 CPU count/compare timer (system timer) - * - * crime: (C) - * - * CRIME_INT_STAT 31:0: - * - * 0 -> 1 Video in 1 - * 1 -> 2 Video in 2 - * 2 -> 3 Video out - * 3 -> 4 Mace ethernet - * 4 -> S SuperIO sub-interrupt - * 5 -> M Miscellaneous sub-interrupt - * 6 -> A Audio sub-interrupt - * 7 -> 8 PCI bridge errors - * 8 -> 9 PCI SCSI aic7xxx 0 - * 9 -> 10 PCI SCSI aic7xxx 1 - * 10 -> 11 PCI slot 0 - * 11 -> 12 unused (PCI slot 1) - * 12 -> 13 unused (PCI slot 2) - * 13 -> 14 unused (PCI shared 0) - * 14 -> 15 unused (PCI shared 1) - * 15 -> 16 unused (PCI shared 2) - * 16 -> 17 GBE0 (E) - * 17 -> 18 GBE1 (E) - * 18 -> 19 GBE2 (E) - * 19 -> 20 GBE3 (E) - * 20 -> 21 CPU errors - * 21 -> 22 Memory errors - * 22 -> 23 RE empty edge (E) - * 23 -> 24 RE full edge (E) - * 24 -> 25 RE idle edge (E) - * 25 -> 26 RE empty level - * 26 -> 27 RE full level - * 27 -> 28 RE idle level - * 28 -> 29 unused (software 0) (E) - * 29 -> 30 unused (software 1) (E) - * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E) - * 31 -> 32 VICE - * - * S, M, A: Use the MACE ISA interrupt register - * MACE_ISA_INT_STAT 31:0 - * - * 0-7 -> 33-40 Audio - * 8 -> 41 RTC - * 9 -> 42 Keyboard - * 10 -> X Keyboard polled - * 11 -> 44 Mouse - * 12 -> X Mouse polled - * 13-15 -> 46-48 Count/compare timers - * 16-19 -> 49-52 Parallel (16 E) - * 20-25 -> 53-58 Serial 1 (22 E) - * 26-31 -> 59-64 Serial 2 (28 E) - * - * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a - * different IRQ map than IRIX uses, but that's OK as Linux irq handling - * is quite different anyway. - */ - -/* Some initial interrupts to set up */ -extern void crime_memerr_intr (unsigned int irq, void *dev_id, - struct pt_regs *regs); -extern void crime_cpuerr_intr (unsigned int irq, void *dev_id, - struct pt_regs *regs); - -struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, - 0, "CRIME memory error", NULL, - NULL }; -struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, - 0, "CRIME CPU error", NULL, - NULL }; - -extern void ip32_handle_int (void); -asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); - -/* - * For interrupts wired from a single device to the CPU. Only the clock - * uses this it seems, which is IRQ 0 and IP7. - */ - -static void enable_cpu_irq(unsigned int irq) -{ - set_cp0_status(STATUSF_IP7); -} - -static unsigned int startup_cpu_irq(unsigned int irq) -{ - enable_cpu_irq(irq); - return 0; -} - -static void disable_cpu_irq(unsigned int irq) -{ - clear_cp0_status(STATUSF_IP7); -} - -static void end_cpu_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_cpu_irq (irq); -} - -#define shutdown_cpu_irq disable_cpu_irq -#define mask_and_ack_cpu_irq disable_cpu_irq - -static struct hw_interrupt_type ip32_cpu_interrupt = { - "IP32 CPU", - startup_cpu_irq, - shutdown_cpu_irq, - enable_cpu_irq, - disable_cpu_irq, - mask_and_ack_cpu_irq, - end_cpu_irq, - NULL -}; - -/* - * This is for pure CRIME interrupts - ie not MACE. The advantage? - * We get to split the register in half and do faster lookups. - */ - -static void enable_crime_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static unsigned int startup_crime_irq(unsigned int irq) -{ - enable_crime_irq(irq); - return 0; /* This is probably not right; we could have pending irqs */ -} - -static void disable_crime_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static void mask_and_ack_crime_irq (unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - /* Edge triggered interrupts must be cleared. */ - if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) - || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) - || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_HARD_INT); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64(CRIME_HARD_INT, crime_mask); - restore_flags(flags); - } - disable_crime_irq(irq); -} - -static void end_crime_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_crime_irq (irq); -} - -#define shutdown_crime_irq disable_crime_irq - -static struct hw_interrupt_type ip32_crime_interrupt = { - "IP32 CRIME", - startup_crime_irq, - shutdown_crime_irq, - enable_crime_irq, - disable_crime_irq, - mask_and_ack_crime_irq, - end_crime_irq, - NULL -}; - -/* - * This is for MACE PCI interrupts. We can decrease bus traffic by masking - * as close to the source as possible. This also means we can take the - * next chunk of the CRIME register in one piece. - */ - -static void enable_macepci_irq(unsigned int irq) -{ - u32 mace_mask; - u64 crime_mask; - unsigned long flags; - - save_and_cli(flags); - mace_mask = mace_read_32(MACEPCI_CONTROL); - mace_mask |= MACEPCI_CONTROL_INT(irq - 9); - mace_write_32(MACEPCI_CONTROL, mace_mask); - /* - * In case the CRIME interrupt isn't enabled, we must enable it; - * however, we never disable interrupts at that level. - */ - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static unsigned int startup_macepci_irq(unsigned int irq) -{ - enable_macepci_irq (irq); - - return 0; /* XXX */ -} - -static void disable_macepci_irq(unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - save_and_cli(flags); - mace_mask = mace_read_32(MACEPCI_CONTROL); - mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9); - mace_write_32(MACEPCI_CONTROL, mace_mask); - restore_flags(flags); -} - -static void end_macepci_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_macepci_irq (irq); -} - -#define shutdown_macepci_irq disable_macepci_irq -#define mask_and_ack_macepci_irq disable_macepci_irq - -static struct hw_interrupt_type ip32_macepci_interrupt = { - "IP32 MACE PCI", - startup_macepci_irq, - shutdown_macepci_irq, - enable_macepci_irq, - disable_macepci_irq, - mask_and_ack_macepci_irq, - end_macepci_irq, - NULL -}; - -/* This is used for MACE ISA interrupts. That means bits 4-6 in the - * CRIME register. - */ - -static void enable_maceisa_irq (unsigned int irq) -{ - u64 crime_mask; - u32 mace_mask; - unsigned int crime_int = 0; - unsigned long flags; - - DBG ("maceisa enable: %u\n", irq); - - switch (irq) { - case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: - crime_int = MACE_AUDIO_INT; - break; - case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ: - crime_int = MACE_MISC_INT; - break; - case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ: - crime_int = MACE_SUPERIO_INT; - break; - } - DBG ("crime_int %016lx enabled\n", crime_int); - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask |= crime_int; - crime_write_64(CRIME_INT_MASK, crime_mask); - mace_mask = mace_read_32(MACEISA_INT_MASK); - mace_mask |= 1 << (irq - 33); - mace_write_32(MACEISA_INT_MASK, mace_mask); - restore_flags(flags); -} - -static unsigned int startup_maceisa_irq (unsigned int irq) -{ - enable_maceisa_irq(irq); - return 0; -} - -static void disable_maceisa_irq(unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - save_and_cli (flags); - mace_mask = mace_read_32(MACEISA_INT_MASK); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32(MACEISA_INT_MASK, mace_mask); - restore_flags(flags); -} - -static void mask_and_ack_maceisa_irq(unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - switch (irq) { - case MACEISA_PARALLEL_IRQ: - case MACEISA_SERIAL1_TDMAPR_IRQ: - case MACEISA_SERIAL2_TDMAPR_IRQ: - save_and_cli(flags); - mace_mask = mace_read_32(MACEISA_INT_STAT); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32(MACEISA_INT_STAT, mace_mask); - restore_flags(flags); - break; - } - disable_maceisa_irq(irq); -} - -static void end_maceisa_irq(unsigned irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_maceisa_irq (irq); -} - -#define shutdown_maceisa_irq disable_maceisa_irq - -static struct hw_interrupt_type ip32_maceisa_interrupt = { - "IP32 MACE ISA", - startup_maceisa_irq, - shutdown_maceisa_irq, - enable_maceisa_irq, - disable_maceisa_irq, - mask_and_ack_maceisa_irq, - end_maceisa_irq, - NULL -}; - -/* This is used for regular non-ISA, non-PCI MACE interrupts. That means - * bits 0-3 and 7 in the CRIME register. - */ - -static void enable_mace_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -static unsigned int startup_mace_irq(unsigned int irq) -{ - enable_mace_irq(irq); - return 0; -} - -static void disable_mace_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static void end_mace_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_mace_irq (irq); -} - -#define shutdown_mace_irq disable_mace_irq -#define mask_and_ack_mace_irq disable_mace_irq - -static struct hw_interrupt_type ip32_mace_interrupt = { - "IP32 MACE", - startup_mace_irq, - shutdown_mace_irq, - enable_mace_irq, - disable_mace_irq, - mask_and_ack_mace_irq, - end_mace_irq, - NULL -}; - -static void ip32_unknown_interrupt (struct pt_regs *regs) -{ - u64 crime; - u32 mace; - - printk ("Unknown interrupt occurred!\n"); - printk ("cp0_status: %08x\tcp0_cause: %08x\n", - read_32bit_cp0_register (CP0_STATUS), - read_32bit_cp0_register (CP0_CAUSE)); - crime = crime_read_64 (CRIME_INT_MASK); - printk ("CRIME interrupt mask: %016lx\n", crime); - crime = crime_read_64 (CRIME_INT_STAT); - printk ("CRIME interrupt status: %016lx\n", crime); - crime = crime_read_64 (CRIME_HARD_INT); - printk ("CRIME hardware interrupt register: %016lx\n", crime); - mace = mace_read_32 (MACEISA_INT_MASK); - printk ("MACE ISA interrupt mask: %08x\n", mace); - mace = mace_read_32 (MACEISA_INT_STAT); - printk ("MACE ISA interrupt status: %08x\n", mace); - mace = mace_read_32 (MACEPCI_CONTROL); - printk ("MACE PCI control register: %08x\n", mace); - - printk("Register dump:\n"); - show_regs(regs); - - printk("Please mail this report to linux-mips@oss.sgi.com\n"); - printk("Spinning..."); - while(1) ; -} - -/* CRIME 1.1 appears to deliver all interrupts to this one pin. */ -void ip32_irq0(struct pt_regs *regs) -{ - u64 crime_int; - u64 crime_mask; - int irq = 0; - unsigned long flags; - - save_and_cli (flags); - /* disable crime interrupts */ - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_write_64(CRIME_INT_MASK, 0); - - crime_int = crime_read_64(CRIME_INT_STAT); - - if (crime_int & CRIME_MACE_INT_MASK) { - crime_int &= CRIME_MACE_INT_MASK; - irq = ffs (crime_int); - } else if (crime_int & CRIME_MACEISA_INT_MASK) { - u32 mace_int; - mace_int = mace_read_32 (MACEISA_INT_STAT); - if (mace_int == 0) - irq = 0; - else - irq = ffs (mace_int) + 32; - } else if (crime_int & CRIME_MACEPCI_INT_MASK) { - crime_int &= CRIME_MACEPCI_INT_MASK; - crime_int >>= 8; - irq = ffs (crime_int) + 8; - } else if (crime_int & 0xffff0000) { - crime_int >>= 16; - irq = ffs (crime_int) + 16; - } - if (irq == 0) - ip32_unknown_interrupt(regs); - DBG("*irq %u*\n", irq); - do_IRQ(irq, regs); - - /* enable crime interrupts */ - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -void ip32_irq1(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq2(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq3(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq4(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq5(struct pt_regs *regs) -{ - do_IRQ (CLOCK_IRQ, regs); -} - -void __init init_IRQ(void) -{ - unsigned int irq; - int i; - - /* Install our interrupt handler, then clear and disable all - * CRIME and MACE interrupts. - */ - crime_write_64(CRIME_INT_MASK, 0); - crime_write_64(CRIME_HARD_INT, 0); - crime_write_64(CRIME_SOFT_INT, 0); - mace_write_32(MACEISA_INT_STAT, 0); - mace_write_32(MACEISA_INT_MASK, 0); - set_except_vector(0, ip32_handle_int); - - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].handler = &no_irq_type; - } - - for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { - hw_irq_controller *controller; - - if (irq == CLOCK_IRQ) - controller = &ip32_cpu_interrupt; - else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ) - controller = &ip32_mace_interrupt; - else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ) - controller = &ip32_macepci_interrupt; - else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ) - controller = &ip32_crime_interrupt; - else - controller = &ip32_maceisa_interrupt; - - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = 0; - irq_desc[irq].depth = 0; - irq_desc[irq].handler = controller; - } - setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); - setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); -} diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-pci.c linux-2.4.22/arch/mips/sgi-ip32/ip32-pci.c --- linux-2.4.21/arch/mips/sgi-ip32/ip32-pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,460 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000, 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG_MACE_PCI - -/* - * O2 has up to 5 PCI devices connected into the MACE bridge. The device - * map looks like this: - * - * 0 aic7xxx 0 - * 1 aic7xxx 1 - * 2 expansion slot - * 3 N/C - * 4 N/C - */ - -#define chkslot(dev) \ -do { \ - if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1 \ - || PCI_SLOT ((dev)->devfn) > 3) \ - return PCIBIOS_DEVICE_NOT_FOUND; \ -} while (0) - -#define mkaddr(dev, where) \ -((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL)) - -void macepci_error (int irq, void *dev, struct pt_regs *regs); - -static int macepci_read_config_byte (struct pci_dev *dev, int where, - u8 *val) -{ - *val = 0xff; - chkslot (dev); - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL)); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_read_config_word (struct pci_dev *dev, int where, - u16 *val) -{ - *val = 0xffff; - chkslot (dev); - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL)); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_read_config_dword (struct pci_dev *dev, int where, - u32 *val) -{ - *val = 0xffffffff; - chkslot (dev); - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_32 (MACEPCI_CONFIG_DATA); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_byte (struct pci_dev *dev, int where, - u8 val) -{ - chkslot (dev); - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_word (struct pci_dev *dev, int where, - u16 val) -{ - chkslot (dev); - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_dword (struct pci_dev *dev, int where, - u32 val) -{ - chkslot (dev); - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_32 (MACEPCI_CONFIG_DATA, val); - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops macepci_ops = { - macepci_read_config_byte, - macepci_read_config_word, - macepci_read_config_dword, - macepci_write_config_byte, - macepci_write_config_word, - macepci_write_config_dword -}; - -struct pci_fixup pcibios_fixups[] = { { 0 } }; - -void __init pcibios_init (void) -{ - struct pci_dev *dev; - u32 start, size; - u16 cmd; - u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */ - u32 base_mem = 0x80100000; /* Likewise */ - u32 rev = mace_read_32 (MACEPCI_REV); - int i; - - printk ("MACE: PCI rev %d detected at %016lx\n", rev, - (u64) MACE_BASE + MACE_PCI); - - /* These are *bus* addresses */ - ioport_resource.start = 0; - ioport_resource.end = 0xffffffffUL; - iomem_resource.start = 0x80000000UL; - iomem_resource.end = 0xffffffffUL; - - /* Clear any outstanding errors and enable interrupts */ - mace_write_32 (MACEPCI_ERROR_ADDR, 0); - mace_write_32 (MACEPCI_ERROR_FLAGS, 0); - mace_write_32 (MACEPCI_CONTROL, 0xff008500); - crime_write_64 (CRIME_HARD_INT, 0UL); - crime_write_64 (CRIME_SOFT_INT, 0UL); - crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL); - - if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0, - "MACE PCI error", NULL)) - panic("PCI bridge can't get interrupt; can't happen."); - - pci_scan_bus (0, &macepci_ops, NULL); - -#ifdef DEBUG_MACE_PCI - pci_for_each_dev (dev) { - printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n", - dev->bus->number, PCI_SLOT (dev->devfn), - PCI_FUNC (dev->devfn)); - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start == 0) - continue; - printk ("%d: %016lx - %016lx (flags %04lx)\n", - i, dev->resource[i].start, - dev->resource[i].end, dev->resource[i].flags); - } - } -#endif - /* - * Assign sane resources to and enable all devices. The requirement - * for the SCSI controllers is well-known: a 256-byte I/O region - * which we must assign, and a 1-page memory region which is - * assigned by the system firmware. - */ - pci_for_each_dev (dev) { - switch (PCI_SLOT (dev->devfn)) { - case 1: /* SCSI bus 0 */ - dev->resource[0].start = 0x1000UL; - dev->resource[0].end = 0x10ffUL; - break; - case 2: /* SCSI bus 1 */ - dev->resource[0].start = 0x2000UL; - dev->resource[0].end = 0x20ffUL; - break; - default: /* Slots - I guess we have only 1 */ - for (i=0; i < 6; i++) { - size = dev->resource[i].end - - dev->resource[i].start; - if (!size - || !(dev->resource[i].flags - & (IORESOURCE_IO|IORESOURCE_MEM))) { - dev->resource[i].start - = dev->resource[i].end = 0UL; - continue; - } - if (dev->resource[i].flags & IORESOURCE_IO) { - dev->resource[i].start = base_io; - base_io += PAGE_ALIGN (size); - } else { - dev->resource[i].start = base_mem; - base_mem += 0x100000UL; - } - dev->resource[i].end = - dev->resource[i].start + size; - } - break; - } - for (i=0; i < 6; i++) { - if (dev->resource[i].start == 0) - continue; - start = dev->resource[i].start; - if (dev->resource[i].flags & IORESOURCE_IO) - start |= 1; - pci_write_config_dword (dev, - PCI_BASE_ADDRESS_0 + (i << 2), (u32) start); - } - pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20); - pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30); - pci_read_config_word (dev, PCI_COMMAND, &cmd); - cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY); - pci_write_config_word (dev, PCI_COMMAND, cmd); - pci_set_master (dev); - } - /* - * Fixup O2 PCI slot. Bad hack. - */ -/* devtag = pci_make_tag(0, 0, 3, 0); - - slot = macepci_conf_read(0, devtag, PCI_COMMAND_STATUS_REG); - slot |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE; - macepci_conf_write(0, devtag, PCI_COMMAND_STATUS_REG, slot); - - slot = macepci_conf_read(0, devtag, PCI_MAPREG_START); - if (slot == 0xffffffe1) - macepci_conf_write(0, devtag, PCI_MAPREG_START, 0x00001000); - - slot = macepci_conf_read(0, devtag, PCI_MAPREG_START + (2 << 2)); - if ((slot & 0xffff0000) == 0) { - slot += 0x00010000; - macepci_conf_write(0, devtag, PCI_MAPREG_START + (2 << 2), - 0x00000000); - } - */ -#ifdef DEBUG_MACE_PCI - printk ("Triggering PCI bridge interrupt...\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST); - - pci_for_each_dev (dev) { - printk ("Device: %d/%d/%d final bus resource map\n", - dev->bus->number, PCI_SLOT (dev->devfn), - PCI_FUNC (dev->devfn)); - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start == 0) - continue; - printk ("%d: %016lx - %016lx (flags %04lx)\n", - i, dev->resource[i].start, - dev->resource[i].end, dev->resource[i].flags); - } - } -#endif -} - -/* - * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of - * the device (1-4 => A-D), tell what irq to use. Note that we don't - * in theory have slots 4 and 5, and we never normally use the shared - * irqs. I suppose a device without a pin A will thank us for doing it - * right if there exists such a broken piece of crap. - */ -static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin) -{ - chkslot (dev); - if (pin == 0) - pin = 1; - switch (slot) { - case 1: - return MACEPCI_SCSI0_IRQ; - case 2: - return MACEPCI_SCSI1_IRQ; - case 3: - switch (pin) { - case 2: - return MACEPCI_SHARED0_IRQ; - case 3: - return MACEPCI_SHARED1_IRQ; - case 4: - return MACEPCI_SHARED2_IRQ; - case 1: - default: - return MACEPCI_SLOT0_IRQ; - } - case 4: - switch (pin) { - case 2: - return MACEPCI_SHARED2_IRQ; - case 3: - return MACEPCI_SHARED0_IRQ; - case 4: - return MACEPCI_SHARED1_IRQ; - case 1: - default: - return MACEPCI_SLOT1_IRQ; - } - return MACEPCI_SLOT1_IRQ; - case 5: - switch (pin) { - case 2: - return MACEPCI_SHARED1_IRQ; - case 3: - return MACEPCI_SHARED2_IRQ; - case 4: - return MACEPCI_SHARED0_IRQ; - case 1: - default: - return MACEPCI_SLOT2_IRQ; - } - default: - return 0; - } -} - -/* - * It's not entirely clear what this does in a system with no bridges. - * In any case, bridges are not supported by Linux in O2. - */ -static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp) -{ - if (PCI_SLOT (dev->devfn) == 2) - *pinp = 2; - else - *pinp = 1; - return PCI_SLOT (dev->devfn); -} - -/* All devices are enabled during initialization. */ -int pcibios_enable_device (struct pci_dev *dev) -{ - return PCIBIOS_SUCCESSFUL; -} - -char * __init pcibios_setup (char *str) -{ - return str; -} - -void __init pcibios_align_resource (void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ -} - -void __init pcibios_update_irq (struct pci_dev *dev, int irq) -{ - pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq); -} - -void __init pcibios_fixup_bus (struct pci_bus *b) -{ - pci_fixup_irqs (macepci_swizzle, macepci_map_irq); -} - -/* XXX anybody know what this is supposed to do? */ -void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus, - struct pbus_set_ranges_data * ranges) -{ - ranges->io_start -= bus->resource[0]->start; - ranges->io_end -= bus->resource[0]->start; - ranges->mem_start -= bus->resource[1]->start; - ranges->mem_end -= bus->resource[1]->start; -} - -/* - * Handle errors from the bridge. This includes master and target aborts, - * various command and address errors, and the interrupt test. This gets - * registered on the bridge error irq. It's conceivable that some of these - * conditions warrant a panic. Anybody care to say which ones? - */ -void macepci_error (int irq, void *dev, struct pt_regs *regs) { - u32 flags, error_addr; - char space; - - flags = mace_read_32 (MACEPCI_ERROR_FLAGS); - error_addr = mace_read_32 (MACEPCI_ERROR_ADDR); - - if (flags & MACEPCI_ERROR_MEMORY_ADDR) - space = 'M'; - else if (flags & MACEPCI_ERROR_CONFIG_ADDR) - space = 'C'; - else space = 'X'; - - if (flags & MACEPCI_ERROR_MASTER_ABORT) { - printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_MASTER_ABORT); - } - if (flags & MACEPCI_ERROR_TARGET_ABORT) { - printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_TARGET_ABORT); - } - if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) { - printk ("MACEPCI: Data parity error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_DATA_PARITY_ERR); - } - if (flags & MACEPCI_ERROR_RETRY_ERR) { - printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_RETRY_ERR); - } - if (flags & MACEPCI_ERROR_ILLEGAL_CMD) { - printk ("MACEPCI: Illegal command at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, - flags & ~MACEPCI_ERROR_ILLEGAL_CMD); - } - if (flags & MACEPCI_ERROR_SYSTEM_ERR) { - printk ("MACEPCI: System error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_SYSTEM_ERR); - } - if (flags & MACEPCI_ERROR_PARITY_ERR) { - printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_PARITY_ERR); - } - if (flags & MACEPCI_ERROR_OVERRUN) { - printk ("MACEPCI: Overrun error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_OVERRUN); - } - if (flags & MACEPCI_ERROR_SIG_TABORT) { - printk ("MACEPCI: Signaled target abort (clearing)\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_SIG_TABORT); - } - if (flags & MACEPCI_ERROR_INTERRUPT_TEST) { - printk ("MACEPCI: Interrupt test triggered (clearing)\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_INTERRUPT_TEST); - } -} -unsigned __init int pcibios_assign_all_busses(void) -{ - return 0; -} diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-reset.c linux-2.4.22/arch/mips/sgi-ip32/ip32-reset.c --- linux-2.4.21/arch/mips/sgi-ip32/ip32-reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-reset.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,34 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 Keith M Wesolowski - * Copyright (C) 2001 Paul Mundt - */ -#include - -#include -#include - -static void ip32_machine_restart(char *cmd) -{ - ArcReboot(); -} - -static inline void ip32_machine_halt(void) -{ - ArcEnterInteractiveMode(); -} - -static void ip32_machine_power_off(void) -{ - ip32_machine_halt(); -} - -void __init ip32_reboot_setup(void) -{ - _machine_restart = ip32_machine_restart; - _machine_halt = ip32_machine_halt; - _machine_power_off = ip32_machine_power_off; -} diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-rtc.c linux-2.4.22/arch/mips/sgi-ip32/ip32-rtc.c --- linux-2.4.21/arch/mips/sgi-ip32/ip32-rtc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,32 +0,0 @@ -/* - * RTC routines for IP32 style attached Dallas chip. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Harald Koerfgen - */ -#include -#include - -static unsigned char ip32_rtc_read_data(unsigned long addr) -{ - return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8)); -} - -static void ip32_rtc_write_data(unsigned char data, unsigned long addr) -{ - mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data); -} - -static int ip32_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops ip32_rtc_ops = { - &ip32_rtc_read_data, - &ip32_rtc_write_data, - &ip32_rtc_bcd_mode -}; diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-setup.c linux-2.4.22/arch/mips/sgi-ip32/ip32-setup.c --- linux-2.4.21/arch/mips/sgi-ip32/ip32-setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,102 +0,0 @@ -/* - * IP32 basic setup - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Harald Koerfgen - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct rtc_ops ip32_rtc_ops; -extern u32 cc_interval; - -#ifdef CONFIG_SGI_O2MACE_ETH - -/* - * This is taken care of in here 'cause they say using Arc later on is - * problematic - */ -extern char o2meth_eaddr[8]; -static inline unsigned char str2hexnum(unsigned char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0; /* foo */ -} - -static inline void str2eaddr(unsigned char *ea, unsigned char *str) -{ - int i; - - for (i = 0; i < 6; i++) { - unsigned char num; - - if(*str == ':') - str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); - ea[i] = num; - } -} -#endif - -extern void ip32_time_init(void); - -void __init ip32_setup(void) -{ -#ifdef CONFIG_SERIAL_CONSOLE - char *ctype; -#endif - TLBMISS_HANDLER_SETUP (); - - mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);; - -#ifdef CONFIG_SERIAL_CONSOLE - ctype = ArcGetEnvironmentVariable("console"); - if (*ctype == 'd') { - if (ctype[1] == '2') - console_setup ("ttyS1"); - else - console_setup ("ttyS0"); - } -#endif -#ifdef CONFIG_SGI_O2MACE_ETH - { - char *mac=ArcGetEnvironmentVariable("eaddr"); - str2eaddr(o2meth_eaddr, mac); - } -#endif - -#ifdef CONFIG_VT - conswitchp = &dummy_con; -#endif - - rtc_ops = &ip32_rtc_ops; - board_time_init = ip32_time_init; - - crime_init (); -} - -int __init page_is_ram (unsigned long pagenr) -{ - /* XXX: to do? */ - return 1; -} diff -urN linux-2.4.21/arch/mips/sgi-ip32/ip32-timer.c linux-2.4.22/arch/mips/sgi-ip32/ip32-timer.c --- linux-2.4.21/arch/mips/sgi-ip32/ip32-timer.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sgi-ip32/ip32-timer.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,238 +0,0 @@ -/* - * IP32 timer calibration - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern volatile unsigned long wall_jiffies; -extern rwlock_t xtime_lock; - -u32 cc_interval; - -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - -/* An arbitrary time; this can be decreased if reliability looks good */ -#define WAIT_MS 10 -#define PER_MHZ (1000000 / 2 / HZ) -/* - * Change this if you have some constant time drift - */ -#define USECS_PER_JIFFY (1000000/HZ) - - -void __init ip32_timer_setup (struct irqaction *irq) -{ - u64 crime_time; - u32 cc_tick; - - printk("Calibrating system timer... "); - - crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK; - cc_tick = read_32bit_cp0_register (CP0_COUNT); - - while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time - < WAIT_MS * 1000000 / CRIME_NS_PER_TICK) - ; - cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick; - cc_interval = cc_tick / HZ * (1000 / WAIT_MS); - /* The round-off seems unnecessary; in testing, the error of the - * above procedure is < 100 ticks, which means it gets filtered - * out by the HZ adjustment. - */ - cc_interval = (cc_interval / PER_MHZ) * PER_MHZ; - - printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ)); - - setup_irq (CLOCK_IRQ, irq); -} - -struct irqaction irq0 = { NULL, SA_INTERRUPT, 0, - "timer", NULL, NULL}; - -void cc_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - u32 count; - - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - - write_32bit_cp0_register (CP0_COMPARE, - (u32) (count + cc_interval)); - kstat.irqs[0][irq]++; - do_timer (regs); - - if (!jiffies) - { - /* - * If jiffies has overflowed in this timer_interrupt we must - * update the timer[hi]/[lo] to make do_fast_gettimeoffset() - * quotient calc still valid. -arca - */ - timerhi = timerlo = 0; - } -} - -/* - * On MIPS only R4000 and better have a cycle counter. - * - * FIXME: Does playing with the RP bit in c0_status interfere with this code? - */ -static unsigned long do_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies; - u32 quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static u32 cached_quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY) - :"$1"); - cached_quotient = quotient; - } - - /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - - return res; -} - -void __init ip32_time_init(void) -{ - unsigned int epoch = 0, year, mon, day, hour, min, sec; - int i; - - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - - /* Attempt to guess the epoch. This is the same heuristic as in - * rtc.c so no stupid things will happen to timekeeping. Who knows, - * maybe Ultrix also uses 1952 as epoch ... - */ - if (year > 10 && year < 44) - epoch = 1980; - else if (year < 96) - epoch = 1952; - year += epoch; - - write_lock_irq (&xtime_lock); - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_usec = 0; - write_unlock_irq (&xtime_lock); - - write_32bit_cp0_register(CP0_COUNT, 0); - irq0.handler = cc_timer_interrupt; - - ip32_timer_setup (&irq0); - -#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) - /* Set ourselves up for future interrupts */ - write_32bit_cp0_register(CP0_COMPARE, - read_32bit_cp0_register(CP0_COUNT) - + cc_interval); - change_cp0_status(ST0_IM, ALLINTS); - sti (); -} diff -urN linux-2.4.21/arch/mips/sibyte/cfe/Makefile linux-2.4.22/arch/mips/sibyte/cfe/Makefile --- linux-2.4.21/arch/mips/sibyte/cfe/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/cfe/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -4,5 +4,6 @@ obj-y = cfe_api.o setup.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += console.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/sibyte/cfe/cfe_api.c linux-2.4.22/arch/mips/sibyte/cfe/cfe_api.c --- linux-2.4.21/arch/mips/sibyte/cfe/cfe_api.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/cfe/cfe_api.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,6 +17,7 @@ */ /* ********************************************************************* + * * Broadcom Common Firmware Environment (CFE) * * Device Function stubs File: cfe_api.c @@ -25,196 +26,218 @@ * call the standard "iocb" interface entry point to CFE). * There should be one routine here per iocb function call. * - * Author: Mitch Lichtenberg (mpl@broadcom.com) + * Authors: Mitch Lichtenberg, Chris Demetriou * ********************************************************************* */ - -#include "cfe_xiocb.h" #include "cfe_api.h" +#include "cfe_api_int.h" -static long cfe_console_handle = -1; -static int (*cfe_dispfunc)(long handle,cfe_xiocb_t *xiocb) = 0; -static cfe_xuint_t cfe_handle = 0; +/* Cast from a native pointer to a cfe_xptr_t and back. */ +#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) +#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) + +#ifdef CFE_API_IMPL_NAMESPACE +#define cfe_iocb_dispatch(a) __cfe_iocb_dispatch(a) +#endif +int cfe_iocb_dispatch(cfe_xiocb_t * xiocb); +#if defined(CFE_API_common) || defined(CFE_API_ALL) /* - * This macro makes a "signed 64-bit pointer" - basically extending a regular - * pointer to its 64-bit compatibility space equivalent. + * Declare the dispatch function with args of "intptr_t". + * This makes sure whatever model we're compiling in + * puts the pointers in a single register. For example, + * combining -mlong64 and -mips1 or -mips2 would lead to + * trouble, since the handle and IOCB pointer will be + * passed in two registers each, and CFE expects one. */ -#define BIGPTR(x) (long long) (long) (x) -typedef unsigned long intptr_t; +static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0; +static cfe_xuint_t cfe_handle = 0; -int cfe_init(cfe_xuint_t handle) +int cfe_init(cfe_xuint_t handle, cfe_xuint_t ept) { - if ((*((unsigned int *) (int) CFE_APISEAL) == CFE_EPTSEAL) || - (*((unsigned int *) (int) CFE_APISEAL_RE) == CFE_EPTSEAL) || - (*((unsigned int *) (int) CFE_APISEAL_OLD) == CFE_EPTSEAL)) { - cfe_dispfunc = (cfe_xptr_t) (int) CFE_APIENTRY; - if (handle) cfe_handle = handle; - return 0; - } else { - return -1; - } + cfe_dispfunc = NATIVE_FROM_XPTR(ept); + cfe_handle = handle; + return 0; } -int cfe_iocb_dispatch(cfe_xiocb_t *xiocb); -int cfe_iocb_dispatch(cfe_xiocb_t *xiocb) +int cfe_iocb_dispatch(cfe_xiocb_t * xiocb) { - if (!cfe_dispfunc) return -1; - return (*cfe_dispfunc)(cfe_handle,xiocb); + if (!cfe_dispfunc) + return -1; + return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb); } +#endif /* CFE_API_common || CFE_API_ALL */ -static int cfe_strlen(char *name) +#if defined(CFE_API_close) || defined(CFE_API_ALL) +int cfe_close(int handle) { - int count = 0; + cfe_xiocb_t xiocb; - while (*name) { - count++; - name++; - } + xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = 0; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; - return count; } +#endif /* CFE_API_close || CFE_API_ALL */ -int cfe_open(char *name) +#if defined(CFE_API_cpu_start) || defined(CFE_API_ALL) +int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; + xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_offset = 0; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(name); - xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); + xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); + xiocb.plist.xiocb_cpuctl.cpu_number = cpu; + xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; + xiocb.plist.xiocb_cpuctl.gp_val = gp; + xiocb.plist.xiocb_cpuctl.sp_val = sp; + xiocb.plist.xiocb_cpuctl.a1_val = a1; + xiocb.plist.xiocb_cpuctl.start_addr = (long) fn; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle; + return xiocb.xiocb_status; } +#endif /* CFE_API_cpu_start || CFE_API_ALL */ -int cfe_close(int handle) +#if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL) +int cfe_cpu_stop(int cpu) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; + xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; + xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = 0; + xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); + xiocb.plist.xiocb_cpuctl.cpu_number = cpu; + xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status); - + return xiocb.xiocb_status; } +#endif /* CFE_API_cpu_stop || CFE_API_ALL */ -int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length) +#if defined(CFE_API_enumenv) || defined(CFE_API_ALL) +int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_READ; + xiocb.xiocb_fcode = CFE_CMD_ENV_SET; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; + xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_offset = offset; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer); - xiocb.plist.xiocb_buffer.buf_length = length; + xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); + xiocb.plist.xiocb_envbuf.enum_idx = idx; + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_envbuf.name_length = namelen; + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); + xiocb.plist.xiocb_envbuf.val_length = vallen; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen; -} - -int cfe_read(int handle,unsigned char *buffer,int length) -{ - return cfe_readblk(handle,0,buffer,length); + return xiocb.xiocb_status; } +#endif /* CFE_API_enumenv || CFE_API_ALL */ - -int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length) +#if defined(CFE_API_enummem) || defined(CFE_API_ALL) +int +cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length, + cfe_xuint_t * type) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; + xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_offset = offset; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer); - xiocb.plist.xiocb_buffer.buf_length = length; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = flags; + xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); + xiocb.plist.xiocb_meminfo.mi_idx = idx; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen; -} + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; -int cfe_write(int handle,unsigned char *buffer,int length) -{ - return cfe_writeblk(handle,0,buffer,length); -} + *start = xiocb.plist.xiocb_meminfo.mi_addr; + *length = xiocb.plist.xiocb_meminfo.mi_size; + *type = xiocb.plist.xiocb_meminfo.mi_type; + return 0; +} +#endif /* CFE_API_enummem || CFE_API_ALL */ -int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen) +#if defined(CFE_API_exit) || defined(CFE_API_ALL) +int cfe_exit(int warm, int status) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; + xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_ioctlcmd = (cfe_xint_t) ioctlnum; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer); - xiocb.plist.xiocb_buffer.buf_length = length; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; + xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); + xiocb.plist.xiocb_exitstat.status = status; cfe_iocb_dispatch(&xiocb); - if (retlen) *retlen = xiocb.plist.xiocb_buffer.buf_retlen; return xiocb.xiocb_status; } +#endif /* CFE_API_exit || CFE_API_ALL */ -int cfe_inpstat(int handle) +#if defined(CFE_API_flushcache) || defined(CFE_API_ALL) +int cfe_flushcache(int flg) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; + xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); - xiocb.plist.xiocb_inpstat.inp_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = flg; + xiocb.xiocb_psize = 0; cfe_iocb_dispatch(&xiocb); - if (xiocb.xiocb_status < 0) return xiocb.xiocb_status; - - return xiocb.plist.xiocb_inpstat.inp_status; - + return xiocb.xiocb_status; } +#endif /* CFE_API_flushcache || CFE_API_ALL */ -long long cfe_getticks(void) +#if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL) +int cfe_getdevinfo(char *name) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; + xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_time_t); - xiocb.plist.xiocb_time.ticks = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = 0; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); cfe_iocb_dispatch(&xiocb); - return xiocb.plist.xiocb_time.ticks; - + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_devflags; } +#endif /* CFE_API_getdevinfo || CFE_API_ALL */ -int cfe_getenv(char *name,char *dest,int destlen) +#if defined(CFE_API_getenv) || defined(CFE_API_ALL) +int cfe_getenv(char *name, char *dest, int destlen) { cfe_xiocb_t xiocb; @@ -226,179 +249,254 @@ xiocb.xiocb_flags = 0; xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); xiocb.plist.xiocb_envbuf.enum_idx = 0; - xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name); + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); - xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(dest); + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); xiocb.plist.xiocb_envbuf.val_length = destlen; cfe_iocb_dispatch(&xiocb); return xiocb.xiocb_status; } +#endif /* CFE_API_getenv || CFE_API_ALL */ -int cfe_setenv(char *name,char *val) +#if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL) +int cfe_getfwinfo(cfe_fwinfo_t * info) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); - xiocb.plist.xiocb_envbuf.enum_idx = 0; - xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name); - xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); - xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val); - xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); + xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t); cfe_iocb_dispatch(&xiocb); - return xiocb.xiocb_status; + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + + info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version; + info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem; + info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags; + info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid; + info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va; + info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa; + info->fwi_bootarea_size = + xiocb.plist.xiocb_fwinfo.fwi_bootarea_size; +#if 0 + info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1; + info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2; + info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3; +#endif + + return 0; } +#endif /* CFE_API_getfwinfo || CFE_API_ALL */ -int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type) +#if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL) +int cfe_getstdhandle(int flg) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; + + xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); - xiocb.plist.xiocb_meminfo.mi_idx = idx; + xiocb.xiocb_flags = flg; + xiocb.xiocb_psize = 0; cfe_iocb_dispatch(&xiocb); - (*addr) = xiocb.plist.xiocb_meminfo.mi_addr; - (*size) = xiocb.plist.xiocb_meminfo.mi_size; - (*type) = xiocb.plist.xiocb_meminfo.mi_type; - - return xiocb.xiocb_status; -} - - -int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen) + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.xiocb_handle; +} +#endif /* CFE_API_getstdhandle || CFE_API_ALL */ + +#if defined(CFE_API_getticks) || defined(CFE_API_ALL) +int64_t +#ifdef CFE_API_IMPL_NAMESPACE +__cfe_getticks(void) +#else +cfe_getticks(void) +#endif { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); - xiocb.plist.xiocb_envbuf.enum_idx = idx; - xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name); - xiocb.plist.xiocb_envbuf.name_length = namelen; - xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val); - xiocb.plist.xiocb_envbuf.val_length = vallen; + xiocb.xiocb_psize = sizeof(xiocb_time_t); + xiocb.plist.xiocb_time.ticks = 0; cfe_iocb_dispatch(&xiocb); - return xiocb.xiocb_status; + return xiocb.plist.xiocb_time.ticks; + } +#endif /* CFE_API_getticks || CFE_API_ALL */ -int cfe_exit(int warm, int status) +#if defined(CFE_API_inpstat) || defined(CFE_API_ALL) +int cfe_inpstat(int handle) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; + xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; - xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); - xiocb.plist.xiocb_exitstat.status = (cfe_xint_t) status; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); + xiocb.plist.xiocb_inpstat.inp_status = 0; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status); + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_inpstat.inp_status; } +#endif /* CFE_API_inpstat || CFE_API_ALL */ -int cfe_flushcache(int flg) +#if defined(CFE_API_ioctl) || defined(CFE_API_ALL) +int +cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, + int length, int *retlen, cfe_xuint_t offset) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; + xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = flg; - xiocb.xiocb_psize = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; cfe_iocb_dispatch(&xiocb); + if (retlen) + *retlen = xiocb.plist.xiocb_buffer.buf_retlen; return xiocb.xiocb_status; } +#endif /* CFE_API_ioctl || CFE_API_ALL */ -int cfe_getstdhandle(int flg) +#if defined(CFE_API_open) || defined(CFE_API_ALL) +int cfe_open(char *name) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; + xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = flg; - xiocb.xiocb_psize = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = 0; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle; + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.xiocb_handle; +} +#endif /* CFE_API_open || CFE_API_ALL */ +#if defined(CFE_API_read) || defined(CFE_API_ALL) +int cfe_read(int handle, unsigned char *buffer, int length) +{ + return cfe_readblk(handle, 0, buffer, length); } +#endif /* CFE_API_read || CFE_API_ALL */ -int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1) +#if defined(CFE_API_readblk) || defined(CFE_API_ALL) +int +cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer, + int length) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; + xiocb.xiocb_fcode = CFE_CMD_DEV_READ; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); - xiocb.plist.xiocb_cpuctl.cpu_number = cpu; - xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; - xiocb.plist.xiocb_cpuctl.gp_val = gp; - xiocb.plist.xiocb_cpuctl.sp_val = sp; - xiocb.plist.xiocb_cpuctl.a1_val = a1; - xiocb.plist.xiocb_cpuctl.start_addr = (long)fn; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; cfe_iocb_dispatch(&xiocb); - return xiocb.xiocb_status; + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_retlen; } +#endif /* CFE_API_readblk || CFE_API_ALL */ - -int cfe_stop_cpu(int cpu) +#if defined(CFE_API_setenv) || defined(CFE_API_ALL) +int cfe_setenv(char *name, char *val) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; + xiocb.xiocb_fcode = CFE_CMD_ENV_SET; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); - xiocb.plist.xiocb_cpuctl.cpu_number = cpu; - xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); + xiocb.plist.xiocb_envbuf.enum_idx = 0; + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); + xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); cfe_iocb_dispatch(&xiocb); return xiocb.xiocb_status; } +#endif /* CFE_API_setenv || CFE_API_ALL */ -void cfe_open_console() +#if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \ + && !defined(CFE_API_STRLEN_CUSTOM) +int cfe_strlen(char *name) { - cfe_console_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); + int count = 0; + + while (*name++) + count++; + + return count; } +#endif /* CFE_API_strlen || CFE_API_ALL */ -void cfe_console_print(const char *str, int len) +#if defined(CFE_API_write) || defined(CFE_API_ALL) +int cfe_write(int handle, unsigned char *buffer, int length) { - int res; - - if (cfe_console_handle != -1) { - do { - res = cfe_writeblk(cfe_console_handle, 0, str, len); - if (res < 0) - break; - str += res; - len -= res; - } while (len); - } + return cfe_writeblk(handle, 0, buffer, length); } +#endif /* CFE_API_write || CFE_API_ALL */ +#if defined(CFE_API_writeblk) || defined(CFE_API_ALL) +int +cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer, + int length) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_retlen; +} +#endif /* CFE_API_writeblk || CFE_API_ALL */ diff -urN linux-2.4.21/arch/mips/sibyte/cfe/cfe_api.h linux-2.4.22/arch/mips/sibyte/cfe/cfe_api.h --- linux-2.4.21/arch/mips/sibyte/cfe/cfe_api.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/cfe/cfe_api.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,55 +17,169 @@ */ /* ********************************************************************* + * * Broadcom Common Firmware Environment (CFE) * * Device function prototypes File: cfe_api.h * - * This module contains prototypes for cfe_devfuncs.c, a set - * of wrapper routines to the IOCB interface. This file, - * along with cfe_api.c, can be incorporated into programs - * that need to call CFE. + * This file contains declarations for doing callbacks to + * cfe from an application. It should be the only header + * needed by the application to use this library * - * Author: Mitch Lichtenberg (mpl@broadcom.com) + * Authors: Mitch Lichtenberg, Chris Demetriou * ********************************************************************* */ -#include +#ifndef CFE_API_H +#define CFE_API_H + +/* + * Apply customizations here for different OSes. These need to: + * * typedef uint64_t, int64_t, intptr_t, uintptr_t. + * * define cfe_strlen() if use of an existing function is desired. + * * define CFE_API_IMPL_NAMESPACE if API functions are to use + * names in the implementation namespace. + * Also, optionally, if the build environment does not do so automatically, + * CFE_API_* can be defined here as desired. + */ +/* Begin customization. */ +#include +#include + +typedef long intptr_t; + +#define cfe_strlen strlen + +#define CFE_API_ALL +#define CFE_API_STRLEN_CUSTOM +/* End customization. */ + + +/* ********************************************************************* + * Constants + ********************************************************************* */ +/* Seal indicating CFE's presence, passed to user program. */ #define CFE_EPTSEAL 0x43464531 -#ifdef CONFIG_MIPS_UNCACHED -#define CFE_APIENTRY 0xBFC00500 -#define CFE_APISEAL 0xBFC004E0 -#define CFE_APISEAL_RE 0xBFC004E8 -#define CFE_APISEAL_OLD 0xBFC00508 + +#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */ +#define CFE_MI_AVAILABLE 1 /* memory is available */ + +#define CFE_FLG_WARMSTART 0x00000001 +#define CFE_FLG_FULL_ARENA 0x00000001 +#define CFE_FLG_ENV_PERMANENT 0x00000001 + +#define CFE_CPU_CMD_START 1 +#define CFE_CPU_CMD_STOP 0 + +#define CFE_STDHANDLE_CONSOLE 0 + +#define CFE_DEV_NETWORK 1 +#define CFE_DEV_DISK 2 +#define CFE_DEV_FLASH 3 +#define CFE_DEV_SERIAL 4 +#define CFE_DEV_CPU 5 +#define CFE_DEV_NVRAM 6 +#define CFE_DEV_CLOCK 7 +#define CFE_DEV_OTHER 8 +#define CFE_DEV_MASK 0x0F + +#define CFE_CACHE_FLUSH_D 1 +#define CFE_CACHE_INVAL_I 2 +#define CFE_CACHE_INVAL_D 4 +#define CFE_CACHE_INVAL_L2 8 + +#define CFE_FWI_64BIT 0x00000001 +#define CFE_FWI_32BIT 0x00000002 +#define CFE_FWI_RELOC 0x00000004 +#define CFE_FWI_UNCACHED 0x00000008 +#define CFE_FWI_MULTICPU 0x00000010 +#define CFE_FWI_FUNCSIM 0x00000020 +#define CFE_FWI_RTLSIM 0x00000040 + +typedef struct { + int64_t fwi_version; /* major, minor, eco version */ + int64_t fwi_totalmem; /* total installed mem */ + int64_t fwi_flags; /* various flags */ + int64_t fwi_boardid; /* board ID */ + int64_t fwi_bootarea_va; /* VA of boot area */ + int64_t fwi_bootarea_pa; /* PA of boot area */ + int64_t fwi_bootarea_size; /* size of boot area */ +} cfe_fwinfo_t; + + +/* + * cfe_strlen is handled specially: If already defined, it has been + * overridden in this environment with a standard strlen-like function. + */ +#ifdef cfe_strlen +# define CFE_API_STRLEN_CUSTOM #else -#define CFE_APIENTRY 0x9FC00500 -#define CFE_APISEAL 0x9FC004E0 -#define CFE_APISEAL_RE 0x9FC004E8 -#define CFE_APISEAL_OLD 0x9FC00508 +# ifdef CFE_API_IMPL_NAMESPACE +# define cfe_strlen(a) __cfe_strlen(a) +# endif +int cfe_strlen(char *name); #endif -#ifndef __ASSEMBLER__ -int cfe_init(cfe_xuint_t handle); -int cfe_open(char *name); +/* + * Defines and prototypes for functions which take no arguments. + */ +#ifdef CFE_API_IMPL_NAMESPACE +int64_t __cfe_getticks(void); +#define cfe_getticks() __cfe_getticks() +#else +int64_t cfe_getticks(void); +#endif + +/* + * Defines and prototypes for the rest of the functions. + */ +#ifdef CFE_API_IMPL_NAMESPACE +#define cfe_close(a) __cfe_close(a) +#define cfe_cpu_start(a,b,c,d,e) __cfe_cpu_start(a,b,c,d,e) +#define cfe_cpu_stop(a) __cfe_cpu_stop(a) +#define cfe_enumenv(a,b,d,e,f) __cfe_enumenv(a,b,d,e,f) +#define cfe_enummem(a,b,c,d,e) __cfe_enummem(a,b,c,d,e) +#define cfe_exit(a,b) __cfe_exit(a,b) +#define cfe_flushcache(a) __cfe_cacheflush(a) +#define cfe_getdevinfo(a) __cfe_getdevinfo(a) +#define cfe_getenv(a,b,c) __cfe_getenv(a,b,c) +#define cfe_getfwinfo(a) __cfe_getfwinfo(a) +#define cfe_getstdhandle(a) __cfe_getstdhandle(a) +#define cfe_init(a,b) __cfe_init(a,b) +#define cfe_inpstat(a) __cfe_inpstat(a) +#define cfe_ioctl(a,b,c,d,e,f) __cfe_ioctl(a,b,c,d,e,f) +#define cfe_open(a) __cfe_open(a) +#define cfe_read(a,b,c) __cfe_read(a,b,c) +#define cfe_readblk(a,b,c,d) __cfe_readblk(a,b,c,d) +#define cfe_setenv(a,b) __cfe_setenv(a,b) +#define cfe_write(a,b,c) __cfe_write(a,b,c) +#define cfe_writeblk(a,b,c,d) __cfe_writeblk(a,b,c,d) +#endif /* CFE_API_IMPL_NAMESPACE */ + int cfe_close(int handle); -int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length); -int cfe_read(int handle,unsigned char *buffer,int length); -int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length); -int cfe_write(int handle,unsigned char *buffer,int length); -int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen); -int cfe_inpstat(int handle); -int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen); -int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type); -int cfe_setenv(char *name,char *val); -int cfe_getenv(char *name,char *dest,int destlen); -long long cfe_getticks(void); +int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1); +int cfe_cpu_stop(int cpu); +int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen); +int cfe_enummem(int idx, int flags, uint64_t * start, uint64_t * length, + uint64_t * type); int cfe_exit(int warm, int status); int cfe_flushcache(int flg); +int cfe_getdevinfo(char *name); +int cfe_getenv(char *name, char *dest, int destlen); +int cfe_getfwinfo(cfe_fwinfo_t * info); int cfe_getstdhandle(int flg); -int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1); -int cfe_stop_cpu(int cpu); +int cfe_init(uint64_t handle, uint64_t ept); +int cfe_inpstat(int handle); +int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, + int length, int *retlen, uint64_t offset); +int cfe_open(char *name); +int cfe_read(int handle, unsigned char *buffer, int length); +int cfe_readblk(int handle, int64_t offset, unsigned char *buffer, + int length); +int cfe_setenv(char *name, char *val); +int cfe_write(int handle, unsigned char *buffer, int length); +int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer, + int length); -void cfe_open_console(void); -void cfe_console_print(const char *, int); -#endif +#endif /* CFE_API_H */ diff -urN linux-2.4.21/arch/mips/sibyte/cfe/cfe_api_int.h linux-2.4.22/arch/mips/sibyte/cfe/cfe_api_int.h --- linux-2.4.21/arch/mips/sibyte/cfe/cfe_api_int.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/cfe/cfe_api_int.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* ********************************************************************* + * + * Broadcom Common Firmware Environment (CFE) + * + * Device function prototypes File: cfe_api_int.h + * + * This header defines all internal types and macros for the + * library. This is stuff that's not exported to an app + * using the library. + * + * Authors: Mitch Lichtenberg, Chris Demetriou + * + ********************************************************************* */ + +#ifndef CFE_API_INT_H +#define CFE_API_INT_H + +/* ********************************************************************* + * Constants + ********************************************************************* */ + +#define CFE_CMD_FW_GETINFO 0 +#define CFE_CMD_FW_RESTART 1 +#define CFE_CMD_FW_BOOT 2 +#define CFE_CMD_FW_CPUCTL 3 +#define CFE_CMD_FW_GETTIME 4 +#define CFE_CMD_FW_MEMENUM 5 +#define CFE_CMD_FW_FLUSHCACHE 6 + +#define CFE_CMD_DEV_GETHANDLE 9 +#define CFE_CMD_DEV_ENUM 10 +#define CFE_CMD_DEV_OPEN 11 +#define CFE_CMD_DEV_INPSTAT 12 +#define CFE_CMD_DEV_READ 13 +#define CFE_CMD_DEV_WRITE 14 +#define CFE_CMD_DEV_IOCTL 15 +#define CFE_CMD_DEV_CLOSE 16 +#define CFE_CMD_DEV_GETINFO 17 + +#define CFE_CMD_ENV_ENUM 20 +#define CFE_CMD_ENV_GET 22 +#define CFE_CMD_ENV_SET 23 +#define CFE_CMD_ENV_DEL 24 + +#define CFE_CMD_MAX 32 + +#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */ + +/* ********************************************************************* + * Structures + ********************************************************************* */ + +typedef uint64_t cfe_xuint_t; +typedef int64_t cfe_xint_t; +typedef int64_t cfe_xptr_t; + +typedef struct xiocb_buffer_s { + cfe_xuint_t buf_offset; /* offset on device (bytes) */ + cfe_xptr_t buf_ptr; /* pointer to a buffer */ + cfe_xuint_t buf_length; /* length of this buffer */ + cfe_xuint_t buf_retlen; /* returned length (for read ops) */ + cfe_xuint_t buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */ +} xiocb_buffer_t; + +#define buf_devflags buf_ioctlcmd /* returned device info flags */ + +typedef struct xiocb_inpstat_s { + cfe_xuint_t inp_status; /* 1 means input available */ +} xiocb_inpstat_t; + +typedef struct xiocb_envbuf_s { + cfe_xint_t enum_idx; /* 0-based enumeration index */ + cfe_xptr_t name_ptr; /* name string buffer */ + cfe_xint_t name_length; /* size of name buffer */ + cfe_xptr_t val_ptr; /* value string buffer */ + cfe_xint_t val_length; /* size of value string buffer */ +} xiocb_envbuf_t; + +typedef struct xiocb_cpuctl_s { + cfe_xuint_t cpu_number; /* cpu number to control */ + cfe_xuint_t cpu_command; /* command to issue to CPU */ + cfe_xuint_t start_addr; /* CPU start address */ + cfe_xuint_t gp_val; /* starting GP value */ + cfe_xuint_t sp_val; /* starting SP value */ + cfe_xuint_t a1_val; /* starting A1 value */ +} xiocb_cpuctl_t; + +typedef struct xiocb_time_s { + cfe_xint_t ticks; /* current time in ticks */ +} xiocb_time_t; + +typedef struct xiocb_exitstat_s { + cfe_xint_t status; +} xiocb_exitstat_t; + +typedef struct xiocb_meminfo_s { + cfe_xint_t mi_idx; /* 0-based enumeration index */ + cfe_xint_t mi_type; /* type of memory block */ + cfe_xuint_t mi_addr; /* physical start address */ + cfe_xuint_t mi_size; /* block size */ +} xiocb_meminfo_t; + +typedef struct xiocb_fwinfo_s { + cfe_xint_t fwi_version; /* major, minor, eco version */ + cfe_xint_t fwi_totalmem; /* total installed mem */ + cfe_xint_t fwi_flags; /* various flags */ + cfe_xint_t fwi_boardid; /* board ID */ + cfe_xint_t fwi_bootarea_va; /* VA of boot area */ + cfe_xint_t fwi_bootarea_pa; /* PA of boot area */ + cfe_xint_t fwi_bootarea_size; /* size of boot area */ + cfe_xint_t fwi_reserved1; + cfe_xint_t fwi_reserved2; + cfe_xint_t fwi_reserved3; +} xiocb_fwinfo_t; + +typedef struct cfe_xiocb_s { + cfe_xuint_t xiocb_fcode; /* IOCB function code */ + cfe_xint_t xiocb_status; /* return status */ + cfe_xint_t xiocb_handle; /* file/device handle */ + cfe_xuint_t xiocb_flags; /* flags for this IOCB */ + cfe_xuint_t xiocb_psize; /* size of parameter list */ + union { + xiocb_buffer_t xiocb_buffer; /* buffer parameters */ + xiocb_inpstat_t xiocb_inpstat; /* input status parameters */ + xiocb_envbuf_t xiocb_envbuf; /* environment function parameters */ + xiocb_cpuctl_t xiocb_cpuctl; /* CPU control parameters */ + xiocb_time_t xiocb_time; /* timer parameters */ + xiocb_meminfo_t xiocb_meminfo; /* memory arena info parameters */ + xiocb_fwinfo_t xiocb_fwinfo; /* firmware information */ + xiocb_exitstat_t xiocb_exitstat; /* Exit Status */ + } plist; +} cfe_xiocb_t; + +#endif /* CFE_API_INT_H */ diff -urN linux-2.4.21/arch/mips/sibyte/cfe/cfe_error.h linux-2.4.22/arch/mips/sibyte/cfe/cfe_error.h --- linux-2.4.21/arch/mips/sibyte/cfe/cfe_error.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/cfe/cfe_error.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,19 +17,18 @@ */ /* ********************************************************************* + * * Broadcom Common Firmware Environment (CFE) - * + * * Error codes File: cfe_error.h - * + * * CFE's global error code list is here. - * - * Author: Mitch Lichtenberg (mpl@broadcom.com) - * + * + * Author: Mitch Lichtenberg + * ********************************************************************* */ - - #define CFE_OK 0 #define CFE_ERR -1 /* generic error */ #define CFE_ERR_INV_COMMAND -2 @@ -74,3 +73,13 @@ #define CFE_ERR_WRONGDEVTYPE -32 #define CFE_ERR_BBCHECKSUM -33 #define CFE_ERR_BOOTPROGCHKSUM -34 + +#define CFE_ERR_LDRNOTAVAIL -35 + +#define CFE_ERR_NOTREADY -36 + +#define CFE_ERR_GETMEM -37 +#define CFE_ERR_SETMEM -38 + +#define CFE_ERR_NOTCONN -39 +#define CFE_ERR_ADDRINUSE -40 diff -urN linux-2.4.21/arch/mips/sibyte/cfe/cfe_xiocb.h linux-2.4.22/arch/mips/sibyte/cfe/cfe_xiocb.h --- linux-2.4.21/arch/mips/sibyte/cfe/cfe_xiocb.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/cfe/cfe_xiocb.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* ********************************************************************* - * Broadcom Common Firmware Environment (CFE) - * - * IOCB definitions File: cfe_iocb.h - * - * This module describes CFE's IOCB structure, the main - * data structure used to communicate API requests with CFE. - * - * Author: Mitch Lichtenberg (mpl@broadcom.com) - * - ********************************************************************* */ - -/* ********************************************************************* - * Constants - ********************************************************************* */ - -#define CFE_CMD_FW_GETINFO 0 -#define CFE_CMD_FW_RESTART 1 -#define CFE_CMD_FW_BOOT 2 -#define CFE_CMD_FW_CPUCTL 3 -#define CFE_CMD_FW_GETTIME 4 -#define CFE_CMD_FW_MEMENUM 5 -#define CFE_CMD_FW_FLUSHCACHE 6 - -#define CFE_CMD_DEV_GETHANDLE 9 -#define CFE_CMD_DEV_ENUM 10 -#define CFE_CMD_DEV_OPEN 11 -#define CFE_CMD_DEV_INPSTAT 12 -#define CFE_CMD_DEV_READ 13 -#define CFE_CMD_DEV_WRITE 14 -#define CFE_CMD_DEV_IOCTL 15 -#define CFE_CMD_DEV_CLOSE 16 -#define CFE_CMD_DEV_GETINFO 17 - -#define CFE_CMD_ENV_ENUM 20 -#define CFE_CMD_ENV_GET 22 -#define CFE_CMD_ENV_SET 23 -#define CFE_CMD_ENV_DEL 24 - -#define CFE_CMD_MAX 32 - -#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */ -#define CFE_MI_AVAILABLE 1 /* memory is available */ - -#define CFE_FLG_WARMSTART 0x00000001 - -#define CFE_FLG_ENV_PERMANENT 0x00000001 - -#define CFE_CPU_CMD_START 1 -#define CFE_CPU_CMD_STOP 0 - -#define CFE_STDHANDLE_CONSOLE 0 - -#define CFE_DEV_NETWORK 1 -#define CFE_DEV_DISK 2 -#define CFE_DEV_FLASH 3 -#define CFE_DEV_SERIAL 4 -#define CFE_DEV_CPU 5 -#define CFE_DEV_NVRAM 6 -#define CFE_DEV_OTHER 7 -#define CFE_DEV_MASK 0x0F - -#define CFE_CACHE_FLUSH_D 1 -#define CFE_CACHE_INVAL_I 2 -#define CFE_CACHE_INVAL_D 4 -#define CFE_CACHE_INVAL_L2 8 - -/* ********************************************************************* - * Structures - ********************************************************************* */ - -typedef unsigned long long cfe_xuint_t; -typedef long long cfe_xint_t; -typedef long long cfe_xptr_t; - -typedef struct xiocb_buffer_s { - cfe_xuint_t buf_offset; /* offset on device (bytes) */ - cfe_xptr_t buf_ptr; /* pointer to a buffer */ - cfe_xuint_t buf_length; /* length of this buffer */ - cfe_xuint_t buf_retlen; /* returned length (for read ops) */ - cfe_xuint_t buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */ -} xiocb_buffer_t; - -#define buf_devflags buf_ioctlcmd /* returned device info flags */ - -typedef struct xiocb_inpstat_s { - cfe_xuint_t inp_status; /* 1 means input available */ -} xiocb_inpstat_t; - -typedef struct xiocb_envbuf_s { - cfe_xint_t enum_idx; /* 0-based enumeration index */ - cfe_xptr_t name_ptr; /* name string buffer */ - cfe_xint_t name_length; /* size of name buffer */ - cfe_xptr_t val_ptr; /* value string buffer */ - cfe_xint_t val_length; /* size of value string buffer */ -} xiocb_envbuf_t; - -typedef struct xiocb_cpuctl_s { - cfe_xuint_t cpu_number; /* cpu number to control */ - cfe_xuint_t cpu_command; /* command to issue to CPU */ - cfe_xuint_t start_addr; /* CPU start address */ - cfe_xuint_t gp_val; /* starting GP value */ - cfe_xuint_t sp_val; /* starting SP value */ - cfe_xuint_t a1_val; /* starting A1 value */ -} xiocb_cpuctl_t; - -typedef struct xiocb_time_s { - cfe_xint_t ticks; /* current time in ticks */ -} xiocb_time_t; - -typedef struct xiocb_exitstat_s { - cfe_xint_t status; -} xiocb_exitstat_t; - -typedef struct xiocb_meminfo_s { - cfe_xint_t mi_idx; /* 0-based enumeration index */ - cfe_xint_t mi_type; /* type of memory block */ - cfe_xuint_t mi_addr; /* physical start address */ - cfe_xuint_t mi_size; /* block size */ -} xiocb_meminfo_t; - -#define CFE_FWI_64BIT 0x00000001 -#define CFE_FWI_32BIT 0x00000002 -#define CFE_FWI_RELOC 0x00000004 -#define CFE_FWI_UNCACHED 0x00000008 -#define CFE_FWI_MULTICPU 0x00000010 -#define CFE_FWI_FUNCSIM 0x00000020 -#define CFE_FWI_RTLSIM 0x00000040 - -typedef struct xiocb_fwinfo_s { - cfe_xint_t fwi_version; /* major, minor, eco version */ - cfe_xint_t fwi_totalmem; /* total installed mem */ - cfe_xint_t fwi_flags; /* various flags */ - cfe_xint_t fwi_boardid; /* board ID */ - cfe_xint_t fwi_bootarea_va; /* VA of boot area */ - cfe_xint_t fwi_bootarea_pa; /* PA of boot area */ - cfe_xint_t fwi_bootarea_size; /* size of boot area */ - cfe_xint_t fwi_reserved1; - cfe_xint_t fwi_reserved2; - cfe_xint_t fwi_reserved3; -} xiocb_fwinfo_t,cfe_fwinfo_t; - -typedef struct cfe_xiocb_s { - cfe_xuint_t xiocb_fcode; /* IOCB function code */ - cfe_xint_t xiocb_status; /* return status */ - cfe_xint_t xiocb_handle; /* file/device handle */ - cfe_xuint_t xiocb_flags; /* flags for this IOCB */ - cfe_xuint_t xiocb_psize; /* size of parameter list */ - union { - xiocb_buffer_t xiocb_buffer; /* buffer parameters */ - xiocb_inpstat_t xiocb_inpstat; /* input status parameters */ - xiocb_envbuf_t xiocb_envbuf; /* environment function parameters */ - xiocb_cpuctl_t xiocb_cpuctl; /* CPU control parameters */ - xiocb_time_t xiocb_time; /* timer parameters */ - xiocb_meminfo_t xiocb_meminfo; /* memory arena info parameters */ - xiocb_fwinfo_t xiocb_fwinfo; /* firmware information */ - xiocb_exitstat_t xiocb_exitstat; /* Exit status */ - } plist; -} cfe_xiocb_t; diff -urN linux-2.4.21/arch/mips/sibyte/cfe/console.c linux-2.4.22/arch/mips/sibyte/cfe/console.c --- linux-2.4.21/arch/mips/sibyte/cfe/console.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/cfe/console.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#include + +#include "cfe_api.h" +#include "cfe_error.h" + +extern int cfe_cons_handle; +static kdev_t cfe_consdev; + +static void cfe_console_write(struct console *cons, const char *str, + unsigned int count) +{ + int i, last, written; + + for (i=0,last=0; i@" * e.g. initrd=3abfd@80010000. This is set up by the loader. @@ -205,21 +217,21 @@ if (!*tmp) { goto fail; } - initrd_size = simple_strtol(str, &endptr, 16); + initrd_size = simple_strtoul(str, &endptr, 16); if (*endptr) { *(tmp-1) = '@'; goto fail; } *(tmp-1) = '@'; - initrd_start = simple_strtol(tmp, &endptr, 16); + initrd_start = simple_strtoul(tmp, &endptr, 16); if (*endptr) { goto fail; } initrd_end = initrd_start + initrd_size; - printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start); + prom_printf("Found initrd of %lx@%lx\n", initrd_size, initrd_start); return 1; fail: - printk("Bad initrd argument. Disabling initrd\n"); + prom_printf("Bad initrd argument. Disabling initrd\n"); initrd_start = 0; initrd_end = 0; return 1; @@ -232,21 +244,56 @@ */ __init int prom_init(int argc, char **argv, char **envp, int *prom_vec) { + uint64_t cfe_ept, cfe_handle; + unsigned int cfe_eptseal; +#ifdef CONFIG_KGDB + char *arg; +#endif + _machine_restart = (void (*)(char *))cfe_linux_exit; _machine_halt = cfe_linux_exit; _machine_power_off = cfe_linux_exit; /* - * This should go away. Detect if we're booting - * straight from cfe without a loader. If we - * are, then we've got a prom vector in a0. Otherwise, - * argc (and argv and envp, for that matter) will be 0) + * Check if a loader was used; if NOT, the 4 arguments are + * what CFE gives us (handle, 0, EPT and EPTSEAL) */ if (argc < 0) { - prom_vec = (int *)argc; + cfe_handle = (uint64_t)(long)argc; + cfe_ept = (long)envp; + cfe_eptseal = (uint32_t)(unsigned long)prom_vec; + } else { + if ((int32_t)(long)prom_vec < 0) { + /* + * Old loader; all it gives us is the handle, + * so use the "known" entrypoint and assume + * the seal. + */ + cfe_handle = (uint64_t)(long)prom_vec; + cfe_ept = (uint64_t)((int32_t)0x9fc00500); + cfe_eptseal = CFE_EPTSEAL; + } else { + /* + * Newer loaders bundle the handle/ept/eptseal + * Note: prom_vec is in the loader's useg + * which is still alive in the TLB. + */ + cfe_handle = (uint64_t)((int32_t *)prom_vec)[0]; + cfe_ept = (uint64_t)((int32_t *)prom_vec)[2]; + cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3]; + } } - cfe_init((long)prom_vec); - cfe_open_console(); + if (cfe_eptseal != CFE_EPTSEAL) { + /* too early for panic to do any good */ + prom_printf("CFE's entrypoint seal doesn't match. Spinning."); + while (1) ; + } + cfe_init(cfe_handle, cfe_ept); + /* + * Get the handle for (at least) prom_putchar, possibly for + * boot console + */ + cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) { if (argc < 0) { /* @@ -254,15 +301,28 @@ * command line */ strcpy(arcs_cmdline, "root=/dev/ram0 "); -#ifdef CONFIG_SIBYTE_PTSWARM - strcat(arcs_cmdline, "console=ttyS0,115200 "); -#endif } else { /* The loader should have set the command line */ - panic("LINUX_CMDLINE not defined in cfe."); + /* too early for panic to do any good */ + prom_printf("LINUX_CMDLINE not defined in cfe."); + while (1) ; } } +#ifdef CONFIG_KGDB + if ((arg = strstr(arcs_cmdline,"kgdb=duart")) != NULL) + kgdb_port = (arg[10] == '0') ? 0 : 1; + else + kgdb_port = 1; +#endif + +#ifdef SIBYTE_DEFAULT_CONSOLE + /* Force default console from board header (allowing override) */ + if (!strstr(arcs_cmdline,"console=")) { + strcat(arcs_cmdline, "console=" SIBYTE_DEFAULT_CONSOLE); + } +#endif + #ifdef CONFIG_BLK_DEV_INITRD { char *ptr; @@ -311,77 +371,10 @@ return 0; } -#ifdef CONFIG_SIBYTE_CFE_CONSOLE - -static void cfe_console_write(struct console *cons, const char *str, - unsigned int count) -{ - int i, last; - - for (i=0,last=0; i -#include - -/* SB1 definitions */ - -/* XXX should come from config1 XXX */ -#define SB1_CACHE_INDEX_MASK 0x1fe0 - -#define CP0_ERRCTL_RECOVERABLE (1 << 31) -#define CP0_ERRCTL_DCACHE (1 << 30) -#define CP0_ERRCTL_ICACHE (1 << 29) -#define CP0_ERRCTL_MULTIBUS (1 << 23) -#define CP0_ERRCTL_MC_TLB (1 << 15) -#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) - -#define CP0_CERRI_TAG_PARITY (1 << 29) -#define CP0_CERRI_DATA_PARITY (1 << 28) -#define CP0_CERRI_EXTERNAL (1 << 26) - -#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) -#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) - -#define CP0_CERRD_MULTIPLE (1 << 31) -#define CP0_CERRD_TAG_STATE (1 << 30) -#define CP0_CERRD_TAG_ADDRESS (1 << 29) -#define CP0_CERRD_DATA_SBE (1 << 28) -#define CP0_CERRD_DATA_DBE (1 << 27) -#define CP0_CERRD_EXTERNAL (1 << 26) -#define CP0_CERRD_LOAD (1 << 25) -#define CP0_CERRD_STORE (1 << 24) -#define CP0_CERRD_FILLWB (1 << 23) -#define CP0_CERRD_COHERENCY (1 << 22) -#define CP0_CERRD_DUPTAG (1 << 21) - -#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) -#define CP0_CERRD_IDX_VALID(c) \ - (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) -#define CP0_CERRD_CAUSES \ - (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) -#define CP0_CERRD_TYPES \ - (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) -#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) - -static uint32_t extract_ic(unsigned short addr, int data); -static uint32_t extract_dc(unsigned short addr, int data); - -spinlock_t in_cacheerr = SPIN_LOCK_UNLOCKED; - -static inline void breakout_errctl(unsigned int val) -{ - if (val & CP0_ERRCTL_RECOVERABLE) - printk(" recoverable"); - if (val & CP0_ERRCTL_DCACHE) - printk(" dcache"); - if (val & CP0_ERRCTL_ICACHE) - printk(" icache"); - if (val & CP0_ERRCTL_MULTIBUS) - printk(" multiple-buserr"); - printk("\n"); -} - -static inline void breakout_cerri(unsigned int val) -{ - if (val & CP0_CERRI_TAG_PARITY) - printk(" tag-parity"); - if (val & CP0_CERRI_DATA_PARITY) - printk(" data-parity"); - if (val & CP0_CERRI_EXTERNAL) - printk(" external"); - printk("\n"); -} - -static inline void breakout_cerrd(unsigned int val) -{ - switch (val & CP0_CERRD_CAUSES) { - case CP0_CERRD_LOAD: - printk(" load,"); - break; - case CP0_CERRD_STORE: - printk(" store,"); - break; - case CP0_CERRD_FILLWB: - printk(" fill/wb,"); - break; - case CP0_CERRD_COHERENCY: - printk(" coherency,"); - break; - case CP0_CERRD_DUPTAG: - printk(" duptags,"); - break; - default: - printk(" NO CAUSE,"); - break; - } - if (!(val & CP0_CERRD_TYPES)) - printk(" NO TYPE"); - else { - if (val & CP0_CERRD_MULTIPLE) - printk(" multi-err"); - if (val & CP0_CERRD_TAG_STATE) - printk(" tag-state"); - if (val & CP0_CERRD_TAG_ADDRESS) - printk(" tag-address"); - if (val & CP0_CERRD_DATA_SBE) - printk(" data-SBE"); - if (val & CP0_CERRD_DATA_DBE) - printk(" data-DBE"); - if (val & CP0_CERRD_EXTERNAL) - printk(" external"); - } - printk("\n"); -} - -asmlinkage void sb1_cache_error(void) -{ - uint64_t cerr_dpa; - uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; - - /* Prevent re-entrance in the SMP case */ - spin_lock(&in_cacheerr); - printk("Cache error exception on CPU %x:\n", - (read_32bit_cp0_register(CP0_PRID) >> 25) & 0x7); - __asm__ __volatile__ ( - ".set push\n\t" - ".set mips64\n\t" - ".set noat\n\t" - "mfc0 %0, $26, 0\n\t" - "mfc0 %1, $27, 0\n\t" - "mfc0 %2, $27, 1\n\t" - "dmfc0 $1, $27, 3\n\t" - "dsrl32 %3, $1, 0 \n\t" - "sll %4, $1, 0 \n\t" - "mfc0 %5, $30\n\t" - ".set pop\n" - : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), - "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); - cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; - printk(" cp0_errorepc == %08x\n", eepc); - printk(" cp0_errctl == %08x", errctl); - breakout_errctl(errctl); - if (errctl & CP0_ERRCTL_ICACHE) { - printk(" cp0_cerr_i == %08x", cerr_i); - breakout_cerri(cerr_i); - if (CP0_CERRI_IDX_VALID(cerr_i)) { - if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) - printk(" cerr_i idx doesn't match eepc\n"); - else { - res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, - (cerr_i & CP0_CERRI_DATA) != 0); - if (!(res & cerr_i)) - printk("...didn't see indicated icache problem\n"); - } - } - } - if (errctl & CP0_ERRCTL_DCACHE) { - printk(" cp0_cerr_d == %08x", cerr_d); - breakout_cerrd(cerr_d); - if (CP0_CERRD_DPA_VALID(cerr_d)) { - printk(" cp0_cerr_dpa == %010llx\n", cerr_dpa); - if (!CP0_CERRD_IDX_VALID(cerr_d)) { - res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, - (cerr_d & CP0_CERRD_DATA) != 0); - if (!(res & cerr_d)) - printk("...didn't see indicated dcache problem\n"); - } else { - if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) - printk(" cerr_d idx doesn't match cerr_dpa\n"); - else { - res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, - (cerr_d & CP0_CERRD_DATA) != 0); - if (!(res & cerr_d)) - printk("...didn't see indicated problem\n"); - } - } - } - } - - while (1); - /* - * This tends to make things get really ugly; let's just stall instead. - * panic("Can't handle the cache error!"); - */ -} - - -/* Parity lookup table. */ -static const uint8_t parity[256] = { - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 -}; - -/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ -static const uint64_t mask_72_64[8] = { - 0x0738C808099264FFL, - 0x38C808099264FF07L, - 0xC808099264FF0738L, - 0x08099264FF0738C8L, - 0x099264FF0738C808L, - 0x9264FF0738C80809L, - 0x64FF0738C8080992L, - 0xFF0738C808099264L -}; - -/* Calculate the parity on a range of bits */ -static char range_parity(uint64_t dword, int max, int min) -{ - char parity = 0; - int i; - dword >>= min; - for (i=max-min; i>=0; i--) { - if (dword & 0x1) - parity = !parity; - dword >>= 1; - } - return parity; -} - -/* Calculate the 4-bit even byte-parity for an instruction */ -static unsigned char inst_parity(uint32_t word) -{ - int i, j; - char parity = 0; - for (j=0; j<4; j++) { - char byte_parity = 0; - for (i=0; i<8; i++) { - if (word & 0x80000000) - byte_parity = !byte_parity; - word <<= 1; - } - parity <<= 1; - parity |= byte_parity; - } - return parity; -} - -static uint32_t extract_ic(unsigned short addr, int data) -{ - unsigned short way; - int valid; - uint64_t taglo, va, tlo_tmp; - uint32_t taghi, taglolo, taglohi; - uint8_t lru; - int res = 0; - - printk("Icache index 0x%04x ", addr); - for (way = 0; way < 4; way++) { - /* Index-load-tag-I */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 4, 0(%3) \n\t" - "mfc0 %0, $29, 0\n\t" - "dmfc0 $1, $28, 0\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (taghi), "=r" (taglohi), - "=r" (taglolo) - : "r" ((way << 13) | addr)); - taglo = ((unsigned long long)taglohi << 32) | taglolo; - if (way == 0) { - lru = (taghi >> 14) & 0xff; - printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", - ((addr >> 5) & 0x3), /* bank */ - ((addr >> 7) & 0x3f), /* index */ - (lru & 0x3), - ((lru >> 2) & 0x3), - ((lru >> 4) & 0x3), - ((lru >> 6) & 0x3)); - } - va = (taglo & 0xC0000FFFFFFFE000) | addr; - if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) - va |= 0x3FFFF00000000000; - valid = ((taghi >> 29) & 1); - if (valid) { - tlo_tmp = taglo & 0xfff3ff; - if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { - printk(" ** bad parity in VTag0/G/ASID\n"); - res |= CP0_CERRI_TAG_PARITY; - } - if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { - printk(" ** bad parity in R/VTag1\n"); - res |= CP0_CERRI_TAG_PARITY; - } - } - if (valid ^ ((taghi >> 27) & 1)) { - printk(" ** bad parity for valid bit\n"); - res |= CP0_CERRI_TAG_PARITY; - } - printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", - way, va, valid, taghi, taglo); - - if (data) { - uint32_t datahi, insta, instb; - uint8_t predecode; - int offset; - - /* (hit all banks and ways) */ - for (offset = 0; offset < 4; offset++) { - /* Index-load-data-I */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 6, 0(%3) \n\t" - "mfc0 %0, $29, 1\n\t" - "dmfc0 $1, $28, 1\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (datahi), "=r" (insta), - "=r" (instb) - : "r" ((way << 13) | addr | (offset << 3))); - predecode = (datahi >> 8) & 0xff; - if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { - printk(" ** bad parity in predecode\n"); - res |= CP0_CERRI_DATA_PARITY; - } - /* XXXKW should/could check predecode bits themselves */ - if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { - printk(" ** bad parity in instruction a\n"); - res |= CP0_CERRI_DATA_PARITY; - } - if ((datahi & 0xf) ^ inst_parity(instb)) { - printk(" ** bad parity in instruction b\n"); - res |= CP0_CERRI_DATA_PARITY; - } - printk(" %05X-%08X%08X", datahi, insta, instb); - } - printk("\n"); - } - } - return res; -} - -/* Compute the ECC for a data doubleword */ -static uint8_t dc_ecc(uint64_t dword) -{ - uint64_t t; - uint32_t w; - uint8_t p; - int i; - - p = 0; - for (i = 7; i >= 0; i--) - { - p <<= 1; - t = dword & mask_72_64[i]; - w = (uint32_t)(t >> 32); - p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] - ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); - w = (uint32_t)(t & 0xFFFFFFFF); - p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] - ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); - } - return p; -} - -struct dc_state { - unsigned char val; - char *name; -}; - -static struct dc_state dc_states[] = { - { 0x00, "INVALID" }, - { 0x0f, "COH-SHD" }, - { 0x13, "NCO-E-C" }, - { 0x19, "NCO-E-D" }, - { 0x16, "COH-E-C" }, - { 0x1c, "COH-E-D" }, - { 0xff, "*ERROR*" } -}; - -#define DC_TAG_VALID(state) \ - (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) - -static char *dc_state_str(unsigned char state) -{ - struct dc_state *dsc = dc_states; - while (dsc->val != 0xff) { - if (dsc->val == state) - break; - dsc++; - } - return dsc->name; -} - -static uint32_t extract_dc(unsigned short addr, int data) -{ - int valid, way; - unsigned char state; - uint64_t taglo, pa; - uint32_t taghi, taglolo, taglohi; - uint8_t ecc, lru; - int res = 0; - - printk("Dcache index 0x%04x ", addr); - for (way = 0; way < 4; way++) { - /* Index-load-tag-D */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 5, 0(%3) \n\t" - "mfc0 %0, $29, 2\n\t" - "dmfc0 $1, $28, 2\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (taghi), "=r" (taglohi), - "=r" (taglolo) - : "r" ((way << 13) | addr)); - - taglo = ((unsigned long long)taglohi << 32) | taglolo; - pa = (taglo & 0xFFFFFFE000) | addr; - if (way == 0) { - lru = (taghi >> 14) & 0xff; - printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", - ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ - ((addr >> 6) & 0x3f), /* index */ - (lru & 0x3), - ((lru >> 2) & 0x3), - ((lru >> 4) & 0x3), - ((lru >> 6) & 0x3)); - } - state = (taghi >> 25) & 0x1f; - valid = DC_TAG_VALID(state); - printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", - way, pa, dc_state_str(state), state, taghi, taglo); - if (valid) { - if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { - printk(" ** bad parity in PTag1\n"); - res |= CP0_CERRD_TAG_ADDRESS; - } - if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { - printk(" ** bad parity in PTag0\n"); - res |= CP0_CERRD_TAG_ADDRESS; - } - } else { - res |= CP0_CERRD_TAG_STATE; - } - - if (data) { - uint64_t datalo; - uint32_t datalohi, datalolo, datahi; - int offset; - - for (offset = 0; offset < 4; offset++) { - /* Index-load-data-D */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 7, 0(%3) \n\t" - "mfc0 %0, $29, 3\n\t" - "dmfc0 $1, $28, 3\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (datahi), "=r" (datalohi), - "=r" (datalolo) - : "r" ((way << 13) | addr | (offset << 3))); - datalo = ((unsigned long long)datalohi << 32) | datalolo; - ecc = dc_ecc(datalo); - if (ecc != datahi) { - int bits = 0; - printk(" ** bad ECC (%02x %02x) ->", - datahi, ecc); - ecc ^= datahi; - while (ecc) { - if (ecc & 1) bits++; - ecc >>= 1; - } - res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; - } - printk(" %02X-%016llX", datahi, datalo); - } - printk("\n"); - } - } - return res; -} diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/Makefile linux-2.4.22/arch/mips/sibyte/sb1250/Makefile --- linux-2.4.21/arch/mips/sibyte/sb1250/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -4,10 +4,11 @@ obj-y := setup.o irq.o irq_handler.o time.o -obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_BCM1250_TBPROF) += bcm1250_tbprof.o -obj-$(CONFIG_MIPS32) += lib_hssubr.o -obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_BLK_DEV_IDE) += ide.o +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o +obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o +obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.22/arch/mips/sibyte/sb1250/bcm1250_tbprof.c --- linux-2.4.21/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Broadcom Corporation + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,15 +30,18 @@ #include #include #include +#include #include #include #include #include -#include "bcm1250_tbprof.h" +#include -#define DEVNAME "sb1250_tbprof" +#define DEVNAME "bcm1250_tbprof" -static struct sbprof_tb *sbp; +static struct sbprof_tb sbp; + +#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES) /************************************************************************ * Support for ZBbus sampling using the trace buffer @@ -53,13 +56,12 @@ * ************************************************************************/ -/* 100 samples per second on a 500 Mhz 1250 */ -#define TB_PERIOD 2500000ULL +static u_int64_t tb_period; static void arm_tb(void) { - unsigned long long scdperfcnt; - unsigned long long next = (1ULL << 40) - TB_PERIOD; + u_int64_t scdperfcnt; + u_int64_t next = (1ULL << 40) - tb_period; /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to trigger start of trace. XXX vary sampling period */ out64(0, KSEG1 + A_SCD_PERF_CNT_1); @@ -75,17 +77,22 @@ out64(next, KSEG1 + A_SCD_PERF_CNT_1); /* Reset the trace buffer */ out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); - out64(M_SCD_TRACE_CFG_FREEZE_FULL, KSEG1 + A_SCD_TRACE_CFG); - sbp->tb_armed = 1; + out64(M_SCD_TRACE_CFG_FREEZE_FULL +#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) + /* XXXKW may want to expose control to the data-collector */ + | M_SCD_TRACE_CFG_FORCECNT +#endif + , KSEG1 + A_SCD_TRACE_CFG); + sbp.tb_armed = 1; } static void sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) { int i; DBG(printk(DEVNAME ": tb_intr\n")); - if (sbp->next_tb_sample < MAX_TB_SAMPLES) { + if (sbp.next_tb_sample < MAX_TB_SAMPLES) { /* XXX should use XKPHYS to make writes bypass L2 */ - unsigned long long *p = sbp->sbprof_tbbuf[sbp->next_tb_sample++]; + u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; /* Read out trace */ out64(M_SCD_TRACE_CFG_START_READ, KSEG1 + A_SCD_TRACE_CFG); __asm__ __volatile__ ("sync" : : : "memory"); @@ -100,11 +107,11 @@ p[i-5] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 hi p[i-6] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 lo } - if (!sbp->tb_enable) { + if (!sbp.tb_enable) { DBG(printk(DEVNAME ": tb_intr shutdown\n")); out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); - sbp->tb_armed = 0; - wake_up(&sbp->tb_sync); + sbp.tb_armed = 0; + wake_up(&sbp.tb_sync); } else { arm_tb(); // knock down current interrupt and get another one later } @@ -112,36 +119,51 @@ /* No more trace buffer samples */ DBG(printk(DEVNAME ": tb_intr full\n")); out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); - sbp->tb_armed = 0; - if (!sbp->tb_enable) { - wake_up(&sbp->tb_sync); + sbp.tb_armed = 0; + if (!sbp.tb_enable) { + wake_up(&sbp.tb_sync); } + wake_up(&sbp.tb_read); } } static void sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs) { - panic(DEVNAME ": pc_intr"); + printk(DEVNAME ": unexpected pc_intr"); } static int sbprof_zbprof_start(struct file *filp) { - if (sbp->tb_enable) + u_int64_t scdperfcnt; + + if (sbp.tb_enable) return -EBUSY; DBG(printk(DEVNAME ": starting\n")); - sbp->tb_enable = 1; - sbp->next_tb_sample = 0; + sbp.tb_enable = 1; + sbp.next_tb_sample = 0; filp->f_pos = 0; if (request_irq - (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, "sbprof_tb trace freeze", sbp)) { + (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) { return -EBUSY; } + /* Make sure there isn't a perf-cnt interrupt waiting */ + scdperfcnt = in64(KSEG1 + A_SCD_PERF_CNT_CFG); + /* Disable and clear counters, override SRC_1 */ + out64((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) | + M_SPC_CFG_ENABLE | + M_SPC_CFG_CLEAR | + V_SPC_CFG_SRC1(1), + KSEG1 + A_SCD_PERF_CNT_CFG); + + /* We grab this interrupt to prevent others from trying to use + it, even though we don't want to service the interrupts + (they only feed into the trace-on-interrupt mechanism) */ if (request_irq - (K_INT_PERF_CNT, sbprof_pc_intr, 0, "sbprof_tb scd perfcnt", sbp)) { - free_irq(K_INT_TRACE_FREEZE, sbp); + (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) { + free_irq(K_INT_TRACE_FREEZE, &sbp); return -EBUSY; } @@ -206,18 +228,18 @@ { DBG(printk(DEVNAME ": stopping\n")); - if (sbp->tb_enable) { - sbp->tb_enable = 0; + if (sbp.tb_enable) { + sbp.tb_enable = 0; /* XXXKW there is a window here where the intr handler may run, see the disable, and do the wake_up before this sleep happens. */ - if (sbp->tb_armed) { + if (sbp.tb_armed) { DBG(printk(DEVNAME ": wait for disarm\n")); - interruptible_sleep_on(&sbp->tb_sync); + interruptible_sleep_on(&sbp.tb_sync); DBG(printk(DEVNAME ": disarm complete\n")); } - free_irq(K_INT_TRACE_FREEZE, sbp); - free_irq(K_INT_PERF_CNT, sbp); + free_irq(K_INT_TRACE_FREEZE, &sbp); + free_irq(K_INT_PERF_CNT, &sbp); } DBG(printk(DEVNAME ": done stopping\n")); @@ -233,24 +255,19 @@ if (minor != 0) { return -ENODEV; } - if (sbp != NULL) { + if (sbp.open) { return -EBUSY; } - /* XXXKW spinlock? */ - sbp = kmalloc(sizeof(struct sbprof_tb), GFP_KERNEL); - if (!sbp) { - return -ENOMEM; - } - memset(sbp, 0, sizeof(struct sbprof_tb)); - sbp->sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); - if (!sbp->sbprof_tbbuf) { - kfree(sbp); - sbp = NULL; + memset(&sbp, 0, sizeof(struct sbprof_tb)); + sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); + if (!sbp.sbprof_tbbuf) { return -ENOMEM; } - memset(sbp->sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); - init_waitqueue_head(&sbp->tb_sync); + memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); + init_waitqueue_head(&sbp.tb_sync); + init_waitqueue_head(&sbp.tb_read); + sbp.open = 1; return 0; } @@ -260,23 +277,22 @@ int minor; minor = MINOR(inode->i_rdev); - if (minor != 0 || sbp == NULL) { + if (minor != 0 || !sbp.open) { return -ENODEV; } - if (sbp->tb_armed || sbp->tb_enable) { + if (sbp.tb_armed || sbp.tb_enable) { sbprof_zbprof_stop(); } - vfree(sbp->sbprof_tbbuf); - kfree(sbp); - sbp = NULL; + vfree(sbp.sbprof_tbbuf); + sbp.open = 0; return 0; } static ssize_t sbprof_tb_read(struct file *filp, char *buf, - size_t size, loff_t *offp) + size_t size, loff_t *offp) { int cur_sample, sample_off, cur_count, sample_left; char *src; @@ -288,9 +304,9 @@ cur_sample = cur_off / TB_SAMPLE_SIZE; sample_off = cur_off % TB_SAMPLE_SIZE; sample_left = TB_SAMPLE_SIZE - sample_off; - while (size && (cur_sample < sbp->next_tb_sample)) { + while (size && (cur_sample < sbp.next_tb_sample)) { cur_count = size < sample_left ? size : sample_left; - src = (char *)(((long)sbp->sbprof_tbbuf[cur_sample])+sample_off); + src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off); copy_to_user(dest, src, cur_count); DBG(printk(DEVNAME ": read from sample %d, %d bytes\n", cur_sample, cur_count)); size -= cur_count; @@ -311,17 +327,12 @@ return count; } -#define SBPROF_ZBSTART _IOW('s', 0, int) -#define SBPROF_ZBSTOP _IOW('s', 1, int) -#define SBPROF_ZBFULL _IOW('s', 2, int) - static int sbprof_tb_ioctl(struct inode *inode, - struct file *filp, - unsigned int command, - unsigned long arg) + struct file *filp, + unsigned int command, + unsigned long arg) { int error = 0; - int full; switch (command) { case SBPROF_ZBSTART: @@ -330,9 +341,10 @@ case SBPROF_ZBSTOP: error = sbprof_zbprof_stop(); break; - case SBPROF_ZBFULL: - full = (sbp->next_tb_sample == MAX_TB_SAMPLES); - return put_user(full, (int *) arg); + case SBPROF_ZBWAITFULL: + interruptible_sleep_on(&sbp.tb_read); + /* XXXKW check if interrupted? */ + return put_user(TB_FULL, (int *) arg); default: error = -EINVAL; break; @@ -342,12 +354,12 @@ } static struct file_operations sbprof_tb_fops = { - owner: THIS_MODULE, - open: sbprof_tb_open, - release: sbprof_tb_release, - read: sbprof_tb_read, - ioctl: sbprof_tb_ioctl, - mmap: NULL, + .owner = THIS_MODULE, + .open = sbprof_tb_open, + .release = sbprof_tb_release, + .read = sbprof_tb_read, + .ioctl = sbprof_tb_ioctl, + .mmap = NULL, }; static devfs_handle_t devfs_handle; @@ -363,8 +375,9 @@ DEVFS_FL_DEFAULT, SBPROF_TB_MAJOR, 0, S_IFCHR | S_IRUGO | S_IWUGO, &sbprof_tb_fops, NULL); - sbp = NULL; - printk(KERN_INFO DEVNAME ": initialized\n"); + sbp.open = 0; + tb_period = zbbus_mhz * 10000LL; + printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period); return 0; } diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/bcm1250_tbprof.h linux-2.4.22/arch/mips/sibyte/sb1250/bcm1250_tbprof.h --- linux-2.4.21/arch/mips/sibyte/sb1250/bcm1250_tbprof.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/bcm1250_tbprof.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2001 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef BCM1250_TBPROF_H - -#if SBPROF_TB_DEBUG -#define DBG(a) a -#else -#define DBG(a) -#endif - -#define SBPROF_TB_MAJOR 240 - -typedef u_int64_t tb_sample_t[6*256]; - -struct sbprof_tb { - tb_sample_t *sbprof_tbbuf; - int next_tb_sample; - - volatile int tb_enable; - volatile int tb_armed; - - wait_queue_head_t tb_sync; -}; - -#define MAX_SAMPLE_BYTES (24*1024*1024) -#define MAX_TBSAMPLE_BYTES (12*1024*1024) - -#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t)) -#define TB_SAMPLE_SIZE (sizeof(tb_sample_t)) -#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE) - -/*************************************************************************** - * Routines for gathering ZBbus profiles using trace buffer - ***************************************************************************/ - -/* Requires: Already called zclk_timer_init with a value that won't - saturate 40 bits. No subsequent use of SCD performance counters - or trace buffer. - Effect: Starts gathering random ZBbus profiles using trace buffer. */ -static int sbprof_zbprof_start(struct file *filp); - -/* Effect: Stops collection of ZBbus profiles */ -static int sbprof_zbprof_stop(void); - - -/*************************************************************************** - * Routines for using 40-bit SCD cycle counter - * - * Client responsible for either handling interrupts or making sure - * the cycles counter never saturates, e.g., by doing - * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs. - ***************************************************************************/ - -/* Configures SCD counter 0 to count ZCLKs starting from val; - Configures SCD counters1,2,3 to count nothing. - Must not be called while gathering ZBbus profiles. - -unsigned long long val; */ -#define zclk_timer_init(val) \ - __asm__ __volatile__ (".set push;" \ - ".set mips64;" \ - "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ - "sd %0, 0x10($8);" /* write val to counter0 */ \ - "sd %1, 0($8);" /* config counter0 for zclks*/ \ - ".set pop" \ - : /* no outputs */ \ - /* enable, counter0 */ \ - : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \ - : /* modifies */ "$8" ) - - -/* Reads SCD counter 0 and puts result in value - unsigned long long val; */ -#define zclk_get(val) \ - __asm__ __volatile__ (".set push;" \ - ".set mips64;" \ - "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ - "ld %0, 0x10($8);" /* write val to counter0 */ \ - ".set pop" \ - : /* outputs */ "=r"(val) \ - : /* inputs */ \ - : /* modifies */ "$8" ) - -#endif diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/bus_watcher.c linux-2.4.22/arch/mips/sibyte/sb1250/bus_watcher.c --- linux-2.4.21/arch/mips/sibyte/sb1250/bus_watcher.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/bus_watcher.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * The Bus Watcher monitors internal bus transactions and maintains + * counts of transactions with error status, logging details and + * causing one of several interrupts. This driver provides a handler + * for those interrupts which aggregates the counts (to avoid + * saturating the 8-bit counters) and provides a presence in + * /proc/bus_watcher if PROC_FS is on. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +struct bw_stats_struct { + uint64_t status; + uint32_t l2_err; + uint32_t memio_err; + int status_printed; + unsigned long l2_cor_d; + unsigned long l2_bad_d; + unsigned long l2_cor_t; + unsigned long l2_bad_t; + unsigned long mem_cor_d; + unsigned long mem_bad_d; + unsigned long bus_error; +} bw_stats; + + +static void print_summary(uint32_t status, uint32_t l2_err, + uint32_t memio_err) +{ + printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + printk("\nLast recorded signature:\n"); + printk("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); +} + +/* + * check_bus_watcher is exported for use in situations where we want + * to see the most recent status of the bus watcher, which might have + * already been destructively read out of the registers. + * + * notes: this is currently used by the cache error handler + * should provide locking against the interrupt handler + */ +void check_bus_watcher(void) +{ + u32 status, l2_err, memio_err; + +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); +#else + /* Use non-destructive register */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS_DEBUG); +#endif + if (!(status & 0x7fffffff)) { + printk("Using last values reaped by bus watcher driver\n"); + status = bw_stats.status; + l2_err = bw_stats.l2_err; + memio_err = bw_stats.memio_err; + } else { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + } + if (status & ~(1UL << 31)) + print_summary(status, l2_err, memio_err); + else + printk("Bus watcher indicates no error\n"); +} + +static int bw_print_buffer(char *page, struct bw_stats_struct *stats) +{ + int len; + + len = sprintf(page, "SiByte Bus Watcher statistics\n"); + len += sprintf(page+len, "-----------------------------\n"); + len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n", + stats->l2_cor_d, stats->l2_bad_d); + len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n", + stats->l2_cor_t, stats->l2_bad_t); + len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n", + stats->mem_cor_d, stats->mem_bad_d); + len += sprintf(page+len, "IO-err %8ld\n", stats->bus_error); + len += sprintf(page+len, "\nLast recorded signature:\n"); + len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f), + (int)(G_SCD_BERR_TID(stats->status) >> 6), + (int)G_SCD_BERR_RID(stats->status), + (int)G_SCD_BERR_DCODE(stats->status)); + /* XXXKW indicate multiple errors between printings, or stats + collection (or both)? */ + if (stats->status & M_SCD_BERR_MULTERRS) + len += sprintf(page+len, "Multiple errors observed since last check.\n"); + if (stats->status_printed) { + len += sprintf(page+len, "(no change since last printing)\n"); + } else { + stats->status_printed = 1; + } + + return len; +} + +#ifdef CONFIG_PROC_FS + +/* For simplicity, I want to assume a single read is required each + time */ +static int bw_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + if (off == 0) { + len = bw_print_buffer(page, data); + *start = page; + } else { + len = 0; + *eof = 1; + } + return len; +} + +static void create_proc_decoder(struct bw_stats_struct *stats) +{ + struct proc_dir_entry *ent; + + ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL, + bw_read_proc, stats); + if (!ent) { + printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n"); + return; + } +} + +#endif /* CONFIG_PROC_FS */ + +/* + * sibyte_bw_int - handle bus watcher interrupts and accumulate counts + * + * notes: possible re-entry due to multiple sources + * should check/indicate saturation + */ +static void sibyte_bw_int(int irq, void *data, struct pt_regs *regs) +{ + struct bw_stats_struct *stats = data; + unsigned long cntr; +#ifndef CONFIG_PROC_FS + char bw_buf[1024]; +#endif + + /* Destructive read, clears register and interrupt */ + stats->status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + stats->status_printed = 0; + + stats->l2_err = cntr = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + stats->l2_cor_d += G_SCD_L2ECC_CORR_D(cntr); + stats->l2_bad_d += G_SCD_L2ECC_BAD_D(cntr); + stats->l2_cor_t += G_SCD_L2ECC_CORR_T(cntr); + stats->l2_bad_t += G_SCD_L2ECC_BAD_T(cntr); + csr_out32(0, IO_SPACE_BASE | A_BUS_L2_ERRORS); + + stats->memio_err = cntr = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + stats->mem_cor_d += G_SCD_MEM_ECC_CORR(cntr); + stats->mem_bad_d += G_SCD_MEM_ECC_BAD(cntr); + stats->bus_error += G_SCD_MEM_BUSERR(cntr); + csr_out32(0, IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + +#ifndef CONFIG_PROC_FS + bw_print_buffer(bw_buf, stats); + printk(bw_buf); +#endif +} + +int __init sibyte_bus_watcher(void) +{ + memset(&bw_stats, 0, sizeof(struct bw_stats_struct)); + bw_stats.status_printed = 1; + + if (request_irq(K_INT_BAD_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + printk("Failed to register bus watcher BAD_ECC irq\n"); + return -1; + } + if (request_irq(K_INT_COR_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + free_irq(K_INT_BAD_ECC, &bw_stats); + printk("Failed to register bus watcher COR_ECC irq\n"); + return -1; + } + if (request_irq(K_INT_IO_BUS, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + free_irq(K_INT_BAD_ECC, &bw_stats); + free_irq(K_INT_COR_ECC, &bw_stats); + printk("Failed to register bus watcher IO_BUS irq\n"); + return -1; + } + +#ifdef CONFIG_PROC_FS + create_proc_decoder(&bw_stats); +#endif + + return 0; +} + +__initcall(sibyte_bus_watcher); diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/ide.c linux-2.4.22/arch/mips/sibyte/sb1250/ide.c --- linux-2.4.21/arch/mips/sibyte/sb1250/ide.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/ide.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Derived loosely from ide-pmac.c, so: + * + * Copyright (C) 1998 Paul Mackerras. + * Copyright (C) 1995-1998 Mark Lord + */ +#include +#include + +#include + +extern struct ide_ops std_ide_ops; + +#ifdef CONFIG_PCMCIA_SIBYTE +extern ide_ack_intr_t sb_pcmcia_ack_intr; +#define SIBYTE_CS_REG(pcaddr) (IO_SPACE_BASE + PCMCIA_PHYS - mips_io_port_base + pcaddr) +#define SB_PC_PORT 0xff00 +#endif + +/* + * We are limiting the number of PCI-IDE devices to leave room for + * GenBus IDE (and possibly PCMCIA/CF?) + */ +static int sibyte_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t sibyte_ide_default_io_base(int index) +{ + return 0; +} + +static void sibyte_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ +#ifdef CONFIG_PCMCIA_SIBYTE + if (data_port == SB_PC_PORT) { + data_port = SIBYTE_CS_REG(0); + ctrl_port = SIBYTE_CS_REG(6); + hw->ack_intr = sb_pcmcia_ack_intr; + } +#endif + std_ide_ops.ide_init_hwif_ports(hw, data_port, ctrl_port, irq); +} + +struct ide_ops sibyte_ide_ops = { + &sibyte_ide_default_irq, + &sibyte_ide_default_io_base, + &sibyte_ide_init_hwif_ports +}; + +/* + * I/O operations. The FPGA for SiByte generic bus IDE deals with + * byte-swapping for us, so we can't share the I/O macros with other + * IDE (e.g. PCI-IDE) devices. + */ + +static inline void sibyte_outb(u8 val, unsigned long port) { + *(volatile u8 *)(mips_io_port_base + (port)) = val; +} + +static inline void sibyte_outw(u16 val, unsigned long port) { + *(volatile u16 *)(mips_io_port_base + (port)) = val; +} + +static inline void sibyte_outl(u32 val, unsigned long port) { + *(volatile u32 *)(mips_io_port_base + (port)) = val; +} + +static inline unsigned char sibyte_inb(unsigned long port) +{ + return (*(volatile u8 *)(mips_io_port_base + (port))); +} + +static inline unsigned short sibyte_inw(unsigned long port) +{ + return (*(volatile u16 *)(mips_io_port_base + (port))); +} + +static inline unsigned int sibyte_inl(unsigned long port) +{ + return (*(volatile u32 *)(mips_io_port_base + (port))); +} + + +static inline void sibyte_outsb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + sibyte_outb(*(u8 *)addr, port); + addr++; + } +} + +static inline void sibyte_insb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u8 *)addr = sibyte_inb(port); + addr++; + } +} + +static inline void sibyte_outsw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + sibyte_outw(*(u16 *)addr, port); + addr += 2; + } +} + +static inline void sibyte_insw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u16 *)addr = sibyte_inw(port); + addr += 2; + } +} + +static inline void sibyte_outsl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + sibyte_outl(*(u32 *)addr, port); + addr += 4; + } +} + +static inline void sibyte_insl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u32 *)addr = sibyte_inl(port); + addr += 4; + } +} + +void sibyte_set_ideops(ide_hwif_t *hwif) +{ + hwif->INB = sibyte_inb; + hwif->INW = sibyte_inw; + hwif->INL = sibyte_inl; + hwif->OUTB = sibyte_outb; + hwif->OUTW = sibyte_outw; + hwif->OUTL = sibyte_outl; + hwif->INSW = sibyte_insw; + hwif->INSL = sibyte_insl; + hwif->OUTSW = sibyte_outsw; + hwif->OUTSL = sibyte_outsl; +} diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/irq.c linux-2.4.22/arch/mips/sibyte/sb1250/irq.c --- linux-2.4.21/arch/mips/sibyte/sb1250/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -50,21 +51,37 @@ static void disable_sb1250_irq(unsigned int irq); static unsigned int startup_sb1250_irq(unsigned int irq); static void ack_sb1250_irq(unsigned int irq); +#ifdef CONFIG_SMP +static void sb1250_set_affinity(unsigned int irq, unsigned long mask); +#endif + +#ifdef CONFIG_SIBYTE_HAS_LDT +extern unsigned long ldt_eoi_space; +#endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB +#include extern void breakpoint(void); -extern void set_debug_traps(void); +static int kgdb_irq; +#ifdef CONFIG_GDB_CONSOLE +extern void register_gdb_console(void); +#endif /* kgdb is on when configured. Pass "nokgdb" kernel arg to turn it off */ static int kgdb_flag = 1; static int __init nokgdb(char *str) { kgdb_flag = 0; + return 1; } __setup("nokgdb", nokgdb); -#endif -#define NR_IRQS 64 +/* Default to UART1 */ +int kgdb_port = 1; +#ifdef CONFIG_SIBYTE_SB1250_DUART +extern char sb1250_duart_present[]; +#endif +#endif static struct hw_interrupt_type sb1250_irq_type = { "SB1250-IMR", @@ -74,9 +91,16 @@ disable_sb1250_irq, ack_sb1250_irq, end_sb1250_irq, +#ifdef CONFIG_SMP + sb1250_set_affinity +#else NULL +#endif }; +/* Store the CPU id (not the logical number) */ +int sb1250_irq_owner[SB1250_NR_IRQS]; + spinlock_t sb1250_imr_lock = SPIN_LOCK_UNLOCKED; void sb1250_mask_irq(int cpu, int irq) @@ -85,9 +109,9 @@ u64 cur_ints; spin_lock_irqsave(&sb1250_imr_lock, flags); - cur_ints = in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); cur_ints |= (((u64) 1) << irq); - out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); spin_unlock_irqrestore(&sb1250_imr_lock, flags); } @@ -97,12 +121,61 @@ u64 cur_ints; spin_lock_irqsave(&sb1250_imr_lock, flags); - cur_ints = in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); cur_ints &= ~(((u64) 1) << irq); - out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); spin_unlock_irqrestore(&sb1250_imr_lock, flags); } +#ifdef CONFIG_SMP +static void sb1250_set_affinity(unsigned int irq, unsigned long mask) +{ + int i = 0, old_cpu, cpu, int_on; + u64 cur_ints; + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + while (mask) { + if (mask & 1) { + mask >>= 1; + break; + } + mask >>= 1; + i++; + } + + if (mask) { + printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq); + return; + } + + /* Convert logical CPU to physical CPU */ + cpu = cpu_logical_map(i); + + /* Protect against other affinity changers and IMR manipulation */ + spin_lock_irqsave(&desc->lock, flags); + spin_lock(&sb1250_imr_lock); + + /* Swizzle each CPU's IMR (but leave the IP selection alone) */ + old_cpu = sb1250_irq_owner[irq]; + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK); + int_on = !(cur_ints & (((u64) 1) << irq)); + if (int_on) { + /* If it was on, mask it */ + cur_ints |= (((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK); + } + sb1250_irq_owner[irq] = cpu; + if (int_on) { + /* unmask for the new CPU */ + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints &= ~(((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + } + spin_unlock(&sb1250_imr_lock); + spin_unlock_irqrestore(&desc->lock, flags); +} +#endif /* Defined in arch/mips/sibyte/sb1250/irq_handler.S */ @@ -112,7 +185,7 @@ static unsigned int startup_sb1250_irq(unsigned int irq) { - sb1250_unmask_irq(0, irq); + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); return 0; /* never anything pending */ } @@ -120,36 +193,58 @@ static void disable_sb1250_irq(unsigned int irq) { - sb1250_mask_irq(0, irq); + sb1250_mask_irq(sb1250_irq_owner[irq], irq); } static void enable_sb1250_irq(unsigned int irq) { - sb1250_unmask_irq(0, irq); + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); } static void ack_sb1250_irq(unsigned int irq) { +#ifdef CONFIG_SIBYTE_HAS_LDT u64 pending; /* - * If the interrupt was an LDT interrupt, now is the time - * to clear it. + * If the interrupt was an HT interrupt, now is the time to + * clear it. NOTE: we assume the HT bridge was set up to + * deliver the interrupts to all CPUs (which makes affinity + * changing easier for us) */ - pending = in64(KSEG1 + A_IMR_REGISTER(0,R_IMR_LDT_INTERRUPT)); + pending = in64(KSEG1 + A_IMR_REGISTER(sb1250_irq_owner[irq], + R_IMR_LDT_INTERRUPT)); pending &= ((u64)1 << (irq)); - if (pending) - out64(pending, KSEG1+A_IMR_REGISTER(0,R_IMR_LDT_INTERRUPT_CLR)); - - sb1250_mask_irq(0, irq); + if (pending) { + int i; + for (i=0; i= NR_IRQS) + if (irq >= SB1250_NR_IRQS) return -EINVAL; spin_lock_irqsave(&desc->lock,flags); @@ -198,6 +298,7 @@ desc->depth = 0; } spin_unlock_irqrestore(&desc->lock,flags); + return 0; } /* @@ -235,7 +336,7 @@ STATUSF_IP1 | STATUSF_IP0; /* Default everything to IP2 */ - for (i = 0; i < NR_IRQS; i++) { /* was I0 */ + for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */ out64(IMR_IP2_VAL, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + @@ -273,44 +374,49 @@ /* * Note that the timer interrupts are also mapped, but this is - * done in sb1250_time_init() + * done in sb1250_time_init(). Also, the profiling driver + * does its own management of IP7. */ -#ifdef CONFIG_BCM1250_PROF - imask |= STATUSF_IP7; -#endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB imask |= STATUSF_IP6; #endif /* Enable necessary IPs, disable the rest */ - change_cp0_status(ST0_IM, imask); + change_c0_status(ST0_IM, imask); set_except_vector(0, sb1250_irq_handler); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (kgdb_flag) { + kgdb_irq = K_INT_UART_0 + kgdb_port; + +#ifdef CONFIG_SIBYTE_SB1250_DUART + sb1250_duart_present[kgdb_port] = 0; +#endif /* Setup uart 1 settings, mapper */ - out64(M_DUART_IMR_BRK, KSEG1 + A_DUART + R_DUART_IMR_B); + out64(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port)); + sb1250_steal_irq(kgdb_irq); out64(IMR_IP6_VAL, - KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_UART_1<<3)); - tmp = in64(KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)); - tmp &= ~(1< -extern void set_async_breakpoint(unsigned int epc); - -#define duart_out(reg, val) out64(val, KSEG1 + A_DUART_CHANREG(1,reg)) -#define duart_in(reg) in64(KSEG1 + A_DUART_CHANREG(1,reg)) +#define duart_out(reg, val) csr_out32(val, KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) +#define duart_in(reg) csr_in32(KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) void sb1250_kgdb_interrupt(struct pt_regs *regs) { @@ -319,10 +425,11 @@ * host to stop the break, since we would see another * interrupt on the end-of-break too) */ + kstat.irqs[smp_processor_id()][kgdb_irq]++; mdelay(500); duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT | M_DUART_RX_EN | M_DUART_TX_EN); - if (!user_mode(regs)) - set_async_breakpoint(regs->cp0_epc); + set_async_breakpoint(®s->cp0_epc); } -#endif /* CONFIG_REMOTE_DEBUG */ + +#endif /* CONFIG_KGDB */ diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/irq_handler.S linux-2.4.22/arch/mips/sibyte/sb1250/irq_handler.S --- linux-2.4.21/arch/mips/sibyte/sb1250/irq_handler.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/irq_handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -77,15 +77,11 @@ mfc0 a0, CP0_EPC jal sbprof_cpu_intr addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ - /* Re-enable interrupts here so that events due to sbprof_cpu_intr - get charged to ret_from_irq (via a recursive interrupt) - rather than the restart pc. */ - mfc0 t0, CP0_STATUS - or t0, ST0_IE j ret_from_irq - mtc0 t0, CP0_STATUS # delay slot + nop 0: #endif + /* Timer interrupt is routed to IP[4] */ andi t1, s0, CAUSEF_IP4 beqz t1, 1f @@ -100,7 +96,7 @@ /* Mailbox interrupt is routed to IP[3] */ andi t1, s0, CAUSEF_IP3 beqz t1, 2f - nop + nop jal sb1250_mailbox_interrupt move a0, sp j ret_from_irq @@ -108,7 +104,7 @@ 2: #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* KGDB (uart 1) interrupt is routed to IP[6] */ andi t1, s0, CAUSEF_IP6 beqz t1, 1f @@ -127,8 +123,14 @@ /* * Default...we've hit an IP[2] interrupt, which means we've got to * check the 1250 interrupt registers to figure out what to do + * Need to detect which CPU we're on, now that smp_affinity is supported. */ la v0, KSEG1 + A_IMR_CPU0_BASE +#ifdef CONFIG_SMP + lw t1, TASK_PROCESSOR($28) + sll t1, IMR_REGISTER_SPACING_SHIFT + addu v0, t1 +#endif ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */ beqz s0, 4f /* No interrupts. Return */ diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/lib_hssubr.S linux-2.4.22/arch/mips/sibyte/sb1250/lib_hssubr.S --- linux-2.4.21/arch/mips/sibyte/sb1250/lib_hssubr.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/lib_hssubr.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include -#include -#include -#include - - .set mips64 - -#define HAZARD SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP - - -/* ********************************************************************* - * hs_read8 - read 8-bit bytes - ********************************************************************* */ - - -LEAF(hs_read8) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0,v0 - lb v0, (a0) - and v0, 0xFF - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read8) - -/* ********************************************************************* - * hs_read16 - read 16-bit shorts - ********************************************************************* */ - -LEAF(hs_read16) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - lh v0, (a0) - and v0, 0xFFFF - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read16) - -/* ********************************************************************* - * hs_read32 - read 32-bit ints - ********************************************************************* */ - -LEAF(hs_read32) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - lw v0, (a0) - and v0, 0xFFFFFFFF - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read32) - -/* ********************************************************************* - * hs_read64 - read 64-bit longs - ********************************************************************* */ - -LEAF(hs_read64) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - ld v0, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read64) - -/* ********************************************************************* - * hs_write8 - write 8-bit bytes - ********************************************************************* */ - -LEAF(hs_write8) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sb a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write8) - -/* ********************************************************************* - * hs_write16 - write 16-bit shorts - ********************************************************************* */ - -LEAF(hs_write16) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sh a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write16) - -/* ********************************************************************* - * hs_write32 - write 32-bit longs - ********************************************************************* */ - -LEAF(hs_write32) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sw a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write32) - -/* ********************************************************************* - * hs_write64 - write 64-bit longs - ********************************************************************* */ - -LEAF(hs_write64) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sd a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write64) diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/lib_hssubr.h linux-2.4.22/arch/mips/sibyte/sb1250/lib_hssubr.h --- linux-2.4.21/arch/mips/sibyte/sb1250/lib_hssubr.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/lib_hssubr.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Broadcom Corporation - * Copyright (C) 2002 Ralf Baechle - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 _LIB_HSSUBR_H -#define _LIB_HSSUBR_H - -#include -#include - -typedef long hsaddr_t; - -#ifdef CONFIG_MIPS64 - -static inline void hs_write8(hsaddr_t a, uint8_t b) -{ - *(volatile uint8_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline void hs_write16(hsaddr_t a, uint16_t b) -{ - *(volatile uint16_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline void hs_write32(hsaddr_t a, uint32_t b) -{ - *(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline void hs_write64(hsaddr_t a, uint64_t b) -{ - *(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline uint8_t hs_read8(hsaddr_t a) -{ - return *(volatile uint8_t *) a; -} - -static inline uint16_t hs_read16(hsaddr_t a) -{ - return *(volatile uint16_t *) a; -} - -static inline uint32_t hs_read32(hsaddr_t a) -{ - return *(volatile uint32_t *) a; -} - -static inline uint64_t hs_read64(hsaddr_t a) -{ - return *(volatile uint64_t *) a; -} - -#else /* just CONFIG_MIPS32 */ - -extern void hs_write8(hsaddr_t a, uint8_t b); -extern void hs_write16(hsaddr_t a, uint16_t b); -extern void hs_write32(hsaddr_t a, uint32_t b); -extern void hs_write64(hsaddr_t a, uint64_t b); -extern uint8_t hs_read8(hsaddr_t a); -extern uint16_t hs_read16(hsaddr_t a); -extern uint32_t hs_read32(hsaddr_t a); -extern uint64_t hs_read64(hsaddr_t a); -#endif - -#endif /* _LIB_HSSUBR_H */ diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/pci.c linux-2.4.22/arch/mips/sibyte/sb1250/pci.c --- linux-2.4.21/arch/mips/sibyte/sb1250/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Broadcom Corporation + * Copyright (C) 2001,2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,17 +24,10 @@ * configuration space, and set up the translation for I/O * space accesses. * - * To access configuration space, we call some assembly-level - * stubs that flip the KX bit on and off in the status - * register, and do XKSEG addressed memory accesses there. - * It's slow (7 SSNOPs to guarantee that KX is set!) but - * fortunately, config space accesses are rare. - * - * We could use the ioremap functionality for the confguration - * space as well as I/O space, but I'm not sure of the - * implications of setting aside 16MB of KSEG2 for something - * that is used so rarely (how much space in the page tables?) - * + * To access configuration space, we use ioremap. In the 32-bit + * kernel, this consumes either 4 or 8 page table pages, and 16MB of + * kernel mapped memory. Hopefully neither of these should be a huge + * problem. */ #include #include @@ -48,56 +41,74 @@ #include #include -#include "lib_hssubr.h" - /* - * This macro calculates the offset into config space where - * a given bus, device/function, and offset live on the sb1250 + * Macros for calculating offsets into config space given a device + * structure or dev/fun/reg */ - #define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where)) +#define CFGADDR(dev,where) CFGOFFSET((dev)->bus->number,(dev)->devfn,where) + +static void *cfg_space; + +#define PCI_BUS_ENABLED 1 +#define LDT_BUS_ENABLED 2 +#define PCI_DEVICE_MODE 4 +static int sb1250_bus_status = 0; + +#define PCI_BRIDGE_DEVICE 0 +#define LDT_BRIDGE_DEVICE 1 + +#ifdef CONFIG_SIBYTE_HAS_LDT /* - * Using the above offset, this macro calcuates the physical address in the - * config space. + * HT's level-sensitive interrupts require EOI, which is generated + * through a 4MB memory-mapped region */ -#define CFGADDR(dev,where) (A_PHYS_LDTPCI_CFG_MATCH_BITS + \ - CFGOFFSET(dev->bus->number,dev->devfn,where)) +unsigned long ldt_eoi_space; +#endif /* * Read/write 32-bit values in config space. */ static inline u32 READCFG32(u32 addr) { - hs_read32(addr & ~3); + return *(u32 *)(cfg_space + (addr&~3)); } static inline void WRITECFG32(u32 addr, u32 data) { - return hs_write32(addr & ~3,(data)); + *(u32 *)(cfg_space + (addr & ~3)) = data; } /* - * This variable is the KSEG2 (kernel virtual) mapping of the ISA/PCI I/O - * space area. We map 64K here and the offsets from this address get treated - * with "match bytes" policy to make everything look little-endian. So, you - * need to also set CONFIG_SWAP_IO_SPACE, but this is the combination that - * works correctly with most of Linux's drivers. + * Some checks before doing config cycles: + * In PCI Device Mode, hide everything on bus 0 except the LDT host + * bridge. Otherwise, access is controlled by bridge MasterEn bits. */ +static int +sb1250_pci_can_access(struct pci_dev *dev) +{ + u32 devno; -#define PCI_BUS_ENABLED 1 -#define LDT_BUS_ENABLED 2 - -static int sb1250_bus_status = 0; - -#define MATCH_BITS 0x20000000 /* really belongs in an include file */ + if (!(sb1250_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE))) + return 0; -#define LDT_BRIDGE_START ((A_PCI_TYPE01_HEADER|MATCH_BITS)+0x00) -#define LDT_BRIDGE_END ((A_PCI_TYPE01_HEADER|MATCH_BITS)+0x20) + if (dev->bus->number == 0) { + devno = PCI_SLOT(dev->devfn); + if (devno == LDT_BRIDGE_DEVICE) + return (sb1250_bus_status & LDT_BUS_ENABLED) != 0; + else if (sb1250_bus_status & PCI_DEVICE_MODE) + return 0; + else + return 1; + } else + return 1; +} /* * Read/write access functions for various sizes of values - * in config space. + * in config space. Return all 1's for disallowed accesses + * for a kludgy but adequate simulation of master aborts. */ static int @@ -106,23 +117,16 @@ u32 data = 0; u32 cfgaddr = CFGADDR(dev, where); - data = READCFG32(cfgaddr); - - /* - * If the LDT was not configured, make it look like the bridge - * header is not there. - */ - if (!(sb1250_bus_status & LDT_BUS_ENABLED) && - (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) { + if (sb1250_pci_can_access(dev)) + data = READCFG32(cfgaddr); + else data = 0xFFFFFFFF; - } *val = (data >> ((where & 3) << 3)) & 0xff; return PCIBIOS_SUCCESSFUL; } - static int sb1250_pci_read_config_word(struct pci_dev *dev, int where, u16 * val) { @@ -132,16 +136,10 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; - data = READCFG32(cfgaddr); - - /* - * If the LDT was not configured, make it look like the bridge - * header is not there. - */ - if (!(sb1250_bus_status & LDT_BUS_ENABLED) && - (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) { + if (sb1250_pci_can_access(dev)) + data = READCFG32(cfgaddr); + else data = 0xFFFFFFFF; - } *val = (data >> ((where & 3) << 3)) & 0xffff; @@ -157,16 +155,10 @@ if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; - data = READCFG32(cfgaddr); - - /* - * If the LDT was not configured, make it look like the bridge - * header is not there. - */ - if (!(sb1250_bus_status & LDT_BUS_ENABLED) && - (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) { + if (sb1250_pci_can_access(dev)) + data = READCFG32(cfgaddr); + else data = 0xFFFFFFFF; - } *val = data; @@ -180,12 +172,14 @@ u32 data = 0; u32 cfgaddr = CFGADDR(dev, where); - data = READCFG32(cfgaddr); + if (sb1250_pci_can_access(dev)) { + data = READCFG32(cfgaddr); - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); - WRITECFG32(cfgaddr, data); + WRITECFG32(cfgaddr, data); + } return PCIBIOS_SUCCESSFUL; } @@ -199,12 +193,14 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; - data = READCFG32(cfgaddr); + if (sb1250_pci_can_access(dev)) { + data = READCFG32(cfgaddr); - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); - WRITECFG32(cfgaddr, data); + WRITECFG32(cfgaddr, data); + } return PCIBIOS_SUCCESSFUL; } @@ -217,7 +213,8 @@ if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; - WRITECFG32(cfgaddr, val); + if (sb1250_pci_can_access(dev)) + WRITECFG32(cfgaddr, val); return PCIBIOS_SUCCESSFUL; } @@ -237,48 +234,60 @@ uint32_t cmdreg; uint64_t reg; + cfg_space = ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16*1024*1024); + /* * See if the PCI bus has been configured by the firmware. */ - - cmdreg = READCFG32((A_PCI_TYPE00_HEADER | MATCH_BITS) + - PCI_COMMAND); - - if (!(cmdreg & PCI_COMMAND_MASTER)) { - printk - ("PCI: Skipping PCI probe. Bus is not initialized.\n"); - return; - } - reg = *((volatile uint64_t *) KSEG1ADDR(A_SCD_SYSTEM_CFG)); if (!(reg & M_SYS_PCI_HOST)) { - printk("PCI: Skipping PCI probe. Processor is in PCI device mode.\n"); - return; + sb1250_bus_status |= PCI_DEVICE_MODE; + } else { + cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), + PCI_COMMAND)); + if (!(cmdreg & PCI_COMMAND_MASTER)) { + printk + ("PCI: Skipping PCI probe. Bus is not initialized.\n"); + iounmap(cfg_space); + return; + } + sb1250_bus_status |= PCI_BUS_ENABLED; } - sb1250_bus_status |= PCI_BUS_ENABLED; - /* - * Establish a mapping from KSEG2 (kernel virtual) to PCI I/O space - * Use "match bytes", even though this exposes endianness. - * big-endian Linuxes will have CONFIG_SWAP_IO_SPACE set. + * Establish mappings in KSEG2 (kernel virtual) to PCI I/O + * space. Use "match bytes" policy to make everything look + * little-endian. So, you need to also set + * CONFIG_SWAP_IO_SPACE, but this is the combination that + * works correctly with most of Linux's drivers. + * XXX ehs: Should this happen in PCI Device mode? */ - set_io_port_base(ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536)); + set_io_port_base((unsigned long) + ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536)); isa_slot_offset = (unsigned long) ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024*1024); +#ifdef CONFIG_SIBYTE_HAS_LDT /* * Also check the LDT bridge's enable, just in case we didn't * initialize that one. */ - cmdreg = READCFG32((A_PCI_TYPE01_HEADER | MATCH_BITS) + - PCI_COMMAND); - + cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(LDT_BRIDGE_DEVICE, 0), + PCI_COMMAND)); if (cmdreg & PCI_COMMAND_MASTER) { sb1250_bus_status |= LDT_BUS_ENABLED; + + /* + * Need bits 23:16 to convey vector number. Note that + * this consumes 4MB of kernel-mapped memory + * (Kseg2/Kseg3) for 32-bit kernel. + */ + ldt_eoi_space = (unsigned long) + ioremap(A_PHYS_LDT_SPECIAL_MATCH_BYTES, 4*1024*1024); } +#endif /* Probe for PCI hardware */ @@ -290,41 +299,10 @@ #endif } -int pcibios_enable_device(struct pci_dev *dev) -{ - /* Not needed, since we enable all devices at startup. */ - return 0; -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -char *__init pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - struct pci_fixup pcibios_fixups[] = { {0} }; -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - unsigned long where, size; - u32 reg; - - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - /* * Called after each bus is probed, but before its children * are examined. diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/prom.c linux-2.4.22/arch/mips/sibyte/sb1250/prom.c --- linux-2.4.21/arch/mips/sibyte/sb1250/prom.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -117,3 +117,7 @@ phys_t addr = pagenr << PAGE_SHIFT; return (addr < (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024)); } + +void prom_putchar(char c) +{ +} diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/setup.c linux-2.4.22/arch/mips/sibyte/sb1250/setup.c --- linux-2.4.21/arch/mips/sibyte/sb1250/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,39 +16,195 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include +#include + +#include +#include +#include #include #include #include #include -/* Setup code likely to be common to all BCM1250 platforms */ +unsigned int sb1_pass; +unsigned int soc_pass; +unsigned int soc_type; +unsigned int periph_rev; +unsigned int zbbus_mhz; + +static char *soc_str; +static char *pass_str; +static unsigned int war_pass; /* XXXKW don't overload PASS defines? */ + +static inline int setup_bcm1250(void); +static inline int setup_bcm112x(void); + +/* Setup code likely to be common to all SiByte platforms */ + +static inline int sys_rev_decode(void) +{ + int ret = 0; + + war_pass = soc_pass; + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: + case K_SYS_SOC_TYPE_BCM1250_ALT2: + soc_str = "BCM1250"; + ret = setup_bcm1250(); + break; + case K_SYS_SOC_TYPE_BCM1120: + soc_str = "BCM1120"; + ret = setup_bcm112x(); + break; + case K_SYS_SOC_TYPE_BCM1125: + soc_str = "BCM1125"; + ret = setup_bcm112x(); + break; + case K_SYS_SOC_TYPE_BCM1125H: + soc_str = "BCM1125H"; + ret = setup_bcm112x(); + break; + default: + prom_printf("Unknown SOC type %x\n", soc_type); + ret = 1; + break; + } + return ret; +} + +static inline int setup_bcm1250(void) +{ + int ret = 0; + + switch (soc_pass) { + case K_SYS_REVISION_BCM1250_PASS1: + periph_rev = 1; + pass_str = "Pass 1"; + break; + case K_SYS_REVISION_BCM1250_A10: + periph_rev = 2; + pass_str = "A8/A10"; + /* XXXKW different war_pass? */ + war_pass = K_SYS_REVISION_BCM1250_PASS2; + break; + case K_SYS_REVISION_BCM1250_PASS2_2: + periph_rev = 2; + pass_str = "B1"; + break; + case K_SYS_REVISION_BCM1250_B2: + periph_rev = 2; + pass_str = "B2"; + war_pass = K_SYS_REVISION_BCM1250_PASS2_2; + break; + case K_SYS_REVISION_BCM1250_PASS3: + periph_rev = 3; + pass_str = "C0"; + break; + case K_SYS_REVISION_BCM1250_C1: + periph_rev = 3; + pass_str = "C1"; + break; + default: + if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) { + periph_rev = 2; + pass_str = "A0-A6"; + war_pass = K_SYS_REVISION_BCM1250_PASS2; + } else { + prom_printf("Unknown BCM1250 rev %x\n", soc_pass); + ret = 1; + } + break; + } + return ret; +} + +static inline int setup_bcm112x(void) +{ + int ret = 0; -unsigned int sb1250_pass; + switch (soc_pass) { + case 0: + /* Early build didn't have revid set */ + periph_rev = 3; + pass_str = "A1"; + war_pass = K_SYS_REVISION_BCM112x_A1; + break; + case K_SYS_REVISION_BCM112x_A1: + periph_rev = 3; + pass_str = "A1"; + break; + case K_SYS_REVISION_BCM112x_A2: + periph_rev = 3; + pass_str = "A2"; + break; + default: + prom_printf("Unknown %s rev %x\n", soc_str, soc_pass); + ret = 1; + } + return ret; +} void sb1250_setup(void) { + uint64_t sys_rev; + int plldiv; int bad_config = 0; - sb1250_pass = G_SYS_REVISION(in64(IO_SPACE_BASE | A_SCD_SYSTEM_REVISION)); - /* sb1250_pass is more specific than "1", "2" etc. There are - many revision numbers corresponding to "Pass 2". */ - switch(sb1250_pass) { - case 1: + sb1_pass = read_c0_prid() & 0xff; + sys_rev = in64(IO_SPACE_BASE | A_SCD_SYSTEM_REVISION); + soc_type = SYS_SOC_TYPE(sys_rev); + soc_pass = G_SYS_REVISION(sys_rev); + + if (sys_rev_decode()) { + prom_printf("Restart after failure to identify SiByte chip\n"); + machine_restart(NULL); + } + + plldiv = G_SYS_PLL_DIV(in64(IO_SPACE_BASE | A_SCD_SYSTEM_CFG)); + zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25); #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS - printk("@@@@ This is a pass 1 board, and the kernel doesn't have the proper workarounds compiled in. @@@@"); + out64(0, KSEG1 + A_SCD_ZBBUS_CYCLE_COUNT); +#endif + + prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n", + soc_str, pass_str, zbbus_mhz * 2, sb1_pass); + prom_printf("Board type: %s\n", get_system_type()); + + switch(war_pass) { + case K_SYS_REVISION_BCM1250_PASS1: +#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS + prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); bad_config = 1; #endif break; - default: -#if defined(CONFIG_CPU_HAS_PREFETCH) || !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) - printk("@@@@ This is a pass 2 board, and the kernel doesn't have the proper workarounds compiled in. @@@@"); - printk("@@@@ Prefetches are enabled in this kernel, but are buggy on this board. @@@@"); + case K_SYS_REVISION_BCM1250_PASS2: + /* Pass 2 - easiest as default for now - so many numbers */ +#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) + prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); + bad_config = 1; +#endif +#ifdef CONFIG_CPU_HAS_PREFETCH + prom_printf("@@@@ Prefetches may be enabled in this kernel, but are buggy on this board. @@@@\n"); bad_config = 1; #endif break; + case K_SYS_REVISION_BCM1250_PASS2_2: +#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS + prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); + bad_config = 1; +#endif +#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || !defined(CONFIG_CPU_HAS_PREFETCH) + prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n"); +#endif + break; + default: + break; } - /* XXXKW this is too early for panic/printk to actually do much! */ if (bad_config) { - panic("Invalid configuration for this pass."); + prom_printf("Invalid configuration for this chip.\n"); + machine_restart(NULL); } } diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/smp.c linux-2.4.22/arch/mips/sibyte/sb1250/smp.c --- linux-2.4.21/arch/mips/sibyte/sb1250/smp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -108,6 +108,9 @@ CPUMASK_SETB(cpu_online_map, 0); atomic_set(&cpus_booted, 1); /* Master CPU is already booted... */ init_idle(); + __cpu_number_map[0] = 0; + __cpu_logical_map[0] = 0; + /* smp_tune_scheduling(); XXX */ /* * This loop attempts to compensate for "holes" in the CPU @@ -128,9 +131,6 @@ p->processor = i; p->cpus_runnable = 1 << i; /* we schedule the first task manually */ - /* Attach to the address space of init_task. */ - atomic_inc(&init_mm.mm_count); - p->active_mm = &init_mm; init_tasks[i] = p; del_from_runqueue(p); @@ -144,6 +144,8 @@ (unsigned long)p); } while (!retval && (cur_cpu < NR_CPUS)); if (retval) { + __cpu_number_map[cur_cpu] = i; + __cpu_logical_map[i] = cur_cpu; i++; } else { panic("CPU discovery disaster"); diff -urN linux-2.4.21/arch/mips/sibyte/sb1250/time.c linux-2.4.22/arch/mips/sibyte/sb1250/time.c --- linux-2.4.21/arch/mips/sibyte/sb1250/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/sb1250/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -52,6 +52,7 @@ void sb1250_time_init(void) { int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0+cpu; /* Only have 4 general purpose timers */ if (cpu > 3) { @@ -63,11 +64,11 @@ do_gettimeoffset = sb1250_gettimeoffset; } - sb1250_mask_irq(cpu, K_INT_TIMER_0 + cpu); + sb1250_mask_irq(cpu, irq); /* Map the timer interrupt to ip[4] of this cpu */ out64(IMR_IP4_VAL, KSEG1 + A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) - + ((K_INT_TIMER_0 + cpu)<<3)); + + (irq<<3)); /* the general purpose timer ticks at 1 Mhz independent if the rest of the system */ /* Disable the timer and set up the count */ @@ -84,8 +85,8 @@ out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); - sb1250_unmask_irq(cpu, K_INT_TIMER_0 + cpu); - sb1250_steal_irq(K_INT_TIMER_0 + cpu); + sb1250_unmask_irq(cpu, irq); + sb1250_steal_irq(irq); /* * This interrupt is "special" in that it doesn't use the request_irq * way to hook the irq line. The timer interrupt is initialized early @@ -99,8 +100,9 @@ void sb1250_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0+cpu; - kstat.irqs[cpu][K_INT_TIMER_0+cpu]++; + kstat.irqs[cpu][irq]++; /* Reset the timer */ out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); @@ -109,13 +111,13 @@ * CPU 0 handles the global timer interrupt job */ if (cpu == 0) { - ll_timer_interrupt(0, regs); + ll_timer_interrupt(irq, regs); } /* * every CPU should do profiling and process accouting */ - ll_local_timer_interrupt(0, regs); + ll_local_timer_interrupt(irq, regs); } /* diff -urN linux-2.4.21/arch/mips/sibyte/swarm/Makefile linux-2.4.22/arch/mips/sibyte/swarm/Makefile --- linux-2.4.21/arch/mips/sibyte/swarm/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/swarm/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -2,27 +2,12 @@ all: sbswarm.a -OBJS-y = setup.o cmdline.o rtc_xicor1241.o +OBJS-y = setup.o cmdline.o rtc_xicor1241.o rtc_m41t81.o -OBJS-$(CONFIG_L3DEMO) += procl3switch.o l3procbootstrap.o l3proc.o -OBJS-$(CONFIG_REMOTE_DEBUG) += dbg_io.o - -#XMITTER=1 - -ifdef XMITTER -l3proc.bin: xmitter - ln xmitter l3proc.bin -else -l3proc.bin: l3proc - ln l3proc l3proc.bin -endif - -l3proc.o: l3proc.bin - mips-linux-ld -Tl3proc.lds -bbinary -o l3proc.o l3proc.bin +OBJS-$(CONFIG_KGDB) += dbg_io.o sbswarm.a: $(OBJS-y) $(AR) rcs sbswarm.a $^ - rm -f l3proc.o l3proc.bin include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/sibyte/swarm/dbg_io.c linux-2.4.22/arch/mips/sibyte/swarm/dbg_io.c --- linux-2.4.21/arch/mips/sibyte/swarm/dbg_io.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/sibyte/swarm/dbg_io.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * kgdb debug routines for swarm board. + * kgdb debug routines for SiByte boards. * * Copyright (C) 2001 MontaVista Software Inc. * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net @@ -35,12 +35,10 @@ static int duart_initialized = 0; /* 0: need to be init'ed by kgdb */ /* -------------------- END OF CONFIG --------------------- */ +extern int kgdb_port; - -#define duart_out(reg, val) out64(val, KSEG1 + A_DUART_CHANREG(1,reg)) -#define duart_in(reg) in64(KSEG1 + A_DUART_CHANREG(1,reg)) - -extern void set_async_breakpoint(unsigned int epc); +#define duart_out(reg, val) csr_out32(val, KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) +#define duart_in(reg) csr_in32(KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) void putDebugChar(unsigned char c); unsigned char getDebugChar(void); diff -urN linux-2.4.21/arch/mips/sibyte/swarm/rtc_m41t81.c linux-2.4.22/arch/mips/sibyte/swarm/rtc_m41t81.c --- linux-2.4.21/arch/mips/sibyte/swarm/rtc_m41t81.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/swarm/rtc_m41t81.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + + +/* M41T81 definitions */ + +/* + * Register bits + */ + +#define M41T81REG_SC_ST 0x80 /* stop bit */ +#define M41T81REG_HR_CB 0x40 /* century bit */ +#define M41T81REG_HR_CEB 0x80 /* century enable bit */ +#define M41T81REG_CTL_S 0x20 /* sign bit */ +#define M41T81REG_CTL_FT 0x40 /* frequency test bit */ +#define M41T81REG_CTL_OUT 0x80 /* output level */ +#define M41T81REG_WD_RB0 0x01 /* watchdog resolution bit 0 */ +#define M41T81REG_WD_RB1 0x02 /* watchdog resolution bit 1 */ +#define M41T81REG_WD_BMB0 0x04 /* watchdog multiplier bit 0 */ +#define M41T81REG_WD_BMB1 0x08 /* watchdog multiplier bit 1 */ +#define M41T81REG_WD_BMB2 0x10 /* watchdog multiplier bit 2 */ +#define M41T81REG_WD_BMB3 0x20 /* watchdog multiplier bit 3 */ +#define M41T81REG_WD_BMB4 0x40 /* watchdog multiplier bit 4 */ +#define M41T81REG_AMO_ABE 0x20 /* alarm in "battery back-up mode" enable bit */ +#define M41T81REG_AMO_SQWE 0x40 /* square wave enable */ +#define M41T81REG_AMO_AFE 0x80 /* alarm flag enable flag */ +#define M41T81REG_ADT_RPT5 0x40 /* alarm repeat mode bit 5 */ +#define M41T81REG_ADT_RPT4 0x80 /* alarm repeat mode bit 4 */ +#define M41T81REG_AHR_RPT3 0x80 /* alarm repeat mode bit 3 */ +#define M41T81REG_AHR_HT 0x40 /* halt update bit */ +#define M41T81REG_AMN_RPT2 0x80 /* alarm repeat mode bit 2 */ +#define M41T81REG_ASC_RPT1 0x80 /* alarm repeat mode bit 1 */ +#define M41T81REG_FLG_AF 0x40 /* alarm flag (read only) */ +#define M41T81REG_FLG_WDF 0x80 /* watchdog flag (read only) */ +#define M41T81REG_SQW_RS0 0x10 /* sqw frequency bit 0 */ +#define M41T81REG_SQW_RS1 0x20 /* sqw frequency bit 1 */ +#define M41T81REG_SQW_RS2 0x40 /* sqw frequency bit 2 */ +#define M41T81REG_SQW_RS3 0x80 /* sqw frequency bit 3 */ + + +/* + * Register numbers + */ + +#define M41T81REG_TSC 0x00 /* tenths/hundredths of second */ +#define M41T81REG_SC 0x01 /* seconds */ +#define M41T81REG_MN 0x02 /* minute */ +#define M41T81REG_HR 0x03 /* hour/century */ +#define M41T81REG_DY 0x04 /* day of week */ +#define M41T81REG_DT 0x05 /* date of month */ +#define M41T81REG_MO 0x06 /* month */ +#define M41T81REG_YR 0x07 /* year */ +#define M41T81REG_CTL 0x08 /* control */ +#define M41T81REG_WD 0x09 /* watchdog */ +#define M41T81REG_AMO 0x0A /* alarm: month */ +#define M41T81REG_ADT 0x0B /* alarm: date */ +#define M41T81REG_AHR 0x0C /* alarm: hour */ +#define M41T81REG_AMN 0x0D /* alarm: minute */ +#define M41T81REG_ASC 0x0E /* alarm: second */ +#define M41T81REG_FLG 0x0F /* flags */ +#define M41T81REG_SQW 0x13 /* square wave register */ + +#define M41T81_CCR_ADDRESS 0x68 +#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg)) + +static int m41t81_read(uint8_t addr) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64(addr & 0xff, SMB_CSR(R_SMB_CMD)); + out64((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + return (in64(SMB_CSR(R_SMB_DATA)) & 0xff); +} + +static int m41t81_write(uint8_t addr, int b) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((addr & 0xFF), SMB_CSR(R_SMB_CMD)); + out64((b & 0xff), SMB_CSR(R_SMB_DATA)); + out64(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + /* read the same byte again to make sure it is written */ + out64(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + return 0; +} + +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) + +int m41t81_set_time(unsigned long t) +{ + struct rtc_time tm; + + to_tm(t, &tm); + + /* + * Note the write order matters as it ensures the correctness. + * When we write sec, 10th sec is clear. It is reasonable to + * believe we should finish writing min within a second. + */ + + BIN_TO_BCD(tm.tm_sec); + m41t81_write(M41T81REG_SC, tm.tm_sec); + + BIN_TO_BCD(tm.tm_min); + m41t81_write(M41T81REG_MN, tm.tm_min); + + BIN_TO_BCD(tm.tm_hour); + tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0); + m41t81_write(M41T81REG_HR, tm.tm_hour); + + /* tm_wday starts from 0 to 6 */ + if (tm.tm_wday == 0) tm.tm_wday = 7; + BIN_TO_BCD(tm.tm_wday); + m41t81_write(M41T81REG_DY, tm.tm_wday); + + BIN_TO_BCD(tm.tm_mday); + m41t81_write(M41T81REG_DT, tm.tm_mday); + + /* tm_mon starts from 0, *ick* */ + tm.tm_mon ++; + BIN_TO_BCD(tm.tm_mon); + m41t81_write(M41T81REG_MO, tm.tm_mon); + + /* we don't do century, everything is beyond 2000 */ + tm.tm_year %= 100; + BIN_TO_BCD(tm.tm_year); + m41t81_write(M41T81REG_YR, tm.tm_year); + + return 0; +} + +unsigned long m41t81_get_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + + /* + * min is valid if two reads of sec are the same. + */ + for (;;) { + sec = m41t81_read(M41T81REG_SC); + min = m41t81_read(M41T81REG_MN); + if (sec == m41t81_read(M41T81REG_SC)) break; + } + hour = m41t81_read(M41T81REG_HR) & 0x3f; + day = m41t81_read(M41T81REG_DT); + mon = m41t81_read(M41T81REG_MO); + year = m41t81_read(M41T81REG_YR); + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + + year += 2000; + + return mktime(year, mon, day, hour, min, sec); +} + +int m41t81_probe(void) +{ + unsigned int tmp; + + /* enable chip if it is not enabled yet */ + tmp = m41t81_read(M41T81REG_SC); + m41t81_write(M41T81REG_SC, tmp & 0x7f); + + return (m41t81_read(M41T81REG_SC) != -1); +} diff -urN linux-2.4.21/arch/mips/sibyte/swarm/rtc_xicor1241.c linux-2.4.22/arch/mips/sibyte/swarm/rtc_xicor1241.c --- linux-2.4.21/arch/mips/sibyte/swarm/rtc_xicor1241.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/swarm/rtc_xicor1241.c 2003-08-25 04:44:40.000000000 -0700 @@ -181,15 +181,14 @@ hour = (hour & 0xf) + 0x12; } - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - day = xicor_read(X1241REG_DT); mon = xicor_read(X1241REG_MO); year = xicor_read(X1241REG_YR); y2k = xicor_read(X1241REG_Y2K); + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); BCD_TO_BIN(day); BCD_TO_BIN(mon); BCD_TO_BIN(year); @@ -200,3 +199,7 @@ return mktime(year, mon, day, hour, min, sec); } +int xicor_probe(void) +{ + return (xicor_read(X1241REG_SC) != -1); +} diff -urN linux-2.4.21/arch/mips/sibyte/swarm/setup.c linux-2.4.22/arch/mips/sibyte/swarm/setup.c --- linux-2.4.21/arch/mips/sibyte/swarm/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sibyte/swarm/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -31,40 +31,36 @@ #include #include #include +#include #include #include +#include #include #include #include #include -#include +#include extern struct rtc_ops *rtc_ops; extern struct rtc_ops swarm_rtc_ops; #ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -#ifdef CONFIG_BLK_DEV_IDE_SIBYTE extern struct ide_ops sibyte_ide_ops; #endif -#endif - -#ifdef CONFIG_L3DEMO -extern void *l3info; -#endif -static unsigned char *led_ptr; -#define LED_BASE_ADDR (A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, LEDS_CS))) -#define setled(index, c) led_ptr[(3-((index)&3)) << 3] = (c) +extern void sb1250_setup(void); -const char *get_system_type(void) -{ - return "SiByte Swarm"; -} +extern int xicor_probe(void); +extern int xicor_set_time(unsigned long); +extern unsigned long xicor_get_time(void); +extern int m41t81_probe(void); +extern int m41t81_set_time(unsigned long); +extern unsigned long m41t81_get_time(void); -void __init bus_error_init(void) +const char *get_system_type(void) { + return "SiByte " SIBYTE_BOARD_NAME; } void __init swarm_timer_setup(struct irqaction *irq) @@ -78,9 +74,20 @@ sb1250_time_init(); } -extern int xicor_set_time(unsigned long); -extern unsigned long xicor_get_time(void); -extern void sb1250_setup(void); +int swarm_be_handler(struct pt_regs *regs, int is_fixup) +{ + if (!is_fixup && (regs->cp0_cause & 4)) { + /* Data bus error - print PA */ +#ifdef CONFIG_MIPS64 + printk("DBE physical address: %010lx\n", + __read_64bit_c0_register($26, 1)); +#else + printk("DBE physical address: %010llx\n", + __read_64bit_c0_split($26, 1)); +#endif + } + return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); +} void __init swarm_setup(void) { @@ -90,16 +97,21 @@ panic_timeout = 5; /* For debug. */ - board_timer_setup = swarm_timer_setup; + board_timer_setup = swarm_timer_setup; + board_be_handler = swarm_be_handler; - rtc_get_time = xicor_get_time; - rtc_set_time = xicor_set_time; - -#ifdef CONFIG_L3DEMO - if (l3info != NULL) { - printk("\n"); + if (xicor_probe()) { + printk("swarm setup: Xicor 1241 RTC detected.\n"); + rtc_get_time = xicor_get_time; + rtc_set_time = xicor_set_time; } -#endif + + if (m41t81_probe()) { + printk("swarm setup: M41T81 RTC detected.\n"); + rtc_get_time = m41t81_get_time; + rtc_set_time = m41t81_set_time; + } + printk("This kernel optimized for " #ifdef CONFIG_SIMULATION "simulation" @@ -115,23 +127,8 @@ " CFE\n"); #ifdef CONFIG_BLK_DEV_IDE -#ifdef CONFIG_BLK_DEV_IDE_SIBYTE ide_ops = &sibyte_ide_ops; -#else - ide_ops = &std_ide_ops; #endif -#endif - - /* Set up the LED base address */ -#ifdef __MIPSEL__ - /* Pass1 workaround (bug 1624) */ - if (sb1250_pass == K_SYS_REVISION_PASS1) - led_ptr = (unsigned char *) - ((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(4+(KSEG1|LED_BASE_ADDR))) << S_IO_ADDRBASE))+0x20); - else -#endif - led_ptr = (unsigned char *) - ((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(KSEG1|LED_BASE_ADDR)) << S_IO_ADDRBASE))+0x20); #ifdef CONFIG_VT #ifdef CONFIG_DUMMY_CONSOLE @@ -152,60 +149,25 @@ #endif } +#ifdef LEDS_PHYS + +#ifdef CONFIG_SIBYTE_CARMEL +/* XXXKW need to detect Monterey/LittleSur/etc */ +#undef LEDS_PHYS +#define LEDS_PHYS MLEDS_PHYS +#endif + +#define setled(index, c) \ + ((unsigned char *)(LEDS_PHYS|IO_SPACE_BASE|0x20))[(3-(index))<<3] = (c) void setleds(char *str) { int i; for (i = 0; i < 4; i++) { if (!str[i]) { - for (; i < 4; i++) { - setled(' ', str[i]); - } + setled(i, ' '); } else { setled(i, str[i]); } } } - -#include - -static struct timer_list led_timer; -static unsigned char default_led_msg[] = - "Today: the CSWARM. Tomorrow: the WORLD!!!! "; -static unsigned char *led_msg = default_led_msg; -static unsigned char *led_msg_ptr = default_led_msg; - -void set_led_msg(char *new_msg) -{ - led_msg = new_msg; - led_msg_ptr = new_msg; - setleds(" "); -} - -static void move_leds(unsigned long arg) -{ - int i; - unsigned char *tmp = led_msg_ptr; - for (i = 0; i < 4; i++) { - setled(i, *tmp); - tmp++; - if (!*tmp) { - tmp = led_msg; - } - } - led_msg_ptr++; - if (!*led_msg_ptr) { - led_msg_ptr = led_msg; - } - del_timer(&led_timer); - led_timer.expires = jiffies + (HZ/8); - add_timer(&led_timer); -} - -void hack_leds(void) -{ - init_timer(&led_timer); - led_timer.expires = jiffies + (HZ/8); - led_timer.data = 0; - led_timer.function = move_leds; - add_timer(&led_timer); -} +#endif diff -urN linux-2.4.21/arch/mips/sni/Makefile linux-2.4.22/arch/mips/sni/Makefile --- linux-2.4.21/arch/mips/sni/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/arch/mips/sni/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,16 +6,16 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true all: sni.o int-handler.o O_TARGET := sni.o -obj-y := int-handler.o io.o irq.o pci.o pcimt_scache.o reset.o setup.o +obj-y += int-handler.o io.o irq.o pcimt_scache.o reset.o \ + setup.o + +obj-$(CONFIG_PCI) += pci.o int-handler.o: int-handler.S diff -urN linux-2.4.21/arch/mips/sni/int-handler.S linux-2.4.22/arch/mips/sni/int-handler.S --- linux-2.4.21/arch/mips/sni/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/sni/int-handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -47,7 +47,7 @@ bnez t1, _hwint0 nop - j restore_all # spurious interrupt + j ret_from_irq # spurious interrupt nop ############################################################################## diff -urN linux-2.4.21/arch/mips/sni/irq.c linux-2.4.22/arch/mips/sni/irq.c --- linux-2.4.21/arch/mips/sni/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/sni/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -9,16 +9,17 @@ #include #include #include +#include #include #include +#include #include #include spinlock_t pciasic_lock = SPIN_LOCK_UNLOCKED; extern asmlinkage void sni_rm200_pci_handle_int(void); -extern void do_IRQ(int irq, struct pt_regs *regs); static void enable_pciasic_irq(unsigned int irq); diff -urN linux-2.4.21/arch/mips/sni/pci.c linux-2.4.22/arch/mips/sni/pci.c --- linux-2.4.21/arch/mips/sni/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/sni/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -15,18 +15,6 @@ #include #include -#ifdef CONFIG_PCI - -#define mkaddr(dev, where) \ -do { \ - if ((dev)->bus->number == 0) \ - return -1; \ - *(volatile u32 *)PCIMT_CONFIG_ADDRESS = \ - ((dev->bus->number & 0xff) << 0x10) | \ - ((dev->devfn & 0xff) << 0x08) | \ - (where & 0xfc); \ -} while(0) - #if 0 /* To do: Bring this uptodate ... */ static void pcimt_pcibios_fixup (void) @@ -40,7 +28,7 @@ */ if (dev->devfn == PCI_DEVFN(1, 0)) { /* Evil hack ... */ - set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NO_WA); + set_c0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NO_WA); dev->irq = PCIMT_IRQ_SCSI; continue; } @@ -65,125 +53,12 @@ } #endif -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int pcimt_read_config_byte (struct pci_dev *dev, - int where, unsigned char *val) -{ - u32 res; - - mkaddr(dev, where); - res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; - *val = res; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_read_config_word (struct pci_dev *dev, - int where, unsigned short *val) -{ - u32 res; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; - *val = res; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_read_config_dword (struct pci_dev *dev, - int where, unsigned int *val) -{ - u32 res; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = le32_to_cpu(res); - *val = res; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_write_config_byte (struct pci_dev *dev, - int where, unsigned char val) -{ - mkaddr(dev, where); - *(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_write_config_word (struct pci_dev *dev, - int where, unsigned short val) -{ - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - *(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val); - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_write_config_dword (struct pci_dev *dev, - int where, unsigned int val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - *(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops sni_pci_ops = { - pcimt_read_config_byte, - pcimt_read_config_word, - pcimt_read_config_dword, - pcimt_write_config_byte, - pcimt_write_config_word, - pcimt_write_config_dword -}; - void __init pcibios_fixup_bus(struct pci_bus *b) { } -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4*resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - new |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} +extern struct pci_ops sni_pci_ops; void __init pcibios_init(void) { @@ -192,33 +67,11 @@ pci_scan_bus(0, ops, NULL); } -int __init pcibios_enable_device(struct pci_dev *dev) -{ - /* Not needed, since we enable all devices at startup. */ - return 0; -} - -void __init -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ -} - unsigned __init int pcibios_assign_all_busses(void) { return 0; } -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - struct pci_fixup pcibios_fixups[] = { { 0 } }; - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/mips/sni/setup.c linux-2.4.22/arch/mips/sni/setup.c --- linux-2.4.21/arch/mips/sni/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/sni/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -31,6 +31,7 @@ #include #include #include +#include extern void sni_machine_restart(char *command); extern void sni_machine_halt(void); @@ -49,6 +50,7 @@ setup_irq(0, irq); } + extern unsigned char sni_map_isa_cache; /* diff -urN linux-2.4.21/arch/mips/tools/offset.c linux-2.4.22/arch/mips/tools/offset.c --- linux-2.4.21/arch/mips/tools/offset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/tools/offset.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,6 +8,7 @@ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. */ +#include #include #include #include @@ -151,12 +152,19 @@ offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); offset("#define SC_PC ", struct sigcontext, sc_pc); offset("#define SC_STATUS ", struct sigcontext, sc_status); - offset("#define SC_OWNEDFP ", struct sigcontext, sc_ownedfp); offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); offset("#define SC_CAUSE ", struct sigcontext, sc_cause); offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); linefeed; + +#ifdef CONFIG_MIPS64 + text("/* Linux 32-bit sigcontext offsets. */"); + offset("#define SC32_FPREGS ", struct sigcontext32, sc_fpregs); + offset("#define SC32_FPC_CSR ", struct sigcontext32, sc_fpc_csr); + offset("#define SC32_FPC_EIR ", struct sigcontext32, sc_fpc_eir); + linefeed; +#endif } void output_signal_defined(void) diff -urN linux-2.4.21/arch/mips/tx4927/common/Makefile linux-2.4.22/arch/mips/tx4927/common/Makefile --- linux-2.4.21/arch/mips/tx4927/common/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/common/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,20 @@ +# +# Makefile for common code for Toshiba TX4927 based systems +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET:= tx4927.o + +obj-y := tx4927_prom.o +obj-y += tx4927_setup.o +obj-y += tx4927_irq.o +obj-y += tx4927_irq_handler.o + +obj-$(CONFIG_KGDB) += tx4927_dbgio.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/tx4927/common/tx4927_dbgio.c linux-2.4.22/arch/mips/tx4927/common/tx4927_dbgio.c --- linux-2.4.21/arch/mips/tx4927/common/tx4927_dbgio.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/common/tx4927_dbgio.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,47 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_dbgio.c + * + * kgdb interface for gdb + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +u8 getDebugChar(void) +{ + extern u8 txx9_sio_kdbg_rd(void); + return (txx9_sio_kdbg_rd()); +} + + +int putDebugChar(u8 byte) +{ + extern int txx9_sio_kdbg_wr( u8 ch ); + return (txx9_sio_kdbg_wr(byte)); +} diff -urN linux-2.4.21/arch/mips/tx4927/common/tx4927_irq.c linux-2.4.22/arch/mips/tx4927/common/tx4927_irq.c --- linux-2.4.21/arch/mips/tx4927/common/tx4927_irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/common/tx4927_irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,708 @@ +/* + * Common tx4927 irq handler + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * DEBUG + */ +#define TX4927_IRQ_CHECK_CP0 +#define TX4927_IRQ_CHECK_PIC + +#undef TX4927_IRQ_DEBUG + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_NONE 0x00000000 + +#define TX4927_IRQ_INFO ( 1 << 0 ) +#define TX4927_IRQ_WARN ( 1 << 1 ) +#define TX4927_IRQ_EROR ( 1 << 2 ) + +#define TX4927_IRQ_INIT ( 1 << 5 ) +#define TX4927_IRQ_NEST1 ( 1 << 6 ) +#define TX4927_IRQ_NEST2 ( 1 << 7 ) +#define TX4927_IRQ_NEST3 ( 1 << 8 ) +#define TX4927_IRQ_NEST4 ( 1 << 9 ) + +#define TX4927_IRQ_CP0_INIT ( 1 << 10 ) +#define TX4927_IRQ_CP0_STARTUP ( 1 << 11 ) +#define TX4927_IRQ_CP0_SHUTDOWN ( 1 << 12 ) +#define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) +#define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) +#define TX4927_IRQ_CP0_MASK ( 1 << 15 ) +#define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) + +#define TX4927_IRQ_PIC_INIT ( 1 << 20 ) +#define TX4927_IRQ_PIC_STARTUP ( 1 << 21 ) +#define TX4927_IRQ_PIC_SHUTDOWN ( 1 << 22 ) +#define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) +#define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) +#define TX4927_IRQ_PIC_MASK ( 1 << 25 ) +#define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) + +#define TX4927_IRQ_ALL 0xffffffff +#endif + +#ifdef TX4927_IRQ_DEBUG +static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE + | TX4927_IRQ_INFO + | TX4927_IRQ_WARN | TX4927_IRQ_EROR +// | TX4927_IRQ_CP0_INIT +// | TX4927_IRQ_CP0_STARTUP +// | TX4927_IRQ_CP0_SHUTDOWN +// | TX4927_IRQ_CP0_ENABLE +// | TX4927_IRQ_CP0_DISABLE +// | TX4927_IRQ_CP0_MASK +// | TX4927_IRQ_CP0_ENDIRQ +// | TX4927_IRQ_PIC_INIT +// | TX4927_IRQ_PIC_STARTUP +// | TX4927_IRQ_PIC_SHUTDOWN +// | TX4927_IRQ_PIC_ENABLE +// | TX4927_IRQ_PIC_DISABLE +// | TX4927_IRQ_PIC_MASK +// | TX4927_IRQ_PIC_ENDIRQ +// | TX4927_IRQ_INIT +// | TX4927_IRQ_NEST1 +// | TX4927_IRQ_NEST2 +// | TX4927_IRQ_NEST3 +// | TX4927_IRQ_NEST4 + ); +#endif + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_DPRINTK(flag,str...) \ + if ( (tx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TX4927_IRQ_DPRINTK(flag,str...) +#endif + +/* + * Forwad definitions for all pic's + */ + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq); +static void tx4927_irq_cp0_shutdown(unsigned int irq); +static void tx4927_irq_cp0_enable(unsigned int irq); +static void tx4927_irq_cp0_disable(unsigned int irq); +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq); +static void tx4927_irq_cp0_end(unsigned int irq); + +static unsigned int tx4927_irq_pic_startup(unsigned int irq); +static void tx4927_irq_pic_shutdown(unsigned int irq); +static void tx4927_irq_pic_enable(unsigned int irq); +static void tx4927_irq_pic_disable(unsigned int irq); +static void tx4927_irq_pic_mask_and_ack(unsigned int irq); +static void tx4927_irq_pic_end(unsigned int irq); + +/* + * Kernel structs for all pic's + */ + +static spinlock_t tx4927_cp0_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t tx4927_pic_lock = SPIN_LOCK_UNLOCKED; + +#define TX4927_CP0_NAME "TX4927-CP0" +static struct hw_interrupt_type tx4927_irq_cp0_type = { + typename: TX4927_CP0_NAME, + startup: tx4927_irq_cp0_startup, + shutdown: tx4927_irq_cp0_shutdown, + enable: tx4927_irq_cp0_enable, + disable: tx4927_irq_cp0_disable, + ack: tx4927_irq_cp0_mask_and_ack, + end: tx4927_irq_cp0_end, + set_affinity: NULL +}; + +#define TX4927_PIC_NAME "TX4927-PIC" +static struct hw_interrupt_type tx4927_irq_pic_type = { + typename: TX4927_PIC_NAME, + startup: tx4927_irq_pic_startup, + shutdown: tx4927_irq_pic_shutdown, + enable: tx4927_irq_pic_enable, + disable: tx4927_irq_pic_disable, + ack: tx4927_irq_pic_mask_and_ack, + end: tx4927_irq_pic_end, + set_affinity: NULL +}; + +#define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +static struct irqaction tx4927_irq_pic_action = +TX4927_PIC_ACTION(TX4927_PIC_NAME); + +#define CCP0_STATUS 12 +#define CCP0_CAUSE 13 + +/* + * Functions for cp0 + */ + +#define tx4927_irq_cp0_mask(irq) ( 1 << ( irq-TX4927_IRQ_CP0_BEG+8 ) ) + +static void tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, + unsigned set_bits) +{ + unsigned long val = 0; + + switch (cp0_reg) { + case CCP0_STATUS: + val = read_c0_status(); + break; + + case CCP0_CAUSE: + val = read_c0_cause(); + break; + + } + + val &= (~clr_bits); + val |= (set_bits); + + switch (cp0_reg) { + case CCP0_STATUS:{ + write_c0_status(val); + break; + } + case CCP0_CAUSE:{ + write_c0_cause(val); + break; + } + } + + return; +} + +static void __init tx4927_irq_cp0_init(void) +{ + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n", + TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); + + for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &tx4927_irq_cp0_type; + } + + return; +} + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_enable(irq); + + return (0); +} + +static void tx4927_irq_cp0_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_cp0_enable(irq); + } + + return; +} + +/* + * Functions for pic + */ + +u32 tx4927_irq_pic_addr(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_IRQ_PIC_BEG; + switch (irq) { + case 17: + case 16: + case 1: + case 0: + return (0xff1ff610); + + case 19: + case 18: + case 3: + case 2: + return (0xff1ff614); + + case 21: + case 20: + case 5: + case 4: + return (0xff1ff618); + + case 23: + case 22: + case 7: + case 6: + return (0xff1ff61c); + + case 25: + case 24: + case 9: + case 8: + return (0xff1ff620); + + case 27: + case 26: + case 11: + case 10: + return (0xff1ff624); + + case 29: + case 28: + case 13: + case 12: + return (0xff1ff628); + + case 31: + case 30: + case 15: + case 14: + return (0xff1ff62c); + + } + return (0); +} + +u32 tx4927_irq_pic_mask(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_IRQ_PIC_BEG; + switch (irq) { + case 31: + case 29: + case 27: + case 25: + case 23: + case 21: + case 19: + case 17:{ + return (0x07000000); + } + case 30: + case 28: + case 26: + case 24: + case 22: + case 20: + case 18: + case 16:{ + return (0x00070000); + } + case 15: + case 13: + case 11: + case 9: + case 7: + case 5: + case 3: + case 1:{ + return (0x00000700); + } + case 14: + case 12: + case 10: + case 8: + case 6: + case 4: + case 2: + case 0:{ + return (0x00000007); + } + } + return (0x00000000); +} + +static void tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, + unsigned set_bits) +{ + unsigned long val = 0; + + val = TX4927_RD(pic_reg); + val &= (~clr_bits); + val |= (set_bits); + TX4927_WR(pic_reg, val); + + return; +} + +static void __init tx4927_irq_pic_init(void) +{ + unsigned long flags; + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n", + TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); + + for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &tx4927_irq_pic_type; + } + + setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + TX4927_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ + TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1); /* irq enable */ + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static unsigned int tx4927_irq_pic_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_enable(irq); + + return (0); +} + +static void tx4927_irq_pic_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, + tx4927_irq_pic_mask(irq)); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), + tx4927_irq_pic_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_pic_enable(irq); + } + + return; +} + +/* + * Main init functions + */ +void __init tx4927_irq_init(void) +{ + extern asmlinkage void tx4927_irq_handler(void); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); + tx4927_irq_cp0_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); + tx4927_irq_pic_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, + "=Calling set_except_vector(tx4927_irq_handler)\n"); + set_except_vector(0, tx4927_irq_handler); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); + + return; +} + +int tx4927_irq_nested(void) +{ + int sw_irq = 0; + u32 level2; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "-\n"); + + level2 = TX4927_RD(0xff1ff6a0); + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=level2a=0x%x\n", level2); + + if ((level2 & 0x10000) == 0) { + level2 &= 0x1f; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=level2b=0x%x\n", level2); + + sw_irq = TX4927_IRQ_PIC_BEG + level2; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=sw_irq=%d\n", sw_irq); + + if (sw_irq == 27) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq-%d\n", + sw_irq); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern int toshiba_rbtx4927_irq_nested(int sw_irq); + + sw_irq = toshiba_rbtx4927_irq_nested(sw_irq); + } +#endif + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq+%d\n", + sw_irq); + } + } + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=sw_irq=%d\n", sw_irq); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "+\n"); + + return (sw_irq); +} diff -urN linux-2.4.21/arch/mips/tx4927/common/tx4927_irq_handler.S linux-2.4.22/arch/mips/tx4927/common/tx4927_irq_handler.S --- linux-2.4.21/arch/mips/tx4927/common/tx4927_irq_handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/common/tx4927_irq_handler.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,104 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_irq_handler.S + * + * Primary interrupt handler for tx4927 based systems + * + * Author: MontaVista Software, Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include + + .align 5 + NESTED(tx4927_irq_handler, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 t0, CP0_CAUSE + mfc0 t1, CP0_STATUS + and t0, t1 + + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_ip7 + + /* IP6..IP3 multiplexed -- do not use */ + + andi t1, t0, STATUSF_IP2 /* tx4927 pic */ + bnez t1, ll_ip2 + + andi t1, t0, STATUSF_IP0 /* user line 0 */ + bnez t1, ll_ip0 + + andi t1, t0, STATUSF_IP1 /* user line 1 */ + bnez t1, ll_ip1 + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(tx4927_irq_handler) + + .align 5 + + +ll_ip7: + li a0, TX4927_IRQ_CPU_TIMER + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip2: + jal tx4927_irq_nested + nop + beqz v0, goto_spurious_interrupt + nop + move a0, v0 + move a1, sp + jal do_IRQ + j ret_from_irq + +goto_spurious_interrupt: + j spurious_interrupt + nop + +ll_ip1: + li a0, TX4927_IRQ_USER1 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip0: + li a0, TX4927_IRQ_USER0 + move a1, sp + jal do_IRQ + j ret_from_irq diff -urN linux-2.4.21/arch/mips/tx4927/common/tx4927_prom.c linux-2.4.22/arch/mips/tx4927/common/tx4927_prom.c --- linux-2.4.21/arch/mips/tx4927/common/tx4927_prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/common/tx4927_prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,146 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_prom.c + * + * common tx4927 memory interface + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include + +static unsigned int __init tx4927_process_sdccr(u64 * addr) +{ + u64 val; + unsigned int sdccr_ce; + unsigned int sdccr_bs; + unsigned int sdccr_rs; + unsigned int sdccr_cs; + unsigned int sdccr_mw; + unsigned int bs = 0; + unsigned int rs = 0; + unsigned int cs = 0; + unsigned int mw = 0; + unsigned int msize = 0; + + val = (*((vu64 *) (addr))); + + /* MVMCP -- need #defs for these bits masks */ + sdccr_ce = ((val & (1 << 10)) >> 10); + sdccr_bs = ((val & (1 << 8)) >> 8); + sdccr_rs = ((val & (3 << 5)) >> 5); + sdccr_cs = ((val & (3 << 2)) >> 2); + sdccr_mw = ((val & (1 << 0)) >> 0); + + if (sdccr_ce) { + switch (sdccr_bs) { + case 0:{ + bs = 2; + break; + } + case 1:{ + bs = 4; + break; + } + } + switch (sdccr_rs) { + case 0:{ + rs = 2048; + break; + } + case 1:{ + rs = 4096; + break; + } + case 2:{ + rs = 8192; + break; + } + case 3:{ + rs = 0; + break; + } + } + switch (sdccr_cs) { + case 0:{ + cs = 256; + break; + } + case 1:{ + cs = 512; + break; + } + case 2:{ + cs = 1024; + break; + } + case 3:{ + cs = 2048; + break; + } + } + switch (sdccr_mw) { + case 0:{ + mw = 8; + break; + } /* 8 bytes = 64 bits */ + case 1:{ + mw = 4; + break; + } /* 4 bytes = 32 bits */ + } + } + + /* bytes per chip MB per chip num chips */ + msize = (((rs * cs * mw) / (1024 * 1024)) * bs); + + return (msize); +} + + +unsigned int __init tx4927_get_mem_size(void) +{ + unsigned int c0; + unsigned int c1; + unsigned int c2; + unsigned int c3; + unsigned int total; + + /* MVMCP -- need #defs for these registers */ + c0 = tx4927_process_sdccr((u64 *) 0xff1f8000); + c1 = tx4927_process_sdccr((u64 *) 0xff1f8008); + c2 = tx4927_process_sdccr((u64 *) 0xff1f8010); + c3 = tx4927_process_sdccr((u64 *) 0xff1f8018); + total = c0 + c1 + c2 + c3; + + return (total); +} diff -urN linux-2.4.21/arch/mips/tx4927/common/tx4927_setup.c linux-2.4.22/arch/mips/tx4927/common/tx4927_setup.c --- linux-2.4.21/arch/mips/tx4927/common/tx4927_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/common/tx4927_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,251 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_setup.c + * + * common tx4927 setup stuff + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#undef DEBUG + +void __init tx4927_setup(void); +void __init tx4927_time_init(void); +void __init tx4927_timer_setup(struct irqaction *irq); +void dump_cp0(char *key); + + +void (*__wbflush) (void); + +static void tx4927_write_buffer_flush(void) +{ + __asm__ __volatile__ + ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t"); +} + + +void __init tx4927_setup(void) +{ + board_time_init = tx4927_time_init; + board_timer_setup = tx4927_timer_setup; + __wbflush = tx4927_write_buffer_flush; + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_setup(void); + toshiba_rbtx4927_setup(); + } +#endif + + return; +} + + +void __init tx4927_time_init(void) +{ + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_time_init(void); + toshiba_rbtx4927_time_init(); + } +#endif + +#ifdef CONFIG_KGDB + { + printk("Calling breakpoint() -- start remote kgdb\n"); + set_debug_traps(); + breakpoint(); + printk("Calling breakpoint() -- done\n"); + } +#endif + + return; +} + + +void __init tx4927_timer_setup(struct irqaction *irq) +{ + u32 count; + u32 c1; + u32 c2; + + setup_irq(TX4927_IRQ_CPU_TIMER, irq); + + /* to generate the first timer interrupt */ + c1 = read_c0_count(); + count = c1 + (mips_counter_frequency / HZ); + write_c0_compare(count); + c2 = read_c0_count(); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_timer_setup(struct irqaction + *irq); + toshiba_rbtx4927_timer_setup(irq); + } +#endif + + return; +} + + +#ifdef DEBUG +void print_cp0(char *key, int num, char *name, u32 val) +{ + printk("%s cp0:%02d:%s=0x%08x\n", key, num, name, val); + return; +} + +indent: Standard input:25: Error:Unexpected end of file + +void +dump_cp0(char *key) +{ + if (key == NULL) + key = ""; + + print_cp0(key, 0, "INDEX ", read_c0_index()); + print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0()); + print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1()); + print_cp0(key, 4, "CONTEXT ", read_c0_context()); + print_cp0(key, 5, "PAGEMASK", read_c0_pagemask()); + print_cp0(key, 6, "WIRED ", read_c0_wired()); + //print_cp0(key, 8, "BADVADDR", read_c0_badvaddr()); + print_cp0(key, 9, "COUNT ", read_c0_count()); + print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi()); + print_cp0(key, 11, "COMPARE ", read_c0_compare()); + print_cp0(key, 12, "STATUS ", read_c0_status()); + print_cp0(key, 13, "CAUSE ", read_c0_cause() & 0xffff87ff); + print_cp0(key, 16, "CONFIG ", read_c0_config()); + return; +} + +void print_pic(char *key, u32 reg, char *name) +{ + printk("%s pic:0x%08x:%s=0x%08x\n", key, reg, name, + TX4927_RD(reg)); + return; +} + + +void dump_pic(char *key) +{ + if (key == NULL) + key = ""; + + print_pic(key, 0xff1ff600, "IRDEN "); + print_pic(key, 0xff1ff604, "IRDM0 "); + print_pic(key, 0xff1ff608, "IRDM1 "); + + print_pic(key, 0xff1ff610, "IRLVL0 "); + print_pic(key, 0xff1ff614, "IRLVL1 "); + print_pic(key, 0xff1ff618, "IRLVL2 "); + print_pic(key, 0xff1ff61c, "IRLVL3 "); + print_pic(key, 0xff1ff620, "IRLVL4 "); + print_pic(key, 0xff1ff624, "IRLVL5 "); + print_pic(key, 0xff1ff628, "IRLVL6 "); + print_pic(key, 0xff1ff62c, "IRLVL7 "); + + print_pic(key, 0xff1ff640, "IRMSK "); + print_pic(key, 0xff1ff660, "IREDC "); + print_pic(key, 0xff1ff680, "IRPND "); + print_pic(key, 0xff1ff6a0, "IRCS "); + + print_pic(key, 0xff1ff514, "IRFLAG1 "); /* don't read IRLAG0 -- it hangs system */ + + print_pic(key, 0xff1ff518, "IRPOL "); + print_pic(key, 0xff1ff51c, "IRRCNT "); + print_pic(key, 0xff1ff520, "IRMASKINT"); + print_pic(key, 0xff1ff524, "IRMASKEXT"); + + return; +} + + +void print_addr(char *hdr, char *key, u32 addr) +{ + printk("%s %s:0x%08x=0x%08x\n", hdr, key, addr, TX4927_RD(addr)); + return; +} + + +void dump_180(char *key) +{ + u32 i; + + for (i = 0x80000180; i < 0x80000180 + 0x80; i += 4) { + print_addr("180", key, i); + } + return; +} + + +void dump_eh0(char *key) +{ + int i; + extern unsigned long exception_handlers[]; + + for (i = (int) exception_handlers; + i < (int) (exception_handlers + 20); i += 4) { + print_addr("eh0", key, i); + } + + return; +} + +void pk0(void) +{ + volatile u32 val; + + __asm__ __volatile__("ori %0, $26, 0":"=r"(val) + ); + printk("k0=[0x%08x]\n", val); +} +#endif diff -urN linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/Makefile linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/Makefile --- linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,20 @@ +# +# Makefile for Toshbia's RBTX4927 board +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET:= toshiba_rbtx4927.o + +obj-y += toshiba_rbtx4927_prom.o +obj-y += toshiba_rbtx4927_setup.o +obj-y += toshiba_rbtx4927_irq.o + +obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_fixup.o +obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_ops.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c --- linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,796 @@ +/* + * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c + * + * Toshiba RBTX4927 specific interrupt handlers + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + */ + + +/* +IRQ Device +00 RBTX4927-ISA/00 +01 RBTX4927-ISA/01 PS2/Keyboard +02 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15) +03 RBTX4927-ISA/03 +04 RBTX4927-ISA/04 +05 RBTX4927-ISA/05 +06 RBTX4927-ISA/06 +07 RBTX4927-ISA/07 +08 RBTX4927-ISA/08 +09 RBTX4927-ISA/09 +10 RBTX4927-ISA/10 +11 RBTX4927-ISA/11 +12 RBTX4927-ISA/12 PS2/Mouse (not supported at this time) +13 RBTX4927-ISA/13 +14 RBTX4927-ISA/14 IDE +15 RBTX4927-ISA/15 + +16 TX4927-CP0/00 Software 0 +17 TX4927-CP0/01 Software 1 +18 TX4927-CP0/02 Cascade TX4927-CP0 +19 TX4927-CP0/03 Multiplexed -- do not use +20 TX4927-CP0/04 Multiplexed -- do not use +21 TX4927-CP0/05 Multiplexed -- do not use +22 TX4927-CP0/06 Multiplexed -- do not use +23 TX4927-CP0/07 CPU TIMER + +24 TX4927-PIC/00 +25 TX4927-PIC/01 +26 TX4927-PIC/02 +27 TX4927-PIC/03 Cascade RBTX4927-IOC +28 TX4927-PIC/04 +29 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet +30 TX4927-PIC/06 +31 TX4927-PIC/07 +32 TX4927-PIC/08 TX4927 SerialIO Channel 0 +33 TX4927-PIC/09 TX4927 SerialIO Channel 1 +34 TX4927-PIC/10 +35 TX4927-PIC/11 +36 TX4927-PIC/12 +37 TX4927-PIC/13 +38 TX4927-PIC/14 +39 TX4927-PIC/15 +40 TX4927-PIC/16 TX4927 PCI PCI-C +41 TX4927-PIC/17 +42 TX4927-PIC/18 +43 TX4927-PIC/19 +44 TX4927-PIC/20 +45 TX4927-PIC/21 +46 TX4927-PIC/22 TX4927 PCI PCI-ERR +47 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used) +48 TX4927-PIC/24 +49 TX4927-PIC/25 +50 TX4927-PIC/26 +51 TX4927-PIC/27 +52 TX4927-PIC/28 +53 TX4927-PIC/29 +54 TX4927-PIC/30 +55 TX4927-PIC/31 + +56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4] +57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5] +58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported] +59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6] +60 RBTX4927-IOC/04 +61 RBTX4927-IOC/05 +62 RBTX4927-IOC/06 +63 RBTX4927-IOC/07 + +NOTES: +SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58 +SouthBridge/ISA/pin=0 no pci irq used by this device +SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14 +SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59 +SouthBridge/PMC/pin=0 no pci irq used by this device +SuperIO/PS2/Keyboard, using INTR via ISA IRQ1 +SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported) +JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_RTC_DS1742 +#include +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include +#endif +#include + + +#undef TOSHIBA_RBTX4927_IRQ_DEBUG + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_IRQ_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_IRQ_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_IRQ_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_STARTUP ( 1 << 11 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN ( 1 << 12 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_MASK ( 1 << 15 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) + +#define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_STARTUP ( 1 << 21 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN ( 1 << 22 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE ( 1 << 24 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_MASK ( 1 << 25 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ ( 1 << 26 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +static const u32 toshiba_rbtx4927_irq_debug_flag = + (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO | + TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR +// | TOSHIBA_RBTX4927_IRQ_IOC_INIT +// | TOSHIBA_RBTX4927_IRQ_IOC_STARTUP +// | TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_MASK +// | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ +// | TOSHIBA_RBTX4927_IRQ_ISA_INIT +// | TOSHIBA_RBTX4927_IRQ_ISA_STARTUP +// | TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_MASK +// | TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ + ); +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) +#endif + + + + +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 + +#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */ +#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */ + + +#define TOSHIBA_RBTX4927_IRQ_ISA_BEG MI8259_IRQ_ISA_BEG +#define TOSHIBA_RBTX4927_IRQ_ISA_END MI8259_IRQ_ISA_END +#define TOSHIBA_RBTX4927_IRQ_ISA_MID ((TOSHIBA_RBTX4927_IRQ_ISA_BEG+TOSHIBA_RBTX4927_IRQ_ISA_END+1)/2) + + +#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA (TOSHIBA_RBTX4927_IRQ_ISA_BEG+2) + +extern int tx4927_using_backplane; + +#ifdef CONFIG_TOSHIBA_FPCIB0 +extern void enable_8259A_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void mask_and_ack_8259A(unsigned int irq); +#endif + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq); +#endif + +static spinlock_t toshiba_rbtx4927_ioc_lock = SPIN_LOCK_UNLOCKED; + + +#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" +static struct hw_interrupt_type toshiba_rbtx4927_irq_ioc_type = { + typename:TOSHIBA_RBTX4927_IOC_NAME, + startup:toshiba_rbtx4927_irq_ioc_startup, + shutdown:toshiba_rbtx4927_irq_ioc_shutdown, + enable:toshiba_rbtx4927_irq_ioc_enable, + disable:toshiba_rbtx4927_irq_ioc_disable, + ack:toshiba_rbtx4927_irq_ioc_mask_and_ack, + end:toshiba_rbtx4927_irq_ioc_end, + set_affinity:NULL +}; +#define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 +#define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +#define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA" +static struct hw_interrupt_type toshiba_rbtx4927_irq_isa_type = { + typename:TOSHIBA_RBTX4927_ISA_NAME, + startup:toshiba_rbtx4927_irq_isa_startup, + shutdown:toshiba_rbtx4927_irq_isa_shutdown, + enable:toshiba_rbtx4927_irq_isa_enable, + disable:toshiba_rbtx4927_irq_isa_disable, + ack:toshiba_rbtx4927_irq_isa_mask_and_ack, + end:toshiba_rbtx4927_irq_isa_end, + set_affinity:NULL +}; +#endif + + +u32 bit2num(u32 num) +{ + u32 i; + + for (i = 0; i < (sizeof(num) * 8); i++) { + if (num & (1 << i)) { + return (i); + } + } + return (0); +} + +int toshiba_rbtx4927_irq_nested(int sw_irq) +{ + u32 level3; + + level3 = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + if (level3) { + sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + bit2num(level3); + if (sw_irq != TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC) { + goto RETURN; + } + } +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + u32 level4; + u32 level5; + + if (tx4927_using_backplane) { + outb(0x0A, 0x20); + level4 = inb(0x20) & 0xff; + if (level4) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_BEG + + bit2num(level4); + if (sw_irq != + TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA) { + goto RETURN; + } + } + + outb(0x0A, 0xA0); + level5 = inb(0xA0) & 0xff; + if (level5) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_MID + + bit2num(level5); + goto RETURN; + } + } + } +#endif + + RETURN: + return (sw_irq); +} + +//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, 0, s, NULL, NULL } +static struct irqaction toshiba_rbtx4927_irq_ioc_action = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME); +#ifdef CONFIG_TOSHIBA_FPCIB0 +static struct irqaction toshiba_rbtx4927_irq_isa_master = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/M"); +static struct irqaction toshiba_rbtx4927_irq_isa_slave = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/S"); +#endif + + +/**********************************************************************************/ +/* Functions for ioc */ +/**********************************************************************************/ + + +static void __init toshiba_rbtx4927_irq_ioc_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_IOC_BEG, + TOSHIBA_RBTX4927_IRQ_IOC_END); + + for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; + i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 3; + irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, + &toshiba_rbtx4927_irq_ioc_action); + + return; +} + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_enable(irq); + + return (0); +} + + +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_ioc_enable(irq); + } + + return; +} + + +/**********************************************************************************/ +/* Functions for isa */ +/**********************************************************************************/ + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void __init toshiba_rbtx4927_irq_isa_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_ISA_BEG, + TOSHIBA_RBTX4927_IRQ_ISA_END); + + for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG; + i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = + ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); + irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, + &toshiba_rbtx4927_irq_isa_master); + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA, + &toshiba_rbtx4927_irq_isa_slave); + + /* make sure we are looking at IRR (not ISR) */ + outb(0x0A, 0x20); + outb(0x0A, 0xA0); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_enable(irq); + + return (0); +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_disable(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + enable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + disable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + mask_and_ack_8259A(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_isa_enable(irq); + } + + return; +} +#endif + + +void __init init_IRQ(void) +{ + extern void tx4927_irq_init(void); + + cli(); + + tx4927_irq_init(); + toshiba_rbtx4927_irq_ioc_init(); +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + toshiba_rbtx4927_irq_isa_init(); + } + } +#endif + +#ifdef CONFIG_PCI + { + extern void toshiba_rbtx4927_pci_irq_init(void); + toshiba_rbtx4927_pci_irq_init(); + } +#endif + + wbflush(); + + return; +} + +void toshiba_rbtx4927_irq_dump(char *key) +{ +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG + { + u32 i, j = 0; + for (i = 0; i < NR_IRQS; i++) { + if (strcmp(irq_desc[i].handler->typename, "none") + == 0) + continue; + + if ((i >= 1) + && (irq_desc[i - 1].handler->typename == + irq_desc[i].handler->typename)) { + j++; + } else { + j = 0; + } + TOSHIBA_RBTX4927_IRQ_DPRINTK + (TOSHIBA_RBTX4927_IRQ_INFO, + "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", + key, i, i, irq_desc[i].status, + (u32) irq_desc[i].handler, + (u32) irq_desc[i].action, + (u32) (irq_desc[i].action ? irq_desc[i]. + action->handler : 0), + irq_desc[i].depth, + irq_desc[i].handler->typename, j); + } + } +#endif + return; +} + +void toshiba_rbtx4927_irq_dump_pics(char *s) +{ + u32 level0_m; + u32 level0_s; + u32 level1_m; + u32 level1_s; + u32 level2; + u32 level2_p; + u32 level2_s; + u32 level3_m; + u32 level3_s; + u32 level4_m; + u32 level4_s; + u32 level5_m; + u32 level5_s; + + if (s == NULL) + s = "null"; + + level0_m = (read_c0_status() & 0x0000ff00) >> 8; + level0_s = (read_c0_cause() & 0x0000ff00) >> 8; + + level1_m = level0_m; + level1_s = level0_s & 0x87; + + level2 = TX4927_RD(0xff1ff6a0); + level2_p = (((level2 & 0x10000)) ? 0 : 1); + level2_s = (((level2 & 0x1f) == 0x1f) ? 0 : (level2 & 0x1f)); + + level3_m = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_ENAB) & 0x1f; + level3_s = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + + level4_m = inb(0x21); + outb(0x0A, 0x20); + level4_s = inb(0x20); + + level5_m = inb(0xa1); + outb(0x0A, 0xa0); + level5_s = inb(0xa0); + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "dump_raw_pic() "); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level0_m, + level0_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level1_m, + level1_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "pic:e=0x%02x/s=0x%02x ", level2_p, + level2_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "ioc:m=0x%02x/s=0x%02x ", level3_m, + level3_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbm:m=0x%02x/s=0x%02x ", level4_m, + level4_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbs:m=0x%02x/s=0x%02x ", level5_m, + level5_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n", + s); + + return; +} diff -urN linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c --- linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,329 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Board specific pci fixups for the Toshiba rbtx4927 + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* will need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ + /* nothing to do here */ +} + +/* look up table for backplane pci irq for slots 17-20 by pin # */ +static unsigned char backplane_pci_irq[4][4] = { + /* PJ6 SLOT: 17, PIN: 1 */ {TX4927_IRQ_IOC_PCIA, + /* PJ6 SLOT: 17, PIN: 2 */ + TX4927_IRQ_IOC_PCIB, + /* PJ6 SLOT: 17, PIN: 3 */ + TX4927_IRQ_IOC_PCIC, + /* PJ6 SLOT: 17, PIN: 4 */ + TX4927_IRQ_IOC_PCID}, + /* SB SLOT: 18, PIN: 1 */ {TX4927_IRQ_IOC_PCIB, + /* SB SLOT: 18, PIN: 2 */ + TX4927_IRQ_IOC_PCIC, + /* SB SLOT: 18, PIN: 3 */ + TX4927_IRQ_IOC_PCID, + /* SB SLOT: 18, PIN: 4 */ + TX4927_IRQ_IOC_PCIA}, + /* PJ5 SLOT: 19, PIN: 1 */ {TX4927_IRQ_IOC_PCIC, + /* PJ5 SLOT: 19, PIN: 2 */ + TX4927_IRQ_IOC_PCID, + /* PJ5 SLOT: 19, PIN: 3 */ + TX4927_IRQ_IOC_PCIA, + /* PJ5 SLOT: 19, PIN: 4 */ + TX4927_IRQ_IOC_PCIB}, + /* PJ4 SLOT: 20, PIN: 1 */ {TX4927_IRQ_IOC_PCID, + /* PJ4 SLOT: 20, PIN: 2 */ + TX4927_IRQ_IOC_PCIA, + /* PJ4 SLOT: 20, PIN: 3 */ + TX4927_IRQ_IOC_PCIB, + /* PJ4 SLOT: 20, PIN: 4 */ + TX4927_IRQ_IOC_PCIC} +}; + +int pci_get_irq(struct pci_dev *dev, int pin) +{ + unsigned char irq = pin; + + DBG("pci_get_irq: pin is %d\n", pin); + /* IRQ rotation */ + irq--; /* 0-3 */ + if (dev->bus->parent == NULL && + PCI_SLOT(dev->devfn) == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { + printk("Onboard PCI_SLOT(dev->devfn) is %d\n", + PCI_SLOT(dev->devfn)); + /* IDSEL=A23 is tx4927 onboard pci slot */ + irq = (irq + PCI_SLOT(dev->devfn)) % 4; + irq++; /* 1-4 */ + DBG("irq is now %d\n", irq); + + switch (irq) { + case 1: + irq = TX4927_IRQ_IOC_PCIA; + break; + case 2: + irq = TX4927_IRQ_IOC_PCIB; + break; + case 3: + irq = TX4927_IRQ_IOC_PCIC; + break; + case 4: + irq = TX4927_IRQ_IOC_PCID; + break; + } + } else { + /* PCI Backplane */ + DBG("PCI Backplane PCI_SLOT(dev->devfn) is %d\n", + PCI_SLOT(dev->devfn)); + irq = backplane_pci_irq[PCI_SLOT(dev->devfn) - 17][irq]; + } + DBG("assigned irq %d\n", irq); + return irq; +} + + +#ifdef TX4927_SUPPORT_PCI_66 +extern int tx4927_pci66; +extern void tx4927_pci66_setup(void); +#endif +extern void tx4927_pci_setup(void); + +#ifdef TX4927_SUPPORT_PCI_66 +int tx4927_pci66_check(void) +{ + struct pci_dev *dev; + unsigned short stat; + int cap66 = 1; + + if (tx4927_pci66 < 0) + return 0; + + /* check 66MHz capability */ + pci_for_each_dev(dev) { + if (cap66) { + pci_read_config_word(dev, PCI_STATUS, &stat); + if (!(stat & PCI_STATUS_66MHZ)) { + printk(KERN_INFO + "PCI: %02x:%02x not 66MHz capable.\n", + dev->bus->number, dev->devfn); + cap66 = 0; + } + } + } + return cap66; +} +#endif + +#ifdef DEBUG +void do_it(u32 offset, u32 reg) +{ + volatile u32 a1; + volatile u32 a2; + volatile u32 v1; + volatile u32 v2; + + a1 = 0xff1f0000 + offset + reg; + a2 = a1 + 4; + + v1 = *(volatile u32 *) a1; + v2 = *(volatile u32 *) a2; + + if (v1) + printk("TX4927 0x%08x 0x%08x\n", a1, v1); + if (v2) + printk("TX4927 0x%08x 0x%08x\n", a2, v2); +} + +void do_it1(u32 base, u32 r) +{ + do_it(base, r); +} + +void do_it2(u32 base, u32 start, u32 stop) +{ + u32 r; + + for (r = start; r <= stop; r += 8) { + do_it(base, r); + } +} +void dump_config(void) +{ + unsigned long id; + unsigned long j; + struct pci_dev *dev; + + printk("----------------------pci\n"); + pci_for_each_dev(dev) { + for (j = 0; j < 64; j++) { + pci_read_config_dword(dev, j * 4, &id); + if (id == 0) + continue; + printk + ("dev 0x%02x 0x%02x:0x%02x -- 0x%02x-0x%02x 0x%08x\n", + dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), (j * 4) + 3, (j * 4), + id); + } + printk("dev 0x%02x \n", dev->devfn); + } + printk("----------------------sdram\n"); + do_it2(0x8000, 0x00, 0x18); + do_it1(0x8000, 0x40); + do_it1(0x8000, 0x58); + printk("----------------------ebus\n"); + do_it2(0x9000, 0x00, 0x38); + printk("----------------------ecc\n"); + do_it2(0xa000, 0x00, 0x08); + printk("----------------------dmac\n"); + do_it2(0xb000, 0x00, 0xf8); + /* b1xx */ + printk("----------------------pci\n"); + /* d */ + printk("----------------------cfg\n"); + do_it2(0xe000, 0x00, 0x20); + do_it1(0xe000, 0x30); + do_it1(0xe000, 0x48); + printk("----------------------timers\n"); + do_it2(0xf000, 0x00, 0xf0); + do_it2(0xf100, 0x00, 0xf0); + do_it2(0xf200, 0x00, 0xf0); + printk("----------------------serial\n"); + do_it2(0xf300, 0x00, 0x20); + do_it2(0xf400, 0x00, 0x20); + printk("----------------------parallel\n"); + do_it2(0xf500, 0x00, 0x0c); + printk("----------------------pic\n"); + do_it2(0xf500, 0x10, 0x24); + do_it2(0xf600, 0x00, 0x2c); + do_it1(0xf600, 0x40); + do_it1(0xf600, 0x60); + do_it1(0xf600, 0x80); + do_it1(0xf600, 0xa0); + printk("----------------------aclink\n"); + do_it2(0xf700, 0x00, 0xfc); + printk("----------------------done\n"); +} +#endif + + +void __init pcibios_fixup_irqs(void) +{ + unsigned char pin; + unsigned char irq; + struct pci_dev *dev; + unsigned int id; + +#ifdef TX4927_SUPPORT_PCI_66 + { + if (tx4927_pci66_check()) { + tx4927_pci66_setup(); + tx4927_pci_setup(); /* Reinitialize PCIC */ + } + } +#endif + + pci_for_each_dev(dev) { + DBG("FIXUP:\n"); + DBG(" devfn=0x%02x (0x%02x:0x%02x)\n", + dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + + pci_read_config_dword(dev, PCI_VENDOR_ID, &id); + DBG(" id=0x%08x\n", id); + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + DBG(" line=0x%02x/%d\n", irq, irq); + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + DBG(" pin=%d\n", pin); + +#ifdef DEBUG + { + unsigned int tmp; + pci_read_config_dword(dev, 0x10, &tmp); + DBG(" bar0:0x10=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x14, &tmp); + DBG(" bar1:0x14=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x1c, &tmp); + DBG(" bar2:0x1c=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x20, &tmp); + DBG(" bar3:0x20=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x24, &tmp); + DBG(" bar4:0x24=0x%08x\n", tmp); + } +#endif + + irq = 0; + + if (id == 0x91301055) { /* ide */ + irq = 14; + } + + if (pin == 0) { + DBG(" auto irq (now=%d) -- skipping pin=0\n", irq); + } else if (irq) { + DBG(" auto irq (now=%d) -- skipping hardcoded irq\n", irq); + } else { + DBG(" auto irq (was=%d)\n", irq); + irq = pci_get_irq(dev, pin); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + irq); + dev->irq = irq; + DBG(" auto irq (now=%d)\n", irq); + } + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + printk(KERN_INFO + "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n", + dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), irq); + + } + +} diff -urN linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c --- linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,317 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c + * + * Define the pci_ops for the Toshiba rbtx4927 + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +/* initialize in setup */ +struct resource pci_io_resource = { + "pci IO space", + (PCIBIOS_MIN_IO), + ((PCIBIOS_MIN_IO) + (TX4927_PCIIO_SIZE)) - 1, + IORESOURCE_IO +}; + +/* initialize in setup */ +struct resource pci_mem_resource = { + "pci memory space", + TX4927_PCIMEM, + TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1, + IORESOURCE_MEM +}; + +extern struct pci_ops tx4927_pci_ops; + +struct pci_channel mips_pci_channels[] = { + /* h/w only supports devices 0x00 to 0x14 */ + {&tx4927_pci_ops, &pci_io_resource, &pci_mem_resource, + PCI_DEVFN(0x00, 0), PCI_DEVFN(0x14, 7)}, + {NULL, NULL, NULL, 0, 0} +}; + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} + +static int +mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, + int *flagsp) +{ + if (bus > 0) { + /* Type 1 configuration */ + tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; + } else { + if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0)) + return -1; + + /* Type 0 configuration */ + tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc); + } + /* clear M_ABORT and Disable M_ABORT Int. */ + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr->pcistatus & 0x0000ffff) | + (PCI_STATUS_REC_MASTER_ABORT << 16); + tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; + return 0; +} + +static int check_abort(int flags) +{ + int code = PCIBIOS_SUCCESSFUL; + if (tx4927_pcicptr-> + pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; + code = PCIBIOS_DEVICE_NOT_FOUND; + // printk("returning PCIBIOS_DEVICE_NOT_FOUND\n"); + } + return code; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int tx4927_pcibios_read_config_byte(struct pci_dev *dev, + int where, unsigned char *val) +{ + int flags, retval; + unsigned char bus, func_num; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *val = + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 3)); +#else + *val = + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)); +#endif + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xff; +//printk("CFG R1 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_read_config_word(struct pci_dev *dev, + int where, unsigned short *val) +{ + int flags, retval; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *val = + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 2)); +#else + *val = + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)); +#endif + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xffff; +//printk("CFG R2 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_read_config_dword(struct pci_dev *dev, + int where, unsigned int *val) +{ + int flags, retval; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *val = tx4927_pcicptr->g2pcfgdata; + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xffffffff; + +//printk("CFG R4 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_write_config_byte(struct pci_dev *dev, + int where, unsigned char val) +{ + int flags; + unsigned char bus, func_num; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 3)) = val; +#else + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)) = val; +#endif +//printk("CFG W1 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +static int tx4927_pcibios_write_config_word(struct pci_dev *dev, + int where, unsigned short val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 2)) = val; +#else + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)) = val; +#endif +//printk("CFG W2 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +static int tx4927_pcibios_write_config_dword(struct pci_dev *dev, + int where, unsigned int val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + tx4927_pcicptr->g2pcfgdata = val; +//printk("CFG W4 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +struct pci_ops tx4927_pci_ops = { + tx4927_pcibios_read_config_byte, + tx4927_pcibios_read_config_word, + tx4927_pcibios_read_config_dword, + tx4927_pcibios_write_config_byte, + tx4927_pcibios_write_config_word, + tx4927_pcibios_write_config_dword +}; diff -urN linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c --- linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,96 @@ +/* + * rbtx4927 specific prom routines + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef COMMAND_LINE_SIZE +#define COMMAND_LINE_SIZE CL_SIZE +#endif + +char arcs_cmdline[COMMAND_LINE_SIZE] = "console=ttyS0,38400 ip=any root=nfs rw"; + +void __init prom_init_cmdline(int argc, char **argv) +{ + int i; /* Always ignore the "-c" at argv[0] */ + + /* ignore all built-in args if any f/w args given */ + if (argc > 1) { + *arcs_cmdline = '\0'; + } + + for (i = 1; i < argc; i++) { + if (i != 1) { + strcat(arcs_cmdline, " "); + } + strcat(arcs_cmdline, argv[i]); + } +} + +void __init prom_init(int argc, char **argv, char **envp, int *pvec) +{ + extern int tx4927_get_mem_size(void); + int msize; + char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES; + extern char* toshiba_name; + + prom_init_cmdline(argc, argv); + + mips_machgroup = MACH_GROUP_TOSHIBA; + + if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) + mips_machtype = MACH_TOSHIBA_RBTX4927; + else + mips_machtype = MACH_TOSHIBA_RBTX4937; + + toshiba_name = toshiba_name_list[mips_machtype]; + + msize = tx4927_get_mem_size(); + add_memory_region(0, msize << 20, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory(void) +{ +} + + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} + +const char *get_system_type(void) +{ + return "Toshiba RBTX4927/RBTX4937"; +} diff -urN linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c --- linux-2.4.21/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,1219 @@ +/* + * Toshiba rbtx4927 specific setup + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2002 MontaVista Software Inc. + * Author: Michael Pruznick, michael_pruznick@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_RTC_DS1742 +#include +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include +#endif +#include +#ifdef CONFIG_PCI +#include +#include +#include +#include +#include +#include +#endif +#ifdef CONFIG_PC_KEYB +#include +#endif +#ifdef CONFIG_BLK_DEV_IDEPCI +#include +#include +#include +extern struct ide_ops std_ide_ops; +#endif + +#undef TOSHIBA_RBTX4927_SETUP_DEBUG + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_SETUP_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_SETUP_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_SETUP_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 ) +#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) +#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 ) +#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 ) +#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) +#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) +#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) +#define TOSHIBA_RBTX4927_SETUP_PCI66 ( 1 << 10 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +static const u32 toshiba_rbtx4927_setup_debug_flag = + (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | + TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR | + TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP | + TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP + | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | + TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66); +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_setup_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) +#endif + +/* These functions are used for rebooting or halting the machine*/ +extern void toshiba_rbtx4927_restart(char *command); +extern void toshiba_rbtx4927_halt(void); +extern void toshiba_rbtx4927_power_off(void); + +int tx4927_using_backplane = 0; + +extern void gt64120_time_init(void); +extern void toshiba_rbtx4927_irq_setup(void); + +#ifdef CONFIG_PCI +#define CONFIG_TX4927BUG_WORKAROUND +#undef TX4927_SUPPORT_COMMAND_IO +#undef TX4927_SUPPORT_PCI_66 +int tx4927_cpu_clock = 100000000; /* 100MHz */ +unsigned long mips_pci_io_base; +unsigned long mips_pci_io_size; +unsigned long mips_pci_mem_base; +unsigned long mips_pci_mem_size; +/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ +unsigned long mips_pci_io_pciaddr = 0; +unsigned long mips_memory_upper; +static int tx4927_ccfg_toeon = 1; +static int tx4927_pcic_trdyto = 0; /* default: disabled */ +unsigned long tx4927_ce_base[8]; +void tx4927_pci_setup(void); +void tx4927_reset_pci_pcic(void); +#ifdef TX4927_SUPPORT_PCI_66 +void tx4927_pci66_setup(void); +extern int tx4927_pci66_check(void); +#endif +int tx4927_pci66 = 0; /* 0:auto */ +#endif + +char *toshiba_name = ""; + +#ifdef CONFIG_PCI +void tx4927_dump_pcic_settings(void) +{ + printk("%s pcic settings:",toshiba_name); + { + int i; + unsigned long *preg = (unsigned long *) tx4927_pcicptr; + for (i = 0; i < sizeof(struct tx4927_pcic_reg); i += 4) { + if (i % 32 == 0) + printk("\n%04x:", i); + if (preg == &tx4927_pcicptr->g2pintack + || preg == &tx4927_pcicptr->g2pspc +#ifdef CONFIG_TX4927BUG_WORKAROUND + || preg == &tx4927_pcicptr->g2pcfgadrs + || preg == &tx4927_pcicptr->g2pcfgdata +#endif + ) { + printk(" XXXXXXXX"); + preg++; + continue; + } + printk(" %08lx", *preg++); + if (preg == &tx4927_pcicptr->g2pcfgadrs) + break; + } + printk("\n"); + } +} + +static void tx4927_pcierr_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + extern void tx4927_dump_pcic_settings(void); + +#ifdef CONFIG_BLK_DEV_IDEPCI + /* ignore MasterAbort for ide probing... */ + if (irq == TX4927_IRQ_IRC_PCIERR && + ((tx4927_pcicptr->pcistatus >> 16) & 0xf900) == + PCI_STATUS_REC_MASTER_ABORT) { + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + + return; + } +#endif + printk("PCI error interrupt (irq 0x%x).\n", irq); + printk("pcistat:%04x, g2pstatus:%08lx, pcicstatus:%08lx\n", + (unsigned short) (tx4927_pcicptr->pcistatus >> 16), + tx4927_pcicptr->g2pstatus, tx4927_pcicptr->pcicstatus); + printk("ccfg:%08lx, tear:%02lx_%08lx\n", + (unsigned long) tx4927_ccfgptr->ccfg, + (unsigned long) (tx4927_ccfgptr->tear >> 32), + (unsigned long) tx4927_ccfgptr->tear); + show_regs(regs); + //tx4927_dump_pcic_settings(); + panic("PCI error at PC:%08lx.", regs->cp0_epc); +} + +static struct irqaction pcic_action = { + tx4927_pcierr_interrupt, 0, 0, "PCI-C", NULL, NULL +}; + +static struct irqaction pcierr_action = { + tx4927_pcierr_interrupt, 0, 0, "PCI-ERR", NULL, NULL +}; + + +void __init toshiba_rbtx4927_pci_irq_init(void) +{ + setup_irq(TX4927_IRQ_IRC_PCIC, &pcic_action); + setup_irq(TX4927_IRQ_IRC_PCIERR, &pcierr_action); +} + +void tx4927_reset_pci_pcic(void) +{ + /* Reset PCI Bus */ + *tx4927_pcireset_ptr = 1; + /* Reset PCIC */ + tx4927_ccfgptr->clkctr |= TX4927_CLKCTR_PCIRST; + udelay(10000); + /* clear PCIC reset */ + tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; + *tx4927_pcireset_ptr = 0; +} +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_PCI +#ifdef TX4927_SUPPORT_PCI_66 +void tx4927_pci66_setup(void) +{ + int pciclk, pciclkin = 1; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, + "-\n"); + + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) + return; + + tx4927_reset_pci_pcic(); + + /* Assert M66EN */ + tx4927_ccfgptr->ccfg |= TX4927_CCFG_PCI66; + /* set PCICLK 66MHz */ + if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = 0; + pcidivmode = + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK; + if (tx4927_cpu_clock >= 170000000) { + /* CPU 200MHz */ + pcidivmode = TX4927_CCFG_PCIDIVMODE_3; + pciclk = tx4927_cpu_clock / 3; + } else { + /* CPU 166MHz */ + pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5; + pciclk = tx4927_cpu_clock * 2 / 5; + } + tx4927_ccfgptr->ccfg = + (tx4927_ccfgptr->ccfg & ~TX4927_CCFG_PCIDIVMODE_MASK) + | pcidivmode; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCI66, + ":PCICLK: ccfg:0x%08lx\n", + (unsigned long) tx4927_ccfgptr->ccfg); + } else { + int pciclk_setting = *tx4927_pci_clk_ptr; + pciclkin = 0; + pciclk = 66666666; + pciclk_setting &= ~TX4927_PCI_CLK_MASK; + pciclk_setting |= TX4927_PCI_CLK_66; + *tx4927_pci_clk_ptr = pciclk_setting; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCI66, + "PCICLK: pci_clk:%02x\n", *tx4927_pci_clk_ptr); + } + + udelay(10000); + + /* clear PCIC reset */ + tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; + /* clear PCI reset */ + *tx4927_pcireset_ptr = 0; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, + "+\n"); +} +#endif /* TX4927_SUPPORT_PCI_66 */ + +void print_pci_status(void) +{ + printk("PCI STATUS %lx\n", tx4927_pcicptr->pcistatus); + printk("PCIC STATUS %lx\n", tx4927_pcicptr->pcicstatus); +} + +static struct pci_dev *fake_pci_dev(struct pci_channel *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + + if (busnr != top_bus) + /* Fake a parent bus structure. */ + bus.parent = &bus; + else + bus.parent = NULL; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +static int early_##rw##_config_##size(struct pci_channel *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, dword, u32) + +static int __init tx4927_pcibios_init(int busno, struct pci_channel *hose) +{ + u32 pci_devfn; + int devfn_start = 0; + int devfn_stop = 0xff; + unsigned int id; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "-\n"); + + if (hose->first_devfn) + devfn_start = hose->first_devfn; + if (hose->last_devfn) + devfn_stop = hose->last_devfn; + + for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { + early_read_config_dword(hose, busno, busno, pci_devfn, + PCI_VENDOR_ID, &id); + + if (id == 0xffffffff) { + continue; + } + + if (id == 0x94601055) { + u8 v08_64; + u32 v32_b0; + u8 v08_e1; +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + char *s = " sb/isa --"; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x64, &v08_64); + early_read_config_dword(hose, busno, busno, + pci_devfn, 0xb0, &v32_b0); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0xe1, &v08_e1); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xe1 = 0x%02x\n", s, v08_e1); + + /* serial irq control */ + v08_64 = 0xd0; + + /* serial irq pin */ + v32_b0 |= 0x00010000; + + /* ide irq on isa14 */ + v08_e1 &= 0xf0; + v08_e1 |= 0x0d; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xe1 = 0x%02x\n", s, v08_e1); + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x64, v08_64); + early_write_config_dword(hose, busno, busno, + pci_devfn, 0xb0, v32_b0); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0xe1, v08_e1); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x64, + &v08_64); + early_read_config_dword(hose, busno, busno, + pci_devfn, 0xb0, + &v32_b0); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0xe1, + &v08_e1); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xe1 = 0x%02x\n", s, v08_e1); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + if (id == 0x91301055) { + u8 v08_04; + u8 v08_09; + u8 v08_41; + u8 v08_43; + u8 v08_5c; +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + char *s = " sb/ide --"; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x04, &v08_04); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x09, &v08_09); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x41, &v08_41); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x43, &v08_43); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x5c, &v08_5c); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x5c = 0x%02x\n", s, v08_5c); + + /* enable ide master/io */ + v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); + + /* enable ide native mode */ + v08_09 |= 0x05; + + /* enable primary ide */ + v08_41 |= 0x80; + + /* enable secondary ide */ + v08_43 |= 0x80; + + /* + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + * + * This line of code is intended to provide the user with a work + * around solution to the anomalies cited in SMSC's anomaly sheet + * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". + * + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + */ + v08_5c |= 0x01; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x5c = 0x%02x\n", s, v08_5c); + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x5c, v08_5c); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x04, v08_04); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x09, v08_09); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x41, v08_41); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x43, v08_43); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x04, + &v08_04); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x09, + &v08_09); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x41, + &v08_41); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x43, + &v08_43); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x5c, + &v08_5c); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x5c = 0x%02x\n", s, v08_5c); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + } + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "+\n"); + + return (busno); +} + +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +void tx4927_pci_setup(void) +{ + static int called = 0; + extern unsigned int tx4927_get_mem_size(void); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "-\n"); + +#ifndef TX4927_SUPPORT_PCI_66 + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) + printk("PCI 66 current unsupported\n"); +#endif + + mips_memory_upper = tx4927_get_mem_size() << 20; + mips_memory_upper += KSEG0; + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_memory_upper\n", + mips_memory_upper); + mips_pci_io_base = TX4927_PCIIO; + mips_pci_io_size = TX4927_PCIIO_SIZE; + mips_pci_mem_base = TX4927_PCIMEM; + mips_pci_mem_size = TX4927_PCIMEM_SIZE; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_base\n", + mips_pci_io_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_size\n", + mips_pci_io_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_base\n", + mips_pci_mem_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_size\n", + mips_pci_mem_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.start\n", + pci_io_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.end\n", + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.start\n", + pci_mem_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.end\n", + pci_mem_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_io_port_base", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_io_resource to 0x%08lx 0x%08lx\n", + pci_io_resource.start, + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_mem_resource to 0x%08lx 0x%08lx\n", + pci_mem_resource.start, + pci_mem_resource.end); + + if (!called) { + printk + ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + (unsigned short) (tx4927_pcicptr->pciid >> 16), + (unsigned short) (tx4927_pcicptr->pciid & 0xffff), + (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), + (!(tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB)) ? "External" : + "Internal"); + called = 1; + } + printk("%s PCIC --%s PCICLK:",toshiba_name, + (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); + if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { + int pciclk = 0; + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + pciclk = tx4927_cpu_clock * 2 / 5; + break; + case TX4927_CCFG_PCIDIVMODE_3: + pciclk = tx4927_cpu_clock / 3; + break; + case TX4927_CCFG_PCIDIVMODE_5: + pciclk = tx4927_cpu_clock / 5; + break; + case TX4927_CCFG_PCIDIVMODE_6: + pciclk = tx4927_cpu_clock / 6; + break; + } + printk("Internal(%dMHz)", pciclk / 1000000); + } else { + int pciclk = 0; + int pciclk_setting = *tx4927_pci_clk_ptr; + switch (pciclk_setting & TX4927_PCI_CLK_MASK) { + case TX4927_PCI_CLK_33: + pciclk = 33333333; + break; + case TX4927_PCI_CLK_25: + pciclk = 25000000; + break; + case TX4927_PCI_CLK_66: + pciclk = 66666666; + break; + case TX4927_PCI_CLK_50: + pciclk = 50000000; + break; + } + printk("External(%dMHz)", pciclk / 1000000); + } + printk("\n"); + + + + /* GB->PCI mappings */ + tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; + tx4927_pcicptr->g2piogbase = mips_pci_io_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PIOGBASE_ECHG +#else + TX4927_PCIC_G2PIOGBASE_BSDIS +#endif + ; + + tx4927_pcicptr->g2piopbase = 0; + + tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4; + tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PMnGBASE_ECHG +#else + TX4927_PCIC_G2PMnGBASE_BSDIS +#endif + ; + tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base; + + tx4927_pcicptr->g2pmmask[1] = 0; + tx4927_pcicptr->g2pmgbase[1] = 0; + tx4927_pcicptr->g2pmpbase[1] = 0; + tx4927_pcicptr->g2pmmask[2] = 0; + tx4927_pcicptr->g2pmgbase[2] = 0; + tx4927_pcicptr->g2pmpbase[2] = 0; + + + /* PCI->GB mappings (I/O 256B) */ + tx4927_pcicptr->p2giopbase = 0; /* 256B */ + + +#ifdef TX4927_SUPPORT_COMMAND_IO + tx4927_pcicptr->p2giogbase = 0 | TX4927_PCIC_P2GIOGBASE_TIOEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GIOGBASE_TECHG +#else + TX4927_PCIC_P2GIOGBASE_TBSDIS +#endif + ; +#else + tx4927_pcicptr->p2giogbase = 0; +#endif + + /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */ + tx4927_pcicptr->p2gm0plbase = 0; + tx4927_pcicptr->p2gm0pubase = 0; + tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GMnGBASE_TECHG +#else + TX4927_PCIC_P2GMnGBASE_TBSDIS +#endif + ; + + /* PCI->GB mappings (MEM 16MB) -not used */ + tx4927_pcicptr->p2gm1plbase = 0xffffffff; +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-PCIC-BUG: P2GM1PUBASE must be 0 + * if P2GM0PUBASE was 0. + */ + tx4927_pcicptr->p2gm1pubase = 0; +#else + tx4927_pcicptr->p2gm1pubase = 0xffffffff; +#endif + tx4927_pcicptr->p2gmgbase[1] = 0; + + /* PCI->GB mappings (MEM 1MB) -not used */ + tx4927_pcicptr->p2gm2pbase = 0xffffffff; + tx4927_pcicptr->p2gmgbase[2] = 0; + + + /* Enable Initiator Memory 0 Space, I/O Space, Config */ + tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK; + tx4927_pcicptr->pciccfg |= + TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE | + TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR; + + + /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ + tx4927_pcicptr->pcicfg1 = 0; + + if (tx4927_pcic_trdyto >= 0) { + tx4927_pcicptr->g2ptocnt &= ~0xff; + tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff); + //printk("%s PCIC -- TRDYTO:%02lx\n",toshiba_name, + // tx4927_pcicptr->g2ptocnt & 0xff); + } + + /* Clear All Local Bus Status */ + tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL; + /* Enable All Local Bus Interrupts */ + tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL; + /* Clear All Initiator Status */ + tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL; + /* Enable All Initiator Interrupts */ + tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL; + /* Clear All PCI Status Error */ + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr->pcistatus & 0x0000ffff) | + (TX4927_PCIC_PCISTATUS_ALL << 16); + /* Enable All PCI Status Error Interrupts */ + tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL; + + /* PCIC Int => IRC IRQ16 */ + tx4927_pcicptr->pcicfg2 = + (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC; + + if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) { + /* XXX */ + } else { + /* Reset Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA; + /* Enable Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN; + } + + tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | +#ifdef TX4927_SUPPORT_COMMAND_IO + PCI_COMMAND_IO | +#endif + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + ":pci setup complete:\n"); + //tx4927_dump_pcic_settings(); + + { + struct pci_channel *p; + int busno; + + busno = 0; + for (p = mips_pci_channels; p->pci_ops != NULL; p++) { + busno = tx4927_pcibios_init(busno, p) + 1; + } + } + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "+\n"); +} + +#endif /* CONFIG_PCI */ + +void toshiba_rbtx4927_restart(char *command) +{ + printk(KERN_NOTICE "System Rebooting...\n"); + + /* enable the s/w reset register */ + reg_wr08(RBTX4927_SW_RESET_ENABLE, RBTX4927_SW_RESET_ENABLE_SET); + + /* wait for enable to be seen */ + while ((reg_rd08(RBTX4927_SW_RESET_ENABLE) & + RBTX4927_SW_RESET_ENABLE_SET) == 0x00); + + /* do a s/w reset */ + reg_wr08(RBTX4927_SW_RESET_DO, RBTX4927_SW_RESET_DO_SET); + + /* do something passive while waiting for reset */ + cli(); + while (1) + asm_wait(); + + /* no return */ +} + +void toshiba_rbtx4927_halt(void) +{ + printk(KERN_NOTICE "System Halted\n"); + cli(); + while (1) { + asm_wait(); + } + /* no return */ +} + +void toshiba_rbtx4927_power_off(void) +{ + toshiba_rbtx4927_halt(); + /* no return */ +} + +void __init toshiba_rbtx4927_setup(void) +{ + vu32 cp0_config; + + printk("CPU is %s\n", toshiba_name); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "-\n"); + + /* f/w leaves this on at startup */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Clearing STO_ERL.\n"); + clear_c0_status(ST0_ERL); + + /* enable caches -- HCP5 does this, pmon does not */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Enabling TX49_CONF_IC,TX49_CONF_DC.\n"); + cp0_config = read_c0_config(); + cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); + write_c0_config(cp0_config); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + extern void dump_cp0(char *); + dump_cp0("toshiba_rbtx4927_early_fw_fixup"); + } +#endif + + /* setup irq stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 pic.\n"); + TX4927_WR(0xff1ff604, 0x00000400); /* irq trigger */ + TX4927_WR(0xff1ff608, 0x00000000); /* irq trigger */ + + /* setup serial stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 sio.\n"); + TX4927_WR(0xff1ff314, 0x00000000); /* h/w flow control off */ + TX4927_WR(0xff1ff414, 0x00000000); /* h/w flow control off */ + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); + + + + set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":mips_io_port_base=0x%08lx\n", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Resource\n"); + ioport_resource.start = 0; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0; + iomem_resource.end = 0xffffffff; + + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":ResetRoutines\n"); + _machine_restart = toshiba_rbtx4927_restart; + _machine_halt = toshiba_rbtx4927_halt; + _machine_power_off = toshiba_rbtx4927_power_off; + + +#ifdef CONFIG_BLK_DEV_IDEPCI + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":ide_ops=&std_ide_ops(modified)\n"); + ide_ops = &std_ide_ops; + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":ide_ops=\n"); + } +#endif + +#ifdef CONFIG_FB + { + conswitchp = &dummy_con; + } +#endif + + + + +#ifdef CONFIG_PCI + + /* PCIC */ + /* + * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. + * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1). + * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) + * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) + * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) + * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) + * i.e. S9[3]: ON (83MHz), OFF (100MHz) + */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "ccfg is %lx, DIV is %x\n", + (unsigned long) tx4927_ccfgptr-> + ccfg, TX4927_CCFG_PCIDIVMODE_MASK); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCI66, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIMIDE, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCIDIVMODE is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK); + + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + case TX4927_CCFG_PCIDIVMODE_5: + tx4927_cpu_clock = 166000000; /* 166MHz */ + break; + default: + tx4927_cpu_clock = 200000000; /* 200MHz */ + } + + /* CCFG */ + /* enable Timeout BusError */ + if (tx4927_ccfg_toeon) + tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; + + /* SDRAMC fixup */ +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-BUG: INF 01-01-18/ BUG 01-01-22 + * G-bus timeout error detection is incorrect + */ + if (tx4927_ccfg_toeon) + tx4927_sdramcptr->tr |= 0x02000000; /* RCD:3tck */ +#endif + +#ifdef TX4927_SUPPORT_PCI_66 + tx4927_pci66_setup(); +#endif + + tx4927_pci_setup(); + + + { + u32 id = 0; + early_read_config_dword(&mips_pci_channels[0], 0, 0, 0x90, + PCI_VENDOR_ID, &id); + if (id == 0x94601055) { + tx4927_using_backplane = 1; + printk("backplane board IS installed\n"); + } else { + printk("backplane board NOT installed\n"); + } + } +#endif + + + /* this is only done if backplane board installed, so must wait for pci */ +#ifdef CONFIG_PC_KEYB + { + if (tx4927_using_backplane) { + extern struct kbd_ops std_kbd_ops; + kbd_ops = &std_kbd_ops; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=&std_kbd_ops\n"); + } else { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=\n"); + } + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=\n"); + } +#endif + + /* this is on ISA bus behind PCI bus, so need PCI up first */ +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=yes\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_init()\n"); + smsc_fdc37m81x_init(0x3f0); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_beg()\n"); + smsc_fdc37m81x_config_beg(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_set(KBD)\n"); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, + SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, + 1); + + smsc_fdc37m81x_config_end(); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_end()\n"); + } else { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=not_found\n"); + } + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, ":fpcibo=no\n"); + } +#endif + + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); +} + +void __init +toshiba_rbtx4927_time_init(void) +{ +#ifdef CONFIG_RTC_DS1742 + u32 c1; + u32 c2; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n"); + +#ifdef CONFIG_RTC_DS1742 + + rtc_get_time = rtc_ds1742_get_time; + rtc_set_time = rtc_ds1742_set_time; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()-\n"); + rtc_ds1742_init(0xbc010000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()+\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_counter_frequency-\n"); + rtc_ds1742_wait(); + + /* get the count */ + c1 = read_c0_count(); + + /* wait for the seconds to change again */ + rtc_ds1742_wait(); + + /* get the count again */ + c2 = read_c0_count(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_counter_frequency+\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c1=%12u\n", c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c2=%12u\n", c2); + + /* this diff is as close as we are going to get to counter ticks per sec */ + mips_counter_frequency = abs(c2 - c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f1=%12u\n", mips_counter_frequency); + + /* round to 1/10th of a MHz */ + mips_counter_frequency /= (100 * 1000); + mips_counter_frequency *= (100 * 1000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f2=%12u\n", mips_counter_frequency); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_INFO, + ":mips_counter_frequency=%uHz (%uMHz)\n", + mips_counter_frequency, + mips_counter_frequency / 1000000); +#else + mips_counter_frequency = 100000000; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); + +} + +void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq) +{ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "-\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "+\n"); +} diff -urN linux-2.4.21/arch/mips/vr4181/common/irq.c linux-2.4.22/arch/mips/vr4181/common/irq.c --- linux-2.4.21/arch/mips/vr4181/common/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/vr4181/common/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * * Credits to Bradley D. LaRonde and Michael Klar for writing the original * irq.c file which was derived from the common irq.c file. - * + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -180,9 +180,9 @@ extern int setup_irq(unsigned int irq, struct irqaction *irqaction); extern void mips_cpu_irq_init(u32 irq_base); -static struct irqaction cascade = +static struct irqaction cascade = { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; -static struct irqaction reserved = +static struct irqaction reserved = { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; void __init init_IRQ(void) @@ -216,7 +216,7 @@ /* Default all ICU IRQs to off ... */ *VR4181_MSYSINT1REG = 0; *VR4181_MSYSINT2REG = 0; - + /* We initialize the level 2 ICU registers to all bits disabled. */ *VR4181_MPIUINTREG = 0; *VR4181_MAIUINTREG = 0; @@ -229,7 +229,7 @@ setup_irq(VR4181_IRQ_INT0, &cascade); setup_irq(VR4181_IRQ_GIU, &cascade); - /* + /* * RTC interrupts are interesting. They have two destinations. * One is at sys irq controller, and the other is at CPU IP3 and IP4. * RTC timer is used as system timer. @@ -239,7 +239,7 @@ setup_irq(VR4181_IRQ_RTCL1, &reserved); setup_irq(VR4181_IRQ_RTCL2, &reserved); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("Setting debug traps - please connect the remote debugger.\n"); set_debug_traps(); diff -urN linux-2.4.21/arch/mips/vr4181/common/serial.c linux-2.4.22/arch/mips/vr4181/common/serial.c --- linux-2.4.21/arch/mips/vr4181/common/serial.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/vr4181/common/serial.c 2003-08-25 04:44:40.000000000 -0700 @@ -14,7 +14,7 @@ /* * [jsun, 010925] - * You need to make sure rs_table has at least one element in + * You need to make sure rs_table has at least one element in * drivers/char/serial.c file. There is no good way to do it right * now. A workaround is to include CONFIG_SERIAL_MANY_PORTS in your * configure file, which would gives you 64 ports and wastes 11K ram. diff -urN linux-2.4.21/arch/mips/vr4181/common/time.c linux-2.4.22/arch/mips/vr4181/common/time.c --- linux-2.4.21/arch/mips/vr4181/common/time.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/vr4181/common/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -2,7 +2,7 @@ * Copyright 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net * - * rtc and time ops for vr4181. Part of code is drived from + * rtc and time ops for vr4181. Part of code is drived from * linux-vr, originally written by Bradley D. LaRonde & Michael Klar. * * This program is free software; you can redistribute it and/or modify it @@ -29,10 +29,10 @@ * RTC ops */ -spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; +extern spinlock_t rtc_lock; /* per VR41xx docs, bad data can be read if between 2 counts */ -static inline unsigned short +static inline unsigned short read_time_reg(volatile unsigned short *reg) { unsigned short value; @@ -43,7 +43,7 @@ return value; } -static unsigned long +static unsigned long vr4181_rtc_get_time(void) { unsigned short regh, regm, regl; @@ -60,7 +60,7 @@ return ((regh << 17) | (regm << 1) | (regl >> 15)); } -static int +static int vr4181_rtc_set_time(unsigned long timeval) { unsigned short intreg; @@ -82,13 +82,13 @@ } -/* +/* * timer interrupt routine (wrapper) * * we need our own interrupt routine because we need to clear * RTC1 interrupt. */ -static void +static void vr4181_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* Clear the interrupt. */ @@ -115,7 +115,7 @@ extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -static void +static void vr4181_timer_setup(struct irqaction *irq) { /* over-write the handler to be our own one */ diff -urN linux-2.4.21/arch/mips/vr4181/osprey/Makefile linux-2.4.22/arch/mips/vr4181/osprey/Makefile --- linux-2.4.21/arch/mips/vr4181/osprey/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/vr4181/osprey/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -12,6 +12,6 @@ obj-y := setup.o prom.o reset.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_KGDB) += dbg_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr4181/osprey/prom.c linux-2.4.22/arch/mips/vr4181/osprey/prom.c --- linux-2.4.21/arch/mips/vr4181/osprey/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/vr4181/osprey/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -26,7 +26,7 @@ return "NEC_Vr41xx Osprey"; } -/* +/* * [jsun] right now we assume it is the nec debug monitor, which does * not pass any arguments. */ diff -urN linux-2.4.21/arch/mips/vr4181/osprey/reset.c linux-2.4.22/arch/mips/vr4181/osprey/reset.c --- linux-2.4.21/arch/mips/vr4181/osprey/reset.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/vr4181/osprey/reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -18,10 +18,10 @@ void nec_osprey_restart(char *command) { - set_cp0_status(ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + set_c0_status(ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21/arch/mips/vr4181/osprey/setup.c linux-2.4.22/arch/mips/vr4181/osprey/setup.c --- linux-2.4.21/arch/mips/vr4181/osprey/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips/vr4181/osprey/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -43,7 +43,7 @@ #ifdef CONFIG_FB conswitchp = &dummy_con; #endif - + _machine_restart = nec_osprey_restart; _machine_halt = nec_osprey_halt; _machine_power_off = nec_osprey_power_off; @@ -64,7 +64,7 @@ // *VR4181_GPMD0REG = 0x00c0; // *VR4181_GPINTEN = 1<<6; - /* [jsun] I believe this will get the interrupt type right + /* [jsun] I believe this will get the interrupt type right * for the ether port. */ *VR4181_GPINTTYPL = 0x3000; diff -urN linux-2.4.21/arch/mips/vr41xx/casio-e55/Makefile linux-2.4.22/arch/mips/vr41xx/casio-e55/Makefile --- linux-2.4.21/arch/mips/vr41xx/casio-e55/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/casio-e55/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,17 @@ +# +# Makefile for the CASIO CASSIOPEIA E-55/65 specific parts of the kernel +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := e55.o + +all: e55.o + +obj-y := init.o setup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/casio-e55/ide-e55.c linux-2.4.22/arch/mips/vr41xx/casio-e55/ide-e55.c --- linux-2.4.21/arch/mips/vr41xx/casio-e55/ide-e55.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/casio-e55/ide-e55.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,99 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * IDE routines for typical pc-like standard configurations + * for the CASIO CASSIOPEIA E-55/65. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa Sun, 24 Feb 2002 + * - Added CASIO CASSIOPEIA E-55/65 support. + */ +#include +#include +#include +#include +#include +#include + +static int e55_ide_default_irq(ide_ioreg_t base) +{ + return 40; +} + +static ide_ioreg_t e55_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0xc1f0; + case 1: return 0xc170; + case 2: return 0xc1e8; + case 3: return 0xc168; + case 4: return 0xc1e0; + case 5: return 0xc160; + } + return 0; +} + +static void e55_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int e55_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void e55_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int e55_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void e55_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void e55_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops e55_ide_ops = { + &e55_ide_default_irq, + &e55_ide_default_io_base, + &e55_ide_init_hwif_ports, + &e55_ide_request_irq, + &e55_ide_free_irq, + &e55_ide_check_region, + &e55_ide_request_region, + &e55_ide_release_region +}; diff -urN linux-2.4.21/arch/mips/vr41xx/casio-e55/init.c linux-2.4.22/arch/mips/vr41xx/casio-e55/init.c --- linux-2.4.21/arch/mips/vr41xx/casio-e55/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/casio-e55/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,49 @@ +/* + * FILE NAME + * arch/mips/vr41xx/casio-e55/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the CASIO CASSIOPEIA E-55/65. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "CASIO CASSIOPEIA E-11/15/55/65"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_CASIO_E55; +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21/arch/mips/vr41xx/casio-e55/setup.c linux-2.4.22/arch/mips/vr41xx/casio-e55/setup.c --- linux-2.4.21/arch/mips/vr41xx/casio-e55/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/casio-e55/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,65 @@ +/* + * FILE NAME + * arch/mips/vr41xx/casio-e55/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the CASIO CASSIOPEIA E-11/15/55/65. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +void __init casio_e55_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); +} diff -urN linux-2.4.21/arch/mips/vr41xx/common/Makefile linux-2.4.22/arch/mips/vr41xx/common/Makefile --- linux-2.4.21/arch/mips/vr41xx/common/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -14,8 +14,12 @@ obj-y := bcu.o cmu.o giu.o icu.o int-handler.o reset.o +export-objs := vrc4173.o + obj-$(CONFIG_PCI) += pciu.o obj-$(CONFIG_SERIAL) += serial.o obj-$(CONFIG_VR41XX_TIME_C) += time.o +obj-$(CONFIG_VRC4173) += vrc4173.o +obj-$(subst m,y,$(CONFIG_IDE)) += ide.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/common/bcu.c linux-2.4.22/arch/mips/vr41xx/common/bcu.c --- linux-2.4.21/arch/mips/vr41xx/common/bcu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/bcu.c 2003-08-25 04:44:40.000000000 -0700 @@ -69,7 +69,7 @@ static inline u16 read_clkspeed(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: return readw(VR4111_CLKSPEEDREG); case CPU_VR4122: return readw(VR4122_CLKSPEEDREG); @@ -86,7 +86,7 @@ { unsigned long pclock = 0; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: pclock = 18432000 * 64; @@ -110,7 +110,7 @@ static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: /* The NEC VR4111 doesn't have the VTClock. */ break; @@ -151,7 +151,7 @@ { unsigned long tclock = 0; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: if (!(clkspeed & DIV2B)) tclock = pclock / 2; @@ -182,8 +182,8 @@ /* * VR4131 Revision 2.0 and 2.1 use a value of (tclock / 2). */ - if ((mips_cpu.processor_id == PRID_VR4131_REV2_0) || - (mips_cpu.processor_id == PRID_VR4131_REV2_1)) + if ((current_cpu_data.processor_id == PRID_VR4131_REV2_0) || + (current_cpu_data.processor_id == PRID_VR4131_REV2_1)) tclock /= 2; else tclock /= 4; diff -urN linux-2.4.21/arch/mips/vr41xx/common/cmu.c linux-2.4.22/arch/mips/vr41xx/common/cmu.c --- linux-2.4.21/arch/mips/vr41xx/common/cmu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/cmu.c 2003-08-25 04:44:40.000000000 -0700 @@ -66,7 +66,7 @@ void __init vr41xx_cmu_init(u16 mask) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_cmu_base = VR4111_CMUCLKMSK; diff -urN linux-2.4.21/arch/mips/vr41xx/common/giu.c linux-2.4.22/arch/mips/vr41xx/common/giu.c --- linux-2.4.21/arch/mips/vr41xx/common/giu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/giu.c 2003-08-25 04:44:40.000000000 -0700 @@ -89,7 +89,7 @@ return res; } -void vr41xx_enable_giuint(u8 pin) +void vr41xx_enable_giuint(int pin) { if (pin < 16) set_giuint(GIUINTENL, (u16)1 << pin); @@ -97,7 +97,7 @@ set_giuint(GIUINTENH, (u16)1 << (pin - 16)); } -void vr41xx_disable_giuint(u8 pin) +void vr41xx_disable_giuint(int pin) { if (pin < 16) clear_giuint(GIUINTENL, (u16)1 << pin); @@ -105,15 +105,15 @@ clear_giuint(GIUINTENH, (u16)1 << (pin - 16)); } -void vr41xx_clear_giuint(u8 pin) +void vr41xx_clear_giuint(int pin) { if (pin < 16) - write_giuint(GIUINTSTATL, (u16)1 << pin); + write_giuint((u16)1 << pin, GIUINTSTATL); else - write_giuint(GIUINTSTATH, (u16)1 << (pin - 16)); + write_giuint((u16)1 << (pin - 16), GIUINTSTATH); } -void vr41xx_set_irq_trigger(u8 pin, u8 trigger, u8 hold) +void vr41xx_set_irq_trigger(int pin, int trigger, int hold) { u16 mask; @@ -146,7 +146,7 @@ vr41xx_clear_giuint(pin); } -void vr41xx_set_irq_level(u8 pin, u8 level) +void vr41xx_set_irq_level(int pin, int level) { u16 mask; @@ -167,7 +167,6 @@ vr41xx_clear_giuint(pin); } -#define GIUINT_CASCADE_IRQ 16 #define GIUINT_NR_IRQS 32 enum { @@ -212,8 +211,6 @@ return retval; } -extern unsigned int do_IRQ(int irq, struct pt_regs *regs); - unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs) { struct vr41xx_giuint_cascade *cascade; @@ -242,7 +239,7 @@ { int i; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_giu_base = VR4111_GIUIOSELL; diff -urN linux-2.4.21/arch/mips/vr41xx/common/icu.c linux-2.4.22/arch/mips/vr41xx/common/icu.c --- linux-2.4.21/arch/mips/vr41xx/common/icu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/icu.c 2003-08-25 04:44:40.000000000 -0700 @@ -54,21 +54,10 @@ #include #include -#define MIPS_CPU_IRQ_BASE 0 -#define SYSINT1_IRQ_BASE 8 -#define SYSINT1_IRQ_LAST 23 -#define SYSINT2_IRQ_BASE 24 -#define SYSINT2_IRQ_LAST 39 -#define GIUINT_IRQ_BASE GIU_IRQ(0) -#define GIUINT_IRQ_LAST GIU_IRQ(31) - -#define ICU_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 2) - extern asmlinkage void vr41xx_handle_interrupt(void); extern void __init init_generic_irq(void); extern void mips_cpu_irq_init(u32 irq_base); -extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void vr41xx_giuint_init(void); extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); @@ -224,15 +213,11 @@ /*=======================================================================*/ -extern void vr41xx_enable_giuint(u8 pin); -extern void vr41xx_disable_giuint(u8 pin); -extern void vr41xx_clear_giuint(u8 pin); - static void enable_giuint_irq(unsigned int irq) { - u8 pin; + int pin; - pin = irq - GIUINT_IRQ_BASE; + pin = irq - GIU_IRQ_BASE; if (pin < 16) set_icu1(MGIUINTLREG, (u16)1 << pin); else @@ -243,9 +228,9 @@ static void disable_giuint_irq(unsigned int irq) { - u8 pin; + int pin; - pin = irq - GIUINT_IRQ_BASE; + pin = irq - GIU_IRQ_BASE; vr41xx_disable_giuint(pin); if (pin < 16) @@ -256,7 +241,7 @@ static unsigned int startup_giuint_irq(unsigned int irq) { - vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE); + vr41xx_clear_giuint(irq - GIU_IRQ_BASE); enable_giuint_irq(irq); @@ -269,7 +254,7 @@ { disable_giuint_irq(irq); - vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE); + vr41xx_clear_giuint(irq - GIU_IRQ_BASE); } static void end_giuint_irq(unsigned int irq) @@ -297,7 +282,7 @@ { int i; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_icu1_base = VR4111_SYSINT1REG; @@ -319,12 +304,12 @@ write_icu2(0, MSYSINT2REG); write_icu2(0, MGIUINTHREG); - for (i = SYSINT1_IRQ_BASE; i <= GIUINT_IRQ_LAST; i++) { + for (i = SYSINT1_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST) irq_desc[i].handler = &sysint1_irq_type; else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST) irq_desc[i].handler = &sysint2_irq_type; - else if (i >= GIUINT_IRQ_BASE && i <= GIUINT_IRQ_LAST) + else if (i >= GIU_IRQ_BASE && i <= GIU_IRQ_LAST) irq_desc[i].handler = &giuint_irq_type; } @@ -343,7 +328,7 @@ set_except_vector(0, vr41xx_handle_interrupt); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("Setting debug traps - please connect the remote debugger.\n"); set_debug_traps(); breakpoint(); diff -urN linux-2.4.21/arch/mips/vr41xx/common/ide.c linux-2.4.22/arch/mips/vr41xx/common/ide.c --- linux-2.4.21/arch/mips/vr41xx/common/ide.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/ide.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,50 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * IDE routines for NEC VR4100 series standard configurations. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + * Copyright (C) 2003 Yoichi Yuasa + */ +#include +#include + +#include + +static int vr41xx_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t vr41xx_ide_default_io_base(int index) +{ + return 0; +} + +static void vr41xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +struct ide_ops vr41xx_ide_ops = { + .ide_default_irq = &vr41xx_ide_default_irq, + .ide_default_io_base = &vr41xx_ide_default_io_base, + .ide_init_hwif_ports = &vr41xx_ide_init_hwif_ports +}; diff -urN linux-2.4.21/arch/mips/vr41xx/common/pciu.c linux-2.4.22/arch/mips/vr41xx/common/pciu.c --- linux-2.4.21/arch/mips/vr41xx/common/pciu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/pciu.c 2003-08-25 04:44:40.000000000 -0700 @@ -262,7 +262,7 @@ /* Clear bus error */ n = readl(BUSERRADREG); - if (mips_cpu.cputype == CPU_VR4122) { + if (current_cpu_data.cputype == CPU_VR4122) { writel(0UL, PCITRDYVREG); pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804); } else { diff -urN linux-2.4.21/arch/mips/vr41xx/common/reset.c linux-2.4.22/arch/mips/vr41xx/common/reset.c --- linux-2.4.21/arch/mips/vr41xx/common/reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/reset.c 2003-08-25 04:44:40.000000000 -0700 @@ -18,10 +18,10 @@ void vr41xx_restart(char *command) { - change_cp0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL)); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + change_c0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL)); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21/arch/mips/vr41xx/common/serial.c linux-2.4.22/arch/mips/vr41xx/common/serial.c --- linux-2.4.21/arch/mips/vr41xx/common/serial.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/serial.c 2003-08-25 04:44:40.000000000 -0700 @@ -67,7 +67,6 @@ #define SIU_BASE_BAUD 1152000 #define SIU_CLOCK 0x0102 -#define SIU_IRQ 17 /* VR4122 and VR4131 DSIU Registers */ #define DSIURB KSEG1ADDR(0x0f000820) @@ -77,7 +76,6 @@ #define DSIU_BASE_BAUD 1152000 #define DSIU_CLOCK 0x0802 -#define DSIU_IRQ 29 int vr41xx_serial_ports = 0; @@ -101,7 +99,7 @@ val |= USE_IRDA | SIU_USES_IRDA; } - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: writew(val, VR4111_SIUIRSEL); @@ -128,7 +126,7 @@ s.baud_base = SIU_BASE_BAUD; s.irq = SIU_IRQ; s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: s.iomem_base = (unsigned char *)VR4111_SIURB; @@ -155,7 +153,8 @@ { struct serial_struct s; - if (mips_cpu.cputype != CPU_VR4122 && mips_cpu.cputype != CPU_VR4131) + if (current_cpu_data.cputype != CPU_VR4122 && + current_cpu_data.cputype != CPU_VR4131) return; memset(&s, 0, sizeof(s)); diff -urN linux-2.4.21/arch/mips/vr41xx/common/time.c linux-2.4.22/arch/mips/vr41xx/common/time.c --- linux-2.4.21/arch/mips/vr41xx/common/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -48,8 +48,7 @@ #include #include #include - -#define MIPS_COUNTER_TIMER_IRQ 7 +#include #define VR4111_ETIMELREG KSEG1ADDR(0x0b0000c0) #define VR4122_ETIMELREG KSEG1ADDR(0x0f000100) @@ -63,7 +62,7 @@ void vr41xx_time_init(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_rtc_base = VR4111_ETIMELREG; @@ -87,8 +86,8 @@ { u32 count; - setup_irq(MIPS_COUNTER_TIMER_IRQ, irq); + setup_irq(MIPS_COUNTER_IRQ, irq); - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register (CP0_COMPARE, count + (mips_counter_frequency / HZ)); + count = read_c0_count(); + write_c0_compare(count + (mips_counter_frequency / HZ)); } diff -urN linux-2.4.21/arch/mips/vr41xx/common/vrc4173.c linux-2.4.22/arch/mips/vr41xx/common/vrc4173.c --- linux-2.4.21/arch/mips/vr41xx/common/vrc4173.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/common/vrc4173.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,279 @@ +/* + * FILE NAME + * drivers/char/vrc4173.c + * + * BRIEF MODULE DESCRIPTION + * NEC VRC4173 driver for NEC VR4122/VR4131. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_DESCRIPTION("NEC VRC4173 driver for NEC VR4122/4131"); +MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_LICENSE("GPL"); + +#define VRC4173_CMUCLKMSK 0x040 +#define VRC4173_CMUSRST 0x042 + +#define VRC4173_SELECTREG 0x09e + +#define VRC4173_SYSINT1REG 0x060 +#define VRC4173_MSYSINT1REG 0x06c + +static struct pci_device_id vrc4173_table[] __devinitdata = { + {PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC4173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0, } +}; + +unsigned long vrc4173_io_offset = 0; + +EXPORT_SYMBOL(vrc4173_io_offset); + +static u16 vrc4173_cmuclkmsk; +static int vrc4173_initialized; + +void vrc4173_clock_supply(u16 mask) +{ + if (vrc4173_initialized) { + vrc4173_cmuclkmsk |= mask; + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + } +} + +void vrc4173_clock_mask(u16 mask) +{ + if (vrc4173_initialized) { + vrc4173_cmuclkmsk &= ~mask; + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + } +} + +static inline void vrc4173_cmu_init(void) +{ + vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK); +} + +EXPORT_SYMBOL(vrc4173_clock_supply); +EXPORT_SYMBOL(vrc4173_clock_mask); + +void vrc4173_select_function(int func) +{ + u16 val; + + if (vrc4173_initialized) { + val = vrc4173_inw(VRC4173_SELECTREG); + switch(func) { + case PS2CH1_SELECT: + val |= 0x0004; + break; + case PS2CH2_SELECT: + val |= 0x0002; + break; + case TOUCHPANEL_SELECT: + val &= 0x0007; + break; + case KIU8_SELECT: + val &= 0x000e; + break; + case KIU10_SELECT: + val &= 0x000c; + break; + case KIU12_SELECT: + val &= 0x0008; + break; + case GPIO_SELECT: + val |= 0x0008; + break; + } + vrc4173_outw(val, VRC4173_SELECTREG); + } +} + +EXPORT_SYMBOL(vrc4173_select_function); + +static void enable_vrc4173_irq(unsigned int irq) +{ + u16 val; + + val = vrc4173_inw(VRC4173_MSYSINT1REG); + val |= (u16)1 << (irq - VRC4173_IRQ_BASE); + vrc4173_outw(val, VRC4173_MSYSINT1REG); +} + +static void disable_vrc4173_irq(unsigned int irq) +{ + u16 val; + + val = vrc4173_inw(VRC4173_MSYSINT1REG); + val &= ~((u16)1 << (irq - VRC4173_IRQ_BASE)); + vrc4173_outw(val, VRC4173_MSYSINT1REG); +} + +static unsigned int startup_vrc4173_irq(unsigned int irq) +{ + enable_vrc4173_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_vrc4173_irq disable_vrc4173_irq +#define ack_vrc4173_irq disable_vrc4173_irq + +static void end_vrc4173_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_vrc4173_irq(irq); +} + +static struct hw_interrupt_type vrc4173_irq_type = { + "VRC4173", + startup_vrc4173_irq, + shutdown_vrc4173_irq, + enable_vrc4173_irq, + disable_vrc4173_irq, + ack_vrc4173_irq, + end_vrc4173_irq, + NULL +}; + +static int vrc4173_get_irq_number(int irq) +{ + u16 status, mask; + int i; + + status = vrc4173_inw(VRC4173_SYSINT1REG); + mask = vrc4173_inw(VRC4173_MSYSINT1REG); + + status &= mask; + if (status) { + for (i = 0; i < 16; i++) + if (status & (0x0001 << i)) + return VRC4173_IRQ_BASE + i; + } + + return -EINVAL; +} + +static inline void vrc4173_icu_init(int cascade_irq) +{ + int i; + + if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15)) + return; + + vrc4173_outw(0, VRC4173_MSYSINT1REG); + + vr41xx_set_irq_trigger(cascade_irq - GIU_IRQ(0), TRIGGER_LEVEL, SIGNAL_THROUGH); + vr41xx_set_irq_level(cascade_irq - GIU_IRQ(0), LEVEL_LOW); + + for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) + irq_desc[i].handler = &vrc4173_irq_type; +} + +static int __devinit vrc4173_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + unsigned long start, flags; + int err; + + if ((err = pci_enable_device(pdev)) < 0) { + printk(KERN_ERR "vrc4173: failed to enable device -- err=%d\n", err); + return err; + } + + pci_set_master(pdev); + + start = pci_resource_start(pdev, 0); + if (!start) { + printk(KERN_ERR "vrc4173:No PCI I/O resources, aborting\n"); + return -ENODEV; + } + + if (!start || (((flags = pci_resource_flags(pdev, 0)) & IORESOURCE_IO) == 0)) { + printk(KERN_ERR "vrc4173: No PCI I/O resources, aborting\n"); + return -ENODEV; + } + + if ((err = pci_request_regions(pdev, "NEC VRC4173")) < 0) { + printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n"); + return err; + } + + set_vrc4173_io_offset(start); + + vrc4173_cmu_init(); + + vrc4173_icu_init(pdev->irq); + + if ((err = vr41xx_cascade_irq(pdev->irq, vrc4173_get_irq_number)) < 0) { + printk(KERN_ERR + "vrc4173: IRQ resource %d is busy, aborting\n", pdev->irq); + return err; + } + + printk(KERN_INFO + "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, pdev->irq); + + return 0; +} + +static struct pci_driver vrc4173_driver = { + name: "NEC VRC4173", + probe: vrc4173_probe, + remove: NULL, + id_table: vrc4173_table, +}; + +static int __devinit vrc4173_init(void) +{ + int err; + + if ((err = pci_module_init(&vrc4173_driver)) < 0) + return err; + + vrc4173_initialized = 1; + + return 0; +} + +static void __devexit vrc4173_exit(void) +{ + vrc4173_initialized = 0; + + pci_unregister_driver(&vrc4173_driver); +} + +module_init(vrc4173_init); +module_exit(vrc4173_exit); diff -urN linux-2.4.21/arch/mips/vr41xx/ibm-workpad/Makefile linux-2.4.22/arch/mips/vr41xx/ibm-workpad/Makefile --- linux-2.4.21/arch/mips/vr41xx/ibm-workpad/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/ibm-workpad/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,17 @@ +# +# Makefile for the IBM WorkPad z50 specific parts of the kernel +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := workpad.o + +all: workpad.o + +obj-y := init.o setup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/ibm-workpad/ide-workpad.c linux-2.4.22/arch/mips/vr41xx/ibm-workpad/ide-workpad.c --- linux-2.4.21/arch/mips/vr41xx/ibm-workpad/ide-workpad.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/ibm-workpad/ide-workpad.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,98 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * IDE routines for typical pc-like standard configurations for the IBM WorkPad z50. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa Sun, 24 Feb 2002 + * - Added IBM WorkPad z50 support. + */ +#include +#include +#include +#include +#include +#include + +static int workpad_ide_default_irq(ide_ioreg_t base) +{ + return 49; +} + +static ide_ioreg_t workpad_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + case 4: return 0x1e0; + case 5: return 0x160; + } + return 0; +} + +static void workpad_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int workpad_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, SA_SHIRQ, device, dev_id); +} + +static void workpad_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int workpad_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void workpad_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void workpad_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops workpad_ide_ops = { + &workpad_ide_default_irq, + &workpad_ide_default_io_base, + &workpad_ide_init_hwif_ports, + &workpad_ide_request_irq, + &workpad_ide_free_irq, + &workpad_ide_check_region, + &workpad_ide_request_region, + &workpad_ide_release_region +}; diff -urN linux-2.4.21/arch/mips/vr41xx/ibm-workpad/init.c linux-2.4.22/arch/mips/vr41xx/ibm-workpad/init.c --- linux-2.4.21/arch/mips/vr41xx/ibm-workpad/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/ibm-workpad/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,49 @@ +/* + * FILE NAME + * arch/mips/vr41xx/ibm-workpad/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the IBM WorkPad z50. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "IBM WorkPad z50"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_IBM_WORKPAD; +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21/arch/mips/vr41xx/ibm-workpad/setup.c linux-2.4.22/arch/mips/vr41xx/ibm-workpad/setup.c --- linux-2.4.21/arch/mips/vr41xx/ibm-workpad/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/ibm-workpad/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,65 @@ +/* + * FILE NAME + * arch/mips/vr41xx/workpad/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the IBM WorkPad z50. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +void __init ibm_workpad_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); +} diff -urN linux-2.4.21/arch/mips/vr41xx/nec-eagle/Makefile linux-2.4.22/arch/mips/vr41xx/nec-eagle/Makefile --- linux-2.4.21/arch/mips/vr41xx/nec-eagle/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/nec-eagle/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -19,7 +19,6 @@ obj-y := init.o irq.o setup.o -obj-$(CONFIG_IDE) += ide-eagle.o -obj-$(CONFIG_PCI) += pci_fixup.o +obj-$(CONFIG_PCI) += pci_fixup.o vrc4173.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/nec-eagle/init.c linux-2.4.22/arch/mips/vr41xx/nec-eagle/init.c --- linux-2.4.21/arch/mips/vr41xx/nec-eagle/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/nec-eagle/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -52,10 +52,6 @@ return "NEC Eagle/Hawk"; } -void __init bus_error_init(void) -{ -} - void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { int i; diff -urN linux-2.4.21/arch/mips/vr41xx/nec-eagle/irq.c linux-2.4.22/arch/mips/vr41xx/nec-eagle/irq.c --- linux-2.4.21/arch/mips/vr41xx/nec-eagle/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/nec-eagle/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -164,9 +164,6 @@ writeb(0, NEC_EAGLE_SDBINTMSK); writeb(0, NEC_EAGLE_PCIINTMSKREG); - vr41xx_set_irq_trigger(VRC4173_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(VRC4173_PIN, LEVEL_LOW); - vr41xx_set_irq_trigger(PCISLOT_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); vr41xx_set_irq_level(PCISLOT_PIN, LEVEL_HIGH); diff -urN linux-2.4.21/arch/mips/vr41xx/nec-eagle/pci_fixup.c linux-2.4.22/arch/mips/vr41xx/nec-eagle/pci_fixup.c --- linux-2.4.21/arch/mips/vr41xx/nec-eagle/pci_fixup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/nec-eagle/pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -47,9 +47,7 @@ #include #include -#ifdef CONFIG_VRC4173 #include -#endif void __init pcibios_fixup_resources(struct pci_dev *dev) { @@ -119,41 +117,44 @@ break; } break; -#ifdef CONFIG_VRC4173 case 12: - dev->irq = VRC4173_CARDU1_IRQ; + dev->irq = VRC4173_PCMCIA1_IRQ; break; case 13: - dev->irq = VRC4173_CARDU2_IRQ; + dev->irq = VRC4173_PCMCIA2_IRQ; break; - case 24: - dev->irq = VRC4173_CARDU1_IRQ; - break; - case 25: - dev->irq = VRC4173_CARDU2_IRQ; - break; -#endif case 28: dev->irq = LANINTA_IRQ; break; case 29: - dev->irq = PCISLOT_IRQ; + switch (pin) { + case 1: + dev->irq = PCISLOT_IRQ; + break; + case 2: + dev->irq = CP_INTB_IRQ; + break; + case 3: + dev->irq = CP_INTC_IRQ; + break; + case 4: + dev->irq = CP_INTD_IRQ; + break; + } break; -#ifdef CONFIG_VRC4173 case 30: switch (func) { case 0: - dev->irq = VRC4173_IRQ; + dev->irq = VRC4173_CASCADE_IRQ; break; case 1: - dev->irq = VRC4173_AC97U_IRQ; + dev->irq = VRC4173_AC97_IRQ; break; case 2: - dev->irq = VRC4173_USBU_IRQ; + dev->irq = VRC4173_USB_IRQ; break; } break; -#endif } pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); diff -urN linux-2.4.21/arch/mips/vr41xx/nec-eagle/setup.c linux-2.4.22/arch/mips/vr41xx/nec-eagle/setup.c --- linux-2.4.21/arch/mips/vr41xx/nec-eagle/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/nec-eagle/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -55,13 +55,12 @@ extern void * __rd_start, * __rd_end; #endif -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops eagle_ide_ops; -#endif - extern void eagle_irq_init(void); #ifdef CONFIG_PCI + +extern void vrc4173_preinit(void); + static struct resource vr41xx_pci_io_resource = { "PCI I/O space", VR41XX_PCI_IO_START, @@ -135,22 +134,22 @@ conswitchp = &dummy_con; #endif -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &eagle_ide_ops; +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; #endif vr41xx_bcu_init(); vr41xx_cmu_init(0); +#ifdef CONFIG_SERIAL vr41xx_dsiu_init(); vr41xx_siu_init(SIU_RS232C, 0); +#endif #ifdef CONFIG_PCI vr41xx_pciu_init(&pci_address_map); -#endif -#ifdef CONFIG_VRC4173 - vrc4173_init(); + vrc4173_preinit(); #endif } diff -urN linux-2.4.21/arch/mips/vr41xx/nec-eagle/vrc4173.c linux-2.4.22/arch/mips/vr41xx/nec-eagle/vrc4173.c --- linux-2.4.21/arch/mips/vr41xx/nec-eagle/vrc4173.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/nec-eagle/vrc4173.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,126 @@ +/* + * FILE NAME + * arch/mips/vr41xx/nec-eagle/vrc4173.c + * + * BRIEF MODULE DESCRIPTION + * Pre-setup for NEC VRC4173. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include + +#ifdef CONFIG_PCI +#include +#include +#include + +#include +#include +#include + +#define PCI_CONFIG_ADDR KSEG1ADDR(0x0f000c18) +#define PCI_CONFIG_DATA KSEG1ADDR(0x0f000c14) + +static inline void config_writeb(u8 reg, u8 val) +{ + u32 data; + int shift; + + writel((1UL << 0x1e) | (reg & 0xfc), PCI_CONFIG_ADDR); + data = readl(PCI_CONFIG_DATA); + + shift = (reg & 3) << 3; + data &= ~(0xff << shift); + data |= (((u32)val) << shift); + + writel(data, PCI_CONFIG_DATA); +} + +static inline u16 config_readw(u8 reg) +{ + u32 data; + + writel(((1UL << 30) | (reg & 0xfc)) , PCI_CONFIG_ADDR); + data = readl(PCI_CONFIG_DATA); + + return (u16)(data >> ((reg & 2) << 3)); +} + +static inline u32 config_readl(u8 reg) +{ + writel(((1UL << 30) | (reg & 0xfc)) , PCI_CONFIG_ADDR); + + return readl(PCI_CONFIG_DATA); +} + +static inline void config_writel(u8 reg, u32 val) +{ + writel((1UL << 0x1e) | (reg & 0xfc), PCI_CONFIG_ADDR); + writel(val, PCI_CONFIG_DATA); +} + +void __init vrc4173_preinit(void) +{ + u32 cmdsts, base; + u16 cmu_mask; + + + if ((config_readw(PCI_VENDOR_ID) == PCI_VENDOR_ID_NEC) && + (config_readw(PCI_DEVICE_ID) == PCI_DEVICE_ID_NEC_VRC4173)) { + /* + * Initialized NEC VRC4173 Bus Control Unit + */ + cmdsts = config_readl(PCI_COMMAND); + config_writel(PCI_COMMAND, + cmdsts | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + + config_writeb(PCI_LATENCY_TIMER, 0x80); + + config_writel(PCI_BASE_ADDRESS_0, VR41XX_PCI_IO_START); + base = config_readl(PCI_BASE_ADDRESS_0); + base &= PCI_BASE_ADDRESS_IO_MASK; + config_writeb(0x40, 0x01); + + /* CARDU1 IDSEL = AD12, CARDU2 IDSEL = AD13 */ + config_writeb(0x41, 0); + + cmu_mask = 0x1000; + outw(cmu_mask, base + 0x040); + cmu_mask |= 0x0800; + outw(cmu_mask, base + 0x040); + + outw(0x000f, base + 0x042); /* Soft reset of CMU */ + cmu_mask |= 0x05e0; + outw(cmu_mask, base + 0x040); + cmu_mask = inw(base + 0x040); /* dummy read */ + outw(0x0000, base + 0x042); + } +} + +#endif diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/Makefile linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/Makefile --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,19 @@ +# +# Makefile for the TANBAC TB0226 specific parts of the kernel +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := tb0226.o + +all: tb0226.o + +obj-y := init.o setup.o + +obj-$(CONFIG_PCI) += pci_fixup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/init.c linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/init.c --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,64 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the TANBAC TB0226. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "TANBAC TB0226"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + u32 config; + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_TANBAC_TB0226; + + switch (current_cpu_data.processor_id) { + case PRID_VR4131_REV1_2: + config = read_c0_config(); + config &= ~0x00000030UL; + config |= 0x00410000UL; + write_c0_config(config); + break; + default: + break; + } +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,87 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The TANBAC TB0226 specific PCI fixups. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev; + u8 slot, pin; + + pci_for_each_dev(dev) { + slot = PCI_SLOT(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(GD82559_1_PIN, TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); + dev->irq = GD82559_1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(GD82559_2_PIN, TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); + dev->irq = GD82559_2_IRQ; + break; + case 14: + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + switch (pin) { + case 1: + vr41xx_set_irq_trigger(UPD720100_INTA_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTA_PIN, LEVEL_LOW); + dev->irq = UPD720100_INTA_IRQ; + break; + case 2: + vr41xx_set_irq_trigger(UPD720100_INTB_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTB_PIN, LEVEL_LOW); + dev->irq = UPD720100_INTB_IRQ; + break; + case 3: + vr41xx_set_irq_trigger(UPD720100_INTC_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTC_PIN, LEVEL_LOW); + dev->irq = UPD720100_INTC_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/setup.c linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/setup.c --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0226/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0226/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,112 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the TANBAC TB0226. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + "PCI I/O space", + VR41XX_PCI_IO_START, + VR41XX_PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource vr41xx_pci_mem_resource = { + "PCI memory space", + VR41XX_PCI_MEM_START, + VR41XX_PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256}, + {NULL, NULL, NULL, 0, 0} +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + VR41XX_PCI_MEM1_BASE, + VR41XX_PCI_MEM1_MASK, + IO_MEM1_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + VR41XX_PCI_MEM2_BASE, + VR41XX_PCI_MEM2_MASK, + IO_MEM2_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + VR41XX_PCI_IO_BASE, + VR41XX_PCI_IO_MASK, + IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + &vr41xx_pci_mem1, + &vr41xx_pci_mem2, + &vr41xx_pci_io +}; +#endif + +void __init tanbac_tb0226_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/Makefile linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/Makefile --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,19 @@ +# +# Makefile for the TANBAC TB0229(VR4131DIMM) specific parts of the kernel +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := tb0229.o + +all: tb0229.o + +obj-y := init.o setup.o reboot.o + +obj-$(CONFIG_PCI) += pci_fixup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/init.c linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/init.c --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,69 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the TANBAC TB0229(VR4131DIMM) + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * Modified for TANBAC TB0229: + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "TANBAC TB0229"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + u32 config; + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_TANBAC_TB0229; + + switch (current_cpu_data.processor_id) { + case PRID_VR4131_REV1_2: + config = read_c0_config(); + config &= ~0x00000030UL; + config |= 0x00410000UL; + write_c0_config(config); + break; + default: + break; + } +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,71 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The TANBAC TB0229(VR4131DIMM) specific PCI fixups. + * + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ +#ifdef CONFIG_TANBAC_TB0219 + struct pci_dev *dev; + u8 slot; + + pci_for_each_dev(dev) { + slot = PCI_SLOT(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN , TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN , TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT2_IRQ; + break; + case 14: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN , TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT3_IRQ; + break; + default: + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +#endif +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/reboot.c linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/reboot.c --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/reboot.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/reboot.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,30 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/reboot.c + * + * BRIEF MODULE DESCRIPTION + * Depending on TANBAC TB0229(VR4131DIMM) of reboot system call. + * + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#define tb0229_hard_reset() writew(0, TB0219_RESET_REGS) + +void tanbac_tb0229_restart(char *command) +{ +#ifdef CONFIG_TANBAC_TB0219 + local_irq_disable(); + tb0229_hard_reset(); + while (1); +#else + vr41xx_restart(command); +#endif +} diff -urN linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/setup.c linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/setup.c --- linux-2.4.21/arch/mips/vr41xx/tanbac-tb0229/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/tanbac-tb0229/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,126 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the TANBAC TB0229 (VR4131DIMM) + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * Modified for TANBAC TB0229: + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + .name = "PCI I/O space", + .start = VR41XX_PCI_IO_START, + .end = VR41XX_PCI_IO_END, + .flags = IORESOURCE_IO, +}; + +static struct resource vr41xx_pci_mem_resource = { + .name = "PCI memory space", + .start = VR41XX_PCI_MEM_START, + .end = VR41XX_PCI_MEM_END, + .flags = IORESOURCE_MEM, +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + { .pci_ops = &vr41xx_pci_ops, + .io_resource = &vr41xx_pci_io_resource, + .mem_resource = &vr41xx_pci_mem_resource, + .first_devfn = 0, + .last_devfn = 256, }, + { .pci_ops = NULL, + .io_resource = NULL, + .mem_resource = NULL, + .first_devfn = 0, + .last_devfn = 0, } +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + .internal_base = VR41XX_PCI_MEM1_BASE, + .address_mask = VR41XX_PCI_MEM1_MASK, + .pci_base = IO_MEM1_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + .internal_base = VR41XX_PCI_MEM2_BASE, + .address_mask = VR41XX_PCI_MEM2_MASK, + .pci_base = IO_MEM2_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + .internal_base = VR41XX_PCI_IO_BASE, + .address_mask = VR41XX_PCI_IO_MASK, + .pci_base = IO_PORT_RESOURCE_START, +}; + +static struct vr41xx_pci_address_map pci_address_map = { + .mem1 = &vr41xx_pci_mem1, + .mem2 = &vr41xx_pci_mem2, + .io = &vr41xx_pci_io, +}; +#endif + +void __init tanbac_tb0229_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = tanbac_tb0229_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + vr41xx_dsiu_init(); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} + diff -urN linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/Makefile linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/Makefile --- linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,19 @@ +# +# Makefile for the Victor MP-C303/304 specific parts of the kernel +# +# 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). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := mpc30x.o + +all: mpc30x.o + +obj-y := init.o setup.o + +obj-$(CONFIG_PCI) += pci_fixup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c --- linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * IDE routines for typical pc-like standard configurations + * for the ZAO Networks Capcella. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa Fri, 23 Aug 2002 + * - Added Victor MP-C303/304 support. + */ +#include +#include +#include +#include +#include +#include + +static int mpc30x_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t mpc30x_ide_default_io_base(int index) +{ + return 0; +} + +static void mpc30x_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int mpc30x_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void mpc30x_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int mpc30x_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void mpc30x_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void mpc30x_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops mpc30x_ide_ops = { + &mpc30x_ide_default_irq, + &mpc30x_ide_default_io_base, + &mpc30x_ide_init_hwif_ports, + &mpc30x_ide_request_irq, + &mpc30x_ide_free_irq, + &mpc30x_ide_check_region, + &mpc30x_ide_request_region, + &mpc30x_ide_release_region +}; diff -urN linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/init.c linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/init.c --- linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,54 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the Victor MP-C303/304. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "Victor MP-C303/304"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_VICTOR_MPC30X; + + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c --- linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The Victor MP-C303/304 specific PCI fixups. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include +#include + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev; + u8 slot, func; + + pci_for_each_dev(dev) { + slot = PCI_SLOT(dev->devfn); + func = PCI_FUNC(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: /* NEC VRC4173 CARDU1 */ + dev->irq = VRC4173_PCMCIA1_IRQ; + break; + case 13: /* NEC VRC4173 CARDU2 */ + dev->irq = VRC4173_PCMCIA2_IRQ; + break; + case 29: /* mediaQ MQ-200 */ + dev->irq = MQ200_IRQ; + break; + case 30: + switch (func) { + case 0: /* NEC VRC4173 */ + dev->irq = VRC4173_CASCADE_IRQ; + break; + case 1: /* NEC VRC4173 AC97U */ + dev->irq = VRC4173_AC97_IRQ; + break; + case 2: /* NEC VRC4173 USBU */ + dev->irq = VRC4173_USB_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -urN linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/setup.c linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/setup.c --- linux-2.4.21/arch/mips/vr41xx/victor-mpc30x/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/victor-mpc30x/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,117 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the Victor MP-C303/304. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + "PCI I/O space", + VR41XX_PCI_IO_START, + VR41XX_PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource vr41xx_pci_mem_resource = { + "PCI memory space", + VR41XX_PCI_MEM_START, + VR41XX_PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256}, + {NULL, NULL, NULL, 0, 0} +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + VR41XX_PCI_MEM1_BASE, + VR41XX_PCI_MEM1_MASK, + IO_MEM1_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + VR41XX_PCI_MEM2_BASE, + VR41XX_PCI_MEM2_MASK, + IO_MEM2_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + VR41XX_PCI_IO_BASE, + VR41XX_PCI_IO_MASK, + IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + &vr41xx_pci_mem1, + &vr41xx_pci_mem2, + &vr41xx_pci_io +}; +#endif + +void __init victor_mpc30x_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} diff -urN linux-2.4.21/arch/mips/vr41xx/zao-capcella/Makefile linux-2.4.22/arch/mips/vr41xx/zao-capcella/Makefile --- linux-2.4.21/arch/mips/vr41xx/zao-capcella/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/zao-capcella/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -14,7 +14,6 @@ obj-y := init.o setup.o -obj-$(CONFIG_IDE) += ide-capcella.o obj-$(CONFIG_PCI) += pci_fixup.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips/vr41xx/zao-capcella/init.c linux-2.4.22/arch/mips/vr41xx/zao-capcella/init.c --- linux-2.4.21/arch/mips/vr41xx/zao-capcella/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/zao-capcella/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -30,10 +30,6 @@ return "ZAO Networks Capcella"; } -void __init bus_error_init(void) -{ -} - void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { u32 config; @@ -51,12 +47,12 @@ mips_machgroup = MACH_GROUP_NEC_VR41XX; mips_machtype = MACH_ZAO_CAPCELLA; - switch (mips_cpu.processor_id) { + switch (current_cpu_data.processor_id) { case PRID_VR4131_REV1_2: - config = read_32bit_cp0_register(CP0_CONFIG); + config = read_c0_config(); config &= ~0x00000030UL; config |= 0x00410000UL; - write_32bit_cp0_register(CP0_CONFIG, config); + write_c0_config(config); break; default: break; diff -urN linux-2.4.21/arch/mips/vr41xx/zao-capcella/setup.c linux-2.4.22/arch/mips/vr41xx/zao-capcella/setup.c --- linux-2.4.21/arch/mips/vr41xx/zao-capcella/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips/vr41xx/zao-capcella/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,10 +29,6 @@ extern void * __rd_start, * __rd_end; #endif -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops capcella_ide_ops; -#endif - #ifdef CONFIG_PCI static struct resource vr41xx_pci_io_resource = { "PCI I/O space", @@ -105,8 +101,8 @@ conswitchp = &dummy_con; #endif -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &capcella_ide_ops; +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; #endif vr41xx_bcu_init(); @@ -114,6 +110,7 @@ vr41xx_cmu_init(0x0102); vr41xx_siu_init(SIU_RS232C, 0); + vr41xx_dsiu_init(); #ifdef CONFIG_PCI vr41xx_pciu_init(&pci_address_map); diff -urN linux-2.4.21/arch/mips64/Makefile linux-2.4.22/arch/mips64/Makefile --- linux-2.4.21/arch/mips64/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -39,9 +39,14 @@ LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG +ifdef CONFIG_KGDB GCCFLAGS += -g +ifdef CONFIG_SB1XXX_CORELIS +GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer endif +endif + +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) # # CPU-dependent compiler/assembler options for optimization. @@ -58,6 +63,10 @@ ifdef CONFIG_CPU_NEVADA GCCFLAGS += -mcpu=r8000 -mips3 -mmad endif +ifdef CONFIG_CPU_RM7000 +GCCFLAGS += $(call check_gcc, -march=rm7000, -mcpu=r5000) \ + -mips2 -Wa,--trap +endif ifdef CONFIG_CPU_R8000 GCCFLAGS += -mcpu=r8000 -mips4 endif @@ -65,7 +74,10 @@ GCCFLAGS += -mcpu=r8000 -mips4 endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call check_gcc, -mcpu=sb1, -mcpu=r5000) -mips4 +ifdef CONFIG_SB1_PASS_1_WORKAROUNDS +MODFLAGS += -msb1-pass1-workarounds +endif endif ifdef CONFIG_CPU_MIPS64 #CFLAGS += -mips64 # Should be used then we get a MIPS64 compiler @@ -78,12 +90,42 @@ CORE_FILES += arch/mips/math-emu/fpu_emulator.o SUBDIRS += arch/mips/math-emu +# +# ramdisk/initrd support +# You need a compressed ramdisk image, named ramdisk.gz in +# arch/mips/ramdisk +# +ifdef CONFIG_EMBEDDED_RAMDISK +CORE_FILES += arch/mips/ramdisk/ramdisk.o +SUBDIRS += arch/mips/ramdisk +endif + # # Board-dependent options and extra files # # +# DECstation family +# +ifdef CONFIG_DECSTATION +CORE_FILES += arch/mips/dec/dec.o +SUBDIRS += arch/mips/dec arch/mips/dec/prom +LIBS += arch/mips/dec/prom/rexlib.a +LOADADDR := 0x80040000 +endif + +# +# Galileo EV64120 Board +# +ifdef CONFIG_MIPS_EV64120 +LIBS += arch/mips/gt64120/common/gt64120.o \ + arch/mips/gt64120/ev64120/ev64120.o +SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/ev64120 +LOADADDR := 0x80100000 +endif + +# # MIPS Atlas board # ifdef CONFIG_MIPS_ATLAS @@ -114,6 +156,45 @@ endif # +# Momentum Ocelot board +# +ifdef CONFIG_MOMENCO_OCELOT +# The Ocelot setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/gt64120/common/gt64120.o \ + arch/mips/gt64120/momenco_ocelot/momenco_ocelot.o +SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/momenco_ocelot +LOADADDR := 0x80100000 +endif + +# +# Momentum Ocelot-G board +# +ifdef CONFIG_MOMENCO_OCELOT_G +# The Ocelot-G setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/momentum/ocelot_g/ocelot_g.o +SUBDIRS += arch/mips/momentum/ocelot_g +LOADADDR := 0x80100000 +endif + +# +# Momentum Ocelot-C and -CS boards +# +ifdef CONFIG_MOMENCO_OCELOT_C +# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/momentum/ocelot_c/ocelot_c.o +SUBDIRS += arch/mips/momentum/ocelot_c +LOADADDR := 0x80100000 +endif + +ifdef CONFIG_PCI +CORE_FILES += arch/mips/pci/pci-core.o +SUBDIRS += arch/mips/pci +endif + +# # SGI IP22 (Indy/Indigo2) # ifdef CONFIG_SGI_IP22 @@ -149,38 +230,34 @@ endif # -# SGI-IP32 (O2) -# -ifdef CONFIG_SGI_IP32 -CORE_FILES += arch/mips/sgi-ip32/ip32-kern.a -LIBS += arch/mips/arc/arclib.a -SUBDIRS += arch/mips/sgi-ip32 arch/mips/arc -# -# Set LOADADDR to >= 0x????????? if you want to leave space for symmon, -# 0x80002000 for production kernels. Note that the value must be -# 16kb aligned or the handling of the current variable will break. -# -LOADADDR := 0x80002000 -endif - -# -# Sibyte SB1250 SOC +# Sibyte SB1250 SOC and Broadcom (SiByte) BCM112x SOCs # -ifdef CONFIG_SIBYTE_SB1250 +ifneq ($(CONFIG_SIBYTE_SB1250)$(CONFIG_SIBYTE_BCM112X),) # This is a LIB so that it links at the end, and initcalls are later # the sequence; but it is built as an object so that modules don't get # removed (as happens, even if they have __initcall/module_init) LIBS += arch/mips/sibyte/sb1250/sb1250.o SUBDIRS += arch/mips/sibyte/sb1250 +ifdef CONFIG_MIPS_UNCACHED +LOADADDR := 0xa0100000 +else +LOADADDR := 0x80100000 +endif endif # -# Sibyte SWARM board +# Sibyte boards: +# +# BCM91250A (SWARM), +# BCM91250E (Sentosa), +# BCM91120C (CRhine), +# BCM91120x (Carmel), +# BCM91125C (CRhone), +# BCM91125E (Rhone). # -ifdef CONFIG_SIBYTE_SWARM +ifdef CONFIG_SIBYTE_BOARD LIBS += arch/mips/sibyte/swarm/sbswarm.a SUBDIRS += arch/mips/sibyte/swarm -LOADADDR := 0x80100000 endif # @@ -192,21 +269,12 @@ endif # -# SB1 Cache Error handler -# -ifdef CONFIG_SB1_CACHE_ERROR -LIBS += arch/mips/sibyte/sb1/sb1kern.a -SUBDIRS += arch/mips/sibyte/sb1 -endif - - -# # Some machines like the Indy need 32-bit ELF binaries for booting purposes. # Other need ECOFF, so we build a 32-bit ELF binary for them which we then # convert to ECOFF using elf2ecoff. # ifdef CONFIG_BOOT_ELF32 -GCCFLAGS += -Wa,-32 +GCCFLAGS += -Wa,-32 $(shell if $(CC) -Wa,-mgp64 -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "-Wa,-mgp64"; fi) LINKFLAGS += -T arch/mips64/ld.script.elf32 endif # @@ -214,17 +282,27 @@ # ELF files from 32-bit files by conversion. # ifdef CONFIG_BOOT_ELF64 -GCCFLAGS += -Wa,-32 +GCCFLAGS += -Wa,-32 $(shell if $(CC) -Wa,-mgp64 -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "-Wa,-mgp64"; fi) LINKFLAGS += -T arch/mips64/ld.script.elf32 #AS += -64 #LD += -m elf64bmip #LINKFLAGS += -T arch/mips64/ld.script.elf64 endif +ifdef CONFIG_CPU_LITTLE_ENDIAN +32bit-bfd = elf32-tradlittlemips +64bit-bfd = elf64-tradlittlemips +else +32bit-bfd = elf32-tradbigmips +64bit-bfd = elf64-tradbigmips +endif + AFLAGS += $(GCCFLAGS) CFLAGS += $(GCCFLAGS) +LD += --oformat $(32bit-bfd) + LINKFLAGS += -Ttext $(LOADADDR) @@ -236,31 +314,20 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot -ifdef CONFIG_CPU_LITTLE_ENDIAN -64bit-bfd = elf64-littlemips -else -64bit-bfd = elf64-bigmips -endif - vmlinux: arch/mips64/ld.script.elf32 arch/mips64/ld.script.elf32: arch/mips64/ld.script.elf32.S $(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/asm-mips64/sn/mapped_kernel.h -Umips arch/mips64/ld.script.elf32.S > arch/mips64/ld.script.elf32 ifdef CONFIG_MAPPED_KERNEL vmlinux.64: vmlinux - $(OBJCOPY) -O $(64bit-bfd) --change-addresses=0xbfffffff40000000 $< $@ + $(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xbfffffff40000000 $< $@ else vmlinux.64: vmlinux - $(OBJCOPY) -O $(64bit-bfd) --change-addresses=0xa7ffffff80000000 $< $@ + $(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xa800000080000000 $< $@ endif -zImage: vmlinux - @$(MAKEBOOT) zImage - -compressed: zImage - -zdisk: vmlinux - @$(MAKEBOOT) zdisk +vmlinux.ecoff: vmlinux + @$(MAKEBOOT) $@ archclean: @$(MAKEBOOT) clean @@ -270,6 +337,7 @@ archmrproper: @$(MAKEBOOT) mrproper $(MAKE) -C arch/mips/tools mrproper + $(RM) $(TOPDIR)/include/asm-$(ARCH)/offset.h archdep: if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \ diff -urN linux-2.4.21/arch/mips64/boot/Makefile linux-2.4.22/arch/mips64/boot/Makefile --- linux-2.4.21/arch/mips64/boot/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips64/boot/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -22,11 +22,11 @@ vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux ./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS) -elf2ecoff: elf2ecoff.c - $(HOSTCC) -o $@ $^ +elf2ecoff: $(TOPDIR)/arch/mips/boot/elf2ecoff.c + $(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^ -addinitrd: addinitrd.c - $(HOSTCC) -o $@ $^ +addinitrd: $(TOPDIR)/arch/mips/boot/addinitrd.c + $(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^ # Don't build dependencies, this may die if $(CC) isn't gcc dep: diff -urN linux-2.4.21/arch/mips64/defconfig linux-2.4.22/arch/mips64/defconfig --- linux-2.4.21/arch/mips64/defconfig 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,20 +62,24 @@ # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -CONFIG_SMP=y -# CONFIG_SGI_IP32 is not set +CONFIG_SMP_CAPABLE=y # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF64=y CONFIG_ARC64=y +CONFIG_L1_CACHE_SHIFT=7 +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_QL_ISP_A64=y -CONFIG_L1_CACHE_SHIFT=7 # CONFIG_MIPS_AU1000 is not set # @@ -87,6 +101,7 @@ CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_SMP=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,7 +114,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set # CONFIG_MIPS_INSANE_LARGE is not set CONFIG_NET=y CONFIG_PCI_NAMES=y @@ -119,6 +133,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -261,6 +277,7 @@ # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -297,16 +314,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set +# CONFIG_SCSI_NSP32 is not set # # Network device support @@ -351,6 +359,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -433,13 +442,22 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_IP27_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -467,8 +485,8 @@ # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -578,9 +596,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # diff -urN linux-2.4.21/arch/mips64/defconfig-atlas linux-2.4.22/arch/mips64/defconfig-atlas --- linux-2.4.21/arch/mips64/defconfig-atlas 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-atlas 2003-08-25 04:44:40.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set CONFIG_MIPS_ATLAS=y # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,21 +56,27 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y # CONFIG_MIPS_AU1000 is not set # @@ -82,7 +98,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -95,7 +110,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set @@ -114,6 +128,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -269,6 +285,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -305,19 +322,10 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# # Network device support # CONFIG_NETDEVICES=y @@ -360,6 +368,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -445,13 +454,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -575,9 +592,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21/arch/mips64/defconfig-decstation linux-2.4.22/arch/mips64/defconfig-decstation --- linux-2.4.21/arch/mips64/defconfig-decstation 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-decstation 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,626 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +CONFIG_DECSTATION=y +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y +CONFIG_IRQ_CPU=y +CONFIG_L1_CACHE_SHIFT=4 +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +CONFIG_CPU_R4X00=y +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +CONFIG_TC=y +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_SCSI_DECNCR=y +# CONFIG_SCSI_DECSII is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set +CONFIG_DECLANCE=y + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_SERIAL_DEC=y +CONFIG_SERIAL_DEC_CONSOLE=y +# CONFIG_DZ is not set +CONFIG_ZS=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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 +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +CONFIG_ULTRIX_PARTITION=y +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Library routines +# +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips64/defconfig-ip22 linux-2.4.22/arch/mips64/defconfig-ip22 --- linux-2.4.21/arch/mips64/defconfig-ip22 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-ip22 2003-08-25 04:44:40.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +58,28 @@ # CONFIG_NINO is not set CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y -CONFIG_ARC_CONSOLE=y -CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y CONFIG_BOOT_ELF32=y -CONFIG_SWAP_IO_SPACE=y +# CONFIG_SWAP_IO_SPACE_W is not set +CONFIG_SWAP_IO_SPACE_L=y CONFIG_IRQ_CPU=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SGI=y # CONFIG_MIPS_AU1000 is not set # @@ -91,7 +101,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,7 +113,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_ARC_CONSOLE=y # CONFIG_IP22_EISA is not set CONFIG_NET=y @@ -125,9 +133,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -282,6 +291,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -310,6 +320,7 @@ # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -354,6 +365,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -411,7 +423,30 @@ CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_IP22_SERIAL=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -439,6 +474,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -447,6 +487,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -457,6 +498,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -464,8 +506,12 @@ # CONFIG_MACHZ_WDT is not set CONFIG_INDYDOG=y # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -478,13 +524,6 @@ # CONFIG_DRM is not set # -# SGI Character devices -# -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y - -# # File systems # # CONFIG_QUOTA is not set @@ -500,8 +539,8 @@ # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -532,7 +571,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set # CONFIG_UDF_RW is not set @@ -595,6 +634,9 @@ # Console drivers # # CONFIG_VGA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_DUMMY_CONSOLE=y # CONFIG_MDA_CONSOLE is not set # @@ -605,15 +647,31 @@ # # Sound # -# CONFIG_SOUND is not set - -# -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_HAL2=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -629,7 +687,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21/arch/mips64/defconfig-ip27 linux-2.4.22/arch/mips64/defconfig-ip27 --- linux-2.4.21/arch/mips64/defconfig-ip27 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-ip27 2003-08-25 04:44:40.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,20 +62,24 @@ # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -CONFIG_SMP=y -# CONFIG_SGI_IP32 is not set +CONFIG_SMP_CAPABLE=y # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF64=y CONFIG_ARC64=y +CONFIG_L1_CACHE_SHIFT=7 +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_QL_ISP_A64=y -CONFIG_L1_CACHE_SHIFT=7 # CONFIG_MIPS_AU1000 is not set # @@ -87,6 +101,7 @@ CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_SMP=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,7 +114,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set # CONFIG_MIPS_INSANE_LARGE is not set CONFIG_NET=y CONFIG_PCI_NAMES=y @@ -119,6 +133,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -261,6 +277,7 @@ # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -297,16 +314,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set +# CONFIG_SCSI_NSP32 is not set # # Network device support @@ -351,6 +359,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -433,13 +442,22 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_IP27_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -467,8 +485,8 @@ # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -578,9 +596,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # diff -urN linux-2.4.21/arch/mips64/defconfig-ip32 linux-2.4.22/arch/mips64/defconfig-ip32 --- linux-2.4.21/arch/mips64/defconfig-ip32 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-ip32 1969-12-31 16:00:00.000000000 -0800 @@ -1,609 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_MIPS=y -# CONFIG_MIPS32 is not set -CONFIG_MIPS64=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Machine selection -# -# CONFIG_ACER_PICA_61 is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set -# CONFIG_BAGET_MIPS is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_EV96100 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_HP_LASERJET is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MAGNUM_4000 is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_DDB5074 is not set -# CONFIG_DDB5476 is not set -# CONFIG_DDB5477 is not set -# CONFIG_NEC_OSPREY is not set -# CONFIG_NEC_EAGLE is not set -# CONFIG_OLIVETTI_M700 is not set -# CONFIG_NINO is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -CONFIG_SGI_IP32=y -# CONFIG_SIBYTE_SB1xxx_SOC is not set -# CONFIG_SNI_RM200_PCI is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_ZAO_CAPCELLA is not set -# CONFIG_HIGHMEM is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_ARC_MEMORY=y -CONFIG_ARC32=y -CONFIG_BOOT_ELF32=y -CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_PC_KEYB=y -CONFIG_PCI=y -# CONFIG_MIPS_AU1000 is not set - -# -# CPU selection -# -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -CONFIG_CPU_R5000=y -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y -# CONFIG_64BIT_PHYS_ADDR is not set -# CONFIG_CPU_ADVANCED is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_LLDSCD=y -# CONFIG_CPU_HAS_WB is not set -CONFIG_CPU_HAS_SYNC=y - -# -# General setup -# -# CONFIG_CPU_LITTLE_ENDIAN is not set -# CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set -CONFIG_ARC_CONSOLE=y -CONFIG_NET=y -CONFIG_PCI_NAMES=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_TC is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -# CONFIG_HOTPLUG_PCI is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -CONFIG_MIPS32_COMPAT=y -CONFIG_BINFMT_ELF32=y -CONFIG_BINFMT_MISC=y -# CONFIG_PM is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# 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_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_BLK_STATS is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y -CONFIG_CHR_DEV_OSST=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=2 -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_DEBUG_QUEUES=y -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_SGI_O2MACE_ETH=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set -# CONFIG_MK712_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks -# -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# 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 -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_MIPS_UNCACHED=y - -# -# Library routines -# -# CONFIG_ZLIB_INFLATE is not set -# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/mips64/defconfig-malta linux-2.4.22/arch/mips64/defconfig-malta --- linux-2.4.21/arch/mips64/defconfig-malta 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-malta 2003-08-25 04:44:40.000000000 -0700 @@ -13,23 +13,34 @@ # # Loadable module support # -# CONFIG_MODULES is not set +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y # # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,10 +58,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,11 +72,14 @@ CONFIG_BOOT_ELF32=y CONFIG_HAVE_STD_PC_SERIAL_PORT=y CONFIG_I8259=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_PC_KEYB=y CONFIG_PCI=y # CONFIG_MIPS_AU1000 is not set @@ -114,6 +132,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -176,8 +196,8 @@ # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -268,6 +288,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -304,19 +325,10 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# # Network device support # CONFIG_NETDEVICES=y @@ -359,6 +371,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -444,13 +457,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -523,13 +544,14 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y # CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -574,9 +596,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21/arch/mips64/defconfig-sb1250-swarm linux-2.4.22/arch/mips64/defconfig-sb1250-swarm --- linux-2.4.21/arch/mips64/defconfig-sb1250-swarm 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-sb1250-swarm 2003-08-25 04:44:40.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,27 +58,44 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set CONFIG_SIBYTE_SB1xxx_SOC=y +CONFIG_SIBYTE_SWARM=y +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_UNKNOWN is not set +CONFIG_SIBYTE_BOARD=y CONFIG_SIBYTE_SB1250=y -# CONFIG_SIMULATION is not set +CONFIG_CPU_SB1_PASS_1=y +# CONFIG_CPU_SB1_PASS_2 is not set +# CONFIG_CPU_SB1_PASS_2_2 is not set +# CONFIG_CPU_SB1_PASS_4 is not set CONFIG_SIBYTE_CFE=y # CONFIG_SIBYTE_CFE_CONSOLE is not set +# CONFIG_SIBYTE_BUS_WATCHER is not set # CONFIG_SIBYTE_SB1250_PROF is not set -# CONFIG_BCM1250_TBPROF is not set -CONFIG_SMP=y +# CONFIG_SIBYTE_TBPROF is not set # CONFIG_PCI is not set -CONFIG_SIBYTE_SWARM=y +CONFIG_SIBYTE_GENBUS_IDE=y +CONFIG_SMP_CAPABLE=y # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_DUMMY_KEYB=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_BOOT_ELF32=y # CONFIG_MIPS_AU1000 is not set @@ -91,14 +118,10 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set CONFIG_CPU_SB1=y -CONFIG_CPU_SB1_PASS_1=y -# CONFIG_CPU_SB1_PASS_2 is not set -# CONFIG_CPU_SB1_PASS_2_2 is not set +CONFIG_SMP=y +# CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_SB1_PASS_1_WORKAROUNDS=y CONFIG_CPU_HAS_PREFETCH=y -CONFIG_SB1_CACHE_ERROR=y -CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y -# CONFIG_SB1_CERR_SPIN is not set CONFIG_VTAG_ICACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set @@ -112,7 +135,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set @@ -130,8 +152,10 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y -# CONFIG_MIPS32_COMPAT is not set -# CONFIG_BINFMT_ELF32 is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -183,8 +207,9 @@ # # Networking options # -# CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y @@ -294,6 +319,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -370,12 +396,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set # CONFIG_TXX927_SERIAL is not set CONFIG_SIBYTE_SB1250_DUART=y CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y CONFIG_SERIAL_CONSOLE=y -CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE=1024 -# CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -403,13 +429,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -534,7 +568,10 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set # diff -urN linux-2.4.21/arch/mips64/defconfig-sead linux-2.4.22/arch/mips64/defconfig-sead --- linux-2.4.21/arch/mips64/defconfig-sead 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/defconfig-sead 2003-08-25 04:44:40.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ CONFIG_MIPS_SEAD=y # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,16 +56,19 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_PCI is not set @@ -109,6 +122,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -231,13 +246,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -348,9 +371,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21/arch/mips64/kernel/Makefile linux-2.4.22/arch/mips64/kernel/Makefile --- linux-2.4.21/arch/mips64/kernel/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -12,25 +12,30 @@ O_TARGET := kernel.o -export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o +export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o time.o obj-y := branch.o cpu-probe.o entry.o irq.o proc.o process.o \ ptrace.o r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o \ reset.o scall_64.o semaphore.o setup.o signal.o syscall.o \ - time.o traps.o unaligned.o + traps.o unaligned.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o +obj-$(CONFIG_NEW_TIME_C) += time.o obj-$(CONFIG_MODULES) += mips64_ksyms.o -obj-$(CONFIG_MIPS32_COMPAT) += linux32.o scall_o32.o signal32.o ioctl32.o -obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o +obj-$(CONFIG_MIPS32_COMPAT) += linux32.o signal32.o ioctl32.o +obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall_n32.o signal_n32.o +obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall_o32.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o + ifndef CONFIG_MAPPED_PCI_IO obj-y += pci-dma.o endif -AFLAGS_r4k_genex.o := -P +CFLAGS_cpu-probe.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) +AFLAGS_r4k_genex.o = -P include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips64/kernel/binfmt_elf32.c linux-2.4.22/arch/mips64/kernel/binfmt_elf32.c --- linux-2.4.21/arch/mips64/kernel/binfmt_elf32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/binfmt_elf32.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,118 +0,0 @@ -/* - * Support for 32-bit Linux/MIPS ELF binaries. - * - * Copyright (C) 1999, 2001 Ralf Baechle - * Copyright (C) 1999, 2001 Silicon Graphics, Inc. - * - * Heavily inspired by the 32-bit Sparc compat code which is - * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) - * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) - */ - -#define ELF_ARCH EM_MIPS -#define ELF_CLASS ELFCLASS32 -#ifdef __MIPSEB__ -#define ELF_DATA ELFDATA2MSB; -#else /* __MIPSEL__ */ -#define ELF_DATA ELFDATA2LSB; -#endif - -/* ELF register definitions */ -#define ELF_NGREG 45 -#define ELF_NFPREG 33 - -typedef unsigned int elf_greg_t; -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef double elf_fpreg_t; -typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(hdr) \ -({ \ - int __res = 1; \ - struct elfhdr *__h = (hdr); \ - \ - if (__h->e_machine != EM_MIPS) \ - __res = 0; \ - if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ - __res = 0; \ - if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ - __res = 0; \ - if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ - ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ - __res = 0; \ - \ - __res; \ -}) - -#define TASK32_SIZE 0x80000000UL -#undef ELF_ET_DYN_BASE -#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) - -#include -#include -#include -#include - -struct timeval32 -{ - int tv_sec, tv_usec; -}; - -#define elf_prstatus elf_prstatus32 -struct elf_prstatus32 -{ - struct elf_siginfo pr_info; /* Info associated with signal */ - short pr_cursig; /* Current signal */ - unsigned int pr_sigpend; /* Set of pending signals */ - unsigned int pr_sighold; /* Set of held signals */ - pid_t pr_pid; - pid_t pr_ppid; - pid_t pr_pgrp; - pid_t pr_sid; - struct timeval32 pr_utime; /* User time */ - struct timeval32 pr_stime; /* System time */ - struct timeval32 pr_cutime; /* Cumulative user time */ - struct timeval32 pr_cstime; /* Cumulative system time */ - elf_gregset_t pr_reg; /* GP registers */ - int pr_fpvalid; /* True if math co-processor being used. */ -}; - -#define elf_prpsinfo elf_prpsinfo32 -struct elf_prpsinfo32 -{ - char pr_state; /* numeric process state */ - char pr_sname; /* char for pr_state */ - char pr_zomb; /* zombie */ - char pr_nice; /* nice val */ - unsigned int pr_flag; /* flags */ - u16 pr_uid; - u16 pr_gid; - pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; - /* Lots missing */ - char pr_fname[16]; /* filename of executable */ - char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ -}; - -#define elf_addr_t u32 -#define elf_caddr_t u32 -#define init_elf_binfmt init_elf32_binfmt -#undef CONFIG_BINFMT_ELF -#ifdef CONFIG_BINFMT_ELF32 -#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 -#endif -#undef CONFIG_BINFMT_ELF_MODULE -#ifdef CONFIG_BINFMT_ELF32_MODULE -#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE -#endif - -MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux/MIPS binaries"); -MODULE_AUTHOR("Ralf Baechle (ralf@oss.sgi.com)"); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - -#include "../../../fs/binfmt_elf.c" diff -urN linux-2.4.21/arch/mips64/kernel/binfmt_elfn32.c linux-2.4.22/arch/mips64/kernel/binfmt_elfn32.c --- linux-2.4.21/arch/mips64/kernel/binfmt_elfn32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/binfmt_elfn32.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,119 @@ +/* + * Support for n32 Linux/MIPS ELF binaries. + * + * Copyright (C) 1999, 2001 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. + * + * Heavily inspired by the 32-bit Sparc compat code which is + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#define ELF_ARCH EM_MIPS +#define ELF_CLASS ELFCLASS32 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB; +#else /* __MIPSEL__ */ +#define ELF_DATA ELFDATA2LSB; +#endif + +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(hdr) \ +({ \ + int __res = 1; \ + struct elfhdr *__h = (hdr); \ + \ + if (__h->e_machine != EM_MIPS) \ + __res = 0; \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI2) == 0) || \ + ((__h->e_flags & EF_MIPS_ABI) != 0)) \ + __res = 0; \ + \ + __res; \ +}) + +#define TASK32_SIZE 0x7fff8000UL +#undef ELF_ET_DYN_BASE +#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + +#include +#include +#include +#include + +struct timeval32 +{ + int tv_sec, tv_usec; +}; + +#define elf_prstatus elf_prstatus32 +struct elf_prstatus32 +{ + struct elf_siginfo pr_info; /* Info associated with signal */ + short pr_cursig; /* Current signal */ + unsigned int pr_sigpend; /* Set of pending signals */ + unsigned int pr_sighold; /* Set of held signals */ + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct timeval32 pr_utime; /* User time */ + struct timeval32 pr_stime; /* System time */ + struct timeval32 pr_cutime; /* Cumulative user time */ + struct timeval32 pr_cstime; /* Cumulative system time */ + elf_gregset_t pr_reg; /* GP registers */ + int pr_fpvalid; /* True if math co-processor being used. */ +}; + +#define elf_prpsinfo elf_prpsinfo32 +struct elf_prpsinfo32 +{ + char pr_state; /* numeric process state */ + char pr_sname; /* char for pr_state */ + char pr_zomb; /* zombie */ + char pr_nice; /* nice val */ + unsigned int pr_flag; /* flags */ + __kernel_uid_t pr_uid; + __kernel_gid_t pr_gid; + pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* filename of executable */ + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ +}; + +#define elf_addr_t u32 +#define elf_caddr_t u32 +#define init_elf_binfmt init_elfn32_binfmt + +#define ELF_CORE_EFLAGS EF_MIPS_ABI2 + +#undef CONFIG_BINFMT_ELF +#ifdef CONFIG_BINFMT_ELF32 +#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 +#endif +#undef CONFIG_BINFMT_ELF_MODULE +#ifdef CONFIG_BINFMT_ELF32_MODULE +#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE +#endif + +MODULE_DESCRIPTION("Binary format loader for compatibility with n32 Linux/MIPS binaries"); +MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); + +#undef MODULE_DESCRIPTION +#undef MODULE_AUTHOR + +#include "../../../fs/binfmt_elf.c" diff -urN linux-2.4.21/arch/mips64/kernel/binfmt_elfo32.c linux-2.4.22/arch/mips64/kernel/binfmt_elfo32.c --- linux-2.4.21/arch/mips64/kernel/binfmt_elfo32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/binfmt_elfo32.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,140 @@ +/* + * Support for o32 Linux/MIPS ELF binaries. + * + * Copyright (C) 1999, 2001 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. + * + * Heavily inspired by the 32-bit Sparc compat code which is + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#define ELF_ARCH EM_MIPS +#define ELF_CLASS ELFCLASS32 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB; +#else /* __MIPSEL__ */ +#define ELF_DATA ELFDATA2LSB; +#endif + +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 + +typedef unsigned int elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(hdr) \ +({ \ + int __res = 1; \ + struct elfhdr *__h = (hdr); \ + \ + if (__h->e_machine != EM_MIPS) \ + __res = 0; \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ + ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ + __res = 0; \ + \ + __res; \ +}) + +#define TASK32_SIZE 0x7fff8000UL +#undef ELF_ET_DYN_BASE +#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + +#include +#include +#include +#include + +struct timeval32 +{ + int tv_sec, tv_usec; +}; + +#define elf_prstatus elf_prstatus32 +struct elf_prstatus32 +{ + struct elf_siginfo pr_info; /* Info associated with signal */ + short pr_cursig; /* Current signal */ + unsigned int pr_sigpend; /* Set of pending signals */ + unsigned int pr_sighold; /* Set of held signals */ + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct timeval32 pr_utime; /* User time */ + struct timeval32 pr_stime; /* System time */ + struct timeval32 pr_cutime; /* Cumulative user time */ + struct timeval32 pr_cstime; /* Cumulative system time */ + elf_gregset_t pr_reg; /* GP registers */ + int pr_fpvalid; /* True if math co-processor being used. */ +}; + +#define elf_prpsinfo elf_prpsinfo32 +struct elf_prpsinfo32 +{ + char pr_state; /* numeric process state */ + char pr_sname; /* char for pr_state */ + char pr_zomb; /* zombie */ + char pr_nice; /* nice val */ + unsigned int pr_flag; /* flags */ + __kernel_uid_t pr_uid; + __kernel_gid_t pr_gid; + pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* filename of executable */ + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ +}; + +#define elf_addr_t u32 +#define elf_caddr_t u32 +#define init_elf_binfmt init_elf32_binfmt + + +#undef ELF_CORE_COPY_REGS +#define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs); + +void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs) +{ + int i; + + memset(_dest, 0, sizeof(elf_gregset_t)); + + /* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */ + for (i=6; i<38; i++) + _dest[i] = (elf_greg_t) _regs->regs[i-6]; + _dest[i++] = (elf_greg_t) _regs->lo; + _dest[i++] = (elf_greg_t) _regs->hi; + _dest[i++] = (elf_greg_t) _regs->cp0_epc; + _dest[i++] = (elf_greg_t) _regs->cp0_badvaddr; + _dest[i++] = (elf_greg_t) _regs->cp0_status; + _dest[i++] = (elf_greg_t) _regs->cp0_cause; +} + +#undef CONFIG_BINFMT_ELF +#ifdef CONFIG_BINFMT_ELF32 +#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 +#endif +#undef CONFIG_BINFMT_ELF_MODULE +#ifdef CONFIG_BINFMT_ELF32_MODULE +#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE +#endif + +MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); +MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); + +#undef MODULE_DESCRIPTION +#undef MODULE_AUTHOR + +#include "../../../fs/binfmt_elf.c" diff -urN linux-2.4.21/arch/mips64/kernel/branch.c linux-2.4.22/arch/mips64/kernel/branch.c --- linux-2.4.21/arch/mips64/kernel/branch.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips64/kernel/branch.c 2003-08-25 04:44:40.000000000 -0700 @@ -164,10 +164,10 @@ * And now the FPA/cp1 branch instructions. */ case cop1_op: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) fcr31 = current->thread.fpu.soft.sr; else - asm("cfc1\t%0,$31":"=r" (fcr31)); + asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; diff -urN linux-2.4.21/arch/mips64/kernel/cpu-probe.c linux-2.4.22/arch/mips64/kernel/cpu-probe.c --- linux-2.4.21/arch/mips64/kernel/cpu-probe.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/cpu-probe.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,9 +1,27 @@ +/* + * arch/mips64/kernel/cpu-probe.c + * + * Processor capabilities determination functions. + * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + #include #include +#include #include + #include #include +#include #include +#include /* * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, @@ -16,14 +34,14 @@ static void r3081_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | R30XX_CONF_HALT); } static void r39xx_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); } static void r4k_wait(void) @@ -39,23 +57,29 @@ /* using the wait instruction makes CP0 counter unusable */ __asm__(".set\tmips3\n\t" "wait\n\t" - "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0"); + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\tmips0"); #else - __asm__("nop\n\t" "nop\n\t"); + __asm__("nop\n\t" + "nop"); #endif } static inline void check_wait(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; + printk("Checking for 'wait' instruction... "); - switch(mips_cpu.cputype) { + switch (c->cputype) { case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; printk(" available.\n"); break; case CPU_TX3927: - case CPU_TX39XX: cpu_wait = r39xx_wait; printk(" available.\n"); break; @@ -89,9 +113,229 @@ } } +static inline void check_mult_sh(void) +{ + unsigned long flags; + int m1, m2; + long p, s, v; + + printk("Checking for the multiply/shift bug... "); + + local_irq_save(flags); + /* + * The following code leads to a wrong result of dsll32 when + * executed on R4000 rev. 2.2 or 3.0. + * + * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and + * 3.0" by MIPS Technologies, Inc., errata #16 and #28 for + * details. I got no permission to duplicate them here, + * sigh... --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" + "mult %1, %2\n\t" + "dsll32 %0, %3, %4\n\t" + "mflo $0\n\t" + ".set pop" + : "=r" (v) + : "r" (5), "r" (8), "r" (5), "I" (0) + : "hi", "lo", "accum"); + local_irq_restore(flags); + + if (v == 5L << 32) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + local_irq_save(flags); + /* + * We want the multiply and the shift to be isolated from the + * rest of the code to disable gcc optimizations. Hence the + * asm statements that execute nothing, but make gcc not know + * what the values of m1, m2 and s are and what v and p are + * used for. + * + * We have to use single integers for m1 and m2 and a double + * one for p to be sure the mulsidi3 gcc's RTL multiplication + * instruction has the workaround applied. Older versions of + * gcc have correct mulsi3, but other multiplication variants + * lack the workaround. + */ + asm volatile( + "" + : "=r" (m1), "=r" (m2), "=r" (s) + : "0" (5), "1" (8), "2" (5)); + p = m1 * m2; + v = s << 32; + asm volatile( + "" + : "=r" (v) + : "0" (v), "r" (p)); + local_irq_restore(flags); + + if (v == 5L << 32) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#ifndef CONFIG_CPU_R4000 + "Configure for R4000 to enable the workaround." +#else + "Please report to ." +#endif + ); +} + +static volatile int daddi_ov __initdata = 0; + +asmlinkage void __init do_daddi_ov(struct pt_regs *regs) +{ + daddi_ov = 1; + regs->cp0_epc += 4; +} + +static inline void check_daddi(void) +{ + extern asmlinkage void handle_daddi_ov(void); + unsigned long flags; + void *handler; + long v; + + printk("Checking for the daddi bug... "); + + local_irq_save(flags); + handler = set_except_vector(12, handle_daddi_ov); + /* + * The following code fails to trigger an overflow exception + * when executed on R4000 rev. 2.2 or 3.0. + * + * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and + * 3.0" by MIPS Technologies, Inc., erratum #23 for details. + * I got no permission to duplicate it here, sigh... --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" +#ifdef HAVE_AS_SET_DADDI + ".set daddi\n\t" +#endif + "daddi %0, %1, %2\n\t" + ".set pop" + : "=r" (v) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + set_except_vector(12, handler); + local_irq_restore(flags); + + if (daddi_ov) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + local_irq_save(flags); + handler = set_except_vector(12, handle_daddi_ov); + asm volatile( + "daddi %0, %1, %2" + : "=r" (v) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + set_except_vector(12, handler); + local_irq_restore(flags); + + if (daddi_ov) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400) + "Configure for R4000 or R4400 to enable the workaround." +#else + "Please report to ." +#endif + ); +} + +static inline void check_daddiu(void) +{ + long v, w; + + printk("Checking for the daddiu bug... "); + + /* + * The following code leads to a wrong result of daddiu when + * executed on R4400 rev. 1.0. + * + * See "MIPS R4400PC/SC Errata, Processor Revision 1.0" by + * MIPS Technologies, Inc., erratum #7 for details. + * + * According to "MIPS R4000PC/SC Errata, Processor Revision + * 2.2 and 3.0" by MIPS Technologies, Inc., erratum #41 this + * problem affects R4000 rev. 2.2 and 3.0, too. Testing + * failed to trigger it so far. + * + * I got no permission to duplicate the errata here, sigh... + * --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" +#ifdef HAVE_AS_SET_DADDI + ".set daddi\n\t" +#endif + "daddiu %0, %2, %3\n\t" + "addiu %1, $0, %3\n\t" + "daddu %1, %2\n\t" + ".set pop" + : "=&r" (v), "=&r" (w) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + + if (v == w) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + asm volatile( + "daddiu %0, %2, %3\n\t" + "addiu %1, $0, %3\n\t" + "daddu %1, %2" + : "=&r" (v), "=&r" (w) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + + if (v == w) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400) + "Configure for R4000 or R4400 to enable the workaround." +#else + "Please report to ." +#endif + ); +} + void __init check_bugs(void) { check_wait(); + check_mult_sh(); + check_daddi(); + check_daddiu(); } /* @@ -104,12 +348,12 @@ #ifdef CONFIG_CPU_R3000 extern unsigned long r3k_cache_size(unsigned long); unsigned long size1, size2; - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); + unsigned long cfg = read_c0_conf(); size1 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC); + write_c0_conf(cfg ^ R30XX_CONF_AC); size2 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg); + write_c0_conf(cfg); return size1 != size2; #else return 0; @@ -123,143 +367,138 @@ { unsigned long tmp, fpu_id; - tmp = read_32bit_cp0_register(CP0_STATUS); + tmp = read_c0_status(); __enable_fpu(); fpu_id = read_32bit_cp1_register(CP1_REVISION); - write_32bit_cp0_register(CP0_STATUS, tmp); + write_c0_status(tmp); return fpu_id; } /* * Check the CPU has an FPU the official way. */ -static inline int cpu_has_fpu(void) +static inline int __cpu_has_fpu(void) { return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); } -/* declaration of the global struct */ -struct mips_cpu mips_cpu = { - processor_id: PRID_IMP_UNKNOWN, - fpu_id: FPIR_IMP_NONE, - cputype: CPU_UNKNOWN -}; - -/* Shortcut for assembler access to mips_cpu.options */ -int *cpuoptions = &mips_cpu.options; - #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) __init void cpu_probe(void) { -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG); + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long config0 = read_c0_config(); unsigned long config1; + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + if (config0 & (1 << 31)) { /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC; - config1 = read_mips32_cp0_config1(); + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; + c->options |= MIPS_CPU_WATCH; if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; + c->options |= MIPS_CPU_MIPS16; if (config1 & (1 << 1)) - mips_cpu.options |= MIPS_CPU_EJTAG; + c->options |= MIPS_CPU_EJTAG; if (config1 & 1) { - mips_cpu.options |= MIPS_CPU_FPU; -#if defined(CONFIG_CPU_MIPS64) - mips_cpu.options |= MIPS_CPU_32FPR; -#endif + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; } - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; } -#endif - mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); - switch (mips_cpu.processor_id & 0xff0000) { + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { case PRID_COMP_LEGACY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_R2000: - mips_cpu.cputype = CPU_R2000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R3000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) + if ((c->processor_id & 0xff) == PRID_REV_R3000A) if (cpu_has_confreg()) - mips_cpu.cputype = CPU_R3081E; + c->cputype = CPU_R3081E; else - mips_cpu.cputype = CPU_R3000A; + c->cputype = CPU_R3000A; else - mips_cpu.cputype = CPU_R3000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R4000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) - mips_cpu.cputype = CPU_R4400SC; + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; else - mips_cpu.cputype = CPU_R4000SC; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH | - MIPS_CPU_VCE; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_VR41XX: - switch (mips_cpu.processor_id & 0xf0) { + switch (c->processor_id & 0xf0) { #ifndef CONFIG_VR4181 case PRID_REV_VR4111: - mips_cpu.cputype = CPU_VR4111; + c->cputype = CPU_VR4111; break; #else case PRID_REV_VR4181: - mips_cpu.cputype = CPU_VR4181; + c->cputype = CPU_VR4181; break; #endif case PRID_REV_VR4121: - mips_cpu.cputype = CPU_VR4121; + c->cputype = CPU_VR4121; break; case PRID_REV_VR4122: - if ((mips_cpu.processor_id & 0xf) < 0x3) - mips_cpu.cputype = CPU_VR4122; + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; else - mips_cpu.cputype = CPU_VR4181A; + c->cputype = CPU_VR4181A; break; case PRID_REV_VR4131: - mips_cpu.cputype = CPU_VR4131; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_VR4131; break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - mips_cpu.cputype = CPU_VR41XX; + c->cputype = CPU_VR41XX; break; } - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS; - mips_cpu.tlbsize = 32; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; break; case PRID_IMP_R4300: - mips_cpu.cputype = CPU_R4300; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R4600: - mips_cpu.cputype = CPU_R4600; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #if 0 case PRID_IMP_R4650: @@ -269,101 +508,97 @@ * for documentation. Commented out because it shares * it's c0_prid id number with the TX3900. */ - mips_cpu.cputype = CPU_R4650; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #endif case PRID_IMP_TX39: - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; - if ((mips_cpu.processor_id & 0xf0) == + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { - mips_cpu.cputype = CPU_TX3927; - mips_cpu.tlbsize = 64; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_TX3927; + c->tlbsize = 64; } else { - switch (mips_cpu.processor_id & 0xff) { + switch (c->processor_id & 0xff) { case PRID_REV_TX3912: - mips_cpu.cputype = CPU_TX3912; - mips_cpu.tlbsize = 32; + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; case PRID_REV_TX3922: - mips_cpu.cputype = CPU_TX3922; - mips_cpu.tlbsize = 64; + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } } break; case PRID_IMP_R4700: - mips_cpu.cputype = CPU_R4700; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_TX49: - mips_cpu.cputype = CPU_TX49XX; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 4; - mips_cpu.dcache.ways = 4; + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5000: - mips_cpu.cputype = CPU_R5000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5432: - mips_cpu.cputype = CPU_R5432; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5500: - mips_cpu.cputype = CPU_R5500; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_NEVADA: - mips_cpu.cputype = CPU_NEVADA; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_DIVEC; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R6000: - mips_cpu.cputype = CPU_R6000; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R6000A: - mips_cpu.cputype = CPU_R6000A; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_RM7000: - mips_cpu.cputype = CPU_RM7000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; /* * Undocumented RM7000: Bit 29 in the info register of * the RM7000 v2.0 indicates if the TLB has 48 or 64 @@ -372,118 +607,139 @@ * 29 1 => 64 entry JTLB * 0 => 48 entry JTLB */ - mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48; + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; break; case PRID_IMP_R8000: - mips_cpu.cputype = CPU_R8000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 384; /* has weird TLB: 3-way x 128 */ + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ break; case PRID_IMP_R10000: - mips_cpu.cputype = CPU_R10000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; case PRID_IMP_R12000: - mips_cpu.cputype = CPU_R12000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) case PRID_COMP_MIPS: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: - mips_cpu.cputype = CPU_4KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KEC: - mips_cpu.cputype = CPU_4KEC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KSC: - mips_cpu.cputype = CPU_4KSC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_5KC: - mips_cpu.cputype = CPU_5KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; break; case PRID_IMP_20KC: - mips_cpu.cputype = CPU_20KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; case PRID_COMP_ALCHEMY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: - switch ((mips_cpu.processor_id >> 24) & 0xff) { + switch ((c->processor_id >> 24) & 0xff) { case 0: - mips_cpu.cputype = CPU_AU1000; + c->cputype = CPU_AU1000; break; case 1: - mips_cpu.cputype = CPU_AU1500; + c->cputype = CPU_AU1500; break; case 2: - mips_cpu.cputype = CPU_AU1100; + c->cputype = CPU_AU1100; break; default: panic("Unknown Au Core!"); break; } - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->isa_level = MIPS_CPU_ISA_M32; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#endif /* CONFIG_CPU_MIPS32 */ case PRID_COMP_SIBYTE: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_SB1: - mips_cpu.cputype = CPU_SB1; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_MCHECK; + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS /* FPU in pass1 is known to have issues. */ - mips_cpu.options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; #endif break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; + break; + } + break; + + case PRID_COMP_SANDCRAFT: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; break; } break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; } - if (mips_cpu.options & MIPS_CPU_FPU) - mips_cpu.fpu_id = cpu_get_fpu_id(); + if (c->options & MIPS_CPU_FPU) + c->fpu_id = cpu_get_fpu_id(); } __init void cpu_report(void) { - printk("CPU revision is: %08x\n", mips_cpu.processor_id); - if (mips_cpu.options & MIPS_CPU_FPU) - printk("FPU revision is: %08x\n", mips_cpu.fpu_id); + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("CPU revision is: %08x\n", c->processor_id); + if (c->options & MIPS_CPU_FPU) + printk("FPU revision is: %08x\n", c->fpu_id); } diff -urN linux-2.4.21/arch/mips64/kernel/entry.S linux-2.4.22/arch/mips64/kernel/entry.S --- linux-2.4.21/arch/mips64/kernel/entry.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -18,7 +18,7 @@ #define KU_USER 0x10 .text - .align 4 + .align 5 FEXPORT(ret_from_fork) move a0, v0 # prev jal schedule_tail diff -urN linux-2.4.21/arch/mips64/kernel/gdb-low.S linux-2.4.22/arch/mips64/kernel/gdb-low.S --- linux-2.4.21/arch/mips64/kernel/gdb-low.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/gdb-low.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,357 @@ +/* + * gdb-low.S contains the low-level trap handler for the GDB stub. + * + * Copyright (C) 1995 Andreas Busse + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) + * part is used to store registers and passed to exception handler. + * The upper part is reserved for "call func" feature where gdb client + * saves some of the regs, setups call frame and passes args. + * + * A trace shows about 200 bytes are used to store about half of all regs. + * The rest should be big enough for frame setup and passing args. + */ + +/* + * The low level trap handler + */ + .align 5 + NESTED(trap_low, GDB_FR_SIZE, sp) + .set noat + .set noreorder + + mfc0 k0,CP0_STATUS + sll k0,3 /* extract cu0 bit */ + bltz k0,1f + move k1,sp + + /* + * Called from user mode, go somewhere else. + */ + lui k1,%hi(saved_vectors) + mfc0 k0,CP0_CAUSE + andi k0,k0,0x7c + add k1,k1,k0 + lw k0,%lo(saved_vectors)(k1) + jr k0 + nop +1: + move k0,sp + subu sp,k1,GDB_FR_SIZE*2 # see comment above + sd k0,GDB_FR_REG29(sp) + sd v0,GDB_FR_REG2(sp) + +/* + * First save the CP0 and special registers + */ + + mfc0 v0,CP0_STATUS + sd v0,GDB_FR_STATUS(sp) + mfc0 v0,CP0_CAUSE + sd v0,GDB_FR_CAUSE(sp) + dmfc0 v0,CP0_EPC + sd v0,GDB_FR_EPC(sp) + dmfc0 v0,CP0_BADVADDR + sd v0,GDB_FR_BADVADDR(sp) + mfhi v0 + sd v0,GDB_FR_HI(sp) + mflo v0 + sd v0,GDB_FR_LO(sp) + +/* + * Now the integer registers + */ + + sd zero,GDB_FR_REG0(sp) /* I know... */ + sd $1,GDB_FR_REG1(sp) + /* v0 already saved */ + sd v1,GDB_FR_REG3(sp) + sd a0,GDB_FR_REG4(sp) + sd a1,GDB_FR_REG5(sp) + sd a2,GDB_FR_REG6(sp) + sd a3,GDB_FR_REG7(sp) + sd a4,GDB_FR_REG8(sp) + sd a5,GDB_FR_REG9(sp) + sd a6,GDB_FR_REG10(sp) + sd a7,GDB_FR_REG11(sp) + sd t0,GDB_FR_REG12(sp) + sd t1,GDB_FR_REG13(sp) + sd t2,GDB_FR_REG14(sp) + sd t3,GDB_FR_REG15(sp) + sd s0,GDB_FR_REG16(sp) + sd s1,GDB_FR_REG17(sp) + sd s2,GDB_FR_REG18(sp) + sd s3,GDB_FR_REG19(sp) + sd s4,GDB_FR_REG20(sp) + sd s5,GDB_FR_REG21(sp) + sd s6,GDB_FR_REG22(sp) + sd s7,GDB_FR_REG23(sp) + sd t8,GDB_FR_REG24(sp) + sd t9,GDB_FR_REG25(sp) + sd k0,GDB_FR_REG26(sp) + sd k1,GDB_FR_REG27(sp) + sd gp,GDB_FR_REG28(sp) + /* sp already saved */ + sd fp,GDB_FR_REG30(sp) + sd ra,GDB_FR_REG31(sp) + + CLI /* disable interrupts */ + +/* + * Followed by the floating point registers + */ + mfc0 v0,CP0_STATUS /* FPU enabled? */ + srl v0,v0,16 + andi v0,v0,(ST0_CU1 >> 16) + + beqz v0,2f /* disabled, skip */ + nop + + sdc1 $0,GDB_FR_FPR0(sp) + sdc1 $1,GDB_FR_FPR1(sp) + sdc1 $2,GDB_FR_FPR2(sp) + sdc1 $3,GDB_FR_FPR3(sp) + sdc1 $4,GDB_FR_FPR4(sp) + sdc1 $5,GDB_FR_FPR5(sp) + sdc1 $6,GDB_FR_FPR6(sp) + sdc1 $7,GDB_FR_FPR7(sp) + sdc1 $8,GDB_FR_FPR8(sp) + sdc1 $9,GDB_FR_FPR9(sp) + sdc1 $10,GDB_FR_FPR10(sp) + sdc1 $11,GDB_FR_FPR11(sp) + sdc1 $12,GDB_FR_FPR12(sp) + sdc1 $13,GDB_FR_FPR13(sp) + sdc1 $14,GDB_FR_FPR14(sp) + sdc1 $15,GDB_FR_FPR15(sp) + sdc1 $16,GDB_FR_FPR16(sp) + sdc1 $17,GDB_FR_FPR17(sp) + sdc1 $18,GDB_FR_FPR18(sp) + sdc1 $19,GDB_FR_FPR19(sp) + sdc1 $20,GDB_FR_FPR20(sp) + sdc1 $21,GDB_FR_FPR21(sp) + sdc1 $22,GDB_FR_FPR22(sp) + sdc1 $23,GDB_FR_FPR23(sp) + sdc1 $24,GDB_FR_FPR24(sp) + sdc1 $25,GDB_FR_FPR25(sp) + sdc1 $26,GDB_FR_FPR26(sp) + sdc1 $27,GDB_FR_FPR27(sp) + sdc1 $28,GDB_FR_FPR28(sp) + sdc1 $29,GDB_FR_FPR29(sp) + sdc1 $30,GDB_FR_FPR30(sp) + sdc1 $31,GDB_FR_FPR31(sp) + +/* + * FPU control registers + */ + + cfc1 v0,CP1_STATUS + sd v0,GDB_FR_FSR(sp) + cfc1 v0,CP1_REVISION + sd v0,GDB_FR_FIR(sp) + +/* + * Current stack frame ptr + */ + +2: + sd sp,GDB_FR_FRP(sp) + +/* + * CP0 registers (R4000/R4400 unused registers skipped) + */ + + mfc0 v0,CP0_INDEX + sd v0,GDB_FR_CP0_INDEX(sp) + mfc0 v0,CP0_RANDOM + sd v0,GDB_FR_CP0_RANDOM(sp) + dmfc0 v0,CP0_ENTRYLO0 + sd v0,GDB_FR_CP0_ENTRYLO0(sp) + dmfc0 v0,CP0_ENTRYLO1 + sd v0,GDB_FR_CP0_ENTRYLO1(sp) + dmfc0 v0,CP0_CONTEXT + sd v0,GDB_FR_CP0_CONTEXT(sp) + mfc0 v0,CP0_PAGEMASK + sd v0,GDB_FR_CP0_PAGEMASK(sp) + mfc0 v0,CP0_WIRED + sd v0,GDB_FR_CP0_WIRED(sp) + dmfc0 v0,CP0_ENTRYHI + sd v0,GDB_FR_CP0_ENTRYHI(sp) + mfc0 v0,CP0_PRID + sd v0,GDB_FR_CP0_PRID(sp) + + .set at + +/* + * Continue with the higher level handler + */ + + move a0,sp + + jal handle_exception + nop + +/* + * Restore all writable registers, in reverse order + */ + + .set noat + + ld v0,GDB_FR_CP0_ENTRYHI(sp) + ld v1,GDB_FR_CP0_WIRED(sp) + dmtc0 v0,CP0_ENTRYHI + mtc0 v1,CP0_WIRED + ld v0,GDB_FR_CP0_PAGEMASK(sp) + ld v1,GDB_FR_CP0_ENTRYLO1(sp) + mtc0 v0,CP0_PAGEMASK + dmtc0 v1,CP0_ENTRYLO1 + ld v0,GDB_FR_CP0_ENTRYLO0(sp) + ld v1,GDB_FR_CP0_INDEX(sp) + dmtc0 v0,CP0_ENTRYLO0 + ld v0,GDB_FR_CP0_CONTEXT(sp) + mtc0 v1,CP0_INDEX + dmtc0 v0,CP0_CONTEXT + + +/* + * Next, the floating point registers + */ + mfc0 v0,CP0_STATUS /* check if the FPU is enabled */ + srl v0,v0,16 + andi v0,v0,(ST0_CU1 >> 16) + + beqz v0,3f /* disabled, skip */ + nop + + ldc1 $31,GDB_FR_FPR31(sp) + ldc1 $30,GDB_FR_FPR30(sp) + ldc1 $29,GDB_FR_FPR29(sp) + ldc1 $28,GDB_FR_FPR28(sp) + ldc1 $27,GDB_FR_FPR27(sp) + ldc1 $26,GDB_FR_FPR26(sp) + ldc1 $25,GDB_FR_FPR25(sp) + ldc1 $24,GDB_FR_FPR24(sp) + ldc1 $23,GDB_FR_FPR23(sp) + ldc1 $22,GDB_FR_FPR22(sp) + ldc1 $21,GDB_FR_FPR21(sp) + ldc1 $20,GDB_FR_FPR20(sp) + ldc1 $19,GDB_FR_FPR19(sp) + ldc1 $18,GDB_FR_FPR18(sp) + ldc1 $17,GDB_FR_FPR17(sp) + ldc1 $16,GDB_FR_FPR16(sp) + ldc1 $15,GDB_FR_FPR15(sp) + ldc1 $14,GDB_FR_FPR14(sp) + ldc1 $13,GDB_FR_FPR13(sp) + ldc1 $12,GDB_FR_FPR12(sp) + ldc1 $11,GDB_FR_FPR11(sp) + ldc1 $10,GDB_FR_FPR10(sp) + ldc1 $9,GDB_FR_FPR9(sp) + ldc1 $8,GDB_FR_FPR8(sp) + ldc1 $7,GDB_FR_FPR7(sp) + ldc1 $6,GDB_FR_FPR6(sp) + ldc1 $5,GDB_FR_FPR5(sp) + ldc1 $4,GDB_FR_FPR4(sp) + ldc1 $3,GDB_FR_FPR3(sp) + ldc1 $2,GDB_FR_FPR2(sp) + ldc1 $1,GDB_FR_FPR1(sp) + ldc1 $0,GDB_FR_FPR0(sp) + +/* + * Now the CP0 and integer registers + */ + +3: + mfc0 t0,CP0_STATUS + ori t0,0x1f + xori t0,0x1f + mtc0 t0,CP0_STATUS + + ld v0,GDB_FR_STATUS(sp) + ld v1,GDB_FR_EPC(sp) + mtc0 v0,CP0_STATUS + dmtc0 v1,CP0_EPC + ld v0,GDB_FR_HI(sp) + ld v1,GDB_FR_LO(sp) + mthi v0 + mtlo v0 + ld ra,GDB_FR_REG31(sp) + ld fp,GDB_FR_REG30(sp) + ld gp,GDB_FR_REG28(sp) + ld k1,GDB_FR_REG27(sp) + ld k0,GDB_FR_REG26(sp) + ld t9,GDB_FR_REG25(sp) + ld t8,GDB_FR_REG24(sp) + ld s7,GDB_FR_REG23(sp) + ld s6,GDB_FR_REG22(sp) + ld s5,GDB_FR_REG21(sp) + ld s4,GDB_FR_REG20(sp) + ld s3,GDB_FR_REG19(sp) + ld s2,GDB_FR_REG18(sp) + ld s1,GDB_FR_REG17(sp) + ld s0,GDB_FR_REG16(sp) + ld t3,GDB_FR_REG15(sp) + ld t2,GDB_FR_REG14(sp) + ld t1,GDB_FR_REG13(sp) + ld t0,GDB_FR_REG12(sp) + ld a7,GDB_FR_REG11(sp) + ld a6,GDB_FR_REG10(sp) + ld a5,GDB_FR_REG9(sp) + ld a4,GDB_FR_REG8(sp) + ld a3,GDB_FR_REG7(sp) + ld a2,GDB_FR_REG6(sp) + ld a1,GDB_FR_REG5(sp) + ld a0,GDB_FR_REG4(sp) + ld v1,GDB_FR_REG3(sp) + ld v0,GDB_FR_REG2(sp) + ld $1,GDB_FR_REG1(sp) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + ld k0, GDB_FR_EPC(sp) + ld sp, GDB_FR_REG29(sp) /* Deallocate stack */ + jr k0 + rfe +#else + ld sp, GDB_FR_REG29(sp) /* Deallocate stack */ + + .set mips3 + eret + .set mips0 +#endif + .set at + .set reorder + END(trap_low) + +LEAF(kgdb_read_byte) +4: lb t0, (a0) + sb t0, (a1) + li v0, 0 + jr ra + .section __ex_table,"a" + PTR 4b, kgdbfault + .previous + END(kgdb_read_byte) + +LEAF(kgdb_write_byte) +5: sb a0, (a1) + li v0, 0 + jr ra + .section __ex_table,"a" + PTR 5b, kgdbfault + .previous + END(kgdb_write_byte) + + .type kgdbfault@function + .ent kgdbfault + +kgdbfault: li v0, -EFAULT + jr ra + .end kgdbfault diff -urN linux-2.4.21/arch/mips64/kernel/gdb-stub.c linux-2.4.22/arch/mips64/kernel/gdb-stub.c --- linux-2.4.21/arch/mips64/kernel/gdb-stub.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/gdb-stub.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,1082 @@ +/* + * arch/mips/kernel/gdb-stub.c + * + * Originally written by Glenn Engel, Lake Stevens Instrument Division + * + * Contributed by HP Systems + * + * Modified for SPARC by Stu Grossman, Cygnus Support. + * + * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse + * Send complaints, suggestions etc. to + * + * Copyright (C) 1995 Andreas Busse + * + * Copyright (C) 2003 MontaVista Software Inc + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + */ + +/* + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a BREAK instruction. + * + * + * The following gdb commands are supported: + * + * command function Return value + * + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * + * k kill + * + * ? What was the last sigval ? SNN (signal NN) + * + * bBB..BB Set baud rate to BB..BB OK or BNN, then sets + * baud rate + * + * All commands and responses are sent with a packet which includes a + * checksum. A packet consists of + * + * $#. + * + * where + * :: + * :: < two hex digits computed as modulo 256 sum of > + * + * When a packet is received, it is first acknowledged with either '+' or '-'. + * '+' indicates a successful transfer. '-' indicates a failed transfer. + * + * Example: + * + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 + * + * + * ============== + * MORE EXAMPLES: + * ============== + * + * For reference -- the following are the steps that one + * company took (RidgeRun Inc) to get remote gdb debugging + * going. In this scenario the host machine was a PC and the + * target platform was a Galileo EVB64120A MIPS evaluation + * board. + * + * Step 1: + * First download gdb-5.0.tar.gz from the internet. + * and then build/install the package. + * + * Example: + * $ tar zxf gdb-5.0.tar.gz + * $ cd gdb-5.0 + * $ ./configure --target=mips-linux-elf + * $ make + * $ install + * $ which mips-linux-elf-gdb + * /usr/local/bin/mips-linux-elf-gdb + * + * Step 2: + * Configure linux for remote debugging and build it. + * + * Example: + * $ cd ~/linux + * $ make menuconfig + * $ make dep; make vmlinux + * + * Step 3: + * Download the kernel to the remote target and start + * the kernel running. It will promptly halt and wait + * for the host gdb session to connect. It does this + * since the "Kernel Hacking" option has defined + * CONFIG_KGDB which in turn enables your calls + * to: + * set_debug_traps(); + * breakpoint(); + * + * Step 4: + * Start the gdb session on the host. + * + * Example: + * $ mips-linux-elf-gdb vmlinux + * (gdb) set remotebaud 115200 + * (gdb) target remote /dev/ttyS1 + * ...at this point you are connected to + * the remote target and can use gdb + * in the normal fasion. Setting + * breakpoints, single stepping, + * printing variables, etc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * external low-level support routines + */ + +extern int putDebugChar(char c); /* write a single character */ +extern char getDebugChar(void); /* read and return a single char */ +extern void trap_low(void); + +/* + * breakpoint and test functions + */ +extern void breakpoint(void); +extern void breakinst(void); +extern void async_breakpoint(void); +extern void async_breakinst(void); +extern void adel(void); + +/* + * local prototypes + */ + +static void getpacket(char *buffer); +static void putpacket(char *buffer); +static int computeSignal(int tt); +static int hex(unsigned char ch); +static int hexToInt(char **ptr, int *intValue); +static int hexToLong(char **ptr, long *longValue); +static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault); +void handle_exception(struct gdb_regs *regs); + +/* + * spin locks for smp case + */ +static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED}; + +/* + * BUFMAX defines the maximum number of characters in inbound/outbound buffers + * at least NUMREGBYTES*2 are needed for register packets + */ +#define BUFMAX 2048 + +static char input_buffer[BUFMAX]; +static char output_buffer[BUFMAX]; +static int initialized; /* !0 means we've been initialized */ +static int kgdb_started; +static const char hexchars[]="0123456789abcdef"; + +/* Used to prevent crashes in memory access. Note that they'll crash anyway if + we haven't set up fault handlers yet... */ +int kgdb_read_byte(unsigned char *address, unsigned char *dest); +int kgdb_write_byte(unsigned char val, unsigned char *dest); + +/* + * Convert ch from a hex digit to an int + */ +static int hex(unsigned char ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch-'a'+10; + if (ch >= '0' && ch <= '9') + return ch-'0'; + if (ch >= 'A' && ch <= 'F') + return ch-'A'+10; + return -1; +} + +/* + * scan for the sequence $# + */ +static void getpacket(char *buffer) +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + unsigned char ch; + + do { + /* + * wait around for the start character, + * ignore all other characters + */ + while ((ch = (getDebugChar() & 0x7f)) != '$') ; + + checksum = 0; + xmitcsum = -1; + count = 0; + + /* + * now, read until a # or end of buffer is found + */ + while (count < BUFMAX) { + ch = getDebugChar() & 0x7f; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + + if (count >= BUFMAX) + continue; + + buffer[count] = 0; + + if (ch == '#') { + xmitcsum = hex(getDebugChar() & 0x7f) << 4; + xmitcsum |= hex(getDebugChar() & 0x7f); + + if (checksum != xmitcsum) + putDebugChar('-'); /* failed checksum */ + else { + putDebugChar('+'); /* successful transfer */ + + /* + * if a sequence char is present, + * reply the sequence ID + */ + if (buffer[2] == ':') { + putDebugChar(buffer[0]); + putDebugChar(buffer[1]); + + /* + * remove sequence chars from buffer + */ + count = strlen(buffer); + for (i=3; i <= count; i++) + buffer[i-3] = buffer[i]; + } + } + } + } + while (checksum != xmitcsum); +} + +/* + * send the packet in buffer. + */ +static void putpacket(char *buffer) +{ + unsigned char checksum; + int count; + unsigned char ch; + + /* + * $#. + */ + + do { + putDebugChar('$'); + checksum = 0; + count = 0; + + while ((ch = buffer[count]) != 0) { + if (!(putDebugChar(ch))) + return; + checksum += ch; + count += 1; + } + + putDebugChar('#'); + putDebugChar(hexchars[checksum >> 4]); + putDebugChar(hexchars[checksum & 0xf]); + + } + while ((getDebugChar() & 0x7f) != '+'); +} + + +/* + * Convert the memory pointed to by mem into hex, placing result in buf. + * Return a pointer to the last char put in buf (null), in case of mem fault, + * return 0. + * may_fault is non-zero if we are reading from arbitrary memory, but is currently + * not used. + */ +static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault) +{ + unsigned char ch; + + while (count-- > 0) { + if (kgdb_read_byte(mem++, &ch) != 0) + return 0; + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch & 0xf]; + } + + *buf = 0; + + return buf; +} + +/* + * convert the hex array pointed to by buf into binary to be placed in mem + * return a pointer to the character AFTER the last byte written + * may_fault is non-zero if we are reading from arbitrary memory, but is currently + * not used. + */ +static char *hex2mem(char *buf, char *mem, int count, int may_fault) +{ + int i; + unsigned char ch; + + for (i=0; itt && ht->signo; ht++) + saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low); + + putDebugChar('+'); /* 'hello world' */ + /* + * In case GDB is started before us, ack any packets + * (presumably "$?#xx") sitting there. + */ + while((c = getDebugChar()) != '$'); + while((c = getDebugChar()) != '#'); + c = getDebugChar(); /* eat first csum byte */ + c = getDebugChar(); /* eat second csum byte */ + putDebugChar('+'); /* ack it */ + + initialized = 1; + restore_flags(flags); +} + +void restore_debug_traps(void) +{ + struct hard_trap_info *ht; + unsigned long flags; + + save_and_cli(flags); + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + set_except_vector(ht->tt, saved_vectors[ht->tt]); + restore_flags(flags); +} + +/* + * Convert the MIPS hardware trap type code to a Unix signal number. + */ +static int computeSignal(int tt) +{ + struct hard_trap_info *ht; + + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + if (ht->tt == tt) + return ht->signo; + + return SIGHUP; /* default for things we don't know about */ +} + +/* + * While we find nice hex chars, build an int. + * Return number of chars processed. + */ +static int hexToInt(char **ptr, int *intValue) +{ + int numChars = 0; + int hexValue; + + *intValue = 0; + + while (**ptr) { + hexValue = hex(**ptr); + if (hexValue < 0) + break; + + *intValue = (*intValue << 4) | hexValue; + numChars ++; + + (*ptr)++; + } + + return (numChars); +} + +static int hexToLong(char **ptr, long *longValue) +{ + int numChars = 0; + int hexValue; + + *longValue = 0; + + while (**ptr) { + hexValue = hex(**ptr); + if (hexValue < 0) + break; + + *longValue = (*longValue << 4) | hexValue; + numChars ++; + + (*ptr)++; + } + + return (numChars); +} + + +#if 0 +/* + * Print registers (on target console) + * Used only to debug the stub... + */ +void show_gdbregs(struct gdb_regs * regs) +{ + /* + * Saved main processor registers + */ + printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg0, regs->reg1, regs->reg2, regs->reg3, + regs->reg4, regs->reg5, regs->reg6, regs->reg7); + printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg8, regs->reg9, regs->reg10, regs->reg11, + regs->reg12, regs->reg13, regs->reg14, regs->reg15); + printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg16, regs->reg17, regs->reg18, regs->reg19, + regs->reg20, regs->reg21, regs->reg22, regs->reg23); + printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg24, regs->reg25, regs->reg26, regs->reg27, + regs->reg28, regs->reg29, regs->reg30, regs->reg31); + + /* + * Saved cp0 registers + */ + printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", + regs->cp0_epc, regs->cp0_status, regs->cp0_cause); +} +#endif /* dead code */ + +/* + * We single-step by setting breakpoints. When an exception + * is handled, we need to restore the instructions hoisted + * when the breakpoints were set. + * + * This is where we save the original instructions. + */ +static struct gdb_bp_save { + unsigned long addr; + unsigned int val; +} step_bp[2]; + +#define BP 0x0000000d /* break opcode */ + +/* + * Set breakpoint instructions for single stepping. + */ +static void single_step(struct gdb_regs *regs) +{ + union mips_instruction insn; + unsigned long targ; + int is_branch, is_cond, i; + + targ = regs->cp0_epc; + insn.word = *(unsigned int *)targ; + is_branch = is_cond = 0; + + switch (insn.i_format.opcode) { + /* + * jr and jalr are in r_format format. + */ + case spec_op: + switch (insn.r_format.func) { + case jalr_op: + case jr_op: + targ = *(®s->reg0 + insn.r_format.rs); + is_branch = 1; + break; + } + break; + + /* + * This group contains: + * bltz_op, bgez_op, bltzl_op, bgezl_op, + * bltzal_op, bgezal_op, bltzall_op, bgezall_op. + */ + case bcond_op: + is_branch = is_cond = 1; + targ += 4 + (insn.i_format.simmediate << 2); + break; + + /* + * These are unconditional and in j_format. + */ + case jal_op: + case j_op: + is_branch = 1; + targ += 4; + targ >>= 28; + targ <<= 28; + targ |= (insn.j_format.target << 2); + break; + + /* + * These are conditional. + */ + case beq_op: + case beql_op: + case bne_op: + case bnel_op: + case blez_op: + case blezl_op: + case bgtz_op: + case bgtzl_op: + case cop0_op: + case cop1_op: + case cop2_op: + case cop1x_op: + is_branch = is_cond = 1; + targ += 4 + (insn.i_format.simmediate << 2); + break; + } + + if (is_branch) { + i = 0; + if (is_cond && targ != (regs->cp0_epc + 8)) { + step_bp[i].addr = regs->cp0_epc + 8; + step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8); + *(unsigned *)(regs->cp0_epc + 8) = BP; + } + step_bp[i].addr = targ; + step_bp[i].val = *(unsigned *)targ; + *(unsigned *)targ = BP; + } else { + step_bp[0].addr = regs->cp0_epc + 4; + step_bp[0].val = *(unsigned *)(regs->cp0_epc + 4); + *(unsigned *)(regs->cp0_epc + 4) = BP; + } +} + +/* + * If asynchronously interrupted by gdb, then we need to set a breakpoint + * at the interrupted instruction so that we wind up stopped with a + * reasonable stack frame. + */ +static struct gdb_bp_save async_bp; + +/* + * Swap the interrupted EPC with our asynchronous breakpoint routine. + * This is safer than stuffing the breakpoint in-place, since no cache + * flushes (or resulting smp_call_functions) are required. The + * assumption is that only one CPU will be handling asynchronous bp's, + * and only one can be active at a time. + */ +extern spinlock_t smp_call_lock; +void set_async_breakpoint(unsigned long *epc) +{ + /* skip breaking into userland */ + if ((*epc & 0x80000000) == 0) + return; + + /* avoid deadlock if someone is make IPC */ + if (spin_is_locked(&smp_call_lock)) + return; + + async_bp.addr = *epc; + *epc = (unsigned long)async_breakpoint; +} + +void kgdb_wait(void *arg) +{ + unsigned flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + + spin_lock(&kgdb_cpulock[cpu]); + spin_unlock(&kgdb_cpulock[cpu]); + + local_irq_restore(flags); +} + + +/* + * This function does all command processing for interfacing to gdb. It + * returns 1 if you should skip the instruction at the trap address, 0 + * otherwise. + */ +void handle_exception (struct gdb_regs *regs) +{ + int trap; /* Trap type */ + int sigval; + long addr; + int length; + char *ptr; + unsigned long *stack; + int i; + + kgdb_started = 1; + + /* + * acquire the big kgdb spinlock + */ + if (!spin_trylock(&kgdb_lock)) { + /* + * some other CPU has the lock, we should go back to + * receive the gdb_wait IPC + */ + return; + } + + /* + * If we're in async_breakpoint(), restore the real EPC from + * the breakpoint. + */ + if (regs->cp0_epc == (unsigned long)async_breakinst) { + regs->cp0_epc = async_bp.addr; + async_bp.addr = 0; + } + + /* + * acquire the CPU spinlocks + */ + for (i=0; i< smp_num_cpus; i++) + if (spin_trylock(&kgdb_cpulock[i]) == 0) + panic("kgdb: couldn't get cpulock %d\n", i); + + /* + * force other cpus to enter kgdb + */ + smp_call_function(kgdb_wait, NULL, 0, 0); + + /* + * If we're in breakpoint() increment the PC + */ + trap = (regs->cp0_cause & 0x7c) >> 2; + if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) + regs->cp0_epc += 4; + + /* + * If we were single_stepping, restore the opcodes hoisted + * for the breakpoint[s]. + */ + if (step_bp[0].addr) { + *(unsigned *)step_bp[0].addr = step_bp[0].val; + step_bp[0].addr = 0; + + if (step_bp[1].addr) { + *(unsigned *)step_bp[1].addr = step_bp[1].val; + step_bp[1].addr = 0; + } + } + + stack = (long *)regs->reg29; /* stack ptr */ + sigval = computeSignal(trap); + + /* + * reply to host that an exception has occurred + */ + ptr = output_buffer; + + /* + * Send trap type (converted to signal) + */ + *ptr++ = 'T'; + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; + + /* + * Send Error PC + */ + *ptr++ = hexchars[REG_EPC >> 4]; + *ptr++ = hexchars[REG_EPC & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®s->cp0_epc, ptr, 8, 0); + *ptr++ = ';'; + + /* + * Send frame pointer + */ + *ptr++ = hexchars[REG_FP >> 4]; + *ptr++ = hexchars[REG_FP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®s->reg30, ptr, 8, 0); + *ptr++ = ';'; + + /* + * Send stack pointer + */ + *ptr++ = hexchars[REG_SP >> 4]; + *ptr++ = hexchars[REG_SP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®s->reg29, ptr, 8, 0); + *ptr++ = ';'; + + *ptr++ = 0; + putpacket(output_buffer); /* send it off... */ + + /* + * Wait for input from remote GDB + */ + while (1) { + output_buffer[0] = 0; + getpacket(input_buffer); + + if (0) { +#include + prom_printf("got %c\n", input_buffer[0]); + } + + switch (input_buffer[0]) + { + case '?': + output_buffer[0] = 'S'; + output_buffer[1] = hexchars[sigval >> 4]; + output_buffer[2] = hexchars[sigval & 0xf]; + output_buffer[3] = 0; + break; + + /* + * Detach debugger; let CPU run + */ + case 'D': + putpacket(output_buffer); + goto finish_kgdb; + break; + + case 'd': + /* toggle debug flag */ + break; + + /* + * Return the value of the CPU registers + */ + case 'g': + ptr = output_buffer; + ptr = mem2hex((char *)®s->reg0, ptr, 32*8, 0); /* r0...r31 */ + ptr = mem2hex((char *)®s->cp0_status, ptr, 6*8, 0); /* cp0 */ + ptr = mem2hex((char *)®s->fpr0, ptr, 32*8, 0); /* f0...31 */ + ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*8, 0); /* cp1 */ + ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*8, 0); /* frp */ + ptr = mem2hex((char *)®s->cp0_index, ptr, 16*8, 0); /* cp0 */ + break; + + /* + * set the value of the CPU registers - return OK + */ + case 'G': + { + ptr = &input_buffer[1]; + hex2mem(ptr, (char *)®s->reg0, 32*8, 0); + ptr += 32*16; + hex2mem(ptr, (char *)®s->cp0_status, 6*8, 0); + ptr += 6*16; + hex2mem(ptr, (char *)®s->fpr0, 32*8, 0); + ptr += 32*16; + hex2mem(ptr, (char *)®s->cp1_fsr, 2*8, 0); + ptr += 2*16; + hex2mem(ptr, (char *)®s->frame_ptr, 2*8, 0); + ptr += 2*16; + hex2mem(ptr, (char *)®s->cp0_index, 16*8, 0); + strcpy(output_buffer,"OK"); + } + break; + + /* + * mAA..AA,LLLL Read LLLL bytes at address AA..AA + */ + case 'm': + ptr = &input_buffer[1]; + + if (hexToLong(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length)) { + if (mem2hex((char *)addr, output_buffer, length, 1)) + break; + strcpy (output_buffer, "E03"); + } else + strcpy(output_buffer,"E01"); + break; + + /* + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK + */ + case 'M': + ptr = &input_buffer[1]; + + if (hexToLong(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length) + && *ptr++ == ':') { + if (hex2mem(ptr, (char *)addr, length, 1)) + strcpy(output_buffer, "OK"); + else + strcpy(output_buffer, "E03"); + } + else + strcpy(output_buffer, "E02"); + break; + + /* + * cAA..AA Continue at address AA..AA(optional) + */ + case 'c': + /* try to read optional parameter, pc unchanged if no parm */ + + ptr = &input_buffer[1]; + if (hexToLong(&ptr, &addr)) + regs->cp0_epc = addr; + + goto exit_kgdb_exception; + break; + + /* + * kill the program; let us try to restart the machine + * Reset the whole machine. + */ + case 'k': + case 'r': + machine_restart("kgdb restarts machine"); + break; + + /* + * Step to next instruction + */ + case 's': + /* + * There is no single step insn in the MIPS ISA, so we + * use breakpoints and continue, instead. + */ + single_step(regs); + goto exit_kgdb_exception; + /* NOTREACHED */ + break; + + /* + * Set baud rate (bBB) + * FIXME: Needs to be written + */ + case 'b': + { +#if 0 + int baudrate; + extern void set_timer_3(); + + ptr = &input_buffer[1]; + if (!hexToInt(&ptr, &baudrate)) + { + strcpy(output_buffer,"B01"); + break; + } + + /* Convert baud rate to uart clock divider */ + + switch (baudrate) + { + case 38400: + baudrate = 16; + break; + case 19200: + baudrate = 33; + break; + case 9600: + baudrate = 65; + break; + default: + baudrate = 0; + strcpy(output_buffer,"B02"); + goto x1; + } + + if (baudrate) { + putpacket("OK"); /* Ack before changing speed */ + set_timer_3(baudrate); /* Set it */ + } +#endif + } + break; + + } /* switch */ + + /* + * reply to the request + */ + + putpacket(output_buffer); + + } /* while */ + + return; + +finish_kgdb: + restore_debug_traps(); + +exit_kgdb_exception: + /* release locks so other CPUs can go */ + for (i=0; i < smp_num_cpus; i++) + spin_unlock(&kgdb_cpulock[i]); + spin_unlock(&kgdb_lock); + + __flush_cache_all(); + return; +} + +/* + * This function will generate a breakpoint exception. It is used at the + * beginning of a program to sync up with a debugger and can be used + * otherwise as a quick means to stop program execution and "break" into + * the debugger. + */ +void breakpoint(void) +{ + if (!initialized) + return; + + __asm__ __volatile__( + ".globl breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); +} + +/* Nothing but the break; don't pollute any registers */ +void async_breakpoint(void) +{ + __asm__ __volatile__( + ".globl async_breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "async_breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); +} + +void adel(void) +{ + __asm__ __volatile__( + ".globl\tadel\n\t" + "lui\t$8,0x8000\n\t" + "lw\t$9,1($8)\n\t" + ); +} + +/* + * malloc is needed by gdb client in "call func()", even a private one + * will make gdb happy + */ +static void *malloc(size_t size) +{ + return kmalloc(size, GFP_ATOMIC); +} + +static void free(void *where) +{ + kfree(where); +} + +#ifdef CONFIG_GDB_CONSOLE + +void gdb_putsn(const char *str, int l) +{ + char outbuf[18]; + + if (!kgdb_started) + return; + + outbuf[0]='O'; + + while(l) { + int i = (l>8)?8:l; + mem2hex((char *)str, &outbuf[1], i, 0); + outbuf[(i*2)+1]=0; + putpacket(outbuf); + str += i; + l -= i; + } +} + +static kdev_t gdb_console_dev(struct console *con) +{ + return MKDEV(1, 3); /* /dev/null */ +} + +static void gdb_console_write(struct console *con, const char *s, unsigned n) +{ + gdb_putsn(s, n); +} + +static struct console gdb_console = { + .name = "gdb", + .write = gdb_console_write, + .device = gdb_console_dev, + .flags = CON_PRINTBUFFER, + .index = -1 +}; + +__init void register_gdb_console(void) +{ + register_console(&gdb_console); +} + +#endif diff -urN linux-2.4.21/arch/mips64/kernel/head.S linux-2.4.22/arch/mips64/kernel/head.S --- linux-2.4.21/arch/mips64/kernel/head.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -107,7 +107,7 @@ PTR_LA $28, init_task_union # init current pointer daddiu sp, $28, KERNEL_STACK_SIZE-32 - set_saved_sp sp, t0 + set_saved_sp sp, t0, t1 /* The firmware/bootloader passes argc/argp/envp * to us as arguments. But clear bss first because @@ -157,8 +157,6 @@ or t0, ST0_KX mtc0 t0, CP0_STATUS - set_saved_sp sp, t0 - jal start_secondary # XXX: IP27: cboot END(smp_bootstrap) @@ -168,13 +166,10 @@ declare_saved_sp -#undef PAGE_SIZE -#define PAGE_SIZE 0x1000 - .macro page name, order=0 .globl \name -\name: .size \name, (PAGE_SIZE << \order) - .org . + (PAGE_SIZE << \order) +\name: .size \name, (_PAGE_SIZE << \order) + .org . + (_PAGE_SIZE << \order) .type \name, @object .endm diff -urN linux-2.4.21/arch/mips64/kernel/i8259.c linux-2.4.22/arch/mips64/kernel/i8259.c --- linux-2.4.21/arch/mips64/kernel/i8259.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/i8259.c 2003-08-25 04:44:40.000000000 -0700 @@ -15,6 +15,7 @@ #include #include +#include #include void enable_8259A_irq(unsigned int irq); diff -urN linux-2.4.21/arch/mips64/kernel/ioctl32.c linux-2.4.22/arch/mips64/kernel/ioctl32.c --- linux-2.4.21/arch/mips64/kernel/ioctl32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/ioctl32.c 2003-08-25 04:44:40.000000000 -0700 @@ -4,6 +4,7 @@ * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) * Copyright (C) 2000 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki * * Mostly stolen from the sparc64 ioctl32 implementation. */ @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -31,17 +33,28 @@ #include #include #include +#include #include #include +#include #include #undef __KERNEL__ /* This file was born to be ugly ... */ #include #define __KERNEL__ +#include + #include #include #include +#ifdef CONFIG_MTD_CHAR +#include +#endif + +#ifdef CONFIG_SIBYTE_TBPROF +#include +#endif long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); @@ -77,6 +90,166 @@ #define A(__x) ((unsigned long)(__x)) + +#ifdef CONFIG_FB + +struct fb_fix_screeninfo32 { + char id[16]; /* identification string eg "TT Builtin" */ + __u32 smem_start; /* Start of frame buffer mem */ + /* (physical address) */ + __u32 smem_len; /* Length of frame buffer mem */ + __u32 type; /* see FB_TYPE_* */ + __u32 type_aux; /* Interleave for interleaved Planes */ + __u32 visual; /* see FB_VISUAL_* */ + __u16 xpanstep; /* zero if no hardware panning */ + __u16 ypanstep; /* zero if no hardware panning */ + __u16 ywrapstep; /* zero if no hardware ywrap */ + __u32 line_length; /* length of a line in bytes */ + __u32 mmio_start; /* Start of Memory Mapped I/O */ + /* (physical address) */ + __u32 mmio_len; /* Length of Memory Mapped I/O */ + __u32 accel; /* Type of acceleration available */ + __u16 reserved[3]; /* Reserved for future compatibility */ +}; + +static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + struct fb_fix_screeninfo fix; + struct fb_fix_screeninfo32 *fix32 = (struct fb_fix_screeninfo32 *)arg; + int err; + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&fix); + set_fs(old_fs); + + if (err == 0) { + err = __copy_to_user((char *)fix32->id, (char *)fix.id, + sizeof(fix.id)); + err |= __put_user((__u32)(unsigned long)fix.smem_start, + &fix32->smem_start); + err |= __put_user(fix.smem_len, &fix32->smem_len); + err |= __put_user(fix.type, &fix32->type); + err |= __put_user(fix.type_aux, &fix32->type_aux); + err |= __put_user(fix.visual, &fix32->visual); + err |= __put_user(fix.xpanstep, &fix32->xpanstep); + err |= __put_user(fix.ypanstep, &fix32->ypanstep); + err |= __put_user(fix.ywrapstep, &fix32->ywrapstep); + err |= __put_user(fix.line_length, &fix32->line_length); + err |= __put_user((__u32)(unsigned long)fix.mmio_start, + &fix32->mmio_start); + err |= __put_user(fix.mmio_len, &fix32->mmio_len); + err |= __put_user(fix.accel, &fix32->accel); + err |= __copy_to_user((char *)fix32->reserved, + (char *)fix.reserved, + sizeof(fix.reserved)); + if (err) + err = -EFAULT; + } + + return err; +} + +struct fb_cmap32 { + __u32 start; /* First entry */ + __u32 len; /* Number of entries */ + __u32 red; /* Red values */ + __u32 green; + __u32 blue; + __u32 transp; /* transparency, can be NULL */ +}; + +static int do_fbiocmap_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + u32 red = 0, green = 0, blue = 0, transp = 0; + struct fb_cmap cmap; + struct fb_cmap32 *cmap32 = (struct fb_cmap32 *)arg; + int err; + + memset(&cmap, 0, sizeof(cmap)); + + err = __get_user(cmap.start, &cmap32->start); + err |= __get_user(cmap.len, &cmap32->len); + err |= __get_user(red, &cmap32->red); + err |= __get_user(green, &cmap32->green); + err |= __get_user(blue, &cmap32->blue); + err |= __get_user(transp, &cmap32->transp); + if (err) + return -EFAULT; + + err = -ENOMEM; + cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.red) + goto out; + cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.green) + goto out; + cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.blue) + goto out; + if (transp) { + cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.transp) + goto out; + } + + if (cmd == FBIOPUTCMAP) { + err = __copy_from_user(cmap.red, (char *)A(red), + cmap.len * sizeof(__u16)); + err |= __copy_from_user(cmap.green, (char *)A(green), + cmap.len * sizeof(__u16)); + err |= __copy_from_user(cmap.blue, (char *)A(blue), + cmap.len * sizeof(__u16)); + if (cmap.transp) + err |= __copy_from_user(cmap.transp, (char *)A(transp), + cmap.len * sizeof(__u16)); + if (err) { + err = -EFAULT; + goto out; + } + } + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&cmap); + set_fs(old_fs); + if (err) + goto out; + + if (cmd == FBIOGETCMAP) { + err = __copy_to_user((char *)A(red), cmap.red, + cmap.len * sizeof(__u16)); + err |= __copy_to_user((char *)A(green), cmap.blue, + cmap.len * sizeof(__u16)); + err |= __copy_to_user((char *)A(blue), cmap.blue, + cmap.len * sizeof(__u16)); + if (cmap.transp) + err |= __copy_to_user((char *)A(transp), cmap.transp, + cmap.len * sizeof(__u16)); + if (err) { + err = -EFAULT; + goto out; + } + } + +out: + if (cmap.red) + kfree(cmap.red); + if (cmap.green) + kfree(cmap.green); + if (cmap.blue) + kfree(cmap.blue); + if (cmap.transp) + kfree(cmap.transp); + + return err; +} + +#endif /* CONFIG_FB */ + + struct timeval32 { int tv_sec; int tv_usec; @@ -571,6 +744,127 @@ return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); } +/* serial_struct_ioctl was taken from x86_64/ia32/ia32_ioctl.c and + * slightly modified for mips */ +/* iomem_base is unsigned char * in linux/serial.h (reserved in sgiserial.h) */ +struct serial_struct32 { + int type; + int line; + unsigned int port; + int irq; + int flags; + int xmit_fifo_size; + int custom_divisor; + int baud_base; + unsigned short close_delay; + char io_type; + char reserved_char[1]; + int hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + __u32 iomem_base; + unsigned short iomem_reg_shift; + unsigned int port_high; + int reserved[1]; +}; + +static int serial_struct_ioctl(unsigned fd, unsigned cmd, void *ptr) +{ + typedef struct serial_struct SS; + struct serial_struct32 *ss32 = ptr; + int err = 0; + struct serial_struct ss; + mm_segment_t oldseg = get_fs(); + set_fs(KERNEL_DS); + if (cmd == TIOCSSERIAL) { + err = -EFAULT; + if (copy_from_user(&ss, ss32, sizeof(struct serial_struct32))) + goto out; + memmove(&ss.iomem_reg_shift, ((char*)&ss.iomem_base)+4, + sizeof(SS)-offsetof(SS,iomem_reg_shift)); + ss.iomem_base = (void *)(long)ss.iomem_base; /* sign extend */ + } + if (!err) + err = sys_ioctl(fd,cmd,(unsigned long)(&ss)); + if (cmd == TIOCGSERIAL && err >= 0) { + __u32 base; + if (__copy_to_user(ss32,&ss,offsetof(SS,iomem_base)) || + __copy_to_user(&ss32->iomem_reg_shift, + &ss.iomem_reg_shift, + sizeof(SS) - offsetof(SS, iomem_reg_shift))) + err = -EFAULT; + base = (unsigned long)ss.iomem_base; + err |= __put_user(base, &ss32->iomem_base); + } + out: + set_fs(oldseg); + return err; +} + +/* loop_status was taken from sparc64/kernel/ioctl32.c */ +struct loop_info32 { + int lo_number; /* ioctl r/o */ + __kernel_dev_t32 lo_device; /* ioctl r/o */ + unsigned int lo_inode; /* ioctl r/o */ + __kernel_dev_t32 lo_rdevice; /* ioctl r/o */ + int lo_offset; + int lo_encrypt_type; + int lo_encrypt_key_size; /* ioctl w/o */ + int lo_flags; /* ioctl r/o */ + char lo_name[LO_NAME_SIZE]; + unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ + unsigned int lo_init[2]; + char reserved[4]; +}; + +static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + struct loop_info l; + int err = -EINVAL; + + switch(cmd) { + case LOOP_SET_STATUS: + err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); + err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); + err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); + err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); + err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, + 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + if (err) { + err = -EFAULT; + } else { + set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&l); + set_fs (old_fs); + } + break; + case LOOP_GET_STATUS: + set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&l); + set_fs (old_fs); + if (!err) { + err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); + err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); + err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); + err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); + err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, + (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + if (err) + err = -EFAULT; + } + break; + default: { + static int count; + if (++count <= 20) + printk("%s: Unknown loop ioctl cmd, fd(%d) " + "cmd(%08x) arg(%08lx)\n", + __FUNCTION__, fd, cmd, arg); + } + } + return err; +} + struct ioctl32_handler { unsigned int cmd; int (*function)(unsigned int, unsigned int, unsigned long); @@ -620,8 +914,8 @@ IOCTL32_DEFAULT(TIOCSCTTY), IOCTL32_DEFAULT(TIOCGPTN), IOCTL32_DEFAULT(TIOCSPTLCK), - IOCTL32_DEFAULT(TIOCGSERIAL), - IOCTL32_DEFAULT(TIOCSSERIAL), + IOCTL32_HANDLER(TIOCGSERIAL, serial_struct_ioctl), + IOCTL32_HANDLER(TIOCSSERIAL, serial_struct_ioctl), IOCTL32_DEFAULT(TIOCSERGETLSR), IOCTL32_DEFAULT(FIOCLEX), @@ -630,6 +924,16 @@ IOCTL32_DEFAULT(FIONBIO), IOCTL32_DEFAULT(FIONREAD), +#ifdef CONFIG_FB + /* Big F */ + IOCTL32_DEFAULT(FBIOGET_VSCREENINFO), + IOCTL32_DEFAULT(FBIOPUT_VSCREENINFO), + IOCTL32_HANDLER(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl), + IOCTL32_HANDLER(FBIOGETCMAP, do_fbiocmap_ioctl), + IOCTL32_HANDLER(FBIOPUTCMAP, do_fbiocmap_ioctl), + IOCTL32_DEFAULT(FBIOPAN_DISPLAY), +#endif /* CONFIG_FB */ + /* Big K */ IOCTL32_DEFAULT(PIO_FONT), IOCTL32_DEFAULT(GIO_FONT), @@ -651,6 +955,7 @@ IOCTL32_DEFAULT(KDSKBSENT), IOCTL32_DEFAULT(KDGKBDIACR), IOCTL32_DEFAULT(KDSKBDIACR), + IOCTL32_DEFAULT(KDKBDREP), IOCTL32_DEFAULT(KDGKBLED), IOCTL32_DEFAULT(KDSKBLED), IOCTL32_DEFAULT(KDGETLED), @@ -793,6 +1098,8 @@ /* Big L */ IOCTL32_DEFAULT(LOOP_SET_FD), IOCTL32_DEFAULT(LOOP_CLR_FD), + IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status), + IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status), /* And these ioctls need translation */ IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), @@ -915,6 +1222,12 @@ IOCTL32_DEFAULT(RESTART_ARRAY_RW), #endif /* CONFIG_MD */ +#ifdef CONFIG_SIBYTE_TBPROF + IOCTL32_DEFAULT(SBPROF_ZBSTART), + IOCTL32_DEFAULT(SBPROF_ZBSTOP), + IOCTL32_DEFAULT(SBPROF_ZBWAITFULL), +#endif /* CONFIG_SIBYTE_TBPROF */ + IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls */ IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans), IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans), @@ -933,6 +1246,7 @@ IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER), IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout), IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE), + IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI), /* Little p (/dev/rtc, /dev/envctrl, etc.) */ IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */ @@ -950,7 +1264,18 @@ IOCTL32_DEFAULT(RTC_RD_TIME), IOCTL32_DEFAULT(RTC_SET_TIME), IOCTL32_DEFAULT(RTC_WKALM_SET), - IOCTL32_DEFAULT(RTC_WKALM_RD) + IOCTL32_DEFAULT(RTC_WKALM_RD), +#ifdef CONFIG_MTD_CHAR + /* Big M */ + IOCTL32_DEFAULT(MEMGETINFO), + IOCTL32_DEFAULT(MEMERASE), + // IOCTL32_DEFAULT(MEMWRITEOOB32, mtd_rw_oob), + // IOCTL32_DEFAULT(MEMREADOOB32, mtd_rw_oob), + IOCTL32_DEFAULT(MEMLOCK), + IOCTL32_DEFAULT(MEMUNLOCK), + IOCTL32_DEFAULT(MEMGETREGIONCOUNT), + IOCTL32_DEFAULT(MEMGETREGIONINFO), +#endif }; #define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \ diff -urN linux-2.4.21/arch/mips64/kernel/irq.c linux-2.4.22/arch/mips64/kernel/irq.c --- linux-2.4.21/arch/mips64/kernel/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -211,7 +211,7 @@ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { diff -urN linux-2.4.21/arch/mips64/kernel/irq_cpu.c linux-2.4.22/arch/mips64/kernel/irq_cpu.c --- linux-2.4.21/arch/mips64/kernel/irq_cpu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/irq_cpu.c 2003-08-25 04:44:40.000000000 -0700 @@ -35,13 +35,13 @@ static inline void unmask_mips_irq(unsigned int irq) { - clear_cp0_cause(0x100 << (irq - mips_cpu_irq_base)); - set_cp0_status(0x100 << (irq - mips_cpu_irq_base)); + clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); + set_c0_status(0x100 << (irq - mips_cpu_irq_base)); } static inline void mask_mips_irq(unsigned int irq) { - clear_cp0_status(0x100 << (irq - mips_cpu_irq_base)); + clear_c0_status(0x100 << (irq - mips_cpu_irq_base)); } static inline void mips_cpu_irq_enable(unsigned int irq) @@ -78,7 +78,7 @@ static void mips_cpu_irq_ack(unsigned int irq) { /* Only necessary for soft interrupts */ - clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8)); mask_mips_irq(irq); } diff -urN linux-2.4.21/arch/mips64/kernel/linux32.c linux-2.4.22/arch/mips64/kernel/linux32.c --- linux-2.4.21/arch/mips64/kernel/linux32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/linux32.c 2003-08-25 04:44:40.000000000 -0700 @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -32,6 +31,7 @@ #include #include #include +#include #include #include @@ -179,7 +179,32 @@ return err; } -asmlinkage int sys_mmap2(void) {return 0;} +asmlinkage unsigned long +sys32_mmap2(unsigned long addr, size_t len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) +{ + struct file * file = NULL; + unsigned long error; + + error = -EINVAL; + if (!(flags & MAP_ANONYMOUS)) { + error = -EBADF; + file = fget(fd); + if (!file) + goto out; + } + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + if (file) + fput(file); + +out: + return error; +} + asmlinkage long sys_truncate(const char * path, unsigned long length); @@ -241,15 +266,15 @@ if (argv != NULL) { for (;;) { - u32 p; - /* egcs is stupid */ - if (!access_ok(VERIFY_READ, argv, sizeof (u32))) - return -EFAULT; - __get_user(p,argv); + u32 p; int error; + + error = get_user(p,argv); + if (error) + return error; if (!p) break; argv++; - if(++i > max) + if (++i > max) return -E2BIG; } } @@ -309,7 +334,6 @@ } err = copy_from_user(kaddr + offset, (char *)A(str), bytes_to_copy); - flush_page_to_ram(page); kunmap(page); if (err) @@ -416,26 +440,22 @@ #else static int nargs(unsigned int arg, char **ap) { - char *ptr; - int n, ret; + unsigned int addr; + int n, err; if (!arg) return 0; n = 0; do { - /* egcs is stupid */ - if (!access_ok(VERIFY_READ, arg, sizeof (unsigned int))) - return -EFAULT; - if (IS_ERR(ret = __get_user((long)ptr,(int *)A(arg)))) - return ret; - if (ap) /* no access_ok needed, we allocated */ - if (IS_ERR(ret = __put_user(ptr, ap++))) - return ret; + err = get_user(addr, (unsigned int *)A(arg)); + if (err) + return err; + if (ap) + *ap++ = (char *) A(addr); arg += sizeof(unsigned int); n++; - } while (ptr); - + } while (addr); return n - 1; } @@ -451,19 +471,20 @@ char * filename; na = nargs(argv, NULL); - if (IS_ERR(na)) - return(na); + if (na < 0) + return na; ne = nargs(envp, NULL); - if (IS_ERR(ne)) - return(ne); + if (ne < 0) + return ne; len = (na + ne + 2) * sizeof(*av); + /* * kmalloc won't work because the `sys_exec' code will attempt * to do a `get_user' on the arg list and `get_user' will fail * on a kernel address (simplifies `get_user'). Instead we * do an mmap to get a user address. Note that since a successful * `execve' frees all current memory we only have to do an - * `munmap' if the `execve' failes. + * `munmap' if the `execve' fails. */ down_write(¤t->mm->mmap_sem); av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE, @@ -473,13 +494,15 @@ if (IS_ERR(av)) return (long) av; ae = av + na + 1; - if (IS_ERR(r = __put_user(0, (av + na)))) - goto out; - if (IS_ERR(r = __put_user(0, (ae + ne)))) + r = __put_user(0, (av + na)); + r |= __put_user(0, (ae + ne)); + if (r) goto out; - if (IS_ERR(r = nargs(argv, av))) + r = nargs(argv, av); + if (r < 0) goto out; - if (IS_ERR(r = nargs(envp, ae))) + r = nargs(envp, ae); + if (r < 0) goto out; filename = getname((char *) (long)regs.regs[4]); r = PTR_ERR(filename); @@ -488,10 +511,10 @@ r = do_execve(filename, av, ae, ®s); putname(filename); - if (IS_ERR(r)) + if (r) out: sys_munmap((unsigned long)av, len); - return(r); + return r ; } #endif @@ -586,7 +609,10 @@ { int err; - err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); + if (verify_area(VERIFY_WRITE, ru, sizeof *ru)) + return -EFAULT; + + err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec); err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec); err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec); @@ -604,6 +630,7 @@ err |= __put_user (r->ru_nsignals, &ru->ru_nsignals); err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw); err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw); + return err; } @@ -635,6 +662,52 @@ return sys32_wait4(pid, stat_addr, options, NULL); } +struct sysinfo32 { + s32 uptime; + u32 loads[3]; + u32 totalram; + u32 freeram; + u32 sharedram; + u32 bufferram; + u32 totalswap; + u32 freeswap; + u16 procs; + u32 totalhigh; + u32 freehigh; + u32 mem_unit; + char _f[8]; +}; + +extern asmlinkage int sys_sysinfo(struct sysinfo *info); + +asmlinkage int sys32_sysinfo(struct sysinfo32 *info) +{ + struct sysinfo s; + int ret, err; + mm_segment_t old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_sysinfo(&s); + set_fs (old_fs); + err = put_user (s.uptime, &info->uptime); + err |= __put_user (s.loads[0], &info->loads[0]); + err |= __put_user (s.loads[1], &info->loads[1]); + err |= __put_user (s.loads[2], &info->loads[2]); + err |= __put_user (s.totalram, &info->totalram); + err |= __put_user (s.freeram, &info->freeram); + err |= __put_user (s.sharedram, &info->sharedram); + err |= __put_user (s.bufferram, &info->bufferram); + err |= __put_user (s.totalswap, &info->totalswap); + err |= __put_user (s.freeswap, &info->freeswap); + err |= __put_user (s.procs, &info->procs); + err |= __put_user (s.totalhigh, &info->totalhigh); + err |= __put_user (s.freehigh, &info->freehigh); + err |= __put_user (s.mem_unit, &info->mem_unit); + if (err) + return -EFAULT; + return ret; +} + #define RLIM_INFINITY32 0x7fffffff #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) @@ -725,12 +798,17 @@ int ret; struct statfs s; mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_statfs((const char *)path, &s); - set_fs (old_fs); - if (put_statfs(buf, &s)) - return -EFAULT; + char *pth; + + pth = getname (path); + ret = PTR_ERR(pth); + if (!IS_ERR(pth)) { + set_fs (KERNEL_DS); + ret = sys_statfs((const char *)path, &s); + set_fs (old_fs); + if (!ret && put_statfs(buf, &s)) + return -EFAULT; + } return ret; } @@ -751,6 +829,38 @@ return ret; } +#ifdef __MIPSEB__ +asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, + int length_hi, int length_lo) +#endif +#ifdef __MIPSEL__ +asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, + int length_lo, int length_hi) +#endif +{ + loff_t length; + + length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; + + return sys_truncate(path, length); +} + +#ifdef __MIPSEB__ +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, + int length_hi, int length_lo) +#endif +#ifdef __MIPSEL__ +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, + int length_lo, int length_hi) +#endif +{ + loff_t length; + + length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; + + return sys_ftruncate(fd, length); +} + extern asmlinkage int sys_getrusage(int who, struct rusage *ru); @@ -843,25 +953,6 @@ return -EFAULT; return 0; - -} -asmlinkage unsigned long -sys32_alarm(unsigned int seconds) -{ - struct itimerval it_new, it_old; - unsigned int oldalarm; - - it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; - it_new.it_value.tv_sec = seconds; - it_new.it_value.tv_usec = 0; - do_setitimer(ITIMER_REAL, &it_new, &it_old); - oldalarm = it_old.it_value.tv_sec; - /* ehhh.. We can't return 0 if we have an alarm pending.. */ - /* And we'd better return too much than too little anyway */ - if (it_old.it_value.tv_usec) - oldalarm++; - - return oldalarm; } /* Translations due to time_t size differences. Which affects all @@ -1572,6 +1663,15 @@ unsigned short sem_nsems; /* no. of semaphores in array */ }; +struct semid64_ds32 { + struct ipc64_perm32 sem_perm; + __kernel_time_t32 sem_otime; + __kernel_time_t32 sem_ctime; + unsigned int sem_nsems; + unsigned int __unused1; + unsigned int __unused2; +}; + struct msqid_ds32 { struct ipc_perm32 msg_perm; @@ -1617,6 +1717,19 @@ unsigned short shm_nattch; }; +struct shmid64_ds32 { + struct ipc64_perm32 shm_perm; + __kernel_size_t32 shm_segsz; + __kernel_time_t32 shm_atime; + __kernel_time_t32 shm_dtime; + __kernel_time_t32 shm_ctime; + __kernel_pid_t32 shm_cpid; + __kernel_pid_t32 shm_lpid; + unsigned int shm_nattch; + unsigned int __unused1; + unsigned int __unused2; +}; + struct ipc_kludge32 { u32 msgp; s32 msgtyp; @@ -1629,7 +1742,6 @@ u32 pad; int err, err2; struct semid64_ds s; - struct semid_ds32 *usp; mm_segment_t old_fs; if (!uptr) @@ -1642,7 +1754,6 @@ else fourth.__pad = (void *)A(pad); switch (third & ~IPC_64) { - case IPC_INFO: case IPC_RMID: case IPC_SET: @@ -1659,34 +1770,60 @@ case IPC_STAT: case SEM_STAT: - usp = (struct semid_ds32 *)A(pad); fourth.__pad = &s; old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_semctl (first, second, third, fourth); set_fs (old_fs); - err2 = put_user(s.sem_perm.key, &usp->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, - &usp->sem_perm.cuid); - err2 |= __put_user (s.sem_perm.cgid, - &usp->sem_perm.cgid); - err2 |= __put_user (s.sem_perm.mode, - &usp->sem_perm.mode); - err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq); - err2 |= __put_user (s.sem_otime, &usp->sem_otime); - err2 |= __put_user (s.sem_ctime, &usp->sem_ctime); - err2 |= __put_user (s.sem_nsems, &usp->sem_nsems); + + if (third & IPC_64) { + struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad); + + if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { + err = -EFAULT; + break; + } + err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); + err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); + err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); + err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); + err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); + err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); + err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); + err2 |= __put_user(s.sem_otime, &usp64->sem_otime); + err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); + err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); + } else { + struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad); + + if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { + err = -EFAULT; + break; + } + err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); + err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); + err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); + err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); + err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); + err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); + err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); + err2 |= __put_user(s.sem_otime, &usp32->sem_otime); + err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); + err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); + } if (err2) err = -EFAULT; break; + default: + err = - EINVAL; + break; } return err; } +static int do_sys32_msgsnd (int first, int second, int third, void *uptr) { struct msgbuf32 *up = (struct msgbuf32 *)uptr; @@ -1886,7 +2023,8 @@ int err = -EFAULT, err2; struct shmid_ds s; struct shmid64_ds s64; - struct shmid_ds32 *up = (struct shmid_ds32 *)uptr; + struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; + struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; mm_segment_t old_fs; struct shm_info32 { int used_ids; @@ -1895,18 +2033,24 @@ } *uip = (struct shm_info32 *)uptr; struct shm_info si; - switch (second) { - + switch (second & ~IPC_64) { case IPC_INFO: + second = IPC_INFO; /* So that we don't have to translate it */ case IPC_RMID: case SHM_LOCK: case SHM_UNLOCK: err = sys_shmctl (first, second, (struct shmid_ds *)uptr); break; case IPC_SET: - err = get_user (s.shm_perm.uid, &up->shm_perm.uid); - err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid); - err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode); + if (second & IPC_64) { + err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); + err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); + err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); + } else { + err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); + err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); + err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); + } if (err) break; old_fs = get_fs (); @@ -1923,23 +2067,45 @@ set_fs (old_fs); if (err < 0) break; - err2 = put_user (s64.shm_perm.key, &up->shm_perm.key); - err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid); - err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid); - err2 |= __put_user (s64.shm_perm.cuid, - &up->shm_perm.cuid); - err2 |= __put_user (s64.shm_perm.cgid, - &up->shm_perm.cgid); - err2 |= __put_user (s64.shm_perm.mode, - &up->shm_perm.mode); - err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq); - err2 |= __put_user (s64.shm_atime, &up->shm_atime); - err2 |= __put_user (s64.shm_dtime, &up->shm_dtime); - err2 |= __put_user (s64.shm_ctime, &up->shm_ctime); - err2 |= __put_user (s64.shm_segsz, &up->shm_segsz); - err2 |= __put_user (s64.shm_nattch, &up->shm_nattch); - err2 |= __put_user (s64.shm_cpid, &up->shm_cpid); - err2 |= __put_user (s64.shm_lpid, &up->shm_lpid); + if (second & IPC_64) { + if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { + err = -EFAULT; + break; + } + err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); + err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); + err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); + err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); + err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); + err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); + err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); + err2 |= __put_user(s64.shm_atime, &up64->shm_atime); + err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); + err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); + err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); + err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); + err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); + err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); + } else { + if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { + err = -EFAULT; + break; + } + err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); + err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); + err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); + err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); + err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); + err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); + err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); + err2 |= __put_user(s64.shm_atime, &up32->shm_atime); + err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); + err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); + err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); + err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); + err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); + err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); + } if (err2) err = -EFAULT; break; @@ -1963,7 +2129,11 @@ err = -EFAULT; break; + default: + err = -ENOSYS; + break; } + return err; } @@ -2037,83 +2207,55 @@ unsigned int __unused[4]; }; -asmlinkage long sys32_sysctl(struct sysctl_args32 *uargs32) -{ - struct __sysctl_args kargs; - struct sysctl_args32 kargs32; - mm_segment_t old_fs; - int name[CTL_MAXNAME]; - size_t oldlen[1]; - int err, ret; - - ret = -EFAULT; - - memset(&kargs, 0, sizeof (kargs)); - - err = get_user(kargs32.name, &uargs32->name); - err |= __get_user(kargs32.nlen, &uargs32->nlen); - err |= __get_user(kargs32.oldval, &uargs32->oldval); - err |= __get_user(kargs32.oldlenp, &uargs32->oldlenp); - err |= __get_user(kargs32.newval, &uargs32->newval); - err |= __get_user(kargs32.newlen, &uargs32->newlen); - if (err) - goto out; +#ifdef CONFIG_SYSCTL - if (kargs32.nlen == 0 || kargs32.nlen >= CTL_MAXNAME) { - ret = -ENOTDIR; - goto out; - } +asmlinkage long sys32_sysctl(struct sysctl_args32 *args) +{ + struct sysctl_args32 tmp; + int error; + size_t oldlen, *oldlenp = NULL; + unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; - kargs.name = name; - kargs.nlen = kargs32.nlen; - if (copy_from_user(kargs.name, (int *)A(kargs32.name), - kargs32.nlen * sizeof(name) / sizeof(name[0]))) - goto out; + if (copy_from_user(&tmp, args, sizeof(tmp))) + return -EFAULT; - if (kargs32.oldval) { - if (!kargs32.oldlenp || get_user(oldlen[0], - (int *)A(kargs32.oldlenp))) + if (tmp.oldval && tmp.oldlenp) { + /* Duh, this is ugly and might not work if sysctl_args + is in read-only memory, but do_sysctl does indirectly + a lot of uaccess in both directions and we'd have to + basically copy the whole sysctl.c here, and + glibc's __sysctl uses rw memory for the structure + anyway. */ + if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || + put_user(oldlen, (size_t *)addr)) return -EFAULT; - kargs.oldlenp = oldlen; - kargs.oldval = kmalloc(oldlen[0], GFP_KERNEL); - if (!kargs.oldval) { - ret = -ENOMEM; - goto out; - } + oldlenp = (size_t *)addr; } - if (kargs32.newval && kargs32.newlen) { - kargs.newval = kmalloc(kargs32.newlen, GFP_KERNEL); - if (!kargs.newval) { - ret = -ENOMEM; - goto out; + lock_kernel(); + error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), + oldlenp, (void *)A(tmp.newval), tmp.newlen); + unlock_kernel(); + if (oldlenp) { + if (!error) { + if (get_user(oldlen, (size_t *)addr) || + put_user(oldlen, (u32 *)A(tmp.oldlenp))) + error = -EFAULT; } - if (copy_from_user(kargs.newval, (int *)A(kargs32.newval), - kargs32.newlen)) - goto out; + copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); } + return error; +} - old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_sysctl(&kargs); - set_fs (old_fs); - - if (ret) - goto out; +#else /* CONFIG_SYSCTL */ - if (kargs.oldval) { - if (put_user(oldlen[0], (int *)A(kargs32.oldlenp)) || - copy_to_user((int *)A(kargs32.oldval), kargs.oldval, - oldlen[0])) - ret = -EFAULT; - } -out: - if (kargs.oldval) - kfree(kargs.oldval); - if (kargs.newval) - kfree(kargs.newval); - return ret; +asmlinkage long sys32_sysctl(struct sysctl_args32 *args) +{ + return -ENOSYS; } +#endif /* CONFIG_SYSCTL */ + asmlinkage long sys32_newuname(struct new_utsname * name) { int ret = 0; @@ -2219,7 +2361,7 @@ /* * Declare the 32-bit version of the msghdr */ - + struct msghdr32 { unsigned int msg_name; /* Socket name */ int msg_namelen; /* Length of name */ @@ -2230,74 +2372,132 @@ unsigned msg_flags; }; -static inline int -shape_msg(struct msghdr *mp, struct msghdr32 *mp32) +struct cmsghdr32 { + __kernel_size_t32 cmsg_len; + int cmsg_level; + int cmsg_type; +}; + +/* Bleech... */ +#define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen)) +#define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen)) + +#define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) ) + +#define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32)))) +#define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len)) +#define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len)) + +#define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \ + (struct cmsghdr32 *)(ctl) : \ + (struct cmsghdr32 *)NULL) +#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen) + +__inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size, + struct cmsghdr32 *__cmsg, int __cmsg_len) { - int ret; - unsigned int i; + struct cmsghdr32 * __ptr; - if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32))) - return(-EFAULT); - ret = __get_user(i, &mp32->msg_name); - mp->msg_name = (void *)A(i); - ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen); - ret |= __get_user(i, &mp32->msg_iov); - mp->msg_iov = (struct iovec *)A(i); - ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen); - ret |= __get_user(i, &mp32->msg_control); - mp->msg_control = (void *)A(i); - ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen); - ret |= __get_user(mp->msg_flags, &mp32->msg_flags); - return(ret ? -EFAULT : 0); + __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) + + CMSG32_ALIGN(__cmsg_len)); + if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size) + return NULL; + + return __ptr; } -/* - * Verify & re-shape IA32 iovec. The caller must ensure that the - * iovec is big enough to hold the re-shaped message iovec. - * - * Save time not doing verify_area. copy_*_user will make this work - * in any case. - * - * Don't need to check the total size for overflow (cf net/core/iovec.c), - * 32-bit sizes can't overflow a 64-bit count. - */ +__inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg, + struct cmsghdr32 *__cmsg, + int __cmsg_len) +{ + return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen, + __cmsg, __cmsg_len); +} -static inline int -verify_iovec32(struct msghdr *m, struct iovec *iov, char *address, int mode) +static inline int iov_from_user32_to_kern(struct iovec *kiov, + struct iovec32 *uiov32, + int niov) { - int size, err, ct; - struct iovec32 *iov32; + int tot_len = 0; - if(m->msg_namelen) - { - if(mode==VERIFY_READ) - { - err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address); - if(err<0) - goto out; + while(niov > 0) { + u32 len, buf; + + if(get_user(len, &uiov32->iov_len) || + get_user(buf, &uiov32->iov_base)) { + tot_len = -EFAULT; + break; } + tot_len += len; + kiov->iov_base = (void *)AA(buf); + kiov->iov_len = (__kernel_size_t) len; + uiov32++; + kiov++; + niov--; + } + return tot_len; +} - m->msg_name = address; - } else - m->msg_name = NULL; +static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg, + struct msghdr32 *umsg) +{ + u32 tmp1, tmp2, tmp3; + int err; - err = -EFAULT; - size = m->msg_iovlen * sizeof(struct iovec32); - if (copy_from_user(iov, m->msg_iov, size)) - goto out; - m->msg_iov=iov; + err = get_user(tmp1, &umsg->msg_name); + err |= __get_user(tmp2, &umsg->msg_iov); + err |= __get_user(tmp3, &umsg->msg_control); + if (err) + return -EFAULT; - err = 0; - iov32 = (struct iovec32 *)iov; - for (ct = m->msg_iovlen; ct-- > 0; ) { - iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len; - iov[ct].iov_base = (void *) A(iov32[ct].iov_base); - err += iov[ct].iov_len; - } -out: + kmsg->msg_name = (void *)AA(tmp1); + kmsg->msg_iov = (struct iovec *)AA(tmp2); + kmsg->msg_control = (void *)AA(tmp3); + + err = get_user(kmsg->msg_namelen, &umsg->msg_namelen); + err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen); + err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen); + err |= get_user(kmsg->msg_flags, &umsg->msg_flags); + return err; } +/* I've named the args so it is easy to tell whose space the pointers are in. */ +static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov, + char *kern_address, int mode) +{ + int tot_len; + + if(kern_msg->msg_namelen) { + if(mode==VERIFY_READ) { + int err = move_addr_to_kernel(kern_msg->msg_name, + kern_msg->msg_namelen, + kern_address); + if(err < 0) + return err; + } + kern_msg->msg_name = kern_address; + } else + kern_msg->msg_name = NULL; + + if(kern_msg->msg_iovlen > UIO_FASTIOV) { + kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec), + GFP_KERNEL); + if(!kern_iov) + return -ENOMEM; + } + + tot_len = iov_from_user32_to_kern(kern_iov, + (struct iovec32 *)kern_msg->msg_iov, + kern_msg->msg_iovlen); + if(tot_len >= 0) + kern_msg->msg_iov = kern_iov; + else if(kern_msg->msg_iovlen > UIO_FASTIOV) + kfree(kern_iov); + + return tot_len; +} + extern __inline__ void sockfd_put(struct socket *sock) { @@ -2305,177 +2505,406 @@ } /* XXX This really belongs in some header file... -DaveM */ -#define MAX_SOCK_ADDR 128 /* 108 for Unix domain - +#define MAX_SOCK_ADDR 128 /* 108 for Unix domain - 16 for IP, 16 for IPX, 24 for IPv6, about 80 for AX.25 */ extern struct socket *sockfd_lookup(int fd, int *err); -/* - * BSD sendmsg interface +/* There is a lot of hair here because the alignment rules (and + * thus placement) of cmsg headers and length are different for + * 32-bit apps. -DaveM */ - -int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags) +static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg, + unsigned char *stackbuf, int stackbuf_size) { - struct socket *sock; - char address[MAX_SOCK_ADDR]; - struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; - unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */ - unsigned char *ctl_buf = ctl; - struct msghdr msg_sys; - int err, ctl_len, iov_size, total_len; + struct cmsghdr32 *ucmsg; + struct cmsghdr *kcmsg, *kcmsg_base; + __kernel_size_t32 ucmlen; + __kernel_size_t kcmlen, tmp; + + kcmlen = 0; + kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf; + ucmsg = CMSG32_FIRSTHDR(kmsg); + while(ucmsg != NULL) { + if(get_user(ucmlen, &ucmsg->cmsg_len)) + return -EFAULT; - err = -EFAULT; - if (shape_msg(&msg_sys, msg)) - goto out; + /* Catch bogons. */ + if(CMSG32_ALIGN(ucmlen) < + CMSG32_ALIGN(sizeof(struct cmsghdr32))) + return -ENOBUFS; + if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control) + + ucmlen) > kmsg->msg_controllen) + return -EINVAL; + + tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) + + CMSG_ALIGN(sizeof(struct cmsghdr))); + kcmlen += tmp; + ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen); + } + if(kcmlen == 0) + return -EINVAL; - sock = sockfd_lookup(fd, &err); - if (!sock) - goto out; + /* The kcmlen holds the 64-bit version of the control length. + * It may not be modified as we do not stick it into the kmsg + * until we have successfully copied over all of the data + * from the user. + */ + if(kcmlen > stackbuf_size) + kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL); + if(kcmsg == NULL) + return -ENOBUFS; + + /* Now copy them over neatly. */ + memset(kcmsg, 0, kcmlen); + ucmsg = CMSG32_FIRSTHDR(kmsg); + while(ucmsg != NULL) { + __get_user(ucmlen, &ucmsg->cmsg_len); + tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) + + CMSG_ALIGN(sizeof(struct cmsghdr))); + kcmsg->cmsg_len = tmp; + __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level); + __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type); + + /* Copy over the data. */ + if(copy_from_user(CMSG_DATA(kcmsg), + CMSG32_DATA(ucmsg), + (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))))) + goto out_free_efault; + + /* Advance. */ + kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp)); + ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen); + } + + /* Ok, looks like we made it. Hook it up and return success. */ + kmsg->msg_control = kcmsg_base; + kmsg->msg_controllen = kcmlen; + return 0; - /* do not move before msg_sys is valid */ - err = -EINVAL; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - goto out_put; +out_free_efault: + if(kcmsg_base != (struct cmsghdr *)stackbuf) + kfree(kcmsg_base); + return -EFAULT; +} - /* Check whether to allocate the iovec area*/ - err = -ENOMEM; - iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32); - if (msg_sys.msg_iovlen > UIO_FASTIOV) { - iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); - if (!iov) - goto out_put; +static void put_cmsg32(struct msghdr *kmsg, int level, int type, + int len, void *data) +{ + struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control; + struct cmsghdr32 cmhdr; + int cmlen = CMSG32_LEN(len); + + if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) { + kmsg->msg_flags |= MSG_CTRUNC; + return; } - /* This will also move the address data into kernel space */ - err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ); - if (err < 0) - goto out_freeiov; - total_len = err; + if(kmsg->msg_controllen < cmlen) { + kmsg->msg_flags |= MSG_CTRUNC; + cmlen = kmsg->msg_controllen; + } + cmhdr.cmsg_level = level; + cmhdr.cmsg_type = type; + cmhdr.cmsg_len = cmlen; - err = -ENOBUFS; + if(copy_to_user(cm, &cmhdr, sizeof cmhdr)) + return; + if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32))) + return; + cmlen = CMSG32_SPACE(len); + kmsg->msg_control += cmlen; + kmsg->msg_controllen -= cmlen; +} + +static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm) +{ + struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control; + int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int); + int fdnum = scm->fp->count; + struct file **fp = scm->fp->fp; + int *cmfptr; + int err = 0, i; + + if (fdnum < fdmax) + fdmax = fdnum; + + for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) { + int new_fd; + err = get_unused_fd(); + if (err < 0) + break; + new_fd = err; + err = put_user(new_fd, cmfptr); + if (err) { + put_unused_fd(new_fd); + break; + } + /* Bump the usage count and install the file. */ + get_file(fp[i]); + fd_install(new_fd, fp[i]); + } - if (msg_sys.msg_controllen > INT_MAX) - goto out_freeiov; - ctl_len = msg_sys.msg_controllen; - if (ctl_len) - { - if (ctl_len > sizeof(ctl)) - { - err = -ENOBUFS; - ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL); - if (ctl_buf == NULL) - goto out_freeiov; + if (i > 0) { + int cmlen = CMSG32_LEN(i * sizeof(int)); + if (!err) + err = put_user(SOL_SOCKET, &cm->cmsg_level); + if (!err) + err = put_user(SCM_RIGHTS, &cm->cmsg_type); + if (!err) + err = put_user(cmlen, &cm->cmsg_len); + if (!err) { + cmlen = CMSG32_SPACE(i * sizeof(int)); + kmsg->msg_control += cmlen; + kmsg->msg_controllen -= cmlen; } - err = -EFAULT; - if (copy_from_user(ctl_buf, msg_sys.msg_control, ctl_len)) - goto out_freectl; - msg_sys.msg_control = ctl_buf; - } - msg_sys.msg_flags = flags; - - if (sock->file->f_flags & O_NONBLOCK) - msg_sys.msg_flags |= MSG_DONTWAIT; - err = sock_sendmsg(sock, &msg_sys, total_len); - -out_freectl: - if (ctl_buf != ctl) - sock_kfree_s(sock->sk, ctl_buf, ctl_len); -out_freeiov: - if (iov != iovstack) - sock_kfree_s(sock->sk, iov, iov_size); -out_put: - sockfd_put(sock); -out: - return err; + } + if (i < fdnum) + kmsg->msg_flags |= MSG_CTRUNC; + + /* + * All of the files that fit in the message have had their + * usage counts incremented, so we just free the list. + */ + __scm_destroy(scm); } -/* - * BSD recvmsg interface +/* In these cases we (currently) can just copy to data over verbatim + * because all CMSGs created by the kernel have well defined types which + * have the same layout in both the 32-bit and 64-bit API. One must add + * some special cased conversions here if we start sending control messages + * with incompatible types. + * + * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after + * we do our work. The remaining cases are: + * + * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean + * IP_TTL int 32-bit clean + * IP_TOS __u8 32-bit clean + * IP_RECVOPTS variable length 32-bit clean + * IP_RETOPTS variable length 32-bit clean + * (these last two are clean because the types are defined + * by the IPv4 protocol) + * IP_RECVERR struct sock_extended_err + + * struct sockaddr_in 32-bit clean + * SOL_IPV6 IPV6_RECVERR struct sock_extended_err + + * struct sockaddr_in6 32-bit clean + * IPV6_PKTINFO struct in6_pktinfo 32-bit clean + * IPV6_HOPLIMIT int 32-bit clean + * IPV6_FLOWINFO u32 32-bit clean + * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean + * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean + * IPV6_RTHDR ipv6 routing exthdr 32-bit clean + * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ - -int -sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) { - struct socket *sock; - struct iovec iovstack[UIO_FASTIOV]; - struct iovec *iov=iovstack; - struct msghdr msg_sys; - unsigned long cmsg_ptr; - int err, iov_size, total_len, len; + unsigned char *workbuf, *wp; + unsigned long bufsz, space_avail; + struct cmsghdr *ucmsg; + + bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr; + space_avail = kmsg->msg_controllen + bufsz; + wp = workbuf = kmalloc(bufsz, GFP_KERNEL); + if(workbuf == NULL) + goto fail; + + /* To make this more sane we assume the kernel sends back properly + * formatted control messages. Because of how the kernel will truncate + * the cmsg_len for MSG_TRUNC cases, we need not check that case either. + */ + ucmsg = (struct cmsghdr *) orig_cmsg_uptr; + while(((unsigned long)ucmsg) <= + (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) { + struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp; + int clen64, clen32; + + /* UCMSG is the 64-bit format CMSG entry in user-space. + * KCMSG32 is within the kernel space temporary buffer + * we use to convert into a 32-bit style CMSG. + */ + __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len); + __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level); + __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); + + clen64 = kcmsg32->cmsg_len; + copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), + clen64 - CMSG_ALIGN(sizeof(*ucmsg))); + clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + + CMSG32_ALIGN(sizeof(struct cmsghdr32))); + kcmsg32->cmsg_len = clen32; + + ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64)); + wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32)); + } + + /* Copy back fixed up data, and adjust pointers. */ + bufsz = (wp - workbuf); + copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz); + + kmsg->msg_control = (struct cmsghdr *) + (((char *)orig_cmsg_uptr) + bufsz); + kmsg->msg_controllen = space_avail - bufsz; - /* kernel mode address */ - char addr[MAX_SOCK_ADDR]; + kfree(workbuf); + return; - /* user mode address pointers */ - struct sockaddr *uaddr; - int *uaddr_len; +fail: + /* If we leave the 64-bit format CMSG chunks in there, + * the application could get confused and crash. So to + * ensure greater recovery, we report no CMSGs. + */ + kmsg->msg_controllen += bufsz; + kmsg->msg_control = (void *) orig_cmsg_uptr; +} - err=-EFAULT; - if (shape_msg(&msg_sys, msg)) - goto out; +asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags) +{ + struct socket *sock; + char address[MAX_SOCK_ADDR]; + struct iovec iov[UIO_FASTIOV]; + unsigned char ctl[sizeof(struct cmsghdr) + 20]; + unsigned char *ctl_buf = ctl; + struct msghdr kern_msg; + int err, total_len; - sock = sockfd_lookup(fd, &err); - if (!sock) + if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) + return -EFAULT; + if(kern_msg.msg_iovlen > UIO_MAXIOV) + return -EINVAL; + err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ); + if (err < 0) goto out; + total_len = err; - err = -EINVAL; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - goto out_put; + if(kern_msg.msg_controllen) { + err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl)); + if(err) + goto out_freeiov; + ctl_buf = kern_msg.msg_control; + } + kern_msg.msg_flags = user_flags; - /* Check whether to allocate the iovec area*/ - err = -ENOMEM; - iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); - if (msg_sys.msg_iovlen > UIO_FASTIOV) { - iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); - if (!iov) - goto out_put; + sock = sockfd_lookup(fd, &err); + if (sock != NULL) { + if (sock->file->f_flags & O_NONBLOCK) + kern_msg.msg_flags |= MSG_DONTWAIT; + err = sock_sendmsg(sock, &kern_msg, total_len); + sockfd_put(sock); } - /* - * Save the user-mode address (verify_iovec will change the - * kernel msghdr to use the kernel address space) - */ + /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */ + if(ctl_buf != ctl) + kfree(ctl_buf); +out_freeiov: + if(kern_msg.msg_iov != iov) + kfree(kern_msg.msg_iov); +out: + return err; +} - uaddr = msg_sys.msg_name; - uaddr_len = &msg->msg_namelen; - err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE); - if (err < 0) - goto out_freeiov; - total_len=err; +asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags) +{ + struct iovec iovstack[UIO_FASTIOV]; + struct msghdr kern_msg; + char addr[MAX_SOCK_ADDR]; + struct socket *sock; + struct iovec *iov = iovstack; + struct sockaddr *uaddr; + int *uaddr_len; + unsigned long cmsg_ptr; + int err, total_len, len = 0; - cmsg_ptr = (unsigned long)msg_sys.msg_control; - msg_sys.msg_flags = 0; + if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) + return -EFAULT; + if(kern_msg.msg_iovlen > UIO_MAXIOV) + return -EINVAL; - if (sock->file->f_flags & O_NONBLOCK) - flags |= MSG_DONTWAIT; - err = sock_recvmsg(sock, &msg_sys, total_len, flags); + uaddr = kern_msg.msg_name; + uaddr_len = &user_msg->msg_namelen; + err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE); if (err < 0) - goto out_freeiov; - len = err; + goto out; + total_len = err; - if (uaddr != NULL) { - err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); - if (err < 0) - goto out_freeiov; + cmsg_ptr = (unsigned long) kern_msg.msg_control; + kern_msg.msg_flags = 0; + + sock = sockfd_lookup(fd, &err); + if (sock != NULL) { + struct scm_cookie scm; + + if (sock->file->f_flags & O_NONBLOCK) + user_flags |= MSG_DONTWAIT; + memset(&scm, 0, sizeof(scm)); + err = sock->ops->recvmsg(sock, &kern_msg, total_len, + user_flags, &scm); + if(err >= 0) { + len = err; + if(!kern_msg.msg_control) { + if(sock->passcred || scm.fp) + kern_msg.msg_flags |= MSG_CTRUNC; + if(scm.fp) + __scm_destroy(&scm); + } else { + /* If recvmsg processing itself placed some + * control messages into user space, it's is + * using 64-bit CMSG processing, so we need + * to fix it up before we tack on more stuff. + */ + if((unsigned long) kern_msg.msg_control != cmsg_ptr) + cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr); + + /* Wheee... */ + if(sock->passcred) + put_cmsg32(&kern_msg, + SOL_SOCKET, SCM_CREDENTIALS, + sizeof(scm.creds), &scm.creds); + if(scm.fp != NULL) + scm_detach_fds32(&kern_msg, &scm); + } + } + sockfd_put(sock); } - err = __put_user(msg_sys.msg_flags, &msg->msg_flags); - if (err) - goto out_freeiov; - err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, - &msg->msg_controllen); - if (err) - goto out_freeiov; - err = len; -out_freeiov: - if (iov != iovstack) - sock_kfree_s(sock->sk, iov, iov_size); -out_put: - sockfd_put(sock); + if(uaddr != NULL && kern_msg.msg_namelen && err >= 0) + err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len); + if(cmsg_ptr != 0 && err >= 0) { + unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control); + __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr); + err |= __put_user(uclen, &user_msg->msg_controllen); + } + if(err >= 0) + err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags); + if(kern_msg.msg_iov != iov) + kfree(kern_msg.msg_iov); out: - return err; + if(err < 0) + return err; + return len; +} + +extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count); + +asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count) +{ + mm_segment_t old_fs = get_fs(); + int ret; + off_t of; + + if (offset && get_user(of, offset)) + return -EFAULT; + + set_fs(KERNEL_DS); + ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); + set_fs(old_fs); + + if (offset && put_user(of, offset)) + return -EFAULT; + + return ret; } asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count); @@ -2520,7 +2949,37 @@ return i; } -#else +#else /* CONFIG_MODULES */ + +asmlinkage unsigned long +sys32_create_module(const char *name_user, size_t size) +{ + return -ENOSYS; +} + +asmlinkage int +sys32_init_module(const char *name_user, struct module *mod_user) +{ + return -ENOSYS; +} + +asmlinkage int +sys32_delete_module(const char *name_user) +{ + return -ENOSYS; +} + +asmlinkage int +sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize, + size_t *ret) +{ + /* Let the program know about the new interface. Not that + it'll do them much good. */ + if (which == 0) + return 0; + + return -ENOSYS; +} asmlinkage long sys32_get_kernel_syms(struct kernel_sym *table) @@ -2528,4 +2987,4 @@ return -ENOSYS; } -#endif +#endif /* CONFIG_MODULES */ diff -urN linux-2.4.21/arch/mips64/kernel/mips64_ksyms.c linux-2.4.22/arch/mips64/kernel/mips64_ksyms.c --- linux-2.4.21/arch/mips64/kernel/mips64_ksyms.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/mips64_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -19,7 +19,9 @@ #include #include +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) #include +#endif #include #include #include @@ -79,17 +81,6 @@ /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); -/* - * Functions to control caches. - */ -EXPORT_SYMBOL(_flush_page_to_ram); -EXPORT_SYMBOL(_flush_cache_l1); - -#ifdef CONFIG_NONCOHERENT_IO -EXPORT_SYMBOL(_dma_cache_wback_inv); -EXPORT_SYMBOL(_dma_cache_inv); -#endif - EXPORT_SYMBOL(invalid_pte_table); /* diff -urN linux-2.4.21/arch/mips64/kernel/pci-dma.c linux-2.4.22/arch/mips64/kernel/pci-dma.c --- linux-2.4.21/arch/mips64/kernel/pci-dma.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/pci-dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -21,6 +21,7 @@ { void *ret; int gfp = GFP_ATOMIC; + struct pci_bus *bus = NULL; #ifdef CONFIG_ISA if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) @@ -30,7 +31,9 @@ if (ret != NULL) { memset(ret, 0, size); - *dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret)); + if (hwdev) + bus = hwdev->bus; + *dma_handle = bus_to_baddr(bus, __pa(ret)); #ifdef CONFIG_NONCOHERENT_IO dma_cache_wback_inv((unsigned long) ret, size); ret = UNCAC_ADDR(ret); diff -urN linux-2.4.21/arch/mips64/kernel/proc.c linux-2.4.22/arch/mips64/kernel/proc.c --- linux-2.4.21/arch/mips64/kernel/proc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/proc.c 2003-08-25 04:44:40.000000000 -0700 @@ -17,10 +17,6 @@ unsigned int vced_count, vcei_count; -#ifndef CONFIG_CPU_HAS_LLSC -unsigned long ll_ops, sc_ops; -#endif - static const char *cpu_name[] = { [CPU_UNKNOWN] "unknown", [CPU_R2000] "R2000", @@ -66,21 +62,21 @@ [CPU_VR41XX] "NEC Vr41xx", [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", - [CPU_TX39XX] "TX39xx", [CPU_20KC] "MIPS 20Kc", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", [CPU_VR4181] "NEC VR4181", - [CPU_VR4181A] "NEC VR4181A" + [CPU_VR4181A] "NEC VR4181A", + [CPU_SR71000] "Sandcraft SR71000" }; static int show_cpuinfo(struct seq_file *m, void *v) { - unsigned int version = mips_cpu.processor_id; - unsigned int fp_vers = mips_cpu.fpu_id; + unsigned int version = current_cpu_data.processor_id; + unsigned int fp_vers = current_cpu_data.fpu_id; unsigned long n = (unsigned long) v - 1; char fmt [64]; @@ -97,9 +93,9 @@ seq_printf(m, "processor\t\t: %ld\n", n); sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", - (mips_cpu.options & MIPS_CPU_FPU) ? " FPU V%d.%d" : ""); - seq_printf(m, fmt, cpu_name[mips_cpu.cputype <= CPU_LAST ? - mips_cpu.cputype : CPU_UNKNOWN], + cpu_has_fpu ? " FPU V%d.%d" : ""); + seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ? + current_cpu_data.cputype : CPU_UNKNOWN], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", @@ -107,23 +103,18 @@ (loops_per_jiffy / (5000/HZ)) % 100); seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); seq_printf(m, "microsecond timers\t: %s\n", - (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no"); - seq_printf(m, "tlb_entries\t\t: %d\n", mips_cpu.tlbsize); + cpu_has_counter ? "yes" : "no"); + seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize); seq_printf(m, "extra interrupt vector\t: %s\n", - (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no"); + cpu_has_divec ? "yes" : "no"); seq_printf(m, "hardware watchpoint\t: %s\n", - watch_available ? "yes" : "no"); + cpu_has_watch ? "yes" : "no"); sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", - (mips_cpu.options & MIPS_CPU_VCE) ? "%d" : "not available"); + cpu_has_vce ? "%d" : "not available"); seq_printf(m, fmt, 'D', vced_count); seq_printf(m, fmt, 'I', vcei_count); -#ifndef CONFIG_CPU_HAS_LLSC - seq_printf(m, "ll emulations\t\t: %lu\n", ll_ops); - seq_printf(m, "sc emulations\t\t: %lu\n", sc_ops); -#endif - return 0; } @@ -145,8 +136,8 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; diff -urN linux-2.4.21/arch/mips64/kernel/process.c linux-2.4.22/arch/mips64/kernel/process.c --- linux-2.4.21/arch/mips64/kernel/process.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/mips64/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -30,6 +32,8 @@ #include #include #include +#include +#include ATTRIB_NORET void cpu_idle(void) { @@ -46,32 +50,30 @@ } } -struct task_struct *last_task_used_math = NULL; - asmlinkage void ret_from_fork(void); +void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) +{ + unsigned long status; + + /* New thread loses kernel privileges. */ + status = regs->cp0_status & ~(ST0_CU0|ST0_FR|ST0_KSU); + status |= KSU_USER; + status |= (current->thread.mflags & MF_32BIT_REGS) ? 0 : ST0_FR; + regs->cp0_status = status; + current->used_math = 0; + lose_fpu(); + regs->cp0_epc = pc; + regs->regs[29] = sp; + current->thread.current_ds = USER_DS; +} + void exit_thread(void) { - /* Forget lazy fpu state */ - if (IS_FPU_OWNER()) { - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - } - CLEAR_FPU_OWNER(); - } } void flush_thread(void) { - /* Forget lazy fpu state */ - if (IS_FPU_OWNER()) { - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - } - CLEAR_FPU_OWNER(); - } } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, @@ -83,10 +85,10 @@ childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; - if (IS_FPU_OWNER()) { - if (mips_cpu.options & MIPS_CPU_FPU) - save_fp(p); + if (is_fpu_owner()) { + save_fp(p); } + /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; @@ -106,12 +108,12 @@ p->thread.reg31 = (unsigned long) ret_from_fork; /* - * New tasks loose permission to use the fpu. This accelerates context - * switching for most programs since they don't use the fpu. + * New tasks lose permission to use the fpu. This accelerates context + * switching for most programs since they don't use the fpu. Most + * MIPS IV CPUs use ST0_CU3 as ST0_XX flag so we leave it unchanged. */ - p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & - ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU); - childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1); + p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1|ST0_KSU); + childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); return 0; } @@ -119,33 +121,8 @@ /* Fill in the fpu structure for a core dump.. */ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { - /* We actually store the FPU info in the task->thread - * area. - */ - if (regs->cp0_status & ST0_CU1) { - memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); - return 1; - } - - return 0; /* Task didn't use the fpu at all. */ -} - -/* Fill in the user structure for a core dump.. */ -void dump_thread(struct pt_regs *regs, struct user *dump) -{ - dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; - dump->start_data = current->mm->start_data; - dump->start_stack = regs->regs[29] & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - dump->start_code) - >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data) - >> PAGE_SHIFT; - dump->u_ssize = (current->mm->start_stack - dump->start_stack + - PAGE_SIZE - 1) >> PAGE_SHIFT; - memcpy(&dump->regs[0], regs, sizeof(struct pt_regs)); - memcpy(&dump->regs[EF_SIZE/4], ¤t->thread.fpu, - sizeof(current->thread.fpu)); + memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } /* @@ -156,25 +133,26 @@ int retval; __asm__ __volatile__( - "move\t$6, $sp\n\t" - "move\t$4, %5\n\t" - "li\t$2, %1\n\t" - "syscall\n\t" - "beq\t$6, $sp, 1f\n\t" - "move\t$4, %3\n\t" - "jalr\t%4\n\t" - "move\t$4, $2\n\t" - "li\t$2, %2\n\t" - "syscall\n" - "1:\tmove\t%0, $2" - :"=r" (retval) - :"i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), - "r" (flags | CLONE_VM) - - /* The called subroutine might have destroyed any of the - * at, result, argument or temporary registers ... */ + " move $6, $sp \n" + " move $4, %5 \n" + " li $2, %1 \n" + " syscall \n" + " beq $6, $sp, 1f \n" + " move $4, %3 \n" + " jalr %4 \n" + " move $4, $2 \n" + " li $2, %2 \n" + " syscall \n" + "1: move %0, $2 \n" + : "=r" (retval) + : "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), + "r" (flags | CLONE_VM) + /* + * The called subroutine might have destroyed any of the + * at, result, argument or temporary registers ... + */ : "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + "$9","$10","$11","$12","$13","$14","$15","$24","$25","$31"); return retval; } @@ -187,6 +165,62 @@ #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) +struct mips_frame_info schedule_frame; +static struct mips_frame_info schedule_timeout_frame; +static struct mips_frame_info sleep_on_frame; +static struct mips_frame_info sleep_on_timeout_frame; +static struct mips_frame_info wait_for_completion_frame; +static int mips_frame_info_initialized; +static int __init get_frame_info(struct mips_frame_info *info, void *func) +{ + int i; + union mips_instruction *ip = (union mips_instruction *)func; + info->pc_offset = -1; + info->frame_offset = -1; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; + if (ip->i_format.opcode == sd_op && + ip->i_format.rs == 29) { + /* sd $ra, offset($sp) */ + if (ip->i_format.rt == 31) { + if (info->pc_offset != -1) + break; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + } + /* sd $s8, offset($sp) */ + if (ip->i_format.rt == 30) { + if (info->frame_offset != -1) + break; + info->frame_offset = + ip->i_format.simmediate / sizeof(long); + } + } + } + if (info->pc_offset == -1 || info->frame_offset == -1) { + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_offset = -1; + return -1; + } + + return 0; +} +void __init frame_info_init(void) +{ + mips_frame_info_initialized = + !get_frame_info(&schedule_frame, schedule) && + !get_frame_info(&schedule_timeout_frame, schedule_timeout) && + !get_frame_info(&sleep_on_frame, sleep_on) && + !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) && + !get_frame_info(&wait_for_completion_frame, wait_for_completion); +} + /* get_wchan - a maintenance nightmare ... */ unsigned long get_wchan(struct task_struct *p) { @@ -195,6 +229,8 @@ if (!p || p == current || p->state == TASK_RUNNING) return 0; + if (!mips_frame_info_initialized) + return 0; pc = thread_saved_pc(&p->thread); if (pc < first_sched || pc >= last_sched) goto out; @@ -207,30 +243,33 @@ goto schedule_timeout_caller; if (pc >= (unsigned long)interruptible_sleep_on) goto schedule_caller; + if (pc >= (unsigned long)wait_for_completion) + goto schedule_caller; goto schedule_timeout_caller; schedule_caller: - frame = ((unsigned long *)p->thread.reg30)[10]; - pc = ((unsigned long *)frame)[7]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + if (pc >= (unsigned long) sleep_on) + pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset]; + else + pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset]; goto out; schedule_timeout_caller: /* Must be schedule_timeout ... */ - pc = ((unsigned long *)p->thread.reg30)[11]; - frame = ((unsigned long *)p->thread.reg30)[10]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; /* The schedule_timeout frame ... */ - pc = ((unsigned long *)frame)[9]; - frame = ((unsigned long *)frame)[8]; + pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; if (pc >= first_sched && pc < last_sched) { - /* schedule_timeout called by interruptible_sleep_on_timeout */ - pc = ((unsigned long *)frame)[7]; - frame = ((unsigned long *)frame)[6]; + /* schedule_timeout called by [interruptible_]sleep_on_timeout */ + frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; + pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; } out: - if (current->thread.mflags & MF_32BIT) /* Kludge for 32-bit ps */ + if (current->thread.mflags & MF_32BIT_ADDR) /* Kludge for 32-bit ps */ pc &= 0xffffffff; return pc; diff -urN linux-2.4.21/arch/mips64/kernel/ptrace.c linux-2.4.22/arch/mips64/kernel/ptrace.c --- linux-2.4.21/arch/mips64/kernel/ptrace.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/ptrace.c 2003-08-25 04:44:40.000000000 -0700 @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -112,34 +113,19 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - if (mips_cpu.options & MIPS_CPU_FPU) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - } -#endif - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } - + unsigned long long *fregs; + fregs = (unsigned long long *)get_fpu_regs(child); /* * The odd registers are actually the high * order bits of the values stored in the even - * registers. + * registers - unless we're using r2k_switch.S. */ if (addr & 1) tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); else tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff); } else { - tmp = -EIO; + tmp = -1; /* FP not yet used */ } break; case PC: @@ -158,13 +144,13 @@ tmp = regs->lo; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) tmp = child->thread.fpu.hard.control; else tmp = child->thread.fpu.soft.sr; break; case FPC_EIR: { /* implementation / version register */ - unsigned int flags; + unsigned long flags; __save_flags(flags); __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); @@ -200,22 +186,8 @@ break; case FPR_BASE ... FPR_BASE + 31: { unsigned long long *fregs; - fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0]; - if (child->used_math) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } -#endif - } else { + fregs = (unsigned long long *)get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); @@ -228,10 +200,12 @@ */ if (addr & 1) { fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; - fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32; + fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32; } else { fregs[addr - FPR_BASE] &= ~0xffffffffLL; - fregs[addr - FPR_BASE] |= data; + /* Must cast, lest sign extension fill upper + bits! */ + fregs[addr - FPR_BASE] |= (unsigned int)data; } break; } @@ -245,7 +219,7 @@ regs->lo = data; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) child->thread.fpu.hard.control = data; else child->thread.fpu.soft.sr = data; @@ -255,7 +229,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ @@ -342,7 +316,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -383,32 +357,8 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - if (mips_cpu.options & MIPS_CPU_FPU) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - } -#endif - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } - - /* - * The odd registers are actually the high - * order bits of the values stored in the even - * registers. - */ - if (addr & 1) - tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); - else - tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff); + unsigned long *fregs = get_fpu_regs(child); + tmp = fregs[addr - FPR_BASE]; } else { tmp = -EIO; } @@ -429,13 +379,13 @@ tmp = regs->lo; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) tmp = child->thread.fpu.hard.control; else tmp = child->thread.fpu.soft.sr; break; case FPC_EIR: { /* implementation / version register */ - unsigned int flags; + unsigned long flags; __save_flags(flags); __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); @@ -470,42 +420,14 @@ regs->regs[addr] = data; break; case FPR_BASE ... FPR_BASE + 31: { - unsigned long long *fregs = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - - if (child->used_math) { -#ifndef CONFIG_SMP - if (mips_cpu.options & MIPS_CPU_FPU) { - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } - } -#endif - } else { + unsigned long *fregs = get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); child->thread.fpu.hard.control = 0; } - /* - * The odd registers are actually the high order bits - * of the values stored in the even registers - unless - * we're using r2k_switch.S. - */ - if (addr & 1) { - fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; - fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32; - } else { - fregs[addr - FPR_BASE] &= ~0xffffffffLL; - fregs[addr - FPR_BASE] |= data; - } + fregs[addr - FPR_BASE] = data; break; } case PC: @@ -518,7 +440,7 @@ regs->lo = data; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) child->thread.fpu.hard.control = data; else child->thread.fpu.soft.sr = data; @@ -528,7 +450,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ diff -urN linux-2.4.21/arch/mips64/kernel/r4k_fpu.S linux-2.4.22/arch/mips64/kernel/r4k_fpu.S --- linux-2.4.21/arch/mips64/kernel/r4k_fpu.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/r4k_fpu.S 2003-08-25 04:44:40.000000000 -0700 @@ -32,11 +32,8 @@ .set noreorder /* Save floating point context */ LEAF(_save_fp_context) - mfc0 t1, CP0_STATUS - sll t2, t1,5 + cfc1 t1, fcr31 - bgez t2, 1f - cfc1 t1, fcr31 /* Store the 16 odd double precision registers */ EX sdc1 $f1, SC_FPREGS+8(a0) EX sdc1 $f3, SC_FPREGS+24(a0) @@ -56,7 +53,6 @@ EX sdc1 $f31, SC_FPREGS+248(a0) /* Store the 16 even double precision registers */ -1: EX sdc1 $f0, SC_FPREGS+0(a0) EX sdc1 $f2, SC_FPREGS+16(a0) EX sdc1 $f4, SC_FPREGS+32(a0) @@ -81,24 +77,42 @@ li v0, 0 # success END(_save_fp_context) + /* Save 32-bit process floating point context */ +LEAF(_save_fp_context32) + cfc1 t1, fcr31 + + EX sdc1 $f0, SC32_FPREGS+0(a0) + EX sdc1 $f2, SC32_FPREGS+16(a0) + EX sdc1 $f4, SC32_FPREGS+32(a0) + EX sdc1 $f6, SC32_FPREGS+48(a0) + EX sdc1 $f8, SC32_FPREGS+64(a0) + EX sdc1 $f10, SC32_FPREGS+80(a0) + EX sdc1 $f12, SC32_FPREGS+96(a0) + EX sdc1 $f14, SC32_FPREGS+112(a0) + EX sdc1 $f16, SC32_FPREGS+128(a0) + EX sdc1 $f18, SC32_FPREGS+144(a0) + EX sdc1 $f20, SC32_FPREGS+160(a0) + EX sdc1 $f22, SC32_FPREGS+176(a0) + EX sdc1 $f24, SC32_FPREGS+192(a0) + EX sdc1 $f26, SC32_FPREGS+208(a0) + EX sdc1 $f28, SC32_FPREGS+224(a0) + EX sdc1 $f30, SC32_FPREGS+240(a0) + EX sw t1, SC32_FPC_CSR(a0) + cfc1 t0, $0 # implementation/version + EX sw t0, SC32_FPC_EIR(a0) + + jr ra + li v0, 0 # success + END(_save_fp_context32) + /* * Restore FPU state: * - fp gp registers * - cp1 status/control register - * - * We base the decision which registers to restore from the signal stack - * frame on the current content of c0_status, not on the content of the - * stack frame which might have been changed by the user. */ LEAF(_restore_fp_context) - mfc0 t1, CP0_STATUS - sll t0, t1,5 - bgez t0, 1f - EX lw t0, SC_FPC_CSR(a0) - - /* Restore the 16 odd double precision registers only - * when enabled in the cp0 status register. - */ + /* Restore an o32/64 sigcontext. */ + EX lw t0, SC_FPC_CSR(a0) EX ldc1 $f1, SC_FPREGS+8(a0) EX ldc1 $f3, SC_FPREGS+24(a0) EX ldc1 $f5, SC_FPREGS+40(a0) @@ -116,11 +130,7 @@ EX ldc1 $f29, SC_FPREGS+232(a0) EX ldc1 $f31, SC_FPREGS+248(a0) - /* - * Restore the 16 even double precision registers - * when cp1 was enabled in the cp0 status register. - */ -1: EX ldc1 $f0, SC_FPREGS+0(a0) + EX ldc1 $f0, SC_FPREGS+0(a0) EX ldc1 $f2, SC_FPREGS+16(a0) EX ldc1 $f4, SC_FPREGS+32(a0) EX ldc1 $f6, SC_FPREGS+48(a0) @@ -141,6 +151,30 @@ li v0, 0 # success END(_restore_fp_context) +LEAF(_restore_fp_context32) + /* Restore an o32 sigcontext. */ + EX lw t0, SC32_FPC_CSR(a0) + EX ldc1 $f0, SC32_FPREGS+0(a0) + EX ldc1 $f2, SC32_FPREGS+16(a0) + EX ldc1 $f4, SC32_FPREGS+32(a0) + EX ldc1 $f6, SC32_FPREGS+48(a0) + EX ldc1 $f8, SC32_FPREGS+64(a0) + EX ldc1 $f10, SC32_FPREGS+80(a0) + EX ldc1 $f12, SC32_FPREGS+96(a0) + EX ldc1 $f14, SC32_FPREGS+112(a0) + EX ldc1 $f16, SC32_FPREGS+128(a0) + EX ldc1 $f18, SC32_FPREGS+144(a0) + EX ldc1 $f20, SC32_FPREGS+160(a0) + EX ldc1 $f22, SC32_FPREGS+176(a0) + EX ldc1 $f24, SC32_FPREGS+192(a0) + EX ldc1 $f26, SC32_FPREGS+208(a0) + EX ldc1 $f28, SC32_FPREGS+224(a0) + EX ldc1 $f30, SC32_FPREGS+240(a0) + ctc1 t0, fcr31 + jr ra + li v0, 0 # success + END(_restore_fp_context32) + .type fault@function .ent fault fault: jr ra diff -urN linux-2.4.21/arch/mips64/kernel/r4k_genex.S linux-2.4.22/arch/mips64/kernel/r4k_genex.S --- linux-2.4.21/arch/mips64/kernel/r4k_genex.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/r4k_genex.S 2003-08-25 04:44:40.000000000 -0700 @@ -5,6 +5,7 @@ * * Copyright (C) 1994 - 1999 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics + * Copyright (C) 2002 Maciej W. Rozycki * * Low level exception handling */ @@ -15,7 +16,7 @@ #include #include #include -#include +#include BUILD_HANDLER adel ade ade silent /* #4 */ BUILD_HANDLER ades ade ade silent /* #5 */ @@ -27,29 +28,38 @@ BUILD_HANDLER ov ov sti silent /* #12 */ BUILD_HANDLER tr tr sti silent /* #13 */ BUILD_HANDLER fpe fpe fpe silent /* #15 */ + BUILD_HANDLER mdmx mdmx sti silent /* #22 */ BUILD_HANDLER watch watch sti verbose /* #23 */ BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ BUILD_HANDLER reserved reserved sti verbose /* others */ + __INIT +/* A temporary overflow handler used by check_daddi(). */ + + BUILD_HANDLER daddi_ov daddi_ov none silent /* #12 */ + + /* General exception handler for CPUs with virtual coherency exception. * - * Be careful when changing this, it has to be at most 128 bytes to fit - * into space reserved for the exception handler. + * Be careful when changing this, it has to be at most 256 (as a special + * exception) bytes to fit into space reserved for the exception handler. */ - NESTED(except_vec3_r4000, 0, sp) + .set push .set noat -#if defined(R5432_CP0_INTERRUPT_WAR) - mfc0 k0, CP0_INDEX -#endif +NESTED(except_vec3_r4000, 0, sp) mfc0 k1, CP0_CAUSE - andi k1, k1, 0x7c li k0, 31<<2 + andi k1, k1, 0x7c + .set push + .set noreorder + .set nomacro beq k1, k0, handle_vced li k0, 14<<2 beq k1, k0, handle_vcei dsll k1, k1, 1 + .set pop ld k0, exception_handlers(k1) jr k0 @@ -60,51 +70,61 @@ * store will be re-executed. */ handle_vced: - mfc0 k0, CP0_BADVADDR + dmfc0 k0, CP0_BADVADDR li k1, -4 # Is this ... and k0, k1 # ... really needed? mtc0 zero, CP0_TAGLO cache Index_Store_Tag_D,(k0) cache Hit_Writeback_Inv_SD,(k0) - lui k0, %hi(vced_count) - lw k1, %lo(vced_count)(k0) + dla k0, vced_count + lw k1, (k0) addiu k1, 1 - sw k1, %lo(vced_count)(k0) + sw k1, (k0) eret handle_vcei: - mfc0 k0, CP0_BADVADDR + dmfc0 k0, CP0_BADVADDR cache Hit_Writeback_Inv_SD,(k0) # also cleans pi - lui k0, %hi(vcei_count) - lw k1, %lo(vcei_count)(k0) + dla k0, vcei_count + lw k1, (k0) addiu k1, 1 - sw k1, %lo(vcei_count)(k0) + sw k1, (k0) eret +END(except_vec3_r4000) + .set pop - END(except_vec3_r4000) - .set at - /* General exception vector for all other CPUs. */ - NESTED(except_vec3_generic, 0, sp) +/* General exception vector for all other CPUs. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. + */ + .set push .set noat +NESTED(except_vec3_generic, 0, sp) +#if R5432_CP0_INTERRUPT_WAR + mfc0 k0, CP0_INDEX +#endif mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c dsll k1, k1, 1 ld k0, exception_handlers(k1) jr k0 - nop - END(except_vec3_generic) - .set at +END(except_vec3_generic) + .set pop + /* - * Special interrupt vector for embedded MIPS. This is a dedicated interrupt - * vector which reduces interrupt processing overhead. The jump instruction - * will be inserted here at initialization time. This handler may only be 8 - * bytes in size! + * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. + * This is a dedicated interrupt exception vector which reduces the + * interrupt processing overhead. The jump instruction will be replaced + * at the initialization time. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. */ NESTED(except_vec4, 0, sp) 1: j 1b /* Dummy, will be replaced */ - nop - END(except_vec4) +END(except_vec4) __FINIT diff -urN linux-2.4.21/arch/mips64/kernel/r4k_switch.S linux-2.4.22/arch/mips64/kernel/r4k_switch.S --- linux-2.4.21/arch/mips64/kernel/r4k_switch.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/r4k_switch.S 2003-08-25 04:44:40.000000000 -0700 @@ -23,6 +23,19 @@ .set mips3 +#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * [jsun] FPU context is saved if and only if the process has used FPU in + * the current run (PF_USEDFPU). In any case, the CU1 bit for user space + * STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* * task_struct *resume(task_struct *prev, task_struct *next) */ @@ -35,6 +48,38 @@ sd ra, THREAD_REG31(a0) /* + * check if we need to save FPU registers + */ + ld t0, TASK_FLAGS(a0) + li t1, PF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + /* + * clear PF_USEDFPU bit in task flags + */ + and t0, t0, t1 + sd t0, TASK_FLAGS(a0) + + /* + * clear saved user stack CU1 bit + */ + ld t0, ST_OFF(a0) + li t1, ~ST0_CU1 + and t0, t0, t1 + sd t0, ST_OFF(a0) + + + sll t2, t0, 5 + bgez t2, 2f + sdc1 $f0, (THREAD_FPU + 0x00)(a0) + fpu_save_16odd a0 +2: + fpu_save_16even a0 t1 # clobbers t1 +1: + + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. */ @@ -42,7 +87,7 @@ cpu_restore_nonscratch $28 daddiu a1, $28, KERNEL_STACK_SIZE-32 - set_saved_sp a1 t0 + set_saved_sp a1, t0, t1 mfc0 t1, CP0_STATUS /* Do we really need this? */ li a3, 0xff00 @@ -57,51 +102,10 @@ END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, ST0_CU1 - or t0, t3 - mtc0 t0, CP0_STATUS - FPU_ENABLE_HAZARD - - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - - ld t1, ST_OFF(a0) # last thread looses fpu - and t1, t3 - sd t1, ST_OFF(a0) - sll t2, t1, 5 - bgez t2, 1f - sdc1 $f0, (THREAD_FPU + 0x00)(a0) - fpu_save_16odd a0 -1: - fpu_save_16even a0 t1 # clobbers t1 -2: - - beqz a1, 3f - - sll t0, t0, 5 # load new fp state - bgez t0, 1f - ldc1 $f0, (THREAD_FPU + 0x00)(a1) - fpu_restore_16odd a1 -1: - .set reorder - fpu_restore_16even a1, t0 # clobbers t0 -3: - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ .set noreorder -LEAF(save_fp) +LEAF(_save_fp) mfc0 t0, CP0_STATUS sll t1, t0, 5 bgez t1, 1f # 16 register mode? @@ -111,12 +115,12 @@ fpu_save_16even a0 t1 # clobbers t1 jr ra sdc1 $f0, (THREAD_FPU + 0x00)(a0) - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) mfc0 t0, CP0_STATUS sll t1, t0, 5 bgez t1, 1f # 16 register mode? @@ -128,7 +132,7 @@ jr ra ldc1 $f0, (THREAD_FPU + 0x00)(a0) - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has @@ -140,7 +144,7 @@ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1 or t0, t1 @@ -188,4 +192,4 @@ dmtc1 t0, $f28 jr ra dmtc1 t0, $f30 - END(init_fpu) + END(_init_fpu) diff -urN linux-2.4.21/arch/mips64/kernel/scall_64.S linux-2.4.22/arch/mips64/kernel/scall_64.S --- linux-2.4.21/arch/mips64/kernel/scall_64.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/scall_64.S 2003-08-25 04:44:40.000000000 -0700 @@ -17,14 +17,15 @@ #include #include -#ifndef CONFIG_MIPS32_COMPAT +#ifndef CONFIG_BINFMT_ELF32 +/* Neither O32 nor N32, so define handle_sys here */ #define handle_sys64 handle_sys #endif .align 5 NESTED(handle_sys64, PT_SIZE, sp) /* When 32-bit compatibility is configured scall_o32.S already did this. */ -#ifndef CONFIG_MIPS32_COMPAT +#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32) .set noat SAVE_SOME STI @@ -66,7 +67,7 @@ SSNOP; SSNOP; SSNOP ld t2, TASK_NEED_RESCHED($28) - bnez t2, reschedule + bnez t2, _64_reschedule lw v0, TASK_SIGPENDING($28) bnez v0, signal_return @@ -83,12 +84,14 @@ ori t0, t0, 1 mtc0 t0, CP0_STATUS + SAVE_STATIC move a0, zero move a1, sp jal do_signal + RESTORE_STATIC b restore_all -reschedule: +_64_reschedule: SAVE_STATIC jal schedule b ret_from_sys_call @@ -130,237 +133,215 @@ .align 3 sys_call_table: - PTR sys_syscall /* 5000 */ - PTR sys_exit - PTR sys_fork - PTR sys_read + PTR sys_read /* 5000 */ PTR sys_write - PTR sys_open /* 5005 */ + PTR sys_open PTR sys_close - PTR sys_waitpid - PTR sys_creat - PTR sys_link - PTR sys_unlink /* 5010 */ - PTR sys_execve - PTR sys_chdir - PTR sys_time - PTR sys_mknod - PTR sys_chmod /* 5015 */ - PTR sys_lchown - PTR sys_ni_syscall - PTR sys_stat + PTR sys_newstat + PTR sys_newfstat /* 5005 */ + PTR sys_newlstat + PTR sys_poll PTR sys_lseek - PTR sys_getpid /* 5020 */ - PTR sys_mount - PTR sys_oldumount - PTR sys_setuid - PTR sys_getuid - PTR sys_stime /* 5025 */ - PTR sys_ni_syscall /* ptrace */ - PTR sys_alarm - PTR sys_fstat + PTR sys_mmap + PTR sys_mprotect /* 5010 */ + PTR sys_munmap + PTR sys_brk + PTR sys_rt_sigaction + PTR sys_rt_sigprocmask + PTR sys_ioctl /* 5015 */ + PTR sys_pread + PTR sys_pwrite + PTR sys_readv + PTR sys_writev + PTR sys_access /* 5020 */ + PTR sys_pipe + PTR sys_select + PTR sys_sched_yield + PTR sys_mremap + PTR sys_msync /* 5025 */ + PTR sys_mincore + PTR sys_madvise + PTR sys_shmget + PTR sys_shmat + PTR sys_shmctl /* 5030 */ + PTR sys_dup + PTR sys_dup2 PTR sys_pause - PTR sys_utime /* 5030 */ - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_access - PTR sys_nice - PTR sys_ni_syscall /* 5035 */ - PTR sys_sync - PTR sys_kill - PTR sys_rename + PTR sys_nanosleep + PTR sys_getitimer /* 5035 */ + PTR sys_setitimer + PTR sys_alarm + PTR sys_getpid + PTR sys_sendfile + PTR sys_socket /* 5040 */ + PTR sys_connect + PTR sys_accept + PTR sys_sendto + PTR sys_recvfrom + PTR sys_sendmsg /* 5045 */ + PTR sys_recvmsg + PTR sys_shutdown + PTR sys_bind + PTR sys_listen + PTR sys_getsockname /* 5050 */ + PTR sys_getpeername + PTR sys_socketpair + PTR sys_setsockopt + PTR sys_getsockopt + PTR sys_clone /* 5055 */ + PTR sys_fork + PTR sys_execve + PTR sys_exit + PTR sys_wait4 + PTR sys_kill /* 5060 */ + PTR sys_newuname + PTR sys_semget + PTR sys_semop + PTR sys_semctl + PTR sys_shmdt /* 5065 */ + PTR sys_msgget + PTR sys_msgsnd + PTR sys_msgrcv + PTR sys_msgctl + PTR sys_fcntl /* 5070 */ + PTR sys_flock + PTR sys_fsync + PTR sys_fdatasync + PTR sys_truncate + PTR sys_ftruncate /* 5075 */ + PTR sys_getdents + PTR sys_getcwd + PTR sys_chdir + PTR sys_fchdir + PTR sys_rename /* 5080 */ PTR sys_mkdir - PTR sys_rmdir /* 5040 */ - PTR sys_dup - PTR sys_pipe + PTR sys_rmdir + PTR sys_creat + PTR sys_link + PTR sys_unlink /* 5085 */ + PTR sys_symlink + PTR sys_readlink + PTR sys_chmod + PTR sys_fchmod + PTR sys_chown /* 5090 */ + PTR sys_fchown + PTR sys_lchown + PTR sys_umask + PTR sys_gettimeofday + PTR sys_getrlimit /* 5095 */ + PTR sys_getrusage + PTR sys_sysinfo PTR sys_times - PTR sys_ni_syscall - PTR sys_brk /* 5045 */ - PTR sys_setgid + PTR sys_ptrace + PTR sys_getuid /* 5100 */ + PTR sys_syslog PTR sys_getgid - PTR sys_ni_syscall /* was signal 2 */ - PTR sys_geteuid - PTR sys_getegid /* 5050 */ - PTR sys_acct - PTR sys_umount - PTR sys_ni_syscall - PTR sys_ioctl - PTR sys_fcntl /* 5055 */ - PTR sys_ni_syscall + PTR sys_setuid + PTR sys_setgid + PTR sys_geteuid /* 5105 */ + PTR sys_getegid PTR sys_setpgid - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_umask /* 5060 */ - PTR sys_chroot - PTR sys_ustat - PTR sys_dup2 PTR sys_getppid - PTR sys_getpgrp /* 5065 */ - PTR sys_setsid - PTR sys_sigaction - PTR sys_sgetmask - PTR sys_ssetmask - PTR sys_setreuid /* 5070 */ + PTR sys_getpgrp + PTR sys_setsid /* 5110 */ + PTR sys_setreuid PTR sys_setregid - PTR sys_sigsuspend - PTR sys_sigpending - PTR sys_sethostname - PTR sys_setrlimit /* 5075 */ - PTR sys_getrlimit - PTR sys_getrusage - PTR sys_gettimeofday - PTR sys_settimeofday - PTR sys_getgroups /* 5080 */ + PTR sys_getgroups PTR sys_setgroups - PTR sys_ni_syscall /* old_select */ - PTR sys_symlink - PTR sys_lstat - PTR sys_readlink /* 5085 */ - PTR sys_uselib - PTR sys_swapon - PTR sys_reboot - PTR sys_ni_syscall /* old_readdir */ - PTR sys_mmap /* 5090 */ - PTR sys_munmap - PTR sys_truncate - PTR sys_ftruncate - PTR sys_fchmod - PTR sys_fchown /* 5095 */ - PTR sys_getpriority - PTR sys_setpriority - PTR sys_ni_syscall - PTR sys_statfs - PTR sys_fstatfs /* 5100 */ - PTR sys_ni_syscall /* sys_ioperm */ - PTR sys_socketcall - PTR sys_syslog - PTR sys_setitimer - PTR sys_getitimer /* 5105 */ - PTR sys_newstat - PTR sys_newlstat - PTR sys_newfstat - PTR sys_ni_syscall - PTR sys_ni_syscall /* sys_ioperm *//* 5110 */ - PTR sys_vhangup - PTR sys_ni_syscall /* was sys_idle */ - PTR sys_ni_syscall /* sys_vm86 */ - PTR sys_wait4 - PTR sys_swapoff /* 5115 */ - PTR sys_sysinfo - PTR sys_ipc - PTR sys_fsync - PTR sys_sigreturn - PTR sys_clone /* 5120 */ - PTR sys_setdomainname - PTR sys_newuname - PTR sys_ni_syscall /* sys_modify_ldt */ - PTR sys_adjtimex - PTR sys_mprotect /* 5125 */ - PTR sys_sigprocmask - PTR sys_create_module - PTR sys_init_module - PTR sys_delete_module - PTR sys_get_kernel_syms /* 5130 */ - PTR sys_quotactl + PTR sys_setresuid /* 5115 */ + PTR sys_getresuid + PTR sys_setresgid + PTR sys_getresgid PTR sys_getpgid - PTR sys_fchdir - PTR sys_bdflush - PTR sys_sysfs /* 5135 */ - PTR sys_personality - PTR sys_ni_syscall /* for afs_syscall */ - PTR sys_setfsuid + PTR sys_setfsuid /* 5120 */ PTR sys_setfsgid - PTR sys_llseek /* 5140 */ - PTR sys_getdents - PTR sys_select - PTR sys_flock - PTR sys_msync - PTR sys_readv /* 5145 */ - PTR sys_writev - PTR sys_cacheflush - PTR sys_cachectl - PTR sys_sysmips - PTR sys_ni_syscall /* 5150 */ PTR sys_getsid - PTR sys_fdatasync - PTR sys_sysctl - PTR sys_mlock - PTR sys_munlock /* 5155 */ - PTR sys_mlockall - PTR sys_munlockall + PTR sys_capget + PTR sys_capset + PTR sys_rt_sigpending /* 5125 */ + PTR sys_rt_sigtimedwait + PTR sys_rt_sigqueueinfo + PTR sys_rt_sigsuspend + PTR sys_sigaltstack + PTR sys_utime /* 5130 */ + PTR sys_mknod + PTR sys_personality + PTR sys_ustat + PTR sys_statfs + PTR sys_fstatfs /* 5135 */ + PTR sys_sysfs + PTR sys_getpriority + PTR sys_setpriority PTR sys_sched_setparam - PTR sys_sched_getparam - PTR sys_sched_setscheduler /* 5160 */ + PTR sys_sched_getparam /* 5140 */ + PTR sys_sched_setscheduler PTR sys_sched_getscheduler - PTR sys_sched_yield PTR sys_sched_get_priority_max PTR sys_sched_get_priority_min - PTR sys_sched_rr_get_interval /* 5165 */ - PTR sys_nanosleep - PTR sys_mremap - PTR sys_accept - PTR sys_bind - PTR sys_connect /* 5170 */ - PTR sys_getpeername - PTR sys_getsockname - PTR sys_getsockopt - PTR sys_listen - PTR sys_recv /* 5175 */ - PTR sys_recvfrom - PTR sys_recvmsg - PTR sys_send - PTR sys_sendmsg - PTR sys_sendto /* 5180 */ - PTR sys_setsockopt - PTR sys_shutdown - PTR sys_socket - PTR sys_socketpair - PTR sys_setresuid /* 5185 */ - PTR sys_getresuid + PTR sys_sched_rr_get_interval /* 5145 */ + PTR sys_mlock + PTR sys_munlock + PTR sys_mlockall + PTR sys_munlockall + PTR sys_vhangup /* 5150 */ + PTR sys_pivot_root + PTR sys_sysctl + PTR sys_prctl + PTR sys_adjtimex + PTR sys_setrlimit /* 5155 */ + PTR sys_chroot + PTR sys_sync + PTR sys_acct + PTR sys_settimeofday + PTR sys_mount /* 5160 */ + PTR sys_umount + PTR sys_swapon + PTR sys_swapoff + PTR sys_reboot + PTR sys_sethostname /* 5165 */ + PTR sys_setdomainname + PTR sys_create_module + PTR sys_init_module + PTR sys_delete_module + PTR sys_get_kernel_syms /* 5170 */ PTR sys_query_module - PTR sys_poll + PTR sys_quotactl PTR sys_nfsservctl - PTR sys_setresgid /* 5190 */ - PTR sys_getresgid - PTR sys_prctl - PTR sys_rt_sigreturn - PTR sys_rt_sigaction - PTR sys_rt_sigprocmask /* 5195 */ - PTR sys_rt_sigpending - PTR sys_rt_sigtimedwait - PTR sys_rt_sigqueueinfo - PTR sys_rt_sigsuspend - PTR sys_pread /* 5200 */ - PTR sys_pwrite - PTR sys_chown - PTR sys_getcwd - PTR sys_capget - PTR sys_capset /* 5205 */ - PTR sys_sigaltstack - PTR sys_sendfile - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_pivot_root /* 5210 */ - PTR sys_mincore - PTR sys_madvise - PTR sys_getdents64 - PTR sys_ni_syscall - PTR sys_gettid /* 5215 */ + PTR sys_ni_syscall /* res. for getpmsg */ + PTR sys_ni_syscall /* 5175 for putpmsg */ + PTR sys_ni_syscall /* res. for afs_syscall */ + PTR sys_ni_syscall /* res. for security */ + PTR sys_gettid PTR sys_readahead - PTR sys_setxattr + PTR sys_setxattr /* 5180 */ PTR sys_lsetxattr PTR sys_fsetxattr - PTR sys_getxattr /* 5220 */ + PTR sys_getxattr PTR sys_lgetxattr - PTR sys_fgetxattr + PTR sys_fgetxattr /* 5185 */ PTR sys_listxattr PTR sys_llistxattr - PTR sys_flistxattr /* 5225 */ + PTR sys_flistxattr PTR sys_removexattr - PTR sys_lremovexattr + PTR sys_lremovexattr /* 5190 */ PTR sys_fremovexattr - PTR sys_tkill, 2 - PTR sys_ni_syscall, 0 /* 5230 res. for sendfile64 */ - PTR sys_ni_syscall, 0 /* res. for futex */ - PTR sys_ni_syscall, 0 /* res. for sched_setaffinity */ - PTR sys_ni_syscall, 0 /* res. for sched_getaffinity */ + PTR sys_tkill + PTR sys_time + PTR sys_ni_syscall /* res. for futex */ + PTR sys_ni_syscall /* 5195 rs. sched_setaffinity */ + PTR sys_ni_syscall /* res. f. sched_getaffinity */ + PTR sys_cacheflush + PTR sys_cachectl + PTR sys_sysmips + PTR sys_ni_syscall /* 5200 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 5205 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 5210 */ + PTR sys_rt_sigreturn diff -urN linux-2.4.21/arch/mips64/kernel/scall_n32.S linux-2.4.22/arch/mips64/kernel/scall_n32.S --- linux-2.4.21/arch/mips64/kernel/scall_n32.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/scall_n32.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,355 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2001 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* This duplicates the definition from */ +#define PT_TRACESYS 0x00000002 /* tracing system calls */ + +/* This duplicates the definition from */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ + +#ifndef CONFIG_MIPS32_O32 +/* No O32, so define handle_sys here */ +#define handle_sysn32 handle_sys +#endif + + .align 5 +NESTED(handle_sysn32, PT_SIZE, sp) +#ifndef CONFIG_MIPS32_O32 + .set noat + SAVE_SOME + STI + .set at +#endif + ld t1, PT_EPC(sp) # skip syscall on return + + subu t0, v0, __NR_N32_Linux # check syscall number + sltiu t0, t0, __NR_N32_Linux_syscalls + 1 + daddiu t1, 4 # skip to next instruction + beqz t0, not_n32_scall + sd t1, PT_EPC(sp) + + dsll t0, v0, 3 # offset into table + ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0) + + sd a3, PT_R26(sp) # save a3 for syscall restarting + + ld t0, TASK_PTRACE($28) # syscall tracing enabled? + andi t0, PT_TRACESYS + bnez t0, trace_a_syscall + + jalr t2 # Do The Real Thing (TM) + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sd t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sd v0, PT_R0(sp) # set flag for syscall restarting +1: sd v0, PT_R2(sp) # result + +ret_from_sys_call: + mfc0 t0, CP0_STATUS + xori t0, t0, 1 + ori t0, t0, 1 + mtc0 t0, CP0_STATUS + + ld t2, TASK_NEED_RESCHED($28) + bnez t2, n32_reschedule + lw v0, TASK_SIGPENDING($28) + bnez v0, signal_return + +restore_all: + RESTORE_SOME + RESTORE_SP + eret + +/* Put this behind restore_all for the sake of the branch prediction. */ +signal_return: + .type signal_return, @function + + mfc0 t0, CP0_STATUS + ori t0, t0, 1 + mtc0 t0, CP0_STATUS + + SAVE_STATIC + move a0, zero + move a1, sp + jal do_signal + RESTORE_STATIC + b restore_all + +n32_reschedule: + SAVE_STATIC + jal schedule + b ret_from_sys_call + +/* ------------------------------------------------------------------------ */ + +trace_a_syscall: + SAVE_STATIC + sd t2,PT_R1(sp) + jal syscall_trace + ld t2,PT_R1(sp) + + ld a0, PT_R4(sp) # Restore argument registers + ld a1, PT_R5(sp) + ld a2, PT_R6(sp) + ld a3, PT_R7(sp) + jalr t2 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sd t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sd v0, PT_R0(sp) # set flag for syscall restarting +1: sd v0, PT_R2(sp) # result + + jal syscall_trace + j ret_from_sys_call + +not_n32_scall: + /* This is not an n32 compatibility syscall, pass it on to + the n64 syscall handlers. */ + j handle_sys64 + + END(handle_sysn32) + +EXPORT(sysn32_call_table) + PTR sys_read /* 6000 */ + PTR sys_write + PTR sys_open + PTR sys_close + PTR sys_newstat + PTR sys_newfstat /* 6005 */ + PTR sys_newlstat + PTR sys_poll + PTR sys_lseek + PTR sys_mmap + PTR sys_mprotect /* 6010 */ + PTR sys_munmap + PTR sys_brk + PTR sys32_rt_sigaction + PTR sys32_rt_sigprocmask + PTR sys32_ioctl /* 6015 */ + PTR sys_pread + PTR sys_pwrite + PTR sys32_readv + PTR sys32_writev + PTR sys_access /* 6020 */ + PTR sys_pipe + PTR sys32_select + PTR sys_sched_yield + PTR sys_mremap + PTR sys_msync /* 6025 */ + PTR sys_mincore + PTR sys_madvise + PTR sys_shmget + PTR sys_shmat + PTR sys_shmctl /* 6030 */ + PTR sys_dup + PTR sys_dup2 + PTR sys_pause + PTR sys32_nanosleep + PTR sys32_getitimer /* 6035 */ + PTR sys32_setitimer + PTR sys_alarm + PTR sys_getpid + PTR sys32_sendfile + PTR sys_socket /* 6040 */ + PTR sys_connect + PTR sys_accept + PTR sys_sendto + PTR sys_recvfrom + PTR sys32_sendmsg /* 6045 */ + PTR sys32_recvmsg + PTR sys_shutdown + PTR sys_bind + PTR sys_listen + PTR sys_getsockname /* 6050 */ + PTR sys_getpeername + PTR sys_socketpair + PTR sys32_setsockopt + PTR sys_getsockopt + PTR sys_clone /* 6055 */ + PTR sys_fork + PTR sys32_execve + PTR sys_exit + PTR sys32_wait4 + PTR sys_kill /* 6060 */ + PTR sys32_newuname + PTR sys_semget + PTR sys_semop + PTR sys_semctl + PTR sys_shmdt /* 6065 */ + PTR sys_msgget + PTR sys_msgsnd + PTR sys_msgrcv + PTR sys_msgctl + PTR sys32_fcntl /* 6070 */ + PTR sys_flock + PTR sys_fsync + PTR sys_fdatasync + PTR sys_truncate + PTR sys_ftruncate /* 6075 */ + PTR sys32_getdents + PTR sys_getcwd + PTR sys_chdir + PTR sys_fchdir + PTR sys_rename /* 6080 */ + PTR sys_mkdir + PTR sys_rmdir + PTR sys_creat + PTR sys_link + PTR sys_unlink /* 6085 */ + PTR sys_symlink + PTR sys_readlink + PTR sys_chmod + PTR sys_fchmod + PTR sys_chown /* 6090 */ + PTR sys_fchown + PTR sys_lchown + PTR sys_umask + PTR sys32_gettimeofday + PTR sys32_getrlimit /* 6095 */ + PTR sys32_getrusage + PTR sys32_sysinfo + PTR sys32_times + PTR sys_ptrace + PTR sys_getuid /* 6100 */ + PTR sys_syslog + PTR sys_getgid + PTR sys_setuid + PTR sys_setgid + PTR sys_geteuid /* 6105 */ + PTR sys_getegid + PTR sys_setpgid + PTR sys_getppid + PTR sys_getpgrp + PTR sys_setsid /* 6110 */ + PTR sys_setreuid + PTR sys_setregid + PTR sys_getgroups + PTR sys_setgroups + PTR sys_setresuid /* 6115 */ + PTR sys_getresuid + PTR sys_setresgid + PTR sys_getresgid + PTR sys_getpgid + PTR sys_setfsuid /* 6120 */ + PTR sys_setfsgid + PTR sys_getsid + PTR sys_capget + PTR sys_capset + PTR sys32_rt_sigpending /* 6125 */ + PTR sys32_rt_sigtimedwait + PTR sys32_rt_sigqueueinfo + PTR sys32_rt_sigsuspend + PTR sys32_sigaltstack + PTR sys32_utime /* 6130 */ + PTR sys_mknod + PTR sys32_personality + PTR sys_ustat + PTR sys32_statfs + PTR sys32_fstatfs /* 6135 */ + PTR sys_sysfs + PTR sys_getpriority + PTR sys_setpriority + PTR sys_sched_setparam + PTR sys_sched_getparam /* 6140 */ + PTR sys_sched_setscheduler + PTR sys_sched_getscheduler + PTR sys_sched_get_priority_max + PTR sys_sched_get_priority_min + PTR sys32_sched_rr_get_interval /* 6145 */ + PTR sys_mlock + PTR sys_munlock + PTR sys_mlockall + PTR sys_munlockall + PTR sys_vhangup /* 6150 */ + PTR sys_pivot_root + PTR sys32_sysctl + PTR sys_prctl + PTR sys32_adjtimex + PTR sys32_setrlimit /* 6155 */ + PTR sys_chroot + PTR sys_sync + PTR sys_acct + PTR sys32_settimeofday + PTR sys_mount /* 6160 */ + PTR sys_umount + PTR sys_swapon + PTR sys_swapoff + PTR sys_reboot + PTR sys_sethostname /* 6165 */ + PTR sys_setdomainname + PTR sys_create_module + PTR sys_init_module + PTR sys_delete_module + PTR sys_get_kernel_syms /* 6170 */ + PTR sys_query_module + PTR sys_quotactl + PTR sys_nfsservctl + PTR sys_ni_syscall /* res. for getpmsg */ + PTR sys_ni_syscall /* 6175 for putpmsg */ + PTR sys_ni_syscall /* res. for afs_syscall */ + PTR sys_ni_syscall /* res. for security */ + PTR sys_gettid + PTR sys32_readahead + PTR sys_setxattr /* 6180 */ + PTR sys_lsetxattr + PTR sys_fsetxattr + PTR sys_getxattr + PTR sys_lgetxattr + PTR sys_fgetxattr /* 6185 */ + PTR sys_listxattr + PTR sys_llistxattr + PTR sys_flistxattr + PTR sys_removexattr + PTR sys_lremovexattr /* 6190 */ + PTR sys_fremovexattr + PTR sys_tkill + PTR sys_time + PTR sys_ni_syscall /* res. for futex */ + PTR sys_ni_syscall /* 6195 rs. sched_setaffinity */ + PTR sys_ni_syscall /* res. f. sched_getaffinity */ + PTR sys_cacheflush + PTR sys_cachectl + PTR sys_sysmips + PTR sys_ni_syscall /* 6200 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 6205 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 6210 */ + PTR sysn32_rt_sigreturn + PTR sys_fcntl + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 6215 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_sendfile64 diff -urN linux-2.4.21/arch/mips64/kernel/scall_o32.S linux-2.4.22/arch/mips64/kernel/scall_o32.S --- linux-2.4.21/arch/mips64/kernel/scall_o32.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/scall_o32.S 2003-08-25 04:44:40.000000000 -0700 @@ -22,9 +22,6 @@ #include #include -/* Highest syscall used of any syscall flavour */ -#define MAX_SYSCALL_NO __NR_Linux32 + __NR_Linux32_syscalls - .align 5 NESTED(handle_sys, PT_SIZE, sp) .set noat @@ -33,8 +30,8 @@ .set at ld t1, PT_EPC(sp) # skip syscall on return - subu t0, v0, __NR_Linux32 # check syscall number - sltiu t0, t0, __NR_Linux32_syscalls + 1 + subu t0, v0, __NR_O32_Linux # check syscall number + sltiu t0, t0, __NR_O32_Linux_syscalls + 1 daddiu t1, 4 # skip to next instruction beqz t0, not_o32_scall sd t1, PT_EPC(sp) @@ -45,10 +42,15 @@ RESTORE_ALL #endif + sll a0, a0, 0 + sll a1, a1, 0 + sll a2, a2, 0 + sll a3, a3, 0 + /* XXX Put both in one cacheline, should save a bit. */ dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_Linux32 * 8))(t0) # syscall routine - lbu t3, (sys_narg_table - __NR_Linux32)(v0) # number of arguments + ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0) + lbu t3, (sys_narg_table - __NR_O32_Linux)(v0) subu t0, t3, 5 # 5 or more arguments? sd a3, PT_R26(sp) # save a3 for syscall restarting @@ -88,18 +90,24 @@ eret .set mips0 -signal_return: mfc0 t0, CP0_STATUS # need_resched and signals atomic test +signal_return: + .type signal_return, @function + + mfc0 t0, CP0_STATUS ori t0, t0, 1 mtc0 t0, CP0_STATUS + + SAVE_STATIC move a0, zero move a1, sp - SAVE_STATIC jal do_signal + RESTORE_STATIC + b restore_all o32_reschedule: SAVE_STATIC jal schedule - b o32_ret_from_sys_call + j ret_from_sys_call /* ------------------------------------------------------------------------ */ @@ -184,9 +192,13 @@ j ret_from_sys_call not_o32_scall: - /* This is not an 32-bit compatibility syscall, pass it on to + /* This is not an o32 compatibility syscall, pass it on to the 64-bit syscall handlers. */ +#ifdef CONFIG_MIPS32_N32 + j handle_sysn32 +#else j handle_sys64 +#endif illegal_syscall: /* This also isn't a 64-bit syscall, throw an error. */ @@ -197,7 +209,7 @@ j ret_from_sys_call END(handle_sys) - LEAF(mips_atomic_set) +LEAF(mips_atomic_set) andi v0, a1, 3 # must be word aligned bnez v0, bad_alignment @@ -205,7 +217,7 @@ daddiu a0, a1, 4 or a0, a0, a1 and a0, a0, v1 - bltz a0, bad_address + bnez a0, bad_address /* Ok, this is the ll/sc case. World is sane :-) */ 1: ll v0, (a1) @@ -240,21 +252,21 @@ jr ra END(mips_atomic_set) - LEAF(sys32_sysmips) +LEAF(sys32_sysmips) beq a0, MIPS_ATOMIC_SET, mips_atomic_set j sys_sysmips END(sys32_sysmips) - LEAF(sys32_syscall) +LEAF(sys32_syscall) ld t0, PT_R29(sp) # user sp - sltu v0, a0, __NR_Linux + __NR_Linux_syscalls + 1 + sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 beqz v0, enosys dsll v0, a0, 3 dla v1, sys32_syscall - ld t2, (sys_call_table - (__NR_Linux32 * 8))(v0) # function pointer - lbu t3, (sys_narg_table - __NR_Linux32)(a0) # number of arguments + ld t2, (sys_call_table - (__NR_O32_Linux * 8))(v0) + lbu t3, (sys_narg_table - __NR_O32_Linux)(a0) li v0, -EINVAL beq t2, v1, out # do not recurse @@ -269,7 +281,7 @@ ld v1, THREAD_CURDS($28) or v0, v0, t1 and v1, v1, v0 - bltz v1, efault + bnez v1, efault move a0, a1 # shift argument registers move a1, a2 @@ -330,7 +342,7 @@ sys sys_chmod 2 /* 4015 */ sys sys_lchown 3 sys sys_ni_syscall 0 - sys sys_stat 2 + sys sys_ni_syscall 0 /* was sys_stat */ sys sys_lseek 3 sys sys_getpid 0 /* 4020 */ sys sys_mount 5 @@ -339,8 +351,8 @@ sys sys_getuid 0 sys sys_stime 1 /* 4025 */ sys sys32_ptrace 4 - sys sys32_alarm 1 - sys sys_fstat 2 + sys sys_alarm 1 + sys sys_ni_syscall 0 /* was sys_fstat */ sys sys_pause 0 sys sys32_utime 2 /* 4030 */ sys sys_ni_syscall 0 @@ -394,9 +406,9 @@ sys sys32_settimeofday 2 sys sys_getgroups 2 /* 4080 */ sys sys_setgroups 2 - sys sys_ni_syscall 0 /* old_select */ + sys sys_ni_syscall 0 /* old_select */ sys sys_symlink 2 - sys sys_lstat 2 + sys sys_ni_syscall 0 /* was sys_lstat */ sys sys_readlink 3 /* 4085 */ sys sys_uselib 1 sys sys_swapon 2 @@ -428,7 +440,7 @@ sys sys_ni_syscall 0 /* sys_vm86 */ sys sys32_wait4 4 sys sys_swapoff 1 /* 4115 */ - sys sys_sysinfo 1 + sys sys32_sysinfo 1 sys sys32_ipc 6 sys sys_fsync 1 sys sys32_sigreturn 0 @@ -519,12 +531,12 @@ sys sys_capget 2 sys sys_capset 2 /* 4205 */ sys sys32_sigaltstack 0 - sys sys_sendfile 4 + sys sys32_sendfile 4 sys sys_ni_syscall 0 sys sys_ni_syscall 0 - sys sys_mmap2 6 /* 4210 */ - sys sys_truncate64 2 - sys sys_ftruncate64 2 + sys sys32_mmap2 6 /* 4210 */ + sys sys32_truncate64 4 + sys sys32_ftruncate64 4 sys sys_newstat 2 sys sys_newlstat 2 sys sys_newfstat 2 /* 4215 */ @@ -549,7 +561,7 @@ sys sys_lremovexattr 2 sys sys_fremovexattr 2 /* 4235 */ sys sys_tkill, 2 - sys sys_ni_syscall, 0 /* res. for sendfile64 */ + sys sys_sendfile64, 5 sys sys_ni_syscall, 0 /* res. for futex */ sys sys_ni_syscall, 0 /* res. for sched_setaffinity */ sys sys_ni_syscall, 0 /* 4240 res. for sched_getaffinity */ diff -urN linux-2.4.21/arch/mips64/kernel/setup.c linux-2.4.22/arch/mips64/kernel/setup.c --- linux-2.4.21/arch/mips64/kernel/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -39,42 +40,35 @@ #include #include -#ifndef CONFIG_SMP -struct cpuinfo_mips cpu_data[1]; -#endif +struct cpuinfo_mips cpu_data[NR_CPUS]; #ifdef CONFIG_VT struct screen_info screen_info; #endif /* - * Not all of the MIPS CPUs have the "wait" instruction available. This - * is set to true if it is available. The wait instruction stops the - * pipeline and reduces the power consumption of the CPU very much. - */ -char wait_available; - -/* * Set if box has EISA slots. */ #ifdef CONFIG_EISA int EISA_bus = 0; #endif -#ifdef CONFIG_BLK_DEV_FD +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) +#include extern struct fd_ops no_fd_ops; struct fd_ops *fd_ops; #endif -#ifdef CONFIG_BLK_DEV_IDE +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) extern struct ide_ops no_ide_ops; struct ide_ops *ide_ops; #endif +extern void * __rd_start, * __rd_end; + extern struct rtc_ops no_rtc_ops; struct rtc_ops *rtc_ops; -extern struct kbd_ops no_kbd_ops; struct kbd_ops *kbd_ops; /* @@ -89,7 +83,7 @@ unsigned char aux_device_present; -extern void load_mmu(void); +extern char _ftext, _etext, _fdata, _edata, _end; static char command_line[CL_SIZE] = { 0, }; char saved_command_line[CL_SIZE]; @@ -102,23 +96,21 @@ const unsigned long mips_io_port_base = -1; EXPORT_SYMBOL(mips_io_port_base); -extern void ip22_setup(void); -extern void ip27_setup(void); -extern void ip32_setup(void); - /* - * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped + * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. */ unsigned long isa_slot_offset; EXPORT_SYMBOL(isa_slot_offset); -extern void sgi_sysinit(void); extern void SetUpBootInfo(void); extern void load_mmu(void); extern ATTRIB_NORET asmlinkage void start_kernel(void); extern void prom_init(int, char **, char **, int *); +static struct resource code_resource = { "Kernel code" }; +static struct resource data_resource = { "Kernel data" }; + asmlinkage void __init init_arch(int argc, char **argv, char **envp, int *prom_vec) { @@ -127,10 +119,6 @@ prom_init(argc, argv, envp, prom_vec); -#ifdef CONFIG_SGI_IP22 - sgi_sysinit(); -#endif - cpu_report(); /* @@ -145,8 +133,8 @@ * Maybe because the kernel is in ckseg0 and not xkphys? Clear it * anyway ... */ - clear_cp0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); - set_cp0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); + set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); start_kernel(); } @@ -243,7 +231,12 @@ } } -void bootmem_init(void) + +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) + +static inline void bootmem_init(void) { #ifdef CONFIG_BLK_DEV_INITRD unsigned long tmp; @@ -252,19 +245,26 @@ unsigned long bootmap_size; unsigned long start_pfn, max_pfn; int i; - extern int _end; - -#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) +#ifdef CONFIG_BLK_DEV_INITRD + tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; + if (tmp < (unsigned long)&_end) + tmp += PAGE_SIZE; + initrd_header = (unsigned long *)tmp; + if (initrd_header[0] == 0x494E5244) { + initrd_start = (unsigned long)&initrd_header[2]; + initrd_end = initrd_start + initrd_header[1]; + } + start_pfn = PFN_UP(CPHYSADDR((&_end)+(initrd_end - initrd_start) + PAGE_SIZE)); +#else /* * Partially used pages are not usable - thus * we are rounding upwards. - * start_pfn = PFN_UP(__pa(&_end)); */ - start_pfn = PFN_UP((unsigned long)&_end - KSEG0); + start_pfn = PFN_UP(CPHYSADDR(&_end)); +#endif /* CONFIG_BLK_DEV_INITRD */ +#ifndef CONFIG_SGI_IP27 /* Find the highest page frame number we have available. */ max_pfn = 0; for (i = 0; i < boot_mem_map.nr_map; i++) { @@ -329,50 +329,128 @@ /* Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); +#endif #ifdef CONFIG_BLK_DEV_INITRD -#error "Initrd is broken, please fit it." - tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; - if (tmp < (unsigned long)&_end) - tmp += PAGE_SIZE; - initrd_header = (unsigned long *)tmp; - if (initrd_header[0] == 0x494E5244) { - initrd_start = (unsigned long)&initrd_header[2]; - initrd_end = initrd_start + initrd_header[1]; - initrd_below_start_ok = 1; - if (initrd_end > memory_end) { + /* Board specific code should have set up initrd_start and initrd_end */ + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + if (&__rd_start != &__rd_end) { + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; + } + initrd_below_start_ok = 1; + if (initrd_start) { + unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", + (void *)initrd_start, + initrd_size); +/* FIXME: is this right? */ +#ifndef CONFIG_SGI_IP27 + if (CPHYSADDR(initrd_end) > PFN_PHYS(max_pfn)) { printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end,memory_end); + "(0x%p > 0x%p)\ndisabling initrd\n", + (void *)CPHYSADDR(initrd_end), + (void *)PFN_PHYS(max_pfn)); initrd_start = 0; - } else - *memory_start_p = initrd_end; + } +#endif /* !CONFIG_SGI_IP27 */ } #endif +} + +static inline void resource_init(void) +{ + int i; + + code_resource.start = virt_to_bus(&_ftext); + code_resource.end = virt_to_bus(&_etext) - 1; + data_resource.start = virt_to_bus(&_fdata); + data_resource.end = virt_to_bus(&_edata) - 1; + + /* + * Request address space for all standard RAM. + */ + for (i = 0; i < boot_mem_map.nr_map; i++) { + struct resource *res; + + res = alloc_bootmem(sizeof(struct resource)); + switch (boot_mem_map.map[i].type) { + case BOOT_MEM_RAM: + case BOOT_MEM_ROM_DATA: + res->name = "System RAM"; + break; + case BOOT_MEM_RESERVED: + default: + res->name = "reserved"; + } + + res->start = boot_mem_map.map[i].addr; + res->end = boot_mem_map.map[i].addr + + boot_mem_map.map[i].size - 1; + + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + request_resource(&iomem_resource, res); + + /* + * We dont't know which RAM region contains kernel data, + * so we try it repeatedly and let the resource manager + * test it. + */ + request_resource(res, &code_resource); + request_resource(res, &data_resource); + } +} #undef PFN_UP #undef PFN_DOWN #undef PFN_PHYS -} void __init setup_arch(char **cmdline_p) { + extern void atlas_setup(void); + extern void decstation_setup(void); + extern void ip22_setup(void); + extern void ip27_setup(void); + extern void malta_setup(void); + extern void momenco_ocelot_setup(void); + extern void momenco_ocelot_g_setup(void); + extern void momenco_ocelot_c_setup(void); + extern void sead_setup(void); + extern void swarm_setup(void); + extern void frame_info_init(void); + + frame_info_init(); +#ifdef CONFIG_MIPS_ATLAS + atlas_setup(); +#endif +#ifdef CONFIG_DECSTATION + decstation_setup(); +#endif #ifdef CONFIG_SGI_IP22 ip22_setup(); #endif #ifdef CONFIG_SGI_IP27 ip27_setup(); #endif -#ifdef CONFIG_SGI_IP32 - ip32_setup(); -#endif -#ifdef CONFIG_SIBYTE_SWARM +#ifdef CONFIG_SIBYTE_BOARD swarm_setup(); #endif #ifdef CONFIG_MIPS_MALTA malta_setup(); #endif +#ifdef CONFIG_MIPS_SEAD + sead_setup(); +#endif +#ifdef CONFIG_MOMENCO_OCELOT + momenco_ocelot_setup(); +#endif +#ifdef CONFIG_MOMENCO_OCELOT_G + momenco_ocelot_g_setup(); +#endif +#ifdef CONFIG_MOMENCO_OCELOT_C + momenco_ocelot_c_setup(); +#endif strncpy(command_line, arcs_cmdline, CL_SIZE); memcpy(saved_command_line, command_line, CL_SIZE); @@ -385,11 +463,15 @@ bootmem_init(); paging_init(); + + resource_init(); } int __init fpu_disable(char *s) { - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; + return 1; } + __setup("nofpu", fpu_disable); diff -urN linux-2.4.21/arch/mips64/kernel/signal.c linux-2.4.22/arch/mips64/kernel/signal.c --- linux-2.4.21/arch/mips64/kernel/signal.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -26,14 +26,13 @@ #include #include #include +#include #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); extern asmlinkage void syscall_trace(void); @@ -75,35 +74,7 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage inline int -sys_sigsuspend(abi64_no_regargs, struct pt_regs regs) -{ - sigset_t *uset, saveset, newset; - - save_static(®s); - uset = (sigset_t *) regs.regs[4]; - if (copy_from_user(&newset, uset, sizeof(sigset_t))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - spin_lock_irq(¤t->sigmask_lock); - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - regs.regs[2] = EINTR; - regs.regs[7] = 1; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, ®s)) - return -EINTR; - } -} - -asmlinkage int -sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset_t *unewset, saveset, newset; size_t sigsetsize; @@ -136,47 +107,7 @@ } } -asmlinkage int -sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - int err = 0; - - if (act) { - old_sigset_t mask; - - if (!access_ok(VERIFY_READ, act, sizeof(*act))) - return -EFAULT; - err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); - err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); - err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); - if (err) - return -EFAULT; - - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) - return -EFAULT; - err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler); - err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig); - err |= __put_user(0, &oact->sa_mask.sig[1]); - err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); - if (err) - return -EFAULT; - } - - return ret; -} - -asmlinkage int -sys_sigaltstack(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys_sigaltstack(abi64_no_regargs, struct pt_regs regs) { const stack_t *uss = (const stack_t *) regs.regs[4]; stack_t *uoss = (stack_t *) regs.regs[5]; @@ -185,58 +116,8 @@ return do_sigaltstack(uss, uoss, usp); } -static inline int restore_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - - /* - * Copy all 32 64-bit values. - */ - -#define restore_fpr(i) \ - do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3); - restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7); - restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11); - restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15); - restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19); - restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23); - restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27); - restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31); - - err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static inline int save_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - -#define save_fpr(i) \ - do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3); - save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7); - save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11); - save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15); - save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19); - save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23); - save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27); - save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31); - - err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -asmlinkage int -restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; err |= __get_user(regs->cp0_epc, &sc->sc_pc); @@ -259,35 +140,20 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); err |= __get_user(current->used_math, &sc->sc_used_math); - if (owned_fp) { - err |= restore_fp_context(sc); - goto out; - } - - if (IS_FPU_OWNER()) { - /* Signal handler acquired FPU - give it back */ - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } if (current->used_math) { - /* Undo possible contamination of thread state */ - err |= restore_thread_fp_context(sc); + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + lose_fpu(); } -out: return err; } -struct sigframe { - u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_code[2]; /* signal trampoline */ - struct sigcontext sf_sc; - sigset_t sf_mask; -}; - struct rt_sigframe { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ @@ -295,42 +161,6 @@ struct ucontext rs_uc; }; -asmlinkage void sys_sigreturn(abi64_no_regargs, struct pt_regs regs) -{ - struct sigframe *frame; - sigset_t blocked; - - frame = (struct sigframe *) regs.regs[29]; - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) - goto badframe; - - sigdelsetmask(&blocked, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); - current->blocked = blocked; - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - if (restore_sigcontext(®s, &frame->sf_sc)) - goto badframe; - - /* - * Don't let your children do this ... - */ - if (current->ptrace & PT_TRACESYS) - syscall_trace(); - __asm__ __volatile__( - "move\t$29, %0\n\t" - "j\tret_from_sys_call" - :/* no outputs */ - :"r" (®s)); - /* Unreached */ - -badframe: - force_sig(SIGSEGV, current); -} - asmlinkage void sys_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) { struct rt_sigframe *frame; @@ -372,10 +202,8 @@ force_sig(SIGSEGV, current); } -static int inline setup_sigcontext(struct pt_regs *regs, - struct sigcontext *sc) +int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; err |= __put_user(regs->cp0_epc, &sc->sc_pc); @@ -400,25 +228,20 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - owned_fp = IS_FPU_OWNER(); - err |= __put_user(owned_fp, &sc->sc_ownedfp); err |= __put_user(current->used_math, &sc->sc_used_math); if (!current->used_math) goto out; - /* There exists FP thread state that may be trashed by signal */ - if (owned_fp) { - /* fp is active. Save context from FPU */ - err |= save_fp_context(sc); - goto out; - } - - /* - * Someone else has FPU. - * Copy Thread context into signal context + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. */ - err |= save_thread_fp_context(sc); + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + err |= save_fp_context(sc); out: return err; @@ -428,7 +251,7 @@ * Determine which stack to use.. */ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) + size_t frame_size) { unsigned long sp; @@ -449,97 +272,25 @@ return (void *)((sp - frame_size) & ALMASK); } -static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set) +static void inline setup_rt_frame(struct k_sigaction * ka, + struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) { - struct sigframe *frame; + struct rt_sigframe *frame; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } - - err |= setup_sigcontext(regs, &frame->sf_sc); - err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); - if (err) - goto give_sigsegv; - /* - * Arguments to signal handler: - * - * a0 = signal number - * a1 = 0 (should be cause) - * a2 = pointer to struct sigcontext + * Set up the return code ... * - * $25 and c0_epc point to the signal handler, $29 points to the - * struct sigframe. + * li v0, __NR_rt_sigreturn + * syscall */ - regs->regs[ 4] = signr; - regs->regs[ 5] = 0; - regs->regs[ 6] = (unsigned long) &frame->sf_sc; - regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->sf_code; - regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; - -#if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", - current->comm, current->pid, - frame, regs->cp0_epc, frame->sf_code); -#endif - return; - -give_sigsegv: - if (signr == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); -} - -static void inline setup_rt_frame(struct k_sigaction * ka, - struct pt_regs *regs, int signr, - sigset_t *set, siginfo_t *info) -{ - struct rt_sigframe *frame; - int err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) - goto give_sigsegv; - - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Create siginfo. */ err |= copy_siginfo_to_user(&frame->rs_info, info); @@ -579,7 +330,7 @@ #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", current->comm, current->pid, - frame, regs->cp0_epc, frame->rs_code); + frame, regs->cp0_epc, regs->regs[31]); #endif return; @@ -589,14 +340,18 @@ force_sig(SIGSEGV, current); } +extern void setup_rt_frame_n32(struct k_sigaction * ka, + struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); + static inline void handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs *regs) + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { - if (ka->sa.sa_flags & SA_SIGINFO) +#ifdef CONFIG_MIPS32_N32 + if ((current->thread.mflags & MF_ABI_MASK) == MF_N32) + setup_rt_frame_n32 (ka, regs, sig, oldset, info); + else +#endif setup_rt_frame(ka, regs, sig, oldset, info); - else - setup_frame(ka, regs, sig, oldset); if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; @@ -609,8 +364,7 @@ } } -static inline void syscall_restart(struct pt_regs *regs, - struct k_sigaction *ka) +static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) { switch(regs->regs[0]) { case ERESTARTNOHAND: @@ -639,7 +393,7 @@ siginfo_t info; #ifdef CONFIG_BINFMT_ELF32 - if (current->thread.mflags & MF_32BIT) { + if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) { return do_signal32(oldset, regs); } #endif diff -urN linux-2.4.21/arch/mips64/kernel/signal32.c linux-2.4.22/arch/mips64/kernel/signal32.c --- linux-2.4.21/arch/mips64/kernel/signal32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/signal32.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,14 +25,13 @@ #include #include #include +#include #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); extern asmlinkage void syscall_trace(void); @@ -52,8 +51,6 @@ unsigned int sa_flags; __sighandler32_t sa_handler; sigset32_t sa_mask; - unsigned int sa_restorer; - int sa_resv[1]; /* reserved */ }; /* IRIX compatible stack_t */ @@ -63,6 +60,14 @@ int ss_flags; } stack32_t; +struct ucontext32 { + u32 uc_flags; + s32 uc_link; + stack32_t uc_stack; + struct sigcontext32 uc_mcontext; + sigset_t32 uc_sigmask; /* mask last for extensibility */ +}; + extern void __put_sigset_unknown_nsig(void); extern void __get_sigset_unknown_nsig(void); @@ -190,8 +195,6 @@ &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user((u32)(u64)new_ka.sa.sa_restorer, - &act->sa_restorer); if (err) return -EFAULT; @@ -210,8 +213,6 @@ err |= __put_user(0, &oact->sa_mask.sig[1]); err |= __put_user(0, &oact->sa_mask.sig[2]); err |= __put_user(0, &oact->sa_mask.sig[3]); - err |= __put_user((u32)(u64)old_ka.sa.sa_restorer, - &oact->sa_restorer); if (err) return -EFAULT; } @@ -257,58 +258,9 @@ return ret; } -static inline int restore_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - - /* - * Copy all 32 64-bit values. - */ - -#define restore_fpr(i) \ - do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3); - restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7); - restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11); - restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15); - restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19); - restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23); - restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27); - restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31); - - err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static inline int save_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - -#define save_fpr(i) \ - do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3); - save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7); - save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11); - save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15); - save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19); - save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23); - save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27); - save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31); - - err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static asmlinkage int restore_sigcontext(struct pt_regs *regs, - struct sigcontext *sc) +static asmlinkage int restore_sigcontext32(struct pt_regs *regs, + struct sigcontext32 *sc) { - int owned_fp; int err = 0; err |= __get_user(regs->cp0_epc, &sc->sc_pc); @@ -331,32 +283,24 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); err |= __get_user(current->used_math, &sc->sc_used_math); - if (owned_fp) { - err |= restore_fp_context(sc); - goto out; - } - - if (IS_FPU_OWNER()) { - /* Signal handler acquired FPU - give it back */ - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } if (current->used_math) { - /* Undo possible contamination of thread state */ - err |= restore_thread_fp_context(sc); + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context32(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + lose_fpu(); } -out: return err; } struct sigframe { u32 sf_ass[4]; /* argument save space for o32 */ u32 sf_code[2]; /* signal trampoline */ - struct sigcontext sf_sc; + struct sigcontext32 sf_sc; sigset_t sf_mask; }; @@ -364,7 +308,7 @@ u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ struct siginfo32 rs_info; - struct ucontext rs_uc; + struct ucontext32 rs_uc; }; static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from) @@ -426,7 +370,7 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if (restore_sigcontext(®s, &frame->sf_sc)) + if (restore_sigcontext32(®s, &frame->sf_sc)) goto badframe; /* @@ -450,6 +394,7 @@ struct rt_sigframe32 *frame; sigset_t set; stack_t st; + s32 sp; frame = (struct rt_sigframe32 *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -463,11 +408,18 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) + if (restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext)) goto badframe; - if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) + /* The ucontext contains a stack32_t, so we must convert! */ + if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) + goto badframe; + st.ss_size = (long) sp; + if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) goto badframe; + if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) + goto badframe; + /* It is more difficult to avoid calling this function than to call it and ignore errors. */ do_sigaltstack(&st, NULL, regs.regs[29]); @@ -486,10 +438,9 @@ force_sig(SIGSEGV, current); } -static int inline setup_sigcontext(struct pt_regs *regs, - struct sigcontext *sc) +static int inline setup_sigcontext32(struct pt_regs *regs, + struct sigcontext32 *sc) { - int owned_fp; int err = 0; err |= __put_user(regs->cp0_epc, &sc->sc_pc); @@ -514,25 +465,20 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - owned_fp = IS_FPU_OWNER(); - err |= __put_user(owned_fp, &sc->sc_ownedfp); err |= __put_user(current->used_math, &sc->sc_used_math); if (!current->used_math) goto out; - /* There exists FP thread state that may be trashed by signal */ - if (owned_fp) { - /* fp is active. Save context from FPU */ - err |= save_fp_context(sc); - goto out; - } - - /* - * Someone else has FPU. - * Copy Thread context into signal context + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. */ - err |= save_thread_fp_context(sc); + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + err |= save_fp_context32(sc); out: return err; @@ -573,25 +519,17 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_Linux32_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_Linux32_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_O32_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0); + err |= __put_user(0x0000000c , frame->sf_code + 1); + flush_cache_sigtramp((unsigned long) frame->sf_code); - err |= setup_sigcontext(regs, &frame->sf_sc); + err |= setup_sigcontext32(regs, &frame->sf_sc); err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); if (err) goto give_sigsegv; @@ -632,6 +570,7 @@ { struct rt_sigframe32 *frame; int err = 0; + s32 sp; frame = get_sigframe(ka, regs, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) @@ -639,21 +578,15 @@ /* Set up to return from userspace. If provided, use a stub already in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_Linux32_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_Linux32_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_O32_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Convert (siginfo_t -> siginfo_t32) and copy to user. */ err |= copy_siginfo_to_user32(&frame->rs_info, info); @@ -661,13 +594,14 @@ /* Create the ucontext. */ err |= __put_user(0, &frame->rs_uc.uc_flags); err |= __put_user(0, &frame->rs_uc.uc_link); - err |= __put_user((void *)current->sas_ss_sp, + sp = (int) (long) current->sas_ss_sp; + err |= __put_user(sp, &frame->rs_uc.uc_stack.ss_sp); err |= __put_user(sas_ss_flags(regs->regs[29]), &frame->rs_uc.uc_stack.ss_flags); err |= __put_user(current->sas_ss_size, &frame->rs_uc.uc_stack.ss_size); - err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); + err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext); err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); if (err) @@ -876,11 +810,14 @@ if (set && get_user (s, set)) return -EFAULT; + set_fs (KERNEL_DS); ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); set_fs (old_fs); + if (!ret && oset && put_user (s, oset)) return -EFAULT; + return ret; } @@ -921,8 +858,6 @@ err |= __get_user((u32)(u64)new_sa.sa.sa_handler, &act->sa_handler); err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags); - err |= __get_user((u32)(u64)new_sa.sa.sa_restorer, - &act->sa_restorer); err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask); if (err) return -EFAULT; @@ -939,8 +874,6 @@ err |= __put_user((u32)(u64)old_sa.sa.sa_handler, &oact->sa_handler); err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags); - err |= __put_user((u32)(u64)old_sa.sa.sa_restorer, - &oact->sa_restorer); err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask); if (err) return -EFAULT; @@ -991,12 +924,114 @@ return ret; } -asmlinkage void sys32_rt_sigtimedwait(void) +struct timespec32 { + int tv_sec; + int tv_nsec; +}; + +asmlinkage int sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo, + struct timespec32 *uts, __kernel_size_t32 sigsetsize) { - panic("%s called.", __FUNCTION__); + int ret, sig; + sigset_t these; + sigset_t32 these32; + struct timespec ts; + siginfo_t info; + long timeout = 0; + + /* + * As the result of a brainfarting competition a few years ago the + * size of sigset_t for the 32-bit kernel was choosen to be 128 bits + * but nothing so far is actually using that many, 64 are enough. So + * for now we just drop the high bits. + */ + if (copy_from_user (&these32, uthese, sizeof(old_sigset_t32))) + return -EFAULT; + + switch (_NSIG_WORDS) { +#ifdef __MIPSEB__ + case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32); + case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32); + case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32); + case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32); +#endif +#ifdef __MIPSEL__ + case 4: these.sig[3] = these32.sig[7] | (((long)these32.sig[6]) << 32); + case 3: these.sig[2] = these32.sig[5] | (((long)these32.sig[4]) << 32); + case 2: these.sig[1] = these32.sig[3] | (((long)these32.sig[2]) << 32); + case 1: these.sig[0] = these32.sig[1] | (((long)these32.sig[0]) << 32); +#endif + } + + /* + * Invert the set of allowed signals to get those we + * want to block. + */ + sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP)); + signotset(&these); + + if (uts) { + if (get_user (ts.tv_sec, &uts->tv_sec) || + get_user (ts.tv_nsec, &uts->tv_nsec)) + return -EINVAL; + if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0 + || ts.tv_sec < 0) + return -EINVAL; + } + + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&these, &info); + if (!sig) { + /* None ready -- temporarily unblock those we're interested + in so that we'll be awakened when they arrive. */ + sigset_t oldblocked = current->blocked; + sigandsets(¤t->blocked, ¤t->blocked, &these); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + timeout = MAX_SCHEDULE_TIMEOUT; + if (uts) + timeout = (timespec_to_jiffies(&ts) + + (ts.tv_sec || ts.tv_nsec)); + + current->state = TASK_INTERRUPTIBLE; + timeout = schedule_timeout(timeout); + + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&these, &info); + current->blocked = oldblocked; + recalc_sigpending(current); + } + spin_unlock_irq(¤t->sigmask_lock); + + if (sig) { + ret = sig; + if (uinfo) { + if (copy_siginfo_to_user32(uinfo, &info)) + ret = -EFAULT; + } + } else { + ret = -EAGAIN; + if (timeout) + ret = -EINTR; + } + + return ret; } -asmlinkage void sys32_rt_sigqueueinfo(void) +extern asmlinkage int sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo); + +asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo) { - panic("%s called.", __FUNCTION__); + siginfo_t info; + int ret; + mm_segment_t old_fs = get_fs(); + + if (copy_from_user (&info, uinfo, 3*sizeof(int)) || + copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE)) + return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_rt_sigqueueinfo(pid, sig, &info); + set_fs (old_fs); + return ret; } diff -urN linux-2.4.21/arch/mips64/kernel/signal_n32.c linux-2.4.22/arch/mips64/kernel/signal_n32.c --- linux-2.4.21/arch/mips64/kernel/signal_n32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/signal_n32.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +/* IRIX compatible stack_t */ +typedef struct sigaltstack32 { + s32 ss_sp; + __kernel_size_t32 ss_size; + int ss_flags; +} stack32_t; + +struct ucontextn32 { + u32 uc_flags; + s32 uc_link; + stack32_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +struct rt_sigframe_n32 { + u32 rs_ass[4]; /* argument save space for o32 */ + u32 rs_code[2]; /* signal trampoline */ + struct siginfo rs_info; + struct ucontextn32 rs_uc; +}; + +extern asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc); +extern int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc); + +asmlinkage void sysn32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) +{ + struct rt_sigframe_n32 *frame; + sigset_t set; + stack_t st; + s32 sp; + + frame = (struct rt_sigframe_n32 *) regs.regs[29]; + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) + goto badframe; + + /* The ucontext contains a stack32_t, so we must convert! */ + if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) + goto badframe; + st.ss_size = (long) sp; + if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) + goto badframe; + if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) + goto badframe; + + /* It is more difficult to avoid calling this function than to + call it and ignore errors. */ + do_sigaltstack(&st, NULL, regs.regs[29]); + + /* + * Don't let your children do this ... + */ + __asm__ __volatile__( + "move\t$29, %0\n\t" + "j\tret_from_sys_call" + :/* no outputs */ + :"r" (®s)); + /* Unreached */ + +badframe: + force_sig(SIGSEGV, current); +} + +/* + * Determine which stack to use.. + */ +static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, + size_t frame_size) +{ + unsigned long sp; + + /* Default to using normal stack */ + sp = regs->regs[29]; + + /* + * FPU emulator may have it's own trampoline active just + * above the user stack, 16-bytes before the next lowest + * 16 byte boundary. Try to avoid trashing it. + */ + sp -= 32; + + /* This is the X/Open sanctioned signal stack switching. */ + if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + + return (void *)((sp - frame_size) & ALMASK); +} + +void setup_rt_frame_n32(struct k_sigaction * ka, + struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) +{ + struct rt_sigframe_n32 *frame; + int err = 0; + s32 sp; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) + goto give_sigsegv; + + /* + * Set up the return code ... + * + * li v0, __NR_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); + + /* Create siginfo. */ + err |= copy_siginfo_to_user(&frame->rs_info, info); + + /* Create the ucontext. */ + err |= __put_user(0, &frame->rs_uc.uc_flags); + err |= __put_user(0, &frame->rs_uc.uc_link); + sp = (int) (long) current->sas_ss_sp; + err |= __put_user(sp, + &frame->rs_uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(regs->regs[29]), + &frame->rs_uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, + &frame->rs_uc.uc_stack.ss_size); + err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); + err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); + + if (err) + goto give_sigsegv; + + /* + * Arguments to signal handler: + * + * a0 = signal number + * a1 = 0 (should be cause) + * a2 = pointer to ucontext + * + * $25 and c0_epc point to the signal handler, $29 points to + * the struct rt_sigframe. + */ + regs->regs[ 4] = signr; + regs->regs[ 5] = (unsigned long) &frame->rs_info; + regs->regs[ 6] = (unsigned long) &frame->rs_uc; + regs->regs[29] = (unsigned long) frame; + regs->regs[31] = (unsigned long) frame->rs_code; + regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; + +#if DEBUG_SIG + printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", + current->comm, current->pid, + frame, regs->cp0_epc, regs->regs[31]); +#endif + return; + +give_sigsegv: + if (signr == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} diff -urN linux-2.4.21/arch/mips64/kernel/smp.c linux-2.4.22/arch/mips64/kernel/smp.c --- linux-2.4.21/arch/mips64/kernel/smp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -43,9 +43,7 @@ spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; int smp_threads_ready; /* Not used */ atomic_t smp_commenced = ATOMIC_INIT(0); -struct cpuinfo_mips cpu_data[NR_CPUS]; -// static atomic_t cpus_booted = ATOMIC_INIT(0); atomic_t cpus_booted = ATOMIC_INIT(0); int smp_num_cpus = 1; /* Number that came online. */ @@ -104,6 +102,7 @@ { unsigned int cpu = smp_processor_id(); + cpu_probe(); prom_init_secondary(); per_cpu_trap_init(); @@ -138,7 +137,7 @@ core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF); } -static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; +spinlock_t smp_call_lock = SPIN_LOCK_UNLOCKED; struct call_data_struct *call_data; @@ -170,7 +169,7 @@ if (wait) atomic_set(&data.finished, 0); - spin_lock(&call_lock); + spin_lock(&smp_call_lock); call_data = &data; /* Send a message to all other CPUs and wait for them to respond */ @@ -186,7 +185,7 @@ if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock(&call_lock); + spin_unlock(&smp_call_lock); return 0; } @@ -224,7 +223,7 @@ */ clear_bit(smp_processor_id(), &cpu_online_map); /* May need to service _machine_restart IPI */ - __sti(); + local_irq_enable(); /* XXXKW wait if available? */ for (;;); } @@ -282,7 +281,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_mm(mm); } @@ -314,7 +313,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_range(mm, start, end); } @@ -338,7 +337,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, vma->vm_mm) = 0; + cpu_context(i, vma->vm_mm) = 0; } local_flush_tlb_page(vma, page); } diff -urN linux-2.4.21/arch/mips64/kernel/syscall.c linux-2.4.22/arch/mips64/kernel/syscall.c --- linux-2.4.21/arch/mips64/kernel/syscall.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/syscall.c 2003-08-25 04:44:40.000000000 -0700 @@ -50,9 +50,11 @@ return res; } -#define COLOUR_ALIGN(addr,pgoff) \ - ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ - (((pgoff)< #include #include +#include #include #include #include #include +#include #include #include @@ -28,9 +31,14 @@ #include #include -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) +/* + * The integer part of the number of usecs per jiffy is taken from tick, + * but the fractional part is not recorded, so we calculate it using the + * initial value of HZ. This aids systems where tick isn't really an + * integer (e.g. for HZ = 128). + */ +#define USECS_PER_JIFFY tick +#define USECS_PER_JIFFY_FRAC ((unsigned long)(u32)((1000000ULL << 32) / HZ)) /* * forward reference @@ -38,11 +46,14 @@ extern rwlock_t xtime_lock; extern volatile unsigned long wall_jiffies; +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + /* * whether we emulate local_timer_interrupts for SMP machines. */ int emulate_local_timer_interrupt; + /* * By default we provide the null RTC ops */ @@ -58,6 +69,85 @@ unsigned long (*rtc_get_time)(void) = null_rtc_get_time; int (*rtc_set_time)(unsigned long) = null_rtc_set_time; +int (*rtc_set_mmss)(unsigned long); + + +/* usecs per counter cycle, shifted to left by 32 bits */ +static unsigned int sll32_usecs_per_cycle; + +/* how many counter cycles in a jiffy */ +static unsigned long cycles_per_jiffy; + +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi, timerlo; + +/* expirelo is the count value for next CPU timer interrupt */ +static unsigned int expirelo; + + +/* + * Null timer ack for systems not needing one (e.g. i8254). + */ +static void null_timer_ack(void) { /* nothing */ } + +/* + * Null high precision timer functions for systems lacking one. + */ +static unsigned int null_hpt_read(void) +{ + return 0; +} + +static void null_hpt_init(unsigned int count) { /* nothing */ } + + +/* + * Timer ack for a R4k-compatible timer of a known frequency. + */ +static void c0_fixed_timer_ack(void) +{ + unsigned int count; + + /* Ack this timer interrupt and set the next one. */ + expirelo += cycles_per_jiffy; + write_c0_compare(expirelo); + + /* Check to see if we have missed any timer interrupts. */ + count = read_c0_count(); + if ((count - expirelo) < 0x7fffffff) { + /* missed_timer_count++; */ + expirelo = count + cycles_per_jiffy; + write_c0_compare(expirelo); + } +} + +/* + * High precision timer functions for a R4k-compatible timer. + */ +static unsigned int c0_hpt_read(void) +{ + return read_c0_count(); +} + +/* For unknown frequency. */ +static void c0_hpt_init(unsigned int count) +{ + write_c0_count(read_c0_count() - count); +} + +/* For a known frequency. Used as an interrupt source. */ +static void c0_fixed_hpt_init(unsigned int count) +{ + expirelo = cycles_per_jiffy; + count = read_c0_count() - count; + write_c0_count(0); + write_c0_compare(cycles_per_jiffy); + write_c0_count(count); +} + +void (*mips_timer_ack)(void); +unsigned int (*mips_hpt_read)(void); +void (*mips_hpt_init)(unsigned int); /* @@ -65,22 +155,23 @@ */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long flags, lost; + + read_lock_irqsave(&xtime_lock, flags); - read_lock_irqsave (&xtime_lock, flags); *tv = xtime; tv->tv_usec += do_gettimeoffset(); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasn't executed yet. */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + lost = jiffies - wall_jiffies; + if (lost) + tv->tv_usec += lost * USECS_PER_JIFFY; - read_unlock_irqrestore (&xtime_lock, flags); + read_unlock_irqrestore(&xtime_lock, flags); - if (tv->tv_usec >= 1000000) { + while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } @@ -88,27 +179,29 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_lock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + /* + * This is revolting. We need to set "xtime" correctly. However, + * the value in this location is the value at the most recent update + * of wall time. Discover what correction gettimeofday() would have + * done, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); + tv->tv_usec -= (jiffies - wall_jiffies) * USECS_PER_JIFFY; - if (tv->tv_usec < 0) { + while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } + xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_unlock_irq(&xtime_lock); } @@ -119,76 +212,61 @@ * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. * Otherwise use calibrate_gettimeoffset() * - * If the CPU does not have counter register all, you can either supply - * your own gettimeoffset() routine, or use null_gettimeoffset() routines, - * which gives the same resolution as HZ. + * If the CPU does not have the counter register, you can either supply + * your own gettimeoffset() routine, or use null_gettimeoffset(), which + * gives the same resolution as HZ. */ +static unsigned long null_gettimeoffset(void) +{ + return 0; +} -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) - -/* usecs per counter cycle, shifted to left by 32 bits */ -static unsigned int sll32_usecs_per_cycle=0; - -/* how many counter cycles in a jiffy */ -static unsigned long cycles_per_jiffy=0; - -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - -/* last time when xtime and rtc are sync'ed up */ -static long last_rtc_update; -/* the function pointer to one of the gettimeoffset funcs*/ +/* The function pointer to one of the gettimeoffset funcs. */ unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; -unsigned long null_gettimeoffset(void) -{ - return 0; -} -unsigned long fixed_rate_gettimeoffset(void) +static unsigned long fixed_rate_gettimeoffset(void) { u32 count; unsigned long res; /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (sll32_usecs_per_cycle)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (sll32_usecs_per_cycle) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } + /* - * Cached "1/(clocks per usec)*2^32" value. + * Cached "1/(clocks per usec) * 2^32" value. * It has to be recalculated once each jiffy. */ static unsigned long cached_quotient; /* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ -static unsigned long last_jiffies = 0; - +static unsigned long last_jiffies; /* - * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij. + * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. */ -unsigned long calibrate_div32_gettimeoffset(void) +static unsigned long calibrate_div32_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -204,20 +282,21 @@ unsigned long r0; do_div64_32(r0, timerhi, timerlo, tmp); do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); + USECS_PER_JIFFY_FRAC, r0); cached_quotient = quotient; } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu %2,%3" - : "=l" (tmp), "=h" (res) - : "r" (count), "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check @@ -229,7 +308,7 @@ return res; } -unsigned long calibrate_div64_gettimeoffset(void) +static unsigned long calibrate_div64_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -239,54 +318,56 @@ quotient = cached_quotient; - if (tmp && last_jiffies != tmp) { + if (last_jiffies != tmp) { last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY)); - cached_quotient = quotient; + if (last_jiffies) { + unsigned long r0; + __asm__(".set push\n\t" + ".set mips3\n\t" + "lwu %0,%3\n\t" + "dsll32 %1,%2,0\n\t" + "or %1,%1,%0\n\t" + "ddivu $0,%1,%4\n\t" + "dsll32 %0,%5,0\n\t" + "or %0,%0,%6\n\t" + "mflo %1\n\t" + "ddivu $0,%0,%1\n\t" + "mflo %0\n\t" + ".set pop" + : "=&r" (quotient), "=&r" (r0) + : "r" (timerhi), "m" (timerlo), + "r" (tmp), "r" (USECS_PER_JIFFY), + "r" (USECS_PER_JIFFY_FRAC) + : "hi", "lo", "accum"); + cached_quotient = quotient; + } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } +/* last time when xtime and rtc are sync'ed up */ +static long last_rtc_update; + /* * local_timer_interrupt() does profiling and process accounting * on a per-CPU basis. @@ -299,7 +380,7 @@ */ void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if(!user_mode(regs)) { + if (!user_mode(regs)) { if (prof_buffer && current->pid) { extern int _stext; unsigned long pc = regs->cp0_epc; @@ -311,44 +392,32 @@ * put them into the last histogram slot, so if * present, they will show up as a sharp peak. */ - if (pc > prof_len-1) - pc = prof_len-1; + if (pc > prof_len - 1) + pc = prof_len - 1; atomic_inc((atomic_t *)&prof_buffer[pc]); } } -#if defined(CONFIG_SMP) +#ifdef CONFIG_SMP /* in UP mode, update_process_times() is invoked by do_timer() */ update_process_times(user_mode(regs)); #endif } /* - * high-level timer interrupt service routines. This function + * High-level timer interrupt service routines. This function * is set as irqaction->handler and is invoked through do_IRQ. */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if (mips_cpu.options & MIPS_CPU_COUNTER) { - unsigned int count; + unsigned int count; - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; + count = mips_hpt_read(); + mips_timer_ack(); - /* - * set up for next timer interrupt - no harm if the machine - * is using another timer interrupt source. - * Note that writing to COMPARE register clears the interrupt - */ - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); - - } + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; /* * call the generic timer interrupt handling @@ -360,27 +429,28 @@ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be * called as close as possible to 500 ms before the new second starts. */ - read_lock (&xtime_lock); + read_lock(&xtime_lock); if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (rtc_set_time(xtime.tv_sec) == 0) { + if (rtc_set_mmss(xtime.tv_sec) == 0) { last_rtc_update = xtime.tv_sec; } else { - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; } } - read_unlock (&xtime_lock); + read_unlock(&xtime_lock); /* - * If jiffies has overflowed in this timer_interrupt we must + * If jiffies has overflown in this timer_interrupt, we must * update the timer[hi]/[lo] to make fast gettimeoffset funcs * quotient calc still valid. -arca */ if (!jiffies) { timerhi = timerlo = 0; + mips_hpt_init(count); } #if !defined(CONFIG_SMP) @@ -391,7 +461,7 @@ * In SMP mode, local_timer_interrupt() is invoked by appropriate * low-level local timer interrupt handler. */ - local_timer_interrupt(0, NULL, regs); + local_timer_interrupt(irq, dev_id, regs); #else /* CONFIG_SMP */ @@ -458,73 +528,92 @@ * c) enable the timer interrupt */ -void (*board_time_init)(void) = NULL; -void (*board_timer_setup)(struct irqaction *irq) = NULL; +void (*board_time_init)(void); +void (*board_timer_setup)(struct irqaction *irq); -unsigned int mips_counter_frequency = 0; +unsigned int mips_counter_frequency; static struct irqaction timer_irqaction = { - timer_interrupt, - SA_INTERRUPT, - 0, - "timer", - NULL, - NULL}; + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer", +}; void __init time_init(void) { if (board_time_init) board_time_init(); + if (!rtc_set_mmss) + rtc_set_mmss = rtc_set_time; + xtime.tv_sec = rtc_get_time(); xtime.tv_usec = 0; - /* choose appropriate gettimeoffset routine */ - if (!(mips_cpu.options & MIPS_CPU_COUNTER)) { - /* no cpu counter - sorry */ - do_gettimeoffset = null_gettimeoffset; - } else if (mips_counter_frequency != 0) { - /* we have cpu counter and know counter frequency! */ - do_gettimeoffset = fixed_rate_gettimeoffset; - } else if ((mips_cpu.isa_level == MIPS_CPU_ISA_M32) || - (mips_cpu.isa_level == MIPS_CPU_ISA_I) || - (mips_cpu.isa_level == MIPS_CPU_ISA_II) ) { - /* we need to calibrate the counter but we don't have - * 64-bit division. */ - do_gettimeoffset = calibrate_div32_gettimeoffset; + /* Choose appropriate high precision timer routines. */ + if (!cpu_has_counter && !mips_hpt_read) { + /* No high precision timer -- sorry. */ + mips_hpt_read = null_hpt_read; + mips_hpt_init = null_hpt_init; + } else if (!mips_counter_frequency) { + /* A high precision timer of unknown frequency. */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_hpt_init; + } + + if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) + /* + * We need to calibrate the counter but we don't have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div32_gettimeoffset; + else + /* + * We need to calibrate the counter but we *do* have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div64_gettimeoffset; } else { - /* we need to calibrate the counter but we *do* have - * 64-bit division. */ - do_gettimeoffset = calibrate_div64_gettimeoffset; - } + /* We know counter frequency! */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_fixed_hpt_init; + + if (!mips_timer_ack) + /* R4k timer interrupt ack. */ + mips_timer_ack = c0_fixed_timer_ack; + } - /* caclulate cache parameters */ - if (mips_counter_frequency) { - u32 count; + do_gettimeoffset = fixed_rate_gettimeoffset; + /* Calculate cache parameters. */ cycles_per_jiffy = mips_counter_frequency / HZ; - /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - /* any better way to do this? */ + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + /* Any better way to do this? */ sll32_usecs_per_cycle = mips_counter_frequency / 100000; sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; sll32_usecs_per_cycle *= 10; - - /* - * For those using cpu counter as timer, this sets up the - * first interrupt - */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); } + if (!mips_timer_ack) + /* No timer interrupt ack (e.g. i8254). */ + mips_timer_ack = null_timer_ack; + + /* This sets up the high precision timer for the first interrupt. */ + mips_hpt_init(mips_hpt_read()); + /* * Call board specific timer interrupt setup. * * this pointer must be setup in machine setup routine. * - * Even if the machine choose to use low-level timer interrupt, + * Even if a machine chooses to use a low-level timer interrupt, * it still needs to setup the timer_irqaction. * In that case, it might be better to set timer_irqaction.handler * to be NULL function so that we are sure the high-level code @@ -537,15 +626,15 @@ #define STARTOFTIME 1970 #define SECDAY 86400L #define SECYR (SECDAY * 365) -#define leapyear(year) ((year) % 4 == 0) -#define days_in_year(a) (leapyear(a) ? 366 : 365) -#define days_in_month(a) (month_days[(a) - 1]) +#define leapyear(y) ((!((y) % 4) && ((y) % 100)) || !((y) % 400)) +#define days_in_year(y) (leapyear(y) ? 366 : 365) +#define days_in_month(m) (month_days[(m) - 1]) static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -void to_tm(unsigned long tim, struct rtc_time * tm) +void to_tm(unsigned long tim, struct rtc_time *tm) { long hms, day, gday; int i; @@ -560,16 +649,16 @@ /* Number of years in days */ for (i = STARTOFTIME; day >= days_in_year(i); i++) - day -= days_in_year(i); + day -= days_in_year(i); tm->tm_year = i; /* Number of months in days left */ if (leapyear(tm->tm_year)) - days_in_month(FEBRUARY) = 29; + days_in_month(FEBRUARY) = 29; for (i = 1; day >= days_in_month(i); i++) - day -= days_in_month(i); + day -= days_in_month(i); days_in_month(FEBRUARY) = 28; - tm->tm_mon = i-1; /* tm_mon starts from 0 to 11 */ + tm->tm_mon = i - 1; /* tm_mon starts from 0 to 11 */ /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; @@ -577,5 +666,10 @@ /* * Determine the day of week */ - tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ + tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ } + +EXPORT_SYMBOL(rtc_lock); +EXPORT_SYMBOL(to_tm); +EXPORT_SYMBOL(rtc_set_time); +EXPORT_SYMBOL(rtc_get_time); diff -urN linux-2.4.21/arch/mips64/kernel/traps.c linux-2.4.22/arch/mips64/kernel/traps.c --- linux-2.4.21/arch/mips64/kernel/traps.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,11 +3,13 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 - 1999 by Ralf Baechle + * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle * Copyright (C) 1995, 1996 Paul M. Antoine * Copyright (C) 1998 Ulf Carlsson * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2002 Maciej W. Rozycki + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000, 01 MIPS Technologies, Inc. + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include #include @@ -21,12 +23,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -47,6 +51,7 @@ extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_mdmx(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); @@ -54,12 +59,8 @@ extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx); -void fpu_emulator_init_fpu(void); - -char watch_available = 0; -char dedicated_iv_available = 0; - -int (*be_board_handler)(struct pt_regs *regs, int is_fixup); +void (*board_be_init)(void); +int (*board_be_handler)(struct pt_regs *regs, int is_fixup); int kstack_depth_to_print = 24; @@ -69,8 +70,6 @@ */ #define MODULE_RANGE (8*1024*1024) -#define OPCODE 0xfc000000 - /* * If the address is either in the .text section of the * kernel, or in the vmalloc'ed module regions, it *may* @@ -190,7 +189,6 @@ show_trace((long *)tsk->thread.reg29); } - void show_code(unsigned int *pc) { long i; @@ -214,15 +212,15 @@ printk("$0 : %016lx %016lx %016lx %016lx\n", 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); printk("$4 : %016lx %016lx %016lx %016lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); + regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); printk("$8 : %016lx %016lx %016lx %016lx\n", regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); printk("$12 : %016lx %016lx %016lx %016lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); + regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); printk("$16 : %016lx %016lx %016lx %016lx\n", regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); printk("$20 : %016lx %016lx %016lx %016lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); + regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); printk("$24 : %016lx %016lx\n", regs->regs[24], regs->regs[25]); printk("$28 : %016lx %016lx %016lx %016lx\n", @@ -336,7 +334,7 @@ spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp != NULL; mp = mp->next) { if (!mod_member_present(mp, archdata_end) || - !mod_archdata_member_present(mp, struct archdata, + !mod_archdata_member_present(mp, struct archdata, dbe_table_end)) continue; ap = (struct archdata *)(mp->archdata_start); @@ -367,8 +365,8 @@ if (fixup) action = MIPS_BE_FIXUP; - if (be_board_handler) - action = be_board_handler(regs, fixup != 0); + if (board_be_handler) + action = board_be_handler(regs, fixup != 0); switch (action) { case MIPS_BE_DISCARD: @@ -395,12 +393,151 @@ force_sig(SIGBUS, current); } -asmlinkage void do_ov(struct pt_regs *regs) +static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) { - siginfo_t info; + unsigned int *epc; + + epc = (unsigned int *) regs->cp0_epc + + ((regs->cp0_cause & CAUSEF_BD) != 0); + if (!get_user(*opcode, epc)) + return 0; + + force_sig(SIGSEGV, current); + return 1; +} + +/* + * ll/sc emulation + */ + +#define OPCODE 0xfc000000 +#define BASE 0x03e00000 +#define RT 0x001f0000 +#define OFFSET 0x0000ffff +#define LL 0xc0000000 +#define SC 0xe0000000 + +/* + * The ll_bit is cleared by r*_switch.S + */ + +unsigned long ll_bit; + +static struct task_struct *ll_task = NULL; + +static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long value, *vaddr; + long offset; + int signal = 0; + + /* + * analyse the ll instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (get_user(value, vaddr)) { + signal = SIGSEGV; + goto sig; + } + + if (ll_task == NULL || ll_task == current) { + ll_bit = 1; + } else { + ll_bit = 0; + } + ll_task = current; - if (compute_return_epc(regs)) + regs->regs[(opcode & RT) >> 16] = value; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long *vaddr, reg; + long offset; + int signal = 0; + + /* + * analyse the sc instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + reg = (opcode & RT) >> 16; + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (ll_bit == 0 || ll_task != current) { + regs->regs[reg] = 0; + compute_return_epc(regs); return; + } + + if (put_user(regs->regs[reg], vaddr)) { + signal = SIGSEGV; + goto sig; + } + + regs->regs[reg] = 1; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +/* + * ll uses the opcode of lwc0 and sc uses the opcode of swc0. That is both + * opcodes are supposed to result in coprocessor unusable exceptions if + * executed on ll/sc-less processors. That's the theory. In practice a + * few processors such as NEC's VR4100 throw reserved instruction exceptions + * instead, so we're doing the emulation thing in both exception handlers. + */ +static inline int simulate_llsc(struct pt_regs *regs) +{ + unsigned int opcode; + + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; + + if ((opcode & OPCODE) == LL) { + simulate_ll(regs, opcode); + return 0; + } + if ((opcode & OPCODE) == SC) { + simulate_sc(regs, opcode); + return 0; + } +} + +asmlinkage void do_ov(struct pt_regs *regs) +{ + siginfo_t info; info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; @@ -444,36 +581,14 @@ /* If something went wrong, signal */ if (sig) - { - /* - * Return EPC is not calculated in the FPU emulator, - * if a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); force_sig(sig, current); - } return; } - if (compute_return_epc(regs)) - return; force_sig(SIGFPE, current); } -static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) -{ - unsigned long *epc; - - epc = (unsigned long *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (!get_user(opcode, epc)) - return 0; - - force_sig(SIGSEGV, current); - return 1; -} - asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; @@ -520,7 +635,7 @@ if (get_insn_opcode(regs, &opcode)) return; - /* Immediate versions don't provide a code. */ + /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) tcode = ((opcode >> 6) & ((1 << 20) - 1)); @@ -551,8 +666,9 @@ { die_if_kernel("Reserved instruction in kernel code", regs); - if (compute_return_epc(regs)) - return; + if (!cpu_has_llsc) + if (!simulate_llsc(regs)) + return; force_sig(SIGILL, current); } @@ -560,69 +676,53 @@ asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; - void fpu_emulator_init_fpu(void); - int sig; + + die_if_kernel("do_cpu invoked from kernel context!", regs); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (cpid != 1) - goto bad_cid; - if (!(mips_cpu.options & MIPS_CPU_FPU)) - goto fp_emul; + switch (cpid) { + case 0: + if (cpu_has_llsc) + break; - regs->cp0_status |= ST0_CU1; + if (!simulate_llsc(regs)) + return; + break; + + case 1: + own_fpu(); + if (current->used_math) { /* Using the FPU again. */ + restore_fp(current); + } else { /* First time FPU user. */ + init_fpu(); + current->used_math = 1; + } + + if (!cpu_has_fpu) { + int sig = fpu_emulator_cop1Handler(0, regs, + ¤t->thread.fpu.soft); + if (sig) + force_sig(sig, current); + } -#ifdef CONFIG_SMP - if (current->used_math) { - lazy_fpu_switch(0, current); - } else { - init_fpu(); - current->used_math = 1; - } - current->flags |= PF_USEDFPU; -#else - if (last_task_used_math == current) return; - if (current->used_math) { /* Using the FPU again. */ - lazy_fpu_switch(last_task_used_math, current); - } else { /* First time FPU user. */ - lazy_fpu_switch(last_task_used_math, 0); - init_fpu(); - current->used_math = 1; + case 2: + case 3: + break; } - last_task_used_math = current; -#endif - return; -fp_emul: - if (last_task_used_math != current) { - if (!current->used_math) { - fpu_emulator_init_fpu(); - current->used_math = 1; - } - } - sig = fpu_emulator_cop1Handler(0, regs, ¤t->thread.fpu.soft); - last_task_used_math = current; - if (sig) { - /* - * Return EPC is not calculated in the FPU emulator, if - * a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); - force_sig(sig, current); - } - return; + force_sig(SIGILL, current); +} -bad_cid: - compute_return_epc(regs); +asmlinkage void do_mdmx(struct pt_regs *regs) +{ force_sig(SIGILL, current); } asmlinkage void do_watch(struct pt_regs *regs) { - extern void dump_tlb_all(void); - /* * We use the watch exception where available to detect stack * overflows. @@ -652,26 +752,9 @@ * caused by a new unknown cpu type or after another deadly * hard/software error. */ + show_regs(regs); panic("Caught reserved exception %ld - should not happen.", - (regs->cp0_cause & 0x1f) >> 2); -} - -static inline void watch_init(unsigned long cputype) -{ - switch(cputype) { - case CPU_R10000: - case CPU_R4000MC: - case CPU_R4400MC: - case CPU_R4000SC: - case CPU_R4400SC: - case CPU_R4000PC: - case CPU_R4400PC: - case CPU_R4200: - case CPU_R4300: - set_except_vector(23, handle_watch); - watch_available = 1; - break; - } + (regs->cp0_cause & 0x7f) >> 2); } unsigned long exception_handlers[32]; @@ -687,7 +770,7 @@ unsigned long old_handler = exception_handlers[n]; exception_handlers[n] = handler; - if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) { + if (n == 0 && cpu_has_divec) { *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | (0x03ffffff & (handler >> 2)); flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); @@ -697,164 +780,149 @@ asmlinkage int (*save_fp_context)(struct sigcontext *sc); asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + +asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc); +asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc); + extern asmlinkage int _save_fp_context(struct sigcontext *sc); extern asmlinkage int _restore_fp_context(struct sigcontext *sc); +extern asmlinkage int _save_fp_context32(struct sigcontext32 *sc); +extern asmlinkage int _restore_fp_context32(struct sigcontext32 *sc); + extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); +extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 *sc); +extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 *sc); + void __init per_cpu_trap_init(void) { unsigned int cpu = smp_processor_id(); /* Some firmware leaves the BEV flag set, clear it. */ - clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); - set_cp0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX); + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); + set_c0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX); + + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + set_c0_status(ST0_XX); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - if (mips_cpu.options & MIPS_CPU_DIVEC) - set_cp0_cause(CAUSEF_IV); + if (cpu_has_divec) + set_c0_cause(CAUSEF_IV); cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; - set_context(((long)(&pgd_current[cpu])) << 23); - set_wired(0); + write_c0_context(((long)(&pgd_current[cpu])) << 23); + write_c0_wired(0); + + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + if (current->mm) + BUG(); + enter_lazy_tlb(&init_mm, current, cpu); } void __init trap_init(void) { - extern char except_vec0; - extern char except_vec1_r4k; - extern char except_vec1_r10k; - extern char except_vec2_generic; + extern char except_vec0_generic; extern char except_vec3_generic, except_vec3_r4000; extern char except_vec4; unsigned long i; - int dummy; per_cpu_trap_init(); /* Copy the generic exception handlers to their final destination. */ - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *) KSEG0 , &except_vec0_generic, 0x80); memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); /* * Setup default vectors */ - for(i = 0; i <= 31; i++) + for (i = 0; i <= 31; i++) set_except_vector(i, handle_reserved); /* * Only some CPUs have the watch exceptions or a dedicated * interrupt vector. */ - watch_init(mips_cpu.cputype); + if (cpu_has_watch) + set_except_vector(23, handle_watch); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8); - - if (mips_cpu.options & MIPS_CPU_MCHECK) - set_except_vector(24, handle_mcheck); + if (cpu_has_divec) + memcpy((void *)(KSEG0 + 0x200), &except_vec4, 0x8); /* * The Data Bus Errors / Instruction Bus Errors are signaled * by external hardware. Therefore these two exceptions * may have board specific handlers. */ - bus_error_init(); + if (board_be_init) + board_be_init(); - /* - * Handling the following exceptions depends mostly of the cpu type - */ - switch(mips_cpu.cputype) { - case CPU_SB1: -#ifdef CONFIG_SB1_CACHE_ERROR - { - /* Special cache error handler for SB1 */ - extern char except_vec2_sb1; - memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); - memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); - } -#endif - /* Enable timer interrupt and scd mapped interrupt */ - clear_cp0_status(0xf000); - set_cp0_status(0xc00); - - /* Fall through. */ - case CPU_R10000: - case CPU_R4000MC: - case CPU_R4400MC: - case CPU_R4000SC: - case CPU_R4400SC: - case CPU_R4000PC: - case CPU_R4400PC: - case CPU_R4200: - case CPU_R4300: - case CPU_R4600: - case CPU_R5000: - case CPU_NEVADA: - case CPU_5KC: - case CPU_20KC: - case CPU_RM7000: - /* Debug TLB refill handler. */ - memcpy((void *)KSEG0, &except_vec0, 0x80); - if ((mips_cpu.options & MIPS_CPU_4KEX) - && (mips_cpu.options & MIPS_CPU_4KTLB)) { - memcpy((void *)KSEG0 + 0x080, &except_vec1_r4k, 0x80); - } else { - memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80); - } - if (mips_cpu.options & MIPS_CPU_VCE) { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, - 0x80); - } else { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, - 0x80); - } + set_except_vector(1, __xtlb_mod); + set_except_vector(2, __xtlb_tlbl); + set_except_vector(3, __xtlb_tlbs); + set_except_vector(4, handle_adel); + set_except_vector(5, handle_ades); + + set_except_vector(6, handle_ibe); + set_except_vector(7, handle_dbe); + + set_except_vector(8, handle_sys); + set_except_vector(9, handle_bp); + set_except_vector(10, handle_ri); + set_except_vector(11, handle_cpu); + set_except_vector(12, handle_ov); + set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); - set_except_vector(1, __xtlb_mod); - set_except_vector(2, __xtlb_tlbl); - set_except_vector(3, __xtlb_tlbs); - set_except_vector(4, handle_adel); - set_except_vector(5, handle_ades); - - set_except_vector(6, handle_ibe); - set_except_vector(7, handle_dbe); - - set_except_vector(8, handle_sys); - set_except_vector(9, handle_bp); - set_except_vector(10, handle_ri); - set_except_vector(11, handle_cpu); - set_except_vector(12, handle_ov); - set_except_vector(13, handle_tr); + if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); - break; - case CPU_R8000: - panic("R8000 is unsupported"); - break; + if (cpu_has_mcheck) + set_except_vector(24, handle_mcheck); - case CPU_UNKNOWN: - default: - panic("Unknown CPU type"); + if (cpu_has_vce) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x100); + else if (cpu_has_4kex) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); + else + memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80); + + if (current_cpu_data.cputype == CPU_R6000 || + current_cpu_data.cputype == CPU_R6000A) { + /* + * The R6000 is the only R-series CPU that features a machine + * check exception (similar to the R4000 cache error) and + * unaligned ldc1/sdc1 exception. The handlers have not been + * written yet. Well, anyway there is no R6000 machine on the + * current list of targets for Linux/MIPS. + * (Duh, crap, there is someone with a tripple R6k machine) + */ + //set_except_vector(14, handle_mc); + //set_except_vector(15, handle_ndc); } - flush_icache_range(KSEG0, KSEG0 + 0x200); - if (mips_cpu.options & MIPS_CPU_FPU) { - save_fp_context = _save_fp_context; + if (cpu_has_fpu) { + save_fp_context = _save_fp_context; restore_fp_context = _restore_fp_context; + save_fp_context32 = _save_fp_context32; + restore_fp_context32 = _restore_fp_context32; } else { save_fp_context = fpu_emulator_save_context; restore_fp_context = fpu_emulator_restore_context; + save_fp_context32 = fpu_emulator_save_context32; + restore_fp_context32 = fpu_emulator_restore_context32; } - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); + flush_icache_range(KSEG0, KSEG0 + 0x400); atomic_inc(&init_mm.mm_count); /* XXX UP? */ current->active_mm = &init_mm; diff -urN linux-2.4.21/arch/mips64/kernel/unaligned.c linux-2.4.22/arch/mips64/kernel/unaligned.c --- linux-2.4.21/arch/mips64/kernel/unaligned.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/kernel/unaligned.c 2003-08-25 04:44:40.000000000 -0700 @@ -88,21 +88,21 @@ #define STR(x) __STR(x) #define __STR(x) #x -/* - * User code may only access USEG; kernel code may access the - * entire address space. - */ -#define check_axs(pc,a,s) \ - if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \ - goto sigbus; +#ifdef CONFIG_PROC_FS +unsigned long unaligned_instructions; +#endif static inline int emulate_load_store_insn(struct pt_regs *regs, - unsigned long addr, unsigned long pc) + void *addr, unsigned long pc, + unsigned long **regptr, unsigned long *newvalue) { union mips_instruction insn; unsigned long value, fixup; + unsigned int res; regs->regs[0] = 0; + *regptr=NULL; + /* * This load never faults. */ @@ -142,183 +142,295 @@ * The remaining opcodes are the ones that are really of interest. */ case lh_op: - check_axs(pc, addr, 2); - __asm__( - ".set\tnoat\n" + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ (".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlb\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlb\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlb\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlb\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lw_op: - check_axs(pc, addr, 4); - __asm__( + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lhu_op: - check_axs(pc, addr, 2); - __asm__( + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ ( ".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlbu\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlbu\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlbu\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlbu\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lwu_op: - check_axs(pc, addr, 4); - __asm__( +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "dsll\t%0, %0, 32\n\t" + "dsrl\t%0, %0, 32\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - value &= 0xffffffff; - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case ld_op: - check_axs(pc, addr, 8); - __asm__( - ".set\tmips3\n" +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 8)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tldl\t%0,(%1)\n" - "2:\tldr\t%0,7(%1)\n\t" + "1:\tldl\t%0, (%2)\n" + "2:\tldr\t%0, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tldl\t%0,7(%1)\n" - "2:\tldr\t%0,(%1)\n\t" + "1:\tldl\t%0, 7(%2)\n" + "2:\tldr\t%0, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case sh_op: - check_axs(pc, addr, 2); + if (verify_area(VERIFY_WRITE, addr, 2)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,1(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,0(%1)\n\t" + "1:\tsb\t%1, 1(%2)\n\t" + "srl\t$1, %1, 0x8\n" + "2:\tsb\t$1, 0(%2)\n\t" ".set\tat\n\t" #endif #ifdef __LITTLE_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,0(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,1(%1)\n\t" + "1:\tsb\t%1, 0(%2)\n\t" + "srl\t$1,%1, 0x8\n" + "2:\tsb\t$1, 1(%2)\n\t" ".set\tat\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return 0; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sw_op: - check_axs(pc, addr, 4); + if (verify_area(VERIFY_WRITE, addr, 4)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tswl\t%0,(%1)\n" - "2:\tswr\t%0,3(%1)\n\t" + "1:\tswl\t%1,(%2)\n" + "2:\tswr\t%1, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tswl\t%0,3(%1)\n" - "2:\tswr\t%0,(%1)\n\t" + "1:\tswl\t%1, 3(%2)\n" + "2:\tswr\t%1, (%2)\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return 0; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sd_op: - check_axs(pc, addr, 8); +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_WRITE, addr, 8)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( - ".set\tmips3\n" + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tsdl\t%0,(%1)\n" - "2:\tsdr\t%0,7(%1)\n\t" + "1:\tsdl\t%1,(%2)\n" + "2:\tsdr\t%1, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tsdl\t%0,7(%1)\n" - "2:\tsdr\t%0,(%1)\n\t" + "1:\tsdl\t%1, 7(%2)\n" + "2:\tsdr\t%1, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return 0; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case lwc1_op: case ldc1_op: @@ -347,6 +459,11 @@ */ goto sigill; } + +#ifdef CONFIG_PROC_FS + unaligned_instructions++; +#endif + return 0; fault: @@ -363,52 +480,48 @@ die_if_kernel ("Unhandled kernel unaligned access", regs); send_sig(SIGSEGV, current, 1); + return 0; + sigbus: - die_if_kernel ("Unhandled kernel unaligned access", regs); + die_if_kernel("Unhandled kernel unaligned access", regs); send_sig(SIGBUS, current, 1); + return 0; + sigill: - die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs); + die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs); send_sig(SIGILL, current, 1); + return 0; } -#ifdef CONFIG_PROC_FS -unsigned long unaligned_instructions; -#endif - asmlinkage void do_ade(struct pt_regs *regs) { - unsigned long pc; + unsigned long *regptr, newval; extern int do_dsemulret(struct pt_regs *); - -#if 0 - printk("ade: Cpu%d[%s:%d:%0lx:%0lx]\n", smp_processor_id(), - current->comm, current->pid, regs->cp0_badvaddr, regs->cp0_epc); -#endif + mm_segment_t seg; + unsigned long pc; /* - * Address errors may be deliberately induced - * by the FPU emulator to take retake control - * of the CPU after executing the instruction - * in the delay slot of an emulated branch. + * Address errors may be deliberately induced by the FPU emulator to + * retake control of the CPU after executing the instruction in the + * delay slot of an emulated branch. */ /* Terminate if exception was recognized as a delay slot return */ if (do_dsemulret(regs)) return; - /* Otherwise handle as normal */ + /* Otherwise handle as normal */ /* * Did we catch a fault trying to load an instruction? - * This also catches attempts to activate MIPS16 code on - * CPUs which don't support it. + * Or are we running in MIPS16 mode? */ - if (regs->cp0_badvaddr == regs->cp0_epc) + if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1)) goto sigbus; - pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); + pc = exception_epc(regs); if ((current->thread.mflags & MF_FIXADE) == 0) goto sigbus; @@ -416,16 +529,28 @@ * Do branch emulation only if we didn't forward the exception. * This is all so but ugly ... */ - if (!emulate_load_store_insn(regs, regs->cp0_badvaddr, pc)) + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); + if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc, + ®ptr, &newval)) { compute_return_epc(regs); - -#ifdef CONFIG_PROC_FS - unaligned_instructions++; -#endif + /* + * Now that branch is evaluated, update the dest + * register if necessary + */ + if (regptr) + *regptr = newval; + } + set_fs(seg); return; sigbus: die_if_kernel("Kernel unaligned instruction access", regs); force_sig(SIGBUS, current); + + /* + * XXX On return from the signal handler we should advance the epc + */ } diff -urN linux-2.4.21/arch/mips64/ld.script.elf32.S linux-2.4.22/arch/mips64/ld.script.elf32.S --- linux-2.4.21/arch/mips64/ld.script.elf32.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/ld.script.elf32.S 2003-08-25 04:44:40.000000000 -0700 @@ -77,6 +77,14 @@ { _fdata = . ; *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } .data1 : { *(.data1) } diff -urN linux-2.4.21/arch/mips64/ld.script.elf64 linux-2.4.22/arch/mips64/ld.script.elf64 --- linux-2.4.21/arch/mips64/ld.script.elf64 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/ld.script.elf64 2003-08-25 04:44:40.000000000 -0700 @@ -86,6 +86,14 @@ { _fdata = . ; *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } .data1 : { *(.data1) } diff -urN linux-2.4.21/arch/mips64/lib/Makefile linux-2.4.22/arch/mips64/lib/Makefile --- linux-2.4.21/arch/mips64/lib/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips64/lib/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,12 +6,12 @@ L_TARGET = lib.a -obj-y += csum_partial.o csum_partial_copy.o dump_tlb.o rtc-std.o \ +obj-y += csum_partial.o csum_partial_copy.o dump_tlb.o promlib.o rtc-std.o \ rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \ strnlen_user.o watch.o obj-$(CONFIG_BLK_DEV_FD) += floppy-no.o floppy-std.o -obj-$(CONFIG_IDE) += ide-std.o ide-no.o -obj-$(CONFIG_PC_KEYB) += kbd-std.o kbd-no.o +obj-$(subst m,y,$(CONFIG_IDE)) += ide-std.o ide-no.o # needed for ide module +obj-$(CONFIG_PC_KEYB) += kbd-std.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/mips64/lib/dump_tlb.c linux-2.4.22/arch/mips64/lib/dump_tlb.c --- linux-2.4.21/arch/mips64/lib/dump_tlb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips64/lib/dump_tlb.c 2003-08-25 04:44:40.000000000 -0700 @@ -36,22 +36,22 @@ unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid; unsigned int s_index, pagemask, c0, c1, i; - s_entryhi = get_entryhi(); - s_index = get_index(); + s_entryhi = read_c0_entryhi(); + s_index = read_c0_index(); asid = s_entryhi & 0xff; for (i = first; i <= last; i++) { - write_32bit_cp0_register(CP0_INDEX, i); + write_c0_index(i); __asm__ __volatile__( ".set\tnoreorder\n\t" "nop;nop;nop;nop\n\t" "tlbr\n\t" "nop;nop;nop;nop\n\t" ".set\treorder"); - pagemask = read_32bit_cp0_register(CP0_PAGEMASK); - entryhi = get_entryhi(); - entrylo0 = get_entrylo0(); - entrylo1 = get_entrylo1(); + pagemask = read_c0_pagemask(); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); /* Unused entries have a virtual address of CKSEG0. */ if ((entryhi & ~0x1ffffUL) != CKSEG0 @@ -81,22 +81,22 @@ } printk("\n"); - set_entryhi(s_entryhi); - set_index(s_index); + write_c0_entryhi(s_entryhi); + write_c0_index(s_index); } void dump_tlb_all(void) { - dump_tlb(0, mips_cpu.tlbsize - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } void dump_tlb_wired(void) { int wired; - wired = read_32bit_cp0_register(CP0_WIRED); + wired = read_c0_wired(); printk("Wired: %d", wired); - dump_tlb(0, read_32bit_cp0_register(CP0_WIRED)); + dump_tlb(0, read_c0_wired()); } #define BARRIER \ @@ -107,19 +107,19 @@ void dump_tlb_addr(unsigned long addr) { - unsigned int flags, oldpid; + unsigned long flags, oldpid; int index; - __save_and_cli(flags); - oldpid = get_entryhi() & 0xff; + local_irq_save(flags); + oldpid = read_c0_entryhi() & 0xff; BARRIER; - set_entryhi((addr & PAGE_MASK) | oldpid); + write_c0_entryhi((addr & PAGE_MASK) | oldpid); BARRIER; tlb_probe(); BARRIER; - index = get_index(); - set_entryhi(oldpid); - __restore_flags(flags); + index = read_c0_index(); + write_c0_entryhi(oldpid); + local_irq_restore(flags); if (index < 0) { printk("No entry for address 0x%08lx in TLB\n", addr); @@ -132,7 +132,7 @@ void dump_tlb_nonwired(void) { - dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_cpu.tlbsize - 1); + dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); } void dump_list_process(struct task_struct *t, void *address) @@ -161,7 +161,7 @@ printk("pte == %08lx, ", (unsigned long) pte); page = *pte; - printk("page == %08lx\n", (unsigned long) pte_val(page)); + printk("page == %08lx\n", pte_val(page)); val = pte_val(page); if (val & _PAGE_PRESENT) printk("present "); diff -urN linux-2.4.21/arch/mips64/lib/ide-no.c linux-2.4.22/arch/mips64/lib/ide-no.c --- linux-2.4.21/arch/mips64/lib/ide-no.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/lib/ide-no.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,42 +29,8 @@ { } -static int no_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - panic("no_no_ide_request_irq called - shouldn't happen"); -} - -static void no_ide_free_irq(unsigned int irq, void *dev_id) -{ - panic("no_ide_free_irq called - shouldn't happen"); -} - -static int no_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_check_region called - shouldn't happen"); -} - -static void no_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - panic("no_ide_request_region called - shouldn't happen"); -} - -static void no_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_release_region called - shouldn't happen"); -} - struct ide_ops no_ide_ops = { &no_ide_default_irq, &no_ide_default_io_base, - &no_ide_init_hwif_ports, - &no_ide_request_irq, - &no_ide_free_irq, - &no_ide_check_region, - &no_ide_request_region, - &no_ide_release_region + &no_ide_init_hwif_ports }; diff -urN linux-2.4.21/arch/mips64/lib/ide-std.c linux-2.4.22/arch/mips64/lib/ide-std.c --- linux-2.4.21/arch/mips64/lib/ide-std.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/lib/ide-std.c 2003-08-25 04:44:40.000000000 -0700 @@ -62,42 +62,8 @@ hw->io_ports[IDE_IRQ_OFFSET] = 0; } -static int std_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - return request_irq(irq, handler, flags, device, dev_id); -} - -static void std_ide_free_irq(unsigned int irq, void *dev_id) -{ - free_irq(irq, dev_id); -} - -static int std_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return check_region(from, extent); -} - -static void std_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - request_region(from, extent, name); -} - -static void std_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - release_region(from, extent); -} - struct ide_ops std_ide_ops = { &std_ide_default_irq, &std_ide_default_io_base, - &std_ide_init_hwif_ports, - &std_ide_request_irq, - &std_ide_free_irq, - &std_ide_check_region, - &std_ide_request_region, - &std_ide_release_region + &std_ide_init_hwif_ports }; diff -urN linux-2.4.21/arch/mips64/lib/kbd-no.c linux-2.4.22/arch/mips64/lib/kbd-no.c --- linux-2.4.21/arch/mips64/lib/kbd-no.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.22/arch/mips64/lib/kbd-no.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,62 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Stub keyboard and psaux routines to keep Linux from crashing on machines - * without a keyboard. - * - * Copyright (C) 1998 by Ralf Baechle - */ -#include -#include - -static void no_kbd_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static void no_aux_free_irq(void) -{ -} - -static unsigned char no_kbd_read_input(void) -{ - return 0; -} - -static void no_kbd_write_output(unsigned char val) -{ -} - -static void no_kbd_write_command(unsigned char val) -{ -} - -static unsigned char no_kbd_read_status(void) -{ - return 0; -} - -struct kbd_ops no_kbd_ops = { - no_kbd_request_region, - no_kbd_request_irq, - - no_aux_request_irq, - no_aux_free_irq, - - no_kbd_read_input, - no_kbd_write_output, - no_kbd_write_command, - no_kbd_read_status -}; diff -urN linux-2.4.21/arch/mips64/lib/memcpy.S linux-2.4.22/arch/mips64/lib/memcpy.S --- linux-2.4.21/arch/mips64/lib/memcpy.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/lib/memcpy.S 2003-08-25 04:44:40.000000000 -0700 @@ -5,776 +5,500 @@ * * Unified implementation of memcpy, memmove and the __copy_user backend. * - * Copyright (C) 1998, 1999, 2000, 2001 Ralf Baechle - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. + * Copyright (C) 2002 Broadcom, Inc. + * memcpy/copy_user author: Mark Vandevoorde * - * For __rmemcpy and memmove an exception is always a kernel bug, therefore - * they're not protected. In order to keep the exception fixup routine - * simple all memory accesses in __copy_user to src rsp. dst are stricly - * incremental. The fixup routine depends on $at not being changed. + * Mnemonic names for arguments to memcpy/__copy_user */ +#include #include #include #include +#define dst a0 +#define src a1 +#define len a2 + /* - * The fixup routine for copy_to_user depends on copying strictly in - * increasing order. Gas expands the ulw/usw macros in the wrong order for - * little endian machines, so we cannot depend on them. + * Spec + * + * memcpy copies len bytes from src to dst and sets v0 to dst. + * It assumes that + * - src and dst don't overlap + * - src is readable + * - dst is writable + * memcpy uses the standard calling convention + * + * __copy_user copies up to len bytes from src to dst and sets a2 (len) to + * the number of uncopied bytes due to an exception caused by a read or write. + * __copy_user assumes that src and dst don't overlap, and that the call is + * implementing one of the following: + * copy_to_user + * - src is readable (no exceptions when reading src) + * copy_from_user + * - dst is writable (no exceptions when writing dst) + * __copy_user uses a non-standard calling convention; see + * include/asm-mips/uaccess.h + * + * When an exception happens on a load, the handler must + # ensure that all of the destination buffer is overwritten to prevent + * leaking information to user mode programs. */ -#ifdef __MIPSEB__ -#define uswL swl -#define uswU swr -#define ulwL lwl -#define ulwU lwr -#define usdL sdl -#define usdU sdr -#define uldL ldl -#define uldU ldr -#endif -#ifdef __MIPSEL__ -#define uswL swr -#define uswU swl -#define ulwL lwr -#define ulwU lwl -#define usdL sdr -#define usdU sdl -#define uldL ldr -#define uldU ldl -#endif -#define EX(insn,reg,addr,handler) \ -9: insn reg, addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - .previous +/* + * Implementation + */ -#define UEX(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 3 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ - .previous +/* + * The exception handler for loads requires that: + * 1- AT contain the address of the byte just past the end of the source + * of the copy, + * 2- src_entry <= src < AT, and + * 3- (dst - src) == (dst_entry - src_entry), + * The _entry suffix denotes values when __copy_user was called. + * + * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user + * (2) is met by incrementing src by the number of bytes copied + * (3) is met by not doing loads between a pair of increments of dst and src + * + * The exception handlers for stores adjust len (if necessary) and return. + * These handlers do not need to overwrite any data. + * + * For __rmemcpy and memmove an exception is always a kernel bug, therefore + * they're not protected. + */ -#define UEXD(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 7 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ +#define EXC(inst_reg,addr,handler) \ +9: inst_reg, addr; \ + .section __ex_table,"a"; \ + PTR 9b, handler; \ .previous -/* ascending order, destination aligned */ -#define MOVE_BIGGERCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(ld, t0, (offset + 0x00)(src), l_fixup); \ - EX(ld, t1, (offset + 0x08)(src), l_fixup); \ - EX(ld, t2, (offset + 0x10)(src), l_fixup); \ - EX(ld, t3, (offset + 0x18)(src), l_fixup); \ - EX(sd, t0, (offset + 0x00)(dst), s_fixup); \ - EX(sd, t1, (offset + 0x08)(dst), s_fixup); \ - EX(sd, t2, (offset + 0x10)(dst), s_fixup); \ - EX(sd, t3, (offset + 0x18)(dst), s_fixup); \ - EX(ld, t0, (offset + 0x20)(src), l_fixup); \ - EX(ld, t1, (offset + 0x28)(src), l_fixup); \ - EX(ld, t2, (offset + 0x30)(src), l_fixup); \ - EX(ld, t3, (offset + 0x38)(src), l_fixup); \ - EX(sd, t0, (offset + 0x20)(dst), s_fixup); \ - EX(sd, t1, (offset + 0x28)(dst), s_fixup); \ - EX(sd, t2, (offset + 0x30)(dst), s_fixup); \ - EX(sd, t3, (offset + 0x38)(dst), s_fixup) - -/* ascending order, destination aligned */ -#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x00)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x04)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x08)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x10)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x14)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x18)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x1c)(dst), s_fixup) - -/* ascending order, destination unaligned */ -#define UMOVE_BIGGERCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(ld, t0, (offset + 0x00)(src), l_fixup); \ - EX(ld, t1, (offset + 0x08)(src), l_fixup); \ - EX(ld, t2, (offset + 0x10)(src), l_fixup); \ - EX(ld, t3, (offset + 0x18)(src), l_fixup); \ - UEXD(usd, t0, (offset + 0x00)(dst), s_fixup); \ - UEXD(usd, t1, (offset + 0x08)(dst), s_fixup); \ - UEXD(usd, t2, (offset + 0x10)(dst), s_fixup); \ - UEXD(usd, t3, (offset + 0x18)(dst), s_fixup); \ - EX(ld, t0, (offset + 0x20)(src), l_fixup); \ - EX(ld, t1, (offset + 0x28)(src), l_fixup); \ - EX(ld, t2, (offset + 0x30)(src), l_fixup); \ - EX(ld, t3, (offset + 0x38)(src), l_fixup); \ - UEXD(usd, t0, (offset + 0x20)(dst), s_fixup); \ - UEXD(usd, t1, (offset + 0x28)(dst), s_fixup); \ - UEXD(usd, t2, (offset + 0x30)(dst), s_fixup); \ - UEXD(usd, t3, (offset + 0x38)(dst), s_fixup) - -/* ascending order, destination unaligned */ -#define UMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x00)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x04)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x08)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x10)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x14)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x18)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x1c)(dst), s_fixup) +/* + * Only on the 64-bit kernel we can made use of 64-bit registers. + */ +#ifdef CONFIG_MIPS64 +#define USE_DOUBLE +#endif + +#ifdef USE_DOUBLE + +#define LOAD ld +#define LOADL ldl +#define LOADR ldr +#define STOREL sdl +#define STORER sdr +#define STORE sd +#define ADD daddu +#define SUB dsubu +#define SRL dsrl +#define SRA dsra +#define SLL dsll +#define SLLV dsllv +#define SRLV dsrlv +#define NBYTES 8 +#define LOG_NBYTES 3 + +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 + +#else + +#define LOAD lw +#define LOADL lwl +#define LOADR lwr +#define STOREL swl +#define STORER swr +#define STORE sw +#define ADD addu +#define SUB subu +#define SRL srl +#define SLL sll +#define SRA sra +#define SLLV sllv +#define SRLV srlv +#define NBYTES 4 +#define LOG_NBYTES 2 + +#endif /* USE_DOUBLE */ + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define LDFIRST LOADR +#define LDREST LOADL +#define STFIRST STORER +#define STREST STOREL +#define SHIFT_DISCARD SLLV +#else +#define LDFIRST LOADL +#define LDREST LOADR +#define STFIRST STOREL +#define STREST STORER +#define SHIFT_DISCARD SRLV +#endif + +#define FIRST(unit) ((unit)*NBYTES) +#define REST(unit) (FIRST(unit)+NBYTES-1) +#define UNIT(unit) FIRST(unit) + +#define ADDRMASK (NBYTES-1) .text .set noreorder .set noat +/* + * A combined memcpy/__copy_user + * __copy_user sets len to 0 for success; else to an upper bound of + * the number of uncopied bytes. + * memcpy sets v0 to dst. + */ .align 5 LEAF(memcpy) /* a0=dst a1=src a2=len */ - move v0, a0 /* return value */ + move v0, dst /* return value */ __memcpy: FEXPORT(__copy_user) - xor ta0, a0, a1 - andi ta0, ta0, 0x7 - move t3, a0 - beqz ta0, can_align - sltiu t8, a2, 0x8 - - b memcpy_u_src # bad alignment - move ta2, a2 - -can_align: - bnez t8, small_memcpy # < 8 bytes to copy - move ta2, a2 - - beqz a2, out - andi t8, a1, 0x1 - -hword_align: - beqz t8, word_align - andi t8, a1, 0x2 - - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - daddu a0, a0, 0x1 - andi t8, a1, 0x2 - -word_align: - beqz t8, dword_align - sltiu t8, a2, 56 - - EX(lh, ta0, (a1), l_fixup) - dsubu a2, a2, 0x2 - EX(sh, ta0, (a0), s_fixup) - sltiu t8, a2, 56 - daddu a0, a0, 0x2 - daddu a1, a1, 0x2 - -dword_align: - bnez t8, do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, qword_align - andi t8, a1, 0x8 - - EX(lw, ta0, 0x00(a1), l_fixup) - dsubu a2, a2, 0x4 - EX(sw, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x4 - daddu a0, a0, 0x4 - andi t8, a1, 0x8 - -qword_align: - beqz t8, oword_align - andi t8, a1, 0x10 - - EX(lw, ta0, 0x00(a1), l_fixup) - EX(lw, ta1, 0x04(a1), l_fixup) - dsubu a2, a2, 0x8 - EX(sw, ta0, 0x00(a0), s_fixup) - EX(sw, ta1, 0x04(a0), s_fixup) - daddu a1, a1, 0x8 - andi t8, a1, 0x10 - daddu a0, a0, 0x8 - -oword_align: - beqz t8, begin_movement - srl t8, a2, 0x7 - - EX(lw, ta3, 0x00(a1), l_fixup) - EX(lw, t0, 0x04(a1), l_fixup) - EX(lw, ta0, 0x08(a1), l_fixup) - EX(lw, ta1, 0x0c(a1), l_fixup) - EX(sw, ta3, 0x00(a0), s_fixup) - EX(sw, t0, 0x04(a0), s_fixup) - EX(sw, ta0, 0x08(a0), s_fixup) - EX(sw, ta1, 0x0c(a0), s_fixup) - dsubu a2, a2, 0x10 - daddu a1, a1, 0x10 - srl t8, a2, 0x7 - daddu a0, a0, 0x10 - -begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -move_128bytes: - PREF (0, 2*128(a0)) - PREF (1, 2*128(a1)) - MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - MOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - daddu a1, a1, 0x80 - bnez t8, move_128bytes - daddu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -move_64bytes: - MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - daddu a1, a1, 0x40 - daddu a0, a0, 0x40 + /* + * Note: dst & src may be unaligned, len may be 0 + * Temps + */ +#define rem t8 + /* + * The "issue break"s below are very approximate. + * Issue delays for dcache fills will perturb the schedule, as will + * load queue full replay traps, etc. + * + * If len < NBYTES use byte operations. + */ + PREF( 0, 0(src) ) + PREF( 1, 0(dst) ) + sltu t2, len, NBYTES + and t1, dst, ADDRMASK + PREF( 0, 1*32(src) ) + PREF( 1, 1*32(dst) ) + bnez t2, copy_bytes_checklen + and t0, src, ADDRMASK + PREF( 0, 2*32(src) ) + PREF( 1, 2*32(dst) ) + bnez t1, dst_unaligned + nop + bnez t0, src_unaligned_dst_aligned + /* + * use delay slot for fall-through + * src and dst are aligned; need to compute rem + */ +both_aligned: + SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter + beqz t0, cleanup_both_aligned # len < 8*NBYTES + and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) + PREF( 0, 3*32(src) ) + PREF( 1, 3*32(dst) ) + .align 4 1: - beqz ta2, do_end_words - andi t8, a2, 0x1c - -move_32bytes: - MOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - daddu a1, a1, 0x20 - daddu a0, a0, 0x20 - -do_end_words: - beqz t8, maybe_end_cruft - srl t8, t8, 0x2 - -end_words: - EX(lw, ta0, (a1), l_fixup) - dsubu t8, t8, 0x1 - EX(sw, ta0, (a0), s_fixup) - daddu a1, a1, 0x4 - bnez t8, end_words - daddu a0, a0, 0x4 - -maybe_end_cruft: - andi ta2, a2, 0x3 - -small_memcpy: - beqz ta2, out - move a2, ta2 - -end_bytes: - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - bnez a2, end_bytes - daddu a0, a0, 0x1 - -out: jr ra - move a2, zero +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 8*NBYTES +EXC( LOAD t4, UNIT(4)(src), l_exc_copy) +EXC( LOAD t7, UNIT(5)(src), l_exc_copy) +EXC( STORE t0, UNIT(0)(dst), s_exc_p8u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p7u) +EXC( LOAD t0, UNIT(6)(src), l_exc_copy) +EXC( LOAD t1, UNIT(7)(src), l_exc_copy) + ADD src, src, 8*NBYTES + ADD dst, dst, 8*NBYTES +EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u) +EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u) +EXC( STORE t4, UNIT(-4)(dst), s_exc_p4u) +EXC( STORE t7, UNIT(-3)(dst), s_exc_p3u) +EXC( STORE t0, UNIT(-2)(dst), s_exc_p2u) +EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u) + PREF( 0, 8*32(src) ) + PREF( 1, 8*32(dst) ) + bne len, rem, 1b + nop -/* ------------------------------------------------------------------------- */ + /* + * len == rem == the number of bytes left to copy < 8*NBYTES + */ +cleanup_both_aligned: + beqz len, done + sltu t0, len, 4*NBYTES + bnez t0, less_than_4units + and rem, len, (NBYTES-1) # rem = len % NBYTES + /* + * len >= 4*NBYTES + */ +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 4*NBYTES + ADD src, src, 4*NBYTES +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + beqz len, done + ADD dst, dst, 4*NBYTES +less_than_4units: + /* + * rem = len % NBYTES + */ + beq rem, len, copy_bytes + nop +1: +EXC( LOAD t0, 0(src), l_exc) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne rem, len, 1b + ADD dst, dst, NBYTES -/* Bad, bad. At least try to align the source */ + /* + * src and dst are aligned, need to copy rem bytes (rem < NBYTES) + * A loop would do only a byte at a time with possible branch + * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE + * because can't assume read-access to dst. Instead, use + * STREST dst, which doesn't require read access to dst. + * + * This code should perform better than a simple loop on modern, + * wide-issue mips processors because the code has fewer branches and + * more instruction-level parallelism. + */ +#define bits t2 + beqz len, done + ADD t1, dst, len # t1 is just past last byte of dst + li bits, 8*NBYTES + SLL rem, len, 3 # rem = number of bits to keep +EXC( LOAD t0, 0(src), l_exc) + SUB bits, bits, rem # bits = number of bits to discard + SHIFT_DISCARD t0, t0, bits +EXC( STREST t0, -1(t1), s_exc) + jr ra + move len, zero +dst_unaligned: + /* + * dst is unaligned + * t0 = src & ADDRMASK + * t1 = dst & ADDRMASK; T1 > 0 + * len >= NBYTES + * + * Copy enough bytes to align dst + * Set match = (src and dst have same alignment) + */ +#define match rem +EXC( LDFIRST t3, FIRST(0)(src), l_exc) + ADD t2, zero, NBYTES +EXC( LDREST t3, REST(0)(src), l_exc_copy) + SUB t2, t2, t1 # t2 = number of bytes copied + xor match, t0, t1 +EXC( STFIRST t3, FIRST(0)(dst), s_exc) + beq len, t2, done + SUB len, len, t2 + ADD dst, dst, t2 + beqz match, both_aligned + ADD src, src, t2 + +src_unaligned_dst_aligned: + SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter + PREF( 0, 3*32(src) ) + beqz t0, cleanup_src_unaligned + and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES + PREF( 1, 3*32(dst) ) +1: +/* + * Avoid consecutive LD*'s to the same register since some mips + * implementations can't issue them in the same cycle. + * It's OK to load FIRST(N+1) before REST(N) because the two addresses + * are to the same unit (unless src is aligned, but it's not). + */ +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) + SUB len, len, 4*NBYTES +EXC( LDREST t0, REST(0)(src), l_exc_copy) +EXC( LDREST t1, REST(1)(src), l_exc_copy) +EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) +EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) +EXC( LDREST t2, REST(2)(src), l_exc_copy) +EXC( LDREST t3, REST(3)(src), l_exc_copy) + PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) + ADD src, src, 4*NBYTES +#ifdef CONFIG_CPU_SB1 + nop # improves slotting +#endif +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) + bne len, rem, 1b + ADD dst, dst, 4*NBYTES + +cleanup_src_unaligned: + beqz len, done + and rem, len, NBYTES-1 # rem = len % NBYTES + beq rem, len, copy_bytes + nop +1: +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDREST t0, REST(0)(src), l_exc_copy) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne len, rem, 1b + ADD dst, dst, NBYTES -memcpy_u_src: - bnez t8, small_memcpy # < 8 bytes? - move ta2, a2 - - daddiu ta0, a1, 7 # ta0: how much to align - ori ta0, 7 - xori ta0, 7 - dsubu ta0, a1 - - UEXD(uld, ta1, 0(a1), l_fixup) # dword alignment - UEXD(usd, ta1, 0(a0), s_fixup) - - daddu a1, ta0 # src - daddu a0, ta0 # dst - dsubu a2, ta0 # len - - sltiu t8, a2, 56 - bnez t8, u_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -u_qword_align: - beqz t8, u_oword_align - andi t8, a1, 0x10 - - EX(ld, ta0, 0x00(a1), l_fixup) - dsubu a2, a2, 0x8 - UEXD(usd, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x8 - andi t8, a1, 0x10 - daddu a0, a0, 0x8 - -u_oword_align: - beqz t8, u_begin_movement - srl t8, a2, 0x7 - - EX(lw, ta3, 0x08(a1), l_fixup) - EX(lw, t0, 0x0c(a1), l_fixup) - EX(lw, ta0, 0x00(a1), l_fixup) - EX(lw, ta1, 0x04(a1), l_fixup) - UEX(usw, ta3, 0x08(a0), s_fixup) - UEX(usw, t0, 0x0c(a0), s_fixup) - UEX(usw, ta0, 0x00(a0), s_fixup) - UEX(usw, ta1, 0x04(a0), s_fixup) - dsubu a2, a2, 0x10 - daddu a1, a1, 0x10 - srl t8, a2, 0x7 - daddu a0, a0, 0x10 - -u_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -u_move_128bytes: - UMOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - UMOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - daddu a1, a1, 0x80 - bnez t8, u_move_128bytes - daddu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -u_move_64bytes: - UMOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - daddu a1, a1, 0x40 - daddu a0, a0, 0x40 +copy_bytes_checklen: + beqz len, done + nop +copy_bytes: + /* 0 < len < NBYTES */ +#define COPY_BYTE(N) \ +EXC( lb t0, N(src), l_exc); \ + SUB len, len, 1; \ + beqz len, done; \ +EXC( sb t0, N(dst), s_exc_p1) + + COPY_BYTE(0) + COPY_BYTE(1) +#ifdef USE_DOUBLE + COPY_BYTE(2) + COPY_BYTE(3) + COPY_BYTE(4) + COPY_BYTE(5) +#endif +EXC( lb t0, NBYTES-2(src), l_exc) + SUB len, len, 1 + jr ra +EXC( sb t0, NBYTES-2(dst), s_exc_p1) +done: + jr ra + nop + END(memcpy) +l_exc_copy: + /* + * Copy bytes from src until faulting load address (or until a + * lb faults) + * + * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) + * may be more than a byte beyond the last address. + * Hence, the lb below may get an exception. + * + * Assumes src < THREAD_BUADDR($28) + */ + LOAD t0, THREAD_BUADDR($28) 1: - beqz ta2, u_do_end_words - andi t8, a2, 0x1c +EXC( lb t1, 0(src), l_exc) + ADD src, src, 1 + sb t1, 0(dst) # can't fault -- we're copy_from_user + bne src, t0, 1b + ADD dst, dst, 1 +l_exc: + LOAD t0, THREAD_BUADDR($28) # t0 is just past last good address + nop + SUB len, AT, t0 # len number of uncopied bytes + /* + * Here's where we rely on src and dst being incremented in tandem, + * See (3) above. + * dst += (fault addr - src) to put dst at first byte to clear + */ + ADD dst, t0 # compute start address in a1 + SUB dst, src + /* + * Clear len bytes starting at dst. Can't call __bzero because it + * might modify len. An inefficient loop for these rare times... + */ + beqz len, done + SUB src, len, 1 +1: sb zero, 0(dst) + ADD dst, dst, 1 + bnez src, 1b + SUB src, src, 1 + jr ra + nop -u_move_32bytes: - UMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - daddu a1, a1, 0x20 - daddu a0, a0, 0x20 - -u_do_end_words: - beqz t8, u_maybe_end_cruft - srl t8, t8, 0x2 - -u_end_words: - EX(lw, ta0, 0x00(a1), l_fixup) - dsubu t8, t8, 0x1 - UEX(usw, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x4 - bnez t8, u_end_words - daddu a0, a0, 0x4 - -u_maybe_end_cruft: - andi ta2, a2, 0x3 - -u_cannot_optimize: - beqz ta2, out - move a2, ta2 - -u_end_bytes: - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - bnez a2, u_end_bytes - daddu a0, a0, 0x1 - jr ra - move a2, zero - END(memcpy) +#define SEXC(n) \ +s_exc_p ## n ## u: \ + jr ra; \ + ADD len, len, n*NBYTES + +SEXC(8) +SEXC(7) +SEXC(6) +SEXC(5) +SEXC(4) +SEXC(3) +SEXC(2) +SEXC(1) -/* descending order, destination aligned */ -#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - sw t0, (offset + 0x10)(dst); \ - sw t1, (offset + 0x14)(dst); \ - sw t2, (offset + 0x18)(dst); \ - sw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - sw t0, (offset + 0x00)(dst); \ - sw t1, (offset + 0x04)(dst); \ - sw t2, (offset + 0x08)(dst); \ - sw t3, (offset + 0x0c)(dst) - -/* descending order, destination ununaligned */ -#define RUMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - usw t0, (offset + 0x10)(dst); \ - usw t1, (offset + 0x14)(dst); \ - usw t2, (offset + 0x18)(dst); \ - usw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - usw t0, (offset + 0x00)(dst); \ - usw t1, (offset + 0x04)(dst); \ - usw t2, (offset + 0x08)(dst); \ - usw t3, (offset + 0x0c)(dst) +s_exc_p1: + jr ra + ADD len, len, 1 +s_exc: + jr ra + nop .align 5 LEAF(memmove) - daddu t0, a0, a2 + ADD t0, a0, a2 + ADD t1, a1, a2 sltu t0, a1, t0 # dst + len <= src -> memcpy - daddu t1, a1, a2 sltu t1, a0, t1 # dst >= src + len -> memcpy and t0, t1 beqz t0, __memcpy - move v0, a0 /* return value */ beqz a2, r_out END(memmove) + /* fall through to __rmemcpy */ LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ - sltu t0, a1, a0 + sltu t0, a1, a0 beqz t0, r_end_bytes_up # src >= dst nop - daddu a0, a2 # dst = dst + len - daddu a1, a2 # src = src + len - -#if 0 /* Horror fix */ - xor ta0, a0, a1 - andi ta0, ta0, 0x3 - move t3, a0 - beqz ta0, r_can_align - sltiu t8, a2, 0x8 - - b r_memcpy_u_src # bad alignment - move ta2, a2 - -r_can_align: - bnez t8, r_small_memcpy # < 8 bytes to copy - move ta2, a2 - - beqz a2, r_out - andi t8, a1, 0x1 - -r_hword_align: - beqz t8, r_word_align - andi t8, a1, 0x2 - - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 - dsubu a0, a0, 0x1 - andi t8, a1, 0x2 - -r_word_align: - beqz t8, r_dword_align - sltiu t8, a2, 56 - - lh ta0, -2(a1) - dsubu a2, a2, 0x2 - sh ta0, -2(a0) - sltiu t8, a2, 56 - dsubu a0, a0, 0x2 - dsubu a1, a1, 0x2 - -r_dword_align: - bnez t8, r_do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, r_qword_align - andi t8, a1, 0x8 - - lw ta0, -4(a1) - dsubu a2, a2, 0x4 - sw ta0, -4(a0) - dsubu a1, a1, 0x4 - dsubu a0, a0, 0x4 - andi t8, a1, 0x8 - -r_qword_align: - beqz t8, r_oword_align - andi t8, a1, 0x10 - - dsubu a1, a1, 0x8 - lw ta0, 0x04(a1) - lw ta1, 0x00(a1) - dsubu a0, a0, 0x8 - sw ta0, 0x04(a0) - sw ta1, 0x00(a0) - dsubu a2, a2, 0x8 - - andi t8, a1, 0x10 - -r_oword_align: - beqz t8, r_begin_movement - srl t8, a2, 0x7 - - dsubu a1, a1, 0x10 - lw ta3, 0x08(a1) # assumes subblock ordering - lw t0, 0x0c(a1) - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x10 - sw ta3, 0x08(a0) - sw t0, 0x0c(a0) - sw ta0, 0x00(a0) - sw ta1, 0x04(a0) - dsubu a2, a2, 0x10 - srl t8, a2, 0x7 - -r_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -r_move_128bytes: - RMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - dsubu a1, a1, 0x80 - bnez t8, r_move_128bytes - dsubu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -r_move_64bytes: - dsubu a1, a1, 0x40 - dsubu a0, a0, 0x40 - RMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - -1: - beqz ta2, r_do_end_words - andi t8, a2, 0x1c - -r_move_32bytes: - dsubu a1, a1, 0x20 - dsubu a0, a0, 0x20 - RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - -r_do_end_words: - beqz t8, r_maybe_end_cruft - srl t8, t8, 0x2 - -r_end_words: - lw ta0, -4(a1) - dsubu t8, t8, 0x1 - sw ta0, -4(a0) - dsubu a1, a1, 0x4 - bnez t8, r_end_words - dsubu a0, a0, 0x4 - -r_maybe_end_cruft: - andi ta2, a2, 0x3 - -r_small_memcpy: - beqz ta2, r_out - move a2, ta2 -#endif /* Horror fix */ + ADD a0, a2 # dst = dst + len + ADD a1, a2 # src = src + len r_end_bytes: - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 + lb t0, -1(a1) + SUB a2, a2, 0x1 + sb t0, -1(a0) + SUB a1, a1, 0x1 bnez a2, r_end_bytes - dsubu a0, a0, 0x1 + SUB a0, a0, 0x1 r_out: - jr ra - move a2, zero + jr ra + move a2, zero r_end_bytes_up: lb t0, (a1) - dsubu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, (a0) - daddu a1, a1, 0x1 + ADD a1, a1, 0x1 bnez a2, r_end_bytes_up - daddu a0, a0, 0x1 + ADD a0, a0, 0x1 jr ra move a2, zero - -#if 0 /* Horror fix */ -/* ------------------------------------------------------------------------- */ - -/* Bad, bad. At least try to align the source */ - -r_memcpy_u_src: - bnez t8, r_small_memcpy # < 8 bytes? - move ta2, a2 - - andi ta0, a1, 7 # ta0: how much to align - - ulw ta1, -8(a1) # dword alignment - ulw ta2, -4(a1) - usw ta1, -8(a0) - usw ta2, -4(a0) - - dsubu a1, ta0 # src - dsubu a0, ta0 # dst - dsubu a2, ta0 # len - - sltiu t8, a2, 56 - bnez t8, ru_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -ru_qword_align: - beqz t8, ru_oword_align - andi t8, a1, 0x10 - - dsubu a1, a1, 0x8 - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x8 - usw ta0, 0x00(a0) - usw ta1, 0x04(a0) - dsubu a2, a2, 0x8 - - andi t8, a1, 0x10 - -ru_oword_align: - beqz t8, ru_begin_movement - srl t8, a2, 0x7 - - dsubu a1, a1, 0x10 - lw ta3, 0x08(a1) # assumes subblock ordering - lw t0, 0x0c(a1) - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x10 - usw ta3, 0x08(a0) - usw t0, 0x0c(a0) - usw ta0, 0x00(a0) - usw ta1, 0x04(a0) - dsubu a2, a2, 0x10 - - srl t8, a2, 0x7 - -ru_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -ru_move_128bytes: - RUMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - dsubu a1, a1, 0x80 - bnez t8, ru_move_128bytes - dsubu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -ru_move_64bytes: - dsubu a1, a1, 0x40 - dsubu a0, a0, 0x40 - RUMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - -1: - beqz ta2, ru_do_end_words - andi t8, a2, 0x1c - -ru_move_32bytes: - dsubu a1, a1, 0x20 - dsubu a0, a0, 0x20 - RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - -ru_do_end_words: - beqz t8, ru_maybe_end_cruft - srl t8, t8, 0x2 - -ru_end_words: - lw ta0, -4(a1) - usw ta0, -4(a0) - dsubu t8, t8, 0x1 - dsubu a1, a1, 0x4 - bnez t8, ru_end_words - dsubu a0, a0, 0x4 - -ru_maybe_end_cruft: - andi ta2, a2, 0x3 - -ru_cannot_optimize: - beqz ta2, r_out - move a2, ta2 - -ru_end_bytes: - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 - bnez a2, ru_end_bytes - dsubu a0, a0, 0x1 - - jr ra - move a2, zero -#endif /* Horror fix */ END(__rmemcpy) - -l_fixup: # clear the rest of the buffer - ld ta0, THREAD_BUADDR($28) - nop - dsubu a2, AT, ta0 # a2 bytes to go - daddu a0, ta0 # compute start address in a1 - dsubu a0, a1 - /* - * Clear len bytes starting at dst. Can't call __bzero because it - * might modify len. An inefficient loop for these rare times... - */ - beqz a2, 2f - dsubu a1, a2, 1 -1: sb zero, 0(a0) - daddu a0, a0, 1 - bnez a1, 1b - dsubu a1, a1, 1 -2: jr ra - nop - -s_fixup: - jr ra - nop diff -urN linux-2.4.21/arch/mips64/lib/promlib.c linux-2.4.22/arch/mips64/lib/promlib.c --- linux-2.4.21/arch/mips64/lib/promlib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/lib/promlib.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,24 @@ +#include +#include + +extern void prom_putchar(char); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff -urN linux-2.4.21/arch/mips64/lib/strlen_user.S linux-2.4.22/arch/mips64/lib/strlen_user.S --- linux-2.4.21/arch/mips64/lib/strlen_user.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/lib/strlen_user.S 2003-08-25 04:44:40.000000000 -0700 @@ -25,7 +25,7 @@ LEAF(__strlen_user_asm) ld v0, THREAD_CURDS($28) # pointer ok? and v0, a0 - bltz v0, fault + bnez v0, fault FEXPORT(__strlen_user_nocheck_asm) move v0, a0 diff -urN linux-2.4.21/arch/mips64/lib/strncpy_user.S linux-2.4.22/arch/mips64/lib/strncpy_user.S --- linux-2.4.21/arch/mips64/lib/strncpy_user.S 2001-09-09 10:43:02.000000000 -0700 +++ linux-2.4.22/arch/mips64/lib/strncpy_user.S 2003-08-25 04:44:40.000000000 -0700 @@ -30,7 +30,7 @@ LEAF(__strncpy_from_user_asm) ld v0, THREAD_CURDS($28) # pointer ok? and v0, a1 - bltz v0, fault + bnez v0, fault FEXPORT(__strncpy_from_user_nocheck_asm) move v0, zero diff -urN linux-2.4.21/arch/mips64/lib/strnlen_user.S linux-2.4.22/arch/mips64/lib/strnlen_user.S --- linux-2.4.21/arch/mips64/lib/strnlen_user.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/lib/strnlen_user.S 2003-08-25 04:44:40.000000000 -0700 @@ -25,7 +25,7 @@ LEAF(__strnlen_user_asm) ld v0, THREAD_CURDS($28) # pointer ok? and v0, a0 - bltz v0, fault + bnez v0, fault FEXPORT(__strnlen_user_nocheck_asm) move v0, a0 diff -urN linux-2.4.21/arch/mips64/mm/Makefile linux-2.4.22/arch/mips64/mm/Makefile --- linux-2.4.21/arch/mips64/mm/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,27 +6,29 @@ O_TARGET := mm.o -export-objs += umap.o -obj-y := extable.o init.o fault.o loadmmu.o - -obj-$(CONFIG_CPU_R4300) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o -obj-$(CONFIG_CPU_R4X00) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5000) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_NEVADA) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_R10000) += andes.o tlbex-r4k.o tlb-glue-r4k.o -obj-$(CONFIG_CPU_SB1) += pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o \ - tlb-glue-r4k.o -obj-$(CONFIG_CPU_MIPS64) += pg-mips64.o c-mips64.o tlb-r4k.o \ - tlbex-r4k.o tlb-glue-r4k.o +export-objs := cache.o loadmmu.o +obj-y := cache.o extable.o init.o fault.o loadmmu.o \ + tlbex-r4k.o + +obj-$(CONFIG_CPU_R4300) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R4X00) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R5000) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_NEVADA) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R5432) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_RM7000) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R10000) += c-r4k.o pg-r4k.o tlb-andes.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_SB1) += c-sb1.o pg-sb1.o tlb-sb1.o tlb-glue-sb1.o \ + cex-sb1.o cerr-sb1.o +obj-$(CONFIG_CPU_MIPS64) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o + +obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o +obj-$(CONFIG_SGI_IP22) += sc-ip22.o # # Debug TLB exception handler, currently unused # -#obj-y += tlb-dbg-r4k.o tlb-glue-r4k.o - -obj-$(CONFIG_SGI_IP22) += umap.o +#obj-y += tlb-dbg-r4k.o AFLAGS_tlb-glue-r4k.o := -P diff -urN linux-2.4.21/arch/mips64/mm/andes.c linux-2.4.22/arch/mips64/mm/andes.c --- linux-2.4.21/arch/mips64/mm/andes.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/andes.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,350 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int scache_lsz64; - -/* - * This version has been tuned on an Origin. For other machines the arguments - * of the pref instructin may have to be tuned differently. - */ -static void andes_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tpref 7,512(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE) - : "memory"); -} - -/* R10000 has no Create_Dirty type cacheops. */ -static void andes_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tpref\t0,2*128(%1)\n\t" - "pref\t1,2*128(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), - "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), "I" (PAGE_SIZE)); -} - -/* Cache operations. These are only used with the virtual memory system, - not for non-coherent I/O so it's ok to ignore the secondary caches. */ -static void -andes_flush_cache_l1(void) -{ - blast_dcache32(); blast_icache64(); -} - -/* - * This is only used during initialization time. vmalloc() also calls - * this, but that will be changed pretty soon. - */ -static void andes_flush_cache_l2(void) -{ - switch (sc_lsize()) { - case 64: - blast_scache64(); - break; - case 128: - blast_scache128(); - break; - default: - printk(KERN_EMERG "Unknown L2 line size\n"); - while(1); - } -} - -void -andes_flush_icache_page(unsigned long page) -{ - if (scache_lsz64) - blast_scache64_page(page); - else - blast_scache128_page(page); -} - -static void -andes_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -#define NTLB_ENTRIES 64 -#define NTLB_ENTRIES_HALF 32 - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - unsigned long entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & ASID_MASK; - set_entryhi(CKSEG0); - set_entrylo0(0); - set_entrylo1(0); - - entry = get_wired(); - - /* Blast 'em all away. */ - while (entry < NTLB_ENTRIES) { - set_index(entry); - tlb_write_indexed(); - entry++; - } - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) - & ASID_MASK); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", - (mm->context & ASID_MASK), start, end); -#endif - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if (size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & ASID_MASK); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) - & ASID_MASK); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - continue; - tlb_write_indexed(); - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) - & ASID_MASK); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & - ASID_MASK); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & ASID_MASK); - set_entryhi(page | newpid); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if (idx < 0) - goto finish; - tlb_write_indexed(); - - finish: - set_entryhi(oldpid); - __restore_flags(flags); - } -} - -/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual - address that already exists will overwrite the old entry and not result - in TLB malfunction or TLB shutdown. */ -static void andes_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & ASID_MASK; - - if ((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & ASID_MASK)) - || (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk(KERN_WARNING - "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - __FUNCTION__, (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & ASID_MASK), pid); - } - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - if (idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - set_entryhi(pid); - __restore_flags(flags); -} - -void __init ld_mmu_andes(void) -{ - printk("Primary instruction cache %dkb, linesize %d bytes\n", - icache_size >> 10, ic_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - dcache_size >> 10, dc_lsize); - printk("Secondary cache sized at %ldK, linesize %ld\n", - scache_size() >> 10, sc_lsize()); - - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - - _flush_cache_l1 = andes_flush_cache_l1; - _flush_cache_l2 = andes_flush_cache_l2; - _flush_cache_sigtramp = andes_flush_cache_sigtramp; - - switch (sc_lsize()) { - case 64: - scache_lsz64 = 1; - break; - case 128: - scache_lsz64 = 0; - break; - default: - printk(KERN_EMERG "Unknown L2 line size\n"); - while(1); - } - - _update_mmu_cache = andes_update_mmu_cache; - - flush_cache_l1(); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - write_32bit_cp0_register(CP0_FRAMEMASK, 0); - - /* From this point on the ARC firmware is dead. */ - local_flush_tlb_all(); - - /* Did I tell you that ARC SUCKS? */ -} diff -urN linux-2.4.21/arch/mips64/mm/c-mips64.c linux-2.4.22/arch/mips64/mm/c-mips64.c --- linux-2.4.21/arch/mips64/mm/c-mips64.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/c-mips64.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,670 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute 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 it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You 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. - * - * MIPS64 CPU variant specific Cache routines. - * These routine are not optimized in any way, they are done in a generic way - * so they can be used on all MIPS64 compliant CPUs, and also done in an - * attempt not to break anything for the R4xx0 style CPUs. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -int icache_size, dcache_size; /* Size in bytes */ -int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include - -#undef DEBUG_CACHE - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - - -static inline void mips64_flush_cache_all_sc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); blast_scache(); - __restore_flags(flags); -} - -static inline void mips64_flush_cache_all_pc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); -} - -static void -mips64_flush_cache_range_sc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - unsigned long flags; - - if(mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if(mm->context != current->mm->context) { - mips64_flush_cache_all_sc(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - __save_and_cli(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache_page(start); - start += PAGE_SIZE; - } - __restore_flags(flags); - } - } -} - -static void mips64_flush_cache_range_pc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void mips64_flush_cache_mm_sc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips64_flush_cache_all_sc(); - } -} - -static void mips64_flush_cache_mm_pc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips64_flush_cache_all_pc(); - } -} - -static void mips64_flush_cache_page_sc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache_page_indexed(page); - blast_scache_page_indexed(page); - } else - blast_scache_page(page); -out: - __restore_flags(flags); -} - -static void mips64_flush_cache_page_pc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since Mips64 caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & ((unsigned long)dcache_size - 1))); - blast_dcache_page_indexed(page); - } -out: - __restore_flags(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void mips64_flush_page_to_ram_sc(struct page *page) -{ - blast_scache_page((unsigned long)page_address(page)); -} - -static void mips64_flush_page_to_ram_pc(struct page *page) -{ - blast_dcache_page((unsigned long)page_address(page)); -} - -static void -mips64_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -static void -mips64_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -static void -mips64_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - unsigned long address; - - if (!(vma->vm_flags & VM_EXEC)) - return; - - address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & ((unsigned long)icache_size - 1)); - blast_icache_page_indexed(address); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -mips64_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - blast_dcache(); - } else { - __save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - bc_wback_inv(addr, size); -} - -static void -mips64_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_scache(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips64_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - blast_dcache(); - } else { - __save_and_cli(flags); - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - invalidate_dcache_line(a); /* Hit_Inv_D */ - if (a == end) break; - a += (unsigned long)dc_lsize; - } - __restore_flags(flags); - } - - bc_inv(addr, size); -} - -static void -mips64_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_scache(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - invalidate_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips64_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("mips64_dma_cache called - should not happen.\n"); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void mips64_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void -mips64_flush_icache_all(void) -{ - if (mips_cpu.cputype == CPU_20KC) { - blast_icache(); - } -} - - -/* Detect and size the various caches. */ -static void __init probe_icache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS64 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - mips_cpu.icache.linesz = ic_lsize; - - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1; - mips_cpu.icache.sets = - (icache_size / ic_lsize) / mips_cpu.icache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 19) & 7))) - mips_cpu.icache.linesz = 2 << lsize; - else - mips_cpu.icache.linesz = lsize; - mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7); - mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7); - - ic_lsize = mips_cpu.icache.linesz; - icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * - ic_lsize; - } - printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n", - icache_size >> 10, ic_lsize, mips_cpu.icache.ways); -} - -static void __init probe_dcache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS64 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - mips_cpu.dcache.linesz = dc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1; - mips_cpu.dcache.sets = - (dcache_size / dc_lsize) / mips_cpu.dcache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 10) & 7))) - mips_cpu.dcache.linesz = 2 << lsize; - else - mips_cpu.dcache.linesz= lsize; - mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7); - mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7); - - dc_lsize = mips_cpu.dcache.linesz; - dcache_size = - mips_cpu.dcache.sets * mips_cpu.dcache.ways - * dc_lsize; - } - printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n", - dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT) - return 0; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - __save_and_cli(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 8, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 9, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 11, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 7, (%0)\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - __restore_flags(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - _clear_page = (void *)mips64_clear_page_dc; - _copy_page = (void *)mips64_copy_page_dc; - _flush_cache_all = mips64_flush_cache_all_pc; - ___flush_cache_all = mips64_flush_cache_all_pc; - _flush_cache_mm = mips64_flush_cache_mm_pc; - _flush_cache_range = mips64_flush_cache_range_pc; - _flush_cache_page = mips64_flush_cache_page_pc; - _flush_page_to_ram = mips64_flush_page_to_ram_pc; - - _flush_icache_page = mips64_flush_icache_page; - - _dma_cache_wback_inv = mips64_dma_cache_wback_inv_pc; - _dma_cache_wback = mips64_dma_cache_wback; - _dma_cache_inv = mips64_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - _flush_cache_all = mips64_flush_cache_all_sc; - ___flush_cache_all = mips64_flush_cache_all_sc; - _flush_cache_mm = mips64_flush_cache_mm_sc; - _flush_cache_range = mips64_flush_cache_range_sc; - _flush_cache_page = mips64_flush_cache_page_sc; - _flush_page_to_ram = mips64_flush_page_to_ram_sc; - _clear_page = (void *)mips64_clear_page_sc; - _copy_page = (void *)mips64_copy_page_sc; - - _flush_icache_page = mips64_flush_icache_page_s; - - _dma_cache_wback_inv = mips64_dma_cache_wback_inv_sc; - _dma_cache_wback = mips64_dma_cache_wback; - _dma_cache_inv = mips64_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (sc_present) { - mips_cpu.scache.linesz = sc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1; - mips_cpu.scache.sets = - (scache_size / sc_lsize) / mips_cpu.scache.ways; - - setup_scache_funcs(); - return; - } - - setup_noscache_funcs(); -} - -void __init ld_mmu_mips64(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - _flush_cache_sigtramp = mips64_flush_cache_sigtramp; - _flush_icache_range = mips64_flush_icache_range; /* Ouch */ - _flush_icache_all = mips64_flush_icache_all; - _flush_cache_l1 = _flush_cache_all; - _flush_cache_l2 = _flush_cache_all; - - __flush_cache_all(); -} diff -urN linux-2.4.21/arch/mips64/mm/c-r4k.c linux-2.4.22/arch/mips64/mm/c-r4k.c --- linux-2.4.21/arch/mips64/mm/c-r4k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/c-r4k.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,1250 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned long icache_size, dcache_size, scache_size; + +extern void andes_clear_page(void * page); +extern void r4k_clear_page32_d16(void * page); +extern void r4k_clear_page32_d32(void * page); +extern void r4k_clear_page_d16(void * page); +extern void r4k_clear_page_d32(void * page); +extern void r4k_clear_page_r4600_v1(void * page); +extern void r4k_clear_page_r4600_v2(void * page); +extern void r4k_clear_page_s16(void * page); +extern void r4k_clear_page_s32(void * page); +extern void r4k_clear_page_s64(void * page); +extern void r4k_clear_page_s128(void * page); +extern void andes_copy_page(void * to, void * from); +extern void r4k_copy_page_d16(void * to, void * from); +extern void r4k_copy_page_d32(void * to, void * from); +extern void r4k_copy_page_r4600_v1(void * to, void * from); +extern void r4k_copy_page_r4600_v2(void * to, void * from); +extern void r4k_copy_page_s16(void * to, void * from); +extern void r4k_copy_page_s32(void * to, void * from); +extern void r4k_copy_page_s64(void * to, void * from); +extern void r4k_copy_page_s128(void * to, void * from); + +/* + * Dummy cache handling routines for machines without boardcaches + */ +static void no_sc_noop(void) {} + +static struct bcache_ops no_sc_ops = { + .bc_enable = (void *)no_sc_noop, + .bc_disable = (void *)no_sc_noop, + .bc_wback_inv = (void *)no_sc_noop, + .bc_inv = (void *)no_sc_noop +}; + +struct bcache_ops *bcops = &no_sc_ops; + +#define R4600_HIT_CACHEOP_WAR_IMPL \ +do { \ + if (R4600_V2_HIT_CACHEOP_WAR && \ + (read_c0_prid() & 0xfff0) == 0x2020) { /* R4600 V2.0 */\ + *(volatile unsigned long *)KSEG1; \ + } \ + if (R4600_V1_HIT_CACHEOP_WAR) \ + __asm__ __volatile__("nop;nop;nop;nop"); \ +} while (0) + +static void r4k_blast_dcache_page(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page(addr); + return; + +dc_32: + R4600_HIT_CACHEOP_WAR_IMPL; + blast_dcache32_page(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache_page_indexed(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page_indexed(addr); + return; + +dc_32: + blast_dcache32_page_indexed(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache(void) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16(); + return; + +dc_32: + blast_dcache32(); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */ +#define JUMP_TO_ALIGN(order) \ + __asm__ __volatile__( \ + "b\t1f\n\t" \ + ".align\t" #order "\n\t" \ + "1:\n\t" \ + ) +#define CACHE32_UNROLL32_ALIGN JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */ +#define CACHE32_UNROLL32_ALIGN2 JUMP_TO_ALIGN(11) + +static inline void tx49_blast_icache32(void) +{ + unsigned long start = KSEG0; + unsigned long end = start + current_cpu_data.icache.waysize; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); +} + +static inline void tx49_blast_icache32_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); +} + +static void r4k_blast_icache_page(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page(addr); + return; + +ic_32: + blast_icache32_page(addr); + return; + +ic_64: + blast_icache64_page(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache_page_indexed(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page_indexed(addr); + return; + +ic_32: + blast_icache32_page_indexed(addr); + return; + +ic_64: + blast_icache64_page_indexed(addr); + return; + +ic_32_tx49: + tx49_blast_icache32_page_indexed(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache(void) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16(); + return; + +ic_32: + blast_icache32(); + return; + +ic_64: + blast_icache64(); + return; + +ic_32_tx49: + tx49_blast_icache32(); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_scache_page(unsigned long addr) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16_page(addr); + return; + +sc_32: + blast_scache32_page(addr); + return; + +sc_64: + blast_scache64_page(addr); + return; + +sc_128: + blast_scache128_page(addr); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_blast_scache(void) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16(); + return; + +sc_32: + blast_scache32(); + return; + +sc_64: + blast_scache64(); + return; + +sc_128: + blast_scache128(); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); +} + +static void r4k___flush_cache_all(void) +{ + r4k_blast_dcache(); + r4k_blast_icache(); + + switch (current_cpu_data.cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R10000: + case CPU_R12000: + r4k_blast_scache(); + } +} + +static void r4k_flush_cache_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (!cpu_has_dc_aliases) + return; + + if (cpu_context(smp_processor_id(), mm) != 0) { + r4k_blast_dcache(); + r4k_blast_icache(); + } +} + +static void r4k_flush_cache_mm(struct mm_struct *mm) +{ + if (!cpu_has_dc_aliases) + return; + + if (!cpu_context(smp_processor_id(), mm)) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); + + /* + * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we + * only flush the primary caches but R10000 and R12000 behave sane ... + */ + if (current_cpu_data.cputype == CPU_R4000SC || + current_cpu_data.cputype == CPU_R4000MC || + current_cpu_data.cputype == CPU_R4400SC || + current_cpu_data.cputype == CPU_R4400MC) + r4k_blast_scache(); +} + +static void r4k_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) +{ + int exec = vma->vm_flags & VM_EXEC; + struct mm_struct *mm = vma->vm_mm; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + /* + * If ownes no valid ASID yet, cannot possibly have gotten + * this page into the cache. + */ + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + page &= PAGE_MASK; + pgdp = pgd_offset(mm, page); + pmdp = pmd_offset(pgdp, page); + ptep = pte_offset(pmdp, page); + + /* + * If the page isn't marked valid, the page cannot possibly be + * in the cache. + */ + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; + + /* + * Doing flushes for another ASID than the current one is + * too difficult since stupid R4k caches do a TLB translation + * for every cache flush operation. So we do indexed flushes + * in that case, which doesn't overly flush the cache too much. + */ + if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page(page); + if (exec) + r4k_blast_icache_page(page); + + return; + } + + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page_indexed(page); + if (exec) { + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache_page_indexed(page); + } +} + +static void r4k_flush_data_cache_page(unsigned long addr) +{ + r4k_blast_dcache_page(addr); +} + +static void r4k_flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + + if (!cpu_has_ic_fills_f_dc) { + if (end - start > dcache_size) + r4k_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + } + + if (end - start > icache_size) + r4k_blast_icache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } +} + +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_subset_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); +} + +#ifdef CONFIG_NONCOHERENT_IO + +static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches + * explicitly + */ + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_wback_inv(addr, size); +} + +static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_inv(addr, size); +} +#endif /* CONFIG_NONCOHERENT_IO */ + +/* + * While we're protected against bad userland addresses we don't care + * very much about what happens in that case. Usually a segmentation + * fault will dump the process later on anyway ... + */ +static void r4k_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); + if (MIPS4K_ICACHE_REFILL_WAR) { + __asm__ __volatile__ ( + ".set push\n\t" + ".set noat\n\t" + ".set mips3\n\t" +#if CONFIG_MIPS32 + "la $at,1f\n\t" +#endif +#if CONFIG_MIPS64 + "dla $at,1f\n\t" +#endif + "cache %0,($at)\n\t" + "nop; nop; nop\n" + "1:\n\t" + ".set pop" + : + : "i" (Hit_Invalidate_I)); + } + if (MIPS_CACHE_SYNC_WAR) + __asm__ __volatile__ ("sync"); +} + +static void r4k_flush_icache_all(void) +{ + if (cpu_has_vtag_icache) + r4k_blast_icache(); +} + +static inline void rm7k_erratum31(void) +{ + const unsigned long ic_lsize = 32; + unsigned long addr; + + /* RM7000 erratum #31. The icache is screwed at startup. */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + "cache\t%2, 0(%0)\n\t" + "cache\t%2, 0x1000(%0)\n\t" + "cache\t%2, 0x2000(%0)\n\t" + "cache\t%2, 0x3000(%0)\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + ".set\tmips0\n\t" + ".set\treorder\n\t" + : + : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); + } +} + +static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", + "5-way", "6-way", "7-way", "8-way" +}; + +static void __init probe_pcache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + unsigned int prid = read_c0_prid(); + unsigned long config1; + unsigned int lsize; + + switch (c->cputype) { + case CPU_R4600: /* QED style two way caches? */ + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit= ffs(dcache_size/2) - 1; + break; + + case CPU_R5432: + case CPU_R5500: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_TX49XX: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = 0; + break; + + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R4300: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_R10000: + case CPU_R12000: + icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29)); + c->icache.linesz = 64; + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26)); + c->dcache.linesz = 32; + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_VR4131: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = ffs(dcache_size/2) - 1; + break; + + case CPU_VR41XX: + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_RM7000: + rm7k_erratum31(); + + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + break; + + default: + if (!(config & MIPS_CONF_M)) + panic("Don't know how to probe P-caches on this cpu."); + + /* + * So we seem to be a MIPS32 or MIPS64 CPU + * So let's probe the I-cache ... + */ + config1 = read_c0_config1(); + + if ((lsize = ((config1 >> 19) & 7))) + c->icache.linesz = 2 << lsize; + else + c->icache.linesz = lsize; + c->icache.sets = 64 << ((config1 >> 22) & 7); + c->icache.ways = 1 + ((config1 >> 16) & 7); + + icache_size = c->icache.sets * + c->icache.ways * + c->icache.linesz; + c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + + /* + * Now probe the MIPS32 / MIPS64 data cache. + */ + c->dcache.flags = 0; + + if ((lsize = ((config1 >> 10) & 7))) + c->dcache.linesz = 2 << lsize; + else + c->dcache.linesz= lsize; + c->dcache.sets = 64 << ((config1 >> 13) & 7); + c->dcache.ways = 1 + ((config1 >> 7) & 7); + + dcache_size = c->dcache.sets * + c->dcache.ways * + c->dcache.linesz; + c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + break; + } + + /* + * Processor configuration sanity check for the R4000SC erratum + * #5. With page sizes larger than 32kB there is no possibility + * to get a VCE exception anymore so we don't care about this + * misconfiguration. The case is rather theoretical anyway; + * presumably no vendor is shipping his hardware in the "bad" + * configuration. + */ + if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && + !(config & CONF_SC) && c->icache.linesz != 16 && + PAGE_SIZE <= 0x8000) + panic("Improper R4000SC processor configuration detected"); + + /* compute a couple of other cache variables */ + c->icache.waysize = icache_size / c->icache.ways; + c->dcache.waysize = dcache_size / c->dcache.ways; + + c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); + c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); + + /* + * R10000 and R12000 P-caches are odd in a positive way. They're 32kB + * 2-way virtually indexed so normally would suffer from aliases. So + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ + if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000) + if (c->dcache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + switch (c->cputype) { + case CPU_20KC: + /* + * Some older 20Kc chips doesn't have the 'VI' bit in + * the config register. + */ + c->icache.flags |= MIPS_CACHE_VTAG; + break; + + case CPU_AU1500: + c->icache.flags |= MIPS_CACHE_IC_F_DC; + break; + } + + printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", + icache_size >> 10, + cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", + way_string[c->icache.ways], c->icache.linesz); + + printk("Primary data cache %ldkB %s, linesize %d bytes.\n", + dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); +} + +/* + * If you even _breathe_ on this function, look at the gcc output and make sure + * it does not pop things on and off the stack for the cache sizing loop that + * executes in KSEG1 space or else you will crash and burn badly. You have + * been warned. + */ +static int __init probe_scache(void) +{ + extern unsigned long stext; + unsigned long flags, addr, begin, end, pow2; + unsigned int config = read_c0_config(); + struct cpuinfo_mips *c = ¤t_cpu_data; + int tmp; + + if (config & CONF_SC) + return 0; + + begin = (unsigned long) &stext; + begin &= ~((4 * 1024 * 1024) - 1); + end = begin + (4 * 1024 * 1024); + + /* + * This is such a bitch, you'd think they would make it easy to do + * this. Away you daemons of stupidity! + */ + local_irq_save(flags); + + /* Fill each size-multiple cache line with a valid tag. */ + pow2 = (64 * 1024); + for (addr = begin; addr < end; addr = (begin + pow2)) { + unsigned long *p = (unsigned long *) addr; + __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ + pow2 <<= 1; + } + + /* Load first line with zero (therefore invalid) tag. */ + write_c0_taglo(0); + write_c0_taghi(0); + __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ + cache_op(Index_Store_Tag_I, begin); + cache_op(Index_Store_Tag_D, begin); + cache_op(Index_Store_Tag_SD, begin); + + /* Now search for the wrap around point. */ + pow2 = (128 * 1024); + tmp = 0; + for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { + cache_op(Index_Load_Tag_SD, addr); + __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ + if (!read_c0_taglo()) + break; + pow2 <<= 1; + } + local_irq_restore(flags); + addr -= begin; + + scache_size = addr; + c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); + c->scache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + + return 1; +} + +static void __init setup_noscache_funcs(void) +{ + unsigned int prid; + + switch (current_cpu_data.dcache.linesz) { + case 16: + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d16; + else + _clear_page = r4k_clear_page32_d16; + _copy_page = r4k_copy_page_d16; + + break; + case 32: + prid = read_c0_prid() & 0xfff0; + if (prid == 0x2010) { /* R4600 V1.7 */ + _clear_page = r4k_clear_page_r4600_v1; + _copy_page = r4k_copy_page_r4600_v1; + } else if (prid == 0x2020) { /* R4600 V2.0 */ + _clear_page = r4k_clear_page_r4600_v2; + _copy_page = r4k_copy_page_r4600_v2; + } else { + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d32; + else + _clear_page = r4k_clear_page32_d32; + _copy_page = r4k_copy_page_d32; + } + break; + } +} + +static void __init setup_scache_funcs(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + if (c->dcache.linesz > c->scache.linesz) + panic("Invalid primary cache configuration detected"); + + if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) { + _clear_page = andes_clear_page; + _copy_page = andes_copy_page; + return; + } + + switch (c->scache.linesz) { + case 16: + _clear_page = r4k_clear_page_s16; + _copy_page = r4k_copy_page_s16; + break; + case 32: + _clear_page = r4k_clear_page_s32; + _copy_page = r4k_copy_page_s32; + break; + case 64: + _clear_page = r4k_clear_page_s64; + _copy_page = r4k_copy_page_s64; + break; + case 128: + _clear_page = r4k_clear_page_s128; + _copy_page = r4k_copy_page_s128; + break; + } +} + +typedef int (*probe_func_t)(unsigned long); +extern int r5k_sc_init(void); +extern int rm7k_sc_init(void); + +static void __init setup_scache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + probe_func_t probe_scache_kseg1; + int sc_present = 0; + + /* + * Do the probing thing on R4000SC and R4400SC processors. Other + * processors don't have a S-cache that would be relevant to the + * Linux memory managment. + */ + switch (c->cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); + sc_present = probe_scache_kseg1(config); + break; + + case CPU_R10000: + case CPU_R12000: + scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16); + c->scache.linesz = 64 << ((config >> 13) & 1); + c->scache.ways = 2; + c->scache.waybit= 0; + sc_present = 1; + break; + + case CPU_R5000: + case CPU_NEVADA: + setup_noscache_funcs(); +#ifdef CONFIG_R5000_CPU_SCACHE + r5k_sc_init(); +#endif + return; + + case CPU_RM7000: + setup_noscache_funcs(); +#ifdef CONFIG_RM7000_CPU_SCACHE + rm7k_sc_init(); +#endif + return; + + default: + sc_present = 0; + } + + if (!sc_present) { + setup_noscache_funcs(); + return; + } + + if ((c->isa_level == MIPS_CPU_ISA_M32 || + c->isa_level == MIPS_CPU_ISA_M64) && + !(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) + panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); + + /* compute a couple of other cache variables */ + c->scache.waysize = scache_size / c->scache.ways; + + c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); + + printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + c->options |= MIPS_CPU_SUBSET_CACHES; + setup_scache_funcs(); +} + +static inline void coherency_setup(void) +{ + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + + /* + * c0_status.cu=0 specifies that updates by the sc instruction use + * the coherency mode specified by the TLB; 1 means cachable + * coherent update on write will be used. Not all processors have + * this bit and; some wire it to zero, others like Toshiba had the + * silly idea of putting something else there ... + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + clear_c0_config(CONF_CU); + break; + } + +} + +void __init ld_mmu_r4xx0(void) +{ + extern char except_vec2_generic; + struct cpuinfo_mips *c = ¤t_cpu_data; + + /* Default cache error handler for R4000 and R5000 family */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80); + + probe_pcache(); + setup_scache(); + coherency_setup(); + + if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + /* + * Some MIPS32 and MIPS64 processors have physically indexed caches. + * This code supports virtually indexed processors and will be + * unnecessarily inefficient on physically indexed processors. + */ + shm_align_mask = max_t( unsigned long, + c->dcache.sets * c->dcache.linesz - 1, + PAGE_SIZE - 1); + + _flush_cache_all = r4k_flush_cache_all; + ___flush_cache_all = r4k___flush_cache_all; + _flush_cache_mm = r4k_flush_cache_mm; + _flush_cache_page = r4k_flush_cache_page; + _flush_icache_page = r4k_flush_icache_page; + _flush_cache_range = r4k_flush_cache_range; + + _flush_cache_sigtramp = r4k_flush_cache_sigtramp; + _flush_icache_all = r4k_flush_icache_all; + _flush_data_cache_page = r4k_flush_data_cache_page; + _flush_icache_range = r4k_flush_icache_range; + +#ifdef CONFIG_NONCOHERENT_IO + _dma_cache_wback_inv = r4k_dma_cache_wback_inv; + _dma_cache_wback = r4k_dma_cache_wback_inv; + _dma_cache_inv = r4k_dma_cache_inv; +#endif + + __flush_cache_all(); +} diff -urN linux-2.4.21/arch/mips64/mm/c-sb1.c linux-2.4.22/arch/mips64/mm/c-sb1.c --- linux-2.4.21/arch/mips64/mm/c-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/c-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,6 +25,15 @@ #include #include +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +extern void sb1_dma_init(void); +extern void sb1_clear_page_dma(void * page); +extern void sb1_copy_page_dma(void * to, void * from); +#else +extern void sb1_clear_page(void * page); +extern void sb1_copy_page(void * to, void * from); +#endif + /* These are probed at ld_mmu time */ static unsigned long icache_size; static unsigned long dcache_size; @@ -33,6 +42,7 @@ static unsigned long dcache_line_size; static unsigned int icache_index_mask; +static unsigned int dcache_index_mask; static unsigned long icache_assoc; static unsigned long dcache_assoc; @@ -40,6 +50,9 @@ static unsigned int icache_sets; static unsigned int dcache_sets; +static unsigned int icache_range_cutoff; +static unsigned int dcache_range_cutoff; + /* * The dcache is fully coherent to the system, with one * big caveat: the instruction stream. In other words, @@ -53,68 +66,223 @@ * to flush it */ -static void sb1_flush_cache_all(void) -{ -} - -static inline void local_sb1___flush_dcache_all(void) +/* + * Writeback and invalidate the entire dcache + */ +static inline void __sb1_writeback_inv_dcache_all(void) { - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* WB/Invalidate this index */ - " daddiu %1, %1, -1 \n" /* Decrement loop count */ + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " daddiu %1, %1, -1 \n" /* Decrement loop count */ " bnez %1, 1b \n" /* loop test */ - " daddu $1, $1, %0 \n" /* Next address */ + " daddu $1, $1, %0 \n" /* Next address */ ".set pop \n" : - : "r" (dcache_line_size), "r" (dcache_sets * dcache_assoc), - "r" (KSEG0), "i" (Index_Writeback_Inv_D)); + : "r" (dcache_line_size), "r" (dcache_sets), + "i" (Index_Writeback_Inv_D)); +} +/* + * Writeback and invalidate a range of the dcache. The addresses are + * virtual, and since we're using index ops and bit 12 is part of both + * the virtual frame and physical index, we have to clear both sets + * (bit 12 set and cleared). + */ +static inline void __sb1_writeback_inv_dcache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " xori $1, $1, 1<<12 \n" + " cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. With physical + * addresseses, we don't have to worry about possible bit 12 aliasing. + * XXXKW is it worth turning on KX and using hit ops with xkphys? + */ +static inline void __sb1_writeback_inv_dcache_phys_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + + +/* + * Invalidate the entire icache + */ +static inline void __sb1_flush_icache_all(void) +{ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " daddiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " daddu $1, $1, %0 \n" /* Next address */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (icache_line_size), "r" (icache_sets), + "i" (Index_Invalidate_I)); +} + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr) +{ + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; #endif - ".set pop \n"); + + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + + /* + * Bumping the ASID is probably cheaper than the flush ... + */ + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); +} + +#ifdef CONFIG_SMP +struct flush_cache_page_args { + struct vm_area_struct *vma; + unsigned long addr; +}; + +static void sb1_flush_cache_page_ipi(void *info) +{ + struct flush_cache_page_args *args = info; + + local_sb1_flush_cache_page(args->vma, args->addr); } -static inline void local_sb1___flush_icache_all(void) +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +{ + struct flush_cache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.addr = addr; + smp_call_function(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_cache_page(vma, addr); +} +#else +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +asm("sb1_flush_cache_page = local_sb1_flush_cache_page"); +#endif + +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) { __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " daddiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " daddu $1, $1, %0 \n" /* Next address */ + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" ".set pop \n" : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); + : "r" (start & ~(icache_line_size - 1)), + "r" ((end + icache_line_size - 1) & ~(icache_line_size - 1)), + "r" (icache_line_size), + "r" (icache_index_mask), + "i" (Index_Invalidate_I)); } + +/* + * Invalidate all caches on this CPU + */ static void local_sb1___flush_cache_all(void) { - local_sb1___flush_dcache_all(); - local_sb1___flush_icache_all(); + __sb1_writeback_inv_dcache_all(); + __sb1_flush_icache_all(); } #ifdef CONFIG_SMP @@ -131,81 +299,28 @@ asm("sb1___flush_cache_all = local_sb1___flush_cache_all"); #endif - /* * When flushing a range in the icache, we have to first writeback * the dcache for the same range, so new ifetches will see any * data that was dirty in the dcache. * - * The start/end arguments are expected to be Kseg addresses. + * The start/end arguments are Kseg addresses (possibly mapped Kseg). */ static void local_sb1_flush_icache_range(unsigned long start, unsigned long end) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - unsigned long flags; - local_irq_save(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - "1: \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - ".align 3 \n" - " lw $0, 0($1) \n" /* Bug 1370, 1368 */ - " sync \n" -#endif - " cache %3, 0($1) \n" /* Hit-WB{,-inval} this address */ - " bne $1, %1, 1b \n" /* loop test */ - " daddu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" ((start + dcache_line_size - 1) & ~(dcache_line_size - 1)), - "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), - "r" (dcache_line_size), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) -#else - "i" (Hit_Writeback_D) -#endif - ); - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" -#endif - ".set pop \n"); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - ".align 3 \n" - "1: cache %3, (0<<13)($1) \n" /* Index-inval this address */ - " cache %3, (1<<13)($1) \n" /* Index-inval this address */ - " cache %3, (2<<13)($1) \n" /* Index-inval this address */ - " cache %3, (3<<13)($1) \n" /* Index-inval this address */ - " bne $1, %1, 1b \n" /* loop test */ - " daddu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" (start & ~(icache_line_size - 1)), - "r" ((end - 1) & ~(icache_line_size - 1)), - "r" (icache_line_size), - "i" (Index_Invalidate_I)); + /* Just wb-inv the whole dcache if the range is big enough */ + if ((end - start) > dcache_range_cutoff) + __sb1_writeback_inv_dcache_all(); + else + __sb1_writeback_inv_dcache_range(start, end); + + /* Just flush the whole icache if the range is big enough */ + if ((end - start) > icache_range_cutoff) + __sb1_flush_icache_all(); + else + __sb1_flush_icache_range(start, end); } #ifdef CONFIG_SMP @@ -236,127 +351,105 @@ #endif /* - * If there's no context yet, or the page isn't executable, no icache flush - * is needed - * - * This is broken. If there is no context yet we still have to writeback - * the d-cache to memory. + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. */ -static void sb1_flush_icache_page(struct vm_area_struct *vma, +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) { - if (!(vma->vm_flags & VM_EXEC)) { + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) return; - } +#endif + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); /* - * We're not sure of the virtual address(es) involved here, so - * conservatively flush the entire caches on all processors - * (ouch). - * - * Bumping the ASID may well be cheaper, need to experiment ... + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) */ - sb1___flush_cache_all(); + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } } -static inline void protected_flush_icache_line(unsigned long addr) +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) { - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - "1: cache %1, (%0) \n" - "2: .set pop \n" - " .section __ex_table,\"a\"\n" - " .dword 1b, 2b \n" - " .previous" - : - : "r" (addr), "i" (Hit_Invalidate_I)); + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); } -static inline void protected_writeback_dcache_line(unsigned long addr) +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - /* Have to be sure the TLB entry exists for the cache op, - so we have to be sure that nothing happens in between the - lw and the cache op - */ - unsigned long flags; - local_irq_save(flags); -#endif - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - " \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "1: lw $0, (%0) \n" - " sync \n" - " .section __ex_table,\"a\"\n" - " .dword 1b, 3f \n" - " .previous \n" -#endif - "2: cache %1, 0(%0) \n" /* Hit-WB{-inval} this address */ - /* XXX: should be able to do this after both dcache cache - ops, but there's no guarantee that this will be inlined, - and the pass1 restriction checker can't detect syncs - following cache ops except in the following basic block. - */ - " sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - " sync \n" -#endif - "3: .set pop \n" - " .section __ex_table,\"a\"\n" - " .dword 2b, 3b \n" - " .previous" - : - : "r" (addr), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + smp_call_function(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_icache_page(vma, page); +} #else - "i" (Hit_Writeback_D) +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page); +asm("sb1_flush_icache_page = local_sb1_flush_icache_page"); #endif - ); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); -#endif -} /* * A signal trampoline must fit into a single cacheline. */ static void local_sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long daddr, iaddr; - - daddr = addr & ~(dcache_line_size - 1); - protected_writeback_dcache_line(daddr); - iaddr = addr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " cache %2, (0<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (1<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (2<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (3<<13)(%0) \n" /* Index-inval this address */ + " xori $1, %0, 1<<12 \n" /* Flip index bit 12 */ + " cache %2, (0<<13)($1) \n" /* Index-inval this address */ + " cache %2, (1<<13)($1) \n" /* Index-inval this address */ + " cache %2, (2<<13)($1) \n" /* Index-inval this address */ + " cache %2, (3<<13)($1) \n" /* Index-inval this address */ + " cache %3, (0<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (1<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (2<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (3<<13)(%1) \n" /* Index-inval this address */ + " bnezl $0, 1f \n" /* Force mispredict */ + " nop \n" + "1: \n" + " .set pop \n" + : + : "r" (addr & dcache_index_mask), "r" (addr & icache_index_mask), + "i" (Index_Writeback_Inv_D), "i" (Index_Invalidate_I)); } #ifdef CONFIG_SMP static void sb1_flush_cache_sigtramp_ipi(void *info) { unsigned long iaddr = (unsigned long) info; - - iaddr = iaddr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + local_sb1_flush_cache_sigtramp(iaddr); } static void sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long tmp; - - /* - * Flush the local dcache, then load the instruction back into a - * register. That will make sure that any remote CPU also has - * written back it's data cache to memory. - */ local_sb1_flush_cache_sigtramp(addr); - __get_user(tmp, (unsigned long *)addr); - smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); } #else @@ -364,64 +457,17 @@ asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp"); #endif -static void sb1_flush_icache_all(void) -{ - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " daddiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " daddu $1, $1, %0 \n" /* Next address */ - ".set pop \n" - : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); -} /* * Anything that just flushes dcache state can be ignored, as we're always * coherent in dcache space. This is just a dummy function that all the * nop'ed routines point to */ - static void sb1_nop(void) { } /* - * This only needs to make sure stores done up to this - * point are visible to other agents outside the CPU. Given - * the coherent nature of the ZBbus, all that's required here is - * a sync to make sure the data gets out to the caches and is - * visible to an arbitrary A Phase from an external agent - * - * Actually, I'm not even sure that's necessary; the semantics - * of this function aren't clear. If it's supposed to serve as - * a memory barrier, this is needed. If it's only meant to - * prevent data from being invisible to non-cpu memory accessors - * for some indefinite period of time (e.g. in a non-coherent - * dcache) then this function would be a complete nop. - */ -static void sb1_flush_page_to_ram(struct page *page) -{ - __asm__ __volatile__( - " sync \n" /* Short pipe */ - :::"memory"); -} - -/* * Cache set values (from the mips64 spec) * 0 - 64 * 1 - 128 @@ -480,7 +526,7 @@ { u32 config1; - config1 = read_mips32_cp0_config1(); + config1 = read_c0_config1(); icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7); dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7); icache_sets = decode_cache_sets((config1 >> 22) & 0x7); @@ -489,7 +535,17 @@ dcache_assoc = ((config1 >> 7) & 0x7) + 1; icache_size = icache_line_size * icache_sets * icache_assoc; dcache_size = dcache_line_size * dcache_sets * dcache_assoc; + /* Need to remove non-index bits for index ops */ icache_index_mask = (icache_sets - 1) * icache_line_size; + dcache_index_mask = (dcache_sets - 1) * dcache_line_size; + /* + * These are for choosing range (index ops) versus all. + * icache flushes all ways for each set, so drop icache_assoc. + * dcache flushes all ways and each setting of bit 12 for each + * index, so drop dcache_assoc and halve the dcache_sets. + */ + icache_range_cutoff = icache_sets * icache_line_size; + dcache_range_cutoff = (dcache_sets / 2) * icache_line_size; } /* @@ -499,25 +555,56 @@ */ void ld_mmu_sb1(void) { + extern char except_vec2_sb1; + unsigned long temp; + + /* Special cache error handler for SB1 */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + probe_cache_sizes(); +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + _clear_page = sb1_clear_page_dma; + _copy_page = sb1_copy_page_dma; + sb1_dma_init(); +#else _clear_page = sb1_clear_page; _copy_page = sb1_copy_page; +#endif - _flush_cache_all = sb1_flush_cache_all; - ___flush_cache_all = sb1___flush_cache_all; - _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + /* + * None of these are needed for the SB1 - the Dcache is + * physically indexed and tagged, so no virtual aliasing can + * occur + */ _flush_cache_range = (void *) sb1_nop; - _flush_page_to_ram = sb1_flush_page_to_ram; - _flush_icache_page = sb1_flush_icache_page; - _flush_icache_range = sb1_flush_icache_range; - - /* None of these are needed for the sb1 */ - _flush_cache_page = (void *) sb1_nop; + _flush_cache_page = sb1_flush_cache_page; + _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + _flush_cache_all = sb1_nop; + /* These routines are for Icache coherence with the Dcache */ + _flush_icache_range = sb1_flush_icache_range; + _flush_icache_page = sb1_flush_icache_page; + _flush_icache_all = __sb1_flush_icache_all; /* local only */ _flush_cache_sigtramp = sb1_flush_cache_sigtramp; - _flush_icache_all = sb1_flush_icache_all; + _flush_data_cache_page = (void *) sb1_nop; - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* Full flushes */ + ___flush_cache_all = sb1___flush_cache_all; + + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* + * This is the only way to force the update of K0 to complete + * before subsequent instruction fetch. + */ + __asm__ __volatile__ ( + " .set push \n" + " .set mips4 \n" + " dla %0, 1f \n" + " dmtc0 %0, $14 \n" + " eret \n" + "1: .set pop \n" + : "=r" (temp)); flush_cache_all(); } diff -urN linux-2.4.21/arch/mips64/mm/cache.c linux-2.4.22/arch/mips64/mm/cache.c --- linux-2.4.21/arch/mips64/mm/cache.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/cache.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,60 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 2003 by Ralf Baechle + */ +#include +#include +#include +#include + +#include + +asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) +{ + /* This should flush more selectivly ... */ + __flush_cache_all(); + + return 0; +} + +void flush_dcache_page(struct page *page) +{ + unsigned long addr; + + if (page->mapping && page->mapping->i_mmap == NULL && + page->mapping->i_mmap_shared == NULL) { + SetPageDcacheDirty(page); + + return; + } + + /* + * We could delay the flush for the !page->mapping case too. But that + * case is for exec env/arg pages and those are %99 certainly going to + * get faulted into the tlb (and thus flushed) anyways. + */ + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); +} + +void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + struct page *page = pte_page(pte); + unsigned long addr; + + if (VALID_PAGE(page) && page->mapping && + (page->flags & (1UL << PG_dcache_dirty))) { + if (pages_do_alias((unsigned long) page_address(page), address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); + } + + ClearPageDcacheDirty(page); + } +} + +EXPORT_SYMBOL(flush_dcache_page); diff -urN linux-2.4.21/arch/mips64/mm/cerr-sb1.c linux-2.4.22/arch/mips64/mm/cerr-sb1.c --- linux-2.4.21/arch/mips64/mm/cerr-sb1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/cerr-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#ifndef CONFIG_SIBYTE_BUS_WATCHER +#include +#include +#include +#include +#endif + +/* SB1 definitions */ + +/* XXX should come from config1 XXX */ +#define SB1_CACHE_INDEX_MASK 0x1fe0 + +#define CP0_ERRCTL_RECOVERABLE (1 << 31) +#define CP0_ERRCTL_DCACHE (1 << 30) +#define CP0_ERRCTL_ICACHE (1 << 29) +#define CP0_ERRCTL_MULTIBUS (1 << 23) +#define CP0_ERRCTL_MC_TLB (1 << 15) +#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) + +#define CP0_CERRI_TAG_PARITY (1 << 29) +#define CP0_CERRI_DATA_PARITY (1 << 28) +#define CP0_CERRI_EXTERNAL (1 << 26) + +#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) +#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) + +#define CP0_CERRD_MULTIPLE (1 << 31) +#define CP0_CERRD_TAG_STATE (1 << 30) +#define CP0_CERRD_TAG_ADDRESS (1 << 29) +#define CP0_CERRD_DATA_SBE (1 << 28) +#define CP0_CERRD_DATA_DBE (1 << 27) +#define CP0_CERRD_EXTERNAL (1 << 26) +#define CP0_CERRD_LOAD (1 << 25) +#define CP0_CERRD_STORE (1 << 24) +#define CP0_CERRD_FILLWB (1 << 23) +#define CP0_CERRD_COHERENCY (1 << 22) +#define CP0_CERRD_DUPTAG (1 << 21) + +#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) +#define CP0_CERRD_IDX_VALID(c) \ + (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) +#define CP0_CERRD_CAUSES \ + (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) +#define CP0_CERRD_TYPES \ + (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) +#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) + +static uint32_t extract_ic(unsigned short addr, int data); +static uint32_t extract_dc(unsigned short addr, int data); + +static inline void breakout_errctl(unsigned int val) +{ + if (val & CP0_ERRCTL_RECOVERABLE) + prom_printf(" recoverable"); + if (val & CP0_ERRCTL_DCACHE) + prom_printf(" dcache"); + if (val & CP0_ERRCTL_ICACHE) + prom_printf(" icache"); + if (val & CP0_ERRCTL_MULTIBUS) + prom_printf(" multiple-buserr"); + prom_printf("\n"); +} + +static inline void breakout_cerri(unsigned int val) +{ + if (val & CP0_CERRI_TAG_PARITY) + prom_printf(" tag-parity"); + if (val & CP0_CERRI_DATA_PARITY) + prom_printf(" data-parity"); + if (val & CP0_CERRI_EXTERNAL) + prom_printf(" external"); + prom_printf("\n"); +} + +static inline void breakout_cerrd(unsigned int val) +{ + switch (val & CP0_CERRD_CAUSES) { + case CP0_CERRD_LOAD: + prom_printf(" load,"); + break; + case CP0_CERRD_STORE: + prom_printf(" store,"); + break; + case CP0_CERRD_FILLWB: + prom_printf(" fill/wb,"); + break; + case CP0_CERRD_COHERENCY: + prom_printf(" coherency,"); + break; + case CP0_CERRD_DUPTAG: + prom_printf(" duptags,"); + break; + default: + prom_printf(" NO CAUSE,"); + break; + } + if (!(val & CP0_CERRD_TYPES)) + prom_printf(" NO TYPE"); + else { + if (val & CP0_CERRD_MULTIPLE) + prom_printf(" multi-err"); + if (val & CP0_CERRD_TAG_STATE) + prom_printf(" tag-state"); + if (val & CP0_CERRD_TAG_ADDRESS) + prom_printf(" tag-address"); + if (val & CP0_CERRD_DATA_SBE) + prom_printf(" data-SBE"); + if (val & CP0_CERRD_DATA_DBE) + prom_printf(" data-DBE"); + if (val & CP0_CERRD_EXTERNAL) + prom_printf(" external"); + } + prom_printf("\n"); +} + +#ifndef CONFIG_SIBYTE_BUS_WATCHER + +static void check_bus_watcher(void) +{ + uint32_t status, l2_err, memio_err; + + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + /* Bit 31 is always on, but there's no #define for that */ + if (status & ~(1UL << 31)) { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + prom_printf("\nLast recorded signature:\n"); + prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); + } else { + prom_printf("Bus watcher indicates no error\n"); + } +} +#else +extern void check_bus_watcher(void); +#endif + +asmlinkage void sb1_cache_error(void) +{ + uint64_t cerr_dpa; + uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; + + prom_printf("Cache error exception on CPU %x:\n", + (read_c0_prid() >> 25) & 0x7); + + __asm__ __volatile__ ( + " .set push\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " mfc0 %0, $26\n\t" + " mfc0 %1, $27\n\t" + " mfc0 %2, $27, 1\n\t" + " dmfc0 $1, $27, 3\n\t" + " dsrl32 %3, $1, 0 \n\t" + " sll %4, $1, 0 \n\t" + " mfc0 %5, $30\n\t" + " .set pop" + : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), + "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); + + cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; + prom_printf(" c0_errorepc == %08x\n", eepc); + prom_printf(" c0_errctl == %08x", errctl); + breakout_errctl(errctl); + if (errctl & CP0_ERRCTL_ICACHE) { + prom_printf(" c0_cerr_i == %08x", cerr_i); + breakout_cerri(cerr_i); + if (CP0_CERRI_IDX_VALID(cerr_i)) { + if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_i idx doesn't match eepc\n"); + else { + res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, + (cerr_i & CP0_CERRI_DATA) != 0); + if (!(res & cerr_i)) + prom_printf("...didn't see indicated icache problem\n"); + } + } + } + if (errctl & CP0_ERRCTL_DCACHE) { + prom_printf(" c0_cerr_d == %08x", cerr_d); + breakout_cerrd(cerr_d); + if (CP0_CERRD_DPA_VALID(cerr_d)) { + prom_printf(" c0_cerr_dpa == %010llx\n", cerr_dpa); + if (!CP0_CERRD_IDX_VALID(cerr_d)) { + res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated dcache problem\n"); + } else { + if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); + else { + res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated problem\n"); + } + } + } + } + + check_bus_watcher(); + + while (1); + /* + * This tends to make things get really ugly; let's just stall instead. + * panic("Can't handle the cache error!"); + */ +} + + +/* Parity lookup table. */ +static const uint8_t parity[256] = { + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 +}; + +/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ +static const uint64_t mask_72_64[8] = { + 0x0738C808099264FFL, + 0x38C808099264FF07L, + 0xC808099264FF0738L, + 0x08099264FF0738C8L, + 0x099264FF0738C808L, + 0x9264FF0738C80809L, + 0x64FF0738C8080992L, + 0xFF0738C808099264L +}; + +/* Calculate the parity on a range of bits */ +static char range_parity(uint64_t dword, int max, int min) +{ + char parity = 0; + int i; + dword >>= min; + for (i=max-min; i>=0; i--) { + if (dword & 0x1) + parity = !parity; + dword >>= 1; + } + return parity; +} + +/* Calculate the 4-bit even byte-parity for an instruction */ +static unsigned char inst_parity(uint32_t word) +{ + int i, j; + char parity = 0; + for (j=0; j<4; j++) { + char byte_parity = 0; + for (i=0; i<8; i++) { + if (word & 0x80000000) + byte_parity = !byte_parity; + word <<= 1; + } + parity <<= 1; + parity |= byte_parity; + } + return parity; +} + +static uint32_t extract_ic(unsigned short addr, int data) +{ + unsigned short way; + int valid; + uint64_t taglo, va, tlo_tmp; + uint32_t taghi, taglolo, taglohi; + uint8_t lru; + int res = 0; + + prom_printf("Icache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + /* Index-load-tag-I */ + __asm__ __volatile__ ( + " .set push \n\t" + " .set noreorder \n\t" + " .set mips64 \n\t" + " .set noat \n\t" + " cache 4, 0(%3) \n\t" + " mfc0 %0, $29 \n\t" + " dmfc0 $1, $28 \n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 5) & 0x3), /* bank */ + ((addr >> 7) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + va = (taglo & 0xC0000FFFFFFFE000) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) + va |= 0x3FFFF00000000000; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; + if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { + prom_printf(" ** bad parity in VTag0/G/ASID\n"); + res |= CP0_CERRI_TAG_PARITY; + } + if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { + prom_printf(" ** bad parity in R/VTag1\n"); + res |= CP0_CERRI_TAG_PARITY; + } + } + if (valid ^ ((taghi >> 27) & 1)) { + prom_printf(" ** bad parity for valid bit\n"); + res |= CP0_CERRI_TAG_PARITY; + } + prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", + way, va, valid, taghi, taglo); + + if (data) { + uint32_t datahi, insta, instb; + uint8_t predecode; + int offset; + + /* (hit all banks and ways) */ + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-I */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 6, 0(%3) \n\t" + " mfc0 %0, $29, 1\n\t" + " dmfc0 $1, $28, 1\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop \n" + : "=r" (datahi), "=r" (insta), "=r" (instb) + : "r" ((way << 13) | addr | (offset << 3))); + predecode = (datahi >> 8) & 0xff; + if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { + prom_printf(" ** bad parity in predecode\n"); + res |= CP0_CERRI_DATA_PARITY; + } + /* XXXKW should/could check predecode bits themselves */ + if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { + prom_printf(" ** bad parity in instruction a\n"); + res |= CP0_CERRI_DATA_PARITY; + } + if ((datahi & 0xf) ^ inst_parity(instb)) { + prom_printf(" ** bad parity in instruction b\n"); + res |= CP0_CERRI_DATA_PARITY; + } + prom_printf(" %05X-%08X%08X", datahi, insta, instb); + } + prom_printf("\n"); + } + } + return res; +} + +/* Compute the ECC for a data doubleword */ +static uint8_t dc_ecc(uint64_t dword) +{ + uint64_t t; + uint32_t w; + uint8_t p; + int i; + + p = 0; + for (i = 7; i >= 0; i--) + { + p <<= 1; + t = dword & mask_72_64[i]; + w = (uint32_t)(t >> 32); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + w = (uint32_t)(t & 0xFFFFFFFF); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + } + return p; +} + +struct dc_state { + unsigned char val; + char *name; +}; + +static struct dc_state dc_states[] = { + { 0x00, "INVALID" }, + { 0x0f, "COH-SHD" }, + { 0x13, "NCO-E-C" }, + { 0x19, "NCO-E-D" }, + { 0x16, "COH-E-C" }, + { 0x1c, "COH-E-D" }, + { 0xff, "*ERROR*" } +}; + +#define DC_TAG_VALID(state) \ + (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) + +static char *dc_state_str(unsigned char state) +{ + struct dc_state *dsc = dc_states; + while (dsc->val != 0xff) { + if (dsc->val == state) + break; + dsc++; + } + return dsc->name; +} + +static uint32_t extract_dc(unsigned short addr, int data) +{ + int valid, way; + unsigned char state; + uint64_t taglo, pa; + uint32_t taghi, taglolo, taglohi; + uint8_t ecc, lru; + int res = 0; + + prom_printf("Dcache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 5, 0(%3)\n\t" /* Index-load-tag-D */ + " mfc0 %0, $29, 2\n\t" + " dmfc0 $1, $28, 2\n\t" + " dsrl32 %1, $1, 0\n\t" + " sll %2, $1, 0\n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + pa = (taglo & 0xFFFFFFE000) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ + ((addr >> 6) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + state = (taghi >> 25) & 0x1f; + valid = DC_TAG_VALID(state); + prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", + way, pa, dc_state_str(state), state, taghi, taglo); + if (valid) { + if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { + prom_printf(" ** bad parity in PTag1\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { + prom_printf(" ** bad parity in PTag0\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + } else { + res |= CP0_CERRD_TAG_STATE; + } + + if (data) { + uint64_t datalo; + uint32_t datalohi, datalolo, datahi; + int offset; + + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-D */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 7, 0(%3)\n\t" /* Index-load-data-D */ + " mfc0 %0, $29, 3\n\t" + " dmfc0 $1, $28, 3\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (datahi), "=r" (datalohi), "=r" (datalolo) + : "r" ((way << 13) | addr | (offset << 3))); + datalo = ((unsigned long long)datalohi << 32) | datalolo; + ecc = dc_ecc(datalo); + if (ecc != datahi) { + int bits = 0; + prom_printf(" ** bad ECC (%02x %02x) ->", + datahi, ecc); + ecc ^= datahi; + while (ecc) { + if (ecc & 1) bits++; + ecc >>= 1; + } + res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; + } + prom_printf(" %02X-%016llX", datahi, datalo); + } + prom_printf("\n"); + } + } + return res; +} diff -urN linux-2.4.21/arch/mips64/mm/cex-sb1.S linux-2.4.22/arch/mips64/mm/cex-sb1.S --- linux-2.4.21/arch/mips64/mm/cex-sb1.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/cex-sb1.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include + +#include +#include +#include +#include +#include + + .text + .set noat + .set mips4 + + __INIT + + /* Cache Error handler for SB1 */ + LEAF(except_vec2_sb1) + mfc0 k1, $26 + # check if error was recoverable + bltz k1, leave_cerr +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + # look for signature of spurious CErr + lui k0, 0x4000 + bne k0, k1, 1f + .word 0x401Bd801 # mfc0 k1, $27, 1 + lui k0, 0xffe0 + and k1, k0, k1 + lui k0, 0x0200 + beq k0, k1, leave_cerr +1: +#endif + j handle_vec2_sb1 + +leave_cerr: + # clear/unlock the registers + mtc0 zero, $26 + mtc0 zero, $27 + .word 0x4080d801 # mtc0 zero, $27, 1 + .word 0x4080d803 # mtc0 zero, $27, 3 + eret + END(except_vec2_sb1) + + __FINIT + + LEAF(handle_vec2_sb1) + mfc0 k0,CP0_CONFIG + li k1,~CONF_CM_CMASK + and k0,k0,k1 + ori k0,k0,CONF_CM_UNCACHED + mtc0 k0,CP0_CONFIG + + SSNOP + SSNOP + SSNOP + SSNOP + bnezl $0, 1f +1: + mfc0 k0, CP0_STATUS + sll k0, k0, 3 # check CU0 (kernel?) + bltz k0, 2f + get_saved_sp + move sp, k1 # want Kseg SP (so uncached) +2: + j sb1_cache_error + + END(handle_vec2_sb1) diff -urN linux-2.4.21/arch/mips64/mm/fault.c linux-2.4.22/arch/mips64/mm/fault.c --- linux-2.4.21/arch/mips64/mm/fault.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 @@ -194,7 +194,6 @@ address, (unsigned long) regs->cp0_epc, (unsigned long) regs->regs[31]); -while(1); #endif info.si_signo = SIGSEGV; info.si_errno = 0; diff -urN linux-2.4.21/arch/mips64/mm/init.c linux-2.4.22/arch/mips64/mm/init.c --- linux-2.4.21/arch/mips64/mm/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -110,14 +110,6 @@ return freed; } - -asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) -{ - /* XXX Just get it working for now... */ - flush_cache_l1(); - return 0; -} - /* * We have up to 8 empty zeroed pages so we can map one of the right colour * when needed. This is necessary only on R4000 / R4400 SC and MC versions @@ -132,16 +124,10 @@ unsigned long order, size; struct page *page; - switch (mips_cpu.cputype) { - case CPU_R4000SC: - case CPU_R4000MC: - case CPU_R4400SC: - case CPU_R4400MC: + if (cpu_has_vce) order = 3; - break; - default: + else order = 0; - } empty_zero_page = __get_free_pages(GFP_KERNEL, order); if (!empty_zero_page) @@ -297,19 +283,24 @@ #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { + /* Switch from KSEG0 to XKPHYS addresses */ + start = (unsigned long)phys_to_virt(CPHYSADDR(start)); + end = (unsigned long)phys_to_virt(CPHYSADDR(end)); + if (start < end) + 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); free_page(start); totalram_pages++; } - printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", - (end - start) >> 10); } #endif extern char __init_begin, __init_end; -extern void prom_free_prom_memory(void); +extern void prom_free_prom_memory(void) __init; void free_initmem(void) diff -urN linux-2.4.21/arch/mips64/mm/loadmmu.c linux-2.4.22/arch/mips64/mm/loadmmu.c --- linux-2.4.21/arch/mips64/mm/loadmmu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/loadmmu.c 2003-08-25 04:44:40.000000000 -0700 @@ -4,20 +4,23 @@ * for more details. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ #include #include #include #include #include +#include +#include +#include #include #include #include -#include -#include /* memory functions */ void (*_clear_page)(void * page); @@ -28,62 +31,79 @@ void (*___flush_cache_all)(void); void (*_flush_cache_mm)(struct mm_struct *mm); void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start, - unsigned long end); + unsigned long end); void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -void (*_flush_cache_sigtramp)(unsigned long addr); void (*_flush_icache_range)(unsigned long start, unsigned long end); void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page); -void (*_flush_page_to_ram)(struct page * page); -void (*_flush_icache_all)(void); -/* MIPS specific cache operations */ -void (*_flush_cache_l2)(void); -void (*_flush_cache_l1)(void); +void (*_flush_cache_sigtramp)(unsigned long addr); +void (*_flush_data_cache_page)(unsigned long addr); +void (*_flush_icache_all)(void); +#ifdef CONFIG_NONCOHERENT_IO /* DMA cache operations. */ void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); void (*_dma_cache_wback)(unsigned long start, unsigned long size); void (*_dma_cache_inv)(unsigned long start, unsigned long size); -/* Miscellaneous. */ -void (*_update_mmu_cache)(struct vm_area_struct * vma, - unsigned long address, pte_t pte); +EXPORT_SYMBOL(_dma_cache_wback_inv); +EXPORT_SYMBOL(_dma_cache_wback); +EXPORT_SYMBOL(_dma_cache_inv); + +#endif /* CONFIG_NONCOHERENT_IO */ +extern void ld_mmu_r23000(void); extern void ld_mmu_r4xx0(void); +extern void ld_mmu_tx39(void); +extern void ld_mmu_r6000(void); +extern void ld_mmu_tfp(void); extern void ld_mmu_andes(void); extern void ld_mmu_sb1(void); extern void sb1_tlb_init(void); -extern void ld_mmu_mips64(void); +extern void r3k_tlb_init(void); extern void r4k_tlb_init(void); +extern void sb1_tlb_init(void); void __init load_mmu(void) { - if (mips_cpu.options & MIPS_CPU_4KTLB) { -#if defined (CONFIG_CPU_R4300) \ - || defined (CONFIG_CPU_R4X00) \ - || defined (CONFIG_CPU_R5000) \ - || defined (CONFIG_CPU_NEVADA) - printk(KERN_INFO "Loading R4000 MMU routines.\n"); + if (cpu_has_4ktlb) { +#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ + defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ + defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ + defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ + defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ + defined(CONFIG_CPU_RM7000) ld_mmu_r4xx0(); -#endif -#if defined(CONFIG_CPU_MIPS64) - printk(KERN_INFO "Loading MIPS64 MMU routines.\n"); - ld_mmu_mips64(); r4k_tlb_init(); #endif - - } else switch(mips_cpu.cputype) { + } else switch (current_cpu_data.cputype) { +#ifdef CONFIG_CPU_R3000 + case CPU_R2000: + case CPU_R3000: + case CPU_R3000A: + case CPU_R3081E: + ld_mmu_r23000(); + r3k_tlb_init(); + break; +#endif +#ifdef CONFIG_CPU_TX39XX + case CPU_TX3912: + case CPU_TX3922: + case CPU_TX3927: + ld_mmu_tx39(); + r3k_tlb_init(); + break; +#endif #ifdef CONFIG_CPU_R10000 case CPU_R10000: case CPU_R12000: - printk(KERN_INFO "Loading R10000 MMU routines.\n"); - ld_mmu_andes(); + ld_mmu_r4xx0(); + andes_tlb_init(); break; #endif -#if defined CONFIG_CPU_SB1 +#ifdef CONFIG_CPU_SB1 case CPU_SB1: - printk(KERN_INFO "Loading SB1 MMU routines.\n"); ld_mmu_sb1(); sb1_tlb_init(); break; @@ -94,13 +114,6 @@ break; default: - /* XXX We need an generic routine in the MIPS port - * XXX to jabber stuff onto the screen on all machines - * XXX before the console is setup. The ARCS prom - * XXX routines look good for this, but only the SGI - * XXX code has a full library for that at this time. - */ - panic("Yeee, unsupported mmu/cache architecture or " - "wrong compiletime kernel configuration."); + panic("Yeee, unsupported mmu/cache architecture."); } } diff -urN linux-2.4.21/arch/mips64/mm/pg-mips64.c linux-2.4.22/arch/mips64/mm/pg-mips64.c --- linux-2.4.21/arch/mips64/mm/pg-mips64.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/pg-mips64.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,126 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute 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 it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You 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. - * - * MIPS64 CPU variant specific Cache routines. - * These routine are not optimized in any way, they are done in a generic way - * so they can be used on all MIPS64 compliant CPUs, and also done in an - * attempt not to break anything for the R4xx0 style CPUs. - */ -#include -#include - -#include -#include -#include - -extern int dc_lsize, ic_lsize, sc_lsize; - -/* - * Zero an entire page. - */ - -void mips64_clear_page_dc(unsigned long page) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) - { - for (i=page; i +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Zero an entire page. Basically a simple unrolled loop should do the + * job but we want more performance by saving memory bus bandwidth. We + * have five flavours of the routine available for: + * + * - 16byte cachelines and no second level cache + * - 32byte cachelines second level cache + * - a version which handles the buggy R4600 v1.x + * - a version which handles the buggy R4600 v2.0 + * - Finally a last version without fancy cache games for the SC and MC + * versions of R4000 and R4400. + */ + +void r4k_clear_page_d16(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "cache\t%3,16(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "cache\t%3,-16(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + +void r4k_clear_page_d32(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + + +/* + * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the + * IDT R4600 V1.7 errata: + * + * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be + * executed if there is no other dcache activity. If the dcache is + * accessed for another instruction immeidately preceding when these + * cache instructions are executing, it is possible that the dcache + * tag match outputs used by these cache instructions will be + * incorrect. These cache instructions should be preceded by at least + * four instructions that are not any kind of load or store + * instruction. + * + * This is not allowed: lw + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * This is allowed: lw + * nop + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + */ +void r4k_clear_page_r4600_v1(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + +/* + * And this one is for the R4600 V2.0 + */ +void r4k_clear_page_r4600_v2(void * page) +{ + unsigned long flags; + + local_irq_save(flags); + *(volatile unsigned int *)KSEG1; + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); + local_irq_restore(flags); +} + +/* + * The next 4 versions are optimized for all possible scache configurations + * of the SC / MC versions of R4000 and R4400 ... + * + * Todo: For even better performance we should have a routine optimized for + * every legal combination of dcache / scache linesize. When I (Ralf) tried + * this the kernel crashed shortly after mounting the root filesystem. CPU + * bug? Weirdo cache instruction semantics? + */ +void r4k_clear_page_s16(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "cache\t%3,16(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "cache\t%3,-16(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s32(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s64(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s128(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "sd\t$0,32(%0)\n\t" + "sd\t$0,40(%0)\n\t" + "sd\t$0,48(%0)\n\t" + "sd\t$0,56(%0)\n\t" + "daddiu\t%0,128\n\t" + "sd\t$0,-64(%0)\n\t" + "sd\t$0,-56(%0)\n\t" + "sd\t$0,-48(%0)\n\t" + "sd\t$0,-40(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +/* + * This version has been tuned on an Origin. For other machines the arguments + * of the pref instructin may have to be tuned differently. + */ +void andes_clear_page(void * page) +{ + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tmips4\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tpref 7,512(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tpop" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE) + : "memory"); +} + + +/* + * This is still inefficient. We only can do better if we know the + * virtual address where the copy will be accessed. + */ + +void r4k_copy_page_d16(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "cache\t%7,16(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "cache\t%7,-16(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +void r4k_copy_page_d32(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +/* + * Again a special version for the R4600 V1.x + */ +void r4k_copy_page_r4600_v1(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +void r4k_copy_page_r4600_v2(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + unsigned long flags; + + local_irq_save(flags); + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); + local_irq_restore(flags); +} + +/* + * These are for R4000SC / R4400MC + */ +void r4k_copy_page_s16(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "cache\t%7,16(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "cache\t%7,-16(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s32(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s64(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s128(void * to, void * from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tcache\t%9,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "ld\t%4,16(%1)\n\t" + "ld\t%5,24(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "sd\t%4,16(%0)\n\t" + "sd\t%5,24(%0)\n\t" + "ld\t%2,32(%1)\n\t" + "ld\t%3,40(%1)\n\t" + "ld\t%4,48(%1)\n\t" + "ld\t%5,56(%1)\n\t" + "sd\t%2,32(%0)\n\t" + "sd\t%3,40(%0)\n\t" + "sd\t%4,48(%0)\n\t" + "sd\t%5,56(%0)\n\t" + "daddiu\t%0,128\n\t" + "daddiu\t%1,128\n\t" + "ld\t%2,-64(%1)\n\t" + "ld\t%3,-56(%1)\n\t" + "ld\t%4,-48(%1)\n\t" + "ld\t%5,-40(%1)\n\t" + "sd\t%2,-64(%0)\n\t" + "sd\t%3,-56(%0)\n\t" + "sd\t%4,-48(%0)\n\t" + "sd\t%5,-40(%0)\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "ld\t%4,-16(%1)\n\t" + "ld\t%5,-8(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "sd\t%4,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%5,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +/* + * This version has been tuned on an Origin. For other machines the arguments + * of the pref instructin may have to be tuned differently. + */ +void andes_copy_page(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tmips4\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tpref\t0,2*128(%1)\n\t" + "pref\t1,2*128(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "ld\t%4,16(%1)\n\t" + "ld\t%5,24(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "sd\t%4,16(%0)\n\t" + "sd\t%5,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "ld\t%4,-16(%1)\n\t" + "ld\t%5,-8(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "sd\t%4,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%5,-8(%0)\n\t" + ".set\tpop\n\t" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), + "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), "I" (PAGE_SIZE)); +} diff -urN linux-2.4.21/arch/mips64/mm/pg-sb1.c linux-2.4.22/arch/mips64/mm/pg-sb1.c --- linux-2.4.21/arch/mips64/mm/pg-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/pg-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,9 +1,10 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Sibyte + * Copyright (C) 2000 SiByte, Inc. * - * Written by Justin Carlson (carlson@sibyte.com) + * Written by Justin Carlson of SiByte, Inc. + * and Kip Walker of Broadcom Corp. * * * This program is free software; you can redistribute it and/or @@ -20,8 +21,16 @@ * 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 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS #define SB1_PREF_LOAD_STREAMED_HINT "0" @@ -49,15 +58,19 @@ ".set noat \n" ".set mips4 \n" " daddiu $1, %0, %2 \n" /* Calculate the end of the page to clear */ +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 4 lines */ " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%0) \n" +#endif "1: sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */ " sd $0, 8(%0) \n" " sd $0, 16(%0) \n" " sd $0, 24(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_STORE_STREAMED_HINT ",128(%0) \n" /* Prefetch 4 lines ahead */ +#endif " bne $1, %0, 1b \n" " daddiu %0, %0, 32\n" /* Next cacheline (This instruction better be short piped!) */ ".set pop \n" @@ -87,12 +100,14 @@ ".set noat \n" ".set mips4 \n" " daddiu $1, %0, %4 \n" /* Calculate the end of the page to copy */ +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_LOAD_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 3 lines */ " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%1) \n" " pref " SB1_PREF_LOAD_STREAMED_HINT ", 32(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%1) \n" " pref " SB1_PREF_LOAD_STREAMED_HINT ", 64(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%1) \n" +#endif "1: lw $2, 0(%0) \n" /* Block copy a cacheline */ " lw $3, 4(%0) \n" " lw $4, 8(%0) \n" @@ -101,8 +116,10 @@ " lw $7, 20(%0) \n" " lw $8, 24(%0) \n" " lw $9, 28(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_LOAD_STREAMED_HINT ", 96(%0) \n" /* Prefetch ahead */ " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%1) \n" +#endif " sw $2, 0(%1) \n" " sw $3, 4(%1) \n" " sw $4, 8(%1) \n" @@ -121,3 +138,78 @@ : "0" (from), "1" (to), "I" (PAGE_SIZE-32) : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); } + + +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + +/* + * Pad descriptors to cacheline, since each is exclusively owned by a + * particular CPU. + */ +typedef struct dmadscr_s { + uint64_t dscr_a; + uint64_t dscr_b; + uint64_t pad_a; + uint64_t pad_b; +} dmadscr_t; + +static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES))); + +void sb1_dma_init(void) +{ + int cpu = smp_processor_id(); + uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1); + + out64(base_val, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_RESET, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_ENABL, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +void sb1_clear_page_dma(void *page) +{ + int cpu = smp_processor_id(); + + /* if the page is above Kseg0, use old way */ + if (KSEGX(page) != K0BASE) + return sb1_clear_page(page); + + page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +void sb1_copy_page_dma(void *to, void *from) +{ + unsigned long from_phys = PHYSADDR(from); + unsigned long to_phys = PHYSADDR(to); + int cpu = smp_processor_id(); + + /* if either page is above Kseg0, use old way */ + if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE)) + return sb1_copy_page(to, from); + + page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +#endif diff -urN linux-2.4.21/arch/mips64/mm/r4xx0.c linux-2.4.22/arch/mips64/mm/r4xx0.c --- linux-2.4.21/arch/mips64/mm/r4xx0.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/r4xx0.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,2313 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -static unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include - -#undef DEBUG_CACHE - - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - -/* - * On processors with QED R4600 style two set assosicative cache - * this is the bit which selects the way in the cache for the - * indexed cachops. - */ -#define icache_waybit (icache_size >> 1) -#define dcache_waybit (dcache_size >> 1) - -/* - * Zero an entire page. Basically a simple unrolled loop should do the - * job but we want more performance by saving memory bus bandwidth. We - * have five flavours of the routine available for: - * - * - 16byte cachelines and no second level cache - * - 32byte cachelines second level cache - * - a version which handles the buggy R4600 v1.x - * - a version which handles the buggy R4600 v2.0 - * - Finally a last version without fancy cache games for the SC and MC - * versions of R4000 and R4400. - */ - -static void r4k_clear_page_d16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -static void r4k_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - - -/* - * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the - * IDT R4600 V1.7 errata: - * - * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Excl_D should only be - * executed if there is no other dcache activity. If the dcache is - * accessed for another instruction immeidately preceding when these - * cache instructions are executing, it is possible that the dcache - * tag match outputs used by these cache instructions will be - * incorrect. These cache instructions should be preceded by at least - * four instructions that are not any kind of load or store - * instruction. - * - * This is not allowed: lw - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - * - * This is allowed: lw - * nop - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - */ -static void r4k_clear_page_r4600_v1(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -/* - * And this one is for the R4600 V2.0 - */ -static void r4k_clear_page_r4600_v2(void * page) -{ - unsigned int flags; - - __save_and_cli(flags); - *(volatile unsigned int *)KSEG1; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); - __restore_flags(flags); -} - -/* - * The next 4 versions are optimized for all possible scache configurations - * of the SC / MC versions of R4000 and R4400 ... - * - * Todo: For even better performance we should have a routine optimized for - * every legal combination of dcache / scache linesize. When I (Ralf) tried - * this the kernel crashed shortly after mounting the root filesystem. CPU - * bug? Weirdo cache instruction semantics? - */ -static void r4k_clear_page_s16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -static void r4k_clear_page_s32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -static void r4k_clear_page_s64(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -static void r4k_clear_page_s128(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "sd\t$0,32(%0)\n\t" - "sd\t$0,40(%0)\n\t" - "sd\t$0,48(%0)\n\t" - "sd\t$0,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "sd\t$0,-64(%0)\n\t" - "sd\t$0,-56(%0)\n\t" - "sd\t$0,-48(%0)\n\t" - "sd\t$0,-40(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -static void r4k_copy_page_d16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -/* - * Again a special version for the R4600 V1.x - */ -static void r4k_copy_page_r4600_v1(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_r4600_v2(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - unsigned int flags; - - __save_and_cli(flags); - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); - __restore_flags(flags); -} - -/* - * These are for R4000SC / R4400MC - */ -static void r4k_copy_page_s16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s64(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s128(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "ld\t%2,32(%1)\n\t" - "ld\t%3,40(%1)\n\t" - "ld\t%4,48(%1)\n\t" - "ld\t%5,56(%1)\n\t" - "sd\t%2,32(%0)\n\t" - "sd\t%3,40(%0)\n\t" - "sd\t%4,48(%0)\n\t" - "sd\t%5,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "daddiu\t%1,128\n\t" - "ld\t%2,-64(%1)\n\t" - "ld\t%3,-56(%1)\n\t" - "ld\t%4,-48(%1)\n\t" - "ld\t%5,-40(%1)\n\t" - "sd\t%2,-64(%0)\n\t" - "sd\t%3,-56(%0)\n\t" - "sd\t%4,-48(%0)\n\t" - "sd\t%5,-40(%0)\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r4k_flush_cache_all_s16d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache16(); -} - -static inline void r4k_flush_cache_all_s32d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache32(); -} - -static inline void r4k_flush_cache_all_s64d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache64(); -} - -static inline void r4k_flush_cache_all_s128d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache128(); -} - -static inline void r4k_flush_cache_all_s32d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache32(); -} - -static inline void r4k_flush_cache_all_s64d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache64(); -} - -static inline void r4k_flush_cache_all_s128d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache128(); -} - -static inline void r4k_flush_cache_all_d16i16(void) -{ - blast_dcache16(); blast_icache16(); -} - -static inline void r4k_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); -} - -static void r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s16d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache16_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s32d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s32d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s64d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s128d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s32d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s64d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s128d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache16(); blast_icache16(); - } -} - -static void r4k_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache32(); blast_icache32(); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d16i16(); - } -} - -static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d16i16(); - } -} - -static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d32i32(); - } -} - -static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d32i32(); - } -} - -static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d32i32(); - } -} - -static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d16i16(); - } -} - -static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d32i32(); - } -} - -static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache16_page_indexed(page); - } else - blast_scache16_page(page); -out: -} - -static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: -} - -static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: -} - -static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: -} - -static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: -} - -static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: -} - -static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: -} - -static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if(mm == current->mm) { - blast_dcache16_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed(page); - } -out: -} - -static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -out: -} - -static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - blast_dcache32_page_indexed(page ^ dcache_waybit); - } -out: -} - -static void r4k_flush_page_to_ram_s16(struct page *page) -{ - blast_scache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s32(struct page *page) -{ - blast_scache32_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s64(struct page *page) -{ - blast_scache64_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s128(struct page *page) -{ - blast_scache128_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - blast_dcache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void -r4k_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -static void -r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - flush_cache_all(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on http://www.idt.com/ - * in .pdf format.) - */ -static void r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - flush_cache_l1(); - } else { - /* Workaround for R4600 bug. See comment above. */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - bc_wback_inv(addr, size); -} - -static void r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= (unsigned long)scache_size) { - flush_cache_l1(); - return; - } - - a = addr & ~((unsigned long)sc_lsize - 1); - end = (addr + size) & ~((unsigned long)sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - flush_cache_l1(); - } else { - /* Workaround for R4600 bug. See comment above. */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - - bc_inv(addr, size); -} - -static void r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= (unsigned long)scache_size) { - flush_cache_l1(); - return; - } - - a = addr & ~((unsigned long)sc_lsize - 1); - end = (addr + size) & ~((unsigned long)sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r4k_flush_cache_sigtramp(unsigned long addr) -{ - __asm__ __volatile__("nop;nop;nop;nop"); /* R4600 V1.7 */ - - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void r4600v20k_flush_cache_sigtramp(unsigned long addr) -{ - unsigned int flags; - - __save_and_cli(flags); - - /* Clear internal cache refill buffer */ - *(volatile unsigned int *)KSEG1; - - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); - - __restore_flags(flags); -} - -#undef DEBUG_TLB - -#define NTLB_ENTRIES 48 /* Fixed on all R4XX0 variants... */ - -#define NTLB_ENTRIES_HALF 24 /* Fixed on all R4XX0 variants... */ - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < NTLB_ENTRIES) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), - mm) & 0xff); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); - } -} - -static void r4k_flush_cache_l2(void) -{ -} - -/* We will need multiple versions of update_mmu_cache(), one that just - * updates the TLB with the new pte(s), and another which also checks - * for the R4k "end of page" hardware bug and does the needy. - */ -static void r4k_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - __save_and_cli(flags); - pid = (get_entryhi() & 0xff); - -#ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) || - (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d - tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & 0xff), pid); - } -#endif - - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - -#if 0 -static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx; - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (get_entryhi() & 0xff)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - BARRIER; - if(idx < 0) - tlb_write_random(); - else - tlb_write_indexed(); - BARRIER; - __restore_flags(flags); -} -#endif - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes)\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes)\n", - dcache_size >> 10, dc_lsize); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - __save_and_cli(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 8, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 9, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 11, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 7, (%0)\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - __restore_flags(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - unsigned int prid; - - switch(dc_lsize) { - case 16: - _clear_page = r4k_clear_page_d16; - _copy_page = r4k_copy_page_d16; - _flush_cache_all = r4k_flush_cache_all_d16i16; - _flush_cache_l1 = r4k_flush_cache_all_d16i16; - _flush_cache_mm = r4k_flush_cache_mm_d16i16; - _flush_cache_range = r4k_flush_cache_range_d16i16; - _flush_cache_page = r4k_flush_cache_page_d16i16; - break; - case 32: - prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0; - if (prid == 0x2010) { /* R4600 V1.7 */ - _clear_page = r4k_clear_page_r4600_v1; - _copy_page = r4k_copy_page_r4600_v1; - } else if (prid == 0x2020) { /* R4600 V2.0 */ - _clear_page = r4k_clear_page_r4600_v2; - _copy_page = r4k_copy_page_r4600_v2; - } else { - _clear_page = r4k_clear_page_d32; - _copy_page = r4k_copy_page_d32; - } - _flush_cache_all = r4k_flush_cache_all_d32i32; - _flush_cache_l1 = r4k_flush_cache_all_d32i32; - _flush_cache_mm = r4k_flush_cache_mm_d32i32; - _flush_cache_range = r4k_flush_cache_range_d32i32; - _flush_cache_page = r4k_flush_cache_page_d32i32; - break; - } - - switch(ic_lsize) { - case 16: - _flush_page_to_ram = r4k_flush_page_to_ram_d16; - break; - case 32: - _flush_page_to_ram = r4k_flush_page_to_ram_d32; - break; - } - _flush_icache_page = r4k_flush_icache_page_p; - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc; - _dma_cache_wback = r4k_dma_cache_wback_inv_pc; - _dma_cache_inv = r4k_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - switch(sc_lsize) { - case 16: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s16d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s16d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s16d16i16; - _flush_cache_range = r4k_flush_cache_range_s16d16i16; - _flush_cache_page = r4k_flush_cache_page_s16d16i16; - break; - case 32: - panic("Invalid cache configuration detected"); - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s16; - _clear_page = r4k_clear_page_s16; - _copy_page = r4k_copy_page_s16; - break; - case 32: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s32d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s32d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s32d16i16; - _flush_cache_range = r4k_flush_cache_range_s32d16i16; - _flush_cache_page = r4k_flush_cache_page_s32d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s32d32i32; - _flush_cache_l1 = r4k_flush_cache_all_s32d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s32d32i32; - _flush_cache_range = r4k_flush_cache_range_s32d32i32; - _flush_cache_page = r4k_flush_cache_page_s32d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s32; - _clear_page = r4k_clear_page_s32; - _copy_page = r4k_copy_page_s32; - break; - case 64: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s64d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s64d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s64d16i16; - _flush_cache_range = r4k_flush_cache_range_s64d16i16; - _flush_cache_page = r4k_flush_cache_page_s64d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s64d32i32; - _flush_cache_l1 = r4k_flush_cache_all_s64d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s64d32i32; - _flush_cache_range = r4k_flush_cache_range_s64d32i32; - _flush_cache_page = r4k_flush_cache_page_s64d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s64; - _clear_page = r4k_clear_page_s64; - _copy_page = r4k_copy_page_s64; - break; - case 128: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s128d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s128d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s128d16i16; - _flush_cache_range = r4k_flush_cache_range_s128d16i16; - _flush_cache_page = r4k_flush_cache_page_s128d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s128d32i32; - _flush_cache_l1 = r4k_flush_cache_all_s128d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s128d32i32; - _flush_cache_range = r4k_flush_cache_range_s128d32i32; - _flush_cache_page = r4k_flush_cache_page_s128d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s128; - _clear_page = r4k_clear_page_s128; - _copy_page = r4k_copy_page_s128; - break; - } - _flush_icache_page = r4k_flush_icache_page_s; - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; - _dma_cache_wback = r4k_dma_cache_wback_inv_sc; - _dma_cache_inv = r4k_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); -extern int r5k_sc_init(void); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (!sc_present) { - setup_noscache_funcs(); - return; - } - - switch(mips_cpu.cputype) { - case CPU_R5000: - case CPU_NEVADA: - setup_noscache_funcs(); -#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA) - r5k_sc_init(); -#endif - break; - default: - setup_scache_funcs(); - } - -} - -void __init ld_mmu_r4xx0(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - switch(mips_cpu.cputype) { - case CPU_R4600: /* QED style two way caches? */ - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - _flush_cache_page = r4k_flush_cache_page_d32i32_r4600; - } - - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) { - _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp; - } - _flush_icache_range = r4k_flush_icache_range; /* Ouch */ - - _flush_cache_l2 = r4k_flush_cache_l2; - - _update_mmu_cache = r4k_update_mmu_cache; - - flush_cache_l1(); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - local_flush_tlb_all(); -} diff -urN linux-2.4.21/arch/mips64/mm/r5k-sc.c linux-2.4.22/arch/mips64/mm/r5k-sc.c --- linux-2.4.21/arch/mips64/mm/r5k-sc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/r5k-sc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,115 +0,0 @@ -/* - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#define SC_LINE 32 -#define SC_PAGE (128*SC_LINE) - -#define cache_op(base,op) \ -__asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, (%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -static inline void blast_r5000_scache(void) -{ - unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache_op(start, R5K_Page_Invalidate_S); - start += SC_PAGE; - } -} - -static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_r5000_scache(); - return; - } - - /* On the R5000 secondary cache we cannot - * invalidate less than a page at a time. - * The secondary cache is physically indexed, write-through. - */ - a = addr & ~(SC_PAGE - 1); - end = (addr + size - 1) & ~(SC_PAGE - 1); - while (a <= end) { - cache_op(a, R5K_Page_Invalidate_S); - a += SC_PAGE; - } -} - -static void r5k_sc_enable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - change_cp0_config(CONF_SE, CONF_SE); - blast_r5000_scache(); - __restore_flags(flags); -} - -static void r5k_sc_disable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_r5000_scache(); - change_cp0_config(CONF_SE, 0); - __restore_flags(flags); -} - -static inline int __init r5k_sc_probe(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - if(config & CONF_SC) - return(0); - - scache_size = (512*1024) << ((config >> 20)&3); - - printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -struct bcache_ops r5k_sc_ops = { - r5k_sc_enable, - r5k_sc_disable, - r5k_dma_cache_inv_sc, - r5k_dma_cache_inv_sc -}; - -void __init r5k_sc_init(void) -{ - if (r5k_sc_probe()) { - r5k_sc_enable(); - bcops = &r5k_sc_ops; - } -} diff -urN linux-2.4.21/arch/mips64/mm/sc-ip22.c linux-2.4.22/arch/mips64/mm/sc-ip22.c --- linux-2.4.21/arch/mips64/mm/sc-ip22.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/sc-ip22.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,177 @@ +/* + * sc-ip22.c: Indy cache management functions. + * + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#undef DEBUG_CACHE + +#define SC_SIZE 0x00080000 +#define SC_LINE 32 +#define CI_MASK (SC_SIZE - SC_LINE) +#define SC_INDEX(n) ((n) & CI_MASK) + +static inline void indy_sc_wipe(unsigned long first, unsigned long last) +{ + unsigned long tmp; + + __asm__ __volatile__( + ".set\tpush\t\t\t# indy_sc_wipe\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + ".set\tnoat\n\t" + "mfc0\t%2, $12\n\t" + "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" + "mtc0\t$1, $12\n\t" + + "dli\t$1, 0x9000000080000000\n\t" + "or\t%0, $1\t\t\t# first line to flush\n\t" + "or\t%1, $1\t\t\t# last line to flush\n\t" + ".set\tat\n\t" + + "1:\tsw\t$0, 0(%0)\n\t" + "bne\t%0, %1, 1b\n\t" + " daddu\t%0, 32\n\t" + + "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (first), "=r" (last), "=&r" (tmp) + : "0" (first), "1" (last)); +} + +static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) +{ + unsigned long first_line, last_line; + unsigned long flags; + +#ifdef DEBUG_CACHE + printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); +#endif + + if (!size) + return; + + /* Which lines to flush? */ + first_line = SC_INDEX(addr); + last_line = SC_INDEX(addr + size - 1); + + local_irq_save(flags); + if (first_line <= last_line) { + indy_sc_wipe(first_line, last_line); + goto out; + } + + indy_sc_wipe(first_line, SC_SIZE - SC_LINE); + indy_sc_wipe(0, last_line); +out: + local_irq_restore(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long addr, tmp1, tmp2; + + /* This is really cool... */ +#ifdef DEBUG_CACHE + printk("Enabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "sb\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop;\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + +#ifdef DEBUG_CACHE + printk("Disabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop\n\t" + "sh\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline int __init indy_sc_probe(void) +{ + unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17); + if (size == 0) + return 0; + + size <<= PAGE_SHIFT; + printk(KERN_INFO "R4600/R5000 SCACHE size %dK, linesize 32 bytes.\n", + size >> 10); + scache_size = size; + + return 1; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + .bc_enable = indy_sc_enable, + .bc_disable = indy_sc_disable, + .bc_wback_inv = indy_sc_wback_invalidate, + .bc_inv = indy_sc_wback_invalidate +}; + +void __init indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} diff -urN linux-2.4.21/arch/mips64/mm/sc-r5k.c linux-2.4.22/arch/mips64/mm/sc-r5k.c --- linux-2.4.21/arch/mips64/mm/sc-r5k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/sc-r5k.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#define SC_LINE 32 +#define SC_PAGE (128*SC_LINE) + +#define cache_op(base,op) \ +__asm__ __volatile__(" \ + .set noreorder; \ + .set mips3; \ + cache %1, (%0); \ + .set mips0; \ + .set reorder" \ + : \ + : "r" (base), \ + "i" (op)); + +static inline void blast_r5000_scache(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + cache_op(start, R5K_Page_Invalidate_S); + start += SC_PAGE; + } +} + +static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (size >= scache_size) { + blast_r5000_scache(); + return; + } + + /* On the R5000 secondary cache we cannot + * invalidate less than a page at a time. + * The secondary cache is physically indexed, write-through. + */ + a = addr & ~(SC_PAGE - 1); + end = (addr + size - 1) & ~(SC_PAGE - 1); + while (a <= end) { + cache_op(a, R5K_Page_Invalidate_S); + a += SC_PAGE; + } +} + +static void r5k_sc_enable(void) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_config(R5K_CONF_SE, R5K_CONF_SE); + blast_r5000_scache(); + local_irq_restore(flags); +} + +static void r5k_sc_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + blast_r5000_scache(); + change_c0_config(R5K_CONF_SE, 0); + local_irq_restore(flags); +} + +static inline int __init r5k_sc_probe(void) +{ + unsigned long config = read_c0_config(); + + if (config & CONF_SC) + return(0); + + scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); + + printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n", + scache_size >> 10); + + return 1; +} + +static struct bcache_ops r5k_sc_ops = { + .bc_enable = r5k_sc_enable, + .bc_disable = r5k_sc_disable, + .bc_wback_inv = r5k_dma_cache_inv_sc, + .bc_inv = r5k_dma_cache_inv_sc +}; + +void __init r5k_sc_init(void) +{ + if (r5k_sc_probe()) { + r5k_sc_enable(); + bcops = &r5k_sc_ops; + } +} diff -urN linux-2.4.21/arch/mips64/mm/sc-rm7k.c linux-2.4.22/arch/mips64/mm/sc-rm7k.c --- linux-2.4.21/arch/mips64/mm/sc-rm7k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/sc-rm7k.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,191 @@ +/* + * sc-rm7k.c: RM7000 cache management functions. + * + * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org), + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Primary cache parameters. */ +#define sc_lsize 32 +#define tc_pagesize (32*128) + +/* Secondary cache parameters. */ +#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ + +extern unsigned long icache_way_size, dcache_way_size; + +#include + +int rm7k_tcache_enabled; + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * (XXX These need to be fixed ...) + */ +static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +static void rm7k_sc_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +/* + * This function is executed in the uncached segment KSEG1. + * It must not touch the stack, because the stack pointer still points + * into KSEG0. + * + * Three options: + * - Write it in assembly and guarantee that we don't use the stack. + * - Disable caching for KSEG0 before calling it. + * - Pray that GCC doesn't randomly start using the stack. + * + * This being Linux, we obviously take the least sane of those options - + * following DaveM's lead in c-r4k.c + * + * It seems we get our kicks from relying on unguaranteed behaviour in GCC + */ +static __init void rm7k_sc_enable(void) +{ + int i; + + set_c0_config(1<<3); /* CONF_SE */ + + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i> 31) & 1) + return 0; + + printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + (scache_size >> 10), sc_lsize); + + if ((config >> 3) & 1) + return; + + printk(KERN_INFO "Enabling secondary cache..."); + func(); + printk(" done\n"); + + /* + * While we're at it let's deal with the tertiary cache. + */ + if ((config >> 17) & 1) + return 1; + + /* + * We can't enable the L3 cache yet. There may be board-specific + * magic necessary to turn it on, and blindly asking the CPU to + * start using it would may give cache errors. + * + * Also, board-specific knowledge may allow us to use the + * CACHE Flash_Invalidate_T instruction if the tag RAM supports + * it, and may specify the size of the L3 cache so we don't have + * to probe it. + */ + printk(KERN_INFO "Tertiary cache present, %s enabled\n", + config&(1<<12) ? "already" : "not (yet)"); + + if ((config >> 12) & 1) + rm7k_tcache_enabled = 1; + + return 1; +} + +struct bcache_ops rm7k_sc_ops = { + .bc_enable = rm7k_sc_enable, + .bc_disable = rm7k_sc_disable, + .bc_wback_inv = rm7k_sc_wback_inv, + .bc_inv = rm7k_sc_inv +}; + +void __init rm7k_sc_init(void) +{ + if (rm7k_sc_probe()) { + rm7k_sc_enable(); + bcops = &rm7k_sc_ops; + } +} diff -urN linux-2.4.21/arch/mips64/mm/tlb-andes.c linux-2.4.22/arch/mips64/mm/tlb-andes.c --- linux-2.4.21/arch/mips64/mm/tlb-andes.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/tlb-andes.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,205 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) + */ +#include +#include +#include +#include +#include +#include +#include +#include + +extern void except_vec1_r10k(void); + +#define NTLB_ENTRIES 64 +#define NTLB_ENTRIES_HALF 32 + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + unsigned long entry; + +#ifdef DEBUG_TLB + printk("[tlball]"); +#endif + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(CKSEG0); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + + entry = read_c0_wired(); + + /* Blast 'em all away. */ + while (entry < NTLB_ENTRIES) { + write_c0_index(entry); + tlb_write_indexed(); + entry++; + } + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { +#ifdef DEBUG_TLB + printk("[tlbmm<%d>]", mm->context); +#endif + drop_mmu_context(mm,cpu); + } +} + +void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbrange<%02x,%08lx,%08lx>]", + (mm->context & ASID_MASK), start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= NTLB_ENTRIES_HALF) { + int oldpid = (read_c0_entryhi() & ASID_MASK); + int newpid = (cpu_context(smp_processor_id(), mm) + & ASID_MASK); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + while(start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0); + if(idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + local_irq_restore(flags); + } +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) { + unsigned long flags; + int oldpid, newpid, idx; + +#ifdef DEBUG_TLB + printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); +#endif + newpid = (cpu_context(smp_processor_id(), vma->vm_mm) & + ASID_MASK); + page &= (PAGE_MASK << 1); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(page | newpid); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0); + if (idx < 0) + goto finish; + tlb_write_indexed(); + + finish: + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +} + +/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual + address that already exists will overwrite the old entry and not result + in TLB malfunction or TLB shutdown. */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned int cpu = smp_processor_id(); + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + + if ((pid != cpu_asid(cpu, vma->vm_mm)) + || (cpu_context(cpu, vma->vm_mm) == 0)) { + printk(KERN_WARNING + "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", + __FUNCTION__, (int) cpu_asid(cpu, vma->vm_mm), pid); + } + + local_irq_save(flags); + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | (pid)); + pgdp = pgd_offset(vma->vm_mm, address); + tlb_probe(); + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset(pmdp, address); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + write_c0_entryhi(address | (pid)); + if (idx < 0) { + tlb_write_random(); + } else { + tlb_write_indexed(); + } + write_c0_entryhi(pid); + local_irq_restore(flags); +} + +void __init andes_tlb_init(void) +{ + /* + * You should never change this register: + * - On R4600 1.7 the tlbp never hits for pages smaller than + * the value in the c0_pagemask register. + * - The entire mm handling assumes the c0_pagemask register to + * be set for 4kb pages. + */ + write_c0_pagemask(PM_4K); + write_c0_wired(0); + write_c0_framemask(0); + + /* From this point on the ARC firmware is dead. */ + local_flush_tlb_all(); + + /* Did I tell you that ARC SUCKS? */ + + memcpy((void *)KSEG1 + 0x080, except_vec1_r10k, 0x80); +} diff -urN linux-2.4.21/arch/mips64/mm/tlb-dbg-r4k.c linux-2.4.22/arch/mips64/mm/tlb-dbg-r4k.c --- linux-2.4.21/arch/mips64/mm/tlb-dbg-r4k.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips64/mm/tlb-dbg-r4k.c 2003-08-25 04:44:40.000000000 -0700 @@ -39,8 +39,8 @@ pmd = pmd_offset(pgd, addr); pte = pte_offset(pmd, addr); - set_entrylo0(pte_val(pte[0]) >> 6); - set_entrylo1(pte_val(pte[1]) >> 6); + write_c0_entrylo0(pte_val(pte[0]) >> 6); + write_c0_entrylo1(pte_val(pte[1]) >> 6); __asm__ __volatile__("nop;nop;nop"); tlb_write_random(); diff -urN linux-2.4.21/arch/mips64/mm/tlb-glue-r4k.S linux-2.4.22/arch/mips64/mm/tlb-glue-r4k.S --- linux-2.4.21/arch/mips64/mm/tlb-glue-r4k.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/mips64/mm/tlb-glue-r4k.S 2003-08-25 04:44:40.000000000 -0700 @@ -19,6 +19,10 @@ STI .endm + .macro __BUILD_kmode + KMODE + .endm + .macro tlb_handler name interruptible writebit NESTED(__\name, PT_SIZE, sp) SAVE_ALL @@ -32,6 +36,6 @@ END(__\name) .endm - tlb_handler xtlb_mod sti 1 - tlb_handler xtlb_tlbl sti 0 - tlb_handler xtlb_tlbs sti 1 + tlb_handler xtlb_mod kmode 1 + tlb_handler xtlb_tlbl kmode 0 + tlb_handler xtlb_tlbs kmode 1 diff -urN linux-2.4.21/arch/mips64/mm/tlb-glue-sb1.S linux-2.4.22/arch/mips64/mm/tlb-glue-sb1.S --- linux-2.4.21/arch/mips64/mm/tlb-glue-sb1.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/tlb-glue-sb1.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,66 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + .macro tlb_handler_m3 name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT + 1 + bnez k0, 1f + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault +1: + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 +#if BCM1250_M3_WAR + tlb_handler_m3 xtlb_tlbl kmode 0 +#else + tlb_handler xtlb_tlbl kmode 0 +#endif + tlb_handler xtlb_tlbs kmode 1 diff -urN linux-2.4.21/arch/mips64/mm/tlb-r4k.c linux-2.4.22/arch/mips64/mm/tlb-r4k.c --- linux-2.4.21/arch/mips64/mm/tlb-r4k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/tlb-r4k.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,7 +33,7 @@ #undef DEBUG_TLB #undef DEBUG_TLBUPDATE -extern char except_vec1_r4k; +extern void except_vec1_r4k(void); /* CP0 hazard avoidance. */ #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ @@ -50,66 +50,62 @@ printk("[tlball]"); #endif - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); + old_ctx = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(XKPHYS); + write_c0_entrylo0(0); + write_c0_entrylo1(0); BARRIER; - entry = get_wired(); + entry = read_c0_wired(); /* Blast 'em all away. */ - while(entry < mips_cpu.tlbsize) { + while(entry < current_cpu_data.tlbsize) { /* Make sure all entries differ. */ - set_entryhi(KSEG0+entry*0x2000); - set_index(entry); + write_c0_entryhi(XKPHYS+entry*0x2000); + write_c0_index(entry); BARRIER; tlb_write_indexed(); BARRIER; entry++; } BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_mm(struct mm_struct *mm) { - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { #ifdef DEBUG_TLB printk("[tlbmm<%d>]", mm->context); #endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & - 0xff); - __restore_flags(flags); + drop_mmu_context(mm,cpu); } } void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { unsigned long flags; int size; #ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), + printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & ASID_MASK), start, end); #endif - __save_and_cli(flags); + local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if(size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & - 0xff); + if(size <= current_cpu_data.tlbsize/2) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); @@ -117,71 +113,69 @@ while(start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) continue; /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); + write_c0_entryhi(XKPHYS+idx*0x2000); BARRIER; tlb_write_indexed(); BARRIER; } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), - mm) & 0xff); + drop_mmu_context(mm, cpu); } - __restore_flags(flags); + local_irq_restore(flags); } } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) { unsigned long flags; unsigned long oldpid, newpid, idx; #ifdef DEBUG_TLB printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); #endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(page | newpid); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); + write_c0_entryhi(XKPHYS+idx*0x2000); BARRIER; tlb_write_indexed(); finish: BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); + write_c0_entryhi(oldpid); + local_irq_restore(flags); } } /* * Updates the TLB with the new pte(s). */ -void mips64_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -195,31 +189,31 @@ if (current->active_mm != vma->vm_mm) return; - pid = get_entryhi() & 0xff; + pid = read_c0_entryhi() & ASID_MASK; #ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) || - (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d - tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & 0xff), pid); + if ((pid != (cpu_asid(smp_processor_id(), vma->vm_mm))) || + (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) { + printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d" + "tlbpid=%d\n", (int) (cpu_context(smp_processor_id(), + vma->vm_mm) & ASID_MASK), pid); } #endif - __save_and_cli(flags); + local_irq_save(flags); address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | (pid)); pgdp = pgd_offset(vma->vm_mm, address); BARRIER; tlb_probe(); BARRIER; pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + write_c0_entryhi(address | (pid)); BARRIER; if(idx < 0) { tlb_write_random(); @@ -227,70 +221,9 @@ tlb_write_indexed(); } BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - -void dump_mm_page(unsigned long addr) -{ - pgd_t *page_dir, *pgd; - pmd_t *pmd; - pte_t *pte, page; - unsigned long val; - - page_dir = pgd_offset(current->mm, 0); - pgd = pgd_offset(current->mm, addr); - pmd = pmd_offset(pgd, addr); - pte = pte_offset(pmd, addr); - page = *pte; - printk("Memory Mapping: VA = %08x, PA = %08x ", addr, (unsigned int) pte_val(page)); - val = pte_val(page); - if (val & _PAGE_PRESENT) printk("present "); - if (val & _PAGE_READ) printk("read "); - if (val & _PAGE_WRITE) printk("write "); - if (val & _PAGE_ACCESSED) printk("accessed "); - if (val & _PAGE_MODIFIED) printk("modified "); - if (val & _PAGE_R4KBUG) printk("r4kbug "); - if (val & _PAGE_GLOBAL) printk("global "); - if (val & _PAGE_VALID) printk("valid "); - printk("\n"); -} - -void show_tlb(void) -{ - unsigned int flags; - unsigned int old_ctx; - unsigned int entry; - unsigned int entrylo0, entrylo1, entryhi; - - __save_and_cli(flags); - - /* Save old context */ - old_ctx = (get_entryhi() & 0xff); - - printk("TLB content:\n"); - entry = 0; - while(entry < mips_cpu.tlbsize) { - set_index(entry); - BARRIER; - tlb_read(); - BARRIER; - entryhi = get_entryhi(); - entrylo0 = get_entrylo0(); - entrylo1 = get_entrylo1(); - printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK); - printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : ""); - printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : ""); - - dump_mm_page(entryhi & ~0xff); - dump_mm_page((entryhi & ~0xff) | 0x1000); - entry++; - } + write_c0_entryhi(pid); BARRIER; - set_entryhi(old_ctx); - - __restore_flags(flags); + local_irq_restore(flags); } void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, @@ -301,27 +234,27 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); + old_ctx = (read_c0_entryhi() & ASID_MASK); + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask (old_pagemask); + write_c0_pagemask(old_pagemask); local_flush_tlb_all(); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -341,67 +274,66 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - old_pagemask = get_pagemask(); - wired = get_wired(); + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); if (--temp_tlb_entry < wired) { printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); ret = -ENOSPC; goto out; } - set_index(temp_tlb_entry); + write_c0_index(temp_tlb_entry); BARRIER; - set_pagemask(pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask(old_pagemask); + write_c0_pagemask(old_pagemask); out: - __restore_flags(flags); + local_irq_restore(flags); return ret; } static void __init probe_tlb(unsigned long config) { - unsigned long config1; - if (!(config & (1 << 31))) { /* * Not a MIPS64 complainant CPU. * Config 1 register not supported, we assume R4k style. */ - mips_cpu.tlbsize = 48; + current_cpu_data.tlbsize = 48; } else { - config1 = read_mips32_cp0_config1(); + unsigned long config1; + + config1 = read_c0_config1(); if (!((config >> 7) & 3)) panic("No MMU present"); else - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1; } - printk("Number of TLB entries %d.\n", mips_cpu.tlbsize); + printk("Number of TLB entries %d.\n", current_cpu_data.tlbsize); } void __init r4k_tlb_init(void) { - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); + unsigned long config = read_c0_config(); probe_tlb(config); - _update_mmu_cache = mips64_update_mmu_cache; - set_pagemask(PM_4K); - write_32bit_cp0_register(CP0_WIRED, 0); - temp_tlb_entry = mips_cpu.tlbsize - 1; + write_c0_pagemask(PM_4K); + write_c0_wired(0); + temp_tlb_entry = current_cpu_data.tlbsize - 1; local_flush_tlb_all(); - memcpy((void *)(KSEG0 + 0x80), &except_vec1_r4k, 0x80); + memcpy((void *)(KSEG0 + 0x80), except_vec1_r4k, 0x80); flush_icache_range(KSEG0, KSEG0 + 0x80); } diff -urN linux-2.4.21/arch/mips64/mm/tlb-sb1.c linux-2.4.22/arch/mips64/mm/tlb-sb1.c --- linux-2.4.21/arch/mips64/mm/tlb-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/tlb-sb1.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,6 +22,8 @@ #include #include +extern void except_vec1_sb1(void); + /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) { @@ -65,30 +67,24 @@ unsigned long old_ctx; unsigned long flags; int entry; - __save_and_cli(flags); - old_ctx = get_entryhi(); + local_irq_save(flags); + old_ctx = read_c0_entryhi(); printk("Current TLB registers state:\n" " EntryHi EntryLo0 EntryLo1 PageMask Index\n" "--------------------------------------------------------------------\n"); dump_cur_tlb_regs(); - printk(" %08X\n", read_32bit_cp0_register(CP0_INDEX)); + printk(" %08X\n", read_c0_index()); printk("\n\nFull TLB Dump:\n" "Idx EntryHi EntryLo0 EntryLo1 PageMask\n" "--------------------------------------------------------------\n"); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_index(entry); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry); printk("\n%02i ", entry); - __asm__ __volatile__ ( - ".set push \n" - "#.set mips64 \n" - ".set mips4 \n" - " tlbr \n" - ".set pop \n"); dump_cur_tlb_regs(); } printk("\n"); - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_all(void) @@ -97,18 +93,18 @@ unsigned long old_ctx; int entry; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); - set_index(entry); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + write_c0_index(entry); tlb_write_indexed(); } - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } @@ -126,15 +122,15 @@ long inc = 1<<24; /* 16MB */ /* Save old context and create impossible VPN2 value */ - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { do { addr += inc; - set_entryhi(addr); + write_c0_entryhi(addr); tlb_probe(); - } while ((int)(get_index()) >= 0); - set_index(entry); + } while ((int)(read_c0_index()) >= 0); + write_c0_index(entry); tlb_write_indexed(); } /* Now that we know we're safe from collisions, we can safely flush @@ -149,15 +145,15 @@ unsigned long flags; int cpu; - __save_and_cli(flags); + local_irq_save(flags); cpu = smp_processor_id(); - if(CPU_CONTEXT(cpu, mm) != 0) { + if (cpu_context(cpu, mm) != 0) { int size; size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if(size <= (mips_cpu.tlbsize/2)) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(cpu, mm) & 0xff); + if(size <= (current_cpu_data.tlbsize/2)) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); @@ -165,63 +161,50 @@ while(start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); if(idx < 0) continue; tlb_write_indexed(); } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, cpu); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); + drop_mmu_context(mm, cpu); } } - __restore_flags(flags); + local_irq_restore(flags); } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { unsigned long flags; - -#ifdef CONFIG_SMP - /* - * This variable is eliminated from CPU_CONTEXT() if SMP isn't defined, - * so conditional it to get rid of silly "unused variable" compiler - * complaints - */ int cpu = smp_processor_id(); -#endif - __save_and_cli(flags); - if (CPU_CONTEXT(cpu, vma->vm_mm) != 0) { + local_irq_save(flags); + if (cpu_context(cpu, vma->vm_mm) != 0) { int oldpid, newpid, idx; -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", CPU_CONTEXT(cpu, vma->vm_mm), page); -#endif - newpid = (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - oldpid = (get_entryhi() & 0xff); - set_entryhi (page | newpid); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); tlb_write_indexed(); finish: - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } - __restore_flags(flags); + local_irq_restore(flags); } @@ -229,23 +212,15 @@ these entries, we just bump the asid. */ void local_flush_tlb_mm(struct mm_struct *mm) { - unsigned long flags; - int cpu; - __save_and_cli(flags); - cpu = smp_processor_id(); - if (CPU_CONTEXT(cpu, mm) != 0) { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) { - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); - } + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + drop_mmu_context(mm, cpu); } - __restore_flags(flags); } /* Stolen from mips32 routines */ -void sb1_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -259,35 +234,24 @@ if (current->active_mm != vma->vm_mm) return; - __save_and_cli(flags); - - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff)) || (CPU_CONTEXT(cpu, vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff), pid); - } -#endif + local_irq_save(flags); + pid = read_c0_entryhi() & ASID_MASK; address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | (pid)); pgdp = pgd_offset(vma->vm_mm, address); tlb_probe(); pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); if (idx < 0) { tlb_write_random(); } else { tlb_write_indexed(); } - set_entryhi(pid); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -297,10 +261,7 @@ */ void sb1_tlb_init(void) { - u32 config1; - - config1 = read_mips32_cp0_config1(); - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + write_c0_pagemask(PM_4K); /* * We don't know what state the firmware left the TLB's in, so this is @@ -308,5 +269,7 @@ * check exceptions due to duplicate TLB entries */ sb1_sanitize_tlb(); - _update_mmu_cache = sb1_update_mmu_cache; + + memcpy((void *)KSEG0 + 0x080, except_vec1_sb1, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); } diff -urN linux-2.4.21/arch/mips64/mm/tlbex-r4k.S linux-2.4.22/arch/mips64/mm/tlbex-r4k.S --- linux-2.4.21/arch/mips64/mm/tlbex-r4k.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/tlbex-r4k.S 2003-08-25 04:44:40.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include .data .comm pgd_current, NR_CPUS * 8, 8 @@ -72,8 +73,9 @@ * Determine that fault address is within vmalloc range. */ dla \tmp, ekptbl - sltu \tmp, \ptr, \tmp + slt \tmp, \ptr, \tmp beqz \tmp, \not_vmalloc # not vmalloc + nop .endm @@ -96,16 +98,16 @@ __INIT .align 5 -LEAF(except_vec0) +LEAF(except_vec0_generic) .set noat PANIC("Unused vector called") 1: b 1b nop -END(except_vec0) +END(except_vec0_generic) /* - * TLB refill handler for the R4000. + * TLB refill handlers for the R4000 and SB1. * Attention: We may only use 32 instructions / 128 bytes. */ .align 5 @@ -116,6 +118,23 @@ nop END(except_vec1_r4k) +LEAF(except_vec1_sb1) +#if BCM1250_M3_WAR + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop + +1: eret + nop +END(except_vec1_sb1) + __FINIT .align 5 @@ -141,6 +160,7 @@ eret END(handle_vec1_r4k) + __INIT /* diff -urN linux-2.4.21/arch/mips64/mm/umap.c linux-2.4.22/arch/mips64/mm/umap.c --- linux-2.4.21/arch/mips64/mm/umap.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/mips64/mm/umap.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,217 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1994 Linus Torvalds - * Copyright (C) 1997 Miguel de Icaza - * Copyright (C) 2001 Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static inline void remove_mapping_pte_range (pmd_t *pmd, unsigned long address, - unsigned long size) -{ - pte_t *pte; - unsigned long end; - - if (pmd_none (*pmd)) - return; - if (pmd_bad (*pmd)){ - printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", - pmd_val (*pmd)); - pmd_clear (pmd); - return; - } - pte = pte_offset (pmd, address); - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t entry = *pte; - if (pte_present (entry)) - set_pte (pte, pte_modify (entry, PAGE_NONE)); - address += PAGE_SIZE; - pte++; - } while (address < end); - -} - -static inline void remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, - unsigned long size) -{ - pmd_t *pmd; - unsigned long end; - - if (pgd_none (*pgd)) - return; - - if (pgd_bad (*pgd)){ - printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", - pgd_val (*pgd)); - pgd_clear (pgd); - return; - } - pmd = pmd_offset (pgd, address); - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - do { - remove_mapping_pte_range (pmd, address, end - address); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - -} - -/* - * This routine is called from the page fault handler to remove a - * range of active mappings at this point - */ -void remove_mapping (struct task_struct *task, unsigned long start, - unsigned long end) -{ - unsigned long beg = start; - pgd_t *dir; - - down_write (&task->mm->mmap_sem); - dir = pgd_offset (task->mm, start); - flush_cache_range (task->mm, beg, end); - while (start < end){ - remove_mapping_pmd_range (dir, start, end - start); - start = (start + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range (task->mm, beg, end); - up_write (&task->mm->mmap_sem); -} - -EXPORT_SYMBOL(remove_mapping); - -void *vmalloc_uncached (unsigned long size) -{ - return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_UNCACHED); -} - -static inline void free_pte(pte_t page) -{ - if (pte_present(page)) { - struct page *ptpage = pte_page(page); - if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage)) - return; - __free_page(ptpage); - if (current->mm->rss <= 0) - return; - current->mm->rss--; - return; - } - swap_free(pte_to_swp_entry(page)); -} - -static inline void forget_pte(pte_t page) -{ - if (!pte_none(page)) { - printk("forget_pte: old mapping existed!\n"); - free_pte(page); - } -} - -/* - * maps a range of vmalloc()ed memory into the requested pages. the old - * mappings are removed. - */ -static inline void vmap_pte_range (pte_t *pte, unsigned long address, - unsigned long size, unsigned long vaddr) -{ - unsigned long end; - pgd_t *vdir; - pmd_t *vpmd; - pte_t *vpte; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t oldpage = *pte; - struct page * page; - pte_clear(pte); - - vdir = pgd_offset_k (vaddr); - vpmd = pmd_offset (vdir, vaddr); - vpte = pte_offset (vpmd, vaddr); - page = pte_page (*vpte); - - set_pte(pte, mk_pte(page, PAGE_USERIO)); - forget_pte(oldpage); - address += PAGE_SIZE; - vaddr += PAGE_SIZE; - pte++; - } while (address < end); -} - -static inline int vmap_pmd_range (pmd_t *pmd, unsigned long address, - unsigned long size, unsigned long vaddr) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - vaddr -= address; - do { - pte_t * pte = pte_alloc(current->mm, pmd, address); - if (!pte) - return -ENOMEM; - vmap_pte_range(pte, address, end - address, address + vaddr); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - return 0; -} - -int vmap_page_range (unsigned long from, unsigned long size, - unsigned long vaddr) -{ - int error = 0; - pgd_t * dir; - unsigned long beg = from; - unsigned long end = from + size; - - vaddr -= from; - dir = pgd_offset(current->mm, from); - flush_cache_range(current->mm, beg, end); - while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); - error = -ENOMEM; - if (!pmd) - break; - error = vmap_pmd_range(pmd, from, end - from, vaddr + from); - if (error) - break; - from = (from + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range(current->mm, beg, end); - return error; -} diff -urN linux-2.4.21/arch/parisc/config.in linux-2.4.22/arch/parisc/config.in --- linux-2.4.21/arch/parisc/config.in 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -136,7 +136,7 @@ if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -196,4 +196,5 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/parisc/defpalo.conf linux-2.4.22/arch/parisc/defpalo.conf --- linux-2.4.21/arch/parisc/defpalo.conf 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/parisc/defpalo.conf 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,21 @@ +# This a generic Palo configuration file. For more information about how +# it works try 'palo -?'. +# +# Most people using 'make palo' want a bootable file, usable for +# network or tape booting for example. +--init-tape=lifimage +--recoverykernel=vmlinux + +########## Pick your ROOT here! ########## +# You need at least one 'root='! +# +# If you want a root ramdisk, use the next 2 lines +# (Edit the ramdisk image name!!!!) +--ramdisk=ram-disk-image-file +--commandline=0/vmlinux HOME=/ root=/dev/ram initrd=0/ramdisk + +# If you want NFS root, use the following command line (Edit the HOSTNAME!!!) +#--commandline=0/vmlinux HOME=/ root=/dev/nfs nfsroot=HOSTNAME ip=bootp + +# If you have root on a disk partition, use this (Edit the partition name!!!) +#--commandline=0/vmlinux HOME=/ root=/dev/sda1 diff -urN linux-2.4.21/arch/parisc/kernel/cache.c linux-2.4.22/arch/parisc/kernel/cache.c --- linux-2.4.21/arch/parisc/kernel/cache.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/kernel/cache.c 2003-08-25 04:44:40.000000000 -0700 @@ -194,31 +194,69 @@ void disable_sr_hashing(void) { - int srhash_type; + int srhash_type; - if (boot_cpu_data.cpu_type == pcxl2) - return; /* pcxl2 doesn't support space register hashing */ + switch (boot_cpu_data.cpu_type) { + case pcx: /* We shouldn't get this far. setup.c should prevent it. */ + BUG(); + return; + + case pcxs: + case pcxt: + case pcxt_: + srhash_type = SRHASH_PCXST; + break; + + case pcxl: + srhash_type = SRHASH_PCXL; + break; + + case pcxl2: /* pcxl2 doesn't support space register hashing */ + return; + + default: /* Currently all PA2.0 machines use the same ins. sequence */ + srhash_type = SRHASH_PA20; + break; + } - switch (boot_cpu_data.cpu_type) { - - case pcx: - BUG(); /* We shouldn't get here. code in setup.c should prevent it */ - return; + disable_sr_hashing_asm(srhash_type); +} - case pcxs: - case pcxt: - case pcxt_: - srhash_type = SRHASH_PCXST; - break; +void __flush_dcache_page(struct page *page) +{ + struct mm_struct *mm = current->active_mm; + struct vm_area_struct *mpnt; - case pcxl: - srhash_type = SRHASH_PCXL; - break; + flush_kernel_dcache_page(page_address(page)); - default: /* Currently all PA2.0 machines use the same ins. sequence */ - srhash_type = SRHASH_PA20; - break; - } + if (!page->mapping) + return; - disable_sr_hashing_asm(srhash_type); + for (mpnt = page->mapping->i_mmap_shared; + mpnt != NULL; + mpnt = mpnt->vm_next_share) + { + unsigned long off; + + /* + * If this VMA is not in our MM, we can ignore it. + */ + if (mpnt->vm_mm != mm) + continue; + + if (page->index < mpnt->vm_pgoff) + continue; + + off = page->index - mpnt->vm_pgoff; + if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT) + continue; + + flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT)); + + /* All user shared mappings should be equivalently mapped, + * so once we've flushed one we should be ok + */ + break; + } } + diff -urN linux-2.4.21/arch/parisc/kernel/ccio-dma.c linux-2.4.22/arch/parisc/kernel/ccio-dma.c --- linux-2.4.21/arch/parisc/kernel/ccio-dma.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/ccio-dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -805,7 +805,7 @@ DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", nents, (unsigned long)sg_dma_address(startsg), cnt, - startsg->address, startsg->length + sg_virt_addr(startsg), startsg->length ); /* @@ -825,7 +825,7 @@ ** Look for a VCONTIG chunk */ if (cnt) { - unsigned long vaddr = (unsigned long)startsg->address; + unsigned long vaddr = (unsigned long) sg_virt_addr(startsg); ASSERT(pdirp); /* Since multiple Vcontig blocks could make up @@ -878,8 +878,8 @@ */ dma_sg = vcontig_sg = startsg; dma_len = vcontig_len = vcontig_end = startsg->length; - vcontig_end += (unsigned long) startsg->address; - dma_offset = (unsigned long) startsg->address & ~IOVP_MASK; + vcontig_end += (unsigned long) sg_virt_addr(startsg); + dma_offset = (unsigned long) sg_virt_addr(startsg) & ~IOVP_MASK; /* PARANOID: clear entries */ sg_dma_address(startsg) = 0; @@ -893,7 +893,7 @@ unsigned long startsg_end; startsg++; - startsg_end = (unsigned long)startsg->address + + startsg_end = (unsigned long) sg_virt_addr(startsg) + startsg->length; /* PARANOID: clear entries */ @@ -912,7 +912,7 @@ /* ** Append the next transaction? */ - if(vcontig_end == (unsigned long) startsg->address) { + if(vcontig_end == (unsigned long) sg_virt_addr(startsg)) { vcontig_len += startsg->length; vcontig_end += startsg->length; dma_len += startsg->length; @@ -981,7 +981,8 @@ /* Fast path single entry scatterlists. */ if(nents == 1) { - sg_dma_address(sglist)= ccio_map_single(dev, sglist->address, + sg_dma_address(sglist)= ccio_map_single(dev, + sg_virt_addr(sglist), sglist->length, direction); sg_dma_len(sglist)= sglist->length; @@ -1043,7 +1044,7 @@ ioc = GET_IOC(dev); DBG_RUN_SG("%s() START %d entries, %p,%x\n", - __FUNCTION__, nents, sglist->address, sglist->length); + __FUNCTION__, nents, sg_virt_address(sglist), sglist->length); #ifdef CONFIG_PROC_FS ioc->usg_calls++; diff -urN linux-2.4.21/arch/parisc/kernel/ccio-rm-dma.c linux-2.4.22/arch/parisc/kernel/ccio-rm-dma.c --- linux-2.4.21/arch/parisc/kernel/ccio-rm-dma.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/ccio-rm-dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -118,7 +118,7 @@ /* KISS: map each buffer seperately. */ while (nents) { - sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction); + sg_dma_address(sglist) = ccio_map_single(dev, sg_virt_addr(sglist), sglist->length, direction); sg_dma_len(sglist) = sglist->length; nents--; sglist++; diff -urN linux-2.4.21/arch/parisc/kernel/drivers.c linux-2.4.22/arch/parisc/kernel/drivers.c --- linux-2.4.21/arch/parisc/kernel/drivers.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/drivers.c 2003-08-25 04:44:40.000000000 -0700 @@ -9,6 +9,7 @@ * Copyright (c) 1999 The Puffin Group * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard * Copyright (c) 2001 Helge Deller + * Copyright (c) 2001,2002 Ryan Bradetich * * The file handles registering devices and drivers, then matching them. * It's the closest we get to a dating agency. @@ -23,7 +24,6 @@ #include #include #include -#include /* See comments in include/asm-parisc/pci.h */ struct pci_dma_ops *hppa_dma_ops; @@ -416,6 +416,7 @@ dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) | (iodc_data[5] << 8) | iodc_data[6]; dev->hpa = hpa; + name = parisc_hardware_description(&dev->id); if (name) { strncpy(dev->name, name, sizeof(dev->name)-1); @@ -461,30 +462,26 @@ #define BC_PORT_MASK 0x8 #define BC_LOWER_PORT 0x8 +#define IO_STATUS offsetof(struct bc_module, io_status) + #define BUS_CONVERTER(dev) \ ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT)) #define IS_LOWER_PORT(dev) \ - ((gsc_readl(&((struct bc_module *)dev->hpa)->io_status) \ - & BC_PORT_MASK) == BC_LOWER_PORT) - -#define READ_IO_IO_LOW(dev) \ - (dev->id.hw_type == HPHW_IOA ? \ - __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low) << 16 : \ - __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low)) - -#define READ_IO_IO_HIGH(dev) \ - (dev->id.hw_type == HPHW_IOA ? \ - __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_high) << 16 : \ - __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_high)) + ((__raw_readl(dev->hpa + IO_STATUS) & BC_PORT_MASK) == BC_LOWER_PORT) +#define MAX_NATIVE_DEVICES 64 +#define NATIVE_DEVICE_OFFSET 0x1000 -static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, - struct parisc_device *parent); - -#define FLEX_MASK (unsigned long)0xfffffffffffc0000 +#define FLEX_MASK (unsigned long)0xfffffffffffc0000 +#define IO_IO_LOW offsetof(struct bc_module, io_io_low) +#define IO_IO_HIGH offsetof(struct bc_module, io_io_high) +#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_LOW) +#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_HIGH) +static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, + struct parisc_device *parent); void walk_lower_bus(struct parisc_device *dev) { @@ -493,15 +490,17 @@ if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev)) return; - io_io_low = ((unsigned long)(signed int)READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK; - io_io_high = ((unsigned long)(signed int)READ_IO_IO_HIGH(dev) + ~FLEX_MASK) & FLEX_MASK; + if(dev->id.hw_type == HPHW_IOA) { + io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16); + io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET; + } else { + io_io_low = (READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK; + io_io_high = (READ_IO_IO_HIGH(dev)+ ~FLEX_MASK) & FLEX_MASK; + } walk_native_bus(io_io_low, io_io_high, dev); } -#define MAX_NATIVE_DEVICES 64 -#define NATIVE_DEVICE_OFFSET 0x1000 - /** * walk_native_bus -- Probe a bus for devices * @io_io_low: Base address of this bus. @@ -515,7 +514,7 @@ * keyboard ports). This problem is not yet solved. */ static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, - struct parisc_device *parent) + struct parisc_device *parent) { int i, devices_found = 0; unsigned long hpa = io_io_low; @@ -523,7 +522,7 @@ get_node_path(parent, &path); do { - for (i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) { + for(i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) { struct parisc_device *dev; /* Was the device already added by Firmware? */ @@ -539,7 +538,7 @@ } walk_lower_bus(dev); } - } while (!devices_found && hpa < io_io_high); + } while(!devices_found && hpa < io_io_high); } #define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000 @@ -552,7 +551,7 @@ */ void walk_central_bus(void) { - walk_native_bus(CENTRAL_BUS_ADDR, + walk_native_bus(CENTRAL_BUS_ADDR, CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET), &root); } diff -urN linux-2.4.21/arch/parisc/kernel/entry.S linux-2.4.22/arch/parisc/kernel/entry.S --- linux-2.4.21/arch/parisc/kernel/entry.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -927,11 +927,11 @@ ldo -16(%r30),%r29 /* Reference param save area */ #endif - ldil L%intr_restore, %r2 + ldil L%intr_check_sig, %r2 copy %r25, %r16 /* save pt_regs */ b handle_interruption - ldo R%intr_restore(%r2), %r2 + ldo R%intr_check_sig(%r2), %r2 /* diff -urN linux-2.4.21/arch/parisc/kernel/hardware.c linux-2.4.22/arch/parisc/kernel/hardware.c --- linux-2.4.21/arch/parisc/kernel/hardware.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/kernel/hardware.c 2003-08-25 04:44:40.000000000 -0700 @@ -99,8 +99,8 @@ {HPHW_NPROC,0x481,0x4,0x81,"Wilbur (E25)"}, {HPHW_NPROC,0x482,0x4,0x81,"WB-80 (E35)"}, {HPHW_NPROC,0x483,0x4,0x81,"WB-96 (E45)"}, - {HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-100 (811/D210,D310)"}, - {HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-75 (801/D200)"}, + {HPHW_NPROC,0x484,0x4,0x81,"UL Proc L-100 (811/D210,D310)"}, + {HPHW_NPROC,0x485,0x4,0x81,"UL Proc L-75 (801/D200)"}, {HPHW_NPROC,0x501,0x4,0x81,"Merlin L2 132 (9000/778/B132L)"}, {HPHW_NPROC,0x502,0x4,0x81,"Merlin L2 160 (9000/778/B160L)"}, {HPHW_NPROC,0x503,0x4,0x81,"Merlin L2+ 132 (9000/778/B132L)"}, @@ -403,7 +403,7 @@ {HPHW_BA, 0x01B, 0x00078, 0x0, "Anole 100 VME BA"}, {HPHW_BA, 0x024, 0x00078, 0x0, "Fast Pace VME BA"}, {HPHW_BA, 0x034, 0x00078, 0x0, "Anole T VME BA"}, - {HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 BME BA"}, + {HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 VME BA"}, {HPHW_BA, 0x04C, 0x00078, 0x0, "Anole L2 165 VME BA"}, {HPHW_BA, 0x011, 0x00081, 0x0, "WB-96 Core BA"}, {HPHW_BA, 0x012, 0x00081, 0x0, "Orville UX Core BA"}, @@ -805,8 +805,8 @@ {HPHW_FIO, 0x04E, 0x0007B, 0x0, "Kiji L2 132 Core Audio"}, {HPHW_FIO, 0x050, 0x0007B, 0x0, "Merlin Jr 132 Core Audio"}, {HPHW_FIO, 0x051, 0x0007B, 0x0, "Firehawk Audio"}, - {HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSU Core Audio"}, - {HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSU Core Audio"}, + {HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSI Core Audio"}, + {HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSI Core Audio"}, {HPHW_FIO, 0x058, 0x0007B, 0x0, "FireHawk 200 Audio"}, {HPHW_FIO, 0x05C, 0x0007B, 0x0, "SummitHawk 230 Core Audio"}, {HPHW_FIO, 0x800, 0x0007B, 0x0, "Hitachi Tiny 64 Audio"}, diff -urN linux-2.4.21/arch/parisc/kernel/head.S linux-2.4.22/arch/parisc/kernel/head.S --- linux-2.4.21/arch/parisc/kernel/head.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -74,7 +74,7 @@ ldo R%PA(_end)(%r4),%r4 $bss_loop: cmpb,<<,n %r3,%r4,$bss_loop - stb,ma %r0,1(%r3) + stw,ma %r0,4(%r3) /* Save away the arguments the boot loader passed in (32 bit args) */ diff -urN linux-2.4.21/arch/parisc/kernel/ioctl32.c linux-2.4.22/arch/parisc/kernel/ioctl32.c --- linux-2.4.21/arch/parisc/kernel/ioctl32.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/ioctl32.c 2003-08-25 04:44:40.000000000 -0700 @@ -3123,6 +3123,11 @@ COMPATIBLE_IOCTL(SIOCDRARP) COMPATIBLE_IOCTL(SIOCADDDLCI) COMPATIBLE_IOCTL(SIOCDELDLCI) +COMPATIBLE_IOCTL(SIOCGMIIPHY) +COMPATIBLE_IOCTL(SIOCGMIIREG) +COMPATIBLE_IOCTL(SIOCSMIIREG) +COMPATIBLE_IOCTL(SIOCGIFVLAN) +COMPATIBLE_IOCTL(SIOCSIFVLAN) /* SG stuff */ COMPATIBLE_IOCTL(SG_SET_TIMEOUT) COMPATIBLE_IOCTL(SG_GET_TIMEOUT) diff -urN linux-2.4.21/arch/parisc/kernel/irq.c linux-2.4.22/arch/parisc/kernel/irq.c --- linux-2.4.21/arch/parisc/kernel/irq.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -57,7 +57,7 @@ /* Bits in EIEM correlate with cpu_irq_action[]. ** Numbered *Big Endian*! (ie bit 0 is MSB) */ -static unsigned long cpu_eiem = 0; +static volatile unsigned long cpu_eiem = 0; static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; /* protect IRQ regions */ @@ -462,7 +462,7 @@ for (irq = 0; eirr_val && bit; bit>>=1, irq++) { - if (!(bit&eirr_val)) + if (!(bit&eirr_val&cpu_eiem)) continue; /* clear bit in mask - can exit loop sooner */ diff -urN linux-2.4.21/arch/parisc/kernel/parisc_ksyms.c linux-2.4.22/arch/parisc/kernel/parisc_ksyms.c --- linux-2.4.21/arch/parisc/kernel/parisc_ksyms.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/parisc_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -67,6 +67,7 @@ #include EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(smp_call_function); #endif /* CONFIG_SMP */ #include @@ -127,7 +128,13 @@ #include EXPORT_SYMBOL(flush_kernel_dcache_range_asm); EXPORT_SYMBOL(flush_kernel_dcache_page); -EXPORT_SYMBOL(flush_all_caches); + +/* asm/pgalloc.h doesn't include all it's dependencies */ +extern void __flush_dcache_page(struct page *page); +EXPORT_SYMBOL(__flush_dcache_page); + +extern void flush_cache_all_local(void); +EXPORT_SYMBOL(flush_cache_all_local); #include extern long sys_open(const char *, int, int); @@ -150,6 +157,8 @@ #include EXPORT_SYMBOL(pdc_add_valid); +EXPORT_SYMBOL(pdc_tod_read); +EXPORT_SYMBOL(pdc_tod_set); EXPORT_SYMBOL(pdc_lan_station_id); EXPORT_SYMBOL(pdc_get_initiator); diff -urN linux-2.4.21/arch/parisc/kernel/pci-dma.c linux-2.4.22/arch/parisc/kernel/pci-dma.c --- linux-2.4.21/arch/parisc/kernel/pci-dma.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/kernel/pci-dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -428,9 +428,9 @@ BUG(); for (i = 0; i < nents; i++, sglist++ ) { - sg_dma_address(sglist) = (dma_addr_t) virt_to_phys(sglist->address); + sg_dma_address(sglist) = (dma_addr_t) virt_to_phys(sg_virt_addr(sglist)); sg_dma_len(sglist) = sglist->length; - flush_kernel_dcache_range((unsigned long)sglist->address, + flush_kernel_dcache_range((unsigned long)sg_virt_addr(sglist), sglist->length); } return nents; @@ -449,7 +449,7 @@ /* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */ for (i = 0; i < nents; i++, sglist++ ) - flush_kernel_dcache_range((unsigned long) sglist->address, sglist->length); + flush_kernel_dcache_range((unsigned long) sg_virt_addr(sglist), sglist->length); return; } @@ -468,7 +468,7 @@ /* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */ for (i = 0; i < nents; i++, sglist++ ) - flush_kernel_dcache_range((unsigned long) sglist->address, sglist->length); + flush_kernel_dcache_range((unsigned long) sg_virt_addr(sglist), sglist->length); } struct pci_dma_ops pcxl_dma_ops = { diff -urN linux-2.4.21/arch/parisc/kernel/perf.c linux-2.4.22/arch/parisc/kernel/perf.c --- linux-2.4.21/arch/parisc/kernel/perf.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/kernel/perf.c 2003-08-25 04:44:40.000000000 -0700 @@ -499,6 +499,8 @@ */ static int __init perf_init(void) { + int ret; + /* Determine correct processor interface to use */ bitmask_array = perf_bitmasks; @@ -517,11 +519,17 @@ return -ENODEV; } + ret = misc_register(&perf_dev); + if (ret) { + printk(KERN_ERR "Performance monitoring counters: " + "cannot register misc device.\n"); + return ret; + } + /* Patch the images to match the system */ perf_patch_images(); spin_lock_init(&perf_lock); - misc_register(&perf_dev); /* TODO: this only lets us access the first cpu.. what to do for SMP? */ cpu_device = cpu_data[0].dev; diff -urN linux-2.4.21/arch/parisc/kernel/processor.c linux-2.4.22/arch/parisc/kernel/processor.c --- linux-2.4.21/arch/parisc/kernel/processor.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/processor.c 2003-08-25 04:44:40.000000000 -0700 @@ -77,8 +77,6 @@ unsigned long txn_addr; unsigned long cpuid; struct cpuinfo_parisc *p; - extern struct irq_region_ops cpu_irq_ops; /* arch/parisc...irq.c */ - extern struct irqaction cpu_irq_actions[]; /* arch/parisc...irq.c */ #ifndef CONFIG_SMP if (boot_cpu_data.cpu_count > 0) { diff -urN linux-2.4.21/arch/parisc/kernel/sba_iommu.c linux-2.4.22/arch/parisc/kernel/sba_iommu.c --- linux-2.4.21/arch/parisc/kernel/sba_iommu.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/sba_iommu.c 2003-08-25 04:44:40.000000000 -0700 @@ -1056,7 +1056,7 @@ printk(KERN_DEBUG " %2d : %08lx/%05x %p/%05x\n", nents, (unsigned long) sg_dma_address(startsg), cnt, - sg_virt_address(startsg), startsg->length + sg_virt_addr(startsg), startsg->length ); #else DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", diff -urN linux-2.4.21/arch/parisc/kernel/smp.c linux-2.4.22/arch/parisc/kernel/smp.c --- linux-2.4.21/arch/parisc/kernel/smp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/kernel/smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -434,25 +435,21 @@ extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */ /* Set modes and Enable floating point coprocessor */ - (void) init_per_cpu(cpunum); + init_per_cpu(cpunum); disable_sr_hashing(); - mb(); /* Well, support 2.4 linux scheme as well. */ - if (test_and_set_bit(cpunum, (unsigned long *) (&cpu_online_map))) - { - extern void machine_halt(void); /* arch/parisc.../process.c */ - + if (test_and_set_bit(cpunum, (unsigned long *) (&cpu_online_map))) { printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); machine_halt(); - } + } /* Initialise the idle task for this CPU */ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - if(current->mm) + if (current->mm) BUG(); enter_lazy_tlb(&init_mm, current, cpunum); diff -urN linux-2.4.21/arch/parisc/kernel/traps.c linux-2.4.22/arch/parisc/kernel/traps.c --- linux-2.4.21/arch/parisc/kernel/traps.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -455,13 +455,6 @@ unsigned long fault_space = 0; struct siginfo si; - /* HACK! jsm is going to fix this. - * entry.S will manage I-bit - only enable I-bit if it was - * enabled before we took the "trap". - */ - if (code != 1) - local_irq_enable(); - switch(code) { case 1: @@ -727,6 +720,7 @@ } } + local_irq_enable(); do_page_fault(regs, code, fault_address); } diff -urN linux-2.4.21/arch/parisc/kernel/unaligned.c linux-2.4.22/arch/parisc/kernel/unaligned.c --- linux-2.4.21/arch/parisc/kernel/unaligned.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/parisc/kernel/unaligned.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,6 +3,7 @@ * Unaligned memory access handler * * Copyright (C) 2001 Randolph Chung + * Significantly tweaked by LaMont Jones * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,28 +67,28 @@ #define OPCODE3_MASK OPCODE3(0x3f,1) #define OPCODE4_MASK OPCODE4(0x3f) -/* skip LDB (index) */ +/* skip LDB - never unaligned (index) */ #define OPCODE_LDH_I OPCODE1(0x03,0,0x1) #define OPCODE_LDW_I OPCODE1(0x03,0,0x2) #define OPCODE_LDD_I OPCODE1(0x03,0,0x3) #define OPCODE_LDDA_I OPCODE1(0x03,0,0x4) -/* skip LDCD (index) */ +#define OPCODE_LDCD_I OPCODE1(0x03,0,0x5) #define OPCODE_LDWA_I OPCODE1(0x03,0,0x6) -/* skip LDCW (index) */ -/* skip LDB (short) */ +#define OPCODE_LDCW_I OPCODE1(0x03,0,0x7) +/* skip LDB - never unaligned (short) */ #define OPCODE_LDH_S OPCODE1(0x03,1,0x1) #define OPCODE_LDW_S OPCODE1(0x03,1,0x2) #define OPCODE_LDD_S OPCODE1(0x03,1,0x3) #define OPCODE_LDDA_S OPCODE1(0x03,1,0x4) -/* skip LDCD (short) */ +#define OPCODE_LDCD_S OPCODE1(0x03,1,0x5) #define OPCODE_LDWA_S OPCODE1(0x03,1,0x6) -/* skip LDCW (short) */ -/* skip STB */ +#define OPCODE_LDCW_S OPCODE1(0x03,1,0x7) +/* skip STB - never unaligned */ #define OPCODE_STH OPCODE1(0x03,1,0x9) #define OPCODE_STW OPCODE1(0x03,1,0xa) #define OPCODE_STD OPCODE1(0x03,1,0xb) -/* skip STBY */ -/* skip STDBY */ +/* skip STBY - never unaligned */ +/* skip STDBY - never unaligned */ #define OPCODE_STWA OPCODE1(0x03,1,0xe) #define OPCODE_STDA OPCODE1(0x03,1,0xf) @@ -103,129 +104,200 @@ #define OPCODE_LDH_L OPCODE4(0x11) #define OPCODE_LDW_L OPCODE4(0x12) -#define OPCODE_LDW_L2 OPCODE4(0x13) +#define OPCODE_LDWM OPCODE4(0x13) #define OPCODE_STH_L OPCODE4(0x19) #define OPCODE_STW_L OPCODE4(0x1A) -#define OPCODE_STW_L2 OPCODE4(0x1B) +#define OPCODE_STWM OPCODE4(0x1B) + +#define MAJOR_OP(i) (((i)>>26)&0x3f) +#define R1(i) (((i)>>21)&0x1f) +#define R2(i) (((i)>>16)&0x1f) +#define R3(i) ((i)&0x1f) +#define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0)) +#define IM5_2(i) IM((i)>>16,5) +#define IM5_3(i) IM((i),5) +#define IM14(i) IM((i),14) int unaligned_enabled = 1; void die_if_kernel (char *str, struct pt_regs *regs, long err); -static int emulate_load(struct pt_regs *regs, int len, int toreg) +static int emulate_ldh(struct pt_regs *regs, int toreg) { unsigned long saddr = regs->ior; unsigned long val = 0; - int ret = 0; - if (regs->isr != regs->sr[7]) - { - printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n", - regs->isr, regs->sr[7]); - return 1; - } + DPRINTF("load " RFMT ":" RFMT " to r%d for 2 bytes\n", + regs->isr, regs->ior, toreg); + + __asm__ __volatile__ ( +" mtsp %3, %%sr1\n" +" ldbs 0(%%sr1,%2), %%r20\n" +" ldbs 1(%%sr1,%2), %0\n" + "depw %%r20, 23, 24, %0\n" + : "=r" (val) + : "0" (val), "r" (saddr), "r" (regs->isr) + : "r20" ); + + DPRINTF("val = 0x" RFMT "\n", val); + + if (toreg) + regs->gr[toreg] = val; + + return 0; +} +static int emulate_ldw(struct pt_regs *regs, int toreg) +{ + unsigned long saddr = regs->ior; + unsigned long val = 0; - DPRINTF("load " RFMT ":" RFMT " to r%d for %d bytes\n", - regs->isr, regs->ior, toreg, len); + DPRINTF("load " RFMT ":" RFMT " to r%d for 4 bytes\n", + regs->isr, regs->ior, toreg); __asm__ __volatile__ ( -" mfsp %%sr1, %%r20\n" -" mtsp %6, %%sr1\n" -" copy %%r0, %0\n" -"0: ldbs,ma 1(%%sr1,%4), %%r19\n" -" addi -1, %5, %5\n" -" cmpib,>= 0, %5, 2f\n" -" or %%r19, %0, %0\n" -" b 0b\n" - -#ifdef __LP64__ - "depd,z %0, 55, 56, %0\n" -#else - "depw,z %0, 23, 24, %0\n" -#endif - -"1: ldi 10, %1\n" -"2: mtsp %%r20, %%sr1\n" -" .section __ex_table,\"a\"\n" +" zdep %2,28,2,%%r19\n" /* r19=(ofs&3)*8 */ +" mtsp %3, %%sr1\n" +" depw %%r0,31,2,%2\n" +" ldw 0(%%sr1,%2),%0\n" +" ldw 4(%%sr1,%2),%%r20\n" +" subi 32,%%r19,%%r19\n" +" mtctl %%r19,11\n" +" vshd %0,%%r20,%0\n" + : "=r" (val) + : "0" (val), "r" (saddr), "r" (regs->isr) + : "r19", "r20" ); + + DPRINTF("val = 0x" RFMT "\n", val); + + if (toreg) + regs->gr[toreg] = val; + + return 0; +} #ifdef __LP64__ - ".dword 0b, (1b-0b)\n" -#else - ".word 0b, (1b-0b)\n" -#endif - ".previous\n" - : "=r" (val), "=r" (ret) - : "0" (val), "1" (ret), "r" (saddr), "r" (len), "r" (regs->isr) +static int emulate_ldd(struct pt_regs *regs, int toreg) +{ + unsigned long saddr = regs->ior; + unsigned long val = 0; + + DPRINTF("load " RFMT ":" RFMT " to r%d for 8 bytes\n", + regs->isr, regs->ior, toreg); + + __asm__ __volatile__ ( +" depd,z %2,60,3,%%r19\n" /* r19=(ofs&7)*8 */ +" mtsp %3, %%sr1\n" +" depd %%r0,63,3,%2\n" +" ldd 0(%%sr1,%2),%0\n" +" ldd 8(%%sr1,%2),%%r20\n" +" subi 64,%%r19,%%r19\n" +" mtsar %%r19\n" +" shrpd %0,%%r20,%%sar,%0\n" + : "=r" (val) + : "0" (val), "r" (saddr), "r" (regs->isr) : "r19", "r20" ); DPRINTF("val = 0x" RFMT "\n", val); - regs->gr[toreg] = val; + if (toreg) + regs->gr[toreg] = val; - return ret; + return 0; } +#endif -static int emulate_store(struct pt_regs *regs, int len, int frreg) +static int emulate_sth(struct pt_regs *regs, int frreg) { - int ret = 0; -#ifdef __LP64__ - unsigned long val = regs->gr[frreg] << (64 - (len << 3)); -#else - unsigned long val = regs->gr[frreg] << (32 - (len << 3)); -#endif + unsigned long val = regs->gr[frreg]; + if (!frreg) + val = 0; - if (regs->isr != regs->sr[7]) - { - printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n", - regs->isr, regs->sr[7]); - return 1; - } + DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 2 bytes\n", frreg, + regs->gr[frreg], regs->isr, regs->ior); + + __asm__ __volatile__ ( +" mtsp %2, %%sr1\n" +" extrw,u %0, 23, 8, %%r19\n" +" stb %0, 1(%%sr1, %1)\n" +" stb %%r19, 0(%%sr1, %1)\n" + : + : "r" (val), "r" (regs->ior), "r" (regs->isr) + : "r19" ); + + return 0; +} +static int emulate_stw(struct pt_regs *regs, int frreg) +{ + unsigned long val = regs->gr[frreg]; + if (!frreg) + val = 0; - DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for %d bytes\n", frreg, - regs->gr[frreg], regs->isr, regs->ior, len); + DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 4 bytes\n", frreg, + regs->gr[frreg], regs->isr, regs->ior); __asm__ __volatile__ ( -" mfsp %%sr1, %%r20\n" /* save sr1 */ -" mtsp %5, %%sr1\n" -#ifdef __LP64__ -"0: extrd,u %2, 7, 8, %%r19\n" -#else -"0: extrw,u %2, 7, 8, %%r19\n" -#endif -"1: stb,ma %%r19, 1(%%sr1, %3)\n" -" addi -1, %4, %4\n" -" cmpib,>= 0, %4, 3f\n" - +" mtsp %2, %%sr1\n" +" zdep %1, 28, 2, %%r19\n" +" dep %%r0, 31, 2, %1\n" +" mtsar %%r19\n" +" depwi,z -2, %%sar, 32, %%r19\n" +" ldw 0(%%sr1,%1),%%r20\n" +" ldw 4(%%sr1,%1),%%r21\n" +" vshd %%r0, %0, %%r22\n" +" vshd %0, %%r0, %%r1\n" +" and %%r20, %%r19, %%r20\n" +" andcm %%r21, %%r19, %%r21\n" +" or %%r22, %%r20, %%r20\n" +" or %%r1, %%r21, %%r21\n" +" stw %%r20,0(%%sr1,%1)\n" +" stw %%r21,4(%%sr1,%1)\n" + : + : "r" (val), "r" (regs->ior), "r" (regs->isr) + : "r19", "r20", "r21", "r22", "r1" ); + + return 0; +} #ifdef __LP64__ - "depd,z %2, 55, 56, %2\n" -#else - "depw,z %2, 23, 24, %2\n" -#endif +static int emulate_std(struct pt_regs *regs, int frreg) +{ + unsigned long val = regs->gr[frreg]; + if (!frreg) + val = 0; -" b 0b\n" -" nop\n" + DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 8 bytes\n", frreg, + regs->gr[frreg], regs->isr, regs->ior); -"2: ldi 11, %0\n" -"3: mtsp %%r20, %%sr1\n" -" .section __ex_table,\"a\"\n" -#ifdef __LP64__ - ".dword 1b, (2b-1b)\n" -#else - ".word 1b, (2b-1b)\n" -#endif - ".previous\n" - : "=r" (ret) - : "0" (ret), "r" (val), "r" (regs->ior), "r" (len), "r" (regs->isr) - : "r19", "r20" ); - return ret; -} + __asm__ __volatile__ ( +" mtsp %2, %%sr1\n" +" depd,z %1, 60, 3, %%r19\n" +" depd %%r0, 63, 3, %1\n" +" mtsar %%r19\n" +" depdi,z -2, %%sar, 64, %%r19\n" +" ldd 0(%%sr1,%1),%%r20\n" +" ldd 8(%%sr1,%1),%%r21\n" +" shrpd %%r0, %0, %%sar, %%r22\n" +" shrpd %0, %%r0, %%sar, %%r1\n" +" and %%r20, %%r19, %%r20\n" +" andcm %%r21, %%r19, %%r21\n" +" or %%r22, %%r20, %%r20\n" +" or %%r1, %%r21, %%r21\n" +" std %%r20,0(%%sr1,%1)\n" +" std %%r21,8(%%sr1,%1)\n" + : + : "r" (val), "r" (regs->ior), "r" (regs->isr) + : "r19", "r20", "r21", "r22", "r1" ); + return 0; +} +#endif void handle_unaligned(struct pt_regs *regs) { unsigned long unaligned_count = 0; unsigned long last_time = 0; + unsigned long newbase = regs->gr[R1(regs->iir)]; + int modify = 0; int ret = -1; struct siginfo si; @@ -284,83 +356,169 @@ if (!unaligned_enabled) goto force_sigbus; + /* handle modification - OK, it's ugly, see the instruction manual */ + switch (MAJOR_OP(regs->iir)) + { + case 0x03: + case 0x09: + case 0x0b: + if (regs->iir&0x20) + { + modify = 1; + if (regs->iir&0x1000) /* short loads */ + if (regs->iir&0x200) + newbase += IM5_3(regs->iir); + else + newbase += IM5_2(regs->iir); + else if (regs->iir&0x2000) /* scaled indexed */ + { + int shift=0; + switch (regs->iir & OPCODE1_MASK) + { + case OPCODE_LDH_I: + shift= 1; break; + case OPCODE_LDW_I: + shift= 2; break; + case OPCODE_LDD_I: + case OPCODE_LDDA_I: + shift= 3; break; + } + newbase += (R2(regs->iir)?regs->gr[R2(regs->iir)]:0)<iir)?regs->gr[R2(regs->iir)]:0); + } + break; + case 0x13: + case 0x1b: + modify = 1; + newbase += IM14(regs->iir); + break; + case 0x14: + case 0x1c: + if (regs->iir&8) + { + modify = 1; + newbase += IM14(regs->iir&~0xe); + } + break; + case 0x16: + case 0x1e: + modify = 1; + newbase += IM14(regs->iir&6); + break; + case 0x17: + case 0x1f: + if (regs->iir&4) + { + modify = 1; + newbase += IM14(regs->iir&~4); + } + break; + } + + if (regs->isr != regs->sr[7]) + { + printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n", + regs->isr, regs->sr[7]); + + /* don't kill him though, since he has appropriate access to the page, or we + * would never have gotten here. + */ + } + /* TODO: make this cleaner... */ switch (regs->iir & OPCODE1_MASK) { case OPCODE_LDH_I: case OPCODE_LDH_S: - ret = emulate_load(regs, 2, regs->iir & 0x1f); + ret = emulate_ldh(regs, R3(regs->iir)); break; case OPCODE_LDW_I: case OPCODE_LDWA_I: case OPCODE_LDW_S: case OPCODE_LDWA_S: - ret = emulate_load(regs, 4, regs->iir&0x1f); - break; - - case OPCODE_LDD_I: - case OPCODE_LDDA_I: - case OPCODE_LDD_S: - case OPCODE_LDDA_S: - ret = emulate_load(regs, 8, regs->iir&0x1f); + ret = emulate_ldw(regs, R3(regs->iir)); break; case OPCODE_STH: - ret = emulate_store(regs, 2, (regs->iir>>16)&0x1f); + ret = emulate_sth(regs, R2(regs->iir)); break; case OPCODE_STW: case OPCODE_STWA: - ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f); + ret = emulate_stw(regs, R2(regs->iir)); + break; + +#ifdef __LP64__ + case OPCODE_LDD_I: + case OPCODE_LDDA_I: + case OPCODE_LDD_S: + case OPCODE_LDDA_S: + ret = emulate_ldd(regs, R3(regs->iir)); break; case OPCODE_STD: case OPCODE_STDA: - ret = emulate_store(regs, 8, (regs->iir>>16)&0x1f); + ret = emulate_std(regs, R2(regs->iir)); + break; +#endif + + case OPCODE_LDCD_I: + case OPCODE_LDCW_I: + case OPCODE_LDCD_S: + case OPCODE_LDCW_S: + ret = -1; /* "undefined", but lets kill them. */ break; } +#ifdef __LP64__ switch (regs->iir & OPCODE2_MASK) { case OPCODE_LDD_L: case OPCODE_FLDD_L: - ret = emulate_load(regs, 8, (regs->iir>>16)&0x1f); + ret = emulate_ldd(regs, R2(regs->iir)); break; case OPCODE_STD_L: case OPCODE_FSTD_L: - ret = emulate_store(regs, 8, (regs->iir>>16)&0x1f); + ret = emulate_std(regs, R2(regs->iir)); break; } +#endif switch (regs->iir & OPCODE3_MASK) { case OPCODE_LDW_M: case OPCODE_FLDW_L: - ret = emulate_load(regs, 4, (regs->iir>>16)&0x1f); + ret = emulate_ldw(regs, R2(regs->iir)); break; case OPCODE_FSTW_L: case OPCODE_STW_M: - ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f); + ret = emulate_stw(regs, R2(regs->iir)); break; } switch (regs->iir & OPCODE4_MASK) { case OPCODE_LDH_L: - ret = emulate_load(regs, 2, (regs->iir>>16)&0x1f); + ret = emulate_ldh(regs, R2(regs->iir)); break; case OPCODE_LDW_L: - case OPCODE_LDW_L2: - ret = emulate_load(regs, 4, (regs->iir>>16)&0x1f); + case OPCODE_LDWM: + ret = emulate_ldw(regs, R2(regs->iir)); break; case OPCODE_STH_L: - ret = emulate_store(regs, 2, (regs->iir>>16)&0x1f); + ret = emulate_sth(regs, R2(regs->iir)); break; case OPCODE_STW_L: - case OPCODE_STW_L2: - ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f); + case OPCODE_STWM: + ret = emulate_stw(regs, R2(regs->iir)); break; } + /* XXX LJ - need to handle float load/store */ + + if (modify && R1(regs->iir)) + regs->gr[R1(regs->iir)] = newbase; + if (ret < 0) printk(KERN_CRIT "Not-handled unaligned insn 0x%08lx\n", regs->iir); @@ -424,9 +582,9 @@ align_mask = 1UL; break; case OPCODE_LDW_L: - case OPCODE_LDW_L2: + case OPCODE_LDWM: case OPCODE_STW_L: - case OPCODE_STW_L2: + case OPCODE_STWM: align_mask = 3UL; break; } diff -urN linux-2.4.21/arch/parisc/math-emu/dfadd.c linux-2.4.22/arch/parisc/math-emu/dfadd.c --- linux-2.4.21/arch/parisc/math-emu/dfadd.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/dfadd.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfadd.c $Revision: 1.1 $ + * @(#) pa/spmath/dfadd.c $Revision: $ * * Purpose: * Double_add: add two double precision values. diff -urN linux-2.4.21/arch/parisc/math-emu/dfcmp.c linux-2.4.22/arch/parisc/math-emu/dfcmp.c --- linux-2.4.21/arch/parisc/math-emu/dfcmp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/dfcmp.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfcmp.c $Revision: 1.1 $ + * @(#) pa/spmath/dfcmp.c $Revision: $ * * Purpose: * dbl_cmp: compare two values diff -urN linux-2.4.21/arch/parisc/math-emu/dfdiv.c linux-2.4.22/arch/parisc/math-emu/dfdiv.c --- linux-2.4.21/arch/parisc/math-emu/dfdiv.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/dfdiv.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfdiv.c $Revision: 1.1 $ + * @(#) pa/spmath/dfdiv.c $Revision: $ * * Purpose: * Double Precision Floating-point Divide diff -urN linux-2.4.21/arch/parisc/math-emu/dfmpy.c linux-2.4.22/arch/parisc/math-emu/dfmpy.c --- linux-2.4.21/arch/parisc/math-emu/dfmpy.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/dfmpy.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfmpy.c $Revision: 1.1 $ + * @(#) pa/spmath/dfmpy.c $Revision: $ * * Purpose: * Double Precision Floating-point Multiply diff -urN linux-2.4.21/arch/parisc/math-emu/dfrem.c linux-2.4.22/arch/parisc/math-emu/dfrem.c --- linux-2.4.21/arch/parisc/math-emu/dfrem.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/dfrem.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfrem.c $Revision: 1.1 $ + * @(#) pa/spmath/dfrem.c $Revision: $ * * Purpose: * Double Precision Floating-point Remainder diff -urN linux-2.4.21/arch/parisc/math-emu/dfsqrt.c linux-2.4.22/arch/parisc/math-emu/dfsqrt.c --- linux-2.4.21/arch/parisc/math-emu/dfsqrt.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/dfsqrt.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfsqrt.c $Revision: 1.1 $ + * @(#) pa/spmath/dfsqrt.c $Revision: $ * * Purpose: * Double Floating-point Square Root diff -urN linux-2.4.21/arch/parisc/math-emu/dfsub.c linux-2.4.22/arch/parisc/math-emu/dfsub.c --- linux-2.4.21/arch/parisc/math-emu/dfsub.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/dfsub.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/dfsub.c $Revision: 1.1 $ + * @(#) pa/spmath/dfsub.c $Revision: $ * * Purpose: * Double_subtract: subtract two double precision values. diff -urN linux-2.4.21/arch/parisc/math-emu/driver.c linux-2.4.22/arch/parisc/math-emu/driver.c --- linux-2.4.21/arch/parisc/math-emu/driver.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/driver.c 2003-08-25 04:44:40.000000000 -0700 @@ -80,14 +80,19 @@ int handle_fpe(struct pt_regs *regs) { - extern void printbinary(unsigned long x, int nbits); + extern int printbinary(char *buf, unsigned long x, int nbits); struct siginfo si; unsigned int orig_sw, sw; int signalcode; + char buf[128]; /* need an intermediate copy of float regs because FPU emulation * code expects an artificial last entry which contains zero + * + * also, the passed in fr registers contain one word that defines + * the fpu type. the fpu type information is constructed + * inside the emulation code */ - __u64 frcopy[33]; + __u64 frcopy[36]; memcpy(frcopy, regs->fr, sizeof regs->fr); frcopy[32] = 0; @@ -96,8 +101,8 @@ if (FPUDEBUG) { printk(KERN_DEBUG "FP VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI ->\n "); - printbinary(orig_sw, 32); - printk(KERN_DEBUG "\n"); + printbinary(buf, orig_sw, 32); + printk(KERN_DEBUG "%s\n", buf); } signalcode = decode_fpu(frcopy, 0x666); @@ -107,8 +112,8 @@ if (FPUDEBUG) { printk(KERN_DEBUG "VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI decode_fpu returns %d|0x%x\n", signalcode >> 24, signalcode & 0xffffff); - printbinary(sw, 32); - printk(KERN_DEBUG "\n"); + printbinary(buf, sw, 32); + printk(KERN_DEBUG "%s\n", buf); } memcpy(regs->fr, frcopy, sizeof regs->fr); diff -urN linux-2.4.21/arch/parisc/math-emu/fcnvff.c linux-2.4.22/arch/parisc/math-emu/fcnvff.c --- linux-2.4.21/arch/parisc/math-emu/fcnvff.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fcnvff.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvff.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvff.c $Revision: $ * * Purpose: * Single Floating-point to Double Floating-point diff -urN linux-2.4.21/arch/parisc/math-emu/fcnvfu.c linux-2.4.22/arch/parisc/math-emu/fcnvfu.c --- linux-2.4.21/arch/parisc/math-emu/fcnvfu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fcnvfu.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfu.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfu.c $Revision: $ * * Purpose: * Floating-point to Unsigned Fixed-point Converts diff -urN linux-2.4.21/arch/parisc/math-emu/fcnvfut.c linux-2.4.22/arch/parisc/math-emu/fcnvfut.c --- linux-2.4.21/arch/parisc/math-emu/fcnvfut.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fcnvfut.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfut.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfut.c $Revision: $ * * Purpose: * Floating-point to Unsigned Fixed-point Converts with Truncation diff -urN linux-2.4.21/arch/parisc/math-emu/fcnvfx.c linux-2.4.22/arch/parisc/math-emu/fcnvfx.c --- linux-2.4.21/arch/parisc/math-emu/fcnvfx.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fcnvfx.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfx.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfx.c $Revision: $ * * Purpose: * Single Floating-point to Single Fixed-point diff -urN linux-2.4.21/arch/parisc/math-emu/fcnvfxt.c linux-2.4.22/arch/parisc/math-emu/fcnvfxt.c --- linux-2.4.21/arch/parisc/math-emu/fcnvfxt.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fcnvfxt.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvfxt.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvfxt.c $Revision: $ * * Purpose: * Single Floating-point to Single Fixed-point /w truncated result diff -urN linux-2.4.21/arch/parisc/math-emu/fcnvuf.c linux-2.4.22/arch/parisc/math-emu/fcnvuf.c --- linux-2.4.21/arch/parisc/math-emu/fcnvuf.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fcnvuf.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvuf.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvuf.c $Revision: $ * * Purpose: * Fixed point to Floating-point Converts diff -urN linux-2.4.21/arch/parisc/math-emu/fcnvxf.c linux-2.4.22/arch/parisc/math-emu/fcnvxf.c --- linux-2.4.21/arch/parisc/math-emu/fcnvxf.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fcnvxf.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fcnvxf.c $Revision: 1.1 $ + * @(#) pa/spmath/fcnvxf.c $Revision: $ * * Purpose: * Single Fixed-point to Single Floating-point diff -urN linux-2.4.21/arch/parisc/math-emu/float.h linux-2.4.22/arch/parisc/math-emu/float.h --- linux-2.4.21/arch/parisc/math-emu/float.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/float.h 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/float.h $Revision: 1.2 $ + * @(#) pa/spmath/float.h $Revision: 1.1 $ * * Purpose: * <> diff -urN linux-2.4.21/arch/parisc/math-emu/fmpyfadd.c linux-2.4.22/arch/parisc/math-emu/fmpyfadd.c --- linux-2.4.21/arch/parisc/math-emu/fmpyfadd.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fmpyfadd.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/fmpyfadd.c $Revision: 1.1 $ + * @(#) pa/spmath/fmpyfadd.c $Revision: $ * * Purpose: * Double Floating-point Multiply Fused Add diff -urN linux-2.4.21/arch/parisc/math-emu/fpu.h linux-2.4.22/arch/parisc/math-emu/fpu.h --- linux-2.4.21/arch/parisc/math-emu/fpu.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fpu.h 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/fp/fpu.h $Revision: 1.2 $ + * @(#) pa/fp/fpu.h $Revision: $ * * Purpose: * <> diff -urN linux-2.4.21/arch/parisc/math-emu/fpudispatch.c linux-2.4.22/arch/parisc/math-emu/fpudispatch.c --- linux-2.4.21/arch/parisc/math-emu/fpudispatch.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/fpudispatch.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/fp/fpudispatch.c $Revision: 1.1 $ + * @(#) pa/fp/fpudispatch.c $Revision: $ * * Purpose: * <> @@ -51,6 +51,7 @@ #include "float.h" #include "types.h" +#include /* #include */ /* #include */ @@ -166,6 +167,20 @@ #define VASSERT(x) +static void parisc_linux_get_fpu_type(u_int fpregs[]) +{ + /* on pa-linux the fpu type is not filled in by the + * caller; it is constructed here + */ + if (boot_cpu_data.cpu_type == pcxs) + fpregs[FPU_TYPE_FLAG_POS] = TIMEX_EXTEN_FLAG; + else if (boot_cpu_data.cpu_type == pcxt || + boot_cpu_data.cpu_type == pcxt_) + fpregs[FPU_TYPE_FLAG_POS] = ROLEX_EXTEN_FLAG; + else if (boot_cpu_data.cpu_type >= pcxu) + fpregs[FPU_TYPE_FLAG_POS] = PA2_0_FPU_FLAG; +} + /* * this routine will decode the excepting floating point instruction and * call the approiate emulation routine. @@ -184,6 +199,8 @@ /* All FP emulation code assumes that ints are 4-bytes in length */ VASSERT(sizeof(int) == 4); + parisc_linux_get_fpu_type(fpregs); + fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS]; /* get fpu type flags */ class = get_class(ir); diff -urN linux-2.4.21/arch/parisc/math-emu/sfadd.c linux-2.4.22/arch/parisc/math-emu/sfadd.c --- linux-2.4.21/arch/parisc/math-emu/sfadd.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/sfadd.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfadd.c $Revision: 1.1 $ + * @(#) pa/spmath/sfadd.c $Revision: $ * * Purpose: * Single_add: add two single precision values. diff -urN linux-2.4.21/arch/parisc/math-emu/sfcmp.c linux-2.4.22/arch/parisc/math-emu/sfcmp.c --- linux-2.4.21/arch/parisc/math-emu/sfcmp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/sfcmp.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfcmp.c $Revision: 1.1 $ + * @(#) pa/spmath/sfcmp.c $Revision: $ * * Purpose: * sgl_cmp: compare two values diff -urN linux-2.4.21/arch/parisc/math-emu/sfdiv.c linux-2.4.22/arch/parisc/math-emu/sfdiv.c --- linux-2.4.21/arch/parisc/math-emu/sfdiv.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/sfdiv.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfdiv.c $Revision: 1.1 $ + * @(#) pa/spmath/sfdiv.c $Revision: $ * * Purpose: * Single Precision Floating-point Divide diff -urN linux-2.4.21/arch/parisc/math-emu/sfmpy.c linux-2.4.22/arch/parisc/math-emu/sfmpy.c --- linux-2.4.21/arch/parisc/math-emu/sfmpy.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/sfmpy.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfmpy.c $Revision: 1.1 $ + * @(#) pa/spmath/sfmpy.c $Revision: $ * * Purpose: * Single Precision Floating-point Multiply diff -urN linux-2.4.21/arch/parisc/math-emu/sfrem.c linux-2.4.22/arch/parisc/math-emu/sfrem.c --- linux-2.4.21/arch/parisc/math-emu/sfrem.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/sfrem.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfrem.c $Revision: 1.1 $ + * @(#) pa/spmath/sfrem.c $Revision: $ * * Purpose: * Single Precision Floating-point Remainder diff -urN linux-2.4.21/arch/parisc/math-emu/sfsqrt.c linux-2.4.22/arch/parisc/math-emu/sfsqrt.c --- linux-2.4.21/arch/parisc/math-emu/sfsqrt.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/sfsqrt.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfsqrt.c $Revision: 1.1 $ + * @(#) pa/spmath/sfsqrt.c $Revision: $ * * Purpose: * Single Floating-point Square Root diff -urN linux-2.4.21/arch/parisc/math-emu/sfsub.c linux-2.4.22/arch/parisc/math-emu/sfsub.c --- linux-2.4.21/arch/parisc/math-emu/sfsub.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.22/arch/parisc/math-emu/sfsub.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,7 +22,7 @@ * BEGIN_DESC * * File: - * @(#) pa/spmath/sfsub.c $Revision: 1.1 $ + * @(#) pa/spmath/sfsub.c $Revision: $ * * Purpose: * Single_subtract: subtract two single precision values. diff -urN linux-2.4.21/arch/ppc/8260_io/enet.c linux-2.4.22/arch/ppc/8260_io/enet.c --- linux-2.4.21/arch/ppc/8260_io/enet.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/8260_io/enet.c 2003-08-25 04:44:40.000000000 -0700 @@ -115,7 +115,7 @@ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ scc_t *sccp; struct net_device_stats stats; - uint tx_full; + uint tx_free; spinlock_t lock; }; @@ -175,9 +175,9 @@ bdp = cep->cur_tx; #ifndef final_version - if (bdp->cbd_sc & BD_ENET_TX_READY) { + if (!cep->tx_free || (bdp->cbd_sc & BD_ENET_TX_READY)) { /* Ooops. All transmit buffers are full. Bail out. - * This should not happen, since cep->tx_full should be set. + * This should not happen, since the tx queue should be stopped. */ printk("%s: tx queue full!.\n", dev->name); return 1; @@ -206,7 +206,7 @@ cep->stats.tx_bytes += skb->len; cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK; - + spin_lock_irq(&cep->lock); /* Send it on its way. Tell CPM its ready, interrupt when done, @@ -223,10 +223,8 @@ else bdp++; - if (bdp->cbd_sc & BD_ENET_TX_READY) { + if (!--cep->tx_free) netif_stop_queue(dev); - cep->tx_full = 1; - } cep->cur_tx = (cbd_t *)bdp; @@ -246,8 +244,8 @@ { int i; cbd_t *bdp; - printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n", - cep->cur_tx, cep->tx_full ? " (full)" : "", + printk(" Ring data dump: cur_tx %p tx_free %d cur_rx %p.\n", + cep->cur_tx, cep->tx_free, cep->cur_rx); bdp = cep->tx_bd_base; printk(" Tx @base %p :\n", bdp); @@ -265,7 +263,7 @@ bdp->cbd_bufaddr); } #endif - if (!cep->tx_full) + if (cep->tx_free) netif_wake_queue(dev); } @@ -309,7 +307,7 @@ spin_lock(&cep->lock); bdp = cep->dirty_tx; while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) { - if ((bdp==cep->cur_tx) && (cep->tx_full == 0)) + if (cep->tx_free == TX_RING_SIZE) break; if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ @@ -365,8 +363,7 @@ /* Since we have freed up a buffer, the ring is no longer * full. */ - if (cep->tx_full) { - cep->tx_full = 0; + if (!cep->tx_free++) { if (netif_queue_stopped(dev)) { netif_wake_queue(dev); } @@ -395,13 +392,10 @@ } /* Check for receive busy, i.e. packets coming but no place to - * put them. This "can't happen" because the receive interrupt - * is tossing previous frames. + * put them. */ - if (int_events & SCCE_ENET_BSY) { + if (int_events & SCCE_ENET_BSY) cep->stats.rx_dropped++; - printk("SCC ENET: BSY can't happen.\n"); - } return; } @@ -429,7 +423,7 @@ for (;;) { if (bdp->cbd_sc & BD_ENET_RX_EMPTY) break; - + #ifndef final_version /* Since we have allocated space to hold a complete frame, both * the first and last indicators should be set. @@ -549,7 +543,7 @@ ep = (scc_enet_t *)dev->base_addr; if (dev->flags&IFF_PROMISC) { - + /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); cep->sccp->scc_pmsr |= SCC_PSMR_PRO; @@ -576,8 +570,8 @@ dmi = dev->mc_list; - for (i=0; imc_count; i++) { - + for (i=0; imc_count; i++, dmi = dmi->next) { + /* Only support group multicast for now. */ if (!(dmi->dmi_addr[0] & 1)) @@ -664,7 +658,7 @@ (PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK); io->iop_pdirc &= ~(PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK); - io->iop_psorc &= + io->iop_psorc &= ~(PC_ENET_RENA | PC_ENET_TXCLK | PC_ENET_RXCLK); io->iop_psorc |= PC_ENET_CLSN; @@ -693,6 +687,7 @@ cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i]; cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; + cep->tx_free = TX_RING_SIZE; cep->cur_rx = cep->rx_bd_base; ep->sen_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; diff -urN linux-2.4.21/arch/ppc/8260_io/fcc_enet.c linux-2.4.22/arch/ppc/8260_io/fcc_enet.c --- linux-2.4.21/arch/ppc/8260_io/fcc_enet.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/8260_io/fcc_enet.c 2003-08-25 04:44:40.000000000 -0700 @@ -551,7 +551,7 @@ for (;;) { if (bdp->cbd_sc & BD_ENET_RX_EMPTY) break; - + #ifndef final_version /* Since we have allocated space to hold a complete frame, both * the first and last indicators should be set. @@ -662,7 +662,7 @@ ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); mii_reg = ep->fec_mii_data; #endif - + if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); return; @@ -1007,7 +1007,7 @@ ep = (fcc_enet_t *)dev->base_addr; if (dev->flags&IFF_PROMISC) { - + /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); cep->fccp->fcc_fpsmr |= FCC_PSMR_PRO; @@ -1030,8 +1030,8 @@ dmi = dev->mc_list; - for (i=0; imc_count; i++) { - + for (i=0; imc_count; i++, dmi = dmi->next) { + /* Only support group multicast for now. */ if (!(dmi->dmi_addr[0] & 1)) @@ -1280,7 +1280,7 @@ ep->fen_genfcc.fcc_tiptr = mem_addr+32; ep->fen_padptr = mem_addr+64; memset((char *)(&(immap->im_dprambase[(mem_addr+64)])), 0x88, 32); - + ep->fen_genfcc.fcc_rbptr = 0; ep->fen_genfcc.fcc_tbptr = 0; ep->fen_genfcc.fcc_rcrc = 0; @@ -1491,7 +1491,7 @@ * updates of the registers. I do lots of interrupt disable/enable * to ensure we don't hang out too long with interrupts disabled. */ - + /* First, crank out 32 1-bits as preamble. * This is 64 transitions to clock the bits, with clock/data * left high. diff -urN linux-2.4.21/arch/ppc/8260_io/uart.c linux-2.4.22/arch/ppc/8260_io/uart.c --- linux-2.4.21/arch/ppc/8260_io/uart.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/8260_io/uart.c 2003-08-25 04:44:40.000000000 -0700 @@ -83,7 +83,7 @@ #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT #define _INLINE_ inline - + #define DBG_CNT(s) /* We overload some of the items in the data structure to meet our @@ -233,7 +233,7 @@ if (serial_paranoia_check(info, tty->device, "rs_stop")) return; - + save_flags(flags); cli(); if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { smcp = &immr->im_smc[idx]; @@ -256,7 +256,7 @@ if (serial_paranoia_check(info, tty->device, "rs_stop")) return; - + save_flags(flags); cli(); if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { smcp = &immr->im_smc[idx]; @@ -281,7 +281,7 @@ * rs_interrupt() should try to keep the interrupt handler as fast as * possible. After you are done making modifications, it is not a bad * idea to do: - * + * * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c * * and look at the resulting assemble code in serial.s. @@ -390,7 +390,7 @@ } */ status &= info->read_status_mask; - + if (status & (BD_SC_BR)) { #ifdef SERIAL_DEBUG_INTR printk("handling break...."); @@ -444,7 +444,7 @@ static _INLINE_ void transmit_chars(ser_info_t *info) { - + if (info->flags & TX_WAKEUP) { rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); } @@ -461,7 +461,7 @@ { int status; struct async_icount *icount; - + status = serial_in(info, UART_MSR); if (status & UART_MSR_ANY_DELTA) { @@ -488,7 +488,7 @@ #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) printk("ttys%d CD now %s...", info->line, (status & UART_MSR_DCD) ? "on" : "off"); -#endif +#endif if (status & UART_MSR_DCD) wake_up_interruptible(&info->open_wait); else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && @@ -537,7 +537,7 @@ ser_info_t *info; volatile smc_t *smcp; volatile scc_t *sccp; - + info = (ser_info_t *)dev_id; if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { @@ -558,7 +558,7 @@ transmit_chars(info); sccp->scc_scce = events; } - + #ifdef SERIAL_DEBUG_INTR printk("rs_interrupt_single(%d, %x)...", info->state->smc_scc_num, events); @@ -597,7 +597,7 @@ { ser_info_t *info = (ser_info_t *) private_; struct tty_struct *tty; - + tty = info->tty; if (!tty) return; @@ -617,13 +617,13 @@ * * serial interrupt routine -> (scheduler tqueue) -> * do_serial_hangup() -> tty->hangup() -> rs_hangup() - * + * */ static void do_serial_hangup(void *private_) { struct async_struct *info = (struct async_struct *) private_; struct tty_struct *tty; - + tty = info->tty; if (tty) tty_hangup(tty); @@ -672,7 +672,7 @@ if (info->tty->termios->c_cflag & CBAUD) info->MCR = UART_MCR_DTR | UART_MCR_RTS; #endif - + if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); @@ -680,7 +680,7 @@ * and set the speed of the serial port */ change_speed(info); - + if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { smcp = &immr->im_smc[idx]; @@ -725,7 +725,7 @@ info->flags |= ASYNC_INITIALIZED; restore_flags(flags); return 0; - + errout: restore_flags(flags); return retval; @@ -752,7 +752,7 @@ printk("Shutting down serial port %d (irq %d)....", info->line, state->irq); #endif - + save_flags(flags); cli(); /* Disable interrupts */ if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { @@ -774,7 +774,7 @@ sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); } - + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); @@ -872,7 +872,7 @@ info->read_status_mask |= BD_SC_FR | BD_SC_PR; if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) info->read_status_mask |= BD_SC_BR; - + /* * Characters to ignore */ @@ -882,7 +882,7 @@ if (I_IGNBRK(info->tty)) { info->ignore_status_mask |= BD_SC_BR; /* - * If we're ignore parity and break indicators, ignore + * If we're ignore parity and break indicators, ignore * overruns too. (For real raw support). */ if (I_IGNPAR(info->tty)) @@ -907,9 +907,9 @@ * enables, because we want to put them back if they were * present. */ - prev_mode = smcp->smc_smcmr; - smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; - smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); + prev_mode = smcp->smc_smcmr & (SMCMR_REN | SMCMR_TEN); + smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART + | prev_mode; } else { sccp = &immr->im_scc[idx - SCC_IDX_BASE]; @@ -960,7 +960,7 @@ if (serial_paranoia_check(info, tty->device, "rs_write")) return 0; - if (!tty) + if (!tty) return 0; bdp = info->tx_cur; @@ -1028,7 +1028,7 @@ static int rs_8xx_chars_in_buffer(struct tty_struct *tty) { ser_info_t *info = (ser_info_t *)tty->driver_data; - + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) return 0; return 0; @@ -1037,7 +1037,7 @@ static void rs_8xx_flush_buffer(struct tty_struct *tty) { ser_info_t *info = (ser_info_t *)tty->driver_data; - + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) return; @@ -1084,7 +1084,7 @@ /* * ------------------------------------------------------------ * rs_throttle() - * + * * This routine is called by the upper-layer tty layer to signal that * incoming characters should be throttled. * ------------------------------------------------------------ @@ -1094,14 +1094,14 @@ ser_info_t *info = (ser_info_t *)tty->driver_data; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - + printk("throttle %s: %d....\n", _tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty)); #endif if (serial_paranoia_check(info, tty->device, "rs_throttle")) return; - + if (I_IXOFF(tty)) rs_8xx_send_xchar(tty, STOP_CHAR(tty)); @@ -1120,14 +1120,14 @@ ser_info_t *info = (ser_info_t *)tty->driver_data; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - + printk("unthrottle %s: %d....\n", _tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty)); #endif if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) return; - + if (I_IXOFF(tty)) { if (info->x_char) info->x_char = 0; @@ -1158,7 +1158,7 @@ * release the bus after transmitting. This must be done when * the transmit shift register is empty, not be done when the * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. + * allows an RS485 driver to be written in user space. */ static int get_lsr_info(struct async_struct * info, unsigned int *value) { @@ -1208,7 +1208,7 @@ return error; #ifdef modem_control switch (cmd) { - case TIOCMBIS: + case TIOCMBIS: if (arg & TIOCM_RTS) info->MCR |= UART_MCR_RTS; if (arg & TIOCM_DTR) @@ -1383,7 +1383,7 @@ if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; } - + switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); @@ -1462,7 +1462,7 @@ cli(); cnow = info->state->icount; /* atomic copy */ sti(); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) return -EIO; /* no change => error */ if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || @@ -1478,7 +1478,7 @@ return 0; #endif - /* + /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) * Return: write counters to the user passed counter struct * NB: both 1->0 and 0->1 transitions are counted except for @@ -1512,7 +1512,7 @@ ser_info_t *info = (ser_info_t *)tty->driver_data; if ( (tty->termios->c_cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) + && ( RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) return; @@ -1527,7 +1527,7 @@ serial_out(info, UART_MCR, info->MCR); sti(); } - + /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) { @@ -1540,7 +1540,7 @@ serial_out(info, UART_MCR, info->MCR); sti(); } - + /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { @@ -1565,7 +1565,7 @@ /* * ------------------------------------------------------------ * rs_close() - * + * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * async structure from the interrupt chain if necessary, and we free @@ -1585,16 +1585,16 @@ return; state = info->state; - + save_flags(flags); cli(); - + if (tty_hung_up_p(filp)) { DBG_CNT("before DEC-hung"); MOD_DEC_USE_COUNT; restore_flags(flags); return; } - + #ifdef SERIAL_DEBUG_OPEN printk("rs_close ttys%d, count = %d\n", info->line, state->count); #endif @@ -1631,7 +1631,7 @@ if (info->flags & ASYNC_CALLOUT_ACTIVE) info->state->callout_termios = *tty->termios; /* - * Now we wait for the transmit buffer to clear; and we notify + * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; @@ -1693,7 +1693,7 @@ unsigned long orig_jiffies, char_time; /*int lsr;*/ volatile cbd_t *bdp; - + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) return; @@ -1707,7 +1707,7 @@ * Set the check interval to be 1/5 of the estimated time to * send a single character, and make it at least 1. The check * interval should also be less than the timeout. - * + * * Note: we have to use pretty tight timings here to satisfy * the NIST-PCTS. */ @@ -1750,12 +1750,12 @@ { ser_info_t *info = (ser_info_t *)tty->driver_data; struct serial_state *state = info->state; - + if (serial_paranoia_check(info, tty->device, "rs_hangup")) return; state = info->state; - + rs_8xx_flush_buffer(tty); shutdown(info); info->event = 0; @@ -1816,7 +1816,7 @@ info->flags |= ASYNC_CALLOUT_ACTIVE; return 0; } - + /* * If non-blocking mode is set, or the port is not enabled, * then make the check up front and then exit. @@ -1839,7 +1839,7 @@ if (tty->termios->c_cflag & CLOCAL) do_clocal = 1; } - + /* * Block waiting for the carrier detect and the line to become * free (i.e., not in use by the callout). While we are in @@ -1855,7 +1855,7 @@ state->line, state->count); #endif cli(); - if (!tty_hung_up_p(filp)) + if (!tty_hung_up_p(filp)) state->count--; sti(); info->blocked_open++; @@ -1874,7 +1874,7 @@ if (info->flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; else - retval = -ERESTARTSYS; + retval = -ERESTARTSYS; #else retval = -EAGAIN; #endif @@ -1974,7 +1974,7 @@ (info->flags & ASYNC_SPLIT_TERMIOS)) { if (tty->driver.subtype == SERIAL_TYPE_NORMAL) *tty->termios = info->state->normal_termios; - else + else *tty->termios = info->state->callout_termios; change_speed(info); } @@ -2027,7 +2027,7 @@ status = serial_in(info, UART_MSR); control = info ? info->MCR : serial_in(info, UART_MCR); sti(); - + stat_buf[0] = 0; stat_buf[1] = 0; if (control & UART_MCR_RTS) @@ -2053,12 +2053,12 @@ if (state->icount.frame) ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - + if (state->icount.parity) ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - + if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); if (state->icount.overrun) ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); @@ -2177,7 +2177,7 @@ /* Send the character out. */ cp = __va(bdp->cbd_bufaddr); *cp = *s; - + bdp->cbd_datlen = 1; bdp->cbd_sc |= BD_SC_READY; @@ -2262,13 +2262,13 @@ volatile scc_uart_t *sup; volatile immap_t *immap; volatile iop8260_t *io; - + init_bh(SERIAL_BH, do_serial_bh); show_serial_version(); /* Initialize the tty_driver structure */ - + /*memset(&serial_driver, 0, sizeof(struct tty_driver));*/ __clear_user(&serial_driver,sizeof(struct tty_driver)); serial_driver.magic = TTY_DRIVER_MAGIC; @@ -2309,7 +2309,7 @@ serial_driver.hangup = rs_8xx_hangup; serial_driver.wait_until_sent = rs_8xx_wait_until_sent; serial_driver.read_proc = rs_8xx_read_proc; - + /* * The callout device is just like normal device except for * major number and the subtype code. @@ -2329,7 +2329,7 @@ panic("Couldn't register serial driver\n"); if (tty_register_driver(&callout_driver)) panic("Couldn't register callout driver\n"); - + immap = immr; cp = &immap->im_cpm; io = &immap->im_ioport; @@ -2390,7 +2390,7 @@ state->closing_wait = 30*HZ; state->callout_termios = callout_driver.init_termios; state->normal_termios = serial_driver.init_termios; - state->icount.cts = state->icount.dsr = + state->icount.cts = state->icount.dsr = state->icount.rng = state->icount.dcd = 0; state->icount.rx = state->icount.tx = 0; state->icount.frame = state->icount.parity = 0; @@ -2577,7 +2577,7 @@ * Enable receive and transmit. */ scp->scc_gsmrh = 0; - scp->scc_gsmrl = + scp->scc_gsmrl = (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); /* Disable all interrupts and clear all pending @@ -2636,7 +2636,7 @@ ser = rs_table + co->index; - + immap = immr; cp = &immap->im_cpm; io = &immap->im_ioport; diff -urN linux-2.4.21/arch/ppc/8xx_io/enet.c linux-2.4.22/arch/ppc/8xx_io/enet.c --- linux-2.4.21/arch/ppc/8xx_io/enet.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/8xx_io/enet.c 2003-08-25 04:44:40.000000000 -0700 @@ -229,7 +229,7 @@ cep->stats.tx_bytes += skb->len; cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK; - + /* Push the data cache so the CPM does not get stale memory * data. */ @@ -447,7 +447,7 @@ for (;;) { if (bdp->cbd_sc & BD_ENET_RX_EMPTY) break; - + #ifndef final_version /* Since we have allocated space to hold a complete frame, both * the first and last indicators should be set. @@ -567,7 +567,7 @@ ep = (scc_enet_t *)dev->base_addr; if (dev->flags&IFF_PROMISC) { - + /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); cep->sccp->scc_pmsr |= SCC_PMSR_PRO; @@ -594,8 +594,8 @@ dmi = dev->mc_list; - for (i=0; imc_count; i++) { - + for (i=0; imc_count; i++, dmi = dmi->next) { + /* Only support group multicast for now. */ if (!(dmi->dmi_addr[0] & 1)) diff -urN linux-2.4.21/arch/ppc/8xx_io/fec.c linux-2.4.22/arch/ppc/8xx_io/fec.c --- linux-2.4.21/arch/ppc/8xx_io/fec.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/8xx_io/fec.c 2003-08-25 04:44:40.000000000 -0700 @@ -163,7 +163,7 @@ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ scc_t *sccp; struct net_device_stats stats; - uint tx_full; + uint tx_free; spinlock_t lock; #ifdef CONFIG_USE_MDIO @@ -229,6 +229,7 @@ mii_list_t *mii_free; mii_list_t *mii_head; mii_list_t *mii_tail; +int mii_stopped; typedef struct mdio_read_data { u16 regval; @@ -295,18 +296,13 @@ fep = dev->priv; fecp = (volatile fec_t*)dev->base_addr; - if (!fep->link) { - /* Link is down or autonegotiation is in progress. */ - return 1; - } - /* Fill in a Tx ring entry */ bdp = fep->cur_tx; #ifndef final_version - if (bdp->cbd_sc & BD_ENET_TX_READY) { + if (!fep->tx_free || (bdp->cbd_sc & BD_ENET_TX_READY)) { /* Ooops. All transmit buffers are full. Bail out. - * This should not happen, since dev->tbusy should be set. + * This should not happen, since the tx queue should be stopped. */ printk("%s: tx queue full!.\n", dev->name); return 1; @@ -357,10 +353,8 @@ bdp++; } - if (bdp->cbd_sc & BD_ENET_TX_READY) { + if (!--fep->tx_free) netif_stop_queue(dev); - fep->tx_full = 1; - } fep->cur_tx = (cbd_t *)bdp; @@ -381,8 +375,8 @@ int i; cbd_t *bdp; - printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", - (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", + printk("Ring data dump: cur_tx %lx, tx_free %d, dirty_tx %lx, cur_rx %lx\n", + (unsigned long)fep->cur_tx, fep->tx_free, (unsigned long)fep->dirty_tx, (unsigned long)fep->cur_rx); @@ -409,7 +403,7 @@ } } #endif - if (!fep->tx_full) + if (fep->tx_free) netif_wake_queue(dev); } @@ -469,7 +463,7 @@ bdp = fep->dirty_tx; while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) { - if (bdp == fep->cur_tx && fep->tx_full == 0) break; + if (fep->tx_free == TX_RING_SIZE) break; skb = fep->tx_skbuff[fep->skb_dirty]; /* Check for errors. */ @@ -519,8 +513,7 @@ /* Since we have freed up a buffer, the ring is no longer * full. */ - if (fep->tx_full) { - fep->tx_full = 0; + if (!fep->tx_free++) { if (netif_queue_stopped(dev)) netif_wake_queue(dev); } @@ -668,6 +661,12 @@ ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); mii_reg = ep->fec_mii_data; + /* Ignore this answer if the request queue has been stopped. + * The request will be re-issued when the queue is restarted. + */ + if (mii_stopped) + return; + if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); return; @@ -714,7 +713,8 @@ mii_tail = mip; } else { mii_head = mii_tail = mip; - (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval; + if (!mii_stopped) + (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval; } } else { retval = 1; @@ -725,6 +725,30 @@ return(retval); } +/* Functions to stop/start the transmission of requests through the MDIO. + * They are intended to be used before and after a FEC reset. + */ +static void stop_mii_queue(struct net_device *dev) +{ + unsigned long flags; + save_flags(flags); + cli(); + mii_stopped = 1; + restore_flags(flags); +} + +static void start_mii_queue(struct net_device *dev) +{ + unsigned long flags; + volatile fec_t *ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); + save_flags(flags); + cli(); + mii_stopped = 0; + if(mii_head) + ep->fec_mii_data = mii_head->mii_regval; + restore_flags(flags); +} + static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) { int k; @@ -995,7 +1019,7 @@ { mk_mii_end, } }, (const phy_cmd_t []) { /* startup - enable interrupts */ - { mk_mii_write(MII_QS6612_IMR, 0x003a), NULL }, + { mk_mii_write(MII_QS6612_IMR, 0x0050), NULL }, { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ { mk_mii_end, } }, @@ -1060,7 +1084,7 @@ 0x020005c1, "DP83843BVJE", - (const phy_cmd_t []) { /* config */ + (const phy_cmd_t []) { /* config */ { mk_mii_write(MII_REG_ANAR, 0x01E1), NULL }, /* Auto-Negociation Register Control set to */ /* auto-negociate 10/100MBps, Half/Full duplex */ { mk_mii_read(MII_REG_CR), mii_parse_cr }, @@ -1132,7 +1156,7 @@ 0x020005c2, "DP83846A", - (const phy_cmd_t []) { /* config */ + (const phy_cmd_t []) { /* config */ { mk_mii_write(MII_REG_ANAR, 0x01E1), NULL }, /* Auto-Negociation Register Control set to */ /* auto-negociate 10/100MBps, Half/Full duplex */ { mk_mii_read(MII_REG_CR), mii_parse_cr }, @@ -1367,31 +1391,20 @@ #ifdef CONFIG_USE_MDIO struct net_device *dev = dev_id; struct fec_enet_private *fep = dev->priv; - volatile immap_t *immap = (immap_t *)IMAP_ADDR; - volatile fec_t *fecp = &(immap->im_cpm.cp_fec); - unsigned int ecntrl = fecp->fec_ecntrl; - - /* We need the FEC enabled to access the MII - */ - if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) { - fecp->fec_ecntrl |= FEC_ECNTRL_ETHER_EN; - } -#endif /* CONFIG_USE_MDIO */ - -#if 0 - disable_irq(fep->mii_irq); /* disable now, enable later */ -#endif - -#ifdef CONFIG_USE_MDIO - mii_do_cmd(dev, fep->phy->ack_int); - mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ - - if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) { - fecp->fec_ecntrl = ecntrl; /* restore old settings */ + /* + * Acknowledge the interrupt if possible. If we have not + * found the PHY yet we can't process or acknowledge the + * interrupt now. Instead we ignore this interrupt for now, + * which we can do since it is edge triggered. It will be + * acknowledged later by fec_enet_open(). + */ + if (fep->phy) { + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ } #else -printk("%s[%d] %s: unexpected Link interrupt\n", __FILE__,__LINE__,__FUNCTION__); + printk ("FEC: unexpected Link interrupt\n"); #endif /* CONFIG_USE_MDIO */ } @@ -1422,7 +1435,7 @@ { /* Initializing timers */ - init_timer( &fep->phy_timer_list ); + init_timer( &fep->phy_timer_list ); /* Starting timer for periodic link status check * After 100 milli-seconds, mdio_timer_callback function is called. @@ -1492,7 +1505,7 @@ { fep->phy_timer_list.expires = jiffies + (1 * HZ); /* Sleep for 1 sec. */ } - add_timer( &fep->phy_timer_list ); + add_timer( &fep->phy_timer_list ); } #endif /* CONFIG_FEC_DP83846A */ @@ -1540,7 +1553,7 @@ else { switch(cmd) - { + { case SIOCETHTOOL: return netdev_ethtool_ioctl(dev, (void*)rq->ifr_data); break; @@ -1571,7 +1584,7 @@ default: retval = -EOPNOTSUPP; break; - } + } } return retval; } @@ -1652,7 +1665,7 @@ dmi = dev->mc_list; - for (i=0; imc_count; i++) { + for (i=0; imc_count; i++, dmi = dmi->next) { /* Only support group multicast for now. */ @@ -1927,6 +1940,11 @@ fep = dev->priv; +#ifdef CONFIG_USE_MDIO + /* Stop the MDIO communication prior to reset. */ + stop_mii_queue(dev); +#endif + /* Whack a reset. We should wait for this. */ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET; @@ -1960,6 +1978,7 @@ fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->tx_free = TX_RING_SIZE; fep->cur_rx = fep->rx_bd_base; /* Reset SKB transmit buffers. @@ -2043,12 +2062,10 @@ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN; fecp->fec_r_des_active = 0x01000000; - /* The tx ring is no longer full. */ - if(fep->tx_full) - { - fep->tx_full = 0; - netif_wake_queue(dev); - } +#ifdef CONFIG_USE_MDIO + /* Re-start any pending MDIO communication. */ + start_mii_queue(dev); +#endif } static void @@ -2080,22 +2097,7 @@ printk ("FEC timeout on graceful transmit stop\n"); } - /* Clear outstanding MII command interrupts. - */ - fecp->fec_ievent = FEC_ENET_MII; - - /* Enable MII command finished interrupt - */ - fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; + /* Disable FEC. Let only MII interrupts. */ fecp->fec_imask = FEC_ENET_MII; - -#ifdef CONFIG_USE_MDIO - /* Set MII speed. - */ - fecp->fec_mii_speed = fep->phy_speed; -#endif /* CONFIG_USE_MDIO */ - - /* Disable FEC - */ fecp->fec_ecntrl &= ~(FEC_ECNTRL_ETHER_EN); } diff -urN linux-2.4.21/arch/ppc/8xx_io/uart.c linux-2.4.22/arch/ppc/8xx_io/uart.c --- linux-2.4.21/arch/ppc/8xx_io/uart.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/8xx_io/uart.c 2003-08-25 04:44:40.000000000 -0700 @@ -112,7 +112,7 @@ #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT #define _INLINE_ inline - + #define DBG_CNT(s) /* We overload some of the items in the data structure to meet our @@ -281,7 +281,7 @@ if (serial_paranoia_check(info, tty->device, "rs_stop")) return; - + save_flags(flags); cli(); idx = PORT_NUM(info->state->smc_scc_num); if (PORT_IS_SCC(info->state->smc_scc_num)) { @@ -305,7 +305,7 @@ if (serial_paranoia_check(info, tty->device, "rs_stop")) return; - + idx = PORT_NUM(info->state->smc_scc_num); save_flags(flags); cli(); if (PORT_IS_SCC(info->state->smc_scc_num)) { @@ -331,7 +331,7 @@ * rs_interrupt() should try to keep the interrupt handler as fast as * possible. After you are done making modifications, it is not a bad * idea to do: - * + * * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c * * and look at the resulting assemble code in serial.s. @@ -477,7 +477,7 @@ } #if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) if (break_pressed && info->line == sercons.index) { - if (ch != 0 && time_before(jiffies, + if (ch != 0 && time_before(jiffies, break_pressed + HZ*5)) { handle_sysrq(ch, regs, NULL, NULL); break_pressed = 0; @@ -495,7 +495,7 @@ } #if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - ignore_char: + ignore_char: #endif /* This BD is ready to be used again. Clear status. * Get next BD. @@ -543,7 +543,7 @@ static _INLINE_ void transmit_chars(ser_info_t *info, struct pt_regs *regs) { - + if ((info->flags & TX_WAKEUP) || (info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) { rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); @@ -561,7 +561,7 @@ { int status; struct async_icount *icount; - + status = serial_in(info, UART_MSR); if (status & UART_MSR_ANY_DELTA) { @@ -588,7 +588,7 @@ #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) printk("ttys%d CD now %s...", info->line, (status & UART_MSR_DCD) ? "on" : "off"); -#endif +#endif if (status & UART_MSR_DCD) wake_up_interruptible(&info->open_wait); else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && @@ -637,7 +637,7 @@ ser_info_t *info; volatile smc_t *smcp; volatile scc_t *sccp; - + info = (ser_info_t *)dev_id; idx = PORT_NUM(info->state->smc_scc_num); @@ -663,7 +663,7 @@ transmit_chars(info, regs); smcp->smc_smce = events; } - + #ifdef SERIAL_DEBUG_INTR printk("rs_interrupt_single(%d, %x)...", info->state->smc_scc_num, events); @@ -702,7 +702,7 @@ { ser_info_t *info = (ser_info_t *) private_; struct tty_struct *tty; - + tty = info->tty; if (!tty) return; @@ -722,13 +722,13 @@ * * serial interrupt routine -> (scheduler tqueue) -> * do_serial_hangup() -> tty->hangup() -> rs_hangup() - * + * */ static void do_serial_hangup(void *private_) { struct async_struct *info = (struct async_struct *) private_; struct tty_struct *tty; - + tty = info->tty; if (tty) tty_hangup(tty); @@ -777,7 +777,7 @@ if (info->tty->termios->c_cflag & CBAUD) info->MCR = UART_MCR_DTR | UART_MCR_RTS; #endif - + if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); @@ -785,7 +785,7 @@ * and set the speed of the serial port */ change_speed(info); - + idx = PORT_NUM(info->state->smc_scc_num); if (PORT_IS_SCC(info->state->smc_scc_num)) { sccp = &cpmp->cp_scc[idx]; @@ -820,7 +820,7 @@ info->flags |= ASYNC_INITIALIZED; restore_flags(flags); return 0; - + errout: restore_flags(flags); return retval; @@ -847,7 +847,7 @@ printk("Shutting down serial port %d (irq %d)....", info->line, state->irq); #endif - + save_flags(flags); cli(); /* Disable interrupts */ idx = PORT_NUM(state->smc_scc_num); @@ -876,7 +876,7 @@ #endif smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); } - + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); @@ -977,7 +977,7 @@ info->read_status_mask |= BD_SC_FR | BD_SC_PR; if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) info->read_status_mask |= BD_SC_BR; - + /* * Characters to ignore */ @@ -987,7 +987,7 @@ if (I_IGNBRK(info->tty)) { info->ignore_status_mask |= BD_SC_BR; /* - * If we're ignore parity and break indicators, ignore + * If we're ignore parity and break indicators, ignore * overruns too. (For real raw support). */ if (I_IGNPAR(info->tty)) @@ -1010,7 +1010,7 @@ sccp = &cpmp->cp_scc[idx]; new_mode = (sbits << 12) | scval; prev_mode = sccp->scc_pmsr; - if (!(prev_mode & SCU_PMSR_PEN)) + if (!(prev_mode & SCU_PMSR_PEN)) /* If parity is disabled, mask out even/odd */ prev_mode &= ~(SCU_PMSR_TPM|SCU_PMSR_RPM); if (prev_mode != new_mode) @@ -1023,9 +1023,9 @@ * enables, because we want to put them back if they were * present. */ - prev_mode = smcp->smc_smcmr; - new_mode = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; - new_mode |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); + prev_mode = smcp->smc_smcmr & (SMCMR_REN | SMCMR_TEN); + new_mode = smcr_mk_clen(bits) | cval | SMCMR_SM_UART + | prev_mode; if (!(prev_mode & SMCMR_PEN)) /* If parity is disabled, mask out even/odd */ prev_mode &= ~SMCMR_PM_EVEN; @@ -1075,7 +1075,7 @@ volatile cbd_t *bdp; #ifdef CONFIG_KGDB_CONSOLE - /* Try to let stub handle output. Returns true if it did. */ + /* Try to let stub handle output. Returns true if it did. */ if (kgdb_output_string(buf, count)) return ret; #endif @@ -1083,7 +1083,7 @@ if (serial_paranoia_check(info, tty->device, "rs_write")) return 0; - if (!tty) + if (!tty) return 0; bdp = info->tx_cur; @@ -1151,7 +1151,7 @@ static int rs_8xx_chars_in_buffer(struct tty_struct *tty) { ser_info_t *info = (ser_info_t *)tty->driver_data; - + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) return 0; return 0; @@ -1160,7 +1160,7 @@ static void rs_8xx_flush_buffer(struct tty_struct *tty) { ser_info_t *info = (ser_info_t *)tty->driver_data; - + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) return; @@ -1207,7 +1207,7 @@ /* * ------------------------------------------------------------ * rs_throttle() - * + * * This routine is called by the upper-layer tty layer to signal that * incoming characters should be throttled. * ------------------------------------------------------------ @@ -1217,14 +1217,14 @@ ser_info_t *info = (ser_info_t *)tty->driver_data; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - + printk("throttle %s: %d....\n", _tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty)); #endif if (serial_paranoia_check(info, tty->device, "rs_throttle")) return; - + if (I_IXOFF(tty)) rs_8xx_send_xchar(tty, STOP_CHAR(tty)); @@ -1243,14 +1243,14 @@ ser_info_t *info = (ser_info_t *)tty->driver_data; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - + printk("unthrottle %s: %d....\n", _tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty)); #endif if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) return; - + if (I_IXOFF(tty)) { if (info->x_char) info->x_char = 0; @@ -1281,7 +1281,7 @@ * release the bus after transmitting. This must be done when * the transmit shift register is empty, not be done when the * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. + * allows an RS485 driver to be written in user space. */ static int get_lsr_info(struct async_struct * info, unsigned int *value) { @@ -1331,7 +1331,7 @@ return error; #ifdef modem_control switch (cmd) { - case TIOCMBIS: + case TIOCMBIS: if (arg & TIOCM_RTS) info->MCR |= UART_MCR_RTS; if (arg & TIOCM_DTR) @@ -1464,7 +1464,7 @@ if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; } - + switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); @@ -1543,7 +1543,7 @@ cli(); cnow = info->state->icount; /* atomic copy */ sti(); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) return -EIO; /* no change => error */ if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || @@ -1559,7 +1559,7 @@ return 0; #endif - /* + /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) * Return: write counters to the user passed counter struct * NB: both 1->0 and 0->1 transitions are counted except for @@ -1593,7 +1593,7 @@ ser_info_t *info = (ser_info_t *)tty->driver_data; if ( (tty->termios->c_cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) + && ( RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) return; @@ -1608,7 +1608,7 @@ serial_out(info, UART_MCR, info->MCR); sti(); } - + /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) { @@ -1621,7 +1621,7 @@ serial_out(info, UART_MCR, info->MCR); sti(); } - + /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { @@ -1646,7 +1646,7 @@ /* * ------------------------------------------------------------ * rs_close() - * + * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * async structure from the interrupt chain if necessary, and we free @@ -1666,16 +1666,16 @@ return; state = info->state; - + save_flags(flags); cli(); - + if (tty_hung_up_p(filp)) { DBG_CNT("before DEC-hung"); MOD_DEC_USE_COUNT; restore_flags(flags); return; } - + #ifdef SERIAL_DEBUG_OPEN printk("rs_close ttys%d, count = %d\n", info->line, state->count); #endif @@ -1712,7 +1712,7 @@ if (info->flags & ASYNC_CALLOUT_ACTIVE) info->state->callout_termios = *tty->termios; /* - * Now we wait for the transmit buffer to clear; and we notify + * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; @@ -1775,7 +1775,7 @@ unsigned long orig_jiffies, char_time; /*int lsr;*/ volatile cbd_t *bdp; - + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) return; @@ -1789,7 +1789,7 @@ * Set the check interval to be 1/5 of the estimated time to * send a single character, and make it at least 1. The check * interval should also be less than the timeout. - * + * * Note: we have to use pretty tight timings here to satisfy * the NIST-PCTS. */ @@ -1843,12 +1843,12 @@ { ser_info_t *info = (ser_info_t *)tty->driver_data; struct serial_state *state = info->state; - + if (serial_paranoia_check(info, tty->device, "rs_hangup")) return; state = info->state; - + rs_8xx_flush_buffer(tty); shutdown(info); info->event = 0; @@ -1909,7 +1909,7 @@ info->flags |= ASYNC_CALLOUT_ACTIVE; return 0; } - + /* * If non-blocking mode is set, or the port is not enabled, * then make the check up front and then exit. @@ -1932,7 +1932,7 @@ if (tty->termios->c_cflag & CLOCAL) do_clocal = 1; } - + /* * Block waiting for the carrier detect and the line to become * free (i.e., not in use by the callout). While we are in @@ -1948,7 +1948,7 @@ state->line, state->count); #endif cli(); - if (!tty_hung_up_p(filp)) + if (!tty_hung_up_p(filp)) state->count--; sti(); info->blocked_open++; @@ -1967,7 +1967,7 @@ if (info->flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; else - retval = -ERESTARTSYS; + retval = -ERESTARTSYS; #else retval = -EAGAIN; #endif @@ -2068,7 +2068,7 @@ (info->flags & ASYNC_SPLIT_TERMIOS)) { if (tty->driver.subtype == SERIAL_TYPE_NORMAL) *tty->termios = info->state->normal_termios; - else + else *tty->termios = info->state->callout_termios; change_speed(info); } @@ -2121,7 +2121,7 @@ status = serial_in(info, UART_MSR); control = info ? info->MCR : serial_in(info, UART_MCR); sti(); - + stat_buf[0] = 0; stat_buf[1] = 0; if (control & UART_MCR_RTS) @@ -2147,12 +2147,12 @@ if (state->icount.frame) ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - + if (state->icount.parity) ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - + if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); if (state->icount.overrun) ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); @@ -2278,7 +2278,7 @@ else cp = __va(bdp->cbd_bufaddr); *cp = *s; - + bdp->cbd_datlen = 1; bdp->cbd_sc |= BD_SC_READY; @@ -2318,7 +2318,7 @@ unsigned count) { #ifdef CONFIG_KGDB_CONSOLE - /* Try to let stub handle output. Returns true if it did. */ + /* Try to let stub handle output. Returns true if it did. */ if (kgdb_output_string(s, count)) return; #endif @@ -2536,13 +2536,13 @@ volatile scc_t *scp; volatile scc_uart_t *sup; volatile immap_t *immap; - + init_bh(SERIAL_BH, do_serial_bh); show_serial_version(); /* Initialize the tty_driver structure */ - + __clear_user(&serial_driver,sizeof(struct tty_driver)); serial_driver.magic = TTY_DRIVER_MAGIC; serial_driver.driver_name = "serial"; @@ -2582,7 +2582,7 @@ serial_driver.hangup = rs_8xx_hangup; serial_driver.wait_until_sent = rs_8xx_wait_until_sent; serial_driver.read_proc = rs_8xx_read_proc; - + /* * The callout device is just like normal device except for * major number and the subtype code. @@ -2602,7 +2602,7 @@ panic("Couldn't register serial driver\n"); if (tty_register_driver(&callout_driver)) panic("Couldn't register callout driver\n"); - + cp = cpmp; /* Get pointer to Communication Processor */ immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ @@ -2663,7 +2663,7 @@ state->closing_wait = 30*HZ; state->callout_termios = callout_driver.init_termios; state->normal_termios = serial_driver.init_termios; - state->icount.cts = state->icount.dsr = + state->icount.cts = state->icount.dsr = state->icount.rng = state->icount.dcd = 0; state->icount.rx = state->icount.tx = 0; state->icount.frame = state->icount.parity = 0; @@ -2800,7 +2800,7 @@ * Enable receive and transmit. */ scp->scc_gsmrh = 0; - scp->scc_gsmrl = + scp->scc_gsmrl = (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); /* Disable all interrupts and clear all pending @@ -3028,7 +3028,7 @@ * Enable receive and transmit. */ scp->scc_gsmrh = 0; - scp->scc_gsmrl = + scp->scc_gsmrl = (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); /* Disable all interrupts and clear all pending diff -urN linux-2.4.21/arch/ppc/Makefile linux-2.4.22/arch/ppc/Makefile --- linux-2.4.21/arch/ppc/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -16,10 +16,6 @@ # Be sure to change PAGE_OFFSET in include/asm-ppc/page.h to match KERNELLOAD =0xc0000000 -ifeq ($(shell uname -m),ppc) -CHECKS = checks -endif - LINKFLAGS = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic CPPFLAGS := $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH) AFLAGS := $(AFLAGS) -I$(TOPDIR)/arch/$(ARCH) @@ -46,7 +42,7 @@ CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') endif -ifdef CONFIG_4xx +ifdef CONFIG_40x HEAD := arch/ppc/kernel/head_4xx.o else ifdef CONFIG_8xx @@ -99,7 +95,7 @@ # All the instructions talk about "make bzImage". bzImage: zImage -$(BOOT_TARGETS): $(CHECKS) vmlinux +$(BOOT_TARGETS): vmlinux @$(MAKEBOOT) $@ %_config: arch/ppc/configs/%_defconfig diff -urN linux-2.4.21/arch/ppc/amiga/config.c linux-2.4.22/arch/ppc/amiga/config.c --- linux-2.4.21/arch/ppc/amiga/config.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/amiga/config.c 2003-08-25 04:44:40.000000000 -0700 @@ -343,7 +343,7 @@ case AMI_DRACO: panic("No support for Draco yet"); - + default: panic("Unknown Amiga Model"); } @@ -644,7 +644,7 @@ volatile struct tod2000 *tod = TOD_2000; tod->cntrl1 = TOD2000_CNTRL1_HOLD; - + while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) ; @@ -709,13 +709,13 @@ tod->second2 = real_seconds % 10; tod->minute1 = real_minutes / 10; tod->minute2 = real_minutes % 10; - + tod->cntrl1 = TOD3000_CNTRL1_FREE; } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { volatile struct tod2000 *tod = TOD_2000; tod->cntrl1 = TOD2000_CNTRL1_HOLD; - + while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) ; @@ -974,7 +974,7 @@ mach_get_model(model); else strcpy(model, "Unknown PowerPC"); - + len += sprintf(buffer+len, "Model:\t\t%s\n", model); len += get_cpuinfo(buffer+len); for (mem = 0, i = 0; i < m68k_realnum_memory; i++) diff -urN linux-2.4.21/arch/ppc/amiga/ints.c linux-2.4.22/arch/ppc/amiga/ints.c --- linux-2.4.21/arch/ppc/amiga/ints.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/amiga/ints.c 2003-08-25 04:44:40.000000000 -0700 @@ -76,8 +76,8 @@ return NULL; } -int sys_request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), +int sys_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { if (irq < IRQ1 || irq > IRQ7) { diff -urN linux-2.4.21/arch/ppc/boot/Makefile linux-2.4.22/arch/ppc/boot/Makefile --- linux-2.4.21/arch/ppc/boot/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -32,6 +32,7 @@ tools-$(CONFIG_ALL_PPC) := addnote mknote hack-coff mkprep tools-$(CONFIG_4xx) := mktree tools-$(CONFIG_LOPEC) := mkbugboot mkprep +tools-$(CONFIG_PPLUS) := mkbugboot mkprep tools-$(CONFIG_SPRUCE) := mktree # These are dirs we don't want to go into on BOOT_TARGETS. We have them for diff -urN linux-2.4.21/arch/ppc/boot/chrp/main.c linux-2.4.22/arch/ppc/boot/chrp/main.c --- linux-2.4.21/arch/ppc/boot/chrp/main.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/chrp/main.c 2003-08-25 04:44:40.000000000 -0700 @@ -43,6 +43,8 @@ static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */ +typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); + void chrpboot(int a1, int a2, void *prom) { @@ -50,7 +52,7 @@ void *dst; unsigned char *im; unsigned int initrd_size, initrd_start; - + printf("chrpboot starting: loaded at 0x%p\n\r", &_start); initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); @@ -89,11 +91,11 @@ flush_cache(dst, len); make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp, (PROG_START + PROG_SIZE)); - + sa = (unsigned long)PROG_START; printf("start address = 0x%x\n\r", sa); - (*(void (*)())sa)(a1, a2, prom, initrd_start, initrd_size); + (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size); printf("returned?\n\r"); diff -urN linux-2.4.21/arch/ppc/boot/common/Makefile linux-2.4.22/arch/ppc/boot/common/Makefile --- linux-2.4.21/arch/ppc/boot/common/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/common/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -11,7 +11,6 @@ USE_STANDARD_AS_RULE := true coffcrt0.o: - $(CC) -I$(TOPDIR)/arch/$(ARCH)/kernel $(AFLAGS) -DXCOFF \ - -traditional -c -o coffcrt0.o crt0.S + $(CC) $(AFLAGS) -DXCOFF -traditional -c -o coffcrt0.o crt0.S include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ppc/boot/common/crt0.S linux-2.4.22/arch/ppc/boot/common/crt0.S --- linux-2.4.21/arch/ppc/boot/common/crt0.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/common/crt0.S 2003-08-25 04:44:40.000000000 -0700 @@ -34,9 +34,9 @@ ## Flush and invalidate the caches for the range in memory covering ## the .text section of the boot loader - + lis r9,_start@h # r9 = &_start - lis r8,_etext@ha # + lis r8,_etext@ha # addi r8,r8,_etext@l # r8 = &_etext 3: dcbf r0,r9 # Flush the data cache icbi r0,r9 # Invalidate the instruction cache @@ -50,12 +50,12 @@ lis r7,_end@ha addi r7,r7,_end@l # r7 = &_end - lis r8,__bss_start@ha # + lis r8,__bss_start@ha # addi r8,r8,__bss_start@l # r8 = &_bss_start ## Determine how large an area, in number of words, to clear - - subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 + + subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 addi r7,r7,3 # r7 += 3 srwi. r7,r7,2 # r7 = size in words. beq 2f # If the size is zero, do not bother diff -urN linux-2.4.21/arch/ppc/boot/common/misc-common.c linux-2.4.22/arch/ppc/boot/common/misc-common.c --- linux-2.4.21/arch/ppc/boot/common/misc-common.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/common/misc-common.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/boot/common/misc-common.c - * + * * Misc. bootloader code (almost) all platforms can use * * Author: Johnnie Peters @@ -74,7 +74,7 @@ void exit(void) { puts("exit\n"); - while(1); + while(1); } int tstc(void) @@ -102,7 +102,7 @@ } } -void +void putc(const char c) { int x,y; @@ -129,7 +129,7 @@ x--; } } else { - vidmem [ ( x + cols * y ) * 2 ] = c; + vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { @@ -170,7 +170,7 @@ x--; } } else { - vidmem [ ( x + cols * y ) * 2 ] = c; + vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { @@ -199,7 +199,7 @@ void *zalloc(void *x, unsigned items, unsigned size) { void *p = avail_ram; - + size *= items; size = (size + 7) & -8; avail_ram += size; @@ -226,7 +226,7 @@ { z_stream s; int r, i, flags; - + /* skip header */ i = 10; flags = src[3]; @@ -248,7 +248,7 @@ puts("gunzip: ran out of data in header\n"); exit(); } - + s.zalloc = zalloc; s.zfree = zfree; r = inflateInit2(&s, -MAX_WBITS); diff -urN linux-2.4.21/arch/ppc/boot/common/misc-simple.c linux-2.4.22/arch/ppc/boot/common/misc-simple.c --- linux-2.4.21/arch/ppc/boot/common/misc-simple.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/common/misc-simple.c 2003-08-25 04:44:40.000000000 -0700 @@ -236,7 +236,7 @@ puts("\n"); } } - + rec->tag = BI_FIRST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); diff -urN linux-2.4.21/arch/ppc/boot/common/mpc10x_memory.c linux-2.4.22/arch/ppc/boot/common/mpc10x_memory.c --- linux-2.4.21/arch/ppc/boot/common/mpc10x_memory.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/common/mpc10x_memory.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/boot/common/mpc10x_common.c - * + * * A routine to find out how much memory the machine has. * * Based on: diff -urN linux-2.4.21/arch/ppc/boot/common/ns16550.c linux-2.4.22/arch/ppc/boot/common/ns16550.c --- linux-2.4.21/arch/ppc/boot/common/ns16550.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/common/ns16550.c 2003-08-25 04:44:40.000000000 -0700 @@ -41,7 +41,7 @@ /* How far apart the registers are. */ shift = rs_table[chan].iomem_reg_shift; - + /* save the LCR */ lcr = inb(com_port + (UART_LCR << shift)); /* Access baud rate */ diff -urN linux-2.4.21/arch/ppc/boot/common/relocate.S linux-2.4.22/arch/ppc/boot/common/relocate.S --- linux-2.4.21/arch/ppc/boot/common/relocate.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/common/relocate.S 2003-08-25 04:44:40.000000000 -0700 @@ -21,8 +21,8 @@ #include #define GETSYM(reg, sym) \ - lis reg, sym@h; ori reg, reg, sym@l - + lis reg, sym@h; ori reg, reg, sym@l + .text /* We get called from the early initialization code. * Register 3 has the address where we were loaded, @@ -54,12 +54,12 @@ cmp cr0,r3,r4 beq start_ldr /* If 0, we don't need to relocate */ - /* Move this code somewhere safe. This is max(load + size, end) - * BIG ASSUMPTION: Addresses below 0x80000000 are assumed to be - * in RAM, and addresses above 0x80000000 are assumed to be in - * Flash. The cmpw instruction below does a signed integer + /* Move this code somewhere safe. This is max(load + size, end) + * BIG ASSUMPTION: Addresses below 0x80000000 are assumed to be + * in RAM, and addresses above 0x80000000 are assumed to be in + * Flash. The cmpw instruction below does a signed integer * comparison, so when comparing a RAM address to a Flash address - * the RAM address will always be greater. This allows the + * the RAM address will always be greater. This allows the * relocation to work when the load address is in Flash. * r8 == load address */ @@ -72,10 +72,10 @@ cmpw r5,r6 bgt 1f b 2f -1: - mr r6, r5 -2: - /* dest is in r6 */ +1: + mr r6, r5 +2: + /* dest is in r6 */ /* Ensure alignment --- this code is precautionary */ addi r6,r6,4 li r5,0x0003 @@ -87,20 +87,20 @@ GETSYM(r3, start) /* Size to copy */ - sub r4,r4,r5 + sub r4,r4,r5 srwi r4,r4,2 - + /* Src addr to copy (= __relocate_start - start + where_loaded) */ sub r3,r5,r3 - add r5,r8,r3 + add r5,r8,r3 /* Save dest */ mr r3, r6 - /* Do the copy */ - mtctr r4 + /* Do the copy */ + mtctr r4 3: lwz r4,0(r5) - stw r4,0(r3) + stw r4,0(r3) addi r3,r3,4 addi r5,r5,4 bdnz 3b @@ -116,23 +116,23 @@ b flush_instruction_cache .section ".relocate_code","xa" - -do_relocate: - /* We have 2 cases --- start < load, or start > load + +do_relocate: + /* We have 2 cases --- start < load, or start > load * This determines whether we copy from the end, or the start. * Its easier to have 2 loops than to have paramaterised * loops. Sigh. */ li r6,0 /* Clear checksum */ mtctr r7 /* Setup for a loop */ - + GETSYM(r4, start) mr r3,r8 /* Get the load addr */ cmp cr0,r4,r3 /* If we need to copy from the end, do so */ bgt do_relocate_from_end - -do_relocate_from_start: + +do_relocate_from_start: 1: lwz r5,0(r3) /* Load and decrement */ stw r5,0(r4) /* Store and decrement */ addi r3,r3,4 @@ -141,7 +141,7 @@ bdnz 1b /* Are we done? */ b do_relocate_out /* Finished */ -do_relocate_from_end: +do_relocate_from_end: GETSYM(r3, end) slwi r4,r7,2 add r4,r8,r4 /* Get the physical end */ @@ -150,7 +150,7 @@ xor r6,r6,r5 bdnz 1b -do_relocate_out: +do_relocate_out: GETSYM(r3,start_ldr) mtlr r3 /* Easiest way to do an absolute jump */ /* Some boards don't boot up with the I-cache enabled. Do that @@ -161,7 +161,7 @@ b flush_instruction_cache .previous - + start_ldr: /* Clear all of BSS and set up stack for C calls */ lis r3,edata@h @@ -200,7 +200,7 @@ /* * Start at the beginning of real code (the first - * three instructions are 'nop' since we + * three instructions are 'nop' since we * sometimes overwrite them). */ ba 0x000c diff -urN linux-2.4.21/arch/ppc/boot/include/rs6000.h linux-2.4.22/arch/ppc/boot/include/rs6000.h --- linux-2.4.21/arch/ppc/boot/include/rs6000.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/include/rs6000.h 2003-08-25 04:44:40.000000000 -0700 @@ -35,7 +35,7 @@ /********************** AOUT "OPTIONAL HEADER" **********************/ -typedef struct +typedef struct { unsigned char magic[2]; /* type of file */ unsigned char vstamp[2]; /* version stamp */ @@ -135,7 +135,7 @@ #define E_FILNMLEN 14 /* # characters in a file name */ #define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ -struct external_syment +struct external_syment { union { char e_name[E_SYMNMLEN]; @@ -157,7 +157,7 @@ #define N_TMASK (060) #define N_BTSHFT (4) #define N_TSHIFT (2) - + union external_auxent { struct { @@ -214,7 +214,7 @@ }; #define SYMENT struct external_syment -#define SYMESZ 18 +#define SYMESZ 18 #define AUXENT union external_auxent #define AUXESZ 18 #define DBXMASK 0x80 /* for dbx storage mask */ diff -urN linux-2.4.21/arch/ppc/boot/include/zlib.h linux-2.4.22/arch/ppc/boot/include/zlib.h --- linux-2.4.21/arch/ppc/boot/include/zlib.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/include/zlib.h 2003-08-25 04:44:40.000000000 -0700 @@ -44,7 +44,7 @@ /* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ @@ -137,7 +137,7 @@ #define ZLIB_VERSION "0.95P" -/* +/* 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 @@ -254,7 +254,7 @@ /* basic functions */ extern int inflateInit OF((z_stream *strm)); -/* +/* Initializes the internal stream state for decompression. The fields zalloc and zfree must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation @@ -333,7 +333,7 @@ extern int inflateInit2 OF((z_stream *strm, int windowBits)); -/* +/* This is another version of inflateInit with more compression options. The fields next_out, zalloc and zfree must be initialized before by the caller. @@ -365,7 +365,7 @@ */ extern int inflateSync OF((z_stream *strm)); -/* +/* Skips invalid compressed data until the special marker (see deflate() above) can be found, or until all available input is skipped. No output is provided. diff -urN linux-2.4.21/arch/ppc/boot/lib/zlib.c linux-2.4.22/arch/ppc/boot/lib/zlib.c --- linux-2.4.21/arch/ppc/boot/lib/zlib.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/lib/zlib.c 2003-08-25 04:44:40.000000000 -0700 @@ -118,7 +118,7 @@ /* deflate.h -- internal compression state * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -129,7 +129,7 @@ /*+++++*/ /* infblock.h -- header to use infblock.c * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -170,7 +170,7 @@ /*+++++*/ /* inftrees.h -- header to use inftrees.c * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -232,7 +232,7 @@ /*+++++*/ /* infcodes.h -- header to use infcodes.c * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -261,7 +261,7 @@ /*+++++*/ /* inflate.c -- zlib interface to inflate modules * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* inflate private state */ @@ -293,7 +293,7 @@ /* mode independent information */ int nowrap; /* flag for no wrapper */ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef + inflate_blocks_statef *blocks; /* current inflate_blocks state */ }; @@ -568,7 +568,7 @@ /*+++++*/ /* infutil.h -- types and macros common to blocks and codes * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -606,7 +606,7 @@ } trees; /* if DTREE, decoding info for trees */ struct { inflate_huft *tl, *td; /* trees to free */ - inflate_codes_statef + inflate_codes_statef *codes; } decode; /* if CODES, current state */ } sub; /* submode */ @@ -664,7 +664,7 @@ /*+++++*/ /* inffast.h -- header to use inffast.c * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -684,7 +684,7 @@ /*+++++*/ /* infblock.c -- interpret and process block types to last block * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* Table for deflate from PKZIP's appnote.txt. */ @@ -1139,7 +1139,7 @@ /*+++++*/ /* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ @@ -1232,7 +1232,7 @@ uInt n; /* number of codes (assumed <= N_MAX) */ uInt s; /* number of simple-valued codes (0..s-1) */ uIntf *d; /* list of base values for non-simple codes */ -uIntf *e; /* list of extra bits for non-simple codes */ +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_stream *zs; /* for zalloc function */ @@ -1602,14 +1602,14 @@ q = (--p)->next; ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); p = q; - } + } return Z_OK; } /*+++++*/ /* infcodes.c -- process literals and length/distance pairs * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ @@ -1850,7 +1850,7 @@ /*+++++*/ /* inflate_util.c -- data and routines common to blocks and codes * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* copy as much as possible from the sliding window to the output area */ @@ -1923,7 +1923,7 @@ /*+++++*/ /* inffast.c -- process literals and length/distance pairs fast * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ @@ -2084,7 +2084,7 @@ /*+++++*/ /* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ @@ -2105,7 +2105,7 @@ /*+++++*/ /* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ diff -urN linux-2.4.21/arch/ppc/boot/pmac/Makefile linux-2.4.22/arch/ppc/boot/pmac/Makefile --- linux-2.4.21/arch/ppc/boot/pmac/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/pmac/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -30,8 +30,6 @@ TFTPIMAGE=/tftpboot/zImage.pmac$(END) -AFLAGS_../common/crt0.o += -I$(TOPDIR)/arch/$(ARCH)/kernel - ../common/coffcrt0.o: $(MAKE) -C ../common coffcrt0.o diff -urN linux-2.4.21/arch/ppc/boot/pmac/chrpmain.c linux-2.4.22/arch/ppc/boot/pmac/chrpmain.c --- linux-2.4.21/arch/ppc/boot/pmac/chrpmain.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/pmac/chrpmain.c 2003-08-25 04:44:40.000000000 -0700 @@ -38,13 +38,15 @@ #define SCRATCH_SIZE (128 << 10) +typedef void (*kernel_start_t)(int, int, void *); + void boot(int a1, int a2, void *prom) { unsigned sa, len; void *dst; unsigned char *im; unsigned initrd_start, initrd_size; - + printf("chrpboot starting: loaded at 0x%p\n", &_start); initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); @@ -87,7 +89,7 @@ sa = (unsigned long)PROG_START; printf("start address = 0x%x\n", sa); - (*(void (*)())sa)(a1, a2, prom); + (*(kernel_start_t)sa)(a1, a2, prom); printf("returned?\n"); diff -urN linux-2.4.21/arch/ppc/boot/pmac/coffmain.c linux-2.4.22/arch/ppc/boot/pmac/coffmain.c --- linux-2.4.21/arch/ppc/boot/pmac/coffmain.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/pmac/coffmain.c 2003-08-25 04:44:40.000000000 -0700 @@ -44,13 +44,15 @@ static char heap[SCRATCH_SIZE]; +typedef void (*kernel_start_t)(int, int, void *); + void boot(int a1, int a2, void *prom) { unsigned sa, len; void *dst; unsigned char *im; unsigned initrd_start, initrd_size; - + printf("coffboot starting: loaded at 0x%p\n", &_start); setup_bats(RAM_START); @@ -92,7 +94,7 @@ sa = (unsigned long)PROG_START; printf("start address = 0x%x\n", sa); - (*(void (*)())sa)(a1, a2, prom); + (*(kernel_start_t)sa)(a1, a2, prom); printf("returned?\n"); diff -urN linux-2.4.21/arch/ppc/boot/pmac/start.c linux-2.4.22/arch/ppc/boot/pmac/start.c --- linux-2.4.21/arch/ppc/boot/pmac/start.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/pmac/start.c 2003-08-25 04:44:40.000000000 -0700 @@ -11,7 +11,7 @@ extern int strlen(const char *s); extern void boot(int a1, int a2, void *prom); -int (*prom)(); +int (*prom)(void *args); void *chosen_handle; void *stdin; @@ -26,7 +26,7 @@ void start(int a1, int a2, void *promptr) { - prom = (int (*)()) promptr; + prom = (int (*)(void *)) promptr; chosen_handle = finddevice("/chosen"); if (chosen_handle == (void *) -1) exit(); diff -urN linux-2.4.21/arch/ppc/boot/prep/Makefile linux-2.4.22/arch/ppc/boot/prep/Makefile --- linux-2.4.21/arch/ppc/boot/prep/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/prep/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -39,10 +39,6 @@ # Extra include search dirs CFLAGS_kbd.o += -I$(TOPDIR)/drivers/char -AFLAGS_head.o += -I$(TOPDIR)/arch/$(ARCH)/kernel -AFLAGS_../common/util.o += -I$(TOPDIR)/arch/$(ARCH)/kernel -AFLAGS_../common/relocate.o += -I$(TOPDIR)/arch/$(ARCH)/kernel -AFLAGS_../simple/legacy.o += -I$(TOPDIR)/arch/$(ARCH)/kernel all: zImage diff -urN linux-2.4.21/arch/ppc/boot/prep/misc.c linux-2.4.22/arch/ppc/boot/prep/misc.c --- linux-2.4.21/arch/ppc/boot/prep/misc.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/prep/misc.c 2003-08-25 04:44:40.000000000 -0700 @@ -353,7 +353,7 @@ unsigned long initrd_loc; unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) + (1 << 20) - 1, (1 << 20)); - + rec = (struct bi_record *)rec_loc; /* We need to make sure that the initrd and bi_recs do not diff -urN linux-2.4.21/arch/ppc/boot/prep/of1275.h linux-2.4.22/arch/ppc/boot/prep/of1275.h --- linux-2.4.21/arch/ppc/boot/prep/of1275.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/prep/of1275.h 2003-08-25 04:44:40.000000000 -0700 @@ -197,7 +197,7 @@ const char *method; int ihandle; /*...*/ - int args[0]; + int args[0]; } of_call_method_service; int of_call_method(const char *method, int ihandle, ...); diff -urN linux-2.4.21/arch/ppc/boot/simple/Makefile linux-2.4.22/arch/ppc/boot/simple/Makefile --- linux-2.4.21/arch/ppc/boot/simple/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/simple/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -33,7 +33,9 @@ ZIMAGEINITRD := zImage.initrd-SMON TFTPIMAGE := /tftpboot/zImage.gemini endif -ifeq ($(CONFIG_LOPEC),y) +# kbuild-2.4 'feature', only one of these will ever by 'y' at a time. +# The rest will be unset. +ifeq ($(CONFIG_LOPEC)$(CONFIG_PPLUS),y) ZIMAGE := zImage-PPLUS ZIMAGEINITRD := zImage.initrd-PPLUS EXTRA := ../common/mpc10x_memory.o @@ -41,7 +43,9 @@ ZNETBOOT := zImage.pplus ZNETBOOTRD := zImage.initrd.pplus endif - +ifeq ($(CONFIG_PPLUS),y) +EXTRA := legacy.o +endif ifeq ($(CONFIG_PAL4),y) ZIMAGE := zImage-PAL4 ZIMAGEINITRD := zImage.initrd-PAL4 @@ -74,7 +78,7 @@ $(MISC) ../common/misc-common.o \ ../common/string.o ../common/util.o \ ../common/serial_stub.o -obj-$(CONFIG_4xx) += embed_config.o +obj-$(CONFIG_40x) += embed_config.o obj-$(CONFIG_8xx) += embed_config.o obj-$(CONFIG_8260) += embed_config.o obj-$(CONFIG_BSEIP) += iic.o diff -urN linux-2.4.21/arch/ppc/boot/simple/embed_config.c linux-2.4.22/arch/ppc/boot/simple/embed_config.c --- linux-2.4.21/arch/ppc/boot/simple/embed_config.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/simple/embed_config.c 2003-08-25 04:44:40.000000000 -0700 @@ -369,8 +369,8 @@ bd->bi_memstart = 0; bd->bi_memsize = (8 * 1024 * 1024); - bd->bi_intfreq = 40000000; - bd->bi_busfreq = 40000000; + bd->bi_intfreq = 48000000; + bd->bi_busfreq = 48000000; } #endif /* FADS */ diff -urN linux-2.4.21/arch/ppc/boot/simple/iic.c linux-2.4.22/arch/ppc/boot/simple/iic.c --- linux-2.4.21/arch/ppc/boot/simple/iic.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/simple/iic.c 2003-08-25 04:44:40.000000000 -0700 @@ -173,7 +173,7 @@ } #endif #endif - + /* Chip errata, clear enable. */ i2c->i2c_i2mod = 0; @@ -207,7 +207,7 @@ while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) temp--; #endif - + /* Chip errata, clear enable. */ i2c->i2c_i2mod = 0; diff -urN linux-2.4.21/arch/ppc/boot/simple/misc-spruce.c linux-2.4.22/arch/ppc/boot/simple/misc-spruce.c --- linux-2.4.21/arch/ppc/boot/simple/misc-spruce.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/simple/misc-spruce.c 2003-08-25 04:44:40.000000000 -0700 @@ -395,7 +395,7 @@ unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) + (1 << 20) - 1, (1 << 20)); rec = (struct bi_record *)rec_loc; - + /* We need to make sure that the initrd and bi_recs do not * overlap. */ if ( initrd_size ) { diff -urN linux-2.4.21/arch/ppc/boot/utils/mkbugboot.c linux-2.4.22/arch/ppc/boot/utils/mkbugboot.c --- linux-2.4.21/arch/ppc/boot/utils/mkbugboot.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/utils/mkbugboot.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,8 +1,8 @@ /* * arch/ppc/pp3boot/mkbugboot.c - * - * Makes a Motorola PPCBUG ROM bootable image which can be flashed - * into one of the FLASH banks on a Motorola PowerPlus board. + * + * Makes a Motorola PPCBUG ROM bootable image which can be flashed + * into one of the FLASH banks on a Motorola PowerPlus board. * * Author: Matt Porter * @@ -99,7 +99,7 @@ { uint8_t header_block[HEADER_SIZE]; bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0]; - + memset(header_block, 0, HEADER_SIZE); /* Fill in the PPCBUG ROM boot header */ @@ -146,7 +146,7 @@ } /* Get file args */ - + /* kernel image file */ if ((image_fd = open( argv[argptr] , 0)) < 0) exit(-1); @@ -182,7 +182,7 @@ bugboot_fd = open(bugbootname, O_RDWR); /* Calculate checksum */ - checksum = calc_checksum(bugboot_fd); + checksum = calc_checksum(bugboot_fd); /* Write out the calculated checksum */ write(bugboot_fd, &checksum, 2); diff -urN linux-2.4.21/arch/ppc/boot/utils/mknote.c linux-2.4.22/arch/ppc/boot/utils/mknote.c --- linux-2.4.21/arch/ppc/boot/utils/mknote.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/utils/mknote.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,7 +25,7 @@ PL(0x1275); /* name */ printf("PowerPC"); printf("%c", 0); - + /* descriptor */ /* real-mode */ PL(0xffffffff); diff -urN linux-2.4.21/arch/ppc/boot/utils/mkprep.c linux-2.4.22/arch/ppc/boot/utils/mkprep.c --- linux-2.4.21/arch/ppc/boot/utils/mkprep.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/utils/mkprep.c 2003-08-25 04:44:40.000000000 -0700 @@ -96,14 +96,14 @@ } /* needs to handle args more elegantly -- but this is a small/simple program */ - + /* check for -pbp */ if ( !strcmp( argv[argptr], "-pbp" ) ) { prep = 1; argptr++; } - + /* check for -asm */ if ( !strcmp( argv[argptr], "-asm" ) ) { @@ -130,7 +130,7 @@ /* skip elf header in input file */ /*if ( !prep )*/ lseek(in_fd, elfhdr_size, SEEK_SET); - + /* write prep partition if necessary */ if ( prep ) write_prep_partition( in_fd, out_fd ); @@ -140,7 +140,7 @@ write_asm_data( in_fd, out_fd ); else copy_image(in_fd, out_fd); - + return 0; } @@ -151,15 +151,15 @@ dword_t *entry = (dword_t *)&block[0]; dword_t *length = (dword_t *)&block[sizeof(long)]; struct stat info; - + if (fstat(in, &info) < 0) { fprintf(stderr,"info failed\n"); exit(-1); } - + bzero( block, sizeof block ); - + /* set entry point and boot image size skipping over elf header */ #ifdef __i386__ *entry = 0x400/*+65536*/; @@ -172,7 +172,7 @@ /* sets magic number for msdos partition (used by linux) */ block[510] = 0x55; block[511] = 0xAA; - + /* * Build a "PReP" partition table entry in the boot record * - "PReP" may only look at the system_indicator @@ -203,13 +203,13 @@ #if 0 pe->beginning_sector = cpu_to_le32(1); #else - /* This has to be 0 on the PowerStack? */ + /* This has to be 0 on the PowerStack? */ #ifdef __i386__ pe->beginning_sector = 0; #else pe->beginning_sector = cpu_to_le32(0); #endif /* __i386__ */ -#endif +#endif #ifdef __i386__ pe->number_of_sectors = 2*18*80-1; @@ -219,7 +219,7 @@ write( out, block, sizeof(block) ); write( out, entry, sizeof(*entry) ); - write( out, length, sizeof(*length) ); + write( out, length, sizeof(*length) ); /* set file position to 2nd sector where image will be written */ lseek( out, 0x400, SEEK_SET ); } @@ -245,7 +245,7 @@ unsigned char *lp; unsigned char buf[SIZE]; unsigned char str[256]; - + write( out, "\t.data\n\t.globl input_data\ninput_data:\n", strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) ); pos = 0; diff -urN linux-2.4.21/arch/ppc/boot/utils/mktree.c linux-2.4.22/arch/ppc/boot/utils/mktree.c --- linux-2.4.21/arch/ppc/boot/utils/mktree.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/boot/utils/mktree.c 2003-08-25 04:44:40.000000000 -0700 @@ -89,7 +89,7 @@ cp = (uint *)&bt; for (i=0; i> 5); - + __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%3 \n\ or %0,%0,%2 \n" diff -urN linux-2.4.21/arch/ppc/kernel/btext.c linux-2.4.22/arch/ppc/kernel/btext.c --- linux-2.4.21/arch/ppc/kernel/btext.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/btext.c 2003-08-25 04:44:40.000000000 -0700 @@ -111,13 +111,13 @@ /* Calc BAT values for mapping the display and store them * in disp_BAT. Those values are then used from head.S to map * the display during identify_machine() and MMU_Init() - * + * * The display is mapped to virtual address 0xD0000000, rather * than 1:1, because some some CHRP machines put the frame buffer * in the region starting at 0xC0000000 (KERNELBASE). * This mapping is temporary and will disappear as soon as the * setup done by MMU_Init() is applied. - * + * * For now, we align the BAT and then map 8Mb on 601 and 16Mb * on other PPCs. This may cause trouble if the framebuffer * is really badly aligned, but I didn't encounter this case @@ -141,7 +141,7 @@ lowbits = addr & ~0xFF000000UL; addr &= 0xFF000000UL; disp_BAT[0] = vaddr | (BL_16M<<2) | 2; - disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); + disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); } else { /* 601 */ lowbits = addr & ~0xFF800000UL; @@ -177,9 +177,9 @@ /* Here's a small text engine to use during early boot * or for debugging purposes - * + * * todo: - * + * * - build some kind of vgacon with it to enable early printk * - move to a separate file * - add a few video driver hooks to keep in sync with display @@ -258,7 +258,7 @@ unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3)) >> 2; int i,j; - + for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++) { unsigned long *ptr = base; @@ -280,7 +280,7 @@ unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3)) >> 2; int i,j; - + for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++) { unsigned long *ptr = base; @@ -302,7 +302,7 @@ unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3)) >> 2; int i,j; - + #ifdef CONFIG_ADB_PMU pmu_suspend(); /* PMU will not shut us down ! */ #endif @@ -389,7 +389,7 @@ btext_drawhex(unsigned long v) { static char hex_table[] = "0123456789abcdef"; - + if (!boot_text_mapped) return; btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]); @@ -410,7 +410,7 @@ unsigned char *base = calc_base(bi, locX << 3, locY << 4); unsigned char *font = &vga_font[((unsigned long)c) * 16]; int rb = bi->dispDeviceRowBytes; - + switch(bi->dispDeviceDepth) { case 24: case 32: @@ -456,10 +456,10 @@ static void BTEXT draw_byte_32(unsigned char *font, unsigned long *base, int rb) { - int l, bits; + int l, bits; int fg = 0xFFFFFFFFUL; int bg = 0x00000000UL; - + for (l = 0; l < 16; ++l) { bits = *font++; @@ -478,7 +478,7 @@ static void BTEXT draw_byte_16(unsigned char *font, unsigned long *base, int rb) { - int l, bits; + int l, bits; int fg = 0xFFFFFFFFUL; int bg = 0x00000000UL; unsigned long *eb = expand_bits_16; @@ -497,7 +497,7 @@ static void BTEXT draw_byte_8(unsigned char *font, unsigned long *base, int rb) { - int l, bits; + int l, bits; int fg = 0x0F0F0F0FUL; int bg = 0x00000000UL; unsigned long *eb = expand_bits_8; @@ -512,346 +512,346 @@ } static unsigned char vga_font[cmapsz] BTDATA = { -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, -0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, -0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, -0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, -0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, -0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, -0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, -0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, -0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, -0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, -0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, -0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, -0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, -0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, -0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, -0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, -0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, -0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, -0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, -0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, -0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, -0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, -0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, -0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, -0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, -0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, -0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, -0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, -0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, -0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, -0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, -0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, -0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, -0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, -0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, -0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, -0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, -0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, -0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, -0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, -0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, -0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, -0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, -0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, -0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, -0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, -0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, -0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, -0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, -0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, -0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, -0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, -0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, -0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, -0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, -0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, -0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, -0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, -0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, -0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, -0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, -0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, -0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, -0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, -0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, -0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, -0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, -0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, -0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, -0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, -0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, -0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, -0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, -0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, -0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, -0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, -0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, -0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, -0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, -0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, -0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, -0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, -0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, -0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, -0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, -0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, -0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, -0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, -0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, -0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, -0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, -0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, -0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, -0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, -0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, -0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, -0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, -0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, -0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, -0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, -0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, -0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, -0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, -0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, -0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, -0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, -0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, -0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, -0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, -0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, -0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, -0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, -0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, -0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, -0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, -0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, -0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, -0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, -0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, -0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, -0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, -0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, -0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, -0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, -0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, -0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, -0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, -0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, -0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, -0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, -0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, -0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, -0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, -0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, -0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, -0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, -0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, -0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, -0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, -0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, -0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, -0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, +0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, +0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, +0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, +0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, +0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, +0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, +0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, +0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, +0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, +0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, +0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, +0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, +0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, +0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, +0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, +0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, +0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, +0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, +0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, +0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, +0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, +0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, +0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, +0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, +0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, +0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, +0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, +0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, +0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, +0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, +0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, +0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, +0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, +0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, +0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, +0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, +0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, +0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, +0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, +0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, +0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, +0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, +0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, +0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, +0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, +0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, +0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, +0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, +0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, +0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, +0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, +0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, +0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, +0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, +0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, +0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, +0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, +0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, +0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, +0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, +0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, +0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, +0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, +0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, +0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, +0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, +0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, +0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, +0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, +0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, +0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, }; diff -urN linux-2.4.21/arch/ppc/kernel/checks.c linux-2.4.22/arch/ppc/kernel/checks.c --- linux-2.4.21/arch/ppc/kernel/checks.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/checks.c 2003-08-25 04:44:40.000000000 -0700 @@ -32,7 +32,7 @@ sizeof(struct thread_struct)%16); ret = -1; } -#endif +#endif if ( sizeof(struct pt_regs) % 16 ) { @@ -41,7 +41,7 @@ sizeof(struct pt_regs), sizeof(struct pt_regs)%16); ret = -1; - + } printf("Task size : %d bytes\n" diff -urN linux-2.4.21/arch/ppc/kernel/cpu_setup_6xx.S linux-2.4.22/arch/ppc/kernel/cpu_setup_6xx.S --- linux-2.4.21/arch/ppc/kernel/cpu_setup_6xx.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/cpu_setup_6xx.S 2003-08-25 04:44:40.000000000 -0700 @@ -142,7 +142,7 @@ sync isync blr - + /* 740/750/7400/7410 * Enable Store Gathering (SGE), Address Brodcast (ABE), * Branch History Table (BHTE), Branch Target ICache (BTIC) @@ -213,7 +213,7 @@ li r7,CPU_FTR_CAN_NAP andc r6,r6,r7 stw r6,CPU_SPEC_FEATURES(r5) -1: +1: mfspr r11,HID0 /* All of the bits we have to set..... @@ -248,20 +248,21 @@ /* Definitions for the table use to save CPU states */ #define CS_HID0 0 #define CS_HID1 4 -#define CS_MSSCR0 8 -#define CS_MSSSR0 12 -#define CS_ICTRL 16 -#define CS_LDSTCR 20 -#define CS_LDSTDB 24 -#define CS_SIZE 28 +#define CS_HID2 8 +#define CS_MSSCR0 12 +#define CS_MSSSR0 16 +#define CS_ICTRL 20 +#define CS_LDSTCR 24 +#define CS_LDSTDB 28 +#define CS_SIZE 32 .data .balign L1_CACHE_LINE_SIZE -cpu_state_storage: +cpu_state_storage: .space CS_SIZE .balign L1_CACHE_LINE_SIZE,0 .text - + /* Called in normal context to backup CPU 0 state. This * does not include cache settings. This function is also * called for machine sleep. This does not include the MMU @@ -311,11 +312,18 @@ stw r4,CS_LDSTCR(r5) mfspr r4,SPRN_LDSTDB stw r4,CS_LDSTDB(r5) -1: +1: bne cr5,1f /* Backup 750FX specific registers */ mfspr r4,SPRN_HID1 stw r4,CS_HID1(r5) + /* If rev 2.x, backup HID2 */ + mfspr r3,PVR + andi. r3,r3,0xff00 + cmpi cr0,r3,0x0200 + bne 1f + mfspr r4,SPRN_HID2 + stw r4,CS_HID2(r5) 1: mtcr r7 blr @@ -395,9 +403,19 @@ sync 2: bne cr5,1f /* Restore 750FX specific registers - * that is restore PLL config & switch - * to PLL 0 + * that is restore HID2 on rev 2.x and PLL config & switch + * to PLL 0 on all */ + /* If rev 2.x, restore HID2 with low voltage bit cleared */ + mfspr r3,PVR + andi. r3,r3,0xff00 + cmpi cr0,r3,0x0200 + bne 4f + lwz r4,CS_HID2(r5) + rlwinm r4,r4,0,19,17 + mtspr SPRN_HID2,r4 + sync +4: lwz r4,CS_HID1(r5) rlwinm r5,r4,0,16,14 mtspr SPRN_HID1,r5 diff -urN linux-2.4.21/arch/ppc/kernel/cputable.c linux-2.4.22/arch/ppc/kernel/cputable.c --- linux-2.4.21/arch/ppc/kernel/cputable.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/cputable.c 2003-08-25 04:44:40.000000000 -0700 @@ -140,16 +140,25 @@ 32, 32, __setup_cpu_750cx }, + { /* 750FX rev 1.x */ + 0xffffff00, 0x70000100, "750FX", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP | + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM, + COMMON_PPC, + 32, 32, + __setup_cpu_750 + }, { /* 750FX rev 2.0 must disable HID0[DPM] */ 0xffffffff, 0x70000200, "750FX", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP | - CPU_FTR_NO_DPM, + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NO_DPM, COMMON_PPC, 32, 32, __setup_cpu_750 }, - { /* 750FX (All revs except 2.0) */ + { /* 750FX (All revs > 2.0) */ 0xffff0000, 0x70000000, "750FX", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP | @@ -274,7 +283,7 @@ 32, 32, __setup_cpu_generic }, -#endif /* CLASSIC_PPC */ +#endif /* CLASSIC_PPC */ #ifdef CONFIG_PPC64BRIDGE { /* Power3 */ 0xffff0000, 0x00400000, "Power3 (630)", @@ -304,7 +313,7 @@ 128, 128, __setup_cpu_power3 }, -#endif /* CONFIG_PPC64BRIDGE */ +#endif /* CONFIG_PPC64BRIDGE */ #ifdef CONFIG_POWER4 { /* Power4 */ 0xffff0000, 0x00350000, "Power4", @@ -313,7 +322,7 @@ 128, 128, __setup_cpu_power4 }, -#endif /* CONFIG_POWER4 */ +#endif /* CONFIG_POWER4 */ #ifdef CONFIG_8xx { /* 8xx */ 0xffff0000, 0x00500000, "8xx", @@ -324,7 +333,7 @@ __setup_cpu_8xx /* Empty */ }, #endif /* CONFIG_8xx */ -#ifdef CONFIG_4xx +#ifdef CONFIG_40x { /* 403GC */ 0xffffff00, 0x00200200, "403GC", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, diff -urN linux-2.4.21/arch/ppc/kernel/entry.S linux-2.4.22/arch/ppc/kernel/entry.S --- linux-2.4.21/arch/ppc/kernel/entry.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP * Copyright (C) 1996 Cort Dougan @@ -16,7 +16,7 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. - * + * */ #include @@ -162,7 +162,7 @@ blrl /* Call handler */ .globl ret_from_syscall_2 ret_from_syscall_2: - stw r3,RESULT(r1) /* Save result */ + stw r3,RESULT(r1) /* Save result */ li r10,-_LAST_ERRNO cmpl 0,r3,r10 blt 60f @@ -202,7 +202,7 @@ * * The code which creates the new task context is in 'copy_thread' * in arch/ppc/kernel/process.c - */ + */ _GLOBAL(_switch) stwu r1,-INT_FRAME_SIZE(r1) stw r0,GPR0(r1) @@ -291,7 +291,7 @@ bl do_signal .globl do_signal_ret do_signal_ret: - .globl ret_to_user_hook + .globl ret_to_user_hook ret_to_user_hook: nop restore: @@ -303,10 +303,13 @@ REST_GPR(31,r1) /* make sure we hard disable here, even if rtl is active, to protect - * SRR[01] and SPRG2 -- Cort + * SRR[01] and SPRG2 -- Cort */ mfmsr r0 /* Get current interrupt state */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ +#ifdef CONFIG_4xx + rlwinm r0,r0,0,23,21 /* clear MSR_DE in r0 */ +#endif SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ @@ -323,6 +326,14 @@ mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ +#if defined(CONFIG_4xx) && !defined(CONFIG_BDI_SWITCH) + /* Restore the processor debugging state of the thread. Only do + * this if we aren't using an Abatron BDI JTAG debugger. It doesn't + * tolerate others mucking with the debug registers. + */ + lwz r0,THREAD+THREAD_DBCR0(r2) + mtspr SPRN_DBCR0,r0 +#endif addi r0,r1,INT_FRAME_SIZE /* size of frame */ stw r0,THREAD+KSP(r2) /* save kernel stack pointer */ tophys(r8,r1) @@ -340,7 +351,7 @@ /* We have to "dummy" load from the context save area in case * these instructions cause an MMU fault. If this happens * after we load SRR0/SRR1, our return context is hosed. -- Dan - * + * * This workaround is not enough, we must also make sure the * actual code for this routine is in the TLB or BAT mapped. * For 6xx/Power3, we know the code is in a BAT, so this should @@ -379,7 +390,7 @@ /* - * PROM code for specific machines follows. Put it + * PROM code for specific machines follows. Put it * here so it's easy to add arch-specific sections later. * -- Cort */ diff -urN linux-2.4.21/arch/ppc/kernel/find_name.c linux-2.4.22/arch/ppc/kernel/find_name.c --- linux-2.4.21/arch/ppc/kernel/find_name.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/find_name.c 2003-08-25 04:44:40.000000000 -0700 @@ -12,7 +12,7 @@ unsigned long addr, cmp, i; FILE *f; char s[256], last[256]; - + if ( argc < 2 ) { fprintf(stderr, "Usage: %s
\n", argv[0]); @@ -25,13 +25,13 @@ /* adjust if addr is relative to kernelbase */ if ( addr < PAGE_OFFSET ) addr += PAGE_OFFSET; - + if ( (f = fopen( "System.map", "r" )) == NULL ) { perror("fopen()\n"); exit(-1); } - + while ( !feof(f) ) { fgets(s, 255 , f); @@ -40,9 +40,9 @@ break; strcpy( last, s); } - + printf( "%s%s", last, s ); - } + } fclose(f); return 0; } diff -urN linux-2.4.21/arch/ppc/kernel/gen550_dbg.c linux-2.4.22/arch/ppc/kernel/gen550_dbg.c --- linux-2.4.21/arch/ppc/kernel/gen550_dbg.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/gen550_dbg.c 2003-08-25 04:44:40.000000000 -0700 @@ -56,6 +56,7 @@ unsigned long serial_init(int chan, void *ignored) { unsigned long com_port; + unsigned char lcr, dlm; /* We need to find out which type io we're expecting. If it's * 'SERIAL_IO_PORT', we get an offset from the isa_io_base. @@ -78,22 +79,38 @@ /* How far apart the registers are. */ shift = rs_table[chan].iomem_reg_shift; - + + /* save the LCR */ + lcr = serial_inb(com_port + (UART_LCR << shift)); + /* Access baud rate */ - serial_outb(com_port + (UART_LCR << shift), 0x80); + serial_outb(com_port + (UART_LCR << shift), UART_LCR_DLAB); + dlm = serial_inb(com_port + (UART_DLM << shift)); - /* Input clock. */ - serial_outb(com_port + (UART_DLL << shift), + /* + * Test if serial port is unconfigured + * We assume that no-one uses less than 110 baud or + * less than 7 bits per character these days. + * -- paulus. + */ + if ((dlm <= 4) && (lcr & 2)) { + /* port is configured, put the old LCR back */ + serial_outb(com_port + (UART_LCR << shift), lcr); + } + else { + /* Input clock. */ + serial_outb(com_port + (UART_DLL << shift), (rs_table[chan].baud_base / SERIAL_BAUD) & 0xFF); - serial_outb(com_port + (UART_DLM << shift), - (rs_table[chan].baud_base / SERIAL_BAUD) >> 8); - /* 8 data, 1 stop, no parity */ - serial_outb(com_port + (UART_LCR << shift), 0x03); - /* RTS/DTR */ - serial_outb(com_port + (UART_MCR << shift), 0x03); + serial_outb(com_port + (UART_DLM << shift), + (rs_table[chan].baud_base / SERIAL_BAUD) >> 8); + /* 8 data, 1 stop, no parity */ + serial_outb(com_port + (UART_LCR << shift), 0x03); + /* RTS/DTR */ + serial_outb(com_port + (UART_MCR << shift), 0x03); - /* Clear & enable FIFOs */ - serial_outb(com_port + (UART_FCR << shift), 0x07); + /* Clear & enable FIFOs */ + serial_outb(com_port + (UART_FCR << shift), 0x07); + } return (com_port); } diff -urN linux-2.4.21/arch/ppc/kernel/gen550_kgdb.c linux-2.4.22/arch/ppc/kernel/gen550_kgdb.c --- linux-2.4.21/arch/ppc/kernel/gen550_kgdb.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/gen550_kgdb.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * port(s) to be used can be accomplished by setting * ppc_md.early_serial_map to a platform-specific mapping function. * - * Adapted from ppc4xx_kgdb.c. + * Adapted from ppc4xx_kgdb.c. * * Matt Porter * diff -urN linux-2.4.21/arch/ppc/kernel/head.S linux-2.4.22/arch/ppc/kernel/head.S --- linux-2.4.21/arch/ppc/kernel/head.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP @@ -66,7 +66,7 @@ mtspr DBAT##n##U,RA; \ mtspr DBAT##n##L,RB; \ 1: -#endif /* CONFIG_PPC64BRIDGE */ +#endif /* CONFIG_PPC64BRIDGE */ .text .globl _stext @@ -79,7 +79,7 @@ .text .globl _start _start: - /* + /* * These are here for legacy reasons, the kernel used to * need to look like a coff function entry for the pmac * but we're always started by some kind of bootloader now. @@ -145,8 +145,8 @@ bl early_init #ifdef CONFIG_APUS -/* On APUS the __va/__pa constants need to be set to the correct - * values before continuing. +/* On APUS the __va/__pa constants need to be set to the correct + * values before continuing. */ mr r4,r30 bl fix_mem_constants @@ -1181,7 +1181,7 @@ /* * Map the memory where the exception handlers will - * be copied to when hash constants have been patched. + * be copied to when hash constants have been patched. */ #ifdef CONFIG_APUS_FAST_EXCEPT lis r8,0xfff0 @@ -1277,7 +1277,7 @@ lis r3,-KERNELBASE@h bl init_idle_6xx #endif /* CONFIG_6xx */ - + /* get current */ lis r2,current_set@h ori r2,r2,current_set@l @@ -1498,13 +1498,13 @@ isync blr -/* +/* * An undocumented "feature" of 604e requires that the v bit * be cleared before changing BAT values. * * Also, newer IBM firmware does not clear bat3 and 4 so * this makes sure it's done. - * -- Cort + * -- Cort */ clear_bats: li r20,0 @@ -1575,7 +1575,7 @@ sync RFI -#ifndef CONFIG_POWER4 +#ifndef CONFIG_POWER4 /* * Use the first pair of BAT registers to map the 1st 16MB * of RAM to KERNELBASE. From this point on we can't safely diff -urN linux-2.4.21/arch/ppc/kernel/head_4xx.S linux-2.4.22/arch/ppc/kernel/head_4xx.S --- linux-2.4.21/arch/ppc/kernel/head_4xx.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/head_4xx.S 2003-08-25 04:44:40.000000000 -0700 @@ -11,6 +11,13 @@ * PowerPC 403GCX modifications. * Copyright (c) 1999 Grant Erickson * PowerPC 403GCX/405GP modifications. + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * PowerPC 403GCX/405GP modifications. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * * * Module name: head_4xx.S * @@ -25,45 +32,32 @@ */ #include - #include #include -#include #include - +#include +#include +#include #include #include "ppc_defs.h" - /* Preprocessor Defines */ #define STND_EXC 0 #define CRIT_EXC 1 -### -### Check to make sure the right processor has been defined. -### - -#if !defined(CONFIG_4xx) -#error "This file is only appropriate for kernels supporting the PPC4xx." -#endif - -### -### Execution entry point. -### - -### -### As with the other PowerPC ports, it is expected that when code -### execution begins here, the following registers contain valid, yet -### optional, information: -### -### r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) -### r4 - Starting address of the init RAM disk -### r5 - Ending address of the init RAM disk -### r6 - Start of kernel command line string (e.g. "mem=96m") -### r7 - End of kernel command line string -### - +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=96m") + * r7 - End of kernel command line string + * + * This is all going to change RSN when we add bi_recs....... -- Dan + */ .text _GLOBAL(_stext) _GLOBAL(_start) @@ -75,98 +69,72 @@ nop nop - ## Save residual data, init RAM disk, and command line parameters - + /* Save parameters we are passed. + */ mr r31,r3 mr r30,r4 mr r29,r5 mr r28,r6 mr r27,r7 + li r24,0 /* CPU number */ - ## Set the ID for this CPU - - li r24,0 - - ## Invalidate all TLB entries - - tlbia - - ## We should still be executing code at physical address 0x0000xxxx - ## at this point. However, start_here is at virtual address - ## 0xC000xxxx. So, set up a TLB mapping to cover this once - ## translation is enabled. - - lis r3,KERNELBASE@h # Load the kernel virtual address - ori r3,r3,KERNELBASE@l - tophys(r4,r3) # Load the kernel physical address - - ## Save the existing PID and load the kernel PID. - - mfspr r7,SPRN_PID # Save the old PID - li r0,0 - mtspr SPRN_PID,r0 # Load the kernel PID - - ## Configure and load entry into TLB slot 0. - - clrrwi r4,r4,10 # Mask off the real page number - ori r4,r4,(TLB_WR | TLB_EX) # Set the write and execute bits - - clrrwi r3,r3,10 # Mask off the effective page number - ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M)) - - tlbwe r4,r0,TLB_DATA # Load the data portion of the entry - tlbwe r3,r0,TLB_TAG # Load the tag portion of the entry - isync - - mtspr SPRN_PID,r7 # Restore the existing PID - - ## Establish the exception vector base - - lis r4,KERNELBASE@h # EVPR only uses the high 16-bits - tophys(r0,r4) # Use the physical address - mtspr SPRN_EVPR,r0 + /* We have to turn on the MMU right away so we get cache modes + * set correctly. + */ + bl initial_mmu - ## Enable the MMU and jump to the main PowerPC kernel start-up code +/* We now have the lower 16 Meg mapped into TLB entries, and the caches + * ready to work. + */ +turn_on_mmu: + li r0,MSR_KERNEL + mtspr SRR1,r0 + lis r0,start_here@h + ori r0,r0,start_here@l + mtspr SRR0,r0 + SYNC + rfi /* enables MMU */ + b . /* prevent prefetch past rfi */ - mfmsr r0 # Get the machine state register - ori r0,r0,(MSR_DR | MSR_IR) # Enable data and instr. translation - mtspr SPRN_SRR1,r0 # Set up the new machine state register - lis r0,start_here@h - ori r0,r0,start_here@l - mtspr SPRN_SRR0,r0 # Set up the new instruction pointer - rfi # Jump to start_here w/ translation on - - -### -### Exception vector entry code. This code runs with address translation -### turned off (i.e. using physical addresses). We assume SPRG3 has the -### physical address of the current task thread_struct. -### +#ifdef CONFIG_405LP + /* Reserve space for ibm405lp_wakeup_info. This contains the physical + * address of a struct ibm405lp_wakeup_info which is used by the + * firmware to pass control back to the kernel on cryo wakeup. Because + * the firmware uses this, the absolute address is fixed: don't try + * changing it. */ + . = 0xfc + .global ibm405lp_wakeup_info +ibm405lp_wakeup_info: + .long 0x0 +#endif - ## Common exception code for all exception types. +/* Exception vector entry code. This code runs with address translation + * turned off (i.e. using physical addresses). We assume SPRG3 has the + * physical address of the current task thread_struct. + */ #define COMMON_PROLOG \ -0: mtspr SPRN_SPRG0,r20; /* We need r20, move it to SPRG0 */\ - mtspr SPRN_SPRG1,r21; /* We need r21, move it to SPRG1 */\ - mfcr r20; /* We need the CR, move it to r20 */\ - mfspr r21,SPRN_SPRG2; /* Exception stack to use */\ - cmpwi cr0,r21,0; /* From user mode or RTAS? */\ - bne 1f; /* Not RTAS, branch */\ - tophys(r21, r1); /* Convert vka in r1 to pka in r21 */\ - subi r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame */\ -1: stw r20,_CCR(r21); /* Save CR on the stack */\ - stw r22,GPR22(r21); /* Save r22 on the stack */\ - stw r23,GPR23(r21); /* r23 Save on the stack */\ - mfspr r20,SPRN_SPRG0; /* Get r20 back out of SPRG0 */\ - stw r20,GPR20(r21); /* Save r20 on the stack */\ - mfspr r22,SPRN_SPRG1; /* Get r21 back out of SPRG0 */\ - stw r22,GPR21(r21); /* Save r21 on the stack */\ - mflr r20; \ - stw r20,_LINK(r21); /* Save LR on the stack */\ - mfctr r22; \ - stw r22,_CTR(r21); /* Save CTR on the stack */\ - mfspr r20,XER; \ - stw r20,_XER(r21); /* Save XER on the stack */ +0: mtspr SPRN_SPRG0,r20; /* We need r20, move it to SPRG0 */\ + mtspr SPRN_SPRG1,r21; /* We need r21, move it to SPRG1 */\ + mfcr r20; /* We need the CR, move it to r20 */\ + mfspr r21,SPRN_SPRG2; /* Exception stack to use */\ + cmpwi cr0,r21,0; /* From user mode or RTAS? */\ + bne 1f; /* Not RTAS, branch */\ + tophys(r21, r1); /* Convert vka in r1 to pka in r21 */\ + subi r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame */\ +1: stw r20,_CCR(r21); /* Save CR on the stack */\ + stw r22,GPR22(r21); /* Save r22 on the stack */\ + stw r23,GPR23(r21); /* r23 Save on the stack */\ + mfspr r20,SPRN_SPRG0; /* Get r20 back out of SPRG0 */\ + stw r20,GPR20(r21); /* Save r20 on the stack */\ + mfspr r22,SPRN_SPRG1; /* Get r21 back out of SPRG0 */\ + stw r22,GPR21(r21); /* Save r21 on the stack */\ + mflr r20; \ + stw r20,_LINK(r21); /* Save LR on the stack */\ + mfctr r22; \ + stw r22,_CTR(r21); /* Save CTR on the stack */\ + mfspr r20,XER; \ + stw r20,_XER(r21); /* Save XER on the stack */ #define COMMON_EPILOG \ stw r0,GPR0(r21); /* Save r0 on the stack */\ @@ -177,25 +145,22 @@ SAVE_4GPRS(3, r21); /* Save r3 through r6 on the stack */\ SAVE_GPR(7, r21); /* Save r7 on the stack */ - ## Common exception code for standard (non-critical) exceptions. - #define STND_EXCEPTION_PROLOG \ COMMON_PROLOG; \ mfspr r22,SPRN_SRR0; /* Faulting instruction address */\ + lis r20,MSR_WE@h; \ mfspr r23,SPRN_SRR1; /* MSR at the time of fault */\ + andc r23,r23,r20; /* disable processor wait state */\ COMMON_EPILOG; - ## Common exception code for critical exceptions. - #define CRIT_EXCEPTION_PROLOG \ COMMON_PROLOG; \ mfspr r22,SPRN_SRR2; /* Faulting instruction address */\ + lis r20,MSR_WE@h; \ mfspr r23,SPRN_SRR3; /* MSR at the time of fault */\ + andc r23,r23,r20; /* disable processor wait state */\ COMMON_EPILOG; -### -### Macros for specific exception types -### #define START_EXCEPTION(n, label) \ . = n; \ @@ -206,8 +171,8 @@ bl transfer_to_handler; \ .long func; \ .long ret_from_except - - + + #define STND_EXCEPTION(n, label, func) \ START_EXCEPTION(n, label); \ STND_EXCEPTION_PROLOG; \ @@ -216,7 +181,7 @@ li r20,MSR_KERNEL; \ FINISH_EXCEPTION(func) - + #define CRIT_EXCEPTION(n, label, func) \ START_EXCEPTION(n, label); \ CRIT_EXCEPTION_PROLOG; \ @@ -225,47 +190,191 @@ li r20,MSR_KERNEL; \ FINISH_EXCEPTION(func) - -### -### Exception vectors. -### - -### 0x0100 - Critical Interrupt Exception +/* Exception vectors. +*/ + +/* 0x0100 - Critical Interrupt Exception +*/ CRIT_EXCEPTION(0x0100, CriticalInterrupt, UnknownException) -### 0x0200 - Machine Check Exception - - CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException) +/* 0x0200 - Machine Check Exception +*/ + START_EXCEPTION(0x0200, MachineCheck) + CRIT_EXCEPTION_PROLOG + + /* + lis r4,0x0400 + mtdcr DCRN_POB0_BESR0,r4 + */ +#ifdef DCRN_POB0_BEAR + mfdcr r4,DCRN_POB0_BEAR + mfdcr r4,DCRN_POB0_BESR0 + mfdcr r4,DCRN_POB0_BESR1 +#endif -### 0x0300 - Data Storage Exception +#ifdef DCRN_PLB0_BEAR + mfdcr r4,DCRN_PLB0_ACR + mfdcr r4,DCRN_PLB0_BEAR + mfdcr r4,DCRN_PLB0_BESR +#endif - START_EXCEPTION(0x0300, DataAccess) - STND_EXCEPTION_PROLOG - mfspr r5,SPRN_ESR # Grab the ESR, save it, pass as arg3 - stw r5,_ESR(r21) - mfspr r4,SPRN_DEAR # Grab the DEAR, save it, pass as arg2 - stw r4,_DEAR(r21) addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,CRIT_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR - FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, ESR, DEAR) - -### 0x0400 - Instruction Storage Exception + FINISH_EXCEPTION(MachineCheckException) + +/* 0x0300 - Data Storage Exception + * This happens for just a few reasons. U0 set (but we don't do that), + * or zone protection fault (user violation, write to protected page). + * If this is just an update of modified status, we do that quickly + * and exit. Otherwise, we call heavywight functions to do the work. + */ + START_EXCEPTION(0x0300, DataStore) + mtspr SPRG0, r20 /* Save some working registers */ + mtspr SPRG1, r21 +#ifdef CONFIG_403GCX + stw r22, 0(r0) + stw r23, 4(r0) + mfcr r21 + mfspr r22, SPRN_PID + stw r21, 8(r0) + stw r22, 12(r0) +#else + mtspr SPRG4, r22 + mtspr SPRG5, r23 + mfcr r21 + mfspr r22, SPRN_PID + mtspr SPRG7, r21 + mtspr SPRG6, r22 +#endif + + /* First, check if it was a zone fault (which means a user + * tried to access a kernel or read-protected page - always + * a SEGV). All other faults here must be stores, so no + * need to check ESR_DST as well. */ + mfspr r20, SPRN_ESR + andis. r20, r20, ESR_DIZ@h + bne 2f + + mfspr r20, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r21, r20, 0x8000 + beq 3f + lis r21, swapper_pg_dir@h + ori r21, r21, swapper_pg_dir@l + li r23, 0 + mtspr SPRN_PID, r23 /* TLB will have 0 TID */ + b 4f + /* Get the PGD for the current thread. + */ +3: + mfspr r21,SPRG3 + lwz r21,PGDIR(r21) +4: + tophys(r21, r21) + rlwimi r21, r20, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r21, 0(r21) /* Get L1 entry */ + rlwinm. r22, r21, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + tophys(r22, r22) + rlwimi r22, r20, 22, 20, 29 /* Compute PTE address */ + lwz r21, 0(r22) /* Get Linux PTE */ + + andi. r23, r21, _PAGE_RW /* Is it writeable? */ + beq 2f /* Bail if not */ + + /* Update 'changed'. + */ + ori r21, r21, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r21, 0(r22) /* Update Linux page table */ + + /* Most of the Linux PTE is ready to load into the TLB LO. + * We set ZSEL, where only the LS-bit determines user access. + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + li r22, 0x0ce2 + andc r21, r21, r22 /* Make sure 20, 21 are zero */ + + /* find the TLB index that caused the fault. It has to be here. + */ + tlbsx r23, 0, r20 + + tlbwe r21, r23, TLB_DATA /* Load TLB LO */ + + /* Done...restore registers and get out of here. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + PPC405_ERR77_SYNC + rfi /* Should sync shadow TLBs */ + b . /* prevent prefetch past rfi */ + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + b DataAccess + +/* 0x0400 - Instruction Storage Exception + * I don't know why it is called "Storage"....This is caused by a fetch + * from non-execute or guarded pages. + */ START_EXCEPTION(0x0400, InstructionAccess) STND_EXCEPTION_PROLOG - mr r4,r22 # Pass SRR0 as arg2 - mr r5,r23 # Pass SRR1 as arg3 + mfspr r5,SPRN_ESR /* Grab the ESR, save it, not really needed */ + stw r5,_ESR(r21) + mr r4,r22 /* Pass SRR0 as arg2 */ + li r5,0 /* Pass zero as arg3 */ addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR - FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, SRR0, SRR1) - -### 0x0500 - External Interrupt Exception + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ + FINISH_EXCEPTION(do_page_fault) /* do_page_fault(regs, SRR0, SRR1) */ +/* 0x0500 - External Interrupt Exception +*/ START_EXCEPTION(0x0500, HardwareInterrupt) STND_EXCEPTION_PROLOG addi r3,r1,STACK_FRAME_OVERHEAD @@ -277,54 +386,72 @@ .long do_IRQ .long ret_from_intercept -### 0x0600 - Alignment Exception - +/* 0x0600 - Alignment Exception +*/ START_EXCEPTION(0x0600, Alignment) STND_EXCEPTION_PROLOG - mfspr r4,SPRN_DEAR # Grab the DEAR and save it + mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ stw r4,_DEAR(r21) addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ FINISH_EXCEPTION(AlignmentException) -### 0x0700 - Program Exception - +/* 0x0700 - Program Exception +*/ START_EXCEPTION(0x0700, ProgramCheck) STND_EXCEPTION_PROLOG + mfspr r4,SPRN_ESR /* Grab the ESR, save it */ + stw r4,_ESR(r21) addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ FINISH_EXCEPTION(ProgramCheckException) - - STND_EXCEPTION(0x0800, Trap_08, UnknownException) + + +/* I'm stealing this unused vector location to build a standard exception + * frame for Data TLB Access errors. The other Data TLB exceptions will bail + * out to this point if they can't resolve the lightweight TLB fault. + */ + START_EXCEPTION(0x0800, DataAccess) + STND_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r21) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + stw r4,_DEAR(r21) + addi r3,r1,STACK_FRAME_OVERHEAD + li r7,STND_EXC + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ + FINISH_EXCEPTION(do_page_fault) /* do_page_fault(regs, ESR, DEAR) */ + STND_EXCEPTION(0x0900, Trap_09, UnknownException) STND_EXCEPTION(0x0A00, Trap_0A, UnknownException) - STND_EXCEPTION(0x0B00, Trap_0B, UnknownException) -### 0x0C00 - System Call Exception - + STND_EXCEPTION(0x0B00, Trap_0B, UnknownException) +/* 0x0C00 - System Call Exception +*/ START_EXCEPTION(0x0C00, SystemCall) STND_EXCEPTION_PROLOG stw r3,ORIG_GPR3(r21) - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ FINISH_EXCEPTION(DoSyscall) STND_EXCEPTION(0x0D00, Trap_0D, UnknownException) STND_EXCEPTION(0x0E00, Trap_0E, UnknownException) STND_EXCEPTION(0x0F00, Trap_0F, UnknownException) -### 0x1000 - Programmable Interval Timer (PIT) Exception - +/* 0x1000 - Programmable Interval Timer (PIT) Exception +*/ START_EXCEPTION(0x1000, Decrementer) STND_EXCEPTION_PROLOG - lis r0,TSR_PIS@h # Set-up the PIT exception mask - mtspr SPRN_TSR,r0 # Clear the PIT exception + lis r0,TSR_PIS@h /* Set-up the PIT exception mask */ + mtspr SPRN_TSR,r0 /* Clear the PIT exception */ addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL bl transfer_to_handler _GLOBAL(timer_interrupt_intercept) @@ -332,28 +459,217 @@ .long ret_from_intercept #if 0 -### 0x1010 - Fixed Interval Timer (FIT) Exception - +/* NOTE: + * FIT and WDT handlers are not implemented yet. + */ + +/* 0x1010 - Fixed Interval Timer (FIT) Exception +*/ STND_EXCEPTION(0x1010, FITException, UnknownException) -### 0x1020 - Watchdog Timer (WDT) Exception +/* 0x1020 - Watchdog Timer (WDT) Exception +*/ CRIT_EXCEPTION(0x1020, WDTException, UnknownException) #endif -### 0x1100 - Data TLB Miss Exception +/* 0x1100 - Data TLB Miss Exception + * As the name implies, translation is not in the MMU, so search the + * page tables and fix it. The only purpose of this function is to + * load TLB entries from the page table if they exist. + */ + START_EXCEPTION(0x1100, DTLBMiss) + mtspr SPRG0, r20 /* Save some working registers */ + mtspr SPRG1, r21 +#ifdef CONFIG_403GCX + stw r22, 0(r0) + stw r23, 4(r0) + mfcr r21 + mfspr r22, SPRN_PID + stw r21, 8(r0) + stw r22, 12(r0) +#else + mtspr SPRG4, r22 + mtspr SPRG5, r23 + mfcr r21 + mfspr r22, SPRN_PID + mtspr SPRG7, r21 + mtspr SPRG6, r22 +#endif + mfspr r20, SPRN_DEAR /* Get faulting address */ - STND_EXCEPTION(0x1100, DTLBMiss, PPC4xx_dtlb_miss) + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r21, r20, 0x8000 + beq 3f + lis r21, swapper_pg_dir@h + ori r21, r21, swapper_pg_dir@l + li r23, 0 + mtspr SPRN_PID, r23 /* TLB will have 0 TID */ + b 4f -### 0x1200 - Instruction TLB Miss Exception + /* Get the PGD for the current thread. + */ +3: + mfspr r21,SPRG3 + lwz r21,PGDIR(r21) +4: + tophys(r21, r21) + rlwimi r21, r20, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r21, 0(r21) /* Get L1 entry */ + rlwinm. r22, r21, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + tophys(r22, r22) + rlwimi r22, r20, 22, 20, 29 /* Compute PTE address */ + lwz r21, 0(r22) /* Get Linux PTE */ + andi. r23, r21, _PAGE_PRESENT + beq 2f - STND_EXCEPTION(0x1200, ITLBMiss, PPC4xx_itlb_miss) + ori r21, r21, _PAGE_ACCESSED + stw r21, 0(r22) + + /* Most of the Linux PTE is ready to load into the TLB LO. + * We set ZSEL, where only the LS-bit determines user access. + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + li r22, 0x0ce2 + andc r21, r21, r22 /* Make sure 20, 21 are zero */ + + b finish_tlb_load + + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + b DataAccess + +/* 0x1200 - Instruction TLB Miss Exception + * Nearly the same as above, except we get our information from different + * registers and bailout to a different point. + */ + START_EXCEPTION(0x1200, ITLBMiss) + mtspr SPRG0, r20 /* Save some working registers */ + mtspr SPRG1, r21 +#ifdef CONFIG_403GCX + stw r22, 0(r0) + stw r23, 4(r0) + mfcr r21 + mfspr r22, SPRN_PID + stw r21, 8(r0) + stw r22, 12(r0) +#else + mtspr SPRG4, r22 + mtspr SPRG5, r23 + mfcr r21 + mfspr r22, SPRN_PID + mtspr SPRG7, r21 + mtspr SPRG6, r22 +#endif + mfspr r20, SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r21, r20, 0x8000 + beq 3f + lis r21, swapper_pg_dir@h + ori r21, r21, swapper_pg_dir@l + li r23, 0 + mtspr SPRN_PID, r23 /* TLB will have 0 TID */ + b 4f + + /* Get the PGD for the current thread. + */ +3: + mfspr r21,SPRG3 + lwz r21,PGDIR(r21) +4: + tophys(r21, r21) + rlwimi r21, r20, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r21, 0(r21) /* Get L1 entry */ + rlwinm. r22, r21, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + tophys(r22, r22) + rlwimi r22, r20, 22, 20, 29 /* Compute PTE address */ + lwz r21, 0(r22) /* Get Linux PTE */ + andi. r23, r21, _PAGE_PRESENT + beq 2f + + ori r21, r21, _PAGE_ACCESSED + stw r21, 0(r22) + + /* Most of the Linux PTE is ready to load into the TLB LO. + * We set ZSEL, where only the LS-bit determines user access. + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + li r22, 0x0ce2 + andc r21, r21, r22 /* Make sure 20, 21 are zero */ + + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + b InstructionAccess STND_EXCEPTION(0x1300, Trap_13, UnknownException) STND_EXCEPTION(0x1400, Trap_14, UnknownException) STND_EXCEPTION(0x1500, Trap_15, UnknownException) STND_EXCEPTION(0x1600, Trap_16, UnknownException) +#ifdef CONFIG_IBM405_ERR51 + /* 405GP errata 51 */ + START_EXCEPTION(0x1700, Trap_17) + b DTLBMiss +#else STND_EXCEPTION(0x1700, Trap_17, UnknownException) +#endif STND_EXCEPTION(0x1800, Trap_18, UnknownException) STND_EXCEPTION(0x1900, Trap_19, UnknownException) STND_EXCEPTION(0x1A00, Trap_1A, UnknownException) @@ -362,73 +678,214 @@ STND_EXCEPTION(0x1D00, Trap_1D, UnknownException) STND_EXCEPTION(0x1E00, Trap_1E, UnknownException) STND_EXCEPTION(0x1F00, Trap_1F, UnknownException) - -### 0x2000 - Debug Exception - CRIT_EXCEPTION(0x2000, DebugTrap, UnknownException) +/* 0x2000 - Debug Exception +*/ + START_EXCEPTION(0x2000, DebugTrap) + b check_single_step_in_exception +ret_to_debug_exception: + CRIT_EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + li r7,CRIT_EXC; + li r20,MSR_KERNEL + FINISH_EXCEPTION(DebugException) + +/* Make sure the final interrupt handler has not spilled past the + * end of its allotted space. + */ + .=0x2100 -### -### Other PowerPC processors, namely those derived from the 6xx-series -### have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. -### However, for the 4xx-series processors these are neither defined nor -### reserved. -### - -### -### This code finishes saving the registers to the exception frame -### and jumps to the appropriate handler for the exception, turning -### on address translation. -### +/* Check for a single step debug exception while in an exception + * handler before state has been saved. This is to catch the case + * where an instruction that we are trying to single step causes + * an exception (eg ITLB miss) and thus the first instruction of + * the exception handler generates a single step debug exception. + * + * If we get a debug trap on the first instruction of an exception handler, + * we reset the MSR_DE in the _exception handlers_ MSR (the debug trap is + * a critical exception, so we are using SPRN_SRR3 to manipulate the MSR). + * The exception handler was handling a non-critical interrupt, so it will + * save (and later restore) the MSR via SPRN_SRR1, which will still have + * the MSR_DE bit set. + */ +check_single_step_in_exception: + /* This first instruction was already executed by the exception + * handler and must be the first instruction of every exception + * handler. + */ + mtspr SPRN_SPRG0,r20 /* Save some working registers... */ + mtspr SPRN_SPRG1,r21 + mfcr r20 /* ..and the cr because we change it */ + + mfspr r21,SPRN_SRR3 /* MSR at the time of fault */ + andi. r21,r21,MSR_PR + bne+ 2f /* trapped from problem state */ + + mfspr r21,SPRN_SRR2 /* Faulting instruction address */ + cmplwi r21,0x2100 + bgt+ 2f /* address above exception vectors */ + + lis r21,DBSR_IC@h /* Remove the trap status */ + mtspr SPRN_DBSR,r21 + + mfspr r21,SPRN_SRR3 + rlwinm r21,r21,0,23,21 /* clear MSR_DE */ + mtspr SPRN_SRR3, r21 /* restore MSR at rcfi without DE */ + + mtcrf 0xff,r20 /* restore registers */ + mfspr r21,SPRN_SPRG1 + mfspr r20,SPRN_SPRG0 + + sync + rfci /* return to the exception handler */ + b . /* prevent prefetch past rfci */ + +2: + mtcrf 0xff,r20 /* restore registers */ + mfspr r21,SPRN_SPRG1 + mfspr r20,SPRN_SPRG0 + b ret_to_debug_exception + +/* Other PowerPC processors, namely those derived from the 6xx-series + * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. + * However, for the 4xx-series processors these are neither defined nor + * reserved. + */ + + /* Damn, I came up one instruction too many to fit into the + * exception space :-). Both the instruction and data TLB + * miss get to this point to load the TLB. + * r20 - EA of fault + * r21 - TLB LO (info from Linux PTE) + * r22, r23 - avilable to use + * PID - loaded with proper value when we get here + * Upon exit, we reload everything and RFI. + * Actually, it will fit now, but oh well.....a common place + * to load the TLB. + */ +tlb_4xx_index: + .long 0 +finish_tlb_load: + /* load the next available TLB index. + */ + lwz r23, tlb_4xx_index@l(0) + addi r23, r23, 1 +#ifdef CONFIG_PIN_TLB + cmpwi 0, r23, 61 /* reserve entries 62, 63 for kernel */ + ble 7f + li r23, 0 +7: +#else + andi. r23, r23, (PPC4XX_TLB_SIZE-1) +#endif + stw r23, tlb_4xx_index@l(0) + +6: + tlbwe r21, r23, TLB_DATA /* Load TLB LO */ + + /* Create EPN. This is the faulting address plus a static + * set of bits. These are size, valid, E, U0, and ensure + * bits 20 and 21 are zero. + */ + li r22, 0x00c0 + rlwimi r20, r22, 0, 20, 31 + tlbwe r20, r23, TLB_TAG /* Load TLB HI */ + + /* Done...restore registers and get out of here. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + PPC405_ERR77_SYNC + rfi /* Should sync shadow TLBs */ + b . /* prevent prefetch past rfi */ + +/* This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception, turning + * on address translation. + */ _GLOBAL(transfer_to_handler) - stw r22,_NIP(r21) # Save the faulting IP on the stack - stw r23,_MSR(r21) # Save the exception MSR on the stack - SAVE_4GPRS(8, r21) # Save r8 through r11 on the stack - SAVE_8GPRS(12, r21) # Save r12 through r19 on the stack - SAVE_8GPRS(24, r21) # Save r24 through r31 on the stack - andi. r23,r23,MSR_PR # Is this from user space? - mfspr r23,SPRN_SPRG3 # If from user, fix up THREAD.regs - beq 2f # No, it is from the kernel; branch. + stw r22,_NIP(r21) /* Save the faulting IP on the stack */ + stw r23,_MSR(r21) /* Save the exception MSR on stack */ + SAVE_4GPRS(8, r21) /* Save r8 through r11 on the stack */ + SAVE_8GPRS(12, r21) /* Save r12 through r19 on the stack */ + SAVE_8GPRS(24, r21) /* Save r24 through r31 on the stack */ + andi. r23,r23,MSR_PR /* Is this from user space? */ + mfspr r23,SPRN_SPRG3 /* If from user, fix up THREAD.regs */ + beq 2f /* No, it is from the kernel; branch. */ + mfspr r24,SPRN_DBCR0 + stw r24,THREAD_DBCR0(r23) /* Save Debug Control in thread_struct */ addi r24,r1,STACK_FRAME_OVERHEAD - stw r24,PT_REGS(r23) # -2: addi r2,r23,-THREAD # Set r2 to current thread + stw r24,PT_REGS(r23) +2: addi r2,r23,-THREAD /* Set r2 to current thread */ tovirt(r2,r2) mflr r23 - andi. r24,r23,0x3f00 # Get vector offset + andi. r24,r23,0x3f00 /* Get vector offset */ stw r24,TRAP(r21) + li r22,RESULT + /* No need to put an erratum #77 workaround here + because interrupts are currently disabled */ + stwcx. r22,r22,r21 /* Clear the reservation */ li r22,0 stw r22,RESULT(r21) - mtspr SPRN_SPRG2,r22 # r1 is now the kernel stack pointer - addi r24,r2,TASK_STRUCT_SIZE # Check for kernel stack overflow + mtspr SPRN_SPRG2,r22 /* r1 is now the kernel stack pointer */ + addi r24,r2,TASK_STRUCT_SIZE /* Check for kernel stack overflow */ cmplw cr0,r1,r2 cmplw cr1,r1,r24 crand cr1,cr1,cr4 - bgt- stack_ovf # If r2 < r1 < r2 + TASK_STRUCT_SIZE - lwz r24,0(r23) # Virtual address of the handler - lwz r23,4(r23) # Handler return pointer - cmpwi cr0,r7,STND_EXC # What type of exception is this? - bne 3f # It is a critical exception... - - ## Standard exception jump path - - mtspr SPRN_SRR0,r24 # Set up the instruction pointer - mtspr SPRN_SRR1,r20 # Set up the machine state register - mtlr r23 # Set up the return pointer + bgt- stack_ovf /* If r2 < r1 < r2 + TASK_STRUCT_SIZE */ + lwz r24,0(r23) /* Virtual address of the handler */ + lwz r23,4(r23) /* Handler return pointer */ + cmpwi cr0,r7,STND_EXC /* What type of exception is this? */ + bne 3f /* It is a critical exception... */ + + /* Standard exception jump path + */ + + /* We have to recover r7 from the register save stack. + * It was used to indicate standard/critical exception. In + * the case of a standard exception that is the system call + * trap, it may have originally contained one of the syscall + * parameters and we have to get it back now. + */ + lwz r7,GPR7(r21) + mtspr SPRN_SRR0,r24 /* Set up the instruction pointer */ + mtspr SPRN_SRR1,r20 /* Set up the machine state register */ + mtlr r23 /* Set up the return pointer */ SYNC - rfi # Enable the MMU, jump to the handler + /* We shouldn't need a 405 erratum #77 workaround here, because we're not + * actually returning to the interrupted instruction yet. */ + rfi + b . /* prevent prefetch past rfi */ - ## Critical exception jump path + /* Critical exception jump path + */ -3: mtspr SPRN_SRR2,r24 # Set up the instruction pointer - mtspr SPRN_SRR3,r20 # Set up the machine state register - mtlr r23 # Set up the return pointer +3: mtspr SPRN_SRR2,r24 /* Set up the instruction pointer */ + mtspr SPRN_SRR3,r20 /* Set up the machine state register */ + mtlr r23 /* Set up the return pointer */ SYNC - rfci # Enable the MMU, jump to the handler + rfci + b . /* prevent prefetch past rfci */ -### -### On kernel stack overlow, load up an initial stack pointer and call -### StackOverflow(regs), which should NOT return. -### +/* On kernel stack overlow, load up an initial stack pointer and call + * StackOverflow(regs), which should NOT return. + */ stack_ovf: addi r3,r1,STACK_FRAME_OVERHEAD @@ -438,143 +895,226 @@ lis r24,StackOverflow@ha addi r24,r24,StackOverflow@l li r20,MSR_KERNEL - mtspr SPRN_SRR0,r24 # Set up the instruction pointer - mtspr SPRN_SRR1,r20 # Set up the machine state register + mtspr SPRN_SRR0,r24 + mtspr SPRN_SRR1,r20 SYNC - rfi # Enable the MMU, jump to StackOverflow - -### -### extern void giveup_altivec(struct task_struct *prev) -### -### The PowerPC 4xx family of processors do not have AltiVec capabilities, so -### this just returns. -### + rfi + b . /* prevent prefetch past rfi */ +/* extern void giveup_altivec(struct task_struct *prev) + * + * The PowerPC 4xx family of processors do not have AltiVec capabilities, so + * this just returns. + */ _GLOBAL(giveup_altivec) blr - -### -### extern void giveup_fpu(struct task_struct *prev) -### -### The PowerPC 4xx family of processors do not have an FPU, so this just -### returns. -### +/* extern void giveup_fpu(struct task_struct *prev) + * + * The PowerPC 4xx family of processors do not have an FPU, so this just + * returns. + */ _GLOBAL(giveup_fpu) blr -### -### extern void abort(void) -### -### At present, this routine just applies a system reset. -### - +/* extern void abort(void) + * + * At present, this routine just applies a system reset. + */ _GLOBAL(abort) - mfspr r13,SPRN_DBCR - oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h - mtspr SPRN_DBCR,r13 + mfspr r13,SPRN_DBCR0 + oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h + mtspr SPRN_DBCR0,r13 -### -### This is where the main kernel code starts. -### - +/* This is where the main kernel code starts. + */ start_here: - ## Establish a pointer to the current task - + + /* ptr to current */ lis r2,init_task_union@h ori r2,r2,init_task_union@l - - ## Clear out the BSS as per ANSI C requirements - lis r7,_end@ha - addi r7,r7,_end@l - lis r8,__bss_start@ha - addi r8,r8,__bss_start@l - subf r7,r8,r7 - addi r7,r7,3 - srwi. r7,r7,2 - beq 2f - addi r8,r8,-4 - mtctr r7 - li r0,0 -3: stwu r0,4(r8) - bdnz 3b + /* ptr to phys current thread */ + tophys(r4,r2) + addi r4,r4,THREAD /* init task's THREAD */ + mtspr SPRG3,r4 + li r3,0 + mtspr SPRG2,r3 /* 0 => r1 has kernel sp */ - ## Stack - -2: addi r1,r2,TASK_UNION_SIZE + /* stack */ + addi r1,r2,TASK_UNION_SIZE li r0,0 stwu r0,-STACK_FRAME_OVERHEAD(r1) - ## Determine what type of platform this is. + bl early_init /* We have to do this with MMU on */ +/* + * Decide what sort of machine this is and initialize the MMU. + */ mr r3,r31 mr r4,r30 mr r5,r29 mr r6,r28 mr r7,r27 - bl identify_machine - - ## Initialize the memory management unit. - + bl machine_init bl MMU_init - ## Go back to running unmapped so that we can change to our - ## exception vectors. - +/* Go back to running unmapped so we can load up new values + * and change to using our exception vectors. + * On the 4xx, all we have to do is invalidate the TLB to clear + * the old 16M byte TLB mappings. + */ lis r4,2f@h ori r4,r4,2f@l tophys(r4,r4) li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR) - mtspr SPRN_SRR0,r4 # Set up the instruction pointer - mtspr SPRN_SRR1,r3 # Set up the machine state register + mtspr SRR0,r4 + mtspr SRR1,r3 rfi + b . /* prevent prefetch past rfi */ + +/* Load up the kernel context */ +2: + SYNC /* Force all PTE updates to finish */ +#ifndef CONFIG_PIN_TLB + tlbia /* Clear all TLB entries */ + sync /* wait for tlbia/tlbie to finish */ +#endif + + /* set up the PTE pointers for the Abatron bdiGDB. + */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r5, 0xf0(r0) /* Must match your Abatron config file */ + tophys(r5,r5) + stw r6, 0(r5) + +/* Now turn on the MMU for real! */ + li r4,MSR_KERNEL + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SRR0,r3 + mtspr SRR1,r4 + rfi /* enable MMU and jump to start_kernel */ + b . /* prevent prefetch past rfi */ + +/* Set up the initial MMU state so we can do the first level of + * kernel initialization. This maps the first 16 MBytes of memory 1:1 + * virtual to physical and more importantly sets the cache mode. + */ +initial_mmu: + tlbia /* Invalidate all TLB entries */ + sync + + /* We should still be executing code at physical address 0x0000xxxx + * at this point. However, start_here is at virtual address + * 0xC000xxxx. So, set up a TLB mapping to cover this once + * translation is enabled. + */ + + lis r3,KERNELBASE@h /* Load the kernel virtual address */ + ori r3,r3,KERNELBASE@l + tophys(r4,r3) /* Load the kernel physical address */ + + iccci r0,r3 /* Invalidate the i-cache before use */ + + /* Load the kernel PID. + */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Configure and load two entries into TLB slots 62 and 63. + * In case we are pinning TLBs, these are reserved in by the + * other TLB functions. If not reserving, then it doesn't + * matter where they are loaded. + */ + clrrwi r4,r4,10 /* Mask off the real page number */ + ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */ + + clrrwi r3,r3,10 /* Mask off the effective page number */ + ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M)) + + li r0,62 /* TLB slot 62 */ + + tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ + tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ + + addis r4, r4, 0x0100 /* Map next 16 M entries */ + addis r3, r3, 0x0100 + + li r0,63 /* TLB slot 63 */ - ## Load up the kernel context + tlbwe r4,r0,TLB_DATA + tlbwe r3,r0,TLB_TAG + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE) + + /* Load a TLB entry for the UART, so that ppc4xx_progress() can use + * the UARTs nice and early. We use a 4k real==virtual mapping. */ + + lis r3,SERIAL_DEBUG_IO_BASE@h + ori r3,r3,SERIAL_DEBUG_IO_BASE@l + mr r4,r3 + clrrwi r4,r4,12 + ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G) + + clrrwi r3,r3,12 + ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K)) + + li r0,0 /* TLB slot 0 */ + tlbwe r4,r0,TLB_DATA + tlbwe r3,r0,TLB_TAG +#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */ + + isync + + /* Establish the exception vector base + */ + lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */ + tophys(r0,r4) /* Use the physical address */ + mtspr SPRN_EVPR,r0 + + blr -2: SYNC # Force all PTE updates to finish -# tlbia # Clear all TLB entries -# sync # Wait for tlbia to finish... - - ## Set up for using our exception vectors - - tophys(r4,r2) # Pointer to physical current thread - addi r4,r4,THREAD # The init task thread - mtspr SPRN_SPRG3,r4 # Save it for exceptions later - li r3,0 # - mtspr SPRN_SPRG2,r3 # 0 implies r1 has kernel stack pointer - - ## Really turn on the MMU and jump into the kernel - - lis r4,MSR_KERNEL@h - ori r4,r4,MSR_KERNEL@l - lis r3,start_kernel@h - ori r3,r3,start_kernel@l - mtspr SPRN_SRR0,r3 # Set up the instruction pointer - mtspr SPRN_SRR1,r4 # Set up the machine state register - rfi # Enable the MMU, jump to the kernel _GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, KERNELBASE@h + lwz r5, 0xf0(r5) + stw r4, 0x4(r5) +#endif + sync mtspr SPRN_PID,r3 + isync /* Need an isync to flush shadow */ + /* TLBs after changing PID */ blr -### -### We put a few things here that have to be page-aligned. This stuff -### goes at the beginning of the data segment, which is page-aligned. -### - +/* We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ .data _GLOBAL(sdata) _GLOBAL(empty_zero_page) .space 4096 _GLOBAL(swapper_pg_dir) - .space 4096 - -### -### This space gets a copy of optional info passed to us by the bootstrap -### which is used to pass parameters into the kernel like root=/dev/sda1, etc. -### + .space 4096 +/* This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ _GLOBAL(cmd_line) .space 512 + +/* Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 diff -urN linux-2.4.21/arch/ppc/kernel/head_8xx.S linux-2.4.22/arch/ppc/kernel/head_8xx.S --- linux-2.4.21/arch/ppc/kernel/head_8xx.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/head_8xx.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * arch/ppc/kernel/except_8xx.S * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP * Copyright (C) 1996 Cort Dougan @@ -74,6 +74,20 @@ * I used to use SPRG2 for a temporary register in the TLB handler, but it * has since been put to other uses. I now use a hack to save a register * and the CCR at memory location 0.....Someday I'll fix this..... + * + * With regard to resetting the CPM. The UART console has a number of subtle + * assumptions built around the initialization to support kgdb/xmon debugging. + * The quick answer is we don't want to reset the CPM so we can proper support + * this debugging. + * + * When the kernel is first booted, kgdb/xmon use the CPM as it was set up by + * the boot rom. There is a second initialization of the UART driver, but + * before the console is initialized. This changes the BDs, but the UART + * still operates for kgdb/xmon. The final stage initialization occurs when + * the console is initialized, and all of the "normal path" debugging and + * messages can occur after this point. So the only time we want to do a CPM + * is in the case of a microcode patch. + * * -- Dan */ @@ -470,7 +484,16 @@ #endif rfi -2: mfspr r20, M_TW /* Restore registers */ +2: + /* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fail + * to update DAR when they cause a DTLB miss. + */ + mfspr r21, MD_EPN + mfspr r20, DAR + rlwimi r20, r21, 0, 0, 19 + mtspr DAR, r20 + + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 lwz r21, 4(r0) @@ -514,20 +537,20 @@ andis. r21, r20, 0x0200 /* If set, indicates store op */ beq 2f - /* The EA of a data TLB miss is automatically stored in the MD_EPN - * register. The EA of a data TLB error is automatically stored in - * the DAR, but not the MD_EPN register. We must copy the 20 most - * significant bits of the EA from the DAR to MD_EPN before we - * start walking the page tables. We also need to copy the CASID + /* The EA of a data TLB miss is automatically stored in the MD_EPN + * register. The EA of a data TLB error is automatically stored in + * the DAR, but not the MD_EPN register. We must copy the 20 most + * significant bits of the EA from the DAR to MD_EPN before we + * start walking the page tables. We also need to copy the CASID * value from the M_CASID register. - * Addendum: The EA of a data TLB error is _supposed_ to be stored - * in DAR, but it seems that this doesn't happen in some cases, such - * as when the error is due to a dcbi instruction to a page with a - * TLB that doesn't have the changed bit set. In such cases, there - * does not appear to be any way to recover the EA of the error - * since it is neither in DAR nor MD_EPN. As a workaround, the - * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs - * are initialized in mapin_ram(). This will avoid the problem, + * Addendum: The EA of a data TLB error is _supposed_ to be stored + * in DAR, but it seems that this doesn't happen in some cases, such + * as when the error is due to a dcbi instruction to a page with a + * TLB that doesn't have the changed bit set. In such cases, there + * does not appear to be any way to recover the EA of the error + * since it is neither in DAR nor MD_EPN. As a workaround, the + * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs + * are initialized in mapin_ram(). This will avoid the problem, * assuming we only use the dcbi instruction on kernel addresses. */ mfspr r20, DAR diff -urN linux-2.4.21/arch/ppc/kernel/i8259.c linux-2.4.22/arch/ppc/kernel/i8259.c --- linux-2.4.21/arch/ppc/kernel/i8259.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/i8259.c 2003-08-25 04:44:40.000000000 -0700 @@ -93,7 +93,7 @@ outb(cached_A1,0xA1); outb(cached_21,0x21); } - + static void i8259_mask_irq(unsigned int irq_nr) { unsigned long flags; diff -urN linux-2.4.21/arch/ppc/kernel/idle.c linux-2.4.22/arch/ppc/kernel/idle.c --- linux-2.4.21/arch/ppc/kernel/idle.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/idle.c 2003-08-25 04:44:40.000000000 -0700 @@ -34,9 +34,7 @@ unsigned long powersave_nap; unsigned long powersave_lowspeed; -#ifdef CONFIG_6xx -extern void power_save_6xx(void); -#endif +extern void power_save(void); int idled(void) { @@ -66,10 +64,8 @@ } } #endif -#ifdef CONFIG_6xx if (do_power_save && !current->need_resched) - power_save_6xx(); -#endif /* CONFIG_6xx */ + power_save(); if (current->need_resched) { schedule(); @@ -86,5 +82,5 @@ int cpu_idle(void) { idled(); - return 0; + return 0; } diff -urN linux-2.4.21/arch/ppc/kernel/idle_6xx.S linux-2.4.22/arch/ppc/kernel/idle_6xx.S --- linux-2.4.21/arch/ppc/kernel/idle_6xx.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/idle_6xx.S 2003-08-25 04:44:40.000000000 -0700 @@ -56,12 +56,12 @@ blr /* - * Here is the power_save_6xx function. This could eventually be + * Here is the power_save function. This could eventually be * split into several functions & changing the function pointer * depending on the various features. */ - .globl power_save_6xx -power_save_6xx: + .globl power_save +power_save: /* Check if we can nap or doze, put HID0 mask in r3 */ lis r3, 0 @@ -83,7 +83,7 @@ cmpi 0,r4,0 beq 1f lis r3,HID0_NAP@h -1: +1: END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) cmpi 0,r3,0 beqlr @@ -99,7 +99,7 @@ beq+ 1f mtmsr r7 /* out of line this ? */ blr -1: +1: /* Some pre-nap cleanups needed on some CPUs */ andis. r0,r3,HID0_NAP@h beq 2f @@ -127,7 +127,7 @@ lwz r4,nap_enter_count@l(r6) addi r4,r4,1 stw r4,nap_enter_count@l(r6) -#endif +#endif 2: BEGIN_FTR_SECTION /* Go to low speed mode on some 750FX */ @@ -138,10 +138,10 @@ mfspr r4,SPRN_HID1 oris r4,r4,0x0001 mtspr SPRN_HID1,r4 -1: +1: END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) - /* Go to NAP or DOZE now */ + /* Go to NAP or DOZE now */ mfspr r4,SPRN_HID0 lis r5,(HID0_NAP|HID0_SLEEP)@h BEGIN_FTR_SECTION @@ -167,7 +167,7 @@ isync sync blr - + /* * Return from NAP/DOZE mode, restore some CPU specific registers, * we are called with DR/IR still off and r2 containing physical @@ -191,7 +191,7 @@ stw r24,nap_return_count@l(r22) 1: #endif - + lwz r24,PROCESSOR(r2) slwi r24,r24,2 /* Todo make sure all these are in the same page diff -urN linux-2.4.21/arch/ppc/kernel/idle_gen.c linux-2.4.22/arch/ppc/kernel/idle_gen.c --- linux-2.4.21/arch/ppc/kernel/idle_gen.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/kernel/idle_gen.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,41 @@ +/* + * This is the old power_save() function from idle.c: + * + * Written by Cort Dougan (cort@cs.nmt.edu) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ +#include +#include +#include + +void power_save(void) +{ + /* Make sure the CPU has the DOZE feature set. */ + if (!(cur_cpu_spec[smp_processor_id()]->cpu_features + & CPU_FTR_CAN_DOZE)) + return; + /* + * Disable interrupts to prevent a lost wakeup + * when going to sleep. This is necessary even with + * RTLinux since we are not guaranteed an interrupt + * didn't come in and is waiting for a __sti() before + * emulating one. This way, we really do hard disable. + * + * We assume that we're sti-ed when we come in here. We + * are in the idle loop so if we're cli-ed then it's a bug + * anyway. + * -- Cort + */ + _nmask_and_or_msr(MSR_EE, 0); + if (!current->need_resched) { + /* set the POW bit in the MSR, and enable interrupts + * so we wake up sometime! */ + _nmask_and_or_msr(0, MSR_POW | MSR_EE); + } + _nmask_and_or_msr(0, MSR_EE); +} diff -urN linux-2.4.21/arch/ppc/kernel/indirect_pci.c linux-2.4.22/arch/ppc/kernel/indirect_pci.c --- linux-2.4.21/arch/ppc/kernel/indirect_pci.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/indirect_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -29,10 +29,19 @@ indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ { \ struct pci_controller *hose = dev->sysdata; \ + u8 cfg_type = 0; \ + \ + if (ppc_md.pci_exclude_device) \ + if (ppc_md.pci_exclude_device(dev->bus->number, dev->devfn)) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + \ + if (hose->set_cfg_type) \ + if (dev->bus->number != hose->first_busno) \ + cfg_type = 1; \ \ out_be32(hose->cfg_addr, \ - ((offset & 0xfc) << 24) | (dev->devfn << 16) \ - | (dev->bus->number << 8) | 0x80); \ + (((offset & 0xfc) | cfg_type) << 24) | (dev->devfn << 16) \ + | ((dev->bus->number - hose->bus_offset) << 8) | 0x80); \ cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ return PCIBIOS_SUCCESSFUL; \ } diff -urN linux-2.4.21/arch/ppc/kernel/irq.c linux-2.4.22/arch/ppc/kernel/irq.c --- linux-2.4.21/arch/ppc/kernel/irq.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -10,7 +10,7 @@ * Adapted for Power Macintosh by Paul Mackerras * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). - * + * * This file contains the code used by various IRQ handling routines: * asking for different IRQ's should be done through these routines * instead of just grabbing them. Thus setups with different IRQ numbers @@ -68,7 +68,7 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}}; - + int ppc_spurious_interrupts = 0; struct irqaction *ppc_irq_action[NR_IRQS]; unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; @@ -234,28 +234,28 @@ free_irq(irq, dev_id); return 0; } - + action = (struct irqaction *) irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL); if (!action) { printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq); return -ENOMEM; } - + action->handler = handler; - action->flags = irqflags; + action->flags = irqflags; action->mask = 0; action->name = devname; action->dev_id = dev_id; action->next = NULL; - + retval = setup_irq(irq, action); if (retval) { kfree(action); return retval; } - + return 0; } @@ -263,9 +263,9 @@ * Generic enable/disable code: this just calls * down into the PIC-specific version for the actual * hardware disable after having gotten the irq - * controller lock. + * controller lock. */ - + /** * disable_irq_nosync - disable an irq without waiting * @irq: Interrupt to disable @@ -276,7 +276,7 @@ * * This function may be called from IRQ context. */ - + void disable_irq_nosync(unsigned int irq) { irq_desc_t *desc = irq_desc + irq; @@ -303,7 +303,7 @@ * * This function may be called - with care - from IRQ context. */ - + void disable_irq(unsigned int irq) { disable_irq_nosync(irq); @@ -324,7 +324,7 @@ * * This function may be called from IRQ context. */ - + void enable_irq(unsigned int irq) { irq_desc_t *desc = irq_desc + irq; @@ -365,15 +365,15 @@ action = irq_desc[i].action; if ( !action || !action->handler ) continue; - len += sprintf(buf+len, "%3d: ", i); + len += sprintf(buf+len, "%3d: ", i); #ifdef CONFIG_SMP for (j = 0; j < smp_num_cpus; j++) len += sprintf(buf+len, "%10u ", kstat.irqs[cpu_logical_map(j)][i]); -#else +#else len += sprintf(buf+len, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ - if ( irq_desc[i].handler ) + if ( irq_desc[i].handler ) len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename ); else len += sprintf(buf+len, " None "); @@ -397,7 +397,7 @@ /* should this be per processor send/receive? */ len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n", atomic_read(&ipi_recv), atomic_read(&ipi_sent)); -#endif +#endif len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); return len; } @@ -433,7 +433,7 @@ kstat.irqs[cpu][irq]++; spin_lock(&desc->lock); - ack_irq(irq); + ack_irq(irq); /* REPLAY is when Linux resends an IRQ that was dropped earlier WAITING is used by probe to mark irqs that are being tested @@ -490,7 +490,7 @@ spin_unlock(&desc->lock); handle_irq_event(irq, regs, action); spin_lock(&desc->lock); - + if (!(desc->status & IRQ_PENDING)) break; desc->status &= ~IRQ_PENDING; @@ -561,7 +561,7 @@ return; else once++; - + ppc_md.init_IRQ(); } @@ -700,11 +700,11 @@ #endif } } while (test_bit(0,&global_irq_lock)); - } while (test_and_set_bit(0,&global_irq_lock)); + } while (test_and_set_bit(0,&global_irq_lock)); } - /* + /* * We also need to make sure that nobody else is running - * in an interrupt context. + * in an interrupt context. */ wait_on_irq(cpu); @@ -729,7 +729,7 @@ void __global_cli(void) { unsigned long flags; - + __save_flags(flags); if (flags & (1 << 15)) { int cpu = smp_processor_id(); diff -urN linux-2.4.21/arch/ppc/kernel/l2cr.S linux-2.4.22/arch/ppc/kernel/l2cr.S --- linux-2.4.21/arch/ppc/kernel/l2cr.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/l2cr.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,17 +1,17 @@ /* L2CR functions Copyright © 1997-1998 by PowerLogix R & D, Inc. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You 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. @@ -36,7 +36,7 @@ several months. The L2CR is similar, but I'm going to assume the user of this functions knows what they are doing. - + Author: Terry Greeniaus (tgree@phys.ualberta.ca) Please e-mail updates to this file to me, thanks! */ @@ -47,7 +47,7 @@ #include /* Usage: - + When setting the L2CR register, you must do a few special things. If you are enabling the cache, you must perform a global invalidate. If you are disabling the cache, you must @@ -104,7 +104,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L2CR) mflr r9 - + /* Stop DST streams */ BEGIN_FTR_SECTION DSSALL @@ -134,10 +134,10 @@ mr r5,r3 bl __flush_disable_L1 mr r3,r5 - + /* Get the current enable bit of the L2CR into r4 */ mfspr r4,L2CR - + /* Tweak some bits */ rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */ rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ @@ -152,7 +152,7 @@ * the size of the L2 cache plus the size of the L1 cache, but 4MB will * cover everything just to be safe). */ - + /**** Might be a good idea to set L2DO here - to prevent instructions from getting into the cache. But since we invalidate the next time we enable the cache it doesn't really matter. @@ -170,7 +170,7 @@ addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b isync - + /* Now, flush the first 4MB of memory */ lis r4,0x0002 mtctr r4 @@ -198,7 +198,7 @@ 21: sync isync b 22b - + 23: /* Perform a global invalidation */ oris r3,r3,0x0020 @@ -220,12 +220,12 @@ 3: mfspr r3,L2CR rlwinm. r4,r3,0,31,31 bne 3b - + 11: rlwinm r3,r3,0,11,9 /* Turn off the L2I bit */ sync mtspr L2CR,r3 sync - + /* See if we need to enable the cache */ cmplwi r5,0 beq 4f @@ -264,7 +264,7 @@ * Here is a similar routine for dealing with the L3 cache * on the 745x family of chips */ - + _GLOBAL(_set_L3CR) /* Make sure this is a 745x chip */ BEGIN_FTR_SECTION @@ -275,7 +275,7 @@ /* Stop DST streams */ DSSALL sync - + /* Turn off interrupts and data relocation. */ mfmsr r7 /* Save MSR in r7 */ rlwinm r4,r7,0,17,15 @@ -286,7 +286,7 @@ /* Get the current enable bit of the L3CR into r4 */ mfspr r4,SPRN_L3CR - + /* Tweak some bits */ rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */ rlwinm r3,r3,0,22,20 /* Turn off the invalidate bit */ @@ -298,7 +298,7 @@ /* Flush the cache. */ - + /* TODO: use HW flush assist */ lis r4,0x0008 @@ -309,7 +309,7 @@ dcbf 0,r4 addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b - + 2: /* Set up the L3CR configuration bits (and switch L3 off) */ sync @@ -327,7 +327,7 @@ li r0,256 mtctr r0 1: bdnz 1b - + /* Perform a global invalidation */ ori r3,r3,0x0400 sync @@ -349,7 +349,7 @@ li r0,256 mtctr r0 1: bdnz 1b - + /* See if we need to enable the cache */ cmplwi r5,0 beq 4f @@ -389,13 +389,13 @@ */ .globl __flush_disable_L1 __flush_disable_L1: - + /* Stop pending alitvec streams and memory accesses */ BEGIN_FTR_SECTION DSSALL END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) sync - + /* Load counter to 0x1000 cache lines (128k) and * load cache with datas */ @@ -426,7 +426,7 @@ rlwinm r3,r3,0,18,15 mtspr SPRN_HID0,r3 sync - isync + isync blr /* inval_enable_L1 - Invalidate and enable L1 cache @@ -449,4 +449,4 @@ blr - + diff -urN linux-2.4.21/arch/ppc/kernel/m8260_setup.c linux-2.4.22/arch/ppc/kernel/m8260_setup.c --- linux-2.4.21/arch/ppc/kernel/m8260_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/m8260_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -148,7 +148,7 @@ bd_t *bp; bp = (bd_t *)__res; - + seq_printf(m, "core clock\t: %d MHz\n" "CPM clock\t: %d MHz\n" "bus clock\t: %d MHz\n", @@ -176,7 +176,7 @@ #endif for ( i = 0 ; i < NR_SIU_INTS ; i++ ) irq_desc[i].handler = &ppc8260_pic; - + /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. */ @@ -195,7 +195,7 @@ { bd_t *binfo; extern unsigned char __res[]; - + binfo = (bd_t *)__res; return binfo->bi_memsize; @@ -221,7 +221,7 @@ if ( r3 ) memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); - + #ifdef CONFIG_BLK_DEV_INITRD /* take care of initrd if we have one */ if ( r4 ) @@ -233,7 +233,7 @@ /* take care of cmd line */ if ( r6 ) { - + *(char *)(r7+KERNELBASE) = 0; strcpy(cmd_line, (char *)(r6+KERNELBASE)); } diff -urN linux-2.4.21/arch/ppc/kernel/m8xx_setup.c linux-2.4.22/arch/ppc/kernel/m8xx_setup.c --- linux-2.4.21/arch/ppc/kernel/m8xx_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/m8xx_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -279,7 +279,7 @@ i8259_init(0); /* The i8259 cascade interrupt must be level sensitive. */ - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &= + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &= ~(0x80000000 >> ISA_BRIDGE_INT); if (request_irq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "i8259 cascade", diff -urN linux-2.4.21/arch/ppc/kernel/misc.S linux-2.4.22/arch/ppc/kernel/misc.S --- linux-2.4.21/arch/ppc/kernel/misc.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/misc.S 2003-08-25 04:44:40.000000000 -0700 @@ -205,7 +205,7 @@ mfmsr r4 stw r4,0(r3) blr - /* + /* * Need these nops here for taking over save/restore to * handle lost intrs * -- Cort @@ -229,7 +229,7 @@ nop _GLOBAL(__save_flags_ptr_end) -/* void __restore_flags(unsigned long flags) */ +/* void __restore_flags(unsigned long flags) */ _GLOBAL(__restore_flags) /* * Just set/clear the MSR_EE bit through restore/flags but do not @@ -277,7 +277,7 @@ SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ blr /* Done */ - /* + /* * Need these nops here for taking over save/restore to * handle lost intrs * -- Cort @@ -305,7 +305,7 @@ SYNC /* Some chip revs have problems here... */ mtmsr r3 /* Update machine state */ blr - /* + /* * Need these nops here for taking over save/restore to * handle lost intrs * -- Cort @@ -348,6 +348,20 @@ * Flush MMU TLB */ _GLOBAL(_tlbia) +#if defined(CONFIG_40x) && defined(CONFIG_PIN_TLB) + /* This needs to be coordinated with other pinning functions since + * we don't keep a memory location of number of entries to reduce + * cache pollution during these operations. + */ + lis r3, 0 + sync +1: + tlbwe r3, r3, TLB_TAG /* just ensure V is clear */ + addi r3, r3, 1 /* so r3 works fine for that */ + cmpwi 0, r3, 61 /* reserve last two entries */ + ble 1b + isync +#else #if defined(CONFIG_SMP) mfmsr r10 SYNC @@ -375,12 +389,24 @@ mtmsr r10 SYNC #endif /* CONFIG_SMP */ - blr +#endif /* defined(CONFIG_40x) && defined(CONFIG_PIN_TLB) */ + blr /* * Flush MMU TLB for a particular address */ _GLOBAL(_tlbie) +#ifdef CONFIG_40x + tlbsx. r3, 0, r3 + bne 10f + sync + /* There are only 64 TLB entries, so r3 < 64, which means bit 25, is clear. + * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate + * the TLB entry. */ + tlbwe r3, r3, TLB_TAG + isync +10: +#else #if defined(CONFIG_SMP) mfmsr r10 SYNC @@ -394,6 +420,7 @@ 10: lwarx r7,0,r9 cmpi 0,r7,0 bne- 10b + PPC405_ERR77(0,r9) stwcx. r8,0,r9 bne- 10b #endif /* CONFIG_SMP */ @@ -407,6 +434,7 @@ mtmsr r10 SYNC #endif +#endif /* CONFIG_40x */ blr /* @@ -418,9 +446,18 @@ isync lis r5, IDC_INVALL@h mtspr IC_CST, r5 -#elif defined(CONFIG_4xx) +#elif CONFIG_4xx +#ifdef CONFIG_403GCX + li r3, 512 + mtctr r3 + lis r4, KERNELBASE@h +1: iccci 0, r4 + addi r4, r4, 16 + bdnz 1b +#else lis r3, KERNELBASE@h iccci 0,r3 +#endif #else mfspr r3,PVR rlwinm r3,r3,16,16,31 @@ -430,7 +467,7 @@ mfspr r3,HID0 ori r3,r3,HID0_ICFI mtspr HID0,r3 -#endif /* CONFIG_8xx */ +#endif /* CONFIG_8xx/4xx */ isync blr @@ -530,6 +567,27 @@ sync /* wait for dcbi's to get to ram */ blr +#ifdef CONFIG_NOT_COHERENT_CACHE +/* + * 40x cores have 8K or 16K dcache and 32 byte line size. + * 440 has a 32K dcache and 32 byte line size. + * 8xx has 1, 2, 4, 8K variants. + * For now, cover the worst case of the 440. + * Must be called with external interrupts disabled. + */ +#define CACHE_NWAYS 64 +#define CACHE_NLINES 16 + +_GLOBAL(flush_dcache_all) + li r4, (2 * CACHE_NWAYS * CACHE_NLINES) + mtctr r4 + lis r5, KERNELBASE@h +1: lwz r3, 0(r5) /* Load one word from every line */ + addi r5, r5, L1_CACHE_LINE_SIZE + bdnz 1b + blr +#endif /* CONFIG_NOT_COHERENT_CACHE */ + /* * Flush a particular page from the data cache to RAM. * Note: this is necessary because the instruction cache does *not* @@ -558,7 +616,7 @@ sync isync blr - + /* * Clear a page using the dcbz instruction, which doesn't cause any * memory traffic (except to write out any cache lines which get @@ -709,7 +767,7 @@ stb r5,0(r3) eieio bdnz 00b - blr + blr _GLOBAL(_insw) cmpwi 0,r5,0 @@ -729,9 +787,9 @@ blelr- 00: lhzu r5,2(r4) eieio - sthbrx r5,0,r3 + sthbrx r5,0,r3 bdnz 00b - blr + blr _GLOBAL(_insl) cmpwi 0,r5,0 @@ -753,7 +811,7 @@ stwbrx r5,0,r3 eieio bdnz 00b - blr + blr _GLOBAL(ide_insw) _GLOBAL(_insw_ns) @@ -777,7 +835,7 @@ sth r5,0(r3) eieio bdnz 00b - blr + blr _GLOBAL(_insl_ns) cmpwi 0,r5,0 @@ -799,11 +857,11 @@ stw r5,0(r3) eieio bdnz 00b - blr + blr /* * Extended precision shifts. - * + * * Updated to be valid for shift counts from 0 to 63 inclusive. * -- Gabriel * @@ -811,12 +869,12 @@ * R5 has shift count * result in R3/R4 * - * ashrdi3: arithmetic right shift (sign propagation) - * lshrdi3: logical right shift + * ashrdi3: arithmetic right shift (sign propagation) + * lshrdi3: logical right shift * ashldi3: left shift */ _GLOBAL(__ashrdi3) - subfic r6,r5,32 + subfic r6,r5,32 srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count addi r7,r5,32 # could be xori, or addi with -32 slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) @@ -829,7 +887,7 @@ blr _GLOBAL(__ashldi3) - subfic r6,r5,32 + subfic r6,r5,32 slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count addi r7,r5,32 # could be xori, or addi with -32 srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count) @@ -840,14 +898,14 @@ blr _GLOBAL(__lshrdi3) - subfic r6,r5,32 + subfic r6,r5,32 srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count addi r7,r5,32 # could be xori, or addi with -32 slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32) or r4,r4,r6 # LSW |= t1 srw r3,r3,r5 # MSW = MSW >> count - or r4,r4,r7 # LSW |= t2 + or r4,r4,r7 # LSW |= t2 blr _GLOBAL(abs) @@ -859,7 +917,7 @@ _GLOBAL(_get_SP) mr r3,r1 /* Close enough */ blr - + /* * These are used in the alignment trap handler when emulating * single-precision loads and stores. @@ -867,7 +925,7 @@ * and exceptions as if the cpu had performed the load or store. */ -#if defined(CONFIG_4xx) +#ifdef CONFIG_4xx _GLOBAL(cvt_fd) lfs 0,0(r3) stfd 0,0(r4) @@ -919,7 +977,7 @@ /* * This routine is just here to keep GCC happy - sigh... - */ + */ _GLOBAL(__main) blr @@ -949,7 +1007,7 @@ SYSCALL(lseek) SYSCALL(read) -/* Why isn't this a) automatic, b) written in 'C'? */ +/* Why isn't this a) automatic, b) written in 'C'? */ .data .align 4 _GLOBAL(sys_call_table) @@ -1127,7 +1185,7 @@ .long sys_prctl .long sys_rt_sigreturn .long sys_rt_sigaction - .long sys_rt_sigprocmask + .long sys_rt_sigprocmask .long sys_rt_sigpending /* 175 */ .long sys_rt_sigtimedwait .long sys_rt_sigqueueinfo @@ -1145,14 +1203,14 @@ .long sys_vfork .long sys_getrlimit /* 190 */ .long sys_readahead - .long sys_mmap2 + .long sys_mmap2 .long sys_truncate64 .long sys_ftruncate64 .long sys_stat64 /* 195 */ .long sys_lstat64 .long sys_fstat64 .long sys_pciconfig_read - .long sys_pciconfig_write + .long sys_pciconfig_write .long sys_pciconfig_iobase /* 200 */ .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ .long sys_getdents64 diff -urN linux-2.4.21/arch/ppc/kernel/mk_defs.c linux-2.4.22/arch/ppc/kernel/mk_defs.c --- linux-2.4.21/arch/ppc/kernel/mk_defs.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/mk_defs.c 2003-08-25 04:44:40.000000000 -0700 @@ -57,6 +57,9 @@ DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_4xx + DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); +#endif /* Interrupt register frame */ DEFINE(TASK_UNION_SIZE, sizeof(union task_union)); DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); diff -urN linux-2.4.21/arch/ppc/kernel/mpc10x_common.c linux-2.4.22/arch/ppc/kernel/mpc10x_common.c --- linux-2.4.21/arch/ppc/kernel/mpc10x_common.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/mpc10x_common.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * arch/ppc/kernel/mpc10x_common.c - * + * * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge, * Mem ctlr, EPIC, etc. * @@ -227,7 +227,7 @@ printk("Host bridge in Agent mode\n"); /* Read or Set LMBAR & PCSRBAR? */ } - + /* Set base addr of the 8240/107 EUMB. */ early_write_config_dword(hose, 0, @@ -236,7 +236,7 @@ phys_eumb_base); /* Map EPIC register part of EUMB into vitual memory */ - OpenPIC_Addr = + OpenPIC_Addr = ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET, MPC10X_EUMB_EPIC_SIZE); } diff -urN linux-2.4.21/arch/ppc/kernel/ocp.c linux-2.4.22/arch/ppc/kernel/ocp.c --- linux-2.4.21/arch/ppc/kernel/ocp.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/kernel/ocp.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,450 @@ +/* + * ocp.c + * + * (c) Benjamin Herrenschmidt (benh@kernel.crashing.org) + * Mipsys - France + * + " Derived from work (c) Armin Kuster akuster@pacbell.net + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DBG(x) printk x +#define DBG(x) + +extern struct ocp_def core_ocp[]; /* Static list of devices, provided by + CPU core */ + +LIST_HEAD(ocp_devices); /* List of all OCP devices */ +LIST_HEAD(ocp_drivers); /* List of all OCP drivers */ +DECLARE_RWSEM(ocp_devices_sem); /* Global semaphores for those lists */ +DECLARE_MUTEX(ocp_drivers_sem); /* Global semaphores for those lists */ + +static int ocp_inited; + +/** + * ocp_driver_match - Match one driver to one device + * @drv: driver to match + * @dev: device to match + * + * This function returns 0 if the driver and device don't match + */ +static int +ocp_driver_match(struct ocp_driver *drv, struct ocp_device *dev) +{ + const struct ocp_device_id *ids = drv->id_table; + + if (!ids) + return 0; + + while (ids->vendor || ids->function) { + if ((ids->vendor == OCP_ANY_ID + || ids->vendor == dev->def->vendor) + && (ids->function == OCP_ANY_ID + || ids->function == dev->def->function)) + return 1; + ids++; + } + return 0; +} + + +/** + * ocp_bind_drivers - Match all drivers with all devices + * @candidate: driver beeing registered + * + * This function is called on driver registration and device discovery, + * it redo the matching of all "driverless" devices with all possible + * driver candidates. + * The driver beeing registered can be optionally passed in, in which + * case, the function will return -ENODEV is no match have been found + * or if all matches failed with a different code than -EAGAIN + */ +static int +ocp_bind_drivers(struct ocp_driver *candidate) +{ + struct list_head *deventry, *drventry; + struct ocp_device *dev; + struct ocp_driver *drv; + int one_again, one_match; + int count = 0; + + DBG(("ocp: binding drivers...\n")); + do { + /* We re-do the match loop if we had a sucess match and got one -EAGAIN + */ + one_match = one_again = 0; + down_read(&ocp_devices_sem); + list_for_each(deventry, &ocp_devices) { + dev = list_entry(deventry, struct ocp_device, link); + if (dev->driver != NULL) + continue; + DBG(("ocp: device %s unmatched, trying to match...\n", dev->name)); + list_for_each(drventry, &ocp_drivers) { + drv = list_entry(drventry, struct ocp_driver, link); + if (ocp_driver_match(drv, dev)) { + int rc; + + /* Hrm... shall we set dev->driver after or before ? */ + DBG(("ocp: match with driver %s, calling probe...\n", drv->name)); + rc = drv->probe(dev); + DBG(("ocp: probe result: %d\n", rc)); + if (rc == 0) { + /* Driver matched, next device */ + dev->driver = drv; + one_match = 1; + if (drv == candidate) + count++; + break; + } else if (rc == -EAGAIN) { + /* Driver matched but asked for later call, next device */ + one_again = 1; + if (drv == candidate) + count++; + break; + } + } + } + } + up_read(&ocp_devices_sem); + } while(one_match && one_again); + DBG(("ocp: binding drivers... done.\n")); + + return count; +} + +/** + * ocp_register_driver - Register an OCP driver + * @drv: pointer to statically defined ocp_driver structure + * + * The driver's probe() callback is called either recursively + * by this function or upon later call of ocp_init + * + * NOTE: Probe is called with ocp_drivers_sem heocp_find_deviceld, it shouldn't + * call ocp_register/unregister_driver on his own code path. + * however, it _can_ call ocp_find_device(). + * + * NOTE2: Detection of devices is a 2 pass step on this implementation, + * hotswap isn't supported. First, all OCP devices are put in the device + * list, _then_ all drivers are probed on each match. + * + * NOTE3: Drivers are allowed to return -EAGAIN from the probe() routine. + * this will cause them to be called again for this specific device as + * soon as another device have been probed or another driver registered. + * this, gives a simple way for a driver like EMAC to wait for another driver, + * like MAL to be up. There is potentially a small race if MAL happens to + * unregister, but this is hopefully never happening. + * + * This function returns a count of how many devices actually matched + * (wether the probe routine returned 0 or -EAGAIN, a different error + * code isn't considered as a match). + */ + +int +ocp_register_driver(struct ocp_driver *drv) +{ + int rc = 0; + + DBG(("ocp: ocp_register_driver(%s)...\n", drv->name)); + + /* Add to driver list */ + down(&ocp_drivers_sem); + list_add_tail(&drv->link, &ocp_drivers); + + /* Check matching devices */ + rc = ocp_bind_drivers(drv); + + up(&ocp_drivers_sem); + + DBG(("ocp: ocp_register_driver(%s)... done, count: %d.\n", drv->name, rc)); + + return rc; +} + +/** + * ocp_unregister_driver - Unregister an OCP driver + * @drv: pointer to statically defined ocp_driver structure + * + * The driver's remove() callback is called recursively + * by this function for any device already registered + */ + +void +ocp_unregister_driver(struct ocp_driver *drv) +{ + struct ocp_device *dev; + struct list_head *entry; + + DBG(("ocp: ocp_unregister_driver(%s)...\n", drv->name)); + + /* Call remove() routine for all devices using it */ + down(&ocp_drivers_sem); + down_read(&ocp_devices_sem); + list_for_each(entry, &ocp_devices) { + dev = list_entry(entry, struct ocp_device, link); + if (dev->driver == drv) { + drv->remove(dev); + dev->driver = NULL; + dev->drvdata = NULL; + } + } + up_read(&ocp_devices_sem); + + /* Unlink driver structure */ + list_del_init(&drv->link); + up(&ocp_drivers_sem); + + DBG(("ocp: ocp_unregister_driver(%s)... done.\n", drv->name)); +} + +/** + * ocp_find_device - Find a device by function & index + * @vendor: vendor ID of the device (or OCP_ANY_ID) + * @function: function code of the device (or OCP_ANY_ID) + * @idx: index of the device (or OCP_ANY_INDEX) + * + * This function allows a lookup of a given function by it's + * index, it's typically used to find the MAL or ZMII associated + * with an EMAC or similar horrors. + * You can pass vendor, though you usually want OCP_ANY_ID there... + */ +struct ocp_device * +ocp_find_device(unsigned int vendor, unsigned int function, int index) +{ + struct list_head *entry; + struct ocp_device *dev, *found = NULL; + + DBG(("ocp: ocp_find_device(vendor: %x, function: %x, index: %d)...\n", + vendor, function, index)); + + down_read(&ocp_devices_sem); + list_for_each(entry, &ocp_devices) { + dev = list_entry(entry, struct ocp_device, link); + if (vendor != OCP_ANY_ID && vendor != dev->def->vendor) + continue; + if (function != OCP_ANY_ID && function != dev->def->function) + continue; + if (index != OCP_ANY_INDEX && index != dev->def->index) + continue; + found = dev; + break; + } + up_read(&ocp_devices_sem); + + DBG(("ocp: ocp_find_device(vendor: %x, function: %x, index: %d)... done.\n", + vendor, function, index)); + + return found; +} + +/** + * ocp_add_one_device - Add a device + * @def: static device definition structure + * + * This function is solely meant to be called by ocp_init + * to add one device from the core static list to the + * device list + */ +static void +ocp_add_one_device(struct ocp_def *def) +{ + struct ocp_device *dev; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) + return; + memset(dev, 0, sizeof(*dev)); + dev->def = def; + dev->current_state = 4; + sprintf(dev->name, "OCP device %04x:%04x:%04x", + dev->def->vendor, dev->def->function, dev->def->index); + list_add_tail(&dev->link, &ocp_devices); +} + +#ifdef CONFIG_PM +/* + * OCP Power management.. + * + * This needs to be done centralized, so that we power manage PCI + * devices in the right order: we should not shut down PCI bridges + * before we've shut down the devices behind them, and we should + * not wake up devices before we've woken up the bridge to the + * device.. Eh? + * + * We do not touch devices that don't have a driver that exports + * a suspend/resume function. That is just too dangerous. If the default + * PCI suspend/resume functions work for a device, the driver can + * easily implement them (ie just have a suspend function that calls + * the pci_set_power_state() function). + * + * BenH: Implementation here couldn't work properly. This version + * slightly modified and _might_ be more useable, but real + * PM support will probably have to wait for 2.5 + */ + +static int ocp_pm_save_state_device(struct ocp_device *dev, u32 state) +{ + int error = 0; + if (dev) { + struct ocp_driver *driver = dev->driver; + if (driver && driver->save_state) + error = driver->save_state(dev,state); + } + return error; +} + +static int ocp_pm_suspend_device(struct ocp_device *dev, u32 state) +{ + int error = 0; + if (dev) { + struct ocp_driver *driver = dev->driver; + if (driver && driver->suspend) + error = driver->suspend(dev,state); + } + return error; +} + +static int ocp_pm_resume_device(struct ocp_device *dev) +{ + int error = 0; + if (dev) { + struct ocp_driver *driver = dev->driver; + if (driver && driver->resume) + error = driver->resume(dev); + } + return error; +} + +static int +ocp_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data) +{ + int error = 0; + struct list_head *entry; + struct ocp_device *dev; + + down(&ocp_drivers_sem); + down_read(&ocp_devices_sem); + + list_for_each(entry, &ocp_devices) { + dev = list_entry(entry, struct ocp_device, link); + switch (rqst) { + case PM_SAVE_STATE: + error = ocp_pm_save_state_device(dev, 3); + break; + case PM_SUSPEND: + error = ocp_pm_suspend_device(dev, 3); + break; + case PM_RESUME: + error = ocp_pm_resume_device(dev); + break; + default: break; + } + if (error) + break; + } + return error; +} + +/* + * Is this ever used ? + */ +void +ppc4xx_cpm_fr(u32 bits, int val) +{ + unsigned long flags; + + save_flags(flags); + cli(); + + if (val) + mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | bits); + else + mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~bits); + + restore_flags(flags); +} +#endif /* CONFIG_PM */ + +/** + * ocp_init - Init OCP device management + * + * This function is meant to be called once, and only once to initialize + * the OCP device management and build the list of devices. Note that + * it can actually be called at any time, it's perfectly legal to + * register drivers before ocp_init() is called + */ +int +ocp_init(void) +{ + struct ocp_def *def; + + /* ocp_init is by default an initcall. If your arch requires this to + * be called earlier, then go on, ocp_init is non-static for that purpose, + * and can safely be called twice + */ + if (ocp_inited) + return 0; + ocp_inited = 1; + + DBG(("ocp: ocp_init()...\n")); + + /* Fill the devices list */ + down_write(&ocp_devices_sem); + for (def = core_ocp; def->vendor != OCP_VENDOR_INVALID; def++) + ocp_add_one_device(def); + up_write(&ocp_devices_sem); + + DBG(("ocp: ocp_init()... added...\n")); + + /* Call drivers probes */ + down(&ocp_drivers_sem); + ocp_bind_drivers(NULL); + up(&ocp_drivers_sem); + +#ifdef CONFIG_PM + pm_register(PM_SYS_DEV, 0, ocp_pm_callback); +#endif + + DBG(("ocp: ocp_init()... done.\n")); + + return 0; +} + +__initcall(ocp_init); + +EXPORT_SYMBOL(ocp_register_driver); +EXPORT_SYMBOL(ocp_unregister_driver); diff -urN linux-2.4.21/arch/ppc/kernel/open_pic.c linux-2.4.22/arch/ppc/kernel/open_pic.c --- linux-2.4.21/arch/ppc/kernel/open_pic.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/open_pic.c 2003-08-25 04:44:40.000000000 -0700 @@ -540,7 +540,7 @@ /* * Send an IPI to one or more CPUs - * + * * Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI) * and not a system-wide interrupt number */ @@ -557,12 +557,12 @@ void openpic_request_IPIs(void) { int i; - + /* - * Make sure this matches what is defined in smp.c for - * smp_message_{pass|recv}() or what shows up in + * Make sure this matches what is defined in smp.c for + * smp_message_{pass|recv}() or what shows up in * /proc/interrupts will be wrong!!! --Troy */ - + if (OpenPIC == NULL) return; @@ -698,7 +698,7 @@ { volatile u_int *vpp; u32 vp; - + check_arg_irq(irq); vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority; openpic_setfield(vpp, OPENPIC_MASK); @@ -712,7 +712,7 @@ #ifdef CONFIG_SMP /* * Enable/disable an IPI interrupt source - * + * * Externally called, irq is an offseted system-wide interrupt number */ void openpic_enable_ipi(u_int irq) @@ -875,7 +875,7 @@ { int i; unsigned long flags; - + spin_lock_irqsave(&openpic_setup_lock, flags); for (i=0; isysdata; unsigned long io_offset; - + new = res->start; res->flags &= ~IORESOURCE_UNSET; if (hose && res->flags & IORESOURCE_IO) { @@ -211,7 +211,7 @@ /* Enable PCI interrupt */ if (pci_read_config_byte(dev, 0x91, &val) == 0) pci_write_config_byte(dev, 0x91, val | 0x30); - /* Disable ISA interrupt mode */ + /* Disable ISA interrupt mode */ if (pci_read_config_byte(dev, 0x92, &val) == 0) pci_write_config_byte(dev, 0x92, val & ~0x06); } @@ -223,7 +223,7 @@ signal out the MFUNC0 pin */ if (pci_read_config_byte(dev, 0x8c, &val) == 0) pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2); - /* Disable ISA interrupt mode */ + /* Disable ISA interrupt mode */ if (pci_read_config_byte(dev, 0x92, &val) == 0) pci_write_config_byte(dev, 0x92, val & ~0x06); } @@ -695,7 +695,7 @@ hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose)); memset(hose, 0, sizeof(struct pci_controller)); - + *hose_tail = hose; hose_tail = &hose->next; @@ -713,7 +713,7 @@ { int *bus_range; int len; - + if (pci_bus >= pci_bus_count) return; bus_range = (int *) get_property(node, "bus-range", &len); @@ -723,11 +723,11 @@ return; } pci_to_OF_bus_map[pci_bus] = bus_range[0]; - + for (node=node->child; node != 0;node = node->sibling) { struct pci_dev* dev; unsigned int *class_code, *reg; - + class_code = (unsigned int *) get_property(node, "class-code", 0); if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) @@ -741,29 +741,29 @@ make_one_node_map(node, dev->subordinate->number); } } - + void __openfirmware pcibios_make_OF_bus_map(void) { int i; struct pci_controller* hose; u8* of_prop_map; - + pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); if (!pci_to_OF_bus_map) { printk(KERN_ERR "Can't allocate OF bus map !\n"); return; } - + /* We fill the bus map with invalid values, that helps * debugging. */ for (i=0; inext) { - struct device_node* node; + struct device_node* node; node = (struct device_node *)hose->arch_data; if (!node) continue; @@ -779,7 +779,7 @@ continue; printk("%d -> %d\n", i, pci_to_OF_bus_map[i]); } -#endif +#endif } typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data); @@ -788,10 +788,10 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data) { struct device_node* sub_node; - + for (; node != 0;node = node->sibling) { unsigned int *class_code; - + if (filter(node, data)) return node; @@ -817,7 +817,7 @@ { unsigned int *reg; u8* fdata = (u8*)data; - + reg = (unsigned int *) get_property(node, "reg", 0); if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] && ((reg[0] >> 16) & 0xff) == fdata[0]) @@ -833,7 +833,7 @@ return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); } -/* +/* * Scans the OF tree for a device node matching a PCI device */ struct device_node* @@ -842,10 +842,10 @@ struct pci_controller *hose; struct device_node *node; int bus; - + if (!have_of) return NULL; - + /* Lookup the hose */ bus = dev->bus->number; hose = pci_bus_to_hose(bus); @@ -862,7 +862,7 @@ bus = pci_to_OF_bus_map[bus]; if (bus == 0xff) return NULL; - + /* Now, lookup childs of the hose */ return scan_OF_childs_for_device(node->child, bus, dev->devfn); } @@ -895,7 +895,7 @@ return ((void *)node == data); } -/* +/* * Returns the PCI device matching a given OF node */ int @@ -904,7 +904,7 @@ unsigned int *reg; struct pci_controller* hose; struct pci_dev* dev; - + if (!have_of) return -ENODEV; /* Make sure it's really a PCI device */ @@ -1038,7 +1038,7 @@ pci_create_OF_bus_map(void) { struct property* of_prop; - + of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); if (of_prop && find_path_device("/")) { memset(of_prop, -1, sizeof(struct property) + 256); @@ -1053,13 +1053,13 @@ /* * This set of routines checks for PCI<->PCI bridges that have closed * IO resources and have child devices. It tries to re-open an IO - * window on them. - * + * window on them. + * * This is a _temporary_ fix to workaround a problem with Apple's OF * closing IO windows on P2P bridges when the OF drivers of cards * below this bridge don't claim any IO range (typically ATI or * Adaptec). - * + * * A more complete fix would be to use drivers/pci/setup-bus.c, which * involves a working pcibios_fixup_pbus_ranges(), some more care about * ordering when creating the host bus resources, and maybe a few more @@ -1075,7 +1075,7 @@ u32 l; u16 w; struct resource res; - + res = *(bus->resource[0]); DBG("Remapping Bus %d, bridge: %s\n", bus->number, bridge->name); @@ -1175,7 +1175,7 @@ break; if (parent_io >= 4) return; - + for (ln=bus->children.next; ln != &bus->children; ln=ln->next) { struct pci_bus *b = pci_bus_b(ln); struct pci_dev *d = b->self; @@ -1193,7 +1193,7 @@ */ if (tmp_res.start == 0) tmp_res.start = 0x1000; - + if (!list_empty(&b->devices) && res && res->flags == 0 && res != bus->resource[parent_io] && (d->class >> 8) == PCI_CLASS_BRIDGE_PCI && @@ -1222,7 +1222,7 @@ *res = tmp_res; res->flags = IORESOURCE_IO; res->name = b->name; - + /* Find a resource in the parent where we can allocate */ for (i = 0 ; i < 4; i++) { struct resource *r = bus->resource[i]; @@ -1233,7 +1233,7 @@ DBG("Trying to allocate from %08lx, size %08lx from parent" " res %d: %08lx -> %08lx\n", res->start, res->end, i, r->start, r->end); - + if (allocate_resource(r, res, res->end + 1, res->start, max, res->end + 1, NULL, NULL) < 0) { DBG("Failed !\n"); @@ -1439,13 +1439,13 @@ if (ppc_md.pcibios_enable_device_hook) if (ppc_md.pcibios_enable_device_hook(dev, 0)) return -EINVAL; - + pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; for (idx=0; idx<6; idx++) { if(!(mask & (1<resource[idx]; if (r->flags & IORESOURCE_UNSET) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); @@ -1709,7 +1709,7 @@ if (!hose) return -ENODEV; - + switch (which) { case IOBASE_BRIDGE_NUMBER: return (long)hose->first_busno; diff -urN linux-2.4.21/arch/ppc/kernel/pci_auto.c linux-2.4.22/arch/ppc/kernel/pci_auto.c --- linux-2.4.21/arch/ppc/kernel/pci_auto.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/pci_auto.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/kernel/pci_auto.c - * + * * PCI autoconfiguration library * * Author: Matt Porter @@ -80,7 +80,7 @@ PCI_BASE_ADDRESS_MEM_TYPE_64) found_mem64 = 1; - addr_mask = PCI_BASE_ADDRESS_MEM_MASK; + addr_mask = PCI_BASE_ADDRESS_MEM_MASK; upper_limit = &pciauto_upper_memspc; DBG("PCI Autoconfig: BAR 0x%x, Mem ", bar); } @@ -104,7 +104,7 @@ * If we are a 64-bit decoder then increment to the * upper 32 bits of the bar and force it to locate * in the lower 4GB of memory. - */ + */ if (found_mem64) { bar += 4; early_write_config_dword(hose, @@ -243,7 +243,7 @@ pci_devfn, PCI_IO_BASE_UPPER16, pciauto_upper_iospc >> 16); - + /* Enable memory and I/O accesses, enable bus master */ early_read_config_dword(hose, current_bus, @@ -329,9 +329,9 @@ /* * Reserve an additional 4MB for mem space and 16KB for * I/O space. This should cover any additional space - * requirement of unusual CardBus devices with + * requirement of unusual CardBus devices with * additional bridges that can consume more address space. - * + * * Although pcmcia-cs currently will reprogram bridge * windows, the goal is to add an option to leave them * alone and use the bridge window ranges as the regions @@ -359,7 +359,7 @@ pci_devfn, 0x2c, pciauto_upper_iospc); - + /* Enable memory and I/O accesses, enable bus master */ early_read_config_dword(hose, current_bus, diff -urN linux-2.4.21/arch/ppc/kernel/ppc-stub.c linux-2.4.22/arch/ppc/kernel/ppc-stub.c --- linux-2.4.21/arch/ppc/kernel/ppc-stub.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/ppc-stub.c 2003-08-25 04:44:40.000000000 -0700 @@ -716,10 +716,10 @@ breakinst: .long 0x7d821008"); } -#ifdef CONFIG_KGDB_CONSOLE -/* +#ifdef CONFIG_KGDB_CONSOLE +/* * Output string in GDB O-packet format if GDB has connected. If nothing - * output, returns 0 (caller must then handle output) + * output, returns 0 (caller must then handle output) */ int kgdb_output_string (const char* s, unsigned int count) @@ -729,7 +729,7 @@ if (!kgdb_started) return 0; - count = (count <= (sizeof(buffer) / 2 - 2)) + count = (count <= (sizeof(buffer) / 2 - 2)) ? count : (sizeof(buffer) / 2 - 2); buffer[0] = 'O'; diff -urN linux-2.4.21/arch/ppc/kernel/ppc405_pci.c linux-2.4.22/arch/ppc/kernel/ppc405_pci.c --- linux-2.4.21/arch/ppc/kernel/ppc405_pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/kernel/ppc405_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,217 @@ +/* + * FILE NAME: ppc405_pci.c + * + * BRIEF MODULE DESCRIPTION: + * Based on arch/ppc/kernel/indirect.c, Copyright (C) 1998 Gabriel Paubert. + * + * Author: MontaVista Software, Inc. + * Frank Rowand + * Debbie Chu + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_DEBUG_BRINGUP +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +extern void bios_fixup(struct pci_controller *, struct pcil0_regs *); +extern int ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, + unsigned char pin); + +void +ppc405_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + unsigned long max_host_addr; + unsigned long min_host_addr; + struct resource *res; + + /* + * openbios puts some graphics cards in the same range as the host + * controller uses to map to SDRAM. Fix it. + */ + + min_host_addr = 0; + max_host_addr = PPC405_PCI_MEM_BASE - 1; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + res = dev->resource + i; + if (!res->start) + continue; + if ((res->flags & IORESOURCE_MEM) && + (((res->start >= min_host_addr) + && (res->start <= max_host_addr)) + || ((res->end >= min_host_addr) + && (res->end <= max_host_addr)) + || ((res->start < min_host_addr) + && (res->end > max_host_addr)) + ) + ) { + + DBG(KERN_ERR "PCI: 0x%lx <= resource[%d] <= 0x%lx" + ", bus 0x%x dev 0x%2.2x.%1.1x,\n" + KERN_ERR " %s\n" + KERN_ERR " fixup will be attempted later\n", + min_host_addr, i, max_host_addr, + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), dev->name); + + /* force pcibios_assign_resources() to assign a new address */ + res->end -= res->start; + res->start = 0; + } + } +} + +static int +ppc4xx_exclude_device(unsigned char bus, unsigned char devfn) +{ + /* We prevent us from seeing ourselves to avoid having + * the kernel try to remap our BAR #1 and fuck up bus + * master from external PCI devices + */ + return (bus == 0 && devfn == 0); +} + +void +ppc4xx_find_bridges(void) +{ + struct pci_controller *hose_a; + struct pcil0_regs *pcip; + unsigned int new_pmm_max; + unsigned int new_pmm_min; + + isa_io_base = 0; + isa_mem_base = 0; + pci_dram_offset = 0; + +#if (PSR_PCI_ARBIT_EN > 1) + /* Check if running in slave mode */ + if ((mfdcr(DCRN_CHPSR) & PSR_PCI_ARBIT_EN) == 0) { + printk("Running as PCI slave, kernel PCI disabled !\n"); + return; + } +#endif + /* Setup PCI32 hose */ + hose_a = pcibios_alloc_controller(); + if (!hose_a) + return; + setup_indirect_pci(hose_a, PPC405_PCI_CONFIG_ADDR, + PPC405_PCI_CONFIG_DATA); + +#ifdef CONFIG_XILINX_OCP + /* Eliminate "unused variable" warning for pcip. Optimizer removes. */ + pcip = NULL; + new_pmm_min = PPC405_PCI_LOWER_MEM; + new_pmm_max = PPC405_PCI_UPPER_MEM; +#else /* Must be IBM */ + pcip = ioremap(PPC4xx_PCI_LCFG_PADDR, PAGE_SIZE); + if (pcip != NULL) { + unsigned int tmp_addr; + unsigned int tmp_size; + unsigned int reg_index; + +#if defined(CONFIG_BIOS_FIXUP) + bios_fixup(hose_a, pcip); +#endif + new_pmm_min = 0xffffffff; + for (reg_index = 0; reg_index < 3; reg_index++) { + tmp_size = in_le32((void *) &(pcip->pmm[reg_index].ma)); // *_PMM0MA + if (tmp_size & 0x1) { + tmp_addr = in_le32((void *) &(pcip->pmm[reg_index].pcila)); // *_PMM0PCILA + if (tmp_addr < PPC405_PCI_PHY_MEM_BASE) { + printk(KERN_DEBUG + "Disabling mapping to PCI mem addr 0x%8.8x\n", + tmp_addr); + out_le32((void *) &(pcip->pmm[reg_index].ma), tmp_size & ~1); // *_PMMOMA + } else { + tmp_addr = in_le32((void *) &(pcip->pmm[reg_index].la)); // *_PMMOLA + if (tmp_addr < new_pmm_min) + new_pmm_min = tmp_addr; + tmp_addr = + tmp_addr + (0xffffffff - + (tmp_size & + 0xffffc000)); + if (tmp_addr > PPC405_PCI_UPPER_MEM) { + new_pmm_max = tmp_addr; // PPC405_PCI_UPPER_MEM + } else { + new_pmm_max = + PPC405_PCI_UPPER_MEM; + } + } + } + + } // for + + iounmap(pcip); + } +#endif + + hose_a->first_busno = 0; + hose_a->last_busno = 0xff; + hose_a->pci_mem_offset = 0; + + /* Setup bridge memory/IO ranges & resources + * TODO: Handle firmwares setting up a legacy ISA mem base + */ + hose_a->io_space.start = PPC405_PCI_LOWER_IO; + hose_a->io_space.end = PPC405_PCI_UPPER_IO; + hose_a->mem_space.start = new_pmm_min; + hose_a->mem_space.end = new_pmm_max; + hose_a->io_base_phys = PPC405_PCI_PHY_IO_BASE; + hose_a->io_base_virt = ioremap(hose_a->io_base_phys, 0x10000); + hose_a->io_resource.start = 0; + hose_a->io_resource.end = PPC405_PCI_UPPER_IO - PPC405_PCI_LOWER_IO; + hose_a->io_resource.flags = IORESOURCE_IO; + hose_a->io_resource.name = "PCI I/O"; + hose_a->mem_resources[0].start = new_pmm_min; + hose_a->mem_resources[0].end = new_pmm_max; + hose_a->mem_resources[0].flags = IORESOURCE_MEM; + hose_a->mem_resources[0].name = "PCI Memory"; + isa_io_base = (int) hose_a->io_base_virt; + isa_mem_base = 0; /* ISA not implemented */ + ISA_DMA_THRESHOLD = 0x00ffffff; /* ??? ISA not implemented */ + + /* Scan busses & initial setup by pci_auto */ + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + + /* Setup ppc_md */ + ppc_md.pcibios_fixup = NULL; + ppc_md.pci_exclude_device = ppc4xx_exclude_device; + ppc_md.pcibios_fixup_resources = ppc405_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = ppc405_map_irq; +} diff -urN linux-2.4.21/arch/ppc/kernel/ppc4xx_pic.c linux-2.4.22/arch/ppc/kernel/ppc4xx_pic.c --- linux-2.4.21/arch/ppc/kernel/ppc4xx_pic.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/ppc4xx_pic.c 2003-08-25 04:44:40.000000000 -0700 @@ -15,10 +15,14 @@ * there are eight internal interrupts for the on-chip serial port * (SPU), DMA controller, and JTAG controller. * - * The PowerPC 405 cores' Universal Interrupt Controller (UIC) has 32 - * possible interrupts as well. There are seven, configurable external - * interrupt pins and there are 17 internal interrupts for the on-chip - * serial port, DMA controller, on-chip Ethernet controller, PCI, etc. + * The PowerPC 405/440 cores' Universal Interrupt Controller (UIC) has + * 32 possible interrupts as well. Depending on the core and SoC + * implementation, a portion of the interrrupts are used for on-chip + * peripherals and a portion of the interrupts are available to be + * configured for external devices generating interrupts. + * + * The PowerNP and 440GP (and most likely future implementations) have + * cascaded UICs. * */ @@ -33,19 +37,31 @@ #include /* Global Variables */ - struct hw_interrupt_type *ppc4xx_pic; +/* + * We define 4xxIRQ_InitSenses table thusly: + * bit 0x1: sense, 0 for edge and 1 for level. + * bit 0x2: polarity, 0 for negative, 1 for positive. + */ +unsigned int ibm4xxPIC_NumInitSenses __initdata = 0; +unsigned char *ibm4xxPIC_InitSenses __initdata = NULL; + +/* Six of one, half dozen of the other....#ifdefs, separate files, + * other tricks..... + * + * There are basically two types of interrupt controllers, the 403 AIC + * and the "others" with UIC. I just kept them both here separated + * with #ifdefs, but it seems to change depending upon how supporting + * files (like ppc4xx.h) change. -- Dan. + */ +#ifdef CONFIG_403 /* Function Prototypes */ -static void ppc403_aic_enable(unsigned int irq); -static void ppc403_aic_disable(unsigned int irq); -static void ppc403_aic_disable_and_ack(unsigned int irq); - -static void ppc405_uic_enable(unsigned int irq); -static void ppc405_uic_disable(unsigned int irq); -static void ppc405_uic_disable_and_ack(unsigned int irq); +static void ppc403_aic_enable(unsigned int irq); +static void ppc403_aic_disable(unsigned int irq); +static void ppc403_aic_disable_and_ack(unsigned int irq); static struct hw_interrupt_type ppc403_aic = { "403GC AIC", @@ -57,55 +73,11 @@ 0 }; -static struct hw_interrupt_type ppc405_uic = { - "405GP UIC", - NULL, - NULL, - ppc405_uic_enable, - ppc405_uic_disable, - ppc405_uic_disable_and_ack, - 0 -}; - -/* - * Document me. - */ -void __init -ppc4xx_pic_init(void) -{ - unsigned long ver = PVR_VER(mfspr(SPRN_PVR)); - - switch (ver) { - - case PVR_VER(PVR_403GC): - /* - * Disable all external interrupts until they are - * explicity requested. - */ - ppc_cached_irq_mask[0] = 0; - mtdcr(DCRN_EXIER, 0); - - ppc4xx_pic = &ppc403_aic; - break; - - case PVR_VER(PVR_405GP): - ppc4xx_pic = &ppc405_uic; - break; - } - - return; -} - -/* - * XXX - Currently 403-specific! - * - * Document me. - */ int -ppc4xx_pic_get_irq(struct pt_regs *regs) +ppc403_pic_get_irq(struct pt_regs *regs) { int irq; - unsigned long bits, mask = (1 << 31); + unsigned long bits; /* * Only report the status of those interrupts that are actually @@ -117,19 +89,17 @@ /* * Walk through the interrupts from highest priority to lowest, and * report the first pending interrupt found. + * We want PPC, not C bit numbering, so just subtract the ffs() + * result from 32. */ + irq = 32 - ffs(bits); - for (irq = 0; irq < NR_IRQS; irq++, mask >>= 1) { - if (bits & mask) - break; - } + if (irq == NR_AIC_IRQS) + irq = -1; return (irq); } -/* - * Document me. - */ static void ppc403_aic_enable(unsigned int irq) { @@ -142,9 +112,6 @@ mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]); } -/* - * Document me. - */ static void ppc403_aic_disable(unsigned int irq) { @@ -157,9 +124,6 @@ mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]); } -/* - * Document me. - */ static void ppc403_aic_disable_and_ack(unsigned int irq) { @@ -173,29 +137,308 @@ mtdcr(DCRN_EXISR, (1 << (31 - bit))); } -/* - * Document me. - */ +#else + +#ifndef UIC1 +#define UIC1 UIC0 +#endif + static void ppc405_uic_enable(unsigned int irq) { - /* XXX - Implement me. */ + int bit, word; + irq_desc_t *desc = irq_desc + irq; + + bit = irq & 0x1f; + word = irq >> 5; + +#ifdef UIC_DEBUG + printk("ppc405_uic_enable - irq %d word %d bit 0x%x\n", irq, word, bit); +#endif + ppc_cached_irq_mask[word] |= 1 << (31 - bit); + switch (word) { + case 0: + mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]); + if ((mfdcr(DCRN_UIC_TR(UIC0)) & (1 << (31 - bit))) == 0) + desc->status |= IRQ_LEVEL; + else + /* lets hope this works since in linux/irq.h + * there is no define for EDGE and it's assumed + * once you set status to LEVEL you would not + * want to change it - Armin + */ + desc->status = desc->status & ~IRQ_LEVEL; + break; + case 1: + mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]); + if ((mfdcr(DCRN_UIC_TR(UIC1)) & (1 << (31 - bit))) == 0) + desc->status |= IRQ_LEVEL; + else + /* lets hope this works since in linux/irq.h + * there is no define for EDGE and it's assumed + * once you set status to LEVEL you would not + * want to change it - Armin + */ + desc->status = desc->status & ~IRQ_LEVEL; + break; + } + } -/* - * Document me. - */ static void ppc405_uic_disable(unsigned int irq) { - /* XXX - Implement me. */ + int bit, word; + + bit = irq & 0x1f; + word = irq >> 5; +#ifdef UIC_DEBUG + printk("ppc405_uic_disable - irq %d word %d bit 0x%x\n", irq, word, + bit); +#endif + ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); + switch (word) { + case 0: + mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]); + break; + case 1: + mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]); + break; + } } -/* - * Document me. - */ static void ppc405_uic_disable_and_ack(unsigned int irq) { - /* XXX - Implement me. */ + int bit, word; + + bit = irq & 0x1f; + word = irq >> 5; + +#ifdef UIC_DEBUG + printk("ppc405_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq, + word, bit); +#endif + ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); + switch (word) { + case 0: + mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]); + mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - bit))); + break; +#if NR_UICS > 1 + case 1: + mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]); + mtdcr(DCRN_UIC_SR(UIC1), (1 << (31 - bit))); + /* ACK cascaded interrupt in UIC0 */ + mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC))); + break; +#endif + } +} + +static void +ppc405_uic_end(unsigned int irq) +{ + int bit, word; + unsigned int tr_bits; + + bit = irq & 0x1f; + word = irq >> 5; + +#ifdef UIC_DEBUG + printk("ppc405_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit); +#endif + + switch (word) { + case 0: + tr_bits = mfdcr(DCRN_UIC_TR(UIC0)); + break; + case 1: + tr_bits = mfdcr(DCRN_UIC_TR(UIC1)); + break; + } + + if ((tr_bits & (1 << (31 - bit))) == 0) { + /* level trigger */ + switch (word) { + case 0: + mtdcr(DCRN_UIC_SR(UIC0), 1 << (31 - bit)); + break; +#if NR_UICS > 1 + case 1: + mtdcr(DCRN_UIC_SR(UIC1), 1 << (31 - bit)); + /* ACK cascaded interrupt in UIC0 */ + mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC))); + break; +#endif + } + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + ppc_cached_irq_mask[word] |= 1 << (31 - bit); + switch (word) { + case 0: + mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]); + break; + case 1: + mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]); + break; + } + } +} + +static struct hw_interrupt_type ppc405_uic = { +#if (NR_UICS == 1) + "IBM UIC", +#else + "IBM UIC Cascade", +#endif + NULL, + NULL, + ppc405_uic_enable, + ppc405_uic_disable, + ppc405_uic_disable_and_ack, + ppc405_uic_end, + 0 +}; + +int +ppc405_pic_get_irq(struct pt_regs *regs) +{ + int irq, cas_irq; + unsigned long bits; + cas_irq = 0; + /* + * Only report the status of those interrupts that are actually + * enabled. + */ + + bits = mfdcr(DCRN_UIC_MSR(UIC0)); + +#if (NR_UICS > 1) + if (bits & UIC_CASCADE_MASK) { + bits = mfdcr(DCRN_UIC_MSR(UIC1)); + cas_irq = 32 - ffs(bits); + irq = 32 + cas_irq; + } else { + irq = 32 - ffs(bits); + if (irq == 32) + irq = -1; + } +#else + /* + * Walk through the interrupts from highest priority to lowest, and + * report the first pending interrupt found. + * We want PPC, not C bit numbering, so just subtract the ffs() + * result from 32. + */ + irq = 32 - ffs(bits); +#endif + if (irq == (NR_UIC_IRQS * NR_UICS)) + irq = -1; + +#ifdef UIC_DEBUG + printk("ppc405_pic_get_irq - irq %d bit 0x%x\n", irq, bits); +#endif + + return (irq); +} +#endif + +void __init +ppc4xx_extpic_init(void) +{ + unsigned int sense, irq; + int bit, word; + unsigned long ppc_cached_sense_mask[NR_MASK_WORDS]; + unsigned long ppc_cached_pol_mask[NR_MASK_WORDS]; + ppc_cached_sense_mask[0] = 0; + ppc_cached_sense_mask[1] = 0; + ppc_cached_pol_mask[0] = 0; + ppc_cached_pol_mask[1] = 0; + + for (irq = 0; irq < NR_IRQS; irq++) { + + bit = irq & 0x1f; + word = irq >> 5; + + sense = (irq < ibm4xxPIC_NumInitSenses) ? + ibm4xxPIC_InitSenses[irq] : + IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE; +#ifdef PPC4xx_PIC_DEBUG + printk("PPC4xx_picext %d word:%x bit:%x sense:%x", irq, word, + bit, sense); +#endif + ppc_cached_sense_mask[word] |= + (~sense & IRQ_SENSE_MASK) << (31 - bit); + ppc_cached_pol_mask[word] |= + ((sense & IRQ_POLARITY_MASK) >> 1) << (31 - bit); + switch (word) { + case 0: +#ifdef PPC4xx_PIC_DEBUG + printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0))); + printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0))); +#endif + /* polarity setting */ + mtdcr(DCRN_UIC_PR(UIC0), ppc_cached_pol_mask[word]); + + /* Level setting */ + mtdcr(DCRN_UIC_TR(UIC0), ppc_cached_sense_mask[word]); + + break; + case 1: +#ifdef PPC4xx_PIC_DEBUG + printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1))); + printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1))); +#endif + /* polarity setting */ + mtdcr(DCRN_UIC_PR(UIC1), ppc_cached_pol_mask[word]); + + /* Level setting */ + mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]); + + break; + } + } + +} +void __init +ppc4xx_pic_init(void) +{ + + /* + * Disable all external interrupts until they are + * explicity requested. + */ + ppc_cached_irq_mask[0] = 0; + ppc_cached_irq_mask[1] = 0; + +#if defined CONFIG_403 + mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]); + + ppc4xx_pic = &ppc403_aic; + ppc_md.get_irq = ppc403_pic_get_irq; +#else +#if (NR_UICS > 1) + ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC); /* enable cascading interrupt */ + mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[1]); + mtdcr(DCRN_UIC_CR(UIC1), 0); + +#endif + mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]); + mtdcr(DCRN_UIC_CR(UIC0), 0); + + if (ibm4xxPIC_InitSenses != NULL) + ppc4xx_extpic_init(); + + /* Clear any pending interrupts */ +#if (NR_UICS > 1) + mtdcr(DCRN_UIC_SR(UIC1), 0xffffffff); +#endif + mtdcr(DCRN_UIC_SR(UIC0), 0xffffffff); + + ppc4xx_pic = &ppc405_uic; + ppc_md.get_irq = ppc405_pic_get_irq; +#endif + } diff -urN linux-2.4.21/arch/ppc/kernel/ppc4xx_setup.c linux-2.4.22/arch/ppc/kernel/ppc4xx_setup.c --- linux-2.4.21/arch/ppc/kernel/ppc4xx_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/kernel/ppc4xx_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,431 @@ +/* + * + * Copyright (c) 1999-2000 Grant Erickson + * + * Copyright 2000-2002 MontaVista Software Inc. + * Completed implementation. + * Author: MontaVista Software, Inc. + * Frank Rowand + * Debbie Chu + * + * Module name: ppc4xx_setup.c + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * IBM PowerPC 4xx based boards. Adapted from original + * code by Gary Thomas, Cort Dougan , and Dan Malek + * . + * + * History: 11/09/2001 - armin + * rename board_setup_nvram_access to board_init. board_init is + * used for all other board specific instructions needed during + * platform_init. + * moved RTC to board.c files + * moved VT/FB to board.c files + * moved r/w4 ide to redwood.c + * + * History: 04/18/02 - Armin + * added ash to setting CETE bit in calibrate() + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Prototypes */ +static void ppc4xx_gdb_init(void); + +extern void abort(void); +extern void ppc4xx_find_bridges(void); + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_pretranslate(unsigned char scancode, char raw_mode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); + +extern int nonpci_ide_default_irq(ide_ioreg_t base); +extern void nonpci_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq); + +extern void ppc4xx_wdt_heartbeat(void); +extern int wdt_enable; +extern unsigned long wdt_period; +//extern void early_uart_init(void); + +/* Board specific functions */ +extern void board_setup_arch(void); +extern void board_io_mapping(void); +extern void board_setup_irq(void); +extern void board_init(void); + +/* Global Variables */ +unsigned char __res[sizeof (bd_t)]; + +#if defined(EMAC_NUMS) && EMAC_NUMS > 0 +u32 emac_phy_map[EMAC_NUMS]; +EXPORT_SYMBOL(emac_phy_map); +#endif + +static void __init +ppc4xx_setup_arch(void) +{ + + /* Setup PCI host bridges */ + +#ifdef CONFIG_PCI + ppc4xx_find_bridges(); +#endif + +#if defined(CONFIG_FB) + conswitchp = &dummy_con; +#endif +#if defined (CONFIG_SERIAL) && !defined (CONFIG_RAINIER) +// early_uart_init(); +#endif + board_setup_arch(); + + ppc4xx_gdb_init(); +} + +/* + * This routine pretty-prints the platform's internal CPU clock + * frequencies into the buffer for usage in /proc/cpuinfo. + */ + +static int +ppc4xx_show_percpuinfo(struct seq_file *m, int i) +{ + bd_t *bip = (bd_t *) __res; + + seq_printf(m, "clock\t\t: %ldMHz\n", (long) bip->bi_intfreq / 1000000); + + return 0; +} + +/* + * This routine pretty-prints the platform's internal bus clock + * frequencies into the buffer for usage in /proc/cpuinfo. + */ +static int +ppc4xx_show_cpuinfo(struct seq_file *m) +{ + bd_t *bip = (bd_t *) __res; + + seq_printf(m, "machine\t\t: %s\n", PPC4xx_MACHINE_NAME); + seq_printf(m, "plb bus clock\t: %ldMHz\n", + (long) bip->bi_busfreq / 1000000); +#ifdef CONFIG_PCI + seq_printf(m, "pci bus clock\t: %dMHz\n", + bip->bi_pci_busfreq / 1000000); +#endif + + return 0; +} + +/* + * Return the virtual address representing the top of physical RAM. + */ +static unsigned long __init +ppc4xx_find_end_of_memory(void) +{ + bd_t *bip = (bd_t *) __res; + + return ((unsigned long) bip->bi_memsize); +} + +static void __init +m4xx_map_io(void) +{ + io_block_mapping(PPC4xx_ONB_IO_VADDR, + PPC4xx_ONB_IO_PADDR, PPC4xx_ONB_IO_SIZE, _PAGE_IO); +#ifdef CONFIG_PCI + io_block_mapping(PPC4xx_PCI_IO_VADDR, + PPC4xx_PCI_IO_PADDR, PPC4xx_PCI_IO_SIZE, _PAGE_IO); + io_block_mapping(PPC4xx_PCI_CFG_VADDR, + PPC4xx_PCI_CFG_PADDR, PPC4xx_PCI_CFG_SIZE, _PAGE_IO); + io_block_mapping(PPC4xx_PCI_LCFG_VADDR, + PPC4xx_PCI_LCFG_PADDR, PPC4xx_PCI_LCFG_SIZE, _PAGE_IO); +#endif + board_io_mapping(); +} + +static void __init +ppc4xx_init_IRQ(void) +{ + int i; + + ppc4xx_pic_init(); + + for (i = 0; i < NR_IRQS; i++) + irq_desc[i].handler = ppc4xx_pic; + + /* give board specific code a chance to setup things */ + board_setup_irq(); + return; +} + +static void +ppc4xx_restart(char *cmd) +{ + printk("%s\n", cmd); + abort(); +} + +static void +ppc4xx_halt(void) +{ + printk("System Halted\n"); + __cli(); + while (1) ; +} + +static void __init +ppc4xx_gdb_init(void) +{ +#if !defined(CONFIG_BDI_SWITCH) + /* + * The Abatron BDI JTAG debugger does not tolerate others + * mucking with the debug registers. + */ + mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); + mtspr(SPRN_DBCR1, 0); +#endif +} + +/* + * This routine retrieves the internal processor frequency from the board + * information structure, sets up the kernel timer decrementer based on + * that value, enables the 4xx programmable interval timer (PIT) and sets + * it up for auto-reload. + */ +static void __init +ppc4xx_calibrate_decr(void) +{ + unsigned int freq; + bd_t *bip = (bd_t *) __res; + +#if defined(CONFIG_WALNUT) || defined(CONFIG_CEDER) \ + || defined(CONFIG_ASH) || defined(CONFIG_SYCAMORE) + /* Openbios sets cpu timers to CPU clk + * we want to use the external clk + * DCR CHCR1 (aka CPC0_CR1) bit CETE to 1 */ + + mtdcr(DCRN_CHCR1, mfdcr(DCRN_CHCR1) & ~CHR1_CETE); +#endif + + freq = bip->bi_tbfreq; +// tb_ticks_per_jiffy = freq / HZ; +// tb_to_us = mulhwu_scale_factor(freq, 1000000); + tb_ticks_per_jiffy = (freq + HZ/2) / HZ; + tb_to_us = mulhwu_scale_factor(tb_ticks_per_jiffy*HZ, 1000000U); + + /* Set the time base to zero. + ** At 200 Mhz, time base will rollover in ~2925 years. + */ + + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS); + mtspr(SPRN_TCR, TCR_PIE | TCR_ARE); + + /* Set the PIT reload value and just let it run. */ + mtspr(SPRN_PIT, tb_ticks_per_jiffy); +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + +/* We assume that the UART has already been initialized by the + firmware or the boot loader */ +static void +serial_putc(u8 * com_port, unsigned char c) +{ + while ((readb(com_port + (UART_LSR)) & UART_LSR_THRE) == 0) ; + writeb(c, com_port); +} + +static void +ppc4xx_progress(char *s, unsigned short hex) +{ + char c; +#ifdef SERIAL_DEBUG_IO_BASE + u8 *com_port = (u8 *) SERIAL_DEBUG_IO_BASE; + + while ((c = *s++) != '\0') { + serial_putc(com_port, c); + } + serial_putc(com_port, '\r'); + serial_putc(com_port, '\n'); +#else + printk("%s\r\n", s); +#endif +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +/* + * IDE stuff. + * should be generic for every IDE PCI chipset + */ +#if defined(CONFIG_BLK_DEV_IDEPCI) +static void +ppc4xx_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i) + hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET; + + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; +} +#endif + +TODC_ALLOC(); + +/* + * Input(s): + * r3 - Optional pointer to a board information structure. + * r4 - Optional pointer to the physical starting address of the init RAM + * disk. + * r5 - Optional pointer to the physical ending address of the init RAM + * disk. + * r6 - Optional pointer to the physical starting address of any kernel + * command-line parameters. + * r7 - Optional pointer to the physical ending address of any kernel + * command-line parameters. + */ +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* + * If we were passed in a board information, copy it into the + * residual data area. + */ + if (r3) { + memcpy((void *) __res, (void *) (r3 + KERNELBASE), + sizeof (bd_t)); + + } +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured in, and there's a valid + * starting address for it, set it up. + */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *) (r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *) (r6 + KERNELBASE)); + } +#if defined(CONFIG_PPC405_WDT) + ppc_md.heartbeat = ppc4xx_wdt_heartbeat; + +/* Look for wdt= option on command line */ + if (strstr(cmd_line, "wdt=")) { + int valid_wdt = 0; + char *p, *q; + for (q = cmd_line; (p = strstr(q, "wdt=")) != 0;) { + q = p + 4; + if (p > cmd_line && p[-1] != ' ') + continue; + wdt_period = simple_strtoul(q, &q, 0); + valid_wdt = 1; + ++q; + } + wdt_enable = valid_wdt; + } +#endif + + /* Initialize machine-dependency vectors */ + + ppc_md.setup_arch = ppc4xx_setup_arch; + ppc_md.show_percpuinfo = ppc4xx_show_percpuinfo; + ppc_md.show_cpuinfo = ppc4xx_show_cpuinfo; + ppc_md.init_IRQ = ppc4xx_init_IRQ; + + ppc_md.restart = ppc4xx_restart; + ppc_md.power_off = ppc4xx_halt; + ppc_md.halt = ppc4xx_halt; + + ppc_md.calibrate_decr = ppc4xx_calibrate_decr; + + ppc_md.find_end_of_memory = ppc4xx_find_end_of_memory; + ppc_md.setup_io_mappings = m4xx_map_io; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = ppc4xx_progress; +#endif +#ifdef CONFIG_KGDB +// ppc_md.early_serial_map = early_uart_init; +#endif +#if defined(CONFIG_VT) && defined(CONFIG_PC_KEYBOARD) +#if defined(CONFIG_REDWOOD_4) && defined(CONFIG_STB_KB) + redwood_irkb_init(); +#else + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#endif +#endif + +/* +** m8xx_setup.c, prep_setup.c use +** defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +*/ +#if defined (CONFIG_IDE) +#if defined(CONFIG_BLK_DEV_IDEPCI) + ppc_ide_md.ide_init_hwif = ppc4xx_ide_init_hwif_ports; +#elif defined (CONFIG_DMA_NONPCI) /* ON board IDE */ + ppc_ide_md.default_irq = nonpci_ide_default_irq; + ppc_ide_md.ide_init_hwif = nonpci_ide_init_hwif_ports; +#endif +#endif + board_init(); + + return; +} diff -urN linux-2.4.21/arch/ppc/kernel/ppc8xx_pic.c linux-2.4.22/arch/ppc/kernel/ppc8xx_pic.c --- linux-2.4.21/arch/ppc/kernel/ppc8xx_pic.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/ppc8xx_pic.c 2003-08-25 04:44:40.000000000 -0700 @@ -52,7 +52,7 @@ word = irq_nr >> 5; ppc_cached_irq_mask[word] |= (1 << (31-bit)); - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask[word]; } } @@ -96,7 +96,7 @@ irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26; /* - * When we read the sivec without an interrupt to process, we will + * When we read the sivec without an interrupt to process, we will * get back SIU_LEVEL7. In this case, return -1 */ if (irq == CPM_INTERRUPT) diff -urN linux-2.4.21/arch/ppc/kernel/ppc_htab.c linux-2.4.22/arch/ppc/kernel/ppc_htab.c --- linux-2.4.21/arch/ppc/kernel/ppc_htab.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/ppc_htab.c 2003-08-25 04:44:40.000000000 -0700 @@ -82,7 +82,7 @@ default: return "unknown"; } -} +} static char *pmc2_lookup(unsigned long mmcr0) { @@ -101,7 +101,7 @@ default: return "unknown"; } -} +} /* * print some useful info about the hash table. This function @@ -177,7 +177,7 @@ if (!valid) zombie_ptes++; } - + n += sprintf( buffer + n, "PTE Hash Table Information\n" "Size\t\t: %luKb\n" @@ -208,7 +208,7 @@ primary_pteg_full, htab_evicts); return_string: #endif /* CONFIG_PPC_STD_MMU */ - + n += sprintf( buffer + n, "Non-error misses: %lu\n" "Error misses\t: %lu\n", @@ -244,7 +244,7 @@ if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { asm volatile ("mtspr %0, %3 \n\t" "mtspr %1, %3 \n\t" - "mtspr %2, %3 \n\t" + "mtspr %2, %3 \n\t" :: "i" (MMCR0), "i" (PMC1), "i" (PMC2), "r" (0)); } } @@ -295,7 +295,7 @@ "i" (PMC1), "r" (0), "i"(PMC2) ); } } - + /* PMC1 values */ if ( !strncmp( buffer, "dtlb", 4) ) { @@ -310,7 +310,7 @@ :: "r" (tmp), "i" (MMCR0), "i" (MMCR0_PMC1_DTLB), "i" (PMC1), "r" (0) ); } - } + } if ( !strncmp( buffer, "ic miss", 7) ) { @@ -325,7 +325,7 @@ :: "r" (tmp), "i" (MMCR0), "i" (MMCR0_PMC1_ICACHEMISS), "i" (PMC1), "r" (0)); } - } + } /* PMC2 values */ if ( !strncmp( buffer, "load miss time", 14) ) @@ -343,7 +343,7 @@ "i" (PMC2), "r" (0) ); } } - + if ( !strncmp( buffer, "itlb", 4) ) { if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { @@ -374,21 +374,21 @@ : "i" (MMCR0), "i" (MMCR0_PMC2_DCACHEMISS), "i" (PMC2), "r" (0) ); } - } - + } + return count; - + #if 0 /* resizing htab is a bit difficult right now -- Cort */ unsigned long size; extern void reset_SDR1(void); - + /* only know how to set size right now */ if ( strncmp( buffer, "size ", 5) ) return -EINVAL; size = simple_strtoul( &buffer[5], NULL, 10 ); - + /* only allow to shrink */ if ( size >= Hash_size>>10 ) return -EINVAL; @@ -396,11 +396,11 @@ /* minimum size of htab */ if ( size < 64 ) return -EINVAL; - + /* make sure it's a multiple of 64k */ if ( size % 64 ) return -EINVAL; - + printk("Hash table resize to %luk\n", size); /* * We need to rehash all kernel entries for the new htab size. @@ -416,7 +416,7 @@ flush_tlb_all(); reset_SDR1(); -#endif +#endif return count; #else /* CONFIG_PPC_STD_MMU */ return 0; @@ -441,18 +441,18 @@ } } +#define TMPBUFLEN 512 int proc_dol2crvec(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) { int vleft, first=1, len, left, val; - #define TMPBUFLEN 256 char buf[TMPBUFLEN], *p; static const char *sizestrings[4] = { "2MB", "256KB", "512KB", "1MB" }; static const char *clockstrings[8] = { - "clock disabled", "+1 clock", "+1.5 clock", "reserved(3)", - "+2 clock", "+2.5 clock", "+3 clock", "reserved(7)" + "clock disabled", "+1 clock", "+1.5 clock", "+3.5 clock", + "+2 clock", "+2.5 clock", "+3 clock", "+4 clock" }; static const char *typestrings[4] = { "flow-through burst SRAM", "reserved SRAM", @@ -464,12 +464,12 @@ if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) return -EFAULT; - + if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) { *lenp = 0; return 0; } - + vleft = table->maxlen / sizeof(int); left = *lenp; @@ -508,24 +508,46 @@ *p++ = '\t'; val = _get_L2CR(); p += sprintf(p, "0x%08x: ", val); - p += sprintf(p, " %s", (val >> 31) & 1 ? "enabled" : + p += sprintf(p, " L2 %s", (val >> 31) & 1 ? "enabled" : "disabled"); p += sprintf(p, ", %sparity", (val>>30)&1 ? "" : "no "); - p += sprintf(p, ", %s", sizestrings[(val >> 28) & 3]); - p += sprintf(p, ", %s", clockstrings[(val >> 25) & 7]); - p += sprintf(p, ", %s", typestrings[(val >> 23) & 2]); - p += sprintf(p, "%s", (val>>22)&1 ? ", data only" : ""); - p += sprintf(p, "%s", (val>>20)&1 ? ", ZZ enabled": ""); - p += sprintf(p, ", %s", (val>>19)&1 ? "write-through" : - "copy-back"); - p += sprintf(p, "%s", (val>>18)&1 ? ", testing" : ""); - p += sprintf(p, ", %sns hold",holdstrings[(val>>16)&3]); - p += sprintf(p, "%s", (val>>15)&1 ? ", DLL slow" : ""); - p += sprintf(p, "%s", (val>>14)&1 ? ", diff clock" :""); - p += sprintf(p, "%s", (val>>13)&1 ? ", DLL bypass" :""); - + + /* 75x & 74x0 have different L2CR than 745x */ + if (!(cur_cpu_spec[0]->cpu_features & + CPU_FTR_SPEC7450)) { + p += sprintf(p, ", %s", + sizestrings[(val >> 28) & 3]); + p += sprintf(p, ", %s", + clockstrings[(val >> 25) & 7]); + p += sprintf(p, ", %s", + typestrings[(val >> 23) & 3]); + p += sprintf(p, "%s", (val>>22)&1 ? + ", data only" : ""); + p += sprintf(p, "%s", (val>>20)&1 ? + ", ZZ enabled": ""); + p += sprintf(p, ", %s", (val>>19)&1 ? + "write-through" : "copy-back"); + p += sprintf(p, "%s", (val>>18)&1 ? + ", testing" : ""); + p += sprintf(p, ", %sns hold", + holdstrings[(val>>16)&3]); + p += sprintf(p, "%s", (val>>15)&1 ? + ", DLL slow" : ""); + p += sprintf(p, "%s", (val>>14)&1 ? + ", diff clock" :""); + p += sprintf(p, "%s", (val>>13)&1 ? + ", DLL bypass" :""); + } else { /* 745x */ + p += sprintf(p, ", %sinstn only", (val>>20)&1 ? + "" : "no "); + p += sprintf(p, ", %sdata only", (val>>16)&1 ? + "" : "no "); + p += sprintf(p, ", %s replacement", + (val>>12)&1 ? "secondary" : "default"); + } + p += sprintf(p,"\n"); - + len = strlen(buf); if (len > left) len = left; @@ -559,3 +581,95 @@ filp->f_pos += *lenp; return 0; } + +int proc_dol3crvec(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int vleft, first=1, len, left, val; + char buf[TMPBUFLEN], *p; + static const char *clockstrings[8] = { + "+6 clock", "reserved(1)", "+2 clock", "+2.5 clock", + "+3 clock", "+3.5 clock", "+4 clock", "+5 clock" + }; + static const char *clocksampstrings[4] = { + "2 clock", "3 clock", "4 clock", "5 clock" + }; + static const char *pclocksampstrings[8] = { + "0 P-clock", "1 P-clock", "2 P-clock", "3 P-clock", + "4 P-clock", "5 P-clock", "reserved(6)", "reserved(7)" + }; + static const char *typestrings[4] = { + "MSUG2 DDR SRAM", + "Pipelined synchronous late-write SRAM", + "Reserved", "PB2 SRAM" + }; + + if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)) + return -EFAULT; + if (write) + return -EFAULT; + + if (filp->f_pos && !write) { + *lenp = 0; + return 0; + } + + vleft = table->maxlen / sizeof(int); + left = *lenp; + + for (; left; first=0) { + p = buf; + if (!first) + *p++ = '\t'; + val = _get_L3CR(); + p += sprintf(p, "0x%08x: ", val); + p += sprintf(p, " L3 %s", (val >> 31) & 1 ? "enabled" : + "disabled"); + p += sprintf(p, ", %sdata parity", (val>>30)&1 ? "" : + "no "); + p += sprintf(p, ", %saddr parity", (val>>29)&1 ? "" : + "no "); + p += sprintf(p, ", %s", (val>>28)&1 ? "2MB" : "1MB"); + p += sprintf(p, ", clocks %s", (val>>27)&1 ? "enabled" : + "disabled"); + p += sprintf(p, ", %s", clockstrings[(val >> 23) & 7]); + p += sprintf(p, ", %sinstn only", (val>>22)&1 ? "" : + "no "); + p += sprintf(p, ", %ssample point override", + (val>>18)&1 ? "" : "no "); + p += sprintf(p, ", %s sample point", + clocksampstrings[(val>>16)&3]); + p += sprintf(p, ", %s sample point", + pclocksampstrings[(val>>13)&7]); + p += sprintf(p, ", %s replacement", (val>>12)&1 ? + "secondary" : "default"); + p += sprintf(p, ", %s", typestrings[(val >> 8) & 3]); + p += sprintf(p, ", %sclock cntl", (val>>7)&1 ? "" : + "no "); + p += sprintf(p, ", %sdata only", (val>>6)&1 ? "" : + "no "); + p += sprintf(p, ", private mem %s", (val>>2)&1 ? + "enabled" : "disabled"); + p += sprintf(p, ", %sprivate mem", val&1 ? "2MB " : + "1MB "); + p += sprintf(p,"\n"); + + len = strlen(buf); + if (len > left) + len = left; + if(copy_to_user(buffer, buf, len)) + return -EFAULT; + left -= len; + buffer += len; + break; + } + + if (!write && !first && left) { + if(put_user('\n', (char *) buffer)) + return -EFAULT; + left--, buffer++; + } + *lenp -= left; + filp->f_pos += *lenp; + return 0; +} diff -urN linux-2.4.21/arch/ppc/kernel/ppc_ksyms.c linux-2.4.22/arch/ppc/kernel/ppc_ksyms.c --- linux-2.4.21/arch/ppc/kernel/ppc_ksyms.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/ppc_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -353,6 +353,10 @@ EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(handle_mm_fault); /* For MOL */ +#ifdef CONFIG_SMP +extern int *hash_table_lock; +EXPORT_SYMBOL_NOVERS(hash_table_lock); /* For MOL */ +#endif EXPORT_SYMBOL_NOVERS(disarm_decr); #ifdef CONFIG_PPC_STD_MMU EXPORT_SYMBOL(flush_hash_page); /* For MOL */ diff -urN linux-2.4.21/arch/ppc/kernel/pplus_common.c linux-2.4.22/arch/ppc/kernel/pplus_common.c --- linux-2.4.21/arch/ppc/kernel/pplus_common.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/kernel/pplus_common.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,317 @@ +/* + * arch/ppc/kernel/pplus_common.c + * + * Common Motorola PowerPlus Platform--really Falcon/Raven or HAWK. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * The Falcon/Raven and HAWK has 4 sets of registers: + * 1) PPC Registers which define the mappings from PPC bus to PCI bus, + * etc. + * 2) PCI Registers which define the mappings from PCI bus to PPC bus and the + * MPIC base address. + * 3) MPIC registers. + * 4) System Memory Controller (SMC) registers. + */ + +/* + * Initialize the Motorola MCG Raven or HAWK host bridge. + * + * This means setting up the PPC bus to PCI memory and I/O space mappings, + * setting the PCI memory space address of the MPIC (mapped straight + * through), and ioremap'ing the mpic registers. + * This routine will set the PCI_CONFIG_ADDR or PCI_CONFIG_DATA + * addresses based on the PCI I/O address that is passed in. + * 'OpenPIC_Addr' will be set correctly by this routine. + */ +int __init +pplus_init(struct pci_controller *hose, + uint ppc_reg_base, + ulong processor_pci_mem_start, + ulong processor_pci_mem_end, + ulong processor_pci_io_start, + ulong processor_pci_io_end, + ulong processor_mpic_base) +{ + uint addr, offset; + + /* + * Some sanity checks... + */ + if (((processor_pci_mem_start&0xffff0000) != processor_pci_mem_start) || + ((processor_pci_io_start &0xffff0000) != processor_pci_io_start)) { + printk("pplus_init: %s\n", + "PPC to PCI mappings must start on 64 KB boundaries"); + return -1; + } + + if (((processor_pci_mem_end &0x0000ffff) != 0x0000ffff) || + ((processor_pci_io_end &0x0000ffff) != 0x0000ffff)) { + printk("pplus_init: PPC to PCI mappings %s\n", + "must end just before a 64 KB boundaries"); + return -1; + } + + if (((processor_pci_mem_end - processor_pci_mem_start) != + (hose->mem_space.end - hose->mem_space.start)) || + ((processor_pci_io_end - processor_pci_io_start) != + (hose->io_space.end - hose->io_space.start))) { + printk("pplus_init: %s\n", + "PPC and PCI memory or I/O space sizes don't match"); + return -1; + } + + if ((processor_mpic_base & 0xfffc0000) != processor_mpic_base) { + printk("pplus_init: %s\n", + "MPIC address must start on 256 MB boundary"); + return -1; + } + + if ((pci_dram_offset & 0xffff0000) != pci_dram_offset) { + printk("pplus_init: %s\n", + "pci_dram_offset must be multiple of 64 KB"); + return -1; + } + + /* + * Disable previous PPC->PCI mappings. + */ + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF0_OFF), 0x00000000); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF1_OFF), 0x00000000); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF2_OFF), 0x00000000); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF3_OFF), 0x00000000); + + /* + * Program the XSADD/XSOFF registers to set up the PCI Mem & I/O + * space mappings. These are the mappings going from the processor to + * the PCI bus. + * + * Note: Don't need to 'AND' start/end addresses with 0xffff0000 + * because sanity check above ensures that they are properly + * aligned. + */ + + /* Set up PPC->PCI Mem mapping */ + addr = processor_pci_mem_start | (processor_pci_mem_end >> 16); + offset = (hose->mem_space.start - processor_pci_mem_start) | 0xd2; + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD0_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF0_OFF), offset); + + /* Set up PPC->MPIC mapping on the bridge */ + addr = processor_mpic_base | + (((processor_mpic_base + PPLUS_MPIC_SIZE) >> 16) - 1); + offset = 0xc2; /* No write posting for this PCI Mem space */ + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD1_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF1_OFF), offset); + + /* Set up PPC->PCI I/O mapping -- Contiguous I/O space */ + addr = processor_pci_io_start | (processor_pci_io_end >> 16); + offset = (hose->io_space.start - processor_pci_io_start) | 0xc0; + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD3_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF3_OFF), offset); + + hose->io_base_virt = (void *)ioremap(processor_pci_io_start, + (processor_pci_io_end - processor_pci_io_start + 1)); + + /* + * Set up the indirect method of accessing PCI config space. + * The PCI config addr/data pair based on start addr of PCI I/O space. + */ + setup_indirect_pci(hose, + processor_pci_io_start + PPLUS_PCI_CONFIG_ADDR_OFF, + processor_pci_io_start + PPLUS_PCI_CONFIG_DATA_OFF); + + /* + * Disable previous PCI->PPC mappings. + */ + + /* XXXX Put in mappings from PCI bus to processor bus XXXX */ + + /* + * Disable MPIC response to PCI I/O space (BAR 0). + * Make MPIC respond to PCI Mem space at specified address. + * (BAR 1). + */ + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_0, + 0x00000000 | 0x1); + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_1, + processor_mpic_base | 0x0); + + /* Map MPIC into vitual memory */ + OpenPIC_Addr = ioremap(processor_mpic_base, PPLUS_MPIC_SIZE); + + return 0; +} + +/* + * Find the amount of RAM present. + * This assumes that PPCBug has initialized the memory controller (SMC) + * on the Falcon/HAWK correctly (i.e., it does no sanity checking). + * It also assumes that the memory base registers are set to configure the + * memory as contigous starting with "RAM A BASE", "RAM B BASE", etc. + * however, RAM base registers can be skipped (e.g. A, B, C are set, + * D is skipped but E is set is okay). + */ +#define MB (1024*1024) + +static uint reg_offset_table[] __initdata = { + PPLUS_SMC_RAM_A_SIZE_REG_OFF, + PPLUS_SMC_RAM_B_SIZE_REG_OFF, + PPLUS_SMC_RAM_C_SIZE_REG_OFF, + PPLUS_SMC_RAM_D_SIZE_REG_OFF, + PPLUS_SMC_RAM_E_SIZE_REG_OFF, + PPLUS_SMC_RAM_F_SIZE_REG_OFF, + PPLUS_SMC_RAM_G_SIZE_REG_OFF, + PPLUS_SMC_RAM_H_SIZE_REG_OFF +}; + +static uint falcon_size_table[] __initdata = { + 0 * MB, /* 0 ==> 0 MB */ + 16 * MB, /* 1 ==> 16 MB */ + 32 * MB, /* 2 ==> 32 MB */ + 64 * MB, /* 3 ==> 64 MB */ + 128 * MB, /* 4 ==> 128 MB */ + 256 * MB, /* 5 ==> 256 MB */ + 1024 * MB, /* 6 ==> 1024 MB (1 GB) */ +}; + +static uint hawk_size_table[] __initdata = { + 0 * MB, /* 0 ==> 0 MB */ + 32 * MB, /* 1 ==> 32 MB */ + 64 * MB, /* 2 ==> 64 MB */ + 64 * MB, /* 3 ==> 64 MB */ + 128 * MB, /* 4 ==> 128 MB */ + 128 * MB, /* 5 ==> 128 MB */ + 128 * MB, /* 6 ==> 128 MB */ + 256 * MB, /* 7 ==> 256 MB */ + 256 * MB, /* 8 ==> 256 MB */ + 512 * MB, /* 9 ==> 512 MB */ +}; + +/* + * *** WARNING: You MUST have a BAT set up to map in the SMC regs *** + * + * Read the memory controller's registers to determine the amount of system + * memory. Assumes that the memory controller registers are already mapped + * into virtual memory--too early to use ioremap(). + */ +unsigned long __init +pplus_get_mem_size(uint smc_base) +{ + unsigned long total; + int i, size_table_entries, reg_limit; + uint vend_dev_id; + uint *size_table; + u_char val; + + + vend_dev_id = in_be32((uint *)smc_base + PCI_VENDOR_ID); + + if (((vend_dev_id & 0xffff0000) >> 16) != PCI_VENDOR_ID_MOTOROLA) { + printk("pplus_get_mem_size: %s (0x%x)\n", + "Not a Motorola Memory Controller", vend_dev_id); + return 0; + } + + vend_dev_id &= 0x0000ffff; + + if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_FALCON) { + size_table = falcon_size_table; + size_table_entries = sizeof(falcon_size_table) / + sizeof(falcon_size_table[0]); + + reg_limit = PPLUS_FALCON_SMC_REG_COUNT; + } + else if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_HAWK) { + size_table = hawk_size_table; + size_table_entries = sizeof(hawk_size_table) / + sizeof(hawk_size_table[0]); + reg_limit = PPLUS_HAWK_SMC_REG_COUNT; + } + else { + printk("pplus_get_mem_size: %s (0x%x)\n", + "Not a Falcon or HAWK", vend_dev_id); + return 0; + } + + total = 0; + + /* Check every reg because PPCBug may skip some */ + for (i=0; i>8, PREP_NVRAM_AS1); return inb(PREP_NVRAM_DATA); } - + void __prep prep_nvram_write_val(int addr, unsigned char val) { @@ -33,7 +33,7 @@ outb(addr>>8, PREP_NVRAM_AS1); outb(val, PREP_NVRAM_DATA); } - + void __init init_prep_nvram(void) { unsigned char *nvp; @@ -51,7 +51,7 @@ *nvp = ppc_md.nvram_read_val(i); nvp++; } - + /* * The PReP NvRAM may be any size so read in the header to * determine how much we must read in order to get the complete diff -urN linux-2.4.21/arch/ppc/kernel/process.c linux-2.4.22/arch/ppc/kernel/process.c --- linux-2.4.21/arch/ppc/kernel/process.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * Updated and modified by Cort Dougan (cort@cs.nmt.edu) and * Paul Mackerras (paulus@cs.anu.edu.au) * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * This program is free software; you can redistribute it and/or @@ -80,7 +80,7 @@ unsigned long tsk_top = task_top(tsk); int ret = 0; -#if 0 +#if 0 /* check thread magic */ if ( tsk->thread.magic != THREAD_MAGIC ) { @@ -91,7 +91,7 @@ if ( !tsk ) printk("check_stack(): tsk bad tsk %p\n",tsk); - + /* check if stored ksp is bad */ if ( (tsk->thread.ksp > stack_top) || (tsk->thread.ksp < tsk_top) ) { @@ -101,7 +101,7 @@ tsk_top, tsk->thread.ksp, stack_top); ret |= 2; } - + /* check if stack ptr RIGHT NOW is bad */ if ( (tsk == current) && ((_get_SP() > stack_top ) || (_get_SP() < tsk_top)) ) { @@ -112,7 +112,7 @@ ret |= 4; } -#if 0 +#if 0 /* check amount of free stack */ for ( i = (unsigned long *)task_top(tsk) ; i < kernel_stack_top(tsk) ; i++ ) { @@ -147,7 +147,7 @@ return 1; } -void +void enable_kernel_altivec(void) { #ifdef CONFIG_SMP @@ -189,7 +189,7 @@ { struct thread_struct *new_thread, *old_thread; unsigned long s; - + __save_flags(s); __cli(); #if CHECK_STACK @@ -201,7 +201,7 @@ /* avoid complexity of lazy save/restore of fpu * by just saving it every time we switch out if * this task used the fpu during the last quantum. - * + * * If it tries to use the fpu again, it'll trap and * reload its fp regs. So we don't have to do a restore * every switch, just a save. @@ -209,7 +209,7 @@ */ if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) ) giveup_fpu(prev); -#ifdef CONFIG_ALTIVEC +#ifdef CONFIG_ALTIVEC /* * If the previous thread used altivec in the last quantum * (thus changing altivec regs) then save them. @@ -223,7 +223,7 @@ */ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))) giveup_altivec(prev); -#endif /* CONFIG_ALTIVEC */ +#endif /* CONFIG_ALTIVEC */ #endif /* CONFIG_SMP */ current_set[smp_processor_id()] = new; @@ -250,27 +250,40 @@ regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, regs->msr&MSR_IR ? 1 : 0, regs->msr&MSR_DR ? 1 : 0); +#ifdef CONFIG_4xx + /* + * TRAP 0x800 is the hijacked FPU unavailable exception vector + * on 40x used to implement the heavyweight data access + * functionality. It is an emulated value (like all trap + * vectors) on 440. + */ + if (regs->trap == 0x300 || regs->trap == 0x600 || regs->trap == 0x800) + printk("DEAR: %08lX, ESR: %08lX\n", regs->dar, regs->dsisr); +#else if (regs->trap == 0x300 || regs->trap == 0x600) printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr); +#endif printk("TASK = %p[%d] '%s' ", current, current->pid, current->comm); printk("Last syscall: %ld ", current->thread.last_syscall); printk("\nlast math %p last altivec %p", last_task_used_math, last_task_used_altivec); -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) && defined(DCRN_PLB0_BEAR) printk("\nPLB0: bear= 0x%8.8x acr= 0x%8.8x besr= 0x%8.8x\n", - mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_PLB0_ACR), + mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESR)); +#endif +#if defined(CONFIG_4xx) && defined(DCRN_POB0_BEAR) printk("PLB0 to OPB: bear= 0x%8.8x besr0= 0x%8.8x besr1= 0x%8.8x\n", - mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_POB0_BESR0), + mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1)); #endif - + #ifdef CONFIG_SMP printk(" CPU: %d", current->processor); #endif /* CONFIG_SMP */ - + printk("\n"); for (i = 0; i < 32; i++) { @@ -475,7 +488,7 @@ #ifdef CONFIG_ALTIVEC if (regs->msr & MSR_VEC) giveup_altivec(current); -#endif /* CONFIG_ALTIVEC */ +#endif /* CONFIG_ALTIVEC */ error = do_execve(filename, (char **) a1, (char **) a2, regs); if (error == 0) current->ptrace &= ~PT_DTRACE; @@ -573,7 +586,7 @@ return; } -#if 0 +#if 0 if ( have_of ) { prom_print(s); @@ -600,7 +613,7 @@ y = 0; } } else { - vidmem [ ( x + cols * y ) * 2 ] = c; + vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { diff -urN linux-2.4.21/arch/ppc/kernel/prom.c linux-2.4.22/arch/ppc/kernel/prom.c --- linux-2.4.21/arch/ppc/kernel/prom.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -1000,8 +1000,8 @@ { unsigned long mask; int i; - - /* Check this one */ + + /* Check this one */ mask = bus_space_to_resource_flags(range->space); for (i=0; iresource[i].flags & mask) == mask && @@ -1049,7 +1049,7 @@ parent = &ioport_resource; else goto fail; - + /* Find a PCI parent if any */ nd = node; pcidev = NULL; @@ -1104,7 +1104,7 @@ parent = &ioport_resource; else return -EINVAL; - + /* Find a PCI parent if any */ nd = node; pcidev = NULL; diff -urN linux-2.4.21/arch/ppc/kernel/ptrace.c linux-2.4.22/arch/ppc/kernel/ptrace.c --- linux-2.4.21/arch/ppc/kernel/ptrace.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/ptrace.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,7 +33,11 @@ /* * Set of msr bits that gdb can change on behalf of a process. */ +#if defined(CONFIG_4xx) +#define MSR_DEBUGCHANGE (0) +#else #define MSR_DEBUGCHANGE (MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1) +#endif /* * does not yet catch signals sent when the child dies. @@ -108,12 +112,12 @@ /* copy AltiVec registers VR[0] .. VR[31] */ for (i = 0; i < 32; i++) - for (j = 0; j < 4; j++, data++) + for (j = 0; j < 4; j++, data++) if (__get_user(task->thread.vr[i].u[j], data)) return -EFAULT; /* copy VSCR */ - for (i = 0; i < 4; i++, data++) + for (i = 0; i < 4; i++, data++) if (__get_user(task->thread.vscr.u[i], data)) return -EFAULT; @@ -129,18 +133,27 @@ set_single_step(struct task_struct *task) { struct pt_regs *regs = task->thread.regs; - +#if defined(CONFIG_4xx) + regs->msr |= MSR_DE; + task->thread.dbcr0 |= (DBCR0_IDM | DBCR0_IC); +#else if (regs != NULL) regs->msr |= MSR_SE; +#endif + } static inline void clear_single_step(struct task_struct *task) { struct pt_regs *regs = task->thread.regs; - +#if defined(CONFIG_4xx) + regs->msr &= ~MSR_DE; + task->thread.dbcr0 &= ~DBCR0_IC; +#else if (regs != NULL) regs->msr &= ~MSR_SE; +#endif } /* @@ -193,7 +206,7 @@ switch (request) { /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned long tmp; int copied; @@ -275,14 +288,20 @@ child->exit_code = data; /* make sure the single step bit is not set. */ clear_single_step(child); +#ifdef CONFIG_4xx + /* ...but traps may be set, so catch those.... + */ + child->thread.regs->msr |= MSR_DE; + child->thread.dbcr0 |= (DBCR0_IDM | DBCR0_TDE); +#endif wake_up_process(child); ret = 0; break; } /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to * exit. */ case PTRACE_KILL: { diff -urN linux-2.4.21/arch/ppc/kernel/setup.c linux-2.4.22/arch/ppc/kernel/setup.c --- linux-2.4.21/arch/ppc/kernel/setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -54,7 +54,7 @@ unsigned long sysmap_size; /* Used with the BI_MEMSIZE bootinfo parameter to store the memory - size value reported by the boot loader. */ + size value reported by the boot loader. */ unsigned long boot_mem_size; unsigned long ISA_DMA_THRESHOLD; @@ -89,7 +89,7 @@ int icache_bsize; int ucache_bsize; -#ifdef CONFIG_VGA_CONSOLE +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB) struct screen_info screen_info = { 0, 25, /* orig-x, orig-y */ 0, /* unused */ @@ -101,18 +101,18 @@ 1, /* orig-video-isVGA */ 16 /* orig-video-points */ }; -#endif /* CONFIG_VGA_CONSOLE */ +#endif /* CONFIG_VGA_CONSOLE || CONFIG_FB */ void machine_restart(char *cmd) { ppc_md.restart(cmd); } - + void machine_power_off(void) { ppc_md.power_off(); } - + void machine_halt(void) { ppc_md.halt(); @@ -207,7 +207,7 @@ break; } - seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", + seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", maj, min, PVR_VER(pvr), PVR_REV(pvr)); seq_printf(m, "bogomips\t: %lu.%02lu\n", @@ -304,7 +304,7 @@ { char *model; struct device_node *root; - + /* ask the OF info if we're a chrp or pmac */ root = find_path_device("/"); if (root != 0) { @@ -333,7 +333,7 @@ btext_clearscreen(); btext_welcome(); } -#endif +#endif parse_bootinfo(find_bootinfo()); @@ -370,7 +370,7 @@ * bootargs property of the /chosen node. * If an initial ramdisk is present, r3 and r4 * are used for initrd_start and initrd_size, - * otherwise they contain 0xdeadbeef. + * otherwise they contain 0xdeadbeef. */ if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) { cmd_line[0] = 0; @@ -393,7 +393,7 @@ } else { struct device_node *chosen; char *p; - + #ifdef CONFIG_BLK_DEV_INITRD if (r3 && r4 && r4 != 0xdeadbeef) { if (r3 < KERNELBASE) @@ -454,7 +454,7 @@ ulong *data = rec->data; switch (rec->tag) { case BI_CMD_LINE: - memcpy(cmd_line, (void *)data, rec->size - + memcpy(cmd_line, (void *)data, rec->size - sizeof(struct bi_record)); break; case BI_SYSMAP: @@ -531,7 +531,7 @@ { /* clear the progress line */ if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); - + if (ppc_md.init != NULL) { ppc_md.init(); } @@ -596,7 +596,7 @@ init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; init_mm.brk = (unsigned long) klimit; - + /* Save unparsed command line copy for /proc/cmdline */ strcpy(saved_command_line, cmd_line); *cmdline_p = cmd_line; diff -urN linux-2.4.21/arch/ppc/kernel/signal.c linux-2.4.22/arch/ppc/kernel/signal.c --- linux-2.4.21/arch/ppc/kernel/signal.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/ppc/kernel/signal.c * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Derived from "arch/i386/kernel/signal.c" @@ -40,7 +40,7 @@ #define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs)) -/* +/* * These are the flags in the MSR that the user is allowed to change * by modifying the saved value of the MSR on the stack. SE and BE * should not be in this list since gdb may want to change these. I.e, @@ -117,7 +117,7 @@ * do_signal() has set R3 to the signal number (the * first argument of the signal handler), so don't * overwrite that with EINTR ! - * In the other cases, do_signal() doesn't touch + * In the other cases, do_signal() doesn't touch * R3, so it's still set to -EINTR (see above). */ return regs->gpr[3]; @@ -163,7 +163,7 @@ return do_sigaltstack(uss, uoss, regs->gpr[1]); } -int +int sys_sigaction(int sig, const struct old_sigaction *act, struct old_sigaction *oact) { @@ -261,8 +261,8 @@ rt_sf++; /* Look at next rt_sigframe */ if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) { /* Last stacked signal - restore registers - - * sigctx is initialized to point to the - * preamble frame (where registers are stored) + * sigctx is initialized to point to the + * preamble frame (where registers are stored) * see handle_signal() */ sr = (struct sigregs *) sigctx.regs; @@ -322,7 +322,7 @@ || __copy_to_user(&frame->fp_regs, current->thread.fpr, ELF_NFPREG * sizeof(double)) /* Set up to return from user space. - It calls the sc exception at offset 0x9999 + It calls the sc exception at offset 0x9999 for sys_rt_sigreturn(). */ || __put_user(0x38006666UL, &frame->tramp[0]) /* li r0,0x6666 */ @@ -422,7 +422,7 @@ badframe: do_exit(SIGSEGV); -} +} /* * Set up a signal frame. @@ -500,7 +500,7 @@ || __put_user(0, &rt_sf->uc.uc_flags) || __put_user(0, &rt_sf->uc.uc_link) || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) - || __put_user(sas_ss_flags(regs->gpr[1]), + || __put_user(sas_ss_flags(regs->gpr[1]), &rt_sf->uc.uc_stack.ss_flags) || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)) @@ -514,7 +514,7 @@ sc = (struct sigcontext_struct *) *newspp; if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) goto badframe; - + if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler) || __put_user(oldset->sig[0], &sc->oldmask) #if _NSIG_WORDS > 1 diff -urN linux-2.4.21/arch/ppc/kernel/smp.c linux-2.4.22/arch/ppc/kernel/smp.c --- linux-2.4.21/arch/ppc/kernel/smp.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -67,7 +67,7 @@ extern void __save_cpu_setup(void); /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. - * + * * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up * in /proc/interrupts will be wrong!!! --Troy */ #define PPC_MSG_CALL_FUNCTION 0 @@ -75,7 +75,7 @@ #define PPC_MSG_INVALIDATE_TLB 2 #define PPC_MSG_XMON_BREAK 3 -static inline void +static inline void smp_message_pass(int target, int msg, unsigned long data, int wait) { if (smp_ops){ @@ -84,7 +84,7 @@ } } -/* +/* * Common functions */ void smp_local_timer_interrupt(struct pt_regs * regs) @@ -100,12 +100,12 @@ void smp_message_recv(int msg, struct pt_regs *regs) { atomic_inc(&ipi_recv); - + switch( msg ) { case PPC_MSG_CALL_FUNCTION: smp_call_function_interrupt(); break; - case PPC_MSG_RESCHEDULE: + case PPC_MSG_RESCHEDULE: current->need_resched = 1; break; case PPC_MSG_INVALIDATE_TLB: @@ -332,7 +332,7 @@ /* Backup CPU 0 state */ __save_cpu_setup(); - + /* * only check for cpus we know exist. We keep the callin map * with cpus at the bottom -- Cort @@ -342,7 +342,7 @@ for (i = 1; i < cpu_nr; i++) { int c; struct pt_regs regs; - + /* create a process for the processor */ /* only regs.msr is actually used, and 0 is OK for it */ memset(®s, 0, sizeof(struct pt_regs)); @@ -368,7 +368,7 @@ /* wake up cpus */ smp_ops->kick_cpu(i); - + /* * wait to see if the cpu made a callin (is actually up). * use this value that I found through experimentation. @@ -376,7 +376,7 @@ */ for ( c = 10000; c && !cpu_callin_map[i] ; c-- ) udelay(100); - + if ( cpu_callin_map[i] ) { char buf[32]; @@ -394,7 +394,7 @@ /* Setup CPU 0 last (important) */ smp_ops->setup_cpu(0); - + if (smp_num_cpus < 2) smp_tb_synchronized = 1; } @@ -497,7 +497,7 @@ */ if (!smp_tb_synchronized && smp_num_cpus == 2) { unsigned long flags; - __save_and_cli(flags); + __save_and_cli(flags); smp_software_tb_sync(0); __restore_flags(flags); } @@ -506,14 +506,14 @@ void __init smp_callin(void) { int cpu = current->processor; - + smp_store_cpu_info(cpu); smp_ops->setup_cpu(cpu); set_dec(tb_ticks_per_jiffy); cpu_online_map |= 1UL << cpu; mb(); cpu_callin_map[cpu] = 1; - + while(!smp_commenced) barrier(); diff -urN linux-2.4.21/arch/ppc/kernel/softemu8xx.c linux-2.4.22/arch/ppc/kernel/softemu8xx.c --- linux-2.4.21/arch/ppc/kernel/softemu8xx.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/softemu8xx.c 2003-08-25 04:44:40.000000000 -0700 @@ -82,7 +82,7 @@ if (copy_from_user(ip, ea, sizeof(double))) retval = -EFAULT; break; - + case LFDU: if (copy_from_user(ip, ea, sizeof(double))) retval = -EFAULT; @@ -137,7 +137,7 @@ printk("Kernel VA for NIP 0x%p ", __va(pa)); print_8xx_pte(current->mm, (unsigned long)__va(pa)); } - + } if (retval == 0) diff -urN linux-2.4.21/arch/ppc/kernel/syscalls.c linux-2.4.22/arch/ppc/kernel/syscalls.c --- linux-2.4.21/arch/ppc/kernel/syscalls.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/syscalls.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/arch/ppc/kernel/sys_ppc.c * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Derived from "arch/i386/kernel/sys_i386.c" @@ -136,7 +136,7 @@ break; } break; - case SHMDT: + case SHMDT: ret = sys_shmdt ((char *)ptr); break; case SHMGET: @@ -180,7 +180,7 @@ if (!(file = fget(fd))) goto out; } - + down_write(¤t->mm->mmap_sem); ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); @@ -263,7 +263,7 @@ return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - + down_read(&uts_sem); error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error -= __put_user(0,name->sysname+__OLD_UTS_LEN); diff -urN linux-2.4.21/arch/ppc/kernel/temp.c linux-2.4.22/arch/ppc/kernel/temp.c --- linux-2.4.21/arch/ppc/kernel/temp.c 2001-08-28 06:58:33.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/temp.c 2003-08-25 04:44:40.000000000 -0700 @@ -6,7 +6,7 @@ * TODO: * dynamic power management to limit peak CPU temp (using ICTC) * calibration??? - * + * * Silly, crazy ideas: use cpu load (from scheduler) and ICTC to extend battery * life in portables, and add a 'performance/watt' metric somewhere in /proc */ @@ -111,7 +111,7 @@ #endif #ifndef CONFIG_TAU_INT /* tau_timeout will do this if not using interrupts */ - set_thresholds(cpu); + set_thresholds(cpu); #endif } @@ -128,7 +128,7 @@ hardirq_enter(cpu); tau[cpu].interrupts++; - + TAUupdate(cpu); hardirq_exit(cpu); @@ -142,14 +142,14 @@ unsigned long flags; int size; int shrink; - + /* disabling interrupts *should* be okay */ save_flags(flags); cli(); #ifndef CONFIG_TAU_INT TAUupdate(cpu); #endif - + size = tau[cpu].high - tau[cpu].low; if (size > min_window && ! tau[cpu].grew) { /* do an exponential shrink of half the amount currently over size */ @@ -168,19 +168,19 @@ } tau[cpu].grew = 0; - + set_thresholds(cpu); /* * Do the enable every time, since otherwise a bunch of (relatively) * complex sleep code needs to be added. One mtspr every time * tau_timeout is called is probably not a big deal. - * + * * Enable thermal sensor and set up sample interval timer * need 20 us to do the compare.. until a nice 'cpu_speed' function * call is implemented, just assume a 500 mhz clock. It doesn't really - * matter if we take too long for a compare since it's all interrupt - * driven anyway. + * matter if we take too long for a compare since it's all interrupt + * driven anyway. * * use a extra long time.. (60 us @ 500 mhz) */ @@ -202,7 +202,7 @@ /* * setup the TAU - * + * * Set things up to use THRM1 as a temperature lower bound, and THRM2 as an upper bound. * Start off at zero */ @@ -212,7 +212,7 @@ void __init TAU_init_smp(void * info) { unsigned long cpu = smp_processor_id(); - + /* set these to a reasonable value and let the timer shrink the * window */ tau[cpu].low = 5; @@ -238,19 +238,19 @@ tau_timer.function = tau_timeout_smp; tau_timer.expires = jiffies + shrink_timer; add_timer(&tau_timer); - + #ifdef CONFIG_SMP smp_call_function(TAU_init_smp, NULL, 1, 0); #endif TAU_init_smp(NULL); - + printk("Thermal assist unit "); #ifdef CONFIG_TAU_INT printk("using interrupts, "); #else printk("using timers, "); #endif - printk("shrink_timer: %d jiffies\n", shrink_timer); + printk("shrink_timer: %d jiffies\n", shrink_timer); tau_initialized = 1; return 0; diff -urN linux-2.4.21/arch/ppc/kernel/time.c linux-2.4.22/arch/ppc/kernel/time.c --- linux-2.4.21/arch/ppc/kernel/time.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -149,12 +149,12 @@ do_IRQ(regs); hardirq_enter(cpu); - + while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) { jiffy_stamp += tb_ticks_per_jiffy; if (!user_mode(regs)) ppc_do_profile(instruction_pointer(regs)); - if (unlikely(!heartbeat_count(cpu)--) + if (unlikely(!heartbeat_count(cpu)--) && heartbeat_reset(cpu)) { ppc_md.heartbeat(); heartbeat_count(cpu) = heartbeat_reset(cpu); @@ -262,7 +262,7 @@ * harmful to relatively short timers. */ - /* This works perfectly on SMP only if the tb are in sync but + /* This works perfectly on SMP only if the tb are in sync but * guarantees an error < 1 jiffy even if they are off by eons, * still reasonable when gettimeofday resolution is 1 jiffy. */ @@ -271,13 +271,13 @@ new_sec = tv->tv_sec; new_usec = tv->tv_usec - mulhwu(tb_to_us, tb_delta); while (new_usec <0) { - new_sec--; + new_sec--; new_usec += 1000000; } xtime.tv_usec = new_usec; xtime.tv_sec = new_sec; - /* In case of a large backwards jump in time with NTP, we want the + /* In case of a large backwards jump in time with NTP, we want the * clock to be updated as soon as the PLL is again in lock. */ last_rtc_update = new_sec - 658; @@ -308,7 +308,7 @@ ppc_md.calibrate_decr(); } - /* Now that the decrementer is calibrated, it can be used in case the + /* Now that the decrementer is calibrated, it can be used in case the * clock is stuck, but the fact that we have to handle the 601 * makes things more complex. Repeatedly read the RTC until the * next second boundary to try to achieve some precision. If there @@ -320,7 +320,7 @@ sec = ppc_md.get_rtc_time(); elapsed = 0; do { - old_stamp = stamp; + old_stamp = stamp; old_sec = sec; stamp = get_native_tbl(); if (__USE_RTC() && stamp < old_stamp) diff -urN linux-2.4.21/arch/ppc/kernel/todc_time.c linux-2.4.22/arch/ppc/kernel/todc_time.c --- linux-2.4.21/arch/ppc/kernel/todc_time.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/todc_time.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/kernel/todc_time.c - * + * * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 * Real Time Clocks/Timekeepers. * @@ -85,7 +85,7 @@ { return readb(todc_info->nvram_data + addr); } - + void todc_direct_write_val(int addr, unsigned char val) { @@ -101,7 +101,7 @@ outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); return inb(todc_info->nvram_data); } - + void todc_m48txx_write_val(int addr, unsigned char val) { @@ -118,7 +118,7 @@ outb(addr, todc_info->nvram_as0); return inb(todc_info->nvram_data); } - + void todc_mc146818_write_val(int addr, unsigned char val) { @@ -395,7 +395,7 @@ todc_write_val(todc_info->month, tm.tm_mon); todc_write_val(todc_info->day_of_month, tm.tm_mday); todc_write_val(todc_info->year, tm.tm_year); - + todc_write_val(todc_info->control_a, save_control); if (todc_info->rtc_type == TODC_TYPE_MC146818) { @@ -438,7 +438,7 @@ } return val; -} +} /* * This was taken from prep_setup.c @@ -451,7 +451,7 @@ ulong tbl, tbu; long i, loop_count; u_char sec; - + todc_time_init(); /* diff -urN linux-2.4.21/arch/ppc/kernel/traps.c linux-2.4.22/arch/ppc/kernel/traps.c --- linux-2.4.21/arch/ppc/kernel/traps.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -167,7 +167,7 @@ #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) /* On 4xx, the reason for the machine check or program exception is in the ESR. */ -#define get_reason(regs) mfspr(SPRN_ESR); +#define get_reason(regs) ((regs)->dsisr) #define REASON_FP 0 #define REASON_ILLEGAL ESR_PIL #define REASON_PRIVILEGED ESR_PPR @@ -213,7 +213,7 @@ printk("Data"); printk(" machine check in kernel mode.\n"); -#else /* CONFIG_4xx */ +#else /* !CONFIG_4xx */ printk("Machine check in kernel mode.\n"); printk("Caused by (from SRR1=%lx): ", reason); switch (reason & 0x601F0000) { @@ -327,7 +327,14 @@ extern int do_mathemu(struct pt_regs *regs); #ifdef CONFIG_MATH_EMULATION - if ((reason & REASON_ILLEGAL) && do_mathemu(regs) == 0) + /* (reason & REASON_ILLEGAL) would be the obvious thing here, + * but there seems to be a hardware bug on the 405GP (RevD) + * that means ESR is sometimes set incorrectly - either to + * ESR_DST (!?) or 0. In the process of chasing this with the + * hardware people - not sure if it can happen on any illegal + * instruction or only on FP instructions, whether there is a + * pattern to occurences etc. -dgibson 31/Mar/2003 */ + if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) return; #endif /* CONFIG_MATH_EMULATION */ @@ -450,6 +457,35 @@ } #endif /* CONFIG_8xx */ +#if defined(CONFIG_4xx) + +void DebugException(struct pt_regs *regs) +{ + unsigned long debug_status; + + debug_status = mfspr(SPRN_DBSR); + + regs->msr &= ~MSR_DE; /* Turn off 'debug' bit */ + if (debug_status & DBSR_TIE) { /* trap instruction*/ + + mtspr(SPRN_DBSR, DBSR_TIE); + + if (!user_mode(regs) && debugger_bpt(regs)) + return; + _exception(SIGTRAP, regs, 0, 0); + + } else if (debug_status & DBSR_IC) { /* instruction completion */ + + mtspr(SPRN_DBSR, DBSR_IC); + current->thread.dbcr0 &= ~DBCR0_IC; + + if (!user_mode(regs) && debugger_sstep(regs)) + return; + _exception(SIGTRAP, regs, 0, 0); + } +} +#endif /* CONFIG_4xx */ + #if !defined(CONFIG_TAU_INT) void TAUException(struct pt_regs *regs) diff -urN linux-2.4.21/arch/ppc/lib/checksum.S linux-2.4.22/arch/ppc/lib/checksum.S --- linux-2.4.21/arch/ppc/lib/checksum.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/lib/checksum.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * This file contains assembly-language implementations * of IP-style 1's complement checksum routines. - * + * * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * This program is free software; you can redistribute it and/or @@ -43,7 +43,7 @@ /* * Compute checksum of TCP or UDP pseudo-header: * csum_tcpudp_magic(saddr, daddr, len, proto, sum) - */ + */ _GLOBAL(csum_tcpudp_magic) rlwimi r5,r6,16,0,15 /* put proto in upper half of len */ addc r0,r3,r4 /* add 4 32-bit words together */ diff -urN linux-2.4.21/arch/ppc/lib/locks.c linux-2.4.22/arch/ppc/lib/locks.c --- linux-2.4.21/arch/ppc/lib/locks.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/lib/locks.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* - * Locks for smp ppc - * + * Locks for smp ppc + * * Written by Cort Dougan (cort@cs.nmt.edu) */ @@ -70,7 +70,7 @@ { if (__spin_trylock(&lock->lock)) return 0; - lock->owner_cpu = smp_processor_id(); + lock->owner_cpu = smp_processor_id(); lock->owner_pc = (unsigned long)__builtin_return_address(0); return 1; } @@ -101,7 +101,7 @@ unsigned long stuck = INIT_STUCK; int cpu = smp_processor_id(); -again: +again: /* get our read lock in there */ atomic_inc((atomic_t *) &(rw)->lock); if ( (signed long)((rw)->lock) < 0) /* someone has a write lock */ @@ -153,7 +153,7 @@ } goto again; } - + if ( (rw)->lock & ~(1<<31)) /* someone has a read lock */ { /* clear our write lock and wait for reads to go away */ diff -urN linux-2.4.21/arch/ppc/lib/string.S linux-2.4.22/arch/ppc/lib/string.S --- linux-2.4.21/arch/ppc/lib/string.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/lib/string.S 2003-08-25 04:44:40.000000000 -0700 @@ -77,6 +77,8 @@ bne 1b blr +/* This clears out any unused part of the destination buffer, + just as the libc version does. -- paulus */ .globl strncpy strncpy: cmpwi 0,r5,0 @@ -88,6 +90,12 @@ cmpwi 0,r0,0 stbu r0,1(r6) bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ + bnelr /* if we didn't hit a null char, we're done */ + mfctr r5 + cmpwi 0,r5,0 /* any space left in destination buffer? */ + beqlr /* we know r0 == 0 here */ +2: stbu r0,1(r6) /* clear it out if so */ + bdnz 2b blr .globl strcat @@ -380,7 +388,7 @@ beq 2b mtctr r7 b 1b - + .globl memcmp memcmp: cmpwi 0,r5,0 diff -urN linux-2.4.21/arch/ppc/math-emu/fcmpo.c linux-2.4.22/arch/ppc/math-emu/fcmpo.c --- linux-2.4.21/arch/ppc/math-emu/fcmpo.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/math-emu/fcmpo.c 2003-08-25 04:44:40.000000000 -0700 @@ -37,7 +37,7 @@ *ccr &= ~(15 << ((7 - crfD) << 2)); *ccr |= (cmp << ((7 - crfD) << 2)); - + #ifdef DEBUG printk("CR: %08x\n", *ccr); #endif diff -urN linux-2.4.21/arch/ppc/math-emu/op-1.h linux-2.4.22/arch/ppc/math-emu/op-1.h --- linux-2.4.21/arch/ppc/math-emu/op-1.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/math-emu/op-1.h 2003-08-25 04:44:40.000000000 -0700 @@ -197,14 +197,14 @@ udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ R##_f = _q | (_r != 0); \ } while (0) - - + + /* * Square root algorithms: * We have just one right now, maybe Newton approximation * should be added for those machines where division is fast. */ - + #define _FP_SQRT_MEAT_1(R, S, T, X, q) \ do { \ while (q) \ @@ -222,7 +222,7 @@ } while (0) /* - * Assembly/disassembly for converting to/from integral types. + * Assembly/disassembly for converting to/from integral types. * No shifting or overflow handled here. */ diff -urN linux-2.4.21/arch/ppc/math-emu/op-2.h linux-2.4.22/arch/ppc/math-emu/op-2.h --- linux-2.4.21/arch/ppc/math-emu/op-2.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/math-emu/op-2.h 2003-08-25 04:44:40.000000000 -0700 @@ -98,7 +98,7 @@ #define _FP_MINFRAC_2 0, 1 /* - * Internals + * Internals */ #define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) @@ -210,8 +210,8 @@ /* This next macro appears to be totally broken. Fortunately nowhere * seems to use it :-> The problem is that we define _z[4] but * then use it in _FP_FRAC_SRS_4, which will attempt to access - * _z_f[n] which will cause an error. The fix probably involves - * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998 + * _z_f[n] which will cause an error. The fix probably involves + * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998 */ #define _FP_MUL_MEAT_2_gmp(fs, R, X, Y) \ do { \ @@ -232,7 +232,7 @@ /* * Division algorithms: - * This seems to be giving me difficulties -- PMM + * This seems to be giving me difficulties -- PMM * Look, NetBSD seems to be able to comment algorithms. Can't you? * I've thrown printks at the problem. * This now appears to work, but I still don't really know why. @@ -354,7 +354,7 @@ * We have just one right now, maybe Newton approximation * should be added for those machines where division is fast. */ - + #define _FP_SQRT_MEAT_2(R, S, T, X, q) \ do { \ while (q) \ @@ -391,7 +391,7 @@ /* - * Assembly/disassembly for converting to/from integral types. + * Assembly/disassembly for converting to/from integral types. * No shifting or overflow handled here. */ diff -urN linux-2.4.21/arch/ppc/math-emu/op-4.h linux-2.4.22/arch/ppc/math-emu/op-4.h --- linux-2.4.21/arch/ppc/math-emu/op-4.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/math-emu/op-4.h 2003-08-25 04:44:40.000000000 -0700 @@ -7,14 +7,14 @@ * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4, * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4 * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use - * _FP_FRAC_DECL_4: it appears to be broken and is not used + * _FP_FRAC_DECL_4: it appears to be broken and is not used * anywhere anyway. ) * * I've now fixed all the macros that were here from the sparc64 code. * [*none* of the shift macros were correct!] -- PMM 02/1998 - * - * The only quadword stuff that remains to be coded is: - * 1) the conversion to/from ints, which requires + * + * The only quadword stuff that remains to be coded is: + * 1) the conversion to/from ints, which requires * that we check (in op-common.h) that the following do the right thing * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt) * 2) multiply, divide and sqrt, which require: @@ -32,9 +32,9 @@ /* The _FP_FRAC_SET_n(X,I) macro is intended for use with another * macro such as _FP_ZEROFRAC_n which returns n comma separated values. * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3) - * which just assigns the In values to the array X##_f[]. + * which just assigns the In values to the array X##_f[]. * This is why the number of parameters doesn't appear to match - * at first glance... -- PMM + * at first glance... -- PMM */ #define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I) #define _FP_FRAC_HIGH_4(X) (X##_f[3]) @@ -70,7 +70,7 @@ } while (0) -/* Right shift with sticky-lsb. +/* Right shift with sticky-lsb. * What this actually means is that we do a standard right-shift, * but that if any of the bits that fall off the right hand side * were one then we always set the LSbit. @@ -187,7 +187,7 @@ /* - * Internals + * Internals */ #define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ @@ -218,9 +218,9 @@ /* Convert FP values between word sizes. This appears to be more * complicated than I'd have expected it to be, so these might be * wrong... These macros are in any case somewhat bogus because they - * use information about what various FRAC_n variables look like + * use information about what various FRAC_n variables look like * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do - * the ones in op-2.h and op-1.h. + * the ones in op-2.h and op-1.h. */ #define _FP_FRAC_CONV_1_4(dfs, sfs, D, S) \ do { \ @@ -237,7 +237,7 @@ D##_f1 = S##_f[1]; \ } while (0) -/* Assembly/disassembly for converting to/from integral types. +/* Assembly/disassembly for converting to/from integral types. * No shifting or overflow handled here. */ /* Put the FP value X into r, which is an integer of size rsize. */ diff -urN linux-2.4.21/arch/ppc/math-emu/op-common.h linux-2.4.22/arch/ppc/math-emu/op-common.h --- linux-2.4.21/arch/ppc/math-emu/op-common.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/math-emu/op-common.h 2003-08-25 04:44:40.000000000 -0700 @@ -525,7 +525,7 @@ * Convert from FP to integer */ -/* "When a NaN, infinity, large positive argument >= 2147483648.0, or +/* "When a NaN, infinity, large positive argument >= 2147483648.0, or * large negative argument <= -2147483649.0 is converted to an integer, * the invalid_current bit...should be set and fp_exception_IEEE_754 should * be raised. If the floating point invalid trap is disabled, no trap occurs @@ -538,7 +538,7 @@ * -- SPARC Architecture Manual V9, Appendix B, which specifies how * SPARCs resolve implementation dependencies in the IEEE-754 spec. * I don't believe that the code below follows this. I'm not even sure - * it's right! + * it's right! * It doesn't cope with needing to convert to an n bit integer when there * is no n bit integer type. Fortunately gcc provides long long so this * isn't a problem for sparc32. @@ -546,7 +546,7 @@ * -- PMM 02/1998 * NB: rsigned is not 'is r declared signed?' but 'should the value stored * in r be signed or unsigned?'. r is always(?) declared unsigned. - * Comments below are mine, BTW -- PMM + * Comments below are mine, BTW -- PMM */ #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ do { \ diff -urN linux-2.4.21/arch/ppc/math-emu/sfp-machine.h linux-2.4.22/arch/ppc/math-emu/sfp-machine.h --- linux-2.4.21/arch/ppc/math-emu/sfp-machine.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/math-emu/sfp-machine.h 2003-08-25 04:44:40.000000000 -0700 @@ -15,10 +15,10 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Actually, this is a PPC (32bit) version, written based on the - i386, sparc, and sparc64 versions, by me, + i386, sparc, and sparc64 versions, by me, Peter Maydell (pmaydell@chiark.greenend.org.uk). Comments are by and large also mine, although they may be inaccurate. @@ -48,12 +48,12 @@ /* We need to know how to multiply and divide. If the host word size * is >= 2*fracbits you can use FP_MUL_MEAT_n_imm(t,R,X,Y) which * codes the multiply with whatever gcc does to 'a * b'. - * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm - * function that can multiply two 1W values and get a 2W result. + * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm + * function that can multiply two 1W values and get a 2W result. * Otherwise you're stuck with _FP_MUL_MEAT_n_hard(t,R,X,Y) which * does bitshifting to avoid overflow. * For division there is FP_DIV_MEAT_n_imm(t,R,X,Y,f) for word size - * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or + * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or * _FP_DIV_HELP_ldiv (see op-1.h). * _FP_DIV_MEAT_udiv() is if you have asm to do 2W/1W => (1W, 1W). * [GCC and glibc have longlong.h which has the asm macro udiv_qrnnd @@ -85,7 +85,7 @@ #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv_64(D,R,X,Y) -/* These macros define what NaN looks like. They're supposed to expand to +/* These macros define what NaN looks like. They're supposed to expand to * a comma-separated set of 32bit unsigned ints that encode NaN. */ #define _FP_NANFRAC_S _FP_QNANBIT_S @@ -94,10 +94,10 @@ #define _FP_KEEPNANFRACP 1 -/* This macro appears to be called when both X and Y are NaNs, and +/* This macro appears to be called when both X and Y are NaNs, and * has to choose one and copy it to R. i386 goes for the larger of the * two, sparc64 just picks Y. I don't understand this at all so I'll - * go with sparc64 because it's shorter :-> -- PMM + * go with sparc64 because it's shorter :-> -- PMM */ #define _FP_CHOOSENAN(fs, wc, R, X, Y) \ do { \ @@ -105,7 +105,7 @@ _FP_FRAC_COPY_##wc(R,Y); \ R##_c = FP_CLS_NAN; \ } while (0) - + extern void fp_unpack_d(long *, unsigned long *, unsigned long *, long *, long *, void *); @@ -151,7 +151,7 @@ _flo->bits.exp = X##_e; \ _flo->bits.sign = X##_s; \ } while (0) - + #define __FP_PACK_RAW_2(fs, val, X) \ do { \ union _FP_UNION_##fs *_flo = \ @@ -288,7 +288,7 @@ "r" ((USItype)(bl))); \ } while (0) -/* asm fragments for mul and div */ +/* asm fragments for mul and div */ /* umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two * UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype diff -urN linux-2.4.21/arch/ppc/math-emu/stfd.c linux-2.4.22/arch/ppc/math-emu/stfd.c --- linux-2.4.21/arch/ppc/math-emu/stfd.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/math-emu/stfd.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ #include #include #include - + int stfd(void *frS, void *ea) { diff -urN linux-2.4.21/arch/ppc/mm/4xx_mmu.c linux-2.4.22/arch/ppc/mm/4xx_mmu.c --- linux-2.4.21/arch/ppc/mm/4xx_mmu.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/4xx_mmu.c 2003-08-25 04:44:40.000000000 -0700 @@ -2,7 +2,7 @@ * This file contains the routines for initializing the MMU * on the 4xx series of chips. * -- paulus - * + * * Derived from arch/ppc/mm/init.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -51,11 +51,6 @@ #include #include -/* Used by the 4xx TLB replacement exception handler. - * Just needed it declared someplace (and initialized to zero). - */ -unsigned int tlb_4xx_index; - /* * MMU_init_hw does the chip-specific initialization of the MMU hardware. */ @@ -89,7 +84,14 @@ * Cache instruction and data space where the exception * vectors and the kernel live in real-mode. */ + /* + * Once the following code is enhanced to not assume that it should + * just enable caching on the first 512MB, we need to make sure that + * we either are given the cache in a known state or handle correctly + * the cache being enabled previously. Currently this will clear + * without flushing. -- Tom + */ - mtspr(SPRN_DCCR, 0x80000000); /* 128 MB of data space at 0x0. */ - mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */ + mtspr(SPRN_DCCR, 0xF0000000); /* 512 MB of data space at 0x0. */ + mtspr(SPRN_ICCR, 0xF0000000); /* 512 MB of instr. space at 0x0. */ } diff -urN linux-2.4.21/arch/ppc/mm/4xx_tlb.c linux-2.4.22/arch/ppc/mm/4xx_tlb.c --- linux-2.4.21/arch/ppc/mm/4xx_tlb.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/4xx_tlb.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,358 +0,0 @@ -/* - * - * Copyright (c) 1998-1999 TiVo, Inc. - * Original implementation. - * Copyright (c) 1999-2000 Grant Erickson - * Minor rework. - * - * Module name: 4xx_tlb.c - * - * Description: - * Routines for manipulating the TLB on PowerPC 400-class processors. - * - */ - -#include - -#include -#include -#include -#include -#include - - -/* Preprocessor Defines */ - -#if !defined(TRUE) || TRUE != 1 -#define TRUE 1 -#endif - -#if !defined(FALSE) || FALSE != 0 -#define FALSE 0 -#endif - - -/* Global Variables */ - -static int pinned = 0; - - -/* Function Prototypes */ - -static int PPC4xx_tlb_miss(struct pt_regs *, unsigned long, int); - -extern void do_page_fault(struct pt_regs *, unsigned long, unsigned long); - - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -static inline void -PPC4xx_tlb_write(unsigned long tag, unsigned long data, unsigned int index) -{ - asm("tlbwe %0,%1,1" : : "r" (data), "r" (index)); - asm("tlbwe %0,%1,0" : : "r" (tag), "r" (index)); -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_flush_tlb_all(void) -{ - int i; - unsigned long flags, pid; - - save_flags(flags); - cli(); - - pid = mfspr(SPRN_PID); - mtspr(SPRN_PID, 0); - - for (i = pinned; i < PPC4XX_TLB_SIZE; i++) { - PPC4xx_tlb_write(0, 0, i); - } - asm("sync;isync"); - - mtspr(SPRN_PID, pid); - restore_flags(flags); -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_dtlb_miss(struct pt_regs *regs) -{ - unsigned long addr = mfspr(SPRN_DEAR); - int write = mfspr(SPRN_ESR) & ESR_DST; - - if (PPC4xx_tlb_miss(regs, addr, write) < 0) { - sti(); - do_page_fault(regs, addr, write); - cli(); - } - -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_itlb_miss(struct pt_regs *regs) -{ - unsigned long addr = regs->nip; - - if (PPC4xx_tlb_miss(regs, addr, 0) < 0) { - sti(); - do_page_fault(regs, addr, 0); - cli(); - } -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_tlb_pin(unsigned long va, unsigned long pa, int pagesz, int cache) -{ - unsigned long tag, data; - unsigned long opid; - - if (pinned >= PPC4XX_TLB_SIZE) - return; - - opid = mfspr(SPRN_PID); - mtspr(SPRN_PID, 0); - - data = (pa & TLB_RPN_MASK) | TLB_WR; - - if (cache) - data |= (TLB_EX); - else - data |= (TLB_G | TLB_I); - - tag = (va & TLB_EPN_MASK) | TLB_VALID | pagesz; - - PPC4xx_tlb_write(tag, data, pinned++); - - mtspr(SPRN_PID, opid); - return; -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_tlb_unpin(unsigned long va, unsigned long pa, int size) -{ - /* XXX - To be implemented. */ -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -static inline void -PPC4xx_tlb_update(unsigned long addr, pte_t *pte) -{ - unsigned long data, tag, rand; - int i, found = 1; - - /* Construct the hardware TLB entry from the Linux-style PTE */ - - tag = tag = (addr & PAGE_MASK) | TLB_VALID | TLB_PAGESZ(PAGESZ_4K); - data = data = (pte_val(*pte) & PAGE_MASK) | TLB_EX | TLB_WR; - -#if 0 - if (pte_val(*pte) & _PAGE_HWWRITE) - data |= TLB_WR; -#endif - - if (pte_val(*pte) & _PAGE_NO_CACHE) - data |= TLB_I; - - if (pte_val(*pte) & _PAGE_GUARDED) - data |= TLB_G; - - if (addr < KERNELBASE) - data |= TLB_ZSEL(1); - - /* Attempt to match the new tag to an existing entry in the TLB. */ - - asm("tlbsx. %0,0,%2;" - "beq 1f;" - "li %1,0;1:" : "=r" (i), "=r" (found) : "r" (tag)); - - /* - * If we found a match for the tag, reuse the entry index and update - * the tag and data portions. Otherwise, we did not find a match. Use - * the lower 5 bits of the lower time base register as a pseudo-random - * index into the TLB and replace the entry at that index. - */ - - if (found) { - PPC4xx_tlb_write(tag, data, i); - } else { - rand = mfspr(SPRN_TBLO) & (PPC4XX_TLB_SIZE - 1); - rand += pinned; - if (rand >= PPC4XX_TLB_SIZE) - rand -= pinned; - - PPC4xx_tlb_write(tag, data, rand); - asm("isync;sync"); - } -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -static int -PPC4xx_tlb_miss(struct pt_regs *regs, unsigned long addr, int write) -{ - unsigned long spid, ospid; - struct mm_struct *mm; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - if (!user_mode(regs) && (addr >= KERNELBASE)) { - mm = &init_mm; - spid = 0; - } else { - mm = current->mm; - spid = mfspr(SPRN_PID); - } - - pgd = pgd_offset(mm, addr); - if (pgd_none(*pgd)) - goto bad; - - pmd = pmd_offset(pgd, addr); - if (pmd_none(*pmd)) - goto bad; - - pte = pte_offset(pmd, addr); - if (pte_none(*pte) || !pte_present(*pte)) - goto bad; - - if (write) { - if (!pte_write(*pte)) - goto bad; - - set_pte(pte, pte_mkdirty(*pte)); - } - set_pte(pte, pte_mkyoung(*pte)); - - ospid = mfspr(SPRN_PID); - mtspr(SPRN_PID, spid); - PPC4xx_tlb_update(addr, pte); - mtspr(SPRN_PID, ospid); - - return (0); -bad: - return (-1); -} diff -urN linux-2.4.21/arch/ppc/mm/4xx_tlb.h linux-2.4.22/arch/ppc/mm/4xx_tlb.h --- linux-2.4.21/arch/ppc/mm/4xx_tlb.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/4xx_tlb.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,35 +0,0 @@ -/* - * - * Copyright (c) 1999 Grant Erickson - * - * Module name: 4xx_tlb.h - * - * Description: - * Routines for manipulating the TLB on PowerPC 400-class processors. - * - */ - -#ifndef __4XX_TLB_H__ -#define __4XX_TLB_H__ - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Function Prototypes */ - -extern void PPC4xx_tlb_pin(unsigned long va, unsigned long pa, - int pagesz, int cache); -extern void PPC4xx_tlb_unpin(unsigned long va, unsigned long pa, - int size); -extern void PPC4xx_tlb_flush_all(void); -extern void PPC4xx_tlb_flush(unsigned long va, int pid); - - -#ifdef __cplusplus -} -#endif - -#endif /* __4XX_TLB_H__ */ diff -urN linux-2.4.21/arch/ppc/mm/Makefile linux-2.4.22/arch/ppc/mm/Makefile --- linux-2.4.21/arch/ppc/mm/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -18,7 +18,7 @@ mmu_context.o pgtable.o obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o -obj-$(CONFIG_4xx) += cachemap.o 4xx_mmu.o -obj-$(CONFIG_8xx) += cachemap.o +obj-$(CONFIG_40x) += 4xx_mmu.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += cachemap.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/ppc/mm/fault.c linux-2.4.22/arch/ppc/mm/fault.c --- linux-2.4.21/arch/ppc/mm/fault.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * arch/ppc/mm/fault.c * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Derived from "arch/i386/mm/fault.c" @@ -197,7 +197,7 @@ /* Guarded storage error. */ goto bad_area; #endif /* CONFIG_8xx */ - + /* a write */ if (is_write) { if (!(vma->vm_flags & VM_WRITE)) @@ -241,7 +241,7 @@ bad_area: up_read(&mm->mmap_sem); - pte_errors++; + pte_errors++; /* User mode accesses cause a SIGSEGV */ if (user_mode(regs)) { @@ -348,7 +348,7 @@ unsigned long va_to_phys(unsigned long address) { pte_t *pte; - + pte = va_to_pte(address); if (pte) return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK))); @@ -371,7 +371,7 @@ if (pte) { printk(" (0x%08lx)->(0x%08lx)->0x%08lx\n", (long)pgd, (long)pte, (long)pte_val(*pte)); -#define pp ((long)pte_val(*pte)) +#define pp ((long)pte_val(*pte)) printk(" RPN: %05lx PP: %lx SPS: %lx SH: %lx " "CI: %lx v: %lx\n", pp>>12, /* rpn */ @@ -381,7 +381,7 @@ (pp>>1)&1, /* cache inhibit */ pp&1 /* valid */ ); -#undef pp +#undef pp } else { printk("no pte\n"); diff -urN linux-2.4.21/arch/ppc/mm/hashtable.S linux-2.4.22/arch/ppc/mm/hashtable.S --- linux-2.4.21/arch/ppc/mm/hashtable.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/hashtable.S 2003-08-25 04:44:40.000000000 -0700 @@ -3,7 +3,7 @@ * * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $ * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP * Copyright (C) 1996 Cort Dougan @@ -20,7 +20,7 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. - * + * */ #include @@ -168,7 +168,7 @@ lwz r23,GPR23(r21) lwz r21,GPR21(r21) RFI - + #ifdef CONFIG_SMP hash_page_out: eieio diff -urN linux-2.4.21/arch/ppc/mm/init.c linux-2.4.22/arch/ppc/mm/init.c --- linux-2.4.21/arch/ppc/mm/init.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -345,7 +345,7 @@ #ifdef CONFIG_BOOTX_TEXT /* By default, we are no longer mapped */ - boot_text_mapped = 0; + boot_text_mapped = 0; /* Must be done last, or ppc_md.progress will die. */ map_boot_text(); #endif @@ -573,14 +573,14 @@ * memory as high as possible (it must be outside of the * bus address seen as the AGP aperture). It will be used * by the r128 DRM driver - * + * * FIXME: We need to make sure that page doesn't overlap any of the\ * above. This could be done by improving mem_pieces_find to be able * to do a backward search from the end of the list. */ if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) { agp_special_page = (total_memory - PAGE_SIZE); - mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0); + mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0); agp_special_page = (unsigned long)__va(agp_special_page); } #endif /* CONFIG_ALL_PPC */ diff -urN linux-2.4.21/arch/ppc/mm/mem_pieces.c linux-2.4.22/arch/ppc/mm/mem_pieces.c --- linux-2.4.21/arch/ppc/mm/mem_pieces.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/mem_pieces.c 2003-08-25 04:44:40.000000000 -0700 @@ -46,14 +46,14 @@ } } panic("Couldn't find %u bytes at %u alignment\n", size, align); - + return NULL; } /* * Remove some memory from an array of pieces */ -void __init +void __init mem_pieces_remove(struct mem_pieces *mp, unsigned int start, unsigned int size, int must_exist) { diff -urN linux-2.4.21/arch/ppc/mm/mmu_context.c linux-2.4.22/arch/ppc/mm/mmu_context.c --- linux-2.4.21/arch/ppc/mm/mmu_context.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/mmu_context.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * specification, the need to work through the hypervisor makes * things sufficiently different that it is handled elsewhere. * -- paulus - * + * * Derived from arch/ppc/mm/init.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * diff -urN linux-2.4.21/arch/ppc/mm/mmu_decl.h linux-2.4.22/arch/ppc/mm/mmu_decl.h --- linux-2.4.21/arch/ppc/mm/mmu_decl.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/mmu_decl.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * Declarations of procedures and variables shared between files * in arch/ppc/mm/. - * + * * Derived from arch/ppc/mm/init.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * diff -urN linux-2.4.21/arch/ppc/mm/pgtable.c linux-2.4.22/arch/ppc/mm/pgtable.c --- linux-2.4.21/arch/ppc/mm/pgtable.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/pgtable.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * This file contains the routines setting up the linux page tables. * -- paulus - * + * * Derived from arch/ppc/mm/init.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -122,7 +122,7 @@ */ if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) goto out; - + if (mem_init_done) { struct vm_struct *area; area = get_vm_area(size, VM_IOREMAP); @@ -193,13 +193,13 @@ adjust_total_lowmem(void) { unsigned long max_low_mem = MAX_LOW_MEM; - + #ifdef HAVE_BATS unsigned long bat_max = 0x10000000; unsigned long align; unsigned long ram; int is601 = 0; - + /* 601s have smaller BATs */ if (PVR_VER(mfspr(PVR)) == 1) { bat_max = 0x00800000; @@ -224,7 +224,7 @@ if (align && align < bat_max) bat_max = align; - /* Calculate BAT values */ + /* Calculate BAT values */ __bat2 = 1UL << __ilog2(ram); if (__bat2 > bat_max) __bat2 = bat_max; @@ -278,11 +278,11 @@ /* On the MPC8xx, we want the page shared so we * don't get ASID compares on kernel space. */ - f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; -#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) + f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED | _PAGE_HWEXEC; +#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) /* Allows stub to set breakpoints everywhere */ f |= _PAGE_WRENABLE; -#else /* !CONFIG_KGDB && !CONFIG_XMON */ +#else /* !CONFIG_KGDB && !CONFIG_XMON && !CONFIG_BDI_SWITCH */ if ((char *) v < _stext || (char *) v >= etext) f |= _PAGE_WRENABLE; #ifdef CONFIG_PPC_STD_MMU @@ -388,7 +388,7 @@ mm = current->mm; else mm = &init_mm; - + pa = 0; if (get_pteptr(mm, addr, &pte)) pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); @@ -421,7 +421,7 @@ goto exit; } } - + ret = (unsigned long) __va(paddr); } exit: diff -urN linux-2.4.21/arch/ppc/mm/ppc_mmu.c linux-2.4.22/arch/ppc/mm/ppc_mmu.c --- linux-2.4.21/arch/ppc/mm/ppc_mmu.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/ppc_mmu.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * specification, the need to work through the hypervisor makes * things sufficiently different that it is handled elsewhere. * -- paulus - * + * * Derived from arch/ppc/mm/init.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -86,13 +86,13 @@ void __init bat_mapin_ram(unsigned long bat2, unsigned long bat3) { unsigned long tot, done; - + tot = total_lowmem; setbat(2, KERNELBASE, PPC_MEMSTART, bat2, _PAGE_KERNEL); done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; if ((done < tot) && !bat_addrs[3].limit && bat3) { tot -= done; - setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bat3, + setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bat3, _PAGE_KERNEL); } } diff -urN linux-2.4.21/arch/ppc/mm/tlb.c linux-2.4.22/arch/ppc/mm/tlb.c --- linux-2.4.21/arch/ppc/mm/tlb.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/mm/tlb.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,10 +1,10 @@ /* * This file contains the routines for TLB flushing. * On machines where the MMU uses a hash table to store virtual to - * physical translations, these routines flush entries from the + * physical translations, these routines flush entries from the * hash table also. * -- paulus - * + * * Derived from arch/ppc/mm/init.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -87,7 +87,7 @@ #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); -#endif +#endif } void @@ -110,7 +110,7 @@ } #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); -#endif +#endif } @@ -155,5 +155,5 @@ #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); -#endif +#endif } diff -urN linux-2.4.21/arch/ppc/platforms/Makefile linux-2.4.22/arch/ppc/platforms/Makefile --- linux-2.4.21/arch/ppc/platforms/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -28,7 +28,7 @@ export-objs := prep_setup.o -obj-$(CONFIG_WALNUT) += walnut.o +obj-$(CONFIG_WALNUT) += walnut.o ibm405gp.o obj-$(CONFIG_APUS) += apus_setup.o ifeq ($(CONFIG_APUS),y) @@ -46,6 +46,7 @@ obj-$(CONFIG_GEMINI) += gemini_pci.o gemini_setup.o gemini_prom.o obj-$(CONFIG_LOPEC) += lopec_setup.o lopec_pci.o obj-$(CONFIG_PAL4) += pal4_setup.o pal4_pci.o cpc700_pic.o +obj-$(CONFIG_PPLUS) += pplus_pci.o pplus_setup.o obj-$(CONFIG_SPRUCE) += spruce_setup.o spruce_pci.o cpc700_pic.o ifeq ($(CONFIG_SMP),y) diff -urN linux-2.4.21/arch/ppc/platforms/apus_pci.c linux-2.4.22/arch/ppc/platforms/apus_pci.c --- linux-2.4.21/arch/ppc/platforms/apus_pci.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/apus_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,7 +33,7 @@ #define DPRINTK(a,b...) printk(KERN_DEBUG "apus_pci: %s: " a, __FUNCTION__ , ## b) #else #define DPRINTK(a,b...) -#endif +#endif /* * The _DEFINITIVE_ memory mapping/unmapping functions. @@ -124,9 +124,9 @@ } -/* +/* * This is from pm2fb.c again - * + * * Check if PCI (B/CVisionPPC) is available, initialize it and set up * the pcibios_* pointers */ diff -urN linux-2.4.21/arch/ppc/platforms/chrp_setup.c linux-2.4.22/arch/ppc/platforms/chrp_setup.c --- linux-2.4.21/arch/ppc/platforms/chrp_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/chrp_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -232,7 +232,7 @@ #ifdef CONFIG_BLK_DEV_INITRD /* this is fine for chrp */ initrd_below_start_ok = 1; - + if (initrd_start) ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); else @@ -277,14 +277,14 @@ if (p && (rate = *(unsigned long *)p->value) > 0) { /* * The value is the number of times per minute. - * For now assign the full workload here to cpu 0. + * For now assign the full workload here to cpu 0. * * We now split the rate and spread the heartbeats * when we kick secondary cpus so we can spread - * the calls evenly. + * the calls evenly. */ ppc_md.heartbeat = chrp_event_scan; - + count = (60*HZ) / rate; if (!count) /* XXX insane */ count = 1; @@ -309,7 +309,7 @@ call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0, __pa(log), 1024 ); } - + void __chrp chrp_restart(char *cmd) { @@ -433,7 +433,7 @@ chrp_init_irq_8259(unsigned long intack) { int i; - + ppc_md.get_irq = i8259_irq; for (i = 0; i < NUM_8259_INTERRUPTS; i++) irq_desc[i].handler = &i8259_pic; @@ -445,7 +445,7 @@ struct device_node *np; unsigned long intack = 0; struct device_node *main_irq_ctrler = NULL; -#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) struct device_node *kbd; #endif @@ -491,10 +491,10 @@ void __init chrp_init2(void) { - + if (chrp_is_briq) briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4); -#ifdef CONFIG_NVRAM +#ifdef CONFIG_NVRAM /* Fix me: currently, a lot of pmac_nvram routines are marked __pmac, and * blindly calling pmac_nvram_init() on chrp cause bad results. * Among others, it cracks on briQ. @@ -563,7 +563,7 @@ rs_table[0].baud_base = (7372800 / 16); rs_table[1].baud_base = (7372800 / 16); } -#endif /* CONFIG_SERIAL */ +#endif /* CONFIG_SERIAL */ ppc_md.setup_arch = chrp_setup_arch; ppc_md.show_percpuinfo = of_show_percpuinfo; @@ -631,7 +631,7 @@ /* * Print the banner, then scroll down so boot progress - * can be printed. -- Cort + * can be printed. -- Cort */ if ( ppc_md.progress ) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); } diff -urN linux-2.4.21/arch/ppc/platforms/chrp_smp.c linux-2.4.22/arch/ppc/platforms/chrp_smp.c --- linux-2.4.21/arch/ppc/platforms/chrp_smp.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/chrp_smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -44,7 +44,7 @@ * call event-scan periodically, not always the same * one. The event-scan function needs to be called a * total of rtas-event-scan-rate times a minute" - * + * * We must call on each cpu in on a regular basis * so that firmware can watch for cpu unique errors. */ diff -urN linux-2.4.21/arch/ppc/platforms/chrp_time.c linux-2.4.22/arch/ppc/platforms/chrp_time.c --- linux-2.4.21/arch/ppc/platforms/chrp_time.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/chrp_time.c 2003-08-25 04:44:40.000000000 -0700 @@ -132,10 +132,10 @@ /* Since the UIP flag is set for about 2.2 ms and the clock * is typically written with a precision of 1 jiffy, trying - * to obtain a precision better than a few milliseconds is + * to obtain a precision better than a few milliseconds is * an illusion. Only consistency is interesting, this also * allows to use the routine for /dev/rtc without a potential - * 1 second kernel busy loop triggered by any reader of /dev/rtc. + * 1 second kernel busy loop triggered by any reader of /dev/rtc. */ for ( i = 0; i<1000000; i++) { diff -urN linux-2.4.21/arch/ppc/platforms/cpc700.h linux-2.4.22/arch/ppc/platforms/cpc700.h --- linux-2.4.21/arch/ppc/platforms/cpc700.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/cpc700.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * include/asm-ppc/cpc700.h - * + * * Header file for IBM CPC700 Host Bridge, et. al. * * Author: Mark A. Greer @@ -85,7 +85,7 @@ */ extern struct hw_interrupt_type cpc700_pic; extern unsigned int cpc700_irq_assigns[32][2]; - + extern void __init cpc700_init_IRQ(void); extern int cpc700_get_irq(struct pt_regs *); diff -urN linux-2.4.21/arch/ppc/platforms/cpc700_pic.c linux-2.4.22/arch/ppc/platforms/cpc700_pic.c --- linux-2.4.21/arch/ppc/platforms/cpc700_pic.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/cpc700_pic.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/platforms/cpc700_pic.c - * + * * Interrupt controller support for IBM Spruce * * Authors: Mark Greer, Matt Porter, and Johnnie Peters @@ -47,7 +47,7 @@ /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */ ppc_cached_irq_mask[0] |= CPC700_UIC_IRQ_BIT(irq); - + CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]); } return; @@ -128,10 +128,10 @@ tmp = CPC700_IN_32(CPC700_UIC_UICCR); tmp |= CPC700_UIC_IRQ_BIT(irq); CPC700_OUT_32(CPC700_UIC_UICCR, tmp); - + return; } - + __init void cpc700_init_IRQ(void) { @@ -179,7 +179,7 @@ irq++; irq_test <<= 1; } while (irq < NR_IRQS); - + if (irq == NR_IRQS) irq = 33; diff -urN linux-2.4.21/arch/ppc/platforms/error_log.c linux-2.4.22/arch/ppc/platforms/error_log.c --- linux-2.4.21/arch/ppc/platforms/error_log.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/error_log.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/kernel/error_log.c - * + * * Copyright (c) 2000 Tilmann Bitterberg * (tilmann@bitterberg.de) * @@ -15,10 +15,10 @@ #include "error_log.h" /* ****************************************************************** */ -/* +/* * EVENT-SCAN * The whole stuff below here doesn't take any action when it found - * an error, it just prints as much information as possible and + * an error, it just prints as much information as possible and * then its up to the user to decide what to do. * * Returns 0 if no errors were found @@ -92,7 +92,7 @@ #endif /* VERBOSE_ERRORS */ }; -const char *_errlog_initiator[] = { +const char *_errlog_initiator[] = { "Unknown or not applicable", "CPU", "PCI", @@ -101,7 +101,7 @@ "Power management" }; -const char *_errlog_target[] = { +const char *_errlog_target[] = { "Unknown or not applicable", "CPU", "PCI", @@ -128,7 +128,7 @@ return 0; } if (error_log.version != 1) - printk(KERN_WARNING "Unknown version (%d), please implement me\n", + printk(KERN_WARNING "Unknown version (%d), please implement me\n", error_log.version); switch (error_log.disposition) { @@ -139,19 +139,19 @@ printk("We have a really serious Problem!\n"); case DISP_LIMITED_RECOVERY: printk("Error classification\n"); - printk("Severity : %s\n", + printk("Severity : %s\n", ppc_rtas_errorlog_check_severity (error_log)); - printk("Initiator : %s\n", + printk("Initiator : %s\n", ppc_rtas_errorlog_check_initiator (error_log)); - printk("Target : %s\n", + printk("Target : %s\n", ppc_rtas_errorlog_check_target (error_log)); - printk("Type : %s\n", + printk("Type : %s\n", ppc_rtas_errorlog_check_type (error_log)); - printk("Ext. log : %s\n", + printk("Ext. log : %s\n", ppc_rtas_errorlog_check_extended (error_log)); if (error_log.extended) ppc_rtas_errorlog_disect_extended (logdata); - return 1; + return 1; default: /* nothing */ break; @@ -174,8 +174,8 @@ "uncorrectable ECC error", "corrected ECC error" /* 10 */ }; - if (error_log.type == TYPE_EPOW) - return "EPOW"; + if (error_log.type == TYPE_EPOW) + return "EPOW"; if (error_log.type >= TYPE_PMGM_POWER_SW_ON) return "PowerMGM Event (not handled right now)"; return _errlog_type[error_log.type]; diff -urN linux-2.4.21/arch/ppc/platforms/error_log.h linux-2.4.22/arch/ppc/platforms/error_log.h --- linux-2.4.21/arch/ppc/platforms/error_log.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/error_log.h 2003-08-25 04:44:40.000000000 -0700 @@ -45,7 +45,7 @@ #define TYPE_ECC_UNCORR 0x09 #define TYPE_ECC_CORR 0x0a #define TYPE_EPOW 0x40 -/* I don't add PowerMGM events right now, this is a different topic */ +/* I don't add PowerMGM events right now, this is a different topic */ #define TYPE_PMGM_POWER_SW_ON 0x60 #define TYPE_PMGM_POWER_SW_OFF 0x61 #define TYPE_PMGM_LID_OPEN 0x62 diff -urN linux-2.4.21/arch/ppc/platforms/gemini.h linux-2.4.22/arch/ppc/platforms/gemini.h --- linux-2.4.21/arch/ppc/platforms/gemini.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/gemini.h 2003-08-25 04:44:40.000000000 -0700 @@ -2,7 +2,7 @@ * arch/ppc/platforms/gemini.h * * - * Onboard registers and descriptions for Synergy Microsystems' + * Onboard registers and descriptions for Synergy Microsystems' * "Gemini" boards. * */ diff -urN linux-2.4.21/arch/ppc/platforms/gemini_pci.c linux-2.4.22/arch/ppc/platforms/gemini_pci.c --- linux-2.4.21/arch/ppc/platforms/gemini_pci.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/gemini_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -92,7 +92,7 @@ { int i; struct pci_dev *dev; - + pci_for_each_dev(dev) { for(i = 0; i < 6; i++) { if (dev->resource[i].flags & IORESOURCE_IO) { @@ -109,7 +109,7 @@ void __init gemini_find_bridges(void) { struct pci_controller* hose; - + ppc_md.pcibios_fixup = gemini_pcibios_fixup; hose = pcibios_alloc_controller(); diff -urN linux-2.4.21/arch/ppc/platforms/gemini_prom.S linux-2.4.22/arch/ppc/platforms/gemini_prom.S --- linux-2.4.21/arch/ppc/platforms/gemini_prom.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/gemini_prom.S 2003-08-25 04:44:40.000000000 -0700 @@ -40,7 +40,7 @@ isync #if 0 /* zero out the bats now that the MMU is off */ -prom_no_mmu: +prom_no_mmu: li r3,0 mtspr IBAT0U,r3 mtspr IBAT0L,r3 diff -urN linux-2.4.21/arch/ppc/platforms/gemini_setup.c linux-2.4.22/arch/ppc/platforms/gemini_setup.c --- linux-2.4.21/arch/ppc/platforms/gemini_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/gemini_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -154,7 +154,7 @@ if (smp_processor_id()) { static short ratelimit; if (!ratelimit++) - printk(KERN_ERR "%s: unexpected heartbeat on cpu %d\n", + printk(KERN_ERR "%s: unexpected heartbeat on cpu %d\n", __FUNCTION__, smp_processor_id()); return; } diff -urN linux-2.4.21/arch/ppc/platforms/ibm405.h linux-2.4.22/arch/ppc/platforms/ibm405.h --- linux-2.4.21/arch/ppc/platforms/ibm405.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/platforms/ibm405.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,332 @@ +/* + * ibm405.h + * + * This was derived from the ppc4xx.h and contains + * common 405 offsets + * + * Armin Kuster akuster@pacbell.net + * Jan, 2002 + * + * + * Copyright 2002 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + * Version 1.0 (02/01/17) - A. Kuster + * Initial version - moved 405 specific out of the other core.h's + * + * Version 1.0 (02/08/02) - A. Kuster + * removed DCRN_UIC1_BASE to NP405L & H + * + * Version 1.2 (05/29/02) - Akuster + * removed DCRN_MALRXCTP2R etc, alread in ibmnp405.h + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM405_H__ +#define __ASM_IBM405_H__ + +#ifdef DCRN_BE_BASE +#define DCRN_BEAR (DCRN_BE_BASE + 0x0) /* Bus Error Address Register */ +#define DCRN_BESR (DCRN_BE_BASE + 0x1) /* Bus Error Syndrome Register */ +#endif +/* DCRN_BESR */ +#define BESR_DSES 0x80000000 /* Data-Side Error Status */ +#define BESR_DMES 0x40000000 /* DMA Error Status */ +#define BESR_RWS 0x20000000 /* Read/Write Status */ +#define BESR_ETMASK 0x1C000000 /* Error Type */ +#define ET_PROT 0 +#define ET_PARITY 1 +#define ET_NCFG 2 +#define ET_BUSERR 4 +#define ET_BUSTO 6 + +/* Clock and power management shifts for emacs */ +#define IBM_CPM_EMMII 0 /* Shift value for MII */ +#define IBM_CPM_EMRX 1 /* Shift value for recv */ +#define IBM_CPM_EMTX 2 /* Shift value for MAC */ + +#ifdef DCRN_CHCR_BASE +#define DCRN_CHCR0 (DCRN_CHCR_BASE + 0x0) /* Chip Control Register 1 */ +#define DCRN_CHCR1 (DCRN_CHCR_BASE + 0x1) /* Chip Control Register 2 */ +#endif +#define CHR1_PCIPW 0x00008000 /* PCI Int enable/Peripheral Write enable */ + +#ifdef DCRN_CHPSR_BASE +#define DCRN_CHPSR (DCRN_CHPSR_BASE + 0x0) /* Chip Pin Strapping */ +#endif + +#ifdef DCRN_CPMFR_BASE +#define DCRN_CPMFR (DCRN_CPMFR_BASE + 0x0) /* CPM Force */ +#endif + +#ifdef DCRN_CPMSR_BASE +#define DCRN_CPMSR (DCRN_CPMSR_BASE + 0x0) /* CPM Status */ +#define DCRN_CPMER (DCRN_CPMSR_BASE + 0x1) /* CPM Enable */ +#endif + +#ifdef DCRN_DCP0_BASE +/* Decompression Controller Address */ +#define DCRN_DCP0_CFGADDR (DCRN_DCP0_BASE + 0x0) +/* Decompression Controller Data */ +#define DCRN_DCP0_CFGDATA (DCRN_DCP0_BASE + 0x1) +#else +#define DCRN_DCP0_CFGADDR 0x0 +#define DCRN_DCP0_CFGDATA 0x0 +#endif + +#ifdef DCRN_DMA0_BASE +/* DMA Channel Control Register 0 */ +#define DCRN_DMACR0 (DCRN_DMA0_BASE + 0x0) +#define DCRN_DMACT0 (DCRN_DMA0_BASE + 0x1) /* DMA Count Register 0 */ +/* DMA Destination Address Register 0 */ +#define DCRN_DMADA0 (DCRN_DMA0_BASE + 0x2) +/* DMA Source Address Register 0 */ +#define DCRN_DMASA0 (DCRN_DMA0_BASE + 0x3) +#ifdef DCRNCAP_DMA_CC +/* DMA Chained Count Register 0 */ +#define DCRN_DMACC0 (DCRN_DMA0_BASE + 0x4) +#endif +#ifdef DCRNCAP_DMA_SG +/* DMA Scatter/Gather Descriptor Addr 0 */ +#define DCRN_ASG0 (DCRN_DMA0_BASE + 0x4) +#endif +#endif + +#ifdef DCRN_DMA1_BASE +/* DMA Channel Control Register 1 */ +#define DCRN_DMACR1 (DCRN_DMA1_BASE + 0x0) +#define DCRN_DMACT1 (DCRN_DMA1_BASE + 0x1) /* DMA Count Register 1 */ +/* DMA Destination Address Register 1 */ +#define DCRN_DMADA1 (DCRN_DMA1_BASE + 0x2) +/* DMA Source Address Register 1 */ +#define DCRN_DMASA1 (DCRN_DMA1_BASE + 0x3) /* DMA Source Address Register 1 */ +#ifdef DCRNCAP_DMA_CC +/* DMA Chained Count Register 1 */ +#define DCRN_DMACC1 (DCRN_DMA1_BASE + 0x4) +#endif +#ifdef DCRNCAP_DMA_SG +/* DMA Scatter/Gather Descriptor Addr 1 */ +#define DCRN_ASG1 (DCRN_DMA1_BASE + 0x4) +#endif +#endif + +#ifdef DCRN_DMA2_BASE +#define DCRN_DMACR2 (DCRN_DMA2_BASE + 0x0) /* DMA Channel Control Register 2 */ +#define DCRN_DMACT2 (DCRN_DMA2_BASE + 0x1) /* DMA Count Register 2 */ +#define DCRN_DMADA2 (DCRN_DMA2_BASE + 0x2) /* DMA Destination Address Register 2 */ +#define DCRN_DMASA2 (DCRN_DMA2_BASE + 0x3) /* DMA Source Address Register 2 */ +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC2 (DCRN_DMA2_BASE + 0x4) /* DMA Chained Count Register 2 */ +#endif +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG2 (DCRN_DMA2_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 2 */ +#endif +#endif + +#ifdef DCRN_DMA3_BASE +#define DCRN_DMACR3 (DCRN_DMA3_BASE + 0x0) /* DMA Channel Control Register 3 */ +#define DCRN_DMACT3 (DCRN_DMA3_BASE + 0x1) /* DMA Count Register 3 */ +#define DCRN_DMADA3 (DCRN_DMA3_BASE + 0x2) /* DMA Destination Address Register 3 */ +#define DCRN_DMASA3 (DCRN_DMA3_BASE + 0x3) /* DMA Source Address Register 3 */ +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC3 (DCRN_DMA3_BASE + 0x4) /* DMA Chained Count Register 3 */ +#endif +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG3 (DCRN_DMA3_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 3 */ +#endif +#endif + +#ifdef DCRN_DMASR_BASE +#define DCRN_DMASR (DCRN_DMASR_BASE + 0x0) /* DMA Status Register */ +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASGC (DCRN_DMASR_BASE + 0x3) /* DMA Scatter/Gather Command */ +/* don't know if these two registers always exist if scatter/gather exists */ +#define DCRN_POL (DCRN_DMASR_BASE + 0x6) /* DMA Polarity Register */ +#define DCRN_SLP (DCRN_DMASR_BASE + 0x5) /* DMA Sleep Register */ +#endif +#endif + +#ifdef DCRN_EBC_BASE +#define DCRN_EBCCFGADR (DCRN_EBC_BASE + 0x0) /* Peripheral Controller Address */ +#define DCRN_EBCCFGDATA (DCRN_EBC_BASE + 0x1) /* Peripheral Controller Data */ +#endif + +#ifdef DCRN_EXIER_BASE +#define DCRN_EXIER (DCRN_EXIER_BASE + 0x0) /* External Interrupt Enable Register */ +#endif + +#ifdef DCRN_EXISR_BASE +#define DCRN_EXISR (DCRN_EXISR_BASE + 0x0) /* External Interrupt Status Register */ +#endif + +#define EXIER_CIE 0x80000000 /* Critical Interrupt Enable */ +#define EXIER_SRIE 0x08000000 /* Serial Port Rx Int. Enable */ +#define EXIER_STIE 0x04000000 /* Serial Port Tx Int. Enable */ +#define EXIER_JRIE 0x02000000 /* JTAG Serial Port Rx Int. Enable */ +#define EXIER_JTIE 0x01000000 /* JTAG Serial Port Tx Int. Enable */ +#define EXIER_D0IE 0x00800000 /* DMA Channel 0 Interrupt Enable */ +#define EXIER_D1IE 0x00400000 /* DMA Channel 1 Interrupt Enable */ +#define EXIER_D2IE 0x00200000 /* DMA Channel 2 Interrupt Enable */ +#define EXIER_D3IE 0x00100000 /* DMA Channel 3 Interrupt Enable */ +#define EXIER_E0IE 0x00000010 /* External Interrupt 0 Enable */ +#define EXIER_E1IE 0x00000008 /* External Interrupt 1 Enable */ +#define EXIER_E2IE 0x00000004 /* External Interrupt 2 Enable */ +#define EXIER_E3IE 0x00000002 /* External Interrupt 3 Enable */ +#define EXIER_E4IE 0x00000001 /* External Interrupt 4 Enable */ + +#ifdef DCRN_IOCR_BASE +#define DCRN_IOCR (DCRN_IOCR_BASE + 0x0) /* Input/Output Configuration Register */ +#endif +#define IOCR_E0TE 0x80000000 +#define IOCR_E0LP 0x40000000 +#define IOCR_E1TE 0x20000000 +#define IOCR_E1LP 0x10000000 +#define IOCR_E2TE 0x08000000 +#define IOCR_E2LP 0x04000000 +#define IOCR_E3TE 0x02000000 +#define IOCR_E3LP 0x01000000 +#define IOCR_E4TE 0x00800000 +#define IOCR_E4LP 0x00400000 +#define IOCR_EDT 0x00080000 +#define IOCR_SOR 0x00040000 +#define IOCR_EDO 0x00008000 +#define IOCR_2XC 0x00004000 +#define IOCR_ATC 0x00002000 +#define IOCR_SPD 0x00001000 +#define IOCR_BEM 0x00000800 +#define IOCR_PTD 0x00000400 +#define IOCR_ARE 0x00000080 +#define IOCR_DRC 0x00000020 +#define IOCR_RDM(x) (((x) & 0x3) << 3) +#define IOCR_TCS 0x00000004 +#define IOCR_SCS 0x00000002 +#define IOCR_SPC 0x00000001 + +#define DCRN_MALCR(base) (base + 0x0) /* MAL Configuration */ +#define DCRN_MALDBR(base) ((base) + 0x3) /* Debug Register */ +#define DCRN_MALESR(base) ((base) + 0x1) /* Error Status */ +#define DCRN_MALIER(base) ((base) + 0x2) /* Interrupt Enable */ +#define DCRN_MALTXCARR(base) ((base) + 0x5) /* TX Channed Active Reset Register */ +#define DCRN_MALTXCASR(base) ((base) + 0x4) /* TX Channel Active Set Register */ +#define DCRN_MALTXDEIR(base) ((base) + 0x7) /* Tx Descriptor Error Interrupt */ +#define DCRN_MALTXEOBISR(base) ((base) + 0x6) /* Tx End of Buffer Interrupt Status */ +#define DCRN_MALRXCARR(base) ((base) + 0x11) /* RX Channed Active Reset Register */ +#define DCRN_MALRXCASR(base) ((base) + 0x10) /* RX Channel Active Set Register */ +#define DCRN_MALRXDEIR(base) ((base) + 0x13) /* Rx Descriptor Error Interrupt */ +#define DCRN_MALRXEOBISR(base) ((base) + 0x12) /* Rx End of Buffer Interrupt Status */ +#define DCRN_MALRXCTP0R(base) ((base) + 0x40) /* Channel Rx 0 Channel Table Pointer */ +#define DCRN_MALRXCTP1R(base) ((base) + 0x41) /* Channel Rx 1 Channel Table Pointer */ +#define DCRN_MALTXCTP0R(base) ((base) + 0x20) /* Channel Tx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP1R(base) ((base) + 0x21) /* Channel Tx 1 Channel Table Pointer */ +#define DCRN_MALTXCTP2R(base) ((base) + 0x22) /* Channel Tx 2 Channel Table Pointer */ +#define DCRN_MALTXCTP3R(base) ((base) + 0x23) /* Channel Tx 3 Channel Table Pointer */ +#define DCRN_MALRCBS0(base) ((base) + 0x60) /* Channel Rx 0 Channel Buffer Size */ +#define DCRN_MALRCBS1(base) ((base) + 0x61) /* Channel Rx 1 Channel Buffer Size */ + + /* DCRN_MALCR */ +#define MALCR_MMSR 0x80000000 /* MAL Software reset */ +#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */ +#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */ +#define MALCR_PLBP_3 0x00C00000 /* highest */ +#define MALCR_GA 0x00200000 /* Guarded Active Bit */ +#define MALCR_OA 0x00100000 /* Ordered Active Bit */ +#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */ +#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */ +#define MALCR_PLBLT_2 0x00020000 +#define MALCR_PLBLT_3 0x00010000 +#define MALCR_PLBLT_4 0x00008000 +#define MALCR_PLBLT_DEFAULT 0x00078000 /* JSP: Is this a valid default?? */ +#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */ +#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */ +#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */ +#define MALCR_LEA 0x00000002 /* Locked Error Active */ +#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */ +/* DCRN_MALESR */ +#define MALESR_EVB 0x80000000 /* Error Valid Bit */ +#define MALESR_CIDRX 0x40000000 /* Channel ID Receive */ +#define MALESR_DE 0x00100000 /* Descriptor Error */ +#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */ +#define MALESR_OTE 0x00040000 /* OPB Timeout Error */ +#define MALESR_OSE 0x00020000 /* OPB Slave Error */ +#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */ +#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */ +#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */ +#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */ +#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */ +#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */ +/* DCRN_MALIER */ +#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */ +#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */ +#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */ +#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */ +#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */ +/* DCRN_MALTXEOBISR */ +#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */ +#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */ + +#ifdef DCRN_PLB0_BASE +#define DCRN_PLB0_BESR (DCRN_PLB0_BASE + 0x0) +#define DCRN_PLB0_BEAR (DCRN_PLB0_BASE + 0x2) +/* doesn't exist on stb03xxx? */ +#define DCRN_PLB0_ACR (DCRN_PLB0_BASE + 0x3) +#endif + +#ifdef DCRN_PLB1_BASE +#define DCRN_PLB1_BESR (DCRN_PLB1_BASE + 0x0) +#define DCRN_PLB1_BEAR (DCRN_PLB1_BASE + 0x1) +/* doesn't exist on stb03xxx? */ +#define DCRN_PLB1_ACR (DCRN_PLB1_BASE + 0x2) +#endif + +#ifdef DCRN_PLLMR_BASE +#define DCRN_PLLMR (DCRN_PLLMR_BASE + 0x0) /* PL1 Mode */ +#endif + +#ifdef DCRN_POB0_BASE +#define DCRN_POB0_BESR0 (DCRN_POB0_BASE + 0x0) +#define DCRN_POB0_BEAR (DCRN_POB0_BASE + 0x2) +#define DCRN_POB0_BESR1 (DCRN_POB0_BASE + 0x4) +#endif + +#define DCRN_UIC_SR(base) (base + 0x0) +#define DCRN_UIC_ER(base) (base + 0x2) +#define DCRN_UIC_CR(base) (base + 0x3) +#define DCRN_UIC_PR(base) (base + 0x4) +#define DCRN_UIC_TR(base) (base + 0x5) +#define DCRN_UIC_MSR(base) (base + 0x6) +#define DCRN_UIC_VR(base) (base + 0x7) +#define DCRN_UIC_VCR(base) (base + 0x8) + +#ifdef DCRN_SDRAM0_BASE +#define DCRN_SDRAM0_CFGADDR (DCRN_SDRAM0_BASE + 0x0) /* Memory Controller Address */ +#define DCRN_SDRAM0_CFGDATA (DCRN_SDRAM0_BASE + 0x1) /* Memory Controller Data */ +#endif + +#ifdef DCRN_OCM0_BASE +#define DCRN_OCMISARC (DCRN_OCM0_BASE + 0x0) /* OCM Instr Side Addr Range Compare */ +#define DCRN_OCMISCR (DCRN_OCM0_BASE + 0x1) /* OCM Instr Side Control */ +#define DCRN_OCMDSARC (DCRN_OCM0_BASE + 0x2) /* OCM Data Side Addr Range Compare */ +#define DCRN_OCMDSCR (DCRN_OCM0_BASE + 0x3) /* OCM Data Side Control */ +#endif + +#endif /* __ASM_IBM405_H__ */ +#endif /* __KERNEL__ */ diff -urN linux-2.4.21/arch/ppc/platforms/ibm405gp.c linux-2.4.22/arch/ppc/platforms/ibm405gp.c --- linux-2.4.21/arch/ppc/platforms/ibm405gp.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/platforms/ibm405gp.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,107 @@ +/* + * + * Copyright 2000-2001 MontaVista Software Inc. + * Original author: Armin Kuster akuster@mvista.com + * + * Module name: ibm405gp.c + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct ocp_func_emac_data ibm405gp_emac0_def = { + .zmii_idx = -1, /* ZMII device index */ + .zmii_mux = 0, /* ZMII input of this EMAC */ + .mal_idx = 0, /* MAL device index */ + .mal_rx_chan = 0, /* MAL rx channel number */ + .mal_tx1_chan = 0, /* MAL tx channel 1 number */ + .mal_tx2_chan = 1, /* MAL tx channel 2 number */ + .wol_irq = BL_MAC_WOL, /* WOL interrupt number */ + .mdio_idx = -1, /* No shared MDIO */ +}; + +static struct ocp_func_mal_data ibm405gp_mal0_def = { + .num_tx_chans = 2*EMAC_NUMS, /* Number of TX channels */ + .num_rx_chans = EMAC_NUMS, /* Number of RX channels */ +}; + +struct ocp_def core_ocp[] __initdata = { + { .vendor = OCP_VENDOR_IBM, + .function = OCP_FUNC_OPB, + .index = 0, + .paddr = OPB_BASE_START, + .irq = OCP_IRQ_NA, + .pm = OCP_CPM_NA, + }, + { .vendor = OCP_VENDOR_IBM, + .function = OCP_FUNC_16550, + .index = 0, + .paddr = UART0_IO_BASE, + .irq = UART0_INT, + .pm = IBM_CPM_UART0 + }, + { .vendor = OCP_VENDOR_IBM, + .function = OCP_FUNC_16550, + .index = 1, + .paddr = UART1_IO_BASE, + .irq = UART1_INT, + .pm = IBM_CPM_UART1 + }, + { .vendor = OCP_VENDOR_IBM, + .function = OCP_FUNC_IIC, + .paddr = IIC0_BASE, + .irq = IIC0_IRQ, + .pm = IBM_CPM_IIC0 + }, + { .vendor = OCP_VENDOR_IBM, + .function = OCP_FUNC_GPIO, + .paddr = GPIO0_BASE, + .irq = OCP_IRQ_NA, + .pm = IBM_CPM_GPIO0 + }, + { .vendor = OCP_VENDOR_IBM, + .function = OCP_FUNC_MAL, + .paddr = OCP_PADDR_NA, + .irq = OCP_IRQ_NA, + .pm = OCP_CPM_NA, + .additions = &ibm405gp_mal0_def, + }, + { .vendor = OCP_VENDOR_IBM, + .function = OCP_FUNC_EMAC, + .index = 0, + .paddr = EMAC0_BASE, + .irq = BL_MAC_ETH0, + .pm = IBM_CPM_EMAC0, + .additions = &ibm405gp_emac0_def, + }, + { .vendor = OCP_VENDOR_INVALID + } +}; diff -urN linux-2.4.21/arch/ppc/platforms/ibm405gp.h linux-2.4.22/arch/ppc/platforms/ibm405gp.h --- linux-2.4.21/arch/ppc/platforms/ibm405gp.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/platforms/ibm405gp.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,193 @@ +/* + * ibm405gp.h + * + * This was derived from the ppc4xx.h and all 405GP specific + * definition and board inclusions were moved here. + * + * Original author: Armin Kuster akuster@mvista.com + * Oct, 2001 + * + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM405GP_H__ +#define __ASM_IBM405GP_H__ + +#include + +/* ibm405.h is included at the bottom of this file */ + +/* PCI + * PCI Bridge config reg definitions + * see 17-19 of manual + */ + +#define PPC405_PCI_CONFIG_ADDR 0xeec00000 +#define PPC405_PCI_CONFIG_DATA 0xeec00004 + +#define PPC405_PCI_PHY_MEM_BASE 0x80000000 /* hose_a->pci_mem_offset */ + /* setbat */ +#define PPC405_PCI_MEM_BASE PPC405_PCI_PHY_MEM_BASE /* setbat */ +#define PPC405_PCI_PHY_IO_BASE 0xe8000000 /* setbat */ +#define PPC405_PCI_IO_BASE PPC405_PCI_PHY_IO_BASE /* setbat */ + +#define PPC405_PCI_LOWER_MEM 0x80000000 /* hose_a->mem_space.start */ +#define PPC405_PCI_UPPER_MEM 0xBfffffff /* hose_a->mem_space.end */ +#define PPC405_PCI_LOWER_IO 0x00000000 /* hose_a->io_space.start */ +#define PPC405_PCI_UPPER_IO 0x0000ffff /* hose_a->io_space.end */ + +#define PPC405_ISA_IO_BASE PPC405_PCI_IO_BASE + +#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +#define OPB_BASE_START 0x40000000 +#define EBIU_BASE_START 0xF0100000 + +/* serial port defines */ +#define RS_TABLE_SIZE 2 + +#define UART0_INT 0 +#define UART1_INT 1 + +#define PCIL0_BASE 0xEF400000 +#define UART0_IO_BASE 0xEF600300 +#define UART1_IO_BASE 0xEF600400 +#define IIC0_BASE 0xEF600500 +#define OPB0_BASE 0xEF600600 +#define GPIO0_BASE 0xEF600700 +#define EMAC0_BASE 0xEF600800 +#define BL_MAC_WOL 9 /* WOL */ +#define BL_MAL_SERR 10 /* MAL SERR */ +#define BL_MAL_TXDE 13 /* MAL TXDE */ +#define BL_MAL_RXDE 14 /* MAL RXDE */ +#define BL_MAL_TXEOB 11 /* MAL TX EOB */ +#define BL_MAL_RXEOB 12 /* MAL RX EOB */ +#define BL_MAC_ETH0 15 /* MAC */ + +#define EMAC_NUMS 1 +#define IIC0_IRQ 2 +#define IIC1_IRQ 0 + +#define IIC_OWN 0x55 +#define IIC_CLOCK 50 +#define BD_EMAC_ADDR(e,i) bi_enetaddr[i] + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: (u8 *)UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#if defined(CONFIG_UART0_TTYS0) +#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) +#endif + +#if defined(CONFIG_UART0_TTYS1) +#define SERIAL_DEBUG_IO_BASE UART1_IO_BASE +#define SERIAL_PORT_DFNS \ + STD_UART_OP(1) \ + STD_UART_OP(0) +#endif + +/* DCR defines */ +#define DCRN_CHCR_BASE 0x0B1 +#define DCRN_CHPSR_BASE 0x0B4 +#define DCRN_CPMSR_BASE 0x0B8 +#define DCRN_CPMFR_BASE 0x0BA + +#define CHR0_U0EC 0x00000080 /* Select external clock for UART0 */ +#define CHR0_U1EC 0x00000040 /* Select external clock for UART1 */ +#define CHR0_UDIV 0x0000003E /* UART internal clock divisor */ +#define CHR1_CETE 0x00800000 /* CPU external timer enable */ + +#define DCRN_CHPSR_BASE 0x0B4 +#define PSR_PLL_FWD_MASK 0xC0000000 +#define PSR_PLL_FDBACK_MASK 0x30000000 +#define PSR_PLL_TUNING_MASK 0x0E000000 +#define PSR_PLB_CPU_MASK 0x01800000 +#define PSR_OPB_PLB_MASK 0x00600000 +#define PSR_PCI_PLB_MASK 0x00180000 +#define PSR_EB_PLB_MASK 0x00060000 +#define PSR_ROM_WIDTH_MASK 0x00018000 +#define PSR_ROM_LOC 0x00004000 +#define PSR_PCI_ASYNC_EN 0x00001000 +#define PSR_PCI_ARBIT_EN 0x00000400 + +#define IBM_CPM_IIC0 0x80000000 /* IIC interface */ +#define IBM_CPM_PCI 0x40000000 /* PCI bridge */ +#define IBM_CPM_CPU 0x20000000 /* processor core */ +#define IBM_CPM_DMA 0x10000000 /* DMA controller */ +#define IBM_CPM_OPB 0x08000000 /* PLB to OPB bridge */ +#define IBM_CPM_DCP 0x04000000 /* CodePack */ +#define IBM_CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */ +#define IBM_CPM_SDRAM0 0x01000000 /* SDRAM memory controller */ +#define IBM_CPM_PLB 0x00800000 /* PLB bus arbiter */ +#define IBM_CPM_GPIO0 0x00400000 /* General Purpose IO (??) */ +#define IBM_CPM_UART0 0x00200000 /* serial port 0 */ +#define IBM_CPM_UART1 0x00100000 /* serial port 1 */ +#define IBM_CPM_UIC 0x00080000 /* Universal Interrupt Controller */ +#define IBM_CPM_TMRCLK 0x00040000 /* CPU timers */ +#define IBM_CPM_EMAC0 0x00020000 /* on-chip ethernet MM unit */ +#define DFLT_IBM4xx_PM ~(IBM_CPM_PCI | IBM_CPM_CPU | IBM_CPM_DMA \ + | IBM_CPM_OPB | IBM_CPM_EBC \ + | IBM_CPM_SDRAM0 | IBM_CPM_PLB \ + | IBM_CPM_UIC | IBM_CPM_TMRCLK) + +#define DCRN_DMA0_BASE 0x100 +#define DCRN_DMA1_BASE 0x108 +#define DCRN_DMA2_BASE 0x110 +#define DCRN_DMA3_BASE 0x118 +#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ +#define DCRN_DMASR_BASE 0x120 +#define DCRN_EBC_BASE 0x012 +#define DCRN_DCP0_BASE 0x014 +#define DCRN_MAL_BASE 0x180 +#define DCRN_OCM0_BASE 0x018 +#define DCRN_PLB0_BASE 0x084 +#define DCRN_PLLMR_BASE 0x0B0 +#define DCRN_POB0_BASE 0x0A0 +#define DCRN_SDRAM0_BASE 0x010 +#define DCRN_UIC0_BASE 0x0C0 +#define UIC0 DCRN_UIC0_BASE + +#include + +#endif /* __ASM_IBM405GP_H__ */ +#endif /* __KERNEL__ */ diff -urN linux-2.4.21/arch/ppc/platforms/ibm_ocp.h linux-2.4.22/arch/ppc/platforms/ibm_ocp.h --- linux-2.4.21/arch/ppc/platforms/ibm_ocp.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/platforms/ibm_ocp.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,152 @@ +/* + * arch/ppc/platforms/ibm_ocp.h + * + * Definitions for the on-chip peripherals on the IBM + * PPC405GP embedded processor. + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM_OCP_H__ +#define __ASM_IBM_OCP_H__ + +#ifndef __ASSEMBLY__ +#include + +// +// TODO: DEPRECATE THIS FILE ! +// + + /* PCI 32 */ + +struct pmm_regs { + u32 la; + u32 ma; + u32 pcila; + u32 pciha; +}; + +typedef struct pcil0_regs { + struct pmm_regs pmm[3]; + u32 ptm1ms; + u32 ptm1la; + u32 ptm2ms; + u32 ptm2la; +} pci0_t; + +/* Serial Ports */ + +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +typedef struct NS16550 { + u8 rbr; /* 0 */ + u8 ier; /* 1 */ + u8 fcr; /* 2 */ + u8 lcr; /* 3 */ + u8 mcr; /* 4 */ + u8 lsr; /* 5 */ + u8 msr; /* 6 */ + u8 scr; /* 7 */ +} uart_t; + +/* I2c */ +typedef struct iic_regs { + u16 mdbuf; + u16 sbbuf; + u8 lmadr; + u8 hmadr; + u8 cntl; + u8 mdcntl; + u8 sts; + u8 extsts; + u8 lsadr; + u8 hsadr; + u8 clkdiv; + u8 intmsk; + u8 xfrcnt; + u8 xtcntlss; + u8 directcntl; +} iic_t; + +/* OPB arbiter */ +typedef struct opb { + u8 pr; + u8 cr; +} opb_t; + +/* General purpose i/o */ + +typedef struct gpio_regs { + u32 or; + u32 tcr; + u32 pad[4]; + u32 odr; + u32 ir; +} gpio_t; + +/* Structure of the memory mapped IDE control. +*/ +typedef struct ide_regs { + unsigned int si_stat; /* IDE status */ + unsigned int si_intenable; /* IDE interrupt enable */ + unsigned int si_control; /* IDE control */ + unsigned int pad0[0x3d]; + unsigned int si_c0rt; /* Chan 0 Register transfer timing */ + unsigned int si_c0fpt; /* Chan 0 Fast PIO transfer timing */ + unsigned int si_c0timo; /* Chan 0 timeout */ + unsigned int pad1[2]; + unsigned int si_c0d0u; /* Chan 0 UDMA transfer timing */ +#define si_c0d0m si_c0d0u /* Chan 0 Multiword DMA timing */ + unsigned int pad2; + unsigned int si_c0d1u; /* Chan 0 dev 1 UDMA timing */ +#define si_c0d1m si_c0d1u /* Chan 0 dev 1 Multiword DMA timing */ + unsigned int si_c0c; /* Chan 0 Control */ + unsigned int si_c0s0; /* Chan 0 Status 0 */ + unsigned int si_c0ie; /* Chan 0 Interrupt Enable */ + unsigned int si_c0s1; /* Chan 0 Status 0 */ + unsigned int pad4[4]; + unsigned int si_c0dcm; /* Chan 0 DMA Command */ + unsigned int si_c0tb; /* Chan 0 PRD Table base address */ + unsigned int si_c0dct; /* Chan 0 DMA Count */ + unsigned int si_c0da; /* Chan 0 DMA Address */ + unsigned int si_c0sr; /* Chan 0 Slew Rate Output Control */ + unsigned char pad5[0xa2]; + unsigned short si_c0adc; /* Chan 0 Alt status/control */ + unsigned char si_c0d; /* Chan 0 data */ + unsigned char si_c0ef; /* Chan 0 error/features */ + unsigned char si_c0sct; /* Chan 0 sector count */ + unsigned char si_c0sn; /* Chan 0 sector number */ + unsigned char si_c0cl; /* Chan 0 cylinder low */ + unsigned char si_c0ch; /* Chan 0 cylinder high */ + unsigned char si_c0dh; /* Chan 0 device/head */ + unsigned char si_c0scm; /* Chan 0 status/command */ +} ide_t; + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_IBM_OCP_H__ */ +#endif /* __KERNEL__ */ diff -urN linux-2.4.21/arch/ppc/platforms/lopec_pci.c linux-2.4.22/arch/ppc/platforms/lopec_pci.c --- linux-2.4.21/arch/ppc/platforms/lopec_pci.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/lopec_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/platforms/lopec_pci.c - * + * * PCI setup routines for the Motorola LoPEC. * * Author: Dan Cox diff -urN linux-2.4.21/arch/ppc/platforms/lopec_setup.c linux-2.4.22/arch/ppc/platforms/lopec_setup.c --- linux-2.4.21/arch/ppc/platforms/lopec_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/lopec_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/platforms/lopec_setup.c - * + * * Setup routines for the Motorola LoPEC. * * Author: Dan Cox @@ -48,7 +48,7 @@ #include #include #include - + extern char saved_command_line[]; extern void lopec_find_bridges(void); @@ -314,7 +314,7 @@ /* Assume early_serial_setup() doesn't modify serial_req */ serial_req.line = 1; serial_req.port = 1; - serial_req.irq = UART1_INT; + serial_req.irq = UART1_INT; serial_req.iomem_base = ioremap(UART1_PORT, 8); #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) @@ -327,7 +327,7 @@ serial_req.line = 2; serial_req.port = 2; - serial_req.irq = UART2_INT; + serial_req.irq = UART2_INT; serial_req.iomem_base = ioremap(UART2_PORT, 8); #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) @@ -372,7 +372,7 @@ #endif #ifdef CONFIG_PPCBUG_NVRAM - /* Read in NVRAM data */ + /* Read in NVRAM data */ init_prep_nvram(); /* if no bootargs, look in NVRAM */ diff -urN linux-2.4.21/arch/ppc/platforms/pal4.h linux-2.4.22/arch/ppc/platforms/pal4.h --- linux-2.4.21/arch/ppc/platforms/pal4.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pal4.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/platforms/pal4.h - * + * * Definitions for SBS Palomar IV board * * Author: Dan Cox diff -urN linux-2.4.21/arch/ppc/platforms/pal4_pci.c linux-2.4.22/arch/ppc/platforms/pal4_pci.c --- linux-2.4.21/arch/ppc/platforms/pal4_pci.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pal4_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,9 +1,9 @@ /* * arch/ppc/platforms/pal4_pci.c - * + * * PCI support for SBS Palomar IV * - * Author: Dan Cox + * Author: Dan Cox * * 2002 (c) MontaVista, Software, Inc. This file is licensed under * the terms of the GNU General Public License version 2. This program @@ -49,7 +49,7 @@ /* Could snatch these from the CPC700.... */ pci_init_resource(&hose->io_resource, - 0x0, + 0x0, 0x03ffffff, IORESOURCE_IO, "PCI host bridge"); @@ -65,10 +65,10 @@ hose->mem_space.start = 0x90000000; hose->mem_space.end = 0x9fffffff; hose->io_base_virt = (void *) 0xf8000000; - + setup_indirect_pci(hose, CPC700_PCI_CONFIG_ADDR, CPC700_PCI_CONFIG_DATA); - + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); ppc_md.pci_swizzle = common_swizzle; diff -urN linux-2.4.21/arch/ppc/platforms/pal4_serial.h linux-2.4.22/arch/ppc/platforms/pal4_serial.h --- linux-2.4.21/arch/ppc/platforms/pal4_serial.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pal4_serial.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * arch/ppc/platforms/pal4_serial.h - * - * Definitions for SBS PalomarIV serial support + * + * Definitions for SBS PalomarIV serial support * * Author: Dan Cox * diff -urN linux-2.4.21/arch/ppc/platforms/pal4_setup.c linux-2.4.22/arch/ppc/platforms/pal4_setup.c --- linux-2.4.21/arch/ppc/platforms/pal4_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pal4_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -133,7 +133,7 @@ { unsigned long l2; - TODC_INIT(TODC_TYPE_MK48T37, 0, 0, + TODC_INIT(TODC_TYPE_MK48T37, 0, 0, ioremap(PAL4_NVRAM, PAL4_NVRAM_SIZE), 8); pal4_find_bridges(); @@ -172,10 +172,10 @@ isa_io_base = 0 /*PAL4_ISA_IO_BASE*/; pci_dram_offset = 0 /*PAL4_PCI_SYS_MEM_BASE*/; - + ppc_md.setup_arch = pal4_setup_arch; ppc_md.show_cpuinfo = pal4_show_cpuinfo; - + ppc_md.find_end_of_memory = pal4_find_end_of_memory; ppc_md.setup_io_mappings = pal4_map_io; diff -urN linux-2.4.21/arch/ppc/platforms/pmac_backlight.c linux-2.4.22/arch/ppc/platforms/pmac_backlight.c --- linux-2.4.21/arch/ppc/platforms/pmac_backlight.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_backlight.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * Miscellaneous procedures for dealing with the PowerMac hardware. * Contains support for the backlight. - * + * * Copyright (C) 2000 Benjamin Herrenschmidt * */ @@ -38,7 +38,7 @@ int valid = 0; bk_node = find_devices("backlight"); - + #ifdef CONFIG_ADB_PMU /* Special case for the old PowerBook since I can't test on it */ backlight_autosave = machine_is_compatible("AAPL,3400/2400") @@ -58,7 +58,7 @@ return; backlighter = ctrler; backlighter_data = data; - + if (bk_node && !backlight_autosave) prop = get_property(bk_node, "bklt", NULL); else @@ -68,7 +68,7 @@ if (backlight_level > BACKLIGHT_MAX) backlight_level = BACKLIGHT_MAX; } - + #ifdef CONFIG_ADB_PMU if (backlight_autosave) { struct adb_request req; @@ -97,7 +97,7 @@ set_backlight_enable(int enable) { int rc; - + if (!backlighter) return -ENODEV; rc = backlighter->set_enable(enable, backlight_level, backlighter_data); @@ -118,7 +118,7 @@ set_backlight_level(int level) { int rc = 0; - + if (!backlighter) return -ENODEV; if (level < BACKLIGHT_MIN) diff -urN linux-2.4.21/arch/ppc/platforms/pmac_feature.c linux-2.4.22/arch/ppc/platforms/pmac_feature.c --- linux-2.4.21/arch/ppc/platforms/pmac_feature.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_feature.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,9 +8,9 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. - * - * TODO: - * + * + * TODO: + * * - Replace mdelay with some schedule loop if possible * - Shorten some obfuscated delays on some routines (like modem * power) @@ -66,7 +66,7 @@ /* * Helper functions regarding the various flavors of mac-io */ - + #define MAX_MACIO_CHIPS 2 enum { @@ -82,7 +82,7 @@ macio_intrepid, }; -static const char* macio_names[] __pmacdata = +static const char* macio_names[] __pmacdata = { "Unknown", "Grand Central", @@ -116,7 +116,7 @@ { while(child) { int i; - + for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++) if (child == macio_chips[i].of_node && (!type || macio_chips[i].type == type)) @@ -139,7 +139,7 @@ /* * Uninorth reg. access. Note that Uni-N regs are big endian */ - + #define UN_REG(r) (uninorth_base + ((r) >> 2)) #define UN_IN(r) (in_be32(UN_REG(r))) #define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) @@ -159,7 +159,7 @@ typedef int (*feature_call)(struct device_node* node, int param, int value); struct feature_table_entry { - unsigned int selector; + unsigned int selector; feature_call function; }; @@ -182,7 +182,7 @@ { struct macio_chip* macio; unsigned long flags; - + macio = macio_find(node, type); if (!macio) return -ENODEV; @@ -206,7 +206,7 @@ unsigned long flags; int htw, trans; unsigned long rmask; - + macio = macio_find(node, 0); if (!macio) return -ENODEV; @@ -226,7 +226,7 @@ #ifdef CONFIG_ADB_PMU if ((param & 0xfff) == PMAC_SCC_IRDA) pmu_enable_irled(1); -#endif /* CONFIG_ADB_PMU */ +#endif /* CONFIG_ADB_PMU */ LOCK(flags); fcr = MACIO_IN32(OHARE_FCR); /* Check if scc cell need enabling */ @@ -285,7 +285,7 @@ #ifdef CONFIG_ADB_PMU if ((param & 0xfff) == PMAC_SCC_IRDA) pmu_enable_irled(0); -#endif /* CONFIG_ADB_PMU */ +#endif /* CONFIG_ADB_PMU */ } return 0; } @@ -352,7 +352,7 @@ } else if (value == 0) { MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); } - + return 0; } @@ -362,7 +362,7 @@ struct macio_chip* macio; u8 gpio; unsigned long flags; - + macio = macio_find(node, macio_unknown); if (!macio) return -ENODEV; @@ -414,7 +414,7 @@ { struct macio_chip* macio; unsigned long flags; - + macio = macio_find(node, macio_unknown); if (!macio) return -ENODEV; @@ -441,7 +441,7 @@ MACIO_BIC(HEATHROW_MBCR, 0x00040000); else MACIO_BIS(HEATHROW_MBCR, 0x00040000); -#endif +#endif (void)MACIO_IN32(HEATHROW_MBCR); udelay(10); UNLOCK(flags); @@ -484,7 +484,7 @@ { struct macio_chip* macio; unsigned long flags; - + macio = macio_find(node, 0); if (!macio) return -ENODEV; @@ -520,7 +520,7 @@ if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || pmac_mb.model_id == PMAC_TYPE_YIKES) return 0; - + macio = macio_find(node, 0); if (!macio) return -ENODEV; @@ -552,7 +552,7 @@ dbdma_save(struct macio_chip* macio, struct dbdma_regs* save) { int i; - + /* Save state & config of DBDMA channels */ for (i=0; i<13; i++) { volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) @@ -569,7 +569,7 @@ dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save) { int i; - + /* Save state & config of DBDMA channels */ for (i=0; i<13; i++) { volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) @@ -668,7 +668,7 @@ unsigned long flags; unsigned long chan_mask; u32 fcr; - + macio = macio_find(node, 0); if (!macio) return -ENODEV; @@ -682,7 +682,7 @@ if (value) { int need_reset_scc = 0; int need_reset_irda = 0; - + LOCK(flags); fcr = MACIO_IN32(KEYLARGO_FCR0); /* Check if scc cell need enabling */ @@ -770,7 +770,7 @@ unsigned long flags; /* Hack for internal USB modem */ - if (node == NULL) { + if (node == NULL) { if (macio_chips[0].type != macio_keylargo) return -ENODEV; node = macio_chips[0].of_node; @@ -781,7 +781,7 @@ gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; - + if (!value) { LOCK(flags); MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); @@ -820,9 +820,9 @@ struct macio_chip* macio; u8 gpio; unsigned long flags; - + /* Hack for internal USB modem */ - if (node == NULL) { + if (node == NULL) { if (macio_chips[0].type != macio_pangea && macio_chips[0].type != macio_intrepid) return -ENODEV; @@ -834,7 +834,7 @@ gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; - + if (!value) { LOCK(flags); MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); @@ -962,7 +962,7 @@ { unsigned long flags; struct macio_chip* macio; - + macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea && macio->type != macio_intrepid) @@ -987,7 +987,7 @@ { struct macio_chip* macio; unsigned long flags; - + macio = macio_find(node, 0); if (!macio) return -ENODEV; @@ -1018,11 +1018,11 @@ struct macio_chip* macio; unsigned long flags; int state; - + macio = macio_find(node, 0); if (!macio) return -ENODEV; - + /* Hint: we allow passing of macio itself for the sake of the * sleep code */ @@ -1110,11 +1110,11 @@ KL_GPIO_RESET_CPU1, KL_GPIO_RESET_CPU2, KL_GPIO_RESET_CPU3 }; - + macio = &macio_chips[0]; if (macio->type != macio_keylargo) return -ENODEV; - + np = find_path_device("/cpus"); if (np == NULL) return -ENODEV; @@ -1130,7 +1130,7 @@ } if (np == NULL || reset_io == 0) reset_io = dflt_reset_lines[param]; - + LOCK(flags); MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(reset_io); @@ -1151,15 +1151,12 @@ char* prop; int number; u32 reg; - + macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea && macio->type != macio_intrepid) return -ENODEV; - /* XXX Fix handling of 3rd USB controller in Intrepid, move the - * port connect stuff (KL4_*) to the sleep code eventually - */ prop = (char *)get_property(node, "AAPL,clock-id", NULL); if (!prop) return -ENODEV; @@ -1167,6 +1164,8 @@ number = 0; else if (strncmp(prop, "usb1u148", 8) == 0) number = 2; + else if (strncmp(prop, "usb2u248", 8) == 0) + number = 4; else return -ENODEV; @@ -1183,44 +1182,79 @@ mdelay(1); LOCK(flags); MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); - } else { + } else if (number == 2) { MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); UNLOCK(flags); (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); LOCK(flags); MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); + } else if (number == 4) { + MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR1); + mdelay(1); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR0, KL1_USB2_CELL_ENABLE); + } + if (number < 4) { + reg = MACIO_IN32(KEYLARGO_FCR4); + reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | + KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number)); + reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | + KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1)); + MACIO_OUT32(KEYLARGO_FCR4, reg); + (void)MACIO_IN32(KEYLARGO_FCR4); + udelay(10); + } else { + reg = MACIO_IN32(KEYLARGO_FCR3); + reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | + KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0)); + reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | + KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1)); + MACIO_OUT32(KEYLARGO_FCR3, reg); + (void)MACIO_IN32(KEYLARGO_FCR3); + udelay(10); } - reg = MACIO_IN32(KEYLARGO_FCR4); - reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | - KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number)); - reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | - KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1)); - MACIO_OUT32(KEYLARGO_FCR4, reg); - (void)MACIO_IN32(KEYLARGO_FCR4); - udelay(10); } else { /* Turn OFF */ - reg = MACIO_IN32(KEYLARGO_FCR4); - reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | - KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number); - reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | - KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1); - MACIO_OUT32(KEYLARGO_FCR4, reg); - (void)MACIO_IN32(KEYLARGO_FCR4); - udelay(1); + if (number < 4) { + reg = MACIO_IN32(KEYLARGO_FCR4); + reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | + KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number); + reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | + KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1); + MACIO_OUT32(KEYLARGO_FCR4, reg); + (void)MACIO_IN32(KEYLARGO_FCR4); + udelay(1); + } else { + reg = MACIO_IN32(KEYLARGO_FCR3); + reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | + KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0); + reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | + KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1); + MACIO_OUT32(KEYLARGO_FCR3, reg); + (void)MACIO_IN32(KEYLARGO_FCR3); + udelay(1); + } if (number == 0) { MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); (void)MACIO_IN32(KEYLARGO_FCR0); udelay(1); MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); (void)MACIO_IN32(KEYLARGO_FCR0); - } else { + } else if (number == 2) { MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); (void)MACIO_IN32(KEYLARGO_FCR0); udelay(1); MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); (void)MACIO_IN32(KEYLARGO_FCR0); + } else if (number == 4) { + MACIO_BIC(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE); + (void)MACIO_IN32(KEYLARGO_FCR1); + udelay(1); + MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR1); } udelay(1); } @@ -1241,7 +1275,7 @@ return -ENODEV; if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) return -ENODEV; - + LOCK(flags); if (value) { UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); @@ -1271,7 +1305,7 @@ return -ENODEV; if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) return -ENODEV; - + LOCK(flags); if (value) { MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0); @@ -1291,7 +1325,7 @@ core99_read_gpio(struct device_node* node, int param, int value) { struct macio_chip* macio = &macio_chips[0]; - + return MACIO_IN8(param); } @@ -1321,7 +1355,7 @@ KL0_SCC_CELL_ENABLE | KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE); - + MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK); MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE); @@ -1344,7 +1378,7 @@ if (sleep_mode) temp |= KL3_SHUTDOWN_PLL_TOTAL; } - + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | KL3_SHUTDOWN_PLLKW35; if (sleep_mode) @@ -1379,7 +1413,7 @@ MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); - + temp = MACIO_IN32(KEYLARGO_FCR3); temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | KL3_SHUTDOWN_PLLKW35; @@ -1411,7 +1445,7 @@ MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); - + temp = MACIO_IN32(KEYLARGO_FCR3); temp |= KL3_IT_SHUTDOWN_PLL1 | KL3_IT_SHUTDOWN_PLL2 | KL3_IT_SHUTDOWN_PLL3; @@ -1435,7 +1469,7 @@ if (macio->type != macio_keylargo && macio->type != macio_pangea && macio->type != macio_intrepid) return -ENODEV; - + /* We power off the wireless slot in case it was not done * by the driver. We don't power it on automatically however */ @@ -1456,7 +1490,7 @@ /* We make sure the sound is off as well */ core99_sound_chip_enable(macio->of_node, 0, 0); - + /* * Save various bits of KeyLargo */ @@ -1482,7 +1516,7 @@ /* Save state & config of DBDMA channels */ dbdma_save(macio, save_dbdma); - + /* * Turn off as much as we can */ @@ -1492,8 +1526,8 @@ intrepid_shutdown(macio, 1); else if (macio->type == macio_keylargo) keylargo_shutdown(macio, 1); - - /* + + /* * Put the host bridge to sleep */ @@ -1532,7 +1566,7 @@ udelay(10); UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); udelay(10); - + /* * Restore KeyLargo */ @@ -1612,7 +1646,7 @@ return pmac_mb.model_id; case PMAC_MB_INFO_FLAGS: return pmac_mb.board_flags; - case PMAC_MB_INFO_NAME: + case PMAC_MB_INFO_NAME: /* hack hack hack... but should work */ *((const char **)value) = pmac_mb.model_name; break; @@ -1620,10 +1654,10 @@ return 0; } -/* +/* * Table definitions */ - + /* Used on any machine */ static struct feature_table_entry any_features[] __pmacdata = { @@ -1775,7 +1809,7 @@ { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, { 0, NULL } }; - + static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { /* Warning: ordering is important as some models may claim * beeing compatible with several types @@ -1928,10 +1962,22 @@ PMAC_TYPE_RACKMAC, rackmac_features, 0, }, + { "RackMac1,2", "XServe rev. 2", + PMAC_TYPE_RACKMAC, rackmac_features, + 0, + }, { "PowerMac3,6", "PowerMac G4 Windtunnel", PMAC_TYPE_WINDTUNNEL, rackmac_features, 0, }, + { "PowerBook5,1", "PowerBook G4 17\"", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, + { "PowerBook6,1", "PowerBook G4 12\"", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, }; /* @@ -1944,7 +1990,7 @@ int param, value, i; feature_call func = NULL; va_list args; - + if (pmac_mb.features) for (i=0; pmac_mb.features[i].function; i++) if (pmac_mb.features[i].selector == selector) { @@ -1976,7 +2022,7 @@ struct macio_chip* macio = &macio_chips[0]; const char* model = NULL; struct device_node *dt; - + /* Lookup known motherboard type in device-tree. First try an * exact match on the "model" property, then try a "compatible" * match is none is found. @@ -2028,8 +2074,8 @@ pmac_mb.features = pangea_features; break; case macio_intrepid: - pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA; - pmac_mb.model_name = "Unknown Pangea-based"; + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID; + pmac_mb.model_name = "Unknown Intrepid-based"; pmac_mb.features = intrepid_features; break; default: @@ -2083,8 +2129,8 @@ if (model && (strncmp(model, "PowerBook", 9) == 0 || strncmp(model, "iBook", 5) == 0)) pmac_mb.board_flags |= PMAC_MB_MOBILE; - - + + printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name); return 0; } @@ -2095,7 +2141,7 @@ probe_uninorth(void) { unsigned long actrl; - + /* Locate core99 Uni-N */ uninorth_node = find_devices("uni-n"); if (uninorth_node && uninorth_node->n_addrs > 0) { @@ -2103,10 +2149,10 @@ uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); } else uninorth_node = NULL; - + if (!uninorth_node) return; - + printk(KERN_INFO "Found Uninorth memory controller & host bridge, revision: %d\n", uninorth_rev); printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); @@ -2126,7 +2172,7 @@ */ if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0) UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); -} +} static void __init probe_one_macio(const char* name, const char* compat, int type) @@ -2135,7 +2181,7 @@ int i; volatile u32* base; u32* revp; - + node = find_devices(name); if (!node || !node->n_addrs) return; @@ -2221,7 +2267,7 @@ char *conn; int port_type = PMAC_SCC_ASYNC; int modem = 0; - + slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); conn = get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) @@ -2243,7 +2289,7 @@ set_initial_features(void) { struct device_node* np; - + /* That hack appears to be necessary for some StarMax motherboards * but I'm not too sure it was audited for side-effects on other * ohare based machines... @@ -2286,7 +2332,7 @@ while(np) { if (np->parent && device_is_compatible(np->parent, "uni-north") - && (device_is_compatible(np, "pci106b,18") || + && (device_is_compatible(np, "pci106b,18") || device_is_compatible(np, "pci106b,30") || device_is_compatible(np, "pci11c1,5811"))) { macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; @@ -2294,7 +2340,7 @@ } np = np->next; } - + /* Enable ATA-100 before PCI probe. */ np = find_devices("ata-6"); while(np) { @@ -2305,7 +2351,7 @@ } np = np->next; } - + /* Switch airport off */ np = find_devices("radio"); while(np) { @@ -2371,7 +2417,7 @@ pmac_feature_late_init(void) { struct device_node* np; - + /* Request some resources late */ if (uninorth_node) request_OF_resource(uninorth_node, 0, NULL); diff -urN linux-2.4.21/arch/ppc/platforms/pmac_nvram.c linux-2.4.22/arch/ppc/platforms/pmac_nvram.c --- linux-2.4.21/arch/ppc/platforms/pmac_nvram.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_nvram.c 2003-08-25 04:44:40.000000000 -0700 @@ -102,7 +102,7 @@ } low %= 65521UL; high %= 65521UL; - + return (high << 16) | low; } @@ -114,7 +114,7 @@ if (hdr99->hdr.signature != CORE99_SIGNATURE) { #ifdef DEBUG printk("Invalid signature\n"); -#endif +#endif return 0; } if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) { @@ -136,9 +136,9 @@ core99_erase_bank(int bank) { int stat, i; - + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; - + out_8(base, CORE99_FLASH_CMD_ERASE_SETUP); out_8(base, CORE99_FLASH_CMD_ERASE_CONFIRM); do { stat = in_8(base); } @@ -160,9 +160,9 @@ core99_write_bank(int bank, u8* datas) { int i, stat = 0; - + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; - + for (i=0; isibling) { int * bus_range; - unsigned int *class_code; + unsigned int *class_code; int len; /* For PCI<->PCI bridges or CardBus bridges, we go down */ @@ -69,7 +69,7 @@ /* This routine fixes the "bus-range" property of all bridges in the * system since they tend to have their "last" member wrong on macs - * + * * Note that the bus numbers manipulated here are OF bus numbers, they * are not Linux bus numbers. */ @@ -78,8 +78,8 @@ { int * bus_range; int len; - - /* Lookup the "bus-range" property for the hose */ + + /* Lookup the "bus-range" property for the hose */ bus_range = (int *) get_property(bridge, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", @@ -91,11 +91,11 @@ /* * Apple MacRISC (UniNorth, Bandit, Chaos) PCI controllers. - * + * * The "Bandit" version is present in all early PCI PowerMacs, * and up to the first ones using Grackle. Some machines may * have 2 bandit controllers (2 PCI busses). - * + * * "Chaos" is used in some "Bandit"-type machines as a bridge * for the separate display bus. It is accessed the same * way as bandit, but cannot be probed for devices. It therefore @@ -116,19 +116,19 @@ |(((unsigned long)(devfn)) << 8) \ |(((unsigned long)(off)) & 0xFCUL) \ |1UL) - + static unsigned int __pmac macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) { unsigned int caddr; - + if (bus == hose->first_busno) { if (dev_fn < (11 << 3)) return 0; caddr = MACRISC_CFA0(dev_fn, offset); } else caddr = MACRISC_CFA1(bus, dev_fn, offset); - + /* Uninorth will return garbage if we don't read back the value ! */ do { out_le32(hose->cfg_addr, caddr); @@ -217,7 +217,7 @@ CHAOS_PCI_OP(read, dword, u32 *) CHAOS_PCI_OP(write, byte, u8) CHAOS_PCI_OP(write, word, u16) -CHAOS_PCI_OP(write, dword, u32) +CHAOS_PCI_OP(write, dword, u32) static struct pci_ops chaos_pci_ops = { @@ -244,7 +244,7 @@ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID); udelay(2); vendev = in_le32((volatile unsigned int *)bp->cfg_data); - if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) + + if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) + PCI_VENDOR_ID_APPLE) { /* read the revision id */ out_le32(bp->cfg_addr, @@ -292,17 +292,17 @@ if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) { #ifdef DEBUG printk("Can't find PCI infos for PCI<->PCI bridge\n"); -#endif +#endif return; } - /* Warning: At this point, we have not yet renumbered all busses. + /* Warning: At this point, we have not yet renumbered all busses. * So we must use OF walking to find out hose */ hose = pci_find_hose_for_OF_device(p2pbridge); if (!hose) { #ifdef DEBUG printk("Can't find hose for PCI<->PCI bridge\n"); -#endif +#endif return; } if (early_read_config_word(hose, bus, devfn, @@ -314,6 +314,51 @@ early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); } +/* + * Some Apple desktop machines have a NEC PD720100A USB2 controller + * on the motherboard. Open Firmware, on these, will disable the + * EHCI part of it so it behaves like a pair of OHCI's. This fixup + * code re-enables it ;) + */ +static void __init +fixup_nec_usb2(void) +{ + struct device_node *nec; + + for (nec = find_devices("usb"); nec != NULL; nec = nec->next) { + struct pci_controller *hose; + u32 data, *prop; + u8 bus, devfn; + + prop = (u32 *)get_property(nec, "vendor-id", NULL); + if (prop == NULL) + continue; + if (0x1033 != *prop) + continue; + prop = (u32 *)get_property(nec, "device-id", NULL); + if (prop == NULL) + continue; + if (0x0035 != *prop) + continue; + prop = (u32 *)get_property(nec, "reg", 0); + if (prop == NULL) + continue; + devfn = (prop[0] >> 8) & 0xff; + bus = (prop[0] >> 16) & 0xff; + if (PCI_FUNC(devfn) != 0) + continue; + hose = pci_find_hose_for_OF_device(nec); + if (!hose) + continue; + printk("Found NEC PD720100A USB2 chip, enabling EHCI...\n"); + early_read_config_dword(hose, bus, devfn, 0xe4, &data); + data &= ~1UL; + early_write_config_dword(hose, bus, devfn, 0xe4, data); + early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE, + nec->intrs[0].line); + } +} + void __init pmac_find_bridges(void) { @@ -321,6 +366,7 @@ add_bridges(find_devices("chaos")); add_bridges(find_devices("pci")); init_p2pbridge(); + fixup_nec_usb2(); } #define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ @@ -416,7 +462,7 @@ char* disp_name; int *bus_range; int first = 1, primary; - + for (; dev != NULL; dev = dev->next) { addr = (struct reg_property *) get_property(dev, "reg", &len); if (addr == NULL || len < sizeof(*addr)) { @@ -429,7 +475,7 @@ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", dev->full_name); } - + hose = pcibios_alloc_controller(); if (!hose) continue; @@ -459,8 +505,8 @@ #ifdef DEBUG printk(" ->Hose at 0x%08lx, cfg_addr=0x%08lx,cfg_data=0x%08lx\n", hose, hose->cfg_addr, hose->cfg_data); -#endif - +#endif + /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(hose, dev, primary); @@ -474,9 +520,9 @@ static void __init pcibios_fixup_OF_interrupts(void) -{ +{ struct pci_dev* dev; - + /* * Open Firmware often doesn't initialize the * PCI_INTERRUPT_LINE config register properly, so we @@ -520,19 +566,19 @@ uninorth_child = node->parent && device_is_compatible(node->parent, "uni-north"); - + /* Firewire & GMAC were disabled after PCI probe, the driver is * claiming them, we must re-enable them now. */ - if (uninorth_child && !strcmp(node->name, "firewire") && - (device_is_compatible(node, "pci106b,18") || + if (uninorth_child && !strcmp(node->name, "firewire") && + (device_is_compatible(node, "pci106b,18") || device_is_compatible(node, "pci106b,30") || device_is_compatible(node, "pci11c1,5811"))) { pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1); pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1); updatecfg = 1; } - if (uninorth_child && !strcmp(node->name, "ethernet") && + if (uninorth_child && !strcmp(node->name, "ethernet") && device_is_compatible(node, "gmac")) { pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1); updatecfg = 1; @@ -540,14 +586,14 @@ if (updatecfg) { u16 cmd; - + /* * Make sure PCI is correctly configured * * We use old pci_bios versions of the function since, by * default, gmac is not powered up, and so will be absent - * from the kernel initial PCI lookup. - * + * from the kernel initial PCI lookup. + * * Should be replaced by 2.4 new PCI mecanisms and really * regiser the device. */ @@ -557,7 +603,7 @@ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); } - + return 0; } @@ -574,12 +620,12 @@ /* OF fails to initialize IDE controllers on macs * (and maybe other machines) - * + * * Ideally, this should be moved to the IDE layer, but we need * to check specifically with Andre Hedrick how to do it cleanly * since the common IDE code seem to care about the fact that the * BIOS may have disabled a controller. - * + * * -- BenH */ pci_for_each_dev(dev) { diff -urN linux-2.4.21/arch/ppc/platforms/pmac_pic.c linux-2.4.22/arch/ppc/platforms/pmac_pic.c --- linux-2.4.21/arch/ppc/platforms/pmac_pic.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_pic.c 2003-08-25 04:44:40.000000000 -0700 @@ -161,7 +161,7 @@ static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) { int irq, bits; - + for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { int i = irq >> 5; bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; @@ -191,7 +191,7 @@ #ifdef CONFIG_SMP void psurge_smp_message_recv(struct pt_regs *); - + /* IPI's are a hack on the powersurge -- Cort */ if ( smp_processor_id() != 0 ) { psurge_smp_message_recv(regs); @@ -221,7 +221,7 @@ { struct device_node *node; int count; - + memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); node = gw->child; count = 0; @@ -234,7 +234,7 @@ node->child->intrs = &gatwick_int_pool[count]; count += 3; } - node->child->n_intrs = 3; + node->child->n_intrs = 3; node->child->intrs[0].line = 15+irq_base; node->child->intrs[1].line = 4+irq_base; node->child->intrs[2].line = 5+irq_base; @@ -253,7 +253,7 @@ node->intrs[0].line = 29+irq_base; printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n", node->intrs[0].line); - + ya_node = node->child; while(ya_node) { @@ -267,7 +267,7 @@ ya_node->intrs[1].line = 1+irq_base; printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n", ya_node->intrs[0].line, ya_node->intrs[1].line); - } + } if (strcasecmp(ya_node->name, "ata4") == 0) { if (ya_node->n_intrs < 2) { ya_node->intrs = &gatwick_int_pool[count]; @@ -278,7 +278,7 @@ ya_node->intrs[1].line = 3+irq_base; printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n", ya_node->intrs[0].line, ya_node->intrs[1].line); - } + } ya_node = ya_node->sibling; } } @@ -345,7 +345,7 @@ struct device_node *irqctrler; unsigned long addr; int irq_cascade = -1; - + /* We first try to detect Apple's new Core99 chipset, since mac-io * is quite different on those machines and contains an IBM MPIC2. */ @@ -403,7 +403,7 @@ /* * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, - * 1998 G3 Series PowerBooks have 128, + * 1998 G3 Series PowerBooks have 128, * other powermacs have 32. * The combo ethernet/modem card for the Powerstar powerbooks * (2400/3400/3500, ohare based) has a second ohare chip @@ -425,17 +425,17 @@ /* get addresses of first controller */ if (irqctrler) { if (irqctrler->n_addrs > 0) { - addr = (unsigned long) + addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); for (i = 0; i < 2; ++i) pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) (addr + (2 - i) * 0x10); } - + /* get addresses of second controller */ irqctrler = irqctrler->next; if (irqctrler && irqctrler->n_addrs > 0) { - addr = (unsigned long) + addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); for (i = 2; i < 4; ++i) pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) @@ -464,7 +464,7 @@ for (i = 0; i < max_irqs; i++) if (level_mask[i >> 5] & (1UL << (i & 0x1f))) irq_desc[i].status = IRQ_LEVEL; - + /* get interrupt line of secondary interrupt controller */ if (irq_cascade >= 0) { printk(KERN_INFO "irq: secondary controller on irq %d\n", diff -urN linux-2.4.21/arch/ppc/platforms/pmac_setup.c linux-2.4.22/arch/ppc/platforms/pmac_setup.c --- linux-2.4.21/arch/ppc/platforms/pmac_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * arch/ppc/platforms/setup.c * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Adapted for Power Macintosh by Paul Mackerras @@ -150,7 +150,7 @@ { struct device_node *cpu_node; int *fp, s; - + cpu_node = find_type_devices("cpu"); if (!cpu_node) return 0; @@ -176,7 +176,7 @@ if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0) mbname = "Unknown"; - + /* find motherboard type */ seq_printf(m, "machine\t\t: "); np = find_devices("device-tree"); @@ -236,7 +236,7 @@ int n; struct reg_property *reg = (struct reg_property *) get_property(np, "reg", &n); - + if (reg != 0) { unsigned long total = 0; @@ -247,9 +247,9 @@ } /* Checks "l2cr-value" property in the registry */ - np = find_devices("cpus"); + np = find_devices("cpus"); if (np == 0) - np = find_type_devices("cpu"); + np = find_type_devices("cpu"); if (np != 0) { unsigned int *l2cr = (unsigned int *) get_property(np, "l2cr-value", NULL); @@ -257,11 +257,11 @@ seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr); } } - + /* Indicate newworld/oldworld */ seq_printf(m, "pmac-generation\t: %s\n", pmac_newworld ? "NewWorld" : "OldWorld"); - + return 0; } @@ -285,7 +285,7 @@ struct device_node *cpu; int *fp; unsigned long pvr; - + pvr = PVR_VER(mfspr(PVR)); /* Set loops_per_jiffy to a half-way reasonable value, @@ -311,12 +311,12 @@ /* Lookup PCI hosts */ pmac_find_bridges(); - + /* Checks "l2cr-value" property in the registry */ if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { - struct device_node *np = find_devices("cpus"); + struct device_node *np = find_devices("cpus"); if (np == 0) - np = find_type_devices("cpu"); + np = find_type_devices("cpu"); if (np != 0) { unsigned int *l2cr = (unsigned int *) get_property(np, "l2cr-value", NULL); @@ -333,7 +333,7 @@ printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n", ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) ? "enabled" : "disabled"); - + #ifdef CONFIG_KGDB zs_kgdb_hook(0); #endif @@ -345,7 +345,7 @@ printk("WARNING ! Your machine is Cuda based but your kernel\n"); printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); } -#endif +#endif #ifdef CONFIG_ADB_PMU find_via_pmu(); #else @@ -353,7 +353,7 @@ printk("WARNING ! Your machine is PMU based but your kernel\n"); printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); } -#endif +#endif #ifdef CONFIG_NVRAM pmac_nvram_init(); #endif @@ -520,7 +520,7 @@ macpart_fix_string(part->processor, 16); macpart_fix_string(part->name, 32); macpart_fix_string(part->type, 32); - + if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE) && strcasecmp(part->processor, "powerpc") == 0) goodness++; @@ -559,7 +559,7 @@ struct page* pg; unsigned secsize, blocks_in_map, blk; unsigned char* data; - + /* Check driver descriptor */ md = (struct mac_driver_desc *) read_one_block(bdev, 0, &pg); if (!md) @@ -568,7 +568,7 @@ goto fail; secsize = be16_to_cpu(md->block_size); page_cache_release(pg); - + /* Check if it looks like a mac partition map */ data = read_one_block(bdev, secsize/512, &pg); if (!data) @@ -591,7 +591,7 @@ check_bootable_part(dev, blk, part); } fail: - if (pg) + if (pg) page_cache_release(pg); } @@ -599,7 +599,7 @@ walk_bootable(struct gendisk *hd, void *data) { int drive; - + for (drive=0; drivenr_real; drive++) { kdev_t dev; struct block_device *bdev; @@ -650,7 +650,7 @@ #ifdef CONFIG_NVRAM pmac_nvram_update(); #endif - + switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: @@ -660,11 +660,11 @@ cuda_poll(); break; #endif /* CONFIG_ADB_CUDA */ -#ifdef CONFIG_ADB_PMU +#ifdef CONFIG_ADB_PMU case SYS_CTRLER_PMU: pmu_restart(); break; -#endif /* CONFIG_ADB_PMU */ +#endif /* CONFIG_ADB_PMU */ default: ; } } @@ -679,7 +679,7 @@ #ifdef CONFIG_NVRAM pmac_nvram_update(); #endif - + switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: @@ -841,7 +841,7 @@ ppc_md.init_IRQ = pmac_pic_init; ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ ppc_md.init = pmac_init2; - + ppc_md.pcibios_fixup = pmac_pcibios_fixup; ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; ppc_md.pcibios_after_init = pmac_pcibios_after_init; @@ -875,7 +875,7 @@ #endif /* CONFIG_BOOTX_TEXT */ if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); - + } #ifdef CONFIG_BOOTX_TEXT diff -urN linux-2.4.21/arch/ppc/platforms/pmac_sleep.S linux-2.4.22/arch/ppc/platforms/pmac_sleep.S --- linux-2.4.21/arch/ppc/platforms/pmac_sleep.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_sleep.S 2003-08-25 04:44:40.000000000 -0700 @@ -74,7 +74,7 @@ mftbu r3 cmpw r3,r4 bne 1b - + /* Save SPRGs */ mfsprg r4,0 stw r4,SL_SPRG0(r1) @@ -162,7 +162,7 @@ sync mtspr SPRN_HID0,r3 sync - + /* Turn off data relocation. */ mfmsr r3 /* Save MSR in r7 */ rlwinm r3,r3,0,28,26 /* Turn off DR bit */ @@ -197,7 +197,7 @@ isync b 1b -/* +/* * Here is the resume code. */ @@ -217,7 +217,7 @@ /* Won't that cause problems on CPU that doesn't support it ? */ lis r3, 0 mtspr SPRN_MMCR0, r3 - + /* sanitize MSR */ mfmsr r3 ori r3,r3,MSR_EE|MSR_IP @@ -235,11 +235,11 @@ lwz r1,0(r3) /* Pass thru to older resume code ... */ -/* +/* * Here is the resume code for older machines. * r1 has the physical address of SL_PC(sp). */ - + grackle_wake_up: /* Invalidate & enable L1 cache, we don't care about * whatever the ROM may have tried to write to memory @@ -260,7 +260,7 @@ bdnz 3b sync isync - + subi r1,r1,SL_PC /* Restore various CPU config stuffs */ @@ -340,7 +340,7 @@ /* restore the MSR and turn on the MMU */ lwz r3,SL_MSR(r1) - bl turn_on_mmu + bl turn_on_mmu /* get back the stack pointer */ tovirt(r1,r1) diff -urN linux-2.4.21/arch/ppc/platforms/pmac_smp.c linux-2.4.22/arch/ppc/platforms/pmac_smp.c --- linux-2.4.21/arch/ppc/platforms/pmac_smp.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,7 +3,7 @@ * * We support both the old "powersurge" SMP architecture * and the current Core99 (G4 PowerMac) machines. - * + * * Note that we don't support the very first rev. of * Apple/DayStar 2 CPUs board, the one with the funky * watchdog. Hopefully, none of these should be there except @@ -466,13 +466,13 @@ local_irq_save(flags); local_irq_disable(); - + /* Save reset vector */ save_vector = *vector; - - /* Setup fake reset vector that does + + /* Setup fake reset vector that does * b __secondary_start_psurge - KERNELBASE - */ + */ switch(nr) { case 1: new_vector = (unsigned long)__secondary_start_psurge; @@ -485,24 +485,24 @@ break; } *vector = 0x48000002 + new_vector - KERNELBASE; - + /* flush data cache and inval instruction cache */ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); - + /* Put some life in our friend */ pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); - + /* FIXME: We wait a bit for the CPU to take the exception, I should * instead wait for the entry code to set something for me. Well, * ideally, all that crap will be done in prom.c and the CPU left * in a RAM-based wait loop like CHRP. */ mdelay(1); - + /* Restore our exception vector */ *vector = save_vector; flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); - + local_irq_restore(flags); if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); } @@ -516,7 +516,7 @@ */ if (cpu_nr != 0) core99_init_caches(); - + /* Setup openpic */ do_openpic_setup_cpu(); diff -urN linux-2.4.21/arch/ppc/platforms/pmac_time.c linux-2.4.22/arch/ppc/platforms/pmac_time.c --- linux-2.4.21/arch/ppc/platforms/pmac_time.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/pmac_time.c 2003-08-25 04:44:40.000000000 -0700 @@ -63,7 +63,7 @@ #ifdef CONFIG_NVRAM s32 delta = 0; int dst; - + delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8; delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb); @@ -204,7 +204,7 @@ tb_ticks_per_jiffy, dstart - dend); iounmap((void *)via); - + return 1; } diff -urN linux-2.4.21/arch/ppc/platforms/pplus_pci.c linux-2.4.22/arch/ppc/platforms/pplus_pci.c --- linux-2.4.21/arch/ppc/platforms/pplus_pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/platforms/pplus_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,539 @@ +/* + * arch/ppc/platforms/pplus_pci.c + * + * PCI setup for MCG PowerPlus + * + * Author: Randy Vinson + * + * Derived from original PowerPlus PReP work by + * Cort Dougan, Johnnie Peters, Matt Porter, and + * Troy Benjegerdes. + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +unsigned char *Motherboard_map_name; + +/* Tables for known hardware */ + +/* Motorola Mesquite */ +static inline int +mesquite_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 19, 19, 19, 19 }, /* IDSEL 16 - PMC Slot 1 */ + { 0, 0, 0, 0 }, /* IDSEL 17 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 18 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 19 - unused */ + { 24, 25, 26, 27 }, /* IDSEL 20 - P2P bridge (to cPCI 1) */ + { 0, 0, 0, 0 }, /* IDSEL 21 - unused */ + { 28, 29, 30, 31 } /* IDSEL 22 - P2P bridge (to cPCI 2) */ + }; + + const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +/* Motorola Sitka */ +static inline int +sitka_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */ + { 0, 0, 0, 0 }, /* IDSEL 18 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 19 - unused */ + { 20, 0, 0, 0 } /* IDSEL 20 - P2P bridge (to cPCI) */ + }; + + const long min_idsel = 14, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +/* Motorola MTX */ +static inline int +MTX_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 12 - SCSI */ + { 0, 0, 0, 0 }, /* IDSEL 13 - unused */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 26, 27, 28, 25 }, /* IDSEL 17 - PMC Slot 2 */ + { 27, 28, 25, 26 } /* IDSEL 18 - PCI Slot 3 */ + }; + + const long min_idsel = 12, max_idsel = 18, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +/* Motorola MTX Plus */ +/* Secondary bus interrupt routing is not supported yet */ +static inline int +MTXplus_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 12 - SCSI */ + { 0, 0, 0, 0 }, /* IDSEL 13 - unused */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 1 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PCI Slot 1P */ + { 26, 27, 28, 25 }, /* IDSEL 17 - PCI Slot 2P */ + { 27, 28, 25, 26 }, /* IDSEL 18 - PCI Slot 3P */ + { 26, 0, 0, 0 }, /* IDSEL 19 - Enet 2 */ + { 0, 0, 0, 0 } /* IDSEL 20 - P2P Bridge */ + }; + + const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +static inline int +Genesis2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + /* 2600 + * Raven 31 + * ISA 11 + * SCSI 12 - IRQ3 + * Univ 13 + * eth 14 - IRQ2 + * VGA 15 - IRQ4 + * PMC1 16 - IRQ9,10,11,12 = PMC1 A-D + * PMC2 17 - IRQ12,9,10,11 = A-D + * SCSI2 18 - IRQ11 + * eth2 19 - IRQ10 + * PCIX 20 - IRQ9,10,11,12 = PCI A-D + */ + + /* 2400 + * Hawk 31 + * ISA 11 + * Univ 13 + * eth 14 - IRQ2 + * PMC1 16 - IRQ9,10,11,12 = PMC A-D + * PMC2 17 - IRQ12,9,10,11 = PMC A-D + * PCIX 20 - IRQ9,10,11,12 = PMC A-D + */ + + /* 2300 + * Raven 31 + * ISA 11 + * Univ 13 + * eth 14 - IRQ2 + * PMC1 16 - 9,10,11,12 = A-D + * PMC2 17 - 9,10,11,12 = B,C,D,A + */ + + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 12 - SCSI */ + { 0, 0, 0, 0 }, /* IDSEL 13 - Universe PCI - VME */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 1 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PCI/PMC Slot 1P */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PCI/PMC Slot 2P */ + { 27, 28, 25, 26 }, /* IDSEL 18 - PCI Slot 3P */ + { 26, 0, 0, 0 }, /* IDSEL 19 - Enet 2 */ + { 25, 26, 27, 28 } /* IDSEL 20 - P2P Bridge */ + }; + + const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +#define MOTOROLA_CPUTYPE_REG 0x800 +#define MOTOROLA_BASETYPE_REG 0x803 +#define MPIC_RAVEN_ID 0x48010000 +#define MPIC_HAWK_ID 0x48030000 +#define MOT_PROC2_BIT 0x800 + +static u_char pplus_openpic_initsenses[] __initdata = { + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),/* MVME2600_INT_SIO */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE),/*MVME2600_INT_FALCN_ECC_ERR*/ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/*MVME2600_INT_PCI_ETHERNET */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_SCSI */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_GRAPHICS*/ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTC */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTD */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_LM_SIG0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_LM_SIG1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), +}; + +int mot_entry = -1; +int prep_keybd_present = 1; +int mot_multi = 0; + +int __init raven_init(void) +{ + unsigned short devid; + unsigned char base_mod; + + /* set the MPIC base address */ + early_write_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, 0x3cfc0000); + + pplus_mpic_init(PREP_ISA_MEM_BASE); + + OpenPIC_InitSenses = pplus_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(pplus_openpic_initsenses); + + ppc_md.get_irq = openpic_get_irq; + + /* This is a hack. If this is a 2300 or 2400 mot board then there is + * no keyboard controller and we have to indicate that. + */ + + early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid); + base_mod = inb(MOTOROLA_BASETYPE_REG); + if ((devid == PCI_DEVICE_ID_MOTOROLA_HAWK) || + (base_mod == 0xF9) || + (base_mod == 0xFA) || (base_mod == 0xE1)) + prep_keybd_present = 0; + + return 1; +} + +struct brd_info { + int cpu_type; /* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */ + /* 0x200 if this board has a Hawk chip. */ + int base_type; + int max_cpu; /* ored with 0x80 if this board should be checked for multi CPU */ + const char *name; + int (*map_irq)(struct pci_dev *, + unsigned char, + unsigned char); +}; +struct brd_info mot_info[] = { + {0x300, 0x00, 0x00, "MVME 2400", Genesis2_map_irq}, + {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", mesquite_map_irq}, + {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", sitka_map_irq}, + {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", mesquite_map_irq}, + {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_map_irq}, + {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_map_irq}, + {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_map_irq}, + {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_map_irq}, + {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_map_irq}, + {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_map_irq}, + {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_map_irq}, + {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_map_irq}, + {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_map_irq}, + {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_map_irq}, + {0x000, 0x00, 0x00, "", NULL} +}; + +void __init pplus_set_board_type(void) +{ + unsigned char cpu_type; + unsigned char base_mod; + int entry; + unsigned short devid; + unsigned long *ProcInfo = NULL; + + cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0; + base_mod = inb(MOTOROLA_BASETYPE_REG); + early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid); + + for (entry = 0; mot_info[entry].cpu_type != 0; entry++) { + + /* Check for Hawk chip */ + if (mot_info[entry].cpu_type & 0x200) { + if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) + continue; + } else { + /* store the system config register for later use. */ + ProcInfo = (unsigned long *)ioremap(0xfef80400, 4); + + /* Check non hawk boards */ + if ((mot_info[entry].cpu_type & 0xff) != cpu_type) + continue; + + if (mot_info[entry].base_type == 0) { + mot_entry = entry; + break; + } + + if (mot_info[entry].base_type != base_mod) + continue; + } + + if (!(mot_info[entry].max_cpu & 0x80)) { + mot_entry = entry; + break; + } + + /* processor 1 not present and max processor zero indicated */ + if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) { + mot_entry = entry; + break; + } + + /* processor 1 present and max processor zero indicated */ + if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) { + mot_entry = entry; + break; + } + + /* Indicate to system if this is a multiprocessor board */ + if (!(*ProcInfo & MOT_PROC2_BIT)) { + mot_multi = 1; + } + } + + if (mot_entry == -1) + + /* No particular cpu type found - assume Mesquite (MCP750) */ + mot_entry = 1; + + Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name; + ppc_md.pci_map_irq = mot_info[mot_entry].map_irq; +} +void __init +pplus_pib_init(void) +{ + unsigned char reg; + unsigned short short_reg; + + struct pci_dev *dev = NULL; + + /* + * Perform specific configuration for the Via Tech or + * or Winbond PCI-ISA-Bridge part. + */ + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_1, dev))) { + /* + * PPCBUG does not set the enable bits + * for the IDE device. Force them on here. + */ + pci_read_config_byte(dev, 0x40, ®); + + reg |= 0x03; /* IDE: Chip Enable Bits */ + pci_write_config_byte(dev, 0x40, reg); + } + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_2, + dev)) && (dev->devfn = 0x5a)) { + /* Force correct USB interrupt */ + dev->irq = 11; + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + dev->irq); + } + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_83C553, dev))) { + /* Clear PCI Interrupt Routing Control Register. */ + short_reg = 0x0000; + pci_write_config_word(dev, 0x44, short_reg); + /* Route IDE interrupts to IRQ 14 */ + reg = 0xEE; + pci_write_config_byte(dev, 0x43, reg); + } + + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_82C105, dev))){ + /* + * Disable LEGIRQ mode so PCI INTS are routed + * directly to the 8259 and enable both channels + */ + pci_write_config_dword(dev, 0x40, 0x10ff0033); + + /* Force correct IDE interrupt */ + dev->irq = 14; + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + dev->irq); + } +} + +void __init +pplus_set_VIA_IDE_legacy(void) +{ + unsigned short vend, dev; + + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend); + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev); + + if ((vend == PCI_VENDOR_ID_VIA) && + (dev == PCI_DEVICE_ID_VIA_82C586_1)) { + + unsigned char temp; + + /* put back original "standard" port base addresses */ + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_0, 0x1f1); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_1, 0x3f5); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_2, 0x171); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_3, 0x375); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_4, 0xcc01); + + /* put into legacy mode */ + early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + &temp); + temp &= ~0x05; + early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + temp); + } +} + +void +pplus_set_VIA_IDE_native(void) +{ + unsigned short vend, dev; + + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend); + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev); + + if ((vend == PCI_VENDOR_ID_VIA) && + (dev == PCI_DEVICE_ID_VIA_82C586_1)) { + + unsigned char temp; + + /* put into native mode */ + early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + &temp); + temp |= 0x05; + early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + temp); + } +} + +void __init +pplus_pcibios_fixup(void) +{ + + printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name); + + /* Setup the Winbond or Via PIB */ + pplus_pib_init(); +} + +static void __init +pplus_init_resource(struct resource *res, unsigned long start, + unsigned long end, int flags) +{ + res->flags = flags; + res->start = start; + res->end = end; + res->name = "PCI host bridge"; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; +} + +void __init +pplus_setup_hose(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->pci_mem_offset = PREP_ISA_MEM_BASE; + hose->io_base_virt = (void *)PREP_ISA_IO_BASE; + + pplus_init_resource(&hose->io_resource, 0x00000000, 0x0fffffff, + IORESOURCE_IO); + pplus_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfdffffff, + IORESOURCE_MEM); + + hose->io_space.start = 0x00000000; + hose->io_space.end = 0x0fffffff; + hose->mem_space.start = 0x00000000; + hose->mem_space.end = 0x3cfbffff; /* MPIC at 0x3cfc0000-0x3dffffff */ + + setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); + + pplus_set_VIA_IDE_legacy(); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = pplus_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + pplus_set_board_type(); +} + diff -urN linux-2.4.21/arch/ppc/platforms/pplus_setup.c linux-2.4.22/arch/ppc/platforms/pplus_setup.c --- linux-2.4.21/arch/ppc/platforms/pplus_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc/platforms/pplus_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,550 @@ +/* + * arch/ppc/platforms/pplus_setup.c + * + * Board setup routines for MCG PowerPlus + * + * Author: Randy Vinson + * + * Derived from original PowerPlus PReP work by + * Cort Dougan, Johnnie Peters, Matt Porter, and + * Troy Benjegerdes. + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#undef DUMP_DBATS + +TODC_ALLOC(); + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern unsigned char pckbd_sysrq_xlate[128]; + +extern char saved_command_line[]; + +extern void pplus_setup_hose(void); +extern void pplus_set_VIA_IDE_native(void); + +extern unsigned long loops_per_jiffy; + +extern void gen550_progress(char *, unsigned short); +extern void gen550_init(int, struct serial_struct *); + +static int +pplus_show_cpuinfo(struct seq_file *m) +{ + extern char *Motherboard_map_name; + + seq_printf(m, "vendor\t\t: Motorola MCG\n"); + seq_printf(m, "machine\t\t: %s\n", Motherboard_map_name); + + return 0; +} + +static void __init +pplus_setup_arch(void) +{ + unsigned char reg; + + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: enter", 0); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000; + + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: find_bridges", 0); + + /* Setup PCI host bridge */ + pplus_setup_hose(); + + /* Set up floppy in PS/2 mode */ + outb(0x09, SIO_CONFIG_RA); + reg = inb(SIO_CONFIG_RD); + reg = (reg & 0x3F) | 0x40; + outb(reg, SIO_CONFIG_RD); + outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ + + /* Enable L2. Assume we don't need to flush -- Cort*/ + *(unsigned char *)(0x8000081c) |= 3; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + + printk(KERN_INFO "Motorola PowerPlus Platform\n"); + printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); + + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: raven_init", 0); + + raven_init(); + +#ifdef CONFIG_VGA_CONSOLE + /* remap the VGA memory */ + vgacon_remap_base = 0xf0000000; + conswitchp = &vga_con; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#ifdef CONFIG_PPCBUG_NVRAM + /* Read in NVRAM data */ + init_prep_nvram(); + + /* if no bootargs, look in NVRAM */ + if ( cmd_line[0] == '\0' ) { + char *bootargs; + bootargs = prep_nvram_get_var("bootargs"); + if (bootargs != NULL) { + strcpy(cmd_line, bootargs); + /* again.. */ + strcpy(saved_command_line, cmd_line); + } + } +#endif + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: exit", 0); +} + +static void +pplus_restart(char *cmd) +{ + unsigned long i = 10000; + + __cli(); + + /* set VIA IDE controller into native mode */ + pplus_set_VIA_IDE_native(); + + /* set exception prefix high - to the prom */ + _nmask_and_or_msr(0, MSR_IP); + + /* make sure bit 0 (reset) is a 0 */ + outb( inb(0x92) & ~1L , 0x92 ); + /* signal a reset to system control port A - soft reset */ + outb( inb(0x92) | 1 , 0x92 ); + + while ( i != 0 ) i++; + panic("restart failed\n"); +} + +static void +pplus_halt(void) +{ + unsigned long flags; + __cli(); + /* set exception prefix high - to the prom */ + save_flags( flags ); + restore_flags( flags|MSR_IP ); + + /* make sure bit 0 (reset) is a 0 */ + outb( inb(0x92) & ~1L , 0x92 ); + /* signal a reset to system control port A - soft reset */ + outb( inb(0x92) | 1 , 0x92 ); + + while ( 1 ) ; + /* + * Not reached + */ +} + +static void +pplus_power_off(void) +{ + pplus_halt(); +} + +static unsigned int +pplus_irq_cannonicalize(u_int irq) +{ + if (irq == 2) + { + return 9; + } + else + { + return irq; + } +} + +static void __init +pplus_init_IRQ(void) +{ + int i; + + if (OpenPIC_Addr != NULL) { + openpic_set_sources(0, 16, OpenPIC_Addr+0x10000); + openpic_init(NUM_8259_INTERRUPTS); + openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", + i8259_irq); + } + + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) + irq_desc[i].handler = &i8259_pic; + i8259_init(0); +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE stuff. + */ +static int +pplus_ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x1f0: return 14; + case 0x170: return 15; + default: return 0; + } +} + +static ide_ioreg_t +pplus_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + default: + return 0; + } +} + +static void __init +pplus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = pplus_ide_default_irq(data_port); +} +#endif + +#ifdef CONFIG_SMP +/* PowerPlus (MTX) support */ +static int __init +smp_pplus_probe(void) +{ + extern int mot_multi; + + if (mot_multi) { + openpic_request_IPIs(); + smp_hw_index[1] = 1; + return 2; + } + + return 1; +} + +static void __init +smp_pplus_kick_cpu(int nr) +{ + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); + printk("CPU1 reset, waiting\n"); +} + +static void __init +smp_pplus_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +static struct smp_ops_t pplus_smp_ops = { + smp_openpic_message_pass, + smp_pplus_probe, + smp_pplus_kick_cpu, + smp_pplus_setup_cpu, +}; +#endif /* CONFIG_SMP */ + +#ifdef DUMP_DBATS +static void print_dbat(int idx, u32 bat) { + + char str[64]; + + sprintf(str, "DBAT%c%c = 0x%08x\n", + (char)((idx - DBAT0U) / 2) + '0', + (idx & 1) ? 'L' : 'U', bat); + ppc_md.progress(str, 0); +} + +#define DUMP_DBAT(x) \ + do { \ + u32 __temp = mfspr(x);\ + print_dbat(x, __temp); \ + } while (0) + +static void dump_dbats(void) { + + if (ppc_md.progress) { + DUMP_DBAT(DBAT0U); + DUMP_DBAT(DBAT0L); + DUMP_DBAT(DBAT1U); + DUMP_DBAT(DBAT1L); + DUMP_DBAT(DBAT2U); + DUMP_DBAT(DBAT2L); + DUMP_DBAT(DBAT3U); + DUMP_DBAT(DBAT3L); + } +} +#endif + +static unsigned long __init +pplus_find_end_of_memory(void) +{ + unsigned long total; + + if (ppc_md.progress) + ppc_md.progress("pplus_find_end_of_memory",0); + +#ifdef DUMP_DBATS + dump_dbats(); +#endif + + total = pplus_get_mem_size(0xfef80000); + return (total); +} + +static void __init +pplus_map_io(void) +{ + io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO); + io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO); +} + +static void __init +pplus_init2(void) +{ +#ifdef CONFIG_NVRAM + request_region(PREP_NVRAM_AS0, 0x8, "nvram"); +#endif + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); +} + +/* + * Set BAT 2 to access 0x8000000 so progress messages will work and set BAT 3 + * to 0xf0000000 to access Falcon/Raven or Hawk registers + */ +static __inline__ void +pplus_set_bat(void) +{ + static int mapping_set = 0; + + if (!mapping_set) { + + /* wait for all outstanding memory accesses to complete */ + mb(); + + /* setup DBATs */ + mtspr(DBAT2U, 0x80001ffe); + mtspr(DBAT2L, 0x8000002a); + mtspr(DBAT3U, 0xf0001ffe); + mtspr(DBAT3L, 0xf000002a); + + /* wait for updates */ + mb(); + + mapping_set = 1; + } + + return; +} + +#if defined(CONFIG_SERIAL) && \ + (defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)) +extern struct serial_state rs_table[]; + +static void __init +pplus_early_serial_map(void) +{ + struct serial_struct serial_req; + + /* Setup serial port access */ + memset(&serial_req, 0, sizeof(serial_req)); + + /* + * rs_table[] already set up by so use that info for + * gen550_init(). This also means early_serial_setup() doesn't + * have to be called. + */ + serial_req.port = rs_table[0].port; + serial_req.io_type = rs_table[0].io_type; + serial_req.iomem_reg_shift = rs_table[0].iomem_reg_shift; +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(0, &serial_req); +#endif + + serial_req.port = rs_table[1].port; + serial_req.io_type = rs_table[1].io_type; + serial_req.iomem_reg_shift = rs_table[1].iomem_reg_shift; +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(1, &serial_req); +#endif +} +#endif + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* Map in board regs, etc. */ + pplus_set_bat(); + + isa_io_base = PREP_ISA_IO_BASE; + isa_mem_base = PREP_ISA_MEM_BASE; + pci_dram_offset = PREP_PCI_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = pplus_setup_arch; + ppc_md.show_percpuinfo = NULL; + ppc_md.show_cpuinfo = pplus_show_cpuinfo; + ppc_md.irq_cannonicalize = pplus_irq_cannonicalize; + ppc_md.init_IRQ = pplus_init_IRQ; + /* this gets changed later on if we have an OpenPIC -- Cort */ + ppc_md.get_irq = i8259_irq; + ppc_md.init = pplus_init2; + + ppc_md.restart = pplus_restart; + ppc_md.power_off = pplus_power_off; + ppc_md.halt = pplus_halt; + + TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1, + PREP_NVRAM_DATA, 8); + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + + ppc_md.find_end_of_memory = pplus_find_end_of_memory; + ppc_md.setup_io_mappings = pplus_map_io; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.default_irq = pplus_ide_default_irq; + ppc_ide_md.default_io_base = pplus_ide_default_io_base; + ppc_ide_md.ide_init_hwif = pplus_ide_init_hwif_ports; +#endif + +#ifdef CONFIG_VT + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; +#endif +#endif + +#if defined(CONFIG_SERIAL) && \ + (defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)) + pplus_early_serial_map(); + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = gen550_progress; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +#endif + +#ifdef CONFIG_SMP + ppc_md.smp_ops = &pplus_smp_ops; +#endif /* CONFIG_SMP */ +} diff -urN linux-2.4.21/arch/ppc/platforms/prep_pci.c linux-2.4.22/arch/ppc/platforms/prep_pci.c --- linux-2.4.21/arch/ppc/platforms/prep_pci.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/prep_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -43,7 +43,7 @@ /* Used for Motorola to store system config register */ static unsigned long *ProcInfo; -/* Tables for known hardware */ +/* Tables for known hardware */ /* Motorola PowerStackII - Utah */ static char Utah_pci_IRQ_map[23] __prepdata = @@ -155,7 +155,7 @@ 15, /* Line 3 */ 15 /* Line 4 */ }; - + /* Motorola Mesquite */ static char Mesquite_pci_IRQ_map[23] __prepdata = { @@ -271,7 +271,7 @@ { 0, /* This is a dummy structure */ }; - + /* Motorola MVME16xx */ static char Genesis_pci_IRQ_map[16] __prepdata = { @@ -301,7 +301,7 @@ 14, /* Line 3 */ 15 /* Line 4 */ }; - + static char Genesis2_pci_IRQ_map[23] __prepdata = { 0, /* Slot 0 - unused */ @@ -616,7 +616,7 @@ #define ELCRM_INT5_LVL 0x20 #define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset) -#define DEVNO(dev) (dev>>3) +#define DEVNO(dev) (dev>>3) #define cfg_read(val, addr, type, op) *val = op((type)(addr)) #define cfg_write(val, addr, type, op) op((type *)(addr), (val)) @@ -740,7 +740,7 @@ OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses); ppc_md.get_irq = openpic_get_irq; - + /* If raven is present on Motorola store the system config register * for later use. */ @@ -916,7 +916,7 @@ unsigned char *ibc_pirq = (unsigned char *)0x80800860; unsigned char *ibc_pcicon = (unsigned char *)0x80800840; int i; - + if ( _prep_type == _PREP_Motorola) { unsigned short irq_mode; @@ -989,7 +989,7 @@ printk("No known machine pci routing!\n"); return; } - + /* Set up mapping from slots */ for (i = 1; i <= 4; i++) ibc_pirq[i-1] = Motherboard_routes[i]; @@ -1010,7 +1010,7 @@ * Perform specific configuration for the Via Tech or * or Winbond PCI-ISA-Bridge part. */ - if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, dev))) { /* * PPCBUG does not set the enable bits @@ -1109,7 +1109,7 @@ * the devfn of the bus bridge with secondary inputs, use those. * Otherwise, assume it's a PMC site and get the interrupt line * value from the interrupt routing table. - */ + */ if (mot_info[mot_entry].secondary_bridge_devfn) { pbus = dev->bus; @@ -1183,7 +1183,7 @@ (dev->resource[i].start > 0x10000000)) { printk("Relocating PCI address %lx -> %lx\n", dev->resource[i].start, - (dev->resource[i].start & + (dev->resource[i].start & 0x00FFFFFF)| 0x01000000); dev->resource[i].start = (dev->resource[i].start & 0x00FFFFFF) @@ -1191,7 +1191,7 @@ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + (i*0x4), dev->resource[i].start); - dev->resource[i].end = + dev->resource[i].end = (dev->resource[i].end & 0x00FFFFFF) | 0x01000000; } @@ -1213,8 +1213,8 @@ prep_pcibios_after_init(void) { struct pci_dev *dev; - - /* If there is a WD 90C, reset the IO BAR to 0x0 (it started that + + /* If there is a WD 90C, reset the IO BAR to 0x0 (it started that * way, but the PCI layer relocated it because it thought 0x0 was * invalid for a BAR). * If you don't do this, the card's VGA base will be +0xc0000 @@ -1263,7 +1263,7 @@ hose->ops = &prep_pci_ops; printk("PReP architecture\n"); -#ifdef CONFIG_PREP_RESIDUAL +#ifdef CONFIG_PREP_RESIDUAL { PPC_DEVICE *hostbridge; @@ -1277,7 +1277,7 @@ 3, 0); if(pkt) { #define p pkt->L4_Pack.L4_Data.L4_PPCPack - setup_indirect_pci(hose, + setup_indirect_pci(hose, ld_le32((unsigned *) (p.PPCData)), ld_le32((unsigned *) (p.PPCData+8))); #undef p diff -urN linux-2.4.21/arch/ppc/platforms/prep_setup.c linux-2.4.22/arch/ppc/platforms/prep_setup.c --- linux-2.4.21/arch/ppc/platforms/prep_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/prep_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -102,7 +102,7 @@ /* for the mac fs */ kdev_t boot_dev; -#ifdef CONFIG_SOUND_CS4232 +#ifdef CONFIG_SOUND_CS4232 long ppc_cs4232_dma, ppc_cs4232_dma2; #endif @@ -111,7 +111,7 @@ extern int probingmem; extern unsigned long loops_per_jiffy; -#ifdef CONFIG_SOUND_CS4232 +#ifdef CONFIG_SOUND_CS4232 EXPORT_SYMBOL(ppc_cs4232_dma); EXPORT_SYMBOL(ppc_cs4232_dma2); #endif @@ -196,7 +196,7 @@ /* print info about the SCSI fuse */ seq_printf(m, "scsi fuse\t: "); - if (equip_reg & PREP_IBM_EQUIPMENT_SCSIFUSE) + if (equip_reg & PREP_IBM_EQUIPMENT_SCSIFUSE) seq_printf(m, "ok"); else seq_printf(m, "bad"); @@ -210,8 +210,8 @@ for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) { if (res->Memories[i].SIMMSize != 0) seq_printf(m, "%d:%ldMiB ", i, - (res->Memories[i].SIMMSize > 1024) ? - res->Memories[i].SIMMSize>>20 : + (res->Memories[i].SIMMSize > 1024) ? + res->Memories[i].SIMMSize>>20 : res->Memories[i].SIMMSize); } seq_printf(m, "\n"); @@ -374,12 +374,12 @@ seq_printf(m, "async, "); else seq_printf(m, "sync burst, "); - + if (l2_reg & 0x4) seq_printf(m, "parity, "); else seq_printf(m, "no parity, "); - + switch (l2_reg & 0x3) { case 0x0: seq_printf(m, "256KiB\n"); @@ -453,8 +453,8 @@ for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) { if (res->Memories[i].SIMMSize != 0) seq_printf(m, "%d:%ldM ", i, - (res->Memories[i].SIMMSize > 1024) ? - res->Memories[i].SIMMSize>>20 : + (res->Memories[i].SIMMSize > 1024) ? + res->Memories[i].SIMMSize>>20 : res->Memories[i].SIMMSize); } seq_printf(m, "\n"); @@ -570,7 +570,7 @@ { /* PREP's without residual data will give incorrect values here */ seq_printf(m, "clock\t\t: "); -#ifdef CONFIG_PREP_RESIDUAL +#ifdef CONFIG_PREP_RESIDUAL if (res->ResidualLength) seq_printf(m, "%ldMHz\n", (res->VitalProductData.ProcessorHz > 1024) ? @@ -583,7 +583,7 @@ return 0; } -#ifdef CONFIG_SOUND_CS4232 +#ifdef CONFIG_SOUND_CS4232 static long __init masktoint(unsigned int i) { int t = -1; @@ -594,7 +594,7 @@ /* * ppc_cs4232_dma and ppc_cs4232_dma2 are used in include/asm/dma.h - * to distinguish sound dma-channels from others. This is because + * to distinguish sound dma-channels from others. This is because * blocksize on 16 bit dma-channels 5,6,7 is 128k, but * the cs4232.c uses 64k like on 8 bit dma-channels 0,1,2,3 */ @@ -605,7 +605,7 @@ /* * Get the needed resource informations from residual data. - * + * */ #ifdef CONFIG_PREP_RESIDUAL audiodevice = residual_find_device(~0, NULL, MultimediaController, @@ -627,7 +627,7 @@ /* * These are the PReP specs' defaults for the cs4231. We use these * as fallback incase we don't have residual data. - * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7 + * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7 * will use the other values. */ if (audiodevice == NULL) { @@ -636,7 +636,7 @@ ppc_cs4232_dma = 1; ppc_cs4232_dma2 = -1; break; - default: + default: ppc_cs4232_dma = 6; ppc_cs4232_dma2 = 7; } @@ -659,8 +659,7 @@ prep_init_vesa(void) { #if defined(CONFIG_PREP_RESIDUAL) && \ - (defined(CONFIG_FB_VGA16) || defined(CONFIG_FB_VGA_16_MODULE) || \ - defined(CONFIG_FB_VESA)) + (defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB)) PPC_DEVICE *vgadev; vgadev = residual_find_device(~0, NULL, DisplayController, SVGAController, @@ -700,10 +699,10 @@ /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; - + /* Lookup PCI host bridges */ prep_find_bridges(); - + /* Set up floppy in PS/2 mode */ outb(0x09, SIO_CONFIG_RA); reg = inb(SIO_CONFIG_RD); @@ -782,7 +781,7 @@ break; } - /* Read in NVRAM data */ + /* Read in NVRAM data */ init_prep_nvram(); /* if no bootargs, look in NVRAM */ @@ -796,7 +795,7 @@ } } -#ifdef CONFIG_SOUND_CS4232 +#ifdef CONFIG_SOUND_CS4232 prep_init_sound(); #endif /* CONFIG_SOUND_CS4232 */ @@ -840,7 +839,7 @@ tb_ticks_per_jiffy = freq / HZ / divisor; return 0; } else -#endif +#endif return 1; } @@ -915,12 +914,12 @@ tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB); if (tmp & MK48T59_RTC_CB_STOP) { printk("Warning: RTC was stopped, date will be wrong.\n"); - ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB, + ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB, tmp & ~MK48T59_RTC_CB_STOP); /* Low frequency crystal oscillators may take a very long * time to startup and stabilize. For now just ignore the * the issue, but attempting to calibrate the decrementer - * from the RTC just after this wakeup is likely to be very + * from the RTC just after this wakeup is likely to be very * inaccurate. Firmware should not allow to load * the OS with the clock stopped anyway... */ @@ -944,11 +943,11 @@ unsigned char save_control; long i; unsigned char sec; - - + + /* Make sure the time is not stopped. */ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB); - + ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, (save_control & (~MK48T59_RTC_CB_STOP))); @@ -1135,7 +1134,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { -#ifdef CONFIG_PREP_RESIDUAL +#ifdef CONFIG_PREP_RESIDUAL /* make a copy of residual data */ if ( r3 ) { memcpy((void *)res,(void *)(r3+KERNELBASE), @@ -1151,7 +1150,7 @@ DMA_MODE_WRITE = 0x48; /* figure out what kind of prep workstation we are */ -#ifdef CONFIG_PREP_RESIDUAL +#ifdef CONFIG_PREP_RESIDUAL if ( res->ResidualLength != 0 ) { if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) ) _prep_type = _PREP_IBM; diff -urN linux-2.4.21/arch/ppc/platforms/prep_time.c linux-2.4.22/arch/ppc/platforms/prep_time.c --- linux-2.4.21/arch/ppc/platforms/prep_time.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/prep_time.c 2003-08-25 04:44:40.000000000 -0700 @@ -114,10 +114,10 @@ /* Since the UIP flag is set for about 2.2 ms and the clock * is typically written with a precision of 1 jiffy, trying - * to obtain a precision better than a few milliseconds is + * to obtain a precision better than a few milliseconds is * an illusion. Only consistency is interesting, this also * allows to use the routine for /dev/rtc without a potential - * 1 second kernel busy loop triggered by any reader of /dev/rtc. + * 1 second kernel busy loop triggered by any reader of /dev/rtc. */ for ( i = 0; i<1000000; i++) { diff -urN linux-2.4.21/arch/ppc/platforms/proc_rtas.c linux-2.4.22/arch/ppc/platforms/proc_rtas.c --- linux-2.4.21/arch/ppc/platforms/proc_rtas.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/proc_rtas.c 2003-08-25 04:44:40.000000000 -0700 @@ -93,7 +93,7 @@ /* Tokens for indicators */ #define TONE_FREQUENCY 0x0001 /* 0 - 1000 (HZ)*/ #define TONE_VOLUME 0x0002 /* 0 - 100 (%) */ -#define SYSTEM_POWER_STATE 0x0003 +#define SYSTEM_POWER_STATE 0x0003 #define WARNING_LIGHT 0x0004 #define DISK_ACTIVITY_LIGHT 0x0005 #define HEX_DISPLAY_UNIT 0x0006 @@ -107,7 +107,7 @@ /* 9006 - 9999: Vendor specific */ /* other */ -#define MAX_SENSORS 17 /* I only know of 17 sensors */ +#define MAX_SENSORS 17 /* I only know of 17 sensors */ #define MAX_LINELENGTH 256 #define SENSOR_PREFIX "ibm,sensor-" #define cel_to_fahr(x) ((x*9/5)+32) @@ -138,9 +138,9 @@ /* Declarations */ static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, int count, int *eof, void *data); -static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, size_t count, loff_t *ppos); -static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, size_t count, loff_t *ppos); static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, size_t count, loff_t *ppos); @@ -184,7 +184,7 @@ }; int ppc_rtas_find_all_sensors (void); -int ppc_rtas_process_sensor(struct individual_sensor s, int state, +int ppc_rtas_process_sensor(struct individual_sensor s, int state, int error, char * buf); char * ppc_rtas_process_error(int error); int get_location_code(struct individual_sensor s, char * buf); @@ -202,7 +202,7 @@ if ((rtas == 0) || (_machine != _MACH_chrp)) { return; } - + proc_rtas = proc_mkdir("rtas", 0); if (proc_rtas == 0) return; @@ -212,19 +212,19 @@ entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas); if (entry) entry->proc_fops = &ppc_rtas_progress_operations; - entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); + entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); if (entry) entry->proc_fops = &ppc_rtas_clock_operations; - entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); + entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; - create_proc_read_entry("sensors", S_IRUGO, proc_rtas, + create_proc_read_entry("sensors", S_IRUGO, proc_rtas, ppc_rtas_sensor_read, NULL); - - entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); + + entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; - entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); + entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; } @@ -248,11 +248,11 @@ to_tm(nowtime, &tm); - error = call_rtas("set-time-for-power-on", 7, 1, NULL, - tm.tm_year, tm.tm_mon, tm.tm_mday, + error = call_rtas("set-time-for-power-on", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */); if (error != 0) - printk(KERN_WARNING "error: setting poweron time returned: %s\n", + printk(KERN_WARNING "error: setting poweron time returned: %s\n", ppc_rtas_process_error(error)); return count; } @@ -287,7 +287,7 @@ strcpy(progress_led, buf); /* save the string */ /* Lets see if the user passed hexdigits */ hex = simple_strtoul(buf, NULL, 10); - + ppc_md.progress ((char *)buf, hex); return count; @@ -313,7 +313,7 @@ /* ****************************************************************** */ /* CLOCK */ /* ****************************************************************** */ -static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { struct rtc_time tm; @@ -328,16 +328,16 @@ } to_tm(nowtime, &tm); - error = call_rtas("set-time-of-day", 7, 1, NULL, - tm.tm_year, tm.tm_mon, tm.tm_mday, + error = call_rtas("set-time-of-day", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, 0); if (error != 0) - printk(KERN_WARNING "error: setting the clock returned: %s\n", + printk(KERN_WARNING "error: setting the clock returned: %s\n", ppc_rtas_process_error(error)); return count; } /* ****************************************************************** */ -static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, size_t count, loff_t *ppos) { unsigned int year, mon, day, hour, min, sec; @@ -345,15 +345,15 @@ int n, error; error = call_rtas("get-time-of-day", 0, 8, ret); - + year = ret[0]; mon = ret[1]; day = ret[2]; hour = ret[3]; min = ret[4]; sec = ret[5]; if (error != 0){ - printk(KERN_WARNING "error: reading the clock returned: %s\n", + printk(KERN_WARNING "error: reading the clock returned: %s\n", ppc_rtas_process_error(error)); n = sprintf (buf, "0"); - } else { + } else { n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec)); } kfree(ret); @@ -395,7 +395,7 @@ j = sensors.sensor[i].quant; /* A sensor may have multiple instances */ while (j >= 0) { - error = call_rtas("get-sensor-state", 2, 2, &ret, + error = call_rtas("get-sensor-state", 2, 2, &ret, sensors.sensor[i].token, sensors.sensor[i].quant-j); state = (int) ret; n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); @@ -479,8 +479,8 @@ * Builds a string out of what the sensor said */ -int ppc_rtas_process_sensor(struct individual_sensor s, int state, - int error, char * buf) +int ppc_rtas_process_sensor(struct individual_sensor s, int state, + int error, char * buf) { /* Defined return vales */ const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", "Mainenance" }; @@ -488,7 +488,7 @@ const char * lid_status[] = { " ", "Open", "Closed" }; const char * power_source[] = { "AC\t", "Battery", "AC & Battery" }; const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" }; - const char * epow_sensor[] = { + const char * epow_sensor[] = { "EPOW Reset", "Cooling warning", "Power warning", "System shutdown", "System halt", "EPOW main enclosure", "EPOW power off" }; @@ -632,8 +632,8 @@ /* ****************************************************************** */ -/* - * Format: +/* + * Format: * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] * the '.' may be an abbrevation */ @@ -670,7 +670,7 @@ len = strlen(tmp); while (strlen(tmp) < 4) n += sprintf (tmp+n, "0"); - + /* invert the string */ while (tmp[i]) { if (i 100) volume = 100; - + rtas_tone_volume = volume; /* save it for later */ error = call_rtas("set-indicator", 3, 1, NULL, TONE_VOLUME, 0, volume); if (error != 0) - printk(KERN_WARNING "error: setting tone volume returned: %s\n", + printk(KERN_WARNING "error: setting tone volume returned: %s\n", ppc_rtas_process_error(error)); return count; } diff -urN linux-2.4.21/arch/ppc/platforms/residual.c linux-2.4.22/arch/ppc/platforms/residual.c --- linux-2.4.21/arch/ppc/platforms/residual.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/residual.c 2003-08-25 04:44:40.000000000 -0700 @@ -142,15 +142,15 @@ "\001\002\006CHRP_Floppy", /* CHRP Floppy in PR*P system */ "\001\003\000GeneralIPI", - + "\002\000\000GeneralEther", "\002\001\000GeneralToken", "\002\002\000GeneralFDDI", - + "\003\000\000GeneralVGA", "\003\001\000GeneralSVGA", "\003\002\000GeneralXGA", - + "\004\000\000GeneralVideo", "\004\001\000GeneralAudio", "\004\001\001CS4232Audio", /* CS 4232 Plug 'n Play Configured */ @@ -160,7 +160,7 @@ "\005\000\000PCIMemoryController", /* PCI Config Method */ "\005\000\001RS6KMemoryController", /* RS6K Config Method */ "\005\001\000GeneralFLASH", - + "\006\000\000GeneralHostBridge", "\006\001\000GeneralISABridge", "\006\002\000GeneralEISABridge", @@ -171,7 +171,7 @@ "\006\004\002PCIBridgeRS6K", "\006\005\000GeneralPCMCIABridge", "\006\006\000GeneralVMEBridge", - + "\007\000\000GeneralRS232", "\007\000\001COMx", "\007\000\002Compatible16450", @@ -191,7 +191,7 @@ "\007\001\003NS26EParPort", /* Ports 26E and 26F */ "\007\001\004NS15CParPort", /* Ports 15C and 15D */ "\007\001\005NS2EParPort", /* Ports 2E and 2F */ - + "\010\000\000GeneralPIC", "\010\000\001ISA_PIC", "\010\000\002EISA_PIC", @@ -207,7 +207,7 @@ "\010\002\002EISA_Timer", "\010\003\000GeneralRTC", "\010\003\001ISA_RTC", - + "\010\004\001StoreThruOnly", "\010\004\002StoreInEnabled", "\010\004\003RS6KL2Cache", @@ -219,7 +219,7 @@ "\010\006\000GeneralPowerManagement", "\010\006\001EPOWPowerManagement", "\010\006\002PowerControl", // d1378 - + "\010\007\000GeneralCMOS", "\010\010\000GeneralOPPanel", @@ -234,30 +234,30 @@ "\010\011\000GeneralServiceProcessor", "\010\012\000GeneralServiceProcessor", "\010\013\000GeneralServiceProcessor", - + "\010\014\001TransferData", "\010\014\002IGMC32", "\010\014\003IGMC64", - + "\010\017\000GeneralSystemPlanar", /* 10/5/95 */ NULL }; -static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType, +static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType, unsigned char SubType) { unsigned char ** s=PnP_SUB_TYPES; - while (*s && !((*s)[0]==BaseType + while (*s && !((*s)[0]==BaseType && (*s)[1]==SubType)) s++; if (*s) return *s+2; else return("Unknown !"); }; -static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType, +static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType, unsigned char SubType, unsigned char Interface) { unsigned char ** s=PnP_INTERFACES; - while (*s && !((*s)[0]==BaseType - && (*s)[1]==SubType + while (*s && !((*s)[0]==BaseType + && (*s)[1]==SubType && (*s)[2]==Interface)) s++; if (*s) return *s+3; else return NULL; @@ -294,7 +294,7 @@ switch (tag_small_item_name(pkt->S1_Pack.Tag)) { case PnPVersion: - printk(" PnPversion 0x%x.%x\n", + printk(" PnPversion 0x%x.%x\n", pkt->S1_Pack.Version[0], /* How to interpret version ? */ pkt->S1_Pack.Version[1]); break; @@ -304,7 +304,7 @@ break; case IRQFormat: #define p pkt->S4_Pack - printk(" IRQ Mask 0x%4.4x, %s %s sensitive\n", + printk(" IRQ Mask 0x%4.4x, %s %s sensitive\n", ld_le16((unsigned short *)p.IRQMask), intlevel[(size>3) ? !(p.IRQInfo&0x05) : 0], intsense[(size>3) ? !(p.IRQInfo&0x03) : 0]); @@ -329,7 +329,7 @@ p.IOInfo&ISAAddr16bit?16:10, ld_le16((unsigned short *)p.RangeMin), ld_le16((unsigned short *)p.RangeMax), - p.IOAlign, p.IONum); + p.IOAlign, p.IONum); #undef p break; case FixedIOPort: @@ -337,20 +337,20 @@ printk(" Fixed (10 decoded bits) I/O port from %3.3x to %3.3x\n", (p.Range[1]<<8)|p.Range[0], ((p.Range[1]<<8)|p.Range[0])+p.IONum-1); -#undef p +#undef p break; case Res1: case Res2: case Res3: - printk(" Undefined packet type %d!\n", + printk(" Undefined packet type %d!\n", tag_small_item_name(pkt->S1_Pack.Tag)); break; case SmallVendorItem: printsmallvendor(pkt,size); break; default: - printk(" Type 0x2.2x%d, size=%d\n", - pkt->S1_Pack.Tag, size); + printk(" Type 0x2.2x%d, size=%d\n", + pkt->S1_Pack.Tag, size); break; } } @@ -432,7 +432,7 @@ break; case 7: printk(" SCSI buses: %d, id(s):", p.PPCData[0]); - for(i=1; i<=p.PPCData[0]; i++) + for(i=1; i<=p.PPCData[0]; i++) printk(" %d%c", p.PPCData[i], i==p.PPCData[0] ? '\n' : ','); break; case 9: @@ -448,11 +448,11 @@ p.PPCData[1]); printk(" ISA interrupts routed to %s\n" - " lines", + " lines", tmpstr); for(i=0; i<16; i++) { int line=ld_le16((unsigned short *)p.PPCData+i+1); - if (line!=0xffff) printk(" %d(IRQ%d)", line, i); + if (line!=0xffff) printk(" %d(IRQ%d)", line, i); } printk("\n"); break; @@ -471,8 +471,8 @@ printlargevendor(pkt, size); break; default: - printk(" Type 0x2.2x%d, size=%d\n", - pkt->S1_Pack.Tag, size); + printk(" Type 0x2.2x%d, size=%d\n", + pkt->S1_Pack.Tag, size); break; } } @@ -486,7 +486,7 @@ int size; if (tag_type(pkt->S1_Pack.Tag)) { size= 3 + - pkt->L1_Pack.Count0 + + pkt->L1_Pack.Count0 + pkt->L1_Pack.Count1*256; printlargepacket(pkt, size); } else { @@ -502,11 +502,11 @@ int i; PPC_DEVICE *dev; #define did dev->DeviceId - + /* make sure we have residual data first */ if ( res->ResidualLength == 0 ) return; - + printk("Residual: %ld devices\n", res->ActualNumDevices); for ( i = 0; i < res->ActualNumDevices ; @@ -515,23 +515,23 @@ char decomp[4], sn[20]; const char * s; dev = &res->Devices[i]; - s = PnP_INTERFACE_STR(did.BaseType, did.SubType, + s = PnP_INTERFACE_STR(did.BaseType, did.SubType, did.Interface); if(!s) { sprintf(sn, "interface %d", did.Interface); s=sn; } - if ( did.BusId & PCIDEVICE ) + if ( did.BusId & PCIDEVICE ) printk("PCI Device, Bus %d, DevFunc 0x%x:", dev->BusAccess.PCIAccess.BusNumber, dev->BusAccess.PCIAccess.DevFuncNumber); if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:"); - if ( did.BusId & ISADEVICE ) + if ( did.BusId & ISADEVICE ) printk("ISA Device, Slot %d, LogicalDev %d:", dev->BusAccess.ISAAccess.SlotNumber, dev->BusAccess.ISAAccess.LogicalDevNumber); if ( did.BusId & EISADEVICE ) printk("EISA Device:"); - if ( did.BusId & PROCESSORDEVICE ) + if ( did.BusId & PROCESSORDEVICE ) printk("ProcBus Device, Bus %d, BUID %d: ", dev->BusAccess.ProcBusAccess.BusNumber, dev->BusAccess.ProcBusAccess.BUID); @@ -544,7 +544,7 @@ decomp[1]='A'-1+((did.DevId>>21)&0x1F); decomp[2]='A'-1+((did.DevId>>16)&0x1F); decomp[3]=0; - printk(" %s%4.4lX, %s, %s, %s\n", + printk(" %s%4.4lX, %s, %s, %s\n", decomp, did.DevId&0xffff, PnP_BASE_TYPES[did.BaseType], PnP_SUB_TYPE_STR(did.BaseType,did.SubType), @@ -572,15 +572,15 @@ static const char* Usage[]={ "FirmwareStack", "FirmwareHeap", "FirmwareCode", "BootImage", "Free", "Unpopulated", "ISAAddr", "PCIConfig", - "IOMemory", "SystemIO", "SystemRegs", "PCIAddr", - "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other" + "IOMemory", "SystemIO", "SystemRegs", "PCIAddr", + "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other" }; static const unsigned char *FWMan[]={ "IBM", "Motorola", "FirmWorks", "Bull" }; static const unsigned char *FWFlags[]={ "Conventional", "OpenFirmware", "Diagnostics", "LowDebug", - "MultiBoot", "LowClient", "Hex41", "FAT", + "MultiBoot", "LowClient", "Hex41", "FAT", "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path" }; static const unsigned char *ESM[]={ @@ -596,15 +596,15 @@ printk("FirmwareFlags:"); for(j=0; j<12; j++) { if (vpd.FirmwareSupports & (1<2 ? 2 : vpd.EndianSwitchMethod]); - printk("SpreadIOMethod: %s\n", + printk("SpreadIOMethod: %s\n", SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]); printk("Processor/Bus frequencies (Hz): %ld/%ld\n", vpd.ProcessorHz, vpd.ProcessorBusHz); @@ -614,7 +614,7 @@ vpd.CoherenceBlockSize, vpd.GranuleSize); for (i=0; iActualNumMemSegs; i++) { int mask=res->Segs[i].Usage, first, j; - printk("%8.8lx-%8.8lx ", + printk("%8.8lx-%8.8lx ", res->Segs[i].BasePage*ps, (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1); for(j=15, first=1; j>=0; j--) { @@ -637,7 +637,7 @@ union _PnP_TAG_PACKET *pkt; PPC_DEVICE *dev; #define did dev->DeviceId - + /* make sure we have residual data first */ if ( res->ResidualLength == 0 ) return; @@ -664,7 +664,7 @@ pci_strdev(did.DevId>>16, did.DevId&0xffff) ); - + if ( did.BusId & PNPISADEVICE ) { printk(" pnp:"); @@ -693,7 +693,7 @@ did.BaseType, did.SubType); printk("\n"); continue; - } + } /* * eisa devices */ @@ -703,7 +703,7 @@ did.BaseType, did.SubType); printk("\n"); continue; - } + } /* * proc bus devices */ @@ -723,26 +723,26 @@ did.BaseType, did.SubType); printk("\n"); continue; - } + } printk("Unknown bus access device: busid %lx\n", did.BusId); } } -#endif +#endif -/* Returns the device index in the residual data, +/* Returns the device index in the residual data, any of the search items may be set as -1 for wildcard, - DevID number field (second halfword) is big endian ! + DevID number field (second halfword) is big endian ! Examples: - search for the Interrupt controller (8259 type), 2 methods: - 1) i8259 = residual_find_device(~0, - NULL, - SystemPeripheral, - ProgrammableInterruptController, - ISA_PIC, + 1) i8259 = residual_find_device(~0, + NULL, + SystemPeripheral, + ProgrammableInterruptController, + ISA_PIC, 0); - 2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0) + 2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0) - search for the first two serial devices, whatever their type) iserial1 = residual_find_device(~0,NULL, @@ -754,8 +754,8 @@ RS232Device, -1, 1) - but search for typical COM1 and COM2 is not easy due to the - fact that the interface may be anything and the name "PNP0500" or - "PNP0501". Quite bad. + fact that the interface may be anything and the name "PNP0500" or + "PNP0501". Quite bad. */ @@ -768,7 +768,7 @@ static int __init same_DevID(unsigned short vendor, unsigned short Number, - char * str) + char * str) { static unsigned const char hexdigit[]="0123456789ABCDEF"; if (strlen(str)!=7) return 0; @@ -836,11 +836,11 @@ if (tag_type(packet_tag)) mask=0xff; else mask=0xF8; masked_tag = packet_tag&mask; for(; *p != END_TAG; p+=size) { - if ((*p & mask) == masked_tag && !(n--)) + if ((*p & mask) == masked_tag && !(n--)) return (PnP_TAG_PACKET *) p; if (tag_type(*p)) size=ld_le16((unsigned short *)(p+1))+3; - else + else size=tag_small_count(*p)+1; } return 0; /* not found */ @@ -853,7 +853,7 @@ int next=0; while (p) { p = (unsigned char *) PnP_find_packet(p, 0x70, next); - if (p && p[1]==packet_type && !(n--)) + if (p && p[1]==packet_type && !(n--)) return (PnP_TAG_PACKET *) p; next = 1; }; @@ -867,7 +867,7 @@ int next=0; while (p) { p = (unsigned char *) PnP_find_packet(p, 0x84, next); - if (p && p[3]==packet_type && !(n--)) + if (p && p[3]==packet_type && !(n--)) return (PnP_TAG_PACKET *) p; next = 1; }; diff -urN linux-2.4.21/arch/ppc/platforms/spd8xx.h linux-2.4.22/arch/ppc/platforms/spd8xx.h --- linux-2.4.21/arch/ppc/platforms/spd8xx.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/spd8xx.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * Speech Design SPD8xxTS board specific definitions - * + * * Copyright (c) 2000,2001 Wolfgang Denk (wd@denx.de) */ @@ -9,7 +9,7 @@ #define __ASM_SPD8XX_H__ #include - + #include #define SPD_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */ diff -urN linux-2.4.21/arch/ppc/platforms/spruce.h linux-2.4.22/arch/ppc/platforms/spruce.h --- linux-2.4.21/arch/ppc/platforms/spruce.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/spruce.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * include/asm-ppc/platforms/spruce.h - * + * * Definitions for IBM Spruce reference board support * * Authors: Matt Porter and Johnnie Peters @@ -51,7 +51,7 @@ /* * Serial port defines - */ + */ #define SPRUCE_FPGA_REG_A 0xff820000 #define SPRUCE_UARTCLK_33M 0x02 #define SPRUCE_UARTCLK_IS_33M(reg) (reg & SPRUCE_UARTCLK_33M) diff -urN linux-2.4.21/arch/ppc/platforms/spruce_pci.c linux-2.4.22/arch/ppc/platforms/spruce_pci.c --- linux-2.4.21/arch/ppc/platforms/spruce_pci.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/spruce_pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * arch/ppc/platforms/spruce_pci.c - * + * * PCI support for IBM Spruce * * Author: Johnnie Peters @@ -31,7 +31,7 @@ { static char pci_irq_table[][4] = /* - * PCI IDSEL/INTPIN->INTLINE + * PCI IDSEL/INTPIN->INTLINE * A B C D */ { @@ -52,7 +52,7 @@ /* Setup hose */ hose = pcibios_alloc_controller(); - if (!hose) + if (!hose) return; hose->first_busno = 0; diff -urN linux-2.4.21/arch/ppc/platforms/tqm8xx.h linux-2.4.22/arch/ppc/platforms/tqm8xx.h --- linux-2.4.21/arch/ppc/platforms/tqm8xx.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/tqm8xx.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,6 +1,6 @@ /* * TQM8xx(L) board specific definitions - * + * * Copyright (c) 1999,2000,2001 Wolfgang Denk (wd@denx.de) */ @@ -8,7 +8,7 @@ #define __MACH_TQM8xx_H #include - + #include #define TQM_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */ diff -urN linux-2.4.21/arch/ppc/platforms/walnut.c linux-2.4.22/arch/ppc/platforms/walnut.c --- linux-2.4.21/arch/ppc/platforms/walnut.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/walnut.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,288 +1,250 @@ /* * - * Copyright (c) 1999-2000 Grant Erickson + * Copyrigh t(c) 1999-2000 Grant Erickson * - * Module name: walnut_setup.c + * Copyright 2000-2002 MontaVista Software Inc. + * Completed implementation. + * Author: MontaVista Software, Inc. + * + * Module name: walnut.c * * Description: * Architecture- / platform-specific boot-time initialization code for - * the IBM PowerPC 403GP "Walnut" evaluation board. Adapted from original + * IBM PowerPC 4xx based boards. Adapted from original * code by Gary Thomas, Cort Dougan , and Dan Malek * . * + * Please read the COPYING file for all license details. */ - #include #include #include #include -#include #include #include #include -#include +#include +#include +#include +#include #include -#include #include #include - -#include "ppc4xx_pic.h" #include -#include "walnut_setup.h" - - -/* Function Prototypes */ - -extern void abort(void); - -/* Global Variables */ - -unsigned char __res[sizeof(bd_t)]; - - -/* - * void __init walnut_init() - * - * Description: - * This routine... - * - * Input(s): - * r3 - Optional pointer to a board information structure. - * r4 - Optional pointer to the physical starting address of the init RAM - * disk. - * r5 - Optional pointer to the physical ending address of the init RAM - * disk. - * r6 - Optional pointer to the physical starting address of any kernel - * command-line parameters. - * r7 - Optional pointer to the physical ending address of any kernel - * command-line parameters. - * - * Output(s): - * N/A - * - * Returns: - * N/A - * +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +void *kb_cs; +void *kb_data; +void *walnut_rtc_base; + +#ifdef CONFIG_PCI +/* Some IRQs unique to Walnut. + * Used by the generic 405 PCI setup functions in ppc4xx_pci.c */ +int __init +ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */ + {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */ + {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */ + {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; +#endif + void __init -walnut_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) +board_setup_arch(void) { - /* - * If we were passed in a board information, copy it into the - * residual data area. - */ - if (r3) { - memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t)); - } +#define WALNUT_PS2_BASE 0xF0100000 +#define WALNUT_FPGA_BASE 0xF0300000 -#if defined(CONFIG_BLK_DEV_INITRD) - /* - * If the init RAM disk has been configured in, and there's a valid - * starting address for it, set it up. - */ - if (r4) { - initrd_start = r4 + KERNELBASE; - initrd_end = r5 + KERNELBASE; + void *fpga_brdc; + unsigned char fpga_brdc_data; + void *fpga_enable; + void *fpga_polarity; + void *fpga_status; + void *fpga_trigger; + + kb_data = ioremap(WALNUT_PS2_BASE, 8); + if (!kb_data) { + printk(KERN_CRIT + "walnut_setup_arch() kb_data ioremap failed\n"); + return; } -#endif /* CONFIG_BLK_DEV_INITRD */ - /* Copy the kernel command line arguments to a safe place. */ + kb_cs = kb_data + 1; - if (r6) { - *(char *)(r7 + KERNELBASE) = 0; - strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + fpga_status = ioremap(WALNUT_FPGA_BASE, 8); + if (!fpga_status) { + printk(KERN_CRIT + "walnut_setup_arch() fpga_status ioremap failed\n"); + return; } - /* Initialize machine-dependency vectors */ + fpga_enable = fpga_status + 1; + fpga_polarity = fpga_status + 2; + fpga_trigger = fpga_status + 3; + fpga_brdc = fpga_status + 4; - ppc_md.setup_arch = walnut_setup_arch; - ppc_md.show_percpuinfo = walnut_show_percpuinfo; - ppc_md.irq_cannonicalize = NULL; - ppc_md.init_IRQ = walnut_init_IRQ; - ppc_md.get_irq = walnut_get_irq; - ppc_md.init = NULL; - - ppc_md.restart = walnut_restart; - ppc_md.power_off = walnut_power_off; - ppc_md.halt = walnut_halt; - - ppc_md.time_init = walnut_time_init; - ppc_md.set_rtc_time = walnut_set_rtc_time; - ppc_md.get_rtc_time = walnut_get_rtc_time; - ppc_md.calibrate_decr = walnut_calibrate_decr; - - ppc_md.kbd_setkeycode = NULL; - ppc_md.kbd_getkeycode = NULL; - ppc_md.kbd_translate = NULL; - ppc_md.kbd_unexpected_up = NULL; - ppc_md.kbd_leds = NULL; - ppc_md.kbd_init_hw = NULL; - ppc_md.ppc_kbd_sysrq_xlate = NULL; -} + /* split the keyboard and mouse interrupts */ + fpga_brdc_data = readb(fpga_brdc); + fpga_brdc_data |= 0x80; + writeb(fpga_brdc_data, fpga_brdc); -/* - * Document me. - */ -void __init -walnut_setup_arch(void) -{ - /* XXX - Implement me */ -} + writeb(0x3, fpga_enable); -/* - * int walnut_show_percpuinfo() - * - * Description: - * This routine pretty-prints the platform's internal CPU and bus clock - * frequencies into the buffer for usage in /proc/cpuinfo. - * - * Input(s): - * *buffer - Buffer into which CPU and bus clock frequencies are to be - * printed. - * - * Output(s): - * *buffer - Buffer with the CPU and bus clock frequencies. - * - * Returns: - * The number of bytes copied into 'buffer' if OK, otherwise zero or less - * on error. - */ -int -walnut_show_percpuinfo(struct seq_file *m) -{ - bd_t *bp = (bd_t *)__res; + writeb(0x3, fpga_polarity); - seq_printf(m, "clock\t\t: %dMHz\n" - "bus clock\t\t: %dMHz\n", - bp->bi_intfreq / 1000000, - bp->bi_busfreq / 1000000); + writeb(0x3, fpga_trigger); - return 0; + /* RTC step for the walnut */ + walnut_rtc_base = (void *) WALNUT_RTC_VADDR; + TODC_INIT(TODC_TYPE_DS1743, walnut_rtc_base, walnut_rtc_base, + walnut_rtc_base, 8); + /* Identify the system */ + printk("IBM Walnut port (C) 2000-2002 MontaVista Software, Inc. (source@mvista.com)\n"); } -/* - * Document me. - */ +#ifdef CONFIG_PCI void __init -walnut_init_IRQ(void) +bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) { - int i; - - ppc4xx_pic_init(); - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].handler = ppc4xx_pic; - } - - return; -} - -/* - * Document me. - */ -int -walnut_get_irq(struct pt_regs *regs) -{ - return (ppc4xx_pic_get_irq(regs)); -} + unsigned int bar_response, bar; + /* + * Expected PCI mapping: + * + * PLB addr PCI memory addr + * --------------------- --------------------- + * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff + * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff + * + * PLB addr PCI io addr + * --------------------- --------------------- + * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000 + * + * The following code is simplified by assuming that the bootrom + * has been well behaved in following this mapping. + */ -/* - * Document me. - */ -void -walnut_restart(char *cmd) -{ - abort(); -} +#ifdef DEBUG + int i; -/* - * Document me. - */ -void -walnut_power_off(void) -{ - walnut_restart(NULL); -} + printk("ioremap PCLIO_BASE = 0x%x\n", pcip); + printk("PCI bridge regs before fixup \n"); + for (i = 0; i <= 3; i++) { + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); + } + printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); + printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); + printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); + printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); + +#endif + + /* added for IBM boot rom version 1.15 bios bar changes -AK */ + + /* Disable region first */ + out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); + /* PLB starting addr, PCI: 0x80000000 */ + out_le32((void *) &(pcip->pmm[0].la), 0x80000000); + /* PCI start addr, 0x80000000 */ + out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); + /* 512MB range of PLB to PCI */ + out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); + /* Enable no pre-fetch, enable region */ + out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - + (PPC405_PCI_UPPER_MEM - + PPC405_PCI_MEM_BASE)) | 0x01)); + + /* Disable region one */ + out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); + out_le32((void *) &(pcip->pmm[1].la), 0x00000000); + out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); + out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); + out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); + out_le32((void *) &(pcip->ptm1ms), 0x00000000); + + /* Disable region two */ + out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); + out_le32((void *) &(pcip->pmm[2].la), 0x00000000); + out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); + out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); + out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); + out_le32((void *) &(pcip->ptm2ms), 0x00000000); + + /* Zero config bars */ + for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { + early_write_config_dword(hose, hose->first_busno, + PCI_FUNC(hose->first_busno), bar, + 0x00000000); + early_read_config_dword(hose, hose->first_busno, + PCI_FUNC(hose->first_busno), bar, + &bar_response); + DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n", + hose->first_busno, PCI_SLOT(hose->first_busno), + PCI_FUNC(hose->first_busno), bar, bar_response); + } + /* end work arround */ -/* - * Document me. - */ -void -walnut_halt(void) -{ - walnut_restart(NULL); -} +#ifdef DEBUG + printk("PCI bridge regs after fixup \n"); + for (i = 0; i <= 3; i++) { + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); + } + printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); + printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); + printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); + printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); -/* - * Document me. - */ -long __init -walnut_time_init(void) -{ - /* XXX - Implement me */ - return 0; +#endif } +#endif -/* - * Document me. - */ -int __init -walnut_set_rtc_time(unsigned long time) +void __init +board_io_mapping(void) { - /* XXX - Implement me */ - - return (0); + io_block_mapping(WALNUT_RTC_VADDR, + WALNUT_RTC_PADDR, WALNUT_RTC_SIZE, _PAGE_IO); } -/* - * Document me. - */ -unsigned long __init -walnut_get_rtc_time(void) +void __init +board_setup_irq(void) { - /* XXX - Implement me */ - - return (0); } -/* - * void __init walnut_calibrate_decr() - * - * Description: - * This routine retrieves the internal processor frequency from the board - * information structure, sets up the kernel timer decrementer based on - * that value, enables the 403 programmable interval timer (PIT) and sets - * it up for auto-reload. - * - * Input(s): - * N/A - * - * Output(s): - * N/A - * - * Returns: - * N/A - * - */ void __init -walnut_calibrate_decr(void) +board_init(void) { - unsigned int freq; - bd_t *bip = (bd_t *)__res; - - freq = bip->bi_intfreq; - - decrementer_count = freq / HZ; - count_period_num = 1; - count_period_den = freq; - - /* Enable the PIT and set auto-reload of its value */ - - mtspr(SPRN_TCR, TCR_PIE | TCR_ARE); - - /* Clear any pending timer interrupts */ - - mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS); + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; } diff -urN linux-2.4.21/arch/ppc/platforms/walnut.h linux-2.4.22/arch/ppc/platforms/walnut.h --- linux-2.4.21/arch/ppc/platforms/walnut.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/platforms/walnut.h 2003-08-25 04:44:40.000000000 -0700 @@ -1,50 +1,91 @@ /* * - * Copyright (c) 1999-2000 Grant Erickson + * Copyright (c) 1999 Grant Erickson * - * Module name: walnut_setup.c + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * Module name: ppc405.h * * Description: - * Architecture- / platform-specific boot-time initialization code for - * the IBM PowerPC 405GP "Walnut" evaluation board. Adapted from original - * code by Gary Thomas, Cort Dougan , and Dan Malek - * . + * Macros, definitions, and data structures specific to the IBM PowerPC + * based boards. + * + * This includes: + * + * 405GP "Walnut" evaluation board * + * Please read the COPYING file for all license details. */ -#ifndef __WALNUT_SETUP_H__ -#define __WALNUT_SETUP_H__ +#ifdef __KERNEL__ +#ifndef __ASM_WALNUT_H__ +#define __ASM_WALNUT_H__ -#include -#include +/* We have a 405GP core */ +#include +#ifndef __ASSEMBLY__ +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Walnut" evaluation board. An effort has been made to + * keep the field names consistent with the 8xx 'bd_t' board info + * structures. + */ -#ifdef __cplusplus -extern "C" { -#endif - -extern unsigned char __res[sizeof(bd_t)]; +typedef struct board_info { + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[30]; /* Version of the IBM ROM */ + unsigned int bi_memsize; /* DRAM installed, in bytes */ + unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */ + unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */ + unsigned int bi_intfreq; /* Processor speed, in Hz */ + unsigned int bi_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */ + unsigned int bi_opbfreq; /* OPB Bus speed, in Hz */ + int bi_iic_fast[1]; /* Use fast i2c mode */ +} bd_t; + +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq -extern void walnut_init(unsigned long r3, - unsigned long ird_start, - unsigned long ird_end, - unsigned long cline_start, - unsigned long cline_end); -extern void walnut_setup_arch(void); -extern int walnut_setup_residual(char *buffer); -extern void walnut_init_IRQ(void); -extern int walnut_get_irq(struct pt_regs *regs); -extern void walnut_restart(char *cmd); -extern void walnut_power_off(void); -extern void walnut_halt(void); -extern void walnut_time_init(void); -extern int walnut_set_rtc_time(unsigned long now); -extern unsigned long walnut_get_rtc_time(void); -extern void walnut_calibrate_decr(void); +/* Memory map for the IBM "Walnut" 405GP evaluation board. + * Generic 4xx plus RTC. + */ -#ifdef __cplusplus -} +extern void *walnut_rtc_base; +#define WALNUT_RTC_PADDR ((uint)0xf0000000) +#define WALNUT_RTC_VADDR WALNUT_RTC_PADDR +#define WALNUT_RTC_SIZE ((uint)8*1024) + +/* ps2 keyboard and mouse */ +#define KEYBOARD_IRQ 25 +#define AUX_IRQ 26 + +#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK +#define BASE_BAUD 201600 +#else +#define BASE_BAUD 691200 #endif -#endif /* __WALNUT_SETUP_H__ */ +#define WALNUT_PS2_BASE 0xF0100000 +#define WALNUT_FPGA_BASE 0xF0300000 + + +extern void *kb_cs; +extern void *kb_data; +#define kbd_read_input() readb(kb_data) +#define kbd_read_status() readb(kb_cs) +#define kbd_write_output(val) writeb(val, kb_data) +#define kbd_write_command(val) writeb(val, kb_cs) + +#define PPC4xx_MACHINE_NAME "IBM Walnut" + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_WALNUT_H__ */ +#endif /* __KERNEL__ */ diff -urN linux-2.4.21/arch/ppc/vmlinux.lds linux-2.4.22/arch/ppc/vmlinux.lds --- linux-2.4.21/arch/ppc/vmlinux.lds 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ppc/vmlinux.lds 2003-08-25 04:44:40.000000000 -0700 @@ -64,6 +64,7 @@ _edata = .; PROVIDE (edata = .); + . = ALIGN(8); .fixup : { *(.fixup) } __start___ex_table = .; __ex_table : { *(__ex_table) } @@ -73,6 +74,7 @@ __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + . = ALIGN(8); __start___ftr_fixup = .; __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; @@ -83,7 +85,7 @@ . = ALIGN(4096); __init_begin = .; .text.init : { *(.text.init) } - .data.init : { + .data.init : { *(.data.init); __vtop_table_begin = .; *(.vtop_fixup); @@ -138,6 +140,7 @@ *(.bss) *(COMMON) } + . = ALIGN(4); _end = . ; PROVIDE (end = .); } diff -urN linux-2.4.21/arch/ppc/xmon/ppc-opc.c linux-2.4.22/arch/ppc/xmon/ppc-opc.c --- linux-2.4.21/arch/ppc/xmon/ppc-opc.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/xmon/ppc-opc.c 2003-08-25 04:44:40.000000000 -0700 @@ -393,7 +393,7 @@ same. */ /*ARGSUSED*/ -static unsigned long +static unsigned long insert_bat (insn, value, errmsg) unsigned long insn; long value; @@ -869,7 +869,7 @@ extraction function just checks that the fields are the same. */ /*ARGSUSED*/ -static unsigned long +static unsigned long insert_rbs (insn, value, errmsg) unsigned long insn; long value; diff -urN linux-2.4.21/arch/ppc/xmon/start.c linux-2.4.22/arch/ppc/xmon/start.c --- linux-2.4.21/arch/ppc/xmon/start.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/xmon/start.c 2003-08-25 04:44:40.000000000 -0700 @@ -98,7 +98,7 @@ xmon(regs); } -static struct sysrq_key_op sysrq_xmon_op = +static struct sysrq_key_op sysrq_xmon_op = { handler: sysrq_handle_xmon, help_msg: "Xmon", @@ -112,7 +112,7 @@ volatile unsigned char *base; use_screen = 0; - + if (_machine == _MACH_Pmac) { struct device_node *np; unsigned long addr; @@ -176,7 +176,7 @@ #endif TXRDY = 4; RXRDY = 1; - + np = find_devices("mac-io"); if (np && np->n_addrs) addr = np->addrs[0].address + 0x13020; diff -urN linux-2.4.21/arch/ppc/xmon/start_8xx.c linux-2.4.22/arch/ppc/xmon/start_8xx.c --- linux-2.4.21/arch/ppc/xmon/start_8xx.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/xmon/start_8xx.c 2003-08-25 04:44:40.000000000 -0700 @@ -46,7 +46,7 @@ cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); use_screen = 0; - + prom_drawstring("xmon uses serial port\n"); } diff -urN linux-2.4.21/arch/ppc/xmon/xmon.c linux-2.4.22/arch/ppc/xmon/xmon.c --- linux-2.4.21/arch/ppc/xmon/xmon.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc/xmon/xmon.c 2003-08-25 04:44:40.000000000 -0700 @@ -716,7 +716,7 @@ extern char do_signal_ret, ret_from_except; printf("backtrace:\n"); - + if (excp != NULL) sp = excp->gpr[1]; else @@ -1176,7 +1176,7 @@ byterev(unsigned char *val, int size) { int t; - + switch (size) { case 2: SWAP(val[0], val[1], t); @@ -1787,7 +1787,7 @@ { char *sym; unsigned long saddr; - + printf("%08x", addr); sym = xmon_find_symbol(addr, &saddr); if (sym) @@ -1807,7 +1807,7 @@ extern unsigned long sysmap_size; if ( !sysmap || !sysmap_size ) return NULL; - + prev = 0; psym = NULL; p = sysmap; @@ -1852,7 +1852,7 @@ char *match; int goodness = 0; int result = 0; - + extern char *sysmap; extern unsigned long sysmap_size; if ( !sysmap || !sysmap_size ) @@ -1883,7 +1883,7 @@ } cur++; } - } + } if (goodness) { p = match; while(p > sysmap && *p != 10) @@ -1895,4 +1895,4 @@ } debugger_fault_handler = 0; return result; -} +} diff -urN linux-2.4.21/arch/ppc64/Makefile linux-2.4.22/arch/ppc64/Makefile --- linux-2.4.21/arch/ppc64/Makefile 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -19,6 +19,13 @@ CHECKS = checks endif +HAS_BIARCH := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;) +ifeq ($(HAS_BIARCH),y) +AS := $(AS) -64 +LD := $(LD) -m elf64ppc +CC := gcc -m64 +endif + LINKFLAGS = -T arch/ppc64/vmlinux.lds -Bstatic \ -e $(KERNELLOAD) -Ttext $(KERNELLOAD) CFLAGS := $(CFLAGS) -fsigned-char -msoft-float -pipe \ diff -urN linux-2.4.21/arch/ppc64/boot/Makefile linux-2.4.22/arch/ppc64/boot/Makefile --- linux-2.4.21/arch/ppc64/boot/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/boot/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -52,7 +52,7 @@ ifeq ($(CONFIG_PPC_ISERIES),y) all: vmlinux.sm else -all: $(TOPDIR)/zImage +all: zImage endif @@ -94,7 +94,7 @@ zImage.o: $(TOPDIR)/vmlinux -vmlinux .config System.map: % : $(TOPDIR)/% +vmlinux .config System.map: % : $(TOPDIR)/% zImage.o gzip -cvf9 $(TOPDIR)/$@ > kernel-$@.gz $(OBJCOPY) zImage.o \ --add-section=.kernel:$@=kernel-$@.gz \ diff -urN linux-2.4.21/arch/ppc64/boot/addnote.c linux-2.4.22/arch/ppc64/boot/addnote.c --- linux-2.4.21/arch/ppc64/boot/addnote.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ppc64/boot/addnote.c 2003-08-25 04:44:40.000000000 -0700 @@ -14,6 +14,7 @@ * Usage: addnote zImage */ #include +#include #include #include #include diff -urN linux-2.4.21/arch/ppc64/boot/zlib.c linux-2.4.22/arch/ppc64/boot/zlib.c --- linux-2.4.21/arch/ppc64/boot/zlib.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ppc64/boot/zlib.c 2003-08-25 04:44:40.000000000 -0700 @@ -735,7 +735,7 @@ 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. + defined for them. Similarly, 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. diff -urN linux-2.4.21/arch/ppc64/config.in linux-2.4.22/arch/ppc64/config.in --- linux-2.4.21/arch/ppc64/config.in 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -39,8 +39,13 @@ bool 'MsChunks Physical to Absolute address translation support' CONFIG_MSCHUNKS tristate 'Firmware flash interface' CONFIG_RTAS_FLASH tristate 'Scanlog Dump interface' CONFIG_SCANLOG +bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS + if [ "$CONFIG_PPC_RTAS" = "y" ]; then + bool 'RTAS Error Inject' CONFIG_RTAS_ERRINJCT + fi fi +bool 'Shared kernel/user space addressing' CONFIG_SHARED_MEMORY_ADDRESSING endmenu @@ -136,7 +141,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -231,6 +236,8 @@ source lib/Config.in +source crypto/Config.in + mainmenu_option next_comment comment 'Kernel hacking' @@ -238,6 +245,7 @@ bool 'Include kgdb kernel debugger' CONFIG_KGDB bool 'Include xmon kernel debugger' CONFIG_XMON bool 'Include kdb kernel debugger' CONFIG_KDB +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB if [ "$CONFIG_KDB" = "y" ]; then bool ' KDB off by default' CONFIG_KDB_OFF define_bool CONFIG_KALLSYMS y diff -urN linux-2.4.21/arch/ppc64/configs/iSeries_devfs_defconfig linux-2.4.22/arch/ppc64/configs/iSeries_devfs_defconfig --- linux-2.4.21/arch/ppc64/configs/iSeries_devfs_defconfig 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/configs/iSeries_devfs_defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -700,6 +700,6 @@ # CONFIG_KDB_OFF is not set # CONFIG_KALLSYMS is not set # CONFIG_PPCDBG is not set -CONFIG_DUMP=y -CONFIG_DUMP_COMPRESS_RLE=y -CONFIG_DUMP_COMPRESS_GZIP=y +# CONFIG_DUMP is not set +# CONFIG_DUMP_COMPRESS_RLE is not set +# CONFIG_DUMP_COMPRESS_GZIP is not set diff -urN linux-2.4.21/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig linux-2.4.22/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig --- linux-2.4.21/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -635,6 +635,6 @@ # CONFIG_KDB_OFF is not set # CONFIG_KALLSYMS is not set # CONFIG_PPCDBG is not set -CONFIG_DUMP=y -CONFIG_DUMP_COMPRESS_RLE=y -CONFIG_DUMP_COMPRESS_GZIP=y +# CONFIG_DUMP is not set +# CONFIG_DUMP_COMPRESS_RLE is not set +# CONFIG_DUMP_COMPRESS_GZIP is not set diff -urN linux-2.4.21/arch/ppc64/configs/pSeries_defconfig linux-2.4.22/arch/ppc64/configs/pSeries_defconfig --- linux-2.4.21/arch/ppc64/configs/pSeries_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/configs/pSeries_defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -27,6 +27,9 @@ # CONFIG_MSCHUNKS is not set CONFIG_RTAS_FLASH=m CONFIG_SCANLOG=m +CONFIG_PPC_RTAS=y +# CONFIG_RTAS_ERRINJCT is not set +# CONFIG_SHARED_MEMORY_ADDRESSING is not set # # Loadable module support @@ -173,6 +176,7 @@ # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes @@ -726,9 +730,12 @@ # CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set -CONFIG_XMON=y -# CONFIG_KDB is not set -# CONFIG_KDB is not set -# CONFIG_KALLSYMS is not set +# CONFIG_XMON is not set +# CONFIG_KDB is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_KDB_OFF is not set +CONFIG_KALLSYMS=y CONFIG_PPCDBG=y # CONFIG_DUMP is not set +# CONFIG_DUMP_COMPRESS_RLE is not set +# CONFIG_DUMP_COMPRESS_GZIP is not set diff -urN linux-2.4.21/arch/ppc64/defconfig linux-2.4.22/arch/ppc64/defconfig --- linux-2.4.21/arch/ppc64/defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -27,6 +27,9 @@ # CONFIG_MSCHUNKS is not set CONFIG_RTAS_FLASH=m CONFIG_SCANLOG=m +CONFIG_PPC_RTAS=y +# CONFIG_RTAS_ERRINJCT is not set +# CONFIG_SHARED_MEMORY_ADDRESSING is not set # # Loadable module support @@ -190,7 +193,7 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set @@ -204,13 +207,11 @@ # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_PDC202XX_FORCE is not set # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set @@ -266,6 +267,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -361,6 +363,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set CONFIG_E100=y # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -467,12 +470,14 @@ CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y # CONFIG_FB_MATROX_G450 is not set +# CONFIG_FB_MATROX_G100A is not set +# CONFIG_FB_MATROX_PROC is not set # CONFIG_FB_MATROX_MULTIHEAD is not set # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set @@ -726,9 +731,8 @@ # CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set -CONFIG_XMON=y +# CONFIG_XMON is not set # CONFIG_KDB is not set -# CONFIG_KDB is not set -# CONFIG_KALLSYMS is not set +# CONFIG_DEBUG_SLAB is not set CONFIG_PPCDBG=y # CONFIG_DUMP is not set diff -urN linux-2.4.21/arch/ppc64/kernel/LparData.c linux-2.4.22/arch/ppc64/kernel/LparData.c --- linux-2.4.21/arch/ppc64/kernel/LparData.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/kernel/LparData.c 2003-08-25 04:44:40.000000000 -0700 @@ -71,7 +71,7 @@ 6, /* TEMP: This allows non-GA driver */ 4, /* We are v5r2m0 */ 3, /* Min supported PLIC = v5r1m0 */ - 3, /* Min usuable PLIC = v5r1m0 */ + 3, /* Min usable PLIC = v5r1m0 */ { 0xd3, 0x89, 0x95, 0xa4, /* "Linux 2.4 "*/ 0xa7, 0x40, 0xf2, 0x4b, 0xf4, 0x4b, 0xf6, 0xf4 }, diff -urN linux-2.4.21/arch/ppc64/kernel/Makefile linux-2.4.22/arch/ppc64/kernel/Makefile --- linux-2.4.21/arch/ppc64/kernel/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -27,7 +27,7 @@ pmc.o mf_proc.o proc_pmc.o proc_pcifr.o iSeries_setup.o \ ItLpQueue.o hvCall.o mf.o HvLpEvent.o ras.o \ iSeries_proc.o HvCall.o flight_recorder.o HvLpConfig.o \ - rtc.o perfmon.o + rtc.o perfmon.o cputable.o obj-$(CONFIG_PCI) += pci.o pci_dn.o pci_dma.o pSeries_lpar.o pSeries_hvCall.o diff -urN linux-2.4.21/arch/ppc64/kernel/XmPciLpEvent.c linux-2.4.22/arch/ppc64/kernel/XmPciLpEvent.c --- linux-2.4.21/arch/ppc64/kernel/XmPciLpEvent.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/kernel/XmPciLpEvent.c 2003-08-25 04:44:40.000000000 -0700 @@ -34,7 +34,7 @@ enum XmPciLpEvent_Subtype { XmPciLpEvent_BusCreated = 0, // PHB has been created XmPciLpEvent_BusError = 1, // PHB has failed - XmPciLpEvent_BusFailed = 2, // Msg to Seconday, Primary failed bus + XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered XmPciLpEvent_BusRecovered = 12, // PHB has been recovered @@ -99,7 +99,7 @@ break; } } - else if (event) { + else if (eventParm) { printk(KERN_ERR "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",(int)eventParm->xType); } else { diff -urN linux-2.4.21/arch/ppc64/kernel/align.c linux-2.4.22/arch/ppc64/kernel/align.c --- linux-2.4.21/arch/ppc64/kernel/align.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/kernel/align.c 2003-08-25 04:44:40.000000000 -0700 @@ -21,6 +21,7 @@ #include #include #include +#include struct aligninfo { unsigned char len; @@ -238,7 +239,7 @@ dsisr = regs->dsisr; /* Power4 doesn't set DSISR for an alignment interrupt */ - if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) + if (cur_cpu_spec->cpu_features & CPU_FTR_NODSISRALIGN) dsisr = make_dsisr( *((unsigned *)regs->nip) ); /* extract the operation and registers from the dsisr */ @@ -306,6 +307,7 @@ /* Doing stfs, have to convert to single */ enable_kernel_fp(); cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread.fpscr); + disable_kernel_fp(); } else data.dd = current->thread.fpr[reg]; @@ -339,6 +341,7 @@ /* Doing lfs, have to convert to double */ enable_kernel_fp(); cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread.fpscr); + disable_kernel_fp(); } else current->thread.fpr[reg] = data.dd; diff -urN linux-2.4.21/arch/ppc64/kernel/chrp_setup.c linux-2.4.22/arch/ppc64/kernel/chrp_setup.c --- linux-2.4.21/arch/ppc64/kernel/chrp_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/chrp_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -65,6 +65,7 @@ #include "open_pic.h" #include "xics.h" #include +#include extern volatile unsigned char *chrp_int_ack_special; @@ -305,6 +306,32 @@ SYSRQ_KEY = 0x63; /* Print Screen */ #endif #endif + /* Build up the firmware_features bitmask field + * using contents of device-tree/ibm,hypertas-functions. + * Ultimately this functionality may be moved into prom.c prom_init(). + */ + struct device_node * dn; + char * hypertas; + unsigned int len; + dn = find_path_device("/rtas"); + cur_cpu_spec->firmware_features=0; + hypertas = get_property(dn, "ibm,hypertas-functions", &len); + if (hypertas) { + while (len > 0){ + int i; + /* check value against table of strings */ + for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) { + if ((firmware_features_table[i].name) && (strcmp(firmware_features_table[i].name,hypertas))==0) { + /* we have a match */ + cur_cpu_spec->firmware_features |= (1UL << firmware_features_table[i].val ); + break; + } + } + int hypertas_len = strlen(hypertas); + len -= hypertas_len +1; + hypertas+= hypertas_len +1; + } + } } void __chrp @@ -315,6 +342,8 @@ char *os; static int display_character, set_indicator; static int max_width; + static spinlock_t progress_lock = SPIN_LOCK_UNLOCKED; + static int pending_newline = 0; /* did last write end with unprinted newline? */ if (!rtas.base) return; @@ -330,34 +359,79 @@ display_character = rtas_token("display-character"); set_indicator = rtas_token("set-indicator"); } - if (display_character == RTAS_UNKNOWN_SERVICE) { - /* use hex display */ - if (set_indicator == RTAS_UNKNOWN_SERVICE) - return; - rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex); + + if(display_character == RTAS_UNKNOWN_SERVICE) { + /* use hex display if available */ + if(set_indicator != RTAS_UNKNOWN_SERVICE) + rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex); return; } - rtas_call(display_character, 1, 1, NULL, '\r'); + spin_lock(&progress_lock); + /* Last write ended with newline, but we didn't print it since + * it would just clear the bottom line of output. Print it now + * instead. + * + * If no newline is pending, print a CR to start output at the + * beginning of the line. + */ + if(pending_newline) { + rtas_call(display_character, 1, 1, NULL, '\r'); + rtas_call(display_character, 1, 1, NULL, '\n'); + pending_newline = 0; + } else + rtas_call(display_character, 1, 1, NULL, '\r'); + width = max_width; os = s; - while ( *os ) - { - if ( (*os == '\n') || (*os == '\r') ) + while (*os) { + if(*os == '\n' || *os == '\r') { + /* Blank to end of line. */ + while(width-- > 0) + rtas_call(display_character, 1, 1, NULL, ' '); + + /* If newline is the last character, save it + * until next call to avoid bumping up the + * display output. + */ + if(*os == '\n' && !os[1]) { + pending_newline = 1; + spin_unlock(&progress_lock); + return; + } + + /* RTAS wants CR-LF, not just LF */ + + if(*os == '\n') { + rtas_call(display_character, 1, 1, NULL, '\r'); + rtas_call(display_character, 1, 1, NULL, '\n'); + } else { + /* CR might be used to re-draw a line, so we'll + * leave it alone and not add LF. + */ + rtas_call(display_character, 1, 1, NULL, *os); + } + width = max_width; - else + } else { width--; - rtas_call(display_character, 1, 1, NULL, *os++ ); + rtas_call(display_character, 1, 1, NULL, *os); + } + + os++; + /* if we overwrite the screen length */ - if ( width == 0 ) + if ( width <= 0 ) while ( (*os != 0) && (*os != '\n') && (*os != '\r') ) os++; } - + /* Blank to end of line. */ while ( width-- > 0 ) rtas_call(display_character, 1, 1, NULL, ' ' ); + + spin_unlock(&progress_lock); } extern void setup_default_decr(void); diff -urN linux-2.4.21/arch/ppc64/kernel/cputable.c linux-2.4.22/arch/ppc64/kernel/cputable.c --- linux-2.4.21/arch/ppc64/kernel/cputable.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/ppc64/kernel/cputable.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,127 @@ +/* + * arch/ppc/kernel/cputable.c + * + * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) + * + * Modifications for ppc64: + * Copyright (C) 2003 Dave Engebretsen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +struct cpu_spec* cur_cpu_spec = NULL; + +extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); + + +/* We only set the altivec features if the kernel was compiled with altivec + * support + */ +#ifdef CONFIG_ALTIVEC +#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC +#else +#define CPU_FTR_ALTIVEC_COMP 0 +#endif + +struct cpu_spec cpu_specs[] = { + { /* Power3 */ + 0xffff0000, 0x00400000, "Power3 (630)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power3, + COMMON_PPC64_FW + }, + { /* Power3+ */ + 0xffff0000, 0x00410000, "Power3 (630+)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power3, + COMMON_PPC64_FW + }, + { /* Northstar */ + 0xffff0000, 0x00330000, "Northstar", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power3, + COMMON_PPC64_FW + }, + { /* Pulsar */ + 0xffff0000, 0x00340000, "Pulsar", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power3, + COMMON_PPC64_FW + }, + { /* I-star */ + 0xffff0000, 0x00360000, "I-star", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power3, + COMMON_PPC64_FW + }, + { /* S-star */ + 0xffff0000, 0x00370000, "S-star", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power3, + COMMON_PPC64_FW + }, + { /* Power4 */ + 0xffff0000, 0x00350000, "Power4", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power4, + COMMON_PPC64_FW + }, + { /* Power4+ */ + 0xffff0000, 0x00380000, "Power4+", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power4, + COMMON_PPC64_FW + }, + { /* default match */ + 0x00000000, 0x00000000, "(Power4-Compatible)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power4, + COMMON_PPC64_FW + } +}; + +firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = { + {FW_FEATURE_PFT, "hcall-pft"}, + {FW_FEATURE_TCE, "hcall-tce"}, + {FW_FEATURE_SPRG0, "hcall-sprg0"}, + {FW_FEATURE_DABR, "hcall-dabr"}, + {FW_FEATURE_COPY, "hcall-copy"}, + {FW_FEATURE_ASR, "hcall-asr"}, + {FW_FEATURE_DEBUG, "hcall-debug"}, + {FW_FEATURE_PERF, "hcall-perf"}, + {FW_FEATURE_DUMP, "hcall-dump"}, + {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, + {FW_FEATURE_MIGRATE, "hcall-migrate"}, +}; diff -urN linux-2.4.21/arch/ppc64/kernel/eeh.c linux-2.4.22/arch/ppc64/kernel/eeh.c --- linux-2.4.21/arch/ppc64/kernel/eeh.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/eeh.c 2003-08-25 04:44:40.000000000 -0700 @@ -129,17 +129,16 @@ int adapters_enabled; }; -/* Enable eeh for the given device node. */ -static void *early_enable_eeh(struct device_node *dn, void *data) + +/* Enable/disable eeh for the given device node. */ +static void *early_set_eeh(struct device_node *dn, struct eeh_early_enable_info *info, int enable) { - struct eeh_early_enable_info *info = data; long ret; char *status = get_property(dn, "status", 0); u32 *class_code = (u32 *)get_property(dn, "class-code", 0); u32 *vendor_id =(u32 *) get_property(dn, "vendor-id", 0); u32 *device_id = (u32 *)get_property(dn, "device-id", 0); u32 *regs; - int enable; if (status && strcmp(status, "ok") != 0) return NULL; /* ignore devices with bad status */ @@ -161,15 +160,19 @@ * hang waiting on status bits that won't change, etc. * But there are a few cases like display devices that make sense. */ - enable = 1; /* i.e. we will do checking */ - if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY) - enable = 0; if (!eeh_check_opts_config(dn, *class_code, *vendor_id, *device_id, enable)) { if (enable) { printk(KERN_INFO "EEH: %s user requested to run without EEH.\n", dn->full_name); enable = 0; } +#if 0 + /* Turn off EEH automatically for graphics ... + * but we don't want to do this, not really. .... */ + } else if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY) { + printk(KERN_INFO "EEH: %s DISPLAY automatically set to run without EEH.\n", dn->full_name); + enable = 0; +#endif } if (!enable) @@ -179,6 +182,16 @@ if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) { /* Parent supports EEH. */ dn->eeh_mode |= EEH_MODE_SUPPORTED; + + /* Recurse to parent to set EEH, since we are probably + * a non-eeh supporting pci bridge chip on some card. + * But recurse only if our eeh setting is to be different. + */ + if ((enable && (EEH_MODE_NOCHECK == dn->eeh_mode)) || + (!enable && (EEH_MODE_NOCHECK != dn->eeh_mode))) + { + early_set_eeh (dn->parent, info, enable); + } dn->eeh_config_addr = dn->parent->eeh_config_addr; return NULL; } @@ -187,19 +200,29 @@ regs = (u32 *)get_property(dn, "reg", 0); if (regs) { /* First register entry is addr (00BBSS00) */ - /* Try to enable eeh */ + /* Try to enable/disable eeh */ ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL, regs[0], info->buid_hi, info->buid_lo, - EEH_ENABLE); + enable ? EEH_ENABLE : EEH_DISABLE); if (ret == 0) { info->adapters_enabled++; dn->eeh_mode |= EEH_MODE_SUPPORTED; dn->eeh_config_addr = regs[0]; + } else { + printk(KERN_INFO "EEH: %s failed to %s ret=%ld\n", dn->full_name, enable ? "enable" : "disable", ret); } } return NULL; } +/* Enable eeh for the given device node. */ +static void *early_enable_eeh(struct device_node *dn, void *data) +{ + struct eeh_early_enable_info *info = data; + /* Set enable to 1, i.e. we will do checking */ + return early_set_eeh (dn, info, 1); +} + /* * Initialize eeh by trying to enable it for all of the adapters in the system. * As a side effect we can determine here if eeh is supported at all. diff -urN linux-2.4.21/arch/ppc64/kernel/entry.S linux-2.4.22/arch/ppc64/kernel/entry.S --- linux-2.4.21/arch/ppc64/kernel/entry.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -437,7 +437,7 @@ mfsrr1 r10 std r10,_SRR1(r1) - /* Unfortunatly, the stack pointer and the MSR are also clobbered, + /* Unfortunately, the stack pointer and the MSR are also clobbered, * so they are saved in the PACA (SPRG3) which allows us to restore * our original state after RTAS returns. */ @@ -548,7 +548,7 @@ mfmsr r11 std r11,_MSR(r1) - /* Unfortunatly, the stack pointer is also clobbered, so it is saved + /* Unfortunately, the stack pointer is also clobbered, so it is saved * in the SPRG2 which allows us to restore our original state after * PROM returns. */ diff -urN linux-2.4.21/arch/ppc64/kernel/head.S linux-2.4.22/arch/ppc64/kernel/head.S --- linux-2.4.21/arch/ppc64/kernel/head.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -746,6 +747,13 @@ #ifdef CONFIG_XMON bl .xmon #endif +#ifdef CONFIG_KDB + /* kdb(KDB_REASON_FAULT,regs->trap,regs); */ + li r3,1 + li r4,0x200 + li r5,0 + bl .kdb +#endif 4: b 4b @@ -781,11 +789,16 @@ FPUnavailable_common: EXCEPTION_PROLOG_COMMON bne .load_up_fpu /* if from user, just load it up */ - li r20,0 + addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef DO_SOFT_DISABLE + ld r20,SOFTE(r1) +#else + rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ +#endif li r6,0x800 - bl .save_remaining_regs /* if from kernel, take a trap */ - bl .KernelFP - b .ret_from_except + bl .save_remaining_regs + bl .KernelFPUnavailableException + BUG_OPCODE .globl SystemCall_common SystemCall_common: @@ -1390,6 +1403,11 @@ li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) + LOADADDR(r3,cpu_specs) + LOADADDR(r4,cur_cpu_spec) + li r5,0 + bl .identify_cpu + LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 @@ -1619,21 +1637,19 @@ /* restore registers and return */ b fast_exception_return + /* - * FP unavailable trap from kernel - print a message, but let - * the task use FP in the kernel until it returns to user mode. + * disable_kernel_fp() + * Disable the FPU. */ -_GLOBAL(KernelFP) - ld r3,_MSR(r1) - ori r3,r3,MSR_FP - std r3,_MSR(r1) /* enable use of FP after return */ - LOADADDR(r3,86f) - mfspr r4,SPRG3 /* Get PACA */ - ld r4,PACACURRENT(r4) /* current */ - ld r5,_NIP(r1) - b .ret_from_except -86: .string "floating point used in kernel (task=%p, pc=%x)\n" - .align 4 +_GLOBAL(disable_kernel_fp) + mfmsr r3 + rldicl r0,r3,(63-MSR_FP_LG),1 + rldicl r3,r0,(MSR_FP_LG+1),0 + mtmsrd r3 /* disable use of fpu now */ + isync + blr + /* * giveup_fpu(tsk) @@ -1861,6 +1877,13 @@ li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) + LOADADDR(r3,cpu_specs) + sub r3,r3,r26 + LOADADDR(r4,cur_cpu_spec) + sub r4,r4,r26 + mr r5,r26 + bl .identify_cpu + /* set up the TOC (physical address) */ LOADADDR(r2,__toc_start) addi r2,r2,0x4000 @@ -1949,6 +1972,9 @@ addi r2,r2,0x4000 addi r2,r2,0x4000 + li r3,0 + bl .do_cpu_ftr_fixups + /* setup the systemcfg pointer */ LOADADDR(r9,systemcfg) SET_REG_TO_CONST(r8, KERNELBASE+0x5000) @@ -2006,6 +2032,11 @@ bl .start_kernel +_GLOBAL(__setup_cpu_power3) + blr +_GLOBAL(__setup_cpu_power4) + blr + _GLOBAL(hmt_init) #ifdef CONFIG_HMT LOADADDR(r5, hmt_thread_data) diff -urN linux-2.4.21/arch/ppc64/kernel/htab.c linux-2.4.22/arch/ppc64/kernel/htab.c --- linux-2.4.21/arch/ppc64/kernel/htab.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/htab.c 2003-08-25 04:44:40.000000000 -0700 @@ -46,6 +46,7 @@ #include #include #include +#include /* * Note: pte --> Linux PTE @@ -183,7 +184,9 @@ /* XXX we currently map kernel text rw, should fix this */ if ((systemcfg->platform & PLATFORM_PSERIES) && - cpu_has_largepage() && (systemcfg->physicalMemorySize > 256*MB)) { + (cur_cpu_spec->cpu_features & + CPU_FTR_16M_PAGE) && + (systemcfg->physicalMemorySize > 256*MB)) { create_pte_mapping((unsigned long)KERNELBASE, KERNELBASE + 256*MB, mode_rw, mask, 0); create_pte_mapping((unsigned long)KERNELBASE + 256*MB, @@ -334,11 +337,23 @@ * Check the user's access rights to the page. If access should be * prevented then send the problem up to do_page_fault. */ +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING + access |= _PAGE_PRESENT; + if (unlikely(access & ~(pte_val(*ptep)))) { + if(!(((ea >> SMALLOC_EA_SHIFT) == + (SMALLOC_START >> SMALLOC_EA_SHIFT)) && + ((current->thread.flags) & PPC_FLAG_SHARED))) { + spin_unlock(&hash_table_lock[lock_slot].lock); + return 1; + } + } +#else access |= _PAGE_PRESENT; if (unlikely(access & ~(pte_val(*ptep)))) { spin_unlock(&hash_table_lock[lock_slot].lock); return 1; } +#endif /* * We have found a pte (which was present). @@ -446,6 +461,19 @@ case VMALLOC_REGION_ID: mm = &init_mm; vsid = get_kernel_vsid(ea); +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING + /* + * Check if this is a user task with shared access to kernel + * data & we got a protection fault. If it is, the kernel + * must have faulted in the segment and the protection flags + * on the segment are kernel access only. Just flush the + * segment table & fault in the segment with the right flags. + */ + if(((current->thread.flags) & PPC_FLAG_SHARED) && + (access & _PAGE_USER)) { + flush_stab(); + } +#endif break; case EEH_REGION_ID: /* diff -urN linux-2.4.21/arch/ppc64/kernel/i8259.c linux-2.4.22/arch/ppc64/kernel/i8259.c --- linux-2.4.21/arch/ppc64/kernel/i8259.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/i8259.c 2003-08-25 04:44:40.000000000 -0700 @@ -146,7 +146,7 @@ /* init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ + outb(0x04, 0x21); /* edge triggered, Cascade (slave) on IRQ2 */ outb(0x01, 0x21); /* Select 8086 mode */ outb(0xFF, 0x21); /* Mask all */ /* init slave interrupt controller */ diff -urN linux-2.4.21/arch/ppc64/kernel/iSeries_IoMmTable.h linux-2.4.22/arch/ppc64/kernel/iSeries_IoMmTable.h --- linux-2.4.21/arch/ppc64/kernel/iSeries_IoMmTable.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/iSeries_IoMmTable.h 2003-08-25 04:44:40.000000000 -0700 @@ -71,7 +71,7 @@ /* iSeries_xlateIoMmAddress */ /************************************************************************/ /* - Translates an I/O Memory address to Device Node that has been the */ -/* allocated the psuedo I/O Address. */ +/* allocated the pseudo I/O Address. */ /* */ /* Parameters: */ /* IoAddress = I/O Memory Address. */ diff -urN linux-2.4.21/arch/ppc64/kernel/iSeries_setup.c linux-2.4.22/arch/ppc64/kernel/iSeries_setup.c --- linux-2.4.21/arch/ppc64/kernel/iSeries_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/iSeries_setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -49,6 +49,7 @@ #include #include #include +#include /* Function Prototypes */ @@ -249,7 +250,8 @@ { unsigned long i; unsigned long mem_blocks = 0; - if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) + + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) mem_blocks = iSeries_process_Regatta_mainstore_vpd( mb_array, max_entries ); else mem_blocks = iSeries_process_Condor_mainstore_vpd( mb_array, max_entries ); diff -urN linux-2.4.21/arch/ppc64/kernel/ioctl32.c linux-2.4.22/arch/ppc64/kernel/ioctl32.c --- linux-2.4.21/arch/ppc64/kernel/ioctl32.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/ioctl32.c 2003-08-25 04:44:40.000000000 -0700 @@ -581,6 +581,17 @@ len += sizeof(struct ethtool_regs); break; } + case ETHTOOL_GEEPROM: + case ETHTOOL_SEEPROM: { + struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data); + /* darned variable size arguments */ + if (get_user(len, (u32 *)&promaddr->len)) { + err = -EFAULT; + goto out; + } + len += sizeof(struct ethtool_eeprom); + break; + } case ETHTOOL_GSET: case ETHTOOL_SSET: len = sizeof(struct ethtool_cmd); break; default: @@ -3070,7 +3081,7 @@ #define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t) /* RED PEN The DRM layer blindly dereferences the send/request - * indice/size arrays even though they are userland + * index/size arrays even though they are userland * pointers. -DaveM */ static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -3894,6 +3905,7 @@ /* RAID */ COMPATIBLE_IOCTL(RAID_VERSION), +COMPATIBLE_IOCTL(RAID_AUTORUN), COMPATIBLE_IOCTL(GET_ARRAY_INFO), COMPATIBLE_IOCTL(GET_DISK_INFO), COMPATIBLE_IOCTL(PRINT_RAID_DEBUG), diff -urN linux-2.4.21/arch/ppc64/kernel/mf.c linux-2.4.22/arch/ppc64/kernel/mf.c --- linux-2.4.21/arch/ppc64/kernel/mf.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/kernel/mf.c 2003-08-25 04:44:40.000000000 -0700 @@ -44,7 +44,7 @@ extern struct pci_dev * iSeries_vio_dev; /* - * This is the structure layout for the Machine Facilites LPAR event + * This is the structure layout for the Machine Facilities LPAR event * flows. */ struct VspCmdData; @@ -402,7 +402,8 @@ */ static int shutdown( void ) { - int rc = kill_proc(1,SIGINT,1); + extern int cad_pid; /* from kernel/sys.c */ + int rc = kill_proc(cad_pid,SIGINT,1); if ( rc ) { diff -urN linux-2.4.21/arch/ppc64/kernel/misc.S linux-2.4.22/arch/ppc64/kernel/misc.S --- linux-2.4.21/arch/ppc64/kernel/misc.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/misc.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,5 +1,5 @@ /* - * arch/ppc/kernel/misc.S + * arch/ppc64/kernel/misc.S * * * @@ -25,6 +25,7 @@ #include #include #include +#include #include "ppc_asm.h" .text @@ -353,7 +354,6 @@ bdnz 00b blr -_GLOBAL(ide_insw) _GLOBAL(_insw_ns) cmpwi 0,r5,0 mtctr r5 @@ -365,7 +365,6 @@ bdnz 00b blr -_GLOBAL(ide_outsw) _GLOBAL(_outsw_ns) cmpwi 0,r5,0 mtctr r5 @@ -480,6 +479,93 @@ blr /* + * identify_cpu, + * In: r3 = base of the cpu_specs array + * r4 = address of cur_cpu_spec + * r5 = relocation offset + */ +_GLOBAL(identify_cpu) + mfpvr r7 +1: + lwz r8,CPU_SPEC_PVR_MASK(r3) + and r8,r8,r7 + lwz r9,CPU_SPEC_PVR_VALUE(r3) + cmplw 0,r9,r8 + beq 1f + addi r3,r3,CPU_SPEC_ENTRY_SIZE + b 1b +1: + add r3,r3,r5 + std r3,0(r4) + blr + +/* + * do_cpu_ftr_fixups - goes through the list of CPU feature fixups + * and writes nop's over sections of code that don't apply for this cpu. + * r3 = data offset (not changed) + */ +_GLOBAL(do_cpu_ftr_fixups) + /* Get CPU 0 features */ + LOADADDR(r6,cur_cpu_spec) + sub r6,r6,r3 + ld r4,0(r6) + sub r4,r4,r3 + ld r4,CPU_SPEC_FEATURES(r4) + /* Get the fixup table */ + LOADADDR(r6,__start___ftr_fixup) + sub r6,r6,r3 + LOADADDR(r7,__stop___ftr_fixup) + sub r7,r7,r3 + /* Do the fixup */ +1: cmpld r6,r7 + bgelr + addi r6,r6,32 + ld r8,-32(r6) /* mask */ + and r8,r8,r4 + ld r9,-24(r6) /* value */ + cmpld r8,r9 + beq 1b + ld r8,-16(r6) /* section begin */ + ld r9,-8(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + sub r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) + andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l + beq 2f + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +2: addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b + +/* + * call_setup_cpu - call the setup_cpu function for this cpu + * r3 = data offset + * + * Setup function is called with: + * r3 = data offset + * r4 = ptr to CPU spec (relocated) + */ +_GLOBAL(call_setup_cpu) + LOADADDR(r4, cur_cpu_spec) + sub r4,r4,r3 + lwz r4,0(r4) # load pointer to cpu_spec + sub r4,r4,r3 # relocate + lwz r6,CPU_SPEC_SETUP(r4) # load function pointer + sub r6,r6,r3 + mtctr r6 + bctr + +/* * Create a kernel thread * arch_kernel_thread(fn, arg, flags) */ @@ -717,7 +803,24 @@ .llong .sys_madvise /* 205 */ .llong .sys_mincore /* 206 */ .llong .sys_gettid /* 207 */ - .rept NR_syscalls-208 +#if 0 /* Reserved syscalls */ + .llong .sys_tkill /* 208 */ + .llong .sys_setxattr + .llong .sys_lsetxattr /* 210 */ + .llong .sys_fsetxattr + .llong .sys_getxattr + .llong .sys_lgetxattr + .llong .sys_fgetxattr + .llong .sys_listxattr /* 215 */ + .llong .sys_llistxattr + .llong .sys_flistxattr + .llong .sys_removexattr + .llong .sys_lremovexattr + .llong .sys_fremovexattr /* 220 */ + .llong .sys_futex +#endif + .llong .sys_perfmonctl /* Put this here for now ... */ + .rept NR_syscalls-222 .llong .sys_ni_syscall .endr #endif @@ -931,6 +1034,23 @@ .llong .sys_madvise /* 205 */ .llong .sys_mincore /* 206 */ .llong .sys_gettid /* 207 */ - .rept NR_syscalls-208 +#if 0 /* Reserved syscalls */ + .llong .sys_tkill /* 208 */ + .llong .sys_setxattr + .llong .sys_lsetxattr /* 210 */ + .llong .sys_fsetxattr + .llong .sys_getxattr + .llong .sys_lgetxattr + .llong .sys_fgetxattr + .llong .sys_listxattr /* 215 */ + .llong .sys_llistxattr + .llong .sys_flistxattr + .llong .sys_removexattr + .llong .sys_lremovexattr + .llong .sys_fremovexattr /* 220 */ + .llong .sys_futex +#endif + .llong .sys_perfmonctl /* Put this here for now ... */ + .rept NR_syscalls-222 .llong .sys_ni_syscall .endr diff -urN linux-2.4.21/arch/ppc64/kernel/mk_defs.c linux-2.4.22/arch/ppc64/kernel/mk_defs.c --- linux-2.4.21/arch/ppc64/kernel/mk_defs.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/mk_defs.c 2003-08-25 04:44:40.000000000 -0700 @@ -37,6 +37,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n#define\t" #sym "\t%0" : : "i" (val)) @@ -188,5 +189,12 @@ DEFINE(CLONE_VM, CLONE_VM); + /* About the CPU features table */ + DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec)); + DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask)); + DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); + DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); + DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + return 0; } diff -urN linux-2.4.21/arch/ppc64/kernel/pSeries_lpar.c linux-2.4.22/arch/ppc64/kernel/pSeries_lpar.c --- linux-2.4.21/arch/ppc64/kernel/pSeries_lpar.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/kernel/pSeries_lpar.c 2003-08-25 04:44:40.000000000 -0700 @@ -276,7 +276,6 @@ -/* Code for hvc_console. Should move it back eventually. */ int hvc_get_chars(int index, char *buf, int count) { diff -urN linux-2.4.21/arch/ppc64/kernel/pci.c linux-2.4.22/arch/ppc64/kernel/pci.c --- linux-2.4.21/arch/ppc64/kernel/pci.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -137,7 +137,7 @@ ioaddr = (addr > _IO_BASE) ? addr - _IO_BASE : 0; pci_for_each_dev(dev) { - if ((dev->class >> 8) == PCI_BASE_CLASS_BRIDGE) + if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) continue; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { unsigned long start = pci_resource_start(dev,i); diff -urN linux-2.4.21/arch/ppc64/kernel/pci.h linux-2.4.22/arch/ppc64/kernel/pci.h --- linux-2.4.21/arch/ppc64/kernel/pci.h 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/pci.h 2003-08-25 04:44:40.000000000 -0700 @@ -71,7 +71,7 @@ static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) { struct device_node *dn = (struct device_node *)(dev->sysdata); - if (dn->devfn == dev->devfn && dn->busno == dev->bus->number) + if (dn->devfn == dev->devfn && dn->busno == (dev->bus->number&0xff)) return dn; /* fast path. sysdata is good */ else return fetch_dev_dn(dev); diff -urN linux-2.4.21/arch/ppc64/kernel/pci_dma.c linux-2.4.22/arch/ppc64/kernel/pci_dma.c --- linux-2.4.21/arch/ppc64/kernel/pci_dma.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/pci_dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -713,12 +713,6 @@ for (ln=bus_list->next; ln != bus_list; ln=ln->next) { bus = pci_bus_b(ln); busdn = PCI_GET_DN(bus); - /* NOTE: there should never be a window declared on a bus when - * child devices also have a window. If this should ever be - * architected, we probably want children to have priority. - * In reality, the PHB containing ISA has the property, but otherwise - * it is the pci-bridges that have the property. - */ dma_window = (u32 *)get_property(busdn, "ibm,dma-window", 0); if (dma_window) { /* Busno hasn't been copied yet. @@ -726,8 +720,9 @@ */ busdn->busno = bus->number; create_pci_bus_tce_table((unsigned long)busdn); - } else - create_tce_tables_for_busesLP(&bus->children); + } + /* look for a window on a bridge even if the PHB had one */ + create_tce_tables_for_busesLP(&bus->children); } } @@ -1349,7 +1344,7 @@ { struct TceTable * tbl; unsigned numTces; - int num_dma; + int num_dma = 0; dma_addr_t dma_handle; PPCDBG(PPCDBG_TCE, "pci_map_sg:\n"); @@ -1373,6 +1368,8 @@ /* Create the tces and get the dma address */ dma_handle = create_tces_sg( tbl, sg, nents, numTces, direction ); + if(dma_handle == NO_TCE) return 0; + /* Fill in the dma scatterlist */ num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces ); } diff -urN linux-2.4.21/arch/ppc64/kernel/perfmon.c linux-2.4.22/arch/ppc64/kernel/perfmon.c --- linux-2.4.21/arch/ppc64/kernel/perfmon.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/perfmon.c 2003-08-25 04:44:40.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include extern char _stext[], _etext[], _end[]; struct perfmon_base_struct perfmon_base = {0, 0, 0, 0, 0, 0, 0, PMC_STATE_INITIAL}; @@ -450,7 +451,7 @@ } perfmon_base.state = PMC_STATE_PROFILE_KERN; - if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) { + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { for(i = 0; i < 8; i++) pdata->pmc[i] = 0x0; pdata->pmc[1] = 0x7f000000; @@ -794,7 +795,7 @@ * Flood enabled is required on GP for PMC cycle profile mode * iSeries SP sets this by default. pSeries requires the OS to enable. */ - if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) { + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { /* Set up the debug bus to pmc mode - a feature of GP */ switch(systemcfg->platform) { case PLATFORM_ISERIES_LPAR: diff -urN linux-2.4.21/arch/ppc64/kernel/pmc.c linux-2.4.22/arch/ppc64/kernel/pmc.c --- linux-2.4.21/arch/ppc64/kernel/pmc.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/pmc.c 2003-08-25 04:44:40.000000000 -0700 @@ -206,7 +206,7 @@ * the segment table. * * Input : unsigned long size: bytes of storage to allocate. - * Return: void * : pointer to the kernal address of the buffer. + * Return: void * : pointer to the kernel address of the buffer. */ void* btmalloc (unsigned long size) { pgd_t *pgdp; diff -urN linux-2.4.21/arch/ppc64/kernel/ppc_ksyms.c linux-2.4.22/arch/ppc64/kernel/ppc_ksyms.c --- linux-2.4.21/arch/ppc64/kernel/ppc_ksyms.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/ppc_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -78,6 +78,13 @@ extern struct pci_dev * iSeries_veth_dev; extern struct pci_dev * iSeries_vio_dev; +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING +extern void shared_malloc(unsigned long); +extern void shared_free(void *); +extern int shared_task_mark(); +extern int shared_task_unmark(); +#endif + EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(syscall_trace); EXPORT_SYMBOL(do_IRQ); @@ -309,3 +316,10 @@ extern void dump_send_ipi(int (*dump_ipi_callback)(struct pt_regs *)); EXPORT_SYMBOL(dump_send_ipi); #endif + +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING +EXPORT_SYMBOL(shared_malloc); +EXPORT_SYMBOL(shared_free); +EXPORT_SYMBOL(shared_task_mark); +EXPORT_SYMBOL(shared_task_unmark); +#endif diff -urN linux-2.4.21/arch/ppc64/kernel/proc_pcifr.c linux-2.4.22/arch/ppc64/kernel/proc_pcifr.c --- linux-2.4.21/arch/ppc64/kernel/proc_pcifr.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/proc_pcifr.c 2003-08-25 04:44:40.000000000 -0700 @@ -198,10 +198,18 @@ /* look for the net devices out */ for (dev = dev_base; dev != NULL; dev = dev->next) { - if (dev->base_addr == PciDev->resource[0].start ) { - BufLen += sprintf(ProcBuffer+BufLen, " - Net device: %s\n", dev->name); + int j; + + if (!dev->base_addr) /* virtual device, no base address */ break; - } /* if */ + + for (j=0;j<6;j++) { /* PCI has 6 base addresses */ + if (dev->base_addr == PciDev->resource[j].start ) { + BufLen += sprintf(ProcBuffer+BufLen, " - Net device: %s\n", dev->name); + break; + } /* if */ + } + if (j!=6) break; /* found one */ } /* for */ } /* if(PCI_SLOT(PciDev->devfn) != 0) */ } diff -urN linux-2.4.21/arch/ppc64/kernel/proc_pmc.c linux-2.4.22/arch/ppc64/kernel/proc_pmc.c --- linux-2.4.21/arch/ppc64/kernel/proc_pmc.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/proc_pmc.c 2003-08-25 04:44:40.000000000 -0700 @@ -49,12 +49,12 @@ static int proc_pmc_control_mode = 0; -static struct proc_dir_entry *proc_ppc64_root = NULL; +struct proc_dir_entry *proc_ppc64_root = NULL; static struct proc_dir_entry *proc_ppc64_pmc_root = NULL; static struct proc_dir_entry *proc_ppc64_pmc_system_root = NULL; static struct proc_dir_entry *proc_ppc64_pmc_cpu_root[NR_CPUS] = {NULL, }; -static spinlock_t proc_ppc64_lock; +spinlock_t proc_ppc64_lock; static int proc_ppc64_page_read(char *page, char **start, off_t off, int count, int *eof, void *data); static void proc_ppc64_create_paca(int num, struct proc_dir_entry *paca_dir); @@ -145,8 +145,13 @@ * /proc/ppc64/pmc/cpu0 */ spin_lock(&proc_ppc64_lock); - proc_ppc64_root = proc_mkdir("ppc64", 0); - if (!proc_ppc64_root) return; + if (proc_ppc64_root == NULL) { + proc_ppc64_root = proc_mkdir("ppc64", 0); + if (!proc_ppc64_root) { + spin_unlock(&proc_ppc64_lock); + return; + } + } spin_unlock(&proc_ppc64_lock); ent = create_proc_entry("naca", S_IFREG|S_IRUGO, proc_ppc64_root); @@ -173,7 +178,9 @@ } /* Placeholder for rtas interfaces. */ - rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root); + if (rtas_proc_dir == NULL) { + rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root); + } /* Create the /proc/ppc64/pcifr for the Pci Flight Recorder. */ proc_pciFr_init(proc_ppc64_root); diff -urN linux-2.4.21/arch/ppc64/kernel/process.c linux-2.4.22/arch/ppc64/kernel/process.c --- linux-2.4.21/arch/ppc64/kernel/process.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 @@ -42,6 +42,7 @@ #include #include #include +#include int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs); @@ -390,7 +391,7 @@ * __get_free_pages() might give us a page > KERNBASE+256M which * is mapped with large ptes so we can't set up the guard page. */ - if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) + if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) return; for (i=0; i < systemcfg->processorCount; i++) { @@ -493,7 +494,7 @@ * gets fixed. */ if (ip < first_sched || ip >= last_sched) - return (ip & 0xFFFFFFFF); + return (ip); } } while (count++ < 16); return 0; diff -urN linux-2.4.21/arch/ppc64/kernel/prom.c linux-2.4.22/arch/ppc64/kernel/prom.c --- linux-2.4.21/arch/ppc64/kernel/prom.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/prom.c 2003-08-25 04:44:40.000000000 -0700 @@ -363,7 +363,7 @@ * d-cache and i-cache sizes... -Peter */ if ( num_cpus == 1 ) { - u32 size, lsize; + u32 size, lsize, sets; call_prom(RELOC("getprop"), 4, 1, node, RELOC("d-cache-size"), @@ -631,6 +631,7 @@ unsigned long offset = reloc_offset(); struct prom_t *_prom = PTRRELOC(&prom); struct rtas_t *_rtas = PTRRELOC(&rtas); + struct naca_struct *_naca = RELOC(naca); struct systemcfg *_systemcfg = RELOC(systemcfg); ihandle prom_rtas; u32 getprop_rval; @@ -1059,6 +1060,7 @@ unsigned long *spinloop = __v2a(&__secondary_hold_spinloop); unsigned long *acknowledge = __v2a(&__secondary_hold_acknowledge); unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold)); + struct naca_struct *_naca = RELOC(naca); struct systemcfg *_systemcfg = RELOC(systemcfg); struct paca_struct *_xPaca = PTRRELOC(&paca[0]); struct prom_t *_prom = PTRRELOC(&prom); @@ -1237,7 +1239,7 @@ #ifdef CONFIG_PPCDBG extern char *trace_names[]; /* defined in udbg.c -- need a better interface */ -static void parse_ppcdbg_optionlist(const char *cmd, +void parse_ppcdbg_optionlist(const char *cmd, const char *cmdend) { unsigned long offset = reloc_offset(); @@ -1559,7 +1561,7 @@ } /* We assume the phys. address size is 3 cells */ - RELOC(prom_mmu) = (ihandle)(unsigned long)getprop_rval; + prom_mmu = (ihandle)(unsigned long)getprop_rval; if ((long)call_prom(RELOC("call-method"), 4, 4, RELOC("translate"), diff -urN linux-2.4.21/arch/ppc64/kernel/rtas-proc.c linux-2.4.22/arch/ppc64/kernel/rtas-proc.c --- linux-2.4.21/arch/ppc64/kernel/rtas-proc.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/rtas-proc.c 2003-08-25 04:44:40.000000000 -0700 @@ -115,14 +115,18 @@ /* Globals */ -static struct proc_dir_entry *proc_rtas; static struct rtas_sensors sensors; -static struct device_node *rtas_node; +static struct device_node *rtas_node = NULL; static unsigned long power_on_time = 0; /* Save the time the user set */ static char progress_led[MAX_LINELENGTH]; static unsigned long rtas_tone_frequency = 1000; static unsigned long rtas_tone_volume = 0; +static unsigned int open_token = 0; + +extern struct proc_dir_entry *proc_ppc64_root; +extern struct proc_dir_entry *rtas_proc_dir; +extern spinlock_t proc_ppc64_lock; /* ****************STRUCTS******************************************* */ struct individual_sensor { @@ -160,6 +164,12 @@ size_t count, loff_t *ppos); static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, size_t count, loff_t *ppos); +static int ppc_rtas_errinjct_open(struct inode *inode, struct file *file); +static int ppc_rtas_errinjct_release(struct inode *inode, struct file *file); +static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf, + size_t count, loff_t *ppos); struct file_operations ppc_rtas_poweron_operations = { .read = ppc_rtas_poweron_read, @@ -184,6 +194,13 @@ .write = ppc_rtas_tone_volume_write }; +struct file_operations ppc_rtas_errinjct_operations = { + .open = ppc_rtas_errinjct_open, + .read = ppc_rtas_errinjct_read, + .write = ppc_rtas_errinjct_write, + .release = ppc_rtas_errinjct_release +}; + int ppc_rtas_find_all_sensors (void); int ppc_rtas_process_sensor(struct individual_sensor s, int state, int error, char * buf); @@ -200,33 +217,54 @@ struct proc_dir_entry *entry; rtas_node = find_devices("rtas"); - if ((rtas_node == 0) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) { + if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) { return; } - proc_rtas = proc_mkdir("rtas", 0); - if (proc_rtas == 0) + spin_lock(&proc_ppc64_lock); + if (proc_ppc64_root == NULL) { + proc_ppc64_root = proc_mkdir("ppc64", 0); + if (!proc_ppc64_root) { + spin_unlock(&proc_ppc64_lock); + return; + } + } + spin_unlock(&proc_ppc64_lock); + + if (rtas_proc_dir == NULL) { + rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root); + } + + if (rtas_proc_dir == NULL) { + printk(KERN_ERR "Failed to create /proc/ppc64/rtas in rtas_init\n"); return; + } /* /proc/rtas entries */ - entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas); + entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, rtas_proc_dir); if (entry) entry->proc_fops = &ppc_rtas_progress_operations; - entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); + entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, rtas_proc_dir); if (entry) entry->proc_fops = &ppc_rtas_clock_operations; - entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); + entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, rtas_proc_dir); if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; - create_proc_read_entry("sensors", S_IRUGO, proc_rtas, + create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir, ppc_rtas_sensor_read, NULL); - entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); + entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, rtas_proc_dir); if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; - entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); + entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, rtas_proc_dir); if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; + +#ifdef CONFIG_RTAS_ERRINJCT + entry = create_proc_entry("errinjct", S_IWUSR|S_IRUGO, rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations; +#endif + } /* ****************************************************************** */ @@ -405,10 +443,14 @@ j = sensors.sensor[i].quant; /* A sensor may have multiple instances */ while (j >= 0) { + error = rtas_call(get_sensor_state, 2, 2, &ret, - sensors.sensor[i].token, sensors.sensor[i].quant-j); + sensors.sensor[i].token, + sensors.sensor[i].quant - j); + state = (int) ret; - n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); + n += ppc_rtas_process_sensor(sensors.sensor[i], state, + error, buffer+n ); n += sprintf (buffer+n, "\n"); j--; } /* while */ @@ -426,6 +468,7 @@ n = count; else *eof = 1; + memcpy(buf, buffer + off, n); *start = buf; kfree(buffer); @@ -436,10 +479,10 @@ int ppc_rtas_find_all_sensors (void) { - unsigned long *utmp; - int len, i, j; + unsigned int *utmp; + int len, i; - utmp = (unsigned long *) get_property(rtas_node, "rtas-sensors", &len); + utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len); if (utmp == NULL) { printk (KERN_ERR "error: could not get rtas-sensors\n"); return 1; @@ -447,9 +490,9 @@ sensors.quant = len / 8; /* int + int */ - for (i=0, j=0; j token_len + WORKSPACE_SIZE) { + count = token_len + WORKSPACE_SIZE; + } + + buf += token_len; + + /* check if there is a workspace */ + if (count > token_len) { + /* Verify the workspace size */ + if ((count - token_len) > WORKSPACE_SIZE) { + max_len = WORKSPACE_SIZE; + } else { + max_len = count - token_len; + } + + workspace = (char *)kmalloc(max_len, GFP_KERNEL); + if (!workspace) { + printk(KERN_WARNING "error: failed kmalloc\n"); + kfree(ei_token); + return -ENOMEM; + } + + memcpy(workspace, buf, max_len); + } + + rc = rtas_errinjct(open_token, ei_token, workspace); + + if (count > token_len) { + kfree(workspace); + } + kfree(ei_token); + + return rc < 0 ? rc : count; +} + +static int ppc_rtas_errinjct_release(struct inode *inode, struct file *file) +{ + int rc; + + rc = rtas_errinjct_close(open_token); + if (rc) { + return rc; + } + open_token = 0; + return 0; +} + +static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + char * buffer; + int i; + int n = 0; + + buffer = (char *)kmalloc(MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1), + GFP_KERNEL); + if (!buffer) { + printk(KERN_ERR "error: kmalloc failed\n"); + return -ENOMEM; + } + + for (i = 0; i < MAX_ERRINJCT_TOKENS && ei_token_list[i].value; i++) { + n += sprintf(buffer+n, ei_token_list[i].name); + n += sprintf(buffer+n, "\n"); + } + + if (*ppos >= strlen(buffer)) { + kfree(buffer); + return 0; + } + if (n > strlen(buffer) - *ppos) + n = strlen(buffer) - *ppos; + + if (n > count) + n = count; + + memcpy(buf, buffer + *ppos, n); + + *ppos += n; + + kfree(buffer); + return n; +} diff -urN linux-2.4.21/arch/ppc64/kernel/rtas.c linux-2.4.22/arch/ppc64/kernel/rtas.c --- linux-2.4.21/arch/ppc64/kernel/rtas.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/rtas.c 2003-08-25 04:44:40.000000000 -0700 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -27,9 +28,11 @@ #include #include #include +#include struct proc_dir_entry *rtas_proc_dir; /* /proc/ppc64/rtas dir */ struct flash_block_list_header rtas_firmware_flash_list = {0, 0}; +struct errinjct_token ei_token_list[MAX_ERRINJCT_TOKENS]; /* * prom_init() is called very early on, before the kernel text @@ -59,7 +62,7 @@ extern unsigned long reloc_offset(void); spinlock_t rtas_data_buf_lock = SPIN_LOCK_UNLOCKED; -char rtas_data_buf[RTAS_DATA_BUF_SIZE]; +char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned; void phys_call_rtas(int token, int nargs, int nret, ...) @@ -219,7 +222,11 @@ image_size += f->blocks[i].length; } next = f->next; - f->next = (struct flash_block_list *)virt_to_absolute((unsigned long)f->next); + /* Don't translate final NULL pointer */ + if(f->next) + f->next = (struct flash_block_list *)virt_to_absolute((unsigned long)f->next); + else + f->next = 0LL; /* make num_blocks into the version/length field */ f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16); } @@ -285,3 +292,108 @@ rtas_flash_bypass_warning(); rtas_power_off(); } + +int +rtas_errinjct_open(void) +{ + u32 ret[2]; + int open_token; + int rc; + + /* The rc and open_token values are backwards due to a misprint in + * the RPA */ + open_token = rtas_call(rtas_token("ibm,open-errinjct"), 0, 2, (void *) &ret); + rc = ret[0]; + + if (rc < 0) { + printk(KERN_WARNING "error: ibm,open-errinjct failed (%d)\n", rc); + return rc; + } + + return open_token; +} + +int +rtas_errinjct(unsigned int open_token, char * ei_token, char * in_workspace) +{ + struct errinjct_token * ei; + int rtas_ei_token = -1; + int rc; + int i; + + ei = ei_token_list; + for (i = 0; i < MAX_ERRINJCT_TOKENS && ei->name; i++) { + if (strcmp(ei_token, ei->name) == 0) { + rtas_ei_token = ei->value; + break; + } + ei++; + } + if (rtas_ei_token == -1) { + return -EINVAL; + } + + spin_lock(&rtas_data_buf_lock); + + if (in_workspace) + memcpy(rtas_data_buf, in_workspace, RTAS_DATA_BUF_SIZE); + + rc = rtas_call(rtas_token("ibm,errinjct"), 3, 1, NULL, rtas_ei_token, + open_token, __pa(rtas_data_buf)); + + spin_unlock(&rtas_data_buf_lock); + + return rc; +} + +int +rtas_errinjct_close(unsigned int open_token) +{ + int rc; + + rc = rtas_call(rtas_token("ibm,close-errinjct"), 1, 1, NULL, open_token); + if (rc != 0) { + printk(KERN_WARNING "error: ibm,close-errinjct failed (%d)\n", rc); + return rc; + } + + return 0; +} + +#ifndef CONFIG_PPC_ISERIES +static int __init rtas_errinjct_init(void) +{ + char * token_array; + char * end_array; + int array_len = 0; + int len; + int i, j; + + token_array = (char *) get_property(rtas.dev, "ibm,errinjct-tokens", + &array_len); + /* if token is not found, then we fall through loop */ + end_array = token_array + array_len; + for (i = 0, j = 0; i < MAX_ERRINJCT_TOKENS && token_array < end_array; i++) { + + len = strnlen(token_array, ERRINJCT_TOKEN_LEN) + 1; + ei_token_list[i].name = (char *) kmalloc(len, GFP_KERNEL); + if (!ei_token_list[i].name) { + printk(KERN_WARNING "error: kmalloc failed\n"); + return -ENOMEM; + } + + strcpy(ei_token_list[i].name, token_array); + token_array += len; + + ei_token_list[i].value = *(int *)token_array; + token_array += sizeof(int); + } + for (; i < MAX_ERRINJCT_TOKENS; i++) { + ei_token_list[i].name = 0; + ei_token_list[i].value = 0; + } + return 0; +} + +__initcall(rtas_errinjct_init); +#endif diff -urN linux-2.4.21/arch/ppc64/kernel/rtasd.c linux-2.4.22/arch/ppc64/kernel/rtasd.c --- linux-2.4.21/arch/ppc64/kernel/rtasd.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/rtasd.c 2003-08-25 04:44:40.000000000 -0700 @@ -49,6 +49,9 @@ #define SURVEILLANCE_TIMEOUT 1 #define SURVEILLANCE_SCANRATE 1 +extern struct proc_dir_entry *proc_ppc64_root; +extern struct proc_dir_entry *rtas_proc_dir; +extern spinlock_t proc_ppc64_lock; /* * Since we use 32 bit RTAS, the physical address of this must be below * 4G or else bad things happen. Allocate this in the kernel data and @@ -821,12 +824,8 @@ current->cpus_allowed = 1UL << cpu_logical_map(cpu); /* Check all cpus for pending events before sleeping*/ - if (first_pass) { - schedule(); - } else { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout((HZ*60/rtas_event_scan_rate) / 2); - } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(first_pass ? HZ : (HZ*60/rtas_event_scan_rate) / 2); } error_vfree: @@ -836,25 +835,45 @@ return -EINVAL; } -static void __init rtas_init(void) +static int __init rtas_init(void) { - struct proc_dir_entry *rtas_dir, *entry; + int ret = 0; + struct proc_dir_entry *entry; - rtas_dir = proc_mkdir("rtas", 0); - if (!rtas_dir) { - printk(KERN_ERR "Failed to create rtas proc directory\n"); + spin_lock(&proc_ppc64_lock); + if (proc_ppc64_root == NULL) { + proc_ppc64_root = proc_mkdir("ppc64", 0); + if (!proc_ppc64_root) { + spin_unlock(&proc_ppc64_lock); + return -EINVAL; + } + } + spin_unlock(&proc_ppc64_lock); + + if (rtas_proc_dir == NULL) { + rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root); + } + + if (rtas_proc_dir == NULL) { + printk(KERN_ERR "Failed to create /proc/ppc64/rtas in rtas_init\n"); + ret = -EINVAL; } else { - entry = create_proc_entry("error_log", S_IRUSR, rtas_dir); + entry = create_proc_entry("error_log", S_IRUSR, rtas_proc_dir); if (entry) entry->proc_fops = &proc_rtas_log_operations; - else + else { printk(KERN_ERR "Failed to create rtas/error_log proc entry\n"); + ret = -EINVAL; + } } - if (kernel_thread(rtasd, 0, CLONE_FS) < 0) + if (kernel_thread(rtasd, 0, CLONE_FS) < 0) { printk(KERN_ERR "Failed to start RTAS daemon\n"); + ret = -EINVAL; + } printk(KERN_ERR "RTAS daemon started\n"); + return ret; } static int __init surveillance_setup(char *str) diff -urN linux-2.4.21/arch/ppc64/kernel/setup.c linux-2.4.22/arch/ppc64/kernel/setup.c --- linux-2.4.21/arch/ppc64/kernel/setup.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -37,9 +37,7 @@ #include #include #include -#ifdef CONFIG_KDB -#include -#endif +#include extern unsigned long klimit; /* extern void *stab; */ @@ -74,10 +72,6 @@ extern void xmon_map_scc(void); #endif -#ifdef CONFIG_KDB -extern void kdb_map_scc(void); -#endif - char saved_command_line[256]; unsigned char aux_device_present; @@ -107,7 +101,7 @@ }; /* - * Do some initial setup of the system. The paramters are those which + * Do some initial setup of the system. The parameters are those which * were passed in from the bootloader. */ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, @@ -187,6 +181,7 @@ /* This is called just before console_init(). * It will be obsolete when Linux gets real early console support (2.5?) + * We need to hack preferred_console to retain the correct behavior */ void setup_before_console_init(void) { @@ -244,6 +239,14 @@ pvr = paca[cpu_id].pvr; + if (cur_cpu_spec->pvr_mask) + seq_printf(m, "%s", cur_cpu_spec->cpu_name); + else + seq_printf(m, "unknown (%08x)", pvr); + + + seq_printf(m, "\n"); +#if 0 switch (PVR_VER(pvr)) { case PV_NORTHSTAR: seq_printf(m, "RS64-II (northstar)\n"); @@ -273,7 +276,7 @@ seq_printf(m, "Unknown (%08x)\n", pvr); break; } - +#endif /* * Assume here that all clock rates are the same in a * smp system. -- Cort @@ -325,6 +328,7 @@ void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + struct device_node *chosen; char *p; #ifdef CONFIG_BLK_DEV_INITRD @@ -333,6 +337,7 @@ initrd_end = initrd_start + r4; ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); initrd_below_start_ok = 1; + lmb_reserve(__pa(initrd_start),r4); } #endif @@ -495,12 +500,6 @@ xmon(0); #endif /* CONFIG_XMON */ -#ifdef CONFIG_KDB - kdb_map_scc(); - if (strstr(cmd_line, "kdb=early")) - kdb(KDB_REASON_CALL,0,0); -#endif - #if defined(CONFIG_KGDB) kgdb_map_scc(); set_debug_traps(); @@ -560,28 +559,28 @@ void ppc64_boot_msg(unsigned int src, const char *msg) { ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg); - printk("[boot]%04x %s\n", src, msg); + udbg_printf("[boot]%04x %s\n", src, msg); } /* Print a termination message (print only -- does not stop the kernel) */ void ppc64_terminate_msg(unsigned int src, const char *msg) { ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg); - printk("[terminate]%04x %s\n", src, msg); + udbg_printf("[terminate]%04x %s\n", src, msg); } /* Print something that needs attention (device error, etc) */ void ppc64_attention_msg(unsigned int src, const char *msg) { ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_ATTN_MESSAGE|src, msg); - printk("[attention]%04x %s\n", src, msg); + udbg_printf("[attention]%04x %s\n", src, msg); } /* Print a dump progress message. */ void ppc64_dump_msg(unsigned int src, const char *msg) { ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_DUMP_MESSAGE|src, msg); - printk("[dump]%04x %s\n", src, msg); + udbg_printf("[dump]%04x %s\n", src, msg); } diff -urN linux-2.4.21/arch/ppc64/kernel/signal.c linux-2.4.22/arch/ppc64/kernel/signal.c --- linux-2.4.21/arch/ppc64/kernel/signal.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -101,6 +101,7 @@ err |= __put_user(from->si_pid, &to->si_pid); switch (from->si_code >> 16) { case __SI_FAULT >> 16: + err |= __put_user(from->si_addr, &to->si_addr); break; case __SI_CHLD >> 16: err |= __put_user(from->si_utime, &to->si_utime); diff -urN linux-2.4.21/arch/ppc64/kernel/stab.c linux-2.4.22/arch/ppc64/kernel/stab.c --- linux-2.4.21/arch/ppc64/kernel/stab.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/ppc64/kernel/stab.c 2003-08-25 04:44:40.000000000 -0700 @@ -17,6 +17,7 @@ #include #include #include +#include inline int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid); @@ -35,10 +36,7 @@ esid = GET_ESID(KERNELBASE); vsid = get_kernel_vsid(esid << SID_SHIFT); - if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) { - __asm__ __volatile__("isync; slbia; isync":::"memory"); - make_ste(stab, esid, vsid); - } else { + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { /* Invalidate the entire SLB & all the ERATS */ __asm__ __volatile__("isync" : : : "memory"); #ifndef CONFIG_PPC_ISERIES @@ -49,7 +47,10 @@ #else __asm__ __volatile__("isync; slbia; isync":::"memory"); #endif - } + } else { + __asm__ __volatile__("isync; slbia; isync":::"memory"); + make_ste(stab, esid, vsid); + } } /* @@ -61,6 +62,15 @@ unsigned long entry, group, old_esid, castout_entry, i; unsigned int global_entry; STE *ste, *castout_ste; + unsigned char kp = 1; + +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING + if(((esid >> SMALLOC_ESID_SHIFT) == + (SMALLOC_START >> SMALLOC_EA_SHIFT)) && + (current->thread.flags & PPC_FLAG_SHARED)) { + kp = 0; + } +#endif /* Search the primary group first. */ global_entry = (esid & 0x1f) << 3; @@ -77,7 +87,7 @@ __asm__ __volatile__ ("eieio" : : : "memory"); ste->dw0.dw0.esid = esid; ste->dw0.dw0.v = 1; - ste->dw0.dw0.kp = 1; + ste->dw0.dw0.kp = kp; /* Order update */ __asm__ __volatile__ ("sync" : : : "memory"); @@ -135,7 +145,7 @@ old_esid = castout_ste->dw0.dw0.esid; castout_ste->dw0.dw0.esid = esid; castout_ste->dw0.dw0.v = 1; - castout_ste->dw0.dw0.kp = 1; + castout_ste->dw0.dw0.kp = kp; __asm__ __volatile__ ("slbie %0" : : "r" (old_esid << SID_SHIFT)); /* Ensure completion of slbie */ __asm__ __volatile__ ("sync" : : : "memory" ); @@ -158,6 +168,15 @@ unsigned long word0; slb_dword1 data; } vsid_data; + unsigned char kp = 1; + +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING + if(((esid >> SMALLOC_ESID_SHIFT) == + (SMALLOC_START >> SMALLOC_EA_SHIFT)) && + (current->thread.flags & PPC_FLAG_SHARED)) { + kp = 0; + } +#endif /* * Find an empty entry, if one exists. @@ -171,7 +190,7 @@ */ vsid_data.word0 = 0; vsid_data.data.vsid = vsid; - vsid_data.data.kp = 1; + vsid_data.data.kp = kp; if (large) vsid_data.data.l = 1; @@ -220,7 +239,7 @@ */ vsid_data.word0 = 0; vsid_data.data.vsid = vsid; - vsid_data.data.kp = 1; + vsid_data.data.kp = kp; if (large) vsid_data.data.l = 1; @@ -264,6 +283,15 @@ } } +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING + /* Shared segments might be mapped into a user task space, + * so we need to add them to the list of entries to flush + */ + if ((ea >> SMALLOC_EA_SHIFT) == (SMALLOC_START >> SMALLOC_EA_SHIFT)) { + kernel_segment = 0; + } +#endif + esid = GET_ESID(ea); if (trap == 0x380 || trap == 0x480) { #ifndef CONFIG_PPC_ISERIES @@ -305,7 +333,15 @@ unsigned char *segments = get_paca()->xSegments; unsigned long flags, i; - if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) { + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + unsigned long flags; + + PMC_SW_PROCESSOR(stab_invalidations); + + __save_and_cli(flags); + __asm__ __volatile__("isync; slbia; isync":::"memory"); + __restore_flags(flags); + } else { unsigned long entry; STE *ste; @@ -330,7 +366,8 @@ entry++, ste++) { unsigned long ea; ea = ste->dw0.dw0.esid << SID_SHIFT; - if (STAB_PRESSURE || (!REGION_ID(ea))) { + if (STAB_PRESSURE || (!REGION_ID(ea)) || + (REGION_ID(ea) == VMALLOC_REGION_ID)) { ste->dw0.dw0.v = 0; PMC_SW_PROCESSOR(stab_invalidations); } @@ -347,13 +384,5 @@ __asm__ __volatile__ ("slbia" : : : "memory"); /* Force flush to complete. */ __asm__ __volatile__ ("sync" : : : "memory"); - } else { - unsigned long flags; - - PMC_SW_PROCESSOR(stab_invalidations); - - __save_and_cli(flags); - __asm__ __volatile__("isync; slbia; isync":::"memory"); - __restore_flags(flags); } } diff -urN linux-2.4.21/arch/ppc64/kernel/sys_ppc32.c linux-2.4.22/arch/ppc64/kernel/sys_ppc32.c --- linux-2.4.21/arch/ppc64/kernel/sys_ppc32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/sys_ppc32.c 2003-08-25 04:44:40.000000000 -0700 @@ -454,7 +454,7 @@ return err; } -struct dqblk32 { +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -473,13 +473,13 @@ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, unsigned long addr) +asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, caddr_t addr) { - int cmd = (int)cmd_parm; - int id = (int)id_parm; + int cmd = (int)cmd_parm; + int id = (int)id_parm; int cmds = cmd >> SUBCMDSHIFT; int err; - struct dqblk d; + struct v1c_mem_dqblk d; mm_segment_t old_fs; char *spec; @@ -487,35 +487,33 @@ current->pid, current, current->comm); switch (cmds) { - case Q_GETQUOTA: + case Q_V1_GETQUOTA: break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, (struct dqblk32 *)addr, - sizeof (struct dqblk32))) + case Q_V1_SETQUOTA: + case Q_V1_SETUSE: + case Q_V1_SETQLIM: + if (copy_from_user(&d, addr, sizeof(struct user_dqblk32))) return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; + d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime; break; default: - return sys_quotactl(cmd, special, - id, (caddr_t)addr); + return sys_quotactl(cmd, special, id, addr); } - spec = getname (special); + spec = getname(special); err = PTR_ERR(spec); - if (IS_ERR(spec)) return err; - old_fs = get_fs (); + 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); set_fs (old_fs); putname (spec); - if (cmds == Q_GETQUOTA) { + if (cmds == Q_V1_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 user_dqblk32 *)&d)->dqb_itime = i; + ((struct user_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user(addr, &d, sizeof(struct user_dqblk32))) return -EFAULT; } @@ -2311,7 +2309,11 @@ u32 totalswap; u32 freeswap; unsigned short procs; - char _f[22]; + unsigned short pad; + u32 totalhigh; + u32 freehigh; + u32 mem_unit; + char _f[20-2*sizeof(u32)-sizeof(int)]; }; extern asmlinkage long sys_sysinfo(struct sysinfo *info); @@ -2320,6 +2322,7 @@ { struct sysinfo s; int ret, err; + int bitcount = 0; mm_segment_t old_fs = get_fs (); PPCDBG(PPCDBG_SYS32, "sys32_sysinfo - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm); @@ -2327,6 +2330,24 @@ set_fs (KERNEL_DS); ret = sys_sysinfo(&s); set_fs (old_fs); + /* Check to see if any memory value is too large for 32-bit and scale + * down if needed + */ + if ((s.totalram >> 32) || (s.totalswap >> 32)) { + while (s.mem_unit < PAGE_SIZE) { + s.mem_unit <<= 1; + bitcount++; + } + s.totalram >>= bitcount; + s.freeram >>= bitcount; + s.sharedram >>= bitcount; + s.bufferram >>= bitcount; + s.totalswap >>= bitcount; + s.freeswap >>= bitcount; + s.totalhigh >>= bitcount; + s.freehigh >>= bitcount; + } + err = put_user (s.uptime, &info->uptime); err |= __put_user (s.loads[0], &info->loads[0]); err |= __put_user (s.loads[1], &info->loads[1]); @@ -2338,6 +2359,10 @@ err |= __put_user (s.totalswap, &info->totalswap); err |= __put_user (s.freeswap, &info->freeswap); err |= __put_user (s.procs, &info->procs); + err |= __put_user (s.totalhigh, &info->totalhigh); + err |= __put_user (s.freehigh, &info->freehigh); + err |= __put_user (s.mem_unit, &info->mem_unit); + if (err) return -EFAULT; @@ -3029,7 +3054,7 @@ err = do_sys32_shmctl(first, second, (void *)AA(ptr)); break; default: - err = -EINVAL; + err = -ENOSYS; break; } diff -urN linux-2.4.21/arch/ppc64/kernel/syscalls.c linux-2.4.22/arch/ppc64/kernel/syscalls.c --- linux-2.4.21/arch/ppc64/kernel/syscalls.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/syscalls.c 2003-08-25 04:44:40.000000000 -0700 @@ -72,7 +72,7 @@ version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; - ret = -EINVAL; + ret = -ENOSYS; switch (call) { case SEMOP: ret = sys_semop (first, (struct sembuf *)ptr, second); diff -urN linux-2.4.21/arch/ppc64/kernel/time.c linux-2.4.22/arch/ppc64/kernel/time.c --- linux-2.4.21/arch/ppc64/kernel/time.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -415,8 +415,8 @@ time_esterror = NTP_PHASE_LIMIT; delta_xsec = mulhdu( (tb_last_stamp-systemcfg->tb_orig_stamp), systemcfg->tb_to_xs ); - new_xsec = (new_usec * XSEC_PER_SEC) / USEC_PER_SEC; - new_xsec += new_sec * XSEC_PER_SEC; + new_xsec = (tv->tv_usec * XSEC_PER_SEC) / USEC_PER_SEC; + new_xsec += tv->tv_sec * XSEC_PER_SEC; if ( new_xsec > delta_xsec ) { systemcfg->stamp_xsec = new_xsec - delta_xsec; } diff -urN linux-2.4.21/arch/ppc64/kernel/traps.c linux-2.4.22/arch/ppc64/kernel/traps.c --- linux-2.4.21/arch/ppc64/kernel/traps.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -42,6 +42,7 @@ #include #include #include +#include /* for ppc_attention_msg */ extern int fix_alignment(struct pt_regs *); extern void bad_page_fault(struct pt_regs *, unsigned long); @@ -75,14 +76,11 @@ void (*debugger_fault_handler)(struct pt_regs *regs); #else #ifdef CONFIG_KDB -/* kdb has different call parms */ -/* ... */ -void (*debugger)(struct pt_regs *regs) = kdb; +void (*debugger)(struct pt_regs *regs); int (*debugger_bpt)(struct pt_regs *regs); int (*debugger_sstep)(struct pt_regs *regs); int (*debugger_iabr_match)(struct pt_regs *regs); -int (*debugger_dabr_match)(struct pt_regs *regs) = kdb; -/* - only defined during (xmon) mread */ +int (*debugger_dabr_match)(struct pt_regs *regs); void (*debugger_fault_handler)(struct pt_regs *regs); #endif /* kdb */ #endif /* kgdb */ @@ -100,13 +98,9 @@ if (!user_mode(regs)) { show_regs(regs); -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB) debugger(regs); #endif -#if defined(CONFIG_KDB) - if (kdb(KDB_REASON_BREAK, 0, (kdb_eframe_t) regs)) - return; -#endif print_backtrace((unsigned long *)regs->gpr[1]); panic("Exception in kernel pc %lx signal %d",regs->nip,signr); #if defined(CONFIG_PPCDBG) && (defined(CONFIG_XMON) || defined(CONFIG_KGDB)) @@ -164,30 +158,11 @@ } #if defined(CONFIG_XMON) xmon(regs); - udbg_printf("leaving xmon...\n"); + if (smp_processor_id() == 0) + udbg_printf("leaving xmon...\n"); #endif #if defined(CONFIG_KDB) - { - int cpu = smp_processor_id(); - static int reset_cpu = -1; - static spinlock_t reset_lock = SPIN_LOCK_UNLOCKED; - - /* Give kdb some help serializing the reset */ - spin_lock(&reset_lock); - if (reset_cpu == -1) { - reset_cpu = cpu; - spin_unlock(&reset_lock); - kdb(KDB_REASON_ENTER, regs->trap, (kdb_eframe_t) regs); - reset_cpu = -1; - } else { - spin_unlock(&reset_lock); - /* Let kdb catch this cpu with an IPI. - * Ideally we need a way to enter kdb w/o it becoming - * confused so we can precisely capture reset state. - */ - return; - } - } + kdb_reset_debugger(regs); #endif } @@ -195,7 +170,6 @@ void MachineCheckException(struct pt_regs *regs) { - siginfo_t info; if (fwnmi_active) { struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs); @@ -205,54 +179,31 @@ FWNMI_release_errinfo(); } - if ( !user_mode(regs) ) { -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) - if (debugger_fault_handler) { - debugger_fault_handler(regs); - return; - } -#endif - printk("Machine check in kernel mode.\n"); - printk("Caused by (from SRR1=%lx): ", regs->msr); - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) - debugger(regs); + if (debugger_fault_handler) { + debugger_fault_handler(regs); + return; + } #endif -#ifdef CONFIG_KDB - if (kdb(KDB_REASON_FAULT, 0, regs)) - return ; + printk(KERN_EMERG "Unrecoverable Machine check.\n"); + printk(KERN_EMERG "Caused by (from SRR1=%lx): ", regs->msr); + show_regs(regs); +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB) + debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("machine check"); - } - - /* - * XXX we should check RI bit on exception exit and kill the - * task if it was cleared - */ - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRERR; - info.si_addr = (void *)regs->nip; - _exception(SIGSEGV, &info, regs); - + print_backtrace((unsigned long *)regs->gpr[1]); + panic("machine check"); } void SMIException(struct pt_regs *regs) { -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB) { debugger(regs); return; } #endif -#ifdef CONFIG_KDB - { - kdb(KDB_REASON_OOPS, 0, regs); - return; - } -#endif show_regs(regs); print_backtrace((unsigned long *)regs->gpr[1]); panic("System Management Interrupt"); @@ -278,15 +229,10 @@ { siginfo_t info; -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined (CONFIG_KDB) if (debugger_iabr_match(regs)) return; #endif -#ifdef CONFIG_KDB - if (kdb(KDB_REASON_BREAK, 0, regs)) - return; -#endif - info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_BRKPT; @@ -353,14 +299,10 @@ } else if (regs->msr & 0x20000) { /* trap exception */ -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB) if (debugger_bpt(regs)) return; #endif -#ifdef CONFIG_KDB - if (kdb(KDB_REASON_BREAK, 0, regs)) - return; -#endif info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_BRKPT; @@ -377,6 +319,14 @@ } } + void +KernelFPUnavailableException(struct pt_regs *regs) +{ + printk("Illegal floating point used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n", + current, regs->nip, regs->trap); + panic("Unrecoverable FP Unavailable Exception in Kernel"); +} + void SingleStepException(struct pt_regs *regs) { @@ -384,15 +334,10 @@ regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB) if (debugger_sstep(regs)) return; #endif -#ifdef CONFIG_KDB - if (kdb(KDB_REASON_DEBUG, 0, regs)) - return; -#endif - info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_TRACE; diff -urN linux-2.4.21/arch/ppc64/kernel/xics.c linux-2.4.22/arch/ppc64/kernel/xics.c --- linux-2.4.21/arch/ppc64/kernel/xics.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/kernel/xics.c 2003-08-25 04:44:40.000000000 -0700 @@ -143,18 +143,22 @@ u_int irq; unsigned long status; long call_status; + unsigned int interrupt_server = default_server; virq -= XICS_IRQ_OFFSET; irq = virt_irq_to_real(virq); if (irq == XICS_IPI) return; + #ifdef CONFIG_IRQ_ALL_CPUS - call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status, - irq, smp_threads_ready ? default_distrib_server : default_server, DEFAULT_PRIORITY); -#else - call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status, - irq, default_server, DEFAULT_PRIORITY); + if((smp_num_cpus == systemcfg->processorCount) && + (smp_threads_ready)) { + interrupt_server = default_distrib_server; + } #endif + call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status, + irq, interrupt_server, DEFAULT_PRIORITY); + if( call_status != 0 ) { printk("xics_enable_irq: irq=%x: rtas_call failed; retn=%lx, status=%lx\n", irq, call_status, status); diff -urN linux-2.4.21/arch/ppc64/lib/copyuser.S linux-2.4.22/arch/ppc64/lib/copyuser.S --- linux-2.4.21/arch/ppc64/lib/copyuser.S 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/lib/copyuser.S 2003-08-25 04:44:40.000000000 -0700 @@ -130,7 +130,7 @@ 6: cmpwi cr1,r5,8 addi r3,r3,32 sld r9,r9,r10 - blt cr1,.Ldo_tail + ble cr1,.Ldo_tail 34: ld r0,8(r4) srd r7,r0,r11 or r9,r7,r9 @@ -483,8 +483,20 @@ * on an exception, reset to the beginning and jump back into the * standard __copy_tofrom_user */ -100: ld r3,-24(r1) - ld r4,-24(r1) +100: ld r20,-120(1) + ld r21,-112(1) + ld r22,-104(1) + ld r23,-96(1) + ld r24,-88(1) + ld r25,-80(1) + ld r26,-72(1) + ld r27,-64(1) + ld r28,-56(1) + ld r29,-48(1) + ld r30,-40(1) + ld r31,-32(1) + ld r3,-24(r1) + ld r4,-16(r1) li r5,4096 b .Ldst_aligned diff -urN linux-2.4.21/arch/ppc64/mm/fault.c linux-2.4.22/arch/ppc64/mm/fault.c --- linux-2.4.21/arch/ppc64/mm/fault.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 @@ -65,7 +65,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code) { - struct vm_area_struct * vma; + struct vm_area_struct * vma, * prev_vma; struct mm_struct *mm = current->mm; siginfo_t info; unsigned long code = SEGV_MAPERR; @@ -90,8 +90,8 @@ } #endif /* CONFIG_XMON || CONFIG_KGDB */ - /* On an SLB miss we can only check for a valid exception entry */ - if (regs->trap == 0x380) { + /* On a kernel SLB miss we can only check for a valid exception entry */ + if (!user_mode(regs) && (regs->trap == 0x380)) { bad_page_fault(regs, address); return; } @@ -99,13 +99,8 @@ #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB) if (error_code & 0x00400000) { /* DABR match */ -#if defined(CONFIG_KDB) - if (kdb(KDB_REASON_BREAK,regs->trap,regs)) - return; -#else if (debugger_dabr_match(regs)) return; -#endif } #endif /* CONFIG_XMON || CONFIG_KGDB || CONFIG_KDB */ @@ -128,6 +123,7 @@ PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_flags = %lx, %lx\n", vma->vm_flags, VM_GROWSDOWN); goto bad_area; } + vma = find_vma_prev(mm, address, &prev_vma); if (expand_stack(vma, address)) { PPCDBG(PPCDBG_MM, "\tdo_page_fault: expand_stack\n"); goto bad_area; @@ -243,13 +239,10 @@ /* kernel has accessed a bad area */ show_regs(regs); -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB) if (debugger_kernel_faults) debugger(regs); #endif -#if defined(CONFIG_KDB) - kdb(KDB_REASON_FAULT, regs->trap, regs); -#endif print_backtrace( (unsigned long *)regs->gpr[1] ); panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d", regs->nip,regs->link,address,current->comm,current->pid); diff -urN linux-2.4.21/arch/ppc64/mm/init.c linux-2.4.22/arch/ppc64/mm/init.c --- linux-2.4.21/arch/ppc64/mm/init.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -279,7 +279,11 @@ /* Implemented to just flush the vmalloc area. * vmalloc is the only user of flush_tlb_all. */ +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING + local_flush_tlb_range( NULL, VMALLOC_START, SMALLOC_END ); +#else local_flush_tlb_range( NULL, VMALLOC_START, VMALLOC_END ); +#endif } void @@ -292,11 +296,6 @@ for ( mp = mm->mmap; mp != NULL; mp = mp->vm_next ) local_flush_tlb_range( mm, mp->vm_start, mp->vm_end ); } - else /* MIKEC: It is not clear why this is needed */ - /* paulus: it is needed to clear out stale HPTEs - * when an address space (represented by an mm_struct) - * is being destroyed. */ - local_flush_tlb_range( mm, USER_START, USER_END ); spin_unlock(&mm->page_table_lock); } @@ -644,3 +643,131 @@ maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK); flush_icache_range(maddr, maddr + len); } + +#ifdef CONFIG_SHARED_MEMORY_ADDRESSING +static spinlock_t shared_malloc_lock = SPIN_LOCK_UNLOCKED; +struct vm_struct *shared_list = NULL; +static struct vm_struct *get_shared_area(unsigned long size, + unsigned long flags); + +void *shared_malloc(unsigned long size) { + pgprot_t prot; + struct vm_struct *area; + unsigned long ea; + + spin_lock(&shared_malloc_lock); + + printk("shared_malloc1 (no _PAGE_USER): addr = 0x%lx, size = 0x%lx\n", + SMALLOC_START, size); + + area = get_shared_area(size, 0); + if (!area) { + spin_unlock(&shared_malloc_lock); + return NULL; + } + + ea = (unsigned long) area->addr; + + prot = __pgprot(pgprot_val(PAGE_KERNEL)); + if (vmalloc_area_pages(VMALLOC_VMADDR(ea), size, GFP_KERNEL, prot)) { + spin_unlock(&shared_malloc_lock); + return NULL; + } + + printk("shared_malloc: addr = 0x%lx, size = 0x%lx\n", ea, size); + + spin_unlock(&shared_malloc_lock); + return(ea); +} + +void shared_free(void *addr) { + struct vm_struct **p, *tmp; + unsigned long size = 0; + + if (!addr) + return; + if ((PAGE_SIZE-1) & (unsigned long) addr) { + printk(KERN_ERR "Trying to shared_free() bad address (%p)\n", + addr); + return; + } + spin_lock(&shared_malloc_lock); + + printk("shared_free: addr = 0x%lx\n", addr); + + /* Scan the memory list for an entry matching + * the address to be freed, get the size (in bytes) + * and free the entry. The list lock is not dropped + * until the page table entries are removed. + */ + for(p = &shared_list; (tmp = *p); p = &tmp->next ) { + if (tmp->addr == addr) { + *p = tmp->next; + vmfree_area_pages(VMALLOC_VMADDR(tmp->addr),tmp->size); + spin_unlock(&shared_malloc_lock); + kfree(tmp); + return; + } + } + + spin_unlock(&shared_malloc_lock); + printk("shared_free: error\n"); +} + +static struct vm_struct *get_shared_area(unsigned long size, + unsigned long flags) { + unsigned long addr; + struct vm_struct **p, *tmp, *area; + + area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); + if (!area) return NULL; + + size += PAGE_SIZE; + if (!size) { + kfree (area); + return NULL; + } + + addr = SMALLOC_START; + for (p = &shared_list; (tmp = *p) ; p = &tmp->next) { + if ((size + addr) < addr) { + kfree(area); + return NULL; + } + if (size + addr <= (unsigned long) tmp->addr) + break; + addr = tmp->size + (unsigned long) tmp->addr; + if (addr > SMALLOC_END-size) { + kfree(area); + return NULL; + } + } + + if (addr + size > SMALLOC_END) { + kfree(area); + return NULL; + } + area->flags = flags; + area->addr = (void *)addr; + area->size = size; + area->next = *p; + *p = area; + return area; +} + +int shared_task_mark() { + current->thread.flags |= PPC_FLAG_SHARED; + printk("current->thread.flags = 0x%lx\n", current->thread.flags); + + return 0; +} + +int shared_task_unmark() { + if(current->thread.flags & PPC_FLAG_SHARED) { + current->thread.flags &= (~PPC_FLAG_SHARED); + return 0; + } else { + return -1; + } +} +#endif diff -urN linux-2.4.21/arch/ppc64/vmlinux.lds linux-2.4.22/arch/ppc64/vmlinux.lds --- linux-2.4.21/arch/ppc64/vmlinux.lds 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/vmlinux.lds 2003-08-25 04:44:40.000000000 -0700 @@ -73,6 +73,9 @@ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; . = ALIGN(4096); .data.page_aligned : { *(.data.page_aligned) } diff -urN linux-2.4.21/arch/ppc64/xmon/xmon.c linux-2.4.22/arch/ppc64/xmon/xmon.c --- linux-2.4.21/arch/ppc64/xmon/xmon.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/ppc64/xmon/xmon.c 2003-08-25 04:44:40.000000000 -0700 @@ -26,6 +26,7 @@ #include #include #include +#include #include "nonstdio.h" #include "privinst.h" @@ -33,9 +34,11 @@ #define skipbl xmon_skipbl #ifdef CONFIG_SMP -static unsigned long cpus_in_xmon = 0; -static unsigned long got_xmon = 0; +static volatile unsigned long cpus_in_xmon = 0; +static volatile unsigned long got_xmon = 0; static volatile int take_xmon = -1; +static volatile int leaving_xmon = 0; + #endif /* CONFIG_SMP */ static unsigned long adrs; @@ -190,7 +193,7 @@ asm volatile("sync; isync"); } -/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs). +/* (Ref: 64-bit PowerPC ELF ABI Supplement; Ian Lance Taylor, Zembu Labs). A PPC stack frame looks like this: High Address @@ -250,12 +253,12 @@ xmon(struct pt_regs *excp) { struct pt_regs regs; - int cmd; + int cmd = 0; unsigned long msr; if (excp == NULL) { /* Ok, grab regs as they are now. - This won't do a particularily good job because the + This won't do a particularly good job because the prologue has already been executed. ToDo: We could reach back into the callers save area to do a better job of representing the @@ -309,9 +312,15 @@ xmon_regs[smp_processor_id()] = excp; excprint(excp); #ifdef CONFIG_SMP - if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) + /* possible race condition here if a CPU is held up and gets + * here while we are exiting */ + leaving_xmon = 0; + if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) { + /* xmon probably caused an exception itself */ + printf("We are already in xmon\n"); for (;;) ; + } while (test_and_set_bit(0, &got_xmon)) { if (take_xmon == smp_processor_id()) { take_xmon = -1; @@ -327,6 +336,9 @@ if (cmd == 's') { xmon_trace[smp_processor_id()] = SSTEP; excp->msr |= MSR_SE; +#ifdef CONFIG_SMP + take_xmon = smp_processor_id(); +#endif } else if (at_breakpoint(excp->nip)) { xmon_trace[smp_processor_id()] = BRSTEP; excp->msr |= MSR_SE; @@ -336,7 +348,9 @@ } xmon_regs[smp_processor_id()] = 0; #ifdef CONFIG_SMP - clear_bit(0, &got_xmon); + leaving_xmon = 1; + if (cmd != 's') + clear_bit(0, &got_xmon); clear_bit(smp_processor_id(), &cpus_in_xmon); #endif /* CONFIG_SMP */ set_msrd(msr); /* restore interrupt enable */ @@ -442,7 +456,7 @@ int i; struct bpt *bp; - if (systemcfg->platform != PLATFORM_PSERIES) + if (!(systemcfg->platform & PLATFORM_PSERIES)) return; bp = bpts; for (i = 0; i < NBPTS; ++i, ++bp) { @@ -458,7 +472,7 @@ } } - if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) { + if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) { if (dabr.enabled) set_dabr(dabr.address); if (iabr.enabled) @@ -473,11 +487,13 @@ struct bpt *bp; unsigned instr; - if (systemcfg->platform != PLATFORM_PSERIES) + if (!(systemcfg->platform & PLATFORM_PSERIES)) return; - if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) { - set_dabr(0); - set_iabr(0); + if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) { + if (dabr.enabled) + set_dabr(0); + if (iabr.enabled) + set_iabr(0); } bp = bpts; @@ -500,11 +516,15 @@ static int cmds(struct pt_regs *excp) { - int cmd; + int cmd = 0; last_cmd = NULL; for(;;) { #ifdef CONFIG_SMP + /* Need to check if we should take any commands on + this CPU. */ + if (leaving_xmon) + return cmd; printf("%d:", smp_processor_id()); #endif /* CONFIG_SMP */ printf("mon> "); @@ -767,10 +787,11 @@ cmd = inchar(); switch (cmd) { case 'd': /* bd - hardware data breakpoint */ - if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) { + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { printf("Not implemented on POWER4\n"); break; } + mode = 7; cmd = inchar(); if (cmd == 'r') @@ -787,7 +808,7 @@ dabr.address = (dabr.address & ~7) | mode; break; case 'i': /* bi - hardware instr breakpoint */ - if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) { + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { printf("Not implemented on POWER4\n"); break; } diff -urN linux-2.4.21/arch/s390/config.in linux-2.4.22/arch/s390/config.in --- linux-2.4.21/arch/s390/config.in 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/s390/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -39,6 +39,10 @@ bool 'Fast IRQ handling' CONFIG_FAST_IRQ bool 'Process warning machine checks' CONFIG_MACHCHK_WARNING bool 'Use chscs for Common I/O' CONFIG_CHSC +tristate 'QDIO support' CONFIG_QDIO +if [ "$CONFIG_QDIO" != "n" ]; then + bool ' Performance statistics in /proc' CONFIG_QDIO_PERF_STATS +fi bool 'Builtin IPL record support' CONFIG_IPL if [ "$CONFIG_IPL" = "y" ]; then choice 'IPL method generated into head.S' \ @@ -75,4 +79,5 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/s390/defconfig linux-2.4.22/arch/s390/defconfig --- linux-2.4.21/arch/s390/defconfig 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/s390/defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -35,8 +35,8 @@ CONFIG_MACHCHK_WARNING=y CONFIG_CHSC=y CONFIG_IPL=y -# CONFIG_IPL_TAPE is not set -CONFIG_IPL_VM=y +CONFIG_IPL_TAPE=y +# CONFIG_IPL_VM is not set CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -64,7 +64,7 @@ CONFIG_DASD=y CONFIG_DASD_ECKD=y CONFIG_DASD_FBA=y -# CONFIG_DASD_DIAG is not set +CONFIG_DASD_DIAG=y # # Multi-device support (RAID and LVM) @@ -118,7 +118,7 @@ # CONFIG_TUN is not set CONFIG_NET_ETHERNET=y CONFIG_TR=y -# CONFIG_FDDI is not set +CONFIG_FDDI=y # # S/390 network device drivers @@ -134,20 +134,98 @@ CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_NET_IPGRE_BROADCAST is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +# CONFIG_IP_NF_MATCH_HELPER is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_MIRROR is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_LOCAL=y +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set CONFIG_IPV6=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_LENGTH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m CONFIG_SHARED_IPV6_CARDS=y # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -158,6 +236,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -166,7 +249,7 @@ # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set +CONFIG_NET_FASTROUTE=y # CONFIG_NET_HW_FLOWCONTROL is not set # @@ -175,6 +258,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # File systems # # CONFIG_QUOTA is not set @@ -187,33 +275,38 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y # 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 # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set -# CONFIG_DEVPTS_FS is not set +CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set @@ -230,12 +323,14 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD_V3=y +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -247,27 +342,80 @@ # 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 # CONFIG_PARTITION_ADVANCED=y # CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y CONFIG_IBM_PARTITION=y -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +CONFIG_LDM_DEBUG=y +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y # CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # # Kernel hacking # CONFIG_MAGIC_SYSRQ=y + +# +# Library routines +# +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/s390/kernel/debug.c linux-2.4.22/arch/s390/kernel/debug.c --- linux-2.4.21/arch/s390/kernel/debug.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390/kernel/debug.c 2003-08-25 04:44:40.000000000 -0700 @@ -949,9 +949,21 @@ int i; unsigned long flags; mode_t mode = S_IFREG; + struct proc_dir_entry *pde; + if (!id) goto out; + pde = debug_create_proc_dir_entry(id->proc_root_entry, + view->name, mode, + &debug_inode_ops, + &debug_file_ops); + if(!pde){ + printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name); + rc = -1; + goto out; + } + spin_lock_irqsave(&id->lock, flags); for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (id->views[i] == NULL) @@ -962,6 +974,8 @@ id->name,view->name); printk(KERN_WARNING "debug: maximum number of views reached (%i)!\n", i); + debug_delete_proc_dir_entry(id->proc_root_entry, pde); + rc = -1; } else { @@ -970,11 +984,7 @@ mode |= S_IRUSR; if (view->input_proc) mode |= S_IWUSR; - id->proc_entries[i] = - debug_create_proc_dir_entry(id->proc_root_entry, - view->name, mode, - &debug_inode_ops, - &debug_file_ops); + id->proc_entries[i] = pde; rc = 0; } spin_unlock_irqrestore(&id->lock, flags); diff -urN linux-2.4.21/arch/s390/kernel/head.S linux-2.4.22/arch/s390/kernel/head.S --- linux-2.4.21/arch/s390/kernel/head.S 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -587,7 +587,7 @@ .long .Lduct # cr2: dispatchable unit control table .long 0 # cr3: instruction authorization .long 0 # cr4: instruction authorization - .long 0 # cr5: various things + .long 0xffffffff # cr5: primary-aste origin .long 0 # cr6: I/O interrupts .long 0 # cr7: secondary space segment table .long 0 # cr8: access registers translation diff -urN linux-2.4.21/arch/s390/kernel/s390_ksyms.c linux-2.4.22/arch/s390/kernel/s390_ksyms.c --- linux-2.4.21/arch/s390/kernel/s390_ksyms.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390/kernel/s390_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -60,5 +60,8 @@ EXPORT_SYMBOL(csum_fold); EXPORT_SYMBOL(console_mode); EXPORT_SYMBOL(console_device); -EXPORT_SYMBOL(pfix_table); +EXPORT_SYMBOL(pfix_get_addr); +EXPORT_SYMBOL(pfix_get_page_addr); +EXPORT_SYMBOL(get_storage_key); EXPORT_SYMBOL_NOVERS(do_call_softirq); +EXPORT_SYMBOL(sys_wait4); diff -urN linux-2.4.21/arch/s390/kernel/setup.c linux-2.4.22/arch/s390/kernel/setup.c --- linux-2.4.21/arch/s390/kernel/setup.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -56,7 +56,117 @@ unsigned long cpu_initialized = 0; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ -void* *pfix_table=NULL; +unsigned long *pfix_table; +unsigned int __global_storage_key; + +unsigned int get_storage_key(void) { return __global_storage_key; } + +unsigned long pfix_get_page_addr(void *addr) +{ + if (!MACHINE_HAS_PFIX) + return (unsigned long) addr; + + return pfix_table[(unsigned long)virt_to_phys(addr)>>PAGE_SHIFT]; +} + +unsigned long pfix_get_addr(void *addr) +{ + if (!MACHINE_HAS_PFIX) + return (unsigned long) addr; + + return pfix_get_page_addr(addr) + ((unsigned long)addr&(PAGE_SIZE-1)); +} + +/* + * These functions allow to lock and unlock pages in VM. They need + * the absolute address of the page to be locked or unlocked. This will + * only work if the diag98 option in the user directory is enabled for + * the guest. + */ + +/* if result is 0, addr will become the host absolute address */ +static inline int pfix_lock_page(void *addr) +{ + int ret; + + __asm__ __volatile__( + " sske %1,%2\n" /* set storage key */ + " l 0,0(%1)\n" /* addr into gpr 0 */ + " lhi 2,0\n" /* function code is 0 */ + " diag 2,0,0x98\n" /* result in gpr 1 */ + " jnz 0f\n" + " lhi %0,0\n" /* if cc=0: return 0 */ + " st 1,0(%1)\n" /* gpr1 contains host absol. addr */ + " j 1f\n" + "0: lr %0,1\n" /* gpr1 contains error code */ + " sske %1,2\n" /* reset storage key */ + "1:\n" + : "=d" (ret), "+d" ((unsigned long)addr) : "d" (__global_storage_key) + : "0", "1", "2", "cc" ); + return ret; +} + +static inline void pfix_unlock_page(unsigned long addr) +{ + __asm__ __volatile__( + " lr 0,%0\n" /* parameter in gpr 0 */ + " lhi 2,4\n" /* function code is 4 */ + " diag 2,0,0x98\n" /* result in gpr 1 */ + " sske %0,%1\n" + : : "a" (addr), "d" (0) + : "0", "1", "2", "cc" ); +} + +static void unpfix_all_pages(void) +{ + unsigned long i; + + if (!pfix_table) + return; + + for (i=0; i> PAGE_SHIFT) * sizeof(long); + pfix_table = alloc_bootmem(size); + if (!pfix_table) + return; + + __global_storage_key = 6 << 4; + for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { + unsigned long start; + + for(start = memory_chunk[i].addr; + (start < memory_chunk[i].addr + memory_chunk[i].size && + start < max_pfn); start += PAGE_SIZE) { + unsigned long index; + + index = start >> PAGE_SHIFT; + pfix_table[index] = start; + r = pfix_lock_page(&pfix_table[index]); + if (r) { + pfix_table[index] = 0; + unpfix_all_pages(); + free_bootmem((unsigned long)pfix_table, size); + machine_flags &= ~128; /* MACHINE_HAS_PFIX=0 */ + __global_storage_key = 0; + printk(KERN_WARNING "Error enabling PFIX at " + "address 0x%08lx.\n", start); + return; + } + } + } + printk (KERN_INFO "PFIX enabled.\n"); +} /* * Setup options @@ -303,11 +413,12 @@ unsigned long memory_start, memory_end; char c = ' ', cn, *to = command_line, *from = COMMAND_LINE; struct resource *res; - unsigned long start_pfn, end_pfn; + unsigned long start_pfn, end_pfn, max_pfn=0; static unsigned int smptrap=0; unsigned long delay = 0; struct _lowcore *lowcore; int i; + static int use_pfix; if (smptrap) return; @@ -380,6 +491,14 @@ /* now wait for the requested amount of time */ udelay(delay); } + /* + * "use_pfix" specifies whether we want to fix all pages, + * if possible. + */ + if (c == ' ' && strncmp(from, "use_pfix", 8) == 0) { + use_pfix = 1; + from += 8; + } cn = *(from++); if (!cn) break; @@ -394,6 +513,10 @@ break; *(to++) = c; } + + if (!use_pfix) + machine_flags &= ~128; /* MACHINE_HAS_PFIX = 0 */ + if (c == ' ' && to > command_line) to--; *to = '\0'; *cmdline_p = command_line; @@ -429,6 +552,8 @@ if (start_chunk < end_chunk) free_bootmem(start_chunk << PAGE_SHIFT, (end_chunk - start_chunk) << PAGE_SHIFT); + if (start_chunk + memory_chunk[i].size > max_pfn) + max_pfn = start_chunk + memory_chunk[i].size; } /* @@ -487,6 +612,10 @@ */ paging_init(); + if (MACHINE_HAS_PFIX) + /* max_pfn may be smaller than memory_end. */ + pfix_all_pages(start_pfn, max_pfn); + res = alloc_bootmem_low(sizeof(struct resource)); res->start = 0; res->end = memory_end; diff -urN linux-2.4.21/arch/s390/mm/init.c linux-2.4.22/arch/s390/mm/init.c --- linux-2.4.21/arch/s390/mm/init.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -154,11 +154,6 @@ if (address >= end_mem) pte_clear(&pte); set_pte(pg_table, pte); - if (address < memory_size) /* do not set storage - key outside the storage - or die */ - set_access_key(pte); /* switch to our - access key */ address += PAGE_SIZE; } } diff -urN linux-2.4.21/arch/s390x/config.in linux-2.4.22/arch/s390x/config.in --- linux-2.4.21/arch/s390x/config.in 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/s390x/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -42,6 +42,10 @@ bool 'Fast IRQ handling' CONFIG_FAST_IRQ bool 'Process warning machine checks' CONFIG_MACHCHK_WARNING bool 'Use chscs for Common I/O' CONFIG_CHSC +tristate 'QDIO support' CONFIG_QDIO +if [ "$CONFIG_QDIO" != "n" ]; then + bool ' Performance statistics in /proc' CONFIG_QDIO_PERF_STATS +fi bool 'Builtin IPL record support' CONFIG_IPL if [ "$CONFIG_IPL" = "y" ]; then choice 'IPL method generated into head.S' \ @@ -79,4 +83,5 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/s390x/defconfig linux-2.4.22/arch/s390x/defconfig --- linux-2.4.21/arch/s390x/defconfig 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/s390x/defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -36,8 +36,8 @@ CONFIG_MACHCHK_WARNING=y CONFIG_CHSC=y CONFIG_IPL=y -# CONFIG_IPL_TAPE is not set -CONFIG_IPL_VM=y +CONFIG_IPL_TAPE=y +# CONFIG_IPL_VM is not set CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -118,7 +118,7 @@ # CONFIG_TUN is not set CONFIG_NET_ETHERNET=y CONFIG_TR=y -# CONFIG_FDDI is not set +CONFIG_FDDI=y # # S/390 network device drivers @@ -134,20 +134,40 @@ CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_NET_IPGRE_BROADCAST is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set CONFIG_IPV6=m + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set CONFIG_SHARED_IPV6_CARDS=y # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -158,6 +178,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -166,7 +191,7 @@ # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set +CONFIG_NET_FASTROUTE=y # CONFIG_NET_HW_FLOWCONTROL is not set # @@ -175,6 +200,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # File systems # # CONFIG_QUOTA is not set @@ -187,33 +217,38 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y # 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 # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set -# CONFIG_DEVPTS_FS is not set +CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set @@ -230,13 +265,17 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y # CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y -# CONFIG_SMB_FS is not set +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set @@ -247,27 +286,80 @@ # 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 # CONFIG_PARTITION_ADVANCED=y # CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y CONFIG_IBM_PARTITION=y -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +CONFIG_LDM_DEBUG=y +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # # Kernel hacking # CONFIG_MAGIC_SYSRQ=y + +# +# Library routines +# +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/s390x/kernel/Makefile linux-2.4.22/arch/s390x/kernel/Makefile --- linux-2.4.21/arch/s390x/kernel/Makefile 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/s390x/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -29,7 +29,7 @@ # obj-$(CONFIG_REMOTE_DEBUG) += gdb-stub.o #gdb-low.o -obj-$(CONFIG_S390_SUPPORT) += linux32.o signal32.o ioctl32.o wrapper32.o exec32.o +obj-$(CONFIG_S390_SUPPORT) += linux32.o signal32.o ioctl32.o wrapper32.o exec32.o exec_domain32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o .PHONY: asm-offsets.h diff -urN linux-2.4.21/arch/s390x/kernel/binfmt_elf32.c linux-2.4.22/arch/s390x/kernel/binfmt_elf32.c --- linux-2.4.21/arch/s390x/kernel/binfmt_elf32.c 2001-04-11 19:02:29.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/binfmt_elf32.c 2003-08-25 04:44:40.000000000 -0700 @@ -87,7 +87,13 @@ #define ELF_PLATFORM (NULL) #ifdef __KERNEL__ -#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) +#define SET_PERSONALITY(ex, ibcs2) \ +do { \ + if (ibcs2) \ + set_personality(PER_SVR4); \ + else if (current->personality != PER_LINUX32) \ + set_personality(PER_LINUX); \ +} while (0) #endif #include "linux32.h" diff -urN linux-2.4.21/arch/s390x/kernel/debug.c linux-2.4.22/arch/s390x/kernel/debug.c --- linux-2.4.21/arch/s390x/kernel/debug.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/debug.c 2003-08-25 04:44:40.000000000 -0700 @@ -949,9 +949,21 @@ int i; unsigned long flags; mode_t mode = S_IFREG; + struct proc_dir_entry *pde; + if (!id) goto out; + pde = debug_create_proc_dir_entry(id->proc_root_entry, + view->name, mode, + &debug_inode_ops, + &debug_file_ops); + if(!pde){ + printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name); + rc = -1; + goto out; + } + spin_lock_irqsave(&id->lock, flags); for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (id->views[i] == NULL) @@ -962,6 +974,8 @@ id->name,view->name); printk(KERN_WARNING "debug: maximum number of views reached (%i)!\n", i); + debug_delete_proc_dir_entry(id->proc_root_entry, pde); + rc = -1; } else { @@ -970,11 +984,7 @@ mode |= S_IRUSR; if (view->input_proc) mode |= S_IWUSR; - id->proc_entries[i] = - debug_create_proc_dir_entry(id->proc_root_entry, - view->name, mode, - &debug_inode_ops, - &debug_file_ops); + id->proc_entries[i] = pde; rc = 0; } spin_unlock_irqrestore(&id->lock, flags); diff -urN linux-2.4.21/arch/s390x/kernel/entry.S linux-2.4.22/arch/s390x/kernel/entry.S --- linux-2.4.21/arch/s390x/kernel/entry.S 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -392,7 +392,7 @@ .long SYSCALL(sys_oldumount,sys32_oldumount_wrapper) .long SYSCALL(sys_ni_syscall,sys32_setuid16_wrapper) /* old setuid16 syscall*/ .long SYSCALL(sys_ni_syscall,sys32_getuid16) /* old getuid16 syscall*/ - .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 25 old stime syscall */ + .long SYSCALL(sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */ .long SYSCALL(sys_ptrace,sys32_ptrace_wrapper) .long SYSCALL(sys_alarm,sys32_alarm_wrapper) .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old fstat syscall */ @@ -489,7 +489,7 @@ .long SYSCALL(sys_sigreturn_glue,sys32_sigreturn_glue) .long SYSCALL(sys_clone_glue,sys_clone_glue) /* 120 */ .long SYSCALL(sys_setdomainname,sys32_setdomainname_wrapper) - .long SYSCALL(sys_newuname,sys32_newuname_wrapper) + .long SYSCALL(s390x_newuname,sys32_newuname_wrapper) .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* modify_ldt for i386 */ .long SYSCALL(sys_adjtimex,sys32_adjtimex_wrapper) .long SYSCALL(sys_mprotect,sys32_mprotect_wrapper) /* 125 */ @@ -503,7 +503,7 @@ .long SYSCALL(sys_fchdir,sys32_fchdir_wrapper) .long SYSCALL(sys_bdflush,sys32_bdflush_wrapper) .long SYSCALL(sys_sysfs,sys32_sysfs_wrapper) /* 135 */ - .long SYSCALL(sys_personality,sys32_personality_wrapper) + .long SYSCALL(s390x_personality,sys32_personality_wrapper) .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* for afs_syscall */ .long SYSCALL(sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */ .long SYSCALL(sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */ @@ -516,7 +516,7 @@ .long SYSCALL(sys_writev,sys32_writev_wrapper) .long SYSCALL(sys_getsid,sys32_getsid_wrapper) .long SYSCALL(sys_fdatasync,sys32_fdatasync_wrapper) - .long SYSCALL(sys_sysctl,sys_ni_syscall) + .long SYSCALL(sys_sysctl,sys32_sysctl_wrapper) .long SYSCALL(sys_mlock,sys32_mlock_wrapper) /* 150 */ .long SYSCALL(sys_munlock,sys32_munlock_wrapper) .long SYSCALL(sys_mlockall,sys32_mlockall_wrapper) @@ -558,7 +558,7 @@ .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams1 */ .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams2 */ .long SYSCALL(sys_vfork_glue,sys_vfork_glue) /* 190 */ - .long SYSCALL(sys_getrlimit,sys32_old_getrlimit_wrapper) + .long SYSCALL(sys_getrlimit,sys32_getrlimit_wrapper) .long SYSCALL(sys_mmap2,sys32_mmap2_wrapper) .long SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper) .long SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper) @@ -589,7 +589,7 @@ .long SYSCALL(sys_madvise,sys32_madvise_wrapper) .long SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */ .long SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper) - .long SYSCALL(sys_readahead,sys_ni_syscall) + .long SYSCALL(sys_readahead,sys32_readahead) .long SYSCALL(sys_ni_syscall,sys_ni_syscall) .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr */ .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */ diff -urN linux-2.4.21/arch/s390x/kernel/exec_domain32.c linux-2.4.22/arch/s390x/kernel/exec_domain32.c --- linux-2.4.21/arch/s390x/kernel/exec_domain32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/s390x/kernel/exec_domain32.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,30 @@ +/* + * Support for 32-bit Linux for S390 personality. + * + * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Gerhard Tonn (ton@de.ibm.com) + * + * + */ + +#include +#include +#include +#include + +struct exec_domain s390_exec_domain; + +static int __init +s390_init (void) +{ + s390_exec_domain.name = "Linux/s390"; + s390_exec_domain.handler = NULL; + s390_exec_domain.pers_low = PER_LINUX32; + s390_exec_domain.pers_high = PER_LINUX32; + s390_exec_domain.signal_map = default_exec_domain.signal_map; + s390_exec_domain.signal_invmap = default_exec_domain.signal_invmap; + register_exec_domain(&s390_exec_domain); + return 0; +} + +__initcall(s390_init); diff -urN linux-2.4.21/arch/s390x/kernel/head.S linux-2.4.22/arch/s390x/kernel/head.S --- linux-2.4.21/arch/s390x/kernel/head.S 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -548,26 +548,11 @@ tm __LC_CPUID,0xff # running under VM ? bno 0f-.LPG1(%r13) oi 7(%r12),1 # set VM flag -# -# we are running under VM, find out if we have PFIX -# - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - lghi %r0,0x4000 - lghi %r2,0 - .long 0x83200098 # diag 2,0,x'0098' - lock page - lghi %r2,4 - .long 0x83200098 # diag 2,0,x'0098' - unlock page - oi 7(%r12),128 # set PFIX flag 0: lh %r0,__LC_CPUID+4 # get cpu version chi %r0,0x7490 # running on a P/390 ? bne 1f-.LPG1(%r13) oi 7(%r12),4 # set P/390 flag 1: - chi %r0,0x2084 # new stidp format? - bne 2f-.LPG1(%r13) - oi 7(%r12),64 # set new stidp flag -2: # # find out if we have the MVPG instruction @@ -601,7 +586,7 @@ .quad .Lduct # cr2: dispatchable unit control table .quad 0 # cr3: instruction authorization .quad 0 # cr4: instruction authorization - .quad 0 # cr5: various things + .quad 0xffffffffffffffff # cr5: primary-aste origin .quad 0 # cr6: I/O interrupts .quad 0 # cr7: secondary space segment table .quad 0 # cr8: access registers translation diff -urN linux-2.4.21/arch/s390x/kernel/ioctl32.c linux-2.4.22/arch/s390x/kernel/ioctl32.c --- linux-2.4.21/arch/s390x/kernel/ioctl32.c 2002-02-25 11:37:56.000000000 -0800 +++ linux-2.4.22/arch/s390x/kernel/ioctl32.c 2003-08-25 04:44:40.000000000 -0700 @@ -25,6 +25,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -373,6 +378,107 @@ return sys_ioctl(fd, cmd, arg); } +struct loop_info32 { + int lo_number; /* ioctl r/o */ + __kernel_dev_t32 lo_device; /* ioctl r/o */ + unsigned int lo_inode; /* ioctl r/o */ + __kernel_dev_t32 lo_rdevice; /* ioctl r/o */ + int lo_offset; + int lo_encrypt_type; + int lo_encrypt_key_size; /* ioctl w/o */ + int lo_flags; /* ioctl r/o */ + char lo_name[LO_NAME_SIZE]; + unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ + unsigned int lo_init[2]; + char reserved[4]; +}; + +static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + struct loop_info l; + int err = -EINVAL; + + switch(cmd) { + case LOOP_SET_STATUS: + err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); + err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); + err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); + err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); + err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, + 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + if (err) { + err = -EFAULT; + } else { + set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&l); + set_fs (old_fs); + } + break; + case LOOP_GET_STATUS: + set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&l); + set_fs (old_fs); + if (!err) { + err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); + err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); + err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); + err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); + err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, + (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + if (err) + err = -EFAULT; + } + break; + default: { + static int count = 0; + if (++count <= 20) + printk("%s: Unknown loop ioctl cmd, fd(%d) " + "cmd(%08x) arg(%08lx)\n", + __FUNCTION__, fd, cmd, arg); + } + } + return err; +} + + +struct blkpg_ioctl_arg32 { + int op; + int flags; + int datalen; + u32 data; +}; + +static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg) +{ + struct blkpg_ioctl_arg a; + struct blkpg_partition p; + int err; + mm_segment_t old_fs = get_fs(); + + err = get_user(a.op, &arg->op); + err |= __get_user(a.flags, &arg->flags); + err |= __get_user(a.datalen, &arg->datalen); + err |= __get_user((long)a.data, &arg->data); + if (err) return err; + switch (a.op) { + case BLKPG_ADD_PARTITION: + case BLKPG_DEL_PARTITION: + if (a.datalen < sizeof(struct blkpg_partition)) + return -EINVAL; + if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) + return -EFAULT; + a.data = &p; + set_fs (KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&a); + set_fs (old_fs); + default: + return -EINVAL; + } + return err; +} + + static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); @@ -413,7 +519,19 @@ IOCTL32_DEFAULT(BIODASDINFO), IOCTL32_DEFAULT(BIODASDFMT), + IOCTL32_DEFAULT(BLKROSET), + IOCTL32_DEFAULT(BLKROGET), IOCTL32_DEFAULT(BLKRRPART), + IOCTL32_DEFAULT(BLKFLSBUF), + IOCTL32_DEFAULT(BLKRASET), + IOCTL32_DEFAULT(BLKFRASET), + IOCTL32_DEFAULT(BLKSECTSET), + IOCTL32_DEFAULT(BLKSSZGET), + IOCTL32_DEFAULT(BLKBSZGET), + IOCTL32_DEFAULT(BLKGETSIZE64), + + IOCTL32_DEFAULT(BLKELVGET), + IOCTL32_DEFAULT(BLKELVSET), IOCTL32_HANDLER(HDIO_GETGEO, hd_geometry_ioctl), @@ -422,6 +540,7 @@ IOCTL32_DEFAULT(TCSETAW), IOCTL32_DEFAULT(TCSETAF), IOCTL32_DEFAULT(TCSBRK), + IOCTL32_DEFAULT(TCSBRKP), IOCTL32_DEFAULT(TCXONC), IOCTL32_DEFAULT(TCFLSH), IOCTL32_DEFAULT(TCGETS), @@ -508,6 +627,10 @@ IOCTL32_DEFAULT(SIOCGSTAMP), + IOCTL32_DEFAULT(LOOP_SET_FD), + IOCTL32_DEFAULT(LOOP_CLR_FD), + + IOCTL32_DEFAULT(SIOCATMARK), IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf), IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc), @@ -552,7 +675,18 @@ IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl), - IOCTL32_HANDLER(BLKGETSIZE, w_long) + IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status), + IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status), + +/* Raw devices */ + IOCTL32_DEFAULT(RAW_SETBIND), + IOCTL32_DEFAULT(RAW_GETBIND), + + IOCTL32_HANDLER(BLKRAGET, w_long), + IOCTL32_HANDLER(BLKGETSIZE, w_long), + IOCTL32_HANDLER(BLKFRAGET, w_long), + IOCTL32_HANDLER(BLKSECTGET, w_long), + IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans) }; @@ -604,6 +738,8 @@ static void ioctl32_insert(struct ioctl32_list *entry) { int hash = ioctl32_hash(entry->handler.cmd); + + entry->next = 0; if (!ioctl32_hash_table[hash]) ioctl32_hash_table[hash] = entry; else { @@ -612,10 +748,51 @@ while (l->next) l = l->next; l->next = entry; - entry->next = 0; } } +int register_ioctl32_conversion(unsigned int cmd, + int (*handler)(unsigned int, unsigned int, + unsigned long, struct file *)) +{ + struct ioctl32_list *l, *new; + int hash; + + hash = ioctl32_hash(cmd); + for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) + if (l->handler.cmd == cmd) + return -EBUSY; + new = kmalloc(sizeof(struct ioctl32_list), GFP_KERNEL); + if (new == NULL) + return -ENOMEM; + new->handler.cmd = cmd; + new->handler.function = (void *) handler; + ioctl32_insert(new); + return 0; +} + +int unregister_ioctl32_conversion(unsigned int cmd) +{ + struct ioctl32_list *p, *l; + int hash; + + hash = ioctl32_hash(cmd); + p = NULL; + for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) { + if (l->handler.cmd == cmd) + break; + p = l; + } + if (l == NULL) + return -ENOENT; + if (p == NULL) + ioctl32_hash_table[hash] = l->next; + else + p->next = l->next; + kfree(l); + return 0; +} + static int __init init_ioctl32(void) { int i; diff -urN linux-2.4.21/arch/s390x/kernel/linux32.c linux-2.4.22/arch/s390x/kernel/linux32.c --- linux-2.4.21/arch/s390x/kernel/linux32.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/linux32.c 2003-08-25 04:44:40.000000000 -0700 @@ -63,6 +63,7 @@ #include #include +#include #include "linux32.h" @@ -384,18 +385,18 @@ struct shmid64_ds32 { struct ipc64_perm_ds32 shm_perm; - unsigned int __pad1; + __kernel_size_t32 shm_segsz; __kernel_time_t32 shm_atime; - unsigned int __pad2; + unsigned int __unused1; __kernel_time_t32 shm_dtime; - unsigned int __pad3; + unsigned int __unused2; __kernel_time_t32 shm_ctime; - __kernel_size_t32 shm_segsz; + unsigned int __unused3; __kernel_pid_t32 shm_cpid; __kernel_pid_t32 shm_lpid; unsigned int shm_nattch; - unsigned int __unused1; - unsigned int __unused2; + unsigned int __unused4; + unsigned int __unused5; }; @@ -504,16 +505,23 @@ static int do_sys32_msgsnd (int first, int second, int third, void *uptr) { - struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); + struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_USER); struct msgbuf32 *up = (struct msgbuf32 *)uptr; mm_segment_t old_fs; int err; if (!p) return -ENOMEM; - err = get_user (p->mtype, &up->mtype); - err |= __copy_from_user (p->mtext, &up->mtext, second); - if (err) + + err = -EINVAL; + if (second > MSGMAX || first < 0 || second < 0) + goto out; + + err = -EFAULT; + if (!uptr) + goto out; + if (get_user (p->mtype, &up->mtype) || + __copy_from_user (p->mtext, &up->mtext, second)) goto out; old_fs = get_fs (); set_fs (KERNEL_DS); @@ -532,6 +540,9 @@ mm_segment_t old_fs; int err; + if (first < 0 || second < 0) + return -EINVAL; + if (!version) { struct ipc_kludge_32 *uipck = (struct ipc_kludge_32 *)uptr; struct ipc_kludge_32 ipck; @@ -546,12 +557,12 @@ msgtyp = ipck.msgtyp; } err = -ENOMEM; - p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); + p = kmalloc (second + sizeof (struct msgbuf), GFP_USER); if (!p) goto out; old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_msgrcv (first, p, second + 4, msgtyp, third); + err = sys_msgrcv (first, p, second, msgtyp, third); set_fs (old_fs); if (err < 0) goto free_then_out; @@ -879,27 +890,39 @@ { switch (cmd) { case F_GETLK: - case F_SETLK: - case F_SETLKW: { struct flock f; mm_segment_t old_fs; long ret; - if(get_flock(&f, (struct flock32 *)arg)) + if(get_flock(&f, (struct flock32 *)A(arg))) return -EFAULT; old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_fcntl(fd, cmd, (unsigned long)&f); set_fs (old_fs); if (ret) return ret; if (f.l_start >= 0x7fffffffUL || - f.l_len >= 0x7fffffffUL || f.l_start + f.l_len >= 0x7fffffffUL) return -EOVERFLOW; - if(put_flock(&f, (struct flock32 *)arg)) + if(put_flock(&f, (struct flock32 *)A(arg))) return -EFAULT; return 0; } + case F_SETLK: + case F_SETLKW: + { + struct flock f; + mm_segment_t old_fs; + long ret; + + if(get_flock(&f, (struct flock32 *)A(arg))) + return -EFAULT; + old_fs = get_fs(); set_fs (KERNEL_DS); + ret = sys_fcntl(fd, cmd, (unsigned long)&f); + set_fs (old_fs); + if (ret) return ret; + return 0; + } default: return sys_fcntl(fd, cmd, (unsigned long)arg); } @@ -912,7 +935,7 @@ return sys32_fcntl(fd, cmd, arg); } -struct dqblk32 { +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -925,46 +948,45 @@ extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr); -asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr) +asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) { int cmds = cmd >> SUBCMDSHIFT; int err; - struct dqblk d; + struct v1c_mem_dqblk d; mm_segment_t old_fs; char *spec; switch (cmds) { - case Q_GETQUOTA: + case Q_V1_GETQUOTA: break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, (struct dqblk32 *)addr, - sizeof (struct dqblk32))) + case Q_V1_SETQUOTA: + case Q_V1_SETUSE: + case Q_V1_SETQLIM: + if (copy_from_user(&d, addr, sizeof (struct user_dqblk32))) return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; + d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime; break; default: - return sys_quotactl(cmd, special, - id, (caddr_t)addr); + return sys_quotactl(cmd, special, id, addr); } - spec = getname (special); + + spec = getname(special); err = PTR_ERR(spec); - if (IS_ERR(spec)) return err; - old_fs = get_fs (); + 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); - set_fs (old_fs); - putname (spec); + set_fs(old_fs); + putname(spec); if (err) return err; - if (cmds == Q_GETQUOTA) { + if (cmds == Q_V1_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 user_dqblk32 *)&d)->dqb_itime = i; + ((struct user_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user(addr, &d, sizeof (struct user_dqblk32))) return -EFAULT; } return 0; @@ -2151,15 +2173,17 @@ return ret; } -#define RLIM_INFINITY32 0x7fffffff -#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) +#define RLIM_OLD_INFINITY32 0x7fffffff +#define RLIM_INFINITY32 0xffffffff +#define RESOURCE32_OLD(x) ((x > RLIM_OLD_INFINITY32) ? RLIM_OLD_INFINITY32 : x) +#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) struct rlimit32 { u32 rlim_cur; u32 rlim_max; }; -extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim); +extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim); asmlinkage int sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim) { @@ -2168,7 +2192,23 @@ mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); - ret = sys_old_getrlimit(resource, &r); + ret = sys_getrlimit(resource, &r); + set_fs (old_fs); + if (!ret) { + ret = put_user (RESOURCE32_OLD(r.rlim_cur), &rlim->rlim_cur); + ret |= __put_user (RESOURCE32_OLD(r.rlim_max), &rlim->rlim_max); + } + return ret; +} + +asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim) +{ + struct rlimit r; + int ret; + mm_segment_t old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_getrlimit(resource, &r); set_fs (old_fs); if (!ret) { ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur); @@ -2588,8 +2628,23 @@ CMSG32_ALIGN(sizeof(struct cmsghdr32))); kcmsg32->cmsg_len = clen32; + switch (kcmsg32->cmsg_type) { + /* + * The timestamp type's data needs to be converted + * from 64-bit time values to 32-bit time values + */ + case SO_TIMESTAMP: { + __kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32); + __kernel_time_t* ptr_time = CMSG_DATA(ucmsg); + get_user(*ptr_time32, ptr_time); + get_user(*(ptr_time32+1), ptr_time+1); + kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) - + sizeof(__kernel_time_t32)); + } + default:; + } ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64)); - wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32)); + wp = (((char *)kcmsg32) + CMSG32_ALIGN(kcmsg32->cmsg_len)); } /* Copy back fixed up data, and adjust pointers. */ @@ -2612,6 +2667,7 @@ kmsg->msg_control = (void *) orig_cmsg_uptr; } +#if 0 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags) { struct socket *sock; @@ -2721,7 +2777,7 @@ sockfd_put(sock); } - if(uaddr != NULL && err >= 0) + if(uaddr != NULL && err >= 0 && kern_msg.msg_namelen) err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len); if(cmsg_ptr != 0 && err >= 0) { unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control); @@ -2737,6 +2793,222 @@ return err; return len; } +#endif + +/* + * BSD sendmsg interface + */ + +int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags) +{ + struct socket *sock; + char address[MAX_SOCK_ADDR]; + struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; + unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */ + unsigned char *ctl_buf = ctl; + struct msghdr msg_sys; + int err, ctl_len, iov_size, total_len; + + err = -EFAULT; + if (msghdr_from_user32_to_kern(&msg_sys, msg)) + goto out; + + sock = sockfd_lookup(fd, &err); + if (!sock) + goto out; + + /* do not move before msg_sys is valid */ + err = -EINVAL; + if (msg_sys.msg_iovlen > UIO_MAXIOV) + goto out_put; + + /* Check whether to allocate the iovec area*/ + err = -ENOMEM; + iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32); + if (msg_sys.msg_iovlen > UIO_FASTIOV) { + iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); + if (!iov) + goto out_put; + } + + /* This will also move the address data into kernel space */ + err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ); + if (err < 0) + goto out_freeiov; + total_len = err; + + err = -ENOBUFS; + + if (msg_sys.msg_controllen > INT_MAX) + goto out_freeiov; + ctl_len = msg_sys.msg_controllen; + if (ctl_len) + { + if (ctl_len > sizeof(ctl)) + { + ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL); + if (ctl_buf == NULL) + goto out_freeiov; + } + else if (ctl_len < sizeof(struct cmsghdr)) + { + /* to get same error message as on 31 bit native */ + err = EOPNOTSUPP; + goto out_freeiov; + } + err = -EFAULT; + if (cmsghdr_from_user32_to_kern(&msg_sys, ctl_buf, ctl_len)) + goto out_freectl; +// msg_sys.msg_control = ctl_buf; + } + msg_sys.msg_flags = flags; + + if (sock->file->f_flags & O_NONBLOCK) + msg_sys.msg_flags |= MSG_DONTWAIT; + err = sock_sendmsg(sock, &msg_sys, total_len); + +out_freectl: + if (ctl_buf != ctl) + sock_kfree_s(sock->sk, ctl_buf, ctl_len); +out_freeiov: + if (iov != iovstack) + sock_kfree_s(sock->sk, iov, iov_size); +out_put: + sockfd_put(sock); +out: + return err; +} + +static __inline__ void +scm_recv32(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm, int flags, unsigned long cmsg_ptr) +{ + if(!msg->msg_control) + { + if(sock->passcred || scm->fp) + msg->msg_flags |= MSG_CTRUNC; + scm_destroy(scm); + return; + } + /* If recvmsg processing itself placed some + * control messages into user space, it's is + * using 64-bit CMSG processing, so we need + * to fix it up before we tack on more stuff. + */ + if((unsigned long) msg->msg_control != cmsg_ptr) + cmsg32_recvmsg_fixup(msg, cmsg_ptr); + /* Wheee... */ + if(sock->passcred) + put_cmsg32(msg, + SOL_SOCKET, SCM_CREDENTIALS, + sizeof(scm->creds), &scm->creds); + if(!scm->fp) + return; + + scm_detach_fds32(msg, scm); +} + +static int +sock_recvmsg32(struct socket *sock, struct msghdr *msg, int size, int flags, + unsigned long cmsg_ptr) +{ + struct scm_cookie scm; + + memset(&scm, 0, sizeof(scm)); + size = sock->ops->recvmsg(sock, msg, size, flags, &scm); + if (size >= 0) + scm_recv32(sock, msg, &scm, flags, cmsg_ptr); + + return size; +} + +/* + * BSD recvmsg interface + */ + +int +sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags) +{ + struct socket *sock; + struct iovec iovstack[UIO_FASTIOV]; + struct iovec *iov=iovstack; + struct msghdr msg_sys; + unsigned long cmsg_ptr; + int err, iov_size, total_len, len; + + /* kernel mode address */ + char addr[MAX_SOCK_ADDR]; + + /* user mode address pointers */ + struct sockaddr *uaddr; + int *uaddr_len; + + err=-EFAULT; + if (msghdr_from_user32_to_kern(&msg_sys, msg)) + goto out; + + sock = sockfd_lookup(fd, &err); + if (!sock) + goto out; + + err = -EINVAL; + if (msg_sys.msg_iovlen > UIO_MAXIOV) + goto out_put; + + /* Check whether to allocate the iovec area*/ + err = -ENOMEM; + iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); + if (msg_sys.msg_iovlen > UIO_FASTIOV) { + iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); + if (!iov) + goto out_put; + } + + /* + * Save the user-mode address (verify_iovec will change the + * kernel msghdr to use the kernel address space) + */ + + uaddr = msg_sys.msg_name; + uaddr_len = &msg->msg_namelen; + err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE); + if (err < 0) + goto out_freeiov; + total_len=err; + + cmsg_ptr = (unsigned long)msg_sys.msg_control; + msg_sys.msg_flags = 0; + + if (sock->file->f_flags & O_NONBLOCK) + flags |= MSG_DONTWAIT; + err = sock_recvmsg32(sock, &msg_sys, total_len, flags, cmsg_ptr); + if (err < 0) + goto out_freeiov; + len = err; + + if (uaddr != NULL && + /* in order to get same error message as on native 31 bit */ + msg_sys.msg_namelen > 0) { + err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); + if (err < 0) + goto out_freeiov; + } + err = __put_user(msg_sys.msg_flags, &msg->msg_flags); + if (err) + goto out_freeiov; + err = __put_user((__kernel_size_t32) ((unsigned long)msg_sys.msg_control - cmsg_ptr), &msg->msg_controllen); + if (err) + goto out_freeiov; + err = len; + +out_freeiov: + if (iov != iovstack) + sock_kfree_s(sock->sk, iov, iov_size); +out_put: + sockfd_put(sock); +out: + return err; +} extern asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen); @@ -2820,6 +3092,20 @@ if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER) return do_set_icmpv6_filter(fd, level, optname, optval, optlen); + if (level == SOL_SOCKET && + (optname == SO_SNDTIMEO || optname == SO_RCVTIMEO)) { + long ret; + struct timeval tmp; + mm_segment_t old_fs; + + if (get_tv32(&tmp, (struct timeval32 *)optval )) + return -EFAULT; + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_setsockopt(fd, level, optname, (char *) &tmp, sizeof(struct timeval)); + set_fs(old_fs); + return ret; + } return sys_setsockopt(fd, level, optname, optval, optlen); } @@ -3669,7 +3955,7 @@ */ static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32) { - return copy_to_user(res32, kres, sizeof(*res32)); + return copy_to_user(res32, kres, sizeof(*res32)) ? -EFAULT : 0; } /* @@ -3891,15 +4177,25 @@ asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count, u32 poshi, u32 poslo) { + if ((ssize_t32) count < 0) + return -EINVAL; return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); } asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf, __kernel_size_t32 count, u32 poshi, u32 poslo) { + if ((ssize_t32) count < 0) + return -EINVAL; return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); } +extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count); + +asmlinkage ssize_t32 sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count) +{ + return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); +} extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count); @@ -4344,3 +4640,22 @@ return ret; } +asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count); + +asmlinkage ssize_t32 sys32_read(unsigned int fd, char * buf, size_t count) +{ + if ((ssize_t32) count < 0) + return -EINVAL; + + return sys_read(fd, buf, count); +} + +asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count); + +asmlinkage ssize_t32 sys32_write(unsigned int fd, char * buf, size_t count) +{ + if ((ssize_t32) count < 0) + return -EINVAL; + + return sys_write(fd, buf, count); +} diff -urN linux-2.4.21/arch/s390x/kernel/s390_ksyms.c linux-2.4.22/arch/s390x/kernel/s390_ksyms.c --- linux-2.4.21/arch/s390x/kernel/s390_ksyms.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/s390_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -62,6 +62,20 @@ EXPORT_SYMBOL(overflowuid); EXPORT_SYMBOL(overflowgid); +#ifdef CONFIG_S390_SUPPORT +/* + * Dynamically add/remove 31 bit ioctl conversion functions. + */ +extern int register_ioctl32_conversion(unsigned int cmd, + int (*handler)(unsigned int, + unsigned int, + unsigned long, + struct file *)); +int unregister_ioctl32_conversion(unsigned int cmd); +EXPORT_SYMBOL(register_ioctl32_conversion); +EXPORT_SYMBOL(unregister_ioctl32_conversion); +#endif + /* * misc. */ @@ -70,5 +84,5 @@ EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(console_mode); EXPORT_SYMBOL(console_device); -EXPORT_SYMBOL(pfix_table); EXPORT_SYMBOL_NOVERS(do_call_softirq); +EXPORT_SYMBOL(sys_wait4); diff -urN linux-2.4.21/arch/s390x/kernel/setup.c linux-2.4.22/arch/s390x/kernel/setup.c --- linux-2.4.21/arch/s390x/kernel/setup.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -56,8 +56,6 @@ unsigned long cpu_initialized = 0; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ -void* *pfix_table=NULL; - /* * Setup options */ @@ -319,10 +317,6 @@ printk((MACHINE_IS_VM) ? "We are running under VM (64 bit mode)\n" : "We are running native (64 bit mode)\n"); - if (MACHINE_IS_VM) - printk((MACHINE_HAS_PFIX) ? - "This machine has PFIX support\n" : - "This machine has no PFIX support\n"); ROOT_DEV = to_kdev_t(0x0100); memory_start = (unsigned long) &_end; /* fixit if use $CODELO etc*/ diff -urN linux-2.4.21/arch/s390x/kernel/signal.c linux-2.4.22/arch/s390x/kernel/signal.c --- linux-2.4.21/arch/s390x/kernel/signal.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -575,10 +575,7 @@ /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff -urN linux-2.4.21/arch/s390x/kernel/signal32.c linux-2.4.22/arch/s390x/kernel/signal32.c --- linux-2.4.21/arch/s390x/kernel/signal32.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/s390x/kernel/signal32.c 2003-08-25 04:44:40.000000000 -0700 @@ -302,7 +302,7 @@ save_fp_regs(&fpregs); __put_user(fpregs.fpc, &sregs->fpregs.fpc); for(i=0; ifpregs.fprs[i].d); + err |= __put_user(fpregs.fprs[i].ui, &sregs->fpregs.fprs[i].d); } return(err); @@ -331,7 +331,7 @@ (regs->psw.addr&PSW_ADDR_DEBUGCHANGE); __get_user(fpregs.fpc, &sregs->fpregs.fpc); for(i=0; ifpregs.fprs[i].d); + err |= __get_user(fpregs.fprs[i].ui, &sregs->fpregs.fprs[i].d); if(!err) restore_fp_regs(&fpregs); } @@ -474,6 +474,10 @@ goto give_sigsegv; } + /* Set up backchain. */ + if (__put_user((unsigned int) regs->gprs[15], (unsigned int *) frame)) + goto give_sigsegv; + /* Set up registers for signal handler */ regs->gprs[15] = (addr_t)frame; regs->psw.addr = FIX_PSW(ka->sa.sa_handler); @@ -527,6 +531,10 @@ (u16 *)(frame->retcode)); } + /* Set up backchain. */ + if (__put_user((unsigned int) regs->gprs[15], (unsigned int *) frame)) + goto give_sigsegv; + /* Set up registers for signal handler */ regs->gprs[15] = (addr_t)frame; regs->psw.addr = FIX_PSW(ka->sa.sa_handler); @@ -675,7 +683,7 @@ continue; switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: + case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: continue; case SIGTSTP: case SIGTTIN: case SIGTTOU: diff -urN linux-2.4.21/arch/s390x/kernel/wrapper32.S linux-2.4.22/arch/s390x/kernel/wrapper32.S --- linux-2.4.21/arch/s390x/kernel/wrapper32.S 2002-02-25 11:37:56.000000000 -0800 +++ linux-2.4.22/arch/s390x/kernel/wrapper32.S 2003-08-25 04:44:40.000000000 -0700 @@ -17,14 +17,14 @@ llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # char * llgfr %r4,%r4 # size_t - jg sys_read # branch to sys_read + jg sys32_read # branch to sys_read .globl sys32_write_wrapper sys32_write_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # const char * llgfr %r4,%r4 # size_t - jg sys_write # branch to system call + jg sys32_write # branch to system call .globl sys32_open_wrapper sys32_open_wrapper: @@ -311,6 +311,12 @@ llgtr %r3,%r3 # struct rlimit_emu31 * jg sys32_old_getrlimit # branch to system call + .globl sys32_getrlimit_wrapper +sys32_getrlimit_wrapper: + llgfr %r2,%r2 # unsigned int + llgtr %r3,%r3 # struct rlimit_emu31 * + jg sys32_getrlimit # branch to system call + .globl sys32_mmap2_wrapper sys32_mmap2_wrapper: llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * @@ -537,7 +543,7 @@ .globl sys32_newuname_wrapper sys32_newuname_wrapper: llgtr %r2,%r2 # struct new_utsname * - jg sys_newuname # branch to system call + jg s390x_newuname # branch to system call .globl sys32_adjtimex_wrapper sys32_adjtimex_wrapper: @@ -614,7 +620,7 @@ .globl sys32_personality_wrapper sys32_personality_wrapper: llgfr %r2,%r2 # unsigned long - jg sys_personality # branch to system call + jg s390x_personality # branch to system call .globl sys32_setfsuid16_wrapper sys32_setfsuid16_wrapper: @@ -1091,3 +1097,13 @@ llgtr %r3,%r3 # struct stat64 * llgfr %r4,%r4 # long jg sys32_fstat64 # branch to system call + + .globl sys32_stime_wrapper +sys32_stime_wrapper: + llgtr %r2,%r2 # int * + jg sys_stime # branch to system call + + .globl sys32_sysctl_wrapper +sys32_sysctl_wrapper: + llgtr %r2,%r2 # struct __sysctl_args32 * + jg sys32_sysctl diff -urN linux-2.4.21/arch/s390x/mm/init.c linux-2.4.22/arch/s390x/mm/init.c --- linux-2.4.21/arch/s390x/mm/init.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/s390x/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -45,6 +45,28 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); +static inline int +__pgd_populate(unsigned long *pgd_slot, unsigned long offset, pmd_t *pmd) +{ + if (offset == 0 && + ((*pgd_slot & _PGD_ENTRY_INV) != 0 || + (*pgd_slot & _PGD_ENTRY_LEN(2)) == 0)) { + /* Set lower pmd, upper pmd is empty. */ + *pgd_slot = __pa(pmd) | _PGD_ENTRY_MASK | + _PGD_ENTRY_OFF(0) | _PGD_ENTRY_LEN(1); + return 1; + } + if (offset == 4 && + ((*pgd_slot & _PGD_ENTRY_INV) != 0 || + (*pgd_slot & _PGD_ENTRY_OFF(2)) != 0)) { + /* Lower pmd empty, set upper pmd. */ + *pgd_slot = (__pa(pmd) - 0x2000) | _PGD_ENTRY_MASK | + _PGD_ENTRY_OFF(2) | _PGD_ENTRY_LEN(3); + return 1; + } + return 0; +} + pmd_t *pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) { unsigned long addr = (unsigned long) pgd; @@ -52,29 +74,42 @@ unsigned long offset = addr & 4; pmd_t *new, *pmd2; int i; - - if (offset == 0 && - ((*pgd_slot & _PGD_ENTRY_INV) != 0 || - (*pgd_slot & _PGD_ENTRY_LEN(2)) == 0)) { - /* Set lower pmd, upper pmd is empty. */ - *pgd_slot = __pa(pmd) | _PGD_ENTRY_MASK | - _PGD_ENTRY_OFF(0) | _PGD_ENTRY_LEN(1); - return pmd; - } - if (offset == 4 && - ((*pgd_slot & _PGD_ENTRY_INV) != 0 || - (*pgd_slot & _PGD_ENTRY_OFF(2)) != 0)) { - /* Lower pmd empty, set upper pmd. */ - *pgd_slot = (__pa(pmd) - 0x2000) | _PGD_ENTRY_MASK | - _PGD_ENTRY_OFF(2) | _PGD_ENTRY_LEN(3); + + /* Check if we can get away with a half-sized pmd. */ + if (__pgd_populate(pgd_slot, offset, pmd)) return pmd; - } + /* We have to enlarge the pmd to 16K if we arrive here. */ + spin_unlock(&mm->page_table_lock); new = (pmd_t *) __get_free_pages(GFP_KERNEL, 2); - if (new == NULL) { + spin_lock(&mm->page_table_lock); + + /* + * Because we dropped the lock, we should re-check the + * entry, as somebody else could have populated it.. + */ + if (!pgd_none(*pgd)) { + if (new) + free_pages((unsigned long) new, 2); + pmd_free(pmd); + return (pmd_t *) pgd_val(*pgd); + } + + if (!new) { pmd_free(pmd); return NULL; } + + /* + * Re-check if we can get away with a half-sized pmd. We + * dropped the lock so somebody else could have freed the + * other half of the pmd. + */ + if (__pgd_populate(pgd_slot, offset, pmd)) { + free_pages((unsigned long) new, 2); + return pmd; + } + /* Set the PG_arch_1 bit on the first and the third pmd page so that pmd_free_fast can recognize pmds that have been allocated with an order 2 allocation. */ @@ -234,11 +269,6 @@ continue; } set_pte(pt_dir, pte); - if (address < memory_size ) /* do not set storage - key outside the storage - or die */ - set_access_key(pte); /* switch to our - access key */ address += PAGE_SIZE; } } diff -urN linux-2.4.21/arch/s390x/vmlinux-shared.lds linux-2.4.22/arch/s390x/vmlinux-shared.lds --- linux-2.4.21/arch/s390x/vmlinux-shared.lds 2002-02-25 11:37:56.000000000 -0800 +++ linux-2.4.22/arch/s390x/vmlinux-shared.lds 2003-08-25 04:44:40.000000000 -0700 @@ -2,7 +2,7 @@ * Written by Martin Schwidefsky (schwidefsky@de.ibm.com) */ OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") -OUTPUT_ARCH(s390) +OUTPUT_ARCH(s390:64-bit) ENTRY(_start) SECTIONS { diff -urN linux-2.4.21/arch/s390x/vmlinux.lds linux-2.4.22/arch/s390x/vmlinux.lds --- linux-2.4.21/arch/s390x/vmlinux.lds 2002-02-25 11:37:56.000000000 -0800 +++ linux-2.4.22/arch/s390x/vmlinux.lds 2003-08-25 04:44:40.000000000 -0700 @@ -2,7 +2,7 @@ * Written by Martin Schwidefsky (schwidefsky@de.ibm.com) */ OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") -OUTPUT_ARCH(s390) +OUTPUT_ARCH(s390:64-bit) ENTRY(_start) SECTIONS { diff -urN linux-2.4.21/arch/sh/Makefile linux-2.4.22/arch/sh/Makefile --- linux-2.4.21/arch/sh/Makefile 2001-10-15 13:36:48.000000000 -0700 +++ linux-2.4.22/arch/sh/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.6 2000/06/10 03:03:52 gniibe Exp $ +# $Id: Makefile,v 1.1.1.1.2.2 2002/05/10 17:58:54 jzs Exp $ # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive @@ -24,6 +24,14 @@ LDFLAGS := -EB endif +ifdef CONFIG_SH_KGDB +CFLAGS :=$(CFLAGS:-fomit-frame-pointer=) -g +AFLAGS += -g +ifdef CONFIG_KGDB_MORE +CFLAGS += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g') +endif +endif + LD =$(CROSS_COMPILE)ld $(LDFLAGS) OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr -S diff -urN linux-2.4.21/arch/sh/config.in linux-2.4.22/arch/sh/config.in --- linux-2.4.21/arch/sh/config.in 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sh/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -30,6 +30,7 @@ "Generic CONFIG_SH_GENERIC \ SolutionEngine CONFIG_SH_SOLUTION_ENGINE \ SolutionEngine7751 CONFIG_SH_7751_SOLUTION_ENGINE \ + SHMobileSolutionEngine CONFIG_SH_MOBILE_SOLUTION_ENGINE \ STB1_Harp CONFIG_SH_STB1_HARP \ STB1_Overdrive CONFIG_SH_STB1_OVERDRIVE \ HP620 CONFIG_SH_HP620 \ @@ -42,11 +43,15 @@ CAT68701 CONFIG_SH_CAT68701 \ BigSur CONFIG_SH_BIGSUR \ SH2000 CONFIG_SH_SH2000 \ + HS7729PCI CONFIG_SH_HS7729PCI \ ADX CONFIG_SH_ADX \ + SecureEdge5410 CONFIG_SH_SECUREEDGE5410 \ + KeyWest CONFIG_SH_KEYWEST \ BareCPU CONFIG_SH_UNKNOWN" Generic -# The SH7750 RTC module is disabled in the Dreamcast -if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then +# The SH7750 RTC module is disabled in the Dreamcast and SH-Mobile SolutionEngine +if [ "$CONFIG_SH_DREAMCAST" = "y" -o \ + "$CONFIG_SH_MOBILE_SOLUTION_ENGINE" = "y" ]; then define_bool CONFIG_SH_RTC n else define_bool CONFIG_SH_RTC y @@ -58,12 +63,18 @@ fi choice 'Processor type' \ - "SH7707 CONFIG_CPU_SUBTYPE_SH7707 \ + "SH7300 CONFIG_CPU_SUBTYPE_SH7300 \ + SH7707 CONFIG_CPU_SUBTYPE_SH7707 \ SH7708 CONFIG_CPU_SUBTYPE_SH7708 \ SH7709 CONFIG_CPU_SUBTYPE_SH7709 \ SH7750 CONFIG_CPU_SUBTYPE_SH7750 \ SH7751 CONFIG_CPU_SUBTYPE_SH7751 \ - ST40STB1 CONFIG_CPU_SUBTYPE_ST40STB1" SH7708 + ST40RA/ST40STB1 CONFIG_CPU_SUBTYPE_ST40STB1 \ + ST40GX1 CONFIG_CPU_SUBTYPE_ST40GX1" SH7708 +if [ "$CONFIG_CPU_SUBTYPE_SH7300" = "y" ]; then + define_bool CONFIG_CPU_SH3 y + define_bool CONFIG_CPU_SH4 n +fi if [ "$CONFIG_CPU_SUBTYPE_SH7707" = "y" ]; then define_bool CONFIG_CPU_SH3 y define_bool CONFIG_CPU_SH4 n @@ -87,6 +98,12 @@ if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then define_bool CONFIG_CPU_SH3 n define_bool CONFIG_CPU_SH4 y + define_bool CONFIG_CPU_SUBTYPE_ST40 y +fi +if [ "$CONFIG_CPU_SUBTYPE_ST40GX1" = "y" ]; then + define_bool CONFIG_CPU_SH3 n + define_bool CONFIG_CPU_SH4 y + define_bool CONFIG_CPU_SUBTYPE_ST40 y fi bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN # Platform-specific memory start and size definitions @@ -100,13 +117,19 @@ define_hex CONFIG_MEMORY_SIZE 04000000 define_bool CONFIG_MEMORY_SET y fi +if [ "$CONFIG_SH_MOBILE_SOLUTION_ENGINE" = "y" ]; then + define_hex CONFIG_MEMORY_START 0c000000 + define_hex CONFIG_MEMORY_SIZE 04000000 + define_bool CONFIG_MEMORY_SET y +fi if [ "$CONFIG_SH_HP600" = "y" -o "$CONFIG_SH_BIGSUR" = "y" -o \ - "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" ]; then + "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" -o \ + "$CONFIG_SH_KEYWEST" = "y" ]; then define_hex CONFIG_MEMORY_START 0c000000 define_hex CONFIG_MEMORY_SIZE 00400000 define_bool CONFIG_MEMORY_SET y fi -if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then +if [ "$CONFIG_CPU_SUBTYPE_ST40" = "y" ]; then bool 'Memory on LMI' CONFIG_ST40_LMI_MEMORY if [ "$CONFIG_ST40_LMI_MEMORY" = "y" ] ; then define_hex CONFIG_MEMORY_START 08000000 @@ -119,11 +142,29 @@ define_hex CONFIG_MEMORY_SIZE 00400000 define_bool CONFIG_MEMORY_SET y fi +if [ "$CONFIG_SH_SECUREEDGE5410" = "y" ]; then + define_hex CONFIG_MEMORY_START 08000000 + define_hex CONFIG_MEMORY_SIZE 01000000 + define_bool CONFIG_MEMORY_SET y +fi +if [ "$CONFIG_SH_HS7729PCI" = "y" ]; then + define_hex CONFIG_MEMORY_START 0c000000 + define_hex CONFIG_MEMORY_SIZE 04000000 + define_bool CONFIG_MEMORY_SET y +fi # If none of the above have set memory start/size, ask the user. if [ "$CONFIG_MEMORY_SET" != "y" ]; then hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 hex 'Physical memory size' CONFIG_MEMORY_SIZE 00400000 fi +dep_bool 'Enable OC RAM zone (experimental)' CONFIG_SCRATCH_SPACE $CONFIG_EXPERIMENTAL + +if [ "$CONFIG_CPU_SUBTYPE_ST40" = "y" ]; then + bool 'PCI emulation of on-chip peripherals' CONFIG_SH_PCI_EMULATION + if [ "$CONFIG_SH_PCI_EMULATION" = "y" -a "$CONFIG_CPU_SUBTYPE_ST40GX1" = "y" ]; then + bool ' USB OHCI Host Controller' CONFIG_SH_PCI_USB + fi +fi endmenu if [ "$CONFIG_SH_HP690" = "y" ]; then @@ -138,7 +179,13 @@ # Even on SuperH devices which don't have an ISA bus, # this variable helps the PCMCIA modules handle # IRQ requesting properly -- Greg Banks. -define_bool CONFIG_ISA y + +if [ "$CONFIG_SH_SECUREEDGE5410" = "y" ]; then + define_bool CONFIG_ISA n +else + define_bool CONFIG_ISA y +fi + define_bool CONFIG_EISA n define_bool CONFIG_MCA n define_bool CONFIG_SBUS n @@ -147,7 +194,7 @@ if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o \ "$CONFIG_SH_UNKNOWN" = "y" -o "$CONFIG_SH_CAT68701" = "y" -o \ - "$CONFIG_SH_ADX" = "y" ]; then + "$CONFIG_SH_ADX" = "y" -o "$CONFIG_SH_HS7729PCI" = "y" ]; then bool 'Compact Flash Enabler support' CONFIG_CF_ENABLER fi @@ -175,21 +222,26 @@ int 'HD64465 IRQ' CONFIG_HD64465_IRQ 5 fi +bool 'Wakeup UBC on startup' CONFIG_UBC_WAKEUP bool 'DMA controller (DMAC) support' CONFIG_SH_DMA +int 'Peripheral clock frequency(Hz) (0: auto detect)' CONFIG_SH_PCLK_FREQ 0 0 1000000000 + +bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL +if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then + string 'Initial kernel command string' CONFIG_CMDLINE "console=ttySC1,115200" +fi bool 'PCI support' CONFIG_PCI if [ "$CONFIG_PCI" = "y" ]; then - choice ' PCI access mode' \ - "BIOS CONFIG_PCI_GOBIOS \ - Direct CONFIG_PCI_GODIRECT \ - Any CONFIG_PCI_GOANY" Any - if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then - define_bool CONFIG_PCI_BIOS y - fi - if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then - define_bool CONFIG_PCI_DIRECT y - fi - bool 'Cache and PCI noncoherent' CONFIG_SH_PCIDMA_NONCOHERENT + if [ "$CONFIG_SH_HS7729PCI" = "y" ]; then + define_bool CONFIG_PCI_SD0001 y + define_hex CONFIG_PCI_SD0001_IRQ 0 + define_hex CONFIG_PCI_SD0001_BASE b0000000 + define_bool CONFIG_SH_PCIDMA_NONCOHERENT y + else + define_bool CONFIG_PCI_SD0001 n + bool 'Cache and PCI noncoherent' CONFIG_SH_PCIDMA_NONCOHERENT + fi fi source drivers/pci/Config.in @@ -259,7 +311,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -280,9 +332,9 @@ # source drivers/input/Config.in -# if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then -# source drivers/maple/Config.in -# fi +if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then + source drivers/maple/Config.in +fi mainmenu_option next_comment comment 'Character devices' @@ -309,6 +361,7 @@ "$CONFIG_SH_STB1_OVERDRIVE" = "y" -o \ "$CONFIG_SH_BIGSUR" = "y" -o \ "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \ + "$CONFIG_SH_MOBILE_SOLUTION_ENGINE" = "y" -o \ "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then bool 'Heartbeat LED' CONFIG_HEARTBEAT fi @@ -341,7 +394,7 @@ bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT - dep_tristate ' SH 3/4 Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH + dep_tristate ' SuperH Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH fi endmenu @@ -385,6 +438,34 @@ if [ "$CONFIG_SH_STANDARD_BIOS" = "y" ]; then bool 'Early printk support' CONFIG_SH_EARLY_PRINTK fi +bool 'Include KGDB kernel debugger' CONFIG_SH_KGDB +if [ "$CONFIG_SH_KGDB" = "y" ]; then + bool ' Enter KGDB on NMI' CONFIG_KGDB_NMI + bool ' Include KGDB thread support' CONFIG_KGDB_THREAD + bool ' Console messages through GDB' CONFIG_SH_KGDB_CONSOLE + bool ' Allow SysRq "G" to enter KGDB?' CONFIG_KGDB_SYSRQ + if [ "$CONFIG_KGDB_SYSRQ" != "n" ]; then + define_bool CONFIG_MAGIC_SYSRQ y + fi + bool ' Include KGDB kernel asserts' CONFIG_KGDB_KERNEL_ASSERTS + bool ' Add additional compile options' CONFIG_KGDB_MORE + if [ "$CONFIG_KGDB_MORE" = "y" ]; then + string ' Additional compile options' CONFIG_KGDB_OPTIONS "-O1" + fi + mainmenu_option next_comment + comment ' Default KGDB port setup' + int 'Port number (ttySCn)' CONFIG_KGDB_DEFPORT 1 + int 'Baud rate' CONFIG_KGDB_DEFBAUD 115200 + choice 'Parity' \ + "None CONFIG_KGDB_DEFPARITY_N \ + Even CONFIG_KGDB_DEFPARITY_E \ + Odd CONFIG_KGDB_DEFPARITY_O" None + choice 'DataBits' \ + "7 CONFIG_KGDB_DEFBITS_7 \ + 8 CONFIG_KGDB_DEFBITS_8" 8 + endmenu +fi endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/sh/kernel/Makefile linux-2.4.22/arch/sh/kernel/Makefile --- linux-2.4.21/arch/sh/kernel/Makefile 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -12,40 +12,53 @@ O_TARGET := kernel.o -export-objs := io.o io_generic.o io_hd64461.o setup_hd64461.o sh_ksyms.o +export-objs := io.o io_generic.o io_hd64461.o setup_hd64461.o sh_ksyms.o \ + dma.o obj-y := process.o signal.o entry.o traps.o irq.o irq_ipr.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ - irq_imask.o io.o io_generic.o sh_ksyms.o + irq_imask.o io.o io_generic.o sh_ksyms.o ubc.o obj-$(CONFIG_CF_ENABLER) += cf-enabler.o obj-$(CONFIG_CPU_SH4) += fpu.o obj-$(CONFIG_SH_RTC) += rtc.o obj-$(CONFIG_SH_DMA) += dma.o obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o +obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o ifeq ($(CONFIG_PCI),y) ifeq ($(CONFIG_SH_DREAMCAST),y) obj-y += pci-dc.o pcibios.o else obj-y += pci-dma.o pcibios.o -obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)+= pci_st40.o +obj-$(CONFIG_CPU_SUBTYPE_ST40)+= pci_st40.o obj-$(CONFIG_CPU_SUBTYPE_SH7751)+= pci-sh7751.o obj-$(CONFIG_SH_BIGSUR)+= pci-bigsur.o obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= pci-7751se.o +obj-$(CONFIG_PCI_SD0001)+= pci-sd0001.o +obj-$(CONFIG_SH_SECUREEDGE5410) += pci-snapgear.o +obj-$(CONFIG_SH_KEYWEST) += pci-v320usc.o endif endif obj-$(CONFIG_SH_HP600) += mach_hp600.o machine-specific-objs += mach_hp600.o +obj-$(CONFIG_SH_HS7729PCI) += mach_hs7729pci.o setup_hs7729pci.o io_hs7729pci.o +machine-specific-objs += mach_hs7729pci.o setup_hs7729pci.o io_hs7729pci.o + obj-$(CONFIG_SH_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o machine-specific-objs += mach_se.o setup_se.o io_se.o led_se.o obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_7751se.o setup_7751se.o \ - io_7751se.o led_7751se.o + io_7751se.o led_se.o machine-specific-objs += mach_7751se.o 7751setup_se.o \ - io_7751se.o led_7751se.o pci-7751se.o + io_7751se.o led_se.o pci-7751se.o + +obj-$(CONFIG_SH_MOBILE_SOLUTION_ENGINE)+= mach_shmse.o setup_shmse.o \ + io_shmse.o led_se.o +machine-specific-objs += mach_shmse.o setup_shmse.o \ + io_shmse.o led_se.o obj-$(CONFIG_SH_BIGSUR) += mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o machine-specific-objs += mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o @@ -65,11 +78,21 @@ obj-$(CONFIG_HD64461) += setup_hd64461.o io_hd64461.o machine-specific-objs += setup_hd64461.o io_hd64461.o -obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) +=irq_intc2.o +obj-$(CONFIG_CPU_SUBTYPE_ST40) +=irq_intc2.o obj-$(CONFIG_SH_ADX) += mach_adx.o setup_adx.o io_adx.o irq_maskreg.o machine-specific-objs += mach_adx.o setup_adx.o io_adx.o irq_maskreg.o +obj-$(CONFIG_SH_SECUREEDGE5410) += mach_snapgear.o setup_snapgear.o io_snapgear.o +machine-specific-objs += mach_snapgear.o setup_snapgear.o io_snapgear.o +ifeq ($(CONFIG_RTC),y) +obj-$(CONFIG_SH_SECUREEDGE5410) += rtc-snapgear.o +machine-specific-objs += rtc-snapgear.o +endif + +obj-$(CONFIG_SH_KEYWEST) += mach_keywest.o setup_keywest.o io_keywest.o +machine-specific-objs += mach_keywest.o setup_keywest.o io_keywest.o + # Doesn't compile well, so don't include in machine-specific-objs obj-$(CONFIG_HD64465) += setup_hd64465.o io_hd64465.o hd64465_gpio.o obj-$(CONFIG_SH_DMIDA) += mach_dmida.o diff -urN linux-2.4.21/arch/sh/kernel/cf-enabler.c linux-2.4.22/arch/sh/kernel/cf-enabler.c --- linux-2.4.21/arch/sh/kernel/cf-enabler.c 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/cf-enabler.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: cf-enabler.c,v 1.8 2001/07/18 12:32:21 gniibe Exp $ +/* $Id: cf-enabler.c,v 1.1.1.1.2.1 2003/06/24 08:52:51 dwmw2 Exp $ * * linux/drivers/block/cf-enabler.c * @@ -11,7 +11,7 @@ #include #include - +#include #include #include @@ -87,7 +87,7 @@ return 0; } -#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE) +#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_HS7729PCI) #include /* @@ -142,15 +142,31 @@ ctrl_outw(0x2000, MRSHPC_ICR); ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206); ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200); + + if (MACH_HS7729PCI) { + /* Empirical evidence shows that we have to delay for + ten milliseconds and then redo the last outb. + I have no clue why. And all the docs are in Japanese + so I feel no shame in just doing it this way. Besides, + all this is just a crap hack for the fact that we don't + have sensible userspace-less PCMCIA support in 2.4. + + dwmw2. + */ + mdelay(10); + ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200); + } + return 0; } #endif int __init cf_init(void) { -#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE) - if (MACH_SE) +#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_HS7729PCI) + if (MACH_SE || MACH_HS7729PCI) { return cf_init_se(); + } #endif return cf_init_default(); } diff -urN linux-2.4.21/arch/sh/kernel/dma.c linux-2.4.22/arch/sh/kernel/dma.c --- linux-2.4.21/arch/sh/kernel/dma.c 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -137,6 +138,25 @@ return 0; } +static void __exit exit_dma(void) +{ +#ifdef CONFIG_CPU_SH4 + free_irq(DMAE_IRQ); +#endif +} + module_init(init_dma); +module_exit(exit_dma); + +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(setup_dma); +EXPORT_SYMBOL(claim_dma_lock); +EXPORT_SYMBOL(release_dma_lock); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(get_dma_residue); -/**/ diff -urN linux-2.4.21/arch/sh/kernel/entry.S linux-2.4.22/arch/sh/kernel/entry.S --- linux-2.4.21/arch/sh/kernel/entry.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,9 +1,11 @@ -/* $Id: entry.S,v 1.71 2001/07/27 11:47:50 gniibe Exp $ +/* $Id: entry.S,v 1.1.1.1.2.16 2003/07/16 18:41:20 yoshii Exp $ * * linux/arch/sh/entry.S * * Copyright (C) 1999, 2000 Niibe Yutaka * + * Modified to support SH7300. Takashi Kusuda (Jun 2003). + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -15,12 +17,6 @@ #include -/* - * Define this to turn on compatibility with the previous - * system call ABI. This feature is not properly maintained. - */ -#undef COMPAT_OLD_SYSCALL_ABI - ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address ! to be jumped is too far, but it causes illegal slot exception. @@ -38,6 +34,12 @@ * * jmp @k0 ! control-transfer instruction * ldc k1, ssr ! delay slot + */ + +/* + * ABI at ret_from_syscall: + * r8: from_syscall (0 or 1) indicating it's from syscall or not + * r9: original r0 (to restart system call) * * Stack layout in 'ret_from_syscall': * ptrace needs to have all regs on the stack. @@ -53,8 +55,7 @@ * gbr * mach * macl - * syscall # - * + * dummy */ /* @@ -66,7 +67,6 @@ tsk_ptrace = 24 PT_TRACESYS = 0x00000002 -PF_USEDFPU = 0x00100000 ENOSYS = 38 EINVAL = 22 @@ -74,7 +74,8 @@ #if defined(__sh3__) TRA = 0xffffffd0 EXPEVT = 0xffffffd4 -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000) #else INTEVT = 0xffffffd8 @@ -87,6 +88,10 @@ MMU_TEA = 0xff00000c ! TLB Exception Address Register #endif +#if defined(CONFIG_KGDB_NMI) +NMI_VEC = 0x1c0 ! Must catch early for debounce +#endif + /* Offsets to the stack */ OFF_R0 = 0 /* Return value. New ABI also arg4 */ OFF_R1 = 4 /* New ABI: arg5 */ @@ -97,9 +102,8 @@ OFF_R6 = 24 /* New ABI: arg2 */ OFF_R7 = 28 /* New ABI: arg3 */ OFF_SP = (15*4) +OFF_PC = (16*4) OFF_SR = (16*4+8) -SYSCALL_NR = (16*4+6*4) - #define k0 r0 #define k1 r1 @@ -220,10 +224,36 @@ 1: .long MMU_TEA 2: .long SYMBOL_NAME(do_address_error) -#if defined(CONFIG_SH_STANDARD_BIOS) + +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) +! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present. +! If both are configured, handle the debug traps (breakpoints) in SW, +! but still allow BIOS traps to FW. + .align 2 - /* Unwind the stack and jmp to the debug entry */ debug_kernel: +#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB) + /* Force BIOS call to FW (debug_trap put TRA in r8) */ + mov r8,r0 + shlr2 r0 + cmp/eq #0x3f,r0 + bt debug_kernel_fw +#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */ + +debug_enter: +#if defined(CONFIG_SH_KGDB) + /* Jump to kgdb, pass stacked regs as arg */ +debug_kernel_sw: + mov.l 3f, r0 + jmp @r0 + mov r15, r4 + .align 2 +3: .long SYMBOL_NAME(kgdb_handle_exception) +#endif /* CONFIG_SH_KGDB */ + +#if defined(CONFIG_SH_STANDARD_BIOS) + /* Unwind the stack and jmp to the debug entry */ +debug_kernel_fw: mov.l @r15+, r0 mov.l @r15+, r1 mov.l @r15+, r2 @@ -259,11 +289,14 @@ .align 2 1: .long 0x300000f0 2: .long SYMBOL_NAME(gdb_vbr_vector) -#endif +#endif /* CONFIG_SH_STANDARD_BIOS */ + +#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ + .align 2 debug_trap: -#if defined(CONFIG_SH_STANDARD_BIOS) +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) mov #OFF_SR, r0 mov.l @(r0,r15), r0 ! get status register shll r0 @@ -304,7 +337,8 @@ mov.l @(tsk_ptrace,r0), r0 ! Is current PTRACE_SYSCALL'd? mov #PT_TRACESYS, r1 tst r1, r0 - bt ret_from_syscall + bt/s syscall_ret + mov #0, r0 bra syscall_ret_trace nop @@ -346,29 +380,11 @@ mov.l @r9, r8 ! ! Is the trap argument >= 0x20? (TRA will be >= 0x80) - mov #0x20, r9 - extu.b r9, r9 - shll2 r9 - cmp/hs r9, r8 + mov #0x7f, r9 + cmp/hi r9, r8 bt debug_trap ! - mov #SYSCALL_NR, r14 - add r15, r14 - ! -#ifdef COMPAT_OLD_SYSCALL_ABI - mov #0x40, r9 - cmp/hs r9, r8 - bf/s old_abi_system_call - nop -#endif ! New Syscall ABI - add #-0x40, r8 - shlr2 r8 - shll8 r8 - shll8 r8 ! r8 = num_args<<16 - mov r3, r10 - or r8, r10 ! Encode syscall # and # of arguments - mov.l r10, @r14 ! set syscall_nr STI() ! stc k_current, r11 @@ -416,6 +432,10 @@ mov.l __sct, r11 add r11, r9 mov.l @r9, r11 + ! Prepare args for do_signal on syscall return + mov #1, r8 ! indicate it's syscall return + mov.l @(OFF_R0,r15), r9 ! save original r0 (syscall arg4) + ! jmp @r11 ! jump to specific syscall handler nop @@ -427,74 +447,6 @@ jmp @r1 ! Call syscall_trace() which notifies superior lds r0, pr ! Then return to ret_from_syscall() - - -#ifdef COMPAT_OLD_SYSCALL_ABI -! Handle old ABI system call. -! Note that ptrace(SYSCALL) is not supported for the old ABI. -! At this point: -! r0, r4-7 as per ABI -! r8 = value of TRA register (= num_args<<2) -! r14 = points to SYSCALL_NR in stack frame -old_abi_system_call: - mov r0, r9 ! Save system call number in r9 - ! ! arrange for return which pops stack - mov.l __old_abi_syscall_ret, r10 - lds r10, pr - ! Build the stack frame if TRA > 0 - mov r8, r10 - cmp/pl r10 - bf 0f - mov.l @(OFF_SP,r15), r0 ! get original user stack -7: add #-4, r10 -4: mov.l @(r0,r10), r1 ! May cause address error exception.. - mov.l r1, @-r15 - cmp/pl r10 - bt 7b -0: - mov.l r9, @r14 ! set syscall_nr - STI() - ! Call the system call handler through the table. - ! First check for bad syscall number - mov.l __n_sys, r10 - cmp/hs r10, r9 - bf 2f - ! Bad syscall number - rts ! return to old_abi_syscall_ret - mov #-ENOSYS, r0 - ! Good syscall number -2: shll2 r9 ! x4 - mov.l __sct, r11 - add r11, r9 - mov.l @r9, r11 - jmp @r11 ! call specific syscall handler, - nop - - .align 2 -__old_abi_syscall_ret: - .long old_abi_syscall_ret - - ! This code gets called on address error exception when copying - ! syscall arguments from user stack to kernel stack. It is - ! supposed to return -EINVAL through old_abi_syscall_ret, but it - ! appears to have been broken for a long time in that the r0 - ! return value will be saved into the kernel stack relative to r15 - ! but the value of r15 is not correct partway through the loop. - ! So the user prog is returned its old r0 value, not -EINVAL. - ! Greg Banks 28 Aug 2000. - .section .fixup,"ax" -fixup_syscall_argerr: - ! First get r15 back to - rts - mov #-EINVAL, r0 - .previous - - .section __ex_table, "a" - .align 2 - .long 4b,fixup_syscall_argerr - .previous -#endif - .align 2 __TRA: .long TRA __syscall_trace: @@ -511,12 +463,28 @@ .align 2 reschedule: + ! gUSA handling + mov.l @(OFF_SP,r15), r0 ! get user space stack pointer + mov r0, r1 + shll r0 + bf/s 1f + shll r0 + bf/s 1f + mov #OFF_PC, r0 + ! SP >= 0xc0000000 : gUSA mark + mov.l @(r0,r15), r2 ! get user space PC (program counter) + mov.l @(OFF_R0,r15), r3 ! end point + cmp/hs r3, r2 ! r2 >= r3? + bt 1f + add r3, r1 ! rewind point #2 + mov.l r1, @(r0,r15) ! reset PC to rewind point #2 + ! +1: mov.l 2f, r1 mova SYMBOL_NAME(ret_from_syscall), r0 - mov.l 1f, r1 jmp @r1 lds r0, pr .align 2 -1: .long SYMBOL_NAME(schedule) +2: .long SYMBOL_NAME(schedule) ret_from_irq: ret_from_exception: @@ -527,14 +495,9 @@ bt restore_all ! Yes, it's from kernel, go back soon ! bra ret_from_syscall - nop + mov #0, r8 ! indicate it's *not* syscall return .align 2 -#ifdef COMPAT_OLD_SYSCALL_ABI -old_abi_syscall_ret: - add r8, r15 ! pop off the arguments - /* fall through */ -#endif syscall_ret: mov.l r0, @(OFF_R0,r15) ! save the return value /* fall through */ @@ -553,9 +516,11 @@ tst r0, r0 bt restore_all signal_return: + mov.l __do_signal, r1 mov r15, r4 mov #0, r5 - mov.l __do_signal, r1 + mov r8, r6 + mov r9, r7 mova restore_all, r0 jmp @r1 lds r0, pr @@ -567,12 +532,6 @@ .align 2 restore_all: -#if defined(__SH4__) - mov.l __fpu_prepare_fd, r0 - jsr @r0 - stc sr, r4 -#endif - ! mov.l @r15+, r0 mov.l @r15+, r1 mov.l @r15+, r2 @@ -585,7 +544,7 @@ stc sr, r8 mov.l __blrb_flags, r9 ! BL =1, RB=1 or r9, r8 - ldc r8, sr ! here, change the register bank + ldc r8, sr ! here, change the register bank ! mov.l @r15+, r8 mov.l @r15+, r9 @@ -594,25 +553,26 @@ mov.l @r15+, r12 mov.l @r15+, r13 mov.l @r15+, r14 - mov.l @r15+, k4 ! original stack pointer + mov.l @r15+, k4 ! original stack pointer ldc.l @r15+, spc lds.l @r15+, pr - mov.l @r15+, k3 ! original SR + mov.l @r15+, k3 ! original SR ldc.l @r15+, gbr lds.l @r15+, mach lds.l @r15+, macl - add #4, r15 ! Skip syscall number + add #4, r15 ! skip placeholder + ! ! ! Calculate new SR value - mov k3, k2 ! original SR value + mov k3, k2 ! original SR value mov.l 1f, k1 stc sr, k0 - and k1, k0 ! Get current FD-bit + and k1, k0 ! Get current FD-bit mov.l 2f, k1 - and k1, k2 ! Mask orignal SR value - or k0, k2 ! Inherit current FD-bit + and k1, k2 ! Mask orignal SR value + or k0, k2 ! Inherit current FD-bit ! - mov k3, k0 ! Calculate IMASK-bits + mov k3, k0 ! Calculate IMASK-bits shlr2 k0 and #0x3c, k0 cmp/eq #0x3c, k0 @@ -620,54 +580,14 @@ shll2 k0 mov g_imask, k0 ! -7: or k0, k2 ! Set the IMASK-bits +7: or k0, k2 ! Set the IMASK-bits ldc k2, ssr ! -#if defined(__SH4__) - shll k2 - shll k2 - bf 9f ! user mode - /* Kernel to kernel transition */ - mov.l 1f, k1 - tst k1, k3 - bf 9f ! it hadn't FPU - ! Kernel to kernel and FPU was used - ! There's the case we don't get FPU now - stc sr, k2 - tst k1, k2 - bt 8f - ! We need to grab FPU here - xor k1, k2 - ldc k2, sr ! Grab FPU - mov.l __init_task_flags, k1 - mov.l @k1, k2 - mov.l __PF_USEDFPU, k0 - or k0, k2 - mov.l k2, @k1 ! Set init_task.flags |= PF_USEDFPU - ! - ! Restoring FPU... - ! -8: mov.l 3f, k1 - lds k1, fpscr - fmov.s @r15+, fr0 - fmov.s @r15+, fr1 - fmov.s @r15+, fr2 - fmov.s @r15+, fr3 - fmov.s @r15+, fr4 - fmov.s @r15+, fr5 - fmov.s @r15+, fr6 - fmov.s @r15+, fr7 - fmov.s @r15+, fr8 - fmov.s @r15+, fr9 - fmov.s @r15+, fr10 - fmov.s @r15+, fr11 - fmov.s @r15+, fr12 - fmov.s @r15+, fr13 - fmov.s @r15+, fr14 - fmov.s @r15+, fr15 - lds.l @r15+, fpscr - lds.l @r15+, fpul -9: +#if defined(CONFIG_KGDB_NMI) + ! Clear in_nmi + mov.l 4f, k0 + mov #0, k1 + mov.b k1, @k0 #endif mov k4, r15 rte @@ -675,17 +595,13 @@ .align 2 __blrb_flags: .long 0x30000000 -#if defined(__SH4__) -__fpu_prepare_fd: - .long SYMBOL_NAME(fpu_prepare_fd) -__init_task_flags: - .long SYMBOL_NAME(init_task_union)+4 -__PF_USEDFPU: - .long PF_USEDFPU -#endif 1: .long 0x00008000 ! FD 2: .long 0xffff7f0f ! ~(IMASK+FD) 3: .long 0x00080000 ! SZ=0, PR=1 +#if defined(CONFIG_KGDB_NMI) +4: .long SYMBOL_NAME(in_nmi) +#endif + ! Exception Vector Base ! @@ -717,6 +633,22 @@ interrupt: mov.l 2f, k2 mov.l 3f, k3 +#if defined(CONFIG_KGDB_NMI) + ! Debounce (filter nested NMI) + mov.l @k2, k0 + mov.l 5f, k1 + cmp/eq k1, k0 + bf 0f + mov.l 6f, k1 + tas.b @k1 + bt 0f + rte + nop + .align 2 +5: .long NMI_VEC +6: .long SYMBOL_NAME(in_nmi) +0: +#endif /* defined(CONFIG_KGDB_NMI) */ bra handle_exception mov.l @k2, k2 @@ -732,61 +664,21 @@ ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), ! save all registers onto stack. ! - stc ssr, k0 ! from kernel space? - shll k0 ! Check MD bit (bit30) by shifting it into the T bit - shll k0 -#if defined(__SH4__) - bf/s 8f ! it's from user to kernel transition - mov r15, k0 ! save original stack to k0 - /* It's a kernel to kernel transition. */ - /* Is the FPU disabled? */ - mov.l 2f, k1 - stc ssr, k0 - tst k1, k0 - mov.l 4f, k1 - bf/s 9f ! FPU is not enabled, no need to save it - mov r15, k0 ! save original stack to k0 - ! FPU is enabled, save it - ! /* XXX: Need to save another bank of FPU if all FPU feature is used */ - ! /* Currently it's not the case for GCC (only udivsi3_i4, divsi3_i4) */ - sts.l fpul, @-r15 - sts.l fpscr, @-r15 - mov.l 6f, k1 - lds k1, fpscr - mov.l 3f, k1 - fmov.s fr15, @-r15 - fmov.s fr14, @-r15 - fmov.s fr13, @-r15 - fmov.s fr12, @-r15 - fmov.s fr11, @-r15 - fmov.s fr10, @-r15 - fmov.s fr9, @-r15 - fmov.s fr8, @-r15 - fmov.s fr7, @-r15 - fmov.s fr6, @-r15 - fmov.s fr5, @-r15 - fmov.s fr4, @-r15 - fmov.s fr3, @-r15 - fmov.s fr2, @-r15 - fmov.s fr1, @-r15 - bra 9f - fmov.s fr0, @-r15 -#else - mov.l 3f, k1 - bt/s 9f ! it's a kernel to kernel transition, and skip the FPU save. - mov r15, k0 ! save original stack to k0 anyway -#endif -8: /* User space to kernel */ + stc ssr, k0 ! Is it from kernel space? + shll k0 ! Check MD bit (bit30) by shifting it into... + shll k0 ! ...the T bit + bt/s 9f ! It's a kernel to kernel transition. + mov r15, k0 ! save original stack to k0 + /* User space to kernel */ mov #0x20, k1 - shll8 k1 ! k1 <= 8192 == THREAD_SIZE + shll8 k1 ! k1 <= 8192 == THREAD_SIZE add current, k1 mov k1, r15 ! change to kernel stack ! - mov.l 4f, k1 ! let kernel release FPU -9: ! Save the user registers on the stack. - ! At this point, k1 should have been set to the new SR value - mov #-1, k4 - mov.l k4, @-r15 ! syscall_nr (default: -1) +9: mov.l 3f, k1 + ! + ! Save the user registers on the stack. + add #-4, r15 ! placeholder ! sts.l macl, @-r15 sts.l mach, @-r15 @@ -806,11 +698,11 @@ mov.l r9, @-r15 mov.l r8, @-r15 ! - stc sr, r8 ! Back to normal register bank, and - or k1, r8 ! Block all interrupts, may release FPU + stc sr, r8 ! Back to normal register bank, and + or k1, r8 ! Block all interrupts mov.l 5f, k1 - and k1, r8 ! ... - ldc r8, sr ! ...changed here. + and k1, r8 ! ... + ldc r8, sr ! ...changed here. ! mov.l r7, @-r15 mov.l r6, @-r15 @@ -831,9 +723,7 @@ nop .align 2 1: .long SYMBOL_NAME(exception_handling_table) -2: .long 0x00008000 ! FD=1 3: .long 0x000000f0 ! FD=0, IMASK=15 -4: .long 0x000080f0 ! FD=1, IMASK=15 5: .long 0xcfffffff ! RB=0, BL=0 6: .long 0x00080000 ! SZ=0, PR=1 @@ -862,7 +752,11 @@ .long error ! reserved_instruction (filled by trap_init) .long error ! illegal_slot_instruction (filled by trap_init) ENTRY(nmi_slot) +#if defined (CONFIG_KGDB_NMI) + .long debug_enter ! Allow trap to debugger +#else .long none ! Not implemented yet +#endif ENTRY(user_break_point_trap) .long break_point_trap ENTRY(interrupt_table) @@ -900,7 +794,8 @@ .long SYMBOL_NAME(do_IRQ) ! rovi .long SYMBOL_NAME(do_IRQ) .long SYMBOL_NAME(do_IRQ) -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) .long SYMBOL_NAME(do_IRQ) ! 32 IRQ irq0 .long SYMBOL_NAME(do_IRQ) ! 33 irq1 .long SYMBOL_NAME(do_IRQ) ! 34 irq2 @@ -930,10 +825,57 @@ .long SYMBOL_NAME(do_IRQ) ! 58 bri2 .long SYMBOL_NAME(do_IRQ) ! 59 txi2 .long SYMBOL_NAME(do_IRQ) ! 60 ADC adi -#if defined(CONFIG_CPU_SUBTYPE_SH7707) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) .long SYMBOL_NAME(do_IRQ) ! 61 LCDC lcdi .long SYMBOL_NAME(do_IRQ) ! 62 PCC pcc0i .long SYMBOL_NAME(do_IRQ) ! 63 pcc1i +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + .long SYMBOL_NAME(do_IRQ) ! 64 + .long SYMBOL_NAME(do_IRQ) ! 65 + .long SYMBOL_NAME(do_IRQ) ! 66 + .long SYMBOL_NAME(do_IRQ) ! 67 + .long SYMBOL_NAME(do_IRQ) ! 68 + .long SYMBOL_NAME(do_IRQ) ! 69 + .long SYMBOL_NAME(do_IRQ) ! 70 + .long SYMBOL_NAME(do_IRQ) ! 71 + .long SYMBOL_NAME(do_IRQ) ! 72 + .long SYMBOL_NAME(do_IRQ) ! 73 + .long SYMBOL_NAME(do_IRQ) ! 74 + .long SYMBOL_NAME(do_IRQ) ! 75 + .long SYMBOL_NAME(do_IRQ) ! 76 + .long SYMBOL_NAME(do_IRQ) ! 77 + .long SYMBOL_NAME(do_IRQ) ! 78 + .long SYMBOL_NAME(do_IRQ) ! 79 + .long SYMBOL_NAME(do_IRQ) ! 80 SCIF0(SH7300) + .long SYMBOL_NAME(do_IRQ) ! 81 + .long SYMBOL_NAME(do_IRQ) ! 82 + .long SYMBOL_NAME(do_IRQ) ! 83 + .long SYMBOL_NAME(do_IRQ) ! 84 + .long SYMBOL_NAME(do_IRQ) ! 85 + .long SYMBOL_NAME(do_IRQ) ! 86 + .long SYMBOL_NAME(do_IRQ) ! 87 + .long SYMBOL_NAME(do_IRQ) ! 88 + .long SYMBOL_NAME(do_IRQ) ! 89 + .long SYMBOL_NAME(do_IRQ) ! 90 + .long SYMBOL_NAME(do_IRQ) ! 91 + .long SYMBOL_NAME(do_IRQ) ! 92 + .long SYMBOL_NAME(do_IRQ) ! 93 + .long SYMBOL_NAME(do_IRQ) ! 94 + .long SYMBOL_NAME(do_IRQ) ! 95 + .long SYMBOL_NAME(do_IRQ) ! 96 + .long SYMBOL_NAME(do_IRQ) ! 97 + .long SYMBOL_NAME(do_IRQ) ! 98 + .long SYMBOL_NAME(do_IRQ) ! 99 + .long SYMBOL_NAME(do_IRQ) ! 100 + .long SYMBOL_NAME(do_IRQ) ! 101 + .long SYMBOL_NAME(do_IRQ) ! 102 + .long SYMBOL_NAME(do_IRQ) ! 103 + .long SYMBOL_NAME(do_IRQ) ! 104 + .long SYMBOL_NAME(do_IRQ) ! 105 + .long SYMBOL_NAME(do_IRQ) ! 106 + .long SYMBOL_NAME(do_IRQ) ! 107 + .long SYMBOL_NAME(do_IRQ) ! 108 +#endif #endif #elif defined(__SH4__) .long SYMBOL_NAME(do_IRQ) ! 32 Hitachi UDI @@ -978,7 +920,7 @@ .long SYMBOL_NAME(do_IRQ) ! pwon .long SYMBOL_NAME(do_IRQ) ! pwdwn .long SYMBOL_NAME(do_IRQ) ! err -#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) +#elif defined(CONFIG_CPU_SUBTYPE_ST40) .long error ! 50 0x840 .long error ! 51 0x860 .long error ! 52 0x880 @@ -1010,14 +952,14 @@ .long SYMBOL_NAME(do_IRQ) ! 78 0xbc0 DMA ERR .long error ! 79 0xbe0 .long SYMBOL_NAME(do_IRQ) ! 80 0xc00 PIO0 - .long SYMBOL_NAME(do_IRQ) ! 81 0xc20 PIO1 - .long SYMBOL_NAME(do_IRQ) ! 82 0xc40 PIO2 + .long error ! 81 0xc20 + .long error ! 82 0xc40 .long error ! 83 0xc60 - .long error ! 84 0xc80 + .long SYMBOL_NAME(do_IRQ) ! 84 0xc80 PIO1 .long error ! 85 0xca0 .long error ! 86 0xcc0 .long error ! 87 0xce0 - .long error ! 88 0xd00 + .long SYMBOL_NAME(do_IRQ) ! 88 0xd00 PIO2 .long error ! 89 0xd20 .long error ! 90 0xd40 .long error ! 91 0xd60 @@ -1041,6 +983,7 @@ .long error ! 109 0xfa0 .long error ! 110 0xfc0 .long error ! 111 0xfe0 +# if defined(CONFIG_CPU_SUBTYPE_ST40STB1) .long SYMBOL_NAME(do_IRQ) ! 112 0x1000 Mailbox .long error ! 113 0x1020 .long error ! 114 0x1040 @@ -1073,6 +1016,74 @@ .long error ! 141 0x13a0 .long error ! 142 0x13c0 .long error ! 143 0x13e0 +# elif defined(CONFIG_CPU_SUBTYPE_ST40GX1) + .long SYMBOL_NAME(do_IRQ) ! 112 0x1000 Mailbox + .long error ! 113 0x1020 + .long error ! 114 0x1040 + .long error ! 115 0x1060 + .long SYMBOL_NAME(do_IRQ) ! 116 0x1080 SSC0 + .long error ! 117 0x10a0 + .long error ! 118 0x10c0 + .long error ! 119 0x10e0 + .long SYMBOL_NAME(do_IRQ) ! 120 0x1100 IRBlaster IRB + .long error ! 121 0x1120 + .long error ! 122 0x1140 + .long error ! 123 0x1160 + .long SYMBOL_NAME(do_IRQ) ! 124 0x1180 USB host + .long error ! 125 0x11a0 + .long error ! 126 0x11c0 + .long error ! 127 0x11e0 + .long SYMBOL_NAME(do_IRQ) ! 128 0x1200 Video Processor BLITER + .long error ! 129 0x1220 + .long error ! 130 0x1240 + .long error ! 131 0x1260 + .long SYMBOL_NAME(do_IRQ) ! 132 0x1280 UART0 UART0 + .long error ! 133 0x12a0 + .long SYMBOL_NAME(do_IRQ) ! 134 0x12c0 UART2 + .long error ! 135 0x12e0 + .long SYMBOL_NAME(do_IRQ) ! 136 0x1300 Additional PIO IO_PIO0 + .long error ! 137 0x1320 + .long error ! 138 0x1340 + .long error ! 139 0x1360 + .long SYMBOL_NAME(do_IRQ) ! 140 0x1380 EMPI INV_ADDR + .long error ! 141 0x13a0 + .long error ! 142 0x13c0 + .long error ! 143 0x13e0 + .long SYMBOL_NAME(do_IRQ) ! 144 0x1400 MAFE + .long error ! 145 0x1420 + .long error ! 146 0x1440 + .long error ! 147 0x1460 + .long SYMBOL_NAME(do_IRQ) ! 148 0x1480 PWM + .long error ! 149 0x14a0 + .long error ! 150 0x14c0 + .long error ! 151 0x14e0 + .long SYMBOL_NAME(do_IRQ) ! 152 0x1500 SSC1 + .long error ! 153 0x1520 + .long error ! 154 0x1540 + .long error ! 155 0x1560 + .long SYMBOL_NAME(do_IRQ) ! 156 0x1580 Additional PIO IO_PIO1 + .long error ! 157 0x15a0 + .long error ! 158 0x15c0 + .long error ! 159 0x15e0 + .long SYMBOL_NAME(do_IRQ) ! 160 0x1600 USB target + .long error ! 161 0x1620 + .long error ! 162 0x1640 + .long error ! 163 0x1660 + .long SYMBOL_NAME(do_IRQ) ! 164 0x1680 UART1 UART1 + .long error ! 165 0x16a0 + .long error ! 166 0x16c0 + .long error ! 167 0x16e0 + .long SYMBOL_NAME(do_IRQ) ! 168 0x1700 Teletext TTXT + .long error ! 169 0x1720 + .long error ! 170 0x1740 + .long error ! 171 0x1760 + .long SYMBOL_NAME(do_IRQ) ! 172 0x1780 Video Sync VTG + .long SYMBOL_NAME(do_IRQ) ! 173 0x17a0 DVP0 + .long SYMBOL_NAME(do_IRQ) ! 174 0x17c0 DVP1 + .long error ! 175 0x17e0 +# else +# error Unknown ST40 type +# endif #endif ENTRY(sys_call_table) @@ -1185,7 +1196,7 @@ .long SYMBOL_NAME(sys_newstat) .long SYMBOL_NAME(sys_newlstat) .long SYMBOL_NAME(sys_newfstat) - .long SYMBOL_NAME(sys_uname) + .long SYMBOL_NAME(sys_ni_syscall) /* old uname */ .long SYMBOL_NAME(sys_ni_syscall) /* 110 */ /* iopl */ .long SYMBOL_NAME(sys_vhangup) .long SYMBOL_NAME(sys_ni_syscall) /* idle */ @@ -1199,7 +1210,7 @@ .long SYMBOL_NAME(sys_clone) /* 120 */ .long SYMBOL_NAME(sys_setdomainname) .long SYMBOL_NAME(sys_newuname) - .long SYMBOL_NAME(sys_ni_syscall) /* sys_modify_ldt */ + .long SYMBOL_NAME(sys_cacheflush) /* sys_modify_ldt for i386 */ .long SYMBOL_NAME(sys_adjtimex) .long SYMBOL_NAME(sys_mprotect) /* 125 */ .long SYMBOL_NAME(sys_sigprocmask) @@ -1256,8 +1267,8 @@ .long SYMBOL_NAME(sys_rt_sigtimedwait) .long SYMBOL_NAME(sys_rt_sigqueueinfo) .long SYMBOL_NAME(sys_rt_sigsuspend) - .long SYMBOL_NAME(sys_pread) /* 180 */ - .long SYMBOL_NAME(sys_pwrite) + .long SYMBOL_NAME(sys_pread_wrapper) /* 180 */ + .long SYMBOL_NAME(sys_pwrite_wrapper) .long SYMBOL_NAME(sys_chown16) .long SYMBOL_NAME(sys_getcwd) .long SYMBOL_NAME(sys_capget) @@ -1299,15 +1310,16 @@ .long SYMBOL_NAME(sys_getdents64) /* 220 */ .long SYMBOL_NAME(sys_fcntl64) .long SYMBOL_NAME(sys_gettid) - .long SYMBOL_NAME(sys_tkill) - + .long SYMBOL_NAME(sys_tkill) + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_readahead) /* 225 */ /* * NOTE!! This doesn't have to be exact - we just have * to make sure we have _enough_ of the "sys_ni_syscall" * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-221 + .rept NR_syscalls-(.-sys_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -urN linux-2.4.21/arch/sh/kernel/fpu.c linux-2.4.22/arch/sh/kernel/fpu.c --- linux-2.4.21/arch/sh/kernel/fpu.c 2001-01-28 18:56:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/fpu.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: fpu.c,v 1.29 2000/03/22 13:42:10 gniibe Exp $ +/* $Id: fpu.c,v 1.1.1.1.2.1 2002/01/25 00:51:42 gniibe Exp $ * * linux/arch/sh/kernel/fpu.c * @@ -18,6 +18,10 @@ #include #include +/* + * Save FPU registers onto task structure. + * Assume called with FPU enabled (SR.FD=0). + */ void save_fpu(struct task_struct *tsk) { @@ -118,7 +122,8 @@ * double precission represents signaling NANS. */ -void fpu_init(void) +static void +fpu_init(void) { asm volatile("lds %0, fpul\n\t" "lds %1, fpscr\n\t" @@ -160,15 +165,125 @@ : "r" (0), "r" (FPSCR_INIT)); } +/** + * denormal_to_double - Given denormalized float number, + * store double float + * + * @fpu: Pointer to sh_fpu_hard structure + * @n: Index to FP register + */ +static void +denormal_to_double (struct sh_fpu_hard_struct *fpu, int n) +{ + unsigned long du, dl; + unsigned long x = fpu->fpul; + int exp = 1023 - 126; + + if (x != 0 && (x & 0x7f800000) == 0) { + du = (x & 0x80000000); + while ((x & 0x00800000) == 0) { + x <<= 1; + exp--; + } + x &= 0x007fffff; + du |= (exp << 20) | (x >> 3); + dl = x << 29; + + fpu->fp_regs[n] = du; + fpu->fp_regs[n+1] = dl; + } +} + +/** + * ieee_fpe_handler - Handle denormalized number exception + * + * @regs: Pointer to register structure + * + * Returns 1 when it's handled (should not cause exception). + */ +static int +ieee_fpe_handler (struct pt_regs *regs) +{ + unsigned short insn = *(unsigned short *) regs->pc; + unsigned short finsn; + unsigned long nextpc; + int nib[4] = { + (insn >> 12) & 0xf, + (insn >> 8) & 0xf, + (insn >> 4) & 0xf, + insn & 0xf}; + + if (nib[0] == 0xb || + (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */ + regs->pr = regs->pc + 4; + + if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */ + nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3); + finsn = *(unsigned short *) (regs->pc + 2); + } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */ + if (regs->sr & 1) + nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); + else + nextpc = regs->pc + 4; + finsn = *(unsigned short *) (regs->pc + 2); + } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */ + if (regs->sr & 1) + nextpc = regs->pc + 4; + else + nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); + finsn = *(unsigned short *) (regs->pc + 2); + } else if (nib[0] == 0x4 && nib[3] == 0xb && + (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */ + nextpc = regs->regs[nib[1]]; + finsn = *(unsigned short *) (regs->pc + 2); + } else if (nib[0] == 0x0 && nib[3] == 0x3 && + (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */ + nextpc = regs->pc + 4 + regs->regs[nib[1]]; + finsn = *(unsigned short *) (regs->pc + 2); + } else if (insn == 0x000b) { /* rts */ + nextpc = regs->pr; + finsn = *(unsigned short *) (regs->pc + 2); + } else { + nextpc = regs->pc + 2; + finsn = insn; + } + + if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ + struct task_struct *tsk = current; + + save_fpu(tsk); + if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) { + /* FPU error */ + denormal_to_double (&tsk->thread.fpu.hard, + (finsn >> 8) & 0xf); + tsk->thread.fpu.hard.fpscr &= + ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); + grab_fpu(); + restore_fpu(tsk); + tsk->flags |= PF_USEDFPU; + } else { + tsk->thread.trap_no = 11; + tsk->thread.error_code = 0; + force_sig(SIGFPE, tsk); + } + + regs->pc = nextpc; + return 1; + } + + return 0; +} + asmlinkage void do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { struct task_struct *tsk = current; - regs.pc += 2; + if (ieee_fpe_handler (®s)) + return; - grab_fpu(); + regs.pc += 2; save_fpu(tsk); tsk->thread.trap_no = 11; tsk->thread.error_code = 0; @@ -181,102 +296,12 @@ { struct task_struct *tsk = current; - if (!user_mode(®s)) { - if (tsk != &init_task) { - unlazy_fpu(tsk); - } - tsk = &init_task; - if (tsk->flags & PF_USEDFPU) { - /* - * This weird situation can be occurred. - * - * There's race condition in __cli: - * - * (1) SR --> register - * (2) Set IMASK of register - * (3) SR <-- register - * - * Between (1) and (2), or (2) and (3) getting - * interrupt, and interrupt handler (or - * softirq) may use FPU. - * - * Then, SR.FD is overwritten by (3). - * - * This results init_task.PF_USEDFPU is on, - * with SR.FD == 1. - * - */ - release_fpu(); - return; - } - } - grab_fpu(); - if (tsk->used_math) { - /* Using the FPU again. */ - restore_fpu(tsk); - } else { - /* First time FPU user. */ - fpu_init(); - tsk->used_math = 1; - } - tsk->flags |= PF_USEDFPU; - release_fpu(); -} - -/* - * Change current FD flag to set FD flag back to exception - */ -asmlinkage void -fpu_prepare_fd(unsigned long sr, unsigned long r5, unsigned long r6, - unsigned long r7, struct pt_regs regs) -{ - __cli(); if (!user_mode(®s)) { - if (init_task.flags & PF_USEDFPU) - grab_fpu(); - else { - if (!(sr & SR_FD)) { - BUG(); - release_fpu(); - } - } + printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); return; } - if (sr & SR_FD) { /* Kernel doesn't grab FPU */ - if (current->flags & PF_USEDFPU) - grab_fpu(); - else { - if (init_task.flags & PF_USEDFPU) { - /* - * This weird situation can be occurred. - * See the comment in do_fpu_state_restore. - */ - grab_fpu(); - save_fpu(&init_task); - } - } - } else { - if (init_task.flags & PF_USEDFPU) - save_fpu(&init_task); - else { - BUG(); - release_fpu(); - } - } -} - -/* Short cut for the FPU exception */ -asmlinkage void -enable_fpu_in_danger(void) -{ - struct task_struct *tsk = current; - - if (tsk != &init_task) - unlazy_fpu(tsk); - - tsk = &init_task; if (tsk->used_math) { /* Using the FPU again. */ restore_fpu(tsk); diff -urN linux-2.4.21/arch/sh/kernel/head.S linux-2.4.22/arch/sh/kernel/head.S --- linux-2.4.21/arch/sh/kernel/head.S 2001-01-28 18:56:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.17 2000/03/06 12:44:24 gniibe Exp $ +/* $Id: head.S,v 1.1.1.1.2.1 2002/01/25 00:51:42 gniibe Exp $ * * arch/sh/kernel/head.S * @@ -50,12 +50,6 @@ sub r1, r0 ! ldc r0, r7_bank ! ... and init_task ! -#if defined(__SH4__) - ! Initialize fpu - mov.l 7f, r0 - jsr @r0 - nop -#endif ! Enable cache mov.l 6f, r0 jsr @r0 @@ -74,12 +68,9 @@ nop .balign 4 -1: .long 0x400000F0 ! MD=1, RB=0, BL=0, FD=0, IMASK=0xF +1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF 2: .long SYMBOL_NAME(stack) 3: .long SYMBOL_NAME(__bss_start) 4: .long SYMBOL_NAME(_end) 5: .long SYMBOL_NAME(start_kernel) 6: .long SYMBOL_NAME(cache_init) -#if defined(__SH4__) -7: .long SYMBOL_NAME(fpu_init) -#endif diff -urN linux-2.4.21/arch/sh/kernel/io_hs7729pci.c linux-2.4.22/arch/sh/kernel/io_hs7729pci.c --- linux-2.4.21/arch/sh/kernel/io_hs7729pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/io_hs7729pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,338 @@ +/* $Id: io_hs7729pci.c,v 1.1.2.1 2003/06/24 08:45:47 dwmw2 Exp $ + * + * linux/arch/sh/kernel/io_hs7729pci.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * I/O routine for Hitachi Semiconductor and Devices HS7729PCI. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pci-sd0001.h" + +#ifdef CONFIG_PCI +#define io_is_pci(port) (port >= PCIBIOS_MIN_IO) +#else +#define io_is_pci(port) (0) +#endif + +/* SH pcmcia io window base, start and end. */ +int sh_pcic_io_wbase = 0xb8400000; +int sh_pcic_io_start; +int sh_pcic_io_stop; +int sh_pcic_io_type; +int sh_pcic_io_dummy; + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +/* MS7750 requires special versions of in*, out* routines, since + PC-like io ports are located at upper half byte of 16-bit word which + can be accessed only with 16-bit wide. */ + +static inline volatile __u16 * +port2adr(unsigned long port) +{ + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); + else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1)); + + else + return (volatile __u16 *) (PA_SUPERIO + (port << 1)); +} + +static inline int +shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6 || + (0x170 <= port && port < 0x178) || port == 0x376 || + port >= 0x1000) + return 0; + else + return 1; +} + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + + +unsigned char hs7729pci_inb(unsigned long port) +{ + if (io_is_pci(port)) + return sd0001_inb(port); + if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); + if (shifted_port(port)) + return (*port2adr(port) >> 8); +#if defined(CONFIG_CF_ENABLER) + else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return *(__u8 *)(PA_MRSHPC_IO + port + 0x40000); +#endif + else + return (*port2adr(port))&0xff; +} + +unsigned char hs7729pci_inb_p(unsigned long port) +{ + unsigned long v; + + if (io_is_pci(port)) + v = sd0001_inb(port); + else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); + else if (shifted_port(port)) + v = (*port2adr(port) >> 8); +#if defined(CONFIG_CF_ENABLER) + else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + v = *(__u8 *)(PA_MRSHPC_IO + port + 0x40000); +#endif + else + v = (*port2adr(port))&0xff; + delay(); + return v; +} + +unsigned short hs7729pci_inw(unsigned long port) +{ + if (io_is_pci(port)) + return sd0001_inw(port); + if (port >= 0x2000 || + (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) + return *port2adr(port); + + maybebadio(inw, port); +} + +unsigned int hs7729pci_inl(unsigned long port) +{ + if (io_is_pci(port)) + return sd0001_inl(port); + else + maybebadio(inl, port); +} + +void hs7729pci_outb(unsigned char value, unsigned long port) +{ + if (io_is_pci(port)) + sd0001_outb(value, port); + else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + *(__u8 *)(sh_pcic_io_wbase + port) = value; + else if (shifted_port(port)) + *(port2adr(port)) = value << 8; +#if defined(CONFIG_CF_ENABLER) + else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + *(__u8 *)(PA_MRSHPC_IO + port + 0x40000) = value; +#endif + else + *(port2adr(port)) = value; +} + +void hs7729pci_outb_p(unsigned char value, unsigned long port) +{ + if (io_is_pci(port)) + sd0001_outb(value, port); + else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + *(__u8 *)(sh_pcic_io_wbase + port) = value; + else if (shifted_port(port)) + *(port2adr(port)) = value << 8; +#if defined(CONFIG_CF_ENABLER) + else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + *(__u8 *)(PA_MRSHPC_IO + port + 0x40000) = value; +#endif + else + *(port2adr(port)) = value; + delay(); +} + +void hs7729pci_outw(unsigned short value, unsigned long port) +{ + if (io_is_pci(port)) + sd0001_outw(value, port); + else if (port >= 0x2000 || + (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) + *port2adr(port) = value; + else + maybebadio(outw, port); +} + +void hs7729pci_outl(unsigned int value, unsigned long port) +{ + if (io_is_pci(port)) + sd0001_outl(value, port); + else + maybebadio(outl, port); +} + +void hs7729pci_insb(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + + if (io_is_pci(port)) + sd0001_insb(port, addr, count); + else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) { + volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port); + while (count--) + *((__u8 *) addr)++ = *bp; + } else if (shifted_port(port)) { + while (count--) + *((__u8 *) addr)++ = *p >> 8; +#if defined(CONFIG_CF_ENABLER) + } else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) { + volatile __u8 *q = (__u8 *)(PA_MRSHPC_IO + port + 0x40000); + while (count--) { + *((__u8 *) addr)++ = *q; + } +#endif + } else { + while (count--) + *((__u8 *) addr)++ = *p; + + } +} + +void hs7729pci_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (io_is_pci(port)) + return sd0001_insw(port, addr, count); +#if defined(CONFIG_CF_ENABLER) + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) { + p = (__u16 *)(PA_MRSHPC_IO + port); + } else +#endif + p = port2adr(port); + while (count--) + *((__u16 *) addr)++ = *p; +} + +void hs7729pci_insl(unsigned long port, void *addr, unsigned long count) +{ + if (io_is_pci(port)) + sd0001_insl(port, addr, count); + else + maybebadio(insl, port); +} + +void hs7729pci_outsb(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + + if (io_is_pci(port)) { + sd0001_outsb(port, addr, count); + return; + } + if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) { + volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port); + while (count--) + *bp = *((__u8 *) addr)++; + } else if (shifted_port(port)) { + while (count--) + *p = *((__u8 *) addr)++ << 8; +#if defined(CONFIG_CF_ENABLER) + } else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) { + volatile __u8 *q = (__u8 *)(PA_MRSHPC_IO + port + 0x40000); + while (count--) { + *q = *((__u8 *) addr)++; + } +#endif + } else while (count--) + *p = *((__u8 *) addr)++; +} + +void hs7729pci_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (io_is_pci(port)) { + sd0001_outsw(port, addr, count); + return; + } +#if defined(CONFIG_CF_ENABLER) + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) { + p = (__u16 *)(PA_MRSHPC_IO + port); + } else +#endif + p = port2adr(port); + while (count--) + *p = *((__u16 *) addr)++; +} + +void hs7729pci_outsl(unsigned long port, const void *addr, unsigned long count) +{ + if (io_is_pci(port)) + sd0001_outsl(port, addr, count); + else + maybebadio(outsl, port); +} + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + +static int +sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); +#if 0 + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); +#endif + return 0; +} + +unsigned long +hs7729pci_isa_port2addr(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; +} + +void *hs7729pci_ioremap(unsigned long phys_addr, unsigned long size) +{ + /* Don't allow wraparound or zero size */ + if (!size || (phys_addr + size - 1) < phys_addr) + return NULL; + +#ifdef CONFIG_PCI + if (phys_addr >= PCIBIOS_MIN_MEM && + phys_addr < (PCIBIOS_MIN_MEM&0xfc000000)+0x03000000) + return sd0001_ioremap(phys_addr, size); +#endif + return (void *) P2SEGADDR(phys_addr); +} + +void hs7729pci_iounmap(void *addr) +{ +#ifdef CONFIG_PCI + /* Ideally for cleanliness we'd have a better way of knowing + if it came from the PCI controller. */ + if ((unsigned long)addr >= VMALLOC_START && + (unsigned long)addr < VMALLOC_END) + sd0001_iounmap(addr); +#endif +} + diff -urN linux-2.4.21/arch/sh/kernel/io_keywest.c linux-2.4.22/arch/sh/kernel/io_keywest.c --- linux-2.4.21/arch/sh/kernel/io_keywest.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/io_keywest.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,330 @@ +/* + * linux/arch/sh/io_keywest.c + * + * IO functions for a Hitachi KeyWest Evaluation Board. + * + * Copyright (C) 2001 Lineo, Japan + * + * This file is subject to the terms and conditions of the GNU General Publi +c + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +//#define KEYWEST_DEBUG 3 +#undef KEYWEST_DEBUG + +#ifdef KEYWEST_DEBUG +#define DPRINTK(args...) printk(args) +#define DIPRINTK(n, args...) if (KEYWEST_DEBUG>(n)) printk(args) +#else +#define DPRINTK(args...) +#define DIPRINTK(n, args...) +#endif + + +/* Low iomap maps port 0-1K to addresses in 8byte chunks */ +#define KEYWEST_IOMAP_LO_THRESH 0x400 +#define KEYWEST_IOMAP_LO_SHIFT 3 +#define KEYWEST_IOMAP_LO_MASK ((1<>KEYWEST_IOMAP_LO_SHIFT) +static u32 keywest_iomap_lo[KEYWEST_IOMAP_LO_NMAP]; +static u8 keywest_iomap_lo_shift[KEYWEST_IOMAP_LO_NMAP]; + +/* High iomap maps port 1K-64K to addresses in 1K chunks */ +#define KEYWEST_IOMAP_HI_THRESH 0x10000 +#define KEYWEST_IOMAP_HI_SHIFT 10 +#define KEYWEST_IOMAP_HI_MASK ((1<>KEYWEST_IOMAP_HI_SHIFT) +static u32 keywest_iomap_hi[KEYWEST_IOMAP_HI_NMAP]; +static u8 keywest_iomap_hi_shift[KEYWEST_IOMAP_HI_NMAP]; + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +#define PORT2ADDR(x) keywest_isa_port2addr(x) +//#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x)) +//#define PORT2ADDR(x) (x) + +void keywest_port_map(u32 baseport, u32 nports, u32 addr, u8 shift) +{ + u32 port, endport = baseport + nports; + + DPRINTK("keywest_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)\n", + baseport, nports, addr); + + for (port = baseport ; + port < endport && port < KEYWEST_IOMAP_LO_THRESH ; + port += (1<>KEYWEST_IOMAP_LO_SHIFT] = addr; + keywest_iomap_lo_shift[port>>KEYWEST_IOMAP_LO_SHIFT] = shift; + addr += (1<<(KEYWEST_IOMAP_LO_SHIFT)); + } + + for (port = MAX(baseport, KEYWEST_IOMAP_LO_THRESH) ; + port < endport && port < KEYWEST_IOMAP_HI_THRESH ; + port += (1<>KEYWEST_IOMAP_HI_SHIFT] = addr; + keywest_iomap_hi_shift[port>>KEYWEST_IOMAP_HI_SHIFT] = shift; + addr += (1<<(KEYWEST_IOMAP_HI_SHIFT)); + } +} +EXPORT_SYMBOL(keywest_port_map); + +void keywest_port_unmap(u32 baseport, u32 nports) +{ + u32 port, endport = baseport + nports; + + DPRINTK("keywest_port_unmap(base=0x%0x, n=0x%0x)\n", baseport, nports); + + for (port = baseport ; + port < endport && port < KEYWEST_IOMAP_LO_THRESH ; + port += (1<>KEYWEST_IOMAP_LO_SHIFT] = 0; + } + + for (port = MAX(baseport, KEYWEST_IOMAP_LO_THRESH) ; + port < endport && port < KEYWEST_IOMAP_HI_THRESH ; + port += (1<>KEYWEST_IOMAP_HI_SHIFT] = 0; + } +} +EXPORT_SYMBOL(keywest_port_unmap); + +unsigned long keywest_isa_port2addr(unsigned long port) +{ + unsigned long addr; + unsigned char shift; + + /* Physical address not in P0, do nothing */ + if (PXSEG(port)) + return(port); + + addr = 0; + /* physical address in P0, map to P2 */ + if (port >= 0x30000) + addr = P2SEGADDR(port); + /* Key West I/O + HD64465 registers 0x10000-0x30000 */ + else if (port >= KEYWEST_IOMAP_HI_THRESH) + addr = KEYWEST_INTERNAL_BASE + (port - KEYWEST_IOMAP_HI_THRESH); + /* Handle remapping of high IO/PCI IO ports */ + else if (port >= KEYWEST_IOMAP_LO_THRESH) { + addr = keywest_iomap_hi[port >> KEYWEST_IOMAP_HI_SHIFT]; + shift = keywest_iomap_hi_shift[port >> KEYWEST_IOMAP_HI_SHIFT]; + if (addr != 0) + addr += (port & KEYWEST_IOMAP_HI_MASK) << shift; + } + /* Handle remapping of low IO ports */ + else { + addr = keywest_iomap_lo[port >> KEYWEST_IOMAP_LO_SHIFT]; + shift = keywest_iomap_lo_shift[port >> KEYWEST_IOMAP_LO_SHIFT]; + if (addr != 0) + addr += (port & KEYWEST_IOMAP_LO_MASK) << shift; + } + + DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lx\n", port, addr); + + return addr; +} + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +unsigned char keywest_inb(unsigned long port) +{ + unsigned long addr = PORT2ADDR(port); + unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr); + + DIPRINTK(0, "inb(%08lx) = %02x\n", addr, (unsigned)b); + return b; +} + +unsigned char keywest_inb_p(unsigned long port) +{ + unsigned long v; + unsigned long addr = PORT2ADDR(port); + + v = (addr == 0 ? 0 : *(volatile unsigned char*)addr); + delay(); + DIPRINTK(0, "inb_p(%08lx) = %02x\n", addr, (unsigned)v); + return v; +} + +unsigned short keywest_inw(unsigned long port) +{ + unsigned long addr = PORT2ADDR(port); + unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr); + DIPRINTK(0, "inw(%08lx) = %04lx\n", addr, b); + return b; +} + +unsigned int keywest_inl(unsigned long port) +{ + unsigned long addr = PORT2ADDR(port); + unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr); + DIPRINTK(0, "inl(%08lx) = %08x\n", addr, b); + return b; +} + +void keywest_insb(unsigned long port, void *buffer, unsigned long count) +{ + unsigned char *buf=buffer; + while(count--) *buf++=inb(port); +} + +void keywest_insw(unsigned long port, void *buffer, unsigned long count) +{ + unsigned short *buf=buffer; + while(count--) *buf++=inw(port); +} + +void keywest_insl(unsigned long port, void *buffer, unsigned long count) +{ +#if 0 + unsigned long *buf=buffer; + while(count--) *buf++=inl(port); +#else + union { + unsigned long l; + unsigned short s[2]; + unsigned char c[4]; + } align; + port = (((unsigned long)(port)) & 0xe0000000) ? port : + keywest_isa_port2addr(port); + switch (((unsigned long) buffer) & 0x3) { + case 0: { + register unsigned long *buf=buffer, *endp = buf + count; + while (buf < endp) + *buf++ = * (volatile unsigned long *) port; + break; + } + case 2: { + register unsigned short *buf=buffer, *endp = buf + (count << 1); + while (buf < endp) { + align.l = * (volatile unsigned long *) port; + *buf++ = align.s[0]; + *buf++ = align.s[1]; + } + break; + } + case 1: + case 3: { + register unsigned char *buf=buffer, *endp = buf + (count << 2); + while (buf < endp) { + align.l = * (volatile unsigned long *) port; + *buf++ = align.c[0]; + *buf++ = align.c[1]; + *buf++ = align.c[2]; + *buf++ = align.c[3]; + } + break; + } + } +#endif +} + +void keywest_outb(unsigned char b, unsigned long port) +{ + unsigned long addr = PORT2ADDR(port); + + DIPRINTK(0, "outb(%02x, %08lx)\n", (unsigned)b, addr); + if (addr != 0) + *(volatile unsigned char*)addr = b; +} + +void keywest_outb_p(unsigned char b, unsigned long port) +{ + unsigned long addr = PORT2ADDR(port); + + DIPRINTK(0, "outb_p(%02x, %08lx)\n", (unsigned)b, addr); + if (addr != 0) + *(volatile unsigned char*)addr = b; + delay(); +} + +void keywest_outw(unsigned short b, unsigned long port) +{ + unsigned long addr = PORT2ADDR(port); + DIPRINTK(0, "outw(%04x, %08lx)\n", (unsigned)b, addr); + if (addr != 0) + *(volatile unsigned short*)addr = b; +} + +void keywest_outl(unsigned int b, unsigned long port) +{ + unsigned long addr = PORT2ADDR(port); + DIPRINTK(0, "outl(%08x, %08lx)\n", b, addr); + if (addr != 0) + *(volatile unsigned long*)addr = b; +} + +void keywest_outsb(unsigned long port, const void *buffer, unsigned long count) +{ + const unsigned char *buf=buffer; + while(count--) outb(*buf++, port); +} + +void keywest_outsw(unsigned long port, const void *buffer, unsigned long count) +{ + const unsigned short *buf=buffer; + while(count--) outw(*buf++, port); +} + +void keywest_outsl(unsigned long port, const void *buffer, unsigned long count) +{ +#if 0 + const unsigned long *buf=buffer; + while(count--) outl(*buf++, port); +#else + union { + unsigned long l; + unsigned short s[2]; + unsigned char c[4]; + } align; + port = (((unsigned long)(port)) & 0xe0000000) ? port : + keywest_isa_port2addr(port); + switch (((unsigned long) buffer) & 0x3) { + case 0: { + register unsigned long *buf=buffer, *endp = buf + count; + while (buf < endp) + * (volatile unsigned long *) port = *buf++; + break; + } + case 2: { + register unsigned short *buf=buffer, *endp = buf + (count << 1); + while (buf < endp) { + align.s[0] = *buf++; + align.s[1] = *buf++; + * (volatile unsigned long *) port = align.l; + } + break; + } + case 1: + case 3: { + register unsigned char *buf=buffer, *endp = buf + (count << 2); + while (buf < endp) { + align.c[0] = *buf++; + align.c[1] = *buf++; + align.c[2] = *buf++; + align.c[3] = *buf++; + * (volatile unsigned long *) port = align.l; + } + break; + } + } +#endif +} + diff -urN linux-2.4.21/arch/sh/kernel/io_se.c linux-2.4.22/arch/sh/kernel/io_se.c --- linux-2.4.21/arch/sh/kernel/io_se.c 2001-10-15 13:36:48.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/io_se.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: io_se.c,v 1.12 2001/08/11 01:23:28 jzs Exp $ +/* $Id: io_se.c,v 1.1.1.1.2.1 2002/02/26 11:42:29 gniibe Exp $ * * linux/arch/sh/kernel/io_se.c * @@ -23,6 +23,7 @@ static inline void delay(void) { ctrl_inw(0xa0000000); + ctrl_inw(0xa0000000); } /* MS7750 requires special versions of in*, out* routines, since diff -urN linux-2.4.21/arch/sh/kernel/io_shmse.c linux-2.4.22/arch/sh/kernel/io_shmse.c --- linux-2.4.21/arch/sh/kernel/io_shmse.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/io_shmse.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,169 @@ +/* + * linux/arch/sh/kernel/io_shmse.c + * + * Copyright (C) 2003 Takashi Kusuda + * Based largely on io_se.c + * + * I/O routine for SH-Mobile SolutionEngine. + */ + +#include +#include +#include +#include +#include + +static inline void delay(void) +{ + ctrl_inw(0xac000000); + ctrl_inw(0xac000000); +} + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08lx\n", \ + #name, (port), (volatile unsigned long) __builtin_return_address(0)) + +unsigned char shmse_inb(unsigned long port) +{ + if (PXSEG(port)){ + return *(volatile unsigned char *) port; + }else{ + maybebadio(inb, port); + return 0; + } +} + +unsigned char shmse_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)){ + v = *(volatile unsigned char *)port; + }else{ + maybebadio(inb_p, port); + return 0; + } + delay(); + return v; +} + +unsigned short shmse_inw(unsigned long port) +{ + if (PXSEG(port)){ + return *(volatile unsigned short *) port; + }else{ + maybebadio(inw, port); + return 0; + } +} + +unsigned int shmse_inl(unsigned long port) +{ + if (PXSEG(port)){ + return *(volatile unsigned short *) port; + }else{ + maybebadio(inl, port); + return 0; + } +} + +void shmse_outb(unsigned char value, unsigned long port) +{ + if (PXSEG(port)){ + *(volatile unsigned char *)port = value; + }else{ + maybebadio(outb, port); + } +} + +void shmse_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)){ + *(volatile unsigned char *)port = value; + }else{ + maybebadio(outb_p, port); + } + delay(); +} + +void shmse_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)){ + *(volatile unsigned short *)port = value; + }else{ + maybebadio(outw, port); + } +} + +void shmse_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)){ + *(volatile unsigned long *)port = value; + }else{ + maybebadio(outl, port); + } +} + +void shmse_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *p = addr; + while (count--) *p++ = shmse_inb(port); +} + +void shmse_insw(unsigned long port, void *addr, unsigned long count) +{ + unsigned short *p = addr; + while (count--) *p++ = shmse_inw(port); +} + +void shmse_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(insl, port); +} + +void shmse_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *p = (unsigned char *)addr; + while (count--) shmse_outb(*p++, port); +} + +void shmse_outsw(unsigned long port, const void *addr, unsigned long count) +{ + unsigned short *p = (unsigned short *)addr; + while (count--) shmse_outw(*p++, port); +} + +void shmse_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(outsw, port); +} + +unsigned char shmse_readb(unsigned long addr) +{ + return *(volatile unsigned char*)addr; +} + +unsigned short shmse_readw(unsigned long addr) +{ + return *(volatile unsigned short*)addr; +} + +unsigned int shmse_readl(unsigned long addr) +{ + return *(volatile unsigned long*)addr; +} + +void shmse_writeb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned char*)addr = b; +} + +void shmse_writew(unsigned short b, unsigned long addr) +{ + *(volatile unsigned short*)addr = b; +} + +void shmse_writel(unsigned int b, unsigned long addr) +{ + *(volatile unsigned long*)addr = b; +} diff -urN linux-2.4.21/arch/sh/kernel/io_snapgear.c linux-2.4.22/arch/sh/kernel/io_snapgear.c --- linux-2.4.21/arch/sh/kernel/io_snapgear.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/io_snapgear.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,299 @@ +/* + * linux/arch/sh/kernel/io_7751se.c + * + * Copyright (C) 2002 David McCullough + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Hitachi 7751 SolutionEngine. + * + * Initial version only to support LAN access; some + * placeholder code from io_se.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_SH_SECUREEDGE5410 +unsigned short secureedge5410_ioport; +#endif + +/* + * The SnapGear uses the built-in PCI controller (PCIC) + * of the 7751 processor + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + + +static inline volatile __u16 * +port2adr(unsigned int port) +{ +#if 0 + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); +#endif + maybebadio(name,port); + return (volatile __u16*)port; +} + + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ + +unsigned char snapgear_inb(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); + else + return (*port2adr(port))&0xff; +} + + +unsigned char snapgear_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)) + v = *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); + else + v = (*port2adr(port))&0xff; + delay(); + return v; +} + + +unsigned short snapgear_inw(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); + else if (port >= 0x2000) + return *port2adr(port); + else + maybebadio(inw, port); + return 0; +} + + +unsigned int snapgear_inl(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned int *)PCI_IOMAP(port); + else if (port >= 0x2000) + return *port2adr(port); + else + maybebadio(inl, port); + return 0; +} + + +void snapgear_outb(unsigned char value, unsigned long port) +{ + + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; + else + *(port2adr(port)) = value; +} + + +void snapgear_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; + else + *(port2adr(port)) = value; + delay(); +} + + +void snapgear_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned short *)PCI_IOMAP(port)) = value; + else if (port >= 0x2000) + *port2adr(port) = value; + else + maybebadio(outw, port); +} + + +void snapgear_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned long*)PCI_IOMAP(port)) = value; + else + maybebadio(outl, port); +} + + +void snapgear_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *p = addr; + while (count--) *p++ = snapgear_inb(port); +} + + +void snapgear_insw(unsigned long port, void *addr, unsigned long count) +{ + unsigned short *p = addr; + while (count--) *p++ = snapgear_inw(port); +} + + +void snapgear_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(insl, port); +} + + +void snapgear_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *p = (unsigned char*)addr; + while (count--) snapgear_outb(*p++, port); +} + + +void snapgear_outsw(unsigned long port, const void *addr, unsigned long count) +{ + unsigned short *p = (unsigned short*)addr; + while (count--) snapgear_outw(*p++, port); +} + + +void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(outsw, port); +} + + +/* For read/write calls, just copy generic (pass-thru); PCIMBR is */ +/* already set up. For a larger memory space, these would need to */ +/* reset PCIMBR as needed on a per-call basis... */ + +unsigned char snapgear_readb(unsigned long addr) +{ + return (* ((volatile unsigned char *) addr)); +} + + +unsigned short snapgear_readw(unsigned long addr) +{ + return (* ((volatile unsigned short *) addr)); +} + + +unsigned int snapgear_readl(unsigned long addr) +{ + return (* ((volatile unsigned long *) addr)); +} + + +void snapgear_writeb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned char*)addr = b; +} + + +void snapgear_writew(unsigned short b, unsigned long addr) +{ + *(volatile unsigned short*)addr = b; +} + + +void snapgear_writel(unsigned int b, unsigned long addr) +{ + *(volatile unsigned long*)addr = b; +} + + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + + +static int +sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); +#if 0 + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); +#endif + return 0; +} + + +unsigned long +snapgear_isa_port2addr(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; +} diff -urN linux-2.4.21/arch/sh/kernel/irq_ipr.c linux-2.4.22/arch/sh/kernel/irq_ipr.c --- linux-2.4.21/arch/sh/kernel/irq_ipr.c 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/irq_ipr.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,15 +1,16 @@ -/* $Id: irq_ipr.c,v 1.20 2001/07/15 23:26:56 gniibe Exp $ +/* $Id: irq_ipr.c,v 1.1.1.1.2.1 2003/07/16 18:41:20 yoshii Exp $ * * linux/arch/sh/kernel/irq_ipr.c * * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2003 Takashi Kusuda * * Interrupt handling for IPR-based IRQ. * * Supported system: * On-chip supporting modules (TMU, RTC, etc.). - * On-chip supporting modules for SH7709/SH7709A/SH7729. + * On-chip supporting modules for SH7300/SH7709/SH7709A/SH7729. * Hitachi SolutionEngine external I/O: * MS7709SE01, MS7709ASE01, and MS7750SE01 * @@ -88,7 +89,8 @@ { disable_ipr_irq(irq); -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) /* This is needed when we use edge triggered setting */ /* XXX: Is it really needed? */ if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { @@ -196,7 +198,10 @@ #endif make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); + +#if defined(CONFIG_SH_RTC) make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); +#endif #ifdef SCI_ERI_IRQ make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); @@ -211,6 +216,10 @@ make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY); +#endif + #ifdef SCIF_ERI_IRQ make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); @@ -225,7 +234,8 @@ make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) /* * Initialize the Interrupt Controller (INTC) * registers to their power on values @@ -242,6 +252,7 @@ make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY); make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY); make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); enable_ipr_irq(PINT0_IRQ); @@ -260,16 +271,19 @@ else if(i & 0x40) pint_map[i] = 6; else if(i & 0x80) pint_map[i] = 7; } -#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */ +#endif +#endif /* CONFIG_CPU_SUBTYPE_SH7300 || CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */ /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq != NULL) { sh_mv.mv_init_irq(); } } -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) int ipr_irq_demux(int irq) { +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) unsigned long creg, dreg, d, sav; if(irq == PINT0_IRQ) @@ -304,6 +318,7 @@ if(d == 0) return irq; return PINT_IRQ_BASE + 8 + pint_map[d]; } +#endif return irq; } #endif diff -urN linux-2.4.21/arch/sh/kernel/kgdb_jmp.S linux-2.4.22/arch/sh/kernel/kgdb_jmp.S --- linux-2.4.21/arch/sh/kernel/kgdb_jmp.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/kgdb_jmp.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,33 @@ +#include + +ENTRY(kgdb_setjmp) + add #(9*4), r4 + sts.l pr, @-r4 + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + rts + mov #0, r0 + +ENTRY(kgdb_longjmp) + mov.l @r4+, r8 + mov.l @r4+, r9 + mov.l @r4+, r10 + mov.l @r4+, r11 + mov.l @r4+, r12 + mov.l @r4+, r13 + mov.l @r4+, r14 + mov.l @r4+, r15 + lds.l @r4+, pr + mov r5, r0 + tst r0, r0 + bf 1f + mov #1, r0 ! in case val==0 +1: rts + nop + diff -urN linux-2.4.21/arch/sh/kernel/kgdb_stub.c linux-2.4.22/arch/sh/kernel/kgdb_stub.c --- linux-2.4.21/arch/sh/kernel/kgdb_stub.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/kgdb_stub.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,1488 @@ +/* + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Contains extracts from code by Glenn Engel, Jim Kingdon, + * David Grothe , Tigran Aivazian , + * Amit S. Kale , William Gatliff , + * Ben Lee, Steve Chamberlain and Benoit Miller . + * + * This version by Henry Bell + * Minor modifications by Jeremy Siegel + * + * Contains low-level support for remote debug using GDB. + * + * To enable debugger support, two things need to happen. A call to + * set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * A breakpoint also needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint() which does + * a trapa if the initialisation phase has been successfully completed. + * + * In this case, set_debug_traps() is not used to "take over" exceptions; + * other kernel code is modified instead to enter the kgdb functions here + * when appropriate (see entry.S for breakpoint traps and NMI interrupts, + * see traps.c for kernel error exceptions). + * + * The following gdb commands are supported: + * + * Command Function Return value + * + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * XAA..AA,LLLL: Same, but data is binary (not hex) OK or ENN + * + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * CNN; Resume at current address with signal SNN + * CNN;AA..AA Resume at address AA..AA with signal SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * SNN; Step one instruction with signal SNN + * SNNAA..AA Step one instruction from AA..AA w/NN SNN + * + * k kill (Detach GDB) + * + * d Toggle debug flag + * D Detach GDB + * + * Hct Set thread t for operations, OK or ENN + * c = 'c' (step, cont), c = 'g' (other + * operations) + * + * qC Query current thread ID QCpid + * qfThreadInfo Get list of current threads (first) m + * qsThreadInfo " " " " " (subsequent) + * qOffsets Get section offsets Text=x;Data=y;Bss=z + * + * TXX Find if thread XX is alive OK or ENN + * ? What was the last sigval ? SNN (signal NN) + * O Output to GDB console + * + * Remote communication protocol. + * + * A debug packet whose contents are is encapsulated for + * transmission in the form: + * + * $ # CSUM1 CSUM2 + * + * must be ASCII alphanumeric and cannot include characters + * '$' or '#'. If starts with two characters followed by + * ':', then the existing stubs interpret this as a sequence number. + * + * CSUM1 and CSUM2 are ascii hex representation of an 8-bit + * checksum of , the most significant nibble is sent first. + * the hex digits 0-9,a-f are used. + * + * Receiver responds with: + * + * + - if CSUM is correct and ready for next packet + * - - if CSUM is incorrect + * + * Responses can be run-length encoded to save space. A '*' means that + * the next character is an ASCII encoding giving a repeat count which + * stands for that many repititions of the character preceding the '*'. + * The encoding is n+29, yielding a printable character where n >=3 + * (which is where RLE starts to win). Don't use an n > 126. + * + * So "0* " means the same as "0000". + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SH_KGDB_CONSOLE +#include +#endif + +/* Function pointers for linkage */ +kgdb_debug_hook_t *kgdb_debug_hook; +kgdb_bus_error_hook_t *kgdb_bus_err_hook; + +int (*kgdb_getchar)(void); +void (*kgdb_putchar)(int); + +static void put_debug_char(int c) +{ + if (!kgdb_putchar) + return; + (*kgdb_putchar)(c); +} +static int get_debug_char(void) +{ + if (!kgdb_getchar) + return -1; + return (*kgdb_getchar)(); +} + +/* Num chars in in/out bound buffers, register packets need NUMREGBYTES * 2 */ +#define BUFMAX 1024 +#define NUMREGBYTES (MAXREG*4) +#define OUTBUFMAX (NUMREGBYTES*2+512) + +enum regs { + R0 = 0, R1, R2, R3, R4, R5, R6, R7, + R8, R9, R10, R11, R12, R13, R14, R15, + PC, PR, GBR, VBR, MACH, MACL, SR, + /* */ + MAXREG +}; + +static unsigned int registers[MAXREG]; +struct kgdb_regs trap_registers; + +char kgdb_in_gdb_mode; +char in_nmi; /* Set during NMI to prevent reentry */ +int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ +int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ +int kgdb_halt; + +/* Exposed for user access */ +struct task_struct *kgdb_current; +unsigned int kgdb_g_imask; +int kgdb_trapa_val; +int kgdb_excode; +struct pt_regs *kgdb_tregs; + +/* Default values for SCI (can override via kernel args in setup.c) */ +#ifndef CONFIG_KGDB_DEFPORT +#define CONFIG_KGDB_DEFPORT 1 +#endif + +#ifndef CONFIG_KGDB_DEFBAUD +#define CONFIG_KGDB_DEFBAUD 115200 +#endif + +#if defined(CONFIG_KGDB_DEFPARITY_E) +#define CONFIG_KGDB_DEFPARITY 'E' +#elif defined(CONFIG_KGDB_DEFPARITY_O) +#define CONFIG_KGDB_DEFPARITY 'O' +#else /* CONFIG_KGDB_DEFPARITY_N */ +#define CONFIG_KGDB_DEFPARITY 'N' +#endif + +#ifdef CONFIG_KGDB_DEFBITS_7 +#define CONFIG_KGDB_DEFBITS '7' +#else /* CONFIG_KGDB_DEFBITS_8 */ +#define CONFIG_KGDB_DEFBITS '8' +#endif + +/* SCI/UART settings, used in kgdb_serial_setup() */ +int (*kgdb_serial_setup)(void) = kgdb_sci_setup; +int kgdb_portnum = CONFIG_KGDB_DEFPORT; +int kgdb_baud = CONFIG_KGDB_DEFBAUD; +char kgdb_parity = CONFIG_KGDB_DEFPARITY; +char kgdb_bits = CONFIG_KGDB_DEFBITS; +int kgdb_cflag; + +/* Jump buffer for setjmp/longjmp */ +static jmp_buf rem_com_env; + +/* TRA differs sh3/4 */ +#if defined(__sh3__) +#define TRA 0xffffffd0 +#elif defined(__SH4__) +#define TRA 0xff000020 +#endif + +/* Macros for single step instruction identification */ +#define OPCODE_BT(op) (((op) & 0xff00) == 0x8900) +#define OPCODE_BF(op) (((op) & 0xff00) == 0x8b00) +#define OPCODE_BTF_DISP(op) (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \ + (((op) & 0x7f ) << 1)) +#define OPCODE_BFS(op) (((op) & 0xff00) == 0x8f00) +#define OPCODE_BTS(op) (((op) & 0xff00) == 0x8d00) +#define OPCODE_BRA(op) (((op) & 0xf000) == 0xa000) +#define OPCODE_BRA_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \ + (((op) & 0x7ff) << 1)) +#define OPCODE_BRAF(op) (((op) & 0xf0ff) == 0x0023) +#define OPCODE_BRAF_REG(op) (((op) & 0x0f00) >> 8) +#define OPCODE_BSR(op) (((op) & 0xf000) == 0xb000) +#define OPCODE_BSR_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \ + (((op) & 0x7ff) << 1)) +#define OPCODE_BSRF(op) (((op) & 0xf0ff) == 0x0003) +#define OPCODE_BSRF_REG(op) (((op) >> 8) & 0xf) +#define OPCODE_JMP(op) (((op) & 0xf0ff) == 0x402b) +#define OPCODE_JMP_REG(op) (((op) >> 8) & 0xf) +#define OPCODE_JSR(op) (((op) & 0xf0ff) == 0x400b) +#define OPCODE_JSR_REG(op) (((op) >> 8) & 0xf) +#define OPCODE_RTS(op) ((op) == 0xb) +#define OPCODE_RTE(op) ((op) == 0x2b) + +#define SR_T_BIT_MASK 0x1 +#define STEP_OPCODE 0xc320 +#define BIOS_CALL_TRAP 0x3f + +/* Exception codes as per SH-4 core manual */ +#define ADDRESS_ERROR_LOAD_VEC 7 +#define ADDRESS_ERROR_STORE_VEC 8 +#define TRAP_VEC 11 +#define INVALID_INSN_VEC 12 +#define INVALID_SLOT_VEC 13 +#define NMI_VEC 14 +#define USER_BREAK_VEC 15 +#define SERIAL_BREAK_VEC 58 + +/* Misc static */ +static int stepped_address; +static short stepped_opcode; +static const char hexchars[] = "0123456789abcdef"; +static char in_buffer[BUFMAX]; +static char out_buffer[OUTBUFMAX]; + +static void kgdb_to_gdb(const char *s); + +#ifdef CONFIG_KGDB_THREAD +static struct task_struct *trapped_thread; +static struct task_struct *current_thread; +typedef unsigned char threadref[8]; +#define BUF_THREAD_ID_SIZE 16 +#endif + +/* Return addr as a real volatile address */ +static inline unsigned int ctrl_inl(const unsigned long addr) +{ + return *(volatile unsigned long *) addr; +} + +/* Correctly set *addr using volatile */ +static inline void ctrl_outl(const unsigned int b, unsigned long addr) +{ + *(volatile unsigned long *) addr = b; +} + +/* Get high hex bits */ +static char highhex(const int x) +{ + return hexchars[(x >> 4) & 0xf]; +} + +/* Get low hex bits */ +static char lowhex(const int x) +{ + return hexchars[x & 0xf]; +} + +/* Convert ch to hex */ +static int hex(const char ch) +{ + if ((ch >= 'a') && (ch <= 'f')) + return (ch - 'a' + 10); + if ((ch >= '0') && (ch <= '9')) + return (ch - '0'); + if ((ch >= 'A') && (ch <= 'F')) + return (ch - 'A' + 10); + return (-1); +} + +/* Convert the memory pointed to by mem into hex, placing result in buf. + Returns a pointer to the last char put in buf (null) */ +static char *mem_to_hex(const char *mem, char *buf, const int count) +{ + int i; + int ch; + unsigned short s_val; + unsigned long l_val; + + /* Check for 16 or 32 */ + if (count == 2 && ((long) mem & 1) == 0) { + s_val = *(unsigned short *) mem; + mem = (char *) &s_val; + } else if (count == 4 && ((long) mem & 3) == 0) { + l_val = *(unsigned long *) mem; + mem = (char *) &l_val; + } + for (i = 0; i < count; i++) { + ch = *mem++; + *buf++ = highhex(ch); + *buf++ = lowhex(ch); + } + *buf = 0; + return (buf); +} + +/* Convert the hex array pointed to by buf into binary, to be placed in mem. + Return a pointer to the character after the last byte written */ +static char *hex_to_mem(const char *buf, char *mem, const int count) +{ + int i; + unsigned char ch; + + for (i = 0; i < count; i++) { + ch = hex(*buf++) << 4; + ch = ch + hex(*buf++); + *mem++ = ch; + } + return (mem); +} + +/* While finding valid hex chars, convert to an integer, then return it */ +static int hex_to_int(char **ptr, int *int_value) +{ + int num_chars = 0; + int hex_value; + + *int_value = 0; + + while (**ptr) { + hex_value = hex(**ptr); + if (hex_value >= 0) { + *int_value = (*int_value << 4) | hex_value; + num_chars++; + } else + break; + (*ptr)++; + } + return num_chars; +} + +/* Copy the binary array pointed to by buf into mem. Fix $, #, + and 0x7d escaped with 0x7d. Return a pointer to the character + after the last byte written. */ +static char *ebin_to_mem(const char *buf, char *mem, int count) +{ + for (; count > 0; count--, buf++) { + if (*buf == 0x7d) + *mem++ = *(++buf) ^ 0x20; + else + *mem++ = *buf; + } + return mem; +} + +/* Pack a hex byte */ +static char *pack_hex_byte(char *pkt, int byte) +{ + *pkt++ = hexchars[(byte >> 4) & 0xf]; + *pkt++ = hexchars[(byte & 0xf)]; + return pkt; +} + +#ifdef CONFIG_KGDB_THREAD + +/* Pack a thread ID */ +static char *pack_threadid(char *pkt, threadref * id) +{ + char *limit; + unsigned char *altid; + + altid = (unsigned char *) id; + + limit = pkt + BUF_THREAD_ID_SIZE; + while (pkt < limit) + pkt = pack_hex_byte(pkt, *altid++); + return pkt; +} + +/* Convert an integer into our threadref */ +static void int_to_threadref(threadref * id, const int value) +{ + unsigned char *scan = (unsigned char *) id; + int i = 4; + + while (i--) + *scan++ = 0; + + *scan++ = (value >> 24) & 0xff; + *scan++ = (value >> 16) & 0xff; + *scan++ = (value >> 8) & 0xff; + *scan++ = (value & 0xff); +} + +/* Return a task structure ptr for a particular pid */ +static struct task_struct *get_thread(int pid) +{ + struct task_struct *thread; + + /* Use PID_MAX w/gdb for pid 0 */ + if (pid == PID_MAX) pid = 0; + + /* First check via PID */ + thread = find_task_by_pid(pid); + + if (thread) + return thread; + + /* Start at the start */ + thread = init_tasks[0]; + + /* Walk along the linked list of tasks */ + do { + if (thread->pid == pid) + return thread; + thread = thread->next_task; + } while (thread != init_tasks[0]); + + return NULL; +} + +#endif /* CONFIG_KGDB_THREAD */ + +/* Scan for the start char '$', read the packet and check the checksum */ +static void get_packet(char *buffer, int buflen) +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + char ch; + + do { + /* Ignore everything until the start character */ + while ((ch = get_debug_char()) != '$'); + + checksum = 0; + xmitcsum = -1; + count = 0; + + /* Now, read until a # or end of buffer is found */ + while (count < (buflen - 1)) { + ch = get_debug_char(); + + if (ch == '#') + break; + + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + + buffer[count] = 0; + + /* Continue to read checksum following # */ + if (ch == '#') { + xmitcsum = hex(get_debug_char()) << 4; + xmitcsum += hex(get_debug_char()); + + /* Checksum */ + if (checksum != xmitcsum) + put_debug_char('-'); /* Failed checksum */ + else { + /* Ack successful transfer */ + put_debug_char('+'); + + /* If a sequence char is present, reply + the sequence ID */ + if (buffer[2] == ':') { + put_debug_char(buffer[0]); + put_debug_char(buffer[1]); + + /* Remove sequence chars from buffer */ + count = strlen(buffer); + for (i = 3; i <= count; i++) + buffer[i - 3] = buffer[i]; + } + } + } + } + while (checksum != xmitcsum); /* Keep trying while we fail */ +} + +/* Send the packet in the buffer with run-length encoding */ +static void put_packet(char *buffer) +{ + int checksum; + char *src; + int runlen; + int encode; + + do { + src = buffer; + put_debug_char('$'); + checksum = 0; + + /* Continue while we still have chars left */ + while (*src) { + /* Check for runs up to 99 chars long */ + for (runlen = 1; runlen < 99; runlen++) { + if (src[0] != src[runlen]) + break; + } + + if (runlen > 3) { + /* Got a useful amount, send encoding */ + encode = runlen + ' ' - 4; + put_debug_char(*src); checksum += *src; + put_debug_char('*'); checksum += '*'; + put_debug_char(encode); checksum += encode; + src += runlen; + } else { + /* Otherwise just send the current char */ + put_debug_char(*src); checksum += *src; + src += 1; + } + } + + /* '#' Separator, put high and low components of checksum */ + put_debug_char('#'); + put_debug_char(highhex(checksum)); + put_debug_char(lowhex(checksum)); + } + while ((get_debug_char()) != '+'); /* While no ack */ +} + +/* A bus error has occurred - perform a longjmp to return execution and + allow handling of the error */ +static void kgdb_handle_bus_error(void) +{ + kgdb_longjmp(rem_com_env, 1); +} + +/* Translate SH-3/4 exception numbers to unix-like signal values */ +static int compute_signal(const int excep_code) +{ + int sigval; + + switch (excep_code) { + + case INVALID_INSN_VEC: + case INVALID_SLOT_VEC: + sigval = SIGILL; + break; + case ADDRESS_ERROR_LOAD_VEC: + case ADDRESS_ERROR_STORE_VEC: + sigval = SIGSEGV; + break; + + case SERIAL_BREAK_VEC: + case NMI_VEC: + sigval = SIGINT; + break; + + case USER_BREAK_VEC: + case TRAP_VEC: + sigval = SIGTRAP; + break; + + default: + sigval = SIGBUS; /* "software generated" */ + break; + } + + return (sigval); +} + +/* Make a local copy of the registers passed into the handler (bletch) */ +static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs, + int *gdb_regs) +{ + gdb_regs[R0] = regs->regs[R0]; + gdb_regs[R1] = regs->regs[R1]; + gdb_regs[R2] = regs->regs[R2]; + gdb_regs[R3] = regs->regs[R3]; + gdb_regs[R4] = regs->regs[R4]; + gdb_regs[R5] = regs->regs[R5]; + gdb_regs[R6] = regs->regs[R6]; + gdb_regs[R7] = regs->regs[R7]; + gdb_regs[R8] = regs->regs[R8]; + gdb_regs[R9] = regs->regs[R9]; + gdb_regs[R10] = regs->regs[R10]; + gdb_regs[R11] = regs->regs[R11]; + gdb_regs[R12] = regs->regs[R12]; + gdb_regs[R13] = regs->regs[R13]; + gdb_regs[R14] = regs->regs[R14]; + gdb_regs[R15] = regs->regs[R15]; + gdb_regs[PC] = regs->pc; + gdb_regs[PR] = regs->pr; + gdb_regs[GBR] = regs->gbr; + gdb_regs[MACH] = regs->mach; + gdb_regs[MACL] = regs->macl; + gdb_regs[SR] = regs->sr; + gdb_regs[VBR] = regs->vbr; +} + +/* Copy local gdb registers back to kgdb regs, for later copy to kernel */ +static void gdb_regs_to_kgdb_regs(const int *gdb_regs, + struct kgdb_regs *regs) +{ + regs->regs[R0] = gdb_regs[R0]; + regs->regs[R1] = gdb_regs[R1]; + regs->regs[R2] = gdb_regs[R2]; + regs->regs[R3] = gdb_regs[R3]; + regs->regs[R4] = gdb_regs[R4]; + regs->regs[R5] = gdb_regs[R5]; + regs->regs[R6] = gdb_regs[R6]; + regs->regs[R7] = gdb_regs[R7]; + regs->regs[R8] = gdb_regs[R8]; + regs->regs[R9] = gdb_regs[R9]; + regs->regs[R10] = gdb_regs[R10]; + regs->regs[R11] = gdb_regs[R11]; + regs->regs[R12] = gdb_regs[R12]; + regs->regs[R13] = gdb_regs[R13]; + regs->regs[R14] = gdb_regs[R14]; + regs->regs[R15] = gdb_regs[R15]; + regs->pc = gdb_regs[PC]; + regs->pr = gdb_regs[PR]; + regs->gbr = gdb_regs[GBR]; + regs->mach = gdb_regs[MACH]; + regs->macl = gdb_regs[MACL]; + regs->sr = gdb_regs[SR]; + regs->vbr = gdb_regs[VBR]; +} + +#ifdef CONFIG_KGDB_THREAD +/* Make a local copy of registers from the specified thread */ +asmlinkage void ret_from_fork(void); +static void thread_regs_to_gdb_regs(const struct task_struct *thread, + int *gdb_regs) +{ + int regno; + int *tregs; + + /* Initialize to zero */ + for (regno = 0; regno < MAXREG; regno++) + gdb_regs[regno] = 0; + + /* Just making sure... */ + if (thread == NULL) + return; + + /* A new fork has pt_regs on the stack from a fork() call */ + if (thread->thread.pc == (unsigned long)ret_from_fork) { + + int vbr_val; + struct pt_regs *kregs; + kregs = (struct pt_regs*)thread->thread.sp; + + gdb_regs[R0] = kregs->regs[R0]; + gdb_regs[R1] = kregs->regs[R1]; + gdb_regs[R2] = kregs->regs[R2]; + gdb_regs[R3] = kregs->regs[R3]; + gdb_regs[R4] = kregs->regs[R4]; + gdb_regs[R5] = kregs->regs[R5]; + gdb_regs[R6] = kregs->regs[R6]; + gdb_regs[R7] = kregs->regs[R7]; + gdb_regs[R8] = kregs->regs[R8]; + gdb_regs[R9] = kregs->regs[R9]; + gdb_regs[R10] = kregs->regs[R10]; + gdb_regs[R11] = kregs->regs[R11]; + gdb_regs[R12] = kregs->regs[R12]; + gdb_regs[R13] = kregs->regs[R13]; + gdb_regs[R14] = kregs->regs[R14]; + gdb_regs[R15] = kregs->regs[R15]; + gdb_regs[PC] = kregs->pc; + gdb_regs[PR] = kregs->pr; + gdb_regs[GBR] = kregs->gbr; + gdb_regs[MACH] = kregs->mach; + gdb_regs[MACL] = kregs->macl; + gdb_regs[SR] = kregs->sr; + + asm("stc vbr, %0":"=r"(vbr_val)); + gdb_regs[VBR] = vbr_val; + return; + } + + /* Otherwise, we have only some registers from switch_to() */ + tregs = (int *)thread->thread.sp; + gdb_regs[R15] = (int)tregs; + gdb_regs[R14] = *tregs++; + gdb_regs[R13] = *tregs++; + gdb_regs[R12] = *tregs++; + gdb_regs[R11] = *tregs++; + gdb_regs[R10] = *tregs++; + gdb_regs[R9] = *tregs++; + gdb_regs[R8] = *tregs++; + gdb_regs[PR] = *tregs++; + gdb_regs[GBR] = *tregs++; + gdb_regs[PC] = thread->thread.pc; +} +#endif /* CONFIG_KGDB_THREAD */ + +/* Calculate the new address for after a step */ +static short *get_step_address(void) +{ + short op = *(short *) trap_registers.pc; + long addr; + + /* BT */ + if (OPCODE_BT(op)) { + if (trap_registers.sr & SR_T_BIT_MASK) + addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op); + else + addr = trap_registers.pc + 2; + } + + /* BTS */ + else if (OPCODE_BTS(op)) { + if (trap_registers.sr & SR_T_BIT_MASK) + addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op); + else + addr = trap_registers.pc + 4; /* Not in delay slot */ + } + + /* BF */ + else if (OPCODE_BF(op)) { + if (!(trap_registers.sr & SR_T_BIT_MASK)) + addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op); + else + addr = trap_registers.pc + 2; + } + + /* BFS */ + else if (OPCODE_BFS(op)) { + if (!(trap_registers.sr & SR_T_BIT_MASK)) + addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op); + else + addr = trap_registers.pc + 4; /* Not in delay slot */ + } + + /* BRA */ + else if (OPCODE_BRA(op)) + addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op); + + /* BRAF */ + else if (OPCODE_BRAF(op)) + addr = trap_registers.pc + 4 + + trap_registers.regs[OPCODE_BRAF_REG(op)]; + + /* BSR */ + else if (OPCODE_BSR(op)) + addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op); + + /* BSRF */ + else if (OPCODE_BSRF(op)) + addr = trap_registers.pc + 4 + + trap_registers.regs[OPCODE_BSRF_REG(op)]; + + /* JMP */ + else if (OPCODE_JMP(op)) + addr = trap_registers.regs[OPCODE_JMP_REG(op)]; + + /* JSR */ + else if (OPCODE_JSR(op)) + addr = trap_registers.regs[OPCODE_JSR_REG(op)]; + + /* RTS */ + else if (OPCODE_RTS(op)) + addr = trap_registers.pr; + + /* RTE */ + else if (OPCODE_RTE(op)) + addr = trap_registers.regs[15]; + + /* Other */ + else + addr = trap_registers.pc + 2; + + kgdb_flush_icache_range(addr, addr + 2); + return (short *) addr; +} + +/* Set up a single-step. Replace the instruction immediately after the + current instruction (i.e. next in the expected flow of control) with a + trap instruction, so that returning will cause only a single instruction + to be executed. Note that this model is slightly broken for instructions + with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch + and the instruction in the delay slot will be executed. */ +static void do_single_step(void) +{ + unsigned short *addr = 0; + + /* Determine where the target instruction will send us to */ + addr = get_step_address(); + stepped_address = (int)addr; + + /* Replace it */ + stepped_opcode = *(short *)addr; + *addr = STEP_OPCODE; + + /* Flush and return */ + kgdb_flush_icache_range((long) addr, (long) addr + 2); + return; +} + +/* Undo a single step */ +static void undo_single_step(void) +{ + /* If we have stepped, put back the old instruction */ + /* Use stepped_address in case we stopped elsewhere */ + if (stepped_opcode != 0) { + *(short*)stepped_address = stepped_opcode; + kgdb_flush_icache_range(stepped_address, stepped_address + 2); + } + stepped_opcode = 0; +} + +/* Send a signal message */ +static void send_signal_msg(const int signum) +{ +#ifndef CONFIG_KGDB_THREAD + out_buffer[0] = 'S'; + out_buffer[1] = highhex(signum); + out_buffer[2] = lowhex(signum); + out_buffer[3] = 0; + put_packet(out_buffer); +#else /* CONFIG_KGDB_THREAD */ + int threadid; + threadref thref; + char *out = out_buffer; + const char *tstring = "thread"; + + *out++ = 'T'; + *out++ = highhex(signum); + *out++ = lowhex(signum); + + while (*tstring) { + *out++ = *tstring++; + } + *out++ = ':'; + + threadid = trapped_thread->pid; + if (threadid == 0) threadid = PID_MAX; + int_to_threadref(&thref, threadid); + pack_threadid(out, &thref); + out += BUF_THREAD_ID_SIZE; + *out++ = ';'; + + *out = 0; + put_packet(out_buffer); +#endif /* CONFIG_KGDB_THREAD */ +} + +/* Reply that all was well */ +static void send_ok_msg(void) +{ + strcpy(out_buffer, "OK"); + put_packet(out_buffer); +} + +/* Reply that an error occurred */ +static void send_err_msg(void) +{ + strcpy(out_buffer, "E01"); + put_packet(out_buffer); +} + +/* Empty message indicates unrecognised command */ +static void send_empty_msg(void) +{ + put_packet(""); +} + +/* Read memory due to 'm' message */ +static void read_mem_msg(void) +{ + char *ptr; + int addr; + int length; + + /* Jmp, disable bus error handler */ + if (kgdb_setjmp(rem_com_env) == 0) { + + kgdb_nofault = 1; + + /* Walk through, have m, */ + ptr = &in_buffer[1]; + if (hex_to_int(&ptr, &addr) && (*ptr++ == ',')) + if (hex_to_int(&ptr, &length)) { + ptr = 0; + if (length * 2 > OUTBUFMAX) + length = OUTBUFMAX / 2; + mem_to_hex((char *) addr, out_buffer, length); + } + if (ptr) + send_err_msg(); + else + put_packet(out_buffer); + } else + send_err_msg(); + + /* Restore bus error handler */ + kgdb_nofault = 0; +} + +/* Write memory due to 'M' or 'X' message */ +static void write_mem_msg(int binary) +{ + char *ptr; + int addr; + int length; + + if (kgdb_setjmp(rem_com_env) == 0) { + + kgdb_nofault = 1; + + /* Walk through, have M,: */ + ptr = &in_buffer[1]; + if (hex_to_int(&ptr, &addr) && (*ptr++ == ',')) + if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) { + if (binary) + ebin_to_mem(ptr, (char*)addr, length); + else + hex_to_mem(ptr, (char*)addr, length); + kgdb_flush_icache_range(addr, addr + length); + ptr = 0; + send_ok_msg(); + } + if (ptr) + send_err_msg(); + } else + send_err_msg(); + + /* Restore bus error handler */ + kgdb_nofault = 0; +} + +/* Continue message */ +static void continue_msg(void) +{ + /* Try to read optional parameter, PC unchanged if none */ + char *ptr = &in_buffer[1]; + int addr; + + if (hex_to_int(&ptr, &addr)) + trap_registers.pc = addr; +} + +/* Continue message with signal */ +static void continue_with_sig_msg(void) +{ + int signal; + char *ptr = &in_buffer[1]; + int addr; + + /* Report limitation */ + kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n"); + + /* Signal */ + hex_to_int(&ptr, &signal); + if (*ptr == ';') + ptr++; + + /* Optional address */ + if (hex_to_int(&ptr, &addr)) + trap_registers.pc = addr; +} + +/* Step message */ +static void step_msg(void) +{ + continue_msg(); + do_single_step(); +} + +/* Step message with signal */ +static void step_with_sig_msg(void) +{ + continue_with_sig_msg(); + do_single_step(); +} + +/* Send register contents */ +static void send_regs_msg(void) +{ +#ifdef CONFIG_KGDB_THREAD + if (!current_thread) + kgdb_regs_to_gdb_regs(&trap_registers, registers); + else + thread_regs_to_gdb_regs(current_thread, registers); +#else + kgdb_regs_to_gdb_regs(&trap_registers, registers); +#endif + + mem_to_hex((char *) registers, out_buffer, NUMREGBYTES); + put_packet(out_buffer); +} + +/* Set register contents - currently can't set other thread's registers */ +static void set_regs_msg(void) +{ +#ifdef CONFIG_KGDB_THREAD + if (!current_thread) { +#endif + kgdb_regs_to_gdb_regs(&trap_registers, registers); + hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES); + gdb_regs_to_kgdb_regs(registers, &trap_registers); + send_ok_msg(); +#ifdef CONFIG_KGDB_THREAD + } else + send_err_msg(); +#endif +} + + +#ifdef CONFIG_KGDB_THREAD + +/* Set the status for a thread */ +void set_thread_msg(void) +{ + int threadid; + struct task_struct *thread = NULL; + char *ptr; + + switch (in_buffer[1]) { + + /* To select which thread for gG etc messages, i.e. supported */ + case 'g': + + ptr = &in_buffer[2]; + hex_to_int(&ptr, &threadid); + thread = get_thread(threadid); + + /* If we haven't found it */ + if (!thread) { + send_err_msg(); + break; + } + + /* Set current_thread (or not) */ + if (thread == trapped_thread) + current_thread = NULL; + else + current_thread = thread; + send_ok_msg(); + break; + + /* To select which thread for cCsS messages, i.e. unsupported */ + case 'c': + send_ok_msg(); + break; + + default: + send_empty_msg(); + break; + } +} + +/* Is a thread alive? */ +static void thread_status_msg(void) +{ + char *ptr; + int threadid; + struct task_struct *thread = NULL; + + ptr = &in_buffer[1]; + hex_to_int(&ptr, &threadid); + thread = get_thread(threadid); + if (thread) + send_ok_msg(); + else + send_err_msg(); +} +/* Send the current thread ID */ +static void thread_id_msg(void) +{ + int threadid; + threadref thref; + + out_buffer[0] = 'Q'; + out_buffer[1] = 'C'; + + if (current_thread) + threadid = current_thread->pid; + else if (trapped_thread) + threadid = trapped_thread->pid; + else /* Impossible, but just in case! */ + { + send_err_msg(); + return; + } + + /* Translate pid 0 to PID_MAX for gdb */ + if (threadid == 0) threadid = PID_MAX; + + int_to_threadref(&thref, threadid); + pack_threadid(out_buffer + 2, &thref); + out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0'; + put_packet(out_buffer); +} + +/* Send thread info */ +static void thread_info_msg(void) +{ + struct task_struct *thread = NULL; + int threadid; + char *pos; + threadref thref; + + /* Start with 'm' */ + out_buffer[0] = 'm'; + pos = &out_buffer[1]; + + /* For all possible thread IDs - this will overrun if > 44 threads! */ + /* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */ + for (threadid = 1; threadid <= PID_MAX; threadid++) { + + read_lock(&tasklist_lock); + thread = get_thread(threadid); + read_unlock(&tasklist_lock); + + /* If it's a valid thread */ + if (thread) { + int_to_threadref(&thref, threadid); + pack_threadid(pos, &thref); + pos += BUF_THREAD_ID_SIZE; + *pos++ = ','; + } + } + *--pos = 0; /* Lose final comma */ + put_packet(out_buffer); + +} + +/* Return printable info for gdb's 'info threads' command */ +static void thread_extra_info_msg(void) +{ + int threadid; + struct task_struct *thread = NULL; + char buffer[20], *ptr; + int i; + + /* Extract thread ID */ + ptr = &in_buffer[17]; + hex_to_int(&ptr, &threadid); + thread = get_thread(threadid); + + /* If we don't recognise it, say so */ + if (thread == NULL) + strcpy(buffer, "(unknown)"); + else + strcpy(buffer, thread->comm); + + /* Construct packet */ + for (i = 0, ptr = out_buffer; buffer[i]; i++) + ptr = pack_hex_byte(ptr, buffer[i]); + + if (thread->thread.pc == (unsigned long)ret_from_fork) { + strcpy(buffer, ""); + for (i = 0; buffer[i]; i++) + ptr = pack_hex_byte(ptr, buffer[i]); + } + + *ptr = '\0'; + put_packet(out_buffer); +} + +/* Handle all qFooBarBaz messages - have to use an if statement as + opposed to a switch because q messages can have > 1 char id. */ +static void query_msg(void) +{ + const char *q_start = &in_buffer[1]; + + /* qC = return current thread ID */ + if (strncmp(q_start, "C", 1) == 0) + thread_id_msg(); + + /* qfThreadInfo = query all threads (first) */ + else if (strncmp(q_start, "fThreadInfo", 11) == 0) + thread_info_msg(); + + /* qsThreadInfo = query all threads (subsequent). We know we have sent + them all after the qfThreadInfo message, so there are no to send */ + else if (strncmp(q_start, "sThreadInfo", 11) == 0) + put_packet("l"); /* el = last */ + + /* qThreadExtraInfo = supply printable information per thread */ + else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0) + thread_extra_info_msg(); + + /* Unsupported - empty message as per spec */ + else + send_empty_msg(); +} +#endif /* CONFIG_KGDB_THREAD */ + +/* The command loop, read and act on requests */ +static void kgdb_command_loop(const int excep_code, const int trapa_value) +{ + int sigval; + + if (excep_code == NMI_VEC) { +#ifndef CONFIG_KGDB_NMI + KGDB_PRINTK("Ignoring unexpected NMI?\n"); + return; +#else /* CONFIG_KGDB_NMI */ + if (!kgdb_enabled) { + kgdb_enabled = 1; + kgdb_init(); + } +#endif /* CONFIG_KGDB_NMI */ + } + + /* Ignore if we're disabled */ + if (!kgdb_enabled) + return; + +#ifdef CONFIG_KGDB_THREAD + /* Until GDB specifies a thread */ + current_thread = NULL; + trapped_thread = current; +#endif + + /* Enter GDB mode (e.g. after detach) */ + if (!kgdb_in_gdb_mode) { + /* Do serial setup, notify user, issue preemptive ack */ + (void)kgdb_serial_setup(); + KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n", + (kgdb_porttype ? kgdb_porttype->name : ""), + kgdb_portnum, kgdb_baud); + kgdb_in_gdb_mode = 1; + put_debug_char('+'); + } + + /* Reply to host that an exception has occurred */ + sigval = compute_signal(excep_code); + send_signal_msg(sigval); + + /* TRAP_VEC exception indicates a software trap inserted in place of + code by GDB so back up PC by one instruction, as this instruction + will later be replaced by its original one. Do NOT do this for + trap 0xff, since that indicates a compiled-in breakpoint which + will not be replaced (and we would retake the trap forever) */ + if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) { + trap_registers.pc -= 2; + } + + /* Undo any stepping we may have done */ + undo_single_step(); + + while (1) { + + out_buffer[0] = 0; + get_packet(in_buffer, BUFMAX); + + /* Examine first char of buffer to see what we need to do */ + switch (in_buffer[0]) { + + case '?': /* Send which signal we've received */ + send_signal_msg(sigval); + break; + + case 'g': /* Return the values of the CPU registers */ + send_regs_msg(); + break; + + case 'G': /* Set the value of the CPU registers */ + set_regs_msg(); + break; + + case 'm': /* Read LLLL bytes address AA..AA */ + read_mem_msg(); + break; + + case 'M': /* Write LLLL bytes address AA..AA, ret OK */ + write_mem_msg(0); /* 0 = data in hex */ + break; + + case 'X': /* Write LLLL bytes esc bin address AA..AA */ + if (kgdb_bits == '8') + write_mem_msg(1); /* 1 = data in binary */ + else + send_empty_msg(); + break; + + case 'C': /* Continue, signum included, we ignore it */ + continue_with_sig_msg(); + return; + + case 'c': /* Continue at address AA..AA (optional) */ + continue_msg(); + return; + + case 'S': /* Step, signum included, we ignore it */ + step_with_sig_msg(); + return; + + case 's': /* Step one instruction from AA..AA */ + step_msg(); + return; + +#ifdef CONFIG_KGDB_THREAD + + case 'H': /* Task related */ + set_thread_msg(); + break; + + case 'T': /* Query thread status */ + thread_status_msg(); + break; + + case 'q': /* Handle query - currently thread-related */ + query_msg(); + break; +#endif + + case 'k': /* 'Kill the program' with a kernel ? */ + break; + + case 'D': /* Detach from program, send reply OK */ + kgdb_in_gdb_mode = 0; + send_ok_msg(); + get_debug_char(); + return; + + default: + send_empty_msg(); + break; + } + } +} + +/* There has been an exception, most likely a breakpoint. */ +void kgdb_handle_exception(struct pt_regs *regs) +{ + int excep_code, vbr_val; + int count; + int trapa_value = ctrl_inl(TRA); + + /* Copy kernel regs (from stack) */ + for (count = 0; count < 16; count++) + trap_registers.regs[count] = regs->regs[count]; + trap_registers.pc = regs->pc; + trap_registers.pr = regs->pr; + trap_registers.sr = regs->sr; + trap_registers.gbr = regs->gbr; + trap_registers.mach = regs->mach; + trap_registers.macl = regs->macl; + + asm("stc vbr, %0":"=r"(vbr_val)); + trap_registers.vbr = vbr_val; + + /* Get excode for command loop call, user access */ + asm("stc r2_bank, %0":"=r"(excep_code)); + kgdb_excode = excep_code; + + /* Other interesting environment items for reference */ + asm("stc r6_bank, %0":"=r"(kgdb_g_imask)); + kgdb_current = current; + kgdb_trapa_val = trapa_value; + kgdb_tregs = regs; + + /* Act on the exception */ + kgdb_command_loop(excep_code >> 5, trapa_value); + + kgdb_current = NULL; + + /* Copy back the (maybe modified) registers */ + for (count = 0; count < 16; count++) + regs->regs[count] = trap_registers.regs[count]; + regs->pc = trap_registers.pc; + regs->pr = trap_registers.pr; + regs->sr = trap_registers.sr; + regs->gbr = trap_registers.gbr; + regs->mach = trap_registers.mach; + regs->macl = trap_registers.macl; + + vbr_val = trap_registers.vbr; + asm("ldc %0, vbr": :"r"(vbr_val)); + + return; +} + +/* Trigger a breakpoint by function */ +void breakpoint(void) +{ + if (!kgdb_enabled) { + kgdb_enabled = 1; + kgdb_init(); + } + BREAKPOINT(); +} + +/* Initialise the KGDB data structures and serial configuration */ +int kgdb_init(void) +{ + if (!kgdb_enabled) + return 1; + + in_nmi = 0; + kgdb_nofault = 0; + stepped_opcode = 0; + kgdb_in_gdb_mode = 0; + + /* Set up for serial comms */ + if (kgdb_serial_setup == NULL) { + KGDB_PRINTK("no serial init function!!\n"); + return -1; + } + + if (kgdb_serial_setup() != 0) { + KGDB_PRINTK("serial setup error\n"); + return -1; + } + + /* Init ptr to exception handler */ + kgdb_debug_hook = kgdb_handle_exception; + kgdb_bus_err_hook = kgdb_handle_bus_error; + + /* Enter kgdb now if requested, or just report init done */ + if (kgdb_halt) { + kgdb_in_gdb_mode = 1; + put_debug_char('+'); + breakpoint(); + } + else + { + KGDB_PRINTK("stub is initialized.\n"); + } + + return 0; +} + +/* Make function available for "user messages"; console will use it too. */ + +char gdbmsgbuf[BUFMAX]; +#define MAXOUT ((BUFMAX-2)/2) + +static void kgdb_msg_write(const char *s, unsigned count) +{ + int i; + int wcount; + char *bufptr; + + /* 'O'utput */ + gdbmsgbuf[0] = 'O'; + + /* Fill and send buffers... */ + while (count > 0) { + bufptr = gdbmsgbuf + 1; + + /* Calculate how many this time */ + wcount = (count > MAXOUT) ? MAXOUT : count; + + /* Pack in hex chars */ + for (i = 0; i < wcount; i++) + bufptr = pack_hex_byte(bufptr, s[i]); + *bufptr = '\0'; + + /* Move up */ + s += wcount; + count -= wcount; + + /* Write packet */ + put_packet(gdbmsgbuf); + } +} + +static void kgdb_to_gdb(const char *s) +{ + kgdb_msg_write(s, strlen(s)); +} + +#ifdef CONFIG_SH_KGDB_CONSOLE +void kgdb_console_write(struct console *co, const char *s, unsigned count) +{ + /* Bail if we're not talking to GDB */ + if (!kgdb_in_gdb_mode) + return; + + kgdb_msg_write(s, count); +} +#endif diff -urN linux-2.4.21/arch/sh/kernel/led_se.c linux-2.4.22/arch/sh/kernel/led_se.c --- linux-2.4.21/arch/sh/kernel/led_se.c 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/led_se.c 2003-08-25 04:44:40.000000000 -0700 @@ -10,7 +10,14 @@ */ #include + +#ifdef CONFIG_SH_7751_SOLUTION_ENGINE +#include +#elif defined(CONFIG_SH_MOBILE_SOLUTION_ENGINE) +#include +#else #include +#endif static void mach_led(int position, int value) { diff -urN linux-2.4.21/arch/sh/kernel/mach_7751se.c linux-2.4.22/arch/sh/kernel/mach_7751se.c --- linux-2.4.21/arch/sh/kernel/mach_7751se.c 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/mach_7751se.c 2003-08-25 04:44:40.000000000 -0700 @@ -18,7 +18,7 @@ #include -void heartbeat_7751se(void); +void heartbeat_se(void); void setup_7751se(void); void init_7751se_IRQ(void); @@ -67,7 +67,7 @@ mv_init_arch: setup_7751se, mv_init_irq: init_7751se_IRQ, #ifdef CONFIG_HEARTBEAT - mv_heartbeat: heartbeat_7751se, + mv_heartbeat: heartbeat_se, #endif mv_rtc_gettimeofday: sh_rtc_gettimeofday, diff -urN linux-2.4.21/arch/sh/kernel/mach_hs7729pci.c linux-2.4.22/arch/sh/kernel/mach_hs7729pci.c --- linux-2.4.21/arch/sh/kernel/mach_hs7729pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/mach_hs7729pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,81 @@ +/* + * linux/arch/sh/kernel/mach_hs7729pci.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Hitachi Semiconductor ans Devices HS7729PCI + */ + +#include +#include + +#include +#include +#include + +#include + +void setup_hs7729pci(void); +void init_hs7729pci_IRQ(void); + + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_hs7729pci __initmv = { + mv_name: "HS7729PCI", + +#if defined(__SH4__) + mv_nr_irqs: 48, +#elif defined(CONFIG_CPU_SUBTYPE_SH7708) + mv_nr_irqs: 32, +#elif defined(CONFIG_CPU_SUBTYPE_SH7709) + mv_nr_irqs: 61, +#endif + + mv_inb: hs7729pci_inb, + mv_inw: hs7729pci_inw, + mv_inl: hs7729pci_inl, + mv_outb: hs7729pci_outb, + mv_outw: hs7729pci_outw, + mv_outl: hs7729pci_outl, + + mv_inb_p: hs7729pci_inb_p, + mv_inw_p: hs7729pci_inw, + mv_inl_p: hs7729pci_inl, + mv_outb_p: hs7729pci_outb_p, + mv_outw_p: hs7729pci_outw, + mv_outl_p: hs7729pci_outl, + + mv_insb: hs7729pci_insb, + mv_insw: hs7729pci_insw, + mv_insl: hs7729pci_insl, + mv_outsb: hs7729pci_outsb, + mv_outsw: hs7729pci_outsw, + mv_outsl: hs7729pci_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_ioremap: hs7729pci_ioremap, + mv_iounmap: hs7729pci_iounmap, + + mv_isa_port2addr: hs7729pci_isa_port2addr, + + mv_init_arch: setup_hs7729pci, + mv_init_irq: init_hs7729pci_IRQ, + + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, + + mv_hw_hs7729pci: 1, +}; +ALIAS_MV(hs7729pci) diff -urN linux-2.4.21/arch/sh/kernel/mach_keywest.c linux-2.4.22/arch/sh/kernel/mach_keywest.c --- linux-2.4.21/arch/sh/kernel/mach_keywest.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/mach_keywest.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,70 @@ +/* + * linux/arch/sh/kernel/mach_keywest.c + * + * Machine vector for HSA KeyWest Evaluiation board + * + * Copyright (C) 2001 Lineo, Japan + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * The Machine Vector + */ +extern void heartbeat_keywest(void); +extern void setup_keywest(void); +extern void init_keywest_IRQ(void); + +struct sh_machine_vector mv_keywest __initmv = { + mv_name: "Key West", + mv_nr_irqs: NR_IRQS, // Defined in + mv_inb: keywest_inb, + mv_inw: keywest_inw, + mv_inl: keywest_inl, + mv_outb: keywest_outb, + mv_outw: keywest_outw, + mv_outl: keywest_outl, + + mv_inb_p: keywest_inb_p, + mv_inw_p: keywest_inw, + mv_inl_p: keywest_inl, + mv_outb_p: keywest_outb_p, + mv_outw_p: keywest_outw, + mv_outl_p: keywest_outl, + + mv_insb: keywest_insb, + mv_insw: keywest_insw, + mv_insl: keywest_insl, + mv_outsb: keywest_outsb, + mv_outsw: keywest_outsw, + mv_outsl: keywest_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_ioremap: generic_ioremap, + mv_iounmap: generic_iounmap, + + mv_isa_port2addr: keywest_isa_port2addr, + mv_irq_demux: keywest_irq_demux, + + mv_init_arch: setup_keywest, + mv_init_irq: init_keywest_IRQ, + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, + +}; +ALIAS_MV(keywest) diff -urN linux-2.4.21/arch/sh/kernel/mach_shmse.c linux-2.4.22/arch/sh/kernel/mach_shmse.c --- linux-2.4.21/arch/sh/kernel/mach_shmse.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/mach_shmse.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,71 @@ +/* + * linux/arch/sh/kernel/mach_shmse.c + * + * Copyright (C) 2003 Takashi Kusuda + * Based largely on mach_se.c + * + * Machine vector for SH-Mobile SolutionEngine + */ + +#include +#include + +#include +#include +#include + +#include + +void heartbeat_se(void); +void setup_shmse(void); +void init_shmse_IRQ(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_shmse __initmv = { + mv_name: "SH-Mobile SE", + + mv_nr_irqs: 109, + + mv_inb: shmse_inb, + mv_inw: shmse_inw, + mv_inl: shmse_inl, + mv_outb: shmse_outb, + mv_outw: shmse_outw, + mv_outl: shmse_outl, + + mv_inb_p: shmse_inb_p, + mv_inw_p: shmse_inw, + mv_inl_p: shmse_inl, + mv_outb_p: shmse_outb_p, + mv_outw_p: shmse_outw, + mv_outl_p: shmse_outl, + + mv_insb: shmse_insb, + mv_insw: shmse_insw, + mv_insl: shmse_insl, + mv_outsb: shmse_outsb, + mv_outsw: shmse_outsw, + mv_outsl: shmse_outsl, + + mv_readb: shmse_readb, + mv_readw: shmse_readw, + mv_readl: shmse_readl, + mv_writeb: shmse_writeb, + mv_writew: shmse_writew, + mv_writel: shmse_writel, + + mv_ioremap: generic_ioremap, + mv_iounmap: generic_iounmap, + + mv_init_arch: setup_shmse, + mv_init_irq: init_shmse_IRQ, +#ifdef CONFIG_HEARTBEAT + mv_heartbeat: heartbeat_se, +#endif + + mv_hw_shmse: 1, +}; +ALIAS_MV(shmse) diff -urN linux-2.4.21/arch/sh/kernel/mach_snapgear.c linux-2.4.22/arch/sh/kernel/mach_snapgear.c --- linux-2.4.21/arch/sh/kernel/mach_snapgear.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/mach_snapgear.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,82 @@ +/* + * linux/arch/sh/kernel/mach_snapgear.c + * + * Minor tweak of mach_se.c file to reference SnapGear items. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Hitachi 7751 SolutionEngine + */ + +#include +#include + +#include +#include +#include + +#include + +extern void setup_snapgear(void); +extern void init_snapgear_IRQ(void); + +extern void snapgear_rtc_gettimeofday(struct timeval *tv); +extern int snapgear_rtc_settimeofday(const struct timeval *tv); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_snapgear __initmv = { + mv_name: "SnapGear", + + mv_nr_irqs: 72, + + mv_inb: snapgear_inb, + mv_inw: snapgear_inw, + mv_inl: snapgear_inl, + mv_outb: snapgear_outb, + mv_outw: snapgear_outw, + mv_outl: snapgear_outl, + + mv_inb_p: snapgear_inb_p, + mv_inw_p: snapgear_inw, + mv_inl_p: snapgear_inl, + mv_outb_p: snapgear_outb_p, + mv_outw_p: snapgear_outw, + mv_outl_p: snapgear_outl, + + mv_insb: snapgear_insb, + mv_insw: snapgear_insw, + mv_insl: snapgear_insl, + mv_outsb: snapgear_outsb, + mv_outsw: snapgear_outsw, + mv_outsl: snapgear_outsl, + + mv_readb: snapgear_readb, + mv_readw: snapgear_readw, + mv_readl: snapgear_readl, + mv_writeb: snapgear_writeb, + mv_writew: snapgear_writew, + mv_writel: snapgear_writel, + + mv_ioremap: generic_ioremap, + mv_iounmap: generic_iounmap, + + mv_isa_port2addr: snapgear_isa_port2addr, + + mv_init_arch: setup_snapgear, + mv_init_irq: init_snapgear_IRQ, + +#ifndef CONFIG_RTC + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, +#else + mv_rtc_gettimeofday: snapgear_rtc_gettimeofday, + mv_rtc_settimeofday: snapgear_rtc_settimeofday, +#endif + + mv_hw_snapgear: 1, +}; +ALIAS_MV(snapgear) diff -urN linux-2.4.21/arch/sh/kernel/pci-sd0001.c linux-2.4.22/arch/sh/kernel/pci-sd0001.c --- linux-2.4.21/arch/sh/kernel/pci-sd0001.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/pci-sd0001.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,795 @@ +/* + * $Id: pci-sd0001.c,v 1.1.2.1 2003/06/24 08:40:50 dwmw2 Exp $ + * + * linux/arch/sh/kernel/pci-sd0001.c + * + * Support Hitachi Semcon SD0001 SH3 PCI Host Bridge . + * + * + * Copyright (C) 2000 Hitachi ULSI Systems Co., Ltd. + * All Rights Reserved. + * + * Copyright (C) 2001-2003 Red Hat, Inc. + * + * Authors: Masayuki Okada (macha@adc.hitachi-ul.co.jp) + * David Woodhouse (dwmw2@redhat.com) + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "pci-sd0001.h" + +spinlock_t sd0001_indirect_lock = SPIN_LOCK_UNLOCKED; + +int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags); + + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif +#define SD0001_INDIR_TIME 1000000 /* ´ÖÀÜ¥¢¥¯¥»¥¹´°Î»ÂÔ¤ÁºÇÂç²ó¿ô */ + +static char *err_int_msg [] = { + "Detect Master Abort", + "Assert Master Abort", + "Detect Target Abort", + "Assert Target Abort", + "Assert PERR", + "Detect PERR", + "Detect SERR", + "Asster SERR", + "Bus Timeout", + "Bus Retry Over", +}; + +/* + * PCI¥Ð¥¹¤Î¥Ð¥¹¥ê¥»¥Ã¥È¼Â¹Ô + */ +static void sd0001_bus_reset(void) +{ + sd0001_writel(SD0001_RST_BUSRST, RESET); + + udelay(64); + + sd0001_writel(0, RESET); +} + +/* + * SD0001¥½¥Õ¥È¥ê¥»¥Ã¥È + */ +static void sd0001_chip_reset(void) +{ + sd0001_writel(SD0001_RST_SWRST, RESET); +} + + +#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +static void +sd0001_int_pcierr (int irq, void *dummy, struct pt_regs *regs) +{ + static char errStrings[30*12]; + u32 int_status; + u32 mask; + u32 indrct_flg; + int reset_fatal; + int i; + int to_cnt = 0; + unsigned long flags; + + spin_lock_irqsave(&sd0001_indirect_lock, flags); + + if ((int_status = (sd0001_readl(INT_STS1) & SD0001_INT_BUSERR))) { + DBG("pciIntErrorHandle Called: status 0x%08x\n", int_status, 0, 0, 0, 0, 0); + + for (mask = 1 << 20, i = 0, errStrings[0] = '\0'; i < 11; i++, mask <<= 1) { + if (int_status & mask) { +/* err_int_cnt[i] ++; */ + strcat(errStrings, err_int_msg[i]); + strcat(errStrings, ", "); + } + } + i = strlen(errStrings); + errStrings[i-2]= '\0'; + + printk(KERN_ERR "PCI Bus 0x%08x(%s) Error\n", int_status, errStrings); + + reset_fatal = 0; + + if (int_status & (SD0001_INT_SSERR|SD0001_INT_RPERR + |SD0001_INT_SPERR|SD0001_INT_STABT + |SD0001_INT_RTABT|SD0001_INT_RMABT)) { + /* Clear of Configration Status Bits */ + sd0001_writel(4, INDIRECT_ADR); + sd0001_writel(0xf9000000, INDIRECT_DATA); + sd0001_writel(0x000c0002, INDIRECT_CTL); + to_cnt = 0; + while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG) + && (to_cnt++ < SD0001_INDIR_TIME)) + ; + + + if (indrct_flg & SD0001_INDRCTF_INDFLG) { + panic("SD0001 Fatal Error 1\n"); + } else { + if (indrct_flg & SD0001_INDRCTF_MABTRCV) { + sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL); + reset_fatal = -1; + } + } + int_status = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR; + } + + if (int_status != 0) { + sd0001_writel(int_status, INT_STS1); /* ³ä¤ê¹þ¤ß¥¯¥ê¥¢ */ + + if (reset_fatal || (sd0001_readl(INT_STS2) & SD0001_INT_BUSERR)) { + printk(KERN_CRIT "Fatal Error:SD0001 PCI Status Can't Clear 0x%08x\n", + int_status & 0x7fffffff); + sd0001_writel(sd0001_readl(INT_ENABLE) & ~int_status, INT_ENABLE); + /* Masked Error Interrupt */ + } + } + } + spin_unlock_irqrestore(&sd0001_indirect_lock, flags); +} + + +static inline u32 convert_dev_to_addr (struct pci_dev *dev, u32 reg) +{ + return (SD0001_CONFIG_ADDR_EN + | (dev->bus->number << 16) + | ((dev->devfn & 0xff) << 8) + | (reg & 0xff) + | ((dev->bus->number)?0x00:0x01)); +} + + +static int sd0001_indirect_RW (u32 addr, u32 cmd, u32 be, + u32 rw, u32 *data) +{ + u32 indrct_flg; + u32 int_sts; + u32 to_cnt = 0; + int st = PCIBIOS_SUCCESSFUL; + unsigned long flags; + + spin_lock_irqsave(&sd0001_indirect_lock, flags); + if ((cmd & SD0001_INDRCTC_CMD_MASK) == SD0001_INDRCTC_CMD_MEMR + || (cmd & SD0001_INDRCTC_CMD_MASK) == SD0001_INDRCTC_CMD_MEMW) + sd0001_writel(addr & 0xfffffffc, INDIRECT_ADR); + else + sd0001_writel(addr, INDIRECT_ADR); + + if (rw == SD0001_INDRCTC_IOWT || rw == SD0001_INDRCTC_COWT) + sd0001_writel(*data, INDIRECT_DATA); + + sd0001_writel(be | cmd | rw , INDIRECT_CTL); + + while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG) + && (to_cnt++ < SD0001_INDIR_TIME)); + + int_sts = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR; + + if (indrct_flg & SD0001_INDRCTF_INDFLG) { /* ¥¿¥¤¥à¥¢¥¦¥È */ + printk("SD0001 Fatal Error 2\n"); + spin_unlock_irqrestore(&sd0001_indirect_lock, flags); + + return PCIBIOS_DEVICE_NOT_FOUND; + } + + if (int_sts != 0 || (indrct_flg & SD0001_INDRCTF_MABTRCV) != 0) { + if ((st = (indrct_flg & SD0001_INDRCTF_MABTRCV) >> 19) != 0) { + sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL); + st |= 0x80000000; + } + + st |= 0x80000000 | int_sts; + + if ((int_sts & (SD0001_INT_SSERR|SD0001_INT_RPERR + |SD0001_INT_SPERR|SD0001_INT_STABT + |SD0001_INT_RTABT|SD0001_INT_RMABT)) + || (indrct_flg & SD0001_INDRCTF_MABTRCV)) { + /* Clear of Configration Status Bits */ + sd0001_writel(4, INDIRECT_ADR); + sd0001_writel(0xf9000000, INDIRECT_DATA); + sd0001_writel(0x000c0002, INDIRECT_CTL); + + to_cnt = 0; + while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG) + && (to_cnt++ < SD0001_INDIR_TIME)); + + if (indrct_flg & SD0001_INDRCTF_INDFLG) { /* ¥¿¥¤¥à¥¢¥¦¥È */ + panic("SD0001 Fatal Error 3\n"); + } + + if (indrct_flg & SD0001_INDRCTF_MABTRCV) { + + sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL); + } + } + + printk(KERN_ERR "PCI Bus Error: status 0x%08x\n", st); + + if ((int_sts = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR) != 0) { + sd0001_writel(int_sts, INT_STS1); /* ³ä¤ê¹þ¤ß¥¯¥ê¥¢ */ + + if (sd0001_readl(INT_STS2) & SD0001_INT_BUSERR) { + printk(KERN_CRIT "Fatal Error:SD0001 PCI Status Can't Clear 0x%08x\n", + sd0001_readl(INT_STS2) & SD0001_INT_BUSERR); + sd0001_writel(sd0001_readl(INT_ENABLE) & ~int_sts, INT_ENABLE); /* Masked Error Interrupt */ + } + } + + *data = 0xffffffff; + } else { + if (rw != SD0001_INDRCTC_IOWT && rw != SD0001_INDRCTC_COWT) + *data = sd0001_readl(INDIRECT_DATA); + } + + spin_unlock_irqrestore(&sd0001_indirect_lock, flags); + return st; +} + +static inline +int sd0001_config_RW (struct pci_dev *dev, u32 reg, u32 be, u32 rw, u32 *data) +{ + u32 reg_addr = convert_dev_to_addr(dev, reg); + + if (reg_addr == 0) { + *data = 0xffffffff; + return PCIBIOS_SUCCESSFUL; + } + + return sd0001_indirect_RW (reg_addr, 0, be, rw, data); + +} + + +static int sd0001_read_config_byte(struct pci_dev *dev, int reg, u8 *val) +{ + int offset; + u32 be; + int re; + union { + u32 ldata; + u8 bdata[4]; + } work; + + be = SD0001_INDRCTC_BE_BYTE << (reg & 0x03); + re = sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_CORD, &work.ldata); + +#if __LITTLE_ENDIAN__ + offset = reg & 0x03; +#else /* __LITTLE_ENDIAN__ */ + offset = 3 - (reg & 0x03); +#endif /* __LITTLE_ENDIAN__ */ + *val = work.bdata[offset]; + + return re; + +} + + +static int sd0001_read_config_word(struct pci_dev *dev, int reg, u16 *val) +{ + int offset; + u32 be; + int re; + union { + u32 ldata; + u16 wdata[2]; + } work; + + be = SD0001_INDRCTC_BE_WORD << (reg & 0x02); + + re = sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_CORD, &work.ldata); + +#if __LITTLE_ENDIAN__ + offset = (reg >> 1) & 0x01; +#else /* __LITTLE_ENDIAN__ */ + offset = 1 - ((reg >> 1) & 0x01); +#endif /* __LITTLE_ENDIAN__ */ + + *val = work.wdata[offset]; + + return re; +} + + +static int sd0001_read_config_dword(struct pci_dev *dev, int reg, u32 *val) +{ + return sd0001_config_RW (dev, reg, SD0001_INDRCTC_BE_LONG, + SD0001_INDRCTC_CORD, val); +} + +static int sd0001_write_config_byte (struct pci_dev *dev, int reg, u8 val) +{ + int offset; + u32 be; + union { + u32 ldata; + u8 bdata[4]; + } work; + + be = SD0001_INDRCTC_BE_BYTE << (reg & 0x03); +#if __LITTLE_ENDIAN__ + offset = reg & 0x03; +#else /* __LITTLE_ENDIAN__ */ + offset = 3 - (reg & 0x03); +#endif /* __LITTLE_ENDIAN__ */ + work.bdata[offset] = val; + + return sd0001_config_RW(dev, reg, be, SD0001_INDRCTC_COWT, &work.ldata); + +} + + +static int sd0001_write_config_word (struct pci_dev *dev, int reg, u16 val) +{ + int offset; + u32 be; + union { + u32 ldata; + u16 wdata[2]; + } work; + + + be = SD0001_INDRCTC_BE_WORD << (reg & 0x02); +#if __LITTLE_ENDIAN__ + offset = (reg >> 1) & 0x01; +#else /* __LITTLE_ENDIAN__ */ + offset = 1 - ((reg >> 1) & 0x01); +#endif /* __LITTLE_ENDIAN__ */ + + work.wdata[offset] = val; + + return sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_COWT, &work.ldata); + +} + + +static int sd0001_write_config_dword (struct pci_dev *dev, int reg, u32 val) +{ + return sd0001_config_RW (dev, reg, SD0001_INDRCTC_BE_LONG, SD0001_INDRCTC_COWT, &val); +} + +static struct pci_ops sd0001_pci_ops = +{ + .read_byte = sd0001_read_config_byte, + .read_word = sd0001_read_config_word, + .read_dword = sd0001_read_config_dword, + .write_byte = sd0001_write_config_byte, + .write_word = sd0001_write_config_word, + .write_dword = sd0001_write_config_dword +}; + +int __init pci_setup_sd0001 (void) +{ + sd0001_writel(0, INT_ENABLE); /* all Interrupt = Mask */ + + sd0001_bus_reset(); + + /* + * PCI¥Ð¥¹À©¸æ¤ÎÆ°ºî¥â¡¼¥É(MCW0¥ì¥¸¥¹¥¿)ÀßÄê + * ¡¦PCI¥Ð¥¹¤Î¥ê¥È¥é¥¤²ó¿ô : ̵¸Â²ó + * ¡¦¥Ð¥¹¥°¥é¥ó¥É¤ÎÍ޻ߤʤ· + */ +#if __LITTLE_ENDIAN__ + sd0001_writel(0x0000, PCI_CTL); +#else + sd0001_writel(SD0001_CTL_MASTER_SWAP | SD0001_CTL_PCI_EDCONV, PCI_CTL); +#endif + sd0001_writel(0, PCI_IO_OFFSET); + sd0001_writel(PCIBIOS_MIN_MEM, PCI_MEM_OFFSET); + + + if (request_irq(CONFIG_PCI_SD0001_IRQ, &sd0001_int_pcierr, SA_SHIRQ, "PCI Bus Error", NULL)) + printk(KERN_ERR "Can't Setup PCI Bus Error Interrupt\n"); + + /* FIXME: Enable INT[ABCD] only when devices actually want them. + We should probably demux them so they appear to the kernel as + separate IRQs */ + sd0001_writel(SD0001_INT_INTEN|SD0001_INT_BUSERR + |SD0001_INT_INTD|SD0001_INT_INTC|SD0001_INT_INTB + |SD0001_INT_INTA, INT_ENABLE); + + + return PCIBIOS_SUCCESSFUL; +} + + +void __init +pcibios_fixup_pbus_ranges(struct pci_bus * bus, + struct pbus_set_ranges_data * ranges) +{ + ranges->io_start -= bus->resource[0]->start; + ranges->io_end -= bus->resource[0]->start; + ranges->mem_start -= bus->resource[1]->start; + ranges->mem_end -= bus->resource[1]->start; +} + + +static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) +{ + return PCI_SLOT(dev->devfn); +} + +static int __init sd0001_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + return CONFIG_PCI_SD0001_IRQ; +} + +void __init pcibios_init(void) +{ + printk(KERN_NOTICE "Linux/SH SD0001 PCI Initialise\n"); + + ioport_resource.end = 0xffff; + iomem_resource.end = 0xfeffffff; + + pci_setup_sd0001(); + pci_scan_bus(0, &sd0001_pci_ops, NULL); + + pci_assign_unassigned_resources(); + + pci_fixup_irqs(no_swizzle, sd0001_map_irq); +} + +char * __init pcibios_setup(char *str) +{ + return str; +} + +extern unsigned long memory_start, memory_end; + +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + struct list_head *list; + + list_for_each(list, &bus->devices) { + struct pci_dev *dev = pci_dev_b(list); + u16 cmd; + if (dev->class >> 8 == PCI_CLASS_BRIDGE_HOST) { + memset(&dev->resource[1], 0, sizeof(struct resource)); + dev->resource[1].start = __pa(memory_start); + dev->resource[1].end = __pa(memory_end)-1; + dev->resource[1].flags = IORESOURCE_MEM|IORESOURCE_PREFETCH; + dev->resource[1].name = "PCI Host RAM"; + request_resource(&iomem_resource, &dev->resource[1]); + +#if 0 + printk("res1 (@%p) %s %08lx %08lx %x %p %p %p\n", + &dev->resource[1], + dev->resource[1].name, + dev->resource[1].start, + dev->resource[1].end, + dev->resource[1].flags, + dev->resource[1].parent, + dev->resource[1].sibling, + dev->resource[1].child); +#endif + pcibios_update_resource(dev, bus->resource[1], + &dev->resource[1], 1); + + cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config_word(dev, PCI_COMMAND, cmd); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); + } + } +} + + + +/* Add future fixups here... */ +struct pci_fixup pcibios_fixups[] = { + { 0 } +}; + + + /* + * Mapping for PCI Devices. + * The SD0001 has a 48MiB window onto the PCI memory space, mapped + * into the CPU's address space at 0xb1000000-0xb3ffffff. + * The range of the PCI space which is accessible is controlled + * by the SD0001's PCI_MEM_OFFSET register, which has a granularity + * of 64MiB. + * + * As far as I can tell from the little I can understand of + * the SD0001 documentation and from the behaviour of the + * device, you have a 48MiB window which can only be moved + * with 64MiB granularity. Therefore to the best of my + * knowledge, you cannot access any PCI memory address where + * ( & 0x03000000) == 0x03000000, except by going + * indirectly through the PCI bridge like we do for configuration + * and I/O cycles. + * + * Hopefully, this is untrue and there's some way of doing it that + * I just don't know because I can't read the docs. For now, we + * allow only access to the first 48MiB of PCI memory space. + * + * In addition to that joy, it appears that when accessing PCI + * memory space directly, the SD0001 swaps address lines #21 + * and #22, hence the macro below to swap addresses back + * again. + * + * Me and my baseball bat want a quiet word with someone. + * + * dwmw2. + */ + +#define unmunge(x) (((x) & ~0x00300000) | ( ((x)&0x00100000) << 1) | ( ((x)&0x00200000) >> 1)) + +void *sd0001_ioremap(unsigned long phys_addr, unsigned long size) +{ + unsigned long offset; + + if ((phys_addr & 0xFFF00000) == ((phys_addr+size) & 0xFFF00000)) { + /* It fits within a single mebibyte we can still use the + directly-mapped region... */ + return (void *)(SD0001_MEM_BASE-(PCIBIOS_MIN_MEM&0xfc000000)+unmunge(phys_addr)); + } + + /* It crosses a mebibyte boundary and hence we have to + play VM tricks to make the region which is physically + contiguous on the PCI bus but not physically contiguous + on the SH3 bus appear virtually contiguous to the kernel. + Got that? Did I mention my baseball bat yet? */ + void * addr; + struct vm_struct * area; + + offset = phys_addr & ~PAGE_MASK; + phys_addr &= PAGE_MASK; + size = PAGE_ALIGN(phys_addr + size - 1) - phys_addr; + + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + addr = area->addr; + + phys_addr += SD0001_MEM_BASE; + while (size) { + unsigned long this_size; + + this_size = 0x100000 - (phys_addr & 0xfffff); + this_size = min(this_size, size); + + if (remap_area_pages(VMALLOC_VMADDR(addr), + unmunge(phys_addr), this_size, + _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_FLAGS_HARD)) { + vfree(area->addr); + return NULL; + } + size -= this_size; + phys_addr += this_size; + addr += this_size; + } + return (void *) (offset + (char *)area->addr); +} + +void sd0001_iounmap(void *addr) +{ + if ((unsigned long)addr >= VMALLOC_START && + (unsigned long)addr < VMALLOC_END) + vfree((void *)((unsigned long)addr & ~PAGE_MASK)); +} + + +static void sd0001_indirect_access_wait(unsigned long i) +{ + + while((sd0001_readl(INDIRECT_STS) & SD0001_INDRCTF_INDFLG) + && --i) + ; + + if (i == 0) { + printk("##### Long Indirect access wait #####\n"); + mdelay(20); + } +} + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +/* PCI IO read long word cycle */ +unsigned long sd0001_inl(unsigned long port) +{ + return *(volatile unsigned long *) (SD0001_IO_BASE+port); +} +void sd0001_outl(unsigned long value, unsigned long port) +{ + *(volatile unsigned long *)(SD0001_IO_BASE+port) = value; +} + +/* The SD0001 doesn't correctly handle byte enables for sub-word + accesses, so we have to do it indirectly like we do configuration + cycles */ + +/* PCI IO read byte cycle */ +unsigned char sd0001_inb(unsigned long port) +{ + unsigned long work, val, byte_e; + unsigned long flags; + + spin_lock_irqsave(&sd0001_indirect_lock, flags); + val = 0; + byte_e = 0x00010000; + work = (port & 0x00000003); + byte_e <<= work; + + port &= 0xFFFFFFFC; + sd0001_writel(port, INDIRECT_ADR); + sd0001_writel(0x00008204 | byte_e, INDIRECT_CTL); /* I/O read cycle */ + sd0001_indirect_access_wait(100); + val = sd0001_readl(INDIRECT_DATA); + + val >>= (work*8); + val &= 0x000000FF; + + spin_unlock_irqrestore(&sd0001_indirect_lock, flags); + + return val; +} + +/* PCI IO write byte cycle */ +void sd0001_outb(unsigned char value, unsigned long port) +{ + unsigned long work, data, byte_e; + unsigned long flags; + + spin_lock_irqsave(&sd0001_indirect_lock, flags); + byte_e = 0x00010000; + work = (port & 0x00000003); + byte_e <<= work; + + data = value; + data <<= (work*8); + + port &= 0xFFFFFFFC; + sd0001_writel(data, INDIRECT_DATA); + sd0001_writel(port, INDIRECT_ADR); + sd0001_writel((0x00008308 | byte_e), INDIRECT_CTL); /* I/O write cycle */ + sd0001_indirect_access_wait(100); + + spin_unlock_irqrestore(&sd0001_indirect_lock, flags); +} + +/* PCI IO read word cycle */ +unsigned short sd0001_inw(unsigned long port) +{ + unsigned long work, val, byte_e; + unsigned long flags; + + spin_lock_irqsave(&sd0001_indirect_lock, flags); + val = 0; + byte_e = 0x00030000; + work = (port & 0x00000003); + byte_e <<= (work & 0x00000002); + work >>= 1; + + port &= 0xFFFFFFFC; + sd0001_writel(port, INDIRECT_ADR); + sd0001_writel((0x00008204 | byte_e), INDIRECT_CTL); /* I/O read cycle */ + sd0001_indirect_access_wait(100); + val = sd0001_readl(INDIRECT_DATA) ; + + val >>= (work*16); + val &= 0x0000FFFF; + + spin_unlock_irqrestore(&sd0001_indirect_lock, flags); + + return val; +} + +/* PCI IO write word cycle */ +void sd0001_outw(unsigned short value, unsigned long port) +{ + unsigned long work, data, byte_e; + unsigned long flags; + + spin_lock_irqsave(&sd0001_indirect_lock, flags); + byte_e = 0x00030000; + work = (port & 0x00000003); + byte_e <<= (work & 0x00000002); + work >>= 1; + + port &= 0xFFFFFFFC; + data = value; + data <<= (work*16); + + sd0001_writel(data, INDIRECT_DATA); + sd0001_writel(port, INDIRECT_ADR); + sd0001_writel((0x00008308 | byte_e), INDIRECT_CTL); /* I/O write cycle */ + sd0001_indirect_access_wait(100); + spin_unlock_irqrestore(&sd0001_indirect_lock, flags); +} + +void sd0001_insb(unsigned long port, void *addr, unsigned long count) +{ + + while (count--) + *((unsigned char *) addr)++ = (unsigned char)sd0001_inb(port); +} + +void sd0001_insw(unsigned long port, void *addr, unsigned long count) +{ + + while (count--) + *((unsigned short *) addr)++ = (unsigned short)sd0001_inw(port); +} + +void sd0001_insl(unsigned long port, void *addr, unsigned long count) +{ + + while (count--) + *((unsigned long *) addr)++ = sd0001_inl(port); +} + +void sd0001_outsb(unsigned long port, const void *addr, unsigned long count) +{ + + while (count--) + sd0001_outb(*((unsigned char *)addr)++, port); +} + +void sd0001_outsw(unsigned long port, const void *addr, unsigned long count) +{ + + while (count--) + sd0001_outw(*((unsigned short *)addr)++, port); +} + +void sd0001_outsl(unsigned long port, const void *addr, unsigned long count) +{ + + while (count--) + sd0001_outl(*((unsigned long *)addr)++, port); +} + +unsigned char sd0001_inb_p(unsigned long port) +{ + unsigned long v; + + v = sd0001_inb(port); + delay(); + return v; +} + +void sd0001_outb_p(unsigned char value, unsigned long port) +{ + + sd0001_outb(value, port); + delay(); +} diff -urN linux-2.4.21/arch/sh/kernel/pci-sd0001.h linux-2.4.22/arch/sh/kernel/pci-sd0001.h --- linux-2.4.21/arch/sh/kernel/pci-sd0001.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/pci-sd0001.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,248 @@ +/* + * $Id: pci-sd0001.h,v 1.1.2.1 2003/06/24 08:40:50 dwmw2 Exp $ + * + * linux/arch/sh/kernel/pci_sd0001.h + * + * Support Hitachi Semcon SD0001 SH3 PCI Host Bridge . + * + * + * Copyright (C) 2000 Masayuki Okada (macha@adc.hitachi-ul.co.jp) + * Hitachi ULSI Systems Co., Ltd. + * + * This program is free software; you can redistribute 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 + * + * + * + * Revision History + * ---------------- + * + */ + +/* + * SD0001 PCI¥Ö¥ê¥Ã¥¸¡¡¥ì¥¸¥¹¥¿¡¢¥Ó¥Ã¥ÈÄêµÁ + */ + + +#ifndef __PCI_SD0001_H +#define __PCI_SD0001_H + +#define SD0001_IO_BASE (P2SEGADDR(CONFIG_PCI_SD0001_BASE)+0x00800000) +#define SD0001_MEM_BASE (P2SEGADDR(CONFIG_PCI_SD0001_BASE)+0x01000000) + +#define SD0001_REG(x) ((volatile u32 *)P2SEGADDR(CONFIG_PCI_SD0001_BASE + (x))) + +#define sd0001_writel(value, reg) do { *(SD0001_REG(SD0001_REG_##reg)) = value; } while(0) +#define sd0001_readl(reg) (*(SD0001_REG(SD0001_REG_##reg))) + +#define SD0001_REG_REV (0x00) /* PCI Class & Revision Code */ +#define SD0001_REG_RESET (0x08) /* ¥ê¥»¥Ã¥È */ +#define SD0001_REG_SDRAM_CTL (0x10) /* SDRAM ¥â¡¼¥É/À©¸æ */ +#define SD0001_REG_INT_STS1 (0x20) /* ³ä¤ê¹þÍ×°øɽ¼¨ */ +#define SD0001_REG_INT_ENABLE (0x24) /* ³ä¤ê¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_REG_INT_STS2 (0x28) /* ³ä¹þ¤ß¥¹¥Æ¡¼¥¿¥¹ */ +#define SD0001_REG_DMA1_CTL_STS (0x30) /* DMA ¥³¥Þ¥ó¥É & ¥¹¥Æ¡¼¥¿¥¹ */ +#define SD0001_REG_DMA1_SADR (0x34) /* DMA ¥½¡¼¥¹¥¢¥É¥ì¥¹ */ +#define SD0001_REG_DMA1_DADR (0x38) /* DMA ¥Ç¥£¥¹¥Æ¥£¥Í¡¼¥·¥ç¥ó¥¢¥É¥ì¥¹ */ +#define SD0001_REG_DMA1_CNT (0x3c) /* DMA žÁ÷¥Ð¥¤¥È¿ô */ +#define SD0001_REG_DMA2_CTL_STS (0x40) /* DMA ¥³¥Þ¥ó¥É & ¥¹¥Æ¡¼¥¿¥¹ */ +#define SD0001_REG_DMA2_SADR (0x44) /* DMA ¥½¡¼¥¹¥¢¥É¥ì¥¹ */ +#define SD0001_REG_DMA2_DADR (0x48) /* DMA ¥Ç¥£¥¹¥Æ¥£¥Í¡¼¥·¥ç¥ó¥¢¥É¥ì¥¹ */ +#define SD0001_REG_DMA2_CNT (0x4c) /* DMA žÁ÷¥Ð¥¤¥È¿ô */ +#define SD0001_REG_PCI_CTL (0x50) /* PCI¥Ð¥¹Æ°ºî¥â¡¼¥É */ +#define SD0001_REG_PCI_IO_OFFSET (0x58) /* PCIľÀÜI/O¥¢¥¯¥»¥¹¥ª¥Õ¥»¥Ã¥È */ +#define SD0001_REG_PCI_MEM_OFFSET (0x5c) /* PCIľÀÜ¥á¥â¥ê¥¢¥¯¥»¥¹¥ª¥Õ¥»¥Ã¥È */ +#define SD0001_REG_INDIRECT_ADR (0x60) /* PCI Configuration¥ì¥¸¥¹¥¿¥¢¥É¥ì¥¹ */ +#define SD0001_REG_INDIRECT_DATA (0x64) /* PCI Configuration¥Ç¡¼¥¿¥ì¥¸¥¹¥¿ */ +#define SD0001_REG_INDIRECT_CTL (0x68) /* PCI¥Ð¥¹´ÖÀÜ¥¢¥¯¥»¥¹À©¸æ */ +#define SD0001_REG_INDIRECT_STS (0x6c) /* PCI¥Ð¥¹´ÖÀÜ¥¢¥¯¥»¥¹¥¹¥Æ¡¼¥¿¥¹ */ +#define SD0001_REG_AWAKE (0x70) /* AWAKE³ä¹þ¤ß */ +#define SD0001_REG_MAIL (0x74) /* MailÄÌ¿® */ + + +/* + * SD0001 ¥ì¥¸¥¹¥¿¤Î³Æ¥Ó¥Ã¥È¤Îµ¡Ç½¤ÎÄêµÁ + */ +/* MODE ¥ì¥¸¥¹¥¿ */ + +/* RST ¥ì¥¸¥¹¥¿ */ +#define SD0001_RST_SWRST 0x80000000 /* SD0001¤Î¥ê¥»¥Ã¥È */ +#define SD0001_RST_BUSRST 0x40000000 /* PCI¥Ð¥¹¥½¥Õ¥È¥ê¥»¥Ã¥È */ +#define SD0001_RST_MASK 0xc0000000 /* RST¥ì¥¸¥¹¥¿ÀßÄê¥Þ¥¹¥¯ */ + + +/* SH3 SD0001 PCI Devices Space & Mamory Size */ +#define SD0001_PCI_IO_WINDOW 0x00800000 /* PCI I/O¶õ´Ö Window: 8MiB */ +#define SD0001_PCI_MEM_WINDOW 0x03000000 /* PCI MEM¶õ´Ö Window: 48MiB */ +#define SD0001_PCI_WINDOW_SHIFT 22 +#define SD0001_SDRAM_MAX 0x04000000 /* SDMAN¥µ¥¤¥º 64MiB */ + + +/* pci_ctl ¥ì¥¸¥¹¥¿ */ +#define SD0001_CTL_MASTER_SWAP 0x80000000 /* PCI¥Ð¥¹¥Þ¥¹¥¿¡¼Å¾Á÷»þ¤Î + Byte Swap ON */ +#define SD0001_CTL_PCI_EDCONV 0x40000000 /* PCI¥Ç¥Ð¥¤¥¹¥¢¥¯¥»¥¹»þ¤Î + EndianÊÑ´¹ ON */ +#define SD0001_CTL_RETRY_MASK 0x000000f0 /* PCI¥ê¥È¥é¥¤¥ª¡¼¥Ð¸¡½Ð¥«¥¦¥ó¥ÈÃÍ */ +#define SD0001_CTL_NOGNT 0x00000002 /* PCI GNT¿®¹æ¤Îȯ¹ÔÄä»ß */ + +/* SD_MDCTL ¥ì¥¸¥¹¥¿ */ +#define SD0001_SDMD_KIND_MASK 0xc0000000 /* SDRAM ¼ïÊÌ ÀßÄê¥Þ¥¹¥¯*/ +#define SD0001_SDMD_KIND_16 0x00000000 /* SDRAM 16Mbits */ +#define SD0001_SDMD_KIND_64 0x40000000 /* SDRAM 64Mbits */ +#define SD0001_SDMD_KIND_128 0x80000000 /* SDRAM 128Mbits */ +#define SD0001_SDMD_KIND_256 0xc0000000 /* SDRAM 256Mbits */ +#define SD0001_SDMD_SIZE_MASK 0x30000000 /* SDRAM SIZE ÀßÄê¥Þ¥¹¥¯ */ +#define SD0001_SDMD_SIZE_4 0x00000000 /* ¥Ç¡¼¥¿¥Ð¥¹ 4bits */ +#define SD0001_SDMD_SIZE_8 0x10000000 /* ¥Ç¡¼¥¿¥Ð¥¹ 8bits */ +#define SD0001_SDMD_SIZE_16 0x20000000 /* ¥Ç¡¼¥¿¥Ð¥¹ 16bits */ +#define SD0001_SDMD_SIZE_32 0x30000000 /* ¥Ç¡¼¥¿¥Ð¥¹ 32bits */ +#define SD0001_SDMD_REF_MASK 0x0000f000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë ÀßÄê¥Þ¥¹¥¯ */ +#define SD0001_SDMD_REF_DEF 0x00000000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë ¥Ç¥Õ¥©¥ë¥È(128cycles) */ +#define SD0001_SDMD_REF_128 0x00001000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 128cycles */ +#define SD0001_SDMD_REF_256 0x00002000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 256cycles */ +#define SD0001_SDMD_REF_384 0x00003000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 384cycles */ +#define SD0001_SDMD_REF_512 0x00004000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 512cycles */ +#define SD0001_SDMD_REF_640 0x00005000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 640cycles */ +#define SD0001_SDMD_REF_768 0x00006000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 768cycles */ +#define SD0001_SDMD_REF_896 0x00007000 /* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 896cycles */ +#define SD0001_SDMD_REF_STOP 0x00008000 /* ¥ê¥Õ¥ì¥Ã¥·¥åÄä»ß */ + +#define SD0001_SDMD_LMODE_MASK 0x00000070 /* CAS¥ì¥¤¥Æ¥ó¥· ÀßÄê¥Þ¥¹¥¯ */ +#define SD0001_SDMD_LMODE_1 0x00000000 /* CAS¥ì¥¤¥Æ¥ó¥· 1 */ +#define SD0001_SDMD_LMODE_2 0x00000010 /* CAS¥ì¥¤¥Æ¥ó¥· 2 */ +#define SD0001_SDMD_LMODE_3 0x00000020 /* CAS¥ì¥¤¥Æ¥ó¥· 3 */ +#define SD0001_SDMD_MASK 0xf000f070 /* SDMS ÀßÄê¥Þ¥¹¥¯ */ + + +/* ³ä¤ê¹þ¤ß ¥Þ¥¹¥¯ */ +#define SD0001_INT_INTEN 0x80000000 /* Á´³ä¤ê¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_INT_RETRY 0x20000000 /* PCI¥Ð¥¹¥ê¥È¥é¥¤²ó¿ô¥ª¡¼¥Ð¡¼ */ +#define SD0001_INT_TO 0x10000000 /* PCI¥Ð¥¹¥¿¥¤¥à¥¢¥¦¥È */ +#define SD0001_INT_SSERR 0x08000000 /* SERR#¥¢¥µ¡¼¥È */ +#define SD0001_INT_RSERR 0x04000000 /* SERR#¸¡½Ð */ +#define SD0001_INT_RPERR 0x02000000 /* PERR#¸¡½Ð */ +#define SD0001_INT_SPERR 0x01000000 /* PERR#¥¢¥µ¡¼¥È */ +#define SD0001_INT_STABT 0x00800000 /* ¥¿¡¼¥²¥Ã¥È¥¢¥Ü¡¼¥Èȯ¹Ô */ +#define SD0001_INT_RTABT 0x00400000 /* ¥¿¡¼¥²¥Ã¥È¥¢¥Ü¡¼¥È¸¡½Ð */ +#define SD0001_INT_LOCK 0x00200000 /* ¥Ç¥Ã¥É¥í¥Ã¥¯¸¡½Ð */ +#define SD0001_INT_RMABT 0x00100000 /* ¥Þ¥¹¥¿¡¼¥¢¥Ü¡¼¥È¸¡½Ð */ +#define SD0001_INT_BUSERR 0x3ff00000 /* PCI¥Ð¥¹¥¨¥é¡¼³ä¹þ¤ß */ +#define SD0001_INT_AWINT 0x00001000 /* AWAKE³ä¹þ¤ß */ +#define SD0001_INT_DMA1 0x00000020 /* DMA¥Á¥ã¥Í¥ë1´°Î» */ +#define SD0001_INT_DMA2 0x00000010 /* DMA¥Á¥ã¥Í¥ë2´°Î» */ +#define SD0001_INT_INTD 0x00000008 /* PCI¥Ð¥¹INTD# */ +#define SD0001_INT_INTC 0x00000004 /* PCI¥Ð¥¹INTC# */ +#define SD0001_INT_INTB 0x00000002 /* PCI¥Ð¥¹INTB# */ +#define SD0001_INT_INTA 0x00000001 /* PCI¥Ð¥¹INTA# */ +#define SD0001_INT_VAILD 0x3ff0103f /* ³ä¤ê¹þ¤ßÍ­¸ú¥Ó¥Ã¥È */ + +/* CONFIG_ADDRESS ¥ì¥¸¥¹¥¿ */ +#define SD0001_CONFIG_ADDR_EN 0x80000000 /* ¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥µ¥¤¥¯¥ë¥¤¥Í¡¼¥Ö¥ë */ + + +/* INDRCT_CMD ¥ì¥¸¥¹¥¿ */ +#define SD0001_INDRCTC_BE_MASK 0x000f0000 /* ¥Ð¥¤¥È¥¤¥Í¡¼¥Ö¥ë */ +#define SD0001_INDRCTC_BE_BYTE 0x00010000 /* ¥Ð¥¤¥È¥¢¥¯¥»¥¹³«»Ï°ÌÃÖ */ +#define SD0001_INDRCTC_BE_WORD 0x00030000 /* ¥ï¡¼¥É¥¢¥¯¥»¥¹³«»Ï°ÌÃÖ */ +#define SD0001_INDRCTC_BE_LONG 0x000f0000 /* ¥í¥ó¥°¥ï¡¼¥É¥¢¥¯¥»¥¹ */ +#define SD0001_INDRCTC_CMDEN 0x00008000 /* CMD Enable */ +#define SD0001_INDRCTC_CMD_IOR 0x00000200 /* I/O Read CMD */ +#define SD0001_INDRCTC_CMD_IOW 0x00000300 /* I/O Write CMD */ +#define SD0001_INDRCTC_CMD_MEMR 0x00000600 /* Memory Read CMD */ +#define SD0001_INDRCTC_CMD_MEMW 0x00000700 /* Memory Write CMD */ +#define SD0001_INDRCTC_CMD_INTA 0x00000000 /* Interrupt Ack CMD */ +#define SD0001_INDRCTC_CMD_MASK 0x00000f00 /* CMD ¥³¡¼¥É */ +#define SD0001_INDRCTC_FLGRESET 0x00000080 /* INDRCT_FLG¤Î¥¨¥é¡¼¥Õ¥é¥°¤Î¥ê¥»¥Ã¥È */ +#define SD0001_INDRCTC_IOWT 0x00000008 /* ´ÖÀÜI/O¥é¥¤¥È»Ø¼¨ */ +#define SD0001_INDRCTC_IORD 0x00000004 /* ´ÖÀÜI/O¥ê¡¼¥É»Ø¼¨ */ +#define SD0001_INDRCTC_COWT 0x00000002 /* ¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥é¥¤¥È»Ø¼¨ */ +#define SD0001_INDRCTC_CORD 0x00000001 /* ¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥ê¡¼¥É»Ø¼¨ */ +#define SD0001_INDRCTC_MASK 0x000f8f8f /* INDRCT_CMD ÀßÄê»þ¥Þ¥¹¥¯ */ + +/* INDRCT_FLG ¥ì¥¸¥¹¥¿ */ +#define SD0001_INDRCTF_MABTRCV 0x00080000 /* ¥Þ¥¹¥¿¡¼¥¢¥Ü¡¼¥ÈȯÀ¸ */ +#define SD0001_INDRCTF_INDFLG 0x00000001 /* ´ÖÀÜ¥¢¥¯¥»¥¹¼Â¹ÔÃæ */ + + +/* Awake ¥ì¥¸¥¹¥¿ */ +#define SD0001_AWAKE_AWOK 0x80000000 /* AWAKE READɽ¼¨ */ +#define SD0001_AWAKE_AWV 0x7fffffff /* AWAKE READÉÕ¿ï¾ðÊó */ + +/* Mail ¥ì¥¸¥¹¥¿ */ +#define SD0001_MAIL_FLAG 0x80000000 /* MAIL ³ä¹þ¤ßȯÀ¸ */ +#define SD0001_MAIL_DATA 0x7fffffff /* MAIL ³ä¹þ¤ßÉÕ¿ï¾ðÊó */ + + +/* + * SD0001 Æ⢠DMAC ¥ì¥¸¥¹¥¿µ¡Ç½ÄêµÁ + */ + +/* DMATCR ¥ì¥¸¥¹¥¿ */ +#define SD0001_DMATCR_MASK 0x0fffffff /* DMATCRÀßÄê¥Þ¥¹¥¯ */ +#define SD0001_DMATCR_MAX 0x04000000 /* ºÇÂçžÁ÷¥Ð¥¤¥È¿ô */ + + + +/* DMCMD ¥ì¥¸¥¹¥¿ */ +#define SD0001_DMCMD_EXEC 0x80000000 /* DMA³«»Ï»Ø¼¨ / ¼Â¹ÔÃæɽ¼¨ */ +#define SD0001_DMCMD_NEND 0x40000000 /* DMAÀ®¸ù¤Ë¤è¤ë´°Î» */ +#define SD0001_DMCMD_AEND 0x20000000 /* DMA¼ºÇԤˤè¤ë´°Î» */ +#define SD0001_DMCMD_STATUS 0x60000000 /* DMA´°Î»¥¹¥Æ¡¼¥¿¥¹ */ + +#define SD0001_DMCMD_SWAP 0x00010000 /* žÁ÷¥Ç¡¼¥¿¤Î Byte Swap */ +#define SD0001_DMCMD_DSR_RAM_PCI 0x00000100 /* DMAžÁ÷Êý¸þ¡§ SDRAM ¢ª PCI */ +#define SD0001_DMCMD_DSR_PCI_RAM 0x00000200 /* DMAžÁ÷Êý¸þ¡§ PCI ¢ª SDRAM */ +#define SD0001_DMCMD_DSR_RAM_RAM 0x00000000 /* DMAžÁ÷Êý¸þ¡§ SDRAM ¢ª SDRAM */ +#define SD0001_DMCMD_MASK 0xe0010f00 /* DMCMD¥ì¥¸¥¹¥¿ÀßÄê¥Þ¥¹¥¯ */ + + +/* INTM PCI ¥ì¥¸¥¹¥¿ */ +#define SD0001_INTMPCI_PERR 0x80000000 /* Detected Perr ³ä¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_INTMPCI_SERR 0x40000000 /* Signalled SERR ³ä¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_INTMPCI_MBAT 0x20000000 /* Received Master Abort ³ä¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_INTMPCI_RTABT 0x10000000 /* Received Target Abort ³ä¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_INTMPCI_STABT 0x08000000 /* Signalled Target Abort ³ä¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_INTMPCI_DPERR 0x01000000 /* DPerr Detected ³ä¹þ¤ß¥Þ¥¹¥¯ */ +#define SD0001_INTMPCI_MAIL 0x00800000 /* MAIL¥ì¥¸¥¹¥¿³ä¹þ¤ß */ + + +/* RESET PCI ¥ì¥¸¥¹¥¿*/ +#define SD0001_RSTPCI_SWRST 0x80000000 /* ¥¿¡¼¥²¥Ã¥È¥Ç¥Ð¥¤¥¹ ¥ê¥»¥Ã¥È */ +#define SD0001_RSTPCI_ALIVE 0x40000000 /* ¥¿¡¼¥²¥Ã¥È¥â¡¼¥É¤Î»þ¤ÎRESET¥ì¥¸¥¹¥¿¤Î */ + /* bit30(PCIRST)¤ÎÃÍ¡£ Read Only */ + + +extern int pci_setup_sd0001(void); + +void sd0001_outl(unsigned long, unsigned long); +unsigned long sd0001_inl(unsigned long); +void sd0001_outw(unsigned short, unsigned long); +unsigned short sd0001_inw(unsigned long); +void sd0001_outb(unsigned char, unsigned long); +unsigned char sd0001_inb(unsigned long); +void sd0001_insb(unsigned long, void *, unsigned long); +void sd0001_insw(unsigned long, void *, unsigned long); +void sd0001_insl(unsigned long, void *, unsigned long); +void sd0001_outsb(unsigned long, const void *, unsigned long); +void sd0001_outsw(unsigned long, const void *, unsigned long); +void sd0001_outsl(unsigned long, const void *, unsigned long); +unsigned char sd0001_inb_p(unsigned long); +void sd0001_outb_p(unsigned char, unsigned long); + +void *sd0001_ioremap(unsigned long, unsigned long); +void sd0001_iounmap(void *); + + +#endif /* __PCI_SD0001_H */ diff -urN linux-2.4.21/arch/sh/kernel/pci-sh7751.c linux-2.4.22/arch/sh/kernel/pci-sh7751.c --- linux-2.4.21/arch/sh/kernel/pci-sh7751.c 2001-11-04 09:31:58.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/pci-sh7751.c 2003-08-25 04:44:40.000000000 -0700 @@ -38,8 +38,6 @@ * Direct access to PCI hardware... */ -#ifdef CONFIG_PCI_DIRECT - #define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3)) @@ -202,8 +200,10 @@ unsigned int tmp, id; /* check for SH7751 hardware */ - id = (SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID; - if(inl(SH7751_PCIREG_BASE+SH7751_PCICONF0) != id) { + id = inl(SH7751_PCIREG_BASE + SH7751_PCICONF0); + + if ((id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID)) && + (id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID))) { PCIDBG(2,"PCI: This is not an SH7751\n"); return NULL; } @@ -226,20 +226,6 @@ return NULL; } -#endif - -/* - * BIOS32 and PCI BIOS handling. - * - * The BIOS version of the pci functions is not yet implemented but it is left - * in for completeness. Currently an error will be generated at compile time. - */ - -#ifdef CONFIG_PCI_BIOS - -#error PCI BIOS is not yet supported on SH7751 - -#endif /* CONFIG_PCI_BIOS */ /***************************************************************************************/ @@ -342,16 +328,9 @@ struct pci_ops *dir = NULL; PCIDBG(1,"PCI: Starting intialization.\n"); -#ifdef CONFIG_PCI_BIOS - if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) { - pci_probe |= PCI_BIOS_SORT; - pci_bios_present = 1; - } -#endif -#ifdef CONFIG_PCI_DIRECT + if (pci_probe & PCI_PROBE_CONF1 ) dir = pci_check_direct(); -#endif if (dir) { pci_root_ops = dir; if(!pcibios_init_platform()) @@ -372,11 +351,6 @@ pci_fixup_irqs(pcibios_swizzle, pcibios_lookup_irq); pcibios_fixup_peer_bridges(); pcibios_resource_survey(); - -#ifdef CONFIG_PCI_BIOS - if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) - pcibios_sort(); -#endif } char * __init pcibios_setup(char *str) @@ -384,29 +358,10 @@ if (!strcmp(str, "off")) { pci_probe = 0; return NULL; - } -#ifdef CONFIG_PCI_BIOS - else if (!strcmp(str, "bios")) { - pci_probe = PCI_PROBE_BIOS; - return NULL; - } else if (!strcmp(str, "nobios")) { - pci_probe &= ~PCI_PROBE_BIOS; - return NULL; - } else if (!strcmp(str, "nosort")) { - pci_probe |= PCI_NO_SORT; - return NULL; - } else if (!strcmp(str, "biosirq")) { - pci_probe |= PCI_BIOS_IRQ_SCAN; - return NULL; - } -#endif -#ifdef CONFIG_PCI_DIRECT - else if (!strcmp(str, "conf1")) { + } else if (!strcmp(str, "conf1")) { pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS; return NULL; - } -#endif - else if (!strcmp(str, "rom")) { + } else if (!strcmp(str, "rom")) { pci_probe |= PCI_ASSIGN_ROMS; return NULL; } else if (!strncmp(str, "lastbus=", 8)) { diff -urN linux-2.4.21/arch/sh/kernel/pci-snapgear.c linux-2.4.22/arch/sh/kernel/pci-snapgear.c --- linux-2.4.21/arch/sh/kernel/pci-snapgear.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/pci-snapgear.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,188 @@ +/* + * linux/arch/sh/kernel/pci-snapgear.c + * + * Author: David McCullough + * + * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * PCI initialization for the SnapGear boards + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PCI_REG(reg) (SH7751_PCIREG_BASE+reg) + +/* PCI: default LOCAL memory window sizes (seen from PCI bus) */ +#define SNAPGEAR_LSR0_SIZE (64*(1<<20)) //64MB +#define SNAPGEAR_LSR1_SIZE (64*(1<<20)) //64MB + +/* + * Initialize the SnapGear PCI interface + * Setup hardware to be Central Funtion + * Copy the BSR regs to the PCI interface + * Setup PCI windows into local RAM + */ +int __init pcibios_init_platform(void) { + u32 reg; + u32 word; + u32 id; + + PCIDBG(1,"PCI: snapgear_pci_init called\n"); + /* Set the BCR's to enable PCI access */ + reg = inl(SH7751_BCR1); + reg |= 0x80000; + outl(reg, SH7751_BCR1); + + /* check for SH7751/SH7751R hardware */ + id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0); + switch (id) { + case (SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID: + printk("PCI: SH7751 PCI host bridge found.\n"); + break; + case (SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID: + printk("PCI: SH7751R PCI host bridge found.\n"); + break; + default: + printk("PCI: Unknown PCI host bridge (id=0x%x).\n", id); + return(0); + } + + /* Turn the clocks back on (not done in reset)*/ + outl(0, PCI_REG(SH7751_PCICLKR)); + /* Clear Powerdown IRQ's (not done in reset) */ + word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0; + outl(word, PCI_REG(SH7751_PCICLKR)); + +#if 0 +/* + * This code is removed as it is done in the bootloader and doing it + * here means the MAC addresses loaded by the bootloader get lost + */ + /* toggle PCI reset pin */ + word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST; + outl(word,PCI_REG(SH7751_PCICR)); + /* Wait for a long time... not 1 sec. but long enough */ + mdelay(100); + word = SH7751_PCICR_PREFIX; + outl(word,PCI_REG(SH7751_PCICR)); +#endif + + /* set the command/status bits to: + * Wait Cycle Control + Parity Enable + Bus Master + + * Mem space enable + */ + word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | + SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; + outl(word, PCI_REG(SH7751_PCICONF1)); + + /* define this host as the host bridge */ + word = SH7751_PCI_HOST_BRIDGE << 24; + outl(word, PCI_REG(SH7751_PCICONF2)); + + /* Set IO and Mem windows to local address + * Make PCI and local address the same for easy 1 to 1 mapping + * Window0 = SNAPGEAR_LSR0_SIZE @ non-cached CS2 base = SDRAM + * Window1 = SNAPGEAR_LSR1_SIZE @ cached CS2 base = SDRAM + */ + word = SNAPGEAR_LSR0_SIZE - 1; + outl(word, PCI_REG(SH7751_PCILSR0)); + word = SNAPGEAR_LSR1_SIZE - 1; + outl(word, PCI_REG(SH7751_PCILSR1)); + /* Set the values on window 0 PCI config registers */ + word = P2SEGADDR(SH7751_CS2_BASE_ADDR); + outl(word, PCI_REG(SH7751_PCILAR0)); + outl(word, PCI_REG(SH7751_PCICONF5)); + /* Set the values on window 1 PCI config registers */ + word = PHYSADDR(SH7751_CS2_BASE_ADDR); + outl(word, PCI_REG(SH7751_PCILAR1)); + outl(word, PCI_REG(SH7751_PCICONF6)); + + /* Set the local 16MB PCI memory space window to + * the lowest PCI mapped address + */ + word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK; + PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word); + outl(word , PCI_REG(SH7751_PCIMBR)); + + /* Map IO space into PCI IO window + * The IO window is 64K-PCIBIOS_MIN_IO in size + * IO addresses will be translated to the + * PCI IO window base address + */ + PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO, + (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO); + + /* Make sure the MSB's of IO window are set to access PCI space correctly */ + word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK; + PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word); + outl(word, PCI_REG(SH7751_PCIIOBR)); + + /* Set PCI WCRx, BCRx's, copy from BSC locations */ + word = inl(SH7751_BCR1); + /* check BCR for SDRAM in area 3 */ + if(((word >> 2) & 1) == 0) { + printk("PCI: Area 2 is not configured for SDRAM. BCR1=0x%x\n", word); + return 0; + } + outl(word, PCI_REG(SH7751_PCIBCR1)); + word = (u16)inw(SH7751_BCR2); + /* check BCR2 for 32bit SDRAM interface*/ + if(((word >> 4) & 0x3) != 0x3) { + printk("PCI: Area 2 is not 32 bit SDRAM. BCR2=0x%x\n", word); + return 0; + } + outl(word, PCI_REG(SH7751_PCIBCR2)); + /* configure the wait control registers */ + word = inl(SH7751_WCR1); + outl(word, PCI_REG(SH7751_PCIWCR1)); + word = inl(SH7751_WCR2); + outl(word, PCI_REG(SH7751_PCIWCR2)); + word = inl(SH7751_WCR3); + outl(word, PCI_REG(SH7751_PCIWCR3)); + word = inl(SH7751_MCR); + outl(word, PCI_REG(SH7751_PCIMCR)); + + /* NOTE: I'm ignoring the PCI error IRQs for now.. + * TODO: add support for the internal error interrupts and + * DMA interrupts... + */ + + /* SH7751 init done, set central function init complete */ + /* use round robin mode to stop a device starving/overruning */ + word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM; + outl(word,PCI_REG(SH7751_PCICR)); + PCIDBG(2,"PCI: snapgear_pci_init finished\n"); + + return 1; +} + +int __init pcibios_map_platform_irq(u8 slot, u8 pin) +{ + int irq = -1; + + switch (slot) { + case 8: /* the PCI bridge */ break; + case 11: irq = 8; break; /* USB */ + case 12: irq = 11; break; /* PCMCIA */ + case 13: irq = 5; break; /* eth0 */ + case 14: irq = 8; break; /* eth1 */ + case 15: irq = 11; break; /* safenet (unused) */ + } + + printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n", + slot, pin - 1 + 'A', irq); + + return irq; +} + diff -urN linux-2.4.21/arch/sh/kernel/pci-v320usc.c linux-2.4.22/arch/sh/kernel/pci-v320usc.c --- linux-2.4.21/arch/sh/kernel/pci-v320usc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/pci-v320usc.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,518 @@ +/****************************************************************************/ +/* + * pci.c: V3 Hurricane specific PCI support. + * + * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com) + * Copyright (C) 2001, Lineo Inc., + * SH3 port. + */ +/****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pci-v320usc.h" + +/****************************************************************************/ +#ifdef CONFIG_PCI +/****************************************************************************/ + +#ifndef CONFIG_PCMCIA +#define V320USC_MEM_SPACE 0xB8000000 /* V320 sees this as AC000000 ! */ +#define V320USC_IO_SPACE 0xB4000000 +#define V320USC_CONF_SPACE 0xB4000000 +#else +#define V320USC_MEM_SPACE 0xab000000 +#define V320USC_IO_SPACE 0xaa000000 +#define V320USC_CONF_SPACE 0xaa000000 +#endif +#define V320USC_BASE 0xb1fd0000 + +#ifdef __LITTLE_ENDIAN +#define reg08(x) (V320USC_BASE + (V320USC_##x)) +#define reg16(x) (V320USC_BASE + (V320USC_##x)) +#else +#define reg08(x) (V320USC_BASE + ((V320USC_##x)^3)) +#define reg16(x) (V320USC_BASE + ((V320USC_##x)^2)) +#endif + +#define reg32(x) (V320USC_BASE + (V320USC_##x)) + +#define v320usc_inb(addr) readb(reg08(addr) +#define v320usc_outb(value, addr) writeb(value, reg08(addr)) +#define v320usc_inw(addr) readw(reg16(addr)) +#define v320usc_outw(value, addr) writew(value, reg16(addr)) +#define v320usc_inl(addr) readl(reg32(addr)) +#define v320usc_outl(value, addr) writel(value, reg32(addr)) + +/****************************************************************************/ + +/* Set the LB_PCI_BASE0 register to allow PCI Memory cycles to be used */ + +static void set_io_cycles(void) +{ + u32 tempscratch; + + v320usc_outl( + (v320usc_inl(LB_PCI_BASE0) & + ~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK)) + | LB_PCI_BASEX_IO, LB_PCI_BASE0); + + /* do a read of the register to flush the posting buffer */ + tempscratch = v320usc_inl(LB_PCI_BASE0); +} + + +/* Set the LB_PCI_BASE0 register to allow PCI Config cycles to be used */ +static void set_config_cycles(int alow) +{ + u32 tempscratch; + + tempscratch = v320usc_inl(LB_PCI_BASE0); + + v320usc_outl((tempscratch & + ~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK)) + | LB_PCI_BASEX_CONFIG | alow, LB_PCI_BASE0); + + /* do a read of the register to flush the posting buffer */ + tempscratch = v320usc_inl(LB_PCI_BASE0); +} + + +static int mkaddr (unsigned char bus, + unsigned char devfn, + unsigned char where) +{ + int addr, alow; + + if (bus) { + addr = ((bus & 0xff) << 0x10) | + ((devfn & 0xff) << 0x08) | + (where & 0xff); + + /* set alow for type 1 configuration cycle */ + alow = 1; + } else { + int device, function; + + if (devfn >= PCI_DEVFN(12, 0)) + return -1; + + device = PCI_SLOT(devfn); + function = PCI_FUNC(devfn); + + /* This next line assumes that the PCI backplane connects */ + /* the IDSEL line for each slot to a Address line with a */ + /* small value resistor. Note: The PCI spec. suggests */ + /* several options here. This code assumes the following */ + /* IDSEL to Address line mapping. */ + + /* Slot Address Line */ + /* 0 - AD11 */ + /* 1 - AD12 */ + /* 2 - AD13 */ + /* 3 - AD14 */ + /* 4 - AD15 */ + + /* 0x800 is AD11 set, shift left by the slot number (device) */ + addr = (0x800 << device) | (function << 8) | where; + + /* set alow for type 0 configuration cycle */ + alow = 0; + } + + set_config_cycles(alow); + + return addr; +} + + +static int v320usc_pcibios_read_config_byte ( + struct pci_dev *dev, + int where, + u8 *val) +{ + int retVal = PCIBIOS_SUCCESSFUL; + unsigned long flags; + int addr; + + save_and_cli(flags); + + /* Clear status bits */ + v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W); + + if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1) + retVal = -1; + else { + // *val = readb(V320USC_CONF_SPACE + addr); + *val = * (unsigned char *) (V320USC_CONF_SPACE + addr); + + /* Check for master abort */ + if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) { + v320usc_outw(0xffff, PCI_STAT_W); + // printk("Master abort byte\n"); + *val = 0xff; + } + } + + set_io_cycles(); + restore_flags(flags); + return retVal; +} + + +static int v320usc_pcibios_read_config_word ( + struct pci_dev *dev, + int where, + u16 *val) +{ + int retVal = PCIBIOS_SUCCESSFUL; + unsigned long flags; + int addr; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + save_and_cli(flags); + + /* Clear status bits */ + v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W); + + if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1) + retVal = -1; + else { + *val = readw(V320USC_CONF_SPACE + addr); + + /* Check for master abort */ + if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) { + v320usc_outw(0xffff, PCI_STAT_W); + // printk("Master abort word\n"); + *val = 0xffff; + } + } + + set_io_cycles(); + + restore_flags(flags); + + return retVal; +} + + +static int v320usc_pcibios_read_config_dword ( + struct pci_dev *dev, + int where, + u32 *val) +{ + int retVal = PCIBIOS_SUCCESSFUL; + unsigned long flags; + int addr; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + save_and_cli(flags); + + /* Clear status bits */ + v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W); + + if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1) + retVal = -1; + else { + *val = readl(V320USC_CONF_SPACE + addr); + + /* Check for master abort */ + if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) { + v320usc_outw(0xffff, PCI_STAT_W); + // printk("Master abort long\n"); + *val = 0xffffffff; + } + } + + set_io_cycles(); + + restore_flags(flags); + + return retVal; +} + + +static int v320usc_pcibios_write_config_byte ( + struct pci_dev *dev, + int where, + u8 val) +{ + int retVal = PCIBIOS_SUCCESSFUL; + unsigned long flags; + int addr; + + save_and_cli(flags); + + if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1) + retVal = -1; + else + writeb(val, V320USC_CONF_SPACE + addr); + + /* wait for write FIFO to empty */ + v320usc_inw(PCI_STAT_W); + + set_io_cycles(); + + restore_flags(flags); + + return retVal; +} + + +static int v320usc_pcibios_write_config_word ( + struct pci_dev *dev, + int where, + u16 val) +{ + int retVal = PCIBIOS_SUCCESSFUL; + unsigned long flags; + int addr; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + save_and_cli(flags); + + if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1) + retVal = -1; + else + writew(val, V320USC_CONF_SPACE + addr); + + /* wait for write FIFO to empty */ + v320usc_inw(PCI_STAT_W); + + set_io_cycles(); + + restore_flags(flags); + + return retVal; +} + + +static int v320usc_pcibios_write_config_dword ( + struct pci_dev *dev, + int where, + u32 val) +{ + int retVal = PCIBIOS_SUCCESSFUL; + unsigned long flags; + int addr; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + save_and_cli(flags); + + if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1) + retVal = -1; + else + writel(val, V320USC_CONF_SPACE + addr); + + /* wait for write FIFO to empty */ + v320usc_inw(PCI_STAT_W); + + set_io_cycles(); + + restore_flags(flags); + + return retVal; +} + + +struct pci_ops pci_config_ops = { + v320usc_pcibios_read_config_byte, + v320usc_pcibios_read_config_word, + v320usc_pcibios_read_config_dword, + v320usc_pcibios_write_config_byte, + v320usc_pcibios_write_config_word, + v320usc_pcibios_write_config_dword +}; + +/****************************************************************************/ + +/* Everything hangs off this */ +static struct pci_bus *pci_root_bus; + +static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) +{ + return PCI_SLOT(dev->devfn); +} + + +static int __init map_keywest_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (pin >= 1 && pin <= 4) + return(PINT_IRQ_BASE + 2 + pin - 1); + return(-1); +} + + +char * +pcibios_setup(char *str) +{ + return(str); +} + + +void __init +pcibios_fixup_pbus_ranges(struct pci_bus *bus, + struct pbus_set_ranges_data *ranges) +{ + ranges->io_start -= bus->resource[0]->start; + ranges->io_end -= bus->resource[0]->start; + ranges->mem_start -= bus->resource[1]->start; + ranges->mem_end -= bus->resource[1]->start; +} + + +void __init pcibios_init(void) +{ + char *mode; + + if (sh_mv.mv_init_pci != NULL) + sh_mv.mv_init_pci(); + + if (v320usc_inw(PCI_VENDOR) != V3USC_PCI_VENDOR) { + printk("V320USC: PCI bridge chip not found\n"); + return; + } + + switch (v320usc_inw(PCI_DEVICE)) { + case V3USC_PCI_DEVICE_MIPS_9: mode = "MIPS 9-bit"; break; + case V3USC_PCI_DEVICE_MIPS_5: mode = "MIPS 5-bit"; break; + case V3USC_PCI_DEVICE_SH3: mode = "SH-3"; break; + case V3USC_PCI_DEVICE_SH4: mode = "SH-4"; break; + default: mode = "unknown !"; break; + } + printk("V3 Semiconductor V320USC bridge in %s mode\n", mode); + + /* + * RST_OUT de asserted + */ + v320usc_outb(0x80, SYSTEM); + + /* + * 16x8 latency time, GRANT, Normal arbitration, RAM Disable, + * CLK_OUT Disable, SYNC_RDY, BREQ_NEG + */ + v320usc_outl(0x10120001, LB_BUS_CFG); + + /* + * System error enable, PCI bus master, Memory & IO Access enable + */ + v320usc_outw(0x0047, PCI_CMD_W); + v320usc_outw(0xf100, PCI_STAT_W); /* clear any errors */ + + /* + * 32x8 clocks as Latency Timer + */ + v320usc_outl(0x00008800, PCI_HDR_CFG); + + v320usc_outl(0x00005761, DRAM_BLK0); + v320usc_outl(0x02005761, DRAM_BLK1); + v320usc_outl(0x00000000, DRAM_BLK2); + v320usc_outl(0x00000000, DRAM_BLK3); + v320usc_outl(0x00000942, DRAM_CFG); + v320usc_outl(0x80030066, PCI_BUS_CFG); + + v320usc_outl(v320usc_inl(INT_STAT), INT_STAT); /* clear any ints */ + + v320usc_outl(0x00000000, INT_CFG0); + v320usc_outl(0x00000000, INT_CFG1); + v320usc_outl(0x00000000, INT_CFG2); + v320usc_outl(0x00000000, INT_CFG3); + +#if 0 + v320usc_outl(0x0c000000, PCI_I2O_BASE); + v320usc_outl(0x0c010053, PCI_I2O_MAP); +#endif + v320usc_outl(0x0c000001, PCI_MEM_BASE); + v320usc_outl(0x00010063, PCI_MEM_MAP); + + v320usc_outl(0x00000000, LB_PCU_BASE); /* Disable PCU on SuperH */ +#if 0 + v320usc_outl(0x00000081, PCI_PCU_BASE); +#endif + +#ifndef CONFIG_PCMCIA + v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */ + v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */ +#else + v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */ + v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */ +#endif + + /* + * do the scan + */ + pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); + pci_assign_unassigned_resources(); + pci_fixup_irqs(no_swizzle, map_keywest_irq); + +#ifndef CONFIG_PCMCIA + v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */ + v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */ +#else + v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */ + v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */ +#endif + + /* + * Lock the system registers + */ + v320usc_outb(0x60, SYSTEM); + + /* + * Map all the PCI IO space + */ + mach_port_map(PCIBIOS_MIN_IO, (64*1024) - PCIBIOS_MIN_IO, + V320USC_IO_SPACE+PCIBIOS_MIN_IO, 0); +} + +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + printk("%s,%d: %s()\n", __FILE__, __LINE__, __FUNCTION__); +} + +static void __init pci_fixup_ide_bases(struct pci_dev *d) +{ + int i; + + /* + * PCI IDE controllers use non-standard I/O port decoding, respect it. + */ + if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + printk("PCI: IDE base address fixup for %s\n", d->slot_name); + for(i=0; i<4; i++) { + struct resource *r = &d->resource[i]; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } + } +} + +/* Add future fixups here... */ +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases }, + { 0 } +}; + +/****************************************************************************/ +#endif /* CONFIG_PCI */ diff -urN linux-2.4.21/arch/sh/kernel/pci-v320usc.h linux-2.4.22/arch/sh/kernel/pci-v320usc.h --- linux-2.4.21/arch/sh/kernel/pci-v320usc.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/pci-v320usc.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,454 @@ +/* + * v320usc.h: Register defines for the V320USC family of devices. + * + * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com) + * + * $Id: pci-v320usc.h,v 1.1 2003/02/20 04:26:36 gerg Exp $ + */ + +#ifndef _V320USC_H_ +#define _V320USC_H_ + +#include + +/* + * General parameters + */ +/* set debug level 4=verbose...1=terse */ +#define DEBUG_PCI 3 +// #undef DEBUG_PCI + +#ifdef DEBUG_PCI +#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); } +#else +#define PCIDBG(n, x...) +#endif + +#if 0 +/* startup values */ +#define PCI_PROBE_BIOS 1 +#define PCI_PROBE_CONF1 2 +#define PCI_PROBE_CONF2 4 +#define PCI_NO_SORT 0x100 +#define PCI_BIOS_SORT 0x200 +#define PCI_NO_CHECKS 0x400 +#define PCI_ASSIGN_ROMS 0x1000 +#define PCI_BIOS_IRQ_SCAN 0x2000 +#endif + + +/* + * platform specific parameters + */ + +/* + * PCI Command Register + * - Offset 04h, Size 16 bits + */ +#define PCI_CMD_W_IO_EN 0x0001 /* I/O access */ +#define PCI_CMD_W_MEM_EN 0x0002 /* Memory access */ +#define PCI_CMD_W_MASTER_EN 0x0004 /* PCI Master */ +#define PCI_CMD_W_MWI_EN 0x0010 /* Memory Write and */ + /* Invalidate enable */ +#define PCI_CMD_W_PAR_EN 0x0040 /* Parity error */ +#define PCI_CMD_W_SERR_EN 0x0100 /* System error */ + /* If PAR_EN is enabled then SERR is */ + /* driven in response to parity error */ +#define PCI_CMD_W_FBB_EN 0x0200 /* Fast back to back */ + /* transfers when Bus Master */ + +/* + * PCI Status Register + * - Offset 06h, Size 16 bits + */ +#define PCI_STAT_W_NEW_CAP 0x0010 /* New Capabilites */ +#define PCI_STAT_W_UDF 0x0040 /* User Defined Feature */ +#define PCI_STAT_W_FAST_BACK 0x0008 /* Fast Back to Back Target */ + /* - Used to indicate ability of this */ + /* device to other Bus Masters */ +#define PCI_STAT_W_PAR_REP 0x0010 /* Data Parity Report when */ + /* USC is a Bus Master and PERR is driven */ +#define PCI_STAT_W_DEVSEL_MASK 0x0600 /* 10-9 Bits Device Select */ + /* Timing */ +#define PCI_STAT_W_DEVSEL_SHIFT 9 + +#define PCI_STAT_W_T_ABORT 0x1000 /* Target Abort - set in */ + /* response to a target abort detected */ + /* while USC was a Bus Master */ +#define PCI_STAT_W_M_ABORT 0x2000 /* Master Abort - set in */ + /* response to a master abort detected */ + /* while USC was a Bus Master */ +#define PCI_STAT_W_SYS_ERR 0x4000 /* System Error - set in */ + /* response to a system error on the */ + /* SERR pin */ +#define PCI_STAT_W_PAR_ERR 0x8000 /* Parity Error - set in */ + /* response to a parity error on the */ + /* PCI bus */ + +/* + * PCI Class and Revision Register + * - Offset 08h, Size 32 bits + */ +#define PCI_CC_REV_VREV_MASK 0x0000000f /* 3-0 Bits Stepping ID */ + /* Rev A = 0,Rev B0 = 1, Rev B1 = 2, */ + /* Rev B2 = 3 */ +#define PCI_CC_REV_VREV_SHIFT 0 + +#define PCI_CC_REV_UREV_MASK 0x000000f0 /* 7-4 Bits User Revision ID */ + /* user definable for system revisions */ +#define PCI_CC_REV_UREV_SHIFT 4 + +#define PCI_CC_REV_PROG_IF_MASK 0x0000ff00 /* 15-8 Bits PCI Programming */ + /* Interface code */ +#define PCI_CC_REV_PROG_IF_SHIFT 8 + +#define PCI_CC_REV_SUB_CLASS_MASK 0x00ff0000 /* 23-16 Bits PCI Sub Class */ +#define PCI_CC_REV_SUB_CLASS_SHIFT 16 + +#define PCI_CC_REV_BASE_CLASS_MASK 0xff000000 /* 32-24 Bits PCI Base Class */ +#define PCI_CC_REV_BASE_CLASS_SHIFT 24 + +/* + * PCI Access to local memory map access + * - Offset 10h, Size 32 bits (I2O mode) + */ +#define PCI_I2O_BASE_IO 0x00000001 /* I/O 1 - I/O space */ + /* 0 - Memory Space */ +#define PCI_I2O_BASE_TYPE_MASK 0x00000006 /* 2-1 Bits Address range */ + /* type */ +#define PCI_I2O_BASE_TYPE_SHIFT 1 /* 0 - device can be mapped */ + /* any where in a 32 bit address space */ +#define PCI_I2O_BASE_PREFETCH 0x00000008 /* Prefetchable - no effect */ +#define PCI_I2O_BASE_ADR_BASE_MASK 0xfff00000 /* 31-20 Bits Base address */ + /* of ATU */ +#define PCI_I2O_BASE_ADR_BASE_SHIFT 20 + +/* + * PCI Access to local memory map access + * - Offset 14h, Size 32 bits + */ +#define PCI_MEM_BASE_IO 0x00000001 /* I/O 1 - I/O space */ + /* 0 - Memory Space */ +#define PCI_MEM_BASE_TYPE_MASK 0x00000006 /* 2-1 Bits Address range */ + /* type */ +#define PCI_MEM_BASE_TYPE_SHIFT 1 /* 0 - device can be mapped */ + /* any where in a 32 bit address space */ +#define PCI_MEM_BASE_PREFETCH 0x00000008 /* Prefetchable - no effect */ +#define PCI_MEM_BASE_ADR_BASE_MASK 0xfff00000 /* 31-20 Bits Base address */ + /* of ATU */ +#define PCI_MEM_BASE_ADR_BASE_SHIFT 20 + +/* + * PCI Bus Parameters Register + * - Offset 3ch, Size 32 bits + */ +#define PCI_BPARAM_INT_LINE_MASK 0x000000ff /* 7-0 Bits Interrupt Line */ +#define PCI_BPARAM_INT_LINE_SHIFT 0 +#define PCI_BPARAM_INT_PIN_MASK 0x00000700 /* 10-8 Bits Interrupt Pin */ + /* 0 - disable, 1 - INTA, 2 - INT B */ + /* 3 - INT C, 4 - INT C */ +#define PCI_BPARAM_INT_PIN_SHIFT 8 +#define PCI_BPARAM_MIN_GRANT_MASK 0x00ff0000 /* 23-16 Bits Minimum Grant */ +#define PCI_BPARAM_MIN_GRANT_SHIFT 16 +#define PCI_BPARAM_MAX_LAT_MASK 0xff000000 /* 31-24 Bits Maximum Latency */ +#define PCI_BPARAM_MAX_LAT_SHIFT 24 + +/* + * LB_PCI_BASEx Registers + * - Offset 60h, Size 32 bits + * - Offset 64h, Size 32 bits + */ +#define LB_PCI_BASEX_ALOW_MASK 0x00000003 /* select value AD1:0 */ +#define LB_PCI_BASEX_ALOW_SHIFT 0x00000000 +#define LB_PCI_BASEX_ERR_EN 0x00000004 +#define LB_PCI_BASEX_PREFETCH 0x00000008 /* prefetch */ +#define LB_PCI_BASEX_SIZE_DISABLE 0x00000000 +#define LB_PCI_BASEX_SIZE_16MB 0x00000010 +#define LB_PCI_BASEX_SIZE_32MB 0x00000020 +#define LB_PCI_BASEX_SIZE_64MB 0x00000030 +#define LB_PCI_BASEX_SIZE_128MB 0x00000040 +#define LB_PCI_BASEX_SIZE_256MB 0x00000050 +#define LB_PCI_BASEX_SIZE_512MB 0x00000060 +#define LB_PCI_BASEX_SIZE_1GB 0x00000070 +#define LB_PCI_BASEX_BYTE_SWAP_NO 0x00000000 /* No swap 32 bits */ +#define LB_PCI_BASEX_BYTE_SWAP_16 0x00000100 /* 16 bits */ +#define LB_PCI_BASEX_BYTE_SWAP_8 0x00000200 /* bits */ +#define LB_PCI_BASEX_BYTE_SWAP_AUTO 0x00000300 /* Auto swap use BE[3:0] */ +#define LB_PCI_BASEX_COMBINE 0x00000800 /* Burst Write Combine */ + +#define LB_PCI_BASEX_PCI_CMD_MASK 0x0000e000 +#define LB_PCI_BASEX_PCI_CMD_SHIFT 13 +#define LB_PCI_BASEX_INT_ACK 0x00000000 /* Interrupt Ack */ +#define LB_PCI_BASEX_IO 0x00002000 /* I/O Read/Write */ +#define LB_PCI_BASEX_MEMORY 0x00006000 /* Memory Read/Write */ +#define LB_PCI_BASEX_CONFIG 0x0000a000 /* Configuration Read/Write */ +#define LB_PCI_BASEX_MULTI_MEMORY 0x0000c000 /* Multiple Memory Read/Write */ +#define LB_PCI_BASEX_MEMORY_INVALIDATE 0x0000e000 /* Multiple Memory Read/e */ + /* Write Invalidate */ +#define LB_PCI_BASEX_MAP_ADR_MASK 0x00ff0000 /* PCI Address map */ +#define LB_PCI_BASEX_MAP_ADR_SHIFT 16 +#define LB_PCI_BASEX_BASE 0xff000000 /* Local Address base */ +#define LB_PCI_BASEX_BASE_ADR_SHIFT 24 + + +/* + * SDRAM Local Base Address Register + * - Offset 78h, Size 32 bits + */ +#define LB_SDRAM_BASE_ENABLE 0x01 /* must be enabled to access */ +#define LB_SDRAM_BASE_SIZE_64M 0x00 +#define LB_SDRAM_BASE_SIZE_128M 0x10 +#define LB_SDRAM_BASE_SIZE_256M 0x20 +#define LB_SDRAM_BASE_SIZE_512M 0x30 +#define LB_SDRAM_BASE_SIZE_1G 0x40 + +#define LB_SDRAM_BASE_MASK 0xfc000000 +#define LB_SDRAM_BASE_SHIFT 26 + + +/* + * Interrupt Configuration Register + * - Offset e0h, Size 32 bits + * - Offset e4h, Size 32 bits + * - Offset e8h, Size 32 bits + * - Offset 158h, Size 32 bits + */ +#define INT_CFGX_LB_MBI 0x00000001 +#define INT_CFGX_PCI_MBI 0x00000002 +#define INT_CFGX_I2O_OP_NE 0x00000008 +#define INT_CFGX_I2O_IF_NF 0x00000010 +#define INT_CFGX_I2O_IP_NE 0x00000020 +#define INT_CFGX_I2O_OP_NF 0x00000040 +#define INT_CFGX_I2O_OF_NE 0x00000080 +#define INT_CFGX_INT0 0x00000100 +#define INT_CFGX_INT1 0x00000200 +#define INT_CFGX_INT2 0x00000400 +#define INT_CFGX_INT3 0x00000800 +#define INT_CFGX_TIMER0 0x00001000 +#define INT_CFGX_TIMER1 0x00002000 +#define INT_CFGX_ENUM 0x00004000 +#define INT_CFGX_DMA0 0x00010000 +#define INT_CFGX_DMA1 0x00020000 +#define INT_CFGX_PWR_STATE 0x00100000 +#define INT_CFGX_HBI 0x00200000 +#define INT_CFGX_WDI 0x00400000 +#define INT_CFGX_BWI 0x00800000 +#define INT_CFGX_PSLAVE_PI 0x01000000 +#define INT_CFGX_PMASTER_PI 0x02000000 +#define INT_CFGX_PCI_T_ABORT 0x04000000 +#define INT_CFGX_PCI_M_ABORT 0x08000000 +#define INT_CFGX_DRA_PI 0x10000000 +#define INT_CFGX_MODE 0x20000000 +#define INT_CFGX_DI0 0x40000000 +#define INT_CFGX_DI1 0x80000000 + + +/* + * Interrupt Status Register + * - Offset ECh, Size 32 bits + */ +#define INT_STAT_BWI 0x00800000 +#define INT_STAT_WDI 0x00400000 +#define INT_STAT_HBI 0x00200000 +#define INT_STAT_DMA1 0x00020000 +#define INT_STAT_DMA0 0x00010000 +#define INT_STAT_TIMER1 0x00002000 +#define INT_STAT_TIMER0 0x00001000 +#define INT_STAT_INT3 0x00000800 +#define INT_STAT_INT2 0x00000400 +#define INT_STAT_INT1 0x00000200 +#define INT_STAT_INT0 0x00000100 + + +/* + * General Purpose Timer Control Register + * - Offset 150h, Size 16 bits + * - Offset 152h, Size 16 bits + */ +#define TIMER_CTLX_W_TI_MODE_0 0x0000 /* Timer input event */ +#define TIMER_CTLX_W_TI_MODE_1 0x0001 +#define TIMER_CTLX_W_TI_MODE_2 0x0002 +#define TIMER_CTLX_W_TI_MODE_3 0x0003 + +#define TIMER_CTLX_W_CNT_EN_0 0x0000 /* Count enable */ +#define TIMER_CTLX_W_CNT_EN_1 0x0004 +#define TIMER_CTLX_W_CNT_EN_2 0x0008 +#define TIMER_CTLX_W_CNT_EN_3 0x000C + +#define TIMER_CTLX_W_TRG_MODE_0 0x0000 /* Trigger mode */ +#define TIMER_CTLX_W_TRG_MODE_1 0x0010 +#define TIMER_CTLX_W_TRG_MODE_2 0x0020 +#define TIMER_CTLX_W_TRG_MODE_3 0x0030 + +#define TIMER_CTLX_W_TO_MODE_0 0x0000 /* Timer output mode */ +#define TIMER_CTLX_W_TO_MODE_1 0x0100 +#define TIMER_CTLX_W_TO_MODE_2 0x0200 +#define TIMER_CTLX_W_TO_MODE_3 0x0300 +#define TIMER_CTLX_W_TO_MODE_4 0x0400 +#define TIMER_CTLX_W_TO_MODE_5 0x0500 + +#define TIMER_CTLX_W_DLTCH_0 0x0000 /* Data latch mode */ +#define TIMER_CTLX_W_DLTCH_1 0x0800 +#define TIMER_CTLX_W_DLTCH_2 0x1000 + +#define TIMER_CTLX_W_ENABLE 0x8000 /* Timer enable */ + + +/* + * DMA Delay Register + * - Offset 16Ch, Size 8 bits + */ +#define DMA_DELAY_MASK 0x000000ff +#define DMA_DELAY_SHIFT 0 + +/* + * DMA Command / Status Register + * - Offset 170h, Size 32 bits + * - Offset 174h, Size 32 bits + */ +#define DMA_CSR_IPR 0x00000001 /* initiate DMA transfer */ +#define DMA_CSR_HALT 0x00000002 /* pause DMA transfer */ +#define DMA_CSR_DONE 0x00000004 /* DMA transfer complete */ +#define DMA_CSR_DCI 0x00000008 /* DMA control interrupt status */ +#define DMA_CSR_DPE 0x00000010 /* DMA PCI BUS error status */ +#define DMA_CSR_DONE_EN 0x00000400 /* DONE interrupt enable */ +#define DMA_CSR_DCI_EN 0x00000800 /* DCI interrupt enable */ +#define DMA_CSR_DPE_EN 0x00001000 /* DPE interrupt enable */ +#define DMA_CSR_PRIORITY 0x00008000 /* DMA channel priority */ +#define DMA_CSR_PCI_CMD0_MASK 0x000E0000 /* PCI Command Type 0 */ +#define DMA_CSR_PCI_CMD0_SHIFT 17 +#define DMA_CSR_PCI_CMD1_MASK 0x00E00000 /* PCI Command Type 1 */ +#define DMA_CSR_PCI_CMD1_SHIFT 21 + +/* + * DMA Transfer Control Register + * - Offset 180h, Size 32 bits + * - Offset 190h, Size 32 bits + */ +#define DMA_XFER_DMA_CNT_MASK 0x000FFFFF /* DMA transfer count */ +#define DMA_XFER_DMA_CNT_SHIFT 0 +#define DMA_XFER_DTERM_EN 0x00400000 /* External terminate count enable */ +#define DMA_XFER_BLOCK_FILL 0x00800000 /* Block fill feature enable */ +#define DMA_XFER_DST_BUS 0x01000000 /* DMA destination BUS */ +#define DMA_XFER_SRC_BUS 0x02000000 /* DMA source BUS */ +#define DMA_XFER_PDST_TYPE 0x04000000 /* PCI destination command type */ +#define DMA_XFER_PSRC_TYPE 0x08000000 /* PCI source command type */ +#define DMA_XFER_SWAP_MASK 0x30000000 /* Byte swap control */ +#define DMA_XFER_SWAP_SHIFT 28 +#define DMA_XFER_UPDT_CNT 0x40000000 /* Update count */ +#define DMA_XFER_DREQ_EN 0x80000000 /* External DRQ enable */ + + +/* + * DMA Control Block Register + * - Offset 180h, Size 32 bits + * - Offset 190h, Size 32 bits + */ +#define DMA_CTLB_BUS 0x00000001 /* DMA Control block address space */ +#define DMA_CTLB_SA_INC_DIS 0x00000004 /* Source address increment disable */ +#define DMA_CTLB_DA_INC_DIS 0x00000008 /* Dest address increment disable */ +#define DMA_CTLB_ADDR_MASK 0xFFFFFFF0 /* DMA Control block address mask */ +#define DMA_CTLB_ADDR_SHIFT 4 + + +/* + * V320USC registers offsets + */ +#define V320USC_PCI_VENDOR 0x00 +#define V320USC_PCI_DEVICE 0x02 +#define V320USC_PCI_CMD_W 0x04 +#define V320USC_PCI_STAT_W 0x06 +#define V320USC_PCI_CC_REV 0x08 +#define V320USC_PCI_HDR_CFG 0x0c +#define V320USC_PCI_I2O_BASE 0x10 +#define V320USC_PCI_MEM_BASE 0x14 +#define V320USC_PCI_REG_BASE 0x18 +#define V320USC_PCI_PCU_BASE 0x1c +#define V320USC_PCI_BPARM 0x3c +#define V320USC_PCI_I2O_MAP 0x50 +#define V320USC_PCI_MEM_MAP 0x54 +#define V320USC_PCI_BUS_CFG 0x5c +#define V320USC_LB_PCI_BASE0 0x60 +#define V320USC_LB_PCI_BASE1 0x64 +#define V320USC_LB_PCU_BASE 0x6c +#define V320USC_SYSTEM 0x73 +#define V320USC_LB_SDRAM_BASE 0x78 +#define V320USC_LB_BUS_CFG 0x7c +#define V320USC_LB_PCI_CTL_W 0x84 +#define V320USC_DRAM_CFG 0x8C +#define V320USC_DRAM_BLK0 0x90 +#define V320USC_DRAM_BLK1 0x94 +#define V320USC_DRAM_BLK2 0x98 +#define V320USC_DRAM_BLK3 0x9c +#define V320USC_INT_CFG0 0xe0 +#define V320USC_INT_CFG1 0xe4 +#define V320USC_INT_CFG2 0xe8 +#define V320USC_INT_STAT 0xec +#define V320USC_WD_HBI_W 0xf4 +#define V320USC_TIMER_DATA0 0x140 +#define V320USC_TIMER_DATA1 0x144 +#define V320USC_TIMER_CTL0_W 0x150 +#define V320USC_TIMER_CTL1_W 0x152 +#define V320USC_INT_CFG3 0x158 +#define V320USC_DMA_DELAY 0x16C +#define V320USC_DMA_CSR0 0x170 +#define V320USC_DMA_CSR1 0x174 +#define V320USC_DMA_XFER_CTL0 0x180 +#define V320USC_DMA_SRC_ADR0 0x184 +#define V320USC_DMA_DST_ADR0 0x188 +#define V320USC_DMA_CTLB_ADR0 0x18C +#define V320USC_DMA_XFER_CTL1 0x190 +#define V320USC_DMA_SRC_ADR1 0x194 +#define V320USC_DMA_DST_ADR1 0x198 +#define V320USC_DMA_CTLB_ADR1 0x19C + +/* + * Vendor/Device ID settings + */ + +#define V3USC_PCI_VENDOR 0x11b0 +#define V3USC_PCI_DEVICE_MIPS_9 0x0100 +#define V3USC_PCI_DEVICE_MIPS_5 0x0101 +#define V3USC_PCI_DEVICE_SH3 0x0102 +#define V3USC_PCI_DEVICE_SH4 0x0103 + +/* + * Stepping of V3USC320 as read back from V3USC_PCI_CC_REV register + */ +#define V3USC_REV_A0 0 +#define V3USC_REV_B0 1 +#define V3USC_REV_B1 2 + +/* + * PCI Bus Parameters Register + * - Offset 3ch, Size 32 bits + */ +#define INTERRUPT_PIN_DISABLE 0x0 /* Disabled */ +#define INTERRUPT_PIN_INTA 0x1 /* Use INTA */ +#define INTERRUPT_PIN_INTB 0x2 /* Use INTB */ +#define INTERRUPT_PIN_INTC 0x3 /* Use INTC */ +#define INTERRUPT_PIN_INTD 0x4 /* Use INTD */ + +/* + * PCI Base Address for Peripheral Access + * - Offset 1ch, Size 32 bits + * PCI Intelligent I/O Address Translation Unit Local Bus Address Map Register + * - Offset ??h, Size 32 bits + */ +#define BYTE_SWAP_NO 0x0 /* No swap 32 bits */ +#define BYTE_SWAP_16 0x1 /* 16 bits */ +#define BYTE_SWAP_8 0x2 /* 8 bits */ +#define BYTE_SWAP_AUTO 0x3 /* Auto swap use BE[3:0] */ +#define APERTURE_SIZE_1M 0x0 /* Aperture size of 1 MB */ +#define APERTURE_SIZE_2M 0x1 /* Aperture size of 2 MB */ +#define APERTURE_SIZE_4M 0x2 /* Aperture size of 4 MB */ +#define APERTURE_SIZE_8M 0x3 /* Aperture size of 8 MB */ +#define APERTURE_SIZE_16M 0x4 /* Aperture size of 16 MB */ +#define APERTURE_SIZE_32M 0x5 /* Aperture size of 32 MB */ +#define APERTURE_SIZE_64M 0x6 /* Aperture size of 64 MB */ +#define APERTURE_SIZE_128M 0x7 /* Aperture size of 128 MB */ +#define APERTURE_SIZE_256M 0x8 /* Aperture size of 256 MB */ +#define APERTURE_SIZE_512M 0x9 /* Aperture size of 512 MB */ +#define APERTURE_SIZE_1G 0xa /* Aperture size of 1 GB */ + +#endif /* _V320USC_H_ */ diff -urN linux-2.4.21/arch/sh/kernel/pci_st40.c linux-2.4.22/arch/sh/kernel/pci_st40.c --- linux-2.4.21/arch/sh/kernel/pci_st40.c 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/pci_st40.c 2003-08-25 04:44:40.000000000 -0700 @@ -21,6 +21,8 @@ #include "pci_st40.h" +static struct resource pci_io_space, pci_mem_space; + /* This is in P2 of course */ #define ST40PCI_BASE_ADDRESS (0xb0000000) #define ST40PCI_MEM_ADDRESS (ST40PCI_BASE_ADDRESS+0x0) @@ -28,97 +30,183 @@ #define ST40PCI_REG_ADDRESS (ST40PCI_BASE_ADDRESS+0x07000000) #define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x)) - -#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg)) -#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg)) -#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg)) +#define ST40PCI_REG_INDEXED(reg, index) \ + (ST40PCI_REG(reg##0) + \ + ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index)) + +#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg));udelay(2); +#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg));udelay(2); +#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg));udelay(2); +#define ST40PCI_WRITE_INDEXED(reg, index, val) \ + writel((val), ST40PCI_REG_INDEXED(reg, index)); udelay(2); #define ST40PCI_READ(reg) readl(ST40PCI_REG(reg)) #define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg)) #define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg)) +#define ST40PCI_READ_INDEXED(reg, index) readl(ST40PCI_REG_INDEXED(reg, index)) #define ST40PCI_SERR_IRQ 64 -#define ST40PCI_SERR_INT_GROUP 0 -#define ST40PCI_SERR_INT_POS 0 -#define ST40PCI_SERR_INT_PRI 15 - #define ST40PCI_ERR_IRQ 65 -#define ST40PCI_ERR_INT_GROUP 1 -#define ST40PCI_ERR_INT_POS 1 -#define ST40PCI_ERR_INT_PRI 14 +#define ST40PCI_AD_INT 66 +#define ST40PCI_PWR_DWN_INT 67 +#define PLLPCICR (0xbb040000+0x10) // CLKGENA.PLL2CR +/* From ST's include/asm-sh/st40_clock.h */ /* Macros to extract PLL params */ #define PLL_MDIV(reg) ( ((unsigned)reg) & 0xff ) #define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff ) -#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 ) +#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x7 ) #define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff ) -/* Build up the appropriate settings */ -#define PLL_SET(mdiv,ndiv,pdiv,setup) \ -( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19)) +/* + * The pcibios_map_platform_irq function is defined in the appropraite + * board specific code and referenced here + */ +extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); + +static void __init pcibios_assign_resources(void); + +static __init void SetPCIPLL(void) +{ + { + /* Lets play with the PLL values */ + unsigned long pll1cr1; + unsigned long mdiv, ndiv, pdiv; + unsigned long muxcr; + unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 }; + unsigned int freq; + +#define CLKGENA 0xbb040000 +#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48 + pll1cr1 = ctrl_inl(PLLPCICR); + printk("PLL1CR1 %08x\n", pll1cr1); + mdiv = PLL_MDIV(pll1cr1); + ndiv = PLL_NDIV(pll1cr1); + pdiv = PLL_PDIV(pll1cr1); + printk("mdiv %02x ndiv %02x pdiv %02x\n", mdiv, ndiv, pdiv); + freq = ((2*27*ndiv)/mdiv) / (1 << pdiv); + printk("PLL freq %dMHz\n", freq); + muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR); + printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]); + } +} + + +struct pci_err { + unsigned mask; + const char *error_string; +}; -#define PLLPCICR (0xbb040000+0x10) -#define PLLPCICR_POWERON (1<<28) -#define PLLPCICR_OUT_EN (1<<29) -#define PLLPCICR_LOCKSELECT (1<<30) -#define PLLPCICR_LOCK (1<<31) +static struct pci_err int_error[]={ + { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"}, + { INT_TTADI, "TTADI: Illegal byte enable in I/O transfer"}, + { INT_TMTO, "TMTO: Target memory read/write timeout"}, + { INT_MDEI, "MDEI: Master function disable error"}, + { INT_APEDI, "APEDI: Address parity error"}, + { INT_SDI, "SDI: SERR detected"}, + { INT_DPEITW, "DPEITW: Data parity error target write"}, + { INT_PEDITR, "PEDITR: PERR detected"}, + { INT_TADIM, "TADIM: Target abort detected"}, + { INT_MADIM, "MADIM: Master abort detected"}, + { INT_MWPDI, "MWPDI: PERR from target at data write"}, + { INT_MRDPEI, "MRDPEI: Master read data parity error"} +}; +#define NUM_PCI_INT_ERRS (sizeof(int_error)/sizeof(struct pci_err)) +static struct pci_err aint_error[]={ + { AINT_MBI, "MBI: Master broken"}, + { AINT_TBTOI, "TBTOI: Target bus timeout"}, + { AINT_MBTOI, "MBTOI: Master bus timeout"}, + { AINT_TAI, "TAI: Target abort"}, + { AINT_MAI, "MAI: Master abort"}, + { AINT_RDPEI, "RDPEI: Read data parity"}, + { AINT_WDPE, "WDPE: Write data parity"} +}; -#define PLL_25MHZ 0x793c8512 -#define PLL_33MHZ PLL_SET(18,88,3,295) +#define NUM_PCI_AINT_ERRS (sizeof(aint_error)/sizeof(struct pci_err)) -static __init void SetPCIPLL(void) +static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors) { - /* Stop the PLL */ - writel(0, PLLPCICR); + int i; - /* Always run at 33Mhz. The PCI clock is totally async - * to the rest of the system - */ - writel(PLL_33MHZ | PLLPCICR_POWERON, PLLPCICR); + for(i=0;i 0x%x\n", pci_int & 0xffff); - printk("PCI AIR -> 0x%x\n", pci_air); - printk("PCI CIR -> 0x%x\n", pci_cir); - ST40PCI_WRITE(INT, ~0); - } - - pci_aint = ST40PCI_READ(AINT); - if (pci_aint) { - printk("PCI ARB INTERRUPT!\n"); - printk("PCI AINT -> 0x%x\n", pci_aint); - printk("PCI AIR -> 0x%x\n", pci_air); - printk("PCI CIR -> 0x%x\n", pci_cir); - ST40PCI_WRITE(AINT, ~0); + if(++count>1) return; + + printk("** PCI ERROR **\n"); + + if(pci_int) { + printk("** INT register status\n"); + print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS); } + if(pci_aint) { + printk("** AINT register status\n"); + print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS); + } + + printk("** Address and command info\n"); + + printk("** Command %s : Address 0x%x\n", + pci_commands[pci_cir&0xf],pci_air); + + if(pci_cir&CIR_PIOTEM) { + printk("CIR_PIOTEM:PIO transfer error for master\n"); + } + if(pci_cir&CIR_RWTET) { + printk("CIR_RWTET:Read/Write transfer error for target\n"); + } } /* Rounds a number UP to the nearest power of two. Used for * sizing the PCI window. */ -static u32 __init r2p2(u32 num) +static u32 r2p2(u32 num) { int i = 31; u32 tmp = num; @@ -161,17 +249,49 @@ } +static void __init pci_fixup_cache_line(struct pci_dev *d) +{ + pci_write_config_byte(d,PCI_CACHE_LINE_SIZE,0); +} + + /* Add future fixups here... */ struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases }, + { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_cache_line }, { 0 } }; +char * __init pcibios_setup(char *str) +{ + return str; +} + +static void __init st40pci_init_resources(void) +{ + pci_io_space.start = PCIBIOS_MIN_IO; + pci_io_space.end = 64*1024 - PCIBIOS_MIN_IO - 1; + pci_io_space.name = "ST40 PCI"; + pci_io_space.flags = IORESOURCE_IO; + + request_resource(&ioport_resource, &pci_io_space); + + pci_mem_space.start = PCIBIOS_MIN_MEM; + pci_mem_space.end = PCIBIOS_MIN_MEM + (96*1024*1024) -1; + pci_mem_space.name = "ST40 PCI"; + pci_mem_space.flags = IORESOURCE_MEM; + + request_resource(&iomem_resource, &pci_mem_space); +} + int __init st40pci_init(unsigned memStart, unsigned memSize) { u32 lsr0; + printk("PCI version register reads 0x%x\n",ST40PCI_READ(VCR_VERSION)); + SetPCIPLL(); + st40pci_init_resources(); /* Initialises the ST40 pci subsystem, performing a reset, then programming * up the address space decoders appropriately @@ -184,21 +304,22 @@ /* Loop while core resets */ while (ST40PCI_READ(CR) & CR_SOFT_RESET); + /* Switch off interrupts */ + ST40PCI_WRITE(INTM, 0); + ST40PCI_WRITE(AINT, 0); + /* Now, lets reset all the cards on the bus with extreme prejudice */ ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL); udelay(250); /* Set bus active, take it out of reset */ - ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_CFINT | CR_PFCS | CR_PFE); + ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE); /* The PCI spec says that no access must be made to the bus until 1 second * after reset. This seem ludicrously long, but some delay is needed here */ mdelay(1000); - /* Switch off interrupts */ - ST40PCI_WRITE(INTM, 0); - ST40PCI_WRITE(AINT, 0); /* Allow it to be a master */ @@ -224,47 +345,24 @@ /* Set up the 64K window */ ST40PCI_WRITE(IOBMR, 0x0); - /* Now we set up the mbars so the PCI bus can see the memory of the machine */ + /* Now we set up the mbars so the PCI bus can see the local memory */ + /* Expose a 256M window starting at PCI address 0... */ + ST40PCI_WRITE(CSR_MBAR0, 0); + ST40PCI_WRITE(LSR0, 0x0fff0001); - if (memSize < (64 * 1024)) { - printk("Ridiculous memory size of 0x%x?\n",memSize); - return 0; - } - - lsr0 = - (memSize > - (512 * 1024 * 1024)) ? 0x1fff0001 : ((r2p2(memSize) - - 0x10000) | 0x1); - - ST40PCI_WRITE(LSR0, lsr0); - - ST40PCI_WRITE(CSR_MBAR0, memStart); - ST40PCI_WRITE(LAR0, memStart); + /* ... and set up the initial incomming window to expose all of RAM */ + pci_set_rbar_region(7, memStart, memStart, memSize); /* Maximise timeout values */ ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff); ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff); ST40PCI_WRITE_BYTE(CSR_MIT, 0xff); - - /* Install the pci interrupt handlers */ - make_intc2_irq(ST40PCI_SERR_IRQ, INTC2_BASE0, - ST40PCI_SERR_INT_GROUP, ST40PCI_SERR_INT_POS, - ST40PCI_SERR_INT_PRI); - - make_intc2_irq(ST40PCI_ERR_IRQ, INTC2_BASE0, ST40PCI_ERR_INT_GROUP, - ST40PCI_ERR_INT_POS, ST40PCI_ERR_INT_PRI); - + ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING); return 1; } -char * __init pcibios_setup(char *str) -{ - return str; -} - - #define SET_CONFIG_BITS(bus,devfn,where)\ (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0)) @@ -276,7 +374,7 @@ if (ST40PCI_READ(INT) & INT_MADIM) { /* Should we clear config space version as well ??? */ ST40PCI_WRITE(INT, INT_MADIM); - ST40PCI_WRITE_SHORT(CSR_STATUS, 0); + ST40PCI_WRITE_SHORT(CSR_STATUS, PCI_RMA); return 1; } @@ -287,6 +385,8 @@ static int st40pci_read_config_byte(struct pci_dev *dev, int where, u8 * val) { + CheckForMasterAbort(); + ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where)); *val = ST40PCI_READ_BYTE(PDR + (where & 3)); @@ -301,6 +401,8 @@ static int st40pci_read_config_word(struct pci_dev *dev, int where, u16 * val) { + CheckForMasterAbort(); + ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where)); *val = ST40PCI_READ_SHORT(PDR + (where & 2)); @@ -315,13 +417,15 @@ static int st40pci_read_config_dword(struct pci_dev *dev, int where, u32 * val) { + CheckForMasterAbort(); ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where)); *val = ST40PCI_READ(PDR); - if (CheckForMasterAbort()) + if (CheckForMasterAbort()) { *val = 0xffffffff; + } return PCIBIOS_SUCCESSFUL; } @@ -379,45 +483,37 @@ static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) { + printk("swizzle for dev %d on bus %d slot %d pin is %d\n", + dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin); return PCI_SLOT(dev->devfn); } +static inline u8 bridge_swizzle(u8 pin, u8 slot) +{ + return (((pin-1) + slot) % 4) + 1; +} -/* This needs to be shunted out of here into the board specific bit */ -#define HARP_PCI_IRQ 1 -#define HARP_BRIDGE_IRQ 2 -#define OVERDRIVE_SLOT0_IRQ 0 - -static int __init map_harp_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - switch (slot) { -#ifdef CONFIG_SH_STB1_HARP - case 2: /*This is the PCI slot on the */ - return HARP_PCI_IRQ; - case 1: /* this is the bridge */ - return HARP_BRIDGE_IRQ; -#elif defined(CONFIG_SH_STB1_OVERDRIVE) - case 1: - case 2: - case 3: - return slot - 1; -#else -#error Unknown board -#endif - default: - return -1; +u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) +{ + if (dev->bus->number != 0) { + u8 pin = *pinp; + do { + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + /* Move up the chain of bridges. */ + dev = dev->bus->self; + } while (dev->bus->self); + *pinp = pin; + + /* The slot is the slot of the last bridge. */ } -} + return PCI_SLOT(dev->devfn); +} void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) { - ranges->io_start -= bus->resource[0]->start; - ranges->io_end -= bus->resource[0]->start; - ranges->mem_start -= bus->resource[1]->start; - ranges->mem_end -= bus->resource[1]->start; } void __init pcibios_init(void) @@ -435,12 +531,20 @@ st40pci_init(PHYSADDR(memory_start), PHYSADDR(memory_end) - PHYSADDR(memory_start)); + if (request_irq(ST40PCI_SERR_IRQ, st40_pci_irq, + SA_INTERRUPT, "st40pci", NULL)) { + printk(KERN_ERR "st40pci: Cannot hook interrupt\n"); + return; + } + if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq, SA_INTERRUPT, "st40pci", NULL)) { printk(KERN_ERR "st40pci: Cannot hook interrupt\n"); return; } + /* Reset state just in case any outstanding (usually SERR) */ + ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0); /* Enable the PCI interrupts on the device */ ST40PCI_WRITE(INTM, ~0); ST40PCI_WRITE(AINT, ~0); @@ -454,10 +558,137 @@ /* ok, do the scan man */ pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); pci_assign_unassigned_resources(); - pci_fixup_irqs(no_swizzle, map_harp_irq); + pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq); } +void __init +pcibios_fixup_resource(struct resource *res, struct resource *root) +{ + res->start += root->start; + res->end += root->start; +} + +void __init +pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) +{ + /* Update device resources. */ + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + if (!dev->resource[i].start) + continue; + if (dev->resource[i].flags & IORESOURCE_IO) + pcibios_fixup_resource(&dev->resource[i], + &pci_io_space); + else if (dev->resource[i].flags & IORESOURCE_MEM) + pcibios_fixup_resource(&dev->resource[i], + &pci_mem_space); + } +} + void __init pcibios_fixup_bus(struct pci_bus *bus) { + /* Propogate hose info into the subordinate devices. */ + struct list_head *ln; + struct pci_dev *dev = bus->self; + + if (!dev) { + bus->resource[0] = &pci_io_space; + bus->resource[1] = &pci_mem_space; + } + + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *dev = pci_dev_b(ln); + if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) + pcibios_fixup_device_resources(dev, bus); + } +} + +static void __init pcibios_assign_resources(void) +{ + struct pci_dev *dev; + int idx; + struct resource *r; + pci_for_each_dev(dev) { + int class = dev->class >> 8; + + /* Don't touch classless devices and host bridges */ + if (!class || class == PCI_CLASS_BRIDGE_HOST) + continue; + + for(idx=0; idx<6; idx++) { + r = &dev->resource[idx]; + + /* + * Don't touch IDE controllers and I/O ports of video cards! + */ + if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) || + (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO))) + continue; + + /* + * We shall assign a new address to this resource, either because + * the BIOS forgot to do so or because we have decided the old + * address was unusable for some reason. + */ + if (!r->start && r->end) + { + pci_assign_resource(dev, idx); + } + } +#if 0 /* don't assign ROMs */ + if (pci_probe & PCI_ASSIGN_ROMS) { + r = &dev->resource[PCI_ROM_RESOURCE]; + r->end -= r->start; + r->start = 0; + if (r->end) + pci_assign_resource(dev, PCI_ROM_RESOURCE); + } +#endif + } +} + +/* + * Publish a region of local address space over the PCI bus + * to other devices. + */ +void pci_set_rbar_region(unsigned int region, unsigned long localAddr, + unsigned long pciOffset, unsigned long regionSize) +{ + unsigned long mask; + + if (region > 7) + return; + + if (regionSize > (512 * 1024 * 1024)) + return; + + mask = r2p2(regionSize) - 0x10000; + + /* Diable the region (in case currently in use, should never happen) */ + ST40PCI_WRITE_INDEXED(RSR, region, 0); + + /* Start of local address space to publish */ + ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) ); + + /* Start of region in PCI address space as an offset from MBAR0 */ + ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset); + + /* Size of region */ + ST40PCI_WRITE_INDEXED(RSR, region, mask | 1); +} + +/* + * Make a previously published region of local address space + * inaccessible to other PCI devices. + */ +void pci_clear_rbar_region(unsigned int region) +{ + if (region > 7) + return; + + ST40PCI_WRITE_INDEXED(RSR, region, 0); + ST40PCI_WRITE_INDEXED(RBAR, region, 0); + ST40PCI_WRITE_INDEXED(RLAR, region, 0); } diff -urN linux-2.4.21/arch/sh/kernel/pci_st40.h linux-2.4.22/arch/sh/kernel/pci_st40.h --- linux-2.4.21/arch/sh/kernel/pci_st40.h 2001-04-11 21:24:52.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/pci_st40.h 2003-08-25 04:44:40.000000000 -0700 @@ -33,13 +33,37 @@ #define ST40PCI_LAR0 0x1c #define ST40PCI_INT 0x24 +#define INT_MNLTDIM (1<<15) +#define INT_TTADI (1<<14) +#define INT_TMTO (1<<9) +#define INT_MDEI (1<<8) +#define INT_APEDI (1<<7) +#define INT_SDI (1<<6) +#define INT_DPEITW (1<<5) +#define INT_PEDITR (1<<4) +#define INT_TADIM (1<<3) #define INT_MADIM (1<<2) +#define INT_MWPDI (1<<1) +#define INT_MRDPEI (1<<0) #define ST40PCI_INTM 0x28 #define ST40PCI_AIR 0x2c + #define ST40PCI_CIR 0x30 +#define CIR_PIOTEM (1<<31) +#define CIR_RWTET (1<<26) + + #define ST40PCI_AINT 0x40 +#define AINT_MBI (1<<13) +#define AINT_TBTOI (1<<12) +#define AINT_MBTOI (1<<11) +#define AINT_TAI (1<<3) +#define AINT_MAI (1<<2) +#define AINT_RDPEI (1<<1) +#define AINT_WDPE (1<<0) + #define ST40PCI_AINTM 0x44 #define ST40PCI_BMIR 0x48 #define ST40PCI_PAR 0x4c @@ -51,11 +75,58 @@ #define ST40PCI_IOBMR 0x74 #define ST40PCI_PDR 0x78 +/* H8 specific registers start here */ +#define ST40PCI_WCBAR 0x7c +#define ST40PCI_LOCCFG_UNLOCK 0x34 + +#define ST40PCI_RBAR0 0x100 +#define ST40PCI_RSR0 0x104 +#define ST40PCI_RLAR0 0x108 + +#define ST40PCI_RBAR1 0x110 +#define ST40PCI_RSR1 0x114 +#define ST40PCI_RLAR1 0x118 + + +#define ST40PCI_RBAR2 0x120 +#define ST40PCI_RSR2 0x124 +#define ST40PCI_RLAR2 0x128 + +#define ST40PCI_RBAR3 0x130 +#define ST40PCI_RSR3 0x134 +#define ST40PCI_RLAR3 0x138 + +#define ST40PCI_RBAR4 0x140 +#define ST40PCI_RSR4 0x144 +#define ST40PCI_RLAR4 0x148 + +#define ST40PCI_RBAR5 0x150 +#define ST40PCI_RSR5 0x154 +#define ST40PCI_RLAR5 0x158 + +#define ST40PCI_RBAR6 0x160 +#define ST40PCI_RSR6 0x164 +#define ST40PCI_RLAR6 0x168 + +#define ST40PCI_RBAR7 0x170 +#define ST40PCI_RSR7 0x174 +#define ST40PCI_RLAR7 0x178 + + +#define ST40PCI_RBAR(n) (0x100+(0x10*(n))) +#define ST40PCI_RSR(n) (0x104+(0x10*(n))) +#define ST40PCI_RLAR(n) (0x108+(0x10*(n))) + +#define ST40PCI_PERF 0x80 +#define PERF_MASTER_WRITE_POSTING (1<<4) +/* H8 specific registers end here */ + /* These are configs space registers */ #define ST40PCI_CSR_VID 0x10000 #define ST40PCI_CSR_DID 0x10002 #define ST40PCI_CSR_CMD 0x10004 #define ST40PCI_CSR_STATUS 0x10006 +#define PCI_RMA (1<<13) #define ST40PCI_CSR_MBAR0 0x10010 #define ST40PCI_CSR_TRDY 0x10040 #define ST40PCI_CSR_RETRY 0x10041 @@ -63,4 +134,10 @@ #define ST40_IO_ADDR 0xb6000000 +#define ST40PCI_INTPIN 0x1003d + +void pci_set_rbar_region(unsigned int region, unsigned long localAddr, + unsigned long pciOffset, unsigned long regionSize); +void pci_clear_rbar_region(unsigned int region); + #endif /* __PCI_ST40_H__ */ diff -urN linux-2.4.21/arch/sh/kernel/process.c linux-2.4.22/arch/sh/kernel/process.c --- linux-2.4.21/arch/sh/kernel/process.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.35 2001/10/11 09:18:17 gniibe Exp $ +/* $Id: process.c,v 1.1.1.1.2.4 2003/05/29 04:21:33 lethal Exp $ * * linux/arch/sh/kernel/process.c * @@ -21,6 +21,8 @@ static int hlt_counter=0; +int ubc_usercnt = 0; + #define HARD_IDLE_TIMEOUT (HZ / 3) void disable_hlt(void) @@ -45,8 +47,9 @@ while (1) { if (hlt_counter) { - if (current->need_resched) - break; + while (1) + if (current->need_resched) + break; } else { __cli(); while (!current->need_resched) { @@ -148,7 +151,10 @@ */ void exit_thread(void) { - /* Nothing to do. */ + if (current->thread.ubc_pc1) { + current->thread.ubc_pc1 = 0; + ubc_usercnt -= 1; + } } void flush_thread(void) @@ -179,11 +185,7 @@ fpvalid = tsk->used_math; if (fpvalid) { - unsigned long flags; - - save_and_cli(flags); unlazy_fpu(tsk); - restore_flags(flags); memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); } @@ -203,15 +205,9 @@ #if defined(__SH4__) struct task_struct *tsk = current; - if (tsk != &init_task) { - unsigned long flags; - - save_and_cli(flags); - unlazy_fpu(tsk); - restore_flags(flags); - p->thread.fpu = current->thread.fpu; - p->used_math = tsk->used_math; - } + unlazy_fpu(tsk); + p->thread.fpu = current->thread.fpu; + p->used_math = tsk->used_math; #endif childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1; *childregs = *regs; @@ -227,6 +223,9 @@ p->thread.sp = (unsigned long) childregs; p->thread.pc = (unsigned long) ret_from_fork; + p->thread.ubc_pc1 = 0; + p->thread.ubc_pc2 = 0; + return 0; } @@ -250,6 +249,37 @@ dump->u_fpvalid = dump_fpu(regs, &dump->fpu); } +/* Tracing by user break controller. */ +static inline void +ubc_set_tracing(int asid, unsigned long nextpc1, unsigned nextpc2) +{ + ctrl_outl(nextpc1, UBC_BARA); + ctrl_outb(asid, UBC_BASRA); + if(UBC_TYPE_SH7729){ + ctrl_outl(0, UBC_BAMRA); + ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); + }else{ + ctrl_outb(0, UBC_BAMRA); + ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA); + } + + if (nextpc2 != (unsigned long) -1) { + ctrl_outl(nextpc2, UBC_BARB); + ctrl_outb(asid, UBC_BASRB); + if(UBC_TYPE_SH7729){ + ctrl_outl(0, UBC_BAMRB); + ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRB); + }else{ + ctrl_outb(0, UBC_BAMRB); + ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB); + } + } + if(UBC_TYPE_SH7729) + ctrl_outl(BRCR_PCTE, UBC_BRCR); + else + ctrl_outw(0, UBC_BRCR); +} + /* * switch_to(x,y) should switch tasks from x to y. * @@ -257,14 +287,9 @@ void __switch_to(struct task_struct *prev, struct task_struct *next) { #if defined(__SH4__) - if (prev != &init_task) { - unsigned long flags; - - save_and_cli(flags); - unlazy_fpu(prev); - restore_flags(flags); - } + unlazy_fpu(prev); #endif + /* * Restore the kernel mode register * k7 (r7_bank1) @@ -272,6 +297,19 @@ asm volatile("ldc %0, r7_bank" : /* no output */ :"r" (next)); + + /* If no tasks are using the UBC, we're done */ + if (ubc_usercnt == 0) + return; + + /* Otherwise, set or clear UBC as appropriate */ + if (next->thread.ubc_pc1) { + ubc_set_tracing(next->mm->context & MMU_CONTEXT_ASID_MASK, + next->thread.ubc_pc1, next->thread.ubc_pc2); + } else { + ctrl_outw(0, UBC_BBRA); + ctrl_outw(0, UBC_BBRB); + } } asmlinkage int sys_fork(unsigned long r4, unsigned long r5, @@ -375,6 +413,9 @@ /* Clear tracing. */ ctrl_outw(0, UBC_BBRA); ctrl_outw(0, UBC_BBRB); + current->thread.ubc_pc1 = 0; + current->thread.ubc_pc2 = (unsigned long) -1; + ubc_usercnt -= 1; force_sig(SIGTRAP, current); } diff -urN linux-2.4.21/arch/sh/kernel/ptrace.c linux-2.4.22/arch/sh/kernel/ptrace.c --- linux-2.4.21/arch/sh/kernel/ptrace.c 2001-10-15 13:36:48.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/ptrace.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: ptrace.c,v 1.13 2001/10/01 02:21:50 gniibe Exp $ +/* $Id: ptrace.c,v 1.1.1.1.2.1 2002/11/12 02:24:19 jzs Exp $ * * linux/arch/sh/kernel/ptrace.c * @@ -71,6 +71,8 @@ /* bra & bsr */ if (nib[0] == 0xa || nib[0] == 0xb) { *pc1 = regs->pc + 4 + ((short) ((inst & 0xfff) << 4) >> 3); + if(*pc1 == regs->pc + 2) + *pc1 = regs->pc + 4; *pc2 = (unsigned long) -1; return; } @@ -85,7 +87,12 @@ /* bt/s & bf/s */ if (nib[0] == 0x8 && (nib[1] == 0xd || nib[1] == 0xf)) { *pc1 = regs->pc + 4 + ((char) (inst & 0xff) << 1); - *pc2 = regs->pc + 4; + if(*pc1 == regs->pc + 2) { + *pc1 = regs->pc + 4; + *pc2 = (unsigned long) -1; + } + else + *pc2 = regs->pc + 4; return; } @@ -93,6 +100,8 @@ if (nib[0] == 0x4 && nib[3] == 0xb && (nib[2] == 0x0 || nib[2] == 0x2)) { *pc1 = regs->regs[nib[1]]; + if(*pc1 == regs->pc + 2) + *pc1 = regs->pc + 4; *pc2 = (unsigned long) -1; return; } @@ -101,12 +110,16 @@ if (nib[0] == 0x0 && nib[3] == 0x3 && (nib[2] == 0x0 || nib[2] == 0x2)) { *pc1 = regs->pc + 4 + regs->regs[nib[1]]; + if(*pc1 == regs->pc + 2) + *pc1 = regs->pc + 4; *pc2 = (unsigned long) -1; return; } if (inst == 0x000b) { *pc1 = regs->pr; + if(*pc1 == regs->pc + 2) + *pc1 = regs->pc + 4; *pc2 = (unsigned long) -1; return; } @@ -116,37 +129,6 @@ return; } -/* Tracing by user break controller. */ -static void -ubc_set_tracing(int asid, unsigned long nextpc1, unsigned nextpc2) -{ - ctrl_outl(nextpc1, UBC_BARA); - ctrl_outb(asid, UBC_BASRA); - if(UBC_TYPE_SH7729){ - ctrl_outl(0x0fff, UBC_BAMRA); - ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); - }else{ - ctrl_outb(BAMR_12, UBC_BAMRA); - ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA); - } - - if (nextpc2 != (unsigned long) -1) { - ctrl_outl(nextpc2, UBC_BARB); - ctrl_outb(asid, UBC_BASRB); - if(UBC_TYPE_SH7729){ - ctrl_outl(0x0fff, UBC_BAMRB); - ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRB); - }else{ - ctrl_outb(BAMR_12, UBC_BAMRB); - ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB); - } - } - if(UBC_TYPE_SH7729) - ctrl_outl(BRCR_PCBA | BRCR_PCBB | BRCR_PCTE, UBC_BRCR); - else - ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR); -} - /* * Called by kernel/ptrace.c when detaching.. * @@ -342,8 +324,11 @@ if (nextpc2 != (unsigned long) -1 && (nextpc2 & 0x80000000)) break; - ubc_set_tracing(child->mm->context & MMU_CONTEXT_ASID_MASK, - nextpc1, nextpc2); + /* Next scheduling will set up UBC */ + if (child->thread.ubc_pc1 == 0) + ubc_usercnt += 1; + child->thread.ubc_pc1 = nextpc1; + child->thread.ubc_pc2 = nextpc2; child->exit_code = data; /* give it a chance to run. */ diff -urN linux-2.4.21/arch/sh/kernel/rtc-snapgear.c linux-2.4.22/arch/sh/kernel/rtc-snapgear.c --- linux-2.4.21/arch/sh/kernel/rtc-snapgear.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/rtc-snapgear.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,323 @@ +/****************************************************************************/ +/* + * linux/arch/sh/kernel/rtc-snapgear.c -- Secureedge5410 RTC code + * + * Copyright (C) 2002 David McCullough + * + * The SecureEdge5410 can have one of 2 real time clocks, the SH + * built in version or the preferred external DS1302. Here we work out + * each to see what we have and then run with it. + */ +/****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/****************************************************************************/ + +static int use_ds1302 = 0; + +/****************************************************************************/ +/* + * we need to implement a DS1302 driver here that can operate in + * conjunction with the builtin rtc driver which is already quite friendly + */ +/*****************************************************************************/ + +#define RTC_CMD_READ 0x81 /* Read command */ +#define RTC_CMD_WRITE 0x80 /* Write command */ + +#define RTC_ADDR_YEAR 0x06 /* Address of year register */ +#define RTC_ADDR_DAY 0x05 /* Address of day of week register */ +#define RTC_ADDR_MON 0x04 /* Address of month register */ +#define RTC_ADDR_DATE 0x03 /* Address of day of month register */ +#define RTC_ADDR_HOUR 0x02 /* Address of hour register */ +#define RTC_ADDR_MIN 0x01 /* Address of minute register */ +#define RTC_ADDR_SEC 0x00 /* Address of second register */ + +#define RTC_RESET 0x1000 +#define RTC_IODATA 0x0800 +#define RTC_SCLK 0x0400 + +#define set_dirp(x) +#define get_dirp(x) 0 +#define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) +#define get_dp(x) SECUREEDGE_READ_IOPORT() + +static void ds1302_sendbits(unsigned int val) +{ + int i; + + for (i = 8; (i); i--, val >>= 1) { + set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? RTC_IODATA : 0)); + set_dp(get_dp() | RTC_SCLK); // clock high + set_dp(get_dp() & ~RTC_SCLK); // clock low + } +} + +static unsigned int ds1302_recvbits(void) +{ + unsigned int val; + int i; + + for (i = 0, val = 0; (i < 8); i++) { + val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); + set_dp(get_dp() | RTC_SCLK); // clock high + set_dp(get_dp() & ~RTC_SCLK); // clock low + } + return(val); +} + +static unsigned int ds1302_readbyte(unsigned int addr) +{ + unsigned int val; + unsigned long flags; + +#if 0 + printk("SnapGear RTC: ds1302_readbyte(addr=%x)\n", addr); +#endif + + save_flags(flags); cli(); + set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); + set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); + + set_dp(get_dp() | RTC_RESET); + ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); + set_dirp(get_dirp() & ~RTC_IODATA); + val = ds1302_recvbits(); + set_dp(get_dp() & ~RTC_RESET); + restore_flags(flags); + + return(val); +} + +static void ds1302_writebyte(unsigned int addr, unsigned int val) +{ + unsigned long flags; + +#if 0 + printk("SnapGear RTC: ds1302_writebyte(addr=%x)\n", addr); +#endif + + save_flags(flags); cli(); + set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); + set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); + set_dp(get_dp() | RTC_RESET); + ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); + ds1302_sendbits(val); + set_dp(get_dp() & ~RTC_RESET); + restore_flags(flags); +} + +static void ds1302_reset(void) +{ + unsigned long flags; + /* Hardware dependant reset/init */ + save_flags(flags); cli(); + set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); + set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); + restore_flags(flags); +} + +/*****************************************************************************/ + +static inline int bcd2int(int val) +{ + return((((val & 0xf0) >> 4) * 10) + (val & 0xf)); +} + +static inline int int2bcd(int val) +{ + return(((val / 10) << 4) + (val % 10)); +} + +/*****************************************************************************/ +/* + * Write and Read some RAM in the DS1302, if it works assume it's there + * Otherwise use the SH4 internal RTC + */ + +void __init secureedge5410_rtc_init(void) +{ + unsigned char *test = "snapgear"; + int i; + + ds1302_reset(); + + use_ds1302 = 1; + + for (i = 0; test[i]; i++) + ds1302_writebyte(32 + i, test[i]); + + for (i = 0; test[i]; i++) + if (ds1302_readbyte(32 + i) != test[i]) { + use_ds1302 = 0; + break; + } + + printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal"); +} + +/****************************************************************************/ +/* + * our generic interface that chooses the correct code to use + */ + +void snapgear_rtc_gettimeofday(struct timeval *tv) +{ + unsigned int sec, min, hr, day, mon, yr; + + if (!use_ds1302) { + sh_rtc_gettimeofday(tv); + return; + } + + sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC)); + min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); + hr = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR)); + day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE)); + mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON)); + yr = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR)); + +bad_time: + if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || + hr > 23 || min > 59 || sec > 59) { + printk(KERN_ERR + "SnapGear RTC: invalid value, resetting to 1 Jan 2000\n"); + ds1302_writebyte(RTC_ADDR_MIN, min = 0); + ds1302_writebyte(RTC_ADDR_HOUR, hr = 0); + ds1302_writebyte(RTC_ADDR_DAY, 7); + ds1302_writebyte(RTC_ADDR_DATE, day = 1); + ds1302_writebyte(RTC_ADDR_MON, mon = 1); + ds1302_writebyte(RTC_ADDR_YEAR, yr = 0); + ds1302_writebyte(RTC_ADDR_SEC, sec = 0); + } + + tv->tv_sec = mktime(2000 + yr, mon, day, hr, min, sec); + if (tv->tv_sec < 0) { +#if 0 + printk("BAD TIME %d %d %d %d %d %d\n", yr, mon, day, hr, min, sec); +#endif + yr = 100; + goto bad_time; + } + tv->tv_usec = 0; +} + +int snapgear_rtc_settimeofday(const struct timeval *tv) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned long nowtime; + + if (!use_ds1302) { + sh_rtc_settimeofday(tv); + return(0); + } + +/* + * This is called direct from the kernel timer handling code. + * It is supposed to synchronize the kernel clock to the RTC. + */ + + nowtime = tv->tv_sec; + +#if 1 + printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime); +#endif + + /* STOP RTC */ + ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); + + cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes)); + ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds)); + } else { + printk(KERN_WARNING + "SnapGear RTC: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + /* START RTC */ + ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); + return(0); +} + +unsigned char secureedge5410_cmos_read(int addr) +{ + unsigned char val = 0; + + if (!use_ds1302) + return(__CMOS_READ(addr, w)); + + switch(addr) { + case RTC_SECONDS: val = ds1302_readbyte(RTC_ADDR_SEC); break; + case RTC_SECONDS_ALARM: break; + case RTC_MINUTES: val = ds1302_readbyte(RTC_ADDR_MIN); break; + case RTC_MINUTES_ALARM: break; + case RTC_HOURS: val = ds1302_readbyte(RTC_ADDR_HOUR); break; + case RTC_HOURS_ALARM: break; + case RTC_DAY_OF_WEEK: val = ds1302_readbyte(RTC_ADDR_DAY); break; + case RTC_DAY_OF_MONTH: val = ds1302_readbyte(RTC_ADDR_DATE); break; + case RTC_MONTH: val = ds1302_readbyte(RTC_ADDR_MON); break; + case RTC_YEAR: val = ds1302_readbyte(RTC_ADDR_YEAR); break; + case RTC_REG_A: /* RTC_FREQ_SELECT */ break; + case RTC_REG_B: /* RTC_CONTROL */ break; + case RTC_REG_C: /* RTC_INTR_FLAGS */ break; + case RTC_REG_D: val = RTC_VRT /* RTC_VALID */; break; + default: break; + } + + return(val); +} + +void secureedge5410_cmos_write(unsigned char val, int addr) +{ + if (!use_ds1302) { + __CMOS_WRITE(val, addr, w); + return; + } + + switch(addr) { + case RTC_SECONDS: ds1302_writebyte(RTC_ADDR_SEC, val); break; + case RTC_SECONDS_ALARM: break; + case RTC_MINUTES: ds1302_writebyte(RTC_ADDR_MIN, val); break; + case RTC_MINUTES_ALARM: break; + case RTC_HOURS: ds1302_writebyte(RTC_ADDR_HOUR, val); break; + case RTC_HOURS_ALARM: break; + case RTC_DAY_OF_WEEK: ds1302_writebyte(RTC_ADDR_DAY, val); break; + case RTC_DAY_OF_MONTH: ds1302_writebyte(RTC_ADDR_DATE, val); break; + case RTC_MONTH: ds1302_writebyte(RTC_ADDR_MON, val); break; + case RTC_YEAR: ds1302_writebyte(RTC_ADDR_YEAR, val); break; + case RTC_REG_A: /* RTC_FREQ_SELECT */ break; + case RTC_REG_B: /* RTC_CONTROL */ break; + case RTC_REG_C: /* RTC_INTR_FLAGS */ break; + case RTC_REG_D: /* RTC_VALID */ break; + default: break; + } +} + +/****************************************************************************/ diff -urN linux-2.4.21/arch/sh/kernel/rtc.c linux-2.4.22/arch/sh/kernel/rtc.c --- linux-2.4.21/arch/sh/kernel/rtc.c 2002-02-25 11:37:56.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/rtc.c 2003-08-25 04:44:40.000000000 -0700 @@ -23,7 +23,7 @@ void sh_rtc_gettimeofday(struct timeval *tv) { - unsigned int sec128, sec, min, hr, wk, day, mon, yr, yr100; + unsigned int sec128, sec, min, hr, wk, day, mon, yr, yr100, badval; again: do { @@ -53,16 +53,21 @@ } #endif - BCD_TO_BIN(yr100); - BCD_TO_BIN(yr); - BCD_TO_BIN(mon); - BCD_TO_BIN(day); - BCD_TO_BIN(hr); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); + badval = ((yr & 15) > 9 || (mon & 15) > 9 || (day & 15) > 9 || + (hr & 15) > 9 || (min & 15) > 9 || (sec & 15) > 9); - if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || - hr > 23 || min > 59 || sec > 59) { + if (!badval) { + BCD_TO_BIN(yr100); + BCD_TO_BIN(yr); + BCD_TO_BIN(mon); + BCD_TO_BIN(day); + BCD_TO_BIN(hr); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + } + + if (badval || yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || + hr > 23 || min > 59 || sec > 59 || (yr100 != 19 && yr100 != 20)) { printk(KERN_ERR "SH RTC: invalid value, resetting to 1 Jan 2000\n"); ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */ diff -urN linux-2.4.21/arch/sh/kernel/setup.c linux-2.4.22/arch/sh/kernel/setup.c --- linux-2.4.21/arch/sh/kernel/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.31 2001/08/23 16:36:40 dwmw2 Exp $ +/* $Id: setup.c,v 1.1.1.1.2.7 2003/06/20 13:13:25 trent Exp $ * * linux/arch/sh/kernel/setup.c * @@ -44,6 +44,11 @@ #include #endif +#ifdef CONFIG_SH_KGDB +#include +static int kgdb_parse_options(char *options); +#endif + /* * Machine setup.. */ @@ -298,6 +303,10 @@ parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable); +#ifdef CONFIG_CMDLINE_BOOL + sprintf(*cmdline_p, CONFIG_CMDLINE); +#endif + #ifdef CONFIG_SH_GENERIC if (mv == NULL) { mv = &mv_unknown; @@ -475,10 +484,20 @@ } #if defined(__SH4__) - /* We already grab/initialized FPU in head.S. Make it consisitent. */ - init_task.used_math = 1; - init_task.flags |= PF_USEDFPU; + init_task.used_math = 0; + init_task.flags &= ~PF_USEDFPU; +#endif + +#ifdef CONFIG_UBC_WAKEUP + /* + * Some brain-damaged loaders decided it would be a good idea to put + * the UBC to sleep. This causes some issues when it comes to things + * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. + * we wake it up and hope that all is well. + */ + ubc_wakeup(); #endif + paging_init(); } @@ -528,7 +547,7 @@ PRINT_CLOCK("CPU", boot_cpu_data.cpu_clock); PRINT_CLOCK("Bus", boot_cpu_data.bus_clock); -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 PRINT_CLOCK("Memory", boot_cpu_data.memory_clock); #endif PRINT_CLOCK("Peripheral module", boot_cpu_data.module_clock); @@ -553,4 +572,94 @@ stop: c_stop, show: show_cpuinfo, }; -#endif +#endif /* CONFIG_PROC_FS */ + +#ifdef CONFIG_SH_KGDB +/* + * Parse command-line kgdb options. By default KGDB is enabled, + * entered on error (or other action) using default serial info. + * The command-line option can include a serial port specification + * and an action to override default or configured behavior. + */ +struct kgdb_sermap kgdb_sci_sermap = +{ "ttySC", 5, kgdb_sci_setup, NULL }; + +struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap; +struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap; + +void kgdb_register_sermap(struct kgdb_sermap *map) +{ + struct kgdb_sermap *last; + + for (last = kgdb_serlist; last->next; last = last->next) + ; + last->next = map; + if (!map->namelen) { + map->namelen = strlen(map->name); + } +} + +static int __init kgdb_parse_options(char *options) +{ + char c; + int baud; + + /* Check for port spec (or use default) */ + + /* Determine port type and instance */ + if (!memcmp(options, "tty", 3)) { + struct kgdb_sermap *map = kgdb_serlist; + + while (map && memcmp(options, map->name, map->namelen)) + map = map->next; + + if (!map) { + KGDB_PRINTK("unknown port spec in %s\n", options); + return -1; + } + + kgdb_porttype = map; + kgdb_serial_setup = map->setup_fn; + kgdb_portnum = options[map->namelen] - '0'; + options += map->namelen + 1; + + options = (*options == ',') ? options+1 : options; + + /* Read optional parameters (baud/parity/bits) */ + baud = simple_strtoul(options, &options, 10); + if (baud != 0) { + kgdb_baud = baud; + + c = toupper(*options); + if (c == 'E' || c == 'O' || c == 'N') { + kgdb_parity = c; + options++; + } + + c = *options; + if (c == '7' || c == '8') { + kgdb_bits = c; + options++; + } + options = (*options == ',') ? options+1 : options; + } + } + + /* Check for action specification */ + if (!memcmp(options, "halt", 4)) { + kgdb_halt = 1; + options += 4; + } else if (!memcmp(options, "disabled", 8)) { + kgdb_enabled = 0; + options += 8; + } + + if (*options) { + KGDB_PRINTK("ignored unknown options: %s\n", options); + return 0; + } + return 1; +} +__setup("kgdb=", kgdb_parse_options); +#endif /* CONFIG_SH_KGDB */ + diff -urN linux-2.4.21/arch/sh/kernel/setup_hs7729pci.c linux-2.4.22/arch/sh/kernel/setup_hs7729pci.c --- linux-2.4.21/arch/sh/kernel/setup_hs7729pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/setup_hs7729pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,212 @@ +/* $Id: setup_hs7729pci.c,v 1.1.2.1 2003/06/24 08:45:47 dwmw2 Exp $ + * + * linux/arch/sh/kernel/setup_hs7729pci.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi Semiconductor and Devices HS7729PCI Support. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +static int interrupt_count; +static int sevenseg_count; + +extern unsigned char aux_device_present; + +/* + * Configure the Super I/O chip + */ +static void __init smsc_config(int index, int data) +{ + outb_p(index, INDEX_PORT); + outb_p(data, DATA_PORT); +} + +static void __init init_smsc(void) +{ + outb_p(CONFIG_ENTER, CONFIG_PORT); + outb_p(CONFIG_ENTER, CONFIG_PORT); + +#if defined(CONFIG_BLK_DEV_FD) + /* FDC */ + smsc_config(CURRENT_LDN_INDEX, LDN_FDC); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */ +#endif + +#if defined(CONFIG_BLK_DEV_IDE) + /* IDE1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_IDE1); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */ + smsc_config(IO_BASE_HI_INDEX, 0x01); + smsc_config(IO_BASE_LO_INDEX, 0x70); + smsc_config(0x62, 0x03); + smsc_config(0x63, 0x76); + +#if 0 +#define SMSC_RD(adr) ({ outb(adr, 0x3f0), inb(0x3f1); }) + + printk("IDE1 addrs 0x%02x%02x, 0x%02x%02x\n", SMSC_RD(0x60), SMSC_RD(0x61), SMSC_RD(0x62), SMSC_RD(0x63)); + printk("IDE1 Reg 0xF0: %02x. IDE1 Reg 0xF1: %02x\n", SMSC_RD(0xf0), SMSC_RD(0xf1)); + printk("Power reg: %02x\n", SMSC_RD(0x22)); + smsc_config(0x22, 0x3f); + printk("Power reg changed to: %02x\n", SMSC_RD(0x22)); +#endif +#endif + + /* AUXIO (GPIO): to use IDE1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO); + smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */ + smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */ + +#if defined(CONFIG_SERIAL) + /* COM1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_COM1); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IO_BASE_HI_INDEX, 0x03); + smsc_config(IO_BASE_LO_INDEX, 0xf8); + smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */ + + /* COM2 */ + smsc_config(CURRENT_LDN_INDEX, LDN_COM2); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IO_BASE_HI_INDEX, 0x02); + smsc_config(IO_BASE_LO_INDEX, 0xf8); + smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */ +#endif + + /* RTC */ + smsc_config(CURRENT_LDN_INDEX, LDN_RTC); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */ + +#if defined(CONFIG_VT) + disable_irq(1); + + /* KBD */ + smsc_config(CURRENT_LDN_INDEX, LDN_KBC); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 1); /* IRQ1 */ + smsc_config(IRQ_SELECT_INDEX+2, 12); /* IRQ12 */ + + /* Let it probe for PS/2 port. It should find one. */ + aux_device_present = 0; +#endif + +#if defined(CONFIG_PARPORT) + /* PARALLEL */ + smsc_config(CURRENT_LDN_INDEX, LDN_PARPORT); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IO_BASE_HI_INDEX, 0x03); + smsc_config(IO_BASE_LO_INDEX, 0x78); + smsc_config(IRQ_SELECT_INDEX, 5); /* IRQ5 */ +#endif + + outb_p(CONFIG_EXIT, CONFIG_PORT); +} + +/* + * Initialize IRQ setting + */ +void __init init_hs7729pci_IRQ(void) +{ + /* + * Super I/O (Just mimic PC): + * 0: SD0001 + * 1: keyboard + * 3: serial 0 + * 4: serial 1 + * 5: printer + * 6: floppy + * 8: rtc + * 12: mouse + * 14: ide0 + */ + ctrl_outw(0x0130, BCR_ILCRA); + ctrl_outw(0x0070, BCR_ILCRB); + ctrl_outw(0x9abc, BCR_ILCRC); + ctrl_outw(0xef84, BCR_ILCRD); + ctrl_outw(0x0506, BCR_ILCRE); + ctrl_outw(0x0002, BCR_ILCRF); + ctrl_outw(0x000d, BCR_ILCRG); + + make_ipr_irq(15, BCR_ILCRA, 3, 0x00); /* IRQ15 */ + make_ipr_irq(14, BCR_ILCRA, 2, 0x01); /* IRQ14 */ + make_ipr_irq(12, BCR_ILCRA, 1, 0x03); /* IRQ12 */ + + make_ipr_irq( 8, BCR_ILCRB, 1, 0x07); /* IRQ8 */ + + make_ipr_irq( 6, BCR_ILCRC, 3, 0x09); /* IRQ6 */ + make_ipr_irq( 5, BCR_ILCRC, 2, 0x0a); /* IRQ5 */ + make_ipr_irq( 4, BCR_ILCRC, 1, 0x0b); /* IRQ4 */ + make_ipr_irq( 3, BCR_ILCRC, 0, 0x0c); /* IRQ3 */ + + make_ipr_irq( 1, BCR_ILCRD, 3, 0x0e); /* IRQ1 */ + make_ipr_irq( 0, BCR_ILCRD, 2, 0x0f); /* PCI_IRQ0 */ + make_ipr_irq( 7, BCR_ILCRD, 1, 0x08); /* USB1_IRQ */ + make_ipr_irq(11, BCR_ILCRD, 0, 0x04); /* USB2_IRQ */ + + make_ipr_irq(10, BCR_ILCRE, 2, 0x05); /* PC_IRQ2 */ + make_ipr_irq( 9, BCR_ILCRE, 0, 0x06); /* PC_IRQ1 */ + + make_ipr_irq(13, BCR_ILCRF, 0, 0x02); /* SLOT_IRQ5 */ + + make_ipr_irq( 2, BCR_ILCRG, 0, 0x0d); /* SLOT_IRQ1 */ +} + +/* + * Initialize the board + */ + +void __init setup_hs7729pci(void) +{ + init_smsc(); + /* XXX: RTC setting comes here */ + interrupt_count = 0; + sevenseg_count = 0; + ctrl_outw(0xffff, PA_LED); + ctrl_outw(0x3f3f, PA_7SEG); +} + +void debug_interrupt(void) +{ + ctrl_outw(interrupt_count, PA_LED); + if (interrupt_count == 0xffff) + interrupt_count = 0; + else + interrupt_count++; +} + +static int sevenseg_data[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, + 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; + +void set_sevenseg(unsigned char val) +{ + unsigned short data; + + data = sevenseg_data[(val & 0xf0) >> 4] << 8; + data |= sevenseg_data[val & 0x0f]; + + ctrl_outw(data, PA_7SEG); +} + +void debug_sevenseg(void) +{ + set_sevenseg(sevenseg_count); + + if (sevenseg_count == 0xff) + sevenseg_count = 0; + else + sevenseg_count++; +} diff -urN linux-2.4.21/arch/sh/kernel/setup_keywest.c linux-2.4.22/arch/sh/kernel/setup_keywest.c --- linux-2.4.21/arch/sh/kernel/setup_keywest.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/setup_keywest.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,215 @@ +/* + * + * By Dustin McIntire (dustin@sensoria.com) (c)2001 + * + * Setup and IRQ handling code for the HD64465 companion chip. + * by Greg Banks + * Copyright (c) 2000 PocketPenguins Inc + * + * Derived from setup_hd64465.c which bore the message: + * Greg Banks + * Copyright (c) 2000 PocketPenguins Inc and + * Copyright (C) 2000 YAEGASHI Takeshi + * and setup_cqreek.c which bore message: + * Copyright (C) 2000 Niibe Yutaka + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Setup and IRQ functions for a Hitachi Big Sur Evaluation Board. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +//#define KEYWEST_DEBUG 3 +#undef KEYWEST_DEBUG + +//LED +#define ALPHA_LED 0xb1ffe038 + +#ifdef KEYWEST_DEBUG +#define DPRINTK(args...) printk(args) +#define DIPRINTK(n, args...) if (KEYWEST_DEBUG>(n)) printk(args) +#else +#define DPRINTK(args...) +#define DIPRINTK(n, args...) +#endif /* KEYWEST_DEBUG */ + +#ifdef CONFIG_HD64465 +extern int hd64465_irq_demux(int irq); +#endif /* CONFIG_HD64465 */ + +extern void keywest_alpha(int i, char ch); + +int keywest_irq_demux(int irq) +{ + int demux_irq = irq; + +#ifdef CONFIG_HD64465 + demux_irq = hd64465_irq_demux(demux_irq); +#endif /* CONFIG_HD64465 */ + +#ifndef CONFIG_SH_GENERIC + demux_irq = ipr_irq_demux(demux_irq); +#endif + + return demux_irq; +} + + +void __init init_keywest_IRQ(void) +{ + if (!MACH_KEYWEST) return; + +} + +void keywest_puts(const char* s) +{ + int n = 0; + + while (*s) { keywest_alpha(n++, *s++); } + while (n < 8) { keywest_alpha(n++, ' '); } +} +EXPORT_SYMBOL(keywest_puts); + +void keywest_printf(const char* fmt, ...) +{ + char buffer[32]; + va_list ap; + + va_start(ap, fmt); + vsprintf(buffer, fmt, ap); + va_end(ap); + keywest_puts(buffer); +} +EXPORT_SYMBOL(keywest_printf); + +static void tahoe_init(void) +{ +#ifdef CONFIG_HD64465 + if (inw(HD64465_REG_SDID) != HD64465_SDID) { + printk("Tahoe board is not present.\n"); + + return; + } + + printk("Hitachi HD64465 chip support (%d.%d)\n", + inw(HD64465_REG_SRR) >> 8, inw(HD64465_REG_SRR) & 0xFF); + + outw(~0, HD64465_REG_NIMR); + //outw(0x03, HD64465_REG_SPLLCR); +#ifdef CONFIG_VT + outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PS2ST), HD64465_REG_SMSCR); /* PS2 */ + //outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_KBCST), HD64465_REG_SMSCR); /* keyboard */ +#endif +#ifdef CONFIG_SERIAL + outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_UARTST), HD64465_REG_SMSCR); /* UART */ +#endif +#ifdef CONFIG_PARPORT + outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PPST), HD64465_REG_SMSCR); /* PARPORT */ +#endif + +#ifdef CONFIG_PCMCIA + outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PC0ST), HD64465_REG_SMSCR); /* PC0 */ + outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PC1ST), HD64465_REG_SMSCR); /* PC1 */ + + /* turn on PCMCIA area 5 and 6 in BCR1 */ + * (unsigned short *) 0xffffff60 |= 0x3; + + /* must put both area 5 and 6 into 8 or 16 bit mode in BCR2 */ + * (unsigned short *) 0xffffff62 &= ~0x3c00; + * (unsigned short *) 0xffffff62 |= 0x2800; /* 16 bit mode */ + + /* setup all the PCMCIA dual purpose pins to be PCMCIA pins */ + * (unsigned short *) 0xa4000108 = 0x0000; /* port E, all pins */ + * (unsigned short *) 0xa400010a = 0x0000; /* port F, all pins */ + * (unsigned short *) 0xa400010c = 0x0000; /* port G, all pins */ + + /* put the PCMCIA interrupts into edge triggered mode */ + // BAD * (unsigned short *) 0xb0005004 |= 0x6000; + +#endif + + /* 0x3c00*/ + * (unsigned short *) 0xa400010e &= ~0x3f00; /* port H, pins 4, 5 & 6 */ + + printk("Hitachi HD64465 configured at 0x%x on irq %d\n", + CONFIG_HD64465_IOBASE, HD64465_IRQ_BASE); +#endif +} + +static void keywest_init(void) +{ + keywest_printf("%s", "Key West"); +#ifdef CONFIG_PCI + /* + * make sure these pins are in PCI mode (PINT) + */ + * (unsigned short *) 0xa4000104 = 0xaaaa; /* port C, all inputs */ + * (unsigned short *) 0xa4000108 = 0x0000; /* port E, all pins */ + * (unsigned short *) 0xa4000110 = 0x0000; /* port J, all pins */ +#ifndef CONFIG_PCMCIA + * (unsigned short *) 0xffffff62 |= 0x3c00; /* Area 5/6 in 32 bit mode */ + + /* Make sure Area 5 & 6 are in PCI mode */ + * (unsigned short *) 0xffffff60 &= ~0x3; /* 5 & 6 as normal memory * + * (unsigned short *) 0xffffff60 &= ~0x1e0; /* ordinary memory 5 & 6 */ +#endif +#endif +} + +int __init setup_keywest(void) +{ + static int done = 0; /* run this only once */ + + if (!MACH_KEYWEST || done) return 0; + done = 1; + + keywest_init(); + tahoe_init(); +#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL) + /* remap IO ports for first ISA serial port to HD64465 UART */ + mach_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1); +#endif /* CONFIG_HD64465 && CONFIG_SERIAL */ + + return 0; +} + +void keywest_alpha(int i, char ch) +{ + volatile unsigned char *alpha = (unsigned char *)ALPHA_LED; + *(alpha + i) = ch; +} + +#if 0 //keywest board(rev.4) not support status LED +void keywest_led_on() +{ + volatile unsigned char *led = (unsigned char *)STATUS_LED; + *led = 0x82; +} + +void keywest_led_off() +{ + volatile unsigned char *led = (unsigned char *)STATUS_LED; + *led = 0x02; +} +#endif + +module_init(setup_keywest); diff -urN linux-2.4.21/arch/sh/kernel/setup_se.c linux-2.4.22/arch/sh/kernel/setup_se.c --- linux-2.4.21/arch/sh/kernel/setup_se.c 2000-08-09 13:59:04.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/setup_se.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: setup_se.c,v 1.6 2000/05/14 08:41:25 gniibe Exp $ +/* $Id: setup_se.c,v 1.1.1.1.2.2 2002/05/10 17:58:54 jzs Exp $ * * linux/arch/sh/kernel/setup_se.c * @@ -18,6 +18,10 @@ #include #include +#ifdef CONFIG_SH_KGDB +#include +#endif + /* * Configure the Super I/O chip */ @@ -108,6 +112,11 @@ make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ } +#ifdef CONFIG_SH_KGDB +static int kgdb_uart_setup(void); +static struct kgdb_sermap kgdb_uart_sermap = +{ "ttyS", 0, kgdb_uart_setup, NULL }; +#endif /* * Initialize the board @@ -116,4 +125,133 @@ { init_smsc(); /* XXX: RTC setting comes here */ +#ifdef CONFIG_SH_KGDB + kgdb_register_sermap(&kgdb_uart_sermap); +#endif +} + +/********************************************************************* + * Currently a hack (e.g. does not interact well w/serial.c, lots of * + * hardcoded stuff) but may be useful if SCI/F needs debugging. * + * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and * + * arch/i386/lib/kgdb_serial.c). * + *********************************************************************/ + +#ifdef CONFIG_SH_KGDB +#include +#include +#include +#include + +#define COM1_PORT 0x3f8 /* Base I/O address */ +#define COM1_IRQ 4 /* IRQ not used yet */ +#define COM2_PORT 0x2f8 /* Base I/O address */ +#define COM2_IRQ 3 /* IRQ not used yet */ + +#define SB_CLOCK 1843200 /* Serial baud clock */ +#define SB_BASE (SB_CLOCK/16) +#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS + +struct uart_port { + int base; +}; +#define UART_NPORTS 2 +struct uart_port uart_ports[] = { + { COM1_PORT }, + { COM2_PORT }, +}; +struct uart_port *kgdb_uart_port; + +#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg) +#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg) + +/* Basic read/write functions for the UART */ +#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE) +static int kgdb_uart_getchar(void) +{ + int lsr; + int c = -1; + + while (c == -1) { + lsr = UART_IN(UART_LSR); + if (lsr & UART_LSR_DR) + c = UART_IN(UART_RX); + if ((lsr & UART_LSR_RXCERR)) + c = -1; + } + return c; +} + +static void kgdb_uart_putchar(int c) +{ + while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0) + ; + UART_OUT(UART_TX, c); +} + +/* + * Initialize UART to configured/requested values. + * (But we don't interrupts yet, or interact w/serial.c) + */ +static int kgdb_uart_setup(void) +{ + int port; + int lcr = 0; + int bdiv = 0; + + if (kgdb_portnum >= UART_NPORTS) { + KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum); + return -1; + } + + kgdb_uart_port = &uart_ports[kgdb_portnum]; + + /* Init sequence from gdb_hook_interrupt */ + UART_IN(UART_RX); + UART_OUT(UART_IER, 0); + + UART_IN(UART_RX); /* Serial driver comments say */ + UART_IN(UART_IIR); /* this clears interrupt regs */ + UART_IN(UART_MSR); + + /* Figure basic LCR values */ + switch (kgdb_bits) { + case '7': + lcr |= UART_LCR_WLEN7; + break; + default: case '8': + lcr |= UART_LCR_WLEN8; + break; + } + switch (kgdb_parity) { + case 'O': + lcr |= UART_LCR_PARITY; + break; + case 'E': + lcr |= (UART_LCR_PARITY | UART_LCR_EPAR); + break; + default: break; + } + + /* Figure the baud rate divisor */ + bdiv = (SB_BASE/kgdb_baud); + + /* Set the baud rate and LCR values */ + UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB)); + UART_OUT(UART_DLL, (bdiv & 0xff)); + UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff)); + UART_OUT(UART_LCR, lcr); + + /* Set the MCR */ + UART_OUT(UART_MCR, SB_MCR); + + /* Turn off FIFOs for now */ + UART_OUT(UART_FCR, 0); + + /* Setup complete: initialize function pointers */ + kgdb_getchar = kgdb_uart_getchar; + kgdb_putchar = kgdb_uart_putchar; + + return 0; } +#endif /* CONFIG_SH_KGDB */ diff -urN linux-2.4.21/arch/sh/kernel/setup_shmse.c linux-2.4.22/arch/sh/kernel/setup_shmse.c --- linux-2.4.21/arch/sh/kernel/setup_shmse.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/setup_shmse.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,22 @@ +/* + * linux/arch/sh/kernel/setup_shmse.c + * + * Copyright (C) 2003 Takashi Kusuda + * + * SH-Mobile SolutionEngine Support. + */ + +#include +#include +#include + +#include +#include + +void __init init_shmse_IRQ(void) +{ +} + +void __init setup_shmse(void) +{ +} diff -urN linux-2.4.21/arch/sh/kernel/setup_snapgear.c linux-2.4.22/arch/sh/kernel/setup_snapgear.c --- linux-2.4.21/arch/sh/kernel/setup_snapgear.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/setup_snapgear.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,186 @@ +/****************************************************************************/ +/* + * linux/arch/sh/kernel/setup_snapgear.c + * + * Copyright (C) 2002 David McCullough + * + * Based on files with the following comments: + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Modified for 7751 Solution Engine by + * Ian da Silva and Jeremy Siegel, 2001. + */ +/****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/****************************************************************************/ +/* + * EraseConfig handling functions + */ + +static void +eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ +#if defined(CONFIG_SH_SECUREEDGE5410) +{ + volatile char dummy = * (volatile char *) 0xb8000000; +} +#endif +#ifdef CONFIG_LEDMAN + ledman_signalreset(); +#else + printk("SnapGear: erase switch interrupt!\n"); +#endif +} + +static int __init +eraseconfig_init(void) +{ + printk("SnapGear: EraseConfig init\n"); + /* Setup "EraseConfig" switch on external IRQ 0 */ + if (request_irq(IRL0_IRQ, eraseconfig_interrupt, SA_INTERRUPT, + "Erase Config", NULL)) + printk("SnapGear: failed to register IRQ%d for Reset witch\n", + IRL0_IRQ); + else + printk("SnapGear: registered EraseConfig switch on IRQ%d\n", + IRL0_IRQ); + return(0); +} + +module_init(eraseconfig_init); + +/****************************************************************************/ +/* + * Initialize IRQ setting + * + * IRL0 = erase switch + * IRL1 = eth0 + * IRL2 = eth1 + * IRL3 = crypto + */ + +void __init +init_snapgear_IRQ(void) +{ + /* enable individual interrupt mode for externals */ + ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + + printk("Setup SnapGear IRQ/IPR ...\n"); + + make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); + make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); + make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); + make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); +} + +/****************************************************************************/ +/* + * Fast poll interrupt simulator. + */ + +#define FAST_POLL 1000 +//#define FAST_POLL_INTR + +#define FASTTIMER_IRQ 17 +#define FASTTIMER_IPR_ADDR INTC_IPRA +#define FASTTIMER_IPR_POS 2 +#define FASTTIMER_PRIORITY 3 + +#ifdef FAST_POLL_INTR +#define TMU1_TCR_INIT 0x0020 +#else +#define TMU1_TCR_INIT 0 +#endif +#define TMU_TSTR_INIT 1 +#define TMU1_TCR_CALIB 0x0000 +#define TMU_TOCR 0xffd80000 /* Byte access */ +#define TMU_TSTR 0xffd80004 /* Byte access */ +#define TMU1_TCOR 0xffd80014 /* Long access */ +#define TMU1_TCNT 0xffd80018 /* Long access */ +#define TMU1_TCR 0xffd8001c /* Word access */ + + +#ifdef FAST_POLL_INTR +static void fast_timer_irq(int irq, void *dev_instance, struct pt_regs *regs) +{ + unsigned long timer_status; + timer_status = ctrl_inw(TMU1_TCR); + timer_status &= ~0x100; + ctrl_outw(timer_status, TMU1_TCR); +} +#endif + +/* + * return the current ticks on the fast timer + */ + +unsigned long +fast_timer_count(void) +{ + return(ctrl_inl(TMU1_TCNT)); +} + +/* + * setup a fast timer for profiling etc etc + */ + +static void +setup_fast_timer() +{ + unsigned long interval; + +#ifdef FAST_POLL_INTR + interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL; + + make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS, + FASTTIMER_PRIORITY); + + printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ); + + if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer", + NULL) != 0) + printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__); +#else + printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ); + interval = 0xffffffff; +#endif + + ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */ + ctrl_outw(TMU1_TCR_INIT, TMU1_TCR); + ctrl_outl(interval, TMU1_TCOR); + ctrl_outl(interval, TMU1_TCNT); + ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */ + + printk("Timer count 1 = 0x%x\n", fast_timer_count()); + udelay(1000); + printk("Timer count 2 = 0x%x\n", fast_timer_count()); +} + +/****************************************************************************/ +/* + * Initialize the board + */ + +void __init +setup_snapgear(void) +{ + /* XXX: RTC setting comes here */ +#ifdef CONFIG_RTC + secureedge5410_rtc_init(); +#endif + // setup_fast_timer(); +} + +/****************************************************************************/ diff -urN linux-2.4.21/arch/sh/kernel/sh_ksyms.c linux-2.4.22/arch/sh/kernel/sh_ksyms.c --- linux-2.4.21/arch/sh/kernel/sh_ksyms.c 2002-02-25 11:37:56.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/sh_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -56,6 +56,7 @@ #endif /* mem exports */ +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memcpy_fromio); @@ -64,6 +65,7 @@ EXPORT_SYMBOL(memset_io); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(__copy_user); #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); @@ -77,6 +79,7 @@ EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down); EXPORT_SYMBOL(__down_interruptible); +EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(__const_udelay); diff -urN linux-2.4.21/arch/sh/kernel/signal.c linux-2.4.22/arch/sh/kernel/signal.c --- linux-2.4.21/arch/sh/kernel/signal.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.21 2000/03/11 14:06:21 gniibe Exp $ +/* $Id: signal.c,v 1.1.1.1.2.11 2002/10/23 00:57:46 mrbrown Exp $ * * linux/arch/sh/kernel/signal.c * @@ -30,7 +30,8 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); +asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, + int from_syscall, unsigned long orig_r0); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { @@ -88,7 +89,7 @@ while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(®s, &saveset)) + if (do_signal(®s, &saveset, 0, 0)) return -EINTR; } } @@ -117,7 +118,7 @@ while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(®s, &saveset)) + if (do_signal(®s, &saveset, 0, 0)) return -EINTR; } } @@ -167,20 +168,21 @@ * Do a signal return; undo the signal stack. */ +#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ +#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */ + struct sigframe { struct sigcontext sc; unsigned long extramask[_NSIG_WORDS-1]; - char retcode[4]; + u16 retcode[3]; }; struct rt_sigframe { - struct siginfo *pinfo; - void *puc; struct siginfo info; struct ucontext uc; - char retcode[4]; + u16 retcode[3]; }; #if defined(__SH4__) @@ -196,39 +198,32 @@ static inline int save_sigcontext_fpu(struct sigcontext *sc) { struct task_struct *tsk = current; - unsigned long flags; - int val; if (!tsk->used_math) { - val = 0; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(0, &sc->sc_ownedfp); return 0; } - val = 1; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(1, &sc->sc_ownedfp); /* This will cause a "finit" to be triggered by the next attempted FPU operation by the 'current' process. */ tsk->used_math = 0; - save_and_cli(flags); unlazy_fpu(tsk); - restore_flags(flags); - return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, sizeof(long)*(16*2+2)); } #endif static int -restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *r0_p) +restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { unsigned int err = 0; #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) - COPY(regs[1]); + COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); @@ -254,19 +249,16 @@ err |= restore_sigcontext_fpu(sc); } #endif - - regs->syscall_nr = -1; /* disable syscall checks */ - err |= __get_user(*r0_p, &sc->sc_regs[0]); return err; } + asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { struct sigframe *frame = (struct sigframe *)regs.regs[15]; sigset_t set; - int r0; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; @@ -284,9 +276,9 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if (restore_sigcontext(®s, &frame->sc, &r0)) + if (restore_sigcontext(®s, &frame->sc)) goto badframe; - return r0; + return regs.regs[0]; badframe: force_sig(SIGSEGV, current); @@ -300,7 +292,6 @@ struct rt_sigframe *frame = (struct rt_sigframe *)regs.regs[15]; sigset_t set; stack_t st; - int r0; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; @@ -314,7 +305,7 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &r0)) + if (restore_sigcontext(®s, &frame->uc.uc_mcontext)) goto badframe; if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) @@ -322,13 +313,12 @@ /* It is more difficult to avoid calling this function than to call it and ignore errors. */ do_sigaltstack(&st, NULL, regs.regs[15]); - - return r0; + return regs.regs[0]; badframe: force_sig(SIGSEGV, current); return 0; -} +} /* * Set up a signal frame. @@ -406,15 +396,11 @@ if (ka->sa.sa_flags & SA_RESTORER) { regs->pr = (unsigned long) ka->sa.sa_restorer; } else { - /* This is : mov #__NR_sigreturn,r3 ; trapa #0x10 */ -#ifdef __LITTLE_ENDIAN__ - unsigned long code = 0xc310e300 | (__NR_sigreturn); -#else - unsigned long code = 0xe300c310 | (__NR_sigreturn << 16); -#endif - + /* Generate return code (system call to sigreturn) */ + err |= __put_user(MOVW(2), &frame->retcode[0]); + err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user((__NR_sigreturn), &frame->retcode[2]); regs->pr = (unsigned long) frame->retcode; - err |= __put_user(code, (long *)(frame->retcode+0)); } if (err) @@ -459,8 +445,6 @@ ? current->exec_domain->signal_invmap[sig] : sig; - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); err |= copy_siginfo_to_user(&frame->info, info); /* Create the ucontext. */ @@ -480,24 +464,22 @@ if (ka->sa.sa_flags & SA_RESTORER) { regs->pr = (unsigned long) ka->sa.sa_restorer; } else { - /* This is : mov #__NR_rt_sigreturn,r3 ; trapa #0x10 */ -#ifdef __LITTLE_ENDIAN__ - unsigned long code = 0xc310e300 | (__NR_rt_sigreturn); -#else - unsigned long code = 0xe300c310 | (__NR_rt_sigreturn << 16); -#endif - + /* Generate return code (system call to rt_sigreturn) */ + err |= __put_user(MOVW(2), &frame->retcode[0]); + err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user((__NR_rt_sigreturn), &frame->retcode[2]); regs->pr = (unsigned long) frame->retcode; - err |= __put_user(code, (long *)(frame->retcode+0)); } if (err) goto give_sigsegv; - /* Set up registers for signal handler */ - regs->regs[15] = (unsigned long) frame; - regs->regs[4] = signal; /* Arg for signal handler */ - regs->pc = (unsigned long) ka->sa.sa_handler; + /* Set up registers (SP, PC, and args) for signal handler */ + regs->regs[15] = (unsigned long) frame; /* Stack pointer */ + regs->regs[4] = signal; /* Arg1 (signal) */ + regs->regs[5] = (unsigned long)&frame->info; /* Arg2 (siginfo) */ + regs->regs[6] = (unsigned long)&frame->uc; /* Arg3 (context) */ + regs->pc = (unsigned long) ka->sa.sa_handler; /* Program counter */ set_fs(USER_DS); @@ -521,10 +503,11 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, + int from_syscall, unsigned long orig_r0) { /* Are we from a system call? */ - if (regs->syscall_nr >= 0) { + if (from_syscall) { /* If so, check system call restarting.. */ switch (regs->regs[0]) { case -ERESTARTNOHAND: @@ -538,9 +521,20 @@ } /* fallthrough */ case -ERESTARTNOINTR: - regs->regs[0] = regs->syscall_nr; + regs->regs[0] = orig_r0; regs->pc -= 2; } + } else { + /* gUSA handling */ + if (regs->regs[15] >= 0xc0000000) { + int offset = (int)regs->regs[15]; + + /* Reset stack pointer: clear critical region mark */ + regs->regs[15] = regs->regs[1]; + if (regs->pc < regs->regs[0]) + /* Go to rewind point #1 */ + regs->pc = regs->regs[0] + offset - 2; + } } /* Set up the stack frame */ @@ -570,7 +564,8 @@ * the kernel can handle, and then we build all the user-level signal handling * stack-frames in one go after that. */ -int do_signal(struct pt_regs *regs, sigset_t *oldset) +int do_signal(struct pt_regs *regs, sigset_t *oldset, + int from_syscall, unsigned long orig_r0) { siginfo_t info; struct k_sigaction *ka; @@ -677,17 +672,18 @@ } /* Whee! Actually deliver the signal. */ - handle_signal(signr, ka, &info, oldset, regs); + handle_signal(signr, ka, &info, oldset, regs, + from_syscall, orig_r0); return 1; } /* Did we come from a system call? */ - if (regs->syscall_nr >= 0) { + if (from_syscall) { /* Restart the system call - no handlers present */ if (regs->regs[0] == -ERESTARTNOHAND || regs->regs[0] == -ERESTARTSYS || regs->regs[0] == -ERESTARTNOINTR) { - regs->regs[0] = regs->syscall_nr; + regs->regs[0] = orig_r0; regs->pc -= 2; } } diff -urN linux-2.4.21/arch/sh/kernel/sys_sh.c linux-2.4.22/arch/sh/kernel/sys_sh.c --- linux-2.4.21/arch/sh/kernel/sys_sh.c 2001-10-15 13:36:48.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/sys_sh.c 2003-08-25 04:44:40.000000000 -0700 @@ -23,6 +23,7 @@ #include #include +#include /* * sys_pipe() is the normal C calling standard for creating @@ -221,15 +222,41 @@ return -EINVAL; } -asmlinkage int sys_uname(struct old_utsname * name) +/* sys_cacheflush -- flush (part of) the processor cache. */ +asmlinkage int +sys_cacheflush (unsigned long addr, unsigned long len, int op) { - int err; - if (!name) + struct vm_area_struct *vma; + + if ((op < 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I))) + return -EINVAL; + + /* + * Verify that the specified address region actually belongs + * to this process. + */ + if (addr + len < addr) return -EFAULT; - down_read(&uts_sem); - err=copy_to_user(name, &system_utsname, sizeof (*name)); - up_read(&uts_sem); - return err?-EFAULT:0; + vma = find_vma (current->mm, addr); + if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) + return -EFAULT; + + switch (op & CACHEFLUSH_D_PURGE) { + case CACHEFLUSH_D_INVAL: + __flush_invalidate_region(addr, len); + break; + case CACHEFLUSH_D_WB: + __flush_wback_region(addr, len); + break; + case CACHEFLUSH_D_PURGE: + __flush_purge_region(addr, len); + break; + } + if (op & CACHEFLUSH_I) { + __flush_icache_all(); + } + + return 0; } asmlinkage int sys_pause(void) @@ -238,3 +265,19 @@ schedule(); return -ERESTARTNOHAND; } + +asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char * buf, + size_t count, long dummy, loff_t pos) +{ + extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf, + size_t count, loff_t pos); + return sys_pread(fd, buf, count, pos); +} + +asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char * buf, + size_t count, long dummy, loff_t pos) +{ + extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf, + size_t count, loff_t pos); + return sys_pwrite(fd, buf, count, pos); +} diff -urN linux-2.4.21/arch/sh/kernel/time.c linux-2.4.22/arch/sh/kernel/time.c --- linux-2.4.21/arch/sh/kernel/time.c 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,9 +1,10 @@ -/* $Id: time.c,v 1.30 2001/09/01 14:34:31 mrbrown Exp $ +/* $Id: time.c,v 1.1.1.1.2.6 2003/07/16 18:43:55 yoshii Exp $ * * linux/arch/sh/kernel/time.c * * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf + * Copyright (C) 2003 Takashi Kusuda * * Some code taken from i386 version. * Copyright (C) 1991, 1992, 1995 Linus Torvalds @@ -29,17 +30,36 @@ #include #include #include +#ifdef CONFIG_SH_KGDB +#include +#endif #include #include -#define TMU_TOCR_INIT 0x00 -#define TMU0_TCR_INIT 0x0020 -#define TMU_TSTR_INIT 1 +#define TMU_TOCR_INIT 0x00 /* Don't output RTC clock */ + +#define TMU0_TCR_INIT 0x0020 /* Clock/4, rising edge; interrupt on */ +#define TMU0_TCR_CALIB 0x0000 /* Clock/4, rising edge; no interrupt */ +#define TMU0_TSTR_INIT 0x01 /* Bit to turn on TMU0 */ -#define TMU0_TCR_CALIB 0x0000 +#define TMU1_TCR_INIT 0x0000 /* Clock/4, rising edge; no interrupt */ +#define TMU1_TSTR_INIT 0x02 /* Bit to turn on TMU1 */ #if defined(__sh3__) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define TMU_TSTR 0xA412FE92 /* Byte access */ + +#define TMU0_TCOR 0xA412FE94 /* Long access */ +#define TMU0_TCNT 0xA412FE98 /* Long access */ +#define TMU0_TCR 0xA412FE9C /* Word access */ + +#define TMU1_TCOR 0xA412FEA0 /* Long access */ +#define TMU1_TCNT 0xA412FEA4 /* Long access */ +#define TMU1_TCR 0xA412FEA8 /* Word access */ + +#define FRQCR 0xA415FF80 +#else #define TMU_TOCR 0xfffffe90 /* Byte access */ #define TMU_TSTR 0xfffffe92 /* Byte access */ @@ -47,7 +67,12 @@ #define TMU0_TCNT 0xfffffe98 /* Long access */ #define TMU0_TCR 0xfffffe9c /* Word access */ +#define TMU1_TCOR 0xfffffea0 /* Long access */ +#define TMU1_TCNT 0xfffffea4 /* Long access */ +#define TMU1_TCR 0xfffffea8 /* Word access */ + #define FRQCR 0xffffff80 +#endif #elif defined(__SH4__) #define TMU_TOCR 0xffd80000 /* Byte access */ #define TMU_TSTR 0xffd80004 /* Byte access */ @@ -56,6 +81,10 @@ #define TMU0_TCNT 0xffd8000c /* Long access */ #define TMU0_TCR 0xffd80010 /* Word access */ +#define TMU1_TCOR 0xffd80014 /* Long access */ +#define TMU1_TCNT 0xffd80018 /* Long access */ +#define TMU1_TCR 0xffd8001c /* Word access */ + #define FRQCR 0xffc00000 /* Core Processor Version Register */ @@ -64,10 +93,10 @@ #define CCN_PVR_CHIP_MASK 0xff #define CCN_PVR_CHIP_ST40STB1 0x4 -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 #define CLOCKGEN_MEMCLKCR 0xbb040038 #define MEMCLKCR_RATIO_MASK 0x7 -#endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */ +#endif /* CONFIG_CPU_SUBTYPE_ST40 */ #endif /* __sh3__ or __SH4__ */ extern rwlock_t xtime_lock; @@ -176,6 +205,27 @@ /* last time the RTC clock got updated */ static long last_rtc_update; +static __inline__ void sh_do_profile (unsigned long pc) +{ + extern int _stext; + + if (!prof_buffer) + return; + + if(pc >= 0xa0000000UL && pc < 0xc0000000UL) + pc -= 0x20000000; + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + /* + * Don't ignore out-of-bounds PC values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (pc > prof_len-1) + pc = prof_len-1; + prof_buffer[pc]++; +} + /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick @@ -245,7 +295,9 @@ * have it count down at its natural rate. */ ctrl_outb(0, TMU_TSTR); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); +#endif ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); ctrl_outl(0xffffffff, TMU0_TCOR); ctrl_outl(0xffffffff, TMU0_TCNT); @@ -257,7 +309,7 @@ } while (tv1.tv_usec == tv2.tv_usec && tv1.tv_sec == tv2.tv_sec); /* actually start the timer */ - ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); + ctrl_outb(TMU0_TSTR_INIT, TMU_TSTR); do { rtc_gettimeofday(&tv2); @@ -283,27 +335,41 @@ return freq * factor; } +static unsigned int sh_pclk_freq __initdata = CONFIG_SH_PCLK_FREQ; +static int __init sh_pclk_setup(char *str) +{ + unsigned int freq; + if (get_option(&str, &freq)) + sh_pclk_freq = freq; + return 1; +} +__setup("sh_pclk=", sh_pclk_setup); + static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; void __init time_init(void) { unsigned int cpu_clock, master_clock, bus_clock, module_clock; -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 unsigned int memory_clock; #endif unsigned int timer_freq; unsigned short frqcr, ifc, pfc, bfc; unsigned long interval; #if defined(__sh3__) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + static int pfc_table[] = { 1, 2, 3, 4, 6 }; +#else static int ifc_table[] = { 1, 2, 4, 1, 3, 1, 1, 1 }; static int pfc_table[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; static int stc_table[] = { 1, 2, 4, 8, 3, 6, 1, 1 }; +#endif #elif defined(__SH4__) static int ifc_table[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; #define bfc_table ifc_table /* Same */ static int pfc_table[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 struct frqcr_data { unsigned short frqcr; struct { @@ -359,19 +425,33 @@ #endif #endif - rtc_gettimeofday(&xtime); + if(rtc_gettimeofday) + rtc_gettimeofday(&xtime); + else{ + xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0); + xtime.tv_usec = 0; + } setup_irq(TIMER_IRQ, &irq0); - timer_freq = get_timer_frequency(); - - module_clock = timer_freq * 4; + if( sh_pclk_freq ){ + module_clock = sh_pclk_freq; + }else{ + timer_freq = get_timer_frequency(); + module_clock = timer_freq * 4; + } #if defined(__sh3__) { unsigned short tmp; frqcr = ctrl_inw(FRQCR); +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + bfc = ((frqcr & 0x0700) >> 8)+1; + ifc = ((frqcr & 0x0070) >> 4)+1; + tmp = frqcr & 0x0007; + pfc = pfc_table[tmp]; +#else tmp = (frqcr & 0x8000) >> 13; tmp |= (frqcr & 0x0030) >> 4; bfc = stc_table[tmp]; @@ -381,10 +461,11 @@ tmp = (frqcr & 0x2000) >> 11; tmp |= frqcr & 0x0003; pfc = pfc_table[tmp]; +#endif } #elif defined(__SH4__) { -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 unsigned long pvr; /* This should probably be moved into the SH3 probing code, and then use the processor @@ -438,14 +519,14 @@ master_clock = module_clock * pfc; bus_clock = master_clock / bfc; cpu_clock = master_clock / ifc; -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 skip_calc: #endif printk("CPU clock: %d.%02dMHz\n", (cpu_clock / 1000000), (cpu_clock % 1000000)/10000); printk("Bus clock: %d.%02dMHz\n", (bus_clock/1000000), (bus_clock % 1000000)/10000); -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 printk("Memory clock: %d.%02dMHz\n", (memory_clock/1000000), (memory_clock % 1000000)/10000); #endif @@ -458,16 +539,37 @@ current_cpu_data.cpu_clock = cpu_clock; current_cpu_data.master_clock = master_clock; current_cpu_data.bus_clock = bus_clock; -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 +#ifdef CONFIG_CPU_SUBTYPE_ST40 current_cpu_data.memory_clock = memory_clock; #endif current_cpu_data.module_clock = module_clock; - /* Start TMU0 */ + /* Stop all timers */ ctrl_outb(0, TMU_TSTR); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); +#endif + + /* Start TMU0 (jiffy interrupts) */ ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); ctrl_outl(interval, TMU0_TCOR); ctrl_outl(interval, TMU0_TCNT); - ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); + ctrl_outb(TMU0_TSTR_INIT, TMU_TSTR); + +#if defined(CONFIG_START_TMU1) + /* Start TMU1 (free-running) */ + ctrl_outw(TMU1_TCR_INIT, TMU1_TCR); + ctrl_outl(0xffffffff, TMU1_TCOR); + ctrl_outl(0xffffffff, TMU1_TCNT); + ctrl_outb((ctrl_inb(TMU_TSTR) | TMU1_TSTR_INIT), TMU_TSTR); +#endif + +#if defined(CONFIG_SH_KGDB) + /* + * Set up kgdb as requested. We do it here because the serial + * init uses the timer vars we just set up for figuring baud. + */ + kgdb_init(); +#endif + } diff -urN linux-2.4.21/arch/sh/kernel/traps.c linux-2.4.22/arch/sh/kernel/traps.c --- linux-2.4.21/arch/sh/kernel/traps.c 2002-02-25 11:37:56.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,10 +1,11 @@ -/* $Id: traps.c,v 1.14 2001/07/24 08:07:10 gniibe Exp $ +/* $Id: traps.c,v 1.1.1.1.2.4 2002/05/10 17:58:54 jzs Exp $ * * linux/arch/sh/traps.c * * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells + * Copyright (C) 2002 Paul Mundt */ /* @@ -31,6 +32,19 @@ #include #include +#ifdef CONFIG_SH_KGDB +#include +#define CHK_REMOTE_DEBUG(regs) \ +{ \ + if ((kgdb_debug_hook != (kgdb_debug_hook_t *) NULL) && (!user_mode(regs))) \ + { \ + (*kgdb_debug_hook)(regs); \ + } \ +} +#else +#define CHK_REMOTE_DEBUG(regs) +#endif + #define DO_ERROR(trapnr, signr, str, name, tsk) \ asmlinkage void do_##name(unsigned long r4, unsigned long r5, \ unsigned long r6, unsigned long r7, \ @@ -42,6 +56,7 @@ sti(); \ tsk->thread.error_code = error_code; \ tsk->thread.trap_no = trapnr; \ + CHK_REMOTE_DEBUG(®s); \ force_sig(signr, tsk); \ die_if_no_fixup(str,®s,error_code); \ } @@ -61,6 +76,7 @@ console_verbose(); spin_lock_irq(&die_lock); printk("%s: %04lx\n", str, err & 0xffff); + CHK_REMOTE_DEBUG(regs); show_regs(regs); spin_unlock_irq(&die_lock); do_exit(SIGSEGV); @@ -300,10 +316,19 @@ /* * handle an instruction that does an unaligned memory access * - have to be careful of branch delay-slot instructions that fault + * SH3: * - if the branch would be taken PC points to the branch * - if the branch would not be taken, PC points to delay-slot + * SH4: + * - PC always points to delayed branch * - return 0 if handled, -EFAULT if failed (may not return if in kernel) */ + +/* Macros to determine offset from current PC for branch instructions */ +/* Explicit type coercion is used to force sign extension where needed */ +#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4) +#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4) + static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) { u_int rm; @@ -392,15 +417,27 @@ break; case 0x0F00: /* bf/s lab */ ret = handle_unaligned_delayslot(regs); - if (ret==0) - regs->pc += (instruction&0x00FF)*2 + 4; + if (ret==0) { +#if defined(__SH4__) + if ((regs->sr & 0x00000001) != 0) + regs->pc += 4; /* next after slot */ + else +#endif + regs->pc += SH_PC_8BIT_OFFSET(instruction); + } break; case 0x0900: /* bt lab - no delayslot */ break; case 0x0D00: /* bt/s lab */ ret = handle_unaligned_delayslot(regs); - if (ret==0) - regs->pc += (instruction&0x00FF)*2 + 4; + if (ret==0) { +#if defined(__SH4__) + if ((regs->sr & 0x00000001) == 0) + regs->pc += 4; /* next after slot */ + else +#endif + regs->pc += SH_PC_8BIT_OFFSET(instruction); + } break; } break; @@ -408,14 +445,14 @@ case 0xA000: /* bra label */ ret = handle_unaligned_delayslot(regs); if (ret==0) - regs->pc += (instruction&0x0FFF)*2 + 4; + regs->pc += SH_PC_12BIT_OFFSET(instruction); break; case 0xB000: /* bsr label */ ret = handle_unaligned_delayslot(regs); if (ret==0) { regs->pr = regs->pc + 4; - regs->pc += (instruction&0x0FFF)*2 + 4; + regs->pc += SH_PC_12BIT_OFFSET(instruction); } break; } @@ -539,29 +576,51 @@ : "memory"); } -void dump_stack(void) +void show_task(unsigned long *sp) { - unsigned long *start; - unsigned long *end; - unsigned long *p; - - asm("mov r15, %0" : "=r" (start)); - asm("stc r7_bank, %0" : "=r" (end)); - end += 8192/4; - - printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end); - for (p=start; p < end; p++) { - extern long _text, _etext; - unsigned long v=*p; - - if ((v >= (unsigned long )&_text) - && (v <= (unsigned long )&_etext)) { - printk("%08lx\n", v); + unsigned long *stack, addr; + unsigned long module_start = VMALLOC_START; + unsigned long module_end = VMALLOC_END; + extern long _text, _etext; + int i = 1; + + if (!sp) { + __asm__ __volatile__ ( + "mov r15, %0\n\t" + "stc r7_bank, %1\n\t" + : "=r" (module_start), + "=r" (module_end) + ); + + sp = (unsigned long *)module_start; + } + + stack = sp; + + printk("\nCall trace: "); + + while (((long)stack & (THREAD_SIZE - 1))) { + if (__get_user(addr, stack)) { + printk("Failing address 0x%lx\n", *stack); + break; + } + stack++; + + if (((addr >= (unsigned long)&_text) && + (addr <= (unsigned long)&_etext)) || + ((addr >= module_start) && (addr <= module_end))) { + if (i && ((i % 8) == 0)) + printk("\n "); + + printk("[<%08lx>] ", addr); + i++; } } + + printk("\n"); } void show_trace_task(struct task_struct *tsk) { - printk("Backtrace not yet implemented for SH.\n"); + show_task((unsigned long *)tsk->thread.sp); } diff -urN linux-2.4.21/arch/sh/kernel/ubc.S linux-2.4.22/arch/sh/kernel/ubc.S --- linux-2.4.21/arch/sh/kernel/ubc.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/kernel/ubc.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,59 @@ +/* + * arch/sh/kernel/ubc.S + * + * Set of management routines for the User Break Controller (UBC) + * + * Copyright (C) 2002 Paul Mundt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#define STBCR2 0xffc00010 + +ENTRY(ubc_sleep) + mov #0, r0 + + mov.l 1f, r1 ! Zero out UBC_BBRA .. + mov.w r0, @r1 + + mov.l 2f, r1 ! .. same for BBRB .. + mov.w r0, @r1 + + mov.l 3f, r1 ! .. and again for BRCR. + mov.w r0, @r1 + + mov.w @r1, r0 ! Dummy read BRCR + + mov.l 4f, r1 ! Set MSTP5 in STBCR2 + mov.b @r1, r0 + or #0x01, r0 + mov.b r0, @r1 + + mov.b @r1, r0 ! Two dummy reads .. + mov.b @r1, r0 + + rts + nop + +ENTRY(ubc_wakeup) + mov.l 4f, r1 ! Clear MSTP5 + mov.b @r1, r0 + and #0xfe, r0 + mov.b r0, @r1 + + mov.b @r1, r0 ! Two more dummy reads .. + mov.b @r1, r0 + + rts + nop + +1: .long UBC_BBRA +2: .long UBC_BBRB +3: .long UBC_BRCR +4: .long STBCR2 + diff -urN linux-2.4.21/arch/sh/lib/delay.c linux-2.4.22/arch/sh/lib/delay.c --- linux-2.4.21/arch/sh/lib/delay.c 2001-01-28 18:56:00.000000000 -0800 +++ linux-2.4.22/arch/sh/lib/delay.c 2003-08-25 04:44:40.000000000 -0700 @@ -33,3 +33,8 @@ { __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 5); /* 2**32 / 1000000000 (rounded up) */ +} diff -urN linux-2.4.21/arch/sh/mm/Makefile linux-2.4.22/arch/sh/mm/Makefile --- linux-2.4.21/arch/sh/mm/Makefile 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/mm/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -10,8 +10,9 @@ O_TARGET := mm.o obj-y := init.o fault.o extable.o clear_page.o copy_page.o +obj-$(CONFIG_PCI_SD0001) += ioremap.o obj-$(CONFIG_CPU_SH3) += cache-sh3.o -obj-$(CONFIG_CPU_SH4) += cache-sh4.o __clear_user_page-sh4.o __copy_user_page-sh4.o ioremap.o +obj-$(CONFIG_CPU_SH4) += cache-sh4.o ioremap.o USE_STANDARD_AS_RULE := true diff -urN linux-2.4.21/arch/sh/mm/cache-sh4.c linux-2.4.22/arch/sh/mm/cache-sh4.c --- linux-2.4.21/arch/sh/mm/cache-sh4.c 2001-10-15 13:36:48.000000000 -0700 +++ linux-2.4.22/arch/sh/mm/cache-sh4.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,9 +1,8 @@ -/* $Id: cache-sh4.c,v 1.16 2001/09/10 11:06:35 dwmw2 Exp $ +/* $Id: cache-sh4.c,v 1.1.1.1.2.8 2003/07/09 09:59:30 trent Exp $ * - * linux/arch/sh/mm/cache.c - * - * Copyright (C) 1999, 2000 Niibe Yutaka + * linux/arch/sh/mm/cache-sh4.c * + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka */ #include @@ -42,6 +41,7 @@ #define CACHE_OC_ADDRESS_ARRAY 0xf4000000 #define CACHE_VALID 1 #define CACHE_UPDATED 2 +#define CACHE_ASSOC 8 #define CACHE_OC_WAY_SHIFT 13 #define CACHE_IC_WAY_SHIFT 13 @@ -56,8 +56,8 @@ static void __init detect_cpu_and_cache_system(void) { -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 - cpu_data->type = CPU_ST40STB1; +#ifdef CONFIG_CPU_SUBTYPE_ST40 + cpu_data->type = CPU_ST40; #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) cpu_data->type = CPU_SH7750; #else @@ -109,7 +109,7 @@ unsigned long size, unsigned long flags); if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE)) - panic("p3_cachie_init failed."); + panic("%s failed.", __FUNCTION__); sema_init (&p3map_sem[0], 1); sema_init (&p3map_sem[1], 1); sema_init (&p3map_sem[2], 1); @@ -177,6 +177,17 @@ } } +void __flush_icache_all(void) +{ + unsigned long flags; + + save_and_cli(flags); + jump_to_P2(); + ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR); + back_to_P1(); + restore_flags(flags); +} + /* * Write back the range of D-cache, and purge the I-cache. * @@ -208,44 +219,26 @@ restore_flags(flags); } -/* - * Writeback&Invalidate the D-cache of the page - */ -static void __flush_dcache_page(unsigned long phys) +static inline void flush_cache_4096(unsigned long start, + unsigned long phys) { - unsigned long addr, data; - unsigned long flags; - - phys |= CACHE_VALID; - - save_and_cli(flags); - jump_to_P2(); - - /* Loop all the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY; - addr < (CACHE_OC_ADDRESS_ARRAY - +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); - addr += (1<= CACHE_OC_ADDRESS_ARRAY) { + /* + * SH7751 and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) + */ + __flush_cache_4096(start | CACHE_ASSOC, phys | 0x80000000, 0); + } else #endif - back_to_P1(); - restore_flags(flags); + { + save_and_cli(flags); + __flush_cache_4096(start | CACHE_ASSOC, phys | 0x80000000, 0x20000000); + restore_flags(flags); + } } /* @@ -254,38 +247,77 @@ */ void flush_dcache_page(struct page *page) { - if (test_bit(PG_mapped, &page->flags)) - __flush_dcache_page(PHYSADDR(page_address(page))); + if (test_bit(PG_mapped, &page->flags)) { + unsigned long phys = PHYSADDR(page_address(page)); + + /* Loop all the D-cache */ + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys); + } } -void flush_cache_all(void) +static inline void flush_icache_all(void) { - extern unsigned long empty_zero_page[1024]; unsigned long flags; - unsigned long addr; save_and_cli(flags); - - /* Prefetch the data to write back D-cache */ - for (addr = (unsigned long)empty_zero_page; - addr < (unsigned long)empty_zero_page + 1024*16; - addr += L1_CACHE_BYTES) - asm volatile("pref @%0"::"r" (addr)); - jump_to_P2(); - /* Flush D-cache/I-cache */ - ctrl_outl(CCR_CACHE_INIT, CCR); + /* Flush I-cache */ + ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR); back_to_P1(); restore_flags(flags); } +void flush_cache_all(void) +{ + extern void __flush_dcache_all(void); + + __flush_dcache_all(); + flush_icache_all(); +} + void flush_cache_mm(struct mm_struct *mm) { /* Is there any good way? */ /* XXX: possibly call flush_cache_range for each vm area */ + /* + * FIXME: Really, the optimal solution here would be able to flush out + * individual lines created by the specified context, but this isn't + * feasible for a number of architectures (such as MIPS, and some + * SPARC) .. is this possible for SuperH? + * + * In the meantime, we'll just flush all of the caches.. this + * seems to be the simplest way to avoid at least a few wasted + * cache flushes. -Lethal + */ flush_cache_all(); } +static void __flush_cache_page(struct vm_area_struct *vma, + unsigned long address, + unsigned long phys) +{ + /* We only need to flush D-cache when we have alias */ + if ((address^phys) & CACHE_ALIAS) { + /* Loop 4K of the D-cache */ + flush_cache_4096( + CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS), + phys); + /* Loop another 4K of the D-cache */ + flush_cache_4096( + CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS), + phys); + } + + if (vma->vm_flags & VM_EXEC) + /* Loop 4K (half) of the I-cache */ + flush_cache_4096( + CACHE_IC_ADDRESS_ARRAY | (address & 0x1000), + phys); +} + /* * Write back and invalidate D-caches. * @@ -298,14 +330,53 @@ void flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - /* - * We could call flush_cache_page for the pages of these range, - * but it's not efficient (scan the caches all the time...). - * - * We can't use A-bit magic, as there's the case we don't have - * valid entry on TLB. - */ - flush_cache_all(); + extern void flush_cache_4096_all(unsigned long start); + + unsigned long p = start & PAGE_MASK; + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long phys; + unsigned long d = 0; + + dir = pgd_offset(mm, p); + pmd = pmd_offset(dir, p); + + do { + if (pmd_none(*pmd) || pmd_bad(*pmd)) { + p &= ~((1 << PMD_SHIFT) -1); + p += (1 << PMD_SHIFT); + pmd++; + continue; + } + pte = pte_offset(pmd, p); + do { + entry = *pte; + if ((pte_val(entry) & _PAGE_PRESENT)) { + phys = pte_val(entry)&PTE_PHYS_MASK; + if ((p^phys) & CACHE_ALIAS) { + d |= 1 << ((p & CACHE_ALIAS)>>12); + d |= 1 << ((phys & CACHE_ALIAS)>>12); + if (d == 0x0f) + goto loop_exit; + } + } + pte++; + p += PAGE_SIZE; + } while (p < end && (unsigned long)pte & PAGE_MASK); + pmd++; + } while (p < end); + loop_exit: + if (d & 1) + flush_cache_4096_all(0); + if (d & 2) + flush_cache_4096_all(0x1000); + if (d & 4) + flush_cache_4096_all(0x2000); + if (d & 8) + flush_cache_4096_all(0x3000); + flush_icache_all(); } /* @@ -319,8 +390,7 @@ pmd_t *pmd; pte_t *pte; pte_t entry; - unsigned long phys, addr, data; - unsigned long flags; + unsigned long phys; dir = pgd_offset(vma->vm_mm, address); pmd = pmd_offset(dir, address); @@ -328,49 +398,11 @@ return; pte = pte_offset(pmd, address); entry = *pte; - if (pte_none(entry) || !pte_present(entry)) + if (!(pte_val(entry) & _PAGE_PRESENT)) return; phys = pte_val(entry)&PTE_PHYS_MASK; - - phys |= CACHE_VALID; - save_and_cli(flags); - jump_to_P2(); - - /* We only need to flush D-cache when we have alias */ - if ((address^phys) & CACHE_ALIAS) { - /* Loop 4K of the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS); - addr < (CACHE_OC_ADDRESS_ARRAY + (address & CACHE_ALIAS) - +(CACHE_OC_NUM_ENTRIES/4<vm_flags & VM_EXEC) - /* Loop 4K of the I-cache */ - for (addr = CACHE_IC_ADDRESS_ARRAY|(address&0x1000); - addr < ((CACHE_IC_ADDRESS_ARRAY|(address&0x1000)) - +(CACHE_IC_NUM_ENTRIES/2< +#include /* * clear_page @@ -18,7 +21,6 @@ * r4 --- to * r5 --- to + 4096 */ -#include ENTRY(clear_page) mov r4,r5 mov.w .Llimit,r0 @@ -50,3 +52,244 @@ rts nop .Llimit: .word (4096-28) + +ENTRY(__clear_user) + ! + mov #0, r0 + mov #0xe0, r1 ! 0xffffffe0 + ! + ! r4..(r4+31)&~32 -------- not aligned [ Area 0 ] + ! (r4+31)&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] + ! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ] + ! + ! Clear area 0 + mov r4, r2 + ! + tst r1, r5 ! length < 32 + bt .Larea2 ! skip to remainder + ! + add #31, r2 + and r1, r2 + cmp/eq r4, r2 + bt .Larea1 + mov r2, r3 + sub r4, r3 + mov r3, r7 + mov r4, r2 + ! +.L0: dt r3 +0: mov.b r0, @r2 + bf/s .L0 + add #1, r2 + ! + sub r7, r5 + mov r2, r4 +.Larea1: + mov r4, r3 + add r5, r3 + and r1, r3 + cmp/hi r2, r3 + bf .Larea2 + ! + ! Clear area 1 +#if defined(__SH4__) +1: movca.l r0, @r2 +#else +1: mov.l r0, @r2 +#endif + add #4, r2 +2: mov.l r0, @r2 + add #4, r2 +3: mov.l r0, @r2 + add #4, r2 +4: mov.l r0, @r2 + add #4, r2 +5: mov.l r0, @r2 + add #4, r2 +6: mov.l r0, @r2 + add #4, r2 +7: mov.l r0, @r2 + add #4, r2 +8: mov.l r0, @r2 + add #4, r2 + cmp/hi r2, r3 + bt/s 1b + nop + ! + ! Clear area 2 +.Larea2: + mov r4, r3 + add r5, r3 + cmp/hs r3, r2 + bt/s .Ldone + sub r2, r3 +.L2: dt r3 +9: mov.b r0, @r2 + bf/s .L2 + add #1, r2 + ! +.Ldone: rts + mov #0, r0 ! return 0 as normal return + + ! return the number of bytes remained +.Lbad_clear_user: + mov r4, r0 + add r5, r0 + rts + sub r2, r0 + +.section __ex_table,"a" + .align 2 + .long 0b, .Lbad_clear_user + .long 1b, .Lbad_clear_user + .long 2b, .Lbad_clear_user + .long 3b, .Lbad_clear_user + .long 4b, .Lbad_clear_user + .long 5b, .Lbad_clear_user + .long 6b, .Lbad_clear_user + .long 7b, .Lbad_clear_user + .long 8b, .Lbad_clear_user + .long 9b, .Lbad_clear_user +.previous + +#if defined(__SH4__) +/* + * __clear_user_page + * @to: P1 address (with same color) + * @orig_to: P1 address + * + * void __clear_user_page(void *to, void *orig_to) + */ + +/* + * r0 --- scratch + * r4 --- to + * r5 --- orig_to + * r6 --- to + 4096 + */ +ENTRY(__clear_user_page) + mov.w .L4096,r0 + mov r4,r6 + add r0,r6 + mov #0,r0 + ! +1: ocbi @r5 + add #32,r5 + movca.l r0,@r4 + mov r4,r1 + add #32,r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + mov.l r0,@-r4 + add #28,r4 + cmp/eq r6,r4 + bf/s 1b + ocbwb @r1 + ! + rts + nop +.L4096: .word 4096 + +ENTRY(__flush_cache_4096) + mov.l 1f,r3 + add r6,r3 + mov r4,r0 + mov #64,r2 + shll r2 + mov #64,r6 + jmp @r3 + mov #96,r7 + .align 2 +1: .long 2f +2: + .rept 32 + mov.l r5,@r0 + mov.l r5,@(32,r0) + mov.l r5,@(r0,r6) + mov.l r5,@(r0,r7) + add r2,r5 + add r2,r0 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop + +ENTRY(__flush_dcache_all) + mov.l 2f,r0 + mov.l 3f,r4 + and r0,r4 ! r4 = (unsigned long)&empty_zero_page[0] & ~0xffffc000 + stc sr,r1 ! save SR + mov.l 4f,r2 + or r1,r2 + mov #32,r3 + shll2 r3 +1: + ldc r2,sr ! set BL bit + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + ldc r1,sr ! restore SR + dt r3 + bf/s 1b + add #32,r4 + + rts + nop + .align 2 +2: .long 0xffffc000 +3: .long SYMBOL_NAME(empty_zero_page) +4: .long 0x10000000 ! BL bit + +/* flush_cache_4096_all(unsigned long addr) */ +ENTRY(flush_cache_4096_all) + mov.l 2f,r0 + mov.l 3f,r2 + and r0,r2 + or r2,r4 ! r4 = addr | (unsigned long)&empty_zero_page[0] & ~0x3fff + stc sr,r1 ! save SR + mov.l 4f,r2 + or r1,r2 + mov #32,r3 +1: + ldc r2,sr ! set BL bit + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + ldc r1,sr ! restore SR + dt r3 + bf/s 1b + add #32,r4 + + rts + nop + .align 2 +2: .long 0xffffc000 +3: .long SYMBOL_NAME(empty_zero_page) +4: .long 0x10000000 ! BL bit +#endif diff -urN linux-2.4.21/arch/sh/mm/copy_page.S linux-2.4.22/arch/sh/mm/copy_page.S --- linux-2.4.21/arch/sh/mm/copy_page.S 2001-09-08 12:29:09.000000000 -0700 +++ linux-2.4.22/arch/sh/mm/copy_page.S 2003-08-25 04:44:40.000000000 -0700 @@ -1,10 +1,12 @@ -/* $Id: copy_page.S,v 1.2 2001/07/23 10:27:25 gniibe Exp $ +/* $Id: copy_page.S,v 1.1.1.1.2.6 2003/03/23 15:30:58 sugioka Exp $ * - * copy_page implementation of SuperH + * copy_page, __copy_user_page, __copy_user implementation of SuperH * * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima + * Copyright (C) 2002 Toshinobu Sugioka * */ +#include /* * copy_page @@ -21,7 +23,6 @@ * r10 --- to * r11 --- from */ -#include ENTRY(copy_page) mov.l r8,@-r15 mov.l r10,@-r15 @@ -66,4 +67,331 @@ mov.l @r15+,r8 rts nop + +#if defined(__SH4__) +/* + * __copy_user_page + * @to: P1 address (with same color) + * @from: P1 address + * @orig_to: P1 address + * + * void __copy_user_page(void *to, void *from, void *orig_to) + */ + +/* + * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch + * r8 --- from + 4096 + * r9 --- orig_to + * r10 --- to + * r11 --- from + */ +ENTRY(__copy_user_page) + mov.l r8,@-r15 + mov.l r9,@-r15 + mov.l r10,@-r15 + mov.l r11,@-r15 + mov r4,r10 + mov r5,r11 + mov r6,r9 + mov r5,r8 + mov.w .L4096,r0 + add r0,r8 + ! +1: ocbi @r9 + add #32,r9 + mov.l @r11+,r0 + mov.l @r11+,r1 + mov.l @r11+,r2 + mov.l @r11+,r3 + mov.l @r11+,r4 + mov.l @r11+,r5 + mov.l @r11+,r6 + mov.l @r11+,r7 + movca.l r0,@r10 + mov r10,r0 + add #32,r10 + mov.l r7,@-r10 + mov.l r6,@-r10 + mov.l r5,@-r10 + mov.l r4,@-r10 + mov.l r3,@-r10 + mov.l r2,@-r10 + mov.l r1,@-r10 + ocbwb @r0 + cmp/eq r11,r8 + bf/s 1b + add #28,r10 + ! + mov.l @r15+,r11 + mov.l @r15+,r10 + mov.l @r15+,r9 + mov.l @r15+,r8 + rts + nop +#endif .L4096: .word 4096 +/* + * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); + * Return the number of bytes NOT copied + */ +#define EX(...) \ + 9999: __VA_ARGS__ ; \ + .section __ex_table, "a"; \ + .long 9999b, 6000f ; \ + .previous +ENTRY(__copy_user) + tst r6,r6 ! Check explicitly for zero + bf 1f + rts + mov #0,r0 ! normal return +1: + mov.l r10,@-r15 + mov.l r9,@-r15 + mov.l r8,@-r15 + mov r4,r3 + add r6,r3 ! last destination address + mov #12,r0 ! Check if small number of bytes + cmp/gt r0,r6 + bt 2f + bra .L_cleanup_loop + nop +2: + neg r5,r0 ! Calculate bytes needed to align source + add #4,r0 + and #3,r0 + tst r0,r0 + bt .L_jump + mov r0,r1 + +.L_loop1: + ! Copy bytes to align source +EX( mov.b @r5+,r0 ) + dt r1 +EX( mov.b r0,@r4 ) + add #-1,r6 + bf/s .L_loop1 + add #1,r4 + +.L_jump: + mov r6,r2 ! Calculate number of longwords to copy + shlr2 r2 + tst r2,r2 + bt .L_cleanup + + mov r4,r0 ! Jump to appropriate routine + and #3,r0 + mov r0,r1 + shll2 r1 + mova .L_jump_tbl,r0 + mov.l @(r0,r1),r1 + jmp @r1 + nop + + .align 2 +.L_jump_tbl: + .long .L_dest00 + .long .L_dest01 + .long .L_dest10 + .long .L_dest11 + +! Destination = 00 + +.L_dest00: + mov r2,r7 + shlr2 r7 + shlr r7 + tst r7,r7 + mov #7,r0 + bt/s 1f + and r0,r2 + .align 2 +2: +EX( mov.l @r5+,r0 ) +EX( mov.l @r5+,r8 ) +EX( mov.l @r5+,r9 ) +EX( mov.l @r5+,r10 ) +EX( mov.l r0,@r4 ) +EX( mov.l r8,@(4,r4) ) +EX( mov.l r9,@(8,r4) ) +EX( mov.l r10,@(12,r4) ) +EX( mov.l @r5+,r0 ) +EX( mov.l @r5+,r8 ) +EX( mov.l @r5+,r9 ) +EX( mov.l @r5+,r10 ) + dt r7 +EX( mov.l r0,@(16,r4) ) +EX( mov.l r8,@(20,r4) ) +EX( mov.l r9,@(24,r4) ) +EX( mov.l r10,@(28,r4) ) + bf/s 2b + add #32,r4 + tst r2,r2 + bt .L_cleanup +1: +EX( mov.l @r5+,r0 ) + dt r2 +EX( mov.l r0,@r4 ) + bf/s 1b + add #4,r4 + + bra .L_cleanup + nop + +! Destination = 10 + +.L_dest10: + mov r2,r7 + shlr2 r7 + shlr r7 + tst r7,r7 + mov #7,r0 + bt/s 1f + and r0,r2 +2: + dt r7 +#ifdef __LITTLE_ENDIAN__ +EX( mov.l @r5+,r0 ) +EX( mov.l @r5+,r1 ) +EX( mov.l @r5+,r8 ) +EX( mov.l @r5+,r9 ) +EX( mov.l @r5+,r10 ) +EX( mov.w r0,@r4 ) + add #2,r4 + xtrct r1,r0 + xtrct r8,r1 + xtrct r9,r8 + xtrct r10,r9 + +EX( mov.l r0,@r4 ) +EX( mov.l r1,@(4,r4) ) +EX( mov.l r8,@(8,r4) ) +EX( mov.l r9,@(12,r4) ) + +EX( mov.l @r5+,r1 ) +EX( mov.l @r5+,r8 ) +EX( mov.l @r5+,r0 ) + xtrct r1,r10 + xtrct r8,r1 + xtrct r0,r8 + shlr16 r0 +EX( mov.l r10,@(16,r4) ) +EX( mov.l r1,@(20,r4) ) +EX( mov.l r8,@(24,r4) ) +EX( mov.w r0,@(28,r4) ) + bf/s 2b + add #30,r4 +#else +EX( mov.l @(28,r5),r0 ) +EX( mov.l @(24,r5),r8 ) +EX( mov.l @(20,r5),r9 ) +EX( mov.l @(16,r5),r10 ) +EX( mov.w r0,@(30,r4) ) + add #-2,r4 + xtrct r8,r0 + xtrct r9,r8 + xtrct r10,r9 +EX( mov.l r0,@(28,r4) ) +EX( mov.l r8,@(24,r4) ) +EX( mov.l r9,@(20,r4) ) + +EX( mov.l @(12,r5),r0 ) +EX( mov.l @(8,r5),r8 ) + xtrct r0,r10 +EX( mov.l @(4,r5),r9 ) + mov.l r10,@(16,r4) +EX( mov.l @r5,r10 ) + xtrct r8,r0 + xtrct r9,r8 + xtrct r10,r9 +EX( mov.l r0,@(12,r4) ) +EX( mov.l r8,@(8,r4) ) + swap.w r10,r0 +EX( mov.l r9,@(4,r4) ) +EX( mov.w r0,@(2,r4) ) + + add #32,r5 + bf/s 2b + add #34,r4 +#endif + tst r2,r2 + bt .L_cleanup + +1: ! Read longword, write two words per iteration +EX( mov.l @r5+,r0 ) + dt r2 +#ifdef __LITTLE_ENDIAN__ +EX( mov.w r0,@r4 ) + shlr16 r0 +EX( mov.w r0,@(2,r4) ) +#else +EX( mov.w r0,@(2,r4) ) + shlr16 r0 +EX( mov.w r0,@r4 ) +#endif + bf/s 1b + add #4,r4 + + bra .L_cleanup + nop + +! Destination = 01 or 11 + +.L_dest01: +.L_dest11: + ! Read longword, write byte, word, byte per iteration +EX( mov.l @r5+,r0 ) + dt r2 +#ifdef __LITTLE_ENDIAN__ +EX( mov.b r0,@r4 ) + shlr8 r0 + add #1,r4 +EX( mov.w r0,@r4 ) + shlr16 r0 +EX( mov.b r0,@(2,r4) ) + bf/s .L_dest01 + add #3,r4 +#else +EX( mov.b r0,@(3,r4) ) + shlr8 r0 + swap.w r0,r7 +EX( mov.b r7,@r4 ) + add #1,r4 +EX( mov.w r0,@r4 ) + bf/s .L_dest01 + add #3,r4 +#endif + +! Cleanup last few bytes +.L_cleanup: + mov r6,r0 + and #3,r0 + tst r0,r0 + bt .L_exit + mov r0,r6 + +.L_cleanup_loop: +EX( mov.b @r5+,r0 ) + dt r6 +EX( mov.b r0,@r4 ) + bf/s .L_cleanup_loop + add #1,r4 + +.L_exit: + mov #0,r0 ! normal return +5000: + +# Exception handler: +.section .fixup, "ax" +6000: + mov.l 8000f,r1 + mov r3,r0 + jmp @r1 + sub r4,r0 + .align 2 +8000: .long 5000b + +.previous + mov.l @r15+,r8 + mov.l @r15+,r9 + rts + mov.l @r15+,r10 diff -urN linux-2.4.21/arch/sh/mm/fault.c linux-2.4.22/arch/sh/mm/fault.c --- linux-2.4.21/arch/sh/mm/fault.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.22/arch/sh/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.49 2001/10/06 19:46:00 lethal Exp $ +/* $Id: fault.c,v 1.1.1.1.2.3 2002/10/24 05:52:58 mrbrown Exp $ * * linux/arch/sh/mm/fault.c * Copyright (C) 1999 Niibe Yutaka @@ -27,6 +27,10 @@ #include #include +#if defined(CONFIG_SH_KGDB) +#include +#endif + extern void die(const char *,struct pt_regs *,long); /* @@ -95,6 +99,11 @@ unsigned long page; unsigned long fixup; +#if defined(CONFIG_SH_KGDB) + if (kgdb_nofault && kgdb_bus_err_hook) + kgdb_bus_err_hook(); +#endif + tsk = current; mm = tsk->mm; @@ -243,10 +252,16 @@ pte_t *pte; pte_t entry; +#if defined(CONFIG_SH_KGDB) + if (kgdb_nofault && kgdb_bus_err_hook) + kgdb_bus_err_hook(); +#endif if (address >= P3SEG && address < P4SEG) dir = pgd_offset_k(address); else if (address >= TASK_SIZE) return 1; + else if (!current->mm) + return 1; else dir = pgd_offset(current->mm, address); diff -urN linux-2.4.21/arch/sh/mm/init.c linux-2.4.22/arch/sh/mm/init.c --- linux-2.4.21/arch/sh/mm/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/sh/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.19 2001/10/01 02:21:50 gniibe Exp $ +/* $Id: init.c,v 1.1.1.1.2.2 2003/07/07 11:23:21 trent Exp $ * * linux/arch/sh/mm/init.c * @@ -139,7 +139,7 @@ void __init mem_init(void) { extern unsigned long empty_zero_page[1024]; - int codesize, reservedpages, datasize, initsize; + int codesize, reservedpages, datasize, bsssize, initsize, pagemapsize; int tmp; max_mapnr = num_physpages = MAX_LOW_PFN - START_PFN; @@ -163,15 +163,19 @@ reservedpages++; codesize = (unsigned long) &_etext - (unsigned long) &_text; datasize = (unsigned long) &_edata - (unsigned long) &_etext; + bsssize = (unsigned long) &_end - (unsigned long) &__bss_start; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + pagemapsize = (max_mapnr + 1)*sizeof(struct page); - printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", - (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), - max_mapnr << (PAGE_SHIFT-10), - codesize >> 10, - reservedpages << (PAGE_SHIFT-10), - datasize >> 10, - initsize >> 10); + printk("Memory: %luk/%luk available (%dk reserved including: %dk kernel code, %dk data, %dk BSS, %dk init, %dk page map)\n", + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), + max_mapnr << (PAGE_SHIFT-10), + reservedpages << (PAGE_SHIFT-10), + codesize >> 10, + datasize >> 10, + bsssize >> 10, + initsize >> 10, + pagemapsize >> 10); p3_cache_init(); } diff -urN linux-2.4.21/arch/sh/overdrive/Makefile linux-2.4.22/arch/sh/overdrive/Makefile --- linux-2.4.21/arch/sh/overdrive/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,20 @@ +# +# Makefile for the STMicroelectronics Overdrive specific parts of the kernel +# +# 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). +# + +all: overdrive.o + +clean: + +O_TARGET := overdrive.o +obj-y := mach.o setup.o io.o led.o + +ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_SH_7750_OVERDRIVE),) +obj-$(CONFIG_PCI) += irq.o fpga.o galileo.o +endif + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/sh/overdrive/fpga.c linux-2.4.22/arch/sh/overdrive/fpga.c --- linux-2.4.21/arch/sh/overdrive/fpga.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/fpga.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file handles programming up the Altera Flex10K that interfaces to + * the Galileo, and does the PS/2 keyboard and mouse + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "gt64111.h" +#include "overdrive.h" +#include "fpga.h" + +#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT +#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK + +/* I need to find out what (if any) the real delay factor here is */ +/* The delay is definately not critical */ +#define long_delay() {int i;for(i=0;i<10000;i++);} +#define short_delay() {int i;for(i=0;i<100;i++);} + +static void __init program_overdrive_fpga(const unsigned char *fpgacode, + int size) +{ + int timeout = 0; + int i, j; + unsigned char b; + static volatile unsigned char *FPGA_ControlReg = + (volatile unsigned char *) (OVERDRIVE_CTRL); + static volatile unsigned char *FPGA_ProgramReg = + (volatile unsigned char *) (FPGA_DCLK_ADDRESS); + + printk("FPGA: Commencing FPGA Programming\n"); + + /* The PCI reset but MUST be low when programming the FPGA !!! */ + b = (*FPGA_ControlReg) & RESET_PCI_MASK; + + (*FPGA_ControlReg) = b; + + /* Prepare FPGA to program */ + + FPGA_NotConfigHigh(); + long_delay(); + + FPGA_NotConfigLow(); + short_delay(); + + while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) { + printk("FPGA: Waiting for NotStatus to go Low ... \n"); + } + + FPGA_NotConfigHigh(); + + /* Wait for FPGA "ready to be programmed" signal */ + printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n"); + + for (timeout = 0; + (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0) + && (timeout < FPGA_TIMEOUT)); timeout++); + + /* Check if timeout condition occured - i.e. an error */ + + if (timeout == FPGA_TIMEOUT) { + printk + ("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n"); + return; + } + + printk("FPGA: Copying data to FPGA ... %d bytes\n", size); + + /* Copy array to FPGA - bit at a time */ + + for (i = 0; i < size; i++) { + volatile unsigned w = 0; + + for (j = 0; j < 8; j++) { + *FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01; + short_delay(); + } + if ((i & 0x3ff) == 0) { + printk("."); + } + } + + /* Waiting for CONFDONE to go high - means the program is complete */ + + for (timeout = 0; + (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0) + && (timeout < FPGA_TIMEOUT)); timeout++) { + + *FPGA_ProgramReg = 0x0; + long_delay(); + } + + if (timeout == FPGA_TIMEOUT) { + printk + ("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n"); + return; + } else { /* Clock another 10 times - gets the device into a working state */ + for (i = 0; i < 10; i++) { + *FPGA_ProgramReg = 0x0; + short_delay(); + } + } + + printk("FPGA: Programming complete\n"); +} + + +static const unsigned char __init fpgacode[] = { +#include "./overdrive.ttf" /* Code from maxplus2 compiler */ + , 0, 0 +}; + + +int __init init_overdrive_fpga(void) +{ + program_overdrive_fpga(fpgacode, sizeof(fpgacode)); + + return 0; +} diff -urN linux-2.4.21/arch/sh/overdrive/fpga.h linux-2.4.22/arch/sh/overdrive/fpga.h --- linux-2.4.21/arch/sh/overdrive/fpga.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/fpga.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + */ + +#ifndef __FPGA_OD_H__ +#define __FPGA_OD_H__ + +/* This routine will program up the fpga which interfaces to the galileo */ +int init_overdrive_fpga(void); + +#endif diff -urN linux-2.4.21/arch/sh/overdrive/galileo.c linux-2.4.22/arch/sh/overdrive/galileo.c --- linux-2.4.21/arch/sh/overdrive/galileo.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/galileo.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,594 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains the PCI routines required for the Galileo GT6411 + * PCI bridge as used on the Orion and Overdrive boards. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "overdrive.h" +#include "gt64111.h" + + +/* After boot, we shift the Galileo registers so that they appear + * in BANK6, along with IO space. This means we can have one contingous + * lump of PCI address space without these registers appearing in the + * middle of them + */ + +#define GT64111_BASE_ADDRESS 0xbb000000 +#define GT64111_IO_BASE_ADDRESS 0x1000 +/* The GT64111 registers appear at this address to the SH4 after reset */ +#define RESET_GT64111_BASE_ADDRESS 0xb4000000 + +/* Macros used to access the Galileo registers */ +#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x) +#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x) + +#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x)) + +#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x)) + +#define GT_WRITE(x,v) writel((v),GT64111_REG(x)) +#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x)) +#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x)) + +#define GT_READ(x) readl(GT64111_REG(x)) +#define GT_READ_BYTE(x) readb(GT64111_REG(x)) +#define GT_READ_SHORT(x) readw(GT64111_REG(x)) + + +/* Where the various SH banks start at */ +#define SH_BANK4_ADR 0xb0000000 +#define SH_BANK5_ADR 0xb4000000 +#define SH_BANK6_ADR 0xb8000000 + +/* Masks out everything but lines 28,27,26 */ +#define BANK_SELECT_MASK 0x1c000000 + +#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK) + +/* + * Masks used for address conversaion. Bank 6 is used for IO and + * has all the address bits zeroed by the FPGA. Special case this + */ +#define MEMORY_BANK_MASK 0x1fffffff +#define IO_BANK_MASK 0x03ffffff + +/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code + * if you want + */ +#define IO_BANK_ADR PCI_GTIO_BASE + +/* Will select the correct mask to apply depending on the SH$ address */ +#define SELECT_BANK_MASK(x) \ + ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK) + +/* Converts between PCI space and P2 region */ +#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x)) + +/* Various macros for figuring out what to stick in the Galileo registers. + * You *really* don't want to figure this stuff out by hand, you always get + * it wrong + */ +#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff) +#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f) +#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff) + +#define PROGRAM_HI_LO(block,a,s) \ + GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\ + GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1)) + +#define PROGRAM_SUB_HI_LO(block,a,s) \ + GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\ + GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1)) + +/* We need to set the size, and the offset register */ + +#define GT_BAR_MASK(x) ((x)&~0xfff) + +/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */ +#define PROGRAM_GT_BAR(block,a,s) \ + GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\ + write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\ + GT_BAR_MASK(a)) + +#define DISABLE_GT_BAR(block) \ + GT_WRITE(PCI_##block##_BANK_SIZE,0),\ + GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\ + 0x80000000) + +/* Macros to disable things we are not going to use */ +#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\ + GT_WRITE(x##_HI_DEC_ADR,0x00) + +#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\ + GT_WRITE(x##_HI_DEC_ADR,0x00) + +static void __init reset_pci(void) +{ + /* Set RESET_PCI bit high */ + writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); + udelay(250); + + /* Set RESET_PCI bit low */ + writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL); + udelay(250); + + writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); + udelay(250); +} + +static int write_config_to_galileo(int where, u32 val); +#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val) + +#define ENABLE_PCI_DRAM + + +#ifdef TEST_DRAM +/* Test function to check out if the PCI DRAM is working OK */ +static int /* __init */ test_dram(unsigned *base, unsigned size) +{ + unsigned *p = base; + unsigned *end = (unsigned *) (((unsigned) base) + size); + unsigned w; + + for (p = base; p < end; p++) { + *p = 0xffffffff; + if (*p != 0xffffffff) { + printk("AAARGH -write failed!!! at %p is %x\n", p, + *p); + return 0; + } + *p = 0x0; + if (*p != 0x0) { + printk("AAARGH -write failed!!!\n"); + return 0; + } + } + + for (p = base; p < end; p++) { + *p = (unsigned) p; + if (*p != (unsigned) p) { + printk("Failed at 0x%p, actually is 0x%x\n", p, + *p); + return 0; + } + } + + for (p = base; p < end; p++) { + w = ((unsigned) p & 0xffff0000); + *p = w | (w >> 16); + } + + for (p = base; p < end; p++) { + w = ((unsigned) p & 0xffff0000); + w |= (w >> 16); + if (*p != w) { + printk + ("Failed at 0x%p, should be 0x%x actually is 0x%x\n", + p, w, *p); + return 0; + } + } + + return 1; +} +#endif + + +/* Function to set up and initialise the galileo. This sets up the BARS, + * maps the DRAM into the address space etc,etc + */ +int __init galileo_init(void) +{ + reset_pci(); + + /* Now shift the galileo regs into this block */ + RESET_GT_WRITE(INTERNAL_SPACE_DEC, + GT_MEM_LO_ADR(GT64111_BASE_ADDRESS)); + + /* Should have a sanity check here, that you can read back at the new + * address what you just wrote + */ + + /* Disable decode for all regions */ + DISABLE_DECODE(RAS10); + DISABLE_DECODE(RAS32); + DISABLE_DECODE(CS20); + DISABLE_DECODE(CS3); + DISABLE_DECODE(PCI_IO); + DISABLE_DECODE(PCI_MEM0); + DISABLE_DECODE(PCI_MEM1); + + /* Disable all BARS */ + GT_WRITE(BAR_ENABLE_ADR, 0x1ff); + DISABLE_GT_BAR(RAS10); + DISABLE_GT_BAR(RAS32); + DISABLE_GT_BAR(CS20); + DISABLE_GT_BAR(CS3); + + /* Tell the BAR where the IO registers now are */ + GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK( + (GT64111_IO_BASE_ADDRESS & + IO_BANK_MASK))); + /* set up a 112 Mb decode */ + PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024); + + /* Set up a 32 MB io space decode */ + PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024); + +#ifdef ENABLE_PCI_DRAM + /* Program up the DRAM configuration - there is DRAM only in bank 0 */ + /* Now set up the DRAM decode */ + PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE); + /* And the sub decode */ + PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE); + + DISABLE_SUB_DECODE(RAS1); + + /* Set refresh rate */ + GT_WRITE(DRAM_BANK0_PARMS, 0x3f); + GT_WRITE(DRAM_CFG, 0x100); + + /* we have to lob off the top bits rememeber!! */ + PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE); + +#endif + + /* We are only interested in decoding RAS10 and the Galileo's internal + * registers (as IO) on the PCI bus + */ +#ifdef ENABLE_PCI_DRAM + GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff); +#else + GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff); +#endif + + /* Change the class code to host bridge, it actually powers up + * as a memory controller + */ + GT_CONFIG_WRITE(8, 0x06000011); + + /* Allow the galileo to master the PCI bus */ + GT_CONFIG_WRITE(PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_IO); + + +#if 0 + printk("Testing PCI DRAM - "); + if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { + printk("Passed\n"); + }else { + printk("FAILED\n"); + } +#endif + return 0; + +} + + +#define SET_CONFIG_BITS(bus,devfn,where)\ + ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) + +#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where) + +/* This write to the galileo config registers, unlike the functions below, can + * be used before the PCI subsystem has started up + */ +static int __init write_config_to_galileo(int where, u32 val) +{ + GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where)); + + GT_WRITE(PCI_CFG_DATA, val); + return 0; +} + +/* We exclude the galileo and slot 31, the galileo because I don't know how to stop + * the setup code shagging up the setup I have done on it, and 31 because the whole + * thing locks up if you try to access that slot (which doesn't exist of course anyway + */ + +#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31))) + +static int galileo_read_config_byte(struct pci_dev *dev, int where, + u8 * val) +{ + + + /* I suspect this doesn't work because this drives a special cycle ? */ + if (EXCLUDED_DEV(dev)) { + *val = 0xff; + return PCIBIOS_SUCCESSFUL; + } + /* Start the config cycle */ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + /* Read back the result */ + *val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3)); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_read_config_word(struct pci_dev *dev, int where, + u16 * val) +{ + + if (EXCLUDED_DEV(dev)) { + *val = 0xffff; + return PCIBIOS_SUCCESSFUL; + } + + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + *val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2)); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_read_config_dword(struct pci_dev *dev, int where, + u32 * val) +{ + if (EXCLUDED_DEV(dev)) { + *val = 0xffffffff; + return PCIBIOS_SUCCESSFUL; + } + + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + *val = GT_READ(PCI_CFG_DATA); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_write_config_byte(struct pci_dev *dev, int where, + u8 val) +{ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + + GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_write_config_word(struct pci_dev *dev, int where, + u16 val) +{ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + + GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + + GT_WRITE(PCI_CFG_DATA, val); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_config_ops = { + galileo_read_config_byte, + galileo_read_config_word, + galileo_read_config_dword, + galileo_write_config_byte, + galileo_write_config_word, + galileo_write_config_dword +}; + + +/* Everything hangs off this */ +static struct pci_bus *pci_root_bus; + + +static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) +{ + return PCI_SLOT(dev->devfn); +} + +static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + /* Slot 1: Galileo + * Slot 2: PCI Slot 1 + * Slot 3: PCI Slot 2 + * Slot 4: ESS + */ + switch (slot) { + case 2: + return OVERDRIVE_PCI_IRQ1; + case 3: + /* Note this assumes you have a hacked card in slot 2 */ + return OVERDRIVE_PCI_IRQ2; + case 4: + return OVERDRIVE_ESS_IRQ; + default: + /* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */ + return -1; + } +} + + + +void __init +pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) +{ + ranges->io_start -= bus->resource[0]->start; + ranges->io_end -= bus->resource[0]->start; + ranges->mem_start -= bus->resource[1]->start; + ranges->mem_end -= bus->resource[1]->start; +} + +static void __init pci_fixup_ide_bases(struct pci_dev *d) +{ + int i; + + /* + * PCI IDE controllers use non-standard I/O port decoding, respect it. + */ + if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + printk("PCI: IDE base address fixup for %s\n", d->slot_name); + for(i=0; i<4; i++) { + struct resource *r = &d->resource[i]; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } + } +} + + +/* Add future fixups here... */ +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases }, + { 0 } +}; + +void __init pcibios_init(void) +{ + static struct resource galio,galmem; + + /* Allocate the registers used by the Galileo */ + galio.flags = IORESOURCE_IO; + galio.name = "Galileo GT64011"; + galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH; + galmem.name = "Galileo GT64011 DRAM"; + + allocate_resource(&ioport_resource, &galio, 256, + GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL); + allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE, + PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE, + PCI_DRAM_SIZE, NULL, NULL); + + /* ok, do the scan man */ + pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); + + pci_assign_unassigned_resources(); + pci_fixup_irqs(no_swizzle, map_od_irq); + +#ifdef TEST_DRAM + printk("Testing PCI DRAM - "); + if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { + printk("Passed\n"); + }else { + printk("FAILED\n"); + } +#endif + +} + +char * __init pcibios_setup(char *str) +{ + return str; +} + + + +int pcibios_enable_device(struct pci_dev *dev) +{ + + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = dev->resource + idx; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because" + " of resource collisions\n", + dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: enabling device %s (%04x -> %04x)\n", + dev->slot_name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; + +} + +/* We should do some optimisation work here I think. Ok for now though */ +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size) +{ +} + +void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + + unsigned long where, size; + u32 reg; + + + printk("PCI: Assigning %3s %08lx to %s\n", + res->flags & IORESOURCE_IO ? "IO" : "MEM", + res->start, dev->name); + + where = PCI_BASE_ADDRESS_0 + resource * 4; + size = res->end - res->start; + + pci_read_config_dword(dev, where, ®); + reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); + pci_write_config_dword(dev, where, reg); +} + + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +/* + * If we set up a device for bus mastering, we need to check the latency + * timer as certain crappy BIOSes forget to set it properly. + */ +unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} diff -urN linux-2.4.21/arch/sh/overdrive/gt64111.h linux-2.4.22/arch/sh/overdrive/gt64111.h --- linux-2.4.21/arch/sh/overdrive/gt64111.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/gt64111.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,109 @@ +#ifndef _GT64111_H_ +#define _GT64111_H_ + +#define MASTER_INTERFACE 0x0 +#define RAS10_LO_DEC_ADR 0x8 +#define RAS10_HI_DEC_ADR 0x10 +#define RAS32_LO_DEC_ADR 0x18 +#define RAS32_HI_DEC_ADR 0x20 +#define CS20_LO_DEC_ADR 0x28 +#define CS20_HI_DEC_ADR 0x30 +#define CS3_LO_DEC_ADR 0x38 +#define CS3_HI_DEC_ADR 0x40 +#define PCI_IO_LO_DEC_ADR 0x48 +#define PCI_IO_HI_DEC_ADR 0x50 +#define PCI_MEM0_LO_DEC_ADR 0x58 +#define PCI_MEM0_HI_DEC_ADR 0x60 +#define INTERNAL_SPACE_DEC 0x68 +#define BUS_ERR_ADR_LO_CPU 0x70 +#define READONLY0 0x78 +#define PCI_MEM1_LO_DEC_ADR 0x80 +#define PCI_MEM1_HI_DEC_ADR 0x88 +#define RAS0_LO_DEC_ADR 0x400 +#define RAS0_HI_DEC_ADR 0x404 +#define RAS1_LO_DEC_ADR 0x408 +#define RAS1_HI_DEC_ADR 0x40c +#define RAS2_LO_DEC_ADR 0x410 +#define RAS2_HI_DEC_ADR 0x414 +#define RAS3_LO_DEC_ADR 0x418 +#define RAS3_HI_DEC_ADR 0x41c +#define DEV_CS0_LO_DEC_ADR 0x420 +#define DEV_CS0_HI_DEC_ADR 0x424 +#define DEV_CS1_LO_DEC_ADR 0x428 +#define DEV_CS1_HI_DEC_ADR 0x42c +#define DEV_CS2_LO_DEC_ADR 0x430 +#define DEV_CS2_HI_DEC_ADR 0x434 +#define DEV_CS3_LO_DEC_ADR 0x438 +#define DEV_CS3_HI_DEC_ADR 0x43c +#define DEV_BOOTCS_LO_DEC_ADR 0x440 +#define DEV_BOOTCS_HI_DEC_ADR 0x444 +#define DEV_ADR_DEC_ERR 0x470 +#define DRAM_CFG 0x448 +#define DRAM_BANK0_PARMS 0x44c +#define DRAM_BANK1_PARMS 0x450 +#define DRAM_BANK2_PARMS 0x454 +#define DRAM_BANK3_PARMS 0x458 +#define DEV_BANK0_PARMS 0x45c +#define DEV_BANK1_PARMS 0x460 +#define DEV_BANK2_PARMS 0x464 +#define DEV_BANK3_PARMS 0x468 +#define DEV_BOOT_BANK_PARMS 0x46c +#define CH0_DMA_BYTECOUNT 0x800 +#define CH1_DMA_BYTECOUNT 0x804 +#define CH2_DMA_BYTECOUNT 0x808 +#define CH3_DMA_BYTECOUNT 0x80c +#define CH0_DMA_SRC_ADR 0x810 +#define CH1_DMA_SRC_ADR 0x814 +#define CH2_DMA_SRC_ADR 0x818 +#define CH3_DMA_SRC_ADR 0x81c +#define CH0_DMA_DST_ADR 0x820 +#define CH1_DMA_DST_ADR 0x824 +#define CH2_DMA_DST_ADR 0x828 +#define CH3_DMA_DST_ADR 0x82c +#define CH0_NEXT_REC_PTR 0x830 +#define CH1_NEXT_REC_PTR 0x834 +#define CH2_NEXT_REC_PTR 0x838 +#define CH3_NEXT_REC_PTR 0x83c +#define CH0_CTRL 0x840 +#define CH1_CTRL 0x844 +#define CH2_CTRL 0x848 +#define CH3_CTRL 0x84c +#define DMA_ARBITER 0x860 +#define TIMER0 0x850 +#define TIMER1 0x854 +#define TIMER2 0x858 +#define TIMER3 0x85c +#define TIMER_CTRL 0x864 +#define PCI_CMD 0xc00 +#define PCI_TIMEOUT 0xc04 +#define PCI_RAS10_BANK_SIZE 0xc08 +#define PCI_RAS32_BANK_SIZE 0xc0c +#define PCI_CS20_BANK_SIZE 0xc10 +#define PCI_CS3_BANK_SIZE 0xc14 +#define PCI_SERRMASK 0xc28 +#define PCI_INTACK 0xc34 +#define PCI_BAR_EN 0xc3c +#define PCI_CFG_ADR 0xcf8 +#define PCI_CFG_DATA 0xcfc +#define PCI_INTCAUSE 0xc18 +#define PCI_MAST_MASK 0xc1c +#define PCI_PCIMASK 0xc24 +#define BAR_ENABLE_ADR 0xc3c + +/* These are config registers, accessible via PCI space */ +#define PCI_CONFIG_RAS10_BASE_ADR 0x010 +#define PCI_CONFIG_RAS32_BASE_ADR 0x014 +#define PCI_CONFIG_CS20_BASE_ADR 0x018 +#define PCI_CONFIG_CS3_BASE_ADR 0x01c +#define PCI_CONFIG_INT_REG_MM_ADR 0x020 +#define PCI_CONFIG_INT_REG_IO_ADR 0x024 +#define PCI_CONFIG_BOARD_VENDOR 0x02c +#define PCI_CONFIG_ROM_ADR 0x030 +#define PCI_CONFIG_INT_PIN_LINE 0x03c + + + + + +#endif + diff -urN linux-2.4.21/arch/sh/overdrive/io.c linux-2.4.22/arch/sh/overdrive/io.c --- linux-2.4.21/arch/sh/overdrive/io.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/io.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains the I/O routines for use on the overdrive board + * + */ + +#include +#include +#include +#include +#include +#include + +#include "overdrive.h" + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the SuperH architecture, we just read/write the + * memory location directly. + */ + +#define dprintk(x...) + +/* Translates an IO address to where it is mapped in memory */ + +#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE) + +unsigned char od_inb(unsigned long port) +{ +dprintk("od_inb(%x)\n", port); + return readb(io_addr(port)) & 0xff; +} + + +unsigned short od_inw(unsigned long port) +{ +dprintk("od_inw(%x)\n", port); + return readw(io_addr(port)) & 0xffff; +} + +unsigned int od_inl(unsigned long port) +{ +dprintk("od_inl(%x)\n", port); + return readl(io_addr(port)); +} + +void od_outb(unsigned char value, unsigned long port) +{ +dprintk("od_outb(%x, %x)\n", value, port); + writeb(value, io_addr(port)); +} + +void od_outw(unsigned short value, unsigned long port) +{ +dprintk("od_outw(%x, %x)\n", value, port); + writew(value, io_addr(port)); +} + +void od_outl(unsigned int value, unsigned long port) +{ +dprintk("od_outl(%x, %x)\n", value, port); + writel(value, io_addr(port)); +} + +/* This is horrible at the moment - needs more work to do something sensible */ +#define IO_DELAY() udelay(10) + +#define OUT_DELAY(x,type) \ +void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();} + +#define IN_DELAY(x,type) \ +unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;} + + +OUT_DELAY(b,char) +OUT_DELAY(w,short) +OUT_DELAY(l,int) + +IN_DELAY(b,char) +IN_DELAY(w,short) +IN_DELAY(l,int) + + +/* Now for the string version of these functions */ +void od_outsb(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p++) { + outb(*p, port); + } +} + + +void od_insb(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p++) { + *p = inb(port); + } +} + +/* For the 16 and 32 bit string functions, we have to worry about alignment. + * The SH does not do unaligned accesses, so we have to read as bytes and + * then write as a word or dword. + * This can be optimised a lot more, especially in the case where the data + * is aligned + */ + +void od_outsw(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned short tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 2) { + tmp = (*p) | ((*(p + 1)) << 8); + outw(tmp, port); + } +} + + +void od_insw(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned short tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 2) { + tmp = inw(port); + p[0] = tmp & 0xff; + p[1] = (tmp >> 8) & 0xff; + } +} + + +void od_outsl(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 4) { + tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) | + ((*(p + 3)) << 24); + outl(tmp, port); + } +} + + +void od_insl(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 4) { + tmp = inl(port); + p[0] = tmp & 0xff; + p[1] = (tmp >> 8) & 0xff; + p[2] = (tmp >> 16) & 0xff; + p[3] = (tmp >> 24) & 0xff; + + } +} diff -urN linux-2.4.21/arch/sh/overdrive/io_od.h linux-2.4.22/arch/sh/overdrive/io_od.h --- linux-2.4.21/arch/sh/overdrive/io_od.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/io_od.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,77 @@ +/* + * include/asm-sh/io_od.h + * + * Copyright 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * IO functions for an STMicroelectronics Overdrive + */ + +#ifndef _ASM_SH_IO_OD_H +#define _ASM_SH_IO_OD_H + +#include + +extern unsigned char od_inb(unsigned long port); +extern unsigned short od_inw(unsigned long port); +extern unsigned int od_inl(unsigned long port); + +extern void od_outb(unsigned char value, unsigned long port); +extern void od_outw(unsigned short value, unsigned long port); +extern void od_outl(unsigned int value, unsigned long port); + +extern unsigned char od_inb_p(unsigned long port); +extern unsigned short od_inw_p(unsigned long port); +extern unsigned int od_inl_p(unsigned long port); +extern void od_outb_p(unsigned char value, unsigned long port); +extern void od_outw_p(unsigned short value, unsigned long port); +extern void od_outl_p(unsigned int value, unsigned long port); + +extern void od_insb(unsigned long port, void *addr, unsigned long count); +extern void od_insw(unsigned long port, void *addr, unsigned long count); +extern void od_insl(unsigned long port, void *addr, unsigned long count); +extern void od_outsb(unsigned long port, const void *addr, unsigned long count); +extern void od_outsw(unsigned long port, const void *addr, unsigned long count); +extern void od_outsl(unsigned long port, const void *addr, unsigned long count); + +extern unsigned long od_isa_port2addr(unsigned long offset); + +#ifdef __WANT_IO_DEF + +# define __inb od_inb +# define __inw od_inw +# define __inl od_inl +# define __outb od_outb +# define __outw od_outw +# define __outl od_outl + +# define __inb_p od_inb_p +# define __inw_p od_inw_p +# define __inl_p od_inl_p +# define __outb_p od_outb_p +# define __outw_p od_outw_p +# define __outl_p od_outl_p + +# define __insb od_insb +# define __insw od_insw +# define __insl od_insl +# define __outsb od_outsb +# define __outsw od_outsw +# define __outsl od_outsl + +# define __readb generic_readb +# define __readw generic_readw +# define __readl generic_readl +# define __writeb generic_writeb +# define __writew generic_writew +# define __writel generic_writel + +# define __isa_port2addr od_isa_port2addr +# define __ioremap generic_ioremap +# define __iounmap generic_iounmap + +#endif + +#endif /* _ASM_SH_IO_OD_H */ diff -urN linux-2.4.21/arch/sh/overdrive/irq.c linux-2.4.22/arch/sh/overdrive/irq.c --- linux-2.4.21/arch/sh/overdrive/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Looks after interrupts on the overdrive board. + * + * Bases on the IPR irq system + */ + +#include +#include +#include + +#include +#include + +#include "overdrive.h" + +struct od_data { + int overdrive_irq; + int irq_mask; +}; + +#define NUM_EXTERNAL_IRQS 16 +#define EXTERNAL_IRQ_NOT_IN_USE (-1) +#define EXTERNAL_IRQ_NOT_ASSIGNED (-1) + +/* + * This table is used to determine what to program into the FPGA's CT register + * for the specified Linux IRQ. + * + * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0)) + * but is one greater than that because the because the FPGA treats 0 + * as disabled, a value of 1 asserts PCI_Int0, and so on. + * + * The overdrive_irq specifies which of the eight interrupt sources generates + * that interrupt, and but is multiplied by four to give the bit offset into + * the CT register. + * + * The seven interrupts levels (SH4 IRL's) we have available here is hardwired + * by the EPLD. The assignments here of which PCI interrupt generates each + * level is arbitary. + */ +static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = { + /* overdrive_irq , irq_mask */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */ +}; + +static void set_od_data(int overdrive_irq, int irq) +{ + if (irq >= NUM_EXTERNAL_IRQS || irq < 0) + return; + od_data_table[irq].overdrive_irq = overdrive_irq << 2; +} + +static void enable_od_irq(unsigned int irq); +void disable_od_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_od_irq disable_od_irq + +static void mask_and_ack_od(unsigned int); +static void end_od_irq(unsigned int irq); + +static unsigned int startup_od_irq(unsigned int irq) +{ + enable_od_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type od_irq_type = { + "Overdrive-IRQ", + startup_od_irq, + shutdown_od_irq, + enable_od_irq, + disable_od_irq, + mask_and_ack_od, + end_od_irq +}; + +static void disable_od_irq(unsigned int irq) +{ + unsigned val, flags; + int overdrive_irq; + unsigned mask; + + /* Not a valid interrupt */ + if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) + return; + + /* Is is necessary to use a cli here? Would a spinlock not be + * mroe efficient? + */ + save_and_cli(flags); + overdrive_irq = od_data_table[irq].overdrive_irq; + if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { + mask = ~(0x7 << overdrive_irq); + val = ctrl_inl(OVERDRIVE_INT_CT); + val &= mask; + ctrl_outl(val, OVERDRIVE_INT_CT); + } + restore_flags(flags); +} + +static void enable_od_irq(unsigned int irq) +{ + unsigned val, flags; + int overdrive_irq; + unsigned mask; + + /* Not a valid interrupt */ + if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) + return; + + /* Set priority in OD back to original value */ + save_and_cli(flags); + /* This one is not in use currently */ + overdrive_irq = od_data_table[irq].overdrive_irq; + if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { + val = ctrl_inl(OVERDRIVE_INT_CT); + mask = ~(0x7 << overdrive_irq); + val &= mask; + mask = od_data_table[irq].irq_mask << overdrive_irq; + val |= mask; + ctrl_outl(val, OVERDRIVE_INT_CT); + } + restore_flags(flags); +} + + + +/* this functions sets the desired irq handler to be an overdrive type */ +static void __init make_od_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &od_irq_type; + disable_od_irq(irq); +} + + +static void mask_and_ack_od(unsigned int irq) +{ + disable_od_irq(irq); +} + +static void end_od_irq(unsigned int irq) +{ + enable_od_irq(irq); +} + +void __init init_overdrive_irq(void) +{ + int i; + + /* Disable all interrupts */ + ctrl_outl(0, OVERDRIVE_INT_CT); + + /* Update interrupt pin mode to use encoded interrupts */ + i = ctrl_inw(INTC_ICR); + i &= ~INTC_ICR_IRLM; + ctrl_outw(i, INTC_ICR); + + for (i = 0; i < NUM_EXTERNAL_IRQS; i++) { + if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) { + make_od_irq(i); + } else if (i != 15) { // Cannot use imask on level 15 + make_imask_irq(i); + } + } + + /* Set up the interrupts */ + set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1); + set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2); + set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ); +} diff -urN linux-2.4.21/arch/sh/overdrive/led.c linux-2.4.22/arch/sh/overdrive/led.c --- linux-2.4.21/arch/sh/overdrive/led.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/led.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,59 @@ +/* + * linux/arch/sh/overdrive/led.c + * + * Copyright (C) 1999 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains an Overdrive specific LED feature. + */ + +#include +#include +#include +#include "overdrive.h" + +static void mach_led(int position, int value) +{ + unsigned long flags; + unsigned long reg; + + save_and_cli(flags); + + reg = readl(OVERDRIVE_CTRL); + if (value) { + reg |= (1<<3); + } else { + reg &= ~(1<<3); + } + writel(reg, OVERDRIVE_CTRL); + + restore_flags(flags); +} + +#ifdef CONFIG_HEARTBEAT + +#include + +/* acts like an actual heart beat -- ie thump-thump-pause... */ +void heartbeat_od(void) +{ + static unsigned cnt = 0, period = 0, dist = 0; + + if (cnt == 0 || cnt == dist) + mach_led( -1, 1); + else if (cnt == 7 || cnt == dist+7) + mach_led( -1, 0); + + if (++cnt > period) { + cnt = 0; + /* The hyperbolic function below modifies the heartbeat period + * length in dependency of the current (5min) load. It goes + * through the points f(0)=126, f(1)=86, f(5)=51, + * f(inf)->30. */ + period = ((672< + +#include +#include +#include + +#include +#include +#include + +void heartbeat_od(void); +void setup_od(void); +void init_overdrive_irq(void); +void galileo_pcibios_init(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_od __initmv = { + mv_name: "SH7750 Overdrive", + + mv_nr_irqs: 48, + + mv_inb: od_inb, + mv_inw: od_inw, + mv_inl: od_inl, + mv_outb: od_outb, + mv_outw: od_outw, + mv_outl: od_outl, + + mv_inb_p: od_inb_p, + mv_inw_p: od_inw_p, + mv_inl_p: od_inl_p, + mv_outb_p: od_outb_p, + mv_outw_p: od_outw_p, + mv_outl_p: od_outl_p, + + mv_insb: od_insb, + mv_insw: od_insw, + mv_insl: od_insl, + mv_outsb: od_outsb, + mv_outsw: od_outsw, + mv_outsl: od_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_ioremap: generic_ioremap, + mv_iounmap: generic_iounmap, + + mv_isa_port2addr: generic_isa_port2addr, + + mv_init_arch: setup_od, +#ifdef CONFIG_PCI + mv_init_irq: init_overdrive_irq, +#endif +#ifdef CONFIG_HEARTBEAT + mv_heartbeat: heartbeat_od, +#endif + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, +}; + +ALIAS_MV(od) diff -urN linux-2.4.21/arch/sh/overdrive/overdrive.h linux-2.4.22/arch/sh/overdrive/overdrive.h --- linux-2.4.21/arch/sh/overdrive/overdrive.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/overdrive.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + */ + +#include + +#ifndef __OVERDRIVE_H__ +#define __OVERDRIVE_H__ + +#define OVERDRIVE_INT_CT 0xa3a00000 +#define OVERDRIVE_INT_DT 0xa3b00000 + +#define OVERDRIVE_CTRL 0xa3000000 + +/* Shoving all these bits into the same register is not a good idea. + * As soon as I get a spare moment, I'll change the FPGA and put each + * bit in a separate register + */ + +#define VALID_CTRL_BITS 0x1f + +#define ENABLE_RS232_MASK 0x1e +#define DISABLE_RS232_BIT 0x01 + +#define ENABLE_NMI_MASK 0x1d +#define DISABLE_NMI_BIT 0x02 + +#define RESET_PCI_MASK 0x1b +#define ENABLE_PCI_BIT 0x04 + +#define ENABLE_LED_MASK 0x17 +#define DISABLE_LED_BIT 0x08 + +#define RESET_FPGA_MASK 0x0f +#define ENABLE_FPGA_BIT 0x10 + + +#define FPGA_DCLK_ADDRESS 0xA3C00000 + +#define FPGA_DATA 0x01 /* W */ +#define FPGA_CONFDONE 0x02 /* R */ +#define FPGA_NOT_STATUS 0x04 /* R */ +#define FPGA_INITDONE 0x08 /* R */ + +#define FPGA_TIMEOUT 100000 + + +/* Interrupts for the overdrive. Note that these numbers have + * nothing to do with the actual IRQ numbers they appear on, + * this is all programmable. This is simply the position in the + * INT_CT register. + */ + +#define OVERDRIVE_PCI_INTA 0 +#define OVERDRIVE_PCI_INTB 1 +#define OVERDRIVE_PCI_INTC 2 +#define OVERDRIVE_PCI_INTD 3 +#define OVERDRIVE_GALILEO_INT 4 +#define OVERDRIVE_GALILEO_LOCAL_INT 5 +#define OVERDRIVE_AUDIO_INT 6 +#define OVERDRIVE_KEYBOARD_INT 7 + +/* Which Linux IRQ should we assign to each interrupt source? */ +#define OVERDRIVE_PCI_IRQ1 2 +#ifdef CONFIG_HACKED_NE2K +#define OVERDRIVE_PCI_IRQ2 7 +#else +#define OVERDRIVE_PCI_IRQ2 2 +#undef OVERDRIVE_PCI_INTB +#define OVERDRIVE_PCI_INTB OVERDRIVE_PCI_INTA + +#endif + +/* Put the ESS solo audio chip on IRQ 4 */ +#define OVERDRIVE_ESS_IRQ 4 + +/* Where the memory behind the PCI bus appears */ +#define PCI_DRAM_BASE 0xb7000000 +#define PCI_DRAM_SIZE (16*1024*1024) +#define PCI_DRAM_FINISH (PCI_DRAM_BASE+PCI_DRAM_SIZE-1) + +/* Where the IO region appears in the memory */ +#define PCI_GTIO_BASE 0xb8000000 + +#endif diff -urN linux-2.4.21/arch/sh/overdrive/pcidma.c linux-2.4.22/arch/sh/overdrive/pcidma.c --- linux-2.4.21/arch/sh/overdrive/pcidma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/pcidma.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Dynamic DMA mapping support. + * + * On the overdrive, we can only DMA from memory behind the PCI bus! + * this means that all DMA'able memory must come from there. + * this restriction will not apply to later boards. + */ + +#include +#include +#include +#include +#include + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t * dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + + printk("BUG: pci_alloc_consistent() called - not yet supported\n"); + /* We ALWAYS need DMA memory on the overdrive hardware, + * due to it's extreme wierdness + * Need to flush the cache here as well, since the memory + * can still be seen through the cache! + */ + gfp |= GFP_DMA; + ret = (void *) __get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + return ret; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long) vaddr, get_order(size)); +} diff -urN linux-2.4.21/arch/sh/overdrive/setup.c linux-2.4.22/arch/sh/overdrive/setup.c --- linux-2.4.21/arch/sh/overdrive/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh/overdrive/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,32 @@ +/* + * arch/sh/overdrive/setup.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * STMicroelectronics Overdrive Support. + */ + +#include +#include +#include +#include + +#include "overdrive.h" +#include "fpga.h" + +/* + * Initialize the board + */ +int __init setup_od(void) +{ +#ifdef CONFIG_PCI + init_overdrive_fpga(); + galileo_init(); +#endif + + /* Enable RS232 receive buffers */ + writel(0x1e, OVERDRIVE_CTRL); +} diff -urN linux-2.4.21/arch/sh/stboards/setup.c linux-2.4.22/arch/sh/stboards/setup.c --- linux-2.4.21/arch/sh/stboards/setup.c 2001-06-27 13:55:29.000000000 -0700 +++ linux-2.4.22/arch/sh/stboards/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -48,3 +48,31 @@ return 0; } + +#ifdef CONFIG_PCI +/* + * PCI based boards need a function that maps IRQ's to given PCI + * slots. This code is used by the st40 pci routines in arch/sh/kernel + */ + +int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { +#ifdef CONFIG_SH_STB1_HARP + case 2: /*This is the PCI slot on the */ + return HARP_PCI_IRQ; + case 1: /* this is the bridge */ + return HARP_BRIDGE_IRQ; +#elif defined(CONFIG_SH_STB1_OVERDRIVE) + case 1: + case 2: + case 3: + return slot - 1; +#else +#error Unknown board +#endif + default: + return -1; + } +} +#endif diff -urN linux-2.4.21/arch/sh64/Makefile linux-2.4.22/arch/sh64/Makefile --- linux-2.4.21/arch/sh64/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,91 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2000, 2001 Paolo Alberelli +# Copyright (C) 2003 Paul Mundt +# +# This file is included by the global makefile so that you can add your own +# architecture-specific flags and dependencies. Remember to do have actions +# for "archclean" and "archdep" for cleaning up and making dependencies for +# this architecture +# +# Note that top level Makefile automagically builds dependencies for SUBDIRS +# but does not automagically clean SUBDIRS. Therefore "archclean" should clean +# up all, "archdep" does nothing on added SUBDIRS. +# + +cpu-y := -mb +cpu-$(CONFIG_LITTLE_ENDIAN) := -ml + +cpu-$(CONFIG_CPU_SH5) += -m5-32media-nofpu + +ifdef CONFIG_LITTLE_ENDIAN +LDFLAGS += -EL -mshlelf32_linux +else +LDFLAGS += -EB -mshelf32_linux +endif + +# No requirements for endianess support from AFLAGS, 'as' always run through gcc +AFLAGS += -m5 -isa=sh64 -traditional +CFLAGS += $(cpu-y) + +ENTRY_POINT = --defsym phys_stext=_stext-0x$(CONFIG_CACHED_MEMORY_OFFSET) \ + -e phys_stext +OBJCOPY = $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment \ + -R .stab -R .stabstr -S +LD = $(CROSS_COMPILE)ld $(LDFLAGS) + +LINKFLAGS += -T arch/$(ARCH)/vmlinux.lds $(ENTRY_POINT) + +ifdef LOADADDR +LINKFLAGS += -Ttext $(word 1,$(LOADADDR)) +endif + +machine-$(CONFIG_SH_CAYMAN) := cayman +machine-$(CONFIG_SH_SIMULATOR) := sim +machine-$(CONFIG_SH_HARP) := harp + +HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o +MAKEROOTFS = + +SUBDIRS += $(addprefix arch/$(ARCH)/, kernel mm lib mach-$(machine-y)) +CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \ + arch/$(ARCH)/mach-$(machine-y)/$(machine-y).o \ + $(CORE_FILES) + +LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +LIBS := $(TOPDIR)/arch/$(ARCH)/lib/lib.a $(LIBS) $(LIBGCC) + +MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot + +# +# override the assembly rules +# +#.S.o: +# $(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o + +vmlinux: arch/$(ARCH)/vmlinux.lds + +arch/$(ARCH)/vmlinux.lds: arch/$(ARCH)/vmlinux.lds.S FORCE + $(CPP) $(TOOLCHAIN) $(AFLAGS) -C -P -I$(HPATH) -U$(ARCH) arch/$(ARCH)/vmlinux.lds.S >arch/$(ARCH)/vmlinux.lds + +FORCE: ; + +zImage: vmlinux + @$(MAKEBOOT) zImage + +compressed: zImage + +zdisk: vmlinux + @$(MAKEBOOT) zdisk + +archclean: +# @$(MAKEBOOT) clean + +archmrproper: + rm -f arch/$(ARCH)/vmlinux.lds + +archdep: +# @$(MAKEBOOT) dep diff -urN linux-2.4.21/arch/sh64/boot/Makefile linux-2.4.22/arch/sh64/boot/Makefile --- linux-2.4.21/arch/sh64/boot/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/boot/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,34 @@ +# +# arch/shmedia/boot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2002 Stuart Menefy +# + +SYSTEM =$(TOPDIR)/vmlinux + +Image: $(CONFIGURE) $(SYSTEM) + $(OBJCOPY) $(SYSTEM) Image + +zImage: $(CONFIGURE) compressed/vmlinux + $(OBJCOPY) compressed/vmlinux zImage + +compressed/vmlinux: $(TOPDIR)/vmlinux + $(MAKE) -C compressed vmlinux + +install: $(CONFIGURE) Image + sh -x ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" + +zinstall: $(CONFIGURE) zImage + sh -x ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" + +dep: + +clean: + rm -f tools/build + rm -f setup bootsect zImage compressed/vmlinux.out + rm -f bsetup bbootsect bzImage compressed/bvmlinux.out + @$(MAKE) -C compressed clean diff -urN linux-2.4.21/arch/sh64/boot/compressed/Makefile linux-2.4.22/arch/sh64/boot/compressed/Makefile --- linux-2.4.21/arch/sh64/boot/compressed/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/boot/compressed/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,57 @@ +# +# linux/arch/shmedia/boot/compressed/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2002 Stuart Menefy +# +# create a compressed vmlinux image from the original vmlinux +# + + +# This is a temporary work around for a problem with the Linux ld. +# We can't use the Linux linker, because it doesn't work with binary +# files, so we use the bard machine linker instead... +PIGGYLD=sh64-superh-elf-ld -EL # -m shlelf64 +# ...which has the knock on that we need this when doing the final link. +EXTRAFLAGS=--no-warn-mismatch + +HEAD = head.o +SYSTEM = $(TOPDIR)/vmlinux + +OBJECTS = $(HEAD) misc.o cache.o + +ZLDFLAGS = -e startup -T vmlinux.lds + +# +# ZIMAGE_OFFSET is the load offset of the compression loader +# (4M for the kernel plus 64K for this loader) +# +ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x$(CONFIG_MEMORY_START)+0x400000+0x10000]) + +ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS) + +all: vmlinux + +vmlinux.lds: vmlinux.lds.S + $(CPP) -traditional -C -P -I$(HPATH) -Ush vmlinux.lds.S >vmlinux.lds + +vmlinux: piggy.o $(OBJECTS) vmlinux.lds + $(LD) $(ZLINKFLAGS) $(EXTRAFLAGS) -o vmlinux $(OBJECTS) piggy.o + +head.o: head.S + $(CC) $(AFLAGS) -traditional -c head.S + +piggy.o: $(SYSTEM) + tmppiggy=_tmp_$$$$piggy; \ + rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \ + $(OBJCOPY) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \ + gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \ + echo "SECTIONS { .image : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \ + $(PIGGYLD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-sh64 -T $$tmppiggy.lnk; \ + rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk + +clean: + rm -f vmlinux _tmp_* diff -urN linux-2.4.21/arch/sh64/boot/compressed/cache.c linux-2.4.22/arch/sh64/boot/compressed/cache.c --- linux-2.4.21/arch/sh64/boot/compressed/cache.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/boot/compressed/cache.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,39 @@ +/* + * arch/shmedia/boot/compressed/cache.c -- simple cache management functions + * + * Code extracted from sh-ipl+g, sh-stub.c, which has the copyright: + * + * This is originally based on an m68k software stub written by Glenn + * Engel at HP, but has changed quite a bit. + * + * Modifications for the SH by Ben Lee and Steve Chamberlain + * +**************************************************************************** + + THIS SOFTWARE IS NOT COPYRIGHTED + + HP offers the following for use in the public domain. HP makes no + warranty with regard to the software or it's performance and the + user accepts the software "AS IS" with all faults. + + HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD + TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +****************************************************************************/ + +#define CACHE_ENABLE 0 +#define CACHE_DISABLE 1 + +int cache_control(unsigned int command) +{ + volatile unsigned int *p = (volatile unsigned int *) 0x80000000; + int i; + + for (i = 0; i < (32 * 1024); i += 32) { + (void *) *p; + p += (32 / sizeof (int)); + } + + return 0; +} diff -urN linux-2.4.21/arch/sh64/boot/compressed/head.S linux-2.4.22/arch/sh64/boot/compressed/head.S --- linux-2.4.21/arch/sh64/boot/compressed/head.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/boot/compressed/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,164 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/shmedia/boot/compressed/head.S + * + * Copied from + * arch/shmedia/kernel/head.S + * which carried the copyright: + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Modification for compressed loader: + * Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com) + */ + +#include +#include +#include +#include + +/* + * Fixed TLB entries to identity map the beginning of RAM + */ +#define MMUIR_TEXT_H 0x0000000000000003 | CONFIG_MEMORY_START + /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ +#define MMUIR_TEXT_L 0x000000000000009a | CONFIG_MEMORY_START + /* 512 Mb, Cacheable (Write-back), execute, Not User, Ph. Add. */ + +#define MMUDR_CACHED_H 0x0000000000000003 | CONFIG_MEMORY_START + /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ +#define MMUDR_CACHED_L 0x000000000000015a | CONFIG_MEMORY_START + /* 512 Mb, Cacheable (Write-back), read/write, Not User, Ph. Add. */ + +#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */ +#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */ + +#if 1 +#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* OCE + OCI + WB */ +#else +#define OCCR0_INIT_VAL OCCR0_OFF +#endif +#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */ + + .text + + .global startup +startup: + /* + * Prevent speculative fetch on device memory due to + * uninitialized target registers. + * This must be executed before the first branch. + */ + ptabs/u ZERO, t0 + ptabs/u ZERO, t1 + ptabs/u ZERO, t2 + ptabs/u ZERO, t3 + ptabs/u ZERO, t4 + ptabs/u ZERO, t5 + ptabs/u ZERO, t6 + ptabs/u ZERO, t7 + synci + + /* + * Set initial TLB entries for cached and uncached regions. + * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't ! + */ + /* Clear ITLBs */ + pta 1f, t1 + movi ITLB_FIXED, r21 + movi ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22 +1: putcfg r21, 0, ZERO /* Clear MMUIR[n].PTEH.V */ + addi r21, TLB_STEP, r21 + bne r21, r22, t1 + + /* Clear DTLBs */ + pta 1f, t1 + movi DTLB_FIXED, r21 + movi DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22 +1: putcfg r21, 0, ZERO /* Clear MMUDR[n].PTEH.V */ + addi r21, TLB_STEP, r21 + bne r21, r22, t1 + + /* Map one big (512Mb) page for ITLB */ + movi ITLB_FIXED, r21 + movi MMUIR_TEXT_L, r22 /* PTEL first */ + putcfg r21, 1, r22 /* Set MMUIR[0].PTEL */ + movi MMUIR_TEXT_H, r22 /* PTEH last */ + putcfg r21, 0, r22 /* Set MMUIR[0].PTEH */ + + /* Map one big CACHED (512Mb) page for DTLB */ + movi DTLB_FIXED, r21 + movi MMUDR_CACHED_L, r22 /* PTEL first */ + putcfg r21, 1, r22 /* Set MMUDR[0].PTEL */ + movi MMUDR_CACHED_H, r22 /* PTEH last */ + putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ + + /* ICache */ + movi ICCR_BASE, r21 + movi ICCR0_INIT_VAL, r22 + movi ICCR1_INIT_VAL, r23 + putcfg r21, ICCR_REG0, r22 + putcfg r21, ICCR_REG1, r23 + synci + + /* OCache */ + movi OCCR_BASE, r21 + movi OCCR0_INIT_VAL, r22 + movi OCCR1_INIT_VAL, r23 + putcfg r21, OCCR_REG0, r22 + putcfg r21, OCCR_REG1, r23 + synco + + /* + * Enable the MMU. + * From here-on code can be non-PIC. + */ + movi SR_HARMLESS | SR_ENABLE_MMU, r22 + putcon r22, SSR + movi 1f, r22 + putcon r22, SPC + synco + rte /* And now go into the hyperspace ... */ +1: /* ... that's the next instruction ! */ + + /* Set initial stack pointer */ + movi datalabel stack_start, r0 + ld.l r0, 0, r15 + + /* + * Clear bss + */ + pt 1f, tr1 + movi datalabel __bss_start, r22 + movi datalabel _end, r23 +1: st.l r22, 0, ZERO + addi r22, 4, r22 + bne r22, r23, tr1 + + /* + * Decompress the kernel. + */ + pt decompress_kernel, tr0 + blink tr0, r18 + + /* + * Disable the MMU. + */ + movi SR_HARMLESS, r22 + putcon r22, SSR + movi 1f, r22 + putcon r22, SPC + synco + rte /* And now go into the hyperspace ... */ +1: /* ... that's the next instruction ! */ + + /* Jump into the decompressed kernel */ + movi datalabel (CONFIG_MEMORY_START + 0x2000)+1, r19 + ptabs r19, tr0 + blink tr0, r18 + + /* Shouldn't return here, but just in case, loop forever */ + pt 1f, tr0 +1: blink tr0, ZERO diff -urN linux-2.4.21/arch/sh64/boot/compressed/install.sh linux-2.4.22/arch/sh64/boot/compressed/install.sh --- linux-2.4.21/arch/sh64/boot/compressed/install.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/boot/compressed/install.sh 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,56 @@ +#!/bin/sh +# +# arch/sh/boot/install.sh +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1995 by Linus Torvalds +# +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin +# Adapted from code in arch/i386/boot/install.sh by Russell King +# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy +# +# "make install" script for sh architecture +# +# Arguments: +# $1 - kernel version +# $2 - kernel image file +# $3 - kernel map file +# $4 - default install path (blank if root directory) +# + +# User may have a custom install script + +if [ -x /sbin/installkernel ]; then + exec /sbin/installkernel "$@" +fi + +if [ "$2" = "zImage" ]; then +# Compressed install + echo "Installing compressed kernel" + if [ -f $4/vmlinuz-$1 ]; then + mv $4/vmlinuz-$1 $4/vmlinuz.old + fi + + if [ -f $4/System.map-$1 ]; then + mv $4/System.map-$1 $4/System.old + fi + + cat $2 > $4/vmlinuz-$1 + cp $3 $4/System.map-$1 +else +# Normal install + echo "Installing normal kernel" + if [ -f $4/vmlinux-$1 ]; then + mv $4/vmlinux-$1 $4/vmlinux.old + fi + + if [ -f $4/System.map ]; then + mv $4/System.map $4/System.old + fi + + cat $2 > $4/vmlinux-$1 + cp $3 $4/System.map +fi diff -urN linux-2.4.21/arch/sh64/boot/compressed/misc.c linux-2.4.22/arch/sh64/boot/compressed/misc.c --- linux-2.4.21/arch/sh64/boot/compressed/misc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/boot/compressed/misc.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,251 @@ +/* + * arch/shmedia/boot/compressed/misc.c + * + * This is a collection of several routines from gzip-1.0.3 + * adapted for Linux. + * + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 + * + * Adapted for SHmedia from sh by Stuart Menefy, May 2002 + */ + +#include +#include + +/* cache.c */ +#define CACHE_ENABLE 0 +#define CACHE_DISABLE 1 +int cache_control(unsigned int command); + +/* + * gzip declarations + */ + +#define OF(args) args +#define STATIC static + +#undef memset +#undef memcpy +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ + +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond,msg) {if(!(cond)) 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 + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +extern char input_data[]; +extern int input_len; + +static long bytes_out = 0; +static uch *output_data; +static unsigned long output_ptr = 0; + +static void *malloc(int size); +static void free(void *where); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +static void puts(const char *); + +extern int _text; /* Defined in vmlinux.lds.S */ +extern int _end; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; + +#define HEAP_SIZE 0x10000 + +#include "../../../../lib/inflate.c" + +static void *malloc(int size) +{ + void *p; + + if (size < 0) + error("Malloc error\n"); + if (free_mem_ptr == 0) + error("Memory error\n"); + + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ + + p = (void *) free_mem_ptr; + free_mem_ptr += size; + + if (free_mem_ptr >= free_mem_end_ptr) + error("\nOut of memory\n"); + + return p; +} + +static void free(void *where) +{ /* Don't care */ +} + +static void gzip_mark(void **ptr) +{ + *ptr = (void *) free_mem_ptr; +} + +static void gzip_release(void **ptr) +{ + free_mem_ptr = (long) *ptr; +} + +void puts(const char *s) +{ +} + +void *memset(void *s, int c, size_t n) +{ + int i; + char *ss = (char *) s; + + for (i = 0; i < n; i++) + ss[i] = c; + return s; +} + +void *memcpy(void *__dest, __const void *__src, size_t __n) +{ + int i; + char *d = (char *) __dest, *s = (char *) __src; + + for (i = 0; i < __n; i++) + d[i] = s[i]; + return __dest; +} + +/* =========================================================================== + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +static int fill_inbuf(void) +{ + if (insize != 0) { + error("ran out of input data\n"); + } + + inbuf = input_data; + insize = input_len; + inptr = 1; + return inbuf[0]; +} + +/* =========================================================================== + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +static void flush_window(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, *out, ch; + + in = window; + out = &output_data[output_ptr]; + for (n = 0; n < outcnt; n++) { + ch = *out++ = *in++; + c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg) outcnt; + output_ptr += (ulg) outcnt; + outcnt = 0; + puts("."); +} + +static void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while (1) ; /* Halt */ +} + +#define STACK_SIZE (4096) +long __attribute__ ((aligned(8))) user_stack[STACK_SIZE]; +long *stack_start = &user_stack[STACK_SIZE]; + +void decompress_kernel(void) +{ + output_data = (uch *) (CONFIG_MEMORY_START + 0x2000); + free_mem_ptr = (unsigned long) &_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + + makecrc(); + puts("Uncompressing Linux... "); + cache_control(CACHE_ENABLE); + gunzip(); + puts("\n"); + +#if 0 + /* When booting from ROM may want to do something like this if the + * boot loader doesn't. + */ + + /* Set up the parameters and command line */ + { + volatile unsigned int *parambase = + (int *) (CONFIG_MEMORY_START + 0x1000); + + parambase[0] = 0x1; /* MOUNT_ROOT_RDONLY */ + parambase[1] = 0x0; /* RAMDISK_FLAGS */ + parambase[2] = 0x0200; /* ORIG_ROOT_DEV */ + parambase[3] = 0x0; /* LOADER_TYPE */ + parambase[4] = 0x0; /* INITRD_START */ + parambase[5] = 0x0; /* INITRD_SIZE */ + parambase[6] = 0; + + strcpy((char *) ((int) parambase + 0x100), + "console=ttySC0,38400"); + } +#endif + + puts("Ok, booting the kernel.\n"); + + cache_control(CACHE_DISABLE); +} diff -urN linux-2.4.21/arch/sh64/boot/compressed/vmlinux.lds.S linux-2.4.22/arch/sh64/boot/compressed/vmlinux.lds.S --- linux-2.4.21/arch/sh64/boot/compressed/vmlinux.lds.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/boot/compressed/vmlinux.lds.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,65 @@ +/* + * ld script to make compressed SuperH/shmedia Linux kernel+decompression + bootstrap + * Modified by Stuart Menefy from arch/sh/vmlinux.lds.S written by Niibe Yutaka + */ + +#include + +#ifdef CONFIG_LITTLE_ENDIAN +/* OUTPUT_FORMAT("elf32-sh64l-linux", "elf32-sh64l-linux", "elf32-sh64l-linux") */ +#define NOP 0x6ff0fff0 +#else +/* OUTPUT_FORMAT("elf32-sh64", "elf32-sh64", "elf32-sh64") */ +#define NOP 0xf0fff06f +#endif + +OUTPUT_FORMAT("elf32-sh64-linux") +OUTPUT_ARCH(sh) +ENTRY(_start) + +#define ALIGNED_GAP(section, align) (((ADDR(section)+SIZEOF(section)+(align)-1) & ~((align)-1))-ADDR(section)) +#define FOLLOWING(section, align) AT (LOADADDR(section) + ALIGNED_GAP(section,align)) + +SECTIONS +{ + _text = .; /* Text and read-only data */ + + .text : { + *(.text) + *(.text64) + *(.text..SHmedia32) + *(.fixup) + *(.gnu.warning) + } = NOP + . = ALIGN(4); + .rodata : { *(.rodata) } + + /* There is no 'real' reason for eight byte alignment, four would work + * as well, but gdb downloads much (*4) faster with this. + */ + . = ALIGN(8); + .image : { *(.image) } + . = ALIGN(4); + _etext = .; /* End of text section */ + + .data : /* Data */ + FOLLOWING(.image, 4) + { + _data = .; + *(.data) + } + _data_image = LOADADDR(.data);/* Address of data section in ROM */ + + _edata = .; /* End of data section */ + + .stack : { stack = .; _stack = .; } + + . = ALIGN(4); + __bss_start = .; /* BSS */ + .bss : { + *(.bss) + } + . = ALIGN(4); + _end = . ; +} diff -urN linux-2.4.21/arch/sh64/config.in linux-2.4.22/arch/sh64/config.in --- linux-2.4.21/arch/sh64/config.in 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,308 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/config-language.txt. +# +mainmenu_name "Linux/SH64 Kernel Configuration" + +define_bool CONFIG_SUPERH y + +define_bool CONFIG_UID16 y +define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n + +mainmenu_option next_comment +comment 'Code maturity level options' +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL +endmenu + +mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment +comment 'System type' +choice 'SuperH system type' \ + "Generic CONFIG_SH_GENERIC \ + Simulator CONFIG_SH_SIMULATOR \ + Cayman CONFIG_SH_CAYMAN \ + ST50-Harp CONFIG_SH_HARP" Simulator +endmenu + +mainmenu_option next_comment +comment 'Processor type and features' +comment 'Processor options' +choice 'Processor family' \ + "SH-5 CONFIG_CPU_SH5" SH-5 + +if [ "$CONFIG_CPU_SH5" = "y" ]; then + choice 'Processor type' \ + "SH5-101 CONFIG_CPU_SUBTYPE_SH5_101 \ + SH5-103 CONFIG_CPU_SUBTYPE_SH5_103" SH5-101 +fi + +choice 'Endianness' \ + "Little-Endian CONFIG_LITTLE_ENDIAN \ + Big-Endian CONFIG_BIG_ENDIAN" Little-Endian + +bool 'Flush floating point denorms to zero' CONFIG_SH64_FPU_DENORM_FLUSH +choice 'Page table levels' \ + "2 CONFIG_SH64_PGTABLE_2_LEVEL \ + 3 CONFIG_SH64_PGTABLE_3_LEVEL" 2 + +# Use 32-bit addressing for now. +# EMI based. +# P2 (UNCACHED) required to use identity mapping +# P1 (CACHED) assumes non-identity. + +# +# Memory options +# +comment 'Memory options' + +int 'Memory size (in MB)' CONFIG_MEMORY_SIZE_IN_MB 64 +hex 'Cached Area Offset' CONFIG_CACHED_MEMORY_OFFSET 20000000 +hex 'Uncached Area Offset' CONFIG_UNCACHED_MEMORY_OFFSET 00000000 +hex 'Physical memory start address' CONFIG_MEMORY_START 80000000 + +# +# Cache options +# +comment 'Cache options' +bool 'DCache Disabling' CONFIG_DCACHE_DISABLED + +if [ "$CONFIG_SH_SIMULATOR" != "y" -a \ + "$CONFIG_DCACHE_DISABLED" != "y" ]; then + choice 'DCache mode' \ + "Write-back CONFIG_DCACHE_WRITE_BACK \ + Write-through CONFIG_DCACHE_WRITE_THROUGH" Write-back +fi + +bool 'ICache Disabling' CONFIG_ICACHE_DISABLED + + +# +# CPU Subtype specific options (errata and such) +# +comment 'CPU Subtype specific options' +if [ "$CONFIG_CPU_SUBTYPE_SH5_101" = "y" ]; then + bool "Include workaround for SH5-101 cut2 silicon defect ID2815" CONFIG_SH64_ID2815_WORKAROUND +fi + +endmenu + +mainmenu_option next_comment +comment 'General setup' + +define_bool CONFIG_ISA n +define_bool CONFIG_SBUS n + +bool 'Networking support' CONFIG_NET + +bool 'PCI support' CONFIG_PCI +if [ "$CONFIG_SH_SIMULATOR" = "y" ]; then + define_bool CONFIG_PCI n + define_bool CONFIG_NET n +fi + +if [ "$CONFIG_SH_HARP" = "y" ]; then + define_bool CONFIG_PCI n + define_bool CONFIG_NET y + define_bool CONFIG_NET_PCI y +fi + +if [ "$CONFIG_PCI" = "y" ]; then + choice ' PCI access mode' \ + "BIOS CONFIG_PCI_GOBIOS \ + Direct CONFIG_PCI_GODIRECT \ + Any CONFIG_PCI_GOANY" Any + if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then + define_bool CONFIG_PCI_BIOS y + fi + if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then + define_bool CONFIG_PCI_DIRECT y + fi +fi + +source drivers/pci/Config.in + +# bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG +# +define_bool CONFIG_HOTPLUG n + +if [ "$CONFIG_HOTPLUG" = "y" ] ; then + source drivers/pcmcia/Config.in +else + define_bool CONFIG_PCMCIA n +fi + +bool 'System V IPC' CONFIG_SYSVIPC +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT +# bool 'Sysctl support' CONFIG_SYSCTL +define_bool CONFIG_SYSCTL y + +if [ "$CONFIG_PROC_FS" = "y" ]; then + choice 'Kernel core (/proc/kcore) format' \ + "ELF CONFIG_KCORE_ELF \ + A.OUT CONFIG_KCORE_AOUT" ELF +fi +tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC + +# source drivers/parport/Config.in + +endmenu + +# source drivers/mtd/Config.in + +source drivers/block/Config.in + +if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in +fi + +mainmenu_option next_comment +comment 'ATA/IDE/MFM/RLL support' + +tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE + +if [ "$CONFIG_IDE" != "n" ]; then + source drivers/ide/Config.in +else + define_bool CONFIG_BLK_DEV_IDE_MODES n + define_bool CONFIG_BLK_DEV_HD n +fi +endmenu + +mainmenu_option next_comment +comment 'SCSI support' + + tristate 'SCSI support' CONFIG_SCSI +##define_bool CONFIG_SCSI n + +if [ "$CONFIG_SCSI" != "n" ]; then + source drivers/scsi/Config.in +fi +endmenu + +# source drivers/ieee1394/Config.in + +if [ "$CONFIG_NET" = "y" ]; then + mainmenu_option next_comment + comment 'Network device support' + + bool 'Network device support' CONFIG_NETDEVICES + if [ "$CONFIG_NETDEVICES" = "y" ]; then + source drivers/net/Config.in + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then + source drivers/atm/Config.in + fi + fi + endmenu +fi + +# +# input before char - char/joystick depends on it. As does USB. +# +source drivers/input/Config.in + +mainmenu_option next_comment +comment 'Character devices' + +bool 'Virtual terminal' CONFIG_VT + +if [ "$CONFIG_VT" = "y" ]; then + bool ' Support for console on virtual terminal' CONFIG_VT_CONSOLE +fi + + +# insert for SCIF serial console support +tristate 'Serial (SCI, SCIF) support' CONFIG_SH_SCI +tristate 'Serial (8250, 16450, 16550 or compatible) support' CONFIG_SERIAL + +if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SH_SCI" = "y" ]; then + bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE +fi + + +comment 'Unix 98 PTY support' +bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 +fi +if [ "$CONFIG_PARPORT" != "n" ]; then + dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT + if [ "$CONFIG_PRINTER" != "n" ]; then + bool ' Support for console on line printer' CONFIG_LP_CONSOLE + fi + dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT +fi + +bool 'Heartbeat LED' CONFIG_HEARTBEAT +dep_bool 'Support for HDSP-253 LED' CONFIG_HDSP253_LED $CONFIG_SH_CAYMAN +tristate 'DMA controller (DMAC) support' CONFIG_SH_DMA +bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE + +mainmenu_option next_comment +comment 'Watchdog Cards' +bool 'Watchdog Timer Support' CONFIG_WATCHDOG +if [ "$CONFIG_WATCHDOG" != "n" ]; then + bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT + dep_tristate ' SuperH Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH +fi +endmenu + +endmenu + +if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then + source drivers/char/pcmcia/Config.in +fi + +source fs/Config.in + +source drivers/media/Config.in + + +if [ "$CONFIG_VT" = "y" ]; then + mainmenu_option next_comment + comment 'Console drivers' + bool 'VGA text console' CONFIG_VGA_CONSOLE + bool 'Video mode selection support' CONFIG_VIDEO_SELECT + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE + source drivers/video/Config.in + fi + endmenu +fi + + +mainmenu_option next_comment +comment 'Sound' + +tristate 'Sound card support' CONFIG_SOUND +# define_bool CONFIG_SOUND n + +if [ "$CONFIG_SOUND" != "n" ]; then + source drivers/sound/Config.in +fi +endmenu + +source drivers/usb/Config.in + +mainmenu_option next_comment +comment 'Kernel hacking' + +bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ +bool 'GDB Stub kernel debug' CONFIG_DEBUG_KERNEL_WITH_GDB_STUB +bool "Debug: audit page tables on return from syscall/exception/interrupt" CONFIG_SH64_PAGE_TABLE_AUDIT +dep_bool "Debug: report TLB fill/purge activity through /proc/tlb" CONFIG_SH64_PROC_TLB $CONFIG_PROC_FS + +endmenu + +source lib/Config.in +source crypto/Config.in + diff -urN linux-2.4.21/arch/sh64/defconfig linux-2.4.22/arch/sh64/defconfig --- linux-2.4.21/arch/sh64/defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,491 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_SUPERH=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System type +# +# CONFIG_SH_GENERIC is not set +# CONFIG_SH_SIMULATOR is not set +CONFIG_SH_CAYMAN=y +# CONFIG_SH_HARP is not set + +# +# Processor type and features +# + +# +# Processor options +# +CONFIG_CPU_SH5=y +CONFIG_CPU_SUBTYPE_SH5_101=y +# CONFIG_CPU_SUBTYPE_SH5_103 is not set +CONFIG_LITTLE_ENDIAN=y +# CONFIG_BIG_ENDIAN is not set +# CONFIG_SH64_FPU_DENORM_FLUSH is not set +CONFIG_SH64_PGTABLE_2_LEVEL=y +# CONFIG_SH64_PGTABLE_3_LEVEL is not set + +# +# Memory options +# +CONFIG_MEMORY_SIZE_IN_MB=64 +CONFIG_CACHED_MEMORY_OFFSET=20000000 +CONFIG_UNCACHED_MEMORY_OFFSET=00000000 +CONFIG_MEMORY_START=80000000 + +# +# Cache options +# +# CONFIG_DCACHE_DISABLED is not set +CONFIG_DCACHE_WRITE_BACK=y +# CONFIG_DCACHE_WRITE_THROUGH is not set +# CONFIG_ICACHE_DISABLED is not set + +# +# CPU Subtype specific options +# +CONFIG_SH64_ID2815_WORKAROUND=y + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +CONFIG_NET=y +CONFIG_PCI=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +CONFIG_PCI_GOANY=y +CONFIG_PCI_BIOS=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# 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_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_STATS=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_STNIC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_TC35815 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 + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SH_SCI=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y + +# +# Unix 98 PTY support +# +# CONFIG_UNIX98_PTYS is not set +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_HEARTBEAT=y +CONFIG_HDSP253_LED=y +CONFIG_SH_DMA=y +# CONFIG_PSMOUSE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# 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=y +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +CONFIG_ROMFS_FS=y +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_VIDEO_SELECT is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +CONFIG_FB_KYRO=y +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_E1355 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +# CONFIG_FBCON_CFB8 is not set +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +CONFIG_FBCON_CFB32=y +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set +# CONFIG_SH64_PAGE_TABLE_AUDIT is not set +# CONFIG_SH64_PROC_TLB is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set diff -urN linux-2.4.21/arch/sh64/kernel/Makefile linux-2.4.22/arch/sh64/kernel/Makefile --- linux-2.4.21/arch/sh64/kernel/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,40 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2000, 2001 Paolo Alberelli +# +# Makefile for the Linux SH-5 kernel. +# +# 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). +# + +.S.o: + $(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o + +O_TARGET := kernel.o + +obj-y := process.o signal.o entry.o traps.o irq.o irq_intc.o \ + ptrace.o setup.o time.o sys_sh64.o semaphore.o sh_ksyms.o + +obj-$(CONFIG_HEARTBEAT) += led.o +obj-$(CONFIG_PCI) += pci-dma.o pcibios.o + +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_CPU_SH5) += pci_sh5.o +endif + +obj-$(CONFIG_SH_DMA) += dma.o + +export-objs := sh_ksyms.o + +ifndef CONFIG_NOFPU_SUPPORT +obj-y += fpu.o +endif + +all: $(O_TARGET) head.o init_task.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/sh64/kernel/dma.c linux-2.4.22/arch/sh64/kernel/dma.c --- linux-2.4.21/arch/sh64/kernel/dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,293 @@ +/* + * arch/sh64/kernel/dma.c + * + * DMA routines for the SH-5 DMAC. + * + * Copyright (C) 2003 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + unsigned long dev_addr; + unsigned long mem_addr; + + unsigned int mode; + unsigned int count; +} dma_info_t; + +static dma_info_t dma_info[MAX_DMA_CHANNELS]; +extern spinlock_t dma_spin_lock; + +/* arch/sh64/kernel/irq_intc.c */ +extern void make_intc_irq(unsigned int irq); + +/* DMAC Interrupts */ +#define DMA_IRQ_DMTE0 18 +#define DMA_IRQ_DERR 22 + +#define DMAC_COMMON_BASE (dmac_base + 0x08) +#define DMAC_SAR_BASE (dmac_base + 0x10) +#define DMAC_DAR_BASE (dmac_base + 0x18) +#define DMAC_COUNT_BASE (dmac_base + 0x20) +#define DMAC_CTRL_BASE (dmac_base + 0x28) +#define DMAC_STATUS_BASE (dmac_base + 0x30) + +#define DMAC_SAR(n) (DMAC_SAR_BASE + ((n) * 0x28)) +#define DMAC_DAR(n) (DMAC_DAR_BASE + ((n) * 0x28)) +#define DMAC_COUNT(n) (DMAC_COUNT_BASE + ((n) * 0x28)) +#define DMAC_CTRL(n) (DMAC_CTRL_BASE + ((n) * 0x28)) +#define DMAC_STATUS(n) (DMAC_STATUS_BASE + ((n) * 0x28)) + +/* DMAC.COMMON Bit Definitions */ +#define DMAC_COMMON_PR 0x00000001 /* Priority */ + /* Bits 1-2 Reserved */ +#define DMAC_COMMON_ME 0x00000008 /* Master Enable */ +#define DMAC_COMMON_NMI 0x00000010 /* NMI Flag */ + /* Bits 5-6 Reserved */ +#define DMAC_COMMON_ER 0x00000780 /* Error Response */ +#define DMAC_COMMON_AAE 0x00007800 /* Address Alignment Error */ + /* Bits 15-63 Reserved */ + +/* DMAC.SAR Bit Definitions */ +#define DMAC_SAR_ADDR 0xffffffff /* Source Address */ + +/* DMAC.DAR Bit Definitions */ +#define DMAC_DAR_ADDR 0xffffffff /* Destination Address */ + +/* DMAC.COUNT Bit Definitions */ +#define DMAC_COUNT_CNT 0xffffffff /* Transfer Count */ + +/* DMAC.CTRL Bit Definitions */ +#define DMAC_CTRL_TS 0x00000007 /* Transfer Size */ +#define DMAC_CTRL_SI 0x00000018 /* Source Increment */ +#define DMAC_CTRL_DI 0x00000060 /* Destination Increment */ +#define DMAC_CTRL_RS 0x00000780 /* Resource Select */ +#define DMAC_CTRL_IE 0x00000800 /* Interrupt Enable */ +#define DMAC_CTRL_TE 0x00001000 /* Transfer Enable */ + /* Bits 15-63 Reserved */ + +/* DMAC.STATUS Bit Definitions */ +#define DMAC_STATUS_TE 0x00000001 /* Transfer End */ +#define DMAC_STATUS_AAE 0x00000002 /* Address Alignment Error */ + /* Bits 2-63 Reserved */ + +static unsigned long dmac_base; + +void set_dma_count(unsigned int chan, unsigned int count); +void set_dma_addr(unsigned int chan, unsigned int addr); + +static void dma_mte(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int chan = irq - DMA_IRQ_DMTE0; + dma_info_t *info = dma_info + chan; + u64 status; + + if (info->mode & DMA_MODE_WRITE) { + sh64_out64(info->mem_addr & DMAC_SAR_ADDR, DMAC_SAR(chan)); + } else { + sh64_out64(info->mem_addr & DMAC_DAR_ADDR, DMAC_DAR(chan)); + } + + set_dma_count(chan, info->count); + + /* Clear the TE bit */ + status = sh64_in64(DMAC_STATUS(chan)); + status &= ~DMAC_STATUS_TE; + sh64_out64(status, DMAC_STATUS(chan)); +} + +static struct irqaction irq_dmte = { + .handler = dma_mte, + .flags = SA_INTERRUPT, + .name = "DMA MTE", +}; + +static void dma_err(int irq, void *dev_id, struct pt_regs *regs) +{ + u64 tmp; + u8 chan; + + printk(KERN_NOTICE "DMAC: Got a DMA Error!\n"); + + tmp = sh64_in64(DMAC_COMMON_BASE); + + /* Check for the type of error */ + if ((chan = tmp & DMAC_COMMON_AAE)) { + /* It's an address alignment error.. */ + printk(KERN_NOTICE "DMAC: Alignment error on channel %d, ", chan); + + printk(KERN_NOTICE "SAR: 0x%08llx, DAR: 0x%08llx, COUNT: %lld\n", + (sh64_in64(DMAC_SAR(chan)) & DMAC_SAR_ADDR), + (sh64_in64(DMAC_DAR(chan)) & DMAC_DAR_ADDR), + (sh64_in64(DMAC_COUNT(chan)) & DMAC_COUNT_CNT)); + + } else if ((chan = tmp & DMAC_COMMON_ER)) { + /* Something else went wrong.. */ + printk(KERN_NOTICE "DMAC: Error on channel %d\n", chan); + } + + /* Reset the ME bit to clear the interrupt */ + tmp |= DMAC_COMMON_ME; + sh64_out64(tmp, DMAC_COMMON_BASE); +} + +static struct irqaction irq_derr = { + .handler = dma_err, + .flags = SA_INTERRUPT, + .name = "DMA Error", +}; + +static inline unsigned long calc_xmit_shift(unsigned int chan) +{ + return sh64_in64(DMAC_CTRL(chan)) & 0x03; +} + +void setup_dma(unsigned int chan, dma_info_t *info) +{ + unsigned int irq = DMA_IRQ_DMTE0 + chan; + dma_info_t *dma = dma_info + chan; + + make_intc_irq(irq); + setup_irq(irq, &irq_dmte); + dma = info; +} + +void enable_dma(unsigned int chan) +{ + u64 ctrl; + + ctrl = sh64_in64(DMAC_CTRL(chan)); + ctrl |= DMAC_CTRL_TE; + sh64_out64(ctrl, DMAC_CTRL(chan)); +} + +void disable_dma(unsigned int chan) +{ + u64 ctrl; + + ctrl = sh64_in64(DMAC_CTRL(chan)); + ctrl &= ~DMAC_CTRL_TE; + sh64_out64(ctrl, DMAC_CTRL(chan)); +} + +void set_dma_mode(unsigned int chan, char mode) +{ + dma_info_t *info = dma_info + chan; + + info->mode = mode; + + set_dma_addr(chan, info->mem_addr); + set_dma_count(chan, info->count); +} + +void set_dma_addr(unsigned int chan, unsigned int addr) +{ + dma_info_t *info = dma_info + chan; + unsigned long sar, dar; + + info->mem_addr = addr; + sar = (info->mode & DMA_MODE_WRITE) ? info->mem_addr : info->dev_addr; + dar = (info->mode & DMA_MODE_WRITE) ? info->dev_addr : info->mem_addr; + + sh64_out64(sar & DMAC_SAR_ADDR, DMAC_SAR(chan)); + sh64_out64(dar & DMAC_SAR_ADDR, DMAC_DAR(chan)); +} + +void set_dma_count(unsigned int chan, unsigned int count) +{ + dma_info_t *info = dma_info + chan; + u64 tmp; + + info->count = count; + + tmp = (info->count >> calc_xmit_shift(chan)) & DMAC_COUNT_CNT; + + sh64_out64(tmp, DMAC_COUNT(chan)); +} + +unsigned long claim_dma_lock(void) +{ + unsigned long flags; + + spin_lock_irqsave(&dma_spin_lock, flags); + + return flags; +} + +void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +int get_dma_residue(unsigned int chan) +{ + return sh64_in64(DMAC_COUNT(chan) << calc_xmit_shift(chan)); +} + +int __init init_dma(void) +{ + struct vcr_info vcr; + u64 tmp; + + /* Remap the DMAC */ + dmac_base = onchip_remap(PHYS_DMAC_BLOCK, 1024, "DMAC"); + if (!dmac_base) { + printk(KERN_ERR "Unable to remap DMAC\n"); + return -ENOMEM; + } + + /* Report DMAC.VCR Info */ + vcr = sh64_get_vcr_info(dmac_base); + printk("DMAC: Module ID: 0x%04x, Module version: 0x%04x\n", + vcr.mod_id, vcr.mod_vers); + + /* Set the ME bit */ + tmp = sh64_in64(DMAC_COMMON_BASE); + tmp |= DMAC_COMMON_ME; + sh64_out64(tmp, DMAC_COMMON_BASE); + + /* Enable the DMAC Error Interrupt */ + make_intc_irq(DMA_IRQ_DERR); + setup_irq(DMA_IRQ_DERR, &irq_derr); + + return 0; +} + +static void __exit exit_dma(void) +{ + onchip_unmap(dmac_base); + free_irq(DMA_IRQ_DERR, 0); +} + +module_init(init_dma); +module_exit(exit_dma); + +MODULE_AUTHOR("Paul Mundt"); +MODULE_DESCRIPTION("DMA API for SH-5 DMAC"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(setup_dma); +EXPORT_SYMBOL(claim_dma_lock); +EXPORT_SYMBOL(release_dma_lock); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(get_dma_residue); + diff -urN linux-2.4.21/arch/sh64/kernel/entry.S linux-2.4.22/arch/sh64/kernel/entry.S --- linux-2.4.21/arch/sh64/kernel/entry.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,2111 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/entry.S + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + */ + +#include +#include +#include + +#include +#include +#include + +/* + * A few defines that ought to come from sched.h referring + * to the task structure. Byte offsets within the task + * structure and related flags. + */ +#define flags 4 +#define sigpending 8 +#define need_resched 20 +#define ptrace 24 + +#define PT_TRACESYS 0x00000002 + + +/* + * SR fields. + */ +#define SR_ASID_MASK 0x00ff0000 +#define SR_FD_MASK 0x00008000 +#define SR_SS 0x08000000 +#define SR_BL 0x10000000 +#define SR_MD 0x40000000 +#define SR_MMU 0x80000000 + +/* + * Event code. + */ +#define EVENT_INTERRUPT 0 +#define EVENT_FAULT_TLB 1 +#define EVENT_FAULT_NOT_TLB 2 +#define EVENT_DEBUG 3 + +/* EXPEVT values */ +#define RESET_CAUSE 0x20 +#define DEBUGSS_CAUSE 0x980 + +/* + * Frame layout. Quad index. + */ +#define FRAME_T(x) FRAME_TBASE+(x*8) +#define FRAME_R(x) FRAME_RBASE+(x*8) +#define FRAME_S(x) FRAME_SBASE+(x*8) +#define FSPC 0 +#define FSSR 1 +#define FSYSCALL_ID 2 + +/* Arrange the save frame to be a multiple of 32 bytes long */ +#define FRAME_SBASE 0 +#define FRAME_RBASE (FRAME_SBASE+(3*8)) /* SYSCALL_ID - SSR - SPC */ +#define FRAME_TBASE (FRAME_RBASE+(63*8)) /* r0 - r62 */ +#define FRAME_PBASE (FRAME_TBASE+(8*8)) /* t0 -t7 */ +#define FRAME_SIZE (FRAME_PBASE+(2*8)) /* pad0-pad1 */ + +#define FP_FRAME_SIZE FP_FRAME_BASE+(33*8) /* dr0 - dr31 + fpscr */ +#define FP_FRAME_BASE 0 + +#define SAVED_R2 0*8 +#define SAVED_R3 1*8 +#define SAVED_R4 2*8 +#define SAVED_R5 3*8 +#define SAVED_R18 4*8 +#define SAVED_R6 5*8 +#define SAVED_T0 6*8 + +/* These are the registers saved in the TLB path that aren't saved in the first + level of the normal one. */ +#define TLB_SAVED_R25 7*8 +#define TLB_SAVED_T1 8*8 +#define TLB_SAVED_T2 9*8 +#define TLB_SAVED_T3 10*8 +#define TLB_SAVED_T4 11*8 +/* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing + breakage otherwise. */ +#define TLB_SAVED_R0 12*8 +#define TLB_SAVED_R1 13*8 + +#define STI() \ + getcon SR, r6; \ + andi r6, ~0xf0, r6; \ + putcon r6, SR; + + .section .data, "aw" + +#define FAST_TLBMISS_STACK_CACHELINES 4 +#define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES) + +/* Register back-up area for all exceptions */ + .balign 32 + /* Allow for 16 quadwords to be pushed by fast tlbmiss handling + * register saves etc. */ + .fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0 +/* This is 32 byte aligned by construction */ +/* Register back-up area for all exceptions */ +reg_save_area: + .quad 0 + .quad 0 + .quad 0 + .quad 0 + + .quad 0 + .quad 0 + .quad 0 + .quad 0 + + .quad 0 + .quad 0 + .quad 0 + .quad 0 + + .quad 0 + .quad 0 + +/* Save area for RESVEC exceptions. We cannot use reg_save_area because of + * reentrancy. Note this area may be accessed via physical address. + * Align so this fits a whole single cache line, for ease of purging. + */ + .balign 32,0,32 +resvec_save_area: + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .balign 32,0,32 + +/* Jump table of 3rd level handlers */ +trap_jtable: + .long do_exception_error /* 0x000 */ + .long do_exception_error /* 0x020 */ + .long tlb_miss_load /* 0x040 */ + .long tlb_miss_store /* 0x060 */ + .long do_exception_error /* 0x080 */ + .long tlb_miss_load /* 0x0A0 */ + .long tlb_miss_store /* 0x0C0 */ + .long do_address_error_load /* 0x0E0 */ + .long do_address_error_store /* 0x100 */ +#ifndef CONFIG_NOFPU_SUPPORT + .long do_fpu_error /* 0x120 */ +#else + .long do_exception_error /* 0x120 */ +#endif + .long do_exception_error /* 0x140 */ + .long system_call /* 0x160 */ + .long do_reserved_inst /* 0x180 */ + .long do_illegal_slot_inst /* 0x1A0 */ + .long do_NMI /* 0x1C0 */ + .long do_exception_error /* 0x1E0 */ + .rept 15 + .long do_IRQ /* 0x200 - 0x3C0 */ + .endr + .long do_exception_error /* 0x3E0 */ + .rept 32 + .long do_IRQ /* 0x400 - 0x7E0 */ + .endr + .long fpu_error_or_IRQA /* 0x800 */ + .long fpu_error_or_IRQB /* 0x820 */ + .long do_IRQ /* 0x840 */ + .long do_IRQ /* 0x860 */ + .rept 6 + .long do_exception_error /* 0x880 - 0x920 */ + .endr + .long do_software_break_point /* 0x940 */ + .long do_exception_error /* 0x960 */ + .long do_single_step /* 0x980 */ + + .rept 3 + .long do_exception_error /* 0x9A0 - 0x9E0 */ + .endr + .long do_IRQ /* 0xA00 */ + .long do_IRQ /* 0xA20 */ + .long itlb_miss_or_IRQ /* 0xA40 */ + .long do_IRQ /* 0xA60 */ + .long do_IRQ /* 0xA80 */ + .long itlb_miss_or_IRQ /* 0xAA0 */ + .long do_exception_error /* 0xAC0 */ + .long do_address_error_exec /* 0xAE0 */ + .rept 8 + .long do_exception_error /* 0xB00 - 0xBE0 */ + .endr + .rept 18 + .long do_IRQ /* 0xC00 - 0xE20 */ + .endr + + +/* System calls jump table */ + +.globl sys_call_table +sys_call_table: + .long sys_ni_syscall /* 0 - old "setup()" system call */ + .long sys_exit + .long sys_fork + .long sys_read + .long sys_write + .long sys_open /* 5 */ + .long sys_close + .long sys_waitpid + .long sys_creat + .long sys_link + .long sys_unlink /* 10 */ + .long sys_execve + .long sys_chdir + .long sys_time + .long sys_mknod + .long sys_chmod /* 15 */ + .long sys_lchown16 + .long sys_ni_syscall /* old break syscall holder */ + .long sys_stat + .long sys_lseek + .long sys_getpid /* 20 */ + .long sys_mount + .long sys_oldumount + .long sys_setuid16 + .long sys_getuid16 + .long sys_stime /* 25 */ + .long sys_ptrace + .long sys_alarm + .long sys_fstat + .long sys_pause + .long sys_utime /* 30 */ + .long sys_ni_syscall /* old stty syscall holder */ + .long sys_ni_syscall /* old gtty syscall holder */ + .long sys_access + .long sys_nice + .long sys_ni_syscall /* 35 */ + /* old ftime syscall holder */ + .long sys_sync + .long sys_kill + .long sys_rename + .long sys_mkdir + .long sys_rmdir /* 40 */ + .long sys_dup + .long sys_pipe + .long sys_times + .long sys_ni_syscall /* old prof syscall holder */ + .long sys_brk /* 45 */ + .long sys_setgid16 + .long sys_getgid16 + .long sys_signal + .long sys_geteuid16 + .long sys_getegid16 /* 50 */ + .long sys_acct + .long sys_umount /* recycled never used phys( */ + .long sys_ni_syscall /* old lock syscall holder */ + .long sys_ioctl + .long sys_fcntl /* 55 */ + .long sys_ni_syscall /* old mpx syscall holder */ + .long sys_setpgid + .long sys_ni_syscall /* old ulimit syscall holder */ + .long sys_ni_syscall /* sys_olduname */ + .long sys_umask /* 60 */ + .long sys_chroot + .long sys_ustat + .long sys_dup2 + .long sys_getppid + .long sys_getpgrp /* 65 */ + .long sys_setsid + .long sys_sigaction + .long sys_sgetmask + .long sys_ssetmask + .long sys_setreuid16 /* 70 */ + .long sys_setregid16 + .long sys_sigsuspend + .long sys_sigpending + .long sys_sethostname + .long sys_setrlimit /* 75 */ + .long sys_old_getrlimit + .long sys_getrusage + .long sys_gettimeofday + .long sys_settimeofday + .long sys_getgroups16 /* 80 */ + .long sys_setgroups16 + .long sys_ni_syscall /* sys_oldselect */ + .long sys_symlink + .long sys_lstat + .long sys_readlink /* 85 */ + .long sys_uselib + .long sys_swapon + .long sys_reboot + .long old_readdir + .long old_mmap /* 90 */ + .long sys_munmap + .long sys_truncate + .long sys_ftruncate + .long sys_fchmod + .long sys_fchown16 /* 95 */ + .long sys_getpriority + .long sys_setpriority + .long sys_ni_syscall /* old profil syscall holder */ + .long sys_statfs + .long sys_fstatfs /* 100 */ + .long sys_ni_syscall /* ioperm */ + .long sys_socketcall /* Obsolete implementation of socket syscall */ + .long sys_syslog + .long sys_setitimer + .long sys_getitimer /* 105 */ + .long sys_newstat + .long sys_newlstat + .long sys_newfstat + .long sys_uname + .long sys_ni_syscall /* 110 */ /* iopl */ + .long sys_vhangup + .long sys_ni_syscall /* idle */ + .long sys_ni_syscall /* vm86old */ + .long sys_wait4 + .long sys_swapoff /* 115 */ + .long sys_sysinfo + .long sys_ipc /* Obsolete ipc syscall implementation */ + .long sys_fsync + .long sys_sigreturn + .long sys_clone /* 120 */ + .long sys_setdomainname + .long sys_newuname + .long sys_ni_syscall /* sys_modify_ldt */ + .long sys_adjtimex + .long sys_mprotect /* 125 */ + .long sys_sigprocmask + .long sys_create_module + .long sys_init_module + .long sys_delete_module + .long sys_get_kernel_syms /* 130 */ + .long sys_quotactl + .long sys_getpgid + .long sys_fchdir + .long sys_bdflush + .long sys_sysfs /* 135 */ + .long sys_personality + .long sys_ni_syscall /* for afs_syscall */ + .long sys_setfsuid16 + .long sys_setfsgid16 + .long sys_llseek /* 140 */ + .long sys_getdents + .long sys_select + .long sys_flock + .long sys_msync + .long sys_readv /* 145 */ + .long sys_writev + .long sys_getsid + .long sys_fdatasync + .long sys_sysctl + .long sys_mlock /* 150 */ + .long sys_munlock + .long sys_mlockall + .long sys_munlockall + .long sys_sched_setparam + .long sys_sched_getparam /* 155 */ + .long sys_sched_setscheduler + .long sys_sched_getscheduler + .long sys_sched_yield + .long sys_sched_get_priority_max + .long sys_sched_get_priority_min /* 160 */ + .long sys_sched_rr_get_interval + .long sys_nanosleep + .long sys_mremap + .long sys_setresuid16 + .long sys_getresuid16 /* 165 */ + .long sys_ni_syscall /* vm86 */ + .long sys_query_module + .long sys_poll + .long sys_nfsservctl + .long sys_setresgid16 /* 170 */ + .long sys_getresgid16 + .long sys_prctl + .long sys_rt_sigreturn + .long sys_rt_sigaction + .long sys_rt_sigprocmask /* 175 */ + .long sys_rt_sigpending + .long sys_rt_sigtimedwait + .long sys_rt_sigqueueinfo + .long sys_rt_sigsuspend + .long sys_pread /* 180 */ + .long sys_pwrite + .long sys_chown16 + .long sys_getcwd + .long sys_capget + .long sys_capset /* 185 */ + .long sys_sigaltstack + .long sys_sendfile + .long sys_ni_syscall /* streams1 */ + .long sys_ni_syscall /* streams2 */ + .long sys_vfork /* 190 */ + .long sys_getrlimit + .long sys_mmap2 + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ + .long sys_lstat64 + .long sys_fstat64 + .long sys_lchown + .long sys_getuid + .long sys_getgid /* 200 */ + .long sys_geteuid + .long sys_getegid + .long sys_setreuid + .long sys_setregid + .long sys_getgroups /* 205 */ + .long sys_setgroups + .long sys_fchown + .long sys_setresuid + .long sys_getresuid + .long sys_setresgid /* 210 */ + .long sys_getresgid + .long sys_chown + .long sys_setuid + .long sys_setgid + .long sys_setfsuid /* 215 */ + .long sys_setfsgid + .long sys_pivot_root + .long sys_mincore + .long sys_madvise + .long sys_socket /* 220 */ + .long sys_bind + .long sys_connect + .long sys_listen + .long sys_accept + .long sys_getsockname /* 225 */ + .long sys_getpeername + .long sys_socketpair + .long sys_send + .long sys_sendto + .long sys_recv /* 230*/ + .long sys_recvfrom + .long sys_shutdown + .long sys_setsockopt + .long sys_getsockopt + .long sys_sendmsg /* 235 */ + .long sys_recvmsg + .long sys_semop /* New ipc syscall implementation */ + .long sys_semget + .long sys_semctl + .long sys_msgsnd /* 240 */ + .long sys_msgrcv + .long sys_msgget + .long sys_msgctl + .long sys_shmatcall + .long sys_shmdt /* 245 */ + .long sys_shmget + .long sys_shmctl + + /* + * NOTE!! This doesn't have to be exact - we just have + * to make sure we have _enough_ of the "sys_ni_syscall" + * entries. Don't panic if you notice that this hasn't + * been shrunk every time we add a new system call. + */ + .rept NR_syscalls-247 + .long sys_ni_syscall + .endr + + .section .text64, "ax" + +/* + * --- Exception/Interrupt/Event Handling Section + */ + +/* + * VBR and RESVEC blocks. + * + * First level handler for VBR-based exceptions. + * + * To avoid waste of space, align to the maximum text block size. + * This is assumed to be at most 128 bytes or 32 instructions. + * DO NOT EXCEED 32 instructions on the first level handlers ! + * + * Also note that RESVEC is contained within the VBR block + * where the room left (1KB - TEXT_SIZE) allows placing + * the RESVEC block (at most 512B + TEXT_SIZE). + * + * So first (and only) level handler for RESVEC-based exceptions. + * + * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss + * and interrupt) we are a lot tight with register space until + * saving onto the stack frame, which is done in handle_exception(). + * + */ + +#define TEXT_SIZE 128 +#define BLOCK_SIZE 1664 /* Dynamic check, 13*128 */ + + .balign TEXT_SIZE +LVBR_block: + .space 256, 0 /* Power-on class handler, */ + /* not required here */ +not_a_tlb_miss: + /* Save original stack pointer into KCR1 */ + putcon SP, KCR1 + + /* Save other original registers into reg_save_area */ + _loada reg_save_area, SP + st.q SP, SAVED_R2, r2 + st.q SP, SAVED_R3, r3 + st.q SP, SAVED_R4, r4 + st.q SP, SAVED_R5, r5 + st.q SP, SAVED_R6, r6 + st.q SP, SAVED_R18, r18 + gettr t0, r3 + st.q SP, SAVED_T0, r3 + +#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT + /* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */ + movi 0x100, r3 + putcon r3, dcr +#endif + + /* Set args for Non-debug, Not a TLB miss class handler */ + getcon EXPEVT, r2 + _loada ret_from_exception, r3 + ori r3, 1, r3 + movi EVENT_FAULT_NOT_TLB, r4 + or SP, ZERO, r5 + getcon KCR1, SP + _ptar handle_exception, t0 + blink t0, ZERO + + /* + * Instead of the natural .balign 1024 place RESVEC here + * respecting the final 1KB alignment. + */ + .balign TEXT_SIZE + /* + * Instead of '.space 1024-TEXT_SIZE' place the RESVEC + * block making sure the final alignment is correct. + */ +LRESVEC_block: + /* Panic handler. Called with MMU off. Possible causes/actions: + * - Reset: Jump to program start. + * - Single Step: Turn off Single Step & return. + * - Others: Call panic handler, passing PC as arg. + * (this may need to be extended...) + */ +reset_or_panic: + putcon SP, DCR + /* First save r0-1 and tr0, as we need to use these */ + _loada resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP + st.q SP, 0, r0 + st.q SP, 8, r1 + gettr t0, r0 + st.q SP, 32, r0 + + /* Check cause */ + getcon EXPEVT, r0 + movi RESET_CAUSE, r1 + sub r1, r0, r1 /* r1=0 if reset */ + _loada _stext-CONFIG_CACHED_MEMORY_OFFSET, r0 + ori r0, 1, r0 + ptabs r0, t0 + beqi r1, 0, t0 /* Jump to start address if reset */ + + getcon EXPEVT, r0 + movi DEBUGSS_CAUSE, r1 + sub r1, r0, r1 /* r1=0 if single step */ + _ptar single_step_panic, t0 + beqi r1, 0, t0 /* jump if single step */ + + /* If we get here, we have an unknown panic. Just call the panic + * handler, passing saved PC. We never expect to return, so we can + * use any regs now. */ + getcon SPC,r2 + getcon SSR,r3 + getcon EXPEVT,r4 + /* Prepare to jump to C - physical address */ + _loada panic_handler-CONFIG_CACHED_MEMORY_OFFSET, r1 + ori r1, 1, r1 + ptabs r1, t0 + getcon DCR, SP + blink t0, ZERO + +single_step_panic: + /* We are in a handler with Single Step set. We need to resume the + * handler, by turning on MMU & turning off Single Step. */ + getcon SSR, r0 + movi SR_MMU, r1 + or r0, r1, r0 + movi ~SR_SS, r1 + and r0, r1, r0 + putcon r0, SSR + /* Restore EXPEVT, as the rte won't do this */ + getcon PEXPEVT, r0 + putcon r0, EXPEVT + /* Restore regs */ + ld.q SP, 32, r0 + ptabs r0, tr0 + ld.q SP, 0, r0 + ld.q SP, 8, r1 + getcon DCR, SP + synco + rte + + .balign TEXT_SIZE +debug_exception: + /* + * Single step/software_break_point first level handler. + * Called with MMU off, so the first thing we do is enable it + * by doing an rte with appropriate SSR. + */ + putcon SP, DCR + /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */ + _loada resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP + + /* With the MMU off, we are bypassing the cache, so purge any + * data that will be made stale by the following stores. + */ + ocbp SP, 0 + synco + + st.q SP, 0, r0 + st.q SP, 8, r1 + getcon SPC, r0 + st.q SP, 16, r0 + getcon SSR, r0 + st.q SP, 24, r0 + + /* Enable MMU, block exceptions, set priv mode, disable single step */ + movi SR_MMU | SR_BL | SR_MD, r1 + or r0, r1, r0 + movi ~SR_SS, r1 + and r0, r1, r0 + putcon r0, SSR + /* Force control to debug_exception_2 when rte is executed */ + _loada debug_exeception_2, r0 + ori r0, 1, r0 /* force SHmedia, just in case */ + putcon r0, SPC + getcon DCR, SP + synco + rte +debug_exeception_2: + /* Restore saved regs */ + putcon SP, KCR1 + _loada resvec_save_area, SP + ld.q SP, 24, r0 + putcon r0, SSR + ld.q SP, 16, r0 + putcon r0, SPC + ld.q SP, 0, r0 + ld.q SP, 8, r1 + + /* Save other original registers into reg_save_area */ + _loada reg_save_area, SP + st.q SP, SAVED_R2, r2 + st.q SP, SAVED_R3, r3 + st.q SP, SAVED_R4, r4 + st.q SP, SAVED_R5, r5 + st.q SP, SAVED_R6, r6 + st.q SP, SAVED_R18, r18 + gettr t0, r3 + st.q SP, SAVED_T0, r3 + + /* Set args for debug class handler */ + getcon EXPEVT, r2 + _loada ret_from_exception, r3 + ori r3, 1, r3 + movi EVENT_DEBUG, r4 + or SP, ZERO, r5 + getcon KCR1, SP + _ptar handle_exception, t0 + blink t0, ZERO + + .balign TEXT_SIZE +debug_interrupt: + /* + * Not supported. If we ever get here loop forever + * We may be MMUOFF or MMUON. Just use pic code. + */ + _ptar debug_interrupt, t0 + blink t0, ZERO + .balign TEXT_SIZE + +LRESVEC_block_end: /* Marker. Unused. */ +tlb_miss: + putcon SP, KCR1 + _loada reg_save_area, SP + /* SP is guaranteed 32-byte aligned. */ + st.q SP, TLB_SAVED_R0 , r0 + st.q SP, TLB_SAVED_R1 , r1 + st.q SP, SAVED_R2 , r2 + st.q SP, SAVED_R3 , r3 + st.q SP, SAVED_R4 , r4 + st.q SP, SAVED_R5 , r5 + st.q SP, SAVED_R6 , r6 + st.q SP, SAVED_R18, r18 + + /* Save R25 for safety; as/ld may want to use it to achieve the call to + * the code in mm/tlbmiss.c */ + st.q SP, TLB_SAVED_R25, r25 + gettr tr0, r2 + gettr tr1, r3 + gettr tr2, r4 + gettr tr3, r5 + gettr tr4, r18 + st.q SP, SAVED_T0 , r2 + st.q SP, TLB_SAVED_T1 , r3 + st.q SP, TLB_SAVED_T2 , r4 + st.q SP, TLB_SAVED_T3 , r5 + st.q SP, TLB_SAVED_T4 , r18 + + pt do_fast_page_fault, tr0 + getcon SSR, r2 + getcon EXPEVT, r3 + getcon TEA, r4 + shlri r2, 30, r2 + andi r2, 1, r2 /* r2 = SSR.MD */ + blink tr0, r18 + + pt fixup_to_invoke_general_handler, tr1 + + /* If the fast path handler fixed the fault, just drop through quickly + to the restore code right away to return to the excepting context. + */ + beqi/u r2, 0, tr1 + +fast_tlb_miss_restore: + ld.q SP, SAVED_T0, r2 + ld.q SP, TLB_SAVED_T1, r3 + ld.q SP, TLB_SAVED_T2, r4 + + ld.q SP, TLB_SAVED_T3, r5 + ld.q SP, TLB_SAVED_T4, r18 + + ptabs r2, tr0 + ptabs r3, tr1 + ptabs r4, tr2 + ptabs r5, tr3 + ptabs r18, tr4 + + ld.q SP, TLB_SAVED_R0, r0 + ld.q SP, TLB_SAVED_R1, r1 + ld.q SP, SAVED_R2, r2 + ld.q SP, SAVED_R3, r3 + ld.q SP, SAVED_R4, r4 + ld.q SP, SAVED_R5, r5 + ld.q SP, SAVED_R6, r6 + ld.q SP, SAVED_R18, r18 + ld.q SP, TLB_SAVED_R25, r25 + + getcon KCR1, SP + rte + nop /* for safety, in case the code is run on sh5-101 cut1.x */ + +fixup_to_invoke_general_handler: + + /* OK, new method. Restore stuff that's not expected to get saved into + the 'first-level' reg save area, then just fall through to setting + up the registers and calling the second-level handler. */ + + /* 2nd level expects r2,3,4,5,6,18,tr0 to be saved. So we must restore + r25,tr1-4 and save r6 to get into the right state. */ + + ld.q SP, TLB_SAVED_T1, r3 + ld.q SP, TLB_SAVED_T2, r4 + ld.q SP, TLB_SAVED_T3, r5 + ld.q SP, TLB_SAVED_T4, r18 + ld.q SP, TLB_SAVED_R25, r25 + + ld.q SP, TLB_SAVED_R0, r0 + ld.q SP, TLB_SAVED_R1, r1 + + ptabs/u r3, tr1 + ptabs/u r4, tr2 + ptabs/u r5, tr3 + ptabs/u r18, tr4 + +#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT + /* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */ + movi 0x400, r3 + putcon r3, dcr +#endif + + /* Set args for Non-debug, TLB miss class handler */ + getcon EXPEVT, r2 + _loada ret_from_exception, r3 + ori r3, 1, r3 + movi EVENT_FAULT_TLB, r4 + or SP, ZERO, r5 + getcon KCR1, SP + _ptar handle_exception, t0 + blink t0, ZERO + +/* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE + DOES END UP AT VBR+0x600 */ + nop + nop + nop + nop + nop + nop +#if 0 + .balign 256 + nop +#endif + .balign 256 + /* VBR + 0x600 */ + +interrupt: + /* Save original stack pointer into KCR1 */ + putcon SP, KCR1 + + /* Save other original registers into reg_save_area */ + _loada reg_save_area, SP + st.q SP, SAVED_R2, r2 + st.q SP, SAVED_R3, r3 + st.q SP, SAVED_R4, r4 + st.q SP, SAVED_R5, r5 + st.q SP, SAVED_R6, r6 + st.q SP, SAVED_R18, r18 + gettr t0, r3 + st.q SP, SAVED_T0, r3 + +#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT + /* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */ + movi 0x600, r3 + putcon r3, dcr +#endif + + /* Set args for interrupt class handler */ + getcon INTEVT, r2 + _loada ret_from_irq, r3 + ori r3, 1, r3 + movi EVENT_INTERRUPT, r4 + or SP, ZERO, r5 + getcon KCR1, SP + _ptar handle_exception, t0 + blink t0, ZERO + .balign TEXT_SIZE /* let's waste the bare minimum */ + +LVBR_block_end: /* Marker. Used for total checking */ + + +/* + * Second level handler for VBR-based exceptions. Pre-handler. + * In common to all stack-frame sensitive handlers. + * + * Inputs: + * (KCR0) Current [current task union] + * (KCR1) Original SP + * (r2) INTEVT/EXPEVT + * (r3) appropriate return address + * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug) + * (r5) Pointer to reg_save_area + * (SP) Original SP + * + * Available registers: + * (r6) + * (r18) + * (t0) + * + */ +handle_exception: + /* Common 2nd level handler. */ + + /* First thing we need an appropriate stack pointer */ + getcon SSR, r6 + shlri r6, 30, r6 + andi r6, 1, r6 + _ptar stack_ok, t0 + bne r6, ZERO, t0 /* Original stack pointer is fine */ + + /* Set stack pointer for user fault */ + getcon KCR0, SP + movi THREAD_SIZE, r6 /* Point to the end */ + add SP, r6, SP + +stack_ok: + /* Make some room for the BASIC frame. */ + movi -(FRAME_SIZE), r6 + add SP, r6, SP + +/* Could do this with no stalling if we had another spare register, but the + code below will be OK. */ + ld.q r5, SAVED_R2, r6 + ld.q r5, SAVED_R3, r18 + st.q SP, FRAME_R(2), r6 + ld.q r5, SAVED_R4, r6 + st.q SP, FRAME_R(3), r18 + ld.q r5, SAVED_R5, r18 + st.q SP, FRAME_R(4), r6 + ld.q r5, SAVED_R6, r6 + st.q SP, FRAME_R(5), r18 + ld.q r5, SAVED_R18, r18 + st.q SP, FRAME_R(6), r6 + ld.q r5, SAVED_T0, r6 + st.q SP, FRAME_R(18), r18 + st.q SP, FRAME_T(0), r6 + + /* Keep old SP around */ + getcon KCR1, r6 + + /* Save the rest of the general purpose registers */ + st.q SP, FRAME_R(0), r0 + st.q SP, FRAME_R(1), r1 + st.q SP, FRAME_R(7), r7 + st.q SP, FRAME_R(8), r8 + st.q SP, FRAME_R(9), r9 + st.q SP, FRAME_R(10), r10 + st.q SP, FRAME_R(11), r11 + st.q SP, FRAME_R(12), r12 + st.q SP, FRAME_R(13), r13 + st.q SP, FRAME_R(14), r14 + + /* SP is somewhere else */ + st.q SP, FRAME_R(15), r6 + + st.q SP, FRAME_R(16), r16 + st.q SP, FRAME_R(17), r17 + /* r18 is saved earlier. */ + st.q SP, FRAME_R(19), r19 + st.q SP, FRAME_R(20), r20 + st.q SP, FRAME_R(21), r21 + st.q SP, FRAME_R(22), r22 + st.q SP, FRAME_R(23), r23 + st.q SP, FRAME_R(24), r24 + st.q SP, FRAME_R(25), r25 + st.q SP, FRAME_R(26), r26 + st.q SP, FRAME_R(27), r27 + st.q SP, FRAME_R(28), r28 + st.q SP, FRAME_R(29), r29 + st.q SP, FRAME_R(30), r30 + st.q SP, FRAME_R(31), r31 + st.q SP, FRAME_R(32), r32 + st.q SP, FRAME_R(33), r33 + st.q SP, FRAME_R(34), r34 + st.q SP, FRAME_R(35), r35 + st.q SP, FRAME_R(36), r36 + st.q SP, FRAME_R(37), r37 + st.q SP, FRAME_R(38), r38 + st.q SP, FRAME_R(39), r39 + st.q SP, FRAME_R(40), r40 + st.q SP, FRAME_R(41), r41 + st.q SP, FRAME_R(42), r42 + st.q SP, FRAME_R(43), r43 + st.q SP, FRAME_R(44), r44 + st.q SP, FRAME_R(45), r45 + st.q SP, FRAME_R(46), r46 + st.q SP, FRAME_R(47), r47 + st.q SP, FRAME_R(48), r48 + st.q SP, FRAME_R(49), r49 + st.q SP, FRAME_R(50), r50 + st.q SP, FRAME_R(51), r51 + st.q SP, FRAME_R(52), r52 + st.q SP, FRAME_R(53), r53 + st.q SP, FRAME_R(54), r54 + st.q SP, FRAME_R(55), r55 + st.q SP, FRAME_R(56), r56 + st.q SP, FRAME_R(57), r57 + st.q SP, FRAME_R(58), r58 + st.q SP, FRAME_R(59), r59 + st.q SP, FRAME_R(60), r60 + st.q SP, FRAME_R(61), r61 + st.q SP, FRAME_R(62), r62 + + /* + * Save the S* registers. + */ + getcon SSR, r61 + st.q SP, FRAME_S(FSSR), r61 + getcon SPC, r62 + st.q SP, FRAME_S(FSPC), r62 + movi -1, r62 /* Reset syscall_nr */ + st.q SP, FRAME_S(FSYSCALL_ID), r62 + + /* Save the rest of the target registers */ + gettr t1, r6 + st.q SP, FRAME_T(1), r6 + gettr t2, r6 + st.q SP, FRAME_T(2), r6 + gettr t3, r6 + st.q SP, FRAME_T(3), r6 + gettr t4, r6 + st.q SP, FRAME_T(4), r6 + gettr t5, r6 + st.q SP, FRAME_T(5), r6 + gettr t6, r6 + st.q SP, FRAME_T(6), r6 + gettr t7, r6 + st.q SP, FRAME_T(7), r6 + +/*#define POOR_MANS_STRACE 1*/ + +#ifdef POOR_MANS_STRACE + /* We've pushed all the registers now, so only r2-r4 hold anything + * useful. Move them into callee save registers */ + or r2, ZERO, r28 + or r3, ZERO, r29 + or r4, ZERO, r30 + + /* Preserve r2 as the event code */ + _loada evt_debug, r3 + ori r3, 1, r3 + ptabs r3, t0 + + /* or SP, ZERO, r5 */ + getcon TRA, r5 + blink t0, LINK + + or r28, ZERO, r2 + or r29, ZERO, r3 + or r30, ZERO, r4 +#endif + + + /* For syscall and debug race condition, get TRA now */ + getcon TRA, r5 + + /* We are in a safe position to turn SR.BL off, but set IMASK=0xf + * Also set FD, to catch FPU usage in the kernel. + * + * benedict.gaster@superh.com 29/07/2002 + * + * On all SH5-101 revisions it is unsafe to raise the IMASK and at the + * same time change BL from 1->0, as any pending interrupt of a level + * higher than he previous value of IMASK will leak through and be + * taken unexpectedly. + * + * To avoid this we raise the IMASK and then issue another PUTCON to + * enable interrupts. + */ + getcon SR, r6 + movi SR_IMASK | SR_FD, r7 + or r6, r7, r6 + putcon r6, SR + movi SR_UNBLOCK_EXC, r7 + and r6, r7, r6 + putcon r6, SR + + + /* Now call the appropriate 3rd level handler */ + or r3, ZERO, LINK + _loada trap_jtable, r3 + shlri r2, 3, r2 + ldx.l r2, r3, r3 + shlri r2, 2, r2 + ptabs r3, t0 + or SP, ZERO, r3 + blink t0, ZERO + +/* + * Second level handler for VBR-based exceptions. Post-handlers. + * + * Post-handlers for interrupts (ret_from_irq), exceptions + * (ret_from_exception) and common reentrance doors (restore_all + * to get back to the original context, ret_from_syscall loop to + * check kernel exiting). + * + * ret_with_reschedule and check_signals are an inner lables of + * the ret_from_syscall loop. + * + * In common to all stack-frame sensitive handlers. + * + * Inputs: + * (SP) struct pt_regs *, original register's frame pointer (basic) + * + */ +ret_from_irq: + ld.q SP, FRAME_S(FSSR), r6 + shlri r6, 30, r6 + andi r6, 1, r6 + _ptar restore_all, t0 + bne r6, ZERO, t0 /* no further checks */ + STI() + _ptar ret_with_reschedule, t0 + blink t0, ZERO /* Do not check softirqs */ + +ret_from_exception: + ld.q SP, FRAME_S(FSSR), r6 + shlri r6, 30, r6 + andi r6, 1, r6 + _ptar restore_all, t0 + bne r6, ZERO, t0 /* no further checks */ + + /* Check softirqs */ + + /* + * Fall-through: + * _ptar ret_from_syscall, t0 + * blink t0, ZERO + */ + +ret_from_syscall: + +ret_with_reschedule: + getcon KCR0, r6 + ld.l r6, need_resched, r7 + _ptar check_signals, t0 + beq r7, ZERO, t0 + + _ptar ret_from_syscall, t0 + gettr t0, LINK + _loada schedule, r6 + ptabs r6, t0 + blink t0, ZERO /* Call schedule(), return on top */ + +check_signals: + getcon KCR0, r6 + ld.l r6, sigpending, r7 + _ptar restore_all, t0 + beq r7, ZERO, t0 + + _loada do_signal, r6 + ptabs r6, t0 + or SP, ZERO, r2 + or ZERO, ZERO, r3 + blink t0, LINK /* Call do_signal(regs, 0), return here */ + +#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT + /* Check page tables before returning (with obvious performance penalty). */ + _loada audit_mm, r6 + ptabs r6, t0 + getcon expevt, r2 + getcon intevt, r3 + getcon tra, r4 + getcon dcr, r5 + blink t0, LINK +#endif + +restore_all: + /* Do prefetches */ + + ld.q SP, FRAME_T(0), r6 + ld.q SP, FRAME_T(1), r7 + ld.q SP, FRAME_T(2), r8 + ld.q SP, FRAME_T(3), r9 + ptabs r6, t0 + ptabs r7, t1 + ptabs r8, t2 + ptabs r9, t3 + ld.q SP, FRAME_T(4), r6 + ld.q SP, FRAME_T(5), r7 + ld.q SP, FRAME_T(6), r8 + ld.q SP, FRAME_T(7), r9 + ptabs r6, t4 + ptabs r7, t5 + ptabs r8, t6 + ptabs r9, t7 + + ld.q SP, FRAME_R(0), r0 + ld.q SP, FRAME_R(1), r1 + ld.q SP, FRAME_R(2), r2 + ld.q SP, FRAME_R(3), r3 + ld.q SP, FRAME_R(4), r4 + ld.q SP, FRAME_R(5), r5 + ld.q SP, FRAME_R(6), r6 + ld.q SP, FRAME_R(7), r7 + ld.q SP, FRAME_R(8), r8 + ld.q SP, FRAME_R(9), r9 + ld.q SP, FRAME_R(10), r10 + ld.q SP, FRAME_R(11), r11 + ld.q SP, FRAME_R(12), r12 + ld.q SP, FRAME_R(13), r13 + ld.q SP, FRAME_R(14), r14 + + ld.q SP, FRAME_R(16), r16 + ld.q SP, FRAME_R(17), r17 + ld.q SP, FRAME_R(18), r18 + ld.q SP, FRAME_R(19), r19 + ld.q SP, FRAME_R(20), r20 + ld.q SP, FRAME_R(21), r21 + ld.q SP, FRAME_R(22), r22 + ld.q SP, FRAME_R(23), r23 + ld.q SP, FRAME_R(24), r24 + ld.q SP, FRAME_R(25), r25 + ld.q SP, FRAME_R(26), r26 + ld.q SP, FRAME_R(27), r27 + ld.q SP, FRAME_R(28), r28 + ld.q SP, FRAME_R(29), r29 + ld.q SP, FRAME_R(30), r30 + ld.q SP, FRAME_R(31), r31 + ld.q SP, FRAME_R(32), r32 + ld.q SP, FRAME_R(33), r33 + ld.q SP, FRAME_R(34), r34 + ld.q SP, FRAME_R(35), r35 + ld.q SP, FRAME_R(36), r36 + ld.q SP, FRAME_R(37), r37 + ld.q SP, FRAME_R(38), r38 + ld.q SP, FRAME_R(39), r39 + ld.q SP, FRAME_R(40), r40 + ld.q SP, FRAME_R(41), r41 + ld.q SP, FRAME_R(42), r42 + ld.q SP, FRAME_R(43), r43 + ld.q SP, FRAME_R(44), r44 + ld.q SP, FRAME_R(45), r45 + ld.q SP, FRAME_R(46), r46 + ld.q SP, FRAME_R(47), r47 + ld.q SP, FRAME_R(48), r48 + ld.q SP, FRAME_R(49), r49 + ld.q SP, FRAME_R(50), r50 + ld.q SP, FRAME_R(51), r51 + ld.q SP, FRAME_R(52), r52 + ld.q SP, FRAME_R(53), r53 + ld.q SP, FRAME_R(54), r54 + ld.q SP, FRAME_R(55), r55 + ld.q SP, FRAME_R(56), r56 + ld.q SP, FRAME_R(57), r57 + ld.q SP, FRAME_R(58), r58 + + getcon SR, r59 + movi SR_BLOCK_EXC, r60 + or r59, r60, r59 + putcon r59, SR /* SR.BL = 1, keep nesting out */ + ld.q SP, FRAME_S(FSSR), r61 + ld.q SP, FRAME_S(FSPC), r62 + movi SR_ASID_MASK, r60 + and r59, r60, r59 + andc r61, r60, r61 /* Clear out older ASID */ + or r59, r61, r61 /* Retain current ASID */ + putcon r61, SSR + putcon r62, SPC + + /* Ignore FSYSCALL_ID */ + + ld.q SP, FRAME_R(59), r59 + ld.q SP, FRAME_R(60), r60 + ld.q SP, FRAME_R(61), r61 + ld.q SP, FRAME_R(62), r62 + + /* Last touch */ + ld.q SP, FRAME_R(15), SP + rte + nop + +/* + * Third level handlers for VBR-based exceptions. Adapting args to + * and/or deflecting to fourth level handlers. + * + * Fourth level handlers interface. + * Most are C-coded handlers directly pointed by the trap_jtable. + * (Third = Fourth level) + * Inputs: + * (r2) fault/interrupt code, entry number (e.g. NMI = 14, + * IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...) + * (r3) struct pt_regs *, original register's frame pointer + * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault) + * (r5) TRA control register (for syscall/debug benefit only) + * (LINK) return address + * (SP) = r3 + * + * Kernel TLB fault handlers will get a slightly different interface. + * (r2) struct pt_regs *, original register's frame pointer + * (r3) writeaccess, whether it's a store fault as opposed to load fault + * (r4) execaccess, whether it's a ITLB fault as opposed to DTLB fault + * (r5) Effective Address of fault + * (LINK) return address + * (SP) = r2 + * + * fpu_error_or_IRQ? is a helper to deflect to the right cause. + * + */ +tlb_miss_load: + or SP, ZERO, r2 + or ZERO, ZERO, r3 /* Read */ + or ZERO, ZERO, r4 /* Data */ + getcon TEA, r5 + _ptar call_do_page_fault, t0 + beq ZERO, ZERO, tr0 + +tlb_miss_store: + or SP, ZERO, r2 + movi 1, r3 /* Write */ + or ZERO, ZERO, r4 /* Data */ + getcon TEA, r5 + _ptar call_do_page_fault, t0 + beq ZERO, ZERO, tr0 + +itlb_miss_or_IRQ: + _ptar its_IRQ, t0 + beqi/u r4, EVENT_INTERRUPT, t0 + or SP, ZERO, r2 + or ZERO, ZERO, r3 /* Read */ + movi 1, r4 /* Text */ + getcon TEA, r5 + /* Fall through */ + +call_do_page_fault: + _loada do_page_fault, r6 + ptabs r6, t0 + blink t0, ZERO + +fpu_error_or_IRQA: + _ptar its_IRQ, t0 + beqi/l r4, EVENT_INTERRUPT, t0 +#ifndef CONFIG_NOFPU_SUPPORT + _loada do_fpu_state_restore, r6 +#else + _loada do_exception_error, r6 +#endif + ptabs r6, t0 + blink t0, ZERO + +fpu_error_or_IRQB: + _ptar its_IRQ, t0 + beqi/l r4, EVENT_INTERRUPT, t0 +#ifndef CONFIG_NOFPU_SUPPORT + _loada do_fpu_state_restore, r6 +#else + _loada do_exception_error, r6 +#endif + ptabs r6, t0 + blink t0, ZERO + +its_IRQ: + _loada do_IRQ, r6 + ptabs r6, t0 + blink t0, ZERO + +/* + * system_call/unknown_trap third level handler: + * + * Inputs: + * (r2) fault/interrupt code, entry number (TRAP = 11) + * (r3) struct pt_regs *, original register's frame pointer + * (r4) Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault) + * (r5) TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr) + * (SP) = r3 + * (LINK) return address: ret_from_exception + * (*r3) Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7) + * + * Outputs: + * (*r3) Syscall reply (Saved r2) + * (LINK) In case of syscall only it can be scrapped. + * Common second level post handler will be ret_from_syscall. + * Common (non-trace) exit point to that is syscall_ret (saving + * result to r2). Common bad exit point is syscall_bad (returning + * ENOSYS then saved to r2). + * + */ + +unknown_trap: + /* Unknown Trap or User Trace */ + _loada do_unknown_trapa, r6 + ptabs r6, t0 + ld.q r3, FRAME_R(9), r2 /* r2 = #arg << 16 | syscall # */ + andi r2, 0x1ff, r2 /* r2 = syscall # */ + blink t0, LINK + + _ptar syscall_ret, t0 + blink t0, ZERO + + /* New syscall implementation*/ +system_call: + _ptar unknown_trap, t0 + or r5, ZERO, r4 /* TRA (=r5) -> r4 */ + shlri r4, 20, r4 + bnei r4, 1, t0 /* unknown_trap if not 0x1yzzzz */ + + /* It's a system call */ + st.q r3, FRAME_S(FSYSCALL_ID), r5 /* ID (0x1yzzzz) -> stack */ + andi r5, 0x1ff, r5 /* syscall # -> r5 */ + + STI() + + _ptar syscall_allowed, t0 + movi NR_syscalls - 1, r4 /* Last valid */ + bgeu/l r4, r5, t0 + +syscall_bad: + /* Return ENOSYS ! */ + movi -(ENOSYS), r2 /* Fall-through */ +syscall_ret: + st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */ + +#ifdef POOR_MANS_STRACE + /* nothing useful in registers at this point */ + + _loada evt_debug2, r5 + ori r5, 1, r5 + ptabs r5, t0 + ld.q SP, FRAME_R(9), r2 + or SP, ZERO, r3 + blink t0, LINK +#endif + + ld.q SP, FRAME_S(FSPC), r2 + addi r2, 4, r2 /* Move PC, being pre-execution event */ + st.q SP, FRAME_S(FSPC), r2 + _ptar ret_from_syscall, t0 + blink t0, ZERO + + +/* A different return path for ret_from_fork, because we now need + * to call schedule_tail with the later kernels. Because prev is + * loaded into r2 by switch_to() means we can just call it straight away + */ + +.global ret_from_fork +ret_from_fork: + + _loada schedule_tail,r5 + ori r5, 1, r5 + ptabs r5, t0 + blink t0, LINK + +#ifdef POOR_MANS_STRACE + /* nothing useful in registers at this point */ + + _loada evt_debug2, r5 + ori r5, 1, r5 + ptabs r5, t0 + ld.q SP, FRAME_R(9), r2 + or SP, ZERO, r3 + blink t0, LINK +#endif + + ld.q SP, FRAME_S(FSPC), r2 + addi r2, 4, r2 /* Move PC, being pre-execution event */ + st.q SP, FRAME_S(FSPC), r2 + _ptar ret_from_syscall, t0 + blink t0, ZERO + + + +syscall_allowed: + /* Use LINK to deflect the exit point, default is syscall_ret */ + _ptar syscall_ret, t0 + gettr t0, LINK + _ptar syscall_notrace, t0 + + getcon KCR0, r2 + ld.l r2, ptrace, r4 + andi r4, PT_TRACESYS, r4 + beq/l r4, ZERO, t0 + + /* Trace it by calling syscall_trace before and after */ + _loada syscall_trace, r4 + ptabs r4, t0 + blink t0, LINK + /* Reload syscall number as r5 is trashed by syscall_trace */ + ld.q SP, FRAME_S(FSYSCALL_ID), r5 + andi r5, 0x1ff, r5 + + _ptar syscall_ret_trace, t0 + gettr t0, LINK + +syscall_notrace: + /* Now point to the appropriate 4th level syscall handler */ + _loada sys_call_table, r4 + shlli r5, 2, r5 + ldx.l r4, r5, r5 + ptabs r5, t0 + + /* Prepare original args */ + ld.q SP, FRAME_R(2), r2 + ld.q SP, FRAME_R(3), r3 + ld.q SP, FRAME_R(4), r4 + ld.q SP, FRAME_R(5), r5 + ld.q SP, FRAME_R(6), r6 + ld.q SP, FRAME_R(7), r7 + + /* And now the trick for those syscalls requiring regs * ! */ + or SP, ZERO, r8 + + /* Call it */ + blink t0, ZERO /* LINK is already properly set */ + +syscall_ret_trace: + /* We get back here only if under trace */ + st.q SP, FRAME_R(9), r2 /* Save return value */ + + /* ... usage of a pt relative (_ptar _syscall_trace) fails on CDC */ + _loada syscall_trace, LINK + ptabs LINK, t0 + blink t0, LINK + + /* This needs to be done after any syscall tracing */ + ld.q SP, FRAME_S(FSPC), r2 + addi r2, 4, r2 /* Move PC, being pre-execution event */ + st.q SP, FRAME_S(FSPC), r2 + + _ptar ret_from_syscall, t0 + blink t0, ZERO /* Resume normal return sequence */ + +/* + * --- Switch to running under a particular ASID and return the previous ASID value + * --- The caller is assumed to have done a cli before calling this. + * + * Input r2 : new ASID + * Output r2 : old ASID + */ + + .global switch_and_save_asid +switch_and_save_asid: + getcon sr, r0 + movi 255, r4 + shlli r4, 16, r4 /* r4 = mask to select ASID */ + and r0, r4, r3 /* r3 = shifted old ASID */ + andi r2, 255, r2 /* mask down new ASID */ + shlli r2, 16, r2 /* align new ASID against SR.ASID */ + andc r0, r4, r0 /* efface old ASID from SR */ + or r0, r2, r0 /* insert the new ASID */ + putcon r0, ssr + _loada 1f, r0 + putcon r0, spc + rte + nop +1: + ptabs r18, tr0 + shlri r3, 16, r2 /* r2 = old ASID */ + blink tr0, r63 + + .global route_to_panic_handler +route_to_panic_handler: + /* Switch to real mode, goto panic_handler, don't return. Useful for + last-chance debugging, e.g. if no output wants to go to the console. + */ + + _loada panic_handler - CONFIG_CACHED_MEMORY_OFFSET, r1 + ptabs r1, tr0 + pta 1f, tr1 + gettr tr1, r0 + putcon r0, spc + getcon sr, r0 + movi 1, r1 + shlli r1, 31, r1 + andc r0, r1, r0 + putcon r0, ssr + rte + nop +1: /* Now in real mode */ + blink tr0, r63 + nop + + .global peek_real_address_q +peek_real_address_q: + /* Two args: + r2 : real mode address to peek + r2(out) : result quadword + + This is provided as a cheapskate way of manipulating device + registers for debugging (to avoid the need to onchip_remap the debug + module, and to avoid the need to onchip_remap the watchpoint + controller in a way that identity maps sufficient bits to avoid the + SH5-101 cut2 silicon defect). + + This code is not performance critical + */ + + add.l r2, r63, r2 /* sign extend address */ + getcon sr, r0 /* r0 = saved original SR */ + movi 1, r1 + shlli r1, 28, r1 + or r0, r1, r1 /* r0 with block bit set */ + putcon r1, sr /* now in critical section */ + movi 1, r36 + shlli r36, 31, r36 + andc r1, r36, r1 /* turn sr.mmu off in real mode section */ + + putcon r1, ssr + _loada .peek0 - CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */ + _loada 1f, r37 /* virtual mode return addr */ + putcon r36, spc + + synco + rte + nop + +.peek0: /* come here in real mode, don't touch caches!! + still in critical section (sr.bl==1) */ + putcon r0, ssr + putcon r37, spc + /* Here's the actual peek. If the address is bad, all bets are now off + * what will happen (handlers invoked in real-mode = bad news) */ + ld.q r2, 0, r2 + synco + rte /* Back to virtual mode */ + nop + +1: + ptabs r18, tr0 + blink tr0, r63 + + .global poke_real_address_q +poke_real_address_q: + /* Two args: + r2 : real mode address to poke + r3 : quadword value to write. + + This is provided as a cheapskate way of manipulating device + registers for debugging (to avoid the need to onchip_remap the debug + module, and to avoid the need to onchip_remap the watchpoint + controller in a way that identity maps sufficient bits to avoid the + SH5-101 cut2 silicon defect). + + This code is not performance critical + */ + + add.l r2, r63, r2 /* sign extend address */ + getcon sr, r0 /* r0 = saved original SR */ + movi 1, r1 + shlli r1, 28, r1 + or r0, r1, r1 /* r0 with block bit set */ + putcon r1, sr /* now in critical section */ + movi 1, r36 + shlli r36, 31, r36 + andc r1, r36, r1 /* turn sr.mmu off in real mode section */ + + /* Bodge : force sr.watch high on return. Can't understand why else this + isn't happening. */ + movi 1, r38 + shlli r38, 26, r38 + or r38, r0, r0 + + putcon r1, ssr + _loada .poke0-CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */ + _loada 1f, r37 /* virtual mode return addr */ + putcon r36, spc + + synco + rte + nop + +.poke0: /* come here in real mode, don't touch caches!! + still in critical section (sr.bl==1) */ + putcon r0, ssr + putcon r37, spc + /* Here's the actual poke. If the address is bad, all bets are now off + * what will happen (handlers invoked in real-mode = bad news) */ + st.q r2, 0, r3 + synco + rte /* Back to virtual mode */ + nop + +1: + ptabs r18, tr0 + blink tr0, r63 + +/* + * --- User Access Handling Section + */ + +/* + * User Access support. It all moved to non inlined Assembler + * functions in here. + * + * __kernel_size_t __copy_user(void *__to, const void *__from, + * __kernel_size_t __n) + * + * Inputs: + * (r2) target address + * (r3) source address + * (r4) size in bytes + * + * Ouputs: + * (*r2) target data + * (r2) non-copied bytes + * + * If a fault occurs on the user pointer, bail out early and return the + * number of bytes not copied in r2. + * Strategy : for large blocks, call a real memcpy function which can + * move >1 byte at a time using unaligned ld/st instructions, and can + * manipulate the cache using prefetch + alloco to improve the speed + * further. If a fault occurs in that function, just revert to the + * byte-by-byte approach used for small blocks; this is rare so the + * performance hit for that case does not matter. + * + * For small blocks it's not worth the overhead of setting up and calling + * the memcpy routine; do the copy a byte at a time. + * + */ + .global __copy_user +__copy_user: + _ptar __copy_user_byte_by_byte, t1 + movi 16, r0 ! this value is a best guess, should tune it by benchmarking + bge/u r0, r4, t1 + _ptar copy_user_memcpy, t0 + addi r15, -32, r15 + /* Save arguments in case we have to fix-up unhandled page fault */ + st.q r15, 0, r2 + st.q r15, 8, r3 + st.q r15, 16, r4 + st.q r15, 24, r35 ! r35 is callee-save + /* Save LINK in a register to reduce RTS time later (otherwise + ld r15,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */ + ori LINK, 0, r35 + blink t0, LINK + + /* Copy completed normally if we get back here */ + ptabs r35, tr0 + ld.q r15, 24, r35 + /* don't restore r2-r4, pointless */ + /* set result=r2 to zero as the copy must have succeeded. */ + or r63, r63, r2 + addi r15, 32, r15 + blink tr0, r63 ! RTS + + .global __copy_user_fixup +__copy_user_fixup: + /* Restore stack frame */ + ori r35, 0, LINK + ld.q r15, 24, r35 + ld.q r15, 16, r4 + ld.q r15, 8, r3 + ld.q r15, 0, r2 + addi r15, 32, r15 + /* Fall through to original code, in the 'same' state we entered with */ + +/* The slow byte-by-byte method is used if the fast copy traps due to a bad + user address. In that rare case, the speed drop can be tolerated. */ +__copy_user_byte_by_byte: + _ptar ___copy_user_exit, t1 + _ptar ___copy_user1, t0 + beq/u r4, r63, t1 /* early exit for zero length copy */ + sub r2, r3, r0 + addi r0, -1, r0 + +___copy_user1: + ld.b r3, 0, r5 /* Fault address 1 */ + + /* Could rewrite this to use just 1 add, but the second comes 'free' + due to load latency */ + addi r3, 1, r3 + addi r4, -1, r4 /* No real fixup required */ +___copy_user2: + stx.b r3, r0, r5 /* Fault address 2 */ + bne r4, ZERO, t0 + +___copy_user_exit: + or r4, ZERO, r2 + ptabs LINK, t0 + blink t0, ZERO + +/* + * __kernel_size_t __clear_user(void *addr, __kernel_size_t size) + * + * Inputs: + * (r2) target address + * (r3) size in bytes + * + * Ouputs: + * (*r2) zero-ed target data + * (r2) non-zero-ed bytes + */ + .global __clear_user +__clear_user: + _ptar ___clear_user_exit, t1 + _ptar ___clear_user1, t0 + beq/u r3, r63, t1 + +___clear_user1: + st.b r2, 0, ZERO /* Fault address */ + addi r2, 1, r2 + addi r3, -1, r3 /* No real fixup required */ + bne r3, ZERO, t0 + +___clear_user_exit: + or r3, ZERO, r2 + ptabs LINK, t0 + blink t0, ZERO + + +/* + * int __strncpy_from_user(unsigned long __dest, unsigned long __src, + * int __count) + * + * Inputs: + * (r2) target address + * (r3) source address + * (r4) maximum size in bytes + * + * Ouputs: + * (*r2) copied data + * (r2) -EFAULT (in case of faulting) + * copied data (otherwise) + */ + .global __strncpy_from_user +__strncpy_from_user: + _ptar ___strncpy_from_user1, t0 + _ptar ___strncpy_from_user_done, t1 + or r4, ZERO, r5 /* r5 = original count */ + beq/u r4, r63, t1 /* early exit if r4==0 */ + movi -(EFAULT), r6 /* r6 = reply, no real fixup */ + or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */ + +___strncpy_from_user1: + ld.b r3, 0, r7 /* Fault address: only in reading */ + st.b r2, 0, r7 + addi r2, 1, r2 + addi r3, 1, r3 + beq/u ZERO, r7, t1 + addi r4, -1, r4 /* return real number of copied bytes */ + bne/l ZERO, r4, t0 + +___strncpy_from_user_done: + sub r5, r4, r6 /* If done, return copied */ + +___strncpy_from_user_exit: + or r6, ZERO, r2 + ptabs LINK, t0 + blink t0, ZERO + +/* + * extern long __strnlen_user(const char *__s, long __n) + * + * Inputs: + * (r2) source address + * (r3) source size in bytes + * + * Ouputs: + * (r2) -EFAULT (in case of faulting) + * string length (otherwise) + */ + .global __strnlen_user +__strnlen_user: + _ptar ___strnlen_user_set_reply, t0 + _ptar ___strnlen_user1, t1 + or ZERO, ZERO, r5 /* r5 = counter */ + movi -(EFAULT), r6 /* r6 = reply, no real fixup */ + or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */ + beq r3, ZERO, t0 + +___strnlen_user1: + ldx.b r2, r5, r7 /* Fault address: only in reading */ + addi r3, -1, r3 /* No real fixup */ + addi r5, 1, r5 + beq r3, ZERO, t0 + bne r7, ZERO, t1 +! The line below used to be active. This meant led to a junk byte lying between each pair +! of entries in the argv & envp structures in memory. Whilst the program saw the right data +! via the argv and envp arguments to main, it meant the 'flat' representation visible through +! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example. +! addi r5, 1, r5 /* Include '\0' */ + +___strnlen_user_set_reply: + or r5, ZERO, r6 /* If done, return counter */ + +___strnlen_user_exit: + or r6, ZERO, r2 + ptabs LINK, t0 + blink t0, ZERO + +/* + * extern long __get_user_asm_?(void *val, long addr) + * + * Inputs: + * (r2) dest address + * (r3) source address (in User Space) + * + * Ouputs: + * (r2) -EFAULT (faulting) + * 0 (not faulting) + */ + .global __get_user_asm_b +__get_user_asm_b: + or r2, ZERO, r4 + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___get_user_asm_b1: + ld.b r3, 0, r5 /* r5 = data */ + st.b r4, 0, r5 + or ZERO, ZERO, r2 + +___get_user_asm_b_exit: + ptabs LINK, t0 + blink t0, ZERO + + + .global __get_user_asm_w +__get_user_asm_w: + or r2, ZERO, r4 + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___get_user_asm_w1: + ld.w r3, 0, r5 /* r5 = data */ + st.w r4, 0, r5 + or ZERO, ZERO, r2 + +___get_user_asm_w_exit: + ptabs LINK, t0 + blink t0, ZERO + + + .global __get_user_asm_l +__get_user_asm_l: + or r2, ZERO, r4 + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___get_user_asm_l1: + ld.l r3, 0, r5 /* r5 = data */ + st.l r4, 0, r5 + or ZERO, ZERO, r2 + +___get_user_asm_l_exit: + ptabs LINK, t0 + blink t0, ZERO + + + .global __get_user_asm_q +__get_user_asm_q: + or r2, ZERO, r4 + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___get_user_asm_q1: + ld.q r3, 0, r5 /* r5 = data */ + st.q r4, 0, r5 + or ZERO, ZERO, r2 + +___get_user_asm_q_exit: + ptabs LINK, t0 + blink t0, ZERO + +/* + * extern long __put_user_asm_?(void *pval, long addr) + * + * Inputs: + * (r2) kernel pointer to value + * (r3) dest address (in User Space) + * + * Ouputs: + * (r2) -EFAULT (faulting) + * 0 (not faulting) + */ + .global __put_user_asm_b +__put_user_asm_b: + ld.b r2, 0, r4 /* r4 = data */ + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___put_user_asm_b1: + st.b r3, 0, r4 + or ZERO, ZERO, r2 + +___put_user_asm_b_exit: + ptabs LINK, t0 + blink t0, ZERO + + + .global __put_user_asm_w +__put_user_asm_w: + ld.w r2, 0, r4 /* r4 = data */ + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___put_user_asm_w1: + st.w r3, 0, r4 + or ZERO, ZERO, r2 + +___put_user_asm_w_exit: + ptabs LINK, t0 + blink t0, ZERO + + + .global __put_user_asm_l +__put_user_asm_l: + ld.l r2, 0, r4 /* r4 = data */ + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___put_user_asm_l1: + st.l r3, 0, r4 + or ZERO, ZERO, r2 + +___put_user_asm_l_exit: + ptabs LINK, t0 + blink t0, ZERO + + + .global __put_user_asm_q +__put_user_asm_q: + ld.q r2, 0, r4 /* r4 = data */ + movi -(EFAULT), r2 /* r2 = reply, no real fixup */ + +___put_user_asm_q1: + st.q r3, 0, r4 + or ZERO, ZERO, r2 + +___put_user_asm_q_exit: + ptabs LINK, t0 + blink t0, ZERO + + +/* + * --- Signal Handling Section + */ + +/* + * extern long long _sa_default_rt_restorer + * extern long long _sa_default_restorer + * + * or, better, + * + * extern void _sa_default_rt_restorer(void) + * extern void _sa_default_restorer(void) + * + * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn() + * from user space. Copied into user space by signal management. + * Both must be quad aligned and 2 quad long (4 instructions). + * + */ + .balign 8 + .global sa_default_rt_restorer +sa_default_rt_restorer: + movi 0x10, r9 + shori __NR_rt_sigreturn, r9 + trapa r9 + nop + + .balign 8 + .global sa_default_restorer +sa_default_restorer: + movi 0x10, r9 + shori __NR_sigreturn, r9 + trapa r9 + nop + +/* + * --- __ex_table Section + */ + +/* + * User Access Exception Table. + */ + .section __ex_table, "a" + + .global asm_uaccess_start /* Just a marker */ +asm_uaccess_start: + + .long ___copy_user1, ___copy_user_exit + .long ___copy_user2, ___copy_user_exit + .long ___clear_user1, ___clear_user_exit + .long ___strncpy_from_user1, ___strncpy_from_user_exit + .long ___strnlen_user1, ___strnlen_user_exit + .long ___get_user_asm_b1, ___get_user_asm_b_exit + .long ___get_user_asm_w1, ___get_user_asm_w_exit + .long ___get_user_asm_l1, ___get_user_asm_l_exit + .long ___get_user_asm_q1, ___get_user_asm_q_exit + .long ___put_user_asm_b1, ___put_user_asm_b_exit + .long ___put_user_asm_w1, ___put_user_asm_w_exit + .long ___put_user_asm_l1, ___put_user_asm_l_exit + .long ___put_user_asm_q1, ___put_user_asm_q_exit + + .global asm_uaccess_end /* Just a marker */ +asm_uaccess_end: + + + + +/* + * --- .text.init Section + */ + + .section .text.init, "ax" + +/* + * void trap_init (void) + * + */ + .global trap_init +trap_init: + addi SP, -24, SP /* Room to save r28/r29/r30 */ + st.q SP, 0, r28 + st.q SP, 8, r29 + st.q SP, 16, r30 + + /* Set VBR and RESVEC */ + _loada LVBR_block, r19 + andi r19, -4, r19 /* reset MMUOFF + reserved */ + /* For RESVEC exceptions we force the MMU off, which means we need the + physical address. */ + _loada LRESVEC_block-CONFIG_CACHED_MEMORY_OFFSET, r20 + andi r20, -4, r20 /* reset reserved */ + ori r20, 1, r20 /* set MMUOFF */ + putcon r19, VBR + putcon r20, RESVEC + + /* Sanity check */ + _loada LVBR_block_end, r21 + andi r21, -4, r21 + movi BLOCK_SIZE, r29 /* r29 = expected size */ + or r19, ZERO, r30 + add r19, r29, r19 + + /* + * Ugly, but better loop forever now than crash afterwards. + * We should print a message, but if we touch LVBR or + * LRESVEC blocks we should not be surprised if we get stuck + * in trap_init(). + */ + _ptar trap_init_loop, t1 + gettr t1, r28 /* r28 = trap_init_loop */ + sub r21, r30, r30 /* r30 = actual size */ + + /* + * VBR/RESVEC handlers overlap by being bigger than + * allowed. Very bad. Just loop forever. + * (r28) panic/loop address + * (r29) expected size + * (r30) actual size + */ +trap_init_loop: + bne r19, r21, t1 + + /* Now that exception vectors are set up reset SR.BL */ + getcon SR, r22 + movi SR_UNBLOCK_EXC, r23 + and r22, r23, r22 + putcon r22, SR + + addi SP, 24, SP + ptabs LINK, t0 + blink t0, ZERO + diff -urN linux-2.4.21/arch/sh64/kernel/fpu.c linux-2.4.22/arch/sh64/kernel/fpu.c --- linux-2.4.21/arch/sh64/kernel/fpu.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/fpu.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,171 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/fpu.c + * + * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli + * + * Started from SH4 version: + * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka + * + */ + +#include +#include +#include +#include +#include + +/* + * Initially load the FPU with signalling NANS. This bit pattern + * has the property that no matter whether considered as single or as + * double precision, it still represents a signalling NAN. + */ +#define sNAN64 0xFFFFFFFFFFFFFFFF + +static struct sh_fpu_hard_struct init_fpuregs = { + { [0 ... 31] = sNAN64 }, + FPSCR_INIT +}; + +inline void fpsave(struct sh_fpu_hard_struct *fpregs) +{ + asm volatile("fst.d %0, (0*8)," __d(0) "\n\t" + "fst.d %0, (1*8)," __d(2) "\n\t" + "fst.d %0, (2*8)," __d(4) "\n\t" + "fst.d %0, (3*8)," __d(6) "\n\t" + "fst.d %0, (4*8)," __d(8) "\n\t" + "fst.d %0, (5*8)," __d(10) "\n\t" + "fst.d %0, (6*8)," __d(12) "\n\t" + "fst.d %0, (7*8)," __d(14) "\n\t" + "fst.d %0, (8*8)," __d(16) "\n\t" + "fst.d %0, (9*8)," __d(18) "\n\t" + "fst.d %0, (10*8)," __d(20) "\n\t" + "fst.d %0, (11*8)," __d(22) "\n\t" + "fst.d %0, (12*8)," __d(24) "\n\t" + "fst.d %0, (13*8)," __d(26) "\n\t" + "fst.d %0, (14*8)," __d(28) "\n\t" + "fst.d %0, (15*8)," __d(30) "\n\t" + "fst.d %0, (16*8)," __d(32) "\n\t" + "fst.d %0, (17*8)," __d(34) "\n\t" + "fst.d %0, (18*8)," __d(36) "\n\t" + "fst.d %0, (19*8)," __d(38) "\n\t" + "fst.d %0, (20*8)," __d(40) "\n\t" + "fst.d %0, (21*8)," __d(42) "\n\t" + "fst.d %0, (22*8)," __d(44) "\n\t" + "fst.d %0, (23*8)," __d(46) "\n\t" + "fst.d %0, (24*8)," __d(48) "\n\t" + "fst.d %0, (25*8)," __d(50) "\n\t" + "fst.d %0, (26*8)," __d(52) "\n\t" + "fst.d %0, (27*8)," __d(54) "\n\t" + "fst.d %0, (28*8)," __d(56) "\n\t" + "fst.d %0, (29*8)," __d(58) "\n\t" + "fst.d %0, (30*8)," __d(60) "\n\t" + "fst.d %0, (31*8)," __d(62) "\n\t" + + "_fgetscr " __f(63) "\n\t" + "fst.s %0, (32*8)," __f(63) "\n\t" + : /* no output */ + : "r" (fpregs) + : "memory"); +} + + +static inline void +fpload(struct sh_fpu_hard_struct *fpregs) +{ + asm volatile("fld.d %0, (0*8)," __d(0) "\n\t" + "fld.d %0, (1*8)," __d(2) "\n\t" + "fld.d %0, (2*8)," __d(4) "\n\t" + "fld.d %0, (3*8)," __d(6) "\n\t" + "fld.d %0, (4*8)," __d(8) "\n\t" + "fld.d %0, (5*8)," __d(10) "\n\t" + "fld.d %0, (6*8)," __d(12) "\n\t" + "fld.d %0, (7*8)," __d(14) "\n\t" + "fld.d %0, (8*8)," __d(16) "\n\t" + "fld.d %0, (9*8)," __d(18) "\n\t" + "fld.d %0, (10*8)," __d(20) "\n\t" + "fld.d %0, (11*8)," __d(22) "\n\t" + "fld.d %0, (12*8)," __d(24) "\n\t" + "fld.d %0, (13*8)," __d(26) "\n\t" + "fld.d %0, (14*8)," __d(28) "\n\t" + "fld.d %0, (15*8)," __d(30) "\n\t" + "fld.d %0, (16*8)," __d(32) "\n\t" + "fld.d %0, (17*8)," __d(34) "\n\t" + "fld.d %0, (18*8)," __d(36) "\n\t" + "fld.d %0, (19*8)," __d(38) "\n\t" + "fld.d %0, (20*8)," __d(40) "\n\t" + "fld.d %0, (21*8)," __d(42) "\n\t" + "fld.d %0, (22*8)," __d(44) "\n\t" + "fld.d %0, (23*8)," __d(46) "\n\t" + "fld.d %0, (24*8)," __d(48) "\n\t" + "fld.d %0, (25*8)," __d(50) "\n\t" + "fld.d %0, (26*8)," __d(52) "\n\t" + "fld.d %0, (27*8)," __d(54) "\n\t" + "fld.d %0, (28*8)," __d(56) "\n\t" + "fld.d %0, (29*8)," __d(58) "\n\t" + "fld.d %0, (30*8)," __d(60) "\n\t" + + "fld.s %0, (32*8)," __f(63) "\n\t" + "_fputscr " __f(63) "\n\t" + + "fld.d %0, (31*8)," __d(62) "\n\t" + : /* no output */ + : "r" (fpregs) ); +} + +void fpinit(struct sh_fpu_hard_struct *fpregs) +{ + *fpregs = init_fpuregs; +} + +asmlinkage void +do_fpu_error(unsigned long ex, struct pt_regs *regs) +{ + struct task_struct *tsk = current; + + regs->pc += 4; + + tsk->thread.trap_no = 11; + tsk->thread.error_code = 0; + force_sig(SIGFPE, tsk); +} + + +asmlinkage void +do_fpu_state_restore(unsigned long ex, struct pt_regs *regs) +{ + void die(const char * str, struct pt_regs * regs, long err); + +#if 0 +printk("do_fpu_state_restore (pid %d, used_math %d, last_used_math pid %d)\n", + current->pid, current->used_math, + last_task_used_math ? last_task_used_math->pid : -1); +#endif + + if (! user_mode(regs)) + die("FPU used in kernel", regs, ex); + + regs->sr &= ~SR_FD; + + if (last_task_used_math == current) + return; + + grab_fpu(); + if (last_task_used_math != NULL) { + /* Other processes fpu state, save away */ + fpsave(&last_task_used_math->thread.fpu.hard); + } + last_task_used_math = current; + if (current->used_math) { + fpload(¤t->thread.fpu.hard); + } else { + /* First time FPU user. */ + fpload(&init_fpuregs); + current->used_math = 1; + } + release_fpu(); +} + diff -urN linux-2.4.21/arch/sh64/kernel/head.S linux-2.4.22/arch/sh64/kernel/head.S --- linux-2.4.21/arch/sh64/kernel/head.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,347 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh5/kernel/head.S + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * + * benedict.gaster@superh.com: 2nd May 2002 + * Moved definition of empty_zero_page to its own section allowing + * it to be placed at an absolute address known at load time. + * + * lethal@linux-sh.org: 9th May 2003 + * Kill off GLOBAL_NAME() usage. + */ + +#include + +#include +#include +#include +#include +#include +#include + +/* + * MMU defines: TLB boundaries. + */ + +#define MMUIR_FIRST ITLB_FIXED +#define MMUIR_END ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP +#define MMUIR_STEP TLB_STEP + +#define MMUDR_FIRST DTLB_FIXED +#define MMUDR_END DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP +#define MMUDR_STEP TLB_STEP + +/* + * MMU defines: Fixed TLBs. + */ +#define MMUIR_TEXT_H 0x0000000000000003 | (CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START) + /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ + +#define MMUIR_TEXT_L 0x000000000000009a | (CONFIG_MEMORY_START) + /* 512 Mb, Cacheable, Write-back, execute, Not User, Ph. Add. */ + +#define MMUDR_CACHED_H 0x0000000000000003 | (CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START) + /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ +#define MMUDR_CACHED_L 0x000000000000015a | (CONFIG_MEMORY_START) + /* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */ + +#ifdef CONFIG_ICACHE_DISABLED +#define ICCR0_INIT_VAL ICCR0_OFF /* ICACHE off */ +#else +#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */ +#endif +#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */ + +#if defined (CONFIG_DCACHE_DISABLED) +#define OCCR0_INIT_VAL OCCR0_OFF /* D-cache: off */ +#elif defined (CONFIG_DCACHE_WRITE_THROUGH) +#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WT /* D-cache: on, */ + /* WT, invalidate */ +#elif defined (CONFIG_DCACHE_WRITE_BACK) +#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* D-cache: on, */ + /* WB, invalidate */ +#else +#error preprocessor flag CONFIG_DCACHE_... not recognized! +#endif + +#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */ + + .section .empty_zero_page, "aw" + .global empty_zero_page + +empty_zero_page: + .long 1 /* MOUNT_ROOT_RDONLY */ + .long 0 /* RAMDISK_FLAGS */ + .long 0x0200 /* ORIG_ROOT_DEV */ + .long 1 /* LOADER_TYPE */ + .long 0x00360000 /* INITRD_START */ + .long 0x000a0000 /* INITRD_SIZE */ + .long 0 + + .text + .balign 4096,0,4096 + + .section .data, "aw" + .balign PAGE_SIZE + + .section .data, "aw" + .balign PAGE_SIZE + + .global swapper_pg_dir +swapper_pg_dir: + .space PAGE_SIZE, 0 + + .global empty_bad_page +empty_bad_page: + .space PAGE_SIZE, 0 + + .global empty_bad_pte_table +empty_bad_pte_table: + .space PAGE_SIZE, 0 + +variables: + .global fpu_in_use +fpu_in_use: .quad 0 + + + .section .text, "ax" + .balign L1_CACHE_BYTES +/* + * Condition at the entry of __stext: + * . Reset state: + * . SR.FD = 1 (FPU disabled) + * . SR.BL = 1 (Exceptions disabled) + * . SR.MD = 1 (Privileged Mode) + * . SR.MMU = 0 (MMU Disabled) + * . SR.CD = 0 (CTC User Visible) + * . SR.IMASK = Undefined (Interrupt Mask) + * + * Operations supposed to be performed by __stext: + * . prevent speculative fetch onto device memory while MMU is off + * . reflect as much as possible SH5 ABI (r15, r26, r27, r18) + * . first, save CPU state and set it to something harmless + * . any CPU detection and/or endianness settings (?) + * . initialize EMI/LMI (but not TMU/RTC/INTC/SCIF): TBD + * . set initial TLB entries for cached and uncached regions + * (no fine granularity paging) + * . set initial cache state + * . enable MMU and caches + * . set CPU to a consistent state + * . registers (including stack pointer and current/KCR0) + * . NOT expecting to set Exception handling nor VBR/RESVEC/DCR + * at this stage. This is all to later Linux initialization steps. + * . initialize FPU + * . clear BSS + * . jump into start_kernel() + * . be prepared to hopeless start_kernel() returns. + * + */ + .global _stext +_stext: + /* + * Prevent speculative fetch on device memory due to + * uninitialized target registers. + */ + ptabs/u ZERO, t0 + ptabs/u ZERO, t1 + ptabs/u ZERO, t2 + ptabs/u ZERO, t3 + ptabs/u ZERO, t4 + ptabs/u ZERO, t5 + ptabs/u ZERO, t6 + ptabs/u ZERO, t7 + synci + + /* + * Set variable/constant pointers according to SH5 ABI. + */ + _loada constants, GCDT + + _loada variables, GVDT + + /* + * Read/Set CPU state. After this block: + * r29 = Initial SR + */ + getcon SR, r29 + movi SR_HARMLESS, r20 + putcon r20, SR + + /* + * Initialize EMI/LMI. To Be Done. + */ + + /* + * CPU detection and/or endianness settings (?). To Be Done. + * Pure PIC code here, please ! Just save state into r30. + * After this block: + * r30 = CPU type/Platform Endianness + */ + + /* + * Set initial TLB entries for cached and uncached regions. + * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't ! + */ + /* Clear ITLBs */ + _ptar clear_ITLB, t1 + movi MMUIR_FIRST, r21 + movi MMUIR_END, r22 +clear_ITLB: + putcfg r21, 0, ZERO /* Clear MMUIR[n].PTEH.V */ + addi r21, MMUIR_STEP, r21 + bne r21, r22, t1 + + /* Clear DTLBs */ + _ptar clear_DTLB, t1 + movi MMUDR_FIRST, r21 + movi MMUDR_END, r22 +clear_DTLB: + putcfg r21, 0, ZERO /* Clear MMUDR[n].PTEH.V */ + addi r21, MMUDR_STEP, r21 + bne r21, r22, t1 + + /* Map one big (512Mb) page for ITLB */ + movi MMUIR_FIRST, r21 + movi MMUIR_TEXT_L, r22 /* PTEL first */ + putcfg r21, 1, r22 /* Set MMUIR[0].PTEL */ + movi MMUIR_TEXT_H, r22 /* PTEH last */ + putcfg r21, 0, r22 /* Set MMUIR[0].PTEH */ + + /* Map one big CACHED (512Mb) page for DTLB */ + movi MMUDR_FIRST, r21 + movi MMUDR_CACHED_L, r22 /* PTEL first */ + putcfg r21, 1, r22 /* Set MMUDR[0].PTEL */ + movi MMUDR_CACHED_H, r22 /* PTEH last */ + putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ + + /* + * Set cache behaviours. + */ + /* ICache */ + movi ICCR_BASE, r21 + movi ICCR0_INIT_VAL, r22 + movi ICCR1_INIT_VAL, r23 + putcfg r21, ICCR_REG0, r22 + putcfg r21, ICCR_REG1, r23 + + /* OCache */ + movi OCCR_BASE, r21 + movi OCCR0_INIT_VAL, r22 + movi OCCR1_INIT_VAL, r23 + putcfg r21, OCCR_REG0, r22 + putcfg r21, OCCR_REG1, r23 + + + /* + * Enable Caches and MMU. Do the first non-PIC jump. + * Now head.S global variables, constants and externs + * can be used. + */ + getcon SR, r21 + movi SR_ENABLE_MMU, r22 + or r21, r22, r21 + putcon r21, SSR + _loada hyperspace, r22 + ori r22, 1, r22 /* Make it SHmedia, not required but..*/ + putcon r22, SPC + synco + rte /* And now go into the hyperspace ... */ +hyperspace: /* ... that's the next instruction ! */ + + /* + * Set CPU to a consistent state. + * r31 = FPU support flag + * t0/t7 in use. Others give a chance to loop somewhere safe + */ + _loada start_kernel, r32 + ori r32, 1, r32 + + ptabs r32, t0 /* r32 = _start_kernel address */ + _ptaru hopeless, t1 + _ptaru hopeless, t2 + _ptaru hopeless, t3 + _ptaru hopeless, t4 + _ptaru hopeless, t5 + _ptaru hopeless, t6 + _ptar hopeless, t7 + gettr t1, r28 /* r28 = hopeless address */ + + /* Set initial stack pointer */ + _loada init_task_union, SP + putcon SP, KCR0 /* Set current to init_task */ + movi THREAD_SIZE, r22 /* Point to the end */ + add SP, r22, SP + + /* + * Initialize FPU. + * Keep FPU flag in r31. After this block: + * r31 = FPU flag + */ + addi GVDT, fpu_in_use - variables, r31 /* Temporary */ + +#ifndef CONFIG_NOFPU_SUPPORT + getcon SR, r21 + movi SR_ENABLE_FPU, r22 + and r21, r22, r22 + putcon r22, SR /* Try to enable */ + getcon SR, r22 + xor r21, r22, r21 + shlri r21, 15, r21 /* Supposedly 0/1 */ + st.q r31, 0 , r21 /* Set fpu_in_use */ +#else + movi 0, r21 + st.q r31, 0 , r21 /* Set fpu_in_use */ +#endif + or r21, ZERO, r31 /* Set FPU flag at last */ + + /* + * Clear bss + */ + _ptar clear_quad, t1 + _loada __bss_start, r22 + _loada _end, r23 +clear_quad: + st.q r22, 0, ZERO + addi r22, 8, r22 + bne r22, r23, t1 /* Both quad aligned, see vmlinux.lds.S */ + _ptaru hopeless, t1 + + /* Say bye to head.S but be prepared to wrongly get back ... */ + blink t0, LINK + + /* If we ever get back here through LINK/t1-t7 */ + _ptaru hopeless, t7 + +hopeless: + /* + * Something's badly wrong here. Loop endlessly, + * there's nothing more we can do about it. + * + * Note on hopeless: it can be jumped into invariably + * before or after jumping into hyperspace. The only + * requirement is to be PIC called (PTA) before and + * any way (PTA/PTABS) after. According to Virtual + * to Physical mapping a simulator/emulator can easily + * tell where we came here from just looking at hopeless + * (PC) address. + * + * For debugging purposes: + * (r28) hopeless/loop address + * (r29) Original SR + * (r30) CPU type/Platform endianness + * (r31) FPU Support + * (r32) _start_kernel address + */ + blink t7, ZERO + + + .balign L1_CACHE_BYTES +constants: +dummyc: .quad 0 + diff -urN linux-2.4.21/arch/sh64/kernel/init_task.c linux-2.4.22/arch/sh64/kernel/init_task.c --- linux-2.4.21/arch/sh64/kernel/init_task.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/init_task.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,36 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/init_task.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + */ + +#include +#include +#include + +#include +#include + +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; +struct mm_struct init_mm = INIT_MM(init_mm); + + +struct pt_regs fake_swapper_regs; + +/* + * Initial task structure. + * + * We need to make sure that this is INIT_TASK_SIZE-byte aligned due + * to the way process stacks are handled. This is done by having a + * special "init_task" linker map entry.. + */ +union task_union init_task_union + __attribute__((__section__(".data.init_task"))) = + { INIT_TASK(init_task_union.task) }; diff -urN linux-2.4.21/arch/sh64/kernel/irq.c linux-2.4.22/arch/sh64/kernel/irq.c --- linux-2.4.21/arch/sh64/kernel/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,706 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/irq.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + */ + +/* + * IRQs are in fact implemented a bit like signal handlers for the kernel. + * Naturally it's not a 1:1 relation, but there are similarities. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Controller mappings for all interrupt sources: + */ +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = + { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}}; + +/* + * Special irq handlers. + */ + +void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } + +/* + * Generic no controller code + */ + +static void enable_none(unsigned int irq) { } +static unsigned int startup_none(unsigned int irq) { return 0; } +static void disable_none(unsigned int irq) { } +static void ack_none(unsigned int irq) +{ +/* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves, it doesnt deserve + * a generic callback i think. + */ + printk("unexpected IRQ trap at irq %02x\n", irq); +} + +/* startup is the same as "enable", shutdown is same as "disable" */ +#define shutdown_none disable_none +#define end_none enable_none + +struct hw_interrupt_type no_irq_type = { + "none", + startup_none, + shutdown_none, + enable_none, + disable_none, + ack_none, + end_none +}; + + +/* + * do_NMI handles all Non-Maskable Interrupts. + */ +asmlinkage void do_NMI(unsigned long vector_num, struct pt_regs * regs) +{ + if (regs->sr & 0x40000000) + printk("unexpected NMI trap in system mode\n"); + else + printk("unexpected NMI trap in user mode\n"); + + /* No statistics */ +} + + +/* + * Generic, controller-independent functions: + */ +#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL) +int get_irq_list(char *buf) +{ + int i, j; + struct irqaction * action; + char *p = buf; + + p += sprintf(p, " "); + for (j=0; jtypename); + p += irq_describe(p, i); + p += sprintf(p, " %s", action->name); + + for (action=action->next; action; action = action->next) + p += sprintf(p, ", %s", action->name); + *p++ = '\n'; + } +#if 0 + p += sprintf(p, "NMI: "); + for (j = 0; j < smp_num_cpus; j++) + p += sprintf(p, "%10u ", + atomic_read(&nmi_counter(cpu_logical_map(j)))); + p += sprintf(p, "\n"); +#endif + + return p - buf; +} +#endif + +/* + * This should really return information about whether + * we should do bottom half handling etc. Right now we + * end up _always_ checking the bottom half, which is a + * waste of time and is not what some drivers would + * prefer. + */ +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) +{ + int status; + int cpu = smp_processor_id(); + + irq_enter(cpu, irq); + + status = 1; /* Force the "do bottom halves" bit */ + + if (!(action->flags & SA_INTERRUPT)) + __sti(); + + do { + status |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + + __cli(); + + irq_exit(cpu, irq); + + return status; +} + +/* + * Generic enable/disable code: this just calls + * down into the PIC-specific version for the actual + * hardware disable after having gotten the irq + * controller lock. + */ + +/** + * disable_irq_nosync - disable an irq without waiting + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. Unlike disable_irq(), this function does not ensure existing + * instances of the IRQ handler have completed before returning. + * + * This function may be called from IRQ context. + */ +void disable_irq_nosync(unsigned int irq) +{ + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + if (!desc->depth++) { + desc->status |= IRQ_DISABLED; + desc->handler->disable(irq); + } + spin_unlock_irqrestore(&desc->lock, flags); +} + +/** + * disable_irq - disable an irq and wait for completion + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. That is for two disables you need two enables. This + * function waits for any pending IRQ handlers for this interrupt + * to complete before returning. If you use this function while + * holding a resource the IRQ handler may need you will deadlock. + * + * This function may be called - with care - from IRQ context. + */ +void disable_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + + if (!local_irq_count(smp_processor_id())) { + do { + barrier(); + } while (irq_desc[irq].status & IRQ_INPROGRESS); + } +} + +/** + * enable_irq - enable interrupt handling on an irq + * @irq: Interrupt to enable + * + * Re-enables the processing of interrupts on this IRQ line + * providing no disable_irq calls are now in effect. + * + * This function may be called from IRQ context. + */ +void enable_irq(unsigned int irq) +{ + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + switch (desc->depth) { + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + desc->status = status; + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { + desc->status = status | IRQ_REPLAY; + hw_resend_irq(desc->handler,irq); + } + desc->handler->enable(irq); + /* fall-through */ + } + default: + desc->depth--; + break; + case 0: + printk("enable_irq() unbalanced from %p\n", + __builtin_return_address(0)); + } + spin_unlock_irqrestore(&desc->lock, flags); +} + +/* + * do_IRQ handles all normal device IRQ's. + */ +asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs) +{ + /* + * We ack quickly, we don't want the irq controller + * thinking we're snobs just because some other CPU has + * disabled global interrupts (we have already done the + * INT_ACK cycles, it's too late to try to pretend to the + * controller that we aren't taking the interrupt). + * + * 0 return value means that this irq is already being + * handled by some other CPU. (or is disabled) + */ + int irq; + int cpu = smp_processor_id(); + irq_desc_t *desc; + struct irqaction * action; + unsigned int status; + + irq = irq_demux(vector_num); + + /* + * Should never happen, if it does check + * vectorN_to_IRQ[] against trap_jtable[]. + */ + if (irq == -1) { + printk("unexpected IRQ trap at vector %03lx\n", vector_num); + return 1; + } + + desc = irq_desc + irq; + + kstat.irqs[cpu][irq]++; + spin_lock(&desc->lock); + desc->handler->ack(irq); + /* + REPLAY is when Linux resends an IRQ that was dropped earlier + WAITING is used by probe to mark irqs that are being tested + */ + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); + status |= IRQ_PENDING; /* we _want_ to handle it */ + + /* + * If the IRQ is disabled for whatever reason, we cannot + * use the action we have. + */ + action = NULL; + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + action = desc->action; + status &= ~IRQ_PENDING; /* we commit to handling */ + status |= IRQ_INPROGRESS; /* we are handling it */ + } + desc->status = status; + + /* + * If there is no IRQ handler or it was disabled, exit early. + Since we set PENDING, if another processor is handling + a different instance of this same irq, the other processor + will take care of it. + */ + if (!action) + goto out; + + /* + * Edge triggered interrupts need to remember + * pending events. + * This applies to any hw interrupts that allow a second + * instance of the same irq to arrive while we are in do_IRQ + * or in the handler. But the code here only handles the _second_ + * instance of the irq, not the third or fourth. So it is mostly + * useful for irq hardware that does not mask cleanly in an + * SMP environment. + */ + for (;;) { + spin_unlock(&desc->lock); + handle_IRQ_event(irq, regs, action); + spin_lock(&desc->lock); + + if (!(desc->status & IRQ_PENDING)) + break; + desc->status &= ~IRQ_PENDING; + } + desc->status &= ~IRQ_INPROGRESS; +out: + /* + * The ->end() handler has to deal with interrupts which got + * disabled while the handler was running. + */ + desc->handler->end(irq); + spin_unlock(&desc->lock); + + if (softirq_pending(cpu)) + do_softirq(); + return 1; +} + +/** + * request_irq - allocate an interrupt line + * @irq: Interrupt line to allocate + * @handler: Function to be called when the IRQ occurs + * @irqflags: Interrupt type flags + * @devname: An ascii name for the claiming device + * @dev_id: A cookie passed back to the handler function + * + * This call allocates interrupt resources and enables the + * interrupt line and IRQ handling. From the point this + * call is made your handler function may be invoked. Since + * your handler function must clear any interrupt the board + * raises, you must take care both to initialise your hardware + * and to set up the interrupt handler in the right order. + * + * Dev_id must be globally unique. Normally the address of the + * device data structure is used as the cookie. Since the handler + * receives this value it makes sense to use it. + * + * If your interrupt is shared you must pass a non NULL dev_id + * as this is required when freeing the interrupt. + * + * Flags: + * + * SA_SHIRQ Interrupt is shared + * + * SA_INTERRUPT Disable local interrupts while processing + * + * SA_SAMPLE_RANDOM The interrupt can be used for entropy + * + */ +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) +{ + int retval; + struct irqaction * action; + +#if 1 + /* + * Sanity-check: shared interrupts should REALLY pass in + * a real dev-ID, otherwise we'll have trouble later trying + * to figure out which interrupt is which (messes up the + * interrupt freeing logic etc). + */ + if (irqflags & SA_SHIRQ) { + if (!dev_id) + printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]); + } +#endif + + if (irq >= NR_IRQS) + return -EINVAL; + if (!handler) + return -EINVAL; + + action = (struct irqaction *) + kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if (!action) + return -ENOMEM; + + action->handler = handler; + action->flags = irqflags; + action->mask = 0; + action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + retval = setup_irq(irq, action); + if (retval) + kfree(action); + return retval; +} + +/** + * free_irq - free an interrupt + * @irq: Interrupt line to free + * @dev_id: Device identity to free + * + * Remove an interrupt handler. The handler is removed and if the + * interrupt line is no longer in use by any driver it is disabled. + * On a shared IRQ the caller must ensure the interrupt is disabled + * on the card it drives before calling this function. The function + * does not return until any executing interrupts for this IRQ + * have completed. + * + * This function may be called from interrupt context. + * + * Bugs: Attempting to free an irq in a handler for the same irq hangs + * the machine. + */ +void free_irq(unsigned int irq, void *dev_id) +{ + irq_desc_t *desc; + struct irqaction **p; + unsigned long flags; + + if (irq >= NR_IRQS) + return; + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + for (;;) { + struct irqaction * action = *p; + if (action) { + struct irqaction **pp = p; + p = &action->next; + if (action->dev_id != dev_id) + continue; + + /* Found it - now remove it from the list of entries */ + *pp = action->next; + if (!desc->action) { + desc->status |= IRQ_DISABLED; + desc->handler->shutdown(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + kfree(action); + return; + } + printk("Trying to free free IRQ%d\n",irq); + spin_unlock_irqrestore(&desc->lock,flags); + return; + } +} + +/* + * IRQ autodetection code.. + * + * This depends on the fact that any interrupt that + * comes in on to an unassigned handler will get stuck + * with "IRQ_WAITING" cleared and the interrupt + * disabled. + */ + +/** + * probe_irq_on - begin an interrupt autodetect + * + * Commence probing for an interrupt. The interrupts are scanned + * and a mask of potential interrupt lines is returned. + * + */ +unsigned long probe_irq_on(void) +{ + unsigned int i; + irq_desc_t *desc; + unsigned long val; + unsigned long delay; + + /* + * something may have generated an irq long ago and we want to + * flush such a longstanding irq before considering it as spurious. + */ + for (i = NR_IRQS-1; i >= 0; i--) { + desc = irq_desc + i; + + spin_lock_irq(&desc->lock); + if (!irq_desc[i].action) { + irq_desc[i].handler->startup(i); + } + spin_unlock_irq(&desc->lock); + } + + /* Wait for longstanding interrupts to trigger. */ + for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) + /* about 20ms delay */ synchronize_irq(); + + /* + * enable any unassigned irqs + * (we must startup again here because if a longstanding irq + * happened in the previous stage, it may have masked itself) + */ + for (i = NR_IRQS-1; i >= 0; i--) { + desc = irq_desc + 1; + + spin_lock_irq(&desc->lock); + if (!desc->action) { + desc->status |= IRQ_AUTODETECT | IRQ_WAITING; + if (desc->handler->startup(i)) + desc->status |= IRQ_PENDING; + } + spin_unlock_irq(&desc->lock); + } + + /* + * Wait for spurious interrupts to trigger + */ + for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) + /* about 100ms delay */ synchronize_irq(); + + /* + * Now filter out any obviously spurious interrupts + */ + val = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc_t *desc = irq_desc + i; + unsigned int status; + + spin_lock_irq(&desc->lock); + status = desc->status; + + if (status & IRQ_AUTODETECT) { + /* It triggered already - consider it spurious. */ + if (!(status & IRQ_WAITING)) { + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } else + if (i < 32) + val |= 1 << i; + } + spin_unlock_irq(&desc->lock); + } + + return val; +} + +/* + * Return the one interrupt that triggered (this can + * handle any interrupt source). + */ + +/** + * probe_irq_off - end an interrupt autodetect + * @val: mask of potential interrupts (unused) + * + * Scans the unused interrupt lines and returns the line which + * appears to have triggered the interrupt. If no interrupt was + * found then zero is returned. If more than one interrupt is + * found then minus the first candidate is returned to indicate + * their is doubt. + * + * The interrupt probe logic state is returned to its previous + * value. + * + * BUGS: When used in a module (which arguably shouldnt happen) + * nothing prevents two IRQ probe callers from overlapping. The + * results of this are non-optimal. + */ +int probe_irq_off(unsigned long val) +{ + int i, irq_found, nr_irqs; + + nr_irqs = 0; + irq_found = 0; + for (i=0; ilock); + status = desc->status; + if (!(status & IRQ_AUTODETECT)) + continue; + + if (status & IRQ_AUTODETECT) { + if (!(status & IRQ_WAITING)) { + if (!nr_irqs) + irq_found = i; + nr_irqs++; + } + + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } + spin_unlock_irq(&desc->lock); + } + + if (nr_irqs > 1) + irq_found = -irq_found; + return irq_found; +} + +int setup_irq(unsigned int irq, struct irqaction * new) +{ + int shared = 0; + unsigned long flags; + struct irqaction *old, **p; + irq_desc_t *desc = irq_desc + irq; + + /* + * Some drivers like serial.c use request_irq() heavily, + * so we have to be careful not to interfere with a + * running system. + */ + if (new->flags & SA_SAMPLE_RANDOM) { + /* + * This function might sleep, we want to call it first, + * outside of the atomic block. + * Yes, this might clear the entropy pool if the wrong + * driver is attempted to be loaded, without actually + * installing a new handler, but is this really a problem, + * only the sysadmin is able to do this. + */ + rand_initialize_irq(irq); + } + + /* + * The following block of code has to be executed atomically + */ + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&desc->lock,flags); + return -EBUSY; + } + + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } + + *p = new; + + if (!shared) { + desc->depth = 0; + desc->status &= ~IRQ_DISABLED; + desc->handler->startup(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + + /* + * No PROC FS support for interrupts. + * For improvements in this area please check + * the i386 branch. + */ + return 0; +} + +#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL) + +void init_irq_proc(void) +{ + /* + * No PROC FS support for interrupts. + * For improvements in this area please check + * the i386 branch. + */ +} +#endif diff -urN linux-2.4.21/arch/sh64/kernel/irq_intc.c linux-2.4.22/arch/sh64/kernel/irq_intc.c --- linux-2.4.21/arch/sh64/kernel/irq_intc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/irq_intc.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,269 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/irq_intc.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Interrupt Controller support for SH5 INTC. + * Per-interrupt selective. IRLM=0 (Fixed priority) is not + * supported being useless without a cascaded interrupt + * controller. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include /* this includes also +#include +#include + +/* + * Maybe the generic Peripheral block could move to a more + * generic include file. INTC Block will be defined here + * and only here to make INTC self-contained in a single + * file. + */ +#define INTC_BLOCK_OFFSET 0x01000000 + +/* Base */ +#define INTC_BASE PHYS_PERIPHERAL_BLOCK + \ + INTC_BLOCK_OFFSET + +/* Address */ +#define INTC_ICR_SET (intc_virt + 0x0) +#define INTC_ICR_CLEAR (intc_virt + 0x8) +#define INTC_INTPRI_0 (intc_virt + 0x10) +#define INTC_INTSRC_0 (intc_virt + 0x50) +#define INTC_INTSRC_1 (intc_virt + 0x58) +#define INTC_INTREQ_0 (intc_virt + 0x60) +#define INTC_INTREQ_1 (intc_virt + 0x68) +#define INTC_INTENB_0 (intc_virt + 0x70) +#define INTC_INTENB_1 (intc_virt + 0x78) +#define INTC_INTDSB_0 (intc_virt + 0x80) +#define INTC_INTDSB_1 (intc_virt + 0x88) + +#define INTC_ICR_IRLM 0x1 +#define INTC_INTPRI_PREGS 8 /* 8 Priority Registers */ +#define INTC_INTPRI_PPREG 8 /* 8 Priorities per Register */ + + +/* + * Mapper between the vector ordinal and the IRQ number + * passed to kernel/device drivers. + */ +int intc_evt_to_irq[(0xE20/0x20)+1] = { + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x000 - 0x0E0 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x100 - 0x1E0 */ + 0, 0, 0, 0, 0, 1, 0, 0, /* 0x200 - 0x2E0 */ + 2, 0, 0, 3, 0, 0, 0, -1, /* 0x300 - 0x3E0 */ + 32, 33, 34, 35, 36, 37, 38, -1, /* 0x400 - 0x4E0 */ + -1, -1, -1, 63, -1, -1, -1, -1, /* 0x500 - 0x5E0 */ + -1, -1, 18, 19, 20, 21, 22, -1, /* 0x600 - 0x6E0 */ + 39, 40, 41, 42, -1, -1, -1, -1, /* 0x700 - 0x7E0 */ + 4, 5, 6, 7, -1, -1, -1, -1, /* 0x800 - 0x8E0 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x900 - 0x9E0 */ + 12, 13, 14, 15, 16, 17, -1, -1, /* 0xA00 - 0xAE0 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB00 - 0xBE0 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC00 - 0xCE0 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD00 - 0xDE0 */ + -1, -1 /* 0xE00 - 0xE20 */ +}; + +/* + * Opposite mapper. + */ +static int IRQ_to_vectorN[NR_INTC_IRQS] = { + 0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /* 0- 7 */ + -1, -1, -1, -1, 0x50, 0x51, 0x52, 0x53, /* 8-15 */ + 0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36, -1, /* 16-23 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 24-31 */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38, /* 32-39 */ + 0x39, 0x3A, 0x3B, -1, -1, -1, -1, -1, /* 40-47 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 48-55 */ + -1, -1, -1, -1, -1, -1, -1, 0x2B, /* 56-63 */ + +}; + +static unsigned long intc_virt; + +static unsigned int startup_intc_irq(unsigned int irq); +static void shutdown_intc_irq(unsigned int irq); +static void enable_intc_irq(unsigned int irq); +static void disable_intc_irq(unsigned int irq); +static void mask_and_ack_intc(unsigned int); +static void end_intc_irq(unsigned int irq); + +static struct hw_interrupt_type intc_irq_type = { + "INTC", + startup_intc_irq, + shutdown_intc_irq, + enable_intc_irq, + disable_intc_irq, + mask_and_ack_intc, + end_intc_irq +}; + +static int irlm; /* IRL mode */ + +static unsigned int startup_intc_irq(unsigned int irq) +{ + enable_intc_irq(irq); + return 0; /* never anything pending */ +} + +static void shutdown_intc_irq(unsigned int irq) +{ + disable_intc_irq(irq); +} + +static void enable_intc_irq(unsigned int irq) +{ + unsigned long reg; + unsigned long bitmask; + + if ((irq <= IRQ_IRL3) && (irlm == NO_PRIORITY)) + printk("Trying to use straight IRL0-3 with an encoding platform.\n"); + + if (irq < 32) { + reg = INTC_INTENB_0; + bitmask = 1 << irq; + } else { + reg = INTC_INTENB_1; + bitmask = 1 << (irq - 32); + } + + ctrl_outl(bitmask, reg); +} + +static void disable_intc_irq(unsigned int irq) +{ + unsigned long reg; + unsigned long bitmask; + + if (irq < 32) { + reg = INTC_INTDSB_0; + bitmask = 1 << irq; + } else { + reg = INTC_INTDSB_1; + bitmask = 1 << (irq - 32); + } + + ctrl_outl(bitmask, reg); +} + +static void mask_and_ack_intc(unsigned int irq) +{ + disable_intc_irq(irq); +} + +static void end_intc_irq(unsigned int irq) +{ + enable_intc_irq(irq); +} + +/* For future use, if we ever support IRLM=0) */ +void make_intc_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &intc_irq_type; + disable_intc_irq(irq); +} + +#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL) +int intc_irq_describe(char* p, int irq) +{ + if (irq < NR_INTC_IRQS) + return sprintf(p, "(0x%3x)", IRQ_to_vectorN[irq]*0x20); + else + return 0; +} +#endif + +void __init init_IRQ(void) +{ + unsigned long long __dummy0, __dummy1=~0x00000000100000f0; + unsigned long reg; + unsigned long data; + int i; + + intc_virt = onchip_remap(INTC_BASE, 1024, "INTC"); + if (!intc_virt) { + panic("Unable to remap INTC\n"); + } + + + /* Set default: per-line enable/disable, priority driven ack/eoi */ + for (i = 0; i < NR_INTC_IRQS; i++) { + if (platform_int_priority[i] != NO_PRIORITY) { + irq_desc[i].handler = &intc_irq_type; + } + } + + + /* Disable all interrupts and set all priorities to 0 to avoid trouble */ + ctrl_outl(-1, INTC_INTDSB_0); + ctrl_outl(-1, INTC_INTDSB_1); + + for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8) + ctrl_outl( NO_PRIORITY, reg); + + + /* Set IRLM */ + /* If all the priorities are set to 'no priority', then + * assume we are using encoded mode. + */ + irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \ + platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3]; + + if (irlm == NO_PRIORITY) { + /* IRLM = 0 */ + reg = INTC_ICR_CLEAR; + i = IRQ_INTA; + printk("Trying to use encoded IRL0-3. IRLs unsupported.\n"); + } else { + /* IRLM = 1 */ + reg = INTC_ICR_SET; + i = IRQ_IRL0; + } + ctrl_outl(INTC_ICR_IRLM, reg); + + /* Set interrupt priorities according to platform description */ + for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) { + data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4); + if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) { + /* Upon the 7th, set Priority Register */ + ctrl_outl(data, reg); + data = 0; + reg += 8; + } + } + +#ifdef CONFIG_SH_CAYMAN + extern void init_cayman_irq(void); + + init_cayman_irq(); +#endif + + /* + * And now let interrupts come in. + * sti() is not enough, we need to + * lower priority, too. + */ + __asm__ __volatile__("getcon " __c0 ", %0\n\t" + "and %0, %1, %0\n\t" + "putcon %0, " __c0 "\n\t" + : "=&r" (__dummy0) + : "r" (__dummy1)); +} diff -urN linux-2.4.21/arch/sh64/kernel/led.c linux-2.4.22/arch/sh64/kernel/led.c --- linux-2.4.21/arch/sh64/kernel/led.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/led.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,69 @@ +/* + * arch/sh64/kernel/led.c + * + * Copyright (C) 2002 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Flash the LEDs + */ +#include +#include +#include + +void mach_alphanum(int pos, unsigned char val); +void mach_led(int pos, int val); + +void print_seg(char *file, int line) +{ + int i; + unsigned int nibble; + + for (i = 0; i < 5; i++) { + mach_alphanum(i, file[i]); + } + + for (i = 0; i < 3; i++) { + nibble = ((line >> (i * 4)) & 0xf); + mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48)); + } +} + +void print_seg_num(unsigned num) +{ + int i; + unsigned int nibble; + + for (i = 0; i < 8; i++) { + nibble = ((num >> (i * 4)) & 0xf); + + mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48)); + } +} + +/* acts like an actual heart beat -- ie thump-thump-pause... */ +void heartbeat(void) +{ + static unsigned int cnt = 0, period = 0, dist = 0; + + if (cnt == 0 || cnt == dist) { + mach_led(-1, 1); + } else if (cnt == 7 || cnt == dist + 7) { + mach_led(-1, 0); + } + + if (++cnt > period) { + cnt = 0; + + /* + * The hyperbolic function below modifies the heartbeat period + * length in dependency of the current (5min) load. It goes + * through the points f(0)=126, f(1)=86, f(5)=51, f(inf)->30. + */ + period = ((672 << FSHIFT) / (5 * avenrun[0] + + (7 << FSHIFT))) + 30; + dist = period / 4; + } +} + diff -urN linux-2.4.21/arch/sh64/kernel/pci-dma.c linux-2.4.22/arch/sh64/kernel/pci-dma.c --- linux-2.4.21/arch/sh64/kernel/pci-dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/pci-dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) + * Copyright (C) 2003 Paul Mundt (lethal@linux-sh.org) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Dynamic DMA mapping support. + */ +#include +#include +#include +#include +#include + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + void *vp; + + if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) + gfp |= GFP_DMA; + + ret = (void *)__get_free_pages(gfp, get_order(size)); + + /* now call our friend ioremap_nocache to give us an uncached area */ + vp = ioremap_nocache(virt_to_phys(ret), size); + + if (vp != NULL) { + memset(vp, 0, size); + *dma_handle = virt_to_bus(ret); + dma_cache_wback_inv((unsigned long)ret, size); + } + + return vp; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + void *alloc; + + alloc = bus_to_virt((unsigned long)dma_handle); + free_pages((unsigned long)alloc, get_order(size)); + + iounmap(vaddr); +} + diff -urN linux-2.4.21/arch/sh64/kernel/pci_sh5.c linux-2.4.22/arch/sh64/kernel/pci_sh5.c --- linux-2.4.21/arch/sh64/kernel/pci_sh5.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/pci_sh5.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,620 @@ +/* + * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Support functions for the SH5 PCI hardware. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "pci_sh5.h" + +#undef DEBUG + +#ifdef DEBUG +# define dprintk(x...) printk(KERN_DEBUG x) +#else +# define dprintk(x...) do { } while (0) +#endif /* DEBUG */ + +static unsigned long pcicr_virt; +unsigned long pciio_virt; + +static void __init pci_fixup_ide_bases(struct pci_dev *d) +{ + int i; + + /* + * PCI IDE controllers use non-standard I/O port decoding, respect it. + */ + if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + printk("PCI: IDE base address fixup for %s\n", d->slot_name); + for(i=0; i<4; i++) { + struct resource *r = &d->resource[i]; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } + } +} + +/* Add future fixups here... */ +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases }, + { 0 } +}; + +char * __init pcibios_setup(char *str) +{ + return str; +} + +/* Rounds a number UP to the nearest power of two. Used for + * sizing the PCI window. + */ +static u32 __init r2p2(u32 num) +{ + int i = 31; + u32 tmp = num; + + if (num == 0) + return 0; + + do { + if (tmp & (1 << 31)) + break; + i--; + tmp <<= 1; + } while (i >= 0); + + tmp = 1 << i; + /* If the original number isn't a power of 2, round it up */ + if (tmp != num) + tmp <<= 1; + + return tmp; +} + +extern unsigned long long memory_start, memory_end; + +int __init sh5pci_init(unsigned memStart, unsigned memSize) +{ + u32 lsr0; + u32 uval; + + pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR"); + if (!pcicr_virt) { + panic("Unable to remap PCICR\n"); + } + + pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO"); + if (!pciio_virt) { + panic("Unable to remap PCIIO\n"); + } + + dprintk("Register base addres is 0x%08lx\n", pcicr_virt); + + /* Clear snoop registers */ + SH5PCI_WRITE(CSCR0, 0); + SH5PCI_WRITE(CSCR1, 0); + + dprintk("Wrote to reg\n"); + + /* Switch off interrupts */ + SH5PCI_WRITE(INTM, 0); + SH5PCI_WRITE(AINTM, 0); + SH5PCI_WRITE(PINTM, 0); + + /* Set bus active, take it out of reset */ + uval = SH5PCI_READ(CR); + + /* Set command Register */ + SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM ); + + uval=SH5PCI_READ(CR); + dprintk("CR is actually 0x%08x\n",uval); + + /* Allow it to be a master */ + /* NB - WE DISABLE I/O ACCESS to stop overlap */ + /* set WAIT bit to enable stepping, an attempt to improve stability */ + SH5PCI_WRITE_SHORT(CSR_CMD, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT); + + /* + ** Set translation mapping memory in order to convert the address + ** used for the main bus, to the PCI internal address. + */ + SH5PCI_WRITE(MBR,0x40000000); + + /* Always set the max size 512M */ + SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024)); + + /* + ** I/O addresses are mapped at internal PCI specific address + ** as is described into the configuration bridge table. + ** These are changed to 0, to allow cards that have legacy + ** io such as vga to function correctly. We set the SH5 IOBAR to + ** 256K, which is a bit big as we can only have 64K of address space + */ + + SH5PCI_WRITE(IOBR,0x0); + + dprintk("PCI:Writing 0x%08x to IOBR\n",0); + + /* Set up a 256K window. Totally pointless waste of address space */ + SH5PCI_WRITE(IOBMR,0); + dprintk("PCI:Writing 0x%08x to IOBMR\n",0); + + /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally, + * we would want to map the I/O region somewhere, but it is so big this is not + * that easy! + */ + SH5PCI_WRITE(CSR_IBAR0,~0); + /* Set memory size value */ + memSize = memory_end - memory_start; + + /* Now we set up the mbars so the PCI bus can see the memory of the machine */ + if (memSize < (1024 * 1024)) { + printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize); + return(-1); + } + + /* Set LSR 0 */ + lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1); + SH5PCI_WRITE(LSR0, lsr0); + + dprintk("PCI:Writing 0x%08x to LSR0\n",lsr0); + + /* Set MBAR 0 */ + SH5PCI_WRITE(CSR_MBAR0, memory_start); + SH5PCI_WRITE(LAR0, memory_start); + + + SH5PCI_WRITE(CSR_MBAR1,0); + SH5PCI_WRITE(LAR1,0); + SH5PCI_WRITE(LSR1,0); + + dprintk("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start); + dprintk("PCI:Writing 0x%08llx to LAR0\n",memory_start); + + /* Enable the PCI interrupts on the device */ + +#if 1 + SH5PCI_WRITE(INTM, ~0); + SH5PCI_WRITE(AINTM, ~0); + SH5PCI_WRITE(PINTM, ~0); +#endif + + dprintk("Switching on all error interrupts\n"); + + return(0); +} + + + +/* Write to config register */ +static int sh5pci_read_config_byte(struct pci_dev *dev, int where, + u8 * val) +{ + SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where)); + + *val = SH5PCI_READ_BYTE(PDR + (where & 3)); + + return PCIBIOS_SUCCESSFUL; +} + +static int sh5pci_read_config_word(struct pci_dev *dev, int where, + u16 * val) +{ + SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where)); + + *val = SH5PCI_READ_SHORT(PDR + (where & 2)); + + + return PCIBIOS_SUCCESSFUL; +} + +static int sh5pci_read_config_dword(struct pci_dev *dev, int where, + u32 * val) +{ + SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where)); + + *val = SH5PCI_READ(PDR); + + return PCIBIOS_SUCCESSFUL; +} + +static int sh5pci_write_config_byte(struct pci_dev *dev, int where, + u8 val) +{ + SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where)); + + SH5PCI_WRITE_BYTE(PDR + (where & 3), val); + + + return PCIBIOS_SUCCESSFUL; +} + + +static int sh5pci_write_config_word(struct pci_dev *dev, int where, + u16 val) +{ + SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where)); + + SH5PCI_WRITE_SHORT(PDR + (where & 2), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int sh5pci_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where)); + + SH5PCI_WRITE(PDR, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static struct pci_ops pci_config_ops = { + sh5pci_read_config_byte, + sh5pci_read_config_word, + sh5pci_read_config_dword, + sh5pci_write_config_byte, + sh5pci_write_config_word, + sh5pci_write_config_dword +}; + +/* Everything hangs off this */ +static struct pci_bus *pci_root_bus; + + +static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) +{ + dprintk("swizzle for dev %d on bus %d slot %d pin is %d\n", + dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin); + return PCI_SLOT(dev->devfn); +} + +static inline u8 bridge_swizzle(u8 pin, u8 slot) +{ + return (((pin-1) + slot) % 4) + 1; +} + +u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) +{ + if (dev->bus->number != 0) { + u8 pin = *pinp; + do { + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + /* Move up the chain of bridges. */ + dev = dev->bus->self; + } while (dev->bus->self); + *pinp = pin; + + /* The slot is the slot of the last bridge. */ + } + + return PCI_SLOT(dev->devfn); +} + +/* This needs to be shunted out of here into the board specific bit */ + +static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int result = -1; + + if (dev->bus->number == 0) { + switch ((slot + (pin-1)) & 3) { + case 0: + result = IRQ_INTA; + break; + case 1: + result = IRQ_INTB; + break; + case 2: + result = IRQ_INTC; + break; + case 3: + result = IRQ_INTD; + break; + } + } + + if (dev->bus->number == 2) { + switch((slot + (pin-1)) & 3) { + case 0: + result = IRQ_P2INTA; + break; + case 1: + result = IRQ_P2INTB; + break; + case 2: + result = IRQ_P2INTC; + break; + case 3: + result = IRQ_P2INTD; + break; + } + } + + dprintk("map_cayman_irq for dev %d on bus %d slot %d, pin is %d : irq=%d\n", + dev->devfn,dev->bus->number,slot,pin,result); + + return result; +} + +#ifdef DEBUG +void print_resource(struct resource *r) +{ + if (r == NULL) + return; + + //printk("Resource %s\n",r->name); + printk("Start 0x%lx end 0x%lx\n",r->start,r->end); +} + +void print_set_ranges_data(struct pbus_set_ranges_data *ranges) +{ + + if (!ranges) { + printk("NO RANGES\n"); + return; + } + + printk("io_start is 0x%lx\n", ranges->io_start); + printk("io_end is 0x%lx\n", ranges->io_end); + printk("mem_start is 0x%lx\n", ranges->mem_start); + printk("mem_end is 0x%lx\n", ranges->mem_end); +} +#endif /* DEBUG */ + +void __init + pcibios_fixup_pbus_ranges(struct pci_bus *bus, + struct pbus_set_ranges_data *ranges) +{ +#ifdef DEBUG + int i; + + dprintk("%s, bus number %d\n",__FUNCTION__,bus->number); + + print_set_ranges_data(ranges); + + for (i = 0; i < 2; i++) + print_resource(bus->resource[i]); +#endif +} + +void pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned pci_int, pci_air, pci_cir, pci_aint; + + pci_int = SH5PCI_READ(INT); + pci_cir = SH5PCI_READ(CIR); + pci_air = SH5PCI_READ(AIR); + + if (pci_int) { + printk("PCI INTERRUPT (at %08llx)!\n", regs->pc); + printk("PCI INT -> 0x%x\n", pci_int & 0xffff); + printk("PCI AIR -> 0x%x\n", pci_air); + printk("PCI CIR -> 0x%x\n", pci_cir); + SH5PCI_WRITE(INT, ~0); + } + + pci_aint = SH5PCI_READ(AINT); + if (pci_aint) { + printk("PCI ARB INTERRUPT!\n"); + printk("PCI AINT -> 0x%x\n", pci_aint); + printk("PCI AIR -> 0x%x\n", pci_air); + printk("PCI CIR -> 0x%x\n", pci_cir); + SH5PCI_WRITE(AINT, ~0); + } + +} + + +void pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + printk("SERR IRQ\n"); + +} + +#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +static void __init +pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer) +{ + struct pbus_set_ranges_data inner; + struct pci_dev *dev; + struct pci_dev *bridge = bus->self; + struct list_head *ln; + + if (!bridge) + return; /* host bridge, nothing to do */ + + /* set reasonable default locations for pcibios_align_resource */ + inner.io_start = PCIBIOS_MIN_IO; + inner.mem_start = PCIBIOS_MIN_MEM; + inner.io_end = inner.io_start; + inner.mem_end = inner.mem_start; + + /* Collect information about how our direct children are layed out. */ + for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { + int i; + dev = pci_dev_b(ln); + + /* Skip bridges for now */ + if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) + continue; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource res; + unsigned long size; + + memcpy(&res, &dev->resource[i], sizeof(res)); + size = res.end - res.start + 1; + + if (res.flags & IORESOURCE_IO) { + res.start = inner.io_end; + pcibios_align_resource(dev, &res, size, 0); + inner.io_end = res.start + size; + } else if (res.flags & IORESOURCE_MEM) { + res.start = inner.mem_end; + pcibios_align_resource(dev, &res, size, 0); + inner.mem_end = res.start + size; + } + } + } + + /* And for all of the subordinate busses. */ + for (ln=bus->children.next; ln != &bus->children; ln=ln->next) + pcibios_size_bridge(pci_bus_b(ln), &inner); + + /* turn the ending locations into sizes (subtract start) */ + inner.io_end -= inner.io_start; + inner.mem_end -= inner.mem_start; + + /* Align the sizes up by bridge rules */ + inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1; + inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1; + + /* Adjust the bridge's allocation requirements */ + bridge->resource[0].end = bridge->resource[0].start + inner.io_end; + bridge->resource[1].end = bridge->resource[1].start + inner.mem_end; + + bridge->resource[PCI_BRIDGE_RESOURCES].end = + bridge->resource[PCI_BRIDGE_RESOURCES].start + inner.io_end; + bridge->resource[PCI_BRIDGE_RESOURCES+1].end = + bridge->resource[PCI_BRIDGE_RESOURCES+1].start + inner.mem_end; + + /* adjust parent's resource requirements */ + if (outer) { + outer->io_end = ROUND_UP(outer->io_end, 4*1024); + outer->io_end += inner.io_end; + + outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024); + outer->mem_end += inner.mem_end; + } +} + +#undef ROUND_UP + +static void __init +pcibios_size_bridges(void) +{ + struct pbus_set_ranges_data outer; + + memset(&outer,0,sizeof(outer)); + pcibios_size_bridge(pci_root_bus,&outer); +} + +void __init +common_init_pci(void) +{ + pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); + pcibios_size_bridges(); + pci_assign_unassigned_resources(); + pci_fixup_irqs(no_swizzle, map_cayman_irq); + // pci_set_bus_ranges(); +} + +void __init pcibios_init(void) +{ + + if (request_irq(IRQ_ERR, pcish5_err_irq, + SA_INTERRUPT, "PCI Error",NULL) < 0) { + printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n"); + return; + } + + + if (request_irq(IRQ_SERR, pcish5_serr_irq, + SA_INTERRUPT, "PCI SERR interrupt", NULL) < 0) { + printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n"); + return; + } + + + /* The pci subsytem needs to know where memory is and how much + * of it there is. I've simply made these globals. A better mechanism + * is probably needed. + */ + sh5pci_init(__pa(memory_start), + __pa(memory_end) - __pa(memory_start)); + + + common_init_pci(); + +#if 0 + pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); + + pci_assign_unassigned_resources(); + + pci_fixup_irqs(no_swizzle, map_cayman_irq); + + pci_set_bus_ranges(); +#endif + +} + +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev = bus->self; + int i; + +#if 1 + if(dev) { + for(i=0; i<3; i++) { + bus->resource[i] = + &dev->resource[PCI_BRIDGE_RESOURCES+i]; + bus->resource[i]->name = bus->name; + } + bus->resource[0]->flags |= IORESOURCE_IO; + bus->resource[1]->flags |= IORESOURCE_MEM; + + /* For now, propogate host limits to the bus; + * we'll adjust them later. */ + +#if 1 + bus->resource[0]->end = 64*1024 - 1 ; + bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1; + bus->resource[0]->start = PCIBIOS_MIN_IO; + bus->resource[1]->start = PCIBIOS_MIN_MEM; +#else + bus->resource[0]->end = 0 + bus->resource[1]->end = 0 + bus->resource[0]->start =0 + bus->resource[1]->start = 0; +#endif + +#ifdef DEBUG + dprintk("in fixup bus resource 0 is:\n"); + print_resource(bus->resource[0]); + dprintk("in fixup bus resource 1 is:\n"); + print_resource(bus->resource[1]); +#endif /* DEBUG */ + + /* Turn off downstream PF memory address range by default */ + bus->resource[2]->start = 1024*1024; + bus->resource[2]->end = bus->resource[2]->start - 1; + } +#endif + +} + diff -urN linux-2.4.21/arch/sh64/kernel/pci_sh5.h linux-2.4.22/arch/sh64/kernel/pci_sh5.h --- linux-2.4.21/arch/sh64/kernel/pci_sh5.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/pci_sh5.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Defintions for the SH5 PCI hardware. + */ + +/* Product ID */ +#define PCISH5_PID 0x350d + +/* vendor ID */ +#define PCISH5_VID 0x1054 + +/* Configuration types */ +#define ST_TYPE0 0x00 /* Configuration cycle type 0 */ +#define ST_TYPE1 0x01 /* Configuration cycle type 1 */ + +/* VCR data */ +#define PCISH5_VCR_STATUS 0x00 +#define PCISH5_VCR_VERSION 0x08 + +/* +** ICR register offsets and bits +*/ +#define PCISH5_ICR_CR 0x100 /* PCI control register values */ +#define CR_PBAM (1<<12) +#define CR_PFCS (1<<11) +#define CR_FTO (1<<10) +#define CR_PFE (1<<9) +#define CR_TBS (1<<8) +#define CR_SPUE (1<<7) +#define CR_BMAM (1<<6) +#define CR_HOST (1<<5) +#define CR_CLKEN (1<<4) +#define CR_SOCS (1<<3) +#define CR_IOCS (1<<2) +#define CR_RSTCTL (1<<1) +#define CR_CFINT (1<<0) +#define CR_LOCK_MASK 0xa5000000 + +#define PCISH5_ICR_INT 0x114 /* Interrupt registert values */ +#define INT_MADIM (1<<2) + +#define PCISH5_ICR_LSR0 0X104 /* Local space register values */ +#define PCISH5_ICR_LSR1 0X108 /* Local space register values */ +#define PCISH5_ICR_LAR0 0x10c /* Local address register values */ +#define PCISH5_ICR_LAR1 0x110 /* Local address register values */ +#define PCISH5_ICR_INTM 0x118 /* Interrupt mask register values */ +#define PCISH5_ICR_AIR 0x11c /* Interrupt error address information register values */ +#define PCISH5_ICR_CIR 0x120 /* Interrupt error command information register values */ +#define PCISH5_ICR_AINT 0x130 /* Interrupt error arbiter interrupt register values */ +#define PCISH5_ICR_AINTM 0x134 /* Interrupt error arbiter interrupt mask register values */ +#define PCISH5_ICR_BMIR 0x138 /* Interrupt error info register of bus master values */ +#define PCISH5_ICR_PAR 0x1c0 /* Pio address register values */ +#define PCISH5_ICR_MBR 0x1c4 /* Memory space bank register values */ +#define PCISH5_ICR_IOBR 0x1c8 /* I/O space bank register values */ +#define PCISH5_ICR_PINT 0x1cc /* power management interrupt register values */ +#define PCISH5_ICR_PINTM 0x1d0 /* power management interrupt mask register values */ +#define PCISH5_ICR_MBMR 0x1d8 /* memory space bank mask register values */ +#define PCISH5_ICR_IOBMR 0x1dc /* I/O space bank mask register values */ +#define PCISH5_ICR_CSCR0 0x210 /* PCI cache snoop control register 0 */ +#define PCISH5_ICR_CSCR1 0x214 /* PCI cache snoop control register 1 */ +#define PCISH5_ICR_PDR 0x220 /* Pio data register values */ + +/* These are configs space registers */ +#define PCISH5_ICR_CSR_VID 0x000 /* Vendor id */ +#define PCISH5_ICR_CSR_DID 0x002 /* Device id */ +#define PCISH5_ICR_CSR_CMD 0x004 /* Command register */ +#define PCISH5_ICR_CSR_STATUS 0x006 /* Stautus */ +#define PCISH5_ICR_CSR_IBAR0 0x010 /* I/O base address register */ +#define PCISH5_ICR_CSR_MBAR0 0x014 /* First Memory base address register */ +#define PCISH5_ICR_CSR_MBAR1 0x018 /* Second Memory base address register */ + + + +/* Base address of registers */ +#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000) +#define SH5PCI_IO_BASE (PHYS_PCI_BLOCK + 0x00800000) +/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG) */ + +/* Register selection macro */ +#define PCISH5_ICR_REG(x) ( pcicr_virt + (PCISH5_ICR_##x)) +/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */ + +/* Write I/O functions */ +#define SH5PCI_WRITE(reg,val) ctrl_outl((u32)(val),PCISH5_ICR_REG(reg)) +#define SH5PCI_WRITE_SHORT(reg,val) ctrl_outw((u16)(val),PCISH5_ICR_REG(reg)) +#define SH5PCI_WRITE_BYTE(reg,val) ctrl_outb((u8)(val),PCISH5_ICR_REG(reg)) + +/* Read I/O functions */ +#define SH5PCI_READ(reg) ctrl_inl(PCISH5_ICR_REG(reg)) +#define SH5PCI_READ_SHORT(reg) ctrl_inw(PCISH5_ICR_REG(reg)) +#define SH5PCI_READ_BYTE(reg) ctrl_inb(PCISH5_ICR_REG(reg)) + +/* Set PCI config bits */ +#define SET_CONFIG_BITS(bus,devfn,where) ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000) + +/* Set PCI command register */ +#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where) + +/* Size converters */ +#define PCISH5_MEM_SIZCONV(x) (((x / 0x40000) - 1) << 18) +#define PCISH5_IO_SIZCONV(x) (((x / 0x40000) - 1) << 18) + + diff -urN linux-2.4.21/arch/sh64/kernel/pcibios.c linux-2.4.22/arch/sh64/kernel/pcibios.c --- linux-2.4.21/arch/sh64/kernel/pcibios.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/pcibios.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,129 @@ +/* + * $Id: pcibios.c,v 1.1 2001/08/24 12:38:19 dwmw2 Exp $ + * + * arch/sh/kernel/pcibios.c + * + * This is GPL'd. + * + * Provided here are generic versions of: + * pcibios_update_resource() + * pcibios_align_resource() + * pcibios_enable_device() + * pcibios_set_master() + * pcibios_update_irq() + * + * These functions are collected here to reduce duplication of common + * code amongst the many platform-specific PCI support code files. + * + * Platform-specific files are expected to provide: + * pcibios_fixup_bus() + * pcibios_init() + * pcibios_setup() + * pcibios_fixup_pbus_ranges() + */ + +#include +#include +#include + +void +pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + u32 new, check; + int reg; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4*resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + new |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* Somebody might have asked allocation of a non-standard resource */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + */ +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + if (!(mask & (1 << idx))) + continue; + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +/* + * If we set up a device for bus mastering, we need to check and set + * the latency timer as it may not be properly set. + */ +unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} diff -urN linux-2.4.21/arch/sh64/kernel/process.c linux-2.4.22/arch/sh64/kernel/process.c --- linux-2.4.21/arch/sh64/kernel/process.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,939 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/process.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 Paul Mundt + * + * Started from SH3/4 version: + * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima + * + * In turn started from i386 version: + * Copyright (C) 1995 Linus Torvalds + * + */ + +/* + * This file handles the architecture-dependent parts of process handling.. + */ + +/* Temporary flags/tests. All to be removed/undefined. BEGIN */ +#define IDLE_TRACE +#define VM_SHOW_TABLES +#define VM_TEST_FAULT +#define VM_TEST_RTLBMISS +#define VM_TEST_WTLBMISS + +#undef VM_SHOW_TABLES +#undef IDLE_TRACE +/* Temporary flags/tests. All to be removed/undefined. END */ + +#define __KERNEL_SYSCALLS__ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include /* includes also */ +#include +#include +#include + +#include + +struct task_struct *last_task_used_math = NULL; + +#ifdef IDLE_TRACE +#ifdef VM_SHOW_TABLES +/* For testing */ +static void print_PTE(long base) +{ + int i, skip=0; + long long x, y, *p = (long long *) base; + + for (i=0; i< 512; i++, p++){ + if (*p == 0) { + if (!skip) { + skip++; + printk("(0s) "); + } + } else { + skip=0; + x = (*p) >> 32; + y = (*p) & 0xffffffff; + printk("%08Lx%08Lx ", x, y); + if (!((i+1)&0x3)) printk("\n"); + } + } +} + +/* For testing */ +static void print_DIR(long base) +{ + int i, skip=0; + long *p = (long *) base; + + for (i=0; i< 512; i++, p++){ + if (*p == 0) { + if (!skip) { + skip++; + printk("(0s) "); + } + } else { + skip=0; + printk("%08lx ", *p); + if (!((i+1)&0x7)) printk("\n"); + } + } +} + +/* For testing */ +static void print_vmalloc_first_tables(void) +{ + +#define PRESENT 0x800 /* Bit 11 */ + + /* + * Do it really dirty by looking at raw addresses, + * raw offsets, no types. If we used pgtable/pgalloc + * macros/definitions we could hide potential bugs. + * + * Note that pointers are 32-bit for CDC. + */ + long pgdt, pmdt, ptet; + + pgdt = (long) &swapper_pg_dir; + printk("-->PGD (0x%08lx):\n", pgdt); + print_DIR(pgdt); + printk("\n"); + + /* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */ + pgdt += 4; + pmdt = (long) (* (long *) pgdt); + if (!(pmdt & PRESENT)) { + printk("No PMD\n"); + return; + } else pmdt &= 0xfffff000; + + printk("-->PMD (0x%08lx):\n", pmdt); + print_DIR(pmdt); + printk("\n"); + + /* Get the pmdt displacement for 0xc0000000 */ + pmdt += 2048; + + /* just look at first two address ranges ... */ + /* ... 0xc0000000 ... */ + ptet = (long) (* (long *) pmdt); + if (!(ptet & PRESENT)) { + printk("No PTE0\n"); + return; + } else ptet &= 0xfffff000; + + printk("-->PTE0 (0x%08lx):\n", ptet); + print_PTE(ptet); + printk("\n"); + + /* ... 0xc0001000 ... */ + ptet += 4; + if (!(ptet & PRESENT)) { + printk("No PTE1\n"); + return; + } else ptet &= 0xfffff000; + printk("-->PTE1 (0x%08lx):\n", ptet); + print_PTE(ptet); + printk("\n"); +} +#else +#define print_vmalloc_first_tables() +#endif /* VM_SHOW_TABLES */ + +static void test_VM(void) +{ + void *a, *b, *c; + +#ifdef VM_SHOW_TABLES + printk("Initial PGD/PMD/PTE\n"); +#endif + print_vmalloc_first_tables(); + + printk("Allocating 2 bytes\n"); + a = vmalloc(2); + print_vmalloc_first_tables(); + + printk("Allocating 4100 bytes\n"); + b = vmalloc(4100); + print_vmalloc_first_tables(); + + printk("Allocating 20234 bytes\n"); + c = vmalloc(20234); + print_vmalloc_first_tables(); + +#ifdef VM_TEST_FAULT + /* Here you may want to fault ! */ + +#ifdef VM_TEST_RTLBMISS + printk("Ready to fault upon read.\n"); + if (* (char *) a) { + printk("RTLBMISSed on area a !\n"); + } + printk("RTLBMISSed on area a !\n"); +#endif + +#ifdef VM_TEST_WTLBMISS + printk("Ready to fault upon write.\n"); + *((char *) b) = 'L'; + printk("WTLBMISSed on area b !\n"); +#endif + +#endif /* VM_TEST_FAULT */ + + printk("Deallocating the 4100 byte chunk\n"); + vfree(b); + print_vmalloc_first_tables(); + + printk("Deallocating the 2 byte chunk\n"); + vfree(a); + print_vmalloc_first_tables(); + + printk("Deallocating the last chunk\n"); + vfree(c); + print_vmalloc_first_tables(); +} + +extern unsigned long volatile jiffies; +int once = 0; +unsigned long old_jiffies; +int pid = -1, pgid = -1; + +void idle_trace(void) +{ + + _syscall0(int, getpid) + _syscall1(int, getpgid, int, pid) + + if (!once) { + /* VM allocation/deallocation simple test */ + test_VM(); + pid = getpid(); + + printk("Got all through to Idle !!\n"); + printk("I'm now going to loop forever ...\n"); + printk("Any ! below is a timer tick.\n"); + printk("Any . below is a getpgid system call from pid = %d.\n", pid); + + + old_jiffies = jiffies; + once++; + } + + if (old_jiffies != jiffies) { + old_jiffies = jiffies - old_jiffies; + switch (old_jiffies) { + case 1: + printk("!"); + break; + case 2: + printk("!!"); + break; + case 3: + printk("!!!"); + break; + case 4: + printk("!!!!"); + break; + default: + printk("(%d!)", (int) old_jiffies); + } + old_jiffies = jiffies; + } + pgid = getpgid(pid); + printk("."); +} +#else +#define idle_trace() do { } while (0) +#endif /* IDLE_TRACE */ + +static int hlt_counter = 1; + +#define HARD_IDLE_TIMEOUT (HZ / 3) + +void disable_hlt(void) +{ + hlt_counter++; +} + +void enable_hlt(void) +{ + hlt_counter--; +} + +static int __init nohlt_setup(char *__unused) +{ + hlt_counter = 1; + return 1; +} + +static int __init hlt_setup(char *__unused) +{ + hlt_counter = 0; + return 1; +} + +__setup("nohlt", nohlt_setup); +__setup("hlt", hlt_setup); + +static inline void hlt(void) +{ + if (hlt_counter) + return; + + /* + * FIXME: Is there any reason why we can't just do a "sleep" + * instead of this crap? + */ + __asm__ __volatile__ ( + ".int %0\n\t" + : /* no outputs */ + : "g" (le32_to_cpu(0x6ff7fff0)) + : "memory" + ); +} + +/* + * The idle loop on a uniprocessor SH.. + */ +void cpu_idle(void *unused) +{ + /* endless idle loop with no priority at all */ + init_idle(); + current->nice = 20; + current->counter = -100; + + while (1) { + while (!current->need_resched) { + if (hlt_counter) + continue; + __sti(); + idle_trace(); + hlt(); + } + schedule(); + check_pgt_cache(); + } +} + +void machine_restart(char * __unused) +{ + extern void phys_stext(void); + + phys_stext(); +} + +void machine_halt(void) +{ + for (;;); +} + +void machine_power_off(void) +{ + enter_deep_standby(); +} + +void show_regs(struct pt_regs * regs) +{ + unsigned long long ah, al, bh, bl, ch, cl; + + printk("\n"); + + ah = (regs->pc) >> 32; + al = (regs->pc) & 0xffffffff; + bh = (regs->regs[18]) >> 32; + bl = (regs->regs[18]) & 0xffffffff; + ch = (regs->regs[15]) >> 32; + cl = (regs->regs[15]) & 0xffffffff; + printk("PC : %08Lx%08Lx LINK: %08Lx%08Lx SP : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->sr) >> 32; + al = (regs->sr) & 0xffffffff; + asm volatile ("getcon " __c13 ", %0" : "=r" (bh)); + asm volatile ("getcon " __c13 ", %0" : "=r" (bl)); + bh = (bh) >> 32; + bl = (bl) & 0xffffffff; + asm volatile ("getcon " __c17 ", %0" : "=r" (ch)); + asm volatile ("getcon " __c17 ", %0" : "=r" (cl)); + ch = (ch) >> 32; + cl = (cl) & 0xffffffff; + printk("SR : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[0]) >> 32; + al = (regs->regs[0]) & 0xffffffff; + bh = (regs->regs[1]) >> 32; + bl = (regs->regs[1]) & 0xffffffff; + ch = (regs->regs[2]) >> 32; + cl = (regs->regs[2]) & 0xffffffff; + printk("R0 : %08Lx%08Lx R1 : %08Lx%08Lx R2 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[3]) >> 32; + al = (regs->regs[3]) & 0xffffffff; + bh = (regs->regs[4]) >> 32; + bl = (regs->regs[4]) & 0xffffffff; + ch = (regs->regs[5]) >> 32; + cl = (regs->regs[5]) & 0xffffffff; + printk("R3 : %08Lx%08Lx R4 : %08Lx%08Lx R5 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[6]) >> 32; + al = (regs->regs[6]) & 0xffffffff; + bh = (regs->regs[7]) >> 32; + bl = (regs->regs[7]) & 0xffffffff; + ch = (regs->regs[8]) >> 32; + cl = (regs->regs[8]) & 0xffffffff; + printk("R6 : %08Lx%08Lx R7 : %08Lx%08Lx R8 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[9]) >> 32; + al = (regs->regs[9]) & 0xffffffff; + bh = (regs->regs[10]) >> 32; + bl = (regs->regs[10]) & 0xffffffff; + ch = (regs->regs[11]) >> 32; + cl = (regs->regs[11]) & 0xffffffff; + printk("R9 : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[12]) >> 32; + al = (regs->regs[12]) & 0xffffffff; + bh = (regs->regs[13]) >> 32; + bl = (regs->regs[13]) & 0xffffffff; + ch = (regs->regs[14]) >> 32; + cl = (regs->regs[14]) & 0xffffffff; + printk("R12 : %08Lx%08Lx R13 : %08Lx%08Lx R14 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[16]) >> 32; + al = (regs->regs[16]) & 0xffffffff; + bh = (regs->regs[17]) >> 32; + bl = (regs->regs[17]) & 0xffffffff; + ch = (regs->regs[19]) >> 32; + cl = (regs->regs[19]) & 0xffffffff; + printk("R16 : %08Lx%08Lx R17 : %08Lx%08Lx R19 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[20]) >> 32; + al = (regs->regs[20]) & 0xffffffff; + bh = (regs->regs[21]) >> 32; + bl = (regs->regs[21]) & 0xffffffff; + ch = (regs->regs[22]) >> 32; + cl = (regs->regs[22]) & 0xffffffff; + printk("R20 : %08Lx%08Lx R21 : %08Lx%08Lx R22 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[23]) >> 32; + al = (regs->regs[23]) & 0xffffffff; + bh = (regs->regs[24]) >> 32; + bl = (regs->regs[24]) & 0xffffffff; + ch = (regs->regs[25]) >> 32; + cl = (regs->regs[25]) & 0xffffffff; + printk("R23 : %08Lx%08Lx R24 : %08Lx%08Lx R25 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[26]) >> 32; + al = (regs->regs[26]) & 0xffffffff; + bh = (regs->regs[27]) >> 32; + bl = (regs->regs[27]) & 0xffffffff; + ch = (regs->regs[28]) >> 32; + cl = (regs->regs[28]) & 0xffffffff; + printk("R26 : %08Lx%08Lx R27 : %08Lx%08Lx R28 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[29]) >> 32; + al = (regs->regs[29]) & 0xffffffff; + bh = (regs->regs[30]) >> 32; + bl = (regs->regs[30]) & 0xffffffff; + ch = (regs->regs[31]) >> 32; + cl = (regs->regs[31]) & 0xffffffff; + printk("R29 : %08Lx%08Lx R30 : %08Lx%08Lx R31 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[32]) >> 32; + al = (regs->regs[32]) & 0xffffffff; + bh = (regs->regs[33]) >> 32; + bl = (regs->regs[33]) & 0xffffffff; + ch = (regs->regs[34]) >> 32; + cl = (regs->regs[34]) & 0xffffffff; + printk("R32 : %08Lx%08Lx R33 : %08Lx%08Lx R34 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[35]) >> 32; + al = (regs->regs[35]) & 0xffffffff; + bh = (regs->regs[36]) >> 32; + bl = (regs->regs[36]) & 0xffffffff; + ch = (regs->regs[37]) >> 32; + cl = (regs->regs[37]) & 0xffffffff; + printk("R35 : %08Lx%08Lx R36 : %08Lx%08Lx R37 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[38]) >> 32; + al = (regs->regs[38]) & 0xffffffff; + bh = (regs->regs[39]) >> 32; + bl = (regs->regs[39]) & 0xffffffff; + ch = (regs->regs[40]) >> 32; + cl = (regs->regs[40]) & 0xffffffff; + printk("R38 : %08Lx%08Lx R39 : %08Lx%08Lx R40 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[41]) >> 32; + al = (regs->regs[41]) & 0xffffffff; + bh = (regs->regs[42]) >> 32; + bl = (regs->regs[42]) & 0xffffffff; + ch = (regs->regs[43]) >> 32; + cl = (regs->regs[43]) & 0xffffffff; + printk("R41 : %08Lx%08Lx R42 : %08Lx%08Lx R43 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[44]) >> 32; + al = (regs->regs[44]) & 0xffffffff; + bh = (regs->regs[45]) >> 32; + bl = (regs->regs[45]) & 0xffffffff; + ch = (regs->regs[46]) >> 32; + cl = (regs->regs[46]) & 0xffffffff; + printk("R44 : %08Lx%08Lx R45 : %08Lx%08Lx R46 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[47]) >> 32; + al = (regs->regs[47]) & 0xffffffff; + bh = (regs->regs[48]) >> 32; + bl = (regs->regs[48]) & 0xffffffff; + ch = (regs->regs[49]) >> 32; + cl = (regs->regs[49]) & 0xffffffff; + printk("R47 : %08Lx%08Lx R48 : %08Lx%08Lx R49 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[50]) >> 32; + al = (regs->regs[50]) & 0xffffffff; + bh = (regs->regs[51]) >> 32; + bl = (regs->regs[51]) & 0xffffffff; + ch = (regs->regs[52]) >> 32; + cl = (regs->regs[52]) & 0xffffffff; + printk("R50 : %08Lx%08Lx R51 : %08Lx%08Lx R52 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[53]) >> 32; + al = (regs->regs[53]) & 0xffffffff; + bh = (regs->regs[54]) >> 32; + bl = (regs->regs[54]) & 0xffffffff; + ch = (regs->regs[55]) >> 32; + cl = (regs->regs[55]) & 0xffffffff; + printk("R53 : %08Lx%08Lx R54 : %08Lx%08Lx R55 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[56]) >> 32; + al = (regs->regs[56]) & 0xffffffff; + bh = (regs->regs[57]) >> 32; + bl = (regs->regs[57]) & 0xffffffff; + ch = (regs->regs[58]) >> 32; + cl = (regs->regs[58]) & 0xffffffff; + printk("R56 : %08Lx%08Lx R57 : %08Lx%08Lx R58 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[59]) >> 32; + al = (regs->regs[59]) & 0xffffffff; + bh = (regs->regs[60]) >> 32; + bl = (regs->regs[60]) & 0xffffffff; + ch = (regs->regs[61]) >> 32; + cl = (regs->regs[61]) & 0xffffffff; + printk("R59 : %08Lx%08Lx R60 : %08Lx%08Lx R61 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[62]) >> 32; + al = (regs->regs[62]) & 0xffffffff; + bh = (regs->tregs[0]) >> 32; + bl = (regs->tregs[0]) & 0xffffffff; + ch = (regs->tregs[1]) >> 32; + cl = (regs->tregs[1]) & 0xffffffff; + printk("R62 : %08Lx%08Lx T0 : %08Lx%08Lx T1 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->tregs[2]) >> 32; + al = (regs->tregs[2]) & 0xffffffff; + bh = (regs->tregs[3]) >> 32; + bl = (regs->tregs[3]) & 0xffffffff; + ch = (regs->tregs[4]) >> 32; + cl = (regs->tregs[4]) & 0xffffffff; + printk("T2 : %08Lx%08Lx T3 : %08Lx%08Lx T4 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->tregs[5]) >> 32; + al = (regs->tregs[5]) & 0xffffffff; + bh = (regs->tregs[6]) >> 32; + bl = (regs->tregs[6]) & 0xffffffff; + ch = (regs->tregs[7]) >> 32; + cl = (regs->tregs[7]) & 0xffffffff; + printk("T5 : %08Lx%08Lx T6 : %08Lx%08Lx T7 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + /* + * If we're in kernel mode, dump the stack too.. + */ + if (!user_mode(regs)) { + extern void show_task(unsigned long *sp); + unsigned long sp = regs->regs[15] & 0xffffffff; + + show_task((unsigned long *)sp); + } +} + +struct task_struct * alloc_task_struct(void) +{ + /* Get task descriptor pages */ + return (struct task_struct *) + __get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE)); +} + +void free_task_struct(struct task_struct *p) +{ + free_pages((unsigned long) p, get_order(THREAD_SIZE)); +} + +/* + * Create a kernel thread + */ + +/* + * This is the mechanism for creating a new kernel thread. + * + * NOTE! Only a kernel-only process(ie the swapper or direct descendants + * who haven't done an "execve()") should use this: it will work within + * a system call from a "real" process, but the process memory space will + * not be free'd until both the parent and the child have exited. + */ +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + /* A bit less processor dependent than older sh ... */ + + unsigned int reply; + +static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp) +static __inline__ _syscall1(int,exit,int,ret) + + reply = clone(flags | CLONE_VM, 0); + if (!reply) { + /* Child */ + reply = exit(fn(arg)); + } + + return reply; +} + +/* + * Free current thread data structures etc.. + */ +void exit_thread(void) +{ + /* See arch/sparc/kernel/process.c for the precedent for doing this -- RPC. + + The SH-5 FPU save/restore approach relies on last_task_used_math + pointing to a live task_struct. When another task tries to use the + FPU for the 1st time, the FPUDIS trap handling (see + arch/sh64/kernel/fpu.c) will save the existing FPU state to the + FP regs field within last_task_used_math before re-loading the new + task's FPU state (or initialising it if the FPU has been used + before). So if last_task_used_math is stale, and its page has already been + re-allocated for another use, the consequences are rather grim. Unless we + null it here, there is no other path through which it would get safely + nulled. */ + +#ifndef CONFIG_NOFPU_SUPPORT + if (last_task_used_math == current) { + last_task_used_math = NULL; + } +#endif +} + +void flush_thread(void) +{ + + /* As far as I can tell, this function isn't actually called from anywhere. + So why does it have a non-null body for most architectures?? -- RPC */ + /* Look closer, this is used in fs/exec.c by flush_old_exec() which is + used by binfmt_elf and friends to remove leftover traces of the + previously running executable. -- PFM */ +#ifndef CONFIG_NOFPU_SUPPORT + if (last_task_used_math == current) { + last_task_used_math = NULL; + } +#endif + + /* if we are a kernel thread, about to change to user thread, + * update kreg + */ + if(current->thread.kregs==&fake_swapper_regs) { + current->thread.kregs= + ((struct pt_regs *)(THREAD_SIZE + (unsigned long) current) - 1); + } +} + +void release_thread(struct task_struct *dead_task) +{ + /* do nothing */ +} + +/* Fill in the fpu structure for a core dump.. */ +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) +{ +#ifndef CONFIG_NOFPU_SUPPORT + int fpvalid; + struct task_struct *tsk = current; + + fpvalid = tsk->used_math; + if (fpvalid) { + if (current == last_task_used_math) { + grab_fpu(); + fpsave(&tsk->thread.fpu.hard); + release_fpu(); + last_task_used_math = 0; + regs->sr |= SR_FD; + } + + memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); + } + + return fpvalid; +#else + return 0; /* Task didn't use the fpu at all. */ +#endif +} + +asmlinkage void ret_from_fork(void); + +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, + struct task_struct *p, struct pt_regs *regs) +{ + struct pt_regs *childregs; + unsigned long long se; /* Sign extension */ +#ifndef CONFIG_NOFPU_SUPPORT + if(last_task_used_math == current) { + grab_fpu(); + fpsave(¤t->thread.fpu.hard); + release_fpu(); + last_task_used_math = NULL; + regs->sr |= SR_FD; + } +#endif + childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1; + *childregs = *regs; + + if (user_mode(regs)) { + childregs->regs[15] = usp; + p->thread.kregs = childregs; + } else { + childregs->regs[15] = (unsigned long)p+THREAD_SIZE; + p->thread.kregs = &fake_swapper_regs; + } + + childregs->regs[9] = 0; /* Set return value for child */ + childregs->sr |= SR_FD; /* Invalidate FPU flag */ + + p->thread.sp = (unsigned long) childregs; + p->thread.pc = (unsigned long) ret_from_fork; + + /* + * Sign extend the edited stack. + * Note that thread.pc and thread.pc will stay + * 32-bit wide and context switch must take care + * of NEFF sign extension. + */ + + se = childregs->regs[15]; + se = (se & NEFF_SIGN) ? (se | NEFF_MASK) : se; + childregs->regs[15] = se; + + return 0; +} + +/* + * fill in the user structure for a core dump.. + */ +void dump_thread(struct pt_regs * regs, struct user * dump) +{ + dump->magic = CMAGIC; + dump->start_code = current->mm->start_code; + dump->start_data = current->mm->start_data; + dump->start_stack = regs->regs[15] & ~(PAGE_SIZE - 1); + dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT; + dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT; + dump->u_ssize = (current->mm->start_stack - dump->start_stack + + PAGE_SIZE - 1) >> PAGE_SHIFT; + /* Debug registers will come here. */ + + dump->regs = *regs; + + dump->u_fpvalid = dump_fpu(regs, &dump->fpu); +} + +/* + * switch_to(x,y) should switch tasks from x to y. + * + */ +struct task_struct * __switch_to(struct task_struct *prev, struct task_struct *next) +{ + /* + * Restore the kernel mode register + * KCR0 = __c17 + */ + asm volatile("putcon %0, " __c17 "\n" + : /* no output */ + :"r" (next)); + return prev; + +} + +asmlinkage int sys_fork(unsigned long r2, unsigned long r3, + unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs *pregs) +{ + return do_fork(SIGCHLD, pregs->regs[15], pregs,0); +} + +asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, + unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs *pregs) +{ + if (!newsp) + newsp = pregs->regs[15]; + return do_fork(clone_flags, newsp, pregs,0); +} + +/* + * This is trivial, and on the face of it looks like it + * could equally well be done in user mode. + * + * Not so, for quite unobvious reasons - register pressure. + * In user mode vfork() cannot have a stack frame, and if + * done by calling the "clone()" system call directly, you + * do not have enough call-clobbered registers to hold all + * the information you need. + */ +asmlinkage int sys_vfork(unsigned long r2, unsigned long r3, + unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs *pregs) +{ + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, pregs->regs[15], pregs,0); +} + +/* + * sys_execve() executes a new program. + */ +asmlinkage int sys_execve(char *ufilename, char **uargv, + char **uenvp, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs *pregs) +{ + int error; + char *filename; + + lock_kernel(); + filename = getname(ufilename); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + + error = do_execve(filename, uargv, uenvp, pregs); + if (error == 0) + current->ptrace &= ~PT_DTRACE; + putname(filename); +out: + unlock_kernel(); + return error; +} + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +extern void interruptible_sleep_on(wait_queue_head_t *q); + +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define mid_sched ((unsigned long) interruptible_sleep_on) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long schedule_frame; + unsigned long pc; + + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + /* + * The same comment as on the Alpha applies here, too ... + */ + pc = thread_saved_pc(&p->thread); + + if (pc >= first_sched && pc < last_sched) { + + schedule_frame = (long) p->thread.sp; + + /* Should we unwind schedule_timeout() ? */ + if (pc < mid_sched) + /* according to disasm: + ** 48 bytes in case of RH toolchain + */ + schedule_frame += 48; + + /* + ** Unwind schedule(). According to disasm: + ** 72 bytes in case of RH toolchain + ** plus 304 bytes of switch_to additional frame. + */ + schedule_frame += 72 + 304; + +#ifdef CS_SAVE_ALL + schedule_frame += 256; +#endif + /* + * schedule_frame now according to SLEEP_ON_VAR. + * Bad thing is that we have no trace of the waiting + * address (the classical WCHAN). SLEEP_ON_VAR should + * have saved q. From the linked list only we can't get + * the object and first parameter is not saved on stack + * by the ABI. The best we can tell is who called the + * *sleep_on* by returning LINK, which is saved at + * offset 64 on all flavours. + */ + return (unsigned long)((unsigned long *)schedule_frame)[16]; + } + return pc; +} + diff -urN linux-2.4.21/arch/sh64/kernel/ptrace.c linux-2.4.22/arch/sh64/kernel/ptrace.c --- linux-2.4.21/arch/sh64/kernel/ptrace.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/ptrace.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,374 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/ptrace.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Started from SH3/4 version: + * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka + * + * Original x86 implementation: + * By Ross Biro 1/23/92 + * edited by Linus Torvalds + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* This mask defines the bits of the SR which the user is not allowed to + change, which are everything except S, Q, M, PR, SZ, FR. */ +#define SR_MASK (0xffff8cfd) + +/* + * does not yet catch signals sent when the child dies. + * in exit.c or in signal.c. + */ + +/* + * This routine will get a word off of the process kernel stack. + */ +static inline int get_stack_long(struct task_struct *task, int offset) +{ + unsigned char *stack; + + stack = (unsigned char *)(task->thread.kregs); + stack += offset; + return (*((int *)stack)); +} + +static inline unsigned long +get_fpu_long(struct task_struct *task, unsigned long addr) +{ + unsigned long tmp; + struct pt_regs *regs; + regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1; + + if (!task->used_math) { + if (addr == offsetof(struct user_fpu_struct, fpscr)) { + tmp = FPSCR_INIT; + } else { + tmp = 0xffffffffUL; /* matches initial value in fpu.c */ + } + return tmp; + } + + if (last_task_used_math == task) { + grab_fpu(); + fpsave(&task->thread.fpu.hard); + release_fpu(); + last_task_used_math = 0; + regs->sr |= SR_FD; + } + + tmp = ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)]; + return tmp; +} + +/* + * This routine will put a word on the process kernel stack. + */ +static inline int put_stack_long(struct task_struct *task, int offset, + unsigned long data) +{ + unsigned char *stack; + + stack = (unsigned char *)(task->thread.kregs); + stack += offset; + *(unsigned long *) stack = data; + return 0; +} + +static inline int +put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data) +{ + struct pt_regs *regs; + + regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1; + + if (!task->used_math) { + fpinit(&task->thread.fpu.hard); + task->used_math = 1; + } else if (last_task_used_math == task) { + grab_fpu(); + fpsave(&task->thread.fpu.hard); + release_fpu(); + last_task_used_math = 0; + regs->sr |= SR_FD; + } + + ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)] = data; + return 0; +} + +asmlinkage int sys_ptrace(long request, long pid, long addr, long data) +{ + struct task_struct *child, *tsk = current; + int ret; + + lock_kernel(); + ret = -EPERM; + if (request == PTRACE_TRACEME) { + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out; + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; + ret = 0; + goto out; + } + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) + goto out; + + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ + goto out_tsk; + + if (request == PTRACE_ATTACH) { + ret = ptrace_attach(child); + goto out_tsk; + } + ret = -ESRCH; + if (!(child->ptrace & PT_PTRACED)) + goto out_tsk; + if (child->state != TASK_STOPPED) { + if (request != PTRACE_KILL) + goto out_tsk; + } + if (child->p_pptr != tsk) + goto out_tsk; + switch (request) { + /* when I and D space are separate, these will need to be fixed. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: { + unsigned long tmp; + int copied; + + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); + ret = -EIO; + if (copied != sizeof(tmp)) + break; + ret = put_user(tmp,(unsigned long *) data); + break; + } + + /* read the word at location addr in the USER area. */ + case PTRACE_PEEKUSR: { + unsigned long tmp; + + ret = -EIO; + if ((addr & 3) || addr < 0) + break; + + if (addr < sizeof(struct pt_regs)) + tmp = get_stack_long(child, addr); + else if ((addr >= offsetof(struct user, fpu)) && + (addr < offsetof(struct user, u_fpvalid))) { + tmp = get_fpu_long(child, addr - offsetof(struct user, fpu)); + } else if (addr == offsetof(struct user, u_fpvalid)) { + tmp = child->used_math; + } else { + break; + } + ret = put_user(tmp, (unsigned long *)data); + break; + } + + /* when I and D space are separate, this will have to be fixed. */ + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + ret = 0; + if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) + break; + ret = -EIO; + break; + + case PTRACE_POKEUSR: + /* write the word at location addr in the USER area. We must + disallow any changes to certain SR bits or u_fpvalid, since + this could crash the kernel or result in a security + loophole. */ + ret = -EIO; + if ((addr & 3) || addr < 0) + break; + + if (addr < sizeof(struct pt_regs)) { + /* Ignore change of top 32 bits of SR */ + if (addr == offsetof (struct pt_regs, sr)+4) + { + ret = 0; + break; + } + /* If lower 32 bits of SR, ignore non-user bits */ + if (addr == offsetof (struct pt_regs, sr)) + { + long cursr = get_stack_long(child, addr); + data &= ~(SR_MASK); + data |= (cursr & SR_MASK); + } + ret = put_stack_long(child, addr, data); + } + else if ((addr >= offsetof(struct user, fpu)) && + (addr < offsetof(struct user, u_fpvalid))) { + ret = put_fpu_long(child, addr - offsetof(struct user, fpu), data); + } + break; + + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: { /* restart after signal. */ + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + if (request == PTRACE_SYSCALL) + child->ptrace |= PT_TRACESYS; + else + child->ptrace &= ~PT_TRACESYS; + child->exit_code = data; + wake_up_process(child); + ret = 0; + break; + } + +/* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + case PTRACE_KILL: { + ret = 0; + if (child->state == TASK_ZOMBIE) /* already dead */ + break; + child->exit_code = SIGKILL; + wake_up_process(child); + break; + } + + case PTRACE_SINGLESTEP: { /* set the trap flag. */ + struct pt_regs *regs; + + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + child->ptrace &= ~PT_TRACESYS; + if ((child->ptrace & PT_DTRACE) == 0) { + /* Spurious delayed TF traps may occur */ + child->ptrace |= PT_DTRACE; + } + + regs = child->thread.kregs; + + regs->sr |= SR_SSTEP; /* auto-resetting upon exception */ + + child->exit_code = data; + /* give it a chance to run. */ + wake_up_process(child); + ret = 0; + break; + } + + case PTRACE_DETACH: /* detach a process that was attached. */ + ret = ptrace_detach(child, data); + break; + + case PTRACE_SETOPTIONS: { + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + + + + ret = 0; + break; + } + default: + ret = -EIO; + break; + } +out_tsk: + free_task_struct(child); +out: + unlock_kernel(); + return ret; +} + +asmlinkage void syscall_trace(void) +{ + struct task_struct *tsk = current; + + if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYS)) + != (PT_PTRACED|PT_TRACESYS)) + return; + tsk->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0); + tsk->state = TASK_STOPPED; + notify_parent(tsk, SIGCHLD); + schedule(); + /* + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl + */ + if (tsk->exit_code) { + send_sig(tsk->exit_code, tsk, 1); + tsk->exit_code = 0; + } +} + +/* Called with interrupts disabled */ +asmlinkage void do_single_step(unsigned long long vec, struct pt_regs *regs) +{ + /* This is called after a single step exception (DEBUGSS). + There is no need to change the PC, as it is a post-execution + exception, as entry.S does not do anything to the PC for DEBUGSS. + We need to clear the Single Step setting in SR to avoid + continually stepping. */ + __sti(); + regs->sr &= ~SR_SSTEP; + force_sig(SIGTRAP, current); +} + +/* Called with interrupts disabled */ +asmlinkage void do_software_break_point(unsigned long long vec, + struct pt_regs *regs) +{ + /* We need to forward step the PC, to counteract the backstep done + in signal.c. */ + __sti(); + force_sig(SIGTRAP, current); + regs->pc += 4; +} + + +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure single step bits etc are not set. + */ +void ptrace_disable(struct task_struct *child) +{ + /* nothing to do.. */ +} diff -urN linux-2.4.21/arch/sh64/kernel/semaphore.c linux-2.4.22/arch/sh64/kernel/semaphore.c --- linux-2.4.21/arch/sh64/kernel/semaphore.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/semaphore.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,137 @@ +/* + * Just taken from alpha implementation. + * This can't work well, perhaps. + */ +/* + * Generic semaphore code. Buyer beware. Do your own + * specific changes in + */ + +#include +#include +#include +#include + +spinlock_t semaphore_wake_lock; + +/* + * Semaphores are implemented using a two-way counter: + * The "count" variable is decremented for each process + * that tries to sleep, while the "waking" variable is + * incremented when the "up()" code goes to wake up waiting + * processes. + * + * Notably, the inline "up()" and "down()" functions can + * efficiently test if they need to do any extra work (up + * needs to do something only if count was negative before + * the increment operation. + * + * waking_non_zero() (from asm/semaphore.h) must execute + * atomically. + * + * When __up() is called, the count was negative before + * incrementing it, and we need to wake up somebody. + * + * This routine adds one to the count of processes that need to + * wake up and exit. ALL waiting processes actually wake up but + * only the one that gets to the "waking" field first will gate + * through and acquire the semaphore. The others will go back + * to sleep. + * + * Note that these functions are only called when there is + * contention on the lock, and as such all this is the + * "non-critical" part of the whole semaphore business. The + * critical part is the inline stuff in + * where we want to avoid any extra jumps and calls. + */ +void __up(struct semaphore *sem) +{ + wake_one_more(sem); + wake_up(&sem->wait); +} + +/* + * Perform the "down" function. Return zero for semaphore acquired, + * return negative for signalled out of the function. + * + * If called from __down, the return is ignored and the wait loop is + * not interruptible. This means that a task waiting on a semaphore + * using "down()" cannot be killed until someone does an "up()" on + * the semaphore. + * + * If called from __down_interruptible, the return value gets checked + * upon return. If the return value is negative then the task continues + * with the negative value in the return register (it can be tested by + * the caller). + * + * Either form may be used in conjunction with "up()". + * + */ + +#define DOWN_VAR \ + struct task_struct *tsk = current; \ + wait_queue_t wait; \ + init_waitqueue_entry(&wait, tsk); + +#define DOWN_HEAD(task_state) \ + \ + \ + tsk->state = (task_state); \ + add_wait_queue(&sem->wait, &wait); \ + \ + /* \ + * Ok, we're set up. sem->count is known to be less than zero \ + * so we must wait. \ + * \ + * We can let go the lock for purposes of waiting. \ + * We re-acquire it after awaking so as to protect \ + * all semaphore operations. \ + * \ + * If "up()" is called before we call waking_non_zero() then \ + * we will catch it right away. If it is called later then \ + * we will have to go through a wakeup cycle to catch it. \ + * \ + * Multiple waiters contend for the semaphore lock to see \ + * who gets to gate through and who has to wait some more. \ + */ \ + for (;;) { + +#define DOWN_TAIL(task_state) \ + tsk->state = (task_state); \ + } \ + tsk->state = TASK_RUNNING; \ + remove_wait_queue(&sem->wait, &wait); + +void __down(struct semaphore * sem) +{ + DOWN_VAR + DOWN_HEAD(TASK_UNINTERRUPTIBLE) + if (waking_non_zero(sem)) + break; + schedule(); + DOWN_TAIL(TASK_UNINTERRUPTIBLE) +} + +int __down_interruptible(struct semaphore * sem) +{ + int ret = 0; + DOWN_VAR + DOWN_HEAD(TASK_INTERRUPTIBLE) + + ret = waking_non_zero_interruptible(sem, tsk); + if (ret) + { + if (ret == 1) + /* ret != 0 only if we get interrupted -arca */ + ret = 0; + break; + } + schedule(); + DOWN_TAIL(TASK_INTERRUPTIBLE) + return ret; +} + +int __down_trylock(struct semaphore * sem) +{ + return waking_non_zero_trylock(sem); +} diff -urN linux-2.4.21/arch/sh64/kernel/setup.c linux-2.4.22/arch/sh64/kernel/setup.c --- linux-2.4.21/arch/sh64/kernel/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,362 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/setup.c + * + * SH-5 Arch Support + * + * This file handles the architecture-dependent parts of initialization + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * benedict.gaster@superh.com: 2nd May 2002 + * Modified to use the empty_zero_page to pass command line arguments. + * + * benedict.gaster@superh.com: 3rd May 2002 + * Added support for ramdisk, removing statically linked romfs at the same time. + * + * lethal@linux-sh.org: 15th May 2003 + * Added generic procfs cpuinfo reporting. Make boards just export their name. + * + * lethal@linux-sh.org: 25th May 2003 + * Added generic get_cpu_subtype() for subtype reporting from cpu_data->type. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_BLK_DEV_RAM +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_VT +#include +#endif + +struct screen_info screen_info; + +/* On a PC this would be initialised as a result of the BIOS detecting the + * mouse. */ +unsigned char aux_device_present = 0xaa; + +#ifdef CONFIG_BLK_DEV_RAM +extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ +extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ +extern int rd_image_start; /* starting block # of image */ +#endif + +extern int root_mountflags; +extern int _text, _etext, _edata, _end; +extern char *get_system_type(void); +extern void platform_setup(void); +extern void platform_monitor(void); +extern void platform_reserve(void); +extern int sh64_cache_init(void); +extern int sh64_tlb_init(void); + +#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_PROMPT_FLAG 0x8000 +#define RAMDISK_LOAD_FLAG 0x4000 + +#define PARAM ((unsigned char *)empty_zero_page) +#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) +#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) +#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008)) +#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c)) +#define INITRD_START (*(unsigned long *) (PARAM+0x010)) +#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) + +#define COMMAND_LINE ((char *) (PARAM+256)) +#define COMMAND_LINE_SIZE 256 + +static char command_line[COMMAND_LINE_SIZE] = { 0, }; + char saved_command_line[COMMAND_LINE_SIZE]; +unsigned long long memory_start = CONFIG_MEMORY_START; +unsigned long long memory_end = CONFIG_MEMORY_START + (CONFIG_MEMORY_SIZE_IN_MB * 1024 * 1024); + +struct sh_cpuinfo boot_cpu_data = { + .type = CPU_SH5_101, +}; + +static inline void parse_mem_cmdline (char ** cmdline_p) +{ + char c = ' ', *to = command_line, *from = COMMAND_LINE; + int len = 0; + + /* Save unparsed command line copy for /proc/cmdline */ + memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + + for (;;) { + /* + * "mem=XXX[kKmM]" defines a size of memory. + */ + if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + { + unsigned long mem_size; + + mem_size = memparse(from+4, &from); + memory_end = memory_start + mem_size; + } + } + c = *(from++); + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; + + *cmdline_p = command_line; +} + +void cpu_relax(void) +{ +} + +void __init setup_arch(char **cmdline_p) +{ + unsigned long bootmap_size, i; + unsigned long first_pfn, start_pfn, last_pfn, pages; + + /* + * Setup TLB mappings + */ + sh64_tlb_init(); + + /* + * Caches are already initialized by the time we get here, so we just + * fill in cpu_data info for the caches. + */ + sh64_cache_init(); + + platform_setup(); + platform_monitor(); + + ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); + +#ifdef CONFIG_BLK_DEV_RAM + rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; + rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); + rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); +#endif + + if (!MOUNT_ROOT_RDONLY) + root_mountflags &= ~MS_RDONLY; + init_mm.start_code = (unsigned long)&_text; + init_mm.end_code = (unsigned long) &_etext; + init_mm.end_data = (unsigned long) &_edata; + init_mm.brk = (unsigned long) &_end; + + code_resource.start = __pa(&_text); + code_resource.end = __pa(&_etext)-1; + data_resource.start = __pa(&_etext); + data_resource.end = __pa(&_edata)-1; + + parse_mem_cmdline(cmdline_p); + + /* + * Find the lowest and highest page frame numbers we have available + */ + first_pfn = PFN_DOWN(memory_start); + last_pfn = PFN_DOWN(memory_end); + pages = last_pfn - first_pfn; + + /* + * Partially used pages are not usable - thus + * we are rounding upwards: + */ + start_pfn = PFN_UP(__pa(&_end)); + /* + * Find a proper area for the bootmem bitmap. After this + * bootstrap step all allocations (until the page allocator + * is intact) must be done via bootmem_alloc(). + */ + bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, + first_pfn, + last_pfn); + /* + * Round it up. + */ + bootmap_size = PFN_PHYS(PFN_UP(bootmap_size)); + + /* + * Register fully available RAM pages with the bootmem allocator. + */ + free_bootmem(PFN_PHYS(first_pfn), PFN_PHYS(pages)); + + /* + * Reserve all kernel sections + bootmem bitmap + a guard page. + */ + reserve_bootmem(PFN_PHYS(first_pfn), + (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE) - PFN_PHYS(first_pfn)); + + /* + * Reserve platform dependent sections + */ + platform_reserve(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (LOADER_TYPE && INITRD_START) { + if (INITRD_START + INITRD_SIZE <= (PFN_PHYS(last_pfn))) { + reserve_bootmem(INITRD_START + __MEMORY_START, INITRD_SIZE); + + initrd_start = + (long) INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0; + + initrd_end = initrd_start + INITRD_SIZE; + } else { + printk("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + (long) INITRD_START + INITRD_SIZE, + PFN_PHYS(last_pfn)); + initrd_start = 0; + } + } +#endif + + /* + * Claim all RAM, ROM, and I/O resources. + */ + + /* Kernel RAM */ + request_resource(&iomem_resource, &code_resource); + request_resource(&iomem_resource, &data_resource); + + /* Other KRAM space */ + for (i = 0; i < STANDARD_KRAM_RESOURCES - 2; i++) + request_resource(&iomem_resource, + &platform_parms.kram_res_p[i]); + + /* XRAM space */ + for (i = 0; i < STANDARD_XRAM_RESOURCES; i++) + request_resource(&iomem_resource, + &platform_parms.xram_res_p[i]); + + /* ROM space */ + for (i = 0; i < STANDARD_ROM_RESOURCES; i++) + request_resource(&iomem_resource, + &platform_parms.rom_res_p[i]); + + /* I/O space */ + for (i = 0; i < STANDARD_IO_RESOURCES; i++) + request_resource(&ioport_resource, + &platform_parms.io_res_p[i]); + + +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif + + printk("Hardware FPU: %s\n", fpu_in_use ? "enabled" : "disabled"); + + paging_init(); +} + +void __xchg_called_with_bad_pointer(void) +{ + printk(KERN_EMERG "xchg() called with bad pointer !\n"); +} + +/* + * Get CPU information + */ +static const char *cpu_name[] = { + [CPU_SH5_101] "SH5-101", + [CPU_SH5_103] "SH5-103", + [CPU_SH_NONE] "Unknown", +}; + +const char *get_cpu_subtype(void) +{ + return cpu_name[boot_cpu_data.type]; +} + +#ifdef CONFIG_PROC_FS +static int show_cpuinfo(struct seq_file *m,void *v) +{ + unsigned int cpu = smp_processor_id(); + + if (!cpu) + seq_printf(m, "machine\t\t: %s\n", get_system_type()); + + seq_printf(m, "processor\t: %d\n", cpu); + seq_printf(m, "cpu family\t: SH-5\n"); + seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype()); + + seq_printf(m, "icache size\t: %dK-bytes\n", + (boot_cpu_data.icache.ways * + boot_cpu_data.icache.sets * + boot_cpu_data.icache.linesz) >> 10); + seq_printf(m, "dcache size\t: %dK-bytes\n", + (boot_cpu_data.dcache.ways * + boot_cpu_data.dcache.sets * + boot_cpu_data.dcache.linesz) >> 10); + seq_printf(m, "itlb entries\t: %d\n", boot_cpu_data.itlb.entries); + seq_printf(m, "dtlb entries\t: %d\n", boot_cpu_data.dtlb.entries); + +#define PRINT_CLOCK(name, value) \ + seq_printf(m, name " clock\t: %d.%02dMHz\n", \ + ((value) / 1000000), ((value) % 1000000)/10000) + + PRINT_CLOCK("cpu", boot_cpu_data.cpu_clock); + PRINT_CLOCK("bus", boot_cpu_data.bus_clock); + PRINT_CLOCK("module", boot_cpu_data.module_clock); + + seq_printf(m, "bogomips\t: %lu.%02lu\n\n", + (loops_per_jiffy*HZ+2500)/500000, + ((loops_per_jiffy*HZ+2500)/5000) % 100); + + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return (void*)(*pos == 0); +} +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + return NULL; +} +static void c_stop(struct seq_file *m, void *v) +{ +} +struct seq_operations cpuinfo_op = { + start: c_start, + next: c_next, + stop: c_stop, + show: show_cpuinfo, +}; +#endif /* CONFIG_PROC_FS */ diff -urN linux-2.4.21/arch/sh64/kernel/sh_ksyms.c linux-2.4.22/arch/sh64/kernel/sh_ksyms.c --- linux-2.4.21/arch/sh64/kernel/sh_ksyms.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/sh_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,93 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/sh_ksyms.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + */ + +#include + + +#if 0 +#ifdef CONFIG_MODVERSIONS +#define EXPORT_SYMTAB 1 +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void dump_thread(struct pt_regs *, struct user *); +extern int dump_fpu(elf_fpregset_t *); + +#if 0 +/* Not yet - there's no declaration of drive_info anywhere. */ +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) +extern struct drive_info_struct drive_info; +EXPORT_SYMBOL(drive_info); +#endif +#endif + +/* platform dependent support */ +EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(kernel_thread); + +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy); + +EXPORT_SYMBOL(strtok); +EXPORT_SYMBOL(strpbrk); +EXPORT_SYMBOL(strstr); + +#ifdef CONFIG_VT +EXPORT_SYMBOL(screen_info); +#endif + +EXPORT_SYMBOL_NOVERS(__down); +EXPORT_SYMBOL_NOVERS(__down_trylock); +EXPORT_SYMBOL_NOVERS(__up); +EXPORT_SYMBOL_NOVERS(__put_user_asm_l); +EXPORT_SYMBOL_NOVERS(__get_user_asm_l); +EXPORT_SYMBOL_NOVERS(memcmp); +EXPORT_SYMBOL_NOVERS(memcpy); +EXPORT_SYMBOL_NOVERS(memset); +EXPORT_SYMBOL_NOVERS(memscan); +EXPORT_SYMBOL_NOVERS(strchr); +EXPORT_SYMBOL_NOVERS(strlen); + +EXPORT_SYMBOL(flush_dcache_page); + +/* Ugh. These come in from libgcc.a at link time. */ + +extern void __sdivsi3(void); +extern void __muldi3(void); +extern void __udivsi3(void); +EXPORT_SYMBOL_NOVERS(__sdivsi3); +EXPORT_SYMBOL_NOVERS(__muldi3); +EXPORT_SYMBOL_NOVERS(__udivsi3); + diff -urN linux-2.4.21/arch/sh64/kernel/signal.c linux-2.4.22/arch/sh64/kernel/signal.c --- linux-2.4.21/arch/sh64/kernel/signal.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,821 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/signal.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Started from sh version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define REG_RET 9 +#define REG_ARG1 2 +#define REG_ARG2 3 +#define REG_SP 15 +#define REG_PR 18 +#define REF_REG_RET regs->regs[REG_RET] +#define REF_REG_SP regs->regs[REG_SP] +#define DEREF_REG_PR regs->regs[REG_PR] + +#define DEBUG_SIG 0 + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); + +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) +{ + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) + return -EFAULT; + if (from->si_code < 0) + return __copy_to_user(to, from, sizeof(siginfo_t)); + else { + int err; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + /* First 32bits of unions are always present. */ + err |= __put_user(from->si_pid, &to->si_pid); + switch (from->si_code >> 16) { + case __SI_FAULT >> 16: + break; + case __SI_CHLD >> 16: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_uid, &to->si_uid); + break; + /* case __SI_RT: This is not generated by the kernel as of now. */ + } + return err; + } +} + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ + +asmlinkage int +sys_sigsuspend(old_sigset_t mask, + unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs * regs) +{ + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sigmask_lock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + REF_REG_RET = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + regs->pc += 4; /* because sys_sigreturn decrements the pc */ + if (do_signal (regs, &saveset)) + { /* pc now points at signal handler. Need to decrement + it because entry.S will increment it. */ + regs->pc -= 4; + return -EINTR; + } + } +} + +asmlinkage int +sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, + unsigned long r4, unsigned long r5, unsigned long r6, + unsigned long r7, + struct pt_regs * regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + REF_REG_RET = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + regs->pc += 4; /* because sys_sigreturn decrements the pc */ + if (do_signal (regs, &saveset)) + { /* pc now points at signal handler. Need to decrement + it because entry.S will increment it. */ + regs->pc -= 4; + return -EINTR; + } + } +} + +asmlinkage int +sys_sigaction(int sig, const struct old_sigaction *act, + struct old_sigaction *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (verify_area(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} + +asmlinkage int +sys_sigaltstack(const stack_t *uss, stack_t *uoss, + unsigned long r4, unsigned long r5, unsigned long r6, + unsigned long r7, + struct pt_regs * regs) +{ + return do_sigaltstack(uss, uoss, REF_REG_SP); +} + + +/* + * Do a signal return; undo the signal stack. + */ + +struct sigframe +{ + struct sigcontext sc; + unsigned long extramask[_NSIG_WORDS-1]; + long long retcode[2]; +}; + +struct rt_sigframe +{ + struct siginfo *pinfo; + void *puc; + struct siginfo info; + struct ucontext uc; + long long retcode[2]; +}; + +#ifndef CONFIG_NOFPU_SUPPORT +static inline int +restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc) +{ + int err = 0; + int fpvalid; + + err |= __get_user (fpvalid, &sc->sc_fpvalid); + current->used_math = fpvalid; + if (! fpvalid) + return err; + + if (current == last_task_used_math) { + last_task_used_math = NULL; + regs->sr |= SR_FD; + } + + err |= __copy_from_user(¤t->thread.fpu.hard, &sc->sc_fpregs[0], + (sizeof(long long) * 32) + (sizeof(int) * 1)); + + return err; +} + +static inline int +setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc) +{ + int err = 0; + int fpvalid; + + fpvalid = current->used_math; + err |= __put_user(fpvalid, &sc->sc_fpvalid); + if (! fpvalid) + return err; + + if (current == last_task_used_math) { + grab_fpu(); + fpsave(¤t->thread.fpu.hard); + release_fpu(); + last_task_used_math = NULL; + regs->sr |= SR_FD; + } + + err |= __copy_to_user(&sc->sc_fpregs[0], ¤t->thread.fpu.hard, + (sizeof(long long) * 32) + (sizeof(int) * 1)); + current->used_math = 0; + + return err; +} +#else +static inline int +restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc) +{} +static inline int +setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc) +{} +#endif + +static int +restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, long long *r2_p) +{ + unsigned int err = 0; + +#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) + + COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); + COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); + COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); + COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]); + COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]); + COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]); + COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]); + COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]); + COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]); + COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]); + COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]); + COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]); + COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]); + COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]); + COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]); + COPY(regs[60]); COPY(regs[61]); COPY(regs[62]); + COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]); + COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]); + COPY(sr); COPY(pc); + +#undef COPY + + /* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr + * has been restored above.) */ + err |= restore_sigcontext_fpu(regs, sc); + + regs->syscall_nr = -1; /* disable syscall checks */ + err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]); + return err; +} + +asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3, + unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs * regs) +{ + struct sigframe *frame = (struct sigframe *) (long) REF_REG_SP; + sigset_t set; + long long ret; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + + if (__get_user(set.sig[0], &frame->sc.oldmask) + || (_NSIG_WORDS > 1 + && __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(regs, &frame->sc, &ret)) + goto badframe; + regs->pc -= 4; + + return (int) ret; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, + unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs * regs) +{ + struct rt_sigframe *frame = (struct rt_sigframe *) (long) REF_REG_SP; + sigset_t set; + stack_t st; + long long ret; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret)) + goto badframe; + regs->pc -= 4; + + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; + /* It is more difficult to avoid calling this function than to + call it and ignore errors. */ + do_sigaltstack(&st, NULL, REF_REG_SP); + + return (int) ret; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +/* + * Set up a signal frame. + */ + +static int +setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, + unsigned long mask) +{ + int err = 0; + + /* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */ + err |= setup_sigcontext_fpu(regs, sc); + +#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) + + COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); + COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); + COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); + COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]); + COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]); + COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]); + COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]); + COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]); + COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]); + COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]); + COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]); + COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]); + COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]); + COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]); + COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]); + COPY(regs[60]); COPY(regs[61]); COPY(regs[62]); + COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]); + COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]); + COPY(sr); COPY(pc); + +#undef COPY + + err |= __put_user(mask, &sc->oldmask); + + return err; +} + +/* + * Determine which stack to use.. + */ +static inline void * +get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) +{ + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + + return (void *)((sp - frame_size) & -8ul); +} + +void sa_default_restorer(void); /* See comments below */ +void sa_default_rt_restorer(void); /* See comments below */ + +static void setup_frame(int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs *regs) +{ + struct sigframe *frame; + int err = 0; + int signal; + + frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + signal = current->exec_domain + && current->exec_domain->signal_invmap + && sig < 32 + ? current->exec_domain->signal_invmap[sig] + : sig; + + err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); + + /* Give up earlier as i386, in case */ + if (err) + goto give_sigsegv; + + if (_NSIG_WORDS > 1) { + err |= __copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + } + + /* Give up earlier as i386, in case */ + if (err) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; + + /* + * On SH5 all edited pointers are subject to NEFF + */ + DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? + (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + } else { + /* + * Different approach on SH5. + * . Endianness independent asm code gets placed in entry.S . + * This is limited to four ASM instructions corresponding + * to two long longs in size. + * . err checking is done on the else branch only + * . flush_icache_range() is called upon __put_user() only + * . all edited pointers are subject to NEFF + * . being code, linker turns ShMedia bit on, always + * dereference index -1. + */ + DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; + DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? + (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + + if (__copy_to_user(frame->retcode, + (unsigned long long)sa_default_restorer & (~1), 16) != 0) + goto give_sigsegv; + + /* Cohere the trampoline with the I-cache. */ + flush_cache_sigtramp(DEREF_REG_PR-1, DEREF_REG_PR-1+16); + } + + /* + * Set up registers for signal handler. + * All edited pointers are subject to NEFF. + */ + regs->regs[REG_SP] = (unsigned long) frame; + regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? + (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; + regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ + regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc; + regs->pc = (unsigned long) ka->sa.sa_handler; + regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; + + set_fs(USER_DS); + +#if DEBUG_SIG + /* Broken %016Lx */ + printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", + signal, + current->comm, current->pid, frame, + regs->pc >> 32, regs->pc & 0xffffffff, + DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff); +#endif + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe *frame; + int err = 0; + int signal; + + frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + signal = current->exec_domain + && current->exec_domain->signal_invmap + && sig < 32 + ? current->exec_domain->signal_invmap[sig] + : sig; + + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + + /* Give up earlier as i386, in case */ + if (err) + goto give_sigsegv; + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user((void *)current->sas_ss_sp, + &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(regs->regs[REG_SP]), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= setup_sigcontext(&frame->uc.uc_mcontext, + regs, set->sig[0]); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Give up earlier as i386, in case */ + if (err) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; + + /* + * On SH5 all edited pointers are subject to NEFF + */ + DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? + (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + } else { + /* + * Different approach on SH5. + * . Endianness independent asm code gets placed in entry.S . + * This is limited to four ASM instructions corresponding + * to two long longs in size. + * . err checking is done on the else branch only + * . flush_icache_range() is called upon __put_user() only + * . all edited pointers are subject to NEFF + * . being code, linker turns ShMedia bit on, always + * dereference index -1. + */ + + DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; + DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? + (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + + if (__copy_to_user(frame->retcode, + (unsigned long long)sa_default_rt_restorer & (~1), 16) != 0) + goto give_sigsegv; + + flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15); + } + + /* + * Set up registers for signal handler. + * All edited pointers are subject to NEFF. + */ + regs->regs[REG_SP] = (unsigned long) frame; + regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? + (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; + regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ + regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; + regs->pc = (unsigned long) ka->sa.sa_handler; + regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; + + set_fs(USER_DS); + +#if DEBUG_SIG + /* Broken %016Lx */ + printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", + signal, + current->comm, current->pid, frame, + regs->pc >> 32, regs->pc & 0xffffffff, + DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff); +#endif + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +/* + * OK, we're invoking a handler + */ + +static void +handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) +{ + /* Are we from a system call? */ + if (regs->syscall_nr >= 0) { + /* If so, check system call restarting.. */ + switch (regs->regs[REG_RET]) { + case -ERESTARTNOHAND: + regs->regs[REG_RET] = -EINTR; + break; + + case -ERESTARTSYS: + if (!(ka->sa.sa_flags & SA_RESTART)) { + regs->regs[REG_RET] = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + /* Decode syscall # */ + regs->regs[REG_RET] = regs->syscall_nr; + regs->pc -= 4; + } + } + + /* Set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(sig, ka, info, oldset, regs); + else + setup_frame(sig, ka, oldset, regs); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sigmask_lock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + } +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + * + * Note that we go through the signals twice: once to check the signals that + * the kernel can handle, and then we build all the user-level signal handling + * stack-frames in one go after that. + */ +int do_signal(struct pt_regs *regs, sigset_t *oldset) +{ + siginfo_t info; + struct k_sigaction *ka; + + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return 1; + + if (!oldset) + oldset = ¤t->blocked; + + for (;;) { + unsigned long signr; + + spin_lock_irq(¤t->sigmask_lock); + signr = dequeue_signal(¤t->blocked, &info); + spin_unlock_irq(¤t->sigmask_lock); + + if (!signr) + break; + if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { + /* Let the debugger run. */ + current->exit_code = signr; + current->state = TASK_STOPPED; + notify_parent(current, SIGCHLD); + schedule(); + + /* We're back. Did the debugger cancel the sig? */ + if (!(signr = current->exit_code)) + continue; + current->exit_code = 0; + + /* The debugger continued. Ignore SIGSTOP. */ + if (signr == SIGSTOP) + continue; + + /* Update the siginfo structure. Is this good? */ + if (signr != info.si_signo) { + info.si_signo = signr; + info.si_errno = 0; + info.si_code = SI_USER; + info.si_pid = current->p_pptr->pid; + info.si_uid = current->p_pptr->uid; + } + + /* If the (new) signal is now blocked, requeue it. */ + if (sigismember(¤t->blocked, signr)) { + send_sig_info(signr, &info, current); + continue; + } + } + + ka = ¤t->sig->action[signr-1]; + if (ka->sa.sa_handler == SIG_IGN) { + if (signr != SIGCHLD) + continue; + /* Check for SIGCHLD: it's special. */ + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + /* nothing */; + continue; + } + + if (ka->sa.sa_handler == SIG_DFL) { + int exit_code = signr; + + /* Init gets no signals it doesn't want. */ + if (current->pid == 1) + continue; + + switch (signr) { + case SIGCONT: case SIGCHLD: case SIGWINCH: + continue; + + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + /* FALLTHRU */ + + case SIGSTOP: + current->state = TASK_STOPPED; + current->exit_code = signr; + if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) + notify_parent(current, SIGCHLD); + schedule(); + continue; + + case SIGQUIT: case SIGILL: case SIGTRAP: + case SIGABRT: case SIGFPE: case SIGSEGV: + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: + if (do_coredump(signr, regs)) + exit_code |= 0x80; + /* FALLTHRU */ + + default: + sig_exit(signr, exit_code, &info); + /* NOTREACHED */ + } + } + + /* Whee! Actually deliver the signal. */ + handle_signal(signr, ka, &info, oldset, regs); + return 1; + } + + /* Did we come from a system call? */ + if (regs->syscall_nr >= 0) { + /* Restart the system call - no handlers present */ + if (regs->regs[REG_RET] == -ERESTARTNOHAND || + regs->regs[REG_RET] == -ERESTARTSYS || + regs->regs[REG_RET] == -ERESTARTNOINTR) { + /* Decode Syscall # */ + regs->regs[REG_RET] = regs->syscall_nr; + regs->pc -= 4; + } + } + return 0; +} diff -urN linux-2.4.21/arch/sh64/kernel/sys_sh64.c linux-2.4.22/arch/sh64/kernel/sys_sh64.c --- linux-2.4.21/arch/sh64/kernel/sys_sh64.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/sys_sh64.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,309 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/sys_sh64.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * This file contains various random system calls that + * have a non-standard calling sequence on the Linux/SH5 + * platform. + * + * Mostly taken from i386 version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define REG_3 3 + +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way Unix traditionally does this, though. + */ +#ifdef NEW_PIPE_IMPLEMENTATION +asmlinkage int sys_pipe(unsigned long * fildes, + unsigned long dummy_r3, + unsigned long dummy_r4, + unsigned long dummy_r5, + unsigned long dummy_r6, + unsigned long dummy_r7, + struct pt_regs * regs) /* r8 = pt_regs forced by entry.S */ +{ + int fd[2]; + int ret; + + ret = do_pipe(fd); + if (ret == 0) + /* + *********************************************************************** + * To avoid the copy_to_user we prefer to break the ABIs convention, * + * packing the valid pair of file IDs into a single register (r3); * + * while r2 is the return code as defined by the sh5-ABIs. * + * BE CAREFUL: pipe stub, into glibc, must be aware of this solution * + *********************************************************************** + +#ifdef __LITTLE_ENDIAN__ + regs->regs[REG_3] = (((unsigned long long) fd[1]) << 32) | ((unsigned long long) fd[0]); +#else + regs->regs[REG_3] = (((unsigned long long) fd[0]) << 32) | ((unsigned long long) fd[1]); +#endif + + */ + /* although not very clever this is endianess independent */ + regs->regs[REG_3] = (unsigned long long) *((unsigned long long *) fd); + + return ret; +} + +#else +asmlinkage int sys_pipe(unsigned long * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + +#endif + +/* + * To avoid cache alias, we map the shard page with same color. + */ +#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1)) + +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct vm_area_struct *vma; + + if (flags & MAP_FIXED) { + /* We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ + if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1))) + return -EINVAL; + return addr; + } + + if (len > TASK_SIZE) + return -ENOMEM; + if (!addr) + addr = TASK_UNMAPPED_BASE; + + if (flags & MAP_PRIVATE) + addr = PAGE_ALIGN(addr); + else + addr = COLOUR_ALIGN(addr); + + for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { + /* At this point: (!vma || addr < vma->vm_end). */ + if (TASK_SIZE - len < addr) + return -ENOMEM; + if (!vma || addr + len <= vma->vm_start) + return addr; + addr = vma->vm_end; + if (!(flags & MAP_PRIVATE)) + addr = COLOUR_ALIGN(addr); + } +} + +asmlinkage long sys_shmatcall(int shmid, void *shmaddr, int shmflg) +{ + unsigned long raddr; + long err; + + lock_kernel(); + err = sys_shmat(shmid, shmaddr, shmflg, &raddr); + if (err) + goto out_shmatcall; + + err = raddr; +out_shmatcall: + unlock_kernel(); + return err; +} + +/* common code for old and new mmaps */ +static inline long do_mmap2( + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + int error = -EBADF; + struct file * file = NULL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return error; +} + +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + return do_mmap2(addr, len, prot, flags, fd, pgoff); +} + +asmlinkage int old_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + int fd, unsigned long off) +{ + if (off & ~PAGE_MASK) + return -EINVAL; + return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT); +} + +/******************************************************************* + * sys_ipc() is the de-multiplexer for the SysV IPC calls... * + * * + * This is really horribly ugly. * + * --- * + * True! But this is a obsolete ipc system calls implementation; * + * infact, all ipc system calls are called, such as alpha and * + * ia64 systems, without the "de-multiplexer" routine (except the * + * shmat syscall that is called by the sys_shmatcall function). * + * --- * + * * + *******************************************************************/ +asmlinkage int sys_ipc(uint call, int first, int second, + int third, void *ptr, long fifth) +{ + int version, ret; + + version = call >> 16; /* hack for backward compatibility */ + call &= 0xffff; + + if (call <= SEMCTL) + switch (call) { + case SEMOP: + return sys_semop (first, (struct sembuf *)ptr, second); + case SEMGET: + return sys_semget (first, second, third); + case SEMCTL: { + union semun fourth; + if (!ptr) + return -EINVAL; + if (get_user(fourth.__pad, (void **) ptr)) + return -EFAULT; + return sys_semctl (first, second, third, fourth); + } + default: + return -EINVAL; + } + + if (call <= MSGCTL) + switch (call) { + case MSGSND: + return sys_msgsnd (first, (struct msgbuf *) ptr, + second, third); + case MSGRCV: + switch (version) { + case 0: { + struct ipc_kludge tmp; + if (!ptr) + return -EINVAL; + + if (copy_from_user(&tmp, + (struct ipc_kludge *) ptr, + sizeof (tmp))) + return -EFAULT; + return sys_msgrcv (first, tmp.msgp, second, + tmp.msgtyp, third); + } + default: + return sys_msgrcv (first, + (struct msgbuf *) ptr, + second, fifth, third); + } + case MSGGET: + return sys_msgget ((key_t) first, second); + case MSGCTL: + return sys_msgctl (first, second, + (struct msqid_ds *) ptr); + default: + return -EINVAL; + } + if (call <= SHMCTL) + switch (call) { + case SHMAT: + switch (version) { + default: { + ulong raddr; + ret = sys_shmat (first, (char *) ptr, + second, &raddr); + if (ret) + return ret; + return put_user (raddr, (ulong *) third); + } + case 1: /* iBCS2 emulator entry point */ + if (!segment_eq(get_fs(), get_ds())) + return -EINVAL; + return sys_shmat (first, (char *) ptr, + second, (ulong *) third); + } + case SHMDT: + return sys_shmdt ((char *)ptr); + case SHMGET: + return sys_shmget (first, second, third); + case SHMCTL: + return sys_shmctl (first, second, + (struct shmid_ds *) ptr); + default: + return -EINVAL; + } + + return -EINVAL; +} + +asmlinkage int sys_uname(struct old_utsname * name) +{ + int err; + if (!name) + return -EFAULT; + down_read(&uts_sem); + err=copy_to_user(name, &system_utsname, sizeof (*name)); + up_read(&uts_sem); + return err?-EFAULT:0; +} + +asmlinkage int sys_pause(void) +{ + current->state = TASK_INTERRUPTIBLE; + schedule(); + return -ERESTARTNOHAND; +} diff -urN linux-2.4.21/arch/sh64/kernel/time.c linux-2.4.22/arch/sh64/kernel/time.c --- linux-2.4.21/arch/sh64/kernel/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,585 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/time.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Original TMU/RTC code taken from sh version. + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka + * Some code taken from i386 version. + * Copyright (C) 1991, 1992, 1995 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* required by inline __asm__ stmt. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TMU_TOCR_INIT 0x00 +#define TMU0_TCR_INIT 0x0020 +#define TMU_TSTR_INIT 1 + +/* RCR1 Bits */ +#define RCR1_CF 0x80 /* Carry Flag */ +#define RCR1_CIE 0x10 /* Carry Interrupt Enable */ +#define RCR1_AIE 0x08 /* Alarm Interrupt Enable */ +#define RCR1_AF 0x01 /* Alarm Flag */ + +/* RCR2 Bits */ +#define RCR2_PEF 0x80 /* PEriodic interrupt Flag */ +#define RCR2_PESMASK 0x70 /* Periodic interrupt Set */ +#define RCR2_RTCEN 0x08 /* ENable RTC */ +#define RCR2_ADJ 0x04 /* ADJustment (30-second) */ +#define RCR2_RESET 0x02 /* Reset bit */ +#define RCR2_START 0x01 /* Start bit */ + +/* Clock, Power and Reset Controller */ +#define CPRC_BLOCK_OFF 0x01010000 +#define CPRC_BASE PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF + +#define FRQCR (cprc_base+0x0) +#define WTCSR (cprc_base+0x0018) +#define STBCR (cprc_base+0x0030) + +/* Time Management Unit */ +#define TMU_BLOCK_OFF 0x01020000 +#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF +#define TMU0_BASE tmu_base + 0x8 + (0xc * 0x0) +#define TMU1_BASE tmu_base + 0x8 + (0xc * 0x1) +#define TMU2_BASE tmu_base + 0x8 + (0xc * 0x2) + +#define TMU_TOCR tmu_base+0x0 /* Byte access */ +#define TMU_TSTR tmu_base+0x4 /* Byte access */ + +#define TMU0_TCOR TMU0_BASE+0x0 /* Long access */ +#define TMU0_TCNT TMU0_BASE+0x4 /* Long access */ +#define TMU0_TCR TMU0_BASE+0x8 /* Word access */ + +/* Real Time Clock */ +#define RTC_BLOCK_OFF 0x01040000 +#define RTC_BASE PHYS_PERIPHERAL_BLOCK + RTC_BLOCK_OFF + +#define R64CNT rtc_base+0x00 +#define RSECCNT rtc_base+0x04 +#define RMINCNT rtc_base+0x08 +#define RHRCNT rtc_base+0x0c +#define RWKCNT rtc_base+0x10 +#define RDAYCNT rtc_base+0x14 +#define RMONCNT rtc_base+0x18 +#define RYRCNT rtc_base+0x1c /* 16bit */ +#define RSECAR rtc_base+0x20 +#define RMINAR rtc_base+0x24 +#define RHRAR rtc_base+0x28 +#define RWKAR rtc_base+0x2c +#define RDAYAR rtc_base+0x30 +#define RMONAR rtc_base+0x34 +#define RCR1 rtc_base+0x38 +#define RCR2 rtc_base+0x3c + +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) +#endif + +extern rwlock_t xtime_lock; +#define TICK_SIZE tick + +extern unsigned long wall_jiffies; +extern unsigned long volatile jiffies; + +static unsigned long tmu_base, rtc_base, cprc_base; + +/* Variables to allow interpolation of time of day to resolution better than a + * jiffy. */ + +/* This is effectively protected by xtime_lock */ +static unsigned long ctc_last_interrupt; +static unsigned long long usecs_per_jiffy = 1000000/HZ; /* Approximation */ + +#define CTC_JIFFY_SCALE_SHIFT 40 + +/* 2**CTC_JIFFY_SCALE_SHIFT / ctc_ticks_per_jiffy */ +static unsigned long long scaled_recip_ctc_ticks_per_jiffy; + +/* Estimate number of microseconds that have elapsed since the last timer tick, + by scaling the delta that has occured in the CTC register. + + WARNING WARNING WARNING : This algorithm relies on the CTC decrementing at + the CPU clock rate. If the CPU sleeps, the CTC stops counting. Bear this + in mind if enabling SLEEP_WORKS in process.c. In that case, this algorithm + probably needs to use TMU.TCNT0 instead. This will work even if the CPU is + sleeping, though will be coarser. + + FIXME : What if usecs_per_tick is moving around too much, e.g. if an adjtime + is running or if the freq or tick arguments of adjtimex are modified after + we have calibrated the scaling factor? This will result in either a jump at + the end of a tick period, or a wrap backwards at the start of the next one, + if the application is reading the time of day often enough. I think we + ought to do better than this. For this reason, usecs_per_jiffy is left + separated out in the calculation below. This allows some future hook into + the adjtime-related stuff in kernel/timer.c to remove this hazard. + +*/ + +static unsigned long usecs_since_tick(void) +{ + unsigned long long current_ctc; + long ctc_ticks_since_interrupt; + unsigned long long ull_ctc_ticks_since_interrupt; + unsigned long result; + + unsigned long long mul1_out; + unsigned long long mul1_out_high; + unsigned long long mul2_out_low, mul2_out_high; + + /* Read CTC register */ + asm ("getcon cr62, %0" : "=r" (current_ctc)); + /* Note, the CTC counts down on each CPU clock, not up. + Note(2), use long type to get correct wraparound arithmetic when + the counter crosses zero. */ + ctc_ticks_since_interrupt = (long) ctc_last_interrupt - (long) current_ctc; + ull_ctc_ticks_since_interrupt = (unsigned long long) ctc_ticks_since_interrupt; + + /* Inline assembly to do 32x32x32->64 multiplier */ + asm volatile ("mulu.l %1, %2, %0" : + "=r" (mul1_out) : + "r" (ull_ctc_ticks_since_interrupt), "r" (usecs_per_jiffy)); + + mul1_out_high = mul1_out >> 32; + + asm volatile ("mulu.l %1, %2, %0" : + "=r" (mul2_out_low) : + "r" (mul1_out), "r" (scaled_recip_ctc_ticks_per_jiffy)); + +#if 1 + asm volatile ("mulu.l %1, %2, %0" : + "=r" (mul2_out_high) : + "r" (mul1_out_high), "r" (scaled_recip_ctc_ticks_per_jiffy)); +#endif + + result = (unsigned long) (((mul2_out_high << 32) + mul2_out_low) >> CTC_JIFFY_SCALE_SHIFT); + + return result; +} + +void do_gettimeofday(struct timeval *tv) +{ + unsigned long flags; + unsigned long usec, sec; + + read_lock_irqsave(&xtime_lock, flags); + usec = usecs_since_tick(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += xtime.tv_usec; + read_unlock_irqrestore(&xtime_lock, flags); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +void do_settimeofday(struct timeval *tv) +{ + write_lock_irq(&xtime_lock); + xtime = *tv; + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; + write_unlock_irq(&xtime_lock); +} + +static int set_rtc_time(unsigned long nowtime) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + + ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */ + + cmos_minutes = ctrl_inb(RMINCNT); + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + ctrl_outb(real_seconds, RSECCNT); + ctrl_outb(real_minutes, RMINCNT); + } else { + printk(KERN_WARNING + "set_rtc_time: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */ + + return retval; +} + +/* last time the RTC clock got updated */ +static long last_rtc_update = 0; + +static inline void sh64_do_profile(unsigned long pc) +{ + extern int _stext; + + /* Don't profile cpu_idle.. */ + if (!prof_buffer || !current->pid) + return; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + + /* + * Don't ignore out-of-bounds PC values silently, put them into the + * last histogram slot, so if present, they will show up as a sharp + * peak. + */ + if (pc > prof_len - 1) + pc = prof_len - 1; + + /* We could just be sloppy and not lock against a re-entry on this + increment, but the profiling code won't always be linked in anyway. */ + atomic_inc((atomic_t *)&prof_buffer[pc]); +} + +/* + * timer_interrupt() needs to keep up the real-time clock, + * as well as call the "do_timer()" routine every clocktick + */ +static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long long current_ctc; + asm ("getcon cr62, %0" : "=r" (current_ctc)); + ctc_last_interrupt = (unsigned long) current_ctc; + + do_timer(regs); + + if (!user_mode(regs)) + sh64_do_profile(regs->pc); + +#ifdef CONFIG_HEARTBEAT + extern void heartbeat(void); + + heartbeat(); +#endif + + /* + * If we have an externally synchronized Linux clock, then update + * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && + xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { + if (set_rtc_time(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + } +} + +/* + * This is the same as the above, except we _also_ save the current + * Time Stamp Counter value at the time of the timer interrupt, so that + * we later on can estimate the time of day more exactly. + */ +static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long timer_status; + + /* Clear UNF bit */ + timer_status = ctrl_inw(TMU0_TCR); + timer_status &= ~0x100; + ctrl_outw(timer_status, TMU0_TCR); + + /* + * Here we are in the timer irq handler. We just have irqs locally + * disabled but we don't know if the timer_bh is running on the other + * CPU. We need to avoid to SMP race with it. NOTE: we don' t need + * the irq version of write_lock because as just said we have irq + * locally disabled. -arca + */ + write_lock(&xtime_lock); + do_timer_interrupt(irq, NULL, regs); + write_unlock(&xtime_lock); +} + + +static unsigned long get_rtc_time(void) +{ + unsigned int sec, min, hr, wk, day, mon, yr, yr100; + + again: + do { + ctrl_outb(0, RCR1); /* Clear CF-bit */ + sec = ctrl_inb(RSECCNT); + min = ctrl_inb(RMINCNT); + hr = ctrl_inb(RHRCNT); + wk = ctrl_inb(RWKCNT); + day = ctrl_inb(RDAYCNT); + mon = ctrl_inb(RMONCNT); + yr = ctrl_inw(RYRCNT); + yr100 = (yr >> 8); + yr &= 0xff; + } while ((ctrl_inb(RCR1) & RCR1_CF) != 0); + + BCD_TO_BIN(yr100); + BCD_TO_BIN(yr); + BCD_TO_BIN(mon); + BCD_TO_BIN(day); + BCD_TO_BIN(hr); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + + if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || + hr > 23 || min > 59 || sec > 59) { + printk(KERN_ERR + "SH RTC: invalid value, resetting to 1 Jan 2000\n"); + ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */ + ctrl_outb(0, RSECCNT); + ctrl_outb(0, RMINCNT); + ctrl_outb(0, RHRCNT); + ctrl_outb(6, RWKCNT); + ctrl_outb(1, RDAYCNT); + ctrl_outb(1, RMONCNT); + ctrl_outw(0x2000, RYRCNT); + ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */ + goto again; + } + + return mktime(yr100 * 100 + yr, mon, day, hr, min, sec); +} + +static __init unsigned int get_cpu_mhz(void) +{ + unsigned int count; + unsigned long __dummy; + + /* + ** Regardless the toolchain, force the compiler to use the + ** arbitrary register r3 as a clock tick counter. + ** NOTE: r3 must be in accordance with rtc_interrupt() + */ + register unsigned long long __clock_tick_count __asm__ ("r3"); + + sti(); + do {} while (ctrl_inb(R64CNT) != 0); + ctrl_outb(RCR1_CIE, RCR1); /* Enable carry interrupt */ + + /* + * r3 is arbitrary. CDC does not support "=z". + */ + asm volatile("gettr " __t0 ", %1\n\t" + "and %2, r63, %2\n\t" + "_pta 4, " __t0 "\n\t" + "addi %0, 1, %0\n\t" + "beq/l %2, r63, " __t0 "\n\t" + "ptabs %1, " __t0 "\n\t" + : "=r"(count), "=r" (__dummy), "=r" (__clock_tick_count) + : "0" (0)); + cli(); + /* + * SH-3: + * CPU clock = 4 stages * loop + * tst rm,rm if id ex + * bt/s 1b if id ex + * add #1,rd if id ex + * (if) pipe line stole + * tst rm,rm if id ex + * .... + * + * + * SH-4: + * CPU clock = 6 stages * loop + * I don't know why. + * .... + * + * SH-5: + * CPU clock = 2 stages * loop + * .... + * + */ + +#if defined (CONFIG_SH_SIMULATOR) + /* + * Let's pretend we are a 5MHz SH-5 to avoid a too + * little timer interval. Also to keep delay + * calibration within a reasonable time. + */ + return 5000000; +#elif defined (CONFIG_ICACHE_DISABLED) + /* + * Let's pretend we are a 300MHz SH-5. + */ + return 300000000; +#else + /* + * This really is count by the number of clock cycles + * per loop (2) by the ratio between a complete R64CNT + * wrap-around (128) and CUI interrupt being raised (64). + */ + return count*2*2; +#endif +} + +static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + ctrl_outb(0, RCR1); /* Disable Carry Interrupts */ + regs->regs[3] = 1; /* Using r3 */ +} + +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq1 = { rtc_interrupt, SA_INTERRUPT, 0, "rtc", NULL, NULL}; + +void __init time_init(void) +{ + unsigned int cpu_clock, master_clock, bus_clock, module_clock; + unsigned long interval; + unsigned long frqcr, ifc, pfc; + static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 }; +#define bfc_table ifc_table /* Same */ +#define pfc_table ifc_table /* Same */ + + tmu_base = onchip_remap(TMU_BASE, 1024, "TMU"); + if (tmu_base == 0UL) { + panic("Unable to remap TMU\n"); + } + + rtc_base = onchip_remap(RTC_BASE, 1024, "RTC"); + if (rtc_base == 0UL) { + panic("Unable to remap RTC\n"); + } + + cprc_base = onchip_remap(CPRC_BASE, 1024, "CPRC"); + if (cprc_base == 0UL) { + panic("Unable to remap CPRC\n"); + } + + xtime.tv_sec = get_rtc_time(); + xtime.tv_usec = 0; + + setup_irq(TIMER_IRQ, &irq0); + setup_irq(RTC_IRQ, &irq1); + + /* Check how fast it is.. */ + cpu_clock = get_cpu_mhz(); + + /* FIXME : Are these divides OK? Note careful order of operations to + * maintain reasonable precision and avoid overflow. */ + scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) / (unsigned long long)(cpu_clock / HZ)); + + disable_irq(RTC_IRQ); + + printk("CPU clock: %d.%02dMHz\n", + (cpu_clock / 1000000), (cpu_clock % 1000000)/10000); + { + unsigned short bfc; + frqcr = ctrl_inl(FRQCR); + ifc = ifc_table[(frqcr>> 6) & 0x0007]; + bfc = bfc_table[(frqcr>> 3) & 0x0007]; + pfc = pfc_table[(frqcr>> 12) & 0x0007]; + master_clock = cpu_clock * ifc; + bus_clock = master_clock/bfc; + } + + printk("Bus clock: %d.%02dMHz\n", + (bus_clock/1000000), (bus_clock % 1000000)/10000); + module_clock = master_clock/pfc; + printk("Module clock: %d.%02dMHz\n", + (module_clock/1000000), (module_clock % 1000000)/10000); + interval = (module_clock/(HZ*4)); + + printk("Interval = %ld\n", interval); + + current_cpu_data.cpu_clock = cpu_clock; + current_cpu_data.master_clock = master_clock; + current_cpu_data.bus_clock = bus_clock; + current_cpu_data.module_clock = module_clock; + + /* Start TMU0 */ + ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); + ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); + ctrl_outl(interval, TMU0_TCOR); + ctrl_outl(interval, TMU0_TCNT); + ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); +} + +void enter_deep_standby(void) +{ + /* Disable watchdog timer */ + ctrl_outl(0xa5000000, WTCSR); + /* Configure deep standby on sleep */ + ctrl_outl(0x03, STBCR); + +#ifdef CONFIG_SH_CAYMAN + { + extern void mach_alphanum(int position, unsigned char value); + extern void mach_alphanum_brightness(int setting); + char halted[] = "Halted. "; + int i; + mach_alphanum_brightness(6); /* dimmest setting above off */ + for (i=0; i<8; i++) { + mach_alphanum(i, halted[i]); + } + asm __volatile__ ("synco"); + } +#endif + + asm __volatile__ ("sleep"); + asm __volatile__ ("synci"); + asm __volatile__ ("nop"); + asm __volatile__ ("nop"); + asm __volatile__ ("nop"); + asm __volatile__ ("nop"); + panic("Unexpected wakeup!\n"); +} + diff -urN linux-2.4.21/arch/sh64/kernel/traps.c linux-2.4.22/arch/sh64/kernel/traps.c --- linux-2.4.21/arch/sh64/kernel/traps.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,304 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/traps.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 Paul Mundt + * + */ + +/* + * 'Traps.c' handles hardware traps and faults after we have saved some + * state in 'entry.S'. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#undef DEBUG_EXCEPTION +#ifdef DEBUG_EXCEPTION +/* implemented in ../lib/dbg.c */ +extern void show_excp_regs(char *fname, int trapnr, int signr, + struct pt_regs *regs); +#else +#define show_excp_regs(a, b, c, d) +#endif + +#define DO_ERROR(trapnr, signr, str, name, tsk) \ +asmlinkage void do_##name(unsigned long error_code, struct pt_regs *regs) \ +{ \ + show_excp_regs(__FUNCTION__, trapnr, signr, regs); \ + tsk->thread.error_code = error_code; \ + tsk->thread.trap_no = trapnr; \ + if (user_mode(regs)) force_sig(signr, tsk); \ + die_if_no_fixup(str,regs,error_code); \ +} + +spinlock_t die_lock; + +void die(const char * str, struct pt_regs * regs, long err) +{ + console_verbose(); + spin_lock_irq(&die_lock); + printk("%s: %lx\n", str, (err & 0xffffff)); + show_regs(regs); + spin_unlock_irq(&die_lock); + do_exit(SIGSEGV); +} + +static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) +{ + if (!user_mode(regs)) + die(str, regs, err); +} + +static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err) +{ + if (!user_mode(regs)) + { + unsigned long fixup; + fixup = search_exception_table(regs->pc); + if (fixup) { + regs->pc = fixup; + return; + } + die(str, regs, err); + } +} + +DO_ERROR( 7, SIGSEGV, "address error (load)", address_error_load, current) +DO_ERROR( 8, SIGSEGV, "address error (store)", address_error_store, current) +DO_ERROR(13, SIGILL, "illegal slot instruction", illegal_slot_inst, current) +DO_ERROR(87, SIGSEGV, "address error (exec)", address_error_exec, current) + +#if defined(CONFIG_SH64_ID2815_WORKAROUND) + +#define OPCODE_INVALID 0 +#define OPCODE_USER_VALID 1 +#define OPCODE_PRIV_VALID 2 + +/* getcon/putcon - requires checking which control register is referenced. */ +#define OPCODE_CTRL_REG 3 + +/* Table of valid opcodes for SHmedia mode. + Form a 10-bit value by concatenating the major/minor opcodes i.e. + opcode[31:26,20:16]. The 6 MSBs of this value index into the following + array. The 4 LSBs select the bit-pair in the entry (bits 1:0 correspond to + LSBs==4'b0000 etc). */ +static unsigned long shmedia_opcode_table[64] = { + 0x55554044,0x54445055,0x15141514,0x14541414,0x00000000,0x10001000,0x01110055,0x04050015, + 0x00000444,0xc0000000,0x44545515,0x40405555,0x55550015,0x10005555,0x55555505,0x04050000, + 0x00000555,0x00000404,0x00040445,0x15151414,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000055,0x40404444,0x00000404,0xc0009495,0x00000000,0x00000000,0x00000000,0x00000000, + 0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, + 0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, + 0x80005050,0x04005055,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, + 0x81055554,0x00000404,0x55555555,0x55555555,0x00000000,0x00000000,0x00000000,0x00000000 +}; + +void do_reserved_inst(unsigned long error_code, struct pt_regs *regs) +{ + /* Workaround SH5-101 cut2 silicon defect #2815 : + in some situations, inter-mode branches from SHcompact -> SHmedia + which should take ITLBMISS or EXECPROT exceptions at the target + falsely take RESINST at the target instead. */ + + unsigned long opcode; + unsigned long pc, aligned_pc; + int get_user_error; + int trapnr = 12; + int signr = SIGILL; + char *exception_name = "reserved_instruction"; + + pc = regs->pc; + if ((pc & 3) == 1) { + /* SHmedia : check for defect. This requires executable vmas + to be readable too. */ + aligned_pc = pc & ~3; + if (!access_ok(VERIFY_READ, aligned_pc, sizeof(unsigned long))) { + get_user_error = -EFAULT; + } else { + get_user_error = __get_user(opcode, (unsigned long *)aligned_pc); + } + if (get_user_error >= 0) { + unsigned long index, shift; + unsigned long major, minor, combined; + unsigned long reserved_field; + reserved_field = opcode & 0xf; /* These bits are currently reserved as zero in all valid opcodes */ + major = (opcode >> 26) & 0x3f; + minor = (opcode >> 16) & 0xf; + combined = (major << 4) | minor; + index = major; + shift = minor << 1; + if (reserved_field == 0) { + int opcode_state = (shmedia_opcode_table[index] >> shift) & 0x3; + switch (opcode_state) { + case OPCODE_INVALID: + /* Trap. */ + break; + case OPCODE_USER_VALID: + /* Restart the instruction : the branch to the instruction will now be from an RTE + not from SHcompact so the silicon defect won't be triggered. */ + return; + case OPCODE_PRIV_VALID: + if (!user_mode(regs)) { + /* Should only ever get here if a module has + SHcompact code inside it. If so, the same fix up is needed. */ + return; /* same reason */ + } + /* Otherwise, user mode trying to execute a privileged instruction - + fall through to trap. */ + break; + case OPCODE_CTRL_REG: + /* If in privileged mode, return as above. */ + if (!user_mode(regs)) return; + /* In user mode ... */ + if (combined == 0x9f) { /* GETCON */ + unsigned long regno = (opcode >> 20) & 0x3f; + if (regno >= 62) { + return; + } + /* Otherwise, reserved or privileged control register, => trap */ + } else if (combined == 0x1bf) { /* PUTCON */ + unsigned long regno = (opcode >> 4) & 0x3f; + if (regno >= 62) { + return; + } + /* Otherwise, reserved or privileged control register, => trap */ + } else { + /* Trap */ + } + break; + default: + /* Fall through to trap. */ + break; + } + } + /* fall through to normal resinst processing */ + } else { + /* Error trying to read opcode. This typically means a + real fault, not a RESINST any more. So change the + codes. */ + trapnr = 87; + exception_name = "address error (exec)"; + signr = SIGSEGV; + } + } + + show_excp_regs("do_reserved_inst", trapnr, signr, regs); + current->thread.error_code = error_code; + current->thread.trap_no = trapnr; + if (user_mode(regs)) force_sig(signr, current); + die_if_no_fixup(exception_name, regs, error_code); +} + +#else /* CONFIG_SH64_ID2815_WORKAROUND */ + +/* If the workaround isn't needed, this is just a straightforward reserved + instruction */ +DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current) + +#endif /* CONFIG_SH64_ID2815_WORKAROUND */ + + +#include + +/* Called with interrupts disabled */ +asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs) +{ + PLS(); + show_excp_regs(__FUNCTION__, -1, -1, regs); + die_if_kernel("exception", regs, ex); +} + +int do_unknown_trapa(unsigned long scId, struct pt_regs *regs) +{ + /* Syscall debug */ + printk("System call ID error: [0x1#args:8 #syscall:16 0x%lx]\n", scId); + + die_if_kernel("unknown trapa", regs, scId); + + return -ENOSYS; +} + +void show_task(unsigned long *sp) +{ + unsigned long module_start, module_end; + unsigned long kernel_start, kernel_end; + unsigned long *stack; + extern int _text, _etext; + int i = 1; + + kernel_start = (unsigned long)&_text; + kernel_end = (unsigned long)&_etext; + + module_start = VMALLOC_START; + module_end = VMALLOC_END; + + if (!sp) { + /* + * If we haven't specified a sane sp, fetch it.. + */ + __asm__ __volatile__ ( + "or r15, r63, %0\n\t" + "getcon " __c17 ", %1\n\t" + : "=r" (module_start), + "=r" (module_end) + ); + + sp = (unsigned long *)module_start; + } + + stack = sp; + + printk("\nCall Trace: "); + + while ((unsigned long)stack & (PAGE_SIZE - 1)) { + unsigned long addr = *stack++; + + if ((addr >= kernel_start && addr < kernel_end) || + (addr >= module_start && addr < module_end)) { + /* + * Do a bit of formatting here.. on an 80 column + * display, 6 entries is the most we can deal with + * per-line, since each address will take up 13 spaces. + */ + if (i && ((i % 6) == 0)) + printk("\n "); + + printk("[<%08lx>] ", addr); + i++; + } + } + + printk("\n"); +} + +void show_trace_task(struct task_struct *tsk) +{ + show_task((unsigned long *)tsk->thread.sp); +} + +void dump_stack(void) +{ + show_task(NULL); +} + diff -urN linux-2.4.21/arch/sh64/lib/Makefile linux-2.4.22/arch/sh64/lib/Makefile --- linux-2.4.21/arch/sh64/lib/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,26 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2000, 2001 Paolo Alberelli +# +# Makefile for the SH-5 specific library files.. +# +# 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). +# + +#.S.o: +# $(CC) $(CFLAGS) $(AFLAGS) -traditional -c $< -o $*.o +.S.o: + $(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o + +L_TARGET = lib.a + +# Panic should really be compiled as PIC +obj-y = udelay.o c-checksum.o dbg.o io.o panic.o memcpy.o copy_user_memcpy.o \ + page_copy.o page_clear.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/sh64/lib/c-checksum.c linux-2.4.22/arch/sh64/lib/c-checksum.c --- linux-2.4.21/arch/sh64/lib/c-checksum.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/c-checksum.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,330 @@ +/* + * arch/sh/lib/csum_parial.c + * + * This file contains network checksum routines that are better done + * in an architecture-specific manner due to speed.. + */ + +#include +#include +#include +#include +#include + +#if 1 +#define dprintk(x...) +#else +#define dprintk(x...) printk(x) +#endif + +static inline unsigned short from64to16(unsigned long long x) +{ + /* add up 32-bit words for 33 bits */ + x = (x & 0xffffffff) + (x >> 32); + /* add up 16-bit and 17-bit words for 17+c bits */ + x = (x & 0xffff) + (x >> 16); + /* add up 16-bit and 2-bit for 16+c bit */ + x = (x & 0xffff) + (x >> 16); + /* add up carry.. */ + x = (x & 0xffff) + (x >> 16); + return x; +} + +static inline unsigned short foldto16(unsigned long x) +{ + /* add up 16-bit for 17 bits */ + x = (x & 0xffff) + (x >> 16); + /* add up carry.. */ + x = (x & 0xffff) + (x >> 16); + return x; +} + +static inline unsigned short myfoldto16(unsigned long long x) +{ + /* Fold down to 32-bits so we don't loose in the typedef-less + network stack. */ + /* 64 to 33 */ + x = (x & 0xffffffff) + (x >> 32); + /* 33 to 32 */ + x = (x & 0xffffffff) + (x >> 32); + + /* add up 16-bit for 17 bits */ + x = (x & 0xffff) + (x >> 16); + /* add up carry.. */ + x = (x & 0xffff) + (x >> 16); + return x; +} + +#define odd(x) ((x)&1) +/* +typedef unsigned short u16; +typedef unsigned u32; +*/ +#define U16(x) ntohs(x) + +static unsigned long do_moronic_csum(const unsigned char *a16p, int cnt) +{ + u32 sum; + int oddb; + + /* This algorithm is correct only for those values of cnt < 65536 */ + + oddb = odd(cnt); + cnt >>= 1; /* convert to a word count */ + sum = 0; /* do a straight two's complement sum */ + while (cnt--) + sum += U16(*a16p++); + if (oddb) /* pick up the odd byte */ + sum += U16(*a16p++) & (u16) 0xFF00; + /* add in the sum of the `carry' bits, making this one's complement */ + sum = (sum & (u32) 0xFFFF) + ((sum >> 16) & (u32) 0xFFFF); + if (sum & (u32) 0x10000) /* one last possible carry */ + sum = (sum + 1) & (u32) 0xFFFF; + if (sum == (u32) 0xFFFF) /* remove the -0 ambiguity */ + sum = (u32) 0; + return sum; + +} + +#if 0 +static inline unsigned long do_csum(const unsigned char *buff, int len) +{ + int odd, count; + unsigned long long result = 0; + + if (len <= 0) + goto out; + odd = 1 & (unsigned long) buff; + if (odd) { + result = *buff << 8; + len--; + buff++; + } + count = len >> 1; /* nr of 16-bit words.. */ + if (count) { + if (2 & (unsigned long) buff) { + result += *(unsigned short *) buff; + count--; + len -= 2; + buff += 2; + } + count >>= 1; /* nr of 32-bit words.. */ + if (count) { + if (4 & (unsigned long) buff) { + result += *(unsigned int *) buff; + count--; + len -= 4; + buff += 4; + } + count >>= 1; /* nr of 64-bit words.. */ + if (count) { + unsigned long carry = 0; + do { + unsigned long w = + *(unsigned long *) buff; + count--; + buff += 8; + result += carry; + result += w; + carry = (w > result); + } while (count); + result += carry; + result = (result & 0xffffffff) + (result >> 32); + } + if (len & 4) { + result += *(unsigned int *) buff; + buff += 4; + } + } + if (len & 2) { + result += *(unsigned short *) buff; + buff += 2; + } + } + if (len & 1) + result += *buff; + result = from64to16(result); + if (odd) + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); + out: + return result; +} + +#else + +static unsigned long do_csum(const unsigned char *buff, int len) +{ + int odd, count; + unsigned long result = 0; + + dprintk("do_csum buff %p, len %d (0x%x)\n", buff, len, len); +#ifdef DEBUG + for (i = 0; i < len; i++) { + if ((i % 26) == 0) + printk("\n"); + printk("%02X ", buff[i]); + } +#endif + + if (len <= 0) + goto out; + + odd = 1 & (unsigned long) buff; + if (odd) { + result = *buff << 8; + len--; + buff++; + } + count = len >> 1; /* nr of 16-bit words.. */ + if (count) { + if (2 & (unsigned long) buff) { + result += *(unsigned short *) buff; + count--; + len -= 2; + buff += 2; + } + count >>= 1; /* nr of 32-bit words.. */ + if (count) { + unsigned long carry = 0; + do { + unsigned long w = *(unsigned long *) buff; + buff += 4; + count--; + result += carry; + result += w; + carry = (w > result); + } while (count); + result += carry; + result = (result & 0xffff) + (result >> 16); + } + if (len & 2) { + result += *(unsigned short *) buff; + buff += 2; + } + } + if (len & 1) + result += *buff; + result = foldto16(result); + if (odd) + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); + + dprintk("\nCHECKSUM is 0x%x\n", result); + + out: + return result; +} + +#endif + +/* computes the checksum of a memory block at buff, length len, + and adds in "sum" (32-bit) */ +unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) +{ + unsigned long long result = do_csum(buff, len); + + /* add in old sum, and carry.. */ + result += sum; + /* 32+c bits -> 32 bits */ + result = (result & 0xffffffff) + (result >> 32); + + dprintk("csum_partial, buff %p len %d sum 0x%x result=0x%016Lx\n", + buff, len, sum, result); + + return result; +} + +/* Copy while checksumming, otherwise like csum_partial. */ +unsigned int +csum_partial_copy(const char *src, char *dst, int len, unsigned int sum) +{ + sum = csum_partial(src, len, sum); + memcpy(dst, src, len); + + return sum; +} + +/* Copy from userspace and compute checksum. If we catch an exception + then zero the rest of the buffer. */ +unsigned int +csum_partial_copy_from_user(const char *src, char *dst, int len, + unsigned int sum, int *err_ptr) +{ + int missing; + + dprintk + ("csum_partial_copy_from_user src %p, dest %p, len %d, sum %08x, err_ptr %p\n", + src, dst, len, sum, err_ptr); + missing = copy_from_user(dst, src, len); + dprintk(" access_ok %d\n", __access_ok((unsigned long) src, len)); + dprintk(" missing %d\n", missing); + if (missing) { + memset(dst + len - missing, 0, missing); + *err_ptr = -EFAULT; + } + + return csum_partial(dst, len, sum); +} + +/* Copy to userspace and compute checksum. */ +unsigned int +csum_partial_copy_to_user(const char *src, char *dst, int len, + unsigned int sum, int *err_ptr) +{ + sum = csum_partial(src, len, sum); + + if (copy_to_user(dst, src, len)) + *err_ptr = -EFAULT; + + return sum; +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) +{ + dprintk("ip_fast_csum %p,%d\n", iph, ihl); + + return ~do_csum(iph, ihl * 4); +} + +unsigned int csum_tcpudp_nofold(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, unsigned int sum) +{ + unsigned long long result; + + dprintk("ntohs(0x%x)=0x%x\n", 0xdead, ntohs(0xdead)); + dprintk("htons(0x%x)=0x%x\n", 0xdead, htons(0xdead)); + + result = ((unsigned long long) saddr + + (unsigned long long) daddr + + (unsigned long long) sum + + ((unsigned long long) ntohs(len) << 16) + + ((unsigned long long) proto << 8)); + + /* Fold down to 32-bits so we don't loose in the typedef-less + network stack. */ + /* 64 to 33 */ + result = (result & 0xffffffff) + (result >> 32); + /* 33 to 32 */ + result = (result & 0xffffffff) + (result >> 32); + + dprintk("%s saddr %x daddr %x len %x proto %x sum %x result %08Lx\n", + __FUNCTION__, saddr, daddr, len, proto, sum, result); + + return result; +} + +// Post SIM: +unsigned int +csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum) +{ + // unsigned dummy; + dprintk("csum_partial_copy_nocheck src %p dst %p len %d\n", src, dst, + len); + + return csum_partial_copy(src, dst, len, sum); +} diff -urN linux-2.4.21/arch/sh64/lib/checksum.S linux-2.4.22/arch/sh64/lib/checksum.S --- linux-2.4.21/arch/sh64/lib/checksum.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/checksum.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,656 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh5/lib/checksum.S + * + * Copyright (C) 2000, 2001 Paolo Alberelli, Stefano D'Andrea + * + */ + +/* + * + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * IP/TCP/UDP checksumming routines + * + * Authors: Jorge Cwik, + * Arnt Gulbrandsen, + * Tom May, + * Pentium Pro/II routines: + * Alexander Kjeldaas + * Finn Arne Gangstad + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception + * handling. + * Andi Kleen, add zeroing on error + * converted to pure assembler + * + * SuperH version: Copyright (C) 1999 Niibe Yutaka + * + * SH-5 version: Copyright (C) 2000 Paolo Alberelli, Stefano D'Andrea + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include + + .section .text64, "ax" +/* + * unsigned int csum_partial(const unsigned char *buf, + * int len, + * unsigned int sum); + * + * + * computes a partial checksum, e.g. for TCP/UDP fragments + */ + +/* + * SH-5 ABI convention: + * Input parameters: + * r2 = *buf + * r3 = len + * r4 = sum so far computed checksum (may be zero) + * return value must be in: + * r2 returned checksum + */ + + /* + * Experiments with Ethernet and SLIP connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. We get at + * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. + * Fortunately, it is easy to convert 2-byte alignment to 4-byte + * alignment for the unrolled loop. + */ + +#ifndef NOTDEF + /* This version of _csum_partial is an easy but unefficient + * implementation. + * It's mainteined only for historical reasons. + */ + .global csum_partial +csum_partial: + _ptar .byte_footer, t1 /* t1 = .byte_footer */ + _ptar .add_short_loop, t2 /* t2 = checksum eval loop */ + _ptar .exiting, t3 /* t3 = add carry... */ + + movi 2, r1 + + /* we assume buf short aligned */ + /* Short must be checksummed */ +.add_short_loop: + bgt r1, r3, t1 /* Size = 1 or 0 (remind) */ + + ld.uw r2, 0, r7 /* r7 = word to be checksumed*/ + add r4, r7, r4 + + addi r2, 2, r2 /* move buf forward... */ + addi r3, -2, r3 /* decrement len */ + blink t2, ZERO /* goto .add_short_loop */ + +.byte_footer: + /* still one byte to be checksummed ? */ + xor r7, r7, r7 + beqi r3, 0, t3 + ld.ub r2, 0, r7 /* r7 = last byte... */ +#ifndef __LITTLE_ENDIAN__ + shlli r7, 8, r7 +#endif + +.exiting: + add r4, r7, r2 + + ptabs r18, t0 + blink t0, ZERO + +#else /* NOTDEF ---------------------------------------------------- */ + + .global csum_partial +csum_partial: + movi 32, r8 /* r8 = sizeof(8 * int) */ + _ptar .byte_footer, t1 /* t1 = .byte_footer */ + _ptar .word_footer, t2 /* t2 = .word_footer */ + _ptar .long_footer, t3 /* t3 = .long_footer */ + _ptar .exit, t4 /* t4 = exit point */ + _ptar .long_aligned, t0 /* t0 = .long_aligned */ + or r2, ZERO, r5 /* r5 = buffer pointer */ + or r3, ZERO, r6 /* r6 = original length */ + andi r2, 2, r7 + beq r7, ZERO, t0 /* It's buf long aligned */ + + /* we assume buf short aligned */ + + beqi r3, 1, t1 /* Size = 1 */ + + /* Short must be checksummed */ + ld.uw r2, 0, r7 /* r7 = word to be checksumed*/ + add r4, r7, r4 + + or ZERO, ZERO, r7 + + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + addi r6, -2, r6 + addi r5, 2, r5 /* r5 is now long aligned */ + beq r6, ZERO, t4 /* Exit if done */ + + or ZERO, ZERO, r7 /* Clean up r7 */ + +.long_aligned: + bgt r8, r6, t3 + + /* 8 Longs to be checksummed */ + ld.l r5, 0, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + ld.l r5, 4, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + + + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + ld.l r5, 8, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + ld.l r5, 12, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + + ld.l r5, 16, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + ld.l r5, 20, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + + ld.l r5, 24, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + + ld.l r5, 28, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + + sub r6, r8, r6 + add r5, r8, r5 + blink t0, ZERO + +.long_footer: + movi 4, r8 + bgt r8, r6, t2 + + /* Long to be checksummed */ + ld.l r5, 0, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + + sub r6, r8, r6 + add r5, r8, r5 + blink t3, ZERO + +.word_footer: + movi 2, r8 + bgt r8, r6, t1 + + /* Short to be checksummed */ + ld.uw r5, 0, r7 /* r7 = data to be checksummed*/ + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + + sub r6, r8, r6 + add r5, r8, r5 + +.byte_footer: + beqi r6, 0, t4 + /* Short to be checksummed */ + ld.ub r5, 0, r7 /* r7 = data to be checksummed*/ + +#ifndef __LITTLE_ENDIAN__ + shlli r7, 8, r7 +#endif + + add r4, r7, r4 + or ZERO, ZERO, r7 + mshflo.l r4, r7, r7 + shlri r4, 32, r4 + add r4, r7, r4 /* Add eventual "carry" */ + + +.exit: + or r4, ZERO, r2 + + ptabs r18, t0 + blink t0, ZERO + +#endif /*NOTDEF*/ + +/* + * unsigned int csum_partial_copy_generic (const char *src, + * char *dst, + * int len, + * int sum, + * int *src_err_ptr, + * int *dst_err_ptr) + * + * + * + * Copy from ds while checksumming, otherwise like csum_partial + * + * The macros SRC and DST specify the type of access for the instruction. + * thus we can call a custom exception handler for all access types. + * + * FIXME: could someone double-check whether I haven't mixed up some SRC and + * DST definitions? It's damn hard to trigger all cases. I hope I got + * them all but there's no guarantee. + */ + +/* + * SH-5 ABI convention: + * Input parameters: + * r2 = const char *src + * r3 = char *dst + * r4 = int len + * r5 = int sum so far computed checksum (may be zero) + * r6 = int *src_err_ptr + * r7 = int *dst_err_ptr + * return value must be in: + * r2 returned checksum + */ + +#ifndef NOTDEF + /* + ** This version of _csum_partial_copy_generic is an easy but + ** unefficient implementation. + ** It's mainteined only for historical reasons. + */ + .global csum_partial_copy_generic +csum_partial_copy_generic: + _ptar .gc_byte_footer, t1 /* t1 = .byte_footer */ + _ptar .gc_add_short_loop, t2 /* t2 = checksum eval loop */ + _ptar .gc_exiting, t3 /* t3 = add carry... */ + + or r2, ZERO, r20 /* r20 = source pointer */ + or r3, ZERO, r21 /* r21 = destination pointer */ + + movi 2, r1 + + /* we assume buf short aligned */ + /* Short must be checksummed */ +.gc_add_short_loop: + + bgt r1, r4, t1 /* Size = 1 or 0 (remind) */ + +.src_err_1: + ld.uw r20, 0, r8 /* r8 = word to be checksum. */ + st.w r21, 0, r8 /* fill data into DST */ + + add r5, r8, r5 + + addi r20, 2, r20 /* move SRC forward... */ + addi r21, 2, r21 /* move DST forward... */ + addi r4, -2, r4 /* decrement len */ + blink t2, ZERO /* goto .gc_add_short_loop */ + +.gc_byte_footer: + /* still one byte to be checksummed ? */ + xor r8, r8, r8 + beqi r4, 0, t3 + +.src_err_2: + ld.ub r20, 0, r8 /* r8 = last byte... */ + st.b r21, 0, r8 +#ifndef __LITTLE_ENDIAN__ + shlli r8, 8, r8 +#endif + +.gc_exiting: + add r5, r8, r2 + + ptabs r18, t0 + blink t0, ZERO + + .section .fixup, "ax" + +_csum_partial_copy_generic_dst_err: + movi -(EFAULT), r8 /* r8 = EFAULT reply */ + st.l r7, 0, r8 /* *DST_ERR = -EFAULT */ + + /* Quiet exit */ + or r5, ZERO, r2 + + ptabs r18, t0 + blink t0, ZERO + +_csum_partial_copy_generic_src_err: + movi -(EFAULT), r8 /* r8 = EFAULT reply */ + ld.l r6, 0, r8 /* *SRC_ERR = -EFAULT */ + + /* + * Now reset the DST buffer. + * r20 points to the next DST byte. + * r3 points to the first DST byte. + */ + _ptar .quiet_exit, t0 + _ptar .src_err_loop, t1 + beq r20, r3, t0 + +.src_err_loop: + addi r20, -1, r20 + ld.b r20, 0, ZERO + bne r20, r3, t1 + + /* Quiet exit */ +.quiet_exit: + or r5, ZERO, r2 + + ptabs r18, t0 + blink t0, ZERO + + .section __ex_table, "a" + + .global asm_checksum_start /* Just a marker */ +asm_checksum_start: + .long .src_err_1, _csum_partial_copy_generic_src_err + .long .src_err_2, _csum_partial_copy_generic_src_err + .long .src_err_1+4, _csum_partial_copy_generic_dst_err + .long .src_err_2+4, _csum_partial_copy_generic_dst_err + .global asm_checksum_end /* Just a marker */ +asm_checksum_end: + +#else /* NOTDEF -------------------------------------------------------- */ + + .global csum_partial_copy_generic +csum_partial_copy_generic: + + movi 32, r27 /* r27 = sizeof(8 * int) */ + _ptar .byte_footer_gc, t1 /* t1 = .byte_footer_gc */ + _ptar .word_footer_gc, t2 /* t2 = .word_footer_gc */ + _ptar .long_footer_gc, t3 /* t3 = .long_footer_gc */ + _ptar .exit_gc, t4 /* t4 = exit point */ + + or r2, ZERO, r24 /* r24 = original SRC pointer */ + or r3, ZERO, r20 /* r20 = original DST pointer */ + or r4, ZERO, r25 /* r25 = original length */ + _ptar .long_aligned_gc, t0 + andi r2, 2, r26 /* check if source it's */ + beq r26, ZERO, t0 /* long aligned */ + + /* It's short aligned */ + + beqi r4, 1, t1 /* Size = 1 */ + + /* Short must be checksummed */ +.src_err_1: + ld.w r2, 0, r26 /* r26: data to be checksummed*/ + st.w r3, 0, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + + addi r25, -2, r25 + addi r24, 2, r24 /* r24 is now long aligned */ + addi r20, 2, r20 /* r20 it's now long aligned */ + beq r25, ZERO, t4 /* Exit if done */ + + or ZERO, ZERO, r26 /* Clean up r26 */ + +.long_aligned_gc: + bgt r27, r25, t3 + + /* 8 Longs to be checksummed */ +.src_err_2: + ld.l r24, 0, r26 /* r26: data to be checksummed*/ + st.l r20, 0, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.src_err_3: + ld.l r24, 4, r26 /* r26: data to be checksummed*/ + st.l r20, 4, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.src_err_4: + ld.l r24, 8, r26 /* r26: data to be checksummed*/ + st.l r20, 8, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.src_err_5: + ld.l r24, 12, r26 /* r26: data to be checksummed*/ + st.l r20, 12, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.src_err_6: + ld.l r24, 16, r26 /* r26: data to be checksummed*/ + st.l r20, 16, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.src_err_7: + ld.l r24, 20, r26 /* r26: data to be checksummed*/ + st.l r20, 20, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26,r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.src_err_8: + ld.l r24, 24, r26 /* r26: data to be checksummed*/ + st.l r20, 24, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.src_err_9: + ld.l r24, 28, r26 /* r26: data to be checksummed*/ + st.l r20, 28, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + + sub r25, r27, r25 + add r24, r27, r24 + add r20, r27, r20 + blink t0, ZERO + +.long_footer_gc: + movi 4, r27 + bgt r27, r25, t2 + + /* Long to be checksummed */ +.src_err_10: + ld.l r24, 0, r26 /* r26: data to be checksummed*/ + st.l r20, 0, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + + sub r25, r27, r25 + add r24, r27, r24 + add r20, r27, r20 + blink t3, ZERO + +.word_footer_gc: + movi 2, r27 + bgt r27, r25, t1 + + /* Short to be checksummed */ +.src_err_11: + ld.uw r24, 0, r26 /* r26: data to be checksummed*/ + st.w r20, 0, r26 /* fill data into DST */ + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + + sub r25, r27, r25 + add r24, r27, r24 + add r20, r27, r20 + +.byte_footer_gc: + beqi r25, 0, t4 + /* Short to be checksummed */ + ld.ub r24, 0, r26 /* r26: data to be checksummed*/ +.src_err_12: + ld.ub r24, 0, r26 /* r26: data to be checksummed*/ + st.b r20, 0, r26 /* fill data into DST */ + +#ifndef __LITTLE_ENDIAN__ + shlli r26, 8, r26 +#endif + + add r5, r26, r5 + or ZERO, ZERO, r26 + mshflo.l r5, r26, r26 + shlri r5, 32, r5 + add r5, r26, r5 /* Add eventual "carry" */ + +.exit_gc: + or r5, ZERO, r2 + + ptabs r18, t0 + blink t0, ZERO + + .section .fixup, "ax" + +_csum_partial_copy_generic_dst_err: + movi -(EFAULT), r21 /* r21 = EFAULT reply */ + ld.l r7, 0, r21 + + /* Quiet exit */ + or r5, ZERO, r2 + + ptabs r18, t0 + blink t0, ZERO + +_csum_partial_copy_generic_src_err: + movi -(EFAULT), r21 /* r21 = EFAULT reply */ + ld.l r6, 0, r21 + + /* + * Now reset the DST buffer. + * r20 points to the next DST byte. + * r3 points to the first DST byte. + */ + _ptar .quiet_exit, t0 + _ptar .src_err_loop, t1 + beq r20, r3, t0 + +.src_err_loop: + addi r20, -1, r20 + st.b r20, 0, ZERO + bne r20, r3, t1 + + /* Quiet exit */ +.quiet_exit: + or r5, ZERO, r2 + + ptabs r18, t0 + blink t0, ZERO + + .section __ex_table, "a" + + .global asm_checksum_start /* Just a marker */ +asm_checksum_start: + .long .src_err_1, _csum_partial_copy_generic_src_err + .long .src_err_2, _csum_partial_copy_generic_src_err + .long .src_err_3, _csum_partial_copy_generic_src_err + .long .src_err_4, _csum_partial_copy_generic_src_err + .long .src_err_5, _csum_partial_copy_generic_src_err + .long .src_err_6, _csum_partial_copy_generic_src_err + .long .src_err_7, _csum_partial_copy_generic_src_err + .long .src_err_8, _csum_partial_copy_generic_src_err + .long .src_err_9, _csum_partial_copy_generic_src_err + .long .src_err_10, _csum_partial_copy_generic_src_err + .long .src_err_11, _csum_partial_copy_generic_src_err + .long .src_err_12, _csum_partial_copy_generic_src_err + .long .src_err_1+4, _csum_partial_copy_generic_dst_err + .long .src_err_2+4, _csum_partial_copy_generic_dst_err + .long .src_err_3+4, _csum_partial_copy_generic_dst_err + .long .src_err_4+4, _csum_partial_copy_generic_dst_err + .long .src_err_5+4, _csum_partial_copy_generic_dst_err + .long .src_err_6+4, _csum_partial_copy_generic_dst_err + .long .src_err_7+4, _csum_partial_copy_generic_dst_err + .long .src_err_8+4, _csum_partial_copy_generic_dst_err + .long .src_err_9+4, _csum_partial_copy_generic_dst_err + .long .src_err_10+4, _csum_partial_copy_generic_dst_err + .long .src_err_11+4, _csum_partial_copy_generic_dst_err + .long .src_err_12+4, _csum_partial_copy_generic_dst_err + + .global asm_checksum_end /* Just a marker */ +asm_checksum_end: +#endif /* NOTDEF */ diff -urN linux-2.4.21/arch/sh64/lib/copy_user_memcpy.S linux-2.4.22/arch/sh64/lib/copy_user_memcpy.S --- linux-2.4.21/arch/sh64/lib/copy_user_memcpy.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/copy_user_memcpy.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,211 @@ +! +! Fast SH memcpy +! +! by Toshiyasu Morita (tm@netcom.com) +! hacked by J"orn Rernnecke (joern.rennecke@superh.com) ("o for o-umlaut) +! SH5 code Copyright 2002 SuperH Ltd. +! +! Entry: ARG0: destination pointer +! ARG1: source pointer +! ARG2: byte count +! +! Exit: RESULT: destination pointer +! any other registers in the range r0-r7: trashed +! +! Notes: Usually one wants to do small reads and write a longword, but +! unfortunately it is difficult in some cases to concatanate bytes +! into a longword on the SH, so this does a longword read and small +! writes. +! +! This implementation makes two assumptions about how it is called: +! +! 1.: If the byte count is nonzero, the address of the last byte to be +! copied is unsigned greater than the address of the first byte to +! be copied. This could be easily swapped for a signed comparison, +! but the algorithm used needs some comparison. +! +! 2.: When there are two or three bytes in the last word of an 11-or-more +! bytes memory chunk to b copied, the rest of the word can be read +! without side effects. +! This could be easily changed by increasing the minumum size of +! a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2, +! however, this would cost a few extra cyles on average. +! For SHmedia, the assumption is that any quadword can be read in its +! enirety if at least one byte is included in the copy. + +/* Imported into Linux kernel by Richard Curnow. This is used to implement the + __copy_user function in the general case, so it has to be a distinct + function from intra-kernel memcpy to allow for exception fix-ups in the + event that the user pointer is bad somewhere in the copy (e.g. due to + running off the end of the vma). + + Note, this algorithm will be slightly wasteful in the case where the source + and destination pointers are equally aligned, because the stlo/sthi pairs + could then be merged back into single stores. If there are a lot of cache + misses, this is probably offset by the stall lengths on the preloads. + +*/ + + .section .text..SHmedia32,"ax" + .little + .balign 32 + .global copy_user_memcpy + .global copy_user_memcpy_end +copy_user_memcpy: + +#define LDUAQ(P,O,D0,D1) ldlo.q P,O,D0; ldhi.q P,O+7,D1 +#define STUAQ(P,O,D0,D1) stlo.q P,O,D0; sthi.q P,O+7,D1 +#define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1 +#define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1 + + ld.b r3,0,r63 + pta/l Large,tr0 + movi 25,r0 + bgeu/u r4,r0,tr0 + nsb r4,r0 + shlli r0,5,r0 + movi (L1-L0+63*32 + 1) & 0xffff,r1 + sub r1, r0, r0 +L0: ptrel r0,tr0 + add r2,r4,r5 + ptabs r18,tr1 + add r3,r4,r6 + blink tr0,r63 + +/* Rearranged to make cut2 safe */ + .balign 8 +L4_7: /* 4..7 byte memcpy cntd. */ + stlo.l r2, 0, r0 + or r6, r7, r6 + sthi.l r5, -1, r6 + stlo.l r5, -4, r6 + blink tr1,r63 + + .balign 8 +L1: /* 0 byte memcpy */ + nop + blink tr1,r63 + nop + nop + nop + nop + +L2_3: /* 2 or 3 byte memcpy cntd. */ + st.b r5,-1,r6 + blink tr1,r63 + + /* 1 byte memcpy */ + ld.b r3,0,r0 + st.b r2,0,r0 + blink tr1,r63 + +L8_15: /* 8..15 byte memcpy cntd. */ + stlo.q r2, 0, r0 + or r6, r7, r6 + sthi.q r5, -1, r6 + stlo.q r5, -8, r6 + blink tr1,r63 + + /* 2 or 3 byte memcpy */ + ld.b r3,0,r0 + ld.b r2,0,r63 + ld.b r3,1,r1 + st.b r2,0,r0 + pta/l L2_3,tr0 + ld.b r6,-1,r6 + st.b r2,1,r1 + blink tr0, r63 + + /* 4 .. 7 byte memcpy */ + LDUAL (r3, 0, r0, r1) + pta L4_7, tr0 + ldlo.l r6, -4, r7 + or r0, r1, r0 + sthi.l r2, 3, r0 + ldhi.l r6, -1, r6 + blink tr0, r63 + + /* 8 .. 15 byte memcpy */ + LDUAQ (r3, 0, r0, r1) + pta L8_15, tr0 + ldlo.q r6, -8, r7 + or r0, r1, r0 + sthi.q r2, 7, r0 + ldhi.q r6, -1, r6 + blink tr0, r63 + + /* 16 .. 24 byte memcpy */ + LDUAQ (r3, 0, r0, r1) + LDUAQ (r3, 8, r8, r9) + or r0, r1, r0 + sthi.q r2, 7, r0 + or r8, r9, r8 + sthi.q r2, 15, r8 + ldlo.q r6, -8, r7 + ldhi.q r6, -1, r6 + stlo.q r2, 8, r8 + stlo.q r2, 0, r0 + or r6, r7, r6 + sthi.q r5, -1, r6 + stlo.q r5, -8, r6 + blink tr1,r63 + +Large: + ld.b r2, 0, r63 + pta/l Loop_ua, tr1 + ori r3, -8, r7 + sub r2, r7, r22 + sub r3, r2, r6 + add r2, r4, r5 + ldlo.q r3, 0, r0 + addi r5, -16, r5 + movi 64+8, r27 ! could subtract r7 from that. + stlo.q r2, 0, r0 + sthi.q r2, 7, r0 + ldx.q r22, r6, r0 + bgtu/l r27, r4, tr1 + + addi r5, -48, r27 + pta/l Loop_line, tr0 + addi r6, 64, r36 + addi r6, -24, r19 + addi r6, -16, r20 + addi r6, -8, r21 + +Loop_line: + ldx.q r22, r36, r63 + alloco r22, 32 + addi r22, 32, r22 + ldx.q r22, r19, r23 + sthi.q r22, -25, r0 + ldx.q r22, r20, r24 + ldx.q r22, r21, r25 + stlo.q r22, -32, r0 + ldx.q r22, r6, r0 + sthi.q r22, -17, r23 + sthi.q r22, -9, r24 + sthi.q r22, -1, r25 + stlo.q r22, -24, r23 + stlo.q r22, -16, r24 + stlo.q r22, -8, r25 + bgeu r27, r22, tr0 + +Loop_ua: + addi r22, 8, r22 + sthi.q r22, -1, r0 + stlo.q r22, -8, r0 + ldx.q r22, r6, r0 + bgtu/l r5, r22, tr1 + + add r3, r4, r7 + ldlo.q r7, -8, r1 + sthi.q r22, 7, r0 + ldhi.q r7, -1, r7 + ptabs r18,tr1 + stlo.q r22, 0, r0 + or r1, r7, r1 + sthi.q r5, 15, r1 + stlo.q r5, 8, r1 + blink tr1, r63 +copy_user_memcpy_end: + nop diff -urN linux-2.4.21/arch/sh64/lib/dbg.c linux-2.4.22/arch/sh64/lib/dbg.c --- linux-2.4.21/arch/sh64/lib/dbg.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/dbg.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,319 @@ +/*-------------------------------------------------------------------------- +-- +-- Identity : Linux50 Debug Funcions +-- +-- File : arch/sh64/lib/dbg.C +-- +-- Copyright 2000, 2001 STMicroelectronics Limited. +-- +--------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +typedef u64 regType_t; + +static regType_t getConfigReg(u64 id) +{ + register u64 reg __asm__("r2"); + asm volatile ("getcfg %1, 0, %0":"=r" (reg):"r"(id)); + return (reg); +} + +/* ======================================================================= */ + +static char *szTab[] = { "4k", "64k", "1M", "512M" }; +static char *protTab[] = { "----", + "---R", + "--X-", + "--XR", + "-W--", + "-W-R", + "-WX-", + "-WXR", + "U---", + "U--R", + "U-X-", + "U-XR", + "UW--", + "UW-R", + "UWX-", + "UWXR" +}; +#define ITLB_BASE 0x00000000 +#define DTLB_BASE 0x00800000 +#define MAX_TLBs 64 +/* PTE High */ +#define GET_VALID(pte) ((pte) & 0x1) +#define GET_SHARED(pte) ((pte) & 0x2) +#define GET_ASID(pte) ((pte >> 2) & 0x0ff) +#define GET_EPN(pte) ((pte) & 0xfffff000) + +/* PTE Low */ +#define GET_CBEHAVIOR(pte) ((pte) & 0x3) +#define GET_PAGE_SIZE(pte) szTab[((pte >> 3) & 0x3)] +#define GET_PROTECTION(pte) protTab[((pte >> 6) & 0xf)] +#define GET_PPN(pte) ((pte) & 0xfffff000) + +#define PAGE_1K_MASK 0x00000000 +#define PAGE_4K_MASK 0x00000010 +#define PAGE_64K_MASK 0x00000080 +#define MMU_PAGESIZE_MASK (PAGE_64K_MASK | PAGE_4K_MASK) +#define PAGE_1MB_MASK MMU_PAGESIZE_MASK +#define PAGE_1K (1024) +#define PAGE_4K (1024 * 4) +#define PAGE_64K (1024 * 64) +#define PAGE_1MB (1024 * 1024) + +#define HOW_TO_READ_TLB_CONTENT \ + "[ ID] PPN EPN ASID Share CB P.Size PROT.\n" + +void print_single_tlb(unsigned long tlb, int single_print) +{ + regType_t pteH; + regType_t pteL; + unsigned int valid, shared, asid, epn, cb, ppn; + char *pSize; + char *pProt; + + /* + ** in case of single print is true, this implies: + ** 1) print the TLB in any case also if NOT VALID + ** 2) print out the header + */ + + pteH = getConfigReg(tlb); + valid = GET_VALID(pteH); + if (single_print) + printk(HOW_TO_READ_TLB_CONTENT); + else if (!valid) + return; + + pteL = getConfigReg(tlb + 1); + + shared = GET_SHARED(pteH); + asid = GET_ASID(pteH); + epn = GET_EPN(pteH); + cb = GET_CBEHAVIOR(pteL); + pSize = GET_PAGE_SIZE(pteL); + pProt = GET_PROTECTION(pteL); + ppn = GET_PPN(pteL); + printk("[%c%2ld] 0x%08x 0x%08x %03d %02x %02x %4s %s\n", + ((valid) ? ' ' : 'u'), ((tlb & 0x0ffff) / TLB_STEP), + ppn, epn, asid, shared, cb, pSize, pProt); +} + +void print_dtlb(void) +{ + int count; + unsigned long tlb; + + printk(" ================= SH-5 D-TLBs Status ===================\n"); + printk(HOW_TO_READ_TLB_CONTENT); + tlb = DTLB_BASE; + for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP) + print_single_tlb(tlb, 0); + printk + (" =============================================================\n"); +} + +void print_itlb(void) +{ + int count; + unsigned long tlb; + + printk(" ================= SH-5 I-TLBs Status ===================\n"); + printk(HOW_TO_READ_TLB_CONTENT); + tlb = ITLB_BASE; + for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP) + print_single_tlb(tlb, 0); + printk + (" =============================================================\n"); +} + +/* ======================================================================= */ + +#include "syscalltab.h" + +void evt_debug(int evt, int ret_addr, int event, int tra) +{ + int syscallno = tra & 0xff; + + // if (event != 0) printk("<%03x>",evt); + + if ((event == 2) && (evt == 0x160)) { + if (syscallno < NUM_SYSCALL_INFO_ENTRIES) + printk("Task %d: %s()\n", + current->pid, + syscall_info_table[syscallno].name); + } +} + +void evt_debug2(unsigned int ret) +{ + printk("Task %d: syscall returns %08x\n", current->pid, ret); +} + +/* ======================================================================= */ + +void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs) +{ + + unsigned long long ah, al, bh, bl, ch, cl; + + printk("\n"); + printk("EXCEPTION - %s: task %d; Linux trap # %d; signal = %d\n", + ((from) ? from : "???"), current->pid, trapnr, signr); + + asm volatile ("getcon " __c5 ", %0":"=r"(ah)); + asm volatile ("getcon " __c5 ", %0":"=r"(al)); + ah = (ah) >> 32; + al = (al) & 0xffffffff; + asm volatile ("getcon " __c18 ", %0":"=r"(bh)); + asm volatile ("getcon " __c18 ", %0":"=r"(bl)); + bh = (bh) >> 32; + bl = (bl) & 0xffffffff; + asm volatile ("getcon " __c4 ", %0":"=r"(ch)); + asm volatile ("getcon " __c4 ", %0":"=r"(cl)); + ch = (ch) >> 32; + cl = (cl) & 0xffffffff; + printk("EXPE: %08Lx%08Lx KCR1: %08Lx%08Lx INTE: %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + asm volatile ("getcon " __c6 ", %0":"=r"(ah)); + asm volatile ("getcon " __c6 ", %0":"=r"(al)); + ah = (ah) >> 32; + al = (al) & 0xffffffff; + asm volatile ("getcon " __c9 ", %0":"=r"(bh)); + asm volatile ("getcon " __c9 ", %0":"=r"(bl)); + bh = (bh) >> 32; + bl = (bl) & 0xffffffff; + asm volatile ("getcon " __c2 ", %0":"=r"(ch)); + asm volatile ("getcon " __c2 ", %0":"=r"(cl)); + ch = (ch) >> 32; + cl = (cl) & 0xffffffff; + printk("PEXP: %08Lx%08Lx PSPC: %08Lx%08Lx PSSR: %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->pc) >> 32; + al = (regs->pc) & 0xffffffff; + bh = (regs->regs[18]) >> 32; + bl = (regs->regs[18]) & 0xffffffff; + ch = (regs->regs[15]) >> 32; + cl = (regs->regs[15]) & 0xffffffff; + printk("PC : %08Lx%08Lx LINK: %08Lx%08Lx SP : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->sr) >> 32; + al = (regs->sr) & 0xffffffff; + asm volatile ("getcon " __c13 ", %0":"=r"(bh)); + asm volatile ("getcon " __c13 ", %0":"=r"(bl)); + bh = (bh) >> 32; + bl = (bl) & 0xffffffff; + asm volatile ("getcon " __c17 ", %0":"=r"(ch)); + asm volatile ("getcon " __c17 ", %0":"=r"(cl)); + ch = (ch) >> 32; + cl = (cl) & 0xffffffff; + printk("SR : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[0]) >> 32; + al = (regs->regs[0]) & 0xffffffff; + bh = (regs->regs[1]) >> 32; + bl = (regs->regs[1]) & 0xffffffff; + ch = (regs->regs[2]) >> 32; + cl = (regs->regs[2]) & 0xffffffff; + printk("R0 : %08Lx%08Lx R1 : %08Lx%08Lx R2 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[3]) >> 32; + al = (regs->regs[3]) & 0xffffffff; + bh = (regs->regs[4]) >> 32; + bl = (regs->regs[4]) & 0xffffffff; + ch = (regs->regs[5]) >> 32; + cl = (regs->regs[5]) & 0xffffffff; + printk("R3 : %08Lx%08Lx R4 : %08Lx%08Lx R5 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[6]) >> 32; + al = (regs->regs[6]) & 0xffffffff; + bh = (regs->regs[7]) >> 32; + bl = (regs->regs[7]) & 0xffffffff; + ch = (regs->regs[8]) >> 32; + cl = (regs->regs[8]) & 0xffffffff; + printk("R6 : %08Lx%08Lx R7 : %08Lx%08Lx R8 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + + ah = (regs->regs[9]) >> 32; + al = (regs->regs[9]) & 0xffffffff; + bh = (regs->regs[10]) >> 32; + bl = (regs->regs[10]) & 0xffffffff; + ch = (regs->regs[11]) >> 32; + cl = (regs->regs[11]) & 0xffffffff; + printk("R9 : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + printk("....\n"); + + ah = (regs->tregs[0]) >> 32; + al = (regs->tregs[0]) & 0xffffffff; + bh = (regs->tregs[1]) >> 32; + bl = (regs->tregs[1]) & 0xffffffff; + ch = (regs->tregs[2]) >> 32; + cl = (regs->tregs[2]) & 0xffffffff; + printk("T0 : %08Lx%08Lx T1 : %08Lx%08Lx T2 : %08Lx%08Lx\n", + ah, al, bh, bl, ch, cl); + printk("....\n"); + + print_dtlb(); + print_itlb(); +} + +/* ======================================================================= */ + +/* +** Depending on scan the MMU, Data or Instrction side +** looking for a valid mapping matching Eaddr & asid. +** Return -1 if not found or the TLB id entry otherwise. +** Note: it works only for 4k pages! +*/ +static unsigned long +lookup_mmu_side(unsigned long base, unsigned long Eaddr, unsigned long asid) +{ + regType_t pteH; + unsigned long epn; + int count; + + epn = Eaddr & 0xfffff000; + + for (count = 0; count < MAX_TLBs; count++, base += TLB_STEP) { + pteH = getConfigReg(base); + if (GET_VALID(pteH)) + if ((unsigned long) GET_EPN(pteH) == epn) + if ((unsigned long) GET_ASID(pteH) == asid) + break; + } + return ((unsigned long) ((count < MAX_TLBs) ? base : -1)); +} + +unsigned long lookup_dtlb(unsigned long Eaddr) +{ + unsigned long asid = get_asid(); + return (lookup_mmu_side((u64) DTLB_BASE, Eaddr, asid)); +} + +unsigned long lookup_itlb(unsigned long Eaddr) +{ + unsigned long asid = get_asid(); + return (lookup_mmu_side((u64) ITLB_BASE, Eaddr, asid)); +} + +void print_page(struct page *page) +{ + printk(" page[%p] -> index 0x%lx, count 0x%x, flags 0x%lx\n", + page, page->index, atomic_read(&page->count), page->flags); + printk(" address_space = %p, pages =%ld\n", page->mapping, + page->mapping->nrpages); + +} diff -urN linux-2.4.21/arch/sh64/lib/io.c linux-2.4.22/arch/sh64/lib/io.c --- linux-2.4.21/arch/sh64/lib/io.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/io.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains the I/O routines for use on the overdrive board + * + */ + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SH_CAYMAN +#include +#endif + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the SuperH architecture, we just read/write the + * memory location directly. + */ + +#define dprintk(x...) + +//#define io_addr(x) (((unsigned)(x) & 0x000fffff)| PCI_ST50_IO_ADDR ) + +#ifdef CONFIG_SH_CAYMAN +extern unsigned long smsc_virt; +extern unsigned long pciio_virt; +#define io_addr(x) ( ((x)<0x400) ? \ + (((x) << 2)|smsc_virt) : \ + ((unsigned long)(x)+pciio_virt) ) +#else +#define io_addr(x) ((unsigned long)(x)+pciio_virt) +#endif + +unsigned long inb(unsigned long port) +{ + unsigned long r; + + r = ctrl_inb(io_addr(port)); + dprintk("inb(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); + return r; +} + +unsigned long inw(unsigned long port) +{ + unsigned long r; + + r = ctrl_inw(io_addr(port)); + dprintk("inw(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); + return r; +} + +unsigned long inl(unsigned long port) +{ + unsigned long r; + + r = ctrl_inl(io_addr(port)); + dprintk("inl(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); + return r; +} + +void outb(unsigned long value, unsigned long port) +{ + dprintk("outb(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); + ctrl_outb(value, io_addr(port)); +} + +void outw(unsigned long value, unsigned long port) +{ + dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); + ctrl_outw(value, io_addr(port)); +} + +void outl(unsigned long value, unsigned long port) +{ + dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); + ctrl_outl(value, io_addr(port)); +} + +/* This is horrible at the moment - needs more work to do something sensible */ +#define IO_DELAY() + +#define OUT_DELAY(x,type) \ +void out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();} + +#define IN_DELAY(x,type) \ +unsigned type in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;} + +#if 1 +OUT_DELAY(b, long) OUT_DELAY(w, long) OUT_DELAY(l, long) + IN_DELAY(b, long) IN_DELAY(w, long) IN_DELAY(l, long) +#endif +/* Now for the string version of these functions */ +void outsb(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p++) { + outb(*p, port); + } +} + +void insb(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p++) { + *p = inb(port); + } +} + +/* For the 16 and 32 bit string functions, we have to worry about alignment. + * The SH does not do unaligned accesses, so we have to read as bytes and + * then write as a word or dword. + * This can be optimised a lot more, especially in the case where the data + * is aligned + */ + +void outsw(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned short tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 2) { + tmp = (*p) | ((*(p + 1)) << 8); + outw(tmp, port); + } +} + +void insw(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned short tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 2) { + tmp = inw(port); + p[0] = tmp & 0xff; + p[1] = (tmp >> 8) & 0xff; + } +} + +void outsl(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 4) { + tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) | + ((*(p + 3)) << 24); + outl(tmp, port); + } +} + +void insl(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 4) { + tmp = inl(port); + p[0] = tmp & 0xff; + p[1] = (tmp >> 8) & 0xff; + p[2] = (tmp >> 16) & 0xff; + p[3] = (tmp >> 24) & 0xff; + + } +} + +void memcpy_toio(unsigned long to, const void *from, long count) +{ + unsigned char *p = (unsigned char *) from; + + while (count) { + count--; + writeb(*p++, to++); + } +} + +void memcpy_fromio(void *to, unsigned long from, long count) +{ + int i; + unsigned char *p = (unsigned char *) to; + + for (i = 0; i < count; i++) { + p[i] = readb(from); + from++; + } +} diff -urN linux-2.4.21/arch/sh64/lib/memcpy.c linux-2.4.22/arch/sh64/lib/memcpy.c --- linux-2.4.21/arch/sh64/lib/memcpy.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/memcpy.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2002 Mark Debbage (Mark.Debbage@superh.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + */ + +#include +#include +#include + +// This is a simplistic optimization of memcpy to increase the +// granularity of access beyond one byte using aligned +// loads and stores. This is not an optimal implementation +// for SH-5 (especially with regard to prefetching and the cache), +// and a better version should be provided later ... + +void *memcpy(void *dest, const void *src, size_t count) +{ + char *d = (char *) dest, *s = (char *) src; + + if (count >= 32) { + int i = 8 - (((unsigned long) d) & 0x7); + + if (i != 8) + while (i-- && count--) { + *d++ = *s++; + } + + if (((((unsigned long) d) & 0x7) == 0) && + ((((unsigned long) s) & 0x7) == 0)) { + while (count >= 32) { + unsigned long long t1, t2, t3, t4; + t1 = *(unsigned long long *) (s); + t2 = *(unsigned long long *) (s + 8); + t3 = *(unsigned long long *) (s + 16); + t4 = *(unsigned long long *) (s + 24); + *(unsigned long long *) (d) = t1; + *(unsigned long long *) (d + 8) = t2; + *(unsigned long long *) (d + 16) = t3; + *(unsigned long long *) (d + 24) = t4; + d += 32; + s += 32; + count -= 32; + } + while (count >= 8) { + *(unsigned long long *) d = + *(unsigned long long *) s; + d += 8; + s += 8; + count -= 8; + } + } + + if (((((unsigned long) d) & 0x3) == 0) && + ((((unsigned long) s) & 0x3) == 0)) { + while (count >= 4) { + *(unsigned long *) d = *(unsigned long *) s; + d += 4; + s += 4; + count -= 4; + } + } + + if (((((unsigned long) d) & 0x1) == 0) && + ((((unsigned long) s) & 0x1) == 0)) { + while (count >= 2) { + *(unsigned short *) d = *(unsigned short *) s; + d += 2; + s += 2; + count -= 2; + } + } + } + + while (count--) { + *d++ = *s++; + } + + return d; +} diff -urN linux-2.4.21/arch/sh64/lib/old-checksum.c linux-2.4.22/arch/sh64/lib/old-checksum.c --- linux-2.4.21/arch/sh64/lib/old-checksum.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/old-checksum.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,17 @@ +/* + * FIXME: old compatibility stuff, will be removed soon. + */ + +#include + +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum) +{ + int src_err=0, dst_err=0; + + sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err); + + if (src_err || dst_err) + printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n"); + + return sum; +} diff -urN linux-2.4.21/arch/sh64/lib/page_clear.S linux-2.4.22/arch/sh64/lib/page_clear.S --- linux-2.4.21/arch/sh64/lib/page_clear.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/page_clear.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,46 @@ +/* Written by Richard P. Curnow, SuperH (UK) Ltd. + + Tight version of memset for the case of just clearing a page. It turns out + that having the alloco's spaced out slightly due to the increment/branch + pair causes them to contend less for access to the cache. Similarly, + keeping the stores apart from the allocos causes less contention. => Do two + separate loops. Do multiple stores per loop to amortise the + increment/branch cost a little. + + Parameters: + r2 : source effective address (start of page) + + Always clears 4096 bytes. + +*/ + + .section .text..SHmedia32,"ax" + .little + + .balign 8 + .global sh64_page_clear +sh64_page_clear: + pta/l 1f, tr1 + pta/l 2f, tr2 + ptabs/l r18, tr0 + + movi 4096, r7 + add r2, r7, r7 + add r2, r63, r6 +1: + alloco r6, 0 + addi r6, 32, r6 + bgt/l r7, r6, tr1 + + add r2, r63, r6 +2: + st.q r6, 0, r63 + st.q r6, 8, r63 + st.q r6, 16, r63 + st.q r6, 24, r63 + addi r6, 32, r6 + bgt/l r7, r6, tr2 + + blink tr0, r63 + + diff -urN linux-2.4.21/arch/sh64/lib/page_copy.S linux-2.4.22/arch/sh64/lib/page_copy.S --- linux-2.4.21/arch/sh64/lib/page_copy.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/page_copy.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,77 @@ +/* Written by Richard P. Curnow, SuperH (UK) Ltd. + + Tight version of mempy for the case of just copying a page. + Prefetch strategy empirically optimised against RTL simulations + of SH5-101 cut2 eval chip with Cayman board DDR memory. + + Parameters: + r2 : source effective address (start of page) + r3 : destination effective address (start of page) + + Always copies 4096 bytes. + + Points to review. + * Currently the prefetch is 4 lines ahead and the alloco is 2 lines ahead. + It seems like the prefetch needs to be at at least 4 lines ahead to get + the data into the cache in time, and the allocos contend with outstanding + prefetches for the same cache set, so it's better to have the numbers + different. + */ + + .section .text..SHmedia32,"ax" + .little + + .balign 8 + .global sh64_page_copy +sh64_page_copy: + + /* Copy 4096 bytes worth of data from r2 to r3. + Do prefetches 4 lines ahead. + Do alloco 2 lines ahead */ + + pta 1f, tr1 + pta 2f, tr2 + pta 3f, tr3 + ptabs r18, tr0 + + ld.q r2, 0x00, r63 + ld.q r2, 0x20, r63 + ld.q r2, 0x40, r63 + ld.q r2, 0x60, r63 + alloco r3, 0x00 + alloco r3, 0x20 + + movi 3968, r6 + add r3, r6, r6 + addi r6, 64, r7 + addi r7, 64, r8 + sub r2, r3, r60 + addi r60, 8, r61 + addi r61, 8, r62 + addi r62, 8, r23 + addi r60, 0x80, r22 + +/* Minimal code size. The extra branches inside the loop don't cost much + because they overlap with the time spent waiting for prefetches to + complete. */ +1: + bge/u r3, r6, tr2 ! skip prefetch for last 4 lines + ldx.q r3, r22, r63 ! prefetch 4 lines hence +2: + bge/u r3, r7, tr3 ! skip alloco for last 2 lines + alloco r3, 0x40 ! alloc destination line 2 lines ahead +3: + ldx.q r3, r60, r36 + ldx.q r3, r61, r37 + ldx.q r3, r62, r38 + ldx.q r3, r23, r39 + st.q r3, 0, r36 + st.q r3, 8, r37 + st.q r3, 16, r38 + st.q r3, 24, r39 + addi r3, 32, r3 + bgt/l r8, r3, tr1 + + blink tr0, r63 ! return + + diff -urN linux-2.4.21/arch/sh64/lib/panic.c linux-2.4.22/arch/sh64/lib/panic.c --- linux-2.4.21/arch/sh64/lib/panic.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/panic.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,60 @@ +/* Panic handler. MUST BE PIC. BE CAREFUL WHAT YOU DO, + * AS THERE ARE NO STATICS AVAILABLE, AND NOWHERE TO GO + * MMU IS OFF!!!!!!!! + */ + +#include +#include +#include + +/* THIS IS A PHYSICAL ADDRESS */ +#define HDSP2534_ADDR (0x04002100) + +void +panic_handler(unsigned long panicPC, unsigned long panicSSR, + unsigned long panicEXPEVT) +{ + int i; + unsigned nibble; + +#ifdef CONFIG_SH_CAYMAN + + while (1) { + + /* This piece of code displays the PC on the LED display */ + for (i = 0; i < 8; i++) { + nibble = ((panicPC >> (i * 4)) & 0xf); + + ctrl_outb(nibble + ((nibble > 9) ? 55 : 48), + HDSP2534_ADDR + 0xe0 + ((7 - i) << 2)); + } + + for (i = 0; i < 2500000; i++) { + } /* poor man's delay */ + + for (i = 0; i < 8; i++) { + nibble = ((panicSSR >> (i * 4)) & 0xf); + + ctrl_outb(nibble + ((nibble > 9) ? 55 : 48), + HDSP2534_ADDR + 0xe0 + ((7 - i) << 2)); + } + + for (i = 0; i < 2500000; i++) { + } /* poor man's delay */ + + for (i = 0; i < 8; i++) { + nibble = ((panicEXPEVT >> (i * 4)) & 0xf); + + ctrl_outb(nibble + ((nibble > 9) ? 55 : 48), + HDSP2534_ADDR + 0xe0 + ((7 - i) << 2)); + } + + for (i = 0; i < 2500000; i++) { + } /* poor man's delay */ + } +#endif + + /* Never return from the panic handler */ + for (;;) ; + +} diff -urN linux-2.4.21/arch/sh64/lib/syscalltab.h linux-2.4.22/arch/sh64/lib/syscalltab.h --- linux-2.4.21/arch/sh64/lib/syscalltab.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/syscalltab.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,311 @@ +struct syscall_info { + int num_params; + const char *name; +}; + +struct syscall_info syscall_info_table[]={ + { 0, "setup" }, /* 0 */ + { 1, "_exit" }, /* 1 */ + { 0, "fork" }, /* 2 */ + { 3, "read" }, /* 3 */ + { 3, "write" }, /* 4 */ + { 3, "open" }, /* 5 */ + { 1, "close" }, /* 6 */ + { 3, "waitpid" }, /* 7 */ + { 2, "creat" }, /* 8 */ + { 2, "link" }, /* 9 */ + { 1, "unlink" }, /* 10 */ + { 3, "execve" }, /* 11 */ + { 1, "chdir" }, /* 12 */ + { 1, "time" }, /* 13 */ + { 3, "mknod" }, /* 14 */ + { 2, "chmod" }, /* 15 */ + { 3, "lchown" }, /* 16 */ + { 0, "break" }, /* 17 */ + { 2, "oldstat" }, /* 18 */ + { 3, "lseek" }, /* 19 */ + { 0, "getpid" }, /* 20 */ + { 5, "mount" }, /* 21 */ + { 1, "oldumount" }, /* 22 */ + { 1, "setuid" }, /* 23 */ + { 0, "getuid" }, /* 24 */ + { 1, "stime" }, /* 25 */ + { 4, "ptrace" }, /* 26 */ + { 1, "alarm" }, /* 27 */ + { 2, "oldfstat" }, /* 28 */ + { 0, "pause" }, /* 29 */ + { 2, "utime" }, /* 30 */ + { 2, "stty" }, /* 31 */ + { 2, "gtty" }, /* 32 */ + { 2, "access" }, /* 33 */ + { 1, "nice" }, /* 34 */ + { 0, "ftime" }, /* 35 */ + { 0, "sync" }, /* 36 */ + { 2, "kill" }, /* 37 */ + { 2, "rename" }, /* 38 */ + { 2, "mkdir" }, /* 39 */ + { 1, "rmdir" }, /* 40 */ + { 1, "dup" }, /* 41 */ + { 1, "pipe" }, /* 42 */ + { 1, "times" }, /* 43 */ + { 0, "prof" }, /* 44 */ + { 1, "brk" }, /* 45 */ + { 1, "setgid" }, /* 46 */ + { 0, "getgid" }, /* 47 */ + { 3, "signal" }, /* 48 */ + { 0, "geteuid" }, /* 49 */ + { 0, "getegid" }, /* 50 */ + { 1, "acct" }, /* 51 */ + { 2, "umount" }, /* 52 */ + { 0, "lock" }, /* 53 */ + { 3, "ioctl" }, /* 54 */ + { 3, "fcntl" }, /* 55 */ + { 0, "mpx" }, /* 56 */ + { 2, "setpgid" }, /* 57 */ + { 2, "ulimit" }, /* 58 */ + { 1, "oldolduname" }, /* 59 */ + { 1, "umask" }, /* 60 */ + { 1, "chroot" }, /* 61 */ + { 2, "ustat" }, /* 62 */ + { 2, "dup2" }, /* 63 */ + { 0, "getppid" }, /* 64 */ + { 0, "getpgrp" }, /* 65 */ + { 0, "setsid" }, /* 66 */ + { 3, "sigaction" }, /* 67 */ + { 0, "siggetmask" }, /* 68 */ + { 1, "sigsetmask" }, /* 69 */ + { 2, "setreuid" }, /* 70 */ + { 2, "setregid" }, /* 71 */ + { 3, "sigsuspend" }, /* 72 */ + { 1, "sigpending" }, /* 73 */ + { 2, "sethostname" }, /* 74 */ + { 2, "setrlimit" }, /* 75 */ + { 2, "getrlimit" }, /* 76 */ + { 2, "getrusage" }, /* 77 */ + { 2, "gettimeofday" }, /* 78 */ + { 2, "settimeofday" }, /* 79 */ + { 2, "getgroups" }, /* 80 */ + { 2, "setgroups" }, /* 81 */ + { 1, "oldselect" }, /* 82 */ + { 2, "symlink" }, /* 83 */ + { 2, "oldlstat" }, /* 84 */ + { 3, "readlink" }, /* 85 */ + { 1, "uselib" }, /* 86 */ + { 1, "swapon" }, /* 87 */ + { 3, "reboot" }, /* 88 */ + { 3, "readdir" }, /* 89 */ + { 6, "old_mmap" }, /* 90 */ + { 2, "munmap" }, /* 91 */ + { 2, "truncate" }, /* 92 */ + { 2, "ftruncate" }, /* 93 */ + { 2, "fchmod" }, /* 94 */ + { 3, "fchown" }, /* 95 */ + { 2, "getpriority" }, /* 96 */ + { 3, "setpriority" }, /* 97 */ + { 4, "profil" }, /* 98 */ + { 2, "statfs" }, /* 99 */ + { 2, "fstatfs" }, /* 100 */ + { 3, "ioperm" }, /* 101 */ + { 2, "socketcall" }, /* 102 */ + { 3, "syslog" }, /* 103 */ + { 3, "setitimer" }, /* 104 */ + { 2, "getitimer" }, /* 105 */ + { 2, "stat" }, /* 106 */ + { 2, "lstat" }, /* 107 */ + { 2, "fstat" }, /* 108 */ + { 1, "olduname" }, /* 109 */ + { 1, "iopl" }, /* 110 */ + { 0, "vhangup" }, /* 111 */ + { 0, "idle" }, /* 112 */ + { 1, "vm86old" }, /* 113 */ + { 4, "wait4" }, /* 114 */ + { 1, "swapoff" }, /* 115 */ + { 1, "sysinfo" }, /* 116 */ + { 5, "ipc" }, /* 117 */ + { 1, "fsync" }, /* 118 */ + { 1, "sigreturn" }, /* 119 */ + { 2, "clone" }, /* 120 */ + { 2, "setdomainname" }, /* 121 */ + { 1, "uname" }, /* 122 */ + { 3, "modify_ldt" }, /* 123 */ + { 1, "adjtimex" }, /* 124 */ + { 3, "mprotect" }, /* 125 */ + { 3, "sigprocmask" }, /* 126 */ + { 2, "create_module" }, /* 127 */ + { 2, "init_module" }, /* 128 */ + { 1, "delete_module" }, /* 129 */ + { 1, "get_kernel_syms"}, /* 130 */ + { 4, "quotactl" }, /* 131 */ + { 1, "getpgid" }, /* 132 */ + { 1, "fchdir" }, /* 133 */ + { 0, "bdflush" }, /* 134 */ + { 3, "sysfs" }, /* 135 */ + { 1, "personality" }, /* 136 */ + { 5, "afs_syscall" }, /* 137 */ + { 1, "setfsuid" }, /* 138 */ + { 1, "setfsgid" }, /* 139 */ + { 5, "_llseek" }, /* 140 */ + { 3, "getdents" }, /* 141 */ + { 5, "select" }, /* 142 */ + { 2, "flock" }, /* 143 */ + { 3, "msync" }, /* 144 */ + { 3, "readv" }, /* 145 */ + { 3, "writev" }, /* 146 */ + { 1, "getsid" }, /* 147 */ + { 1, "fdatasync" }, /* 148 */ + { 1, "_sysctl" }, /* 149 */ + { 1, "mlock" }, /* 150 */ + { 2, "munlock" }, /* 151 */ + { 2, "mlockall" }, /* 152 */ + { 1, "munlockall" }, /* 153 */ + { 0, "sched_setparam"}, /* 154 */ + { 2, "sched_getparam"}, /* 155 */ + { 3, "sched_setscheduler"}, /* 156 */ + { 1, "sched_getscheduler"}, /* 157 */ + { 0, "sched_yield"}, /* 158 */ + { 1, "sched_get_priority_max"}, /* 159 */ + { 1, "sched_get_priority_min"}, /* 160 */ + { 2, "sched_rr_get_interval"}, /* 161 */ + { 2, "nanosleep" }, /* 162 */ + { 4, "mremap" }, /* 163 */ + { 3, "setresuid" }, /* 164 */ + { 3, "getresuid" }, /* 165 */ + { 5, "vm86" }, /* 166 */ + { 5, "query_module" }, /* 167 */ + { 3, "poll" }, /* 168 */ + { 3, "nfsservctl" }, /* 169 */ + { 3, "setresgid" }, /* 170 */ + { 3, "getresgid" }, /* 171 */ + { 5, "prctl" }, /* 172 */ + { 1, "rt_sigreturn" }, /* 173 */ + { 4, "rt_sigaction" }, /* 174 */ + { 4, "rt_sigprocmask"}, /* 175 */ + { 2, "rt_sigpending" }, /* 176 */ + { 4, "rt_sigtimedwait"}, /* 177 */ + { 3, "rt_sigqueueinfo"}, /* 178 */ + { 2, "rt_sigsuspend" }, /* 179 */ + + { 5, "pread" }, /* 180 */ + { 5, "pwrite" }, /* 181 */ + { 3, "chown" }, /* 182 */ + { 2, "getcwd" }, /* 183 */ + { 2, "capget" }, /* 184 */ + { 2, "capset" }, /* 185 */ + { 2, "sigaltstack" }, /* 186 */ + { 4, "sendfile" }, /* 187 */ + { 5, "SYS_188" }, /* 188 */ + { 5, "SYS_189" }, /* 189 */ + { 0, "vfork" }, /* 190 */ + { 5, "getrlimit" }, /* 191 */ + { 6, "mmap2" }, /* 192 */ + { 5, "truncate64" }, /* 193 */ + { 5, "ftruncate64" }, /* 194 */ + { 2, "stat64" }, /* 195 */ + { 2, "lstat64" }, /* 196 */ + { 2, "fstat64" }, /* 197 */ + { 3, "lchown32" }, /* 198 */ + { 0, "getuid32" }, /* 199 */ + + { 0, "getgid32" }, /* 200 */ + { 0, "geteuid32" }, /* 201 */ + { 0, "getegid32" }, /* 202 */ + { 2, "setreuid32" }, /* 203 */ + { 2, "setregid32" }, /* 204 */ + { 2, "getgroups32" }, /* 205 */ + { 2, "setgroups32" }, /* 206 */ + { 3, "fchown32" }, /* 207 */ + { 3, "setresuid32" }, /* 208 */ + { 3, "getresuid32" }, /* 209 */ + { 3, "setresgid32" }, /* 210 */ + { 3, "getsetgid32" }, /* 211 */ + { 3, "chown32" }, /* 212 */ + { 1, "setuid32" }, /* 213 */ + { 1, "setgid32" }, /* 214 */ + { 1, "setfsuid32" }, /* 215 */ + { 1, "setfsgid32" }, /* 216 */ + { 2, "pivot_root" }, /* 217 */ + { 3, "mincore" }, /* 218 */ + { 3, "madvise" }, /* 219 */ + { 4, "getdents64" }, /* 220 */ + { 3, "fcntl64" }, /* 221 */ + { 4, "SYS_222" }, /* 222 */ + { 4, "SYS_223" }, /* 223 */ + { 4, "SYS_224" }, /* 224 */ + { 5, "SYS_225" }, /* 225 */ + { 5, "SYS_226" }, /* 226 */ + { 5, "SYS_227" }, /* 227 */ + { 5, "SYS_228" }, /* 228 */ + { 5, "SYS_229" }, /* 229 */ + { 8, "socket_subcall"}, /* 230 */ + { 3, "socket" }, /* 231 */ + { 3, "bind" }, /* 232 */ + { 3, "connect" }, /* 233 */ + { 2, "listen" }, /* 234 */ + { 3, "accept" }, /* 235 */ + { 3, "getsockname" }, /* 236 */ + { 3, "getpeername" }, /* 237 */ + { 4, "socketpair" }, /* 238 */ + { 4, "send" }, /* 239 */ + { 4, "recv" }, /* 240 */ + { 6, "sendto" }, /* 241 */ + { 6, "recvfrom" }, /* 242 */ + { 2, "shutdown" }, /* 243 */ + { 5, "setsockopt" }, /* 244 */ + { 5, "getsockopt" }, /* 245 */ + { 5, "sendmsg" }, /* 246 */ + { 5, "recvmsg" }, /* 247 */ + { 5, "SYS_248" }, /* 248 */ + { 5, "SYS_249" }, /* 249 */ + { 4, "ipc_subcall" }, /* 250 */ + { 4, "semop" }, /* 251 */ + { 4, "semget" }, /* 252 */ + { 4, "semctl" }, /* 253 */ + { 4, "ipc_subcall" }, /* 254 */ + { 4, "ipc_subcall" }, /* 255 */ + { 4, "ipc_subcall" }, /* 256 */ + { 4, "ipc_subcall" }, /* 257 */ + { 4, "ipc_subcall" }, /* 258 */ + { 4, "ipc_subcall" }, /* 259 */ + { 4, "ipc_subcall" }, /* 260 */ + { 4, "msgsnd" }, /* 261 */ + { 4, "msgrcv" }, /* 262 */ + { 4, "msgget" }, /* 263 */ + { 4, "msgctl" }, /* 264 */ + { 4, "ipc_subcall" }, /* 265 */ + { 4, "ipc_subcall" }, /* 266 */ + { 4, "ipc_subcall" }, /* 267 */ + { 4, "ipc_subcall" }, /* 268 */ + { 4, "ipc_subcall" }, /* 269 */ + { 4, "ipc_subcall" }, /* 270 */ + { 4, "shmat" }, /* 271 */ + { 4, "shmdt" }, /* 272 */ + { 4, "shmget" }, /* 273 */ + { 4, "shmctl" }, /* 274 */ + { 5, "SYS_275" }, /* 275 */ + { 5, "SYS_276" }, /* 276 */ + { 5, "SYS_277" }, /* 277 */ + { 5, "SYS_278" }, /* 278 */ + { 5, "SYS_279" }, /* 279 */ + { 8, "socket_subcall"}, /* 280 */ + { 3, "socket" }, /* 281 */ + { 3, "bind" }, /* 282 */ + { 3, "connect" }, /* 283 */ + { 2, "listen" }, /* 284 */ + { 3, "accept" }, /* 285 */ + { 3, "getsockname" }, /* 286 */ + { 3, "getpeername" }, /* 287 */ + { 4, "socketpair" }, /* 288 */ + { 4, "send" }, /* 289 */ + { 4, "recv" }, /* 290 */ + { 6, "sendto" }, /* 291 */ + { 6, "recvfrom" }, /* 292 */ + { 2, "shutdown" }, /* 293 */ + { 5, "setsockopt" }, /* 294 */ + { 5, "getsockopt" }, /* 295 */ + { 5, "sendmsg" }, /* 296 */ + { 5, "recvmsg" }, /* 297 */ + { 5, "SYS_298" }, /* 298 */ + { 5, "SYS_299" }, /* 299 */ +}; + +#define NUM_SYSCALL_INFO_ENTRIES (sizeof(syscall_info_table)/sizeof(struct syscall_info)) diff -urN linux-2.4.21/arch/sh64/lib/udelay.c linux-2.4.22/arch/sh64/lib/udelay.c --- linux-2.4.21/arch/sh64/lib/udelay.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/lib/udelay.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1993, 2000 Linus Torvalds + * + * Delay routines, using a pre-computed "loops_per_jiffy" value. + */ +#include +#include +#include +#include +#include + +/* + * Use only for very small delays (< 1 msec). + * + * The active part of our cycle counter is only 32-bits wide, and + * we're treating the difference between two marks as signed. On + * a 1GHz box, that's about 2 seconds. + */ + +void __delay(int loops) +{ + long long dummy; + __asm__ __volatile__("gettr " __t0 ", %1\n\t" + "_pta 4, " __t0 "\n\t" + "addi %0, -1, %0\n\t" + "bne %0, r63, " __t0 "\n\t" + "ptabs %1, " __t0 "\n\t":"=r"(loops), + "=r"(dummy) + :"0"(loops)); +} + +void __udelay(unsigned long long usecs, unsigned long lpj) +{ + usecs *= (((unsigned long long) HZ << 32) / 1000000) * lpj; + __delay((long long) usecs >> 32); +} + +void __ndelay(unsigned long long nsecs, unsigned long lpj) +{ + nsecs *= (((unsigned long long) HZ << 32) / 1000000000) * lpj; + __delay((long long) nsecs >> 32); +} + +void udelay(unsigned long usecs) +{ + __udelay(usecs, loops_per_jiffy); +} + +void ndelay(unsigned long nsecs) +{ + __ndelay(nsecs, loops_per_jiffy); +} + diff -urN linux-2.4.21/arch/sh64/mach-cayman/Makefile linux-2.4.22/arch/sh64/mach-cayman/Makefile --- linux-2.4.21/arch/sh64/mach-cayman/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mach-cayman/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,15 @@ +# +# Makefile for the Hitachi Cayman specific parts of the kernel +# +# 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). +# + +O_TARGET := cayman.o + +obj-y := setup.o irq.o +obj-$(CONFIG_HEARTBEAT) += led.o + +include $(TOPDIR)/Rules.make + diff -urN linux-2.4.21/arch/sh64/mach-cayman/irq.c linux-2.4.22/arch/sh64/mach-cayman/irq.c --- linux-2.4.21/arch/sh64/mach-cayman/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mach-cayman/irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,191 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/kernel/irq_cayman.c + * + * SH-5 Cayman Interrupt Support + * + * This file handles the board specific parts of the Cayman interrupt system + * + * Copyright (C) 2002 Stuart Menefy + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long epld_virt; + +#define EPLD_BASE 0x04002000 +#define EPLD_STATUS_BASE (epld_virt + 0x10) +#define EPLD_MASK_BASE (epld_virt + 0x20) + +static void cayman_interrupt_smsc(int irq, void *dev_id, struct pt_regs *regs) +{ + printk(KERN_INFO "CAYMAN: spurious interrupt\n"); +} + +static void cayman_interrupt_pci2(int irq, void *dev_id, struct pt_regs *regs) +{ + printk(KERN_INFO "CAYMAN: spurious PCI interrupt, IRQ %d\n", irq); +} + +static struct irqaction cayman_action_smsc = { + .name = "Cayman SMSC Mux", + .handler = cayman_interrupt_smsc, + .flags = SA_INTERRUPT, +}; + +static struct irqaction cayman_action_pci2 = { + .name = "Cayman PCI2 Mux", + .handler = cayman_interrupt_pci2, + .flags = SA_INTERRUPT, +}; + +static void enable_cayman_irq(unsigned int irq) +{ + unsigned long flags; + unsigned long mask; + unsigned int reg; + unsigned char bit; + + irq -= START_EXT_IRQS; + reg = EPLD_MASK_BASE + ((irq / 8) << 2); + bit = 1<<(irq % 8); + save_and_cli(flags); + mask = ctrl_inl(reg); + mask |= bit; + ctrl_outl(mask, reg); + restore_flags(flags); +} + +void disable_cayman_irq(unsigned int irq) +{ + unsigned long flags; + unsigned long mask; + unsigned int reg; + unsigned char bit; + + irq -= START_EXT_IRQS; + reg = EPLD_MASK_BASE + ((irq / 8) << 2); + bit = 1<<(irq % 8); + save_and_cli(flags); + mask = ctrl_inl(reg); + mask &= ~bit; + ctrl_outl(mask, reg); + restore_flags(flags); +} + +static void ack_cayman_irq(unsigned int irq) +{ + disable_cayman_irq(irq); +} + +static void end_cayman_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_cayman_irq(irq); +} + +static unsigned int startup_cayman_irq(unsigned int irq) +{ + enable_cayman_irq(irq); + return 0; /* never anything pending */ +} + +static void shutdown_cayman_irq(unsigned int irq) +{ + disable_cayman_irq(irq); +} + +struct hw_interrupt_type cayman_irq_type = { + .typename = "Cayman-IRQ", + .startup = startup_cayman_irq, + .shutdown = shutdown_cayman_irq, + .enable = enable_cayman_irq, + .disable = disable_cayman_irq, + .ack = ack_cayman_irq, + .end = end_cayman_irq, +}; + +int cayman_irq_demux(int evt) +{ + int irq = intc_evt_to_irq[evt]; + + if (irq == SMSC_IRQ) { + unsigned long status; + int i; + + status = ctrl_inl(EPLD_STATUS_BASE) & + ctrl_inl(EPLD_MASK_BASE) & 0xff; + if (status == 0) { + irq = -1; + } else { + for (i=0; i<8; i++) { + if (status & (1<= NR_INTC_IRQS + 24) && (irq < NR_INTC_IRQS + 32)) { + return sprintf(p, "(PCI2 %d)", irq - (NR_INTC_IRQS + 24)); + } + + return 0; +} +#endif + +void init_cayman_irq(void) +{ + int i; + + epld_virt = onchip_remap(EPLD_BASE, 1024, "EPLD"); + if (!epld_virt) { + printk(KERN_ERR "Cayman IRQ: Unable to remap EPLD\n"); + return; + } + + for (i=0; i + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Flash the LEDs + */ +#include + +/* +** It is supposed these functions to be used for a low level +** debugging (via Cayman LEDs), hence to be available as soon +** as possible. +** Unfortunately Cayman LEDs relies on Cayman EPLD to be mapped +** (this happen when IRQ are initialized... quite late). +** These triky dependencies should be removed. Temporary, it +** may be enough to NOP until EPLD is mapped. +*/ + +extern unsigned long epld_virt; + +#define LED_ADDR (epld_virt + 0x008) +#define HDSP2534_ADDR (epld_virt + 0x100) + +void mach_led(int position, int value) +{ + if (!epld_virt) + return; + + if (value) + ctrl_outl(0, LED_ADDR); + else + ctrl_outl(1, LED_ADDR); + +} + +void mach_alphanum(int position, unsigned char value) +{ + if (!epld_virt) + return; + + ctrl_outb(value, HDSP2534_ADDR + 0xe0 + (position << 2)); +} + +void mach_alphanum_brightness(int setting) +{ + ctrl_outb(setting & 7, HDSP2534_ADDR + 0xc0); +} diff -urN linux-2.4.21/arch/sh64/mach-cayman/setup.c linux-2.4.22/arch/sh64/mach-cayman/setup.c --- linux-2.4.21/arch/sh64/mach-cayman/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mach-cayman/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,209 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mach-cayman/setup.c + * + * SH5 Cayman support + * + * This file handles the architecture-dependent parts of initialization + * + * Copyright David J. Mckay. + * Needs major work! + * + * benedict.gaster@superh.com: 3rd May 2002 + * Added support for ramdisk, removing statically linked romfs at the same time. + * + * lethal@linux-sh.org: 15th May 2003 + * Use the generic procfs cpuinfo interface, just return a valid board name. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource))) + +/* + * Platform Dependent Interrupt Priorities. + */ + +/* Using defaults defined in irq.h */ +#define RES NO_PRIORITY /* Disabled */ +#define IR0 IRL0_PRIORITY /* IRLs */ +#define IR1 IRL1_PRIORITY +#define IR2 IRL2_PRIORITY +#define IR3 IRL3_PRIORITY +#define PCA INTA_PRIORITY /* PCI Ints */ +#define PCB INTB_PRIORITY +#define PCC INTC_PRIORITY +#define PCD INTD_PRIORITY +#define SER TOP_PRIORITY +#define ERR TOP_PRIORITY +#define PW0 TOP_PRIORITY +#define PW1 TOP_PRIORITY +#define PW2 TOP_PRIORITY +#define PW3 TOP_PRIORITY +#define DM0 NO_PRIORITY /* DMA Ints */ +#define DM1 NO_PRIORITY +#define DM2 NO_PRIORITY +#define DM3 NO_PRIORITY +#define DAE NO_PRIORITY +#define TU0 TIMER_PRIORITY /* TMU Ints */ +#define TU1 NO_PRIORITY +#define TU2 NO_PRIORITY +#define TI2 NO_PRIORITY +#define ATI NO_PRIORITY /* RTC Ints */ +#define PRI NO_PRIORITY +#define CUI RTC_PRIORITY +#define ERI SCIF_PRIORITY /* SCIF Ints */ +#define RXI SCIF_PRIORITY +#define BRI SCIF_PRIORITY +#define TXI SCIF_PRIORITY +#define ITI TOP_PRIORITY /* WDT Ints */ + +/* Setup for the SMSC FDC37C935 */ +#define SMSC_BASE 0x04000000 +#define SMSC_CONFIG_PORT_ADDR 0x3f0 +#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR +#define SMSC_DATA_PORT_ADDR 0x3f1 + +#define SMSC_ENTER_CONFIG_KEY 0x55 +#define SMSC_EXIT_CONFIG_KEY 0xaa + +#define SMCS_LOGICAL_DEV_INDEX 0x07 +#define SMSC_DEVICE_ID_INDEX 0x20 +#define SMSC_DEVICE_REV_INDEX 0x21 +#define SMSC_ACTIVATE_INDEX 0x30 +#define SMSC_PRIMARY_INT_INDEX 0x70 +#define SMSC_SECONDARY_INT_INDEX 0x72 + +#define SMSC_KEYBOARD_DEVICE 7 + +#define SMSC_READ_INDEXED(index) ({ \ + outb((index), SMSC_INDEX_PORT_ADDR); \ + inb(SMSC_DATA_PORT_ADDR); }) +#define SMSC_WRITE_INDEXED(val, index) ({ \ + outb((index), SMSC_INDEX_PORT_ADDR); \ + outb((val), SMSC_DATA_PORT_ADDR); }) + +unsigned long smsc_virt; + +/* + * Platform dependent structures: maps and parms block. + */ +struct resource io_resources[] = { + /* To be updated with external devices */ +}; + +struct resource kram_resources[] = { + { "Kernel code", 0, 0 }, /* These must be last in the array */ + { "Kernel data", 0, 0 } /* These must be last in the array */ +}; + +struct resource xram_resources[] = { + /* To be updated with external devices */ +}; + +struct resource rom_resources[] = { + /* To be updated with external devices */ +}; + +struct sh64_platform platform_parms = { + .readonly_rootfs = 1, + .initial_root_dev = 0x0100, + .loader_type = 1, + .io_res_p = io_resources, + .io_res_count = RES_COUNT(io_resources), + .kram_res_p = kram_resources, + .kram_res_count = RES_COUNT(kram_resources), + .xram_res_p = xram_resources, + .xram_res_count = RES_COUNT(xram_resources), + .rom_res_p = rom_resources, + .rom_res_count = RES_COUNT(rom_resources), +}; + +int platform_int_priority[NR_INTC_IRQS] = { + IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ + RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ + PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */ + TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */ + RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */ + RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */ +}; + +static int __init smsc_setup(void) +{ + unsigned char devid, devrev; + + smsc_virt = onchip_remap(SMSC_BASE, 1024, "SMSC"); + if (!smsc_virt) { + panic("Unable to remap SMSC\n"); + } + + /* Initially the chip is in run state */ + /* Put it into configuration state */ + outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + + /* Read device ID info */ + devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX); + devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX); + printk("SMSC devid %02x rev %02x\n", devid, devrev); + + /* Select the keyboard device */ + SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX); + + /* enable it */ + SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + + /* Select the interrupts */ + /* On a PC keyboard is IRQ1, mouse is IRQ12 */ + SMSC_WRITE_INDEXED(1, SMSC_PRIMARY_INT_INDEX); + SMSC_WRITE_INDEXED(12, SMSC_SECONDARY_INT_INDEX); + + /* Exit the configuraton state */ + outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + + return 0; +} + +/* This is grotty, but, because kernel is always referenced on the link line + * before any devices, this is safe. + */ +__initcall(smsc_setup); + +void __init platform_setup(void) +{ + /* Cayman platform leaves the decision to head.S, for now */ + platform_parms.fpu_flags = fpu_in_use; +} + +void __init platform_monitor(void) +{ + /* Nothing yet .. */ +} + +void __init platform_reserve(void) +{ + /* Nothing yet .. */ +} + +const char *get_system_type(void) +{ + return "Hitachi Cayman"; +} + diff -urN linux-2.4.21/arch/sh64/mach-harp/Makefile linux-2.4.22/arch/sh64/mach-harp/Makefile --- linux-2.4.21/arch/sh64/mach-harp/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mach-harp/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,14 @@ +# +# Makefile for the ST50 Harp specific parts of the kernel +# +# 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). +# + +O_TARGET := harp.o + +obj-y := setup.o + +include $(TOPDIR)/Rules.make + diff -urN linux-2.4.21/arch/sh64/mach-harp/setup.c linux-2.4.22/arch/sh64/mach-harp/setup.c --- linux-2.4.21/arch/sh64/mach-harp/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mach-harp/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,139 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mach-harp/setup.c + * + * SH-5 Simulator Platform Support + * + * This file handles the architecture-dependent parts of initialization + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * benedict.gaster@superh.com: 3rd May 2002 + * Added support for ramdisk, removing statically linked romfs at the same time. * + * + * lethal@linux-sh.org: 15th May 2003 + * Use the generic procfs cpuinfo interface, just return a valid board name. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource))) + +/* + * Platform Dependent Interrupt Priorities. + */ + +/* Using defaults defined in irq.h */ +#define RES NO_PRIORITY /* Disabled */ +#define IR0 IRL0_PRIORITY /* IRLs */ +#define IR1 IRL1_PRIORITY +#define IR2 IRL2_PRIORITY +#define IR3 IRL3_PRIORITY +#define PCA INTA_PRIORITY /* PCI Ints */ +#define PCB INTB_PRIORITY +#define PCC INTC_PRIORITY +#define PCD INTD_PRIORITY +#define SER TOP_PRIORITY +#define ERR TOP_PRIORITY +#define PW0 TOP_PRIORITY +#define PW1 TOP_PRIORITY +#define PW2 TOP_PRIORITY +#define PW3 TOP_PRIORITY +#define DM0 NO_PRIORITY /* DMA Ints */ +#define DM1 NO_PRIORITY +#define DM2 NO_PRIORITY +#define DM3 NO_PRIORITY +#define DAE NO_PRIORITY +#define TU0 TIMER_PRIORITY /* TMU Ints */ +#define TU1 NO_PRIORITY +#define TU2 NO_PRIORITY +#define TI2 NO_PRIORITY +#define ATI NO_PRIORITY /* RTC Ints */ +#define PRI NO_PRIORITY +#define CUI RTC_PRIORITY +#define ERI SCIF_PRIORITY /* SCIF Ints */ +#define RXI SCIF_PRIORITY +#define BRI SCIF_PRIORITY +#define TXI SCIF_PRIORITY +#define ITI TOP_PRIORITY /* WDT Ints */ + +/* + * Platform dependent structures: maps and parms block. + */ +struct resource io_resources[] = { + /* To be updated with external devices */ +}; + +struct resource kram_resources[] = { + { "Kernel code", 0, 0 }, /* These must be last in the array */ + { "Kernel data", 0, 0 } /* These must be last in the array */ +}; + +struct resource xram_resources[] = { + /* To be updated with external devices */ +}; + +struct resource rom_resources[] = { + /* To be updated with external devices */ +}; + +struct sh64_platform platform_parms = { + .readonly_rootfs = 1, + .initial_root_dev = 0x0100, + .loader_type = 1, + .io_res_p = io_resources, + .io_res_count = RES_COUNT(io_resources), + .kram_res_p = kram_resources, + .kram_res_count = RES_COUNT(kram_resources), + .xram_res_p = xram_resources, + .xram_res_count = RES_COUNT(xram_resources), + .rom_res_p = rom_resources, + .rom_res_count = RES_COUNT(rom_resources), +}; + +int platform_int_priority[NR_INTC_IRQS] = { + IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ + RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ + PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */ + TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */ + RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */ + RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */ +}; + +void __init platform_setup(void) +{ + /* Harp platform leaves the decision to head.S, for now */ + platform_parms.fpu_flags = fpu_in_use; +} + +void __init platform_monitor(void) +{ + /* Nothing yet .. */ +} + +void __init platform_reserve(void) +{ + /* Nothing yet .. */ +} + +const char *get_system_type(void) +{ + return "ST50 Harp"; +} + diff -urN linux-2.4.21/arch/sh64/mach-sim/Makefile linux-2.4.22/arch/sh64/mach-sim/Makefile --- linux-2.4.21/arch/sh64/mach-sim/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mach-sim/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,14 @@ +# +# Makefile for the SH-5 Simulator specific parts of the kernel +# +# 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). +# + +O_TARGET := sim.o + +obj-y := setup.o + +include $(TOPDIR)/Rules.make + diff -urN linux-2.4.21/arch/sh64/mach-sim/setup.c linux-2.4.22/arch/sh64/mach-sim/setup.c --- linux-2.4.21/arch/sh64/mach-sim/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mach-sim/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,164 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mach-sim/setup.c + * + * ST50 Simulator Platform Support + * + * This file handles the architecture-dependent parts of initialization + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * lethal@linux-sh.org: 15th May 2003 + * Use the generic procfs cpuinfo interface, just return a valid board name. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +#include "../rootfs/rootfs.h" +#endif + +static __init void platform_monitor(void); +static __init void platform_setup(void); +static __init void platform_reserve(void); + + +#define PHYS_MEMORY CONFIG_MEMORY_SIZE_IN_MB*1024*1024 + +#if (PHYS_MEMORY < P1SEG_FOOTPRINT_RAM) +#error "Invalid kernel configuration. Physical memory below footprint requirements." +#endif + +#define RAM_DISK_START CONFIG_MEMORY_START+P1SEG_INITRD_BLOCK /* Top of 4MB */ +#ifdef PLATFORM_ROMFS_SIZE +#define RAM_DISK_SIZE (PAGE_ALIGN(PLATFORM_ROMFS_SIZE)) /* Variable Top */ +#if ((RAM_DISK_START + RAM_DISK_SIZE) > (CONFIG_MEMORY_START + PHYS_MEMORY)) +#error "Invalid kernel configuration. ROM RootFS exceeding physical memory." +#endif +#else +#define RAM_DISK_SIZE P1SEG_INITRD_BLOCK_SIZE /* Top of 4MB */ +#endif + +#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource))) + +/* + * Platform Dependent Interrupt Priorities. + */ + +/* Using defaults defined in irq.h */ +#define RES NO_PRIORITY /* Disabled */ +#define IR0 IRL0_PRIORITY /* IRLs */ +#define IR1 IRL1_PRIORITY +#define IR2 IRL2_PRIORITY +#define IR3 IRL3_PRIORITY +#define PCA INTA_PRIORITY /* PCI Ints */ +#define PCB INTB_PRIORITY +#define PCC INTC_PRIORITY +#define PCD INTD_PRIORITY +#define SER TOP_PRIORITY +#define ERR TOP_PRIORITY +#define PW0 TOP_PRIORITY +#define PW1 TOP_PRIORITY +#define PW2 TOP_PRIORITY +#define PW3 TOP_PRIORITY +#define DM0 NO_PRIORITY /* DMA Ints */ +#define DM1 NO_PRIORITY +#define DM2 NO_PRIORITY +#define DM3 NO_PRIORITY +#define DAE NO_PRIORITY +#define TU0 TIMER_PRIORITY /* TMU Ints */ +#define TU1 NO_PRIORITY +#define TU2 NO_PRIORITY +#define TI2 NO_PRIORITY +#define ATI NO_PRIORITY /* RTC Ints */ +#define PRI NO_PRIORITY +#define CUI RTC_PRIORITY +#define ERI SCIF_PRIORITY /* SCIF Ints */ +#define RXI SCIF_PRIORITY +#define BRI SCIF_PRIORITY +#define TXI SCIF_PRIORITY +#define ITI TOP_PRIORITY /* WDT Ints */ + +/* + * Platform dependent structures: maps and parms block. + */ +struct resource io_resources[] = { + /* Nothing yet .. */ +}; + +struct resource kram_resources[] = { + { "Kernel code", 0, 0 }, /* These must be last in the array */ + { "Kernel data", 0, 0 } /* These must be last in the array */ +}; + +struct resource xram_resources[] = { + /* Nothing yet .. */ +}; + +struct resource rom_resources[] = { + /* Nothing yet .. */ +}; + +struct sh64_platform platform_parms = { + .readonly_rootfs = 1, + .initial_root_dev = 0x0100, + .loader_type = 1, + .initrd_start = RAM_DISK_START, + .initrd_size = RAM_DISK_SIZE, + .io_res_p = io_resources, + .io_res_count = RES_COUNT(io_resources), + .kram_res_p = kram_resources, + .kram_res_count = RES_COUNT(kram_resources), + .xram_res_p = xram_resources, + .xram_res_count = RES_COUNT(xram_resources), + .rom_res_p = rom_resources, + .rom_res_count = RES_COUNT(rom_resources), +}; + +int platform_int_priority[NR_IRQS] = { + IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ + RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ + PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */ + TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */ + RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */ + RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */ +}; + +void __init platform_setup(void) +{ + /* Simulator platform leaves the decision to head.S */ + platform_parms.fpu_flags = fpu_in_use; +} + +void __init platform_monitor(void) +{ + /* Nothing yet .. */ +} + +void __init platform_reserve(void) +{ + /* Nothing yet .. */ +} + +const char *get_system_type(void) +{ + return "SH-5 Simulator"; +} + diff -urN linux-2.4.21/arch/sh64/mm/Makefile linux-2.4.22/arch/sh64/mm/Makefile --- linux-2.4.21/arch/sh64/mm/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,43 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2000, 2001 Paolo Alberelli +# +# Makefile for the sh64-specific parts of the Linux memory manager. +# +# 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). +# + +O_TARGET := mm.o +obj-y := init.o fault.o ioremap.o extable.o cache.o tlbmiss.o tlb.o + +# Special flags for tlbmiss.o. This puts restrictions on the number of +# caller-save registers that the compiler can target when building this file. +# This is required because the code is called from a context in entry.S where +# very few registers have been saved in the exception handler (for speed +# reasons). +# The caller save registers that have been saved and which can be used are +# r2,r3,r4,r5 : argument passing +# r15, r18 : SP and LINK +# tr0-4 : allow all caller-save TR's. The compiler seems to be able to make +# use of them, so it's probably beneficial to performance to save them +# and have them available for it. +# +# The resources not listed below are callee save, i.e. the compiler is free to +# use any of them and will spill them to the stack itself. + +CFLAGS_tlbmiss.o += -ffixed-r7 \ + -ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \ + -ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \ + -ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \ + -ffixed-r24 -ffixed-r25 -ffixed-r26 -ffixed-r27 \ + -ffixed-r36 -ffixed-r37 -ffixed-r38 -ffixed-r39 -ffixed-r40 \ + -ffixed-r41 -ffixed-r42 -ffixed-r43 \ + -ffixed-r60 -ffixed-r61 -ffixed-r62 + + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/sh64/mm/cache.c linux-2.4.22/arch/sh64/mm/cache.c --- linux-2.4.21/arch/sh64/mm/cache.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/cache.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,1087 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mm/cache.c + * + * Original version Copyright (C) 2000, 2001 Paolo Alberelli + * Second version Copyright (C) benedict.gaster@superh.com 2002 + * Third version Copyright Richard.Curnow@superh.com 2003 + * Hacks to third version Copyright (C) 2003 Paul Mundt + */ + +/****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for flush_itlb_range */ + +#include + +/* This function is in entry.S */ +extern unsigned long switch_and_save_asid(unsigned long new_asid); + +/* Wired TLB entry for the D-cache */ +static unsigned long long dtlb_cache_slot; + +/** + * sh64_cache_init() + * + * This is pretty much just a straightforward clone of the SH + * detect_cpu_and_cache_system(). + * + * This function is responsible for setting up all of the cache + * info dynamically as well as taking care of CPU probing and + * setting up the relevant subtype data. + * + * FIXME: For the time being, we only really support the SH5-101 + * out of the box, and don't support dynamic probing for things + * like the SH5-103 or even cut2 of the SH5-101. Implement this + * later! + */ +int __init sh64_cache_init(void) +{ + /* + * First, setup some sane values for the I-cache. + */ + cpu_data->icache.ways = 4; + cpu_data->icache.sets = 256; + cpu_data->icache.linesz = L1_CACHE_BYTES; + + /* + * FIXME: This can probably be cleaned up a bit as well.. for example, + * do we really need the way shift _and_ the way_step_shift ?? Judging + * by the existing code, I would guess no.. is there any valid reason + * why we need to be tracking this around? + */ + cpu_data->icache.way_shift = 13; + cpu_data->icache.entry_shift = 5; + cpu_data->icache.set_shift = 4; + cpu_data->icache.way_step_shift = 16; + cpu_data->icache.asid_shift = 2; + + /* + * way offset = cache size / associativity, so just don't factor in + * associativity in the first place.. + */ + cpu_data->icache.way_ofs = cpu_data->icache.sets * + cpu_data->icache.linesz; + + cpu_data->icache.asid_mask = 0x3fc; + cpu_data->icache.idx_mask = 0x1fe0; + cpu_data->icache.epn_mask = 0xffffe000; + cpu_data->icache.flags = 0; + + /* + * Next, setup some sane values for the D-cache. + * + * On the SH5, these are pretty consistent with the I-cache settings, + * so we just copy over the existing definitions.. these can be fixed + * up later, especially if we add runtime CPU probing. + * + * Though in the meantime it saves us from having to duplicate all of + * the above definitions.. + */ + cpu_data->dcache = cpu_data->icache; + + /* + * Setup any cache-related flags here + */ +#if defined(CONFIG_DCACHE_WRITE_THROUGH) + set_bit(SH_CACHE_MODE_WT, &(cpu_data->dcache.flags)); +#elif defined(CONFIG_DCACHE_WRITE_BACK) + set_bit(SH_CACHE_MODE_WB, &(cpu_data->dcache.flags)); +#endif + + /* + * We also need to reserve a slot for the D-cache in the DTLB, so we + * do this now .. + */ + dtlb_cache_slot = sh64_get_wired_dtlb_entry(); + + return 0; +} + +/*##########################################################################*/ + +/* From here onwards, a rewrite of the implementation, + by Richard.Curnow@superh.com. + + The major changes in this compared to the old version are; + 1. use more selective purging through OCBP instead of using ALLOCO to purge + by natural replacement. This avoids purging out unrelated cache lines + that happen to be in the same set. + 2. exploit the APIs copy_user_page and clear_user_page better + 3. be more selective about I-cache purging, in particular use invalidate_all + more sparingly. + + NOTE : all this code runs in process context. As long as it's not used in a + pre-emptible or SMP kernel, there are no issues with locking, reentrancy + etc. When it gets used in a such a kernel this will have to be addressed. + (Note, there is no SMP realisation of sh64 yet.) + */ + +/*########################################################################## + SUPPORT FUNCTIONS + ##########################################################################*/ + +/****************************************************************************/ +/* The following group of functions deal with mapping and unmapping a temporary + page into the DTLB slot that have been set aside for our exclusive use. */ +/* In order to accomplish this, we use the generic interface for adding and + removing a wired slot entry as defined in arch/sh64/mm/tlb.c */ +/****************************************************************************/ + +static inline void sh64_setup_dtlb_cache_slot(unsigned long eaddr, unsigned long asid, unsigned long paddr) +{ + sh64_setup_tlb_slot(dtlb_cache_slot, eaddr, asid, paddr); +} + +static inline void sh64_teardown_dtlb_cache_slot(void) +{ + sh64_teardown_tlb_slot(dtlb_cache_slot); +} + +/****************************************************************************/ + +#ifndef CONFIG_ICACHE_DISABLED + +static void __inline__ sh64_icache_inv_all(void) +{ + unsigned long long addr, flag, data; + unsigned int flags; + + addr=ICCR0; + flag=ICCR0_ICI; + data=0; + + /* TODO : does this really need to be a critical section? */ + save_and_cli(flags); + + /* Without %1 it gets unexplicably wrong */ + asm volatile("getcfg %3, 0, %0\n\t" + "or %0, %2, %0\n\t" + "putcfg %3, 0, %0\n\t" + "synci" + : "=&r" (data) + : "0" (data), "r" (flag), "r" (addr)); + + restore_flags(flags); +} + +static void sh64_icache_inv_kernel_range(unsigned long start, unsigned long end) +{ + /* Invalidate range of addresses [start,end] from the I-cache, where + * the addresses lie in the kernel superpage. */ + + unsigned long long ullend, addr, aligned_start; + /* FIXME : This sign extension needs to be made generic. */ + aligned_start = (unsigned long long)(signed long long)(signed long) start; + aligned_start &= L1_CACHE_ALIGN_MASK; + addr = aligned_start; + /* FIXME : likewise this one */ + ullend = (unsigned long long) (signed long long) (signed long) end; + while (addr <= ullend) { + asm __volatile__ ("icbi %0, 0" : : "r" (addr)); + addr += L1_CACHE_BYTES; + } +} + +static void sh64_icache_inv_user_page(struct vm_area_struct *vma, unsigned long eaddr) +{ + /* If we get called, we know that vma->vm_flags contains VM_EXEC. + Also, eaddr is page-aligned. */ + + /* For SMP/pre-emptible, this will need to be locked to prevent the + ASID from changing under us if there's a reschedule. */ + + unsigned long long addr, end_addr; + addr = eaddr; + end_addr = addr + PAGE_SIZE; + + + /* FIXME : is there any issue using 'current_asid' here? i.e. can this + ever get called with 'vma->vm_mm->context.asid' != current_asid? + (the normal case would be munmap or a page flush following a COW + break etc, and using current_asid is OK for those.). If we need to + use vma->vm_mm->context.asid, we'd have to switch ASIDs and run in + the context of the victim. */ + while (addr < end_addr) { + /* Worth unrolling a little */ + asm __volatile__("icbi %0, 0" : : "r" (addr)); + asm __volatile__("icbi %0, 32" : : "r" (addr)); + asm __volatile__("icbi %0, 64" : : "r" (addr)); + asm __volatile__("icbi %0, 96" : : "r" (addr)); + addr += 128; + } + return; +} + +/****************************************************************************/ + +static void sh64_icache_inv_user_page_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* Used for invalidating big chunks of I-cache, i.e. assume the range + is whole pages. If 'start' or 'end' is not page aligned, the code + is conservative and invalidates to the ends of the enclosing pages. + This is functionally OK, just a performance loss. */ + + /* See the comments below in sh64_dcache_purge_user_range() regarding + the choice of algorithm. However, for the I-cache option (2) isn't + available because there are no physical tags so aliases can't be + resolved. The icbi instruction has to be used through the user + mapping. Because icbi is cheaper than ocbp on a cache hit, it + would be cheaper to use the selective code for a large range than is + possible with the D-cache. Just assume 64 for now as a working + figure. + */ + + int n_pages; + + if (!mm) return; + + n_pages = ((end - start) >> PAGE_SHIFT); + if (n_pages >= 64) { + sh64_icache_inv_all(); + } else { + unsigned long aligned_start; + unsigned long eaddr; + unsigned long after_last_page_start; + unsigned long mm_asid, current_asid; + unsigned long long flags = 0ULL; + + mm_asid = mm->context & MMU_CONTEXT_ASID_MASK; + current_asid = get_asid(); + + if (mm_asid != current_asid) { + /* Switch ASID and run the invalidate loop under cli */ + save_and_cli(flags); + switch_and_save_asid(mm_asid); + } + + aligned_start = start & PAGE_MASK; + after_last_page_start = PAGE_SIZE + ((end - 1) & PAGE_MASK); + + while (aligned_start < after_last_page_start) { + struct vm_area_struct *vma; + unsigned long vma_end; + vma = find_vma(mm, aligned_start); + if (!vma || (aligned_start <= vma->vm_end)) { + /* Avoid getting stuck in an error condition */ + aligned_start += PAGE_SIZE; + continue; + } + vma_end = vma->vm_end; + if (vma->vm_flags & VM_EXEC) { + /* Executable */ + eaddr = aligned_start; + while (eaddr < vma_end) { + sh64_icache_inv_user_page(vma, eaddr); + eaddr += PAGE_SIZE; + } + } + aligned_start = vma->vm_end; /* Skip to start of next region */ + } + if (mm_asid != current_asid) { + switch_and_save_asid(current_asid); + restore_flags(flags); + } + } +} + +static void sh64_icache_inv_user_small_range(struct mm_struct *mm, + unsigned long start, int len) +{ + + /* Invalidate a small range of user context I-cache, not necessarily + page (or even cache-line) aligned. */ + + unsigned long long eaddr = start; + unsigned long long eaddr_end = start + len; + unsigned long current_asid, mm_asid; + unsigned long long flags; + unsigned long long epage_start; + + /* Since this is used inside ptrace, the ASID in the mm context + typically won't match current_asid. We'll have to switch ASID to do + this. For safety, and given that the range will be small, do all + this under cli. + + Note, there is a hazard that the ASID in mm->context is no longer + actually associated with mm, i.e. if the mm->context has started a + new cycle since mm was last active. However, this is just a + performance issue: all that happens is that we invalidate lines + belonging to another mm, so the owning process has to refill them + when that mm goes live again. mm itself can't have any cache + entries because there will have been a flush_cache_all when the new + mm->context cycle started. */ + + /* Align to start of cache line. Otherwise, suppose len==8 and start + was at 32N+28 : the last 4 bytes wouldn't get invalidated. */ + eaddr = start & L1_CACHE_ALIGN_MASK; + eaddr_end = start + len; + + save_and_cli(flags); + mm_asid = mm->context & MMU_CONTEXT_ASID_MASK; + current_asid = switch_and_save_asid(mm_asid); + + epage_start = eaddr & PAGE_MASK; + + while (eaddr < eaddr_end) + { + asm __volatile__("icbi %0, 0" : : "r" (eaddr)); + eaddr += L1_CACHE_BYTES; + } + switch_and_save_asid(current_asid); + restore_flags(flags); +} + +static void sh64_icache_inv_current_user_range(unsigned long start, unsigned long end) +{ + /* The icbi instruction never raises ITLBMISS. i.e. if there's not a + cache hit on the virtual tag the instruction ends there, without a + TLB lookup. */ + + unsigned long long aligned_start; + unsigned long long ull_end; + unsigned long long addr; + + ull_end = end; + + /* Just invalidate over the range using the natural addresses. TLB + miss handling will be OK (TBC). Since it's for the current process, + either we're already in the right ASID context, or the ASIDs have + been recycled since we were last active in which case we might just + invalidate another processes I-cache entries : no worries, just a + performance drop for him. */ + aligned_start = start & L1_CACHE_ALIGN_MASK; + addr = aligned_start; + while (addr < ull_end) { + asm __volatile__ ("icbi %0, 0" : : "r" (addr)); + asm __volatile__ ("nop"); + asm __volatile__ ("nop"); + addr += L1_CACHE_BYTES; + } +} + +#endif /* !CONFIG_ICACHE_DISABLED */ + +/****************************************************************************/ + +#ifndef CONFIG_DCACHE_DISABLED + +/* Buffer used as the target of alloco instructions to purge data from cache + sets by natural eviction. -- RPC */ +#define DUMMY_ALLOCO_AREA_SIZE L1_CACHE_SIZE_BYTES + (1024 * 4) +static unsigned char dummy_alloco_area[DUMMY_ALLOCO_AREA_SIZE] __cacheline_aligned = { 0, }; + +/****************************************************************************/ + +static void __inline__ sh64_dcache_purge_sets(int sets_to_purge_base, int n_sets) +{ + /* Purge all ways in a particular block of sets, specified by the base + set number and number of sets. Can handle wrap-around, if that's + needed. */ + + int dummy_buffer_base_set; + unsigned long long eaddr, eaddr0, eaddr1; + int j; + int set_offset; + + dummy_buffer_base_set = ((int)&dummy_alloco_area & cpu_data->dcache.idx_mask) >> cpu_data->dcache.entry_shift; + set_offset = sets_to_purge_base - dummy_buffer_base_set; + + for (j=0; jdcache.sets - 1); + eaddr0 = (unsigned long long)dummy_alloco_area + (set_offset << cpu_data->dcache.entry_shift); + + /* Do one alloco which hits the required set per cache way. For + write-back mode, this will purge the #ways resident lines. There's + little point unrolling this loop because the allocos stall more if + they're too close together. */ + eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways; + for (eaddr=eaddr0; eaddrdcache.way_ofs) { + asm __volatile__ ("alloco %0, 0" : : "r" (eaddr)); + } + + eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways; + for (eaddr=eaddr0; eaddrdcache.way_ofs) { + /* Load from each address. Required because alloco is a NOP if + the cache is write-through. Write-through is a config option. */ + if (test_bit(SH_CACHE_MODE_WT, &(cpu_data->dcache.flags))) + *(volatile unsigned char *)(int)eaddr; + } + } + + /* Don't use OCBI to invalidate the lines. That costs cycles directly. + If the dummy block is just left resident, it will naturally get + evicted as required. */ + + return; +} + +/****************************************************************************/ + +static void sh64_dcache_purge_all(void) +{ + /* Purge the entire contents of the dcache. The most efficient way to + achieve this is to use alloco instructions on a region of unused + memory equal in size to the cache, thereby causing the current + contents to be discarded by natural eviction. The alternative, + namely reading every tag, setting up a mapping for the corresponding + page and doing an OCBP for the line, would be much more expensive. + */ + + sh64_dcache_purge_sets(0, cpu_data->dcache.sets); + + return; + +} + +/****************************************************************************/ + +static void sh64_dcache_purge_kernel_range(unsigned long start, unsigned long end) +{ + /* Purge the range of addresses [start,end] from the D-cache. The + addresses lie in the superpage mapping. There's no harm if we + overpurge at either end - just a small performance loss. */ + unsigned long long ullend, addr, aligned_start; + /* FIXME : This sign extension needs to be made generic. */ + aligned_start = (unsigned long long)(signed long long)(signed long) start; + aligned_start &= L1_CACHE_ALIGN_MASK; + addr = aligned_start; + /* FIXME : likewise this one */ + ullend = (unsigned long long) (signed long long) (signed long) end; + while (addr <= ullend) { + asm __volatile__ ("ocbp %0, 0" : : "r" (addr)); + addr += L1_CACHE_BYTES; + } + return; +} + +/* Assumes this address (+ (2**n_synbits) pages up from it) aren't used for + anything else in the kernel */ +#define MAGIC_PAGE0_START 0xffffffffe0000000ULL + +static void sh64_dcache_purge_coloured_phy_page(unsigned long paddr, unsigned long eaddr) +{ + /* Purge the physical page 'paddr' from the cache. It's known that any + cache lines requiring attention have the same page colour as the the + address 'eaddr'. + + This relies on the fact that the D-cache matches on physical tags + when no virtual tag matches. So we create an alias for the original + page and purge through that. (Alternatively, we could have done + this by switching ASID to match the original mapping and purged + through that, but that involves ASID switching cost + probably a + TLBMISS + refill anyway.) + */ + + unsigned long long magic_page_start; + unsigned long long magic_eaddr, magic_eaddr_end; + + magic_page_start = MAGIC_PAGE0_START + (eaddr & CACHE_OC_SYN_MASK); + + /* As long as the kernel is not pre-emptible, this doesn't need to be + under cli/sti. */ + + sh64_setup_dtlb_cache_slot(magic_page_start, get_asid(), paddr); + + magic_eaddr = magic_page_start; + magic_eaddr_end = magic_eaddr + PAGE_SIZE; + while (magic_eaddr < magic_eaddr_end) { + /* Little point in unrolling this loop - the OCBPs are blocking + and won't go any quicker (i.e. the loop overhead is parallel + to part of the OCBP execution.) */ + asm __volatile__ ("ocbp %0, 0" : : "r" (magic_eaddr)); + magic_eaddr += L1_CACHE_BYTES; + } + + sh64_teardown_dtlb_cache_slot(); +} + +/****************************************************************************/ + +static void sh64_dcache_purge_phy_page(unsigned long paddr) +{ + /* Pure a page given its physical start address, by creating a + temporary 1 page mapping and purging across that. Even if we know + the virtual address (& vma or mm) of the page, the method here is + more elegant because it avoids issues of coping with page faults on + the purge instructions (i.e. no special-case code required in the + critical path in the TLB miss handling). */ + + unsigned long long eaddr_start, eaddr, eaddr_end; + int i; + + /* As long as the kernel is not pre-emptible, this doesn't need to be + under cli/sti. */ + + eaddr_start = MAGIC_PAGE0_START; + for (i=0; i < (1 << CACHE_OC_N_SYNBITS); i++) { + sh64_setup_dtlb_cache_slot(eaddr_start, get_asid(), paddr); + + eaddr = eaddr_start; + eaddr_end = eaddr + PAGE_SIZE; + while (eaddr < eaddr_end) { + asm __volatile__ ("ocbp %0, 0" : : "r" (eaddr)); + eaddr += L1_CACHE_BYTES; + } + + sh64_teardown_dtlb_cache_slot(); + eaddr_start += PAGE_SIZE; + } +} + +static void sh64_dcache_purge_virt_page(struct mm_struct *mm, unsigned long eaddr) +{ + unsigned long phys; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + + pgd = pgd_offset(mm, eaddr); + pmd = pmd_offset(pgd, eaddr); + + if (pmd_none(*pmd) || pmd_bad(*pmd)) + return; + + pte = pte_offset(pmd, eaddr); + entry = *pte; + + if (pte_none(entry) || !pte_present(entry)) + return; + + phys = pte_val(entry) & PAGE_MASK; + + sh64_dcache_purge_phy_page(phys); +} + +static void sh64_dcache_purge_user_page(struct mm_struct *mm, unsigned long eaddr) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long paddr; + + /* NOTE : all the callers of this have mm->page_table_lock held, so the + following page table traversal is safe even on SMP/pre-emptible. */ + + if (!mm) return; /* No way to find physical address of page */ + pgd = pgd_offset(mm, eaddr); + if (pgd_bad(*pgd)) return; + + pmd = pmd_offset(pgd, eaddr); + if (pmd_none(*pmd) || pmd_bad(*pmd)) return; + + pte = pte_offset(pmd, eaddr); + entry = *pte; + if (pte_none(entry) || !pte_present(entry)) return; + + paddr = pte_val(entry) & PAGE_MASK; + + sh64_dcache_purge_coloured_phy_page(paddr, eaddr); + +} +/****************************************************************************/ + +static void sh64_dcache_purge_user_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* There are at least 5 choices for the implementation of this, with + pros (+), cons(-), comments(*): + + 1. ocbp each line in the range through the original user's ASID + + no lines spuriously evicted + - tlbmiss handling (must either handle faults on demand => extra + special-case code in tlbmiss critical path), or map the page in + advance (=> flush_tlb_range in advance to avoid multiple hits) + - ASID switching + - expensive for large ranges + + 2. temporarily map each page in the range to a special effective + address and ocbp through the temporary mapping; relies on the + fact that SH-5 OCB* always do TLB lookup and match on ptags (they + never look at the etags) + + no spurious evictions + - expensive for large ranges + * surely cheaper than (1) + + 3. walk all the lines in the cache, check the tags, if a match + occurs create a page mapping to ocbp the line through + + no spurious evictions + - tag inspection overhead + - (especially for small ranges) + - potential cost of setting up/tearing down page mapping for + every line that matches the range + * cost partly independent of range size + + 4. walk all the lines in the cache, check the tags, if a match + occurs use 4 * alloco to purge the line (+3 other probably + innocent victims) by natural eviction + + no tlb mapping overheads + - spurious evictions + - tag inspection overhead + + 5. implement like flush_cache_all + + no tag inspection overhead + - spurious evictions + - bad for small ranges + + (1) can be ruled out as more expensive than (2). (2) appears best + for small ranges. The choice between (3), (4) and (5) for large + ranges and the range size for the large/small boundary need + benchmarking to determine. + + For now use approach (2) for small ranges and (5) for large ones. + + */ + + int n_pages; + + n_pages = ((end - start) >> PAGE_SHIFT); + if (n_pages >= 64) { +#if 1 + sh64_dcache_purge_all(); +#else + unsigned long long set, way; + unsigned long mm_asid = mm->context & MMU_CONTEXT_ASID_MASK; + for (set = 0; set < cpu_data->dcache.sets; set++) { + unsigned long long set_base_config_addr = CACHE_OC_ADDRESS_ARRAY + (set << cpu_data->dcache.set_shift); + for (way = 0; way < cpu_data->dcache.ways; way++) { + unsigned long long config_addr = set_base_config_addr + (way << cpu_data->dcache.way_step_shift); + unsigned long long tag0; + unsigned long line_valid; + + asm __volatile__("getcfg %1, 0, %0" : "=r" (tag0) : "r" (config_addr)); + line_valid = tag0 & SH_CACHE_VALID; + if (line_valid) { + unsigned long cache_asid; + unsigned long epn; + + cache_asid = (tag0 & cpu_data->dcache.asid_mask) >> cpu_data->dcache.asid_shift; + /* The next line needs some + explanation. The virtual tags + encode bits [31:13] of the virtual + address, bit [12] of the 'tag' being + implied by the cache set index. */ + epn = (tag0 & cpu_data->dcache.epn_mask) | ((set & 0x80) << cpu_data->dcache.entry_shift); + + if ((cache_asid == mm_asid) && (start <= epn) && (epn < end)) { + /* TODO : could optimise this + call by batching multiple + adjacent sets together. */ + sh64_dcache_purge_sets(set, 1); + break; /* Don't waste time inspecting other ways for this set */ + } + } + } + } +#endif + } else { + /* 'Small' range */ + unsigned long aligned_start; + unsigned long eaddr; + unsigned long last_page_start; + + aligned_start = start & PAGE_MASK; + /* 'end' is 1 byte beyond the end of the range */ + last_page_start = (end - 1) & PAGE_MASK; + + eaddr = aligned_start; + while (eaddr <= last_page_start) { + sh64_dcache_purge_user_page(mm, eaddr); + eaddr += PAGE_SIZE; + } + } + return; +} + +static void sh64_dcache_wback_current_user_range(unsigned long start, unsigned long end) +{ + unsigned long long aligned_start; + unsigned long long ull_end; + unsigned long long addr; + + ull_end = end; + + /* Just wback over the range using the natural addresses. TLB miss + handling will be OK (TBC) : the range has just been written to by + the signal frame setup code, so the PTEs must exist. + + TODO : with SMP or pre-emptible, run this under cli to guard against + the risk of a reschedule causing a new ASID cycle to begin. + */ + aligned_start = start & L1_CACHE_ALIGN_MASK; + addr = aligned_start; + while (addr < ull_end) { + asm __volatile__ ("ocbwb %0, 0" : : "r" (addr)); + addr += L1_CACHE_BYTES; + } +} + +#endif /* !CONFIG_DCACHE_DISABLED */ + +/****************************************************************************/ + +/* These *MUST* lie in an area of virtual address space that's otherwise unused. */ +#define UNIQUE_EADDR_START 0xc0000000UL +#define UNIQUE_EADDR_END 0xd0000000UL + +static unsigned long sh64_make_unique_eaddr(unsigned long user_eaddr, unsigned long paddr) +{ + /* Given a physical address paddr, and a user virtual address + user_eaddr which will eventually be mapped to it, create a one-off + kernel-private eaddr mapped to the same paddr. This is used for + creating special destination pages for copy_user_page and + clear_user_page */ + + static unsigned long current_pointer = UNIQUE_EADDR_START; + unsigned long coloured_pointer; + + if (current_pointer == UNIQUE_EADDR_END) { + sh64_dcache_purge_all(); + current_pointer = UNIQUE_EADDR_START; + } + + coloured_pointer = (current_pointer & ~CACHE_OC_SYN_MASK) | (user_eaddr & CACHE_OC_SYN_MASK); + sh64_setup_dtlb_cache_slot(coloured_pointer, get_asid(), paddr); + + current_pointer += (PAGE_SIZE << CACHE_OC_N_SYNBITS); + + return coloured_pointer; +} + +/****************************************************************************/ + +static void sh64_copy_user_page_coloured(void *to, void *from, unsigned long address) +{ + void *coloured_to; + + /* Discard any existing cache entries of the wrong colour. These are + present quite often, if the kernel has recently used the page + internally, then given it up, then it's been allocated to the user. + */ + sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long) to); + + coloured_to = (void *) sh64_make_unique_eaddr(address, __pa(to)); + sh64_page_copy(from, coloured_to); + + sh64_teardown_dtlb_cache_slot(); +} + +static void sh64_clear_user_page_coloured(void *to, unsigned long address) +{ + void *coloured_to; + + /* Discard any existing kernel-originated lines of the wrong colour (as + above) */ + sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long) to); + + coloured_to = (void *) sh64_make_unique_eaddr(address, __pa(to)); + sh64_page_clear(coloured_to); + + sh64_teardown_dtlb_cache_slot(); +} + +/****************************************************************************/ + +/*########################################################################## + EXTERNALLY CALLABLE API. + ##########################################################################*/ + +/* These functions are described in Documentation/cachetlb.txt. + Each one of these functions varies in behaviour depending on whether the + I-cache and/or D-cache are configured out. + + Note that the Linux term 'flush' corresponds to what is termed 'purge' in + the sh/sh64 jargon for the D-cache, i.e. write back dirty data then + invalidate the cache lines, and 'invalidate' for the I-cache. + */ + +#undef FLUSH_TRACE + +void flush_cache_all(void) +{ + /* Invalidate the entire contents of both caches, after writing back to + memory any dirty data from the D-cache. */ + sh64_dcache_purge_all(); + sh64_icache_inv_all(); +} + +/****************************************************************************/ + +void flush_cache_mm(struct mm_struct *mm) +{ + /* Invalidate an entire user-address space from both caches, after + writing back dirty data (e.g. for shared mmap etc). */ + + /* This could be coded selectively by inspecting all the tags then + doing 4*alloco on any set containing a match (as for + flush_cache_range), but fork/exit/execve (where this is called from) + are expensive anyway. */ + + /* Have to do a purge here, despite the comments re I-cache below. + There could be odd-coloured dirty data associated with the mm still + in the cache - if this gets written out through natural eviction + after the kernel has reused the page there will be chaos. + + TODO Perhaps a selective purge is appropriate. + */ + sh64_dcache_purge_all(); + + /* The mm being torn down won't ever be active again, so any Icache + lines tagged with its ASID won't be visible for the rest of the + lifetime of this ASID cycle. Before the ASID gets reused, there + will be a flush_cache_all. This is similar to the lack of action + needed in flush_tlb_mm - see fault.c. */ +#if 0 + sh64_icache_inv_all(); +#endif +} + +/****************************************************************************/ + +void flush_cache_range(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + /* Invalidate (from both caches) the range [start,end) of virtual + addresses from the user address space specified by mm, after writing + back any dirty data. + + Note(1), 'end' is 1 byte beyond the end of the range to flush. + + Note(2), this is called with mm->page_table_lock held.*/ + + sh64_dcache_purge_user_range(mm, start, end); + sh64_icache_inv_user_page_range(mm, start, end); +} + +/****************************************************************************/ + +void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr) +{ + /* Invalidate any entries in either cache for the vma within the user + address space vma->vm_mm for the page starting at virtual address + 'eaddr'. This seems to be used primarily in breaking COW. Note, + the I-cache must be searched too in case the page in question is + both writable and being executed from (e.g. stack trampolines.) + + Note(1), this is called with mm->page_table_lock held. + */ + + sh64_dcache_purge_virt_page(vma->vm_mm, eaddr); + + if (vma->vm_flags & VM_EXEC) { + sh64_icache_inv_user_page(vma, eaddr); + } +} + +/****************************************************************************/ + +void flush_page_to_ram(struct page *page) +{ + /* This is a depracated API, being replaced by copy/clear_user_page and + flush_dcache_page. However, parts of the generic code (e.g. ptrace) + still require an implementation of flush_page_to_ram for them to + work properly. + + The 'page' argument defines a *physical* page. After the function, + no lines in the D-cache must reference that page, and any dirty + entries in the page must have been written out. (This is used to + make memory coherent with the cache when the I-cache is about to see + the data etc) -- RPC */ + + /* As an elaboration on the above, flush_page_to_ram() is indeed + deprecated, and the majority of users (such as ptrace) are using + this erroneously anyways. As such, there's two different things we + can do here.. namely, we can either nop this out and hope that some + clueless generic code isn't abusing the interface (this is what we + do for sh, and it seems to work just fine), or we can play it safe + (albeit much slower, since we have the added cost of additional + flushing to contend with) and just wrap to the existing + flush_dcache_page() behavior. -- PFM */ + + flush_dcache_page(page); +} + +/****************************************************************************/ + +#ifndef CONFIG_DCACHE_DISABLED + +void copy_user_page(void *to, void *from, unsigned long address) +{ + /* 'from' and 'to' are kernel virtual addresses (within the superpage + mapping of the physical RAM). 'address' is the user virtual address + where the copy 'to' will be mapped after. This allows a custom + mapping to be used to ensure that the new copy is placed in the + right cache sets for the user to see it without having to bounce it + out via memory. Note however : the call to flush_page_to_ram in + (generic)/mm/memory.c:(break_cow) undoes all this good work in that one + very important case! + + TBD : can we guarantee that on every call, any cache entries for + 'from' are in the same colour sets as 'address' also? i.e. is this + always used just to deal with COW? (I suspect not). */ + + /* There are two possibilities here for when the page 'from' was last accessed: + * by the kernel : this is OK, no purge required. + * by the/a user (e.g. for break_COW) : need to purge. + + If the potential user mapping at 'address' is the same colour as + 'from' there is no need to purge any cache lines from the 'from' + page mapped into cache sets of colour 'address'. (The copy will be + accessing the page through 'from'). + */ + + if (((address ^ (unsigned long) from) & CACHE_OC_SYN_MASK) != 0) { + sh64_dcache_purge_coloured_phy_page(__pa(from), address); + } + + if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) { + /* No synonym problem on destination */ + sh64_page_copy(from, to); + } else { + sh64_copy_user_page_coloured(to, from, address); + } + + /* Note, don't need to flush 'from' page from the cache again - it's + done anyway by the generic code */ +} + +void clear_user_page(void *to, unsigned long address) +{ + /* 'to' is a kernel virtual address (within the superpage + mapping of the physical RAM). 'address' is the user virtual address + where the 'to' page will be mapped after. This allows a custom + mapping to be used to ensure that the new copy is placed in the + right cache sets for the user to see it without having to bounce it + out via memory. + */ + + if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) { + /* No synonym problem on destination */ + sh64_page_clear(to); + } else { + sh64_clear_user_page_coloured(to, address); + } +} + +#endif /* !CONFIG_DCACHE_DISABLED */ + +/****************************************************************************/ + +void flush_dcache_page(struct page *page) +{ + /* The behaviour of this function is equivalent to that of + flush_page_to_ram above. */ + + sh64_dcache_purge_phy_page(page_to_phys(page)); + wmb(); +} + +/****************************************************************************/ + +void flush_icache_range(unsigned long start, unsigned long end) +{ + /* Flush the range [start,end] of kernel virtual adddress space from + the I-cache. The corresponding range must be purged from the + D-cache also because the SH-5 doesn't have cache snooping between + the caches. The addresses will be visible through the superpage + mapping, therefore it's guaranteed that there no cache entries for + the range in cache sets of the wrong colour. + + Primarily used for cohering the I-cache after a module has + been loaded. */ + + /* We also make sure to purge the same range from the D-cache since + flush_page_to_ram() won't be doing this for us! */ + + sh64_dcache_purge_kernel_range(start, end); + wmb(); + sh64_icache_inv_kernel_range(start, end); +} + +/****************************************************************************/ + +void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, int len) +{ + /* Flush the range of user (defined by vma->vm_mm) address space + starting at 'addr' for 'len' bytes from the cache. The range does + not straddle a page boundary, the unique physical page containing + the range is 'page'. This seems to be used mainly for invalidating + an address range following a poke into the program text through the + ptrace() call from another process (e.g. for BRK instruction + insertion). */ + + sh64_dcache_purge_coloured_phy_page(page_to_phys(page), addr); + wmb(); + + if (vma->vm_flags & VM_EXEC) { + sh64_icache_inv_user_small_range(vma->vm_mm, addr, len); + } +} + +/****************************************************************************/ + +void flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + /* Called when a page-cache page is about to be mapped into a user + address space (defined by vma->vm_mm). Since the SH-5 I-cache + hasn't got physical tags, this doesn't have to do anything. Empirically, this is OK. + + Note, SH-5 I-cache entries can legally outlive the ITLB mapping + anyway. So even if an executable page is dropped by the generic VM + to free a page, we can still execute it from the cache. (The cache + invalidation occurs as part of flush_cache_range or flush_cache_mm + when the munmap() or exit() finally happens.) -- RPC */ + + /* We also want to purge this page from the D-cache, since we can't + rely on flush_page_to_ram() do to do the D-cache purge. + + Yes, this esentially constitutes misuse of flush_icache_page(), but + we need this specifically for do_swap_page() in mm/memory.c for + purging the page from both the I and D-cache. (This is primarily + a performance hack!). + + We can probably do away with this entirely once we get around to + doing selective flushing from update_mmu_cache() once we can + sanely test the page flags for PG_arch_1 (PG_dcache_dirty) to see if + we need to do the D-cache purge. -- PFM */ + + sh64_dcache_purge_phy_page(page_to_phys(page)); + wmb(); +} + +/*########################################################################## + ARCH/SH64 PRIVATE CALLABLE API. + ##########################################################################*/ + +void flush_cache_sigtramp(unsigned long start, unsigned long end) +{ + /* For the address range [start,end), write back the data from the + D-cache and invalidate the corresponding region of the I-cache for + the current process. Used to flush signal trampolines on the stack + to make them executable. */ + + sh64_dcache_wback_current_user_range(start, end); + wmb(); + sh64_icache_inv_current_user_range(start, end); +} + diff -urN linux-2.4.21/arch/sh64/mm/extable.c linux-2.4.22/arch/sh64/mm/extable.c --- linux-2.4.21/arch/sh64/mm/extable.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/extable.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,95 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mm/extable.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Completely coherent with i386/sh/... + * + */ + +#include +#include +#include + +extern const struct exception_table_entry __start___ex_table[]; +extern const struct exception_table_entry __stop___ex_table[]; + +static inline unsigned long +search_one_table(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) +{ + while (first <= last) { + const struct exception_table_entry *mid; + long diff; + + mid = (last - first) / 2 + first; + diff = mid->insn - value; + if (diff == 0) + return mid->fixup; + else if (diff < 0) + + /* + * The dicotomic search assumes the same + * upward assignement of linker addresses + * for both .text and __ex_table sections. + * __ex_table entries gets automagically + * ordered. + */ + first = mid+1; + else + last = mid-1; + } + return 0; +} + + +/* Some functions that may trap due to a bad user-mode address have too many loads + and stores in them to make it at all practical to label each one and put them all in + the main exception table. + + In particular, the fast memcpy routine is like this. It's fix-up is just to fall back + to a slow byte-at-a-time copy, which is handled the conventional way. So it's functionally + OK to just handle any trap occurring in the fast memcpy with that fixup. */ +unsigned long +check_exception_ranges(unsigned long addr) +{ + extern unsigned long copy_user_memcpy, copy_user_memcpy_end, __copy_user_fixup; + if ((addr >= (unsigned long) ©_user_memcpy) && (addr <= (unsigned long) ©_user_memcpy_end)) { + return (unsigned long) &__copy_user_fixup; + } + + return 0; /* no match */ +} + + +unsigned long +search_exception_table(unsigned long addr) +{ + unsigned long ret; + + ret = check_exception_ranges(addr); + if (ret) return ret; + +#ifndef CONFIG_MODULES + /* There is only the kernel to search. */ + ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); + if (ret) return ret; +#else + /* The kernel is the last "module" -- no need to treat it special. */ + struct module *mp; + for (mp = module_list; mp != NULL; mp = mp->next) { + if (mp->ex_table_start == NULL) + continue; + ret = search_one_table(mp->ex_table_start, + mp->ex_table_end - 1, addr); + if (ret) return ret; + } +#endif + + return 0; +} diff -urN linux-2.4.21/arch/sh64/mm/fault.c linux-2.4.22/arch/sh64/mm/fault.c --- linux-2.4.21/arch/sh64/mm/fault.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,695 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mm/fault.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 (/proc/tlb, audit_mm, bug fixes) + * Copyright (C) 2003 Paul Mundt + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include /* required by inline asm statements */ + +#if defined(CONFIG_SH64_PROC_TLB) +#include +#include +/* Count numbers of tlb refills in each region */ +static unsigned long long calls_to_update_mmu_cache = 0ULL; +static unsigned long long calls_to_flush_tlb_page = 0ULL; +static unsigned long long calls_to_flush_tlb_range = 0ULL; +static unsigned long long calls_to_flush_tlb_mm = 0ULL; +static unsigned long long calls_to_flush_tlb_all = 0ULL; +unsigned long long calls_to_do_slow_page_fault = 0ULL; +unsigned long long calls_to_do_fast_page_fault = 0ULL; + +/* Count size of ranges for flush_tlb_range */ +static unsigned long long flush_tlb_range_1 = 0ULL; +static unsigned long long flush_tlb_range_2 = 0ULL; +static unsigned long long flush_tlb_range_3_4 = 0ULL; +static unsigned long long flush_tlb_range_5_7 = 0ULL; +static unsigned long long flush_tlb_range_8_11 = 0ULL; +static unsigned long long flush_tlb_range_12_15 = 0ULL; +static unsigned long long flush_tlb_range_16_up = 0ULL; + +static unsigned long long page_not_present = 0ULL; + +#endif + +extern void die(const char *,struct pt_regs *,long); + +#define PFLAG(val,flag) (( (val) & (flag) ) ? #flag : "" ) +#define PPROT(flag) PFLAG(pgprot_val(prot),flag) + +static __inline__ void print_prots(pgprot_t prot) +{ + printk("prot is 0x%08lx\n",pgprot_val(prot)); + + printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ), + PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER)); +} + + +static __inline__ void print_vma(struct vm_area_struct *vma) +{ + printk("vma start 0x%08lx\n",vma->vm_start); + printk("vma end 0x%08lx\n",vma->vm_end); + + print_prots(vma->vm_page_prot); + printk("vm_flags 0x%08lx\n",vma->vm_flags); +} + +static __inline__ void print_task(struct task_struct *tsk) +{ + printk("Task pid %d\n",tsk->pid); +} + +static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address) +{ + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + + dir = pgd_offset(mm, address); + if (pgd_none(*dir)) { + return NULL; + } + + pmd = pmd_offset(dir, address); + if (pmd_none(*pmd)) { + return NULL; + } + + pte = pte_offset(pmd, address); + entry = *pte; + + if (pte_none(entry)) { + return NULL; + } + if (!pte_present(entry)) { + return NULL; + } + + return pte; +} + +/* + * This routine handles page faults. It determines the address, + * and the problem, and then passes it off to one of the appropriate + * routines. + */ +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, + unsigned long textaccess, unsigned long address) +{ + struct task_struct *tsk; + struct mm_struct *mm; + struct vm_area_struct * vma; + unsigned long page; + unsigned long long lpage; + unsigned long fixup; + pte_t *pte; + +#if defined(CONFIG_SH64_PROC_TLB) + ++calls_to_do_slow_page_fault; +#endif + + /* SIM + * Note this is now called with interrupts still disabled + * This is to cope with being called for a missing IO port + * address with interupts disabled. This should be fixed as + * soon as we have a better 'fast path' miss handler. + * + * Plus take care how you try and debug this stuff. + * For example, writing debug data to a port which you + * have just faulted on is not going to work. + */ + + tsk = current; + mm = tsk->mm; + + /* Not an IO address, so reenable interrupts */ + sti(); + + /* + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ + if (in_interrupt() || !mm) + goto no_context; + + /* TLB misses upon some cache flushes get done under cli() */ + down_read(&mm->mmap_sem); + + vma = find_vma(mm, address); + + if (!vma) { +#ifdef DEBUG_FAULT + print_task(tsk); + printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", + __FUNCTION__,__LINE__, + address,regs->pc,textaccess,writeaccess); + show_regs(regs); +#endif + goto bad_area; + } + if (vma->vm_start <= address) { + goto good_area; + } + + if (!(vma->vm_flags & VM_GROWSDOWN)) { +#ifdef DEBUG_FAULT + print_task(tsk); + printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", + __FUNCTION__,__LINE__, + address,regs->pc,textaccess,writeaccess); + show_regs(regs); + + print_vma(vma); +#endif + goto bad_area; + } + if (expand_stack(vma, address)) { +#ifdef DEBUG_FAULT + print_task(tsk); + printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", + __FUNCTION__,__LINE__, + address,regs->pc,textaccess,writeaccess); + show_regs(regs); +#endif + goto bad_area; + } +/* + * Ok, we have a good vm_area for this memory access, so + * we can handle it.. + */ +good_area: + if (writeaccess) { + if (!(vma->vm_flags & VM_WRITE)) + goto bad_area; + } else { + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + goto bad_area; + } + + if (textaccess) { + if (!(vma->vm_flags & VM_EXEC)) + goto bad_area; + } + + /* + * If for any reason at all we couldn't handle the fault, + * make sure we exit gracefully rather than endlessly redo + * the fault. + */ +survive: + switch (handle_mm_fault(mm, vma, address, writeaccess)) { + case 1: + tsk->min_flt++; + break; + case 2: + tsk->maj_flt++; + break; + case 0: + goto do_sigbus; + default: + goto out_of_memory; + } + /* If we get here, the page fault has been handled. Do the TLB refill + now from the newly-setup PTE, to avoid having to fault again right + away on the same instruction. */ + pte = lookup_pte (mm, address); + if (!pte) { + /* From empirical evidence, we can get here, due to + !pte_present(pte). (e.g. if a swap-in occurs, and the page + is swapped back out again before the process that wanted it + gets rescheduled?) */ + goto no_pte; + } + + __do_tlb_refill(address, textaccess, pte); + +no_pte: + + up_read(&mm->mmap_sem); + return; + +/* + * Something tried to access memory that isn't in our memory map.. + * Fix it, but check if it's kernel or user first.. + */ +bad_area: +#ifdef DEBUG_FAULT + printk("fault:bad area\n"); +#endif + up_read(&mm->mmap_sem); + + if (user_mode(regs)) { + tsk->thread.address = address; + tsk->thread.error_code = writeaccess; + force_sig(SIGSEGV, tsk); + return; + } + +no_context: +#ifdef DEBUG_FAULT + printk("fault:No context\n"); +#endif + /* Are we prepared to handle this kernel fault? */ + fixup = search_exception_table(regs->pc); + if (fixup != 0) { + regs->pc = fixup; + return; + } + +/* + * Oops. The kernel tried to access some bad page. We'll have to + * terminate things with extreme prejudice. + * + */ + if (address < PAGE_SIZE) + printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); + else + printk(KERN_ALERT "Unable to handle kernel paging request"); + printk(" at virtual address %08lx\n", address); + printk(KERN_ALERT "pc = %08Lx%08Lx\n", regs->pc >> 32, regs->pc & 0xffffffff); + die("Oops", regs, writeaccess); + do_exit(SIGKILL); + +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +out_of_memory: + if (current->pid == 1) { + yield(); + goto survive; + } + printk("fault:Out of memory\n"); + up_read(&mm->mmap_sem); + printk("VM: killing process %s\n", tsk->comm); + if (user_mode(regs)) + do_exit(SIGKILL); + goto no_context; + +do_sigbus: + printk("fault:Do sigbus\n"); + up_read(&mm->mmap_sem); + + /* + * Send a sigbus, regardless of whether we were in kernel + * or user mode. + */ + tsk->thread.address = address; + tsk->thread.error_code = writeaccess; + tsk->thread.trap_no = 14; + force_sig(SIGBUS, tsk); + + /* Kernel mode? Handle exceptions or die */ + if (!user_mode(regs)) + goto no_context; +} + + +void flush_tlb_all(void); + +void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ +#if defined(CONFIG_SH64_PROC_TLB) + ++calls_to_update_mmu_cache; +#endif + /* This appears to get called once for every pte entry that gets + established => I don't think it's efficient to try refilling the + TLBs with the pages - some may not get accessed even. Also, for + executable pages, it is impossible to determine reliably here which + TLB they should be mapped into (or both even). + + So, just do nothing here and handle faults on demand. In the + TLBMISS handling case, the refill is now done anyway after the pte + has been fixed up, so that deals with most useful cases. + */ + + return; +} + +static void __flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + unsigned long long match, pteh=0, lpage; + unsigned long tlb; + struct mm_struct *mm; + + mm = vma->vm_mm; + + if (mm->context == NO_CONTEXT) + return; + + /* + * Sign-extend based on neff. + */ + lpage = (page & NEFF_SIGN) ? (page | NEFF_MASK) : page; + match = ((mm->context & MMU_CONTEXT_ASID_MASK) << PTEH_ASID_SHIFT) | PTEH_VALID; + match |= lpage; + + /* Do ITLB : don't bother for pages in non-exectutable VMAs */ + if (vma->vm_flags & VM_EXEC) { + for_each_itlb_entry(tlb) { + asm volatile ("getcfg %1, 0, %0" + : "=r" (pteh) + : "r" (tlb) ); + + if (pteh == match) { + __flush_tlb_slot(tlb); + break; + } + + } + } + + /* Do DTLB : any page could potentially be in here. */ + for_each_dtlb_entry(tlb) { + asm volatile ("getcfg %1, 0, %0" + : "=r" (pteh) + : "r" (tlb) ); + + if (pteh == match) { + __flush_tlb_slot(tlb); + break; + } + + } +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + unsigned long flags; + +#if defined(CONFIG_SH64_PROC_TLB) + ++calls_to_flush_tlb_page; +#endif + + if (vma->vm_mm) { + page &= PAGE_MASK; + save_and_cli(flags); + __flush_tlb_page(vma, page); + restore_flags(flags); + } +} + +void flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + unsigned long flags; + unsigned long long match, pteh=0, pteh_epn, pteh_low; + unsigned long tlb; + +#if defined(CONFIG_SH64_PROC_TLB) + ++calls_to_flush_tlb_range; + + { + unsigned long size = (end - 1) - start; + size >>= 12; /* divide by PAGE_SIZE */ + size++; /* end=start+4096 => 1 page */ + switch (size) { + case 1 : flush_tlb_range_1++; break; + case 2 : flush_tlb_range_2++; break; + case 3 ... 4 : flush_tlb_range_3_4++; break; + case 5 ... 7 : flush_tlb_range_5_7++; break; + case 8 ... 11 : flush_tlb_range_8_11++; break; + case 12 ... 15 : flush_tlb_range_12_15++; break; + default : flush_tlb_range_16_up++; break; + } + } +#endif + + if (mm->context == NO_CONTEXT) + return; + + save_and_cli(flags); + + start &= PAGE_MASK; + end &= PAGE_MASK; + + match = ((mm->context & MMU_CONTEXT_ASID_MASK) << PTEH_ASID_SHIFT) | PTEH_VALID; + + /* Flush ITLB */ + for_each_itlb_entry(tlb) { + asm volatile ("getcfg %1, 0, %0" + : "=r" (pteh) + : "r" (tlb) ); + + pteh_epn = pteh & PAGE_MASK; + pteh_low = pteh & ~PAGE_MASK; + + if (pteh_low == match && pteh_epn >= start && pteh_epn <= end) + __flush_tlb_slot(tlb); + } + + /* Flush DTLB */ + for_each_dtlb_entry(tlb) { + asm volatile ("getcfg %1, 0, %0" + : "=r" (pteh) + : "r" (tlb) ); + + pteh_epn = pteh & PAGE_MASK; + pteh_low = pteh & ~PAGE_MASK; + + if (pteh_low == match && pteh_epn >= start && pteh_epn <= end) + __flush_tlb_slot(tlb); + } + + restore_flags(flags); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + unsigned long flags; + +#if defined(CONFIG_SH64_PROC_TLB) + ++calls_to_flush_tlb_mm; +#endif + + if (mm->context == NO_CONTEXT) + return; + + save_and_cli(flags); + + mm->context=NO_CONTEXT; + if(mm==current->mm) + activate_context(mm); + + restore_flags(flags); + +} + +void flush_tlb_all(void) +{ + /* Invalidate all, including shared pages, excluding fixed TLBs */ + + unsigned long flags, tlb; + +#if defined(CONFIG_SH64_PROC_TLB) + ++calls_to_flush_tlb_all; +#endif + + save_and_cli(flags); + + /* Flush each ITLB entry */ + for_each_itlb_entry(tlb) { + __flush_tlb_slot(tlb); + } + + /* Flush each DTLB entry */ + for_each_dtlb_entry(tlb) { + __flush_tlb_slot(tlb); + } + + restore_flags(flags); +} + +#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT +/* Scan the page table structure of an entire struct mm for obvious anomalies. */ + +static inline int starts_a(unsigned long xx) +{ + /* Check if virtual address starts with 'a'. The kernel's superpage + * lives at a0000000-bfffffff, and the lower part maps the RAM + directly. So if a kernel pointer doesn't start with it's top nibble + = 'a' (at least up to 256Mb of RAM), it's bad. - RPC */ + if (((xx >> 28) & 0xf) == 0xa) { + return 1; + } else { + return 0; + } +} + +static inline int is_present(unsigned long x) +{ + unsigned long mask = 0x80000000UL | _KERNPG_TABLE; + unsigned long y; + + y = x & mask; + if (y) return 1; + else return 0; +} + +void audit_mm (unsigned long long expevt, unsigned long long intevt, unsigned long long tra, unsigned long long vec) +{ + /* It seems simpler to have pgd,pmd,pte declared as pointers of + appropriate types that we can just apply array indices to. What + we're doing here didn't fit with the existing macros very well. */ + typedef unsigned long long my_pte_t; + typedef my_pte_t *my_pmd_t; + typedef my_pmd_t *my_pgd_t; + +#define SHOW_SRC do { \ + switch (vec) { \ + case 0x100: case 0x400: \ + printk("EXPEVT=%08llx TRA=%08llx VEC=%08llx\n", expevt, tra, vec); break; \ + case 0x600: \ + printk("INTEVT=%08llx\n", intevt); break; \ + default: \ + printk("Source of this syscall/irq/exc unknown\n"); break; \ + } \ + } \ + while (0) + + my_pgd_t *pgd; + my_pmd_t *pmd; + my_pte_t *pte; + + unsigned long xx_pgd, xx_pmd, xx_pte; + int i, j, k; + int pid = current->pid; + struct mm_struct *mm; + + /* Ought to check for the page_present condition also. */ + + mm = current->active_mm; + if (in_interrupt() || !mm) return; + + pgd = (my_pgd_t *) mm->pgd; + xx_pgd = (unsigned long) pgd; + + if (!starts_a(xx_pgd)) { + printk("PID %5d, corrupt mm->pgd = %08lx\n", pid, xx_pgd); + SHOW_SRC; + return; /* not a lot of point going on. */ + } + + for (i=0; i= 0x40000000UL) && (masked_entry < 0x5fffffffUL); + in_emi = (masked_entry >= 0x80000000UL) && (masked_entry < 0x8fffffffUL); /* Assume 256Mb of RAM at most */ + if (!in_emi && !in_pci) { /* Assume 128Mb of RAM */ + printk("PID %5d, pte[%d] corrupted (=%08lx%08lx) (in pmd[%d], pgd[%d])\n", pid, k, (unsigned long) (entry>>32), (unsigned long) entry, j, i); + SHOW_SRC; + continue; /* no point scanning further. */ + } + } + } + } + } +} +#endif /* CONFIG_SH64_PAGE_TABLE_AUDIT */ + +#if defined(CONFIG_SH64_PROC_TLB) +/* Procfs interface to read the performance information */ + +static int +tlb_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data) +{ + int len=0; + len += sprintf(buf+len, "do_fast_page_fault called %12lld times\n", calls_to_do_fast_page_fault); + len += sprintf(buf+len, "do_slow_page_fault called %12lld times\n", calls_to_do_slow_page_fault); + len += sprintf(buf+len, "update_mmu_cache called %12lld times\n", calls_to_update_mmu_cache); + len += sprintf(buf+len, "flush_tlb_page called %12lld times\n", calls_to_flush_tlb_page); + len += sprintf(buf+len, "flush_tlb_range called %12lld times\n", calls_to_flush_tlb_range); + len += sprintf(buf+len, "flush_tlb_mm called %12lld times\n", calls_to_flush_tlb_mm); + len += sprintf(buf+len, "flush_tlb_all called %12lld times\n", calls_to_flush_tlb_all); + len += sprintf(buf+len, "flush_tlb_range_sizes\n" + " 1 : %12lld\n" + " 2 : %12lld\n" + " 3 - 4 : %12lld\n" + " 5 - 7 : %12lld\n" + " 8 - 11 : %12lld\n" + "12 - 15 : %12lld\n" + "16+ : %12lld\n", + flush_tlb_range_1, flush_tlb_range_2, flush_tlb_range_3_4, + flush_tlb_range_5_7, flush_tlb_range_8_11, flush_tlb_range_12_15, + flush_tlb_range_16_up); + len += sprintf(buf+len, "page not present %12lld times\n", page_not_present); + *eof = 1; + return len; +} + +static int __init register_proc_tlb(void) +{ + create_proc_read_entry("tlb", 0, NULL, tlb_proc_info, NULL); + return 0; +} + +__initcall(register_proc_tlb); + +#endif diff -urN linux-2.4.21/arch/sh64/mm/init.c linux-2.4.22/arch/sh64/mm/init.c --- linux-2.4.21/arch/sh64/mm/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,203 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mm/init.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +#include +#endif + +mmu_gather_t mmu_gathers[NR_CPUS]; + +/* + * Cache of MMU context last used. + */ +unsigned long mmu_context_cache; +pgd_t * mmu_pdtp_cache; + +static unsigned long totalram_pages = 0; +static unsigned long totalhigh_pages = 0; + +/* + * BAD_PAGE is the page that is used for page faults when linux + * is out-of-memory. Older versions of linux just did a + * do_exit(), but using this instead means there is less risk + * for a process dying in kernel mode, possibly leaving an inode + * unused etc.. + * + * BAD_PAGETABLE is the accompanying page-table: it is initialized + * to point to BAD_PAGE entries. + * + * ZERO_PAGE is a special page that is used for zero-initialized + * data and COW. + */ + +extern unsigned char empty_zero_page[PAGE_SIZE]; +extern unsigned char empty_bad_page[PAGE_SIZE]; +extern pte_t empty_bad_pte_table[PTRS_PER_PTE]; +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +extern char _text, _etext, _edata, __bss_start, _end; +extern char __init_begin, __init_end; + +/* It'd be good if these lines were in the standard header file. */ +#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT) +#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn) + + +void show_mem(void) +{ + int i, total = 0, reserved = 0; + int shared = 0, cached = 0; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (page_count(mem_map+i)) + shared += page_count(mem_map+i) - 1; + } + printk("%d pages of RAM\n",total); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); + + show_buffers(); +} + +/* + * paging_init() sets up the page tables. + * + * head.S already did a lot to set up address translation for the kernel. + * Here we comes with: + * . MMU enabled + * . ASID set (SR) + * . some 512MB regions being mapped of which the most relevant here is: + * . CACHED segment (ASID 0 [irrelevant], shared AND NOT user) + * . possible variable length regions being mapped as: + * . UNCACHED segment (ASID 0 [irrelevant], shared AND NOT user) + * . All of the memory regions are placed, independently from the platform + * on high addresses, above 0x80000000. + * . swapper_pg_dir is already cleared out by the .space directive + * in any case swapper does not require a real page directory since + * it's all kernel contained. + * + * Those pesky NULL-reference errors in the kernel are then + * dealt with by not mapping address 0x00000000 at all. + * + */ +void __init paging_init(void) +{ + unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; + + + mmu_context_cache = MMU_CONTEXT_FIRST_VERSION; + + /* + * All memory is good as ZONE_NORMAL (fall-through) and ZONE_DMA. + */ + zones_size[ZONE_DMA] = MAX_LOW_PFN - START_PFN; + + free_area_init_node(0, NODE_DATA(0), 0,zones_size, __MEMORY_START, 0); +} + +void __init mem_init(void) +{ + int codesize, reservedpages, datasize, initsize; + int tmp; + + max_mapnr = num_physpages = MAX_LOW_PFN - START_PFN; + high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE); + + /* + * Clear the zero-page. + * This is not required but we might want to re-use + * this very page to pass boot parameters, one day. + */ + memset(empty_zero_page, 0, PAGE_SIZE); + + /* this will put all low memory onto the freelists */ + totalram_pages += free_all_bootmem(); + reservedpages = 0; + for (tmp = 0; tmp < num_physpages; tmp++) + /* + * Only count reserved RAM pages + */ + if (PageReserved(mem_map+tmp)) + reservedpages++; + codesize = (unsigned long) &_etext - (unsigned long) &_text; + datasize = (unsigned long) &_edata - (unsigned long) &_etext; + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + + printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), + max_mapnr << (PAGE_SHIFT-10), + codesize >> 10, + reservedpages << (PAGE_SHIFT-10), + datasize >> 10, + initsize >> 10); +} + +void free_initmem(void) +{ + unsigned long addr; + + addr = (unsigned long)(&__init_begin); + for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { + ClearPageReserved(mem_map + MAP_NR(addr)); + set_page_count(mem_map+MAP_NR(addr), 1); + free_page(addr); + totalram_pages++; + } + printk ("Freeing unused kernel memory: %ldk freed\n", (&__init_end - &__init_begin) >> 10); +} + +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + unsigned long p; + for (p = start; p < end; p += PAGE_SIZE) { + ClearPageReserved(mem_map + MAP_NR(p)); + set_page_count(mem_map+MAP_NR(p), 1); + free_page(p); + totalram_pages++; + } + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); +} +#endif + +void si_meminfo(struct sysinfo *val) +{ + val->totalram = totalram_pages; + val->sharedram = 0; + val->freeram = nr_free_pages(); + val->bufferram = atomic_read(&buffermem_pages); + val->totalhigh = totalhigh_pages; + val->freehigh = nr_free_highpages(); + val->mem_unit = PAGE_SIZE; + return; +} diff -urN linux-2.4.21/arch/sh64/mm/ioremap.c linux-2.4.22/arch/sh64/mm/ioremap.c --- linux-2.4.21/arch/sh64/mm/ioremap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/ioremap.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,440 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mm/ioremap.c + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 Paul Mundt + * + * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly + * derived from arch/i386/mm/ioremap.c . + * + * (C) Copyright 1995 1996 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include + +/* +** change to: +** #define DEBUG_IOREMAP(args) printk(args) +** to turn on ioremap trace. +*/ +#define DEBUG_IOREMAP(args) + +static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + + DEBUG_IOREMAP((" %s: pte %x address %x size %x phys_addr %x\n", \ + __FUNCTION__,pte,address,size,phys_addr)); + + do { + if (!pte_none(*pte)) + printk("remap_area_pte: page already exists\n"); + set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | + _PAGE_READ | _PAGE_WRITE | + _PAGE_DIRTY | _PAGE_ACCESSED |_PAGE_SHARED | flags))); + address += PAGE_SIZE; + phys_addr += PAGE_SIZE; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + + DEBUG_IOREMAP(("%s: pmd 0x%08x, addr. 0x%08x, phys. 0x%08x, end 0x%08x pmd 0x%08x\n", \ + pmd, address, phys_addr, end)); + + phys_addr -= address; + do { + + DEBUG_IOREMAP(("%s: pmd 0x%08x, addr. 0x%08x, phys. 0x%08x, end 0x%08x pmd 0x%08x\n", \ + __FUNCTION__, pmd, address, phys_addr, end)); + + pte_t * pte = pte_alloc(&init_mm, pmd, address); + if (!pte) { + return -ENOMEM; + } + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + + DEBUG_IOREMAP(("remap_area_pmd address is 0x%08x phys_addr is 0x%08x end 0x%08x\n", address,phys_addr,end)); + + + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + spin_lock(&init_mm.page_table_lock); + do { + + pmd_t *pmd = pmd_alloc(&init_mm,dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) { + break; + } + error=0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + spin_unlock(&init_mm.page_table_lock); + flush_tlb_all(); + return 0; +} + +/* + * Generic mapping function (not visible outside): + */ + +/* + * Remap an arbitrary physical address space into the kernel virtual + * address space. Needed when the kernel wants to access high addresses + * directly. + * + * NOTE! We need to allow non-page-aligned mappings too: we will obviously + * have to convert them into an offset in a page-aligned mapping, but the + * caller shouldn't need to know that small detail. + */ +void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) +{ + void * addr; + struct vm_struct * area; + unsigned long offset, last_addr; + + /* Don't allow wraparound or zero size */ + last_addr = phys_addr + size - 1; + if (!size || last_addr < phys_addr) + return NULL; + + /* + * Mappings have to be page-aligned + */ + offset = phys_addr & ~PAGE_MASK; + phys_addr &= PAGE_MASK; + size = PAGE_ALIGN(last_addr) - phys_addr; + + /* + * Ok, go for it.. + */ + area = get_vm_area(size, VM_IOREMAP); + DEBUG_IOREMAP(("Get vm_area returns 0x%08x addr 0x%08x \n", \ + area, area->addr)); + + if (!area) + return NULL; + addr = area->addr; + if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) { + vfree(addr); + return NULL; + } + return (void *) (offset + (char *)addr); +} + +void iounmap(void *addr) +{ + if (((long) addr >= VMALLOC_START) && ((long) addr <= VMALLOC_END)) + return vfree((void *) (PAGE_MASK & (unsigned long) addr)); +} + +static struct resource shmedia_iomap = { + .name = "shmedia_iomap", + .start = IOBASE_VADDR, + .end = IOBASE_END - 1, +}; + +static void shmedia_mapioaddr(unsigned long pa, unsigned long va); +static void shmedia_unmapioaddr(unsigned long vaddr); +static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz); + +/* + * We have the same problem as the SPARC, so lets have the same comment: + * Our mini-allocator... + * Boy this is gross! We need it because we must map I/O for + * timers and interrupt controller before the kmalloc is available. + */ + +#define XNMLN 15 +#define XNRES 10 + +struct xresource { + struct resource xres; /* Must be first */ + int xflag; /* 1 == used */ + char xname[XNMLN+1]; +}; + +static struct xresource xresv[XNRES]; + +static struct xresource *xres_alloc(void) +{ + struct xresource *xrp; + int n; + + xrp = xresv; + for (n = 0; n < XNRES; n++) { + if (xrp->xflag == 0) { + xrp->xflag = 1; + return xrp; + } + xrp++; + } + return NULL; +} + +static void xres_free(struct xresource *xrp) +{ + xrp->xflag = 0; +} + +static struct resource *shmedia_find_resource(struct resource *root, + unsigned long vaddr) +{ + struct resource *res; + + for (res = root->child; res; res = res->sibling) + if (res->start <= vaddr && res->end >= vaddr) + return res; + + return NULL; +} + +static unsigned long shmedia_alloc_io(unsigned long phys, unsigned long size, + const char *name) +{ + static int printed_full = 0; + struct xresource *xres; + struct resource *res; + char *tack; + int tlen; + + if (name == NULL) name = "???"; + + if ((xres = xres_alloc()) != 0) { + tack = xres->xname; + res = &xres->xres; + } else { + if (!printed_full) { + printk("%s: done with statics, switching to kmalloc\n", + __FUNCTION__); + printed_full = 1; + } + tlen = strlen(name); + tack = kmalloc(sizeof (struct resource) + tlen + 1, GFP_KERNEL); + if (!tack) + return -ENOMEM; + memset(tack, 0, sizeof(struct resource)); + res = (struct resource *) tack; + tack += sizeof (struct resource); + } + + strncpy(tack, name, XNMLN); + tack[XNMLN] = 0; + res->name = tack; + + return shmedia_ioremap(res, phys, size); +} + +static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz) +{ + unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK); + unsigned long round_sz = (offset + sz + PAGE_SIZE-1) & PAGE_MASK; + unsigned long va; + unsigned int psz; + + if (allocate_resource(&shmedia_iomap, res, round_sz, + shmedia_iomap.start, shmedia_iomap.end, + PAGE_SIZE, NULL, NULL) != 0) { + panic("alloc_io_res(%s): cannot occupy\n", + (res->name != NULL)? res->name: "???"); + } + + va = res->start; + pa &= PAGE_MASK; + + psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE; + + /* log at boot time ... */ + printk("mapioaddr: %6s [%2ld page%s] va 0x%08lx pa 0x%08x\n", + ((res->name != NULL) ? res->name : "???"), + psz, psz == 1 ? " " : "s", va, pa); + + for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) { + shmedia_mapioaddr(pa, va); + va += PAGE_SIZE; + pa += PAGE_SIZE; + } + + res->start += offset; + res->end = res->start + sz - 1; /* not strictly necessary.. */ + + return res->start; +} + +static void shmedia_free_io(struct resource *res) +{ + unsigned long len = res->end - res->start + 1; + + BUG_ON((len & (PAGE_SIZE - 1)) != 0); + + while (len) { + len -= PAGE_SIZE; + shmedia_unmapioaddr(res->start + len); + } + + release_resource(res); +} + +static void shmedia_mapioaddr(unsigned long pa, unsigned long va) +{ + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + unsigned long flags = 1; /* 1 = CB0-1 device */ + + + DEBUG_IOREMAP(("shmedia_mapiopage pa %08x va %08x\n", pa, va)); + + pgdp = pgd_offset_k(va); + if (pgd_none(*pgdp)) { + pmdp = alloc_bootmem_low_pages(PTRS_PER_PMD * sizeof(pmd_t)); + if (pmdp == NULL) panic("No memory for pmd\n"); + memset(pmdp, 0, PTRS_PER_PGD * sizeof(pmd_t)); + set_pgd(pgdp, __pgd((unsigned long)pmdp | _KERNPG_TABLE)); + } + + pmdp = pmd_offset(pgdp, va); + if (pmd_none(*pmdp)) { + ptep = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t)); + if (ptep == NULL) panic("No memory for pte\n"); + clear_page((void *)ptep); + set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE)); + } + + ptep = pte_offset(pmdp, va); + set_pte(ptep, mk_pte_phys(pa, __pgprot(_PAGE_PRESENT | + _PAGE_READ | _PAGE_WRITE | + _PAGE_DIRTY | _PAGE_ACCESSED |_PAGE_SHARED | flags))); +} + +static void shmedia_unmapioaddr(unsigned long vaddr) +{ + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + pgdp = pgd_offset_k(vaddr); + pmdp = pmd_offset(pgdp, vaddr); + + if (pmd_none(*pmdp) || pmd_bad(*pmdp)) + return; + + ptep = pte_offset(pmdp, vaddr); + + if (pte_none(*ptep) || !pte_present(*ptep)) + return; + + clear_page((void *)ptep); + pte_clear(ptep); +} + +unsigned long onchip_remap(unsigned long phys, unsigned long size, const char *name) +{ + if (size < PAGE_SIZE) + size = PAGE_SIZE; + + return shmedia_alloc_io(phys, size, name); +} + +void onchip_unmap(unsigned long vaddr) +{ + struct resource *res; + unsigned int psz; + + res = shmedia_find_resource(&shmedia_iomap, vaddr); + if (!res) { + printk(KERN_ERR "%s: Failed to free 0x%08lx\n", + __FUNCTION__, vaddr); + return; + } + + psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE; + + printk(KERN_DEBUG "unmapioaddr: %6s [%2ld page%s] freed\n", + res->name, psz, psz == 1 ? " " : "s"); + + shmedia_free_io(res); + + if ((char *)res >= (char *)xresv && + (char *)res < (char *)&xresv[XNRES]) { + xres_free((struct xresource *)res); + } else { + kfree(res); + } +} + +#ifdef CONFIG_PROC_FS +static int +ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, + void *data) +{ + char *p = buf, *e = buf + length; + struct resource *r; + const char *nm; + + for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) { + if (p + 32 >= e) /* Better than nothing */ + break; + if ((nm = r->name) == 0) nm = "???"; + p += sprintf(p, "%08lx-%08lx: %s\n", r->start, r->end, nm); + } + + return p-buf; +} +#endif /* CONFIG_PROC_FS */ + +static int __init register_proc_onchip(void) +{ +#ifdef CONFIG_PROC_FS + create_proc_read_entry("io_map",0,0, ioremap_proc_info, &shmedia_iomap); +#endif + return 0; +} + +__initcall(register_proc_onchip); diff -urN linux-2.4.21/arch/sh64/mm/tlb.c linux-2.4.22/arch/sh64/mm/tlb.c --- linux-2.4.21/arch/sh64/mm/tlb.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/tlb.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,166 @@ +/* + * arch/sh64/mm/tlb.c + * + * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 Richard Curnow + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include +#include +#include +#include +#include + +/** + * sh64_tlb_init + * + * Perform initial setup for the DTLB and ITLB. + */ +int __init sh64_tlb_init(void) +{ + /* Assign some sane DTLB defaults */ + cpu_data->dtlb.entries = 64; + cpu_data->dtlb.step = 0x10; + + cpu_data->dtlb.first = DTLB_FIXED | cpu_data->dtlb.step; + cpu_data->dtlb.next = cpu_data->dtlb.first; + + cpu_data->dtlb.last = DTLB_FIXED | + ((cpu_data->dtlb.entries - 1) * + cpu_data->dtlb.step); + + /* And again for the ITLB */ + cpu_data->itlb.entries = 64; + cpu_data->itlb.step = 0x10; + + cpu_data->itlb.first = ITLB_FIXED | cpu_data->itlb.step; + cpu_data->itlb.next = cpu_data->itlb.first; + cpu_data->itlb.last = ITLB_FIXED | + ((cpu_data->itlb.entries - 1) * + cpu_data->itlb.step); + + return 0; +} + +/** + * sh64_next_free_dtlb_entry + * + * Find the next available DTLB entry + */ +unsigned long long sh64_next_free_dtlb_entry(void) +{ + return cpu_data->dtlb.next; +} + +/** + * sh64_get_wired_dtlb_entry + * + * Allocate a wired (locked-in) entry in the DTLB + */ +unsigned long long sh64_get_wired_dtlb_entry(void) +{ + unsigned long long entry = sh64_next_free_dtlb_entry(); + + cpu_data->dtlb.first += cpu_data->dtlb.step; + cpu_data->dtlb.next += cpu_data->dtlb.step; + + return entry; +} + +/** + * sh64_put_wired_dtlb_entry + * + * @entry: Address of TLB slot. + * + * Free a wired (locked-in) entry in the DTLB. + * + * Works like a stack, last one to allocate must be first one to free. + */ +int sh64_put_wired_dtlb_entry(unsigned long long entry) +{ + __flush_tlb_slot(entry); + + /* + * We don't do any particularly useful tracking of wired entries, + * so this approach works like a stack .. last one to be allocated + * has to be the first one to be freed. + * + * We could potentially load wired entries into a list and work on + * rebalancing the list periodically (which also entails moving the + * contents of a TLB entry) .. though I have a feeling that this is + * more trouble than it's worth. + */ + + /* + * Entry must be valid .. we don't want any ITLB addresses! + */ + if (entry <= DTLB_FIXED) + return -EINVAL; + + /* + * Next, check if we're within range to be freed. (ie, must be the + * entry beneath the first 'free' entry! + */ + if (entry < (cpu_data->dtlb.first - cpu_data->dtlb.step)) + return -EINVAL; + + /* If we are, then bring this entry back into the list */ + cpu_data->dtlb.first -= cpu_data->dtlb.step; + cpu_data->dtlb.next = entry; + + return 0; +} + +/** + * sh64_setup_tlb_slot + * + * @config_addr: Address of TLB slot. + * @eaddr: Virtual address. + * @asid: Address Space Identifier. + * @paddr: Physical address. + * + * Load up a virtual<->physical translation for @eaddr<->@paddr in the + * pre-allocated TLB slot @config_addr (see sh64_get_wired_dtlb_entry). + */ +inline void sh64_setup_tlb_slot(unsigned long long config_addr, + unsigned long eaddr, + unsigned long asid, + unsigned long paddr) +{ + unsigned long long pteh, ptel; + + /* Sign extension */ +#if (NEFF == 32) + pteh = (unsigned long long)(signed long long)(signed long) eaddr; +#else +#error "Can't sign extend more than 32 bits yet" +#endif + pteh &= PAGE_MASK; + pteh |= (asid << PTEH_ASID_SHIFT) | PTEH_VALID; +#if (NEFF == 32) + ptel = (unsigned long long)(signed long long)(signed long) paddr; +#else +#error "Can't sign extend more than 32 bits yet" +#endif + ptel &= PAGE_MASK; + ptel |= (_PAGE_CACHABLE | _PAGE_READ | _PAGE_WRITE); + + asm volatile("putcfg %0, 1, %1\n\t" + "putcfg %0, 0, %2\n" + : : "r" (config_addr), "r" (ptel), "r" (pteh)); +} + +/** + * sh64_teardown_tlb_slot + * + * @config_addr: Address of TLB slot. + * + * Teardown any existing mapping in the TLB slot @config_addr. + */ +inline void sh64_teardown_tlb_slot(unsigned long long config_addr) + __attribute__ ((alias("__flush_tlb_slot"))); + diff -urN linux-2.4.21/arch/sh64/mm/tlbmiss.c linux-2.4.22/arch/sh64/mm/tlbmiss.c --- linux-2.4.21/arch/sh64/mm/tlbmiss.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/mm/tlbmiss.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,283 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh64/mm/tlbmiss.c + * + * Original code from fault.c + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Fast PTE->TLB refill path + * Copyright (C) 2003 Richard.Curnow@superh.com + * + * IMPORTANT NOTES : + * The do_fast_page_fault function is called from a context in entry.S where very few registers + * have been saved. In particular, the code in this file must be compiled not to use ANY + * caller-save regiseters that are not part of the restricted save set. Also, it means that + * code in this file must not make calls to functions elsewhere in the kernel, or else the + * excepting context will see corruption in its caller-save registers. Plus, the entry.S save + * area is non-reentrant, so this code has to run with SR.BL==1, i.e. no interrupts taken inside + * it and panic on any exception. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include /* required by inline asm statements */ + +/* Callable from fault.c, so not static */ +__inline__ void __do_tlb_refill(unsigned long address, + unsigned long long is_text_not_data, pte_t *pte) +{ + unsigned long long ptel; + unsigned long long pteh=0; + struct tlb_info *tlbp; + unsigned long long next; + + /* Get PTEL first */ + ptel = pte_val(*pte); + + /* + * Set PTEH register + */ + pteh = address & MMU_VPN_MASK; + + /* Sign extend based on neff. */ +#if (NEFF == 32) + /* Faster sign extension */ + pteh = (unsigned long long)(signed long long)(signed long)pteh; +#else + /* General case */ + pteh = (pteh & NEFF_SIGN) ? (pteh | NEFF_MASK) : pteh; +#endif + + /* Set the ASID. */ + pteh |= get_asid() << PTEH_ASID_SHIFT; + + pteh |= PTEH_VALID; + + /* Set PTEL register, set_pte has performed the sign extension */ + ptel &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ + ptel |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */ + + tlbp = is_text_not_data ? &(cpu_data->itlb) : &(cpu_data->dtlb); + next = tlbp->next; + __flush_tlb_slot(next); + asm volatile ("putcfg %0,1,%2\n\n\t" + "putcfg %0,0,%1\n" + : : "r" (next), "r" (pteh), "r" (ptel) ); + + next += TLB_STEP; + if (next > tlbp->last) next = tlbp->first; + tlbp->next = next; + +} + +static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long protection_flags, + unsigned long long textaccess, + unsigned long address) +{ + pgd_t *dir; + pmd_t *pmd; + static pte_t *pte; + pte_t entry; + + dir = pgd_offset_k(address); + pmd = pmd_offset(dir, address); + + + if (pmd_none(*pmd)) { + return 0; + } + if (pmd_bad(*pmd)) { + pmd_clear(pmd); + return 0; + } + pte = pte_offset(pmd, address); + entry = *pte; + if (pte_none(entry) || !pte_present(entry)) { + return 0; + } + + if ((pte_val(entry) & protection_flags) != protection_flags) { + return 0; + } + + __do_tlb_refill(address, textaccess, pte); + + return 1; +} + +static int handle_tlbmiss(struct mm_struct *mm, unsigned long long protection_flags, + unsigned long long textaccess, + unsigned long address) +{ + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + + + /* NB. The PGD currently only contains a single entry - there is no + page table tree stored for the top half of the address space since + virtual pages in that region should never be mapped in user mode. + (In kernel mode, the only things in that region are the 512Mb super + page (locked in), and vmalloc (modules) + I/O device pages (handled + by handle_vmalloc_fault), so no PGD for the upper half is required + by kernel mode either). + + See how mm->pgd is allocated and initialised in pgd_alloc to see why + the next test is necessary. - RPC */ + if (address >= (unsigned long) TASK_SIZE) { + /* upper half - never has page table entries. */ + return 0; + } + dir = pgd_offset(mm, address); + if (pgd_none(*dir)) { + return 0; + } + if (!pgd_present(*dir)) { + return 0; + } + + pmd = pmd_offset(dir, address); + if (pmd_none(*pmd)) { + return 0; + } + if (!pmd_present(*pmd)) { + return 0; + } + pte = pte_offset(pmd, address); + entry = *pte; + if (pte_none(entry)) { + return 0; + } + if (!pte_present(entry)) { + return 0; + } + + /* If the page doesn't have sufficient protection bits set to service the + kind of fault being handled, there's not much point doing the TLB refill. + Punt the fault to the general handler. */ + if ((pte_val(entry) & protection_flags) != protection_flags) { + return 0; + } + + __do_tlb_refill(address, textaccess, pte); + + return 1; +} + +/* Put all this information into one structure so that everything is just arithmetic + relative to a single base address. This reduces the number of movi/shori pairs needed + just to load addresses of static data. */ +struct expevt_lookup { + unsigned short protection_flags[8]; + unsigned char is_text_access[8]; + unsigned char is_write_access[8]; +}; + +#define PRU (1<<9) +#define PRW (1<<8) +#define PRX (1<<7) +#define PRR (1<<6) + +#define DIRTY (_PAGE_DIRTY | _PAGE_ACCESSED) +#define YOUNG (_PAGE_ACCESSED) + +/* Sized as 8 rather than 4 to allow checking the PTE's PRU bit against whether + the fault happened in user mode or privileged mode. */ +static struct expevt_lookup expevt_lookup_table = { + .protection_flags = {PRX, PRX, 0, 0, PRR, PRR, PRW, PRW}, + .is_text_access = {1, 1, 0, 0, 0, 0, 0, 0} +}; + +/* + This routine handles page faults that can be serviced just by refilling a + TLB entry from an existing page table entry. (This case represents a very + large majority of page faults.) Return 1 if the fault was successfully + handled. Return 0 if the fault could not be handled. (This leads into the + general fault handling in fault.c which deals with mapping file-backed + pages, stack growth, segmentation faults, swapping etc etc) + */ +asmlinkage int do_fast_page_fault(unsigned long long ssr_md, unsigned long long expevt, + unsigned long address) +{ + struct task_struct *tsk; + struct mm_struct *mm; + unsigned long long textaccess; + unsigned long long protection_flags; + unsigned long long index; + unsigned long long expevt4; + + /* The next few lines implement a way of hashing EXPEVT into a small array index + which can be used to lookup parameters specific to the type of TLBMISS being + handled. Note: + ITLBMISS has EXPEVT==0xa40 + RTLBMISS has EXPEVT==0x040 + WTLBMISS has EXPEVT==0x060 + */ + + expevt4 = (expevt >> 4); + /* TODO : xor ssr_md into this expression too. Then we can check that PRU is set + when it needs to be. */ + index = expevt4 ^ (expevt4 >> 5); + index &= 7; + protection_flags = expevt_lookup_table.protection_flags[index]; + textaccess = expevt_lookup_table.is_text_access[index]; + +#if (CONFIG_SH64_PROC_TLB) + ++calls_to_do_fast_page_fault; +#endif + + /* SIM + * Note this is now called with interrupts still disabled + * This is to cope with being called for a missing IO port + * address with interupts disabled. This should be fixed as + * soon as we have a better 'fast path' miss handler. + * + * Plus take care how you try and debug this stuff. + * For example, writing debug data to a port which you + * have just faulted on is not going to work. + */ + + tsk = current; + mm = tsk->mm; + + if ((address >= VMALLOC_START && address < VMALLOC_END) || + (address >= IOBASE_VADDR && address < IOBASE_END)) { + if (ssr_md) { + /* Process-contexts can never have this address range mapped */ + if (handle_vmalloc_fault(mm, protection_flags, textaccess, address)) { + return 1; + } + } + } else if (!in_interrupt() && mm) { + if (handle_tlbmiss(mm, protection_flags, textaccess, address)) { + return 1; + } + } + + return 0; + +} + diff -urN linux-2.4.21/arch/sh64/vmlinux.lds.S linux-2.4.22/arch/sh64/vmlinux.lds.S --- linux-2.4.21/arch/sh64/vmlinux.lds.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/sh64/vmlinux.lds.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,158 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * arch/sh5/vmlinux.lds.S + * + * ld script to make ST50 Linux kernel + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * benedict.gaster@superh.com: 2nd May 2002 + * Add definition of empty_zero_page to be the first page of kernel image. + * + * benedict.gaster@superh.com: 3rd May 2002 + * Added support for ramdisk, removing statically linked romfs at the same time. + * + * lethal@linux-sh.org: 9th May 2003 + * Kill off GLOBAL_NAME() usage and other CDC-isms. + * + * lethal@linux-sh.org: 19th May 2003 + * Remove support for ancient toolchains. + */ + +#include +#include +#include +#include + +#ifdef NOTDEF +#ifdef CONFIG_LITTLE_ENDIAN +OUTPUT_FORMAT("elf32-sh64l-linux", "elf32-sh64l-linux", "elf32-sh64l-linux") +#else +OUTPUT_FORMAT("elf32-sh64", "elf32-sh64", "elf32-sh64") +#endif +#endif + +OUTPUT_ARCH(sh:sh5) + +#define C_PHYS(x) AT (ADDR(x) - CONFIG_CACHED_MEMORY_OFFSET) +#define U_PHYS(x) AT (ADDR(x) - CONFIG_UNCACHED_MEMORY_OFFSET) + +ENTRY(__start) +SECTIONS +{ + . = CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START + PAGE_SIZE; + _text = .; /* Text and read-only data */ + text = .; /* Text and read-only data */ + + .empty_zero_page : C_PHYS(.empty_zero_page) { + *(.empty_zero_page) + } = 0 + + .text : C_PHYS(.text) { + *(.text) + *(.text64) + *(.text..SHmedia32) + *(.fixup) + *(.gnu.warning) +#ifdef CONFIG_LITTLE_ENDIAN + } = 0x6ff0fff0 +#else + } = 0xf0fff06f +#endif + .text.lock : C_PHYS(.text.lock) { *(.text.lock) } /* out-of-line lock text */ + .rodata : C_PHYS(.rodata) { *(.rodata) *(.rodata.str1.8) } + .kstrtab : C_PHYS(.kstrtab) { *(.kstrtab) } + + /* We likely want __ex_table to be Cache Line aligned */ + . = ALIGN(L1_CACHE_BYTES); /* Exception table */ + __start___ex_table = .; + __ex_table : C_PHYS(__ex_table) { *(__ex_table) } + __stop___ex_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : C_PHYS(__ksymtab) { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; /* End of text section */ + + .data : C_PHYS(.data) { /* Data */ + *(.data) + CONSTRUCTORS + } + + _edata = .; /* End of data section */ + + . = ALIGN(INIT_TASK_SIZE); /* init_task: structure size aligned */ + .data.init_task : C_PHYS(.data.init_task) { *(.data.init_task) } + + . = ALIGN(PAGE_SIZE); /* Init code and data */ + __init_begin = .; + .text.init : C_PHYS(.text.init) { *(.text.init) } + .data.init : C_PHYS(.data.init) { *(.data.init) } + . = ALIGN(L1_CACHE_BYTES); /* Better if Cache Line aligned */ + __setup_start = .; + .setup.init : C_PHYS(.setup.init) { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : C_PHYS(.initcall.init) { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(PAGE_SIZE); + __init_end = .; + + . = ALIGN(L1_CACHE_BYTES); + .data.cacheline_aligned : C_PHYS(.data.cacheline_aligned) { *(.data.cacheline_aligned) } + + /* Align to the biggest single data representation, head and tail */ + . = ALIGN(8); + __bss_start = .; /* BSS */ + .bss : C_PHYS(.bss) { + *(.bss) + } + . = ALIGN(8); + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* Stabs debugging sections. */ + .stab 0 : C_PHYS(.stab) { *(.stab) } + .stabstr 0 : C_PHYS(.stabstr) { *(.stabstr) } + .stab.excl 0 : C_PHYS(.stab.excl) { *(.stab.excl) } + .stab.exclstr 0 : C_PHYS(.stab.exclstr) { *(.stab.exclstr) } + .stab.index 0 : C_PHYS(.stab.index) { *(.stab.index) } + .stab.indexstr 0 : C_PHYS(.stab.indexstr) { *(.stab.indexstr) } + .comment 0 : C_PHYS(.comment) { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging section are relative to the beginning + of the section so we begin .debug at 0. */ + /* DWARF 1 */ + .debug 0 : C_PHYS(.debug) { *(.debug) } + .line 0 : C_PHYS(.line) { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : C_PHYS(.debug_srcinfo) { *(.debug_srcinfo) } + .debug_sfnames 0 : C_PHYS(.debug_sfnames) { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : C_PHYS(.debug_aranges) { *(.debug_aranges) } + .debug_pubnames 0 : C_PHYS(.debug_pubnames) { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : C_PHYS(.debug_info) { *(.debug_info) } + .debug_abbrev 0 : C_PHYS(.debug_abbrev) { *(.debug_abbrev) } + .debug_line 0 : C_PHYS(.debug_line) { *(.debug_line) } + .debug_frame 0 : C_PHYS(.debug_frame) { *(.debug_frame) } + .debug_str 0 : C_PHYS(.debug_str) { *(.debug_str) } + .debug_loc 0 : C_PHYS(.debug_loc) { *(.debug_loc) } + .debug_macinfo 0 : C_PHYS(.debug_macinfo) { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : C_PHYS(.debug_weaknames) { *(.debug_weaknames) } + .debug_funcnames 0 : C_PHYS(.debug_funcnames) { *(.debug_funcnames) } + .debug_typenames 0 : C_PHYS(.debug_typenames) { *(.debug_typenames) } + .debug_varnames 0 : C_PHYS(.debug_varnames) { *(.debug_varnames) } + /* These must appear regardless of . */ +} diff -urN linux-2.4.21/arch/sparc/config.in linux-2.4.22/arch/sparc/config.in --- linux-2.4.21/arch/sparc/config.in 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -209,8 +209,8 @@ 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 + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then + dep_tristate ' PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP $CONFIG_ATM fi fi fi @@ -235,7 +235,7 @@ # if [ "$CONFIG_FDDI" = "y" ]; then # fi - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" != "n" ]; then source drivers/atm/Config.in fi fi @@ -275,4 +275,5 @@ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/sparc/kernel/signal.c linux-2.4.22/arch/sparc/kernel/signal.c --- linux-2.4.21/arch/sparc/kernel/signal.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -1131,6 +1131,8 @@ line = d_path(map->vm_file->f_dentry, map->vm_file->f_vfsmnt, buffer, PAGE_SIZE); + if (IS_ERR(line)) + break; } printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT, kdevname(dev), ino); diff -urN linux-2.4.21/arch/sparc/kernel/sys_sparc.c linux-2.4.22/arch/sparc/kernel/sys_sparc.c --- linux-2.4.21/arch/sparc/kernel/sys_sparc.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc/kernel/sys_sparc.c 2003-08-25 04:44:40.000000000 -0700 @@ -123,7 +123,10 @@ if (call <= SEMCTL) switch (call) { case SEMOP: - err = sys_semop (first, (struct sembuf *)ptr, second); + err = sys_semtimedop (first, (struct sembuf *)ptr, second, NULL); + goto out; + case SEMTIMEDOP: + err = sys_semtimedop (first, (struct sembuf *)ptr, second, (const struct timespec *) fifth); goto out; case SEMGET: err = sys_semget (first, second, third); diff -urN linux-2.4.21/arch/sparc64/boot/Makefile linux-2.4.22/arch/sparc64/boot/Makefile --- linux-2.4.21/arch/sparc64/boot/Makefile 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/boot/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -20,7 +20,7 @@ $(HOSTCC) $(HOSTCFLAGS) -o piggyback piggyback.c image: $(TOPDIR)/vmlinux - $(STRIP) -R .comment -R .note $(TOPDIR)/vmlinux -o $@ + $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start $(TOPDIR)/vmlinux -o $@ dep: diff -urN linux-2.4.21/arch/sparc64/config.in linux-2.4.22/arch/sparc64/config.in --- linux-2.4.21/arch/sparc64/config.in 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/arch/sparc64/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -234,7 +234,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in - if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then source drivers/atm/Config.in fi fi @@ -309,4 +309,5 @@ endmenu +source crypto/Config.in source lib/Config.in diff -urN linux-2.4.21/arch/sparc64/defconfig linux-2.4.22/arch/sparc64/defconfig --- linux-2.4.21/arch/sparc64/defconfig 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -104,6 +104,7 @@ CONFIG_FB_ATY_CT=y # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set @@ -179,19 +180,104 @@ CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_NETLINK_DEV=y -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set +CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y CONFIG_ARPD=y CONFIG_INET_ECN=y # CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_AMANDA=m +# CONFIG_IP_NF_NAT_LOCAL is not set +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_COMPAT_IPFWADM=m +CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IPV6=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m # CONFIG_KHTTPD is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m @@ -234,6 +320,7 @@ CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m CONFIG_NET_QOS=y CONFIG_NET_ESTIMATOR=y CONFIG_NET_CLS=y @@ -292,7 +379,7 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set CONFIG_BLK_DEV_AEC62XX=m CONFIG_BLK_DEV_ALI15X3=y # CONFIG_WDC_ALI15X3 is not set @@ -365,6 +452,10 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=5000 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_AIC79XX is not set CONFIG_SCSI_AIC7XXX_OLD=m CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8 @@ -429,6 +520,7 @@ CONFIG_IEEE1394_CMP=m CONFIG_IEEE1394_AMDTP=m # CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_OUI_DB=y # # Network device support @@ -513,6 +605,7 @@ # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m CONFIG_E1000=m +CONFIG_E1000_NAPI=y CONFIG_MYRI_SBUS=m CONFIG_NS83820=m # CONFIG_HAMACHI is not set @@ -593,6 +686,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m # CONFIG_REISERFS_FS is not set @@ -602,6 +696,7 @@ # CONFIG_ADFS_FS_RW is not set CONFIG_AFFS_FS=m # CONFIG_HFS_FS is not set +CONFIG_HFSPLUS_FS=m CONFIG_BEFS_FS=m # CONFIG_BEFS_DEBUG is not set CONFIG_BFS_FS=m @@ -651,6 +746,7 @@ CONFIG_INTERMEZZO_FS=m CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y @@ -832,6 +928,7 @@ CONFIG_USB_RTL8150=m CONFIG_USB_KAWETH=m CONFIG_USB_CATC=m +CONFIG_USB_AX8817X=m CONFIG_USB_CDCETHER=m CONFIG_USB_USBNET=m @@ -886,6 +983,7 @@ CONFIG_USB_TIGL=m # CONFIG_USB_BRLVGER is not set CONFIG_USB_LCD=m +# CONFIG_USB_SPEEDTOUCH is not set # # Bluetooth support @@ -898,11 +996,13 @@ CONFIG_BLUEZ_BNEP=m CONFIG_BLUEZ_BNEP_MC_FILTER=y CONFIG_BLUEZ_BNEP_PROTO_FILTER=y +CONFIG_BLUEZ_CMTP=m # # Bluetooth device drivers # CONFIG_BLUEZ_HCIUSB=m +CONFIG_BLUEZ_USB_SCO=y CONFIG_BLUEZ_USB_ZERO_PACKET=y CONFIG_BLUEZ_HCIUART=m CONFIG_BLUEZ_HCIUART_H4=y @@ -931,7 +1031,27 @@ # CONFIG_STACK_DEBUG is not set # +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set + +# # Library routines # +CONFIG_CRC32=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.21/arch/sparc64/kernel/head.S linux-2.4.22/arch/sparc64/kernel/head.S --- linux-2.4.21/arch/sparc64/kernel/head.S 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -66,7 +66,7 @@ sparc_ramdisk_size: .word 0 .xword reboot_command - .xword bootstr_len + .xword bootstr_info .word _end /* We must be careful, 32-bit OpenBOOT will get confused if it @@ -742,8 +742,9 @@ .data .align 8 - .globl prom_tba + .globl prom_tba, tlb_type prom_tba: .xword 0 +tlb_type: .word 0 /* Must NOT end up in BSS */ .section ".fixup",#alloc,#execinstr .globl __ret_efault __ret_efault: diff -urN linux-2.4.21/arch/sparc64/kernel/ioctl32.c linux-2.4.22/arch/sparc64/kernel/ioctl32.c --- linux-2.4.21/arch/sparc64/kernel/ioctl32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/kernel/ioctl32.c 2003-08-25 04:44:40.000000000 -0700 @@ -4313,6 +4313,11 @@ #define BNEPGETCONNLIST _IOR('B', 210, int) #define BNEPGETCONNINFO _IOR('B', 211, int) +#define CMTPCONNADD _IOW('C', 200, int) +#define CMTPCONNDEL _IOW('C', 201, int) +#define CMTPGETCONNLIST _IOR('C', 210, int) +#define CMTPGETCONNINFO _IOR('C', 211, int) + struct ioctl_trans { unsigned int cmd; unsigned int handler; @@ -4460,6 +4465,7 @@ COMPATIBLE_IOCTL(STOP_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY_RO) COMPATIBLE_IOCTL(RESTART_ARRAY_RW) +COMPATIBLE_IOCTL(RAID_AUTORUN) /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) @@ -5036,6 +5042,10 @@ COMPATIBLE_IOCTL(BNEPCONNDEL) COMPATIBLE_IOCTL(BNEPGETCONNLIST) COMPATIBLE_IOCTL(BNEPGETCONNINFO) +COMPATIBLE_IOCTL(CMTPCONNADD) +COMPATIBLE_IOCTL(CMTPCONNDEL) +COMPATIBLE_IOCTL(CMTPGETCONNLIST) +COMPATIBLE_IOCTL(CMTPGETCONNINFO) /* Scanner */ COMPATIBLE_IOCTL(SCANNER_IOCTL_VENDOR) COMPATIBLE_IOCTL(SCANNER_IOCTL_PRODUCT) diff -urN linux-2.4.21/arch/sparc64/kernel/pci.c linux-2.4.22/arch/sparc64/kernel/pci.c --- linux-2.4.21/arch/sparc64/kernel/pci.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/arch/sparc64/kernel/pci.c 2003-08-25 04:44:40.000000000 -0700 @@ -97,7 +97,7 @@ #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ sizeof(pci_controller_table[0])) -static void pci_controller_init(char *model_name, int namelen, int node) +static int pci_controller_init(char *model_name, int namelen, int node) { int i; @@ -106,43 +106,83 @@ pci_controller_table[i].model_name, namelen)) { pci_controller_table[i].init(node, model_name); - return; + return 1; } } printk("PCI: Warning unknown controller, model name [%s]\n", model_name); printk("PCI: Ignoring controller...\n"); + + return 0; } -/* Find each controller in the system, attach and initialize - * software state structure for each and link into the - * pci_controller_root. Setup the controller enough such - * that bus scanning can be done. - */ -static void pci_controller_probe(void) +static int pci_is_controller(char *model_name, int namelen, int node) +{ + int i; + + for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { + if (!strncmp(model_name, + pci_controller_table[i].model_name, + namelen)) { + return 1; + } + } + return 0; +} + + +static int pci_controller_scan(int (*handler)(char *, int, int)) { - char namebuf[16]; + char namebuf[64]; int node; + int count = 0; - printk("PCI: Probing for controllers.\n"); node = prom_getchild(prom_root_node); while ((node = prom_searchsiblings(node, "pci")) != 0) { int len; - len = prom_getproperty(node, "model", - namebuf, sizeof(namebuf)); - if (len > 0) - pci_controller_init(namebuf, len, node); - else { - len = prom_getproperty(node, "compatible", - namebuf, sizeof(namebuf)); - if (len > 0) - pci_controller_init(namebuf, len, node); + if ((len = prom_getproperty(node, "model", namebuf, sizeof(namebuf))) > 0 || + (len = prom_getproperty(node, "compatible", namebuf, sizeof(namebuf))) > 0) { + int item_len = 0; + + /* Our value may be a multi-valued string in the + * case of some compatible properties. For sanity, + * only try the first one. */ + + while (namebuf[item_len] && len) { + len--; + item_len++; + } + + if (handler(namebuf, item_len, node)) + count++; } + node = prom_getsibling(node); if (!node) break; } + + return count; +} + + +/* Is there some PCI controller in the system? */ +int pcic_present(void) +{ + return pci_controller_scan(pci_is_controller); +} + +/* Find each controller in the system, attach and initialize + * software state structure for each and link into the + * pci_controller_root. Setup the controller enough such + * that bus scanning can be done. + */ +static void pci_controller_probe(void) +{ + printk("PCI: Probing for controllers.\n"); + + pci_controller_scan(pci_controller_init); } static void pci_scan_each_controller_bus(void) diff -urN linux-2.4.21/arch/sparc64/kernel/pci_sabre.c linux-2.4.22/arch/sparc64/kernel/pci_sabre.c --- linux-2.4.21/arch/sparc64/kernel/pci_sabre.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/sparc64/kernel/pci_sabre.c 2003-08-25 04:44:40.000000000 -0700 @@ -1543,6 +1543,7 @@ u32 busrange[2]; u32 vdma[2]; u32 upa_portid, dma_mask; + u64 clear_irq; int bus; hummingbird_p = 0; @@ -1619,6 +1620,16 @@ printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n", p->controller_regs, pci_dma_wsync); + /* Clear interrupts */ + + /* PCI first */ + for (clear_irq = SABRE_ICLR_A_SLOT0; clear_irq < SABRE_ICLR_B_SLOT0 + 0x80; clear_irq += 8) + sabre_write(p->controller_regs + clear_irq, 0x0UL); + + /* Then OBIO */ + for (clear_irq = SABRE_ICLR_SCSI; clear_irq < SABRE_ICLR_SCSI + 0x80; clear_irq += 8) + sabre_write(p->controller_regs + clear_irq, 0x0UL); + /* Error interrupts are enabled later after the bus scan. */ sabre_write(p->controller_regs + SABRE_PCICTRL, (SABRE_PCICTRL_MRLEN | SABRE_PCICTRL_SERR | diff -urN linux-2.4.21/arch/sparc64/kernel/signal.c linux-2.4.22/arch/sparc64/kernel/signal.c --- linux-2.4.21/arch/sparc64/kernel/signal.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 @@ -679,6 +679,8 @@ line = d_path(map->vm_file->f_dentry, map->vm_file->f_vfsmnt, buffer, PAGE_SIZE); + if (IS_ERR(line)) + break; } printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT, kdevname(dev), ino); diff -urN linux-2.4.21/arch/sparc64/kernel/signal32.c linux-2.4.22/arch/sparc64/kernel/signal32.c --- linux-2.4.21/arch/sparc64/kernel/signal32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/kernel/signal32.c 2003-08-25 04:44:40.000000000 -0700 @@ -1348,6 +1348,8 @@ line = d_path(map->vm_file->f_dentry, map->vm_file->f_vfsmnt, buffer, PAGE_SIZE); + if (IS_ERR(line)) + break; } printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT, kdevname(dev), ino); diff -urN linux-2.4.21/arch/sparc64/kernel/sys_sparc.c linux-2.4.22/arch/sparc64/kernel/sys_sparc.c --- linux-2.4.21/arch/sparc64/kernel/sys_sparc.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/kernel/sys_sparc.c 2003-08-25 04:44:40.000000000 -0700 @@ -182,7 +182,10 @@ if (call <= SEMCTL) switch (call) { case SEMOP: - err = sys_semop (first, (struct sembuf *)ptr, second); + err = sys_semtimedop (first, (struct sembuf *)ptr, second, NULL); + goto out; + case SEMTIMEDOP: + err = sys_semtimedop (first, (struct sembuf *)ptr, second, (const struct timespec *) fifth); goto out; case SEMGET: err = sys_semget (first, second, (int)third); @@ -223,9 +226,15 @@ } if (call <= SHMCTL) switch (call) { - case SHMAT: - err = sys_shmat (first, (char *) ptr, second, (ulong *) third); + case SHMAT: { + ulong raddr; + err = sys_shmat (first, (char *) ptr, second, &raddr); + if (!err) { + if (put_user(raddr, (ulong *) third)) + err = -EFAULT; + } goto out; + } case SHMDT: err = sys_shmdt ((char *)ptr); goto out; diff -urN linux-2.4.21/arch/sparc64/kernel/sys_sparc32.c linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c --- linux-2.4.21/arch/sparc64/kernel/sys_sparc32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c 2003-08-25 04:44:40.000000000 -0700 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -506,7 +507,7 @@ static int do_sys32_msgsnd (int first, int second, int third, void *uptr) { - struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); + struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_USER); struct msgbuf32 *up = (struct msgbuf32 *)uptr; mm_segment_t old_fs; int err; @@ -548,12 +549,12 @@ msgtyp = ipck.msgtyp; } err = -ENOMEM; - p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); + p = kmalloc (second + sizeof (struct msgbuf), GFP_USER); if (!p) goto out; old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_msgrcv (first, p, second + 4, msgtyp, third); + err = sys_msgrcv (first, p, second, msgtyp, third); set_fs (old_fs); if (err < 0) goto free_then_out; @@ -762,6 +763,38 @@ return err; } +static __inline__ void *alloc_user_space(long len) +{ + struct pt_regs *regs = current->thread.kregs; + unsigned long usp = regs->u_regs[UREG_I6]; + + if (!(current->thread.flags & SPARC_FLAG_32BIT)) + usp += STACK_BIAS; + + return (void *) (usp - len); +} + +struct timespec32 { + s32 tv_sec; + s32 tv_nsec; +}; + +static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems, + const struct timespec32 *timeout32) +{ + struct timespec32 t32; + struct timespec *t64 = alloc_user_space(sizeof(*t64)); + + if (copy_from_user(&t32, timeout32, sizeof(t32))) + return -EFAULT; + + if (put_user(t32.tv_sec, &t64->tv_sec) || + put_user(t32.tv_nsec, &t64->tv_nsec)) + return -EFAULT; + + return sys_semtimedop(semid, tsems, nsems, t64); +} + asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { int version, err; @@ -773,8 +806,10 @@ switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semop (first, (struct sembuf *)AA(ptr), second); + err = sys_semtimedop (first, (struct sembuf *)AA(ptr), second, NULL); goto out; + case SEMTIMEDOP: + err = sys32_semtimedop (first, (struct sembuf *)AA(ptr), second, (const struct timespec32 *) AA(fifth)); case SEMGET: err = sys_semget (first, second, third); goto out; @@ -889,7 +924,7 @@ return sys32_fcntl(fd, cmd, arg); } -struct dqblk32 { +struct user_dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; @@ -902,44 +937,42 @@ extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr); -asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr) +asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr) { int cmds = cmd >> SUBCMDSHIFT; int err; - struct dqblk d; + struct v1c_mem_dqblk d; mm_segment_t old_fs; char *spec; switch (cmds) { - case Q_GETQUOTA: + case Q_V1_GETQUOTA: break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, (struct dqblk32 *)addr, - sizeof (struct dqblk32))) + case Q_V1_SETQUOTA: + case Q_V1_SETUSE: + case Q_V1_SETQLIM: + if (copy_from_user(&d, addr, sizeof(struct user_dqblk32))) return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; + d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime; break; default: - return sys_quotactl(cmd, special, - id, (caddr_t)addr); + return sys_quotactl(cmd, special, id, addr); } - spec = getname (special); + spec = getname(special); err = PTR_ERR(spec); - if (IS_ERR(spec)) return err; - old_fs = get_fs (); + 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); set_fs (old_fs); putname (spec); - if (cmds == Q_GETQUOTA) { + if (cmds == Q_V1_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 user_dqblk32 *)&d)->dqb_itime = i; + ((struct user_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user(addr, &d, sizeof(struct user_dqblk32))) return -EFAULT; } return err; @@ -1891,7 +1924,11 @@ u32 totalswap; u32 freeswap; unsigned short procs; - char _f[22]; + unsigned short pad; + u32 totalhigh; + u32 freehigh; + u32 mem_unit; + char _f[20-2*sizeof(int)-sizeof(int)]; }; extern asmlinkage int sys_sysinfo(struct sysinfo *info); @@ -1900,11 +1937,30 @@ { struct sysinfo s; int ret, err; + int bitcount = 0; mm_segment_t old_fs = get_fs (); - set_fs (KERNEL_DS); + set_fs(KERNEL_DS); ret = sys_sysinfo(&s); - set_fs (old_fs); + set_fs(old_fs); + /* Check to see if any memory value is too large for 32-bit and + * scale down if needed. + */ + if ((s.totalram >> 32) || (s.totalswap >> 32)) { + while (s.mem_unit < PAGE_SIZE) { + s.mem_unit <<= 1; + bitcount++; + } + s.totalram >>= bitcount; + s.freeram >>= bitcount; + s.sharedram >>= bitcount; + s.bufferram >>= bitcount; + s.totalswap >>= bitcount; + s.freeswap >>= bitcount; + s.totalhigh >>= bitcount; + s.freehigh >>= bitcount; + } + err = put_user (s.uptime, &info->uptime); err |= __put_user (s.loads[0], &info->loads[0]); err |= __put_user (s.loads[1], &info->loads[1]); @@ -1916,16 +1972,14 @@ err |= __put_user (s.totalswap, &info->totalswap); err |= __put_user (s.freeswap, &info->freeswap); err |= __put_user (s.procs, &info->procs); + err |= __put_user (s.totalhigh, &info->totalhigh); + err |= __put_user (s.freehigh, &info->freehigh); + err |= __put_user (s.mem_unit, &info->mem_unit); if (err) return -EFAULT; return ret; } -struct timespec32 { - s32 tv_sec; - s32 tv_nsec; -}; - extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval); asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval) @@ -2102,13 +2156,6 @@ spin_lock_irq(¤t->sigmask_lock); sig = dequeue_signal(&these, &info); if (!sig) { - /* None ready -- temporarily unblock those we're interested - in so that we'll be awakened when they arrive. */ - sigset_t oldblocked = current->blocked; - sigandsets(¤t->blocked, ¤t->blocked, &these); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - timeout = MAX_SCHEDULE_TIMEOUT; if (uts) timeout = (timespec_to_jiffies(&ts) @@ -2117,10 +2164,23 @@ current->state = TASK_INTERRUPTIBLE; timeout = schedule_timeout(timeout); - spin_lock_irq(¤t->sigmask_lock); - sig = dequeue_signal(&these, &info); - current->blocked = oldblocked; - recalc_sigpending(current); + if (timeout) { + /* None ready -- temporarily unblock those we're + * interested while we are sleeping in so that we'll + * be awakened when they arrive. */ + sigset_t oldblocked = current->blocked; + sigandsets(¤t->blocked, ¤t->blocked, &these); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + current->state = TASK_INTERRUPTIBLE; + timeout = schedule_timeout(timeout); + + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&these, &info); + current->blocked = oldblocked; + recalc_sigpending(current); + } } spin_unlock_irq(¤t->sigmask_lock); @@ -2911,33 +2971,6 @@ return ret; } -static int do_set_icmpv6_filter(int fd, int level, int optname, - char *optval, int optlen) -{ - struct icmp6_filter kfilter; - mm_segment_t old_fs; - int ret, i; - - if (copy_from_user(&kfilter, optval, sizeof(kfilter))) - return -EFAULT; - - - for (i = 0; i < 8; i += 2) { - u32 tmp = kfilter.data[i]; - - kfilter.data[i] = kfilter.data[i + 1]; - kfilter.data[i + 1] = tmp; - } - - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_setsockopt(fd, level, optname, - (char *) &kfilter, sizeof(kfilter)); - set_fs(old_fs); - - return ret; -} - static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int optlen) { struct timeval32 *up = (struct timeval32 *) optval; @@ -2969,9 +3002,6 @@ optval, optlen); if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) return do_set_sock_timeout(fd, level, optname, optval, optlen); - if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER) - return do_set_icmpv6_filter(fd, level, optname, - optval, optlen); return sys_setsockopt(fd, level, optname, optval, optlen); } diff -urN linux-2.4.21/arch/sparc64/mm/init.c linux-2.4.22/arch/sparc64/mm/init.c --- linux-2.4.21/arch/sparc64/mm/init.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/arch/sparc64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -46,8 +46,6 @@ /* Ugly, but necessary... -DaveM */ unsigned long phys_base; -enum ultra_tlb_layout tlb_type = spitfire; - /* get_new_mmu_context() uses "cache + 1". */ spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED; unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; diff -urN linux-2.4.21/arch/sparc64/prom/bootstr.c linux-2.4.22/arch/sparc64/prom/bootstr.c --- linux-2.4.21/arch/sparc64/prom/bootstr.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/arch/sparc64/prom/bootstr.c 2003-08-25 04:44:40.000000000 -0700 @@ -15,16 +15,22 @@ */ #define BARG_LEN 256 -int bootstr_len = BARG_LEN; -static int bootstr_valid = 0; -static char bootstr_buf[BARG_LEN] = { 0 }; +struct { + int bootstr_len; + int bootstr_valid; + char bootstr_buf[BARG_LEN]; +} bootstr_info = { + .bootstr_len = BARG_LEN, +}; char * __init prom_getbootargs(void) { /* This check saves us from a panic when bootfd patches args. */ - if (bootstr_valid) return bootstr_buf; - prom_getstring(prom_chosen_node, "bootargs", bootstr_buf, BARG_LEN); - bootstr_valid = 1; - return bootstr_buf; + if (bootstr_info.bootstr_valid) + return bootstr_info.bootstr_buf; + prom_getstring(prom_chosen_node, "bootargs", + bootstr_info.bootstr_buf, BARG_LEN); + bootstr_info.bootstr_valid = 1; + return bootstr_info.bootstr_buf; } diff -urN linux-2.4.21/arch/sparc64/prom/init.c linux-2.4.22/arch/sparc64/prom/init.c --- linux-2.4.21/arch/sparc64/prom/init.c 1999-12-20 22:05:52.000000000 -0800 +++ linux-2.4.22/arch/sparc64/prom/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -36,6 +36,7 @@ int ints[3]; int node; int i = 0; + int bufadjust; prom_vers = PROM_P1275; @@ -63,9 +64,19 @@ if (strncmp (buffer, "OBP ", 4)) goto strange_version; - /* Version field is expected to be 'OBP xx.yy.zz date...' */ + /* + * Version field is expected to be 'OBP xx.yy.zz date...' + * However, Sun can't stick to this format very well, so + * we need to check for 'OBP xx.yy.zz date...' and adjust + * accordingly. -spot + */ + + if (strncmp (buffer, "OBP ", 5)) + bufadjust = 4; + else + bufadjust = 5; - p = buffer + 4; + p = buffer + bufadjust; while (p && isdigit(*p) && i < 3) { ints[i++] = simple_strtoul(p, NULL, 0); if ((p = strchr(p, '.')) != NULL) @@ -77,7 +88,7 @@ prom_rev = ints[1]; prom_prev = (ints[0] << 16) | (ints[1] << 8) | ints[2]; - printk ("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + 4); + printk ("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust); prom_meminit(); diff -urN linux-2.4.21/arch/x86_64/Makefile linux-2.4.22/arch/x86_64/Makefile --- linux-2.4.21/arch/x86_64/Makefile 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -19,7 +19,7 @@ # 20010105 Andi Kleen, add IA32 compiler. # ....and later removed it again.... # -# $Id: Makefile,v 1.32 2003/03/03 16:06:43 ak Exp $ +# $Id: Makefile,v 1.33 2003/05/12 14:36:34 ak Exp $ # # early bootup linking needs 32bit. You can either use real 32bit tools @@ -46,6 +46,7 @@ CFLAGS += -finline-limit=2000 # needed for earlier gcc 3.1 CFLAGS += -fno-strength-reduce +CFLAGS += -Wno-sign-compare #CFLAGS += -g ifneq ($(CONFIG_X86_REMOTE_DEBUG),y) CFLAGS += -fno-asynchronous-unwind-tables diff -urN linux-2.4.21/arch/x86_64/boot/setup.S linux-2.4.22/arch/x86_64/boot/setup.S --- linux-2.4.21/arch/x86_64/boot/setup.S 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/boot/setup.S 2003-08-25 04:44:40.000000000 -0700 @@ -347,6 +347,11 @@ sse_ok: popw %ds +# tell BIOS we want to go to long mode + movl $0xec00,%eax # declare target operating mode + movl $2,%ebx # long mode + int $0x15 + # Get memory size (extended mem, kB) xorl %eax, %eax diff -urN linux-2.4.21/arch/x86_64/config.in linux-2.4.22/arch/x86_64/config.in --- linux-2.4.21/arch/x86_64/config.in 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/config.in 2003-08-25 04:44:40.000000000 -0700 @@ -112,12 +112,7 @@ bool 'IA32 Emulation' CONFIG_IA32_EMULATION -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_bool ' ACPI support' CONFIG_ACPI $CONFIG_PM - if [ "$CONFIG_ACPI" != "n" ]; then - source drivers/acpi/Config.in - fi -fi +source drivers/acpi/Config.in endmenu @@ -173,7 +168,7 @@ if [ "$CONFIG_NETDEVICES" = "y" ]; then source drivers/net/Config.in # seems to be largely not 64bit safe -# if [ "$CONFIG_ATM" = "y" ]; then +# if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then # source drivers/atm/Config.in # fi fi @@ -232,6 +227,8 @@ source net/bluetooth/Config.in +source crypto/Config.in + mainmenu_option next_comment comment 'Kernel hacking' diff -urN linux-2.4.21/arch/x86_64/defconfig linux-2.4.22/arch/x86_64/defconfig --- linux-2.4.21/arch/x86_64/defconfig 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/defconfig 2003-08-25 04:44:40.000000000 -0700 @@ -65,16 +65,29 @@ # CONFIG_BINFMT_MISC is not set CONFIG_PM=y CONFIG_IA32_EMULATION=y + +# +# ACPI Support +# CONFIG_ACPI=y -CONFIG_ACPI_DEBUG=y -CONFIG_ACPI_BUSMGR=y -CONFIG_ACPI_SYS=y -CONFIG_ACPI_CPU=y -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_AC=y +# CONFIG_ACPI_HT_ONLY is not set +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_BUS=y +CONFIG_ACPI_INTERPRETER=y CONFIG_ACPI_EC=y -CONFIG_ACPI_CMBATT=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_ASUS is not set +# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_DEBUG=y # # Memory Technology Devices (MTD) @@ -218,7 +231,7 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set @@ -232,13 +245,11 @@ # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_PDC202XX_FORCE is not set # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set @@ -295,8 +306,10 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set @@ -324,10 +337,13 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SEAGATE is not set +# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set @@ -582,7 +598,6 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set -CONFIG_SIMICSFS=y # # Network File Systems @@ -703,5 +718,6 @@ # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21/arch/x86_64/ia32/ia32_binfmt.c linux-2.4.22/arch/x86_64/ia32/ia32_binfmt.c --- linux-2.4.21/arch/x86_64/ia32/ia32_binfmt.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/ia32/ia32_binfmt.c 2003-08-25 04:44:40.000000000 -0700 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,7 @@ #define ELF_NAME "elf/i386" -#define IA32_PAGE_OFFSET 0xFFFFe000 +#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) #define IA32_STACK_TOP IA32_PAGE_OFFSET #define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) @@ -243,8 +244,9 @@ mpnt->vm_mm = current->mm; mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p; mpnt->vm_end = IA32_STACK_TOP; - mpnt->vm_page_prot = PAGE_COPY_EXEC; - mpnt->vm_flags = VM_STACK_FLAGS; + mpnt->vm_flags = vm_stack_flags32; + mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? + PAGE_COPY_EXEC : PAGE_COPY; mpnt->vm_ops = NULL; mpnt->vm_pgoff = 0; mpnt->vm_file = NULL; diff -urN linux-2.4.21/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c --- linux-2.4.21/arch/x86_64/ia32/ia32_ioctl.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c 2003-08-25 04:44:40.000000000 -0700 @@ -3488,7 +3488,7 @@ }; #define REF_SYMBOL(handler) if (0) (void)handler; -#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler); asm volatile(".quad %P0, " #handler ",0"::"i" (cmd)); +#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler); asm volatile(".quad %P0, " #handler ",0"::"n" (cmd)); #define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler) #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl) #define IOCTL_TABLE_START void ioctl_dummy(void) { asm volatile("\nioctl_start:\n\t" ); @@ -4555,7 +4555,7 @@ "cmd(%08x){%s} arg(%08x) on %s\n", current->comm, current->pid, (int)fd, (unsigned int)cmd, buf, (unsigned int)arg, - fn); + IS_ERR(fn) ? "???" : fn); if (path) free_page((unsigned long)path); } diff -urN linux-2.4.21/arch/x86_64/ia32/sys_ia32.c linux-2.4.22/arch/x86_64/ia32/sys_ia32.c --- linux-2.4.21/arch/x86_64/ia32/sys_ia32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/ia32/sys_ia32.c 2003-08-25 04:44:40.000000000 -0700 @@ -16,7 +16,7 @@ * * This file assumes that there is a hole at the end of user address space. * - * $Id: sys_ia32.c,v 1.54 2003/03/24 09:28:26 ak Exp $ + * $Id: sys_ia32.c,v 1.58 2003/05/09 17:21:17 ak Exp $ */ #include @@ -845,6 +845,7 @@ ret = -EINVAL; if (n < 0) goto out_nofds; + size = FDS_BYTES(n); if (n > current->files->max_fdset) n = current->files->max_fdset; @@ -855,7 +856,6 @@ * long-words. */ ret = -ENOMEM; - size = FDS_BYTES(n); bits = kmalloc(6 * size, GFP_KERNEL); if (!bits) goto out_nofds; @@ -1062,8 +1062,8 @@ #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) struct rlimit32 { - int rlim_cur; - int rlim_max; + unsigned rlim_cur; + unsigned rlim_max; }; extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim); @@ -1080,6 +1080,10 @@ ret = sys_getrlimit(resource, &r); set_fs(old_fs); if (!ret) { + if (r.rlim_cur >= 0xffffffff) + r.rlim_cur = RLIM_INFINITY32; + if (r.rlim_max >= 0xffffffff) + r.rlim_max = RLIM_INFINITY32; if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) || __put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur) || __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max)) @@ -1099,9 +1103,13 @@ old_fs = get_fs(); set_fs(KERNEL_DS); - ret = sys_old_getrlimit(resource, &r); + ret = sys_getrlimit(resource, &r); set_fs(old_fs); if (!ret) { + if (r.rlim_cur >= 0x7fffffff) + r.rlim_cur = RLIM_INFINITY32; + if (r.rlim_max >= 0x7fffffff) + r.rlim_max = RLIM_INFINITY32; if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) || __put_user(r.rlim_cur, &rlim->rlim_cur) || __put_user(r.rlim_max, &rlim->rlim_max)) @@ -1494,7 +1502,11 @@ u32 totalswap; u32 freeswap; unsigned short procs; - char _f[22]; + unsigned short pad; + u32 totalhigh; + u32 freehigh; + u32 mem_unit; + char _f[20-2*sizeof(u32)-sizeof(int)]; }; extern asmlinkage long sys_sysinfo(struct sysinfo *info); @@ -1520,7 +1532,10 @@ __put_user (s.bufferram, &info->bufferram) || __put_user (s.totalswap, &info->totalswap) || __put_user (s.freeswap, &info->freeswap) || - __put_user (s.procs, &info->procs)) + __put_user (s.procs, &info->procs) || + __put_user (s.totalhigh, &info->totalhigh) || + __put_user (s.freehigh, &info->freehigh) || + __put_user (s.mem_unit, &info->mem_unit)) return -EFAULT; return 0; } @@ -2550,7 +2565,7 @@ static int __init ia32_init (void) { - printk("IA32 emulation $Id: sys_ia32.c,v 1.54 2003/03/24 09:28:26 ak Exp $\n"); + printk("IA32 emulation $Id: sys_ia32.c,v 1.58 2003/05/09 17:21:17 ak Exp $\n"); ia32_exec_domain.signal_map = default_exec_domain.signal_map; ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; register_exec_domain(&ia32_exec_domain); diff -urN linux-2.4.21/arch/x86_64/kernel/Makefile linux-2.4.22/arch/x86_64/kernel/Makefile --- linux-2.4.21/arch/x86_64/kernel/Makefile 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/arch/x86_64/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -15,12 +15,12 @@ O_TARGET := kernel.o -export-objs := mtrr.o msr.o cpuid.o x8664_ksyms.o pci-gart.o +export-objs := mtrr.o msr.o cpuid.o x8664_ksyms.o pci-gart.o setup.o obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \ pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \ - setup64.o acpitable.o e820.o + setup64.o e820.o warmreboot.o ifdef CONFIG_PCI obj-y += pci-x86_64.o @@ -37,6 +37,9 @@ obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o obj-$(CONFIG_MCE) += bluesmoke.o +obj-$(CONFIG_ACPI) += acpi.o +obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o suspend.o + include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/arch/x86_64/kernel/acpi.c linux-2.4.22/arch/x86_64/kernel/acpi.c --- linux-2.4.21/arch/x86_64/kernel/acpi.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/x86_64/kernel/acpi.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,536 @@ +/* + * acpi.c - Architecture-Specific Low-Level ACPI Support + * + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2001 Jun Nakajima + * Copyright (C) 2001 Patrick Mochel + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PREFIX "ACPI: " + + +/* -------------------------------------------------------------------------- + Boot-time Configuration + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_BOOT + +enum acpi_irq_model_id acpi_irq_model; + + +/* + * Use reserved fixmap pages for physical-to-virtual mappings of ACPI tables. + * Note that the same range is used for each table, so tables that need to + * persist should be memcpy'd. + */ + +extern unsigned long end_pfn; + +char * +__acpi_map_table ( + unsigned long phys_addr, + unsigned long size) +{ +#if 0 + unsigned long base = 0; + unsigned long mapped_phys = phys_addr; + unsigned long offset = phys_addr & (PAGE_SIZE - 1); + unsigned long mapped_size = PAGE_SIZE - offset; + unsigned long avail_size = mapped_size + (PAGE_SIZE * FIX_ACPI_PAGES); + int idx = FIX_ACPI_BEGIN; +#endif + + //printk("__acpi_map_table at %lx size %lu\n", phys_addr, size); + + if (!phys_addr || !size) + return NULL; + + if (phys_addr < (end_pfn_map << PAGE_SHIFT)) + return __va(phys_addr); + + panic("acpi mapping beyond end_pfn: %lx > %lx\n", phys_addr, end_pfn_map< avail_size) + return NULL; + + /* If the table doesn't map completely into the fist page... */ + if (size > mapped_size) { + do { + /* Make sure we don't go past our range */ + if (idx++ == FIX_ACPI_END) + return NULL; + mapped_phys = mapped_phys + PAGE_SIZE; + set_fixmap(idx, mapped_phys); + mapped_size = mapped_size + PAGE_SIZE; + } while (mapped_size < size); + } + + return ((unsigned char *) base + offset); +#endif +} + + +#ifdef CONFIG_X86_LOCAL_APIC + +int acpi_lapic; + +static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; + + +static int __init +acpi_parse_madt ( + unsigned long phys_addr, + unsigned long size) +{ + struct acpi_table_madt *madt = NULL; + + if (!phys_addr || !size) + return -EINVAL; + + madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); + if (!madt) { + printk(KERN_WARNING PREFIX "Unable to map MADT\n"); + return -ENODEV; + } + + if (madt->lapic_address) + acpi_lapic_addr = (u64) madt->lapic_address; + + printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", + madt->lapic_address); + + return 0; +} + + +static int __init +acpi_parse_lapic ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic *processor = NULL; + + processor = (struct acpi_table_lapic*) header; + if (!processor) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_register_lapic ( + processor->id, /* APIC ID */ + processor->flags.enabled); /* Enabled? */ + + return 0; +} + + +static int __init +acpi_parse_lapic_addr_ovr ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; + + lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; + if (!lapic_addr_ovr) + return -EINVAL; + + acpi_lapic_addr = lapic_addr_ovr->address; + + return 0; +} + + +static int __init +acpi_parse_lapic_nmi ( + acpi_table_entry_header *header) +{ + struct acpi_table_lapic_nmi *lapic_nmi = NULL; + + lapic_nmi = (struct acpi_table_lapic_nmi*) header; + if (!lapic_nmi) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + if (lapic_nmi->lint != 1) + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); + + return 0; +} + +#endif /*CONFIG_X86_LOCAL_APIC*/ + +#ifdef CONFIG_X86_IO_APIC + +int acpi_ioapic; + +static int __init +acpi_parse_ioapic ( + acpi_table_entry_header *header) +{ + struct acpi_table_ioapic *ioapic = NULL; + + ioapic = (struct acpi_table_ioapic*) header; + if (!ioapic) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_register_ioapic ( + ioapic->id, + ioapic->address, + ioapic->global_irq_base); + + return 0; +} + + +static int __init +acpi_parse_int_src_ovr ( + acpi_table_entry_header *header) +{ + struct acpi_table_int_src_ovr *intsrc = NULL; + + intsrc = (struct acpi_table_int_src_ovr*) header; + if (!intsrc) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + mp_override_legacy_irq ( + intsrc->bus_irq, + intsrc->flags.polarity, + intsrc->flags.trigger, + intsrc->global_irq); + + return 0; +} + + +static int __init +acpi_parse_nmi_src ( + acpi_table_entry_header *header) +{ + struct acpi_table_nmi_src *nmi_src = NULL; + + nmi_src = (struct acpi_table_nmi_src*) header; + if (!nmi_src) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + /* TBD: Support nimsrc entries? */ + + return 0; +} + +#endif /*CONFIG_X86_IO_APIC*/ + +static int __init +acpi_parse_hpet ( + unsigned long phys_addr, + unsigned long size) +{ + struct acpi_table_hpet *hpet_tbl; + + hpet_tbl = __va(phys_addr); + + if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { + printk(KERN_WARNING "acpi: HPET timers must be located in memory.\n"); + return -1; + } + + hpet_address = hpet_tbl->addr.addrl | ((long) hpet_tbl->addr.addrh << 32); + + printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address); + + return 0; +} + +static unsigned long __init +acpi_scan_rsdp ( + unsigned long start, + unsigned long length) +{ + unsigned long offset = 0; + unsigned long sig_len = sizeof("RSD PTR ") - 1; + + /* + * Scan all 16-byte boundaries of the physical memory region for the + * RSDP signature. + */ + for (offset = 0; offset < length; offset += 16) { + if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) + continue; + return (start + offset); + } + + return 0; +} + + +unsigned long __init +acpi_find_rsdp (void) +{ + unsigned long rsdp_phys = 0; + + /* + * Scan memory looking for the RSDP signature. First search EBDA (low + * memory) paragraphs and then search upper memory (E0000-FFFFF). + */ + rsdp_phys = acpi_scan_rsdp (0, 0x400); + if (!rsdp_phys) + rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); + + return rsdp_phys; +} + + +int __init +acpi_boot_init (void) + +{ + int result = 0; + + /* + * The default interrupt routing model is PIC (8259). This gets + * overriden if IOAPICs are enumerated (below). + */ + acpi_irq_model = ACPI_IRQ_MODEL_PIC; + + /* + * Initialize the ACPI boot-time table parser. + */ + result = acpi_table_init(); + if (result) + return result; + +#ifdef CONFIG_X86_LOCAL_APIC + + /* + * MADT + * ---- + * Parse the Multiple APIC Description Table (MADT), if exists. + * Note that this table provides platform SMP configuration + * information -- the successor to MPS tables. + */ + + result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); + if (!result) { + printk(KERN_WARNING PREFIX "MADT not present\n"); + return 0; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing MADT\n"); + return result; + } + else if (result > 1) + printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); + + /* + * Local APIC + * ---------- + * Note that the LAPIC address is obtained from the MADT (32-bit value) + * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). + */ + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); + return result; + } + + mp_register_lapic_address(acpi_lapic_addr); + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic); + if (!result) { + printk(KERN_ERR PREFIX "No LAPIC entries present\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return -ENODEV; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + acpi_lapic = 1; + +#endif /*CONFIG_X86_LOCAL_APIC*/ + +#ifdef CONFIG_X86_IO_APIC + + /* + * I/O APIC + * -------- + */ + + result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic); + if (!result) { + printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); + return -ENODEV; + } + else if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); + return result; + } + + /* Build a default routing table for legacy (ISA) interrupts. */ + mp_config_acpi_legacy_irqs(); + + result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src); + if (result < 0) { + printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return result; + } + + acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; + + acpi_ioapic = 1; + +#endif /*CONFIG_X86_IO_APIC*/ + +#ifdef CONFIG_X86_LOCAL_APIC + if (acpi_lapic && acpi_ioapic) + smp_found_config = 1; +#endif + result = acpi_table_parse(ACPI_HPET, acpi_parse_hpet); + if (result < 0) + printk("ACPI: no HPET table found (%d).\n", result); + + return 0; +} + +#endif /*CONFIG_ACPI_BOOT*/ + + +/* -------------------------------------------------------------------------- + Low-Level Sleep Support + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_SLEEP + +/* address in low memory of the wakeup routine. */ +unsigned long acpi_wakeup_address = 0; +extern char wakeup_start, wakeup_end; + +extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); + +static void init_low_mapping(void) +{ + cpu_pda[0].level4_pgt[0] = cpu_pda[0].level4_pgt[pml4_index(PAGE_OFFSET)]; + flush_tlb_all(); +} + +/** + * acpi_save_state_mem - save kernel state + * + * Create an identity mapped page table and copy the wakeup routine to + * low memory. + */ +int acpi_save_state_mem (void) +{ + init_low_mapping(); + + memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); + acpi_copy_wakeup_routine(acpi_wakeup_address); + + return 0; +} + +/** + * acpi_save_state_disk - save kernel state to disk + * + */ +int acpi_save_state_disk (void) +{ + return 1; +} + +/* + * acpi_restore_state + */ +void acpi_restore_state_mem (void) +{ + cpu_pda[0].level4_pgt[0] = 0; + flush_tlb_all(); +} + +/** + * acpi_reserve_bootmem - do _very_ early ACPI initialisation + * + * We allocate a page in low memory for the wakeup + * routine for when we come back from a sleep state. The + * runtime allocator allows specification of <16M pages, but not + * <1M pages. + */ +void __init acpi_reserve_bootmem(void) +{ + acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); + if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) + printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); + printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); +} + +#endif /*CONFIG_ACPI_SLEEP*/ + + diff -urN linux-2.4.21/arch/x86_64/kernel/acpi_wakeup.S linux-2.4.22/arch/x86_64/kernel/acpi_wakeup.S --- linux-2.4.21/arch/x86_64/kernel/acpi_wakeup.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/x86_64/kernel/acpi_wakeup.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,515 @@ +.text +#include +#include +#include +#include + +# Copyright 2003 Pavel Machek , distribute under GPLv2 +# +# wakeup_code runs in real mode, and at unknown address (determined at run-time). +# Therefore it must only use relative jumps/calls. +# +# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled +# +# If physical address of wakeup_code is 0x12345, BIOS should call us with +# cs = 0x1234, eip = 0x05 +# + + +ALIGN + .align 16 +ENTRY(wakeup_start) +wakeup_code: + wakeup_code_start = . + .code16 + +# Running in *copy* of this code, somewhere in low 1MB. + + movb $0xa1, %al ; outb %al, $0x80 + cli + cld + # setup data segment + movw %cs, %ax + movw %ax, %ds # Make ds:0 point to wakeup_start + movw %ax, %ss + mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board + + pushl $0 # Kill any dangerous flags + popfl + + movl real_magic - wakeup_code, %eax + cmpl $0x12345678, %eax + jne bogus_real_magic + + lcall $0xc000,$3 + + movw $0xb800, %ax + movw %ax,%fs + movw $0x0e00 + 'L', %fs:(0x10) + + movb $0xa2, %al ; outb %al, $0x80 + + lidt %ds:idt_48a - wakeup_code + xorl %eax, %eax + movw %ds, %ax # (Convert %ds:gdt to a linear ptr) + shll $4, %eax + addl $(gdta - wakeup_code), %eax + movl %eax, gdt_48a +2 - wakeup_code + lgdt %ds:gdt_48a - wakeup_code # load gdt with whatever is + # appropriate + + movl $1, %eax # protected mode (PE) bit + lmsw %ax # This is it! + jmp 1f +1: + + .byte 0x66, 0xea # prefix + jmpi-opcode + .long wakeup_32 - __START_KERNEL_map + .word __KERNEL_CS + + .code32 +wakeup_32: +# Running in this code, but at low address; paging is not yet turned on. + movb $0xa5, %al ; outb %al, $0x80 + + /* Check if extended functions are implemented */ + movl $0x80000000, %eax + cpuid + cmpl $0x80000000, %eax + jbe bogus_cpu + wbinvd + mov $0x80000001, %eax + cpuid + btl $29, %edx + jnc bogus_cpu + movl %edx,%edi + + movw $__KERNEL_DS, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + movw $__KERNEL_DS, %ax + movw %ax, %ss + + mov $(wakeup_stack - __START_KERNEL_map), %esp + movl saved_magic - __START_KERNEL_map, %eax + cmpl $0x9abcdef0, %eax + jne bogus_32_magic + + /* + * Prepare for entering 64bits mode + */ + + /* Enable PAE mode and PGE */ + xorl %eax, %eax + btsl $5, %eax + btsl $7, %eax + movl %eax, %cr4 + + /* Setup early boot stage 4 level pagetables */ + movl $(wakeup_level4_pgt - __START_KERNEL_map), %eax + movl %eax, %cr3 + + /* Setup EFER (Extended Feature Enable Register) */ + movl $MSR_EFER, %ecx + rdmsr + /* Fool rdmsr and reset %eax to avoid dependences */ + xorl %eax, %eax + /* Enable Long Mode */ + btsl $_EFER_LME, %eax + /* Enable System Call */ + btsl $_EFER_SCE, %eax + + /* No Execute supported? */ + btl $20,%edi + jnc 1f + btsl $_EFER_NX, %eax +1: + + /* Make changes effective */ + wrmsr + wbinvd + + xorl %eax, %eax + btsl $31, %eax /* Enable paging and in turn activate Long Mode */ + btsl $0, %eax /* Enable protected mode */ + btsl $1, %eax /* Enable MP */ + btsl $4, %eax /* Enable ET */ + btsl $5, %eax /* Enable NE */ + btsl $16, %eax /* Enable WP */ + btsl $18, %eax /* Enable AM */ + + /* Make changes effective */ + movl %eax, %cr0 + /* At this point: + CR4.PAE must be 1 + CS.L must be 0 + CR3 must point to PML4 + Next instruction must be a branch + This must be on identity-mapped page + */ + jmp reach_compatibility_mode +reach_compatibility_mode: + movw $0x0e00 + 'i', %ds:(0xb8012) + movb $0xa8, %al ; outb %al, $0x80; + + /* + * At this point we're in long mode but in 32bit compatibility mode + * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn + * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we load + * the new gdt/idt that has __KERNEL_CS with CS.L = 1. + */ + + movw $0x0e00 + 'n', %ds:(0xb8014) + movb $0xa9, %al ; outb %al, $0x80 + + /* Load new GDT with the 64bit segment using 32bit descriptor */ + movl $(pGDT32 - __START_KERNEL_map), %eax + lgdt (%eax) + + movl $(wakeup_jumpvector - __START_KERNEL_map), %eax + /* Finally jump in 64bit mode */ + ljmp *(%eax) + +wakeup_jumpvector: + .long wakeup_long64 - __START_KERNEL_map + .word __KERNEL_CS + +.code64 + + /* Hooray, we are in Long 64-bit mode (but still running in low memory) */ +wakeup_long64: + /* + * We must switch to a new descriptor in kernel space for the GDT + * because soon the kernel won't have access anymore to the userspace + * addresses where we're currently running on. We have to do that here + * because in 32bit we couldn't load a 64bit linear address. + */ + lgdt pGDT64 - __START_KERNEL_map + + movw $0x0e00 + 'u', %ds:(0xb8016) + + nop + nop + movw $__KERNEL_DS, %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movq saved_esp, %rsp + + movw $0x0e00 + 'x', %ds:(0xb8018) + movq saved_ebx, %rbx + movq saved_edi, %rdi + movq saved_esi, %rsi + movq saved_ebp, %rbp + + movw $0x0e00 + '!', %ds:(0xb801a) + movq saved_eip, %rax + jmp %rax + +.code32 + + .align 64 +gdta: + .word 0, 0, 0, 0 # dummy + + .word 0, 0, 0, 0 # unused + + .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) + .word 0 # base address = 0 + .word 0x9B00 # code read/exec. ??? Why I need 0x9B00 (as opposed to 0x9A00 in order for this to work?) + .word 0x00CF # granularity = 4096, 386 + # (+5th nibble of limit) + + .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) + .word 0 # base address = 0 + .word 0x9200 # data read/write + .word 0x00CF # granularity = 4096, 386 + # (+5th nibble of limit) +# this is 64bit descriptor for code + .word 0xFFFF + .word 0 + .word 0x9A00 # code read/exec + .word 0x00AF # as above, but it is long mode and with D=0 + +idt_48a: + .word 0 # idt limit = 0 + .word 0, 0 # idt base = 0L + +gdt_48a: + .word 0x8000 # gdt limit=2048, + # 256 GDT entries + .word 0, 0 # gdt base (filled in later) + + +real_save_gdt: .word 0 + .quad 0 +real_magic: .quad 0 +video_mode: .quad 0 + +bogus_real_magic: + movb $0xba,%al ; outb %al,$0x80 + jmp bogus_real_magic + +bogus_32_magic: + movb $0xb3,%al ; outb %al,$0x80 + jmp bogus_32_magic + +bogus_31_magic: + movb $0xb1,%al ; outb %al,$0x80 + jmp bogus_31_magic + +bogus_cpu: + movb $0xbc,%al ; outb %al,$0x80 + jmp bogus_cpu + + +/* This code uses an extended set of video mode numbers. These include: + * Aliases for standard modes + * NORMAL_VGA (-1) + * EXTENDED_VGA (-2) + * ASK_VGA (-3) + * Video modes numbered by menu position -- NOT RECOMMENDED because of lack + * of compatibility when extending the table. These are between 0x00 and 0xff. + */ +#define VIDEO_FIRST_MENU 0x0000 + +/* Standard BIOS video modes (BIOS number + 0x0100) */ +#define VIDEO_FIRST_BIOS 0x0100 + +/* VESA BIOS video modes (VESA number + 0x0200) */ +#define VIDEO_FIRST_VESA 0x0200 + +/* Video7 special modes (BIOS number + 0x0900) */ +#define VIDEO_FIRST_V7 0x0900 + +# Setting of user mode (AX=mode ID) => CF=success +mode_seta: + movw %ax, %bx +#if 0 + cmpb $0xff, %ah + jz setalias + + testb $VIDEO_RECALC>>8, %ah + jnz _setrec + + cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah + jnc setres + + cmpb $VIDEO_FIRST_SPECIAL>>8, %ah + jz setspc + + cmpb $VIDEO_FIRST_V7>>8, %ah + jz setv7 +#endif + + cmpb $VIDEO_FIRST_VESA>>8, %ah + jnc check_vesaa +#if 0 + orb %ah, %ah + jz setmenu +#endif + + decb %ah +# jz setbios Add bios modes later + +setbada: clc + ret + +check_vesaa: + subb $VIDEO_FIRST_VESA>>8, %bh + orw $0x4000, %bx # Use linear frame buffer + movw $0x4f02, %ax # VESA BIOS mode set call + int $0x10 + cmpw $0x004f, %ax # AL=4f if implemented + jnz _setbada # AH=0 if OK + + stc + ret + +_setbada: jmp setbada + + .code64 +bogus_magic: + movw $0x0e00 + 'B', %ds:(0xb8018) + jmp bogus_magic + +bogus_magic2: + movw $0x0e00 + '2', %ds:(0xb8018) + jmp bogus_magic2 + + +wakeup_stack_begin: # Stack grows down + +.org 0xff0 +wakeup_stack: # Just below end of page + +ENTRY(wakeup_end) + +## +# acpi_copy_wakeup_routine +# +# Copy the above routine to low memory. +# +# Parameters: +# %rdi: place to copy wakeup routine to +# +# Returned address is location of code in low memory (past data and stack) +# +ENTRY(acpi_copy_wakeup_routine) + pushq %rax + pushq %rcx + pushq %rdx + + sgdt saved_gdt + sidt saved_idt + sldt saved_ldt + str saved_tss + + movq %cr3, %rdx + movq %rdx, saved_cr3 + movq %cr4, %rdx + movq %rdx, saved_cr4 + movq %cr0, %rdx + movq %rdx, saved_cr0 + sgdt real_save_gdt - wakeup_start (,%rdi) + movl $MSR_EFER, %ecx + rdmsr + movl %eax, saved_efer + movl %edx, saved_efer2 + +# movq saved_videomode, %rdx # FIXME: videomode + movq %rdx, video_mode - wakeup_start (,%rdi) + movq $0x12345678, real_magic - wakeup_start (,%rdi) + movq $0x123456789abcdef0, %rdx + movq %rdx, saved_magic + + movl saved_magic - __START_KERNEL_map, %eax + cmpl $0x9abcdef0, %eax + jne bogus_32_magic + + # make sure %cr4 is set correctly (features, etc) + movl saved_cr4 - __START_KERNEL_map, %eax + movq %rax, %cr4 + + movl saved_cr0 - __START_KERNEL_map, %eax + movq %rax, %cr0 + jmp 1f # Flush pipelines +1: + # restore the regs we used + popq %rdx + popq %rcx + popq %rax +ENTRY(do_suspend_lowlevel_s4bios) + ret + + .align 2 + .p2align 4,,15 +.globl do_suspend_lowlevel + .type do_suspend_lowlevel,@function +do_suspend_lowlevel: +.LFB5: + subq $8, %rsp +.LCFI2: + testl %edi, %edi + jne .L99 + xorl %eax, %eax + call save_processor_state + + movq %rsp, saved_context_esp(%rip) + movq %rax, saved_context_eax(%rip) + movq %rbx, saved_context_ebx(%rip) + movq %rcx, saved_context_ecx(%rip) + movq %rdx, saved_context_edx(%rip) + movq %rbp, saved_context_ebp(%rip) + movq %rsi, saved_context_esi(%rip) + movq %rdi, saved_context_edi(%rip) + movq %r8, saved_context_r08(%rip) + movq %r9, saved_context_r09(%rip) + movq %r10, saved_context_r10(%rip) + movq %r11, saved_context_r11(%rip) + movq %r12, saved_context_r12(%rip) + movq %r13, saved_context_r13(%rip) + movq %r14, saved_context_r14(%rip) + movq %r15, saved_context_r15(%rip) + pushfq ; popq saved_context_eflags(%rip) + + movq $.L97, saved_eip(%rip) + + movq %rsp,saved_esp + movq %rbp,saved_ebp + movq %rbx,saved_ebx + movq %rdi,saved_edi + movq %rsi,saved_esi + + addq $8, %rsp + movl $3, %edi + xorl %eax, %eax + jmp acpi_enter_sleep_state +.L97: + .p2align 4,,7 +.L99: + .align 4 + movl $24, %eax + movw %ax, %ds + movq saved_context+58(%rip), %rax + movq %rax, %cr4 + movq saved_context+50(%rip), %rax + movq %rax, %cr3 + movq saved_context+42(%rip), %rax + movq %rax, %cr2 + movq saved_context+34(%rip), %rax + movq %rax, %cr0 + pushq saved_context_eflags(%rip) ; popfq + movq saved_context_esp(%rip), %rsp + movq saved_context_ebp(%rip), %rbp + movq saved_context_eax(%rip), %rax + movq saved_context_ebx(%rip), %rbx + movq saved_context_ecx(%rip), %rcx + movq saved_context_edx(%rip), %rdx + movq saved_context_esi(%rip), %rsi + movq saved_context_edi(%rip), %rdi + movq saved_context_r08(%rip), %r8 + movq saved_context_r09(%rip), %r9 + movq saved_context_r10(%rip), %r10 + movq saved_context_r11(%rip), %r11 + movq saved_context_r12(%rip), %r12 + movq saved_context_r13(%rip), %r13 + movq saved_context_r14(%rip), %r14 + movq saved_context_r15(%rip), %r15 + + xorl %eax, %eax + addq $8, %rsp + jmp restore_processor_state +.LFE5: +.Lfe5: + .size do_suspend_lowlevel,.Lfe5-do_suspend_lowlevel + +.data +ALIGN +ENTRY(saved_ebp) .quad 0 +ENTRY(saved_esi) .quad 0 +ENTRY(saved_edi) .quad 0 +ENTRY(saved_ebx) .quad 0 + +ENTRY(saved_eip) .quad 0 +ENTRY(saved_esp) .quad 0 + +ENTRY(saved_magic) .quad 0 + +ALIGN +# saved registers +saved_gdt: .quad 0,0 +saved_idt: .quad 0,0 +saved_ldt: .quad 0 +saved_tss: .quad 0 + +saved_cr0: .quad 0 +saved_cr3: .quad 0 +saved_cr4: .quad 0 +saved_efer: .quad 0 +saved_efer2: .quad 0 diff -urN linux-2.4.21/arch/x86_64/kernel/acpitable.c linux-2.4.22/arch/x86_64/kernel/acpitable.c --- linux-2.4.21/arch/x86_64/kernel/acpitable.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/acpitable.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,304 +0,0 @@ -/* - * acpitable.c - x86-64-specific ACPI (1.0 & 2.0) boot-time initialization - * - * Copyright (C) 1999 Andrew Henroid - * Copyright (C) 2001 Richard Schaal - * Copyright (C) 2001 Paul Diefenbaugh - * Copyright (C) 2001 Jun Nakajima - * Copyright (C) 2001 Arjan van de Ven - * Copyright (C) 2002 Vojtech Pavlik - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "acpitable.h" - -static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT]; - -extern unsigned long end_pfn; -static inline int bad_ptr(void *p) -{ - if ((unsigned long)p >> PAGE_SHIFT >= end_pfn) - return 1; - return 0; -} - -/* - * Checksum an ACPI table. - */ - -static unsigned char __init acpi_checksum(void *buffer, int length) -{ - unsigned char sum = 0; - while (length--) - sum += *(unsigned char *)buffer++; - return sum; -} - -/* - * Print an ACPI table header for debugging. - */ - -static char __init *acpi_kill_spaces(char *t, char *s, int m) -{ - int l = strnlen(s, m); - strncpy(t, s, m); - t[l] = 0; - while (l > 0 && (t[l - 1] == ' ' || t[l - 1] == '\t')) t[--l] = 0; - while (t[0] == ' ' || t[0] == '\t') t++; - return t; -} - -static void __init acpi_print_table_header(struct acpi_table_header * header) -{ - char oem[7], id[9]; - - printk(KERN_INFO "acpi: %.4s rev: %d oem: %s id: %s build: %d.%d\n", - header->signature, header->revision, acpi_kill_spaces(oem, header->oem_id, 6), - acpi_kill_spaces(id, header->oem_table_id, 8), header->oem_revision >> 16, - header->oem_revision & 0xffff); -} - -/* - * Search a block of memory for the RSDP signature - */ - -static void* __init acpi_tb_scan_memory_for_rsdp(void *address, int length) -{ - u32 offset = 0; - - while (offset < length) { - if (strncmp(address, "RSD PTR ", 8) == 0 && - acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) { - printk(KERN_INFO "acpi: RSDP found at address %p\n", address); - return address; - } - offset += RSDP_SCAN_STEP; - address += RSDP_SCAN_STEP; - } - return NULL; -} - -/* - * Search lower 1_mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. - */ - -static struct acpi_table_rsdp* __init acpi_find_root_pointer(void) -{ - struct acpi_table_rsdp *rsdp; - - if ((rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE), LO_RSDP_WINDOW_SIZE))) - return rsdp; - - if ((rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE), HI_RSDP_WINDOW_SIZE))) - return rsdp; - - return NULL; -} - -static int __init acpi_process_table(u64 table) -{ - struct acpi_table_header *header; - int type; - - header = __va(table); - - acpi_print_table_header(header); - - if (acpi_checksum(header, header->length)) { - printk(KERN_WARNING "acpi: ACPI table at %#lx has invalid checksum.\n", table); - return -1; - } - - for (type = 0; type < ACPI_TABLE_COUNT; type++) - if (!strncmp(header->signature, acpi_table_signatures[type], 4)) - break; - - if (type == ACPI_TABLE_COUNT || !acpi_boot_ops[type]) - return 0; - - return acpi_boot_ops[type](header, table); -} - -static int __init acpi_tables_init(void) -{ - struct acpi_table_rsdp *rsdp; - struct acpi_table_xsdt *xsdt = NULL; - struct acpi_table_rsdt *rsdt = NULL; - char oem[7]; - int i; - - if (!(rsdp = acpi_find_root_pointer())) { - printk(KERN_ERR "acpi: Couldn't find ACPI root pointer!\n"); - return -1; - } - - printk(KERN_INFO "acpi: RSDP rev: %d oem: %s\n", - rsdp->revision, acpi_kill_spaces(oem, rsdp->oem_id, 6)); - - if (!acpi_checksum(rsdp, RSDP2_CHECKSUM_LENGTH) - && rsdp->length >= RSDP2_CHECKSUM_LENGTH) { /* ACPI 2.0 might be present */ - xsdt = __va(rsdp->xsdt_address); - if (bad_ptr(xsdt)) - return -1; - if (!strncmp(xsdt->header.signature, "XSDT", 4)) { - acpi_print_table_header(&xsdt->header); - for (i = 0; i < (xsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u64); i++) - if (acpi_process_table(xsdt->entry[i])) - return -1; - return 0; - } - } - - rsdt = __va(rsdp->rsdt_address); - if (bad_ptr(rsdt)) - return -1; - if (!strncmp(rsdt->header.signature, "RSDT", 4)) { - acpi_print_table_header(&rsdt->header); - for (i = 0; i < (rsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u32); i++) - if (acpi_process_table(rsdt->entry[i])) - return -1; - return 0; - } - - printk(KERN_WARNING "acpi: No ACPI table directory found.\n"); - return -1; -} - -static void __init acpi_parse_lapic(struct acpi_table_lapic *local_apic) -{ - printk(KERN_INFO "acpi: LAPIC acpi_id: %d id: %d enabled: %d\n", - local_apic->acpi_id, local_apic->id, local_apic->flags.enabled); -} - -static void __init acpi_parse_ioapic(struct acpi_table_ioapic *ioapic) -{ - printk(KERN_INFO "acpi: IOAPIC id: %d address: %#x global_irq_base: %#x\n", - ioapic->id, ioapic->address, ioapic->global_irq_base); -} - -static void __init acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc) -{ - printk(KERN_INFO "acpi: INT_SRC_OVR bus: %d irq: %d global_irq: %d polarity: %d trigger: %d\n", - intsrc->bus, intsrc->bus_irq, intsrc->global_irq, intsrc->flags.polarity, intsrc->flags.trigger); -} - -static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc) -{ - printk(KERN_INFO "acpi: NMI_SRC polarity: %d trigger: %d global_irq: %d\n", - nmisrc->flags.polarity, nmisrc->flags.trigger, nmisrc->global_irq); -} - -static void __init acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi) -{ - printk(KERN_INFO "acpi: LAPIC_NMI acpi_id: %d polarity: %d trigger: %d lint: %d\n", - localnmi->acpi_id, localnmi->flags.polarity, localnmi->flags.trigger, localnmi->lint); -} - -static void __init acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr) -{ - printk(KERN_INFO "acpi: LAPIC_ADDR_OVR address: %#lx\n", - (unsigned long) lapic_addr_ovr->address); -} - -static void __init acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc) -{ - printk(KERN_INFO "acpi: PLAT_INT_SRC polarity: %d trigger: %d type: %d id: %d eid: %d iosapic_vector: %#x global_irq: %d\n", - plintsrc->flags.polarity, plintsrc->flags.trigger, plintsrc->type, plintsrc->id, plintsrc->eid, - plintsrc->iosapic_vector, plintsrc->global_irq); -} - -static int __init acpi_parse_madt(struct acpi_table_header *header, unsigned long phys) -{ - - struct acpi_table_madt *madt; - struct acpi_madt_entry_header *entry_header; - int table_size; - - madt = __va(phys); - table_size = header->length - sizeof(*madt); - entry_header = (void *)madt + sizeof(*madt); - - while (entry_header && table_size > 0) { - - switch (entry_header->type) { - case ACPI_MADT_LAPIC: - acpi_parse_lapic((void *) entry_header); - break; - case ACPI_MADT_IOAPIC: - acpi_parse_ioapic((void *) entry_header); - break; - case ACPI_MADT_INT_SRC_OVR: - acpi_parse_int_src_ovr((void *) entry_header); - break; - case ACPI_MADT_NMI_SRC: - acpi_parse_nmi_src((void *) entry_header); - break; - case ACPI_MADT_LAPIC_NMI: - acpi_parse_lapic_nmi((void *) entry_header); - break; - case ACPI_MADT_LAPIC_ADDR_OVR: - acpi_parse_lapic_addr_ovr((void *) entry_header); - break; - case ACPI_MADT_PLAT_INT_SRC: - acpi_parse_plat_int_src((void *) entry_header); - break; - default: - printk(KERN_WARNING "acpi: Unsupported MADT entry type 0x%x\n", entry_header->type); - break; - } - - table_size -= entry_header->length; - entry_header = (void *) entry_header + entry_header->length; - } - - printk(KERN_INFO "acpi: Local APIC address %#x\n", madt->lapic_address); - - return 0; -} - -static int __init acpi_parse_hpet(struct acpi_table_header *header, unsigned long phys) -{ - struct acpi_table_hpet *hpet_tbl; - - hpet_tbl = __va(phys); - - if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { - printk(KERN_WARNING "acpi: HPET timers must be located in memory.\n"); - return -1; - } - - hpet_address = hpet_tbl->addr.addrl | ((long) hpet_tbl->addr.addrh << 32); - - printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address); - - return 0; -} - -/* - * Configure the processor info using MADT in the ACPI tables. If we fail to - * configure that, then we use the MPS tables. - */ - -void __init config_acpi_tables(void) -{ - acpi_boot_ops[ACPI_APIC] = acpi_parse_madt; - acpi_boot_ops[ACPI_HPET] = acpi_parse_hpet; - - if (acpi_tables_init()) - printk(KERN_ERR "acpi: Init failed.\n"); -} diff -urN linux-2.4.21/arch/x86_64/kernel/aperture.c linux-2.4.22/arch/x86_64/kernel/aperture.c --- linux-2.4.21/arch/x86_64/kernel/aperture.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/aperture.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,14 +1,14 @@ /* * Firmware replacement code. * - * Work around broken BIOSes that don't set an aperture. - * The IOMMU code needs an aperture even who no AGP is present in the system. - * Map the aperture over some low memory. This is cheaper than doing bounce - * buffering. The memory is lost. This is done at early boot because only - * the bootmem allocator can allocate 32+MB. + * Work around broken BIOSes that don't set an aperture or only set the + * aperture in the AGP bridge. + * If all fails map the aperture over some low memory. This is cheaper than + * doing bounce buffering. The memory is lost. This is done at early boot + * because only the bootmem allocator can allocate 32+MB. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: aperture.c,v 1.4 2002/11/28 06:05:58 ak Exp $ + * $Id: aperture.c,v 1.7 2003/08/01 03:36:18 ak Exp $ */ #include #include @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -64,16 +66,130 @@ return (u32)__pa(p); } +static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) +{ + if (!aper_base) + return 0; + if (aper_size < 64*1024*1024) { + printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20); + return 0; + } + if (aper_base + aper_size >= 0xffffffff) { + printk("Aperture from %s beyond 4GB. Ignoring.\n",name); + return 0; + } + if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) { + printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); + return 0; + } + return 1; +} + +/* Find a PCI capability */ +static __u32 __init find_cap(int num, int slot, int func, int cap) +{ + if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST)) + return 0; + u8 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST); + int bytes; + for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { + pos &= ~3; + u8 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID); + if (id == 0xff) + break; + if (id == cap) + return pos; + pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT); + } + return 0; +} + +/* Read a standard AGPv3 bridge header */ +static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order) +{ + printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func); + u32 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14); + + if (apsizereg == 0xffffffff) { + printk("APSIZE in AGP bridge unreadable\n"); + return 0; + } + + u32 apsize = apsizereg & 0xfff; + /* Some BIOS use weird encodings not in the AGPv3 table. */ + if (apsize & 0xff) + apsize |= 0xf00; + int nbits = hweight16(apsize); + *order = 7 - nbits; + if ((int)*order < 0) /* < 32MB */ + *order = 0; + + u32 aper_low = read_pci_config(num,slot,func, 0x10); + u32 aper_hi = read_pci_config(num,slot,func,0x14); + u64 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); + + printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n", + aper, 32 << *order, apsizereg); + + if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order)) + return 0; + return (u32)aper; +} + +/* Look for an AGP bridge. Windows only expects the aperture in the + AGP bridge and some BIOS forget to initialize the Northbridge too. + Work around this here. + + Do an PCI bus scan by hand because we're running before the PCI + subsystem. + + All K8 AGP bridges are AGPv3 compliant, so we can do this scan + generically. It's probably overkill to always scan all slots because + the AGP bridges should be always an own bus on the HT hierarchy, + but do it here for future safety. */ +static __u32 __init search_agp_bridge(u32 *order, int *valid_agp) +{ + int num, slot, func; + + /* Poor man's PCI discovery */ + for (num = 0; num < 32; num++) { + for (slot = 0; slot < 32; slot++) { + for (func = 0; func < 8; func++) { + u32 class, cap; + class = read_pci_config(num,slot,func, + PCI_CLASS_REVISION); + if (class == 0xffffffff) + break; + + switch (class >> 16) { + case PCI_CLASS_BRIDGE_HOST: + case PCI_CLASS_BRIDGE_OTHER: /* needed? */ + /* AGP bridge? */ + cap = find_cap(num,slot,func,PCI_CAP_ID_AGP); + if (!cap) + break; + *valid_agp = 1; + return read_agp(num,slot,func,cap,order); + } + + /* No multi-function device? */ + u8 type = read_pci_config_byte(num,slot,func, + PCI_HEADER_TYPE); + if (!(type & 0x80)) + break; + } + } + } + printk("No AGP bridge found\n"); + return 0; +} + void __init iommu_hole_init(void) { int fix, num; - u32 aper_size, aper_alloc, aper_order; + u32 aper_size, aper_alloc = 0, aper_order; u64 aper_base; - - if (no_iommu) - return; - if (end_pfn < (0xffffffff>>PAGE_SHIFT) && !force_mmu) - return; + int valid_agp = 0; printk("Checking aperture...\n"); @@ -87,15 +203,13 @@ aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff; aper_base <<= 25; - printk("CPU %d: aperture @ %Lx size %u KB\n", num-24, - aper_base, aper_size>>10); - if (!aper_base || aper_base + aper_size >= 0xffffffff) { - fix = 1; - break; - } + printk("CPU %d: aperture @ %Lx size %u MB\n", num-24, + aper_base, aper_size>>20); - if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) { - printk("Aperture pointing to e820 RAM. Ignoring.\n"); + char name[30]; + sprintf(name, "northbridge cpu %d", num-24); + + if (!aperture_valid(name, aper_base, aper_size)) { fix = 1; break; } @@ -104,12 +218,40 @@ if (!fix && !fallback_aper_force) return; + if (!fallback_aper_force) + aper_alloc = search_agp_bridge(&aper_order, &valid_agp); + + if (aper_alloc) { + /* Got the aperture from the AGP bridge */ + } else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) || + force_mmu || + valid_agp || + fallback_aper_force) { + /* When there is a AGP bridge in the system assume the + user wants to use the AGP driver too and needs an + aperture. However this case (AGP but no good + aperture) should only happen with a more broken than + usual BIOS, because it would even break Windows. */ + printk("Your BIOS doesn't leave a aperture memory hole\n"); printk("Please enable the IOMMU option in the BIOS setup\n"); + printk("This costs you %d MB of RAM\n", 32 << fallback_aper_order); + + aper_order = fallback_aper_order; aper_alloc = allocate_aperture(); - if (!aper_alloc) + if (!aper_alloc) { + /* Could disable AGP and IOMMU here, but it's probably + not worth it. But the later users cannot deal with + bad apertures and turning on the aperture over memory + causes very strange problems, so it's better to + panic early. */ + panic("Not enough memory for aperture"); + } + } else { return; + } + /* Fix up the north bridges */ for (num = 24; num < 32; num++) { if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) continue; @@ -117,7 +259,7 @@ /* Don't enable translation yet. That is done later. Assume this BIOS didn't initialise the GART so just overwrite all previous bits */ - write_pci_config(0, num, 3, 0x90, fallback_aper_order<<1); + write_pci_config(0, num, 3, 0x90, aper_order<<1); write_pci_config(0, num, 3, 0x94, aper_alloc>>25); } } diff -urN linux-2.4.21/arch/x86_64/kernel/apic.c linux-2.4.22/arch/x86_64/kernel/apic.c --- linux-2.4.21/arch/x86_64/kernel/apic.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/apic.c 2003-08-25 04:44:40.000000000 -0700 @@ -591,52 +591,14 @@ 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); - - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) - break; - goto no_apic; - case X86_VENDOR_INTEL: - if (boot_cpu_data.x86 == 6 || - (boot_cpu_data.x86 == 15 && cpu_has_apic) || - (boot_cpu_data.x86 == 5 && cpu_has_apic)) - break; - goto no_apic; - default: - goto no_apic; - } - + /* Don't force the APIC if the BIOS didn't enable it. Usually + it is broken in some way. */ if (!cpu_has_apic) { - /* - * Some BIOSes disable the local APIC in the - * APIC_BASE MSR. This can only be done in - * software for Intel P6 and AMD K7 (Model > 1). - */ - rdmsr(MSR_IA32_APICBASE, l, h); - if (!(l & MSR_IA32_APICBASE_ENABLE)) { - printk("Local APIC disabled by BIOS -- reenabling.\n"); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; - wrmsr(MSR_IA32_APICBASE, l, h); - } - } - /* - * The APIC feature bit should now be enabled - * in `cpuid' - */ - features = cpuid_edx(1); - if (!(features & (1 << X86_FEATURE_APIC))) { - printk("Could not enable APIC!\n"); + printk(KERN_INFO "APIC disabled by BIOS.\n"); return -1; } set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability); @@ -645,15 +607,11 @@ if (nmi_watchdog != NMI_NONE) nmi_watchdog = NMI_LOCAL_APIC; - printk("Found and enabled local APIC!\n"); + printk(KERN_INFO "Found and enabled local APIC!\n"); apic_pm_init1(); return 0; - -no_apic: - printk("No local APIC present or hardware disabled\n"); - return -1; } void __init init_apic_mappings(void) @@ -1065,7 +1023,11 @@ */ int __init APIC_init_uniprocessor (void) { - if (!smp_found_config && !cpu_has_apic) { + if (apic_disabled) + clear_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability); + + if (!cpu_has_apic) { + printk("No APIC available.\n"); apic_disabled = 1; return -1; } @@ -1103,3 +1065,11 @@ return 0; } + +static int disable_local_apic(char *s) +{ + apic_disabled = 1; + return 0; +} +__setup("nolocalapic", disable_local_apic); + diff -urN linux-2.4.21/arch/x86_64/kernel/bluesmoke.c linux-2.4.22/arch/x86_64/kernel/bluesmoke.c --- linux-2.4.21/arch/x86_64/kernel/bluesmoke.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/bluesmoke.c 2003-08-25 04:44:40.000000000 -0700 @@ -125,6 +125,67 @@ return NULL; } +static char *transaction[] = { + "instruction", "data", "generic", "reserved" +}; +static char *cachelevel[] = { + "level 0", "level 1", "level 2", "level generic" +}; +static char *memtrans[] = { + "generic error", "generic read", "generic write", "data read", + "data write", "instruction fetch", "prefetch", "snoop", + "?", "?", "?", "?", "?", "?", "?" +}; +static char *partproc[] = { + "local node origin", "local node response", + "local node observed", "generic" +}; +static char *timeout[] = { + "request didn't time out", + "request timed out" +}; +static char *memoryio[] = { + "memory access", "res.", "i/o access", "generic" +}; +static char *extendederr[] = { + "ecc error", + "crc error", + "sync error", + "mst abort", + "tgt abort", + "gart error", + "rmw error", + "wdog error", + "chipkill ecc error", + "<9>","<10>","<11>","<12>", + "<13>","<14>","<15>" +}; +static char *highbits[32] = { + [31] = "previous error lost", + [30] = "error overflow", + [29] = "error uncorrected", + [28] = "error enable", + [27] = "misc error valid", + [26] = "error address valid", + [25] = "processor context corrupt", + [24] = "res24", + [23] = "res23", + /* 22-15 ecc syndrome bits */ + [14] = "corrected ecc error", + [13] = "uncorrected ecc error", + [12] = "res12", + [11] = "res11", + [10] = "res10", + [9] = "res9", + [8] = "dram scrub error", + [7] = "res7", + /* 6-4 ht link number of error */ + [3] = "res3", + [2] = "res2", + [1] = "err cpu0", + [0] = "err cpu1", +}; + static void check_k8_nb(void) { struct pci_dev *nb; @@ -139,20 +200,52 @@ return; printk(KERN_ERR "Northbridge status %08x%08x\n", statushigh,statuslow); - if (statuslow & 0x10) - printk(KERN_ERR "GART error %d\n", statuslow & 0xf); - if (statushigh & (1<<31)) - printk(KERN_ERR "Lost an northbridge error\n"); - if (statushigh & (1<<25)) - printk(KERN_EMERG "NB status: unrecoverable\n"); + + unsigned short errcode = statuslow & 0xffff; + switch (errcode >> 8) { + case 0: + printk(KERN_ERR " GART TLB error %s %s\n", + transaction[(errcode >> 2) & 3], + cachelevel[errcode & 3]); + break; + case 1: + if (errcode & (1<<11)) { + printk(KERN_ERR " bus error %s %s %s %s %s\n", + partproc[(errcode >> 10) & 0x3], + timeout[(errcode >> 9) & 1], + memtrans[(errcode >> 4) & 0xf], + memoryio[(errcode >> 2) & 0x3], + cachelevel[(errcode & 0x3)]); + } else if (errcode & (1<<8)) { + printk(KERN_ERR " memory error %s %s %s\n", + memtrans[(errcode >> 4) & 0xf], + transaction[(errcode >> 2) & 0x3], + cachelevel[(errcode & 0x3)]); + } else { + printk(KERN_ERR " unknown error code %x\n", errcode); + } + break; + } + if (statushigh & ((1<<14)|(1<<13))) + printk(KERN_ERR " ECC syndrome bits %x\n", + (((statuslow >> 24) & 0xff) << 8) | ((statushigh >> 15) & 0x7f)); + errcode = (statuslow >> 16) & 0xf; + printk(KERN_ERR " extended error %s\n", extendederr[(statuslow >> 16) & 0xf]); + + /* should only print when it was a HyperTransport related error. */ + printk(KERN_ERR " link number %x\n", (statushigh >> 4) & 3); + + int i; + for (i = 0; i < 32; i++) + if (highbits[i] && (statushigh & (1<devfn, reg, reg2); - ignored_banks |= (1UL<<4); - } - set_in_cr4(X86_CR4_MCE); if (mcheck_interval && (smp_processor_id() == 0)) { diff -urN linux-2.4.21/arch/x86_64/kernel/e820.c linux-2.4.22/arch/x86_64/kernel/e820.c --- linux-2.4.21/arch/x86_64/kernel/e820.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/e820.c 2003-08-25 04:44:40.000000000 -0700 @@ -500,6 +500,7 @@ extern char command_line[], saved_command_line[]; extern int fallback_aper_order; extern int iommu_setup(char *opt); +extern int acpi_disabled; void __init parse_mem_cmdline (char ** cmdline_p) { @@ -537,8 +538,10 @@ else if (!memcmp(from,"iommu=",6)) { iommu_setup(from+6); } - #endif + else if (!memcmp(from, "acpi=off", 8)) + acpi_disabled = 1; + next: c = *(from++); if (!c) diff -urN linux-2.4.21/arch/x86_64/kernel/head.S linux-2.4.22/arch/x86_64/kernel/head.S --- linux-2.4.21/arch/x86_64/kernel/head.S 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 @@ -6,7 +6,7 @@ * Copyright (C) 2000 Karsten Keil * Copyright (C) 2001,2002 Andi Kleen * - * $Id: head.S,v 1.55 2003/02/11 12:29:15 ak Exp $ + * $Id: head.S,v 1.56 2003/05/12 14:38:43 ak Exp $ */ @@ -198,6 +198,7 @@ 1: jmp 1b + .globl pGDT32 .org 0xf00 pGDT32: .word gdt32_end-gdt_table32 @@ -312,10 +313,19 @@ .quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ .org 0xb000 +ENTRY(wakeup_level4_pgt) + .quad 0x0000000000102007 /* -> level3_ident_pgt */ + .fill 255,8,0 + .quad 0x000000000010a007 + .fill 254,8,0 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ + .quad 0x0000000000103007 /* -> level3_kernel_pgt */ + .data .globl SYMBOL_NAME(gdt) + .globl pGDT64 .word 0 .align 16 .word 0 @@ -340,7 +350,7 @@ .align 64 /* cacheline aligned, keep this synchronized with asm/desc.h */ ENTRY(gdt_table) .quad 0x0000000000000000 /* This one is magic */ - .quad 0x0000000000000000 /* unused */ + .quad 0x00af9a000000ffff ^ (1<<21) /* __KERNEL_COMPAT32_CS */ .quad 0x00af9a000000ffff /* __KERNEL_CS */ .quad 0x00cf92000000ffff /* __KERNEL_DS */ .quad 0x00cffe000000ffff /* __USER32_CS */ diff -urN linux-2.4.21/arch/x86_64/kernel/io_apic.c linux-2.4.22/arch/x86_64/kernel/io_apic.c --- linux-2.4.21/arch/x86_64/kernel/io_apic.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/io_apic.c 2003-08-25 04:44:40.000000000 -0700 @@ -17,6 +17,7 @@ * thanks to Eric Gilmore * and Rolf G. Tews * for testing these extensively + * Paul Diefenbaugh : Added full ACPI support */ #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include @@ -1046,6 +1048,10 @@ unsigned char old_id; unsigned long flags; + if (acpi_ioapic) + /* This gets done during IOAPIC enumeration for ACPI. */ + return; + /* * Set the IOAPIC ID to the value stored in the MPC table. */ @@ -1641,8 +1647,7 @@ printk("ENABLING IO-APIC IRQs\n"); /* - * Set up the IO-APIC IRQ routing table by parsing the MP-BIOS - * mptable: + * Set up IO-APIC IRQ routing. */ setup_ioapic_ids_from_mpc(); sync_Arb_IDs(); @@ -1651,3 +1656,159 @@ check_timer(); print_IO_APIC(); } + + +/* -------------------------------------------------------------------------- + ACPI-based IOAPIC Configuration + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_BOOT + +#define IO_APIC_MAX_ID 15 + +int __init io_apic_get_unique_id (int ioapic, int apic_id) +{ + struct IO_APIC_reg_00 reg_00; + static unsigned long apic_id_map = 0; + unsigned long flags; + int i = 0; + + /* + * The P4 platform supports up to 256 APIC IDs on two separate APIC + * buses (one for LAPICs, one for IOAPICs), where predecessors only + * supports up to 16 on one shared APIC bus. + * + * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full + * advantage of new APIC bus architecture. + */ + + if (!apic_id_map) + apic_id_map = phys_cpu_present_map; + + spin_lock_irqsave(&ioapic_lock, flags); + *(int *)®_00 = io_apic_read(ioapic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + if (apic_id >= IO_APIC_MAX_ID) { + printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " + "%d\n", ioapic, apic_id, reg_00.ID); + apic_id = reg_00.ID; + } + + /* + * Every APIC in a system must have a unique ID or we get lots of nice + * 'stuck on smp_invalidate_needed IPI wait' messages. + */ + if (apic_id_map & (1 << apic_id)) { + + for (i = 0; i < IO_APIC_MAX_ID; i++) { + if (!(apic_id_map & (1 << i))) + break; + } + + if (i == IO_APIC_MAX_ID) + panic("Max apic_id exceeded!\n"); + + printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " + "trying %d\n", ioapic, apic_id, i); + + apic_id = i; + } + + apic_id_map |= (1 << apic_id); + + if (reg_00.ID != apic_id) { + reg_00.ID = apic_id; + + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic, 0, *(int *)®_00); + *(int *)®_00 = io_apic_read(ioapic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + /* Sanity check */ + if (reg_00.ID != apic_id) + panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); + } + + printk(KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); + + return apic_id; +} + + +int __init io_apic_get_version (int ioapic) +{ + struct IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + *(int *)®_01 = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.version; +} + + +int __init io_apic_get_redir_entries (int ioapic) +{ + struct IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + *(int *)®_01 = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.entries; +} + + +int io_apic_set_pci_routing (int ioapic, int pin, int irq) +{ + struct IO_APIC_route_entry entry; + unsigned long flags; + + if (!IO_APIC_IRQ(irq)) { + printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0/n", + ioapic); + return -EINVAL; + } + + /* + * Generate a PCI IRQ routing entry and program the IOAPIC accordingly. + * Note that we mask (disable) IRQs now -- these get enabled when the + * corresponding device driver registers for this IRQ. + */ + + memset(&entry,0,sizeof(entry)); + + entry.delivery_mode = dest_LowestPrio; + entry.dest_mode = INT_DELIVERY_MODE; + entry.dest.logical.logical_dest = TARGET_CPUS; + entry.mask = 1; /* Disabled (masked) */ + entry.trigger = 1; /* Level sensitive */ + entry.polarity = 1; /* Low active */ + + add_pin_to_irq(irq, ioapic, pin); + + entry.vector = assign_irq_vector(irq); + + printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> " + "IRQ %d)\n", ioapic, + mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq); + + irq_desc[irq].handler = &ioapic_level_irq_type; + + set_intr_gate(entry.vector, interrupt[irq]); + + if (!ioapic && (irq < 16)) + disable_8259A_irq(irq); + + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return entry.vector; +} + +#endif /*CONFIG_ACPI_BOOT*/ diff -urN linux-2.4.21/arch/x86_64/kernel/mpparse.c linux-2.4.22/arch/x86_64/kernel/mpparse.c --- linux-2.4.21/arch/x86_64/kernel/mpparse.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/arch/x86_64/kernel/mpparse.c 2003-08-25 04:44:40.000000000 -0700 @@ -9,12 +9,14 @@ * Erich Boleyn : MP v1.4 and additional changes. * Alan Cox : Added EBDA scanning * Ingo Molnar : various cleanups and rewrites - * Maciej W. Rozycki : Bits for default MP configurations + * Maciej W. Rozycki: Bits for default MP configurations + * Paul Diefenbaugh: Added full ACPI support */ #include #include #include +#include #include #include #include @@ -23,11 +25,13 @@ #include #include +#include #include #include #include #include #include +#include /* Have we found an MP table */ int smp_found_config = 0; @@ -249,7 +253,11 @@ printk("APIC at: 0x%X\n",mpc->mpc_lapic); - /* save the local APIC address, it might be non-default */ + /* + * Save the local APIC address (it might be non-default) -- but only + * if we're not using ACPI. + */ + if (!acpi_lapic) mp_lapic_addr = mpc->mpc_lapic; /* @@ -261,6 +269,8 @@ { struct mpc_config_processor *m= (struct mpc_config_processor *)mpt; + /* ACPI may have already provided this data */ + if (!acpi_lapic) MP_processor_info(m); mpt += sizeof(*m); count += sizeof(*m); @@ -475,6 +485,19 @@ void __init get_smp_config (void) { struct intel_mp_floating *mpf = mpf_found; + /* + * ACPI may be used to obtain the entire SMP configuration or just to + * enumerate/configure processors (CONFIG_ACPI_HT_ONLY). Note that + * ACPI supports both logical (e.g. Hyper-Threading) and physical + * processors, where MPS only supports physical. + */ + if (acpi_lapic && acpi_ioapic) { + printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n"); + return; + } + else if (acpi_lapic) + printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); + printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); if (mpf->mpf_feature2 & (1<<7)) { printk(" IMCR and PIC compatibility mode.\n"); @@ -614,3 +637,368 @@ #endif } + +/* -------------------------------------------------------------------------- + ACPI-based MP Configuration + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_BOOT + +void __init mp_register_lapic_address ( + u64 address) +{ + mp_lapic_addr = (unsigned long) address; + + set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); + + if (boot_cpu_id == -1U) + boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); + + Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); +} + + +void __init mp_register_lapic ( + u8 id, + u8 enabled) +{ + struct mpc_config_processor processor; + int boot_cpu = 0; + + if (id >= MAX_APICS) { + printk(KERN_WARNING "Processor #%d invalid (max %d)\n", + id, MAX_APICS); + return; + } + + if (id == boot_cpu_physical_apicid) + boot_cpu = 1; + + processor.mpc_type = MP_PROCESSOR; + processor.mpc_apicid = id; + processor.mpc_apicver = 0x10; /* TBD: lapic version */ + processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); + processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | + (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; + processor.mpc_reserved[0] = 0; + processor.mpc_reserved[1] = 0; + + MP_processor_info(&processor); +} + +#ifdef CONFIG_X86_IO_APIC + +#define MP_ISA_BUS 0 +#define MP_MAX_IOAPIC_PIN 127 + +struct mp_ioapic_routing { + int apic_id; + int irq_start; + int irq_end; + u32 pin_programmed[4]; +} mp_ioapic_routing[MAX_IO_APICS]; + + +static int __init mp_find_ioapic ( + int irq) +{ + int i = 0; + + /* Find the IOAPIC that manages this IRQ. */ + for (i = 0; i < nr_ioapics; i++) { + if ((irq >= mp_ioapic_routing[i].irq_start) + && (irq <= mp_ioapic_routing[i].irq_end)) + return i; + } + + printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d/n", irq); + + return -1; +} + + +void __init mp_register_ioapic ( + u8 id, + u32 address, + u32 irq_base) +{ + int idx = 0; + + if (nr_ioapics >= MAX_IO_APICS) { + printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " + "(found %d)\n", MAX_IO_APICS, nr_ioapics); + panic("Recompile kernel with bigger MAX_IO_APICS!\n"); + } + if (!address) { + printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" + " found in MADT table, skipping!\n"); + return; + } + + idx = nr_ioapics++; + + mp_ioapics[idx].mpc_type = MP_IOAPIC; + mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; + mp_ioapics[idx].mpc_apicaddr = address; + + set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); + mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); + mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); + + /* + * Build basic IRQ lookup table to facilitate irq->io_apic lookups + * and to prevent reprogramming of IOAPIC pins (PCI IRQs). + */ + mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid; + mp_ioapic_routing[idx].irq_start = irq_base; + mp_ioapic_routing[idx].irq_end = irq_base + + io_apic_get_redir_entries(idx); + + printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " + "IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, + mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, + mp_ioapic_routing[idx].irq_start, + mp_ioapic_routing[idx].irq_end); + + return; +} + + +void __init mp_override_legacy_irq ( + u8 bus_irq, + u8 polarity, + u8 trigger, + u32 global_irq) +{ + struct mpc_config_intsrc intsrc; + int i = 0; + int found = 0; + int ioapic = -1; + int pin = -1; + + /* + * Convert 'global_irq' to 'ioapic.pin'. + */ + ioapic = mp_find_ioapic(global_irq); + if (ioapic < 0) + return; + pin = global_irq - mp_ioapic_routing[ioapic].irq_start; + + /* + * TBD: This check is for faulty timer entries, where the override + * erroneously sets the trigger to level, resulting in a HUGE + * increase of timer interrupts! + */ + if ((bus_irq == 0) && (global_irq == 2) && (trigger == 3)) + trigger = 1; + + intsrc.mpc_type = MP_INTSRC; + intsrc.mpc_irqtype = mp_INT; + intsrc.mpc_irqflag = (trigger << 2) | polarity; + intsrc.mpc_srcbus = MP_ISA_BUS; + intsrc.mpc_srcbusirq = bus_irq; /* IRQ */ + intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; /* APIC ID */ + intsrc.mpc_dstirq = pin; /* INTIN# */ + + Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", + intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, + (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, + intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq); + + /* + * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it. + * Otherwise create a new entry (e.g. global_irq == 2). + */ + for (i = 0; i < mp_irq_entries; i++) { + if ((mp_irqs[i].mpc_dstapic == intsrc.mpc_dstapic) + && (mp_irqs[i].mpc_dstirq == intsrc.mpc_dstirq)) { + mp_irqs[i] = intsrc; + found = 1; + break; + } + } + if (!found) { + mp_irqs[mp_irq_entries] = intsrc; + if (++mp_irq_entries == MAX_IRQ_SOURCES) + panic("Max # of irq sources exceeded!\n"); + } + + return; +} + + +void __init mp_config_acpi_legacy_irqs (void) +{ + struct mpc_config_intsrc intsrc; + int i = 0; + int ioapic = -1; + + /* + * Fabricate the legacy ISA bus (bus #31). + */ + mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; + Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); + + /* + * Locate the IOAPIC that manages the ISA IRQs (0-15). + */ + ioapic = mp_find_ioapic(0); + if (ioapic < 0) + return; + + intsrc.mpc_type = MP_INTSRC; + intsrc.mpc_irqflag = 0; /* Conforming */ + intsrc.mpc_srcbus = MP_ISA_BUS; + intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; + + /* + * Use the default configuration for the IRQs 0-15. These may be + * overriden by (MADT) interrupt source override entries. + */ + for (i = 0; i < 16; i++) { + + if (i == 2) continue; /* Don't connect IRQ2 */ + + intsrc.mpc_irqtype = i ? mp_INT : mp_ExtINT; /* 8259A to #0 */ + intsrc.mpc_srcbusirq = i; /* Identity mapped */ + intsrc.mpc_dstirq = i; + + Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, " + "%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, + (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, + intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, + intsrc.mpc_dstirq); + + mp_irqs[mp_irq_entries] = intsrc; + if (++mp_irq_entries == MAX_IRQ_SOURCES) + panic("Max # of irq sources exceeded!\n"); + } + + return; +} + + + +#ifndef CONFIG_ACPI_HT_ONLY + +/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */ + +extern FADT_DESCRIPTOR acpi_fadt; + +void __init mp_config_ioapic_for_sci(int irq) +{ + int ioapic; + int ioapic_pin; + struct acpi_table_madt* madt; + struct acpi_table_int_src_ovr *entry = NULL; + void *madt_end; + acpi_status status; + + /* + * Ensure that if there is an interrupt source override entry + * for the ACPI SCI, we leave it as is. Unfortunately this involves + * walking the MADT again. + */ + status = acpi_get_firmware_table("APIC", 1, ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) &madt); + if (ACPI_SUCCESS(status)) { + madt_end = (void *) (unsigned long)madt + madt->header.length; + + entry = (struct acpi_table_int_src_ovr *) + ((unsigned long) madt + sizeof(struct acpi_table_madt)); + + while ((void *) entry < madt_end) { + if (entry->header.type == ACPI_MADT_INT_SRC_OVR && + acpi_fadt.sci_int == entry->global_irq) + return; + + entry = (struct acpi_table_int_src_ovr *) + ((unsigned long) entry + entry->header.length); + } + } + + ioapic = mp_find_ioapic(irq); + + ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; + + io_apic_set_pci_routing(ioapic, ioapic_pin, irq); +} + +#endif /*CONFIG_ACPI_HT_ONLY*/ + +#ifdef CONFIG_ACPI_PCI + +void __init mp_parse_prt (void) +{ + struct list_head *node = NULL; + struct acpi_prt_entry *entry = NULL; + int vector = 0; + int ioapic = -1; + int ioapic_pin = 0; + int irq = 0; + int idx, bit = 0; + + /* + * Parsing through the PCI Interrupt Routing Table (PRT) and program + * routing for all static (IOAPIC-direct) entries. + */ + list_for_each(node, &acpi_prt.entries) { + entry = list_entry(node, struct acpi_prt_entry, node); + + /* Need to get irq for dynamic entry */ + if (entry->link.handle) { + irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index); + if (!irq) + continue; + } else + irq = entry->link.index; + + irq = entry->link.index; + ioapic = mp_find_ioapic(irq); + if (ioapic < 0) + continue; + ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; + + /* + * Avoid pin reprogramming. PRTs typically include entries + * with redundant pin->irq mappings (but unique PCI devices); + * we only only program the IOAPIC on the first. + */ + bit = ioapic_pin % 32; + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); + if (idx > 3) { + printk(KERN_ERR "Invalid reference to IOAPIC pin " + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, + ioapic_pin); + continue; + } + if ((1<irq = irq; + continue; + } + + mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq = irq; + + printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> vector 0x%02x" + " -> IRQ %d\n", entry->id.segment, entry->id.bus, + entry->id.device, ('A' + entry->pin), + mp_ioapic_routing[ioapic].apic_id, ioapic_pin, vector, + entry->irq); + } + + return; +} + +#endif /*CONFIG_ACPI_PCI*/ + +#endif /*CONFIG_X86_IO_APIC*/ + +#endif /*CONFIG_ACPI_BOOT*/ diff -urN linux-2.4.21/arch/x86_64/kernel/pci-dma.c linux-2.4.22/arch/x86_64/kernel/pci-dma.c --- linux-2.4.21/arch/x86_64/kernel/pci-dma.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/pci-dma.c 2003-08-25 04:44:40.000000000 -0700 @@ -37,7 +37,6 @@ */ for (i = 0; i < nents; i++ ) { struct scatterlist *s = &sg[i]; - int flush = (i == nents-1); void *addr = s->address; if (addr) BUG_ON(s->page || s->offset); @@ -45,8 +44,7 @@ addr = page_address(s->page) + s->offset; else BUG(); - s->dma_address = __pci_map_single(hwdev, addr, s->length, - direction, flush); + s->dma_address = pci_map_single(hwdev, addr, s->length, direction); if (unlikely(s->dma_address == bad_dma_address)) goto error; } diff -urN linux-2.4.21/arch/x86_64/kernel/pci-gart.c linux-2.4.22/arch/x86_64/kernel/pci-gart.c --- linux-2.4.21/arch/x86_64/kernel/pci-gart.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/pci-gart.c 2003-08-25 04:44:40.000000000 -0700 @@ -8,25 +8,9 @@ * See Documentation/DMA-mapping.txt for the interface specification. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: pci-gart.c,v 1.20 2003/03/12 08:23:29 ak Exp $ + * $Id: pci-gart.c,v 1.27 2003/08/05 18:25:31 ak Exp $ */ -/* - * Notebook: - -agpgart_be - check if the simple reservation scheme is enough. - -possible future tuning: - fast path for sg streaming mappings - more intelligent flush strategy - flush only a single NB? flush only when - gart area fills up and alloc_iommu wraps. - don't flush on allocation - need to unmap the gart area first to avoid prefetches - by the CPU - move boundary between IOMMU and AGP in GART dynamically - -*/ - #include #include #include @@ -36,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +57,8 @@ #define for_all_nb(dev) \ pci_for_each_dev(dev) \ - if (dev->bus->number == 0 && PCI_FUNC(dev->devfn) == 3 && \ + if (dev->vendor == PCI_VENDOR_ID_AMD && dev->device==0x1103 &&\ + dev->bus->number == 0 && PCI_FUNC(dev->devfn) == 3 && \ (PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31)) #define EMERGENCY_PAGES 32 /* = 128KB */ @@ -90,21 +76,27 @@ static unsigned long next_bit; /* protected by iommu_bitmap_lock */ +static struct pci_dev *northbridges[NR_CPUS + 1]; +static u32 northbridge_flush_word[NR_CPUS + 1]; +static int need_flush; /* global flush state. set for each gart wrap */ static unsigned long alloc_iommu(int size) { unsigned long offset, flags; spin_lock_irqsave(&iommu_bitmap_lock, flags); - offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size); - if (offset == -1) + if (offset == -1) { + need_flush = 1; offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size); + } if (offset != -1) { set_bit_string(iommu_gart_bitmap, offset, size); next_bit = offset+size; - if (next_bit >= iommu_pages) + if (next_bit >= iommu_pages) { + need_flush = 1; next_bit = 0; } + } spin_unlock_irqrestore(&iommu_bitmap_lock, flags); return offset; } @@ -114,20 +106,38 @@ unsigned long flags; spin_lock_irqsave(&iommu_bitmap_lock, flags); clear_bit_string(iommu_gart_bitmap, offset, size); - next_bit = offset; spin_unlock_irqrestore(&iommu_bitmap_lock, flags); } -static inline void flush_gart(void) + +/* + * Use global flush state to avoid races with multiple flushers. + */ +static void __flush_gart(void) { - struct pci_dev *nb; - for_all_nb(nb) { - u32 flag; - pci_read_config_dword(nb, 0x9c, &flag); /* could cache this */ - /* could complain for PTE walk errors here (bit 1 of flag) */ - flag |= 1; - pci_write_config_dword(nb, 0x9c, flag); + unsigned long flags; + int flushed = 0; + int i; + + spin_lock_irqsave(&iommu_bitmap_lock, flags); + /* recheck flush count inside lock */ + if (need_flush) { + for (i = 0; northbridges[i]; i++) { + pci_write_config_dword(northbridges[i], 0x9c, + northbridge_flush_word[i] | 1); + flushed++; + } + if (!flushed) + printk("nothing to flush?\n"); + need_flush = 0; } + spin_unlock_irqrestore(&iommu_bitmap_lock, flags); +} + +static inline void flush_gart(void) +{ + if (need_flush) + __flush_gart(); } void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, @@ -150,9 +160,10 @@ if (memory == NULL) { return NULL; } else { - int high = (unsigned long)virt_to_bus(memory) + size - >= 0xffffffff; - int mmu = high; + int high = 0, mmu; + if (((unsigned long)virt_to_bus(memory) + size) > 0xffffffffUL) + high = 1; + mmu = high; if (force_mmu && !(gfp & GFP_DMA)) mmu = 1; if (no_iommu) { @@ -199,25 +210,22 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t bus) { - u64 pte; unsigned long iommu_page; - int i; size = round_up(size, PAGE_SIZE); - if (bus < iommu_bus_base || bus > iommu_bus_base + iommu_size) { - free_pages((unsigned long)vaddr, get_order(size)); - return; - } - size >>= PAGE_SHIFT; - iommu_page = (bus - iommu_bus_base) / PAGE_SIZE; - for (i = 0; i < size; i++) { - pte = iommu_gatt_base[iommu_page + i]; + if (bus >= iommu_bus_base && bus <= iommu_bus_base + iommu_size) { + unsigned pages = size >> PAGE_SHIFT; + iommu_page = (bus - iommu_bus_base) >> PAGE_SHIFT; + vaddr = __va(GPTE_DECODE(iommu_gatt_base[iommu_page])); + int i; + for (i = 0; i < pages; i++) { + u64 pte = iommu_gatt_base[iommu_page + i]; BUG_ON((pte & GPTE_VALID) == 0); iommu_gatt_base[iommu_page + i] = 0; - free_page((unsigned long) __va(GPTE_DECODE(pte))); } - flush_gart(); - free_iommu(iommu_page, size); + free_iommu(iommu_page, pages); + } + free_pages((unsigned long)vaddr, get_order(size)); } #ifdef CONFIG_IOMMU_LEAK @@ -251,8 +259,7 @@ * Unfortunately the drivers cannot handle this operation properly. * Return some non mapped prereserved space in the aperture and * let the Northbridge deal with it. This will result in garbage - * in the IO operation. When the size exceeds the prereserved space - * memory corruption will occur or random memory will be DMAed + * in the IO operation. When the size exceeds the prereserved spa * memory corruption will occur or random memory will be DMAed * out. Hopefully no network devices use single mappings that big. */ @@ -287,8 +294,8 @@ return mmu; } -dma_addr_t __pci_map_single(struct pci_dev *dev, void *addr, size_t size, - int dir, int flush) +dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, + int dir) { unsigned long iommu_page; unsigned long phys_mem, bus; @@ -318,18 +325,12 @@ */ iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); -#ifdef CONFIG_IOMMU_DEBUG - /* paranoia check */ - BUG_ON(GPTE_DECODE(iommu_gatt_base[iommu_page+i]) != phys_mem); -#endif - #ifdef CONFIG_IOMMU_LEAK /* XXX need eventually caller of pci_map_sg */ if (iommu_leak_tab) iommu_leak_tab[iommu_page + i] = __builtin_return_address(0); #endif } - if (flush) flush_gart(); bus = iommu_bus_base + iommu_page*PAGE_SIZE; @@ -343,12 +344,13 @@ size_t size, int direction) { unsigned long iommu_page; - int i, npages; + int npages; if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || dma_addr > iommu_bus_base + iommu_size) return; iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT; + int i; for (i = 0; i < npages; i++) { iommu_gatt_base[iommu_page + i] = 0; #ifdef CONFIG_IOMMU_LEAK @@ -356,11 +358,10 @@ iommu_leak_tab[iommu_page + i] = 0; #endif } - flush_gart(); free_iommu(iommu_page, npages); } -EXPORT_SYMBOL(__pci_map_single); +EXPORT_SYMBOL(pci_map_single); EXPORT_SYMBOL(pci_unmap_single); static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size) @@ -444,7 +445,7 @@ u32 ctl; u32 gatt_reg; - gatt_reg = ((u64)gatt) >> 12; + gatt_reg = __pa(gatt) >> 12; gatt_reg <<= 4; pci_write_config_dword(dev, 0x98, gatt_reg); pci_read_config_dword(dev, 0x90, &ctl); @@ -534,7 +535,31 @@ iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT); bad_dma_address = iommu_bus_base; + /* + * Unmap the IOMMU part of the GART. The alias of the page is always mapped + * with cache enabled and there is no full cache coherency across the GART + * remapping. The unmapping avoids automatic prefetches from the CPU + * allocating cache lines in there. All CPU accesses are done via the + * direct mapping to the backing memory. The GART address is only used by PCI + * devices. + */ + clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size); + + struct pci_dev *dev; + for_all_nb(dev) { + u32 flag; + int cpu = PCI_SLOT(dev->devfn) - 24; + if (cpu >= NR_CPUS) + continue; + northbridges[cpu] = dev; + + pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */ + northbridge_flush_word[cpu] = flag; + } + asm volatile("wbinvd" ::: "memory"); + + flush_gart(); } /* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]] @@ -543,8 +568,8 @@ off don't use the IOMMU leak turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on) memaper[=order] allocate an own aperture over RAM with size 32MB^order. - noforce don't force IOMMU usage. Should be fastest. - force Force IOMMU and turn on unmap debugging. + noforce don't force IOMMU usage. Default + force Force IOMMU for all devices. */ __init int iommu_setup(char *opt) { diff -urN linux-2.4.21/arch/x86_64/kernel/pci-irq.c linux-2.4.22/arch/x86_64/kernel/pci-irq.c --- linux-2.4.21/arch/x86_64/kernel/pci-irq.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/pci-irq.c 2003-08-25 04:44:40.000000000 -0700 @@ -116,7 +116,7 @@ * Code for querying and setting of IRQ routes on various interrupt routers. */ -static void eisa_set_level_irq(unsigned int irq) +void eisa_set_level_irq(unsigned int irq) { unsigned char mask = 1 << (irq & 7); unsigned int port = 0x4d0 + (irq >> 3); diff -urN linux-2.4.21/arch/x86_64/kernel/pci-pc.c linux-2.4.22/arch/x86_64/kernel/pci-pc.c --- linux-2.4.21/arch/x86_64/kernel/pci-pc.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/arch/x86_64/kernel/pci-pc.c 2003-08-25 04:44:40.000000000 -0700 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,14 @@ struct pci_bus *pci_root_bus; struct pci_ops *pci_root_ops; +int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL; +int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL; + +static int pci_using_acpi_prt = 0; + +/* XXX: not taken by all accesses currently */ +static spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED; + /* * Direct access to PCI hardware... */ @@ -43,6 +52,66 @@ #define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3)) +#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \ + (0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) + +static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, + u32 *value) +{ + unsigned long flags; + + if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + return -EINVAL; + + spin_lock_irqsave(&pci_config_lock, flags); + + outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); + + switch (len) { + case 1: + *value = inb(0xCFC + (reg & 3)); + break; + case 2: + *value = inw(0xCFC + (reg & 2)); + break; + case 4: + *value = inl(0xCFC); + break; + } + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return 0; +} + +static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) +{ + unsigned long flags; + + if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + return -EINVAL; + + spin_lock_irqsave(&pci_config_lock, flags); + + outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); + + switch (len) { + case 1: + outb((u8)value, 0xCFC + (reg & 3)); + break; + case 2: + outw((u16)value, 0xCFC + (reg & 2)); + break; + case 4: + outl((u32)value, 0xCFC); + break; + } + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return 0; +} + static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value) { outl(CONFIG_CMD(dev,where), 0xCF8); @@ -106,6 +175,76 @@ outb(FUNC(dev->devfn), 0xCF8); \ outb(dev->bus->number, 0xCFA); +#define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg) + +static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) +{ + unsigned long flags; + + if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + return -EINVAL; + + if (dev & 0x10) + return PCIBIOS_DEVICE_NOT_FOUND; + + spin_lock_irqsave(&pci_config_lock, flags); + + outb((u8)(0xF0 | (fn << 1)), 0xCF8); + outb((u8)bus, 0xCFA); + + switch (len) { + case 1: + *value = inb(PCI_CONF2_ADDRESS(dev, reg)); + break; + case 2: + *value = inw(PCI_CONF2_ADDRESS(dev, reg)); + break; + case 4: + *value = inl(PCI_CONF2_ADDRESS(dev, reg)); + break; + } + + outb (0, 0xCF8); + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return 0; +} + +static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) +{ + unsigned long flags; + + if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + return -EINVAL; + + if (dev & 0x10) + return PCIBIOS_DEVICE_NOT_FOUND; + + spin_lock_irqsave(&pci_config_lock, flags); + + outb((u8)(0xF0 | (fn << 1)), 0xCF8); + outb((u8)bus, 0xCFA); + + switch (len) { + case 1: + outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg)); + break; + case 2: + outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg)); + break; + case 4: + outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg)); + break; + } + + outb (0, 0xCF8); + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return 0; +} + static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value) { SET(dev); @@ -244,6 +383,23 @@ #endif +struct pci_bus * __devinit pcibios_scan_root(int busnum) +{ + struct list_head *list; + struct pci_bus *bus; + + list_for_each(list, &pci_root_buses) { + bus = pci_bus_b(list); + if (bus->number == busnum) { + /* Already scanned */ + return bus; + } + } + + printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); + + return pci_scan_bus(busnum, pci_root_ops, NULL); +} /* * Several buggy motherboards address only 16 devices and mirror @@ -387,10 +543,38 @@ pci_read_bridge_bases(b); } +void __devinit pcibios_config_init(void) +{ + /* + * Try all known PCI access methods. Note that we support using + * both PCI BIOS and direct access, with a preference for direct. + */ + +#ifdef CONFIG_PCI_DIRECT + if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) + && (pci_root_ops = pci_check_direct())) { + if (pci_root_ops == &pci_direct_conf1) { + pci_config_read = pci_conf1_read; + pci_config_write = pci_conf1_write; + } + else { + pci_config_read = pci_conf2_read; + pci_config_write = pci_conf2_write; + } + } else + printk("??? no pci access\n"); +#endif + + return; +} + void __devinit pcibios_init(void) { struct pci_ops *dir = NULL; + if (!pci_root_ops) + pcibios_config_init(); + #ifdef CONFIG_PCI_DIRECT if (pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) dir = pci_check_direct(); @@ -403,12 +587,18 @@ } printk(KERN_INFO "PCI: Probing PCI hardware\n"); - pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL); - +#ifdef CONFIG_ACPI_PCI + if (!acpi_pci_irq_init()) + pci_using_acpi_prt = 1; +#endif + if (!pci_using_acpi_prt) { + pci_root_bus = pcibios_scan_root(0); pcibios_irq_init(); pci_scan_mptable(); pcibios_fixup_peer_bridges(); pcibios_fixup_irqs(); + } + pcibios_resource_survey(); #ifdef CONFIG_GART_IOMMU @@ -469,6 +659,15 @@ if ((err = pcibios_enable_resources(dev, mask)) < 0) return err; + +#ifdef CONFIG_ACPI_PCI + if (pci_using_acpi_prt) { + acpi_pci_irq_enable(dev); + return 0; + } +#endif + pcibios_enable_irq(dev); + return 0; } diff -urN linux-2.4.21/arch/x86_64/kernel/process.c linux-2.4.22/arch/x86_64/kernel/process.c --- linux-2.4.21/arch/x86_64/kernel/process.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 @@ -9,7 +9,7 @@ * X86-64 port * Andi Kleen. * - * $Id: process.c,v 1.64 2003/03/31 15:11:26 ak Exp $ + * $Id: process.c,v 1.70 2003/06/09 05:18:21 ak Exp $ */ /* @@ -54,6 +54,7 @@ #include #include #include +#include #include @@ -159,34 +160,37 @@ __setup("idle=", idle_setup); static long no_idt[3]; -static int reboot_mode; - -#ifdef CONFIG_SMP -int reboot_smp = 0; -static int reboot_cpu = -1; -#endif +static enum { + BOOT_BIOS = 'b', + BOOT_TRIPLE = 't', + BOOT_KBD = 'k', +} reboot_type = BOOT_KBD; +static int reboot_mode = 0; + +/* reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old] + bios Use the CPU reboto vector for warm reset + warm Don't set the cold reboot flag + cold Set the cold reboto flag + triple Force a triple fault (init) + kbd Use the keyboard controller. cold reset (default) + */ static int __init reboot_setup(char *str) { - while(1) { + for (;;) { switch (*str) { - case 'w': /* "warm" reboot (no memory testing etc) */ + case 'w': reboot_mode = 0x1234; break; - case 'c': /* "cold" reboot (with memory testing etc) */ - reboot_mode = 0x0; + + case 'c': + reboot_mode = 0; break; -#ifdef CONFIG_SMP - case 's': /* "smp" reboot by executing reset on BSP or other CPU*/ - reboot_smp = 1; - if (isdigit(str[1])) - sscanf(str+1, "%d", &reboot_cpu); - else if (!strncmp(str,"smp",3)) - sscanf(str+3, "%d", &reboot_cpu); - /* we will leave sorting out the final value - when we are ready to reboot, since we might not - have set up boot_cpu_id or smp_num_cpu */ + + case 't': + case 'b': + case 'k': + reboot_type = *str; break; -#endif } if((str = strchr(str,',')) != NULL) str++; @@ -195,9 +199,34 @@ } return 1; } - __setup("reboot=", reboot_setup); +/* overwrites random kernel memory. Should not be kernel .text */ +#define WARMBOOT_TRAMP 0x1000UL + +static void reboot_warm(void) +{ + extern unsigned char warm_reboot[], warm_reboot_end[]; + printk("warm reboot\n"); + + __cli(); + + /* restore identity mapping */ + init_level4_pgt[0] = __pml4(__pa(level3_ident_pgt) | 7); + __flush_tlb_all(); + + memcpy(__va(WARMBOOT_TRAMP), warm_reboot, warm_reboot_end - warm_reboot); + + asm volatile( " pushq $0\n" /* ss */ + " pushq $0x2000\n" /* rsp */ + " pushfq\n" /* eflags */ + " pushq %[cs]\n" + " pushq %[target]\n" + " iretq" :: + [cs] "i" (__KERNEL_COMPAT32_CS), + [target] "b" (WARMBOOT_TRAMP)); +} + static inline void kb_wait(void) { int i; @@ -207,60 +236,76 @@ break; } -void machine_restart(char * __unused) + +#ifdef CONFIG_SMP +static void smp_halt(void) { -#if CONFIG_SMP - int cpuid; + int cpuid = safe_smp_processor_id(); + static int first_entry = 1; - cpuid = GET_APIC_ID(apic_read(APIC_ID)); + if (first_entry) { + first_entry = 0; + smp_call_function((void *)machine_restart, NULL, 1, 0); + } - if (reboot_smp) { + smp_stop_cpu(); - /* check to see if reboot_cpu is valid - if its not, default to the BSP */ - if ((reboot_cpu == -1) || - (reboot_cpu > (NR_CPUS -1)) || - !(phys_cpu_present_map & (1<rsp); } diff -urN linux-2.4.21/arch/x86_64/kernel/setup.c linux-2.4.22/arch/x86_64/kernel/setup.c --- linux-2.4.21/arch/x86_64/kernel/setup.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -46,6 +48,8 @@ #include #include +int acpi_disabled __initdata = 0; + /* * Machine setup.. */ @@ -55,6 +59,7 @@ }; unsigned long mmu_cr4_features; +EXPORT_SYMBOL(mmu_cr4_features); /* For PCI or other memory-mapped resources */ unsigned long pci_mem_start = 0x10000000; @@ -271,6 +276,12 @@ kernel_end = round_up(__pa_symbol(&_end), PAGE_SIZE); reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY); +#ifdef CONFIG_ACPI_SLEEP + /* + * Reserve low memory region for sleep support. + */ + acpi_reserve_bootmem(); +#endif #ifdef CONFIG_X86_LOCAL_APIC /* * Find and reserve possible boot-time SMP configuration: @@ -284,6 +295,13 @@ #endif paging_init(); +#ifdef CONFIG_ACPI_BOOT + /* + * Parse the ACPI tables for possible boot-time SMP configuration. + */ + if (!acpi_disabled) + acpi_boot_init(); +#endif #ifdef CONFIG_X86_LOCAL_APIC /* * get boot-time SMP configuration: diff -urN linux-2.4.21/arch/x86_64/kernel/setup64.c linux-2.4.22/arch/x86_64/kernel/setup64.c --- linux-2.4.21/arch/x86_64/kernel/setup64.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/setup64.c 2003-08-25 04:44:40.000000000 -0700 @@ -3,7 +3,7 @@ * Copyright (C) 1995 Linus Torvalds * Copyright 2001, 2002 SuSE Labs / Andi Kleen. * See setup.c for older changelog. - * $Id: setup64.c,v 1.19 2003/02/21 19:37:21 ak Exp $ + * $Id: setup64.c,v 1.23 2003/05/16 14:22:27 ak Exp $ */ #include #include @@ -18,6 +18,7 @@ #include #include #include +#include char x86_boot_params[2048] __initdata = {0,}; @@ -31,24 +32,82 @@ struct desc_ptr gdt_descr = { 0 /* filled in */, (unsigned long) gdt_table }; struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; +/* When you change the default make sure the no EFER path below sets the + correct flags everywhere. */ unsigned long __supported_pte_mask = ~0UL; -static int do_not_nx = 1; +static int do_not_nx __initdata = 0; +unsigned long vm_stack_flags = __VM_STACK_FLAGS; +unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; +unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; +unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; +unsigned long vm_force_exec32 = PROT_EXEC; char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned; +/* noexec=on|off + +on Enable +off Disable +noforce (default) Don't enable by default for heap/stack/data, + but allow PROT_EXEC to be effective + +*/ + static int __init nonx_setup(char *str) { - if (!strncmp(str,"off",3)) { - __supported_pte_mask &= ~_PAGE_NX; - do_not_nx = 1; - } else if (!strncmp(str, "on",3)) { - do_not_nx = 0; + if (!strncmp(str, "on",3)) { __supported_pte_mask |= _PAGE_NX; + do_not_nx = 0; + vm_data_default_flags &= ~VM_EXEC; + vm_stack_flags &= ~VM_EXEC; + } else if (!strncmp(str, "noforce",7) || !strncmp(str,"off",3)) { + do_not_nx = (str[0] == 'o'); + if (do_not_nx) + __supported_pte_mask &= ~_PAGE_NX; + vm_data_default_flags |= VM_EXEC; + vm_stack_flags |= VM_EXEC; + } + return 1; +} + +/* noexec32=opt{,opt} + +Control the no exec default for 32bit processes. Can be also overwritten +per executable using ELF header flags (e.g. needed for the X server) +Requires noexec=on or noexec=noforce to be effective. + +Valid options: + all,on Heap,stack,data is non executable. + off (default) Heap,stack,data is executable + stack Stack is non executable, heap/data is. + force Don't imply PROT_EXEC for PROT_READ + compat (default) Imply PROT_EXEC for PROT_READ + +*/ +static int __init nonx32_setup(char *str) +{ + char *s; + while ((s = strsep(&str, ",")) != NULL) { + if (!strcmp(s, "all") || !strcmp(s,"on")) { + vm_data_default_flags32 &= ~VM_EXEC; + vm_stack_flags32 &= ~VM_EXEC; + } else if (!strcmp(s, "off")) { + vm_data_default_flags32 |= VM_EXEC; + vm_stack_flags32 |= VM_EXEC; + } else if (!strcmp(s, "stack")) { + vm_data_default_flags32 |= VM_EXEC; + vm_stack_flags32 &= ~VM_EXEC; + } else if (!strcmp(s, "force")) { + vm_force_exec32 = 0; + } else if (!strcmp(s, "compat")) { + vm_force_exec32 = PROT_EXEC; + } } return 1; } __setup("noexec=", nonx_setup); +__setup("noexec32=", nonx32_setup); void pda_init(int cpu) { @@ -84,6 +143,21 @@ wrmsrl(MSR_GS_BASE, cpu_pda + cpu); } +void syscall_init(void) +{ + /* + * LSTAR and STAR live in a bit strange symbiosis. + * They both write to the same internal register. STAR allows to set CS/DS + * but only a 32bit target. LSTAR sets the 64bit rip. + */ + wrmsrl(MSR_STAR, ((u64)__USER32_CS)<<48 | ((u64)__KERNEL_CS)<<32); + wrmsrl(MSR_LSTAR, system_call); + +#ifdef CONFIG_IA32_EMULATION + wrmsrl(MSR_CSTAR, ia32_cstar_target); +#endif +} + #define EXCEPTION_STK_ORDER 0 /* >= N_EXCEPTION_STACKS*EXCEPTION_STKSZ */ char boot_exception_stacks[N_EXCEPTION_STACKS*EXCEPTION_STKSZ]; @@ -132,21 +206,13 @@ asm volatile("pushfq ; popq %%rax ; btr $14,%%rax ; pushq %%rax ; popfq" ::: "eax"); - /* - * LSTAR and STAR live in a bit strange symbiosis. - * They both write to the same internal register. STAR allows to set CS/DS - * but only a 32bit target. LSTAR sets the 64bit rip. - */ - wrmsrl(MSR_STAR, ((u64)__USER32_CS)<<48 | ((u64)__KERNEL_CS)<<32); - wrmsrl(MSR_LSTAR, system_call); - -#ifdef CONFIG_IA32_EMULATION - wrmsrl(MSR_CSTAR, ia32_cstar_target); -#endif + syscall_init(); rdmsrl(MSR_EFER, efer); if (!(efer & EFER_NX) || do_not_nx) { __supported_pte_mask &= ~_PAGE_NX; + } else { + __supported_pte_mask |= _PAGE_NX; } t->io_map_base = INVALID_IO_BITMAP_OFFSET; diff -urN linux-2.4.21/arch/x86_64/kernel/smp.c linux-2.4.22/arch/x86_64/kernel/smp.c --- linux-2.4.21/arch/x86_64/kernel/smp.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/smp.c 2003-08-25 04:44:40.000000000 -0700 @@ -488,7 +488,7 @@ return 0; } -static void stop_this_cpu (void * dummy) +void smp_stop_cpu(void) { /* * Remove this CPU: @@ -496,8 +496,14 @@ clear_bit(smp_processor_id(), &cpu_online_map); __cli(); disable_local_APIC(); - for(;;) __asm__("hlt"); - for (;;); + __sti(); +} + +static void smp_really_stop_cpu(void *dummy) +{ + smp_stop_cpu(); + for (;;) + asm("hlt"); } /* @@ -506,12 +512,8 @@ void smp_send_stop(void) { - smp_call_function(stop_this_cpu, NULL, 1, 0); - smp_num_cpus = 1; - - __cli(); - disable_local_APIC(); - __sti(); + smp_call_function(smp_really_stop_cpu, NULL, 1, 0); + smp_stop_cpu(); } /* diff -urN linux-2.4.21/arch/x86_64/kernel/suspend.c linux-2.4.22/arch/x86_64/kernel/suspend.c --- linux-2.4.21/arch/x86_64/kernel/suspend.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/x86_64/kernel/suspend.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,169 @@ +/* + * Suspend support specific for i386. + * + * Distribute under GPLv2 + * + * Copyright (c) 2002 Pavel Machek + * Copyright (c) 2001 Patrick Mochel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void fix_processor_context(void); + +/* Image of the saved processor state. If you touch this, fix acpi_wakeup.S. */ +struct saved_context { + u16 ds, es, fs, gs, ss; + unsigned long gs_base, gs_kernel_base, fs_base; + unsigned long cr0, cr2, cr3, cr4; + u16 gdt_pad; + u16 gdt_limit; + unsigned long gdt_base; + u16 idt_pad; + u16 idt_limit; + unsigned long idt_base; + u16 ldt; + u16 tss; + unsigned long tr; + unsigned long safety; + unsigned long return_address; + unsigned long eflags; +} __attribute__((packed)); + +struct saved_context saved_context; + +unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx; +unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi; +unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11; +unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15; +unsigned long saved_context_eflags; + +void save_processor_state (void) +{ + kernel_fpu_begin(); + + /* + * descriptor tables + */ + asm volatile ("sgdt %0" : "=m" (saved_context.gdt_limit)); + asm volatile ("sidt %0" : "=m" (saved_context.idt_limit)); + asm volatile ("sldt %0" : "=m" (saved_context.ldt)); + asm volatile ("str %0" : "=m" (saved_context.tr)); + + /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ + /* EFER should be constant for kernel version, no need to handle it. */ + /* + * segment registers + */ + asm volatile ("movw %%ds, %0" : "=m" (saved_context.ds)); + asm volatile ("movw %%es, %0" : "=m" (saved_context.es)); + asm volatile ("movw %%fs, %0" : "=m" (saved_context.fs)); + asm volatile ("movw %%gs, %0" : "=m" (saved_context.gs)); + asm volatile ("movw %%ss, %0" : "=m" (saved_context.ss)); + + rdmsrl(MSR_FS_BASE, saved_context.fs_base); + rdmsrl(MSR_GS_BASE, saved_context.gs_base); + rdmsrl(MSR_KERNEL_GS_BASE, saved_context.gs_kernel_base); + + /* + * control registers + */ + asm volatile ("movq %%cr0, %0" : "=r" (saved_context.cr0)); + asm volatile ("movq %%cr2, %0" : "=r" (saved_context.cr2)); + asm volatile ("movq %%cr3, %0" : "=r" (saved_context.cr3)); + asm volatile ("movq %%cr4, %0" : "=r" (saved_context.cr4)); +} + +static void +do_fpu_end(void) +{ + /* restore FPU regs if necessary */ + kernel_fpu_end(); +} + +void restore_processor_state(void) +{ + /* + * control registers + */ + asm volatile ("movq %0, %%cr4" :: "r" (saved_context.cr4)); + asm volatile ("movq %0, %%cr3" :: "r" (saved_context.cr3)); + asm volatile ("movq %0, %%cr2" :: "r" (saved_context.cr2)); + asm volatile ("movq %0, %%cr0" :: "r" (saved_context.cr0)); + + /* + * segment registers + */ + asm volatile ("movw %0, %%ds" :: "r" (saved_context.ds)); + asm volatile ("movw %0, %%es" :: "r" (saved_context.es)); + asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs)); + load_gs_index(saved_context.gs); + asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss)); + + wrmsrl(MSR_FS_BASE, saved_context.fs_base); + wrmsrl(MSR_GS_BASE, saved_context.gs_base); + wrmsrl(MSR_KERNEL_GS_BASE, saved_context.gs_kernel_base); + + /* + * now restore the descriptor tables to their proper values + * ltr is done i fix_processor_context(). + */ + asm volatile ("lgdt %0" :: "m" (saved_context.gdt_limit)); + asm volatile ("lidt %0" :: "m" (saved_context.idt_limit)); + asm volatile ("lldt %0" :: "m" (saved_context.ldt)); + + fix_processor_context(); + + do_fpu_end(); +} + +#define loaddebug(thread,register) \ + set_debug((thread)->debugreg[register], register) + +void fix_processor_context(void) +{ + int cpu = smp_processor_id(); + struct tss_struct * t = init_tss + cpu; + + set_tss_desc(cpu,t); + + /* clear busy TSS */ + gdt_cpu_table[cpu].tss.type = 9; + + syscall_init(); /* This sets MSR_*STAR and related */ + load_TR(cpu); /* This does ltr */ + load_LDT(current->active_mm); /* This does lldt */ + + /* + * Now maybe reload the debug registers + */ + if (current->thread.debugreg[7]){ + loaddebug(¤t->thread, 0); + loaddebug(¤t->thread, 1); + loaddebug(¤t->thread, 2); + loaddebug(¤t->thread, 3); + /* no 4 and 5 */ + loaddebug(¤t->thread, 6); + loaddebug(¤t->thread, 7); + } + +} + + diff -urN linux-2.4.21/arch/x86_64/kernel/time.c linux-2.4.22/arch/x86_64/kernel/time.c --- linux-2.4.21/arch/x86_64/kernel/time.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 @@ -63,6 +63,11 @@ return ((hpet_readl(HPET_COUNTER) - vxtime.last) * vxtime.quot) >> 32; } +static unsigned int do_gettimeoffset_nop(void) +{ + return 0; +} + unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; /* @@ -482,14 +487,10 @@ static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; -extern void __init config_acpi_tables(void); - void __init time_init(void) { char *timename; - config_acpi_tables(); - #ifdef HPET_HACK_ENABLE_DANGEROUS if (!hpet_address) { printk(KERN_WARNING "time.c: WARNING: Enabling HPET base manually!\n"); @@ -546,12 +547,17 @@ } else { timetype = "HPET/TSC"; vxtime.mode = VXTIME_TSC; - do_gettimeoffset = do_gettimeoffset_tsc; } } else { + if (notsc) { + timetype = "PIT"; + vxtime.mode = VXTIME_STUPID; + do_gettimeoffset = do_gettimeoffset_nop; + } else { timetype = "PIT/TSC"; vxtime.mode = VXTIME_TSC; } + } printk(KERN_INFO "time.c: Using %s based timekeeping.\n", timetype); } diff -urN linux-2.4.21/arch/x86_64/kernel/traps.c linux-2.4.22/arch/x86_64/kernel/traps.c --- linux-2.4.21/arch/x86_64/kernel/traps.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 @@ -7,7 +7,7 @@ * Pentium III FXSR, SSE support * Gareth Hughes , May 2000 * - * $Id: traps.c,v 1.62 2003/03/14 16:06:35 ak Exp $ + * $Id: traps.c,v 1.66 2003/06/09 05:18:21 ak Exp $ */ /* @@ -290,7 +290,7 @@ rsp = regs->rsp; } printk("CPU %d ", cpu); - show_regs(regs); + __show_regs(regs); printk("Process %s (pid: %d, stackpage=%08lx)\n", cur->comm, cur->pid, 4096+(unsigned long)cur); @@ -344,6 +344,7 @@ void die(const char * str, struct pt_regs * regs, long err) { + unsigned long flags; int cpu; console_verbose(); bust_spinlocks(1); @@ -352,6 +353,7 @@ notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); cpu = safe_smp_processor_id(); /* racy, but better than risking deadlock. */ + __save_flags(flags); __cli(); if (!spin_trylock(&die_lock)) { if (cpu == die_owner) @@ -362,7 +364,7 @@ die_owner = cpu; show_registers(regs); bust_spinlocks(0); - spin_unlock_irq(&die_lock); + spin_unlock_irqrestore(&die_lock, flags); do_exit(SIGSEGV); } @@ -402,8 +404,11 @@ struct task_struct *tsk = current; tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; - if (exception_trace && trapnr != 3) - printk("%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", + if (exception_trace && !(tsk->ptrace & PT_PTRACED) && + (tsk->sig->action[signr-1].sa.sa_handler == SIG_IGN || + (tsk->sig->action[signr-1].sa.sa_handler == SIG_DFL))) + printk(KERN_INFO + "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", tsk->comm, tsk->pid, str, regs->rip,regs->rsp,error_code); if (info) @@ -418,7 +423,6 @@ { unsigned long fixup = search_exception_table(regs->rip); if (fixup) { - extern int exception_trace; regs->rip = fixup; } else die(str, regs, error_code); @@ -478,20 +482,25 @@ by the segment reloads in __switch_to. Otherwise the wake_up could deadlock on scheduler locks. */ oops_in_progress++; - printk("general protection handler: wrong gs %lx expected %p\n", gs, pda); + printk(KERN_EMERG + "general protection handler: wrong gs %lx expected %p\n", gs, pda); oops_in_progress--; } } #endif if (regs->cs & 3) { - current->thread.error_code = error_code; - current->thread.trap_no = 13; - if (exception_trace) - printk("%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", - current->comm, current->pid, + struct task_struct *tsk = current; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + if (exception_trace && !(tsk->ptrace & PT_PTRACED) && + (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_IGN || + (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_DFL))) + printk(KERN_INFO + "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", + tsk->comm, tsk->pid, regs->rip,regs->rsp,error_code); - force_sig(SIGSEGV, current); + force_sig(SIGSEGV, tsk); return; } @@ -594,7 +603,7 @@ rdmsrl(MSR_GS_BASE, gs); if (gs != (unsigned long)pda) { wrmsrl(MSR_GS_BASE, pda); - printk("debug handler: wrong gs %lx expected %p\n", gs, pda); + printk(KERN_EMERG "debug handler: wrong gs %lx expected %p\n", gs, pda); } } #endif @@ -809,7 +818,7 @@ #ifndef CONFIG_MCE void do_machine_check(struct pt_regs *regs) { - printk("Machine check ignored\n"); + printk(KERN_INFO "Machine check ignored\n"); } #endif @@ -837,7 +846,7 @@ set_intr_gate(19,&simd_coprocessor_error); #ifdef CONFIG_IA32_EMULATION - set_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall); + set_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall); #endif /* diff -urN linux-2.4.21/arch/x86_64/kernel/warmreboot.S linux-2.4.22/arch/x86_64/kernel/warmreboot.S --- linux-2.4.21/arch/x86_64/kernel/warmreboot.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/arch/x86_64/kernel/warmreboot.S 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,83 @@ +/* + * Switch back to real mode and call the BIOS reboot vector. + * This is a trampoline copied around in process.c + * Written 2003 by Andi Kleen, SuSE Labs. + */ + +#include + +#define R(x) x-warm_reboot(%ebx) +#define R64(x) x-warm_reboot(%rbx) + + /* running in identity mapping and in the first 64k of memory + and in compatibility mode. This must be position independent */ + + /* Follows 14.7 "Leaving Long Mode" in the AMD x86-64 manual, volume 2 + and 8.9.2 "Switching Back to Real-Address Mode" in the Intel IA32 + manual, volume 2 */ + + /* ebx: self pointer to warm_reboot */ + + .globl warm_reboot +warm_reboot: + addl %ebx, R64(real_mode_desc) /* relocate tables */ + addl %ebx,2+R64(warm_gdt_desc) + + movq %cr0,%rax + btr $31,%rax + movq %rax,%cr0 /* disable paging */ + jmp 1f /* flush prefetch queue */ + + .code32 +1: movl $MSR_EFER,%ecx + rdmsr + andl $~((1<<_EFER_LME)|(1<<_EFER_SCE)|(1<<_EFER_NX)),%eax + wrmsr /* disable long mode in EFER */ + + xorl %eax,%eax + movl %eax,%cr3 /* flush tlb */ + + /* Running protected mode without paging now */ + + wbinvd /* flush caches. Needed? */ + + lidt R(warm_idt_desc) + lgdt R(warm_gdt_desc) + + movl $0x10,%ecx /* load segment registers with real mode settings */ + movl %ecx,%ds + movl %ecx,%es + movl %ecx,%fs + movl %ecx,%gs + movl %ecx,%ss + + lea R(real_mode_desc),%eax + ljmp *(%eax) + + .code16: +real_mode: + xorl %eax,%eax + movl %eax,%cr0 + + /* some people claim $0xf000,0xfff0 is better. Use what 32bit linux uses. */ + /* code as bytes because gas has problems with it */ + .byte 0xea,0xf0,0xff,0x00,0xf0 /* ljmp 0xf000:0xfff0 */ + +real_mode_desc: + .long real_mode - warm_reboot + .short 8 +warm_gdt_desc: + .short 8*3 + .long warm_gdt - warm_reboot +warm_gdt: + .quad 0 + .quad 0x00009a000000ffff /* 16-bit real-mode 64k code at 0x00000000 */ + .quad 0x000092000100ffff /* 16-bit real-mode 64k data at 0x00000100 */ + +warm_idt_desc: + .short 0x3ff + .long 0 + + .globl warm_reboot_end +warm_reboot_end: + diff -urN linux-2.4.21/arch/x86_64/mm/fault.c linux-2.4.22/arch/x86_64/mm/fault.c --- linux-2.4.21/arch/x86_64/mm/fault.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 @@ -229,9 +229,12 @@ /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { - if (exception_trace) - printk("%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n", - current->comm, current->pid, address, regs->rip, + if (exception_trace && !(tsk->ptrace & PT_PTRACED) && + (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_IGN || + (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_DFL))) + printk(KERN_INFO + "%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n", + tsk->comm, tsk->pid, address, regs->rip, regs->rsp, error_code); tsk->thread.cr2 = address; @@ -253,7 +256,7 @@ if (0 && exception_trace) printk(KERN_ERR "%s: fixed kernel exception at %lx address %lx err:%ld\n", - current->comm, regs->rip, address, error_code); + tsk->comm, regs->rip, address, error_code); return; } @@ -265,6 +268,21 @@ console_verbose(); bust_spinlocks(1); + int cpu = safe_smp_processor_id(); + unsigned long flags; + extern int die_owner; + extern spinlock_t die_lock; + + __save_flags(flags); + __cli(); + if (!spin_trylock(&die_lock)) { + if (cpu == die_owner) + /* nested oops. should stop eventually */; + else + spin_lock(&die_lock); + } + die_owner = cpu; + if (address < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); else @@ -275,6 +293,7 @@ dump_pagetable(address); die("Oops", regs, error_code); bust_spinlocks(0); + spin_unlock_irqrestore(&die_lock, flags); do_exit(SIGKILL); /* diff -urN linux-2.4.21/arch/x86_64/mm/init.c linux-2.4.22/arch/x86_64/mm/init.c --- linux-2.4.21/arch/x86_64/mm/init.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 @@ -418,35 +418,31 @@ #endif } -void __init __map_kernel_range(void *address, int len, pgprot_t prot) +/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches + from the CPU leading to inconsistent cache lines. address and size + must be aligned to 2MB boundaries. + Does nothing when the mapping doesn't exist. */ +void __init clear_kernel_mapping(unsigned long address, unsigned long size) { - int i; - void *end = address + len; - BUG_ON((pgprot_val(prot) & _PAGE_PSE) == 0); - address = (void *)((unsigned long)address & LARGE_PAGE_MASK); + unsigned long end = address + size; + + BUG_ON(address & ~LARGE_PAGE_MASK); + BUG_ON(size & ~LARGE_PAGE_MASK); + for (; address < end; address += LARGE_PAGE_SIZE) { - pml4_t *pml4; - pgd_t *pgd; - pmd_t *pmd; - - pml4 = pml4_offset_k((unsigned long) address); - if (pml4_none(*pml4)) { - void *p = (void *)get_zeroed_page(GFP_KERNEL); - if (!p) panic("Cannot map kernel range"); - for (i = 0; i < smp_num_cpus; i++) { - set_pml4((pml4_t *)(cpu_pda[i].level4_pgt) + - pml4_index((unsigned long)address), - mk_kernel_pml4(virt_to_phys(p),KERNPG_TABLE)); - } - } - pgd = pgd_offset_k((unsigned long)address); - if (pgd_none(*pgd)) { - void *p = (void *)get_zeroed_page(GFP_KERNEL); - if (!p) panic("Cannot map kernel range"); - set_pgd(pgd, __mk_pgd(virt_to_phys(p), KERNPG_TABLE)); + pgd_t *pgd = pgd_offset_k(address); + if (!pgd || pgd_none(*pgd)) + continue; + pmd_t *pmd = pmd_offset(pgd, address); + if (!pmd || pmd_none(*pmd)) + continue; + if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { + /* Could handle this, but it should not happen currently. */ + printk(KERN_ERR + "clear_kernel_mapping: mapping has been split. will leak memory\n"); + pmd_ERROR(*pmd); } - pmd = pmd_offset(pgd, (unsigned long) address); - set_pmd(pmd, __mk_pmd(virt_to_phys(address), prot)); + set_pmd(pmd, __pmd(0)); } __flush_tlb_all(); } diff -urN linux-2.4.21/arch/x86_64/mm/k8topology.c linux-2.4.22/arch/x86_64/mm/k8topology.c --- linux-2.4.21/arch/x86_64/mm/k8topology.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/arch/x86_64/mm/k8topology.c 2003-08-25 04:44:40.000000000 -0700 @@ -176,10 +176,27 @@ } printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); - for_all_nodes(i) { + for (i = 0; i < MAXNODE; i++) { + if (nodes[i].start != nodes[i].end) setup_node_bootmem(i, nodes[i].start, nodes[i].end); } + /* There are unfortunately some poorly designed mainboards around + that only connect memory to a single CPU. This breaks the 1:1 cpu->node + mapping. To avoid this fill in the mapping for all possible + CPUs, as the number of CPUs is not known yet. + We round robin the existing nodes. */ + int rr = 0; + for (i = 0; i < MAXNODE; i++) { + if (nodes[i].start != nodes[i].end) + continue; + if ((nodes_present >> rr) == 0) + rr = 0; + rr = ffz(~nodes_present >> rr); + PLAT_NODE_DATA(i) = PLAT_NODE_DATA(rr); + rr++; + } + return 0; } diff -urN linux-2.4.21/crypto/Config.in linux-2.4.22/crypto/Config.in --- linux-2.4.21/crypto/Config.in 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/Config.in 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,84 @@ +# +# Cryptographic API Configuration +# +mainmenu_option next_comment +comment 'Cryptographic options' + +if [ "$CONFIG_INET_AH" = "y" -o \ + "$CONFIG_INET_AH" = "m" -o \ + "$CONFIG_INET_ESP" = "y" -o \ + "$CONFIG_INET_ESP" = "m" -o \ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ + "$CONFIG_INET6_ESP" = "m" ]; then + define_bool CONFIG_CRYPTO y +else + bool 'Cryptographic API' CONFIG_CRYPTO +fi + +if [ "$CONFIG_CRYPTO" = "y" ]; then + if [ "$CONFIG_INET_AH" = "y" -o \ + "$CONFIG_INET_AH" = "m" -o \ + "$CONFIG_INET_ESP" = "y" -o \ + "$CONFIG_INET_ESP" = "m" -o \ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ + "$CONFIG_INET6_ESP" = "m" ]; then + define_bool CONFIG_CRYPTO_HMAC y + else + bool ' HMAC support' CONFIG_CRYPTO_HMAC + fi + tristate ' NULL algorithms' CONFIG_CRYPTO_NULL + tristate ' MD4 digest algorithm' CONFIG_CRYPTO_MD4 + if [ "$CONFIG_INET_AH" = "y" -o \ + "$CONFIG_INET_AH" = "m" -o \ + "$CONFIG_INET_ESP" = "y" -o \ + "$CONFIG_INET_ESP" = "m" -o \ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ + "$CONFIG_INET6_ESP" = "m" ]; then + define_bool CONFIG_CRYPTO_MD5 y + else + tristate ' MD5 digest algorithm' CONFIG_CRYPTO_MD5 + fi + if [ "$CONFIG_INET_AH" = "y" -o \ + "$CONFIG_INET_AH" = "m" -o \ + "$CONFIG_INET_ESP" = "y" -o \ + "$CONFIG_INET_ESP" = "m" -o \ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ + "$CONFIG_INET6_ESP" = "m" ]; then + define_bool CONFIG_CRYPTO_SHA1 y + else + tristate ' SHA1 digest algorithm' CONFIG_CRYPTO_SHA1 + fi + tristate ' SHA256 digest algorithm' CONFIG_CRYPTO_SHA256 + tristate ' SHA384 and SHA512 digest algorithms' CONFIG_CRYPTO_SHA512 + if [ "$CONFIG_INET_ESP" = "y" -o \ + "$CONFIG_INET_ESP" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ + "$CONFIG_INET6_ESP" = "m" ]; then + define_bool CONFIG_CRYPTO_DES y + else + tristate ' DES and Triple DES EDE cipher algorithms' CONFIG_CRYPTO_DES + fi + tristate ' Blowfish cipher algorithm' CONFIG_CRYPTO_BLOWFISH + tristate ' Twofish cipher algorithm' CONFIG_CRYPTO_TWOFISH + tristate ' Serpent cipher algorithm' CONFIG_CRYPTO_SERPENT + tristate ' AES cipher algorithms' CONFIG_CRYPTO_AES + if [ "$CONFIG_INET_IPCOMP" = "y" -o \ + "$CONFIG_INET_IPCOMP" = "m" -o \ + "$CONFIG_INET6_IPCOMP" = "y" -o \ + "$CONFIG_INET6_IPCOMP" = "m" ]; then + define_bool CONFIG_CRYPTO_DEFLATE y + else + tristate ' Deflate compression algorithm' CONFIG_CRYPTO_DEFLATE + fi + tristate ' Testing module' CONFIG_CRYPTO_TEST +fi + +endmenu diff -urN linux-2.4.21/crypto/Makefile linux-2.4.22/crypto/Makefile --- linux-2.4.21/crypto/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,31 @@ +# +# Cryptographic API +# + +O_TARGET := crypto.o + +export-objs := api.o hmac.o + +autoload-crypto-$(CONFIG_KMOD) = autoload.o +proc-crypto-$(CONFIG_PROC_FS) = proc.o + +obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \ + $(autoload-crypto-y) $(proc-crypto-y) + +obj-$(CONFIG_CRYPTO_HMAC) += hmac.o +obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o +obj-$(CONFIG_CRYPTO_MD4) += md4.o +obj-$(CONFIG_CRYPTO_MD5) += md5.o +obj-$(CONFIG_CRYPTO_SHA1) += sha1.o +obj-$(CONFIG_CRYPTO_SHA256) += sha256.o +obj-$(CONFIG_CRYPTO_SHA512) += sha512.o +obj-$(CONFIG_CRYPTO_DES) += des.o +obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o +obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o +obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o +obj-$(CONFIG_CRYPTO_AES) += aes.o +obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o + +obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/crypto/aes.c linux-2.4.22/crypto/aes.c --- linux-2.4.21/crypto/aes.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/aes.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,469 @@ +/* + * Cryptographic API. + * + * AES Cipher Algorithm. + * + * Based on Brian Gladman's code. + * + * Linux developers: + * Alexander Kjeldaas + * Herbert Valerio Riedel + * Kyle McMartin + * Adam J. Richter (conversion to 2.5 API). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * --------------------------------------------------------------------------- + * Copyright (c) 2002, Dr Brian Gladman , Worcester, UK. + * All rights reserved. + * + * LICENSE TERMS + * + * The free distribution and use of this software in both source and binary + * form is allowed (with or without changes) provided that: + * + * 1. distributions of this source code include the above copyright + * notice, this list of conditions and the following disclaimer; + * + * 2. distributions in binary form include the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other associated materials; + * + * 3. the copyright holder's name is not used to endorse products + * built using this software without specific written permission. + * + * ALTERNATIVELY, provided that this notice is retained in full, this product + * may be distributed under the terms of the GNU General Public License (GPL), + * in which case the provisions of the GPL apply INSTEAD OF those given above. + * + * DISCLAIMER + * + * This software is provided 'as is' with no explicit or implied warranties + * in respect of its properties, including, but not limited to, correctness + * and/or fitness for purpose. + * --------------------------------------------------------------------------- + */ + +/* Some changes from the Gladman version: + s/RIJNDAEL(e_key)/E_KEY/g + s/RIJNDAEL(d_key)/D_KEY/g +*/ + +#include +#include +#include +#include +#include +#include + +#define AES_MIN_KEY_SIZE 16 +#define AES_MAX_KEY_SIZE 32 + +#define AES_BLOCK_SIZE 16 + +static inline +u32 generic_rotr32 (const u32 x, const unsigned bits) +{ + const unsigned n = bits % 32; + return (x >> n) | (x << (32 - n)); +} + +static inline +u32 generic_rotl32 (const u32 x, const unsigned bits) +{ + const unsigned n = bits % 32; + return (x << n) | (x >> (32 - n)); +} + +#define rotl generic_rotl32 +#define rotr generic_rotr32 + +/* + * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) + */ +inline static u8 +byte(const u32 x, const unsigned n) +{ + return x >> (n << 3); +} + +#define u32_in(x) le32_to_cpu(*(const u32 *)(x)) +#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from)) + +struct aes_ctx { + int key_length; + u32 E[60]; + u32 D[60]; +}; + +#define E_KEY ctx->E +#define D_KEY ctx->D + +static u8 pow_tab[256]; +static u8 log_tab[256]; +static u8 sbx_tab[256]; +static u8 isb_tab[256]; +static u32 rco_tab[10]; +static u32 ft_tab[4][256]; +static u32 it_tab[4][256]; + +static u32 fl_tab[4][256]; +static u32 il_tab[4][256]; + +static inline u8 +f_mult (u8 a, u8 b) +{ + u8 aa = log_tab[a], cc = aa + log_tab[b]; + + return pow_tab[cc + (cc < aa ? 1 : 0)]; +} + +#define ff_mult(a,b) (a && b ? f_mult(a, b) : 0) + +#define f_rn(bo, bi, n, k) \ + bo[n] = ft_tab[0][byte(bi[n],0)] ^ \ + ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rn(bo, bi, n, k) \ + bo[n] = it_tab[0][byte(bi[n],0)] ^ \ + it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +#define ls_box(x) \ + ( fl_tab[0][byte(x, 0)] ^ \ + fl_tab[1][byte(x, 1)] ^ \ + fl_tab[2][byte(x, 2)] ^ \ + fl_tab[3][byte(x, 3)] ) + +#define f_rl(bo, bi, n, k) \ + bo[n] = fl_tab[0][byte(bi[n],0)] ^ \ + fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rl(bo, bi, n, k) \ + bo[n] = il_tab[0][byte(bi[n],0)] ^ \ + il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +static void +gen_tabs (void) +{ + u32 i, t; + u8 p, q; + + /* log and power tables for GF(2**8) finite field with + 0x011b as modular polynomial - the simplest prmitive + root is 0x03, used here to generate the tables */ + + for (i = 0, p = 1; i < 256; ++i) { + pow_tab[i] = (u8) p; + log_tab[p] = (u8) i; + + p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; + + for (i = 0, p = 1; i < 10; ++i) { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + for (i = 0; i < 256; ++i) { + p = (i ? pow_tab[255 - log_tab[i]] : 0); + q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); + p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); + sbx_tab[i] = p; + isb_tab[p] = (u8) i; + } + + for (i = 0; i < 256; ++i) { + p = sbx_tab[i]; + + t = p; + fl_tab[0][i] = t; + fl_tab[1][i] = rotl (t, 8); + fl_tab[2][i] = rotl (t, 16); + fl_tab[3][i] = rotl (t, 24); + + t = ((u32) ff_mult (2, p)) | + ((u32) p << 8) | + ((u32) p << 16) | ((u32) ff_mult (3, p) << 24); + + ft_tab[0][i] = t; + ft_tab[1][i] = rotl (t, 8); + ft_tab[2][i] = rotl (t, 16); + ft_tab[3][i] = rotl (t, 24); + + p = isb_tab[i]; + + t = p; + il_tab[0][i] = t; + il_tab[1][i] = rotl (t, 8); + il_tab[2][i] = rotl (t, 16); + il_tab[3][i] = rotl (t, 24); + + t = ((u32) ff_mult (14, p)) | + ((u32) ff_mult (9, p) << 8) | + ((u32) ff_mult (13, p) << 16) | + ((u32) ff_mult (11, p) << 24); + + it_tab[0][i] = t; + it_tab[1][i] = rotl (t, 8); + it_tab[2][i] = rotl (t, 16); + it_tab[3][i] = rotl (t, 24); + } +} + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y,x) \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= rotr(u ^ t, 8) ^ \ + rotr(v ^ t, 16) ^ \ + rotr(t,24) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \ + t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \ + t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \ + t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \ +} + +#define loop6(i) \ +{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \ + t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \ + t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \ + t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \ + t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \ + t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \ +} + +#define loop8(i) \ +{ t = rotr(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \ + t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \ + t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \ + t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \ + t = E_KEY[8 * i + 4] ^ ls_box(t); \ + E_KEY[8 * i + 12] = t; \ + t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \ + t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \ + t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ +} + +static int +aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) +{ + struct aes_ctx *ctx = ctx_arg; + u32 i, t, u, v, w; + + if (key_len != 16 && key_len != 24 && key_len != 32) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + ctx->key_length = key_len; + + E_KEY[0] = u32_in (in_key); + E_KEY[1] = u32_in (in_key + 4); + E_KEY[2] = u32_in (in_key + 8); + E_KEY[3] = u32_in (in_key + 12); + + switch (key_len) { + case 16: + t = E_KEY[3]; + for (i = 0; i < 10; ++i) + loop4 (i); + break; + + case 24: + E_KEY[4] = u32_in (in_key + 16); + t = E_KEY[5] = u32_in (in_key + 20); + for (i = 0; i < 8; ++i) + loop6 (i); + break; + + case 32: + E_KEY[4] = u32_in (in_key + 16); + E_KEY[5] = u32_in (in_key + 20); + E_KEY[6] = u32_in (in_key + 24); + t = E_KEY[7] = u32_in (in_key + 28); + for (i = 0; i < 7; ++i) + loop8 (i); + break; + } + + D_KEY[0] = E_KEY[0]; + D_KEY[1] = E_KEY[1]; + D_KEY[2] = E_KEY[2]; + D_KEY[3] = E_KEY[3]; + + for (i = 4; i < key_len + 24; ++i) { + imix_col (D_KEY[i], E_KEY[i]); + } + + return 0; +} + +/* encrypt a block of text */ + +#define f_nround(bo, bi, k) \ + f_rn(bo, bi, 0, k); \ + f_rn(bo, bi, 1, k); \ + f_rn(bo, bi, 2, k); \ + f_rn(bo, bi, 3, k); \ + k += 4 + +#define f_lround(bo, bi, k) \ + f_rl(bo, bi, 0, k); \ + f_rl(bo, bi, 1, k); \ + f_rl(bo, bi, 2, k); \ + f_rl(bo, bi, 3, k) + +static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in) +{ + const struct aes_ctx *ctx = ctx_arg; + u32 b0[4], b1[4]; + const u32 *kp = E_KEY + 4; + + b0[0] = u32_in (in) ^ E_KEY[0]; + b0[1] = u32_in (in + 4) ^ E_KEY[1]; + b0[2] = u32_in (in + 8) ^ E_KEY[2]; + b0[3] = u32_in (in + 12) ^ E_KEY[3]; + + if (ctx->key_length > 24) { + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + } + + if (ctx->key_length > 16) { + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + } + + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_lround (b0, b1, kp); + + u32_out (out, b0[0]); + u32_out (out + 4, b0[1]); + u32_out (out + 8, b0[2]); + u32_out (out + 12, b0[3]); +} + +/* decrypt a block of text */ + +#define i_nround(bo, bi, k) \ + i_rn(bo, bi, 0, k); \ + i_rn(bo, bi, 1, k); \ + i_rn(bo, bi, 2, k); \ + i_rn(bo, bi, 3, k); \ + k -= 4 + +#define i_lround(bo, bi, k) \ + i_rl(bo, bi, 0, k); \ + i_rl(bo, bi, 1, k); \ + i_rl(bo, bi, 2, k); \ + i_rl(bo, bi, 3, k) + +static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in) +{ + const struct aes_ctx *ctx = ctx_arg; + u32 b0[4], b1[4]; + const int key_len = ctx->key_length; + const u32 *kp = D_KEY + key_len + 20; + + b0[0] = u32_in (in) ^ E_KEY[key_len + 24]; + b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25]; + b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26]; + b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27]; + + if (key_len > 24) { + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + } + + if (key_len > 16) { + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + } + + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_lround (b0, b1, kp); + + u32_out (out, b0[0]); + u32_out (out + 4, b0[1]); + u32_out (out + 8, b0[2]); + u32_out (out + 12, b0[3]); +} + + +static struct crypto_alg aes_alg = { + .cra_name = "aes", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aes_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_ivsize = AES_BLOCK_SIZE, + .cia_setkey = aes_set_key, + .cia_encrypt = aes_encrypt, + .cia_decrypt = aes_decrypt + } + } +}; + +static int __init aes_init(void) +{ + gen_tabs(); + return crypto_register_alg(&aes_alg); +} + +static void __exit aes_fini(void) +{ + crypto_unregister_alg(&aes_alg); +} + +module_init(aes_init); +module_exit(aes_fini); + +MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); +MODULE_LICENSE("Dual BSD/GPL"); + diff -urN linux-2.4.21/crypto/api.c linux-2.4.22/crypto/api.c --- linux-2.4.21/crypto/api.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/api.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,227 @@ +/* + * Scatterlist Cryptographic API. + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * + * Portions derived from Cryptoapi, by Alexander Kjeldaas + * and Nettle, by Niels Möller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include "internal.h" + +LIST_HEAD(crypto_alg_list); +DECLARE_RWSEM(crypto_alg_sem); + +static inline int crypto_alg_get(struct crypto_alg *alg) +{ + return try_inc_mod_count(alg->cra_module); +} + +static inline void crypto_alg_put(struct crypto_alg *alg) +{ + if (alg->cra_module) + __MOD_DEC_USE_COUNT(alg->cra_module); +} + +struct crypto_alg *crypto_alg_lookup(const char *name) +{ + struct crypto_alg *q, *alg = NULL; + + down_read(&crypto_alg_sem); + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (!(strcmp(q->cra_name, name))) { + if (crypto_alg_get(q)) + alg = q; + break; + } + } + + up_read(&crypto_alg_sem); + return alg; +} + +static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) +{ + tfm->crt_flags = 0; + + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + return crypto_init_cipher_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_DIGEST: + return crypto_init_digest_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_COMPRESS: + return crypto_init_compress_flags(tfm, flags); + + default: + break; + } + + BUG(); + return -EINVAL; +} + +static int crypto_init_ops(struct crypto_tfm *tfm) +{ + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + return crypto_init_cipher_ops(tfm); + + case CRYPTO_ALG_TYPE_DIGEST: + return crypto_init_digest_ops(tfm); + + case CRYPTO_ALG_TYPE_COMPRESS: + return crypto_init_compress_ops(tfm); + + default: + break; + } + + BUG(); + return -EINVAL; +} + +static void crypto_exit_ops(struct crypto_tfm *tfm) +{ + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + crypto_exit_cipher_ops(tfm); + break; + + case CRYPTO_ALG_TYPE_DIGEST: + crypto_exit_digest_ops(tfm); + break; + + case CRYPTO_ALG_TYPE_COMPRESS: + crypto_exit_compress_ops(tfm); + break; + + default: + BUG(); + + } +} + +struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) +{ + struct crypto_tfm *tfm = NULL; + struct crypto_alg *alg; + + alg = crypto_alg_mod_lookup(name); + if (alg == NULL) + goto out; + + tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); + if (tfm == NULL) + goto out_put; + + memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); + + tfm->__crt_alg = alg; + + if (crypto_init_flags(tfm, flags)) + goto out_free_tfm; + + if (crypto_init_ops(tfm)) { + crypto_exit_ops(tfm); + goto out_free_tfm; + } + + goto out; + +out_free_tfm: + kfree(tfm); + tfm = NULL; +out_put: + crypto_alg_put(alg); +out: + return tfm; +} + +void crypto_free_tfm(struct crypto_tfm *tfm) +{ + crypto_exit_ops(tfm); + crypto_alg_put(tfm->__crt_alg); + kfree(tfm); +} + +int crypto_register_alg(struct crypto_alg *alg) +{ + int ret = 0; + struct crypto_alg *q; + + down_write(&crypto_alg_sem); + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (!(strcmp(q->cra_name, alg->cra_name))) { + ret = -EEXIST; + goto out; + } + } + + list_add_tail(&alg->cra_list, &crypto_alg_list); +out: + up_write(&crypto_alg_sem); + return ret; +} + +int crypto_unregister_alg(struct crypto_alg *alg) +{ + int ret = -ENOENT; + struct crypto_alg *q; + + BUG_ON(!alg->cra_module); + + down_write(&crypto_alg_sem); + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (alg == q) { + list_del(&alg->cra_list); + ret = 0; + goto out; + } + } +out: + up_write(&crypto_alg_sem); + return ret; +} + +int crypto_alg_available(const char *name, u32 flags) +{ + int ret = 0; + struct crypto_alg *alg = crypto_alg_mod_lookup(name); + + if (alg) { + crypto_alg_put(alg); + ret = 1; + } + + return ret; +} + +static int __init init_crypto(void) +{ + printk(KERN_INFO "Initializing Cryptographic API\n"); + crypto_init_proc(); + return 0; +} + +__initcall(init_crypto); + +EXPORT_SYMBOL_GPL(crypto_register_alg); +EXPORT_SYMBOL_GPL(crypto_unregister_alg); +EXPORT_SYMBOL_GPL(crypto_alloc_tfm); +EXPORT_SYMBOL_GPL(crypto_free_tfm); +EXPORT_SYMBOL_GPL(crypto_alg_available); diff -urN linux-2.4.21/crypto/autoload.c linux-2.4.22/crypto/autoload.c --- linux-2.4.21/crypto/autoload.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/autoload.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,37 @@ +/* + * Cryptographic API. + * + * Algorithm autoloader. + * + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include "internal.h" + +/* + * A far more intelligent version of this is planned. For now, just + * try an exact match on the name of the algorithm. + */ +void crypto_alg_autoload(const char *name) +{ + request_module(name); +} + +struct crypto_alg *crypto_alg_mod_lookup(const char *name) +{ + struct crypto_alg *alg = crypto_alg_lookup(name); + if (alg == NULL) { + crypto_alg_autoload(name); + alg = crypto_alg_lookup(name); + } + return alg; +} diff -urN linux-2.4.21/crypto/blowfish.c linux-2.4.22/crypto/blowfish.c --- linux-2.4.21/crypto/blowfish.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/blowfish.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,479 @@ +/* + * Cryptographic API. + * + * Blowfish Cipher Algorithm, by Bruce Schneier. + * http://www.counterpane.com/blowfish.html + * + * Adapated from Kerneli implementation. + * + * Copyright (c) Herbert Valerio Riedel + * Copyright (c) Kyle McMartin + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include +#include +#include +#include + +#define BF_BLOCK_SIZE 8 +#define BF_MIN_KEY_SIZE 4 +#define BF_MAX_KEY_SIZE 56 + +struct bf_ctx { + u32 p[18]; + u32 s[1024]; +}; + +static const u32 bf_pbox[16 + 2] = { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b, +}; + +static const u32 bf_sbox[256 * 4] = { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, +}; + +/* + * Round loop unrolling macros, S is a pointer to a S-Box array + * organized in 4 unsigned longs at a row. + */ +#define GET32_3(x) (((x) & 0xff)) +#define GET32_2(x) (((x) >> (8)) & (0xff)) +#define GET32_1(x) (((x) >> (16)) & (0xff)) +#define GET32_0(x) (((x) >> (24)) & (0xff)) + +#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \ + S[512 + GET32_2(x)]) + S[768 + GET32_3(x)]) + +#define ROUND(a, b, n) b ^= P[n]; a ^= bf_F (b) + +/* + * The blowfish encipher, processes 64-bit blocks. + * NOTE: This function MUSTN'T respect endianess + */ +static inline void encrypt_block(struct bf_ctx *bctx, u32 *dst, u32 *src) +{ + const u32 *P = bctx->p; + const u32 *S = bctx->s; + u32 yl = src[0]; + u32 yr = src[1]; + + ROUND(yr, yl, 0); + ROUND(yl, yr, 1); + ROUND(yr, yl, 2); + ROUND(yl, yr, 3); + ROUND(yr, yl, 4); + ROUND(yl, yr, 5); + ROUND(yr, yl, 6); + ROUND(yl, yr, 7); + ROUND(yr, yl, 8); + ROUND(yl, yr, 9); + ROUND(yr, yl, 10); + ROUND(yl, yr, 11); + ROUND(yr, yl, 12); + ROUND(yl, yr, 13); + ROUND(yr, yl, 14); + ROUND(yl, yr, 15); + + yl ^= P[16]; + yr ^= P[17]; + + dst[0] = yr; + dst[1] = yl; +} + +static void bf_encrypt(void *ctx, u8 *dst, const u8 *src) +{ + const u32 *in_blk = (const u32 *)src; + u32 *const out_blk = (u32 *)dst; + u32 in32[2], out32[2]; + + in32[0] = be32_to_cpu(in_blk[0]); + in32[1] = be32_to_cpu(in_blk[1]); + encrypt_block(ctx, out32, in32); + out_blk[0] = cpu_to_be32(out32[0]); + out_blk[1] = cpu_to_be32(out32[1]); +} + +static void bf_decrypt(void *ctx, u8 *dst, const u8 *src) +{ + const u32 *in_blk = (const u32 *)src; + u32 *const out_blk = (u32 *)dst; + const u32 *P = ((struct bf_ctx *)ctx)->p; + const u32 *S = ((struct bf_ctx *)ctx)->s; + u32 yl = be32_to_cpu(in_blk[0]); + u32 yr = be32_to_cpu(in_blk[1]); + + ROUND(yr, yl, 17); + ROUND(yl, yr, 16); + ROUND(yr, yl, 15); + ROUND(yl, yr, 14); + ROUND(yr, yl, 13); + ROUND(yl, yr, 12); + ROUND(yr, yl, 11); + ROUND(yl, yr, 10); + ROUND(yr, yl, 9); + ROUND(yl, yr, 8); + ROUND(yr, yl, 7); + ROUND(yl, yr, 6); + ROUND(yr, yl, 5); + ROUND(yl, yr, 4); + ROUND(yr, yl, 3); + ROUND(yl, yr, 2); + + yl ^= P[1]; + yr ^= P[0]; + + out_blk[0] = cpu_to_be32(yr); + out_blk[1] = cpu_to_be32(yl); +} + +/* + * Calculates the blowfish S and P boxes for encryption and decryption. + */ +static int bf_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) +{ + short i, j, count; + u32 data[2], temp; + u32 *P = ((struct bf_ctx *)ctx)->p; + u32 *S = ((struct bf_ctx *)ctx)->s; + + /* Copy the initialization s-boxes */ + for (i = 0, count = 0; i < 256; i++) + for (j = 0; j < 4; j++, count++) + S[count] = bf_sbox[count]; + + /* Set the p-boxes */ + for (i = 0; i < 16 + 2; i++) + P[i] = bf_pbox[i]; + + /* Actual subkey generation */ + for (j = 0, i = 0; i < 16 + 2; i++) { + temp = (((u32 )key[j] << 24) | + ((u32 )key[(j + 1) % keylen] << 16) | + ((u32 )key[(j + 2) % keylen] << 8) | + ((u32 )key[(j + 3) % keylen])); + + P[i] = P[i] ^ temp; + j = (j + 4) % keylen; + } + + data[0] = 0x00000000; + data[1] = 0x00000000; + + for (i = 0; i < 16 + 2; i += 2) { + encrypt_block((struct bf_ctx *)ctx, data, data); + + P[i] = data[0]; + P[i + 1] = data[1]; + } + + for (i = 0; i < 4; i++) { + for (j = 0, count = i * 256; j < 256; j += 2, count += 2) { + encrypt_block((struct bf_ctx *)ctx, data, data); + + S[count] = data[0]; + S[count + 1] = data[1]; + } + } + + /* Bruce says not to bother with the weak key check. */ + return 0; +} + +static struct crypto_alg alg = { + .cra_name = "blowfish", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = BF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct bf_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = BF_MIN_KEY_SIZE, + .cia_max_keysize = BF_MAX_KEY_SIZE, + .cia_ivsize = BF_BLOCK_SIZE, + .cia_setkey = bf_setkey, + .cia_encrypt = bf_encrypt, + .cia_decrypt = bf_decrypt } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Blowfish Cipher Algorithm"); diff -urN linux-2.4.21/crypto/cipher.c linux-2.4.22/crypto/cipher.c --- linux-2.4.21/crypto/cipher.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/cipher.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,417 @@ +/* + * Cryptographic API. + * + * Cipher operations. + * + * Copyright (c) 2002 James Morris + * Generic scatterwalk code by Adam J. Richter . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +typedef void (cryptfn_t)(void *, u8 *, const u8 *); +typedef void (procfn_t)(struct crypto_tfm *, u8 *, + u8*, cryptfn_t, int enc, void *); + +struct scatter_walk { + struct scatterlist *sg; + struct page *page; + void *data; + unsigned int len_this_page; + unsigned int len_this_segment; + unsigned int offset; +}; + +enum km_type crypto_km_types[] = { + KM_USER0, + KM_USER1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, +}; + +static inline void xor_64(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; +} + +static inline void xor_128(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; + ((u32 *)a)[2] ^= ((u32 *)b)[2]; + ((u32 *)a)[3] ^= ((u32 *)b)[3]; +} + + +/* Define sg_next is an inline routine now in case we want to change + scatterlist to a linked list later. */ +static inline struct scatterlist *sg_next(struct scatterlist *sg) +{ + return sg + 1; +} + +void *which_buf(struct scatter_walk *walk, unsigned int nbytes, void *scratch) +{ + if (nbytes <= walk->len_this_page && + (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <= + PAGE_CACHE_SIZE) + return walk->data; + else + return scratch; +} + +static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out) +{ + if (out) + memcpy(sgdata, buf, nbytes); + else + memcpy(buf, sgdata, nbytes); +} + +static void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg) +{ + unsigned int rest_of_page; + + walk->sg = sg; + + walk->page = sg->page; + walk->len_this_segment = sg->length; + + rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1)); + walk->len_this_page = min(sg->length, rest_of_page); + walk->offset = sg->offset; +} + +static void scatterwalk_map(struct scatter_walk *walk, int out) +{ + walk->data = crypto_kmap(walk->page, out) + walk->offset; +} + +static void scatter_page_done(struct scatter_walk *walk, int out, + unsigned int more) +{ + /* walk->data may be pointing the first byte of the next page; + however, we know we transfered at least one byte. So, + walk->data - 1 will be a virutual address in the mapped page. */ + + if (out) + flush_dcache_page(walk->page); + + if (more) { + walk->len_this_segment -= walk->len_this_page; + + if (walk->len_this_segment) { + walk->page++; + walk->len_this_page = min(walk->len_this_segment, + (unsigned)PAGE_CACHE_SIZE); + walk->offset = 0; + } + else + scatterwalk_start(walk, sg_next(walk->sg)); + } +} + +static void scatter_done(struct scatter_walk *walk, int out, int more) +{ + crypto_kunmap(walk->data, out); + if (walk->len_this_page == 0 || !more) + scatter_page_done(walk, out, more); +} + +/* + * Do not call this unless the total length of all of the fragments + * has been verified as multiple of the block size. + */ +static int copy_chunks(void *buf, struct scatter_walk *walk, + size_t nbytes, int out) +{ + if (buf != walk->data) { + while (nbytes > walk->len_this_page) { + memcpy_dir(buf, walk->data, walk->len_this_page, out); + buf += walk->len_this_page; + nbytes -= walk->len_this_page; + + crypto_kunmap(walk->data, out); + scatter_page_done(walk, out, 1); + scatterwalk_map(walk, out); + } + + memcpy_dir(buf, walk->data, nbytes, out); + } + + walk->offset += nbytes; + walk->len_this_page -= nbytes; + walk->len_this_segment -= nbytes; + return 0; +} + +/* + * Generic encrypt/decrypt wrapper for ciphers, handles operations across + * multiple page boundaries by using temporary blocks. In user context, + * the kernel is given a chance to schedule us once per block. + */ +static int crypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, cryptfn_t crfn, + procfn_t prfn, int enc, void *info) +{ + struct scatter_walk walk_in, walk_out; + const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + u8 tmp_src[nbytes > src->length ? bsize : 0]; + u8 tmp_dst[nbytes > dst->length ? bsize : 0]; + + if (!nbytes) + return 0; + + if (nbytes % bsize) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; + return -EINVAL; + } + + scatterwalk_start(&walk_in, src); + scatterwalk_start(&walk_out, dst); + + for(;;) { + u8 *src_p, *dst_p; + + scatterwalk_map(&walk_in, 0); + scatterwalk_map(&walk_out, 1); + src_p = which_buf(&walk_in, bsize, tmp_src); + dst_p = which_buf(&walk_out, bsize, tmp_dst); + + nbytes -= bsize; + + copy_chunks(src_p, &walk_in, bsize, 0); + + prfn(tfm, dst_p, src_p, crfn, enc, info); + + scatter_done(&walk_in, 0, nbytes); + + copy_chunks(dst_p, &walk_out, bsize, 1); + scatter_done(&walk_out, 1, nbytes); + + if (!nbytes) + return 0; + + crypto_yield(tfm); + } +} + +static void cbc_process(struct crypto_tfm *tfm, + u8 *dst, u8 *src, cryptfn_t fn, int enc, void *info) +{ + u8 *iv = info; + + /* Null encryption */ + if (!iv) + return; + + if (enc) { + tfm->crt_u.cipher.cit_xor_block(iv, src); + fn(crypto_tfm_ctx(tfm), dst, iv); + memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm)); + } else { + const int need_stack = (src == dst); + u8 stack[need_stack ? crypto_tfm_alg_blocksize(tfm) : 0]; + u8 *buf = need_stack ? stack : dst; + + fn(crypto_tfm_ctx(tfm), buf, src); + tfm->crt_u.cipher.cit_xor_block(buf, iv); + memcpy(iv, src, crypto_tfm_alg_blocksize(tfm)); + if (buf != dst) + memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm)); + } +} + +static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src, + cryptfn_t fn, int enc, void *info) +{ + fn(crypto_tfm_ctx(tfm), dst, src); +} + +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; + + if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } else + return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen, + &tfm->crt_flags); +} + +static int ecb_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_encrypt, + ecb_process, 1, NULL); +} + +static int ecb_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_decrypt, + ecb_process, 1, NULL); +} + +static int cbc_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_encrypt, + cbc_process, 1, tfm->crt_cipher.cit_iv); +} + +static int cbc_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_encrypt, + cbc_process, 1, iv); +} + +static int cbc_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_decrypt, + cbc_process, 0, tfm->crt_cipher.cit_iv); +} + +static int cbc_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_decrypt, + cbc_process, 0, iv); +} + +static int nocrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return -ENOSYS; +} + +static int nocrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return -ENOSYS; +} + +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags) +{ + u32 mode = flags & CRYPTO_TFM_MODE_MASK; + + tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB; + if (flags & CRYPTO_TFM_REQ_WEAK_KEY) + tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY; + + return 0; +} + +int crypto_init_cipher_ops(struct crypto_tfm *tfm) +{ + int ret = 0; + struct crypto_alg *alg = tfm->__crt_alg; + struct cipher_tfm *ops = &tfm->crt_cipher; + + ops->cit_setkey = setkey; + + switch (tfm->crt_cipher.cit_mode) { + case CRYPTO_TFM_MODE_ECB: + ops->cit_encrypt = ecb_encrypt; + ops->cit_decrypt = ecb_decrypt; + break; + + case CRYPTO_TFM_MODE_CBC: + ops->cit_encrypt = cbc_encrypt; + ops->cit_decrypt = cbc_decrypt; + ops->cit_encrypt_iv = cbc_encrypt_iv; + ops->cit_decrypt_iv = cbc_decrypt_iv; + break; + + case CRYPTO_TFM_MODE_CFB: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + case CRYPTO_TFM_MODE_CTR: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + default: + BUG(); + } + + if (alg->cra_cipher.cia_ivsize && + ops->cit_mode != CRYPTO_TFM_MODE_ECB) { + + switch (crypto_tfm_alg_blocksize(tfm)) { + case 8: + ops->cit_xor_block = xor_64; + break; + + case 16: + ops->cit_xor_block = xor_128; + break; + + default: + printk(KERN_WARNING "%s: block size %u not supported\n", + crypto_tfm_alg_name(tfm), + crypto_tfm_alg_blocksize(tfm)); + ret = -EINVAL; + goto out; + } + + ops->cit_iv = kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL); + if (ops->cit_iv == NULL) + ret = -ENOMEM; + } + +out: + return ret; +} + +void crypto_exit_cipher_ops(struct crypto_tfm *tfm) +{ + if (tfm->crt_cipher.cit_iv) + kfree(tfm->crt_cipher.cit_iv); +} diff -urN linux-2.4.21/crypto/compress.c linux-2.4.22/crypto/compress.c --- linux-2.4.21/crypto/compress.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/compress.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,63 @@ +/* + * Cryptographic API. + * + * Compression operations. + * + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include "internal.h" + +static int crypto_compress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm), + src, slen, dst, + dlen); +} + +static int crypto_decompress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm), + src, slen, dst, + dlen); +} + +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + +int crypto_init_compress_ops(struct crypto_tfm *tfm) +{ + int ret = 0; + struct compress_tfm *ops = &tfm->crt_compress; + + ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm)); + if (ret) + goto out; + + ops->cot_compress = crypto_compress; + ops->cot_decompress = crypto_decompress; + +out: + return ret; +} + +void crypto_exit_compress_ops(struct crypto_tfm *tfm) +{ + tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm)); +} diff -urN linux-2.4.21/crypto/crypto_null.c linux-2.4.22/crypto/crypto_null.c --- linux-2.4.21/crypto/crypto_null.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/crypto_null.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,134 @@ +/* + * Cryptographic API. + * + * Null algorithms, aka Much Ado About Nothing. + * + * These are needed for IPsec, and may be useful in general for + * testing & debugging. + * + * The null cipher is compliant with RFC2410. + * + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include +#include +#include +#include + +#define NULL_KEY_SIZE 0 +#define NULL_BLOCK_SIZE 1 +#define NULL_DIGEST_SIZE 0 + +static int null_compress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ return 0; } + +static int null_decompress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ return 0; } + +static void null_init(void *ctx) +{ } + +static void null_update(void *ctx, const u8 *data, unsigned int len) +{ } + +static void null_final(void *ctx, u8 *out) +{ } + +static int null_setkey(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags) +{ return 0; } + +static void null_encrypt(void *ctx, u8 *dst, const u8 *src) +{ } + +static void null_decrypt(void *ctx, u8 *dst, const u8 *src) +{ } + +static struct crypto_alg compress_null = { + .cra_name = "compress_null", + .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, + .cra_blocksize = NULL_BLOCK_SIZE, + .cra_ctxsize = 0, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(compress_null.cra_list), + .cra_u = { .compress = { + .coa_compress = null_compress, + .coa_decompress = null_decompress } } +}; + +static struct crypto_alg digest_null = { + .cra_name = "digest_null", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = NULL_BLOCK_SIZE, + .cra_ctxsize = 0, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(digest_null.cra_list), + .cra_u = { .digest = { + .dia_digestsize = NULL_DIGEST_SIZE, + .dia_init = null_init, + .dia_update = null_update, + .dia_final = null_final } } +}; + +static struct crypto_alg cipher_null = { + .cra_name = "cipher_null", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = NULL_BLOCK_SIZE, + .cra_ctxsize = 0, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(cipher_null.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = NULL_KEY_SIZE, + .cia_max_keysize = NULL_KEY_SIZE, + .cia_ivsize = 0, + .cia_setkey = null_setkey, + .cia_encrypt = null_encrypt, + .cia_decrypt = null_decrypt } } +}; + +static int __init init(void) +{ + int ret = 0; + + ret = crypto_register_alg(&cipher_null); + if (ret < 0) + goto out; + + ret = crypto_register_alg(&digest_null); + if (ret < 0) { + crypto_unregister_alg(&cipher_null); + goto out; + } + + ret = crypto_register_alg(&compress_null); + if (ret < 0) { + crypto_unregister_alg(&digest_null); + crypto_unregister_alg(&cipher_null); + goto out; + } + +out: + return ret; +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&compress_null); + crypto_unregister_alg(&digest_null); + crypto_unregister_alg(&cipher_null); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Null Cryptographic Algorithms"); diff -urN linux-2.4.21/crypto/deflate.c linux-2.4.22/crypto/deflate.c --- linux-2.4.21/crypto/deflate.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/deflate.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,236 @@ +/* + * Cryptographic API. + * + * Deflate algorithm (RFC 1951), implemented here primarily for use + * by IPCOMP (RFC 3173 & RFC 2394). + * + * Copyright (c) 2003 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * FIXME: deflate transforms will require up to a total of about 436k of kernel + * memory on i386 (390k for compression, the rest for decompression), as the + * current zlib kernel code uses a worst case pre-allocation system by default. + * This needs to be fixed so that the amount of memory required is properly + * related to the winbits and memlevel parameters. + * + * The default winbits of 11 should suit most packets, and it may be something + * to configure on a per-tfm basis in the future. + * + * Currently, compression history is not maintained between tfm calls, as + * it is not needed for IPCOMP and keeps the code simpler. It can be + * implemented if someone wants it. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION +#define DEFLATE_DEF_WINBITS 11 +#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL + +struct deflate_ctx { + int comp_initialized; + int decomp_initialized; + struct z_stream_s comp_stream; + struct z_stream_s decomp_stream; +}; + +static inline int deflate_gfp(void) +{ + return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; +} + +static int deflate_init(void *ctx) +{ + return 0; +} + +static void deflate_exit(void *ctx) +{ + struct deflate_ctx *dctx = ctx; + + if (dctx->comp_initialized) + vfree(dctx->comp_stream.workspace); + if (dctx->decomp_initialized) + kfree(dctx->decomp_stream.workspace); +} + +/* + * Lazy initialization to make interface simple without allocating + * un-needed workspaces. Thus can be called in softirq context. + */ +static int deflate_comp_init(struct deflate_ctx *ctx) +{ + int ret = 0; + struct z_stream_s *stream = &ctx->comp_stream; + + stream->workspace = __vmalloc(zlib_deflate_workspacesize(), + deflate_gfp()|__GFP_HIGHMEM, + PAGE_KERNEL); + if (!stream->workspace ) { + ret = -ENOMEM; + goto out; + } + memset(stream->workspace, 0, zlib_deflate_workspacesize()); + ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, + -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, + Z_DEFAULT_STRATEGY); + if (ret != Z_OK) { + ret = -EINVAL; + goto out_free; + } + ctx->comp_initialized = 1; +out: + return ret; +out_free: + vfree(stream->workspace); + goto out; +} + +static int deflate_decomp_init(struct deflate_ctx *ctx) +{ + int ret = 0; + struct z_stream_s *stream = &ctx->decomp_stream; + + stream->workspace = kmalloc(zlib_inflate_workspacesize(), + deflate_gfp()); + if (!stream->workspace ) { + ret = -ENOMEM; + goto out; + } + memset(stream->workspace, 0, zlib_inflate_workspacesize()); + ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS); + if (ret != Z_OK) { + ret = -EINVAL; + goto out_free; + } + ctx->decomp_initialized = 1; +out: + return ret; +out_free: + kfree(stream->workspace); + goto out; +} + +static int deflate_compress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + int ret = 0; + struct deflate_ctx *dctx = ctx; + struct z_stream_s *stream = &dctx->comp_stream; + + if (!dctx->comp_initialized) { + ret = deflate_comp_init(dctx); + if (ret) + goto out; + } + + ret = zlib_deflateReset(stream); + if (ret != Z_OK) { + ret = -EINVAL; + goto out; + } + + stream->next_in = (u8 *)src; + stream->avail_in = slen; + stream->next_out = (u8 *)dst; + stream->avail_out = *dlen; + + ret = zlib_deflate(stream, Z_FINISH); + if (ret != Z_STREAM_END) { + ret = -EINVAL; + goto out; + } + ret = 0; + *dlen = stream->total_out; +out: + return ret; +} + +static int deflate_decompress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + + int ret = 0; + struct deflate_ctx *dctx = ctx; + struct z_stream_s *stream = &dctx->decomp_stream; + + if (!dctx->decomp_initialized) { + ret = deflate_decomp_init(dctx); + if (ret) + goto out; + } + + ret = zlib_inflateReset(stream); + if (ret != Z_OK) { + ret = -EINVAL; + goto out; + } + + stream->next_in = (u8 *)src; + stream->avail_in = slen; + stream->next_out = (u8 *)dst; + stream->avail_out = *dlen; + + ret = zlib_inflate(stream, Z_SYNC_FLUSH); + /* + * Work around a bug in zlib, which sometimes wants to taste an extra + * byte when being used in the (undocumented) raw deflate mode. + * (From USAGI). + */ + if (ret == Z_OK && !stream->avail_in && stream->avail_out) { + u8 zerostuff = 0; + stream->next_in = &zerostuff; + stream->avail_in = 1; + ret = zlib_inflate(stream, Z_FINISH); + } + if (ret != Z_STREAM_END) { + ret = -EINVAL; + goto out; + } + ret = 0; + *dlen = stream->total_out; +out: + return ret; +} + +static struct crypto_alg alg = { + .cra_name = "deflate", + .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, + .cra_ctxsize = sizeof(struct deflate_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .compress = { + .coa_init = deflate_init, + .coa_exit = deflate_exit, + .coa_compress = deflate_compress, + .coa_decompress = deflate_decompress } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP"); +MODULE_AUTHOR("James Morris "); + diff -urN linux-2.4.21/crypto/des.c linux-2.4.22/crypto/des.c --- linux-2.4.21/crypto/des.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/des.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,1299 @@ +/* + * Cryptographic API. + * + * DES & Triple DES EDE Cipher Algorithms. + * + * Originally released as descore by Dana L. How . + * Modified by Raimar Falke for the Linux-Kernel. + * Derived from Cryptoapi and Nettle implementations, adapted for in-place + * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL. + * + * Copyright (c) 1992 Dana L. How. + * Copyright (c) Raimar Falke + * Copyright (c) Gisle Sælensminde + * Copyright (C) 2001 Niels Möller. + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include +#include +#include +#include +#include + +#define DES_KEY_SIZE 8 +#define DES_EXPKEY_WORDS 32 +#define DES_BLOCK_SIZE 8 + +#define DES3_EDE_KEY_SIZE (3 * DES_KEY_SIZE) +#define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS) +#define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE + +#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o)) + +struct des_ctx { + u8 iv[DES_BLOCK_SIZE]; + u32 expkey[DES_EXPKEY_WORDS]; +}; + +struct des3_ede_ctx { + u8 iv[DES_BLOCK_SIZE]; + u32 expkey[DES3_EDE_EXPKEY_WORDS]; +}; + +static const u32 des_keymap[] = { + 0x02080008, 0x02082000, 0x00002008, 0x00000000, + 0x02002000, 0x00080008, 0x02080000, 0x02082008, + 0x00000008, 0x02000000, 0x00082000, 0x00002008, + 0x00082008, 0x02002008, 0x02000008, 0x02080000, + 0x00002000, 0x00082008, 0x00080008, 0x02002000, + 0x02082008, 0x02000008, 0x00000000, 0x00082000, + 0x02000000, 0x00080000, 0x02002008, 0x02080008, + 0x00080000, 0x00002000, 0x02082000, 0x00000008, + 0x00080000, 0x00002000, 0x02000008, 0x02082008, + 0x00002008, 0x02000000, 0x00000000, 0x00082000, + 0x02080008, 0x02002008, 0x02002000, 0x00080008, + 0x02082000, 0x00000008, 0x00080008, 0x02002000, + 0x02082008, 0x00080000, 0x02080000, 0x02000008, + 0x00082000, 0x00002008, 0x02002008, 0x02080000, + 0x00000008, 0x02082000, 0x00082008, 0x00000000, + 0x02000000, 0x02080008, 0x00002000, 0x00082008, + + 0x08000004, 0x00020004, 0x00000000, 0x08020200, + 0x00020004, 0x00000200, 0x08000204, 0x00020000, + 0x00000204, 0x08020204, 0x00020200, 0x08000000, + 0x08000200, 0x08000004, 0x08020000, 0x00020204, + 0x00020000, 0x08000204, 0x08020004, 0x00000000, + 0x00000200, 0x00000004, 0x08020200, 0x08020004, + 0x08020204, 0x08020000, 0x08000000, 0x00000204, + 0x00000004, 0x00020200, 0x00020204, 0x08000200, + 0x00000204, 0x08000000, 0x08000200, 0x00020204, + 0x08020200, 0x00020004, 0x00000000, 0x08000200, + 0x08000000, 0x00000200, 0x08020004, 0x00020000, + 0x00020004, 0x08020204, 0x00020200, 0x00000004, + 0x08020204, 0x00020200, 0x00020000, 0x08000204, + 0x08000004, 0x08020000, 0x00020204, 0x00000000, + 0x00000200, 0x08000004, 0x08000204, 0x08020200, + 0x08020000, 0x00000204, 0x00000004, 0x08020004, + + 0x80040100, 0x01000100, 0x80000000, 0x81040100, + 0x00000000, 0x01040000, 0x81000100, 0x80040000, + 0x01040100, 0x81000000, 0x01000000, 0x80000100, + 0x81000000, 0x80040100, 0x00040000, 0x01000000, + 0x81040000, 0x00040100, 0x00000100, 0x80000000, + 0x00040100, 0x81000100, 0x01040000, 0x00000100, + 0x80000100, 0x00000000, 0x80040000, 0x01040100, + 0x01000100, 0x81040000, 0x81040100, 0x00040000, + 0x81040000, 0x80000100, 0x00040000, 0x81000000, + 0x00040100, 0x01000100, 0x80000000, 0x01040000, + 0x81000100, 0x00000000, 0x00000100, 0x80040000, + 0x00000000, 0x81040000, 0x01040100, 0x00000100, + 0x01000000, 0x81040100, 0x80040100, 0x00040000, + 0x81040100, 0x80000000, 0x01000100, 0x80040100, + 0x80040000, 0x00040100, 0x01040000, 0x81000100, + 0x80000100, 0x01000000, 0x81000000, 0x01040100, + + 0x04010801, 0x00000000, 0x00010800, 0x04010000, + 0x04000001, 0x00000801, 0x04000800, 0x00010800, + 0x00000800, 0x04010001, 0x00000001, 0x04000800, + 0x00010001, 0x04010800, 0x04010000, 0x00000001, + 0x00010000, 0x04000801, 0x04010001, 0x00000800, + 0x00010801, 0x04000000, 0x00000000, 0x00010001, + 0x04000801, 0x00010801, 0x04010800, 0x04000001, + 0x04000000, 0x00010000, 0x00000801, 0x04010801, + 0x00010001, 0x04010800, 0x04000800, 0x00010801, + 0x04010801, 0x00010001, 0x04000001, 0x00000000, + 0x04000000, 0x00000801, 0x00010000, 0x04010001, + 0x00000800, 0x04000000, 0x00010801, 0x04000801, + 0x04010800, 0x00000800, 0x00000000, 0x04000001, + 0x00000001, 0x04010801, 0x00010800, 0x04010000, + 0x04010001, 0x00010000, 0x00000801, 0x04000800, + 0x04000801, 0x00000001, 0x04010000, 0x00010800, + + 0x00000400, 0x00000020, 0x00100020, 0x40100000, + 0x40100420, 0x40000400, 0x00000420, 0x00000000, + 0x00100000, 0x40100020, 0x40000020, 0x00100400, + 0x40000000, 0x00100420, 0x00100400, 0x40000020, + 0x40100020, 0x00000400, 0x40000400, 0x40100420, + 0x00000000, 0x00100020, 0x40100000, 0x00000420, + 0x40100400, 0x40000420, 0x00100420, 0x40000000, + 0x40000420, 0x40100400, 0x00000020, 0x00100000, + 0x40000420, 0x00100400, 0x40100400, 0x40000020, + 0x00000400, 0x00000020, 0x00100000, 0x40100400, + 0x40100020, 0x40000420, 0x00000420, 0x00000000, + 0x00000020, 0x40100000, 0x40000000, 0x00100020, + 0x00000000, 0x40100020, 0x00100020, 0x00000420, + 0x40000020, 0x00000400, 0x40100420, 0x00100000, + 0x00100420, 0x40000000, 0x40000400, 0x40100420, + 0x40100000, 0x00100420, 0x00100400, 0x40000400, + + 0x00800000, 0x00001000, 0x00000040, 0x00801042, + 0x00801002, 0x00800040, 0x00001042, 0x00801000, + 0x00001000, 0x00000002, 0x00800002, 0x00001040, + 0x00800042, 0x00801002, 0x00801040, 0x00000000, + 0x00001040, 0x00800000, 0x00001002, 0x00000042, + 0x00800040, 0x00001042, 0x00000000, 0x00800002, + 0x00000002, 0x00800042, 0x00801042, 0x00001002, + 0x00801000, 0x00000040, 0x00000042, 0x00801040, + 0x00801040, 0x00800042, 0x00001002, 0x00801000, + 0x00001000, 0x00000002, 0x00800002, 0x00800040, + 0x00800000, 0x00001040, 0x00801042, 0x00000000, + 0x00001042, 0x00800000, 0x00000040, 0x00001002, + 0x00800042, 0x00000040, 0x00000000, 0x00801042, + 0x00801002, 0x00801040, 0x00000042, 0x00001000, + 0x00001040, 0x00801002, 0x00800040, 0x00000042, + 0x00000002, 0x00001042, 0x00801000, 0x00800002, + + 0x10400000, 0x00404010, 0x00000010, 0x10400010, + 0x10004000, 0x00400000, 0x10400010, 0x00004010, + 0x00400010, 0x00004000, 0x00404000, 0x10000000, + 0x10404010, 0x10000010, 0x10000000, 0x10404000, + 0x00000000, 0x10004000, 0x00404010, 0x00000010, + 0x10000010, 0x10404010, 0x00004000, 0x10400000, + 0x10404000, 0x00400010, 0x10004010, 0x00404000, + 0x00004010, 0x00000000, 0x00400000, 0x10004010, + 0x00404010, 0x00000010, 0x10000000, 0x00004000, + 0x10000010, 0x10004000, 0x00404000, 0x10400010, + 0x00000000, 0x00404010, 0x00004010, 0x10404000, + 0x10004000, 0x00400000, 0x10404010, 0x10000000, + 0x10004010, 0x10400000, 0x00400000, 0x10404010, + 0x00004000, 0x00400010, 0x10400010, 0x00004010, + 0x00400010, 0x00000000, 0x10404000, 0x10000010, + 0x10400000, 0x10004010, 0x00000010, 0x00404000, + + 0x00208080, 0x00008000, 0x20200000, 0x20208080, + 0x00200000, 0x20008080, 0x20008000, 0x20200000, + 0x20008080, 0x00208080, 0x00208000, 0x20000080, + 0x20200080, 0x00200000, 0x00000000, 0x20008000, + 0x00008000, 0x20000000, 0x00200080, 0x00008080, + 0x20208080, 0x00208000, 0x20000080, 0x00200080, + 0x20000000, 0x00000080, 0x00008080, 0x20208000, + 0x00000080, 0x20200080, 0x20208000, 0x00000000, + 0x00000000, 0x20208080, 0x00200080, 0x20008000, + 0x00208080, 0x00008000, 0x20000080, 0x00200080, + 0x20208000, 0x00000080, 0x00008080, 0x20200000, + 0x20008080, 0x20000000, 0x20200000, 0x00208000, + 0x20208080, 0x00008080, 0x00208000, 0x20200080, + 0x00200000, 0x20000080, 0x20008000, 0x00000000, + 0x00008000, 0x00200000, 0x20200080, 0x00208080, + 0x20000000, 0x20208000, 0x00000080, 0x20008080, +}; + +static const u8 rotors[] = { + 34, 13, 5, 46, 47, 18, 32, 41, 11, 53, 33, 20, + 14, 36, 30, 24, 49, 2, 15, 37, 42, 50, 0, 21, + 38, 48, 6, 26, 39, 4, 52, 25, 12, 27, 31, 40, + 1, 17, 28, 29, 23, 51, 35, 7, 3, 22, 9, 43, + + 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27, + 21, 43, 37, 0, 1, 9, 22, 44, 49, 2, 7, 28, + 45, 55, 13, 33, 46, 11, 6, 32, 19, 34, 38, 47, + 8, 24, 35, 36, 30, 3, 42, 14, 10, 29, 16, 50, + + 55, 34, 26, 38, 11, 39, 53, 5, 32, 45, 54, 41, + 35, 2, 51, 14, 15, 23, 36, 3, 8, 16, 21, 42, + 6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52, 4, + 22, 7, 49, 50, 44, 17, 1, 28, 24, 43, 30, 9, + + 12, 48, 40, 52, 25, 53, 38, 19, 46, 6, 11, 55, + 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35, 1, + 20, 26, 41, 4, 45, 39, 34, 31, 47, 5, 13, 18, + 36, 21, 8, 9, 3, 0, 15, 42, 7, 2, 44, 23, + + 26, 5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12, + 8, 30, 24, 42, 43, 51, 9, 0, 36, 44, 49, 15, + 34, 40, 55, 18, 6, 53, 48, 45, 4, 19, 27, 32, + 50, 35, 22, 23, 17, 14, 29, 1, 21, 16, 3, 37, + + 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26, + 22, 44, 7, 1, 2, 10, 23, 14, 50, 3, 8, 29, + 48, 54, 12, 32, 20, 38, 5, 6, 18, 33, 41, 46, + 9, 49, 36, 37, 0, 28, 43, 15, 35, 30, 17, 51, + + 54, 33, 25, 41, 38, 13, 27, 4, 6, 48, 53, 40, + 36, 3, 21, 15, 16, 24, 37, 28, 9, 17, 22, 43, + 5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31, + 23, 8, 50, 51, 14, 42, 2, 29, 49, 44, 0, 10, + + 11, 47, 39, 55, 52, 27, 41, 18, 20, 5, 38, 54, + 50, 17, 35, 29, 30, 7, 51, 42, 23, 0, 36, 2, + 19, 25, 40, 31, 48, 13, 33, 34, 46, 4, 12, 45, + 37, 22, 9, 10, 28, 1, 16, 43, 8, 3, 14, 24, + + 18, 54, 46, 5, 6, 34, 48, 25, 27, 12, 45, 4, + 2, 24, 42, 36, 37, 14, 3, 49, 30, 7, 43, 9, + 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52, + 44, 29, 16, 17, 35, 8, 23, 50, 15, 10, 21, 0, + + 32, 11, 31, 19, 20, 48, 5, 39, 41, 26, 6, 18, + 16, 7, 1, 50, 51, 28, 17, 8, 44, 21, 2, 23, + 40, 46, 4, 52, 12, 34, 54, 55, 38, 25, 33, 13, + 3, 43, 30, 0, 49, 22, 37, 9, 29, 24, 35, 14, + + 46, 25, 45, 33, 34, 5, 19, 53, 55, 40, 20, 32, + 30, 21, 15, 9, 10, 42, 0, 22, 3, 35, 16, 37, + 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27, + 17, 2, 44, 14, 8, 36, 51, 23, 43, 7, 49, 28, + + 31, 39, 6, 47, 48, 19, 33, 38, 12, 54, 34, 46, + 44, 35, 29, 23, 24, 1, 14, 36, 17, 49, 30, 51, + 11, 45, 32, 27, 40, 5, 25, 26, 13, 53, 4, 41, + 0, 16, 3, 28, 22, 50, 10, 37, 2, 21, 8, 42, + + 45, 53, 20, 4, 5, 33, 47, 52, 26, 11, 48, 31, + 3, 49, 43, 37, 7, 15, 28, 50, 0, 8, 44, 10, + 25, 6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55, + 14, 30, 17, 42, 36, 9, 24, 51, 16, 35, 22, 1, + + 6, 38, 34, 18, 19, 47, 4, 13, 40, 25, 5, 45, + 17, 8, 2, 51, 21, 29, 42, 9, 14, 22, 3, 24, + 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12, + 28, 44, 0, 1, 50, 23, 7, 10, 30, 49, 36, 15, + + 20, 52, 48, 32, 33, 4, 18, 27, 54, 39, 19, 6, + 0, 22, 16, 10, 35, 43, 1, 23, 28, 36, 17, 7, + 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26, + 42, 3, 14, 15, 9, 37, 21, 24, 44, 8, 50, 29, + + 27, 6, 55, 39, 40, 11, 25, 34, 4, 46, 26, 13, + 7, 29, 23, 17, 42, 50, 8, 30, 35, 43, 24, 14, + 31, 41, 52, 19, 32, 54, 45, 18, 5, 20, 53, 33, + 49, 10, 21, 22, 16, 44, 28, 0, 51, 15, 2, 36, +}; + +static const u8 parity[] = { + 8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3, + 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, + 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, + 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, + 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, + 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, + 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, + 4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8, +}; + + +static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src) +{ + u32 x, y, z; + + x = src[7]; + x <<= 8; + x |= src[6]; + x <<= 8; + x |= src[5]; + x <<= 8; + x |= src[4]; + y = src[3]; + y <<= 8; + y |= src[2]; + y <<= 8; + y |= src[1]; + y <<= 8; + y |= src[0]; + z = ((x >> 004) ^ y) & 0x0F0F0F0FL; + x ^= z << 004; + y ^= z; + z = ((y >> 020) ^ x) & 0x0000FFFFL; + y ^= z << 020; + x ^= z; + z = ((x >> 002) ^ y) & 0x33333333L; + x ^= z << 002; + y ^= z; + z = ((y >> 010) ^ x) & 0x00FF00FFL; + y ^= z << 010; + x ^= z; + x = x >> 1 | x << 31; + z = (x ^ y) & 0x55555555L; + y ^= z; + x ^= z; + y = y >> 1 | y << 31; + z = expkey[0]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[1]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[2]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[3]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[4]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[5]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[6]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[7]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[8]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[9]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[10]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[11]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[12]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[13]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[14]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[15]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[16]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[17]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[18]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[19]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[20]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[21]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[22]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[23]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[24]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[25]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[26]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[27]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[28]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[29]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[30]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[31]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + x = x << 1 | x >> 31; + z = (x ^ y) & 0x55555555L; + y ^= z; + x ^= z; + y = y << 1 | y >> 31; + z = ((x >> 010) ^ y) & 0x00FF00FFL; + x ^= z << 010; + y ^= z; + z = ((y >> 002) ^ x) & 0x33333333L; + y ^= z << 002; + x ^= z; + z = ((x >> 020) ^ y) & 0x0000FFFFL; + x ^= z << 020; + y ^= z; + z = ((y >> 004) ^ x) & 0x0F0F0F0FL; + y ^= z << 004; + x ^= z; + dst[0] = x; + x >>= 8; + dst[1] = x; + x >>= 8; + dst[2] = x; + x >>= 8; + dst[3] = x; + dst[4] = y; + y >>= 8; + dst[5] = y; + y >>= 8; + dst[6] = y; + y >>= 8; + dst[7] = y; +} + +static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src) +{ + u32 x, y, z; + + x = src[7]; + x <<= 8; + x |= src[6]; + x <<= 8; + x |= src[5]; + x <<= 8; + x |= src[4]; + y = src[3]; + y <<= 8; + y |= src[2]; + y <<= 8; + y |= src[1]; + y <<= 8; + y |= src[0]; + z = ((x >> 004) ^ y) & 0x0F0F0F0FL; + x ^= z << 004; + y ^= z; + z = ((y >> 020) ^ x) & 0x0000FFFFL; + y ^= z << 020; + x ^= z; + z = ((x >> 002) ^ y) & 0x33333333L; + x ^= z << 002; + y ^= z; + z = ((y >> 010) ^ x) & 0x00FF00FFL; + y ^= z << 010; + x ^= z; + x = x >> 1 | x << 31; + z = (x ^ y) & 0x55555555L; + y ^= z; + x ^= z; + y = y >> 1 | y << 31; + z = expkey[31]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[30]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[29]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[28]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[27]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[26]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[25]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[24]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[23]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[22]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[21]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[20]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[19]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[18]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[17]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[16]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[15]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[14]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[13]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[12]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[11]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[10]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[9]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[8]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[7]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[6]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[5]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[4]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[3]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[2]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + z = expkey[1]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); + z = expkey[0]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); + x = x << 1 | x >> 31; + z = (x ^ y) & 0x55555555L; + y ^= z; + x ^= z; + y = y << 1 | y >> 31; + z = ((x >> 010) ^ y) & 0x00FF00FFL; + x ^= z << 010; + y ^= z; + z = ((y >> 002) ^ x) & 0x33333333L; + y ^= z << 002; + x ^= z; + z = ((x >> 020) ^ y) & 0x0000FFFFL; + x ^= z << 020; + y ^= z; + z = ((y >> 004) ^ x) & 0x0F0F0F0FL; + y ^= z << 004; + x ^= z; + dst[0] = x; + x >>= 8; + dst[1] = x; + x >>= 8; + dst[2] = x; + x >>= 8; + dst[3] = x; + dst[4] = y; + y >>= 8; + dst[5] = y; + y >>= 8; + dst[6] = y; + y >>= 8; + dst[7] = y; +} + +/* + * RFC2451: Weak key checks SHOULD be performed. + */ +static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags) +{ + const u8 *k; + u8 *b0, *b1; + u32 n, w; + u8 bits0[56], bits1[56]; + + n = parity[key[0]]; n <<= 4; + n |= parity[key[1]]; n <<= 4; + n |= parity[key[2]]; n <<= 4; + n |= parity[key[3]]; n <<= 4; + n |= parity[key[4]]; n <<= 4; + n |= parity[key[5]]; n <<= 4; + n |= parity[key[6]]; n <<= 4; + n |= parity[key[7]]; + w = 0x88888888L; + + if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) + && !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */ + if (n < 0x41415151) { + if (n < 0x31312121) { + if (n < 0x14141515) { + /* 01 01 01 01 01 01 01 01 */ + if (n == 0x11111111) goto weak; + /* 01 1F 01 1F 01 0E 01 0E */ + if (n == 0x13131212) goto weak; + } else { + /* 01 E0 01 E0 01 F1 01 F1 */ + if (n == 0x14141515) goto weak; + /* 01 FE 01 FE 01 FE 01 FE */ + if (n == 0x16161616) goto weak; + } + } else { + if (n < 0x34342525) { + /* 1F 01 1F 01 0E 01 0E 01 */ + if (n == 0x31312121) goto weak; + /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */ + if (n == 0x33332222) goto weak; + } else { + /* 1F E0 1F E0 0E F1 0E F1 */ + if (n == 0x34342525) goto weak; + /* 1F FE 1F FE 0E FE 0E FE */ + if (n == 0x36362626) goto weak; + } + } + } else { + if (n < 0x61616161) { + if (n < 0x44445555) { + /* E0 01 E0 01 F1 01 F1 01 */ + if (n == 0x41415151) goto weak; + /* E0 1F E0 1F F1 0E F1 0E */ + if (n == 0x43435252) goto weak; + } else { + /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */ + if (n == 0x44445555) goto weak; + /* E0 FE E0 FE F1 FE F1 FE */ + if (n == 0x46465656) goto weak; + } + } else { + if (n < 0x64646565) { + /* FE 01 FE 01 FE 01 FE 01 */ + if (n == 0x61616161) goto weak; + /* FE 1F FE 1F FE 0E FE 0E */ + if (n == 0x63636262) goto weak; + } else { + /* FE E0 FE E0 FE F1 FE F1 */ + if (n == 0x64646565) goto weak; + /* FE FE FE FE FE FE FE FE */ + if (n == 0x66666666) goto weak; + } + } + } + + goto not_weak; +weak: + *flags |= CRYPTO_TFM_RES_WEAK_KEY; + return -EINVAL; + } + +not_weak: + + /* explode the bits */ + n = 56; + b0 = bits0; + b1 = bits1; + + do { + w = (256 | *key++) << 2; + do { + --n; + b1[n] = 8 & w; + w >>= 1; + b0[n] = 4 & w; + } while ( w >= 16 ); + } while ( n ); + + /* put the bits in the correct places */ + n = 16; + k = rotors; + + do { + w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4; + w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2; + w |= b1[k[ 4 ]] | b0[k[ 5 ]]; + w <<= 8; + w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4; + w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2; + w |= b1[k[10 ]] | b0[k[11 ]]; + w <<= 8; + w |= (b1[k[12 ]] | b0[k[13 ]]) << 4; + w |= (b1[k[14 ]] | b0[k[15 ]]) << 2; + w |= b1[k[16 ]] | b0[k[17 ]]; + w <<= 8; + w |= (b1[k[18 ]] | b0[k[19 ]]) << 4; + w |= (b1[k[20 ]] | b0[k[21 ]]) << 2; + w |= b1[k[22 ]] | b0[k[23 ]]; + expkey[0] = w; + + w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4; + w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2; + w |= b1[k[ 4+24]] | b0[k[ 5+24]]; + w <<= 8; + w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4; + w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2; + w |= b1[k[10+24]] | b0[k[11+24]]; + w <<= 8; + w |= (b1[k[12+24]] | b0[k[13+24]]) << 4; + w |= (b1[k[14+24]] | b0[k[15+24]]) << 2; + w |= b1[k[16+24]] | b0[k[17+24]]; + w <<= 8; + w |= (b1[k[18+24]] | b0[k[19+24]]) << 4; + w |= (b1[k[20+24]] | b0[k[21+24]]) << 2; + w |= b1[k[22+24]] | b0[k[23+24]]; + + ROR(w, 4, 28); /* could be eliminated */ + expkey[1] = w; + + k += 48; + expkey += 2; + } while (--n); + + return 0; +} + +static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) +{ + return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags); +} + +static void des_encrypt(void *ctx, u8 *dst, const u8 *src) +{ + des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src); +} + +static void des_decrypt(void *ctx, u8 *dst, const u8 *src) +{ + des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src); +} + +/* + * RFC2451: + * + * For DES-EDE3, there is no known need to reject weak or + * complementation keys. Any weakness is obviated by the use of + * multiple keys. + * + * However, if the first two or last two independent 64-bit keys are + * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the + * same as DES. Implementers MUST reject keys that exhibit this + * property. + * + */ +static int des3_ede_setkey(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags) +{ + unsigned int i, off; + struct des3_ede_ctx *dctx = ctx; + + if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && + memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], + DES_KEY_SIZE))) { + + *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; + return -EINVAL; + } + + for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS, + key += DES_KEY_SIZE) { + int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags); + if (ret < 0) + return ret; + } + return 0; +} + +static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src) +{ + struct des3_ede_ctx *dctx = ctx; + + des_small_fips_encrypt(dctx->expkey, dst, src); + des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst); + des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst); +} + +static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src) +{ + struct des3_ede_ctx *dctx = ctx; + + des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src); + des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst); + des_small_fips_decrypt(dctx->expkey, dst, dst); +} + +static struct crypto_alg des_alg = { + .cra_name = "des", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct des_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(des_alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = DES_KEY_SIZE, + .cia_max_keysize = DES_KEY_SIZE, + .cia_ivsize = DES_BLOCK_SIZE, + .cia_setkey = des_setkey, + .cia_encrypt = des_encrypt, + .cia_decrypt = des_decrypt } } +}; + +static struct crypto_alg des3_ede_alg = { + .cra_name = "des3_ede", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct des3_ede_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(des3_ede_alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = DES3_EDE_KEY_SIZE, + .cia_max_keysize = DES3_EDE_KEY_SIZE, + .cia_ivsize = DES3_EDE_BLOCK_SIZE, + .cia_setkey = des3_ede_setkey, + .cia_encrypt = des3_ede_encrypt, + .cia_decrypt = des3_ede_decrypt } } +}; + +static int __init init(void) +{ + int ret = 0; + + ret = crypto_register_alg(&des_alg); + if (ret < 0) + goto out; + + ret = crypto_register_alg(&des3_ede_alg); + if (ret < 0) + crypto_unregister_alg(&des_alg); +out: + return ret; +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&des3_ede_alg); + crypto_unregister_alg(&des_alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); diff -urN linux-2.4.21/crypto/digest.c linux-2.4.22/crypto/digest.c --- linux-2.4.21/crypto/digest.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/digest.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,82 @@ +/* + * Cryptographic API. + * + * Digest operations. + * + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include "internal.h" + +static void init(struct crypto_tfm *tfm) +{ + tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm)); +} + +static void update(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg) +{ + unsigned int i; + + for (i = 0; i < nsg; i++) { + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; + tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), + p, sg[i].length); + crypto_kunmap(p, 0); + crypto_yield(tfm); + } +} + +static void final(struct crypto_tfm *tfm, u8 *out) +{ + tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); +} + +static void digest(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg, u8 *out) +{ + unsigned int i; + + tfm->crt_digest.dit_init(tfm); + + for (i = 0; i < nsg; i++) { + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; + tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), + p, sg[i].length); + crypto_kunmap(p, 0); + crypto_yield(tfm); + } + crypto_digest_final(tfm, out); +} + +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + +int crypto_init_digest_ops(struct crypto_tfm *tfm) +{ + struct digest_tfm *ops = &tfm->crt_digest; + + ops->dit_init = init; + ops->dit_update = update; + ops->dit_final = final; + ops->dit_digest = digest; + + return crypto_alloc_hmac_block(tfm); +} + +void crypto_exit_digest_ops(struct crypto_tfm *tfm) +{ + crypto_free_hmac_block(tfm); +} diff -urN linux-2.4.21/crypto/hmac.c linux-2.4.22/crypto/hmac.c --- linux-2.4.21/crypto/hmac.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/hmac.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,134 @@ +/* + * Cryptographic API. + * + * HMAC: Keyed-Hashing for Message Authentication (RFC2104). + * + * Copyright (c) 2002 James Morris + * + * The HMAC implementation is derived from USAGI. + * Copyright (c) 2002 Kazunori Miyazawa / USAGI + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include "internal.h" + +static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen) +{ + struct scatterlist tmp; + + tmp.page = virt_to_page(key); + tmp.offset = ((long)key & ~PAGE_MASK); + tmp.length = keylen; + crypto_digest_digest(tfm, &tmp, 1, key); + +} + +int crypto_alloc_hmac_block(struct crypto_tfm *tfm) +{ + int ret = 0; + + BUG_ON(!crypto_tfm_alg_blocksize(tfm)); + + tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm), + GFP_KERNEL); + if (tfm->crt_digest.dit_hmac_block == NULL) + ret = -ENOMEM; + + return ret; + +} + +void crypto_free_hmac_block(struct crypto_tfm *tfm) +{ + if (tfm->crt_digest.dit_hmac_block) + kfree(tfm->crt_digest.dit_hmac_block); +} + +void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) +{ + unsigned int i; + struct scatterlist tmp; + char *ipad = tfm->crt_digest.dit_hmac_block; + + if (*keylen > crypto_tfm_alg_blocksize(tfm)) { + hash_key(tfm, key, *keylen); + *keylen = crypto_tfm_alg_digestsize(tfm); + } + + memset(ipad, 0, crypto_tfm_alg_blocksize(tfm)); + memcpy(ipad, key, *keylen); + + for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++) + ipad[i] ^= 0x36; + + tmp.page = virt_to_page(ipad); + tmp.offset = ((long)ipad & ~PAGE_MASK); + tmp.length = crypto_tfm_alg_blocksize(tfm); + + crypto_digest_init(tfm); + crypto_digest_update(tfm, &tmp, 1); +} + +void crypto_hmac_update(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg) +{ + crypto_digest_update(tfm, sg, nsg); +} + +void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, + unsigned int *keylen, u8 *out) +{ + unsigned int i; + struct scatterlist tmp; + char *opad = tfm->crt_digest.dit_hmac_block; + + if (*keylen > crypto_tfm_alg_blocksize(tfm)) { + hash_key(tfm, key, *keylen); + *keylen = crypto_tfm_alg_digestsize(tfm); + } + + crypto_digest_final(tfm, out); + + memset(opad, 0, crypto_tfm_alg_blocksize(tfm)); + memcpy(opad, key, *keylen); + + for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++) + opad[i] ^= 0x5c; + + tmp.page = virt_to_page(opad); + tmp.offset = ((long)opad & ~PAGE_MASK); + tmp.length = crypto_tfm_alg_blocksize(tfm); + + crypto_digest_init(tfm); + crypto_digest_update(tfm, &tmp, 1); + + tmp.page = virt_to_page(out); + tmp.offset = ((long)out & ~PAGE_MASK); + tmp.length = crypto_tfm_alg_digestsize(tfm); + + crypto_digest_update(tfm, &tmp, 1); + crypto_digest_final(tfm, out); +} + +void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, + struct scatterlist *sg, unsigned int nsg, u8 *out) +{ + crypto_hmac_init(tfm, key, keylen); + crypto_hmac_update(tfm, sg, nsg); + crypto_hmac_final(tfm, key, keylen, out); +} + +EXPORT_SYMBOL_GPL(crypto_hmac_init); +EXPORT_SYMBOL_GPL(crypto_hmac_update); +EXPORT_SYMBOL_GPL(crypto_hmac_final); +EXPORT_SYMBOL_GPL(crypto_hmac); + diff -urN linux-2.4.21/crypto/internal.h linux-2.4.22/crypto/internal.h --- linux-2.4.21/crypto/internal.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/internal.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,94 @@ +/* + * Cryptographic API. + * + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#ifndef _CRYPTO_INTERNAL_H +#define _CRYPTO_INTERNAL_H +#include +#include +#include +#include +#include +#include + +extern enum km_type crypto_km_types[]; + +static inline enum km_type crypto_kmap_type(int out) +{ + return crypto_km_types[(in_softirq() ? 2 : 0) + out]; +} + +static inline void *crypto_kmap(struct page *page, int out) +{ + return kmap_atomic(page, crypto_kmap_type(out)); +} + +static inline void crypto_kunmap(void *vaddr, int out) +{ + kunmap_atomic(vaddr, crypto_kmap_type(out)); +} + +static inline void crypto_yield(struct crypto_tfm *tfm) +{ + if (!in_softirq()) + cond_resched(); +} + +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) +{ + return (void *)&tfm[1]; +} + +struct crypto_alg *crypto_alg_lookup(const char *name); + +#ifdef CONFIG_KMOD +void crypto_alg_autoload(const char *name); +struct crypto_alg *crypto_alg_mod_lookup(const char *name); +#else +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) +{ + return crypto_alg_lookup(name); +} +#endif + +#ifdef CONFIG_CRYPTO_HMAC +int crypto_alloc_hmac_block(struct crypto_tfm *tfm); +void crypto_free_hmac_block(struct crypto_tfm *tfm); +#else +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm) +{ + return 0; +} + +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm) +{ } +#endif + +#ifdef CONFIG_PROC_FS +void __init crypto_init_proc(void); +#else +static inline void crypto_init_proc(void) +{ } +#endif + +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); + +int crypto_init_digest_ops(struct crypto_tfm *tfm); +int crypto_init_cipher_ops(struct crypto_tfm *tfm); +int crypto_init_compress_ops(struct crypto_tfm *tfm); + +void crypto_exit_digest_ops(struct crypto_tfm *tfm); +void crypto_exit_cipher_ops(struct crypto_tfm *tfm); +void crypto_exit_compress_ops(struct crypto_tfm *tfm); + +#endif /* _CRYPTO_INTERNAL_H */ + diff -urN linux-2.4.21/crypto/md4.c linux-2.4.22/crypto/md4.c --- linux-2.4.21/crypto/md4.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/md4.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,250 @@ +/* + * Cryptographic API. + * + * MD4 Message Digest Algorithm (RFC1320). + * + * Implementation derived from Andrew Tridgell and Steve French's + * CIFS MD4 implementation, and the cryptoapi implementation + * originally based on the public domain implementation written + * by Colin Plumb in 1993. + * + * Copyright (c) Andrew Tridgell 1997-1998. + * Modified by Steve French (sfrench@us.ibm.com) 2002 + * Copyright (c) Cryptoapi developers. + * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include +#include +#include +#include + +#define MD4_DIGEST_SIZE 16 +#define MD4_HMAC_BLOCK_SIZE 64 +#define MD4_BLOCK_WORDS 16 +#define MD4_HASH_WORDS 4 + +struct md4_ctx { + u32 hash[MD4_HASH_WORDS]; + u32 block[MD4_BLOCK_WORDS]; + u64 byte_count; +}; + +static inline u32 lshift(u32 x, unsigned int s) +{ + x &= 0xFFFFFFFF; + return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); +} + +static inline u32 F(u32 x, u32 y, u32 z) +{ + return (x & y) | ((~x) & z); +} + +static inline u32 G(u32 x, u32 y, u32 z) +{ + return (x & y) | (x & z) | (y & z); +} + +static inline u32 H(u32 x, u32 y, u32 z) +{ + return x ^ y ^ z; +} + +#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s)) +#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s)) +#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s)) + +/* XXX: this stuff can be optimized */ +static inline void le32_to_cpu_array(u32 *buf, unsigned int words) +{ + while (words--) { + __le32_to_cpus(buf); + buf++; + } +} + +static inline void cpu_to_le32_array(u32 *buf, unsigned int words) +{ + while (words--) { + __cpu_to_le32s(buf); + buf++; + } +} + +static void md4_transform(u32 *hash, u32 const *in) +{ + u32 a, b, c, d; + + a = hash[0]; + b = hash[1]; + c = hash[2]; + d = hash[3]; + + ROUND1(a, b, c, d, in[0], 3); + ROUND1(d, a, b, c, in[1], 7); + ROUND1(c, d, a, b, in[2], 11); + ROUND1(b, c, d, a, in[3], 19); + ROUND1(a, b, c, d, in[4], 3); + ROUND1(d, a, b, c, in[5], 7); + ROUND1(c, d, a, b, in[6], 11); + ROUND1(b, c, d, a, in[7], 19); + ROUND1(a, b, c, d, in[8], 3); + ROUND1(d, a, b, c, in[9], 7); + ROUND1(c, d, a, b, in[10], 11); + ROUND1(b, c, d, a, in[11], 19); + ROUND1(a, b, c, d, in[12], 3); + ROUND1(d, a, b, c, in[13], 7); + ROUND1(c, d, a, b, in[14], 11); + ROUND1(b, c, d, a, in[15], 19); + + ROUND2(a, b, c, d,in[ 0], 3); + ROUND2(d, a, b, c, in[4], 5); + ROUND2(c, d, a, b, in[8], 9); + ROUND2(b, c, d, a, in[12], 13); + ROUND2(a, b, c, d, in[1], 3); + ROUND2(d, a, b, c, in[5], 5); + ROUND2(c, d, a, b, in[9], 9); + ROUND2(b, c, d, a, in[13], 13); + ROUND2(a, b, c, d, in[2], 3); + ROUND2(d, a, b, c, in[6], 5); + ROUND2(c, d, a, b, in[10], 9); + ROUND2(b, c, d, a, in[14], 13); + ROUND2(a, b, c, d, in[3], 3); + ROUND2(d, a, b, c, in[7], 5); + ROUND2(c, d, a, b, in[11], 9); + ROUND2(b, c, d, a, in[15], 13); + + ROUND3(a, b, c, d,in[ 0], 3); + ROUND3(d, a, b, c, in[8], 9); + ROUND3(c, d, a, b, in[4], 11); + ROUND3(b, c, d, a, in[12], 15); + ROUND3(a, b, c, d, in[2], 3); + ROUND3(d, a, b, c, in[10], 9); + ROUND3(c, d, a, b, in[6], 11); + ROUND3(b, c, d, a, in[14], 15); + ROUND3(a, b, c, d, in[1], 3); + ROUND3(d, a, b, c, in[9], 9); + ROUND3(c, d, a, b, in[5], 11); + ROUND3(b, c, d, a, in[13], 15); + ROUND3(a, b, c, d, in[3], 3); + ROUND3(d, a, b, c, in[11], 9); + ROUND3(c, d, a, b, in[7], 11); + ROUND3(b, c, d, a, in[15], 15); + + hash[0] += a; + hash[1] += b; + hash[2] += c; + hash[3] += d; +} + +static inline void md4_transform_helper(struct md4_ctx *ctx) +{ + le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32)); + md4_transform(ctx->hash, ctx->block); +} + +static void md4_init(void *ctx) +{ + struct md4_ctx *mctx = ctx; + + mctx->hash[0] = 0x67452301; + mctx->hash[1] = 0xefcdab89; + mctx->hash[2] = 0x98badcfe; + mctx->hash[3] = 0x10325476; + mctx->byte_count = 0; +} + +static void md4_update(void *ctx, const u8 *data, unsigned int len) +{ + struct md4_ctx *mctx = ctx; + const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); + + mctx->byte_count += len; + + if (avail > len) { + memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), + data, len); + return; + } + + memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), + data, avail); + + md4_transform_helper(mctx); + data += avail; + len -= avail; + + while (len >= sizeof(mctx->block)) { + memcpy(mctx->block, data, sizeof(mctx->block)); + md4_transform_helper(mctx); + data += sizeof(mctx->block); + len -= sizeof(mctx->block); + } + + memcpy(mctx->block, data, len); +} + +static void md4_final(void *ctx, u8 *out) +{ + struct md4_ctx *mctx = ctx; + const unsigned int offset = mctx->byte_count & 0x3f; + char *p = (char *)mctx->block + offset; + int padding = 56 - (offset + 1); + + *p++ = 0x80; + if (padding < 0) { + memset(p, 0x00, padding + sizeof (u64)); + md4_transform_helper(mctx); + p = (char *)mctx->block; + padding = 56; + } + + memset(p, 0, padding); + mctx->block[14] = mctx->byte_count << 3; + mctx->block[15] = mctx->byte_count >> 29; + le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - + sizeof(u64)) / sizeof(u32)); + md4_transform(mctx->hash, mctx->block); + cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); + memcpy(out, mctx->hash, sizeof(mctx->hash)); + memset(mctx, 0, sizeof(*mctx)); +} + +static struct crypto_alg alg = { + .cra_name = "md4", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = MD4_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct md4_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = MD4_DIGEST_SIZE, + .dia_init = md4_init, + .dia_update = md4_update, + .dia_final = md4_final } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MD4 Message Digest Algorithm"); + diff -urN linux-2.4.21/crypto/md5.c linux-2.4.22/crypto/md5.c --- linux-2.4.21/crypto/md5.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/md5.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,244 @@ +/* + * Cryptographic API. + * + * MD5 Message Digest Algorithm (RFC1321). + * + * Derived from cryptoapi implementation, originally based on the + * public domain implementation written by Colin Plumb in 1993. + * + * Copyright (c) Cryptoapi developers. + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include + +#define MD5_DIGEST_SIZE 16 +#define MD5_HMAC_BLOCK_SIZE 64 +#define MD5_BLOCK_WORDS 16 +#define MD5_HASH_WORDS 4 + +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, in, s) \ + (w += f(x, y, z) + in, w = (w<>(32-s)) + x) + +struct md5_ctx { + u32 hash[MD5_HASH_WORDS]; + u32 block[MD5_BLOCK_WORDS]; + u64 byte_count; +}; + +static void md5_transform(u32 *hash, u32 const *in) +{ + u32 a, b, c, d; + + a = hash[0]; + b = hash[1]; + c = hash[2]; + d = hash[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + hash[0] += a; + hash[1] += b; + hash[2] += c; + hash[3] += d; +} + +/* XXX: this stuff can be optimized */ +static inline void le32_to_cpu_array(u32 *buf, unsigned int words) +{ + while (words--) { + __le32_to_cpus(buf); + buf++; + } +} + +static inline void cpu_to_le32_array(u32 *buf, unsigned int words) +{ + while (words--) { + __cpu_to_le32s(buf); + buf++; + } +} + +static inline void md5_transform_helper(struct md5_ctx *ctx) +{ + le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32)); + md5_transform(ctx->hash, ctx->block); +} + +static void md5_init(void *ctx) +{ + struct md5_ctx *mctx = ctx; + + mctx->hash[0] = 0x67452301; + mctx->hash[1] = 0xefcdab89; + mctx->hash[2] = 0x98badcfe; + mctx->hash[3] = 0x10325476; + mctx->byte_count = 0; +} + +static void md5_update(void *ctx, const u8 *data, unsigned int len) +{ + struct md5_ctx *mctx = ctx; + const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); + + mctx->byte_count += len; + + if (avail > len) { + memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), + data, len); + return; + } + + memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), + data, avail); + + md5_transform_helper(mctx); + data += avail; + len -= avail; + + while (len >= sizeof(mctx->block)) { + memcpy(mctx->block, data, sizeof(mctx->block)); + md5_transform_helper(mctx); + data += sizeof(mctx->block); + len -= sizeof(mctx->block); + } + + memcpy(mctx->block, data, len); +} + +static void md5_final(void *ctx, u8 *out) +{ + struct md5_ctx *mctx = ctx; + const unsigned int offset = mctx->byte_count & 0x3f; + char *p = (char *)mctx->block + offset; + int padding = 56 - (offset + 1); + + *p++ = 0x80; + if (padding < 0) { + memset(p, 0x00, padding + sizeof (u64)); + md5_transform_helper(mctx); + p = (char *)mctx->block; + padding = 56; + } + + memset(p, 0, padding); + mctx->block[14] = mctx->byte_count << 3; + mctx->block[15] = mctx->byte_count >> 29; + le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - + sizeof(u64)) / sizeof(u32)); + md5_transform(mctx->hash, mctx->block); + cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); + memcpy(out, mctx->hash, sizeof(mctx->hash)); + memset(mctx, 0, sizeof(*mctx)); +} + +static struct crypto_alg alg = { + .cra_name = "md5", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct md5_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = MD5_DIGEST_SIZE, + .dia_init = md5_init, + .dia_update = md5_update, + .dia_final = md5_final } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MD5 Message Digest Algorithm"); diff -urN linux-2.4.21/crypto/proc.c linux-2.4.22/crypto/proc.c --- linux-2.4.21/crypto/proc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/proc.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,109 @@ +/* + * Scatterlist Cryptographic API. + * + * Procfs information. + * + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include "internal.h" + +extern struct list_head crypto_alg_list; +extern struct rw_semaphore crypto_alg_sem; + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + struct list_head *v; + loff_t n = *pos; + + down_read(&crypto_alg_sem); + list_for_each(v, &crypto_alg_list) + if (!n--) + return list_entry(v, struct crypto_alg, cra_list); + return NULL; +} + +static void *c_next(struct seq_file *m, void *p, loff_t *pos) +{ + struct list_head *v = p; + + (*pos)++; + v = v->next; + return (v == &crypto_alg_list) ? + NULL : list_entry(v, struct crypto_alg, cra_list); +} + +static void c_stop(struct seq_file *m, void *p) +{ + up_read(&crypto_alg_sem); +} + +static int c_show(struct seq_file *m, void *p) +{ + struct crypto_alg *alg = (struct crypto_alg *)p; + + seq_printf(m, "name : %s\n", alg->cra_name); + seq_printf(m, "module : %s\n", + (alg->cra_module ? + alg->cra_module->name : + "kernel")); + + switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { + case CRYPTO_ALG_TYPE_CIPHER: + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); + seq_printf(m, "min keysize : %u\n", + alg->cra_cipher.cia_min_keysize); + seq_printf(m, "max keysize : %u\n", + alg->cra_cipher.cia_max_keysize); + seq_printf(m, "ivsize : %u\n", + alg->cra_cipher.cia_ivsize); + break; + + case CRYPTO_ALG_TYPE_DIGEST: + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); + seq_printf(m, "digestsize : %u\n", + alg->cra_digest.dia_digestsize); + break; + } + + seq_putc(m, '\n'); + return 0; +} + +static struct seq_operations crypto_seq_ops = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show +}; + +static int crypto_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &crypto_seq_ops); +} + +static struct file_operations proc_crypto_ops = { + .open = crypto_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + +void __init crypto_init_proc(void) +{ + struct proc_dir_entry *proc; + + proc = create_proc_entry("crypto", 0, NULL); + if (proc) + proc->proc_fops = &proc_crypto_ops; +} diff -urN linux-2.4.21/crypto/serpent.c linux-2.4.22/crypto/serpent.c --- linux-2.4.21/crypto/serpent.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/serpent.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,507 @@ +/* + * Cryptographic API. + * + * Serpent Cipher Algorithm. + * + * Copyright (C) 2002 Dag Arne Osvik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +/* Key is padded to the maximum of 256 bits before round key generation. + * Any key length <= 256 bits (32 bytes) is allowed by the algorithm. + */ + +#define SERPENT_MIN_KEY_SIZE 0 +#define SERPENT_MAX_KEY_SIZE 32 +#define SERPENT_EXPKEY_WORDS 132 +#define SERPENT_BLOCK_SIZE 16 + +#define PHI 0x9e3779b9UL +#define ROL(x,r) ((x) = ((x) << (r)) | ((x) >> (32-(r)))) +#define ROR(x,r) ((x) = ((x) >> (r)) | ((x) << (32-(r)))) + +#define keyiter(a,b,c,d,i,j) \ + b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; ROL(b,11); k[j] = b; + +#define loadkeys(x0,x1,x2,x3,i) \ + x0=k[i]; x1=k[i+1]; x2=k[i+2]; x3=k[i+3]; + +#define storekeys(x0,x1,x2,x3,i) \ + k[i]=x0; k[i+1]=x1; k[i+2]=x2; k[i+3]=x3; + +#define K(x0,x1,x2,x3,i) \ + x3 ^= k[4*(i)+3]; x2 ^= k[4*(i)+2]; \ + x1 ^= k[4*(i)+1]; x0 ^= k[4*(i)+0]; + +#define LK(x0,x1,x2,x3,x4,i) \ + ROL(x0,13); \ + ROL(x2,3); x1 ^= x0; x4 = x0 << 3; \ + x3 ^= x2; x1 ^= x2; \ + ROL(x1,1); x3 ^= x4; \ + ROL(x3,7); x4 = x1; \ + x0 ^= x1; x4 <<= 7; x2 ^= x3; \ + x0 ^= x3; x2 ^= x4; x3 ^= k[4*i+3]; \ + x1 ^= k[4*i+1]; ROL(x0,5); ROL(x2,22); \ + x0 ^= k[4*i+0]; x2 ^= k[4*i+2]; + +#define KL(x0,x1,x2,x3,x4,i) \ + x0 ^= k[4*i+0]; x1 ^= k[4*i+1]; x2 ^= k[4*i+2]; \ + x3 ^= k[4*i+3]; ROR(x0,5); ROR(x2,22); \ + x4 = x1; x2 ^= x3; x0 ^= x3; \ + x4 <<= 7; x0 ^= x1; ROR(x1,1); \ + x2 ^= x4; ROR(x3,7); x4 = x0 << 3; \ + x1 ^= x0; x3 ^= x4; ROR(x0,13); \ + x1 ^= x2; x3 ^= x2; ROR(x2,3); + +#define S0(x0,x1,x2,x3,x4) \ + x4 = x3; \ + x3 |= x0; x0 ^= x4; x4 ^= x2; \ + x4 =~ x4; x3 ^= x1; x1 &= x0; \ + x1 ^= x4; x2 ^= x0; x0 ^= x3; \ + x4 |= x0; x0 ^= x2; x2 &= x1; \ + x3 ^= x2; x1 =~ x1; x2 ^= x4; \ + x1 ^= x2; + +#define S1(x0,x1,x2,x3,x4) \ + x4 = x1; \ + x1 ^= x0; x0 ^= x3; x3 =~ x3; \ + x4 &= x1; x0 |= x1; x3 ^= x2; \ + x0 ^= x3; x1 ^= x3; x3 ^= x4; \ + x1 |= x4; x4 ^= x2; x2 &= x0; \ + x2 ^= x1; x1 |= x0; x0 =~ x0; \ + x0 ^= x2; x4 ^= x1; + +#define S2(x0,x1,x2,x3,x4) \ + x3 =~ x3; \ + x1 ^= x0; x4 = x0; x0 &= x2; \ + x0 ^= x3; x3 |= x4; x2 ^= x1; \ + x3 ^= x1; x1 &= x0; x0 ^= x2; \ + x2 &= x3; x3 |= x1; x0 =~ x0; \ + x3 ^= x0; x4 ^= x0; x0 ^= x2; \ + x1 |= x2; + +#define S3(x0,x1,x2,x3,x4) \ + x4 = x1; \ + x1 ^= x3; x3 |= x0; x4 &= x0; \ + x0 ^= x2; x2 ^= x1; x1 &= x3; \ + x2 ^= x3; x0 |= x4; x4 ^= x3; \ + x1 ^= x0; x0 &= x3; x3 &= x4; \ + x3 ^= x2; x4 |= x1; x2 &= x1; \ + x4 ^= x3; x0 ^= x3; x3 ^= x2; + +#define S4(x0,x1,x2,x3,x4) \ + x4 = x3; \ + x3 &= x0; x0 ^= x4; \ + x3 ^= x2; x2 |= x4; x0 ^= x1; \ + x4 ^= x3; x2 |= x0; \ + x2 ^= x1; x1 &= x0; \ + x1 ^= x4; x4 &= x2; x2 ^= x3; \ + x4 ^= x0; x3 |= x1; x1 =~ x1; \ + x3 ^= x0; + +#define S5(x0,x1,x2,x3,x4) \ + x4 = x1; x1 |= x0; \ + x2 ^= x1; x3 =~ x3; x4 ^= x0; \ + x0 ^= x2; x1 &= x4; x4 |= x3; \ + x4 ^= x0; x0 &= x3; x1 ^= x3; \ + x3 ^= x2; x0 ^= x1; x2 &= x4; \ + x1 ^= x2; x2 &= x0; \ + x3 ^= x2; + +#define S6(x0,x1,x2,x3,x4) \ + x4 = x1; \ + x3 ^= x0; x1 ^= x2; x2 ^= x0; \ + x0 &= x3; x1 |= x3; x4 =~ x4; \ + x0 ^= x1; x1 ^= x2; \ + x3 ^= x4; x4 ^= x0; x2 &= x0; \ + x4 ^= x1; x2 ^= x3; x3 &= x1; \ + x3 ^= x0; x1 ^= x2; + +#define S7(x0,x1,x2,x3,x4) \ + x1 =~ x1; \ + x4 = x1; x0 =~ x0; x1 &= x2; \ + x1 ^= x3; x3 |= x4; x4 ^= x2; \ + x2 ^= x3; x3 ^= x0; x0 |= x1; \ + x2 &= x0; x0 ^= x4; x4 ^= x3; \ + x3 &= x0; x4 ^= x1; \ + x2 ^= x4; x3 ^= x1; x4 |= x0; \ + x4 ^= x1; + +#define SI0(x0,x1,x2,x3,x4) \ + x4 = x3; x1 ^= x0; \ + x3 |= x1; x4 ^= x1; x0 =~ x0; \ + x2 ^= x3; x3 ^= x0; x0 &= x1; \ + x0 ^= x2; x2 &= x3; x3 ^= x4; \ + x2 ^= x3; x1 ^= x3; x3 &= x0; \ + x1 ^= x0; x0 ^= x2; x4 ^= x3; + +#define SI1(x0,x1,x2,x3,x4) \ + x1 ^= x3; x4 = x0; \ + x0 ^= x2; x2 =~ x2; x4 |= x1; \ + x4 ^= x3; x3 &= x1; x1 ^= x2; \ + x2 &= x4; x4 ^= x1; x1 |= x3; \ + x3 ^= x0; x2 ^= x0; x0 |= x4; \ + x2 ^= x4; x1 ^= x0; \ + x4 ^= x1; + +#define SI2(x0,x1,x2,x3,x4) \ + x2 ^= x1; x4 = x3; x3 =~ x3; \ + x3 |= x2; x2 ^= x4; x4 ^= x0; \ + x3 ^= x1; x1 |= x2; x2 ^= x0; \ + x1 ^= x4; x4 |= x3; x2 ^= x3; \ + x4 ^= x2; x2 &= x1; \ + x2 ^= x3; x3 ^= x4; x4 ^= x0; + +#define SI3(x0,x1,x2,x3,x4) \ + x2 ^= x1; \ + x4 = x1; x1 &= x2; \ + x1 ^= x0; x0 |= x4; x4 ^= x3; \ + x0 ^= x3; x3 |= x1; x1 ^= x2; \ + x1 ^= x3; x0 ^= x2; x2 ^= x3; \ + x3 &= x1; x1 ^= x0; x0 &= x2; \ + x4 ^= x3; x3 ^= x0; x0 ^= x1; + +#define SI4(x0,x1,x2,x3,x4) \ + x2 ^= x3; x4 = x0; x0 &= x1; \ + x0 ^= x2; x2 |= x3; x4 =~ x4; \ + x1 ^= x0; x0 ^= x2; x2 &= x4; \ + x2 ^= x0; x0 |= x4; \ + x0 ^= x3; x3 &= x2; \ + x4 ^= x3; x3 ^= x1; x1 &= x0; \ + x4 ^= x1; x0 ^= x3; + +#define SI5(x0,x1,x2,x3,x4) \ + x4 = x1; x1 |= x2; \ + x2 ^= x4; x1 ^= x3; x3 &= x4; \ + x2 ^= x3; x3 |= x0; x0 =~ x0; \ + x3 ^= x2; x2 |= x0; x4 ^= x1; \ + x2 ^= x4; x4 &= x0; x0 ^= x1; \ + x1 ^= x3; x0 &= x2; x2 ^= x3; \ + x0 ^= x2; x2 ^= x4; x4 ^= x3; + +#define SI6(x0,x1,x2,x3,x4) \ + x0 ^= x2; \ + x4 = x0; x0 &= x3; x2 ^= x3; \ + x0 ^= x2; x3 ^= x1; x2 |= x4; \ + x2 ^= x3; x3 &= x0; x0 =~ x0; \ + x3 ^= x1; x1 &= x2; x4 ^= x0; \ + x3 ^= x4; x4 ^= x2; x0 ^= x1; \ + x2 ^= x0; + +#define SI7(x0,x1,x2,x3,x4) \ + x4 = x3; x3 &= x0; x0 ^= x2; \ + x2 |= x4; x4 ^= x1; x0 =~ x0; \ + x1 |= x3; x4 ^= x0; x0 &= x2; \ + x0 ^= x1; x1 &= x2; x3 ^= x2; \ + x4 ^= x3; x2 &= x3; x3 |= x0; \ + x1 ^= x4; x3 ^= x4; x4 &= x0; \ + x4 ^= x2; + +struct serpent_ctx { + u8 iv[SERPENT_BLOCK_SIZE]; + u32 expkey[SERPENT_EXPKEY_WORDS]; +}; + +static int setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) +{ + u32 *k = ((struct serpent_ctx *)ctx)->expkey; + u8 *k8 = (u8 *)k; + u32 r0,r1,r2,r3,r4; + int i; + + if ((keylen < SERPENT_MIN_KEY_SIZE) + || (keylen > SERPENT_MAX_KEY_SIZE)) + { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + /* Copy key, add padding */ + + for (i = 0; i < keylen; ++i) + k8[i] = key[i]; + if (i < SERPENT_MAX_KEY_SIZE) + k8[i++] = 1; + while (i < SERPENT_MAX_KEY_SIZE) + k8[i++] = 0; + + /* Expand key using polynomial */ + + r0 = le32_to_cpu(k[3]); + r1 = le32_to_cpu(k[4]); + r2 = le32_to_cpu(k[5]); + r3 = le32_to_cpu(k[6]); + r4 = le32_to_cpu(k[7]); + + keyiter(le32_to_cpu(k[0]),r0,r4,r2,0,0); + keyiter(le32_to_cpu(k[1]),r1,r0,r3,1,1); + keyiter(le32_to_cpu(k[2]),r2,r1,r4,2,2); + keyiter(le32_to_cpu(k[3]),r3,r2,r0,3,3); + keyiter(le32_to_cpu(k[4]),r4,r3,r1,4,4); + keyiter(le32_to_cpu(k[5]),r0,r4,r2,5,5); + keyiter(le32_to_cpu(k[6]),r1,r0,r3,6,6); + keyiter(le32_to_cpu(k[7]),r2,r1,r4,7,7); + + keyiter(k[ 0],r3,r2,r0, 8, 8); keyiter(k[ 1],r4,r3,r1, 9, 9); + keyiter(k[ 2],r0,r4,r2, 10, 10); keyiter(k[ 3],r1,r0,r3, 11, 11); + keyiter(k[ 4],r2,r1,r4, 12, 12); keyiter(k[ 5],r3,r2,r0, 13, 13); + keyiter(k[ 6],r4,r3,r1, 14, 14); keyiter(k[ 7],r0,r4,r2, 15, 15); + keyiter(k[ 8],r1,r0,r3, 16, 16); keyiter(k[ 9],r2,r1,r4, 17, 17); + keyiter(k[ 10],r3,r2,r0, 18, 18); keyiter(k[ 11],r4,r3,r1, 19, 19); + keyiter(k[ 12],r0,r4,r2, 20, 20); keyiter(k[ 13],r1,r0,r3, 21, 21); + keyiter(k[ 14],r2,r1,r4, 22, 22); keyiter(k[ 15],r3,r2,r0, 23, 23); + keyiter(k[ 16],r4,r3,r1, 24, 24); keyiter(k[ 17],r0,r4,r2, 25, 25); + keyiter(k[ 18],r1,r0,r3, 26, 26); keyiter(k[ 19],r2,r1,r4, 27, 27); + keyiter(k[ 20],r3,r2,r0, 28, 28); keyiter(k[ 21],r4,r3,r1, 29, 29); + keyiter(k[ 22],r0,r4,r2, 30, 30); keyiter(k[ 23],r1,r0,r3, 31, 31); + + k += 50; + + keyiter(k[-26],r2,r1,r4, 32,-18); keyiter(k[-25],r3,r2,r0, 33,-17); + keyiter(k[-24],r4,r3,r1, 34,-16); keyiter(k[-23],r0,r4,r2, 35,-15); + keyiter(k[-22],r1,r0,r3, 36,-14); keyiter(k[-21],r2,r1,r4, 37,-13); + keyiter(k[-20],r3,r2,r0, 38,-12); keyiter(k[-19],r4,r3,r1, 39,-11); + keyiter(k[-18],r0,r4,r2, 40,-10); keyiter(k[-17],r1,r0,r3, 41, -9); + keyiter(k[-16],r2,r1,r4, 42, -8); keyiter(k[-15],r3,r2,r0, 43, -7); + keyiter(k[-14],r4,r3,r1, 44, -6); keyiter(k[-13],r0,r4,r2, 45, -5); + keyiter(k[-12],r1,r0,r3, 46, -4); keyiter(k[-11],r2,r1,r4, 47, -3); + keyiter(k[-10],r3,r2,r0, 48, -2); keyiter(k[ -9],r4,r3,r1, 49, -1); + keyiter(k[ -8],r0,r4,r2, 50, 0); keyiter(k[ -7],r1,r0,r3, 51, 1); + keyiter(k[ -6],r2,r1,r4, 52, 2); keyiter(k[ -5],r3,r2,r0, 53, 3); + keyiter(k[ -4],r4,r3,r1, 54, 4); keyiter(k[ -3],r0,r4,r2, 55, 5); + keyiter(k[ -2],r1,r0,r3, 56, 6); keyiter(k[ -1],r2,r1,r4, 57, 7); + keyiter(k[ 0],r3,r2,r0, 58, 8); keyiter(k[ 1],r4,r3,r1, 59, 9); + keyiter(k[ 2],r0,r4,r2, 60, 10); keyiter(k[ 3],r1,r0,r3, 61, 11); + keyiter(k[ 4],r2,r1,r4, 62, 12); keyiter(k[ 5],r3,r2,r0, 63, 13); + keyiter(k[ 6],r4,r3,r1, 64, 14); keyiter(k[ 7],r0,r4,r2, 65, 15); + keyiter(k[ 8],r1,r0,r3, 66, 16); keyiter(k[ 9],r2,r1,r4, 67, 17); + keyiter(k[ 10],r3,r2,r0, 68, 18); keyiter(k[ 11],r4,r3,r1, 69, 19); + keyiter(k[ 12],r0,r4,r2, 70, 20); keyiter(k[ 13],r1,r0,r3, 71, 21); + keyiter(k[ 14],r2,r1,r4, 72, 22); keyiter(k[ 15],r3,r2,r0, 73, 23); + keyiter(k[ 16],r4,r3,r1, 74, 24); keyiter(k[ 17],r0,r4,r2, 75, 25); + keyiter(k[ 18],r1,r0,r3, 76, 26); keyiter(k[ 19],r2,r1,r4, 77, 27); + keyiter(k[ 20],r3,r2,r0, 78, 28); keyiter(k[ 21],r4,r3,r1, 79, 29); + keyiter(k[ 22],r0,r4,r2, 80, 30); keyiter(k[ 23],r1,r0,r3, 81, 31); + + k += 50; + + keyiter(k[-26],r2,r1,r4, 82,-18); keyiter(k[-25],r3,r2,r0, 83,-17); + keyiter(k[-24],r4,r3,r1, 84,-16); keyiter(k[-23],r0,r4,r2, 85,-15); + keyiter(k[-22],r1,r0,r3, 86,-14); keyiter(k[-21],r2,r1,r4, 87,-13); + keyiter(k[-20],r3,r2,r0, 88,-12); keyiter(k[-19],r4,r3,r1, 89,-11); + keyiter(k[-18],r0,r4,r2, 90,-10); keyiter(k[-17],r1,r0,r3, 91, -9); + keyiter(k[-16],r2,r1,r4, 92, -8); keyiter(k[-15],r3,r2,r0, 93, -7); + keyiter(k[-14],r4,r3,r1, 94, -6); keyiter(k[-13],r0,r4,r2, 95, -5); + keyiter(k[-12],r1,r0,r3, 96, -4); keyiter(k[-11],r2,r1,r4, 97, -3); + keyiter(k[-10],r3,r2,r0, 98, -2); keyiter(k[ -9],r4,r3,r1, 99, -1); + keyiter(k[ -8],r0,r4,r2,100, 0); keyiter(k[ -7],r1,r0,r3,101, 1); + keyiter(k[ -6],r2,r1,r4,102, 2); keyiter(k[ -5],r3,r2,r0,103, 3); + keyiter(k[ -4],r4,r3,r1,104, 4); keyiter(k[ -3],r0,r4,r2,105, 5); + keyiter(k[ -2],r1,r0,r3,106, 6); keyiter(k[ -1],r2,r1,r4,107, 7); + keyiter(k[ 0],r3,r2,r0,108, 8); keyiter(k[ 1],r4,r3,r1,109, 9); + keyiter(k[ 2],r0,r4,r2,110, 10); keyiter(k[ 3],r1,r0,r3,111, 11); + keyiter(k[ 4],r2,r1,r4,112, 12); keyiter(k[ 5],r3,r2,r0,113, 13); + keyiter(k[ 6],r4,r3,r1,114, 14); keyiter(k[ 7],r0,r4,r2,115, 15); + keyiter(k[ 8],r1,r0,r3,116, 16); keyiter(k[ 9],r2,r1,r4,117, 17); + keyiter(k[ 10],r3,r2,r0,118, 18); keyiter(k[ 11],r4,r3,r1,119, 19); + keyiter(k[ 12],r0,r4,r2,120, 20); keyiter(k[ 13],r1,r0,r3,121, 21); + keyiter(k[ 14],r2,r1,r4,122, 22); keyiter(k[ 15],r3,r2,r0,123, 23); + keyiter(k[ 16],r4,r3,r1,124, 24); keyiter(k[ 17],r0,r4,r2,125, 25); + keyiter(k[ 18],r1,r0,r3,126, 26); keyiter(k[ 19],r2,r1,r4,127, 27); + keyiter(k[ 20],r3,r2,r0,128, 28); keyiter(k[ 21],r4,r3,r1,129, 29); + keyiter(k[ 22],r0,r4,r2,130, 30); keyiter(k[ 23],r1,r0,r3,131, 31); + + /* Apply S-boxes */ + + S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 28); loadkeys(r1,r2,r4,r3, 24); + S4(r1,r2,r4,r3,r0); storekeys(r2,r4,r3,r0, 24); loadkeys(r2,r4,r3,r0, 20); + S5(r2,r4,r3,r0,r1); storekeys(r1,r2,r4,r0, 20); loadkeys(r1,r2,r4,r0, 16); + S6(r1,r2,r4,r0,r3); storekeys(r4,r3,r2,r0, 16); loadkeys(r4,r3,r2,r0, 12); + S7(r4,r3,r2,r0,r1); storekeys(r1,r2,r0,r4, 12); loadkeys(r1,r2,r0,r4, 8); + S0(r1,r2,r0,r4,r3); storekeys(r0,r2,r4,r1, 8); loadkeys(r0,r2,r4,r1, 4); + S1(r0,r2,r4,r1,r3); storekeys(r3,r4,r1,r0, 4); loadkeys(r3,r4,r1,r0, 0); + S2(r3,r4,r1,r0,r2); storekeys(r2,r4,r3,r0, 0); loadkeys(r2,r4,r3,r0, -4); + S3(r2,r4,r3,r0,r1); storekeys(r0,r1,r4,r2, -4); loadkeys(r0,r1,r4,r2, -8); + S4(r0,r1,r4,r2,r3); storekeys(r1,r4,r2,r3, -8); loadkeys(r1,r4,r2,r3,-12); + S5(r1,r4,r2,r3,r0); storekeys(r0,r1,r4,r3,-12); loadkeys(r0,r1,r4,r3,-16); + S6(r0,r1,r4,r3,r2); storekeys(r4,r2,r1,r3,-16); loadkeys(r4,r2,r1,r3,-20); + S7(r4,r2,r1,r3,r0); storekeys(r0,r1,r3,r4,-20); loadkeys(r0,r1,r3,r4,-24); + S0(r0,r1,r3,r4,r2); storekeys(r3,r1,r4,r0,-24); loadkeys(r3,r1,r4,r0,-28); + k -= 50; + S1(r3,r1,r4,r0,r2); storekeys(r2,r4,r0,r3, 22); loadkeys(r2,r4,r0,r3, 18); + S2(r2,r4,r0,r3,r1); storekeys(r1,r4,r2,r3, 18); loadkeys(r1,r4,r2,r3, 14); + S3(r1,r4,r2,r3,r0); storekeys(r3,r0,r4,r1, 14); loadkeys(r3,r0,r4,r1, 10); + S4(r3,r0,r4,r1,r2); storekeys(r0,r4,r1,r2, 10); loadkeys(r0,r4,r1,r2, 6); + S5(r0,r4,r1,r2,r3); storekeys(r3,r0,r4,r2, 6); loadkeys(r3,r0,r4,r2, 2); + S6(r3,r0,r4,r2,r1); storekeys(r4,r1,r0,r2, 2); loadkeys(r4,r1,r0,r2, -2); + S7(r4,r1,r0,r2,r3); storekeys(r3,r0,r2,r4, -2); loadkeys(r3,r0,r2,r4, -6); + S0(r3,r0,r2,r4,r1); storekeys(r2,r0,r4,r3, -6); loadkeys(r2,r0,r4,r3,-10); + S1(r2,r0,r4,r3,r1); storekeys(r1,r4,r3,r2,-10); loadkeys(r1,r4,r3,r2,-14); + S2(r1,r4,r3,r2,r0); storekeys(r0,r4,r1,r2,-14); loadkeys(r0,r4,r1,r2,-18); + S3(r0,r4,r1,r2,r3); storekeys(r2,r3,r4,r0,-18); loadkeys(r2,r3,r4,r0,-22); + k -= 50; + S4(r2,r3,r4,r0,r1); storekeys(r3,r4,r0,r1, 28); loadkeys(r3,r4,r0,r1, 24); + S5(r3,r4,r0,r1,r2); storekeys(r2,r3,r4,r1, 24); loadkeys(r2,r3,r4,r1, 20); + S6(r2,r3,r4,r1,r0); storekeys(r4,r0,r3,r1, 20); loadkeys(r4,r0,r3,r1, 16); + S7(r4,r0,r3,r1,r2); storekeys(r2,r3,r1,r4, 16); loadkeys(r2,r3,r1,r4, 12); + S0(r2,r3,r1,r4,r0); storekeys(r1,r3,r4,r2, 12); loadkeys(r1,r3,r4,r2, 8); + S1(r1,r3,r4,r2,r0); storekeys(r0,r4,r2,r1, 8); loadkeys(r0,r4,r2,r1, 4); + S2(r0,r4,r2,r1,r3); storekeys(r3,r4,r0,r1, 4); loadkeys(r3,r4,r0,r1, 0); + S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 0); + + return 0; +} + +static void encrypt(void *ctx, u8 *dst, const u8 *src) +{ + const u32 + *k = ((struct serpent_ctx *)ctx)->expkey, + *s = (const u32 *)src; + u32 *d = (u32 *)dst, + r0, r1, r2, r3, r4; + +/* + * Note: The conversions between u8* and u32* might cause trouble + * on architectures with stricter alignment rules than x86 + */ + + r0 = le32_to_cpu(s[0]); + r1 = le32_to_cpu(s[1]); + r2 = le32_to_cpu(s[2]); + r3 = le32_to_cpu(s[3]); + + K(r0,r1,r2,r3,0); + S0(r0,r1,r2,r3,r4); LK(r2,r1,r3,r0,r4,1); + S1(r2,r1,r3,r0,r4); LK(r4,r3,r0,r2,r1,2); + S2(r4,r3,r0,r2,r1); LK(r1,r3,r4,r2,r0,3); + S3(r1,r3,r4,r2,r0); LK(r2,r0,r3,r1,r4,4); + S4(r2,r0,r3,r1,r4); LK(r0,r3,r1,r4,r2,5); + S5(r0,r3,r1,r4,r2); LK(r2,r0,r3,r4,r1,6); + S6(r2,r0,r3,r4,r1); LK(r3,r1,r0,r4,r2,7); + S7(r3,r1,r0,r4,r2); LK(r2,r0,r4,r3,r1,8); + S0(r2,r0,r4,r3,r1); LK(r4,r0,r3,r2,r1,9); + S1(r4,r0,r3,r2,r1); LK(r1,r3,r2,r4,r0,10); + S2(r1,r3,r2,r4,r0); LK(r0,r3,r1,r4,r2,11); + S3(r0,r3,r1,r4,r2); LK(r4,r2,r3,r0,r1,12); + S4(r4,r2,r3,r0,r1); LK(r2,r3,r0,r1,r4,13); + S5(r2,r3,r0,r1,r4); LK(r4,r2,r3,r1,r0,14); + S6(r4,r2,r3,r1,r0); LK(r3,r0,r2,r1,r4,15); + S7(r3,r0,r2,r1,r4); LK(r4,r2,r1,r3,r0,16); + S0(r4,r2,r1,r3,r0); LK(r1,r2,r3,r4,r0,17); + S1(r1,r2,r3,r4,r0); LK(r0,r3,r4,r1,r2,18); + S2(r0,r3,r4,r1,r2); LK(r2,r3,r0,r1,r4,19); + S3(r2,r3,r0,r1,r4); LK(r1,r4,r3,r2,r0,20); + S4(r1,r4,r3,r2,r0); LK(r4,r3,r2,r0,r1,21); + S5(r4,r3,r2,r0,r1); LK(r1,r4,r3,r0,r2,22); + S6(r1,r4,r3,r0,r2); LK(r3,r2,r4,r0,r1,23); + S7(r3,r2,r4,r0,r1); LK(r1,r4,r0,r3,r2,24); + S0(r1,r4,r0,r3,r2); LK(r0,r4,r3,r1,r2,25); + S1(r0,r4,r3,r1,r2); LK(r2,r3,r1,r0,r4,26); + S2(r2,r3,r1,r0,r4); LK(r4,r3,r2,r0,r1,27); + S3(r4,r3,r2,r0,r1); LK(r0,r1,r3,r4,r2,28); + S4(r0,r1,r3,r4,r2); LK(r1,r3,r4,r2,r0,29); + S5(r1,r3,r4,r2,r0); LK(r0,r1,r3,r2,r4,30); + S6(r0,r1,r3,r2,r4); LK(r3,r4,r1,r2,r0,31); + S7(r3,r4,r1,r2,r0); K(r0,r1,r2,r3,32); + + d[0] = cpu_to_le32(r0); + d[1] = cpu_to_le32(r1); + d[2] = cpu_to_le32(r2); + d[3] = cpu_to_le32(r3); +} + +static void decrypt(void *ctx, u8 *dst, const u8 *src) +{ + const u32 + *k = ((struct serpent_ctx *)ctx)->expkey, + *s = (const u32 *)src; + u32 *d = (u32 *)dst, + r0, r1, r2, r3, r4; + + r0 = le32_to_cpu(s[0]); + r1 = le32_to_cpu(s[1]); + r2 = le32_to_cpu(s[2]); + r3 = le32_to_cpu(s[3]); + + K(r0,r1,r2,r3,32); + SI7(r0,r1,r2,r3,r4); KL(r1,r3,r0,r4,r2,31); + SI6(r1,r3,r0,r4,r2); KL(r0,r2,r4,r1,r3,30); + SI5(r0,r2,r4,r1,r3); KL(r2,r3,r0,r4,r1,29); + SI4(r2,r3,r0,r4,r1); KL(r2,r0,r1,r4,r3,28); + SI3(r2,r0,r1,r4,r3); KL(r1,r2,r3,r4,r0,27); + SI2(r1,r2,r3,r4,r0); KL(r2,r0,r4,r3,r1,26); + SI1(r2,r0,r4,r3,r1); KL(r1,r0,r4,r3,r2,25); + SI0(r1,r0,r4,r3,r2); KL(r4,r2,r0,r1,r3,24); + SI7(r4,r2,r0,r1,r3); KL(r2,r1,r4,r3,r0,23); + SI6(r2,r1,r4,r3,r0); KL(r4,r0,r3,r2,r1,22); + SI5(r4,r0,r3,r2,r1); KL(r0,r1,r4,r3,r2,21); + SI4(r0,r1,r4,r3,r2); KL(r0,r4,r2,r3,r1,20); + SI3(r0,r4,r2,r3,r1); KL(r2,r0,r1,r3,r4,19); + SI2(r2,r0,r1,r3,r4); KL(r0,r4,r3,r1,r2,18); + SI1(r0,r4,r3,r1,r2); KL(r2,r4,r3,r1,r0,17); + SI0(r2,r4,r3,r1,r0); KL(r3,r0,r4,r2,r1,16); + SI7(r3,r0,r4,r2,r1); KL(r0,r2,r3,r1,r4,15); + SI6(r0,r2,r3,r1,r4); KL(r3,r4,r1,r0,r2,14); + SI5(r3,r4,r1,r0,r2); KL(r4,r2,r3,r1,r0,13); + SI4(r4,r2,r3,r1,r0); KL(r4,r3,r0,r1,r2,12); + SI3(r4,r3,r0,r1,r2); KL(r0,r4,r2,r1,r3,11); + SI2(r0,r4,r2,r1,r3); KL(r4,r3,r1,r2,r0,10); + SI1(r4,r3,r1,r2,r0); KL(r0,r3,r1,r2,r4,9); + SI0(r0,r3,r1,r2,r4); KL(r1,r4,r3,r0,r2,8); + SI7(r1,r4,r3,r0,r2); KL(r4,r0,r1,r2,r3,7); + SI6(r4,r0,r1,r2,r3); KL(r1,r3,r2,r4,r0,6); + SI5(r1,r3,r2,r4,r0); KL(r3,r0,r1,r2,r4,5); + SI4(r3,r0,r1,r2,r4); KL(r3,r1,r4,r2,r0,4); + SI3(r3,r1,r4,r2,r0); KL(r4,r3,r0,r2,r1,3); + SI2(r4,r3,r0,r2,r1); KL(r3,r1,r2,r0,r4,2); + SI1(r3,r1,r2,r0,r4); KL(r4,r1,r2,r0,r3,1); + SI0(r4,r1,r2,r0,r3); K(r2,r3,r1,r4,0); + + d[0] = cpu_to_le32(r2); + d[1] = cpu_to_le32(r3); + d[2] = cpu_to_le32(r1); + d[3] = cpu_to_le32(r4); +} + +static struct crypto_alg serpent_alg = { + .cra_name = "serpent", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct serpent_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = SERPENT_MIN_KEY_SIZE, + .cia_max_keysize = SERPENT_MAX_KEY_SIZE, + .cia_ivsize = SERPENT_BLOCK_SIZE, + .cia_setkey = setkey, + .cia_encrypt = encrypt, + .cia_decrypt = decrypt } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&serpent_alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&serpent_alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Serpent Cipher Algorithm"); +MODULE_AUTHOR("Dag Arne Osvik "); diff -urN linux-2.4.21/crypto/sha1.c linux-2.4.22/crypto/sha1.c --- linux-2.4.21/crypto/sha1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/sha1.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,208 @@ +/* + * Cryptographic API. + * + * SHA1 Secure Hash Algorithm. + * + * Derived from cryptoapi implementation, adapted for in-place + * scatterlist interface. Originally based on the public domain + * implementation written by Steve Reid. + * + * Copyright (c) Alan Smithee. + * Copyright (c) Andrew McDonald + * Copyright (c) Jean-Francois Dive + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include + +#define SHA1_DIGEST_SIZE 20 +#define SHA1_HMAC_BLOCK_SIZE 64 + +static inline u32 rol(u32 value, u32 bits) +{ + return (((value) << (bits)) | ((value) >> (32 - (bits)))); +} + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +# define blk0(i) block32[i] + +#define blk(i) (block32[i&15] = rol(block32[(i+13)&15]^block32[(i+8)&15] \ + ^block32[(i+2)&15]^block32[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5); \ + w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5); \ + w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5); \ + w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +struct sha1_ctx { + u64 count; + u32 state[5]; + u8 buffer[64]; +}; + +/* Hash a single 512-bit block. This is the core of the algorithm. */ +static void sha1_transform(u32 *state, const u8 *in) +{ + u32 a, b, c, d, e; + u32 block32[16]; + + /* convert/copy data to workspace */ + for (a = 0; a < sizeof(block32)/sizeof(u32); a++) + block32[a] = be32_to_cpu (((const u32 *)in)[a]); + + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; + memset (block32, 0x00, sizeof block32); +} + +static void sha1_init(void *ctx) +{ + struct sha1_ctx *sctx = ctx; + static const struct sha1_ctx initstate = { + 0, + { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }, + { 0, } + }; + + *sctx = initstate; +} + +static void sha1_update(void *ctx, const u8 *data, unsigned int len) +{ + struct sha1_ctx *sctx = ctx; + unsigned int i, j; + + j = (sctx->count >> 3) & 0x3f; + sctx->count += len << 3; + + if ((j + len) > 63) { + memcpy(&sctx->buffer[j], data, (i = 64-j)); + sha1_transform(sctx->state, sctx->buffer); + for ( ; i + 63 < len; i += 64) { + sha1_transform(sctx->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&sctx->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ +static void sha1_final(void* ctx, u8 *out) +{ + struct sha1_ctx *sctx = ctx; + u32 i, j, index, padlen; + u64 t; + u8 bits[8] = { 0, }; + static const u8 padding[64] = { 0x80, }; + + t = sctx->count; + bits[7] = 0xff & t; t>>=8; + bits[6] = 0xff & t; t>>=8; + bits[5] = 0xff & t; t>>=8; + bits[4] = 0xff & t; t>>=8; + bits[3] = 0xff & t; t>>=8; + bits[2] = 0xff & t; t>>=8; + bits[1] = 0xff & t; t>>=8; + bits[0] = 0xff & t; + + /* Pad out to 56 mod 64 */ + index = (sctx->count >> 3) & 0x3f; + padlen = (index < 56) ? (56 - index) : ((64+56) - index); + sha1_update(sctx, padding, padlen); + + /* Append length */ + sha1_update(sctx, bits, sizeof bits); + + /* Store state in digest */ + for (i = j = 0; i < 5; i++, j += 4) { + u32 t2 = sctx->state[i]; + out[j+3] = t2 & 0xff; t2>>=8; + out[j+2] = t2 & 0xff; t2>>=8; + out[j+1] = t2 & 0xff; t2>>=8; + out[j ] = t2 & 0xff; + } + + /* Wipe context */ + memset(sctx, 0, sizeof *sctx); +} + +static struct crypto_alg alg = { + .cra_name = "sha1", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = SHA1_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sha1_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = SHA1_DIGEST_SIZE, + .dia_init = sha1_init, + .dia_update = sha1_update, + .dia_final = sha1_final } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); diff -urN linux-2.4.21/crypto/sha256.c linux-2.4.22/crypto/sha256.c --- linux-2.4.21/crypto/sha256.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/sha256.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,362 @@ +/* + * Cryptographic API. + * + * SHA-256, as specified in + * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf + * + * SHA-256 code by Jean-Luc Cooke . + * + * Copyright (c) Jean-Luc Cooke + * Copyright (c) Andrew McDonald + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include + +#define SHA256_DIGEST_SIZE 32 +#define SHA256_HMAC_BLOCK_SIZE 64 + +struct sha256_ctx { + u32 count[2]; + u32 state[8]; + u8 buf[128]; +}; + +static inline u32 Ch(u32 x, u32 y, u32 z) +{ + return ((x & y) ^ (~x & z)); +} + +static inline u32 Maj(u32 x, u32 y, u32 z) +{ + return ((x & y) ^ (x & z) ^ (y & z)); +} + +static inline u32 RORu32(u32 x, u32 y) +{ + return (x >> y) | (x << (32 - y)); +} + +#define e0(x) (RORu32(x, 2) ^ RORu32(x,13) ^ RORu32(x,22)) +#define e1(x) (RORu32(x, 6) ^ RORu32(x,11) ^ RORu32(x,25)) +#define s0(x) (RORu32(x, 7) ^ RORu32(x,18) ^ (x >> 3)) +#define s1(x) (RORu32(x,17) ^ RORu32(x,19) ^ (x >> 10)) + +#define H0 0x6a09e667 +#define H1 0xbb67ae85 +#define H2 0x3c6ef372 +#define H3 0xa54ff53a +#define H4 0x510e527f +#define H5 0x9b05688c +#define H6 0x1f83d9ab +#define H7 0x5be0cd19 + +static inline void LOAD_OP(int I, u32 *W, const u8 *input) +{ + u32 t1 = input[(4 * I)] & 0xff; + + t1 <<= 8; + t1 |= input[(4 * I) + 1] & 0xff; + t1 <<= 8; + t1 |= input[(4 * I) + 2] & 0xff; + t1 <<= 8; + t1 |= input[(4 * I) + 3] & 0xff; + W[I] = t1; +} + +static inline void BLEND_OP(int I, u32 *W) +{ + W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; +} + +static void sha256_transform(u32 *state, const u8 *input) +{ + u32 a, b, c, d, e, f, g, h, t1, t2; + u32 W[64]; + int i; + + /* load the input */ + for (i = 0; i < 16; i++) + LOAD_OP(i, W, input); + + /* now blend */ + for (i = 16; i < 64; i++) + BLEND_OP(i, W); + + /* load the state into our registers */ + a=state[0]; b=state[1]; c=state[2]; d=state[3]; + e=state[4]; f=state[5]; g=state[6]; h=state[7]; + + /* now iterate */ + t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; + state[4] += e; state[5] += f; state[6] += g; state[7] += h; + + /* clear any sensitive info... */ + a = b = c = d = e = f = g = h = t1 = t2 = 0; + memset(W, 0, 64 * sizeof(u32)); +} + +static void sha256_init(void *ctx) +{ + struct sha256_ctx *sctx = ctx; + sctx->state[0] = H0; + sctx->state[1] = H1; + sctx->state[2] = H2; + sctx->state[3] = H3; + sctx->state[4] = H4; + sctx->state[5] = H5; + sctx->state[6] = H6; + sctx->state[7] = H7; + sctx->count[0] = sctx->count[1] = 0; + memset(sctx->buf, 0, sizeof(sctx->buf)); +} + +static void sha256_update(void *ctx, const u8 *data, unsigned int len) +{ + struct sha256_ctx *sctx = ctx; + unsigned int i, index, part_len; + + /* Compute number of bytes mod 128 */ + index = (unsigned int)((sctx->count[0] >> 3) & 0x3f); + + /* Update number of bits */ + if ((sctx->count[0] += (len << 3)) < (len << 3)) { + sctx->count[1]++; + sctx->count[1] += (len >> 29); + } + + part_len = 64 - index; + + /* Transform as many times as possible. */ + if (len >= part_len) { + memcpy(&sctx->buf[index], data, part_len); + sha256_transform(sctx->state, sctx->buf); + + for (i = part_len; i + 63 < len; i += 64) + sha256_transform(sctx->state, &data[i]); + index = 0; + } else { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&sctx->buf[index], &data[i], len-i); +} + +static void sha256_final(void* ctx, u8 *out) +{ + struct sha256_ctx *sctx = ctx; + u8 bits[8]; + unsigned int index, pad_len, t; + int i, j; + const u8 padding[64] = { 0x80, }; + + /* Save number of bits */ + t = sctx->count[0]; + bits[7] = t; t >>= 8; + bits[6] = t; t >>= 8; + bits[5] = t; t >>= 8; + bits[4] = t; + t = sctx->count[1]; + bits[3] = t; t >>= 8; + bits[2] = t; t >>= 8; + bits[1] = t; t >>= 8; + bits[0] = t; + + /* Pad out to 56 mod 64. */ + index = (sctx->count[0] >> 3) & 0x3f; + pad_len = (index < 56) ? (56 - index) : ((64+56) - index); + sha256_update(sctx, padding, pad_len); + + /* Append length (before padding) */ + sha256_update(sctx, bits, 8); + + /* Store state in digest */ + for (i = j = 0; i < 8; i++, j += 4) { + t = sctx->state[i]; + out[j+3] = t; t >>= 8; + out[j+2] = t; t >>= 8; + out[j+1] = t; t >>= 8; + out[j ] = t; + } + + /* Zeroize sensitive information. */ + memset(sctx, 0, sizeof(*sctx)); +} + + +static struct crypto_alg alg = { + .cra_name = "sha256", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = SHA256_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sha256_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = SHA256_DIGEST_SIZE, + .dia_init = sha256_init, + .dia_update = sha256_update, + .dia_final = sha256_final } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm"); diff -urN linux-2.4.21/crypto/sha512.c linux-2.4.22/crypto/sha512.c --- linux-2.4.21/crypto/sha512.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/sha512.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,373 @@ +/* SHA-512 code by Jean-Luc Cooke + * + * Copyright (c) Jean-Luc Cooke + * Copyright (c) Andrew McDonald + * Copyright (c) 2003 Kyle McMartin + * + * This program is free software; you can redistribute 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. + * + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#define SHA384_DIGEST_SIZE 48 +#define SHA512_DIGEST_SIZE 64 +#define SHA384_HMAC_BLOCK_SIZE 96 +#define SHA512_HMAC_BLOCK_SIZE 128 + +struct sha512_ctx { + u64 state[8]; + u32 count[4]; + u8 buf[128]; +}; + +static inline u64 Ch(u64 x, u64 y, u64 z) +{ + return ((x & y) ^ (~x & z)); +} + +static inline u64 Maj(u64 x, u64 y, u64 z) +{ + return ((x & y) ^ (x & z) ^ (y & z)); +} + +static inline u64 RORu64(u64 x, u64 y) +{ + return (x >> y) | (x << (64 - y)); +} + +const u64 sha512_K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, +}; + +#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39)) +#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41)) +#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7)) +#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6)) + +/* H* initial state for SHA-512 */ +#define H0 0x6a09e667f3bcc908ULL +#define H1 0xbb67ae8584caa73bULL +#define H2 0x3c6ef372fe94f82bULL +#define H3 0xa54ff53a5f1d36f1ULL +#define H4 0x510e527fade682d1ULL +#define H5 0x9b05688c2b3e6c1fULL +#define H6 0x1f83d9abfb41bd6bULL +#define H7 0x5be0cd19137e2179ULL + +/* H'* initial state for SHA-384 */ +#define HP0 0xcbbb9d5dc1059ed8ULL +#define HP1 0x629a292a367cd507ULL +#define HP2 0x9159015a3070dd17ULL +#define HP3 0x152fecd8f70e5939ULL +#define HP4 0x67332667ffc00b31ULL +#define HP5 0x8eb44a8768581511ULL +#define HP6 0xdb0c2e0d64f98fa7ULL +#define HP7 0x47b5481dbefa4fa4ULL + +static inline void LOAD_OP(int I, u64 *W, const u8 *input) +{ + u64 t1 = input[(8*I) ] & 0xff; + t1 <<= 8; + t1 |= input[(8*I)+1] & 0xff; + t1 <<= 8; + t1 |= input[(8*I)+2] & 0xff; + t1 <<= 8; + t1 |= input[(8*I)+3] & 0xff; + t1 <<= 8; + t1 |= input[(8*I)+4] & 0xff; + t1 <<= 8; + t1 |= input[(8*I)+5] & 0xff; + t1 <<= 8; + t1 |= input[(8*I)+6] & 0xff; + t1 <<= 8; + t1 |= input[(8*I)+7] & 0xff; + W[I] = t1; +} + +static inline void BLEND_OP(int I, u64 *W) +{ + W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; +} + +static void +sha512_transform(u64 *state, const u8 *input) +{ + u64 a, b, c, d, e, f, g, h, t1, t2; + u64 W[80]; + + int i; + + /* load the input */ + for (i = 0; i < 16; i++) + LOAD_OP(i, W, input); + + for (i = 16; i < 80; i++) { + BLEND_OP(i, W); + } + + /* load the state into our registers */ + a=state[0]; b=state[1]; c=state[2]; d=state[3]; + e=state[4]; f=state[5]; g=state[6]; h=state[7]; + + /* now iterate */ + for (i=0; i<80; i+=8) { + t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; + } + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; + state[4] += e; state[5] += f; state[6] += g; state[7] += h; + + /* erase our data */ + a = b = c = d = e = f = g = h = t1 = t2 = 0; + memset(W, 0, 80 * sizeof(u64)); +} + +static void +sha512_init(void *ctx) +{ + struct sha512_ctx *sctx = ctx; + sctx->state[0] = H0; + sctx->state[1] = H1; + sctx->state[2] = H2; + sctx->state[3] = H3; + sctx->state[4] = H4; + sctx->state[5] = H5; + sctx->state[6] = H6; + sctx->state[7] = H7; + sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0; + memset(sctx->buf, 0, sizeof(sctx->buf)); +} + +static void +sha384_init(void *ctx) +{ + struct sha512_ctx *sctx = ctx; + sctx->state[0] = HP0; + sctx->state[1] = HP1; + sctx->state[2] = HP2; + sctx->state[3] = HP3; + sctx->state[4] = HP4; + sctx->state[5] = HP5; + sctx->state[6] = HP6; + sctx->state[7] = HP7; + sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0; + memset(sctx->buf, 0, sizeof(sctx->buf)); +} + +static void +sha512_update(void *ctx, const u8 *data, unsigned int len) +{ + struct sha512_ctx *sctx = ctx; + + unsigned int i, index, part_len; + + /* Compute number of bytes mod 128 */ + index = (unsigned int)((sctx->count[0] >> 3) & 0x7F); + + /* Update number of bits */ + if ((sctx->count[0] += (len << 3)) < (len << 3)) { + if ((sctx->count[1] += 1) < 1) + if ((sctx->count[2] += 1) < 1) + sctx->count[3]++; + sctx->count[1] += (len >> 29); + } + + part_len = 128 - index; + + /* Transform as many times as possible. */ + if (len >= part_len) { + memcpy(&sctx->buf[index], data, part_len); + sha512_transform(sctx->state, sctx->buf); + + for (i = part_len; i + 127 < len; i+=128) + sha512_transform(sctx->state, &data[i]); + + index = 0; + } else { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&sctx->buf[index], &data[i], len - i); +} + +static void +sha512_final(void *ctx, u8 *hash) +{ + struct sha512_ctx *sctx = ctx; + + const static u8 padding[128] = { 0x80, }; + + u32 t; + u64 t2; + u8 bits[128]; + unsigned int index, pad_len; + int i, j; + + index = pad_len = t = i = j = 0; + t2 = 0; + + /* Save number of bits */ + t = sctx->count[0]; + bits[15] = t; t>>=8; + bits[14] = t; t>>=8; + bits[13] = t; t>>=8; + bits[12] = t; + t = sctx->count[1]; + bits[11] = t; t>>=8; + bits[10] = t; t>>=8; + bits[9 ] = t; t>>=8; + bits[8 ] = t; + t = sctx->count[2]; + bits[7 ] = t; t>>=8; + bits[6 ] = t; t>>=8; + bits[5 ] = t; t>>=8; + bits[4 ] = t; + t = sctx->count[3]; + bits[3 ] = t; t>>=8; + bits[2 ] = t; t>>=8; + bits[1 ] = t; t>>=8; + bits[0 ] = t; + + /* Pad out to 112 mod 128. */ + index = (sctx->count[0] >> 3) & 0x7f; + pad_len = (index < 112) ? (112 - index) : ((128+112) - index); + sha512_update(sctx, padding, pad_len); + + /* Append length (before padding) */ + sha512_update(sctx, bits, 16); + + /* Store state in digest */ + for (i = j = 0; i < 8; i++, j += 8) { + t2 = sctx->state[i]; + hash[j+7] = (char)t2 & 0xff; t2>>=8; + hash[j+6] = (char)t2 & 0xff; t2>>=8; + hash[j+5] = (char)t2 & 0xff; t2>>=8; + hash[j+4] = (char)t2 & 0xff; t2>>=8; + hash[j+3] = (char)t2 & 0xff; t2>>=8; + hash[j+2] = (char)t2 & 0xff; t2>>=8; + hash[j+1] = (char)t2 & 0xff; t2>>=8; + hash[j ] = (char)t2 & 0xff; + } + + /* Zeroize sensitive information. */ + memset(sctx, 0, sizeof(struct sha512_ctx)); +} + +static void sha384_final(void *ctx, u8 *hash) +{ + struct sha512_ctx *sctx = ctx; + u8 D[64]; + + sha512_final(sctx, D); + + memcpy(hash, D, 48); + memset(D, 0, 64); +} + +static struct crypto_alg sha512 = { + .cra_name = "sha512", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = SHA512_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sha512_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(sha512.cra_list), + .cra_u = { .digest = { + .dia_digestsize = SHA512_DIGEST_SIZE, + .dia_init = sha512_init, + .dia_update = sha512_update, + .dia_final = sha512_final } + } +}; + +static struct crypto_alg sha384 = { + .cra_name = "sha384", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = SHA384_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sha512_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(sha384.cra_list), + .cra_u = { .digest = { + .dia_digestsize = SHA384_DIGEST_SIZE, + .dia_init = sha384_init, + .dia_update = sha512_update, + .dia_final = sha384_final } + } +}; + +static int __init init(void) +{ + int ret = 0; + + if ((ret = crypto_register_alg(&sha384)) < 0) + goto out; + if ((ret = crypto_register_alg(&sha512)) < 0) + crypto_unregister_alg(&sha384); +out: + return ret; +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&sha384); + crypto_unregister_alg(&sha512); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms"); diff -urN linux-2.4.21/crypto/tcrypt.c linux-2.4.22/crypto/tcrypt.c --- linux-2.4.21/crypto/tcrypt.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/tcrypt.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,2418 @@ +/* + * Quick & dirty crypto testing module. + * + * This will only exist until we have a better testing mechanism + * (e.g. a char device). + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 Jean-Francois Dive + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tcrypt.h" + +/* + * Need to kmalloc() memory for testing kmap(). + */ +#define TVMEMSIZE 4096 +#define XBUFSIZE 32768 + +/* + * Indexes into the xbuf to simulate cross-page access. + */ +#define IDX1 37 +#define IDX2 32400 +#define IDX3 1 +#define IDX4 8193 +#define IDX5 22222 +#define IDX6 17101 +#define IDX7 27333 +#define IDX8 3000 + +static int mode = 0; +static char *xbuf; +static char *tvmem; + +static char *check[] = { + "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", + "twofish", "serpent", "sha384", "sha512", "md4", "aes", "deflate", + NULL +}; + +static void +hexdump(unsigned char *buf, unsigned int len) +{ + while (len--) + printk("%02x", *buf++); + + printk("\n"); +} + +static void +test_md5(void) +{ + char *p; + unsigned int i; + struct scatterlist sg[2]; + char result[128]; + struct crypto_tfm *tfm; + struct md5_testvec *md5_tv; + unsigned int tsize; + + printk("\ntesting md5\n"); + + tsize = sizeof (md5_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, md5_tv_template, tsize); + md5_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("md5", 0); + if (tfm == NULL) { + printk("failed to load transform for md5\n"); + return; + } + + for (i = 0; i < MD5_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = md5_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(md5_tv[i].plaintext); + + crypto_digest_init(tfm); + crypto_digest_update(tfm, sg, 1); + crypto_digest_final(tfm, result); + + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, md5_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + printk("\ntesting md5 across pages\n"); + + /* setup the dummy buffer first */ + memset(xbuf, 0, XBUFSIZE); + memcpy(&xbuf[IDX1], "abcdefghijklm", 13); + memcpy(&xbuf[IDX2], "nopqrstuvwxyz", 13); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 13; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 13; + + memset(result, 0, sizeof (result)); + crypto_digest_digest(tfm, sg, 2, result); + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + + printk("%s\n", + memcmp(result, md5_tv[4].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); + crypto_free_tfm(tfm); +} + +#ifdef CONFIG_CRYPTO_HMAC +static void +test_hmac_md5(void) +{ + char *p; + unsigned int i, klen; + struct scatterlist sg[2]; + char result[128]; + struct crypto_tfm *tfm; + struct hmac_md5_testvec *hmac_md5_tv; + unsigned int tsize; + + tfm = crypto_alloc_tfm("md5", 0); + if (tfm == NULL) { + printk("failed to load transform for md5\n"); + return; + } + + printk("\ntesting hmac_md5\n"); + + tsize = sizeof (hmac_md5_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + + memcpy(tvmem, hmac_md5_tv_template, tsize); + hmac_md5_tv = (void *) tvmem; + + for (i = 0; i < HMAC_MD5_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = hmac_md5_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(hmac_md5_tv[i].plaintext); + + klen = strlen(hmac_md5_tv[i].key); + crypto_hmac(tfm, hmac_md5_tv[i].key, &klen, sg, 1, result); + + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, hmac_md5_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + printk("\ntesting hmac_md5 across pages\n"); + + memset(xbuf, 0, XBUFSIZE); + + memcpy(&xbuf[IDX1], "what do ya want ", 16); + memcpy(&xbuf[IDX2], "for nothing?", 12); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 16; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 12; + + memset(result, 0, sizeof (result)); + klen = strlen(hmac_md5_tv[7].key); + crypto_hmac(tfm, hmac_md5_tv[7].key, &klen, sg, 2, result); + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + + printk("%s\n", + memcmp(result, hmac_md5_tv[7].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); +out: + crypto_free_tfm(tfm); +} + +static void +test_hmac_sha1(void) +{ + char *p; + unsigned int i, klen; + struct crypto_tfm *tfm; + struct hmac_sha1_testvec *hmac_sha1_tv; + struct scatterlist sg[2]; + unsigned int tsize; + char result[SHA1_DIGEST_SIZE]; + + tfm = crypto_alloc_tfm("sha1", 0); + if (tfm == NULL) { + printk("failed to load transform for sha1\n"); + return; + } + + printk("\ntesting hmac_sha1\n"); + + tsize = sizeof (hmac_sha1_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + + memcpy(tvmem, hmac_sha1_tv_template, tsize); + hmac_sha1_tv = (void *) tvmem; + + for (i = 0; i < HMAC_SHA1_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = hmac_sha1_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(hmac_sha1_tv[i].plaintext); + + klen = strlen(hmac_sha1_tv[i].key); + + crypto_hmac(tfm, hmac_sha1_tv[i].key, &klen, sg, 1, result); + + hexdump(result, sizeof (result)); + printk("%s\n", + memcmp(result, hmac_sha1_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + printk("\ntesting hmac_sha1 across pages\n"); + + /* setup the dummy buffer first */ + memset(xbuf, 0, XBUFSIZE); + + memcpy(&xbuf[IDX1], "what do ya want ", 16); + memcpy(&xbuf[IDX2], "for nothing?", 12); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 16; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 12; + + memset(result, 0, sizeof (result)); + klen = strlen(hmac_sha1_tv[7].key); + crypto_hmac(tfm, hmac_sha1_tv[7].key, &klen, sg, 2, result); + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + + printk("%s\n", + memcmp(result, hmac_sha1_tv[7].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); +out: + crypto_free_tfm(tfm); +} + +static void +test_hmac_sha256(void) +{ + char *p; + unsigned int i, klen; + struct crypto_tfm *tfm; + struct hmac_sha256_testvec *hmac_sha256_tv; + struct scatterlist sg[2]; + unsigned int tsize; + char result[SHA256_DIGEST_SIZE]; + + tfm = crypto_alloc_tfm("sha256", 0); + if (tfm == NULL) { + printk("failed to load transform for sha256\n"); + return; + } + + printk("\ntesting hmac_sha256\n"); + + tsize = sizeof (hmac_sha256_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + + memcpy(tvmem, hmac_sha256_tv_template, tsize); + hmac_sha256_tv = (void *) tvmem; + + for (i = 0; i < HMAC_SHA256_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = hmac_sha256_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(hmac_sha256_tv[i].plaintext); + + klen = strlen(hmac_sha256_tv[i].key); + + hexdump(hmac_sha256_tv[i].key, strlen(hmac_sha256_tv[i].key)); + crypto_hmac(tfm, hmac_sha256_tv[i].key, &klen, sg, 1, result); + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, hmac_sha256_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); + } + +out: + crypto_free_tfm(tfm); +} + +#endif /* CONFIG_CRYPTO_HMAC */ + +static void +test_md4(void) +{ + char *p; + unsigned int i; + struct scatterlist sg[1]; + char result[128]; + struct crypto_tfm *tfm; + struct md4_testvec *md4_tv; + unsigned int tsize; + + printk("\ntesting md4\n"); + + tsize = sizeof (md4_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, md4_tv_template, tsize); + md4_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("md4", 0); + if (tfm == NULL) { + printk("failed to load transform for md4\n"); + return; + } + + for (i = 0; i < MD4_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = md4_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(md4_tv[i].plaintext); + + crypto_digest_digest(tfm, sg, 1, result); + + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, md4_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + crypto_free_tfm(tfm); +} + +static void +test_sha1(void) +{ + char *p; + unsigned int i; + struct crypto_tfm *tfm; + struct sha1_testvec *sha1_tv; + struct scatterlist sg[2]; + unsigned int tsize; + char result[SHA1_DIGEST_SIZE]; + + printk("\ntesting sha1\n"); + + tsize = sizeof (sha1_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, sha1_tv_template, tsize); + sha1_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("sha1", 0); + if (tfm == NULL) { + printk("failed to load transform for sha1\n"); + return; + } + + for (i = 0; i < SHA1_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = sha1_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(sha1_tv[i].plaintext); + + crypto_digest_init(tfm); + crypto_digest_update(tfm, sg, 1); + crypto_digest_final(tfm, result); + + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, sha1_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + printk("\ntesting sha1 across pages\n"); + + /* setup the dummy buffer first */ + memset(xbuf, 0, XBUFSIZE); + memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); + memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 28; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 28; + + memset(result, 0, sizeof (result)); + crypto_digest_digest(tfm, sg, 2, result); + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, sha1_tv[1].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); + crypto_free_tfm(tfm); +} + +static void +test_sha256(void) +{ + char *p; + unsigned int i; + struct crypto_tfm *tfm; + struct sha256_testvec *sha256_tv; + struct scatterlist sg[2]; + unsigned int tsize; + char result[SHA256_DIGEST_SIZE]; + + printk("\ntesting sha256\n"); + + tsize = sizeof (sha256_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, sha256_tv_template, tsize); + sha256_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("sha256", 0); + if (tfm == NULL) { + printk("failed to load transform for sha256\n"); + return; + } + + for (i = 0; i < SHA256_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = sha256_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(sha256_tv[i].plaintext); + + crypto_digest_init(tfm); + crypto_digest_update(tfm, sg, 1); + crypto_digest_final(tfm, result); + + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, sha256_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + printk("\ntesting sha256 across pages\n"); + + /* setup the dummy buffer first */ + memset(xbuf, 0, XBUFSIZE); + memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); + memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 28; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 28; + + memset(result, 0, sizeof (result)); + crypto_digest_digest(tfm, sg, 2, result); + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, sha256_tv[1].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); + + crypto_free_tfm(tfm); +} + +static void +test_sha384(void) +{ + char *p; + unsigned int i; + struct crypto_tfm *tfm; + struct sha384_testvec *sha384_tv; + struct scatterlist sg[2]; + unsigned int tsize; + char result[SHA384_DIGEST_SIZE]; + + printk("\ntesting sha384\n"); + + tsize = sizeof (sha384_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, sha384_tv_template, tsize); + sha384_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("sha384", 0); + if (tfm == NULL) { + printk("failed to load transform for sha384\n"); + return; + } + + for (i = 0; i < SHA384_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = sha384_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(sha384_tv[i].plaintext); + + crypto_digest_init(tfm); + crypto_digest_update(tfm, sg, 1); + crypto_digest_final(tfm, result); + + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, sha384_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + crypto_free_tfm(tfm); +} + +static void +test_sha512(void) +{ + char *p; + unsigned int i; + struct crypto_tfm *tfm; + struct sha512_testvec *sha512_tv; + struct scatterlist sg[2]; + unsigned int tsize; + char result[SHA512_DIGEST_SIZE]; + + printk("\ntesting sha512\n"); + + tsize = sizeof (sha512_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, sha512_tv_template, tsize); + sha512_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("sha512", 0); + if (tfm == NULL) { + printk("failed to load transform for sha512\n"); + return; + } + + for (i = 0; i < SHA512_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + p = sha512_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = strlen(sha512_tv[i].plaintext); + + crypto_digest_init(tfm); + crypto_digest_update(tfm, sg, 1); + crypto_digest_final(tfm, result); + + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, sha512_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); + } + + crypto_free_tfm(tfm); +} + +void +test_des(void) +{ + unsigned int ret, i, len; + unsigned int tsize; + char *p, *q; + struct crypto_tfm *tfm; + char *key; + char res[8]; + struct des_tv *des_tv; + struct scatterlist sg[8]; + + printk("\ntesting des encryption\n"); + + tsize = sizeof (des_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, des_enc_tv_template, tsize); + des_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("des", 0); + if (tfm == NULL) { + printk("failed to load transform for des (default ecb)\n"); + return; + } + + for (i = 0; i < DES_ENC_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + + key = des_tv[i].key; + tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!des_tv[i].fail) + goto out; + } + + len = des_tv[i].len; + + p = des_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = len; + ret = crypto_cipher_encrypt(tfm, sg, sg, len); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, len); + + printk("%s\n", + memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); + + } + + printk("\ntesting des ecb encryption across pages\n"); + + i = 5; + key = des_tv[i].key; + tfm->crt_flags = 0; + + hexdump(key, 8); + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8); + memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 8; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 8; + + ret = crypto_cipher_encrypt(tfm, sg, sg, 16); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 8); + printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 8); + printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); + + printk("\ntesting des ecb encryption chunking scenario A\n"); + + /* + * Scenario A: + * + * F1 F2 F3 + * [8 + 6] [2 + 8] [8] + * ^^^^^^ ^ + * a b c + * + * Chunking should begin at a, then end with b, and + * continue encrypting at an offset of 2 until c. + * + */ + i = 7; + + key = des_tv[i].key; + tfm->crt_flags = 0; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + + /* Frag 1: 8 + 6 */ + memcpy(&xbuf[IDX3], des_tv[i].plaintext, 14); + + /* Frag 2: 2 + 8 */ + memcpy(&xbuf[IDX4], des_tv[i].plaintext + 14, 10); + + /* Frag 3: 8 */ + memcpy(&xbuf[IDX5], des_tv[i].plaintext + 24, 8); + + p = &xbuf[IDX3]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 14; + + p = &xbuf[IDX4]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 10; + + p = &xbuf[IDX5]; + sg[2].page = virt_to_page(p); + sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].length = 8; + + ret = crypto_cipher_encrypt(tfm, sg, sg, 32); + + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 14); + printk("%s\n", memcmp(q, des_tv[i].result, 14) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 10); + printk("%s\n", memcmp(q, des_tv[i].result + 14, 10) ? "fail" : "pass"); + + printk("page 3\n"); + q = kmap(sg[2].page) + sg[2].offset; + hexdump(q, 8); + printk("%s\n", memcmp(q, des_tv[i].result + 24, 8) ? "fail" : "pass"); + + printk("\ntesting des ecb encryption chunking scenario B\n"); + + /* + * Scenario B: + * + * F1 F2 F3 F4 + * [2] [1] [3] [2 + 8 + 8] + */ + i = 7; + + key = des_tv[i].key; + tfm->crt_flags = 0; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + + /* Frag 1: 2 */ + memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2); + + /* Frag 2: 1 */ + memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 1); + + /* Frag 3: 3 */ + memcpy(&xbuf[IDX5], des_tv[i].plaintext + 3, 3); + + /* Frag 4: 2 + 8 + 8 */ + memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 18); + + p = &xbuf[IDX3]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 2; + + p = &xbuf[IDX4]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 1; + + p = &xbuf[IDX5]; + sg[2].page = virt_to_page(p); + sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].length = 3; + + p = &xbuf[IDX6]; + sg[3].page = virt_to_page(p); + sg[3].offset = ((long) p & ~PAGE_MASK); + sg[3].length = 18; + + ret = crypto_cipher_encrypt(tfm, sg, sg, 24); + + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 2); + printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 1); + printk("%s\n", memcmp(q, des_tv[i].result + 2, 1) ? "fail" : "pass"); + + printk("page 3\n"); + q = kmap(sg[2].page) + sg[2].offset; + hexdump(q, 3); + printk("%s\n", memcmp(q, des_tv[i].result + 3, 3) ? "fail" : "pass"); + + printk("page 4\n"); + q = kmap(sg[3].page) + sg[3].offset; + hexdump(q, 18); + printk("%s\n", memcmp(q, des_tv[i].result + 6, 18) ? "fail" : "pass"); + + printk("\ntesting des ecb encryption chunking scenario C\n"); + + /* + * Scenario B: + * + * F1 F2 F3 F4 F5 + * [2] [2] [2] [2] [8] + */ + i = 7; + + key = des_tv[i].key; + tfm->crt_flags = 0; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + + /* Frag 1: 2 */ + memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2); + + /* Frag 2: 2 */ + memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 2); + + /* Frag 3: 2 */ + memcpy(&xbuf[IDX5], des_tv[i].plaintext + 4, 2); + + /* Frag 4: 2 */ + memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 2); + + /* Frag 5: 8 */ + memcpy(&xbuf[IDX7], des_tv[i].plaintext + 8, 8); + + p = &xbuf[IDX3]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 2; + + p = &xbuf[IDX4]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 2; + + p = &xbuf[IDX5]; + sg[2].page = virt_to_page(p); + sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].length = 2; + + p = &xbuf[IDX6]; + sg[3].page = virt_to_page(p); + sg[3].offset = ((long) p & ~PAGE_MASK); + sg[3].length = 2; + + p = &xbuf[IDX7]; + sg[4].page = virt_to_page(p); + sg[4].offset = ((long) p & ~PAGE_MASK); + sg[4].length = 8; + + ret = crypto_cipher_encrypt(tfm, sg, sg, 16); + + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 2); + printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 2); + printk("%s\n", memcmp(q, des_tv[i].result + 2, 2) ? "fail" : "pass"); + + printk("page 3\n"); + q = kmap(sg[2].page) + sg[2].offset; + hexdump(q, 2); + printk("%s\n", memcmp(q, des_tv[i].result + 4, 2) ? "fail" : "pass"); + + printk("page 4\n"); + q = kmap(sg[3].page) + sg[3].offset; + hexdump(q, 2); + printk("%s\n", memcmp(q, des_tv[i].result + 6, 2) ? "fail" : "pass"); + + printk("page 5\n"); + q = kmap(sg[4].page) + sg[4].offset; + hexdump(q, 8); + printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); + + printk("\ntesting des ecb encryption chunking scenario D\n"); + + /* + * Scenario D, torture test, one byte per frag. + */ + i = 7; + key = des_tv[i].key; + tfm->crt_flags = 0; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, XBUFSIZE); + + xbuf[IDX1] = des_tv[i].plaintext[0]; + xbuf[IDX2] = des_tv[i].plaintext[1]; + xbuf[IDX3] = des_tv[i].plaintext[2]; + xbuf[IDX4] = des_tv[i].plaintext[3]; + xbuf[IDX5] = des_tv[i].plaintext[4]; + xbuf[IDX6] = des_tv[i].plaintext[5]; + xbuf[IDX7] = des_tv[i].plaintext[6]; + xbuf[IDX8] = des_tv[i].plaintext[7]; + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 1; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 1; + + p = &xbuf[IDX3]; + sg[2].page = virt_to_page(p); + sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].length = 1; + + p = &xbuf[IDX4]; + sg[3].page = virt_to_page(p); + sg[3].offset = ((long) p & ~PAGE_MASK); + sg[3].length = 1; + + p = &xbuf[IDX5]; + sg[4].page = virt_to_page(p); + sg[4].offset = ((long) p & ~PAGE_MASK); + sg[4].length = 1; + + p = &xbuf[IDX6]; + sg[5].page = virt_to_page(p); + sg[5].offset = ((long) p & ~PAGE_MASK); + sg[5].length = 1; + + p = &xbuf[IDX7]; + sg[6].page = virt_to_page(p); + sg[6].offset = ((long) p & ~PAGE_MASK); + sg[6].length = 1; + + p = &xbuf[IDX8]; + sg[7].page = virt_to_page(p); + sg[7].offset = ((long) p & ~PAGE_MASK); + sg[7].length = 1; + + ret = crypto_cipher_encrypt(tfm, sg, sg, 8); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + for (i = 0; i < 8; i++) + res[i] = *(char *) (kmap(sg[i].page) + sg[i].offset); + + hexdump(res, 8); + printk("%s\n", memcmp(res, des_tv[7].result, 8) ? "fail" : "pass"); + + printk("\ntesting des decryption\n"); + + tsize = sizeof (des_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + memcpy(tvmem, des_dec_tv_template, tsize); + des_tv = (void *) tvmem; + + for (i = 0; i < DES_DEC_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + + key = des_tv[i].key; + + tfm->crt_flags = 0; + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + len = des_tv[i].len; + + p = des_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = len; + + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("des_decrypt() failed flags=%x\n", + tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, len); + + printk("%s\n", + memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); + + } + + printk("\ntesting des ecb decryption across pages\n"); + + i = 6; + + key = des_tv[i].key; + tfm->crt_flags = 0; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8); + memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 8; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 8; + + ret = crypto_cipher_decrypt(tfm, sg, sg, 16); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 8); + printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 8); + printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); + + /* + * Scenario E: + * + * F1 F2 F3 + * [3] [5 + 7] [1] + * + */ + printk("\ntesting des ecb decryption chunking scenario E\n"); + i = 2; + + key = des_tv[i].key; + tfm->crt_flags = 0; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + + memcpy(&xbuf[IDX1], des_tv[i].plaintext, 3); + memcpy(&xbuf[IDX2], des_tv[i].plaintext + 3, 12); + memcpy(&xbuf[IDX3], des_tv[i].plaintext + 15, 1); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 3; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 12; + + p = &xbuf[IDX3]; + sg[2].page = virt_to_page(p); + sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].length = 1; + + ret = crypto_cipher_decrypt(tfm, sg, sg, 16); + + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 3); + printk("%s\n", memcmp(q, des_tv[i].result, 3) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 12); + printk("%s\n", memcmp(q, des_tv[i].result + 3, 12) ? "fail" : "pass"); + + printk("page 3\n"); + q = kmap(sg[2].page) + sg[2].offset; + hexdump(q, 1); + printk("%s\n", memcmp(q, des_tv[i].result + 15, 1) ? "fail" : "pass"); + + crypto_free_tfm(tfm); + + tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC); + if (tfm == NULL) { + printk("failed to load transform for des cbc\n"); + return; + } + + printk("\ntesting des cbc encryption\n"); + + tsize = sizeof (des_cbc_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + memcpy(tvmem, des_cbc_enc_tv_template, tsize); + des_tv = (void *) tvmem; + + crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); + crypto_cipher_get_iv(tfm, res, crypto_tfm_alg_ivsize(tfm)); + + if (memcmp(res, des_tv[i].iv, sizeof(res))) { + printk("crypto_cipher_[set|get]_iv() failed\n"); + goto out; + } + + for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + + key = des_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + len = des_tv[i].len; + p = des_tv[i].plaintext; + + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = len; + + crypto_cipher_set_iv(tfm, des_tv[i].iv, + crypto_tfm_alg_ivsize(tfm)); + + ret = crypto_cipher_encrypt(tfm, sg, sg, len); + if (ret) { + printk("des_cbc_encrypt() failed flags=%x\n", + tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, len); + + printk("%s\n", + memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); + } + + crypto_free_tfm(tfm); + + /* + * Scenario F: + * + * F1 F2 + * [8 + 5] [3 + 8] + * + */ + printk("\ntesting des cbc encryption chunking scenario F\n"); + i = 4; + + tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC); + if (tfm == NULL) { + printk("failed to load transform for CRYPTO_ALG_DES_CCB\n"); + return; + } + + tfm->crt_flags = 0; + key = des_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + + memcpy(&xbuf[IDX1], des_tv[i].plaintext, 13); + memcpy(&xbuf[IDX2], des_tv[i].plaintext + 13, 11); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 13; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 11; + + crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); + + ret = crypto_cipher_encrypt(tfm, sg, sg, 24); + if (ret) { + printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 13); + printk("%s\n", memcmp(q, des_tv[i].result, 13) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 11); + printk("%s\n", memcmp(q, des_tv[i].result + 13, 11) ? "fail" : "pass"); + + tsize = sizeof (des_cbc_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + memcpy(tvmem, des_cbc_dec_tv_template, tsize); + des_tv = (void *) tvmem; + + printk("\ntesting des cbc decryption\n"); + + for (i = 0; i < DES_CBC_DEC_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + + tfm->crt_flags = 0; + key = des_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + len = des_tv[i].len; + p = des_tv[i].plaintext; + + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = len; + + crypto_cipher_set_iv(tfm, des_tv[i].iv, + crypto_tfm_alg_blocksize(tfm)); + + ret = crypto_cipher_decrypt(tfm, sg, sg, len); + if (ret) { + printk("des_cbc_decrypt() failed flags=%x\n", + tfm->crt_flags); + goto out; + } + + hexdump(tfm->crt_cipher.cit_iv, 8); + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, len); + + printk("%s\n", + memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); + } + + /* + * Scenario G: + * + * F1 F2 + * [4] [4] + * + */ + printk("\ntesting des cbc decryption chunking scenario G\n"); + i = 3; + + tfm->crt_flags = 0; + key = des_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, 8); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + /* setup the dummy buffer first */ + memset(xbuf, 0, sizeof (xbuf)); + memcpy(&xbuf[IDX1], des_tv[i].plaintext, 4); + memcpy(&xbuf[IDX2], des_tv[i].plaintext + 4, 4); + + p = &xbuf[IDX1]; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = 4; + + p = &xbuf[IDX2]; + sg[1].page = virt_to_page(p); + sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].length = 4; + + crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); + + ret = crypto_cipher_decrypt(tfm, sg, sg, 8); + if (ret) { + printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + printk("page 1\n"); + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, 4); + printk("%s\n", memcmp(q, des_tv[i].result, 4) ? "fail" : "pass"); + + printk("page 2\n"); + q = kmap(sg[1].page) + sg[1].offset; + hexdump(q, 4); + printk("%s\n", memcmp(q, des_tv[i].result + 4, 4) ? "fail" : "pass"); + + out: + crypto_free_tfm(tfm); +} + +void +test_des3_ede(void) +{ + unsigned int ret, i, len; + unsigned int tsize; + char *p, *q; + struct crypto_tfm *tfm; + char *key; + /*char res[8]; */ + struct des_tv *des_tv; + struct scatterlist sg[8]; + + printk("\ntesting des3 ede encryption\n"); + + tsize = sizeof (des3_ede_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, des3_ede_enc_tv_template, tsize); + des_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("des3_ede", CRYPTO_TFM_MODE_ECB); + if (tfm == NULL) { + printk("failed to load transform for 3des ecb\n"); + return; + } + + for (i = 0; i < DES3_EDE_ENC_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + + key = des_tv[i].key; + ret = crypto_cipher_setkey(tfm, key, 24); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!des_tv[i].fail) + goto out; + } + + len = des_tv[i].len; + + p = des_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = len; + ret = crypto_cipher_encrypt(tfm, sg, sg, len); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, len); + + printk("%s\n", + memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); + } + + printk("\ntesting des3 ede decryption\n"); + + tsize = sizeof (des3_ede_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, des3_ede_dec_tv_template, tsize); + des_tv = (void *) tvmem; + + for (i = 0; i < DES3_EDE_DEC_TEST_VECTORS; i++) { + printk("test %u:\n", i + 1); + + key = des_tv[i].key; + ret = crypto_cipher_setkey(tfm, key, 24); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!des_tv[i].fail) + goto out; + } + + len = des_tv[i].len; + + p = des_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = len; + ret = crypto_cipher_decrypt(tfm, sg, sg, len); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, len); + + printk("%s\n", + memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); + } + + out: + crypto_free_tfm(tfm); +} + +void +test_blowfish(void) +{ + unsigned int ret, i; + unsigned int tsize; + char *p, *q; + struct crypto_tfm *tfm; + char *key; + struct bf_tv *bf_tv; + struct scatterlist sg[1]; + + printk("\ntesting blowfish encryption\n"); + + tsize = sizeof (bf_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, bf_enc_tv_template, tsize); + bf_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("blowfish", 0); + if (tfm == NULL) { + printk("failed to load transform for blowfish (default ecb)\n"); + return; + } + + for (i = 0; i < BF_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, bf_tv[i].keylen * 8); + key = bf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!bf_tv[i].fail) + goto out; + } + + p = bf_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = bf_tv[i].plen; + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, bf_tv[i].rlen); + + printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? + "fail" : "pass"); + } + + printk("\ntesting blowfish decryption\n"); + + tsize = sizeof (bf_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, bf_dec_tv_template, tsize); + bf_tv = (void *) tvmem; + + for (i = 0; i < BF_DEC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, bf_tv[i].keylen * 8); + key = bf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!bf_tv[i].fail) + goto out; + } + + p = bf_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = bf_tv[i].plen; + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, bf_tv[i].rlen); + + printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? + "fail" : "pass"); + } + + crypto_free_tfm(tfm); + + tfm = crypto_alloc_tfm("blowfish", CRYPTO_TFM_MODE_CBC); + if (tfm == NULL) { + printk("failed to load transform for blowfish cbc\n"); + return; + } + + printk("\ntesting blowfish cbc encryption\n"); + + tsize = sizeof (bf_cbc_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + memcpy(tvmem, bf_cbc_enc_tv_template, tsize); + bf_tv = (void *) tvmem; + + for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, bf_tv[i].keylen * 8); + + key = bf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + p = bf_tv[i].plaintext; + + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = bf_tv[i].plen; + + crypto_cipher_set_iv(tfm, bf_tv[i].iv, + crypto_tfm_alg_ivsize(tfm)); + + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("blowfish_cbc_encrypt() failed flags=%x\n", + tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, bf_tv[i].rlen); + + printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) + ? "fail" : "pass"); + } + + printk("\ntesting blowfish cbc decryption\n"); + + tsize = sizeof (bf_cbc_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + memcpy(tvmem, bf_cbc_dec_tv_template, tsize); + bf_tv = (void *) tvmem; + + for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, bf_tv[i].keylen * 8); + key = bf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + p = bf_tv[i].plaintext; + + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = bf_tv[i].plen; + + crypto_cipher_set_iv(tfm, bf_tv[i].iv, + crypto_tfm_alg_ivsize(tfm)); + + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("blowfish_cbc_decrypt() failed flags=%x\n", + tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, bf_tv[i].rlen); + + printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) + ? "fail" : "pass"); + } + +out: + crypto_free_tfm(tfm); +} + + +void +test_twofish(void) +{ + unsigned int ret, i; + unsigned int tsize; + char *p, *q; + struct crypto_tfm *tfm; + char *key; + struct tf_tv *tf_tv; + struct scatterlist sg[1]; + + printk("\ntesting twofish encryption\n"); + + tsize = sizeof (tf_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, tf_enc_tv_template, tsize); + tf_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("twofish", 0); + if (tfm == NULL) { + printk("failed to load transform for blowfish (default ecb)\n"); + return; + } + + for (i = 0; i < TF_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, tf_tv[i].keylen * 8); + key = tf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!tf_tv[i].fail) + goto out; + } + + p = tf_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = tf_tv[i].plen; + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, tf_tv[i].rlen); + + printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? + "fail" : "pass"); + } + + printk("\ntesting twofish decryption\n"); + + tsize = sizeof (tf_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, tf_dec_tv_template, tsize); + tf_tv = (void *) tvmem; + + for (i = 0; i < TF_DEC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, tf_tv[i].keylen * 8); + key = tf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!tf_tv[i].fail) + goto out; + } + + p = tf_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = tf_tv[i].plen; + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, tf_tv[i].rlen); + + printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? + "fail" : "pass"); + } + + crypto_free_tfm(tfm); + + tfm = crypto_alloc_tfm("twofish", CRYPTO_TFM_MODE_CBC); + if (tfm == NULL) { + printk("failed to load transform for twofish cbc\n"); + return; + } + + printk("\ntesting twofish cbc encryption\n"); + + tsize = sizeof (tf_cbc_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + memcpy(tvmem, tf_cbc_enc_tv_template, tsize); + tf_tv = (void *) tvmem; + + for (i = 0; i < TF_CBC_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, tf_tv[i].keylen * 8); + + key = tf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + p = tf_tv[i].plaintext; + + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = tf_tv[i].plen; + + crypto_cipher_set_iv(tfm, tf_tv[i].iv, + crypto_tfm_alg_ivsize(tfm)); + + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("blowfish_cbc_encrypt() failed flags=%x\n", + tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, tf_tv[i].rlen); + + printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) + ? "fail" : "pass"); + } + + printk("\ntesting twofish cbc decryption\n"); + + tsize = sizeof (tf_cbc_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + memcpy(tvmem, tf_cbc_dec_tv_template, tsize); + tf_tv = (void *) tvmem; + + for (i = 0; i < TF_CBC_DEC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, tf_tv[i].keylen * 8); + + key = tf_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + p = tf_tv[i].plaintext; + + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = tf_tv[i].plen; + + crypto_cipher_set_iv(tfm, tf_tv[i].iv, + crypto_tfm_alg_ivsize(tfm)); + + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("blowfish_cbc_decrypt() failed flags=%x\n", + tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, tf_tv[i].rlen); + + printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) + ? "fail" : "pass"); + } + +out: + crypto_free_tfm(tfm); +} + +void +test_serpent(void) +{ + unsigned int ret, i, tsize; + u8 *p, *q, *key; + struct crypto_tfm *tfm; + struct serpent_tv *serp_tv; + struct scatterlist sg[1]; + + printk("\ntesting serpent encryption\n"); + + tfm = crypto_alloc_tfm("serpent", 0); + if (tfm == NULL) { + printk("failed to load transform for serpent (default ecb)\n"); + return; + } + + tsize = sizeof (serpent_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, serpent_enc_tv_template, tsize); + serp_tv = (void *) tvmem; + for (i = 0; i < SERPENT_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8); + key = serp_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!serp_tv[i].fail) + goto out; + } + + p = serp_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = sizeof(serp_tv[i].plaintext); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, sizeof(serp_tv[i].result)); + + printk("%s\n", memcmp(q, serp_tv[i].result, + sizeof(serp_tv[i].result)) ? "fail" : "pass"); + } + + printk("\ntesting serpent decryption\n"); + + tsize = sizeof (serpent_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, serpent_dec_tv_template, tsize); + serp_tv = (void *) tvmem; + for (i = 0; i < SERPENT_DEC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8); + key = serp_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!serp_tv[i].fail) + goto out; + } + + p = serp_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = sizeof(serp_tv[i].plaintext); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, sizeof(serp_tv[i].result)); + + printk("%s\n", memcmp(q, serp_tv[i].result, + sizeof(serp_tv[i].result)) ? "fail" : "pass"); + } + +out: + crypto_free_tfm(tfm); +} + +void +test_aes(void) +{ + unsigned int ret, i; + unsigned int tsize; + char *p, *q; + struct crypto_tfm *tfm; + char *key; + struct aes_tv *aes_tv; + struct scatterlist sg[1]; + + printk("\ntesting aes encryption\n"); + + tsize = sizeof (aes_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, aes_enc_tv_template, tsize); + aes_tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("aes", 0); + if (tfm == NULL) { + printk("failed to load transform for aes (default ecb)\n"); + return; + } + + for (i = 0; i < AES_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, aes_tv[i].keylen * 8); + key = aes_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!aes_tv[i].fail) + goto out; + } + + p = aes_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = aes_tv[i].plen; + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, aes_tv[i].rlen); + + printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ? + "fail" : "pass"); + } + + printk("\ntesting aes decryption\n"); + + tsize = sizeof (aes_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, aes_dec_tv_template, tsize); + aes_tv = (void *) tvmem; + + for (i = 0; i < AES_DEC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", + i + 1, aes_tv[i].keylen * 8); + key = aes_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!aes_tv[i].fail) + goto out; + } + + p = aes_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = aes_tv[i].plen; + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, aes_tv[i].rlen); + + printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ? + "fail" : "pass"); + } + +out: + crypto_free_tfm(tfm); +} + +static void +test_deflate(void) +{ + unsigned int i; + char result[COMP_BUF_SIZE]; + struct crypto_tfm *tfm; + struct comp_testvec *tv; + unsigned int tsize; + + printk("\ntesting deflate compression\n"); + + tsize = sizeof (deflate_comp_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, deflate_comp_tv_template, tsize); + tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("deflate", 0); + if (tfm == NULL) { + printk("failed to load transform for deflate\n"); + return; + } + + for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) { + int ilen, ret, dlen = COMP_BUF_SIZE; + + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + ilen = tv[i].inlen; + ret = crypto_comp_compress(tfm, tv[i].input, + ilen, result, &dlen); + if (ret) { + printk("fail: ret=%d\n", ret); + continue; + } + hexdump(result, dlen); + printk("%s (ratio %d:%d)\n", + memcmp(result, tv[i].output, dlen) ? "fail" : "pass", + ilen, dlen); + } + + printk("\ntesting deflate decompression\n"); + + tsize = sizeof (deflate_decomp_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + + memcpy(tvmem, deflate_decomp_tv_template, tsize); + tv = (void *) tvmem; + + for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) { + int ilen, ret, dlen = COMP_BUF_SIZE; + + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + ilen = tv[i].inlen; + ret = crypto_comp_decompress(tfm, tv[i].input, + ilen, result, &dlen); + if (ret) { + printk("fail: ret=%d\n", ret); + continue; + } + hexdump(result, dlen); + printk("%s (ratio %d:%d)\n", + memcmp(result, tv[i].output, dlen) ? "fail" : "pass", + ilen, dlen); + } +out: + crypto_free_tfm(tfm); +} + +static void +test_available(void) +{ + char **name = check; + + while (*name) { + printk("alg %s ", *name); + printk((crypto_alg_available(*name, 0)) ? + "found\n" : "not found\n"); + name++; + } +} + +static void +do_test(void) +{ + switch (mode) { + + case 0: + test_md5(); + test_sha1(); + test_des(); + test_des3_ede(); + test_md4(); + test_sha256(); + test_blowfish(); + test_twofish(); + test_serpent(); + test_aes(); + test_sha384(); + test_sha512(); + test_deflate(); +#ifdef CONFIG_CRYPTO_HMAC + test_hmac_md5(); + test_hmac_sha1(); + test_hmac_sha256(); +#endif + break; + + case 1: + test_md5(); + break; + + case 2: + test_sha1(); + break; + + case 3: + test_des(); + break; + + case 4: + test_des3_ede(); + break; + + case 5: + test_md4(); + break; + + case 6: + test_sha256(); + break; + + case 7: + test_blowfish(); + break; + + case 8: + test_twofish(); + break; + + case 9: + test_serpent(); + break; + + case 10: + test_aes(); + break; + + case 11: + test_sha384(); + break; + + case 12: + test_sha512(); + break; + + case 13: + test_deflate(); + break; + +#ifdef CONFIG_CRYPTO_HMAC + case 100: + test_hmac_md5(); + break; + + case 101: + test_hmac_sha1(); + break; + + case 102: + test_hmac_sha256(); + break; + +#endif + + case 1000: + test_available(); + break; + + default: + /* useful for debugging */ + printk("not testing anything\n"); + break; + } +} + +static int __init +init(void) +{ + tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL); + if (tvmem == NULL) + return -ENOMEM; + + xbuf = kmalloc(XBUFSIZE, GFP_KERNEL); + if (xbuf == NULL) { + kfree(tvmem); + return -ENOMEM; + } + + do_test(); + + kfree(xbuf); + kfree(tvmem); + return 0; +} + +module_init(init); + +MODULE_PARM(mode, "i"); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Quick & dirty crypto testing module"); +MODULE_AUTHOR("James Morris "); diff -urN linux-2.4.21/crypto/tcrypt.h linux-2.4.22/crypto/tcrypt.h --- linux-2.4.21/crypto/tcrypt.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/tcrypt.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,1785 @@ +/* + * Quick & dirty crypto testing module. + * + * This will only exist until we have a better testing mechanism + * (e.g. a char device). + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 Jean-Francois Dive + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#ifndef _CRYPTO_TCRYPT_H +#define _CRYPTO_TCRYPT_H + +#define MD5_DIGEST_SIZE 16 +#define MD4_DIGEST_SIZE 16 +#define SHA1_DIGEST_SIZE 20 +#define SHA256_DIGEST_SIZE 32 +#define SHA384_DIGEST_SIZE 48 +#define SHA512_DIGEST_SIZE 64 + +/* + * MD4 test vectors from RFC1320 + */ +#define MD4_TEST_VECTORS 7 + +struct md4_testvec { + char plaintext[128]; + char digest[MD4_DIGEST_SIZE]; +} md4_tv_template[] = { + { "", + { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, + 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 } + }, + + { "a", + { 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, + 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 } + }, + + { "abc", + { 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, + 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d } + }, + + { "message digest", + { 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, + 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b } + }, + + { "abcdefghijklmnopqrstuvwxyz", + { 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, + 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 } + }, + + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, + 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 } + }, + + { "123456789012345678901234567890123456789012345678901234567890123" + "45678901234567890", + { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, + 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 } + }, +}; + +/* + * MD5 test vectors from RFC1321 + */ +#define MD5_TEST_VECTORS 7 + +struct md5_testvec { + char plaintext[128]; + char digest[MD5_DIGEST_SIZE]; +} md5_tv_template[] = { + { "", + { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, + + { "a", + { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, + + { "abc", + { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, + + { "message digest", + { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, + + { "abcdefghijklmnopqrstuvwxyz", + { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, + + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, + + { "12345678901234567890123456789012345678901234567890123456789012" + "345678901234567890", + { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } } +}; + +#ifdef CONFIG_CRYPTO_HMAC +/* + * HMAC-MD5 test vectors from RFC2202 + * (These need to be fixed to not use strlen). + */ +#define HMAC_MD5_TEST_VECTORS 7 + +struct hmac_md5_testvec { + char key[128]; + char plaintext[128]; + char digest[MD5_DIGEST_SIZE]; +}; + +struct hmac_md5_testvec hmac_md5_tv_template[] = +{ + + { + { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00}, + + "Hi There", + + { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, + 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d } + }, + + { + { 'J', 'e', 'f', 'e', 0 }, + + "what do ya want for nothing?", + + { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 } + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, + + { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0x00 }, + + { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, + 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 } + }, + + { + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 }, + + { + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0x00 }, + + { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, + 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 } + }, + + { + { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 }, + + "Test With Truncation", + + { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, + 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c } + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00 }, + + "Test Using Larger Than Block-Size Key - Hash Key First", + + { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, + 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd } + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00 }, + + "Test Using Larger Than Block-Size Key and Larger Than One " + "Block-Size Data", + + { 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, + 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e } + }, + + /* cross page test, need to retain key */ + + { + { 'J', 'e', 'f', 'e', 0 }, + + "what do ya want for nothing?", + + { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 } + }, + +}; + + +/* + * HMAC-SHA1 test vectors from RFC2202 + */ + +#define HMAC_SHA1_TEST_VECTORS 7 + +struct hmac_sha1_testvec { + char key[128]; + char plaintext[128]; + char digest[SHA1_DIGEST_SIZE]; +} hmac_sha1_tv_template[] = { + + { + { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x00}, + + "Hi There", + + { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, + 0xe2, 0x8b, 0xc0, 0xb6, 0xfb ,0x37, 0x8c, 0x8e, 0xf1, + 0x46, 0xbe, 0x00 } + }, + + { + { 'J', 'e', 'f', 'e', 0 }, + + "what do ya want for nothing?", + + { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, + 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 } + + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00}, + + + { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0x00 }, + + { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, + 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 } + + }, + + { + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 }, + + { + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0x00 }, + + { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, + 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda } + + }, + + { + { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x00 }, + + "Test With Truncation", + + { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, + 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 } + + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00 }, + + "Test Using Larger Than Block-Size Key - Hash Key First", + + { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, + 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 } + + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00 }, + + "Test Using Larger Than Block-Size Key and Larger Than One " + "Block-Size Data", + + { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, + 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 } + }, + + /* cross page test */ + { + { 'J', 'e', 'f', 'e', 0 }, + + "what do ya want for nothing?", + + { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, + 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 } + + }, + +}; + +/* + * HMAC-SHA256 test vectors from + * draft-ietf-ipsec-ciph-sha-256-01.txt + */ +#define HMAC_SHA256_TEST_VECTORS 10 + +struct hmac_sha256_testvec { + char key[128]; + char plaintext[128]; + char digest[SHA256_DIGEST_SIZE]; +} hmac_sha256_tv_template[] = { + + { + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 }, + + + { "abc" }, + + { 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a, + 0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a, + 0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66, + 0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81 }, + + }, + + { + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + + { 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08, + 0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae, + 0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49, + 0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30 } + }, + + { + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + + { 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34, + 0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab, + 0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5, + 0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3 } + }, + + { + { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00 }, + + { "Hi There" }, + + { 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6, + 0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5, + 0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c, + 0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7 } + }, + + { + { "Jefe" }, + + { "what do ya want for nothing?" }, + + { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, + 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, + 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, + 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, + + { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0x00 }, + + { 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea, + 0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62, + 0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc, + 0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0 } + }, + + { + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x00 }, + + { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0x00 }, + + { 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74, + 0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55, + 0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85, + 0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17 } + }, + + { + { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 }, + + { "Test With Truncation" }, + + { 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b, + 0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17, + 0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27, + 0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42 } + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, + + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + + { 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09, + 0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb, + 0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e, + 0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f } + }, + + { + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, + + { "Test Using Larger Than Block-Size Key and Larger Than " + "One Block-Size Data" }, + + { 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3, + 0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8, + 0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc, + 0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6 } + }, +}; + + +#endif /* CONFIG_CRYPTO_HMAC */ + +/* + * SHA1 test vectors from from FIPS PUB 180-1 + */ +#define SHA1_TEST_VECTORS 2 + +struct sha1_testvec { + char plaintext[128]; + char digest[SHA1_DIGEST_SIZE]; +} sha1_tv_template[] = { + { "abc", + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C ,0x9C, 0xD0, 0xD8, 0x9D } + }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E ,0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } + } +}; + +/* + * SHA256 test vectors from from NIST + */ +#define SHA256_TEST_VECTORS 2 + +struct sha256_testvec { + char plaintext[128]; + char digest[SHA256_DIGEST_SIZE]; +} sha256_tv_template[] = { + { "abc", + { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } + }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } + }, +}; + +/* + * SHA384 test vectors from from NIST and kerneli + */ +#define SHA384_TEST_VECTORS 4 + +struct sha384_testvec { + char plaintext[128]; + char digest[SHA384_DIGEST_SIZE]; +} sha384_tv_template[] = { + + { "abc", + { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } + }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39, + 0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39, + 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab, + 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6, + 0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f, + 0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b } + }, + + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } + }, + + { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" + "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb, + 0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a, + 0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc, + 0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a, + 0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a, + 0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 } + }, +}; + +/* + * SHA512 test vectors from from NIST and kerneli + */ +#define SHA512_TEST_VECTORS 4 + +struct sha512_testvec { + char plaintext[128]; + char digest[SHA512_DIGEST_SIZE]; +} sha512_tv_template[] = { + + { "abc", + { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } + }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a, + 0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16, + 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8, + 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35, + 0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9, + 0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0, + 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03, + 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 } + }, + + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } + }, + + { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" + "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11, + 0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d, + 0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c, + 0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d, + 0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67, + 0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe, + 0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8, + 0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9 + } + }, +}; + +/* + * DES test vectors. + */ +#define DES_ENC_TEST_VECTORS 5 +#define DES_DEC_TEST_VECTORS 2 +#define DES_CBC_ENC_TEST_VECTORS 4 +#define DES_CBC_DEC_TEST_VECTORS 3 +#define DES3_EDE_ENC_TEST_VECTORS 3 +#define DES3_EDE_DEC_TEST_VECTORS 3 + +struct des_tv { + unsigned int len; + int fail; + char key[24]; + char iv[8]; + char plaintext[128]; + char result[128]; +}; + +struct des_tv des_enc_tv_template[] = { + + /* From Applied Cryptography */ + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d } + }, + + /* Same key, different plaintext block */ + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0 }, + { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + { 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b } + }, + + /* Sbox test from NBS */ + { + 8, 0, + + { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 }, + { 0 }, + { 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 }, + { 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B } + }, + + /* Three blocks */ + { + 24, 0, + + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + + { 0 }, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef }, + + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b, + 0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 }, + }, + + /* Weak key */ + { + 8, 1, + + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d } + }, + + /* Two blocks -- for testing encryption across pages */ + { + 16, 0, + + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + + { 0 }, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b } + }, + + /* Two blocks -- for testing decryption across pages */ + { + 16, 0, + + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + + { 0 }, + + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + }, + + /* Four blocks -- for testing encryption with chunking */ + { + 24, 0, + + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + + { 0 }, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b, + 0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, + }, + +}; + +struct des_tv des_dec_tv_template[] = { + + /* From Applied Cryptography */ + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0 }, + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, + }, + + /* Sbox test from NBS */ + { + 8, 0, + + { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 }, + { 0 }, + { 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B }, + { 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 } + }, + + /* Two blocks, for chunking test */ + { + 16, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0 }, + + { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B }, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 } + }, + +}; + +struct des_tv des_cbc_enc_tv_template[] = { + /* From OpenSSL */ + { + 24, 0, + + {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + + { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 }, + + { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, + 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, + 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 } + }, + + /* FIPS Pub 81 */ + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }, + { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 }, + { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + + }, + + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, + { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + }, + + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, + { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, + }, + + /* Copy of openssl vector for chunk testing */ + + /* From OpenSSL */ + { + 24, 0, + + {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + + { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 }, + + { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, + 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, + 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 } + }, + + +}; + +struct des_tv des_cbc_dec_tv_template[] = { + + /* FIPS Pub 81 */ + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }, + { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 }, + }, + + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, + }, + + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, + { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, + }, + + /* Copy of above, for chunk testing */ + + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, + { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, + }, +}; + +/* + * We really need some more test vectors, especially for DES3 CBC. + */ +struct des_tv des3_ede_enc_tv_template[] = { + + /* These are from openssl */ + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, + + { 0 }, + + { 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61 }, + + { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 }, + }, + + { + 8, 0, + + { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17, + 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98, + 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 }, + + { 0 }, + + { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 }, + + { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 } + }, + + + { + 8, 0, + + { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20, + 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01, + 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 }, + + { 0 }, + + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + + { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b } + }, +}; + +struct des_tv des3_ede_dec_tv_template[] = { + + /* These are from openssl */ + { + 8, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, + + { 0 }, + + + { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 }, + + { 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61 }, + }, + + { + 8, 0, + + { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17, + 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98, + 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 }, + + { 0 }, + + { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 }, + + { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 }, + + }, + + + { + 8, 0, + + { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20, + 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01, + 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 }, + + { 0 }, + + { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b }, + + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + }, +}; + +/* + * Blowfish test vectors. + */ +#define BF_ENC_TEST_VECTORS 6 +#define BF_DEC_TEST_VECTORS 6 +#define BF_CBC_ENC_TEST_VECTORS 1 +#define BF_CBC_DEC_TEST_VECTORS 1 + +struct bf_tv { + unsigned int keylen; + unsigned int plen; + unsigned int rlen; + int fail; + char key[56]; + char iv[8]; + char plaintext[32]; + char result[32]; +}; + +struct bf_tv bf_enc_tv_template[] = { + + /* DES test vectors from OpenSSL */ + { + 8, 8, 8, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, + { 0 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 }, + }, + + { + 8, 8, 8, 0, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, }, + { 0 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE }, + }, + + { + 8, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, }, + { 0 }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 } + }, + + /* Vary the keylength... */ + + { + 16, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, + 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F }, + { 0 }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C } + }, + + { + 21, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, + 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, + 0x00, 0x11, 0x22, 0x33, 0x44 }, + { 0 }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F } + }, + + /* Generated with bf488 */ + { + 56, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, + 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, + 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, + 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0 }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 } + } + +}; + +struct bf_tv bf_dec_tv_template[] = { + + /* DES test vectors from OpenSSL */ + { + 8, 8, 8, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, + { 0 }, + { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + + { + 8, 8, 8, 0, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, }, + { 0 }, + { 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF } + }, + + { + 8, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, }, + { 0 }, + { 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } + }, + + /* Vary the keylength... */ + + { + 16, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, + 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F }, + { 0 }, + { 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } + }, + + { + 21, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, + 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, + 0x00, 0x11, 0x22, 0x33, 0x44 }, + { 0 }, + { 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } + }, + + /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */ + { + 56, 8, 8, 0, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, + 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, + 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, + 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0 }, + { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } + } +}; + +struct bf_tv bf_cbc_enc_tv_template[] = { + + /* From OpenSSL */ + { + 16, 32, 32, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, + + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, + + { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 }, + + { 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6, + 0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93, + 0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9, + 0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC } + }, +}; + +struct bf_tv bf_cbc_dec_tv_template[] = { + + /* From OpenSSL */ + { + 16, 32, 32, 0, + + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, + + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, + + { 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6, + 0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93, + 0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9, + 0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC }, + + { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 } + }, +}; + +/* + * Twofish test vectors. + */ +#define TF_ENC_TEST_VECTORS 3 +#define TF_DEC_TEST_VECTORS 3 +#define TF_CBC_ENC_TEST_VECTORS 4 +#define TF_CBC_DEC_TEST_VECTORS 4 + +struct tf_tv { + unsigned int keylen; + unsigned int plen; + unsigned int rlen; + int fail; + char key[32]; + char iv[16]; + char plaintext[48]; + char result[48]; +}; + +struct tf_tv tf_enc_tv_template[] = { + { + 16, 16, 16, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, + 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A } + }, + { + 24, 16, 16, 0, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + { 0 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, + 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 } + }, + { + 32, 16, 16, 0, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, + { 0 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, + 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 } + }, +}; + +struct tf_tv tf_dec_tv_template[] = { + { + 16, 16, 16, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0 }, + { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, + 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + { + 24, 16, 16, 0, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + { 0 }, + { 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, + 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + { + 32, 16, 16, 0, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, + { 0 }, + { 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, + 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, +}; + +struct tf_tv tf_cbc_enc_tv_template[] = { + /* Generated with Nettle */ + { + 16, 16, 16, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + }, + + { + 16, 16, 16, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + }, + + { + 16, 16, 16, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + }, + + { + 16, 48, 48, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a, + 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19, + 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + }, +}; + +struct tf_tv tf_cbc_dec_tv_template[] = { + /* Reverse of the first four above */ + { + 16, 16, 16, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + + { + 16, 16, 16, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + + { + 16, 16, 16, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + + { + 16, 48, 48, 0, + + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a, + 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19, + 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, +}; + +/* + * Serpent test vectors. These are backwards because Serpent writes + * octect sequences in right-to-left mode. + */ +#define SERPENT_ENC_TEST_VECTORS 4 +#define SERPENT_DEC_TEST_VECTORS 4 + +struct serpent_tv { + unsigned int keylen, fail; + u8 key[32], plaintext[16], result[16]; +}; + +struct serpent_tv serpent_enc_tv_template[] = +{ + { + 0, 0, + { 0 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47, + 0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 } + }, + { + 16, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c, + 0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d } + }, + { + 32, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, + 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c } + }, + { + 16, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c, + 0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49} + } +}; + +struct serpent_tv serpent_dec_tv_template[] = +{ + { + 0, 0, + { 0 }, + { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47, + 0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + + }, + { + 16, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c, + 0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + }, + { + 32, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + + { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, + 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + }, + { + 16, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, + { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c, + 0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + } +}; + +/* + * AES test vectors. + */ +#define AES_ENC_TEST_VECTORS 3 +#define AES_DEC_TEST_VECTORS 3 + +struct aes_tv { + unsigned int keylen; + unsigned int plen; + unsigned int rlen; + int fail; + char key[32]; + char iv[8]; + char plaintext[16]; + char result[16]; +}; + +struct aes_tv aes_enc_tv_template[] = { + /* From FIPS-197 */ + { + 16, 16, 16, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }, + }, + { + 24, 16, 16, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + { 0 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }, + }, + { + 32, 16, 16, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + { 0 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }, + }, +}; + +struct aes_tv aes_dec_tv_template[] = { + /* From FIPS-197 */ + { + 16, 16, 16, 0, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0 }, + { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + }, + + { + 24, 16, 16, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + { 0 }, + { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + }, + { + 32, 16, 16, 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + { 0 }, + { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + }, +}; + +/* + * Compression stuff. + */ +#define COMP_BUF_SIZE 512 + +struct comp_testvec { + int inlen, outlen; + char input[COMP_BUF_SIZE]; + char output[COMP_BUF_SIZE]; +}; + +/* + * Deflate test vectors (null-terminated strings). + * Params: winbits=11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL. + */ +#define DEFLATE_COMP_TEST_VECTORS 2 +#define DEFLATE_DECOMP_TEST_VECTORS 2 + +struct comp_testvec deflate_comp_tv_template[] = { + { + 70, 38, + + "Join us now and share the software " + "Join us now and share the software ", + + { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, + 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, + 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, + 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, + 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 + }, + }, + + { + 191, 122, + + "This document describes a compression method based on the DEFLATE" + "compression algorithm. This document defines the application of " + "the DEFLATE algorithm to the IP Payload Compression Protocol.", + + { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, + 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, + 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, + 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, + 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, + 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, + 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, + 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, + 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, + 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, + 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, + 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, + 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, + 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, + 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, + 0xfa, 0x02 }, + }, +}; + +struct comp_testvec deflate_decomp_tv_template[] = { + { + 122, 191, + + { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, + 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, + 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, + 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, + 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, + 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, + 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, + 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, + 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, + 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, + 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, + 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, + 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, + 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, + 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, + 0xfa, 0x02 }, + + "This document describes a compression method based on the DEFLATE" + "compression algorithm. This document defines the application of " + "the DEFLATE algorithm to the IP Payload Compression Protocol.", + }, + + { + 38, 70, + + { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, + 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, + 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, + 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, + 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 + }, + + "Join us now and share the software " + "Join us now and share the software ", + }, +}; + +#endif /* _CRYPTO_TCRYPT_H */ diff -urN linux-2.4.21/crypto/twofish.c linux-2.4.22/crypto/twofish.c --- linux-2.4.21/crypto/twofish.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/crypto/twofish.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,900 @@ +/* + * Twofish for CryptoAPI + * + * Originaly Twofish for GPG + * By Matthew Skala , July 26, 1998 + * 256-bit key length added March 20, 1999 + * Some modifications to reduce the text size by Werner Koch, April, 1998 + * Ported to the kerneli patch by Marc Mutz + * Ported to CryptoAPI by Colin Slater + * + * The original author has disclaimed all copyright interest in this + * code and thus put it in the public domain. The subsequent authors + * have put this under the GNU General Public License. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * This code is a "clean room" implementation, written from the paper + * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey, + * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available + * through http://www.counterpane.com/twofish.html + * + * For background information on multiplication in finite fields, used for + * the matrix operations in the key schedule, see the book _Contemporary + * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the + * Third Edition. + */ +#include +#include +#include +#include +#include + + +/* The large precomputed tables for the Twofish cipher (twofish.c) + * Taken from the same source as twofish.c + * Marc Mutz + */ + +/* These two tables are the q0 and q1 permutations, exactly as described in + * the Twofish paper. */ + +static const u8 q0[256] = { + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0 +}; + +static const u8 q1[256] = { + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 +}; + +/* These MDS tables are actually tables of MDS composed with q0 and q1, + * because it is only ever used that way and we can save some time by + * precomputing. Of course the main saving comes from precomputing the + * GF(2^8) multiplication involved in the MDS matrix multiply; by looking + * things up in these tables we reduce the matrix multiply to four lookups + * and three XORs. Semi-formally, the definition of these tables is: + * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T + * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T + * where ^T means "transpose", the matrix multiply is performed in GF(2^8) + * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described + * by Schneier et al, and I'm casually glossing over the byte/word + * conversion issues. */ + +static const u32 mds[4][256] = { + {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, + 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, + 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32, + 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, + 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, + 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, + 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1, + 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, + 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, + 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, + 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0, + 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, + 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, + 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, + 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3, + 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, + 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, + 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, + 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C, + 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, + 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, + 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, + 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72, + 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, + 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, + 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, + 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39, + 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, + 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, + 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, + 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5, + 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, + 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, + 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, + 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E, + 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, + 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, + 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, + 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2, + 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, + 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, + 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, + 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91}, + + {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, + 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, + 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020, + 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, + 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, + 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, + 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A, + 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, + 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, + 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, + 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9, + 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, + 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, + 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, + 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414, + 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, + 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, + 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, + 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5, + 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, + 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, + 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, + 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202, + 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, + 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, + 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, + 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808, + 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, + 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, + 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, + 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505, + 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, + 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, + 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, + 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF, + 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, + 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, + 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, + 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6, + 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, + 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, + 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, + 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8}, + + {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, + 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, + 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A, + 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, + 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, + 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, + 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB, + 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, + 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, + 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, + 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C, + 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, + 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, + 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, + 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035, + 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, + 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, + 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, + 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F, + 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, + 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, + 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, + 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA, + 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, + 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, + 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, + 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D, + 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, + 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, + 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, + 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086, + 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, + 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, + 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, + 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691, + 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, + 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, + 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, + 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E, + 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, + 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, + 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, + 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF}, + + {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, + 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, + 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643, + 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, + 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, + 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, + 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3, + 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, + 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, + 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, + 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF, + 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, + 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, + 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, + 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA, + 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, + 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, + 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, + 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D, + 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, + 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, + 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, + 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B, + 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, + 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, + 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, + 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE, + 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, + 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, + 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, + 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E, + 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, + 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, + 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, + 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718, + 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, + 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, + 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, + 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882, + 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, + 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, + 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, + 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8} +}; + +/* The exp_to_poly and poly_to_exp tables are used to perform efficient + * operations in GF(2^8) represented as GF(2)[x]/w(x) where + * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the + * definition of the RS matrix in the key schedule. Elements of that field + * are polynomials of degree not greater than 7 and all coefficients 0 or 1, + * which can be represented naturally by bytes (just substitute x=2). In that + * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8) + * multiplication is inefficient without hardware support. To multiply + * faster, I make use of the fact x is a generator for the nonzero elements, + * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for + * some n in 0..254. Note that that caret is exponentiation in GF(2^8), + * *not* polynomial notation. So if I want to compute pq where p and q are + * in GF(2^8), I can just say: + * 1. if p=0 or q=0 then pq=0 + * 2. otherwise, find m and n such that p=x^m and q=x^n + * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq + * The translations in steps 2 and 3 are looked up in the tables + * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this + * in action, look at the CALC_S macro. As additional wrinkles, note that + * one of my operands is always a constant, so the poly_to_exp lookup on it + * is done in advance; I included the original values in the comments so + * readers can have some chance of recognizing that this *is* the RS matrix + * from the Twofish paper. I've only included the table entries I actually + * need; I never do a lookup on a variable input of zero and the biggest + * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll + * never sum to more than 491. I'm repeating part of the exp_to_poly table + * so that I don't have to do mod-255 reduction in the exponent arithmetic. + * Since I know my constant operands are never zero, I only have to worry + * about zero values in the variable operand, and I do it with a simple + * conditional branch. I know conditionals are expensive, but I couldn't + * see a non-horrible way of avoiding them, and I did manage to group the + * statements so that each if covers four group multiplications. */ + +static const u8 poly_to_exp[255] = { + 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19, + 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A, + 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C, + 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B, + 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47, + 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D, + 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8, + 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C, + 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83, + 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48, + 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26, + 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E, + 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3, + 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9, + 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A, + 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D, + 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75, + 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84, + 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64, + 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49, + 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF, + 0x85, 0xC8, 0xA1 +}; + +static const u8 exp_to_poly[492] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2, + 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6, + 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A, + 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63, + 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C, + 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07, + 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88, + 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12, + 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7, + 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C, + 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8, + 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25, + 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A, + 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE, + 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC, + 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E, + 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92, + 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89, + 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB, + 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1, + 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, + 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, + 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, + 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, + 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, + 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, + 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, + 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, + 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, + 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, + 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, + 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, + 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, + 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, + 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, + 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, + 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, + 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, + 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, + 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB +}; + + +/* The table constants are indices of + * S-box entries, preprocessed through q0 and q1. */ +static const u8 calc_sb_tbl[512] = { + 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4, + 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8, + 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B, + 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B, + 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD, + 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1, + 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B, + 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F, + 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B, + 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D, + 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E, + 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5, + 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14, + 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3, + 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54, + 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51, + 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A, + 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96, + 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10, + 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C, + 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7, + 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70, + 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB, + 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8, + 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF, + 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC, + 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF, + 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2, + 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82, + 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9, + 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97, + 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17, + 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D, + 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3, + 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C, + 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E, + 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F, + 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49, + 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21, + 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9, + 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD, + 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01, + 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F, + 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48, + 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E, + 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19, + 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57, + 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64, + 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE, + 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5, + 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44, + 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69, + 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15, + 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E, + 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34, + 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC, + 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B, + 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB, + 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52, + 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9, + 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4, + 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2, + 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56, + 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91 +}; + +/* Macro to perform one column of the RS matrix multiplication. The + * parameters a, b, c, and d are the four bytes of output; i is the index + * of the key bytes, and w, x, y, and z, are the column of constants from + * the RS matrix, preprocessed through the poly_to_exp table. */ + +#define CALC_S(a, b, c, d, i, w, x, y, z) \ + if (key[i]) { \ + tmp = poly_to_exp[key[i] - 1]; \ + (a) ^= exp_to_poly[tmp + (w)]; \ + (b) ^= exp_to_poly[tmp + (x)]; \ + (c) ^= exp_to_poly[tmp + (y)]; \ + (d) ^= exp_to_poly[tmp + (z)]; \ + } + +/* Macros to calculate the key-dependent S-boxes for a 128-bit key using + * the S vector from CALC_S. CALC_SB_2 computes a single entry in all + * four S-boxes, where i is the index of the entry to compute, and a and b + * are the index numbers preprocessed through the q0 and q1 tables + * respectively. */ + +#define CALC_SB_2(i, a, b) \ + ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \ + ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \ + ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \ + ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh] + +/* Macro exactly like CALC_SB_2, but for 192-bit keys. */ + +#define CALC_SB192_2(i, a, b) \ + ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \ + ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \ + ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \ + ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl]; + +/* Macro exactly like CALC_SB_2, but for 256-bit keys. */ + +#define CALC_SB256_2(i, a, b) \ + ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \ + ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \ + ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \ + ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp]; + +/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the + * last two stages of the h() function for a given index (either 2i or 2i+1). + * a, b, c, and d are the four bytes going into the last two stages. For + * 128-bit keys, this is the entire h() function and a and c are the index + * preprocessed through q0 and q1 respectively; for longer keys they are the + * output of previous stages. j is the index of the first key byte to use. + * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2 + * twice, doing the Psuedo-Hadamard Transform, and doing the necessary + * rotations. Its parameters are: a, the array to write the results into, + * j, the index of the first output entry, k and l, the preprocessed indices + * for index 2i, and m and n, the preprocessed indices for index 2i+1. + * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an + * additional lookup-and-XOR stage. The parameters a, b, c and d are the + * four bytes going into the last three stages. For 192-bit keys, c = d + * are the index preprocessed through q0, and a = b are the index + * preprocessed through q1; j is the index of the first key byte to use. + * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro + * instead of CALC_K_2. + * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an + * additional lookup-and-XOR stage. The parameters a and b are the index + * preprocessed through q0 and q1 respectively; j is the index of the first + * key byte to use. CALC_K256 is identical to CALC_K but for using the + * CALC_K256_2 macro instead of CALC_K_2. */ + +#define CALC_K_2(a, b, c, d, j) \ + mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \ + ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \ + ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \ + ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]] + +#define CALC_K(a, j, k, l, m, n) \ + x = CALC_K_2 (k, l, k, l, 0); \ + y = CALC_K_2 (m, n, m, n, 4); \ + y = (y << 8) + (y >> 24); \ + x += y; y += x; ctx->a[j] = x; \ + ctx->a[(j) + 1] = (y << 9) + (y >> 23) + +#define CALC_K192_2(a, b, c, d, j) \ + CALC_K_2 (q0[a ^ key[(j) + 16]], \ + q1[b ^ key[(j) + 17]], \ + q0[c ^ key[(j) + 18]], \ + q1[d ^ key[(j) + 19]], j) + +#define CALC_K192(a, j, k, l, m, n) \ + x = CALC_K192_2 (l, l, k, k, 0); \ + y = CALC_K192_2 (n, n, m, m, 4); \ + y = (y << 8) + (y >> 24); \ + x += y; y += x; ctx->a[j] = x; \ + ctx->a[(j) + 1] = (y << 9) + (y >> 23) + +#define CALC_K256_2(a, b, j) \ + CALC_K192_2 (q1[b ^ key[(j) + 24]], \ + q1[a ^ key[(j) + 25]], \ + q0[a ^ key[(j) + 26]], \ + q0[b ^ key[(j) + 27]], j) + +#define CALC_K256(a, j, k, l, m, n) \ + x = CALC_K256_2 (k, l, 0); \ + y = CALC_K256_2 (m, n, 4); \ + y = (y << 8) + (y >> 24); \ + x += y; y += x; ctx->a[j] = x; \ + ctx->a[(j) + 1] = (y << 9) + (y >> 23) + + +/* Macros to compute the g() function in the encryption and decryption + * rounds. G1 is the straight g() function; G2 includes the 8-bit + * rotation for the high 32-bit word. */ + +#define G1(a) \ + (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \ + ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24]) + +#define G2(b) \ + (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \ + ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24]) + +/* Encryption and decryption Feistel rounds. Each one calls the two g() + * macros, does the PHT, and performs the XOR and the appropriate bit + * rotations. The parameters are the round number (used to select subkeys), + * and the four 32-bit chunks of the text. */ + +#define ENCROUND(n, a, b, c, d) \ + x = G1 (a); y = G2 (b); \ + x += y; y += x + ctx->k[2 * (n) + 1]; \ + (c) ^= x + ctx->k[2 * (n)]; \ + (c) = ((c) >> 1) + ((c) << 31); \ + (d) = (((d) << 1)+((d) >> 31)) ^ y + +#define DECROUND(n, a, b, c, d) \ + x = G1 (a); y = G2 (b); \ + x += y; y += x; \ + (d) ^= y + ctx->k[2 * (n) + 1]; \ + (d) = ((d) >> 1) + ((d) << 31); \ + (c) = (((c) << 1)+((c) >> 31)); \ + (c) ^= (x + ctx->k[2 * (n)]) + +/* Encryption and decryption cycles; each one is simply two Feistel rounds + * with the 32-bit chunks re-ordered to simulate the "swap" */ + +#define ENCCYCLE(n) \ + ENCROUND (2 * (n), a, b, c, d); \ + ENCROUND (2 * (n) + 1, c, d, a, b) + +#define DECCYCLE(n) \ + DECROUND (2 * (n) + 1, c, d, a, b); \ + DECROUND (2 * (n), a, b, c, d) + +/* Macros to convert the input and output bytes into 32-bit words, + * and simultaneously perform the whitening step. INPACK packs word + * number n into the variable named by x, using whitening subkey number m. + * OUTUNPACK unpacks word number n from the variable named by x, using + * whitening subkey number m. */ + +#define INPACK(n, x, m) \ + x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \ + ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m] + +#define OUTUNPACK(n, x, m) \ + x ^= ctx->w[m]; \ + out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \ + out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24 + +#define TF_MIN_KEY_SIZE 16 +#define TF_MAX_KEY_SIZE 32 +#define TF_BLOCK_SIZE 16 + +/* Structure for an expanded Twofish key. s contains the key-dependent + * S-boxes composed with the MDS matrix; w contains the eight "whitening" + * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note + * that k[i] corresponds to what the Twofish paper calls K[i+8]. */ +struct twofish_ctx { + u32 s[4][256], w[8], k[32]; +}; + +/* Perform the key setup. */ +static int twofish_setkey(void *cx, const u8 *key, + unsigned int key_len, u32 *flags) +{ + + struct twofish_ctx *ctx = cx; + + int i, j, k; + + /* Temporaries for CALC_K. */ + u32 x, y; + + /* The S vector used to key the S-boxes, split up into individual bytes. + * 128-bit keys use only sa through sh; 256-bit use all of them. */ + u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0; + u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0; + + /* Temporary for CALC_S. */ + u8 tmp; + + /* Check key length. */ + if (key_len != 16 && key_len != 24 && key_len != 32) + return -EINVAL; /* unsupported key length */ + + /* Compute the first two words of the S vector. The magic numbers are + * the entries of the RS matrix, preprocessed through poly_to_exp. The + * numbers in the comments are the original (polynomial form) matrix + * entries. */ + CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + + if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */ + /* Calculate the third word of the S vector */ + CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + } + + if (key_len == 32) { /* 256-bit key */ + /* Calculate the fourth word of the S vector */ + CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + + /* Compute the S-boxes. */ + for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { + CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); + } + + /* Calculate whitening and round subkeys. The constants are + * indices of subkeys, preprocessed through q0 and q1. */ + CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3); + CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); + CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B); + CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8); + CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3); + CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B); + CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D); + CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B); + CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32); + CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD); + CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71); + CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1); + CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F); + CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B); + CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA); + CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F); + CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA); + CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B); + CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00); + CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D); + } else if (key_len == 24) { /* 192-bit key */ + /* Compute the S-boxes. */ + for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { + CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); + } + + /* Calculate whitening and round subkeys. The constants are + * indices of subkeys, preprocessed through q0 and q1. */ + CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3); + CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); + CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B); + CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8); + CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3); + CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B); + CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D); + CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B); + CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32); + CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD); + CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71); + CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1); + CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F); + CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B); + CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA); + CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F); + CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA); + CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B); + CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00); + CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D); + } else { /* 128-bit key */ + /* Compute the S-boxes. */ + for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { + CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); + } + + /* Calculate whitening and round subkeys. The constants are + * indices of subkeys, preprocessed through q0 and q1. */ + CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3); + CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); + CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B); + CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8); + CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3); + CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B); + CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D); + CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B); + CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32); + CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD); + CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71); + CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1); + CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F); + CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B); + CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA); + CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F); + CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA); + CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B); + CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00); + CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D); + } + + return 0; +} + +/* Encrypt one block. in and out may be the same. */ +static void twofish_encrypt(void *cx, u8 *out, const u8 *in) +{ + struct twofish_ctx *ctx = cx; + + /* The four 32-bit chunks of the text. */ + u32 a, b, c, d; + + /* Temporaries used by the round function. */ + u32 x, y; + + /* Input whitening and packing. */ + INPACK (0, a, 0); + INPACK (1, b, 1); + INPACK (2, c, 2); + INPACK (3, d, 3); + + /* Encryption Feistel cycles. */ + ENCCYCLE (0); + ENCCYCLE (1); + ENCCYCLE (2); + ENCCYCLE (3); + ENCCYCLE (4); + ENCCYCLE (5); + ENCCYCLE (6); + ENCCYCLE (7); + + /* Output whitening and unpacking. */ + OUTUNPACK (0, c, 4); + OUTUNPACK (1, d, 5); + OUTUNPACK (2, a, 6); + OUTUNPACK (3, b, 7); + +} + +/* Decrypt one block. in and out may be the same. */ +static void twofish_decrypt(void *cx, u8 *out, const u8 *in) +{ + struct twofish_ctx *ctx = cx; + + /* The four 32-bit chunks of the text. */ + u32 a, b, c, d; + + /* Temporaries used by the round function. */ + u32 x, y; + + /* Input whitening and packing. */ + INPACK (0, c, 4); + INPACK (1, d, 5); + INPACK (2, a, 6); + INPACK (3, b, 7); + + /* Encryption Feistel cycles. */ + DECCYCLE (7); + DECCYCLE (6); + DECCYCLE (5); + DECCYCLE (4); + DECCYCLE (3); + DECCYCLE (2); + DECCYCLE (1); + DECCYCLE (0); + + /* Output whitening and unpacking. */ + OUTUNPACK (0, a, 0); + OUTUNPACK (1, b, 1); + OUTUNPACK (2, c, 2); + OUTUNPACK (3, d, 3); + +} + +static struct crypto_alg alg = { + .cra_name = "twofish", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct twofish_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = TF_MIN_KEY_SIZE, + .cia_max_keysize = TF_MAX_KEY_SIZE, + .cia_ivsize = TF_BLOCK_SIZE, + .cia_setkey = twofish_setkey, + .cia_encrypt = twofish_encrypt, + .cia_decrypt = twofish_decrypt } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION ("Twofish Cipher Algorithm"); diff -urN linux-2.4.21/drivers/Makefile linux-2.4.22/drivers/Makefile --- linux-2.4.21/drivers/Makefile 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -6,7 +6,7 @@ # -mod-subdirs := dio hil mtd sbus video macintosh usb input telephony sgi ide \ +mod-subdirs := dio hil mtd sbus video macintosh usb input telephony ide \ message/i2o message/fusion scsi md ieee1394 pnp isdn atm \ fc4 net/hamradio i2c acpi bluetooth @@ -30,7 +30,6 @@ subdir-$(CONFIG_USB) += usb subdir-$(CONFIG_INPUT) += input subdir-$(CONFIG_PHONE) += telephony -subdir-$(CONFIG_SGI) += sgi subdir-$(CONFIG_IDE) += ide subdir-$(CONFIG_SCSI) += scsi subdir-$(CONFIG_I2O) += message/i2o @@ -45,7 +44,7 @@ # CONFIG_HAMRADIO can be set without CONFIG_NETDEVICE being set -- ch subdir-$(CONFIG_HAMRADIO) += net/hamradio subdir-$(CONFIG_I2C) += i2c -subdir-$(CONFIG_ACPI) += acpi +subdir-$(CONFIG_ACPI_BOOT) += acpi subdir-$(CONFIG_BLUEZ) += bluetooth diff -urN linux-2.4.21/drivers/acorn/block/fd1772.c linux-2.4.22/drivers/acorn/block/fd1772.c --- linux-2.4.21/drivers/acorn/block/fd1772.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acorn/block/fd1772.c 2003-08-25 04:44:40.000000000 -0700 @@ -1567,26 +1567,26 @@ int fd1772_init(void) { - int err; - int i; + int i, err; if (!machine_is_archimedes()) return 0; - if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) { + err = register_blkdev(MAJOR_NR, "fd", &floppy_fops); + if (err) { printk("Unable to get major %d for floppy\n", MAJOR_NR); - return 1; + goto err_out; } + err = -EBUSY; if (request_dma(FLOPPY_DMA, "fd1772")) { printk("Unable to grab DMA%d for the floppy (1772) driver\n", FLOPPY_DMA); - return 1; + goto err_blkdev; }; if (request_dma(FIQ_FD1772, "fd1772 end")) { printk("Unable to grab DMA%d for the floppy (1772) driver\n", FIQ_FD1772); - err = 1; /* XXX */ - goto cleanup_dma; + goto err_dma1; }; /* initialize variables */ @@ -1596,16 +1596,15 @@ BufferDrive = BufferSide = BufferTrack = -1; /* Atari uses 512 - I want to eventually cope with 1K sectors */ DMABuffer = (char *)kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL); - if (DMABuffer == NULL) - goto cleanup_dma; TrackBuffer = DMABuffer + 512; #else /* Allocate memory for the DMAbuffer - on the Atari this takes it out of some special memory... */ DMABuffer = (char *) kmalloc(2048); /* Copes with pretty large sectors */ - if (DMABuffer == NULL) - goto cleanup_dma; #endif + if (DMABuffer == NULL) + goto err_dma2; + enable_dma(FIQ_FD1772); /* This inserts a call to our command end routine */ for (i = 0; i < FD_MAX_UNITS; i++) { unit[i].track = -1; @@ -1624,7 +1623,13 @@ config_types(); return 0; -cleanup_dma: + + err_dma2: + free_dma(FIQ_FD1772); + err_dma1: free_dma(FLOPPY_DMA); + err_blkdev: + unregister_blkdev(MAJOR_NR, &floppy_fops); + err_out: return err; } diff -urN linux-2.4.21/drivers/acorn/char/Makefile linux-2.4.22/drivers/acorn/char/Makefile --- linux-2.4.21/drivers/acorn/char/Makefile 2001-08-12 10:38:48.000000000 -0700 +++ linux-2.4.22/drivers/acorn/char/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -24,7 +24,9 @@ obj-arc := keyb_arc.o obj-rpc := keyb_ps2.o obj-clps7500 := keyb_ps2.o defkeymap-acorn.o +obj-riscstation := keyb_ps2.o defkeymap-acorn.o +obj-$(CONFIG_7K5MOUSE) += mouse_ps2.o obj-$(CONFIG_RPCMOUSE) += mouse_rpc.o obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o diff -urN linux-2.4.21/drivers/acorn/char/i2c.c linux-2.4.22/drivers/acorn/char/i2c.c --- linux-2.4.21/drivers/acorn/char/i2c.c 2001-03-02 18:38:37.000000000 -0800 +++ linux-2.4.22/drivers/acorn/char/i2c.c 2003-08-25 04:44:40.000000000 -0700 @@ -14,6 +14,9 @@ */ #include #include +#include +#include +#include #include #include @@ -21,15 +24,19 @@ #include #include #include +#include #include "pcf8583.h" -extern unsigned long -mktime(unsigned int year, unsigned int mon, unsigned int day, - unsigned int hour, unsigned int min, unsigned int sec); extern int (*set_rtc)(void); static struct i2c_client *rtc_client; +static const unsigned char days_in_mon[] = + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +static unsigned int rtc_epoch = 1900; + +#define CMOS_CHECKSUM (63) +#define CMOS_YEAR (64 + 128) static inline int rtc_command(int cmd, void *data) { @@ -44,12 +51,10 @@ /* * Read the current RTC time and date, and update xtime. */ -static void get_rtc_time(void) +static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year) { - unsigned char ctrl; - unsigned char year; - struct rtc_tm rtctm; - struct mem rtcmem = { 0xc0, 1, &year }; + unsigned char ctrl, yr[2]; + struct mem rtcmem = { CMOS_YEAR, sizeof(yr), yr }; /* * Ensure that the RTC is running. @@ -73,22 +78,53 @@ if (rtc_command(MEM_READ, &rtcmem)) return; - if (rtc_command(RTC_GETDATETIME, &rtctm)) + if (rtc_command(RTC_GETDATETIME, rtctm)) return; - if (year < 70) - year += 100; + *year = yr[1] * 100 + yr[0]; +} + +static int set_rtc_time(struct rtc_tm *rtctm, unsigned int year) +{ + unsigned char yr[2], leap, chk; + struct mem cmos_year = { CMOS_YEAR, sizeof(yr), yr }; + struct mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; + int ret; + + leap = (!(year % 4) && (year % 100)) || !(year % 400); + + if (rtctm->mon > 12 || rtctm->mday == 0) + return -EINVAL; + + if (rtctm->mday > (days_in_mon[rtctm->mon] + (rtctm->mon == 2 && leap))) + return -EINVAL; + + if (rtctm->hours >= 24 || rtctm->mins >= 60 || rtctm->secs >= 60) + return -EINVAL; - xtime.tv_usec = rtctm.cs * 10000; - xtime.tv_sec = mktime(1900 + year, rtctm.mon, rtctm.mday, - rtctm.hours, rtctm.mins, rtctm.secs); + ret = rtc_command(RTC_SETDATETIME, rtctm); + if (ret == 0) { + rtc_command(MEM_READ, &cmos_check); + rtc_command(MEM_READ, &cmos_year); + + chk -= yr[1] + yr[0]; + + yr[1] = year / 100; + yr[0] = year % 100; + + chk += yr[1] + yr[0]; + + rtc_command(MEM_WRITE, &cmos_year); + rtc_command(MEM_WRITE, &cmos_check); + } + return ret; } /* * Set the RTC time only. Note that * we do not touch the date. */ -static int set_rtc_time(void) +static int k_set_rtc_time(void) { struct rtc_tm new_rtctm, old_rtctm; unsigned long nowtime = xtime.tv_sec; @@ -110,13 +146,70 @@ * [ rtc: 1/1/2000 23:58:00, real 2/1/2000 00:01:00, * rtc gets set to 1/1/2000 00:01:00 ] */ - if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) || - (new_rtctm.hours == 23 && new_rtctm.mins == 59)) + if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) || + (new_rtctm.hours == 23 && new_rtctm.mins == 59)) return 1; return rtc_command(RTC_SETTIME, &new_rtctm); } +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + unsigned int year; + struct rtc_time rtctm; + struct rtc_tm rtc_raw; + + switch (cmd) { + case RTC_ALM_READ: + case RTC_ALM_SET: + break; + + case RTC_RD_TIME: + get_rtc_time(&rtc_raw, &year); + rtctm.tm_sec = rtc_raw.secs; + rtctm.tm_min = rtc_raw.mins; + rtctm.tm_hour = rtc_raw.hours; + rtctm.tm_mday = rtc_raw.mday; + rtctm.tm_mon = rtc_raw.mon - 1; /* month starts at 0 */ + rtctm.tm_year = year - 1900; /* starts at 1900 */ + return copy_to_user((void *)arg, &rtctm, sizeof(rtctm)) + ? -EFAULT : 0; + + case RTC_SET_TIME: + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtctm, (void *)arg, sizeof(rtctm))) + return -EFAULT; + rtc_raw.secs = rtctm.tm_sec; + rtc_raw.mins = rtctm.tm_min; + rtc_raw.hours = rtctm.tm_hour; + rtc_raw.mday = rtctm.tm_mday; + rtc_raw.mon = rtctm.tm_mon + 1; + rtc_raw.year_off = 2; + year = rtctm.tm_year + 1900; + return set_rtc_time(&rtc_raw, year); + break; + + case RTC_EPOCH_READ: + return put_user(rtc_epoch, (unsigned long *)arg); + + } + return -EINVAL; +} + +static struct file_operations rtc_fops = { + ioctl: rtc_ioctl, +}; + +static struct miscdevice rtc_dev = { + minor: RTC_MINOR, + name: "rtc", + fops: &rtc_fops, +}; + +/* IOC / IOMD i2c driver */ #define FORCE_ONES 0xdc #define SCL 0x02 @@ -184,9 +277,16 @@ { if (client->id == I2C_DRIVERID_PCF8583 && client->addr == 0x50) { + struct rtc_tm rtctm; + unsigned int year; + rtc_client = client; - get_rtc_time(); - set_rtc = set_rtc_time; + get_rtc_time(&rtctm, &year); + + xtime.tv_usec = rtctm.cs * 10000; + xtime.tv_sec = mktime(year, rtctm.mon, rtctm.mday, + rtctm.hours, rtctm.mins, rtctm.secs); + set_rtc = k_set_rtc_time; } return 0; @@ -212,9 +312,16 @@ static int __init i2c_ioc_init(void) { + int ret; + force_ones = FORCE_ONES | SCL | SDA; - return i2c_bit_add_bus(&ioc_ops); + ret = i2c_bit_add_bus(&ioc_ops); + + if (ret >= 0) + misc_register(&rtc_dev); + + return ret; } __initcall(i2c_ioc_init); diff -urN linux-2.4.21/drivers/acorn/char/keyb_arc.c linux-2.4.22/drivers/acorn/char/keyb_arc.c --- linux-2.4.21/drivers/acorn/char/keyb_arc.c 2001-08-12 10:38:48.000000000 -0700 +++ linux-2.4.22/drivers/acorn/char/keyb_arc.c 2003-08-25 04:44:40.000000000 -0700 @@ -419,12 +419,51 @@ disable_irq(irq); } +static int a5kkbd_setkeycode(unsigned int scancode, unsigned int keycode) +{ + return -EINVAL; +} + +static int a5kkbd_getkeycode(unsigned int scancode) +{ + return -EINVAL; +} + +static int a5kkbd_translate(unsigned char scancode, unsigned char *keycode, char rawmode) +{ + *keycode = scancode; + return 1; +} + +static char a5kkbd_unexpected_up(unsigned char keycode) +{ + return 0200; +} + +static int a5kkbd_rate(struct kbd_repeat *rep) +{ + return -EINVAL; +} + #ifdef CONFIG_KBDMOUSE static struct busmouse a5kkbd_mouse = { 6, "kbdmouse", NULL, NULL, NULL, 7 }; #endif +struct kbd_ops_struct a5k_kbd_ops = { + k_setkeycode: a5kkbd_setkeycode, + k_getkeycode: a5kkbd_getkeycode, + k_translate: a5kkbd_translate, + k_unexpected_up: a5kkbd_unexpected_up, + k_leds: a5kkbd_leds, + k_rate: a5kkbd_rate, +#ifdef CONFIG_MAGIC_SYSRQ + k_sysrq_xlate: a5kkbd_sysrq_xlate, + k_sysrq_key: 13, +#endif +}; + void __init a5kkbd_init_hw (void) { if (request_irq (IRQ_KEYBOARDTX, a5kkbd_tx, 0, "keyboard", NULL) != 0) diff -urN linux-2.4.21/drivers/acorn/char/mouse_ps2.c linux-2.4.22/drivers/acorn/char/mouse_ps2.c --- linux-2.4.21/drivers/acorn/char/mouse_ps2.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acorn/char/mouse_ps2.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,8 +1,6 @@ /* * Driver for PS/2 mouse on IOMD interface */ - -#include #include #include #include @@ -294,3 +292,6 @@ return 0; } + +module_init(psaux_init); + diff -urN linux-2.4.21/drivers/acorn/char/serial-atomwide.c linux-2.4.22/drivers/acorn/char/serial-atomwide.c --- linux-2.4.21/drivers/acorn/char/serial-atomwide.c 2000-09-18 15:15:22.000000000 -0700 +++ linux-2.4.22/drivers/acorn/char/serial-atomwide.c 2003-08-25 04:44:40.000000000 -0700 @@ -12,15 +12,28 @@ * 07-05-1996 RMK Altered for greater number of cards. * 30-07-1996 RMK Now uses generic card code. */ -#define MY_CARD_LIST { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL } -#define MY_NUMPORTS 3 -#define MY_BAUD_BASE (7372800 / 16) -#define MY_BASE_ADDRESS(ec) \ - ecard_address ((ec), ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2) -#define MY_PORT_ADDRESS(port,cardaddr) \ - ((cardaddr) + 0x200 - (port) * 0x100) +#include +#include -#define INIT serial_card_atomwide_init -#define EXIT serial_card_atomwide_exit +#define MAX_PORTS 3 + +struct serial_card_type { + unsigned int num_ports; + unsigned int baud_base; + unsigned int type; + unsigned int offset[MAX_PORTS]; +}; + +static struct serial_card_type atomwide_type = { + .num_ports = 3, + .baud_base = 7372800 / 16, + .type = ECARD_RES_IOCSLOW, + .offset = { 0x2800, 0x2400, 0x2000 }, +}; + +static const struct ecard_id serial_cids[] = { + { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, &atomwide_type }, + { 0xffff, 0xffff } +}; #include "serial-card.c" diff -urN linux-2.4.21/drivers/acorn/char/serial-card.c linux-2.4.22/drivers/acorn/char/serial-card.c --- linux-2.4.21/drivers/acorn/char/serial-card.c 2001-09-13 15:21:32.000000000 -0700 +++ linux-2.4.22/drivers/acorn/char/serial-card.c 2003-08-25 04:44:40.000000000 -0700 @@ -27,106 +27,110 @@ */ #include #include -#include +#include +#include #include +#include +#include #include +#include #include #include -#ifndef NUM_SERIALS -#define NUM_SERIALS MY_NUMPORTS * MAX_ECARDS -#endif - -#ifdef MODULE -static int __serial_ports[NUM_SERIALS]; -static int __serial_pcount; -static int __serial_addr[NUM_SERIALS]; -static struct expansion_card *expcard[MAX_ECARDS]; -#define ADD_ECARD(ec,card) expcard[(card)] = (ec) -#define ADD_PORT(port,addr) \ - do { \ - __serial_ports[__serial_pcount] = (port); \ - __serial_addr[__serial_pcount] = (addr); \ - __serial_pcount += 1; \ - } while (0) -#else -#define ADD_ECARD(ec,card) -#define ADD_PORT(port,addr) -#endif +struct serial_card_info { + unsigned int num_ports; + int ports[MAX_PORTS]; +}; -static const card_ids serial_cids[] = { MY_CARD_LIST, { 0xffff, 0xffff } }; - -static inline int serial_register_onedev (unsigned long port, int irq) +static inline int +serial_register_onedev(unsigned long baddr, void *vaddr, int irq, unsigned int baud_base) { - struct serial_struct req; + struct serial_struct req; - memset(&req, 0, sizeof(req)); - req.baud_base = MY_BAUD_BASE; - req.irq = irq; - req.port = port; - req.flags = 0; + memset(&req, 0, sizeof(req)); + req.irq = irq; + req.flags = UPF_AUTOPROBE | UPF_RESOURCES | + UPF_SHARE_IRQ; + req.baud_base = baud_base; + req.io_type = UPIO_MEM; + req.iomem_base = vaddr; + req.iomem_reg_shift = 2; + req.iomap_base = baddr; - return register_serial(&req); + return register_serial(&req); } -static int __init INIT (void) +static int __devinit +serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) { - int card = 0; - - ecard_startfind (); + struct serial_card_info *info; + struct serial_card_type *type = id->data; + unsigned long bus_addr; + unsigned char *virt_addr; + unsigned int port; + + info = kmalloc(sizeof(struct serial_card_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + memset(info, 0, sizeof(struct serial_card_info)); + info->num_ports = type->num_ports; + + ecard_set_drvdata(ec, info); + + bus_addr = ec->resource[type->type].start; + virt_addr = ioremap(bus_addr, ec->resource[type->type].end - bus_addr + 1); + if (!virt_addr) { + kfree(info); + return -ENOMEM; + } - do { - struct expansion_card *ec; - unsigned long cardaddr; - int port; + for (port = 0; port < info->num_ports; port ++) { + unsigned long baddr = bus_addr + type->offset[port]; + unsigned char *vaddr = virt_addr + type->offset[port]; - ec = ecard_find (0, serial_cids); - if (!ec) - break; + info->ports[port] = serial_register_onedev(baddr, vaddr, + ec->irq, type->baud_base); + } - cardaddr = MY_BASE_ADDRESS(ec); + return 0; +} - for (port = 0; port < MY_NUMPORTS; port ++) { - unsigned long address; - int line; +static void __devexit serial_card_remove(struct expansion_card *ec) +{ + struct serial_card_info *info = ecard_get_drvdata(ec); + int i; - address = MY_PORT_ADDRESS(port, cardaddr); + ecard_set_drvdata(ec, NULL); - line = serial_register_onedev (address, ec->irq); - if (line < 0) - break; - ADD_PORT(line, address); - } + for (i = 0; i < info->num_ports; i++) + if (info->ports[i] > 0) + unregister_serial(info->ports[i]); - if (port) { - ecard_claim (ec); - ADD_ECARD(ec, card); - } else - break; - } while (++card < MAX_ECARDS); - return card ? 0 : -ENODEV; + kfree(info); } -static void __exit EXIT (void) +static struct ecard_driver serial_card_driver = { + .probe = serial_card_probe, + .remove = __devexit_p(serial_card_remove), + .id_table = serial_cids, +}; + +static int __init serial_card_init(void) { -#ifdef MODULE - int i; + return ecard_register_driver(&serial_card_driver); +} - for (i = 0; i < __serial_pcount; i++) { - unregister_serial(__serial_ports[i]); - release_region(__serial_addr[i], 8); - } - - for (i = 0; i < MAX_ECARDS; i++) - if (expcard[i]) - ecard_release (expcard[i]); -#endif +static void __exit serial_card_exit(void) +{ + ecard_remove_driver(&serial_card_driver); } EXPORT_NO_SYMBOLS; +MODULE_AUTHOR("Russell King"); MODULE_LICENSE("GPL"); -module_init(INIT); -module_exit(EXIT); +module_init(serial_card_init); +module_exit(serial_card_exit); diff -urN linux-2.4.21/drivers/acorn/char/serial-dualsp.c linux-2.4.22/drivers/acorn/char/serial-dualsp.c --- linux-2.4.21/drivers/acorn/char/serial-dualsp.c 2000-09-18 15:15:22.000000000 -0700 +++ linux-2.4.22/drivers/acorn/char/serial-dualsp.c 2003-08-25 04:44:40.000000000 -0700 @@ -10,15 +10,28 @@ * Changelog: * 30-07-1996 RMK Created */ -#define MY_CARD_LIST { MANU_SERPORT, PROD_SERPORT_DSPORT } -#define MY_NUMPORTS 2 -#define MY_BAUD_BASE (3686400 / 16) -#define MY_BASE_ADDRESS(ec) \ - ecard_address (ec, ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2) -#define MY_PORT_ADDRESS(port,cardaddress) \ - ((cardaddress) + (port) * 8) +#include +#include -#define INIT serial_card_dualsp_init -#define EXIT serial_card_dualsp_exit +#define MAX_PORTS 3 + +struct serial_card_type { + unsigned int num_ports; + unsigned int baud_base; + unsigned int type; + unsigned int offset[MAX_PORTS]; +}; + +static struct serial_card_type serport_type = { + .num_ports = 2, + .baud_base = 3686400 / 16, + .type = ECARD_RES_IOCSLOW, + .offset = { 0x2000, 0x2020 }, +}; + +static const struct ecard_id serial_cids[] = { + { MANU_SERPORT, PROD_SERPORT_DSPORT, &serport_type }, + { 0xffff, 0xffff } +}; #include "serial-card.c" diff -urN linux-2.4.21/drivers/acorn/net/ether1.c linux-2.4.22/drivers/acorn/net/ether1.c --- linux-2.4.21/drivers/acorn/net/ether1.c 2001-09-13 15:21:32.000000000 -0700 +++ linux-2.4.22/drivers/acorn/net/ether1.c 2003-08-25 04:44:40.000000000 -0700 @@ -647,6 +647,11 @@ { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + if (!is_valid_ether_addr(dev->dev_addr)) { + printk("%s: invalid ethernet MAC address\n", dev->name); + return -EINVAL; + } + if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) return -EAGAIN; @@ -684,7 +689,6 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; - int len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr; unsigned long flags; tx_t tx; @@ -702,19 +706,25 @@ priv->restart = 0; } + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if (!skb) + goto out; + } + /* * insert packet followed by a nop */ txaddr = ether1_txalloc (dev, TX_SIZE); tbdaddr = ether1_txalloc (dev, TBD_SIZE); - dataddr = ether1_txalloc (dev, len); + dataddr = ether1_txalloc (dev, skb->len); nopaddr = ether1_txalloc (dev, NOP_SIZE); tx.tx_status = 0; tx.tx_command = CMD_TX | CMD_INTR; tx.tx_link = nopaddr; tx.tx_tbdoffset = tbdaddr; - tbd.tbd_opts = TBD_EOL | len; + tbd.tbd_opts = TBD_EOL | skb->len; tbd.tbd_link = I82586_NULL; tbd.tbd_bufl = dataddr; tbd.tbd_bufh = 0; @@ -725,7 +735,7 @@ save_flags_cli(flags); ether1_writebuffer (dev, &tx, txaddr, TX_SIZE); ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE); - ether1_writebuffer (dev, skb->data, dataddr, len); + ether1_writebuffer (dev, skb->data, dataddr, skb->len); ether1_writebuffer (dev, &nop, nopaddr, NOP_SIZE); tmp = priv->tx_link; priv->tx_link = nopaddr; @@ -747,6 +757,7 @@ if (tst == -1) netif_stop_queue(dev); + out: return 0; } @@ -971,6 +982,23 @@ return &priv->stats; } +static int +ether1_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + if (netif_running(dev)) + return -EBUSY; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + /* + * We'll set the MAC address on the chip when we open it. + */ + + return 0; +} + /* * Set or clear the multicast filter for this adaptor. * num_addrs == -1 Promiscuous mode, receive all packets. @@ -1038,6 +1066,7 @@ dev->hard_start_xmit = ether1_sendpacket; dev->get_stats = ether1_getstats; dev->set_multicast_list = ether1_setmulticastlist; + dev->set_mac_address = ether1_set_mac_address; dev->tx_timeout = ether1_timeout; dev->watchdog_timeo = 5 * HZ / 100; return 0; diff -urN linux-2.4.21/drivers/acorn/net/ether3.c linux-2.4.22/drivers/acorn/net/ether3.c --- linux-2.4.21/drivers/acorn/net/ether3.c 2001-09-13 15:21:32.000000000 -0700 +++ linux-2.4.22/drivers/acorn/net/ether3.c 2003-08-25 04:44:40.000000000 -0700 @@ -417,6 +417,9 @@ static int ether3_open(struct net_device *dev) { + if (!is_valid_ether_addr(dev->dev_addr)) + return -EINVAL; + if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev)) return -EAGAIN; @@ -460,6 +463,23 @@ return &priv->stats; } +static int +ether3_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + if (netif_running(dev)) + return -EBUSY; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + /* + * We'll set the MAC address on the chip when we open it. + */ + + return 0; +} + /* * Set or clear promiscuous/multicast mode filter for this adaptor. * @@ -531,6 +551,12 @@ return 0; } + if (skb->len != length) { + skb = skb_padto(skb, length); + if (!skb) + goto out; + } + next_ptr = (priv->tx_head + 1) & 15; save_flags_cli(flags); @@ -572,6 +598,7 @@ if (priv->tx_tail == next_ptr) netif_stop_queue(dev); + out: return 0; } @@ -718,7 +745,7 @@ /* * Don't print this message too many times... */ - if (jiffies - last_warned > 30 * HZ) { + if (time_after(jiffies, last_warned + 10 * HZ)) { last_warned = jiffies; printk("%s: memory squeeze, dropping packet.\n", dev->name); } @@ -875,6 +902,7 @@ dev->hard_start_xmit = ether3_sendpacket; dev->get_stats = ether3_getstats; dev->set_multicast_list = ether3_setmulticastlist; + dev->set_mac_address = ether3_set_mac_address; dev->tx_timeout = ether3_timeout; dev->watchdog_timeo = 5 * HZ / 100; return 0; diff -urN linux-2.4.21/drivers/acorn/net/etherh.c linux-2.4.22/drivers/acorn/net/etherh.c --- linux-2.4.21/drivers/acorn/net/etherh.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/acorn/net/etherh.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/net/etherh.c * - * Copyright (C) 2000 Russell King + * Copyright (C) 2000-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -23,6 +23,7 @@ * 12-10-1999 CK/TEW EtherM driver first release * 21-12-2000 TTC EtherH/EtherM integration * 25-12-2000 RMK 1.08 Clean integration of EtherM into this driver. + * 03-01-2002 RMK 1.09 Always enable IRQs if we're in the nic slot. */ #include @@ -64,13 +65,18 @@ { 0xffff, 0xffff } }; +struct etherh_priv { + unsigned int id; + unsigned int ctrl_port; + unsigned int ctrl; +}; MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("EtherH/EtherM driver"); MODULE_LICENSE("GPL"); static char version[] __initdata = - "EtherH/EtherM Driver (c) 2000 Russell King v1.08\n"; + "EtherH/EtherM Driver (c) 2002 Russell King v1.09\n"; #define ETHERH500_DATAPORT 0x200 /* MEMC */ #define ETHERH500_NS8390 0x000 /* MEMC */ @@ -97,18 +103,61 @@ #define ETHERM_TX_START_PAGE 64 #define ETHERM_STOP_PAGE 127 -/* --------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ + +static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned int mask) +{ + eh->ctrl |= mask; + outb(eh->ctrl, eh->ctrl_port); +} + +static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned int mask) +{ + eh->ctrl &= ~mask; + outb(eh->ctrl, eh->ctrl_port); +} + +static inline unsigned int etherh_get_stat(struct etherh_priv *eh) +{ + return inb(eh->ctrl_port); +} + + + + +static void etherh_irq_enable(ecard_t *ec, int irqnr) +{ + struct etherh_priv *eh = ec->irq_data; + + etherh_set_ctrl(eh, ETHERH_CP_IE); +} + +static void etherh_irq_disable(ecard_t *ec, int irqnr) +{ + struct etherh_priv *eh = ec->irq_data; + + etherh_clr_ctrl(eh, ETHERH_CP_IE); +} + +static expansioncard_ops_t etherh_ops = { + irqenable: etherh_irq_enable, + irqdisable: etherh_irq_disable, +}; + + + static void etherh_setif(struct net_device *dev) { struct ei_device *ei_local = (struct ei_device *) dev->priv; + struct etherh_priv *eh = (struct etherh_priv *)dev->rmem_start; unsigned long addr, flags; save_flags_cli(flags); /* set the interface type */ - switch (dev->mem_end) { + switch (eh->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A: addr = dev->base_addr + EN0_RCNTHI; @@ -124,14 +173,13 @@ break; case PROD_I3_ETHERLAN500: - addr = dev->rmem_start; - switch (dev->if_port) { case IF_PORT_10BASE2: - outb(inb(addr) & ~ETHERH_CP_IF, addr); + etherh_clr_ctrl(eh, ETHERH_CP_IF); break; + case IF_PORT_10BASET: - outb(inb(addr) | ETHERH_CP_IF, addr); + etherh_set_ctrl(eh, ETHERH_CP_IF); break; } break; @@ -147,9 +195,10 @@ etherh_getifstat(struct net_device *dev) { struct ei_device *ei_local = (struct ei_device *) dev->priv; + struct etherh_priv *eh = (struct etherh_priv *)dev->rmem_start; int stat = 0; - switch (dev->mem_end) { + switch (eh->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A: switch (dev->if_port) { @@ -168,7 +217,7 @@ stat = 1; break; case IF_PORT_10BASET: - stat = inb(dev->rmem_start) & ETHERH_CP_HEARTBEAT; + stat = etherh_get_stat(eh) & ETHERH_CP_HEARTBEAT; break; } break; @@ -251,7 +300,13 @@ return; } - ei_local->dmaing |= 1; + /* + * Make sure we have a round number of bytes if we're in word mode. + */ + if (count & 1 && ei_local->word16) + count++; + + ei_local->dmaing = 1; addr = dev->base_addr; dma_addr = dev->mem_start; @@ -291,7 +346,7 @@ } outb (ENISR_RDC, addr + EN0_ISR); - ei_local->dmaing &= ~1; + ei_local->dmaing = 0; } /* @@ -311,7 +366,7 @@ return; } - ei_local->dmaing |= 1; + ei_local->dmaing = 1; addr = dev->base_addr; dma_addr = dev->mem_start; @@ -332,7 +387,7 @@ insb (dma_addr, buf, count); outb (ENISR_RDC, addr + EN0_ISR); - ei_local->dmaing &= ~1; + ei_local->dmaing = 0; } /* @@ -351,7 +406,7 @@ return; } - ei_local->dmaing |= 1; + ei_local->dmaing = 1; addr = dev->base_addr; dma_addr = dev->mem_start; @@ -369,7 +424,7 @@ insb (dma_addr, hdr, sizeof (*hdr)); outb (ENISR_RDC, addr + EN0_ISR); - ei_local->dmaing &= ~1; + ei_local->dmaing = 0; } /* @@ -385,6 +440,12 @@ { struct ei_device *ei_local = (struct ei_device *) dev->priv; + if (!is_valid_ether_addr(dev->dev_addr)) { + printk(KERN_WARNING "%s: invalid ethernet address\n", + dev->name); + return -EINVAL; + } + if (request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)) return -EAGAIN; @@ -427,22 +488,22 @@ return 0; } -static void etherh_irq_enable(ecard_t *ec, int irqnr) +static int +etherh_set_mac_address(struct net_device *dev, void *p) { - unsigned int ctrl_addr = (unsigned int)ec->irq_data; - outb(inb(ctrl_addr) | ETHERH_CP_IE, ctrl_addr); -} + struct sockaddr *addr = p; -static void etherh_irq_disable(ecard_t *ec, int irqnr) -{ - unsigned int ctrl_addr = (unsigned int)ec->irq_data; - outb(inb(ctrl_addr) & ~ETHERH_CP_IE, ctrl_addr); -} + if (netif_running(dev)) + return -EBUSY; -static expansioncard_ops_t etherh_ops = { - irqenable: etherh_irq_enable, - irqdisable: etherh_irq_disable, -}; + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + /* + * We'll set the MAC address on the chip when we open it. + */ + + return 0; +} /* * Initialisation @@ -460,11 +521,13 @@ * Read the ethernet address string from the on board rom. * This is an ascii string... */ -static int __init etherh_addr(char *addr, struct expansion_card *ec) +static void __init etherh_addr(char *addr, struct expansion_card *ec) { struct in_chunk_dir cd; char *s; + memset(addr, 0, 6); + if (ecard_readchunk(&cd, ec, 0xf5, 0) && (s = strchr(cd.d.string, '('))) { int i; for (i = 0; i < 6; i++) { @@ -472,31 +535,25 @@ if (*s != (i == 5? ')' : ':')) break; } - if (i == 6) - return 0; } - return -ENODEV; } /* * Create an ethernet address from the system serial number. */ -static int __init etherm_addr(char *addr) +static void __init etherm_addr(char *addr) { unsigned int serial; - if (system_serial_low == 0 && system_serial_high == 0) - return -ENODEV; - serial = system_serial_low | system_serial_high; - - addr[0] = 0; - addr[1] = 0; - addr[2] = 0xa4; - addr[3] = 0x10 + (serial >> 24); - addr[4] = serial >> 16; - addr[5] = serial >> 8; - return 0; + if (serial != 0) { + addr[0] = 0; + addr[1] = 0; + addr[2] = 0xa4; + addr[3] = 0x10 + (serial >> 24); + addr[4] = serial >> 16; + addr[5] = serial >> 8; + } } static u32 etherh_regoffsets[16]; @@ -506,6 +563,7 @@ { struct ei_device *ei_local; struct net_device *dev; + struct etherh_priv *eh; const char *dev_type; int i, size; @@ -517,42 +575,50 @@ if (!dev) goto out; + eh = kmalloc(sizeof(struct etherh_priv), GFP_KERNEL); + if (!eh) + goto out_nopriv; + SET_MODULE_OWNER(dev); - dev->open = etherh_open; - dev->stop = etherh_close; - dev->set_config = etherh_set_config; - dev->irq = ec->irq; - dev->base_addr = ecard_address(ec, ECARD_MEMC, 0); - dev->mem_end = ec->cid.product; + dev->open = etherh_open; + dev->stop = etherh_close; + dev->set_mac_address = etherh_set_mac_address; + dev->set_config = etherh_set_config; + dev->irq = ec->irq; + dev->base_addr = ecard_address(ec, ECARD_MEMC, 0); + dev->rmem_start = (unsigned long)eh; + + /* + * IRQ and control port handling + */ ec->ops = ðerh_ops; + ec->irq_data = eh; + eh->ctrl = 0; + eh->id = ec->cid.product; switch (ec->cid.product) { case PROD_ANT_ETHERM: - if (etherm_addr(dev->dev_addr)) - goto free; + etherm_addr(dev->dev_addr); dev->base_addr += ETHERM_NS8390; dev->mem_start = dev->base_addr + ETHERM_DATAPORT; - ec->irq_data = (void *)(dev->base_addr + ETHERM_CTRLPORT); + eh->ctrl_port = dev->base_addr + ETHERM_CTRLPORT; break; case PROD_I3_ETHERLAN500: - if (etherh_addr(dev->dev_addr, ec)) - goto free; + etherh_addr(dev->dev_addr, ec); dev->base_addr += ETHERH500_NS8390; dev->mem_start = dev->base_addr + ETHERH500_DATAPORT; - dev->rmem_start = (unsigned long) - ec->irq_data = (void *)ecard_address (ec, ECARD_IOC, ECARD_FAST) + eh->ctrl_port = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ETHERH500_CTRLPORT; break; case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A: - if (etherh_addr(dev->dev_addr, ec)) - goto free; + etherh_addr(dev->dev_addr, ec); dev->base_addr += ETHERH600_NS8390; - dev->mem_start = dev->base_addr + ETHERH600_DATAPORT; - ec->irq_data = (void *)(dev->base_addr + ETHERH600_CTRLPORT); + dev->mem_start = dev->base_addr + ETHERH600_DATAPORT; + eh->ctrl_port = dev->base_addr + ETHERH600_CTRLPORT; break; default: @@ -572,6 +638,12 @@ goto release; /* + * If we're in the NIC slot, make sure the IRQ is enabled + */ + if (dev->irq == 11) + etherh_set_ctrl(eh, ETHERH_CP_IE); + + /* * Unfortunately, ethdev_init eventually calls * ether_setup, which re-writes dev->flags. */ @@ -636,6 +708,8 @@ release: release_region(dev->base_addr, 16); free: + kfree(eh); +out_nopriv: unregister_netdev(dev); kfree(dev); out: @@ -696,6 +770,7 @@ } if (e_card[i]) { e_card[i]->ops = NULL; + kfree(e_card[i]->irq_data); ecard_release(e_card[i]); e_card[i] = NULL; } diff -urN linux-2.4.21/drivers/acorn/scsi/arxescsi.c linux-2.4.22/drivers/acorn/scsi/arxescsi.c --- linux-2.4.21/drivers/acorn/scsi/arxescsi.c 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/drivers/acorn/scsi/arxescsi.c 2003-08-25 04:44:40.000000000 -0700 @@ -37,16 +37,22 @@ #include "../../scsi/sd.h" #include "../../scsi/hosts.h" -#include "arxescsi.h" +#include #include "fas216.h" +#include "scsi.h" -/* Hmm - this should go somewhere else */ -#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE) +struct arxescsi_info { + FAS216_Info info; + struct expansion_card *ec; + unsigned int dmaarea; /* Pseudo DMA area */ +}; -/* Configuration */ -#define ARXESCSI_XTALFREQ 24 -#define ARXESCSI_ASYNC_PERIOD 200 -#define ARXESCSI_SYNC_DEPTH 0 +#define DMADATA_OFFSET (0x200/4) + +#define DMASTAT_OFFSET (0x600/4) +#define DMASTAT_DRQ (1 << 0) + +#define CSTATUS_IRQ (1 << 0) /* * List of devices that the driver will recognise @@ -56,11 +62,7 @@ /* * Version */ -#define VER_MAJOR 0 -#define VER_MINOR 1 -#define VER_PATCH 1 - -static struct expansion_card *ecs[MAX_ECARDS]; +#define VERSION "1.10 (22/01/2003 2.4.19-rmk5)" /* * Function: int arxescsi_dma_setup(host, SCpnt, direction, min_type) @@ -157,7 +159,7 @@ void arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, int transfer) { - ARXEScsi_Info *info = (ARXEScsi_Info *)host->hostdata; + struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata; unsigned int length, io, error=0; unsigned char *addr; @@ -182,7 +184,7 @@ if (getb(io, 4) & STAT_INT) break; - if (!(getb(io, 48) & CSTATUS_IRQ)) + if (!(getb(io, 48) & DMASTAT_DRQ)) continue; word = *addr | *(addr + 1) << 8; @@ -205,7 +207,7 @@ break; } - if (!(getb(io, 48) & CSTATUS_IRQ)) + if (!(getb(io, 48) & DMASTAT_DRQ)) continue; insw(info->dmaarea, addr, 256 >> 1); @@ -221,7 +223,7 @@ if (getb(io, 4) & STAT_INT) break; - if (!(getb(io, 48) & CSTATUS_IRQ)) + if (!(getb(io, 48) & DMASTAT_DRQ)) continue; word = getw(io, 16); @@ -248,96 +250,6 @@ } /* - * Function: int arxescsi_detect(Scsi_Host_Template * tpnt) - * Purpose : initialises ARXE SCSI driver - * Params : tpnt - template for this SCSI adapter - * Returns : >0 if host found, 0 otherwise. - */ -int arxescsi_detect(Scsi_Host_Template *tpnt) -{ - static const card_ids arxescsi_cids[] = { ARXESCSI_LIST, { 0xffff, 0xffff} }; - int count = 0; - struct Scsi_Host *host; - - tpnt->proc_name = "arxescsi"; - memset(ecs, 0, sizeof (ecs)); - - ecard_startfind(); - - while (1) { - ARXEScsi_Info *info; - - ecs[count] = ecard_find(0, arxescsi_cids); - if (!ecs[count]) - break; - - ecard_claim(ecs[count]); - - host = scsi_register(tpnt, sizeof (ARXEScsi_Info)); - if (!host) { - ecard_release(ecs[count]); - break; - } - - host->io_port = ecard_address(ecs[count], ECARD_MEMC, 0) + 0x0800; - host->irq = NO_IRQ; - host->dma_channel = NO_DMA; - host->can_queue = 0; /* no command queueing */ - info = (ARXEScsi_Info *)host->hostdata; - - info->info.scsi.io_port = host->io_port; - info->info.scsi.irq = host->irq; - info->info.scsi.io_shift = 3; - info->info.ifcfg.clockrate = ARXESCSI_XTALFREQ; - info->info.ifcfg.select_timeout = 255; - info->info.ifcfg.asyncperiod = ARXESCSI_ASYNC_PERIOD; - info->info.ifcfg.sync_max_depth = ARXESCSI_SYNC_DEPTH; - info->info.ifcfg.cntl3 = CNTL3_FASTSCSI | CNTL3_FASTCLK; - info->info.ifcfg.disconnect_ok = 0; - info->info.ifcfg.wide_max_size = 0; - info->info.dma.setup = arxescsi_dma_setup; - info->info.dma.pseudo = arxescsi_dma_pseudo; - info->info.dma.stop = arxescsi_dma_stop; - info->dmaarea = host->io_port + 128; - info->cstatus = host->io_port + 384; - - ecs[count]->irqaddr = (unsigned char *)BUS_ADDR(host->io_port); - ecs[count]->irqmask = CSTATUS_IRQ; - - request_region(host->io_port , 120, "arxescsi-fas"); - request_region(host->io_port + 128, 384, "arxescsi-dma"); - - printk("scsi%d: Has no interrupts - using polling mode\n", - host->host_no); - - fas216_init(host); - ++count; - } - return count; -} - -/* - * Function: int arxescsi_release(struct Scsi_Host * host) - * Purpose : releases all resources used by this adapter - * Params : host - driver host structure to return info for. - * Returns : nothing - */ -int arxescsi_release(struct Scsi_Host *host) -{ - int i; - - fas216_release(host); - - release_region(host->io_port, 120); - release_region(host->io_port + 128, 384); - - for (i = 0; i < MAX_ECARDS; i++) - if (ecs[i] && host->io_port == (ecard_address(ecs[i], ECARD_MEMC, 0) + 0x0800)) - ecard_release(ecs[i]); - return 0; -} - -/* * Function: const char *arxescsi_info(struct Scsi_Host * host) * Purpose : returns a descriptive string about this interface, * Params : host - driver host structure to return info for. @@ -345,13 +257,12 @@ */ const char *arxescsi_info(struct Scsi_Host *host) { - ARXEScsi_Info *info = (ARXEScsi_Info *)host->hostdata; - static char string[100], *p; + struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%d.%d.%d", VER_MAJOR, VER_MINOR, VER_PATCH); + sprintf(string, "%s (%s) in slot %d v%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION); return string; } @@ -374,26 +285,20 @@ int length, int host_no, int inout) { int pos, begin; - struct Scsi_Host *host = scsi_hostlist; - ARXEScsi_Info *info; + struct Scsi_Host *host; + struct arxescsi_info *info; Scsi_Device *scd; - while (host) { - if (host->host_no == host_no) - break; - host = host->next; - } + host = scsi_host_hn_get(host_no); if (!host) return 0; - info = (ARXEScsi_Info *)host->hostdata; + info = (struct arxescsi_info *)host->hostdata; if (inout == 1) return -EINVAL; begin = 0; - pos = sprintf(buffer, - "ARXE 16-bit SCSI driver version %d.%d.%d\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + pos = sprintf(buffer, "ARXE 16-bit SCSI driver v%s\n", VERSION); pos += fas216_print_host(&info->info, buffer + pos); pos += fas216_print_stats(&info->info, buffer + pos); @@ -418,11 +323,156 @@ return pos; } -static Scsi_Host_Template arxescsi_template = ARXEScsi; +static int arxescsi_probe(struct expansion_card *ec); + +/* + * Function: int arxescsi_detect(Scsi_Host_Template * tpnt) + * Purpose : initialises ARXE SCSI driver + * Params : tpnt - template for this SCSI adapter + * Returns : >0 if host found, 0 otherwise. + */ +static int arxescsi_detect(Scsi_Host_Template *tpnt) +{ + static const card_ids arxescsi_cids[] = { ARXESCSI_LIST, { 0xffff, 0xffff} }; + int count = 0, ret; + + ecard_startfind(); + + while (1) { + struct expansion_card *ec; + ec = ecard_find(0, arxescsi_cids); + if (!ec) + break; + + ecard_claim(ec); + ret = arxescsi_probe(ec); + if (ret) { + ecard_release(ec); + break; + } + ++count; + } + return count; +} + +static void arxescsi_remove(struct Scsi_Host *host); + +/* + * Function: int arxescsi_release(struct Scsi_Host * host) + * Purpose : releases all resources used by this adapter + * Params : host - driver host structure to return info for. + * Returns : nothing + */ +static int arxescsi_release(struct Scsi_Host *host) +{ + arxescsi_remove(host); + return 0; +} + +static Scsi_Host_Template arxescsi_template = { + .module = THIS_MODULE, + .proc_info = arxescsi_proc_info, + .name = "ARXE SCSI card", + .detect = arxescsi_detect, + .release = arxescsi_release, + .info = arxescsi_info, + .bios_param = scsicam_bios_param, + .command = fas216_command, + .queuecommand = fas216_queue_command, + .eh_host_reset_handler = fas216_eh_host_reset, + .eh_bus_reset_handler = fas216_eh_bus_reset, + .eh_device_reset_handler = fas216_eh_device_reset, + .eh_abort_handler = fas216_eh_abort, + .use_new_eh_code = 1, + + .can_queue = 0, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = DISABLE_CLUSTERING, + .proc_name = "arxescsi", +}; + +static int +arxescsi_probe(struct expansion_card *ec) +{ + struct Scsi_Host *host; + struct arxescsi_info *info; + unsigned long base; + int ret; + + base = ecard_address(ec, ECARD_MEMC, 0) + 0x0800; + + if (!request_region(base, 512, "arxescsi")) { + ret = -EBUSY; + goto out; + } + + host = scsi_register(&arxescsi_template, sizeof(struct arxescsi_info)); + if (!host) { + ret = -ENOMEM; + goto out_region; + } + + host->io_port = base; + host->irq = NO_IRQ; + host->dma_channel = NO_DMA; + + info = (struct arxescsi_info *)host->hostdata; + info->ec = ec; + info->dmaarea = base + DMADATA_OFFSET; + + info->info.scsi.io_port = host->io_port; + info->info.scsi.irq = NO_IRQ; + info->info.scsi.io_shift = 3; + info->info.ifcfg.clockrate = 24; /* MHz */ + info->info.ifcfg.select_timeout = 255; + info->info.ifcfg.asyncperiod = 200; /* ns */ + info->info.ifcfg.sync_max_depth = 0; + info->info.ifcfg.cntl3 = CNTL3_FASTSCSI | CNTL3_FASTCLK; + info->info.ifcfg.disconnect_ok = 0; + info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = FASCAP_PSEUDODMA; + info->info.dma.setup = arxescsi_dma_setup; + info->info.dma.pseudo = arxescsi_dma_pseudo; + info->info.dma.stop = arxescsi_dma_stop; + + ec->irqaddr = (unsigned char *)ioaddr(base); + ec->irqmask = CSTATUS_IRQ; + + ret = fas216_init(host); + if (ret) + goto out_unregister; + + ret = fas216_add(host); + if (ret == 0) + goto out; + + fas216_release(host); + out_unregister: + scsi_unregister(host); + out_region: + release_region(base, 512); + out: + return ret; +} + +static void arxescsi_remove(struct Scsi_Host *host) +{ + struct arxescsi_info *info; + + info = (struct arxescsi_info *)host->hostdata; + + fas216_remove(host); + + release_region(host->io_port, 512); + + ecard_release(info->ec); + fas216_release(host); +} static int __init init_arxe_scsi_driver(void) { - arxescsi_template.module = THIS_MODULE; scsi_register_module(MODULE_SCSI_HA, &arxescsi_template); if (arxescsi_template.present) return 0; diff -urN linux-2.4.21/drivers/acorn/scsi/arxescsi.h linux-2.4.22/drivers/acorn/scsi/arxescsi.h --- linux-2.4.21/drivers/acorn/scsi/arxescsi.h 2000-05-12 11:21:20.000000000 -0700 +++ linux-2.4.22/drivers/acorn/scsi/arxescsi.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,82 +0,0 @@ -/* - * ARXE SCSI card driver - * - * Copyright (C) 1997-2000 Russell King - * - * Changes to support ARXE 16-bit SCSI card by Stefan Hanske - */ -#ifndef ARXE_SCSI_H -#define ARXE_SCSI_H - -#define MANU_ARXE 0x0041 -#define PROD_ARXE_SCSI 0x00be - -extern int arxescsi_detect (Scsi_Host_Template *); -extern int arxescsi_release (struct Scsi_Host *); -extern const char *arxescsi_info (struct Scsi_Host *); -extern int arxescsi_proc_info (char *buffer, char **start, off_t offset, - int length, int hostno, int inout); - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef CAN_QUEUE -/* - * Default queue size - */ -#define CAN_QUEUE 1 -#endif - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 1 -#endif - -#ifndef SCSI_ID -/* - * Default SCSI host ID - */ -#define SCSI_ID 7 -#endif - -#include - -#include "fas216.h" - -#define ARXEScsi { \ -proc_info: arxescsi_proc_info, \ -name: "ARXE SCSI card", \ -detect: arxescsi_detect, \ -release: arxescsi_release, \ -info: arxescsi_info, \ -bios_param: scsicam_bios_param, \ -can_queue: CAN_QUEUE, \ -this_id: SCSI_ID, \ -sg_tablesize: SG_ALL, \ -cmd_per_lun: CMD_PER_LUN, \ -use_clustering: DISABLE_CLUSTERING, \ -command: fas216_command, \ -queuecommand: fas216_queue_command, \ -eh_host_reset_handler: fas216_eh_host_reset, \ -eh_bus_reset_handler: fas216_eh_bus_reset, \ -eh_device_reset_handler: fas216_eh_device_reset, \ -eh_abort_handler: fas216_eh_abort, \ -use_new_eh_code: 1 \ - } - -#ifndef HOSTS_C - -typedef struct { - FAS216_Info info; - - /* other info... */ - unsigned int cstatus; /* card status register */ - unsigned int dmaarea; /* Pseudo DMA area */ -} ARXEScsi_Info; - -#define CSTATUS_IRQ (1 << 0) -#define CSTATUS_DRQ (1 << 0) - -#endif /* HOSTS_C */ - -#endif /* ARXE_SCSI_H */ diff -urN linux-2.4.21/drivers/acorn/scsi/cumana_2.c linux-2.4.22/drivers/acorn/scsi/cumana_2.c --- linux-2.4.21/drivers/acorn/scsi/cumana_2.c 2001-11-04 09:31:57.000000000 -0800 +++ linux-2.4.22/drivers/acorn/scsi/cumana_2.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/cumana_2.c * - * Copyright (C) 1997-2000 Russell King + * Copyright (C) 1997-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include #include @@ -38,14 +36,10 @@ #include "../../scsi/sd.h" #include "../../scsi/hosts.h" #include "fas216.h" +#include "scsi.h" #include -/* Configuration */ -#define CUMANASCSI2_XTALFREQ 40 -#define CUMANASCSI2_ASYNC_PERIOD 200 -#define CUMANASCSI2_SYNC_DEPTH 7 - /* * List of devices that the driver will recognise */ @@ -76,11 +70,7 @@ /* * Version */ -#define VER_MAJOR 0 -#define VER_MINOR 0 -#define VER_PATCH 4 - -static struct expansion_card *ecs[MAX_ECARDS]; +#define VERSION "1.00 (13/11/2002 2.4.19-rmk5)" /* * Use term=0,1,0,0,0 to turn terminators on/off @@ -89,16 +79,16 @@ #define NR_SG 256 -typedef struct { - FAS216_Info info; - - /* other info... */ - unsigned int status; /* card status register */ - unsigned int alatch; /* Control register */ - unsigned int terms; /* Terminator state */ - unsigned int dmaarea; /* Pseudo DMA area */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ -} CumanaScsi2_Info; +struct cumanascsi2_info { + FAS216_Info info; + struct expansion_card *ec; + + unsigned int status; /* card status register */ + unsigned int alatch; /* Control register */ + unsigned int terms; /* Terminator state */ + unsigned int dmaarea; /* Pseudo DMA area */ + struct scatterlist sg[NR_SG]; /* Scatter DMA list */ +}; #define CSTATUS_IRQ (1 << 0) #define CSTATUS_DRQ (1 << 1) @@ -128,12 +118,8 @@ } static const expansioncard_ops_t cumanascsi_2_ops = { - cumanascsi_2_irqenable, - cumanascsi_2_irqdisable, - NULL, - NULL, - NULL, - NULL + .irqenable = cumanascsi_2_irqenable, + .irqdisable = cumanascsi_2_irqdisable, }; /* Prototype: void cumanascsi_2_terminator_ctl(host, on_off) @@ -144,7 +130,7 @@ static void cumanascsi_2_terminator_ctl(struct Scsi_Host *host, int on_off) { - CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata; + struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; if (on_off) { info->terms = 1; @@ -164,9 +150,7 @@ static void cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *host = (struct Scsi_Host *)dev_id; - - fas216_intr(host); + fas216_intr(dev_id); } /* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type) @@ -181,36 +165,30 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { - CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata; + struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; int dmach = host->dma_channel; outb(ALATCH_DIS_DMA, info->alatch); if (dmach != NO_DMA && (min_type == fasdma_real_all || SCp->this_residual >= 512)) { - int bufs = SCp->buffers_residual; - int pci_dir, dma_dir, alatch_dir; + int bufs, map_dir, dma_dir, alatch_dir; - if (bufs) - memcpy(info->sg + 1, SCp->buffer + 1, - sizeof(struct scatterlist) * bufs); - info->sg[0].address = SCp->ptr; - info->sg[0].page = NULL; - info->sg[0].length = SCp->this_residual; + bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG); if (direction == DMA_OUT) - pci_dir = PCI_DMA_TODEVICE, + map_dir = PCI_DMA_TODEVICE, dma_dir = DMA_MODE_WRITE, alatch_dir = ALATCH_DMA_OUT; else - pci_dir = PCI_DMA_FROMDEVICE, + map_dir = PCI_DMA_FROMDEVICE, dma_dir = DMA_MODE_READ, alatch_dir = ALATCH_DMA_IN; - pci_map_sg(NULL, info->sg, bufs + 1, pci_dir); + pci_map_sg(NULL, info->sg, bufs, map_dir); disable_dma(dmach); - set_dma_sg(dmach, info->sg, bufs + 1); + set_dma_sg(dmach, info->sg, bufs); outb(alatch_dir, info->alatch); set_dma_mode(dmach, dma_dir); enable_dma(dmach); @@ -238,7 +216,7 @@ cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, int transfer) { - CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata; + struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; unsigned int length; unsigned char *addr; @@ -271,7 +249,7 @@ unsigned int status = inb(info->status); if (status & STATUS_INT) - goto end; + return; if (!(status & STATUS_DRQ)) continue; @@ -287,7 +265,7 @@ unsigned int status = inb(info->status); if (status & STATUS_INT) - goto end; + return; if (!(status & STATUS_DRQ)) continue; @@ -300,8 +278,6 @@ } } } - -end: } /* Prototype: int cumanascsi_2_dma_stop(host, SCpnt) @@ -312,124 +288,13 @@ static void cumanascsi_2_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) { - CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata; + struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; if (host->dma_channel != NO_DMA) { outb(ALATCH_DIS_DMA, info->alatch); disable_dma(host->dma_channel); } } -/* Prototype: int cumanascsi_2_detect(Scsi_Host_Template * tpnt) - * Purpose : initialises Cumana SCSI 2 driver - * Params : tpnt - template for this SCSI adapter - * Returns : >0 if host found, 0 otherwise. - */ -int -cumanascsi_2_detect(Scsi_Host_Template *tpnt) -{ - static const card_ids cumanascsi_2_cids[] = - { CUMANASCSI2_LIST, { 0xffff, 0xffff} }; - int count = 0; - struct Scsi_Host *host; - - tpnt->proc_name = "cumanascs2"; - memset(ecs, 0, sizeof (ecs)); - - ecard_startfind(); - - while (1) { - CumanaScsi2_Info *info; - - ecs[count] = ecard_find(0, cumanascsi_2_cids); - if (!ecs[count]) - break; - - ecard_claim(ecs[count]); - - host = scsi_register(tpnt, sizeof (CumanaScsi2_Info)); - if (!host) { - ecard_release(ecs[count]); - break; - } - - host->io_port = ecard_address(ecs[count], ECARD_MEMC, 0); - host->irq = ecs[count]->irq; - host->dma_channel = ecs[count]->dma; - info = (CumanaScsi2_Info *)host->hostdata; - - info->terms = term[count] ? 1 : 0; - cumanascsi_2_terminator_ctl(host, info->terms); - - info->info.scsi.io_port = host->io_port + CUMANASCSI2_FAS216_OFFSET; - info->info.scsi.io_shift = CUMANASCSI2_FAS216_SHIFT; - info->info.scsi.irq = host->irq; - info->info.ifcfg.clockrate = CUMANASCSI2_XTALFREQ; - info->info.ifcfg.select_timeout = 255; - info->info.ifcfg.asyncperiod = CUMANASCSI2_ASYNC_PERIOD; - info->info.ifcfg.sync_max_depth = CUMANASCSI2_SYNC_DEPTH; - info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; - info->info.ifcfg.disconnect_ok = 1; - info->info.ifcfg.wide_max_size = 0; - info->info.dma.setup = cumanascsi_2_dma_setup; - info->info.dma.pseudo = cumanascsi_2_dma_pseudo; - info->info.dma.stop = cumanascsi_2_dma_stop; - info->dmaarea = host->io_port + CUMANASCSI2_PSEUDODMA; - info->status = host->io_port + CUMANASCSI2_STATUS; - info->alatch = host->io_port + CUMANASCSI2_ALATCH; - - ecs[count]->irqaddr = (unsigned char *)ioaddr(info->status); - ecs[count]->irqmask = STATUS_INT; - ecs[count]->irq_data = (void *)info->alatch; - ecs[count]->ops = (expansioncard_ops_t *)&cumanascsi_2_ops; - - request_region(host->io_port + CUMANASCSI2_FAS216_OFFSET, - 16 << CUMANASCSI2_FAS216_SHIFT, "cumanascsi2-fas"); - - if (host->irq != NO_IRQ && - request_irq(host->irq, cumanascsi_2_intr, - SA_INTERRUPT, "cumanascsi2", host)) { - printk("scsi%d: IRQ%d not free, interrupts disabled\n", - host->host_no, host->irq); - host->irq = NO_IRQ; - info->info.scsi.irq = NO_IRQ; - } - - if (host->dma_channel != NO_DMA && - request_dma(host->dma_channel, "cumanascsi2")) { - printk("scsi%d: DMA%d not free, DMA disabled\n", - host->host_no, host->dma_channel); - host->dma_channel = NO_DMA; - } - - fas216_init(host); - ++count; - } - return count; -} - -/* Prototype: int cumanascsi_2_release(struct Scsi_Host * host) - * Purpose : releases all resources used by this adapter - * Params : host - driver host structure to return info for. - */ -int cumanascsi_2_release(struct Scsi_Host *host) -{ - int i; - - fas216_release(host); - - if (host->irq != NO_IRQ) - free_irq(host->irq, host); - if (host->dma_channel != NO_DMA) - free_dma(host->dma_channel); - release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET, - 16 << CUMANASCSI2_FAS216_SHIFT); - - for (i = 0; i < MAX_ECARDS; i++) - if (ecs[i] && host->io_port == ecard_address (ecs[i], ECARD_MEMC, 0)) - ecard_release (ecs[i]); - return 0; -} - /* Prototype: const char *cumanascsi_2_info(struct Scsi_Host * host) * Purpose : returns a descriptive string about this interface, * Params : host - driver host structure to return info for. @@ -437,15 +302,12 @@ */ const char *cumanascsi_2_info(struct Scsi_Host *host) { - CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata; - static char string[100], *p; + struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%d.%d.%d terminators o%s", - VER_MAJOR, VER_MINOR, VER_PATCH, - info->terms ? "n" : "ff"); + sprintf(string, "%s (%s) in slot %d v%s terminators o%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION, info->terms ? "n" : "ff"); return string; } @@ -498,28 +360,21 @@ int length, int host_no, int inout) { int pos, begin; - struct Scsi_Host *host = scsi_hostlist; - CumanaScsi2_Info *info; + struct Scsi_Host *host; + struct cumanascsi2_info *info; Scsi_Device *scd; - while (host) { - if (host->host_no == host_no) - break; - host = host->next; - } + host = scsi_host_hn_get(host_no); if (!host) return 0; if (inout == 1) return cumanascsi_2_set_proc_info(host, buffer, length); - info = (CumanaScsi2_Info *)host->hostdata; + info = (struct cumanascsi2_info *)host->hostdata; begin = 0; - pos = sprintf(buffer, - "Cumana SCSI II driver version %d.%d.%d\n", - VER_MAJOR, VER_MINOR, VER_PATCH); - + pos = sprintf(buffer, "Cumana SCSI II driver v%s\n", VERSION); pos += fas216_print_host(&info->info, buffer + pos); pos += sprintf(buffer + pos, "Term : o%s\n", info->terms ? "n" : "ff"); @@ -556,28 +411,194 @@ return pos; } +static int cumanascsi2_probe(struct expansion_card *ec); + +/* Prototype: int cumanascsi_2_detect(Scsi_Host_Template * tpnt) + * Purpose : initialises Cumana SCSI 2 driver + * Params : tpnt - template for this SCSI adapter + * Returns : >0 if host found, 0 otherwise. + */ +static int +cumanascsi_2_detect(Scsi_Host_Template *tpnt) +{ + static const card_ids cumanascsi_2_cids[] = + { CUMANASCSI2_LIST, { 0xffff, 0xffff} }; + int count = 0, ret; + + ecard_startfind(); + + while (1) { + struct expansion_card *ec; + + ec = ecard_find(0, cumanascsi_2_cids); + if (!ec) + break; + + ecard_claim(ec); + ret = cumanascsi2_probe(ec); + if (ret) { + ecard_release(ec); + break; + } + + ++count; + } + return count; +} + +static void cumanascsi2_remove(struct Scsi_Host *host); + +/* Prototype: int cumanascsi_2_release(struct Scsi_Host * host) + * Purpose : releases all resources used by this adapter + * Params : host - driver host structure to return info for. + */ +static int cumanascsi_2_release(struct Scsi_Host *host) +{ + cumanascsi2_remove(host); + return 0; +} + static Scsi_Host_Template cumanascsi2_template = { - module: THIS_MODULE, - proc_info: cumanascsi_2_proc_info, - name: "Cumana SCSI II", - detect: cumanascsi_2_detect, - release: cumanascsi_2_release, - info: cumanascsi_2_info, - bios_param: scsicam_bios_param, - can_queue: 1, - this_id: 7, - sg_tablesize: SG_ALL, - cmd_per_lun: 1, - use_clustering: DISABLE_CLUSTERING, - command: fas216_command, - queuecommand: fas216_queue_command, - eh_host_reset_handler: fas216_eh_host_reset, - eh_bus_reset_handler: fas216_eh_bus_reset, - eh_device_reset_handler: fas216_eh_device_reset, - eh_abort_handler: fas216_eh_abort, - use_new_eh_code: 1 + .module = THIS_MODULE, + .proc_info = cumanascsi_2_proc_info, + .name = "Cumana SCSI II", + .detect = cumanascsi_2_detect, + .release = cumanascsi_2_release, + .info = cumanascsi_2_info, + .bios_param = scsicam_bios_param, + .command = fas216_command, + .queuecommand = fas216_queue_command, + .eh_host_reset_handler = fas216_eh_host_reset, + .eh_bus_reset_handler = fas216_eh_bus_reset, + .eh_device_reset_handler = fas216_eh_device_reset, + .eh_abort_handler = fas216_eh_abort, + .use_new_eh_code = 1, + + .can_queue = 1, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = DISABLE_CLUSTERING, + .proc_name = "cumanascsi2", }; +static int +cumanascsi2_probe(struct expansion_card *ec) +{ + struct Scsi_Host *host; + struct cumanascsi2_info *info; + unsigned long base; + int ret; + + base = ecard_address(ec, ECARD_MEMC, 0); + + if (request_region(base + CUMANASCSI2_FAS216_OFFSET, + 16 << CUMANASCSI2_FAS216_SHIFT, "cumanascsi2-fas")) { + ret = -EBUSY; + goto out; + } + + host = scsi_register(&cumanascsi2_template, + sizeof(struct cumanascsi2_info)); + if (!host) { + ret = -ENOMEM; + goto out_region; + } + + host->io_port = base; + host->irq = ec->irq; + host->dma_channel = ec->dma; + + info = (struct cumanascsi2_info *)host->hostdata; + info->ec = ec; + info->dmaarea = base + CUMANASCSI2_PSEUDODMA; + info->status = base + CUMANASCSI2_STATUS; + info->alatch = base + CUMANASCSI2_ALATCH; + + ec->irqaddr = (unsigned char *)ioaddr(info->status); + ec->irqmask = STATUS_INT; + ec->irq_data = (void *)base + CUMANASCSI2_ALATCH; + ec->ops = (expansioncard_ops_t *)&cumanascsi_2_ops; + + cumanascsi_2_terminator_ctl(host, term[ec->slot_no]); + + info->info.scsi.io_port = base + CUMANASCSI2_FAS216_OFFSET; + info->info.scsi.io_shift = CUMANASCSI2_FAS216_SHIFT; + info->info.scsi.irq = host->irq; + info->info.ifcfg.clockrate = 40; /* MHz */ + info->info.ifcfg.select_timeout = 255; + info->info.ifcfg.asyncperiod = 200; /* ns */ + info->info.ifcfg.sync_max_depth = 7; + info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; + info->info.ifcfg.disconnect_ok = 1; + info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = 0; + info->info.dma.setup = cumanascsi_2_dma_setup; + info->info.dma.pseudo = cumanascsi_2_dma_pseudo; + info->info.dma.stop = cumanascsi_2_dma_stop; + + ret = fas216_init(host); + if (ret) + goto out_free; + + ret = request_irq(host->irq, cumanascsi_2_intr, + SA_INTERRUPT, "cumanascsi2", &info->info); + if (ret) { + printk("scsi%d: IRQ%d not free: %d\n", + host->host_no, host->irq, ret); + goto out_release; + } + + if (host->dma_channel != NO_DMA) { + if (request_dma(host->dma_channel, "cumanascsi2")) { + printk("scsi%d: DMA%d not free, using PIO\n", + host->host_no, host->dma_channel); + host->dma_channel = NO_DMA; + } else { + set_dma_speed(host->dma_channel, 180); + info->info.ifcfg.capabilities |= FASCAP_DMA; + } + } + + ret = fas216_add(host); + if (ret == 0) + goto out; + + if (host->dma_channel != NO_DMA) + free_dma(host->dma_channel); + free_irq(host->irq, host); + + out_release: + fas216_release(host); + + out_free: + scsi_unregister(host); + + out_region: + release_region(base + CUMANASCSI2_FAS216_OFFSET, + 16 << CUMANASCSI2_FAS216_SHIFT); + + out: + return ret; +} + +static void cumanascsi2_remove(struct Scsi_Host *host) +{ + struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; + + fas216_remove(host); + + if (host->dma_channel != NO_DMA) + free_dma(host->dma_channel); + free_irq(host->irq, host); + + release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET, + 16 << CUMANASCSI2_FAS216_SHIFT); + + fas216_release(host); + ecard_release(info->ec); +} + static int __init cumanascsi2_init(void) { scsi_register_module(MODULE_SCSI_HA, &cumanascsi2_template); diff -urN linux-2.4.21/drivers/acorn/scsi/eesox.c linux-2.4.22/drivers/acorn/scsi/eesox.c --- linux-2.4.21/drivers/acorn/scsi/eesox.c 2001-11-04 09:31:57.000000000 -0800 +++ linux-2.4.22/drivers/acorn/scsi/eesox.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/eesox.c * - * Copyright (C) 1997-2000 Russell King + * Copyright (C) 1997-2003 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include #include @@ -44,14 +42,10 @@ #include "../../scsi/sd.h" #include "../../scsi/hosts.h" #include "fas216.h" +#include "scsi.h" #include -/* Configuration */ -#define EESOX_XTALFREQ 40 -#define EESOX_ASYNC_PERIOD 200 -#define EESOX_SYNC_DEPTH 7 - /* * List of devices that the driver will recognise */ @@ -60,7 +54,7 @@ #define EESOX_FAS216_OFFSET 0xc00 #define EESOX_FAS216_SHIFT 3 -#define EESOX_STATUS 0xa00 +#define EESOX_DMASTAT 0xa00 #define EESOX_STAT_INTR 0x01 #define EESOX_STAT_DMA 0x02 @@ -69,16 +63,12 @@ #define EESOX_TERM_ENABLE 0x02 #define EESOX_RESET 0x01 -#define EESOX_DMA_OFFSET 0xe00 +#define EESOX_DMADATA 0xe00 /* * Version */ -#define VER_MAJOR 0 -#define VER_MINOR 0 -#define VER_PATCH 3 - -static struct expansion_card *ecs[MAX_ECARDS]; +#define VERSION "1.10 (22/01/2003 2.4.19-rmk5)" /* * Use term=0,1,0,0,0 to turn terminators on/off @@ -87,20 +77,15 @@ #define NR_SG 256 -struct control { - unsigned int io_port; - unsigned int control; +struct eesoxscsi_info { + FAS216_Info info; + struct expansion_card *ec; + + unsigned int ctl_port; + unsigned int control; + struct scatterlist sg[NR_SG]; /* Scatter DMA list */ }; -typedef struct { - FAS216_Info info; - - struct control control; - - unsigned int dmaarea; /* Pseudo DMA area */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ -} EESOXScsi_Info; - /* Prototype: void eesoxscsi_irqenable(ec, irqnr) * Purpose : Enable interrupts on EESOX SCSI card * Params : ec - expansion card structure @@ -109,11 +94,11 @@ static void eesoxscsi_irqenable(struct expansion_card *ec, int irqnr) { - struct control *control = (struct control *)ec->irq_data; + struct eesoxscsi_info *info = (struct eesoxscsi_info *)ec->irq_data; - control->control |= EESOX_INTR_ENABLE; + info->control |= EESOX_INTR_ENABLE; - outb(control->control, control->io_port); + outb(info->control, info->ctl_port); } /* Prototype: void eesoxscsi_irqdisable(ec, irqnr) @@ -124,20 +109,16 @@ static void eesoxscsi_irqdisable(struct expansion_card *ec, int irqnr) { - struct control *control = (struct control *)ec->irq_data; + struct eesoxscsi_info *info = (struct eesoxscsi_info *)ec->irq_data; - control->control &= ~EESOX_INTR_ENABLE; + info->control &= ~EESOX_INTR_ENABLE; - outb(control->control, control->io_port); + outb(info->control, info->ctl_port); } static const expansioncard_ops_t eesoxscsi_ops = { - eesoxscsi_irqenable, - eesoxscsi_irqdisable, - NULL, - NULL, - NULL, - NULL + .irqenable = eesoxscsi_irqenable, + .irqdisable = eesoxscsi_irqdisable, }; /* Prototype: void eesoxscsi_terminator_ctl(*host, on_off) @@ -148,17 +129,17 @@ static void eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off) { - EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata; + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; unsigned long flags; save_flags_cli(flags); if (on_off) - info->control.control |= EESOX_TERM_ENABLE; + info->control |= EESOX_TERM_ENABLE; else - info->control.control &= ~EESOX_TERM_ENABLE; - restore_flags(flags); + info->control &= ~EESOX_TERM_ENABLE; - outb(info->control.control, info->control.io_port); + outb(info->control, info->ctl_port); + restore_flags(flags); } /* Prototype: void eesoxscsi_intr(irq, *dev_id, *regs) @@ -170,9 +151,7 @@ static void eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *host = (struct Scsi_Host *)dev_id; - - fas216_intr(host); + fas216_intr(dev_id); } /* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type) @@ -187,32 +166,26 @@ eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { - EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata; + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; int dmach = host->dma_channel; if (dmach != NO_DMA && (min_type == fasdma_real_all || SCp->this_residual >= 512)) { - int bufs = SCp->buffers_residual; - int pci_dir, dma_dir; + int bufs, map_dir, dma_dir; - if (bufs) - memcpy(info->sg + 1, SCp->buffer + 1, - sizeof(struct scatterlist) * bufs); - info->sg[0].address = SCp->ptr; - info->sg[0].page = NULL; - info->sg[0].length = SCp->this_residual; + bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG); if (direction == DMA_OUT) - pci_dir = PCI_DMA_TODEVICE, + map_dir = PCI_DMA_TODEVICE, dma_dir = DMA_MODE_WRITE; else - pci_dir = PCI_DMA_FROMDEVICE, + map_dir = PCI_DMA_FROMDEVICE, dma_dir = DMA_MODE_READ; - pci_map_sg(NULL, info->sg, bufs + 1, pci_dir); + pci_map_sg(NULL, info->sg, bufs, map_dir); disable_dma(dmach); - set_dma_sg(dmach, info->sg, bufs + 1); + set_dma_sg(dmach, info->sg, bufs); set_dma_mode(dmach, dma_dir); enable_dma(dmach); return fasdma_real_all; @@ -225,215 +198,174 @@ return fasdma_pseudo; } -static void -eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, - fasdmadir_t dir, int transfer_size) +static void eesoxscsi_buffer_in(void *buf, int length, unsigned long base) { - EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata; - unsigned int status; - unsigned int length = SCp->this_residual; - union { - unsigned char *c; - unsigned short *s; - unsigned long *l; - } buffer; + const unsigned long reg_fas = base + EESOX_FAS216_OFFSET; + const unsigned long reg_dmastat = base + EESOX_DMASTAT; + const unsigned long reg_dmadata = base + EESOX_DMADATA; + + do { + unsigned int status; + + /* + * Interrupt request? + */ + status = inb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT)); + if (status & STAT_INT) + break; - buffer.c = SCp->ptr; + /* + * DMA request active? + */ + status = inb(reg_dmastat); + if (!(status & EESOX_STAT_DMA)) + continue; + + /* + * Get number of bytes in FIFO + */ + status = inb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF; + if (status > 16) + status = 16; + if (status > length) + status = length; + + /* + * Align buffer. + */ + if (((u32)buf) & 2 && status >= 2) { + *((u16 *)buf)++ = inw(reg_dmadata); + status -= 2; + length -= 2; + } - status = inb(host->io_port + EESOX_STATUS); - if (dir == DMA_IN) { - while (length > 8) { - if (status & EESOX_STAT_DMA) { - unsigned long l1, l2; - - l1 = inw(info->dmaarea); - l1 |= inw(info->dmaarea) << 16; - l2 = inw(info->dmaarea); - l2 |= inw(info->dmaarea) << 16; - *buffer.l++ = l1; - *buffer.l++ = l2; - length -= 8; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 1) { - if (status & EESOX_STAT_DMA) { - *buffer.s++ = inw(info->dmaarea); - length -= 2; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 0) { - if (status & EESOX_STAT_DMA) { - *buffer.c++ = inw(info->dmaarea); - length -= 1; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); + if (status >= 8) { + unsigned long l1, l2; + + l1 = inw(reg_dmadata); + l1 |= inw(reg_dmadata) << 16; + l2 = inw(reg_dmadata); + l2 |= inw(reg_dmadata) << 16; + *((u32 *)buf)++ = l1; + *((u32 *)buf)++ = l2; + length -= 8; + continue; } - } else { - while (length > 8) { - if (status & EESOX_STAT_DMA) { - unsigned long l1, l2; - - l1 = *buffer.l++; - l2 = *buffer.l++; - - outw(l1, info->dmaarea); - outw(l1 >> 16, info->dmaarea); - outw(l2, info->dmaarea); - outw(l2 >> 16, info->dmaarea); - length -= 8; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 1) { - if (status & EESOX_STAT_DMA) { - outw(*buffer.s++, info->dmaarea); - length -= 2; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 0) { - if (status & EESOX_STAT_DMA) { - outw(*buffer.c++, info->dmaarea); - length -= 1; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); + + if (status >= 4) { + unsigned long l1; + + l1 = inw(reg_dmadata); + l1 |= inw(reg_dmadata) << 16; + *((u32 *)buf)++ = l1; + length -= 4; + continue; } - } -end: -} -/* Prototype: int eesoxscsi_dma_stop(host, SCpnt) - * Purpose : stops DMA/PIO - * Params : host - host - * SCpnt - command - */ -static void -eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) -{ - if (host->dma_channel != NO_DMA) - disable_dma(host->dma_channel); + if (status >= 2) { + *((u16 *)buf)++ = inw(reg_dmadata); + length -= 2; + } + } while (length); } -/* Prototype: int eesoxscsi_detect(Scsi_Host_Template * tpnt) - * Purpose : initialises EESOX SCSI driver - * Params : tpnt - template for this SCSI adapter - * Returns : >0 if host found, 0 otherwise. - */ -int -eesoxscsi_detect(Scsi_Host_Template *tpnt) +static void eesoxscsi_buffer_out(void *buf, int length, unsigned long base) { - static const card_ids eesoxscsi_cids[] = - { EESOXSCSI_LIST, { 0xffff, 0xffff} }; - int count = 0; - struct Scsi_Host *host; - - tpnt->proc_name = "eesox"; - memset(ecs, 0, sizeof (ecs)); - - ecard_startfind(); + const unsigned long reg_fas = base + EESOX_FAS216_OFFSET; + const unsigned long reg_dmastat = base + EESOX_DMASTAT; + const unsigned long reg_dmadata = base + EESOX_DMADATA; - while(1) { - EESOXScsi_Info *info; + do { + unsigned int status; - ecs[count] = ecard_find(0, eesoxscsi_cids); - if (!ecs[count]) + /* + * Interrupt request? + */ + status = inb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT)); + if (status & STAT_INT) break; - ecard_claim(ecs[count]); + /* + * DMA request active? + */ + status = inb(reg_dmastat); + if (!(status & EESOX_STAT_DMA)) + continue; + + /* + * Get number of bytes in FIFO + */ + status = inb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF; + if (status > 16) + status = 16; + status = 16 - status; + if (status > length) + status = length; + + /* + * Align buffer. + */ + if (((u32)buf) & 2 && status >= 2) { + outw(*((u16 *)buf)++, reg_dmadata); + status -= 2; + length -= 2; + } - host = scsi_register(tpnt, sizeof (EESOXScsi_Info)); - if (!host) { - ecard_release(ecs[count]); - break; + if (status >= 8) { + unsigned long l1, l2; + + l1 = *((u32 *)buf)++; + l2 = *((u32 *)buf)++; + + outw(l1, reg_dmadata); + outw(l1 >> 16, reg_dmadata); + outw(l2, reg_dmadata); + outw(l2 >> 16, reg_dmadata); + status -= 8; + length -= 8; + continue; } - host->io_port = ecard_address(ecs[count], ECARD_IOC, ECARD_FAST); - host->irq = ecs[count]->irq; - host->dma_channel = ecs[count]->dma; - info = (EESOXScsi_Info *)host->hostdata; - - info->control.io_port = host->io_port + EESOX_CONTROL; - info->control.control = term[count] ? EESOX_TERM_ENABLE : 0; - outb(info->control.control, info->control.io_port); - - ecs[count]->irqaddr = (unsigned char *) - ioaddr(host->io_port + EESOX_STATUS); - ecs[count]->irqmask = EESOX_STAT_INTR; - ecs[count]->irq_data = &info->control; - ecs[count]->ops = (expansioncard_ops_t *)&eesoxscsi_ops; - - info->info.scsi.io_port = host->io_port + EESOX_FAS216_OFFSET; - info->info.scsi.io_shift = EESOX_FAS216_SHIFT; - info->info.scsi.irq = host->irq; - info->info.ifcfg.clockrate = EESOX_XTALFREQ; - info->info.ifcfg.select_timeout = 255; - info->info.ifcfg.asyncperiod = EESOX_ASYNC_PERIOD; - info->info.ifcfg.sync_max_depth = EESOX_SYNC_DEPTH; - info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; - info->info.ifcfg.disconnect_ok = 1; - info->info.ifcfg.wide_max_size = 0; - info->info.dma.setup = eesoxscsi_dma_setup; - info->info.dma.pseudo = eesoxscsi_dma_pseudo; - info->info.dma.stop = eesoxscsi_dma_stop; - info->dmaarea = host->io_port + EESOX_DMA_OFFSET; - - request_region(host->io_port + EESOX_FAS216_OFFSET, - 16 << EESOX_FAS216_SHIFT, "eesox2-fas"); - - if (host->irq != NO_IRQ && - request_irq(host->irq, eesoxscsi_intr, - SA_INTERRUPT, "eesox", host)) { - printk("scsi%d: IRQ%d not free, interrupts disabled\n", - host->host_no, host->irq); - host->irq = NO_IRQ; + if (status >= 4) { + unsigned long l1; + + l1 = *((u32 *)buf)++; + outw(l1, reg_dmadata); + outw(l1 >> 16, reg_dmadata); + status -= 4; + length -= 4; + continue; } - if (host->dma_channel != NO_DMA && - request_dma(host->dma_channel, "eesox")) { - printk("scsi%d: DMA%d not free, DMA disabled\n", - host->host_no, host->dma_channel); - host->dma_channel = NO_DMA; + if (status >= 2) { + outw(*((u16 *)buf)++, reg_dmadata); + length -= 2; } + } while (length); +} - fas216_init(host); - ++count; +static void +eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, + fasdmadir_t dir, int transfer_size) +{ + unsigned int base = host->io_port; + if (dir == DMA_IN) { + eesoxscsi_buffer_in(SCp->ptr, SCp->this_residual, base); + } else { + eesoxscsi_buffer_out(SCp->ptr, SCp->this_residual, base); } - return count; } -/* Prototype: int eesoxscsi_release(struct Scsi_Host * host) - * Purpose : releases all resources used by this adapter - * Params : host - driver host structure to return info for. +/* Prototype: int eesoxscsi_dma_stop(host, SCpnt) + * Purpose : stops DMA/PIO + * Params : host - host + * SCpnt - command */ -int eesoxscsi_release(struct Scsi_Host *host) +static void +eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) { - int i; - - fas216_release(host); - - if (host->irq != NO_IRQ) - free_irq(host->irq, host); if (host->dma_channel != NO_DMA) - free_dma(host->dma_channel); - release_region(host->io_port + EESOX_FAS216_OFFSET, 16 << EESOX_FAS216_SHIFT); - - for (i = 0; i < MAX_ECARDS; i++) - if (ecs[i] && - host->io_port == ecard_address(ecs[i], ECARD_IOC, ECARD_FAST)) - ecard_release(ecs[i]); - return 0; + disable_dma(host->dma_channel); } /* Prototype: const char *eesoxscsi_info(struct Scsi_Host * host) @@ -443,15 +375,12 @@ */ const char *eesoxscsi_info(struct Scsi_Host *host) { - EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata; - static char string[100], *p; + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%d.%d.%d terminators o%s", - VER_MAJOR, VER_MINOR, VER_PATCH, - info->control.control & EESOX_TERM_ENABLE ? "n" : "ff"); + sprintf(string, "%s (%s) in slot %d v%s terminators o%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION, info->control & EESOX_TERM_ENABLE ? "n" : "ff"); return string; } @@ -504,43 +433,37 @@ int length, int host_no, int inout) { int pos, begin; - struct Scsi_Host *host = scsi_hostlist; - EESOXScsi_Info *info; + struct Scsi_Host *host; + struct eesoxscsi_info *info; Scsi_Device *scd; - while (host) { - if (host->host_no == host_no) - break; - host = host->next; - } + host = scsi_host_hn_get(host_no); if (!host) return 0; if (inout == 1) return eesoxscsi_set_proc_info(host, buffer, length); - info = (EESOXScsi_Info *)host->hostdata; + info = (struct eesoxscsi_info *)host->hostdata; begin = 0; - pos = sprintf(buffer, - "EESOX SCSI driver version %d.%d.%d\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + pos = sprintf(buffer, "EESOX SCSI driver v%s\n", VERSION); pos += fas216_print_host(&info->info, buffer + pos); pos += sprintf(buffer + pos, "Term : o%s\n", - info->control.control & EESOX_TERM_ENABLE ? "n" : "ff"); + info->control & EESOX_TERM_ENABLE ? "n" : "ff"); pos += fas216_print_stats(&info->info, buffer + pos); - pos += sprintf (buffer+pos, "\nAttached devices:\n"); + pos += sprintf(buffer+pos, "\nAttached devices:\n"); for (scd = host->host_queue; scd; scd = scd->next) { int len; - proc_print_scsidevice (scd, buffer, &len, pos); + proc_print_scsidevice(scd, buffer, &len, pos); pos += len; - pos += sprintf (buffer+pos, "Extensions: "); + pos += sprintf(buffer+pos, "Extensions: "); if (scd->tagged_supported) - pos += sprintf (buffer+pos, "TAG %sabled [%d] ", + pos += sprintf(buffer+pos, "TAG %sabled [%d] ", scd->tagged_queue ? "en" : "dis", scd->current_tag); pos += sprintf (buffer+pos, "\n"); @@ -558,28 +481,188 @@ return pos; } +static int eesoxscsi_probe(struct expansion_card *ec); + +/* Prototype: int eesoxscsi_detect(Scsi_Host_Template * tpnt) + * Purpose : initialises EESOX SCSI driver + * Params : tpnt - template for this SCSI adapter + * Returns : >0 if host found, 0 otherwise. + */ +static int eesoxscsi_detect(Scsi_Host_Template *tpnt) +{ + static const card_ids eesoxscsi_cids[] = + { EESOXSCSI_LIST, { 0xffff, 0xffff} }; + struct expansion_card *ec; + int count = 0, ret; + + ecard_startfind(); + + while(1) { + ec = ecard_find(0, eesoxscsi_cids); + if (!ec) + break; + + ecard_claim(ec); + + ret = eesoxscsi_probe(ec); + if (ret) { + ecard_release(ec); + break; + } + ++count; + } + return count; +} + +static void eesoxscsi_remove(struct Scsi_Host *host); + +/* Prototype: int eesoxscsi_release(struct Scsi_Host * host) + * Purpose : releases all resources used by this adapter + * Params : host - driver host structure to return info for. + */ +static int eesoxscsi_release(struct Scsi_Host *host) +{ + eesoxscsi_remove(host); + return 0; +} + static Scsi_Host_Template eesox_template = { - module: THIS_MODULE, - proc_info: eesoxscsi_proc_info, - name: "EESOX SCSI", - detect: eesoxscsi_detect, - release: eesoxscsi_release, - info: eesoxscsi_info, - bios_param: scsicam_bios_param, - can_queue: 1, - this_id: 7, - sg_tablesize: SG_ALL, - cmd_per_lun: 1, - use_clustering: DISABLE_CLUSTERING, - command: fas216_command, - queuecommand: fas216_queue_command, - eh_host_reset_handler: fas216_eh_host_reset, - eh_bus_reset_handler: fas216_eh_bus_reset, - eh_device_reset_handler: fas216_eh_device_reset, - eh_abort_handler: fas216_eh_abort, - use_new_eh_code: 1 + .module = THIS_MODULE, + .proc_info = eesoxscsi_proc_info, + .name = "EESOX SCSI", + .detect = eesoxscsi_detect, + .release = eesoxscsi_release, + .info = eesoxscsi_info, + .bios_param = scsicam_bios_param, + .command = fas216_command, + .queuecommand = fas216_queue_command, + .eh_host_reset_handler = fas216_eh_host_reset, + .eh_bus_reset_handler = fas216_eh_bus_reset, + .eh_device_reset_handler = fas216_eh_device_reset, + .eh_abort_handler = fas216_eh_abort, + .use_new_eh_code = 1, + + .can_queue = 1, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = DISABLE_CLUSTERING, + .proc_name = "eesox", }; +static int +eesoxscsi_probe(struct expansion_card *ec) +{ + struct Scsi_Host *host; + struct eesoxscsi_info *info; + unsigned long base; + int ret; + + base = ecard_address(ec, ECARD_IOC, ECARD_FAST); + + if (!request_region(base + EESOX_FAS216_OFFSET, + 16 << EESOX_FAS216_SHIFT, "eesox2-fas")) { + ret = -EBUSY; + goto out; + } + + host = scsi_register(&eesox_template, + sizeof(struct eesoxscsi_info)); + if (!host) { + ret = -ENOMEM; + goto out_region; + } + + host->io_port = base; + host->irq = ec->irq; + host->dma_channel = ec->dma; + + info = (struct eesoxscsi_info *)host->hostdata; + info->ec = ec; + info->ctl_port = base + EESOX_CONTROL; + info->control = term[ec->slot_no] ? EESOX_TERM_ENABLE : 0; + outb(info->control, info->ctl_port); + + ec->irqaddr = (unsigned char *)ioaddr(base + EESOX_DMASTAT); + ec->irqmask = EESOX_STAT_INTR; + ec->irq_data = info; + ec->ops = (expansioncard_ops_t *)&eesoxscsi_ops; + + info->info.scsi.io_port = base + EESOX_FAS216_OFFSET; + info->info.scsi.io_shift = EESOX_FAS216_SHIFT; + info->info.scsi.irq = host->irq; + info->info.ifcfg.clockrate = 40; /* MHz */ + info->info.ifcfg.select_timeout = 255; + info->info.ifcfg.asyncperiod = 200; /* ns */ + info->info.ifcfg.sync_max_depth = 7; + info->info.ifcfg.cntl3 = CNTL3_FASTSCSI | CNTL3_FASTCLK; + info->info.ifcfg.disconnect_ok = 1; + info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = FASCAP_PSEUDODMA; + info->info.dma.setup = eesoxscsi_dma_setup; + info->info.dma.pseudo = eesoxscsi_dma_pseudo; + info->info.dma.stop = eesoxscsi_dma_stop; + + ret = fas216_init(host); + if (ret) + goto out_free; + + ret = request_irq(host->irq, eesoxscsi_intr, 0, "eesox", &info->info); + if (ret) { + printk("scsi%d: IRQ%d not free: %d\n", + host->host_no, host->irq, ret); + goto out_remove; + } + + if (host->dma_channel != NO_DMA) { + if (request_dma(host->dma_channel, "eesox")) { + printk("scsi%d: DMA%d not free, DMA disabled\n", + host->host_no, host->dma_channel); + host->dma_channel = NO_DMA; + } else { + set_dma_speed(host->dma_channel, 180); + info->info.ifcfg.capabilities |= FASCAP_DMA; + info->info.ifcfg.cntl3 |= CNTL3_BS8; + } + } + + ret = fas216_add(host); + if (ret == 0) + goto out; + + if (host->dma_channel != NO_DMA) + free_dma(host->dma_channel); + free_irq(host->irq, host); + + out_remove: + fas216_remove(host); + + out_free: + scsi_unregister(host); + + out_region: + release_region(base + EESOX_FAS216_OFFSET, 16 << EESOX_FAS216_SHIFT); + + out: + return ret; +} + +static void eesoxscsi_remove(struct Scsi_Host *host) +{ + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; + + fas216_remove(host); + + if (host->dma_channel != NO_DMA) + free_dma(host->dma_channel); + free_irq(host->irq, host); + + release_region(host->io_port + EESOX_FAS216_OFFSET, 16 << EESOX_FAS216_SHIFT); + + fas216_release(host); + ecard_release(info->ec); +} + static int __init eesox_init(void) { scsi_register_module(MODULE_SCSI_HA, &eesox_template); diff -urN linux-2.4.21/drivers/acorn/scsi/fas216.c linux-2.4.22/drivers/acorn/scsi/fas216.c --- linux-2.4.21/drivers/acorn/scsi/fas216.c 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/drivers/acorn/scsi/fas216.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* - * linux/arch/arm/drivers/scsi/fas216.c + * linux/drivers/acorn/scsi/fas216.c * - * Copyright (C) 1997-2000 Russell King + * Copyright (C) 1997-2003 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -10,7 +10,7 @@ * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and * other sources, including: * the AMD Am53CF94 data sheet - * the AMD Am53C94 data sheet + * the AMD Am53C94 data sheet * * This is a generic driver. To use it, have a look at cumana_2.c. You * should define your own structure that overlays FAS216_Info, eg: @@ -33,9 +33,6 @@ * 02-04-2000 RMK Converted to use the new error handling, and * automatically request sense data upon check * condition status from targets. - * - * Todo: - * - allow individual devices to enable sync xfers. */ #include #include @@ -44,25 +41,20 @@ #include #include #include -#include -#include #include +#include #include +#include #include #include #include #include -#define FAS216_C - #include "../../scsi/scsi.h" #include "../../scsi/hosts.h" #include "fas216.h" - -#define VER_MAJOR 0 -#define VER_MINOR 0 -#define VER_PATCH 5 +#include "scsi.h" /* NOTE: SCSI2 Synchronous transfers *require* DMA according to * the data sheet. This restriction is crazy, especially when @@ -88,35 +80,68 @@ * I was thinking that this was a good chip until I found this restriction ;( */ #define SCSI2_SYNC -#undef SCSI2_WIDE #undef SCSI2_TAG #undef DEBUG_CONNECT -#undef DEBUG_BUSSERVICE -#undef DEBUG_FUNCTIONDONE #undef DEBUG_MESSAGES #undef CHECK_STRUCTURE -static struct { int stat, ssr, isr, ph; } list[8]; -static int ptr; +#ifndef ABORT_TAG +#define ABORT_TAG 0x0d +#endif + +#define LOG_CONNECT (1 << 0) +#define LOG_BUSSERVICE (1 << 1) +#define LOG_FUNCTIONDONE (1 << 2) +#define LOG_MESSAGES (1 << 3) +#define LOG_BUFFER (1 << 4) +#define LOG_ERROR (1 << 8) + +static int level_mask = LOG_ERROR; + +MODULE_PARM(level_mask, "i"); + +static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg) +{ + unsigned int off = reg << info->scsi.io_shift; + + return inb(info->scsi.io_port + off); +} + +static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val) +{ + unsigned int off = reg << info->scsi.io_shift; + + outb(val, info->scsi.io_port + off); +} static void fas216_dumpstate(FAS216_Info *info) { unsigned char is, stat, inst; - is = inb(REG_IS(info)); - stat = inb(REG_STAT(info)); - inst = inb(REG_INST(info)); + is = fas216_readb(info, REG_IS); + stat = fas216_readb(info, REG_STAT); + inst = fas216_readb(info, REG_INST); printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X" " INST=%02X IS=%02X CFIS=%02X", - inb(REG_CTCL(info)), inb(REG_CTCM(info)), - inb(REG_CMD(info)), stat, inst, is, - inb(REG_CFIS(info))); + fas216_readb(info, REG_CTCL), + fas216_readb(info, REG_CTCM), + fas216_readb(info, REG_CMD), stat, inst, is, + fas216_readb(info, REG_CFIS)); printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n", - inb(REG_CNTL1(info)), inb(REG_CNTL2(info)), - inb(REG_CNTL3(info)), inb(REG_CTCH(info))); + fas216_readb(info, REG_CNTL1), + fas216_readb(info, REG_CNTL2), + fas216_readb(info, REG_CNTL3), + fas216_readb(info, REG_CTCH)); +} + +static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix) +{ + printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s", + prefix, SCp->ptr, SCp->this_residual, SCp->buffer, + SCp->buffers_residual, suffix); } static void fas216_dumpinfo(FAS216_Info *info) @@ -135,13 +160,9 @@ info->scsi.io_port, info->scsi.io_shift, info->scsi.irq, info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2], info->scsi.cfg[3]); - printk(" type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }\n", - info->scsi.type, info->scsi.phase, - info->scsi.reconnected.target, - info->scsi.reconnected.lun, info->scsi.reconnected.tag); - printk(" SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n", - info->scsi.SCp.ptr, info->scsi.SCp.this_residual, - info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual); + printk(" type=%p phase=%X\n", + info->scsi.type, info->scsi.phase); + print_SCp(&info->scsi.SCp, " SCp={ ", " }\n"); printk(" msgs async_stp=%X disconnectable=%d aborting=%d }\n", info->scsi.async_stp, info->scsi.disconnectable, info->scsi.aborting); @@ -155,7 +176,7 @@ info->ifcfg.clockrate, info->ifcfg.select_timeout, info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth); for (i = 0; i < 8; i++) { - printk(" busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n", + printk(" busyluns[%d]=%02x dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n", i, info->busyluns[i], i, info->device[i].disconnect_ok, info->device[i].stp, info->device[i].sof, info->device[i].sync_state); @@ -203,21 +224,24 @@ static const char *fas216_drv_phase(FAS216_Info *info) { - switch (info->scsi.phase) { - case PHASE_IDLE: return "idle"; - case PHASE_SELECTION: return "selection"; - case PHASE_COMMAND: return "command"; - case PHASE_RECONNECTED: return "reconnected"; - case PHASE_DATAOUT: return "data out"; - case PHASE_DATAIN: return "data in"; - case PHASE_MSGIN: return "message in"; - case PHASE_MSGIN_DISCONNECT: return "disconnect"; - case PHASE_MSGOUT_EXPECT: return "expect message out"; - case PHASE_MSGOUT: return "message out"; - case PHASE_STATUS: return "status"; - case PHASE_DONE: return "done"; - default: return "???"; - } + static const char *phases[] = { + [PHASE_IDLE] = "idle", + [PHASE_SELECTION] = "selection", + [PHASE_COMMAND] = "command", + [PHASE_DATAOUT] = "data out", + [PHASE_DATAIN] = "data in", + [PHASE_MSGIN] = "message in", + [PHASE_MSGIN_DISCONNECT]= "disconnect", + [PHASE_MSGOUT_EXPECT] = "expect message out", + [PHASE_MSGOUT] = "message out", + [PHASE_STATUS] = "status", + [PHASE_DONE] = "done", + }; + + if (info->scsi.phase < ARRAY_SIZE(phases) && + phases[info->scsi.phase]) + return phases[info->scsi.phase]; + return "???"; } static char fas216_target(FAS216_Info *info) @@ -228,56 +252,128 @@ return 'H'; } +static void +fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap) +{ + static char buf[1024]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + printk("scsi%d.%c: %s", info->host->host_no, target, buf); +} + +static void +fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...) +{ + va_list args; + + if (level != 0 && !(level & level_mask)) + return; + + va_start(args, fmt); + fas216_do_log(info, '0' + SCpnt->target, fmt, args); + va_end(args); + + printk("CDB: "); + print_command(SCpnt->cmnd); +} + +static void +fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...) +{ + va_list args; + + if (level != 0 && !(level & level_mask)) + return; + + if (target < 0) + target = 'H'; + else + target += '0'; + + va_start(args, fmt); + fas216_do_log(info, target, fmt, args); + va_end(args); + + printk("\n"); +} + +static void fas216_log(FAS216_Info *info, int level, char *fmt, ...) +{ + va_list args; + + if (level != 0 && !(level & level_mask)) + return; + + va_start(args, fmt); + fas216_do_log(info, fas216_target(info), fmt, args); + va_end(args); + + printk("\n"); +} + +#define PH_SIZE 32 + +static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE]; +static int ph_ptr; + static void add_debug_list(int stat, int ssr, int isr, int ph) { - list[ptr].stat = stat; - list[ptr].ssr = ssr; - list[ptr].isr = isr; - list[ptr].ph = ph; + ph_list[ph_ptr].stat = stat; + ph_list[ph_ptr].ssr = ssr; + ph_list[ph_ptr].isr = isr; + ph_list[ph_ptr].ph = ph; + + ph_ptr = (ph_ptr + 1) & (PH_SIZE-1); +} + +static struct { int command; void *from; } cmd_list[8]; +static int cmd_ptr; + +static void fas216_cmd(FAS216_Info *info, unsigned int command) +{ + cmd_list[cmd_ptr].command = command; + cmd_list[cmd_ptr].from = __builtin_return_address(0); + + cmd_ptr = (cmd_ptr + 1) & 7; - ptr = (ptr + 1) & 7; + fas216_writeb(info, REG_CMD, command); } static void print_debug_list(void) { int i; - i = ptr; + i = ph_ptr; - printk(KERN_ERR "SCSI IRQ trail: "); + printk(KERN_ERR "SCSI IRQ trail\n"); do { - printk("%02X:%02X:%02X:%1X ", - list[i].stat, list[i].ssr, - list[i].isr, list[i].ph); + printk(" %02x:%02x:%02x:%1x", + ph_list[i].stat, ph_list[i].ssr, + ph_list[i].isr, ph_list[i].ph); + i = (i + 1) & (PH_SIZE - 1); + if (((i ^ ph_ptr) & 7) == 0) + printk("\n"); + } while (i != ph_ptr); + if ((i ^ ph_ptr) & 7) + printk("\n"); + + i = cmd_ptr; + printk(KERN_ERR "FAS216 commands: "); + do { + printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from); i = (i + 1) & 7; - } while (i != ptr); + } while (i != cmd_ptr); printk("\n"); } static void fas216_done(FAS216_Info *info, unsigned int result); -/* Function: int fas216_clockrate(unsigned int clock) - * Purpose : calculate correct value to be written into clock conversion - * factor register. - * Params : clock - clock speed in MHz - * Returns : CLKF_ value - */ -static int fas216_clockrate(int clock) -{ - if (clock <= 10 || clock > 40) { - printk(KERN_CRIT - "fas216: invalid clock rate: check your driver!\n"); - clock = -1; - } else - clock = ((clock - 1) / 5 + 1) & 7; - - return clock; -} - -/* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos) - * Purpose : retrieve a last message from the list, using position in fifo - * Params : info - interface to search - * : pos - current fifo position +/** + * fas216_get_last_msg - retrive last message from the list + * @info: interface to search + * @pos: current fifo position + * + * Retrieve a last message from the list, using position in fifo. */ static inline unsigned short fas216_get_last_msg(FAS216_Info *info, int pos) @@ -298,22 +394,21 @@ packed_msg = msg->msg[0]; } -#ifdef DEBUG_MESSAGES - printk("Message: %04X found at position %02X\n", - packed_msg, pos); -#endif + fas216_log(info, LOG_MESSAGES, + "Message: %04x found at position %02x\n", packed_msg, pos); + return packed_msg; } -/* Function: int fas216_syncperiod(FAS216_Info *info, int ns) - * Purpose : Calculate value to be loaded into the STP register - * for a given period in ns - * Params : info - state structure for interface connected to device - * : ns - period in ns (between subsequent bytes) - * Returns : Value suitable for REG_STP +/** + * fas216_syncperiod - calculate STP register value + * @info: state structure for interface connected to device + * @ns: period in ns (between subsequent bytes) + * + * Calculate value to be loaded into the STP register for a given period + * in ns. Returns a value suitable for REG_STP. */ -static int -fas216_syncperiod(FAS216_Info *info, int ns) +static int fas216_syncperiod(FAS216_Info *info, int ns) { int value = (info->ifcfg.clockrate * ns) / 1000; @@ -327,23 +422,28 @@ return value & 31; } -/* Function: void fas216_set_sync(FAS216_Info *info, int target) - * Purpose : Correctly setup FAS216 chip for specified transfer period. - * Params : info - state structure for interface - * : target - target +/** + * fas216_set_sync - setup FAS216 chip for specified transfer period. + * @info: state structure for interface connected to device + * @target: target + * + * Correctly setup FAS216 chip for specified transfer period. * Notes : we need to switch the chip out of FASTSCSI mode if we have * a transfer period >= 200ns - otherwise the chip will violate * the SCSI timings. */ -static void -fas216_set_sync(FAS216_Info *info, int target) +static void fas216_set_sync(FAS216_Info *info, int target) { - outb(info->device[target].sof, REG_SOF(info)); - outb(info->device[target].stp, REG_STP(info)); + unsigned int cntl3; + + fas216_writeb(info, REG_SOF, info->device[target].sof); + fas216_writeb(info, REG_STP, info->device[target].stp); + + cntl3 = info->scsi.cfg[2]; if (info->device[target].period >= (200 / 4)) - outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info)); - else - outb(info->scsi.cfg[2], REG_CNTL3(info)); + cntl3 = cntl3 & ~CNTL3_FASTSCSI; + + fas216_writeb(info, REG_CNTL3, cntl3); } /* Synchronous transfer support @@ -364,19 +464,20 @@ * Using the correct method assures compatibility with wide data * transfers and future enhancements. * - * We will always initiate a synchronous transfer negociation request on + * We will always initiate a synchronous transfer negotiation request on * every INQUIRY or REQUEST SENSE message, unless the target itself has - * at some point performed a synchronous transfer negociation request, or + * at some point performed a synchronous transfer negotiation request, or * we have synchronous transfers disabled for this device. */ -/* Function: void fas216_handlesync(FAS216_Info *info, char *msg) - * Purpose : Handle a synchronous transfer message from the target - * Params : info - state structure for interface - * : msg - message from target +/** + * fas216_handlesync - Handle a synchronous transfer message + * @info: state structure for interface + * @msg: message from target + * + * Handle a synchronous transfer message from the target */ -static void -fas216_handlesync(FAS216_Info *info, char *msg) +static void fas216_handlesync(FAS216_Info *info, char *msg) { struct fas216_device *dev = &info->device[info->SCpnt->target]; enum { sync, async, none, reject } res = none; @@ -392,7 +493,7 @@ * message with a MESSAGE REJECT message. * * Hence, if we get this condition, we disable - * negociation for this device. + * negotiation for this device. */ if (dev->sync_state == neg_inprogress) { dev->sync_state = neg_invalid; @@ -410,14 +511,14 @@ res = reject; break; - /* We were not negociating a synchronous transfer, - * but the device sent us a negociation request. + /* We were not negotiating a synchronous transfer, + * but the device sent us a negotiation request. * Honour the request by sending back a SDTR * message containing our capability, limited by * the targets capability. */ default: - outb(CMD_SETATN, REG_CMD(info)); + fas216_cmd(info, CMD_SETATN); if (msg[4] > info->ifcfg.sync_max_depth) msg[4] = info->ifcfg.sync_max_depth; if (msg[3] < 1000 / info->ifcfg.clockrate) @@ -436,7 +537,7 @@ res = sync; break; - /* We initiated the synchronous transfer negociation, + /* We initiated the synchronous transfer negotiation, * and have successfully received a response from the * target. The synchronous transfer agreement has been * reached. Note: if the values returned are out of our @@ -465,7 +566,7 @@ break; case reject: - outb(CMD_SETATN, REG_CMD(info)); + fas216_cmd(info, CMD_SETATN); msgqueue_flush(&info->scsi.msgs); msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT); info->scsi.phase = PHASE_MSGOUT_EXPECT; @@ -482,332 +583,277 @@ } } -/* Function: void fas216_handlewide(FAS216_Info *info, char *msg) - * Purpose : Handle a wide transfer message from the target - * Params : info - state structure for interface - * : msg - message from target +/** + * fas216_updateptrs - update data pointers after transfer suspended/paused + * @info: interface's local pointer to update + * @bytes_transferred: number of bytes transferred + * + * Update data pointers after transfer suspended/paused */ -static void -fas216_handlewide(FAS216_Info *info, char *msg) +static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) { - struct fas216_device *dev = &info->device[info->SCpnt->target]; - enum { wide, bit8, none, reject } res = none; + Scsi_Pointer *SCp = &info->scsi.SCp; -#ifdef SCSI2_WIDE - switch (msg[0]) { - case MESSAGE_REJECT: - /* Wide transfer request failed. - * Note: SCSI II r10: - * - * SCSI devices that are capable of wide - * data transfers shall not respond to a - * WDTR message with a MESSAGE REJECT message. - * - * Hence, if we get this condition, we never - * reattempt negociation for this device. - */ - if (dev->wide_state == neg_inprogress) { - dev->wide_state = neg_invalid; - res = bit8; - } - break; + fas216_checkmagic(info); - case EXTENDED_MESSAGE: - switch (dev->wide_state) { - /* We don't accept wide data transfer requests. - * Respond with a MESSAGE REJECT to prevent a - * wide data transfer agreement from being reached. - */ - case neg_invalid: - res = reject; - break; + BUG_ON(bytes_transferred < 0); - /* We were not negociating a wide data transfer, - * but the device sent is a negociation request. - * Honour the request by sending back a WDTR - * message containing our capability, limited by - * the targets capability. - */ - default: - outb(CMD_SETATN, REG_CMD(info)); - if (msg[3] > info->ifcfg.wide_max_size) - msg[3] = info->ifcfg.wide_max_size; + info->SCpnt->request_bufflen -= bytes_transferred; - msgqueue_flush(&info->scsi.msgs); - msgqueue_addmsg(&info->scsi.msgs, 4, - EXTENDED_MESSAGE, 2, EXTENDED_WDTR, - msg[3]); - info->scsi.phase = PHASE_MSGOUT_EXPECT; - res = wide; + while (bytes_transferred != 0) { + if (SCp->this_residual > bytes_transferred) break; - - /* We initiated the wide data transfer negociation, - * and have successfully received a response from the - * target. The synchronous transfer agreement has been - * reached. Note: if the values returned are out of our - * bounds, we must reject the message. + /* + * We have used up this buffer. Move on to the + * next buffer. */ - case neg_inprogress: - res = reject; - if (msg[3] <= info->ifcfg.wide_max_size) { - dev->wide_state = neg_complete; - res = wide; - } - break; + bytes_transferred -= SCp->this_residual; + if (!next_SCp(SCp) && bytes_transferred) { + printk(KERN_WARNING "scsi%d.%c: out of buffers\n", + info->host->host_no, '0' + info->SCpnt->target); + return; } } -#else - res = reject; -#endif - - switch (res) { - case wide: - dev->wide_xfer = msg[3]; - break; - - case reject: - outb(CMD_SETATN, REG_CMD(info)); - msgqueue_flush(&info->scsi.msgs); - msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT); - info->scsi.phase = PHASE_MSGOUT_EXPECT; - - case bit8: - dev->wide_xfer = 0; - break; - case none: - break; - } + SCp->this_residual -= bytes_transferred; + if (SCp->this_residual) + SCp->ptr += bytes_transferred; + else + SCp->ptr = NULL; } -/* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) - * Purpose : update data pointers after transfer suspended/paused - * Params : info - interface's local pointer to update - * bytes_transferred - number of bytes transferred +/** + * fas216_pio - transfer data off of/on to card using programmed IO + * @info: interface to transfer data to/from + * @direction: direction to transfer data (DMA_OUT/DMA_IN) + * + * Transfer data off of/on to card using programmed IO. + * Notes: this is incredibly slow. */ -static void -fas216_updateptrs(FAS216_Info *info, int bytes_transferred) +static void fas216_pio(FAS216_Info *info, fasdmadir_t direction) { - unsigned char *ptr; - unsigned int residual; + Scsi_Pointer *SCp = &info->scsi.SCp; fas216_checkmagic(info); - ptr = info->scsi.SCp.ptr; - residual = info->scsi.SCp.this_residual; - - info->SCpnt->request_bufflen -= bytes_transferred; - - while (residual <= bytes_transferred && bytes_transferred) { - /* We have used up this buffer */ - bytes_transferred -= residual; - if (info->scsi.SCp.buffers_residual) { - info->scsi.SCp.buffer++; - info->scsi.SCp.buffers_residual--; - ptr = (unsigned char *)info->scsi.SCp.buffer->address; - residual = info->scsi.SCp.buffer->length; - } else { - ptr = NULL; - residual = 0; - } - } + if (direction == DMA_OUT) + fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp)); + else + put_next_SCp_byte(SCp, fas216_readb(info, REG_FF)); - residual -= bytes_transferred; - ptr += bytes_transferred; + if (SCp->this_residual == 0) + next_SCp(SCp); +} - if (residual == 0) - ptr = NULL; +static void fas216_set_stc(FAS216_Info *info, unsigned int length) +{ + fas216_writeb(info, REG_STCL, length); + fas216_writeb(info, REG_STCM, length >> 8); + fas216_writeb(info, REG_STCH, length >> 16); +} - info->scsi.SCp.ptr = ptr; - info->scsi.SCp.this_residual = residual; +static unsigned int fas216_get_ctc(FAS216_Info *info) +{ + return fas216_readb(info, REG_CTCL) + + (fas216_readb(info, REG_CTCM) << 8) + + (fas216_readb(info, REG_CTCH) << 16); } -/* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction) - * Purpose : transfer data off of/on to card using programmed IO - * Params : info - interface to transfer data to/from - * direction - direction to transfer data (DMA_OUT/DMA_IN) - * Notes : this is incredibly slow +/** + * fas216_cleanuptransfer - clean up after a transfer has completed. + * @info: interface to clean up + * + * Update the data pointers according to the number of bytes transferred + * on the SCSI bus. */ -static void -fas216_pio(FAS216_Info *info, fasdmadir_t direction) +static void fas216_cleanuptransfer(FAS216_Info *info) { - unsigned int residual; - char *ptr; + unsigned long total, residual, fifo; + fasdmatype_t dmatype = info->dma.transfer_type; - fas216_checkmagic(info); + info->dma.transfer_type = fasdma_none; - residual = info->scsi.SCp.this_residual; - ptr = info->scsi.SCp.ptr; + /* + * PIO transfers do not need to be cleaned up. + */ + if (dmatype == fasdma_pio || dmatype == fasdma_none) + return; - if (direction == DMA_OUT) - outb(*ptr++, REG_FF(info)); + if (dmatype == fasdma_real_all) + total = info->SCpnt->request_bufflen; else - *ptr++ = inb(REG_FF(info)); + total = info->scsi.SCp.this_residual; - residual -= 1; + residual = fas216_get_ctc(info); - if (residual == 0) { - if (info->scsi.SCp.buffers_residual) { - info->scsi.SCp.buffer++; - info->scsi.SCp.buffers_residual--; - ptr = (unsigned char *)info->scsi.SCp.buffer->address; - residual = info->scsi.SCp.buffer->length; - } else { - ptr = NULL; - residual = 0; - } - } + fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; - info->scsi.SCp.ptr = ptr; - info->scsi.SCp.this_residual = residual; + fas216_log(info, LOG_BUFFER, "cleaning up from previous " + "transfer: length 0x%06x, residual 0x%x, fifo %d", + total, residual, fifo); + + /* + * If we were performing Data-Out, the transfer counter + * counts down each time a byte is transferred by the + * host to the FIFO. This means we must include the + * bytes left in the FIFO from the transfer counter. + */ + if (info->scsi.phase == PHASE_DATAOUT) + residual += fifo; + + fas216_updateptrs(info, total - residual); } -/* Function: void fas216_starttransfer(FAS216_Info *info, - * fasdmadir_t direction) - * Purpose : Start a DMA/PIO transfer off of/on to card - * Params : info - interface from which device disconnected from - * direction - transfer direction (DMA_OUT/DMA_IN) +/** + * fas216_transfer - Perform a DMA/PIO transfer off of/on to card + * @info: interface from which device disconnected from + * + * Start a DMA/PIO transfer off of/on to card */ -static void -fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo) +static void fas216_transfer(FAS216_Info *info) { + fasdmadir_t direction; fasdmatype_t dmatype; - fas216_checkmagic(info); - - info->scsi.phase = (direction == DMA_OUT) ? - PHASE_DATAOUT : PHASE_DATAIN; - - if (info->dma.transfer_type != fasdma_none && - info->dma.transfer_type != fasdma_pio) { - unsigned long total, residual; - - if (info->dma.transfer_type == fasdma_real_all) - total = info->SCpnt->request_bufflen; - else - total = info->scsi.SCp.this_residual; - - residual = (inb(REG_CFIS(info)) & CFIS_CF) + - inb(REG_CTCL(info)) + - (inb(REG_CTCM(info)) << 8) + - (inb(REG_CTCH(info)) << 16); - fas216_updateptrs(info, total - residual); - } - info->dma.transfer_type = fasdma_none; + fas216_log(info, LOG_BUFFER, + "starttransfer: buffer %p length 0x%06x reqlen 0x%06x", + info->scsi.SCp.ptr, info->scsi.SCp.this_residual, + info->SCpnt->request_bufflen); if (!info->scsi.SCp.ptr) { - printk("scsi%d.%c: null buffer passed to " - "fas216_starttransfer\n", info->host->host_no, - fas216_target(info)); + fas216_log(info, LOG_ERROR, "null buffer passed to " + "fas216_starttransfer"); + print_SCp(&info->scsi.SCp, "SCp: ", "\n"); + print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n"); return; } - /* flush FIFO */ - if (flush_fifo) - outb(CMD_FLUSHFIFO, REG_CMD(info)); - /* - * Default to PIO mode or DMA mode if we have a synchronous - * transfer agreement. + * If we have a synchronous transfer agreement in effect, we must + * use DMA mode. If we are using asynchronous transfers, we may + * use DMA mode or PIO mode. */ - if (info->device[info->SCpnt->target].sof && info->dma.setup) + if (info->device[info->SCpnt->target].sof) dmatype = fasdma_real_all; else dmatype = fasdma_pio; + if (info->scsi.phase == PHASE_DATAOUT) + direction = DMA_OUT; + else + direction = DMA_IN; + if (info->dma.setup) dmatype = info->dma.setup(info->host, &info->scsi.SCp, direction, dmatype); info->dma.transfer_type = dmatype; + if (dmatype == fasdma_real_all) + fas216_set_stc(info, info->SCpnt->request_bufflen); + else + fas216_set_stc(info, info->scsi.SCp.this_residual); + switch (dmatype) { case fasdma_pio: - outb(0, REG_SOF(info)); - outb(info->scsi.async_stp, REG_STP(info)); - outb(info->scsi.SCp.this_residual, REG_STCL(info)); - outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info)); - outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info)); - outb(CMD_TRANSFERINFO, REG_CMD(info)); + fas216_log(info, LOG_BUFFER, "PIO transfer"); + fas216_writeb(info, REG_SOF, 0); + fas216_writeb(info, REG_STP, info->scsi.async_stp); + fas216_cmd(info, CMD_TRANSFERINFO); fas216_pio(info, direction); break; case fasdma_pseudo: - outb(info->scsi.SCp.this_residual, REG_STCL(info)); - outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info)); - outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info)); - outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info)); + fas216_log(info, LOG_BUFFER, "pseudo transfer"); + fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA); info->dma.pseudo(info->host, &info->scsi.SCp, direction, info->SCpnt->transfersize); break; case fasdma_real_block: - outb(info->scsi.SCp.this_residual, REG_STCL(info)); - outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info)); - outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info)); - outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info)); + fas216_log(info, LOG_BUFFER, "block dma transfer"); + fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA); break; case fasdma_real_all: - outb(info->SCpnt->request_bufflen, REG_STCL(info)); - outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info)); - outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info)); - outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info)); + fas216_log(info, LOG_BUFFER, "total dma transfer"); + fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA); break; default: - printk(KERN_ERR "scsi%d.%d: invalid FAS216 DMA type\n", - info->host->host_no, fas216_target(info)); + fas216_log(info, LOG_BUFFER | LOG_ERROR, + "invalid FAS216 DMA type"); break; } } -/* Function: void fas216_stoptransfer(FAS216_Info *info) - * Purpose : Stop a DMA transfer onto / off of the card - * Params : info - interface from which device disconnected from +/** + * fas216_stoptransfer - Stop a DMA transfer onto / off of the card + * @info: interface from which device disconnected from + * + * Called when we switch away from DATA IN or DATA OUT phases. */ -static void -fas216_stoptransfer(FAS216_Info *info) +static void fas216_stoptransfer(FAS216_Info *info) { fas216_checkmagic(info); - if (info->dma.transfer_type != fasdma_none && - info->dma.transfer_type != fasdma_pio) { - unsigned long total, residual; + if (info->dma.transfer_type == fasdma_real_all || + info->dma.transfer_type == fasdma_real_block) + info->dma.stop(info->host, &info->scsi.SCp); - if ((info->dma.transfer_type == fasdma_real_all || - info->dma.transfer_type == fasdma_real_block) && - info->dma.stop) - info->dma.stop(info->host, &info->scsi.SCp); + fas216_cleanuptransfer(info); - if (info->dma.transfer_type == fasdma_real_all) - total = info->SCpnt->request_bufflen; - else - total = info->scsi.SCp.this_residual; + if (info->scsi.phase == PHASE_DATAIN) { + unsigned int fifo; - residual = (inb(REG_CFIS(info)) & CFIS_CF) + - inb(REG_CTCL(info)) + - (inb(REG_CTCM(info)) << 8) + - (inb(REG_CTCH(info)) << 16); - fas216_updateptrs(info, total - residual); - info->dma.transfer_type = fasdma_none; + /* + * If we were performing Data-In, then the FIFO counter + * contains the number of bytes not transferred via DMA + * from the on-board FIFO. Read them manually. + */ + fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; + while (fifo && info->scsi.SCp.ptr) { + *info->scsi.SCp.ptr = fas216_readb(info, REG_FF); + fas216_updateptrs(info, 1); + fifo--; + } + } else { + /* + * After a Data-Out phase, there may be unsent + * bytes left in the FIFO. Flush them out. + */ + fas216_cmd(info, CMD_FLUSHFIFO); } - if (info->scsi.phase == PHASE_DATAOUT) - outb(CMD_FLUSHFIFO, REG_CMD(info)); } -/* Function: void fas216_disconnected_intr(FAS216_Info *info) - * Purpose : handle device disconnection - * Params : info - interface from which device disconnected from +static void fas216_aborttransfer(FAS216_Info *info) +{ + fas216_checkmagic(info); + + if (info->dma.transfer_type == fasdma_real_all || + info->dma.transfer_type == fasdma_real_block) + info->dma.stop(info->host, &info->scsi.SCp); + + info->dma.transfer_type = fasdma_none; + fas216_cmd(info, CMD_FLUSHFIFO); +} + +static void fas216_kick(FAS216_Info *info); + +/** + * fas216_disconnected_intr - handle device disconnection + * @info: interface from which device disconnected from + * + * Handle device disconnection */ -static void -fas216_disconnect_intr(FAS216_Info *info) +static void fas216_disconnect_intr(FAS216_Info *info) { + unsigned long flags; + fas216_checkmagic(info); -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: disconnect phase=%02X\n", info->host->host_no, - fas216_target(info), info->scsi.phase); -#endif + fas216_log(info, LOG_CONNECT, "disconnect phase=%02x", + info->scsi.phase); + msgqueue_flush(&info->scsi.msgs); switch (info->scsi.phase) { @@ -817,11 +863,13 @@ break; case PHASE_MSGIN_DISCONNECT: /* message in - disconnecting */ - outb(CMD_ENABLESEL, REG_CMD(info)); info->scsi.disconnectable = 1; - info->scsi.reconnected.tag = 0; info->scsi.phase = PHASE_IDLE; info->stats.disconnects += 1; + spin_lock_irqsave(&info->host_lock, flags); + if (info->scsi.phase == PHASE_IDLE) + fas216_kick(info); + spin_unlock_irqrestore(&info->host_lock, flags); break; case PHASE_DONE: /* at end of command - complete */ @@ -845,295 +893,131 @@ } } -/* Function: void fas216_reselected_intr(FAS216_Info *info) - * Purpose : Start reconnection of a device - * Params : info - interface which was reselected +/** + * fas216_reselected_intr - start reconnection of a device + * @info: interface which was reselected + * + * Start reconnection of a device */ static void fas216_reselected_intr(FAS216_Info *info) { - unsigned char target, identify_msg, ok; + unsigned int cfis, i; + unsigned char msg[4]; + unsigned char target, lun, tag; fas216_checkmagic(info); - if ((info->scsi.phase == PHASE_SELECTION || - info->scsi.phase == PHASE_SELSTEPS) && info->SCpnt) { - Scsi_Cmnd *SCpnt = info->SCpnt; + if (info->scsi.phase == PHASE_SELECTION || + info->scsi.phase == PHASE_SELSTEPS) { + fas216_log(info, LOG_ERROR, "wrong phase in reselected_intr\n"); + return; + } - info->origSCpnt = SCpnt; - info->SCpnt = NULL; + cfis = fas216_readb(info, REG_CFIS); - if (info->device[SCpnt->target].wide_state == neg_inprogress) - info->device[SCpnt->target].wide_state = neg_wait; - if (info->device[SCpnt->target].sync_state == neg_inprogress) - info->device[SCpnt->target].sync_state = neg_wait; - } + fas216_log(info, LOG_CONNECT, "reconnect phase=%02x cfis=%02x", + info->scsi.phase, cfis); -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: reconnect phase=%02X\n", info->host->host_no, - fas216_target(info), info->scsi.phase); -#endif + cfis &= CFIS_CF; - if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) { + if (cfis < 2 || cfis > 4) { printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n", info->host->host_no); - outb(CMD_SETATN, REG_CMD(info)); - outb(CMD_MSGACCEPTED, REG_CMD(info)); - msgqueue_flush(&info->scsi.msgs); - msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); - info->scsi.phase = PHASE_MSGOUT_EXPECT; - return; - } - - target = inb(REG_FF(info)); - identify_msg = inb(REG_FF(info)); - - ok = 1; - if (!(target & (1 << info->host->this_id))) { - printk(KERN_ERR "scsi%d.H: invalid host id on reselect\n", info->host->host_no); - ok = 0; + goto bad_message; } - if (!(identify_msg & 0x80)) { - printk(KERN_ERR "scsi%d.H: no IDENTIFY message on reselect, got msg %02X\n", - info->host->host_no, identify_msg); - ok = 0; - } + for (i = 0; i < cfis; i++) + msg[i] = fas216_readb(info, REG_FF); - if (!ok) { - /* - * Something went wrong - send an initiator error to - * the target. - */ - outb(CMD_SETATN, REG_CMD(info)); - outb(CMD_MSGACCEPTED, REG_CMD(info)); - msgqueue_flush(&info->scsi.msgs); - msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); - info->scsi.phase = PHASE_MSGOUT_EXPECT; - return; - } + if (!(msg[0] & (1 << info->host->this_id)) || + !(msg[1] & 0x80)) + goto initiator_error; - target &= ~(1 << info->host->this_id); - switch (target) { - case 1: target = 0; break; - case 2: target = 1; break; - case 4: target = 2; break; - case 8: target = 3; break; - case 16: target = 4; break; - case 32: target = 5; break; - case 64: target = 6; break; - case 128: target = 7; break; - default: target = info->host->this_id; break; - } - - identify_msg &= 7; - info->scsi.reconnected.target = target; - info->scsi.reconnected.lun = identify_msg; - info->scsi.reconnected.tag = 0; - - ok = 0; - if (info->scsi.disconnectable && info->SCpnt && - info->SCpnt->target == target && info->SCpnt->lun == identify_msg) - ok = 1; + target = msg[0] & ~(1 << info->host->this_id); + target = ffs(target) - 1; + lun = msg[1] & 7; + tag = 0; - if (!ok && queue_probetgtlun(&info->queues.disconnected, target, identify_msg)) - ok = 1; + if (cfis >= 3) { + if (msg[2] != SIMPLE_QUEUE_TAG) + goto initiator_error; - msgqueue_flush(&info->scsi.msgs); - if (ok) { - info->scsi.phase = PHASE_RECONNECTED; - outb(target, REG_SDID(info)); - } else { - /* - * Our command structure not found - abort the - * command on the target. Since we have no - * record of this command, we can't send - * an INITIATOR DETECTED ERROR message. - */ - outb(CMD_SETATN, REG_CMD(info)); - msgqueue_addmsg(&info->scsi.msgs, 1, ABORT); - info->scsi.phase = PHASE_MSGOUT_EXPECT; + tag = msg[3]; } - outb(CMD_MSGACCEPTED, REG_CMD(info)); -} - -/* Function: void fas216_finish_reconnect(FAS216_Info *info) - * Purpose : finish reconnection sequence for device - * Params : info - interface which caused function done interrupt - */ -static void -fas216_finish_reconnect(FAS216_Info *info) -{ - fas216_checkmagic(info); + /* set up for synchronous transfers */ + fas216_writeb(info, REG_SDID, target); + fas216_set_sync(info, target); + msgqueue_flush(&info->scsi.msgs); -#ifdef DEBUG_CONNECT - printk("Connected: %1X %1X %02X, reconnected: %1X %1X %02X\n", - info->SCpnt->target, info->SCpnt->lun, info->SCpnt->tag, - info->scsi.reconnected.target, info->scsi.reconnected.lun, - info->scsi.reconnected.tag); -#endif + fas216_log(info, LOG_CONNECT, "Reconnected: target %1x lun %1x tag %02x", + target, lun, tag); if (info->scsi.disconnectable && info->SCpnt) { info->scsi.disconnectable = 0; - if (info->SCpnt->target == info->scsi.reconnected.target && - info->SCpnt->lun == info->scsi.reconnected.lun && - info->SCpnt->tag == info->scsi.reconnected.tag) { -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: reconnected", - info->host->host_no, fas216_target(info)); -#endif + if (info->SCpnt->target == target && + info->SCpnt->lun == lun && + info->SCpnt->tag == tag) { + fas216_log(info, LOG_CONNECT, "reconnected previously connected command"); } else { queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt); -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: had to move command to disconnected queue\n", - info->host->host_no, fas216_target(info)); -#endif + fas216_log(info, LOG_CONNECT, "had to move command to disconnected queue"); info->SCpnt = NULL; } } if (!info->SCpnt) { info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected, - info->scsi.reconnected.target, - info->scsi.reconnected.lun, - info->scsi.reconnected.tag); -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: had to get command", - info->host->host_no, fas216_target(info)); -#endif + target, lun, tag); + fas216_log(info, LOG_CONNECT, "had to get command"); } - if (!info->SCpnt) { - outb(CMD_SETATN, REG_CMD(info)); - msgqueue_flush(&info->scsi.msgs); -#if 0 - if (info->scsi.reconnected.tag) - msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, info->scsi.reconnected.tag); - else -#endif - msgqueue_addmsg(&info->scsi.msgs, 1, ABORT); - info->scsi.phase = PHASE_MSGOUT_EXPECT; - info->scsi.aborting = 1; - } else { + + if (info->SCpnt) { /* * Restore data pointer from SAVED data pointer */ info->scsi.SCp = info->SCpnt->SCp; -#ifdef DEBUG_CONNECT - printk(", data pointers: [%p, %X]", - info->scsi.SCp.ptr, info->scsi.SCp.this_residual); -#endif - } -#ifdef DEBUG_CONNECT - printk("\n"); -#endif -} -static int fas216_wait_cmd(FAS216_Info *info, int cmd) -{ - int tout; - int stat; - - outb(cmd, REG_CMD(info)); + fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]", + info->scsi.SCp.ptr, info->scsi.SCp.this_residual); + info->scsi.phase = PHASE_MSGIN; + } else { + /* + * Our command structure not found - abort the + * command on the target. Since we have no + * record of this command, we can't send + * an INITIATOR DETECTED ERROR message. + */ + fas216_cmd(info, CMD_SETATN); - for (tout = 1000; tout; tout -= 1) { - stat = inb(REG_STAT(info)); - if (stat & STAT_INT) - break; - udelay(1); + if (tag) + msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, tag); + else + msgqueue_addmsg(&info->scsi.msgs, 1, ABORT); + info->scsi.phase = PHASE_MSGOUT_EXPECT; + info->scsi.aborting = 1; } - return stat; -} - -static int fas216_get_msg_byte(FAS216_Info *info) -{ - int stat; - - stat = fas216_wait_cmd(info, CMD_MSGACCEPTED); - - if ((stat & STAT_INT) == 0) - goto timedout; - - if ((stat & STAT_BUSMASK) != STAT_MESGIN) - goto unexpected_phase_change; - - inb(REG_INST(info)); - - stat = fas216_wait_cmd(info, CMD_TRANSFERINFO); - - if ((stat & STAT_INT) == 0) - goto timedout; - - if ((stat & STAT_BUSMASK) != STAT_MESGIN) - goto unexpected_phase_change; - - inb(REG_INST(info)); - - return inb(REG_FF(info)); - -timedout: - printk("scsi%d.%c: timed out waiting for message byte\n", - info->host->host_no, fas216_target(info)); - return -1; - -unexpected_phase_change: - printk("scsi%d.%c: unexpected phase change: status = %02X\n", - info->host->host_no, fas216_target(info), stat); + fas216_cmd(info, CMD_MSGACCEPTED); + return; - return -2; + initiator_error: + printk(KERN_ERR "scsi%d.H: error during reselection: bytes", + info->host->host_no); + for (i = 0; i < cfis; i++) + printk(" %02x", msg[i]); + printk("\n"); + bad_message: + fas216_cmd(info, CMD_SETATN); + msgqueue_flush(&info->scsi.msgs); + msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); + info->scsi.phase = PHASE_MSGOUT_EXPECT; + fas216_cmd(info, CMD_MSGACCEPTED); } -/* Function: void fas216_message(FAS216_Info *info) - * Purpose : handle a function done interrupt from FAS216 chip - * Params : info - interface which caused function done interrupt - */ -static void fas216_message(FAS216_Info *info) +static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen) { - unsigned char *message = info->scsi.message; - unsigned int msglen = 1, i; - int msgbyte = 0; - - fas216_checkmagic(info); - - message[0] = inb(REG_FF(info)); - - if (message[0] == EXTENDED_MESSAGE) { - msgbyte = fas216_get_msg_byte(info); - - if (msgbyte >= 0) { - message[1] = msgbyte; - - for (msglen = 2; msglen < message[1] + 2; msglen++) { - msgbyte = fas216_get_msg_byte(info); - - if (msgbyte >= 0) - message[msglen] = msgbyte; - else - break; - } - } - } - - info->scsi.msglen = msglen; - -#ifdef DEBUG_MESSAGES - { - int i; - - printk("scsi%d.%c: message in: ", - info->host->host_no, fas216_target(info)); - for (i = 0; i < msglen; i++) - printk("%02X ", message[i]); - printk("\n"); - } -#endif - - if (info->scsi.phase == PHASE_RECONNECTED) { - if (message[0] == SIMPLE_QUEUE_TAG) - info->scsi.reconnected.tag = message[1]; - fas216_finish_reconnect(info); - info->scsi.phase = PHASE_MSGIN; - } + int i; switch (message[0]) { case COMMAND_COMPLETE: @@ -1159,11 +1043,9 @@ */ info->SCpnt->SCp = info->scsi.SCp; info->SCpnt->SCp.sent_command = 0; -#if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT) - printk("scsi%d.%c: save data pointers: [%p, %X]\n", - info->host->host_no, fas216_target(info), + fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER, + "save data pointers: [%p, %X]", info->scsi.SCp.ptr, info->scsi.SCp.this_residual); -#endif break; case RESTORE_POINTERS: @@ -1174,11 +1056,9 @@ * Restore current data pointer from SAVED data pointer */ info->scsi.SCp = info->SCpnt->SCp; -#if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT) - printk("scsi%d.%c: restore data pointers: [%p, %X]\n", - info->host->host_no, fas216_target(info), + fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER, + "restore data pointers: [%p, 0x%x]", info->scsi.SCp.ptr, info->scsi.SCp.this_residual); -#endif break; case DISCONNECT: @@ -1197,13 +1077,8 @@ fas216_handlesync(info, message); break; - case EXTENDED_MESSAGE | EXTENDED_WDTR << 8: - fas216_handlewide(info, message); - break; - default: - printk("scsi%d.%c: reject, last message %04X\n", - info->host->host_no, fas216_target(info), + fas216_log(info, 0, "reject, last message 0x%04x", fas216_get_last_msg(info, info->scsi.msgin_fifo)); } break; @@ -1211,29 +1086,15 @@ case NOP: break; - case SIMPLE_QUEUE_TAG: - if (msglen < 2) - goto unrecognised; - - /* handled above - print a warning since this is untested */ - printk("scsi%d.%c: reconnect queue tag %02X\n", - info->host->host_no, fas216_target(info), - message[1]); - break; - case EXTENDED_MESSAGE: if (msglen < 3) goto unrecognised; switch (message[2]) { - case EXTENDED_SDTR: /* Sync transfer negociation request/reply */ + case EXTENDED_SDTR: /* Sync transfer negotiation request/reply */ fas216_handlesync(info, message); break; - case EXTENDED_WDTR: /* Wide transfer negociation request/reply */ - fas216_handlewide(info, message); - break; - default: goto unrecognised; } @@ -1242,12 +1103,10 @@ default: goto unrecognised; } - outb(CMD_MSGACCEPTED, REG_CMD(info)); return; unrecognised: - printk("scsi%d.%c: unrecognised message, rejecting\n", - info->host->host_no, fas216_target(info)); + fas216_log(info, 0, "unrecognised message, rejecting"); printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info)); for (i = 0; i < msglen; i++) printk("%s%02X", i & 31 ? " " : "\n ", message[i]); @@ -1258,19 +1117,138 @@ * I can't use SETATN since the chip gives me an * invalid command interrupt when I do. Weird. */ -outb(CMD_NOP, REG_CMD(info)); +fas216_cmd(info, CMD_NOP); fas216_dumpstate(info); - outb(CMD_SETATN, REG_CMD(info)); + fas216_cmd(info, CMD_SETATN); msgqueue_flush(&info->scsi.msgs); msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT); info->scsi.phase = PHASE_MSGOUT_EXPECT; fas216_dumpstate(info); - outb(CMD_MSGACCEPTED, REG_CMD(info)); } -/* Function: void fas216_send_command(FAS216_Info *info) - * Purpose : send a command to a target after all message bytes have been sent - * Params : info - interface which caused bus service +static int fas216_wait_cmd(FAS216_Info *info, int cmd) +{ + int tout; + int stat; + + fas216_cmd(info, cmd); + + for (tout = 1000; tout; tout -= 1) { + stat = fas216_readb(info, REG_STAT); + if (stat & (STAT_INT|STAT_PARITYERROR)) + break; + udelay(1); + } + + return stat; +} + +static int fas216_get_msg_byte(FAS216_Info *info) +{ + unsigned int stat = fas216_wait_cmd(info, CMD_MSGACCEPTED); + + if ((stat & STAT_INT) == 0) + goto timedout; + + if ((stat & STAT_BUSMASK) != STAT_MESGIN) + goto unexpected_phase_change; + + fas216_readb(info, REG_INST); + + stat = fas216_wait_cmd(info, CMD_TRANSFERINFO); + + if ((stat & STAT_INT) == 0) + goto timedout; + + if (stat & STAT_PARITYERROR) + goto parity_error; + + if ((stat & STAT_BUSMASK) != STAT_MESGIN) + goto unexpected_phase_change; + + fas216_readb(info, REG_INST); + + return fas216_readb(info, REG_FF); + +timedout: + fas216_log(info, LOG_ERROR, "timed out waiting for message byte"); + return -1; + +unexpected_phase_change: + fas216_log(info, LOG_ERROR, "unexpected phase change: status = %02x", stat); + return -2; + +parity_error: + fas216_log(info, LOG_ERROR, "parity error during message in phase"); + return -3; +} + +/** + * fas216_message - handle a function done interrupt from FAS216 chip + * @info: interface which caused function done interrupt + * + * Handle a function done interrupt from FAS216 chip + */ +static void fas216_message(FAS216_Info *info) +{ + unsigned char *message = info->scsi.message; + unsigned int msglen = 1; + int msgbyte = 0; + + fas216_checkmagic(info); + + message[0] = fas216_readb(info, REG_FF); + + if (message[0] == EXTENDED_MESSAGE) { + msgbyte = fas216_get_msg_byte(info); + + if (msgbyte >= 0) { + message[1] = msgbyte; + + for (msglen = 2; msglen < message[1] + 2; msglen++) { + msgbyte = fas216_get_msg_byte(info); + + if (msgbyte >= 0) + message[msglen] = msgbyte; + else + break; + } + } + } + + if (msgbyte == -3) + goto parity_error; + +#ifdef DEBUG_MESSAGES + { + int i; + + printk("scsi%d.%c: message in: ", + info->host->host_no, fas216_target(info)); + for (i = 0; i < msglen; i++) + printk("%02X ", message[i]); + printk("\n"); + } +#endif + + fas216_parse_message(info, message, msglen); + fas216_cmd(info, CMD_MSGACCEPTED); + return; + +parity_error: + fas216_cmd(info, CMD_SETATN); + msgqueue_flush(&info->scsi.msgs); + msgqueue_addmsg(&info->scsi.msgs, 1, MSG_PARITY_ERROR); + info->scsi.phase = PHASE_MSGOUT_EXPECT; + fas216_cmd(info, CMD_MSGACCEPTED); + return; +} + +/** + * fas216_send_command - send command after all message bytes have been sent + * @info: interface which caused bus service + * + * Send a command to a target after all message bytes have been sent */ static void fas216_send_command(FAS216_Info *info) { @@ -1278,22 +1256,24 @@ fas216_checkmagic(info); - outb(CMD_NOP|CMD_WITHDMA, REG_CMD(info)); - outb(CMD_FLUSHFIFO, REG_CMD(info)); + fas216_cmd(info, CMD_NOP|CMD_WITHDMA); + fas216_cmd(info, CMD_FLUSHFIFO); /* load command */ for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++) - outb(info->SCpnt->cmnd[i], REG_FF(info)); + fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]); - outb(CMD_TRANSFERINFO, REG_CMD(info)); + fas216_cmd(info, CMD_TRANSFERINFO); info->scsi.phase = PHASE_COMMAND; } -/* Function: void fas216_send_messageout(FAS216_Info *info, int start) - * Purpose : handle bus service to send a message - * Params : info - interface which caused bus service - * Note : We do not allow the device to change the data direction! +/** + * fas216_send_messageout - handle bus service to send a message + * @info: interface which caused bus service + * + * Handle bus service to send a message. + * Note: We do not allow the device to change the data direction! */ static void fas216_send_messageout(FAS216_Info *info, int start) { @@ -1301,7 +1281,7 @@ fas216_checkmagic(info); - outb(CMD_FLUSHFIFO, REG_CMD(info)); + fas216_cmd(info, CMD_FLUSHFIFO); if (tot_msglen) { struct message *msg; @@ -1311,42 +1291,43 @@ int i; for (i = start; i < msg->length; i++) - outb(msg->msg[i], REG_FF(info)); + fas216_writeb(info, REG_FF, msg->msg[i]); - msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF); + msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF); start = 0; } } else - outb(NOP, REG_FF(info)); + fas216_writeb(info, REG_FF, NOP); - outb(CMD_TRANSFERINFO, REG_CMD(info)); + fas216_cmd(info, CMD_TRANSFERINFO); info->scsi.phase = PHASE_MSGOUT; } -/* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr) - * Purpose : handle a bus service interrupt from FAS216 chip - * Params : info - interface which caused bus service interrupt - * stat - Status register contents - * ssr - SCSI Status register contents +/** + * fas216_busservice_intr - handle bus service interrupt from FAS216 chip + * @info: interface which caused bus service interrupt + * @stat: Status register contents + * @is: SCSI Status register contents + * + * Handle a bus service interrupt from FAS216 chip */ -static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr) +static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int is) { fas216_checkmagic(info); -#ifdef DEBUG_BUSSERVICE - printk("scsi%d.%c: bus service: stat=%02X ssr=%02X phase=%02X\n", - info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase); -#endif + fas216_log(info, LOG_BUSSERVICE, + "bus service: stat=%02x is=%02x phase=%02x", + stat, is, info->scsi.phase); switch (info->scsi.phase) { case PHASE_SELECTION: - if ((ssr & IS_BITS) != 1) + if ((is & IS_BITS) != IS_MSGBYTESENT) goto bad_is; break; case PHASE_SELSTEPS: - switch (ssr & IS_BITS) { + switch (is & IS_BITS) { case IS_SELARB: case IS_MSGBYTESENT: goto bad_is; @@ -1365,42 +1346,36 @@ break; } - outb(CMD_NOP, REG_CMD(info)); + fas216_cmd(info, CMD_NOP); #define STATE(st,ph) ((ph) << 3 | (st)) /* This table describes the legal SCSI state transitions, * as described by the SCSI II spec. */ switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) { - /* Reselmsgin -> Data In */ - case STATE(STAT_DATAIN, PHASE_RECONNECTED): - fas216_finish_reconnect(info); case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In */ - case STATE(STAT_DATAIN, PHASE_DATAIN): /* Data In -> Data In */ case STATE(STAT_DATAIN, PHASE_MSGOUT): /* Message Out -> Data In */ case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command -> Data In */ case STATE(STAT_DATAIN, PHASE_MSGIN): /* Message In -> Data In */ - fas216_starttransfer(info, DMA_IN, 0); + info->scsi.phase = PHASE_DATAIN; + fas216_transfer(info); return; + case STATE(STAT_DATAIN, PHASE_DATAIN): /* Data In -> Data In */ case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out -> Data Out */ - fas216_starttransfer(info, DMA_OUT, 0); + fas216_cleanuptransfer(info); + fas216_transfer(info); return; - /* Reselmsgin -> Data Out */ - case STATE(STAT_DATAOUT, PHASE_RECONNECTED): - fas216_finish_reconnect(info); case STATE(STAT_DATAOUT, PHASE_SELSTEPS):/* Sel w/ steps-> Data Out */ case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out -> Data Out */ case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command -> Data Out */ case STATE(STAT_DATAOUT, PHASE_MSGIN): /* Message In -> Data Out */ - fas216_starttransfer(info, DMA_OUT, 1); + fas216_cmd(info, CMD_FLUSHFIFO); + info->scsi.phase = PHASE_DATAOUT; + fas216_transfer(info); return; - /* Reselmsgin -> Status */ - case STATE(STAT_STATUS, PHASE_RECONNECTED): - fas216_finish_reconnect(info); - goto status; case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out -> Status */ case STATE(STAT_STATUS, PHASE_DATAIN): /* Data In -> Status */ fas216_stoptransfer(info); @@ -1408,8 +1383,7 @@ case STATE(STAT_STATUS, PHASE_MSGOUT): /* Message Out -> Status */ case STATE(STAT_STATUS, PHASE_COMMAND): /* Command -> Status */ case STATE(STAT_STATUS, PHASE_MSGIN): /* Message In -> Status */ - status: - outb(CMD_INITCMDCOMPLETE, REG_CMD(info)); + fas216_cmd(info, CMD_INITCMDCOMPLETE); info->scsi.phase = PHASE_STATUS; return; @@ -1419,32 +1393,59 @@ case STATE(STAT_MESGIN, PHASE_COMMAND): /* Command -> Message In */ case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In */ case STATE(STAT_MESGIN, PHASE_MSGOUT): /* Message Out -> Message In */ - info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF; - outb(CMD_FLUSHFIFO, REG_CMD(info)); - outb(CMD_TRANSFERINFO, REG_CMD(info)); + info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; + fas216_cmd(info, CMD_FLUSHFIFO); + fas216_cmd(info, CMD_TRANSFERINFO); info->scsi.phase = PHASE_MSGIN; return; - /* Reselmsgin -> Message In */ - case STATE(STAT_MESGIN, PHASE_RECONNECTED): case STATE(STAT_MESGIN, PHASE_MSGIN): - info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF; - outb(CMD_TRANSFERINFO, REG_CMD(info)); + info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; + fas216_cmd(info, CMD_TRANSFERINFO); return; - /* Reselmsgin -> Command */ - case STATE(STAT_COMMAND, PHASE_RECONNECTED): - fas216_finish_reconnect(info); case STATE(STAT_COMMAND, PHASE_MSGOUT): /* Message Out -> Command */ case STATE(STAT_COMMAND, PHASE_MSGIN): /* Message In -> Command */ fas216_send_command(info); info->scsi.phase = PHASE_COMMAND; return; - /* Selection -> Message Out */ + + + /* + * Selection -> Message Out + */ case STATE(STAT_MESGOUT, PHASE_SELECTION): fas216_send_messageout(info, 1); return; - /* Any -> Message Out */ + + /* + * Message Out -> Message Out + */ + case STATE(STAT_MESGOUT, PHASE_SELSTEPS): + case STATE(STAT_MESGOUT, PHASE_MSGOUT): + /* + * If we get another message out phase, this usually + * means some parity error occurred. Resend complete + * set of messages. If we have more than one byte to + * send, we need to assert ATN again. + */ + if (info->device[info->SCpnt->target].parity_check) { + /* + * We were testing... good, the device + * supports parity checking. + */ + info->device[info->SCpnt->target].parity_check = 0; + info->device[info->SCpnt->target].parity_enabled = 1; + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); + } + + if (msgqueue_msglength(&info->scsi.msgs) > 1) + fas216_cmd(info, CMD_SETATN); + /*FALLTHROUGH*/ + + /* + * Any -> Message Out + */ case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT): fas216_send_messageout(info, 0); return; @@ -1463,30 +1464,13 @@ printk(KERN_ERR "scsi%d.%c: " "target trying to receive more command bytes\n", info->host->host_no, fas216_target(info)); - outb(CMD_SETATN, REG_CMD(info)); - outb(15, REG_STCL(info)); - outb(0, REG_STCM(info)); - outb(0, REG_STCH(info)); - outb(CMD_PADBYTES | CMD_WITHDMA, REG_CMD(info)); + fas216_cmd(info, CMD_SETATN); + fas216_set_stc(info, 15); + fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA); msgqueue_flush(&info->scsi.msgs); msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); info->scsi.phase = PHASE_MSGOUT_EXPECT; return; - - /* Selection -> Message Out */ - case STATE(STAT_MESGOUT, PHASE_SELSTEPS): - case STATE(STAT_MESGOUT, PHASE_MSGOUT): /* Message Out -> Message Out */ - /* If we get another message out phase, this - * usually means some parity error occurred. - * Resend complete set of messages. If we have - * more than 1 byte to send, we need to assert - * ATN again. - */ - if (msgqueue_msglength(&info->scsi.msgs) > 1) - outb(CMD_SETATN, REG_CMD(info)); - - fas216_send_messageout(info, 0); - return; } if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) { @@ -1494,11 +1478,11 @@ info->host->host_no, fas216_target(info), fas216_bus_phase(stat)); msgqueue_flush(&info->scsi.msgs); - outb(CMD_SETATN, REG_CMD(info)); + fas216_cmd(info, CMD_SETATN); msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); info->scsi.phase = PHASE_MSGOUT_EXPECT; info->scsi.aborting = 1; - outb(CMD_TRANSFERINFO, REG_CMD(info)); + fas216_cmd(info, CMD_TRANSFERINFO); return; } printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n", @@ -1509,191 +1493,245 @@ return; bad_is: - printk("scsi%d.%c: bus service at step %d?\n", - info->host->host_no, fas216_target(info), - ssr & IS_BITS); + fas216_log(info, 0, "bus service at step %d?", is & IS_BITS); + fas216_dumpstate(info); print_debug_list(); fas216_done(info, DID_ERROR); } -/* Function: void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr) - * Purpose : handle a function done interrupt from FAS216 chip - * Params : info - interface which caused function done interrupt - * stat - Status register contents - * ssr - SCSI Status register contents +/** + * fas216_funcdone_intr - handle a function done interrupt from FAS216 chip + * @info: interface which caused function done interrupt + * @stat: Status register contents + * @is: SCSI Status register contents + * + * Handle a function done interrupt from FAS216 chip */ -static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr) +static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int is) { - int status, message; + unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF; fas216_checkmagic(info); -#ifdef DEBUG_FUNCTIONDONE - printk("scsi%d.%c: function done: stat=%X ssr=%X phase=%02X\n", - info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase); -#endif + fas216_log(info, LOG_FUNCTIONDONE, + "function done: stat=%02x is=%02x phase=%02x", + stat, is, info->scsi.phase); + switch (info->scsi.phase) { case PHASE_STATUS: /* status phase - read status and msg */ - status = inb(REG_FF(info)); - message = inb(REG_FF(info)); - info->scsi.SCp.Message = message; - info->scsi.SCp.Status = status; + if (fifo_len != 2) { + fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len); + } + /* + * Read status then message byte. + */ + info->scsi.SCp.Status = fas216_readb(info, REG_FF); + info->scsi.SCp.Message = fas216_readb(info, REG_FF); info->scsi.phase = PHASE_DONE; - outb(CMD_MSGACCEPTED, REG_CMD(info)); + fas216_cmd(info, CMD_MSGACCEPTED); + break; + + case PHASE_IDLE: + case PHASE_SELECTION: + case PHASE_SELSTEPS: break; - case PHASE_IDLE: /* reselected? */ case PHASE_MSGIN: /* message in phase */ - case PHASE_RECONNECTED: /* reconnected command */ if ((stat & STAT_BUSMASK) == STAT_MESGIN) { - info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF; + info->scsi.msgin_fifo = fifo_len; fas216_message(info); break; } default: - printk("scsi%d.%c: internal phase %s for function done?" - " What do I do with this?\n", - info->host->host_no, fas216_target(info), + fas216_log(info, 0, "internal phase %s for function done?" + " What do I do with this?", fas216_drv_phase(info)); } } -/* Function: void fas216_intr(struct Scsi_Host *instance) - * Purpose : handle interrupts from the interface to progress a command - * Params : instance - interface to service +static void fas216_bus_reset(FAS216_Info *info) +{ + neg_t sync_state; + int i; + + msgqueue_flush(&info->scsi.msgs); + + sync_state = neg_invalid; + +#ifdef SCSI2_SYNC + if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA)) + sync_state = neg_wait; +#endif + + info->scsi.phase = PHASE_IDLE; + info->SCpnt = NULL; /* bug! */ + memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp)); + + for (i = 0; i < 8; i++) { + info->device[i].disconnect_ok = info->ifcfg.disconnect_ok; + info->device[i].sync_state = sync_state; + info->device[i].period = info->ifcfg.asyncperiod / 4; + info->device[i].stp = info->scsi.async_stp; + info->device[i].sof = 0; + info->device[i].wide_xfer = 0; + } + + info->rst_bus_status = 1; + wake_up(&info->eh_wait); +} + +/** + * fas216_intr - handle interrupts to progress a command + * @info: interface to service + * + * Handle interrupts from the interface to progress a command */ -void fas216_intr(struct Scsi_Host *instance) +void fas216_intr(FAS216_Info *info) { - FAS216_Info *info = (FAS216_Info *)instance->hostdata; - unsigned char isr, ssr, stat; + unsigned char inst, is, stat; fas216_checkmagic(info); - stat = inb(REG_STAT(info)); - ssr = inb(REG_IS(info)); - isr = inb(REG_INST(info)); + stat = fas216_readb(info, REG_STAT); + is = fas216_readb(info, REG_IS); + inst = fas216_readb(info, REG_INST); - add_debug_list(stat, ssr, isr, info->scsi.phase); + add_debug_list(stat, is, inst, info->scsi.phase); if (stat & STAT_INT) { - if (isr & INST_BUSRESET) { - printk(KERN_DEBUG "scsi%d.H: bus reset detected\n", instance->host_no); - scsi_report_bus_reset(instance, 0); - } else if (isr & INST_ILLEGALCMD) { - printk(KERN_CRIT "scsi%d.H: illegal command given\n", instance->host_no); + if (inst & INST_BUSRESET) { + fas216_log(info, 0, "bus reset detected"); + fas216_bus_reset(info); + scsi_report_bus_reset(info->host, 0); + } else if (inst & INST_ILLEGALCMD) { + fas216_log(info, LOG_ERROR, "illegal command given\n"); fas216_dumpstate(info); - } else if (isr & INST_DISCONNECT) + print_debug_list(); + } else if (inst & INST_DISCONNECT) fas216_disconnect_intr(info); - else if (isr & INST_RESELECTED) /* reselected */ + else if (inst & INST_RESELECTED) /* reselected */ fas216_reselected_intr(info); - else if (isr & INST_BUSSERVICE) /* bus service request */ - fas216_busservice_intr(info, stat, ssr); - else if (isr & INST_FUNCDONE) /* function done */ - fas216_funcdone_intr(info, stat, ssr); + else if (inst & INST_BUSSERVICE) /* bus service request */ + fas216_busservice_intr(info, stat, is); + else if (inst & INST_FUNCDONE) /* function done */ + fas216_funcdone_intr(info, stat, is); else - printk("scsi%d.%c: unknown interrupt received:" - " phase %s isr %02X ssr %02X stat %02X\n", - instance->host_no, fas216_target(info), - fas216_drv_phase(info), isr, ssr, stat); + fas216_log(info, 0, "unknown interrupt received:" + " phase %s inst %02X is %02X stat %02X", + fas216_drv_phase(info), inst, is, stat); } } -/* Function: void fas216_kick(FAS216_Info *info) - * Purpose : kick a command to the interface - interface should be idle - * Params : info - our host interface to kick - * Notes : Interrupts are always disabled! - */ -static void fas216_kick(FAS216_Info *info) +static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt) { - Scsi_Cmnd *SCpnt = NULL; - int tot_msglen, from_queue = 0, disconnect_ok; + int tot_msglen; - fas216_checkmagic(info); + /* following what the ESP driver says */ + fas216_set_stc(info, 0); + fas216_cmd(info, CMD_NOP | CMD_WITHDMA); - /* - * Obtain the next command to process. - */ - do { - if (info->reqSCpnt) { - SCpnt = info->reqSCpnt; - info->reqSCpnt = NULL; - break; - } + /* flush FIFO */ + fas216_cmd(info, CMD_FLUSHFIFO); - if (info->origSCpnt) { - SCpnt = info->origSCpnt; - info->origSCpnt = NULL; - break; + /* load bus-id and timeout */ + fas216_writeb(info, REG_SDID, BUSID(SCpnt->target)); + fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout); + + /* synchronous transfers */ + fas216_set_sync(info, SCpnt->target); + + tot_msglen = msgqueue_msglength(&info->scsi.msgs); + +#ifdef DEBUG_MESSAGES + { + struct message *msg; + int msgnr = 0, i; + + printk("scsi%d.%c: message out: ", + info->host->host_no, '0' + SCpnt->target); + while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) { + printk("{ "); + for (i = 0; i < msg->length; i++) + printk("%02x ", msg->msg[i]); + printk("} "); } + printk("\n"); + } +#endif - /* retrieve next command */ - if (!SCpnt) { - SCpnt = queue_remove_exclude(&info->queues.issue, - info->busyluns); - from_queue = 1; - break; + if (tot_msglen == 1 || tot_msglen == 3) { + /* + * We have an easy message length to send... + */ + struct message *msg; + int msgnr = 0, i; + + info->scsi.phase = PHASE_SELSTEPS; + + /* load message bytes */ + while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) { + for (i = 0; i < msg->length; i++) + fas216_writeb(info, REG_FF, msg->msg[i]); + msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF); } - } while (0); - if (!SCpnt) /* no command pending - just exit */ - return; + /* load command */ + for (i = 0; i < SCpnt->cmd_len; i++) + fas216_writeb(info, REG_FF, SCpnt->cmnd[i]); - if (info->scsi.disconnectable && info->SCpnt) { - queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt); - info->scsi.disconnectable = 0; - info->SCpnt = NULL; - printk("scsi%d.%c: moved command to disconnected queue\n", - info->host->host_no, fas216_target(info)); + if (tot_msglen == 1) + fas216_cmd(info, CMD_SELECTATN); + else + fas216_cmd(info, CMD_SELECTATN3); + } else { + /* + * We have an unusual number of message bytes to send. + * Load first byte into fifo, and issue SELECT with ATN and + * stop steps. + */ + struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0); + + fas216_writeb(info, REG_FF, msg->msg[0]); + msg->fifo = 1; + + fas216_cmd(info, CMD_SELECTATNSTOP); } +} + +/* + * Decide whether we need to perform a parity test on this device. + * Can also be used to force parity error conditions during initial + * information transfer phase (message out) for test purposes. + */ +static int parity_test(FAS216_Info *info, int target) +{ +#if 0 + if (target == 3) { + info->device[target].parity_check = 0; + return 1; + } +#endif + return info->device[target].parity_check; +} + +static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt) +{ + int disconnect_ok; /* * claim host busy */ info->scsi.phase = PHASE_SELECTION; - info->SCpnt = SCpnt; info->scsi.SCp = SCpnt->SCp; + info->SCpnt = SCpnt; info->dma.transfer_type = fasdma_none; -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: starting cmd %02X", - info->host->host_no, '0' + SCpnt->target, - SCpnt->cmnd[0]); -#endif - - if (from_queue) { -#ifdef SCSI2_TAG - /* - * tagged queuing - allocate a new tag to this command - */ - if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE && - SCpnt->cmnd[0] != INQUIRY) { - SCpnt->device->current_tag += 1; - if (SCpnt->device->current_tag == 0) - SCpnt->device->current_tag = 1; - SCpnt->tag = SCpnt->device->current_tag; - } else -#endif - set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns); - - info->stats.removes += 1; - switch (SCpnt->cmnd[0]) { - case WRITE_6: - case WRITE_10: - case WRITE_12: - info->stats.writes += 1; - break; - case READ_6: - case READ_10: - case READ_12: - info->stats.reads += 1; - break; - default: - info->stats.miscs += 1; - break; - } - } + if (parity_test(info, SCpnt->target)) + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE); + else + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); /* * Don't allow request sense commands to disconnect. @@ -1714,15 +1752,6 @@ msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag); do { -#ifdef SCSI2_WIDE - if (info->device[SCpnt->target].wide_state == neg_wait) { - info->device[SCpnt->target].wide_state = neg_inprogress; - msgqueue_addmsg(&info->scsi.msgs, 4, - EXTENDED_MESSAGE, 2, EXTENDED_WDTR, - info->ifcfg.wide_max_size); - break; - } -#endif #ifdef SCSI2_SYNC if ((info->device[SCpnt->target].sync_state == neg_wait || info->device[SCpnt->target].sync_state == neg_complete) && @@ -1738,100 +1767,202 @@ #endif } while (0); + __fas216_start_command(info, SCpnt); +} + +static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt) +{ +#ifdef SCSI2_TAG + /* + * tagged queuing - allocate a new tag to this command + */ + if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE && + SCpnt->cmnd[0] != INQUIRY) { + SCpnt->device->current_tag += 1; + if (SCpnt->device->current_tag == 0) + SCpnt->device->current_tag = 1; + SCpnt->tag = SCpnt->device->current_tag; + } else +#endif + set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns); + + info->stats.removes += 1; + switch (SCpnt->cmnd[0]) { + case WRITE_6: + case WRITE_10: + case WRITE_12: + info->stats.writes += 1; + break; + case READ_6: + case READ_10: + case READ_12: + info->stats.reads += 1; + break; + default: + info->stats.miscs += 1; + break; + } +} + +static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt) +{ + struct message *msg; + + /* + * claim host busy + */ + info->scsi.phase = PHASE_SELECTION; + info->scsi.SCp = SCpnt->SCp; + info->SCpnt = SCpnt; + info->dma.transfer_type = fasdma_none; + + fas216_log(info, LOG_ERROR, "sending bus device reset"); + + msgqueue_flush(&info->scsi.msgs); + msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET); + /* following what the ESP driver says */ - outb(0, REG_STCL(info)); - outb(0, REG_STCM(info)); - outb(0, REG_STCH(info)); - outb(CMD_NOP | CMD_WITHDMA, REG_CMD(info)); + fas216_set_stc(info, 0); + fas216_cmd(info, CMD_NOP | CMD_WITHDMA); /* flush FIFO */ - outb(CMD_FLUSHFIFO, REG_CMD(info)); + fas216_cmd(info, CMD_FLUSHFIFO); /* load bus-id and timeout */ - outb(BUSID(SCpnt->target), REG_SDID(info)); - outb(info->ifcfg.select_timeout, REG_STIM(info)); + fas216_writeb(info, REG_SDID, BUSID(SCpnt->target)); + fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout); /* synchronous transfers */ fas216_set_sync(info, SCpnt->target); - tot_msglen = msgqueue_msglength(&info->scsi.msgs); + msg = msgqueue_getmsg(&info->scsi.msgs, 0); -#ifdef DEBUG_MESSAGES - { - struct message *msg; - int msgnr = 0, i; + fas216_writeb(info, REG_FF, BUS_DEVICE_RESET); + msg->fifo = 1; - printk("scsi%d.%c: message out: ", - info->host->host_no, '0' + SCpnt->target); - while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) { - printk("{ "); - for (i = 0; i < msg->length; i++) - printk("%02x ", msg->msg[i]); - printk("} "); + fas216_cmd(info, CMD_SELECTATNSTOP); +} + +/** + * fas216_kick - kick a command to the interface + * @info: our host interface to kick + * + * Kick a command to the interface, interface should be idle. + * Notes: Interrupts are always disabled! + */ +static void fas216_kick(FAS216_Info *info) +{ + Scsi_Cmnd *SCpnt = NULL; +#define TYPE_OTHER 0 +#define TYPE_RESET 1 +#define TYPE_QUEUE 2 + int where_from = TYPE_OTHER; + + fas216_checkmagic(info); + + /* + * Obtain the next command to process. + */ + do { + if (info->rstSCpnt) { + SCpnt = info->rstSCpnt; + /* don't remove it */ + where_from = TYPE_RESET; + break; } - printk("\n"); - } -#endif - if (tot_msglen == 1 || tot_msglen == 3) { - /* - * We have an easy message length to send... - */ - struct message *msg; - int msgnr = 0, i; + if (info->reqSCpnt) { + SCpnt = info->reqSCpnt; + info->reqSCpnt = NULL; + break; + } - info->scsi.phase = PHASE_SELSTEPS; + if (info->origSCpnt) { + SCpnt = info->origSCpnt; + info->origSCpnt = NULL; + break; + } - /* load message bytes */ - while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) { - for (i = 0; i < msg->length; i++) - outb(msg->msg[i], REG_FF(info)); - msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF); + /* retrieve next command */ + if (!SCpnt) { + SCpnt = queue_remove_exclude(&info->queues.issue, + info->busyluns); + where_from = TYPE_QUEUE; + break; } + } while (0); - /* load command */ - for (i = 0; i < SCpnt->cmd_len; i++) - outb(SCpnt->cmnd[i], REG_FF(info)); - - if (tot_msglen == 1) - outb(CMD_SELECTATN, REG_CMD(info)); - else - outb(CMD_SELECTATN3, REG_CMD(info)); - } else { + if (!SCpnt) { /* - * We have an unusual number of message bytes to send. - * Load first byte into fifo, and issue SELECT with ATN and - * stop steps. + * no command pending, so enable reselection. */ - struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0); + fas216_cmd(info, CMD_ENABLESEL); + return; + } - outb(msg->msg[0], REG_FF(info)); - msg->fifo = 1; + /* + * We're going to start a command, so disable reselection + */ + fas216_cmd(info, CMD_DISABLESEL); + + if (info->scsi.disconnectable && info->SCpnt) { + fas216_log(info, LOG_CONNECT, + "moved command for %d to disconnected queue", + info->SCpnt->target); + queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt); + info->scsi.disconnectable = 0; + info->SCpnt = NULL; + } - outb(CMD_SELECTATNSTOP, REG_CMD(info)); + fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt, "starting "); + + switch (where_from) { + case TYPE_QUEUE: + fas216_allocate_tag(info, SCpnt); + case TYPE_OTHER: + fas216_start_command(info, SCpnt); + break; + case TYPE_RESET: + fas216_do_bus_device_reset(info, SCpnt); + break; } -#ifdef DEBUG_CONNECT - printk(", data pointers [%p, %X]\n", + fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]", info->scsi.SCp.ptr, info->scsi.SCp.this_residual); -#endif - /* should now get either DISCONNECT or (FUNCTION DONE with BUS SERVICE) intr */ + + /* + * should now get either DISCONNECT or + * (FUNCTION DONE with BUS SERVICE) interrupt + */ +} + +/* + * Clean up from issuing a BUS DEVICE RESET message to a device. + */ +static void +fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result) +{ + fas216_log(info, LOG_ERROR, "fas216 device reset complete"); + + info->rstSCpnt = NULL; + info->rst_dev_status = 1; + wake_up(&info->eh_wait); } -/* Function: void fas216_rq_sns_done(info, SCpnt, result) - * Purpose : Finish processing automatic request sense command - * Params : info - interface that completed - * SCpnt - command that completed - * result - driver byte of result +/** + * fas216_rq_sns_done - Finish processing automatic request sense command + * @info: interface that completed + * @SCpnt: command that completed + * @result: driver byte of result + * + * Finish processing automatic request sense command */ static void fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result) { -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: request sense complete, result=%04X%02X%02X\n", - info->host->host_no, '0' + SCpnt->target, result, - SCpnt->SCp.Message, SCpnt->SCp.Status); -#endif + fas216_log_target(info, LOG_CONNECT, SCpnt->target, + "request sense complete, result=0x%04x%02x%02x", + result, SCpnt->SCp.Message, SCpnt->SCp.Status); if (result != DID_OK || SCpnt->SCp.Status != GOOD) /* @@ -1840,7 +1971,8 @@ * confuse the higher levels. */ memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer)); - +//printk("scsi%d.%c: sense buffer: ", info->host->host_no, '0' + SCpnt->target); +//{ int i; for (i = 0; i < 32; i++) printk("%02x ", SCpnt->sense_buffer[i]); printk("\n"); } /* * Note that we don't set SCpnt->result, since that should * reflect the status of the command that we were asked by @@ -1850,11 +1982,13 @@ SCpnt->scsi_done(SCpnt); } -/* Function: void fas216_std_done(info, SCpnt, result) - * Purpose : Finish processing of standard command - * Params : info - interface that completed - * SCpnt - command that completed - * result - driver byte of result +/** + * fas216_std_done - finish processing of standard command + * @info: interface that completed + * @SCpnt: command that completed + * @result: driver byte of result + * + * Finish processing of standard command */ static void fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result) @@ -1864,31 +1998,29 @@ SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 | info->scsi.SCp.Status; -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: command complete, result=%08X, command=", - info->host->host_no, '0' + SCpnt->target, SCpnt->result); - print_command(SCpnt->cmnd); -#endif + fas216_log_command(info, LOG_CONNECT, SCpnt, + "command complete, result=0x%08x ", SCpnt->result); /* - * If the driver detected an error, or the command - * was request sense, then we're all done. + * If the driver detected an error, we're all done. */ - if (result != DID_OK || SCpnt->cmnd[0] == REQUEST_SENSE) + if (host_byte(SCpnt->result) != DID_OK || + msg_byte(SCpnt->result) != COMMAND_COMPLETE) goto done; /* - * If the command returned CHECK_CONDITION status, - * request the sense information. + * If the command returned CHECK_CONDITION or COMMAND_TERMINATED + * status, request the sense information. */ - if (info->scsi.SCp.Status == CHECK_CONDITION) + if (status_byte(SCpnt->result) == CHECK_CONDITION || + status_byte(SCpnt->result) == COMMAND_TERMINATED) goto request_sense; /* * If the command did not complete with GOOD status, * we are all done here. */ - if (info->scsi.SCp.Status != GOOD) + if (status_byte(SCpnt->result) != GOOD) goto done; /* @@ -1902,24 +2034,38 @@ switch (SCpnt->cmnd[0]) { case INQUIRY: case START_STOP: -// case READ_CAPACITY: case MODE_SENSE: break; default: printk(KERN_ERR "scsi%d.%c: incomplete data transfer " - "detected: res=%08X ptr=%p len=%X command=", + "detected: res=%08X ptr=%p len=%X CDB: ", info->host->host_no, '0' + SCpnt->target, SCpnt->result, info->scsi.SCp.ptr, info->scsi.SCp.this_residual); print_command(SCpnt->cmnd); + SCpnt->result &= ~(255 << 16); + SCpnt->result |= DID_BAD_TARGET << 16; + goto request_sense; } } -done: SCpnt->scsi_done(SCpnt); - return; +done: + if (SCpnt->scsi_done) { + SCpnt->scsi_done(SCpnt); + return; + } + + panic("scsi%d.H: null scsi_done function in fas216_done", + info->host->host_no); + request_sense: + if (SCpnt->cmnd[0] == REQUEST_SENSE) + goto done; + + fas216_log_target(info, LOG_CONNECT, SCpnt->target, + "requesting sense"); memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd)); SCpnt->cmnd[0] = REQUEST_SENSE; SCpnt->cmnd[1] = SCpnt->lun << 5; @@ -1931,6 +2077,7 @@ SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer); SCpnt->SCp.Message = 0; SCpnt->SCp.Status = 0; + SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer); SCpnt->sc_data_direction = SCSI_DATA_READ; SCpnt->use_sg = 0; SCpnt->tag = 0; @@ -1947,15 +2094,18 @@ info->reqSCpnt = SCpnt; } -/* Function: void fas216_done(FAS216_Info *info, unsigned int result) - * Purpose : complete processing for current command - * Params : info - interface that completed - * result - driver byte of result +/** + * fas216_done - complete processing for current command + * @info: interface that completed + * @result: driver byte of result + * + * Complete processing for current command */ static void fas216_done(FAS216_Info *info, unsigned int result) { void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int); Scsi_Cmnd *SCpnt; + unsigned long flags; fas216_checkmagic(info); @@ -1966,12 +2116,8 @@ info->SCpnt = NULL; info->scsi.phase = PHASE_IDLE; - if (!SCpnt->scsi_done) - goto no_done; - if (info->scsi.aborting) { - printk("scsi%d.%c: uncaught abort - returning DID_ABORT\n", - info->host->host_no, fas216_target(info)); + fas216_log(info, 0, "uncaught abort - returning DID_ABORT"); result = DID_ABORT; info->scsi.aborting = 0; } @@ -1982,7 +2128,7 @@ */ if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) { printk("scsi%d.%c: zero bytes left to transfer, but " - "buffer pointer still valid: ptr=%p len=%08x command=", + "buffer pointer still valid: ptr=%p len=%08x CDB: ", info->host->host_no, '0' + SCpnt->target, info->scsi.SCp.ptr, info->scsi.SCp.this_residual); info->scsi.SCp.ptr = NULL; @@ -1994,29 +2140,33 @@ * the sense information, fas216_kick will re-assert the busy * status. */ + info->device[SCpnt->target].parity_check = 0; clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns); fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble; fn(info, SCpnt, result); - if (info->scsi.irq != NO_IRQ) - fas216_kick(info); + if (info->scsi.irq != NO_IRQ) { + spin_lock_irqsave(&info->host_lock, flags); + if (info->scsi.phase == PHASE_IDLE) + fas216_kick(info); + spin_unlock_irqrestore(&info->host_lock, flags); + } return; no_command: panic("scsi%d.H: null command in fas216_done", info->host->host_no); -no_done: - panic("scsi%d.H: null scsi_done function in fas216_done", - info->host->host_no); } -/* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) - * Purpose : queue a command for adapter to process. - * Params : SCpnt - Command to queue - * done - done function to call once command is complete - * Returns : 0 - success, else error - * Notes : io_request_lock is held, interrupts are disabled. +/** + * fas216_queue_command - queue a command for adapter to process. + * @SCpnt: Command to queue + * @done: done function to call once command is complete + * + * Queue a command for adapter to process. + * Returns: 0 on success, else error. + * Notes: io_request_lock is held, interrupts are disabled. */ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { @@ -2025,61 +2175,20 @@ fas216_checkmagic(info); -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: received queuable command (%p) %02X\n", - SCpnt->host->host_no, '0' + SCpnt->target, - SCpnt, SCpnt->cmnd[0]); -#endif + fas216_log_command(info, LOG_CONNECT, SCpnt, + "received command (%p) ", SCpnt); SCpnt->scsi_done = done; SCpnt->host_scribble = (void *)fas216_std_done; SCpnt->result = 0; - SCpnt->SCp.Message = 0; - SCpnt->SCp.Status = 0; - - if (SCpnt->use_sg) { - unsigned long len = 0; - int buf; - - SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer; - SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; - SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address; - SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; - /* - * Calculate correct buffer length. Some commands - * come in with the wrong request_bufflen. - */ - for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++) - len += SCpnt->SCp.buffer[buf].length; - - if (SCpnt->request_bufflen != len) - printk(KERN_WARNING "scsi%d.%c: bad request buffer " - "length %d, should be %ld\n", info->host->host_no, - '0' + SCpnt->target, SCpnt->request_bufflen, len); - SCpnt->request_bufflen = len; - } else { - SCpnt->SCp.buffer = NULL; - SCpnt->SCp.buffers_residual = 0; - SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer; - SCpnt->SCp.this_residual = SCpnt->request_bufflen; - } - /* - * If the upper SCSI layers pass a buffer, but zero length, - * we aren't interested in the buffer pointer. - */ - if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) { -#if 0 - printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for " - "command ", info->host->host_no, '0' + SCpnt->target); - print_command(SCpnt->cmnd); -#endif - SCpnt->SCp.ptr = NULL; - } + init_SCp(SCpnt); info->stats.queues += 1; SCpnt->tag = 0; + spin_lock(&info->host_lock); + /* * Add command into execute queue and let it complete under * whatever scheme we're using. @@ -2090,15 +2199,21 @@ * If we successfully added the command, * kick the interface to get it moving. */ - if (result == 0 && (!info->SCpnt || info->scsi.disconnectable)) + if (result == 0 && info->scsi.phase == PHASE_IDLE) fas216_kick(info); + spin_unlock(&info->host_lock); + + fas216_log_target(info, LOG_CONNECT, -1, "queue %s", + result ? "failure" : "success"); return result; } -/* Function: void fas216_internal_done(Scsi_Cmnd *SCpnt) - * Purpose : trigger restart of a waiting thread in fas216_command - * Params : SCpnt - Command to wake +/** + * fas216_internal_done - trigger restart of a waiting thread in fas216_command + * @SCpnt: Command to wake + * + * Trigger restart of a waiting thread in fas216_command */ static void fas216_internal_done(Scsi_Cmnd *SCpnt) { @@ -2109,11 +2224,13 @@ info->internal_done = 1; } -/* Function: int fas216_command(Scsi_Cmnd *SCpnt) - * Purpose : queue a command for adapter to process. - * Params : SCpnt - Command to queue - * Returns : scsi result code - * Notes : io_request_lock is held, interrupts are disabled. +/** + * fas216_command - queue a command for adapter to process. + * @SCpnt: Command to queue + * + * Queue a command for adapter to process. + * Returns: scsi result code. + * Notes: io_request_lock is held, interrupts are disabled. */ int fas216_command(Scsi_Cmnd *SCpnt) { @@ -2125,8 +2242,7 @@ * We should only be using this if we don't have an interrupt. * Provide some "incentive" to use the queueing code. */ - if (info->scsi.irq != NO_IRQ) - BUG(); + BUG_ON(info->scsi.irq != NO_IRQ); info->internal_done = 0; fas216_queue_command(SCpnt, fas216_internal_done); @@ -2148,9 +2264,9 @@ * and go to sleep if we know that the device is going * to be some time (eg, disconnected). */ - if (inb(REG_STAT(info)) & STAT_INT) { + if (fas216_readb(info, REG_STAT) & STAT_INT) { spin_lock_irq(&io_request_lock); - fas216_intr(info->host); + fas216_intr(info); spin_unlock_irq(&io_request_lock); } } @@ -2160,23 +2276,42 @@ return SCpnt->result; } -enum res_abort { - res_failed, /* unable to abort */ +/* + * Error handler timeout function. Indicate that we timed out, + * and wake up any error handler process so it can continue. + */ +static void fas216_eh_timer(unsigned long data) +{ + FAS216_Info *info = (FAS216_Info *)data; + + fas216_log(info, LOG_ERROR, "error handling timed out\n"); + + del_timer(&info->eh_timer); + + if (info->rst_bus_status == 0) + info->rst_bus_status = -1; + if (info->rst_dev_status == 0) + info->rst_dev_status = -1; + + wake_up(&info->eh_wait); +} + +enum res_find { + res_failed, /* not found */ res_success, /* command on issue queue */ - res_success_clear, /* command marked tgt/lun busy */ res_hw_abort /* command on disconnected dev */ }; -/* - * Prototype: enum res_abort fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt) - * Purpose : decide how to abort a command - * Params : SCpnt - command to abort - * Returns : abort status +/** + * fas216_do_abort - decide how to abort a command + * @SCpnt: command to abort + * + * Decide how to abort a command. + * Returns: abort status */ -static enum res_abort -fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt) +static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt) { - enum res_abort res = res_failed; + enum res_find res = res_failed; if (queue_remove_cmd(&info->queues.issue, SCpnt)) { /* @@ -2224,19 +2359,22 @@ * been set. */ info->origSCpnt = NULL; + clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns); printk("waiting for execution "); - res = res_success_clear; + res = res_success; } else printk("unknown "); return res; } -/* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt) - * Purpose : abort this command - * Params : SCpnt - command to abort - * Returns : FAILED if unable to abort - * Notes : io_request_lock is taken, and irqs are disabled +/** + * fas216_eh_abort - abort this command + * @SCpnt: command to abort + * + * Abort this command. + * Returns: FAILED if unable to abort + * Notes: io_request_lock is taken, and irqs are disabled */ int fas216_eh_abort(Scsi_Cmnd *SCpnt) { @@ -2247,22 +2385,15 @@ info->stats.aborts += 1; + printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no); + print_command(SCpnt->data_cmnd); + print_debug_list(); fas216_dumpstate(info); - fas216_dumpinfo(info); - printk(KERN_WARNING "scsi%d: abort ", info->host->host_no); - - switch (fas216_do_abort(info, SCpnt)) { - /* - * We managed to find the command and cleared it out. - * We do not expect the command to be executing on the - * target, but we have set the busylun bit. - */ - case res_success_clear: - printk("clear "); - clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns); + printk(KERN_WARNING "scsi%d: abort %p ", info->host->host_no, SCpnt); + switch (fas216_find_command(info, SCpnt)) { /* * We found the command, and cleared it out. Either * the command is still known to be executing on the @@ -2293,155 +2424,195 @@ return result; } -/* Function: void fas216_reset_state(FAS216_Info *info) - * Purpose : Initialise driver internal state - * Params : info - state to initialise +/** + * fas216_eh_device_reset - Reset the device associated with this command + * @SCpnt: command specifing device to reset + * + * Reset the device associated with this command. + * Returns: FAILED if unable to reset. + * Notes: We won't be re-entered, so we'll only have one device + * reset on the go at one time. */ -static void fas216_reset_state(FAS216_Info *info) +int fas216_eh_device_reset(Scsi_Cmnd *SCpnt) { - neg_t sync_state, wide_state; - int i; + FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata; + unsigned long flags; + int i, res = FAILED, target = SCpnt->target; - fas216_checkmagic(info); + fas216_log(info, LOG_ERROR, "device reset for target %d", target); - /* - * Clear out all stale info in our state structure - */ - memset(info->busyluns, 0, sizeof(info->busyluns)); - msgqueue_flush(&info->scsi.msgs); - info->scsi.reconnected.target = 0; - info->scsi.reconnected.lun = 0; - info->scsi.reconnected.tag = 0; - info->scsi.disconnectable = 0; - info->scsi.aborting = 0; - info->scsi.phase = PHASE_IDLE; - info->scsi.async_stp = - fas216_syncperiod(info, info->ifcfg.asyncperiod); + spin_lock_irqsave(&info->host_lock, flags); - if (info->ifcfg.wide_max_size == 0) - wide_state = neg_invalid; - else -#ifdef SCSI2_WIDE - wide_state = neg_wait; -#else - wide_state = neg_invalid; -#endif + do { + /* + * If we are currently connected to a device, and + * it is the device we want to reset, there is + * nothing we can do here. Chances are it is stuck, + * and we need a bus reset. + */ + if (info->SCpnt && !info->scsi.disconnectable && + info->SCpnt->target == SCpnt->target) + break; - if (info->host->dma_channel == NO_DMA || !info->dma.setup) - sync_state = neg_invalid; - else -#ifdef SCSI2_SYNC - sync_state = neg_wait; -#else - sync_state = neg_invalid; -#endif + /* + * We're going to be resetting this device. Remove + * all pending commands from the driver. By doing + * so, we guarantee that we won't touch the command + * structures except to process the reset request. + */ + queue_remove_all_target(&info->queues.issue, target); + queue_remove_all_target(&info->queues.disconnected, target); + if (info->origSCpnt && info->origSCpnt->target == target) + info->origSCpnt = NULL; + if (info->reqSCpnt && info->reqSCpnt->target == target) + info->reqSCpnt = NULL; + for (i = 0; i < 8; i++) + clear_bit(target * 8 + i, info->busyluns); - for (i = 0; i < 8; i++) { - info->device[i].disconnect_ok = info->ifcfg.disconnect_ok; - info->device[i].sync_state = sync_state; - info->device[i].wide_state = wide_state; - info->device[i].period = info->ifcfg.asyncperiod / 4; - info->device[i].stp = info->scsi.async_stp; - info->device[i].sof = 0; - info->device[i].wide_xfer = 0; - } + /* + * Hijack this SCSI command structure to send + * a bus device reset message to this device. + */ + SCpnt->host_scribble = (void *)fas216_devicereset_done; - /* - * Drain all commands on disconnected queue - */ - while (queue_remove(&info->queues.disconnected) != NULL); + info->rst_dev_status = 0; + info->rstSCpnt = SCpnt; - /* - * Remove executing commands. - */ - info->SCpnt = NULL; - info->reqSCpnt = NULL; - info->origSCpnt = NULL; -} + if (info->scsi.phase == PHASE_IDLE) + fas216_kick(info); -/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt) - * Purpose : Reset the device associated with this command - * Params : SCpnt - command specifing device to reset - * Returns : FAILED if unable to reset - */ -int fas216_eh_device_reset(Scsi_Cmnd *SCpnt) -{ - FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata; + mod_timer(&info->eh_timer, 30 * HZ); + spin_unlock_irqrestore(&info->host_lock, flags); + + /* + * Wait up to 30 seconds for the reset to complete. + */ + wait_event(info->eh_wait, info->rst_dev_status); + + del_timer_sync(&info->eh_timer); + spin_lock_irqsave(&info->host_lock, flags); + info->rstSCpnt = NULL; + + if (info->rst_dev_status == 1) + res = SUCCESS; + } while (0); + + SCpnt->host_scribble = NULL; + spin_unlock_irqrestore(&info->host_lock, flags); + + fas216_log(info, LOG_ERROR, "device reset complete: %s\n", + res == SUCCESS ? "success" : "failed"); - printk("scsi%d.%c: "__FUNCTION__": called\n", - info->host->host_no, '0' + SCpnt->target); - return FAILED; + return res; } -/* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt) - * Purpose : Reset the bus associated with the command - * Params : SCpnt - command specifing bus to reset - * Returns : FAILED if unable to reset - * Notes : io_request_lock is taken, and irqs are disabled +/** + * fas216_eh_bus_reset - Reset the bus associated with the command + * @SCpnt: command specifing bus to reset + * + * Reset the bus associated with the command. + * Returns: FAILED if unable to reset. + * Notes: Further commands are blocked. */ int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata; - int result = FAILED; + unsigned long flags; + Scsi_Device *SDpnt; fas216_checkmagic(info); + fas216_log(info, LOG_ERROR, "resetting bus"); info->stats.bus_resets += 1; - printk("scsi%d.%c: "__FUNCTION__": resetting bus\n", - info->host->host_no, '0' + SCpnt->target); + spin_lock_irqsave(&info->host_lock, flags); /* - * Attempt to stop all activity on this interface. + * Stop all activity on this interface. */ - outb(info->scsi.cfg[2], REG_CNTL3(info)); - fas216_stoptransfer(info); + fas216_aborttransfer(info); + fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]); /* - * Clear any pending interrupts + * Clear any pending interrupts. */ - while (inb(REG_STAT(info)) & STAT_INT) - inb(REG_INST(info)); + while (fas216_readb(info, REG_STAT) & STAT_INT) + fas216_readb(info, REG_INST); + + info->rst_bus_status = 0; /* - * Reset the SCSI bus + * For each attached hard-reset device, clear out + * all command structures. Leave the running + * command in place. */ - outb(CMD_RESETSCSI, REG_CMD(info)); - udelay(5); + for (SDpnt = info->host->host_queue; SDpnt; SDpnt = SDpnt->next) { + int i; + + if (SDpnt->soft_reset) + continue; + + queue_remove_all_target(&info->queues.issue, SDpnt->id); + queue_remove_all_target(&info->queues.disconnected, SDpnt->id); + if (info->origSCpnt && info->origSCpnt->target == SDpnt->id) + info->origSCpnt = NULL; + if (info->reqSCpnt && info->reqSCpnt->target == SDpnt->id) + info->reqSCpnt = NULL; + info->SCpnt = NULL; + + for (i = 0; i < 8; i++) + clear_bit(SDpnt->id * 8 + i, info->busyluns); + } + + info->scsi.phase = PHASE_IDLE; /* - * Clear reset interrupt + * Reset the SCSI bus. Device cleanup happens in + * the interrupt handler. */ - if (inb(REG_STAT(info)) & STAT_INT && - inb(REG_INST(info)) & INST_BUSRESET) - result = SUCCESS; + fas216_cmd(info, CMD_RESETSCSI); - fas216_reset_state(info); + mod_timer(&info->eh_timer, jiffies + HZ); + spin_unlock_irqrestore(&info->host_lock, flags); - return result; + /* + * Wait one second for the interrupt. + */ + wait_event(info->eh_wait, info->rst_bus_status); + del_timer_sync(&info->eh_timer); + + fas216_log(info, LOG_ERROR, "bus reset complete: %s\n", + info->rst_bus_status == 1 ? "success" : "failed"); + + return info->rst_bus_status == 1 ? SUCCESS : FAILED; } -/* Function: void fas216_init_chip(FAS216_Info *info) - * Purpose : Initialise FAS216 state after reset - * Params : info - state structure for interface +/** + * fas216_init_chip - Initialise FAS216 state after reset + * @info: state structure for interface + * + * Initialise FAS216 state after reset */ static void fas216_init_chip(FAS216_Info *info) { - outb(fas216_clockrate(info->ifcfg.clockrate), REG_CLKF(info)); - outb(info->scsi.cfg[0], REG_CNTL1(info)); - outb(info->scsi.cfg[1], REG_CNTL2(info)); - outb(info->scsi.cfg[2], REG_CNTL3(info)); - outb(info->ifcfg.select_timeout, REG_STIM(info)); - outb(0, REG_SOF(info)); - outb(info->scsi.async_stp, REG_STP(info)); - outb(info->scsi.cfg[0], REG_CNTL1(info)); + unsigned int clock = ((info->ifcfg.clockrate - 1) / 5 + 1) & 7; + fas216_writeb(info, REG_CLKF, clock); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); + fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]); + fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]); + fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout); + fas216_writeb(info, REG_SOF, 0); + fas216_writeb(info, REG_STP, info->scsi.async_stp); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); } -/* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt) - * Purpose : Reset the host associated with this command - * Params : SCpnt - command specifing host to reset - * Returns : FAILED if unable to reset - * Notes : io_request_lock is taken, and irqs are disabled +/** + * fas216_eh_host_reset - Reset the host associated with this command + * @SCpnt: command specifing host to reset + * + * Reset the host associated with this command. + * Returns: FAILED if unable to reset. + * Notes: io_request_lock is taken, and irqs are disabled */ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt) { @@ -2449,13 +2620,13 @@ fas216_checkmagic(info); - printk("scsi%d.%c: "__FUNCTION__": resetting host\n", - info->host->host_no, '0' + SCpnt->target); + printk("scsi%d.%c: %s: resetting host\n", + info->host->host_no, '0' + SCpnt->target, __FUNCTION__); /* * Reset the SCSI chip. */ - outb(CMD_RESETCHIP, REG_CMD(info)); + fas216_cmd(info, CMD_RESETCHIP); /* * Ugly ugly ugly! @@ -2464,13 +2635,13 @@ * IRQs after the sleep. */ spin_unlock_irq(&io_request_lock); - scsi_sleep(25*HZ/100); + scsi_sleep(50 * HZ/100); spin_lock_irq(&io_request_lock); /* * Release the SCSI reset. */ - outb(CMD_NOP, REG_CMD(info)); + fas216_cmd(info, CMD_NOP); fas216_init_chip(info); @@ -2502,56 +2673,56 @@ /* * Reset the chip. */ - outb(CMD_RESETCHIP, REG_CMD(info)); + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); udelay(50); - outb(CMD_NOP, REG_CMD(info)); + fas216_writeb(info, REG_CMD, CMD_NOP); /* * Check to see if control reg 2 is present. */ - outb(0, REG_CNTL3(info)); - outb(CNTL2_S2FE, REG_CNTL2(info)); + fas216_writeb(info, REG_CNTL3, 0); + fas216_writeb(info, REG_CNTL2, CNTL2_S2FE); /* * If we are unable to read back control reg 2 * correctly, it is not present, and we have a * NCR53C90. */ - if ((inb(REG_CNTL2(info)) & (~0xe0)) != CNTL2_S2FE) + if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE) return TYPE_NCR53C90; /* * Now, check control register 3 */ - outb(0, REG_CNTL2(info)); - outb(0, REG_CNTL3(info)); - outb(5, REG_CNTL3(info)); + fas216_writeb(info, REG_CNTL2, 0); + fas216_writeb(info, REG_CNTL3, 0); + fas216_writeb(info, REG_CNTL3, 5); /* * If we are unable to read the register back * correctly, we have a NCR53C90A */ - if (inb(REG_CNTL3(info)) != 5) + if (fas216_readb(info, REG_CNTL3) != 5) return TYPE_NCR53C90A; /* * Now read the ID from the chip. */ - outb(0, REG_CNTL3(info)); + fas216_writeb(info, REG_CNTL3, 0); - outb(CNTL3_ADIDCHK, REG_CNTL3(info)); - outb(0, REG_CNTL3(info)); + fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK); + fas216_writeb(info, REG_CNTL3, 0); - outb(CMD_RESETCHIP, REG_CMD(info)); - udelay(5); - outb(CMD_WITHDMA | CMD_NOP, REG_CMD(info)); + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); + udelay(50); + fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP); - outb(CNTL2_ENF, REG_CNTL2(info)); - outb(CMD_RESETCHIP, REG_CMD(info)); - udelay(5); - outb(CMD_NOP, REG_CMD(info)); + fas216_writeb(info, REG_CNTL2, CNTL2_ENF); + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); + udelay(50); + fas216_writeb(info, REG_CMD, CMD_NOP); - rev = inb(REG1_ID(info)); + rev = fas216_readb(info, REG_ID); family = rev >> 3; rev &= 7; @@ -2577,33 +2748,106 @@ return TYPE_NCR53C9x; } -/* Function: int fas216_init(struct Scsi_Host *instance) - * Purpose : initialise FAS/NCR/AMD SCSI ic. - * Params : instance - a driver-specific filled-out structure - * Returns : 0 on success +/** + * fas216_reset_state - Initialise driver internal state + * @info: state to initialise + * + * Initialise driver internal state */ -int fas216_init(struct Scsi_Host *instance) +static void fas216_reset_state(FAS216_Info *info) { - FAS216_Info *info = (FAS216_Info *)instance->hostdata; - int type; + int i; + + fas216_checkmagic(info); + + fas216_bus_reset(info); - info->magic_start = MAGIC; - info->magic_end = MAGIC; - info->host = instance; - info->scsi.cfg[0] = instance->this_id; - info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE; - info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB; + /* + * Clear out all stale info in our state structure + */ + memset(info->busyluns, 0, sizeof(info->busyluns)); + info->scsi.disconnectable = 0; + info->scsi.aborting = 0; + + for (i = 0; i < 8; i++) { + info->device[i].parity_enabled = 0; + info->device[i].parity_check = 1; + } + + /* + * Drain all commands on disconnected queue + */ + while (queue_remove(&info->queues.disconnected) != NULL); + + /* + * Remove executing commands. + */ + info->SCpnt = NULL; + info->reqSCpnt = NULL; + info->rstSCpnt = NULL; + info->origSCpnt = NULL; +} + +/** + * fas216_init - initialise FAS/NCR/AMD SCSI structures. + * @host: a driver-specific filled-out structure + * + * Initialise FAS/NCR/AMD SCSI structures. + * Returns: 0 on success + */ +int fas216_init(struct Scsi_Host *host) +{ + FAS216_Info *info = (FAS216_Info *)host->hostdata; + + info->magic_start = MAGIC; + info->magic_end = MAGIC; + info->host = host; + info->scsi.cfg[0] = host->this_id | CNTL1_PERE; + info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE; + info->scsi.cfg[2] = info->ifcfg.cntl3 | + CNTL3_ADIDCHK | CNTL3_QTAG | CNTL3_G2CB | CNTL3_LBTM; + info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod); + + info->rst_dev_status = -1; + info->rst_bus_status = -1; + init_waitqueue_head(&info->eh_wait); + init_timer(&info->eh_timer); + info->eh_timer.data = (unsigned long)info; + info->eh_timer.function = fas216_eh_timer; + + spin_lock_init(&info->host_lock); memset(&info->stats, 0, sizeof(info->stats)); msgqueue_initialise(&info->scsi.msgs); if (!queue_initialise(&info->queues.issue)) - return 1; + return -ENOMEM; if (!queue_initialise(&info->queues.disconnected)) { queue_free(&info->queues.issue); - return 1; + return -ENOMEM; + } + + return 0; +} + +/** + * fas216_add - initialise FAS/NCR/AMD SCSI ic. + * @host: a driver-specific filled-out structure + * + * Initialise FAS/NCR/AMD SCSI ic. + * Returns: 0 on success + */ +int fas216_add(struct Scsi_Host *host) +{ + FAS216_Info *info = (FAS216_Info *)host->hostdata; + int type; + + if (info->ifcfg.clockrate <= 10 || info->ifcfg.clockrate > 40) { + printk(KERN_CRIT "fas216: invalid clock rate %u MHz\n", + info->ifcfg.clockrate); + return -EINVAL; } fas216_reset_state(info); @@ -2622,78 +2866,53 @@ * the resulting reset interrupt, so mask it * out. */ - outb(info->scsi.cfg[0] | CNTL1_DISR, REG_CNTL1(info)); - outb(CMD_RESETSCSI, REG_CMD(info)); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR); + fas216_writeb(info, REG_CMD, CMD_RESETSCSI); /* * scsi standard says wait 250ms */ spin_unlock_irq(&io_request_lock); - scsi_sleep(25*HZ/100); + scsi_sleep(100*HZ/100); spin_lock_irq(&io_request_lock); - outb(info->scsi.cfg[0], REG_CNTL1(info)); - inb(REG_INST(info)); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); + fas216_readb(info, REG_INST); fas216_checkmagic(info); return 0; } -/* Function: int fas216_release(struct Scsi_Host *instance) - * Purpose : release all resources and put everything to bed for - * FAS/NCR/AMD SCSI ic. - * Params : instance - a driver-specific filled-out structure - * Returns : 0 on success - */ -int fas216_release(struct Scsi_Host *instance) +void fas216_remove(struct Scsi_Host *host) { - FAS216_Info *info = (FAS216_Info *)instance->hostdata; + FAS216_Info *info = (FAS216_Info *)host->hostdata; fas216_checkmagic(info); - outb(CMD_RESETCHIP, REG_CMD(info)); - queue_free(&info->queues.disconnected); - queue_free(&info->queues.issue); - - return 0; + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); } -/* - * Function: int fas216_info(FAS216_Info *info, char *buffer) - * Purpose : generate a string containing information about this - * host. - * Params : info - FAS216 host information - * buffer - string buffer to build string - * Returns : size of built string +/** + * fas216_release - release all resources for FAS/NCR/AMD SCSI ic. + * @host: a driver-specific filled-out structure + * + * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic. */ -int fas216_info(FAS216_Info *info, char *buffer) +void fas216_release(struct Scsi_Host *host) { - char *p = buffer; + FAS216_Info *info = (FAS216_Info *)host->hostdata; - p += sprintf(p, "(%s) at port 0x%08lX ", - info->scsi.type, info->host->io_port); - - if (info->host->irq != NO_IRQ) - p += sprintf(p, "irq %d ", info->host->irq); - else - p += sprintf(p, "no irq "); - - if (info->host->dma_channel != NO_DMA) - p += sprintf(p, "dma %d ", info->host->dma_channel); - else - p += sprintf(p, "no dma "); - - return p - buffer; + queue_free(&info->queues.disconnected); + queue_free(&info->queues.issue); } int fas216_print_host(FAS216_Info *info, char *buffer) { - return sprintf(buffer, "\n" "Chip : %s\n" - " Address: 0x%08lX\n" + " Address: 0x%08lx\n" " IRQ : %d\n" " DMA : %d\n", info->scsi.type, info->host->io_port, @@ -2702,8 +2921,9 @@ int fas216_print_stats(FAS216_Info *info, char *buffer) { - return sprintf(buffer, - "\n" + char *p = buffer; + + p += sprintf(p, "\n" "Command Statistics:\n" " Queued : %u\n" " Issued : %u\n" @@ -2720,6 +2940,8 @@ info->stats.writes, info->stats.miscs, info->stats.disconnects, info->stats.aborts, info->stats.bus_resets, info->stats.host_resets); + + return p - buffer; } int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer) @@ -2738,7 +2960,9 @@ scd->tagged_queue ? "en" : "dis", scd->current_tag); - p += sprintf(p, "\n Transfers : %d-bit ", + p += sprintf(p, "%s\n", dev->parity_enabled ? "parity" : ""); + + p += sprintf(p, " Transfers : %d-bit ", 8 << dev->wide_xfer); if (dev->sof) @@ -2750,11 +2974,12 @@ return p - buffer; } -EXPORT_SYMBOL(fas216_info); EXPORT_SYMBOL(fas216_init); +EXPORT_SYMBOL(fas216_add); EXPORT_SYMBOL(fas216_queue_command); EXPORT_SYMBOL(fas216_command); EXPORT_SYMBOL(fas216_intr); +EXPORT_SYMBOL(fas216_remove); EXPORT_SYMBOL(fas216_release); EXPORT_SYMBOL(fas216_eh_abort); EXPORT_SYMBOL(fas216_eh_device_reset); diff -urN linux-2.4.21/drivers/acorn/scsi/fas216.h linux-2.4.22/drivers/acorn/scsi/fas216.h --- linux-2.4.21/drivers/acorn/scsi/fas216.h 2000-09-18 15:15:22.000000000 -0700 +++ linux-2.4.22/drivers/acorn/scsi/fas216.h 2003-08-25 04:44:40.000000000 -0700 @@ -22,18 +22,18 @@ /* FAS register definitions */ /* transfer count low */ -#define REG_CTCL(x) ((x)->scsi.io_port) -#define REG_STCL(x) ((x)->scsi.io_port) +#define REG_CTCL (0) +#define REG_STCL (0) /* transfer count medium */ -#define REG_CTCM(x) ((x)->scsi.io_port + (1 << (x)->scsi.io_shift)) -#define REG_STCM(x) ((x)->scsi.io_port + (1 << (x)->scsi.io_shift)) +#define REG_CTCM (1) +#define REG_STCM (1) /* fifo data */ -#define REG_FF(x) ((x)->scsi.io_port + (2 << (x)->scsi.io_shift)) +#define REG_FF (2) /* command */ -#define REG_CMD(x) ((x)->scsi.io_port + (3 << (x)->scsi.io_shift)) +#define REG_CMD (3) #define CMD_NOP 0x00 #define CMD_FLUSHFIFO 0x01 #define CMD_RESETCHIP 0x02 @@ -57,7 +57,7 @@ #define CMD_WITHDMA 0x80 /* status register (read) */ -#define REG_STAT(x) ((x)->scsi.io_port + (4 << (x)->scsi.io_shift)) +#define REG_STAT (4) #define STAT_IO (1 << 0) /* IO phase */ #define STAT_CD (1 << 1) /* CD phase */ #define STAT_MSG (1 << 2) /* MSG phase */ @@ -76,11 +76,11 @@ #define STAT_MESGIN (STAT_MSG|STAT_CD|STAT_IO) /* Message In */ /* bus ID for select / reselect */ -#define REG_SDID(x) ((x)->scsi.io_port + (4 << (x)->scsi.io_shift)) +#define REG_SDID (4) #define BUSID(target) ((target) & 7) /* Interrupt status register (read) */ -#define REG_INST(x) ((x)->scsi.io_port + (5 << (x)->scsi.io_shift)) +#define REG_INST (5) #define INST_SELWOATN (1 << 0) /* Select w/o ATN */ #define INST_SELATN (1 << 1) /* Select w/ATN */ #define INST_RESELECTED (1 << 2) /* Reselected */ @@ -91,10 +91,10 @@ #define INST_BUSRESET (1 << 7) /* SCSI Bus reset */ /* Timeout register (write) */ -#define REG_STIM(x) ((x)->scsi.io_port + (5 << (x)->scsi.io_shift)) +#define REG_STIM (5) /* Sequence step register (read) */ -#define REG_IS(x) ((x)->scsi.io_port + (6 << (x)->scsi.io_shift)) +#define REG_IS (6) #define IS_BITS 0x07 #define IS_SELARB 0x00 /* Select & Arb ok */ #define IS_MSGBYTESENT 0x01 /* One byte message sent*/ @@ -104,18 +104,18 @@ #define IS_SOF 0x08 /* Sync off flag */ /* Transfer period step (write) */ -#define REG_STP(x) ((x)->scsi.io_port + (6 << (x)->scsi.io_shift)) +#define REG_STP (6) /* Synchronous Offset (write) */ -#define REG_SOF(x) ((x)->scsi.io_port + (7 << (x)->scsi.io_shift)) +#define REG_SOF (7) /* Fifo state register (read) */ -#define REG_CFIS(x) ((x)->scsi.io_port + (7 << (x)->scsi.io_shift)) +#define REG_CFIS (7) #define CFIS_CF 0x1f /* Num bytes in FIFO */ #define CFIS_IS 0xe0 /* Step */ /* config register 1 */ -#define REG_CNTL1(x) ((x)->scsi.io_port + (8 << (x)->scsi.io_shift)) +#define REG_CNTL1 (8) #define CNTL1_CID (7 << 0) /* Chip ID */ #define CNTL1_STE (1 << 3) /* Self test enable */ #define CNTL1_PERE (1 << 4) /* Parity enable reporting en. */ @@ -124,7 +124,7 @@ #define CNTL1_ETM (1 << 7) /* Extended Timing Mode */ /* Clock conversion factor (read) */ -#define REG_CLKF(x) ((x)->scsi.io_port + (9 << (x)->scsi.io_shift)) +#define REG_CLKF (9) #define CLKF_F37MHZ 0x00 /* 35.01 - 40 MHz */ #define CLKF_F10MHZ 0x02 /* 10 MHz */ #define CLKF_F12MHZ 0x03 /* 10.01 - 15 MHz */ @@ -134,13 +134,13 @@ #define CLKF_F32MHZ 0x07 /* 30.01 - 35 MHz */ /* Chip test register (write) */ -#define REG0_FTM(x) ((x)->scsi.io_port + (10 << (x)->scsi.io_shift)) +#define REG_FTM (10) #define TEST_FTM 0x01 /* Force target mode */ #define TEST_FIM 0x02 /* Force initiator mode */ #define TEST_FHI 0x04 /* Force high impedance mode */ /* Configuration register 2 (read/write) */ -#define REG_CNTL2(x) ((x)->scsi.io_port + (11 << (x)->scsi.io_shift)) +#define REG_CNTL2 (11) #define CNTL2_PGDP (1 << 0) /* Pass Th/Generate Data Parity */ #define CNTL2_PGRP (1 << 1) /* Pass Th/Generate Reg Parity */ #define CNTL2_ACDPE (1 << 2) /* Abort on Cmd/Data Parity Err */ @@ -151,7 +151,7 @@ #define CNTL2_DAE (1 << 7) /* Data Alignment Enable */ /* Configuration register 3 (read/write) */ -#define REG_CNTL3(x) ((x)->scsi.io_port + (12 << (x)->scsi.io_shift)) +#define REG_CNTL3 (12) #define CNTL3_BS8 (1 << 0) /* Burst size 8 */ #define CNTL3_MDM (1 << 1) /* Modify DMA mode */ #define CNTL3_LBTM (1 << 2) /* Last Byte Transfer mode */ @@ -162,14 +162,14 @@ #define CNTL3_ADIDCHK (1 << 7) /* Additional ID check */ /* High transfer count (read/write) */ -#define REG_CTCH(x) ((x)->scsi.io_port + (14 << (x)->scsi.io_shift)) -#define REG_STCH(x) ((x)->scsi.io_port + (14 << (x)->scsi.io_shift)) +#define REG_CTCH (14) +#define REG_STCH (14) -/* ID reigster (read only) */ -#define REG1_ID(x) ((x)->scsi.io_port + (14 << (x)->scsi.io_shift)) +/* ID register (read only) */ +#define REG_ID (14) /* Data alignment */ -#define REG0_DAL(x) ((x)->scsi.io_port + (15 << (x)->scsi.io_shift)) +#define REG_DAL (15) typedef enum { PHASE_IDLE, /* we're not planning on doing anything */ @@ -177,7 +177,6 @@ PHASE_SELSTEPS, /* selection with command steps */ PHASE_COMMAND, /* command sent */ PHASE_MESSAGESENT, /* selected, and we're sending cmd */ - PHASE_RECONNECTED, /* reconnected */ PHASE_DATAOUT, /* data out to device */ PHASE_DATAIN, /* data in from device */ PHASE_MSGIN, /* message in from device */ @@ -212,27 +211,36 @@ #define MAGIC 0x441296bdUL #define NR_MSGS 8 +#define FASCAP_DMA (1 << 0) +#define FASCAP_PSEUDODMA (1 << 1) + typedef struct { unsigned long magic_start; + spinlock_t host_lock; struct Scsi_Host *host; /* host */ Scsi_Cmnd *SCpnt; /* currently processing command */ Scsi_Cmnd *origSCpnt; /* original connecting command */ Scsi_Cmnd *reqSCpnt; /* request sense command */ + Scsi_Cmnd *rstSCpnt; /* reset command */ + Scsi_Cmnd *pending_SCpnt[8]; /* per-device pending commands */ + int next_pending; /* next pending device */ + + /* + * Error recovery + */ + wait_queue_head_t eh_wait; + struct timer_list eh_timer; + unsigned int rst_dev_status; + unsigned int rst_bus_status; /* driver information */ struct { + phase_t phase; /* current phase */ unsigned int io_port; /* base address of FAS216 */ unsigned int io_shift; /* shift to adjust reg offsets by */ - unsigned int irq; /* interrupt */ unsigned char cfg[4]; /* configuration registers */ const char *type; /* chip type */ - phase_t phase; /* current phase */ - - struct { - unsigned char target; /* reconnected target */ - unsigned char lun; /* reconnected lun */ - unsigned char tag; /* reconnected tag */ - } reconnected; + unsigned int irq; /* interrupt */ Scsi_Pointer SCp; /* current commands data pointer */ @@ -241,7 +249,6 @@ unsigned int async_stp; /* Async transfer STP value */ unsigned char msgin_fifo; /* bytes in fifo at time of message in */ unsigned char message[256]; /* last message received from device */ - unsigned int msglen; /* length of last message received */ unsigned char disconnectable:1; /* this command can be disconnected */ unsigned char aborting:1; /* aborting command */ @@ -269,6 +276,7 @@ unsigned char wide_max_size; /* Maximum wide transfer size */ unsigned char cntl3; /* Control Reg 3 */ unsigned int asyncperiod; /* Async transfer period (ns) */ + unsigned int capabilities; /* driver capabilities */ unsigned int disconnect_ok:1; /* Disconnects allowed? */ } ifcfg; @@ -281,6 +289,8 @@ /* per-device info */ struct fas216_device { unsigned char disconnect_ok:1; /* device can disconnect */ + unsigned char parity_enabled:1; /* parity checking enabled */ + unsigned char parity_check:1; /* need to check parity checking */ unsigned char period; /* sync xfer period in (*4ns) */ unsigned char stp; /* synchronous transfer period */ unsigned char sof; /* synchronous offset register */ @@ -300,31 +310,22 @@ /* miscellaneous */ int internal_done; /* flag to indicate request done */ - unsigned long magic_end; } FAS216_Info; /* Function: int fas216_init (struct Scsi_Host *instance) - * Purpose : initialise FAS/NCR/AMD SCSI ic. + * Purpose : initialise FAS/NCR/AMD SCSI structures. * Params : instance - a driver-specific filled-out structure * Returns : 0 on success */ extern int fas216_init (struct Scsi_Host *instance); -/* Function: int fas216_abort (Scsi_Cmnd *SCpnt) - * Purpose : abort a command if something horrible happens. - * Params : SCpnt - Command that is believed to be causing a problem. - * Returns : one of SCSI_ABORT_ macros. - */ -extern int fas216_abort (Scsi_Cmnd *); - -/* Function: int fas216_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags) - * Purpose : resets the adapter if something horrible happens. - * Params : SCpnt - Command that is believed to be causing a problem. - * reset_flags - flags indicating reset type that is believed to be required. - * Returns : one of SCSI_RESET_ macros, or'd with the SCSI_RESET_*_RESET macros. +/* Function: int fas216_add (struct Scsi_Host *instance) + * Purpose : initialise FAS/NCR/AMD SCSI ic. + * Params : instance - a driver-specific filled-out structure + * Returns : 0 on success */ -extern int fas216_reset (Scsi_Cmnd *, unsigned int); +extern int fas216_add (struct Scsi_Host *instance); /* Function: int fas216_queue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) * Purpose : queue a command for adapter to process. @@ -341,20 +342,21 @@ */ extern int fas216_command (Scsi_Cmnd *); -/* Function: void fas216_intr (struct Scsi_Host *instance) +/* Function: void fas216_intr (FAS216_Info *info) * Purpose : handle interrupts from the interface to progress a command - * Params : instance - interface to service + * Params : info - interface to service */ -extern void fas216_intr (struct Scsi_Host *instance); +extern void fas216_intr (FAS216_Info *info); + +extern void fas216_remove (struct Scsi_Host *instance); /* Function: int fas216_release (struct Scsi_Host *instance) * Purpose : release all resources and put everything to bed for FAS/NCR/AMD SCSI ic. * Params : instance - a driver-specific filled-out structure * Returns : 0 on success */ -extern int fas216_release (struct Scsi_Host *instance); +extern void fas216_release (struct Scsi_Host *instance); -extern int fas216_info(FAS216_Info *info, char *buffer); extern int fas216_print_host(FAS216_Info *info, char *buffer); extern int fas216_print_stats(FAS216_Info *info, char *buffer); extern int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer); diff -urN linux-2.4.21/drivers/acorn/scsi/powertec.c linux-2.4.22/drivers/acorn/scsi/powertec.c --- linux-2.4.21/drivers/acorn/scsi/powertec.c 2001-11-04 09:31:57.000000000 -0800 +++ linux-2.4.22/drivers/acorn/scsi/powertec.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/powertec.c * - * Copyright (C) 1997-2000 Russell King + * Copyright (C) 1997-2003 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include #include @@ -41,14 +39,10 @@ #include "../../scsi/sd.h" #include "../../scsi/hosts.h" #include "fas216.h" +#include "scsi.h" #include -/* Configuration */ -#define POWERTEC_XTALFREQ 40 -#define POWERTEC_ASYNC_PERIOD 200 -#define POWERTEC_SYNC_DEPTH 7 - /* * List of devices that the driver will recognise */ @@ -70,33 +64,23 @@ #define POWERTEC_INTR_ENABLE 1 #define POWERTEC_INTR_DISABLE 0 -/* - * Version - */ -#define VER_MAJOR 0 -#define VER_MINOR 0 -#define VER_PATCH 5 - -static struct expansion_card *ecs[MAX_ECARDS]; +#define VERSION "1.10 (22/01/2003 2.4.19-rmk5)" /* - * Use term=0,1,0,0,0 to turn terminators on/off + * Use term=0,1,0,0,0 to turn terminators on/off. + * One entry per slot. */ static int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; #define NR_SG 256 -typedef struct { +struct powertec_info { FAS216_Info info; - - struct { - unsigned int term_port; - unsigned int terms; - } control; - - /* other info... */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ -} PowerTecScsi_Info; + struct expansion_card *ec; + unsigned int term_port; + unsigned int term_ctl; + struct scatterlist sg[NR_SG]; +}; /* Prototype: void powertecscsi_irqenable(ec, irqnr) * Purpose : Enable interrupts on Powertec SCSI card @@ -123,12 +107,8 @@ } static const expansioncard_ops_t powertecscsi_ops = { - powertecscsi_irqenable, - powertecscsi_irqdisable, - NULL, - NULL, - NULL, - NULL + .irqenable = powertecscsi_irqenable, + .irqdisable = powertecscsi_irqdisable, }; /* Prototype: void powertecscsi_terminator_ctl(host, on_off) @@ -139,14 +119,10 @@ static void powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off) { - PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata; - - if (on_off) - info->control.terms = POWERTEC_TERM_ENABLE; - else - info->control.terms = 0; + struct powertec_info *info = (struct powertec_info *)host->hostdata; - outb(info->control.terms, info->control.term_port); + info->term_ctl = on_off ? POWERTEC_TERM_ENABLE : 0; + outb(info->term_ctl, info->term_port); } /* Prototype: void powertecscsi_intr(irq, *dev_id, *regs) @@ -158,9 +134,7 @@ static void powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *host = (struct Scsi_Host *)dev_id; - - fas216_intr(host); + fas216_intr(dev_id); } /* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type) @@ -175,32 +149,26 @@ powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { - PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata; + struct powertec_info *info = (struct powertec_info *)host->hostdata; int dmach = host->dma_channel; - if (dmach != NO_DMA && - (min_type == fasdma_real_all || SCp->this_residual >= 512)) { - int bufs = SCp->buffers_residual; - int pci_dir, dma_dir; - - if (bufs) - memcpy(info->sg + 1, SCp->buffer + 1, - sizeof(struct scatterlist) * bufs); - info->sg[0].address = SCp->ptr; - info->sg[0].page = NULL; - info->sg[0].length = SCp->this_residual; + if (info->info.ifcfg.capabilities & FASCAP_DMA && + min_type == fasdma_real_all) { + int bufs, map_dir, dma_dir; + + bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG); if (direction == DMA_OUT) - pci_dir = PCI_DMA_TODEVICE, + map_dir = PCI_DMA_TODEVICE, dma_dir = DMA_MODE_WRITE; else - pci_dir = PCI_DMA_FROMDEVICE, + map_dir = PCI_DMA_FROMDEVICE, dma_dir = DMA_MODE_READ; - pci_map_sg(NULL, info->sg, bufs + 1, pci_dir); + pci_map_sg(NULL, info->sg, bufs, map_dir); disable_dma(dmach); - set_dma_sg(dmach, info->sg, bufs + 1); + set_dma_sg(dmach, info->sg, bufs); set_dma_mode(dmach, dma_dir); enable_dma(dmach); return fasdma_real_all; @@ -225,122 +193,6 @@ disable_dma(host->dma_channel); } -/* Prototype: int powertecscsi_detect(Scsi_Host_Template * tpnt) - * Purpose : initialises PowerTec SCSI driver - * Params : tpnt - template for this SCSI adapter - * Returns : >0 if host found, 0 otherwise. - */ -int -powertecscsi_detect(Scsi_Host_Template *tpnt) -{ - static const card_ids powertecscsi_cids[] = - { POWERTECSCSI_LIST, { 0xffff, 0xffff} }; - int count = 0; - struct Scsi_Host *host; - - tpnt->proc_name = "powertec"; - memset(ecs, 0, sizeof (ecs)); - - ecard_startfind(); - - while (1) { - PowerTecScsi_Info *info; - - ecs[count] = ecard_find(0, powertecscsi_cids); - if (!ecs[count]) - break; - - ecard_claim(ecs[count]); - - host = scsi_register(tpnt, sizeof (PowerTecScsi_Info)); - if (!host) { - ecard_release(ecs[count]); - break; - } - - host->io_port = ecard_address(ecs[count], ECARD_IOC, ECARD_FAST); - host->irq = ecs[count]->irq; - host->dma_channel = ecs[count]->dma; - info = (PowerTecScsi_Info *)host->hostdata; - - if (host->dma_channel != NO_DMA) - set_dma_speed(host->dma_channel, 180); - - info->control.term_port = host->io_port + POWERTEC_TERM_CONTROL; - info->control.terms = term[count] ? POWERTEC_TERM_ENABLE : 0; - powertecscsi_terminator_ctl(host, info->control.terms); - - info->info.scsi.io_port = - host->io_port + POWERTEC_FAS216_OFFSET; - info->info.scsi.io_shift= POWERTEC_FAS216_SHIFT; - info->info.scsi.irq = host->irq; - info->info.ifcfg.clockrate = POWERTEC_XTALFREQ; - info->info.ifcfg.select_timeout = 255; - info->info.ifcfg.asyncperiod = POWERTEC_ASYNC_PERIOD; - info->info.ifcfg.sync_max_depth = POWERTEC_SYNC_DEPTH; - info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; - info->info.ifcfg.disconnect_ok = 1; - info->info.ifcfg.wide_max_size = 0; - info->info.dma.setup = powertecscsi_dma_setup; - info->info.dma.pseudo = NULL; - info->info.dma.stop = powertecscsi_dma_stop; - - ecs[count]->irqaddr = (unsigned char *) - ioaddr(host->io_port + POWERTEC_INTR_STATUS); - ecs[count]->irqmask = POWERTEC_INTR_BIT; - ecs[count]->irq_data = (void *) - (host->io_port + POWERTEC_INTR_CONTROL); - ecs[count]->ops = (expansioncard_ops_t *)&powertecscsi_ops; - - request_region(host->io_port + POWERTEC_FAS216_OFFSET, - 16 << POWERTEC_FAS216_SHIFT, "powertec2-fas"); - - if (host->irq != NO_IRQ && - request_irq(host->irq, powertecscsi_intr, - SA_INTERRUPT, "powertec", host)) { - printk("scsi%d: IRQ%d not free, interrupts disabled\n", - host->host_no, host->irq); - host->irq = NO_IRQ; - info->info.scsi.irq = NO_IRQ; - } - - if (host->dma_channel != NO_DMA && - request_dma(host->dma_channel, "powertec")) { - printk("scsi%d: DMA%d not free, DMA disabled\n", - host->host_no, host->dma_channel); - host->dma_channel = NO_DMA; - } - - fas216_init(host); - ++count; - } - return count; -} - -/* Prototype: int powertecscsi_release(struct Scsi_Host * host) - * Purpose : releases all resources used by this adapter - * Params : host - driver host structure to return info for. - */ -int powertecscsi_release(struct Scsi_Host *host) -{ - int i; - - fas216_release(host); - - if (host->irq != NO_IRQ) - free_irq(host->irq, host); - if (host->dma_channel != NO_DMA) - free_dma(host->dma_channel); - release_region(host->io_port + POWERTEC_FAS216_OFFSET, - 16 << POWERTEC_FAS216_SHIFT); - - for (i = 0; i < MAX_ECARDS; i++) - if (ecs[i] && - host->io_port == ecard_address(ecs[i], ECARD_IOC, ECARD_FAST)) - ecard_release(ecs[i]); - return 0; -} - /* Prototype: const char *powertecscsi_info(struct Scsi_Host * host) * Purpose : returns a descriptive string about this interface, * Params : host - driver host structure to return info for. @@ -348,15 +200,12 @@ */ const char *powertecscsi_info(struct Scsi_Host *host) { - PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata; - static char string[100], *p; + struct powertec_info *info = (struct powertec_info *)host->hostdata; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%d.%d.%d terminators o%s", - VER_MAJOR, VER_MINOR, VER_PATCH, - info->control.terms ? "n" : "ff"); + sprintf(string, "%s (%s) in slot %d v%s terminators o%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION, info->term_ctl ? "n" : "ff"); return string; } @@ -409,31 +258,25 @@ int length, int host_no, int inout) { int pos, begin; - struct Scsi_Host *host = scsi_hostlist; - PowerTecScsi_Info *info; + struct Scsi_Host *host; + struct powertec_info *info; Scsi_Device *scd; - while (host) { - if (host->host_no == host_no) - break; - host = host->next; - } + host = scsi_host_hn_get(host_no); if (!host) return 0; if (inout == 1) return powertecscsi_set_proc_info(host, buffer, length); - info = (PowerTecScsi_Info *)host->hostdata; + info = (struct powertec_info *)host->hostdata; begin = 0; - pos = sprintf(buffer, - "PowerTec SCSI driver version %d.%d.%d\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + pos = sprintf(buffer, "PowerTec SCSI driver v%s\n", VERSION); pos += fas216_print_host(&info->info, buffer + pos); pos += sprintf(buffer + pos, "Term : o%s\n", - info->control.terms ? "n" : "ff"); + info->term_ctl ? "n" : "ff"); pos += fas216_print_stats(&info->info, buffer + pos); @@ -458,28 +301,186 @@ return pos; } +static int powertecscsi_probe(struct expansion_card *ec); + +/* Prototype: int powertecscsi_detect(Scsi_Host_Template * tpnt) + * Purpose : initialises PowerTec SCSI driver + * Params : tpnt - template for this SCSI adapter + * Returns : >0 if host found, 0 otherwise. + */ +static int powertecscsi_detect(Scsi_Host_Template *tpnt) +{ + static const card_ids powertecscsi_cids[] = + { POWERTECSCSI_LIST, { 0xffff, 0xffff} }; + struct expansion_card *ec; + int count = 0, ret; + + ecard_startfind(); + + while (1) { + ec = ecard_find(0, powertecscsi_cids); + if (!ec) + break; + + ecard_claim(ec); + + ret = powertecscsi_probe(ec); + if (ret) { + ecard_release(ec); + break; + } + ++count; + } + return count; +} + +static void powertecscsi_remove(struct Scsi_Host *host); + +/* Prototype: int powertecscsi_release(struct Scsi_Host * host) + * Purpose : releases all resources used by this adapter + * Params : host - driver host structure to return info for. + */ +static int powertecscsi_release(struct Scsi_Host *host) +{ + powertecscsi_remove(host); + return 0; +} + static Scsi_Host_Template powertecscsi_template = { - module: THIS_MODULE, - proc_info: powertecscsi_proc_info, - name: "PowerTec SCSI", - detect: powertecscsi_detect, - release: powertecscsi_release, - info: powertecscsi_info, - bios_param: scsicam_bios_param, - can_queue: 1, - this_id: 7, - sg_tablesize: SG_ALL, - cmd_per_lun: 1, - use_clustering: ENABLE_CLUSTERING, - command: fas216_command, - queuecommand: fas216_queue_command, - eh_host_reset_handler: fas216_eh_host_reset, - eh_bus_reset_handler: fas216_eh_bus_reset, - eh_device_reset_handler: fas216_eh_device_reset, - eh_abort_handler: fas216_eh_abort, - use_new_eh_code: 1 + .module = THIS_MODULE, + .proc_info = powertecscsi_proc_info, + .name = "PowerTec SCSI", + .detect = powertecscsi_detect, + .release = powertecscsi_release, + .info = powertecscsi_info, + .bios_param = scsicam_bios_param, + .command = fas216_command, + .queuecommand = fas216_queue_command, + .eh_host_reset_handler = fas216_eh_host_reset, + .eh_bus_reset_handler = fas216_eh_bus_reset, + .eh_device_reset_handler = fas216_eh_device_reset, + .eh_abort_handler = fas216_eh_abort, + .use_new_eh_code = 1, + + .can_queue = 1, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = ENABLE_CLUSTERING, + .proc_name = "powertec", }; +static int +powertecscsi_probe(struct expansion_card *ec) +{ + struct Scsi_Host *host; + struct powertec_info *info; + unsigned long base; + int ret; + + base = ecard_address(ec, ECARD_IOC, ECARD_FAST); + + request_region(base + POWERTEC_FAS216_OFFSET, + 16 << POWERTEC_FAS216_SHIFT, "powertec2-fas"); + + host = scsi_register(&powertecscsi_template, + sizeof (struct powertec_info)); + if (!host) { + ret = -ENOMEM; + goto out_region; + } + + host->io_port = base; + host->irq = ec->irq; + host->dma_channel = ec->dma; + + ec->irqaddr = (unsigned char *)ioaddr(base + POWERTEC_INTR_STATUS); + ec->irqmask = POWERTEC_INTR_BIT; + ec->irq_data = (void *)(base + POWERTEC_INTR_CONTROL); + ec->ops = (expansioncard_ops_t *)&powertecscsi_ops; + + info = (struct powertec_info *)host->hostdata; + info->ec = ec; + info->term_port = base + POWERTEC_TERM_CONTROL; + powertecscsi_terminator_ctl(host, term[ec->slot_no]); + + info->info.scsi.io_port = host->io_port + POWERTEC_FAS216_OFFSET; + info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT; + info->info.scsi.irq = host->irq; + info->info.ifcfg.clockrate = 40; /* MHz */ + info->info.ifcfg.select_timeout = 255; + info->info.ifcfg.asyncperiod = 200; /* ns */ + info->info.ifcfg.sync_max_depth = 7; + info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; + info->info.ifcfg.disconnect_ok = 1; + info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = 0; + info->info.dma.setup = powertecscsi_dma_setup; + info->info.dma.pseudo = NULL; + info->info.dma.stop = powertecscsi_dma_stop; + + ret = fas216_init(host); + if (ret) + goto out_free; + + ret = request_irq(host->irq, powertecscsi_intr, + SA_INTERRUPT, "powertec", &info->info); + if (ret) { + printk("scsi%d: IRQ%d not free: %d\n", + host->host_no, host->irq, ret); + goto out_release; + } + + if (host->dma_channel != NO_DMA) { + if (request_dma(host->dma_channel, "powertec")) { + printk("scsi%d: DMA%d not free, using PIO\n", + host->host_no, host->dma_channel); + host->dma_channel = NO_DMA; + } else { + set_dma_speed(host->dma_channel, 180); + info->info.ifcfg.capabilities |= FASCAP_DMA; + } + } + + ret = fas216_add(host); + if (ret == 0) + goto out; + + if (host->dma_channel != NO_DMA) + free_dma(host->dma_channel); + free_irq(host->irq, host); + + out_release: + fas216_release(host); + + out_free: + scsi_unregister(host); + + out_region: + release_region(base + POWERTEC_FAS216_OFFSET, + 16 << POWERTEC_FAS216_SHIFT); + + out: + return ret; +} + +static void powertecscsi_remove(struct Scsi_Host *host) +{ + struct powertec_info *info = (struct powertec_info *)host->hostdata; + + fas216_remove(host); + + if (host->dma_channel != NO_DMA) + free_dma(host->dma_channel); + free_irq(host->irq, info); + + release_region(host->io_port + POWERTEC_FAS216_OFFSET, + 16 << POWERTEC_FAS216_SHIFT); + + fas216_release(host); + ecard_release(info->ec); +} + static int __init powertecscsi_init(void) { scsi_register_module(MODULE_SCSI_HA, &powertecscsi_template); diff -urN linux-2.4.21/drivers/acorn/scsi/queue.c linux-2.4.22/drivers/acorn/scsi/queue.c --- linux-2.4.21/drivers/acorn/scsi/queue.c 2001-10-11 09:04:57.000000000 -0700 +++ linux-2.4.22/drivers/acorn/scsi/queue.c 2003-08-25 04:44:40.000000000 -0700 @@ -229,6 +229,27 @@ } /* + * Function: queue_remove_all_target(queue, target) + * Purpose : remove all SCSI commands from the queue for a specified target + * Params : queue - queue to remove command from + * target - target device id + * Returns : nothing + */ +void queue_remove_all_target(Queue_t *queue, int target) +{ + unsigned long flags; + struct list_head *l; + + spin_lock_irqsave(&queue->queue_lock, flags); + list_for_each(l, &queue->head) { + QE_t *q = list_entry(l, QE_t, list); + if (q->SCpnt->target == target) + __queue_remove(queue, l); + } + spin_unlock_irqrestore(&queue->queue_lock, flags); +} + +/* * Function: int queue_probetgtlun (queue, target, lun) * Purpose : check to see if we have a command in the queue for the specified * target/lun. @@ -290,6 +311,7 @@ EXPORT_SYMBOL(queue_remove_exclude); EXPORT_SYMBOL(queue_remove_tgtluntag); EXPORT_SYMBOL(queue_remove_cmd); +EXPORT_SYMBOL(queue_remove_all_target); EXPORT_SYMBOL(queue_probetgtlun); MODULE_AUTHOR("Russell King"); diff -urN linux-2.4.21/drivers/acorn/scsi/queue.h linux-2.4.22/drivers/acorn/scsi/queue.h --- linux-2.4.21/drivers/acorn/scsi/queue.h 2000-09-18 15:15:22.000000000 -0700 +++ linux-2.4.22/drivers/acorn/scsi/queue.h 2003-08-25 04:44:40.000000000 -0700 @@ -74,6 +74,15 @@ extern Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag); /* + * Function: queue_remove_all_target(queue, target) + * Purpose : remove all SCSI commands from the queue for a specified target + * Params : queue - queue to remove command from + * target - target device id + * Returns : nothing + */ +extern void queue_remove_all_target(Queue_t *queue, int target); + +/* * Function: int queue_probetgtlun (queue, target, lun) * Purpose : check to see if we have a command in the queue for the specified * target/lun. diff -urN linux-2.4.21/drivers/acorn/scsi/scsi.h linux-2.4.22/drivers/acorn/scsi/scsi.h --- linux-2.4.21/drivers/acorn/scsi/scsi.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acorn/scsi/scsi.h 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,123 @@ +/* + * linux/drivers/acorn/scsi/scsi.h + * + * Copyright (C) 2002 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Commonly used scsi driver functions. + */ + +#define BELT_AND_BRACES + +/* + * The scatter-gather list handling. This contains all + * the yucky stuff that needs to be fixed properly. + */ +static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max) +{ + int bufs = SCp->buffers_residual; + + BUG_ON(bufs + 1 > max); + + sg->address = SCp->ptr; + sg->length = SCp->this_residual; + + if (bufs) + memcpy(sg + 1, SCp->buffer + 1, + sizeof(struct scatterlist) * bufs); + return bufs + 1; +} + +static inline int next_SCp(Scsi_Pointer *SCp) +{ + int ret = SCp->buffers_residual; + if (ret) { + SCp->buffer++; + SCp->buffers_residual--; + SCp->ptr = (unsigned char *)SCp->buffer->address; + SCp->this_residual = SCp->buffer->length; + } else { + SCp->ptr = NULL; + SCp->this_residual = 0; + } + return ret; +} + +static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp) +{ + char c = *SCp->ptr; + + SCp->ptr += 1; + SCp->this_residual -= 1; + + return c; +} + +static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c) +{ + *SCp->ptr = c; + SCp->ptr += 1; + SCp->this_residual -= 1; +} + +static inline void init_SCp(Scsi_Cmnd *SCpnt) +{ + memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer)); + + if (SCpnt->use_sg) { + unsigned long len = 0; + int buf; + + SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer; + SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; + SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address; + SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; + +#ifdef BELT_AND_BRACES + /* + * Calculate correct buffer length. Some commands + * come in with the wrong request_bufflen. + */ + for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++) + len += SCpnt->SCp.buffer[buf].length; + + if (SCpnt->request_bufflen != len) + printk(KERN_WARNING "scsi%d.%c: bad request buffer " + "length %d, should be %ld\n", SCpnt->host->host_no, + '0' + SCpnt->target, SCpnt->request_bufflen, len); + SCpnt->request_bufflen = len; +#endif + } else { + SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer; + SCpnt->SCp.this_residual = SCpnt->request_bufflen; + } + + /* + * If the upper SCSI layers pass a buffer, but zero length, + * we aren't interested in the buffer pointer. + */ + if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) { +#if 0 //def BELT_AND_BRACES + printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for " + "command ", SCpnt->host->host_no, '0' + SCpnt->target); + print_command(SCpnt->cmnd); +#endif + SCpnt->SCp.ptr = NULL; + } +} + +static inline struct Scsi_Host *scsi_host_hn_get(int host_no) +{ + struct Scsi_Host *host = scsi_hostlist; + + while (host) { + if (host->host_no == host_no) + break; + host = host->next; + } + + return host; +} diff -urN linux-2.4.21/drivers/acpi/Config.in linux-2.4.22/drivers/acpi/Config.in --- linux-2.4.21/drivers/acpi/Config.in 2001-06-20 17:47:39.000000000 -0700 +++ linux-2.4.22/drivers/acpi/Config.in 2003-08-25 04:44:40.000000000 -0700 @@ -1,17 +1,94 @@ # -# ACPI configuration +# ACPI Configuration # -#mainmenu_option next_comment -#comment 'ACPI Configuration' -dep_bool ' ACPI Debug Statements' CONFIG_ACPI_DEBUG $CONFIG_ACPI -dep_tristate ' ACPI Bus Manager' CONFIG_ACPI_BUSMGR $CONFIG_ACPI +if [ "$CONFIG_X86" = "y" ]; then -dep_tristate ' System' CONFIG_ACPI_SYS $CONFIG_ACPI_BUSMGR $CONFIG_ACPI -dep_tristate ' Processor' CONFIG_ACPI_CPU $CONFIG_ACPI_BUSMGR $CONFIG_ACPI -dep_tristate ' Button' CONFIG_ACPI_BUTTON $CONFIG_ACPI_BUSMGR $CONFIG_ACPI -dep_tristate ' AC Adapter' CONFIG_ACPI_AC $CONFIG_ACPI_BUSMGR $CONFIG_ACPI -dep_tristate ' Embedded Controller' CONFIG_ACPI_EC $CONFIG_ACPI_BUSMGR $CONFIG_ACPI -dep_tristate ' Control Method Battery' CONFIG_ACPI_CMBATT $CONFIG_ACPI_BUSMGR $CONFIG_ACPI $CONFIG_ACPI_EC -dep_tristate ' Thermal' CONFIG_ACPI_THERMAL $CONFIG_ACPI_BUSMGR $CONFIG_ACPI $CONFIG_ACPI_EC -#endmenu + mainmenu_option next_comment + comment 'ACPI Support' + bool 'ACPI Support' CONFIG_ACPI + if [ "$CONFIG_ACPI" = "y" ]; then + if [ "$CONFIG_SMP" = "y" ]; then + bool 'CPU Enumeration Only' CONFIG_ACPI_HT_ONLY + else + define_bool CONFIG_ACPI_HT_ONLY n + fi + + if [ "$CONFIG_ACPI_HT_ONLY" = "n" ]; then + define_bool CONFIG_ACPI_BOOT y + define_bool CONFIG_ACPI_BUS y + define_bool CONFIG_ACPI_INTERPRETER y + define_bool CONFIG_ACPI_EC y + define_bool CONFIG_ACPI_POWER y + if [ "$CONFIG_PCI" = "y" ]; then + define_bool CONFIG_ACPI_PCI y + fi + define_bool CONFIG_ACPI_SLEEP y + define_bool CONFIG_ACPI_SYSTEM y + tristate ' AC Adapter' CONFIG_ACPI_AC + tristate ' Battery' CONFIG_ACPI_BATTERY + tristate ' Button' CONFIG_ACPI_BUTTON + tristate ' Fan' CONFIG_ACPI_FAN + tristate ' Processor' CONFIG_ACPI_PROCESSOR + dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR + if [ "$CONFIG_NUMA" = "y" -a "$CONFIG_X86_64" != "y" ]; then + dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA + fi + tristate ' ASUS Laptop Extras' CONFIG_ACPI_ASUS + tristate ' Toshiba Laptop Extras' CONFIG_ACPI_TOSHIBA + bool ' Debug Statements' CONFIG_ACPI_DEBUG + bool ' Relaxed AML Checking' CONFIG_ACPI_RELAXED_AML + fi + fi + + endmenu + +fi + + +if [ "$CONFIG_IA64" = "y" ]; then + + if [ "$CONFIG_IA64_SGI_SN" = "y" ]; then + mainmenu_option next_comment + comment 'ACPI Support' + define_bool CONFIG_ACPI y + define_bool CONFIG_ACPI_EFI y + define_bool CONFIG_ACPI_BOOT y + define_bool CONFIG_ACPI_BUS n + define_bool CONFIG_ACPI_INTERPRETER n + define_bool CONFIG_ACPI_PCI n + define_bool CONFIG_ACPI_POWER n + define_bool CONFIG_ACPI_SYSTEM n + define_bool CONFIG_ACPI_BUTTON n + define_bool CONFIG_ACPI_FAN n + define_bool CONFIG_ACPI_PROCESSOR n + define_bool CONFIG_ACPI_THERMAL n + define_bool CONFIG_ACPI_NUMA y + endmenu + fi + + if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then + mainmenu_option next_comment + comment 'ACPI Support' + if [ "$CONFIG_PCI" = "y" ]; then + define_bool CONFIG_ACPI_PCI y + fi + define_bool CONFIG_ACPI y + define_bool CONFIG_ACPI_EFI y + define_bool CONFIG_ACPI_BOOT y + define_bool CONFIG_ACPI_BUS y + define_bool CONFIG_ACPI_INTERPRETER y + define_bool CONFIG_ACPI_POWER y + define_bool CONFIG_ACPI_SYSTEM y + tristate ' Button' CONFIG_ACPI_BUTTON + tristate ' Fan' CONFIG_ACPI_FAN + tristate ' Processor' CONFIG_ACPI_PROCESSOR + dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR + if [ "$CONFIG_NUMA" = "y" ]; then + dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA + fi + bool ' Debug Statements' CONFIG_ACPI_DEBUG + endmenu + fi + +fi diff -urN linux-2.4.21/drivers/acpi/Makefile linux-2.4.22/drivers/acpi/Makefile --- linux-2.4.21/drivers/acpi/Makefile 2001-10-24 14:06:21.000000000 -0700 +++ linux-2.4.22/drivers/acpi/Makefile 2003-08-25 04:44:40.000000000 -0700 @@ -4,51 +4,54 @@ O_TARGET := acpi.o -export-objs := acpi_ksyms.o - export ACPI_CFLAGS -ACPI_CFLAGS := -D_LINUX -I$(CURDIR)/include - -# -# CONFIG_ACPI_KERNEL_CONFIG is currently only IA64 -# -ifdef CONFIG_ACPI_KERNEL_CONFIG - ACPI_CFLAGS += -DCONFIG_ACPI_KERNEL_CONFIG_ONLY -endif - -acpi-subdirs := utilities dispatcher events hardware \ - executer namespace parser resources tables +ACPI_CFLAGS := -Os ifdef CONFIG_ACPI_DEBUG - ACPI_CFLAGS += -DACPI_DEBUG -Wno-unused + ACPI_CFLAGS += -DACPI_DEBUG_OUTPUT endif -ifdef CONFIG_ACPI_DEBUGGER - ACPI_CFLAGS += -DENABLE_DEBUGGER - acpi-subdirs += debugger -endif +EXTRA_CFLAGS += $(ACPI_CFLAGS) -EXTRA_CFLAGS += $(ACPI_CFLAGS) +export-objs := acpi_ksyms.o processor.o -mod-subdirs := ospm +obj-$(CONFIG_ACPI) := acpi_ksyms.o -subdir-$(CONFIG_ACPI) += $(acpi-subdirs) -subdir-$(CONFIG_ACPI_BUSMGR) += ospm +# +# ACPI Boot-Time Table Parsing +# +obj-$(CONFIG_ACPI_BOOT) += tables.o +obj-$(CONFIG_ACPI_INTERPRETER) += blacklist.o -obj-$(CONFIG_ACPI) += driver.o os.o acpi_ksyms.o -obj-$(CONFIG_ACPI) += $(foreach dir,$(acpi-subdirs),$(dir)/$(dir).o) -ifdef CONFIG_ACPI_KERNEL_CONFIG - obj-$(CONFIG_ACPI) += acpiconf.o osconf.o +# +# ACPI Core Subsystem (Interpreter) +# +ifeq ($(CONFIG_ACPI_INTERPRETER),y) + obj-y += osl.o utils.o + subdir-y += dispatcher events executer hardware namespace parser \ + resources tables utilities + obj-y += $(foreach dir,$(subdir-y),$(dir)/$(dir).o) endif -ifeq ($(CONFIG_ACPI_BUSMGR),y) - obj-y += ospm/ospm.o +# +# ACPI Bus and Device Drivers +# +ifeq ($(CONFIG_ACPI_BUS),y) + obj-y += bus.o + obj-$(CONFIG_ACPI_AC) += ac.o + obj-$(CONFIG_ACPI_BATTERY) += battery.o + obj-$(CONFIG_ACPI_BUTTON) += button.o + obj-$(CONFIG_ACPI_EC) += ec.o + obj-$(CONFIG_ACPI_FAN) += fan.o + obj-$(CONFIG_ACPI_PCI) += pci_root.o pci_link.o pci_irq.o pci_bind.o + obj-$(CONFIG_ACPI_POWER) += power.o + obj-$(CONFIG_ACPI_PROCESSOR) += processor.o + obj-$(CONFIG_ACPI_THERMAL) += thermal.o + obj-$(CONFIG_ACPI_SYSTEM) += system.o + obj-$(CONFIG_ACPI_NUMA) += numa.o + obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o + obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o endif -# commented out until we distribute it -ASG -#ifeq ($(CONFIG_KDB),y) -# obj-m += kdb/kdbm_acpi.o -#endif - include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ac.c linux-2.4.22/drivers/acpi/ac.c --- linux-2.4.21/drivers/acpi/ac.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ac.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,346 @@ +/* + * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 26 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_AC_COMPONENT +ACPI_MODULE_NAME ("acpi_ac") + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +#define PREFIX "ACPI: " + + +int acpi_ac_add (struct acpi_device *device); +int acpi_ac_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_ac_driver = { + .name = ACPI_AC_DRIVER_NAME, + .class = ACPI_AC_CLASS, + .ids = ACPI_AC_HID, + .ops = { + .add = acpi_ac_add, + .remove = acpi_ac_remove, + }, +}; + +struct acpi_ac { + acpi_handle handle; + unsigned long state; +}; + + +/* -------------------------------------------------------------------------- + AC Adapter Management + -------------------------------------------------------------------------- */ + +static int +acpi_ac_get_state ( + struct acpi_ac *ac) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE("acpi_ac_get_state"); + + if (!ac) + return_VALUE(-EINVAL); + + status = acpi_evaluate_integer(ac->handle, "_PSR", NULL, &ac->state); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error reading AC Adapter state\n")); + ac->state = ACPI_AC_STATUS_UNKNOWN; + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_ac_dir = NULL; + +static int +acpi_ac_read_state ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_ac *ac = (struct acpi_ac *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_ac_read_state"); + + if (!ac || (off != 0)) + goto end; + + if (acpi_ac_get_state(ac)) { + p += sprintf(p, "ERROR: Unable to read AC Adapter state\n"); + goto end; + } + + p += sprintf(p, "state: "); + switch (ac->state) { + case ACPI_AC_STATUS_OFFLINE: + p += sprintf(p, "off-line\n"); + break; + case ACPI_AC_STATUS_ONLINE: + p += sprintf(p, "on-line\n"); + break; + default: + p += sprintf(p, "unknown\n"); + break; + } + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_ac_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_ac_add_fs"); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_ac_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + /* 'state' [R] */ + entry = create_proc_entry(ACPI_AC_FILE_STATE, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_AC_FILE_STATE)); + else { + entry->read_proc = acpi_ac_read_state; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + + +static int +acpi_ac_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_ac_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Model + -------------------------------------------------------------------------- */ + +void +acpi_ac_notify ( + acpi_handle handle, + u32 event, + void *data) +{ + struct acpi_ac *ac = (struct acpi_ac *) data; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_ac_notify"); + + if (!ac) + return; + + if (acpi_bus_get_device(ac->handle, &device)) + return_VOID; + + switch (event) { + case ACPI_AC_NOTIFY_STATUS: + acpi_ac_get_state(ac); + acpi_bus_generate_event(device, event, (u32) ac->state); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return_VOID; +} + + +int +acpi_ac_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_ac *ac = NULL; + + ACPI_FUNCTION_TRACE("acpi_ac_add"); + + if (!device) + return_VALUE(-EINVAL); + + ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL); + if (!ac) + return_VALUE(-ENOMEM); + memset(ac, 0, sizeof(struct acpi_ac)); + + ac->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_AC_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_AC_CLASS); + acpi_driver_data(device) = ac; + + result = acpi_ac_get_state(ac); + if (result) + goto end; + + result = acpi_ac_add_fs(device); + if (result) + goto end; + + status = acpi_install_notify_handler(ac->handle, + ACPI_DEVICE_NOTIFY, acpi_ac_notify, ac); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + result = -ENODEV; + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s] (%s)\n", + acpi_device_name(device), acpi_device_bid(device), + ac->state?"on-line":"off-line"); + +end: + if (result) { + acpi_ac_remove_fs(device); + kfree(ac); + } + + return_VALUE(result); +} + + +int +acpi_ac_remove ( + struct acpi_device *device, + int type) +{ + acpi_status status = AE_OK; + struct acpi_ac *ac = NULL; + + ACPI_FUNCTION_TRACE("acpi_ac_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + ac = (struct acpi_ac *) acpi_driver_data(device); + + status = acpi_remove_notify_handler(ac->handle, + ACPI_DEVICE_NOTIFY, acpi_ac_notify); + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + + acpi_ac_remove_fs(device); + + kfree(ac); + + return_VALUE(0); +} + + +int __init +acpi_ac_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_ac_init"); + + acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); + if (!acpi_ac_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_ac_driver); + if (result < 0) { + remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +void __exit +acpi_ac_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_ac_exit"); + + acpi_bus_unregister_driver(&acpi_ac_driver); + + remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); + + return_VOID; +} + + +module_init(acpi_ac_init); +module_exit(acpi_ac_exit); diff -urN linux-2.4.21/drivers/acpi/acpi_ksyms.c linux-2.4.22/drivers/acpi/acpi_ksyms.c --- linux-2.4.21/drivers/acpi/acpi_ksyms.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/acpi_ksyms.c 2003-08-25 04:44:40.000000000 -0700 @@ -1,64 +1,56 @@ /* - * ksyms.c - ACPI exported symbols + * acpi_ksyms.c - ACPI Kernel Symbols ($Revision: 15 $) * - * Copyright (C) 2000 Andrew Grover + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 "acpi.h" -#include "acdebug.h" -extern int acpi_in_debugger; -extern FADT_DESCRIPTOR acpi_fadt; +#ifdef CONFIG_ACPI_INTERPRETER -#define _COMPONENT OS_DEPENDENT - MODULE_NAME ("symbols") +/* ACPI Debugger */ #ifdef ENABLE_DEBUGGER + +extern int acpi_in_debugger; + EXPORT_SYMBOL(acpi_in_debugger); EXPORT_SYMBOL(acpi_db_user_commands); -#endif -#ifdef ACPI_DEBUG +#endif /* ENABLE_DEBUGGER */ + +/* ACPI Core Subsystem */ + +#ifdef ACPI_DEBUG_OUTPUT +EXPORT_SYMBOL(acpi_dbg_layer); +EXPORT_SYMBOL(acpi_dbg_level); EXPORT_SYMBOL(acpi_ut_debug_print_raw); EXPORT_SYMBOL(acpi_ut_debug_print); EXPORT_SYMBOL(acpi_ut_status_exit); +EXPORT_SYMBOL(acpi_ut_value_exit); EXPORT_SYMBOL(acpi_ut_exit); EXPORT_SYMBOL(acpi_ut_trace); -#endif - -EXPORT_SYMBOL(acpi_gbl_FADT); - -EXPORT_SYMBOL(acpi_os_free); -EXPORT_SYMBOL(acpi_os_printf); -EXPORT_SYMBOL(acpi_os_callocate); -EXPORT_SYMBOL(acpi_os_sleep); -EXPORT_SYMBOL(acpi_os_stall); -EXPORT_SYMBOL(acpi_os_queue_for_execution); - -EXPORT_SYMBOL(acpi_dbg_layer); -EXPORT_SYMBOL(acpi_dbg_level); - -EXPORT_SYMBOL(acpi_format_exception); +#endif /*ACPI_DEBUG_OUTPUT*/ EXPORT_SYMBOL(acpi_get_handle); EXPORT_SYMBOL(acpi_get_parent); @@ -69,7 +61,6 @@ EXPORT_SYMBOL(acpi_evaluate_object); EXPORT_SYMBOL(acpi_get_table); EXPORT_SYMBOL(acpi_get_firmware_table); - EXPORT_SYMBOL(acpi_install_notify_handler); EXPORT_SYMBOL(acpi_remove_notify_handler); EXPORT_SYMBOL(acpi_install_gpe_handler); @@ -78,40 +69,89 @@ EXPORT_SYMBOL(acpi_remove_address_space_handler); EXPORT_SYMBOL(acpi_install_fixed_event_handler); EXPORT_SYMBOL(acpi_remove_fixed_event_handler); - EXPORT_SYMBOL(acpi_acquire_global_lock); EXPORT_SYMBOL(acpi_release_global_lock); - +EXPORT_SYMBOL(acpi_install_gpe_block); +EXPORT_SYMBOL(acpi_remove_gpe_block); EXPORT_SYMBOL(acpi_get_current_resources); EXPORT_SYMBOL(acpi_get_possible_resources); +EXPORT_SYMBOL(acpi_walk_resources); EXPORT_SYMBOL(acpi_set_current_resources); - EXPORT_SYMBOL(acpi_enable_event); EXPORT_SYMBOL(acpi_disable_event); EXPORT_SYMBOL(acpi_clear_event); - EXPORT_SYMBOL(acpi_get_timer_duration); EXPORT_SYMBOL(acpi_get_timer); +EXPORT_SYMBOL(acpi_get_sleep_type_data); +EXPORT_SYMBOL(acpi_get_register); +EXPORT_SYMBOL(acpi_set_register); +EXPORT_SYMBOL(acpi_enter_sleep_state); +EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios); +EXPORT_SYMBOL(acpi_get_system_info); +EXPORT_SYMBOL(acpi_get_devices); + +/* ACPI OS Services Layer (acpi_osl.c) */ +EXPORT_SYMBOL(acpi_os_free); +EXPORT_SYMBOL(acpi_os_printf); +EXPORT_SYMBOL(acpi_os_sleep); +EXPORT_SYMBOL(acpi_os_stall); +EXPORT_SYMBOL(acpi_os_signal); +EXPORT_SYMBOL(acpi_os_queue_for_execution); EXPORT_SYMBOL(acpi_os_signal_semaphore); EXPORT_SYMBOL(acpi_os_create_semaphore); EXPORT_SYMBOL(acpi_os_delete_semaphore); EXPORT_SYMBOL(acpi_os_wait_semaphore); -EXPORT_SYMBOL(acpi_os_read_port); -EXPORT_SYMBOL(acpi_os_write_port); +EXPORT_SYMBOL(acpi_os_read_pci_configuration); + +/* ACPI Utilities (acpi_utils.c) */ + +EXPORT_SYMBOL(acpi_extract_package); +EXPORT_SYMBOL(acpi_evaluate_integer); +EXPORT_SYMBOL(acpi_evaluate_reference); + +#endif /*CONFIG_ACPI_INTERPRETER*/ + + +/* ACPI Bus Driver (acpi_bus.c) */ + +#ifdef CONFIG_ACPI_BUS EXPORT_SYMBOL(acpi_fadt); -EXPORT_SYMBOL(acpi_hw_register_bit_access); -EXPORT_SYMBOL(acpi_hw_obtain_sleep_type_register_data); -EXPORT_SYMBOL(acpi_enter_sleep_state); -EXPORT_SYMBOL(acpi_get_system_info); -EXPORT_SYMBOL(acpi_leave_sleep_state); EXPORT_SYMBOL(acpi_walk_namespace); -/*EXPORT_SYMBOL(acpi_save_state_mem);*/ -/*EXPORT_SYMBOL(acpi_save_state_disk);*/ -EXPORT_SYMBOL(acpi_hw_register_read); -EXPORT_SYMBOL(acpi_set_firmware_waking_vector); -EXPORT_SYMBOL(acpi_subsystem_status); +EXPORT_SYMBOL(acpi_root_dir); +EXPORT_SYMBOL(acpi_bus_get_device); +EXPORT_SYMBOL(acpi_bus_get_status); +EXPORT_SYMBOL(acpi_bus_get_power); +EXPORT_SYMBOL(acpi_bus_set_power); +EXPORT_SYMBOL(acpi_bus_generate_event); +EXPORT_SYMBOL(acpi_bus_receive_event); +EXPORT_SYMBOL(acpi_bus_register_driver); +EXPORT_SYMBOL(acpi_bus_unregister_driver); +EXPORT_SYMBOL(acpi_bus_scan); +EXPORT_SYMBOL(acpi_init); + +#endif /*CONFIG_ACPI_BUS*/ + + +/* ACPI PCI Driver (pci_irq.c) */ + +#ifdef CONFIG_ACPI_PCI + +#include +extern int acpi_pci_irq_enable(struct pci_dev *dev); +EXPORT_SYMBOL(acpi_pci_irq_enable); +extern int acpi_pci_irq_lookup (int segment, int bus, int device, int pin); +EXPORT_SYMBOL(acpi_pci_irq_lookup); +EXPORT_SYMBOL(acpi_pci_register_driver); +EXPORT_SYMBOL(acpi_pci_unregister_driver); +#endif /*CONFIG_ACPI_PCI */ + +#ifdef CONFIG_ACPI_EC +/* ACPI EC driver (ec.c) */ + +EXPORT_SYMBOL(ec_read); +EXPORT_SYMBOL(ec_write); +#endif -EXPORT_SYMBOL(acpi_os_signal); diff -urN linux-2.4.21/drivers/acpi/asus_acpi.c linux-2.4.22/drivers/acpi/asus_acpi.c --- linux-2.4.21/drivers/acpi/asus_acpi.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/asus_acpi.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,952 @@ +/* + * asus_acpi.c - Asus Laptop ACPI Extras + * + * + * Copyright (C) 2002, 2003 Julien Lerouge, Karol Kozimor + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * The development page for this driver is located at + * http://sourceforge.net/projects/acpi4asus/ + * + * Credits: + * Johann Wiesner - Small compile fixes + * John Belmonte - ACPI code for Toshiba laptop was a good starting point. + * + * TODO + * add Fn key status + * Add mode selection on module loading (parameter) -> still necessary ? + * Complete display switching -- may require dirty hacks? + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ASUS_ACPI_VERSION "0.24a" + +#define PROC_ASUS "asus" //the directory +#define PROC_MLED "mled" +#define PROC_WLED "wled" +#define PROC_INFOS "info" +#define PROC_LCD "lcd" +#define PROC_BRN "brn" +#define PROC_DISP "disp" + +#define ACPI_HOTK_NAME "Asus Laptop ACPI Extras Driver" +#define ACPI_HOTK_CLASS "hotkey" +#define ACPI_HOTK_DEVICE_NAME "Hotkey" +#define ACPI_HOTK_HID "ATK0100" + +/* + * Some events we use, same for all Asus + */ +#define BR_UP 0x10 +#define BR_DOWN 0x20 + +/* + * Flags for hotk status + */ +#define MLED_ON 0x01 //is MLED ON ? +#define WLED_ON 0x02 + +MODULE_AUTHOR("Julien Lerouge, Karol Kozimor"); +MODULE_DESCRIPTION(ACPI_HOTK_NAME); +MODULE_LICENSE("GPL"); +EXPORT_NO_SYMBOLS; + + +static uid_t asus_uid = 0; +static gid_t asus_gid = 0; +MODULE_PARM(asus_uid, "i"); +MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n"); +MODULE_PARM(asus_gid, "i"); +MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n"); + + +/* For each model, all features implemented */ +struct model_data { + char *name; //name of the laptop + char *mt_mled; //method to handle mled + char *mled_status; //node to handle mled reading + char *mt_wled; //method to handle wled + char *wled_status; //node to handle wled reading + char *mt_lcd_switch; //method to turn LCD ON/OFF + char *lcd_status; //node to read LCD panel state + char *brightness_up; //method to set brightness up + char *brightness_down; //guess what ? + char *brightness_set; //method to set absolute brightness + char *brightness_get; //method to get absolute brightness + char *brightness_status;//node to get brightness + char *display_set; //method to set video output + char *display_get; //method to get video output +}; + +/* + * This is the main structure, we can use it to store anything interesting + * about the hotk device + */ +struct asus_hotk { + struct acpi_device *device; //the device we are in + acpi_handle handle; //the handle of the hotk device + char status; //status of the hotk, for LEDs, ... + struct model_data *methods; //methods available on the laptop + u8 brightness; //brighness level + enum { + L2X = 0, //L200D -> TODO check Q11 (Fn+F8) + // Calling this method simply hang the + // computer, ISMI method hangs the laptop. + L3X, //L3C + L3D, //L3400D + M2X, //M2400E + S1X, //S1300A -> TODO special keys do not work ? + D1X, //D1 + L1X, //L1400B + A1X, //A1340D, A1300F + J1X, //S200 (J1) + //TODO A1370D does not seems to have a ATK device + // L8400 model doesn't have ATK + END_MODEL, + } model; //Models currently supported + u16 event_count[128]; //count for each event TODO make this better +}; + +/* Here we go */ +#define L3X_PREFIX "\\_SB.PCI0.PX40.ECD0." +#define S1X_PREFIX "\\_SB.PCI0.PX40." +#define L1X_PREFIX S1X_PREFIX +#define A1X_PREFIX "\\_SB.PCI0.ISA.EC0." +#define J1X_PREFIX A1X_PREFIX + +static struct model_data model_conf[END_MODEL] = { + /* + * name| mled |mled read| wled |wled read| lcd sw |lcd read | + * br up|br down | br set | br read | br status|set disp | get disp + * + * br set and read shall be in hotk device ! + * same for set disp + * + * TODO I have seen a SWBX and AIBX method on some models, like L1400B, + * it seems to be a kind of switch, but what for ? + * + */ + {"L2X", "MLED", "\\SGP6", "WLED", "\\RCP3", "\\Q10", "\\SGP0", + "\\Q0E", "\\Q0F", NULL, NULL, NULL, "SDSP", "\\INFB"}, + + {"L3X", "MLED", NULL, "WLED", NULL, L3X_PREFIX "_Q10", "\\GL32", + L3X_PREFIX "_Q0F", L3X_PREFIX "_Q0E", "SPLV", "GPLV", "\\BLVL", "SDSP", + "\\_SB.PCI0.PCI1.VGAC.NMAP"}, + + {"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG", + "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"}, + + {"M2X", "MLED", NULL, "WLED", NULL, "\\Q10", "\\GP06", + "\\Q0E","\\Q0F", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"}, + + {"S1X", "MLED", "\\EMLE", "WLED", NULL, S1X_PREFIX "Q10", "\\PNOF", + S1X_PREFIX "Q0F", S1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL}, + + {"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11", + "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"}, + + {"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF", + L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL}, + + {"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI", + A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL}, + + {"J1X", "MLED", "\\MAIL", NULL, NULL, J1X_PREFIX "_Q10", "\\BKLI", + J1X_PREFIX "_Q0B", J1X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL} +}; + +/* procdir we use */ +static struct proc_dir_entry *asus_proc_dir = NULL; + +/* + * This header is made available to allow proper configuration given model, + * revision number , ... this info cannot go in struct asus_hotk because it is + * available before the hotk + */ +static struct acpi_table_header *asus_info = NULL; + +/* + * The hotkey driver declaration + */ +static int asus_hotk_add(struct acpi_device *device); +static int asus_hotk_remove(struct acpi_device *device, int type); +static struct acpi_driver asus_hotk_driver = { + .name = ACPI_HOTK_NAME, + .class = ACPI_HOTK_CLASS, + .ids = ACPI_HOTK_HID, + .ops = { + .add = asus_hotk_add, + .remove = asus_hotk_remove, + }, +}; + +/* + * This function evaluates an ACPI method, given an int as parameter, the + * method is searched within the scope of the handle, can be NULL. The output + * of the method is written is output, which can also be NULL + * + * returns 1 if write is successful, 0 else. + */ +static int write_acpi_int(acpi_handle handle, const char *method, int val, + struct acpi_buffer *output) +{ + struct acpi_object_list params; //list of input parameters (an int here) + union acpi_object in_obj; //the only param we use + acpi_status status; + + params.count = 1; + params.pointer = &in_obj; + in_obj.type = ACPI_TYPE_INTEGER; + in_obj.integer.value = val; + + status = acpi_evaluate_object(handle, (char *) method, ¶ms, output); + return (status == AE_OK); +} + + +static int read_acpi_int(acpi_handle handle, const char *method, int *val) +{ + struct acpi_buffer output; + union acpi_object out_obj; + acpi_status status; + + output.length = sizeof(out_obj); + output.pointer = &out_obj; + + status = acpi_evaluate_object(handle, (char*) method, NULL, &output); + *val = out_obj.integer.value; + return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); +} + +/* + * We write our info in page, we begin at offset off and cannot write more + * than count bytes. We set eof to 1 if we handle those 2 values. We return the + * number of bytes written in page + */ +static int +proc_read_info(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + int len = 0; + struct asus_hotk *hotk = (struct asus_hotk *) data; + char buf[16]; //enough for all info + /* + * We use the easy way, we don't care of off and count, so we don't set eof + * to 1 + */ + + len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); + len += + sprintf(page + len, "Model reference : %s\n", + hotk->methods->name); + if (asus_info) { + snprintf(buf, 5, "%s", asus_info->signature); + len += sprintf(page + len, "ACPI signature : %s\n", buf); + snprintf(buf, 16, "%d", asus_info->length); + len += sprintf(page + len, "Table length : %s\n", buf); + snprintf(buf, 16, "%d", asus_info->revision); + len += sprintf(page + len, "ACPI minor version : %s\n", buf); + snprintf(buf, 16, "%d", asus_info->checksum); + len += sprintf(page + len, "Checksum : %s\n", buf); + snprintf(buf, 7, "%s", asus_info->oem_id); + len += sprintf(page + len, "OEM identification : %s\n", buf); + snprintf(buf, 9, "%s", asus_info->oem_table_id); + len += sprintf(page + len, "OEM table id : %s\n", buf); + snprintf(buf, 16, "%x", asus_info->oem_revision); + len += sprintf(page + len, "OEM rev number : 0x%s\n", buf); + snprintf(buf, 5, "%s", asus_info->asl_compiler_id); + len += sprintf(page + len, "ASL comp vendor ID : %s\n", buf); + snprintf(buf, 16, "%x", asus_info->asl_compiler_revision); + len += sprintf(page + len, "ASL comp rev number: 0x%s\n", buf); + } + + return len; +} + + +/* + * proc file handlers + */ +static int +proc_read_mled(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + int len = 0; + struct asus_hotk *hotk = (struct asus_hotk *) data; + int led_status = 0; + /* + * We use the easy way, we don't care of off and count, so we don't set eof + * to 1 + */ + if (hotk->methods->mled_status) { + if (read_acpi_int(NULL, hotk->methods->mled_status, + &led_status)) + len = sprintf(page, "%d\n", led_status); + else + printk(KERN_NOTICE "Asus ACPI: Error reading MLED " + "status\n"); + } else { + len = sprintf(page, "%d\n", (hotk->status & MLED_ON) ? 1 : 0); + } + + return len; +} + + +static int +proc_write_mled(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int value; + int led_out = 0; + struct asus_hotk *hotk = (struct asus_hotk *) data; + + + + /* scan expression. Multiple expressions may be delimited with ; */ + if (sscanf(buffer, "%i", &value) == 1) + led_out = ~value & 1; + + hotk->status = + (value) ? (hotk->status | MLED_ON) : (hotk->status & ~MLED_ON); + + /* We don't have to check mt_mled exists if we are here :) */ + if (!write_acpi_int(hotk->handle, hotk->methods->mt_mled, led_out, + NULL)) + printk(KERN_NOTICE "Asus ACPI: MLED write failed\n"); + + + + return count; +} + +/* + * We write our info in page, we begin at offset off and cannot write more + * than count bytes. We set eof to 1 if we handle those 2 values. We return the + * number of bytes written in page + */ +static int +proc_read_wled(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + int len = 0; + struct asus_hotk *hotk = (struct asus_hotk *) data; + int led_status; + + if (hotk->methods->wled_status) { + if (read_acpi_int(NULL, hotk->methods->mled_status, + &led_status)) + len = sprintf(page, "%d\n", led_status); + else + printk(KERN_NOTICE "Asus ACPI: Error reading WLED " + "status\n"); + } else { + len = sprintf(page, "%d\n", (hotk->status & WLED_ON) ? 1 : 0); + } + + return len; +} + +static int +proc_write_wled(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int value; + int led_out = 0; + struct asus_hotk *hotk = (struct asus_hotk *) data; + + /* scan expression. Multiple expressions may be delimited with ; */ + if (sscanf(buffer, "%i", &value) == 1) + led_out = value & 1; + + hotk->status = + (value) ? (hotk->status | WLED_ON) : (hotk->status & ~WLED_ON); + + /* We don't have to check if mt_wled exists if we are here :) */ + if (!write_acpi_int(hotk->handle, hotk->methods->mt_wled, led_out, + NULL)) + printk(KERN_NOTICE "Asus ACPI: WLED write failed\n"); + + + return count; +} + + +static int get_lcd_state(struct asus_hotk *hotk) +{ + int lcd = 0; + + /* We don't have to check anything, if we are here */ + if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) + printk(KERN_NOTICE "Asus ACPI: Error reading LCD status\n"); + + if (hotk->model == L2X) + lcd = ~lcd; + + return (lcd & 1); +} + + +static int +proc_read_lcd(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + return sprintf(page, "%d\n", get_lcd_state((struct asus_hotk *) data)); +} + + +static int +proc_write_lcd(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int value; + int lcd = 0; + acpi_status status = 0; + int lcd_status = 0; + struct asus_hotk *hotk = (struct asus_hotk *) data; + + /* scan expression. Multiple expressions may be delimited with ; */ + if (sscanf(buffer, "%i", &value) == 1) + lcd = value & 1; + + lcd_status = get_lcd_state(hotk); + + if (lcd_status != lcd) { + /* switch */ + status = + acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch, + NULL, NULL); + if (ACPI_FAILURE(status)) + printk(KERN_NOTICE "Asus ACPI: Error switching LCD\n"); + } + + return count; +} + + +/* + * Change the brightness level + */ +static void set_brightness(int value, struct asus_hotk *hotk) +{ + acpi_status status = 0; + + /* ATKD laptop */ + if(hotk->methods->brightness_set) { + if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, + value, NULL)) + printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n"); + return; + } + + /* HOTK laptop if we are here, act as appropriate */ + value -= hotk->brightness; + while (value != 0) { + status = acpi_evaluate_object(NULL, (value > 0) ? + hotk->methods->brightness_up : + hotk->methods->brightness_down, + NULL, NULL); + (value > 0) ? value-- : value++; + if (ACPI_FAILURE(status)) + printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n"); + } + return; +} + +static int read_brightness(struct asus_hotk *hotk) +{ + int value; + + if(hotk->methods->brightness_get) { /* ATKD laptop */ + if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, + &value)) + printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n"); + } else if (hotk->methods->brightness_status) { /* For D1 for example */ + if (!read_acpi_int(NULL, hotk->methods->brightness_status, + &value)) + printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n"); + } else /* HOTK laptop */ + value = hotk->brightness; + return value; +} + +static int +proc_read_brn(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + struct asus_hotk *hotk = (struct asus_hotk *) data; + return sprintf(page, "%d\n", read_brightness(hotk)); +} + +static int +proc_write_brn(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int value; + struct asus_hotk *hotk = (struct asus_hotk *) data; + + /* scan expression. Multiple expressions may be delimited with ; */ + if (sscanf(buffer, "%d", &value) == 1) { + value = (0 < value) ? ((15 < value) ? 15 : value) : 0; + /* 0 <= value <= 15 */ + set_brightness(value, hotk); + } else { + printk(KERN_NOTICE "Asus ACPI: Error reading user input\n"); + } + + return count; +} + +static void set_display(int value, struct asus_hotk *hotk) +{ + /* no sanity check needed for now */ + if (!write_acpi_int(hotk->handle, hotk->methods->display_set, + value, NULL)) + printk(KERN_NOTICE "Asus ACPI: Error setting display\n"); + return; +} + +/* + * Now, *this* one could be more user-friendly, but so far, no-one has + * complained. The significance of bits is the same as in proc_write_disp() + */ + +static int +proc_read_disp(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + int value = 0; + struct asus_hotk *hotk = (struct asus_hotk *) data; + + if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) + printk(KERN_NOTICE "Asus ACPI: Error reading display status\n"); + return sprintf(page, "%d\n", value); +} + +/* + * Preliminary support for display switching. As of now: 0x01 should activate + * the LCD output, 0x02 should do for CRT, and 0x04 for TV-Out. Any combination + * (bitwise) of these will suffice. I never actually tested 3 displays hooked up + * simultaneously, so be warned. + */ + +static int +proc_write_disp(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int value; + struct asus_hotk *hotk = (struct asus_hotk *) data; + + /* scan expression. Multiple expressions may be delimited with ; */ + if (sscanf(buffer, "%d", &value) == 1) + set_display(value, hotk); + else { + printk(KERN_NOTICE "Asus ACPI: Error reading user input\n"); + } + + return count; +} + +static int asus_hotk_add_fs(struct acpi_device *device) +{ + struct proc_dir_entry *proc; + struct asus_hotk *hotk = acpi_driver_data(device); + mode_t mode; + + /* + * If parameter uid or gid is not changed, keep the default setting for + * our proc entries (-rw-rw-rw-) else, it means we care about security, + * and then set to -rw-rw---- + */ + + if ((asus_uid == 0) && (asus_gid == 0)){ + mode = S_IFREG | S_IRUGO | S_IWUGO; + }else{ + mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; + } + + acpi_device_dir(device) = asus_proc_dir; + if (!acpi_device_dir(device)) + return(-ENODEV); + + proc = create_proc_entry(PROC_INFOS, mode, acpi_device_dir(device)); + if (proc) { + proc->read_proc = proc_read_info; + proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid;; + } else { + printk(KERN_NOTICE " Unable to create " PROC_INFOS + " fs entry\n"); + } + + if (hotk->methods->mt_wled) { + proc = create_proc_entry(PROC_WLED, mode, acpi_device_dir(device)); + if (proc) { + proc->write_proc = proc_write_wled; + proc->read_proc = proc_read_wled; + proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid;; + } else { + printk(KERN_NOTICE " Unable to create " PROC_WLED + " fs entry\n"); + } + } + + if (hotk->methods->mt_mled) { + proc = create_proc_entry(PROC_MLED, mode, acpi_device_dir(device)); + if (proc) { + proc->write_proc = proc_write_mled; + proc->read_proc = proc_read_mled; + proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid;; + } else { + printk(KERN_NOTICE " Unable to create " PROC_MLED + " fs entry\n"); + } + } + + /* + * We need both read node and write method as LCD switch is also accessible + * from keyboard + */ + if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { + proc = create_proc_entry(PROC_LCD, mode, acpi_device_dir(device)); + if (proc) { + proc->write_proc = proc_write_lcd; + proc->read_proc = proc_read_lcd; + proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid;; + } else { + printk(KERN_NOTICE " Unable to create " PROC_LCD + " fs entry\n"); + } + } + + if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || + (hotk->methods->brightness_get && hotk->methods->brightness_get)) { + proc = create_proc_entry(PROC_BRN, mode, acpi_device_dir(device)); + if (proc) { + proc->write_proc = proc_write_brn; + proc->read_proc = proc_read_brn; + proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid;; + } else { + printk(KERN_NOTICE " Unable to create " PROC_BRN + " fs entry\n"); + } + } + + if (hotk->methods->display_set) { + proc = create_proc_entry(PROC_DISP, mode, acpi_device_dir(device)); + if (proc) { + proc->write_proc = proc_write_disp; + proc->read_proc = proc_read_disp; + proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid;; + } else { + printk(KERN_NOTICE " Unable to create " PROC_DISP + " fs entry\n"); + } + } + + return (AE_OK); +} + + +static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) +{ + /* TODO Find a better way to handle events count. Here, in data, we receive + * the hotk, so we can make anything !! + */ + struct asus_hotk *hotk = (struct asus_hotk *) data; + + if (!hotk) + return; + + if ((event & ~((u32) BR_UP)) < 16) { + hotk->brightness = (event & ~((u32) BR_UP)); + } else if ((event & ~((u32) BR_DOWN)) < 16 ) { + hotk->brightness = (event & ~((u32) BR_DOWN)); + } + + acpi_bus_generate_event(hotk->device, event, + hotk->event_count[event % 128]++); + + return; +} + +/* + * This function is used to initialize the hotk with right values. In this + * method, we can make all the detection we want, and modify the hotk struct + */ +static int asus_hotk_get_info(struct asus_hotk *hotk) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *model = NULL; + + /* + * We have to write 0 on init this far for all ASUS models + */ + if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { + printk(KERN_NOTICE " Hotkey initialization failed\n"); + return -ENODEV; + } + + /* + * Here, we also use asus_info to make decision. For example, on INIT + * method, S1X and L1X models both reports to be L84F, but they don't + * have the same methods (L1X has WLED, S1X don't) + */ + model = (union acpi_object *) buffer.pointer; + if (model->type == ACPI_TYPE_STRING) { + printk(KERN_NOTICE " %s model detected, ", model->string.pointer); + } + + hotk->model = END_MODEL; + if (strncmp(model->string.pointer, "L3D", 3) == 0) + hotk->model = L3D; + /* + * L2B has same settings that L3X, except for GL32, but as + * there is no node to get the LCD status, and as GL32 is never + * used anywhere else, I assume it's safe, even if lcd get is + * broken for this model (TODO fix it ?) + */ + else if (strncmp(model->string.pointer, "L3", 2) == 0 || + strncmp(model->string.pointer, "L2B", 3) == 0) + hotk->model = L3X; + else if (strncmp(model->string.pointer, "M2", 2) == 0) + hotk->model = M2X; + else if (strncmp(model->string.pointer, "L2", 2) == 0) + hotk->model = L2X; + else if (strncmp(model->string.pointer, "L8", 2) == 0) + /* S1300A reports L84F, but L1400B too */ + if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) + hotk->model = L1X; + else + hotk->model = S1X; + else if (strncmp(model->string.pointer, "D1", 2) == 0) + hotk->model = D1X; + else if (strncmp(model->string.pointer, "A1", 2) == 0) + hotk->model = A1X; + else if (strncmp(model->string.pointer, "J1", 2) == 0) + hotk->model = J1X; + + + if (hotk->model == END_MODEL) { + /* By default use the same values, as I don't know others */ + printk("unsupported, trying default values, contact the " + "developers\n"); + hotk->model = L2X; + } else { + printk("supported\n"); + } + + hotk->methods = &model_conf[hotk->model]; + + acpi_os_free(model); + + return AE_OK; +} + + + +static int asus_hotk_check(struct asus_hotk *hotk) +{ + int result = 0; + + if (!hotk) + return(-EINVAL); + + result = acpi_bus_get_status(hotk->device); + if (result) + return(result); + + if (hotk->device->status.present) { + result = asus_hotk_get_info(hotk); + } else { + printk(KERN_NOTICE " Hotkey device not present, aborting\n"); + return(-EINVAL); + } + + return(result); +} + + + +static int asus_hotk_add(struct acpi_device *device) +{ + struct asus_hotk *hotk = NULL; + acpi_status status = AE_OK; + int result; + + if (!device) + return(-EINVAL); + + hotk = + (struct asus_hotk *) kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); + if (!hotk) + return(-ENOMEM); + memset(hotk, 0, sizeof(struct asus_hotk)); + + hotk->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_HOTK_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_HOTK_CLASS); + acpi_driver_data(device) = hotk; + hotk->device = device; + + + result = asus_hotk_check(hotk); + if (result) + goto end; + + result = asus_hotk_add_fs(device); + if (result) + goto end; + + /* + * We install the handler, it will receive the hotk in parameter, so, we + * could add other data to the hotk struct + */ + status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, + asus_hotk_notify, hotk); + if (ACPI_FAILURE(status)) { + printk(KERN_NOTICE + " Error installing notify handler\n"); + } else { + printk(KERN_DEBUG + " Notify Handler installed successfully\n"); + } + + /* For HOTK laptops: init the hotk->brightness value */ + if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) && + (hotk->methods->brightness_up && hotk->methods->brightness_down)) { + status = acpi_evaluate_object(NULL, hotk->methods->brightness_down, + NULL, NULL); + if (ACPI_FAILURE(status)) + printk(KERN_NOTICE " Error changing brightness\n"); + status = acpi_evaluate_object(NULL, hotk->methods->brightness_up, + NULL, NULL); + if (ACPI_FAILURE(status)) + printk(KERN_NOTICE " Error changing brightness\n"); + } + + end: + if (result) { + kfree(hotk); + } + + return(result); +} + + + + +static int asus_hotk_remove(struct acpi_device *device, int type) +{ + acpi_status status = 0; + struct asus_hotk *hotk = NULL; + + if (!device || !acpi_driver_data(device)) + return(-EINVAL); + + hotk = (struct asus_hotk *) acpi_driver_data(device); + + status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, + asus_hotk_notify); + if (ACPI_FAILURE(status)) + printk(KERN_NOTICE "Error removing notify handler\n"); + + kfree(hotk); + + return(0); +} + + + + +static int __init asus_acpi_init(void) +{ + int result = 0; + acpi_status status = 0; + struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; + + printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", + ASUS_ACPI_VERSION); + /* + * Here is the code to know the model we are running on. We need to + * know this before calling the acpi_bus_register_driver function, in + * case the HID for the laptop we are running on is different from + * ACPI_HOTK_HID, which I have never seen yet :) + * + * This information is then available in the global var asus_info + */ + status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt); + if (ACPI_FAILURE(status)) { + printk(KERN_NOTICE " Couldn't get the DSDT table header\n"); + } else { + asus_info = (struct acpi_table_header *) dsdt.pointer; + } + + asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); + if (!asus_proc_dir) + return(-ENODEV); + asus_proc_dir->owner = THIS_MODULE; + + result = acpi_bus_register_driver(&asus_hotk_driver); + if (result < 0) { + printk(KERN_NOTICE " Error registering " ACPI_HOTK_NAME " \n"); + remove_proc_entry(PROC_ASUS, acpi_root_dir); + return(-ENODEV); + } + + return(0); +} + + + +static void __exit asus_acpi_exit(void) +{ + acpi_bus_unregister_driver(&asus_hotk_driver); + remove_proc_entry(PROC_ASUS, acpi_root_dir); + + acpi_os_free(asus_info); + + return; +} + +module_init(asus_acpi_init); +module_exit(asus_acpi_exit); diff -urN linux-2.4.21/drivers/acpi/battery.c linux-2.4.22/drivers/acpi/battery.c --- linux-2.4.21/drivers/acpi/battery.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/battery.c 2003-08-25 04:44:40.000000000 -0700 @@ -0,0 +1,825 @@ +/* + * acpi_battery.c - ACPI Battery Driver ($Revision: 36 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_BATTERY_COMPONENT +ACPI_MODULE_NAME ("acpi_battery") + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +#define PREFIX "ACPI: " + + +#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF + +#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" +#define ACPI_BATTERY_FORMAT_BST "NNNN" + +static int acpi_battery_add (struct acpi_device *device); +static int acpi_battery_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_battery_driver = { + .name = ACPI_BATTERY_DRIVER_NAME, + .class = ACPI_BATTERY_CLASS, + .ids = ACPI_BATTERY_HID, + .ops = { + .add = acpi_battery_add, + .remove = acpi_battery_remove, + }, +}; + +struct acpi_battery_status { + acpi_integer state; + acpi_integer present_rate; + acpi_integer remaining_capacity; + acpi_integer present_voltage; +}; + +struct acpi_battery_info { + acpi_integer power_unit; + acpi_integer design_capacity; + acpi_integer last_full_capacity; + acpi_integer battery_technology; + acpi_integer design_voltage; + acpi_integer design_capacity_warning; + acpi_integer design_capacity_low; + acpi_integer battery_capacity_granularity_1; + acpi_integer battery_capacity_granularity_2; + acpi_string model_number; + acpi_string serial_number; + acpi_string battery_type; + acpi_string oem_info; +}; + +struct acpi_battery_flags { + u8 present:1; /* Bay occupied? */ + u8 power_unit:1; /* 0=watts, 1=apms */ + u8 alarm:1; /* _BTP present? */ + u8 reserved:5; +}; + +struct acpi_battery_trips { + unsigned long warning; + unsigned long low; +}; + +struct acpi_battery { + acpi_handle handle; + struct acpi_battery_flags flags; + struct acpi_battery_trips trips; + unsigned long alarm; + struct acpi_battery_info *info; +}; + + +/* -------------------------------------------------------------------------- + Battery Management + -------------------------------------------------------------------------- */ + +static int +acpi_battery_get_info ( + struct acpi_battery *battery, + struct acpi_battery_info **bif) +{ + int result = 0; + acpi_status status = 0; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_buffer format = {sizeof(ACPI_BATTERY_FORMAT_BIF), + ACPI_BATTERY_FORMAT_BIF}; + struct acpi_buffer data = {0, NULL}; + union acpi_object *package = NULL; + + ACPI_FUNCTION_TRACE("acpi_battery_get_info"); + + if (!battery || !bif) + return_VALUE(-EINVAL); + + /* Evalute _BIF */ + + status = acpi_evaluate_object(battery->handle, "_BIF", NULL, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BIF\n")); + return_VALUE(-ENODEV); + } + + package = (union acpi_object *) buffer.pointer; + + /* Extract Package Data */ + + status = acpi_extract_package(package, &format, &data); + if (status != AE_BUFFER_OVERFLOW) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BIF\n")); + result = -ENODEV; + goto end; + } + + data.pointer = kmalloc(data.length, GFP_KERNEL); + if (!data.pointer) { + result = -ENOMEM; + goto end; + } + memset(data.pointer, 0, data.length); + + status = acpi_extract_package(package, &format, &data); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BIF\n")); + kfree(data.pointer); + result = -ENODEV; + goto end; + } + +end: + acpi_os_free(buffer.pointer); + + if (!result) + (*bif) = (struct acpi_battery_info *) data.pointer; + + return_VALUE(result); +} + +static int +acpi_battery_get_status ( + struct acpi_battery *battery, + struct acpi_battery_status **bst) +{ + int result = 0; + acpi_status status = 0; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_buffer format = {sizeof(ACPI_BATTERY_FORMAT_BST), + ACPI_BATTERY_FORMAT_BST}; + struct acpi_buffer data = {0, NULL}; + union acpi_object *package = NULL; + + ACPI_FUNCTION_TRACE("acpi_battery_get_status"); + + if (!battery || !bst) + return_VALUE(-EINVAL); + + /* Evalute _BST */ + + status = acpi_evaluate_object(battery->handle, "_BST", NULL, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BST\n")); + return_VALUE(-ENODEV); + } + + package = (union acpi_object *) buffer.pointer; + + /* Extract Package Data */ + + status = acpi_extract_package(package, &format, &data); + if (status != AE_BUFFER_OVERFLOW) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n")); + result = -ENODEV; + goto end; + } + + data.pointer = kmalloc(data.length, GFP_KERNEL); + if (!data.pointer) { + result = -ENOMEM; + goto end; + } + memset(data.pointer, 0, data.length); + + status = acpi_extract_package(package, &format, &data); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n")); + kfree(data.pointer); + result = -ENODEV; + goto end; + } + +end: + acpi_os_free(buffer.pointer); + + if (!result) + (*bst) = (struct acpi_battery_status *) data.pointer; + + return_VALUE(result); +} + + +static int +acpi_battery_set_alarm ( + struct acpi_battery *battery, + unsigned long alarm) +{ + acpi_status status = 0; + union acpi_object arg0 = {ACPI_TYPE_INTEGER}; + struct acpi_object_list arg_list = {1, &arg0}; + + ACPI_FUNCTION_TRACE("acpi_battery_set_alarm"); + + if (!battery) + return_VALUE(-EINVAL); + + if (!battery->flags.alarm) + return_VALUE(-ENODEV); + + arg0.integer.value = alarm; + + status = acpi_evaluate_object(battery->handle, "_BTP", &arg_list, NULL); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm)); + + battery->alarm = alarm; + + return_VALUE(0); +} + + +static int +acpi_battery_check ( + struct acpi_battery *battery) +{ + int result = 0; + acpi_status status = AE_OK; + acpi_handle handle = NULL; + struct acpi_device *device = NULL; + struct acpi_battery_info *bif = NULL; + + ACPI_FUNCTION_TRACE("acpi_battery_check"); + + if (!battery) + return_VALUE(-EINVAL); + + result = acpi_bus_get_device(battery->handle, &device); + if (result) + return_VALUE(result); + + result = acpi_bus_get_status(device); + if (result) + return_VALUE(result); + + /* Insertion? */ + + if (!battery->flags.present && device->status.battery_present) { + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); + + /* Evalute _BIF to get certain static information */ + + result = acpi_battery_get_info(battery, &bif); + if (result) + return_VALUE(result); + + battery->flags.power_unit = bif->power_unit; + battery->trips.warning = bif->design_capacity_warning; + battery->trips.low = bif->design_capacity_low; + kfree(bif); + + /* See if alarms are supported, and if so, set default */ + + status = acpi_get_handle(battery->handle, "_BTP", &handle); + if (ACPI_SUCCESS(status)) { + battery->flags.alarm = 1; + acpi_battery_set_alarm(battery, battery->trips.warning); + } + } + + /* Removal? */ + + else if (battery->flags.present && !device->status.battery_present) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n")); + } + + battery->flags.present = device->status.battery_present; + + return_VALUE(result); +} + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_battery_dir = NULL; + +static int +acpi_battery_read_info ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + int result = 0; + struct acpi_battery *battery = (struct acpi_battery *) data; + struct acpi_battery_info *bif = NULL; + char *units = "?"; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_battery_read_info"); + + if (!battery) + goto end; + + if (battery->flags.present) + p += sprintf(p, "present: yes\n"); + else { + p += sprintf(p, "present: no\n"); + goto end; + } + + /* Battery Info (_BIF) */ + + result = acpi_battery_get_info(battery, &bif); + if (result || !bif) { + p += sprintf(p, "ERROR: Unable to read battery information\n"); + goto end; + } + + units = bif->power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + p += sprintf(p, "design capacity: unknown\n"); + else + p += sprintf(p, "design capacity: %d %sh\n", + (u32) bif->design_capacity, units); + + if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + p += sprintf(p, "last full capacity: unknown\n"); + else + p += sprintf(p, "last full capacity: %d %sh\n", + (u32) bif->last_full_capacity, units); + + switch ((u32) bif->battery_technology) { + case 0: + p += sprintf(p, "battery technology: non-rechargeable\n"); + break; + case 1: + p += sprintf(p, "battery technology: rechargeable\n"); + break; + default: + p += sprintf(p, "battery technology: unknown\n"); + break; + } + + if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) + p += sprintf(p, "design voltage: unknown\n"); + else + p += sprintf(p, "design voltage: %d mV\n", + (u32) bif->design_voltage); + + p += sprintf(p, "design capacity warning: %d %sh\n", + (u32) bif->design_capacity_warning, units); + p += sprintf(p, "design capacity low: %d %sh\n", + (u32) bif->design_capacity_low, units); + p += sprintf(p, "capacity granularity 1: %d %sh\n", + (u32) bif->battery_capacity_granularity_1, units); + p += sprintf(p, "capacity granularity 2: %d %sh\n", + (u32) bif->battery_capacity_granularity_2, units); + p += sprintf(p, "model number: %s\n", + bif->model_number); + p += sprintf(p, "serial number: %s\n", + bif->serial_number); + p += sprintf(p, "battery type: %s\n", + bif->battery_type); + p += sprintf(p, "OEM info: %s\n", + bif->oem_info); + +end: + kfree(bif); + + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_battery_read_state ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + int result = 0; + struct acpi_battery *battery = (struct acpi_battery *) data; + struct acpi_battery_status *bst = NULL; + char *units = "?"; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_battery_read_state"); + + if (!battery) + goto end; + + if (battery->flags.present) + p += sprintf(p, "present: yes\n"); + else { + p += sprintf(p, "present: no\n"); + goto end; + } + + /* Battery Units */ + + units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + /* Battery Status (_BST) */ + + result = acpi_battery_get_status(battery, &bst); + if (result || !bst) { + p += sprintf(p, "ERROR: Unable to read battery status\n"); + goto end; + } + + if (!(bst->state & 0x04)) + p += sprintf(p, "capacity state: ok\n"); + else + p += sprintf(p, "capacity state: critical\n"); + + if ((bst->state & 0x01) && (bst->state & 0x02)) + p += sprintf(p, "charging state: charging/discharging\n"); + else if (bst->state & 0x01) + p += sprintf(p, "charging state: discharging\n"); + else if (bst->state & 0x02) + p += sprintf(p, "charging state: charging\n"); + else + p += sprintf(p, "charging state: unknown\n"); + + if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) + p += sprintf(p, "present rate: unknown\n"); + else + p += sprintf(p, "present rate: %d %s\n", + (u32) bst->present_rate, units); + + if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + p += sprintf(p, "remaining capacity: unknown\n"); + else + p += sprintf(p, "remaining capacity: %d %sh\n", + (u32) bst->remaining_capacity, units); + + if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) + p += sprintf(p, "present voltage: unknown\n"); + else + p += sprintf(p, "present voltage: %d mV\n", + (u32) bst->present_voltage); + +end: + kfree(bst); + + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_battery_read_alarm ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_battery *battery = (struct acpi_battery *) data; + char *units = "?"; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_battery_read_alarm"); + + if (!battery) + goto end; + + if (!battery->flags.present) { + p += sprintf(p, "present: no\n"); + goto end; + } + + /* Battery Units */ + + units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + /* Battery Alarm */ + + p += sprintf(p, "alarm: "); + if (!battery->alarm) + p += sprintf(p, "unsupported\n"); + else + p += sprintf(p, "%d %sh\n", (u32) battery->alarm, units); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_battery_write_alarm ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_battery *battery = (struct acpi_battery *) data; + char alarm_string[12] = {'\0'}; + + ACPI_FUNCTION_TRACE("acpi_battery_write_alarm"); + + if (!battery || (count > sizeof(alarm_string) - 1)) + return_VALUE(-EINVAL); + + if (!battery->flags.present) + return_VALUE(-ENODEV); + + if (copy_from_user(alarm_string, buffer, count)) + return_VALUE(-EFAULT); + + alarm_string[count] = '\0'; + + result = acpi_battery_set_alarm(battery, + simple_strtoul(alarm_string, NULL, 0)); + if (result) + return_VALUE(result); + + return_VALUE(count); +} + + +static int +acpi_battery_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_battery_add_fs"); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_battery_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + /* 'info' [R] */ + entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_BATTERY_FILE_INFO)); + else { + entry->read_proc = acpi_battery_read_info; + entry->data = acpi_driver_data(device); + } + + /* 'status' [R] */ + entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_BATTERY_FILE_STATUS)); + else { + entry->read_proc = acpi_battery_read_state; + entry->data = acpi_driver_data(device); + } + + /* 'alarm' [R/W] */ + entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_BATTERY_FILE_ALARM)); + else { + entry->read_proc = acpi_battery_read_alarm; + entry->write_proc = acpi_battery_write_alarm; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + + +static int +acpi_battery_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_battery_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +static void +acpi_battery_notify ( + acpi_handle handle, + u32 event, + void *data) +{ + struct acpi_battery *battery = (struct acpi_battery *) data; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_battery_notify"); + + if (!battery) + return_VOID; + + if (acpi_bus_get_device(handle, &device)) + return_VOID; + + switch (event) { + case ACPI_BATTERY_NOTIFY_STATUS: + case ACPI_BATTERY_NOTIFY_INFO: + acpi_battery_check(battery); + acpi_bus_generate_event(device, event, battery->flags.present); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return_VOID; +} + + +static int +acpi_battery_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = 0; + struct acpi_battery *battery = NULL; + + ACPI_FUNCTION_TRACE("acpi_battery_add"); + + if (!device) + return_VALUE(-EINVAL); + + battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL); + if (!battery) + return_VALUE(-ENOMEM); + memset(battery, 0, sizeof(struct acpi_battery)); + + battery->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_BATTERY_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_BATTERY_CLASS); + acpi_driver_data(device) = battery; + + result = acpi_battery_check(battery); + if (result) + goto end; + + result = acpi_battery_add_fs(device); + if (result) + goto end; + + status = acpi_install_notify_handler(battery->handle, + ACPI_DEVICE_NOTIFY, acpi_battery_notify, battery); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + result = -ENODEV; + goto end; + } + + printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", + ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), + device->status.battery_present?"present":"absent"); + +end: + if (result) { + acpi_battery_remove_fs(device); + kfree(battery); + } + + return_VALUE(result); +} + + +static int +acpi_battery_remove ( + struct acpi_device *device, + int type) +{ + acpi_status status = 0; + struct acpi_battery *battery = NULL; + + ACPI_FUNCTION_TRACE("acpi_battery_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + battery = (struct acpi_battery *) acpi_driver_data(device); + + status = acpi_remove_notify_handler(battery->handle, + ACPI_DEVICE_NOTIFY, acpi_battery_notify); + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + + acpi_battery_remove_fs(device); + + kfree(battery); + + return_VALUE(0); +} + + +static int __init +acpi_battery_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_battery_init"); + + acpi_battery_dir = proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); + if (!acpi_battery_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_battery_driver); + if (result < 0) { + remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +static void __exit +acpi_battery_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_battery_exit"); + + acpi_bus_unregister_driver(&acpi_battery_driver); + + remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); + + return_VOID; +} + + +module_init(acpi_battery_init); +module_exit(acpi_battery_exit); diff -urN linux-2.4.21/drivers/acpi/blacklist.c linux-2.4.22/drivers/acpi/blacklist.c --- linux-2.4.21/drivers/acpi/blacklist.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/blacklist.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,141 @@ +/* + * blacklist.c + * + * Check to see if the given machine has a known bad ACPI BIOS + * + * Copyright (C) 2002 Andy Grover + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 + +#define PREFIX "ACPI: " + +enum acpi_blacklist_predicates +{ + all_versions, + less_than_or_equal, + equal, + greater_than_or_equal, +}; + +struct acpi_blacklist_item +{ + char oem_id[7]; + char oem_table_id[9]; + u32 oem_revision; + acpi_table_type table; + enum acpi_blacklist_predicates oem_revision_predicate; + char *reason; + u32 is_critical_error; +}; + +/* + * POLICY: If *anything* doesn't work, put it on the blacklist. + * If they are critical errors, mark it critical, and abort driver load. + */ +static struct acpi_blacklist_item acpi_blacklist[] __initdata = +{ + /* Portege 7020, BIOS 8.10 */ + {"TOSHIB", "7020CT ", 0x19991112, ACPI_DSDT, all_versions, "Implicit Return", 0}, + /* Portege 4030 */ + {"TOSHIB", "4030 ", 0x19991112, ACPI_DSDT, all_versions, "Implicit Return", 0}, + /* Portege 310/320, BIOS 7.1 */ + {"TOSHIB", "310 ", 0x19990511, ACPI_DSDT, all_versions, "Implicit Return", 0}, + /* Seattle 2, old bios rev. */ + {"INTEL ", "440BX ", 0x00001000, ACPI_DSDT, less_than_or_equal, "Field beyond end of region", 0}, + /* ASUS K7M */ + {"ASUS ", "K7M ", 0x00001000, ACPI_DSDT, less_than_or_equal, "Field beyond end of region", 0}, + /* Intel 810 Motherboard? */ + {"MNTRAL", "MO81010A", 0x00000012, ACPI_DSDT, less_than_or_equal, "Field beyond end of region", 0}, + /* Compaq Presario 711FR */ + {"COMAPQ", "EAGLES", 0x06040000, ACPI_DSDT, less_than_or_equal, "SCI issues (C2 disabled)", 0}, + /* Compaq Presario 1700 */ + {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal, "Multiple problems", 1}, + /* Sony FX120, FX140, FX150? */ + {"SONY ", "U0 ", 0x20010313, ACPI_DSDT, less_than_or_equal, "ACPI driver problem", 1}, + /* Compaq Presario 800, Insyde BIOS */ + {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal, "Does not use _REG to protect EC OpRegions", 1}, + /* IBM 600E - _ADR should return 7, but it returns 1 */ + {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT, less_than_or_equal, "Incorrect _ADR", 1}, + {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions, "Bogus PCI routing", 1}, + + {""} +}; + + +int __init +acpi_blacklisted(void) +{ + int i = 0; + int blacklisted = 0; + struct acpi_table_header *table_header; + + while (acpi_blacklist[i].oem_id[0] != '\0') + { + if (acpi_get_table_header_early(acpi_blacklist[i].table, &table_header)) { + i++; + continue; + } + + if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) { + i++; + continue; + } + + if (strncmp(acpi_blacklist[i].oem_table_id, table_header->oem_table_id, 8)) { + i++; + continue; + } + + if ((acpi_blacklist[i].oem_revision_predicate == all_versions) + || (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal + && table_header->oem_revision <= acpi_blacklist[i].oem_revision) + || (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal + && table_header->oem_revision >= acpi_blacklist[i].oem_revision) + || (acpi_blacklist[i].oem_revision_predicate == equal + && table_header->oem_revision == acpi_blacklist[i].oem_revision)) { + + printk(KERN_ERR PREFIX "Vendor \"%6.6s\" System \"%8.8s\" " + "Revision 0x%x has a known ACPI BIOS problem.\n", + acpi_blacklist[i].oem_id, + acpi_blacklist[i].oem_table_id, + acpi_blacklist[i].oem_revision); + + printk(KERN_ERR PREFIX "Reason: %s. This is a %s error\n", + acpi_blacklist[i].reason, + (acpi_blacklist[i].is_critical_error ? "non-recoverable" : "recoverable")); + + blacklisted = acpi_blacklist[i].is_critical_error; + break; + } + else { + i++; + } + } + + return blacklisted; +} + diff -urN linux-2.4.21/drivers/acpi/bus.c linux-2.4.22/drivers/acpi/bus.c --- linux-2.4.21/drivers/acpi/bus.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/bus.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,2092 @@ +/* + * acpi_bus.c - ACPI Bus Driver ($Revision: 77 $) + * + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_X86 +#include +#endif +#include +#include +#include /* for acpi_ex_eisa_id_to_string() */ + + +#define _COMPONENT ACPI_BUS_COMPONENT +ACPI_MODULE_NAME ("acpi_bus") + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_BUS_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +#define PREFIX "ACPI: " + +extern void eisa_set_level_irq(unsigned int irq); + +extern int acpi_disabled; + +FADT_DESCRIPTOR acpi_fadt; +struct acpi_device *acpi_root; +struct proc_dir_entry *acpi_root_dir; + +#define STRUCT_TO_INT(s) (*((int*)&s)) + + +/* -------------------------------------------------------------------------- + Linux Driver Model (LDM) Support + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_LDM + +static int acpi_device_probe(struct device *dev); +static int acpi_device_remove(struct device *dev); +static int acpi_device_suspend(struct device *dev, u32 state, u32 stage); +static int acpi_device_resume(struct device *dev, u32 stage); + +static struct device_driver acpi_bus_driver = { + .probe = acpi_device_probe, + .remove = acpi_device_remove, + .suspend = acpi_device_suspend, + .resume = acpi_device_resume, +}; + + +static int +acpi_device_probe ( + struct device *dev) +{ + ACPI_FUNCTION_TRACE("acpi_device_probe"); + + if (!dev) + return_VALUE(-EINVAL); + + /* TBD */ + + return_VALUE(0); +} + + +static int +acpi_device_remove ( + struct device *dev) +{ + ACPI_FUNCTION_TRACE("acpi_device_remove"); + + if (!dev) + return_VALUE(-EINVAL); + + /* TBD */ + + return_VALUE(0); +} + + +static int +acpi_device_suspend ( + struct device *dev, + u32 state, + u32 stage) +{ + ACPI_FUNCTION_TRACE("acpi_device_suspend"); + + if (!dev) + return_VALUE(-EINVAL); + + /* TBD */ + + return_VALUE(0); +} + + +static int +acpi_device_resume ( + struct device *dev, + u32 stage) +{ + ACPI_FUNCTION_TRACE("acpi_device_resume"); + + if (!dev) + return_VALUE(-EINVAL); + + /* TBD */ + + return_VALUE(0); +} + +#if 0 /* not used ATM */ +static int +acpi_platform_add ( + struct device *dev) +{ + ACPI_FUNCTION_TRACE("acpi_platform_add"); + + if (!dev) + return -EINVAL; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s (%s) added\n", + dev->name, dev->bus_id)); + + /* TBD */ + + return_VALUE(0); +} + + +static int +acpi_platform_remove ( + struct device *dev) +{ + ACPI_FUNCTION_TRACE("acpi_platform_add"); + + if (!dev) + return -EINVAL; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s (%s) removed\n", + dev->name, dev->bus_id)); + + /* TBD */ + + return_VALUE(0); +} +#endif /* unused */ + + +#endif /*CONFIG_LDM*/ + + +static int +acpi_device_register ( + struct acpi_device *device, + struct acpi_device *parent) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_device_register"); + + if (!device) + return_VALUE(-EINVAL); + +#ifdef CONFIG_LDM + sprintf(device->dev.name, "ACPI device %s:%s", + device->pnp.hardware_id, device->pnp.unique_id); + strncpy(device->dev.bus_id, device->pnp.bus_id, sizeof(acpi_bus_id)); + if (parent) + device->dev.parent = &parent->dev; + device->dev.driver = &acpi_bus_driver; + + result = device_register(&device->dev); +#endif /*CONFIG_LDM*/ + + return_VALUE(result); +} + + +static int +acpi_device_unregister ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_device_unregister"); + + if (!device) + return_VALUE(-EINVAL); + +#ifdef CONFIG_LDM + put_device(&device->dev); +#endif /*CONFIG_LDM*/ + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Device Management + -------------------------------------------------------------------------- */ + +static void +acpi_bus_data_handler ( + acpi_handle handle, + u32 function, + void *context) +{ + ACPI_FUNCTION_TRACE("acpi_bus_data_handler"); + + /* TBD */ + + return_VOID; +} + + +int +acpi_bus_get_device ( + acpi_handle handle, + struct acpi_device **device) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE("acpi_bus_get_device"); + + if (!device) + return_VALUE(-EINVAL); + + /* TBD: Support fixed-feature devices */ + + status = acpi_get_data(handle, acpi_bus_data_handler, (void**) device); + if (ACPI_FAILURE(status) || !*device) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context for object [%p]\n", + handle)); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + +int +acpi_bus_get_status ( + struct acpi_device *device) +{ + acpi_status status = AE_OK; + unsigned long sta = 0; + + ACPI_FUNCTION_TRACE("acpi_bus_get_status"); + + if (!device) + return_VALUE(-EINVAL); + + /* + * Evaluate _STA if present. + */ + if (device->flags.dynamic_status) { + status = acpi_evaluate_integer(device->handle, "_STA", NULL, &sta); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + STRUCT_TO_INT(device->status) = (int) sta; + } + + /* + * Otherwise we assume the status of our parent (unless we don't + * have one, in which case status is implied). + */ + else if (device->parent) + device->status = device->parent->status; + else + STRUCT_TO_INT(device->status) = 0x0F; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", + device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status))); + + return_VALUE(0); +} + + +/* +static int +acpi_bus_create_device_fs (struct device *device) +{ + ACPI_FUNCTION_TRACE("acpi_bus_create_device_fs"); + + if (!device) + return_VALUE(-EINVAL); + + if (device->dir.entry) + return_VALUE(-EEXIST); + + if (!device->parent) + device->dir.entry = proc_mkdir(device->pnp.bus_id, NULL); + else + device->dir.entry = proc_mkdir(device->pnp.bus_id, + device->parent->fs.entry); + + if (!device->dir.entry) { + printk(KERN_ERR PREFIX "Unable to create fs entry '%s'\n", + device->pnp.bus_id); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +static int +acpi_bus_remove_device_fs (struct device *device) +{ + ACPI_FUNCTION_TRACE("acpi_bus_create_device_fs"); + + if (!device) + return_VALUE(-EINVAL); + + if (!device->dir.entry) + return_VALUE(-ENODEV); + + if (!device->parent) + remove_proc_entry(device->pnp_bus_id, NULL); + else + remove_proc_entry(device->pnp.bus_id, device->parent->fs.entry); + + device->dir.entry = NULL; + + return_VALUE(0); +} +*/ + + +/* -------------------------------------------------------------------------- + Power Management + -------------------------------------------------------------------------- */ + +int +acpi_bus_get_power ( + acpi_handle handle, + int *state) +{ + int result = 0; + acpi_status status = 0; + struct acpi_device *device = NULL; + unsigned long psc = 0; + + ACPI_FUNCTION_TRACE("acpi_bus_get_power"); + + result = acpi_bus_get_device(handle, &device); + if (result) + return_VALUE(result); + + *state = ACPI_STATE_UNKNOWN; + + if (!device->flags.power_manageable) { + /* TBD: Non-recursive algorithm for walking up hierarchy */ + if (device->parent) + *state = device->parent->power.state; + else + *state = ACPI_STATE_D0; + } + else { + /* + * Get the device's power state either directly (via _PSC) or + * indirectly (via power resources). + */ + if (device->power.flags.explicit_get) { + status = acpi_evaluate_integer(device->handle, "_PSC", + NULL, &psc); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + device->power.state = (int) psc; + } + else if (device->power.flags.power_resources) { + result = acpi_power_get_inferred_state(device); + if (result) + return_VALUE(result); + } + + *state = device->power.state; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", + device->pnp.bus_id, device->power.state)); + + return_VALUE(0); +} + + +int +acpi_bus_set_power ( + acpi_handle handle, + int state) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_device *device = NULL; + char object_name[5] = {'_','P','S','0'+state,'\0'}; + + ACPI_FUNCTION_TRACE("acpi_bus_set_power"); + + result = acpi_bus_get_device(handle, &device); + if (result) + return_VALUE(result); + + if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) + return_VALUE(-EINVAL); + + /* Make sure this is a valid target state */ + + if (!device->flags.power_manageable) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n")); + return_VALUE(-ENODEV); + } + if (state == device->power.state) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state)); + return_VALUE(0); + } + if (!device->power.states[state].flags.valid) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", state)); + return_VALUE(-ENODEV); + } + if (device->parent && (state < device->parent->power.state)) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Cannot set device to a higher-powered state than parent\n")); + return_VALUE(-ENODEV); + } + + /* + * Transition Power + * ---------------- + * On transitions to a high-powered state we first apply power (via + * power resources) then evalute _PSx. Conversly for transitions to + * a lower-powered state. + */ + if (state < device->power.state) { + if (device->power.flags.power_resources) { + result = acpi_power_transition(device, state); + if (result) + goto end; + } + if (device->power.states[state].flags.explicit_set) { + status = acpi_evaluate_object(device->handle, + object_name, NULL, NULL); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto end; + } + } + } + else { + if (device->power.states[state].flags.explicit_set) { + status = acpi_evaluate_object(device->handle, + object_name, NULL, NULL); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto end; + } + } + if (device->power.flags.power_resources) { + result = acpi_power_transition(device, state); + if (result) + goto end; + } + } + +end: + if (result) + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error transitioning device [%s] to D%d\n", + device->pnp.bus_id, state)); + else + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n", + device->pnp.bus_id, state)); + + return_VALUE(result); +} + + +static int +acpi_bus_get_power_flags ( + struct acpi_device *device) +{ + acpi_status status = 0; + acpi_handle handle = 0; + u32 i = 0; + + ACPI_FUNCTION_TRACE("acpi_bus_get_power_flags"); + + if (!device) + return -ENODEV; + + /* + * Power Management Flags + */ + status = acpi_get_handle(device->handle, "_PSC", &handle); + if (ACPI_SUCCESS(status)) + device->power.flags.explicit_get = 1; + status = acpi_get_handle(device->handle, "_IRC", &handle); + if (ACPI_SUCCESS(status)) + device->power.flags.inrush_current = 1; + status = acpi_get_handle(device->handle, "_PRW", &handle); + if (ACPI_SUCCESS(status)) + device->power.flags.wake_capable = 1; + + /* + * Enumerate supported power management states + */ + for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { + struct acpi_device_power_state *ps = &device->power.states[i]; + char object_name[5] = {'_','P','R','0'+i,'\0'}; + + /* Evaluate "_PRx" to se if power resources are referenced */ + acpi_evaluate_reference(device->handle, object_name, NULL, + &ps->resources); + if (ps->resources.count) { + device->power.flags.power_resources = 1; + ps->flags.valid = 1; + } + + /* Evaluate "_PSx" to see if we can do explicit sets */ + object_name[2] = 'S'; + status = acpi_get_handle(device->handle, object_name, &handle); + if (ACPI_SUCCESS(status)) { + ps->flags.explicit_set = 1; + ps->flags.valid = 1; + } + + /* State is valid if we have some power control */ + if (ps->resources.count || ps->flags.explicit_set) + ps->flags.valid = 1; + + ps->power = -1; /* Unknown - driver assigned */ + ps->latency = -1; /* Unknown - driver assigned */ + } + + /* Set defaults for D0 and D3 states (always valid) */ + device->power.states[ACPI_STATE_D0].flags.valid = 1; + device->power.states[ACPI_STATE_D0].power = 100; + device->power.states[ACPI_STATE_D3].flags.valid = 1; + device->power.states[ACPI_STATE_D3].power = 0; + + /* + * System Power States + * ------------------- + */ + /* TBD: S1-S4 power state support and resource requirements. */ + /* + for (i=ACPI_STATE_S1; ihandle, name, NULL, + &state); + if (ACPI_FAILURE(status)) + continue; + } + */ + + /* TBD: System wake support and resource requirements. */ + + device->power.state = ACPI_STATE_UNKNOWN; + + return 0; +} + + +/* -------------------------------------------------------------------------- + Performance Management + -------------------------------------------------------------------------- */ + +static int +acpi_bus_get_perf_flags ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_bus_get_perf_flags"); + + if (!device) + return -ENODEV; + + device->performance.state = ACPI_STATE_UNKNOWN; + + return 0; +} + + +/* -------------------------------------------------------------------------- + Event Management + -------------------------------------------------------------------------- */ + +static spinlock_t acpi_bus_event_lock = SPIN_LOCK_UNLOCKED; + +LIST_HEAD(acpi_bus_event_list); +DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); + +extern int event_is_open; + +int +acpi_bus_generate_event ( + struct acpi_device *device, + u8 type, + int data) +{ + struct acpi_bus_event *event = NULL; + u32 flags = 0; + + ACPI_FUNCTION_TRACE("acpi_bus_generate_event"); + + if (!device) + return_VALUE(-EINVAL); + + /* drop event on the floor if no one's listening */ + if (!event_is_open) + return_VALUE(0); + + event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC); + if (!event) + return_VALUE(-ENOMEM); + + sprintf(event->device_class, "%s", device->pnp.device_class); + sprintf(event->bus_id, "%s", device->pnp.bus_id); + event->type = type; + event->data = data; + + spin_lock_irqsave(&acpi_bus_event_lock, flags); + list_add_tail(&event->node, &acpi_bus_event_list); + spin_unlock_irqrestore(&acpi_bus_event_lock, flags); + + wake_up_interruptible(&acpi_bus_event_queue); + + return_VALUE(0); +} + +int +acpi_bus_receive_event ( + struct acpi_bus_event *event) +{ + u32 flags = 0; + struct acpi_bus_event *entry = NULL; + + DECLARE_WAITQUEUE(wait, current); + + ACPI_FUNCTION_TRACE("acpi_bus_receive_event"); + + if (!event) + return -EINVAL; + + if (list_empty(&acpi_bus_event_list)) { + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&acpi_bus_event_queue, &wait); + + if (list_empty(&acpi_bus_event_list)) + schedule(); + + remove_wait_queue(&acpi_bus_event_queue, &wait); + set_current_state(TASK_RUNNING); + + if (signal_pending(current)) + return_VALUE(-ERESTARTSYS); + } + + spin_lock_irqsave(&acpi_bus_event_lock, flags); + entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); + if (entry) + list_del(&entry->node); + spin_unlock_irqrestore(&acpi_bus_event_lock, flags); + + if (!entry) + return_VALUE(-ENODEV); + + memcpy(event, entry, sizeof(struct acpi_bus_event)); + + kfree(entry); + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Namespace Management + -------------------------------------------------------------------------- */ + +#define WALK_UP 0 +#define WALK_DOWN 1 + +typedef int (*acpi_bus_walk_callback)(struct acpi_device*, int, void*); + +#define HAS_CHILDREN(d) ((d)->children.next != &((d)->children)) +#define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children)) +#define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node)) + + +/** + * acpi_bus_walk + * ------------- + * Used to walk the ACPI Bus's device namespace. Can walk down (depth-first) + * or up. Able to parse starting at any node in the namespace. Note that a + * callback return value of -ELOOP will terminate the walk. + * + * @start: starting point + * callback: function to call for every device encountered while parsing + * direction: direction to parse (up or down) + * @data: context for this search operation + */ +static int +acpi_bus_walk ( + struct acpi_device *start, + acpi_bus_walk_callback callback, + int direction, + void *data) +{ + int result = 0; + int level = 0; + struct acpi_device *device = NULL; + + if (!start || !callback) + return -EINVAL; + + device = start; + + /* + * Parse Namespace + * --------------- + * Parse a given subtree (specified by start) in the given direction. + * Walking 'up' simply means that we execute the callback on leaf + * devices prior to their parents (useful for things like removing + * or powering down a subtree). + */ + + while (device) { + + if (direction == WALK_DOWN) + if (-ELOOP == callback(device, level, data)) + break; + + /* Depth First */ + + if (HAS_CHILDREN(device)) { + device = NODE_TO_DEVICE(device->children.next); + ++level; + continue; + } + + if (direction == WALK_UP) + if (-ELOOP == callback(device, level, data)) + break; + + /* Now Breadth */ + + if (HAS_SIBLINGS(device)) { + device = NODE_TO_DEVICE(device->node.next); + continue; + } + + /* Scope Exhausted - Find Next */ + + while ((device = device->parent)) { + --level; + if (HAS_SIBLINGS(device)) { + device = NODE_TO_DEVICE(device->node.next); + break; + } + } + } + + if ((direction == WALK_UP) && (result == 0)) + callback(start, level, data); + + return result; +} + + +/* -------------------------------------------------------------------------- + Notification Handling + -------------------------------------------------------------------------- */ + +static int +acpi_bus_check_device ( + struct acpi_device *device, + int *status_changed) +{ + acpi_status status = 0; + struct acpi_device_status old_status; + + ACPI_FUNCTION_TRACE("acpi_bus_check_device"); + + if (!device) + return_VALUE(-EINVAL); + + if (status_changed) + *status_changed = 0; + + old_status = device->status; + + /* + * Make sure this device's parent is present before we go about + * messing with the device. + */ + if (device->parent && !device->parent->status.present) { + device->status = device->parent->status; + if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) { + if (status_changed) + *status_changed = 1; + } + return_VALUE(0); + } + + status = acpi_bus_get_status(device); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) + return_VALUE(0); + + if (status_changed) + *status_changed = 1; + + /* + * Device Insertion/Removal + */ + if ((device->status.present) && !(old_status.present)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n")); + /* TBD: Handle device insertion */ + } + else if (!(device->status.present) && (old_status.present)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); + /* TBD: Handle device removal */ + } + + return_VALUE(0); +} + + +static int +acpi_bus_check_scope ( + struct acpi_device *device) +{ + int result = 0; + int status_changed = 0; + + ACPI_FUNCTION_TRACE("acpi_bus_check_scope"); + + if (!device) + return_VALUE(-EINVAL); + + /* Status Change? */ + result = acpi_bus_check_device(device, &status_changed); + if (result) + return_VALUE(result); + + if (!status_changed) + return_VALUE(0); + + /* + * TBD: Enumerate child devices within this device's scope and + * run acpi_bus_check_device()'s on them. + */ + + return_VALUE(0); +} + + +/** + * acpi_bus_notify + * --------------- + * Callback for all 'system-level' device notifications (values 0x00-0x7F). + */ +static void +acpi_bus_notify ( + acpi_handle handle, + u32 type, + void *data) +{ + int result = 0; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_bus_notify"); + + if (acpi_bus_get_device(handle, &device)) + return_VOID; + + switch (type) { + + case ACPI_NOTIFY_BUS_CHECK: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS CHECK notification for device [%s]\n", + device->pnp.bus_id)); + result = acpi_bus_check_scope(device); + /* + * TBD: We'll need to outsource certain events to non-ACPI + * drivers via the device manager (device.c). + */ + break; + + case ACPI_NOTIFY_DEVICE_CHECK: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK notification for device [%s]\n", + device->pnp.bus_id)); + result = acpi_bus_check_device(device, NULL); + /* + * TBD: We'll need to outsource certain events to non-ACPI + * drivers via the device manager (device.c). + */ + break; + + case ACPI_NOTIFY_DEVICE_WAKE: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE WAKE notification for device [%s]\n", + device->pnp.bus_id)); + /* TBD */ + break; + + case ACPI_NOTIFY_EJECT_REQUEST: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received EJECT REQUEST notification for device [%s]\n", + device->pnp.bus_id)); + /* TBD */ + break; + + case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK LIGHT notification for device [%s]\n", + device->pnp.bus_id)); + /* TBD: Exactly what does 'light' mean? */ + break; + + case ACPI_NOTIFY_FREQUENCY_MISMATCH: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received FREQUENCY MISMATCH notification for device [%s]\n", + device->pnp.bus_id)); + /* TBD */ + break; + + case ACPI_NOTIFY_BUS_MODE_MISMATCH: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS MODE MISMATCH notification for device [%s]\n", + device->pnp.bus_id)); + /* TBD */ + break; + + case ACPI_NOTIFY_POWER_FAULT: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received POWER FAULT notification for device [%s]\n", + device->pnp.bus_id)); + /* TBD */ + break; + + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received unknown/unsupported notification [%08x]\n", + type)); + break; + } + + return_VOID; +} + + +/* -------------------------------------------------------------------------- + Driver Management + -------------------------------------------------------------------------- */ + +static LIST_HEAD(acpi_bus_drivers); +static DECLARE_MUTEX(acpi_bus_drivers_lock); + + +/** + * acpi_bus_match + * -------------- + * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it + * matches the specified driver's criteria. + */ +static int +acpi_bus_match ( + struct acpi_device *device, + struct acpi_driver *driver) +{ + int error = 0; + + if (device->flags.hardware_id) + if (strstr(driver->ids, device->pnp.hardware_id)) + goto Done; + + if (device->flags.compatible_ids) { + struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; + int i; + + /* compare multiple _CID entries against driver ids */ + for (i = 0; i < cid_list->count; i++) + { + if (strstr(driver->ids, cid_list->id[i].value)) + goto Done; + } + } + error = -ENOENT; + + Done: + + return error; +} + + +/** + * acpi_bus_driver_init + * -------------------- + * Used to initialize a device via its device driver. Called whenever a + * driver is bound to a device. Invokes the driver's add() and start() ops. + */ +static int +acpi_bus_driver_init ( + struct acpi_device *device, + struct acpi_driver *driver) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_bus_driver_init"); + + if (!device || !driver) + return_VALUE(-EINVAL); + + if (!driver->ops.add) + return_VALUE(-ENOSYS); + + result = driver->ops.add(device); + if (result) { + device->driver = NULL; + acpi_driver_data(device) = NULL; + return_VALUE(result); + } + + device->driver = driver; + + /* + * TBD - Configuration Management: Assign resources to device based + * upon possible configuration and currently allocated resources. + */ + + if (driver->ops.start) { + result = driver->ops.start(device); + if (result && driver->ops.remove) + driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); + return_VALUE(result); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); + +#ifdef CONFIG_LDM + /* + * Update the device information (in the global device hierarchy) now + * that there's a driver bound to it. + */ + strncpy(device->dev.name, device->pnp.device_name, + sizeof(device->dev.name)); +#endif + + if (driver->ops.scan) { + driver->ops.scan(device); + } + + return_VALUE(0); +} + + +/** + * acpi_bus_attach + * ------------- + * Callback for acpi_bus_walk() used to find devices that match a specific + * driver's criteria and then attach the driver. + */ +static int +acpi_bus_attach ( + struct acpi_device *device, + int level, + void *data) +{ + int result = 0; + struct acpi_driver *driver = NULL; + + ACPI_FUNCTION_TRACE("acpi_bus_attach"); + + if (!device || !data) + return_VALUE(-EINVAL); + + driver = (struct acpi_driver *) data; + + if (device->driver) + return_VALUE(-EEXIST); + + if (!device->status.present) + return_VALUE(-ENODEV); + + result = acpi_bus_match(device, driver); + if (result) + return_VALUE(result); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", + driver->name, device->pnp.bus_id)); + + result = acpi_bus_driver_init(device, driver); + if (result) + return_VALUE(result); + + down(&acpi_bus_drivers_lock); + ++driver->references; + up(&acpi_bus_drivers_lock); + + return_VALUE(0); +} + + +/** + * acpi_bus_unattach + * ----------------- + * Callback for acpi_bus_walk() used to find devices that match a specific + * driver's criteria and unattach the driver. + */ +static int +acpi_bus_unattach ( + struct acpi_device *device, + int level, + void *data) +{ + int result = 0; + struct acpi_driver *driver = (struct acpi_driver *) data; + + ACPI_FUNCTION_TRACE("acpi_bus_unattach"); + + if (!device || !driver) + return_VALUE(-EINVAL); + + if (device->driver != driver) + return_VALUE(-ENOENT); + + if (!driver->ops.remove) + return_VALUE(-ENOSYS); + + result = driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); + if (result) + return_VALUE(result); + + device->driver = NULL; + acpi_driver_data(device) = NULL; + + down(&acpi_bus_drivers_lock); + driver->references--; + up(&acpi_bus_drivers_lock); + + return_VALUE(0); +} + + +/** + * acpi_bus_find_driver + * -------------------- + * Parses the list of registered drivers looking for a driver applicable for + * the specified device. + */ +static int +acpi_bus_find_driver ( + struct acpi_device *device) +{ + int result = -ENODEV; + struct list_head *entry = NULL; + struct acpi_driver *driver = NULL; + + ACPI_FUNCTION_TRACE("acpi_bus_find_driver"); + + if (!device || device->driver) + return_VALUE(-EINVAL); + + down(&acpi_bus_drivers_lock); + + list_for_each(entry, &acpi_bus_drivers) { + + driver = list_entry(entry, struct acpi_driver, node); + + if (acpi_bus_match(device, driver)) + continue; + + result = acpi_bus_driver_init(device, driver); + if (!result) + ++driver->references; + + break; + } + + up(&acpi_bus_drivers_lock); + + return_VALUE(result); +} + + +/** + * acpi_bus_register_driver + * ------------------------ + * Registers a driver with the ACPI bus. Searches the namespace for all + * devices that match the driver's criteria and binds. + */ +int +acpi_bus_register_driver ( + struct acpi_driver *driver) +{ + ACPI_FUNCTION_TRACE("acpi_bus_register_driver"); + + if (!driver) + return_VALUE(-EINVAL); + + if (acpi_disabled) + return_VALUE(-ENODEV); + + down(&acpi_bus_drivers_lock); + list_add_tail(&driver->node, &acpi_bus_drivers); + up(&acpi_bus_drivers_lock); + + acpi_bus_walk(acpi_root, acpi_bus_attach, + WALK_DOWN, driver); + + return_VALUE(driver->references); +} + + +/** + * acpi_bus_unregister_driver + * -------------------------- + * Unregisters a driver with the ACPI bus. Searches the namespace for all + * devices that match the driver's criteria and unbinds. + */ +int +acpi_bus_unregister_driver ( + struct acpi_driver *driver) +{ + ACPI_FUNCTION_TRACE("acpi_bus_unregister_driver"); + + if (!driver) + return_VALUE(-EINVAL); + + acpi_bus_walk(acpi_root, acpi_bus_unattach, WALK_UP, driver); + + if (driver->references) + return_VALUE(driver->references); + + down(&acpi_bus_drivers_lock); + list_del(&driver->node); + up(&acpi_bus_drivers_lock); + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Device Enumeration + -------------------------------------------------------------------------- */ + +static int +acpi_bus_get_flags ( + struct acpi_device *device) +{ + acpi_status status = AE_OK; + acpi_handle temp = NULL; + + ACPI_FUNCTION_TRACE("acpi_bus_get_flags"); + + /* Presence of _STA indicates 'dynamic_status' */ + status = acpi_get_handle(device->handle, "_STA", &temp); + if (ACPI_SUCCESS(status)) + device->flags.dynamic_status = 1; + + /* Presence of _CID indicates 'compatible_ids' */ + status = acpi_get_handle(device->handle, "_CID", &temp); + if (ACPI_SUCCESS(status)) + device->flags.compatible_ids = 1; + + /* Presence of _RMV indicates 'removable' */ + status = acpi_get_handle(device->handle, "_RMV", &temp); + if (ACPI_SUCCESS(status)) + device->flags.removable = 1; + + /* Presence of _EJD|_EJ0 indicates 'ejectable' */ + status = acpi_get_handle(device->handle, "_EJD", &temp); + if (ACPI_SUCCESS(status)) + device->flags.ejectable = 1; + else { + status = acpi_get_handle(device->handle, "_EJ0", &temp); + if (ACPI_SUCCESS(status)) + device->flags.ejectable = 1; + } + + /* Presence of _LCK indicates 'lockable' */ + status = acpi_get_handle(device->handle, "_LCK", &temp); + if (ACPI_SUCCESS(status)) + device->flags.lockable = 1; + + /* Presence of _PS0|_PR0 indicates 'power manageable' */ + status = acpi_get_handle(device->handle, "_PS0", &temp); + if (ACPI_FAILURE(status)) + status = acpi_get_handle(device->handle, "_PR0", &temp); + if (ACPI_SUCCESS(status)) + device->flags.power_manageable = 1; + + /* TBD: Peformance management */ + + return_VALUE(0); +} + + +static int +acpi_bus_add ( + struct acpi_device **child, + struct acpi_device *parent, + acpi_handle handle, + int type) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_device *device = NULL; + char bus_id[5] = {'?',0}; + struct acpi_buffer buffer = {0, NULL}; + struct acpi_device_info *info; + char *hid = NULL; + char *uid = NULL; + struct acpi_compatible_id_list *cid_list = NULL; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_bus_add"); + + if (!child) + return_VALUE(-EINVAL); + + device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL); + if (!device) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n")); + return_VALUE(-ENOMEM); + } + memset(device, 0, sizeof(struct acpi_device)); + + device->handle = handle; + device->parent = parent; + + /* + * Bus ID + * ------ + * The device's Bus ID is simply the object name. + * TBD: Shouldn't this value be unique (within the ACPI namespace)? + */ + switch (type) { + case ACPI_BUS_TYPE_SYSTEM: + sprintf(device->pnp.bus_id, "%s", "ACPI"); + break; + case ACPI_BUS_TYPE_POWER_BUTTON: + sprintf(device->pnp.bus_id, "%s", "PWRF"); + break; + case ACPI_BUS_TYPE_SLEEP_BUTTON: + sprintf(device->pnp.bus_id, "%s", "SLPF"); + break; + default: + buffer.length = sizeof(bus_id); + buffer.pointer = bus_id; + acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); + /* Clean up trailing underscores (if any) */ + for (i = 3; i > 1; i--) { + if (bus_id[i] == '_') + bus_id[i] = '\0'; + else + break; + } + sprintf(device->pnp.bus_id, "%s", bus_id); + buffer.pointer = NULL; + break; + } + + /* + * Flags + * ----- + * Get prior to calling acpi_bus_get_status() so we know whether + * or not _STA is present. Note that we only look for object + * handles -- cannot evaluate objects until we know the device is + * present and properly initialized. + */ + result = acpi_bus_get_flags(device); + if (result) + goto end; + + /* + * Status + * ------ + * See if the device is present. We always assume that non-Device() + * objects (e.g. thermal zones, power resources, processors, etc.) are + * present, functioning, etc. (at least when parent object is present). + * Note that _STA has a different meaning for some objects (e.g. + * power resources) so we need to be careful how we use it. + */ + switch (type) { + case ACPI_BUS_TYPE_DEVICE: + result = acpi_bus_get_status(device); + if (result) + goto end; + break; + default: + STRUCT_TO_INT(device->status) = 0x0F; + break; + } + if (!device->status.present) { + result = -ENOENT; + goto end; + } + + /* + * Initialize Device + * ----------------- + * TBD: Synch with Core's enumeration/initialization process. + */ + + /* + * Hardware ID, Unique ID, & Bus Address + * ------------------------------------- + */ + switch (type) { + case ACPI_BUS_TYPE_DEVICE: + buffer.length = ACPI_ALLOCATE_BUFFER; + buffer.pointer = NULL; + status = acpi_get_object_info(handle, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error reading device info\n")); + result = -ENODEV; + goto end; + } + info = buffer.pointer; + if (info->valid & ACPI_VALID_HID) + hid = info->hardware_id.value; + if (info->valid & ACPI_VALID_UID) + uid = info->unique_id.value; + if (info->valid & ACPI_VALID_CID) { + cid_list = &info->compatibility_id; + device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL); + if (device->pnp.cid_list) + memcpy(device->pnp.cid_list, cid_list, cid_list->size); + else + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n")); + } + if (info->valid & ACPI_VALID_ADR) { + device->pnp.bus_address = info->address; + device->flags.bus_address = 1; + } + break; + case ACPI_BUS_TYPE_POWER: + hid = ACPI_POWER_HID; + break; + case ACPI_BUS_TYPE_PROCESSOR: + hid = ACPI_PROCESSOR_HID; + break; + case ACPI_BUS_TYPE_SYSTEM: + hid = ACPI_SYSTEM_HID; + break; + case ACPI_BUS_TYPE_THERMAL: + hid = ACPI_THERMAL_HID; + break; + case ACPI_BUS_TYPE_POWER_BUTTON: + hid = ACPI_BUTTON_HID_POWERF; + break; + case ACPI_BUS_TYPE_SLEEP_BUTTON: + hid = ACPI_BUTTON_HID_SLEEPF; + break; + } + + /* + * \_SB + * ---- + * Fix for the system root bus device -- the only root-level device. + */ + if ((parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { + hid = ACPI_BUS_HID; + sprintf(device->pnp.device_name, "%s", ACPI_BUS_DEVICE_NAME); + sprintf(device->pnp.device_class, "%s", ACPI_BUS_CLASS); + } + + if (hid) { + sprintf(device->pnp.hardware_id, "%s", hid); + device->flags.hardware_id = 1; + } + if (uid) { + sprintf(device->pnp.unique_id, "%s", uid); + device->flags.unique_id = 1; + } + + /* + * If we called get_object_info, we now are finished with the buffer, + * so we can free it. + */ + if (buffer.pointer) + acpi_os_free(buffer.pointer); + + /* + * Power Management + * ---------------- + */ + if (device->flags.power_manageable) { + result = acpi_bus_get_power_flags(device); + if (result) + goto end; + } + + /* + * Performance Management + * ---------------------- + */ + if (device->flags.performance_manageable) { + result = acpi_bus_get_perf_flags(device); + if (result) + goto end; + } + + /* + * Context + * ------- + * Attach this 'struct acpi_device' to the ACPI object. This makes + * resolutions from handle->device very efficient. Note that we need + * to be careful with fixed-feature devices as they all attach to the + * root object. + */ + switch (type) { + case ACPI_BUS_TYPE_POWER_BUTTON: + case ACPI_BUS_TYPE_SLEEP_BUTTON: + break; + default: + status = acpi_attach_data(device->handle, + acpi_bus_data_handler, device); + break; + } + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error attaching device data\n")); + result = -ENODEV; + goto end; + } + + /* + * Linkage + * ------- + * Link this device to its parent and siblings. + */ + INIT_LIST_HEAD(&device->children); + if (!device->parent) + INIT_LIST_HEAD(&device->node); + else + list_add_tail(&device->node, &device->parent->children); + +#ifdef CONFIG_ACPI_DEBUG + { + char *type_string = NULL; + char name[80] = {'?','\0'}; + struct acpi_buffer buffer = {sizeof(name), name}; + + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + + switch (type) { + case ACPI_BUS_TYPE_DEVICE: + type_string = "Device"; + break; + case ACPI_BUS_TYPE_POWER: + type_string = "Power Resource"; + break; + case ACPI_BUS_TYPE_PROCESSOR: + type_string = "Processor"; + break; + case ACPI_BUS_TYPE_SYSTEM: + type_string = "System"; + break; + case ACPI_BUS_TYPE_THERMAL: + type_string = "Thermal Zone"; + break; + case ACPI_BUS_TYPE_POWER_BUTTON: + type_string = "Power Button"; + sprintf(name, "PWRB"); + break; + case ACPI_BUS_TYPE_SLEEP_BUTTON: + type_string = "Sleep Button"; + sprintf(name, "SLPB"); + break; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s %s [%p]\n", + type_string, name, handle)); + } +#endif /*CONFIG_ACPI_DEBUG*/ + + /* + * Global Device Hierarchy: + * ------------------------ + * Register this device with the global device hierarchy. + */ + acpi_device_register(device, parent); + + /* + * Bind _ADR-Based Devices + * ----------------------- + * If there's a a bus address (_ADR) then we utilize the parent's + * 'bind' function (if exists) to bind the ACPI- and natively- + * enumerated device representations. + */ + if (device->flags.bus_address) { + if (device->parent && device->parent->ops.bind) + device->parent->ops.bind(device); + } + + /* + * Locate & Attach Driver + * ---------------------- + * If there's a hardware id (_HID) or compatible ids (_CID) we check + * to see if there's a driver installed for this kind of device. Note + * that drivers can install before or after a device is enumerated. + * + * TBD: Assumes LDM provides driver hot-plug capability. + */ + if (device->flags.hardware_id || device->flags.compatible_ids) + acpi_bus_find_driver(device); + +end: + if (result) { + if (device->pnp.cid_list) { + kfree(device->pnp.cid_list); + } + kfree(device); + return_VALUE(result); + } + *child = device; + + return_VALUE(0); +} + + +static int +acpi_bus_remove ( + struct acpi_device *device, + int type) +{ + ACPI_FUNCTION_TRACE("acpi_bus_remove"); + + if (!device) + return_VALUE(-ENODEV); + + acpi_device_unregister(device); + +#if 0 + if (device->pnp.cid_list) + kfree(device->pnp.cid_list); +#endif + kfree(device); + + return_VALUE(0); +} + + +int +acpi_bus_scan ( + struct acpi_device *start) +{ + acpi_status status = AE_OK; + struct acpi_device *parent = NULL; + struct acpi_device *child = NULL; + acpi_handle phandle = 0; + acpi_handle chandle = 0; + acpi_object_type type = 0; + u32 level = 1; + + ACPI_FUNCTION_TRACE("acpi_bus_scan"); + + if (!start) + return_VALUE(-EINVAL); + + parent = start; + phandle = start->handle; + + /* + * Parse through the ACPI namespace, identify all 'devices', and + * create a new 'struct acpi_device' for each. + */ + while ((level > 0) && parent) { + + status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, + chandle, &chandle); + + /* + * If this scope is exhausted then move our way back up. + */ + if (ACPI_FAILURE(status)) { + level--; + chandle = phandle; + acpi_get_parent(phandle, &phandle); + if (parent->parent) + parent = parent->parent; + continue; + } + + status = acpi_get_type(chandle, &type); + if (ACPI_FAILURE(status)) + continue; + + /* + * If this is a scope object then parse it (depth-first). + */ + if (type == ACPI_TYPE_LOCAL_SCOPE) { + level++; + phandle = chandle; + chandle = 0; + continue; + } + + /* + * We're only interested in objects that we consider 'devices'. + */ + switch (type) { + case ACPI_TYPE_DEVICE: + type = ACPI_BUS_TYPE_DEVICE; + break; + case ACPI_TYPE_PROCESSOR: + type = ACPI_BUS_TYPE_PROCESSOR; + break; + case ACPI_TYPE_THERMAL: + type = ACPI_BUS_TYPE_THERMAL; + break; + case ACPI_TYPE_POWER: + type = ACPI_BUS_TYPE_POWER; + break; + default: + continue; + } + + status = acpi_bus_add(&child, parent, chandle, type); + if (ACPI_FAILURE(status)) + continue; + + /* + * If the device is present, enabled, and functioning then + * parse its scope (depth-first). Note that we need to + * represent absent devices to facilitate PnP notifications + * -- but only the subtree head (not all of its children, + * which will be enumerated when the parent is inserted). + * + * TBD: Need notifications and other detection mechanisms + * in place before we can fully implement this. + */ + if (child->status.present) { + status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, + 0, NULL); + if (ACPI_SUCCESS(status)) { + level++; + phandle = chandle; + chandle = 0; + parent = child; + } + } + } + + return_VALUE(0); +} + + +static int +acpi_bus_scan_fixed ( + struct acpi_device *root) +{ + int result = 0; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_bus_scan_fixed"); + + if (!root) + return_VALUE(-ENODEV); + + /* + * Enumerate all fixed-feature devices. + */ + if (acpi_fadt.pwr_button == 0) + result = acpi_bus_add(&device, acpi_root, + NULL, ACPI_BUS_TYPE_POWER_BUTTON); + + if (acpi_fadt.sleep_button == 0) + result = acpi_bus_add(&device, acpi_root, + NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); + + return_VALUE(result); +} + + +/* -------------------------------------------------------------------------- + Initialization/Cleanup + -------------------------------------------------------------------------- */ + +static int __init +acpi_bus_init_irq (void) +{ + acpi_status status = AE_OK; + union acpi_object arg = {ACPI_TYPE_INTEGER}; + struct acpi_object_list arg_list = {1, &arg}; + char *message = NULL; + + ACPI_FUNCTION_TRACE("acpi_bus_init_irq"); + + /* + * Let the system know what interrupt model we are using by + * evaluating the \_PIC object, if exists. + */ + + switch (acpi_irq_model) { + case ACPI_IRQ_MODEL_PIC: + message = "PIC"; + break; + case ACPI_IRQ_MODEL_IOAPIC: + message = "IOAPIC"; + break; + case ACPI_IRQ_MODEL_IOSAPIC: + message = "IOSAPIC"; + break; + default: + printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n"); + return_VALUE(-ENODEV); + } + + printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message); + + arg.integer.value = acpi_irq_model; + + status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL); + if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PIC\n")); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +static int __init +acpi_bus_init (void) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_buffer buffer = {sizeof(acpi_fadt), &acpi_fadt}; + + ACPI_FUNCTION_TRACE("acpi_bus_init"); + + status = acpi_initialize_subsystem(); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n"); + goto error0; + } + + status = acpi_load_tables(); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to load the System Description Tables\n"); + goto error0; + } + + /* + * Get a separate copy of the FADT for use by other drivers. + */ + status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to get the FADT\n"); + goto error1; + } + +#ifdef CONFIG_X86 + /* Ensure the SCI is set to level-triggered, active-low */ + if (acpi_ioapic) + mp_config_ioapic_for_sci(acpi_fadt.sci_int); + else + eisa_set_level_irq(acpi_fadt.sci_int); +#endif + + status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n"); + goto error1; + } + +#ifdef CONFIG_ACPI_EC + /* + * ACPI 2.0 requires the EC driver to be loaded and work before + * the EC device is found in the namespace. This is accomplished + * by looking for the ECDT table, and getting the EC parameters out + * of that. + */ + result = acpi_ec_ecdt_probe(); + if (result) { + goto error1; + } +#endif + + status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n"); + goto error1; + } + + printk(KERN_INFO PREFIX "Interpreter enabled\n"); + + /* + * Get the system interrupt model and evaluate \_PIC. + */ + result = acpi_bus_init_irq(); + if (result) + goto error1; + + /* + * Register the for all standard device notifications. + */ + status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to register for device notifications\n"); + result = -ENODEV; + goto error1; + } + + /* + * Create the root device in the bus's device tree + */ + result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, + ACPI_BUS_TYPE_SYSTEM); + if (result) + goto error2; + + /* + * Create the top ACPI proc directory + */ + acpi_device_dir(acpi_root) = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL); + if (!acpi_root) { + result = -ENODEV; + goto error3; + } + acpi_root_dir = acpi_device_dir(acpi_root); + + /* + * Install drivers required for proper enumeration of the + * ACPI namespace. + */ + acpi_system_init(); /* ACPI System */ + acpi_power_init(); /* ACPI Bus Power Management */ +#ifdef CONFIG_ACPI_EC + acpi_ec_init(); /* ACPI Embedded Controller */ +#endif +#ifdef CONFIG_ACPI_PCI + acpi_pci_link_init(); /* ACPI PCI Interrupt Link */ + acpi_pci_root_init(); /* ACPI PCI Root Bridge */ +#endif + /* + * Enumerate devices in the ACPI namespace. + */ + result = acpi_bus_scan_fixed(acpi_root); + if (result) + goto error4; + result = acpi_bus_scan(acpi_root); + if (result) + goto error4; + + return_VALUE(0); + + /* Mimic structured exception handling */ +error4: + remove_proc_entry(ACPI_BUS_FILE_ROOT, NULL); +error3: + acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL); +error2: + acpi_remove_notify_handler(ACPI_ROOT_OBJECT, + ACPI_SYSTEM_NOTIFY, &acpi_bus_notify); +error1: + acpi_terminate(); +error0: + return_VALUE(-ENODEV); +} + + +static void __exit +acpi_bus_exit (void) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE("acpi_bus_exit"); + + status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, + ACPI_SYSTEM_NOTIFY, acpi_bus_notify); + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + +#ifdef CONFIG_ACPI_PCI + acpi_pci_root_exit(); + acpi_pci_link_exit(); +#endif +#ifdef CONFIG_ACPI_EC + acpi_ec_exit(); +#endif + acpi_power_exit(); + acpi_system_exit(); + + acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL); + + remove_proc_entry(ACPI_BUS_FILE_ROOT, NULL); + + status = acpi_terminate(); + if (ACPI_FAILURE(status)) + printk(KERN_ERR PREFIX "Unable to terminate the ACPI Interpreter\n"); + else + printk(KERN_ERR PREFIX "Interpreter disabled\n"); + + return_VOID; +} + + +int __init +acpi_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_init"); + + printk(KERN_INFO PREFIX "Subsystem revision %08x\n", + ACPI_CA_VERSION); + + /* Initial core debug level excludes drivers, so include them now */ + acpi_set_debug(ACPI_DEBUG_LOW); + + if (acpi_disabled) { + printk(KERN_INFO PREFIX "Interpreter disabled.\n"); + return -ENODEV; + } + +#ifdef CONFIG_PM + if (PM_IS_ACTIVE()) { + printk(KERN_INFO PREFIX "APM is already active, exiting\n"); + return -ENODEV; + } +#endif + + result = acpi_bus_init(); + if (result) + return_VALUE(result); + +#ifdef CONFIG_PM + pm_active = 1; +#endif + + return_VALUE(0); +} + + +void __exit +acpi_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_exit"); + +#ifdef CONFIG_PM + pm_active = 0; +#endif + + acpi_bus_exit(); + + return_VOID; +} + + +int __init +acpi_setup(char *str) +{ + while (str && *str) { + if (strncmp(str, "off", 3) == 0) + acpi_disabled = 1; + str = strchr(str, ','); + if (str) + str += strspn(str, ", \t"); + } + return 1; +} + + +__setup("acpi=", acpi_setup); diff -urN linux-2.4.21/drivers/acpi/button.c linux-2.4.22/drivers/acpi/button.c --- linux-2.4.21/drivers/acpi/button.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/button.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,498 @@ +/* + * acpi_button.c - ACPI Button Driver ($Revision: 29 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_BUTTON_COMPONENT +ACPI_MODULE_NAME ("acpi_button") + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +#define PREFIX "ACPI: " + + +static int acpi_button_add (struct acpi_device *device); +static int acpi_button_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_button_driver = { + .name = ACPI_BUTTON_DRIVER_NAME, + .class = ACPI_BUTTON_CLASS, + .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", + .ops = { + .add = acpi_button_add, + .remove = acpi_button_remove, + }, +}; + +struct acpi_button { + acpi_handle handle; + struct acpi_device *device; /* Fixed button kludge */ + u8 type; + unsigned long pushed; +}; + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +static struct proc_dir_entry *acpi_button_dir = NULL; + +static int +acpi_button_read_info ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_button *button = (struct acpi_button *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_button_read_info"); + + if (!button || !button->device) + goto end; + + p += sprintf(p, "type: %s\n", + acpi_device_name(button->device)); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + +static int +acpi_button_lid_read_state( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_button *button = (struct acpi_button *) data; + char *p = page; + int len = 0; + acpi_status status=AE_OK; + unsigned long state; + + ACPI_FUNCTION_TRACE("acpi_button_lid_read_state"); + + if (!button || !button->device) + goto end; + + status=acpi_evaluate_integer(button->handle,"_LID",NULL,&state); + if (ACPI_FAILURE(status)){ + p += sprintf(p, "state: unsupported\n"); + } + else{ + p += sprintf(p, "state: %s\n", (state ? "open" : "closed")); + } + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + +static int +acpi_button_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + struct acpi_button *button = NULL; + + ACPI_FUNCTION_TRACE("acpi_button_add_fs"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + button = acpi_driver_data(device); + + switch (button->type) { + case ACPI_BUTTON_TYPE_POWER: + case ACPI_BUTTON_TYPE_POWERF: + entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, + acpi_button_dir); + break; + case ACPI_BUTTON_TYPE_SLEEP: + case ACPI_BUTTON_TYPE_SLEEPF: + entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, + acpi_button_dir); + break; + case ACPI_BUTTON_TYPE_LID: + entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, + acpi_button_dir); + break; + } + + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + + /* 'info' [R] */ + entry = create_proc_entry(ACPI_BUTTON_FILE_INFO, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_BUTTON_FILE_INFO)); + else { + entry->read_proc = acpi_button_read_info; + entry->data = acpi_driver_data(device); + } + + if (button->type==ACPI_BUTTON_TYPE_LID){ + /* 'state' [R] */ + entry = create_proc_entry(ACPI_BUTTON_FILE_STATE, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_BUTTON_FILE_STATE)); + else { + entry->read_proc = acpi_button_lid_read_state; + entry->data = acpi_driver_data(device); + } + } + + return_VALUE(0); +} + + +static int +acpi_button_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_button_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_button_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +void +acpi_button_notify ( + acpi_handle handle, + u32 event, + void *data) +{ + struct acpi_button *button = (struct acpi_button *) data; + + ACPI_FUNCTION_TRACE("acpi_button_notify"); + + if (!button || !button->device) + return_VOID; + + switch (event) { + case ACPI_BUTTON_NOTIFY_STATUS: + acpi_bus_generate_event(button->device, event, ++button->pushed); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return_VOID; +} + + +acpi_status +acpi_button_notify_fixed ( + void *data) +{ + struct acpi_button *button = (struct acpi_button *) data; + + ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); + + if (!button) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); + + return_ACPI_STATUS(AE_OK); +} + + +static int +acpi_button_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_button *button = NULL; + + static struct acpi_device *power_button; + static struct acpi_device *sleep_button; + static struct acpi_device *lid_button; + + ACPI_FUNCTION_TRACE("acpi_button_add"); + + if (!device) + return_VALUE(-EINVAL); + + button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL); + if (!button) + return_VALUE(-ENOMEM); + memset(button, 0, sizeof(struct acpi_button)); + + button->device = device; + button->handle = device->handle; + acpi_driver_data(device) = button; + + /* + * Determine the button type (via hid), as fixed-feature buttons + * need to be handled a bit differently than generic-space. + */ + if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) { + button->type = ACPI_BUTTON_TYPE_POWER; + sprintf(acpi_device_name(device), "%s", + ACPI_BUTTON_DEVICE_NAME_POWER); + sprintf(acpi_device_class(device), "%s/%s", + ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER); + } + else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) { + button->type = ACPI_BUTTON_TYPE_POWERF; + sprintf(acpi_device_name(device), "%s", + ACPI_BUTTON_DEVICE_NAME_POWERF); + sprintf(acpi_device_class(device), "%s/%s", + ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER); + } + else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) { + button->type = ACPI_BUTTON_TYPE_SLEEP; + sprintf(acpi_device_name(device), "%s", + ACPI_BUTTON_DEVICE_NAME_SLEEP); + sprintf(acpi_device_class(device), "%s/%s", + ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP); + } + else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) { + button->type = ACPI_BUTTON_TYPE_SLEEPF; + sprintf(acpi_device_name(device), "%s", + ACPI_BUTTON_DEVICE_NAME_SLEEPF); + sprintf(acpi_device_class(device), "%s/%s", + ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP); + } + else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) { + button->type = ACPI_BUTTON_TYPE_LID; + sprintf(acpi_device_name(device), "%s", + ACPI_BUTTON_DEVICE_NAME_LID); + sprintf(acpi_device_class(device), "%s/%s", + ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); + } + else { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported hid [%s]\n", + acpi_device_hid(device))); + result = -ENODEV; + goto end; + } + + /* + * Ensure only one button of each type is used. + */ + switch (button->type) { + case ACPI_BUTTON_TYPE_POWER: + case ACPI_BUTTON_TYPE_POWERF: + if (!power_button) + power_button = device; + else { + kfree(button); + return_VALUE(-ENODEV); + } + break; + case ACPI_BUTTON_TYPE_SLEEP: + case ACPI_BUTTON_TYPE_SLEEPF: + if (!sleep_button) + sleep_button = device; + else { + kfree(button); + return_VALUE(-ENODEV); + } + break; + case ACPI_BUTTON_TYPE_LID: + if (!lid_button) + lid_button = device; + else { + kfree(button); + return_VALUE(-ENODEV); + } + break; + } + + result = acpi_button_add_fs(device); + if (result) + goto end; + + switch (button->type) { + case ACPI_BUTTON_TYPE_POWERF: + status = acpi_install_fixed_event_handler ( + ACPI_EVENT_POWER_BUTTON, + acpi_button_notify_fixed, + button); + break; + case ACPI_BUTTON_TYPE_SLEEPF: + status = acpi_install_fixed_event_handler ( + ACPI_EVENT_SLEEP_BUTTON, + acpi_button_notify_fixed, + button); + break; + default: + status = acpi_install_notify_handler ( + button->handle, + ACPI_DEVICE_NOTIFY, + acpi_button_notify, + button); + break; + } + + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + result = -ENODEV; + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s]\n", + acpi_device_name(device), acpi_device_bid(device)); + +end: + if (result) { + acpi_button_remove_fs(device); + kfree(button); + } + + return_VALUE(result); +} + + +static int +acpi_button_remove (struct acpi_device *device, int type) +{ + acpi_status status = 0; + struct acpi_button *button = NULL; + + ACPI_FUNCTION_TRACE("acpi_button_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + button = acpi_driver_data(device); + + /* Unregister for device notifications. */ + switch (button->type) { + case ACPI_BUTTON_TYPE_POWERF: + status = acpi_remove_fixed_event_handler( + ACPI_EVENT_POWER_BUTTON, acpi_button_notify_fixed); + break; + case ACPI_BUTTON_TYPE_SLEEPF: + status = acpi_remove_fixed_event_handler( + ACPI_EVENT_SLEEP_BUTTON, acpi_button_notify_fixed); + break; + default: + status = acpi_remove_notify_handler(button->handle, + ACPI_DEVICE_NOTIFY, acpi_button_notify); + break; + } + + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + + acpi_button_remove_fs(device); + + kfree(button); + + return_VALUE(0); +} + + +static int __init +acpi_button_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_button_init"); + + acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); + if (!acpi_button_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_button_driver); + if (result < 0) { + remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +static void __exit +acpi_button_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_button_exit"); + + acpi_bus_unregister_driver(&acpi_button_driver); + + remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); + + return_VOID; +} + + +module_init(acpi_button_init); +module_exit(acpi_button_exit); diff -urN linux-2.4.21/drivers/acpi/debugger/Makefile linux-2.4.22/drivers/acpi/debugger/Makefile --- linux-2.4.21/drivers/acpi/debugger/Makefile 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,12 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory -# - -O_TARGET := $(notdir $(CURDIR)).o - -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) - -EXTRA_CFLAGS += $(ACPI_CFLAGS) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/debugger/dbcmds.c linux-2.4.22/drivers/acpi/debugger/dbcmds.c --- linux-2.4.21/drivers/acpi/debugger/dbcmds.c 2001-10-24 14:06:21.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbcmds.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,996 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbcmds - debug commands and output routines - * $Revision: 66 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acevents.h" -#include "acinterp.h" -#include "acdebug.h" -#include "actables.h" -#include "acresrc.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbcmds") - - -/* - * Arguments for the Objects command - * These object types map directly to the ACPI_TYPES - */ - -ARGUMENT_INFO acpi_db_object_types [] = -{ {"ANY"}, - {"NUMBERS"}, - {"STRINGS"}, - {"BUFFERS"}, - {"PACKAGES"}, - {"FIELDS"}, - {"DEVICES"}, - {"EVENTS"}, - {"METHODS"}, - {"MUTEXES"}, - {"REGIONS"}, - {"POWERRESOURCES"}, - {"PROCESSORS"}, - {"THERMALZONES"}, - {"BUFFERFIELDS"}, - {"DDBHANDLES"}, - {NULL} /* Must be null terminated */ -}; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_walk_for_references - * - * PARAMETERS: Callback from Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Check if this namespace object refers to the target object - * that is passed in as the context value. - * - ******************************************************************************/ - -acpi_status -acpi_db_walk_for_references ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_operand_object *obj_desc = (acpi_operand_object *) context; - acpi_namespace_node *node = (acpi_namespace_node *) obj_handle; - - - /* Check for match against the namespace node itself */ - - if (node == (void *) obj_desc) { - acpi_os_printf ("Object is a Node [%4.4s]\n", &node->name); - } - - /* Check for match against the object attached to the node */ - - if (node->object == obj_desc) { - acpi_os_printf ("Reference at Node->Object %p [%4.4s]\n", node, &node->name); - } - - /* Check first child for a match */ - /* TBD: [Investigate] probably now obsolete with new datastructure */ - - if (node->child == (void *) obj_desc) { - acpi_os_printf ("Reference at Node->Child %p [%4.4s]\n", node, &node->name); - } - - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_find_references - * - * PARAMETERS: Object_arg - String with hex value of the object - * - * RETURN: None - * - * DESCRIPTION: Search namespace for all references to the input object - * - ******************************************************************************/ - -void -acpi_db_find_references ( - NATIVE_CHAR *object_arg) -{ - acpi_operand_object *obj_desc; - - - /* Convert string to object pointer */ - - obj_desc = (acpi_operand_object *) STRTOUL (object_arg, NULL, 16); - - /* Search all nodes in namespace */ - - acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_db_walk_for_references, (void *) obj_desc, NULL); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_locks - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display information about internal mutexes. - * - ******************************************************************************/ - -void -acpi_db_display_locks (void) -{ - u32 i; - - - for (i = 0; i < MAX_MTX; i++) { - acpi_os_printf ("%26s : %s\n", acpi_ut_get_mutex_name (i), - acpi_gbl_acpi_mutex_info[i].owner_id == ACPI_MUTEX_NOT_ACQUIRED - ? "Locked" : "Unlocked"); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_table_info - * - * PARAMETERS: Table_arg - String with name of table to be displayed - * - * RETURN: None - * - * DESCRIPTION: Display information about loaded tables. Current - * implementation displays all loaded tables. - * - ******************************************************************************/ - -void -acpi_db_display_table_info ( - NATIVE_CHAR *table_arg) -{ - u32 i; - - - for (i = 0; i < NUM_ACPI_TABLES; i++) { - if (acpi_gbl_acpi_tables[i].pointer) { - acpi_os_printf ("%s at %p length %X\n", acpi_gbl_acpi_table_data[i].name, - acpi_gbl_acpi_tables[i].pointer, acpi_gbl_acpi_tables[i].length); - } - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_unload_acpi_table - * - * PARAMETERS: Table_arg - Name of the table to be unloaded - * Instance_arg - Which instance of the table to unload (if - * there are multiple tables of the same type) - * - * RETURN: Nonde - * - * DESCRIPTION: Unload an ACPI table. - * Instance is not implemented - * - ******************************************************************************/ - -void -acpi_db_unload_acpi_table ( - NATIVE_CHAR *table_arg, - NATIVE_CHAR *instance_arg) -{ - u32 i; - acpi_status status; - - - /* Search all tables for the target type */ - - for (i = 0; i < NUM_ACPI_TABLES; i++) { - if (!STRNCMP (table_arg, acpi_gbl_acpi_table_data[i].signature, - acpi_gbl_acpi_table_data[i].sig_length)) { - /* Found the table, unload it */ - - status = acpi_unload_table (i); - if (ACPI_SUCCESS (status)) { - acpi_os_printf ("[%s] unloaded and uninstalled\n", table_arg); - } - else { - acpi_os_printf ("%s, while unloading [%s]\n", - acpi_format_exception (status), table_arg); - } - - return; - } - } - - acpi_os_printf ("Unknown table type [%s]\n", table_arg); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_method_breakpoint - * - * PARAMETERS: Location - AML offset of breakpoint - * Walk_state - Current walk info - * Op - Current Op (from parse walk) - * - * RETURN: None - * - * DESCRIPTION: Set a breakpoint in a control method at the specified - * AML offset - * - ******************************************************************************/ - -void -acpi_db_set_method_breakpoint ( - NATIVE_CHAR *location, - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - u32 address; - - - if (!op) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - /* Get and verify the breakpoint address */ - - address = STRTOUL (location, NULL, 16); - if (address <= op->aml_offset) { - acpi_os_printf ("Breakpoint %X is beyond current address %X\n", address, op->aml_offset); - } - - /* Save breakpoint in current walk */ - - walk_state->method_breakpoint = address; - acpi_os_printf ("Breakpoint set at AML offset %X\n", address); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_method_call_breakpoint - * - * PARAMETERS: Op - Current Op (from parse walk) - * - * RETURN: None - * - * DESCRIPTION: Set a breakpoint in a control method at the specified - * AML offset - * - ******************************************************************************/ - -void -acpi_db_set_method_call_breakpoint ( - acpi_parse_object *op) -{ - - - if (!op) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - - acpi_gbl_step_to_next_call = TRUE; -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_disassemble_aml - * - * PARAMETERS: Statements - Number of statements to disassemble - * Op - Current Op (from parse walk) - * - * RETURN: None - * - * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number - * of statements specified. - * - ******************************************************************************/ - -void -acpi_db_disassemble_aml ( - NATIVE_CHAR *statements, - acpi_parse_object *op) -{ - u32 num_statements = 8; - - - if (!op) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - if (statements) { - num_statements = STRTOUL (statements, NULL, 0); - } - - - acpi_db_display_op (NULL, op, num_statements); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_namespace - * - * PARAMETERS: Start_arg - Node to begin namespace dump - * Depth_arg - Maximum tree depth to be dumped - * - * RETURN: None - * - * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed - * with type and other information. - * - ******************************************************************************/ - -void -acpi_db_dump_namespace ( - NATIVE_CHAR *start_arg, - NATIVE_CHAR *depth_arg) -{ - acpi_handle subtree_entry = acpi_gbl_root_node; - u32 max_depth = ACPI_UINT32_MAX; - - - /* No argument given, just start at the root and dump entire namespace */ - - if (start_arg) { - /* Check if numeric argument, must be a Node */ - - if ((start_arg[0] >= 0x30) && (start_arg[0] <= 0x39)) { - subtree_entry = (acpi_handle) STRTOUL (start_arg, NULL, 16); - if (!acpi_os_readable (subtree_entry, sizeof (acpi_namespace_node))) { - acpi_os_printf ("Address %p is invalid in this address space\n", subtree_entry); - return; - } - - if (!VALID_DESCRIPTOR_TYPE ((subtree_entry), ACPI_DESC_TYPE_NAMED)) { - acpi_os_printf ("Address %p is not a valid Named object\n", subtree_entry); - return; - } - } - - /* Alpha argument */ - - else { - /* The parameter is a name string that must be resolved to a Named obj*/ - - subtree_entry = acpi_db_local_ns_lookup (start_arg); - if (!subtree_entry) { - subtree_entry = acpi_gbl_root_node; - } - } - - /* Now we can check for the depth argument */ - - if (depth_arg) { - max_depth = STRTOUL (depth_arg, NULL, 0); - } - } - - - acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT); - acpi_os_printf ("ACPI Namespace (from %p subtree):\n", subtree_entry); - - /* Display the subtree */ - - acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT); - acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, ACPI_UINT32_MAX, subtree_entry); - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_namespace_by_owner - * - * PARAMETERS: Owner_arg - Owner ID whose nodes will be displayed - * Depth_arg - Maximum tree depth to be dumped - * - * RETURN: None - * - * DESCRIPTION: Dump elements of the namespace that are owned by the Owner_id. - * - ******************************************************************************/ - -void -acpi_db_dump_namespace_by_owner ( - NATIVE_CHAR *owner_arg, - NATIVE_CHAR *depth_arg) -{ - acpi_handle subtree_entry = acpi_gbl_root_node; - u32 max_depth = ACPI_UINT32_MAX; - u16 owner_id; - - - owner_id = (u16) STRTOUL (owner_arg, NULL, 0); - - - /* Now we can check for the depth argument */ - - if (depth_arg) { - max_depth = STRTOUL (depth_arg, NULL, 0); - } - - - acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT); - acpi_os_printf ("ACPI Namespace by owner %X:\n", owner_id); - - /* Display the subtree */ - - acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT); - acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, owner_id, subtree_entry); - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_send_notify - * - * PARAMETERS: Name - Name of ACPI object to send the notify to - * Value - Value of the notify to send. - * - * RETURN: None - * - * DESCRIPTION: Send an ACPI notification. The value specified is sent to the - * named object as an ACPI notify. - * - ******************************************************************************/ - -void -acpi_db_send_notify ( - NATIVE_CHAR *name, - u32 value) -{ - acpi_namespace_node *node; - - - /* Translate name to an Named object */ - - node = acpi_db_local_ns_lookup (name); - if (!node) { - return; - } - - /* Decode Named object type */ - - switch (node->type) { - case ACPI_TYPE_DEVICE: - case ACPI_TYPE_THERMAL: - - /* Send the notify */ - - acpi_ev_queue_notify_request (node, value); - break; - - default: - acpi_os_printf ("Named object is not a device or a thermal object\n"); - break; - } - -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_method_data - * - * PARAMETERS: Type_arg - L for local, A for argument - * Index_arg - which one - * Value_arg - Value to set. - * - * RETURN: None - * - * DESCRIPTION: Set a local or argument for the running control method. - * NOTE: only object supported is Number. - * - ******************************************************************************/ - -void -acpi_db_set_method_data ( - NATIVE_CHAR *type_arg, - NATIVE_CHAR *index_arg, - NATIVE_CHAR *value_arg) -{ - NATIVE_CHAR type; - u32 index; - u32 value; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - - - /* Validate Type_arg */ - - STRUPR (type_arg); - type = type_arg[0]; - if ((type != 'L') && - (type != 'A')) { - acpi_os_printf ("Invalid SET operand: %s\n", type_arg); - return; - } - - /* Get the index and value */ - - index = STRTOUL (index_arg, NULL, 16); - value = STRTOUL (value_arg, NULL, 16); - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - - /* Create and initialize the new object */ - - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!obj_desc) { - acpi_os_printf ("Could not create an internal object\n"); - return; - } - - obj_desc->integer.value = value; - - - /* Store the new object into the target */ - - switch (type) { - case 'A': - - /* Set a method argument */ - - if (index > MTH_NUM_ARGS) { - acpi_os_printf ("Arg%d - Invalid argument name\n", index); - return; - } - - acpi_ds_store_object_to_local (AML_ARG_OP, index, obj_desc, walk_state); - obj_desc = walk_state->arguments[index].object; - - acpi_os_printf ("Arg%d: ", index); - acpi_db_display_internal_object (obj_desc, walk_state); - break; - - case 'L': - - /* Set a method local */ - - if (index > MTH_NUM_LOCALS) { - acpi_os_printf ("Local%d - Invalid local variable name\n", index); - return; - } - - acpi_ds_store_object_to_local (AML_LOCAL_OP, index, obj_desc, walk_state); - obj_desc = walk_state->local_variables[index].object; - - acpi_os_printf ("Local%d: ", index); - acpi_db_display_internal_object (obj_desc, walk_state); - break; - - default: - break; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_walk_for_specific_objects - * - * PARAMETERS: Callback from Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Display short info about objects in the namespace - * - ******************************************************************************/ - -acpi_status -acpi_db_walk_for_specific_objects ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_operand_object *obj_desc; - acpi_status status; - u32 buf_size; - NATIVE_CHAR buffer[64]; - - - obj_desc = ((acpi_namespace_node *)obj_handle)->object; - buf_size = sizeof (buffer) / sizeof (*buffer); - - /* Get and display the full pathname to this object */ - - status = acpi_ns_handle_to_pathname (obj_handle, &buf_size, buffer); - - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle); - return (AE_OK); - } - - acpi_os_printf ("%32s", buffer); - - - /* Display short information about the object */ - - if (obj_desc) { - switch (obj_desc->common.type) { - case ACPI_TYPE_METHOD: - acpi_os_printf (" #Args %d Concurrency %X", obj_desc->method.param_count, obj_desc->method.concurrency); - break; - - case ACPI_TYPE_INTEGER: - acpi_os_printf (" Value %X", obj_desc->integer.value); - break; - - case ACPI_TYPE_STRING: - acpi_os_printf (" \"%s\"", obj_desc->string.pointer); - break; - - case ACPI_TYPE_REGION: - acpi_os_printf (" Space_id %X Address %X Length %X", obj_desc->region.space_id, obj_desc->region.address, obj_desc->region.length); - break; - - case ACPI_TYPE_PACKAGE: - acpi_os_printf (" #Elements %X", obj_desc->package.count); - break; - - case ACPI_TYPE_BUFFER: - acpi_os_printf (" Length %X", obj_desc->buffer.length); - break; - } - } - - acpi_os_printf ("\n"); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_objects - * - * PARAMETERS: Obj_type_arg - Type of object to display - * Display_count_arg - Max depth to display - * - * RETURN: None - * - * DESCRIPTION: Display objects in the namespace of the requested type - * - ******************************************************************************/ - -acpi_status -acpi_db_display_objects ( - NATIVE_CHAR *obj_type_arg, - NATIVE_CHAR *display_count_arg) -{ - acpi_object_type8 type; - - - /* Get the object type */ - - type = acpi_db_match_argument (obj_type_arg, acpi_db_object_types); - if (type == ACPI_TYPE_NOT_FOUND) { - acpi_os_printf ("Invalid or unsupported argument\n"); - return (AE_OK); - } - - acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT); - acpi_os_printf ("Objects of type [%s] defined in the current ACPI Namespace: \n", acpi_ut_get_type_name (type)); - - acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT); - - /* Walk the namespace from the root */ - - acpi_walk_namespace (type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_db_walk_for_specific_objects, (void *) &type, NULL); - - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_walk_and_match_name - * - * PARAMETERS: Callback from Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Find a particular name/names within the namespace. Wildcards - * are supported -- '?' matches any character. - * - ******************************************************************************/ - -acpi_status -acpi_db_walk_and_match_name ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_status status; - NATIVE_CHAR *requested_name = (NATIVE_CHAR *) context; - u32 i; - u32 buf_size; - NATIVE_CHAR buffer[96]; - - - /* Check for a name match */ - - for (i = 0; i < 4; i++) { - /* Wildcard support */ - - if ((requested_name[i] != '?') && - (requested_name[i] != ((NATIVE_CHAR *) (&((acpi_namespace_node *) obj_handle)->name))[i])) { - /* No match, just exit */ - - return (AE_OK); - } - } - - - /* Get the full pathname to this object */ - - buf_size = sizeof (buffer) / sizeof (*buffer); - - status = acpi_ns_handle_to_pathname (obj_handle, &buf_size, buffer); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle); - } - - else { - acpi_os_printf ("%32s (%p) - %s\n", buffer, obj_handle, - acpi_ut_get_type_name (((acpi_namespace_node *) obj_handle)->type)); - } - - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_find_name_in_namespace - * - * PARAMETERS: Name_arg - The 4-character ACPI name to find. - * wildcards are supported. - * - * RETURN: None - * - * DESCRIPTION: Search the namespace for a given name (with wildcards) - * - ******************************************************************************/ - -acpi_status -acpi_db_find_name_in_namespace ( - NATIVE_CHAR *name_arg) -{ - - if (STRLEN (name_arg) > 4) { - acpi_os_printf ("Name must be no longer than 4 characters\n"); - return (AE_OK); - } - - /* Walk the namespace from the root */ - - acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_db_walk_and_match_name, name_arg, NULL); - - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_scope - * - * PARAMETERS: Name - New scope path - * - * RETURN: Status - * - * DESCRIPTION: Set the "current scope" as maintained by this utility. - * The scope is used as a prefix to ACPI paths. - * - ******************************************************************************/ - -void -acpi_db_set_scope ( - NATIVE_CHAR *name) -{ - - if (!name || name[0] == 0) { - acpi_os_printf ("Current scope: %s\n", acpi_gbl_db_scope_buf); - return; - } - - acpi_db_prep_namestring (name); - - /* TBD: [Future] Validate scope here */ - - if (name[0] == '\\') { - STRCPY (acpi_gbl_db_scope_buf, name); - STRCAT (acpi_gbl_db_scope_buf, "\\"); - } - - else { - STRCAT (acpi_gbl_db_scope_buf, name); - STRCAT (acpi_gbl_db_scope_buf, "\\"); - } - - acpi_os_printf ("New scope: %s\n", acpi_gbl_db_scope_buf); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_resources - * - * PARAMETERS: Object_arg - String with hex value of the object - * - * RETURN: None - * - * DESCRIPTION: - * - ******************************************************************************/ - -void -acpi_db_display_resources ( - NATIVE_CHAR *object_arg) -{ -#ifndef _IA16 - acpi_operand_object *obj_desc; - acpi_status status; - acpi_buffer return_obj; - - - acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT); - - /* Convert string to object pointer */ - - obj_desc = (acpi_operand_object *) STRTOUL (object_arg, NULL, 16); - - /* Prepare for a return object of arbitrary size */ - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - - /* _PRT */ - - acpi_os_printf ("Evaluating _PRT\n"); - - status = acpi_evaluate_object (obj_desc, "_PRT", NULL, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not obtain _PRT: %s\n", acpi_format_exception (status)); - goto get_crs; - } - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_get_irq_routing_table (obj_desc, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Get_irq_routing_table failed: %s\n", acpi_format_exception (status)); - } - - else { - acpi_rs_dump_irq_list ((u8 *) acpi_gbl_db_buffer); - } - - - /* _CRS */ - -get_crs: - acpi_os_printf ("Evaluating _CRS\n"); - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_evaluate_object (obj_desc, "_CRS", NULL, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not obtain _CRS: %s\n", acpi_format_exception (status)); - goto get_prs; - } - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_get_current_resources (obj_desc, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Acpi_get_current_resources failed: %s\n", acpi_format_exception (status)); - } - - else { - acpi_rs_dump_resource_list ((acpi_resource *) acpi_gbl_db_buffer); - } - - - /* _PRS */ - -get_prs: - acpi_os_printf ("Evaluating _PRS\n"); - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_evaluate_object (obj_desc, "_PRS", NULL, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not obtain _PRS: %s\n", acpi_format_exception (status)); - goto cleanup; - } - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_get_possible_resources (obj_desc, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Acpi_get_possible_resources failed: %s\n", acpi_format_exception (status)); - } - - else { - acpi_rs_dump_resource_list ((acpi_resource *) acpi_gbl_db_buffer); - } - - -cleanup: - - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); - return; -#endif - -} - - -#endif /* ENABLE_DEBUGGER */ diff -urN linux-2.4.21/drivers/acpi/debugger/dbdisasm.c linux-2.4.22/drivers/acpi/debugger/dbdisasm.c --- linux-2.4.21/drivers/acpi/debugger/dbdisasm.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbdisasm.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,715 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbdisasm - parser op tree display routines - * $Revision: 50 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbdisasm") - - -#define MAX_SHOW_ENTRY 128 -#define BLOCK_PAREN 1 -#define BLOCK_BRACE 2 -#define DB_NO_OP_INFO " [%2.2d] " -#define DB_FULL_OP_INFO "%5.5X #%4.4X [%2.2d] " - - -NATIVE_CHAR *acpi_gbl_db_disasm_indent = "...."; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_block_type - * - * PARAMETERS: Op - Object to be examined - * - * RETURN: Status - * - * DESCRIPTION: Type of block for this op (parens or braces) - * - ******************************************************************************/ - -u32 -acpi_db_block_type ( - acpi_parse_object *op) -{ - - switch (op->opcode) { - case AML_METHOD_OP: - return (BLOCK_BRACE); - break; - - default: - break; - } - - return (BLOCK_PAREN); - -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_display_object_pathname - * - * PARAMETERS: Op - Object whose pathname is to be obtained - * - * RETURN: Status - * - * DESCRIPTION: Diplay the pathname associated with a named object. Two - * versions. One searches the parse tree (for parser-only - * applications suchas Acpi_dump), and the other searches the - * ACPI namespace (the parse tree is probably deleted) - * - ******************************************************************************/ - -#ifdef PARSER_ONLY - -acpi_status -acpi_ps_display_object_pathname ( - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - acpi_parse_object *target_op; - - - /* Search parent tree up to the root if necessary */ - - target_op = acpi_ps_find (op, op->value.name, 0, 0); - if (!target_op) { - /* - * Didn't find the name in the parse tree. This may be - * a problem, or it may simply be one of the predefined names - * (such as _OS_). Rather than worry about looking up all - * the predefined names, just display the name as given - */ - acpi_os_printf (" **** Path not found in parse tree"); - } - - else { - /* The target was found, print the name and complete path */ - - acpi_os_printf (" (Path "); - acpi_db_display_path (target_op); - acpi_os_printf (")"); - } - - return (AE_OK); -} - -#else - -acpi_status -acpi_ps_display_object_pathname ( - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - acpi_status status; - acpi_namespace_node *node; - NATIVE_CHAR buffer[MAX_SHOW_ENTRY]; - u32 buffer_size = MAX_SHOW_ENTRY; - u32 debug_level; - - - /* Save current debug level so we don't get extraneous debug output */ - - debug_level = acpi_dbg_level; - acpi_dbg_level = 0; - - /* Just get the Node out of the Op object */ - - node = op->node; - if (!node) { - /* Node not defined in this scope, look it up */ - - status = acpi_ns_lookup (walk_state->scope_info, op->value.string, ACPI_TYPE_ANY, - IMODE_EXECUTE, NS_SEARCH_PARENT, walk_state, &(node)); - - if (ACPI_FAILURE (status)) { - /* - * We can't get the pathname since the object - * is not in the namespace. This can happen during single - * stepping where a dynamic named object is *about* to be created. - */ - acpi_os_printf (" [Path not found]"); - goto exit; - } - - /* Save it for next time. */ - - op->node = node; - } - - /* Convert Named_desc/handle to a full pathname */ - - status = acpi_ns_handle_to_pathname (node, &buffer_size, buffer); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("****Could not get pathname****)"); - goto exit; - } - - acpi_os_printf (" (Path %s)", buffer); - - -exit: - /* Restore the debug level */ - - acpi_dbg_level = debug_level; - return (status); -} - -#endif - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_op - * - * PARAMETERS: Origin - Starting object - * Num_opcodes - Max number of opcodes to be displayed - * - * RETURN: None - * - * DESCRIPTION: Display parser object and its children - * - ******************************************************************************/ - -void -acpi_db_display_op ( - acpi_walk_state *walk_state, - acpi_parse_object *origin, - u32 num_opcodes) -{ - acpi_parse_object *op = origin; - acpi_parse_object *arg; - acpi_parse_object *depth; - u32 depth_count = 0; - u32 last_depth = 0; - u32 i; - u32 j; - - - if (op) { - while (op) { - /* indentation */ - - depth_count = 0; - if (!acpi_gbl_db_opt_verbose) { - depth_count++; - } - - /* Determine the nesting depth of this argument */ - - for (depth = op->parent; depth; depth = depth->parent) { - arg = acpi_ps_get_arg (depth, 0); - while (arg && arg != origin) { - arg = arg->next; - } - - if (arg) { - break; - } - - depth_count++; - } - - - /* Open a new block if we are nested further than last time */ - - if (depth_count > last_depth) { - VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth)); - for (i = 0; i < last_depth; i++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - - if (acpi_db_block_type (op) == BLOCK_PAREN) { - acpi_os_printf ("(\n"); - } - else { - acpi_os_printf ("{\n"); - } - } - - /* Close a block if we are nested less than last time */ - - else if (depth_count < last_depth) { - for (j = 0; j < (last_depth - depth_count); j++) { - VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth - j)); - for (i = 0; i < (last_depth - j - 1); i++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - - if (acpi_db_block_type (op) == BLOCK_PAREN) { - acpi_os_printf (")\n"); - } - else { - acpi_os_printf ("}\n"); - } - } - } - - /* In verbose mode, print the AML offset, opcode and depth count */ - - VERBOSE_PRINT ((DB_FULL_OP_INFO, (unsigned) op->aml_offset, op->opcode, depth_count)); - - - /* Indent the output according to the depth count */ - - for (i = 0; i < depth_count; i++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - - - /* Now print the opcode */ - - acpi_db_display_opcode (walk_state, op); - - /* Resolve a name reference */ - - if ((op->opcode == AML_INT_NAMEPATH_OP && op->value.name) && - (op->parent) && - (acpi_gbl_db_opt_verbose)) { - acpi_ps_display_object_pathname (walk_state, op); - } - - acpi_os_printf ("\n"); - - /* Get the next node in the tree */ - - op = acpi_ps_get_depth_next (origin, op); - last_depth = depth_count; - - num_opcodes--; - if (!num_opcodes) { - op = NULL; - } - } - - /* Close the last block(s) */ - - depth_count = last_depth -1; - for (i = 0; i < last_depth; i++) { - VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth - i)); - for (j = 0; j < depth_count; j++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - acpi_os_printf ("}\n"); - depth_count--; - } - - } - - else { - acpi_db_display_opcode (walk_state, op); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_namestring - * - * PARAMETERS: Name - ACPI Name string to store - * - * RETURN: None - * - * DESCRIPTION: Display namestring. Handles prefix characters - * - ******************************************************************************/ - -void -acpi_db_display_namestring ( - NATIVE_CHAR *name) -{ - u32 seg_count; - u8 do_dot = FALSE; - - - if (!name) { - acpi_os_printf (""); - return; - } - - if (acpi_ps_is_prefix_char (GET8 (name))) { - /* append prefix character */ - - acpi_os_printf ("%1c", GET8 (name)); - name++; - } - - switch (GET8 (name)) { - case AML_DUAL_NAME_PREFIX: - seg_count = 2; - name++; - break; - - case AML_MULTI_NAME_PREFIX_OP: - seg_count = (u32) GET8 (name + 1); - name += 2; - break; - - default: - seg_count = 1; - break; - } - - while (seg_count--) { - /* append Name segment */ - - if (do_dot) { - /* append dot */ - - acpi_os_printf ("."); - } - - acpi_os_printf ("%4.4s", name); - do_dot = TRUE; - - name += 4; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_path - * - * PARAMETERS: Op - Named Op whose path is to be constructed - * - * RETURN: None - * - * DESCRIPTION: Walk backwards from current scope and display the name - * of each previous level of scope up to the root scope - * (like "pwd" does with file systems) - * - ******************************************************************************/ - -void -acpi_db_display_path ( - acpi_parse_object *op) -{ - acpi_parse_object *prev; - acpi_parse_object *search; - u32 name; - u8 do_dot = FALSE; - acpi_parse_object *name_path; - const acpi_opcode_info *op_info; - - - /* We are only interested in named objects */ - - op_info = acpi_ps_get_opcode_info (op->opcode); - if (!(op_info->flags & AML_NSNODE)) { - return; - } - - - if (op_info->flags & AML_CREATE) { - /* Field creation - check for a fully qualified namepath */ - - if (op->opcode == AML_CREATE_FIELD_OP) { - name_path = acpi_ps_get_arg (op, 3); - } - else { - name_path = acpi_ps_get_arg (op, 2); - } - - if ((name_path) && - (name_path->value.string) && - (name_path->value.string[0] == '\\')) { - acpi_db_display_namestring (name_path->value.string); - return; - } - } - - prev = NULL; /* Start with Root Node */ - - while (prev != op) { - /* Search upwards in the tree to find scope with "prev" as its parent */ - - search = op; - for (; ;) { - if (search->parent == prev) { - break; - } - - /* Go up one level */ - - search = search->parent; - } - - if (prev) { - op_info = acpi_ps_get_opcode_info (search->opcode); - if (!(op_info->flags & AML_FIELD)) { - /* below root scope, append scope name */ - - if (do_dot) { - /* append dot */ - - acpi_os_printf ("."); - } - - if (op_info->flags & AML_CREATE) { - if (op->opcode == AML_CREATE_FIELD_OP) { - name_path = acpi_ps_get_arg (op, 3); - } - else { - name_path = acpi_ps_get_arg (op, 2); - } - - if ((name_path) && - (name_path->value.string)) { - acpi_os_printf ("%4.4s", name_path->value.string); - } - } - - else { - name = acpi_ps_get_name (search); - acpi_os_printf ("%4.4s", &name); - } - - do_dot = TRUE; - } - } - - prev = search; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_opcode - * - * PARAMETERS: Op - Op that is to be printed - * - * RETURN: Status - * - * DESCRIPTION: Store printed op in a Buffer and return its length - * (or -1 if out of space) - * - * NOTE: Terse mode prints out ASL-like code. Verbose mode adds more info. - * - ******************************************************************************/ - -void -acpi_db_display_opcode ( - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - u8 *byte_data; - u32 byte_count; - u32 i; - const acpi_opcode_info *op_info = NULL; - u32 name; - - - if (!op) { - acpi_os_printf (""); - } - - - /* op and arguments */ - - switch (op->opcode) { - - case AML_BYTE_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u8) 0x%2.2X", op->value.integer8); - } - - else { - acpi_os_printf ("0x%2.2X", op->value.integer8); - } - - break; - - - case AML_WORD_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u16) 0x%4.4X", op->value.integer16); - } - - else { - acpi_os_printf ("0x%4.4X", op->value.integer16); - } - - break; - - - case AML_DWORD_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u32) 0x%8.8X", op->value.integer32); - } - - else { - acpi_os_printf ("0x%8.8X", op->value.integer32); - } - - break; - - - case AML_QWORD_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u64) 0x%8.8X%8.8X", op->value.integer64.hi, - op->value.integer64.lo); - } - - else { - acpi_os_printf ("0x%8.8X%8.8X", op->value.integer64.hi, - op->value.integer64.lo); - } - - break; - - - case AML_STRING_OP: - - if (op->value.string) { - acpi_os_printf ("\"%s\"", op->value.string); - } - - else { - acpi_os_printf ("<\"NULL STRING PTR\">"); - } - - break; - - - case AML_INT_STATICSTRING_OP: - - if (op->value.string) { - acpi_os_printf ("\"%s\"", op->value.string); - } - - else { - acpi_os_printf ("\"\""); - } - - break; - - - case AML_INT_NAMEPATH_OP: - - acpi_db_display_namestring (op->value.name); - break; - - - case AML_INT_NAMEDFIELD_OP: - - acpi_os_printf ("Named_field (Length 0x%8.8X) ", op->value.integer32); - break; - - - case AML_INT_RESERVEDFIELD_OP: - - acpi_os_printf ("Reserved_field (Length 0x%8.8X) ", op->value.integer32); - break; - - - case AML_INT_ACCESSFIELD_OP: - - acpi_os_printf ("Access_field (Length 0x%8.8X) ", op->value.integer32); - break; - - - case AML_INT_BYTELIST_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("Byte_list (Length 0x%8.8X) ", op->value.integer32); - } - - else { - acpi_os_printf ("0x%2.2X", op->value.integer32); - - byte_count = op->value.integer32; - byte_data = ((acpi_parse2_object *) op)->data; - - for (i = 0; i < byte_count; i++) { - acpi_os_printf (", 0x%2.2X", byte_data[i]); - } - } - - break; - - - default: - - /* Just get the opcode name and print it */ - - op_info = acpi_ps_get_opcode_info (op->opcode); - acpi_os_printf ("%s", op_info->name); - - -#ifndef PARSER_ONLY - if ((op->opcode == AML_INT_RETURN_VALUE_OP) && - (walk_state->results) && - (walk_state->results->results.num_results)) { - acpi_db_decode_internal_object (walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]); - } -#endif - - break; - } - - if (!op_info) { - /* If there is another element in the list, add a comma */ - - if (op->next) { - acpi_os_printf (","); - } - } - - /* - * If this is a named opcode, print the associated name value - */ - op_info = acpi_ps_get_opcode_info (op->opcode); - if (op && (op_info->flags & AML_NAMED)) { - name = acpi_ps_get_name (op); - acpi_os_printf (" %4.4s", &name); - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf (" (Path \\"); - acpi_db_display_path (op); - acpi_os_printf (")"); - } - } -} - - -#endif /* ENABLE_DEBUGGER */ - diff -urN linux-2.4.21/drivers/acpi/debugger/dbdisply.c linux-2.4.22/drivers/acpi/debugger/dbdisply.c --- linux-2.4.21/drivers/acpi/debugger/dbdisply.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbdisply.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,794 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbdisply - debug display commands - * $Revision: 57 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acevents.h" -#include "acinterp.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbdisply") - - -/****************************************************************************** - * - * FUNCTION: Acpi_db_get_pointer - * - * PARAMETERS: Target - Pointer to string to be converted - * - * RETURN: Converted pointer - * - * DESCRIPTION: Convert an ascii pointer value to a real value - * - *****************************************************************************/ - -void * -acpi_db_get_pointer ( - void *target) -{ - void *obj_ptr; - - -#ifdef _IA16 -#include - - /* Have to handle 16-bit pointers of the form segment:offset */ - - if (!sscanf (target, "%p", &obj_ptr)) { - acpi_os_printf ("Invalid pointer: %s\n", target); - return (NULL); - } - -#else - - /* Simple flat pointer */ - - obj_ptr = (void *) STRTOUL (target, NULL, 16); - -#endif - - return (obj_ptr); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_parser_descriptor - * - * PARAMETERS: Op - A parser Op descriptor - * - * RETURN: None - * - * DESCRIPTION: Display a formatted parser object - * - ******************************************************************************/ - -void -acpi_db_dump_parser_descriptor ( - acpi_parse_object *op) -{ - const acpi_opcode_info *info; - - - info = acpi_ps_get_opcode_info (op->opcode); - - acpi_os_printf ("Parser Op Descriptor:\n"); - acpi_os_printf ("%20.20s : %4.4X\n", "Opcode", op->opcode); - - DEBUG_ONLY_MEMBERS (acpi_os_printf ("%20.20s : %s\n", "Opcode Name", info->name)); - - acpi_os_printf ("%20.20s : %p\n", "Value/Arg_list", op->value); - acpi_os_printf ("%20.20s : %p\n", "Parent", op->parent); - acpi_os_printf ("%20.20s : %p\n", "Next_op", op->next); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_decode_and_display_object - * - * PARAMETERS: Target - String with object to be displayed. Names - * and hex pointers are supported. - * Output_type - Byte, Word, Dword, or Qword (B|W|D|Q) - * - * RETURN: None - * - * DESCRIPTION: Display a formatted ACPI object - * - ******************************************************************************/ - -void -acpi_db_decode_and_display_object ( - NATIVE_CHAR *target, - NATIVE_CHAR *output_type) -{ - void *obj_ptr; - acpi_namespace_node *node; - u32 display = DB_BYTE_DISPLAY; - NATIVE_CHAR buffer[80]; - acpi_buffer ret_buf; - acpi_status status; - u32 size; - - - if (!target) { - return; - } - - /* Decode the output type */ - - if (output_type) { - STRUPR (output_type); - if (output_type[0] == 'W') { - display = DB_WORD_DISPLAY; - } - else if (output_type[0] == 'D') { - display = DB_DWORD_DISPLAY; - } - else if (output_type[0] == 'Q') { - display = DB_QWORD_DISPLAY; - } - } - - - ret_buf.length = sizeof (buffer); - ret_buf.pointer = buffer; - - /* Differentiate between a number and a name */ - - if ((target[0] >= 0x30) && (target[0] <= 0x39)) { - obj_ptr = acpi_db_get_pointer (target); - if (!acpi_os_readable (obj_ptr, 16)) { - acpi_os_printf ("Address %p is invalid in this address space\n", obj_ptr); - return; - } - - /* Decode the object type */ - - if (VALID_DESCRIPTOR_TYPE ((obj_ptr), ACPI_DESC_TYPE_NAMED)) { - /* This is a Node */ - - if (!acpi_os_readable (obj_ptr, sizeof (acpi_namespace_node))) { - acpi_os_printf ("Cannot read entire Named object at address %p\n", obj_ptr); - return; - } - - node = obj_ptr; - goto dump_nte; - } - - else if (VALID_DESCRIPTOR_TYPE ((obj_ptr), ACPI_DESC_TYPE_INTERNAL)) { - /* This is an ACPI OBJECT */ - - if (!acpi_os_readable (obj_ptr, sizeof (acpi_operand_object))) { - acpi_os_printf ("Cannot read entire ACPI object at address %p\n", obj_ptr); - return; - } - - acpi_ut_dump_buffer (obj_ptr, sizeof (acpi_operand_object), display, ACPI_UINT32_MAX); - acpi_ex_dump_object_descriptor (obj_ptr, 1); - } - - else if (VALID_DESCRIPTOR_TYPE ((obj_ptr), ACPI_DESC_TYPE_PARSER)) { - /* This is an Parser Op object */ - - if (!acpi_os_readable (obj_ptr, sizeof (acpi_parse_object))) { - acpi_os_printf ("Cannot read entire Parser object at address %p\n", obj_ptr); - return; - } - - - acpi_ut_dump_buffer (obj_ptr, sizeof (acpi_parse_object), display, ACPI_UINT32_MAX); - acpi_db_dump_parser_descriptor ((acpi_parse_object *) obj_ptr); - } - - else { - size = 16; - if (acpi_os_readable (obj_ptr, 64)) { - size = 64; - } - - /* Just dump some memory */ - - acpi_ut_dump_buffer (obj_ptr, size, display, ACPI_UINT32_MAX); - } - - return; - } - - - /* The parameter is a name string that must be resolved to a Named obj */ - - node = acpi_db_local_ns_lookup (target); - if (!node) { - return; - } - - -dump_nte: - /* Now dump the Named obj */ - - status = acpi_get_name (node, ACPI_FULL_PATHNAME, &ret_buf); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not convert name to pathname\n"); - } - - else { - acpi_os_printf ("Object (%p) Pathname: %s\n", node, ret_buf.pointer); - } - - if (!acpi_os_readable (node, sizeof (acpi_namespace_node))) { - acpi_os_printf ("Invalid Named object at address %p\n", node); - return; - } - - acpi_ut_dump_buffer ((void *) node, sizeof (acpi_namespace_node), display, ACPI_UINT32_MAX); - acpi_ex_dump_node (node, 1); - - if (node->object) { - acpi_os_printf ("\n_attached Object (%p):\n", node->object); - if (!acpi_os_readable (node->object, sizeof (acpi_operand_object))) { - acpi_os_printf ("Invalid internal ACPI Object at address %p\n", node->object); - return; - } - - acpi_ut_dump_buffer ((void *) node->object, sizeof (acpi_operand_object), display, ACPI_UINT32_MAX); - acpi_ex_dump_object_descriptor (node->object, 1); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_decode_internal_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * - * RETURN: None - * - * DESCRIPTION: Short display of an internal object. Numbers and Strings. - * - ******************************************************************************/ - -void -acpi_db_decode_internal_object ( - acpi_operand_object *obj_desc) -{ - u32 i; - - - if (!obj_desc) { - return; - } - - acpi_os_printf (" %s", acpi_ut_get_type_name (obj_desc->common.type)); - - switch (obj_desc->common.type) { - case ACPI_TYPE_INTEGER: - - acpi_os_printf (" %.8X%.8X", HIDWORD (obj_desc->integer.value), - LODWORD (obj_desc->integer.value)); - break; - - - case ACPI_TYPE_STRING: - - acpi_os_printf ("(%d) \"%.24s", - obj_desc->string.length, obj_desc->string.pointer); - - if (obj_desc->string.length > 24) - { - acpi_os_printf ("..."); - } - else - { - acpi_os_printf ("\""); - } - break; - - - case ACPI_TYPE_BUFFER: - - acpi_os_printf ("(%d)", obj_desc->buffer.length); - for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) { - acpi_os_printf (" %2.2X", obj_desc->buffer.pointer[i]); - } - break; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_internal_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * Walk_state - Current walk state - * - * RETURN: None - * - * DESCRIPTION: Short display of an internal object - * - ******************************************************************************/ - -void -acpi_db_display_internal_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) -{ - u8 type; - - - acpi_os_printf ("%p ", obj_desc); - - if (!obj_desc) { - acpi_os_printf ("\n"); - return; - } - - - /* Decode the object type */ - - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_PARSER)) { - acpi_os_printf (" "); - } - - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - acpi_os_printf (" Name %4.4s Type-%s", - &((acpi_namespace_node *)obj_desc)->name, - acpi_ut_get_type_name (((acpi_namespace_node *) obj_desc)->type)); - if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_ARG) { - acpi_os_printf (" [Method Arg]"); - } - if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_LOCAL) { - acpi_os_printf (" [Method Local]"); - } - } - - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { - type = obj_desc->common.type; - if (type > INTERNAL_TYPE_MAX) { - acpi_os_printf (" Type %x [Invalid Type]", type); - return; - } - - /* Decode the ACPI object type */ - - switch (obj_desc->common.type) { - case INTERNAL_TYPE_REFERENCE: - switch (obj_desc->reference.opcode) { - case AML_ZERO_OP: - acpi_os_printf ("[Const] Zero (0) [Null Target]", 0); - break; - - case AML_ONES_OP: - acpi_os_printf ("[Const] Ones (0xFFFFFFFFFFFFFFFF) [No Limit]"); - break; - - case AML_ONE_OP: - acpi_os_printf ("[Const] One (1)"); - break; - - case AML_REVISION_OP: - acpi_os_printf ("[Const] Revision (%X)", ACPI_CA_SUPPORT_LEVEL); - break; - - case AML_LOCAL_OP: - acpi_os_printf ("[Local%d]", obj_desc->reference.offset); - if (walk_state) { - obj_desc = walk_state->local_variables[obj_desc->reference.offset].object; - acpi_os_printf (" %p", obj_desc); - acpi_db_decode_internal_object (obj_desc); - } - break; - - case AML_ARG_OP: - acpi_os_printf ("[Arg%d] ", obj_desc->reference.offset); - if (walk_state) { - obj_desc = walk_state->arguments[obj_desc->reference.offset].object; - acpi_os_printf (" %p", obj_desc); - acpi_db_decode_internal_object (obj_desc); - } - break; - - case AML_DEBUG_OP: - acpi_os_printf ("[Debug] "); - break; - - case AML_INDEX_OP: - acpi_os_printf ("[Index] "); - acpi_db_decode_internal_object (obj_desc->reference.object); - break; - - default: - break; - - } - break; - - default: - acpi_os_printf (" "); - acpi_os_printf (" "); - acpi_db_decode_internal_object (obj_desc); - break; - } - } - - else { - acpi_os_printf (" "); - } - - acpi_os_printf ("\n"); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_method_info - * - * PARAMETERS: Start_op - Root of the control method parse tree - * - * RETURN: None - * - * DESCRIPTION: Display information about the current method - * - ******************************************************************************/ - -void -acpi_db_display_method_info ( - acpi_parse_object *start_op) -{ - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - acpi_namespace_node *node; - acpi_parse_object *root_op; - acpi_parse_object *op; - const acpi_opcode_info *op_info; - u32 num_ops = 0; - u32 num_operands = 0; - u32 num_operators = 0; - u32 num_remaining_ops = 0; - u32 num_remaining_operands = 0; - u32 num_remaining_operators = 0; - u32 num_args; - u32 concurrency; - u8 count_remaining = FALSE; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - - num_args = obj_desc->method.param_count; - concurrency = obj_desc->method.concurrency; - - acpi_os_printf ("Currently executing control method is [%4.4s]\n", &node->name); - acpi_os_printf ("%X arguments, max concurrency = %X\n", num_args, concurrency); - - - root_op = start_op; - while (root_op->parent) { - root_op = root_op->parent; - } - - op = root_op; - - while (op) { - if (op == start_op) { - count_remaining = TRUE; - } - - num_ops++; - if (count_remaining) { - num_remaining_ops++; - } - - /* Decode the opcode */ - - op_info = acpi_ps_get_opcode_info (op->opcode); - switch (op_info->class) { - case AML_CLASS_ARGUMENT: - if (count_remaining) { - num_remaining_operands++; - } - - num_operands++; - break; - - case AML_CLASS_UNKNOWN: - /* Bad opcode or ASCII character */ - - continue; - - default: - if (count_remaining) { - num_remaining_operators++; - } - - num_operators++; - break; - } - - - op = acpi_ps_get_depth_next (start_op, op); - } - - acpi_os_printf ("Method contains: %X AML Opcodes - %X Operators, %X Operands\n", - num_ops, num_operators, num_operands); - - acpi_os_printf ("Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n", - num_remaining_ops, num_remaining_operators, num_remaining_operands); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_locals - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display all locals for the currently running control method - * - ******************************************************************************/ - -void -acpi_db_display_locals (void) -{ - u32 i; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - - - acpi_os_printf ("Local Variables for method [%4.4s]:\n", &node->name); - - for (i = 0; i < MTH_NUM_LOCALS; i++) { - obj_desc = walk_state->local_variables[i].object; - acpi_os_printf ("Local%d: ", i); - acpi_db_display_internal_object (obj_desc, walk_state); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_arguments - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display all arguments for the currently running control method - * - ******************************************************************************/ - -void -acpi_db_display_arguments (void) -{ - u32 i; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - u32 num_args; - u32 concurrency; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - - num_args = obj_desc->method.param_count; - concurrency = obj_desc->method.concurrency; - - acpi_os_printf ("Method [%4.4s] has %X arguments, max concurrency = %X\n", &node->name, num_args, concurrency); - - for (i = 0; i < num_args; i++) { - obj_desc = walk_state->arguments[i].object; - acpi_os_printf ("Arg%d: ", i); - acpi_db_display_internal_object (obj_desc, walk_state); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_results - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display current contents of a method result stack - * - ******************************************************************************/ - -void -acpi_db_display_results (void) -{ - u32 i; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - u32 num_results = 0; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - - if (walk_state->results) { - num_results = walk_state->results->results.num_results; - } - - acpi_os_printf ("Method [%4.4s] has %X stacked result objects\n", &node->name, num_results); - - for (i = 0; i < num_results; i++) { - obj_desc = walk_state->results->results.obj_desc[i]; - acpi_os_printf ("Result%d: ", i); - acpi_db_display_internal_object (obj_desc, walk_state); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_calling_tree - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display current calling tree of nested control methods - * - ******************************************************************************/ - -void -acpi_db_display_calling_tree (void) -{ - u32 i; - acpi_walk_state *walk_state; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - node = walk_state->method_node; - - acpi_os_printf ("Current Control Method Call Tree\n"); - - for (i = 0; walk_state; i++) { - node = walk_state->method_node; - - acpi_os_printf (" [%4.4s]\n", &node->name); - - walk_state = walk_state->next; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_result_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * Walk_state - Current walk state - * - * RETURN: None - * - * DESCRIPTION: Display the result of an AML opcode - * - ******************************************************************************/ - -void -acpi_db_display_result_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) -{ - - /* TBD: [Future] We don't always want to display the result. - * For now, only display if single stepping - * however, this output is very useful in other contexts also - */ - if (!acpi_gbl_cm_single_step) { - return; - } - - acpi_os_printf ("Result_obj: "); - acpi_db_display_internal_object (obj_desc, walk_state); - acpi_os_printf ("\n"); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_argument_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * Walk_state - Current walk state - * - * RETURN: None - * - * DESCRIPTION: Display the result of an AML opcode - * - ******************************************************************************/ - -void -acpi_db_display_argument_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) -{ - - - if (!acpi_gbl_cm_single_step) { - return; - } - - acpi_os_printf ("Arg_obj: "); - acpi_db_display_internal_object (obj_desc, walk_state); -} - -#endif /* ENABLE_DEBUGGER */ - diff -urN linux-2.4.21/drivers/acpi/debugger/dbexec.c linux-2.4.22/drivers/acpi/debugger/dbexec.c --- linux-2.4.21/drivers/acpi/debugger/dbexec.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbexec.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,404 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbexec - debugger control method execution - * $Revision: 34 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acevents.h" -#include "acinterp.h" -#include "acdebug.h" -#include "actables.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbexec") - - -db_method_info acpi_gbl_db_method_info; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute_method - * - * PARAMETERS: Info - Valid info segment - * Return_obj - Where to put return object - * - * RETURN: Status - * - * DESCRIPTION: Execute a control method. - * - ******************************************************************************/ - -acpi_status -acpi_db_execute_method ( - db_method_info *info, - acpi_buffer *return_obj) -{ - acpi_status status; - acpi_object_list param_objects; - acpi_object params[MTH_NUM_ARGS]; - u32 i; - - - if (acpi_gbl_db_output_to_file && !acpi_dbg_level) { - acpi_os_printf ("Warning: debug output is not enabled!\n"); - } - - /* Are there arguments to the method? */ - - if (info->args && info->args[0]) { - for (i = 0; info->args[i] && i < MTH_NUM_ARGS; i++) { - params[i].type = ACPI_TYPE_INTEGER; - params[i].integer.value = STRTOUL (info->args[i], NULL, 16); - } - - param_objects.pointer = params; - param_objects.count = i; - } - - else { - /* Setup default parameters */ - - params[0].type = ACPI_TYPE_INTEGER; - params[0].integer.value = 0x01020304; - - params[1].type = ACPI_TYPE_STRING; - params[1].string.length = 12; - params[1].string.pointer = "AML Debugger"; - - param_objects.pointer = params; - param_objects.count = 2; - } - - /* Prepare for a return object of arbitrary size */ - - return_obj->pointer = acpi_gbl_db_buffer; - return_obj->length = ACPI_DEBUG_BUFFER_SIZE; - - - /* Do the actual method execution */ - - status = acpi_evaluate_object (NULL, info->pathname, ¶m_objects, return_obj); - - acpi_gbl_cm_single_step = FALSE; - acpi_gbl_method_executing = FALSE; - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute_setup - * - * PARAMETERS: Info - Valid method info - * - * RETURN: Status - * - * DESCRIPTION: Setup info segment prior to method execution - * - ******************************************************************************/ - -void -acpi_db_execute_setup ( - db_method_info *info) -{ - - /* Catenate the current scope to the supplied name */ - - info->pathname[0] = 0; - if ((info->name[0] != '\\') && - (info->name[0] != '/')) { - STRCAT (info->pathname, acpi_gbl_db_scope_buf); - } - - STRCAT (info->pathname, info->name); - acpi_db_prep_namestring (info->pathname); - - acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT); - acpi_os_printf ("Executing %s\n", info->pathname); - - if (info->flags & EX_SINGLE_STEP) { - acpi_gbl_cm_single_step = TRUE; - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); - } - - else { - /* No single step, allow redirection to a file */ - - acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_outstanding_allocations - * - * PARAMETERS: None - * - * RETURN: Current global allocation count minus cache entries - * - * DESCRIPTION: Determine the current number of "outstanding" allocations -- - * those allocations that have not been freed and also are not - * in one of the various object caches. - * - ******************************************************************************/ - -u32 -acpi_db_get_outstanding_allocations (void) -{ - u32 i; - u32 outstanding = 0; - - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - - for (i = ACPI_MEM_LIST_FIRST_CACHE_LIST; i < ACPI_NUM_MEM_LISTS; i++) { - outstanding += (acpi_gbl_memory_lists[i].total_allocated - - acpi_gbl_memory_lists[i].total_freed - - acpi_gbl_memory_lists[i].cache_depth); - } -#endif - - return (outstanding); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute - * - * PARAMETERS: Name - Name of method to execute - * Args - Parameters to the method - * Flags - single step/no single step - * - * RETURN: Status - * - * DESCRIPTION: Execute a control method. Name is relative to the current - * scope. - * - ******************************************************************************/ - -void -acpi_db_execute ( - NATIVE_CHAR *name, - NATIVE_CHAR **args, - u32 flags) -{ - acpi_status status; - acpi_buffer return_obj; - - -#ifdef ACPI_DEBUG - u32 previous_allocations; - u32 allocations; - - - /* Memory allocation tracking */ - - previous_allocations = acpi_db_get_outstanding_allocations (); -#endif - - acpi_gbl_db_method_info.name = name; - acpi_gbl_db_method_info.args = args; - acpi_gbl_db_method_info.flags = flags; - - acpi_db_execute_setup (&acpi_gbl_db_method_info); - status = acpi_db_execute_method (&acpi_gbl_db_method_info, &return_obj); - - /* - * Allow any handlers in separate threads to complete. - * (Such as Notify handlers invoked from AML executed above). - */ - acpi_os_sleep (0, 10); - - -#ifdef ACPI_DEBUG - - /* Memory allocation tracking */ - - allocations = acpi_db_get_outstanding_allocations () - previous_allocations; - - acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT); - - if (allocations > 0) { - acpi_os_printf ("Outstanding: %ld allocations after execution\n", - allocations); - } -#endif - - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Execution of %s failed with status %s\n", - acpi_gbl_db_method_info.pathname, acpi_format_exception (status)); - } - - else { - /* Display a return object, if any */ - - if (return_obj.length) { - acpi_os_printf ("Execution of %s returned object %p Buflen %X\n", - acpi_gbl_db_method_info.pathname, return_obj.pointer, return_obj.length); - acpi_db_dump_object (return_obj.pointer, 1); - } - } - - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_method_thread - * - * PARAMETERS: Context - Execution info segment - * - * RETURN: None - * - * DESCRIPTION: Debugger execute thread. Waits for a command line, then - * simply dispatches it. - * - ******************************************************************************/ - -void -acpi_db_method_thread ( - void *context) -{ - acpi_status status; - db_method_info *info = context; - u32 i; - acpi_buffer return_obj; - - - for (i = 0; i < info->num_loops; i++) { - status = acpi_db_execute_method (info, &return_obj); - if (ACPI_SUCCESS (status)) { - if (return_obj.length) { - acpi_os_printf ("Execution of %s returned object %p Buflen %X\n", - info->pathname, return_obj.pointer, return_obj.length); - acpi_db_dump_object (return_obj.pointer, 1); - } - } - } - - /* Signal our completion */ - - acpi_os_signal_semaphore (info->thread_gate, 1); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_create_execution_threads - * - * PARAMETERS: Num_threads_arg - Number of threads to create - * Num_loops_arg - Loop count for the thread(s) - * Method_name_arg - Control method to execute - * - * RETURN: None - * - * DESCRIPTION: Create threads to execute method(s) - * - ******************************************************************************/ - -void -acpi_db_create_execution_threads ( - NATIVE_CHAR *num_threads_arg, - NATIVE_CHAR *num_loops_arg, - NATIVE_CHAR *method_name_arg) -{ - acpi_status status; - u32 num_threads; - u32 num_loops; - u32 i; - acpi_handle thread_gate; - - - /* Get the arguments */ - - num_threads = STRTOUL (num_threads_arg, NULL, 0); - num_loops = STRTOUL (num_loops_arg, NULL, 0); - - if (!num_threads || !num_loops) { - acpi_os_printf ("Bad argument: Threads %X, Loops %X\n", num_threads, num_loops); - return; - } - - - /* Create the synchronization semaphore */ - - status = acpi_os_create_semaphore (1, 0, &thread_gate); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not create semaphore, %s\n", acpi_format_exception (status)); - return; - } - - /* Setup the context to be passed to each thread */ - - acpi_gbl_db_method_info.name = method_name_arg; - acpi_gbl_db_method_info.args = NULL; - acpi_gbl_db_method_info.flags = 0; - acpi_gbl_db_method_info.num_loops = num_loops; - acpi_gbl_db_method_info.thread_gate = thread_gate; - - acpi_db_execute_setup (&acpi_gbl_db_method_info); - - - /* Create the threads */ - - acpi_os_printf ("Creating %X threads to execute %X times each\n", num_threads, num_loops); - - for (i = 0; i < (num_threads); i++) { - acpi_os_queue_for_execution (OSD_PRIORITY_MED, acpi_db_method_thread, &acpi_gbl_db_method_info); - } - - - /* Wait for all threads to complete */ - - i = num_threads; - while (i) /* Brain damage for OSD implementations that only support wait of 1 unit */ { - status = acpi_os_wait_semaphore (thread_gate, 1, WAIT_FOREVER); - i--; - } - - /* Cleanup and exit */ - - acpi_os_delete_semaphore (thread_gate); - - acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT); - acpi_os_printf ("All threads (%X) have completed\n", num_threads); - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); -} - - -#endif /* ENABLE_DEBUGGER */ - - diff -urN linux-2.4.21/drivers/acpi/debugger/dbfileio.c linux-2.4.22/drivers/acpi/debugger/dbfileio.c --- linux-2.4.21/drivers/acpi/debugger/dbfileio.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbfileio.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,381 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbfileio - Debugger file I/O commands. These can't usually - * be used when running the debugger in Ring 0 (Kernel mode) - * $Revision: 53 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acdebug.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acevents.h" -#include "actables.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbfileio") - - -/* - * NOTE: this is here for lack of a better place. It is used in all - * flavors of the debugger, need LCD file - */ -#ifdef ACPI_APPLICATION -#include -FILE *acpi_gbl_debug_file = NULL; -#endif - - -acpi_table_header *acpi_gbl_db_table_ptr = NULL; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_match_argument - * - * PARAMETERS: User_argument - User command line - * Arguments - Array of commands to match against - * - * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found - * - * DESCRIPTION: Search command array for a command match - * - ******************************************************************************/ - -acpi_object_type8 -acpi_db_match_argument ( - NATIVE_CHAR *user_argument, - ARGUMENT_INFO *arguments) -{ - u32 i; - - - if (!user_argument || user_argument[0] == 0) { - return (ACPI_TYPE_NOT_FOUND); - } - - for (i = 0; arguments[i].name; i++) { - if (STRSTR (arguments[i].name, user_argument) == arguments[i].name) { - return ((acpi_object_type8) i); - } - } - - /* Argument not recognized */ - - return (ACPI_TYPE_NOT_FOUND); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_close_debug_file - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: If open, close the current debug output file - * - ******************************************************************************/ - -void -acpi_db_close_debug_file ( - void) -{ - -#ifdef ACPI_APPLICATION - - if (acpi_gbl_debug_file) { - fclose (acpi_gbl_debug_file); - acpi_gbl_debug_file = NULL; - acpi_gbl_db_output_to_file = FALSE; - acpi_os_printf ("Debug output file %s closed\n", acpi_gbl_db_debug_filename); - } -#endif - -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_open_debug_file - * - * PARAMETERS: Name - Filename to open - * - * RETURN: Status - * - * DESCRIPTION: Open a file where debug output will be directed. - * - ******************************************************************************/ - -void -acpi_db_open_debug_file ( - NATIVE_CHAR *name) -{ - -#ifdef ACPI_APPLICATION - - acpi_db_close_debug_file (); - acpi_gbl_debug_file = fopen (name, "w+"); - if (acpi_gbl_debug_file) { - acpi_os_printf ("Debug output file %s opened\n", name); - STRCPY (acpi_gbl_db_debug_filename, name); - acpi_gbl_db_output_to_file = TRUE; - } - else { - acpi_os_printf ("Could not open debug file %s\n", name); - } - -#endif -} - - -#ifdef ACPI_APPLICATION -/******************************************************************************* - * - * FUNCTION: Acpi_db_load_table - * - * PARAMETERS: fp - File that contains table - * Table_ptr - Return value, buffer with table - * Table_lenght - Return value, length of table - * - * RETURN: Status - * - * DESCRIPTION: Load the DSDT from the file pointer - * - ******************************************************************************/ - -acpi_status -acpi_db_load_table( - FILE *fp, - acpi_table_header **table_ptr, - u32 *table_length) -{ - acpi_table_header table_header; - u8 *aml_start; - u32 aml_length; - u32 actual; - acpi_status status; - - - /* Read the table header */ - - if (fread (&table_header, 1, sizeof (table_header), fp) != sizeof (acpi_table_header)) { - acpi_os_printf ("Couldn't read the table header\n"); - return (AE_BAD_SIGNATURE); - } - - - /* Validate the table header/length */ - - status = acpi_tb_validate_table_header (&table_header); - if ((ACPI_FAILURE (status)) || - (table_header.length > 524288)) /* 1/2 Mbyte should be enough */ { - acpi_os_printf ("Table header is invalid!\n"); - return (AE_ERROR); - } - - - /* We only support a limited number of table types */ - - if (STRNCMP ((char *) table_header.signature, DSDT_SIG, 4) && - STRNCMP ((char *) table_header.signature, PSDT_SIG, 4) && - STRNCMP ((char *) table_header.signature, SSDT_SIG, 4)) { - acpi_os_printf ("Table signature is invalid\n"); - DUMP_BUFFER (&table_header, sizeof (acpi_table_header)); - return (AE_ERROR); - } - - /* Allocate a buffer for the table */ - - *table_length = table_header.length; - *table_ptr = acpi_os_allocate ((size_t) *table_length); - if (!*table_ptr) { - acpi_os_printf ("Could not allocate memory for ACPI table %4.4s (size=%X)\n", - table_header.signature, table_header.length); - return (AE_NO_MEMORY); - } - - - aml_start = (u8 *) *table_ptr + sizeof (table_header); - aml_length = *table_length - sizeof (table_header); - - /* Copy the header to the buffer */ - - MEMCPY (*table_ptr, &table_header, sizeof (table_header)); - - /* Get the rest of the table */ - - actual = fread (aml_start, 1, (size_t) aml_length, fp); - if (actual == aml_length) { - return (AE_OK); - } - - if (actual > 0) { - acpi_os_printf ("Warning - reading table, asked for %X got %X\n", aml_length, actual); - return (AE_OK); - } - - - acpi_os_printf ("Error - could not read the table file\n"); - acpi_os_free (*table_ptr); - *table_ptr = NULL; - *table_length = 0; - - return (AE_ERROR); -} -#endif - - -/******************************************************************************* - * - * FUNCTION: Ae_local_load_table - * - * PARAMETERS: Table_ptr - pointer to a buffer containing the entire - * table to be loaded - * - * RETURN: Status - * - * DESCRIPTION: This function is called to load a table from the caller's - * buffer. The buffer must contain an entire ACPI Table including - * a valid header. The header fields will be verified, and if it - * is determined that the table is invalid, the call will fail. - * - * If the call fails an appropriate status will be returned. - * - ******************************************************************************/ - -acpi_status -ae_local_load_table ( - acpi_table_header *table_ptr) -{ - acpi_status status; - acpi_table_desc table_info; - - - FUNCTION_TRACE ("Ae_local_load_table"); - - if (!table_ptr) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - /* Install the new table into the local data structures */ - - table_info.pointer = table_ptr; - - status = acpi_tb_install_table (NULL, &table_info); - if (ACPI_FAILURE (status)) { - /* Free table allocated by Acpi_tb_get_table */ - - acpi_tb_delete_single_table (&table_info); - return_ACPI_STATUS (status); - } - - -#ifndef PARSER_ONLY - status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); - if (ACPI_FAILURE (status)) { - /* Uninstall table and free the buffer */ - - acpi_tb_delete_acpi_table (ACPI_TABLE_DSDT); - return_ACPI_STATUS (status); - } -#endif - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_load_acpi_table - * - * PARAMETERS: Filname - File where table is located - * - * RETURN: Status - * - * DESCRIPTION: Load an ACPI table from a file - * - ******************************************************************************/ - -acpi_status -acpi_db_load_acpi_table ( - NATIVE_CHAR *filename) -{ -#ifdef ACPI_APPLICATION - FILE *fp; - acpi_status status; - u32 table_length; - - - /* Open the file */ - - fp = fopen (filename, "rb"); - if (!fp) { - acpi_os_printf ("Could not open file %s\n", filename); - return (AE_ERROR); - } - - - /* Get the entire file */ - - acpi_os_printf ("Loading Acpi table from file %s\n", filename); - status = acpi_db_load_table (fp, &acpi_gbl_db_table_ptr, &table_length); - fclose(fp); - - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Couldn't get table from the file\n"); - return (status); - } - - /* Attempt to recognize and install the table */ - - status = ae_local_load_table (acpi_gbl_db_table_ptr); - if (ACPI_FAILURE (status)) { - if (status == AE_EXIST) { - acpi_os_printf ("Table %4.4s is already installed\n", - &acpi_gbl_db_table_ptr->signature); - } - else { - acpi_os_printf ("Could not install table, %s\n", - acpi_format_exception (status)); - } - - acpi_os_free (acpi_gbl_db_table_ptr); - return (status); - } - - acpi_os_printf ("%4.4s at %p successfully installed and loaded\n", - &acpi_gbl_db_table_ptr->signature, acpi_gbl_db_table_ptr); - - acpi_gbl_acpi_hardware_present = FALSE; - -#endif /* ACPI_APPLICATION */ - return (AE_OK); -} - - -#endif /* ENABLE_DEBUGGER */ - diff -urN linux-2.4.21/drivers/acpi/debugger/dbhistry.c linux-2.4.22/drivers/acpi/debugger/dbhistry.c --- linux-2.4.21/drivers/acpi/debugger/dbhistry.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbhistry.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,201 +0,0 @@ -/****************************************************************************** - * - * Module Name: dbhistry - debugger HISTORY command - * $Revision: 19 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acevents.h" -#include "acinterp.h" -#include "acdebug.h" -#include "actables.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbhistry") - - -#define HI_NO_HISTORY 0 -#define HI_RECORD_HISTORY 1 -#define HISTORY_SIZE 20 - - -typedef struct history_info -{ - NATIVE_CHAR command[80]; - u32 cmd_num; - -} HISTORY_INFO; - - -HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE]; -u16 acpi_gbl_lo_history = 0; -u16 acpi_gbl_num_history = 0; -u16 acpi_gbl_next_history_index = 0; -u32 acpi_gbl_next_cmd_num = 1; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_add_to_history - * - * PARAMETERS: Command_line - Command to add - * - * RETURN: None - * - * DESCRIPTION: Add a command line to the history buffer. - * - ******************************************************************************/ - -void -acpi_db_add_to_history ( - NATIVE_CHAR *command_line) -{ - - - /* Put command into the next available slot */ - - STRCPY (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command, command_line); - - acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num = acpi_gbl_next_cmd_num; - - /* Adjust indexes */ - - if ((acpi_gbl_num_history == HISTORY_SIZE) && - (acpi_gbl_next_history_index == acpi_gbl_lo_history)) { - acpi_gbl_lo_history++; - if (acpi_gbl_lo_history >= HISTORY_SIZE) { - acpi_gbl_lo_history = 0; - } - } - - acpi_gbl_next_history_index++; - if (acpi_gbl_next_history_index >= HISTORY_SIZE) { - acpi_gbl_next_history_index = 0; - } - - - acpi_gbl_next_cmd_num++; - if (acpi_gbl_num_history < HISTORY_SIZE) { - acpi_gbl_num_history++; - } - -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_history - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display the contents of the history buffer - * - ******************************************************************************/ - -void -acpi_db_display_history (void) -{ - NATIVE_UINT i; - u16 history_index; - - - history_index = acpi_gbl_lo_history; - - /* Dump entire history buffer */ - - for (i = 0; i < acpi_gbl_num_history; i++) { - acpi_os_printf ("%ld %s\n", acpi_gbl_history_buffer[history_index].cmd_num, - acpi_gbl_history_buffer[history_index].command); - - history_index++; - if (history_index >= HISTORY_SIZE) { - history_index = 0; - } - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_from_history - * - * PARAMETERS: Command_num_arg - String containing the number of the - * command to be retrieved - * - * RETURN: None - * - * DESCRIPTION: Get a command from the history buffer - * - ******************************************************************************/ - -NATIVE_CHAR * -acpi_db_get_from_history ( - NATIVE_CHAR *command_num_arg) -{ - NATIVE_UINT i; - u16 history_index; - u32 cmd_num; - - - if (command_num_arg == NULL) { - cmd_num = acpi_gbl_next_cmd_num - 1; - } - - else { - cmd_num = STRTOUL (command_num_arg, NULL, 0); - } - - - /* Search history buffer */ - - history_index = acpi_gbl_lo_history; - for (i = 0; i < acpi_gbl_num_history; i++) { - if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) { - /* Found the commnad, return it */ - - return (acpi_gbl_history_buffer[history_index].command); - } - - - history_index++; - if (history_index >= HISTORY_SIZE) { - history_index = 0; - } - } - - acpi_os_printf ("Invalid history number: %d\n", history_index); - return (NULL); -} - - -#endif /* ENABLE_DEBUGGER */ - diff -urN linux-2.4.21/drivers/acpi/debugger/dbinput.c linux-2.4.22/drivers/acpi/debugger/dbinput.c --- linux-2.4.21/drivers/acpi/debugger/dbinput.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbinput.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,924 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbinput - user front-end to the AML debugger - * $Revision: 72 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "actables.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbinput") - - -/* - * Globals that are specific to the debugger - */ - -NATIVE_CHAR acpi_gbl_db_line_buf[80]; -NATIVE_CHAR acpi_gbl_db_parsed_buf[80]; -NATIVE_CHAR acpi_gbl_db_scope_buf[40]; -NATIVE_CHAR acpi_gbl_db_debug_filename[40]; -NATIVE_CHAR *acpi_gbl_db_args[DB_MAX_ARGS]; -NATIVE_CHAR *acpi_gbl_db_buffer = NULL; -NATIVE_CHAR *acpi_gbl_db_filename = NULL; -u8 acpi_gbl_db_output_to_file = FALSE; - -u32 acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2; -u32 acpi_gbl_db_console_debug_level = NORMAL_DEFAULT | ACPI_LV_TABLES; -u8 acpi_gbl_db_output_flags = DB_CONSOLE_OUTPUT; - - -u8 acpi_gbl_db_opt_tables = FALSE; -u8 acpi_gbl_db_opt_disasm = FALSE; -u8 acpi_gbl_db_opt_stats = FALSE; -u8 acpi_gbl_db_opt_parse_jit = FALSE; -u8 acpi_gbl_db_opt_verbose = TRUE; -u8 acpi_gbl_db_opt_ini_methods = TRUE; - -/* - * Statistic globals - */ -u16 acpi_gbl_obj_type_count[INTERNAL_TYPE_NODE_MAX+1]; -u16 acpi_gbl_node_type_count[INTERNAL_TYPE_NODE_MAX+1]; -u16 acpi_gbl_obj_type_count_misc; -u16 acpi_gbl_node_type_count_misc; -u32 acpi_gbl_num_nodes; -u32 acpi_gbl_num_objects; - - -u32 acpi_gbl_size_of_parse_tree; -u32 acpi_gbl_size_of_method_trees; -u32 acpi_gbl_size_of_node_entries; -u32 acpi_gbl_size_of_acpi_objects; - -/* - * Top-level debugger commands. - * - * This list of commands must match the string table below it - */ - -enum acpi_ex_debugger_commands -{ - CMD_NOT_FOUND = 0, - CMD_NULL, - CMD_ALLOCATIONS, - CMD_ARGS, - CMD_ARGUMENTS, - CMD_BREAKPOINT, - CMD_CALL, - CMD_CLOSE, - CMD_DEBUG, - CMD_DUMP, - CMD_ENABLEACPI, - CMD_EVENT, - CMD_EXECUTE, - CMD_EXIT, - CMD_FIND, - CMD_GO, - CMD_HELP, - CMD_HELP2, - CMD_HISTORY, - CMD_HISTORY_EXE, - CMD_HISTORY_LAST, - CMD_INFORMATION, - CMD_INTO, - CMD_LEVEL, - CMD_LIST, - CMD_LOAD, - CMD_LOCALS, - CMD_LOCKS, - CMD_METHODS, - CMD_NAMESPACE, - CMD_NOTIFY, - CMD_OBJECT, - CMD_OPEN, - CMD_OWNER, - CMD_PREFIX, - CMD_QUIT, - CMD_REFERENCES, - CMD_RESOURCES, - CMD_RESULTS, - CMD_SET, - CMD_STATS, - CMD_STOP, - CMD_TABLES, - CMD_TERMINATE, - CMD_THREADS, - CMD_TREE, - CMD_UNLOAD -}; - -#define CMD_FIRST_VALID 2 - - -const COMMAND_INFO acpi_gbl_db_commands[] = -{ {"", 0}, - {"", 0}, - {"ALLOCATIONS", 0}, - {"ARGS", 0}, - {"ARGUMENTS", 0}, - {"BREAKPOINT", 1}, - {"CALL", 0}, - {"CLOSE", 0}, - {"DEBUG", 1}, - {"DUMP", 1}, - {"ENABLEACPI", 0}, - {"EVENT", 1}, - {"EXECUTE", 1}, - {"EXIT", 0}, - {"FIND", 1}, - {"GO", 0}, - {"HELP", 0}, - {"?", 0}, - {"HISTORY", 0}, - {"!", 1}, - {"!!", 0}, - {"INFORMATION", 0}, - {"INTO", 0}, - {"LEVEL", 0}, - {"LIST", 0}, - {"LOAD", 1}, - {"LOCALS", 0}, - {"LOCKS", 0}, - {"METHODS", 0}, - {"NAMESPACE", 0}, - {"NOTIFY", 2}, - {"OBJECT", 1}, - {"OPEN", 1}, - {"OWNER", 1}, - {"PREFIX", 0}, - {"QUIT", 0}, - {"REFERENCES", 1}, - {"RESOURCES", 1}, - {"RESULTS", 0}, - {"SET", 3}, - {"STATS", 0}, - {"STOP", 0}, - {"TABLES", 0}, - {"TERMINATE", 0}, - {"THREADS", 3}, - {"TREE", 0}, - {"UNLOAD", 1}, - {NULL, 0} -}; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_help - * - * PARAMETERS: Help_type - Subcommand (optional) - * - * RETURN: None - * - * DESCRIPTION: Print a usage message. - * - ******************************************************************************/ - -void -acpi_db_display_help ( - NATIVE_CHAR *help_type) -{ - - - /* No parameter, just give the overview */ - - if (!help_type) - { - acpi_os_printf ("ACPI CA Debugger Commands\n\n"); - acpi_os_printf ("The following classes of commands are available. Help is available for\n"); - acpi_os_printf ("each class by entering \"Help \"\n\n"); - acpi_os_printf (" [GENERAL] General-Purpose Commands\n"); - acpi_os_printf (" [NAMESPACE] Namespace Access Commands\n"); - acpi_os_printf (" [METHOD] Control Method Execution Commands\n"); - acpi_os_printf (" [FILE] File I/O Commands\n"); - return; - - } - - - /* - * Parameter is the command class - * - * The idea here is to keep each class of commands smaller than a screenful - */ - - switch (help_type[0]) - { - case 'G': - acpi_os_printf ("\n_general-Purpose Commands\n\n"); - acpi_os_printf ("Allocations Display list of current memory allocations\n"); - acpi_os_printf ("Dump
|\n"); - acpi_os_printf (" [Byte|Word|Dword|Qword] Display ACPI objects or memory\n"); - acpi_os_printf ("Enable_acpi Enable ACPI (hardware) mode\n"); - acpi_os_printf ("Help This help screen\n"); - acpi_os_printf ("History Display command history buffer\n"); - acpi_os_printf ("Level [] [console] Get/Set debug level for file or console\n"); - acpi_os_printf ("Locks Current status of internal mutexes\n"); - acpi_os_printf ("Quit or Exit Exit this command\n"); - acpi_os_printf ("Stats [Allocations|Memory|Misc\n"); - acpi_os_printf (" |Objects|Tables] Display namespace and memory statistics\n"); - acpi_os_printf ("Tables Display info about loaded ACPI tables\n"); - acpi_os_printf ("Unload [Instance] Unload an ACPI table\n"); - acpi_os_printf ("! Execute command from history buffer\n"); - acpi_os_printf ("!! Execute last command again\n"); - return; - - case 'N': - acpi_os_printf ("\n_namespace Access Commands\n\n"); - acpi_os_printf ("Debug [Arguments] Single Step a control method\n"); - acpi_os_printf ("Event Generate Acpi_event (Fixed/GPE)\n"); - acpi_os_printf ("Execute [Arguments] Execute control method\n"); - acpi_os_printf ("Find (? is wildcard) Find ACPI name(s) with wildcards\n"); - acpi_os_printf ("Method Display list of loaded control methods\n"); - acpi_os_printf ("Namespace [|] [Depth] Display loaded namespace tree/subtree\n"); - acpi_os_printf ("Notify Send a notification\n"); - acpi_os_printf ("Objects Display all objects of the given type\n"); - acpi_os_printf ("Owner [Depth] Display loaded namespace by object owner\n"); - acpi_os_printf ("Prefix [] Set or Get current execution prefix\n"); - acpi_os_printf ("References Find all references to object at addr\n"); - acpi_os_printf ("Resources xxx Get and display resources\n"); - acpi_os_printf ("Terminate Delete namespace and all internal objects\n"); - acpi_os_printf ("Thread Spawn threads to execute method(s)\n"); - return; - - case 'M': - acpi_os_printf ("\n_control Method Execution Commands\n\n"); - acpi_os_printf ("Arguments (or Args) Display method arguments\n"); - acpi_os_printf ("Breakpoint Set an AML execution breakpoint\n"); - acpi_os_printf ("Call Run to next control method invocation\n"); - acpi_os_printf ("Go Allow method to run to completion\n"); - acpi_os_printf ("Information Display info about the current method\n"); - acpi_os_printf ("Into Step into (not over) a method call\n"); - acpi_os_printf ("List [# of Aml Opcodes] Display method ASL statements\n"); - acpi_os_printf ("Locals Display method local variables\n"); - acpi_os_printf ("Results Display method result stack\n"); - acpi_os_printf ("Set <#> Set method data (Arguments/Locals)\n"); - acpi_os_printf ("Stop Terminate control method\n"); - acpi_os_printf ("Tree Display control method calling tree\n"); - acpi_os_printf (" Single step next AML opcode (over calls)\n"); - return; - - case 'F': - acpi_os_printf ("\n_file I/O Commands\n\n"); - acpi_os_printf ("Close Close debug output file\n"); - acpi_os_printf ("Open Open a file for debug output\n"); - acpi_os_printf ("Load Load ACPI table from a file\n"); - return; - - default: - acpi_os_printf ("Unrecognized Command Class: %x\n", help_type); - return; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_next_token - * - * PARAMETERS: String - Command buffer - * Next - Return value, end of next token - * - * RETURN: Pointer to the start of the next token. - * - * DESCRIPTION: Command line parsing. Get the next token on the command line - * - ******************************************************************************/ - -NATIVE_CHAR * -acpi_db_get_next_token ( - NATIVE_CHAR *string, - NATIVE_CHAR **next) -{ - NATIVE_CHAR *start; - - /* At end of buffer? */ - - if (!string || !(*string)) - { - return (NULL); - } - - - /* Get rid of any spaces at the beginning */ - - if (*string == ' ') - { - while (*string && (*string == ' ')) - { - string++; - } - - if (!(*string)) - { - return (NULL); - } - } - - start = string; - - /* Find end of token */ - - while (*string && (*string != ' ')) - { - string++; - } - - - if (!(*string)) - { - *next = NULL; - } - - else - { - *string = 0; - *next = string + 1; - } - - return (start); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_line - * - * PARAMETERS: Input_buffer - Command line buffer - * - * RETURN: None - * - * DESCRIPTION: Get the next command line from the user. Gets entire line - * up to the next newline - * - ******************************************************************************/ - -u32 -acpi_db_get_line ( - NATIVE_CHAR *input_buffer) -{ - u32 i; - u32 count; - NATIVE_CHAR *next; - NATIVE_CHAR *this; - - - STRCPY (acpi_gbl_db_parsed_buf, input_buffer); - STRUPR (acpi_gbl_db_parsed_buf); - - this = acpi_gbl_db_parsed_buf; - for (i = 0; i < DB_MAX_ARGS; i++) - { - acpi_gbl_db_args[i] = acpi_db_get_next_token (this, &next); - if (!acpi_gbl_db_args[i]) - { - break; - } - - this = next; - } - - - /* Uppercase the actual command */ - - if (acpi_gbl_db_args[0]) - { - STRUPR (acpi_gbl_db_args[0]); - } - - count = i; - if (count) - { - count--; /* Number of args only */ - } - - return (count); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_match_command - * - * PARAMETERS: User_command - User command line - * - * RETURN: Index into command array, -1 if not found - * - * DESCRIPTION: Search command array for a command match - * - ******************************************************************************/ - -u32 -acpi_db_match_command ( - NATIVE_CHAR *user_command) -{ - u32 i; - - - if (!user_command || user_command[0] == 0) - { - return (CMD_NULL); - } - - for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) - { - if (STRSTR (acpi_gbl_db_commands[i].name, user_command) == acpi_gbl_db_commands[i].name) - { - return (i); - } - } - - /* Command not recognized */ - - return (CMD_NOT_FOUND); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_command_dispatch - * - * PARAMETERS: Input_buffer - Command line buffer - * Walk_state - Current walk - * Op - Current (executing) parse op - * - * RETURN: Status - * - * DESCRIPTION: Command dispatcher. Called from two places: - * - ******************************************************************************/ - -acpi_status -acpi_db_command_dispatch ( - NATIVE_CHAR *input_buffer, - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - u32 temp; - u32 command_index; - u32 param_count; - NATIVE_CHAR *command_line; - acpi_status status = AE_CTRL_TRUE; - - - /* If Acpi_terminate has been called, terminate this thread */ - - if (acpi_gbl_db_terminate_threads) - { - return (AE_CTRL_TERMINATE); - } - - param_count = acpi_db_get_line (input_buffer); - command_index = acpi_db_match_command (acpi_gbl_db_args[0]); - temp = 0; - - /* Verify that we have the minimum number of params */ - - if (param_count < acpi_gbl_db_commands[command_index].min_args) - { - acpi_os_printf ("%d parameters entered, [%s] requires %d parameters\n", - param_count, acpi_gbl_db_commands[command_index].name, acpi_gbl_db_commands[command_index].min_args); - return (AE_CTRL_TRUE); - } - - /* Decode and dispatch the command */ - - switch (command_index) - { - case CMD_NULL: - if (op) - { - return (AE_OK); - } - break; - - case CMD_ALLOCATIONS: - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_ut_dump_allocations ((u32) -1, NULL); -#endif - break; - - case CMD_ARGS: - case CMD_ARGUMENTS: - acpi_db_display_arguments (); - break; - - case CMD_BREAKPOINT: - acpi_db_set_method_breakpoint (acpi_gbl_db_args[1], walk_state, op); - break; - - case CMD_CALL: - acpi_db_set_method_call_breakpoint (op); - status = AE_OK; - break; - - case CMD_CLOSE: - acpi_db_close_debug_file (); - break; - - case CMD_DEBUG: - acpi_db_execute (acpi_gbl_db_args[1], &acpi_gbl_db_args[2], EX_SINGLE_STEP); - break; - - case CMD_DUMP: - acpi_db_decode_and_display_object (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_ENABLEACPI: - status = acpi_enable(); - if (ACPI_FAILURE(status)) - { - acpi_os_printf("Acpi_enable failed (Status=%X)\n", status); - return (status); - } - break; - - case CMD_EVENT: - acpi_os_printf ("Event command not implemented\n"); - break; - - case CMD_EXECUTE: - acpi_db_execute (acpi_gbl_db_args[1], &acpi_gbl_db_args[2], EX_NO_SINGLE_STEP); - break; - - case CMD_FIND: - acpi_db_find_name_in_namespace (acpi_gbl_db_args[1]); - break; - - case CMD_GO: - acpi_gbl_cm_single_step = FALSE; - return (AE_OK); - - case CMD_HELP: - case CMD_HELP2: - acpi_db_display_help (acpi_gbl_db_args[1]); - break; - - case CMD_HISTORY: - acpi_db_display_history (); - break; - - case CMD_HISTORY_EXE: - command_line = acpi_db_get_from_history (acpi_gbl_db_args[1]); - if (!command_line) - { - return (AE_CTRL_TRUE); - } - - status = acpi_db_command_dispatch (command_line, walk_state, op); - if (ACPI_SUCCESS (status)) - { - status = AE_CTRL_TRUE; - } - return (status); - break; - - case CMD_HISTORY_LAST: - command_line = acpi_db_get_from_history (NULL); - if (!command_line) - { - return (AE_CTRL_TRUE); - } - - status = acpi_db_command_dispatch (command_line, walk_state, op); - if (ACPI_SUCCESS (status)) - { - status = AE_CTRL_TRUE; - } - return (status); - - case CMD_INFORMATION: - acpi_db_display_method_info (op); - break; - - case CMD_INTO: - if (op) - { - acpi_gbl_cm_single_step = TRUE; - -/* TBD: Must get current walk state */ - /* Acpi_gbl_Method_breakpoint = 0; */ - return (AE_OK); - } - break; - - case CMD_LEVEL: - if (param_count == 0) - { - acpi_os_printf ("Current debug level for file output is: %8.8lX\n", acpi_gbl_db_debug_level); - acpi_os_printf ("Current debug level for console output is: %8.8lX\n", acpi_gbl_db_console_debug_level); - } - else if (param_count == 2) - { - temp = acpi_gbl_db_console_debug_level; - acpi_gbl_db_console_debug_level = STRTOUL (acpi_gbl_db_args[1], NULL, 16); - acpi_os_printf ("Debug Level for console output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_console_debug_level); - } - else - { - temp = acpi_gbl_db_debug_level; - acpi_gbl_db_debug_level = STRTOUL (acpi_gbl_db_args[1], NULL, 16); - acpi_os_printf ("Debug Level for file output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_debug_level); - } - break; - - case CMD_LIST: - acpi_db_disassemble_aml (acpi_gbl_db_args[1], op); - break; - - case CMD_LOAD: - status = acpi_db_load_acpi_table (acpi_gbl_db_args[1]); - if (ACPI_FAILURE (status)) - { - return (status); - } - break; - - case CMD_LOCKS: - acpi_db_display_locks (); - break; - - case CMD_LOCALS: - acpi_db_display_locals (); - break; - - case CMD_METHODS: - acpi_db_display_objects ("METHOD", acpi_gbl_db_args[1]); - break; - - case CMD_NAMESPACE: - acpi_db_dump_namespace (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_NOTIFY: - temp = STRTOUL (acpi_gbl_db_args[2], NULL, 0); - acpi_db_send_notify (acpi_gbl_db_args[1], temp); - break; - - case CMD_OBJECT: - acpi_db_display_objects (STRUPR (acpi_gbl_db_args[1]), acpi_gbl_db_args[2]); - break; - - case CMD_OPEN: - acpi_db_open_debug_file (acpi_gbl_db_args[1]); - break; - - case CMD_OWNER: - acpi_db_dump_namespace_by_owner (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_PREFIX: - acpi_db_set_scope (acpi_gbl_db_args[1]); - break; - - case CMD_REFERENCES: - acpi_db_find_references (acpi_gbl_db_args[1]); - break; - - case CMD_RESOURCES: - acpi_db_display_resources (acpi_gbl_db_args[1]); - break; - - case CMD_RESULTS: - acpi_db_display_results (); - break; - - case CMD_SET: - acpi_db_set_method_data (acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]); - break; - - case CMD_STATS: - acpi_db_display_statistics (acpi_gbl_db_args[1]); - break; - - case CMD_STOP: - return (AE_AML_ERROR); - break; - - case CMD_TABLES: - acpi_db_display_table_info (acpi_gbl_db_args[1]); - break; - - case CMD_TERMINATE: - acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT); - acpi_ut_subsystem_shutdown (); - - /* TBD: [Restructure] Need some way to re-initialize without re-creating the semaphores! */ - - /* Acpi_initialize (NULL); */ - break; - - case CMD_THREADS: - acpi_db_create_execution_threads (acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]); - break; - - case CMD_TREE: - acpi_db_display_calling_tree (); - break; - - case CMD_UNLOAD: - acpi_db_unload_acpi_table (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_EXIT: - case CMD_QUIT: - if (op) - { - acpi_os_printf ("Method execution terminated\n"); - return (AE_CTRL_TERMINATE); - } - - if (!acpi_gbl_db_output_to_file) - { - acpi_dbg_level = DEBUG_DEFAULT; - } - - /* Shutdown */ - - /* Acpi_ut_subsystem_shutdown (); */ - acpi_db_close_debug_file (); - - acpi_gbl_db_terminate_threads = TRUE; - - return (AE_CTRL_TERMINATE); - - case CMD_NOT_FOUND: - acpi_os_printf ("Unknown Command\n"); - return (AE_CTRL_TRUE); - } - - - /* Add all commands that come here to the history buffer */ - - acpi_db_add_to_history (input_buffer); - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute_thread - * - * PARAMETERS: Context - Not used - * - * RETURN: None - * - * DESCRIPTION: Debugger execute thread. Waits for a command line, then - * simply dispatches it. - * - ******************************************************************************/ - -void -acpi_db_execute_thread ( - void *context) -{ - acpi_status status = AE_OK; - - - while (status != AE_CTRL_TERMINATE) - { - acpi_gbl_method_executing = FALSE; - acpi_gbl_step_to_next_call = FALSE; - - acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY); - status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, NULL, NULL); - acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_single_thread - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Debugger execute thread. Waits for a command line, then - * simply dispatches it. - * - ******************************************************************************/ - -void -acpi_db_single_thread ( - void) -{ - acpi_status status = AE_OK; - - - acpi_gbl_method_executing = FALSE; - acpi_gbl_step_to_next_call = FALSE; - - status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, NULL, NULL); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_user_commands - * - * PARAMETERS: Prompt - User prompt (depends on mode) - * Op - Current executing parse op - * - * RETURN: None - * - * DESCRIPTION: Command line execution for the AML debugger. Commands are - * matched and dispatched here. - * - ******************************************************************************/ - -acpi_status -acpi_db_user_commands ( - NATIVE_CHAR prompt, - acpi_parse_object *op) -{ - acpi_status status = AE_OK; - - - /* TBD: [Restructure] Need a separate command line buffer for step mode */ - - while (!acpi_gbl_db_terminate_threads) - { - /* Force output to console until a command is entered */ - - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); - - /* Different prompt if method is executing */ - - if (!acpi_gbl_method_executing) - { - acpi_os_printf ("%1c ", DB_COMMAND_PROMPT); - } - else - { - acpi_os_printf ("%1c ", DB_EXECUTE_PROMPT); - } - - /* Get the user input line */ - - acpi_os_get_line (acpi_gbl_db_line_buf); - - - /* Check for single or multithreaded debug */ - - if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) - { - /* - * Signal the debug thread that we have a command to execute, - * and wait for the command to complete. - */ - acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_READY); - acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - } - - else - { - /* Just call to the command line interpreter */ - - acpi_db_single_thread (); - } - } - - - /* - * Only this thread (the original thread) should actually terminate the subsystem, - * because all the semaphores are deleted during termination - */ - acpi_terminate (); - return (status); -} - - -#endif /* ENABLE_DEBUGGER */ - diff -urN linux-2.4.21/drivers/acpi/debugger/dbstats.c linux-2.4.22/drivers/acpi/debugger/dbstats.c --- linux-2.4.21/drivers/acpi/debugger/dbstats.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbstats.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,456 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbstats - Generation and display of ACPI table statistics - * $Revision: 47 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbstats") - -/* - * Statistics subcommands - */ -ARGUMENT_INFO acpi_db_stat_types [] = -{ {"ALLOCATIONS"}, - {"OBJECTS"}, - {"MEMORY"}, - {"MISC"}, - {"TABLES"}, - {"SIZES"}, - {"STACK"}, - {NULL} /* Must be null terminated */ -}; - -#define CMD_ALLOCATIONS 0 -#define CMD_OBJECTS 1 -#define CMD_MEMORY 2 -#define CMD_MISC 3 -#define CMD_TABLES 4 -#define CMD_SIZES 5 -#define CMD_STACK 6 - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_enumerate_object - * - * PARAMETERS: Obj_desc - Object to be counted - * - * RETURN: None - * - * DESCRIPTION: Add this object to the global counts, by object type. - * Recursively handles subobjects and packages. - * - * [TBD] Restructure - remove recursion. - * - ******************************************************************************/ - -void -acpi_db_enumerate_object ( - acpi_operand_object *obj_desc) -{ - u32 type; - u32 i; - - - if (!obj_desc) - { - return; - } - - - /* Enumerate this object first */ - - acpi_gbl_num_objects++; - - type = obj_desc->common.type; - if (type > INTERNAL_TYPE_NODE_MAX) - { - acpi_gbl_obj_type_count_misc++; - } - else - { - acpi_gbl_obj_type_count [type]++; - } - - /* Count the sub-objects */ - - switch (type) - { - case ACPI_TYPE_PACKAGE: - for (i = 0; i< obj_desc->package.count; i++) - { - acpi_db_enumerate_object (obj_desc->package.elements[i]); - } - break; - - case ACPI_TYPE_DEVICE: - acpi_db_enumerate_object (obj_desc->device.sys_handler); - acpi_db_enumerate_object (obj_desc->device.drv_handler); - acpi_db_enumerate_object (obj_desc->device.addr_handler); - break; - - case ACPI_TYPE_REGION: - acpi_db_enumerate_object (obj_desc->region.addr_handler); - break; - - case ACPI_TYPE_POWER: - acpi_db_enumerate_object (obj_desc->power_resource.sys_handler); - acpi_db_enumerate_object (obj_desc->power_resource.drv_handler); - break; - - case ACPI_TYPE_PROCESSOR: - acpi_db_enumerate_object (obj_desc->processor.sys_handler); - acpi_db_enumerate_object (obj_desc->processor.drv_handler); - acpi_db_enumerate_object (obj_desc->processor.addr_handler); - break; - - case ACPI_TYPE_THERMAL: - acpi_db_enumerate_object (obj_desc->thermal_zone.sys_handler); - acpi_db_enumerate_object (obj_desc->thermal_zone.drv_handler); - acpi_db_enumerate_object (obj_desc->thermal_zone.addr_handler); - break; - } -} - - -#ifndef PARSER_ONLY - -/******************************************************************************* - * - * FUNCTION: Acpi_db_classify_one_object - * - * PARAMETERS: Callback for Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and - * the parent namespace node. - * - ******************************************************************************/ - -acpi_status -acpi_db_classify_one_object ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_namespace_node *node; - acpi_operand_object *obj_desc; - u32 type; - - - acpi_gbl_num_nodes++; - - node = (acpi_namespace_node *) obj_handle; - obj_desc = ((acpi_namespace_node *) obj_handle)->object; - - acpi_db_enumerate_object (obj_desc); - - type = node->type; - if (type > INTERNAL_TYPE_NODE_MAX) - { - acpi_gbl_node_type_count_misc++; - } - - else - { - acpi_gbl_node_type_count [type]++; - } - - return AE_OK; - - - /* TBD: These need to be counted during the initial parsing phase */ - /* - if (Acpi_ps_is_named_op (Op->Opcode)) - { - Num_nodes++; - } - - if (Is_method) - { - Num_method_elements++; - } - - Num_grammar_elements++; - Op = Acpi_ps_get_depth_next (Root, Op); - - Size_of_parse_tree = (Num_grammar_elements - Num_method_elements) * (u32) sizeof (acpi_parse_object); - Size_of_method_trees = Num_method_elements * (u32) sizeof (acpi_parse_object); - Size_of_node_entries = Num_nodes * (u32) sizeof (acpi_namespace_node); - Size_of_acpi_objects = Num_nodes * (u32) sizeof (acpi_operand_object); - - */ -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_count_namespace_objects - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Count and classify the entire namespace, including all - * namespace nodes and attached objects. - * - ******************************************************************************/ - -acpi_status -acpi_db_count_namespace_objects ( - void) -{ - u32 i; - - - acpi_gbl_num_nodes = 0; - acpi_gbl_num_objects = 0; - - acpi_gbl_obj_type_count_misc = 0; - for (i = 0; i < (INTERNAL_TYPE_NODE_MAX -1); i++) - { - acpi_gbl_obj_type_count [i] = 0; - acpi_gbl_node_type_count [i] = 0; - } - - acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - FALSE, acpi_db_classify_one_object, NULL, NULL); - - return (AE_OK); -} - -#endif - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_statistics - * - * PARAMETERS: Type_arg - Subcommand - * - * RETURN: Status - * - * DESCRIPTION: Display various statistics - * - ******************************************************************************/ - -acpi_status -acpi_db_display_statistics ( - NATIVE_CHAR *type_arg) -{ - u32 i; - u32 type; - u32 outstanding; - u32 size; - - - if (!acpi_gbl_DSDT) - { - acpi_os_printf ("*** Warning: There is no DSDT loaded\n"); - } - - if (!type_arg) - { - acpi_os_printf ("The following subcommands are available:\n ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n"); - return (AE_OK); - } - - STRUPR (type_arg); - type = acpi_db_match_argument (type_arg, acpi_db_stat_types); - if (type == (u32) -1) - { - acpi_os_printf ("Invalid or unsupported argument\n"); - return (AE_OK); - } - - - switch (type) - { -#ifndef PARSER_ONLY - case CMD_ALLOCATIONS: -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_ut_dump_allocation_info (); -#endif - break; -#endif - - case CMD_TABLES: - - acpi_os_printf ("ACPI Table Information:\n\n"); - if (acpi_gbl_DSDT) - { - acpi_os_printf ("DSDT Length:................% 7ld (%X)\n", acpi_gbl_DSDT->length, acpi_gbl_DSDT->length); - } - break; - - case CMD_OBJECTS: - -#ifndef PARSER_ONLY - - acpi_db_count_namespace_objects (); - - acpi_os_printf ("\n_objects defined in the current namespace:\n\n"); - - acpi_os_printf ("%16.16s % 10.10s % 10.10s\n", "ACPI_TYPE", "NODES", "OBJECTS"); - - for (i = 0; i < INTERNAL_TYPE_NODE_MAX; i++) - { - acpi_os_printf ("%16.16s % 10ld% 10ld\n", acpi_ut_get_type_name (i), - acpi_gbl_node_type_count [i], acpi_gbl_obj_type_count [i]); - } - acpi_os_printf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown", - acpi_gbl_node_type_count_misc, acpi_gbl_obj_type_count_misc); - - acpi_os_printf ("%16.16s % 10ld% 10ld\n", "TOTALS:", - acpi_gbl_num_nodes, acpi_gbl_num_objects); - -#endif - break; - - case CMD_MEMORY: - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_os_printf ("\n----Object and Cache Statistics---------------------------------------------\n"); - - for (i = 0; i < ACPI_NUM_MEM_LISTS; i++) - { - acpi_os_printf ("\n%s\n", acpi_gbl_memory_lists[i].list_name); - - if (acpi_gbl_memory_lists[i].max_cache_depth > 0) - { - acpi_os_printf (" Cache: [Depth Max Avail Size] % 7d % 7d % 7d % 7d B\n", - acpi_gbl_memory_lists[i].cache_depth, - acpi_gbl_memory_lists[i].max_cache_depth, - acpi_gbl_memory_lists[i].max_cache_depth - acpi_gbl_memory_lists[i].cache_depth, - (acpi_gbl_memory_lists[i].cache_depth * acpi_gbl_memory_lists[i].object_size)); - - acpi_os_printf (" Cache: [Requests Hits Misses Obj_size] % 7d % 7d % 7d % 7d B\n", - acpi_gbl_memory_lists[i].cache_requests, - acpi_gbl_memory_lists[i].cache_hits, - acpi_gbl_memory_lists[i].cache_requests - acpi_gbl_memory_lists[i].cache_hits, - acpi_gbl_memory_lists[i].object_size); - } - - outstanding = acpi_gbl_memory_lists[i].total_allocated - - acpi_gbl_memory_lists[i].total_freed - - acpi_gbl_memory_lists[i].cache_depth; - - if (acpi_gbl_memory_lists[i].object_size) - { - size = ROUND_UP_TO_1K (outstanding * acpi_gbl_memory_lists[i].object_size); - } - else - { - size = ROUND_UP_TO_1K (acpi_gbl_memory_lists[i].current_total_size); - } - - acpi_os_printf (" Mem: [Alloc Free Outstanding Size] % 7d % 7d % 7d % 7d Kb\n", - acpi_gbl_memory_lists[i].total_allocated, - acpi_gbl_memory_lists[i].total_freed, - outstanding, size); - } -#endif - - break; - - case CMD_MISC: - - acpi_os_printf ("\n_miscellaneous Statistics:\n\n"); - acpi_os_printf ("Calls to Acpi_ps_find:.. ........% 7ld\n", acpi_gbl_ps_find_count); - acpi_os_printf ("Calls to Acpi_ns_lookup:..........% 7ld\n", acpi_gbl_ns_lookup_count); - - acpi_os_printf ("\n"); - - acpi_os_printf ("Mutex usage:\n\n"); - for (i = 0; i < NUM_MTX; i++) - { - acpi_os_printf ("%-28s: % 7ld\n", acpi_ut_get_mutex_name (i), acpi_gbl_acpi_mutex_info[i].use_count); - } - break; - - - case CMD_SIZES: - - acpi_os_printf ("\n_internal object sizes:\n\n"); - - acpi_os_printf ("Common %3d\n", sizeof (ACPI_OBJECT_COMMON)); - acpi_os_printf ("Number %3d\n", sizeof (ACPI_OBJECT_INTEGER)); - acpi_os_printf ("String %3d\n", sizeof (ACPI_OBJECT_STRING)); - acpi_os_printf ("Buffer %3d\n", sizeof (ACPI_OBJECT_BUFFER)); - acpi_os_printf ("Package %3d\n", sizeof (ACPI_OBJECT_PACKAGE)); - acpi_os_printf ("Buffer_field %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD)); - acpi_os_printf ("Device %3d\n", sizeof (ACPI_OBJECT_DEVICE)); - acpi_os_printf ("Event %3d\n", sizeof (ACPI_OBJECT_EVENT)); - acpi_os_printf ("Method %3d\n", sizeof (ACPI_OBJECT_METHOD)); - acpi_os_printf ("Mutex %3d\n", sizeof (ACPI_OBJECT_MUTEX)); - acpi_os_printf ("Region %3d\n", sizeof (ACPI_OBJECT_REGION)); - acpi_os_printf ("Power_resource %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE)); - acpi_os_printf ("Processor %3d\n", sizeof (ACPI_OBJECT_PROCESSOR)); - acpi_os_printf ("Thermal_zone %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE)); - acpi_os_printf ("Region_field %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD)); - acpi_os_printf ("Bank_field %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD)); - acpi_os_printf ("Index_field %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD)); - acpi_os_printf ("Reference %3d\n", sizeof (ACPI_OBJECT_REFERENCE)); - acpi_os_printf ("Notify_handler %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER)); - acpi_os_printf ("Addr_handler %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER)); - acpi_os_printf ("Extra %3d\n", sizeof (ACPI_OBJECT_EXTRA)); - - acpi_os_printf ("\n"); - - acpi_os_printf ("Parse_object %3d\n", sizeof (acpi_parse_object)); - acpi_os_printf ("Parse2_object %3d\n", sizeof (acpi_parse2_object)); - acpi_os_printf ("Operand_object %3d\n", sizeof (acpi_operand_object)); - acpi_os_printf ("Namespace_node %3d\n", sizeof (acpi_namespace_node)); - - break; - - - case CMD_STACK: - - size = acpi_gbl_entry_stack_pointer - acpi_gbl_lowest_stack_pointer; - - acpi_os_printf ("\n_subsystem Stack Usage:\n\n"); - acpi_os_printf ("Entry Stack Pointer %X\n", acpi_gbl_entry_stack_pointer); - acpi_os_printf ("Lowest Stack Pointer %X\n", acpi_gbl_lowest_stack_pointer); - acpi_os_printf ("Stack Use %X (%d)\n", size, size); - acpi_os_printf ("Deepest Procedure Nesting %d\n", acpi_gbl_deepest_nesting); - break; - } - - acpi_os_printf ("\n"); - return (AE_OK); -} - - -#endif /* ENABLE_DEBUGGER */ diff -urN linux-2.4.21/drivers/acpi/debugger/dbutils.c linux-2.4.22/drivers/acpi/debugger/dbutils.c --- linux-2.4.21/drivers/acpi/debugger/dbutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbutils.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,384 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbutils - AML debugger utilities - * $Revision: 45 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acevents.h" -#include "acinterp.h" -#include "acdebug.h" -#include "acdispat.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbutils") - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_output_destination - * - * PARAMETERS: Output_flags - Current flags word - * - * RETURN: None - * - * DESCRIPTION: Set the current destination for debugger output. Alos sets - * the debug output level accordingly. - * - ******************************************************************************/ - -void -acpi_db_set_output_destination ( - u32 output_flags) -{ - - acpi_gbl_db_output_flags = (u8) output_flags; - - if (output_flags & DB_REDIRECTABLE_OUTPUT) { - if (acpi_gbl_db_output_to_file) { - acpi_dbg_level = acpi_gbl_db_debug_level; - } - } - else { - acpi_dbg_level = acpi_gbl_db_console_debug_level; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_buffer - * - * PARAMETERS: Address - Pointer to the buffer - * - * RETURN: None - * - * DESCRIPTION: Print a portion of a buffer - * - ******************************************************************************/ - -void -acpi_db_dump_buffer ( - u32 address) -{ - - acpi_os_printf ("\n_location %X:\n", address); - - acpi_dbg_level |= ACPI_LV_TABLES; - acpi_ut_dump_buffer ((u8 *) address, 64, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_object - * - * PARAMETERS: Obj_desc - External ACPI object to dump - * Level - Nesting level. - * - * RETURN: None - * - * DESCRIPTION: Dump the contents of an ACPI external object - * - ******************************************************************************/ - -void -acpi_db_dump_object ( - acpi_object *obj_desc, - u32 level) -{ - u32 i; - - - if (!obj_desc) { - acpi_os_printf ("[Null Object]\n"); - return; - } - - for (i = 0; i < level; i++) { - acpi_os_printf (" "); - } - - switch (obj_desc->type) { - case ACPI_TYPE_ANY: - - acpi_os_printf ("[Object Reference] = %p\n", obj_desc->reference.handle); - break; - - - case ACPI_TYPE_INTEGER: - - acpi_os_printf ("[Integer] = %8.8X%8.8X\n", HIDWORD (obj_desc->integer.value), - LODWORD (obj_desc->integer.value)); - break; - - - case ACPI_TYPE_STRING: - - acpi_os_printf ("[String] Value: "); - for (i = 0; i < obj_desc->string.length; i++) { - acpi_os_printf ("%c", obj_desc->string.pointer[i]); - } - acpi_os_printf ("\n"); - break; - - - case ACPI_TYPE_BUFFER: - - acpi_os_printf ("[Buffer] = "); - acpi_ut_dump_buffer ((u8 *) obj_desc->buffer.pointer, obj_desc->buffer.length, DB_DWORD_DISPLAY, _COMPONENT); - break; - - - case ACPI_TYPE_PACKAGE: - - acpi_os_printf ("[Package] Contains %d Elements: \n", obj_desc->package.count); - - for (i = 0; i < obj_desc->package.count; i++) { - acpi_db_dump_object (&obj_desc->package.elements[i], level+1); - } - break; - - - case INTERNAL_TYPE_REFERENCE: - - acpi_os_printf ("[Object Reference] = %p\n", obj_desc->reference.handle); - break; - - - case ACPI_TYPE_PROCESSOR: - - acpi_os_printf ("[Processor]\n"); - break; - - - case ACPI_TYPE_POWER: - - acpi_os_printf ("[Power Resource]\n"); - break; - - - default: - - acpi_os_printf ("[Unknown Type] %X \n", obj_desc->type); - break; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_prep_namestring - * - * PARAMETERS: Name - String to prepare - * - * RETURN: None - * - * DESCRIPTION: Translate all forward slashes and dots to backslashes. - * - ******************************************************************************/ - -void -acpi_db_prep_namestring ( - NATIVE_CHAR *name) -{ - - - if (!name) { - return; - } - - STRUPR (name); - - /* Convert a leading forward slash to a backslash */ - - if (*name == '/') { - *name = '\\'; - } - - /* Ignore a leading backslash, this is the root prefix */ - - if (*name == '\\') { - name++; - } - - /* Convert all slash path separators to dots */ - - while (*name) { - if ((*name == '/') || - (*name == '\\')) { - *name = '.'; - } - - name++; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_second_pass_parse - * - * PARAMETERS: Root - Root of the parse tree - * - * RETURN: Status - * - * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until - * second pass to parse the control methods - * - ******************************************************************************/ - -acpi_status -acpi_db_second_pass_parse ( - acpi_parse_object *root) -{ - acpi_parse_object *op = root; - acpi_parse2_object *method; - acpi_parse_object *search_op; - acpi_parse_object *start_op; - acpi_status status = AE_OK; - u32 base_aml_offset; - acpi_walk_state *walk_state; - - - FUNCTION_ENTRY (); - - - acpi_os_printf ("Pass two parse ....\n"); - - - while (op) { - if (op->opcode == AML_METHOD_OP) { - method = (acpi_parse2_object *) op; - - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - NULL, NULL, NULL); - if (!walk_state) { - return (AE_NO_MEMORY); - } - - - walk_state->parser_state.aml = - walk_state->parser_state.aml_start = method->data; - walk_state->parser_state.aml_end = - walk_state->parser_state.pkg_end = method->data + method->length; - walk_state->parser_state.start_scope = op; - - walk_state->descending_callback = acpi_ds_load1_begin_op; - walk_state->ascending_callback = acpi_ds_load1_end_op; - - - status = acpi_ps_parse_aml (walk_state); - - - base_aml_offset = (method->value.arg)->aml_offset + 1; - start_op = (method->value.arg)->next; - search_op = start_op; - - while (search_op) { - search_op->aml_offset += base_aml_offset; - search_op = acpi_ps_get_depth_next (start_op, search_op); - } - - } - - if (op->opcode == AML_REGION_OP) { - /* TBD: [Investigate] this isn't quite the right thing to do! */ - /* - * - * Method = (ACPI_DEFERRED_OP *) Op; - * Status = Acpi_ps_parse_aml (Op, Method->Body, Method->Body_length); - */ - } - - if (ACPI_FAILURE (status)) { - break; - } - - op = acpi_ps_get_depth_next (root, op); - } - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_local_ns_lookup - * - * PARAMETERS: Name - Name to lookup - * - * RETURN: Pointer to a namespace node - * - * DESCRIPTION: Lookup a name in the ACPI namespace - * - ******************************************************************************/ - -acpi_namespace_node * -acpi_db_local_ns_lookup ( - NATIVE_CHAR *name) -{ - NATIVE_CHAR *internal_path; - acpi_status status; - acpi_namespace_node *node = NULL; - - - acpi_db_prep_namestring (name); - - /* Build an internal namestring */ - - status = acpi_ns_internalize_name (name, &internal_path); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Invalid namestring: %s\n", name); - return (NULL); - } - - /* Lookup the name */ - - /* TBD: [Investigate] what scope do we use? */ - /* Use the root scope for the start of the search */ - - status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, - NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, NULL, &node); - - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not locate name: %s %s\n", name, acpi_format_exception (status)); - } - - - ACPI_MEM_FREE (internal_path); - - return (node); -} - - -#endif /* ENABLE_DEBUGGER */ - - diff -urN linux-2.4.21/drivers/acpi/debugger/dbxface.c linux-2.4.22/drivers/acpi/debugger/dbxface.c --- linux-2.4.21/drivers/acpi/debugger/dbxface.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/debugger/dbxface.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,321 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbxface - AML Debugger external interfaces - * $Revision: 45 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acevents.h" -#include "acinterp.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - MODULE_NAME ("dbxface") - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_single_step - * - * PARAMETERS: Walk_state - Current walk - * Op - Current executing op - * Opcode_class - Class of the current AML Opcode - * - * RETURN: Status - * - * DESCRIPTION: Called just before execution of an AML opcode. - * - ******************************************************************************/ - -acpi_status -acpi_db_single_step ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - u32 opcode_class) -{ - acpi_parse_object *next; - acpi_status status = AE_OK; - u32 original_debug_level; - acpi_parse_object *display_op; - - - FUNCTION_ENTRY (); - - /* Is there a breakpoint set? */ - - if (walk_state->method_breakpoint) { - /* Check if the breakpoint has been reached or passed */ - - if (walk_state->method_breakpoint <= op->aml_offset) { - /* Hit the breakpoint, resume single step, reset breakpoint */ - - acpi_os_printf ("***Break*** at AML offset %X\n", op->aml_offset); - acpi_gbl_cm_single_step = TRUE; - acpi_gbl_step_to_next_call = FALSE; - walk_state->method_breakpoint = 0; - } - } - - /* - * Check if this is an opcode that we are interested in -- - * namely, opcodes that have arguments - */ - if (op->opcode == AML_INT_NAMEDFIELD_OP) { - return (AE_OK); - } - - switch (opcode_class) { - case AML_CLASS_UNKNOWN: - case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */ - return (AE_OK); - break; - } - - /* - * Under certain debug conditions, display this opcode and its operands - */ - if ((acpi_gbl_db_output_to_file) || - (acpi_gbl_cm_single_step) || - (acpi_dbg_level & ACPI_LV_PARSE)) { - if ((acpi_gbl_db_output_to_file) || - (acpi_dbg_level & ACPI_LV_PARSE)) { - acpi_os_printf ("\n[Aml_debug] Next AML Opcode to execute:\n"); - } - - /* - * Display this op (and only this op - zero out the NEXT field temporarily, - * and disable parser trace output for the duration of the display because - * we don't want the extraneous debug output) - */ - original_debug_level = acpi_dbg_level; - acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS); - next = op->next; - op->next = NULL; - - - display_op = op; - if (op->parent) { - if ((op->parent->opcode == AML_IF_OP) || - (op->parent->opcode == AML_WHILE_OP)) { - display_op = op->parent; - } - } - - /* Now we can display it */ - - acpi_db_display_op (walk_state, display_op, ACPI_UINT32_MAX); - - if ((op->opcode == AML_IF_OP) || - (op->opcode == AML_WHILE_OP)) { - if (walk_state->control_state->common.value) { - acpi_os_printf ("Predicate was TRUE, executed block\n"); - } - else { - acpi_os_printf ("Predicate is FALSE, skipping block\n"); - } - } - - else if (op->opcode == AML_ELSE_OP) { - /* TBD */ - } - - /* Restore everything */ - - op->next = next; - acpi_os_printf ("\n"); - acpi_dbg_level = original_debug_level; - } - - /* If we are not single stepping, just continue executing the method */ - - if (!acpi_gbl_cm_single_step) { - return (AE_OK); - } - - - /* - * If we are executing a step-to-call command, - * Check if this is a method call. - */ - if (acpi_gbl_step_to_next_call) { - if (op->opcode != AML_INT_METHODCALL_OP) { - /* Not a method call, just keep executing */ - - return (AE_OK); - } - - /* Found a method call, stop executing */ - - acpi_gbl_step_to_next_call = FALSE; - } - - - /* - * If the next opcode is a method call, we will "step over" it - * by default. - */ - if (op->opcode == AML_INT_METHODCALL_OP) { - acpi_gbl_cm_single_step = FALSE; /* No more single step while executing called method */ - - /* Set the breakpoint on the call, it will stop execution as soon as we return */ - - /* TBD: [Future] don't kill the user breakpoint! */ - - walk_state->method_breakpoint = /* Op->Aml_offset + */ 1; /* Must be non-zero! */ - } - - - /* TBD: [Investigate] what are the namespace locking issues here */ - - /* Acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */ - - /* Go into the command loop and await next user command */ - - acpi_gbl_method_executing = TRUE; - status = AE_CTRL_TRUE; - while (status == AE_CTRL_TRUE) { - if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) { - /* Handshake with the front-end that gets user command lines */ - - acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY); - } - - else { - /* Single threaded, we must get a command line ourselves */ - - /* Force output to console until a command is entered */ - - acpi_db_set_output_destination (DB_CONSOLE_OUTPUT); - - /* Different prompt if method is executing */ - - if (!acpi_gbl_method_executing) { - acpi_os_printf ("%1c ", DB_COMMAND_PROMPT); - } - else { - acpi_os_printf ("%1c ", DB_EXECUTE_PROMPT); - } - - /* Get the user input line */ - - acpi_os_get_line (acpi_gbl_db_line_buf); - } - - status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, walk_state, op); - } - - /* Acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */ - - /* User commands complete, continue execution of the interrupted method */ - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_initialize - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Init and start debugger - * - ******************************************************************************/ - -int -acpi_db_initialize (void) -{ - - - /* Init globals */ - - acpi_gbl_db_buffer = acpi_os_callocate (ACPI_DEBUG_BUFFER_SIZE); - - /* Initial scope is the root */ - - acpi_gbl_db_scope_buf [0] = '\\'; - acpi_gbl_db_scope_buf [1] = 0; - - - /* - * If configured for multi-thread support, the debug executor runs in - * a separate thread so that the front end can be in another address - * space, environment, or even another machine. - */ - if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) { - /* These were created with one unit, grab it */ - - acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY); - - /* Create the debug execution thread to execute commands */ - - acpi_os_queue_for_execution (0, acpi_db_execute_thread, NULL); - } - - if (!acpi_gbl_db_opt_verbose) { - acpi_gbl_db_disasm_indent = " "; - acpi_gbl_db_opt_disasm = TRUE; - acpi_gbl_db_opt_stats = FALSE; - } - - return (0); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_terminate - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Stop debugger - * - ******************************************************************************/ - -void -acpi_db_terminate (void) -{ - - if (acpi_gbl_db_table_ptr) { - acpi_os_free (acpi_gbl_db_table_ptr); - } - if (acpi_gbl_db_buffer) { - acpi_os_free (acpi_gbl_db_buffer); - } -} - - -#endif /* ENABLE_DEBUGGER */ diff -urN linux-2.4.21/drivers/acpi/dispatcher/Makefile linux-2.4.22/drivers/acpi/dispatcher/Makefile --- linux-2.4.21/drivers/acpi/dispatcher/Makefile 2001-06-20 17:47:39.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsfield.c linux-2.4.22/drivers/acpi/dispatcher/dsfield.c --- linux-2.4.21/drivers/acpi/dispatcher/dsfield.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/dispatcher/dsfield.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,78 +1,98 @@ /****************************************************************************** * * Module Name: dsfield - Dispatcher field routines - * $Revision: 46 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acparser.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dsfield") + ACPI_MODULE_NAME ("dsfield") /******************************************************************************* * - * FUNCTION: Acpi_ds_create_buffer_field + * FUNCTION: acpi_ds_create_buffer_field * * PARAMETERS: Opcode - The opcode to be executed * Operands - List of operands for the opcode - * Walk_state - Current state + * walk_state - Current state * * RETURN: Status * - * DESCRIPTION: Execute the Create_field operators: - * Create_bit_field_op, - * Create_byte_field_op, - * Create_word_field_op, - * Create_dWord_field_op, - * Create_qWord_field_op, - * Create_field_op (all of which define fields in buffers) + * DESCRIPTION: Execute the create_field operators: + * create_bit_field_op, + * create_byte_field_op, + * create_word_field_op, + * create_dword_field_op, + * create_qword_field_op, + * create_field_op (all of which define fields in buffers) * ******************************************************************************/ acpi_status acpi_ds_create_buffer_field ( - acpi_parse_object *op, - acpi_walk_state *walk_state) + union acpi_parse_object *op, + struct acpi_walk_state *walk_state) { - acpi_parse_object *arg; - acpi_namespace_node *node; - acpi_status status; - acpi_operand_object *obj_desc; + union acpi_parse_object *arg; + struct acpi_namespace_node *node; + acpi_status status; + union acpi_operand_object *obj_desc; + union acpi_operand_object *second_desc = NULL; + u32 flags; - FUNCTION_TRACE ("Ds_create_buffer_field"); + ACPI_FUNCTION_TRACE ("ds_create_buffer_field"); - /* Get the Name_string argument */ + /* Get the name_string argument */ - if (op->opcode == AML_CREATE_FIELD_OP) { + if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { arg = acpi_ps_get_arg (op, 3); } else { @@ -86,13 +106,25 @@ } /* - * Enter the Name_string into the namespace + * During the load phase, we want to enter the name of the field into + * the namespace. During the execute phase (when we evaluate the size + * operand), we want to lookup the name */ - status = acpi_ns_lookup (walk_state->scope_info, arg->value.string, - INTERNAL_TYPE_DEF_ANY, IMODE_LOAD_PASS1, - NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, - walk_state, &(node)); + if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) { + flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; + } + else { + flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; + } + + /* + * Enter the name_string into the namespace + */ + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string, + ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, + flags, walk_state, &(node)); if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (arg->common.value.string, status); return_ACPI_STATUS (status); } @@ -100,14 +132,15 @@ * for now, we will put it in the "op" object that the parser uses, so we * can get it again at the end of this scope */ - op->node = node; + op->common.node = node; /* * If there is no object attached to the node, this node was just created and * we need to create the field object. Otherwise, this was a lookup of an * existing node and we don't want to create the field object again. */ - if (node->object) { + obj_desc = acpi_ns_get_attached_object (node); + if (obj_desc) { return_ACPI_STATUS (AE_OK); } @@ -125,27 +158,21 @@ } /* - * Allocate a method object for this field unit - */ - obj_desc->buffer_field.extra = acpi_ut_create_internal_object ( - INTERNAL_TYPE_EXTRA); - if (!obj_desc->buffer_field.extra) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* * Remember location in AML stream of the field unit * opcode and operands -- since the buffer and index * operands must be evaluated. */ - obj_desc->buffer_field.extra->extra.aml_start = ((acpi_parse2_object *) op)->data; - obj_desc->buffer_field.extra->extra.aml_length = ((acpi_parse2_object *) op)->length; + second_desc = obj_desc->common.next_object; + second_desc->extra.aml_start = op->named.data; + second_desc->extra.aml_length = op->named.length; obj_desc->buffer_field.node = node; - /* Attach constructed field descriptor to parent node */ + /* Attach constructed field descriptors to parent node */ status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_BUFFER_FIELD); + if (ACPI_FAILURE (status)) { + goto cleanup; + } cleanup: @@ -159,10 +186,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_get_field_names + * FUNCTION: acpi_ds_get_field_names * - * PARAMETERS: Info - Create_field info structure - * ` Walk_state - Current method state + * PARAMETERS: Info - create_field info structure + * ` walk_state - Current method state * Arg - First parser arg for the field name list * * RETURN: Status @@ -174,14 +201,15 @@ acpi_status acpi_ds_get_field_names ( - ACPI_CREATE_FIELD_INFO *info, - acpi_walk_state *walk_state, - acpi_parse_object *arg) + struct acpi_create_field_info *info, + struct acpi_walk_state *walk_state, + union acpi_parse_object *arg) { - acpi_status status; + acpi_status status; + acpi_integer position; - PROC_NAME("acpi_ds_get_field_names"); + ACPI_FUNCTION_TRACE_PTR ("ds_get_field_names", info); /* First field starts at bit zero */ @@ -194,51 +222,78 @@ /* * Three types of field elements are handled: * 1) Offset - specifies a bit offset - * 2) Access_as - changes the access mode + * 2) access_as - changes the access mode * 3) Name - Enters a new named field into the namespace */ - switch (arg->opcode) { + switch (arg->common.aml_opcode) { case AML_INT_RESERVEDFIELD_OP: - info->field_bit_position += arg->value.size; + position = (acpi_integer) info->field_bit_position + + (acpi_integer) arg->common.value.size; + + if (position > ACPI_UINT32_MAX) { + ACPI_REPORT_ERROR (("Bit offset within field too large (> 0xFFFFFFFF)\n")); + return_ACPI_STATUS (AE_SUPPORT); + } + + info->field_bit_position = (u32) position; break; case AML_INT_ACCESSFIELD_OP: /* - * Get a new Access_type and Access_attribute for all - * entries (until end or another Access_as keyword) + * Get a new access_type and access_attribute -- to be used for all + * field units that follow, until field end or another access_as keyword. + * + * In field_flags, preserve the flag bits other than the ACCESS_TYPE bits */ - info->field_flags = (u8) ((info->field_flags & FIELD_ACCESS_TYPE_MASK) || - ((u8) (arg->value.integer >> 8))); + info->field_flags = (u8) ((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | + ((u8) ((u32) arg->common.value.integer >> 8))); + + info->attribute = (u8) (arg->common.value.integer); break; case AML_INT_NAMEDFIELD_OP: - /* Enter a new field name into the namespace */ + /* Lookup the name */ status = acpi_ns_lookup (walk_state->scope_info, - (NATIVE_CHAR *) &((acpi_parse2_object *)arg)->name, - info->field_type, IMODE_LOAD_PASS1, - NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, - NULL, &info->field_node); + (char *) &arg->named.name, + info->field_type, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, + walk_state, &info->field_node); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + ACPI_REPORT_NSERROR ((char *) &arg->named.name, status); + if (status != AE_ALREADY_EXISTS) { + return_ACPI_STATUS (status); + } + + /* Already exists, ignore error */ + } + else { + arg->common.node = info->field_node; + info->field_bit_length = arg->common.value.size; + + /* Create and initialize an object for the new Field Node */ + + status = acpi_ex_prep_field_value (info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - /* Create and initialize an object for the new Field Node */ + /* Keep track of bit position for the next field */ - info->field_bit_length = arg->value.size; + position = (acpi_integer) info->field_bit_position + + (acpi_integer) arg->common.value.size; - status = acpi_ex_prep_field_value (info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + if (position > ACPI_UINT32_MAX) { + ACPI_REPORT_ERROR (("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n", + (char *) &info->field_node->name)); + return_ACPI_STATUS (AE_SUPPORT); } - /* Keep track of bit position for the next field */ - info->field_bit_position += info->field_bit_length; break; @@ -246,12 +301,11 @@ default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %X\n", - arg->opcode)); - return_ACPI_STATUS (AE_AML_ERROR); - break; + arg->common.aml_opcode)); + return_ACPI_STATUS (AE_AML_BAD_OPCODE); } - arg = arg->next; + arg = arg->common.next; } return_ACPI_STATUS (AE_OK); @@ -260,11 +314,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_create_field + * FUNCTION: acpi_ds_create_field * * PARAMETERS: Op - Op containing the Field definition and args - * Region_node - Object for the containing Operation Region - * ` Walk_state - Current method state + * region_node - Object for the containing Operation Region + * ` walk_state - Current method state * * RETURN: Status * @@ -274,41 +328,43 @@ acpi_status acpi_ds_create_field ( - acpi_parse_object *op, - acpi_namespace_node *region_node, - acpi_walk_state *walk_state) + union acpi_parse_object *op, + struct acpi_namespace_node *region_node, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_AML_ERROR; - acpi_parse_object *arg; - ACPI_CREATE_FIELD_INFO info; + acpi_status status; + union acpi_parse_object *arg; + struct acpi_create_field_info info; - FUNCTION_TRACE_PTR ("Ds_create_field", op); + ACPI_FUNCTION_TRACE_PTR ("ds_create_field", op); - /* First arg is the name of the parent Op_region (must already exist) */ + /* First arg is the name of the parent op_region (must already exist) */ - arg = op->value.arg; + arg = op->common.value.arg; if (!region_node) { - status = acpi_ns_lookup (walk_state->scope_info, arg->value.name, - ACPI_TYPE_REGION, IMODE_EXECUTE, - NS_SEARCH_PARENT, walk_state, ®ion_node); + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name, + ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT, walk_state, ®ion_node); if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (arg->common.value.name, status); return_ACPI_STATUS (status); } } /* Second arg is the field flags */ - arg = arg->next; - info.field_flags = arg->value.integer8; + arg = arg->common.next; + info.field_flags = (u8) arg->common.value.integer; + info.attribute = 0; /* Each remaining arg is a Named Field */ - info.field_type = INTERNAL_TYPE_REGION_FIELD; + info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD; info.region_node = region_node; - status = acpi_ds_get_field_names (&info, walk_state, arg->next); + status = acpi_ds_get_field_names (&info, walk_state, arg->common.next); return_ACPI_STATUS (status); } @@ -316,11 +372,95 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_create_bank_field + * FUNCTION: acpi_ds_init_field_objects * * PARAMETERS: Op - Op containing the Field definition and args - * Region_node - Object for the containing Operation Region - * ` Walk_state - Current method state + * ` walk_state - Current method state + * + * RETURN: Status + * + * DESCRIPTION: For each "Field Unit" name in the argument list that is + * part of the field declaration, enter the name into the + * namespace. + * + ******************************************************************************/ + +acpi_status +acpi_ds_init_field_objects ( + union acpi_parse_object *op, + struct acpi_walk_state *walk_state) +{ + acpi_status status; + union acpi_parse_object *arg = NULL; + struct acpi_namespace_node *node; + u8 type = 0; + + + ACPI_FUNCTION_TRACE_PTR ("ds_init_field_objects", op); + + + switch (walk_state->opcode) { + case AML_FIELD_OP: + arg = acpi_ps_get_arg (op, 2); + type = ACPI_TYPE_LOCAL_REGION_FIELD; + break; + + case AML_BANK_FIELD_OP: + arg = acpi_ps_get_arg (op, 4); + type = ACPI_TYPE_LOCAL_BANK_FIELD; + break; + + case AML_INDEX_FIELD_OP: + arg = acpi_ps_get_arg (op, 3); + type = ACPI_TYPE_LOCAL_INDEX_FIELD; + break; + + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* + * Walk the list of entries in the field_list + */ + while (arg) { + /* Ignore OFFSET and ACCESSAS terms here */ + + if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { + status = acpi_ns_lookup (walk_state->scope_info, + (char *) &arg->named.name, + type, ACPI_IMODE_LOAD_PASS1, + ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, + walk_state, &node); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR ((char *) &arg->named.name, status); + if (status != AE_ALREADY_EXISTS) { + return_ACPI_STATUS (status); + } + + /* Name already exists, just ignore this error */ + + status = AE_OK; + } + + arg->common.node = node; + } + + /* Move to next field in the list */ + + arg = arg->common.next; + } + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ds_create_bank_field + * + * PARAMETERS: Op - Op containing the Field definition and args + * region_node - Object for the containing Operation Region + * ` walk_state - Current method state * * RETURN: Status * @@ -330,56 +470,58 @@ acpi_status acpi_ds_create_bank_field ( - acpi_parse_object *op, - acpi_namespace_node *region_node, - acpi_walk_state *walk_state) + union acpi_parse_object *op, + struct acpi_namespace_node *region_node, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_AML_ERROR; - acpi_parse_object *arg; - ACPI_CREATE_FIELD_INFO info; + acpi_status status; + union acpi_parse_object *arg; + struct acpi_create_field_info info; - FUNCTION_TRACE_PTR ("Ds_create_bank_field", op); + ACPI_FUNCTION_TRACE_PTR ("ds_create_bank_field", op); - /* First arg is the name of the parent Op_region (must already exist) */ + /* First arg is the name of the parent op_region (must already exist) */ - arg = op->value.arg; + arg = op->common.value.arg; if (!region_node) { - status = acpi_ns_lookup (walk_state->scope_info, arg->value.name, - ACPI_TYPE_REGION, IMODE_EXECUTE, - NS_SEARCH_PARENT, walk_state, ®ion_node); + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name, + ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT, walk_state, ®ion_node); if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (arg->common.value.name, status); return_ACPI_STATUS (status); } } - /* Second arg is the Bank Register (must already exist) */ + /* Second arg is the Bank Register (Field) (must already exist) */ - arg = arg->next; - status = acpi_ns_lookup (walk_state->scope_info, arg->value.string, - INTERNAL_TYPE_BANK_FIELD_DEFN, IMODE_EXECUTE, - NS_SEARCH_PARENT, walk_state, &info.register_node); + arg = arg->common.next; + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string, + ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node); if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (arg->common.value.string, status); return_ACPI_STATUS (status); } - /* Third arg is the Bank_value */ + /* Third arg is the bank_value */ - arg = arg->next; - info.bank_value = arg->value.integer32; + arg = arg->common.next; + info.bank_value = (u32) arg->common.value.integer; /* Fourth arg is the field flags */ - arg = arg->next; - info.field_flags = arg->value.integer8; + arg = arg->common.next; + info.field_flags = (u8) arg->common.value.integer; /* Each remaining arg is a Named Field */ - info.field_type = INTERNAL_TYPE_BANK_FIELD; + info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; info.region_node = region_node; - status = acpi_ds_get_field_names (&info, walk_state, arg->next); + status = acpi_ds_get_field_names (&info, walk_state, arg->common.next); return_ACPI_STATUS (status); } @@ -387,11 +529,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_create_index_field + * FUNCTION: acpi_ds_create_index_field * * PARAMETERS: Op - Op containing the Field definition and args - * Region_node - Object for the containing Operation Region - * ` Walk_state - Current method state + * region_node - Object for the containing Operation Region + * ` walk_state - Current method state * * RETURN: Status * @@ -401,50 +543,51 @@ acpi_status acpi_ds_create_index_field ( - acpi_parse_object *op, - acpi_namespace_node *region_node, - acpi_walk_state *walk_state) + union acpi_parse_object *op, + struct acpi_namespace_node *region_node, + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_parse_object *arg; - ACPI_CREATE_FIELD_INFO info; + acpi_status status; + union acpi_parse_object *arg; + struct acpi_create_field_info info; - FUNCTION_TRACE_PTR ("Ds_create_index_field", op); + ACPI_FUNCTION_TRACE_PTR ("ds_create_index_field", op); /* First arg is the name of the Index register (must already exist) */ - arg = op->value.arg; - status = acpi_ns_lookup (walk_state->scope_info, arg->value.string, - ACPI_TYPE_ANY, IMODE_EXECUTE, - NS_SEARCH_PARENT, walk_state, &info.register_node); + arg = op->common.value.arg; + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string, + ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node); if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (arg->common.value.string, status); return_ACPI_STATUS (status); } /* Second arg is the data register (must already exist) */ - arg = arg->next; - status = acpi_ns_lookup (walk_state->scope_info, arg->value.string, - INTERNAL_TYPE_INDEX_FIELD_DEFN, IMODE_EXECUTE, - NS_SEARCH_PARENT, walk_state, &info.data_register_node); + arg = arg->common.next; + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string, + ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT, walk_state, &info.data_register_node); if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (arg->common.value.string, status); return_ACPI_STATUS (status); } /* Next arg is the field flags */ - arg = arg->next; - info.field_flags = arg->value.integer8; - + arg = arg->common.next; + info.field_flags = (u8) arg->common.value.integer; /* Each remaining arg is a Named Field */ - info.field_type = INTERNAL_TYPE_INDEX_FIELD; + info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD; info.region_node = region_node; - status = acpi_ds_get_field_names (&info, walk_state, arg->next); + status = acpi_ds_get_field_names (&info, walk_state, arg->common.next); return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsinit.c linux-2.4.22/drivers/acpi/dispatcher/dsinit.c --- linux-2.4.21/drivers/acpi/dispatcher/dsinit.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/dispatcher/dsinit.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,235 @@ +/****************************************************************************** + * + * Module Name: dsinit - Object initialization namespace walk + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include +#include +#include + +#define _COMPONENT ACPI_DISPATCHER + ACPI_MODULE_NAME ("dsinit") + + +/******************************************************************************* + * + * FUNCTION: acpi_ds_init_one_object + * + * PARAMETERS: obj_handle - Node + * Level - Current nesting level + * Context - Points to a init info struct + * return_value - Not used + * + * RETURN: Status + * + * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object + * within the namespace. + * + * Currently, the only objects that require initialization are: + * 1) Methods + * 2) Operation Regions + * + ******************************************************************************/ + +acpi_status +acpi_ds_init_one_object ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) +{ + acpi_object_type type; + acpi_status status; + struct acpi_init_walk_info *info = (struct acpi_init_walk_info *) context; + + + ACPI_FUNCTION_NAME ("ds_init_one_object"); + + + /* + * We are only interested in objects owned by the table that + * was just loaded + */ + if (((struct acpi_namespace_node *) obj_handle)->owner_id != + info->table_desc->table_id) { + return (AE_OK); + } + + info->object_count++; + + /* And even then, we are only interested in a few object types */ + + type = acpi_ns_get_type (obj_handle); + + switch (type) { + case ACPI_TYPE_REGION: + + status = acpi_ds_initialize_region (obj_handle); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n", + obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii, + acpi_format_exception (status))); + } + + info->op_region_count++; + break; + + + case ACPI_TYPE_METHOD: + + info->method_count++; + + /* Print a dot for each method unless we are going to print the entire pathname */ + + if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); + } + + /* + * Set the execution data width (32 or 64) based upon the + * revision number of the parent ACPI table. + * TBD: This is really for possible future support of integer width + * on a per-table basis. Currently, we just use a global for the width. + */ + if (info->table_desc->pointer->revision == 1) { + ((struct acpi_namespace_node *) obj_handle)->flags |= ANOBJ_DATA_WIDTH_32; + } + + /* + * Always parse methods to detect errors, we may delete + * the parse tree below + */ + status = acpi_ds_parse_method (obj_handle); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n", + obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii, + acpi_format_exception (status))); + + /* This parse failed, but we will continue parsing more methods */ + + break; + } + + /* + * Delete the parse tree. We simple re-parse the method + * for every execution since there isn't much overhead + */ + acpi_ns_delete_namespace_subtree (obj_handle); + acpi_ns_delete_namespace_by_owner (((struct acpi_namespace_node *) obj_handle)->object->method.owning_id); + break; + + + case ACPI_TYPE_DEVICE: + + info->device_count++; + break; + + + default: + break; + } + + /* + * We ignore errors from above, and always return OK, since + * we don't want to abort the walk on a single error. + */ + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ds_initialize_objects + * + * PARAMETERS: table_desc - Descriptor for parent ACPI table + * start_node - Root of subtree to be initialized. + * + * RETURN: Status + * + * DESCRIPTION: Walk the namespace starting at "start_node" and perform any + * necessary initialization on the objects found therein + * + ******************************************************************************/ + +acpi_status +acpi_ds_initialize_objects ( + struct acpi_table_desc *table_desc, + struct acpi_namespace_node *start_node) +{ + acpi_status status; + struct acpi_init_walk_info info; + + + ACPI_FUNCTION_TRACE ("ds_initialize_objects"); + + + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "**** Starting initialization of namespace objects ****\n")); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:")); + + info.method_count = 0; + info.op_region_count = 0; + info.object_count = 0; + info.device_count = 0; + info.table_desc = table_desc; + + /* Walk entire namespace from the supplied root */ + + status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, + acpi_ds_init_one_object, &info, NULL); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed, %s\n", + acpi_format_exception (status))); + } + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, + "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", + table_desc->pointer->signature, table_desc->table_id, info.object_count, + info.device_count, info.method_count, info.op_region_count)); + + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "%hd Methods, %hd Regions\n", info.method_count, info.op_region_count)); + + return_ACPI_STATUS (AE_OK); +} + + diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsmethod.c linux-2.4.22/drivers/acpi/dispatcher/dsmethod.c --- linux-2.4.21/drivers/acpi/dispatcher/dsmethod.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dsmethod.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,51 +1,67 @@ /****************************************************************************** * * Module Name: dsmethod - Parser/Interpreter interface - control method parsing - * $Revision: 69 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" -#include "acdebug.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dsmethod") + ACPI_MODULE_NAME ("dsmethod") /******************************************************************************* * - * FUNCTION: Acpi_ds_parse_method + * FUNCTION: acpi_ds_parse_method * - * PARAMETERS: Obj_handle - Node of the method + * PARAMETERS: obj_handle - Node of the method * Level - Current nesting level * Context - Points to a method counter - * Return_value - Not used + * return_value - Not used * * RETURN: Status * @@ -58,17 +74,17 @@ acpi_status acpi_ds_parse_method ( - acpi_handle obj_handle) + acpi_handle obj_handle) { - acpi_status status; - acpi_operand_object *obj_desc; - acpi_parse_object *op; - acpi_namespace_node *node; - acpi_owner_id owner_id; - acpi_walk_state *walk_state; + acpi_status status; + union acpi_operand_object *obj_desc; + union acpi_parse_object *op; + struct acpi_namespace_node *node; + acpi_owner_id owner_id; + struct acpi_walk_state *walk_state; - FUNCTION_TRACE_PTR ("Ds_parse_method", obj_handle); + ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", obj_handle); /* Parameter Validation */ @@ -77,14 +93,13 @@ return_ACPI_STATUS (AE_NULL_ENTRY); } - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Parsing [%4.4s] **** Named_obj=%p\n", - (char*)&((acpi_namespace_node *)obj_handle)->name, obj_handle)); - + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n", + ((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle)); /* Extract the method object from the method Node */ - node = (acpi_namespace_node *) obj_handle; - obj_desc = node->object; + node = (struct acpi_namespace_node *) obj_handle; + obj_desc = acpi_ns_get_attached_object (node); if (!obj_desc) { return_ACPI_STATUS (AE_NULL_OBJECT); } @@ -112,13 +127,20 @@ /* Init new op with the method name and pointer back to the Node */ - acpi_ps_set_name (op, node->name); - op->node = node; + acpi_ps_set_name (op, node->name.integer); + op->common.node = node; + + /* + * Get a new owner_id for objects created by this method. Namespace + * objects (such as Operation Regions) can be created during the + * first pass parse. + */ + owner_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); + obj_desc->method.owning_id = owner_id; /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -126,7 +148,7 @@ status = acpi_ds_init_aml_walk (walk_state, op, node, obj_desc->method.aml_start, obj_desc->method.aml_length, NULL, NULL, 1); if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ + acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); } @@ -145,27 +167,22 @@ return_ACPI_STATUS (status); } - /* Get a new Owner_id for objects created by this method */ - - owner_id = acpi_ut_allocate_owner_id (OWNER_TYPE_METHOD); - obj_desc->method.owning_id = owner_id; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** [%4.4s] Parsed **** Named_obj=%p Op=%p\n", - (char*)&((acpi_namespace_node *)obj_handle)->name, obj_handle, op)); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", + ((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle, op)); acpi_ps_delete_parse_tree (op); - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ds_begin_method_execution + * FUNCTION: acpi_ds_begin_method_execution * - * PARAMETERS: Method_node - Node of the method - * Obj_desc - The method object - * Calling_method_node - Caller of this method (if non-null) + * PARAMETERS: method_node - Node of the method + * obj_desc - The method object + * calling_method_node - Caller of this method (if non-null) * * RETURN: Status * @@ -179,21 +196,20 @@ acpi_status acpi_ds_begin_method_execution ( - acpi_namespace_node *method_node, - acpi_operand_object *obj_desc, - acpi_namespace_node *calling_method_node) + struct acpi_namespace_node *method_node, + union acpi_operand_object *obj_desc, + struct acpi_namespace_node *calling_method_node) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE_PTR ("Ds_begin_method_execution", method_node); + ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node); if (!method_node) { return_ACPI_STATUS (AE_NULL_ENTRY); } - /* * If there is a concurrency limit on this method, we need to * obtain a unit from the method semaphore. @@ -201,7 +217,7 @@ if (obj_desc->method.semaphore) { /* * Allow recursive method calls, up to the reentrancy/concurrency - * limit imposed by the SERIALIZED rule and the Sync_level method + * limit imposed by the SERIALIZED rule and the sync_level method * parameter. * * The point of this code is to avoid permanently blocking a @@ -218,25 +234,23 @@ * interpreter if we block */ status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore, - WAIT_FOREVER); + ACPI_WAIT_FOREVER); } - /* * Increment the method parse tree thread count since it has been * reentered one more time (even if it is the same thread) */ obj_desc->method.thread_count++; - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ds_call_control_method + * FUNCTION: acpi_ds_call_control_method * - * PARAMETERS: Walk_state - Current state of the walk + * PARAMETERS: walk_state - Current state of the walk * Op - Current Op to be walked * * RETURN: Status @@ -247,18 +261,18 @@ acpi_status acpi_ds_call_control_method ( - acpi_walk_list *walk_list, - acpi_walk_state *this_walk_state, - acpi_parse_object *op) /* TBD: This operand is obsolete */ + struct acpi_thread_state *thread, + struct acpi_walk_state *this_walk_state, + union acpi_parse_object *op) { - acpi_status status; - acpi_namespace_node *method_node; - acpi_operand_object *obj_desc; - acpi_walk_state *next_walk_state; - u32 i; + acpi_status status; + struct acpi_namespace_node *method_node; + union acpi_operand_object *obj_desc; + struct acpi_walk_state *next_walk_state; + u32 i; - FUNCTION_TRACE_PTR ("Ds_call_control_method", this_walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_call_control_method", this_walk_state); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n", this_walk_state->prev_op, this_walk_state)); @@ -276,6 +290,8 @@ return_ACPI_STATUS (AE_NULL_OBJECT); } + obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); + /* Init for new method, wait on concurrency semaphore */ status = acpi_ds_begin_method_execution (method_node, obj_desc, @@ -284,19 +300,17 @@ return_ACPI_STATUS (status); } - /* 1) Parse: Create a new walk state for the preempting walk */ next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, op, obj_desc, NULL); if (!next_walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); - goto cleanup; } /* Create and init a Root Node */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); + op = acpi_ps_create_scope_op (); if (!op) { status = AE_NO_MEMORY; goto cleanup; @@ -306,7 +320,7 @@ obj_desc->method.aml_start, obj_desc->method.aml_length, NULL, NULL, 1); if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ + acpi_ds_delete_walk_state (next_walk_state); goto cleanup; } @@ -315,11 +329,10 @@ status = acpi_ps_parse_aml (next_walk_state); acpi_ps_delete_parse_tree (op); - /* 2) Execute: Create a new state for the preempting walk */ next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, - NULL, obj_desc, walk_list); + NULL, obj_desc, thread); if (!next_walk_state) { status = AE_NO_MEMORY; goto cleanup; @@ -353,8 +366,8 @@ this_walk_state->num_operands = 0; - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Starting nested execution, newstate=%p\n", - next_walk_state)); + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "Starting nested execution, newstate=%p\n", next_walk_state)); return_ACPI_STATUS (AE_OK); @@ -362,7 +375,7 @@ /* On error, we must delete the new walk state */ cleanup: - acpi_ds_terminate_control_method (next_walk_state); + (void) acpi_ds_terminate_control_method (next_walk_state); acpi_ds_delete_walk_state (next_walk_state); return_ACPI_STATUS (status); @@ -371,9 +384,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_restart_control_method + * FUNCTION: acpi_ds_restart_control_method * - * PARAMETERS: Walk_state - State of the method when it was preempted + * PARAMETERS: walk_state - State of the method when it was preempted * Op - Pointer to new current op * * RETURN: Status @@ -384,13 +397,13 @@ acpi_status acpi_ds_restart_control_method ( - acpi_walk_state *walk_state, - acpi_operand_object *return_desc) + struct acpi_walk_state *walk_state, + union acpi_operand_object *return_desc) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE_PTR ("Ds_restart_control_method", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state); if (return_desc) { @@ -405,7 +418,6 @@ return_ACPI_STATUS (status); } } - else { /* * Delete the return value if it will not be used by the @@ -413,24 +425,22 @@ */ acpi_ut_remove_reference (return_desc); } - } ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Method=%p Return=%p Return_used?=%X Res_stack=%p State=%p\n", + "Method=%p Return=%p return_used?=%X res_stack=%p State=%p\n", walk_state->method_call_op, return_desc, walk_state->return_used, walk_state->results, walk_state)); - return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ds_terminate_control_method + * FUNCTION: acpi_ds_terminate_control_method * - * PARAMETERS: Walk_state - State of the method + * PARAMETERS: walk_state - State of the method * * RETURN: Status * @@ -442,16 +452,21 @@ acpi_status acpi_ds_terminate_control_method ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object *obj_desc; - acpi_namespace_node *method_node; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *method_node; + acpi_status status; - FUNCTION_TRACE_PTR ("Ds_terminate_control_method", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_terminate_control_method", walk_state); - /* The method object should be stored in the walk state */ + if (!walk_state) { + return (AE_BAD_PARAMETER); + } + + /* The current method object was saved in the walk state */ obj_desc = walk_state->method_desc; if (!obj_desc) { @@ -467,14 +482,22 @@ * If this is the last thread executing the method, * we have additional cleanup to perform */ - acpi_ut_acquire_mutex (ACPI_MTX_PARSER); - + status = acpi_ut_acquire_mutex (ACPI_MTX_PARSER); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Signal completion of the execution of this method if necessary */ if (walk_state->method_desc->method.semaphore) { - acpi_os_signal_semaphore ( - walk_state->method_desc->method.semaphore, 1); + status = acpi_os_signal_semaphore ( + walk_state->method_desc->method.semaphore, 1); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not signal method semaphore\n")); + status = AE_OK; + + /* Ignore error and continue cleanup */ + } } /* Decrement the thread count on the method parse tree */ @@ -493,7 +516,11 @@ * Delete any namespace entries created immediately underneath * the method */ - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + if (method_node->child) { acpi_ns_delete_namespace_subtree (method_node); } @@ -503,11 +530,14 @@ * the namespace */ acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - acpi_ut_release_mutex (ACPI_MTX_PARSER); - return_ACPI_STATUS (AE_OK); + status = acpi_ut_release_mutex (ACPI_MTX_PARSER); + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsmthdat.c linux-2.4.22/drivers/acpi/dispatcher/dsmthdat.c --- linux-2.4.21/drivers/acpi/dispatcher/dsmthdat.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dsmthdat.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,193 +1,196 @@ /******************************************************************************* * * Module Name: dsmthdat - control method arguments and local variables - * $Revision: 49 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dsmthdat") + ACPI_MODULE_NAME ("dsmthdat") /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_init + * FUNCTION: acpi_ds_method_data_init * - * PARAMETERS: Walk_state - Current walk state object + * PARAMETERS: walk_state - Current walk state object * * RETURN: Status * * DESCRIPTION: Initialize the data structures that hold the method's arguments * and locals. The data struct is an array of NTEs for each. - * This allows Ref_of and De_ref_of to work properly for these + * This allows ref_of and de_ref_of to work properly for these * special data types. * + * NOTES: walk_state fields are initialized to zero by the + * ACPI_MEM_CALLOCATE(). + * + * A pseudo-Namespace Node is assigned to each argument and local + * so that ref_of() can return a pointer to the Node. + * ******************************************************************************/ -acpi_status +void acpi_ds_method_data_init ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - u32 i; + u32 i; - FUNCTION_TRACE ("Ds_method_data_init"); + ACPI_FUNCTION_TRACE ("ds_method_data_init"); - /* - * Walk_state fields are initialized to zero by the - * ACPI_MEM_CALLOCATE(). - * - * An Node is assigned to each argument and local so - * that Ref_of() can return a pointer to the Node. - */ /* Init the method arguments */ - for (i = 0; i < MTH_NUM_ARGS; i++) { - MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name, - NAMEOF_ARG_NTE); - walk_state->arguments[i].name |= (i << 24); - walk_state->arguments[i].data_type = ACPI_DESC_TYPE_NAMED; - walk_state->arguments[i].type = ACPI_TYPE_ANY; - walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; + for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) { + ACPI_MOVE_32_TO_32 (&walk_state->arguments[i].name, + NAMEOF_ARG_NTE); + walk_state->arguments[i].name.integer |= (i << 24); + walk_state->arguments[i].descriptor = ACPI_DESC_TYPE_NAMED; + walk_state->arguments[i].type = ACPI_TYPE_ANY; + walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; } /* Init the method locals */ - for (i = 0; i < MTH_NUM_LOCALS; i++) { - MOVE_UNALIGNED32_TO_32 (&walk_state->local_variables[i].name, - NAMEOF_LOCAL_NTE); - - walk_state->local_variables[i].name |= (i << 24); - walk_state->local_variables[i].data_type = ACPI_DESC_TYPE_NAMED; - walk_state->local_variables[i].type = ACPI_TYPE_ANY; - walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; + for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) { + ACPI_MOVE_32_TO_32 (&walk_state->local_variables[i].name, + NAMEOF_LOCAL_NTE); + + walk_state->local_variables[i].name.integer |= (i << 24); + walk_state->local_variables[i].descriptor = ACPI_DESC_TYPE_NAMED; + walk_state->local_variables[i].type = ACPI_TYPE_ANY; + walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; } - return_ACPI_STATUS (AE_OK); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_delete_all + * FUNCTION: acpi_ds_method_data_delete_all * - * PARAMETERS: Walk_state - Current walk state object + * PARAMETERS: walk_state - Current walk state object * - * RETURN: Status + * RETURN: None * * DESCRIPTION: Delete method locals and arguments. Arguments are only * deleted if this method was called from another method. * ******************************************************************************/ -acpi_status +void acpi_ds_method_data_delete_all ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - u32 index; - acpi_operand_object *object; + u32 index; - FUNCTION_TRACE ("Ds_method_data_delete_all"); + ACPI_FUNCTION_TRACE ("ds_method_data_delete_all"); - /* Delete the locals */ + /* Detach the locals */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting local variables in %p\n", walk_state)); + for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) { + if (walk_state->local_variables[index].object) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n", + index, walk_state->local_variables[index].object)); - for (index = 0; index < MTH_NUM_LOCALS; index++) { - object = walk_state->local_variables[index].object; - if (object) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n", index, object)); + /* Detach object (if present) and remove a reference */ - /* Remove first */ - - walk_state->local_variables[index].object = NULL; - - /* Was given a ref when stored */ - - acpi_ut_remove_reference (object); - } + acpi_ns_detach_object (&walk_state->local_variables[index]); + } } + /* Detach the arguments */ - /* Delete the arguments */ - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting arguments in %p\n", walk_state)); - - for (index = 0; index < MTH_NUM_ARGS; index++) { - object = walk_state->arguments[index].object; - if (object) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n", index, object)); - - /* Remove first */ - - walk_state->arguments[index].object = NULL; + for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) { + if (walk_state->arguments[index].object) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n", + index, walk_state->arguments[index].object)); - /* Was given a ref when stored */ + /* Detach object (if present) and remove a reference */ - acpi_ut_remove_reference (object); + acpi_ns_detach_object (&walk_state->arguments[index]); } } - return_ACPI_STATUS (AE_OK); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_init_args + * FUNCTION: acpi_ds_method_data_init_args * * PARAMETERS: *Params - Pointer to a parameter list for the method - * Max_param_count - The arg count for this method - * Walk_state - Current walk state object + * max_param_count - The arg count for this method + * walk_state - Current walk state object * * RETURN: Status * - * DESCRIPTION: Initialize arguments for a method + * DESCRIPTION: Initialize arguments for a method. The parameter list is a list + * of ACPI operand objects, either null terminated or whose length + * is defined by max_param_count. * ******************************************************************************/ acpi_status acpi_ds_method_data_init_args ( - acpi_operand_object **params, - u32 max_param_count, - acpi_walk_state *walk_state) + union acpi_operand_object **params, + u32 max_param_count, + struct acpi_walk_state *walk_state) { - acpi_status status; - u32 mindex; - u32 pindex; + acpi_status status; + u32 index = 0; - FUNCTION_TRACE_PTR ("Ds_method_data_init_args", params); + ACPI_FUNCTION_TRACE_PTR ("ds_method_data_init_args", params); if (!params) { @@ -197,293 +200,224 @@ /* Copy passed parameters into the new method stack frame */ - for (pindex = mindex = 0; - (mindex < MTH_NUM_ARGS) && (pindex < max_param_count); - mindex++) { - if (params[pindex]) { - /* - * A valid parameter. - * Set the current method argument to the - * Params[Pindex++] argument object descriptor - */ - status = acpi_ds_store_object_to_local (AML_ARG_OP, mindex, - params[pindex], walk_state); - if (ACPI_FAILURE (status)) { - break; - } - - pindex++; + while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) { + /* + * A valid parameter. + * Store the argument in the method/walk descriptor + */ + status = acpi_ds_store_object_to_local (AML_ARG_OP, index, params[index], + walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - else { - break; - } + index++; } - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", pindex)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", index)); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_get_entry + * FUNCTION: acpi_ds_method_data_get_node * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument to get - * Entry - Pointer to where a pointer to the stack - * entry is returned. - * Walk_state - Current walk state object - * - * RETURN: Status + * Index - which local_var or argument whose type + * to get + * walk_state - Current walk state object * - * DESCRIPTION: Get the address of the object entry given by Opcode:Index + * RETURN: Get the Node associated with a local or arg. * ******************************************************************************/ acpi_status -acpi_ds_method_data_get_entry ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state, - acpi_operand_object ***entry) +acpi_ds_method_data_get_node ( + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node **node) { - - FUNCTION_TRACE_U32 ("Ds_method_data_get_entry", index); + ACPI_FUNCTION_TRACE ("ds_method_data_get_node"); /* - * Get the requested object. - * The stack "Opcode" is either a Local_variable or an Argument + * Method Locals and Arguments are supported */ switch (opcode) { - case AML_LOCAL_OP: - if (index > MTH_MAX_LOCAL) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local_var index %d is invalid (max %d)\n", - index, MTH_MAX_LOCAL)); - return_ACPI_STATUS (AE_BAD_PARAMETER); + if (index > ACPI_METHOD_MAX_LOCAL) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n", + index, ACPI_METHOD_MAX_LOCAL)); + return_ACPI_STATUS (AE_AML_INVALID_INDEX); } - *entry = (acpi_operand_object **) - &walk_state->local_variables[index].object; - break; + /* Return a pointer to the pseudo-node */ + *node = &walk_state->local_variables[index]; + break; case AML_ARG_OP: - if (index > MTH_MAX_ARG) { + if (index > ACPI_METHOD_MAX_ARG) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n", - index, MTH_MAX_ARG)); - return_ACPI_STATUS (AE_BAD_PARAMETER); + index, ACPI_METHOD_MAX_ARG)); + return_ACPI_STATUS (AE_AML_INVALID_INDEX); } - *entry = (acpi_operand_object **) - &walk_state->arguments[index].object; - break; + /* Return a pointer to the pseudo-node */ + *node = &walk_state->arguments[index]; + break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode)); - return_ACPI_STATUS (AE_BAD_PARAMETER); + return_ACPI_STATUS (AE_AML_BAD_OPCODE); } - return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_set_entry + * FUNCTION: acpi_ds_method_data_set_value * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument to get + * Index - which local_var or argument to get * Object - Object to be inserted into the stack entry - * Walk_state - Current walk state object + * walk_state - Current walk state object * * RETURN: Status * * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index. + * Note: There is no "implicit conversion" for locals. * ******************************************************************************/ acpi_status -acpi_ds_method_data_set_entry ( - u16 opcode, - u32 index, - acpi_operand_object *object, - acpi_walk_state *walk_state) +acpi_ds_method_data_set_value ( + u16 opcode, + u32 index, + union acpi_operand_object *object, + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_operand_object **entry; + acpi_status status; + struct acpi_namespace_node *node; + + ACPI_FUNCTION_TRACE ("ds_method_data_set_value"); - FUNCTION_TRACE ("Ds_method_data_set_entry"); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "obj %p op %X, ref count = %d [%s]\n", object, + opcode, object->common.reference_count, + acpi_ut_get_type_name (object->common.type))); - /* Get a pointer to the stack entry to set */ + /* Get the namespace node for the arg/local */ - status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry); + status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* Increment ref count so object can't be deleted while installed */ - + /* + * Increment ref count so object can't be deleted while installed. + * NOTE: We do not copy the object in order to preserve the call by + * reference semantics of ACPI Control Method invocation. + * (See ACPI specification 2.0_c) + */ acpi_ut_add_reference (object); - /* Install the object into the stack entry */ - - *entry = object; + /* Install the object */ - return_ACPI_STATUS (AE_OK); + node->object = object; + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_get_type + * FUNCTION: acpi_ds_method_data_get_type * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument whose type + * Index - which local_var or argument whose type * to get - * Walk_state - Current walk state object + * walk_state - Current walk state object * - * RETURN: Data type of selected Arg or Local - * Used only in Exec_monadic2()/Type_op. + * RETURN: Data type of current value of the selected Arg or Local * ******************************************************************************/ -acpi_object_type8 +acpi_object_type acpi_ds_method_data_get_type ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state) + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_operand_object **entry; - acpi_operand_object *object; + acpi_status status; + struct acpi_namespace_node *node; + union acpi_operand_object *object; - FUNCTION_TRACE ("Ds_method_data_get_type"); + ACPI_FUNCTION_TRACE ("ds_method_data_get_type"); - /* Get a pointer to the requested stack entry */ + /* Get the namespace node for the arg/local */ - status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry); + status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node); if (ACPI_FAILURE (status)) { return_VALUE ((ACPI_TYPE_NOT_FOUND)); } - /* Get the object from the method stack */ - - object = *entry; - - /* Get the object type */ + /* Get the object */ + object = acpi_ns_get_attached_object (node); if (!object) { - /* Any == 0 => "uninitialized" -- see spec 15.2.3.5.2.28 */ - return_VALUE (ACPI_TYPE_ANY); - } - - return_VALUE (object->common.type); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ds_method_data_get_node - * - * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument whose type - * to get - * Walk_state - Current walk state object - * - * RETURN: Get the Node associated with a local or arg. - * - ******************************************************************************/ + /* Uninitialized local/arg, return TYPE_ANY */ -acpi_namespace_node * -acpi_ds_method_data_get_node ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state) -{ - acpi_namespace_node *node = NULL; - - - FUNCTION_TRACE ("Ds_method_data_get_node"); - - - switch (opcode) { - - case AML_LOCAL_OP: - - if (index > MTH_MAX_LOCAL) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n", - index, MTH_MAX_LOCAL)); - return_PTR (node); - } - - node = &walk_state->local_variables[index]; - break; - - - case AML_ARG_OP: - - if (index > MTH_MAX_ARG) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n", - index, MTH_MAX_ARG)); - return_PTR (node); - } - - node = &walk_state->arguments[index]; - break; - - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode)); - break; + return_VALUE (ACPI_TYPE_ANY); } + /* Get the object type */ - return_PTR (node); + return_VALUE (ACPI_GET_OBJECT_TYPE (object)); } /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_get_value + * FUNCTION: acpi_ds_method_data_get_value * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument to get - * Walk_state - Current walk state object - * *Dest_desc - Ptr to Descriptor into which selected Arg + * Index - which local_var or argument to get + * walk_state - Current walk state object + * *dest_desc - Ptr to Descriptor into which selected Arg * or Local value should be copied * * RETURN: Status * * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame * at the current top of the method stack. - * Used only in Acpi_ex_resolve_to_value(). + * Used only in acpi_ex_resolve_to_value(). * ******************************************************************************/ acpi_status acpi_ds_method_data_get_value ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state, - acpi_operand_object **dest_desc) + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state, + union acpi_operand_object **dest_desc) { - acpi_status status; - acpi_operand_object **entry; - acpi_operand_object *object; + acpi_status status; + struct acpi_namespace_node *node; + union acpi_operand_object *object; - FUNCTION_TRACE ("Ds_method_data_get_value"); + ACPI_FUNCTION_TRACE ("ds_method_data_get_value"); /* Validate the object descriptor */ @@ -493,24 +427,22 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } + /* Get the namespace node for the arg/local */ - /* Get a pointer to the requested method stack entry */ - - status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry); + status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* Get the object from the method stack */ - - object = *entry; + /* Get the object from the node */ + object = node->object; /* Examine the returned object, it must be valid. */ if (!object) { /* - * Index points to uninitialized object stack value. + * Index points to uninitialized object. * This means that either 1) The expected argument was * not passed to the method, or 2) A local variable * was referenced by the method (via the ASL) @@ -519,25 +451,25 @@ switch (opcode) { case AML_ARG_OP: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at entry %p\n", - index, entry)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n", + index, node)); return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG); - break; case AML_LOCAL_OP: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at entry %p\n", - index, entry)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at node %p\n", + index, node)); return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL); - break; + + default: + return_ACPI_STATUS (AE_AML_INTERNAL); } } - /* - * Index points to initialized and valid object stack value. + * The Index points to an initialized and valid object. * Return an additional reference to the object */ *dest_desc = object; @@ -549,125 +481,126 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_method_data_delete_value + * FUNCTION: acpi_ds_method_data_delete_value * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument to delete - * Walk_state - Current walk state object + * Index - which local_var or argument to delete + * walk_state - Current walk state object * - * RETURN: Status + * RETURN: None * * DESCRIPTION: Delete the entry at Opcode:Index on the method stack. Inserts * a null into the stack slot after the object is deleted. * ******************************************************************************/ -acpi_status +void acpi_ds_method_data_delete_value ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state) + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_operand_object **entry; - acpi_operand_object *object; + acpi_status status; + struct acpi_namespace_node *node; + union acpi_operand_object *object; - FUNCTION_TRACE ("Ds_method_data_delete_value"); + ACPI_FUNCTION_TRACE ("ds_method_data_delete_value"); - /* Get a pointer to the requested entry */ + /* Get the namespace node for the arg/local */ - status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry); + status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + return_VOID; } - /* Get the current entry in this slot k */ + /* Get the associated object */ - object = *entry; + object = acpi_ns_get_attached_object (node); /* * Undefine the Arg or Local by setting its descriptor * pointer to NULL. Locals/Args can contain both * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs */ - *entry = NULL; + node->object = NULL; if ((object) && - (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL))) { + (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_OPERAND)) { /* - * There is a valid object in this slot + * There is a valid object. * Decrement the reference count by one to balance the - * increment when the object was stored in the slot. + * increment when the object was stored. */ acpi_ut_remove_reference (object); } - return_ACPI_STATUS (AE_OK); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ds_store_object_to_local + * FUNCTION: acpi_ds_store_object_to_local * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument to set - * Src_desc - Value to be stored - * Walk_state - Current walk state + * Index - which local_var or argument to set + * obj_desc - Value to be stored + * walk_state - Current walk state * * RETURN: Status * - * DESCRIPTION: Store a value in an Arg or Local. The Src_desc is installed + * DESCRIPTION: Store a value in an Arg or Local. The obj_desc is installed * as the new value for the Arg or Local and the reference count - * for Src_desc is incremented. + * for obj_desc is incremented. * ******************************************************************************/ acpi_status acpi_ds_store_object_to_local ( - u16 opcode, - u32 index, - acpi_operand_object *src_desc, - acpi_walk_state *walk_state) + u16 opcode, + u32 index, + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_operand_object **entry; + acpi_status status; + struct acpi_namespace_node *node; + union acpi_operand_object *current_obj_desc; - FUNCTION_TRACE ("Ds_method_data_set_value"); + ACPI_FUNCTION_TRACE ("ds_store_object_to_local"); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n", - opcode, index, src_desc)); + opcode, index, obj_desc)); /* Parameter validation */ - if (!src_desc) { + if (!obj_desc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + /* Get the namespace node for the arg/local */ - /* Get a pointer to the requested method stack entry */ - - status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry); + status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node); if (ACPI_FAILURE (status)) { - goto cleanup; + return_ACPI_STATUS (status); } - if (*entry == src_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", src_desc)); - goto cleanup; + current_obj_desc = acpi_ns_get_attached_object (node); + if (current_obj_desc == obj_desc) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", + obj_desc)); + return_ACPI_STATUS (status); } - /* * If there is an object already in this slot, we either * have to delete it, or if this is an argument and there * is an object reference stored there, we have to do * an indirect store! */ - if (*entry) { + if (current_obj_desc) { /* * Check for an indirect store if an argument * contains an object reference (stored as an Node). @@ -675,45 +608,46 @@ * locals, since a store to a local should overwrite * anything there, including an object reference. * - * If both Arg0 and Local0 contain Ref_of (Local4): + * If both Arg0 and Local0 contain ref_of (Local4): * * Store (1, Arg0) - Causes indirect store to local4 * Store (1, Local0) - Stores 1 in local0, overwriting * the reference to local4 - * Store (1, De_refof (Local0)) - Causes indirect store to local4 + * Store (1, de_refof (Local0)) - Causes indirect store to local4 * * Weird, but true. */ - if ((opcode == AML_ARG_OP) && - (VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED))) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Arg (%p) is an Obj_ref(Node), storing in %p\n", - src_desc, *entry)); - - /* Detach an existing object from the Node */ - - acpi_ns_detach_object ((acpi_namespace_node *) *entry); - + if (opcode == AML_ARG_OP) { /* - * Store this object into the Node - * (do the indirect store) + * Make sure that the object is the correct type. This may be overkill, but + * it is here because references were NS nodes in the past. Now they are + * operand objects of type Reference. */ - status = acpi_ns_attach_object ((acpi_namespace_node *) *entry, src_desc, - src_desc->common.type); - return_ACPI_STATUS (status); - } - + if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) { + ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: %X\n", + current_obj_desc->common.type)); + return_ACPI_STATUS (AE_AML_INTERNAL); + } -#ifdef ACPI_ENABLE_IMPLICIT_CONVERSION - /* - * Perform "Implicit conversion" of the new object to the type of the - * existing object - */ - status = acpi_ex_convert_to_target_type ((*entry)->common.type, &src_desc, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; + /* + * If we have a valid reference object that came from ref_of(), do the + * indirect store + */ + if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) && + (current_obj_desc->reference.opcode == AML_REF_OF_OP)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Arg (%p) is an obj_ref(Node), storing in node %p\n", + obj_desc, current_obj_desc)); + + /* + * Store this object to the Node + * (perform the indirect store) + */ + status = acpi_ex_store_object_to_node (obj_desc, + current_obj_desc->reference.object, walk_state); + return_ACPI_STATUS (status); + } } -#endif /* * Delete the existing object @@ -722,27 +656,14 @@ acpi_ds_method_data_delete_value (opcode, index, walk_state); } - /* - * Install the Obj_stack descriptor (*Src_desc) into + * Install the obj_stack descriptor (*obj_desc) into * the descriptor for the Arg or Local. * Install the new object in the stack entry * (increments the object reference count by one) */ - status = acpi_ds_method_data_set_entry (opcode, index, src_desc, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - /* Normal exit */ - - return_ACPI_STATUS (AE_OK); - - - /* Error exit */ - -cleanup: - + status = acpi_ds_method_data_set_value (opcode, index, obj_desc, walk_state); return_ACPI_STATUS (status); } + diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsobject.c linux-2.4.22/drivers/acpi/dispatcher/dsobject.c --- linux-2.4.21/drivers/acpi/dispatcher/dsobject.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dsobject.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,692 +1,612 @@ /****************************************************************************** * * Module Name: dsobject - Dispatcher object management routines - * $Revision: 81 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dsobject") + ACPI_MODULE_NAME ("dsobject") -/******************************************************************************* +#ifndef ACPI_NO_METHOD_EXECUTION +/***************************************************************************** * - * FUNCTION: Acpi_ds_init_one_object + * FUNCTION: acpi_ds_build_internal_object * - * PARAMETERS: Obj_handle - Node - * Level - Current nesting level - * Context - Points to a init info struct - * Return_value - Not used + * PARAMETERS: walk_state - Current walk state + * Op - Parser object to be translated + * obj_desc_ptr - Where the ACPI internal object is returned * * RETURN: Status * - * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object - * within the namespace. - * - * Currently, the only objects that require initialization are: - * 1) Methods - * 2) Op Regions + * DESCRIPTION: Translate a parser Op object to the equivalent namespace object + * Simple objects are any objects other than a package object! * - ******************************************************************************/ + ****************************************************************************/ acpi_status -acpi_ds_init_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value) +acpi_ds_build_internal_object ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + union acpi_operand_object **obj_desc_ptr) { - acpi_object_type8 type; - acpi_status status; - acpi_init_walk_info *info = (acpi_init_walk_info *) context; - u8 table_revision; - - - PROC_NAME ("Ds_init_one_object"); - - - info->object_count++; - table_revision = info->table_desc->pointer->revision; - - /* - * We are only interested in objects owned by the table that - * was just loaded - */ - if (((acpi_namespace_node *) obj_handle)->owner_id != - info->table_desc->table_id) { - return (AE_OK); - } - - - /* And even then, we are only interested in a few object types */ - - type = acpi_ns_get_type (obj_handle); - - switch (type) { + union acpi_operand_object *obj_desc; + acpi_status status; - case ACPI_TYPE_REGION: - acpi_ds_initialize_region (obj_handle); + ACPI_FUNCTION_TRACE ("ds_build_internal_object"); - info->op_region_count++; - break; - - - case ACPI_TYPE_METHOD: - - info->method_count++; - - if (!(acpi_dbg_level & ACPI_LV_INIT)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); - } - - /* - * Set the execution data width (32 or 64) based upon the - * revision number of the parent ACPI table. - */ - if (table_revision == 1) { - ((acpi_namespace_node *)obj_handle)->flags |= ANOBJ_DATA_WIDTH_32; - } + *obj_desc_ptr = NULL; + if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { /* - * Always parse methods to detect errors, we may delete - * the parse tree below + * This is an named object reference. If this name was + * previously looked up in the namespace, it was stored in this op. + * Otherwise, go ahead and look it up now */ - status = acpi_ds_parse_method (obj_handle); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n", - obj_handle, (char*)&((acpi_namespace_node *)obj_handle)->name, - acpi_format_exception (status))); + if (!op->common.node) { + status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string, + ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, + (struct acpi_namespace_node **) &(op->common.node)); - /* This parse failed, but we will continue parsing more methods */ - - break; + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (op->common.value.string, status); + return_ACPI_STATUS (status); + } } - - /* - * Delete the parse tree. We simple re-parse the method - * for every execution since there isn't much overhead - */ - acpi_ns_delete_namespace_subtree (obj_handle); - break; - - default: - break; } - /* - * We ignore errors from above, and always return OK, since - * we don't want to abort the walk on a single error. - */ - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ds_initialize_objects - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Walk the entire namespace and perform any necessary - * initialization on the objects found therein - * - ******************************************************************************/ - -acpi_status -acpi_ds_initialize_objects ( - acpi_table_desc *table_desc, - acpi_namespace_node *start_node) -{ - acpi_status status; - acpi_init_walk_info info; - - - FUNCTION_TRACE ("Ds_initialize_objects"); - - - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "**** Starting initialization of namespace objects ****\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Parsing Methods:")); - - - info.method_count = 0; - info.op_region_count = 0; - info.object_count = 0; - info.table_desc = table_desc; - + /* Create and init the internal ACPI object */ - /* Walk entire namespace from the supplied root */ + obj_desc = acpi_ut_create_internal_object ((acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type); + if (!obj_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, - acpi_ds_init_one_object, &info, NULL); + status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed! %x\n", status)); + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - "\n%d Control Methods found and parsed (%d nodes total)\n", - info.method_count, info.object_count)); - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "%d Control Methods found\n", info.method_count)); - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "%d Op Regions found\n", info.op_region_count)); - + *obj_desc_ptr = obj_desc; return_ACPI_STATUS (AE_OK); } /***************************************************************************** * - * FUNCTION: Acpi_ds_init_object_from_op + * FUNCTION: acpi_ds_build_internal_buffer_obj * - * PARAMETERS: Op - Parser op used to init the internal object - * Opcode - AML opcode associated with the object - * Obj_desc - Namespace object to be initialized + * PARAMETERS: walk_state - Current walk state + * Op - Parser object to be translated + * buffer_length - Length of the buffer + * obj_desc_ptr - Where the ACPI internal object is returned * * RETURN: Status * - * DESCRIPTION: Initialize a namespace object from a parser Op and its - * associated arguments. The namespace object is a more compact - * representation of the Op and its arguments. + * DESCRIPTION: Translate a parser Op package object to the equivalent + * namespace object * ****************************************************************************/ acpi_status -acpi_ds_init_object_from_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - u16 opcode, - acpi_operand_object **ret_obj_desc) +acpi_ds_build_internal_buffer_obj ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + u32 buffer_length, + union acpi_operand_object **obj_desc_ptr) { - acpi_status status; - acpi_parse_object *arg; - acpi_parse2_object *byte_list; - acpi_operand_object *arg_desc; - const acpi_opcode_info *op_info; - acpi_operand_object *obj_desc; - + union acpi_parse_object *arg; + union acpi_operand_object *obj_desc; + union acpi_parse_object *byte_list; + u32 byte_list_length = 0; - PROC_NAME ("Ds_init_object_from_op"); + ACPI_FUNCTION_TRACE ("ds_build_internal_buffer_obj"); - obj_desc = *ret_obj_desc; - op_info = acpi_ps_get_opcode_info (opcode); - if (op_info->class == AML_CLASS_UNKNOWN) { - /* Unknown opcode */ - return (AE_TYPE); + obj_desc = *obj_desc_ptr; + if (obj_desc) { + /* + * We are evaluating a Named buffer object "Name (xxxx, Buffer)". + * The buffer object already exists (from the NS node) + */ } + else { + /* Create a new buffer object */ - - /* Get and prepare the first argument */ - - switch (obj_desc->common.type) { - case ACPI_TYPE_BUFFER: - - /* First arg is a number */ - - acpi_ds_create_operand (walk_state, op->value.arg, 0); - arg_desc = walk_state->operands [walk_state->num_operands - 1]; - acpi_ds_obj_stack_pop (1, walk_state); - - /* Resolve the object (could be an arg or local) */ - - status = acpi_ex_resolve_to_value (&arg_desc, walk_state); - if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (arg_desc); - return (status); + obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + *obj_desc_ptr = obj_desc; + if (!obj_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); } + } - /* We are expecting a number */ + /* + * Second arg is the buffer data (optional) byte_list can be either + * individual bytes or a string initializer. In either case, a + * byte_list appears in the AML. + */ + arg = op->common.value.arg; /* skip first arg */ - if (arg_desc->common.type != ACPI_TYPE_INTEGER) { + byte_list = arg->named.next; + if (byte_list) { + if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Expecting number, got obj: %p type %X\n", - arg_desc, arg_desc->common.type)); - acpi_ut_remove_reference (arg_desc); + "Expecting bytelist, got AML opcode %X in op %p\n", + byte_list->common.aml_opcode, byte_list)); + + acpi_ut_remove_reference (obj_desc); return (AE_TYPE); } - /* Get the value, delete the internal object */ + byte_list_length = (u32) byte_list->common.value.integer; + } - obj_desc->buffer.length = (u32) arg_desc->integer.value; - acpi_ut_remove_reference (arg_desc); + /* + * The buffer length (number of bytes) will be the larger of: + * 1) The specified buffer length and + * 2) The length of the initializer byte list + */ + obj_desc->buffer.length = buffer_length; + if (byte_list_length > buffer_length) { + obj_desc->buffer.length = byte_list_length; + } - /* Allocate the buffer */ + /* Allocate the buffer */ - if (obj_desc->buffer.length == 0) { - obj_desc->buffer.pointer = NULL; - REPORT_WARNING (("Buffer created with zero length in AML\n")); - break; + if (obj_desc->buffer.length == 0) { + obj_desc->buffer.pointer = NULL; + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Buffer defined with zero length in AML, creating\n")); + } + else { + obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE ( + obj_desc->buffer.length); + if (!obj_desc->buffer.pointer) { + acpi_ut_delete_object_desc (obj_desc); + return_ACPI_STATUS (AE_NO_MEMORY); } - else { - obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE ( - obj_desc->buffer.length); + /* Initialize buffer from the byte_list (if present) */ - if (!obj_desc->buffer.pointer) { - return (AE_NO_MEMORY); - } + if (byte_list) { + ACPI_MEMCPY (obj_desc->buffer.pointer, byte_list->named.data, + byte_list_length); } + } - /* - * Second arg is the buffer data (optional) Byte_list can be either - * individual bytes or a string initializer. - */ - arg = op->value.arg; /* skip first arg */ - - byte_list = (acpi_parse2_object *) arg->next; - if (byte_list) { - if (byte_list->opcode != AML_INT_BYTELIST_OP) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Expecting bytelist, got: %p\n", - byte_list)); - return (AE_TYPE); - } + obj_desc->buffer.flags |= AOPOBJ_DATA_VALID; + op->common.node = (struct acpi_namespace_node *) obj_desc; + return_ACPI_STATUS (AE_OK); +} - MEMCPY (obj_desc->buffer.pointer, byte_list->data, - obj_desc->buffer.length); - } - break; +/***************************************************************************** + * + * FUNCTION: acpi_ds_build_internal_package_obj + * + * PARAMETERS: walk_state - Current walk state + * Op - Parser object to be translated + * package_length - Number of elements in the package + * obj_desc_ptr - Where the ACPI internal object is returned + * + * RETURN: Status + * + * DESCRIPTION: Translate a parser Op package object to the equivalent + * namespace object + * + ****************************************************************************/ +acpi_status +acpi_ds_build_internal_package_obj ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + u32 package_length, + union acpi_operand_object **obj_desc_ptr) +{ + union acpi_parse_object *arg; + union acpi_parse_object *parent; + union acpi_operand_object *obj_desc = NULL; + u32 package_list_length; + acpi_status status = AE_OK; + u32 i; - case ACPI_TYPE_PACKAGE: - /* - * When called, an internal package object has already been built and - * is pointed to by Obj_desc. Acpi_ds_build_internal_object builds another - * internal package object, so remove reference to the original so - * that it is deleted. Error checking is done within the remove - * reference function. - */ - acpi_ut_remove_reference (obj_desc); - status = acpi_ds_build_internal_object (walk_state, op, ret_obj_desc); - break; + ACPI_FUNCTION_TRACE ("ds_build_internal_package_obj"); - case ACPI_TYPE_INTEGER: - obj_desc->integer.value = op->value.integer; - break; + /* Find the parent of a possibly nested package */ - case ACPI_TYPE_STRING: - obj_desc->string.pointer = op->value.string; - obj_desc->string.length = STRLEN (op->value.string); + parent = op->common.parent; + while ((parent->common.aml_opcode == AML_PACKAGE_OP) || + (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { + parent = parent->common.parent; + } + obj_desc = *obj_desc_ptr; + if (obj_desc) { /* - * The string is contained in the ACPI table, don't ever try - * to delete it + * We are evaluating a Named package object "Name (xxxx, Package)". + * Get the existing package object from the NS node */ - obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; - break; - - - case ACPI_TYPE_METHOD: - break; - - - case INTERNAL_TYPE_REFERENCE: - - switch (op_info->type) { - case AML_TYPE_LOCAL_VARIABLE: - - /* Split the opcode into a base opcode + offset */ - - obj_desc->reference.opcode = AML_LOCAL_OP; - obj_desc->reference.offset = opcode - AML_LOCAL_OP; - break; + } + else { + obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE); + *obj_desc_ptr = obj_desc; + if (!obj_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + obj_desc->package.node = parent->common.node; + } - case AML_TYPE_METHOD_ARGUMENT: + obj_desc->package.count = package_length; - /* Split the opcode into a base opcode + offset */ + /* Count the number of items in the package list */ - obj_desc->reference.opcode = AML_ARG_OP; - obj_desc->reference.offset = opcode - AML_ARG_OP; - break; + package_list_length = 0; + arg = op->common.value.arg; + arg = arg->common.next; + while (arg) { + package_list_length++; + arg = arg->common.next; + } + /* + * The package length (number of elements) will be the greater + * of the specified length and the length of the initializer list + */ + if (package_list_length > package_length) { + obj_desc->package.count = package_list_length; + } - default: /* Constants, Literals, etc.. */ + /* + * Allocate the pointer array (array of pointers to the + * individual objects). Add an extra pointer slot so + * that the list is always null terminated. + */ + obj_desc->package.elements = ACPI_MEM_CALLOCATE ( + ((acpi_size) obj_desc->package.count + 1) * sizeof (void *)); - if (op->opcode == AML_INT_NAMEPATH_OP) { - /* Node was saved in Op */ + if (!obj_desc->package.elements) { + acpi_ut_delete_object_desc (obj_desc); + return_ACPI_STATUS (AE_NO_MEMORY); + } - obj_desc->reference.node = op->node; - } + /* + * Now init the elements of the package + */ + i = 0; + arg = op->common.value.arg; + arg = arg->common.next; + while (arg) { + if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { + /* Object (package or buffer) is already built */ - obj_desc->reference.opcode = opcode; - break; + obj_desc->package.elements[i] = ACPI_CAST_PTR (union acpi_operand_object, arg->common.node); + } + else { + status = acpi_ds_build_internal_object (walk_state, arg, + &obj_desc->package.elements[i]); } - break; - - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %x\n", - obj_desc->common.type)); - - break; + i++; + arg = arg->common.next; } - return (AE_OK); + obj_desc->package.flags |= AOPOBJ_DATA_VALID; + op->common.node = (struct acpi_namespace_node *) obj_desc; + return_ACPI_STATUS (status); } /***************************************************************************** * - * FUNCTION: Acpi_ds_build_internal_simple_obj + * FUNCTION: acpi_ds_create_node * - * PARAMETERS: Op - Parser object to be translated - * Obj_desc_ptr - Where the ACPI internal object is returned + * PARAMETERS: walk_state - Current walk state + * Node - NS Node to be initialized + * Op - Parser object to be translated * * RETURN: Status * - * DESCRIPTION: Translate a parser Op object to the equivalent namespace object - * Simple objects are any objects other than a package object! + * DESCRIPTION: Create the object to be associated with a namespace node * ****************************************************************************/ -static acpi_status -acpi_ds_build_internal_simple_obj ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_operand_object **obj_desc_ptr) +acpi_status +acpi_ds_create_node ( + struct acpi_walk_state *walk_state, + struct acpi_namespace_node *node, + union acpi_parse_object *op) { - acpi_operand_object *obj_desc; - acpi_object_type8 type; - acpi_status status; - u32 length; - char *name; + acpi_status status; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE ("Ds_build_internal_simple_obj"); - - - if (op->opcode == AML_INT_NAMEPATH_OP) { - /* - * This is an object reference. If The name was - * previously looked up in the NS, it is stored in this op. - * Otherwise, go ahead and look it up now - */ - if (!op->node) { - status = acpi_ns_lookup (walk_state->scope_info, - op->value.string, ACPI_TYPE_ANY, - IMODE_EXECUTE, - NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, - NULL, - (acpi_namespace_node **)&(op->node)); + ACPI_FUNCTION_TRACE_PTR ("ds_create_node", op); - if (ACPI_FAILURE (status)) { - if (status == AE_NOT_FOUND) { - name = NULL; - acpi_ns_externalize_name (ACPI_UINT32_MAX, op->value.string, &length, &name); - - if (name) { - REPORT_WARNING (("Reference %s at AML %X not found\n", - name, op->aml_offset)); - ACPI_MEM_FREE (name); - } - - else { - REPORT_WARNING (("Reference %s at AML %X not found\n", - op->value.string, op->aml_offset)); - } - - *obj_desc_ptr = NULL; - } - - else { - return_ACPI_STATUS (status); - } - } - } - /* - * The reference will be a Reference - * TBD: [Restructure] unless we really need a separate - * type of INTERNAL_TYPE_REFERENCE change - * Acpi_ds_map_opcode_to_data_type to handle this case - */ - type = INTERNAL_TYPE_REFERENCE; - } - else { - type = acpi_ds_map_opcode_to_data_type (op->opcode, NULL); + /* + * Because of the execution pass through the non-control-method + * parts of the table, we can arrive here twice. Only init + * the named object node the first time through + */ + if (acpi_ns_get_attached_object (node)) { + return_ACPI_STATUS (AE_OK); } + if (!op->common.value.arg) { + /* No arguments, there is nothing to do */ - /* Create and init the internal ACPI object */ - - obj_desc = acpi_ut_create_internal_object (type); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); + return_ACPI_STATUS (AE_OK); } - status = acpi_ds_init_object_from_op (walk_state, op, op->opcode, &obj_desc); + /* Build an internal object for the argument(s) */ + + status = acpi_ds_build_internal_object (walk_state, op->common.value.arg, &obj_desc); if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } - *obj_desc_ptr = obj_desc; + /* Re-type the object according to its argument */ - return_ACPI_STATUS (AE_OK); + node->type = ACPI_GET_OBJECT_TYPE (obj_desc); + + /* Attach obj to node */ + + status = acpi_ns_attach_object (node, obj_desc, node->type); + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); } +#endif /* ACPI_NO_METHOD_EXECUTION */ + /***************************************************************************** * - * FUNCTION: Acpi_ds_build_internal_package_obj + * FUNCTION: acpi_ds_init_object_from_op * - * PARAMETERS: Op - Parser object to be translated - * Obj_desc_ptr - Where the ACPI internal object is returned + * PARAMETERS: walk_state - Current walk state + * Op - Parser op used to init the internal object + * Opcode - AML opcode associated with the object + * ret_obj_desc - Namespace object to be initialized * * RETURN: Status * - * DESCRIPTION: Translate a parser Op package object to the equivalent - * namespace object + * DESCRIPTION: Initialize a namespace object from a parser Op and its + * associated arguments. The namespace object is a more compact + * representation of the Op and its arguments. * ****************************************************************************/ acpi_status -acpi_ds_build_internal_package_obj ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_operand_object **obj_desc_ptr) +acpi_ds_init_object_from_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + u16 opcode, + union acpi_operand_object **ret_obj_desc) { - acpi_parse_object *arg; - acpi_operand_object *obj_desc; - acpi_status status = AE_OK; + const struct acpi_opcode_info *op_info; + union acpi_operand_object *obj_desc; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ds_build_internal_package_obj"); + ACPI_FUNCTION_TRACE ("ds_init_object_from_op"); - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE); - *obj_desc_ptr = obj_desc; - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); + obj_desc = *ret_obj_desc; + op_info = acpi_ps_get_opcode_info (opcode); + if (op_info->class == AML_CLASS_UNKNOWN) { + /* Unknown opcode */ + + return_ACPI_STATUS (AE_TYPE); } - if (op->opcode == AML_VAR_PACKAGE_OP) { + /* Perform per-object initialization */ + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_BUFFER: + /* - * Variable length package parameters are evaluated JIT + * Defer evaluation of Buffer term_arg operand */ - return_ACPI_STATUS (AE_OK); - } + obj_desc->buffer.node = (struct acpi_namespace_node *) walk_state->operands[0]; + obj_desc->buffer.aml_start = op->named.data; + obj_desc->buffer.aml_length = op->named.length; + break; - /* The first argument must be the package length */ - arg = op->value.arg; - obj_desc->package.count = arg->value.integer32; + case ACPI_TYPE_PACKAGE: - /* - * Allocate the array of pointers (ptrs to the - * individual objects) Add an extra pointer slot so - * that the list is always null terminated. - */ - obj_desc->package.elements = ACPI_MEM_CALLOCATE ( - (obj_desc->package.count + 1) * sizeof (void *)); + /* + * Defer evaluation of Package term_arg operand + */ + obj_desc->package.node = (struct acpi_namespace_node *) walk_state->operands[0]; + obj_desc->package.aml_start = op->named.data; + obj_desc->package.aml_length = op->named.length; + break; - if (!obj_desc->package.elements) { - acpi_ut_delete_object_desc (obj_desc); - return_ACPI_STATUS (AE_NO_MEMORY); - } - obj_desc->package.next_element = obj_desc->package.elements; + case ACPI_TYPE_INTEGER: - /* - * Now init the elements of the package - */ - arg = arg->next; - while (arg) { - if (arg->opcode == AML_PACKAGE_OP) { - status = acpi_ds_build_internal_package_obj (walk_state, arg, - obj_desc->package.next_element); - } + switch (op_info->type) { + case AML_TYPE_CONSTANT: + /* + * Resolve AML Constants here - AND ONLY HERE! + * All constants are integers. + * We mark the integer with a flag that indicates that it started life + * as a constant -- so that stores to constants will perform as expected (noop). + * (zero_op is used as a placeholder for optional target operands.) + */ + obj_desc->common.flags = AOPOBJ_AML_CONSTANT; - else { - status = acpi_ds_build_internal_simple_obj (walk_state, arg, - obj_desc->package.next_element); - } + switch (opcode) { + case AML_ZERO_OP: - obj_desc->package.next_element++; - arg = arg->next; - } + obj_desc->integer.value = 0; + break; - obj_desc->package.flags |= AOPOBJ_DATA_VALID; - return_ACPI_STATUS (status); -} + case AML_ONE_OP: + obj_desc->integer.value = 1; + break; -/***************************************************************************** - * - * FUNCTION: Acpi_ds_build_internal_object - * - * PARAMETERS: Op - Parser object to be translated - * Obj_desc_ptr - Where the ACPI internal object is returned - * - * RETURN: Status - * - * DESCRIPTION: Translate a parser Op object to the equivalent namespace - * object - * - ****************************************************************************/ + case AML_ONES_OP: + + obj_desc->integer.value = ACPI_INTEGER_MAX; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + +#ifndef ACPI_NO_METHOD_EXECUTION + acpi_ex_truncate_for32bit_table (obj_desc); +#endif + break; + + case AML_REVISION_OP: + + obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL; + break; + + default: + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode)); + status = AE_AML_OPERAND_TYPE; + break; + } + break; -acpi_status -acpi_ds_build_internal_object ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_operand_object **obj_desc_ptr) -{ - acpi_status status; + case AML_TYPE_LITERAL: + + obj_desc->integer.value = op->common.value.integer; + break; - switch (op->opcode) { - case AML_PACKAGE_OP: - case AML_VAR_PACKAGE_OP: - status = acpi_ds_build_internal_package_obj (walk_state, op, obj_desc_ptr); + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type)); + status = AE_AML_OPERAND_TYPE; + break; + } break; - default: + case ACPI_TYPE_STRING: - status = acpi_ds_build_internal_simple_obj (walk_state, op, obj_desc_ptr); + obj_desc->string.pointer = op->common.value.string; + obj_desc->string.length = (u32) ACPI_STRLEN (op->common.value.string); + + /* + * The string is contained in the ACPI table, don't ever try + * to delete it + */ + obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; break; - } - return (status); -} + case ACPI_TYPE_METHOD: + break; -/***************************************************************************** - * - * FUNCTION: Acpi_ds_create_node - * - * PARAMETERS: Op - Parser object to be translated - * Obj_desc_ptr - Where the ACPI internal object is returned - * - * RETURN: Status - * - * DESCRIPTION: - * - ****************************************************************************/ -acpi_status -acpi_ds_create_node ( - acpi_walk_state *walk_state, - acpi_namespace_node *node, - acpi_parse_object *op) -{ - acpi_status status; - acpi_operand_object *obj_desc; + case ACPI_TYPE_LOCAL_REFERENCE: + switch (op_info->type) { + case AML_TYPE_LOCAL_VARIABLE: - FUNCTION_TRACE_PTR ("Ds_create_node", op); + /* Split the opcode into a base opcode + offset */ + obj_desc->reference.opcode = AML_LOCAL_OP; + obj_desc->reference.offset = opcode - AML_LOCAL_OP; - /* - * Because of the execution pass through the non-control-method - * parts of the table, we can arrive here twice. Only init - * the named object node the first time through - */ - if (node->object) { - return_ACPI_STATUS (AE_OK); - } +#ifndef ACPI_NO_METHOD_EXECUTION + status = acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset, + walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object); +#endif + break; - if (!op->value.arg) { - /* No arguments, there is nothing to do */ - return_ACPI_STATUS (AE_OK); - } + case AML_TYPE_METHOD_ARGUMENT: - /* Build an internal object for the argument(s) */ + /* Split the opcode into a base opcode + offset */ - status = acpi_ds_build_internal_object (walk_state, op->value.arg, &obj_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + obj_desc->reference.opcode = AML_ARG_OP; + obj_desc->reference.offset = opcode - AML_ARG_OP; + break; - /* Re-type the object according to it's argument */ + default: /* Other literals, etc.. */ - node->type = obj_desc->common.type; + if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { + /* Node was saved in Op */ - /* Init obj */ + obj_desc->reference.node = op->common.node; + } - status = acpi_ns_attach_object (node, obj_desc, (u8) node->type); + obj_desc->reference.opcode = opcode; + break; + } + break; - /* Remove local reference to the object */ - acpi_ut_remove_reference (obj_desc); + default: + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n", + ACPI_GET_OBJECT_TYPE (obj_desc))); + + status = AE_AML_OPERAND_TYPE; + break; + } + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsopcode.c linux-2.4.22/drivers/acpi/dispatcher/dsopcode.c --- linux-2.4.21/drivers/acpi/dispatcher/dsopcode.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dsopcode.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,126 +2,118 @@ * * Module Name: dsopcode - Dispatcher Op Region support and handling of * "control" opcodes - * $Revision: 56 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acevents.h" -#include "actables.h" +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dsopcode") + ACPI_MODULE_NAME ("dsopcode") /***************************************************************************** * - * FUNCTION: Acpi_ds_get_buffer_field_arguments + * FUNCTION: acpi_ds_execute_arguments * - * PARAMETERS: Obj_desc - A valid Buffer_field object + * PARAMETERS: Node - Parent NS node + * aml_length - Length of executable AML + * aml_start - Pointer to the AML * * RETURN: Status. * - * DESCRIPTION: Get Buffer_field Buffer and Index. This implements the late - * evaluation of these field attributes. + * DESCRIPTION: Late execution of region or field arguments * ****************************************************************************/ acpi_status -acpi_ds_get_buffer_field_arguments ( - acpi_operand_object *obj_desc) +acpi_ds_execute_arguments ( + struct acpi_namespace_node *node, + struct acpi_namespace_node *scope_node, + u32 aml_length, + u8 *aml_start) { - acpi_operand_object *extra_desc; - acpi_namespace_node *node; - acpi_parse_object *op; - acpi_parse_object *field_op; - acpi_status status; - acpi_table_desc *table_desc; - acpi_walk_state *walk_state; - + acpi_status status; + union acpi_parse_object *op; + struct acpi_walk_state *walk_state; + union acpi_parse_object *arg; - FUNCTION_TRACE_PTR ("Ds_get_buffer_field_arguments", obj_desc); - - if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { - return_ACPI_STATUS (AE_OK); - } - - - /* Get the AML pointer (method object) and Buffer_field node */ - - extra_desc = obj_desc->buffer_field.extra; - node = obj_desc->buffer_field.node; - - DEBUG_EXEC(acpi_ut_display_init_pathname (node, " [Field]")); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] Buffer_field JIT Init\n", - (char*)&node->name)); + ACPI_FUNCTION_TRACE ("ds_execute_arguments"); /* - * Allocate a new parser op to be the root of the parsed - * Op_region tree + * Allocate a new parser op to be the root of the parsed tree */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); + op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP); if (!op) { - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } - /* Save the Node for use in Acpi_ps_parse_aml */ - - op->node = acpi_ns_get_parent_object (node); + /* Save the Node for use in acpi_ps_parse_aml */ - /* Get a handle to the parent ACPI table */ - - status = acpi_tb_handle_to_object (node->owner_id, &table_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + op->common.node = scope_node; /* Create and initialize a new parser state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); } - status = acpi_ds_init_aml_walk (walk_state, op, NULL, extra_desc->extra.aml_start, - extra_desc->extra.aml_length, NULL, NULL, 1); + status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, + aml_length, NULL, NULL, 1); if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ + acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); } - /* TBD: No Walk flags?? */ - - walk_state->parse_flags = 0; + walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; - /* Pass1: Parse the entire Buffer_field declaration */ + /* Pass1: Parse the entire declaration */ status = acpi_ps_parse_aml (walk_state); if (ACPI_FAILURE (status)) { @@ -129,204 +121,250 @@ return_ACPI_STATUS (status); } - /* Get and init the actual Field_unit Op created above */ - - field_op = op->value.arg; - op->node = node; - + /* Get and init the Op created above */ - field_op = op->value.arg; - field_op->node = node; + arg = op->common.value.arg; + op->common.node = node; + arg->common.node = node; acpi_ps_delete_parse_tree (op); - /* Evaluate the address and length arguments for the Op_region */ + /* Evaluate the address and length arguments for the Buffer Field */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); + op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP); if (!op) { - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } - op->node = acpi_ns_get_parent_object (node); + op->common.node = scope_node; /* Create and initialize a new parser state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); } - status = acpi_ds_init_aml_walk (walk_state, op, NULL, extra_desc->extra.aml_start, - extra_desc->extra.aml_length, NULL, NULL, 3); + status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, + aml_length, NULL, NULL, 3); if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ + acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); } status = acpi_ps_parse_aml (walk_state); acpi_ps_delete_parse_tree (op); - - /* - * The pseudo-method object is no longer needed since the region is - * now initialized - */ - acpi_ut_remove_reference (obj_desc->buffer_field.extra); - obj_desc->buffer_field.extra = NULL; - return_ACPI_STATUS (status); } /***************************************************************************** * - * FUNCTION: Acpi_ds_get_region_arguments + * FUNCTION: acpi_ds_get_buffer_field_arguments * - * PARAMETERS: Obj_desc - A valid region object + * PARAMETERS: obj_desc - A valid buffer_field object * * RETURN: Status. * - * DESCRIPTION: Get region address and length. This implements the late - * evaluation of these region attributes. + * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late + * evaluation of these field attributes. * ****************************************************************************/ acpi_status -acpi_ds_get_region_arguments ( - acpi_operand_object *obj_desc) +acpi_ds_get_buffer_field_arguments ( + union acpi_operand_object *obj_desc) { - acpi_operand_object *extra_desc = NULL; - acpi_namespace_node *node; - acpi_parse_object *op; - acpi_parse_object *region_op; - acpi_status status; - acpi_table_desc *table_desc; - acpi_walk_state *walk_state; + union acpi_operand_object *extra_desc; + struct acpi_namespace_node *node; + acpi_status status; - FUNCTION_TRACE_PTR ("Ds_get_region_arguments", obj_desc); + ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc); - if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { return_ACPI_STATUS (AE_OK); } + /* Get the AML pointer (method object) and buffer_field node */ - /* Get the AML pointer (method object) and region node */ + extra_desc = acpi_ns_get_secondary_object (obj_desc); + node = obj_desc->buffer_field.node; - extra_desc = obj_desc->region.extra; - node = obj_desc->region.node; + ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field JIT Init\n", + node->name.ascii)); - DEBUG_EXEC(acpi_ut_display_init_pathname (node, " [Operation Region]")); + /* Execute the AML code for the term_arg arguments */ - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] Op_region Init at AML %p\n", - (char*)&node->name, extra_desc->extra.aml_start)); + status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node), + extra_desc->extra.aml_length, extra_desc->extra.aml_start); + return_ACPI_STATUS (status); +} - /* - * Allocate a new parser op to be the root of the parsed - * Op_region tree - */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!op) { - return (AE_NO_MEMORY); - } - /* Save the Node for use in Acpi_ps_parse_aml */ +/***************************************************************************** + * + * FUNCTION: acpi_ds_get_buffer_arguments + * + * PARAMETERS: obj_desc - A valid Bufferobject + * + * RETURN: Status. + * + * DESCRIPTION: Get Buffer length and initializer byte list. This implements + * the late evaluation of these attributes. + * + ****************************************************************************/ - op->node = acpi_ns_get_parent_object (node); +acpi_status +acpi_ds_get_buffer_arguments ( + union acpi_operand_object *obj_desc) +{ + struct acpi_namespace_node *node; + acpi_status status; - /* Get a handle to the parent ACPI table */ - status = acpi_tb_handle_to_object (node->owner_id, &table_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc); - /* Create and initialize a new parser state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - op, NULL, NULL); - if (!walk_state) { - return_ACPI_STATUS (AE_NO_MEMORY); + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + return_ACPI_STATUS (AE_OK); } - status = acpi_ds_init_aml_walk (walk_state, op, NULL, extra_desc->extra.aml_start, - extra_desc->extra.aml_length, NULL, NULL, 1); - if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ - return_ACPI_STATUS (status); + /* Get the Buffer node */ + + node = obj_desc->buffer.node; + if (!node) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No pointer back to NS node in buffer %p\n", obj_desc)); + return_ACPI_STATUS (AE_AML_INTERNAL); } - /* TBD: No Walk flags?? */ + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer JIT Init\n")); - walk_state->parse_flags = 0; + /* Execute the AML code for the term_arg arguments */ - /* Parse the entire Op_region declaration, creating a parse tree */ + status = acpi_ds_execute_arguments (node, node, + obj_desc->buffer.aml_length, obj_desc->buffer.aml_start); + return_ACPI_STATUS (status); +} - status = acpi_ps_parse_aml (walk_state); - if (ACPI_FAILURE (status)) { - acpi_ps_delete_parse_tree (op); - return_ACPI_STATUS (status); - } - /* Get and init the actual Region_op created above */ +/***************************************************************************** + * + * FUNCTION: acpi_ds_get_package_arguments + * + * PARAMETERS: obj_desc - A valid Packageobject + * + * RETURN: Status. + * + * DESCRIPTION: Get Package length and initializer byte list. This implements + * the late evaluation of these attributes. + * + ****************************************************************************/ - region_op = op->value.arg; - op->node = node; +acpi_status +acpi_ds_get_package_arguments ( + union acpi_operand_object *obj_desc) +{ + struct acpi_namespace_node *node; + acpi_status status; - region_op = op->value.arg; - region_op->node = node; - acpi_ps_delete_parse_tree (op); + ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc); - /* Evaluate the address and length arguments for the Op_region */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!op) { - return (AE_NO_MEMORY); + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + return_ACPI_STATUS (AE_OK); } - op->node = acpi_ns_get_parent_object (node); + /* Get the Package node */ - /* Create and initialize a new parser state */ + node = obj_desc->package.node; + if (!node) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No pointer back to NS node in package %p\n", obj_desc)); + return_ACPI_STATUS (AE_AML_INTERNAL); + } - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - op, NULL, NULL); - if (!walk_state) { - return_ACPI_STATUS (AE_NO_MEMORY); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package JIT Init\n")); + + /* Execute the AML code for the term_arg arguments */ + + status = acpi_ds_execute_arguments (node, node, + obj_desc->package.aml_length, obj_desc->package.aml_start); + return_ACPI_STATUS (status); +} + + +/***************************************************************************** + * + * FUNCTION: acpi_ds_get_region_arguments + * + * PARAMETERS: obj_desc - A valid region object + * + * RETURN: Status. + * + * DESCRIPTION: Get region address and length. This implements the late + * evaluation of these region attributes. + * + ****************************************************************************/ + +acpi_status +acpi_ds_get_region_arguments ( + union acpi_operand_object *obj_desc) +{ + struct acpi_namespace_node *node; + acpi_status status; + union acpi_operand_object *extra_desc; + + + ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc); + + + if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { + return_ACPI_STATUS (AE_OK); } - status = acpi_ds_init_aml_walk (walk_state, op, NULL, extra_desc->extra.aml_start, - extra_desc->extra.aml_length, NULL, NULL, 3); - if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ - return_ACPI_STATUS (status); + extra_desc = acpi_ns_get_secondary_object (obj_desc); + if (!extra_desc) { + return_ACPI_STATUS (AE_NOT_EXIST); } - status = acpi_ps_parse_aml (walk_state); - acpi_ps_delete_parse_tree (op); + /* Get the Region node */ + + node = obj_desc->region.node; + ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL)); + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Init at AML %p\n", + node->name.ascii, extra_desc->extra.aml_start)); + + + status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node), + extra_desc->extra.aml_length, extra_desc->extra.aml_start); return_ACPI_STATUS (status); } /***************************************************************************** * - * FUNCTION: Acpi_ds_initialize_region + * FUNCTION: acpi_ds_initialize_region * * PARAMETERS: Op - A valid region Op object * * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Front end to ev_initialize_region * ****************************************************************************/ acpi_status acpi_ds_initialize_region ( - acpi_handle obj_handle) + acpi_handle obj_handle) { - acpi_operand_object *obj_desc; - acpi_status status; + union acpi_operand_object *obj_desc; + acpi_status status; obj_desc = acpi_ns_get_attached_object (obj_handle); @@ -334,301 +372,276 @@ /* Namespace is NOT locked */ status = acpi_ev_initialize_region (obj_desc, FALSE); - return (status); } /***************************************************************************** * - * FUNCTION: Acpi_ds_eval_buffer_field_operands + * FUNCTION: acpi_ds_init_buffer_field * - * PARAMETERS: Op - A valid Buffer_field Op object + * PARAMETERS: aml_opcode - create_xxx_field + * obj_desc - buffer_field object + * buffer_desc - Host Buffer + * offset_desc - Offset into buffer + * Length - Length of field (CREATE_FIELD_OP only) + * Result - Where to store the result * * RETURN: Status * - * DESCRIPTION: Get Buffer_field Buffer and Index - * Called from Acpi_ds_exec_end_op during Buffer_field parse tree walk - * - * ACPI SPECIFICATION REFERENCES: - * Each of the Buffer Field opcodes is defined as specified in in-line - * comments below. For each one, use the following definitions. - * - * Def_bit_field := Bit_field_op Src_buf Bit_idx Destination - * Def_byte_field := Byte_field_op Src_buf Byte_idx Destination - * Def_create_field := Create_field_op Src_buf Bit_idx Num_bits Name_string - * Def_dWord_field := DWord_field_op Src_buf Byte_idx Destination - * Def_word_field := Word_field_op Src_buf Byte_idx Destination - * Bit_index := Term_arg=>Integer - * Byte_index := Term_arg=>Integer - * Destination := Name_string - * Num_bits := Term_arg=>Integer - * Source_buf := Term_arg=>Buffer + * DESCRIPTION: Perform actual initialization of a buffer field * ****************************************************************************/ acpi_status -acpi_ds_eval_buffer_field_operands ( - acpi_walk_state *walk_state, - acpi_parse_object *op) +acpi_ds_init_buffer_field ( + u16 aml_opcode, + union acpi_operand_object *obj_desc, + union acpi_operand_object *buffer_desc, + union acpi_operand_object *offset_desc, + union acpi_operand_object *length_desc, + union acpi_operand_object *result_desc) { - acpi_status status; - acpi_operand_object *obj_desc; - acpi_namespace_node *node; - acpi_parse_object *next_op; - u32 offset; - u32 bit_offset; - u32 bit_count; - u8 field_flags; - acpi_operand_object *res_desc = NULL; - acpi_operand_object *cnt_desc = NULL; - acpi_operand_object *off_desc = NULL; - acpi_operand_object *src_desc = NULL; - - - FUNCTION_TRACE_PTR ("Ds_eval_buffer_field_operands", op); - - - /* - * This is where we evaluate the address and length fields of the - * Create_xxx_field declaration - */ - node = op->node; - - /* Next_op points to the op that holds the Buffer */ - - next_op = op->value.arg; - - /* Acpi_evaluate/create the address and length operands */ - - status = acpi_ds_create_operands (walk_state, next_op); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + u32 offset; + u32 bit_offset; + u32 bit_count; + u8 field_flags; + acpi_status status; - obj_desc = acpi_ns_get_attached_object (node); - if (!obj_desc) { - return_ACPI_STATUS (AE_NOT_EXIST); - } + ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc); - /* Resolve the operands */ - status = acpi_ex_resolve_operands (op->opcode, WALK_OPERANDS, walk_state); - DUMP_OPERANDS (WALK_OPERANDS, IMODE_EXECUTE, acpi_ps_get_opcode_name (op->opcode), - walk_state->num_operands, "after Acpi_ex_resolve_operands"); + /* Host object must be a Buffer */ - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n", - acpi_ps_get_opcode_name (op->opcode), status)); + if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Target of Create Field is not a Buffer object - %s\n", + acpi_ut_get_object_type_name (buffer_desc))); + status = AE_AML_OPERAND_TYPE; goto cleanup; } - /* Get the operands */ - - if (AML_CREATE_FIELD_OP == op->opcode) { - res_desc = walk_state->operands[3]; - cnt_desc = walk_state->operands[2]; - } - else { - res_desc = walk_state->operands[2]; - } - - off_desc = walk_state->operands[1]; - src_desc = walk_state->operands[0]; - - - offset = (u32) off_desc->integer.value; - /* - * If Res_desc is a Name, it will be a direct name pointer after - * Acpi_ex_resolve_operands() + * The last parameter to all of these opcodes (result_desc) started + * out as a name_string, and should therefore now be a NS node + * after resolution in acpi_ex_resolve_operands(). */ - if (!VALID_DESCRIPTOR_TYPE (res_desc, ACPI_DESC_TYPE_NAMED)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a Node\n", - acpi_ps_get_opcode_name (op->opcode))); + if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a NS Node\n", + acpi_ps_get_opcode_name (aml_opcode))); status = AE_AML_OPERAND_TYPE; goto cleanup; } + offset = (u32) offset_desc->integer.value; + /* * Setup the Bit offsets and counts, according to the opcode */ - switch (op->opcode) { - - /* Def_create_field */ - + switch (aml_opcode) { case AML_CREATE_FIELD_OP: /* Offset is in bits, count is in bits */ - bit_offset = offset; - bit_count = (u32) cnt_desc->integer.value; - field_flags = ACCESS_BYTE_ACC; + bit_offset = offset; + bit_count = (u32) length_desc->integer.value; + field_flags = AML_FIELD_ACCESS_BYTE; break; - - /* Def_create_bit_field */ - case AML_CREATE_BIT_FIELD_OP: /* Offset is in bits, Field is one bit */ - bit_offset = offset; - bit_count = 1; - field_flags = ACCESS_BYTE_ACC; + bit_offset = offset; + bit_count = 1; + field_flags = AML_FIELD_ACCESS_BYTE; break; - - /* Def_create_byte_field */ - case AML_CREATE_BYTE_FIELD_OP: /* Offset is in bytes, field is one byte */ - bit_offset = 8 * offset; - bit_count = 8; - field_flags = ACCESS_BYTE_ACC; + bit_offset = 8 * offset; + bit_count = 8; + field_flags = AML_FIELD_ACCESS_BYTE; break; - - /* Def_create_word_field */ - case AML_CREATE_WORD_FIELD_OP: /* Offset is in bytes, field is one word */ - bit_offset = 8 * offset; - bit_count = 16; - field_flags = ACCESS_WORD_ACC; + bit_offset = 8 * offset; + bit_count = 16; + field_flags = AML_FIELD_ACCESS_WORD; break; - - /* Def_create_dWord_field */ - case AML_CREATE_DWORD_FIELD_OP: /* Offset is in bytes, field is one dword */ - bit_offset = 8 * offset; - bit_count = 32; - field_flags = ACCESS_DWORD_ACC; + bit_offset = 8 * offset; + bit_count = 32; + field_flags = AML_FIELD_ACCESS_DWORD; break; - - /* Def_create_qWord_field */ - case AML_CREATE_QWORD_FIELD_OP: /* Offset is in bytes, field is one qword */ - bit_offset = 8 * offset; - bit_count = 64; - field_flags = ACCESS_QWORD_ACC; + bit_offset = 8 * offset; + bit_count = 64; + field_flags = AML_FIELD_ACCESS_QWORD; break; - default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Internal error - unknown field creation opcode %02x\n", - op->opcode)); + "Unknown field creation opcode %02x\n", + aml_opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } + /* Entire field must fit within the current length of the buffer */ + + if ((bit_offset + bit_count) > + (8 * (u32) buffer_desc->buffer.length)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Field size %d exceeds Buffer size %d (bits)\n", + bit_offset + bit_count, 8 * (u32) buffer_desc->buffer.length)); + status = AE_AML_BUFFER_LIMIT; + goto cleanup; + } + /* - * Setup field according to the object type + * Initialize areas of the field object that are common to all fields + * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE) */ - switch (src_desc->common.type) { + status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0, + bit_offset, bit_count); + if (ACPI_FAILURE (status)) { + goto cleanup; + } - /* Source_buff := Term_arg=>Buffer */ + obj_desc->buffer_field.buffer_obj = buffer_desc; - case ACPI_TYPE_BUFFER: + /* Reference count for buffer_desc inherits obj_desc count */ - if ((bit_offset + bit_count) > - (8 * (u32) src_desc->buffer.length)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Field size %d exceeds Buffer size %d (bits)\n", - bit_offset + bit_count, 8 * (u32) src_desc->buffer.length)); - status = AE_AML_BUFFER_LIMIT; - goto cleanup; - } + buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count + + obj_desc->common.reference_count); - /* - * Initialize areas of the field object that are common to all fields - * For Field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE) - */ - status = acpi_ex_prep_common_field_object (obj_desc, field_flags, - bit_offset, bit_count); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } +cleanup: - obj_desc->buffer_field.buffer_obj = src_desc; + /* Always delete the operands */ - /* Reference count for Src_desc inherits Obj_desc count */ + acpi_ut_remove_reference (offset_desc); + acpi_ut_remove_reference (buffer_desc); - src_desc->common.reference_count = (u16) (src_desc->common.reference_count + - obj_desc->common.reference_count); + if (aml_opcode == AML_CREATE_FIELD_OP) { + acpi_ut_remove_reference (length_desc); + } - break; + /* On failure, delete the result descriptor */ + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (result_desc); /* Result descriptor */ + } + else { + /* Now the address and length are valid for this buffer_field */ - /* Improper object type */ + obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; + } - default: + return_ACPI_STATUS (status); +} - if ((src_desc->common.type > (u8) INTERNAL_TYPE_REFERENCE) || !acpi_ut_valid_object_type (src_desc->common.type)) /* TBD: This line MUST be a single line until Acpi_src can handle it (block deletion) */ { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Tried to create field in invalid object type %X\n", - src_desc->common.type)); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Tried to create field in improper object type - %s\n", - acpi_ut_get_type_name (src_desc->common.type))); - } +/***************************************************************************** + * + * FUNCTION: acpi_ds_eval_buffer_field_operands + * + * PARAMETERS: walk_state - Current walk + * Op - A valid buffer_field Op object + * + * RETURN: Status + * + * DESCRIPTION: Get buffer_field Buffer and Index + * Called from acpi_ds_exec_end_op during buffer_field parse tree walk + * + ****************************************************************************/ - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } +acpi_status +acpi_ds_eval_buffer_field_operands ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op) +{ + acpi_status status; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + union acpi_parse_object *next_op; - if (AML_CREATE_FIELD_OP == op->opcode) { - /* Delete object descriptor unique to Create_field */ + ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op); - acpi_ut_remove_reference (cnt_desc); - cnt_desc = NULL; - } + /* + * This is where we evaluate the address and length fields of the + * create_xxx_field declaration + */ + node = op->common.node; + + /* next_op points to the op that holds the Buffer */ -cleanup: + next_op = op->common.value.arg; - /* Always delete the operands */ + /* Evaluate/create the address and length operands */ - acpi_ut_remove_reference (off_desc); - acpi_ut_remove_reference (src_desc); + status = acpi_ds_create_operands (walk_state, next_op); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - if (AML_CREATE_FIELD_OP == op->opcode) { - acpi_ut_remove_reference (cnt_desc); + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + return_ACPI_STATUS (AE_NOT_EXIST); } - /* On failure, delete the result descriptor */ + /* Resolve the operands */ + + status = acpi_ex_resolve_operands (op->common.aml_opcode, + ACPI_WALK_OPERANDS, walk_state); + + ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, + acpi_ps_get_opcode_name (op->common.aml_opcode), + walk_state->num_operands, "after acpi_ex_resolve_operands"); if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (res_desc); /* Result descriptor */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n", + acpi_ps_get_opcode_name (op->common.aml_opcode), status)); + + return_ACPI_STATUS (status); } + /* Initialize the Buffer Field */ + + if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { + /* NOTE: Slightly different operands for this opcode */ + + status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc, + walk_state->operands[0], walk_state->operands[1], + walk_state->operands[2], walk_state->operands[3]); + } else { - /* Now the address and length are valid for this Buffer_field */ + /* All other, create_xxx_field opcodes */ - obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; + status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc, + walk_state->operands[0], walk_state->operands[1], + NULL, walk_state->operands[2]); } return_ACPI_STATUS (status); @@ -637,46 +650,47 @@ /***************************************************************************** * - * FUNCTION: Acpi_ds_eval_region_operands + * FUNCTION: acpi_ds_eval_region_operands * - * PARAMETERS: Op - A valid region Op object + * PARAMETERS: walk_state - Current walk + * Op - A valid region Op object * * RETURN: Status * * DESCRIPTION: Get region address and length - * Called from Acpi_ds_exec_end_op during Op_region parse tree walk + * Called from acpi_ds_exec_end_op during op_region parse tree walk * ****************************************************************************/ acpi_status acpi_ds_eval_region_operands ( - acpi_walk_state *walk_state, - acpi_parse_object *op) + struct acpi_walk_state *walk_state, + union acpi_parse_object *op) { - acpi_status status; - acpi_operand_object *obj_desc; - acpi_operand_object *operand_desc; - acpi_namespace_node *node; - acpi_parse_object *next_op; + acpi_status status; + union acpi_operand_object *obj_desc; + union acpi_operand_object *operand_desc; + struct acpi_namespace_node *node; + union acpi_parse_object *next_op; - FUNCTION_TRACE_PTR ("Ds_eval_region_operands", op); + ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op); /* - * This is where we evaluate the address and length fields of the Op_region declaration + * This is where we evaluate the address and length fields of the op_region declaration */ - node = op->node; + node = op->common.node; - /* Next_op points to the op that holds the Space_iD */ + /* next_op points to the op that holds the space_iD */ - next_op = op->value.arg; + next_op = op->common.value.arg; - /* Next_op points to address op */ + /* next_op points to address op */ - next_op = next_op->next; + next_op = next_op->common.next; - /* Acpi_evaluate/create the address and length operands */ + /* Evaluate/create the address and length operands */ status = acpi_ds_create_operands (walk_state, next_op); if (ACPI_FAILURE (status)) { @@ -685,15 +699,14 @@ /* Resolve the length and address operands to numbers */ - status = acpi_ex_resolve_operands (op->opcode, WALK_OPERANDS, walk_state); + status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - DUMP_OPERANDS (WALK_OPERANDS, IMODE_EXECUTE, - acpi_ps_get_opcode_name (op->opcode), - 1, "after Acpi_ex_resolve_operands"); - + ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, + acpi_ps_get_opcode_name (op->common.aml_opcode), + 1, "after acpi_ex_resolve_operands"); obj_desc = acpi_ns_get_attached_object (node); if (!obj_desc) { @@ -715,12 +728,12 @@ */ operand_desc = walk_state->operands[walk_state->num_operands - 2]; - obj_desc->region.address = (ACPI_PHYSICAL_ADDRESS) operand_desc->integer.value; + obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value; acpi_ut_remove_reference (operand_desc); - - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Rgn_obj %p Addr %8.8X%8.8X Len %X\n", - obj_desc, HIDWORD(obj_desc->region.address), LODWORD(obj_desc->region.address), + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n", + obj_desc, + ACPI_HIDWORD (obj_desc->region.address), ACPI_LODWORD (obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ @@ -731,11 +744,106 @@ } +/***************************************************************************** + * + * FUNCTION: acpi_ds_eval_data_object_operands + * + * PARAMETERS: walk_state - Current walk + * Op - A valid data_object Op object + * obj_desc - data_object + * + * RETURN: Status + * + * DESCRIPTION: Get the operands and complete the following data objec types: + * Buffer + * Package + * + ****************************************************************************/ + +acpi_status +acpi_ds_eval_data_object_operands ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + union acpi_operand_object *obj_desc) +{ + acpi_status status; + union acpi_operand_object *arg_desc; + u32 length; + + + ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands"); + + + /* The first operand (for all of these data objects) is the length */ + + status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_ex_resolve_operands (walk_state->opcode, + &(walk_state->operands [walk_state->num_operands -1]), + walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Extract length operand */ + + arg_desc = walk_state->operands [walk_state->num_operands - 1]; + length = (u32) arg_desc->integer.value; + + /* Cleanup for length operand */ + + status = acpi_ds_obj_stack_pop (1, walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + acpi_ut_remove_reference (arg_desc); + + /* + * Create the actual data object + */ + switch (op->common.aml_opcode) { + case AML_BUFFER_OP: + + status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc); + break; + + case AML_PACKAGE_OP: + case AML_VAR_PACKAGE_OP: + + status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc); + break; + + default: + return_ACPI_STATUS (AE_AML_BAD_OPCODE); + } + + if (ACPI_SUCCESS (status)) { + /* + * Return the object in the walk_state, unless the parent is a package -- + * in this case, the return object will be stored in the parse tree + * for the package. + */ + if ((!op->common.parent) || + ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && + (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) && + (op->common.parent->common.aml_opcode != AML_NAME_OP))) { + walk_state->result_obj = obj_desc; + } + } + + return_ACPI_STATUS (status); +} + + /******************************************************************************* * - * FUNCTION: Acpi_ds_exec_begin_control_op + * FUNCTION: acpi_ds_exec_begin_control_op * - * PARAMETERS: Walk_list - The list that owns the walk stack + * PARAMETERS: walk_list - The list that owns the walk stack * Op - The control Op * * RETURN: Status @@ -747,20 +855,20 @@ acpi_status acpi_ds_exec_begin_control_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op) + struct acpi_walk_state *walk_state, + union acpi_parse_object *op) { - acpi_status status = AE_OK; - acpi_generic_state *control_state; + acpi_status status = AE_OK; + union acpi_generic_state *control_state; - PROC_NAME ("Ds_exec_begin_control_op"); + ACPI_FUNCTION_NAME ("ds_exec_begin_control_op"); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op, - op->opcode, walk_state)); + op->common.aml_opcode, walk_state)); - switch (op->opcode) { + switch (op->common.aml_opcode) { case AML_IF_OP: case AML_WHILE_OP: @@ -774,19 +882,19 @@ status = AE_NO_MEMORY; break; } - - acpi_ut_push_generic_state (&walk_state->control_state, control_state); - /* * Save a pointer to the predicate for multiple executions * of a loop */ - walk_state->control_state->control.aml_predicate_start = - walk_state->parser_state.aml - 1; - /* TBD: can this be removed? */ - /*Acpi_ps_pkg_length_encoding_size (GET8 (Walk_state->Parser_state->Aml));*/ - break; + control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1; + control_state->control.package_end = walk_state->parser_state.pkg_end; + control_state->control.opcode = op->common.aml_opcode; + + /* Push the control state on this walk's control stack */ + + acpi_ut_push_generic_state (&walk_state->control_state, control_state); + break; case AML_ELSE_OP: @@ -799,12 +907,10 @@ break; - case AML_RETURN_OP: break; - default: break; } @@ -815,9 +921,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_exec_end_control_op + * FUNCTION: acpi_ds_exec_end_control_op * - * PARAMETERS: Walk_list - The list that owns the walk stack + * PARAMETERS: walk_list - The list that owns the walk stack * Op - The control Op * * RETURN: Status @@ -825,22 +931,21 @@ * DESCRIPTION: Handles all control ops encountered during control method * execution. * - * ******************************************************************************/ acpi_status acpi_ds_exec_end_control_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op) + struct acpi_walk_state *walk_state, + union acpi_parse_object *op) { - acpi_status status = AE_OK; - acpi_generic_state *control_state; + acpi_status status = AE_OK; + union acpi_generic_state *control_state; - PROC_NAME ("Ds_exec_end_control_op"); + ACPI_FUNCTION_NAME ("ds_exec_end_control_op"); - switch (op->opcode) { + switch (op->common.aml_opcode) { case AML_IF_OP: ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op)); @@ -890,17 +995,17 @@ case AML_RETURN_OP: ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "[RETURN_OP] Op=%p Arg=%p\n",op, op->value.arg)); + "[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg)); /* * One optional operand -- the return value * It can be either an immediate operand or a result that * has been bubbled up the tree */ - if (op->value.arg) { + if (op->common.value.arg) { /* Return statement has an immediate operand */ - status = acpi_ds_create_operands (walk_state, op->value.arg); + status = acpi_ds_create_operands (walk_state, op->common.value.arg); if (ACPI_FAILURE (status)) { return (status); } @@ -917,12 +1022,11 @@ /* * Get the return value and save as the last result - * value. This is the only place where Walk_state->Return_desc + * value. This is the only place where walk_state->return_desc * is set to anything other than zero! */ walk_state->return_desc = walk_state->operands[0]; } - else if ((walk_state->results) && (walk_state->results->results.num_results > 0)) { /* @@ -934,18 +1038,17 @@ * * Allow references created by the Index operator to return unchanged. */ - if (VALID_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc [0], ACPI_DESC_TYPE_INTERNAL) && - ((walk_state->results->results.obj_desc [0])->common.type == INTERNAL_TYPE_REFERENCE) && + if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) && + (ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == ACPI_TYPE_LOCAL_REFERENCE) && ((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) { - status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state); - if (ACPI_FAILURE (status)) { - return (status); - } + status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } } walk_state->return_desc = walk_state->results->results.obj_desc [0]; } - else { /* No return operand */ @@ -960,7 +1063,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Completed RETURN_OP State=%p, Ret_val=%p\n", + "Completed RETURN_OP State=%p, ret_val=%p\n", walk_state, walk_state->return_desc)); /* End the control method execution right now */ @@ -979,7 +1082,7 @@ /* Call up to the OS service layer to handle this */ - acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode"); + status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode"); /* If and when it returns, all done. */ @@ -987,43 +1090,47 @@ case AML_BREAK_OP: + case AML_CONTINUE_OP: /* ACPI 2.0 */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Break to end of current package, Op=%p\n", op)); - /* TBD: update behavior for ACPI 2.0 */ + /* Pop and delete control states until we find a while */ - /* - * As per the ACPI specification: - * "The break operation causes the current package - * execution to complete" - * "Break -- Stop executing the current code package - * at this point" - * - * Returning AE_FALSE here will cause termination of - * the current package, and execution will continue one - * level up, starting with the completion of the parent Op. - */ - status = AE_CTRL_FALSE; - break; + while (walk_state->control_state && + (walk_state->control_state->control.opcode != AML_WHILE_OP)) { + control_state = acpi_ut_pop_generic_state (&walk_state->control_state); + acpi_ut_delete_generic_state (control_state); + } + /* No while found? */ - case AML_CONTINUE_OP: /* ACPI 2.0 */ + if (!walk_state->control_state) { + return (AE_AML_NO_WHILE); + } + + /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */ + + walk_state->aml_last_while = walk_state->control_state->control.package_end; - status = AE_NOT_IMPLEMENTED; + /* Return status depending on opcode */ + + if (op->common.aml_opcode == AML_BREAK_OP) { + status = AE_CTRL_BREAK; + } + else { + status = AE_CTRL_CONTINUE; + } break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n", - op->opcode, op)); + op->common.aml_opcode, op)); status = AE_AML_BAD_OPCODE; break; } - return (status); } diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsutils.c linux-2.4.22/drivers/acpi/dispatcher/dsutils.c --- linux-2.4.21/drivers/acpi/dispatcher/dsutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dsutils.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,48 +1,67 @@ /******************************************************************************* * * Module Name: dsutils - Dispatcher utilities - * $Revision: 80 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acdebug.h" +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dsutils") + ACPI_MODULE_NAME ("dsutils") +#ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* * - * FUNCTION: Acpi_ds_is_result_used + * FUNCTION: acpi_ds_is_result_used * * PARAMETERS: Op - * Result_obj - * Walk_state + * result_obj + * walk_state * * RETURN: Status * @@ -52,13 +71,13 @@ u8 acpi_ds_is_result_used ( - acpi_parse_object *op, - acpi_walk_state *walk_state) + union acpi_parse_object *op, + struct acpi_walk_state *walk_state) { - const acpi_opcode_info *parent_info; + const struct acpi_opcode_info *parent_info; - FUNCTION_TRACE_PTR ("Ds_is_result_used", op); + ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op); /* Must have both an Op and a Result Object */ @@ -68,29 +87,25 @@ return_VALUE (TRUE); } - /* * If there is no parent, the result can't possibly be used! * (An executing method typically has no parent, since each * method is parsed separately) However, a method that is * invoked from another method has a parent. */ - if (!op->parent) { + if (!op->common.parent) { return_VALUE (FALSE); } - /* * Get info on the parent. The root Op is AML_SCOPE */ - - parent_info = acpi_ps_get_opcode_info (op->parent->opcode); + parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode); if (parent_info->class == AML_CLASS_UNKNOWN) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op)); return_VALUE (FALSE); } - /* * Decide what to do with the result based on the parent. If * the parent opcode will not use the result, delete the object. @@ -98,88 +113,100 @@ * as an operand later. */ switch (parent_info->class) { - /* - * In these cases, the parent will never use the return object - */ - case AML_CLASS_CONTROL: /* IF, ELSE, WHILE only */ + case AML_CLASS_CONTROL: - switch (op->parent->opcode) { + switch (op->common.parent->common.aml_opcode) { case AML_RETURN_OP: /* Never delete the return value associated with a return opcode */ - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Result used, [RETURN] opcode=%X Op=%p\n", op->opcode, op)); - return_VALUE (TRUE); - break; + goto result_used; case AML_IF_OP: case AML_WHILE_OP: /* * If we are executing the predicate AND this is the predicate op, - * we will use the return value! + * we will use the return value */ - if ((walk_state->control_state->common.state == CONTROL_PREDICATE_EXECUTING) && + if ((walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING) && (walk_state->control_state->control.predicate_op == op)) { - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Result used as a predicate, [IF/WHILE] opcode=%X Op=%p\n", - op->opcode, op)); - return_VALUE (TRUE); + goto result_used; } + break; + default: + /* Ignore other control opcodes */ break; } + /* The general control opcode returns no result */ - /* Fall through to not used case below */ + goto result_not_used; - case AML_CLASS_NAMED_OBJECT: /* Scope, method, etc. */ case AML_CLASS_CREATE: /* - * These opcodes allow Term_arg(s) as operands and therefore - * method calls. The result is used. + * These opcodes allow term_arg(s) as operands and therefore + * the operands can be method calls. The result is used. */ - if ((op->parent->opcode == AML_REGION_OP) || - (op->parent->opcode == AML_CREATE_FIELD_OP) || - (op->parent->opcode == AML_CREATE_BIT_FIELD_OP) || - (op->parent->opcode == AML_CREATE_BYTE_FIELD_OP) || - (op->parent->opcode == AML_CREATE_WORD_FIELD_OP) || - (op->parent->opcode == AML_CREATE_DWORD_FIELD_OP) || - (op->parent->opcode == AML_CREATE_QWORD_FIELD_OP)) { - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Result used, [Region or Create_field] opcode=%X Op=%p\n", - op->opcode, op)); - return_VALUE (TRUE); + goto result_used; + + + case AML_CLASS_NAMED_OBJECT: + + if ((op->common.parent->common.aml_opcode == AML_REGION_OP) || + (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) || + (op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || + (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) || + (op->common.parent->common.aml_opcode == AML_BUFFER_OP) || + (op->common.parent->common.aml_opcode == AML_INT_EVAL_SUBTREE_OP)) { + /* + * These opcodes allow term_arg(s) as operands and therefore + * the operands can be method calls. The result is used. + */ + goto result_used; } - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Result not used, Parent opcode=%X Op=%p\n", op->opcode, op)); + goto result_not_used; - return_VALUE (FALSE); - break; - /* - * In all other cases. the parent will actually use the return - * object, so keep it. - */ default: - break; + + /* + * In all other cases. the parent will actually use the return + * object, so keep it. + */ + goto result_used; } + +result_used: + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] used by Parent [%s] Op=%p\n", + acpi_ps_get_opcode_name (op->common.aml_opcode), + acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op)); + return_VALUE (TRUE); + + +result_not_used: + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] not used by Parent [%s] Op=%p\n", + acpi_ps_get_opcode_name (op->common.aml_opcode), + acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op)); + + return_VALUE (FALSE); + } /******************************************************************************* * - * FUNCTION: Acpi_ds_delete_result_if_not_used + * FUNCTION: acpi_ds_delete_result_if_not_used * * PARAMETERS: Op - * Result_obj - * Walk_state + * result_obj + * walk_state * * RETURN: Status * @@ -192,15 +219,15 @@ void acpi_ds_delete_result_if_not_used ( - acpi_parse_object *op, - acpi_operand_object *result_obj, - acpi_walk_state *walk_state) + union acpi_parse_object *op, + union acpi_operand_object *result_obj, + struct acpi_walk_state *walk_state) { - acpi_operand_object *obj_desc; - acpi_status status; + union acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE_PTR ("Ds_delete_result_if_not_used", result_obj); + ACPI_FUNCTION_TRACE_PTR ("ds_delete_result_if_not_used", result_obj); if (!op) { @@ -215,7 +242,7 @@ if (!acpi_ds_is_result_used (op, walk_state)) { /* - * Must pop the result stack (Obj_desc should be equal to Result_obj) + * Must pop the result stack (obj_desc should be equal to result_obj) */ status = acpi_ds_result_pop (&obj_desc, walk_state); if (ACPI_SUCCESS (status)) { @@ -229,9 +256,89 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_create_operand + * FUNCTION: acpi_ds_resolve_operands + * + * PARAMETERS: walk_state - Current walk state with operands on stack + * + * RETURN: Status + * + * DESCRIPTION: Resolve all operands to their values. Used to prepare + * arguments to a control method invocation (a call from one + * method to another.) + * + ******************************************************************************/ + +acpi_status +acpi_ds_resolve_operands ( + struct acpi_walk_state *walk_state) +{ + u32 i; + acpi_status status = AE_OK; + + + ACPI_FUNCTION_TRACE_PTR ("ds_resolve_operands", walk_state); + + + /* + * Attempt to resolve each of the valid operands + * Method arguments are passed by value, not by reference + */ + for (i = 0; i < walk_state->num_operands; i++) { + status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state); + if (ACPI_FAILURE (status)) { + break; + } + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ds_clear_operands + * + * PARAMETERS: walk_state - Current walk state with operands on stack + * + * RETURN: None + * + * DESCRIPTION: Clear all operands on the current walk state operand stack. + * + ******************************************************************************/ + +void +acpi_ds_clear_operands ( + struct acpi_walk_state *walk_state) +{ + u32 i; + + + ACPI_FUNCTION_TRACE_PTR ("acpi_ds_clear_operands", walk_state); + + + /* + * Remove a reference on each operand on the stack + */ + for (i = 0; i < walk_state->num_operands; i++) { + /* + * Remove a reference to all operands, including both + * "Arguments" and "Targets". + */ + acpi_ut_remove_reference (walk_state->operands[i]); + walk_state->operands[i] = NULL; + } + + walk_state->num_operands = 0; + return_VOID; +} +#endif + + +/******************************************************************************* + * + * FUNCTION: acpi_ds_create_operand * - * PARAMETERS: Walk_state + * PARAMETERS: walk_state * Arg * * RETURN: Status @@ -245,34 +352,32 @@ acpi_status acpi_ds_create_operand ( - acpi_walk_state *walk_state, - acpi_parse_object *arg, - u32 arg_index) + struct acpi_walk_state *walk_state, + union acpi_parse_object *arg, + u32 arg_index) { - acpi_status status = AE_OK; - NATIVE_CHAR *name_string; - u32 name_length; - acpi_object_type8 data_type; - acpi_operand_object *obj_desc; - acpi_parse_object *parent_op; - u16 opcode; - u32 flags; - operating_mode interpreter_mode; - const acpi_opcode_info *op_info; + acpi_status status = AE_OK; + char *name_string; + u32 name_length; + union acpi_operand_object *obj_desc; + union acpi_parse_object *parent_op; + u16 opcode; + acpi_interpreter_mode interpreter_mode; + const struct acpi_opcode_info *op_info; - FUNCTION_TRACE_PTR ("Ds_create_operand", arg); + ACPI_FUNCTION_TRACE_PTR ("ds_create_operand", arg); /* A valid name must be looked up in the namespace */ - if ((arg->opcode == AML_INT_NAMEPATH_OP) && - (arg->value.string)) { + if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && + (arg->common.value.string)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", arg)); /* Get the entire name string from the AML stream */ - status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->value.buffer, + status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->common.value.buffer, &name_string, &name_length); if (ACPI_FAILURE (status)) { @@ -281,7 +386,7 @@ /* * All prefixes have been handled, and the name is - * in Name_string + * in name_string */ /* @@ -290,46 +395,41 @@ * IMODE_EXECUTE) in order to support the creation of * namespace objects during the execution of control methods. */ - parent_op = arg->parent; - op_info = acpi_ps_get_opcode_info (parent_op->opcode); + parent_op = arg->common.parent; + op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode); if ((op_info->flags & AML_NSNODE) && - (parent_op->opcode != AML_INT_METHODCALL_OP) && - (parent_op->opcode != AML_REGION_OP) && - (parent_op->opcode != AML_INT_NAMEPATH_OP)) { + (parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) && + (parent_op->common.aml_opcode != AML_REGION_OP) && + (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) { /* Enter name into namespace if not found */ - interpreter_mode = IMODE_LOAD_PASS2; + interpreter_mode = ACPI_IMODE_LOAD_PASS2; } else { /* Return a failure if name not found */ - interpreter_mode = IMODE_EXECUTE; + interpreter_mode = ACPI_IMODE_EXECUTE; } status = acpi_ns_lookup (walk_state->scope_info, name_string, ACPI_TYPE_ANY, interpreter_mode, - NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, walk_state, - (acpi_namespace_node **) &obj_desc); - - /* Free the namestring created above */ - - ACPI_MEM_FREE (name_string); - + ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc)); /* * The only case where we pass through (ignore) a NOT_FOUND - * error is for the Cond_ref_of opcode. + * error is for the cond_ref_of opcode. */ if (status == AE_NOT_FOUND) { - if (parent_op->opcode == AML_COND_REF_OF_OP) { + if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) { /* * For the Conditional Reference op, it's OK if * the name is not found; We just need a way to * indicate this to the interpreter, set the * object to the root */ - obj_desc = (acpi_operand_object *) acpi_gbl_root_node; + obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node); status = AE_OK; } @@ -339,14 +439,17 @@ * very serious error at this point */ status = AE_AML_NAME_NOT_FOUND; - - /* TBD: Externalize Name_string and print */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Object name was not found in namespace\n")); } } + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (name_string, status); + } + + /* Free the namestring created above */ + + ACPI_MEM_FREE (name_string); + /* Check status from the lookup */ if (ACPI_FAILURE (status)) { @@ -359,47 +462,42 @@ if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state)); + ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state)); } else { /* Check for null name case */ - if (arg->opcode == AML_INT_NAMEPATH_OP) { + if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { /* * If the name is null, this means that this is an * optional result parameter that was not specified - * in the original ASL. Create an Reference for a - * placeholder + * in the original ASL. Create a Zero Constant for a + * placeholder. (Store to a constant is a Noop.) */ opcode = AML_ZERO_OP; /* Has no arguments! */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg)); - - /* - * TBD: [Investigate] anything else needed for the - * zero op lvalue? - */ } else { - opcode = arg->opcode; + opcode = arg->common.aml_opcode; } + /* Get the object type of the argument */ - /* Get the data type of the argument */ - - data_type = acpi_ds_map_opcode_to_data_type (opcode, &flags); - if (data_type == INTERNAL_TYPE_INVALID) { + op_info = acpi_ps_get_opcode_info (opcode); + if (op_info->object_type == ACPI_TYPE_INVALID) { return_ACPI_STATUS (AE_NOT_IMPLEMENTED); } - if (flags & OP_HAS_RETURN_VALUE) { + if (op_info->flags & AML_HAS_RETVAL) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Argument previously created, already stacked \n")); - DEBUGGER_EXEC (acpi_db_display_argument_object (walk_state->operands [walk_state->num_operands - 1], walk_state)); + ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object ( + walk_state->operands [walk_state->num_operands - 1], walk_state)); /* * Use value that was already previously returned @@ -415,13 +513,11 @@ acpi_format_exception (status))); return_ACPI_STATUS (status); } - } - else { /* Create an ACPI_INTERNAL_OBJECT for the argument */ - obj_desc = acpi_ut_create_internal_object (data_type); + obj_desc = acpi_ut_create_internal_object (op_info->object_type); if (!obj_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -434,7 +530,7 @@ acpi_ut_delete_object_desc (obj_desc); return_ACPI_STATUS (status); } - } + } /* Put the operand object on the object stack */ @@ -443,7 +539,7 @@ return_ACPI_STATUS (status); } - DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state)); + ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state)); } return_ACPI_STATUS (AE_OK); @@ -452,9 +548,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_create_operands + * FUNCTION: acpi_ds_create_operands * - * PARAMETERS: First_arg - First argument of a parser argument tree + * PARAMETERS: first_arg - First argument of a parser argument tree * * RETURN: Status * @@ -466,15 +562,15 @@ acpi_status acpi_ds_create_operands ( - acpi_walk_state *walk_state, - acpi_parse_object *first_arg) + struct acpi_walk_state *walk_state, + union acpi_parse_object *first_arg) { - acpi_status status = AE_OK; - acpi_parse_object *arg; - u32 arg_count = 0; + acpi_status status = AE_OK; + union acpi_parse_object *arg; + u32 arg_count = 0; - FUNCTION_TRACE_PTR ("Ds_create_operands", first_arg); + ACPI_FUNCTION_TRACE_PTR ("ds_create_operands", first_arg); /* For all arguments in the list... */ @@ -491,7 +587,7 @@ /* Move on to next argument, if any */ - arg = arg->next; + arg = arg->common.next; arg_count++; } @@ -504,7 +600,7 @@ * pop everything off of the operand stack and delete those * objects */ - acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state); + (void) acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While creating Arg %d - %s\n", (arg_count + 1), acpi_format_exception (status))); @@ -512,307 +608,3 @@ } -/******************************************************************************* - * - * FUNCTION: Acpi_ds_resolve_operands - * - * PARAMETERS: Walk_state - Current walk state with operands on stack - * - * RETURN: Status - * - * DESCRIPTION: Resolve all operands to their values. Used to prepare - * arguments to a control method invocation (a call from one - * method to another.) - * - ******************************************************************************/ - -acpi_status -acpi_ds_resolve_operands ( - acpi_walk_state *walk_state) -{ - u32 i; - acpi_status status = AE_OK; - - - FUNCTION_TRACE_PTR ("Ds_resolve_operands", walk_state); - - - /* - * Attempt to resolve each of the valid operands - * Method arguments are passed by value, not by reference - */ - - /* - * TBD: [Investigate] Note from previous parser: - * Ref_of problem with Acpi_ex_resolve_to_value() conversion. - */ - for (i = 0; i < walk_state->num_operands; i++) { - status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state); - if (ACPI_FAILURE (status)) { - break; - } - } - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ds_map_opcode_to_data_type - * - * PARAMETERS: Opcode - AML opcode to map - * Out_flags - Additional info about the opcode - * - * RETURN: The ACPI type associated with the opcode - * - * DESCRIPTION: Convert a raw AML opcode to the associated ACPI data type, - * if any. If the opcode returns a value as part of the - * intepreter execution, a flag is returned in Out_flags. - * - ******************************************************************************/ - -acpi_object_type8 -acpi_ds_map_opcode_to_data_type ( - u16 opcode, - u32 *out_flags) -{ - acpi_object_type8 data_type = INTERNAL_TYPE_INVALID; - const acpi_opcode_info *op_info; - u32 flags = 0; - - - PROC_NAME ("Ds_map_opcode_to_data_type"); - - - op_info = acpi_ps_get_opcode_info (opcode); - if (op_info->class == AML_CLASS_UNKNOWN) { - /* Unknown opcode */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown AML opcode: %x\n", opcode)); - return (data_type); - } - - -/* - * TBD: Use op class - */ - - switch (op_info->type) { - - case AML_TYPE_LITERAL: - - switch (opcode) { - case AML_BYTE_OP: - case AML_WORD_OP: - case AML_DWORD_OP: - case AML_QWORD_OP: - - data_type = ACPI_TYPE_INTEGER; - break; - - - case AML_STRING_OP: - - data_type = ACPI_TYPE_STRING; - break; - - case AML_INT_NAMEPATH_OP: - data_type = INTERNAL_TYPE_REFERENCE; - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown (type LITERAL) AML opcode: %x\n", opcode)); - break; - } - break; - - - case AML_TYPE_DATA_TERM: - - switch (opcode) { - case AML_BUFFER_OP: - - data_type = ACPI_TYPE_BUFFER; - break; - - case AML_PACKAGE_OP: - case AML_VAR_PACKAGE_OP: - - data_type = ACPI_TYPE_PACKAGE; - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown (type DATA_TERM) AML opcode: %x\n", opcode)); - break; - } - break; - - - case AML_TYPE_CONSTANT: - case AML_TYPE_METHOD_ARGUMENT: - case AML_TYPE_LOCAL_VARIABLE: - - data_type = INTERNAL_TYPE_REFERENCE; - break; - - - case AML_TYPE_EXEC_1A_0T_1R: - case AML_TYPE_EXEC_1A_1T_1R: - case AML_TYPE_EXEC_2A_0T_1R: - case AML_TYPE_EXEC_2A_1T_1R: - case AML_TYPE_EXEC_2A_2T_1R: - case AML_TYPE_EXEC_3A_1T_1R: - case AML_TYPE_EXEC_6A_0T_1R: - case AML_TYPE_RETURN: - - flags = OP_HAS_RETURN_VALUE; - data_type = ACPI_TYPE_ANY; - break; - - - case AML_TYPE_METHOD_CALL: - - flags = OP_HAS_RETURN_VALUE; - data_type = ACPI_TYPE_METHOD; - break; - - - case AML_TYPE_NAMED_FIELD: - case AML_TYPE_NAMED_SIMPLE: - case AML_TYPE_NAMED_COMPLEX: - case AML_TYPE_NAMED_NO_OBJ: - - data_type = acpi_ds_map_named_opcode_to_data_type (opcode); - break; - - - case AML_TYPE_EXEC_1A_0T_0R: - case AML_TYPE_EXEC_2A_0T_0R: - case AML_TYPE_EXEC_3A_0T_0R: - case AML_TYPE_EXEC_1A_1T_0R: - case AML_TYPE_CONTROL: - - /* No mapping needed at this time */ - - break; - - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unimplemented data type opcode: %x\n", opcode)); - break; - } - - /* Return flags to caller if requested */ - - if (out_flags) { - *out_flags = flags; - } - - return (data_type); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ds_map_named_opcode_to_data_type - * - * PARAMETERS: Opcode - The Named AML opcode to map - * - * RETURN: The ACPI type associated with the named opcode - * - * DESCRIPTION: Convert a raw Named AML opcode to the associated data type. - * Named opcodes are a subsystem of the AML opcodes. - * - ******************************************************************************/ - -acpi_object_type8 -acpi_ds_map_named_opcode_to_data_type ( - u16 opcode) -{ - acpi_object_type8 data_type; - - - FUNCTION_ENTRY (); - - - /* Decode Opcode */ - - switch (opcode) { - case AML_SCOPE_OP: - data_type = INTERNAL_TYPE_SCOPE; - break; - - case AML_DEVICE_OP: - data_type = ACPI_TYPE_DEVICE; - break; - - case AML_THERMAL_ZONE_OP: - data_type = ACPI_TYPE_THERMAL; - break; - - case AML_METHOD_OP: - data_type = ACPI_TYPE_METHOD; - break; - - case AML_POWER_RES_OP: - data_type = ACPI_TYPE_POWER; - break; - - case AML_PROCESSOR_OP: - data_type = ACPI_TYPE_PROCESSOR; - break; - - case AML_FIELD_OP: /* Field_op */ - data_type = INTERNAL_TYPE_FIELD_DEFN; - break; - - case AML_INDEX_FIELD_OP: /* Index_field_op */ - data_type = INTERNAL_TYPE_INDEX_FIELD_DEFN; - break; - - case AML_BANK_FIELD_OP: /* Bank_field_op */ - data_type = INTERNAL_TYPE_BANK_FIELD_DEFN; - break; - - case AML_INT_NAMEDFIELD_OP: /* NO CASE IN ORIGINAL */ - data_type = ACPI_TYPE_ANY; - break; - - case AML_NAME_OP: /* Name_op - special code in original */ - case AML_INT_NAMEPATH_OP: - data_type = ACPI_TYPE_ANY; - break; - - case AML_ALIAS_OP: - data_type = INTERNAL_TYPE_ALIAS; - break; - - case AML_MUTEX_OP: - data_type = ACPI_TYPE_MUTEX; - break; - - case AML_EVENT_OP: - data_type = ACPI_TYPE_EVENT; - break; - - case AML_DATA_REGION_OP: - case AML_REGION_OP: - data_type = ACPI_TYPE_REGION; - break; - - - default: - data_type = ACPI_TYPE_ANY; - break; - - } - - return (data_type); -} - - diff -urN linux-2.4.21/drivers/acpi/dispatcher/dswexec.c linux-2.4.22/drivers/acpi/dispatcher/dswexec.c --- linux-2.4.21/drivers/acpi/dispatcher/dswexec.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/dispatcher/dswexec.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,45 +2,64 @@ * * Module Name: dswexec - Dispatcher method execution callbacks; * dispatch to interpreter. - * $Revision: 79 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acdebug.h" +#include +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dswexec") + ACPI_MODULE_NAME ("dswexec") /* - * Dispatch tables for opcode classes + * Dispatch table for opcode classes */ -ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch [] = { +static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch [] = { acpi_ex_opcode_1A_0T_0R, acpi_ex_opcode_1A_0T_1R, acpi_ex_opcode_1A_1T_0R, @@ -55,9 +74,9 @@ /***************************************************************************** * - * FUNCTION: Acpi_ds_get_predicate_value + * FUNCTION: acpi_ds_get_predicate_value * - * PARAMETERS: Walk_state - Current state of the parse tree walk + * PARAMETERS: walk_state - Current state of the parse tree walk * * RETURN: Status * @@ -67,18 +86,18 @@ acpi_status acpi_ds_get_predicate_value ( - acpi_walk_state *walk_state, - u32 has_result_obj) { - acpi_status status = AE_OK; - acpi_operand_object *obj_desc; + struct acpi_walk_state *walk_state, + union acpi_operand_object *result_obj) { + acpi_status status = AE_OK; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE_PTR ("Ds_get_predicate_value", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_get_predicate_value", walk_state); walk_state->control_state->common.state = 0; - if (has_result_obj) { + if (result_obj) { status = acpi_ds_result_pop (&obj_desc, walk_state); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, @@ -88,7 +107,6 @@ return_ACPI_STATUS (status); } } - else { status = acpi_ds_create_operand (walk_state, walk_state->op, 0); if (ACPI_FAILURE (status)) { @@ -104,30 +122,28 @@ } if (!obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No predicate Obj_desc=%p State=%p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No predicate obj_desc=%p State=%p\n", obj_desc, walk_state)); return_ACPI_STATUS (AE_AML_NO_OPERAND); } - /* * Result of predicate evaluation currently must * be a number */ - if (obj_desc->common.type != ACPI_TYPE_INTEGER) { + if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Bad predicate (not a number) Obj_desc=%p State=%p Type=%X\n", - obj_desc, walk_state, obj_desc->common.type)); + "Bad predicate (not a number) obj_desc=%p State=%p Type=%X\n", + obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; } - /* Truncate the predicate to 32-bits if necessary */ - acpi_ex_truncate_for32bit_table (obj_desc, walk_state); + acpi_ex_truncate_for32bit_table (obj_desc); /* * Save the result of the predicate evaluation on @@ -136,7 +152,6 @@ if (obj_desc->integer.value) { walk_state->control_state->common.value = TRUE; } - else { /* * Predicate is FALSE, we will just toss the @@ -149,12 +164,12 @@ cleanup: - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%pn", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", walk_state->control_state->common.value, walk_state->op)); /* Break to debugger to display result */ - DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state)); + ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state)); /* * Delete the predicate result object (we know that @@ -162,17 +177,17 @@ */ acpi_ut_remove_reference (obj_desc); - walk_state->control_state->common.state = CONTROL_NORMAL; + walk_state->control_state->common.state = ACPI_CONTROL_NORMAL; return_ACPI_STATUS (status); } /***************************************************************************** * - * FUNCTION: Acpi_ds_exec_begin_op + * FUNCTION: acpi_ds_exec_begin_op * - * PARAMETERS: Walk_state - Current state of the parse tree walk - * Out_op - Return op if a new one is created + * PARAMETERS: walk_state - Current state of the parse tree walk + * out_op - Return op if a new one is created * * RETURN: Status * @@ -184,15 +199,15 @@ acpi_status acpi_ds_exec_begin_op ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op) + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op) { - acpi_parse_object *op; - acpi_status status = AE_OK; - u32 opcode_class; + union acpi_parse_object *op; + acpi_status status = AE_OK; + u32 opcode_class; - FUNCTION_TRACE_PTR ("Ds_exec_begin_op", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_exec_begin_op", walk_state); op = walk_state->op; @@ -204,8 +219,18 @@ op = *out_op; walk_state->op = op; - walk_state->op_info = acpi_ps_get_opcode_info (op->opcode); - walk_state->opcode = op->opcode; + walk_state->opcode = op->common.aml_opcode; + walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); + + if (acpi_ns_opens_scope (walk_state->op_info->object_type)) { + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n", + acpi_ut_get_type_name (walk_state->op_info->object_type), op)); + + status = acpi_ds_scope_stack_pop (walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } } if (op == walk_state->origin) { @@ -223,11 +248,11 @@ */ if ((walk_state->control_state) && (walk_state->control_state->common.state == - CONTROL_CONDITIONAL_EXECUTING)) { + ACPI_CONTROL_CONDITIONAL_EXECUTING)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n", op, walk_state)); - walk_state->control_state->common.state = CONTROL_PREDICATE_EXECUTING; + walk_state->control_state->common.state = ACPI_CONTROL_PREDICATE_EXECUTING; /* Save start of predicate */ @@ -239,7 +264,7 @@ /* We want to send namepaths to the load code */ - if (op->opcode == AML_INT_NAMEPATH_OP) { + if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { opcode_class = AML_CLASS_NAMED_OBJECT; } @@ -260,7 +285,7 @@ case AML_CLASS_NAMED_OBJECT: - if (walk_state->walk_type == WALK_METHOD) { + if (walk_state->walk_type == ACPI_WALK_METHOD) { /* * Found a named object declaration during method * execution; we must enter this object into the @@ -271,19 +296,16 @@ status = acpi_ds_load2_begin_op (walk_state, NULL); } - - if (op->opcode == AML_REGION_OP) { + if (op->common.aml_opcode == AML_REGION_OP) { status = acpi_ds_result_stack_push (walk_state); } - break; - /* most operators with arguments */ - case AML_CLASS_EXECUTE: case AML_CLASS_CREATE: + /* most operators with arguments */ /* Start a new result/operand state */ status = acpi_ds_result_stack_push (walk_state); @@ -302,9 +324,9 @@ /***************************************************************************** * - * FUNCTION: Acpi_ds_exec_end_op + * FUNCTION: acpi_ds_exec_end_op * - * PARAMETERS: Walk_state - Current state of the parse tree walk + * PARAMETERS: walk_state - Current state of the parse tree walk * Op - Op that has been just been completed in the * walk; Arguments have now been evaluated. * @@ -318,18 +340,17 @@ acpi_status acpi_ds_exec_end_op ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_parse_object *op; - acpi_status status = AE_OK; - u32 op_type; - u32 op_class; - acpi_parse_object *next_op; - acpi_parse_object *first_arg; - u32 i; + union acpi_parse_object *op; + acpi_status status = AE_OK; + u32 op_type; + u32 op_class; + union acpi_parse_object *next_op; + union acpi_parse_object *first_arg; - FUNCTION_TRACE_PTR ("Ds_exec_end_op", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_exec_end_op", walk_state); op = walk_state->op; @@ -337,11 +358,11 @@ op_class = walk_state->op_info->class; if (op_class == AML_CLASS_UNKNOWN) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->opcode)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->common.aml_opcode)); return_ACPI_STATUS (AE_NOT_IMPLEMENTED); } - first_arg = op->value.arg; + first_arg = op->common.value.arg; /* Init the walk state */ @@ -349,22 +370,19 @@ walk_state->return_desc = NULL; walk_state->result_obj = NULL; - /* Call debugger for single step support (DEBUG build only) */ - DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, op_class)); - DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return_ACPI_STATUS (status);}); + ACPI_DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, op_class)); + ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return_ACPI_STATUS (status);}); - - switch (op_class) { /* Decode the Opcode Class */ - case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */ + switch (op_class) { + case AML_CLASS_ARGUMENT: /* constants, literals, etc. -- do nothing */ break; - /* most operators with arguments */ - case AML_CLASS_EXECUTE: + case AML_CLASS_EXECUTE: /* most operators with arguments */ /* Build resolved operand stack */ @@ -385,48 +403,28 @@ status = acpi_ex_resolve_operands (walk_state->opcode, &(walk_state->operands [walk_state->num_operands -1]), walk_state); - if (ACPI_FAILURE (status)) { - /* TBD: must pop and delete operands */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%s]: Could not resolve operands, %s\n", - acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception (status))); + if (ACPI_SUCCESS (status)) { + ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, + acpi_ps_get_opcode_name (walk_state->opcode), + walk_state->num_operands, "after ex_resolve_operands"); /* - * On error, we must delete all the operands and clear the - * operand stack + * Dispatch the request to the appropriate interpreter handler + * routine. There is one routine per opcode "type" based upon the + * number of opcode arguments and return type. */ - for (i = 0; i < walk_state->num_operands; i++) { - acpi_ut_remove_reference (walk_state->operands[i]); - walk_state->operands[i] = NULL; - } - - walk_state->num_operands = 0; - goto cleanup; + status = acpi_gbl_op_type_dispatch [op_type] (walk_state); } - - DUMP_OPERANDS (WALK_OPERANDS, IMODE_EXECUTE, acpi_ps_get_opcode_name (walk_state->opcode), - walk_state->num_operands, "after Ex_resolve_operands"); - - /* - * Dispatch the request to the appropriate interpreter handler - * routine. There is one routine per opcode "type" based upon the - * number of opcode arguments and return type. - */ - status = acpi_gbl_op_type_dispatch [op_type] (walk_state); - - - /* Delete argument objects and clear the operand stack */ - - for (i = 0; i < walk_state->num_operands; i++) { - /* - * Remove a reference to all operands, including both - * "Arguments" and "Targets". - */ - acpi_ut_remove_reference (walk_state->operands[i]); - walk_state->operands[i] = NULL; + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "[%s]: Could not resolve operands, %s\n", + acpi_ps_get_opcode_name (walk_state->opcode), + acpi_format_exception (status))); } - walk_state->num_operands = 0; + /* Always delete the argument objects and clear the operand stack */ + + acpi_ds_clear_operands (walk_state); /* * If a result object was returned from above, push it on the @@ -445,11 +443,14 @@ switch (op_type) { case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */ - /* 1 Operand, 0 External_result, 0 Internal_result */ + /* 1 Operand, 0 external_result, 0 internal_result */ status = acpi_ds_exec_end_control_op (walk_state, op); + if (ACPI_FAILURE (status)) { + break; + } - acpi_ds_result_stack_pop (walk_state); + status = acpi_ds_result_stack_pop (walk_state); break; @@ -461,13 +462,13 @@ * (AML_METHODCALL) Op->Value->Arg->Node contains * the method Node pointer */ - /* Next_op points to the op that holds the method name */ + /* next_op points to the op that holds the method name */ next_op = first_arg; - /* Next_op points to first argument op */ + /* next_op points to first argument op */ - next_op = next_op->next; + next_op = next_op->common.next; /* * Get the method's arguments and put them on the operand stack @@ -478,13 +479,15 @@ } /* - * Since the operands will be passed to another - * control method, we must resolve all local - * references here (Local variables, arguments - * to *this* method, etc.) + * Since the operands will be passed to another control method, + * we must resolve all local references here (Local variables, + * arguments to *this* method, etc.) */ status = acpi_ds_resolve_operands (walk_state); if (ACPI_FAILURE (status)) { + /* On error, clear all resolved operands */ + + acpi_ds_clear_operands (walk_state); break; } @@ -499,13 +502,12 @@ * especially the operand count! */ return_ACPI_STATUS (status); - break; case AML_TYPE_CREATE_FIELD: ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Executing Create_field Buffer/Index Op=%p\n", op)); + "Executing create_field Buffer/Index Op=%p\n", op)); status = acpi_ds_load2_end_op (walk_state); if (ACPI_FAILURE (status)) { @@ -516,18 +518,65 @@ break; + case AML_TYPE_CREATE_OBJECT: + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Executing create_object (Buffer/Package) Op=%p\n", op)); + + switch (op->common.parent->common.aml_opcode) { + case AML_NAME_OP: + + /* + * Put the Node on the object stack (Contains the ACPI Name of + * this object) + */ + walk_state->operands[0] = (void *) op->common.parent->common.node; + walk_state->num_operands = 1; + + status = acpi_ds_create_node (walk_state, op->common.parent->common.node, op->common.parent); + if (ACPI_FAILURE (status)) { + break; + } + + /* Fall through */ + /*lint -fallthrough */ + + case AML_INT_EVAL_SUBTREE_OP: + + status = acpi_ds_eval_data_object_operands (walk_state, op, + acpi_ns_get_attached_object (op->common.parent->common.node)); + break; + + default: + + status = acpi_ds_eval_data_object_operands (walk_state, op, NULL); + break; + } + + /* + * If a result object was returned from above, push it on the + * current result stack + */ + if (ACPI_SUCCESS (status) && + walk_state->result_obj) { + status = acpi_ds_result_push (walk_state->result_obj, walk_state); + } + break; + + case AML_TYPE_NAMED_FIELD: case AML_TYPE_NAMED_COMPLEX: case AML_TYPE_NAMED_SIMPLE: + case AML_TYPE_NAMED_NO_OBJ: status = acpi_ds_load2_end_op (walk_state); if (ACPI_FAILURE (status)) { break; } - if (op->opcode == AML_REGION_OP) { + if (op->common.aml_opcode == AML_REGION_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Executing Op_region Address/Length Op=%p\n", op)); + "Executing op_region Address/Length Op=%p\n", op)); status = acpi_ds_eval_region_operands (walk_state, op); if (ACPI_FAILURE (status)) { @@ -539,23 +588,26 @@ break; + case AML_TYPE_UNDEFINED: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Undefined opcode type Op=%p\n", op)); return_ACPI_STATUS (AE_NOT_IMPLEMENTED); - break; case AML_TYPE_BOGUS: - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Internal opcode=%X type Op=%p\n", + + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "Internal opcode=%X type Op=%p\n", walk_state->opcode, op)); break; + default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n", - op_class, op_type, op->opcode, op)); + op_class, op_type, op->common.aml_opcode, op)); status = AE_NOT_IMPLEMENTED; break; @@ -563,10 +615,10 @@ } /* - * ACPI 2.0 support for 64-bit integers: - * Truncate numeric result value if we are executing from a 32-bit ACPI table + * ACPI 2.0 support for 64-bit integers: Truncate numeric + * result value if we are executing from a 32-bit ACPI table */ - acpi_ex_truncate_for32bit_table (walk_state->result_obj, walk_state); + acpi_ex_truncate_for32bit_table (walk_state->result_obj); /* * Check if we just completed the evaluation of a @@ -575,9 +627,9 @@ if ((walk_state->control_state) && (walk_state->control_state->common.state == - CONTROL_PREDICATE_EXECUTING) && + ACPI_CONTROL_PREDICATE_EXECUTING) && (walk_state->control_state->control.predicate_op == op)) { - status = acpi_ds_get_predicate_value (walk_state, !! walk_state->result_obj); + status = acpi_ds_get_predicate_value (walk_state, walk_state->result_obj); walk_state->result_obj = NULL; } @@ -586,7 +638,7 @@ if (walk_state->result_obj) { /* Break to debugger to display result */ - DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj, walk_state)); + ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj, walk_state)); /* * Delete the result op if and only if: @@ -596,12 +648,26 @@ acpi_ds_delete_result_if_not_used (op, walk_state->result_obj, walk_state); } +#ifdef _UNDER_DEVELOPMENT + + if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) { + acpi_db_method_end (walk_state); + } +#endif + /* Always clear the object stack */ - /* TBD: [Investigate] Clear stack of return value, - but don't delete it */ walk_state->num_operands = 0; +#ifdef ACPI_DISASSEMBLER + + /* On error, display method locals/args */ + + if (ACPI_FAILURE (status)) { + acpi_dm_dump_method_info (status, walk_state, op); + } +#endif + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/dispatcher/dswload.c linux-2.4.22/drivers/acpi/dispatcher/dswload.c --- linux-2.4.21/drivers/acpi/dispatcher/dswload.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dswload.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,48 +1,66 @@ /****************************************************************************** * * Module Name: dswload - Dispatcher namespace load callbacks - * $Revision: 50 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acevents.h" +#include +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dswload") + ACPI_MODULE_NAME ("dswload") /******************************************************************************* * - * FUNCTION: Acpi_ds_init_callbacks + * FUNCTION: acpi_ds_init_callbacks * - * PARAMETERS: Walk_state - Current state of the parse tree walk - * Pass_number - 1, 2, or 3 + * PARAMETERS: walk_state - Current state of the parse tree walk + * pass_number - 1, 2, or 3 * * RETURN: Status * @@ -52,8 +70,8 @@ acpi_status acpi_ds_init_callbacks ( - acpi_walk_state *walk_state, - u32 pass_number) + struct acpi_walk_state *walk_state, + u32 pass_number) { switch (pass_number) { @@ -70,14 +88,15 @@ break; case 3: +#ifndef ACPI_NO_METHOD_EXECUTION walk_state->parse_flags |= ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE; walk_state->descending_callback = acpi_ds_exec_begin_op; walk_state->ascending_callback = acpi_ds_exec_end_op; +#endif break; default: return (AE_BAD_PARAMETER); - break; } return (AE_OK); @@ -86,9 +105,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_load1_begin_op + * FUNCTION: acpi_ds_load1_begin_op * - * PARAMETERS: Walk_state - Current state of the parse tree walk + * PARAMETERS: walk_state - Current state of the parse tree walk * Op - Op that has been just been reached in the * walk; Arguments have not been evaluated yet. * @@ -100,33 +119,42 @@ acpi_status acpi_ds_load1_begin_op ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op) + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op) { - acpi_parse_object *op; - acpi_namespace_node *node; - acpi_status status; - acpi_object_type8 data_type; - NATIVE_CHAR *path; + union acpi_parse_object *op; + struct acpi_namespace_node *node; + acpi_status status; + acpi_object_type object_type; + char *path; + u32 flags; + + ACPI_FUNCTION_NAME ("ds_load1_begin_op"); - PROC_NAME ("Ds_load1_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); - /* We are only interested in opcodes that have an associated name */ - if (walk_state->op) { - if (!(walk_state->op_info->flags & AML_NAMED)) { + if (op) { + if (!(walk_state->op_info->flags & AML_NAMED)) { +#if 0 + if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || + (walk_state->op_info->class == AML_CLASS_CONTROL)) { + acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n", walk_state->op_info->name); + *out_op = op; + return (AE_CTRL_SKIP); + } +#endif *out_op = op; return (AE_OK); } /* Check if this object has already been installed in the namespace */ - if (op->node) { + if (op->common.node) { *out_op = op; return (AE_OK); } @@ -136,30 +164,117 @@ /* Map the raw opcode into an internal object type */ - data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode); - + object_type = walk_state->op_info->object_type; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); + "State=%p Op=%p [%s] ", walk_state, op, acpi_ut_get_type_name (object_type))); + switch (walk_state->opcode) { + case AML_SCOPE_OP: - if (walk_state->opcode == AML_SCOPE_OP) { - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); - } + /* + * The target name of the Scope() operator must exist at this point so + * that we can actually open the scope to enter new names underneath it. + * Allow search-to-root for single namesegs. + */ + status = acpi_ns_lookup (walk_state->scope_info, path, object_type, + ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (path, status); + return (status); + } - /* - * Enter the named type into the internal namespace. We enter the name - * as we go downward in the parse tree. Any necessary subobjects that involve - * arguments to the opcode must be created as we go back up the parse tree later. - */ - status = acpi_ns_lookup (walk_state->scope_info, path, data_type, - IMODE_LOAD_PASS1, NS_NO_UPSEARCH, walk_state, &(node)); + /* + * Check to make sure that the target is + * one of the opcodes that actually opens a scope + */ + switch (node->type) { + case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ + case ACPI_TYPE_DEVICE: + case ACPI_TYPE_POWER: + case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_THERMAL: + + /* These are acceptable types */ + break; - if (ACPI_FAILURE (status)) { - return (status); + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + + /* + * These types we will allow, but we will change the type. This + * enables some existing code of the form: + * + * Name (DEB, 0) + * Scope (DEB) { ... } + * + * Note: silently change the type here. On the second pass, we will report a warning + */ + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", + path, acpi_ut_get_type_name (node->type))); + + node->type = ACPI_TYPE_ANY; + walk_state->scope_info->common.value = ACPI_TYPE_ANY; + break; + + default: + + /* All other types are an error */ + + ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", + acpi_ut_get_type_name (node->type), path)); + + return (AE_AML_OPERAND_TYPE); + } + break; + + + default: + + /* + * For all other named opcodes, we will enter the name into the namespace. + * + * Setup the search flags. + * Since we are entering a name into the namespace, we do not want to + * enable the search-to-root upsearch. + * + * There are only two conditions where it is acceptable that the name + * already exists: + * 1) the Scope() operator can reopen a scoping object that was + * previously defined (Scope, Method, Device, etc.) + * 2) Whenever we are parsing a deferred opcode (op_region, Buffer, + * buffer_field, or Package), the name of the object is already + * in the namespace. + */ + flags = ACPI_NS_NO_UPSEARCH; + if ((walk_state->opcode != AML_SCOPE_OP) && + (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { + flags |= ACPI_NS_ERROR_IF_FOUND; + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Cannot already exist\n")); + } + else { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Both Find or Create allowed\n")); + } + + /* + * Enter the named type into the internal namespace. We enter the name + * as we go downward in the parse tree. Any necessary subobjects that involve + * arguments to the opcode must be created as we go back up the parse tree later. + */ + status = acpi_ns_lookup (walk_state->scope_info, path, object_type, + ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node)); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (path, status); + return (status); + } + break; } + + /* Common exit */ + if (!op) { /* Create a new op */ @@ -171,13 +286,18 @@ /* Initialize */ - ((acpi_parse2_object *)op)->name = node->name; + op->named.name = node->name.integer; + +#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) + op->named.path = (u8 *) path; +#endif + /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed */ - op->node = node; + op->common.node = node; acpi_ps_append_arg (acpi_ps_get_parent_scope (&walk_state->parser_state), op); *out_op = op; @@ -187,9 +307,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_load1_end_op + * FUNCTION: acpi_ds_load1_end_op * - * PARAMETERS: Walk_state - Current state of the parse tree walk + * PARAMETERS: walk_state - Current state of the parse tree walk * Op - Op that has been just been completed in the * walk; Arguments have now been evaluated. * @@ -202,57 +322,107 @@ acpi_status acpi_ds_load1_end_op ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_parse_object *op; - acpi_object_type8 data_type; + union acpi_parse_object *op; + acpi_object_type object_type; + acpi_status status = AE_OK; + + ACPI_FUNCTION_NAME ("ds_load1_end_op"); - PROC_NAME ("Ds_load1_end_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); - /* We are only interested in opcodes that have an associated name */ - if (!(walk_state->op_info->flags & AML_NAMED)) { + if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) { return (AE_OK); } - /* Get the type to determine if we should pop the scope */ + /* Get the object type to determine if we should pop the scope */ - data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode); + object_type = walk_state->op_info->object_type; - if (op->opcode == AML_NAME_OP) { - /* For Name opcode, check the argument */ +#ifndef ACPI_NO_METHOD_EXECUTION + if (walk_state->op_info->flags & AML_FIELD) { + if (walk_state->opcode == AML_FIELD_OP || + walk_state->opcode == AML_BANK_FIELD_OP || + walk_state->opcode == AML_INDEX_FIELD_OP) { + status = acpi_ds_init_field_objects (op, walk_state); + } + return (status); + } - if (op->value.arg) { - data_type = acpi_ds_map_opcode_to_data_type ( - (op->value.arg)->opcode, NULL); - ((acpi_namespace_node *)op->node)->type = - (u8) data_type; + + if (op->common.aml_opcode == AML_REGION_OP) { + status = acpi_ex_create_region (op->named.data, op->named.length, + (acpi_adr_space_type) ((op->common.value.arg)->common.value.integer), walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } + } +#endif + + if (op->common.aml_opcode == AML_NAME_OP) { + /* For Name opcode, get the object type from the argument */ + + if (op->common.value.arg) { + object_type = (acpi_ps_get_opcode_info ((op->common.value.arg)->common.aml_opcode))->object_type; + op->common.node->type = (u8) object_type; + } + } + + if (op->common.aml_opcode == AML_METHOD_OP) { + /* + * method_op pkg_length name_string method_flags term_list + * + * Note: We must create the method node/object pair as soon as we + * see the method declaration. This allows later pass1 parsing + * of invocations of the method (need to know the number of + * arguments.) + */ + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "LOADING-Method: State=%p Op=%p named_obj=%p\n", + walk_state, op, op->named.node)); + + if (!acpi_ns_get_attached_object (op->named.node)) { + walk_state->operands[0] = (void *) op->named.node; + walk_state->num_operands = 1; + + status = acpi_ds_create_operands (walk_state, op->common.value.arg); + if (ACPI_SUCCESS (status)) { + status = acpi_ex_create_method (op->named.data, + op->named.length, walk_state); + } + walk_state->operands[0] = NULL; + walk_state->num_operands = 0; + + if (ACPI_FAILURE (status)) { + return (status); + } } } /* Pop the scope stack */ - if (acpi_ns_opens_scope (data_type)) { + if (acpi_ns_opens_scope (object_type)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n", - acpi_ut_get_type_name (data_type), op)); + acpi_ut_get_type_name (object_type), op)); - acpi_ds_scope_stack_pop (walk_state); + status = acpi_ds_scope_stack_pop (walk_state); } - return (AE_OK); + return (status); } /******************************************************************************* * - * FUNCTION: Acpi_ds_load2_begin_op + * FUNCTION: acpi_ds_load2_begin_op * - * PARAMETERS: Walk_state - Current state of the parse tree walk + * PARAMETERS: walk_state - Current state of the parse tree walk * Op - Op that has been just been reached in the * walk; Arguments have not been evaluated yet. * @@ -264,35 +434,28 @@ acpi_status acpi_ds_load2_begin_op ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op) + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op) { - acpi_parse_object *op; - acpi_namespace_node *node; - acpi_status status; - acpi_object_type8 data_type; - NATIVE_CHAR *buffer_ptr; - void *original = NULL; + union acpi_parse_object *op; + struct acpi_namespace_node *node; + acpi_status status; + acpi_object_type object_type; + char *buffer_ptr; - PROC_NAME ("Ds_load2_begin_op"); + ACPI_FUNCTION_TRACE ("ds_load2_begin_op"); + op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); - if (op) { /* We only care about Namespace opcodes here */ - if (!(walk_state->op_info->flags & AML_NSOPCODE) && - walk_state->opcode != AML_INT_NAMEPATH_OP) { - return (AE_OK); - } - - /* TBD: [Restructure] Temp! same code as in psparse */ - - if (!(walk_state->op_info->flags & AML_NAMED)) { - return (AE_OK); + if ((!(walk_state->op_info->flags & AML_NSOPCODE) && (walk_state->opcode != AML_INT_NAMEPATH_OP)) || + (!(walk_state->op_info->flags & AML_NAMED))) { + return_ACPI_STATUS (AE_OK); } /* @@ -301,61 +464,125 @@ if (walk_state->opcode == AML_INT_NAMEPATH_OP) { /* For Namepath op, get the path string */ - buffer_ptr = op->value.string; + buffer_ptr = op->common.value.string; if (!buffer_ptr) { /* No name, just exit */ - return (AE_OK); + return_ACPI_STATUS (AE_OK); } } else { /* Get name from the op */ - buffer_ptr = (NATIVE_CHAR *) &((acpi_parse2_object *)op)->name; + buffer_ptr = (char *) &op->named.name; } } else { + /* Get the namestring from the raw AML */ + buffer_ptr = acpi_ps_get_next_namestring (&walk_state->parser_state); } + /* Map the opcode into an internal object type */ - /* Map the raw opcode into an internal object type */ - - data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode); + object_type = walk_state->op_info->object_type; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); + "State=%p Op=%p Type=%X\n", walk_state, op, object_type)); + + switch (walk_state->opcode) { + case AML_FIELD_OP: + case AML_BANK_FIELD_OP: + case AML_INDEX_FIELD_OP: - if (walk_state->opcode == AML_FIELD_OP || - walk_state->opcode == AML_BANK_FIELD_OP || - walk_state->opcode == AML_INDEX_FIELD_OP) { node = NULL; status = AE_OK; - } + break; + + case AML_INT_NAMEPATH_OP: - else if (walk_state->opcode == AML_INT_NAMEPATH_OP) { /* - * The Name_path is an object reference to an existing object. Don't enter the + * The name_path is an object reference to an existing object. Don't enter the * name into the namespace, but look it up for use later */ - status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type, - IMODE_EXECUTE, NS_SEARCH_PARENT, walk_state, &(node)); - } + status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, + ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); + break; - else { - if (op && op->node) { - original = op->node; - node = op->node; + case AML_SCOPE_OP: - if (acpi_ns_opens_scope (data_type)) { - status = acpi_ds_scope_stack_push (node, data_type, walk_state); + /* + * The Path is an object reference to an existing object. Don't enter the + * name into the namespace, but look it up for use later + */ + status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, + ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (buffer_ptr, status); + return_ACPI_STATUS (status); + } + /* + * We must check to make sure that the target is + * one of the opcodes that actually opens a scope + */ + switch (node->type) { + case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ + case ACPI_TYPE_DEVICE: + case ACPI_TYPE_POWER: + case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_THERMAL: + + /* These are acceptable types */ + break; + + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + + /* + * These types we will allow, but we will change the type. This + * enables some existing code of the form: + * + * Name (DEB, 0) + * Scope (DEB) { ... } + */ + + ACPI_REPORT_WARNING (("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", + buffer_ptr, acpi_ut_get_type_name (node->type))); + + node->type = ACPI_TYPE_ANY; + walk_state->scope_info->common.value = ACPI_TYPE_ANY; + break; + + default: + + /* All other types are an error */ + + ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s]\n", + acpi_ut_get_type_name (node->type), buffer_ptr)); + + return (AE_AML_OPERAND_TYPE); + } + break; + + default: + + /* All other opcodes */ + + if (op && op->common.node) { + /* This op/node was previously entered into the namespace */ + + node = op->common.node; + + if (acpi_ns_opens_scope (object_type)) { + status = acpi_ds_scope_stack_push (node, object_type, walk_state); if (ACPI_FAILURE (status)) { - return (status); + return_ACPI_STATUS (status); } } - return (AE_OK); + return_ACPI_STATUS (AE_OK); } /* @@ -363,50 +590,50 @@ * as we go downward in the parse tree. Any necessary subobjects that involve * arguments to the opcode must be created as we go back up the parse tree later. */ - status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type, - IMODE_EXECUTE, NS_NO_UPSEARCH, walk_state, &(node)); + status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, + ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, walk_state, &(node)); + break; } - if (ACPI_SUCCESS (status)) { - if (!op) { - /* Create a new op */ + if (ACPI_FAILURE (status)) { + ACPI_REPORT_NSERROR (buffer_ptr, status); + return_ACPI_STATUS (status); + } - op = acpi_ps_alloc_op (walk_state->opcode); - if (!op) { - return (AE_NO_MEMORY); - } - /* Initialize */ + if (!op) { + /* Create a new op */ - ((acpi_parse2_object *)op)->name = node->name; - *out_op = op; + op = acpi_ps_alloc_op (walk_state->opcode); + if (!op) { + return_ACPI_STATUS (AE_NO_MEMORY); } - /* - * Put the Node in the "op" object that the parser uses, so we - * can get it again quickly when this scope is closed - */ - op->node = node; - - if (original) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "old %p new %p\n", original, node)); + /* Initialize the new op */ - if (original != node) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Lookup match error: old %p new %p\n", original, node)); - } + if (node) { + op->named.name = node->name.integer; + } + if (out_op) { + *out_op = op; } } - return (status); + /* + * Put the Node in the "op" object that the parser uses, so we + * can get it again quickly when this scope is closed + */ + op->common.node = node; + + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ds_load2_end_op + * FUNCTION: acpi_ds_load2_end_op * - * PARAMETERS: Walk_state - Current state of the parse tree walk + * PARAMETERS: walk_state - Current state of the parse tree walk * Op - Op that has been just been completed in the * walk; Arguments have now been evaluated. * @@ -419,48 +646,44 @@ acpi_status acpi_ds_load2_end_op ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_parse_object *op; - acpi_status status = AE_OK; - acpi_object_type8 data_type; - acpi_namespace_node *node; - acpi_parse_object *arg; - acpi_namespace_node *new_node; - u32 i; + union acpi_parse_object *op; + acpi_status status = AE_OK; + acpi_object_type object_type; + struct acpi_namespace_node *node; + union acpi_parse_object *arg; + struct acpi_namespace_node *new_node; +#ifndef ACPI_NO_METHOD_EXECUTION + u32 i; +#endif - PROC_NAME ("Ds_load2_end_op"); + ACPI_FUNCTION_TRACE ("ds_load2_end_op"); op = walk_state->op; - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); - + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", + walk_state->op_info->name, op, walk_state)); /* Only interested in opcodes that have namespace objects */ if (!(walk_state->op_info->flags & AML_NSOBJECT)) { - return (AE_OK); + return_ACPI_STATUS (AE_OK); } - if (op->opcode == AML_SCOPE_OP) { + if (op->common.aml_opcode == AML_SCOPE_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Ending scope Op=%p State=%p\n", op, walk_state)); - - if (((acpi_parse2_object *)op)->name == -1) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n", - op, walk_state)); - return (AE_OK); - } } - data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode); + object_type = walk_state->op_info->object_type; /* * Get the Node/name from the earlier lookup * (It was saved in the *op structure) */ - node = op->node; + node = op->common.node; /* * Put the Node on the object stack (Contains the ACPI Name of @@ -471,11 +694,14 @@ /* Pop the scope stack */ - if (acpi_ns_opens_scope (data_type)) { - + if (acpi_ns_opens_scope (object_type) && (op->common.aml_opcode != AML_INT_METHODCALL_OP)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n", - acpi_ut_get_type_name (data_type), op)); - acpi_ds_scope_stack_pop (walk_state); + acpi_ut_get_type_name (object_type), op)); + + status = acpi_ds_scope_stack_pop (walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } } /* @@ -507,14 +733,16 @@ */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Create-Load [%s] State=%p Op=%p Named_obj=%p\n", - acpi_ps_get_opcode_name (op->opcode), walk_state, op, node)); + "Create-Load [%s] State=%p Op=%p named_obj=%p\n", + acpi_ps_get_opcode_name (op->common.aml_opcode), walk_state, op, node)); /* Decode the opcode */ - arg = op->value.arg; + arg = op->common.value.arg; switch (walk_state->op_info->type) { +#ifndef ACPI_NO_METHOD_EXECUTION + case AML_TYPE_CREATE_FIELD: /* @@ -527,24 +755,25 @@ case AML_TYPE_NAMED_FIELD: - arg = op->value.arg; - switch (op->opcode) { + switch (op->common.aml_opcode) { case AML_INDEX_FIELD_OP: - status = acpi_ds_create_index_field (op, (acpi_handle) arg->node, + status = acpi_ds_create_index_field (op, (acpi_handle) arg->common.node, walk_state); break; - case AML_BANK_FIELD_OP: - status = acpi_ds_create_bank_field (op, arg->node, walk_state); + status = acpi_ds_create_bank_field (op, arg->common.node, walk_state); break; - case AML_FIELD_OP: - status = acpi_ds_create_field (op, arg->node, walk_state); + status = acpi_ds_create_field (op, arg->common.node, walk_state); + break; + + default: + /* All NAMED_FIELD opcodes must be handled above */ break; } break; @@ -557,31 +786,27 @@ goto cleanup; } - switch (op->opcode) { + switch (op->common.aml_opcode) { case AML_PROCESSOR_OP: status = acpi_ex_create_processor (walk_state); break; - case AML_POWER_RES_OP: status = acpi_ex_create_power_resource (walk_state); break; - case AML_MUTEX_OP: status = acpi_ex_create_mutex (walk_state); break; - case AML_EVENT_OP: status = acpi_ex_create_event (walk_state); break; - case AML_DATA_REGION_OP: status = acpi_ex_create_table_region (walk_state); @@ -597,7 +822,6 @@ status = AE_OK; goto cleanup; - break; } /* Delete operands */ @@ -608,40 +832,32 @@ } break; - +#endif /* ACPI_NO_METHOD_EXECUTION */ case AML_TYPE_NAMED_COMPLEX: - switch (op->opcode) { - case AML_METHOD_OP: - /* - * Method_op Pkg_length Names_string Method_flags Term_list - */ - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "LOADING-Method: State=%p Op=%p Named_obj=%p\n", - walk_state, op, node)); - - if (!node->object) { - status = acpi_ds_create_operands (walk_state, arg); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - status = acpi_ex_create_method (((acpi_parse2_object *) op)->data, - ((acpi_parse2_object *) op)->length, - walk_state); - } - break; - - + switch (op->common.aml_opcode) { +#ifndef ACPI_NO_METHOD_EXECUTION case AML_REGION_OP: /* - * The Op_region is not fully parsed at this time. Only valid argument is the Space_id. + * The op_region is not fully parsed at this time. Only valid argument is the space_id. * (We must save the address of the AML of the address and length operands) */ - status = acpi_ex_create_region (((acpi_parse2_object *) op)->data, - ((acpi_parse2_object *) op)->length, - (ACPI_ADR_SPACE_TYPE) arg->value.integer, walk_state); + /* + * If we have a valid region, initialize it + * Namespace is NOT locked at this point. + */ + status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node), FALSE); + if (ACPI_FAILURE (status)) { + /* + * If AE_NOT_EXIST is returned, it is not fatal + * because many regions get created before a handler + * is installed for said region. + */ + if (AE_NOT_EXIST == status) { + status = AE_OK; + } + } break; @@ -649,6 +865,13 @@ status = acpi_ds_create_node (walk_state, node, op); break; +#endif /* ACPI_NO_METHOD_EXECUTION */ + + + default: + /* All NAMED_COMPLEX opcodes must be handled above */ + /* Note: Method objects were already created in Pass 1 */ + break; } break; @@ -662,29 +885,34 @@ case AML_CLASS_METHOD_CALL: ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "RESOLVING-Method_call: State=%p Op=%p Named_obj=%p\n", + "RESOLVING-method_call: State=%p Op=%p named_obj=%p\n", walk_state, op, node)); /* * Lookup the method name and save the Node */ - status = acpi_ns_lookup (walk_state->scope_info, arg->value.string, - ACPI_TYPE_ANY, IMODE_LOAD_PASS2, - NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, + status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string, + ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, walk_state, &(new_node)); if (ACPI_SUCCESS (status)) { - /* TBD: has name already been resolved by here ??*/ - - /* TBD: [Restructure] Make sure that what we found is indeed a method! */ - /* We didn't search for a method on purpose, to see if the name would resolve! */ + /* + * Make sure that what we found is indeed a method + * We didn't search for a method on purpose, to see if the name would resolve + */ + if (new_node->type != ACPI_TYPE_METHOD) { + status = AE_AML_OPERAND_TYPE; + } /* We could put the returned object (Node) on the object stack for later, but * for now, we will put it in the "op" object that the parser uses, so we * can get it again at the end of this scope */ - op->node = new_node; + op->common.node = new_node; + } + else { + ACPI_REPORT_NSERROR (arg->common.value.string, status); } - break; @@ -692,14 +920,13 @@ break; } - cleanup: /* Remove the Node pushed at the very beginning */ walk_state->operands[0] = NULL; walk_state->num_operands = 0; - return (status); + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/dispatcher/dswscope.c linux-2.4.22/drivers/acpi/dispatcher/dswscope.c --- linux-2.4.21/drivers/acpi/dispatcher/dswscope.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dswscope.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,36 +1,53 @@ /****************************************************************************** * * Module Name: dswscope - Scope stack manipulation - * $Revision: 49 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acdispat.h" +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dswscope") + ACPI_MODULE_NAME ("dswscope") #define STACK_POP(head) head @@ -38,7 +55,7 @@ /**************************************************************************** * - * FUNCTION: Acpi_ds_scope_stack_clear + * FUNCTION: acpi_ds_scope_stack_clear * * PARAMETERS: None * @@ -49,11 +66,11 @@ void acpi_ds_scope_stack_clear ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_generic_state *scope_info; + union acpi_generic_state *scope_info; - PROC_NAME ("Ds_scope_stack_clear"); + ACPI_FUNCTION_NAME ("ds_scope_stack_clear"); while (walk_state->scope_info) { @@ -63,7 +80,7 @@ walk_state->scope_info = scope_info->scope.next; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Popped object type %X\n", scope_info->common.value)); + "Popped object type (%s)\n", acpi_ut_get_type_name (scope_info->common.value))); acpi_ut_delete_generic_state (scope_info); } } @@ -71,7 +88,7 @@ /**************************************************************************** * - * FUNCTION: Acpi_ds_scope_stack_push + * FUNCTION: acpi_ds_scope_stack_push * * PARAMETERS: *Node, - Name to be made current * Type, - Type of frame being pushed @@ -83,27 +100,28 @@ acpi_status acpi_ds_scope_stack_push ( - acpi_namespace_node *node, - acpi_object_type8 type, - acpi_walk_state *walk_state) + struct acpi_namespace_node *node, + acpi_object_type type, + struct acpi_walk_state *walk_state) { - acpi_generic_state *scope_info; + union acpi_generic_state *scope_info; + union acpi_generic_state *old_scope_info; - FUNCTION_TRACE ("Ds_scope_stack_push"); + ACPI_FUNCTION_TRACE ("ds_scope_stack_push"); if (!node) { /* Invalid scope */ - REPORT_ERROR (("Ds_scope_stack_push: null scope passed\n")); + ACPI_REPORT_ERROR (("ds_scope_stack_push: null scope passed\n")); return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Make sure object type is valid */ - if (!acpi_ex_validate_object_type (type)) { - REPORT_WARNING (("Ds_scope_stack_push: type code out of range\n")); + if (!acpi_ut_valid_object_type (type)) { + ACPI_REPORT_WARNING (("ds_scope_stack_push: type code out of range\n")); } @@ -120,6 +138,28 @@ scope_info->scope.node = node; scope_info->common.value = (u16) type; + walk_state->scope_depth++; + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "[%.2d] Pushed scope ", (u32) walk_state->scope_depth)); + + old_scope_info = walk_state->scope_info; + if (old_scope_info) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, + "[%4.4s] (%10s)", + old_scope_info->scope.node->name.ascii, + acpi_ut_get_type_name (old_scope_info->common.value))); + } + else { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, + "[\\___] (%10s)", "ROOT")); + } + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, + ", New scope -> [%4.4s] (%s)\n", + scope_info->scope.node->name.ascii, + acpi_ut_get_type_name (scope_info->common.value))); + /* Push new scope object onto stack */ acpi_ut_push_generic_state (&walk_state->scope_info, scope_info); @@ -130,7 +170,7 @@ /**************************************************************************** * - * FUNCTION: Acpi_ds_scope_stack_pop + * FUNCTION: acpi_ds_scope_stack_pop * * PARAMETERS: Type - The type of frame to be found * @@ -147,12 +187,13 @@ acpi_status acpi_ds_scope_stack_pop ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_generic_state *scope_info; + union acpi_generic_state *scope_info; + union acpi_generic_state *new_scope_info; - FUNCTION_TRACE ("Ds_scope_stack_pop"); + ACPI_FUNCTION_TRACE ("ds_scope_stack_pop"); /* @@ -163,8 +204,25 @@ return_ACPI_STATUS (AE_STACK_UNDERFLOW); } + walk_state->scope_depth--; + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Popped object type %X\n", scope_info->common.value)); + "[%.2d] Popped scope [%4.4s] (%10s), New scope -> ", + (u32) walk_state->scope_depth, + scope_info->scope.node->name.ascii, + acpi_ut_get_type_name (scope_info->common.value))); + + new_scope_info = walk_state->scope_info; + if (new_scope_info) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, + "[%4.4s] (%s)\n", + new_scope_info->scope.node->name.ascii, + acpi_ut_get_type_name (new_scope_info->common.value))); + } + else { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, + "[\\___] (ROOT)\n")); + } acpi_ut_delete_generic_state (scope_info); diff -urN linux-2.4.21/drivers/acpi/dispatcher/dswstate.c linux-2.4.22/drivers/acpi/dispatcher/dswstate.c --- linux-2.4.21/drivers/acpi/dispatcher/dswstate.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/dispatcher/dswstate.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,46 +1,62 @@ /****************************************************************************** * * Module Name: dswstate - Dispatcher parse tree walk management routines - * $Revision: 54 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acparser.h" -#include "acdispat.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_DISPATCHER - MODULE_NAME ("dswstate") + ACPI_MODULE_NAME ("dswstate") /******************************************************************************* * - * FUNCTION: Acpi_ds_result_insert + * FUNCTION: acpi_ds_result_insert * * PARAMETERS: Object - Object to push - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * @@ -50,14 +66,14 @@ acpi_status acpi_ds_result_insert ( - void *object, - u32 index, - acpi_walk_state *walk_state) + void *object, + u32 index, + struct acpi_walk_state *walk_state) { - acpi_generic_state *state; + union acpi_generic_state *state; - PROC_NAME ("Ds_result_insert"); + ACPI_FUNCTION_NAME ("ds_result_insert"); state = walk_state->results; @@ -67,7 +83,7 @@ return (AE_NOT_EXIST); } - if (index >= OBJ_NUM_OPERANDS) { + if (index >= ACPI_OBJ_NUM_OPERANDS) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index out of range: %X Obj=%p State=%p Num=%X\n", index, object, walk_state, state->results.num_results)); @@ -86,7 +102,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", - object, object ? acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type) : "NULL", + object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL", walk_state, state->results.num_results, walk_state->current_result)); return (AE_OK); @@ -95,10 +111,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_remove + * FUNCTION: acpi_ds_result_remove * * PARAMETERS: Object - Where to return the popped object - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * @@ -109,14 +125,14 @@ acpi_status acpi_ds_result_remove ( - acpi_operand_object **object, - u32 index, - acpi_walk_state *walk_state) + union acpi_operand_object **object, + u32 index, + struct acpi_walk_state *walk_state) { - acpi_generic_state *state; + union acpi_generic_state *state; - PROC_NAME ("Ds_result_remove"); + ACPI_FUNCTION_NAME ("ds_result_remove"); state = walk_state->results; @@ -126,13 +142,12 @@ return (AE_NOT_EXIST); } - if (index >= OBJ_NUM_OPERANDS) { + if (index >= ACPI_OBJ_MAX_OPERAND) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index out of range: %X State=%p Num=%X\n", index, walk_state, state->results.num_results)); } - /* Check for a valid result object */ if (!state->results.obj_desc [index]) { @@ -151,7 +166,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n", - *object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL", + *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL", index, walk_state, state->results.num_results)); return (AE_OK); @@ -160,10 +175,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_pop + * FUNCTION: acpi_ds_result_pop * * PARAMETERS: Object - Where to return the popped object - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * @@ -174,14 +189,14 @@ acpi_status acpi_ds_result_pop ( - acpi_operand_object **object, - acpi_walk_state *walk_state) + union acpi_operand_object **object, + struct acpi_walk_state *walk_state) { - u32 index; - acpi_generic_state *state; + acpi_native_uint index; + union acpi_generic_state *state; - PROC_NAME ("Ds_result_pop"); + ACPI_FUNCTION_NAME ("ds_result_pop"); state = walk_state->results; @@ -199,7 +214,7 @@ state->results.num_results--; - for (index = OBJ_NUM_OPERANDS; index; index--) { + for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) { /* Check for a valid result object */ if (state->results.obj_desc [index -1]) { @@ -207,8 +222,8 @@ state->results.obj_desc [index -1] = NULL; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n", - *object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL", - index -1, walk_state, state->results.num_results)); + *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL", + (u32) index -1, walk_state, state->results.num_results)); return (AE_OK); } @@ -220,10 +235,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_pop_from_bottom + * FUNCTION: acpi_ds_result_pop_from_bottom * * PARAMETERS: Object - Where to return the popped object - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * @@ -234,14 +249,14 @@ acpi_status acpi_ds_result_pop_from_bottom ( - acpi_operand_object **object, - acpi_walk_state *walk_state) + union acpi_operand_object **object, + struct acpi_walk_state *walk_state) { - u32 index; - acpi_generic_state *state; + acpi_native_uint index; + union acpi_generic_state *state; - PROC_NAME ("Ds_result_pop_from_bottom"); + ACPI_FUNCTION_NAME ("ds_result_pop_from_bottom"); state = walk_state->results; @@ -251,7 +266,6 @@ return (AE_NOT_EXIST); } - if (!state->results.num_results) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state)); return (AE_AML_NO_RETURN_VALUE); @@ -273,12 +287,12 @@ if (!*object) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n", - walk_state, state->results.num_results, index)); + walk_state, state->results.num_results, (u32) index)); return (AE_AML_NO_RETURN_VALUE); } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n", - *object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL", + *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL", state, walk_state)); @@ -288,10 +302,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_push + * FUNCTION: acpi_ds_result_push * * PARAMETERS: Object - Where to return the popped object - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * @@ -301,13 +315,13 @@ acpi_status acpi_ds_result_push ( - acpi_operand_object *object, - acpi_walk_state *walk_state) + union acpi_operand_object *object, + struct acpi_walk_state *walk_state) { - acpi_generic_state *state; + union acpi_generic_state *state; - PROC_NAME ("Ds_result_push"); + ACPI_FUNCTION_NAME ("ds_result_push"); state = walk_state->results; @@ -316,7 +330,7 @@ return (AE_AML_INTERNAL); } - if (state->results.num_results == OBJ_NUM_OPERANDS) { + if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack overflow: Obj=%p State=%p Num=%X\n", object, walk_state, state->results.num_results)); @@ -329,12 +343,11 @@ return (AE_BAD_PARAMETER); } - state->results.obj_desc [state->results.num_results] = object; state->results.num_results++; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", - object, object ? acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type) : "NULL", + object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL", walk_state, state->results.num_results, walk_state->current_result)); return (AE_OK); @@ -343,24 +356,24 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_stack_push + * FUNCTION: acpi_ds_result_stack_push * * PARAMETERS: Object - Object to push - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Push an object onto the walk_state result stack. * ******************************************************************************/ acpi_status acpi_ds_result_stack_push ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_generic_state *state; + union acpi_generic_state *state; - PROC_NAME ("Ds_result_stack_push"); + ACPI_FUNCTION_NAME ("ds_result_stack_push"); state = acpi_ut_create_generic_state (); @@ -380,23 +393,23 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_stack_pop + * FUNCTION: acpi_ds_result_stack_pop * - * PARAMETERS: Walk_state - Current Walk state + * PARAMETERS: walk_state - Current Walk state * * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Pop an object off of the walk_state result stack. * ******************************************************************************/ acpi_status acpi_ds_result_stack_pop ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_generic_state *state; + union acpi_generic_state *state; - PROC_NAME ("Ds_result_stack_pop"); + ACPI_FUNCTION_NAME ("ds_result_stack_pop"); /* Check for stack underflow */ @@ -411,7 +424,7 @@ state = acpi_ut_pop_generic_state (&walk_state->results); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Result=%p Remaining_results=%X State=%p\n", + "Result=%p remaining_results=%X State=%p\n", state, state->results.num_results, walk_state)); acpi_ut_delete_generic_state (state); @@ -422,9 +435,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_obj_stack_delete_all + * FUNCTION: acpi_ds_obj_stack_delete_all * - * PARAMETERS: Walk_state - Current Walk state + * PARAMETERS: walk_state - Current Walk state * * RETURN: Status * @@ -435,17 +448,17 @@ acpi_status acpi_ds_obj_stack_delete_all ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - u32 i; + u32 i; - FUNCTION_TRACE_PTR ("Ds_obj_stack_delete_all", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state); /* The stack size is configurable, but fixed */ - for (i = 0; i < OBJ_NUM_OPERANDS; i++) { + for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) { if (walk_state->operands[i]) { acpi_ut_remove_reference (walk_state->operands[i]); walk_state->operands[i] = NULL; @@ -458,10 +471,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_obj_stack_push + * FUNCTION: acpi_ds_obj_stack_push * * PARAMETERS: Object - Object to push - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * @@ -471,15 +484,15 @@ acpi_status acpi_ds_obj_stack_push ( - void *object, - acpi_walk_state *walk_state) + void *object, + struct acpi_walk_state *walk_state) { - PROC_NAME ("Ds_obj_stack_push"); + ACPI_FUNCTION_NAME ("ds_obj_stack_push"); /* Check for stack overflow */ - if (walk_state->num_operands >= OBJ_NUM_OPERANDS) { + if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "overflow! Obj=%p State=%p #Ops=%X\n", object, walk_state, walk_state->num_operands)); @@ -492,7 +505,7 @@ walk_state->num_operands++; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", - object, acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type), + object, acpi_ut_get_object_type_name ((union acpi_operand_object *) object), walk_state, walk_state->num_operands)); return (AE_OK); @@ -502,10 +515,10 @@ #if 0 /******************************************************************************* * - * FUNCTION: Acpi_ds_obj_stack_pop_object + * FUNCTION: acpi_ds_obj_stack_pop_object * - * PARAMETERS: Pop_count - Number of objects/entries to pop - * Walk_state - Current Walk state + * PARAMETERS: pop_count - Number of objects/entries to pop + * walk_state - Current Walk state * * RETURN: Status * @@ -516,10 +529,10 @@ acpi_status acpi_ds_obj_stack_pop_object ( - acpi_operand_object **object, - acpi_walk_state *walk_state) + union acpi_operand_object **object, + struct acpi_walk_state *walk_state) { - PROC_NAME ("Ds_obj_stack_pop_object"); + ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object"); /* Check for stack underflow */ @@ -552,7 +565,7 @@ walk_state->operands [walk_state->num_operands] = NULL; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", - *object, acpi_ut_get_type_name ((*object)->common.type), + *object, acpi_ut_get_object_type_name (*object), walk_state, walk_state->num_operands)); return (AE_OK); @@ -561,10 +574,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_obj_stack_pop + * FUNCTION: acpi_ds_obj_stack_pop * - * PARAMETERS: Pop_count - Number of objects/entries to pop - * Walk_state - Current Walk state + * PARAMETERS: pop_count - Number of objects/entries to pop + * walk_state - Current Walk state * * RETURN: Status * @@ -575,12 +588,12 @@ acpi_status acpi_ds_obj_stack_pop ( - u32 pop_count, - acpi_walk_state *walk_state) + u32 pop_count, + struct acpi_walk_state *walk_state) { - u32 i; + u32 i; - PROC_NAME ("Ds_obj_stack_pop"); + ACPI_FUNCTION_NAME ("ds_obj_stack_pop"); for (i = 0; i < pop_count; i++) { @@ -608,10 +621,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_obj_stack_pop_and_delete + * FUNCTION: acpi_ds_obj_stack_pop_and_delete * - * PARAMETERS: Pop_count - Number of objects/entries to pop - * Walk_state - Current Walk state + * PARAMETERS: pop_count - Number of objects/entries to pop + * walk_state - Current Walk state * * RETURN: Status * @@ -622,13 +635,13 @@ acpi_status acpi_ds_obj_stack_pop_and_delete ( - u32 pop_count, - acpi_walk_state *walk_state) + u32 pop_count, + struct acpi_walk_state *walk_state) { - u32 i; - acpi_operand_object *obj_desc; + u32 i; + union acpi_operand_object *obj_desc; - PROC_NAME ("Ds_obj_stack_pop_and_delete"); + ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete"); for (i = 0; i < pop_count; i++) { @@ -660,11 +673,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_obj_stack_get_value + * FUNCTION: acpi_ds_obj_stack_get_value * * PARAMETERS: Index - Stack index whose value is desired. Based * on the top of the stack (index=0 == top) - * Walk_state - Current Walk state + * walk_state - Current Walk state * * RETURN: Status * @@ -675,11 +688,11 @@ void * acpi_ds_obj_stack_get_value ( - u32 index, - acpi_walk_state *walk_state) + u32 index, + struct acpi_walk_state *walk_state) { - FUNCTION_TRACE_PTR ("Ds_obj_stack_get_value", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state); /* Can't do it if the stack is empty */ @@ -694,67 +707,66 @@ return_PTR (NULL); } - - return_PTR (walk_state->operands[(NATIVE_UINT)(walk_state->num_operands - 1) - + return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) - index]); } /******************************************************************************* * - * FUNCTION: Acpi_ds_get_current_walk_state + * FUNCTION: acpi_ds_get_current_walk_state * - * PARAMETERS: Walk_list - Get current active state for this walk list + * PARAMETERS: Thread - Get current active state for this Thread * * RETURN: Pointer to the current walk state * * DESCRIPTION: Get the walk state that is at the head of the list (the "current" - * walk state. + * walk state.) * ******************************************************************************/ -acpi_walk_state * +struct acpi_walk_state * acpi_ds_get_current_walk_state ( - acpi_walk_list *walk_list) + struct acpi_thread_state *thread) { - PROC_NAME ("Ds_get_current_walk_state"); - + ACPI_FUNCTION_NAME ("ds_get_current_walk_state"); - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Ds_get_current_walk_state, =%p\n", - walk_list->walk_state)); - if (!walk_list) { + if (!thread) { return (NULL); } - return (walk_list->walk_state); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current walk_state %p\n", + thread->walk_state_list)); + + return (thread->walk_state_list); } /******************************************************************************* * - * FUNCTION: Acpi_ds_push_walk_state + * FUNCTION: acpi_ds_push_walk_state * - * PARAMETERS: Walk_state - State to push - * Walk_list - The list that owns the walk stack + * PARAMETERS: walk_state - State to push + * walk_list - The list that owns the walk stack * * RETURN: None * - * DESCRIPTION: Place the Walk_state at the head of the state list. + * DESCRIPTION: Place the walk_state at the head of the state list. * ******************************************************************************/ void acpi_ds_push_walk_state ( - acpi_walk_state *walk_state, - acpi_walk_list *walk_list) + struct acpi_walk_state *walk_state, + struct acpi_thread_state *thread) { - FUNCTION_TRACE ("Ds_push_walk_state"); + ACPI_FUNCTION_TRACE ("ds_push_walk_state"); - walk_state->next = walk_list->walk_state; - walk_list->walk_state = walk_state; + walk_state->next = thread->walk_state_list; + thread->walk_state_list = walk_state; return_VOID; } @@ -762,11 +774,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_pop_walk_state + * FUNCTION: acpi_ds_pop_walk_state * - * PARAMETERS: Walk_list - The list that owns the walk stack + * PARAMETERS: walk_list - The list that owns the walk stack * - * RETURN: A Walk_state object popped from the stack + * RETURN: A walk_state object popped from the stack * * DESCRIPTION: Remove and return the walkstate object that is at the head of * the walk stack for the given walk list. NULL indicates that @@ -774,27 +786,27 @@ * ******************************************************************************/ -acpi_walk_state * +struct acpi_walk_state * acpi_ds_pop_walk_state ( - acpi_walk_list *walk_list) + struct acpi_thread_state *thread) { - acpi_walk_state *walk_state; + struct acpi_walk_state *walk_state; - FUNCTION_TRACE ("Ds_pop_walk_state"); + ACPI_FUNCTION_TRACE ("ds_pop_walk_state"); - walk_state = walk_list->walk_state; + walk_state = thread->walk_state_list; if (walk_state) { /* Next walk state becomes the current walk state */ - walk_list->walk_state = walk_state->next; + thread->walk_state_list = walk_state->next; /* * Don't clear the NEXT field, this serves as an indicator * that there is a parent WALK STATE - * Walk_state->Next = NULL; + * NO: walk_state->Next = NULL; */ } @@ -804,30 +816,30 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_create_walk_state + * FUNCTION: acpi_ds_create_walk_state * * PARAMETERS: Origin - Starting point for this walk - * Walk_list - Owning walk list + * Thread - Current thread state * * RETURN: Pointer to the new walk state. * - * DESCRIPTION: Allocate and initialize a new walk state. The current walk state - * is set to this new state. + * DESCRIPTION: Allocate and initialize a new walk state. The current walk + * state is set to this new state. * ******************************************************************************/ -acpi_walk_state * +struct acpi_walk_state * acpi_ds_create_walk_state ( - acpi_owner_id owner_id, - acpi_parse_object *origin, - acpi_operand_object *mth_desc, - acpi_walk_list *walk_list) + acpi_owner_id owner_id, + union acpi_parse_object *origin, + union acpi_operand_object *mth_desc, + struct acpi_thread_state *thread) { - acpi_walk_state *walk_state; - acpi_status status; + struct acpi_walk_state *walk_state; + acpi_status status; - FUNCTION_TRACE ("Ds_create_walk_state"); + ACPI_FUNCTION_TRACE ("ds_create_walk_state"); walk_state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_WALK); @@ -839,11 +851,13 @@ walk_state->owner_id = owner_id; walk_state->origin = origin; walk_state->method_desc = mth_desc; - walk_state->walk_list = walk_list; + walk_state->thread = thread; + + walk_state->parser_state.start_op = origin; /* Init the method args/local */ -#ifndef _ACPI_ASL_COMPILER +#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) acpi_ds_method_data_init (walk_state); #endif @@ -856,20 +870,19 @@ /* Put the new state at the head of the walk list */ - if (walk_list) { - acpi_ds_push_walk_state (walk_state, walk_list); + if (thread) { + acpi_ds_push_walk_state (walk_state, thread); } return_PTR (walk_state); } -#ifndef _ACPI_ASL_COMPILER /******************************************************************************* * - * FUNCTION: Acpi_ds_init_aml_walk + * FUNCTION: acpi_ds_init_aml_walk * - * PARAMETERS: Walk_state - New state to be initialized + * PARAMETERS: walk_state - New state to be initialized * * RETURN: None * @@ -879,20 +892,21 @@ acpi_status acpi_ds_init_aml_walk ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_namespace_node *method_node, - u8 *aml_start, - u32 aml_length, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc, - u32 pass_number) + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + struct acpi_namespace_node *method_node, + u8 *aml_start, + u32 aml_length, + union acpi_operand_object **params, + union acpi_operand_object **return_obj_desc, + u32 pass_number) { - acpi_status status; - acpi_parse_state *parser_state = &walk_state->parser_state; + acpi_status status; + struct acpi_parse_state *parser_state = &walk_state->parser_state; + union acpi_parse_object *extra_op; - FUNCTION_TRACE ("Ds_init_aml_walk"); + ACPI_FUNCTION_TRACE ("ds_init_aml_walk"); walk_state->parser_state.aml = @@ -900,8 +914,7 @@ walk_state->parser_state.aml_end = walk_state->parser_state.pkg_end = aml_start + aml_length; - /* The Next_op of the Next_walk will be the beginning of the method */ - /* TBD: [Restructure] -- obsolete? */ + /* The next_op of the next_walk will be the beginning of the method */ walk_state->next_op = NULL; walk_state->params = params; @@ -914,11 +927,10 @@ if (method_node) { walk_state->parser_state.start_node = method_node; - walk_state->walk_type = WALK_METHOD; + walk_state->walk_type = ACPI_WALK_METHOD; walk_state->method_node = method_node; walk_state->method_desc = acpi_ns_get_attached_object (method_node); - /* Push start scope on scope stack and make it current */ status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state); @@ -928,13 +940,29 @@ /* Init the method arguments */ - acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state); + status = acpi_ds_method_data_init_args (params, ACPI_METHOD_NUM_ARGS, walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - else { - /* Setup the current scope */ + /* + * Setup the current scope. + * Find a Named Op that has a namespace node associated with it. + * search upwards from this Op. Current scope is the first + * Op with a namespace node. + */ + extra_op = parser_state->start_op; + while (extra_op && !extra_op->common.node) { + extra_op = extra_op->common.parent; + } + if (!extra_op) { + parser_state->start_node = NULL; + } + else { + parser_state->start_node = extra_op->common.node; + } - parser_state->start_node = parser_state->start_op->node; if (parser_state->start_node) { /* Push start scope on scope stack and make it current */ @@ -946,18 +974,16 @@ } } - acpi_ds_init_callbacks (walk_state, pass_number); - - return_ACPI_STATUS (AE_OK); + status = acpi_ds_init_callbacks (walk_state, pass_number); + return_ACPI_STATUS (status); } -#endif /******************************************************************************* * - * FUNCTION: Acpi_ds_delete_walk_state + * FUNCTION: acpi_ds_delete_walk_state * - * PARAMETERS: Walk_state - State to delete + * PARAMETERS: walk_state - State to delete * * RETURN: Status * @@ -967,12 +993,12 @@ void acpi_ds_delete_walk_state ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_TRACE_PTR ("Ds_delete_walk_state", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_delete_walk_state", walk_state); if (!walk_state) { @@ -984,7 +1010,6 @@ return; } - if (walk_state->parser_state.scope) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state)); } @@ -1023,7 +1048,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_ds_delete_walk_state_cache + * FUNCTION: acpi_ds_delete_walk_state_cache * * PARAMETERS: None * @@ -1038,7 +1063,7 @@ acpi_ds_delete_walk_state_cache ( void) { - FUNCTION_TRACE ("Ds_delete_walk_state_cache"); + ACPI_FUNCTION_TRACE ("ds_delete_walk_state_cache"); acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK); diff -urN linux-2.4.21/drivers/acpi/driver.c linux-2.4.22/drivers/acpi/driver.c --- linux-2.4.21/drivers/acpi/driver.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/driver.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,217 +0,0 @@ -/* - * driver.c - ACPI driver - * - * Copyright (C) 2000 Andrew Henroid - * Copyright (C) 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - */ -/* - * Changes - * David Woodhouse 2000-12-6 - * - Fix interruptible_sleep_on() races - * Andrew Grover 2001-2-28 - * - Major revamping - * Peter Breuer 2001-5-20 - * - parse boot time params. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi.h" - - -#define _COMPONENT OS_DEPENDENT - MODULE_NAME ("driver") - -FADT_DESCRIPTOR acpi_fadt; - -static int acpi_disabled = 0; - -enum acpi_blacklist_predicates -{ - all_versions, - less_than_or_equal, - equal, - greater_than_or_equal, -}; - -struct acpi_blacklist_item -{ - char oem_id[7]; - char oem_table_id[9]; - u32 oem_revision; - enum acpi_blacklist_predicates oem_revision_predicate; -}; - -/* - * Currently, this blacklists based on items in the FADT. We may want to - * expand this to using other ACPI tables in the future, too. - */ -static struct acpi_blacklist_item acpi_blacklist[] __initdata = -{ - {"TOSHIB", "750 ", 0x970814, less_than_or_equal}, /* Portege 7020, BIOS 8.10 */ - {""} -}; - -int -acpi_blacklisted(FADT_DESCRIPTOR *fadt) -{ - int i = 0; - - while (acpi_blacklist[i].oem_id[0] != '\0') - { - if (strncmp(acpi_blacklist[i].oem_id, fadt->header.oem_id, 6)) { - i++; - continue; - } - - if (strncmp(acpi_blacklist[i].oem_table_id, fadt->header.oem_table_id, 8)) { - i++; - continue; - } - - if (acpi_blacklist[i].oem_revision_predicate == all_versions) - return TRUE; - - if (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal - && fadt->header.oem_revision <= acpi_blacklist[i].oem_revision) - return TRUE; - - if (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal - && fadt->header.oem_revision >= acpi_blacklist[i].oem_revision) - return TRUE; - - if (acpi_blacklist[i].oem_revision_predicate == equal - && fadt->header.oem_revision == acpi_blacklist[i].oem_revision) - return TRUE; - - i++; - } - - return FALSE; -} - -/* - * Start the interpreter - */ -int -acpi_init(void) -{ - acpi_buffer buffer; - acpi_system_info sys_info; - - if (PM_IS_ACTIVE()) { - printk(KERN_NOTICE "ACPI: APM is already active, exiting\n"); - return -ENODEV; - } - - if (acpi_disabled) { - printk(KERN_NOTICE "ACPI: disabled by cmdline, exiting\n"); - return -ENODEV; - } - - if (!ACPI_SUCCESS(acpi_initialize_subsystem())) { - printk(KERN_ERR "ACPI: Driver initialization failed\n"); - return -ENODEV; - } - - /* from this point on, on error we must call acpi_terminate() */ - if (!ACPI_SUCCESS(acpi_load_tables())) { - printk(KERN_ERR "ACPI: System description table load failed\n"); - acpi_terminate(); - return -ENODEV; - } - - /* get a separate copy of the FADT for use by other drivers */ - memset(&acpi_fadt, 0, sizeof(acpi_fadt)); - buffer.pointer = &acpi_fadt; - buffer.length = sizeof(acpi_fadt); - - if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FADT, 1, &buffer))) { - printk(KERN_ERR "ACPI: Could not get FADT\n"); - acpi_terminate(); - return -ENODEV; - } - - if (acpi_blacklisted(&acpi_fadt)) { - printk(KERN_ERR "ACPI: On blacklist -- BIOS not fully ACPI compliant\n"); - acpi_terminate(); - return -ENODEV; - } - - buffer.length = sizeof(sys_info); - buffer.pointer = &sys_info; - - if (!ACPI_SUCCESS (acpi_get_system_info(&buffer))) { - printk(KERN_ERR "ACPI: Could not get system info\n"); - acpi_terminate(); - return -ENODEV; - } - - printk(KERN_INFO "ACPI: Core Subsystem version [%x]\n", sys_info.acpi_ca_version); - - if (!ACPI_SUCCESS(acpi_enable_subsystem(ACPI_FULL_INITIALIZATION))) { - printk(KERN_ERR "ACPI: Subsystem enable failed\n"); - acpi_terminate(); - return -ENODEV; - } - - printk(KERN_INFO "ACPI: Subsystem enabled\n"); - - pm_active = 1; - - return 0; -} - -/* - * Terminate the interpreter - */ -void -acpi_exit(void) -{ - acpi_terminate(); - - pm_active = 0; - - printk(KERN_ERR "ACPI: Subsystem disabled\n"); -} - -module_init(acpi_init); -module_exit(acpi_exit); - -#ifndef MODULE -static int __init acpi_setup(char *str) { - while (str && *str) { - if (strncmp(str, "off", 3) == 0) - acpi_disabled = 1; - str = strchr(str, ','); - if (str) - str += strspn(str, ", \t"); - } - return 1; -} - -__setup("acpi=", acpi_setup); -#endif diff -urN linux-2.4.21/drivers/acpi/ec.c linux-2.4.22/drivers/acpi/ec.c --- linux-2.4.21/drivers/acpi/ec.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ec.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,859 @@ +/* + * acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 36 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_EC_COMPONENT +ACPI_MODULE_NAME ("acpi_ec") + +#define PREFIX "ACPI: " + + +#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ +#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ +#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ + +#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ +#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ + +#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ +#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ +#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ + +#define ACPI_EC_COMMAND_READ 0x80 +#define ACPI_EC_COMMAND_WRITE 0x81 +#define ACPI_EC_COMMAND_QUERY 0x84 + +static int acpi_ec_add (struct acpi_device *device); +static int acpi_ec_remove (struct acpi_device *device, int type); +static int acpi_ec_start (struct acpi_device *device); +static int acpi_ec_stop (struct acpi_device *device, int type); + +static struct acpi_driver acpi_ec_driver = { + .name = ACPI_EC_DRIVER_NAME, + .class = ACPI_EC_CLASS, + .ids = ACPI_EC_HID, + .ops = { + .add = acpi_ec_add, + .remove = acpi_ec_remove, + .start = acpi_ec_start, + .stop = acpi_ec_stop, + }, +}; + +struct acpi_ec { + acpi_handle handle; + unsigned long uid; + unsigned long gpe_bit; + struct acpi_generic_address status_addr; + struct acpi_generic_address command_addr; + struct acpi_generic_address data_addr; + unsigned long global_lock; + spinlock_t lock; +}; + +/* If we find an EC via the ECDT, we need to keep a ptr to its context */ +static struct acpi_ec *ec_ecdt; + +/* External interfaces use first EC only, so remember */ +static struct acpi_device *first_ec; + +/* -------------------------------------------------------------------------- + Transaction Management + -------------------------------------------------------------------------- */ + +static int +acpi_ec_wait ( + struct acpi_ec *ec, + u8 event) +{ + u32 acpi_ec_status = 0; + u32 i = ACPI_EC_UDELAY_COUNT; + + if (!ec) + return -EINVAL; + + /* Poll the EC status register waiting for the event to occur. */ + switch (event) { + case ACPI_EC_EVENT_OBF: + do { + acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); + if (acpi_ec_status & ACPI_EC_FLAG_OBF) + return 0; + udelay(ACPI_EC_UDELAY); + } while (--i>0); + break; + case ACPI_EC_EVENT_IBE: + do { + acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); + if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) + return 0; + udelay(ACPI_EC_UDELAY); + } while (--i>0); + break; + default: + return -EINVAL; + } + + return -ETIME; +} + + +static int +acpi_ec_read ( + struct acpi_ec *ec, + u8 address, + u32 *data) +{ + acpi_status status = AE_OK; + int result = 0; + unsigned long flags = 0; + u32 glk = 0; + + ACPI_FUNCTION_TRACE("acpi_ec_read"); + + if (!ec || !data) + return_VALUE(-EINVAL); + + *data = 0; + + if (ec->global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + } + + spin_lock_irqsave(&ec->lock, flags); + + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; + + acpi_hw_low_level_write(8, address, &ec->data_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); + if (result) + goto end; + + + acpi_hw_low_level_read(8, data, &ec->data_addr); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", + *data, address)); + +end: + spin_unlock_irqrestore(&ec->lock, flags); + + if (ec->global_lock) + acpi_release_global_lock(glk); + + return_VALUE(result); +} + + +static int +acpi_ec_write ( + struct acpi_ec *ec, + u8 address, + u8 data) +{ + int result = 0; + acpi_status status = AE_OK; + unsigned long flags = 0; + u32 glk = 0; + + ACPI_FUNCTION_TRACE("acpi_ec_write"); + + if (!ec) + return_VALUE(-EINVAL); + + if (ec->global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + } + + spin_lock_irqsave(&ec->lock, flags); + + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; + + acpi_hw_low_level_write(8, address, &ec->data_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; + + acpi_hw_low_level_write(8, data, &ec->data_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", + data, address)); + +end: + spin_unlock_irqrestore(&ec->lock, flags); + + if (ec->global_lock) + acpi_release_global_lock(glk); + + return_VALUE(result); +} + +/* + * Externally callable EC access functions. For now, assume 1 EC only + */ +int +ec_read(u8 addr, u8 *val) +{ + struct acpi_ec *ec; + int err; + u32 temp_data; + + if (!first_ec) + return -ENODEV; + + ec = acpi_driver_data(first_ec); + + err = acpi_ec_read(ec, addr, &temp_data); + + if (!err) { + *val = temp_data; + return 0; + } + else + return err; +} + +int +ec_write(u8 addr, u8 val) +{ + struct acpi_ec *ec; + int err; + + if (!first_ec) + return -ENODEV; + + ec = acpi_driver_data(first_ec); + + err = acpi_ec_write(ec, addr, val); + + return err; +} + + +static int +acpi_ec_query ( + struct acpi_ec *ec, + u32 *data) +{ + int result = 0; + acpi_status status = AE_OK; + unsigned long flags = 0; + u32 glk = 0; + + ACPI_FUNCTION_TRACE("acpi_ec_query"); + + if (!ec || !data) + return_VALUE(-EINVAL); + + *data = 0; + + if (ec->global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + } + + /* + * Query the EC to find out which _Qxx method we need to evaluate. + * Note that successful completion of the query causes the ACPI_EC_SCI + * bit to be cleared (and thus clearing the interrupt source). + */ + spin_lock_irqsave(&ec->lock, flags); + + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); + if (result) + goto end; + + acpi_hw_low_level_read(8, data, &ec->data_addr); + if (!*data) + result = -ENODATA; + +end: + spin_unlock_irqrestore(&ec->lock, flags); + + if (ec->global_lock) + acpi_release_global_lock(glk); + + return_VALUE(result); +} + + +/* -------------------------------------------------------------------------- + Event Management + -------------------------------------------------------------------------- */ + +struct acpi_ec_query_data { + acpi_handle handle; + u8 data; +}; + +static void +acpi_ec_gpe_query ( + void *ec_cxt) +{ + struct acpi_ec *ec = (struct acpi_ec *) ec_cxt; + u32 value = 0; + unsigned long flags = 0; + static char object_name[5] = {'_','Q','0','0','\0'}; + const char hex[] = {'0','1','2','3','4','5','6','7', + '8','9','A','B','C','D','E','F'}; + + ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); + + if (!ec_cxt) + goto end; + + spin_lock_irqsave(&ec->lock, flags); + acpi_hw_low_level_read(8, &value, &ec->command_addr); + spin_unlock_irqrestore(&ec->lock, flags); + + /* TBD: Implement asynch events! + * NOTE: All we care about are EC-SCI's. Other EC events are + * handled via polling (yuck!). This is because some systems + * treat EC-SCIs as level (versus EDGE!) triggered, preventing + * a purely interrupt-driven approach (grumble, grumble). + */ + if (!(value & ACPI_EC_FLAG_SCI)) + goto end; + + if (acpi_ec_query(ec, &value)) + goto end; + + object_name[2] = hex[((value >> 4) & 0x0F)]; + object_name[3] = hex[(value & 0x0F)]; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); + + acpi_evaluate_object(ec->handle, object_name, NULL, NULL); + +end: + acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); +} + +static void +acpi_ec_gpe_handler ( + void *data) +{ + acpi_status status = AE_OK; + struct acpi_ec *ec = (struct acpi_ec *) data; + + if (!ec) + return; + + acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR); + + status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, + acpi_ec_gpe_query, ec); +} + +/* -------------------------------------------------------------------------- + Address Space Management + -------------------------------------------------------------------------- */ + +static acpi_status +acpi_ec_space_setup ( + acpi_handle region_handle, + u32 function, + void *handler_context, + void **return_context) +{ + /* + * The EC object is in the handler context and is needed + * when calling the acpi_ec_space_handler. + */ + *return_context = handler_context; + + return AE_OK; +} + + +static acpi_status +acpi_ec_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context) +{ + int result = 0; + struct acpi_ec *ec = NULL; + u32 temp = 0; + + ACPI_FUNCTION_TRACE("acpi_ec_space_handler"); + + if ((address > 0xFF) || (bit_width != 8) || !value || !handler_context) + return_VALUE(AE_BAD_PARAMETER); + + ec = (struct acpi_ec *) handler_context; + + switch (function) { + case ACPI_READ: + result = acpi_ec_read(ec, (u8) address, &temp); + *value = (acpi_integer) temp; + break; + case ACPI_WRITE: + result = acpi_ec_write(ec, (u8) address, (u8) *value); + break; + default: + result = -EINVAL; + break; + } + + switch (result) { + case -EINVAL: + return_VALUE(AE_BAD_PARAMETER); + break; + case -ENODEV: + return_VALUE(AE_NOT_FOUND); + break; + case -ETIME: + return_VALUE(AE_TIME); + break; + default: + return_VALUE(AE_OK); + } + +} + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_ec_dir = NULL; + + +static int +acpi_ec_read_info ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_ec *ec = (struct acpi_ec *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_ec_read_info"); + + if (!ec || (off != 0)) + goto end; + + p += sprintf(p, "gpe bit: 0x%02x\n", + (u32) ec->gpe_bit); + p += sprintf(p, "ports: 0x%02x, 0x%02x\n", + (u32) ec->status_addr.address, (u32) ec->data_addr.address); + p += sprintf(p, "use global lock: %s\n", + ec->global_lock?"yes":"no"); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_ec_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_ec_add_fs"); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_ec_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + entry = create_proc_read_entry(ACPI_EC_FILE_INFO, S_IRUGO, + acpi_device_dir(device), acpi_ec_read_info, + acpi_driver_data(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Unable to create '%s' fs entry\n", + ACPI_EC_FILE_INFO)); + + return_VALUE(0); +} + + +static int +acpi_ec_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_ec_remove_fs"); + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +static int +acpi_ec_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_ec *ec = NULL; + unsigned long uid; + + ACPI_FUNCTION_TRACE("acpi_ec_add"); + + if (!device) + return_VALUE(-EINVAL); + + ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + if (!ec) + return_VALUE(-ENOMEM); + memset(ec, 0, sizeof(struct acpi_ec)); + + ec->handle = device->handle; + ec->uid = -1; + ec->lock = SPIN_LOCK_UNLOCKED; + sprintf(acpi_device_name(device), "%s", ACPI_EC_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_EC_CLASS); + acpi_driver_data(device) = ec; + + /* Use the global lock for all EC transactions? */ + acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock); + + /* If our UID matches the UID for the ECDT-enumerated EC, + we now have the *real* EC info, so kill the makeshift one.*/ + acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid); + if (ec_ecdt && ec_ecdt->uid == uid) { + acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, + ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); + + acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler); + + kfree(ec_ecdt); + } + + /* Get GPE bit assignment (EC events). */ + /* TODO: Add support for _GPE returning a package */ + status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error obtaining GPE bit assignment\n")); + result = -ENODEV; + goto end; + } + + result = acpi_ec_add_fs(device); + if (result) + goto end; + + printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", + acpi_device_name(device), acpi_device_bid(device), + (u32) ec->gpe_bit); + + if (!first_ec) + first_ec = device; + +end: + if (result) + kfree(ec); + + return_VALUE(result); +} + + +static int +acpi_ec_remove ( + struct acpi_device *device, + int type) +{ + struct acpi_ec *ec = NULL; + + ACPI_FUNCTION_TRACE("acpi_ec_remove"); + + if (!device) + return_VALUE(-EINVAL); + + ec = acpi_driver_data(device); + + acpi_ec_remove_fs(device); + + kfree(ec); + + return_VALUE(0); +} + + +static acpi_status +acpi_ec_io_ports ( + struct acpi_resource *resource, + void *context) +{ + struct acpi_ec *ec = (struct acpi_ec *) context; + struct acpi_generic_address *addr; + + if (resource->id != ACPI_RSTYPE_IO) { + return AE_OK; + } + + /* + * The first address region returned is the data port, and + * the second address region returned is the status/command + * port. + */ + if (ec->data_addr.register_bit_width == 0) { + addr = &ec->data_addr; + } else if (ec->command_addr.register_bit_width == 0) { + addr = &ec->command_addr; + } else { + return AE_CTRL_TERMINATE; + } + + addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; + addr->register_bit_width = 8; + addr->register_bit_offset = 0; + addr->address = resource->data.io.min_base_address; + + return AE_OK; +} + + +static int +acpi_ec_start ( + struct acpi_device *device) +{ + acpi_status status = AE_OK; + struct acpi_ec *ec = NULL; + + ACPI_FUNCTION_TRACE("acpi_ec_start"); + + if (!device) + return_VALUE(-EINVAL); + + ec = acpi_driver_data(device); + + if (!ec) + return_VALUE(-EINVAL); + + /* + * Get I/O port addresses. Convert to GAS format. + */ + status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS, + acpi_ec_io_ports, ec); + if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); + return_VALUE(-ENODEV); + } + + ec->status_addr = ec->command_addr; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", + (u32) ec->gpe_bit, (u32) ec->command_addr.address, + (u32) ec->data_addr.address)); + + /* + * Install GPE handler + */ + status = acpi_install_gpe_handler(NULL, ec->gpe_bit, + ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); + if (ACPI_FAILURE(status)) { + return_VALUE(-ENODEV); + } + + status = acpi_install_address_space_handler (ec->handle, + ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, + &acpi_ec_space_setup, ec); + if (ACPI_FAILURE(status)) { + acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler); + return_VALUE(-ENODEV); + } + + return_VALUE(AE_OK); +} + + +static int +acpi_ec_stop ( + struct acpi_device *device, + int type) +{ + acpi_status status = AE_OK; + struct acpi_ec *ec = NULL; + + ACPI_FUNCTION_TRACE("acpi_ec_stop"); + + if (!device) + return_VALUE(-EINVAL); + + ec = acpi_driver_data(device); + + status = acpi_remove_address_space_handler(ec->handle, + ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + status = acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + return_VALUE(0); +} + + +int __init +acpi_ec_ecdt_probe (void) +{ + acpi_status status; + struct acpi_table_ecdt *ecdt_ptr; + + status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) &ecdt_ptr); + if (ACPI_FAILURE(status)) + return 0; + + printk(KERN_INFO PREFIX "Found ECDT\n"); + + /* + * Generate a temporary ec context to use until the namespace is scanned + */ + ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + if (!ec_ecdt) + return -ENOMEM; + memset(ec_ecdt, 0, sizeof(struct acpi_ec)); + + ec_ecdt->command_addr = ecdt_ptr->ec_control; + ec_ecdt->status_addr = ecdt_ptr->ec_control; + ec_ecdt->data_addr = ecdt_ptr->ec_data; + ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; + ec_ecdt->lock = SPIN_LOCK_UNLOCKED; + /* use the GL just to be safe */ + ec_ecdt->global_lock = TRUE; + ec_ecdt->uid = ecdt_ptr->uid; + + status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); + if (ACPI_FAILURE(status)) { + goto error; + } + + /* + * Install GPE handler + */ + status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, + ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, + ec_ecdt); + if (ACPI_FAILURE(status)) { + goto error; + } + + status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT, + ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, + &acpi_ec_space_setup, ec_ecdt); + if (ACPI_FAILURE(status)) { + acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, + &acpi_ec_gpe_handler); + goto error; + } + + return 0; + +error: + printk(KERN_ERR PREFIX "Could not use ECDT\n"); + kfree(ec_ecdt); + ec_ecdt = NULL; + + return -ENODEV; +} + + +int __init +acpi_ec_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_ec_init"); + + acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir); + if (!acpi_ec_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_ec_driver); + if (result < 0) { + remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + +/* EC can't be unloaded atm, so don't compile these */ +#if 0 +void __exit +acpi_ec_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_ec_exit"); + + acpi_bus_unregister_driver(&acpi_ec_driver); + + remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); + + return_VOID; +} +#endif /* 0 */ + diff -urN linux-2.4.21/drivers/acpi/events/Makefile linux-2.4.22/drivers/acpi/events/Makefile --- linux-2.4.21/drivers/acpi/events/Makefile 2001-06-20 17:47:39.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/events/evevent.c linux-2.4.22/drivers/acpi/events/evevent.c --- linux-2.4.21/drivers/acpi/events/evevent.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/events/evevent.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,49 +1,62 @@ /****************************************************************************** * - * Module Name: evevent - Fixed and General Purpose Acpi_event - * handling and dispatch - * $Revision: 51 $ + * Module Name: evevent - Fixed Event handling and dispatch * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "acevents.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evevent") + ACPI_MODULE_NAME ("evevent") /******************************************************************************* * - * FUNCTION: Acpi_ev_initialize + * FUNCTION: acpi_ev_initialize * * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Ensures that the system control interrupt (SCI) is properly - * configured, disables SCI event sources, installs the SCI - * handler + * DESCRIPTION: Initialize global data structures for events. * ******************************************************************************/ @@ -51,10 +64,10 @@ acpi_ev_initialize ( void) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Ev_initialize"); + ACPI_FUNCTION_TRACE ("ev_initialize"); /* Make sure we have ACPI tables */ @@ -64,48 +77,60 @@ return_ACPI_STATUS (AE_NO_ACPI_TABLES); } - - /* Make sure the BIOS supports ACPI mode */ - - if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "ACPI Mode is not supported!\n")); - return_ACPI_STATUS (AE_ERROR); - } - - - acpi_gbl_original_mode = acpi_hw_get_mode(); - /* - * Initialize the Fixed and General Purpose Acpi_events prior. This is - * done prior to enabling SCIs to prevent interrupts from occuring - * before handers are installed. + * Initialize the Fixed and General Purpose Events. This is + * done prior to enabling SCIs to prevent interrupts from + * occurring before handers are installed. */ status = acpi_ev_fixed_event_initialize (); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize fixed events.\n")); + ACPI_REPORT_ERROR (( + "Unable to initialize fixed events, %s\n", + acpi_format_exception (status))); return_ACPI_STATUS (status); } status = acpi_ev_gpe_initialize (); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize general purpose events.\n")); + ACPI_REPORT_ERROR (( + "Unable to initialize general purpose events, %s\n", + acpi_format_exception (status))); return_ACPI_STATUS (status); } - /* Install the SCI handler */ + return_ACPI_STATUS (status); +} - status = acpi_ev_install_sci_handler (); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to install System Control Interrupt Handler\n")); - return_ACPI_STATUS (status); - } +/******************************************************************************* + * + * FUNCTION: acpi_ev_handler_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock + * + ******************************************************************************/ + +acpi_status +acpi_ev_handler_initialize ( + void) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_handler_initialize"); - /* Install handlers for control method GPE handlers (_Lxx, _Exx) */ - status = acpi_ev_init_gpe_control_methods (); + /* Install the SCI handler */ + + status = acpi_ev_install_sci_handler (); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize Gpe control methods\n")); + ACPI_REPORT_ERROR (( + "Unable to install System Control Interrupt Handler, %s\n", + acpi_format_exception (status))); return_ACPI_STATUS (status); } @@ -113,44 +138,55 @@ status = acpi_ev_init_global_lock_handler (); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize Global Lock handler\n")); + ACPI_REPORT_ERROR (( + "Unable to initialize Global Lock handler, %s\n", + acpi_format_exception (status))); return_ACPI_STATUS (status); } - + acpi_gbl_events_initialized = TRUE; return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ev_fixed_event_initialize + * FUNCTION: acpi_ev_fixed_event_initialize * * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Initialize the Fixed Acpi_event data structures + * DESCRIPTION: Install the fixed event handlers and enable the fixed events. * ******************************************************************************/ acpi_status -acpi_ev_fixed_event_initialize(void) +acpi_ev_fixed_event_initialize ( + void) { - int i = 0; + acpi_native_uint i; + acpi_status status; - /* Initialize the structure that keeps track of fixed event handlers */ + /* + * Initialize the structure that keeps track of fixed event handlers + * and enable the fixed events. + */ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { acpi_gbl_fixed_event_handlers[i].handler = NULL; acpi_gbl_fixed_event_handlers[i].context = NULL; - } - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, TMR_EN, 0); - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, GBL_EN, 0); - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, PWRBTN_EN, 0); - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, SLPBTN_EN, 0); - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, RTC_EN, 0); + /* Enable the fixed event */ + + if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { + status = acpi_set_register (acpi_gbl_fixed_event_info[i].enable_register_id, + 0, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return (status); + } + } + } return (AE_OK); } @@ -158,7 +194,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_fixed_event_detect + * FUNCTION: acpi_ev_fixed_event_detect * * PARAMETERS: None * @@ -169,54 +205,41 @@ ******************************************************************************/ u32 -acpi_ev_fixed_event_detect (void) +acpi_ev_fixed_event_detect ( + void) { - u32 int_status = INTERRUPT_NOT_HANDLED; - u32 status_register; - u32 enable_register; + u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; + u32 fixed_status; + u32 fixed_enable; + acpi_native_uint i; - PROC_NAME ("Ev_fixed_event_detect"); + ACPI_FUNCTION_NAME ("ev_fixed_event_detect"); /* * Read the fixed feature status and enable registers, as all the cases - * depend on their values. + * depend on their values. Ignore errors here. */ - status_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS); - enable_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN); + (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, &fixed_status); + (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE, &fixed_enable); ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, - "Fixed Acpi_event Block: Enable %08X Status %08X\n", - enable_register, status_register)); - + "Fixed Event Block: Enable %08X Status %08X\n", + fixed_enable, fixed_status)); - /* power management timer roll over */ - - if ((status_register & ACPI_STATUS_PMTIMER) && - (enable_register & ACPI_ENABLE_PMTIMER)) { - int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_PMTIMER); - } - - /* global event (BIOS wants the global lock) */ - - if ((status_register & ACPI_STATUS_GLOBAL) && - (enable_register & ACPI_ENABLE_GLOBAL)) { - int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_GLOBAL); - } - - /* power button event */ - - if ((status_register & ACPI_STATUS_POWER_BUTTON) && - (enable_register & ACPI_ENABLE_POWER_BUTTON)) { - int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_POWER_BUTTON); - } + /* + * Check for all possible Fixed Events and dispatch those that are active + */ + for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { + /* Both the status and enable bits must be on for this event */ - /* sleep button event */ + if ((fixed_status & acpi_gbl_fixed_event_info[i].status_bit_mask) && + (fixed_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) { + /* Found an active (signalled) event */ - if ((status_register & ACPI_STATUS_SLEEP_BUTTON) && - (enable_register & ACPI_ENABLE_SLEEP_BUTTON)) { - int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_SLEEP_BUTTON); + int_status |= acpi_ev_fixed_event_dispatch ((u32) i); + } } return (int_status); @@ -225,7 +248,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_fixed_event_dispatch + * FUNCTION: acpi_ev_fixed_event_dispatch * * PARAMETERS: Event - Event type * @@ -238,590 +261,37 @@ u32 acpi_ev_fixed_event_dispatch ( - u32 event) + u32 event) { - u32 register_id; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* Clear the status bit */ - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_STS; - break; - - case ACPI_EVENT_GLOBAL: - register_id = GBL_STS; - break; - - case ACPI_EVENT_POWER_BUTTON: - register_id = PWRBTN_STS; - break; - - case ACPI_EVENT_SLEEP_BUTTON: - register_id = SLPBTN_STS; - break; - - case ACPI_EVENT_RTC: - register_id = RTC_STS; - break; - - default: - return 0; - break; - } - - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, register_id, 1); + (void) acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id, + 1, ACPI_MTX_DO_NOT_LOCK); /* * Make sure we've got a handler. If not, report an error. * The event is disabled to prevent further interrupts. */ if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { - register_id = (PM1_EN | REGISTER_BIT_ID(register_id)); + (void) acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id, + 0, ACPI_MTX_DO_NOT_LOCK); - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, - register_id, 0); - - REPORT_ERROR ( - ("Ev_gpe_dispatch: No installed handler for fixed event [%08X]\n", + ACPI_REPORT_ERROR ( + ("No installed handler for fixed event [%08X]\n", event)); - return (INTERRUPT_NOT_HANDLED); + return (ACPI_INTERRUPT_NOT_HANDLED); } - /* Invoke the handler */ + /* Invoke the Fixed Event handler */ return ((acpi_gbl_fixed_event_handlers[event].handler)( acpi_gbl_fixed_event_handlers[event].context)); } -/******************************************************************************* - * - * FUNCTION: Acpi_ev_gpe_initialize - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Initialize the GPE data structures - * - ******************************************************************************/ - -acpi_status -acpi_ev_gpe_initialize (void) -{ - u32 i; - u32 j; - u32 register_index; - u32 gpe_number; - u16 gpe0register_count; - u16 gpe1_register_count; - - - FUNCTION_TRACE ("Ev_gpe_initialize"); - - /* - * Set up various GPE counts - * - * You may ask,why are the GPE register block lengths divided by 2? - * From the ACPI 2.0 Spec, section, 4.7.1.6 General-Purpose Event - * Registers, we have, - * - * "Each register block contains two registers of equal length - * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the - * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN - * The length of the GPE1_STS and GPE1_EN registers is equal to - * half the GPE1_LEN. If a generic register block is not supported - * then its respective block pointer and block length values in the - * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need - * to be the same size." - */ - gpe0register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); - gpe1_register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); - acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count; - - if (!acpi_gbl_gpe_register_count) { - REPORT_WARNING (("Zero GPEs are defined in the FADT\n")); - return_ACPI_STATUS (AE_OK); - } - - /* - * Allocate the Gpe information block - */ - acpi_gbl_gpe_registers = ACPI_MEM_CALLOCATE (acpi_gbl_gpe_register_count * - sizeof (acpi_gpe_registers)); - if (!acpi_gbl_gpe_registers) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Could not allocate the Gpe_registers block\n")); - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* - * Allocate the Gpe dispatch handler block - * There are eight distinct GP events per register. - * Initialization to zeros is sufficient - */ - acpi_gbl_gpe_info = ACPI_MEM_CALLOCATE (MUL_8 (acpi_gbl_gpe_register_count) * - sizeof (acpi_gpe_level_info)); - if (!acpi_gbl_gpe_info) { - ACPI_MEM_FREE (acpi_gbl_gpe_registers); - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_info block\n")); - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* Set the Gpe validation table to GPE_INVALID */ - - MEMSET (acpi_gbl_gpe_valid, (int) ACPI_GPE_INVALID, ACPI_NUM_GPE); - - /* - * Initialize the Gpe information and validation blocks. A goal of these - * blocks is to hide the fact that there are two separate GPE register sets - * In a given block, the status registers occupy the first half, and - * the enable registers occupy the second half. - */ - - /* GPE Block 0 */ - - register_index = 0; - - for (i = 0; i < gpe0register_count; i++) { - acpi_gbl_gpe_registers[register_index].status_addr = - (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i); - - acpi_gbl_gpe_registers[register_index].enable_addr = - (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i + gpe0register_count); - - acpi_gbl_gpe_registers[register_index].gpe_base = (u8) MUL_8 (i); - - for (j = 0; j < 8; j++) { - gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j; - acpi_gbl_gpe_valid[gpe_number] = (u8) register_index; - } - - /* - * Clear the status/enable registers. Note that status registers - * are cleared by writing a '1', while enable registers are cleared - * by writing a '0'. - */ - acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8); - acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8); - - register_index++; - } - - /* GPE Block 1 */ - - for (i = 0; i < gpe1_register_count; i++) { - acpi_gbl_gpe_registers[register_index].status_addr = - (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i); - - acpi_gbl_gpe_registers[register_index].enable_addr = - (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i + gpe1_register_count); - - acpi_gbl_gpe_registers[register_index].gpe_base = - (u8) (acpi_gbl_FADT->gpe1_base + MUL_8 (i)); - - for (j = 0; j < 8; j++) { - gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j; - acpi_gbl_gpe_valid[gpe_number] = (u8) register_index; - } - - /* - * Clear the status/enable registers. Note that status registers - * are cleared by writing a '1', while enable registers are cleared - * by writing a '0'. - */ - acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8); - acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8); - - register_index++; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE registers: %X@%8.8X%8.8X (Blk0) %X@%8.8X%8.8X (Blk1)\n", - gpe0register_count, HIDWORD(acpi_gbl_FADT->Xgpe0blk.address), LODWORD(acpi_gbl_FADT->Xgpe0blk.address), - gpe1_register_count, HIDWORD(acpi_gbl_FADT->Xgpe1_blk.address), LODWORD(acpi_gbl_FADT->Xgpe1_blk.address))); - - return_ACPI_STATUS (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ev_save_method_info - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Called from Acpi_walk_namespace. Expects each object to be a - * control method under the _GPE portion of the namespace. - * Extract the name and GPE type from the object, saving this - * information for quick lookup during GPE dispatch - * - * The name of each GPE control method is of the form: - * "_Lnn" or "_Enn" - * Where: - * L - means that the GPE is level triggered - * E - means that the GPE is edge triggered - * nn - is the GPE number - * - ******************************************************************************/ - -static acpi_status -acpi_ev_save_method_info ( - acpi_handle obj_handle, - u32 level, - void *obj_desc, - void **return_value) -{ - u32 gpe_number; - NATIVE_CHAR name[ACPI_NAME_SIZE + 1]; - u8 type; - - - PROC_NAME ("Ev_save_method_info"); - - - /* Extract the name from the object and convert to a string */ - - MOVE_UNALIGNED32_TO_32 (name, &((acpi_namespace_node *) obj_handle)->name); - name[ACPI_NAME_SIZE] = 0; - - /* - * Edge/Level determination is based on the 2nd s8 of the method name - */ - if (name[1] == 'L') { - type = ACPI_EVENT_LEVEL_TRIGGERED; - } - else if (name[1] == 'E') { - type = ACPI_EVENT_EDGE_TRIGGERED; - } - else { - /* Unknown method type, just ignore it! */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n", - name)); - return (AE_OK); - } - - /* Convert the last two characters of the name to the Gpe Number */ - - gpe_number = STRTOUL (&name[2], NULL, 16); - if (gpe_number == ACPI_UINT32_MAX) { - /* Conversion failed; invalid method, just ignore it */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)\n", - name)); - return (AE_OK); - } - - /* Ensure that we have a valid GPE number */ - - if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) { - /* Not valid, all we can do here is ignore it */ - - return (AE_OK); - } - - /* - * Now we can add this information to the Gpe_info block - * for use during dispatch of this GPE. - */ - acpi_gbl_gpe_info [gpe_number].type = type; - acpi_gbl_gpe_info [gpe_number].method_handle = obj_handle; - - - /* - * Enable the GPE (SCIs should be disabled at this point) - */ - acpi_hw_enable_gpe (gpe_number); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %X\n", - name, gpe_number)); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ev_init_gpe_control_methods - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Obtain the control methods associated with the GPEs. - * - * NOTE: Must be called AFTER namespace initialization! - * - ******************************************************************************/ - -acpi_status -acpi_ev_init_gpe_control_methods (void) -{ - acpi_status status; - - - FUNCTION_TRACE ("Ev_init_gpe_control_methods"); - - - /* Get a permanent handle to the _GPE object */ - - status = acpi_get_handle (NULL, "\\_GPE", &acpi_gbl_gpe_obj_handle); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Traverse the namespace under \_GPE to find all methods there */ - - status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle, - ACPI_UINT32_MAX, acpi_ev_save_method_info, - NULL, NULL); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ev_gpe_detect - * - * PARAMETERS: None - * - * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED - * - * DESCRIPTION: Detect if any GP events have occurred - * - ******************************************************************************/ - -u32 -acpi_ev_gpe_detect (void) -{ - u32 int_status = INTERRUPT_NOT_HANDLED; - u32 i; - u32 j; - u8 enabled_status_byte; - u8 bit_mask; - - - PROC_NAME ("Ev_gpe_detect"); - - - /* - * Read all of the 8-bit GPE status and enable registers - * in both of the register blocks, saving all of it. - * Find all currently active GP events. - */ - for (i = 0; i < acpi_gbl_gpe_register_count; i++) { - acpi_os_read_port (acpi_gbl_gpe_registers[i].status_addr, - &acpi_gbl_gpe_registers[i].status, 8); - - acpi_os_read_port (acpi_gbl_gpe_registers[i].enable_addr, - &acpi_gbl_gpe_registers[i].enable, 8); - - ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, - "GPE block at %X - Enable %08X Status %08X\n", - acpi_gbl_gpe_registers[i].enable_addr, - acpi_gbl_gpe_registers[i].status, - acpi_gbl_gpe_registers[i].enable)); - - /* First check if there is anything active at all in this register */ - - enabled_status_byte = (u8) (acpi_gbl_gpe_registers[i].status & - acpi_gbl_gpe_registers[i].enable); - - if (!enabled_status_byte) { - /* No active GPEs in this register, move on */ - - continue; - } - - /* Now look at the individual GPEs in this byte register */ - - for (j = 0, bit_mask = 1; j < 8; j++, bit_mask <<= 1) { - /* Examine one GPE bit */ - - if (enabled_status_byte & bit_mask) { - /* - * Found an active GPE. Dispatch the event to a handler - * or method. - */ - int_status |= acpi_ev_gpe_dispatch ( - acpi_gbl_gpe_registers[i].gpe_base + j); - } - } - } - - return (int_status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ev_asynch_execute_gpe_method - * - * PARAMETERS: Gpe_number - The 0-based Gpe number - * - * RETURN: None - * - * DESCRIPTION: Perform the actual execution of a GPE control method. This - * function is called from an invocation of Acpi_os_queue_for_execution - * (and therefore does NOT execute at interrupt level) so that - * the control method itself is not executed in the context of - * the SCI interrupt handler. - * - ******************************************************************************/ - -static void -acpi_ev_asynch_execute_gpe_method ( - void *context) -{ - unsigned long gpe_number = (unsigned long) context; - acpi_gpe_level_info gpe_info; - - - FUNCTION_TRACE ("Ev_asynch_execute_gpe_method"); - - /* - * Take a snapshot of the GPE info for this level - */ - acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); - gpe_info = acpi_gbl_gpe_info [gpe_number]; - acpi_ut_release_mutex (ACPI_MTX_EVENTS); - - /* - * Method Handler (_Lxx, _Exx): - * ---------------------------- - * Evaluate the _Lxx/_Exx control method that corresponds to this GPE. - */ - if (gpe_info.method_handle) { - acpi_ns_evaluate_by_handle (gpe_info.method_handle, NULL, NULL); - } - - /* - * Level-Triggered? - * ---------------- - * If level-triggered we clear the GPE status bit after handling the event. - */ - if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } - - /* - * Enable the GPE. - */ - acpi_hw_enable_gpe (gpe_number); - - return_VOID; -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ev_gpe_dispatch - * - * PARAMETERS: Gpe_number - The 0-based Gpe number - * - * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED - * - * DESCRIPTION: Handle and dispatch a General Purpose Acpi_event. - * Clears the status bit for the requested event. - * - * TBD: [Investigate] is this still valid or necessary: - * The Gpe handler differs from the fixed events in that it clears the enable - * bit rather than the status bit to clear the interrupt. This allows - * software outside of interrupt context to determine what caused the SCI and - * dispatch the correct AML. - * - ******************************************************************************/ - -u32 -acpi_ev_gpe_dispatch ( - u32 gpe_number) -{ - acpi_gpe_level_info gpe_info; - - - FUNCTION_TRACE ("Ev_gpe_dispatch"); - - - /* - * Valid GPE number? - */ - if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid GPE bit [%X].\n", gpe_number)); - return_VALUE (INTERRUPT_NOT_HANDLED); - } - - /* - * Disable the GPE. - */ - acpi_hw_disable_gpe (gpe_number); - - gpe_info = acpi_gbl_gpe_info [gpe_number]; - - /* - * Edge-Triggered? - * --------------- - * If edge-triggered, clear the GPE status bit now. Note that - * level-triggered events are cleared after the GPE is serviced. - */ - if (gpe_info.type & ACPI_EVENT_EDGE_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } - /* - * Function Handler (e.g. EC)? - */ - if (gpe_info.handler) { - /* Invoke function handler (at interrupt level). */ - - gpe_info.handler (gpe_info.context); - - /* Level-Triggered? */ - - if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } - - /* Enable GPE */ - - acpi_hw_enable_gpe (gpe_number); - } - - /* - * Method Handler (e.g. _Exx/_Lxx)? - */ - else if (gpe_info.method_handle) { - if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE, - acpi_ev_asynch_execute_gpe_method, (void*) (u64)gpe_number))) { - /* - * Shoudn't occur, but if it does report an error. Note that - * the GPE will remain disabled until the ACPI Core Subsystem - * is restarted, or the handler is removed/reinstalled. - */ - REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE bit [%X]\n", gpe_number)); - } - } - - /* - * No Handler? Report an error and leave the GPE disabled. - */ - else { - REPORT_ERROR (("Acpi_ev_gpe_dispatch: No installed handler for GPE [%X]\n", gpe_number)); - - /* Level-Triggered? */ - - if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } - } - - return_VALUE (INTERRUPT_HANDLED); -} diff -urN linux-2.4.21/drivers/acpi/events/evgpe.c linux-2.4.22/drivers/acpi/events/evgpe.c --- linux-2.4.21/drivers/acpi/events/evgpe.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/events/evgpe.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,425 @@ +/****************************************************************************** + * + * Module Name: evgpe - General Purpose Event handling and dispatch + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include +#include + +#define _COMPONENT ACPI_EVENTS + ACPI_MODULE_NAME ("evgpe") + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_get_gpe_event_info + * + * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 + * gpe_number - Raw GPE number + * + * RETURN: A GPE event_info struct. NULL if not a valid GPE + * + * DESCRIPTION: Returns the event_info struct associated with this GPE. + * Validates the gpe_block and the gpe_number + * + * Should be called only when the GPE lists are semaphore locked + * and not subject to change. + * + ******************************************************************************/ + +struct acpi_gpe_event_info * +acpi_ev_get_gpe_event_info ( + acpi_handle gpe_device, + u32 gpe_number) +{ + union acpi_operand_object *obj_desc; + struct acpi_gpe_block_info *gpe_block; + acpi_native_uint i; + + + ACPI_FUNCTION_ENTRY (); + + + /* A NULL gpe_block means use the FADT-defined GPE block(s) */ + + if (!gpe_device) { + /* Examine GPE Block 0 and 1 (These blocks are permanent) */ + + for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) { + gpe_block = acpi_gbl_gpe_fadt_blocks[i]; + if (gpe_block) { + if ((gpe_number >= gpe_block->block_base_number) && + (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) { + return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]); + } + } + } + + /* The gpe_number was not in the range of either FADT GPE block */ + + return (NULL); + } + + /* + * A Non-null gpe_device means this is a GPE Block Device. + */ + obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) gpe_device); + if (!obj_desc || + !obj_desc->device.gpe_block) { + return (NULL); + } + + gpe_block = obj_desc->device.gpe_block; + + if ((gpe_number >= gpe_block->block_base_number) && + (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) { + return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]); + } + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_gpe_detect + * + * PARAMETERS: gpe_xrupt_list - Interrupt block for this interrupt. + * Can have multiple GPE blocks attached. + * + * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED + * + * DESCRIPTION: Detect if any GP events have occurred. This function is + * executed at interrupt level. + * + ******************************************************************************/ + +u32 +acpi_ev_gpe_detect ( + struct acpi_gpe_xrupt_info *gpe_xrupt_list) +{ + u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; + u8 enabled_status_byte; + u8 bit_mask; + struct acpi_gpe_register_info *gpe_register_info; + u32 in_value; + acpi_status status; + struct acpi_gpe_block_info *gpe_block; + u32 gpe_number; + u32 i; + u32 j; + + + ACPI_FUNCTION_NAME ("ev_gpe_detect"); + + + /* Examine all GPE blocks attached to this interrupt level */ + + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR); + gpe_block = gpe_xrupt_list->gpe_block_list_head; + while (gpe_block) { + /* + * Read all of the 8-bit GPE status and enable registers + * in this GPE block, saving all of them. + * Find all currently active GP events. + */ + for (i = 0; i < gpe_block->register_count; i++) { + /* Get the next status/enable pair */ + + gpe_register_info = &gpe_block->register_info[i]; + + /* Read the Status Register */ + + status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, + &gpe_register_info->status_address); + gpe_register_info->status = (u8) in_value; + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + + /* Read the Enable Register */ + + status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, + &gpe_register_info->enable_address); + gpe_register_info->enable = (u8) in_value; + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, + "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n", + ACPI_HIDWORD (gpe_register_info->status_address.address), + ACPI_LODWORD (gpe_register_info->status_address.address), + gpe_register_info->status, + ACPI_HIDWORD (gpe_register_info->enable_address.address), + ACPI_LODWORD (gpe_register_info->enable_address.address), + gpe_register_info->enable)); + + /* First check if there is anything active at all in this register */ + + enabled_status_byte = (u8) (gpe_register_info->status & + gpe_register_info->enable); + if (!enabled_status_byte) { + /* No active GPEs in this register, move on */ + + continue; + } + + /* Now look at the individual GPEs in this byte register */ + + for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) { + /* Examine one GPE bit */ + + if (enabled_status_byte & bit_mask) { + /* + * Found an active GPE. Dispatch the event to a handler + * or method. + */ + gpe_number = (i * ACPI_GPE_REGISTER_WIDTH) + j; + + int_status |= acpi_ev_gpe_dispatch ( + &gpe_block->event_info[gpe_number], + gpe_number + gpe_block->register_info[gpe_number].base_gpe_number); + } + } + } + + gpe_block = gpe_block->next; + } + +unlock_and_exit: + + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR); + return (int_status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_asynch_execute_gpe_method + * + * PARAMETERS: Context (gpe_event_info) - Info for this GPE + * + * RETURN: None + * + * DESCRIPTION: Perform the actual execution of a GPE control method. This + * function is called from an invocation of acpi_os_queue_for_execution + * (and therefore does NOT execute at interrupt level) so that + * the control method itself is not executed in the context of + * an interrupt handler. + * + ******************************************************************************/ + +static void ACPI_SYSTEM_XFACE +acpi_ev_asynch_execute_gpe_method ( + void *context) +{ + struct acpi_gpe_event_info *gpe_event_info = (void *) context; + u32 gpe_number = 0; + acpi_status status; + struct acpi_gpe_event_info local_gpe_event_info; + + + ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method"); + + + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_VOID; + } + + /* Must revalidate the gpe_number/gpe_block */ + + if (!acpi_ev_valid_gpe_event (gpe_event_info)) { + status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); + return_VOID; + } + + /* + * Take a snapshot of the GPE info for this level - we copy the + * info to prevent a race condition with remove_handler/remove_block. + */ + ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info)); + + status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_VOID; + } + + if (local_gpe_event_info.method_node) { + /* + * Invoke the GPE Method (_Lxx, _Exx): + * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.) + */ + status = acpi_ns_evaluate_by_handle (local_gpe_event_info.method_node, NULL, NULL); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n", + acpi_format_exception (status), + local_gpe_event_info.method_node->name.ascii, gpe_number)); + } + } + + if (local_gpe_event_info.flags & ACPI_EVENT_LEVEL_TRIGGERED) { + /* + * GPE is level-triggered, we clear the GPE status bit after handling + * the event. + */ + status = acpi_hw_clear_gpe (&local_gpe_event_info); + if (ACPI_FAILURE (status)) { + return_VOID; + } + } + + /* Enable this GPE */ + + (void) acpi_hw_enable_gpe (&local_gpe_event_info); + return_VOID; +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_gpe_dispatch + * + * PARAMETERS: gpe_event_info - info for this GPE + * gpe_number - Number relative to the parent GPE block + * + * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED + * + * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) + * or method (e.g. _Lxx/_Exx) handler. + * + * This function executes at interrupt level. + * + ******************************************************************************/ + +u32 +acpi_ev_gpe_dispatch ( + struct acpi_gpe_event_info *gpe_event_info, + u32 gpe_number) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_gpe_dispatch"); + + + /* + * If edge-triggered, clear the GPE status bit now. Note that + * level-triggered events are cleared after the GPE is serviced. + */ + if (gpe_event_info->flags & ACPI_EVENT_EDGE_TRIGGERED) { + status = acpi_hw_clear_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n", + gpe_number)); + return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); + } + } + + /* + * Dispatch the GPE to either an installed handler, or the control + * method associated with this GPE (_Lxx or _Exx). + * If a handler exists, we invoke it and do not attempt to run the method. + * If there is neither a handler nor a method, we disable the level to + * prevent further events from coming in here. + */ + if (gpe_event_info->handler) { + /* Invoke the installed handler (at interrupt level) */ + + gpe_event_info->handler (gpe_event_info->context); + } + else if (gpe_event_info->method_node) { + /* + * Disable GPE, so it doesn't keep firing before the method has a + * chance to run. + */ + status = acpi_hw_disable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", + gpe_number)); + return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); + } + + /* Execute the method associated with the GPE. */ + + if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE, + acpi_ev_asynch_execute_gpe_method, + gpe_event_info))) { + ACPI_REPORT_ERROR (( + "acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2X], event is disabled\n", + gpe_number)); + } + } + else { + /* No handler or method to run! */ + + ACPI_REPORT_ERROR (( + "acpi_ev_gpe_dispatch: No handler or method for GPE[%2X], disabling event\n", + gpe_number)); + + /* + * Disable the GPE. The GPE will remain disabled until the ACPI + * Core Subsystem is restarted, or the handler is reinstalled. + */ + status = acpi_hw_disable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", + gpe_number)); + return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); + } + } + + /* It is now safe to clear level-triggered events. */ + + if (gpe_event_info->flags & ACPI_EVENT_LEVEL_TRIGGERED) { + status = acpi_hw_clear_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n", + gpe_number)); + return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); + } + } + + return_VALUE (ACPI_INTERRUPT_HANDLED); +} + diff -urN linux-2.4.21/drivers/acpi/events/evgpeblk.c linux-2.4.22/drivers/acpi/events/evgpeblk.c --- linux-2.4.21/drivers/acpi/events/evgpeblk.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/events/evgpeblk.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,903 @@ +/****************************************************************************** + * + * Module Name: evgpeblk - GPE block creation and initialization. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include +#include + +#define _COMPONENT ACPI_EVENTS + ACPI_MODULE_NAME ("evgpeblk") + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_valid_gpe_event + * + * PARAMETERS: gpe_event_info - Info for this GPE + * + * RETURN: TRUE if the gpe_event is valid + * + * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. + * Should be called only when the GPE lists are semaphore locked + * and not subject to change. + * + ******************************************************************************/ + +u8 +acpi_ev_valid_gpe_event ( + struct acpi_gpe_event_info *gpe_event_info) +{ + struct acpi_gpe_xrupt_info *gpe_xrupt_block; + struct acpi_gpe_block_info *gpe_block; + + + ACPI_FUNCTION_ENTRY (); + + + /* No need for spin lock since we are not changing any list elements */ + + /* Walk the GPE interrupt levels */ + + gpe_xrupt_block = acpi_gbl_gpe_xrupt_list_head; + while (gpe_xrupt_block) { + gpe_block = gpe_xrupt_block->gpe_block_list_head; + + /* Walk the GPE blocks on this interrupt level */ + + while (gpe_block) { + if ((&gpe_block->event_info[0] <= gpe_event_info) && + (&gpe_block->event_info[((acpi_size) gpe_block->register_count) * 8] > gpe_event_info)) { + return (TRUE); + } + + gpe_block = gpe_block->next; + } + + gpe_xrupt_block = gpe_xrupt_block->next; + } + + return (FALSE); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_walk_gpe_list + * + * PARAMETERS: gpe_walk_callback - Routine called for each GPE block + * + * RETURN: Status + * + * DESCRIPTION: Walk the GPE lists. + * FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED + * + ******************************************************************************/ + +acpi_status +acpi_ev_walk_gpe_list ( + ACPI_GPE_CALLBACK gpe_walk_callback) +{ + struct acpi_gpe_block_info *gpe_block; + struct acpi_gpe_xrupt_info *gpe_xrupt_info; + acpi_status status = AE_OK; + + + ACPI_FUNCTION_TRACE ("ev_walk_gpe_list"); + + + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR); + + /* Walk the interrupt level descriptor list */ + + gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; + while (gpe_xrupt_info) { + /* Walk all Gpe Blocks attached to this interrupt level */ + + gpe_block = gpe_xrupt_info->gpe_block_list_head; + while (gpe_block) { + /* One callback per GPE block */ + + status = gpe_walk_callback (gpe_xrupt_info, gpe_block); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + + gpe_block = gpe_block->next; + } + + gpe_xrupt_info = gpe_xrupt_info->next; + } + +unlock_and_exit: + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_save_method_info + * + * PARAMETERS: Callback from walk_namespace + * + * RETURN: Status + * + * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a + * control method under the _GPE portion of the namespace. + * Extract the name and GPE type from the object, saving this + * information for quick lookup during GPE dispatch + * + * The name of each GPE control method is of the form: + * "_Lnn" or "_Enn" + * Where: + * L - means that the GPE is level triggered + * E - means that the GPE is edge triggered + * nn - is the GPE number [in HEX] + * + ******************************************************************************/ + +static acpi_status +acpi_ev_save_method_info ( + acpi_handle obj_handle, + u32 level, + void *obj_desc, + void **return_value) +{ + struct acpi_gpe_block_info *gpe_block = (void *) obj_desc; + struct acpi_gpe_event_info *gpe_event_info; + u32 gpe_number; + char name[ACPI_NAME_SIZE + 1]; + u8 type; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_save_method_info"); + + + /* Extract the name from the object and convert to a string */ + + ACPI_MOVE_32_TO_32 (name, + &((struct acpi_namespace_node *) obj_handle)->name.integer); + name[ACPI_NAME_SIZE] = 0; + + /* + * Edge/Level determination is based on the 2nd character + * of the method name + */ + switch (name[1]) { + case 'L': + type = ACPI_EVENT_LEVEL_TRIGGERED; + break; + + case 'E': + type = ACPI_EVENT_EDGE_TRIGGERED; + break; + + default: + /* Unknown method type, just ignore it! */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n", + name)); + return_ACPI_STATUS (AE_OK); + } + + /* Convert the last two characters of the name to the GPE Number */ + + gpe_number = ACPI_STRTOUL (&name[2], NULL, 16); + if (gpe_number == ACPI_UINT32_MAX) { + /* Conversion failed; invalid method, just ignore it */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not extract GPE number from name: %s (name is not of form _Lnn or _Enn)\n", + name)); + return_ACPI_STATUS (AE_OK); + } + + /* Ensure that we have a valid GPE number for this GPE block */ + + if ((gpe_number < gpe_block->block_base_number) || + (gpe_number >= (gpe_block->block_base_number + (gpe_block->register_count * 8)))) { + /* + * Not valid for this GPE block, just ignore it + * However, it may be valid for a different GPE block, since GPE0 and GPE1 + * methods both appear under \_GPE. + */ + return_ACPI_STATUS (AE_OK); + } + + /* + * Now we can add this information to the gpe_event_info block + * for use during dispatch of this GPE. + */ + gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; + + gpe_event_info->flags = type; + gpe_event_info->method_node = (struct acpi_namespace_node *) obj_handle; + + /* Enable the GPE (SCIs should be disabled at this point) */ + + status = acpi_hw_enable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, + "Registered GPE method %s as GPE number 0x%.2X\n", + name, gpe_number)); + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_get_gpe_xrupt_block + * + * PARAMETERS: interrupt_level - Interrupt for a GPE block + * + * RETURN: A GPE interrupt block + * + * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt + * block per unique interrupt level used for GPEs. + * Should be called only when the GPE lists are semaphore locked + * and not subject to change. + * + ******************************************************************************/ + +static struct acpi_gpe_xrupt_info * +acpi_ev_get_gpe_xrupt_block ( + u32 interrupt_level) +{ + struct acpi_gpe_xrupt_info *next_gpe_xrupt; + struct acpi_gpe_xrupt_info *gpe_xrupt; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_get_gpe_xrupt_block"); + + + /* No need for spin lock since we are not changing any list elements here */ + + next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head; + while (next_gpe_xrupt) { + if (next_gpe_xrupt->interrupt_level == interrupt_level) { + return_PTR (next_gpe_xrupt); + } + + next_gpe_xrupt = next_gpe_xrupt->next; + } + + /* Not found, must allocate a new xrupt descriptor */ + + gpe_xrupt = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_xrupt_info)); + if (!gpe_xrupt) { + return_PTR (NULL); + } + + gpe_xrupt->interrupt_level = interrupt_level; + + /* Install new interrupt descriptor with spin lock */ + + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + if (acpi_gbl_gpe_xrupt_list_head) { + next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head; + while (next_gpe_xrupt->next) { + next_gpe_xrupt = next_gpe_xrupt->next; + } + + next_gpe_xrupt->next = gpe_xrupt; + gpe_xrupt->previous = next_gpe_xrupt; + } + else { + acpi_gbl_gpe_xrupt_list_head = gpe_xrupt; + } + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + + /* Install new interrupt handler if not SCI_INT */ + + if (interrupt_level != acpi_gbl_FADT->sci_int) { + status = acpi_os_install_interrupt_handler (interrupt_level, + acpi_ev_gpe_xrupt_handler, gpe_xrupt); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not install GPE interrupt handler at level 0x%X\n", + interrupt_level)); + return_PTR (NULL); + } + } + + return_PTR (gpe_xrupt); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_delete_gpe_xrupt + * + * PARAMETERS: gpe_xrupt - A GPE interrupt info block + * + * RETURN: Status + * + * DESCRIPTION: Remove and free a gpe_xrupt block. Remove an associated + * interrupt handler if not the SCI interrupt. + * + ******************************************************************************/ + +static acpi_status +acpi_ev_delete_gpe_xrupt ( + struct acpi_gpe_xrupt_info *gpe_xrupt) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_delete_gpe_xrupt"); + + + /* We never want to remove the SCI interrupt handler */ + + if (gpe_xrupt->interrupt_level == acpi_gbl_FADT->sci_int) { + gpe_xrupt->gpe_block_list_head = NULL; + return_ACPI_STATUS (AE_OK); + } + + /* Disable this interrupt */ + + status = acpi_os_remove_interrupt_handler (gpe_xrupt->interrupt_level, + acpi_ev_gpe_xrupt_handler); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Unlink the interrupt block with lock */ + + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + if (gpe_xrupt->previous) { + gpe_xrupt->previous->next = gpe_xrupt->next; + } + + if (gpe_xrupt->next) { + gpe_xrupt->next->previous = gpe_xrupt->previous; + } + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + + /* Free the block */ + + ACPI_MEM_FREE (gpe_xrupt); + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_install_gpe_block + * + * PARAMETERS: gpe_block - New GPE block + * interrupt_level - Level to be associated with this GPE block + * + * RETURN: Status + * + * DESCRIPTION: Install new GPE block with mutex support + * + ******************************************************************************/ + +static acpi_status +acpi_ev_install_gpe_block ( + struct acpi_gpe_block_info *gpe_block, + u32 interrupt_level) +{ + struct acpi_gpe_block_info *next_gpe_block; + struct acpi_gpe_xrupt_info *gpe_xrupt_block; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_install_gpe_block"); + + + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + gpe_xrupt_block = acpi_ev_get_gpe_xrupt_block (interrupt_level); + if (!gpe_xrupt_block) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } + + /* Install the new block at the end of the list for this interrupt with lock */ + + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + if (gpe_xrupt_block->gpe_block_list_head) { + next_gpe_block = gpe_xrupt_block->gpe_block_list_head; + while (next_gpe_block->next) { + next_gpe_block = next_gpe_block->next; + } + + next_gpe_block->next = gpe_block; + gpe_block->previous = next_gpe_block; + } + else { + gpe_xrupt_block->gpe_block_list_head = gpe_block; + } + + gpe_block->xrupt_block = gpe_xrupt_block; + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + +unlock_and_exit: + status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_delete_gpe_block + * + * PARAMETERS: gpe_block - Existing GPE block + * + * RETURN: Status + * + * DESCRIPTION: Install new GPE block with mutex support + * + ******************************************************************************/ + +acpi_status +acpi_ev_delete_gpe_block ( + struct acpi_gpe_block_info *gpe_block) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_install_gpe_block"); + + + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Disable all GPEs in this block */ + + status = acpi_hw_disable_gpe_block (gpe_block->xrupt_block, gpe_block); + + if (!gpe_block->previous && !gpe_block->next) { + /* This is the last gpe_block on this interrupt */ + + status = acpi_ev_delete_gpe_xrupt (gpe_block->xrupt_block); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + } + else { + /* Remove the block on this interrupt with lock */ + + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + if (gpe_block->previous) { + gpe_block->previous->next = gpe_block->next; + } + else { + gpe_block->xrupt_block->gpe_block_list_head = gpe_block->next; + } + + if (gpe_block->next) { + gpe_block->next->previous = gpe_block->previous; + } + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + } + + /* Free the gpe_block */ + + ACPI_MEM_FREE (gpe_block->register_info); + ACPI_MEM_FREE (gpe_block->event_info); + ACPI_MEM_FREE (gpe_block); + +unlock_and_exit: + status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_create_gpe_info_blocks + * + * PARAMETERS: gpe_block - New GPE block + * + * RETURN: Status + * + * DESCRIPTION: Create the register_info and event_info blocks for this GPE block + * + ******************************************************************************/ + +static acpi_status +acpi_ev_create_gpe_info_blocks ( + struct acpi_gpe_block_info *gpe_block) +{ + struct acpi_gpe_register_info *gpe_register_info = NULL; + struct acpi_gpe_event_info *gpe_event_info = NULL; + struct acpi_gpe_event_info *this_event; + struct acpi_gpe_register_info *this_register; + acpi_native_uint i; + acpi_native_uint j; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_create_gpe_info_blocks"); + + + /* Allocate the GPE register information block */ + + gpe_register_info = ACPI_MEM_CALLOCATE ( + (acpi_size) gpe_block->register_count * + sizeof (struct acpi_gpe_register_info)); + if (!gpe_register_info) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not allocate the gpe_register_info table\n")); + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* + * Allocate the GPE event_info block. There are eight distinct GPEs + * per register. Initialization to zeros is sufficient. + */ + gpe_event_info = ACPI_MEM_CALLOCATE ( + ((acpi_size) gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) * + sizeof (struct acpi_gpe_event_info)); + if (!gpe_event_info) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_event_info table\n")); + status = AE_NO_MEMORY; + goto error_exit; + } + + /* Save the new Info arrays in the GPE block */ + + gpe_block->register_info = gpe_register_info; + gpe_block->event_info = gpe_event_info; + + /* + * Initialize the GPE Register and Event structures. A goal of these + * tables is to hide the fact that there are two separate GPE register sets + * in a given gpe hardware block, the status registers occupy the first half, + * and the enable registers occupy the second half. + */ + this_register = gpe_register_info; + this_event = gpe_event_info; + + for (i = 0; i < gpe_block->register_count; i++) { + /* Init the register_info for this GPE register (8 GPEs) */ + + this_register->base_gpe_number = (u8) (gpe_block->block_base_number + + (i * ACPI_GPE_REGISTER_WIDTH)); + + ACPI_STORE_ADDRESS (this_register->status_address.address, + (gpe_block->block_address.address + + i)); + + ACPI_STORE_ADDRESS (this_register->enable_address.address, + (gpe_block->block_address.address + + i + + gpe_block->register_count)); + + this_register->status_address.address_space_id = gpe_block->block_address.address_space_id; + this_register->enable_address.address_space_id = gpe_block->block_address.address_space_id; + this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; + this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; + this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; + this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; + + /* Init the event_info for each GPE within this register */ + + for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { + this_event->bit_mask = acpi_gbl_decode_to8bit[j]; + this_event->register_info = this_register; + this_event++; + } + + /* + * Clear the status/enable registers. Note that status registers + * are cleared by writing a '1', while enable registers are cleared + * by writing a '0'. + */ + status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00, + &this_register->enable_address); + if (ACPI_FAILURE (status)) { + goto error_exit; + } + + status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF, + &this_register->status_address); + if (ACPI_FAILURE (status)) { + goto error_exit; + } + + this_register++; + } + + return_ACPI_STATUS (AE_OK); + + +error_exit: + if (gpe_register_info) { + ACPI_MEM_FREE (gpe_register_info); + } + if (gpe_event_info) { + ACPI_MEM_FREE (gpe_event_info); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_create_gpe_block + * + * PARAMETERS: gpe_device - Handle to the parent GPE block + * gpe_block_address - Address and space_iD + * register_count - Number of GPE register pairs in the block + * gpe_block_base_number - Starting GPE number for the block + * interrupt_level - H/W interrupt for the block + * return_gpe_block - Where the new block descriptor is returned + * + * RETURN: Status + * + * DESCRIPTION: Create and Install a block of GPE registers + * + ******************************************************************************/ + +acpi_status +acpi_ev_create_gpe_block ( + struct acpi_namespace_node *gpe_device, + struct acpi_generic_address *gpe_block_address, + u32 register_count, + u8 gpe_block_base_number, + u32 interrupt_level, + struct acpi_gpe_block_info **return_gpe_block) +{ + struct acpi_gpe_block_info *gpe_block; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_create_gpe_block"); + + + if (!register_count) { + return_ACPI_STATUS (AE_OK); + } + + /* Allocate a new GPE block */ + + gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info)); + if (!gpe_block) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Initialize the new GPE block */ + + gpe_block->register_count = register_count; + gpe_block->block_base_number = gpe_block_base_number; + + ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address)); + + /* Create the register_info and event_info sub-structures */ + + status = acpi_ev_create_gpe_info_blocks (gpe_block); + if (ACPI_FAILURE (status)) { + ACPI_MEM_FREE (gpe_block); + return_ACPI_STATUS (status); + } + + /* Install the new block in the global list(s) */ + + status = acpi_ev_install_gpe_block (gpe_block, interrupt_level); + if (ACPI_FAILURE (status)) { + ACPI_MEM_FREE (gpe_block); + return_ACPI_STATUS (status); + } + + /* Dump info about this GPE block */ + + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n", + gpe_block->block_base_number, + (u32) (gpe_block->block_base_number + + ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)), + gpe_device->name.ascii, + gpe_block->register_count, + ACPI_HIDWORD (gpe_block->block_address.address), + ACPI_LODWORD (gpe_block->block_address.address), + interrupt_level)); + + /* Find all GPE methods (_Lxx, _Exx) for this block */ + + status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device, + ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info, + gpe_block, NULL); + + /* Return the new block */ + + if (return_gpe_block) { + (*return_gpe_block) = gpe_block; + } + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_gpe_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize the GPE data structures + * + ******************************************************************************/ + +acpi_status +acpi_ev_gpe_initialize (void) +{ + u32 register_count0 = 0; + u32 register_count1 = 0; + u32 gpe_number_max = 0; + acpi_handle gpe_device; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_gpe_initialize"); + + + /* Get a handle to the predefined _GPE object */ + + status = acpi_get_handle (NULL, "\\_GPE", &gpe_device); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* + * Initialize the GPE Blocks defined in the FADT + * + * Why the GPE register block lengths are divided by 2: From the ACPI Spec, + * section "General-Purpose Event Registers", we have: + * + * "Each register block contains two registers of equal length + * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the + * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN + * The length of the GPE1_STS and GPE1_EN registers is equal to + * half the GPE1_LEN. If a generic register block is not supported + * then its respective block pointer and block length values in the + * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need + * to be the same size." + */ + + /* + * Determine the maximum GPE number for this machine. + * + * Note: both GPE0 and GPE1 are optional, and either can exist without + * the other. + * + * If EITHER the register length OR the block address are zero, then that + * particular block is not supported. + */ + if (acpi_gbl_FADT->gpe0_blk_len && + acpi_gbl_FADT->xgpe0_blk.address) { + /* GPE block 0 exists (has both length and address > 0) */ + + register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2); + + gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; + + /* Install GPE Block 0 */ + + status = acpi_ev_create_gpe_block (gpe_device, &acpi_gbl_FADT->xgpe0_blk, + register_count0, 0, acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (( + "Could not create GPE Block 0, %s\n", + acpi_format_exception (status))); + } + } + + if (acpi_gbl_FADT->gpe1_blk_len && + acpi_gbl_FADT->xgpe1_blk.address) { + /* GPE block 1 exists (has both length and address > 0) */ + + register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2); + + /* Check for GPE0/GPE1 overlap (if both banks exist) */ + + if ((register_count0) && + (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) { + ACPI_REPORT_ERROR (( + "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n", + gpe_number_max, acpi_gbl_FADT->gpe1_base, + acpi_gbl_FADT->gpe1_base + + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1))); + + /* Ignore GPE1 block by setting the register count to zero */ + + register_count1 = 0; + } + else { + /* Install GPE Block 1 */ + + status = acpi_ev_create_gpe_block (gpe_device, &acpi_gbl_FADT->xgpe1_blk, + register_count1, acpi_gbl_FADT->gpe1_base, + acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[1]); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (( + "Could not create GPE Block 1, %s\n", + acpi_format_exception (status))); + } + + /* + * GPE0 and GPE1 do not have to be contiguous in the GPE number + * space. However, GPE0 always starts at GPE number zero. + */ + gpe_number_max = acpi_gbl_FADT->gpe1_base + + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); + } + } + + /* Exit if there are no GPE registers */ + + if ((register_count0 + register_count1) == 0) { + /* GPEs are not required by ACPI, this is OK */ + + ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n")); + return_ACPI_STATUS (AE_OK); + } + + /* Check for Max GPE number out-of-range */ + + if (gpe_number_max > ACPI_GPE_MAX) { + ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n", + gpe_number_max)); + return_ACPI_STATUS (AE_BAD_VALUE); + } + + return_ACPI_STATUS (AE_OK); +} + + diff -urN linux-2.4.21/drivers/acpi/events/evmisc.c linux-2.4.22/drivers/acpi/events/evmisc.c --- linux-2.4.21/drivers/acpi/events/evmisc.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/evmisc.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,42 +1,92 @@ /****************************************************************************** * - * Module Name: evmisc - ACPI device notification handler dispatch - * and ACPI Global Lock support - * $Revision: 35 $ + * Module Name: evmisc - Miscellaneous event manager support functions * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "achware.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evmisc") + ACPI_MODULE_NAME ("evmisc") /******************************************************************************* * - * FUNCTION: Acpi_ev_queue_notify_request + * FUNCTION: acpi_ev_is_notify_object + * + * PARAMETERS: Node - Node to check + * + * RETURN: TRUE if notifies allowed on this object + * + * DESCRIPTION: Check type of node for a object that supports notifies. + * + * TBD: This could be replaced by a flag bit in the node. + * + ******************************************************************************/ + +u8 +acpi_ev_is_notify_object ( + struct acpi_namespace_node *node) +{ + switch (node->type) { + case ACPI_TYPE_DEVICE: + case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_POWER: + case ACPI_TYPE_THERMAL: + /* + * These are the ONLY objects that can receive ACPI notifications + */ + return (TRUE); + + default: + return (FALSE); + } +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_queue_notify_request * * PARAMETERS: * @@ -49,16 +99,16 @@ acpi_status acpi_ev_queue_notify_request ( - acpi_namespace_node *node, - u32 notify_value) + struct acpi_namespace_node *node, + u32 notify_value) { - acpi_operand_object *obj_desc; - acpi_operand_object *handler_obj = NULL; - acpi_generic_state *notify_info; - acpi_status status = AE_OK; + union acpi_operand_object *obj_desc; + union acpi_operand_object *handler_obj = NULL; + union acpi_generic_state *notify_info; + acpi_status status = AE_OK; - PROC_NAME ("Ev_queue_notify_request"); + ACPI_FUNCTION_NAME ("ev_queue_notify_request"); /* @@ -92,43 +142,38 @@ break; } - /* - * Get the notify object attached to the device Node + * Get the notify object attached to the NS Node */ obj_desc = acpi_ns_get_attached_object (node); if (obj_desc) { - /* We have the notify object, Get the right handler */ switch (node->type) { case ACPI_TYPE_DEVICE: - if (notify_value <= MAX_SYS_NOTIFY) { - handler_obj = obj_desc->device.sys_handler; - } - else { - handler_obj = obj_desc->device.drv_handler; - } - break; - case ACPI_TYPE_THERMAL: - if (notify_value <= MAX_SYS_NOTIFY) { - handler_obj = obj_desc->thermal_zone.sys_handler; + case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_POWER: + + if (notify_value <= ACPI_MAX_SYS_NOTIFY) { + handler_obj = obj_desc->common_notify.system_notify; } else { - handler_obj = obj_desc->thermal_zone.drv_handler; + handler_obj = obj_desc->common_notify.device_notify; } break; + + default: + /* All other types are not supported */ + return (AE_TYPE); } } - /* If there is any handler to run, schedule the dispatcher */ - if ((acpi_gbl_sys_notify.handler && (notify_value <= MAX_SYS_NOTIFY)) || - (acpi_gbl_drv_notify.handler && (notify_value > MAX_SYS_NOTIFY)) || + if ((acpi_gbl_system_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) || + (acpi_gbl_device_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) { - notify_info = acpi_ut_create_generic_state (); if (!notify_info) { return (AE_NO_MEMORY); @@ -149,7 +194,8 @@ if (!handler_obj) { /* There is no per-device notify handler for this device */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No notify handler for node %p \n", node)); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "No notify handler for [%4.4s] node %p\n", node->name.ascii, node)); } return (status); @@ -158,7 +204,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_notify_dispatch + * FUNCTION: acpi_ev_notify_dispatch * * PARAMETERS: * @@ -169,42 +215,40 @@ * ******************************************************************************/ -void +void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch ( - void *context) + void *context) { - acpi_generic_state *notify_info = (acpi_generic_state *) context; - acpi_notify_handler global_handler = NULL; - void *global_context = NULL; - acpi_operand_object *handler_obj; + union acpi_generic_state *notify_info = (union acpi_generic_state *) context; + acpi_notify_handler global_handler = NULL; + void *global_context = NULL; + union acpi_operand_object *handler_obj; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* * We will invoke a global notify handler if installed. * This is done _before_ we invoke the per-device handler attached to the device. */ - if (notify_info->notify.value <= MAX_SYS_NOTIFY) { + if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) { /* Global system notification handler */ - if (acpi_gbl_sys_notify.handler) { - global_handler = acpi_gbl_sys_notify.handler; - global_context = acpi_gbl_sys_notify.context; + if (acpi_gbl_system_notify.handler) { + global_handler = acpi_gbl_system_notify.handler; + global_context = acpi_gbl_system_notify.context; } } - else { /* Global driver notification handler */ - if (acpi_gbl_drv_notify.handler) { - global_handler = acpi_gbl_drv_notify.handler; - global_context = acpi_gbl_drv_notify.context; + if (acpi_gbl_device_notify.handler) { + global_handler = acpi_gbl_device_notify.handler; + global_context = acpi_gbl_device_notify.context; } } - /* Invoke the system handler first, if present */ if (global_handler) { @@ -215,8 +259,8 @@ handler_obj = notify_info->notify.handler_obj; if (handler_obj) { - handler_obj->notify_handler.handler (notify_info->notify.node, notify_info->notify.value, - handler_obj->notify_handler.context); + handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value, + handler_obj->notify.context); } /* All done with the info object */ @@ -227,7 +271,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_global_lock_thread + * FUNCTION: acpi_ev_global_lock_thread * * RETURN: None * @@ -237,25 +281,30 @@ * ******************************************************************************/ -static void +static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread ( - void *context) + void *context) { + acpi_status status; + /* Signal threads that are waiting for the lock */ if (acpi_gbl_global_lock_thread_count) { /* Send sufficient units to the semaphore */ - acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore, + status = acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore, acpi_gbl_global_lock_thread_count); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not signal Global Lock semaphore\n")); + } } } /******************************************************************************* * - * FUNCTION: Acpi_ev_global_lock_handler + * FUNCTION: acpi_ev_global_lock_handler * * RETURN: Status * @@ -267,10 +316,10 @@ static u32 acpi_ev_global_lock_handler ( - void *context) + void *context) { - u8 acquired = FALSE; - void *global_lock; + u8 acquired = FALSE; + acpi_status status; /* @@ -278,8 +327,7 @@ * If we don't get it now, it will be marked pending and we will * take another interrupt when it becomes free. */ - global_lock = acpi_gbl_FACS->global_lock; - ACPI_ACQUIRE_GLOBAL_LOCK (global_lock, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { /* Got the lock, now wake all threads waiting for it */ @@ -287,17 +335,23 @@ /* Run the Global Lock thread which will signal all waiting threads */ - acpi_os_queue_for_execution (OSD_PRIORITY_HIGH, acpi_ev_global_lock_thread, - context); + status = acpi_os_queue_for_execution (OSD_PRIORITY_HIGH, + acpi_ev_global_lock_thread, context); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not queue Global Lock thread, %s\n", + acpi_format_exception (status))); + + return (ACPI_INTERRUPT_NOT_HANDLED); + } } - return (INTERRUPT_HANDLED); + return (ACPI_INTERRUPT_HANDLED); } /******************************************************************************* * - * FUNCTION: Acpi_ev_init_global_lock_handler + * FUNCTION: acpi_ev_init_global_lock_handler * * RETURN: Status * @@ -308,10 +362,10 @@ acpi_status acpi_ev_init_global_lock_handler (void) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Ev_init_global_lock_handler"); + ACPI_FUNCTION_TRACE ("ev_init_global_lock_handler"); acpi_gbl_global_lock_present = TRUE; @@ -320,7 +374,7 @@ /* * If the global lock does not exist on this platform, the attempt - * to enable GBL_STS will fail (the GBL_EN bit will not stick) + * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick) * Map to AE_OK, but mark global lock as not present. * Any attempt to actually use the global lock will be flagged * with an error. @@ -336,7 +390,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_ev_acquire_global_lock + * FUNCTION: acpi_ev_acquire_global_lock * * RETURN: Status * @@ -345,116 +399,170 @@ *****************************************************************************/ acpi_status -acpi_ev_acquire_global_lock(void) +acpi_ev_acquire_global_lock ( + u16 timeout) { - acpi_status status = AE_OK; - u8 acquired = FALSE; - void *global_lock; + acpi_status status = AE_OK; + u8 acquired = FALSE; - FUNCTION_TRACE ("Ev_acquire_global_lock"); + ACPI_FUNCTION_TRACE ("ev_acquire_global_lock"); + +#ifndef ACPI_APPLICATION /* Make sure that we actually have a global lock */ if (!acpi_gbl_global_lock_present) { return_ACPI_STATUS (AE_NO_GLOBAL_LOCK); } +#endif /* One more thread wants the global lock */ acpi_gbl_global_lock_thread_count++; - - /* If we (OS side) have the hardware lock already, we are done */ + /* If we (OS side vs. BIOS side) have the hardware lock already, we are done */ if (acpi_gbl_global_lock_acquired) { return_ACPI_STATUS (AE_OK); } - /* Only if the FACS is valid */ - - if (!acpi_gbl_FACS) { - return_ACPI_STATUS (AE_OK); - } - - /* We must acquire the actual hardware lock */ - global_lock = acpi_gbl_FACS->global_lock; - ACPI_ACQUIRE_GLOBAL_LOCK (global_lock, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { /* We got the lock */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Acquired the Global Lock\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired the HW Global Lock\n")); acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS (AE_OK); } - /* * Did not get the lock. The pending bit was set above, and we must now * wait until we get the global lock released interrupt. */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Waiting for the HW Global Lock\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); - /* - * Acquire the global lock semaphore first. - * Since this wait will block, we must release the interpreter - */ + /* + * Acquire the global lock semaphore first. + * Since this wait will block, we must release the interpreter + */ status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore, - ACPI_UINT32_MAX); + timeout); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ev_release_global_lock + * FUNCTION: acpi_ev_release_global_lock * * DESCRIPTION: Releases ownership of the Global Lock. * ******************************************************************************/ -void +acpi_status acpi_ev_release_global_lock (void) { - u8 pending = FALSE; - void *global_lock; + u8 pending = FALSE; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ev_release_global_lock"); + ACPI_FUNCTION_TRACE ("ev_release_global_lock"); if (!acpi_gbl_global_lock_thread_count) { - REPORT_WARNING(("Global Lock has not be acquired, cannot release\n")); - return_VOID; + ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n")); + return_ACPI_STATUS (AE_NOT_ACQUIRED); } - /* One fewer thread has the global lock */ + /* One fewer thread has the global lock */ acpi_gbl_global_lock_thread_count--; + if (acpi_gbl_global_lock_thread_count) { + /* There are still some threads holding the lock, cannot release */ - /* Have all threads released the lock? */ + return_ACPI_STATUS (AE_OK); + } - if (!acpi_gbl_global_lock_thread_count) { - /* - * No more threads holding lock, we can do the actual hardware - * release - */ - global_lock = acpi_gbl_FACS->global_lock; - ACPI_RELEASE_GLOBAL_LOCK (global_lock, pending); - acpi_gbl_global_lock_acquired = FALSE; + /* + * No more threads holding lock, we can do the actual hardware + * release + */ + ACPI_RELEASE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, pending); + acpi_gbl_global_lock_acquired = FALSE; + /* + * If the pending bit was set, we must write GBL_RLS to the control + * register + */ + if (pending) { + status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE, 1, ACPI_MTX_LOCK); + } + + return_ACPI_STATUS (status); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_ev_terminate + * + * PARAMETERS: none + * + * RETURN: none + * + * DESCRIPTION: Disable events and free memory allocated for table storage. + * + ******************************************************************************/ + +void +acpi_ev_terminate (void) +{ + acpi_native_uint i; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_terminate"); + + + if (acpi_gbl_events_initialized) { /* - * If the pending bit was set, we must write GBL_RLS to the control - * register + * Disable all event-related functionality. + * In all cases, on error, print a message but obviously we don't abort. */ - if (pending) { - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, - GBL_RLS, 1); + + /* Disable all fixed events */ + + for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { + status = acpi_disable_event ((u32) i, 0); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable fixed event %d\n", (u32) i)); + } + } + + /* Disable all GPEs in all GPE blocks */ + + status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block); + + /* Remove SCI handler */ + + status = acpi_ev_remove_sci_handler (); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n")); } } + /* Return to original mode if necessary */ + + if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) { + status = acpi_disable (); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_disable failed\n")); + } + } return_VOID; } + diff -urN linux-2.4.21/drivers/acpi/events/evregion.c linux-2.4.22/drivers/acpi/events/evregion.c --- linux-2.4.21/drivers/acpi/events/evregion.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/evregion.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,66 +1,93 @@ /****************************************************************************** * - * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch - * $Revision: 113 $ + * Module Name: evregion - ACPI address_space (op_region) handler dispatch * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "amlcode.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evregion") + ACPI_MODULE_NAME ("evregion") + +#define ACPI_NUM_DEFAULT_SPACES 4 + +u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = { + ACPI_ADR_SPACE_SYSTEM_MEMORY, + ACPI_ADR_SPACE_SYSTEM_IO, + ACPI_ADR_SPACE_PCI_CONFIG, + ACPI_ADR_SPACE_DATA_TABLE}; /******************************************************************************* * - * FUNCTION: Acpi_ev_install_default_address_space_handlers + * FUNCTION: acpi_ev_init_address_spaces * - * PARAMETERS: + * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Installs the core subsystem address space handlers. + * DESCRIPTION: Installs the core subsystem default address space handlers. * ******************************************************************************/ acpi_status -acpi_ev_install_default_address_space_handlers ( - void) -{ - acpi_status status; +acpi_ev_init_address_spaces ( + void) { + acpi_status status; + acpi_native_uint i; - FUNCTION_TRACE ("Ev_install_default_address_space_handlers"); + ACPI_FUNCTION_TRACE ("ev_init_address_spaces"); /* * All address spaces (PCI Config, EC, SMBus) are scope dependent - * and registration must occur for a specific device. In the case - * system memory and IO address spaces there is currently no device - * associated with the address space. For these we use the root. + * and registration must occur for a specific device. + * + * In the case of the system memory and IO address spaces there is currently + * no device associated with the address space. For these we use the root. + * * We install the default PCI config space handler at the root so * that this space is immediately available even though the we have * not enumerated all the PCI Root Buses yet. This is to conform @@ -68,45 +95,39 @@ * space must be always available -- even though we are nowhere * near ready to find the PCI root buses at this point. * - * NOTE: We ignore AE_EXIST because this means that a handler has - * already been installed (via Acpi_install_address_space_handler) + * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler + * has already been installed (via acpi_install_address_space_handler). + * Similar for AE_SAME_HANDLER. */ - status = acpi_install_address_space_handler (acpi_gbl_root_node, - ACPI_ADR_SPACE_SYSTEM_MEMORY, - ACPI_DEFAULT_HANDLER, NULL, NULL); - if ((ACPI_FAILURE (status)) && - (status != AE_EXIST)) { - return_ACPI_STATUS (status); - } - - status = acpi_install_address_space_handler (acpi_gbl_root_node, - ACPI_ADR_SPACE_SYSTEM_IO, - ACPI_DEFAULT_HANDLER, NULL, NULL); - if ((ACPI_FAILURE (status)) && - (status != AE_EXIST)) { - return_ACPI_STATUS (status); - } - - status = acpi_install_address_space_handler (acpi_gbl_root_node, - ACPI_ADR_SPACE_PCI_CONFIG, - ACPI_DEFAULT_HANDLER, NULL, NULL); - if ((ACPI_FAILURE (status)) && - (status != AE_EXIST)) { - return_ACPI_STATUS (status); - } + for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { + status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node, + acpi_gbl_default_address_spaces[i], + ACPI_DEFAULT_HANDLER, NULL, NULL); + switch (status) { + case AE_OK: + case AE_SAME_HANDLER: + case AE_ALREADY_EXISTS: + + /* These exceptions are all OK */ + + break; + + default: + + return_ACPI_STATUS (status); + } + } return_ACPI_STATUS (AE_OK); } -/* TBD: [Restructure] Move elsewhere */ - /******************************************************************************* * - * FUNCTION: Acpi_ev_execute_reg_method + * FUNCTION: acpi_ev_execute_reg_method * - * PARAMETERS: Region_obj - Object structure + * PARAMETERS: region_obj - Object structure * Function - On (1) or Off (0) * * RETURN: Status @@ -117,25 +138,31 @@ static acpi_status acpi_ev_execute_reg_method ( - acpi_operand_object *region_obj, - u32 function) + union acpi_operand_object *region_obj, + u32 function) { - acpi_operand_object *params[3]; - acpi_status status; + union acpi_operand_object *params[3]; + union acpi_operand_object *region_obj2; + acpi_status status; + + ACPI_FUNCTION_TRACE ("ev_execute_reg_method"); - FUNCTION_TRACE ("Ev_execute_reg_method"); + region_obj2 = acpi_ns_get_secondary_object (region_obj); + if (!region_obj2) { + return_ACPI_STATUS (AE_NOT_EXIST); + } - if (region_obj->region.extra->extra.method_REG == NULL) { + if (region_obj2->extra.method_REG == NULL) { return_ACPI_STATUS (AE_OK); } /* - * _REG method has two arguments - * Arg0: Integer: Operation region space ID - * Same value as Region_obj->Region.Space_id - * Arg1: Integer: connection status + * _REG method has two arguments + * Arg0: Integer: Operation region space ID + * Same value as region_obj->Region.space_id + * Arg1: Integer: connection status * 1 for connecting the handler, * 0 for disconnecting the handler * Passed as a parameter @@ -151,18 +178,16 @@ goto cleanup; } - /* - * Set up the parameter objects - */ - params[0]->integer.value = region_obj->region.space_id; + /* Set up the parameter objects */ + + params[0]->integer.value = region_obj->region.space_id; params[1]->integer.value = function; params[2] = NULL; - /* - * Execute the method, no return value - */ - DEBUG_EXEC(acpi_ut_display_init_pathname (region_obj->region.extra->extra.method_REG, " [Method]")); - status = acpi_ns_evaluate_by_handle (region_obj->region.extra->extra.method_REG, params, NULL); + /* Execute the method, no return value */ + + ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL)); + status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL); acpi_ut_remove_reference (params[1]); @@ -175,13 +200,13 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_address_space_dispatch + * FUNCTION: acpi_ev_address_space_dispatch * - * PARAMETERS: Region_obj - internal region object - * Space_id - ID of the address space (0-255) + * PARAMETERS: region_obj - internal region object + * space_id - ID of the address space (0-255) * Function - Read or Write operation * Address - Where in the space to read or write - * Bit_width - Field width in bits (8, 16, or 32) + * bit_width - Field width in bits (8, 16, 32, or 64) * Value - Pointer to in or out value * * RETURN: Status @@ -193,121 +218,142 @@ acpi_status acpi_ev_address_space_dispatch ( - acpi_operand_object *region_obj, - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value) + union acpi_operand_object *region_obj, + u32 function, + acpi_physical_address address, + u32 bit_width, + void *value) { - acpi_status status; - acpi_adr_space_handler handler; - acpi_adr_space_setup region_setup; - acpi_operand_object *handler_desc; - void *region_context = NULL; + acpi_status status; + acpi_status status2; + acpi_adr_space_handler handler; + acpi_adr_space_setup region_setup; + union acpi_operand_object *handler_desc; + union acpi_operand_object *region_obj2; + void *region_context = NULL; - FUNCTION_TRACE ("Ev_address_space_dispatch"); + ACPI_FUNCTION_TRACE ("ev_address_space_dispatch"); - /* - * Ensure that there is a handler associated with this region - */ - handler_desc = region_obj->region.addr_handler; + region_obj2 = acpi_ns_get_secondary_object (region_obj); + if (!region_obj2) { + return_ACPI_STATUS (AE_NOT_EXIST); + } + + /* Ensure that there is a handler associated with this region */ + + handler_desc = region_obj->region.address_space; if (!handler_desc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n", region_obj, acpi_ut_get_region_name (region_obj->region.space_id))); - return_ACPI_STATUS(AE_NOT_EXIST); + return_ACPI_STATUS (AE_NOT_EXIST); } /* * It may be the case that the region has never been initialized * Some types of regions require special init code */ - if (!(region_obj->region.flags & AOPOBJ_INITIALIZED)) { + if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { /* * This region has not been initialized yet, do it */ - region_setup = handler_desc->addr_handler.setup; + region_setup = handler_desc->address_space.setup; if (!region_setup) { - /* - * Bad news, no init routine and not init'd - */ + /* No initialization routine, exit with error */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n", region_obj, acpi_ut_get_region_name (region_obj->region.space_id))); - return_ACPI_STATUS (AE_UNKNOWN_STATUS); + return_ACPI_STATUS (AE_NOT_EXIST); } /* * We must exit the interpreter because the region setup will potentially - * execute control methods + * execute control methods (e.g., _REG method for this region) */ acpi_ex_exit_interpreter (); status = region_setup (region_obj, ACPI_REGION_ACTIVATE, - handler_desc->addr_handler.context, ®ion_context); + handler_desc->address_space.context, ®ion_context); /* Re-enter the interpreter */ - acpi_ex_enter_interpreter (); + status2 = acpi_ex_enter_interpreter (); + if (ACPI_FAILURE (status2)) { + return_ACPI_STATUS (status2); + } + + /* Check for failure of the Region Setup */ - /* - * Init routine may fail - */ if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n", acpi_format_exception (status), acpi_ut_get_region_name (region_obj->region.space_id))); - return_ACPI_STATUS(status); + return_ACPI_STATUS (status); } - region_obj->region.flags |= AOPOBJ_INITIALIZED; - /* - * Save the returned context for use in all accesses to - * this particular region. + * Region initialization may have been completed by region_setup */ - region_obj->region.extra->extra.region_context = region_context; + if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { + region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; + + if (region_obj2->extra.region_context) { + /* The handler for this region was already installed */ + + ACPI_MEM_FREE (region_context); + } + else { + /* + * Save the returned context for use in all accesses to + * this particular region + */ + region_obj2->extra.region_context = region_context; + } + } } - /* - * We have everything we need, begin the process - */ - handler = handler_desc->addr_handler.handler; + /* We have everything we need, we can invoke the address space handler */ - ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Addrhandler %p (%p), Address %8.8X%8.8X\n", - ®ion_obj->region.addr_handler->addr_handler, handler, HIDWORD(address), - LODWORD(address))); + handler = handler_desc->address_space.handler; - if (!(handler_desc->addr_handler.flags & ADDR_HANDLER_DEFAULT_INSTALLED)) { - /* - * For handlers other than the default (supplied) handlers, we must - * exit the interpreter because the handler *might* block -- we don't - * know what it will do, so we can't hold the lock on the intepreter. + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, + "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", + ®ion_obj->region.address_space->address_space, handler, + ACPI_HIDWORD (address), ACPI_LODWORD (address), + acpi_ut_get_region_name (region_obj->region.space_id))); + + if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + /* + * For handlers other than the default (supplied) handlers, we must + * exit the interpreter because the handler *might* block -- we don't + * know what it will do, so we can't hold the lock on the intepreter. */ acpi_ex_exit_interpreter(); } - /* - * Invoke the handler. - */ + /* Call the handler */ + status = handler (function, address, bit_width, value, - handler_desc->addr_handler.context, - region_obj->region.extra->extra.region_context); + handler_desc->address_space.context, + region_obj2->extra.region_context); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region handler: %s [%s]\n", - acpi_format_exception (status), - acpi_ut_get_region_name (region_obj->region.space_id))); + ACPI_REPORT_ERROR (("Handler for [%s] returned %s\n", + acpi_ut_get_region_name (region_obj->region.space_id), + acpi_format_exception (status))); } - if (!(handler_desc->addr_handler.flags & ADDR_HANDLER_DEFAULT_INSTALLED)) { + if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter */ - acpi_ex_enter_interpreter (); + status2 = acpi_ex_enter_interpreter (); + if (ACPI_FAILURE (status2)) { + return_ACPI_STATUS (status2); + } } return_ACPI_STATUS (status); @@ -315,10 +361,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_disassociate_region_from_handler + * FUNCTION: acpi_ev_detach_region * - * PARAMETERS: Region_obj - Region Object - * Acpi_ns_is_locked - Namespace Region Already Locked? + * PARAMETERS: region_obj - Region Object + * acpi_ns_is_locked - Namespace Region Already Locked? * * RETURN: None * @@ -328,112 +374,118 @@ ******************************************************************************/ void -acpi_ev_disassociate_region_from_handler( - acpi_operand_object *region_obj, - u8 acpi_ns_is_locked) +acpi_ev_detach_region( + union acpi_operand_object *region_obj, + u8 acpi_ns_is_locked) { - acpi_operand_object *handler_obj; - acpi_operand_object *obj_desc; - acpi_operand_object **last_obj_ptr; - acpi_adr_space_setup region_setup; - void *region_context; - acpi_status status; + union acpi_operand_object *handler_obj; + union acpi_operand_object *obj_desc; + union acpi_operand_object **last_obj_ptr; + acpi_adr_space_setup region_setup; + void *region_context; + union acpi_operand_object *region_obj2; + acpi_status status; + + ACPI_FUNCTION_TRACE ("ev_detach_region"); - FUNCTION_TRACE ("Ev_disassociate_region_from_handler"); + region_obj2 = acpi_ns_get_secondary_object (region_obj); + if (!region_obj2) { + return_VOID; + } + region_context = region_obj2->extra.region_context; - region_context = region_obj->region.extra->extra.region_context; + /* Get the address handler from the region object */ - /* - * Get the address handler from the region object - */ - handler_obj = region_obj->region.addr_handler; + handler_obj = region_obj->region.address_space; if (!handler_obj) { - /* - * This region has no handler, all done - */ + /* This region has no handler, all done */ + return_VOID; } + /* Find this region in the handler's list */ - /* - * Find this region in the handler's list - */ - obj_desc = handler_obj->addr_handler.region_list; - last_obj_ptr = &handler_obj->addr_handler.region_list; + obj_desc = handler_obj->address_space.region_list; + last_obj_ptr = &handler_obj->address_space.region_list; while (obj_desc) { - /* - * See if this is the one - */ + /* Is this the correct Region? */ + if (obj_desc == region_obj) { ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Removing Region %p from address handler %p\n", region_obj, handler_obj)); - /* - * This is it, remove it from the handler's list - */ + + /* This is it, remove it from the handler's list */ + *last_obj_ptr = obj_desc->region.next; obj_desc->region.next = NULL; /* Must clear field */ if (acpi_ns_is_locked) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_VOID; + } } - /* - * Now stop region accesses by executing the _REG method - */ - acpi_ev_execute_reg_method (region_obj, 0); + /* Now stop region accesses by executing the _REG method */ + + status = acpi_ev_execute_reg_method (region_obj, 0); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n", + acpi_format_exception (status), + acpi_ut_get_region_name (region_obj->region.space_id))); + } if (acpi_ns_is_locked) { - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_VOID; + } } - /* - * Call the setup handler with the deactivate notification - */ - region_setup = handler_obj->addr_handler.setup; + /* Call the setup handler with the deactivate notification */ + + region_setup = handler_obj->address_space.setup; status = region_setup (region_obj, ACPI_REGION_DEACTIVATE, - handler_obj->addr_handler.context, ®ion_context); + handler_obj->address_space.context, ®ion_context); + + /* Init routine may fail, Just ignore errors */ - /* - * Init routine may fail, Just ignore errors - */ if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n", acpi_format_exception (status), acpi_ut_get_region_name (region_obj->region.space_id))); } - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); + region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE); /* - * Remove handler reference in the region + * Remove handler reference in the region * - * NOTE: this doesn't mean that the region goes away - * The region is just inaccessible as indicated to - * the _REG method + * NOTE: this doesn't mean that the region goes away + * The region is just inaccessible as indicated to + * the _REG method * - * If the region is on the handler's list - * this better be the region's handler + * If the region is on the handler's list + * this better be the region's handler */ - region_obj->region.addr_handler = NULL; + region_obj->region.address_space = NULL; + acpi_ut_remove_reference (handler_obj); return_VOID; + } - } /* found the right handler */ + /* Walk the linked list of handlers */ - /* - * Move through the linked list of handlers - */ last_obj_ptr = &obj_desc->region.next; obj_desc = obj_desc->region.next; } - /* - * If we get here, the region was not in the handler's region list - */ + /* If we get here, the region was not in the handler's region list */ + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Cannot remove region %p from address handler %p\n", region_obj, handler_obj)); @@ -444,11 +496,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_associate_region_and_handler + * FUNCTION: acpi_ev_attach_region * - * PARAMETERS: Handler_obj - Handler Object - * Region_obj - Region Object - * Acpi_ns_is_locked - Namespace Region Already Locked? + * PARAMETERS: handler_obj - Handler Object + * region_obj - Region Object + * acpi_ns_is_locked - Namespace Region Already Locked? * * RETURN: None * @@ -458,15 +510,16 @@ ******************************************************************************/ acpi_status -acpi_ev_associate_region_and_handler ( - acpi_operand_object *handler_obj, - acpi_operand_object *region_obj, - u8 acpi_ns_is_locked) +acpi_ev_attach_region ( + union acpi_operand_object *handler_obj, + union acpi_operand_object *region_obj, + u8 acpi_ns_is_locked) { - acpi_status status; + acpi_status status; + acpi_status status2; - FUNCTION_TRACE ("Ev_associate_region_and_handler"); + ACPI_FUNCTION_TRACE ("ev_attach_region"); ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, @@ -474,28 +527,38 @@ region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id))); - /* - * Link this region to the front of the handler's list - */ - region_obj->region.next = handler_obj->addr_handler.region_list; - handler_obj->addr_handler.region_list = region_obj; + /* Link this region to the front of the handler's list */ - /* - * set the region's handler - */ - region_obj->region.addr_handler = handler_obj; + region_obj->region.next = handler_obj->address_space.region_list; + handler_obj->address_space.region_list = region_obj; + + /* Install the region's handler */ + + if (region_obj->region.address_space) { + return_ACPI_STATUS (AE_ALREADY_EXISTS); + } + + region_obj->region.address_space = handler_obj; + acpi_ut_add_reference (handler_obj); /* - * Last thing, tell all users that this region is usable + * Tell all users that this region is usable by running the _REG + * method */ if (acpi_ns_is_locked) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + status2 = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status2)) { + return_ACPI_STATUS (status2); + } } status = acpi_ev_execute_reg_method (region_obj, 1); if (acpi_ns_is_locked) { - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status2 = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status2)) { + return_ACPI_STATUS (status2); + } } return_ACPI_STATUS (status); @@ -504,14 +567,14 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_addr_handler_helper + * FUNCTION: acpi_ev_install_handler * * PARAMETERS: Handle - Node to be dumped * Level - Nesting level of the handle - * Context - Passed into Acpi_ns_walk_namespace + * Context - Passed into acpi_ns_walk_namespace * - * DESCRIPTION: This routine checks to see if the object is a Region if it - * is then the address handler is installed in it. + * DESCRIPTION: This routine installs an address handler into objects that are + * of type Region or Device. * * If the Object is a Device, and the device has a handler of * the same type then the search is terminated in that branch. @@ -522,23 +585,23 @@ ******************************************************************************/ acpi_status -acpi_ev_addr_handler_helper ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value) +acpi_ev_install_handler ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) { - acpi_operand_object *handler_obj; - acpi_operand_object *tmp_obj; - acpi_operand_object *obj_desc; - acpi_namespace_node *node; - acpi_status status; + union acpi_operand_object *handler_obj; + union acpi_operand_object *next_handler_obj; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + acpi_status status; - PROC_NAME ("Ev_addr_handler_helper"); + ACPI_FUNCTION_NAME ("ev_install_handler"); - handler_obj = (acpi_operand_object *) context; + handler_obj = (union acpi_operand_object *) context; /* Parameter validation */ @@ -554,8 +617,8 @@ } /* - * We only care about regions.and objects - * that can have address handlers + * We only care about regions.and objects + * that are allowed to have address space handlers */ if ((node->type != ACPI_TYPE_DEVICE) && (node->type != ACPI_TYPE_REGION) && @@ -567,81 +630,70 @@ obj_desc = acpi_ns_get_attached_object (node); if (!obj_desc) { - /* - * The object DNE, we don't care about it - */ + /* No object, just exit */ + return (AE_OK); } - /* - * Devices are handled different than regions - */ - if (IS_THIS_OBJECT_TYPE (obj_desc, ACPI_TYPE_DEVICE)) { - /* - * See if this guy has any handlers - */ - tmp_obj = obj_desc->device.addr_handler; - while (tmp_obj) { - /* - * Now let's see if it's for the same address space. - */ - if (tmp_obj->addr_handler.space_id == handler_obj->addr_handler.space_id) { - /* - * It's for the same address space - */ + /* Devices are handled different than regions */ + + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) { + /* Check if this Device already has a handler for this address space */ + + next_handler_obj = obj_desc->device.address_space; + while (next_handler_obj) { + /* Found a handler, is it for the same address space? */ + + if (next_handler_obj->address_space.space_id == handler_obj->address_space.space_id) { ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Found handler for region [%s] in device %p(%p) handler %p\n", - acpi_ut_get_region_name (handler_obj->addr_handler.space_id), - obj_desc, tmp_obj, handler_obj)); + acpi_ut_get_region_name (handler_obj->address_space.space_id), + obj_desc, next_handler_obj, handler_obj)); /* - * Since the object we found it on was a device, then it - * means that someone has already installed a handler for - * the branch of the namespace from this device on. Just - * bail out telling the walk routine to not traverse this - * branch. This preserves the scoping rule for handlers. + * Since the object we found it on was a device, then it + * means that someone has already installed a handler for + * the branch of the namespace from this device on. Just + * bail out telling the walk routine to not traverse this + * branch. This preserves the scoping rule for handlers. */ return (AE_CTRL_DEPTH); } - /* - * Move through the linked list of handlers - */ - tmp_obj = tmp_obj->addr_handler.next; + /* Walk the linked list of handlers attached to this device */ + + next_handler_obj = next_handler_obj->address_space.next; } /* - * As long as the device didn't have a handler for this - * space we don't care about it. We just ignore it and - * proceed. + * As long as the device didn't have a handler for this + * space we don't care about it. We just ignore it and + * proceed. */ return (AE_OK); } - /* - * Only here if it was a region - */ - if (obj_desc->region.space_id != handler_obj->addr_handler.space_id) { + /* Object is a Region */ + + if (obj_desc->region.space_id != handler_obj->address_space.space_id) { /* - * This region is for a different address space - * ignore it + * This region is for a different address space + * -- just ignore it */ return (AE_OK); } /* - * Now we have a region and it is for the handler's address - * space type. + * Now we have a region and it is for the handler's address + * space type. * - * First disconnect region for any previous handler (if any) + * First disconnect region for any previous handler (if any) */ - acpi_ev_disassociate_region_from_handler (obj_desc, FALSE); + acpi_ev_detach_region (obj_desc, FALSE); - /* - * Then connect the region to the new handler - */ - status = acpi_ev_associate_region_and_handler (handler_obj, obj_desc, FALSE); + /* Connect the region to the new handler */ + status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE); return (status); } diff -urN linux-2.4.21/drivers/acpi/events/evrgnini.c linux-2.4.22/drivers/acpi/events/evrgnini.c --- linux-2.4.21/drivers/acpi/events/evrgnini.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/evrgnini.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,47 +1,63 @@ /****************************************************************************** * - * Module Name: evrgnini- ACPI Address_space (Op_region) init - * $Revision: 48 $ + * Module Name: evrgnini- ACPI address_space (op_region) init * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evrgnini") + ACPI_MODULE_NAME ("evrgnini") /******************************************************************************* * - * FUNCTION: Acpi_ev_system_memory_region_setup + * FUNCTION: acpi_ev_system_memory_region_setup * - * PARAMETERS: Region_obj - region we are interested in - * Function - start or stop - * Handler_context - Address space handler context - * Region_context - Region specific context + * PARAMETERS: region_obj - Region we are interested in + * Function - Start or stop + * handler_context - Address space handler context + * region_context - Region specific context * * RETURN: Status * @@ -51,12 +67,16 @@ acpi_status acpi_ev_system_memory_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context) + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context) { - FUNCTION_TRACE ("Ev_system_memory_region_setup"); + union acpi_operand_object *region_desc = (union acpi_operand_object *) handle; + struct acpi_mem_space_context *local_region_context; + + + ACPI_FUNCTION_TRACE ("ev_system_memory_region_setup"); if (function == ACPI_REGION_DEACTIVATE) { @@ -67,26 +87,31 @@ return_ACPI_STATUS (AE_OK); } + /* Create a new context */ - /* Activate. Create a new context */ - - *region_context = ACPI_MEM_CALLOCATE (sizeof (acpi_mem_space_context)); - if (!(*region_context)) { + local_region_context = ACPI_MEM_CALLOCATE (sizeof (struct acpi_mem_space_context)); + if (!(local_region_context)) { return_ACPI_STATUS (AE_NO_MEMORY); } + /* Save the region length and address for use in the handler */ + + local_region_context->length = region_desc->region.length; + local_region_context->address = region_desc->region.address; + + *region_context = local_region_context; return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ev_io_space_region_setup + * FUNCTION: acpi_ev_io_space_region_setup * - * PARAMETERS: Region_obj - region we are interested in - * Function - start or stop - * Handler_context - Address space handler context - * Region_context - Region specific context + * PARAMETERS: region_obj - Region we are interested in + * Function - Start or stop + * handler_context - Address space handler context + * region_context - Region specific context * * RETURN: Status * @@ -96,12 +121,12 @@ acpi_status acpi_ev_io_space_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context) + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context) { - FUNCTION_TRACE ("Ev_io_space_region_setup"); + ACPI_FUNCTION_TRACE ("ev_io_space_region_setup"); if (function == ACPI_REGION_DEACTIVATE) { @@ -117,12 +142,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_pci_config_region_setup + * FUNCTION: acpi_ev_pci_config_region_setup * - * PARAMETERS: Region_obj - region we are interested in - * Function - start or stop - * Handler_context - Address space handler context - * Region_context - Region specific context + * PARAMETERS: region_obj - Region we are interested in + * Function - Start or stop + * handler_context - Address space handler context + * region_context - Region specific context * * RETURN: Status * @@ -134,128 +159,155 @@ acpi_status acpi_ev_pci_config_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context) + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context) { - acpi_status status = AE_OK; - acpi_integer temp; - acpi_pci_id *pci_id = *region_context; - acpi_operand_object *handler_obj; - acpi_namespace_node *node; - acpi_operand_object *region_obj = (acpi_operand_object *) handle; - acpi_device_id object_hID; + acpi_status status = AE_OK; + acpi_integer pci_value; + struct acpi_pci_id *pci_id = *region_context; + union acpi_operand_object *handler_obj; + struct acpi_namespace_node *parent_node; + struct acpi_namespace_node *pci_root_node; + union acpi_operand_object *region_obj = (union acpi_operand_object *) handle; + struct acpi_device_id object_hID; - FUNCTION_TRACE ("Ev_pci_config_region_setup"); + ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup"); - handler_obj = region_obj->region.addr_handler; + handler_obj = region_obj->region.address_space; if (!handler_obj) { /* - * No installed handler. This shouldn't happen because the dispatch - * routine checks before we get here, but we check again just in case. + * No installed handler. This shouldn't happen because the dispatch + * routine checks before we get here, but we check again just in case. */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Attempting to init a region %p, with no handler\n", region_obj)); return_ACPI_STATUS (AE_NOT_EXIST); } + *region_context = NULL; if (function == ACPI_REGION_DEACTIVATE) { if (pci_id) { ACPI_MEM_FREE (pci_id); - *region_context = NULL; } - return_ACPI_STATUS (status); } - - /* Create a new context */ - - pci_id = ACPI_MEM_CALLOCATE (sizeof (acpi_pci_id)); - if (!pci_id) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* - * For PCI Config space access, we have to pass the segment, bus, - * device and function numbers. This routine must acquire those. - */ + parent_node = acpi_ns_get_parent_node (region_obj->region.node); /* - * First get device and function numbers from the _ADR object - * in the parent's scope. - */ - node = acpi_ns_get_parent_object (region_obj->region.node); - - - /* Acpi_evaluate the _ADR object */ - - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp); - - /* - * The default is zero, since the allocation above zeroed the data, just - * do nothing on failures. - */ - if (ACPI_SUCCESS (status)) { - pci_id->device = HIWORD (temp); - pci_id->function = LOWORD (temp); - } - - /* - * Get the _SEG and _BBN values from the device upon which the handler - * is installed. + * Get the _SEG and _BBN values from the device upon which the handler + * is installed. * - * We need to get the _SEG and _BBN objects relative to the PCI BUS device. - * This is the device the handler has been registered to handle. + * We need to get the _SEG and _BBN objects relative to the PCI BUS device. + * This is the device the handler has been registered to handle. */ /* - * If the Addr_handler.Node is still pointing to the root, we need - * to scan upward for a PCI Root bridge and re-associate the Op_region - * handlers with that device. + * If the address_space.Node is still pointing to the root, we need + * to scan upward for a PCI Root bridge and re-associate the op_region + * handlers with that device. */ - if (handler_obj->addr_handler.node == acpi_gbl_root_node) { - /* - * Node is currently the parent object - */ - while (node != acpi_gbl_root_node) { - status = acpi_ut_execute_HID (node, &object_hID); + if (handler_obj->address_space.node == acpi_gbl_root_node) { + /* Start search from the parent object */ + + pci_root_node = parent_node; + while (pci_root_node != acpi_gbl_root_node) { + status = acpi_ut_execute_HID (pci_root_node, &object_hID); if (ACPI_SUCCESS (status)) { - if (!(STRNCMP (object_hID.buffer, PCI_ROOT_HID_STRING, + /* Got a valid _HID, check if this is a PCI root */ + + if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING, sizeof (PCI_ROOT_HID_STRING)))) { - acpi_install_address_space_handler (node, + /* Install a handler for this PCI root bridge */ + + status = acpi_install_address_space_handler ((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); + if (ACPI_FAILURE (status)) { + if (status == AE_SAME_HANDLER) { + /* + * It is OK if the handler is already installed on the root + * bridge. Still need to return a context object for the + * new PCI_Config operation region, however. + */ + status = AE_OK; + } + else { + ACPI_REPORT_ERROR (( + "Could not install pci_config handler for Root Bridge %4.4s, %s\n", + pci_root_node->name.ascii, acpi_format_exception (status))); + } + } break; } } - node = acpi_ns_get_parent_object (node); + pci_root_node = acpi_ns_get_parent_node (pci_root_node); } + + /* PCI root bridge not found, use namespace root node */ } else { - node = handler_obj->addr_handler.node; + pci_root_node = handler_obj->address_space.node; } /* - * The PCI segment number comes from the _SEG method + * If this region is now initialized, we are done. + * (install_address_space_handler could have initialized it) */ - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp); - if (ACPI_SUCCESS (status)) { - pci_id->segment = LOWORD (temp); + if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) { + return_ACPI_STATUS (AE_OK); + } + + /* Region is still not initialized. Create a new context */ + + pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id)); + if (!pci_id) { + return_ACPI_STATUS (AE_NO_MEMORY); } /* - * The PCI bus number comes from the _BBN method + * For PCI_Config space access, we need the segment, bus, + * device and function numbers. Acquire them here. + */ + + /* + * Get the PCI device and function numbers from the _ADR object + * contained in the parent's scope. + */ + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value); + + /* + * The default is zero, and since the allocation above zeroed + * the data, just do nothing on failure. */ - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp); if (ACPI_SUCCESS (status)) { - pci_id->bus = LOWORD (temp); + pci_id->device = ACPI_HIWORD (ACPI_LODWORD (pci_value)); + pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value)); } + /* The PCI segment number comes from the _SEG method */ + + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value); + if (ACPI_SUCCESS (status)) { + pci_id->segment = ACPI_LOWORD (pci_value); + } + + /* The PCI bus number comes from the _BBN method */ + + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value); + if (ACPI_SUCCESS (status)) { + pci_id->bus = ACPI_LOWORD (pci_value); + } + + /* Complete this device's pci_id */ + + acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id); + *region_context = pci_id; return_ACPI_STATUS (AE_OK); } @@ -263,12 +315,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_pci_bar_region_setup + * FUNCTION: acpi_ev_pci_bar_region_setup * - * PARAMETERS: Region_obj - region we are interested in - * Function - start or stop - * Handler_context - Address space handler context - * Region_context - Region specific context + * PARAMETERS: region_obj - Region we are interested in + * Function - Start or stop + * handler_context - Address space handler context + * region_context - Region specific context * * RETURN: Status * @@ -280,13 +332,12 @@ acpi_status acpi_ev_pci_bar_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context) + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context) { - - FUNCTION_TRACE ("Ev_pci_bar_region_setup"); + ACPI_FUNCTION_TRACE ("ev_pci_bar_region_setup"); return_ACPI_STATUS (AE_OK); @@ -295,12 +346,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_cmos_region_setup + * FUNCTION: acpi_ev_cmos_region_setup * - * PARAMETERS: Region_obj - region we are interested in - * Function - start or stop - * Handler_context - Address space handler context - * Region_context - Region specific context + * PARAMETERS: region_obj - Region we are interested in + * Function - Start or stop + * handler_context - Address space handler context + * region_context - Region specific context * * RETURN: Status * @@ -312,13 +363,12 @@ acpi_status acpi_ev_cmos_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context) + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context) { - - FUNCTION_TRACE ("Ev_cmos_region_setup"); + ACPI_FUNCTION_TRACE ("ev_cmos_region_setup"); return_ACPI_STATUS (AE_OK); @@ -327,12 +377,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_default_region_setup + * FUNCTION: acpi_ev_default_region_setup * - * PARAMETERS: Region_obj - region we are interested in - * Function - start or stop - * Handler_context - Address space handler context - * Region_context - Region specific context + * PARAMETERS: region_obj - Region we are interested in + * Function - Start or stop + * handler_context - Address space handler context + * region_context - Region specific context * * RETURN: Status * @@ -342,12 +392,12 @@ acpi_status acpi_ev_default_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context) + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context) { - FUNCTION_TRACE ("Ev_default_region_setup"); + ACPI_FUNCTION_TRACE ("ev_default_region_setup"); if (function == ACPI_REGION_DEACTIVATE) { @@ -363,9 +413,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ev_initialize_region + * FUNCTION: acpi_ev_initialize_region * - * PARAMETERS: Region_obj - Region we are initializing + * PARAMETERS: region_obj - Region we are initializing + * acpi_ns_locked - Is namespace locked? * * RETURN: Status * @@ -375,7 +426,7 @@ * Get the appropriate address space handler for a newly * created region. * - * This also performs address space specific intialization. For + * This also performs address space specific initialization. For * example, PCI regions must have an _ADR object that contains * a PCI address in the scope of the definition. This address is * required to perform an access to PCI config space. @@ -384,113 +435,124 @@ acpi_status acpi_ev_initialize_region ( - acpi_operand_object *region_obj, - u8 acpi_ns_locked) + union acpi_operand_object *region_obj, + u8 acpi_ns_locked) { - acpi_operand_object *handler_obj; - acpi_operand_object *obj_desc; - ACPI_ADR_SPACE_TYPE space_id; - acpi_namespace_node *node; - acpi_status status; - acpi_namespace_node *method_node; - acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG; + union acpi_operand_object *handler_obj; + union acpi_operand_object *obj_desc; + acpi_adr_space_type space_id; + struct acpi_namespace_node *node; + acpi_status status; + struct acpi_namespace_node *method_node; + acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG; + union acpi_operand_object *region_obj2; - FUNCTION_TRACE_U32 ("Ev_initialize_region", acpi_ns_locked); + ACPI_FUNCTION_TRACE_U32 ("ev_initialize_region", acpi_ns_locked); if (!region_obj) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - node = acpi_ns_get_parent_object (region_obj->region.node); + if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) { + return_ACPI_STATUS (AE_OK); + } + + region_obj2 = acpi_ns_get_secondary_object (region_obj); + if (!region_obj2) { + return_ACPI_STATUS (AE_NOT_EXIST); + } + + node = acpi_ns_get_parent_node (region_obj->region.node); space_id = region_obj->region.space_id; - region_obj->region.addr_handler = NULL; - region_obj->region.extra->extra.method_REG = NULL; - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); + /* Setup defaults */ + + region_obj->region.address_space = NULL; + region_obj2->extra.method_REG = NULL; + region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE); + region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED; + + /* Find any "_REG" method associated with this region definition */ - /* - * Find any "_REG" associated with this region definition - */ status = acpi_ns_search_node (*reg_name_ptr, node, ACPI_TYPE_METHOD, &method_node); if (ACPI_SUCCESS (status)) { /* - * The _REG method is optional and there can be only one per region - * definition. This will be executed when the handler is attached - * or removed + * The _REG method is optional and there can be only one per region + * definition. This will be executed when the handler is attached + * or removed */ - region_obj->region.extra->extra.method_REG = method_node; + region_obj2->extra.method_REG = method_node; } /* - * The following loop depends upon the root Node having no parent - * ie: Acpi_gbl_Root_node->Parent_entry being set to NULL + * The following loop depends upon the root Node having no parent + * ie: acpi_gbl_root_node->parent_entry being set to NULL */ while (node) { - /* - * Check to see if a handler exists - */ + /* Check to see if a handler exists */ + handler_obj = NULL; obj_desc = acpi_ns_get_attached_object (node); if (obj_desc) { - /* - * can only be a handler if the object exists - */ + /* Can only be a handler if the object exists */ + switch (node->type) { case ACPI_TYPE_DEVICE: - handler_obj = obj_desc->device.addr_handler; + handler_obj = obj_desc->device.address_space; break; case ACPI_TYPE_PROCESSOR: - handler_obj = obj_desc->processor.addr_handler; + handler_obj = obj_desc->processor.address_space; break; case ACPI_TYPE_THERMAL: - handler_obj = obj_desc->thermal_zone.addr_handler; + handler_obj = obj_desc->thermal_zone.address_space; + break; + + default: + /* Ignore other objects */ break; } while (handler_obj) { - /* - * This guy has at least one address handler - * see if it has the type we want - */ - if (handler_obj->addr_handler.space_id == space_id) { + /* Is this handler of the correct type? */ + + if (handler_obj->address_space.space_id == space_id) { + /* Found correct handler */ + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Found handler %p for region %p in obj %p\n", handler_obj, region_obj, obj_desc)); - /* - * Found it! Now update the region and the handler - */ - acpi_ev_associate_region_and_handler (handler_obj, region_obj, - acpi_ns_locked); + status = acpi_ev_attach_region (handler_obj, region_obj, + acpi_ns_locked); + return_ACPI_STATUS (AE_OK); } - handler_obj = handler_obj->addr_handler.next; + /* Try next handler in the list */ - } /* while handlerobj */ + handler_obj = handler_obj->address_space.next; + } } /* - * This one does not have the handler we need - * Pop up one level + * This node does not have the handler we need; + * Pop up one level */ - node = acpi_ns_get_parent_object (node); + node = acpi_ns_get_parent_node (node); + } - } /* while Node != ROOT */ + /* If we get here, there is no handler for this region */ - /* - * If we get here, there is no handler for this region - */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "No handler for Region_type %s(%X) (Region_obj %p)\n", + "No handler for region_type %s(%X) (region_obj %p)\n", acpi_ut_get_region_name (space_id), space_id, region_obj)); return_ACPI_STATUS (AE_NOT_EXIST); diff -urN linux-2.4.21/drivers/acpi/events/evsci.c linux-2.4.22/drivers/acpi/events/evsci.c --- linux-2.4.21/drivers/acpi/events/evsci.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/evsci.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,281 +2,198 @@ * * Module Name: evsci - System Control Interrupt configuration and * legacy to ACPI mode state transition functions - * $Revision: 74 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "achware.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evsci") - - -/* - * Elements correspond to counts for TMR, NOT_USED, GBL, PWR_BTN, SLP_BTN, RTC, - * and GENERAL respectively. These counts are modified by the ACPI interrupt - * handler. - * - * TBD: [Investigate] Note that GENERAL should probably be split out into - * one element for each bit in the GPE registers - */ + ACPI_MODULE_NAME ("evsci") /******************************************************************************* * - * FUNCTION: Acpi_ev_sci_handler + * FUNCTION: acpi_ev_sci_xrupt_handler * * PARAMETERS: Context - Calling Context * * RETURN: Status code indicates whether interrupt was handled. * * DESCRIPTION: Interrupt handler that will figure out what function or - * control method to call to deal with a SCI. Installed - * using BU interrupt support. + * control method to call to deal with a SCI. * ******************************************************************************/ -static u32 -acpi_ev_sci_handler (void *context) +static u32 ACPI_SYSTEM_XFACE +acpi_ev_sci_xrupt_handler ( + void *context) { - u32 interrupt_handled = INTERRUPT_NOT_HANDLED; + struct acpi_gpe_xrupt_info *gpe_xrupt_list = context; + u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; - FUNCTION_TRACE("Ev_sci_handler"); + ACPI_FUNCTION_TRACE("ev_sci_xrupt_handler"); /* - * Make sure that ACPI is enabled by checking SCI_EN. Note that we are - * required to treat the SCI interrupt as sharable, level, active low. + * We are guaranteed by the ACPI CA initialization/shutdown code that + * if this interrupt handler is installed, ACPI is enabled. */ - if (!acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) { - /* ACPI is not enabled; this interrupt cannot be for us */ - - return_VALUE (INTERRUPT_NOT_HANDLED); - } /* - * Fixed Acpi_events: - * ------------- - * Check for and dispatch any Fixed Acpi_events that have occurred + * Fixed Events: + * Check for and dispatch any Fixed Events that have occurred */ interrupt_handled |= acpi_ev_fixed_event_detect (); /* - * GPEs: - * ----- + * General Purpose Events: * Check for and dispatch any GPEs that have occurred */ - interrupt_handled |= acpi_ev_gpe_detect (); + interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list); return_VALUE (interrupt_handled); } -/****************************************************************************** - * - * FUNCTION: Acpi_ev_install_sci_handler - * - * PARAMETERS: none - * - * RETURN: Status - * - * DESCRIPTION: Installs SCI handler. - * - ******************************************************************************/ - -u32 -acpi_ev_install_sci_handler (void) -{ - u32 status = AE_OK; - - - FUNCTION_TRACE ("Ev_install_sci_handler"); - - - status = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, - acpi_ev_sci_handler, NULL); - return_ACPI_STATUS (status); -} - - -/****************************************************************************** - +/******************************************************************************* * - * FUNCTION: Acpi_ev_remove_sci_handler + * FUNCTION: acpi_ev_gpe_xrupt_handler * - * PARAMETERS: none + * PARAMETERS: Context - Calling Context * - * RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not - * installed to begin with + * RETURN: Status code indicates whether interrupt was handled. * - * DESCRIPTION: Restores original status of all fixed event enable bits and - * removes SCI handler. + * DESCRIPTION: Handler for GPE Block Device interrupts * ******************************************************************************/ -acpi_status -acpi_ev_remove_sci_handler (void) +u32 ACPI_SYSTEM_XFACE +acpi_ev_gpe_xrupt_handler ( + void *context) { - FUNCTION_TRACE ("Ev_remove_sci_handler"); - + struct acpi_gpe_xrupt_info *gpe_xrupt_list = context; + u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; -#if 0 - /* TBD:[Investigate] Figure this out!! Disable all events first ??? */ - if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (TMR_FIXED_EVENT)) { - acpi_event_disable_event (TMR_FIXED_EVENT); - } + ACPI_FUNCTION_TRACE("ev_gpe_xrupt_handler"); - if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (GBL_FIXED_EVENT)) { - acpi_event_disable_event (GBL_FIXED_EVENT); - } - if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (PWR_BTN_FIXED_EVENT)) { - acpi_event_disable_event (PWR_BTN_FIXED_EVENT); - } - - if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (SLP_BTN_FIXED_EVENT)) { - acpi_event_disable_event (SLP_BTN_FIXED_EVENT); - } - - if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (RTC_FIXED_EVENT)) { - acpi_event_disable_event (RTC_FIXED_EVENT); - } - - original_fixed_enable_bit_status = 0; - -#endif + /* + * We are guaranteed by the ACPI CA initialization/shutdown code that + * if this interrupt handler is installed, ACPI is enabled. + */ - acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, - acpi_ev_sci_handler); + /* + * GPEs: + * Check for and dispatch any GPEs that have occurred + */ + interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list); - return_ACPI_STATUS (AE_OK); + return_VALUE (interrupt_handled); } -/******************************************************************************* +/****************************************************************************** * - * FUNCTION: Acpi_ev_restore_acpi_state + * FUNCTION: acpi_ev_install_sci_handler * * PARAMETERS: none * - * RETURN: none + * RETURN: Status * - * DESCRIPTION: Restore the original ACPI state of the machine + * DESCRIPTION: Installs SCI handler. * ******************************************************************************/ -void -acpi_ev_restore_acpi_state (void) +u32 +acpi_ev_install_sci_handler (void) { - u32 index; - - - FUNCTION_TRACE ("Ev_restore_acpi_state"); - - - /* Restore the state of the chipset enable bits. */ + u32 status = AE_OK; - if (acpi_gbl_restore_acpi_chipset == TRUE) { - /* Restore the fixed events */ - if (acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN) != - acpi_gbl_pm1_enable_register_save) { - acpi_hw_register_write (ACPI_MTX_LOCK, PM1_EN, - acpi_gbl_pm1_enable_register_save); - } + ACPI_FUNCTION_TRACE ("ev_install_sci_handler"); - /* Ensure that all status bits are clear */ - - acpi_hw_clear_acpi_status (); - - - /* Now restore the GPEs */ - - for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { - if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index) != - acpi_gbl_gpe0enable_register_save[index]) { - acpi_hw_register_write (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index, - acpi_gbl_gpe0enable_register_save[index]); - } - } - - /* GPE 1 present? */ - - if (acpi_gbl_FADT->gpe1_blk_len) { - for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { - if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index) != - acpi_gbl_gpe1_enable_register_save[index]) { - acpi_hw_register_write (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index, - acpi_gbl_gpe1_enable_register_save[index]); - } - } - } - - if (acpi_hw_get_mode() != acpi_gbl_original_mode) { - acpi_hw_set_mode (acpi_gbl_original_mode); - } - } - - return_VOID; + status = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, + acpi_ev_sci_xrupt_handler, acpi_gbl_gpe_xrupt_list_head); + return_ACPI_STATUS (status); } /****************************************************************************** * - * FUNCTION: Acpi_ev_terminate + * FUNCTION: acpi_ev_remove_sci_handler * * PARAMETERS: none * - * RETURN: none + * RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not + * installed to begin with + * + * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be + * taken. * - * DESCRIPTION: free memory allocated for table storage. + * Note: It doesn't seem important to disable all events or set the event + * enable registers to their original values. The OS should disable + * the SCI interrupt level when the handler is removed, so no more + * events will come in. * ******************************************************************************/ -void -acpi_ev_terminate (void) +acpi_status +acpi_ev_remove_sci_handler (void) { + acpi_status status; - FUNCTION_TRACE ("Ev_terminate"); + ACPI_FUNCTION_TRACE ("ev_remove_sci_handler"); - /* - * Free global tables, etc. - */ - if (acpi_gbl_gpe_registers) { - ACPI_MEM_FREE (acpi_gbl_gpe_registers); - } - - if (acpi_gbl_gpe_info) { - ACPI_MEM_FREE (acpi_gbl_gpe_info); - } - return_VOID; + /* Just let the OS remove the handler and disable the level */ + + status = acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, + acpi_ev_sci_xrupt_handler); + + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/events/evxface.c linux-2.4.22/drivers/acpi/events/evxface.c --- linux-2.4.21/drivers/acpi/events/evxface.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/evxface.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,43 +1,59 @@ /****************************************************************************** * * Module Name: evxface - External interfaces for ACPI events - * $Revision: 116 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "acnamesp.h" -#include "acevents.h" -#include "amlcode.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evxface") + ACPI_MODULE_NAME ("evxface") /******************************************************************************* * - * FUNCTION: Acpi_install_fixed_event_handler + * FUNCTION: acpi_install_fixed_event_handler * * PARAMETERS: Event - Event type to enable. * Handler - Pointer to the handler function for the @@ -53,14 +69,14 @@ acpi_status acpi_install_fixed_event_handler ( - u32 event, - acpi_event_handler handler, - void *context) + u32 event, + acpi_event_handler handler, + void *context) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Acpi_install_fixed_event_handler"); + ACPI_FUNCTION_TRACE ("acpi_install_fixed_event_handler"); /* Parameter validation */ @@ -69,23 +85,25 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Don't allow two handlers. */ if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { - status = AE_EXIST; + status = AE_ALREADY_EXISTS; goto cleanup; } - /* Install the handler before enabling the event */ acpi_gbl_fixed_event_handlers[event].handler = handler; acpi_gbl_fixed_event_handlers[event].context = context; - status = acpi_enable_event (event, ACPI_EVENT_FIXED, 0); - if (!ACPI_SUCCESS (status)) { + status = acpi_enable_event (event, 0); + if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n")); /* Remove the handler */ @@ -93,7 +111,6 @@ acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; } - else { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Enabled fixed event %X, Handler=%p\n", event, handler)); @@ -101,14 +118,14 @@ cleanup: - acpi_ut_release_mutex (ACPI_MTX_EVENTS); + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_remove_fixed_event_handler + * FUNCTION: acpi_remove_fixed_event_handler * * PARAMETERS: Event - Event type to disable. * Handler - Address of the handler @@ -121,13 +138,13 @@ acpi_status acpi_remove_fixed_event_handler ( - u32 event, - acpi_event_handler handler) + u32 event, + acpi_event_handler handler) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Acpi_remove_fixed_event_handler"); + ACPI_FUNCTION_TRACE ("acpi_remove_fixed_event_handler"); /* Parameter validation */ @@ -136,18 +153,21 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Disable the event before removing the handler */ - status = acpi_disable_event(event, ACPI_EVENT_FIXED, 0); + status = acpi_disable_event (event, 0); /* Always Remove the handler */ acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; - if (!ACPI_SUCCESS (status)) { + if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not write to fixed event enable register.\n")); } @@ -155,19 +175,19 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", event)); } - acpi_ut_release_mutex (ACPI_MTX_EVENTS); + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_install_notify_handler + * FUNCTION: acpi_install_notify_handler * * PARAMETERS: Device - The device for which notifies will be handled - * Handler_type - The type of handler: - * ACPI_SYSTEM_NOTIFY: System_handler (00-7f) - * ACPI_DEVICE_NOTIFY: Driver_handler (80-ff) + * handler_type - The type of handler: + * ACPI_SYSTEM_NOTIFY: system_handler (00-7f) + * ACPI_DEVICE_NOTIFY: driver_handler (80-ff) * Handler - Address of the handler * Context - Value passed to the handler on each GPE * @@ -179,33 +199,37 @@ acpi_status acpi_install_notify_handler ( - acpi_handle device, - u32 handler_type, - acpi_notify_handler handler, - void *context) + acpi_handle device, + u32 handler_type, + acpi_notify_handler handler, + void *context) { - acpi_operand_object *obj_desc; - acpi_operand_object *notify_obj; - acpi_namespace_node *device_node; - acpi_status status = AE_OK; + union acpi_operand_object *obj_desc; + union acpi_operand_object *notify_obj; + struct acpi_namespace_node *node; + acpi_status status; - FUNCTION_TRACE ("Acpi_install_notify_handler"); + ACPI_FUNCTION_TRACE ("acpi_install_notify_handler"); /* Parameter validation */ - if ((!handler) || + if ((!device) || + (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Convert and validate the device handle */ - device_node = acpi_ns_map_handle_to_node (device); - if (!device_node) { + node = acpi_ns_map_handle_to_node (device); + if (!node) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } @@ -220,22 +244,22 @@ /* Make sure the handler is not already installed */ if (((handler_type == ACPI_SYSTEM_NOTIFY) && - acpi_gbl_sys_notify.handler) || + acpi_gbl_system_notify.handler) || ((handler_type == ACPI_DEVICE_NOTIFY) && - acpi_gbl_drv_notify.handler)) { - status = AE_EXIST; + acpi_gbl_device_notify.handler)) { + status = AE_ALREADY_EXISTS; goto unlock_and_exit; } if (handler_type == ACPI_SYSTEM_NOTIFY) { - acpi_gbl_sys_notify.node = device_node; - acpi_gbl_sys_notify.handler = handler; - acpi_gbl_sys_notify.context = context; + acpi_gbl_system_notify.node = node; + acpi_gbl_system_notify.handler = handler; + acpi_gbl_system_notify.context = context; } else /* ACPI_DEVICE_NOTIFY */ { - acpi_gbl_drv_notify.node = device_node; - acpi_gbl_drv_notify.handler = handler; - acpi_gbl_drv_notify.context = context; + acpi_gbl_device_notify.node = node; + acpi_gbl_device_notify.handler = handler; + acpi_gbl_device_notify.context = context; } /* Global notify handler installed */ @@ -247,37 +271,31 @@ * Note that only certain object types can receive notifications. */ else { - /* - * These are the ONLY objects that can receive ACPI notifications - */ - if ((device_node->type != ACPI_TYPE_DEVICE) && - (device_node->type != ACPI_TYPE_PROCESSOR) && - (device_node->type != ACPI_TYPE_POWER) && - (device_node->type != ACPI_TYPE_THERMAL)) { - status = AE_BAD_PARAMETER; + /* Notifies allowed on this object? */ + + if (!acpi_ev_is_notify_object (node)) { + status = AE_TYPE; goto unlock_and_exit; } /* Check for an existing internal object */ - obj_desc = acpi_ns_get_attached_object (device_node); + obj_desc = acpi_ns_get_attached_object (node); if (obj_desc) { - /* Object exists - make sure there's no handler */ if (((handler_type == ACPI_SYSTEM_NOTIFY) && - obj_desc->device.sys_handler) || + obj_desc->common_notify.system_notify) || ((handler_type == ACPI_DEVICE_NOTIFY) && - obj_desc->device.drv_handler)) { - status = AE_EXIST; + obj_desc->common_notify.device_notify)) { + status = AE_ALREADY_EXISTS; goto unlock_and_exit; } } - else { /* Create a new object */ - obj_desc = acpi_ut_create_internal_object (device_node->type); + obj_desc = acpi_ut_create_internal_object (node->type); if (!obj_desc) { status = AE_NO_MEMORY; goto unlock_and_exit; @@ -285,7 +303,12 @@ /* Attach new object to the Node */ - status = acpi_ns_attach_object (device, obj_desc, (u8) device_node->type); + status = acpi_ns_attach_object (device, obj_desc, node->type); + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); + if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -293,41 +316,39 @@ /* Install the handler */ - notify_obj = acpi_ut_create_internal_object (INTERNAL_TYPE_NOTIFY); + notify_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_NOTIFY); if (!notify_obj) { status = AE_NO_MEMORY; goto unlock_and_exit; } - notify_obj->notify_handler.node = device_node; - notify_obj->notify_handler.handler = handler; - notify_obj->notify_handler.context = context; - + notify_obj->notify.node = node; + notify_obj->notify.handler = handler; + notify_obj->notify.context = context; if (handler_type == ACPI_SYSTEM_NOTIFY) { - obj_desc->device.sys_handler = notify_obj; + obj_desc->common_notify.system_notify = notify_obj; } - else /* ACPI_DEVICE_NOTIFY */ { - obj_desc->device.drv_handler = notify_obj; + obj_desc->common_notify.device_notify = notify_obj; } } unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_remove_notify_handler + * FUNCTION: acpi_remove_notify_handler * * PARAMETERS: Device - The device for which notifies will be handled - * Handler_type - The type of handler: - * ACPI_SYSTEM_NOTIFY: System_handler (00-7f) - * ACPI_DEVICE_NOTIFY: Driver_handler (80-ff) + * handler_type - The type of handler: + * ACPI_SYSTEM_NOTIFY: system_handler (00-7f) + * ACPI_DEVICE_NOTIFY: driver_handler (80-ff) * Handler - Address of the handler * RETURN: Status * @@ -337,32 +358,36 @@ acpi_status acpi_remove_notify_handler ( - acpi_handle device, - u32 handler_type, - acpi_notify_handler handler) + acpi_handle device, + u32 handler_type, + acpi_notify_handler handler) { - acpi_operand_object *notify_obj; - acpi_operand_object *obj_desc; - acpi_namespace_node *device_node; - acpi_status status = AE_OK; + union acpi_operand_object *notify_obj; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + acpi_status status; - FUNCTION_TRACE ("Acpi_remove_notify_handler"); + ACPI_FUNCTION_TRACE ("acpi_remove_notify_handler"); /* Parameter validation */ - if ((!handler) || + if ((!device) || + (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Convert and validate the device handle */ - device_node = acpi_ns_map_handle_to_node (device); - if (!device_node) { + node = acpi_ns_map_handle_to_node (device); + if (!node) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } @@ -374,22 +399,22 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n")); if (((handler_type == ACPI_SYSTEM_NOTIFY) && - !acpi_gbl_sys_notify.handler) || + !acpi_gbl_system_notify.handler) || ((handler_type == ACPI_DEVICE_NOTIFY) && - !acpi_gbl_drv_notify.handler)) { + !acpi_gbl_device_notify.handler)) { status = AE_NOT_EXIST; goto unlock_and_exit; } if (handler_type == ACPI_SYSTEM_NOTIFY) { - acpi_gbl_sys_notify.node = NULL; - acpi_gbl_sys_notify.handler = NULL; - acpi_gbl_sys_notify.context = NULL; + acpi_gbl_system_notify.node = NULL; + acpi_gbl_system_notify.handler = NULL; + acpi_gbl_system_notify.context = NULL; } else { - acpi_gbl_drv_notify.node = NULL; - acpi_gbl_drv_notify.handler = NULL; - acpi_gbl_drv_notify.context = NULL; + acpi_gbl_device_notify.node = NULL; + acpi_gbl_device_notify.handler = NULL; + acpi_gbl_device_notify.context = NULL; } } @@ -397,20 +422,16 @@ * All Other Objects */ else { - /* - * These are the ONLY objects that can receive ACPI notifications - */ - if ((device_node->type != ACPI_TYPE_DEVICE) && - (device_node->type != ACPI_TYPE_PROCESSOR) && - (device_node->type != ACPI_TYPE_POWER) && - (device_node->type != ACPI_TYPE_THERMAL)) { - status = AE_BAD_PARAMETER; + /* Notifies allowed on this object? */ + + if (!acpi_ev_is_notify_object (node)) { + status = AE_TYPE; goto unlock_and_exit; } /* Check for an existing internal object */ - obj_desc = acpi_ns_get_attached_object (device_node); + obj_desc = acpi_ns_get_attached_object (node); if (!obj_desc) { status = AE_NOT_EXIST; goto unlock_and_exit; @@ -419,14 +440,14 @@ /* Object exists - make sure there's an existing handler */ if (handler_type == ACPI_SYSTEM_NOTIFY) { - notify_obj = obj_desc->device.sys_handler; + notify_obj = obj_desc->common_notify.system_notify; } else { - notify_obj = obj_desc->device.drv_handler; + notify_obj = obj_desc->common_notify.device_notify; } if ((!notify_obj) || - (notify_obj->notify_handler.handler != handler)) { + (notify_obj->notify.handler != handler)) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } @@ -434,10 +455,10 @@ /* Remove the handler */ if (handler_type == ACPI_SYSTEM_NOTIFY) { - obj_desc->device.sys_handler = NULL; + obj_desc->common_notify.system_notify = NULL; } else { - obj_desc->device.drv_handler = NULL; + obj_desc->common_notify.device_notify = NULL; } acpi_ut_remove_reference (notify_obj); @@ -445,17 +466,17 @@ unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_install_gpe_handler + * FUNCTION: acpi_install_gpe_handler * - * PARAMETERS: Gpe_number - The GPE number. The numbering scheme is - * bank 0 first, then bank 1. + * PARAMETERS: gpe_number - The GPE number within the GPE block + * gpe_block - GPE block (NULL == FADT GPEs) * Type - Whether this GPE should be treated as an * edge- or level-triggered interrupt. * Handler - Address of the handler @@ -469,124 +490,150 @@ acpi_status acpi_install_gpe_handler ( - u32 gpe_number, - u32 type, - acpi_gpe_handler handler, - void *context) + acpi_handle gpe_device, + u32 gpe_number, + u32 type, + acpi_gpe_handler handler, + void *context) { - acpi_status status = AE_OK; + acpi_status status; + struct acpi_gpe_event_info *gpe_event_info; - FUNCTION_TRACE ("Acpi_install_gpe_handler"); + ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler"); /* Parameter validation */ - if (!handler || (gpe_number > ACPI_GPE_MAX)) { + if (!handler) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* Ensure that we have a valid GPE number */ - if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; } - acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); - /* Make sure that there isn't a handler there already */ - if (acpi_gbl_gpe_info[gpe_number].handler) { - status = AE_EXIST; - goto cleanup; + if (gpe_event_info->handler) { + status = AE_ALREADY_EXISTS; + goto unlock_and_exit; } /* Install the handler */ - acpi_gbl_gpe_info[gpe_number].handler = handler; - acpi_gbl_gpe_info[gpe_number].context = context; - acpi_gbl_gpe_info[gpe_number].type = (u8) type; + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + gpe_event_info->handler = handler; + gpe_event_info->context = context; + gpe_event_info->flags = (u8) type; + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); /* Clear the GPE (of stale events), the enable it */ - acpi_hw_clear_gpe (gpe_number); - acpi_hw_enable_gpe (gpe_number); + status = acpi_hw_clear_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + + status = acpi_hw_enable_gpe (gpe_event_info); -cleanup: - acpi_ut_release_mutex (ACPI_MTX_EVENTS); +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_remove_gpe_handler + * FUNCTION: acpi_remove_gpe_handler * - * PARAMETERS: Gpe_number - The event to remove a handler + * PARAMETERS: gpe_number - The event to remove a handler + * gpe_block - GPE block (NULL == FADT GPEs) * Handler - Address of the handler * * RETURN: Status * - * DESCRIPTION: Remove a handler for a General Purpose Acpi_event. + * DESCRIPTION: Remove a handler for a General Purpose acpi_event. * ******************************************************************************/ acpi_status acpi_remove_gpe_handler ( - u32 gpe_number, - acpi_gpe_handler handler) + acpi_handle gpe_device, + u32 gpe_number, + acpi_gpe_handler handler) { - acpi_status status = AE_OK; + acpi_status status; + struct acpi_gpe_event_info *gpe_event_info; - FUNCTION_TRACE ("Acpi_remove_gpe_handler"); + ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler"); /* Parameter validation */ - if (!handler || (gpe_number > ACPI_GPE_MAX)) { + if (!handler) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* Ensure that we have a valid GPE number */ - if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; } /* Disable the GPE before removing the handler */ - acpi_hw_disable_gpe (gpe_number); - - acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + status = acpi_hw_disable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } /* Make sure that the installed handler is the same */ - if (acpi_gbl_gpe_info[gpe_number].handler != handler) { - acpi_hw_enable_gpe (gpe_number); + if (gpe_event_info->handler != handler) { + (void) acpi_hw_enable_gpe (gpe_event_info); status = AE_BAD_PARAMETER; - goto cleanup; + goto unlock_and_exit; } /* Remove the handler */ - acpi_gbl_gpe_info[gpe_number].handler = NULL; - acpi_gbl_gpe_info[gpe_number].context = NULL; + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + gpe_event_info->handler = NULL; + gpe_event_info->context = NULL; + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); -cleanup: - acpi_ut_release_mutex (ACPI_MTX_EVENTS); +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_acquire_global_lock + * FUNCTION: acpi_acquire_global_lock * * PARAMETERS: Timeout - How long the caller is willing to wait - * Out_handle - A handle to the lock if acquired + * out_handle - A handle to the lock if acquired * * RETURN: Status * @@ -596,32 +643,38 @@ acpi_status acpi_acquire_global_lock ( - void) + u16 timeout, + u32 *handle) { - acpi_status status; + acpi_status status; + + if (!handle) { + return (AE_BAD_PARAMETER); + } status = acpi_ex_enter_interpreter (); if (ACPI_FAILURE (status)) { return (status); } - /* - * TBD: [Restructure] add timeout param to internal interface, and - * perhaps INTERPRETER_LOCKED - */ - status = acpi_ev_acquire_global_lock (); + status = acpi_ev_acquire_global_lock (timeout); acpi_ex_exit_interpreter (); + if (ACPI_SUCCESS (status)) { + acpi_gbl_global_lock_handle++; + *handle = acpi_gbl_global_lock_handle; + } + return (status); } /******************************************************************************* * - * FUNCTION: Acpi_release_global_lock + * FUNCTION: acpi_release_global_lock * - * PARAMETERS: Handle - Returned from Acpi_acquire_global_lock + * PARAMETERS: Handle - Returned from acpi_acquire_global_lock * * RETURN: Status * @@ -631,11 +684,17 @@ acpi_status acpi_release_global_lock ( - void) + u32 handle) { + acpi_status status; + - acpi_ev_release_global_lock (); - return (AE_OK); + if (handle != acpi_gbl_global_lock_handle) { + return (AE_NOT_ACQUIRED); + } + + status = acpi_ev_release_global_lock (); + return (status); } diff -urN linux-2.4.21/drivers/acpi/events/evxfevnt.c linux-2.4.22/drivers/acpi/events/evxfevnt.c --- linux-2.4.21/drivers/acpi/events/evxfevnt.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/evxfevnt.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,43 +1,58 @@ /****************************************************************************** * * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable - * $Revision: 38 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "acnamesp.h" -#include "acevents.h" -#include "amlcode.h" -#include "acinterp.h" +#include +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evxfevnt") + ACPI_MODULE_NAME ("evxfevnt") /******************************************************************************* * - * FUNCTION: Acpi_enable + * FUNCTION: acpi_enable * * PARAMETERS: None * @@ -50,74 +65,79 @@ acpi_status acpi_enable (void) { - acpi_status status; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Acpi_enable"); + ACPI_FUNCTION_TRACE ("acpi_enable"); - /* Make sure we've got ACPI tables */ + /* Make sure we have the FADT*/ - if (!acpi_gbl_DSDT) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!\n")); + if (!acpi_gbl_FADT) { + ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n")); return_ACPI_STATUS (AE_NO_ACPI_TABLES); } - /* Make sure the BIOS supports ACPI mode */ - - if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Only legacy mode supported!\n")); - return_ACPI_STATUS (AE_ERROR); + if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n")); } + else { + /* Transition to ACPI mode */ - /* Transition to ACPI mode */ + status = acpi_hw_set_mode (ACPI_SYS_MODE_ACPI); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n")); + return_ACPI_STATUS (status); + } - status = acpi_hw_set_mode (SYS_MODE_ACPI); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Could not transition to ACPI mode.\n")); - return_ACPI_STATUS (status); + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n")); } - ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Transition to ACPI mode successful\n")); - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_disable + * FUNCTION: acpi_disable * * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Returns the system to original ACPI/legacy mode, and - * uninstalls the SCI interrupt handler. + * DESCRIPTION: Transfers the system into LEGACY mode. * ******************************************************************************/ acpi_status acpi_disable (void) { - acpi_status status; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Acpi_disable"); + ACPI_FUNCTION_TRACE ("acpi_disable"); - /* Restore original mode */ + if (!acpi_gbl_FADT) { + ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n")); + return_ACPI_STATUS (AE_NO_ACPI_TABLES); + } - status = acpi_hw_set_mode (acpi_gbl_original_mode); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to transition to original mode")); - return_ACPI_STATUS (status); + if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n")); } + else { + /* Transition to LEGACY mode */ + + status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY); - /* Unload the SCI interrupt handler */ + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not exit ACPI mode to legacy mode")); + return_ACPI_STATUS (status); + } - acpi_ev_remove_sci_handler (); - acpi_ev_restore_acpi_state (); + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n")); + } return_ACPI_STATUS (status); } @@ -125,107 +145,179 @@ /******************************************************************************* * - * FUNCTION: Acpi_enable_event + * FUNCTION: acpi_enable_event * - * PARAMETERS: Event - The fixed event or GPE to be enabled - * Type - The type of event - * Flags - Just enable, or also wake enable? + * PARAMETERS: Event - The fixed eventto be enabled + * Flags - Reserved * * RETURN: Status * - * DESCRIPTION: Enable an ACPI event (fixed and general purpose) + * DESCRIPTION: Enable an ACPI event (fixed) * ******************************************************************************/ acpi_status acpi_enable_event ( - u32 event, - u32 type, - u32 flags) + u32 event, + u32 flags) { - acpi_status status = AE_OK; - u32 register_id; + acpi_status status = AE_OK; + u32 value; - FUNCTION_TRACE ("Acpi_enable_event"); + ACPI_FUNCTION_TRACE ("acpi_enable_event"); - /* The Type must be either Fixed Acpi_event or GPE */ + /* Decode the Fixed Event */ - switch (type) { + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - case ACPI_EVENT_FIXED: + /* + * Enable the requested fixed event (by writing a one to the + * enable register bit) + */ + status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id, + 1, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - /* Decode the Fixed Acpi_event */ + /* Make sure that the hardware responded */ - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_EN; - break; + status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id, + &value, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - case ACPI_EVENT_GLOBAL: - register_id = GBL_EN; - break; + if (value != 1) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not enable %s event\n", acpi_ut_get_event_name (event))); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); + } - case ACPI_EVENT_POWER_BUTTON: - register_id = PWRBTN_EN; - break; + return_ACPI_STATUS (status); +} - case ACPI_EVENT_SLEEP_BUTTON: - register_id = SLPBTN_EN; - break; - case ACPI_EVENT_RTC: - register_id = RTC_EN; - break; +/******************************************************************************* + * + * FUNCTION: acpi_enable_gpe + * + * PARAMETERS: gpe_device - Parent GPE Device + * gpe_number - GPE level within the GPE block + * Flags - Just enable, or also wake enable? + * Called from ISR or not + * + * RETURN: Status + * + * DESCRIPTION: Enable an ACPI event (general purpose) + * + ******************************************************************************/ + +acpi_status +acpi_enable_gpe ( + acpi_handle gpe_device, + u32 gpe_number, + u32 flags) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - break; - } - /* - * Enable the requested fixed event (by writing a one to the - * enable register bit) - */ - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); - - if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Fixed event bit clear when it should be set\n")); - return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); + ACPI_FUNCTION_TRACE ("acpi_enable_gpe"); + + + /* Use semaphore lock if not executing at interrupt level */ + + if (flags & ACPI_NOT_ISR) { + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + } - break; + /* Ensure that we have a valid GPE number */ + gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } - case ACPI_EVENT_GPE: + /* Enable the requested GPE number */ - /* Ensure that we have a valid GPE number */ + status = acpi_hw_enable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - if ((event > ACPI_GPE_MAX) || - (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + if (flags & ACPI_EVENT_WAKE_ENABLE) { + acpi_hw_enable_gpe_for_wakeup (gpe_event_info); + } +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } + return_ACPI_STATUS (status); +} - /* Enable the requested GPE number */ - if (flags & ACPI_EVENT_ENABLE) { - acpi_hw_enable_gpe (event); - } - if (flags & ACPI_EVENT_WAKE_ENABLE) { - acpi_hw_enable_gpe_for_wakeup (event); - } +/******************************************************************************* + * + * FUNCTION: acpi_disable_event + * + * PARAMETERS: Event - The fixed eventto be enabled + * Flags - Reserved + * + * RETURN: Status + * + * DESCRIPTION: Disable an ACPI event (fixed) + * + ******************************************************************************/ + +acpi_status +acpi_disable_event ( + u32 event, + u32 flags) +{ + acpi_status status = AE_OK; + u32 value; - break; + ACPI_FUNCTION_TRACE ("acpi_disable_event"); - default: - status = AE_BAD_PARAMETER; + /* Decode the Fixed Event */ + + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* + * Disable the requested fixed event (by writing a zero to the + * enable register bit) + */ + status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id, + 0, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id, + &value, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + if (value != 0) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not disable %s events\n", acpi_ut_get_event_name (event))); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); + } return_ACPI_STATUS (status); } @@ -233,293 +325,412 @@ /******************************************************************************* * - * FUNCTION: Acpi_disable_event + * FUNCTION: acpi_disable_gpe * - * PARAMETERS: Event - The fixed event or GPE to be enabled - * Type - The type of event, fixed or general purpose - * Flags - Wake disable vs. non-wake disable + * PARAMETERS: gpe_device - Parent GPE Device + * gpe_number - GPE level within the GPE block + * Flags - Just enable, or also wake enable? + * Called from ISR or not * * RETURN: Status * - * DESCRIPTION: Disable an ACPI event (fixed and general purpose) + * DESCRIPTION: Disable an ACPI event (general purpose) * ******************************************************************************/ acpi_status -acpi_disable_event ( - u32 event, - u32 type, - u32 flags) +acpi_disable_gpe ( + acpi_handle gpe_device, + u32 gpe_number, + u32 flags) { - acpi_status status = AE_OK; - u32 register_id; + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; + + + ACPI_FUNCTION_TRACE ("acpi_disable_gpe"); + + + /* Use semaphore lock if not executing at interrupt level */ + + if (flags & ACPI_NOT_ISR) { + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + /* Ensure that we have a valid GPE number */ - FUNCTION_TRACE ("Acpi_disable_event"); + gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + /* + * Only disable the requested GPE number for wake if specified. + * Otherwise, turn it totally off + */ + if (flags & ACPI_EVENT_WAKE_DISABLE) { + acpi_hw_disable_gpe_for_wakeup (gpe_event_info); + } + else { + status = acpi_hw_disable_gpe (gpe_event_info); + } +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } + return_ACPI_STATUS (status); +} - /* The Type must be either Fixed Acpi_event or GPE */ - switch (type) { +/******************************************************************************* + * + * FUNCTION: acpi_clear_event + * + * PARAMETERS: Event - The fixed event to be cleared + * + * RETURN: Status + * + * DESCRIPTION: Clear an ACPI event (fixed) + * + ******************************************************************************/ - case ACPI_EVENT_FIXED: +acpi_status +acpi_clear_event ( + u32 event) +{ + acpi_status status = AE_OK; - /* Decode the Fixed Acpi_event */ - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_EN; - break; + ACPI_FUNCTION_TRACE ("acpi_clear_event"); - case ACPI_EVENT_GLOBAL: - register_id = GBL_EN; - break; - case ACPI_EVENT_POWER_BUTTON: - register_id = PWRBTN_EN; - break; + /* Decode the Fixed Event */ - case ACPI_EVENT_SLEEP_BUTTON: - register_id = SLPBTN_EN; - break; + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - case ACPI_EVENT_RTC: - register_id = RTC_EN; - break; + /* + * Clear the requested fixed event (By writing a one to the + * status register bit) + */ + status = acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id, + 1, ACPI_MTX_LOCK); - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - break; - } + return_ACPI_STATUS (status); +} - /* - * Disable the requested fixed event (by writing a zero to the - * enable register bit) - */ - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0); - - if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Fixed event bit set when it should be clear,\n")); - return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); - } - break; +/******************************************************************************* + * + * FUNCTION: acpi_clear_gpe + * + * PARAMETERS: gpe_device - Parent GPE Device + * gpe_number - GPE level within the GPE block + * Flags - Called from an ISR or not + * + * RETURN: Status + * + * DESCRIPTION: Clear an ACPI event (general purpose) + * + ******************************************************************************/ +acpi_status +acpi_clear_gpe ( + acpi_handle gpe_device, + u32 gpe_number, + u32 flags) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; - case ACPI_EVENT_GPE: - /* Ensure that we have a valid GPE number */ + ACPI_FUNCTION_TRACE ("acpi_clear_gpe"); - if ((event > ACPI_GPE_MAX) || - (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - /* Disable the requested GPE number */ + /* Use semaphore lock if not executing at interrupt level */ - if (flags & ACPI_EVENT_DISABLE) { - acpi_hw_disable_gpe (event); - } - if (flags & ACPI_EVENT_WAKE_DISABLE) { - acpi_hw_disable_gpe_for_wakeup (event); + if (flags & ACPI_NOT_ISR) { + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + } - break; - + /* Ensure that we have a valid GPE number */ - default: + gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); + if (!gpe_event_info) { status = AE_BAD_PARAMETER; + goto unlock_and_exit; } + status = acpi_hw_clear_gpe (gpe_event_info); + +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_clear_event + * FUNCTION: acpi_get_event_status * - * PARAMETERS: Event - The fixed event or GPE to be cleared - * Type - The type of event + * PARAMETERS: Event - The fixed event + * Event Status - Where the current status of the event will + * be returned * * RETURN: Status * - * DESCRIPTION: Clear an ACPI event (fixed and general purpose) + * DESCRIPTION: Obtains and returns the current status of the event * ******************************************************************************/ acpi_status -acpi_clear_event ( - u32 event, - u32 type) +acpi_get_event_status ( + u32 event, + acpi_event_status *event_status) { - acpi_status status = AE_OK; - u32 register_id; - + acpi_status status = AE_OK; - FUNCTION_TRACE ("Acpi_clear_event"); + ACPI_FUNCTION_TRACE ("acpi_get_event_status"); - /* The Type must be either Fixed Acpi_event or GPE */ - switch (type) { + if (!event_status) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - case ACPI_EVENT_FIXED: + /* Decode the Fixed Event */ - /* Decode the Fixed Acpi_event */ + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_STS; - break; + /* Get the status of the requested fixed event */ - case ACPI_EVENT_GLOBAL: - register_id = GBL_STS; - break; + status = acpi_get_register (acpi_gbl_fixed_event_info[event].status_register_id, + event_status, ACPI_MTX_LOCK); - case ACPI_EVENT_POWER_BUTTON: - register_id = PWRBTN_STS; - break; + return_ACPI_STATUS (status); +} - case ACPI_EVENT_SLEEP_BUTTON: - register_id = SLPBTN_STS; - break; - case ACPI_EVENT_RTC: - register_id = RTC_STS; - break; +/******************************************************************************* + * + * FUNCTION: acpi_get_gpe_status + * + * PARAMETERS: gpe_device - Parent GPE Device + * gpe_number - GPE level within the GPE block + * Flags - Called from an ISR or not + * Event Status - Where the current status of the event will + * be returned + * + * RETURN: Status + * + * DESCRIPTION: Get status of an event (general purpose) + * + ******************************************************************************/ - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - break; - } +acpi_status +acpi_get_gpe_status ( + acpi_handle gpe_device, + u32 gpe_number, + u32 flags, + acpi_event_status *event_status) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; - /* - * Clear the requested fixed event (By writing a one to the - * status register bit) - */ - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); - break; + ACPI_FUNCTION_TRACE ("acpi_get_gpe_status"); - case ACPI_EVENT_GPE: - /* Ensure that we have a valid GPE number */ + /* Use semaphore lock if not executing at interrupt level */ - if ((event > ACPI_GPE_MAX) || - (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + if (flags & ACPI_NOT_ISR) { + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + } + /* Ensure that we have a valid GPE number */ - acpi_hw_clear_gpe (event); - break; + gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + /* Obtain status on the requested GPE number */ - default: + status = acpi_hw_get_gpe_status (gpe_event_info, event_status); - status = AE_BAD_PARAMETER; +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); } - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_get_event_status + * FUNCTION: acpi_install_gpe_block * - * PARAMETERS: Event - The fixed event or GPE - * Type - The type of event - * Status - Where the current status of the event will - * be returned + * PARAMETERS: gpe_device - Handle to the parent GPE Block Device + * gpe_block_address - Address and space_iD + * register_count - Number of GPE register pairs in the block + * interrupt_level - H/W interrupt for the block * * RETURN: Status * - * DESCRIPTION: Obtains and returns the current status of the event + * DESCRIPTION: Create and Install a block of GPE registers * ******************************************************************************/ - acpi_status -acpi_get_event_status ( - u32 event, - u32 type, - acpi_event_status *event_status) +acpi_install_gpe_block ( + acpi_handle gpe_device, + struct acpi_generic_address *gpe_block_address, + u32 register_count, + u32 interrupt_level) { - acpi_status status = AE_OK; - u32 register_id; + acpi_status status; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + struct acpi_gpe_block_info *gpe_block; - FUNCTION_TRACE ("Acpi_get_event_status"); + ACPI_FUNCTION_TRACE ("acpi_install_gpe_block"); - if (!event_status) { + if ((!gpe_device) || + (!gpe_block_address) || + (!register_count)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } - /* The Type must be either Fixed Acpi_event or GPE */ - - switch (type) { + node = acpi_ns_map_handle_to_node (gpe_device); + if (!node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } - case ACPI_EVENT_FIXED: + /* + * For user-installed GPE Block Devices, the gpe_block_base_number + * is always zero + */ + status = acpi_ev_create_gpe_block (node, gpe_block_address, register_count, + 0, interrupt_level, &gpe_block); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - /* Decode the Fixed Acpi_event */ + /* Get the device_object attached to the node */ - switch (event) { - case ACPI_EVENT_PMTIMER: - register_id = TMR_STS; - break; + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, create a new one */ - case ACPI_EVENT_GLOBAL: - register_id = GBL_STS; - break; + obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_DEVICE); + if (!obj_desc) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } - case ACPI_EVENT_POWER_BUTTON: - register_id = PWRBTN_STS; - break; + status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE); - case ACPI_EVENT_SLEEP_BUTTON: - register_id = SLPBTN_STS; - break; + /* Remove local reference to the object */ - case ACPI_EVENT_RTC: - register_id = RTC_STS; - break; + acpi_ut_remove_reference (obj_desc); - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - break; + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; } + } + + /* Install the GPE block in the device_object */ - /* Get the status of the requested fixed event */ + obj_desc->device.gpe_block = gpe_block; - *event_status = acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, register_id); - break; +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (status); +} - case ACPI_EVENT_GPE: - /* Ensure that we have a valid GPE number */ +/******************************************************************************* + * + * FUNCTION: acpi_remove_gpe_block + * + * PARAMETERS: gpe_device - Handle to the parent GPE Block Device + * + * RETURN: Status + * + * DESCRIPTION: Remove a previously installed block of GPE registers + * + ******************************************************************************/ + +acpi_status +acpi_remove_gpe_block ( + acpi_handle gpe_device) +{ + union acpi_operand_object *obj_desc; + acpi_status status; + struct acpi_namespace_node *node; - if ((event > ACPI_GPE_MAX) || - (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + ACPI_FUNCTION_TRACE ("acpi_remove_gpe_block"); - /* Obtain status on the requested GPE number */ - acpi_hw_get_gpe_status (event, event_status); - break; + if (!gpe_device) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } - default: + node = acpi_ns_map_handle_to_node (gpe_device); + if (!node) { status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + /* Get the device_object attached to the node */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc || + !obj_desc->device.gpe_block) { + return_ACPI_STATUS (AE_NULL_OBJECT); + } + + /* Delete the GPE block (but not the device_object) */ + + status = acpi_ev_delete_gpe_block (obj_desc->device.gpe_block); + if (ACPI_SUCCESS (status)) { + obj_desc->device.gpe_block = NULL; } +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/events/evxfregn.c linux-2.4.22/drivers/acpi/events/evxfregn.c --- linux-2.4.21/drivers/acpi/events/evxfregn.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/events/evxfregn.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,84 +2,101 @@ * * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and * Address Spaces. - * $Revision: 40 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "acnamesp.h" -#include "acevents.h" -#include "amlcode.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EVENTS - MODULE_NAME ("evxfregn") + ACPI_MODULE_NAME ("evxfregn") /******************************************************************************* * - * FUNCTION: Acpi_install_address_space_handler + * FUNCTION: acpi_install_address_space_handler * * PARAMETERS: Device - Handle for the device - * Space_id - The address space ID + * space_id - The address space ID * Handler - Address of the handler * Setup - Address of the setup function * Context - Value passed to the handler on each access * * RETURN: Status * - * DESCRIPTION: Install a handler for all Op_regions of a given Space_id. + * DESCRIPTION: Install a handler for all op_regions of a given space_id. * ******************************************************************************/ acpi_status acpi_install_address_space_handler ( - acpi_handle device, - ACPI_ADR_SPACE_TYPE space_id, - acpi_adr_space_handler handler, - acpi_adr_space_setup setup, - void *context) + acpi_handle device, + acpi_adr_space_type space_id, + acpi_adr_space_handler handler, + acpi_adr_space_setup setup, + void *context) { - acpi_operand_object *obj_desc; - acpi_operand_object *handler_obj; - acpi_namespace_node *node; - acpi_status status = AE_OK; - acpi_object_type8 type; - u16 flags = 0; + union acpi_operand_object *obj_desc; + union acpi_operand_object *handler_obj; + struct acpi_namespace_node *node; + acpi_status status; + acpi_object_type type; + u16 flags = 0; - FUNCTION_TRACE ("Acpi_install_address_space_handler"); + ACPI_FUNCTION_TRACE ("acpi_install_address_space_handler"); /* Parameter validation */ - if ((!device) || - ((!handler) && (handler != ACPI_DEFAULT_HANDLER)) || - (space_id > ACPI_MAX_ADDRESS_SPACE)) { + if (!device) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Convert and validate the device handle */ @@ -103,7 +120,7 @@ } if (handler == ACPI_DEFAULT_HANDLER) { - flags = ADDR_HANDLER_DEFAULT_INSTALLED; + flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED; switch (space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: @@ -131,55 +148,65 @@ setup = acpi_ev_pci_bar_region_setup; break; + case ACPI_ADR_SPACE_DATA_TABLE: + handler = acpi_ex_data_table_space_handler; + setup = NULL; + break; + default: - status = AE_NOT_EXIST; + status = AE_BAD_PARAMETER; goto unlock_and_exit; - break; } } - /* - * If the caller hasn't specified a setup routine, use the default - */ + /* If the caller hasn't specified a setup routine, use the default */ + if (!setup) { setup = acpi_ev_default_region_setup; } - /* - * Check for an existing internal object - */ + /* Check for an existing internal object */ + obj_desc = acpi_ns_get_attached_object (node); if (obj_desc) { /* - * The object exists. + * The attached device object already exists. * Make sure the handler is not already installed. */ + handler_obj = obj_desc->device.address_space; - /* check the address handler the user requested */ + /* Walk the handler list for this device */ - handler_obj = obj_desc->device.addr_handler; while (handler_obj) { - /* - * We have an Address handler, see if user requested this - * address space. - */ - if(handler_obj->addr_handler.space_id == space_id) { - status = AE_EXIST; + /* Same space_id indicates a handler already installed */ + + if(handler_obj->address_space.space_id == space_id) { + if (handler_obj->address_space.handler == handler) { + /* + * It is (relatively) OK to attempt to install the SAME + * handler twice. This can easily happen with PCI_Config space. + */ + status = AE_SAME_HANDLER; + goto unlock_and_exit; + } + else { + /* A handler is already installed */ + + status = AE_ALREADY_EXISTS; + } goto unlock_and_exit; } - /* - * Move through the linked list of handlers - */ - handler_obj = handler_obj->addr_handler.next; + /* Walk the linked list of handlers */ + + handler_obj = handler_obj->address_space.next; } } - else { ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Creating object on Device %p while installing handler\n", node)); - /* Obj_desc does not exist, create one */ + /* obj_desc does not exist, create one */ if (node->type == ACPI_TYPE_ANY) { type = ACPI_TYPE_DEVICE; @@ -200,110 +227,117 @@ /* Attach the new object to the Node */ - status = acpi_ns_attach_object (node, obj_desc, (u8) type); + status = acpi_ns_attach_object (node, obj_desc, type); + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); + if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); goto unlock_and_exit; } } ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Installing address handler for region %s(%X) on Device %p(%p)\n", - acpi_ut_get_region_name (space_id), space_id, node, obj_desc)); + "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", + acpi_ut_get_region_name (space_id), space_id, node->name.ascii, node, obj_desc)); /* - * Now we can install the handler + * Install the handler * - * At this point we know that there is no existing handler. - * So, we just allocate the object for the handler and link it + * At this point there is no existing handler. + * Just allocate the object for the handler and link it * into the list. */ - handler_obj = acpi_ut_create_internal_object (INTERNAL_TYPE_ADDRESS_HANDLER); + handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER); if (!handler_obj) { status = AE_NO_MEMORY; goto unlock_and_exit; } - handler_obj->addr_handler.space_id = (u8) space_id; - handler_obj->addr_handler.hflags = flags; - handler_obj->addr_handler.next = obj_desc->device.addr_handler; - handler_obj->addr_handler.region_list = NULL; - handler_obj->addr_handler.node = node; - handler_obj->addr_handler.handler = handler; - handler_obj->addr_handler.context = context; - handler_obj->addr_handler.setup = setup; + /* Init handler obj */ + + handler_obj->address_space.space_id = (u8) space_id; + handler_obj->address_space.hflags = flags; + handler_obj->address_space.region_list = NULL; + handler_obj->address_space.node = node; + handler_obj->address_space.handler = handler; + handler_obj->address_space.context = context; + handler_obj->address_space.setup = setup; + + /* Install at head of Device.address_space list */ + + handler_obj->address_space.next = obj_desc->device.address_space; + + /* + * The Device object is the first reference on the handler_obj. + * Each region that uses the handler adds a reference. + */ + obj_desc->device.address_space = handler_obj; /* - * Now walk the namespace finding all of the regions this + * Walk the namespace finding all of the regions this * handler will manage. * - * We start at the device and search the branch toward + * Start at the device and search the branch toward * the leaf nodes until either the leaf is encountered or * a device is detected that has an address handler of the * same type. * - * In either case we back up and search down the remainder + * In either case, back up and search down the remainder * of the branch */ - status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, - ACPI_UINT32_MAX, NS_WALK_UNLOCK, - acpi_ev_addr_handler_helper, - handler_obj, NULL); - - /* - * Place this handler 1st on the list - */ - handler_obj->common.reference_count = - (u16) (handler_obj->common.reference_count + - obj_desc->common.reference_count - 1); - obj_desc->device.addr_handler = handler_obj; - + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler, + handler_obj, NULL); unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_remove_address_space_handler + * FUNCTION: acpi_remove_address_space_handler * - * PARAMETERS: Space_id - The address space ID + * PARAMETERS: Device - Handle for the device + * space_id - The address space ID * Handler - Address of the handler * * RETURN: Status * - * DESCRIPTION: Install a handler for accesses on an Operation Region + * DESCRIPTION: Remove a previously installed handler. * ******************************************************************************/ acpi_status acpi_remove_address_space_handler ( - acpi_handle device, - ACPI_ADR_SPACE_TYPE space_id, - acpi_adr_space_handler handler) + acpi_handle device, + acpi_adr_space_type space_id, + acpi_adr_space_handler handler) { - acpi_operand_object *obj_desc; - acpi_operand_object *handler_obj; - acpi_operand_object *region_obj; - acpi_operand_object **last_obj_ptr; - acpi_namespace_node *node; - acpi_status status = AE_OK; + union acpi_operand_object *obj_desc; + union acpi_operand_object *handler_obj; + union acpi_operand_object *region_obj; + union acpi_operand_object **last_obj_ptr; + struct acpi_namespace_node *node; + acpi_status status; - FUNCTION_TRACE ("Acpi_remove_address_space_handler"); + ACPI_FUNCTION_TRACE ("acpi_remove_address_space_handler"); /* Parameter validation */ - if ((!device) || - ((!handler) && (handler != ACPI_DEFAULT_HANDLER)) || - (space_id > ACPI_MAX_ADDRESS_SPACE)) { + if (!device) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Convert and validate the device handle */ @@ -313,7 +347,6 @@ goto unlock_and_exit; } - /* Make sure the internal object exists */ obj_desc = acpi_ns_get_attached_object (node); @@ -322,25 +355,22 @@ goto unlock_and_exit; } - /* - * find the address handler the user requested - */ - handler_obj = obj_desc->device.addr_handler; - last_obj_ptr = &obj_desc->device.addr_handler; + /* Find the address handler the user requested */ + + handler_obj = obj_desc->device.address_space; + last_obj_ptr = &obj_desc->device.address_space; while (handler_obj) { - /* - * We have a handler, see if user requested this one - */ - if (handler_obj->addr_handler.space_id == space_id) { - /* - * Got it, first dereference this in the Regions - */ + /* We have a handler, see if user requested this one */ + + if (handler_obj->address_space.space_id == space_id) { + /* Matched space_id, first dereference this in the Regions */ + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Removing address handler %p(%p) for region %s on Device %p(%p)\n", handler_obj, handler, acpi_ut_get_region_name (space_id), node, obj_desc)); - region_obj = handler_obj->addr_handler.region_list; + region_obj = handler_obj->address_space.region_list; /* Walk the handler's region list */ @@ -352,51 +382,42 @@ * The region is just inaccessible as indicated to * the _REG method */ - acpi_ev_disassociate_region_from_handler(region_obj, TRUE); + acpi_ev_detach_region (region_obj, TRUE); /* - * Walk the list, since we took the first region and it - * was removed from the list by the dissassociate call - * we just get the first item on the list again + * Walk the list: Just grab the head because the + * detach_region removed the previous head. */ - region_obj = handler_obj->addr_handler.region_list; + region_obj = handler_obj->address_space.region_list; } - /* - * Remove this Handler object from the list - */ - *last_obj_ptr = handler_obj->addr_handler.next; - - /* - * Now we can delete the handler object - */ - acpi_ut_remove_reference (handler_obj); - acpi_ut_remove_reference (handler_obj); + /* Remove this Handler object from the list */ + *last_obj_ptr = handler_obj->address_space.next; + + /* Now we can delete the handler object */ + + acpi_ut_remove_reference (handler_obj); goto unlock_and_exit; } - /* - * Move through the linked list of handlers - */ - last_obj_ptr = &handler_obj->addr_handler.next; - handler_obj = handler_obj->addr_handler.next; + /* Walk the linked list of handlers */ + + last_obj_ptr = &handler_obj->address_space.next; + handler_obj = handler_obj->address_space.next; } + /* The handler does not exist */ - /* - * The handler does not exist - */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Unable to remove address handler %p for %s(%X), Dev_node %p, obj %p\n", + "Unable to remove address handler %p for %s(%X), dev_node %p, obj %p\n", handler, acpi_ut_get_region_name (space_id), space_id, node, obj_desc)); status = AE_NOT_EXIST; - unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/executer/Makefile linux-2.4.22/drivers/acpi/executer/Makefile --- linux-2.4.21/drivers/acpi/executer/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/executer/exconfig.c linux-2.4.22/drivers/acpi/executer/exconfig.c --- linux-2.4.21/drivers/acpi/executer/exconfig.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exconfig.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,242 +1,459 @@ /****************************************************************************** * * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes) - * $Revision: 44 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acevents.h" -#include "actables.h" -#include "acdispat.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exconfig") + ACPI_MODULE_NAME ("exconfig") -/***************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_ex_load_table_op + * FUNCTION: acpi_ex_add_table * - * PARAMETERS: Rgn_desc - Op region where the table will be obtained - * Ddb_handle - Where a handle to the table will be returned + * PARAMETERS: Table - Pointer to raw table + * parent_node - Where to load the table (scope) + * ddb_handle - Where to return the table handle. + * + * RETURN: Status + * + * DESCRIPTION: Common function to Install and Load an ACPI table with a + * returned table handle. + * + ******************************************************************************/ + +acpi_status +acpi_ex_add_table ( + struct acpi_table_header *table, + struct acpi_namespace_node *parent_node, + union acpi_operand_object **ddb_handle) +{ + acpi_status status; + struct acpi_table_desc table_info; + union acpi_operand_object *obj_desc; + + + ACPI_FUNCTION_TRACE ("ex_add_table"); + + + /* Create an object to be the table handle */ + + obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE); + if (!obj_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Install the new table into the local data structures */ + + table_info.pointer = table; + table_info.length = (acpi_size) table->length; + table_info.allocation = ACPI_MEM_ALLOCATED; + + status = acpi_tb_install_table (&table_info); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* Add the table to the namespace */ + + status = acpi_ns_load_table (table_info.installed_desc, parent_node); + if (ACPI_FAILURE (status)) { + /* Uninstall table on error */ + + (void) acpi_tb_uninstall_table (table_info.installed_desc); + goto cleanup; + } + + /* Init the table handle */ + + obj_desc->reference.opcode = AML_LOAD_OP; + obj_desc->reference.object = table_info.installed_desc; + *ddb_handle = obj_desc; + return_ACPI_STATUS (AE_OK); + + +cleanup: + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ex_load_table_op + * + * PARAMETERS: walk_state - Current state with operands + * return_desc - Where to store the return object * * RETURN: Status * * DESCRIPTION: Load an ACPI table * - ****************************************************************************/ + ******************************************************************************/ acpi_status -acpi_ex_load_op ( - acpi_operand_object *rgn_desc, - acpi_operand_object *ddb_handle) +acpi_ex_load_table_op ( + struct acpi_walk_state *walk_state, + union acpi_operand_object **return_desc) { - acpi_status status; - acpi_operand_object *table_desc = NULL; - u8 *table_ptr; - u8 *table_data_ptr; - acpi_table_header table_header; - acpi_table_desc table_info; - u32 i; + acpi_status status; + union acpi_operand_object **operand = &walk_state->operands[0]; + struct acpi_table_header *table; + struct acpi_namespace_node *parent_node; + struct acpi_namespace_node *start_node; + struct acpi_namespace_node *parameter_node = NULL; + union acpi_operand_object *ddb_handle; + + ACPI_FUNCTION_TRACE ("ex_load_table_op"); - FUNCTION_TRACE ("Ex_load_op"); - /* TBD: [Unhandled] Object can be either a field or an opregion */ +#if 0 + /* + * Make sure that the signature does not match one of the tables that + * is already loaded. + */ + status = acpi_tb_match_signature (operand[0]->string.pointer, NULL); + if (status == AE_OK) { + /* Signature matched -- don't allow override */ + return_ACPI_STATUS (AE_ALREADY_EXISTS); + } +#endif - /* Get the table header */ + /* Find the ACPI table */ - table_header.length = 0; - for (i = 0; i < sizeof (acpi_table_header); i++) { - status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE, - (ACPI_PHYSICAL_ADDRESS) i, 8, - (u32 *) ((u8 *) &table_header + i)); + status = acpi_tb_find_table (operand[0]->string.pointer, + operand[1]->string.pointer, + operand[2]->string.pointer, &table); + if (ACPI_FAILURE (status)) { + if (status != AE_NOT_FOUND) { + return_ACPI_STATUS (status); + } + + /* Not found, return an Integer=0 and AE_OK */ + + ddb_handle = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!ddb_handle) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + ddb_handle->integer.value = 0; + *return_desc = ddb_handle; + + return_ACPI_STATUS (AE_OK); + } + + /* Default nodes */ + + start_node = walk_state->scope_info->scope.node; + parent_node = acpi_gbl_root_node; + + /* root_path (optional parameter) */ + + if (operand[3]->string.length > 0) { + /* + * Find the node referenced by the root_path_string. This is the + * location within the namespace where the table will be loaded. + */ + status = acpi_ns_get_node_by_path (operand[3]->string.pointer, start_node, + ACPI_NS_SEARCH_PARENT, &parent_node); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } - /* Allocate a buffer for the entire table */ + /* parameter_path (optional parameter) */ - table_ptr = ACPI_MEM_ALLOCATE (table_header.length); - if (!table_ptr) { - return_ACPI_STATUS (AE_NO_MEMORY); + if (operand[4]->string.length > 0) { + if ((operand[4]->string.pointer[0] != '\\') && + (operand[4]->string.pointer[0] != '^')) { + /* + * Path is not absolute, so it will be relative to the node + * referenced by the root_path_string (or the NS root if omitted) + */ + start_node = parent_node; + } + + /* + * Find the node referenced by the parameter_path_string + */ + status = acpi_ns_get_node_by_path (operand[4]->string.pointer, start_node, + ACPI_NS_SEARCH_PARENT, ¶meter_node); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - /* Copy the header to the buffer */ + /* Load the table into the namespace */ - MEMCPY (table_ptr, &table_header, sizeof (acpi_table_header)); - table_data_ptr = table_ptr + sizeof (acpi_table_header); + status = acpi_ex_add_table (table, parent_node, &ddb_handle); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* Parameter Data (optional) */ - /* Get the table from the op region */ + if (parameter_node) { + /* Store the parameter data into the optional parameter object */ - for (i = 0; i < table_header.length; i++) { - status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE, - (ACPI_PHYSICAL_ADDRESS) i, 8, - (u32 *) (table_data_ptr + i)); + status = acpi_ex_store (operand[5], ACPI_CAST_PTR (union acpi_operand_object, parameter_node), + walk_state); if (ACPI_FAILURE (status)) { - goto cleanup; + (void) acpi_ex_unload_table (ddb_handle); } } + return_ACPI_STATUS (status); +} - /* Table must be either an SSDT or a PSDT */ - if ((!STRNCMP (table_header.signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) && - (!STRNCMP (table_header.signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Table has invalid signature [%4.4s], must be SSDT or PSDT\n", - (char*)table_header.signature)); - status = AE_BAD_SIGNATURE; - goto cleanup; - } +/******************************************************************************* + * + * FUNCTION: acpi_ex_load_op + * + * PARAMETERS: obj_desc - Region or Field where the table will be + * obtained + * Target - Where a handle to the table will be stored + * walk_state - Current state + * + * RETURN: Status + * + * DESCRIPTION: Load an ACPI table from a field or operation region + * + ******************************************************************************/ - /* Create an object to be the table handle */ +acpi_status +acpi_ex_load_op ( + union acpi_operand_object *obj_desc, + union acpi_operand_object *target, + struct acpi_walk_state *walk_state) +{ + acpi_status status; + union acpi_operand_object *ddb_handle; + union acpi_operand_object *buffer_desc = NULL; + struct acpi_table_header *table_ptr = NULL; + u8 *table_data_ptr; + struct acpi_table_header table_header; + u32 i; + + ACPI_FUNCTION_TRACE ("ex_load_op"); + + + /* Object can be either an op_region or a Field */ + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_REGION: + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n", + obj_desc, acpi_ut_get_object_type_name (obj_desc))); + + /* Get the table header */ + + table_header.length = 0; + for (i = 0; i < sizeof (struct acpi_table_header); i++) { + status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ, + (acpi_physical_address) i, 8, + ((u8 *) &table_header) + i); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } - table_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE); - if (!table_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } + /* Allocate a buffer for the entire table */ + table_ptr = ACPI_MEM_ALLOCATE (table_header.length); + if (!table_ptr) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - /* Install the new table into the local data structures */ + /* Copy the header to the buffer */ - table_info.pointer = (acpi_table_header *) table_ptr; - table_info.length = table_header.length; - table_info.allocation = ACPI_MEM_ALLOCATED; - table_info.base_pointer = table_ptr; + ACPI_MEMCPY (table_ptr, &table_header, sizeof (struct acpi_table_header)); + table_data_ptr = ACPI_PTR_ADD (u8, table_ptr, sizeof (struct acpi_table_header)); - status = acpi_tb_install_table (NULL, &table_info); - if (ACPI_FAILURE (status)) { - goto cleanup; - } + /* Get the table from the op region */ - /* Add the table to the namespace */ + for (i = 0; i < table_header.length; i++) { + status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ, + (acpi_physical_address) i, 8, + ((u8 *) table_data_ptr + i)); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + } + break; - /* TBD: [Restructure] - change to whatever new interface is appropriate */ -/* - Status = Acpi_load_namespace (); - if (ACPI_FAILURE (Status)) - { -*/ - /* TBD: [Errors] Unload the table on failure ? */ -/* - goto Cleanup; + + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Field %p %s\n", + obj_desc, acpi_ut_get_object_type_name (obj_desc))); + + /* + * The length of the field must be at least as large as the table. + * Read the entire field and thus the entire table. Buffer is + * allocated during the read. + */ + status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer); + break; + + + default: + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } -*/ + /* The table must be either an SSDT or a PSDT */ - /* TBD: [Investigate] we need a pointer to the table desc */ + if ((!ACPI_STRNCMP (table_ptr->signature, + acpi_gbl_table_data[ACPI_TABLE_PSDT].signature, + acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) && + (!ACPI_STRNCMP (table_ptr->signature, + acpi_gbl_table_data[ACPI_TABLE_SSDT].signature, + acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Table has invalid signature [%4.4s], must be SSDT or PSDT\n", + table_ptr->signature)); + status = AE_BAD_SIGNATURE; + goto cleanup; + } - /* Init the table handle */ + /* Install the new table into the local data structures */ - table_desc->reference.opcode = AML_LOAD_OP; - table_desc->reference.object = table_info.installed_desc; + status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle); + if (ACPI_FAILURE (status)) { + goto cleanup; + } - /* TBD: store the tabledesc into the Ddb_handle target */ - /* Ddb_handle = Table_desc; */ + /* Store the ddb_handle into the Target operand */ + + status = acpi_ex_store (ddb_handle, target, walk_state); + if (ACPI_FAILURE (status)) { + (void) acpi_ex_unload_table (ddb_handle); + } return_ACPI_STATUS (status); cleanup: - ACPI_MEM_FREE (table_desc); - ACPI_MEM_FREE (table_ptr); + if (buffer_desc) { + acpi_ut_remove_reference (buffer_desc); + } + else { + ACPI_MEM_FREE (table_ptr); + } return_ACPI_STATUS (status); } -/***************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_ex_unload_table + * FUNCTION: acpi_ex_unload_table * - * PARAMETERS: Ddb_handle - Handle to a previously loaded table + * PARAMETERS: ddb_handle - Handle to a previously loaded table * * RETURN: Status * * DESCRIPTION: Unload an ACPI table * - ****************************************************************************/ + ******************************************************************************/ acpi_status acpi_ex_unload_table ( - acpi_operand_object *ddb_handle) + union acpi_operand_object *ddb_handle) { - acpi_status status = AE_NOT_IMPLEMENTED; - acpi_operand_object *table_desc = ddb_handle; - acpi_table_desc *table_info; + acpi_status status = AE_NOT_IMPLEMENTED; + union acpi_operand_object *table_desc = ddb_handle; + struct acpi_table_desc *table_info; - FUNCTION_TRACE ("Ex_unload_table"); + ACPI_FUNCTION_TRACE ("ex_unload_table"); /* * Validate the handle - * Although the handle is partially validated in Acpi_ex_reconfiguration(), - * when it calls Acpi_ex_resolve_operands(), the handle is more completely + * Although the handle is partially validated in acpi_ex_reconfiguration(), + * when it calls acpi_ex_resolve_operands(), the handle is more completely * validated here. */ if ((!ddb_handle) || - (!VALID_DESCRIPTOR_TYPE (ddb_handle, ACPI_DESC_TYPE_INTERNAL)) || - (((acpi_operand_object *)ddb_handle)->common.type != - INTERNAL_TYPE_REFERENCE)) { + (ACPI_GET_DESCRIPTOR_TYPE (ddb_handle) != ACPI_DESC_TYPE_OPERAND) || + (ACPI_GET_OBJECT_TYPE (ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Get the actual table descriptor from the Ddb_handle */ + /* Get the actual table descriptor from the ddb_handle */ - table_info = (acpi_table_desc *) table_desc->reference.object; + table_info = (struct acpi_table_desc *) table_desc->reference.object; /* * Delete the entire namespace under this table Node - * (Offset contains the Table_id) + * (Offset contains the table_id) */ - status = acpi_ns_delete_namespace_by_owner (table_info->table_id); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + acpi_ns_delete_namespace_by_owner (table_info->table_id); /* Delete the table itself */ - acpi_tb_uninstall_table (table_info->installed_desc); + (void) acpi_tb_uninstall_table (table_info->installed_desc); - /* Delete the table descriptor (Ddb_handle) */ + /* Delete the table descriptor (ddb_handle) */ acpi_ut_remove_reference (table_desc); - return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/executer/exconvrt.c linux-2.4.22/drivers/acpi/executer/exconvrt.c --- linux-2.4.21/drivers/acpi/executer/exconvrt.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exconvrt.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,49 +1,63 @@ /****************************************************************************** * * Module Name: exconvrt - Object conversion routines - * $Revision: 24 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "acevents.h" -#include "amlcode.h" -#include "acdispat.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exconvrt") + ACPI_MODULE_NAME ("exconvrt") /******************************************************************************* * - * FUNCTION: Acpi_ex_convert_to_integer + * FUNCTION: acpi_ex_convert_to_integer * - * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * PARAMETERS: *obj_desc - Object to be converted. Must be an * Integer, Buffer, or String - * Walk_state - Current method state + * walk_state - Current method state * * RETURN: Status * @@ -53,60 +67,40 @@ acpi_status acpi_ex_convert_to_integer ( - acpi_operand_object *obj_desc, - acpi_operand_object **result_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc, + struct acpi_walk_state *walk_state) { - u32 i; - acpi_operand_object *ret_desc; - u32 count; - char *pointer; - acpi_integer result; - u32 integer_size = sizeof (acpi_integer); + u32 i; + union acpi_operand_object *ret_desc; + u32 count; + u8 *pointer; + acpi_integer result; + acpi_status status; - FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_integer", obj_desc); - switch (obj_desc->common.type) { + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_INTEGER: *result_desc = obj_desc; - return (AE_OK); + return_ACPI_STATUS (AE_OK); case ACPI_TYPE_STRING: - pointer = obj_desc->string.pointer; + pointer = (u8 *) obj_desc->string.pointer; count = obj_desc->string.length; break; case ACPI_TYPE_BUFFER: - pointer = (char *) obj_desc->buffer.pointer; + pointer = obj_desc->buffer.pointer; count = obj_desc->buffer.length; break; default: - return (AE_TYPE); - } - - /* - * Create a new integer - */ - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - return (AE_NO_MEMORY); - } - - - /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ - - if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { - /* - * We are running a method that exists in a 32-bit ACPI table. - * Truncate the value to 32 bits by zeroing out the upper 32-bit field - */ - integer_size = sizeof (u32); + return_ACPI_STATUS (AE_TYPE); } - /* * Convert the buffer/string to an integer. Note that both buffers and * strings are treated as raw data - we don't convert ascii to hex for @@ -120,23 +114,24 @@ /* Transfer no more than an integer's worth of data */ - if (count > integer_size) { - count = integer_size; + if (count > acpi_gbl_integer_byte_width) { + count = acpi_gbl_integer_byte_width; } /* * String conversion is different than Buffer conversion */ - switch (obj_desc->common.type) { + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_STRING: - /* TBD: Need to use 64-bit STRTOUL */ - /* * Convert string to an integer * String must be hexadecimal as per the ACPI specification */ - result = STRTOUL (pointer, NULL, 16); + status = acpi_ut_strtoul64 ((char *) pointer, 16, &result); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } break; @@ -154,14 +149,31 @@ */ result |= (((acpi_integer) pointer[i]) << (i * 8)); } + break; + + default: + /* No other types can get here */ break; } - /* Save the Result, delete original descriptor, store new descriptor */ + /* + * Create a new integer + */ + ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!ret_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Save the Result */ ret_desc->integer.value = result; + /* + * If we are about to overwrite the original object on the operand stack, + * we must remove a reference on the original object because we are + * essentially removing it from the stack. + */ if (*result_desc == obj_desc) { if (walk_state->opcode != AML_STORE_OP) { acpi_ut_remove_reference (obj_desc); @@ -169,139 +181,152 @@ } *result_desc = ret_desc; - return (AE_OK); + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_convert_to_buffer + * FUNCTION: acpi_ex_convert_to_buffer * - * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * PARAMETERS: *obj_desc - Object to be converted. Must be an * Integer, Buffer, or String - * Walk_state - Current method state + * walk_state - Current method state * * RETURN: Status * - * DESCRIPTION: Convert an ACPI Object to an Buffer + * DESCRIPTION: Convert an ACPI Object to a Buffer * ******************************************************************************/ acpi_status acpi_ex_convert_to_buffer ( - acpi_operand_object *obj_desc, - acpi_operand_object **result_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc, + struct acpi_walk_state *walk_state) { - acpi_operand_object *ret_desc; - u32 i; - u32 integer_size = sizeof (acpi_integer); - u8 *new_buf; + union acpi_operand_object *ret_desc; + u32 i; + u8 *new_buf; - FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_buffer", obj_desc); - switch (obj_desc->common.type) { - case ACPI_TYPE_INTEGER: + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_BUFFER: - /* - * Create a new Buffer - */ - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); - if (!ret_desc) { - return (AE_NO_MEMORY); - } + /* No conversion necessary */ - /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ + *result_desc = obj_desc; + return_ACPI_STATUS (AE_OK); - if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { - /* - * We are running a method that exists in a 32-bit ACPI table. - * Truncate the value to 32 bits by zeroing out the upper - * 32-bit field - */ - integer_size = sizeof (u32); - } - /* Need enough space for one integers */ + case ACPI_TYPE_INTEGER: - ret_desc->buffer.length = integer_size; - new_buf = ACPI_MEM_CALLOCATE (integer_size); - if (!new_buf) { - REPORT_ERROR - (("Ex_convert_to_buffer: Buffer allocation failure\n")); - acpi_ut_remove_reference (ret_desc); - return (AE_NO_MEMORY); + /* + * Create a new Buffer object. + * Need enough space for one integer + */ + ret_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width); + if (!ret_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); } /* Copy the integer to the buffer */ - for (i = 0; i < integer_size; i++) { + new_buf = ret_desc->buffer.pointer; + for (i = 0; i < acpi_gbl_integer_byte_width; i++) { new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8)); } - ret_desc->buffer.pointer = new_buf; - - /* Return the new buffer descriptor */ - - if (*result_desc == obj_desc) { - if (walk_state->opcode != AML_STORE_OP) { - acpi_ut_remove_reference (obj_desc); - } - } - - *result_desc = ret_desc; break; case ACPI_TYPE_STRING: - *result_desc = obj_desc; - break; + /* + * Create a new Buffer object + * Size will be the string length + */ + ret_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length); + if (!ret_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - case ACPI_TYPE_BUFFER: - *result_desc = obj_desc; + /* Copy the string to the buffer */ + + new_buf = ret_desc->buffer.pointer; + ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer, + obj_desc->string.length); break; default: - return (AE_TYPE); - break; - } + return_ACPI_STATUS (AE_TYPE); + } + + /* Mark buffer initialized */ + + ret_desc->common.flags |= AOPOBJ_DATA_VALID; + + /* + * If we are about to overwrite the original object on the operand stack, + * we must remove a reference on the original object because we are + * essentially removing it from the stack. + */ + if (*result_desc == obj_desc) { + if (walk_state->opcode != AML_STORE_OP) { + acpi_ut_remove_reference (obj_desc); + } + } - return (AE_OK); + *result_desc = ret_desc; + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_convert_ascii + * FUNCTION: acpi_ex_convert_ascii * - * PARAMETERS: Integer + * PARAMETERS: Integer - Value to be converted + * Base - 10 or 16 + * String - Where the string is returned + * data_width - Size of data item to be converted * * RETURN: Actual string length * - * DESCRIPTION: Convert an ACPI Integer to a hex string + * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string * ******************************************************************************/ u32 acpi_ex_convert_to_ascii ( - acpi_integer integer, - u32 base, - u8 *string) + acpi_integer integer, + u32 base, + u8 *string, + u8 data_width) { - u32 i; - u32 j; - u32 k = 0; - u8 hex_digit; - acpi_integer digit; - u32 remainder; - u32 length = sizeof (acpi_integer); - u8 leading_zero = TRUE; + u32 i; + u32 j; + u32 k = 0; + char hex_digit; + acpi_integer digit; + u32 remainder; + u32 length; + u8 leading_zero; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); + + if (data_width < sizeof (acpi_integer)) { + leading_zero = FALSE; + length = data_width; + } + else { + leading_zero = TRUE; + length = sizeof (acpi_integer); + } switch (base) { @@ -313,7 +338,7 @@ digit = integer; for (j = 1; j < i; j++) { - acpi_ut_short_divide (&digit, 10, &digit, &remainder); + (void) acpi_ut_short_divide (&digit, 10, &digit, &remainder); } /* Create the decimal digit */ @@ -323,7 +348,7 @@ } if (!leading_zero) { - string[k] = (u8) (ASCII_ZERO + remainder); + string[k] = (u8) (ACPI_ASCII_ZERO + remainder); k++; } } @@ -336,12 +361,12 @@ for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) { hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4)); - if (hex_digit != ASCII_ZERO) { + if (hex_digit != ACPI_ASCII_ZERO) { leading_zero = FALSE; } if (!leading_zero) { - string[k] = hex_digit; + string[k] = (u8) hex_digit; k++; } } @@ -358,22 +383,22 @@ * Finally, null terminate the string and return the length */ if (!k) { - string [0] = ASCII_ZERO; + string [0] = ACPI_ASCII_ZERO; k = 1; } - string [k] = 0; + string [k] = 0; return (k); } /******************************************************************************* * - * FUNCTION: Acpi_ex_convert_to_string + * FUNCTION: acpi_ex_convert_to_string * - * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * PARAMETERS: *obj_desc - Object to be converted. Must be an * Integer, Buffer, or String - * Walk_state - Current method state + * walk_state - Current method state * * RETURN: Status * @@ -383,39 +408,39 @@ acpi_status acpi_ex_convert_to_string ( - acpi_operand_object *obj_desc, - acpi_operand_object **result_desc, - u32 base, - u32 max_length, - acpi_walk_state *walk_state) + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc, + u32 base, + u32 max_length, + struct acpi_walk_state *walk_state) { - acpi_operand_object *ret_desc; - u32 i; - u32 index; - u32 string_length; - u32 integer_size = sizeof (acpi_integer); - u8 *new_buf; - u8 *pointer; + union acpi_operand_object *ret_desc; + u32 i; + u32 string_length; + u8 *new_buf; + u8 *pointer; - FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc); - switch (obj_desc->common.type) { - case ACPI_TYPE_INTEGER: + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_STRING: - /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ + if (max_length >= obj_desc->string.length) { + *result_desc = obj_desc; + return_ACPI_STATUS (AE_OK); + } + else { + /* Must copy the string first and then truncate it */ - if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { - /* - * We are running a method that exists in a 32-bit ACPI table. - * Truncate the value to 32 bits by zeroing out the upper - * 32-bit field - */ - integer_size = sizeof (u32); + return_ACPI_STATUS (AE_NOT_IMPLEMENTED); } - string_length = integer_size * 2; + + case ACPI_TYPE_INTEGER: + + string_length = acpi_gbl_integer_byte_width * 2; if (base == 10) { string_length = ACPI_MAX_DECIMAL_DIGITS; } @@ -425,23 +450,22 @@ */ ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); if (!ret_desc) { - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } /* Need enough space for one ASCII integer plus null terminator */ - new_buf = ACPI_MEM_CALLOCATE (string_length + 1); + new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1); if (!new_buf) { - REPORT_ERROR - (("Ex_convert_to_string: Buffer allocation failure\n")); + ACPI_REPORT_ERROR + (("ex_convert_to_string: Buffer allocation failure\n")); acpi_ut_remove_reference (ret_desc); - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } - /* Convert */ - i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf); + i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf, sizeof (acpi_integer)); /* Null terminate at the correct place */ @@ -455,29 +479,25 @@ } ret_desc->buffer.pointer = new_buf; - - /* Return the new buffer descriptor */ - - if (*result_desc == obj_desc) { - if (walk_state->opcode != AML_STORE_OP) { - acpi_ut_remove_reference (obj_desc); - } - } - - *result_desc = ret_desc; break; case ACPI_TYPE_BUFFER: - string_length = obj_desc->buffer.length * 3; - if (base == 10) { - string_length = obj_desc->buffer.length * 4; + /* Find the string length */ + + pointer = obj_desc->buffer.pointer; + for (string_length = 0; string_length < obj_desc->buffer.length; string_length++) { + /* Exit on null terminator */ + + if (!pointer[string_length]) { + break; + } } if (max_length > ACPI_MAX_STRING_CONVERSION) { if (string_length > ACPI_MAX_STRING_CONVERSION) { - return (AE_AML_STRING_LIMIT); + return_ACPI_STATUS (AE_AML_STRING_LIMIT); } } @@ -486,7 +506,7 @@ */ ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); if (!ret_desc) { - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } /* String length is the lesser of the Max or the actual length */ @@ -495,92 +515,77 @@ string_length = max_length; } - new_buf = ACPI_MEM_CALLOCATE (string_length + 1); + new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1); if (!new_buf) { - REPORT_ERROR - (("Ex_convert_to_string: Buffer allocation failure\n")); + ACPI_REPORT_ERROR + (("ex_convert_to_string: Buffer allocation failure\n")); acpi_ut_remove_reference (ret_desc); - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } - /* - * Convert each byte of the buffer to two ASCII characters plus a space. - */ - pointer = obj_desc->buffer.pointer; - index = 0; - for (i = 0, index = 0; i < obj_desc->buffer.length; i++) { - index = acpi_ex_convert_to_ascii (pointer[i], base, &new_buf[index]); + /* Copy the appropriate number of buffer characters */ - new_buf[index] = ' '; - index++; - } + ACPI_MEMCPY (new_buf, pointer, string_length); /* Null terminate */ - new_buf [index-1] = 0; + new_buf [string_length] = 0; ret_desc->buffer.pointer = new_buf; - ret_desc->string.length = STRLEN ((char *) new_buf); - - - /* Return the new buffer descriptor */ - - if (*result_desc == obj_desc) { - if (walk_state->opcode != AML_STORE_OP) { - acpi_ut_remove_reference (obj_desc); - } - } - - *result_desc = ret_desc; + ret_desc->string.length = string_length; break; - case ACPI_TYPE_STRING: - - if (max_length >= obj_desc->string.length) { - *result_desc = obj_desc; - } + default: + return_ACPI_STATUS (AE_TYPE); + } - else { - /* Must copy the string first and then truncate it */ - return (AE_NOT_IMPLEMENTED); + /* + * If we are about to overwrite the original object on the operand stack, + * we must remove a reference on the original object because we are + * essentially removing it from the stack. + */ + if (*result_desc == obj_desc) { + if (walk_state->opcode != AML_STORE_OP) { + acpi_ut_remove_reference (obj_desc); } - break; - - - default: - return (AE_TYPE); - break; - } + } - return (AE_OK); + *result_desc = ret_desc; + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_convert_to_target_type + * FUNCTION: acpi_ex_convert_to_target_type * - * PARAMETERS: *Obj_desc - Object to be converted. - * Walk_state - Current method state + * PARAMETERS: destination_type - Current type of the destination + * source_desc - Source object to be converted. + * walk_state - Current method state * * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Implements "implicit conversion" rules for storing an object. * ******************************************************************************/ acpi_status acpi_ex_convert_to_target_type ( - acpi_object_type8 destination_type, - acpi_operand_object **obj_desc, - acpi_walk_state *walk_state) + acpi_object_type destination_type, + union acpi_operand_object *source_desc, + union acpi_operand_object **result_desc, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE ("ex_convert_to_target_type"); - FUNCTION_TRACE ("Ex_convert_to_target_type"); + /* Default behavior */ + + *result_desc = source_desc; /* * If required by the target, @@ -592,7 +597,7 @@ case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ switch (destination_type) { - case INTERNAL_TYPE_REGION_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: /* * Named field can always handle conversions */ @@ -601,10 +606,10 @@ default: /* No conversion allowed for these types */ - if (destination_type != (*obj_desc)->common.type) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Target does not allow conversion of type %s to %s\n", - acpi_ut_get_type_name ((*obj_desc)->common.type), + if (destination_type != ACPI_GET_OBJECT_TYPE (source_desc)) { + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Explicit operator, will store (%s) over existing type (%s)\n", + acpi_ut_get_object_type_name (source_desc), acpi_ut_get_type_name (destination_type))); status = AE_TYPE; } @@ -617,13 +622,13 @@ switch (destination_type) { case ACPI_TYPE_INTEGER: case ACPI_TYPE_BUFFER_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: /* * These types require an Integer operand. We can convert * a Buffer or a String to an Integer if necessary. */ - status = acpi_ex_convert_to_integer (*obj_desc, obj_desc, walk_state); + status = acpi_ex_convert_to_integer (source_desc, result_desc, walk_state); break; @@ -633,17 +638,22 @@ * The operand must be a String. We can convert an * Integer or Buffer if necessary */ - status = acpi_ex_convert_to_string (*obj_desc, obj_desc, 16, ACPI_UINT32_MAX, walk_state); + status = acpi_ex_convert_to_string (source_desc, result_desc, 16, ACPI_UINT32_MAX, walk_state); break; case ACPI_TYPE_BUFFER: /* - * The operand must be a String. We can convert an - * Integer or Buffer if necessary + * The operand must be a Buffer. We can convert an + * Integer or String if necessary */ - status = acpi_ex_convert_to_buffer (*obj_desc, obj_desc, walk_state); + status = acpi_ex_convert_to_buffer (source_desc, result_desc, walk_state); + break; + + + default: + status = AE_AML_INTERNAL; break; } break; @@ -651,21 +661,20 @@ case ARGI_REFERENCE: /* - * Create_xxxx_field cases - we are storing the field object into the name + * create_xxxx_field cases - we are storing the field object into the name */ break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown Target type ID 0x%X Op %s Dest_type %s\n", + "Unknown Target type ID 0x%X Op %s dest_type %s\n", GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args), walk_state->op_info->name, acpi_ut_get_type_name (destination_type))); status = AE_AML_INTERNAL; } - /* * Source-to-Target conversion semantics: * diff -urN linux-2.4.21/drivers/acpi/executer/excreate.c linux-2.4.22/drivers/acpi/executer/excreate.c --- linux-2.4.21/drivers/acpi/executer/excreate.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/excreate.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,48 +1,65 @@ /****************************************************************************** * * Module Name: excreate - Named object creation - * $Revision: 71 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acevents.h" -#include "acdispat.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("excreate") + ACPI_MODULE_NAME ("excreate") +#ifndef ACPI_NO_METHOD_EXECUTION /***************************************************************************** * - * FUNCTION: Acpi_ex_create_alias + * FUNCTION: acpi_ex_create_alias * - * PARAMETERS: Walk_state - Current state, contains List of - * operands for the opcode + * PARAMETERS: walk_state - Current state, contains operands * * RETURN: Status * @@ -52,32 +69,69 @@ acpi_status acpi_ex_create_alias ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_namespace_node *source_node; - acpi_status status; + struct acpi_namespace_node *target_node; + struct acpi_namespace_node *alias_node; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_create_alias"); + ACPI_FUNCTION_TRACE ("ex_create_alias"); /* Get the source/alias operands (both namespace nodes) */ - source_node = (acpi_namespace_node *) walk_state->operands[1]; + alias_node = (struct acpi_namespace_node *) walk_state->operands[0]; + target_node = (struct acpi_namespace_node *) walk_state->operands[1]; - - /* Attach the original source object to the new Alias Node */ - - status = acpi_ns_attach_object ((acpi_namespace_node *) walk_state->operands[0], - source_node->object, - source_node->type); + if (target_node->type == ACPI_TYPE_LOCAL_ALIAS) { + /* + * Dereference an existing alias so that we don't create a chain + * of aliases. With this code, we guarantee that an alias is + * always exactly one level of indirection away from the + * actual aliased name. + */ + target_node = (struct acpi_namespace_node *) target_node->object; + } /* - * The new alias assumes the type of the source, but it points - * to the same object. The reference count of the object has an - * additional reference to prevent deletion out from under either the - * source or the alias Node + * For objects that can never change (i.e., the NS node will + * permanently point to the same object), we can simply attach + * the object to the new NS node. For other objects (such as + * Integers, buffers, etc.), we have to point the Alias node + * to the original Node. */ + switch (target_node->type) { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + case ACPI_TYPE_PACKAGE: + case ACPI_TYPE_BUFFER_FIELD: + + /* + * The new alias has the type ALIAS and points to the original + * NS node, not the object itself. This is because for these + * types, the object can change dynamically via a Store. + */ + alias_node->type = ACPI_TYPE_LOCAL_ALIAS; + alias_node->object = ACPI_CAST_PTR (union acpi_operand_object, target_node); + break; + + default: + + /* Attach the original source object to the new Alias Node */ + + /* + * The new alias assumes the type of the target, and it points + * to the same object. The reference count of the object has an + * additional reference to prevent deletion out from under either the + * target node or the alias Node + */ + status = acpi_ns_attach_object (alias_node, + acpi_ns_get_attached_object (target_node), + target_node->type); + break; + } /* Since both operands are Nodes, we don't need to delete them */ @@ -87,9 +141,9 @@ /***************************************************************************** * - * FUNCTION: Acpi_ex_create_event + * FUNCTION: acpi_ex_create_event * - * PARAMETERS: Walk_state - Current state + * PARAMETERS: walk_state - Current state * * RETURN: Status * @@ -99,13 +153,13 @@ acpi_status acpi_ex_create_event ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_operand_object *obj_desc; + acpi_status status; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE ("Ex_create_event"); + ACPI_FUNCTION_TRACE ("ex_create_event"); obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_EVENT); @@ -114,11 +168,11 @@ goto cleanup; } - /* Create the actual OS semaphore */ - - /* TBD: [Investigate] should be created with 0 or 1 units? */ - - status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 1, + /* + * Create the actual OS semaphore, with zero initial units -- meaning + * that the event is created in an unsignalled state + */ + status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &obj_desc->event.semaphore); if (ACPI_FAILURE (status)) { goto cleanup; @@ -126,8 +180,8 @@ /* Attach object to the Node */ - status = acpi_ns_attach_object ((acpi_namespace_node *) walk_state->operands[0], - obj_desc, (u8) ACPI_TYPE_EVENT); + status = acpi_ns_attach_object ((struct acpi_namespace_node *) walk_state->operands[0], + obj_desc, ACPI_TYPE_EVENT); cleanup: /* @@ -141,27 +195,27 @@ /***************************************************************************** * - * FUNCTION: Acpi_ex_create_mutex + * FUNCTION: acpi_ex_create_mutex * - * PARAMETERS: Walk_state - Current state + * PARAMETERS: walk_state - Current state * * RETURN: Status * * DESCRIPTION: Create a new mutex object * - * Mutex (Name[0], Sync_level[1]) + * Mutex (Name[0], sync_level[1]) * ****************************************************************************/ acpi_status acpi_ex_create_mutex ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object *obj_desc; + acpi_status status = AE_OK; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE_PTR ("Ex_create_mutex", WALK_OPERANDS); + ACPI_FUNCTION_TRACE_PTR ("ex_create_mutex", ACPI_WALK_OPERANDS); /* Create the new mutex object */ @@ -172,8 +226,11 @@ goto cleanup; } - /* Create the actual OS semaphore */ - + /* + * Create the actual OS semaphore. + * One unit max to make it a mutex, with one initial unit to allow + * the mutex to be acquired. + */ status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore); if (ACPI_FAILURE (status)) { goto cleanup; @@ -182,9 +239,10 @@ /* Init object and attach to NS node */ obj_desc->mutex.sync_level = (u8) walk_state->operands[1]->integer.value; + obj_desc->mutex.node = (struct acpi_namespace_node *) walk_state->operands[0]; - status = acpi_ns_attach_object ((acpi_namespace_node *) walk_state->operands[0], - obj_desc, (u8) ACPI_TYPE_MUTEX); + status = acpi_ns_attach_object (obj_desc->mutex.node, + obj_desc, ACPI_TYPE_MUTEX); cleanup: @@ -199,12 +257,12 @@ /***************************************************************************** * - * FUNCTION: Acpi_ex_create_region + * FUNCTION: acpi_ex_create_region * - * PARAMETERS: Aml_start - Pointer to the region declaration AML - * Aml_length - Max length of the declaration AML + * PARAMETERS: aml_start - Pointer to the region declaration AML + * aml_length - Max length of the declaration AML * Operands - List of operands for the opcode - * Walk_state - Current state + * walk_state - Current state * * RETURN: Status * @@ -214,28 +272,29 @@ acpi_status acpi_ex_create_region ( - u8 *aml_start, - u32 aml_length, - u8 region_space, - acpi_walk_state *walk_state) + u8 *aml_start, + u32 aml_length, + u8 region_space, + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_operand_object *obj_desc; - acpi_namespace_node *node; + acpi_status status; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + union acpi_operand_object *region_obj2; - FUNCTION_TRACE ("Ex_create_region"); + ACPI_FUNCTION_TRACE ("ex_create_region"); /* Get the Node from the object stack */ - node = (acpi_namespace_node *) walk_state->operands[0]; + node = walk_state->op->common.node; /* * If the region object is already attached to this node, * just return */ - if (node->object) { + if (acpi_ns_get_attached_object (node)) { return_ACPI_STATUS (AE_OK); } @@ -243,9 +302,9 @@ * Space ID must be one of the predefined IDs, or in the user-defined * range */ - if ((region_space >= NUM_REGION_TYPES) && - (region_space < USER_REGION_BEGIN)) { - REPORT_ERROR (("Invalid Address_space type %X\n", region_space)); + if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && + (region_space < ACPI_USER_REGION_BEGIN)) { + ACPI_REPORT_ERROR (("Invalid address_space type %X\n", region_space)); return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID); } @@ -261,21 +320,13 @@ goto cleanup; } - /* Allocate a method object for this region */ - - obj_desc->region.extra = acpi_ut_create_internal_object ( - INTERNAL_TYPE_EXTRA); - if (!obj_desc->region.extra) { - status = AE_NO_MEMORY; - goto cleanup; - } - /* * Remember location in AML stream of address & length * operands since they need to be evaluated at run time. */ - obj_desc->region.extra->extra.aml_start = aml_start; - obj_desc->region.extra->extra.aml_length = aml_length; + region_obj2 = obj_desc->common.next_object; + region_obj2->extra.aml_start = aml_start; + region_obj2->extra.aml_length = aml_length; /* Init the region from the operands */ @@ -286,102 +337,137 @@ /* Install the new region object in the parent Node */ - status = acpi_ns_attach_object (node, obj_desc, - (u8) ACPI_TYPE_REGION); - if (ACPI_FAILURE (status)) { - goto cleanup; - } + status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION); - /* - * If we have a valid region, initialize it - * Namespace is NOT locked at this point. - */ - status = acpi_ev_initialize_region (obj_desc, FALSE); - if (ACPI_FAILURE (status)) { - /* - * If AE_NOT_EXIST is returned, it is not fatal - * because many regions get created before a handler - * is installed for said region. - */ - if (AE_NOT_EXIST == status) { - status = AE_OK; - } - } cleanup: /* Remove local reference to the object */ acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); } /***************************************************************************** * - * FUNCTION: Acpi_ex_create_table_region + * FUNCTION: acpi_ex_create_table_region * - * PARAMETERS: Walk_state - Current state + * PARAMETERS: walk_state - Current state * * RETURN: Status * - * DESCRIPTION: Create a new Data_table_region object + * DESCRIPTION: Create a new data_table_region object * ****************************************************************************/ acpi_status acpi_ex_create_table_region ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; + acpi_status status; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + struct acpi_table_header *table; + union acpi_operand_object *region_obj2; - FUNCTION_TRACE ("Ex_create_table_region"); + ACPI_FUNCTION_TRACE ("ex_create_table_region"); -/* - acpi_operand_object *Obj_desc; - Obj_desc = Acpi_ut_create_internal_object (ACPI_TYPE_REGION); - if (!Obj_desc) - { - Status = AE_NO_MEMORY; - goto Cleanup; + /* Get the Node from the object stack */ + + node = walk_state->op->common.node; + + /* + * If the region object is already attached to this node, + * just return + */ + if (acpi_ns_get_attached_object (node)) { + return_ACPI_STATUS (AE_OK); } + /* Find the ACPI table */ -Cleanup: -*/ + status = acpi_tb_find_table (operand[1]->string.pointer, + operand[2]->string.pointer, + operand[3]->string.pointer, &table); + + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Create the region descriptor */ + + obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION); + if (!obj_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + region_obj2 = obj_desc->common.next_object; + region_obj2->extra.region_context = NULL; + + /* Init the region from the operands */ + + obj_desc->region.space_id = REGION_DATA_TABLE; + obj_desc->region.address = (acpi_physical_address) ACPI_TO_INTEGER (table); + obj_desc->region.length = table->length; + obj_desc->region.node = node; + obj_desc->region.flags = AOPOBJ_DATA_VALID; + /* Install the new region object in the parent Node */ + + status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + status = acpi_ev_initialize_region (obj_desc, FALSE); + if (ACPI_FAILURE (status)) { + if (status == AE_NOT_EXIST) { + status = AE_OK; + } + else { + goto cleanup; + } + } + + obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE; + + +cleanup: + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } /***************************************************************************** * - * FUNCTION: Acpi_ex_create_processor + * FUNCTION: acpi_ex_create_processor * - * PARAMETERS: Op - Op containing the Processor definition and - * args - * Processor_node - Parent Node for the processor object + * PARAMETERS: walk_state - Current state * * RETURN: Status * * DESCRIPTION: Create a new processor object and populate the fields * - * Processor (Name[0], Cpu_iD[1], Pblock_addr[2], Pblock_length[3]) + * Processor (Name[0], cpu_iD[1], pblock_addr[2], pblock_length[3]) * ****************************************************************************/ acpi_status acpi_ex_create_processor ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *obj_desc; - acpi_status status; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE_PTR ("Ex_create_processor", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ex_create_processor", walk_state); /* Create the processor object */ @@ -395,13 +481,13 @@ * Initialize the processor object from the operands */ obj_desc->processor.proc_id = (u8) operand[1]->integer.value; - obj_desc->processor.address = (ACPI_IO_ADDRESS) operand[2]->integer.value; + obj_desc->processor.address = (acpi_io_address) operand[2]->integer.value; obj_desc->processor.length = (u8) operand[3]->integer.value; /* Install the processor object in the parent Node */ - status = acpi_ns_attach_object ((acpi_namespace_node *) operand[0], - obj_desc, (u8) ACPI_TYPE_PROCESSOR); + status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0], + obj_desc, ACPI_TYPE_PROCESSOR); /* Remove local reference to the object */ @@ -413,30 +499,28 @@ /***************************************************************************** * - * FUNCTION: Acpi_ex_create_power_resource + * FUNCTION: acpi_ex_create_power_resource * - * PARAMETERS: Op - Op containing the Power_resource definition - * and args - * Power_node - Parent Node for the power object + * PARAMETERS: walk_state - Current state * * RETURN: Status * - * DESCRIPTION: Create a new Power_resource object and populate the fields + * DESCRIPTION: Create a new power_resource object and populate the fields * - * Power_resource (Name[0], System_level[1], Resource_order[2]) + * power_resource (Name[0], system_level[1], resource_order[2]) * ****************************************************************************/ acpi_status acpi_ex_create_power_resource ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_status status; - acpi_operand_object *obj_desc; + union acpi_operand_object **operand = &walk_state->operands[0]; + acpi_status status; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE_PTR ("Ex_create_power_resource", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ex_create_power_resource", walk_state); /* Create the power resource object */ @@ -453,8 +537,8 @@ /* Install the power resource object in the parent Node */ - status = acpi_ns_attach_object ((acpi_namespace_node *) operand[0], - obj_desc, (u8) ACPI_TYPE_POWER); + status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0], + obj_desc, ACPI_TYPE_POWER); /* Remove local reference to the object */ @@ -463,15 +547,15 @@ return_ACPI_STATUS (status); } +#endif /***************************************************************************** * - * FUNCTION: Acpi_ex_create_method + * FUNCTION: acpi_ex_create_method * - * PARAMETERS: Aml_start - First byte of the method's AML - * Aml_length - AML byte count for this method - * Method_flags - AML method flag byte - * Method - Method Node + * PARAMETERS: aml_start - First byte of the method's AML + * aml_length - AML byte count for this method + * walk_state - Current state * * RETURN: Status * @@ -481,17 +565,17 @@ acpi_status acpi_ex_create_method ( - u8 *aml_start, - u32 aml_length, - acpi_walk_state *walk_state) + u8 *aml_start, + u32 aml_length, + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *obj_desc; - acpi_status status; - u8 method_flags; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *obj_desc; + acpi_status status; + u8 method_flags; - FUNCTION_TRACE_PTR ("Ex_create_method", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ex_create_method", walk_state); /* Create a new method object */ @@ -520,7 +604,7 @@ if (method_flags & METHOD_FLAGS_SERIALIZED) { /* * ACPI 1.0: Concurrency = 1 - * ACPI 2.0: Concurrency = (Sync_level (in method declaration) + 1) + * ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1) */ obj_desc->method.concurrency = (u8) (((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1); @@ -532,8 +616,8 @@ /* Attach the new object to the method Node */ - status = acpi_ns_attach_object ((acpi_namespace_node *) operand[0], - obj_desc, (u8) ACPI_TYPE_METHOD); + status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0], + obj_desc, ACPI_TYPE_METHOD); /* Remove local reference to the object */ diff -urN linux-2.4.21/drivers/acpi/executer/exdump.c linux-2.4.22/drivers/acpi/executer/exdump.c --- linux-2.4.21/drivers/acpi/executer/exdump.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exdump.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,271 +1,198 @@ /****************************************************************************** * * Module Name: exdump - Interpreter debug output routines - * $Revision: 126 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "actables.h" -#include "acparser.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exdump") + ACPI_MODULE_NAME ("exdump") /* * The following routines are used for debug output only */ -#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /***************************************************************************** * - * FUNCTION: Acpi_ex_show_hex_value + * FUNCTION: acpi_ex_dump_operand * - * PARAMETERS: Byte_count - Number of bytes to print (1, 2, or 4) - * *Aml_start - Address in AML stream of bytes to print - * Interpreter_mode - Current running mode (load1/Load2/Exec) - * Lead_space - # of spaces to print ahead of value - * 0 => none ahead but one behind - * - * DESCRIPTION: Print Byte_count byte(s) starting at Aml_start as a single - * value, in hex. If Byte_count > 1 or the value printed is > 9, also - * print in decimal. - * - ****************************************************************************/ - -void -acpi_ex_show_hex_value ( - u32 byte_count, - u8 *aml_start, - u32 lead_space) -{ - u32 value; /* Value retrieved from AML stream */ - u32 show_decimal_value; - u32 length; /* Length of printed field */ - u8 *current_aml_ptr = NULL; /* Pointer to current byte of AML value */ - - - FUNCTION_TRACE ("Ex_show_hex_value"); - - - if (!aml_start) { - REPORT_ERROR (("Ex_show_hex_value: null pointer\n")); - } - - /* - * AML numbers are always stored little-endian, - * even if the processor is big-endian. - */ - for (current_aml_ptr = aml_start + byte_count, - value = 0; - current_aml_ptr > aml_start; ) { - value = (value << 8) + (u32)* --current_aml_ptr; - } - - length = lead_space * byte_count + 2; - if (byte_count > 1) { - length += (byte_count - 1); - } - - show_decimal_value = (byte_count > 1 || value > 9); - if (show_decimal_value) { - length += 3 + acpi_ex_digits_needed (value, 10); - } - - for (length = lead_space; length; --length ) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " ")); - } - - while (byte_count--) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, "%02x", *aml_start++)); - - if (byte_count) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " ")); - } - } - - if (show_decimal_value) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " [%d]", value)); - } - - if (0 == lead_space) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " ")); - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, "\n")); - return_VOID; -} - - -/***************************************************************************** - * - * FUNCTION: Acpi_ex_dump_operand - * - * PARAMETERS: *Entry_desc - Pointer to entry to be dumped + * PARAMETERS: *obj_desc - Pointer to entry to be dumped * * RETURN: Status * - * DESCRIPTION: Dump a stack entry + * DESCRIPTION: Dump an operand object * ****************************************************************************/ -acpi_status +void acpi_ex_dump_operand ( - acpi_operand_object *entry_desc) + union acpi_operand_object *obj_desc) { - u8 *buf = NULL; - u32 length; - u32 i; + u8 *buf = NULL; + u32 length; + union acpi_operand_object **element; + u16 element_index; - PROC_NAME ("Ex_dump_operand") + ACPI_FUNCTION_NAME ("ex_dump_operand") - if (!entry_desc) { + if (!((ACPI_LV_EXEC & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { + return; + } + + if (!obj_desc) { /* * This usually indicates that something serious is wrong -- * since most (if not all) * code that dumps the stack expects something to be there! */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null stack entry ptr\n")); - return (AE_OK); + acpi_os_printf ("Null stack entry ptr\n"); + return; } - if (VALID_DESCRIPTOR_TYPE (entry_desc, ACPI_DESC_TYPE_NAMED)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%p NS Node: ", entry_desc)); - DUMP_ENTRY (entry_desc, ACPI_LV_INFO); - return (AE_OK); + if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p NS Node: ", obj_desc)); + ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC); + return; } - if (!VALID_DESCRIPTOR_TYPE (entry_desc, ACPI_DESC_TYPE_INTERNAL)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%p Is not a local object \n", entry_desc)); - DUMP_BUFFER (entry_desc, sizeof (acpi_operand_object)); - return (AE_OK); + if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is not a local object\n", obj_desc)); + ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object)); + return; } - /* Entry_desc is a valid object */ - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%p ", entry_desc)); - - switch (entry_desc->common.type) { - case INTERNAL_TYPE_REFERENCE: - - switch (entry_desc->reference.opcode) { - case AML_ZERO_OP: - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: Zero\n")); - break; - + /* obj_desc is a valid object */ - case AML_ONE_OP: - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: One\n")); - break; - - - case AML_ONES_OP: - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: Ones\n")); - break; - - - case AML_REVISION_OP: - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: Revision\n")); - break; + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc)); + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_LOCAL_REFERENCE: + switch (obj_desc->reference.opcode) { case AML_DEBUG_OP: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: Debug\n")); + acpi_os_printf ("Reference: Debug\n"); break; case AML_NAME_OP: - DUMP_PATHNAME (entry_desc->reference.object, "Reference: Name: ", + ACPI_DUMP_PATHNAME (obj_desc->reference.object, "Reference: Name: ", ACPI_LV_INFO, _COMPONENT); - DUMP_ENTRY (entry_desc->reference.object, ACPI_LV_INFO); + ACPI_DUMP_ENTRY (obj_desc->reference.object, ACPI_LV_INFO); break; case AML_INDEX_OP: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: Index %p\n", - entry_desc->reference.object)); + acpi_os_printf ("Reference: Index %p\n", + obj_desc->reference.object); + break; + + + case AML_REF_OF_OP: + + acpi_os_printf ("Reference: (ref_of) %p\n", + obj_desc->reference.object); break; case AML_ARG_OP: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: Arg%d", - entry_desc->reference.offset)); + acpi_os_printf ("Reference: Arg%d", + obj_desc->reference.offset); - if (ACPI_TYPE_INTEGER == entry_desc->common.type) { + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { /* Value is a Number */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " value is [%8.8X%8.8x]", - HIDWORD(entry_desc->integer.value), - LODWORD(entry_desc->integer.value))); + acpi_os_printf (" value is [%8.8X%8.8x]", + ACPI_HIDWORD(obj_desc->integer.value), + ACPI_LODWORD(obj_desc->integer.value)); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); + acpi_os_printf ("\n"); break; case AML_LOCAL_OP: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference: Local%d", - entry_desc->reference.offset)); + acpi_os_printf ("Reference: Local%d", + obj_desc->reference.offset); - if (ACPI_TYPE_INTEGER == entry_desc->common.type) { + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { /* Value is a Number */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " value is [%8.8X%8.8x]", - HIDWORD(entry_desc->integer.value), - LODWORD(entry_desc->integer.value))); + acpi_os_printf (" value is [%8.8X%8.8x]", + ACPI_HIDWORD(obj_desc->integer.value), + ACPI_LODWORD(obj_desc->integer.value)); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); + acpi_os_printf ("\n"); break; case AML_INT_NAMEPATH_OP: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference.Node->Name %X\n", - entry_desc->reference.node->name)); + + acpi_os_printf ("Reference.Node->Name %X\n", + obj_desc->reference.node->name.integer); break; + default: /* unknown opcode */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Unknown opcode=%X\n", - entry_desc->reference.opcode)); + acpi_os_printf ("Unknown Reference opcode=%X\n", + obj_desc->reference.opcode); break; } @@ -275,11 +202,11 @@ case ACPI_TYPE_BUFFER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Buffer len %X @ %p \n", - entry_desc->buffer.length, - entry_desc->buffer.pointer)); + acpi_os_printf ("Buffer len %X @ %p \n", + obj_desc->buffer.length, + obj_desc->buffer.pointer); - length = entry_desc->buffer.length; + length = obj_desc->buffer.length; if (length > 64) { length = 64; @@ -287,13 +214,13 @@ /* Debug only -- dump the buffer contents */ - if (entry_desc->buffer.pointer) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Buffer Contents: ")); + if (obj_desc->buffer.pointer) { + acpi_os_printf ("Buffer Contents: "); - for (buf = entry_desc->buffer.pointer; length--; ++buf) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " %02x", *buf)); + for (buf = obj_desc->buffer.pointer; length--; ++buf) { + acpi_os_printf (" %02x", *buf); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,"\n")); + acpi_os_printf ("\n"); } break; @@ -301,135 +228,104 @@ case ACPI_TYPE_INTEGER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Integer %8.8X%8.8X\n", - HIDWORD (entry_desc->integer.value), - LODWORD (entry_desc->integer.value))); - break; - - - case INTERNAL_TYPE_IF: - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "If [Integer] %8.8X%8.8X\n", - HIDWORD (entry_desc->integer.value), - LODWORD (entry_desc->integer.value))); - break; - - - case INTERNAL_TYPE_WHILE: - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "While [Integer] %8.8X%8.8X\n", - HIDWORD (entry_desc->integer.value), - LODWORD (entry_desc->integer.value))); + acpi_os_printf ("Integer %8.8X%8.8X\n", + ACPI_HIDWORD (obj_desc->integer.value), + ACPI_LODWORD (obj_desc->integer.value)); break; case ACPI_TYPE_PACKAGE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Package count %X @ %p\n", - entry_desc->package.count, entry_desc->package.elements)); + acpi_os_printf ("Package count %X @ %p\n", + obj_desc->package.count, obj_desc->package.elements); /* * If elements exist, package vector pointer is valid, * and debug_level exceeds 1, dump package's elements. */ - if (entry_desc->package.count && - entry_desc->package.elements && + if (obj_desc->package.count && + obj_desc->package.elements && acpi_dbg_level > 1) { - acpi_operand_object**element; - u16 element_index; - - for (element_index = 0, element = entry_desc->package.elements; - element_index < entry_desc->package.count; + for (element_index = 0, element = obj_desc->package.elements; + element_index < obj_desc->package.count; ++element_index, ++element) { acpi_ex_dump_operand (*element); } } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); - + acpi_os_printf ("\n"); break; case ACPI_TYPE_REGION: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Region %s (%X)", - acpi_ut_get_region_name (entry_desc->region.space_id), - entry_desc->region.space_id)); + acpi_os_printf ("Region %s (%X)", + acpi_ut_get_region_name (obj_desc->region.space_id), + obj_desc->region.space_id); /* * If the address and length have not been evaluated, * don't print them. */ - if (!(entry_desc->region.flags & AOPOBJ_DATA_VALID)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); + if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) { + acpi_os_printf ("\n"); } else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " base %8.8X%8.8X Length %X\n", - HIDWORD(entry_desc->region.address), - LODWORD(entry_desc->region.address), - entry_desc->region.length)); + acpi_os_printf (" base %8.8X%8.8X Length %X\n", + ACPI_HIDWORD (obj_desc->region.address), + ACPI_LODWORD (obj_desc->region.address), + obj_desc->region.length); } break; case ACPI_TYPE_STRING: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "String length %X @ %p \"", - entry_desc->string.length, entry_desc->string.pointer)); - - for (i = 0; i < entry_desc->string.length; i++) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "%c", - entry_desc->string.pointer[i])); - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\"\n")); + acpi_os_printf ("String length %X @ %p ", + obj_desc->string.length, obj_desc->string.pointer); + acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX); + acpi_os_printf ("\n"); break; - case INTERNAL_TYPE_BANK_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Bank_field\n")); + acpi_os_printf ("bank_field\n"); break; - case INTERNAL_TYPE_REGION_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, - "Region_field: bits=%X bitaccwidth=%X lock=%X update=%X at byte=%X bit=%X of below:\n", - entry_desc->field.bit_length, entry_desc->field.access_bit_width, - entry_desc->field.lock_rule, entry_desc->field.update_rule, - entry_desc->field.base_byte_offset, entry_desc->field.start_field_bit_offset)); - DUMP_STACK_ENTRY (entry_desc->field.region_obj); + acpi_os_printf ( + "region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n", + obj_desc->field.bit_length, obj_desc->field.access_byte_width, + obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK, + obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK, + obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset); + ACPI_DUMP_STACK_ENTRY (obj_desc->field.region_obj); break; - case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Index_field\n")); + acpi_os_printf ("index_field\n"); break; case ACPI_TYPE_BUFFER_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, - "Buffer_field: %X bits at byte %X bit %X of \n", - entry_desc->buffer_field.bit_length, entry_desc->buffer_field.base_byte_offset, - entry_desc->buffer_field.start_field_bit_offset)); + acpi_os_printf ( + "buffer_field: %X bits at byte %X bit %X of \n", + obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset, + obj_desc->buffer_field.start_field_bit_offset); - if (!entry_desc->buffer_field.buffer_obj) - { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*NULL* \n")); + if (!obj_desc->buffer_field.buffer_obj) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL* \n")); } - - else if (ACPI_TYPE_BUFFER != - entry_desc->buffer_field.buffer_obj->common.type) - { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "*not a Buffer* \n")); + else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER) { + acpi_os_printf ("*not a Buffer* \n"); } - - else - { - DUMP_STACK_ENTRY (entry_desc->buffer_field.buffer_obj); + else { + ACPI_DUMP_STACK_ENTRY (obj_desc->buffer_field.buffer_obj); } break; @@ -437,81 +333,67 @@ case ACPI_TYPE_EVENT: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Event\n")); + acpi_os_printf ("Event\n"); break; case ACPI_TYPE_METHOD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, + acpi_os_printf ( "Method(%X) @ %p:%X\n", - entry_desc->method.param_count, - entry_desc->method.aml_start, entry_desc->method.aml_length)); + obj_desc->method.param_count, + obj_desc->method.aml_start, obj_desc->method.aml_length); break; case ACPI_TYPE_MUTEX: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Mutex\n")); + acpi_os_printf ("Mutex\n"); break; case ACPI_TYPE_DEVICE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Device\n")); + acpi_os_printf ("Device\n"); break; case ACPI_TYPE_POWER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Power\n")); + acpi_os_printf ("Power\n"); break; case ACPI_TYPE_PROCESSOR: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Processor\n")); + acpi_os_printf ("Processor\n"); break; case ACPI_TYPE_THERMAL: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Thermal\n")); + acpi_os_printf ("Thermal\n"); break; default: - /* unknown Entry_desc->Common.Type value */ - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Unknown Type %X\n", - entry_desc->common.type)); - - /* Back up to previous entry */ - - entry_desc--; - + /* Unknown Type */ - /* TBD: [Restructure] Change to use dump object routine !! */ - /* What is all of this?? */ - - DUMP_BUFFER (entry_desc, sizeof (acpi_operand_object)); - DUMP_BUFFER (++entry_desc, sizeof (acpi_operand_object)); - DUMP_BUFFER (++entry_desc, sizeof (acpi_operand_object)); + acpi_os_printf ("Unknown Type %X\n", ACPI_GET_OBJECT_TYPE (obj_desc)); break; - } - return (AE_OK); + return; } /***************************************************************************** * - * FUNCTION: Acpi_ex_dump_operands + * FUNCTION: acpi_ex_dump_operands * - * PARAMETERS: Interpreter_mode - Load or Exec + * PARAMETERS: interpreter_mode - Load or Exec * *Ident - Identification - * Num_levels - # of stack entries to dump above line + * num_levels - # of stack entries to dump above line * *Note - Output notation * * DESCRIPTION: Dump the object stack @@ -520,54 +402,45 @@ void acpi_ex_dump_operands ( - acpi_operand_object **operands, - operating_mode interpreter_mode, - NATIVE_CHAR *ident, - u32 num_levels, - NATIVE_CHAR *note, - NATIVE_CHAR *module_name, - u32 line_number) + union acpi_operand_object **operands, + acpi_interpreter_mode interpreter_mode, + char *ident, + u32 num_levels, + char *note, + char *module_name, + u32 line_number) { - NATIVE_UINT i; - acpi_operand_object **entry_desc; + acpi_native_uint i; + union acpi_operand_object **obj_desc; - PROC_NAME ("Ex_dump_operands"); + ACPI_FUNCTION_NAME ("ex_dump_operands"); - if (!ident) - { + if (!ident) { ident = "?"; } - if (!note) - { + if (!note) { note = "?"; } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "************* Operand Stack Contents (Opcode [%s], %d Operands)\n", ident, num_levels)); - if (num_levels == 0) - { + if (num_levels == 0) { num_levels = 1; } - /* Dump the stack starting at the top, working down */ - - for (i = 0; num_levels > 0; i--, num_levels--) - { - entry_desc = &operands[i]; + /* Dump the operand stack starting at the top */ - if (ACPI_FAILURE (acpi_ex_dump_operand (*entry_desc))) - { - break; - } + for (i = 0; num_levels > 0; i--, num_levels--) { + obj_desc = &operands[i]; + acpi_ex_dump_operand (*obj_desc); } - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "************* Stack dump from %s(%d), %s\n", module_name, line_number, note)); return; @@ -576,7 +449,59 @@ /***************************************************************************** * - * FUNCTION: Acpi_ex_dump_node + * FUNCTION: acpi_ex_out* + * + * PARAMETERS: Title - Descriptive text + * Value - Value to be displayed + * + * DESCRIPTION: Object dump output formatting functions. These functions + * reduce the number of format strings required and keeps them + * all in one place for easy modification. + * + ****************************************************************************/ + +void +acpi_ex_out_string ( + char *title, + char *value) +{ + acpi_os_printf ("%20s : %s\n", title, value); +} + +void +acpi_ex_out_pointer ( + char *title, + void *value) +{ + acpi_os_printf ("%20s : %p\n", title, value); +} + +void +acpi_ex_out_integer ( + char *title, + u32 value) +{ + acpi_os_printf ("%20s : %X\n", title, value); +} + +void +acpi_ex_out_address ( + char *title, + acpi_physical_address value) +{ + +#if ACPI_MACHINE_WIDTH == 16 + acpi_os_printf ("%20s : %p\n", title, value); +#else + acpi_os_printf ("%20s : %8.8X%8.8X\n", title, + ACPI_HIDWORD (value), ACPI_LODWORD (value)); +#endif +} + + +/***************************************************************************** + * + * FUNCTION: acpi_ex_dump_node * * PARAMETERS: *Node - Descriptor to dump * Flags - Force display @@ -587,37 +512,34 @@ void acpi_ex_dump_node ( - acpi_namespace_node *node, - u32 flags) + struct acpi_namespace_node *node, + u32 flags) { - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); - if (!flags) - { - if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) - { + if (!flags) { + if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { return; } } - - acpi_os_printf ("%20s : %4.4s\n", "Name", (char*)&node->name); - acpi_os_printf ("%20s : %s\n", "Type", acpi_ut_get_type_name (node->type)); - acpi_os_printf ("%20s : %X\n", "Flags", node->flags); - acpi_os_printf ("%20s : %X\n", "Owner Id", node->owner_id); - acpi_os_printf ("%20s : %X\n", "Reference Count", node->reference_count); - acpi_os_printf ("%20s : %p\n", "Attached Object", node->object); - acpi_os_printf ("%20s : %p\n", "Child_list", node->child); - acpi_os_printf ("%20s : %p\n", "Next_peer", node->peer); - acpi_os_printf ("%20s : %p\n", "Parent", acpi_ns_get_parent_object (node)); + acpi_os_printf ("%20s : %4.4s\n", "Name", node->name.ascii); + acpi_ex_out_string ("Type", acpi_ut_get_type_name (node->type)); + acpi_ex_out_integer ("Flags", node->flags); + acpi_ex_out_integer ("Owner Id", node->owner_id); + acpi_ex_out_integer ("Reference Count", node->reference_count); + acpi_ex_out_pointer ("Attached Object", acpi_ns_get_attached_object (node)); + acpi_ex_out_pointer ("child_list", node->child); + acpi_ex_out_pointer ("next_peer", node->peer); + acpi_ex_out_pointer ("Parent", acpi_ns_get_parent_node (node)); } /***************************************************************************** * - * FUNCTION: Acpi_ex_dump_object_descriptor + * FUNCTION: acpi_ex_dump_object_descriptor * * PARAMETERS: *Object - Descriptor to dump * Flags - Force display @@ -628,253 +550,240 @@ void acpi_ex_dump_object_descriptor ( - acpi_operand_object *obj_desc, - u32 flags) + union acpi_operand_object *obj_desc, + u32 flags) { - const acpi_opcode_info *op_info; + u32 i; - FUNCTION_TRACE ("Ex_dump_object_descriptor"); + ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor"); - if (!flags) - { - if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) - { - return; + if (!flags) { + if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { + return_VOID; } } - if (!(VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL))) - { - acpi_os_printf ("%p is not a valid ACPI object\n", obj_desc); + if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) { + acpi_ex_dump_node ((struct acpi_namespace_node *) obj_desc, flags); + acpi_os_printf ("\nAttached Object (%p):\n", ((struct acpi_namespace_node *) obj_desc)->object); + acpi_ex_dump_object_descriptor (((struct acpi_namespace_node *) obj_desc)->object, flags); return; } + if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { + acpi_os_printf ("ex_dump_object_descriptor: %p is not a valid ACPI object\n", obj_desc); + return_VOID; + } + /* Common Fields */ - acpi_os_printf ("%20s : %X\n", "Reference Count", obj_desc->common.reference_count); - acpi_os_printf ("%20s : %X\n", "Flags", obj_desc->common.flags); + acpi_ex_out_string ("Type", acpi_ut_get_object_type_name (obj_desc)); + acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count); + acpi_ex_out_integer ("Flags", obj_desc->common.flags); /* Object-specific Fields */ - switch (obj_desc->common.type) - { + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_INTEGER: - acpi_os_printf ("%20s : %s\n", "Type", "Integer"); - acpi_os_printf ("%20s : %X%8.8X\n", "Value", HIDWORD (obj_desc->integer.value), - LODWORD (obj_desc->integer.value)); + acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value", + ACPI_HIDWORD (obj_desc->integer.value), + ACPI_LODWORD (obj_desc->integer.value)); break; case ACPI_TYPE_STRING: - acpi_os_printf ("%20s : %s\n", "Type", "String"); - acpi_os_printf ("%20s : %X\n", "Length", obj_desc->string.length); - acpi_os_printf ("%20s : %p\n", "Pointer", obj_desc->string.pointer); + acpi_ex_out_integer ("Length", obj_desc->string.length); + + acpi_os_printf ("%20s : %p ", "Pointer", obj_desc->string.pointer); + acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX); + acpi_os_printf ("\n"); break; case ACPI_TYPE_BUFFER: - acpi_os_printf ("%20s : %s\n", "Type", "Buffer"); - acpi_os_printf ("%20s : %X\n", "Length", obj_desc->buffer.length); - acpi_os_printf ("%20s : %p\n", "Pointer", obj_desc->buffer.pointer); + acpi_ex_out_integer ("Length", obj_desc->buffer.length); + acpi_ex_out_pointer ("Pointer", obj_desc->buffer.pointer); + ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length); break; case ACPI_TYPE_PACKAGE: - acpi_os_printf ("%20s : %s\n", "Type", "Package"); - acpi_os_printf ("%20s : %X\n", "Flags", obj_desc->package.flags); - acpi_os_printf ("%20s : %X\n", "Count", obj_desc->package.count); - acpi_os_printf ("%20s : %p\n", "Elements", obj_desc->package.elements); - acpi_os_printf ("%20s : %p\n", "Next_element", obj_desc->package.next_element); - break; - - - case ACPI_TYPE_BUFFER_FIELD: - - acpi_os_printf ("%20s : %s\n", "Type", "Buffer_field"); - acpi_os_printf ("%20s : %X\n", "Bit_length", obj_desc->buffer_field.bit_length); - acpi_os_printf ("%20s : %X\n", "Bit_offset", obj_desc->buffer_field.start_field_bit_offset); - acpi_os_printf ("%20s : %X\n", "Base_byte_offset",obj_desc->buffer_field.base_byte_offset); - acpi_os_printf ("%20s : %p\n", "Buffer_obj", obj_desc->buffer_field.buffer_obj); + acpi_ex_out_integer ("Flags", obj_desc->package.flags); + acpi_ex_out_integer ("Count", obj_desc->package.count); + acpi_ex_out_pointer ("Elements", obj_desc->package.elements); + + /* Dump the package contents */ + + if (obj_desc->package.count > 0) { + acpi_os_printf ("\nPackage Contents:\n"); + for (i = 0; i < obj_desc->package.count; i++) { + acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]); + if (obj_desc->package.elements[i]) { + acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc->package.elements[i])); + } + acpi_os_printf ("\n"); + } + } break; case ACPI_TYPE_DEVICE: - acpi_os_printf ("%20s : %s\n", "Type", "Device"); - acpi_os_printf ("%20s : %p\n", "Addr_handler", obj_desc->device.addr_handler); - acpi_os_printf ("%20s : %p\n", "Sys_handler", obj_desc->device.sys_handler); - acpi_os_printf ("%20s : %p\n", "Drv_handler", obj_desc->device.drv_handler); + acpi_ex_out_pointer ("address_space", obj_desc->device.address_space); + acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify); break; + case ACPI_TYPE_EVENT: - acpi_os_printf ("%20s : %s\n", "Type", "Event"); - acpi_os_printf ("%20s : %X\n", "Semaphore", obj_desc->event.semaphore); + acpi_ex_out_pointer ("Semaphore", obj_desc->event.semaphore); break; case ACPI_TYPE_METHOD: - acpi_os_printf ("%20s : %s\n", "Type", "Method"); - acpi_os_printf ("%20s : %X\n", "Param_count", obj_desc->method.param_count); - acpi_os_printf ("%20s : %X\n", "Concurrency", obj_desc->method.concurrency); - acpi_os_printf ("%20s : %p\n", "Semaphore", obj_desc->method.semaphore); - acpi_os_printf ("%20s : %X\n", "Aml_length", obj_desc->method.aml_length); - acpi_os_printf ("%20s : %X\n", "Aml_start", obj_desc->method.aml_start); + acpi_ex_out_integer ("param_count", obj_desc->method.param_count); + acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency); + acpi_ex_out_pointer ("Semaphore", obj_desc->method.semaphore); + acpi_ex_out_integer ("owning_id", obj_desc->method.owning_id); + acpi_ex_out_integer ("aml_length", obj_desc->method.aml_length); + acpi_ex_out_pointer ("aml_start", obj_desc->method.aml_start); break; case ACPI_TYPE_MUTEX: - acpi_os_printf ("%20s : %s\n", "Type", "Mutex"); - acpi_os_printf ("%20s : %X\n", "Sync_level", obj_desc->mutex.sync_level); - acpi_os_printf ("%20s : %p\n", "Owner", obj_desc->mutex.owner); - acpi_os_printf ("%20s : %X\n", "Acquisition_depth", obj_desc->mutex.acquisition_depth); - acpi_os_printf ("%20s : %p\n", "Semaphore", obj_desc->mutex.semaphore); + acpi_ex_out_integer ("sync_level", obj_desc->mutex.sync_level); + acpi_ex_out_pointer ("owner_thread", obj_desc->mutex.owner_thread); + acpi_ex_out_integer ("acquisition_depth",obj_desc->mutex.acquisition_depth); + acpi_ex_out_pointer ("Semaphore", obj_desc->mutex.semaphore); break; case ACPI_TYPE_REGION: - acpi_os_printf ("%20s : %s\n", "Type", "Region"); - acpi_os_printf ("%20s : %X\n", "Space_id", obj_desc->region.space_id); - acpi_os_printf ("%20s : %X\n", "Flags", obj_desc->region.flags); - acpi_os_printf ("%20s : %X\n", "Address", obj_desc->region.address); - acpi_os_printf ("%20s : %X\n", "Length", obj_desc->region.length); - acpi_os_printf ("%20s : %p\n", "Addr_handler", obj_desc->region.addr_handler); - acpi_os_printf ("%20s : %p\n", "Next", obj_desc->region.next); + acpi_ex_out_integer ("space_id", obj_desc->region.space_id); + acpi_ex_out_integer ("Flags", obj_desc->region.flags); + acpi_ex_out_address ("Address", obj_desc->region.address); + acpi_ex_out_integer ("Length", obj_desc->region.length); + acpi_ex_out_pointer ("address_space", obj_desc->region.address_space); + acpi_ex_out_pointer ("Next", obj_desc->region.next); break; case ACPI_TYPE_POWER: - acpi_os_printf ("%20s : %s\n", "Type", "Power_resource"); - acpi_os_printf ("%20s : %X\n", "System_level", obj_desc->power_resource.system_level); - acpi_os_printf ("%20s : %X\n", "Resource_order", obj_desc->power_resource.resource_order); - acpi_os_printf ("%20s : %p\n", "Sys_handler", obj_desc->power_resource.sys_handler); - acpi_os_printf ("%20s : %p\n", "Drv_handler", obj_desc->power_resource.drv_handler); + acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level); + acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order); + acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify); break; case ACPI_TYPE_PROCESSOR: - acpi_os_printf ("%20s : %s\n", "Type", "Processor"); - acpi_os_printf ("%20s : %X\n", "Processor ID", obj_desc->processor.proc_id); - acpi_os_printf ("%20s : %X\n", "Length", obj_desc->processor.length); - acpi_os_printf ("%20s : %X\n", "Address", obj_desc->processor.address); - acpi_os_printf ("%20s : %p\n", "Sys_handler", obj_desc->processor.sys_handler); - acpi_os_printf ("%20s : %p\n", "Drv_handler", obj_desc->processor.drv_handler); - acpi_os_printf ("%20s : %p\n", "Addr_handler", obj_desc->processor.addr_handler); + acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id); + acpi_ex_out_integer ("Length", obj_desc->processor.length); + acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address); + acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify); + acpi_ex_out_pointer ("address_space", obj_desc->processor.address_space); break; case ACPI_TYPE_THERMAL: - acpi_os_printf ("%20s : %s\n", "Type", "Thermal_zone"); - acpi_os_printf ("%20s : %p\n", "Sys_handler", obj_desc->thermal_zone.sys_handler); - acpi_os_printf ("%20s : %p\n", "Drv_handler", obj_desc->thermal_zone.drv_handler); - acpi_os_printf ("%20s : %p\n", "Addr_handler", obj_desc->thermal_zone.addr_handler); + acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify); + acpi_ex_out_pointer ("address_space", obj_desc->thermal_zone.address_space); break; - case INTERNAL_TYPE_REGION_FIELD: - - acpi_os_printf ("%20s : %p\n", "Access_bit_width", obj_desc->field.access_bit_width); - acpi_os_printf ("%20s : %p\n", "Bit_length", obj_desc->field.bit_length); - acpi_os_printf ("%20s : %p\n", "Base_byte_offset",obj_desc->field.base_byte_offset); - acpi_os_printf ("%20s : %p\n", "Bit_offset", obj_desc->field.start_field_bit_offset); - acpi_os_printf ("%20s : %p\n", "Region_obj", obj_desc->field.region_obj); - break; - - - case INTERNAL_TYPE_BANK_FIELD: - - acpi_os_printf ("%20s : %s\n", "Type", "Bank_field"); - acpi_os_printf ("%20s : %X\n", "Access_bit_width", obj_desc->bank_field.access_bit_width); - acpi_os_printf ("%20s : %X\n", "Lock_rule", obj_desc->bank_field.lock_rule); - acpi_os_printf ("%20s : %X\n", "Update_rule", obj_desc->bank_field.update_rule); - acpi_os_printf ("%20s : %X\n", "Bit_length", obj_desc->bank_field.bit_length); - acpi_os_printf ("%20s : %X\n", "Bit_offset", obj_desc->bank_field.start_field_bit_offset); - acpi_os_printf ("%20s : %X\n", "Base_byte_offset", obj_desc->bank_field.base_byte_offset); - acpi_os_printf ("%20s : %X\n", "Value", obj_desc->bank_field.value); - acpi_os_printf ("%20s : %p\n", "Region_obj", obj_desc->bank_field.region_obj); - acpi_os_printf ("%20s : %X\n", "Bank_register_obj", obj_desc->bank_field.bank_register_obj); - break; - - - case INTERNAL_TYPE_INDEX_FIELD: - - acpi_os_printf ("%20s : %s\n", "Type", "Index_field"); - acpi_os_printf ("%20s : %X\n", "Access_bit_width", obj_desc->index_field.access_bit_width); - acpi_os_printf ("%20s : %X\n", "Lock_rule", obj_desc->index_field.lock_rule); - acpi_os_printf ("%20s : %X\n", "Update_rule", obj_desc->index_field.update_rule); - acpi_os_printf ("%20s : %X\n", "Bit_length", obj_desc->index_field.bit_length); - acpi_os_printf ("%20s : %X\n", "Bit_offset", obj_desc->index_field.start_field_bit_offset); - acpi_os_printf ("%20s : %X\n", "Value", obj_desc->index_field.value); - acpi_os_printf ("%20s : %X\n", "Index", obj_desc->index_field.index_obj); - acpi_os_printf ("%20s : %X\n", "Data", obj_desc->index_field.data_obj); - break; - - - case INTERNAL_TYPE_REFERENCE: - - op_info = acpi_ps_get_opcode_info (obj_desc->reference.opcode); + case ACPI_TYPE_BUFFER_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags); + acpi_ex_out_integer ("access_byte_width", obj_desc->common_field.access_byte_width); + acpi_ex_out_integer ("bit_length", obj_desc->common_field.bit_length); + acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset); + acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset); + acpi_ex_out_integer ("datum_valid_bits", obj_desc->common_field.datum_valid_bits); + acpi_ex_out_integer ("end_fld_valid_bits", obj_desc->common_field.end_field_valid_bits); + acpi_ex_out_integer ("end_buf_valid_bits", obj_desc->common_field.end_buffer_valid_bits); + acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node); + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_BUFFER_FIELD: + acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj); + break; + + case ACPI_TYPE_LOCAL_REGION_FIELD: + acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj); + break; + + case ACPI_TYPE_LOCAL_BANK_FIELD: + acpi_ex_out_integer ("Value", obj_desc->bank_field.value); + acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj); + acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj); + break; + + case ACPI_TYPE_LOCAL_INDEX_FIELD: + acpi_ex_out_integer ("Value", obj_desc->index_field.value); + acpi_ex_out_pointer ("Index", obj_desc->index_field.index_obj); + acpi_ex_out_pointer ("Data", obj_desc->index_field.data_obj); + break; - acpi_os_printf ("%20s : %s\n", "Type", "Reference"); - acpi_os_printf ("%20s : %X\n", "Target_type", obj_desc->reference.target_type); - acpi_os_printf ("%20s : %s\n", "Opcode", op_info->name); - acpi_os_printf ("%20s : %X\n", "Offset", obj_desc->reference.offset); - acpi_os_printf ("%20s : %p\n", "Obj_desc", obj_desc->reference.object); - acpi_os_printf ("%20s : %p\n", "Node", obj_desc->reference.node); - acpi_os_printf ("%20s : %p\n", "Where", obj_desc->reference.where); + default: + /* All object types covered above */ + break; + } break; - case INTERNAL_TYPE_ADDRESS_HANDLER: + case ACPI_TYPE_LOCAL_REFERENCE: - acpi_os_printf ("%20s : %s\n", "Type", "Address Handler"); - acpi_os_printf ("%20s : %X\n", "Space_id", obj_desc->addr_handler.space_id); - acpi_os_printf ("%20s : %p\n", "Next", obj_desc->addr_handler.next); - acpi_os_printf ("%20s : %p\n", "Region_list", obj_desc->addr_handler.region_list); - acpi_os_printf ("%20s : %p\n", "Node", obj_desc->addr_handler.node); - acpi_os_printf ("%20s : %p\n", "Handler", obj_desc->addr_handler.handler); - acpi_os_printf ("%20s : %p\n", "Context", obj_desc->addr_handler.context); + acpi_ex_out_integer ("target_type", obj_desc->reference.target_type); + acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name); + acpi_ex_out_integer ("Offset", obj_desc->reference.offset); + acpi_ex_out_pointer ("obj_desc", obj_desc->reference.object); + acpi_ex_out_pointer ("Node", obj_desc->reference.node); + acpi_ex_out_pointer ("Where", obj_desc->reference.where); break; - case INTERNAL_TYPE_NOTIFY: + case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: - acpi_os_printf ("%20s : %s\n", "Type", "Notify Handler"); - acpi_os_printf ("%20s : %p\n", "Node", obj_desc->notify_handler.node); - acpi_os_printf ("%20s : %p\n", "Handler", obj_desc->notify_handler.handler); - acpi_os_printf ("%20s : %p\n", "Context", obj_desc->notify_handler.context); + acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id); + acpi_ex_out_pointer ("Next", obj_desc->address_space.next); + acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list); + acpi_ex_out_pointer ("Node", obj_desc->address_space.node); + acpi_ex_out_pointer ("Context", obj_desc->address_space.context); break; - case INTERNAL_TYPE_ALIAS: - case INTERNAL_TYPE_FIELD_DEFN: - case INTERNAL_TYPE_BANK_FIELD_DEFN: - case INTERNAL_TYPE_INDEX_FIELD_DEFN: - case INTERNAL_TYPE_IF: - case INTERNAL_TYPE_ELSE: - case INTERNAL_TYPE_WHILE: - case INTERNAL_TYPE_SCOPE: - case INTERNAL_TYPE_DEF_ANY: + case ACPI_TYPE_LOCAL_NOTIFY: - acpi_os_printf ("*** Structure display not implemented for type %X! ***\n", - obj_desc->common.type); + acpi_ex_out_pointer ("Node", obj_desc->notify.node); + acpi_ex_out_pointer ("Context", obj_desc->notify.context); break; + case ACPI_TYPE_LOCAL_ALIAS: + case ACPI_TYPE_LOCAL_EXTRA: + case ACPI_TYPE_LOCAL_DATA: default: - acpi_os_printf ("*** Cannot display unknown type %X! ***\n", obj_desc->common.type); + acpi_os_printf ("ex_dump_object_descriptor: Display not implemented for object type %s\n", + acpi_ut_get_object_type_name (obj_desc)); break; } diff -urN linux-2.4.21/drivers/acpi/executer/exfield.c linux-2.4.22/drivers/acpi/executer/exfield.c --- linux-2.4.21/drivers/acpi/executer/exfield.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exfield.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,69 +1,85 @@ /****************************************************************************** * * Module Name: exfield - ACPI AML (p-code) execution - field manipulation - * $Revision: 95 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "achware.h" -#include "acevents.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exfield") + ACPI_MODULE_NAME ("exfield") /******************************************************************************* * - * FUNCTION: Acpi_ex_read_data_from_field + * FUNCTION: acpi_ex_read_data_from_field * - * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE - * *Field_node - Parent node for field to be accessed - * *Buffer - Value(s) to be read or written - * Buffer_length - Number of bytes to transfer + * PARAMETERS: walk_state - Current execution state + * obj_desc - The named field + * ret_buffer_desc - Where the return data object is stored * - * RETURN: Status3 + * RETURN: Status * - * DESCRIPTION: Read or write a named field + * DESCRIPTION: Read from a named field. Returns either an Integer or a + * Buffer, depending on the size of the field. * ******************************************************************************/ acpi_status acpi_ex_read_data_from_field ( - acpi_operand_object *obj_desc, - acpi_operand_object **ret_buffer_desc) + struct acpi_walk_state *walk_state, + union acpi_operand_object *obj_desc, + union acpi_operand_object **ret_buffer_desc) { - acpi_status status; - acpi_operand_object *buffer_desc; - u32 length; - void *buffer; + acpi_status status; + union acpi_operand_object *buffer_desc; + acpi_size length; + void *buffer; + u8 locked; - FUNCTION_TRACE_PTR ("Ex_read_data_from_field", obj_desc); + ACPI_FUNCTION_TRACE_PTR ("ex_read_data_from_field", obj_desc); /* Parameter validation */ @@ -72,6 +88,44 @@ return_ACPI_STATUS (AE_AML_NO_OPERAND); } + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) { + /* + * If the buffer_field arguments have not been previously evaluated, + * evaluate them now and save the results. + */ + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_buffer_field_arguments (obj_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + } + else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) && + (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) { + /* + * This is an SMBus read. We must create a buffer to hold the data + * and directly access the region handler. + */ + buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE); + if (!buffer_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Lock entire transaction if requested */ + + locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags); + + /* + * Perform the read. + * Note: Smbus protocol value is passed in upper 16-bits of Function + */ + status = acpi_ex_access_region (obj_desc, 0, + ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer), + ACPI_READ | (obj_desc->field.attribute << 16)); + acpi_ex_release_global_lock (locked); + goto exit; + } + /* * Allocate a buffer for the contents of the field. * @@ -82,28 +136,16 @@ * * Note: Field.length is in bits. */ - length = ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length); - - if (length > sizeof (acpi_integer)) { + length = (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length); + if (length > acpi_gbl_integer_byte_width) { /* Field is too large for an Integer, create a Buffer instead */ - buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + buffer_desc = acpi_ut_create_buffer_object (length); if (!buffer_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } - - /* Create the actual read buffer */ - - buffer_desc->buffer.pointer = ACPI_MEM_CALLOCATE (length); - if (!buffer_desc->buffer.pointer) { - acpi_ut_remove_reference (buffer_desc); - return_ACPI_STATUS (AE_NO_MEMORY); - } - - buffer_desc->buffer.length = length; buffer = buffer_desc->buffer.pointer; } - else { /* Field will fit within an Integer (normal case) */ @@ -112,39 +154,34 @@ return_ACPI_STATUS (AE_NO_MEMORY); } - length = sizeof (buffer_desc->integer.value); + length = acpi_gbl_integer_byte_width; + buffer_desc->integer.value = 0; buffer = &buffer_desc->integer.value; } + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Obj=%p Type=%X Buf=%p Len=%X\n", + obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "field_write: bit_len=%X bit_off=%X byte_off=%X\n", + obj_desc->common_field.bit_length, + obj_desc->common_field.start_field_bit_offset, + obj_desc->common_field.base_byte_offset)); - /* Read from the appropriate field */ - - switch (obj_desc->common.type) { - case ACPI_TYPE_BUFFER_FIELD: - status = acpi_ex_access_buffer_field (ACPI_READ, obj_desc, buffer, length); - break; - - case INTERNAL_TYPE_REGION_FIELD: - status = acpi_ex_access_region_field (ACPI_READ, obj_desc, buffer, length); - break; + /* Lock entire transaction if requested */ - case INTERNAL_TYPE_BANK_FIELD: - status = acpi_ex_access_bank_field (ACPI_READ, obj_desc, buffer, length); - break; + locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags); - case INTERNAL_TYPE_INDEX_FIELD: - status = acpi_ex_access_index_field (ACPI_READ, obj_desc, buffer, length); - break; + /* Read from the field */ - default: - status = AE_AML_INTERNAL; - } + status = acpi_ex_extract_from_field (obj_desc, buffer, (u32) length); + acpi_ex_release_global_lock (locked); +exit: if (ACPI_FAILURE (status)) { acpi_ut_remove_reference (buffer_desc); } - else if (ret_buffer_desc) { *ret_buffer_desc = buffer_desc; } @@ -155,31 +192,33 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_write_data_to_field + * FUNCTION: acpi_ex_write_data_to_field * - * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE - * *Field_node - Parent node for field to be accessed - * *Buffer - Value(s) to be read or written - * Buffer_length - Number of bytes to transfer + * PARAMETERS: source_desc - Contains data to write + * obj_desc - The named field * * RETURN: Status * - * DESCRIPTION: Read or write a named field + * DESCRIPTION: Write to a named field * ******************************************************************************/ - acpi_status acpi_ex_write_data_to_field ( - acpi_operand_object *source_desc, - acpi_operand_object *obj_desc) + union acpi_operand_object *source_desc, + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc) { - acpi_status status; - u32 length; - void *buffer; + acpi_status status; + u32 length; + u32 required_length; + void *buffer; + void *new_buffer; + u8 locked; + union acpi_operand_object *buffer_desc; - FUNCTION_TRACE_PTR ("Ex_write_data_to_field", obj_desc); + ACPI_FUNCTION_TRACE_PTR ("ex_write_data_to_field", obj_desc); /* Parameter validation */ @@ -188,11 +227,67 @@ return_ACPI_STATUS (AE_AML_NO_OPERAND); } + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) { + /* + * If the buffer_field arguments have not been previously evaluated, + * evaluate them now and save the results. + */ + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_buffer_field_arguments (obj_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + } + else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) && + (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) { + /* + * This is an SMBus write. We will bypass the entire field mechanism + * and handoff the buffer directly to the handler. + * + * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). + */ + if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) { + ACPI_REPORT_ERROR (("SMBus write requires Buffer, found type %s\n", + acpi_ut_get_object_type_name (source_desc))); + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + } + + if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) { + ACPI_REPORT_ERROR (("SMBus write requires Buffer of length %X, found length %X\n", + ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length)); + return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); + } + + buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE); + if (!buffer_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + buffer = buffer_desc->buffer.pointer; + ACPI_MEMCPY (buffer, source_desc->buffer.pointer, ACPI_SMBUS_BUFFER_SIZE); + + /* Lock entire transaction if requested */ + + locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags); + + /* + * Perform the write (returns status and perhaps data in the same buffer) + * Note: SMBus protocol type is passed in upper 16-bits of Function. + */ + status = acpi_ex_access_region (obj_desc, 0, + (acpi_integer *) buffer, + ACPI_WRITE | (obj_desc->field.attribute << 16)); + acpi_ex_release_global_lock (locked); + + *result_desc = buffer_desc; + return_ACPI_STATUS (status); + } /* * Get a pointer to the data to be written */ - switch (source_desc->common.type) { + switch (ACPI_GET_OBJECT_TYPE (source_desc)) { case ACPI_TYPE_INTEGER: buffer = &source_desc->integer.value; length = sizeof (source_desc->integer.value); @@ -212,315 +307,58 @@ return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* - * Decode the type of field to be written + * We must have a buffer that is at least as long as the field + * we are writing to. This is because individual fields are + * indivisible and partial writes are not supported -- as per + * the ACPI specification. */ - switch (obj_desc->common.type) { - case ACPI_TYPE_BUFFER_FIELD: - status = acpi_ex_access_buffer_field (ACPI_WRITE, obj_desc, buffer, length); - break; - - case INTERNAL_TYPE_REGION_FIELD: - status = acpi_ex_access_region_field (ACPI_WRITE, obj_desc, buffer, length); - break; - - case INTERNAL_TYPE_BANK_FIELD: - status = acpi_ex_access_bank_field (ACPI_WRITE, obj_desc, buffer, length); - break; - - case INTERNAL_TYPE_INDEX_FIELD: - status = acpi_ex_access_index_field (ACPI_WRITE, obj_desc, buffer, length); - break; - - default: - return_ACPI_STATUS (AE_AML_INTERNAL); - } - - - return_ACPI_STATUS (status); -} + new_buffer = NULL; + required_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); + if (length < required_length) { + /* We need to create a new buffer */ -/******************************************************************************* - * - * FUNCTION: Acpi_ex_access_buffer_field - * - * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE - * *Field_node - Parent node for field to be accessed - * *Buffer - Value(s) to be read or written - * Buffer_length - Number of bytes to transfer - * - * RETURN: Status - * - * DESCRIPTION: Read or write a named field - * - ******************************************************************************/ - -acpi_status -acpi_ex_access_buffer_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) -{ - acpi_status status; - - - FUNCTION_TRACE_PTR ("Ex_access_buffer_field", obj_desc); - - - /* - * If the Buffer_field arguments have not been previously evaluated, - * evaluate them now and save the results. - */ - if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { - status = acpi_ds_get_buffer_field_arguments (obj_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + new_buffer = ACPI_MEM_CALLOCATE (required_length); + if (!new_buffer) { + return_ACPI_STATUS (AE_NO_MEMORY); } - } - - - status = acpi_ex_common_access_field (mode, obj_desc, buffer, buffer_length); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_access_region_field - * - * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE - * *Field_node - Parent node for field to be accessed - * *Buffer - Value(s) to be read or written - * Buffer_length - Number of bytes to transfer - * - * RETURN: Status - * - * DESCRIPTION: Read or write a named field - * - ******************************************************************************/ - -acpi_status -acpi_ex_access_region_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) -{ - acpi_status status; - u8 locked; - - - FUNCTION_TRACE_PTR ("Ex_access_region_field", obj_desc); - - - /* - * Get the global lock if needed - */ - locked = acpi_ex_acquire_global_lock (obj_desc->field.lock_rule); - - status = acpi_ex_common_access_field (mode, obj_desc, buffer, buffer_length); - - /* - * Release global lock if we acquired it earlier - */ - acpi_ex_release_global_lock (locked); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_access_bank_field - * - * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE - * *Field_node - Parent node for field to be accessed - * *Buffer - Value(s) to be read or written - * Buffer_length - Number of bytes to transfer - * - * RETURN: Status - * - * DESCRIPTION: Read or write a Bank Field - * - ******************************************************************************/ - -acpi_status -acpi_ex_access_bank_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) -{ - acpi_status status; - u8 locked; - - - FUNCTION_TRACE_PTR ("Ex_access_bank_field", obj_desc); - - - /* - * Get the global lock if needed - */ - locked = acpi_ex_acquire_global_lock (obj_desc->bank_field.lock_rule); - - - /* - * Write the Bank_value to the Bank_register to select the bank. - * The Bank_value for this Bank_field is specified in the - * Bank_field ASL declaration. The Bank_register is always a Field in - * an operation region. - */ - status = acpi_ex_common_access_field (ACPI_WRITE, - obj_desc->bank_field.bank_register_obj, - &obj_desc->bank_field.value, - sizeof (obj_desc->bank_field.value)); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - /* - * The bank was successfully selected, now read or write the actual - * data. - */ - status = acpi_ex_common_access_field (mode, obj_desc, buffer, buffer_length); - - -cleanup: - /* - * Release global lock if we acquired it earlier - */ - acpi_ex_release_global_lock (locked); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_access_index_field - * - * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE - * *Field_node - Parent node for field to be accessed - * *Buffer - Value(s) to be read or written - * Buffer_length - Number of bytes to transfer - * - * RETURN: Status - * - * DESCRIPTION: Read or write a Index Field - * - ******************************************************************************/ - -acpi_status -acpi_ex_access_index_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) -{ - acpi_status status; - u8 locked; - - - FUNCTION_TRACE_PTR ("Ex_access_index_field", obj_desc); - - - /* - * Get the global lock if needed - */ - locked = acpi_ex_acquire_global_lock (obj_desc->index_field.lock_rule); - - - /* - * Set Index value to select proper Data register - */ - status = acpi_ex_common_access_field (ACPI_WRITE, - obj_desc->index_field.index_obj, - &obj_desc->index_field.value, - sizeof (obj_desc->index_field.value)); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - /* Now read/write the data register */ - - status = acpi_ex_common_access_field (mode, obj_desc->index_field.data_obj, - buffer, buffer_length); - -cleanup: - /* - * Release global lock if we acquired it earlier - */ - acpi_ex_release_global_lock (locked); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_common_access_field - * - * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE - * *Field_node - Parent node for field to be accessed - * *Buffer - Value(s) to be read or written - * Buffer_length - Size of buffer, in bytes. Must be large - * enough for all bits of the field. - * - * RETURN: Status - * - * DESCRIPTION: Read or write a named field - * - ******************************************************************************/ - -acpi_status -acpi_ex_common_access_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) -{ - acpi_status status; - - - FUNCTION_TRACE_PTR ("Ex_common_access_field", obj_desc); - - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Obj=%p Type=%X Buf=%p Len=%X\n", - obj_desc, obj_desc->common.type, buffer, buffer_length)); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode=%d Bit_len=%X Bit_off=%X Byte_off=%X\n", - mode, obj_desc->common_field.bit_length, + /* + * Copy the original data to the new buffer, starting + * at Byte zero. All unused (upper) bytes of the + * buffer will be 0. + */ + ACPI_MEMCPY ((char *) new_buffer, (char *) buffer, length); + buffer = new_buffer; + length = required_length; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Obj=%p Type=%X Buf=%p Len=%X\n", + obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, length)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "field_read: bit_len=%X bit_off=%X byte_off=%X\n", + obj_desc->common_field.bit_length, obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.base_byte_offset)); + /* Lock entire transaction if requested */ - /* Perform the actual read or write of the field */ + locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags); - switch (mode) { - case ACPI_READ: - - status = acpi_ex_extract_from_field (obj_desc, buffer, buffer_length); - break; - - - case ACPI_WRITE: - - status = acpi_ex_insert_into_field (obj_desc, buffer, buffer_length); - break; + /* Write to the field */ + status = acpi_ex_insert_into_field (obj_desc, buffer, length); + acpi_ex_release_global_lock (locked); - default: + /* Free temporary buffer if we used one */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown I/O Mode: %X\n", mode)); - status = AE_BAD_PARAMETER; - break; + if (new_buffer) { + ACPI_MEM_FREE (new_buffer); } - return_ACPI_STATUS (status); } + diff -urN linux-2.4.21/drivers/acpi/executer/exfldio.c linux-2.4.22/drivers/acpi/executer/exfldio.c --- linux-2.4.21/drivers/acpi/executer/exfldio.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exfldio.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,73 +1,94 @@ /****************************************************************************** * * Module Name: exfldio - Aml Field I/O - * $Revision: 66 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "achware.h" -#include "acevents.h" -#include "acdispat.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exfldio") + ACPI_MODULE_NAME ("exfldio") /******************************************************************************* * - * FUNCTION: Acpi_ex_setup_field + * FUNCTION: acpi_ex_setup_region * - * PARAMETERS: *Obj_desc - Field to be read or written - * Field_datum_byte_offset - Current offset into the field + * PARAMETERS: *obj_desc - Field to be read or written + * field_datum_byte_offset - Byte offset of this datum within the + * parent field * * RETURN: Status * - * DESCRIPTION: Common processing for Acpi_ex_extract_from_field and - * Acpi_ex_insert_into_field + * DESCRIPTION: Common processing for acpi_ex_extract_from_field and + * acpi_ex_insert_into_field. Initialize the * ******************************************************************************/ acpi_status -acpi_ex_setup_field ( - acpi_operand_object *obj_desc, - u32 field_datum_byte_offset) +acpi_ex_setup_region ( + union acpi_operand_object *obj_desc, + u32 field_datum_byte_offset) { - acpi_status status = AE_OK; - acpi_operand_object *rgn_desc; + acpi_status status = AE_OK; + union acpi_operand_object *rgn_desc; - FUNCTION_TRACE_U32 ("Ex_setup_field", field_datum_byte_offset); + ACPI_FUNCTION_TRACE_U32 ("ex_setup_region", field_datum_byte_offset); rgn_desc = obj_desc->common_field.region_obj; - if (ACPI_TYPE_REGION != rgn_desc->common.type) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %x %s\n", - rgn_desc->common.type, acpi_ut_get_type_name (rgn_desc->common.type))); + /* We must have a valid region */ + + if (ACPI_GET_OBJECT_TYPE (rgn_desc) != ACPI_TYPE_REGION) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X (%s)\n", + ACPI_GET_OBJECT_TYPE (rgn_desc), + acpi_ut_get_object_type_name (rgn_desc))); + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -76,30 +97,36 @@ * evaluate them now and save the results. */ if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) { - status = acpi_ds_get_region_arguments (rgn_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } + if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { + /* SMBus has a non-linear address space */ + + return_ACPI_STATUS (AE_OK); + } + /* * Validate the request. The entire request from the byte offset for a * length of one field datum (access width) must fit within the region. * (Region length is specified in bytes) */ - if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + - field_datum_byte_offset + - obj_desc->common_field.access_byte_width)) { + if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + + field_datum_byte_offset + + obj_desc->common_field.access_byte_width)) { if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) { /* - * This is the case where the Access_type (Acc_word, etc.) is wider + * This is the case where the access_type (acc_word, etc.) is wider * than the region itself. For example, a region of length one * byte, and a field with Dword access specified. */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Field access width (%d bytes) too large for region size (%X)\n", - obj_desc->common_field.access_byte_width, rgn_desc->region.length)); + "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n", + obj_desc->common_field.node->name.ascii, obj_desc->common_field.access_byte_width, + rgn_desc->region.node->name.ascii, rgn_desc->region.length)); } /* @@ -107,12 +134,46 @@ * exceeds region length, indicate an error */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Field base+offset+width %X+%X+%X exceeds region size (%X bytes) field=%p region=%p\n", - obj_desc->common_field.base_byte_offset, field_datum_byte_offset, - obj_desc->common_field.access_byte_width, - rgn_desc->region.length, obj_desc, rgn_desc)); + "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n", + obj_desc->common_field.node->name.ascii, obj_desc->common_field.base_byte_offset, + field_datum_byte_offset, obj_desc->common_field.access_byte_width, + rgn_desc->region.node->name.ascii, rgn_desc->region.length)); + + #ifdef CONFIG_ACPI_RELAXED_AML + { + /* + * Allow access to the field if it is within the region size + * rounded up to a multiple of the access byte width. This + * overcomes "off-by-one" programming errors in the AML often + * found in Toshiba laptops. These errors were allowed by + * the Microsoft ASL compiler. + */ + u32 rounded_length = ACPI_ROUND_UP(rgn_desc->region.length, + obj_desc->common_field.access_byte_width); - return_ACPI_STATUS (AE_AML_REGION_LIMIT); + if (rounded_length < (obj_desc->common_field.base_byte_offset + + field_datum_byte_offset + + obj_desc->common_field.access_byte_width)) { + return_ACPI_STATUS (AE_AML_REGION_LIMIT); + } else { + static int warn_once = 1; + if (warn_once) { + // Could also associate a flag with each field, and + // warn once for each field. + ACPI_REPORT_WARNING(( + "The ACPI AML in your computer contains errors, " + "please nag the manufacturer to correct it.\n")); + ACPI_REPORT_WARNING(( + "Allowing relaxed access to fields; " + "turn on CONFIG_ACPI_DEBUG for details.\n")); + warn_once = 0; + } + return_ACPI_STATUS (AE_OK); + } + } + #else + return_ACPI_STATUS (AE_AML_REGION_LIMIT); + #endif } return_ACPI_STATUS (AE_OK); @@ -121,116 +182,415 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_read_field_datum + * FUNCTION: acpi_ex_access_region * - * PARAMETERS: *Obj_desc - Field to be read - * *Value - Where to store value (must be 32 bits) + * PARAMETERS: *obj_desc - Field to be read + * field_datum_byte_offset - Byte offset of this datum within the + * parent field + * *Value - Where to store value (must at least + * the size of acpi_integer) + * Function - Read or Write flag plus other region- + * dependent flags * * RETURN: Status * - * DESCRIPTION: Retrieve the value of the given field + * DESCRIPTION: Read or Write a single field datum to an Operation Region. * ******************************************************************************/ acpi_status -acpi_ex_read_field_datum ( - acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - u32 *value) +acpi_ex_access_region ( + union acpi_operand_object *obj_desc, + u32 field_datum_byte_offset, + acpi_integer *value, + u32 function) { - acpi_status status; - acpi_operand_object *rgn_desc; - ACPI_PHYSICAL_ADDRESS address; - u32 local_value; + acpi_status status; + union acpi_operand_object *rgn_desc; + acpi_physical_address address; + + + ACPI_FUNCTION_TRACE ("ex_access_region"); + + + /* + * Ensure that the region operands are fully evaluated and verify + * the validity of the request + */ + status = acpi_ex_setup_region (obj_desc, field_datum_byte_offset); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* + * The physical address of this field datum is: + * + * 1) The base of the region, plus + * 2) The base offset of the field, plus + * 3) The current offset into the field + */ + rgn_desc = obj_desc->common_field.region_obj; + address = rgn_desc->region.address + + obj_desc->common_field.base_byte_offset + + field_datum_byte_offset; + + if ((function & ACPI_IO_MASK) == ACPI_READ) { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]")); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]")); + } + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD, + " Region[%s-%X] Access %X Base:Off %X:%X at %8.8X%8.8X\n", + acpi_ut_get_region_name (rgn_desc->region.space_id), + rgn_desc->region.space_id, + obj_desc->common_field.access_byte_width, + obj_desc->common_field.base_byte_offset, + field_datum_byte_offset, + ACPI_HIDWORD (address), ACPI_LODWORD (address))); - FUNCTION_TRACE_U32 ("Ex_read_field_datum", field_datum_byte_offset); + /* Invoke the appropriate address_space/op_region handler */ + status = acpi_ev_address_space_dispatch (rgn_desc, function, + address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value); - if (!value) { - local_value = 0; - value = &local_value; /* support reads without saving value */ + if (ACPI_FAILURE (status)) { + if (status == AE_NOT_IMPLEMENTED) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Region %s(%X) not implemented\n", + acpi_ut_get_region_name (rgn_desc->region.space_id), + rgn_desc->region.space_id)); + } + else if (status == AE_NOT_EXIST) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Region %s(%X) has no handler\n", + acpi_ut_get_region_name (rgn_desc->region.space_id), + rgn_desc->region.space_id)); + } } - /* Clear the entire return buffer first, [Very Important!] */ + return_ACPI_STATUS (status); +} - *value = 0; + +/******************************************************************************* + * + * FUNCTION: acpi_ex_register_overflow + * + * PARAMETERS: *obj_desc - Register(Field) to be written + * Value - Value to be stored + * + * RETURN: TRUE if value overflows the field, FALSE otherwise + * + * DESCRIPTION: Check if a value is out of range of the field being written. + * Used to check if the values written to Index and Bank registers + * are out of range. Normally, the value is simply truncated + * to fit the field, but this case is most likely a serious + * coding error in the ASL. + * + ******************************************************************************/ + +u8 +acpi_ex_register_overflow ( + union acpi_operand_object *obj_desc, + acpi_integer value) +{ + + if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) { + /* + * The field is large enough to hold the maximum integer, so we can + * never overflow it. + */ + return (FALSE); + } + + if (value >= ((acpi_integer) 1 << obj_desc->common_field.bit_length)) { + /* + * The Value is larger than the maximum value that can fit into + * the register. + */ + return (TRUE); + } + + /* The Value will fit into the field with no truncation */ + + return (FALSE); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ex_field_datum_io + * + * PARAMETERS: *obj_desc - Field to be read + * field_datum_byte_offset - Byte offset of this datum within the + * parent field + * *Value - Where to store value (must be 64 bits) + * read_write - Read or Write flag + * + * RETURN: Status + * + * DESCRIPTION: Read or Write a single datum of a field. The field_type is + * demultiplexed here to handle the different types of fields + * (buffer_field, region_field, index_field, bank_field) + * + ******************************************************************************/ + +acpi_status +acpi_ex_field_datum_io ( + union acpi_operand_object *obj_desc, + u32 field_datum_byte_offset, + acpi_integer *value, + u32 read_write) +{ + acpi_status status; + acpi_integer local_value; + + + ACPI_FUNCTION_TRACE_U32 ("ex_field_datum_io", field_datum_byte_offset); + + + if (read_write == ACPI_READ) { + if (!value) { + local_value = 0; + value = &local_value; /* To support reads without saving return value */ + } + + /* Clear the entire return buffer first, [Very Important!] */ + + *value = 0; + } /* - * Buffer_fields - Read from a Buffer - * Other Fields - Read from a Operation Region. + * The four types of fields are: + * + * buffer_fields - Read/write from/to a Buffer + * region_fields - Read/write from/to a Operation Region. + * bank_fields - Write to a Bank Register, then read/write from/to an op_region + * index_fields - Write to an Index Register, then read/write from/to a Data Register */ - switch (obj_desc->common.type) { + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_BUFFER_FIELD: - /* - * For Buffer_fields, we only need to copy the data from the - * source buffer. Length is the field width in bytes. + * If the buffer_field arguments have not been previously evaluated, + * evaluate them now and save the results. */ - MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer - + obj_desc->buffer_field.base_byte_offset + field_datum_byte_offset, - obj_desc->common_field.access_byte_width); + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_buffer_field_arguments (obj_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + if (read_write == ACPI_READ) { + /* + * Copy the data from the source buffer. + * Length is the field width in bytes. + */ + ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer + + obj_desc->buffer_field.base_byte_offset + + field_datum_byte_offset, + obj_desc->common_field.access_byte_width); + } + else { + /* + * Copy the data to the target buffer. + * Length is the field width in bytes. + */ + ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer + + obj_desc->buffer_field.base_byte_offset + + field_datum_byte_offset, + value, obj_desc->common_field.access_byte_width); + } + status = AE_OK; break; - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + + /* Ensure that the bank_value is not beyond the capacity of the register */ + + if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj, + (acpi_integer) obj_desc->bank_field.value)) { + return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); + } /* - * For other fields, we need to go through an Operation Region - * (Only types that will get here are Region_fields and Bank_fields) + * For bank_fields, we must write the bank_value to the bank_register + * (itself a region_field) before we can access the data. */ - status = acpi_ex_setup_field (obj_desc, field_datum_byte_offset); + status = acpi_ex_insert_into_field (obj_desc->bank_field.bank_obj, + &obj_desc->bank_field.value, + sizeof (obj_desc->bank_field.value)); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* - * The physical address of this field datum is: - * - * 1) The base of the region, plus - * 2) The base offset of the field, plus - * 3) The current offset into the field - */ - rgn_desc = obj_desc->common_field.region_obj; - address = rgn_desc->region.address + obj_desc->common_field.base_byte_offset + - field_datum_byte_offset; - - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Region %s(%X) width %X base:off %X:%X at %8.8X%8.8X\n", - acpi_ut_get_region_name (rgn_desc->region.space_id), - rgn_desc->region.space_id, obj_desc->common_field.access_bit_width, - obj_desc->common_field.base_byte_offset, field_datum_byte_offset, - HIDWORD(address), LODWORD(address))); + * Now that the Bank has been selected, fall through to the + * region_field case and write the datum to the Operation Region + */ - /* Invoke the appropriate Address_space/Op_region handler */ + /*lint -fallthrough */ - status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE, - address, obj_desc->common_field.access_bit_width, value); - if (status == AE_NOT_IMPLEMENTED) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %s(%X) not implemented\n", - acpi_ut_get_region_name (rgn_desc->region.space_id), - rgn_desc->region.space_id)); + + case ACPI_TYPE_LOCAL_REGION_FIELD: + /* + * For simple region_fields, we just directly access the owning + * Operation Region. + */ + status = acpi_ex_access_region (obj_desc, field_datum_byte_offset, value, + read_write); + break; + + + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + + /* Ensure that the index_value is not beyond the capacity of the register */ + + if (acpi_ex_register_overflow (obj_desc->index_field.index_obj, + (acpi_integer) obj_desc->index_field.value)) { + return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); } - else if (status == AE_NOT_EXIST) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %s(%X) has no handler\n", - acpi_ut_get_region_name (rgn_desc->region.space_id), - rgn_desc->region.space_id)); + /* Write the index value to the index_register (itself a region_field) */ + + status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj, + &obj_desc->index_field.value, + sizeof (obj_desc->index_field.value)); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + if (read_write == ACPI_READ) { + /* Read the datum from the data_register */ + + status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj, + value, obj_desc->common_field.access_byte_width); + } + else { + /* Write the datum to the Data register */ + + status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj, + value, obj_desc->common_field.access_byte_width); } break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p, wrong source type - %s\n", - obj_desc, acpi_ut_get_type_name (obj_desc->common.type))); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p, Wrong object type - %s\n", + obj_desc, acpi_ut_get_object_type_name (obj_desc))); status = AE_AML_INTERNAL; break; } + if (ACPI_SUCCESS (status)) { + if (read_write == ACPI_READ) { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read=%8.8X%8.8X\n", + ACPI_HIDWORD (*value), ACPI_LODWORD (*value))); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written=%8.8X%8.8X\n", + ACPI_HIDWORD (*value), ACPI_LODWORD (*value))); + } + } + + return_ACPI_STATUS (status); +} - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Returned value=%08X \n", *value)); + +/******************************************************************************* + * + * FUNCTION: acpi_ex_write_with_update_rule + * + * PARAMETERS: *obj_desc - Field to be set + * Value - Value to store + * + * RETURN: Status + * + * DESCRIPTION: Apply the field update rule to a field write + * + ******************************************************************************/ + +acpi_status +acpi_ex_write_with_update_rule ( + union acpi_operand_object *obj_desc, + acpi_integer mask, + acpi_integer field_value, + u32 field_datum_byte_offset) +{ + acpi_status status = AE_OK; + acpi_integer merged_value; + acpi_integer current_value; + + + ACPI_FUNCTION_TRACE_U32 ("ex_write_with_update_rule", mask); + + + /* Start with the new bits */ + + merged_value = field_value; + + /* If the mask is all ones, we don't need to worry about the update rule */ + + if (mask != ACPI_INTEGER_MAX) { + /* Decode the update rule */ + + switch (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK) { + case AML_FIELD_UPDATE_PRESERVE: + /* + * Check if update rule needs to be applied (not if mask is all + * ones) The left shift drops the bits we want to ignore. + */ + if ((~mask << (ACPI_MUL_8 (sizeof (mask)) - + ACPI_MUL_8 (obj_desc->common_field.access_byte_width))) != 0) { + /* + * Read the current contents of the byte/word/dword containing + * the field, and merge with the new field value. + */ + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + ¤t_value, ACPI_READ); + merged_value |= (current_value & ~mask); + } + break; + + case AML_FIELD_UPDATE_WRITE_AS_ONES: + + /* Set positions outside the field to all ones */ + + merged_value |= ~mask; + break; + + case AML_FIELD_UPDATE_WRITE_AS_ZEROS: + + /* Set positions outside the field to all zeros */ + + merged_value &= mask; + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "write_with_update_rule: Unknown update_rule setting: %X\n", + (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK))); + return_ACPI_STATUS (AE_AML_OPERAND_VALUE); + } + } + + /* Write the merged value */ + + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &merged_value, ACPI_WRITE); + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Mask %8.8X%8.8X datum_offset %X Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", + ACPI_HIDWORD (mask), ACPI_LODWORD (mask), + field_datum_byte_offset, + ACPI_HIDWORD (field_value), ACPI_LODWORD (field_value), + ACPI_HIDWORD (merged_value),ACPI_LODWORD (merged_value))); return_ACPI_STATUS (status); } @@ -238,43 +598,65 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_get_buffer_datum + * FUNCTION: acpi_ex_get_buffer_datum * - * PARAMETERS: Merged_datum - Value to store - * Buffer - Receiving buffer - * Byte_granularity - 1/2/4 Granularity of the field + * PARAMETERS: Datum - Where the Datum is returned + * Buffer - Raw field buffer + * buffer_length - Entire length (used for big-endian only) + * byte_granularity - 1/2/4/8 Granularity of the field * (aka Datum Size) - * Offset - Datum offset into the buffer + * buffer_offset - Datum offset into the buffer * * RETURN: none * - * DESCRIPTION: Store the merged datum to the buffer according to the + * DESCRIPTION: Get a datum from the buffer according to the buffer field * byte granularity * ******************************************************************************/ -static void -acpi_ex_get_buffer_datum( - u32 *datum, - void *buffer, - u32 byte_granularity, - u32 offset) +void +acpi_ex_get_buffer_datum ( + acpi_integer *datum, + void *buffer, + u32 buffer_length, + u32 byte_granularity, + u32 buffer_offset) { + u32 index; + + + ACPI_FUNCTION_ENTRY (); - FUNCTION_ENTRY (); + /* Get proper index into buffer (handles big/little endian) */ + + index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity); + + /* Move the requested number of bytes */ switch (byte_granularity) { case ACPI_FIELD_BYTE_GRANULARITY: - *datum = ((u8 *) buffer) [offset]; + + *datum = ((u8 *) buffer) [index]; break; case ACPI_FIELD_WORD_GRANULARITY: - MOVE_UNALIGNED16_TO_32 (datum, &(((u16 *) buffer) [offset])); + + ACPI_MOVE_16_TO_64 (datum, &(((u16 *) buffer) [index])); break; case ACPI_FIELD_DWORD_GRANULARITY: - MOVE_UNALIGNED32_TO_32 (datum, &(((u32 *) buffer) [offset])); + + ACPI_MOVE_32_TO_64 (datum, &(((u32 *) buffer) [index])); + break; + + case ACPI_FIELD_QWORD_GRANULARITY: + + ACPI_MOVE_64_TO_64 (datum, &(((u64 *) buffer) [index])); + break; + + default: + /* Should not get here */ break; } } @@ -282,13 +664,14 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_set_buffer_datum + * FUNCTION: acpi_ex_set_buffer_datum * - * PARAMETERS: Merged_datum - Value to store + * PARAMETERS: merged_datum - Value to store * Buffer - Receiving buffer - * Byte_granularity - 1/2/4 Granularity of the field + * buffer_length - Entire length (used for big-endian only) + * byte_granularity - 1/2/4/8 Granularity of the field * (aka Datum Size) - * Offset - Datum offset into the buffer + * buffer_offset - Datum offset into the buffer * * RETURN: none * @@ -297,28 +680,48 @@ * ******************************************************************************/ -static void +void acpi_ex_set_buffer_datum ( - u32 merged_datum, - void *buffer, - u32 byte_granularity, - u32 offset) + acpi_integer merged_datum, + void *buffer, + u32 buffer_length, + u32 byte_granularity, + u32 buffer_offset) { + u32 index; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); + /* Get proper index into buffer (handles big/little endian) */ + + index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity); + + /* Move the requested number of bytes */ + switch (byte_granularity) { case ACPI_FIELD_BYTE_GRANULARITY: - ((u8 *) buffer) [offset] = (u8) merged_datum; + + ((u8 *) buffer) [index] = (u8) merged_datum; break; case ACPI_FIELD_WORD_GRANULARITY: - MOVE_UNALIGNED16_TO_16 (&(((u16 *) buffer)[offset]), &merged_datum); + + ACPI_MOVE_64_TO_16 (&(((u16 *) buffer)[index]), &merged_datum); break; case ACPI_FIELD_DWORD_GRANULARITY: - MOVE_UNALIGNED32_TO_32 (&(((u32 *) buffer)[offset]), &merged_datum); + + ACPI_MOVE_64_TO_32 (&(((u32 *) buffer)[index]), &merged_datum); + break; + + case ACPI_FIELD_QWORD_GRANULARITY: + + ACPI_MOVE_64_TO_64 (&(((u64 *) buffer)[index]), &merged_datum); + break; + + default: + /* Should not get here */ break; } } @@ -326,9 +729,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_extract_from_field + * FUNCTION: acpi_ex_extract_from_field * - * PARAMETERS: *Obj_desc - Field to be read + * PARAMETERS: *obj_desc - Field to be read * *Value - Where to store value * * RETURN: Status @@ -339,29 +742,30 @@ acpi_status acpi_ex_extract_from_field ( - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) + union acpi_operand_object *obj_desc, + void *buffer, + u32 buffer_length) { - acpi_status status; - u32 field_datum_byte_offset; - u32 datum_offset; - u32 previous_raw_datum; - u32 this_raw_datum = 0; - u32 merged_datum = 0; - u32 byte_field_length; - u32 datum_count; + acpi_status status; + u32 field_datum_byte_offset; + u32 datum_offset; + acpi_integer previous_raw_datum; + acpi_integer this_raw_datum = 0; + acpi_integer merged_datum = 0; + u32 byte_field_length; + u32 datum_count; - FUNCTION_TRACE ("Ex_extract_from_field"); + ACPI_FUNCTION_TRACE ("ex_extract_from_field"); /* * The field must fit within the caller's buffer */ - byte_field_length = ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); if (byte_field_length > buffer_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Field size %X (bytes) too large for buffer (%X)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Field size %X (bytes) too large for buffer (%X)\n", byte_field_length, buffer_length)); return_ACPI_STATUS (AE_BUFFER_OVERFLOW); @@ -369,26 +773,27 @@ /* Convert field byte count to datum count, round up if necessary */ - datum_count = ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width); + datum_count = ACPI_ROUND_UP_TO (byte_field_length, + obj_desc->common_field.access_byte_width); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Byte_len=%x, Datum_len=%x, Bit_gran=%x, Byte_gran=%x\n", - byte_field_length, datum_count, obj_desc->common_field.access_bit_width, - obj_desc->common_field.access_byte_width)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "byte_len=%X, datum_len=%X, byte_gran=%X\n", + byte_field_length, datum_count,obj_desc->common_field.access_byte_width)); /* * Clear the caller's buffer (the whole buffer length as given) * This is very important, especially in the cases where a byte is read, * but the buffer is really a u32 (4 bytes). */ - MEMSET (buffer, 0, buffer_length); + ACPI_MEMSET (buffer, 0, buffer_length); /* Read the first raw datum to prime the loop */ field_datum_byte_offset = 0; datum_offset= 0; - status = acpi_ex_read_field_datum (obj_desc, field_datum_byte_offset, &previous_raw_datum); + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &previous_raw_datum, ACPI_READ); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -397,7 +802,7 @@ /* We might actually be done if the request fits in one datum */ if ((datum_count == 1) && - (obj_desc->common_field.access_flags & AFIELD_SINGLE_DATUM)) { + (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) { /* 1) Shift the valid data bits down to start at bit 0 */ merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset); @@ -405,13 +810,13 @@ /* 2) Mask off any upper unused bits (bits not part of the field) */ if (obj_desc->common_field.end_buffer_valid_bits) { - merged_datum &= MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); + merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); } /* Store the datum to the caller buffer */ - acpi_ex_set_buffer_datum (merged_datum, buffer, obj_desc->common_field.access_byte_width, - datum_offset); + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, datum_offset); return_ACPI_STATUS (AE_OK); } @@ -427,17 +832,18 @@ * to perform a final read, since this would potentially read * past the end of the region. * - * TBD: [Investigate] It may make more sense to just split the aligned - * and non-aligned cases since the aligned case is so very simple, + * We could just split the aligned and non-aligned cases since the + * aligned case is so very simple, but this would require more code. */ - if ((obj_desc->common_field.start_field_bit_offset != 0) || + if ((obj_desc->common_field.start_field_bit_offset != 0) || ((obj_desc->common_field.start_field_bit_offset == 0) && (datum_offset < (datum_count -1)))) { /* * Get the next raw datum, it contains some or all bits * of the current field datum */ - status = acpi_ex_read_field_datum (obj_desc, field_datum_byte_offset, &this_raw_datum); + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &this_raw_datum, ACPI_READ); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -451,7 +857,6 @@ merged_datum = previous_raw_datum; } - else { /* * Put together the appropriate bits of the two raw data to make a @@ -474,7 +879,7 @@ */ if (obj_desc->common_field.end_buffer_valid_bits) { merged_datum &= - MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); + ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); } } } @@ -483,8 +888,8 @@ * Store the merged field datum in the caller's buffer, according to * the granularity of the field (size of each datum). */ - acpi_ex_set_buffer_datum (merged_datum, buffer, obj_desc->common_field.access_byte_width, - datum_offset); + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, datum_offset); /* * Save the raw datum that was just acquired since it may contain bits @@ -500,214 +905,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_write_field_datum + * FUNCTION: acpi_ex_insert_into_field * - * PARAMETERS: *Obj_desc - Field to be set - * Value - Value to store - * - * RETURN: Status - * - * DESCRIPTION: Store the value into the given field - * - ******************************************************************************/ - -static acpi_status -acpi_ex_write_field_datum ( - acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - u32 value) -{ - acpi_status status = AE_OK; - acpi_operand_object *rgn_desc = NULL; - ACPI_PHYSICAL_ADDRESS address; - - - FUNCTION_TRACE_U32 ("Ex_write_field_datum", field_datum_byte_offset); - - - /* - * Buffer_fields - Read from a Buffer - * Other Fields - Read from a Operation Region. - */ - switch (obj_desc->common.type) { - case ACPI_TYPE_BUFFER_FIELD: - - /* - * For Buffer_fields, we only need to copy the data to the - * target buffer. Length is the field width in bytes. - */ - MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer - + obj_desc->buffer_field.base_byte_offset + field_datum_byte_offset, - &value, obj_desc->common_field.access_byte_width); - status = AE_OK; - break; - - - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - - /* - * For other fields, we need to go through an Operation Region - * (Only types that will get here are Region_fields and Bank_fields) - */ - status = acpi_ex_setup_field (obj_desc, field_datum_byte_offset); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* - * The physical address of this field datum is: - * - * 1) The base of the region, plus - * 2) The base offset of the field, plus - * 3) The current offset into the field - */ - rgn_desc = obj_desc->common_field.region_obj; - address = rgn_desc->region.address + - obj_desc->common_field.base_byte_offset + - field_datum_byte_offset; - - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Store %X in Region %s(%X) at %8.8X%8.8X width %X\n", - value, acpi_ut_get_region_name (rgn_desc->region.space_id), - rgn_desc->region.space_id, HIDWORD(address), LODWORD(address), - obj_desc->common_field.access_bit_width)); - - /* Invoke the appropriate Address_space/Op_region handler */ - - status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_WRITE_ADR_SPACE, - address, obj_desc->common_field.access_bit_width, &value); - - if (status == AE_NOT_IMPLEMENTED) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "**** Region type %s(%X) not implemented\n", - acpi_ut_get_region_name (rgn_desc->region.space_id), - rgn_desc->region.space_id)); - } - - else if (status == AE_NOT_EXIST) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "**** Region type %s(%X) does not have a handler\n", - acpi_ut_get_region_name (rgn_desc->region.space_id), - rgn_desc->region.space_id)); - } - - break; - - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p, wrong source type - %s\n", - obj_desc, acpi_ut_get_type_name (obj_desc->common.type))); - status = AE_AML_INTERNAL; - break; - } - - - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value written=%08X \n", value)); - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_write_field_datum_with_update_rule - * - * PARAMETERS: *Obj_desc - Field to be set - * Value - Value to store - * - * RETURN: Status - * - * DESCRIPTION: Apply the field update rule to a field write - * - ******************************************************************************/ - -static acpi_status -acpi_ex_write_field_datum_with_update_rule ( - acpi_operand_object *obj_desc, - u32 mask, - u32 field_value, - u32 field_datum_byte_offset) -{ - acpi_status status = AE_OK; - u32 merged_value; - u32 current_value; - - - FUNCTION_TRACE ("Ex_write_field_datum_with_update_rule"); - - - /* Start with the new bits */ - - merged_value = field_value; - - /* If the mask is all ones, we don't need to worry about the update rule */ - - if (mask != ACPI_UINT32_MAX) { - /* Decode the update rule */ - - switch (obj_desc->common_field.update_rule) { - case UPDATE_PRESERVE: - /* - * Check if update rule needs to be applied (not if mask is all - * ones) The left shift drops the bits we want to ignore. - */ - if ((~mask << (sizeof (mask) * 8 - - obj_desc->common_field.access_bit_width)) != 0) { - /* - * Read the current contents of the byte/word/dword containing - * the field, and merge with the new field value. - */ - status = acpi_ex_read_field_datum (obj_desc, field_datum_byte_offset, - ¤t_value); - merged_value |= (current_value & ~mask); - } - break; - - - case UPDATE_WRITE_AS_ONES: - - /* Set positions outside the field to all ones */ - - merged_value |= ~mask; - break; - - - case UPDATE_WRITE_AS_ZEROS: - - /* Set positions outside the field to all zeros */ - - merged_value &= mask; - break; - - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Write_with_update_rule: Unknown Update_rule setting: %x\n", - obj_desc->common_field.update_rule)); - return_ACPI_STATUS (AE_AML_OPERAND_VALUE); - break; - } - } - - - /* Write the merged value */ - - status = acpi_ex_write_field_datum (obj_desc, field_datum_byte_offset, - merged_value); - - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Mask %X Datum_offset %X Value %X, Merged_value %X\n", - mask, field_datum_byte_offset, field_value, merged_value)); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_insert_into_field - * - * PARAMETERS: *Obj_desc - Field to be set + * PARAMETERS: *obj_desc - Field to be set * Buffer - Value to store * * RETURN: Status @@ -718,22 +918,22 @@ acpi_status acpi_ex_insert_into_field ( - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length) + union acpi_operand_object *obj_desc, + void *buffer, + u32 buffer_length) { - acpi_status status; - u32 field_datum_byte_offset; - u32 datum_offset; - u32 mask; - u32 merged_datum; - u32 previous_raw_datum; - u32 this_raw_datum; - u32 byte_field_length; - u32 datum_count; + acpi_status status; + u32 field_datum_byte_offset; + u32 datum_offset; + acpi_integer mask; + acpi_integer merged_datum; + acpi_integer previous_raw_datum; + acpi_integer this_raw_datum; + u32 byte_field_length; + u32 datum_count; - FUNCTION_TRACE ("Ex_insert_into_field"); + ACPI_FUNCTION_TRACE ("ex_insert_into_field"); /* @@ -742,24 +942,21 @@ * larger than the field, this typically happens when an integer is * written to a field that is actually smaller than an integer. */ - byte_field_length = ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); if (buffer_length < byte_field_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Buffer length %X too small for field %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Buffer length %X too small for field %X\n", buffer_length, byte_field_length)); - /* TBD: Need a better error code */ - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); } /* Convert byte count to datum count, round up if necessary */ - datum_count = ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width); + datum_count = ACPI_ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Byte_len=%x, Datum_len=%x, Bit_gran=%x, Byte_gran=%x\n", - byte_field_length, datum_count, obj_desc->common_field.access_bit_width, - obj_desc->common_field.access_byte_width)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "byte_len=%X, datum_len=%X, byte_gran=%X\n", + byte_field_length, datum_count, obj_desc->common_field.access_byte_width)); /* * Break the request into up to three parts (similar to an I/O request): @@ -772,7 +969,7 @@ /* Get a single datum from the caller's buffer */ - acpi_ex_get_buffer_datum (&previous_raw_datum, buffer, + acpi_ex_get_buffer_datum (&previous_raw_datum, buffer, buffer_length, obj_desc->common_field.access_byte_width, datum_offset); /* @@ -781,19 +978,19 @@ * Note: The code in this section also handles the aligned case * * Construct Mask with 1 bits where the field is, 0 bits elsewhere - * (Only the bottom 5 bits of Bit_length are valid for a shift operation) + * (Only the bottom 5 bits of bit_length are valid for a shift operation) * * Mask off bits that are "below" the field (if any) */ - mask = MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset); + mask = ACPI_MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset); /* If the field fits in one datum, may need to mask upper bits */ - if ((obj_desc->common_field.access_flags & AFIELD_SINGLE_DATUM) && + if ((obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM) && obj_desc->common_field.end_field_valid_bits) { /* There are bits above the field, mask them off also */ - mask &= MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); + mask &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); } /* Shift and mask the value into the field position */ @@ -803,7 +1000,7 @@ /* Apply the update rule (if necessary) and write the datum to the field */ - status = acpi_ex_write_field_datum_with_update_rule (obj_desc, mask, merged_datum, + status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_datum_byte_offset); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); @@ -812,7 +1009,7 @@ /* If the entire field fits within one datum, we are done. */ if ((datum_count == 1) && - (obj_desc->common_field.access_flags & AFIELD_SINGLE_DATUM)) { + (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) { return_ACPI_STATUS (AE_OK); } @@ -835,7 +1032,7 @@ * Get the next raw buffer datum. It may contain bits of the previous * field datum */ - acpi_ex_get_buffer_datum (&this_raw_datum, buffer, + acpi_ex_get_buffer_datum (&this_raw_datum, buffer, buffer_length, obj_desc->common_field.access_byte_width, datum_offset); /* Create the field datum based on the field alignment */ @@ -849,7 +1046,6 @@ (previous_raw_datum >> obj_desc->common_field.datum_valid_bits) | (this_raw_datum << obj_desc->common_field.start_field_bit_offset); } - else { /* Field began aligned on datum boundary */ @@ -874,24 +1070,23 @@ * * Mask off the unused bits above (after) the end-of-field */ - mask = MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); + mask = ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); merged_datum &= mask; /* Write the last datum with the update rule */ - status = acpi_ex_write_field_datum_with_update_rule (obj_desc, mask, - merged_datum, field_datum_byte_offset); + status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, + field_datum_byte_offset); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } } - else { /* Normal case -- write the completed datum */ - status = acpi_ex_write_field_datum (obj_desc, - field_datum_byte_offset, merged_datum); + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &merged_datum, ACPI_WRITE); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/executer/exmisc.c linux-2.4.22/drivers/acpi/executer/exmisc.c --- linux-2.4.21/drivers/acpi/executer/exmisc.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exmisc.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,122 +2,229 @@ /****************************************************************************** * * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes - * $Revision: 92 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acdispat.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exmisc") + ACPI_MODULE_NAME ("exmisc") /******************************************************************************* * - * FUNCTION: Acpi_ex_get_object_reference + * FUNCTION: acpi_ex_get_object_reference * - * PARAMETERS: Obj_desc - Create a reference to this object - * Return_desc - Where to store the reference + * PARAMETERS: obj_desc - Create a reference to this object + * return_desc - Where to store the reference + * walk_state - Current state * * RETURN: Status * * DESCRIPTION: Obtain and return a "reference" to the target object - * Common code for the Ref_of_op and the Cond_ref_of_op. + * Common code for the ref_of_op and the cond_ref_of_op. * ******************************************************************************/ acpi_status acpi_ex_get_object_reference ( - acpi_operand_object *obj_desc, - acpi_operand_object **return_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *obj_desc, + union acpi_operand_object **return_desc, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; + union acpi_operand_object *reference_obj; + union acpi_operand_object *referenced_obj; - FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc); + ACPI_FUNCTION_TRACE_PTR ("ex_get_object_reference", obj_desc); - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { - if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) { - *return_desc = NULL; - status = AE_TYPE; - goto cleanup; + *return_desc = NULL; + + switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) { + case ACPI_DESC_TYPE_OPERAND: + + if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) { + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* - * Not a Name -- an indirect name pointer would have - * been converted to a direct name pointer in Acpi_ex_resolve_operands + * Must be a reference to a Local or Arg */ switch (obj_desc->reference.opcode) { case AML_LOCAL_OP: case AML_ARG_OP: - *return_desc = (void *) acpi_ds_method_data_get_node (obj_desc->reference.opcode, - obj_desc->reference.offset, walk_state); + /* The referenced object is the pseudo-node for the local/arg */ + + referenced_obj = obj_desc->reference.object; break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference subtype %X\n", obj_desc->reference.opcode)); - *return_desc = NULL; - status = AE_AML_INTERNAL; - goto cleanup; + return_ACPI_STATUS (AE_AML_INTERNAL); } + break; - } - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - /* Must be a named object; Just return the Node */ + case ACPI_DESC_TYPE_NAMED: - *return_desc = obj_desc; + /* + * A named reference that has already been resolved to a Node + */ + referenced_obj = obj_desc; + break; + + + default: + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type %X in %p\n", + ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc)); + return_ACPI_STATUS (AE_TYPE); } - else { - *return_desc = NULL; - status = AE_TYPE; + + /* Create a new reference object */ + + reference_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE); + if (!reference_obj) { + return_ACPI_STATUS (AE_NO_MEMORY); } + reference_obj->reference.opcode = AML_REF_OF_OP; + reference_obj->reference.object = referenced_obj; + *return_desc = reference_obj; -cleanup: + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n", + obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc)); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *return_desc)); - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_do_concatenate + * FUNCTION: acpi_ex_concat_template * - * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * PARAMETERS: *obj_desc - Object to be converted. Must be an * Integer, Buffer, or String - * Walk_state - Current walk state + * walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Concatenate two resource templates + * + ******************************************************************************/ + +acpi_status +acpi_ex_concat_template ( + union acpi_operand_object *obj_desc1, + union acpi_operand_object *obj_desc2, + union acpi_operand_object **actual_return_desc, + struct acpi_walk_state *walk_state) +{ + union acpi_operand_object *return_desc; + u8 *new_buf; + u8 *end_tag1; + u8 *end_tag2; + acpi_size length1; + acpi_size length2; + + + ACPI_FUNCTION_TRACE ("ex_concat_template"); + + + /* Find the end_tags in each resource template */ + + end_tag1 = acpi_ut_get_resource_end_tag (obj_desc1); + end_tag2 = acpi_ut_get_resource_end_tag (obj_desc2); + if (!end_tag1 || !end_tag2) { + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + } + + /* Compute the length of each part */ + + length1 = ACPI_PTR_DIFF (end_tag1, obj_desc1->buffer.pointer); + length2 = ACPI_PTR_DIFF (end_tag2, obj_desc2->buffer.pointer) + + 2; /* Size of END_TAG */ + + /* Create a new buffer object for the result */ + + return_desc = acpi_ut_create_buffer_object (length1 + length2); + if (!return_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Copy the templates to the new descriptor */ + + new_buf = return_desc->buffer.pointer; + ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, length1); + ACPI_MEMCPY (new_buf + length1, obj_desc2->buffer.pointer, length2); + + /* Compute the new checksum */ + + new_buf[return_desc->buffer.length - 1] = + acpi_ut_generate_checksum (return_desc->buffer.pointer, + (return_desc->buffer.length - 1)); + + /* Return the completed template descriptor */ + + *actual_return_desc = return_desc; + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ex_do_concatenate + * + * PARAMETERS: obj_desc1 - First source object + * obj_desc2 - Second source object + * actual_return_desc - Where to place the return object + * walk_state - Current walk state * * RETURN: Status * @@ -127,75 +234,54 @@ acpi_status acpi_ex_do_concatenate ( - acpi_operand_object *obj_desc, - acpi_operand_object *obj_desc2, - acpi_operand_object **actual_return_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *obj_desc1, + union acpi_operand_object *obj_desc2, + union acpi_operand_object **actual_return_desc, + struct acpi_walk_state *walk_state) { - acpi_status status; - u32 i; - acpi_integer this_integer; - acpi_operand_object *return_desc; - NATIVE_CHAR *new_buf; - u32 integer_size = sizeof (acpi_integer); + acpi_status status; + u32 i; + acpi_integer this_integer; + union acpi_operand_object *return_desc; + char *new_buf; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* * There are three cases to handle: - * 1) Two Integers concatenated to produce a buffer - * 2) Two Strings concatenated to produce a string - * 3) Two Buffers concatenated to produce a buffer + * + * 1) Two Integers concatenated to produce a new Buffer + * 2) Two Strings concatenated to produce a new String + * 3) Two Buffers concatenated to produce a new Buffer */ - switch (obj_desc->common.type) { + switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) { case ACPI_TYPE_INTEGER: - /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ - - if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { - /* - * We are running a method that exists in a 32-bit ACPI table. - * Truncate the value to 32 bits by zeroing out the upper - * 32-bit field - */ - integer_size = sizeof (u32); - } - - /* Result of two integers is a buffer */ + /* Result of two Integers is a Buffer */ + /* Need enough buffer space for two integers */ - return_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width * 2); if (!return_desc) { return (AE_NO_MEMORY); } - /* Need enough space for two integers */ - - return_desc->buffer.length = integer_size * 2; - new_buf = ACPI_MEM_CALLOCATE (return_desc->buffer.length); - if (!new_buf) { - REPORT_ERROR - (("Ex_do_concatenate: Buffer allocation failure\n")); - status = AE_NO_MEMORY; - goto cleanup; - } - - return_desc->buffer.pointer = (u8 *) new_buf; + new_buf = (char *) return_desc->buffer.pointer; /* Convert the first integer */ - this_integer = obj_desc->integer.value; - for (i = 0; i < integer_size; i++) { - new_buf[i] = (u8) this_integer; + this_integer = obj_desc1->integer.value; + for (i = 0; i < acpi_gbl_integer_byte_width; i++) { + new_buf[i] = (char) this_integer; this_integer >>= 8; } /* Convert the second integer */ this_integer = obj_desc2->integer.value; - for (; i < (integer_size * 2); i++) { - new_buf[i] = (u8) this_integer; + for (; i < (ACPI_MUL_2 (acpi_gbl_integer_byte_width)); i++) { + new_buf[i] = (char) this_integer; this_integer >>= 8; } @@ -204,6 +290,8 @@ case ACPI_TYPE_STRING: + /* Result of two Strings is a String */ + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); if (!return_desc) { return (AE_NO_MEMORY); @@ -211,66 +299,60 @@ /* Operand0 is string */ - new_buf = ACPI_MEM_ALLOCATE (obj_desc->string.length + - obj_desc2->string.length + 1); + new_buf = ACPI_MEM_CALLOCATE ((acpi_size) obj_desc1->string.length + + (acpi_size) obj_desc2->string.length + 1); if (!new_buf) { - REPORT_ERROR - (("Ex_do_concatenate: String allocation failure\n")); + ACPI_REPORT_ERROR + (("ex_do_concatenate: String allocation failure\n")); status = AE_NO_MEMORY; goto cleanup; } - STRCPY (new_buf, obj_desc->string.pointer); - STRCPY (new_buf + obj_desc->string.length, + /* Concatenate the strings */ + + ACPI_STRCPY (new_buf, obj_desc1->string.pointer); + ACPI_STRCPY (new_buf + obj_desc1->string.length, obj_desc2->string.pointer); - /* Point the return object to the new string */ + /* Complete the String object initialization */ return_desc->string.pointer = new_buf; - return_desc->string.length = obj_desc->string.length += - obj_desc2->string.length; + return_desc->string.length = obj_desc1->string.length + + obj_desc2->string.length; break; case ACPI_TYPE_BUFFER: - /* Operand0 is a buffer */ + /* Result of two Buffers is a Buffer */ - return_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + return_desc = acpi_ut_create_buffer_object ( + (acpi_size) obj_desc1->buffer.length + + (acpi_size) obj_desc2->buffer.length); if (!return_desc) { return (AE_NO_MEMORY); } - new_buf = ACPI_MEM_ALLOCATE (obj_desc->buffer.length + - obj_desc2->buffer.length); - if (!new_buf) { - REPORT_ERROR - (("Ex_do_concatenate: Buffer allocation failure\n")); - status = AE_NO_MEMORY; - goto cleanup; - } + new_buf = (char *) return_desc->buffer.pointer; - MEMCPY (new_buf, obj_desc->buffer.pointer, - obj_desc->buffer.length); - MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer, - obj_desc2->buffer.length); + /* Concatenate the buffers */ - /* - * Point the return object to the new buffer - */ + ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, + obj_desc1->buffer.length); + ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer, + obj_desc2->buffer.length); - return_desc->buffer.pointer = (u8 *) new_buf; - return_desc->buffer.length = obj_desc->buffer.length + - obj_desc2->buffer.length; break; default: + + /* Invalid object type, should not happen here */ + status = AE_AML_INTERNAL; return_desc = NULL; } - *actual_return_desc = return_desc; return (AE_OK); @@ -284,11 +366,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_do_math_op + * FUNCTION: acpi_ex_do_math_op * * PARAMETERS: Opcode - AML opcode * Operand0 - Integer operand #0 - * Operand0 - Integer operand #1 + * Operand1 - Integer operand #1 * * RETURN: Integer result of the operation * @@ -300,9 +382,9 @@ acpi_integer acpi_ex_do_math_op ( - u16 opcode, - acpi_integer operand0, - acpi_integer operand1) + u16 opcode, + acpi_integer operand0, + acpi_integer operand1) { @@ -342,12 +424,12 @@ return (operand0 * operand1); - case AML_SHIFT_LEFT_OP: /* Shift_left (Operand, Shift_count, Result) */ + case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */ return (operand0 << operand1); - case AML_SHIFT_RIGHT_OP: /* Shift_right (Operand, Shift_count, Result) */ + case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */ return (operand0 >> operand1); @@ -365,11 +447,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_do_logical_op + * FUNCTION: acpi_ex_do_logical_op * * PARAMETERS: Opcode - AML opcode * Operand0 - Integer operand #0 - * Operand0 - Integer operand #1 + * Operand1 - Integer operand #1 * * RETURN: TRUE/FALSE result of the operation * @@ -386,9 +468,9 @@ u8 acpi_ex_do_logical_op ( - u16 opcode, - acpi_integer operand0, - acpi_integer operand1) + u16 opcode, + acpi_integer operand0, + acpi_integer operand1) { @@ -432,6 +514,9 @@ return (TRUE); } break; + + default: + break; } return (FALSE); diff -urN linux-2.4.21/drivers/acpi/executer/exmutex.c linux-2.4.22/drivers/acpi/executer/exmutex.c --- linux-2.4.21/drivers/acpi/executer/exmutex.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exmutex.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,107 +2,136 @@ /****************************************************************************** * * Module Name: exmutex - ASL Mutex Acquire/Release functions - * $Revision: 7 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "achware.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exmutex") + ACPI_MODULE_NAME ("exmutex") /******************************************************************************* * - * FUNCTION: Acpi_ex_unlink_mutex + * FUNCTION: acpi_ex_unlink_mutex * - * PARAMETERS: *Obj_desc - The mutex to be unlinked + * PARAMETERS: *obj_desc - The mutex to be unlinked * * RETURN: Status * - * DESCRIPTION: Remove a mutex from the "Acquired_mutex" list + * DESCRIPTION: Remove a mutex from the "acquired_mutex" list * ******************************************************************************/ void acpi_ex_unlink_mutex ( - acpi_operand_object *obj_desc) + union acpi_operand_object *obj_desc) { + struct acpi_thread_state *thread = obj_desc->mutex.owner_thread; + + + if (!thread) { + return; + } if (obj_desc->mutex.next) { (obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev; } + if (obj_desc->mutex.prev) { (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; } + else { + thread->acquired_mutex_list = obj_desc->mutex.next; + } } /******************************************************************************* * - * FUNCTION: Acpi_ex_link_mutex + * FUNCTION: acpi_ex_link_mutex * - * PARAMETERS: *Obj_desc - The mutex to be linked - * *List_head - head of the "Acquired_mutex" list + * PARAMETERS: *obj_desc - The mutex to be linked + * *list_head - head of the "acquired_mutex" list * * RETURN: Status * - * DESCRIPTION: Add a mutex to the "Acquired_mutex" list for this walk + * DESCRIPTION: Add a mutex to the "acquired_mutex" list for this walk * ******************************************************************************/ void acpi_ex_link_mutex ( - acpi_operand_object *obj_desc, - acpi_operand_object *list_head) + union acpi_operand_object *obj_desc, + struct acpi_thread_state *thread) { + union acpi_operand_object *list_head; + + + list_head = thread->acquired_mutex_list; /* This object will be the first object in the list */ - obj_desc->mutex.prev = list_head; - obj_desc->mutex.next = list_head->mutex.next; + obj_desc->mutex.prev = NULL; + obj_desc->mutex.next = list_head; /* Update old first object to point back to this object */ - if (list_head->mutex.next) { - (list_head->mutex.next)->mutex.prev = obj_desc; + if (list_head) { + list_head->mutex.prev = obj_desc; } /* Update list head */ - list_head->mutex.next = obj_desc; + thread->acquired_mutex_list = obj_desc; } /******************************************************************************* * - * FUNCTION: Acpi_ex_acquire_mutex + * FUNCTION: acpi_ex_acquire_mutex * - * PARAMETERS: *Time_desc - The 'time to delay' object descriptor - * *Obj_desc - The object descriptor for this op + * PARAMETERS: *time_desc - The 'time to delay' object descriptor + * *obj_desc - The object descriptor for this op * * RETURN: Status * @@ -112,32 +141,48 @@ acpi_status acpi_ex_acquire_mutex ( - acpi_operand_object *time_desc, - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *time_desc, + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state) { - acpi_status status; + acpi_status status; + + ACPI_FUNCTION_TRACE_PTR ("ex_acquire_mutex", obj_desc); - FUNCTION_TRACE_PTR ("Ex_acquire_mutex", obj_desc); if (!obj_desc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + /* Sanity check -- we must have a valid thread ID */ + + if (!walk_state->thread) { + ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n", + obj_desc->mutex.node->name.ascii)); + return_ACPI_STATUS (AE_AML_INTERNAL); + } + /* * Current Sync must be less than or equal to the sync level of the * mutex. This mechanism provides some deadlock prevention */ - if (walk_state->current_sync_level > obj_desc->mutex.sync_level) { + if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { + ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n", + obj_desc->mutex.node->name.ascii)); return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } /* - * If the mutex is already owned by this thread, - * just increment the acquisition depth + * Support for multiple acquires by the owning thread */ - if (obj_desc->mutex.owner == walk_state) { + + if ((obj_desc->mutex.owner_thread) && + (obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id)) { + /* + * The mutex is already owned by this thread, + * just increment the acquisition depth + */ obj_desc->mutex.acquisition_depth++; return_ACPI_STATUS (AE_OK); } @@ -146,21 +191,21 @@ status = acpi_ex_system_acquire_mutex (time_desc, obj_desc); if (ACPI_FAILURE (status)) { - /* Includes failure from a timeout on Time_desc */ + /* Includes failure from a timeout on time_desc */ return_ACPI_STATUS (status); } /* Have the mutex, update mutex and walk info */ - obj_desc->mutex.owner = walk_state; + obj_desc->mutex.owner_thread = walk_state->thread; obj_desc->mutex.acquisition_depth = 1; - walk_state->current_sync_level = obj_desc->mutex.sync_level; - /* Link the mutex to the walk state for force-unlock at method exit */ + walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; - acpi_ex_link_mutex (obj_desc, (acpi_operand_object *) - &(walk_state->walk_list->acquired_mutex_list)); + /* Link the mutex to the current thread for force-unlock at method exit */ + + acpi_ex_link_mutex (obj_desc, walk_state->thread); return_ACPI_STATUS (AE_OK); } @@ -168,9 +213,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_release_mutex + * FUNCTION: acpi_ex_release_mutex * - * PARAMETERS: *Obj_desc - The object descriptor for this op + * PARAMETERS: *obj_desc - The object descriptor for this op * * RETURN: Status * @@ -180,13 +225,13 @@ acpi_status acpi_ex_release_mutex ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Ex_release_mutex"); + ACPI_FUNCTION_TRACE ("ex_release_mutex"); if (!obj_desc) { @@ -195,13 +240,28 @@ /* The mutex must have been previously acquired in order to release it */ - if (!obj_desc->mutex.owner) { + if (!obj_desc->mutex.owner_thread) { + ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], not acquired\n", + obj_desc->mutex.node->name.ascii)); return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED); } + /* Sanity check -- we must have a valid thread ID */ + + if (!walk_state->thread) { + ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], null thread info\n", + obj_desc->mutex.node->name.ascii)); + return_ACPI_STATUS (AE_AML_INTERNAL); + } + /* The Mutex is owned, but this thread must be the owner */ - if (obj_desc->mutex.owner != walk_state) { + if (obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) { + ACPI_REPORT_ERROR (( + "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", + walk_state->thread->thread_id, + obj_desc->mutex.node->name.ascii, + obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS (AE_AML_NOT_OWNER); } @@ -209,7 +269,9 @@ * The sync level of the mutex must be less than or * equal to the current sync level */ - if (obj_desc->mutex.sync_level > walk_state->current_sync_level) { + if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { + ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n", + obj_desc->mutex.node->name.ascii)); return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } @@ -223,6 +285,9 @@ return_ACPI_STATUS (AE_OK); } + /* Unlink the mutex from the owner's list */ + + acpi_ex_unlink_mutex (obj_desc); /* Release the mutex */ @@ -230,12 +295,8 @@ /* Update the mutex and walk state */ - obj_desc->mutex.owner = NULL; - walk_state->current_sync_level = obj_desc->mutex.sync_level; - - /* Unlink the mutex from the owner's list */ - - acpi_ex_unlink_mutex (obj_desc); + obj_desc->mutex.owner_thread = NULL; + walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; return_ACPI_STATUS (status); } @@ -243,9 +304,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_release_all_mutexes + * FUNCTION: acpi_ex_release_all_mutexes * - * PARAMETERS: *Mutex_list - Head of the mutex list + * PARAMETERS: *mutex_list - Head of the mutex list * * RETURN: Status * @@ -253,15 +314,16 @@ * ******************************************************************************/ -acpi_status +void acpi_ex_release_all_mutexes ( - acpi_operand_object *list_head) + struct acpi_thread_state *thread) { - acpi_operand_object *next = list_head->mutex.next; - acpi_operand_object *this; + union acpi_operand_object *next = thread->acquired_mutex_list; + union acpi_operand_object *this; + acpi_status status; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* @@ -271,19 +333,21 @@ this = next; next = this->mutex.next; - /* Mark mutex un-owned */ - - this->mutex.owner = NULL; - this->mutex.prev = NULL; - this->mutex.next = NULL; - this->mutex.acquisition_depth = 0; + this->mutex.acquisition_depth = 1; + this->mutex.prev = NULL; + this->mutex.next = NULL; /* Release the mutex */ - acpi_ex_system_release_mutex (this); - } + status = acpi_ex_system_release_mutex (this); + if (ACPI_FAILURE (status)) { + continue; + } + + /* Mark mutex unowned */ - return (AE_OK); + this->mutex.owner_thread = NULL; + } } diff -urN linux-2.4.21/drivers/acpi/executer/exnames.c linux-2.4.22/drivers/acpi/executer/exnames.c --- linux-2.4.21/drivers/acpi/executer/exnames.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exnames.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,36 +2,53 @@ /****************************************************************************** * * Module Name: exnames - interpreter/scanner name load/execute - * $Revision: 83 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exnames") + ACPI_MODULE_NAME ("exnames") /* AML Package Length encodings */ @@ -44,11 +61,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_allocate_name_string + * FUNCTION: acpi_ex_allocate_name_string * - * PARAMETERS: Prefix_count - Count of parent levels. Special cases: + * PARAMETERS: prefix_count - Count of parent levels. Special cases: * (-1) = root, 0 = none - * Num_name_segs - count of 4-character name segments + * num_name_segs - count of 4-character name segments * * RETURN: A pointer to the allocated string segment. This segment must * be deleted by the caller. @@ -58,24 +75,24 @@ * ******************************************************************************/ -NATIVE_CHAR * +char * acpi_ex_allocate_name_string ( - u32 prefix_count, - u32 num_name_segs) + u32 prefix_count, + u32 num_name_segs) { - NATIVE_CHAR *temp_ptr; - NATIVE_CHAR *name_string; - u32 size_needed; + char *temp_ptr; + char *name_string; + u32 size_needed; - FUNCTION_TRACE ("Ex_allocate_name_string"); + ACPI_FUNCTION_TRACE ("ex_allocate_name_string"); /* - * Allow room for all \ and ^ prefixes, all segments, and a Multi_name_prefix. + * Allow room for all \ and ^ prefixes, all segments, and a multi_name_prefix. * Also, one byte for the null terminator. * This may actually be somewhat longer than needed. */ - if (prefix_count == (u32) -1) { + if (prefix_count == ACPI_UINT32_MAX) { /* Special case for root */ size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1; @@ -90,7 +107,7 @@ */ name_string = ACPI_MEM_ALLOCATE (size_needed); if (!name_string) { - REPORT_ERROR (("Ex_allocate_name_string: Could not allocate size %d\n", size_needed)); + ACPI_REPORT_ERROR (("ex_allocate_name_string: Could not allocate size %d\n", size_needed)); return_PTR (NULL); } @@ -98,10 +115,9 @@ /* Set up Root or Parent prefixes if needed */ - if (prefix_count == (u32) -1) { + if (prefix_count == ACPI_UINT32_MAX) { *temp_ptr++ = AML_ROOT_PREFIX; } - else { while (prefix_count--) { *temp_ptr++ = AML_PARENT_PREFIX; @@ -117,7 +133,6 @@ *temp_ptr++ = AML_MULTI_NAME_PREFIX_OP; *temp_ptr++ = (char) num_name_segs; } - else if (2 == num_name_segs) { /* Set up dual prefixes */ @@ -125,7 +140,7 @@ } /* - * Terminate string following prefixes. Acpi_ex_name_segment() will + * Terminate string following prefixes. acpi_ex_name_segment() will * append the segment(s) */ *temp_ptr = 0; @@ -135,9 +150,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_name_segment + * FUNCTION: acpi_ex_name_segment * - * PARAMETERS: Interpreter_mode - Current running mode (load1/Load2/Exec) + * PARAMETERS: interpreter_mode - Current running mode (load1/Load2/Exec) * * RETURN: Status * @@ -147,16 +162,16 @@ acpi_status acpi_ex_name_segment ( - u8 **in_aml_address, - NATIVE_CHAR *name_string) + u8 **in_aml_address, + char *name_string) { - u8 *aml_address = *in_aml_address; - acpi_status status = AE_OK; - u32 index; - NATIVE_CHAR char_buf[5]; + char *aml_address = (void *) *in_aml_address; + acpi_status status = AE_OK; + u32 index; + char char_buf[5]; - FUNCTION_TRACE ("Ex_name_segment"); + ACPI_FUNCTION_TRACE ("ex_name_segment"); /* @@ -172,34 +187,32 @@ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n")); - for (index = 4; - (index > 0) && (acpi_ut_valid_acpi_character (*aml_address)); - --index) { - char_buf[4 - index] = *aml_address++; - ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", char_buf[4 - index])); + for (index = 0; + (index < ACPI_NAME_SIZE) && (acpi_ut_valid_acpi_character (*aml_address)); + index++) { + char_buf[index] = *aml_address++; + ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", char_buf[index])); } /* Valid name segment */ - if (0 == index) { + if (index == 4) { /* Found 4 valid characters */ char_buf[4] = '\0'; if (name_string) { - STRCAT (name_string, char_buf); + ACPI_STRCAT (name_string, char_buf); ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Appended to - %s \n", name_string)); } - else { ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "No Name string - %s \n", char_buf)); } } - - else if (4 == index) { + else if (index == 0) { /* * First character was not a valid name character, * so we are looking at something other than a name. @@ -209,7 +222,6 @@ char_buf[0])); status = AE_CTRL_PENDING; } - else { /* Segment started with one or more valid characters, but fewer than 4 */ @@ -218,16 +230,16 @@ *aml_address, aml_address)); } - *in_aml_address = aml_address; + *in_aml_address = (u8 *) aml_address; return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_get_name_string + * FUNCTION: acpi_ex_get_name_string * - * PARAMETERS: Data_type - Data type to be associated with this name + * PARAMETERS: data_type - Data type to be associated with this name * * RETURN: Status * @@ -235,30 +247,28 @@ * ******************************************************************************/ - acpi_status acpi_ex_get_name_string ( - acpi_object_type8 data_type, - u8 *in_aml_address, - NATIVE_CHAR **out_name_string, - u32 *out_name_length) + acpi_object_type data_type, + u8 *in_aml_address, + char **out_name_string, + u32 *out_name_length) { - acpi_status status = AE_OK; - u8 *aml_address = in_aml_address; - NATIVE_CHAR *name_string = NULL; - u32 num_segments; - u32 prefix_count = 0; - u8 prefix = 0; - u8 has_prefix = FALSE; - - - FUNCTION_TRACE_PTR ("Ex_get_name_string", aml_address); - - - if (INTERNAL_TYPE_REGION_FIELD == data_type || - INTERNAL_TYPE_BANK_FIELD == data_type || - INTERNAL_TYPE_INDEX_FIELD == data_type) { - /* Disallow prefixes for types associated with Field_unit names */ + acpi_status status = AE_OK; + u8 *aml_address = in_aml_address; + char *name_string = NULL; + u32 num_segments; + u32 prefix_count = 0; + u8 has_prefix = FALSE; + + + ACPI_FUNCTION_TRACE_PTR ("ex_get_name_string", aml_address); + + + if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type || + ACPI_TYPE_LOCAL_BANK_FIELD == data_type || + ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) { + /* Disallow prefixes for types associated with field_unit names */ name_string = acpi_ex_allocate_name_string (0, 1); if (!name_string) { @@ -268,24 +278,22 @@ status = acpi_ex_name_segment (&aml_address, name_string); } } - else { /* - * Data_type is not a field name. + * data_type is not a field name. * Examine first character of name for root or parent prefix operators */ switch (*aml_address) { - case AML_ROOT_PREFIX: - prefix = *aml_address++; - ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Root_prefix: %x\n", prefix)); + ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n", aml_address)); /* - * Remember that we have a Root_prefix -- - * see comment in Acpi_ex_allocate_name_string() + * Remember that we have a root_prefix -- + * see comment in acpi_ex_allocate_name_string() */ - prefix_count = (u32) -1; + aml_address++; + prefix_count = ACPI_UINT32_MAX; has_prefix = TRUE; break; @@ -295,18 +303,21 @@ /* Increment past possibly multiple parent prefixes */ do { - prefix = *aml_address++; - ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Parent_prefix: %x\n", prefix)); + ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n", aml_address)); - ++prefix_count; + aml_address++; + prefix_count++; } while (*aml_address == AML_PARENT_PREFIX); + has_prefix = TRUE; break; default: + /* Not a prefix character */ + break; } @@ -314,12 +325,11 @@ /* Examine first character of name for name segment prefix operator */ switch (*aml_address) { - case AML_DUAL_NAME_PREFIX: - prefix = *aml_address++; - ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Dual_name_prefix: %x\n", prefix)); + ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n", aml_address)); + aml_address++; name_string = acpi_ex_allocate_name_string (prefix_count, 2); if (!name_string) { status = AE_NO_MEMORY; @@ -339,12 +349,12 @@ case AML_MULTI_NAME_PREFIX_OP: - prefix = *aml_address++; - ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Multi_name_prefix: %x\n", prefix)); + ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n", aml_address)); /* Fetch count of segments remaining in name path */ - num_segments = *aml_address++; + aml_address++; + num_segments = *aml_address; name_string = acpi_ex_allocate_name_string (prefix_count, num_segments); if (!name_string) { @@ -354,11 +364,12 @@ /* Indicate that we processed a prefix */ + aml_address++; has_prefix = TRUE; while (num_segments && (status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) { - --num_segments; + num_segments--; } break; @@ -366,10 +377,10 @@ case 0: - /* Null_name valid as of 8-12-98 ASL/AML Grammar Update */ + /* null_name valid as of 8-12-98 ASL/AML Grammar Update */ - if (-1 == prefix_count) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Name_seg is \"\\\" followed by NULL\n")); + if (prefix_count == ACPI_UINT32_MAX) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "name_seg is \"\\\" followed by NULL\n")); } /* Consume the NULL byte */ @@ -396,20 +407,17 @@ status = acpi_ex_name_segment (&aml_address, name_string); break; - - } /* Switch (Peek_op ()) */ + } } - if (AE_CTRL_PENDING == status && has_prefix) { /* Ran out of segments after processing a prefix */ - REPORT_ERROR ( - ("Ex_do_name: Malformed Name at %p\n", name_string)); + ACPI_REPORT_ERROR ( + ("ex_do_name: Malformed Name at %p\n", name_string)); status = AE_AML_BAD_NAME; } - *out_name_string = name_string; *out_name_length = (u32) (aml_address - in_aml_address); diff -urN linux-2.4.21/drivers/acpi/executer/exoparg1.c linux-2.4.22/drivers/acpi/executer/exoparg1.c --- linux-2.4.21/drivers/acpi/executer/exoparg1.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exoparg1.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,39 +2,57 @@ /****************************************************************************** * * Module Name: exoparg1 - AML execution - opcodes with 1 argument - * $Revision: 120 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exoparg1") + ACPI_MODULE_NAME ("exoparg1") /*! @@ -59,12 +77,11 @@ * fully resolved operands. !*/ - /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_1A_0T_0R + * FUNCTION: acpi_ex_opcode_1A_0T_0R * - * PARAMETERS: Walk_state - Current state (contains AML opcode) + * PARAMETERS: walk_state - Current state (contains AML opcode) * * RETURN: Status * @@ -75,45 +92,45 @@ acpi_status acpi_ex_opcode_1A_0T_0R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_status status = AE_OK; + union acpi_operand_object **operand = &walk_state->operands[0]; + acpi_status status = AE_OK; - FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); - /* Examine the opcode */ + /* Examine the AML opcode */ switch (walk_state->opcode) { - case AML_RELEASE_OP: /* Release (Mutex_object) */ + case AML_RELEASE_OP: /* Release (mutex_object) */ status = acpi_ex_release_mutex (operand[0], walk_state); break; - case AML_RESET_OP: /* Reset (Event_object) */ + case AML_RESET_OP: /* Reset (event_object) */ status = acpi_ex_system_reset_event (operand[0]); break; - case AML_SIGNAL_OP: /* Signal (Event_object) */ + case AML_SIGNAL_OP: /* Signal (event_object) */ status = acpi_ex_system_signal_event (operand[0]); break; - case AML_SLEEP_OP: /* Sleep (Msec_time) */ + case AML_SLEEP_OP: /* Sleep (msec_time) */ - acpi_ex_system_do_suspend ((u32) operand[0]->integer.value); + status = acpi_ex_system_do_suspend ((u32) operand[0]->integer.value); break; - case AML_STALL_OP: /* Stall (Usec_time) */ + case AML_STALL_OP: /* Stall (usec_time) */ - acpi_ex_system_do_stall ((u32) operand[0]->integer.value); + status = acpi_ex_system_do_stall ((u32) operand[0]->integer.value); break; @@ -125,7 +142,7 @@ default: /* Unknown opcode */ - REPORT_ERROR (("Acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; @@ -137,9 +154,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_1A_1T_0R + * FUNCTION: acpi_ex_opcode_1A_1T_0R * - * PARAMETERS: Walk_state - Current state (contains AML opcode) + * PARAMETERS: walk_state - Current state (contains AML opcode) * * RETURN: Status * @@ -150,25 +167,26 @@ acpi_status acpi_ex_opcode_1A_1T_0R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object **operand = &walk_state->operands[0]; + acpi_status status = AE_OK; + union acpi_operand_object **operand = &walk_state->operands[0]; - FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); - switch (walk_state->opcode) { + /* Examine the AML opcode */ + switch (walk_state->opcode) { case AML_LOAD_OP: - status = acpi_ex_load_op (operand[0], operand[1]); + status = acpi_ex_load_op (operand[0], operand[1], walk_state); break; default: /* Unknown opcode */ - REPORT_ERROR (("Acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; @@ -183,9 +201,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_1A_1T_1R + * FUNCTION: acpi_ex_opcode_1A_1T_1R * - * PARAMETERS: Walk_state - Current state (contains AML opcode) + * PARAMETERS: walk_state - Current state (contains AML opcode) * * RETURN: Status * @@ -196,22 +214,22 @@ acpi_status acpi_ex_opcode_1A_1T_1R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *return_desc = NULL; - acpi_operand_object *return_desc2 = NULL; - u32 temp32; - u32 i; - u32 j; - acpi_integer digit; + acpi_status status = AE_OK; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *return_desc = NULL; + union acpi_operand_object *return_desc2 = NULL; + u32 temp32; + u32 i; + u32 power_of_ten; + acpi_integer digit; - FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); - /* Create a return object of type Integer for most opcodes */ + /* Examine the AML opcode */ switch (walk_state->opcode) { case AML_BIT_NOT_OP: @@ -221,156 +239,162 @@ case AML_TO_BCD_OP: case AML_COND_REF_OF_OP: + /* Create a return object of type Integer for these opcodes */ + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; } - break; - } + switch (walk_state->opcode) { + case AML_BIT_NOT_OP: /* Not (Operand, Result) */ + return_desc->integer.value = ~operand[0]->integer.value; + break; - switch (walk_state->opcode) { - case AML_BIT_NOT_OP: /* Not (Operand, Result) */ + case AML_FIND_SET_LEFT_BIT_OP: /* find_set_left_bit (Operand, Result) */ - return_desc->integer.value = ~operand[0]->integer.value; - break; + return_desc->integer.value = operand[0]->integer.value; + /* + * Acpi specification describes Integer type as a little + * endian unsigned value, so this boundary condition is valid. + */ + for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { + return_desc->integer.value >>= 1; + } - case AML_FIND_SET_LEFT_BIT_OP: /* Find_set_left_bit (Operand, Result) */ + return_desc->integer.value = temp32; + break; - return_desc->integer.value = operand[0]->integer.value; + case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */ - /* - * Acpi specification describes Integer type as a little - * endian unsigned value, so this boundary condition is valid. - */ - for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { - return_desc->integer.value >>= 1; - } + return_desc->integer.value = operand[0]->integer.value; - return_desc->integer.value = temp32; - break; + /* + * The Acpi specification describes Integer type as a little + * endian unsigned value, so this boundary condition is valid. + */ + for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { + return_desc->integer.value <<= 1; + } + /* Since the bit position is one-based, subtract from 33 (65) */ - case AML_FIND_SET_RIGHT_BIT_OP: /* Find_set_right_bit (Operand, Result) */ + return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32; + break; - return_desc->integer.value = operand[0]->integer.value; + case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */ - /* - * The Acpi specification describes Integer type as a little - * endian unsigned value, so this boundary condition is valid. - */ - for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { - return_desc->integer.value <<= 1; - } + /* + * The 64-bit ACPI integer can hold 16 4-bit BCD characters + * (if table is 32-bit, integer can hold 8 BCD characters) + * Convert each 4-bit BCD value + */ + power_of_ten = 1; + return_desc->integer.value = 0; + digit = operand[0]->integer.value; - /* Since the bit position is one-based, subtract from 33 (65) */ + /* Convert each BCD digit (each is one nybble wide) */ - return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32; - break; + for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) { + /* Get the least significant 4-bit BCD digit */ + temp32 = ((u32) digit) & 0xF; - case AML_FROM_BCD_OP: /* From_bcd (BCDValue, Result) */ + /* Check the range of the digit */ - /* - * The 64-bit ACPI integer can hold 16 4-bit BCD integers - */ - return_desc->integer.value = 0; - for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { - /* Get one BCD digit */ + if (temp32 > 9) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "BCD digit too large (not decimal): 0x%X\n", + temp32)); - digit = (acpi_integer) ((operand[0]->integer.value >> (i * 4)) & 0xF); + status = AE_AML_NUMERIC_OVERFLOW; + goto cleanup; + } - /* Check the range of the digit */ + /* Sum the digit into the result with the current power of 10 */ - if (digit > 9) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: %d\n", - (u32) digit)); - status = AE_AML_NUMERIC_OVERFLOW; - goto cleanup; - } + return_desc->integer.value += (((acpi_integer) temp32) * power_of_ten); - if (digit > 0) { - /* Sum into the result with the appropriate power of 10 */ + /* Shift to next BCD digit */ - for (j = 0; j < i; j++) { - digit *= 10; - } + digit >>= 4; - return_desc->integer.value += digit; + /* Next power of 10 */ + + power_of_ten *= 10; } - } - break; + break; - case AML_TO_BCD_OP: /* To_bcd (Operand, Result) */ + case AML_TO_BCD_OP: /* to_bcd (Operand, Result) */ - if (operand[0]->integer.value > ACPI_MAX_BCD_VALUE) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %8.8X%8.8X\n", - HIDWORD(operand[0]->integer.value), LODWORD(operand[0]->integer.value))); - status = AE_AML_NUMERIC_OVERFLOW; - goto cleanup; - } + return_desc->integer.value = 0; + digit = operand[0]->integer.value; - return_desc->integer.value = 0; - for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { - /* Divide by nth factor of 10 */ + /* Each BCD digit is one nybble wide */ - temp32 = 0; - digit = operand[0]->integer.value; - for (j = 0; j < i; j++) { - acpi_ut_short_divide (&digit, 10, &digit, &temp32); + for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) { + (void) acpi_ut_short_divide (&digit, 10, &digit, &temp32); + + /* Insert the BCD digit that resides in the remainder from above */ + + return_desc->integer.value |= (((acpi_integer) temp32) << (i * 4)); } - /* Create the BCD digit from the remainder above */ + /* Overflow if there is any data left in Digit */ if (digit > 0) { - return_desc->integer.value += (temp32 << (i * 4)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n", + ACPI_HIDWORD(operand[0]->integer.value), + ACPI_LODWORD(operand[0]->integer.value))); + status = AE_AML_NUMERIC_OVERFLOW; + goto cleanup; } - } - break; + break; - case AML_COND_REF_OF_OP: /* Cond_ref_of (Source_object, Result) */ + case AML_COND_REF_OF_OP: /* cond_ref_of (source_object, Result) */ - /* - * This op is a little strange because the internal return value is - * different than the return value stored in the result descriptor - * (There are really two return values) - */ - if ((acpi_namespace_node *) operand[0] == acpi_gbl_root_node) { /* - * This means that the object does not exist in the namespace, - * return FALSE + * This op is a little strange because the internal return value is + * different than the return value stored in the result descriptor + * (There are really two return values) */ - return_desc->integer.value = 0; + if ((struct acpi_namespace_node *) operand[0] == acpi_gbl_root_node) { + /* + * This means that the object does not exist in the namespace, + * return FALSE + */ + return_desc->integer.value = 0; + goto cleanup; + } - /* - * Must delete the result descriptor since there is no reference - * being returned - */ - acpi_ut_remove_reference (operand[1]); - goto cleanup; - } + /* Get the object reference, store it, and remove our reference */ - /* Get the object reference and store it */ + status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } - status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } + status = acpi_ex_store (return_desc2, operand[1], walk_state); + acpi_ut_remove_reference (return_desc2); - status = acpi_ex_store (return_desc2, operand[1], walk_state); + /* The object exists in the namespace, return TRUE */ - /* The object exists in the namespace, return TRUE */ + return_desc->integer.value = ACPI_INTEGER_MAX; + goto cleanup; - return_desc->integer.value = ACPI_INTEGER_MAX; - goto cleanup; + + default: + /* No other opcodes get here */ + break; + } break; @@ -386,16 +410,19 @@ return_ACPI_STATUS (status); } - /* - * Normally, we would remove a reference on the Operand[0] parameter; - * But since it is being used as the internal return object - * (meaning we would normally increment it), the two cancel out, - * and we simply don't do anything. - */ - walk_state->result_obj = operand[0]; - walk_state->operands[0] = NULL; /* Prevent deletion */ + /* It is possible that the Store already produced a return object */ + + if (!walk_state->result_obj) { + /* + * Normally, we would remove a reference on the Operand[0] parameter; + * But since it is being used as the internal return object + * (meaning we would normally increment it), the two cancel out, + * and we simply don't do anything. + */ + walk_state->result_obj = operand[0]; + walk_state->operands[0] = NULL; /* Prevent deletion */ + } return_ACPI_STATUS (status); - break; /* @@ -403,58 +430,54 @@ */ case AML_COPY_OP: /* Copy (Source, Target) */ - status = AE_NOT_IMPLEMENTED; - goto cleanup; + status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc, walk_state); break; - case AML_TO_DECSTRING_OP: /* To_decimal_string (Data, Result) */ + case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */ status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state); break; - case AML_TO_HEXSTRING_OP: /* To_hex_string (Data, Result) */ + case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */ status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state); break; - case AML_TO_BUFFER_OP: /* To_buffer (Data, Result) */ + case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */ status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state); break; - case AML_TO_INTEGER_OP: /* To_integer (Data, Result) */ + case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */ status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state); break; - /* - * These are two obsolete opcodes - */ - case AML_SHIFT_LEFT_BIT_OP: /* Shift_left_bit (Source, Bit_num) */ - case AML_SHIFT_RIGHT_BIT_OP: /* Shift_right_bit (Source, Bit_num) */ - + case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */ + case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */ + /* + * These are two obsolete opcodes + */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n", acpi_ps_get_opcode_name (walk_state->opcode))); status = AE_SUPPORT; goto cleanup; - break; default: /* Unknown opcode */ - REPORT_ERROR (("Acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } - /* * Store the return value computed above into the target object */ @@ -463,7 +486,9 @@ cleanup: - walk_state->result_obj = return_desc; + if (!walk_state->result_obj) { + walk_state->result_obj = return_desc; + } /* Delete return object on error */ @@ -477,9 +502,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_1A_0T_1R + * FUNCTION: acpi_ex_opcode_1A_0T_1R * - * PARAMETERS: Walk_state - Current state (contains AML opcode) + * PARAMETERS: walk_state - Current state (contains AML opcode) * * RETURN: Status * @@ -489,23 +514,22 @@ acpi_status acpi_ex_opcode_1A_0T_1R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *temp_desc; - acpi_operand_object *return_desc = NULL; - acpi_status status = AE_OK; - u32 type; - acpi_integer value; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *temp_desc; + union acpi_operand_object *return_desc = NULL; + acpi_status status = AE_OK; + u32 type; + acpi_integer value; - FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); - /* Get the operand and decode the opcode */ + /* Examine the AML opcode */ switch (walk_state->opcode) { - case AML_LNOT_OP: /* LNot (Operand) */ return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); @@ -523,18 +547,18 @@ /* * Since we are expecting a Reference operand, it - * can be either a Node or an internal object. + * can be either a NS Node or an internal object. */ return_desc = operand[0]; - if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_INTERNAL)) { + if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_OPERAND) { /* Internal reference object - prevent deletion */ acpi_ut_add_reference (return_desc); } /* - * Convert the Return_desc Reference to a Number - * (This removes a reference on the Return_desc object) + * Convert the return_desc Reference to a Number + * (This removes a reference on the return_desc object) */ status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state); if (ACPI_FAILURE (status)) { @@ -545,7 +569,7 @@ } /* - * Return_desc is now guaranteed to be an Integer object + * return_desc is now guaranteed to be an Integer object * Do the actual increment or decrement */ if (AML_INCREMENT_OP == walk_state->opcode) { @@ -561,83 +585,13 @@ break; - case AML_TYPE_OP: /* Object_type (Source_object) */ - - if (INTERNAL_TYPE_REFERENCE == operand[0]->common.type) { - /* - * Not a Name -- an indirect name pointer would have - * been converted to a direct name pointer in Resolve_operands - */ - switch (operand[0]->reference.opcode) { - case AML_ZERO_OP: - case AML_ONE_OP: - case AML_ONES_OP: - case AML_REVISION_OP: - - /* Constants are of type Integer */ - - type = ACPI_TYPE_INTEGER; - break; - + case AML_TYPE_OP: /* object_type (source_object) */ - case AML_DEBUG_OP: - - /* Per 1.0b spec, Debug object is of type "Debug_object" */ - - type = ACPI_TYPE_DEBUG_OBJECT; - break; - - - case AML_INDEX_OP: - - /* Get the type of this reference (index into another object) */ - - type = operand[0]->reference.target_type; - if (type == ACPI_TYPE_PACKAGE) { - /* - * The main object is a package, we want to get the type - * of the individual package element that is referenced by - * the index. - */ - type = (*(operand[0]->reference.where))->common.type; - } - - break; - - - case AML_LOCAL_OP: - case AML_ARG_OP: - - type = acpi_ds_method_data_get_type (operand[0]->reference.opcode, - operand[0]->reference.offset, walk_state); - break; - - - default: - - REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R/Type_op: Internal error - Unknown Reference subtype %X\n", - operand[0]->reference.opcode)); - status = AE_AML_INTERNAL; - goto cleanup; - } - } - - else { - /* - * It's not a Reference, so it must be a direct name pointer. - */ - type = acpi_ns_get_type ((acpi_namespace_node *) operand[0]); - - /* Convert internal types to external types */ - - switch (type) { - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: - - type = ACPI_TYPE_FIELD_UNIT; - } + /* Get the type of the base object */ + status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL); + if (ACPI_FAILURE (status)) { + goto cleanup; } /* Allocate a descriptor to hold the type. */ @@ -652,44 +606,38 @@ break; - case AML_SIZE_OF_OP: /* Size_of (Source_object) */ + case AML_SIZE_OF_OP: /* size_of (source_object) */ - temp_desc = operand[0]; - if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { - temp_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) operand[0]); - } + /* Get the base object */ - if (!temp_desc) { - value = 0; + status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc); + if (ACPI_FAILURE (status)) { + goto cleanup; } - else { - switch (temp_desc->common.type) { - case ACPI_TYPE_BUFFER: - value = temp_desc->buffer.length; - break; - - case ACPI_TYPE_STRING: - value = temp_desc->string.length; - break; - - case ACPI_TYPE_PACKAGE: - value = temp_desc->package.count; - break; - - case INTERNAL_TYPE_REFERENCE: - - /* TBD: this must be a reference to a buf/str/pkg?? */ - - value = 4; - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Not Buf/Str/Pkg - found type %X\n", - temp_desc->common.type)); - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + /* + * Type is guaranteed to be a buffer, string, or package at this + * point (even if the original operand was an object reference, it + * will be resolved and typechecked during operand resolution.) + */ + switch (type) { + case ACPI_TYPE_BUFFER: + value = temp_desc->buffer.length; + break; + + case ACPI_TYPE_STRING: + value = temp_desc->string.length; + break; + + case ACPI_TYPE_PACKAGE: + value = temp_desc->package.count; + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "size_of, Not Buf/Str/Pkg - found type %s\n", + acpi_ut_get_type_name (type))); + status = AE_AML_OPERAND_TYPE; + goto cleanup; } /* @@ -706,7 +654,7 @@ break; - case AML_REF_OF_OP: /* Ref_of (Source_object) */ + case AML_REF_OF_OP: /* ref_of (source_object) */ status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state); if (ACPI_FAILURE (status)) { @@ -715,79 +663,113 @@ break; - case AML_DEREF_OF_OP: /* Deref_of (Obj_reference) */ + case AML_DEREF_OF_OP: /* deref_of (obj_reference | String) */ - /* Check for a method local or argument */ + /* Check for a method local or argument, or standalone String */ - if (!VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { - /* - * Must resolve/dereference the local/arg reference first - */ - switch (operand[0]->reference.opcode) { - /* Set Operand[0] to the value of the local/arg */ + if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) != ACPI_DESC_TYPE_NAMED) { + switch (ACPI_GET_OBJECT_TYPE (operand[0])) { + case ACPI_TYPE_LOCAL_REFERENCE: + /* + * This is a deref_of (local_x | arg_x) + * + * Must resolve/dereference the local/arg reference first + */ + switch (operand[0]->reference.opcode) { + case AML_LOCAL_OP: + case AML_ARG_OP: + + /* Set Operand[0] to the value of the local/arg */ + + status = acpi_ds_method_data_get_value (operand[0]->reference.opcode, + operand[0]->reference.offset, walk_state, &temp_desc); + if (ACPI_FAILURE (status)) { + goto cleanup; + } - case AML_LOCAL_OP: - case AML_ARG_OP: + /* + * Delete our reference to the input object and + * point to the object just retrieved + */ + acpi_ut_remove_reference (operand[0]); + operand[0] = temp_desc; + break; - acpi_ds_method_data_get_value (operand[0]->reference.opcode, - operand[0]->reference.offset, walk_state, &temp_desc); + case AML_REF_OF_OP: - /* - * Delete our reference to the input object and - * point to the object just retrieved - */ - acpi_ut_remove_reference (operand[0]); - operand[0] = temp_desc; - break; + /* Get the object to which the reference refers */ - default: + temp_desc = operand[0]->reference.object; + acpi_ut_remove_reference (operand[0]); + operand[0] = temp_desc; + break; - /* Index op - handled below */ - break; - } - } + default: + /* Must be an Index op - handled below */ + break; + } + break; - /* Operand[0] may have changed from the code above */ - if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { - /* Get the actual object from the Node (This is the dereference) */ + case ACPI_TYPE_STRING: - return_desc = ((acpi_namespace_node *) operand[0])->object; + /* + * This is a deref_of (String). The string is a reference to a named ACPI object. + * + * 1) Find the owning Node + * 2) Dereference the node to an actual object. Could be a Field, so we nee + * to resolve the node to a value. + */ + status = acpi_ns_get_node_by_path (operand[0]->string.pointer, + walk_state->scope_info->scope.node, ACPI_NS_SEARCH_PARENT, + ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc)); + if (ACPI_FAILURE (status)) { + goto cleanup; + } - /* Returning a pointer to the object, add another reference! */ + status = acpi_ex_resolve_node_to_value ( + ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc), walk_state); + goto cleanup; - acpi_ut_add_reference (return_desc); - } - else { - /* - * This must be a reference object produced by the Index - * ASL operation -- check internal opcode - */ - if ((operand[0]->reference.opcode != AML_INDEX_OP) && - (operand[0]->reference.opcode != AML_REF_OF_OP)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", - operand[0], operand[0]->reference.opcode)); + default: - status = AE_TYPE; + status = AE_AML_OPERAND_TYPE; goto cleanup; } + } + /* Operand[0] may have changed from the code above */ + if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_NAMED) { + /* + * This is a deref_of (object_reference) + * Get the actual object from the Node (This is the dereference). + * -- This case may only happen when a local_x or arg_x is dereferenced above. + */ + return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) operand[0]); + } + else { + /* + * This must be a reference object produced by either the Index() or + * ref_of() operator + */ switch (operand[0]->reference.opcode) { case AML_INDEX_OP: /* - * Supported target types for the Index operator are - * 1) A Buffer - * 2) A Package + * The target type for the Index operator must be + * either a Buffer or a Package */ - if (operand[0]->reference.target_type == ACPI_TYPE_BUFFER_FIELD) { + switch (operand[0]->reference.target_type) { + case ACPI_TYPE_BUFFER_FIELD: + + temp_desc = operand[0]->reference.object; + /* - * The target is a buffer, we must create a new object that - * contains one element of the buffer, the element pointed - * to by the index. + * Create a new object that contains one element of the + * buffer -- the element pointed to by the index. * * NOTE: index into a buffer is NOT a pointer to a * sub-buffer of the main buffer, it is only a pointer to a @@ -799,20 +781,21 @@ goto cleanup; } - temp_desc = operand[0]->reference.object; + /* + * Since we are returning the value of the buffer at the + * indexed location, we don't need to add an additional + * reference to the buffer itself. + */ return_desc->integer.value = temp_desc->buffer.pointer[operand[0]->reference.offset]; + break; - /* TBD: [Investigate] (see below) Don't add an additional - * ref! - */ - } - else if (operand[0]->reference.target_type == ACPI_TYPE_PACKAGE) { + case ACPI_TYPE_PACKAGE: + /* - * The target is a package, we want to return the referenced - * element of the package. We must add another reference to - * this object, however. + * Return the referenced element of the package. We must add + * another reference to the referenced object, however. */ return_desc = *(operand[0]->reference.where); if (!return_desc) { @@ -821,7 +804,6 @@ * an uninitialized package element and is thus a * severe error. */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", operand[0])); status = AE_AML_UNINITIALIZED_ELEMENT; @@ -829,15 +811,16 @@ } acpi_ut_add_reference (return_desc); - } + break; + + + default: - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Target_type %X in obj %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Index target_type %X in obj %p\n", operand[0]->reference.target_type, operand[0])); status = AE_AML_OPERAND_TYPE; goto cleanup; } - break; @@ -845,19 +828,31 @@ return_desc = operand[0]->reference.object; + if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) == ACPI_DESC_TYPE_NAMED) { + + return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) return_desc); + } + /* Add another reference to the object! */ acpi_ut_add_reference (return_desc); break; + + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", + operand[0], operand[0]->reference.opcode)); + + status = AE_TYPE; + goto cleanup; } } - break; default: - REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; diff -urN linux-2.4.21/drivers/acpi/executer/exoparg2.c linux-2.4.22/drivers/acpi/executer/exoparg2.c --- linux-2.4.21/drivers/acpi/executer/exoparg2.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exoparg2.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,40 +1,56 @@ /****************************************************************************** * * Module Name: exoparg2 - AML execution - opcodes with 2 arguments - * $Revision: 97 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "acevents.h" -#include "amlcode.h" -#include "acdispat.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exoparg2") + ACPI_MODULE_NAME ("exoparg2") /*! @@ -62,9 +78,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_2A_0T_0R + * FUNCTION: acpi_ex_opcode_2A_0T_0R * - * PARAMETERS: Walk_state - Current walk state + * PARAMETERS: walk_state - Current walk state * * RETURN: Status * @@ -77,57 +93,52 @@ acpi_status acpi_ex_opcode_2A_0T_0R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_namespace_node *node; - acpi_status status = AE_OK; + union acpi_operand_object **operand = &walk_state->operands[0]; + struct acpi_namespace_node *node; + acpi_status status = AE_OK; - FUNCTION_TRACE_STR ("Ex_opcode_2A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_0R", + acpi_ps_get_opcode_name (walk_state->opcode)); /* Examine the opcode */ switch (walk_state->opcode) { - - case AML_NOTIFY_OP: /* Notify (Notify_object, Notify_value) */ + case AML_NOTIFY_OP: /* Notify (notify_object, notify_value) */ /* The first operand is a namespace node */ - node = (acpi_namespace_node *) operand[0]; + node = (struct acpi_namespace_node *) operand[0]; - /* The node must refer to a device or thermal zone */ + /* Notifies allowed on this object? */ - if (node && operand[1]) /* TBD: is this check necessary? */ { - switch (node->type) { - case ACPI_TYPE_DEVICE: - case ACPI_TYPE_THERMAL: - - /* - * Dispatch the notify to the appropriate handler - * NOTE: the request is queued for execution after this method - * completes. The notify handlers are NOT invoked synchronously - * from this thread -- because handlers may in turn run other - * control methods. - */ - status = acpi_ev_queue_notify_request (node, - (u32) operand[1]->integer.value); - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type %X\n", - node->type)); + if (!acpi_ev_is_notify_object (node)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type [%s]\n", + acpi_ut_get_type_name (node->type))); - status = AE_AML_OPERAND_TYPE; - break; - } + status = AE_AML_OPERAND_TYPE; + break; } + + /* + * Dispatch the notify to the appropriate handler + * NOTE: the request is queued for execution after this method + * completes. The notify handlers are NOT invoked synchronously + * from this thread -- because handlers may in turn run other + * control methods. + */ + status = acpi_ev_queue_notify_request (node, + (u32) operand[1]->integer.value); break; + default: - REPORT_ERROR (("Acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; } @@ -137,9 +148,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_2A_2T_1R + * FUNCTION: acpi_ex_opcode_2A_2T_1R * - * PARAMETERS: Walk_state - Current walk state + * PARAMETERS: walk_state - Current walk state * * RETURN: Status * @@ -150,22 +161,22 @@ acpi_status acpi_ex_opcode_2A_2T_1R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *return_desc1 = NULL; - acpi_operand_object *return_desc2 = NULL; - acpi_status status; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *return_desc1 = NULL; + union acpi_operand_object *return_desc2 = NULL; + acpi_status status; - FUNCTION_TRACE_STR ("Ex_opcode_2A_2T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); /* * Execute the opcode */ switch (walk_state->opcode) { - case AML_DIVIDE_OP: /* Divide (Dividend, Divisor, Remainder_result Quotient_result) */ + case AML_DIVIDE_OP: /* Divide (Dividend, Divisor, remainder_result quotient_result) */ return_desc1 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); if (!return_desc1) { @@ -179,7 +190,7 @@ goto cleanup; } - /* Quotient to Return_desc1, remainder to Return_desc2 */ + /* Quotient to return_desc1, remainder to return_desc2 */ status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, &return_desc1->integer.value, &return_desc2->integer.value); @@ -191,11 +202,10 @@ default: - REPORT_ERROR (("Acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; - break; } @@ -235,9 +245,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_2A_1T_1R + * FUNCTION: acpi_ex_opcode_2A_1T_1R * - * PARAMETERS: Walk_state - Current walk state + * PARAMETERS: walk_state - Current walk state * * RETURN: Status * @@ -248,16 +258,17 @@ acpi_status acpi_ex_opcode_2A_1T_1R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *return_desc = NULL; - acpi_operand_object *temp_desc; - u32 index; - acpi_status status = AE_OK; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *return_desc = NULL; + union acpi_operand_object *temp_desc = NULL; + u32 index; + acpi_status status = AE_OK; + acpi_size length; - FUNCTION_TRACE_STR ("Ex_opcode_2A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); /* @@ -280,7 +291,7 @@ switch (walk_state->opcode) { - case AML_MOD_OP: /* Mod (Dividend, Divisor, Remainder_result (ACPI 2.0) */ + case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */ return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); if (!return_desc) { @@ -288,11 +299,10 @@ goto cleanup; } - /* Return_desc will contain the remainder */ + /* return_desc will contain the remainder */ status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, NULL, &return_desc->integer.value); - break; @@ -305,17 +315,17 @@ * guaranteed to be either Integer/String/Buffer by the operand * resolution mechanism above. */ - switch (operand[0]->common.type) { + switch (ACPI_GET_OBJECT_TYPE (operand[0])) { case ACPI_TYPE_INTEGER: - status = acpi_ex_convert_to_integer (operand[1], &operand[1], walk_state); + status = acpi_ex_convert_to_integer (operand[1], &temp_desc, walk_state); break; case ACPI_TYPE_STRING: - status = acpi_ex_convert_to_string (operand[1], &operand[1], 16, ACPI_UINT32_MAX, walk_state); + status = acpi_ex_convert_to_string (operand[1], &temp_desc, 16, ACPI_UINT32_MAX, walk_state); break; case ACPI_TYPE_BUFFER: - status = acpi_ex_convert_to_buffer (operand[1], &operand[1], walk_state); + status = acpi_ex_convert_to_buffer (operand[1], &temp_desc, walk_state); break; default: @@ -331,20 +341,69 @@ * (Both are Integer, String, or Buffer), and we can now perform the * concatenation. */ - status = acpi_ex_do_concatenate (operand[0], operand[1], &return_desc, walk_state); + status = acpi_ex_do_concatenate (operand[0], temp_desc, &return_desc, walk_state); + if (temp_desc != operand[1]) { + acpi_ut_remove_reference (temp_desc); + } break; - case AML_TO_STRING_OP: /* To_string (Buffer, Length, Result) (ACPI 2.0) */ + case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */ + + /* + * Input object is guaranteed to be a buffer at this point (it may have + * been converted.) Copy the raw buffer data to a new object of type String. + */ + + /* Get the length of the new string */ + + length = 0; + if (operand[1]->integer.value == 0) { + /* Handle optional length value */ + + operand[1]->integer.value = ACPI_INTEGER_MAX; + } + + while ((length < operand[0]->buffer.length) && + (length < operand[1]->integer.value) && + (operand[0]->buffer.pointer[length])) { + length++; + } + + if (length > ACPI_MAX_STRING_CONVERSION) { + status = AE_AML_STRING_LIMIT; + goto cleanup; + } + + /* Create the internal return object */ - status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, - (u32) operand[1]->integer.value, walk_state); + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Allocate a new string buffer (Length + 1 for null terminator) */ + + return_desc->string.pointer = ACPI_MEM_CALLOCATE (length + 1); + if (!return_desc->string.pointer) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Copy the raw buffer data with no transform */ + + ACPI_MEMCPY (return_desc->string.pointer, operand[0]->buffer.pointer, length); + + /* Set the string length */ + + return_desc->string.length = (u32) length; break; - case AML_CONCAT_RES_OP: /* Concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */ + case AML_CONCAT_RES_OP: /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */ - status = AE_NOT_IMPLEMENTED; + status = acpi_ex_concat_template (operand[0], operand[1], &return_desc, walk_state); break; @@ -352,7 +411,7 @@ /* Create the internal return object */ - return_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE); + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -363,73 +422,52 @@ /* * At this point, the Source operand is either a Package or a Buffer */ - if (operand[0]->common.type == ACPI_TYPE_PACKAGE) { + if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) { /* Object to be indexed is a Package */ if (index >= operand[0]->package.count) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond package end\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond package end (%X)\n", + index, operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; goto cleanup; } - if ((operand[2]->common.type == INTERNAL_TYPE_REFERENCE) && - (operand[2]->reference.opcode == AML_ZERO_OP)) { - /* - * There is no actual result descriptor (the Zero_op Result - * descriptor is a placeholder), so just delete the placeholder and - * return a reference to the package element - */ - acpi_ut_remove_reference (operand[2]); - } - - else { - /* - * Each element of the package is an internal object. Get the one - * we are after. - */ - temp_desc = operand[0]->package.elements [index]; - return_desc->reference.opcode = AML_INDEX_OP; - return_desc->reference.target_type = temp_desc->common.type; - return_desc->reference.object = temp_desc; - - status = acpi_ex_store (return_desc, operand[2], walk_state); - return_desc->reference.object = NULL; - } - - /* - * The local return object must always be a reference to the package element, - * not the element itself. - */ - return_desc->reference.opcode = AML_INDEX_OP; return_desc->reference.target_type = ACPI_TYPE_PACKAGE; + return_desc->reference.object = operand[0]->package.elements [index]; return_desc->reference.where = &operand[0]->package.elements [index]; } - else { /* Object to be indexed is a Buffer */ if (index >= operand[0]->buffer.length) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond end of buffer\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond end of buffer (%X)\n", + index, operand[0]->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } - return_desc->reference.opcode = AML_INDEX_OP; return_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD; - return_desc->reference.object = operand[0]; - return_desc->reference.offset = index; - - status = acpi_ex_store (return_desc, operand[2], walk_state); + return_desc->reference.object = operand[0]; } + /* Complete the Index reference object */ + + return_desc->reference.opcode = AML_INDEX_OP; + return_desc->reference.offset = index; + + /* Store the reference to the Target */ + + status = acpi_ex_store (return_desc, operand[2], walk_state); + + /* Return the reference */ + walk_state->result_obj = return_desc; goto cleanup; - break; default: - REPORT_ERROR (("Acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; @@ -440,7 +478,7 @@ if (ACPI_SUCCESS (status)) { /* - * Store the result of the operation (which is now in Return_desc) into + * Store the result of the operation (which is now in return_desc) into * the Target descriptor. */ status = acpi_ex_store (return_desc, operand[2], walk_state); @@ -448,7 +486,9 @@ goto cleanup; } - walk_state->result_obj = return_desc; + if (!walk_state->result_obj) { + walk_state->result_obj = return_desc; + } } @@ -466,9 +506,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_2A_0T_1R + * FUNCTION: acpi_ex_opcode_2A_0T_1R * - * PARAMETERS: Walk_state - Current walk state + * PARAMETERS: walk_state - Current walk state * * RETURN: Status * @@ -478,15 +518,15 @@ acpi_status acpi_ex_opcode_2A_0T_1R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *return_desc = NULL; - acpi_status status = AE_OK; - u8 logical_result = FALSE; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *return_desc = NULL; + acpi_status status = AE_OK; + u8 logical_result = FALSE; - FUNCTION_TRACE_STR ("Ex_opcode_2A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); /* Create the internal return object */ @@ -500,7 +540,7 @@ /* * Execute the Opcode */ - if (walk_state->op_info->flags & AML_LOGICAL) /* Logical_op (Operand0, Operand1) */ { + if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ { logical_result = acpi_ex_do_logical_op (walk_state->opcode, operand[0]->integer.value, operand[1]->integer.value); @@ -509,7 +549,7 @@ switch (walk_state->opcode) { - case AML_ACQUIRE_OP: /* Acquire (Mutex_object, Timeout) */ + case AML_ACQUIRE_OP: /* Acquire (mutex_object, Timeout) */ status = acpi_ex_acquire_mutex (operand[1], operand[0], walk_state); if (status == AE_TIME) { @@ -519,7 +559,7 @@ break; - case AML_WAIT_OP: /* Wait (Event_object, Timeout) */ + case AML_WAIT_OP: /* Wait (event_object, Timeout) */ status = acpi_ex_system_wait_event (operand[1], operand[0]); if (status == AE_TIME) { @@ -531,16 +571,16 @@ default: - REPORT_ERROR (("Acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; - break; } store_logical_result: /* - * Set return value to according to Logical_result. logical TRUE (all ones) + * Set return value to according to logical_result. logical TRUE (all ones) * Default is FALSE (zero) */ if (logical_result) { diff -urN linux-2.4.21/drivers/acpi/executer/exoparg3.c linux-2.4.22/drivers/acpi/executer/exoparg3.c --- linux-2.4.21/drivers/acpi/executer/exoparg3.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exoparg3.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,37 +2,55 @@ /****************************************************************************** * * Module Name: exoparg3 - AML execution - opcodes with 3 arguments - * $Revision: 3 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exoparg3") + ACPI_MODULE_NAME ("exoparg3") /*! @@ -60,9 +78,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_3A_0T_0R + * FUNCTION: acpi_ex_opcode_3A_0T_0R * - * PARAMETERS: Walk_state - Current walk state + * PARAMETERS: walk_state - Current walk state * * RETURN: Status * @@ -72,27 +90,27 @@ acpi_status acpi_ex_opcode_3A_0T_0R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - ACPI_SIGNAL_FATAL_INFO *fatal; - acpi_status status = AE_OK; + union acpi_operand_object **operand = &walk_state->operands[0]; + struct acpi_signal_fatal_info *fatal; + acpi_status status = AE_OK; - FUNCTION_TRACE_STR ("Ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); switch (walk_state->opcode) { - case AML_FATAL_OP: /* Fatal (Fatal_type Fatal_code Fatal_arg) */ + case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Fatal_op: Type %x Code %x Arg %x <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", + "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", (u32) operand[0]->integer.value, (u32) operand[1]->integer.value, (u32) operand[2]->integer.value)); - fatal = ACPI_MEM_ALLOCATE (sizeof (ACPI_SIGNAL_FATAL_INFO)); + fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info)); if (fatal) { fatal->type = (u32) operand[0]->integer.value; fatal->code = (u32) operand[1]->integer.value; @@ -102,7 +120,7 @@ /* * Always signal the OS! */ - acpi_os_signal (ACPI_SIGNAL_FATAL, fatal); + status = acpi_os_signal (ACPI_SIGNAL_FATAL, fatal); /* Might return while OS is shutting down, just continue */ @@ -112,11 +130,10 @@ default: - REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; - break; } @@ -128,9 +145,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_3A_1T_1R + * FUNCTION: acpi_ex_opcode_3A_1T_1R * - * PARAMETERS: Walk_state - Current walk state + * PARAMETERS: walk_state - Current walk state * * RETURN: Status * @@ -140,17 +157,17 @@ acpi_status acpi_ex_opcode_3A_1T_1R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *return_desc = NULL; - char *buffer; - acpi_status status = AE_OK; - u32 index; - u32 length; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *return_desc = NULL; + char *buffer; + acpi_status status = AE_OK; + acpi_native_uint index; + acpi_size length; - FUNCTION_TRACE_STR ("Ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); switch (walk_state->opcode) { @@ -160,7 +177,7 @@ * Create the return object. The Source operand is guaranteed to be * either a String or a Buffer, so just use its type. */ - return_desc = acpi_ut_create_internal_object (operand[0]->common.type); + return_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (operand[0])); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -168,8 +185,8 @@ /* Get the Integer values from the objects */ - index = (u32) operand[1]->integer.value; - length = (u32) operand[2]->integer.value; + index = (acpi_native_uint) operand[1]->integer.value; + length = (acpi_size) operand[2]->integer.value; /* * If the index is beyond the length of the String/Buffer, or if the @@ -181,37 +198,36 @@ if ((index + length) > operand[0]->string.length) { - length = operand[0]->string.length - index; + length = (acpi_size) operand[0]->string.length - index; } /* Allocate a new buffer for the String/Buffer */ - buffer = ACPI_MEM_CALLOCATE (length + 1); + buffer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1); if (!buffer) { - return (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup; } /* Copy the portion requested */ - MEMCPY (buffer, operand[0]->string.pointer + index, - length); + ACPI_MEMCPY (buffer, operand[0]->string.pointer + index, + length); /* Set the length of the new String/Buffer */ return_desc->string.pointer = buffer; - return_desc->string.length = length; + return_desc->string.length = (u32) length; } - break; default: - REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; - break; } /* Store the result in the target */ @@ -228,7 +244,9 @@ /* Set the return object and exit */ - walk_state->result_obj = return_desc; + if (!walk_state->result_obj) { + walk_state->result_obj = return_desc; + } return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/executer/exoparg6.c linux-2.4.22/drivers/acpi/executer/exoparg6.c --- linux-2.4.21/drivers/acpi/executer/exoparg6.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exoparg6.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,37 +2,55 @@ /****************************************************************************** * * Module Name: exoparg6 - AML execution - opcodes with 6 arguments - * $Revision: 4 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exoparg6") + ACPI_MODULE_NAME ("exoparg6") /*! @@ -60,11 +78,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_do_match + * FUNCTION: acpi_ex_do_match * - * PARAMETERS: Match_op - The AML match operand - * Package_value - Value from the target package - * Match_value - Value to be matched + * PARAMETERS: match_op - The AML match operand + * package_value - Value from the target package + * match_value - Value to be matched * * RETURN: TRUE if the match is successful, FALSE otherwise * @@ -74,9 +92,9 @@ u8 acpi_ex_do_match ( - u32 match_op, - acpi_integer package_value, - acpi_integer match_value) + u32 match_op, + acpi_integer package_value, + acpi_integer match_value) { switch (match_op) { @@ -137,9 +155,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_opcode_6A_0T_1R + * FUNCTION: acpi_ex_opcode_6A_0T_1R * - * PARAMETERS: Walk_state - Current walk state + * PARAMETERS: walk_state - Current walk state * * RETURN: Status * @@ -149,23 +167,23 @@ acpi_status acpi_ex_opcode_6A_0T_1R ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *return_desc = NULL; - acpi_status status = AE_OK; - u32 index; - acpi_operand_object *this_element; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *return_desc = NULL; + acpi_status status = AE_OK; + u32 index; + union acpi_operand_object *this_element; - FUNCTION_TRACE_STR ("Ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); switch (walk_state->opcode) { case AML_MATCH_OP: /* - * Match (Search_package[0], Match_op1[1], Match_object1[2], - * Match_op2[3], Match_object2[4], Start_index[5]) + * Match (search_package[0], match_op1[1], match_object1[2], + * match_op2[3], match_object2[4], start_index[5]) */ /* Validate match comparison sub-opcodes */ @@ -199,8 +217,9 @@ * Examine each element until a match is found. Within the loop, * "continue" signifies that the current element does not match * and the next should be examined. + * * Upon finding a match, the loop will terminate via "break" at - * the bottom. If it terminates "normally", Match_value will be -1 + * the bottom. If it terminates "normally", match_value will be -1 * (its initial value) indicating that no match was found. When * returned as a Number, this will produce the Ones value as specified. */ @@ -209,27 +228,21 @@ /* * Treat any NULL or non-numeric elements as non-matching. - * TBD [Unhandled] - if an element is a Name, - * should we examine its value? */ if (!this_element || - this_element->common.type != ACPI_TYPE_INTEGER) { + ACPI_GET_OBJECT_TYPE (this_element) != ACPI_TYPE_INTEGER) { continue; } - /* - * Within these switch statements: - * "break" (exit from the switch) signifies a match; - * "continue" (proceed to next iteration of enclosing - * "for" loop) signifies a non-match. + * "continue" (proceed to next iteration of enclosing + * "for" loop) signifies a non-match. */ if (!acpi_ex_do_match ((u32) operand[1]->integer.value, this_element->integer.value, operand[2]->integer.value)) { continue; } - if (!acpi_ex_do_match ((u32) operand[3]->integer.value, this_element->integer.value, operand[4]->integer.value)) { continue; @@ -246,18 +259,16 @@ case AML_LOAD_TABLE_OP: - status = AE_NOT_IMPLEMENTED; - goto cleanup; + status = acpi_ex_load_table_op (walk_state, &return_desc); break; default: - REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", + ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; - break; } diff -urN linux-2.4.21/drivers/acpi/executer/exprep.c linux-2.4.22/drivers/acpi/executer/exprep.c --- linux-2.4.21/drivers/acpi/executer/exprep.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exprep.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,292 +2,348 @@ /****************************************************************************** * * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities - * $Revision: 99 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acparser.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exprep") + ACPI_MODULE_NAME ("exprep") /******************************************************************************* * - * FUNCTION: Acpi_ex_decode_field_access_type + * FUNCTION: acpi_ex_decode_field_access * * PARAMETERS: Access - Encoded field access bits * Length - Field length. * - * RETURN: Field granularity (8, 16, 32 or 64) + * RETURN: Field granularity (8, 16, 32 or 64) and + * byte_alignment (1, 2, 3, or 4) * - * DESCRIPTION: Decode the Access_type bits of a field definition. + * DESCRIPTION: Decode the access_type bits of a field definition. * ******************************************************************************/ static u32 -acpi_ex_decode_field_access_type ( - u32 access, - u16 length, - u32 *alignment) +acpi_ex_decode_field_access ( + union acpi_operand_object *obj_desc, + u8 field_flags, + u32 *return_byte_alignment) { - PROC_NAME ("Ex_decode_field_access_type"); + u32 access; + u8 byte_alignment; + u8 bit_length; +/* u32 Length; */ + ACPI_FUNCTION_NAME ("ex_decode_field_access"); + + + access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK); + switch (access) { - case ACCESS_ANY_ACC: + case AML_FIELD_ACCESS_ANY: + + byte_alignment = 1; + bit_length = 8; - *alignment = 8; +#if 0 + /* + * TBD: optimize + * + * Any attempt to optimize the access size to the size of the field + * must take into consideration the length of the region and take + * care that an access to the field will not attempt to access + * beyond the end of the region. + */ /* Use the length to set the access type */ + length = obj_desc->common_field.bit_length; + if (length <= 8) { - return (8); + bit_length = 8; } else if (length <= 16) { - return (16); + bit_length = 16; } else if (length <= 32) { - return (32); + bit_length = 32; } else if (length <= 64) { - return (64); + bit_length = 64; } + else { + /* Larger than Qword - just use byte-size chunks */ - /* Default is 8 (byte) */ - - return (8); + bit_length = 8; + } +#endif break; - case ACCESS_BYTE_ACC: - *alignment = 8; - return (8); + case AML_FIELD_ACCESS_BYTE: + case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */ + byte_alignment = 1; + bit_length = 8; break; - case ACCESS_WORD_ACC: - *alignment = 16; - return (16); + case AML_FIELD_ACCESS_WORD: + byte_alignment = 2; + bit_length = 16; break; - case ACCESS_DWORD_ACC: - *alignment = 32; - return (32); + case AML_FIELD_ACCESS_DWORD: + byte_alignment = 4; + bit_length = 32; break; - case ACCESS_QWORD_ACC: /* ACPI 2.0 */ - *alignment = 64; - return (64); + case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ + byte_alignment = 8; + bit_length = 64; break; default: /* Invalid field access type */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown field access type %x\n", + "Unknown field access type %X\n", access)); return (0); } + + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) { + /* + * buffer_field access can be on any byte boundary, so the + * byte_alignment is always 1 byte -- regardless of any byte_alignment + * implied by the field access type. + */ + byte_alignment = 1; + } + + *return_byte_alignment = byte_alignment; + return (bit_length); } /******************************************************************************* * - * FUNCTION: Acpi_ex_prep_common_field_object + * FUNCTION: acpi_ex_prep_common_field_object * - * PARAMETERS: Obj_desc - The field object - * Field_flags - Access, Lock_rule, and Update_rule. - * The format of a Field_flag is described + * PARAMETERS: obj_desc - The field object + * field_flags - Access, lock_rule, and update_rule. + * The format of a field_flag is described * in the ACPI specification - * Field_bit_position - Field start position - * Field_bit_length - Field length in number of bits + * field_bit_position - Field start position + * field_bit_length - Field length in number of bits * * RETURN: Status * * DESCRIPTION: Initialize the areas of the field object that are common - * to the various types of fields. + * to the various types of fields. Note: This is very "sensitive" + * code because we are solving the general case for field + * alignment. * ******************************************************************************/ acpi_status acpi_ex_prep_common_field_object ( - acpi_operand_object *obj_desc, - u8 field_flags, - u32 field_bit_position, - u32 field_bit_length) + union acpi_operand_object *obj_desc, + u8 field_flags, + u8 field_attribute, + u32 field_bit_position, + u32 field_bit_length) { - u32 access_bit_width; - u32 alignment; - u32 nearest_byte_address; + u32 access_bit_width; + u32 byte_alignment; + u32 nearest_byte_address; - FUNCTION_TRACE ("Ex_prep_common_field_object"); + ACPI_FUNCTION_TRACE ("ex_prep_common_field_object"); /* * Note: the structure being initialized is the - * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common area - * are initialized by this procedure. + * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common + * area are initialized by this procedure. */ - - /* Demultiplex the Field_flags byte */ - - obj_desc->common_field.lock_rule = (u8) ((field_flags & LOCK_RULE_MASK) - >> LOCK_RULE_SHIFT); - obj_desc->common_field.update_rule = (u8) ((field_flags & UPDATE_RULE_MASK) - >> UPDATE_RULE_SHIFT); - /* Other misc fields */ - - obj_desc->common_field.bit_length = (u16) field_bit_length; + obj_desc->common_field.field_flags = field_flags; + obj_desc->common_field.attribute = field_attribute; + obj_desc->common_field.bit_length = field_bit_length; /* * Decode the access type so we can compute offsets. The access type gives * two pieces of information - the width of each field access and the - * necessary alignment of the access. For Any_acc, the width used is the - * largest necessary/possible in an attempt to access the whole field in one - * I/O operation. However, for Any_acc, the alignment is 8. For all other - * access types (Byte, Word, Dword, Qword), the width is the same as the - * alignment. + * necessary byte_alignment (address granularity) of the access. + * + * For any_acc, the access_bit_width is the largest width that is both + * necessary and possible in an attempt to access the whole field in one + * I/O operation. However, for any_acc, the byte_alignment is always one + * byte. + * + * For all Buffer Fields, the byte_alignment is always one byte. + * + * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is + * the same (equivalent) as the byte_alignment. */ - access_bit_width = acpi_ex_decode_field_access_type ( - ((field_flags & ACCESS_TYPE_MASK) >> ACCESS_TYPE_SHIFT), - obj_desc->field.bit_length, &alignment); + access_bit_width = acpi_ex_decode_field_access (obj_desc, field_flags, + &byte_alignment); if (!access_bit_width) { return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } /* Setup width (access granularity) fields */ - obj_desc->common_field.access_bit_width = (u8) access_bit_width; /* 8, 16, 32, 64 */ - obj_desc->common_field.access_byte_width = (u8) DIV_8 (access_bit_width); /* 1, 2, 4, 8 */ - - if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) { - /* - * Buffer_field access can be on any byte boundary, so the - * alignment is always 8 (regardless of any alignment implied by the - * field access type.) - */ - alignment = 8; - } - + obj_desc->common_field.access_byte_width = (u8) + ACPI_DIV_8 (access_bit_width); /* 1, 2, 4, 8 */ /* - * Base_byte_offset is the address of the start of the field within the region. It is - * the byte address of the first *datum* (field-width data unit) of the field. - * (i.e., the first datum that contains at least the first *bit* of the field.) + * base_byte_offset is the address of the start of the field within the + * region. It is the byte address of the first *datum* (field-width data + * unit) of the field. (i.e., the first datum that contains at least the + * first *bit* of the field.) + * + * Note: byte_alignment is always either equal to the access_bit_width or 8 + * (Byte access), and it defines the addressing granularity of the parent + * region or buffer. */ - nearest_byte_address = ROUND_BITS_DOWN_TO_BYTES (field_bit_position); - obj_desc->common_field.base_byte_offset = ROUND_DOWN (nearest_byte_address, - DIV_8 (alignment)); + nearest_byte_address = + ACPI_ROUND_BITS_DOWN_TO_BYTES (field_bit_position); + obj_desc->common_field.base_byte_offset = + ACPI_ROUND_DOWN (nearest_byte_address, byte_alignment); /* - * Start_field_bit_offset is the offset of the first bit of the field within a field datum. - * This is calculated as the number of bits from the Base_byte_offset. In other words, - * the start of the field is relative to a byte address, regardless of the access type - * of the field. + * start_field_bit_offset is the offset of the first bit of the field within + * a field datum. */ - obj_desc->common_field.start_field_bit_offset = (u8) (MOD_8 (field_bit_position)); + obj_desc->common_field.start_field_bit_offset = (u8) + (field_bit_position - ACPI_MUL_8 (obj_desc->common_field.base_byte_offset)); /* - * Datum_valid_bits is the number of valid field bits in the first field datum. + * Valid bits -- the number of bits that compose a partial datum, + * 1) At the end of the field within the region (arbitrary starting bit + * offset) + * 2) At the end of a buffer used to contain the field (starting offset + * always zero) */ - obj_desc->common_field.datum_valid_bits = (u8) (access_bit_width - - obj_desc->common_field.start_field_bit_offset); + obj_desc->common_field.end_field_valid_bits = (u8) + ((obj_desc->common_field.start_field_bit_offset + field_bit_length) % + access_bit_width); + /* start_buffer_bit_offset always = 0 */ + + obj_desc->common_field.end_buffer_valid_bits = (u8) + (field_bit_length % access_bit_width); /* - * Valid bits -- the number of bits that compose a partial datum, - * 1) At the end of the field within the region (arbitrary starting bit offset) - * 2) At the end of a buffer used to contain the field (starting offset always zero) + * datum_valid_bits is the number of valid field bits in the first + * field datum. */ - obj_desc->common_field.end_field_valid_bits = (u8) ((obj_desc->common_field.start_field_bit_offset + - field_bit_length) % access_bit_width); - obj_desc->common_field.end_buffer_valid_bits = (u8) (field_bit_length % access_bit_width); /* Start_buffer_bit_offset always = 0 */ - + obj_desc->common_field.datum_valid_bits = (u8) + (access_bit_width - obj_desc->common_field.start_field_bit_offset); /* - * Does the entire field fit within a single field access element - * (datum)? (without crossing a datum boundary) + * Does the entire field fit within a single field access element? (datum) + * (i.e., without crossing a datum boundary) */ - if ((obj_desc->common_field.start_field_bit_offset + obj_desc->common_field.bit_length) <= - (u16) obj_desc->common_field.access_bit_width) { - obj_desc->common_field.access_flags |= AFIELD_SINGLE_DATUM; + if ((obj_desc->common_field.start_field_bit_offset + field_bit_length) <= + (u16) access_bit_width) { + obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM; } - return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_prep_field_value + * FUNCTION: acpi_ex_prep_field_value * * PARAMETERS: Node - Owning Node - * Region_node - Region in which field is being defined - * Field_flags - Access, Lock_rule, and Update_rule. - * Field_bit_position - Field start position - * Field_bit_length - Field length in number of bits + * region_node - Region in which field is being defined + * field_flags - Access, lock_rule, and update_rule. + * field_bit_position - Field start position + * field_bit_length - Field length in number of bits * * RETURN: Status * - * DESCRIPTION: Construct an acpi_operand_object of type Def_field and + * DESCRIPTION: Construct an union acpi_operand_object of type def_field and * connect it to the parent Node. * ******************************************************************************/ acpi_status acpi_ex_prep_field_value ( - ACPI_CREATE_FIELD_INFO *info) + struct acpi_create_field_info *info) { - acpi_operand_object *obj_desc; - u32 type; - acpi_status status; + union acpi_operand_object *obj_desc; + u32 type; + acpi_status status; - FUNCTION_TRACE ("Ex_prep_field_value"); + ACPI_FUNCTION_TRACE ("ex_prep_field_value"); /* Parameter validation */ - if (info->field_type != INTERNAL_TYPE_INDEX_FIELD) { + if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) { if (!info->region_node) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Region_node\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null region_node\n")); return_ACPI_STATUS (AE_AML_NO_OPERAND); } type = acpi_ns_get_type (info->region_node); if (type != ACPI_TYPE_REGION) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X %s\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Needed Region, found type %X %s\n", type, acpi_ut_get_type_name (type))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } } - /* Allocate a new region object */ + /* Allocate a new field object */ obj_desc = acpi_ut_create_internal_object (info->field_type); if (!obj_desc) { @@ -296,8 +352,9 @@ /* Initialize areas of the object that are common to all fields */ + obj_desc->common_field.node = info->field_node; status = acpi_ex_prep_common_field_object (obj_desc, info->field_flags, - info->field_bit_position, info->field_bit_length); + info->attribute, info->field_bit_position, info->field_bit_length); if (ACPI_FAILURE (status)) { acpi_ut_delete_object_desc (obj_desc); return_ACPI_STATUS (status); @@ -306,44 +363,48 @@ /* Initialize areas of the object that are specific to the field type */ switch (info->field_type) { - case INTERNAL_TYPE_REGION_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: - obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node); + obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node); /* An additional reference for the container */ acpi_ut_add_reference (obj_desc->field.region_obj); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Region_field: Bitoff=%X Off=%X Gran=%X Region %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "region_field: Bitoff=%X Off=%X Gran=%X Region %p\n", obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset, - obj_desc->field.access_bit_width, obj_desc->field.region_obj)); + obj_desc->field.access_byte_width, obj_desc->field.region_obj)); break; - case INTERNAL_TYPE_BANK_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: - obj_desc->bank_field.value = info->bank_value; - obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node); - obj_desc->bank_field.bank_register_obj = acpi_ns_get_attached_object (info->register_node); + obj_desc->bank_field.value = info->bank_value; + obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node); + obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (info->register_node); /* An additional reference for the attached objects */ acpi_ut_add_reference (obj_desc->bank_field.region_obj); - acpi_ut_add_reference (obj_desc->bank_field.bank_register_obj); + acpi_ut_add_reference (obj_desc->bank_field.bank_obj); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Bank Field: Bit_off=%X Off=%X Gran=%X Region %p Bank_reg %p\n", - obj_desc->bank_field.start_field_bit_offset, obj_desc->bank_field.base_byte_offset, - obj_desc->field.access_bit_width, obj_desc->bank_field.region_obj, - obj_desc->bank_field.bank_register_obj)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Bank Field: bit_off=%X Off=%X Gran=%X Region %p bank_reg %p\n", + obj_desc->bank_field.start_field_bit_offset, + obj_desc->bank_field.base_byte_offset, + obj_desc->field.access_byte_width, + obj_desc->bank_field.region_obj, + obj_desc->bank_field.bank_obj)); break; - case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node); obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node); - obj_desc->index_field.value = (u32) (info->field_bit_position / - obj_desc->field.access_bit_width); + obj_desc->index_field.value = (u32) + (info->field_bit_position / ACPI_MUL_8 (obj_desc->field.access_byte_width)); if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Index Object\n")); @@ -355,22 +416,29 @@ acpi_ut_add_reference (obj_desc->index_field.data_obj); acpi_ut_add_reference (obj_desc->index_field.index_obj); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Index_field: bitoff=%X off=%X gran=%X Index %p Data %p\n", - obj_desc->index_field.start_field_bit_offset, obj_desc->index_field.base_byte_offset, - obj_desc->field.access_bit_width, obj_desc->index_field.index_obj, + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "index_field: bitoff=%X off=%X gran=%X Index %p Data %p\n", + obj_desc->index_field.start_field_bit_offset, + obj_desc->index_field.base_byte_offset, + obj_desc->field.access_byte_width, + obj_desc->index_field.index_obj, obj_desc->index_field.data_obj)); break; + + default: + /* No other types should get here */ + break; } /* - * Store the constructed descriptor (Obj_desc) into the parent Node, - * preserving the current type of that Named_obj. + * Store the constructed descriptor (obj_desc) into the parent Node, + * preserving the current type of that named_obj. */ status = acpi_ns_attach_object (info->field_node, obj_desc, - (u8) acpi_ns_get_type (info->field_node)); + acpi_ns_get_type (info->field_node)); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "set Named_obj %p (%4.4s) val = %p\n", - info->field_node, (char*)&(info->field_node->name), obj_desc)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "set named_obj %p (%4.4s) val = %p\n", + info->field_node, info->field_node->name.ascii, obj_desc)); /* Remove local reference to the object */ diff -urN linux-2.4.21/drivers/acpi/executer/exregion.c linux-2.4.22/drivers/acpi/executer/exregion.c --- linux-2.4.21/drivers/acpi/executer/exregion.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exregion.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,52 +1,66 @@ /****************************************************************************** * - * Module Name: exregion - ACPI default Op_region (address space) handlers - * $Revision: 61 $ + * Module Name: exregion - ACPI default op_region (address space) handlers * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "achware.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exregion") + ACPI_MODULE_NAME ("exregion") /******************************************************************************* * - * FUNCTION: Acpi_ex_system_memory_space_handler + * FUNCTION: acpi_ex_system_memory_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write - * Bit_width - Field width in bits (8, 16, or 32) + * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value - * Handler_context - Pointer to Handler's context - * Region_context - Pointer to context specific to the + * handler_context - Pointer to Handler's context + * region_context - Pointer to context specific to the * accessed region * * RETURN: Status @@ -57,20 +71,23 @@ acpi_status acpi_ex_system_memory_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context) + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context) { - acpi_status status = AE_OK; - void *logical_addr_ptr = NULL; - acpi_mem_space_context *mem_info = region_context; - u32 length; + acpi_status status = AE_OK; + void *logical_addr_ptr = NULL; + struct acpi_mem_space_context *mem_info = region_context; + u32 length; + acpi_size window_size; +#ifndef ACPI_MISALIGNED_TRANSFERS + u32 remainder; +#endif - - FUNCTION_TRACE ("Ex_system_memory_space_handler"); + ACPI_FUNCTION_TRACE ("ex_system_memory_space_handler"); /* Validate and translate the bit width */ @@ -88,14 +105,28 @@ length = 4; break; + case 64: + length = 8; + break; + default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid System_memory width %d\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid system_memory width %d\n", bit_width)); return_ACPI_STATUS (AE_AML_OPERAND_VALUE); - break; } +#ifndef ACPI_MISALIGNED_TRANSFERS + /* + * Hardware does not support non-aligned data transfers, we must verify + * the request. + */ + (void) acpi_ut_short_divide ((acpi_integer *) &address, length, NULL, &remainder); + if (remainder != 0) { + return_ACPI_STATUS (AE_AML_ALIGNMENT); + } +#endif + /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR @@ -115,61 +146,80 @@ mem_info->mapped_length); } - mem_info->mapped_length = 0; /* In case of failure below */ + /* + * Don't attempt to map memory beyond the end of the region, and + * constrain the maximum mapping size to something reasonable. + */ + window_size = (acpi_size) ((mem_info->address + mem_info->length) - address); + if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) { + window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE; + } /* Create a new mapping starting at the address given */ - status = acpi_os_map_memory (address, SYSMEM_REGION_WINDOW_SIZE, + status = acpi_os_map_memory (address, window_size, (void **) &mem_info->mapped_logical_address); if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n", + ACPI_HIDWORD (address), ACPI_LODWORD (address), (u32) window_size)); + mem_info->mapped_length = 0; return_ACPI_STATUS (status); } /* Save the physical address and mapping size */ mem_info->mapped_physical_address = address; - mem_info->mapped_length = SYSMEM_REGION_WINDOW_SIZE; + mem_info->mapped_length = window_size; } - /* * Generate a logical pointer corresponding to the address we want to * access */ - - /* TBD: should these pointers go to 64-bit in all cases ? */ - logical_addr_ptr = mem_info->mapped_logical_address + ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "System_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, - HIDWORD (address), LODWORD (address))); - - /* Perform the memory read or write */ + "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, + ACPI_HIDWORD (address), ACPI_LODWORD (address))); + /* + * Perform the memory read or write + * + * Note: For machines that do not support non-aligned transfers, the target + * address was checked for alignment above. We do not attempt to break the + * transfer up into smaller (byte-size) chunks because the AML specifically + * asked for a transfer width that the hardware may require. + */ switch (function) { + case ACPI_READ: - case ACPI_READ_ADR_SPACE: - + *value = 0; switch (bit_width) { case 8: - *value = (u32)* (u8 *) logical_addr_ptr; + *value = (acpi_integer) *((u8 *) logical_addr_ptr); break; case 16: - MOVE_UNALIGNED16_TO_32 (value, logical_addr_ptr); + *value = (acpi_integer) *((u16 *) logical_addr_ptr); break; case 32: - MOVE_UNALIGNED32_TO_32 (value, logical_addr_ptr); + *value = (acpi_integer) *((u32 *) logical_addr_ptr); break; - } +#if ACPI_MACHINE_WIDTH != 16 + case 64: + *value = (acpi_integer) *((u64 *) logical_addr_ptr); + break; +#endif + default: + /* bit_width was already validated */ + break; + } break; - - case ACPI_WRITE_ADR_SPACE: + case ACPI_WRITE: switch (bit_width) { case 8: @@ -177,16 +227,24 @@ break; case 16: - MOVE_UNALIGNED16_TO_16 (logical_addr_ptr, value); + *(u16 *) logical_addr_ptr = (u16) *value; break; case 32: - MOVE_UNALIGNED32_TO_32 (logical_addr_ptr, value); + *(u32 *) logical_addr_ptr = (u32) *value; break; - } - break; +#if ACPI_MACHINE_WIDTH != 16 + case 64: + *(u64 *) logical_addr_ptr = (u64) *value; + break; +#endif + default: + /* bit_width was already validated */ + break; + } + break; default: status = AE_BAD_PARAMETER; @@ -199,14 +257,14 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_system_io_space_handler + * FUNCTION: acpi_ex_system_io_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write - * Bit_width - Field width in bits (8, 16, or 32) + * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value - * Handler_context - Pointer to Handler's context - * Region_context - Pointer to context specific to the + * handler_context - Pointer to Handler's context + * region_context - Pointer to context specific to the * accessed region * * RETURN: Status @@ -217,40 +275,38 @@ acpi_status acpi_ex_system_io_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context) + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; + u32 value32; - FUNCTION_TRACE ("Ex_system_io_space_handler"); + ACPI_FUNCTION_TRACE ("ex_system_io_space_handler"); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "System_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, - HIDWORD (address), LODWORD (address))); + "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, + ACPI_HIDWORD (address), ACPI_LODWORD (address))); /* Decode the function parameter */ switch (function) { + case ACPI_READ: - case ACPI_READ_ADR_SPACE: - - *value = 0; - status = acpi_os_read_port ((ACPI_IO_ADDRESS) address, value, bit_width); + status = acpi_os_read_port ((acpi_io_address) address, &value32, bit_width); + *value = value32; break; + case ACPI_WRITE: - case ACPI_WRITE_ADR_SPACE: - - status = acpi_os_write_port ((ACPI_IO_ADDRESS) address, *value, bit_width); + status = acpi_os_write_port ((acpi_io_address) address, (u32) *value, bit_width); break; - default: status = AE_BAD_PARAMETER; break; @@ -262,14 +318,14 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_pci_config_space_handler + * FUNCTION: acpi_ex_pci_config_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write - * Bit_width - Field width in bits (8, 16, or 32) + * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value - * Handler_context - Pointer to Handler's context - * Region_context - Pointer to context specific to the + * handler_context - Pointer to Handler's context + * region_context - Pointer to context specific to the * accessed region * * RETURN: Status @@ -280,56 +336,53 @@ acpi_status acpi_ex_pci_config_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context) + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context) { - acpi_status status = AE_OK; - acpi_pci_id *pci_id; - u16 pci_register; + acpi_status status = AE_OK; + struct acpi_pci_id *pci_id; + u16 pci_register; - FUNCTION_TRACE ("Ex_pci_config_space_handler"); + ACPI_FUNCTION_TRACE ("ex_pci_config_space_handler"); /* - * The arguments to Acpi_os(Read|Write)Pci_cfg(Byte|Word|Dword) are: + * The arguments to acpi_os(Read|Write)pci_configuration are: * - * Pci_segment is the PCI bus segment range 0-31 - * Pci_bus is the PCI bus number range 0-255 - * Pci_device is the PCI device number range 0-31 - * Pci_function is the PCI device function number - * Pci_register is the Config space register range 0-255 bytes + * pci_segment is the PCI bus segment range 0-31 + * pci_bus is the PCI bus number range 0-255 + * pci_device is the PCI device number range 0-31 + * pci_function is the PCI device function number + * pci_register is the Config space register range 0-255 bytes * * Value - input value for write, output address for read * */ - pci_id = (acpi_pci_id *) region_context; - pci_register = (u16) address; + pci_id = (struct acpi_pci_id *) region_context; + pci_register = (u16) (u32) address; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", + "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", function, bit_width, pci_id->segment, pci_id->bus, pci_id->device, pci_id->function, pci_register)); switch (function) { - - case ACPI_READ_ADR_SPACE: + case ACPI_READ: *value = 0; status = acpi_os_read_pci_configuration (pci_id, pci_register, value, bit_width); break; - - case ACPI_WRITE_ADR_SPACE: + case ACPI_WRITE: status = acpi_os_write_pci_configuration (pci_id, pci_register, *value, bit_width); break; - default: status = AE_BAD_PARAMETER; @@ -342,14 +395,14 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_cmos_space_handler + * FUNCTION: acpi_ex_cmos_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write - * Bit_width - Field width in bits (8, 16, or 32) + * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value - * Handler_context - Pointer to Handler's context - * Region_context - Pointer to context specific to the + * handler_context - Pointer to Handler's context + * region_context - Pointer to context specific to the * accessed region * * RETURN: Status @@ -360,17 +413,17 @@ acpi_status acpi_ex_cmos_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context) + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_cmos_space_handler"); + ACPI_FUNCTION_TRACE ("ex_cmos_space_handler"); return_ACPI_STATUS (status); @@ -379,37 +432,97 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_pci_bar_space_handler + * FUNCTION: acpi_ex_pci_bar_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write - * Bit_width - Field width in bits (8, 16, or 32) + * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value - * Handler_context - Pointer to Handler's context - * Region_context - Pointer to context specific to the + * handler_context - Pointer to Handler's context + * region_context - Pointer to context specific to the * accessed region * * RETURN: Status * - * DESCRIPTION: Handler for the PCI Bar_target address space (Op Region) + * DESCRIPTION: Handler for the PCI bar_target address space (Op Region) * ******************************************************************************/ acpi_status acpi_ex_pci_bar_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context) + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_pci_bar_space_handler"); + ACPI_FUNCTION_TRACE ("ex_pci_bar_space_handler"); return_ACPI_STATUS (status); } + +/******************************************************************************* + * + * FUNCTION: acpi_ex_data_table_space_handler + * + * PARAMETERS: Function - Read or Write operation + * Address - Where in the space to read or write + * bit_width - Field width in bits (8, 16, or 32) + * Value - Pointer to in or out value + * handler_context - Pointer to Handler's context + * region_context - Pointer to context specific to the + * accessed region + * + * RETURN: Status + * + * DESCRIPTION: Handler for the Data Table address space (Op Region) + * + ******************************************************************************/ + +acpi_status +acpi_ex_data_table_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context) +{ + acpi_status status = AE_OK; + u32 byte_width = ACPI_DIV_8 (bit_width); + u32 i; + char *logical_addr_ptr; + + + ACPI_FUNCTION_TRACE ("ex_data_table_space_handler"); + + + logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address); + + + /* Perform the memory read or write */ + + switch (function) { + case ACPI_READ: + + for (i = 0; i < byte_width; i++) { + ((char *) value) [i] = logical_addr_ptr[i]; + } + break; + + case ACPI_WRITE: + default: + + return_ACPI_STATUS (AE_SUPPORT); + } + + return_ACPI_STATUS (status); +} + + diff -urN linux-2.4.21/drivers/acpi/executer/exresnte.c linux-2.4.22/drivers/acpi/executer/exresnte.c --- linux-2.4.21/drivers/acpi/executer/exresnte.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exresnte.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,51 +2,65 @@ /****************************************************************************** * * Module Name: exresnte - AML Interpreter object resolution - * $Revision: 43 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" -#include "acevents.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exresnte") + ACPI_MODULE_NAME ("exresnte") /******************************************************************************* * - * FUNCTION: Acpi_ex_resolve_node_to_value + * FUNCTION: acpi_ex_resolve_node_to_value * - * PARAMETERS: Object_ptr - Pointer to a location that contains + * PARAMETERS: object_ptr - Pointer to a location that contains * a pointer to a NS node, and will receive a * pointer to the resolved object. - * Walk_state - Current state. Valid only if executing AML + * walk_state - Current state. Valid only if executing AML * code. NULL if simply resolving an object * * RETURN: Status @@ -67,32 +81,39 @@ acpi_status acpi_ex_resolve_node_to_value ( - acpi_namespace_node **object_ptr, - acpi_walk_state *walk_state) + struct acpi_namespace_node **object_ptr, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object *source_desc; - acpi_operand_object *obj_desc = NULL; - acpi_namespace_node *node; - acpi_object_type8 entry_type; - acpi_integer temp_val; + acpi_status status = AE_OK; + union acpi_operand_object *source_desc; + union acpi_operand_object *obj_desc = NULL; + struct acpi_namespace_node *node; + acpi_object_type entry_type; - FUNCTION_TRACE ("Ex_resolve_node_to_value"); + ACPI_FUNCTION_TRACE ("ex_resolve_node_to_value"); /* - * The stack pointer points to a acpi_namespace_node (Node). Get the + * The stack pointer points to a struct acpi_namespace_node (Node). Get the * object that is attached to the Node. */ - node = *object_ptr; - source_desc = acpi_ns_get_attached_object (node); + node = *object_ptr; + source_desc = acpi_ns_get_attached_object (node); entry_type = acpi_ns_get_type ((acpi_handle) node); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p Source_desc=%p Type=%X\n", - node, source_desc, entry_type)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p source_desc=%p [%s]\n", + node, source_desc, acpi_ut_get_type_name (entry_type))); + if (entry_type == ACPI_TYPE_LOCAL_ALIAS) { + /* There is always exactly one level of indirection */ + + node = (struct acpi_namespace_node *) node->object; + source_desc = acpi_ns_get_attached_object (node); + entry_type = acpi_ns_get_type ((acpi_handle) node); + *object_ptr = node; + } /* * Several object types require no further processing: @@ -115,42 +136,47 @@ * of the attached object or pointer */ switch (entry_type) { - case ACPI_TYPE_PACKAGE: - if (ACPI_TYPE_PACKAGE != source_desc->common.type) { + if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_PACKAGE) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Package, type %s\n", - acpi_ut_get_type_name (source_desc->common.type))); + acpi_ut_get_object_type_name (source_desc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* Return an additional reference to the object */ + status = acpi_ds_get_package_arguments (source_desc); + if (ACPI_SUCCESS (status)) { + /* Return an additional reference to the object */ - obj_desc = source_desc; - acpi_ut_add_reference (obj_desc); + obj_desc = source_desc; + acpi_ut_add_reference (obj_desc); + } break; case ACPI_TYPE_BUFFER: - if (ACPI_TYPE_BUFFER != source_desc->common.type) { + if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Buffer, type %s\n", - acpi_ut_get_type_name (source_desc->common.type))); + acpi_ut_get_object_type_name (source_desc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* Return an additional reference to the object */ + status = acpi_ds_get_buffer_arguments (source_desc); + if (ACPI_SUCCESS (status)) { + /* Return an additional reference to the object */ - obj_desc = source_desc; - acpi_ut_add_reference (obj_desc); + obj_desc = source_desc; + acpi_ut_add_reference (obj_desc); + } break; case ACPI_TYPE_STRING: - if (ACPI_TYPE_STRING != source_desc->common.type) { + if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a String, type %s\n", - acpi_ut_get_type_name (source_desc->common.type))); + acpi_ut_get_object_type_name (source_desc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -163,9 +189,9 @@ case ACPI_TYPE_INTEGER: - if (ACPI_TYPE_INTEGER != source_desc->common.type) { + if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Integer, type %s\n", - acpi_ut_get_type_name (source_desc->common.type))); + acpi_ut_get_object_type_name (source_desc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -177,17 +203,16 @@ case ACPI_TYPE_BUFFER_FIELD: - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Field_read Node=%p Source_desc=%p Type=%X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read Node=%p source_desc=%p Type=%X\n", node, source_desc, entry_type)); - status = acpi_ex_read_data_from_field (source_desc, &obj_desc); + status = acpi_ex_read_data_from_field (walk_state, source_desc, &obj_desc); break; - /* * For these objects, just return the object attached to the Node */ @@ -206,7 +231,7 @@ break; - /* TYPE_Any is untyped, and thus there is no object associated with it */ + /* TYPE_ANY is untyped, and thus there is no object associated with it */ case ACPI_TYPE_ANY: @@ -214,64 +239,16 @@ node)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ - break; - - - /* - * The only named references allowed are named constants - * e.g. -- Name (\OSFL, Ones) - */ - case INTERNAL_TYPE_REFERENCE: - switch (source_desc->reference.opcode) { - case AML_ZERO_OP: + case ACPI_TYPE_LOCAL_REFERENCE: - temp_val = 0; - break; + /* No named references are allowed here */ - case AML_ONE_OP: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X\n", + source_desc->reference.opcode)); - temp_val = 1; - break; - - case AML_ONES_OP: - - temp_val = ACPI_INTEGER_MAX; - break; - - case AML_REVISION_OP: - - temp_val = ACPI_CA_SUPPORT_LEVEL; - break; - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n", - source_desc->reference.opcode)); - - return_ACPI_STATUS (AE_AML_BAD_OPCODE); - } - - /* Create object for result */ - - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - obj_desc->integer.value = temp_val; - - /* - * Truncate value if we are executing from a 32-bit ACPI table - * AND actually executing AML code. If we are resolving - * an object in the namespace via an external call to the - * subsystem, we will have a null Walk_state - */ - if (walk_state) { - acpi_ex_truncate_for32bit_table (obj_desc, walk_state); - } - break; + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); /* Default case is for unknown types */ @@ -283,7 +260,7 @@ return_ACPI_STATUS (AE_AML_OPERAND_TYPE); - } /* switch (Entry_type) */ + } /* switch (entry_type) */ /* Put the object descriptor on the stack */ diff -urN linux-2.4.21/drivers/acpi/executer/exresolv.c linux-2.4.22/drivers/acpi/executer/exresolv.c --- linux-2.4.21/drivers/acpi/executer/exresolv.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exresolv.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,156 +2,66 @@ /****************************************************************************** * * Module Name: exresolv - AML Interpreter object resolution - * $Revision: 101 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" -#include "acevents.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exresolv") + ACPI_MODULE_NAME ("exresolv") /******************************************************************************* * - * FUNCTION: Acpi_ex_get_buffer_field_value + * FUNCTION: acpi_ex_resolve_to_value * - * PARAMETERS: *Obj_desc - Pointer to a Buffer_field - * *Result_desc - Pointer to an empty descriptor which will - * become an Integer with the field's value - * - * RETURN: Status - * - * DESCRIPTION: Retrieve the value from a Buffer_field - * - ******************************************************************************/ - -acpi_status -acpi_ex_get_buffer_field_value ( - acpi_operand_object *obj_desc, - acpi_operand_object *result_desc) -{ - acpi_status status; - u32 mask; - u8 *location; - - - FUNCTION_TRACE ("Ex_get_buffer_field_value"); - - - /* - * Parameter validation - */ - if (!obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null field pointer\n")); - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } - - if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { - status = acpi_ds_get_buffer_field_arguments (obj_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - } - - if (!obj_desc->buffer_field.buffer_obj) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null container pointer\n")); - return_ACPI_STATUS (AE_AML_INTERNAL); - } - - if (ACPI_TYPE_BUFFER != obj_desc->buffer_field.buffer_obj->common.type) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - container is not a Buffer\n")); - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); - } - - if (!result_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null result pointer\n")); - return_ACPI_STATUS (AE_AML_INTERNAL); - } - - - /* Field location is (base of buffer) + (byte offset) */ - - location = obj_desc->buffer_field.buffer_obj->buffer.pointer - + obj_desc->buffer_field.base_byte_offset; - - /* - * Construct Mask with as many 1 bits as the field width - * - * NOTE: Only the bottom 5 bits are valid for a shift operation, so - * special care must be taken for any shift greater than 31 bits. - * - * TBD: [Unhandled] Fields greater than 32 bits will not work. - */ - if (obj_desc->buffer_field.bit_length < 32) { - mask = ((u32) 1 << obj_desc->buffer_field.bit_length) - (u32) 1; - } - else { - mask = ACPI_UINT32_MAX; - } - - result_desc->integer.type = (u8) ACPI_TYPE_INTEGER; - - /* Get the 32 bit value at the location */ - - MOVE_UNALIGNED32_TO_32 (&result_desc->integer.value, location); - - /* - * Shift the 32-bit word containing the field, and mask off the - * resulting value - */ - result_desc->integer.value = - (result_desc->integer.value >> obj_desc->buffer_field.start_field_bit_offset) & mask; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "** Read from buffer %p byte %d bit %d width %d addr %p mask %08X val %8.8X%8.8X\n", - obj_desc->buffer_field.buffer_obj->buffer.pointer, - obj_desc->buffer_field.base_byte_offset, - obj_desc->buffer_field.start_field_bit_offset, - obj_desc->buffer_field.bit_length, - location, mask, - HIDWORD(result_desc->integer.value), - LODWORD(result_desc->integer.value))); - - return_ACPI_STATUS (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_resolve_to_value - * - * PARAMETERS: **Stack_ptr - Points to entry on Obj_stack, which can - * be either an (acpi_operand_object *) + * PARAMETERS: **stack_ptr - Points to entry on obj_stack, which can + * be either an (union acpi_operand_object *) * or an acpi_handle. - * Walk_state - Current method state + * walk_state - Current method state * * RETURN: Status * @@ -161,13 +71,13 @@ acpi_status acpi_ex_resolve_to_value ( - acpi_operand_object **stack_ptr, - acpi_walk_state *walk_state) + union acpi_operand_object **stack_ptr, + struct acpi_walk_state *walk_state) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE_PTR ("Ex_resolve_to_value", stack_ptr); + ACPI_FUNCTION_TRACE_PTR ("ex_resolve_to_value", stack_ptr); if (!stack_ptr || !*stack_ptr) { @@ -175,13 +85,12 @@ return_ACPI_STATUS (AE_AML_NO_OPERAND); } - /* - * The entity pointed to by the Stack_ptr can be either - * 1) A valid acpi_operand_object, or - * 2) A acpi_namespace_node (Named_obj) + * The entity pointed to by the stack_ptr can be either + * 1) A valid union acpi_operand_object, or + * 2) A struct acpi_namespace_node (named_obj) */ - if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_INTERNAL)) { + if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_OPERAND) { status = acpi_ex_resolve_object_to_value (stack_ptr, walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); @@ -189,30 +98,30 @@ } /* - * Object on the stack may have changed if Acpi_ex_resolve_object_to_value() + * Object on the stack may have changed if acpi_ex_resolve_object_to_value() * was called (i.e., we can't use an _else_ here.) */ - if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_NAMED)) { - status = acpi_ex_resolve_node_to_value ((acpi_namespace_node **) stack_ptr, + if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_NAMED) { + status = acpi_ex_resolve_node_to_value ( + ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, stack_ptr), walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Resolved object %p\n", *stack_ptr)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr)); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_resolve_object_to_value + * FUNCTION: acpi_ex_resolve_object_to_value * - * PARAMETERS: Stack_ptr - Pointer to a stack location that contains a + * PARAMETERS: stack_ptr - Pointer to a stack location that contains a * ptr to an internal object. - * Walk_state - Current method state + * walk_state - Current method state * * RETURN: Status * @@ -223,36 +132,34 @@ acpi_status acpi_ex_resolve_object_to_value ( - acpi_operand_object **stack_ptr, - acpi_walk_state *walk_state) + union acpi_operand_object **stack_ptr, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object *stack_desc; - void *temp_node; - acpi_operand_object *obj_desc; - u16 opcode; + acpi_status status = AE_OK; + union acpi_operand_object *stack_desc; + void *temp_node; + union acpi_operand_object *obj_desc; + u16 opcode; - FUNCTION_TRACE ("Ex_resolve_object_to_value"); + ACPI_FUNCTION_TRACE ("ex_resolve_object_to_value"); stack_desc = *stack_ptr; - /* This is an acpi_operand_object */ + /* This is an union acpi_operand_object */ - switch (stack_desc->common.type) { - - case INTERNAL_TYPE_REFERENCE: + switch (ACPI_GET_OBJECT_TYPE (stack_desc)) { + case ACPI_TYPE_LOCAL_REFERENCE: opcode = stack_desc->reference.opcode; switch (opcode) { - case AML_NAME_OP: /* * Convert indirect name ptr to a direct name ptr. - * Then, Acpi_ex_resolve_node_to_value can be used to get the value + * Then, acpi_ex_resolve_node_to_value can be used to get the value */ temp_node = stack_desc->reference.object; @@ -286,58 +193,11 @@ acpi_ut_remove_reference (stack_desc); *stack_ptr = obj_desc; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "[Arg/Local %d] Value_obj is %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %d] value_obj is %p\n", stack_desc->reference.offset, obj_desc)); break; - /* - * For constants, we must change the reference/constant object - * to a real integer object - */ - case AML_ZERO_OP: - case AML_ONE_OP: - case AML_ONES_OP: - case AML_REVISION_OP: - - /* Create a new integer object */ - - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - switch (opcode) { - case AML_ZERO_OP: - obj_desc->integer.value = 0; - break; - - case AML_ONE_OP: - obj_desc->integer.value = 1; - break; - - case AML_ONES_OP: - obj_desc->integer.value = ACPI_INTEGER_MAX; - - /* Truncate value if we are executing from a 32-bit ACPI table */ - - acpi_ex_truncate_for32bit_table (obj_desc, walk_state); - break; - - case AML_REVISION_OP: - obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL; - break; - } - - /* - * Remove a reference from the original reference object - * and put the new object in its place - */ - acpi_ut_remove_reference (stack_desc); - *stack_ptr = obj_desc; - break; - - case AML_INDEX_OP: switch (stack_desc->reference.target_type) { @@ -348,6 +208,7 @@ case ACPI_TYPE_PACKAGE: + obj_desc = *stack_desc->reference.where; if (obj_desc) { /* @@ -359,7 +220,6 @@ acpi_ut_add_reference (obj_desc); *stack_ptr = obj_desc; } - else { /* * A NULL object descriptor means an unitialized element of @@ -372,83 +232,243 @@ } break; + default: + /* Invalid reference object */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown Target_type %X in Index/Reference obj %p\n", + "Unknown target_type %X in Index/Reference obj %p\n", stack_desc->reference.target_type, stack_desc)); status = AE_AML_INTERNAL; break; } - break; + case AML_REF_OF_OP: case AML_DEBUG_OP: /* Just leave the object as-is */ + break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference object subtype %02X in %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X in %p\n", opcode, stack_desc)); status = AE_AML_INTERNAL; break; + } + break; - } /* switch (Opcode) */ - break; /* case INTERNAL_TYPE_REFERENCE */ + case ACPI_TYPE_BUFFER: + status = acpi_ds_get_buffer_arguments (stack_desc); + break; - case ACPI_TYPE_BUFFER_FIELD: - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_ANY); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } + case ACPI_TYPE_PACKAGE: + + status = acpi_ds_get_package_arguments (stack_desc); + break; - status = acpi_ex_get_buffer_field_value (stack_desc, obj_desc); - if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); - obj_desc = NULL; - } + /* + * These cases may never happen here, but just in case.. + */ + case ACPI_TYPE_BUFFER_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read source_desc=%p Type=%X\n", + stack_desc, ACPI_GET_OBJECT_TYPE (stack_desc))); + + status = acpi_ex_read_data_from_field (walk_state, stack_desc, &obj_desc); *stack_ptr = (void *) obj_desc; break; + default: + break; + } - case INTERNAL_TYPE_BANK_FIELD: + return_ACPI_STATUS (status); +} - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_ANY); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - /* TBD: WRONG! */ +/******************************************************************************* + * + * FUNCTION: acpi_ex_resolve_multiple + * + * PARAMETERS: walk_state - Current state (contains AML opcode) + * Operand - Starting point for resolution + * return_type - Where the object type is returned + * return_desc - Where the resolved object is returned + * + * RETURN: Status + * + * DESCRIPTION: Return the base object and type. Traverse a reference list if + * necessary to get to the base object. + * + ******************************************************************************/ - status = acpi_ex_get_buffer_field_value (stack_desc, obj_desc); - if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); - obj_desc = NULL; +acpi_status +acpi_ex_resolve_multiple ( + struct acpi_walk_state *walk_state, + union acpi_operand_object *operand, + acpi_object_type *return_type, + union acpi_operand_object **return_desc) +{ + union acpi_operand_object *obj_desc = (void *) operand; + struct acpi_namespace_node *node; + acpi_object_type type; + + + ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple"); + + + /* + * For reference objects created via the ref_of or Index operators, + * we need to get to the base object (as per the ACPI specification + * of the object_type and size_of operators). This means traversing + * the list of possibly many nested references. + */ + while (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { + switch (obj_desc->reference.opcode) { + case AML_REF_OF_OP: + + /* Dereference the reference pointer */ + + node = obj_desc->reference.object; + + /* All "References" point to a NS node */ + + if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) { + return_ACPI_STATUS (AE_AML_INTERNAL); + } + + /* Get the attached object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, use the NS node type */ + + type = acpi_ns_get_type (node); + goto exit; + } + + /* Check for circular references */ + + if (obj_desc == operand) { + return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE); + } + break; + + + case AML_INDEX_OP: + + /* Get the type of this reference (index into another object) */ + + type = obj_desc->reference.target_type; + if (type != ACPI_TYPE_PACKAGE) { + goto exit; + } + + /* + * The main object is a package, we want to get the type + * of the individual package element that is referenced by + * the index. + * + * This could of course in turn be another reference object. + */ + obj_desc = *(obj_desc->reference.where); + break; + + + case AML_INT_NAMEPATH_OP: + + /* Dereference the reference pointer */ + + node = obj_desc->reference.node; + + /* All "References" point to a NS node */ + + if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) { + return_ACPI_STATUS (AE_AML_INTERNAL); + } + + /* Get the attached object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, use the NS node type */ + + type = acpi_ns_get_type (node); + goto exit; + } + + /* Check for circular references */ + + if (obj_desc == operand) { + return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE); + } + break; + + + case AML_DEBUG_OP: + + /* The Debug Object is of type "debug_object" */ + + type = ACPI_TYPE_DEBUG_OBJECT; + goto exit; + + + default: + + ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n", + obj_desc->reference.opcode)); + return_ACPI_STATUS (AE_AML_INTERNAL); } + } - *stack_ptr = (void *) obj_desc; - break; + /* + * Now we are guaranteed to have an object that has not been created + * via the ref_of or Index operators. + */ + type = ACPI_GET_OBJECT_TYPE (obj_desc); - /* TBD: [Future] - may need to handle Index_field, and Def_field someday */ +exit: + /* Convert internal types to external types */ - default: + switch (type) { + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + type = ACPI_TYPE_FIELD_UNIT; break; - } /* switch (Stack_desc->Common.Type) */ + case ACPI_TYPE_LOCAL_SCOPE: + /* Per ACPI Specification, Scope is untyped */ - return_ACPI_STATUS (status); + type = ACPI_TYPE_ANY; + break; + + default: + /* No change to Type required */ + break; + } + + *return_type = type; + if (return_desc) { + *return_desc = obj_desc; + } + return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/executer/exresop.c linux-2.4.22/drivers/acpi/executer/exresop.c --- linux-2.4.21/drivers/acpi/executer/exresop.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exresop.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,49 +2,63 @@ /****************************************************************************** * * Module Name: exresop - AML Interpreter operand/object resolution - * $Revision: 41 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" -#include "acevents.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exresop") + ACPI_MODULE_NAME ("exresop") /******************************************************************************* * - * FUNCTION: Acpi_ex_check_object_type + * FUNCTION: acpi_ex_check_object_type * - * PARAMETERS: Type_needed Object type needed - * This_type Actual object type + * PARAMETERS: type_needed Object type needed + * this_type Actual object type * Object Object pointer * * RETURN: Status @@ -55,11 +69,11 @@ acpi_status acpi_ex_check_object_type ( - acpi_object_type type_needed, - acpi_object_type this_type, - void *object) + acpi_object_type type_needed, + acpi_object_type this_type, + void *object) { - PROC_NAME ("Ex_check_object_type"); + ACPI_FUNCTION_NAME ("ex_check_object_type"); if (type_needed == ACPI_TYPE_ANY) { @@ -68,8 +82,20 @@ return (AE_OK); } + if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) { + /* + * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference + * objects and thus allow them to be targets. (As per the ACPI + * specification, a store to a constant is a noop.) + */ + if ((this_type == ACPI_TYPE_INTEGER) && + (((union acpi_operand_object *) object)->common.flags & AOPOBJ_AML_CONSTANT)) { + return (AE_OK); + } + } + if (type_needed != this_type) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed [%s], found [%s] %p\n", acpi_ut_get_type_name (type_needed), acpi_ut_get_type_name (this_type), object)); @@ -83,40 +109,42 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_resolve_operands + * FUNCTION: acpi_ex_resolve_operands * - * PARAMETERS: Opcode Opcode being interpreted - * Stack_ptr Top of operand stack + * PARAMETERS: Opcode - Opcode being interpreted + * stack_ptr - Pointer to the operand stack to be + * resolved + * walk_state - Current state * * RETURN: Status * - * DESCRIPTION: Convert stack entries to required types - * - * Each nibble in Arg_types represents one required operand - * and indicates the required Type: + * DESCRIPTION: Convert multiple input operands to the types required by the + * target operator. * - * The corresponding stack entry will be converted to the - * required type if possible, else return an exception + * Each 5-bit group in arg_types represents one required + * operand and indicates the required Type. The corresponding operand + * will be converted to the required type if possible, otherwise we + * abort with an exception. * ******************************************************************************/ acpi_status acpi_ex_resolve_operands ( - u16 opcode, - acpi_operand_object **stack_ptr, - acpi_walk_state *walk_state) + u16 opcode, + union acpi_operand_object **stack_ptr, + struct acpi_walk_state *walk_state) { - acpi_operand_object *obj_desc; - acpi_status status = AE_OK; - u8 object_type; - void *temp_node; - u32 arg_types; - const acpi_opcode_info *op_info; - u32 this_arg_type; - acpi_object_type type_needed; + union acpi_operand_object *obj_desc; + acpi_status status = AE_OK; + u8 object_type; + void *temp_node; + u32 arg_types; + const struct acpi_opcode_info *op_info; + u32 this_arg_type; + acpi_object_type type_needed; - FUNCTION_TRACE_U32 ("Ex_resolve_operands", opcode); + ACPI_FUNCTION_TRACE_U32 ("ex_resolve_operands", opcode); op_info = acpi_ps_get_opcode_info (opcode); @@ -124,7 +152,6 @@ return_ACPI_STATUS (AE_AML_BAD_OPCODE); } - arg_types = op_info->runtime_args; if (arg_types == ARGI_INVALID_OPCODE) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - %X is not a valid AML opcode\n", @@ -133,12 +160,11 @@ return_ACPI_STATUS (AE_AML_INTERNAL); } - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X Operand_types=%X \n", - opcode, arg_types)); - + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] operand_types=%X \n", + opcode, op_info->name, arg_types)); /* - * Normal exit is with (Arg_types == 0) at end of argument list. + * Normal exit is with (arg_types == 0) at end of argument list. * Function will return an exception from within the loop upon * finding an entry which is not (or cannot be converted * to) the required type; if stack underflows; or upon @@ -158,27 +184,31 @@ /* Decode the descriptor type */ - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { + switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) { + case ACPI_DESC_TYPE_NAMED: + /* Node */ - object_type = ((acpi_namespace_node *) obj_desc)->type; - } + object_type = ((struct acpi_namespace_node *) obj_desc)->type; + break; + + + case ACPI_DESC_TYPE_OPERAND: - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { /* ACPI internal object */ - object_type = obj_desc->common.type; + object_type = ACPI_GET_OBJECT_TYPE (obj_desc); /* Check for bad acpi_object_type */ - if (!acpi_ex_validate_object_type (object_type)) { + if (!acpi_ut_valid_object_type (object_type)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad operand object type [%X]\n", object_type)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - if (object_type == (u8) INTERNAL_TYPE_REFERENCE) { + if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) { /* * Decode the Reference */ @@ -187,39 +217,36 @@ return_ACPI_STATUS (AE_AML_BAD_OPCODE); } - switch (obj_desc->reference.opcode) { - case AML_ZERO_OP: - case AML_ONE_OP: - case AML_ONES_OP: case AML_DEBUG_OP: case AML_NAME_OP: case AML_INDEX_OP: + case AML_REF_OF_OP: case AML_ARG_OP: case AML_LOCAL_OP: - case AML_REVISION_OP: - DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Reference Opcode: %s\n", op_info->name))); break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Reference Opcode: Unknown [%02x]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unknown Reference Opcode %X\n", obj_desc->reference.opcode)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); - break; } } - } + break; + + + default: - else { /* Invalid descriptor */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad descriptor type %X in Obj %p\n", - obj_desc->common.data_type, obj_desc)); + ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -231,34 +258,45 @@ this_arg_type = GET_CURRENT_ARG_TYPE (arg_types); INCREMENT_ARG_LIST (arg_types); - /* * Handle cases where the object does not need to be * resolved to a value */ switch (this_arg_type) { + case ARGI_REF_OR_STRING: /* Can be a String or Reference */ - case ARGI_REFERENCE: /* References */ + if ((ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) && + (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_STRING)) { + /* + * String found - the string references a named object and must be + * resolved to a node + */ + goto next_operand; + } + + /* Else not a string - fall through to the normal Reference case below */ + /*lint -fallthrough */ + + case ARGI_REFERENCE: /* References: */ case ARGI_INTEGER_REF: case ARGI_OBJECT_REF: case ARGI_DEVICE_REF: - case ARGI_TARGETREF: /* TBD: must implement implicit conversion rules before store */ + case ARGI_TARGETREF: /* Allows implicit conversion rules before store */ case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ - case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */ + case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */ - /* Need an operand of type INTERNAL_TYPE_REFERENCE */ + /* Need an operand of type ACPI_TYPE_LOCAL_REFERENCE */ - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) /* direct name ptr OK as-is */ { + if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) /* Node (name) ptr OK as-is */ { goto next_operand; } - status = acpi_ex_check_object_type (INTERNAL_TYPE_REFERENCE, + status = acpi_ex_check_object_type (ACPI_TYPE_LOCAL_REFERENCE, object_type, obj_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - if (AML_NAME_OP == obj_desc->reference.opcode) { /* * Convert an indirect name ptr to direct name ptr and put @@ -268,25 +306,27 @@ acpi_ut_remove_reference (obj_desc); (*stack_ptr) = temp_node; } - goto next_operand; - break; case ARGI_ANYTYPE: /* - * We don't want to resolve Index_op reference objects during - * a store because this would be an implicit De_ref_of operation. + * We don't want to resolve index_op reference objects during + * a store because this would be an implicit de_ref_of operation. * Instead, we just want to store the reference object. * -- All others must be resolved below. */ if ((opcode == AML_STORE_OP) && - ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) && + (ACPI_GET_OBJECT_TYPE (*stack_ptr) == ACPI_TYPE_LOCAL_REFERENCE) && ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) { goto next_operand; } break; + + default: + /* All cases covered above */ + break; } @@ -298,6 +338,9 @@ return_ACPI_STATUS (status); } + /* Get the resolved object */ + + obj_desc = *stack_ptr; /* * Check the resulting object (value) type @@ -321,20 +364,6 @@ type_needed = ACPI_TYPE_EVENT; break; - case ARGI_REGION: - - /* Need an operand of type ACPI_TYPE_REGION */ - - type_needed = ACPI_TYPE_REGION; - break; - - case ARGI_IF: /* If */ - - /* Need an operand of type INTERNAL_TYPE_IF */ - - type_needed = INTERNAL_TYPE_IF; - break; - case ARGI_PACKAGE: /* Package */ /* Need an operand of type ACPI_TYPE_PACKAGE */ @@ -358,22 +387,21 @@ /* * Need an operand of type ACPI_TYPE_INTEGER, * But we can implicitly convert from a STRING or BUFFER + * Aka - "Implicit Source Operand Conversion" */ - status = acpi_ex_convert_to_integer (*stack_ptr, stack_ptr, walk_state); + status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, walk_state); if (ACPI_FAILURE (status)) { if (status == AE_TYPE) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr)); + acpi_ut_get_object_type_name (obj_desc), obj_desc)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } return_ACPI_STATUS (status); } - goto next_operand; - break; case ARGI_BUFFER: @@ -381,22 +409,21 @@ /* * Need an operand of type ACPI_TYPE_BUFFER, * But we can implicitly convert from a STRING or INTEGER + * Aka - "Implicit Source Operand Conversion" */ - status = acpi_ex_convert_to_buffer (*stack_ptr, stack_ptr, walk_state); + status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state); if (ACPI_FAILURE (status)) { if (status == AE_TYPE) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr)); + acpi_ut_get_object_type_name (obj_desc), obj_desc)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } return_ACPI_STATUS (status); } - goto next_operand; - break; case ARGI_STRING: @@ -404,95 +431,146 @@ /* * Need an operand of type ACPI_TYPE_STRING, * But we can implicitly convert from a BUFFER or INTEGER + * Aka - "Implicit Source Operand Conversion" */ - status = acpi_ex_convert_to_string (*stack_ptr, stack_ptr, 16, ACPI_UINT32_MAX, walk_state); + status = acpi_ex_convert_to_string (obj_desc, stack_ptr, 16, ACPI_UINT32_MAX, walk_state); if (ACPI_FAILURE (status)) { if (status == AE_TYPE) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr)); + acpi_ut_get_object_type_name (obj_desc), obj_desc)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } return_ACPI_STATUS (status); } - goto next_operand; - break; case ARGI_COMPUTEDATA: /* Need an operand of type INTEGER, STRING or BUFFER */ - if ((ACPI_TYPE_INTEGER != (*stack_ptr)->common.type) && - (ACPI_TYPE_STRING != (*stack_ptr)->common.type) && - (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + + /* Valid operand */ + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr)); + acpi_ut_get_object_type_name (obj_desc), obj_desc)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } goto next_operand; - break; - case ARGI_DATAOBJECT: - /* - * ARGI_DATAOBJECT is only used by the Size_of operator. - * - * The ACPI specification allows Size_of to return the size of - * a Buffer, String or Package. However, the MS ACPI.SYS AML - * Interpreter also allows an Node reference to return without - * error with a size of 4. - */ + case ARGI_BUFFER_OR_STRING: + + /* Need an operand of type STRING or BUFFER */ + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: - /* Need a buffer, string, package or Node reference */ + /* Valid operand */ + break; - if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) && - ((*stack_ptr)->common.type != ACPI_TYPE_STRING) && - ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) && - ((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Needed [Buf/Str/Pkg/Ref], found [%s] %p\n", - acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr)); + case ACPI_TYPE_INTEGER: + + /* Highest priority conversion is to type Buffer */ + + status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Needed [Integer/String/Buffer], found [%s] %p\n", + acpi_ut_get_object_type_name (obj_desc), obj_desc)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } + goto next_operand; + + case ARGI_DATAOBJECT: /* - * If this is a reference, only allow a reference to an Node. + * ARGI_DATAOBJECT is only used by the size_of operator. + * Need a buffer, string, package, or ref_of reference. + * + * The only reference allowed here is a direct reference to + * a namespace node. */ - if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) { - if (!(*stack_ptr)->reference.node) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Needed [Node Reference], found [%p]\n", - *stack_ptr)); + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_PACKAGE: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + case ACPI_TYPE_LOCAL_REFERENCE: + + /* Valid operand */ + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Needed [Buffer/String/Package/Reference], found [%s] %p\n", + acpi_ut_get_object_type_name (obj_desc), obj_desc)); - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); - } + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } goto next_operand; - break; case ARGI_COMPLEXOBJ: /* Need a buffer or package or (ACPI 2.0) String */ - if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) && - ((*stack_ptr)->common.type != ACPI_TYPE_STRING) && - ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Needed [Buf/Pkg], found [%s] %p\n", - acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr)); + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_PACKAGE: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + + /* Valid operand */ + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Needed [Buffer/String/Package], found [%s] %p\n", + acpi_ut_get_object_type_name (obj_desc), obj_desc)); + + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + } + goto next_operand; + + + case ARGI_REGION_OR_FIELD: + + /* Need an operand of type ACPI_TYPE_REGION or a FIELD in a region */ + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_REGION: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + /* Valid operand */ + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Needed [Region/region_field], found [%s] %p\n", + acpi_ut_get_object_type_name (obj_desc), obj_desc)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } goto next_operand; - break; default: @@ -500,27 +578,25 @@ /* Unknown type */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Internal - Unknown ARGI type %X\n", + "Internal - Unknown ARGI (required operand) type %X\n", this_arg_type)); return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* * Make sure that the original object was resolved to the * required object type (Simple cases only). */ status = acpi_ex_check_object_type (type_needed, - (*stack_ptr)->common.type, *stack_ptr); + ACPI_GET_OBJECT_TYPE (*stack_ptr), *stack_ptr); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - next_operand: /* - * If more operands needed, decrement Stack_ptr to point + * If more operands needed, decrement stack_ptr to point * to next operand on stack */ if (GET_CURRENT_ARG_TYPE (arg_types)) { @@ -529,7 +605,6 @@ } /* while (*Types) */ - return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/executer/exstore.c linux-2.4.22/drivers/acpi/executer/exstore.c --- linux-2.4.21/drivers/acpi/executer/exstore.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/executer/exstore.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,113 +2,142 @@ /****************************************************************************** * * Module Name: exstore - AML Interpreter object store support - * $Revision: 150 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "actables.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exstore") + ACPI_MODULE_NAME ("exstore") /******************************************************************************* * - * FUNCTION: Acpi_ex_store + * FUNCTION: acpi_ex_store * - * PARAMETERS: *Source_desc - Value to be stored - * *Dest_desc - Where to store it. Must be an NS node - * or an acpi_operand_object of type + * PARAMETERS: *source_desc - Value to be stored + * *dest_desc - Where to store it. Must be an NS node + * or an union acpi_operand_object of type * Reference; + * walk_state - Current walk state * * RETURN: Status * - * DESCRIPTION: Store the value described by Source_desc into the location - * described by Dest_desc. Called by various interpreter + * DESCRIPTION: Store the value described by source_desc into the location + * described by dest_desc. Called by various interpreter * functions to store the result of an operation into - * the destination operand. + * the destination operand -- not just simply the actual "Store" + * ASL operator. * ******************************************************************************/ acpi_status acpi_ex_store ( - acpi_operand_object *source_desc, - acpi_operand_object *dest_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *source_desc, + union acpi_operand_object *dest_desc, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object *ref_desc = dest_desc; + acpi_status status = AE_OK; + union acpi_operand_object *ref_desc = dest_desc; - FUNCTION_TRACE_PTR ("Ex_store", dest_desc); + ACPI_FUNCTION_TRACE_PTR ("ex_store", dest_desc); /* Validate parameters */ if (!source_desc || !dest_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null parameter\n")); return_ACPI_STATUS (AE_AML_NO_OPERAND); } - /* Dest_desc can be either a namespace node or an ACPI object */ + /* dest_desc can be either a namespace node or an ACPI object */ - if (VALID_DESCRIPTOR_TYPE (dest_desc, ACPI_DESC_TYPE_NAMED)) { + if (ACPI_GET_DESCRIPTOR_TYPE (dest_desc) == ACPI_DESC_TYPE_NAMED) { /* * Dest is a namespace node, - * Storing an object into a Name "container" + * Storing an object into a Named node. */ status = acpi_ex_store_object_to_node (source_desc, - (acpi_namespace_node *) dest_desc, walk_state); - - /* All done, that's it */ + (struct acpi_namespace_node *) dest_desc, walk_state); return_ACPI_STATUS (status); } + /* Destination object must be a Reference or a Constant object */ + + switch (ACPI_GET_OBJECT_TYPE (dest_desc)) { + case ACPI_TYPE_LOCAL_REFERENCE: + break; + + case ACPI_TYPE_INTEGER: + + /* Allow stores to Constants -- a Noop as per ACPI spec */ + + if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) { + return_ACPI_STATUS (AE_OK); + } + + /*lint -fallthrough */ - /* Destination object must be an object of type Reference */ + default: - if (dest_desc->common.type != INTERNAL_TYPE_REFERENCE) { /* Destination is not an Reference */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Destination is not a Reference_obj [%p]\n", dest_desc)); + "Destination is not a Reference or Constant object [%p]\n", dest_desc)); - DUMP_STACK_ENTRY (source_desc); - DUMP_STACK_ENTRY (dest_desc); - DUMP_OPERANDS (&dest_desc, IMODE_EXECUTE, "Ex_store", - 2, "Target is not a Reference_obj"); + ACPI_DUMP_STACK_ENTRY (source_desc); + ACPI_DUMP_STACK_ENTRY (dest_desc); + ACPI_DUMP_OPERANDS (&dest_desc, ACPI_IMODE_EXECUTE, "ex_store", + 2, "Target is not a Reference or Constant object"); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* * Examine the Reference opcode. These cases are handled: * @@ -116,11 +145,10 @@ * 2) Store to an indexed area of a Buffer or Package * 3) Store to a Method Local or Arg * 4) Store to the debug object - * 5) Store to a constant -- a noop */ switch (ref_desc->reference.opcode) { - case AML_NAME_OP: + case AML_REF_OF_OP: /* Storing an object into a Name "container" */ @@ -153,23 +181,24 @@ * Storing to the Debug object causes the value stored to be * displayed and otherwise has no effect -- see ACPI Specification */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Write to Debug Object: ****:\n\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Write to Debug Object: ****:\n\n")); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ", - acpi_ut_get_type_name (source_desc->common.type))); + acpi_ut_get_object_type_name (source_desc))); - switch (source_desc->common.type) { + switch (ACPI_GET_OBJECT_TYPE (source_desc)) { case ACPI_TYPE_INTEGER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X (%d)\n", - (u32) source_desc->integer.value, (u32) source_desc->integer.value)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%8.8X%8.8X\n", + ACPI_HIDWORD (source_desc->integer.value), + ACPI_LODWORD (source_desc->integer.value))); break; case ACPI_TYPE_BUFFER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%X\n", - (u32) source_desc->buffer.length)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length %.2X\n", + (u32) source_desc->buffer.length)); break; @@ -181,47 +210,31 @@ case ACPI_TYPE_PACKAGE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements - %p\n", - source_desc->package.elements)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements Ptr - %p\n", + source_desc->package.elements)); break; default: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "@0x%p\n", source_desc)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Type %s %p\n", + acpi_ut_get_object_type_name (source_desc), source_desc)); break; } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); - break; - - - case AML_ZERO_OP: - case AML_ONE_OP: - case AML_ONES_OP: - case AML_REVISION_OP: - - /* - * Storing to a constant is a no-op -- see ACPI Specification - * Delete the reference descriptor, however - */ + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n")); break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - Unknown Reference subtype %02x\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X\n", ref_desc->reference.opcode)); - - /* TBD: [Restructure] use object dump routine !! */ - - DUMP_BUFFER (ref_desc, sizeof (acpi_operand_object)); + ACPI_DUMP_ENTRY (ref_desc, ACPI_LV_ERROR); status = AE_AML_INTERNAL; break; - - } /* switch (Ref_desc->Reference.Opcode) */ - + } return_ACPI_STATUS (status); } @@ -229,38 +242,38 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_store_object_to_index + * FUNCTION: acpi_ex_store_object_to_index * - * PARAMETERS: *Source_desc - Value to be stored - * *Node - Named object to receive the value + * PARAMETERS: *source_desc - Value to be stored + * *dest_desc - Named object to receive the value + * walk_state - Current walk state * * RETURN: Status * - * DESCRIPTION: Store the object to the named object. + * DESCRIPTION: Store the object to indexed Buffer or Package element * ******************************************************************************/ acpi_status acpi_ex_store_object_to_index ( - acpi_operand_object *source_desc, - acpi_operand_object *dest_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *source_desc, + union acpi_operand_object *index_desc, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object *obj_desc; - u32 length; - u32 i; - u8 value = 0; + acpi_status status = AE_OK; + union acpi_operand_object *obj_desc; + union acpi_operand_object *new_desc; + u8 value = 0; - FUNCTION_TRACE ("Ex_store_object_to_index"); + ACPI_FUNCTION_TRACE ("ex_store_object_to_index"); /* * Destination must be a reference pointer, and * must point to either a buffer or a package */ - switch (dest_desc->reference.target_type) { + switch (index_desc->reference.target_type) { case ACPI_TYPE_PACKAGE: /* * Storing to a package element is not simple. The source must be @@ -268,74 +281,34 @@ * source is copied into the destination - we can't just point to the * source object. */ - if (dest_desc->reference.target_type == ACPI_TYPE_PACKAGE) { - /* - * The object at *(Dest_desc->Reference.Where) is the - * element within the package that is to be modified. - */ - obj_desc = *(dest_desc->reference.where); - if (obj_desc) { - /* - * If the Destination element is a package, we will delete - * that object and construct a new one. - * - * TBD: [Investigate] Should both the src and dest be required - * to be packages? - * && (Source_desc->Common.Type == ACPI_TYPE_PACKAGE) - */ - if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { - /* Take away the reference for being part of a package */ - - acpi_ut_remove_reference (obj_desc); - obj_desc = NULL; - } - } + /* + * The object at *(index_desc->Reference.Where) is the + * element within the package that is to be modified. + */ + obj_desc = *(index_desc->reference.where); + + /* Do the conversion/store */ - if (!obj_desc) { - /* - * If the Obj_desc is NULL, it means that an uninitialized package - * element has been used as a destination (this is OK), therefore, - * we must create the destination element to match the type of the - * source element NOTE: Source_desccan be of any type. - */ - obj_desc = acpi_ut_create_internal_object (source_desc->common.type); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* - * If the source is a package, copy the source to the new dest - */ - if (ACPI_TYPE_PACKAGE == obj_desc->common.type) { - status = acpi_ut_copy_ipackage_to_ipackage (source_desc, obj_desc, walk_state); - if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); - } - } + status = acpi_ex_store_object_to_object (source_desc, obj_desc, &new_desc, + walk_state); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not store object to indexed package element\n")); + return_ACPI_STATUS (status); + } - /* Install the new descriptor into the package */ + /* + * If a new object was created, we must install it as the new + * package element + */ + if (new_desc != obj_desc) { + acpi_ut_remove_reference (obj_desc); + *(index_desc->reference.where) = new_desc; - *(dest_desc->reference.where) = obj_desc; - } + /* If same as the original source, add a reference */ - if (ACPI_TYPE_PACKAGE != obj_desc->common.type) { - /* - * The destination element is not a package, so we need to - * convert the contents of the source (Source_desc) and copy into - * the destination (Obj_desc) - */ - status = acpi_ex_store_object_to_object (source_desc, obj_desc, - walk_state); - if (ACPI_FAILURE (status)) { - /* - * An error occurrered when copying the internal object - * so delete the reference. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unable to copy the internal object\n")); - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); - } + if (new_desc == source_desc) { + acpi_ut_add_reference (new_desc); } } break; @@ -343,21 +316,20 @@ case ACPI_TYPE_BUFFER_FIELD: - - /* TBD: can probably call the generic Buffer/Field routines */ - /* - * Storing into a buffer at a location defined by an Index. + * Store into a Buffer (not actually a real buffer_field) at a + * location defined by an Index. * - * Each 8-bit element of the source object is written to the - * 8-bit Buffer Field of the Index destination object. + * The first 8-bit element of the source object is written to the + * 8-bit Buffer location defined by the Index destination object, + * according to the ACPI 2.0 specification. */ /* - * Set the Obj_desc to the destination object and type check. + * Make sure the target is a Buffer */ - obj_desc = dest_desc->reference.object; - if (obj_desc->common.type != ACPI_TYPE_BUFFER) { + obj_desc = index_desc->reference.object; + if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) { return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -365,84 +337,65 @@ * The assignment of the individual elements will be slightly * different for each source type. */ - switch (source_desc->common.type) { + switch (ACPI_GET_OBJECT_TYPE (source_desc)) { case ACPI_TYPE_INTEGER: - /* - * Type is Integer, assign bytewise - * This loop to assign each of the elements is somewhat - * backward because of the Big Endian-ness of IA-64 - */ - length = sizeof (acpi_integer); - for (i = length; i != 0; i--) { - value = (u8)(source_desc->integer.value >> (MUL_8 (i - 1))); - obj_desc->buffer.pointer[dest_desc->reference.offset] = value; - } - break; + /* Use the least-significant byte of the integer */ - case ACPI_TYPE_BUFFER: - /* - * Type is Buffer, the Length is in the structure. - * Just loop through the elements and assign each one in turn. - */ - length = source_desc->buffer.length; - for (i = 0; i < length; i++) { - value = source_desc->buffer.pointer[i]; - obj_desc->buffer.pointer[dest_desc->reference.offset] = value; - } + value = (u8) (source_desc->integer.value); break; + case ACPI_TYPE_BUFFER: - case ACPI_TYPE_STRING: - /* - * Type is String, the Length is in the structure. - * Just loop through the elements and assign each one in turn. - */ - length = source_desc->string.length; - for (i = 0; i < length; i++) { - value = source_desc->string.pointer[i]; - obj_desc->buffer.pointer[dest_desc->reference.offset] = value; - } + value = source_desc->buffer.pointer[0]; break; + case ACPI_TYPE_STRING: + + value = (u8) source_desc->string.pointer[0]; + break; default: - /* Other types are invalid */ + /* All other types are invalid */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Source must be Number/Buffer/String type, not %X\n", - source_desc->common.type)); - status = AE_AML_OPERAND_TYPE; - break; + "Source must be Integer/Buffer/String type, not %s\n", + acpi_ut_get_object_type_name (source_desc))); + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } + + /* Store the source value into the target buffer byte */ + + obj_desc->buffer.pointer[index_desc->reference.offset] = value; break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Target is not a Package or Buffer_field\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Target is not a Package or buffer_field\n")); status = AE_AML_OPERAND_TYPE; break; } - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_store_object_to_node + * FUNCTION: acpi_ex_store_object_to_node * - * PARAMETERS: *Source_desc - Value to be stored - * *Node - Named object to receive the value + * PARAMETERS: source_desc - Value to be stored + * Node - Named object to receive the value + * walk_state - Current walk state * * RETURN: Status * * DESCRIPTION: Store the object to the named object. * * The Assignment of an object to a named object is handled here - * The val passed in will replace the current value (if any) + * The value passed in will replace the current value (if any) * with the input value. * * When storing into an object the data is converted to the @@ -450,41 +403,34 @@ * that the target object type (for an initialized target) will * not be changed by a store operation. * - * NOTE: the global lock is acquired early. This will result - * in the global lock being held a bit longer. Also, if the - * function fails during set up we may get the lock when we - * don't really need it. I don't think we care. + * Assumes parameters are already validated. * ******************************************************************************/ acpi_status acpi_ex_store_object_to_node ( - acpi_operand_object *source_desc, - acpi_namespace_node *node, - acpi_walk_state *walk_state) + union acpi_operand_object *source_desc, + struct acpi_namespace_node *node, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_operand_object *target_desc; - acpi_object_type8 target_type = ACPI_TYPE_ANY; + acpi_status status = AE_OK; + union acpi_operand_object *target_desc; + union acpi_operand_object *new_desc; + acpi_object_type target_type; - FUNCTION_TRACE ("Ex_store_object_to_node"); + ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc); /* - * Assuming the parameters were already validated - */ - - /* * Get current type of the node, and object attached to Node */ target_type = acpi_ns_get_type (node); target_desc = acpi_ns_get_attached_object (node); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) into node %p(%s)\n", - node, acpi_ut_get_type_name (source_desc->common.type), - source_desc, acpi_ut_get_type_name (target_type))); - + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", + source_desc, acpi_ut_get_object_type_name (source_desc), + node, acpi_ut_get_type_name (target_type))); /* * Resolve the source object to an actual value @@ -495,20 +441,19 @@ return_ACPI_STATUS (status); } - /* * Do the actual store operation */ switch (target_type) { case ACPI_TYPE_BUFFER_FIELD: - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: /* * For fields, copy the source data to the target field. */ - status = acpi_ex_write_data_to_field (source_desc, target_desc); + status = acpi_ex_write_data_to_field (source_desc, target_desc, &walk_state->result_obj); break; @@ -522,122 +467,44 @@ * * Copy and/or convert the source object to a new target object */ - status = acpi_ex_store_object (source_desc, target_type, &target_desc, walk_state); + status = acpi_ex_store_object_to_object (source_desc, target_desc, &new_desc, walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* - * Store the new Target_desc as the new value of the Name, and set - * the Name's type to that of the value being stored in it. - * Source_desc reference count is incremented by Attach_object. - */ - status = acpi_ns_attach_object (node, target_desc, target_type); + if (new_desc != target_desc) { + /* + * Store the new new_desc as the new value of the Name, and set + * the Name's type to that of the value being stored in it. + * source_desc reference count is incremented by attach_object. + * + * Note: This may change the type of the node if an explicit store + * has been performed such that the node/object type has been + * changed. + */ + status = acpi_ns_attach_object (node, new_desc, new_desc->common.type); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Store %s into %s via Convert/Attach\n", - acpi_ut_get_type_name (target_desc->common.type), - acpi_ut_get_type_name (target_type))); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Store %s into %s via Convert/Attach\n", + acpi_ut_get_object_type_name (source_desc), + acpi_ut_get_object_type_name (new_desc))); + } break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %s (%p) directly into node (%p), no implicit conversion\n", - acpi_ut_get_type_name (source_desc->common.type), source_desc, node)); + acpi_ut_get_object_type_name (source_desc), source_desc, node)); /* No conversions for all other types. Just attach the source object */ - status = acpi_ns_attach_object (node, source_desc, source_desc->common.type); + status = acpi_ns_attach_object (node, source_desc, ACPI_GET_OBJECT_TYPE (source_desc)); break; } - return_ACPI_STATUS (status); } -/******************************************************************************* - * - * FUNCTION: Acpi_ex_store_object_to_object - * - * PARAMETERS: *Source_desc - Value to be stored - * *Dest_desc - Object to receive the value - * - * RETURN: Status - * - * DESCRIPTION: Store an object to another object. - * - * The Assignment of an object to another (not named) object - * is handled here. - * The val passed in will replace the current value (if any) - * with the input value. - * - * When storing into an object the data is converted to the - * target object type then stored in the object. This means - * that the target object type (for an initialized target) will - * not be changed by a store operation. - * - * This module allows destination types of Number, String, - * and Buffer. - * - ******************************************************************************/ - -acpi_status -acpi_ex_store_object_to_object ( - acpi_operand_object *source_desc, - acpi_operand_object *dest_desc, - acpi_walk_state *walk_state) -{ - acpi_status status = AE_OK; - acpi_object_type8 destination_type = dest_desc->common.type; - - - FUNCTION_TRACE ("Ex_store_object_to_object"); - - - /* - * Assuming the parameters are valid! - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) to %p(%s)\n", - source_desc, acpi_ut_get_type_name (source_desc->common.type), - dest_desc, acpi_ut_get_type_name (dest_desc->common.type))); - - - /* - * From this interface, we only support Integers/Strings/Buffers - */ - switch (destination_type) { - case ACPI_TYPE_INTEGER: - case ACPI_TYPE_STRING: - case ACPI_TYPE_BUFFER: - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into %s not implemented\n", - acpi_ut_get_type_name (dest_desc->common.type))); - - return_ACPI_STATUS (AE_NOT_IMPLEMENTED); - } - - - /* - * Resolve the source object to an actual value - * (If it is a reference object) - */ - status = acpi_ex_resolve_object (&source_desc, destination_type, walk_state); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - - /* - * Copy and/or convert the source object to the destination object - */ - status = acpi_ex_store_object (source_desc, destination_type, &dest_desc, walk_state); - - - return_ACPI_STATUS (status); -} - diff -urN linux-2.4.21/drivers/acpi/executer/exstoren.c linux-2.4.22/drivers/acpi/executer/exstoren.c --- linux-2.4.21/drivers/acpi/executer/exstoren.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exstoren.c 2003-08-25 04:44:41.000000000 -0700 @@ -3,128 +3,136 @@ * * Module Name: exstoren - AML Interpreter object store support, * Store to Node (namespace object) - * $Revision: 40 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exstoren") + ACPI_MODULE_NAME ("exstoren") /******************************************************************************* * - * FUNCTION: Acpi_ex_resolve_object + * FUNCTION: acpi_ex_resolve_object * - * PARAMETERS: Source_desc_ptr - Pointer to the source object - * Target_type - Current type of the target - * Walk_state - Current walk state + * PARAMETERS: source_desc_ptr - Pointer to the source object + * target_type - Current type of the target + * walk_state - Current walk state * - * RETURN: Status, resolved object in Source_desc_ptr. + * RETURN: Status, resolved object in source_desc_ptr. * * DESCRIPTION: Resolve an object. If the object is a reference, dereference - * it and return the actual object in the Source_desc_ptr. + * it and return the actual object in the source_desc_ptr. * ******************************************************************************/ acpi_status acpi_ex_resolve_object ( - acpi_operand_object **source_desc_ptr, - acpi_object_type8 target_type, - acpi_walk_state *walk_state) + union acpi_operand_object **source_desc_ptr, + acpi_object_type target_type, + struct acpi_walk_state *walk_state) { - acpi_operand_object *source_desc = *source_desc_ptr; - acpi_status status = AE_OK; + union acpi_operand_object *source_desc = *source_desc_ptr; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_resolve_object"); + ACPI_FUNCTION_TRACE ("ex_resolve_object"); /* - * Ensure we have a Source that can be stored in the target + * Ensure we have a Target that can be stored to */ switch (target_type) { - - /* This case handles the "interchangeable" types Integer, String, and Buffer. */ - - /* - * These cases all require only Integers or values that - * can be converted to Integers (Strings or Buffers) - */ case ACPI_TYPE_BUFFER_FIELD: - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + /* + * These cases all require only Integers or values that + * can be converted to Integers (Strings or Buffers) + */ - /* - * Stores into a Field/Region or into a Buffer/String - * are all essentially the same. - */ case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: + /* + * Stores into a Field/Region or into a Integer/Buffer/String + * are all essentially the same. This case handles the + * "interchangeable" types Integer, String, and Buffer. + */ + if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) { + /* Resolve a reference object first */ - /* TBD: FIX - check for source==REF, resolve, then check type */ + status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state); + if (ACPI_FAILURE (status)) { + break; + } + } /* - * If Source_desc is not a valid type, try to resolve it to one. + * Must have a Integer, Buffer, or String */ - if ((source_desc->common.type != ACPI_TYPE_INTEGER) && - (source_desc->common.type != ACPI_TYPE_BUFFER) && - (source_desc->common.type != ACPI_TYPE_STRING)) { + if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) && + (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) && + (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING)) { /* - * Initially not a valid type, convert + * Conversion successful but still not a valid type */ - status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state); - if (ACPI_SUCCESS (status) && - (source_desc->common.type != ACPI_TYPE_INTEGER) && - (source_desc->common.type != ACPI_TYPE_BUFFER) && - (source_desc->common.type != ACPI_TYPE_STRING)) { - /* - * Conversion successful but still not a valid type - */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Cannot assign type %s to %s (must be type Int/Str/Buf)\n", - acpi_ut_get_type_name ((*source_desc_ptr)->common.type), - acpi_ut_get_type_name (target_type))); - status = AE_AML_OPERAND_TYPE; - } + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Cannot assign type %s to %s (must be type Int/Str/Buf)\n", + acpi_ut_get_object_type_name (source_desc), + acpi_ut_get_type_name (target_type))); + status = AE_AML_OPERAND_TYPE; } break; - case INTERNAL_TYPE_ALIAS: + case ACPI_TYPE_LOCAL_ALIAS: /* - * Aliases are resolved by Acpi_ex_prep_operands + * Aliases are resolved by acpi_ex_prep_operands */ ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into Alias - should never happen\n")); status = AE_AML_INTERNAL; @@ -147,12 +155,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_store_object + * FUNCTION: acpi_ex_store_object_to_object * - * PARAMETERS: Source_desc - Object to store - * Target_type - Current type of the target - * Target_desc_ptr - Pointer to the target - * Walk_state - Current walk state + * PARAMETERS: source_desc - Object to store + * dest_desc - Object to receive a copy of the source + * new_desc - New object if dest_desc is obsoleted + * walk_state - Current walk state * * RETURN: Status * @@ -161,93 +169,123 @@ * conversion), and a copy of the value of the source to * the target. * + * The Assignment of an object to another (not named) object + * is handled here. + * The Source passed in will replace the current value (if any) + * with the input value. + * + * When storing into an object the data is converted to the + * target object type then stored in the object. This means + * that the target object type (for an initialized target) will + * not be changed by a store operation. + * + * This module allows destination types of Number, String, + * Buffer, and Package. + * + * Assumes parameters are already validated. NOTE: source_desc + * resolution (from a reference object) must be performed by + * the caller if necessary. + * ******************************************************************************/ acpi_status -acpi_ex_store_object ( - acpi_operand_object *source_desc, - acpi_object_type8 target_type, - acpi_operand_object **target_desc_ptr, - acpi_walk_state *walk_state) +acpi_ex_store_object_to_object ( + union acpi_operand_object *source_desc, + union acpi_operand_object *dest_desc, + union acpi_operand_object **new_desc, + struct acpi_walk_state *walk_state) { - acpi_operand_object *target_desc = *target_desc_ptr; - acpi_status status = AE_OK; + union acpi_operand_object *actual_src_desc; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_store_object"); + ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc); - /* - * Perform the "implicit conversion" of the source to the current type - * of the target - As per the ACPI specification. - * - * If no conversion performed, Source_desc is left alone, otherwise it - * is updated with a new object. - */ - status = acpi_ex_convert_to_target_type (target_type, &source_desc, walk_state); - if (ACPI_FAILURE (status)) { + actual_src_desc = source_desc; + if (!dest_desc) { + /* + * There is no destination object (An uninitialized node or + * package element), so we can simply copy the source object + * creating a new destination object + */ + status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, new_desc, walk_state); return_ACPI_STATUS (status); } - /* - * We now have two objects of identical types, and we can perform a - * copy of the *value* of the source object. - */ - switch (target_type) { - case ACPI_TYPE_ANY: - case INTERNAL_TYPE_DEF_ANY: - + if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) { /* - * The target namespace node is uninitialized (has no target object), - * and will take on the type of the source object + * The source type does not match the type of the destination. + * Perform the "implicit conversion" of the source to the current type + * of the target as per the ACPI specification. + * + * If no conversion performed, actual_src_desc = source_desc. + * Otherwise, actual_src_desc is a temporary object to hold the + * converted object. */ - *target_desc_ptr = source_desc; - break; + status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc), source_desc, + &actual_src_desc, walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + if (source_desc == actual_src_desc) { + /* + * No conversion was performed. Return the source_desc as the + * new object. + */ + *new_desc = source_desc; + return_ACPI_STATUS (AE_OK); + } + } + /* + * We now have two objects of identical types, and we can perform a + * copy of the *value* of the source object. + */ + switch (ACPI_GET_OBJECT_TYPE (dest_desc)) { case ACPI_TYPE_INTEGER: - target_desc->integer.value = source_desc->integer.value; + dest_desc->integer.value = actual_src_desc->integer.value; /* Truncate value if we are executing from a 32-bit ACPI table */ - acpi_ex_truncate_for32bit_table (target_desc, walk_state); + acpi_ex_truncate_for32bit_table (dest_desc); break; case ACPI_TYPE_STRING: - status = acpi_ex_copy_string_to_string (source_desc, target_desc); + status = acpi_ex_store_string_to_string (actual_src_desc, dest_desc); break; - case ACPI_TYPE_BUFFER: - status = acpi_ex_copy_buffer_to_buffer (source_desc, target_desc); + status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc); break; - case ACPI_TYPE_PACKAGE: - /* - * TBD: [Unhandled] Not real sure what to do here - */ - status = AE_NOT_IMPLEMENTED; + status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc, walk_state); break; - default: - /* * All other types come here. */ ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into type %s not implemented\n", - acpi_ut_get_type_name (target_type))); + acpi_ut_get_object_type_name (dest_desc))); status = AE_NOT_IMPLEMENTED; break; } + if (actual_src_desc != source_desc) { + /* Delete the intermediate (temporary) source object */ + + acpi_ut_remove_reference (actual_src_desc); + } + *new_desc = dest_desc; return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/executer/exstorob.c linux-2.4.22/drivers/acpi/executer/exstorob.c --- linux-2.4.21/drivers/acpi/executer/exstorob.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exstorob.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,48 +2,61 @@ /****************************************************************************** * * Module Name: exstorob - AML Interpreter object store support, store to object - * $Revision: 37 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exstorob") + ACPI_MODULE_NAME ("exstorob") /******************************************************************************* * - * FUNCTION: Acpi_ex_copy_buffer_to_buffer + * FUNCTION: acpi_ex_store_buffer_to_buffer * - * PARAMETERS: Source_desc - Source object to copy - * Target_desc - Destination object of the copy + * PARAMETERS: source_desc - Source object to copy + * target_desc - Destination object of the copy * * RETURN: Status * @@ -52,33 +65,35 @@ ******************************************************************************/ acpi_status -acpi_ex_copy_buffer_to_buffer ( - acpi_operand_object *source_desc, - acpi_operand_object *target_desc) +acpi_ex_store_buffer_to_buffer ( + union acpi_operand_object *source_desc, + union acpi_operand_object *target_desc) { - u32 length; - u8 *buffer; + u32 length; + u8 *buffer; - PROC_NAME ("Ex_copy_buffer_to_buffer"); + ACPI_FUNCTION_TRACE_PTR ("ex_store_buffer_to_buffer", source_desc); /* - * We know that Source_desc is a buffer by now + * We know that source_desc is a buffer by now */ buffer = (u8 *) source_desc->buffer.pointer; length = source_desc->buffer.length; /* - * If target is a buffer of length zero, allocate a new - * buffer of the proper length + * If target is a buffer of length zero or is a static buffer, + * allocate a new buffer of the proper length */ - if (target_desc->buffer.length == 0) { + if ((target_desc->buffer.length == 0) || + (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) { target_desc->buffer.pointer = ACPI_MEM_ALLOCATE (length); if (!target_desc->buffer.pointer) { - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } + target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER; target_desc->buffer.length = length; } @@ -89,31 +104,33 @@ if (length <= target_desc->buffer.length) { /* Clear existing buffer and copy in the new one */ - MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length); - MEMCPY (target_desc->buffer.pointer, buffer, length); + ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length); + ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length); } - else { /* * Truncate the source, copy only what will fit */ - MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length); + ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Truncating src buffer from %X to %X\n", length, target_desc->buffer.length)); } - return (AE_OK); + /* Copy flags */ + + target_desc->buffer.flags = source_desc->buffer.flags; + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_copy_string_to_string + * FUNCTION: acpi_ex_store_string_to_string * - * PARAMETERS: Source_desc - Source object to copy - * Target_desc - Destination object of the copy + * PARAMETERS: source_desc - Source object to copy + * target_desc - Destination object of the copy * * RETURN: Status * @@ -122,36 +139,39 @@ ******************************************************************************/ acpi_status -acpi_ex_copy_string_to_string ( - acpi_operand_object *source_desc, - acpi_operand_object *target_desc) +acpi_ex_store_string_to_string ( + union acpi_operand_object *source_desc, + union acpi_operand_object *target_desc) { - u32 length; - u8 *buffer; + u32 length; + u8 *buffer; - FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc); /* - * We know that Source_desc is a string by now. + * We know that source_desc is a string by now. */ buffer = (u8 *) source_desc->string.pointer; length = source_desc->string.length; /* - * Setting a string value replaces the old string + * Replace existing string value if it will fit and the string + * pointer is not a static pointer (part of an ACPI table) */ - if (length < target_desc->string.length) { - /* Clear old string and copy in the new one */ - - MEMSET (target_desc->string.pointer, 0, target_desc->string.length); - MEMCPY (target_desc->string.pointer, buffer, length); + if ((length < target_desc->string.length) && + (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) { + /* + * String will fit in existing non-static buffer. + * Clear old string and copy in the new one + */ + ACPI_MEMSET (target_desc->string.pointer, 0, (acpi_size) target_desc->string.length + 1); + ACPI_MEMCPY (target_desc->string.pointer, buffer, length); } - else { /* - * Free the current buffer, then allocate a buffer + * Free the current buffer, then allocate a new buffer * large enough to hold the value */ if (target_desc->string.pointer && @@ -162,16 +182,19 @@ ACPI_MEM_FREE (target_desc->string.pointer); } - target_desc->string.pointer = ACPI_MEM_ALLOCATE (length + 1); + target_desc->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1); if (!target_desc->string.pointer) { - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } - target_desc->string.length = length; - MEMCPY (target_desc->string.pointer, buffer, length); + target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER; + ACPI_MEMCPY (target_desc->string.pointer, buffer, length); } - return (AE_OK); + /* Set the new target length */ + + target_desc->string.length = length; + return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/executer/exsystem.c linux-2.4.22/drivers/acpi/executer/exsystem.c --- linux-2.4.21/drivers/acpi/executer/exsystem.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exsystem.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,42 +2,58 @@ /****************************************************************************** * * Module Name: exsystem - Interface to OS services - * $Revision: 67 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "achware.h" -#include "acevents.h" +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exsystem") + ACPI_MODULE_NAME ("exsystem") /******************************************************************************* * - * FUNCTION: Acpi_ex_system_wait_semaphore + * FUNCTION: acpi_ex_system_wait_semaphore * * PARAMETERS: Semaphore - OSD semaphore to wait on * Timeout - Max time to wait @@ -52,13 +68,14 @@ acpi_status acpi_ex_system_wait_semaphore ( - acpi_handle semaphore, - u32 timeout) + acpi_handle semaphore, + u16 timeout) { - acpi_status status; + acpi_status status; + acpi_status status2; - FUNCTION_TRACE ("Ex_system_wait_semaphore"); + ACPI_FUNCTION_TRACE ("ex_system_wait_semaphore"); status = acpi_os_wait_semaphore (semaphore, 1, 0); @@ -78,11 +95,11 @@ /* Reacquire the interpreter */ - status = acpi_ex_enter_interpreter (); - if (ACPI_SUCCESS (status)) { - /* Restore the timeout exception */ + status2 = acpi_ex_enter_interpreter (); + if (ACPI_FAILURE (status2)) { + /* Report fatal error, could not acquire interpreter */ - status = AE_TIME; + return_ACPI_STATUS (status2); } } @@ -92,21 +109,24 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_system_do_stall + * FUNCTION: acpi_ex_system_do_stall * - * PARAMETERS: How_long - The amount of time to stall + * PARAMETERS: how_long - The amount of time to stall * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Suspend running thread for specified amount of time. * ******************************************************************************/ -void +acpi_status acpi_ex_system_do_stall ( - u32 how_long) + u32 how_long) { - FUNCTION_ENTRY (); + acpi_status status = AE_OK; + + + ACPI_FUNCTION_ENTRY (); if (how_long > 1000) /* 1 millisecond */ { @@ -114,24 +134,26 @@ acpi_ex_exit_interpreter (); - acpi_os_stall (how_long); + acpi_os_sleep (0, (how_long / 1000) + 1); /* And now we must get the interpreter again */ - acpi_ex_enter_interpreter (); + status = acpi_ex_enter_interpreter (); } else { - acpi_os_sleep (0, (how_long / 1000) + 1); + acpi_os_stall (how_long); } + + return (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_system_do_suspend + * FUNCTION: acpi_ex_system_do_suspend * - * PARAMETERS: How_long - The amount of time to suspend + * PARAMETERS: how_long - The amount of time to suspend * * RETURN: None * @@ -139,12 +161,14 @@ * ******************************************************************************/ -void +acpi_status acpi_ex_system_do_suspend ( - u32 how_long) + u32 how_long) { + acpi_status status; - FUNCTION_ENTRY (); + + ACPI_FUNCTION_ENTRY (); /* Since this thread will sleep, we must release the interpreter */ @@ -156,34 +180,35 @@ /* And now we must get the interpreter again */ - acpi_ex_enter_interpreter (); + status = acpi_ex_enter_interpreter (); + return (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_system_acquire_mutex + * FUNCTION: acpi_ex_system_acquire_mutex * - * PARAMETERS: *Time_desc - The 'time to delay' object descriptor - * *Obj_desc - The object descriptor for this op + * PARAMETERS: *time_desc - The 'time to delay' object descriptor + * *obj_desc - The object descriptor for this op * * RETURN: Status * * DESCRIPTION: Provides an access point to perform synchronization operations * within the AML. This function will cause a lock to be generated - * for the Mutex pointed to by Obj_desc. + * for the Mutex pointed to by obj_desc. * ******************************************************************************/ acpi_status acpi_ex_system_acquire_mutex ( - acpi_operand_object *time_desc, - acpi_operand_object *obj_desc) + union acpi_operand_object *time_desc, + union acpi_operand_object *obj_desc) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE_PTR ("Ex_system_acquire_mutex", obj_desc); + ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc); if (!obj_desc) { @@ -194,21 +219,21 @@ * Support for the _GL_ Mutex object -- go get the global lock */ if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) { - status = acpi_ev_acquire_global_lock (); + status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value); return_ACPI_STATUS (status); } status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore, - (u32) time_desc->integer.value); + (u16) time_desc->integer.value); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_system_release_mutex + * FUNCTION: acpi_ex_system_release_mutex * - * PARAMETERS: *Obj_desc - The object descriptor for this op + * PARAMETERS: *obj_desc - The object descriptor for this op * * RETURN: Status * @@ -221,12 +246,12 @@ acpi_status acpi_ex_system_release_mutex ( - acpi_operand_object *obj_desc) + union acpi_operand_object *obj_desc) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_system_release_mutex"); + ACPI_FUNCTION_TRACE ("ex_system_release_mutex"); if (!obj_desc) { @@ -237,8 +262,8 @@ * Support for the _GL_ Mutex object -- release the global lock */ if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) { - acpi_ev_release_global_lock (); - return_ACPI_STATUS (AE_OK); + status = acpi_ev_release_global_lock (); + return_ACPI_STATUS (status); } status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1); @@ -248,9 +273,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_system_signal_event + * FUNCTION: acpi_ex_system_signal_event * - * PARAMETERS: *Obj_desc - The object descriptor for this op + * PARAMETERS: *obj_desc - The object descriptor for this op * * RETURN: AE_OK * @@ -261,12 +286,12 @@ acpi_status acpi_ex_system_signal_event ( - acpi_operand_object *obj_desc) + union acpi_operand_object *obj_desc) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_system_signal_event"); + ACPI_FUNCTION_TRACE ("ex_system_signal_event"); if (obj_desc) { @@ -279,10 +304,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_system_wait_event + * FUNCTION: acpi_ex_system_wait_event * - * PARAMETERS: *Time_desc - The 'time to delay' object descriptor - * *Obj_desc - The object descriptor for this op + * PARAMETERS: *time_desc - The 'time to delay' object descriptor + * *obj_desc - The object descriptor for this op * * RETURN: Status * @@ -294,30 +319,29 @@ acpi_status acpi_ex_system_wait_event ( - acpi_operand_object *time_desc, - acpi_operand_object *obj_desc) + union acpi_operand_object *time_desc, + union acpi_operand_object *obj_desc) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_system_wait_event"); + ACPI_FUNCTION_TRACE ("ex_system_wait_event"); if (obj_desc) { status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore, - (u32) time_desc->integer.value); + (u16) time_desc->integer.value); } - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_system_reset_event + * FUNCTION: acpi_ex_system_reset_event * - * PARAMETERS: *Obj_desc - The object descriptor for this op + * PARAMETERS: *obj_desc - The object descriptor for this op * * RETURN: Status * @@ -327,13 +351,13 @@ acpi_status acpi_ex_system_reset_event ( - acpi_operand_object *obj_desc) + union acpi_operand_object *obj_desc) { - acpi_status status = AE_OK; - void *temp_semaphore; + acpi_status status = AE_OK; + void *temp_semaphore; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* @@ -342,7 +366,7 @@ */ status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore); if (ACPI_SUCCESS (status)) { - acpi_os_delete_semaphore (obj_desc->event.semaphore); + (void) acpi_os_delete_semaphore (obj_desc->event.semaphore); obj_desc->event.semaphore = temp_semaphore; } diff -urN linux-2.4.21/drivers/acpi/executer/exutils.c linux-2.4.22/drivers/acpi/executer/exutils.c --- linux-2.4.21/drivers/acpi/executer/exutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/executer/exutils.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,26 +2,44 @@ /****************************************************************************** * * Module Name: exutils - interpreter/scanner utilities - * $Revision: 85 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ @@ -41,45 +59,48 @@ #define DEFINE_AML_GLOBALS -#include "acpi.h" -#include "acparser.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acevents.h" -#include "acparser.h" +#include +#include +#include +#include #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exutils") + ACPI_MODULE_NAME ("exutils") +#ifndef ACPI_NO_METHOD_EXECUTION + /******************************************************************************* * - * FUNCTION: Acpi_ex_enter_interpreter + * FUNCTION: acpi_ex_enter_interpreter * * PARAMETERS: None * - * DESCRIPTION: Enter the interpreter execution region - * TBD: should be a macro + * DESCRIPTION: Enter the interpreter execution region. Failure to enter + * the interpreter region is a fatal system error * ******************************************************************************/ acpi_status acpi_ex_enter_interpreter (void) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Ex_enter_interpreter"); + ACPI_FUNCTION_TRACE ("ex_enter_interpreter"); status = acpi_ut_acquire_mutex (ACPI_MTX_EXECUTE); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not acquire interpreter mutex\n")); + } + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ex_exit_interpreter + * FUNCTION: acpi_ex_exit_interpreter * * PARAMETERS: None * @@ -95,56 +116,31 @@ * already executing * 7) About to invoke a user-installed opregion handler * - * TBD: should be a macro - * ******************************************************************************/ void acpi_ex_exit_interpreter (void) { - FUNCTION_TRACE ("Ex_exit_interpreter"); - - - acpi_ut_release_mutex (ACPI_MTX_EXECUTE); - - return_VOID; -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_validate_object_type - * - * PARAMETERS: Type Object type to validate - * - * DESCRIPTION: Determine if a type is a valid ACPI object type - * - ******************************************************************************/ + acpi_status status; -u8 -acpi_ex_validate_object_type ( - acpi_object_type type) -{ - FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE ("ex_exit_interpreter"); - if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) || - (type > INTERNAL_TYPE_MAX)) { - return (FALSE); + status = acpi_ut_release_mutex (ACPI_MTX_EXECUTE); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not release interpreter mutex\n")); } - return (TRUE); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ex_truncate_for32bit_table + * FUNCTION: acpi_ex_truncate_for32bit_table * - * PARAMETERS: Obj_desc - Object to be truncated - * Walk_state - Current walk state - * (A method must be executing) + * PARAMETERS: obj_desc - Object to be truncated * * RETURN: none * @@ -155,11 +151,10 @@ void acpi_ex_truncate_for32bit_table ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) + union acpi_operand_object *obj_desc) { - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* @@ -167,12 +162,11 @@ * a control method */ if ((!obj_desc) || - (obj_desc->common.type != ACPI_TYPE_INTEGER) || - (!walk_state->method_node)) { + (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER)) { return; } - if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { + if (acpi_gbl_integer_byte_width == 4) { /* * We are running a method that exists in a 32-bit ACPI table. * Truncate the value to 32 bits by zeroing out the upper 32-bit field @@ -184,9 +178,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_acquire_global_lock + * FUNCTION: acpi_ex_acquire_global_lock * - * PARAMETERS: Rule - Lock rule: Always_lock, Never_lock + * PARAMETERS: field_flags - Flags with Lock rule: + * always_lock or never_lock * * RETURN: TRUE/FALSE indicating whether the lock was actually acquired * @@ -198,25 +193,24 @@ u8 acpi_ex_acquire_global_lock ( - u32 rule) + u32 field_flags) { - u8 locked = FALSE; - acpi_status status; + u8 locked = FALSE; + acpi_status status; - FUNCTION_TRACE ("Ex_acquire_global_lock"); + ACPI_FUNCTION_TRACE ("ex_acquire_global_lock"); - /* Only attempt lock if the Rule says so */ + /* Only attempt lock if the always_lock bit is set */ - if (rule == (u32) GLOCK_ALWAYS_LOCK) { - /* We should attempt to get the lock */ + if (field_flags & AML_FIELD_LOCK_RULE_MASK) { + /* We should attempt to get the lock, wait forever */ - status = acpi_ev_acquire_global_lock (); + status = acpi_ev_acquire_global_lock (ACPI_WAIT_FOREVER); if (ACPI_SUCCESS (status)) { locked = TRUE; } - else { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not acquire Global Lock, %s\n", acpi_format_exception (status))); @@ -229,10 +223,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_release_global_lock + * FUNCTION: acpi_ex_release_global_lock * - * PARAMETERS: Locked_by_me - Return value from corresponding call to - * Acquire_global_lock. + * PARAMETERS: locked_by_me - Return value from corresponding call to + * acquire_global_lock. * * RETURN: Status * @@ -240,12 +234,14 @@ * ******************************************************************************/ -acpi_status +void acpi_ex_release_global_lock ( - u8 locked_by_me) + u8 locked_by_me) { + acpi_status status; - FUNCTION_TRACE ("Ex_release_global_lock"); + + ACPI_FUNCTION_TRACE ("ex_release_global_lock"); /* Only attempt unlock if the caller locked it */ @@ -253,17 +249,22 @@ if (locked_by_me) { /* OK, now release the lock */ - acpi_ev_release_global_lock (); - } + status = acpi_ev_release_global_lock (); + if (ACPI_FAILURE (status)) { + /* Report the error, but there isn't much else we can do */ + ACPI_REPORT_ERROR (("Could not release ACPI Global Lock, %s\n", + acpi_format_exception (status))); + } + } - return_ACPI_STATUS (AE_OK); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ex_digits_needed + * FUNCTION: acpi_ex_digits_needed * * PARAMETERS: Value - Value to be represented * Base - Base of representation @@ -274,26 +275,30 @@ u32 acpi_ex_digits_needed ( - acpi_integer value, - u32 base) + acpi_integer value, + u32 base) { - u32 num_digits = 0; + u32 num_digits; + acpi_integer current_value; + acpi_integer quotient; - FUNCTION_TRACE ("Ex_digits_needed"); + ACPI_FUNCTION_TRACE ("ex_digits_needed"); - if (base < 1) { - REPORT_ERROR (("Ex_digits_needed: Internal error - Invalid base\n")); + /* + * acpi_integer is unsigned, so we don't worry about a '-' + */ + if ((current_value = value) == 0) { + return_VALUE (1); } - else { - /* - * acpi_integer is unsigned, which is why we don't worry about a '-' - */ - for (num_digits = 1; - (acpi_ut_short_divide (&value, base, &value, NULL)); - ++num_digits) { ; } + num_digits = 0; + + while (current_value) { + (void) acpi_ut_short_divide (¤t_value, base, "ient, NULL); + num_digits++; + current_value = quotient; } return_VALUE (num_digits); @@ -302,115 +307,74 @@ /******************************************************************************* * - * FUNCTION: ntohl - * - * PARAMETERS: Value - Value to be converted - * - * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) - * - ******************************************************************************/ - -static u32 -_ntohl ( - u32 value) -{ - union { - u32 value; - u8 bytes[4]; - } out; - - union { - u32 value; - u8 bytes[4]; - } in; - - - FUNCTION_ENTRY (); - - - in.value = value; - - out.bytes[0] = in.bytes[3]; - out.bytes[1] = in.bytes[2]; - out.bytes[2] = in.bytes[1]; - out.bytes[3] = in.bytes[0]; - - return (out.value); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_eisa_id_to_string + * FUNCTION: acpi_ex_eisa_id_to_string * - * PARAMETERS: Numeric_id - EISA ID to be converted - * Out_string - Where to put the converted string (8 bytes) + * PARAMETERS: numeric_id - EISA ID to be converted + * out_string - Where to put the converted string (8 bytes) * * DESCRIPTION: Convert a numeric EISA ID to string representation * ******************************************************************************/ -acpi_status +void acpi_ex_eisa_id_to_string ( - u32 numeric_id, - NATIVE_CHAR *out_string) + u32 numeric_id, + char *out_string) { - u32 id; + u32 eisa_id; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); - /* swap to big-endian to get contiguous bits */ + /* Swap ID to big-endian to get contiguous bits */ - id = _ntohl (numeric_id); + eisa_id = acpi_ut_dword_byte_swap (numeric_id); - out_string[0] = (char) ('@' + ((id >> 26) & 0x1f)); - out_string[1] = (char) ('@' + ((id >> 21) & 0x1f)); - out_string[2] = (char) ('@' + ((id >> 16) & 0x1f)); - out_string[3] = acpi_ut_hex_to_ascii_char (id, 12); - out_string[4] = acpi_ut_hex_to_ascii_char (id, 8); - out_string[5] = acpi_ut_hex_to_ascii_char (id, 4); - out_string[6] = acpi_ut_hex_to_ascii_char (id, 0); + out_string[0] = (char) ('@' + (((unsigned long) eisa_id >> 26) & 0x1f)); + out_string[1] = (char) ('@' + ((eisa_id >> 21) & 0x1f)); + out_string[2] = (char) ('@' + ((eisa_id >> 16) & 0x1f)); + out_string[3] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 12); + out_string[4] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 8); + out_string[5] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 4); + out_string[6] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 0); out_string[7] = 0; - - return (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ex_unsigned_integer_to_string + * FUNCTION: acpi_ex_unsigned_integer_to_string * * PARAMETERS: Value - Value to be converted - * Out_string - Where to put the converted string (8 bytes) + * out_string - Where to put the converted string (8 bytes) * * RETURN: Convert a number to string representation * ******************************************************************************/ -acpi_status +void acpi_ex_unsigned_integer_to_string ( - acpi_integer value, - NATIVE_CHAR *out_string) + acpi_integer value, + char *out_string) { - u32 count; - u32 digits_needed; - u32 remainder; + u32 count; + u32 digits_needed; + u32 remainder; + acpi_integer quotient; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); digits_needed = acpi_ex_digits_needed (value, 10); out_string[digits_needed] = 0; for (count = digits_needed; count > 0; count--) { - acpi_ut_short_divide (&value, 10, &value, &remainder); - out_string[count-1] = (NATIVE_CHAR) ('0' + remainder); + (void) acpi_ut_short_divide (&value, 10, "ient, &remainder); + out_string[count-1] = (char) ('0' + remainder);\ + value = quotient; } - - return (AE_OK); } - +#endif diff -urN linux-2.4.21/drivers/acpi/fan.c linux-2.4.22/drivers/acpi/fan.c --- linux-2.4.21/drivers/acpi/fan.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/fan.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,296 @@ +/* + * acpi_fan.c - ACPI Fan Driver ($Revision: 28 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_FAN_COMPONENT +ACPI_MODULE_NAME ("acpi_fan") + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +#define PREFIX "ACPI: " + + +int acpi_fan_add (struct acpi_device *device); +int acpi_fan_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_fan_driver = { + .name = ACPI_FAN_DRIVER_NAME, + .class = ACPI_FAN_CLASS, + .ids = ACPI_FAN_HID, + .ops = { + .add = acpi_fan_add, + .remove = acpi_fan_remove, + }, +}; + +struct acpi_fan { + acpi_handle handle; +}; + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_fan_dir = NULL; + + +static int +acpi_fan_read_state ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_fan *fan = (struct acpi_fan *) data; + char *p = page; + int len = 0; + int state = 0; + + ACPI_FUNCTION_TRACE("acpi_fan_read_state"); + + if (!fan || (off != 0)) + goto end; + + if (acpi_bus_get_power(fan->handle, &state)) + goto end; + + p += sprintf(p, "status: %s\n", + !state?"on":"off"); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_fan_write_state ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_fan *fan = (struct acpi_fan *) data; + char state_string[12] = {'\0'}; + + ACPI_FUNCTION_TRACE("acpi_fan_write_state"); + + if (!fan || (count > sizeof(state_string) - 1)) + return_VALUE(-EINVAL); + + if (copy_from_user(state_string, buffer, count)) + return_VALUE(-EFAULT); + + state_string[count] = '\0'; + + result = acpi_bus_set_power(fan->handle, + simple_strtoul(state_string, NULL, 0)); + if (result) + return_VALUE(result); + + return_VALUE(count); +} + + +static int +acpi_fan_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_fan_add_fs"); + + if (!device) + return_VALUE(-EINVAL); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_fan_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + /* 'status' [R/W] */ + entry = create_proc_entry(ACPI_FAN_FILE_STATE, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_FAN_FILE_STATE)); + else { + entry->read_proc = acpi_fan_read_state; + entry->write_proc = acpi_fan_write_state; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + + +static int +acpi_fan_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_fan_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_fan_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +int +acpi_fan_add ( + struct acpi_device *device) +{ + int result = 0; + struct acpi_fan *fan = NULL; + int state = 0; + + ACPI_FUNCTION_TRACE("acpi_fan_add"); + + if (!device) + return_VALUE(-EINVAL); + + fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL); + if (!fan) + return_VALUE(-ENOMEM); + memset(fan, 0, sizeof(struct acpi_fan)); + + fan->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_FAN_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_FAN_CLASS); + acpi_driver_data(device) = fan; + + result = acpi_bus_get_power(fan->handle, &state); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error reading power state\n")); + goto end; + } + + result = acpi_fan_add_fs(device); + if (result) + goto end; + + printk(KERN_INFO PREFIX "%s [%s] (%s)\n", + acpi_device_name(device), acpi_device_bid(device), + !device->power.state?"on":"off"); + +end: + if (result) + kfree(fan); + + return_VALUE(result); +} + + +int +acpi_fan_remove ( + struct acpi_device *device, + int type) +{ + struct acpi_fan *fan = NULL; + + ACPI_FUNCTION_TRACE("acpi_fan_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + fan = (struct acpi_fan *) acpi_driver_data(device); + + acpi_fan_remove_fs(device); + + kfree(fan); + + return_VALUE(0); +} + + +int __init +acpi_fan_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_fan_init"); + + acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); + if (!acpi_fan_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_fan_driver); + if (result < 0) { + remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +void __exit +acpi_fan_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_fan_exit"); + + acpi_bus_unregister_driver(&acpi_fan_driver); + + remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); + + return_VOID; +} + + +module_init(acpi_fan_init); +module_exit(acpi_fan_exit); + diff -urN linux-2.4.21/drivers/acpi/hardware/Makefile linux-2.4.22/drivers/acpi/hardware/Makefile --- linux-2.4.21/drivers/acpi/hardware/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/hardware/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/hardware/hwacpi.c linux-2.4.22/drivers/acpi/hardware/hwacpi.c --- linux-2.4.21/drivers/acpi/hardware/hwacpi.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/hardware/hwacpi.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,40 +2,57 @@ /****************************************************************************** * * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface - * $Revision: 46 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" +#include #define _COMPONENT ACPI_HARDWARE - MODULE_NAME ("hwacpi") + ACPI_MODULE_NAME ("hwacpi") /****************************************************************************** * - * FUNCTION: Acpi_hw_initialize + * FUNCTION: acpi_hw_initialize * * PARAMETERS: None * @@ -49,182 +66,120 @@ acpi_hw_initialize ( void) { - acpi_status status = AE_OK; - u32 index; + acpi_status status; - FUNCTION_TRACE ("Hw_initialize"); + ACPI_FUNCTION_TRACE ("hw_initialize"); /* We must have the ACPI tables by the time we get here */ if (!acpi_gbl_FADT) { - acpi_gbl_restore_acpi_chipset = FALSE; - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No FADT!\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "A FADT is not loaded\n")); return_ACPI_STATUS (AE_NO_ACPI_TABLES); } - /* Identify current ACPI/legacy mode */ - - switch (acpi_gbl_system_flags & SYS_MODES_MASK) { - case (SYS_MODE_ACPI): - - acpi_gbl_original_mode = SYS_MODE_ACPI; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System supports ACPI mode only.\n")); - break; - - - case (SYS_MODE_LEGACY): - - acpi_gbl_original_mode = SYS_MODE_LEGACY; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Tables loaded from buffer, hardware assumed to support LEGACY mode only.\n")); - break; - + /* Sanity check the FADT for valid values */ - case (SYS_MODE_ACPI | SYS_MODE_LEGACY): - - if (acpi_hw_get_mode () == SYS_MODE_ACPI) { - acpi_gbl_original_mode = SYS_MODE_ACPI; - } - else { - acpi_gbl_original_mode = SYS_MODE_LEGACY; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "System supports both ACPI and LEGACY modes.\n")); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "System is currently in %s mode.\n", - (acpi_gbl_original_mode == SYS_MODE_ACPI) ? "ACPI" : "LEGACY")); - break; + status = acpi_ut_validate_fadt (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - - if (acpi_gbl_system_flags & SYS_MODE_ACPI) { - /* Target system supports ACPI mode */ - - /* - * The purpose of this code is to save the initial state - * of the ACPI event enable registers. An exit function will be - * registered which will restore this state when the application - * exits. The exit function will also clear all of the ACPI event - * status bits prior to restoring the original mode. - * - * The location of the PM1a_evt_blk enable registers is defined as the - * base of PM1a_evt_blk + DIV_2(PM1a_evt_blk_length). Since the spec further - * fully defines the PM1a_evt_blk to be a total of 4 bytes, the offset - * for the enable registers is always 2 from the base. It is hard - * coded here. If this changes in the spec, this code will need to - * be modified. The PM1b_evt_blk behaves as expected. - */ - acpi_gbl_pm1_enable_register_save = (u16) acpi_hw_register_read ( - ACPI_MTX_LOCK, PM1_EN); - - - /* - * The GPEs behave similarly, except that the length of the register - * block is not fixed, so the buffer must be allocated with malloc - */ - if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) && - acpi_gbl_FADT->gpe0blk_len) { - /* GPE0 specified in FADT */ - - acpi_gbl_gpe0enable_register_save = ACPI_MEM_ALLOCATE ( - DIV_2 (acpi_gbl_FADT->gpe0blk_len)); - if (!acpi_gbl_gpe0enable_register_save) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* Save state of GPE0 enable bits */ - - for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { - acpi_gbl_gpe0enable_register_save[index] = - (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index); - } - } - - else { - acpi_gbl_gpe0enable_register_save = NULL; - } - - if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) && - acpi_gbl_FADT->gpe1_blk_len) { - /* GPE1 defined */ - - acpi_gbl_gpe1_enable_register_save = ACPI_MEM_ALLOCATE ( - DIV_2 (acpi_gbl_FADT->gpe1_blk_len)); - if (!acpi_gbl_gpe1_enable_register_save) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* save state of GPE1 enable bits */ - - for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { - acpi_gbl_gpe1_enable_register_save[index] = - (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index); - } - } - - else { - acpi_gbl_gpe1_enable_register_save = NULL; - } - } - - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } /****************************************************************************** * - * FUNCTION: Acpi_hw_set_mode + * FUNCTION: acpi_hw_set_mode * * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY * * RETURN: Status * - * DESCRIPTION: Transitions the system into the requested mode or does nothing - * if the system is already in that mode. + * DESCRIPTION: Transitions the system into the requested mode. * ******************************************************************************/ acpi_status acpi_hw_set_mode ( - u32 mode) + u32 mode) { - acpi_status status = AE_NO_HARDWARE_RESPONSE; + acpi_status status; + u32 retry; + + ACPI_FUNCTION_TRACE ("hw_set_mode"); - FUNCTION_TRACE ("Hw_set_mode"); + /* + * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, + * system does not support mode transition. + */ + if (!acpi_gbl_FADT->smi_cmd) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No SMI_CMD in FADT, mode transition failed.\n")); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); + } + + /* + * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE + * in FADT: If it is zero, enabling or disabling is not supported. + * As old systems may have used zero for mode transition, + * we make sure both the numbers are zero to determine these + * transitions are not supported. + */ + if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No mode transition supported in this system.\n")); + return_ACPI_STATUS (AE_OK); + } + switch (mode) { + case ACPI_SYS_MODE_ACPI: - if (mode == SYS_MODE_ACPI) { /* BIOS should have disabled ALL fixed and GP events */ - acpi_os_write_port (acpi_gbl_FADT->smi_cmd, acpi_gbl_FADT->acpi_enable, 8); + status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->acpi_enable, 8); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n")); - } + break; + + case ACPI_SYS_MODE_LEGACY: - else if (mode == SYS_MODE_LEGACY) { /* * BIOS should clear all fixed status bits and restore fixed event * enable bits to default */ - acpi_os_write_port (acpi_gbl_FADT->smi_cmd, acpi_gbl_FADT->acpi_disable, 8); + status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->acpi_disable, 8); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable Legacy (non-ACPI) mode\n")); + break; + + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Give the platform some time to react */ + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - acpi_os_stall (20000); + /* + * Some hardware takes a LONG time to switch modes. Give them 3 sec to + * do so, but allow faster systems to proceed more quickly. + */ + retry = 3000; + while (retry) { + status = AE_NO_HARDWARE_RESPONSE; - if (acpi_hw_get_mode () == mode) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode)); - status = AE_OK; + if (acpi_hw_get_mode() == mode) { + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode)); + status = AE_OK; + break; + } + acpi_os_stall(1000); + retry--; } return_ACPI_STATUS (status); @@ -233,7 +188,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_hw_get_mode + * FUNCTION: acpi_hw_get_mode * * PARAMETERS: none * @@ -247,74 +202,25 @@ u32 acpi_hw_get_mode (void) { + acpi_status status; + u32 value; - FUNCTION_TRACE ("Hw_get_mode"); + ACPI_FUNCTION_TRACE ("hw_get_mode"); - if (acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, SCI_EN)) { - return_VALUE (SYS_MODE_ACPI); - } - else { - return_VALUE (SYS_MODE_LEGACY); - } -} - + /* If there's no smi_cmd port, then it's ACPI only hw */ + if (!acpi_gbl_FADT->smi_cmd) + return_VALUE (ACPI_SYS_MODE_ACPI); -/****************************************************************************** - * - * FUNCTION: Acpi_hw_get_mode_capabilities - * - * PARAMETERS: none - * - * RETURN: logical OR of SYS_MODE_ACPI and SYS_MODE_LEGACY determined at initial - * system state. - * - * DESCRIPTION: Returns capablities of system - * - ******************************************************************************/ - -u32 -acpi_hw_get_mode_capabilities (void) -{ - - FUNCTION_TRACE ("Hw_get_mode_capabilities"); - - - if (!(acpi_gbl_system_flags & SYS_MODES_MASK)) { - if (acpi_hw_get_mode () == SYS_MODE_LEGACY) { - /* - * Assume that if this call is being made, Acpi_init has been called - * and ACPI support has been established by the presence of the - * tables. Therefore since we're in SYS_MODE_LEGACY, the system - * must support both modes - */ - acpi_gbl_system_flags |= (SYS_MODE_ACPI | SYS_MODE_LEGACY); - } - - else { - /* TBD: [Investigate] !!! this may be unsafe... */ - /* - * system is is ACPI mode, so try to switch back to LEGACY to see if - * it is supported - */ - acpi_hw_set_mode (SYS_MODE_LEGACY); - - if (acpi_hw_get_mode () == SYS_MODE_LEGACY) { - /* Now in SYS_MODE_LEGACY, so both are supported */ - - acpi_gbl_system_flags |= (SYS_MODE_ACPI | SYS_MODE_LEGACY); - acpi_hw_set_mode (SYS_MODE_ACPI); - } - - else { - /* Still in SYS_MODE_ACPI so this must be an ACPI only system */ - - acpi_gbl_system_flags |= SYS_MODE_ACPI; - } - } + status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_VALUE (ACPI_SYS_MODE_LEGACY); } - return_VALUE (acpi_gbl_system_flags & SYS_MODES_MASK); + if (value) { + return_VALUE (ACPI_SYS_MODE_ACPI); + } + else { + return_VALUE (ACPI_SYS_MODE_LEGACY); + } } - - diff -urN linux-2.4.21/drivers/acpi/hardware/hwgpe.c linux-2.4.22/drivers/acpi/hardware/hwgpe.c --- linux-2.4.21/drivers/acpi/hardware/hwgpe.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/hardware/hwgpe.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,42 +2,58 @@ /****************************************************************************** * * Module Name: hwgpe - Low level GPE enable/disable/clear functions - * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "acnamesp.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_HARDWARE - MODULE_NAME ("hwgpe") + ACPI_MODULE_NAME ("hwgpe") /****************************************************************************** * - * FUNCTION: Acpi_hw_enable_gpe + * FUNCTION: acpi_hw_enable_gpe * - * PARAMETERS: Gpe_number - The GPE + * PARAMETERS: gpe_number - The GPE * * RETURN: None * @@ -45,43 +61,41 @@ * ******************************************************************************/ -void +acpi_status acpi_hw_enable_gpe ( - u32 gpe_number) + struct acpi_gpe_event_info *gpe_event_info) { - u32 in_byte; - u32 register_index; - u32 bit_mask; - - - FUNCTION_ENTRY (); + u32 in_byte; + acpi_status status; - /* - * Translate GPE number to index into global registers array. - */ - register_index = acpi_gbl_gpe_valid[gpe_number]; + ACPI_FUNCTION_ENTRY (); - /* - * Figure out the bit offset for this GPE within the target register. - */ - bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Read the current value of the register, set the appropriate bit * to enable the GPE, and write out the new register. */ - in_byte = 0; - acpi_os_read_port (acpi_gbl_gpe_registers[register_index].enable_addr, &in_byte, 8); - acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, - (in_byte | bit_mask), 8); + status = acpi_hw_low_level_read (8, &in_byte, + &gpe_event_info->register_info->enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Write with the new GPE bit enabled */ + + status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask), + &gpe_event_info->register_info->enable_address); + + return (status); } + /****************************************************************************** * - * FUNCTION: Acpi_hw_enable_gpe_for_wakeup + * FUNCTION: acpi_hw_enable_gpe_for_wakeup * - * PARAMETERS: Gpe_number - The GPE + * PARAMETERS: gpe_number - The GPE * * RETURN: None * @@ -92,36 +106,33 @@ void acpi_hw_enable_gpe_for_wakeup ( - u32 gpe_number) + struct acpi_gpe_event_info *gpe_event_info) { - u32 register_index; - u32 bit_mask; + struct acpi_gpe_register_info *gpe_register_info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); - /* - * Translate GPE number to index into global registers array. - */ - register_index = acpi_gbl_gpe_valid[gpe_number]; + /* Get the info block for the entire GPE register */ - /* - * Figure out the bit offset for this GPE within the target register. - */ - bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return; + } /* * Set the bit so we will not disable this when sleeping */ - acpi_gbl_gpe_registers[register_index].wake_enable |= bit_mask; + gpe_register_info->wake_enable |= gpe_event_info->bit_mask; } + /****************************************************************************** * - * FUNCTION: Acpi_hw_disable_gpe + * FUNCTION: acpi_hw_disable_gpe * - * PARAMETERS: Gpe_number - The GPE + * PARAMETERS: gpe_number - The GPE * * RETURN: None * @@ -129,45 +140,53 @@ * ******************************************************************************/ -void +acpi_status acpi_hw_disable_gpe ( - u32 gpe_number) + struct acpi_gpe_event_info *gpe_event_info) { - u32 in_byte; - u32 register_index; - u32 bit_mask; + u32 in_byte; + acpi_status status; + struct acpi_gpe_register_info *gpe_register_info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); - /* - * Translate GPE number to index into global registers array. - */ - register_index = acpi_gbl_gpe_valid[gpe_number]; + /* Get the info block for the entire GPE register */ - /* - * Figure out the bit offset for this GPE within the target register. - */ - bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return (AE_BAD_PARAMETER); + } /* * Read the current value of the register, clear the appropriate bit, * and write out the new register value to disable the GPE. */ - in_byte = 0; - acpi_os_read_port (acpi_gbl_gpe_registers[register_index].enable_addr, &in_byte, 8); - acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, - (in_byte & ~bit_mask), 8); + status = acpi_hw_low_level_read (8, &in_byte, + &gpe_register_info->enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Write the byte with this GPE bit cleared */ + + status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)), + &gpe_register_info->enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } - acpi_hw_disable_gpe_for_wakeup(gpe_number); + acpi_hw_disable_gpe_for_wakeup (gpe_event_info); + return (AE_OK); } + /****************************************************************************** * - * FUNCTION: Acpi_hw_disable_gpe_for_wakeup + * FUNCTION: acpi_hw_disable_gpe_for_wakeup * - * PARAMETERS: Gpe_number - The GPE + * PARAMETERS: gpe_number - The GPE * * RETURN: None * @@ -178,36 +197,33 @@ void acpi_hw_disable_gpe_for_wakeup ( - u32 gpe_number) + struct acpi_gpe_event_info *gpe_event_info) { - u32 register_index; - u32 bit_mask; + struct acpi_gpe_register_info *gpe_register_info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); - /* - * Translate GPE number to index into global registers array. - */ - register_index = acpi_gbl_gpe_valid[gpe_number]; + /* Get the info block for the entire GPE register */ - /* - * Figure out the bit offset for this GPE within the target register. - */ - bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return; + } /* * Clear the bit so we will disable this when sleeping */ - acpi_gbl_gpe_registers[register_index].wake_enable &= ~bit_mask; + gpe_register_info->wake_enable &= ~(gpe_event_info->bit_mask); } + /****************************************************************************** * - * FUNCTION: Acpi_hw_clear_gpe + * FUNCTION: acpi_hw_clear_gpe * - * PARAMETERS: Gpe_number - The GPE + * PARAMETERS: gpe_number - The GPE * * RETURN: None * @@ -215,40 +231,32 @@ * ******************************************************************************/ -void +acpi_status acpi_hw_clear_gpe ( - u32 gpe_number) + struct acpi_gpe_event_info *gpe_event_info) { - u32 register_index; - u32 bit_mask; + acpi_status status; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* - * Translate GPE number to index into global registers array. - */ - register_index = acpi_gbl_gpe_valid[gpe_number]; - - /* - * Figure out the bit offset for this GPE within the target register. - */ - bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; - - /* * Write a one to the appropriate bit in the status register to * clear this GPE. */ - acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, bit_mask, 8); + status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask, + &gpe_event_info->register_info->status_address); + + return (status); } /****************************************************************************** * - * FUNCTION: Acpi_hw_get_gpe_status + * FUNCTION: acpi_hw_get_gpe_status * - * PARAMETERS: Gpe_number - The GPE + * PARAMETERS: gpe_number - The GPE * * RETURN: None * @@ -256,127 +264,317 @@ * ******************************************************************************/ -void +acpi_status acpi_hw_get_gpe_status ( - u32 gpe_number, - acpi_event_status *event_status) + struct acpi_gpe_event_info *gpe_event_info, + acpi_event_status *event_status) { - u32 in_byte = 0; - u32 register_index = 0; - u32 bit_mask = 0; + u32 in_byte; + u8 bit_mask; + struct acpi_gpe_register_info *gpe_register_info; + acpi_status status; + acpi_event_status local_event_status = 0; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (!event_status) { - return; + return (AE_BAD_PARAMETER); } - (*event_status) = 0; + /* Get the info block for the entire GPE register */ - /* - * Translate GPE number to index into global registers array. - */ - register_index = acpi_gbl_gpe_valid[gpe_number]; + gpe_register_info = gpe_event_info->register_info; - /* - * Figure out the bit offset for this GPE within the target register. - */ - bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; + /* Get the register bitmask for this GPE */ + + bit_mask = gpe_event_info->bit_mask; + + /* GPE Enabled? */ + + status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - /* - * Enabled?: - */ - in_byte = 0; - acpi_os_read_port (acpi_gbl_gpe_registers[register_index].enable_addr, &in_byte, 8); if (bit_mask & in_byte) { - (*event_status) |= ACPI_EVENT_FLAG_ENABLED; + local_event_status |= ACPI_EVENT_FLAG_ENABLED; } - /* - * Enabled for wake?: - */ - if (bit_mask & acpi_gbl_gpe_registers[register_index].wake_enable) { - (*event_status) |= ACPI_EVENT_FLAG_WAKE_ENABLED; + /* GPE Enabled for wake? */ + + if (bit_mask & gpe_register_info->wake_enable) { + local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED; + } + + /* GPE active (set)? */ + + status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; } - /* - * Set? - */ - in_byte = 0; - acpi_os_read_port (acpi_gbl_gpe_registers[register_index].status_addr, &in_byte, 8); if (bit_mask & in_byte) { - (*event_status) |= ACPI_EVENT_FLAG_SET; + local_event_status |= ACPI_EVENT_FLAG_SET; } + + /* Set return value */ + + (*event_status) = local_event_status; + + +unlock_and_exit: + return (status); } + /****************************************************************************** * - * FUNCTION: Acpi_hw_disable_non_wakeup_gpes + * FUNCTION: acpi_hw_disable_gpe_block * - * PARAMETERS: None + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info * - * RETURN: None + * RETURN: Status * - * DESCRIPTION: Disable all non-wakeup GPEs - * Call with interrupts disabled. The interrupt handler also - * modifies Acpi_gbl_Gpe_registers[i].Enable, so it should not be - * given the chance to run until after non-wake GPEs are - * re-enabled. + * DESCRIPTION: Disable all GPEs within a GPE block * ******************************************************************************/ -void -acpi_hw_disable_non_wakeup_gpes ( - void) +acpi_status +acpi_hw_disable_gpe_block ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block) { - u32 i; + u32 i; + struct acpi_gpe_register_info *gpe_register_info; + acpi_status status; - FUNCTION_ENTRY (); - for (i = 0; i < acpi_gbl_gpe_register_count; i++) { + /* Get the register info for the entire GPE block */ + + gpe_register_info = gpe_block->register_info; + + /* Examine each GPE Register within the block */ + + for (i = 0; i < gpe_block->register_count; i++) { + status = acpi_hw_low_level_write (8, 0x00, + &gpe_block->register_info[i].enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_hw_clear_gpe_block + * + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Clear all GPEs within a GPE block + * + ******************************************************************************/ + +acpi_status +acpi_hw_clear_gpe_block ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block) +{ + u32 i; + struct acpi_gpe_register_info *gpe_register_info; + acpi_status status; + + + /* Get the register info for the entire GPE block */ + + gpe_register_info = gpe_block->register_info; + + /* Examine each GPE Register within the block */ + + for (i = 0; i < gpe_block->register_count; i++) { + status = acpi_hw_low_level_write (8, 0xFF, + &gpe_block->register_info[i].status_address); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_hw_disable_non_wakeup_gpe_block + * + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Disable all GPEs except wakeup GPEs in a GPE block + * + ******************************************************************************/ + +static acpi_status +acpi_hw_disable_non_wakeup_gpe_block ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block) +{ + u32 i; + struct acpi_gpe_register_info *gpe_register_info; + u32 in_value; + acpi_status status; + + + /* Get the register info for the entire GPE block */ + + gpe_register_info = gpe_block->register_info; + + /* Examine each GPE Register within the block */ + + for (i = 0; i < gpe_block->register_count; i++) { /* * Read the enabled status of all GPEs. We * will be using it to restore all the GPEs later. */ - acpi_os_read_port (acpi_gbl_gpe_registers[i].enable_addr, - &acpi_gbl_gpe_registers[i].enable, 8); + status = acpi_hw_low_level_read (8, &in_value, + &gpe_register_info->enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + + gpe_register_info->enable = (u8) in_value; /* - * Disable all GPEs but wakeup GPEs. + * Disable all GPEs except wakeup GPEs. */ - acpi_os_write_port(acpi_gbl_gpe_registers[i].enable_addr, - acpi_gbl_gpe_registers[i].wake_enable, 8); + status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable, + &gpe_register_info->enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + + gpe_register_info++; } + + return (AE_OK); } + /****************************************************************************** * - * FUNCTION: Acpi_hw_enable_non_wakeup_gpes + * FUNCTION: acpi_hw_disable_non_wakeup_gpes * * PARAMETERS: None * * RETURN: None * - * DESCRIPTION: Enable all non-wakeup GPEs we previously enabled. + * DESCRIPTION: Disable all non-wakeup GPEs + * Called with interrupts disabled. The interrupt handler also + * modifies gpe_register_info->Enable, so it should not be + * given the chance to run until after non-wake GPEs are + * re-enabled. * ******************************************************************************/ -void -acpi_hw_enable_non_wakeup_gpes ( +acpi_status +acpi_hw_disable_non_wakeup_gpes ( void) { - u32 i; + acpi_status status; + + + ACPI_FUNCTION_ENTRY (); + + + status = acpi_ev_walk_gpe_list (acpi_hw_disable_non_wakeup_gpe_block); + + return (status); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_hw_enable_non_wakeup_gpe_block + * + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Enable a single GPE. + * + ******************************************************************************/ + +static acpi_status +acpi_hw_enable_non_wakeup_gpe_block ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block) +{ + u32 i; + struct acpi_gpe_register_info *gpe_register_info; + acpi_status status; + + + /* This callback processes one entire GPE block */ - FUNCTION_ENTRY (); + /* Get the register info for the entire GPE block */ - for (i = 0; i < acpi_gbl_gpe_register_count; i++) { + gpe_register_info = gpe_block->register_info; + + /* Examine each GPE register within the block */ + + for (i = 0; i < gpe_block->register_count; i++) { /* * We previously stored the enabled status of all GPEs. * Blast them back in. */ - acpi_os_write_port(acpi_gbl_gpe_registers[i].enable_addr, - acpi_gbl_gpe_registers[i].enable, 8); + status = acpi_hw_low_level_write (8, gpe_register_info->enable, + &gpe_register_info->enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + + gpe_register_info++; } + + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_hw_enable_non_wakeup_gpes + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Enable all non-wakeup GPEs we previously enabled. + * + ******************************************************************************/ + +acpi_status +acpi_hw_enable_non_wakeup_gpes ( + void) +{ + acpi_status status; + + + ACPI_FUNCTION_ENTRY (); + + + status = acpi_ev_walk_gpe_list (acpi_hw_enable_non_wakeup_gpe_block); + + return (status); } diff -urN linux-2.4.21/drivers/acpi/hardware/hwregs.c linux-2.4.22/drivers/acpi/hardware/hwregs.c --- linux-2.4.21/drivers/acpi/hardware/hwregs.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/hardware/hwregs.c 2003-08-25 04:44:41.000000000 -0700 @@ -3,71 +3,60 @@ * * Module Name: hwregs - Read/write access functions for the various ACPI * control and status registers. - * $Revision: 110 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_HARDWARE - MODULE_NAME ("hwregs") + ACPI_MODULE_NAME ("hwregs") /******************************************************************************* * - * FUNCTION: Acpi_hw_get_bit_shift + * FUNCTION: acpi_hw_clear_acpi_status * - * PARAMETERS: Mask - Input mask to determine bit shift from. - * Must have at least 1 bit set. - * - * RETURN: Bit location of the lsb of the mask - * - * DESCRIPTION: Returns the bit number for the low order bit that's set. - * - ******************************************************************************/ - -u32 -acpi_hw_get_bit_shift ( - u32 mask) -{ - u32 shift; - - - FUNCTION_TRACE ("Hw_get_bit_shift"); - - - for (shift = 0; ((mask >> shift) & 1) == 0; shift++) { ; } - - return_VALUE (shift); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_hw_clear_acpi_status - * - * PARAMETERS: none + * PARAMETERS: Flags - Lock the hardware or not * * RETURN: none * @@ -75,506 +64,403 @@ * ******************************************************************************/ -void -acpi_hw_clear_acpi_status (void) +acpi_status +acpi_hw_clear_acpi_status ( + u32 flags) { - u16 gpe_length; - u16 index; + acpi_status status; - FUNCTION_TRACE ("Hw_clear_acpi_status"); + ACPI_FUNCTION_TRACE ("hw_clear_acpi_status"); ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", - ALL_FIXED_STS_BITS, - (u16) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address))); + ACPI_BITMASK_ALL_FIXED_STATUS, + (u16) acpi_gbl_FADT->xpm1a_evt_blk.address)); - - acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); - - acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); - - - if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address)) { - acpi_os_write_port ((ACPI_IO_ADDRESS) - ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address), - ALL_FIXED_STS_BITS, 16); + if (flags & ACPI_MTX_LOCK) { + status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - /* now clear the GPE Bits */ + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, + ACPI_BITMASK_ALL_FIXED_STATUS); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - if (acpi_gbl_FADT->gpe0blk_len) { - gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); + /* Clear the fixed events */ - for (index = 0; index < gpe_length; index++) { - acpi_os_write_port ((ACPI_IO_ADDRESS) ( - ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + index), - 0xFF, 8); + if (acpi_gbl_FADT->xpm1b_evt_blk.address) { + status = acpi_hw_low_level_write (16, ACPI_BITMASK_ALL_FIXED_STATUS, + &acpi_gbl_FADT->xpm1b_evt_blk); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; } } - if (acpi_gbl_FADT->gpe1_blk_len) { - gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); + /* Clear the GPE Bits in all GPE registers in all GPE blocks */ - for (index = 0; index < gpe_length; index++) { - acpi_os_write_port ((ACPI_IO_ADDRESS) ( - ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + index), - 0xFF, 8); - } - } + status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block); - acpi_ut_release_mutex (ACPI_MTX_HARDWARE); - return_VOID; +unlock_and_exit: + if (flags & ACPI_MTX_LOCK) { + (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE); + } + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_hw_obtain_sleep_type_register_data + * FUNCTION: acpi_get_sleep_type_data * - * PARAMETERS: Sleep_state - Numeric state requested - * *Slp_Typ_a - Pointer to byte to receive SLP_TYPa value - * *Slp_Typ_b - Pointer to byte to receive SLP_TYPb value + * PARAMETERS: sleep_state - Numeric sleep state + * *sleep_type_a - Where SLP_TYPa is returned + * *sleep_type_b - Where SLP_TYPb is returned * * RETURN: Status - ACPI status * - * DESCRIPTION: Acpi_hw_obtain_sleep_type_register_data() obtains the SLP_TYP and - * SLP_TYPb values for the sleep state requested. + * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep + * state. * ******************************************************************************/ acpi_status -acpi_hw_obtain_sleep_type_register_data ( - u8 sleep_state, - u8 *slp_typ_a, - u8 *slp_typ_b) +acpi_get_sleep_type_data ( + u8 sleep_state, + u8 *sleep_type_a, + u8 *sleep_type_b) { - acpi_status status = AE_OK; - acpi_operand_object *obj_desc; + acpi_status status = AE_OK; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE ("Hw_obtain_sleep_type_register_data"); + ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data"); /* - * Validate parameters + * Validate parameters */ if ((sleep_state > ACPI_S_STATES_MAX) || - !slp_typ_a || !slp_typ_b) { + !sleep_type_a || !sleep_type_b) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* - * Acpi_evaluate the namespace object containing the values for this state + * Evaluate the namespace object containing the values for this state */ - status = acpi_ns_evaluate_by_name ((NATIVE_CHAR *) acpi_gbl_db_sleep_states[sleep_state], + status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_db_sleep_states[sleep_state], NULL, &obj_desc); if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n", + acpi_format_exception (status), acpi_gbl_db_sleep_states[sleep_state])); + return_ACPI_STATUS (status); } + /* Must have a return object */ + if (!obj_desc) { - REPORT_ERROR (("Missing Sleep State object\n")); - return_ACPI_STATUS (AE_NOT_EXIST); + ACPI_REPORT_ERROR (("Missing Sleep State object\n")); + status = AE_NOT_EXIST; } - /* - * We got something, now ensure it is correct. The object must - * be a package and must have at least 2 numeric values as the - * two elements - */ + /* It must be of type Package */ - /* Even though Acpi_evaluate_object resolves package references, - * Ns_evaluate dpesn't. So, we do it here. - */ - status = acpi_ut_resolve_package_references(obj_desc); + else if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_PACKAGE) { + ACPI_REPORT_ERROR (("Sleep State object not a Package\n")); + status = AE_AML_OPERAND_TYPE; + } - if (obj_desc->package.count < 2) { - /* Must have at least two elements */ + /* The package must have at least two elements */ - REPORT_ERROR (("Sleep State package does not have at least two elements\n")); - status = AE_ERROR; + else if (obj_desc->package.count < 2) { + ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n")); + status = AE_AML_NO_OPERAND; } - else if (((obj_desc->package.elements[0])->common.type != - ACPI_TYPE_INTEGER) || - ((obj_desc->package.elements[1])->common.type != - ACPI_TYPE_INTEGER)) { - /* Must have two */ + /* The first two elements must both be of type Integer */ - REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); - status = AE_ERROR; + else if ((ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[0]) != ACPI_TYPE_INTEGER) || + (ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[1]) != ACPI_TYPE_INTEGER)) { + ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n", + acpi_ut_get_object_type_name (obj_desc->package.elements[0]), + acpi_ut_get_object_type_name (obj_desc->package.elements[1]))); + status = AE_AML_OPERAND_TYPE; } - else { /* - * Valid _Sx_ package size, type, and value + * Valid _Sx_ package size, type, and value */ - *slp_typ_a = (u8) (obj_desc->package.elements[0])->integer.value; - - *slp_typ_b = (u8) (obj_desc->package.elements[1])->integer.value; + *sleep_type_a = (u8) (obj_desc->package.elements[0])->integer.value; + *sleep_type_b = (u8) (obj_desc->package.elements[1])->integer.value; } - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %X\n", - obj_desc, obj_desc->common.type)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n", + acpi_gbl_db_sleep_states[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc))); } acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_hw_register_bit_access + * FUNCTION: acpi_hw_get_register_bit_mask * - * PARAMETERS: Read_write - Either ACPI_READ or ACPI_WRITE. - * Use_lock - Lock the hardware - * Register_id - index of ACPI Register to access - * Value - (only used on write) value to write to the - * Register. Shifted all the way right. + * PARAMETERS: register_id - Index of ACPI Register to access * - * RETURN: Value written to or read from specified Register. This value - * is shifted all the way right. + * RETURN: The bit mask to be used when accessing the register * - * DESCRIPTION: Generic ACPI Register read/write function. + * DESCRIPTION: Map register_id into a register bit mask. * ******************************************************************************/ -u32 -acpi_hw_register_bit_access ( - NATIVE_UINT read_write, - u8 use_lock, - u32 register_id, - ...) /* Value (only used on write) */ +struct acpi_bit_register_info * +acpi_hw_get_bit_register_info ( + u32 register_id) { - u32 register_value = 0; - u32 mask = 0; - u32 value = 0; - va_list marker; - - - FUNCTION_TRACE ("Hw_register_bit_access"); + ACPI_FUNCTION_NAME ("hw_get_bit_register_info"); - if (read_write == ACPI_WRITE) { - va_start (marker, register_id); - value = va_arg (marker, u32); - va_end (marker); + if (register_id > ACPI_BITREG_MAX) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid bit_register ID: %X\n", register_id)); + return (NULL); } - if (ACPI_MTX_LOCK == use_lock) { - acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); - } + return (&acpi_gbl_bit_register_info[register_id]); +} - /* - * Decode the Register ID - * Register id = Register block id | bit id - * - * Check bit id to fine locate Register offset. - * Check Mask to determine Register offset, and then read-write. - */ - switch (REGISTER_BLOCK_ID (register_id)) { - case PM1_STS: - switch (register_id) { - case TMR_STS: - mask = TMR_STS_MASK; - break; +/******************************************************************************* + * + * FUNCTION: acpi_get_register + * + * PARAMETERS: register_id - ID of ACPI bit_register to access + * return_value - Value that was read from the register + * Flags - Lock the hardware or not + * + * RETURN: Value is read from specified Register. Value returned is + * normalized to bit0 (is shifted all the way right) + * + * DESCRIPTION: ACPI bit_register read function. + * + ******************************************************************************/ - case BM_STS: - mask = BM_STS_MASK; - break; +acpi_status +acpi_get_register ( + u32 register_id, + u32 *return_value, + u32 flags) +{ + u32 register_value = 0; + struct acpi_bit_register_info *bit_reg_info; + acpi_status status; - case GBL_STS: - mask = GBL_STS_MASK; - break; - case PWRBTN_STS: - mask = PWRBTN_STS_MASK; - break; + ACPI_FUNCTION_TRACE ("acpi_get_register"); - case SLPBTN_STS: - mask = SLPBTN_STS_MASK; - break; - case RTC_STS: - mask = RTC_STS_MASK; - break; + /* Get the info structure corresponding to the requested ACPI Register */ - case WAK_STS: - mask = WAK_STS_MASK; - break; + bit_reg_info = acpi_hw_get_bit_register_info (register_id); + if (!bit_reg_info) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - default: - mask = 0; - break; + if (flags & ACPI_MTX_LOCK) { + status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + } + + status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + bit_reg_info->parent_register, ®ister_value); - register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS); + if (flags & ACPI_MTX_LOCK) { + (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE); + } - if (read_write == ACPI_WRITE) { - /* - * Status Registers are different from the rest. Clear by - * writing 1, writing 0 has no effect. So, the only relevent - * information is the single bit we're interested in, all - * others should be written as 0 so they will be left - * unchanged - */ - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; + if (ACPI_SUCCESS (status)) { + /* Normalize the value that was read */ - if (value) { - acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, - (u16) value); - register_value = 0; - } - } + register_value = ((register_value & bit_reg_info->access_bit_mask) + >> bit_reg_info->bit_position); - break; + *return_value = register_value; + ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %8.8X register %X\n", + register_value, bit_reg_info->parent_register)); + } - case PM1_EN: + return_ACPI_STATUS (status); +} - switch (register_id) { - case TMR_EN: - mask = TMR_EN_MASK; - break; - case GBL_EN: - mask = GBL_EN_MASK; - break; +/******************************************************************************* + * + * FUNCTION: acpi_set_register + * + * PARAMETERS: register_id - ID of ACPI bit_register to access + * Value - (only used on write) value to write to the + * Register, NOT pre-normalized to the bit pos. + * Flags - Lock the hardware or not + * + * RETURN: None + * + * DESCRIPTION: ACPI Bit Register write function. + * + ******************************************************************************/ - case PWRBTN_EN: - mask = PWRBTN_EN_MASK; - break; +acpi_status +acpi_set_register ( + u32 register_id, + u32 value, + u32 flags) +{ + u32 register_value = 0; + struct acpi_bit_register_info *bit_reg_info; + acpi_status status; - case SLPBTN_EN: - mask = SLPBTN_EN_MASK; - break; - case RTC_EN: - mask = RTC_EN_MASK; - break; + ACPI_FUNCTION_TRACE_U32 ("acpi_set_register", register_id); - default: - mask = 0; - break; - } - register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN); + /* Get the info structure corresponding to the requested ACPI Register */ - if (read_write == ACPI_WRITE) { - register_value &= ~mask; - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; - register_value |= value; + bit_reg_info = acpi_hw_get_bit_register_info (register_id); + if (!bit_reg_info) { + ACPI_REPORT_ERROR (("Bad ACPI HW register_id: %X\n", register_id)); + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (u16) register_value); + if (flags & ACPI_MTX_LOCK) { + status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + } - break; + /* Always do a register read first so we can insert the new bits */ + status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + bit_reg_info->parent_register, ®ister_value); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - case PM1_CONTROL: + /* + * Decode the Register ID + * Register ID = [Register block ID] | [bit ID] + * + * Check bit ID to fine locate Register offset. + * Check Mask to determine Register offset, and then read-write. + */ + switch (bit_reg_info->parent_register) { + case ACPI_REGISTER_PM1_STATUS: - switch (register_id) { - case SCI_EN: - mask = SCI_EN_MASK; - break; + /* + * Status Registers are different from the rest. Clear by + * writing 1, and writing 0 has no effect. So, the only relevant + * information is the single bit we're interested in, all others should + * be written as 0 so they will be left unchanged. + */ + value = ACPI_REGISTER_PREPARE_BITS (value, + bit_reg_info->bit_position, bit_reg_info->access_bit_mask); + if (value) { + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_STATUS, (u16) value); + register_value = 0; + } + break; - case BM_RLD: - mask = BM_RLD_MASK; - break; - case GBL_RLS: - mask = GBL_RLS_MASK; - break; + case ACPI_REGISTER_PM1_ENABLE: - case SLP_TYPE_A: - case SLP_TYPE_B: - mask = SLP_TYPE_X_MASK; - break; + ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position, + bit_reg_info->access_bit_mask, value); - case SLP_EN: - mask = SLP_EN_MASK; - break; + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_ENABLE, (u16) register_value); + break; - default: - mask = 0; - break; - } + case ACPI_REGISTER_PM1_CONTROL: /* - * Read the PM1 Control register. + * Write the PM1 Control register. * Note that at this level, the fact that there are actually TWO - * registers (A and B) and that B may not exist, are abstracted. + * registers (A and B - and B may not exist) is abstracted. */ - register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); - ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", register_value)); - if (read_write == ACPI_WRITE) { - register_value &= ~mask; - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; - register_value |= value; + ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position, + bit_reg_info->access_bit_mask, value); - /* - * SLP_TYPE_x Registers are written differently - * than any other control Registers with - * respect to A and B Registers. The value - * for A may be different than the value for B - * - * Therefore, pass the Register_id, not just generic PM1_CONTROL, - * because we need to do different things. Yuck. - */ - acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id, - (u16) register_value); - } + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, (u16) register_value); break; - case PM2_CONTROL: + case ACPI_REGISTER_PM2_CONTROL: - switch (register_id) { - case ARB_DIS: - mask = ARB_DIS_MASK; - break; - - default: - mask = 0; - break; + status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM2_CONTROL, ®ister_value); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; } - register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); - ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", - register_value, HIDWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address), - LODWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address))); - - if (read_write == ACPI_WRITE) { - register_value &= ~mask; - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; - register_value |= value; - - ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", - register_value, - HIDWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address), - LODWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address))); - - acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, - PM2_CONTROL, (u8) (register_value)); - } - break; - - - case PM_TIMER: - - mask = TMR_VAL_MASK; - register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, - PM_TIMER); - ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM_TIMER: Read %X from %8.8X%8.8X\n", register_value, - HIDWORD(acpi_gbl_FADT->Xpm_tmr_blk.address), - LODWORD(acpi_gbl_FADT->Xpm_tmr_blk.address))); - - break; - - - case GPE1_EN_BLOCK: - case GPE1_STS_BLOCK: - case GPE0_EN_BLOCK: - case GPE0_STS_BLOCK: - - /* Determine the bit to be accessed - * - * (u32) Register_id: - * 31 24 16 8 0 - * +--------+--------+--------+--------+ - * | gpe_block_id | gpe_bit_number | - * +--------+--------+--------+--------+ - * - * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK - * gpe_bit_number is relative from the gpe_block (0x00~0xFF) - */ - mask = REGISTER_BIT_ID(register_id); /* gpe_bit_number */ - register_id = REGISTER_BLOCK_ID(register_id) | (mask >> 3); - mask = acpi_gbl_decode_to8bit [mask % 8]; - - /* - * The base address of the GPE 0 Register Block - * Plus 1/2 the length of the GPE 0 Register Block - * The enable Register is the Register following the Status Register - * and each Register is defined as 1/2 of the total Register Block - */ - - /* - * This sets the bit within Enable_bit that needs to be written to - * the Register indicated in Mask to a 1, all others are 0 - */ + ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address), + ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address))); - /* Now get the current Enable Bits in the selected Reg */ + ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position, + bit_reg_info->access_bit_mask, value); - register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id); - ACPI_DEBUG_PRINT ((ACPI_DB_IO, "GPE Enable bits: Read %X from %X\n", - register_value, register_id)); - - if (read_write == ACPI_WRITE) { - register_value &= ~mask; - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; - register_value |= value; + ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", + register_value, + ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address), + ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address))); - /* - * This write will put the Action state into the General Purpose - * Enable Register indexed by the value in Mask - */ - ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", - register_value, register_id)); - acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id, - (u8) register_value); - register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, - register_id); - } + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM2_CONTROL, (u8) (register_value)); break; - case SMI_CMD_BLOCK: - case PROCESSOR_BLOCK: - - /* Not used by any callers at this time - therefore, not implemented */ - default: - - mask = 0; break; } - if (ACPI_MTX_LOCK == use_lock) { - acpi_ut_release_mutex (ACPI_MTX_HARDWARE); + +unlock_and_exit: + + if (flags & ACPI_MTX_LOCK) { + (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE); } + /* Normalize the value that was read */ - register_value &= mask; - register_value >>= acpi_hw_get_bit_shift (mask); + ACPI_DEBUG_EXEC (register_value = ((register_value & bit_reg_info->access_bit_mask) >> bit_reg_info->bit_position)); - ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Register I/O: returning %X\n", register_value)); - return_VALUE (register_value); + ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n", + value, register_value, bit_reg_info->parent_register)); + return_ACPI_STATUS (status); } /****************************************************************************** * - * FUNCTION: Acpi_hw_register_read + * FUNCTION: acpi_hw_register_read * - * PARAMETERS: Use_lock - Mutex hw access. - * Register_id - Register_iD + Offset. + * PARAMETERS: use_lock - Mutex hw access. + * register_id - register_iD + Offset. * * RETURN: Value read or written. * @@ -583,112 +469,109 @@ * ******************************************************************************/ -u32 +acpi_status acpi_hw_register_read ( - u8 use_lock, - u32 register_id) + u8 use_lock, + u32 register_id, + u32 *return_value) { - u32 value = 0; - u32 bank_offset; + u32 value1 = 0; + u32 value2 = 0; + acpi_status status; - FUNCTION_TRACE ("Hw_register_read"); + ACPI_FUNCTION_TRACE ("hw_register_read"); if (ACPI_MTX_LOCK == use_lock) { - acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); + status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } + switch (register_id) { + case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ - switch (REGISTER_BLOCK_ID(register_id)) { - case PM1_STS: /* 16-bit access */ - - value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, 0); - value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, 0); - break; - + status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - case PM1_EN: /* 16-bit access*/ + /* PM1B is optional */ - bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); - value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset); - value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset); + status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk); + value1 |= value2; break; - case PM1_CONTROL: /* 16-bit access */ - - value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); - value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); - break; + case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ + status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_xpm1a_enable); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - case PM2_CONTROL: /* 8-bit access */ + /* PM1B is optional */ - value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xpm2_cnt_blk, 0); + status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_xpm1b_enable); + value1 |= value2; break; - case PM_TIMER: /* 32-bit access */ - - value = acpi_hw_low_level_read (32, &acpi_gbl_FADT->Xpm_tmr_blk, 0); - break; - + case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ - /* - * For the GPE? Blocks, the lower word of Register_id contains the - * byte offset for which to read, as each part of each block may be - * several bytes long. - */ - case GPE0_STS_BLOCK: /* 8-bit access */ + status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - bank_offset = REGISTER_BIT_ID(register_id); - value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset); + status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk); + value1 |= value2; break; - case GPE0_EN_BLOCK: /* 8-bit access */ - - bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len) + REGISTER_BIT_ID(register_id); - value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset); - break; - case GPE1_STS_BLOCK: /* 8-bit access */ + case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - bank_offset = REGISTER_BIT_ID(register_id); - value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); + status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk); break; - case GPE1_EN_BLOCK: /* 8-bit access */ - bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len) + REGISTER_BIT_ID(register_id); - value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); + case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ + + status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk); break; - case SMI_CMD_BLOCK: /* 8bit */ + case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ - acpi_os_read_port (acpi_gbl_FADT->smi_cmd, &value, 8); + status = acpi_os_read_port (acpi_gbl_FADT->smi_cmd, &value1, 8); break; default: - /* Value will be returned as 0 */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", register_id)); + status = AE_BAD_PARAMETER; break; } - +unlock_and_exit: if (ACPI_MTX_LOCK == use_lock) { - acpi_ut_release_mutex (ACPI_MTX_HARDWARE); + (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE); + } + + if (ACPI_SUCCESS (status)) { + *return_value = value1; } - return_VALUE (value); + return_ACPI_STATUS (status); } /****************************************************************************** * - * FUNCTION: Acpi_hw_register_write + * FUNCTION: acpi_hw_register_write * - * PARAMETERS: Use_lock - Mutex hw access. - * Register_id - Register_iD + Offset. + * PARAMETERS: use_lock - Mutex hw access. + * register_id - register_iD + Offset. * * RETURN: Value read or written. * @@ -697,179 +580,165 @@ * ******************************************************************************/ -void +acpi_status acpi_hw_register_write ( - u8 use_lock, - u32 register_id, - u32 value) + u8 use_lock, + u32 register_id, + u32 value) { - u32 bank_offset; + acpi_status status; - FUNCTION_TRACE ("Hw_register_write"); + ACPI_FUNCTION_TRACE ("hw_register_write"); if (ACPI_MTX_LOCK == use_lock) { - acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); + status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } + switch (register_id) { + case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ - switch (REGISTER_BLOCK_ID (register_id)) { - case PM1_STS: /* 16-bit access */ - - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, 0); - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, 0); - break; - - - case PM1_EN: /* 16-bit access*/ - - bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset); - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset); - break; - + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - case PM1_CONTROL: /* 16-bit access */ + /* PM1B is optional */ - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk); break; - case PM1A_CONTROL: /* 16-bit access */ - - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); - break; + case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ + status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1a_enable); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - case PM1B_CONTROL: /* 16-bit access */ + /* PM1B is optional */ - acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1b_enable); break; - case PM2_CONTROL: /* 8-bit access */ - - acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xpm2_cnt_blk, 0); - break; - + case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ - case PM_TIMER: /* 32-bit access */ + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } - acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->Xpm_tmr_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk); break; - case GPE0_STS_BLOCK: /* 8-bit access */ + case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ - bank_offset = REGISTER_BIT_ID(register_id); - acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk); break; - case GPE0_EN_BLOCK: /* 8-bit access */ + case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ - bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len) + REGISTER_BIT_ID(register_id); - acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk); break; - case GPE1_STS_BLOCK: /* 8-bit access */ + case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - bank_offset = REGISTER_BIT_ID(register_id); - acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); + status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk); break; - case GPE1_EN_BLOCK: /* 8-bit access */ + case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len) + REGISTER_BIT_ID(register_id); - acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); + status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk); break; - case SMI_CMD_BLOCK: /* 8bit */ + case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ - /* For 2.0, SMI_CMD is always in IO space */ - /* TBD: what about 1.0? 0.71? */ + /* SMI_CMD is currently always in IO space */ - acpi_os_write_port (acpi_gbl_FADT->smi_cmd, value, 8); + status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, value, 8); break; default: - value = 0; + status = AE_BAD_PARAMETER; break; } - +unlock_and_exit: if (ACPI_MTX_LOCK == use_lock) { - acpi_ut_release_mutex (ACPI_MTX_HARDWARE); + (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE); } - return_VOID; + return_ACPI_STATUS (status); } /****************************************************************************** * - * FUNCTION: Acpi_hw_low_level_read + * FUNCTION: acpi_hw_low_level_read * - * PARAMETERS: Register - GAS register structure - * Offset - Offset from the base address in the GAS - * Width - 8, 16, or 32 + * PARAMETERS: Width - 8, 16, or 32 + * Value - Where the value is returned + * Register - GAS register structure * - * RETURN: Value read + * RETURN: Status * * DESCRIPTION: Read from either memory, IO, or PCI config space. * ******************************************************************************/ -u32 +acpi_status acpi_hw_low_level_read ( - u32 width, - acpi_generic_address *reg, - u32 offset) + u32 width, + u32 *value, + struct acpi_generic_address *reg) { - u32 value = 0; - ACPI_PHYSICAL_ADDRESS mem_address; - ACPI_IO_ADDRESS io_address; - acpi_pci_id pci_id; - u16 pci_register; + struct acpi_pci_id pci_id; + u16 pci_register; + acpi_status status; - FUNCTION_ENTRY (); + ACPI_FUNCTION_NAME ("hw_low_level_read"); /* * Must have a valid pointer to a GAS structure, and - * a non-zero address within + * a non-zero address within. However, don't return an error + * because the PM1A/B code must not fail if B isn't present. */ if ((!reg) || - (!ACPI_VALID_ADDRESS (reg->address))) { - return 0; + (!reg->address)) { + return (AE_OK); } - + *value = 0; /* * Three address spaces supported: - * Memory, Io, or PCI config. + * Memory, IO, or PCI_Config. */ switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); - - acpi_os_read_memory (mem_address, &value, width); + status = acpi_os_read_memory ( + (acpi_physical_address) reg->address, + value, width); break; case ACPI_ADR_SPACE_SYSTEM_IO: - io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); - - acpi_os_read_port (io_address, &value, width); + status = acpi_os_read_port ((acpi_io_address) reg->address, + value, width); break; @@ -877,78 +746,86 @@ pci_id.segment = 0; pci_id.bus = 0; - pci_id.device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (reg->address)); - pci_id.function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (reg->address)); - pci_register = (u16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset); + pci_id.device = ACPI_PCI_DEVICE (reg->address); + pci_id.function = ACPI_PCI_FUNCTION (reg->address); + pci_register = (u16) ACPI_PCI_REGISTER (reg->address); - acpi_os_read_pci_configuration (&pci_id, pci_register, &value, width); + status = acpi_os_read_pci_configuration (&pci_id, pci_register, + value, width); break; + + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unsupported address space: %X\n", reg->address_space_id)); + return (AE_BAD_PARAMETER); } - return value; + ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", + *value, width, + ACPI_HIDWORD (reg->address), + ACPI_LODWORD (reg->address), + acpi_ut_get_region_name (reg->address_space_id))); + + return (status); } /****************************************************************************** * - * FUNCTION: Acpi_hw_low_level_write + * FUNCTION: acpi_hw_low_level_write * * PARAMETERS: Width - 8, 16, or 32 * Value - To be written * Register - GAS register structure - * Offset - Offset from the base address in the GAS - * * - * RETURN: Value read + * RETURN: Status * - * DESCRIPTION: Read from either memory, IO, or PCI config space. + * DESCRIPTION: Write to either memory, IO, or PCI config space. * ******************************************************************************/ -void +acpi_status acpi_hw_low_level_write ( - u32 width, - u32 value, - acpi_generic_address *reg, - u32 offset) + u32 width, + u32 value, + struct acpi_generic_address *reg) { - ACPI_PHYSICAL_ADDRESS mem_address; - ACPI_IO_ADDRESS io_address; - acpi_pci_id pci_id; - u16 pci_register; + struct acpi_pci_id pci_id; + u16 pci_register; + acpi_status status; - FUNCTION_ENTRY (); + ACPI_FUNCTION_NAME ("hw_low_level_write"); /* * Must have a valid pointer to a GAS structure, and - * a non-zero address within + * a non-zero address within. However, don't return an error + * because the PM1A/B code must not fail if B isn't present. */ if ((!reg) || - (!ACPI_VALID_ADDRESS (reg->address))) { - return; + (!reg->address)) { + return (AE_OK); } - /* * Three address spaces supported: - * Memory, Io, or PCI config. + * Memory, IO, or PCI_Config. */ switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); - - acpi_os_write_memory (mem_address, value, width); + status = acpi_os_write_memory ( + (acpi_physical_address) reg->address, + value, width); break; case ACPI_ADR_SPACE_SYSTEM_IO: - io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); - - acpi_os_write_port (io_address, value, width); + status = acpi_os_write_port ((acpi_io_address) reg->address, + value, width); break; @@ -956,11 +833,26 @@ pci_id.segment = 0; pci_id.bus = 0; - pci_id.device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (reg->address)); - pci_id.function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (reg->address)); - pci_register = (u16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset); + pci_id.device = ACPI_PCI_DEVICE (reg->address); + pci_id.function = ACPI_PCI_FUNCTION (reg->address); + pci_register = (u16) ACPI_PCI_REGISTER (reg->address); - acpi_os_write_pci_configuration (&pci_id, pci_register, value, width); + status = acpi_os_write_pci_configuration (&pci_id, pci_register, + (acpi_integer) value, width); break; + + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unsupported address space: %X\n", reg->address_space_id)); + return (AE_BAD_PARAMETER); } + + ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", + value, width, + ACPI_HIDWORD (reg->address), + ACPI_LODWORD (reg->address), + acpi_ut_get_region_name (reg->address_space_id))); + + return (status); } diff -urN linux-2.4.21/drivers/acpi/hardware/hwsleep.c linux-2.4.22/drivers/acpi/hardware/hwsleep.c --- linux-2.4.21/drivers/acpi/hardware/hwsleep.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/hardware/hwsleep.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,70 +2,82 @@ /****************************************************************************** * * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface - * $Revision: 22 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "achware.h" +#include #define _COMPONENT ACPI_HARDWARE - MODULE_NAME ("hwsleep") + ACPI_MODULE_NAME ("hwsleep") /****************************************************************************** * - * FUNCTION: Acpi_set_firmware_waking_vector + * FUNCTION: acpi_set_firmware_waking_vector * - * PARAMETERS: Physical_address - Physical address of ACPI real mode + * PARAMETERS: physical_address - Physical address of ACPI real mode * entry point. * - * RETURN: AE_OK or AE_ERROR + * RETURN: Status * - * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS + * DESCRIPTION: access function for d_firmware_waking_vector field in FACS * ******************************************************************************/ acpi_status acpi_set_firmware_waking_vector ( - ACPI_PHYSICAL_ADDRESS physical_address) + acpi_physical_address physical_address) { - FUNCTION_TRACE ("Acpi_set_firmware_waking_vector"); - - - /* Make sure that we have an FACS */ + ACPI_FUNCTION_TRACE ("acpi_set_firmware_waking_vector"); - if (!acpi_gbl_FACS) { - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } /* Set the vector */ - if (acpi_gbl_FACS->vector_width == 32) { - * (u32 *) acpi_gbl_FACS->firmware_waking_vector = (u32) physical_address; + if (acpi_gbl_common_fACS.vector_width == 32) { + *(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector)) + = (u32) physical_address; } else { - *acpi_gbl_FACS->firmware_waking_vector = physical_address; + *acpi_gbl_common_fACS.firmware_waking_vector + = physical_address; } return_ACPI_STATUS (AE_OK); @@ -74,167 +86,300 @@ /****************************************************************************** * - * FUNCTION: Acpi_get_firmware_waking_vector + * FUNCTION: acpi_get_firmware_waking_vector * - * PARAMETERS: *Physical_address - Output buffer where contents of - * the Firmware_waking_vector field of + * PARAMETERS: *physical_address - Output buffer where contents of + * the firmware_waking_vector field of * the FACS will be stored. * * RETURN: Status * - * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS + * DESCRIPTION: Access function for firmware_waking_vector field in FACS * ******************************************************************************/ acpi_status acpi_get_firmware_waking_vector ( - ACPI_PHYSICAL_ADDRESS *physical_address) + acpi_physical_address *physical_address) { - FUNCTION_TRACE ("Acpi_get_firmware_waking_vector"); + ACPI_FUNCTION_TRACE ("acpi_get_firmware_waking_vector"); if (!physical_address) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Make sure that we have an FACS */ - - if (!acpi_gbl_FACS) { - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } - /* Get the vector */ - if (acpi_gbl_FACS->vector_width == 32) { - *physical_address = * (u32 *) acpi_gbl_FACS->firmware_waking_vector; + if (acpi_gbl_common_fACS.vector_width == 32) { + *physical_address = (acpi_physical_address) + *(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector)); } else { - *physical_address = *acpi_gbl_FACS->firmware_waking_vector; + *physical_address = + *acpi_gbl_common_fACS.firmware_waking_vector; } return_ACPI_STATUS (AE_OK); } + /****************************************************************************** * - * FUNCTION: Acpi_enter_sleep_state + * FUNCTION: acpi_enter_sleep_state_prep * - * PARAMETERS: Sleep_state - Which sleep state to enter + * PARAMETERS: sleep_state - Which sleep state to enter * * RETURN: Status * - * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) + * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) + * This function must execute with interrupts enabled. + * We break sleeping into 2 stages so that OSPM can handle + * various OS-specific tasks between the two steps. * ******************************************************************************/ acpi_status -acpi_enter_sleep_state ( - u8 sleep_state) +acpi_enter_sleep_state_prep ( + u8 sleep_state) { - acpi_status status; - acpi_object_list arg_list; - acpi_object arg; - u8 type_a; - u8 type_b; - u16 PM1Acontrol; - u16 PM1Bcontrol; + acpi_status status; + struct acpi_object_list arg_list; + union acpi_object arg; - FUNCTION_TRACE ("Acpi_enter_sleep_state"); + ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_prep"); /* * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */ - status = acpi_hw_obtain_sleep_type_register_data (sleep_state, &type_a, &type_b); - if (!ACPI_SUCCESS (status)) { - return status; + status = acpi_get_sleep_type_data (sleep_state, + &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - /* run the _PTS and _GTS methods */ + /* Setup parameter object */ - MEMSET(&arg_list, 0, sizeof(arg_list)); arg_list.count = 1; arg_list.pointer = &arg; - MEMSET(&arg, 0, sizeof(arg)); arg.type = ACPI_TYPE_INTEGER; arg.integer.value = sleep_state; - acpi_evaluate_object (NULL, "\\_PTS", &arg_list, NULL); - acpi_evaluate_object (NULL, "\\_GTS", &arg_list, NULL); + /* Run the _PTS and _GTS methods */ - /* clear wake status */ + status = acpi_evaluate_object (NULL, "\\_PTS", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + return_ACPI_STATUS (status); + } - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1); + status = acpi_evaluate_object (NULL, "\\_GTS", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + return_ACPI_STATUS (status); + } - disable (); + return_ACPI_STATUS (AE_OK); +} - acpi_hw_disable_non_wakeup_gpes(); - PM1Acontrol = (u16) acpi_hw_register_read (ACPI_MTX_LOCK, PM1_CONTROL); +/****************************************************************************** + * + * FUNCTION: acpi_enter_sleep_state + * + * PARAMETERS: sleep_state - Which sleep state to enter + * + * RETURN: Status + * + * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED + * + ******************************************************************************/ - ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Entering S%d\n", sleep_state)); +acpi_status +acpi_enter_sleep_state ( + u8 sleep_state) +{ + u32 PM1Acontrol; + u32 PM1Bcontrol; + struct acpi_bit_register_info *sleep_type_reg_info; + struct acpi_bit_register_info *sleep_enable_reg_info; + u32 in_value; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state"); + + + if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || + (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { + ACPI_REPORT_ERROR (("Sleep values out of range: A=%X B=%X\n", + acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); + return_ACPI_STATUS (AE_AML_OPERAND_VALUE); + } + + + sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A); + sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE); + + /* Clear wake status */ + + status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Disable BM arbitration */ + + status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_hw_disable_non_wakeup_gpes(); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Get current value of PM1A control */ + + status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", sleep_state)); - /* mask off SLP_EN and SLP_TYP fields */ + /* Clear SLP_EN and SLP_TYP fields */ - PM1Acontrol &= ~(SLP_TYPE_X_MASK | SLP_EN_MASK); + PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask); PM1Bcontrol = PM1Acontrol; - /* mask in SLP_TYP */ + /* Insert SLP_TYP bits */ - PM1Acontrol |= (type_a << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK)); - PM1Bcontrol |= (type_b << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK)); + PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); + PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); - /* write #1: fill in SLP_TYP data */ + /* Write #1: fill in SLP_TYP data */ - acpi_hw_register_write (ACPI_MTX_LOCK, PM1A_CONTROL, PM1Acontrol); - acpi_hw_register_write (ACPI_MTX_LOCK, PM1B_CONTROL, PM1Bcontrol); + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - /* mask in SLP_EN */ + /* Insert SLP_ENABLE bit */ - PM1Acontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK)); - PM1Bcontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK)); + PM1Acontrol |= sleep_enable_reg_info->access_bit_mask; + PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask; - /* flush caches */ + /* Write #2: SLP_TYP + SLP_EN */ - wbinvd(); + ACPI_FLUSH_CPU_CACHE (); - /* write #2: SLP_TYP + SLP_EN */ + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - acpi_hw_register_write (ACPI_MTX_LOCK, PM1A_CONTROL, PM1Acontrol); - acpi_hw_register_write (ACPI_MTX_LOCK, PM1B_CONTROL, PM1Bcontrol); + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* * Wait a second, then try again. This is to get S4/5 to work on all machines. */ if (sleep_state > ACPI_STATE_S3) { - acpi_os_stall(1000000); - - acpi_hw_register_write (ACPI_MTX_LOCK, PM1_CONTROL, - (1 << acpi_hw_get_bit_shift (SLP_EN_MASK))); + /* + * We wait so long to allow chipsets that poll this reg very slowly to + * still read the right value. Ideally, this entire block would go + * away entirely. + */ + acpi_os_stall (10000000); + + status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, + sleep_enable_reg_info->access_bit_mask); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - /* wait until we enter sleep state */ + /* Wait until we enter sleep state */ do { - acpi_os_stall(10000); - } - while (!acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, WAK_STS)); + status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - acpi_hw_enable_non_wakeup_gpes(); + /* Spin until we wake */ - enable (); + } while (!in_value); return_ACPI_STATUS (AE_OK); } + /****************************************************************************** * - * FUNCTION: Acpi_leave_sleep_state + * FUNCTION: acpi_enter_sleep_state_s4bios * - * PARAMETERS: Sleep_state - Which sleep state we just exited + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Perform a S4 bios request. + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED + * + ******************************************************************************/ + +acpi_status +acpi_enter_sleep_state_s4bios ( + void) +{ + u32 in_value; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios"); + + acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); + acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); + + acpi_hw_disable_non_wakeup_gpes(); + + ACPI_FLUSH_CPU_CACHE(); + + status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8); + + do { + acpi_os_stall(1000); + status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } while (!in_value); + + return_ACPI_STATUS (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: acpi_leave_sleep_state + * + * PARAMETERS: sleep_state - Which sleep state we just exited * * RETURN: Status * @@ -244,29 +389,49 @@ acpi_status acpi_leave_sleep_state ( - u8 sleep_state) + u8 sleep_state) { - acpi_object_list arg_list; - acpi_object arg; + struct acpi_object_list arg_list; + union acpi_object arg; + acpi_status status; - FUNCTION_TRACE ("Acpi_leave_sleep_state"); + ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state"); - MEMSET (&arg_list, 0, sizeof(arg_list)); + /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ + + acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; + + /* Setup parameter object */ + arg_list.count = 1; arg_list.pointer = &arg; - MEMSET (&arg, 0, sizeof(arg)); arg.type = ACPI_TYPE_INTEGER; arg.integer.value = sleep_state; - acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL); - acpi_evaluate_object (NULL, "\\_WAK", &arg_list, NULL); + /* Ignore any errors from these methods */ + + status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status))); + } + + status = acpi_evaluate_object (NULL, "\\_WAK", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status))); + } /* _WAK returns stuff - do we want to look at it? */ - acpi_hw_enable_non_wakeup_gpes(); + status = acpi_hw_enable_non_wakeup_gpes(); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - return_ACPI_STATUS (AE_OK); + /* Disable BM arbitration */ + status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); + + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/hardware/hwtimer.c linux-2.4.22/drivers/acpi/hardware/hwtimer.c --- linux-2.4.21/drivers/acpi/hardware/hwtimer.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/hardware/hwtimer.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,38 +2,55 @@ /****************************************************************************** * * Name: hwtimer.c - ACPI Power Management Timer Interface - * $Revision: 14 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" +#include #define _COMPONENT ACPI_HARDWARE - MODULE_NAME ("hwtimer") + ACPI_MODULE_NAME ("hwtimer") /****************************************************************************** * - * FUNCTION: Acpi_get_timer_resolution + * FUNCTION: acpi_get_timer_resolution * * PARAMETERS: none * @@ -45,9 +62,9 @@ acpi_status acpi_get_timer_resolution ( - u32 *resolution) + u32 *resolution) { - FUNCTION_TRACE ("Acpi_get_timer_resolution"); + ACPI_FUNCTION_TRACE ("acpi_get_timer_resolution"); if (!resolution) { @@ -57,7 +74,6 @@ if (0 == acpi_gbl_FADT->tmr_val_ext) { *resolution = 24; } - else { *resolution = 32; } @@ -68,7 +84,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_get_timer + * FUNCTION: acpi_get_timer * * PARAMETERS: none * @@ -80,31 +96,33 @@ acpi_status acpi_get_timer ( - u32 *ticks) + u32 *ticks) { - FUNCTION_TRACE ("Acpi_get_timer"); + acpi_status status; + + + ACPI_FUNCTION_TRACE ("acpi_get_timer"); if (!ticks) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_os_read_port ((ACPI_IO_ADDRESS) - ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address), ticks, 32); + status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk); - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (status); } /****************************************************************************** * - * FUNCTION: Acpi_get_timer_duration + * FUNCTION: acpi_get_timer_duration * - * PARAMETERS: Start_ticks - * End_ticks - * Time_elapsed + * PARAMETERS: start_ticks + * end_ticks + * time_elapsed * - * RETURN: Time_elapsed + * RETURN: time_elapsed * * DESCRIPTION: Computes the time elapsed (in microseconds) between two * PM Timer time stamps, taking into account the possibility of @@ -115,27 +133,29 @@ * transitions (unlike many CPU timestamp counters) -- making it * a versatile and accurate timer. * - * Note that this function accomodates only a single timer + * Note that this function accommodates only a single timer * rollover. Thus for 24-bit timers, this function should only * be used for calculating durations less than ~4.6 seconds - * (~20 hours for 32-bit timers). + * (~20 minutes for 32-bit timers) -- calculations below + * + * 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec + * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes * ******************************************************************************/ acpi_status acpi_get_timer_duration ( - u32 start_ticks, - u32 end_ticks, - u32 *time_elapsed) + u32 start_ticks, + u32 end_ticks, + u32 *time_elapsed) { - u32 delta_ticks = 0; - u32 seconds = 0; - u32 milliseconds = 0; - u32 microseconds = 0; - u32 remainder = 0; + u32 delta_ticks = 0; + union uint64_overlay normalized_ticks; + acpi_status status; + acpi_integer out_quotient; - FUNCTION_TRACE ("Acpi_get_timer_duration"); + ACPI_FUNCTION_TRACE ("acpi_get_timer_duration"); if (!time_elapsed) { @@ -150,21 +170,18 @@ if (start_ticks < end_ticks) { delta_ticks = end_ticks - start_ticks; } - else if (start_ticks > end_ticks) { - /* 24-bit Timer */ - if (0 == acpi_gbl_FADT->tmr_val_ext) { + /* 24-bit Timer */ + delta_ticks = (((0x00FFFFFF - start_ticks) + end_ticks) & 0x00FFFFFF); } - - /* 32-bit Timer */ - else { + /* 32-bit Timer */ + delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks; } } - else { *time_elapsed = 0; return_ACPI_STATUS (AE_OK); @@ -173,49 +190,18 @@ /* * Compute Duration: * ----------------- - * Since certain compilers (gcc/Linux, argh!) don't support 64-bit - * divides in kernel-space we have to do some trickery to preserve - * accuracy while using 32-bit math. - * - * TBD: Change to use 64-bit math when supported. * - * The process is as follows: - * 1. Compute the number of seconds by dividing Delta Ticks by - * the timer frequency. - * 2. Compute the number of milliseconds in the remainder from step #1 - * by multiplying by 1000 and then dividing by the timer frequency. - * 3. Compute the number of microseconds in the remainder from step #2 - * by multiplying by 1000 and then dividing by the timer frequency. - * 4. Add the results from steps 1, 2, and 3 to get the total duration. + * Requires a 64-bit divide: * - * Example: The time elapsed for Delta_ticks = 0xFFFFFFFF should be - * 1199864031 microseconds. This is computed as follows: - * Step #1: Seconds = 1199; Remainder = 3092840 - * Step #2: Milliseconds = 864; Remainder = 113120 - * Step #3: Microseconds = 31; Remainder = + * time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY; */ + normalized_ticks.full = ((u64) delta_ticks) * 1000000; - /* Step #1 */ - - seconds = delta_ticks / PM_TIMER_FREQUENCY; - remainder = delta_ticks % PM_TIMER_FREQUENCY; - - /* Step #2 */ - - milliseconds = (remainder * 1000) / PM_TIMER_FREQUENCY; - remainder = (remainder * 1000) % PM_TIMER_FREQUENCY; + status = acpi_ut_short_divide (&normalized_ticks.full, PM_TIMER_FREQUENCY, + &out_quotient, NULL); - /* Step #3 */ - - microseconds = (remainder * 1000) / PM_TIMER_FREQUENCY; - - /* Step #4 */ - - *time_elapsed = seconds * 1000000; - *time_elapsed += milliseconds * 1000; - *time_elapsed += microseconds; - - return_ACPI_STATUS (AE_OK); + *time_elapsed = (u32) out_quotient; + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/include/acconfig.h linux-2.4.22/drivers/acpi/include/acconfig.h --- linux-2.4.21/drivers/acpi/include/acconfig.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acconfig.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,162 +0,0 @@ -/****************************************************************************** - * - * Name: acconfig.h - Global configuration constants - * $Revision: 74 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 _ACCONFIG_H -#define _ACCONFIG_H - - -/****************************************************************************** - * - * Compile-time options - * - *****************************************************************************/ - -/* - * ACPI_DEBUG - This switch enables all the debug facilities of the ACPI - * subsystem. This includes the DEBUG_PRINT output statements - * When disabled, all DEBUG_PRINT statements are compiled out. - * - * ACPI_APPLICATION - Use this switch if the subsystem is going to be run - * at the application level. - * - */ - - -/****************************************************************************** - * - * Subsystem Constants - * - *****************************************************************************/ - - -/* Version string */ - -#define ACPI_CA_VERSION 0x20011018 - -/* Version of ACPI supported */ - -#define ACPI_CA_SUPPORT_LEVEL 2 - - -/* Maximum objects in the various object caches */ - -#define MAX_STATE_CACHE_DEPTH 64 /* State objects for stacks */ -#define MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */ -#define MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */ -#define MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */ -#define MAX_WALK_CACHE_DEPTH 4 /* Objects for parse tree walks (method execution) */ - - -/* String size constants */ - -#define MAX_STRING_LENGTH 512 -#define PATHNAME_MAX 256 /* A full namespace pathname */ - - -/* Maximum count for a semaphore object */ - -#define MAX_SEMAPHORE_COUNT 256 - - -/* Max reference count (for debug only) */ - -#define MAX_REFERENCE_COUNT 0x400 - - -/* Size of cached memory mapping for system memory operation region */ - -#define SYSMEM_REGION_WINDOW_SIZE 4096 - - -/* - * Debugger threading model - * Use single threaded if the entire subsystem is contained in an application - * Use multiple threaded when the subsystem is running in the kernel. - * - * By default the model is single threaded if ACPI_APPLICATION is set, - * multi-threaded if ACPI_APPLICATION is not set. - */ - -#define DEBUGGER_SINGLE_THREADED 0 -#define DEBUGGER_MULTI_THREADED 1 - -#ifdef ACPI_APPLICATION -#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED - -#else -#define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED -#endif - - -/****************************************************************************** - * - * ACPI Specification constants (Do not change unless the specification changes) - * - *****************************************************************************/ - -/* - * Method info (in WALK_STATE), containing local variables and argumetns - */ - -#define MTH_NUM_LOCALS 8 -#define MTH_MAX_LOCAL 7 - -#define MTH_NUM_ARGS 7 -#define MTH_MAX_ARG 6 - -/* Maximum length of resulting string when converting from a buffer */ - -#define ACPI_MAX_STRING_CONVERSION 200 - -/* - * Operand Stack (in WALK_STATE), Must be large enough to contain MTH_MAX_ARG - */ - -#define OBJ_NUM_OPERANDS 8 -#define OBJ_MAX_OPERAND 7 - -/* Names within the namespace are 4 bytes long */ - -#define ACPI_NAME_SIZE 4 -#define PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 s8 for separator */ -#define PATH_SEPARATOR '.' - - -/* Constants used in searching for the RSDP in low memory */ - -#define LO_RSDP_WINDOW_BASE 0 /* Physical Address */ -#define HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */ -#define LO_RSDP_WINDOW_SIZE 0x400 -#define HI_RSDP_WINDOW_SIZE 0x20000 -#define RSDP_SCAN_STEP 16 - -/* Maximum Space_ids for Operation Regions */ - -#define ACPI_MAX_ADDRESS_SPACE 255 -#define ACPI_NUM_ADDRESS_SPACES 256 - - -#endif /* _ACCONFIG_H */ - diff -urN linux-2.4.21/drivers/acpi/include/acdebug.h linux-2.4.22/drivers/acpi/include/acdebug.h --- linux-2.4.21/drivers/acpi/include/acdebug.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acdebug.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,410 +0,0 @@ -/****************************************************************************** - * - * Name: acdebug.h - ACPI/AML debugger - * $Revision: 50 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACDEBUG_H__ -#define __ACDEBUG_H__ - - -#define DB_MAX_ARGS 8 /* Must be max method args + 1 */ - -#define DB_COMMAND_PROMPT '-' -#define DB_EXECUTE_PROMPT '%' - - -extern int optind; -extern NATIVE_CHAR *optarg; -extern u8 *aml_start; -extern u32 aml_length; - -extern u8 acpi_gbl_db_opt_tables; -extern u8 acpi_gbl_db_opt_disasm; -extern u8 acpi_gbl_db_opt_stats; -extern u8 acpi_gbl_db_opt_parse_jit; -extern u8 acpi_gbl_db_opt_verbose; -extern u8 acpi_gbl_db_opt_ini_methods; - - -extern NATIVE_CHAR *acpi_gbl_db_args[DB_MAX_ARGS]; -extern NATIVE_CHAR acpi_gbl_db_line_buf[80]; -extern NATIVE_CHAR acpi_gbl_db_scope_buf[40]; -extern NATIVE_CHAR acpi_gbl_db_debug_filename[40]; -extern u8 acpi_gbl_db_output_to_file; -extern NATIVE_CHAR *acpi_gbl_db_buffer; -extern NATIVE_CHAR *acpi_gbl_db_filename; -extern NATIVE_CHAR *acpi_gbl_db_disasm_indent; -extern u8 acpi_gbl_db_output_flags; -extern u32 acpi_gbl_db_debug_level; -extern u32 acpi_gbl_db_console_debug_level; -extern acpi_table_header *acpi_gbl_db_table_ptr; - -/* - * Statistic globals - */ -extern u16 acpi_gbl_obj_type_count[INTERNAL_TYPE_NODE_MAX+1]; -extern u16 acpi_gbl_node_type_count[INTERNAL_TYPE_NODE_MAX+1]; -extern u16 acpi_gbl_obj_type_count_misc; -extern u16 acpi_gbl_node_type_count_misc; -extern u32 acpi_gbl_num_nodes; -extern u32 acpi_gbl_num_objects; - - -extern u32 acpi_gbl_size_of_parse_tree; -extern u32 acpi_gbl_size_of_method_trees; -extern u32 acpi_gbl_size_of_node_entries; -extern u32 acpi_gbl_size_of_acpi_objects; - - -#define ACPI_DEBUG_BUFFER_SIZE 4196 - -#define DB_REDIRECTABLE_OUTPUT 0x01 -#define DB_CONSOLE_OUTPUT 0x02 -#define DB_DUPLICATE_OUTPUT 0x03 - - -typedef struct command_info -{ - NATIVE_CHAR *name; /* Command Name */ - u8 min_args; /* Minimum arguments required */ - -} COMMAND_INFO; - - -typedef struct argument_info -{ - NATIVE_CHAR *name; /* Argument Name */ - -} ARGUMENT_INFO; - - -#define PARAM_LIST(pl) pl - -#define DBTEST_OUTPUT_LEVEL(lvl) if (acpi_gbl_db_opt_verbose) - -#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\ - acpi_os_printf PARAM_LIST(fp);} - -#define EX_NO_SINGLE_STEP 1 -#define EX_SINGLE_STEP 2 - - -/* Prototypes */ - - -/* - * dbapi - external debugger interfaces - */ - -int -acpi_db_initialize ( - void); - -void -acpi_db_terminate ( - void); - -acpi_status -acpi_db_single_step ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - u32 op_type); - - -/* - * dbcmds - debug commands and output routines - */ - - -void -acpi_db_display_table_info ( - NATIVE_CHAR *table_arg); - -void -acpi_db_unload_acpi_table ( - NATIVE_CHAR *table_arg, - NATIVE_CHAR *instance_arg); - -void -acpi_db_set_method_breakpoint ( - NATIVE_CHAR *location, - acpi_walk_state *walk_state, - acpi_parse_object *op); - -void -acpi_db_set_method_call_breakpoint ( - acpi_parse_object *op); - -void -acpi_db_disassemble_aml ( - NATIVE_CHAR *statements, - acpi_parse_object *op); - -void -acpi_db_dump_namespace ( - NATIVE_CHAR *start_arg, - NATIVE_CHAR *depth_arg); - -void -acpi_db_dump_namespace_by_owner ( - NATIVE_CHAR *owner_arg, - NATIVE_CHAR *depth_arg); - -void -acpi_db_send_notify ( - NATIVE_CHAR *name, - u32 value); - -void -acpi_db_set_method_data ( - NATIVE_CHAR *type_arg, - NATIVE_CHAR *index_arg, - NATIVE_CHAR *value_arg); - -acpi_status -acpi_db_display_objects ( - NATIVE_CHAR *obj_type_arg, - NATIVE_CHAR *display_count_arg); - -acpi_status -acpi_db_find_name_in_namespace ( - NATIVE_CHAR *name_arg); - -void -acpi_db_set_scope ( - NATIVE_CHAR *name); - -void -acpi_db_find_references ( - NATIVE_CHAR *object_arg); - -void -acpi_db_display_locks (void); - - -void -acpi_db_display_resources ( - NATIVE_CHAR *object_arg); - - -/* - * dbdisasm - AML disassembler - */ - -void -acpi_db_display_op ( - acpi_walk_state *walk_state, - acpi_parse_object *origin, - u32 num_opcodes); - -void -acpi_db_display_namestring ( - NATIVE_CHAR *name); - -void -acpi_db_display_path ( - acpi_parse_object *op); - -void -acpi_db_display_opcode ( - acpi_walk_state *walk_state, - acpi_parse_object *op); - -void -acpi_db_decode_internal_object ( - acpi_operand_object *obj_desc); - - -/* - * dbdisply - debug display commands - */ - - -void -acpi_db_display_method_info ( - acpi_parse_object *op); - -void -acpi_db_decode_and_display_object ( - NATIVE_CHAR *target, - NATIVE_CHAR *output_type); - -void -acpi_db_display_result_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_db_display_all_methods ( - NATIVE_CHAR *display_count_arg); - -void -acpi_db_display_internal_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state); - -void -acpi_db_display_arguments ( - void); - -void -acpi_db_display_locals ( - void); - -void -acpi_db_display_results ( - void); - -void -acpi_db_display_calling_tree ( - void); - -void -acpi_db_display_argument_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state); - - -/* - * dbexec - debugger control method execution - */ - -void -acpi_db_execute ( - NATIVE_CHAR *name, - NATIVE_CHAR **args, - u32 flags); - -void -acpi_db_create_execution_threads ( - NATIVE_CHAR *num_threads_arg, - NATIVE_CHAR *num_loops_arg, - NATIVE_CHAR *method_name_arg); - - -/* - * dbfileio - Debugger file I/O commands - */ - -acpi_object_type8 -acpi_db_match_argument ( - NATIVE_CHAR *user_argument, - ARGUMENT_INFO *arguments); - - -void -acpi_db_close_debug_file ( - void); - -void -acpi_db_open_debug_file ( - NATIVE_CHAR *name); - -acpi_status -acpi_db_load_acpi_table ( - NATIVE_CHAR *filename); - - -/* - * dbhistry - debugger HISTORY command - */ - -void -acpi_db_add_to_history ( - NATIVE_CHAR *command_line); - -void -acpi_db_display_history (void); - -NATIVE_CHAR * -acpi_db_get_from_history ( - NATIVE_CHAR *command_num_arg); - - -/* - * dbinput - user front-end to the AML debugger - */ - -acpi_status -acpi_db_command_dispatch ( - NATIVE_CHAR *input_buffer, - acpi_walk_state *walk_state, - acpi_parse_object *op); - -void -acpi_db_execute_thread ( - void *context); - -acpi_status -acpi_db_user_commands ( - NATIVE_CHAR prompt, - acpi_parse_object *op); - - -/* - * dbstats - Generation and display of ACPI table statistics - */ - -void -acpi_db_generate_statistics ( - acpi_parse_object *root, - u8 is_method); - - -acpi_status -acpi_db_display_statistics ( - NATIVE_CHAR *type_arg); - - -/* - * dbutils - AML debugger utilities - */ - -void -acpi_db_set_output_destination ( - u32 where); - -void -acpi_db_dump_buffer ( - u32 address); - -void -acpi_db_dump_object ( - acpi_object *obj_desc, - u32 level); - -void -acpi_db_prep_namestring ( - NATIVE_CHAR *name); - - -acpi_status -acpi_db_second_pass_parse ( - acpi_parse_object *root); - -acpi_namespace_node * -acpi_db_local_ns_lookup ( - NATIVE_CHAR *name); - - -#endif /* __ACDEBUG_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acdispat.h linux-2.4.22/drivers/acpi/include/acdispat.h --- linux-2.4.21/drivers/acpi/include/acdispat.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acdispat.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,453 +0,0 @@ -/****************************************************************************** - * - * Name: acdispat.h - dispatcher (parser to interpreter interface) - * $Revision: 45 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 _ACDISPAT_H_ -#define _ACDISPAT_H_ - - -#define NAMEOF_LOCAL_NTE "__L0" -#define NAMEOF_ARG_NTE "__A0" - - -/* Common interfaces */ - -acpi_status -acpi_ds_obj_stack_push ( - void *object, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_obj_stack_pop ( - u32 pop_count, - acpi_walk_state *walk_state); - -void * -acpi_ds_obj_stack_get_value ( - u32 index, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_obj_stack_pop_object ( - acpi_operand_object **object, - acpi_walk_state *walk_state); - - -/* dsopcode - support for late evaluation */ - -acpi_status -acpi_ds_get_buffer_field_arguments ( - acpi_operand_object *obj_desc); - -acpi_status -acpi_ds_get_region_arguments ( - acpi_operand_object *rgn_desc); - - -/* dsctrl - Parser/Interpreter interface, control stack routines */ - - -acpi_status -acpi_ds_exec_begin_control_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op); - -acpi_status -acpi_ds_exec_end_control_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op); - - -/* dsexec - Parser/Interpreter interface, method execution callbacks */ - - -acpi_status -acpi_ds_get_predicate_value ( - acpi_walk_state *walk_state, - u32 has_result_obj); - -acpi_status -acpi_ds_exec_begin_op ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op); - -acpi_status -acpi_ds_exec_end_op ( - acpi_walk_state *state); - - -/* dsfield - Parser/Interpreter interface for AML fields */ - -acpi_status -acpi_ds_create_field ( - acpi_parse_object *op, - acpi_namespace_node *region_node, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_bank_field ( - acpi_parse_object *op, - acpi_namespace_node *region_node, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_index_field ( - acpi_parse_object *op, - acpi_namespace_node *region_node, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_buffer_field ( - acpi_parse_object *op, - acpi_walk_state *walk_state); - - -/* dsload - Parser/Interpreter interface, namespace load callbacks */ - -acpi_status -acpi_ds_load1_begin_op ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op); - -acpi_status -acpi_ds_load1_end_op ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_load2_begin_op ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op); - -acpi_status -acpi_ds_load2_end_op ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_init_callbacks ( - acpi_walk_state *walk_state, - u32 pass_number); - - -/* dsmthdat - method data (locals/args) */ - - -acpi_status -acpi_ds_store_object_to_local ( - u16 opcode, - u32 index, - acpi_operand_object *src_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_get_entry ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state, - acpi_operand_object ***node); - -acpi_status -acpi_ds_method_data_delete_all ( - acpi_walk_state *walk_state); - -u8 -acpi_ds_is_method_value ( - acpi_operand_object *obj_desc); - -acpi_object_type8 -acpi_ds_method_data_get_type ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_get_value ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state, - acpi_operand_object **dest_desc); - -acpi_status -acpi_ds_method_data_delete_value ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_init_args ( - acpi_operand_object **params, - u32 max_param_count, - acpi_walk_state *walk_state); - -acpi_namespace_node * -acpi_ds_method_data_get_node ( - u16 opcode, - u32 index, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_init ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_set_entry ( - u16 opcode, - u32 index, - acpi_operand_object *object, - acpi_walk_state *walk_state); - - -/* dsmethod - Parser/Interpreter interface - control method parsing */ - -acpi_status -acpi_ds_parse_method ( - acpi_handle obj_handle); - -acpi_status -acpi_ds_call_control_method ( - acpi_walk_list *walk_list, - acpi_walk_state *walk_state, - acpi_parse_object *op); - -acpi_status -acpi_ds_restart_control_method ( - acpi_walk_state *walk_state, - acpi_operand_object *return_desc); - -acpi_status -acpi_ds_terminate_control_method ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_begin_method_execution ( - acpi_namespace_node *method_node, - acpi_operand_object *obj_desc, - acpi_namespace_node *calling_method_node); - - -/* dsobj - Parser/Interpreter interface - object initialization and conversion */ - -acpi_status -acpi_ds_init_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - -acpi_status -acpi_ds_initialize_objects ( - acpi_table_desc *table_desc, - acpi_namespace_node *start_node); - -acpi_status -acpi_ds_build_internal_package_obj ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_operand_object **obj_desc); - -acpi_status -acpi_ds_build_internal_object ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_operand_object **obj_desc_ptr); - -acpi_status -acpi_ds_init_object_from_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - u16 opcode, - acpi_operand_object **obj_desc); - -acpi_status -acpi_ds_create_node ( - acpi_walk_state *walk_state, - acpi_namespace_node *node, - acpi_parse_object *op); - - -/* dsregn - Parser/Interpreter interface - Op Region parsing */ - -acpi_status -acpi_ds_eval_buffer_field_operands ( - acpi_walk_state *walk_state, - acpi_parse_object *op); - -acpi_status -acpi_ds_eval_region_operands ( - acpi_walk_state *walk_state, - acpi_parse_object *op); - -acpi_status -acpi_ds_initialize_region ( - acpi_handle obj_handle); - - -/* dsutils - Parser/Interpreter interface utility routines */ - -u8 -acpi_ds_is_result_used ( - acpi_parse_object *op, - acpi_walk_state *walk_state); - -void -acpi_ds_delete_result_if_not_used ( - acpi_parse_object *op, - acpi_operand_object *result_obj, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_operand ( - acpi_walk_state *walk_state, - acpi_parse_object *arg, - u32 args_remaining); - -acpi_status -acpi_ds_create_operands ( - acpi_walk_state *walk_state, - acpi_parse_object *first_arg); - -acpi_status -acpi_ds_resolve_operands ( - acpi_walk_state *walk_state); - -acpi_object_type8 -acpi_ds_map_opcode_to_data_type ( - u16 opcode, - u32 *out_flags); - -acpi_object_type8 -acpi_ds_map_named_opcode_to_data_type ( - u16 opcode); - - -/* - * dswscope - Scope Stack manipulation - */ - -acpi_status -acpi_ds_scope_stack_push ( - acpi_namespace_node *node, - acpi_object_type8 type, - acpi_walk_state *walk_state); - - -acpi_status -acpi_ds_scope_stack_pop ( - acpi_walk_state *walk_state); - -void -acpi_ds_scope_stack_clear ( - acpi_walk_state *walk_state); - - -/* dswstate - parser WALK_STATE management routines */ - -acpi_walk_state * -acpi_ds_create_walk_state ( - acpi_owner_id owner_id, - acpi_parse_object *origin, - acpi_operand_object *mth_desc, - acpi_walk_list *walk_list); - -acpi_status -acpi_ds_init_aml_walk ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_namespace_node *method_node, - u8 *aml_start, - u32 aml_length, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc, - u32 pass_number); - -acpi_status -acpi_ds_obj_stack_delete_all ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_obj_stack_pop_and_delete ( - u32 pop_count, - acpi_walk_state *walk_state); - -void -acpi_ds_delete_walk_state ( - acpi_walk_state *walk_state); - -acpi_walk_state * -acpi_ds_pop_walk_state ( - acpi_walk_list *walk_list); - -void -acpi_ds_push_walk_state ( - acpi_walk_state *walk_state, - acpi_walk_list *walk_list); - -acpi_status -acpi_ds_result_stack_pop ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_stack_push ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_stack_clear ( - acpi_walk_state *walk_state); - -acpi_walk_state * -acpi_ds_get_current_walk_state ( - acpi_walk_list *walk_list); - -void -acpi_ds_delete_walk_state_cache ( - void); - -acpi_status -acpi_ds_result_insert ( - void *object, - u32 index, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_remove ( - acpi_operand_object **object, - u32 index, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_pop ( - acpi_operand_object **object, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_push ( - acpi_operand_object *object, - acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_pop_from_bottom ( - acpi_operand_object **object, - acpi_walk_state *walk_state); - -#endif /* _ACDISPAT_H_ */ diff -urN linux-2.4.21/drivers/acpi/include/acevents.h linux-2.4.22/drivers/acpi/include/acevents.h --- linux-2.4.21/drivers/acpi/include/acevents.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acevents.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,217 +0,0 @@ -/****************************************************************************** - * - * Name: acevents.h - Event subcomponent prototypes and defines - * $Revision: 66 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACEVENTS_H__ -#define __ACEVENTS_H__ - - -acpi_status -acpi_ev_initialize ( - void); - - -/* - * Acpi_evfixed - Fixed event handling - */ - -acpi_status -acpi_ev_fixed_event_initialize ( - void); - -u32 -acpi_ev_fixed_event_detect ( - void); - -u32 -acpi_ev_fixed_event_dispatch ( - u32 acpi_event); - - -/* - * Acpi_evglock - Global Lock support - */ - -acpi_status -acpi_ev_acquire_global_lock( - void); - -void -acpi_ev_release_global_lock( - void); - -acpi_status -acpi_ev_init_global_lock_handler ( - void); - - -/* - * Acpi_evgpe - GPE handling and dispatch - */ - -acpi_status -acpi_ev_gpe_initialize ( - void); - -acpi_status -acpi_ev_init_gpe_control_methods ( - void); - -u32 -acpi_ev_gpe_dispatch ( - u32 gpe_number); - -u32 -acpi_ev_gpe_detect ( - void); - - -/* - * Acpi_evnotify - Device Notify handling and dispatch - */ - -acpi_status -acpi_ev_queue_notify_request ( - acpi_namespace_node *node, - u32 notify_value); - -void -acpi_ev_notify_dispatch ( - void *context); - -/* - * Acpi_evregion - Address Space handling - */ - -acpi_status -acpi_ev_install_default_address_space_handlers ( - void); - -acpi_status -acpi_ev_address_space_dispatch ( - acpi_operand_object *region_obj, - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value); - - -acpi_status -acpi_ev_addr_handler_helper ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - -void -acpi_ev_disassociate_region_from_handler( - acpi_operand_object *region_obj, - u8 acpi_ns_is_locked); - - -acpi_status -acpi_ev_associate_region_and_handler ( - acpi_operand_object *handler_obj, - acpi_operand_object *region_obj, - u8 acpi_ns_is_locked); - - -/* - * Acpi_evregini - Region initialization and setup - */ - -acpi_status -acpi_ev_system_memory_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_io_space_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_pci_config_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_cmos_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_pci_bar_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_default_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_initialize_region ( - acpi_operand_object *region_obj, - u8 acpi_ns_locked); - - -/* - * Evsci - SCI (System Control Interrupt) handling/dispatch - */ - -u32 -acpi_ev_install_sci_handler ( - void); - -acpi_status -acpi_ev_remove_sci_handler ( - void); - -u32 -acpi_ev_initialize_sCI ( - u32 program_sCI); - -void -acpi_ev_restore_acpi_state ( - void); - -void -acpi_ev_terminate ( - void); - - -#endif /* __ACEVENTS_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acexcep.h linux-2.4.22/drivers/acpi/include/acexcep.h --- linux-2.4.21/drivers/acpi/include/acexcep.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acexcep.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,248 +0,0 @@ -/****************************************************************************** - * - * Name: acexcep.h - Exception codes returned by the ACPI subsystem - * $Revision: 50 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACEXCEP_H__ -#define __ACEXCEP_H__ - - -/* - * Exceptions returned by external ACPI interfaces - */ - -#define AE_CODE_ENVIRONMENTAL 0x0000 -#define AE_CODE_PROGRAMMER 0x1000 -#define AE_CODE_ACPI_TABLES 0x2000 -#define AE_CODE_AML 0x3000 -#define AE_CODE_CONTROL 0x4000 -#define AE_CODE_MASK 0xF000 - - -#define ACPI_SUCCESS(a) (!(a)) -#define ACPI_FAILURE(a) (a) - - -#define AE_OK (acpi_status) 0x0000 - -/* - * Environmental exceptions - */ -#define AE_ERROR (acpi_status) (0x0001 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_ACPI_TABLES (acpi_status) (0x0002 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_NAMESPACE (acpi_status) (0x0003 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_MEMORY (acpi_status) (0x0004 | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_FOUND (acpi_status) (0x0005 | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_EXIST (acpi_status) (0x0006 | AE_CODE_ENVIRONMENTAL) -#define AE_EXIST (acpi_status) (0x0007 | AE_CODE_ENVIRONMENTAL) -#define AE_TYPE (acpi_status) (0x0008 | AE_CODE_ENVIRONMENTAL) -#define AE_NULL_OBJECT (acpi_status) (0x0009 | AE_CODE_ENVIRONMENTAL) -#define AE_NULL_ENTRY (acpi_status) (0x000A | AE_CODE_ENVIRONMENTAL) -#define AE_BUFFER_OVERFLOW (acpi_status) (0x000B | AE_CODE_ENVIRONMENTAL) -#define AE_STACK_OVERFLOW (acpi_status) (0x000C | AE_CODE_ENVIRONMENTAL) -#define AE_STACK_UNDERFLOW (acpi_status) (0x000D | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_IMPLEMENTED (acpi_status) (0x000E | AE_CODE_ENVIRONMENTAL) -#define AE_VERSION_MISMATCH (acpi_status) (0x000F | AE_CODE_ENVIRONMENTAL) -#define AE_SUPPORT (acpi_status) (0x0010 | AE_CODE_ENVIRONMENTAL) -#define AE_SHARE (acpi_status) (0x0011 | AE_CODE_ENVIRONMENTAL) -#define AE_LIMIT (acpi_status) (0x0012 | AE_CODE_ENVIRONMENTAL) -#define AE_TIME (acpi_status) (0x0013 | AE_CODE_ENVIRONMENTAL) -#define AE_UNKNOWN_STATUS (acpi_status) (0x0014 | AE_CODE_ENVIRONMENTAL) -#define AE_ACQUIRE_DEADLOCK (acpi_status) (0x0015 | AE_CODE_ENVIRONMENTAL) -#define AE_RELEASE_DEADLOCK (acpi_status) (0x0016 | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_ACQUIRED (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL) -#define AE_ALREADY_ACQUIRED (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_HARDWARE_RESPONSE (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_GLOBAL_LOCK (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) - -#define AE_CODE_ENV_MAX 0x001A - -/* - * Programmer exceptions - */ -#define AE_BAD_PARAMETER (acpi_status) (0x0001 | AE_CODE_PROGRAMMER) -#define AE_BAD_CHARACTER (acpi_status) (0x0002 | AE_CODE_PROGRAMMER) -#define AE_BAD_PATHNAME (acpi_status) (0x0003 | AE_CODE_PROGRAMMER) -#define AE_BAD_DATA (acpi_status) (0x0004 | AE_CODE_PROGRAMMER) -#define AE_BAD_ADDRESS (acpi_status) (0x0005 | AE_CODE_PROGRAMMER) - -#define AE_CODE_PGM_MAX 0x0005 - - -/* - * Acpi table exceptions - */ -#define AE_BAD_SIGNATURE (acpi_status) (0x0001 | AE_CODE_ACPI_TABLES) -#define AE_BAD_HEADER (acpi_status) (0x0002 | AE_CODE_ACPI_TABLES) -#define AE_BAD_CHECKSUM (acpi_status) (0x0003 | AE_CODE_ACPI_TABLES) -#define AE_BAD_VALUE (acpi_status) (0x0004 | AE_CODE_ACPI_TABLES) - -#define AE_CODE_TBL_MAX 0x0003 - - -/* - * AML exceptions. These are caused by problems with - * the actual AML byte stream - */ -#define AE_AML_ERROR (acpi_status) (0x0001 | AE_CODE_AML) -#define AE_AML_PARSE (acpi_status) (0x0002 | AE_CODE_AML) -#define AE_AML_BAD_OPCODE (acpi_status) (0x0003 | AE_CODE_AML) -#define AE_AML_NO_OPERAND (acpi_status) (0x0004 | AE_CODE_AML) -#define AE_AML_OPERAND_TYPE (acpi_status) (0x0005 | AE_CODE_AML) -#define AE_AML_OPERAND_VALUE (acpi_status) (0x0006 | AE_CODE_AML) -#define AE_AML_UNINITIALIZED_LOCAL (acpi_status) (0x0007 | AE_CODE_AML) -#define AE_AML_UNINITIALIZED_ARG (acpi_status) (0x0008 | AE_CODE_AML) -#define AE_AML_UNINITIALIZED_ELEMENT (acpi_status) (0x0009 | AE_CODE_AML) -#define AE_AML_NUMERIC_OVERFLOW (acpi_status) (0x000A | AE_CODE_AML) -#define AE_AML_REGION_LIMIT (acpi_status) (0x000B | AE_CODE_AML) -#define AE_AML_BUFFER_LIMIT (acpi_status) (0x000C | AE_CODE_AML) -#define AE_AML_PACKAGE_LIMIT (acpi_status) (0x000D | AE_CODE_AML) -#define AE_AML_DIVIDE_BY_ZERO (acpi_status) (0x000E | AE_CODE_AML) -#define AE_AML_BAD_NAME (acpi_status) (0x000F | AE_CODE_AML) -#define AE_AML_NAME_NOT_FOUND (acpi_status) (0x0010 | AE_CODE_AML) -#define AE_AML_INTERNAL (acpi_status) (0x0011 | AE_CODE_AML) -#define AE_AML_INVALID_SPACE_ID (acpi_status) (0x0012 | AE_CODE_AML) -#define AE_AML_STRING_LIMIT (acpi_status) (0x0013 | AE_CODE_AML) -#define AE_AML_NO_RETURN_VALUE (acpi_status) (0x0014 | AE_CODE_AML) -#define AE_AML_METHOD_LIMIT (acpi_status) (0x0015 | AE_CODE_AML) -#define AE_AML_NOT_OWNER (acpi_status) (0x0016 | AE_CODE_AML) -#define AE_AML_MUTEX_ORDER (acpi_status) (0x0017 | AE_CODE_AML) -#define AE_AML_MUTEX_NOT_ACQUIRED (acpi_status) (0x0018 | AE_CODE_AML) -#define AE_AML_INVALID_RESOURCE_TYPE (acpi_status) (0x0019 | AE_CODE_AML) - -#define AE_CODE_AML_MAX 0x0019 - -/* - * Internal exceptions used for control - */ -#define AE_CTRL_RETURN_VALUE (acpi_status) (0x0001 | AE_CODE_CONTROL) -#define AE_CTRL_PENDING (acpi_status) (0x0002 | AE_CODE_CONTROL) -#define AE_CTRL_TERMINATE (acpi_status) (0x0003 | AE_CODE_CONTROL) -#define AE_CTRL_TRUE (acpi_status) (0x0004 | AE_CODE_CONTROL) -#define AE_CTRL_FALSE (acpi_status) (0x0005 | AE_CODE_CONTROL) -#define AE_CTRL_DEPTH (acpi_status) (0x0006 | AE_CODE_CONTROL) -#define AE_CTRL_END (acpi_status) (0x0007 | AE_CODE_CONTROL) -#define AE_CTRL_TRANSFER (acpi_status) (0x0008 | AE_CODE_CONTROL) - -#define AE_CODE_CTRL_MAX 0x0008 - - -#ifdef DEFINE_ACPI_GLOBALS - -/* - * String versions of the exception codes above - * These strings must match the corresponding defines exactly - */ -NATIVE_CHAR const *acpi_gbl_exception_names_env[] = -{ - "AE_OK", - "AE_ERROR", - "AE_NO_ACPI_TABLES", - "AE_NO_NAMESPACE", - "AE_NO_MEMORY", - "AE_NOT_FOUND", - "AE_NOT_EXIST", - "AE_EXIST", - "AE_TYPE", - "AE_NULL_OBJECT", - "AE_NULL_ENTRY", - "AE_BUFFER_OVERFLOW", - "AE_STACK_OVERFLOW", - "AE_STACK_UNDERFLOW", - "AE_NOT_IMPLEMENTED", - "AE_VERSION_MISMATCH", - "AE_SUPPORT", - "AE_SHARE", - "AE_LIMIT", - "AE_TIME", - "AE_UNKNOWN_STATUS", - "AE_ACQUIRE_DEADLOCK", - "AE_RELEASE_DEADLOCK", - "AE_NOT_ACQUIRED", - "AE_ALREADY_ACQUIRED", - "AE_NO_HARDWARE_RESPONSE", - "AE_NO_GLOBAL_LOCK", -}; - -NATIVE_CHAR const *acpi_gbl_exception_names_pgm[] = -{ - "AE_BAD_PARAMETER", - "AE_BAD_CHARACTER", - "AE_BAD_PATHNAME", - "AE_BAD_DATA", - "AE_BAD_ADDRESS", -}; - -NATIVE_CHAR const *acpi_gbl_exception_names_tbl[] = -{ - "AE_BAD_SIGNATURE", - "AE_BAD_HEADER", - "AE_BAD_CHECKSUM", - "AE_BAD_VALUE", -}; - -NATIVE_CHAR const *acpi_gbl_exception_names_aml[] = -{ - "AE_AML_ERROR", - "AE_AML_PARSE", - "AE_AML_BAD_OPCODE", - "AE_AML_NO_OPERAND", - "AE_AML_OPERAND_TYPE", - "AE_AML_OPERAND_VALUE", - "AE_AML_UNINITIALIZED_LOCAL", - "AE_AML_UNINITIALIZED_ARG", - "AE_AML_UNINITIALIZED_ELEMENT", - "AE_AML_NUMERIC_OVERFLOW", - "AE_AML_REGION_LIMIT", - "AE_AML_BUFFER_LIMIT", - "AE_AML_PACKAGE_LIMIT", - "AE_AML_DIVIDE_BY_ZERO", - "AE_AML_BAD_NAME", - "AE_AML_NAME_NOT_FOUND", - "AE_AML_INTERNAL", - "AE_AML_INVALID_SPACE_ID", - "AE_AML_STRING_LIMIT", - "AE_AML_NO_RETURN_VALUE", - "AE_AML_METHOD_LIMIT", - "AE_AML_NOT_OWNER", - "AE_AML_MUTEX_ORDER", - "AE_AML_MUTEX_NOT_ACQUIRED", - "AE_AML_INVALID_RESOURCE_TYPE", -}; - -NATIVE_CHAR const *acpi_gbl_exception_names_ctrl[] = -{ - "AE_CTRL_RETURN_VALUE", - "AE_CTRL_PENDING", - "AE_CTRL_TERMINATE", - "AE_CTRL_TRUE", - "AE_CTRL_FALSE", - "AE_CTRL_DEPTH", - "AE_CTRL_END", - "AE_CTRL_TRANSFER", -}; - -#endif /* ACPI GLOBALS */ - - -#endif /* __ACEXCEP_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acglobal.h linux-2.4.22/drivers/acpi/include/acglobal.h --- linux-2.4.21/drivers/acpi/include/acglobal.h 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/include/acglobal.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,232 +0,0 @@ -/****************************************************************************** - * - * Name: acglobal.h - Declarations for global variables - * $Revision: 106 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACGLOBAL_H__ -#define __ACGLOBAL_H__ - - -/* - * Ensure that the globals are actually defined only once. - * - * The use of these defines allows a single list of globals (here) in order - * to simplify maintenance of the code. - */ -#ifdef DEFINE_ACPI_GLOBALS -#define ACPI_EXTERN -#else -#define ACPI_EXTERN extern -#endif - - -/***************************************************************************** - * - * Debug support - * - ****************************************************************************/ - -/* Runtime configuration of debug print levels */ - -extern u32 acpi_dbg_level; -extern u32 acpi_dbg_layer; - -/* Procedure nesting level for debug output */ - -extern u32 acpi_gbl_nesting_level; - - -/***************************************************************************** - * - * ACPI Table globals - * - ****************************************************************************/ - -/* - * Table pointers. - * Although these pointers are somewhat redundant with the global Acpi_table, - * they are convenient because they are typed pointers. - * - * These tables are single-table only; meaning that there can be at most one - * of each in the system. Each global points to the actual table. - * - */ -ACPI_EXTERN RSDP_DESCRIPTOR *acpi_gbl_RSDP; -ACPI_EXTERN xsdt_descriptor *acpi_gbl_XSDT; -ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT; -ACPI_EXTERN acpi_table_header *acpi_gbl_DSDT; -ACPI_EXTERN acpi_common_facs *acpi_gbl_FACS; - -/* - * Since there may be multiple SSDTs and PSDTS, a single pointer is not - * sufficient; Therefore, there isn't one! - */ - - -/* - * ACPI Table info arrays - */ -extern acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; -extern ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES]; - -/* - * Predefined mutex objects. This array contains the - * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs. - * (The table maps local handles to the real OS handles) - */ -ACPI_EXTERN acpi_mutex_info acpi_gbl_acpi_mutex_info [NUM_MTX]; - - -/***************************************************************************** - * - * Miscellaneous globals - * - ****************************************************************************/ - - -ACPI_EXTERN ACPI_MEMORY_LIST acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS]; -ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_drv_notify; -ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_sys_notify; -ACPI_EXTERN u8 *acpi_gbl_gpe0enable_register_save; -ACPI_EXTERN u8 *acpi_gbl_gpe1_enable_register_save; -ACPI_EXTERN acpi_walk_state *acpi_gbl_breakpoint_walk; -ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore; - -ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count; -ACPI_EXTERN u32 acpi_gbl_restore_acpi_chipset; -ACPI_EXTERN u32 acpi_gbl_original_mode; -ACPI_EXTERN u32 acpi_gbl_edge_level_save; -ACPI_EXTERN u32 acpi_gbl_irq_enable_save; -ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; -ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; -ACPI_EXTERN u32 acpi_gbl_ps_find_count; -ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; -ACPI_EXTERN u16 acpi_gbl_next_table_owner_id; -ACPI_EXTERN u16 acpi_gbl_next_method_owner_id; -ACPI_EXTERN u8 acpi_gbl_debugger_configuration; -ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; -ACPI_EXTERN u8 acpi_gbl_step_to_next_call; -ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; -ACPI_EXTERN u8 acpi_gbl_global_lock_present; - -extern u8 acpi_gbl_shutdown; -extern u32 acpi_gbl_system_flags; -extern u32 acpi_gbl_startup_flags; -extern const u8 acpi_gbl_decode_to8bit[8]; -extern const NATIVE_CHAR *acpi_gbl_db_sleep_states[ACPI_NUM_SLEEP_STATES]; - - -/***************************************************************************** - * - * Namespace globals - * - ****************************************************************************/ - -#define NUM_NS_TYPES INTERNAL_TYPE_INVALID+1 -#define NUM_PREDEFINED_NAMES 9 - - -ACPI_EXTERN acpi_namespace_node acpi_gbl_root_node_struct; -ACPI_EXTERN acpi_namespace_node *acpi_gbl_root_node; - -extern const u8 acpi_gbl_ns_properties[NUM_NS_TYPES]; -extern const predefined_names acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES]; - -#ifdef ACPI_DEBUG -ACPI_EXTERN u32 acpi_gbl_current_node_count; -ACPI_EXTERN u32 acpi_gbl_current_node_size; -ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count; -ACPI_EXTERN unsigned long acpi_gbl_entry_stack_pointer; -ACPI_EXTERN u32 acpi_gbl_lowest_stack_pointer; -ACPI_EXTERN u32 acpi_gbl_deepest_nesting; -#endif - -/***************************************************************************** - * - * Interpreter globals - * - ****************************************************************************/ - - -ACPI_EXTERN acpi_walk_list *acpi_gbl_current_walk_list; - -/* Address Space handlers */ - -ACPI_EXTERN acpi_adr_space_info acpi_gbl_address_spaces[ACPI_NUM_ADDRESS_SPACES]; - -/* Control method single step flag */ - -ACPI_EXTERN u8 acpi_gbl_cm_single_step; - - -/***************************************************************************** - * - * Parser globals - * - ****************************************************************************/ - -ACPI_EXTERN acpi_parse_object *acpi_gbl_parsed_namespace_root; - - -/***************************************************************************** - * - * Event globals - * - ****************************************************************************/ - -ACPI_EXTERN acpi_fixed_event_info acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]; -ACPI_EXTERN acpi_handle acpi_gbl_gpe_obj_handle; -ACPI_EXTERN u32 acpi_gbl_gpe_register_count; -ACPI_EXTERN acpi_gpe_registers *acpi_gbl_gpe_registers; -ACPI_EXTERN acpi_gpe_level_info *acpi_gbl_gpe_info; - -/* - * Gpe validation and translation table - * Indexed by the GPE number, returns GPE_INVALID if the GPE is not supported. - * Otherwise, returns a valid index into the global GPE table. - * - * This table is needed because the GPE numbers supported by block 1 do not - * have to be contiguous with the GPE numbers supported by block 0. - */ -ACPI_EXTERN u8 acpi_gbl_gpe_valid [ACPI_NUM_GPE]; - -/* Acpi_event counter for debug only */ - -#ifdef ACPI_DEBUG -ACPI_EXTERN u32 acpi_gbl_event_count[ACPI_NUM_FIXED_EVENTS]; -#endif - - -/***************************************************************************** - * - * Debugger globals - * - ****************************************************************************/ - -#ifdef ENABLE_DEBUGGER -ACPI_EXTERN u8 acpi_gbl_method_executing; -ACPI_EXTERN u8 acpi_gbl_db_terminate_threads; -#endif - - -#endif /* __ACGLOBAL_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/achware.h linux-2.4.22/drivers/acpi/include/achware.h --- linux-2.4.21/drivers/acpi/include/achware.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/achware.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,166 +0,0 @@ -/****************************************************************************** - * - * Name: achware.h -- hardware specific interfaces - * $Revision: 56 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACHWARE_H__ -#define __ACHWARE_H__ - - -/* PM Timer ticks per second (HZ) */ -#define PM_TIMER_FREQUENCY 3579545 - - -/* Prototypes */ - - -acpi_status -acpi_hw_initialize ( - void); - -acpi_status -acpi_hw_shutdown ( - void); - -acpi_status -acpi_hw_initialize_system_info ( - void); - -acpi_status -acpi_hw_set_mode ( - u32 mode); - -u32 -acpi_hw_get_mode ( - void); - -u32 -acpi_hw_get_mode_capabilities ( - void); - -/* Register I/O Prototypes */ - - -u32 -acpi_hw_register_bit_access ( - NATIVE_UINT read_write, - u8 use_lock, - u32 register_id, - ... /* DWORD Write Value */); - -u32 -acpi_hw_register_read ( - u8 use_lock, - u32 register_id); - -void -acpi_hw_register_write ( - u8 use_lock, - u32 register_id, - u32 value); - -u32 -acpi_hw_low_level_read ( - u32 width, - acpi_generic_address *reg, - u32 offset); - -void -acpi_hw_low_level_write ( - u32 width, - u32 value, - acpi_generic_address *reg, - u32 offset); - -void -acpi_hw_clear_acpi_status ( - void); - -u32 -acpi_hw_get_bit_shift ( - u32 mask); - - -/* GPE support */ - -void -acpi_hw_enable_gpe ( - u32 gpe_number); - -void -acpi_hw_enable_gpe_for_wakeup ( - u32 gpe_number); - -void -acpi_hw_disable_gpe ( - u32 gpe_number); - -void -acpi_hw_disable_gpe_for_wakeup ( - u32 gpe_number); - -void -acpi_hw_clear_gpe ( - u32 gpe_number); - -void -acpi_hw_get_gpe_status ( - u32 gpe_number, - acpi_event_status *event_status); - -void -acpi_hw_disable_non_wakeup_gpes ( - void); - -void -acpi_hw_enable_non_wakeup_gpes ( - void); - - -/* Sleep Prototypes */ - -acpi_status -acpi_hw_obtain_sleep_type_register_data ( - u8 sleep_state, - u8 *slp_typ_a, - u8 *slp_typ_b); - - -/* ACPI Timer prototypes */ - -acpi_status -acpi_get_timer_resolution ( - u32 *resolution); - -acpi_status -acpi_get_timer ( - u32 *ticks); - -acpi_status -acpi_get_timer_duration ( - u32 start_ticks, - u32 end_ticks, - u32 *time_elapsed); - - -#endif /* __ACHWARE_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acinterp.h linux-2.4.22/drivers/acpi/include/acinterp.h --- linux-2.4.21/drivers/acpi/include/acinterp.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acinterp.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,704 +0,0 @@ -/****************************************************************************** - * - * Name: acinterp.h - Interpreter subcomponent prototypes and defines - * $Revision: 116 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACINTERP_H__ -#define __ACINTERP_H__ - - -#define WALK_OPERANDS &(walk_state->operands [walk_state->num_operands -1]) - - -/* Interpreter constants */ - -#define AML_END_OF_BLOCK -1 -#define PUSH_PKG_LENGTH 1 -#define DO_NOT_PUSH_PKG_LENGTH 0 - - -#define STACK_TOP 0 -#define STACK_BOTTOM (u32) -1 - -/* Constants for global "When_to_parse_methods" */ - -#define METHOD_PARSE_AT_INIT 0x0 -#define METHOD_PARSE_JUST_IN_TIME 0x1 -#define METHOD_DELETE_AT_COMPLETION 0x2 - - -acpi_status -acpi_ex_resolve_operands ( - u16 opcode, - acpi_operand_object **stack_ptr, - acpi_walk_state *walk_state); - - -/* - * amxface - External interpreter interfaces - */ - -acpi_status -acpi_ex_load_table ( - acpi_table_type table_id); - -acpi_status -acpi_ex_execute_method ( - acpi_namespace_node *method_node, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc); - - -/* - * amconvrt - object conversion - */ - -acpi_status -acpi_ex_convert_to_integer ( - acpi_operand_object *obj_desc, - acpi_operand_object **result_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_convert_to_buffer ( - acpi_operand_object *obj_desc, - acpi_operand_object **result_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_convert_to_string ( - acpi_operand_object *obj_desc, - acpi_operand_object **result_desc, - u32 base, - u32 max_length, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_convert_to_target_type ( - acpi_object_type8 destination_type, - acpi_operand_object **obj_desc, - acpi_walk_state *walk_state); - - -/* - * amfield - ACPI AML (p-code) execution - field manipulation - */ - -acpi_status -acpi_ex_extract_from_field ( - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - -acpi_status -acpi_ex_insert_into_field ( - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - -acpi_status -acpi_ex_setup_field ( - acpi_operand_object *obj_desc, - u32 field_byte_offset); - -acpi_status -acpi_ex_read_field_datum ( - acpi_operand_object *obj_desc, - u32 field_byte_offset, - u32 *value); - -acpi_status -acpi_ex_common_access_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - - -acpi_status -acpi_ex_access_index_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - -acpi_status -acpi_ex_access_bank_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - -acpi_status -acpi_ex_access_region_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - - -acpi_status -acpi_ex_access_buffer_field ( - u32 mode, - acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - -acpi_status -acpi_ex_read_data_from_field ( - acpi_operand_object *obj_desc, - acpi_operand_object **ret_buffer_desc); - -acpi_status -acpi_ex_write_data_to_field ( - acpi_operand_object *source_desc, - acpi_operand_object *obj_desc); - -/* - * ammisc - ACPI AML (p-code) execution - specific opcodes - */ - -acpi_status -acpi_ex_opcode_3A_0T_0R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_3A_1T_1R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_6A_0T_1R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_get_object_reference ( - acpi_operand_object *obj_desc, - acpi_operand_object **return_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_do_concatenate ( - acpi_operand_object *obj_desc, - acpi_operand_object *obj_desc2, - acpi_operand_object **actual_return_desc, - acpi_walk_state *walk_state); - -u8 -acpi_ex_do_logical_op ( - u16 opcode, - acpi_integer operand0, - acpi_integer operand1); - -acpi_integer -acpi_ex_do_math_op ( - u16 opcode, - acpi_integer operand0, - acpi_integer operand1); - -acpi_status -acpi_ex_load_op ( - acpi_operand_object *rgn_desc, - acpi_operand_object *ddb_handle); - -acpi_status -acpi_ex_unload_table ( - acpi_operand_object *ddb_handle); - -acpi_status -acpi_ex_create_mutex ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_processor ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_power_resource ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_region ( - u8 *aml_start, - u32 aml_length, - u8 region_space, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_table_region ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_event ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_alias ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_method ( - u8 *aml_start, - u32 aml_length, - acpi_walk_state *walk_state); - - -/* - * ammutex - mutex support - */ - -acpi_status -acpi_ex_acquire_mutex ( - acpi_operand_object *time_desc, - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_release_mutex ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_release_all_mutexes ( - acpi_operand_object *mutex_list); - -void -acpi_ex_unlink_mutex ( - acpi_operand_object *obj_desc); - - -/* - * amprep - ACPI AML (p-code) execution - prep utilities - */ - -acpi_status -acpi_ex_prep_common_field_object ( - acpi_operand_object *obj_desc, - u8 field_flags, - u32 field_position, - u32 field_length); - -acpi_status -acpi_ex_prep_region_field_value ( - acpi_namespace_node *node, - acpi_handle region, - u8 field_flags, - u32 field_position, - u32 field_length); - -acpi_status -acpi_ex_prep_bank_field_value ( - acpi_namespace_node *node, - acpi_namespace_node *region_node, - acpi_namespace_node *bank_register_node, - u32 bank_val, - u8 field_flags, - u32 field_position, - u32 field_length); - -acpi_status -acpi_ex_prep_index_field_value ( - acpi_namespace_node *node, - acpi_namespace_node *index_reg, - acpi_namespace_node *data_reg, - u8 field_flags, - u32 field_position, - u32 field_length); - -acpi_status -acpi_ex_prep_field_value ( - ACPI_CREATE_FIELD_INFO *info); - -/* - * amsystem - Interface to OS services - */ - -acpi_status -acpi_ex_system_do_notify_op ( - acpi_operand_object *value, - acpi_operand_object *obj_desc); - -void -acpi_ex_system_do_suspend( - u32 time); - -void -acpi_ex_system_do_stall ( - u32 time); - -acpi_status -acpi_ex_system_acquire_mutex( - acpi_operand_object *time, - acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_release_mutex( - acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_signal_event( - acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_wait_event( - acpi_operand_object *time, - acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_reset_event( - acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_wait_semaphore ( - acpi_handle semaphore, - u32 timeout); - - -/* - * ammonadic - ACPI AML (p-code) execution, monadic operators - */ - -acpi_status -acpi_ex_opcode_1A_0T_0R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_1A_0T_1R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_1A_1T_1R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_1A_1T_0R ( - acpi_walk_state *walk_state); - -/* - * amdyadic - ACPI AML (p-code) execution, dyadic operators - */ - -acpi_status -acpi_ex_opcode_2A_0T_0R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_2A_0T_1R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_2A_1T_1R ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_2A_2T_1R ( - acpi_walk_state *walk_state); - - -/* - * amresolv - Object resolution and get value functions - */ - -acpi_status -acpi_ex_resolve_to_value ( - acpi_operand_object **stack_ptr, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_resolve_node_to_value ( - acpi_namespace_node **stack_ptr, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_resolve_object_to_value ( - acpi_operand_object **stack_ptr, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_get_buffer_field_value ( - acpi_operand_object *field_desc, - acpi_operand_object *result_desc); - - -/* - * amdump - Scanner debug output routines - */ - -void -acpi_ex_show_hex_value ( - u32 byte_count, - u8 *aml_start, - u32 lead_space); - - -acpi_status -acpi_ex_dump_operand ( - acpi_operand_object *entry_desc); - -void -acpi_ex_dump_operands ( - acpi_operand_object **operands, - operating_mode interpreter_mode, - NATIVE_CHAR *ident, - u32 num_levels, - NATIVE_CHAR *note, - NATIVE_CHAR *module_name, - u32 line_number); - -void -acpi_ex_dump_object_descriptor ( - acpi_operand_object *object, - u32 flags); - - -void -acpi_ex_dump_node ( - acpi_namespace_node *node, - u32 flags); - - -/* - * amnames - interpreter/scanner name load/execute - */ - -NATIVE_CHAR * -acpi_ex_allocate_name_string ( - u32 prefix_count, - u32 num_name_segs); - -u32 -acpi_ex_good_char ( - u32 character); - -acpi_status -acpi_ex_name_segment ( - u8 **in_aml_address, - NATIVE_CHAR *name_string); - -acpi_status -acpi_ex_get_name_string ( - acpi_object_type8 data_type, - u8 *in_aml_address, - NATIVE_CHAR **out_name_string, - u32 *out_name_length); - -acpi_status -acpi_ex_do_name ( - acpi_object_type data_type, - operating_mode load_exec_mode); - - -/* - * amstore - Object store support - */ - -acpi_status -acpi_ex_store ( - acpi_operand_object *val_desc, - acpi_operand_object *dest_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_store_object_to_index ( - acpi_operand_object *val_desc, - acpi_operand_object *dest_desc, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_store_object_to_node ( - acpi_operand_object *source_desc, - acpi_namespace_node *node, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_store_object_to_object ( - acpi_operand_object *source_desc, - acpi_operand_object *dest_desc, - acpi_walk_state *walk_state); - - -/* - * - */ - -acpi_status -acpi_ex_resolve_object ( - acpi_operand_object **source_desc_ptr, - acpi_object_type8 target_type, - acpi_walk_state *walk_state); - -acpi_status -acpi_ex_store_object ( - acpi_operand_object *source_desc, - acpi_object_type8 target_type, - acpi_operand_object **target_desc_ptr, - acpi_walk_state *walk_state); - - -/* - * amcopy - object copy - */ - -acpi_status -acpi_ex_copy_buffer_to_buffer ( - acpi_operand_object *source_desc, - acpi_operand_object *target_desc); - -acpi_status -acpi_ex_copy_string_to_string ( - acpi_operand_object *source_desc, - acpi_operand_object *target_desc); - -acpi_status -acpi_ex_copy_integer_to_index_field ( - acpi_operand_object *source_desc, - acpi_operand_object *target_desc); - -acpi_status -acpi_ex_copy_integer_to_bank_field ( - acpi_operand_object *source_desc, - acpi_operand_object *target_desc); - -acpi_status -acpi_ex_copy_data_to_named_field ( - acpi_operand_object *source_desc, - acpi_namespace_node *node); - -acpi_status -acpi_ex_copy_integer_to_buffer_field ( - acpi_operand_object *source_desc, - acpi_operand_object *target_desc); - -/* - * amutils - interpreter/scanner utilities - */ - -acpi_status -acpi_ex_enter_interpreter ( - void); - -void -acpi_ex_exit_interpreter ( - void); - -void -acpi_ex_truncate_for32bit_table ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state); - -u8 -acpi_ex_validate_object_type ( - acpi_object_type type); - -u8 -acpi_ex_acquire_global_lock ( - u32 rule); - -acpi_status -acpi_ex_release_global_lock ( - u8 locked); - -u32 -acpi_ex_digits_needed ( - acpi_integer value, - u32 base); - -acpi_status -acpi_ex_eisa_id_to_string ( - u32 numeric_id, - NATIVE_CHAR *out_string); - -acpi_status -acpi_ex_unsigned_integer_to_string ( - acpi_integer value, - NATIVE_CHAR *out_string); - - -/* - * amregion - default Op_region handlers - */ - -acpi_status -acpi_ex_system_memory_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_system_io_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_pci_config_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_cmos_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_pci_bar_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_embedded_controller_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_sm_bus_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - - -#endif /* __INTERP_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/aclocal.h linux-2.4.22/drivers/acpi/include/aclocal.h --- linux-2.4.21/drivers/acpi/include/aclocal.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/aclocal.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,973 +0,0 @@ -/****************************************************************************** - * - * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 138 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACLOCAL_H__ -#define __ACLOCAL_H__ - - -#define WAIT_FOREVER ((u32) -1) - -typedef void* acpi_mutex; -typedef u32 ACPI_MUTEX_HANDLE; - - -#define ACPI_MEMORY_MODE 0x01 -#define ACPI_LOGICAL_ADDRESSING 0x00 -#define ACPI_PHYSICAL_ADDRESSING 0x01 - -/* Object descriptor types */ - -#define ACPI_CACHED_OBJECT 0x11 /* ORed in when object is cached */ -#define ACPI_DESC_TYPE_STATE 0x20 -#define ACPI_DESC_TYPE_STATE_UPDATE 0x21 -#define ACPI_DESC_TYPE_STATE_PACKAGE 0x22 -#define ACPI_DESC_TYPE_STATE_CONTROL 0x23 -#define ACPI_DESC_TYPE_STATE_RPSCOPE 0x24 -#define ACPI_DESC_TYPE_STATE_PSCOPE 0x25 -#define ACPI_DESC_TYPE_STATE_WSCOPE 0x26 -#define ACPI_DESC_TYPE_STATE_RESULT 0x27 -#define ACPI_DESC_TYPE_STATE_NOTIFY 0x28 -#define ACPI_DESC_TYPE_WALK 0x44 -#define ACPI_DESC_TYPE_PARSER 0x66 -#define ACPI_DESC_TYPE_INTERNAL 0x88 -#define ACPI_DESC_TYPE_NAMED 0xAA - - -/***************************************************************************** - * - * Mutex typedefs and structs - * - ****************************************************************************/ - - -/* - * Predefined handles for the mutex objects used within the subsystem - * All mutex objects are automatically created by Acpi_ut_mutex_initialize. - * - * The acquire/release ordering protocol is implied via this list. Mutexes - * with a lower value must be acquired before mutexes with a higher value. - * - * NOTE: any changes here must be reflected in the Acpi_gbl_Mutex_names table also! - */ - -#define ACPI_MTX_EXECUTE 0 -#define ACPI_MTX_INTERPRETER 1 -#define ACPI_MTX_PARSER 2 -#define ACPI_MTX_DISPATCHER 3 -#define ACPI_MTX_TABLES 4 -#define ACPI_MTX_OP_REGIONS 5 -#define ACPI_MTX_NAMESPACE 6 -#define ACPI_MTX_EVENTS 7 -#define ACPI_MTX_HARDWARE 8 -#define ACPI_MTX_CACHES 9 -#define ACPI_MTX_MEMORY 10 -#define ACPI_MTX_DEBUG_CMD_COMPLETE 11 -#define ACPI_MTX_DEBUG_CMD_READY 12 - -#define MAX_MTX 12 -#define NUM_MTX MAX_MTX+1 - - -#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) -#ifdef DEFINE_ACPI_GLOBALS - -/* Names for the mutexes used in the subsystem */ - -static NATIVE_CHAR *acpi_gbl_mutex_names[] = -{ - "ACPI_MTX_Execute", - "ACPI_MTX_Interpreter", - "ACPI_MTX_Parser", - "ACPI_MTX_Dispatcher", - "ACPI_MTX_Tables", - "ACPI_MTX_Op_regions", - "ACPI_MTX_Namespace", - "ACPI_MTX_Events", - "ACPI_MTX_Hardware", - "ACPI_MTX_Caches", - "ACPI_MTX_Memory", - "ACPI_MTX_Debug_cmd_complete", - "ACPI_MTX_Debug_cmd_ready", -}; - -#endif -#endif - - -/* Table for the global mutexes */ - -typedef struct acpi_mutex_info -{ - acpi_mutex mutex; - u32 use_count; - u32 owner_id; - -} acpi_mutex_info; - -/* This owner ID means that the mutex is not in use (unlocked) */ - -#define ACPI_MUTEX_NOT_ACQUIRED (u32) (-1) - - -/* Lock flag parameter for various interfaces */ - -#define ACPI_MTX_DO_NOT_LOCK 0 -#define ACPI_MTX_LOCK 1 - - -typedef u16 acpi_owner_id; -#define OWNER_TYPE_TABLE 0x0 -#define OWNER_TYPE_METHOD 0x1 -#define FIRST_METHOD_ID 0x0000 -#define FIRST_TABLE_ID 0x8000 - -/* TBD: [Restructure] get rid of the need for this! */ - -#define TABLE_ID_DSDT (acpi_owner_id) 0x8000 - - -/* Field access granularities */ - -#define ACPI_FIELD_BYTE_GRANULARITY 1 -#define ACPI_FIELD_WORD_GRANULARITY 2 -#define ACPI_FIELD_DWORD_GRANULARITY 4 -#define ACPI_FIELD_QWORD_GRANULARITY 8 - -/***************************************************************************** - * - * Namespace typedefs and structs - * - ****************************************************************************/ - - -/* Operational modes of the AML interpreter/scanner */ - -typedef enum -{ - IMODE_LOAD_PASS1 = 0x01, - IMODE_LOAD_PASS2 = 0x02, - IMODE_EXECUTE = 0x0E - -} operating_mode; - - -/* - * The Node describes a named object that appears in the AML - * An Acpi_node is used to store Nodes. - * - * Data_type is used to differentiate between internal descriptors, and MUST - * be the first byte in this structure. - */ - -typedef struct acpi_node -{ - u8 data_type; - u8 type; /* Type associated with this name */ - u16 owner_id; - u32 name; /* ACPI Name, always 4 chars per ACPI spec */ - - - union acpi_operand_obj *object; /* Pointer to attached ACPI object (optional) */ - struct acpi_node *child; /* first child */ - struct acpi_node *peer; /* Next peer*/ - u16 reference_count; /* Current count of references and children */ - u8 flags; - -} acpi_namespace_node; - - -#define ENTRY_NOT_FOUND NULL - - -/* Node flags */ - -#define ANOBJ_AML_ATTACHMENT 0x01 -#define ANOBJ_END_OF_PEER_LIST 0x02 -#define ANOBJ_DATA_WIDTH_32 0x04 /* Parent table is 64-bits */ -#define ANOBJ_METHOD_ARG 0x08 -#define ANOBJ_METHOD_LOCAL 0x10 -#define ANOBJ_METHOD_NO_RETVAL 0x20 -#define ANOBJ_METHOD_SOME_NO_RETVAL 0x40 - -#define ANOBJ_IS_BIT_OFFSET 0x80 - - -/* - * ACPI Table Descriptor. One per ACPI table - */ -typedef struct acpi_table_desc -{ - struct acpi_table_desc *prev; - struct acpi_table_desc *next; - struct acpi_table_desc *installed_desc; - acpi_table_header *pointer; - void *base_pointer; - u8 *aml_start; - u64 physical_address; - u32 aml_length; - u32 length; - u32 count; - acpi_owner_id table_id; - u8 type; - u8 allocation; - u8 loaded_into_namespace; - -} acpi_table_desc; - - -typedef struct -{ - NATIVE_CHAR *search_for; - acpi_handle *list; - u32 *count; - -} find_context; - - -typedef struct -{ - acpi_namespace_node *node; -} ns_search_data; - - -/* - * Predefined Namespace items - */ -typedef struct -{ - NATIVE_CHAR *name; - acpi_object_type8 type; - NATIVE_CHAR *val; - -} predefined_names; - - -/* Object types used during package copies */ - - -#define ACPI_COPY_TYPE_SIMPLE 0 -#define ACPI_COPY_TYPE_PACKAGE 1 - -/* Info structure used to convert external<->internal namestrings */ - -typedef struct acpi_namestring_info -{ - NATIVE_CHAR *external_name; - NATIVE_CHAR *next_external_char; - NATIVE_CHAR *internal_name; - u32 length; - u32 num_segments; - u32 num_carats; - u8 fully_qualified; - -} acpi_namestring_info; - - -/* Field creation info */ - -typedef struct -{ - acpi_namespace_node *region_node; - acpi_namespace_node *field_node; - acpi_namespace_node *register_node; - acpi_namespace_node *data_register_node; - u32 bank_value; - u32 field_bit_position; - u32 field_bit_length; - u8 field_flags; - u8 field_type; - -} ACPI_CREATE_FIELD_INFO; - -/* - * Field flags: Bits 00 - 03 : Access_type (Any_acc, Byte_acc, etc.) - * 04 : Lock_rule (1 == Lock) - * 05 - 06 : Update_rule - */ - -#define FIELD_ACCESS_TYPE_MASK 0x0F -#define FIELD_LOCK_RULE_MASK 0x10 -#define FIELD_UPDATE_RULE_MASK 0x60 - - -/***************************************************************************** - * - * Event typedefs and structs - * - ****************************************************************************/ - - -/* Status bits. */ - -#define ACPI_STATUS_PMTIMER 0x0001 -#define ACPI_STATUS_BUSMASTER 0x0010 -#define ACPI_STATUS_GLOBAL 0x0020 -#define ACPI_STATUS_POWER_BUTTON 0x0100 -#define ACPI_STATUS_SLEEP_BUTTON 0x0200 -#define ACPI_STATUS_RTC_ALARM 0x0400 - -/* Enable bits. */ - -#define ACPI_ENABLE_PMTIMER 0x0001 -#define ACPI_ENABLE_GLOBAL 0x0020 -#define ACPI_ENABLE_POWER_BUTTON 0x0100 -#define ACPI_ENABLE_SLEEP_BUTTON 0x0200 -#define ACPI_ENABLE_RTC_ALARM 0x0400 - - -/* - * Entry in the Address_space (AKA Operation Region) table - */ - -typedef struct -{ - acpi_adr_space_handler handler; - void *context; - -} acpi_adr_space_info; - - -/* Values and addresses of the GPE registers (both banks) */ - -typedef struct -{ - u16 status_addr; /* Address of status reg */ - u16 enable_addr; /* Address of enable reg */ - u8 status; /* Current value of status reg */ - u8 enable; /* Current value of enable reg */ - u8 wake_enable; /* Mask of bits to keep enabled when sleeping */ - u8 gpe_base; /* Base GPE number */ - -} acpi_gpe_registers; - - -#define ACPI_GPE_LEVEL_TRIGGERED 1 -#define ACPI_GPE_EDGE_TRIGGERED 2 - - -/* Information about each particular GPE level */ - -typedef struct -{ - u8 type; /* Level or Edge */ - - acpi_handle method_handle; /* Method handle for direct (fast) execution */ - acpi_gpe_handler handler; /* Address of handler, if any */ - void *context; /* Context to be passed to handler */ - -} acpi_gpe_level_info; - - -/* Information about each particular fixed event */ - -typedef struct -{ - acpi_event_handler handler; /* Address of handler. */ - void *context; /* Context to be passed to handler */ - -} acpi_fixed_event_info; - - -/* Information used during field processing */ - -typedef struct -{ - u8 skip_field; - u8 field_flag; - u32 pkg_length; - -} acpi_field_info; - - -/***************************************************************************** - * - * Generic "state" object for stacks - * - ****************************************************************************/ - - -#define CONTROL_NORMAL 0xC0 -#define CONTROL_CONDITIONAL_EXECUTING 0xC1 -#define CONTROL_PREDICATE_EXECUTING 0xC2 -#define CONTROL_PREDICATE_FALSE 0xC3 -#define CONTROL_PREDICATE_TRUE 0xC4 - - -/* Forward declarations */ -struct acpi_walk_state; -struct acpi_walk_list; -struct acpi_parse_obj; -struct acpi_obj_mutex; - - -#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\ - u8 data_type; /* To differentiate various internal objs */\ - u8 flags; \ - u16 value; \ - u16 state; \ - u16 acpi_eval; \ - void *next; \ - -typedef struct acpi_common_state -{ - ACPI_STATE_COMMON -} acpi_common_state; - - -/* - * Update state - used to traverse complex objects such as packages - */ -typedef struct acpi_update_state -{ - ACPI_STATE_COMMON - union acpi_operand_obj *object; - -} acpi_update_state; - - -/* - * Pkg state - used to traverse nested package structures - */ -typedef struct acpi_pkg_state -{ - ACPI_STATE_COMMON - union acpi_operand_obj *source_object; - union acpi_operand_obj *dest_object; - struct acpi_walk_state *walk_state; - void *this_target_obj; - u32 num_packages; - u16 index; - -} acpi_pkg_state; - - -/* - * Control state - one per if/else and while constructs. - * Allows nesting of these constructs - */ -typedef struct acpi_control_state -{ - ACPI_STATE_COMMON - struct acpi_parse_obj *predicate_op; - u8 *aml_predicate_start; /* Start of if/while predicate */ - -} acpi_control_state; - - -/* - * Scope state - current scope during namespace lookups - */ -typedef struct acpi_scope_state -{ - ACPI_STATE_COMMON - acpi_namespace_node *node; - -} acpi_scope_state; - - -typedef struct acpi_pscope_state -{ - ACPI_STATE_COMMON - struct acpi_parse_obj *op; /* current op being parsed */ - u8 *arg_end; /* current argument end */ - u8 *pkg_end; /* current package end */ - u32 arg_list; /* next argument to parse */ - u32 arg_count; /* Number of fixed arguments */ - -} acpi_pscope_state; - - -/* - * Result values - used to accumulate the results of nested - * AML arguments - */ -typedef struct acpi_result_values -{ - ACPI_STATE_COMMON - union acpi_operand_obj *obj_desc [OBJ_NUM_OPERANDS]; - u8 num_results; - u8 last_insert; - -} acpi_result_values; - - -typedef -acpi_status (*acpi_parse_downwards) ( - struct acpi_walk_state *walk_state, - struct acpi_parse_obj **out_op); - -typedef -acpi_status (*acpi_parse_upwards) ( - struct acpi_walk_state *walk_state); - - -/* - * Notify info - used to pass info to the deferred notify - * handler/dispatcher. - */ -typedef struct acpi_notify_info -{ - ACPI_STATE_COMMON - acpi_namespace_node *node; - union acpi_operand_obj *handler_obj; - -} acpi_notify_info; - - -/* Generic state is union of structs above */ - -typedef union acpi_gen_state -{ - acpi_common_state common; - acpi_control_state control; - acpi_update_state update; - acpi_scope_state scope; - acpi_pscope_state parse_scope; - acpi_pkg_state pkg; - acpi_result_values results; - acpi_notify_info notify; - -} acpi_generic_state; - - -/***************************************************************************** - * - * Interpreter typedefs and structs - * - ****************************************************************************/ - -typedef -acpi_status (*ACPI_EXECUTE_OP) ( - struct acpi_walk_state *walk_state); - - -/***************************************************************************** - * - * Parser typedefs and structs - * - ****************************************************************************/ - -/* - * AML opcode, name, and argument layout - */ -typedef struct acpi_opcode_info -{ - u32 parse_args; /* Grammar/Parse time arguments */ - u32 runtime_args; /* Interpret time arguments */ - u16 flags; /* Misc flags */ - u8 class; /* Opcode class */ - u8 type; /* Opcode type */ - -#ifdef _OPCODE_NAMES - NATIVE_CHAR *name; /* op name (debug only) */ -#endif - -} acpi_opcode_info; - - -typedef union acpi_parse_val -{ - acpi_integer integer; /* integer constant (Up to 64 bits) */ - uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */ - u32 integer32; /* integer constant, 32 bits only */ - u16 integer16; /* integer constant, 16 bits only */ - u8 integer8; /* integer constant, 8 bits only */ - u32 size; /* bytelist or field size */ - NATIVE_CHAR *string; /* NULL terminated string */ - u8 *buffer; /* buffer or string */ - NATIVE_CHAR *name; /* NULL terminated string */ - struct acpi_parse_obj *arg; /* arguments and contained ops */ - -} acpi_parse_value; - - -#define ACPI_PARSE_COMMON \ - u8 data_type; /* To differentiate various internal objs */\ - u8 flags; /* Type of Op */\ - u16 opcode; /* AML opcode */\ - u32 aml_offset; /* offset of declaration in AML */\ - struct acpi_parse_obj *parent; /* parent op */\ - struct acpi_parse_obj *next; /* next op */\ - DEBUG_ONLY_MEMBERS (\ - NATIVE_CHAR op_name[16]) /* op name (debug only) */\ - /* NON-DEBUG members below: */\ - acpi_namespace_node *node; /* for use by interpreter */\ - acpi_parse_value value; /* Value or args associated with the opcode */\ - - -/* - * generic operation (eg. If, While, Store) - */ -typedef struct acpi_parse_obj -{ - ACPI_PARSE_COMMON -} acpi_parse_object; - - -/* - * Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and Op_regions), - * and bytelists. - */ -typedef struct acpi_parse2_obj -{ - ACPI_PARSE_COMMON - u8 *data; /* AML body or bytelist data */ - u32 length; /* AML length */ - u32 name; /* 4-byte name or zero if no name */ - -} acpi_parse2_object; - - -/* - * Parse state - one state per parser invocation and each control - * method. - */ -typedef struct acpi_parse_state -{ - u32 aml_size; - u8 *aml_start; /* first AML byte */ - u8 *aml; /* next AML byte */ - u8 *aml_end; /* (last + 1) AML byte */ - u8 *pkg_start; /* current package begin */ - u8 *pkg_end; /* current package end */ - - struct acpi_parse_obj *start_op; /* root of parse tree */ - struct acpi_node *start_node; - union acpi_gen_state *scope; /* current scope */ - - - struct acpi_parse_obj *start_scope; - - -} acpi_parse_state; - - -/***************************************************************************** - * - * Hardware and PNP - * - ****************************************************************************/ - - -/* PCI */ -#define PCI_ROOT_HID_STRING "PNP0A03" - -/* - * The #define's and enum below establish an abstract way of identifying what - * register block and register is to be accessed. Do not change any of the - * values as they are used in switch statements and offset calculations. - */ - -#define REGISTER_BLOCK_MASK 0xFF00 /* Register Block Id */ -#define BIT_IN_REGISTER_MASK 0x00FF /* Bit Id in the Register Block Id */ -#define BYTE_IN_REGISTER_MASK 0x00FF /* Register Offset in the Register Block */ - -#define REGISTER_BLOCK_ID(reg_id) (reg_id & REGISTER_BLOCK_MASK) -#define REGISTER_BIT_ID(reg_id) (reg_id & BIT_IN_REGISTER_MASK) -#define REGISTER_OFFSET(reg_id) (reg_id & BYTE_IN_REGISTER_MASK) - -/* - * Access Rule - * To access a Register Bit: - * -> Use Bit Name (= Register Block Id | Bit Id) defined in the enum. - * - * To access a Register: - * -> Use Register Id (= Register Block Id | Register Offset) - */ - - -/* - * Register Block Id - */ -#define PM1_STS 0x0100 -#define PM1_EN 0x0200 -#define PM1_CONTROL 0x0300 -#define PM1A_CONTROL 0x0400 -#define PM1B_CONTROL 0x0500 -#define PM2_CONTROL 0x0600 -#define PM_TIMER 0x0700 -#define PROCESSOR_BLOCK 0x0800 -#define GPE0_STS_BLOCK 0x0900 -#define GPE0_EN_BLOCK 0x0A00 -#define GPE1_STS_BLOCK 0x0B00 -#define GPE1_EN_BLOCK 0x0C00 -#define SMI_CMD_BLOCK 0x0D00 - -/* - * Address space bitmasks for mmio or io spaces - */ - -#define SMI_CMD_ADDRESS_SPACE 0x01 -#define PM1_BLK_ADDRESS_SPACE 0x02 -#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 -#define PM_TMR_BLK_ADDRESS_SPACE 0x08 -#define GPE0_BLK_ADDRESS_SPACE 0x10 -#define GPE1_BLK_ADDRESS_SPACE 0x20 - -/* - * Control bit definitions - */ -#define TMR_STS (PM1_STS | 0x01) -#define BM_STS (PM1_STS | 0x02) -#define GBL_STS (PM1_STS | 0x03) -#define PWRBTN_STS (PM1_STS | 0x04) -#define SLPBTN_STS (PM1_STS | 0x05) -#define RTC_STS (PM1_STS | 0x06) -#define WAK_STS (PM1_STS | 0x07) - -#define TMR_EN (PM1_EN | 0x01) - /* no BM_EN */ -#define GBL_EN (PM1_EN | 0x03) -#define PWRBTN_EN (PM1_EN | 0x04) -#define SLPBTN_EN (PM1_EN | 0x05) -#define RTC_EN (PM1_EN | 0x06) -#define WAK_EN (PM1_EN | 0x07) - -#define SCI_EN (PM1_CONTROL | 0x01) -#define BM_RLD (PM1_CONTROL | 0x02) -#define GBL_RLS (PM1_CONTROL | 0x03) -#define SLP_TYPE_A (PM1_CONTROL | 0x04) -#define SLP_TYPE_B (PM1_CONTROL | 0x05) -#define SLP_EN (PM1_CONTROL | 0x06) - -#define ARB_DIS (PM2_CONTROL | 0x01) - -#define TMR_VAL (PM_TIMER | 0x01) - -#define GPE0_STS (GPE0_STS_BLOCK | 0x01) -#define GPE0_EN (GPE0_EN_BLOCK | 0x01) - -#define GPE1_STS (GPE1_STS_BLOCK | 0x01) -#define GPE1_EN (GPE1_EN_BLOCK | 0x01) - - -#define TMR_STS_MASK 0x0001 -#define BM_STS_MASK 0x0010 -#define GBL_STS_MASK 0x0020 -#define PWRBTN_STS_MASK 0x0100 -#define SLPBTN_STS_MASK 0x0200 -#define RTC_STS_MASK 0x0400 -#define WAK_STS_MASK 0x8000 - -#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK \ - | PWRBTN_STS_MASK | SLPBTN_STS_MASK \ - | RTC_STS_MASK | WAK_STS_MASK) - -#define TMR_EN_MASK 0x0001 -#define GBL_EN_MASK 0x0020 -#define PWRBTN_EN_MASK 0x0100 -#define SLPBTN_EN_MASK 0x0200 -#define RTC_EN_MASK 0x0400 - -#define SCI_EN_MASK 0x0001 -#define BM_RLD_MASK 0x0002 -#define GBL_RLS_MASK 0x0004 -#define SLP_TYPE_X_MASK 0x1C00 -#define SLP_EN_MASK 0x2000 - -#define ARB_DIS_MASK 0x0001 -#define TMR_VAL_MASK 0xFFFFFFFF - -#define GPE0_STS_MASK -#define GPE0_EN_MASK - -#define GPE1_STS_MASK -#define GPE1_EN_MASK - - -#define ACPI_READ 1 -#define ACPI_WRITE 2 - - -/***************************************************************************** - * - * Resource descriptors - * - ****************************************************************************/ - - -/* Resource_type values */ - -#define RESOURCE_TYPE_MEMORY_RANGE 0 -#define RESOURCE_TYPE_IO_RANGE 1 -#define RESOURCE_TYPE_BUS_NUMBER_RANGE 2 - -/* Resource descriptor types and masks */ - -#define RESOURCE_DESC_TYPE_LARGE 0x80 -#define RESOURCE_DESC_TYPE_SMALL 0x00 - -#define RESOURCE_DESC_TYPE_MASK 0x80 -#define RESOURCE_DESC_SMALL_MASK 0x78 /* Only bits 6:3 contain the type */ - - -/* - * Small resource descriptor types - * Note: The 3 length bits (2:0) must be zero - */ -#define RESOURCE_DESC_IRQ_FORMAT 0x20 -#define RESOURCE_DESC_DMA_FORMAT 0x28 -#define RESOURCE_DESC_START_DEPENDENT 0x30 -#define RESOURCE_DESC_END_DEPENDENT 0x38 -#define RESOURCE_DESC_IO_PORT 0x40 -#define RESOURCE_DESC_FIXED_IO_PORT 0x48 -#define RESOURCE_DESC_SMALL_VENDOR 0x70 -#define RESOURCE_DESC_END_TAG 0x78 - -/* - * Large resource descriptor types - */ - -#define RESOURCE_DESC_MEMORY_24 0x81 -#define RESOURCE_DESC_GENERAL_REGISTER 0x82 -#define RESOURCE_DESC_LARGE_VENDOR 0x84 -#define RESOURCE_DESC_MEMORY_32 0x85 -#define RESOURCE_DESC_FIXED_MEMORY_32 0x86 -#define RESOURCE_DESC_DWORD_ADDRESS_SPACE 0x87 -#define RESOURCE_DESC_WORD_ADDRESS_SPACE 0x88 -#define RESOURCE_DESC_EXTENDED_XRUPT 0x89 -#define RESOURCE_DESC_QWORD_ADDRESS_SPACE 0x8A - - -/* String version of device HIDs and UIDs */ - -#define ACPI_DEVICE_ID_LENGTH 0x09 - -typedef struct -{ - char buffer[ACPI_DEVICE_ID_LENGTH]; - -} acpi_device_id; - - -/***************************************************************************** - * - * Miscellaneous - * - ****************************************************************************/ - -#define ASCII_ZERO 0x30 - -/***************************************************************************** - * - * Debugger - * - ****************************************************************************/ - -typedef struct dbmethodinfo -{ - acpi_handle thread_gate; - NATIVE_CHAR *name; - NATIVE_CHAR **args; - u32 flags; - u32 num_loops; - NATIVE_CHAR pathname[128]; - -} db_method_info; - - -/***************************************************************************** - * - * Debug - * - ****************************************************************************/ - -typedef struct -{ - u32 component_id; - NATIVE_CHAR *proc_name; - NATIVE_CHAR *module_name; - -} acpi_debug_print_info; - - -/* Entry for a memory allocation (debug only) */ - - -#define MEM_MALLOC 0 -#define MEM_CALLOC 1 -#define MAX_MODULE_NAME 16 - -#define ACPI_COMMON_DEBUG_MEM_HEADER \ - struct acpi_debug_mem_block *previous; \ - struct acpi_debug_mem_block *next; \ - u32 size; \ - u32 component; \ - u32 line; \ - NATIVE_CHAR module[MAX_MODULE_NAME]; \ - u8 alloc_type; - - -typedef struct -{ - ACPI_COMMON_DEBUG_MEM_HEADER - -} acpi_debug_mem_header; - -typedef struct acpi_debug_mem_block -{ - ACPI_COMMON_DEBUG_MEM_HEADER - u64 user_space; - -} acpi_debug_mem_block; - - -#define ACPI_MEM_LIST_GLOBAL 0 -#define ACPI_MEM_LIST_NSNODE 1 - -#define ACPI_MEM_LIST_FIRST_CACHE_LIST 2 -#define ACPI_MEM_LIST_STATE 2 -#define ACPI_MEM_LIST_PSNODE 3 -#define ACPI_MEM_LIST_PSNODE_EXT 4 -#define ACPI_MEM_LIST_OPERAND 5 -#define ACPI_MEM_LIST_WALK 6 -#define ACPI_MEM_LIST_MAX 6 -#define ACPI_NUM_MEM_LISTS 7 - - -typedef struct -{ - void *list_head; - u16 link_offset; - u16 max_cache_depth; - u16 cache_depth; - u16 object_size; - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - - /* Statistics for debug memory tracking only */ - - u32 total_allocated; - u32 total_freed; - u32 current_total_size; - u32 cache_requests; - u32 cache_hits; - char *list_name; -#endif - -} ACPI_MEMORY_LIST; - - -#endif /* __ACLOCAL_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acmacros.h linux-2.4.22/drivers/acpi/include/acmacros.h --- linux-2.4.21/drivers/acpi/include/acmacros.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acmacros.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,584 +0,0 @@ -/****************************************************************************** - * - * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 97 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACMACROS_H__ -#define __ACMACROS_H__ - - -/* - * Data manipulation macros - */ - -#ifndef LOWORD -#define LOWORD(l) ((u16)(NATIVE_UINT)(l)) -#endif - -#ifndef HIWORD -#define HIWORD(l) ((u16)((((NATIVE_UINT)(l)) >> 16) & 0xFFFF)) -#endif - -#ifndef LOBYTE -#define LOBYTE(l) ((u8)(u16)(l)) -#endif - -#ifndef HIBYTE -#define HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) -#endif - -#define BIT0(x) ((((x) & 0x01) > 0) ? 1 : 0) -#define BIT1(x) ((((x) & 0x02) > 0) ? 1 : 0) -#define BIT2(x) ((((x) & 0x04) > 0) ? 1 : 0) - -#define BIT3(x) ((((x) & 0x08) > 0) ? 1 : 0) -#define BIT4(x) ((((x) & 0x10) > 0) ? 1 : 0) -#define BIT5(x) ((((x) & 0x20) > 0) ? 1 : 0) -#define BIT6(x) ((((x) & 0x40) > 0) ? 1 : 0) -#define BIT7(x) ((((x) & 0x80) > 0) ? 1 : 0) - -#define LOW_BASE(w) ((u16) ((w) & 0x0000FFFF)) -#define MID_BASE(b) ((u8) (((b) & 0x00FF0000) >> 16)) -#define HI_BASE(b) ((u8) (((b) & 0xFF000000) >> 24)) -#define LOW_LIMIT(w) ((u16) ((w) & 0x0000FFFF)) -#define HI_LIMIT(b) ((u8) (((b) & 0x00FF0000) >> 16)) - - -#ifdef _IA16 -/* - * For 16-bit addresses, we have to assume that the upper 32 bits - * are zero. - */ -#ifndef LODWORD -#define LODWORD(l) (l) -#endif - -#ifndef HIDWORD -#define HIDWORD(l) (0) -#endif - -#define ACPI_GET_ADDRESS(a) ((a).lo) -#define ACPI_STORE_ADDRESS(a,b) {(a).hi=0;(a).lo=(b);} -#define ACPI_VALID_ADDRESS(a) ((a).hi | (a).lo) - -#else -#ifdef ACPI_NO_INTEGER64_SUPPORT -/* - * acpi_integer is 32-bits, no 64-bit support on this platform - */ -#ifndef LODWORD -#define LODWORD(l) ((u32)(l)) -#endif - -#ifndef HIDWORD -#define HIDWORD(l) (0) -#endif - -#define ACPI_GET_ADDRESS(a) (a) -#define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) -#define ACPI_VALID_ADDRESS(a) (a) - -#else - -/* - * Full 64-bit address/integer on both 32-bit and 64-bit platforms - */ -#ifndef LODWORD -#define LODWORD(l) ((u32)(u64)(l)) -#endif - -#ifndef HIDWORD -#define HIDWORD(l) ((u32)(((*(uint64_struct *)(&l))).hi)) -#endif - -#define ACPI_GET_ADDRESS(a) (a) -#define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) -#define ACPI_VALID_ADDRESS(a) (a) -#endif -#endif - - /* - * Extract a byte of data using a pointer. Any more than a byte and we - * get into potential aligment issues -- see the STORE macros below - */ -#define GET8(addr) (*(u8*)(addr)) - -/* Pointer arithmetic */ - - -#define POINTER_ADD(t,a,b) (t *) ((NATIVE_UINT)(a) + (NATIVE_UINT)(b)) -#define POINTER_DIFF(a,b) ((u32) ((NATIVE_UINT)(a) - (NATIVE_UINT)(b))) - -/* - * Macros for moving data around to/from buffers that are possibly unaligned. - * If the hardware supports the transfer of unaligned data, just do the store. - * Otherwise, we have to move one byte at a time. - */ - -#ifdef _HW_ALIGNMENT_SUPPORT - -/* The hardware supports unaligned transfers, just do the move */ - -#define MOVE_UNALIGNED16_TO_16(d,s) *(u16*)(d) = *(u16*)(s) -#define MOVE_UNALIGNED32_TO_32(d,s) *(u32*)(d) = *(u32*)(s) -#define MOVE_UNALIGNED16_TO_32(d,s) *(u32*)(d) = *(u16*)(s) -#define MOVE_UNALIGNED64_TO_64(d,s) *(u64*)(d) = *(u64*)(s) - -#else -/* - * The hardware does not support unaligned transfers. We must move the - * data one byte at a time. These macros work whether the source or - * the destination (or both) is/are unaligned. - */ - -#define MOVE_UNALIGNED16_TO_16(d,s) {((u8 *)(d))[0] = ((u8 *)(s))[0];\ - ((u8 *)(d))[1] = ((u8 *)(s))[1];} - -#define MOVE_UNALIGNED32_TO_32(d,s) {((u8 *)(d))[0] = ((u8 *)(s))[0];\ - ((u8 *)(d))[1] = ((u8 *)(s))[1];\ - ((u8 *)(d))[2] = ((u8 *)(s))[2];\ - ((u8 *)(d))[3] = ((u8 *)(s))[3];} - -#define MOVE_UNALIGNED16_TO_32(d,s) {(*(u32*)(d)) = 0; MOVE_UNALIGNED16_TO_16(d,s);} - -#define MOVE_UNALIGNED64_TO_64(d,s) {((u8 *)(d))[0] = ((u8 *)(s))[0];\ - ((u8 *)(d))[1] = ((u8 *)(s))[1];\ - ((u8 *)(d))[2] = ((u8 *)(s))[2];\ - ((u8 *)(d))[3] = ((u8 *)(s))[3];\ - ((u8 *)(d))[4] = ((u8 *)(s))[4];\ - ((u8 *)(d))[5] = ((u8 *)(s))[5];\ - ((u8 *)(d))[6] = ((u8 *)(s))[6];\ - ((u8 *)(d))[7] = ((u8 *)(s))[7];} - -#endif - - -/* - * Fast power-of-two math macros for non-optimized compilers - */ - -#define _DIV(value,power_of2) ((u32) ((value) >> (power_of2))) -#define _MUL(value,power_of2) ((u32) ((value) << (power_of2))) -#define _MOD(value,divisor) ((u32) ((value) & ((divisor) -1))) - -#define DIV_2(a) _DIV(a,1) -#define MUL_2(a) _MUL(a,1) -#define MOD_2(a) _MOD(a,2) - -#define DIV_4(a) _DIV(a,2) -#define MUL_4(a) _MUL(a,2) -#define MOD_4(a) _MOD(a,4) - -#define DIV_8(a) _DIV(a,3) -#define MUL_8(a) _MUL(a,3) -#define MOD_8(a) _MOD(a,8) - -#define DIV_16(a) _DIV(a,4) -#define MUL_16(a) _MUL(a,4) -#define MOD_16(a) _MOD(a,16) - - -/* - * Rounding macros (Power of two boundaries only) - */ -#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) -#define ROUND_UP(value,boundary) (((value) + ((boundary)-1)) & (~((boundary)-1))) - -#define ROUND_DOWN_TO_32_BITS(a) ROUND_DOWN(a,4) -#define ROUND_DOWN_TO_64_BITS(a) ROUND_DOWN(a,8) -#define ROUND_DOWN_TO_NATIVE_WORD(a) ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY) - -#define ROUND_UP_TO_32_bITS(a) ROUND_UP(a,4) -#define ROUND_UP_TO_64_bITS(a) ROUND_UP(a,8) -#define ROUND_UP_TO_NATIVE_WORD(a) ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY) - -#define ROUND_PTR_UP_TO_4(a,b) ((b *)(((NATIVE_UINT)(a) + 3) & ~3)) -#define ROUND_PTR_UP_TO_8(a,b) ((b *)(((NATIVE_UINT)(a) + 7) & ~7)) - -#define ROUND_BITS_UP_TO_BYTES(a) DIV_8((a) + 7) -#define ROUND_BITS_DOWN_TO_BYTES(a) DIV_8((a)) - -#define ROUND_UP_TO_1K(a) (((a) + 1023) >> 10) - -/* Generic (non-power-of-two) rounding */ - -#define ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary)) - -/* - * Bitmask creation - * Bit positions start at zero. - * MASK_BITS_ABOVE creates a mask starting AT the position and above - * MASK_BITS_BELOW creates a mask starting one bit BELOW the position - */ -#define MASK_BITS_ABOVE(position) (~(((u32)(-1)) << ((u32) (position)))) -#define MASK_BITS_BELOW(position) (((u32)(-1)) << ((u32) (position))) - - -/* Macros for GAS addressing */ - -#ifndef _IA16 - -#define ACPI_PCI_DEVICE_MASK (u64) 0x0000FFFF00000000 -#define ACPI_PCI_FUNCTION_MASK (u64) 0x00000000FFFF0000 -#define ACPI_PCI_REGISTER_MASK (u64) 0x000000000000FFFF - -#define ACPI_PCI_FUNCTION(a) (u16) ((((a) & ACPI_PCI_FUNCTION_MASK) >> 16)) -#define ACPI_PCI_DEVICE(a) (u16) ((((a) & ACPI_PCI_DEVICE_MASK) >> 32)) -#define ACPI_PCI_REGISTER(a) (u16) (((a) & ACPI_PCI_REGISTER_MASK)) - -#else - -/* No support for GAS and PCI IDs in 16-bit mode */ - -#define ACPI_PCI_FUNCTION(a) (u16) ((a) & 0xFFFF0000) -#define ACPI_PCI_DEVICE(a) (u16) ((a) & 0x0000FFFF) -#define ACPI_PCI_REGISTER(a) (u16) ((a) & 0x0000FFFF) - -#endif - -/* - * An acpi_handle (which is actually an acpi_namespace_node *) can appear in some contexts, - * such as on ap_obj_stack, where a pointer to an acpi_operand_object can also - * appear. This macro is used to distinguish them. - * - * The Data_type field is the first field in both structures. - */ -#define VALID_DESCRIPTOR_TYPE(d,t) (((acpi_namespace_node *)d)->data_type == t) - - -/* Macro to test the object type */ - -#define IS_THIS_OBJECT_TYPE(d,t) (((acpi_operand_object *)d)->common.type == (u8)t) - -/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */ - -#define IS_SINGLE_TABLE(x) (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0) - -/* - * Macro to check if a pointer is within an ACPI table. - * Parameter (a) is the pointer to check. Parameter (b) must be defined - * as a pointer to an acpi_table_header. (b+1) then points past the header, - * and ((u8 *)b+b->Length) points one byte past the end of the table. - */ -#ifndef _IA16 -#define IS_IN_ACPI_TABLE(a,b) (((u8 *)(a) >= (u8 *)(b + 1)) &&\ - ((u8 *)(a) < ((u8 *)b + b->length))) - -#else -#define IS_IN_ACPI_TABLE(a,b) (_segment)(a) == (_segment)(b) &&\ - (((u8 *)(a) >= (u8 *)(b + 1)) &&\ - ((u8 *)(a) < ((u8 *)b + b->length))) -#endif - -/* - * Macros for the master AML opcode table - */ -#ifdef ACPI_DEBUG -#define ACPI_OP(name,Pargs,Iargs,class,type,flags) {Pargs,Iargs,flags,class,type,name} -#else -#define ACPI_OP(name,Pargs,Iargs,class,type,flags) {Pargs,Iargs,flags,class,type} -#endif - -#define ARG_TYPE_WIDTH 5 -#define ARG_1(x) ((u32)(x)) -#define ARG_2(x) ((u32)(x) << (1 * ARG_TYPE_WIDTH)) -#define ARG_3(x) ((u32)(x) << (2 * ARG_TYPE_WIDTH)) -#define ARG_4(x) ((u32)(x) << (3 * ARG_TYPE_WIDTH)) -#define ARG_5(x) ((u32)(x) << (4 * ARG_TYPE_WIDTH)) -#define ARG_6(x) ((u32)(x) << (5 * ARG_TYPE_WIDTH)) - -#define ARGI_LIST1(a) (ARG_1(a)) -#define ARGI_LIST2(a,b) (ARG_1(b)|ARG_2(a)) -#define ARGI_LIST3(a,b,c) (ARG_1(c)|ARG_2(b)|ARG_3(a)) -#define ARGI_LIST4(a,b,c,d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a)) -#define ARGI_LIST5(a,b,c,d,e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a)) -#define ARGI_LIST6(a,b,c,d,e,f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a)) - -#define ARGP_LIST1(a) (ARG_1(a)) -#define ARGP_LIST2(a,b) (ARG_1(a)|ARG_2(b)) -#define ARGP_LIST3(a,b,c) (ARG_1(a)|ARG_2(b)|ARG_3(c)) -#define ARGP_LIST4(a,b,c,d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)) -#define ARGP_LIST5(a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)) -#define ARGP_LIST6(a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f)) - -#define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F)) -#define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) - - -/* - * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions) - * - * 1) Address space - * 2) Length in bytes -- convert to length in bits - * 3) Bit offset is zero - * 4) Reserved field is zero - * 5) Expand address to 64 bits - */ -#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d) {a.address_space_id = (u8) d;\ - a.register_bit_width = (u8) MUL_8 (b);\ - a.register_bit_offset = 0;\ - a.reserved = 0;\ - ACPI_STORE_ADDRESS (a.address,c);} - -/* ACPI V1.0 entries -- address space is always I/O */ - -#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c) ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO) - - -/* - * Reporting macros that are never compiled out - */ - -#define PARAM_LIST(pl) pl - -/* - * Error reporting. These versions add callers module and line#. Since - * _THIS_MODULE gets compiled out when ACPI_DEBUG isn't defined, only - * use it in debug mode. - */ - -#ifdef ACPI_DEBUG - -#define REPORT_INFO(fp) {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \ - acpi_os_printf PARAM_LIST(fp);} -#define REPORT_ERROR(fp) {acpi_ut_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \ - acpi_os_printf PARAM_LIST(fp);} -#define REPORT_WARNING(fp) {acpi_ut_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \ - acpi_os_printf PARAM_LIST(fp);} - -#else - -#define REPORT_INFO(fp) {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf PARAM_LIST(fp);} -#define REPORT_ERROR(fp) {acpi_ut_report_error("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf PARAM_LIST(fp);} -#define REPORT_WARNING(fp) {acpi_ut_report_warning("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf PARAM_LIST(fp);} - -#endif - -/* Error reporting. These versions pass thru the module and line# */ - -#define _REPORT_INFO(a,b,c,fp) {acpi_ut_report_info(a,b,c); \ - acpi_os_printf PARAM_LIST(fp);} -#define _REPORT_ERROR(a,b,c,fp) {acpi_ut_report_error(a,b,c); \ - acpi_os_printf PARAM_LIST(fp);} -#define _REPORT_WARNING(a,b,c,fp) {acpi_ut_report_warning(a,b,c); \ - acpi_os_printf PARAM_LIST(fp);} - -/* - * Debug macros that are conditionally compiled - */ - -#ifdef ACPI_DEBUG - -#define MODULE_NAME(name) static char *_THIS_MODULE = name; - -/* - * Function entry tracing. - * The first parameter should be the procedure name as a quoted string. This is declared - * as a local string ("_Proc_name) so that it can be also used by the function exit macros below. - */ - -#define PROC_NAME(a) acpi_debug_print_info _dbg; \ - _dbg.component_id = _COMPONENT; \ - _dbg.proc_name = a; \ - _dbg.module_name = _THIS_MODULE; - -#define FUNCTION_TRACE(a) PROC_NAME(a)\ - acpi_ut_trace(__LINE__,&_dbg) -#define FUNCTION_TRACE_PTR(a,b) PROC_NAME(a)\ - acpi_ut_trace_ptr(__LINE__,&_dbg,(void *)b) -#define FUNCTION_TRACE_U32(a,b) PROC_NAME(a)\ - acpi_ut_trace_u32(__LINE__,&_dbg,(u32)b) -#define FUNCTION_TRACE_STR(a,b) PROC_NAME(a)\ - acpi_ut_trace_str(__LINE__,&_dbg,(NATIVE_CHAR *)b) - -#define FUNCTION_ENTRY() acpi_ut_track_stack_ptr() - -/* - * Function exit tracing. - * WARNING: These macros include a return statement. This is usually considered - * bad form, but having a separate exit macro is very ugly and difficult to maintain. - * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros - * so that "_Proc_name" is defined. - */ -#define return_VOID {acpi_ut_exit(__LINE__,&_dbg);return;} -#define return_ACPI_STATUS(s) {acpi_ut_status_exit(__LINE__,&_dbg,s);return(s);} -#define return_VALUE(s) {acpi_ut_value_exit(__LINE__,&_dbg,s);return(s);} -#define return_PTR(s) {acpi_ut_ptr_exit(__LINE__,&_dbg,(u8 *)s);return(s);} - - -/* Conditional execution */ - -#define DEBUG_EXEC(a) a -#define NORMAL_EXEC(a) - -#define DEBUG_DEFINE(a) a; -#define DEBUG_ONLY_MEMBERS(a) a; -#define _OPCODE_NAMES -#define _VERBOSE_STRUCTURES - - -/* Stack and buffer dumping */ - -#define DUMP_STACK_ENTRY(a) acpi_ex_dump_operand(a) -#define DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__) - - -#define DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b) -#define DUMP_TABLES(a,b) acpi_ns_dump_tables(a,b) -#define DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d) -#define DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a) -#define DUMP_BUFFER(a,b) acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT) -#define BREAK_MSG(a) acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a)) - - -/* - * Generate INT3 on ACPI_ERROR (Debug only!) - */ - -#define ERROR_BREAK -#ifdef ERROR_BREAK -#define BREAK_ON_ERROR(lvl) if ((lvl)&ACPI_ERROR) acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,"Fatal error encountered\n") -#else -#define BREAK_ON_ERROR(lvl) -#endif - -/* - * Master debug print macros - * Print iff: - * 1) Debug print for the current component is enabled - * 2) Debug error level or trace level for the print statement is enabled - */ - -#define ACPI_DEBUG_PRINT(pl) acpi_ut_debug_print PARAM_LIST(pl) -#define ACPI_DEBUG_PRINT_RAW(pl) acpi_ut_debug_print_raw PARAM_LIST(pl) - - -#else -/* - * This is the non-debug case -- make everything go away, - * leaving no executable debug code! - */ - -#define MODULE_NAME(name) -#define _THIS_MODULE "" - -#define DEBUG_EXEC(a) -#define NORMAL_EXEC(a) a; - -#define DEBUG_DEFINE(a) -#define DEBUG_ONLY_MEMBERS(a) -#define PROC_NAME(a) -#define FUNCTION_TRACE(a) -#define FUNCTION_TRACE_PTR(a,b) -#define FUNCTION_TRACE_U32(a,b) -#define FUNCTION_TRACE_STR(a,b) -#define FUNCTION_EXIT -#define FUNCTION_STATUS_EXIT(s) -#define FUNCTION_VALUE_EXIT(s) -#define FUNCTION_ENTRY() -#define DUMP_STACK_ENTRY(a) -#define DUMP_OPERANDS(a,b,c,d,e) -#define DUMP_ENTRY(a,b) -#define DUMP_TABLES(a,b) -#define DUMP_PATHNAME(a,b,c,d) -#define DUMP_RESOURCE_LIST(a) -#define DUMP_BUFFER(a,b) -#define ACPI_DEBUG_PRINT(pl) -#define ACPI_DEBUG_PRINT_RAW(pl) -#define BREAK_MSG(a) - -#define return_VOID return -#define return_ACPI_STATUS(s) return(s) -#define return_VALUE(s) return(s) -#define return_PTR(s) return(s) - -#endif - -/* - * Some code only gets executed when the debugger is built in. - * Note that this is entirely independent of whether the - * DEBUG_PRINT stuff (set by ACPI_DEBUG) is on, or not. - */ -#ifdef ENABLE_DEBUGGER -#define DEBUGGER_EXEC(a) a -#else -#define DEBUGGER_EXEC(a) -#endif - - -/* - * For 16-bit code, we want to shrink some things even though - * we are using ACPI_DEBUG to get the debug output - */ -#ifdef _IA16 -#undef DEBUG_ONLY_MEMBERS -#undef _VERBOSE_STRUCTURES -#define DEBUG_ONLY_MEMBERS(a) -#endif - - -#ifdef ACPI_DEBUG -/* - * 1) Set name to blanks - * 2) Copy the object name - */ -#define ADD_OBJECT_NAME(a,b) MEMSET (a->common.name, ' ', sizeof (a->common.name));\ - STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name)) -#else - -#define ADD_OBJECT_NAME(a,b) -#endif - - -/* - * Memory allocation tracking (DEBUG ONLY) - */ - -#ifndef ACPI_DBG_TRACK_ALLOCATIONS - -/* Memory allocation */ - -#define ACPI_MEM_ALLOCATE(a) acpi_os_allocate(a) -#define ACPI_MEM_CALLOCATE(a) acpi_os_callocate(a) -#define ACPI_MEM_FREE(a) acpi_os_free(a) -#define ACPI_MEM_TRACKING(a) - - -#else - -/* Memory allocation */ - -#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate(a,_COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate(a, _COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_FREE(a) acpi_ut_free(a,_COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_TRACKING(a) a - -#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ - - -#define ACPI_GET_STACK_POINTER _asm {mov eax, ebx} - -#endif /* ACMACROS_H */ diff -urN linux-2.4.21/drivers/acpi/include/acnamesp.h linux-2.4.22/drivers/acpi/include/acnamesp.h --- linux-2.4.21/drivers/acpi/include/acnamesp.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acnamesp.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,423 +0,0 @@ -/****************************************************************************** - * - * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * $Revision: 110 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACNAMESP_H__ -#define __ACNAMESP_H__ - - -/* To search the entire name space, pass this as Search_base */ - -#define NS_ALL ((acpi_handle)0) - -/* - * Elements of Acpi_ns_properties are bit significant - * and should be one-to-one with values of acpi_object_type - */ -#define NSP_NORMAL 0 -#define NSP_NEWSCOPE 1 /* a definition of this type opens a name scope */ -#define NSP_LOCAL 2 /* suppress search of enclosing scopes */ - - -/* Definitions of the predefined namespace names */ - -#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ -#define ACPI_ROOT_NAME (u32) 0x2F202020 /* Root name is "/ " */ -#define ACPI_SYS_BUS_NAME (u32) 0x5F53425F /* Sys bus name is "_SB_" */ - -#define NS_ROOT_PATH "/" -#define NS_SYSTEM_BUS "_SB_" - - -/* Flags for Acpi_ns_lookup, Acpi_ns_search_and_enter */ - -#define NS_NO_UPSEARCH 0 -#define NS_SEARCH_PARENT 0x01 -#define NS_DONT_OPEN_SCOPE 0x02 -#define NS_NO_PEER_SEARCH 0x04 -#define NS_ERROR_IF_FOUND 0x08 - -#define NS_WALK_UNLOCK TRUE -#define NS_WALK_NO_UNLOCK FALSE - - -acpi_status -acpi_ns_load_namespace ( - void); - -acpi_status -acpi_ns_initialize_objects ( - void); - -acpi_status -acpi_ns_initialize_devices ( - void); - - -/* Namespace init - nsxfinit */ - -acpi_status -acpi_ns_init_one_device ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - -acpi_status -acpi_ns_init_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - - -acpi_status -acpi_ns_walk_namespace ( - acpi_object_type8 type, - acpi_handle start_object, - u32 max_depth, - u8 unlock_before_callback, - acpi_walk_callback user_function, - void *context, - void **return_value); - -acpi_namespace_node * -acpi_ns_get_next_node ( - acpi_object_type8 type, - acpi_namespace_node *parent, - acpi_namespace_node *child); - -acpi_status -acpi_ns_delete_namespace_by_owner ( - u16 table_id); - - -/* Namespace loading - nsload */ - -acpi_status -acpi_ns_one_complete_parse ( - u32 pass_number, - acpi_table_desc *table_desc); - -acpi_status -acpi_ns_parse_table ( - acpi_table_desc *table_desc, - acpi_namespace_node *scope); - -acpi_status -acpi_ns_load_table ( - acpi_table_desc *table_desc, - acpi_namespace_node *node); - -acpi_status -acpi_ns_load_table_by_type ( - acpi_table_type table_type); - - -/* - * Top-level namespace access - nsaccess - */ - - -acpi_status -acpi_ns_root_initialize ( - void); - -acpi_status -acpi_ns_lookup ( - acpi_generic_state *scope_info, - NATIVE_CHAR *name, - acpi_object_type8 type, - operating_mode interpreter_mode, - u32 flags, - acpi_walk_state *walk_state, - acpi_namespace_node **ret_node); - - -/* - * Named object allocation/deallocation - nsalloc - */ - - -acpi_namespace_node * -acpi_ns_create_node ( - u32 name); - -void -acpi_ns_delete_node ( - acpi_namespace_node *node); - -acpi_status -acpi_ns_delete_namespace_subtree ( - acpi_namespace_node *parent_handle); - -void -acpi_ns_detach_object ( - acpi_namespace_node *node); - -void -acpi_ns_delete_children ( - acpi_namespace_node *parent); - - -/* - * Namespace modification - nsmodify - */ - -acpi_status -acpi_ns_unload_namespace ( - acpi_handle handle); - -acpi_status -acpi_ns_delete_subtree ( - acpi_handle start_handle); - - -/* - * Namespace dump/print utilities - nsdump - */ - -void -acpi_ns_dump_tables ( - acpi_handle search_base, - u32 max_depth); - -void -acpi_ns_dump_entry ( - acpi_handle handle, - u32 debug_level); - -acpi_status -acpi_ns_dump_pathname ( - acpi_handle handle, - NATIVE_CHAR *msg, - u32 level, - u32 component); - -void -acpi_ns_dump_root_devices ( - void); - -void -acpi_ns_dump_objects ( - acpi_object_type8 type, - u8 display_type, - u32 max_depth, - u32 ownder_id, - acpi_handle start_handle); - - -/* - * Namespace evaluation functions - nseval - */ - -acpi_status -acpi_ns_evaluate_by_handle ( - acpi_namespace_node *prefix_node, - acpi_operand_object **params, - acpi_operand_object **return_object); - -acpi_status -acpi_ns_evaluate_by_name ( - NATIVE_CHAR *pathname, - acpi_operand_object **params, - acpi_operand_object **return_object); - -acpi_status -acpi_ns_evaluate_relative ( - acpi_namespace_node *prefix_node, - NATIVE_CHAR *pathname, - acpi_operand_object **params, - acpi_operand_object **return_object); - -acpi_status -acpi_ns_execute_control_method ( - acpi_namespace_node *method_node, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc); - -acpi_status -acpi_ns_get_object_value ( - acpi_namespace_node *object_node, - acpi_operand_object **return_obj_desc); - - -/* - * Parent/Child/Peer utility functions - nsfamily - */ - -acpi_name -acpi_ns_find_parent_name ( - acpi_namespace_node *node_to_search); - -u8 -acpi_ns_exist_downstream_sibling ( - acpi_namespace_node *this_node); - - -/* - * Scope manipulation - nsscope - */ - -u32 -acpi_ns_opens_scope ( - acpi_object_type8 type); - -NATIVE_CHAR * -acpi_ns_get_table_pathname ( - acpi_namespace_node *node); - -NATIVE_CHAR * -acpi_ns_name_of_current_scope ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ns_handle_to_pathname ( - acpi_handle obj_handle, - u32 *buf_size, - NATIVE_CHAR *user_buffer); - -u8 -acpi_ns_pattern_match ( - acpi_namespace_node *obj_node, - NATIVE_CHAR *search_for); - -acpi_status -acpi_ns_get_node ( - NATIVE_CHAR *pathname, - acpi_namespace_node *in_prefix_node, - acpi_namespace_node **out_node); - -u32 -acpi_ns_get_pathname_length ( - acpi_namespace_node *node); - - -/* - * Object management for NTEs - nsobject - */ - -acpi_status -acpi_ns_attach_object ( - acpi_namespace_node *node, - acpi_operand_object *object, - acpi_object_type8 type); - - -/* - * Namespace searching and entry - nssearch - */ - -acpi_status -acpi_ns_search_and_enter ( - u32 entry_name, - acpi_walk_state *walk_state, - acpi_namespace_node *node, - operating_mode interpreter_mode, - acpi_object_type8 type, - u32 flags, - acpi_namespace_node **ret_node); - -acpi_status -acpi_ns_search_node ( - u32 entry_name, - acpi_namespace_node *node, - acpi_object_type8 type, - acpi_namespace_node **ret_node); - -void -acpi_ns_install_node ( - acpi_walk_state *walk_state, - acpi_namespace_node *parent_node, /* Parent */ - acpi_namespace_node *node, /* New Child*/ - acpi_object_type8 type); - - -/* - * Utility functions - nsutils - */ - -u8 -acpi_ns_valid_root_prefix ( - NATIVE_CHAR prefix); - -u8 -acpi_ns_valid_path_separator ( - NATIVE_CHAR sep); - -acpi_object_type8 -acpi_ns_get_type ( - acpi_namespace_node *node); - -void * -acpi_ns_get_attached_object ( - acpi_namespace_node *node); - -u32 -acpi_ns_local ( - acpi_object_type8 type); - -acpi_status -acpi_ns_build_internal_name ( - acpi_namestring_info *info); - -acpi_status -acpi_ns_get_internal_name_length ( - acpi_namestring_info *info); - -acpi_status -acpi_ns_internalize_name ( - NATIVE_CHAR *dotted_name, - NATIVE_CHAR **converted_name); - -acpi_status -acpi_ns_externalize_name ( - u32 internal_name_length, - NATIVE_CHAR *internal_name, - u32 *converted_name_length, - NATIVE_CHAR **converted_name); - -acpi_namespace_node * -acpi_ns_map_handle_to_node ( - acpi_handle handle); - -acpi_handle -acpi_ns_convert_entry_to_handle( - acpi_namespace_node *node); - -void -acpi_ns_terminate ( - void); - -acpi_namespace_node * -acpi_ns_get_parent_object ( - acpi_namespace_node *node); - - -acpi_namespace_node * -acpi_ns_get_next_valid_node ( - acpi_namespace_node *node); - - -#endif /* __ACNAMESP_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acobject.h linux-2.4.22/drivers/acpi/include/acobject.h --- linux-2.4.21/drivers/acpi/include/acobject.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acobject.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,451 +0,0 @@ - -/****************************************************************************** - * - * Name: acobject.h - Definition of acpi_operand_object (Internal object only) - * $Revision: 93 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 _ACOBJECT_H -#define _ACOBJECT_H - - -/* - * The acpi_operand_object is used to pass AML operands from the dispatcher - * to the interpreter, and to keep track of the various handlers such as - * address space handlers and notify handlers. The object is a constant - * size in order to allow them to be cached and reused. - * - * All variants of the acpi_operand_object are defined with the same - * sequence of field types, with fields that are not used in a particular - * variant being named "Reserved". This is not strictly necessary, but - * may in some circumstances simplify understanding if these structures - * need to be displayed in a debugger having limited (or no) support for - * union types. It also simplifies some debug code in Dump_table() which - * dumps multi-level values: fetching Buffer.Pointer suffices to pick up - * the value or next level for any of several types. - */ - -/****************************************************************************** - * - * Common Descriptors - * - *****************************************************************************/ - -/* - * Common area for all objects. - * - * Data_type is used to differentiate between internal descriptors, and MUST - * be the first byte in this structure. - */ - - -#define ACPI_OBJECT_COMMON_HEADER /* SIZE/ALIGNMENT: 32-bits plus trailing 8-bit flag */\ - u8 data_type; /* To differentiate various internal objs */\ - u8 type; /* acpi_object_type */\ - u16 reference_count; /* For object deletion management */\ - u8 flags; \ - -/* Defines for flag byte above */ - -#define AOPOBJ_STATIC_ALLOCATION 0x1 -#define AOPOBJ_STATIC_POINTER 0x2 -#define AOPOBJ_DATA_VALID 0x4 -#define AOPOBJ_ZERO_CONST 0x4 -#define AOPOBJ_INITIALIZED 0x8 - - -/* - * Common bitfield for the field objects - * "Field Datum" -- a datum from the actual field object - * "Buffer Datum" -- a datum from a user buffer, read from or to be written to the field - */ -#define ACPI_COMMON_FIELD_INFO /* SIZE/ALIGNMENT: 24 bits + three 32-bit values */\ - u8 access_flags;\ - u16 bit_length; /* Length of field in bits */\ - u32 base_byte_offset; /* Byte offset within containing object */\ - u8 access_bit_width; /* Read/Write size in bits (from ASL Access_type)*/\ - u8 access_byte_width; /* Read/Write size in bytes */\ - u8 update_rule; /* How neighboring field bits are handled */\ - u8 lock_rule; /* Global Lock: 1 = "Must Lock" */\ - u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ - u8 datum_valid_bits; /* Valid bit in first "Field datum" */\ - u8 end_field_valid_bits; /* Valid bits in the last "field datum" */\ - u8 end_buffer_valid_bits; /* Valid bits in the last "buffer datum" */\ - u32 value; /* Value to store into the Bank or Index register */ - - -/* Access flag bits */ - -#define AFIELD_SINGLE_DATUM 0x1 - - -/* - * Fields common to both Strings and Buffers - */ -#define ACPI_COMMON_BUFFER_INFO \ - u32 length; - - -/****************************************************************************** - * - * Individual Object Descriptors - * - *****************************************************************************/ - - -typedef struct /* COMMON */ -{ - ACPI_OBJECT_COMMON_HEADER - -} ACPI_OBJECT_COMMON; - - -typedef struct /* CACHE_LIST */ -{ - ACPI_OBJECT_COMMON_HEADER - union acpi_operand_obj *next; /* Link for object cache and internal lists*/ - -} ACPI_OBJECT_CACHE_LIST; - - -typedef struct /* NUMBER - has value */ -{ - ACPI_OBJECT_COMMON_HEADER - - acpi_integer value; - -} ACPI_OBJECT_INTEGER; - - -typedef struct /* STRING - has length and pointer - Null terminated, ASCII characters only */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_BUFFER_INFO - NATIVE_CHAR *pointer; /* String value in AML stream or in allocated space */ - -} ACPI_OBJECT_STRING; - - -typedef struct /* BUFFER - has length and pointer - not null terminated */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_BUFFER_INFO - u8 *pointer; /* Buffer value in AML stream or in allocated space */ - -} ACPI_OBJECT_BUFFER; - - -typedef struct /* PACKAGE - has count, elements, next element */ -{ - ACPI_OBJECT_COMMON_HEADER - - u32 count; /* # of elements in package */ - union acpi_operand_obj **elements; /* Array of pointers to Acpi_objects */ - union acpi_operand_obj **next_element; /* used only while initializing */ - -} ACPI_OBJECT_PACKAGE; - - -typedef struct /* DEVICE - has handle and notification handler/context */ -{ - ACPI_OBJECT_COMMON_HEADER - - union acpi_operand_obj *sys_handler; /* Handler for system notifies */ - union acpi_operand_obj *drv_handler; /* Handler for driver notifies */ - union acpi_operand_obj *addr_handler; /* Handler for Address space */ - -} ACPI_OBJECT_DEVICE; - - -typedef struct /* EVENT */ -{ - ACPI_OBJECT_COMMON_HEADER - void *semaphore; - -} ACPI_OBJECT_EVENT; - - -#define INFINITE_CONCURRENCY 0xFF - -typedef struct /* METHOD */ -{ - ACPI_OBJECT_COMMON_HEADER - u8 method_flags; - u8 param_count; - - u32 aml_length; - - void *semaphore; - u8 *aml_start; - - u8 concurrency; - u8 thread_count; - acpi_owner_id owning_id; - -} ACPI_OBJECT_METHOD; - - -typedef struct acpi_obj_mutex /* MUTEX */ -{ - ACPI_OBJECT_COMMON_HEADER - u16 sync_level; - u16 acquisition_depth; - - void *semaphore; - void *owner; - union acpi_operand_obj *prev; /* Link for list of acquired mutexes */ - union acpi_operand_obj *next; /* Link for list of acquired mutexes */ - -} ACPI_OBJECT_MUTEX; - - -typedef struct /* REGION */ -{ - ACPI_OBJECT_COMMON_HEADER - - u8 space_id; - u32 length; - ACPI_PHYSICAL_ADDRESS address; - union acpi_operand_obj *extra; /* Pointer to executable AML (in region definition) */ - - union acpi_operand_obj *addr_handler; /* Handler for system notifies */ - acpi_namespace_node *node; /* containing object */ - union acpi_operand_obj *next; - -} ACPI_OBJECT_REGION; - - -typedef struct /* POWER RESOURCE - has Handle and notification handler/context*/ -{ - ACPI_OBJECT_COMMON_HEADER - - u32 system_level; - u32 resource_order; - - union acpi_operand_obj *sys_handler; /* Handler for system notifies */ - union acpi_operand_obj *drv_handler; /* Handler for driver notifies */ - -} ACPI_OBJECT_POWER_RESOURCE; - - -typedef struct /* PROCESSOR - has Handle and notification handler/context*/ -{ - ACPI_OBJECT_COMMON_HEADER - - u32 proc_id; - u32 length; - ACPI_IO_ADDRESS address; - - union acpi_operand_obj *sys_handler; /* Handler for system notifies */ - union acpi_operand_obj *drv_handler; /* Handler for driver notifies */ - union acpi_operand_obj *addr_handler; /* Handler for Address space */ - -} ACPI_OBJECT_PROCESSOR; - - -typedef struct /* THERMAL ZONE - has Handle and Handler/Context */ -{ - ACPI_OBJECT_COMMON_HEADER - - union acpi_operand_obj *sys_handler; /* Handler for system notifies */ - union acpi_operand_obj *drv_handler; /* Handler for driver notifies */ - union acpi_operand_obj *addr_handler; /* Handler for Address space */ - -} ACPI_OBJECT_THERMAL_ZONE; - - -/* - * Fields. All share a common header/info field. - */ - -typedef struct /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - union acpi_operand_obj *region_obj; /* Containing Operation Region object */ - /* (REGION/BANK fields only) */ -} ACPI_OBJECT_FIELD_COMMON; - - -typedef struct /* REGION FIELD */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - union acpi_operand_obj *region_obj; /* Containing Op_region object */ - -} ACPI_OBJECT_REGION_FIELD; - - -typedef struct /* BANK FIELD */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - - union acpi_operand_obj *region_obj; /* Containing Op_region object */ - union acpi_operand_obj *bank_register_obj; /* Bank_select Register object */ - -} ACPI_OBJECT_BANK_FIELD; - - -typedef struct /* INDEX FIELD */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - - /* - * No "Region_obj" pointer needed since the Index and Data registers - * are each field definitions unto themselves. - */ - union acpi_operand_obj *index_obj; /* Index register */ - union acpi_operand_obj *data_obj; /* Data register */ - - -} ACPI_OBJECT_INDEX_FIELD; - - -/* The Buffer_field is different in that it is part of a Buffer, not an Op_region */ - -typedef struct /* BUFFER FIELD */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - - union acpi_operand_obj *extra; /* Pointer to executable AML (in field definition) */ - acpi_namespace_node *node; /* Parent (containing) object node */ - union acpi_operand_obj *buffer_obj; /* Containing Buffer object */ - -} ACPI_OBJECT_BUFFER_FIELD; - - -/* - * Handlers - */ - -typedef struct /* NOTIFY HANDLER */ -{ - ACPI_OBJECT_COMMON_HEADER - - acpi_namespace_node *node; /* Parent device */ - acpi_notify_handler handler; - void *context; - -} ACPI_OBJECT_NOTIFY_HANDLER; - - -/* Flags for address handler */ - -#define ADDR_HANDLER_DEFAULT_INSTALLED 0x1 - - -typedef struct /* ADDRESS HANDLER */ -{ - ACPI_OBJECT_COMMON_HEADER - - u8 space_id; - u16 hflags; - acpi_adr_space_handler handler; - - acpi_namespace_node *node; /* Parent device */ - void *context; - acpi_adr_space_setup setup; - union acpi_operand_obj *region_list; /* regions using this handler */ - union acpi_operand_obj *next; - -} ACPI_OBJECT_ADDR_HANDLER; - - -/* - * The Reference object type is used for these opcodes: - * Arg[0-6], Local[0-7], Index_op, Name_op, Zero_op, One_op, Ones_op, Debug_op - */ - -typedef struct /* Reference - Local object type */ -{ - ACPI_OBJECT_COMMON_HEADER - - u8 target_type; /* Used for Index_op */ - u16 opcode; - u32 offset; /* Used for Arg_op, Local_op, and Index_op */ - - void *object; /* Name_op=>HANDLE to obj, Index_op=>acpi_operand_object */ - acpi_namespace_node *node; - union acpi_operand_obj **where; - -} ACPI_OBJECT_REFERENCE; - - -/* - * Extra object is used as additional storage for types that - * have AML code in their declarations (Term_args) that must be - * evaluated at run time. - * - * Currently: Region and Field_unit types - */ - -typedef struct /* EXTRA */ -{ - ACPI_OBJECT_COMMON_HEADER - u8 byte_fill1; - u16 word_fill1; - u32 aml_length; - u8 *aml_start; - acpi_namespace_node *method_REG; /* _REG method for this region (if any) */ - void *region_context; /* Region-specific data */ - -} ACPI_OBJECT_EXTRA; - - -/****************************************************************************** - * - * acpi_operand_object Descriptor - a giant union of all of the above - * - *****************************************************************************/ - -typedef union acpi_operand_obj -{ - ACPI_OBJECT_COMMON common; - ACPI_OBJECT_CACHE_LIST cache; - ACPI_OBJECT_INTEGER integer; - ACPI_OBJECT_STRING string; - ACPI_OBJECT_BUFFER buffer; - ACPI_OBJECT_PACKAGE package; - ACPI_OBJECT_BUFFER_FIELD buffer_field; - ACPI_OBJECT_DEVICE device; - ACPI_OBJECT_EVENT event; - ACPI_OBJECT_METHOD method; - ACPI_OBJECT_MUTEX mutex; - ACPI_OBJECT_REGION region; - ACPI_OBJECT_POWER_RESOURCE power_resource; - ACPI_OBJECT_PROCESSOR processor; - ACPI_OBJECT_THERMAL_ZONE thermal_zone; - ACPI_OBJECT_FIELD_COMMON common_field; - ACPI_OBJECT_REGION_FIELD field; - ACPI_OBJECT_BANK_FIELD bank_field; - ACPI_OBJECT_INDEX_FIELD index_field; - ACPI_OBJECT_REFERENCE reference; - ACPI_OBJECT_NOTIFY_HANDLER notify_handler; - ACPI_OBJECT_ADDR_HANDLER addr_handler; - ACPI_OBJECT_EXTRA extra; - -} acpi_operand_object; - -#endif /* _ACOBJECT_H */ diff -urN linux-2.4.21/drivers/acpi/include/acoutput.h linux-2.4.22/drivers/acpi/include/acoutput.h --- linux-2.4.21/drivers/acpi/include/acoutput.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acoutput.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,182 +0,0 @@ -/****************************************************************************** - * - * Name: acoutput.h -- debug output - * $Revision: 84 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACOUTPUT_H__ -#define __ACOUTPUT_H__ - -/* - * Debug levels and component IDs. These are used to control the - * granularity of the output of the DEBUG_PRINT macro -- on a per- - * component basis and a per-exception-type basis. - */ - -/* Component IDs are used in the global "Debug_layer" */ - -#define ACPI_UTILITIES 0x00000001 -#define ACPI_HARDWARE 0x00000002 -#define ACPI_EVENTS 0x00000004 -#define ACPI_TABLES 0x00000008 -#define ACPI_NAMESPACE 0x00000010 -#define ACPI_PARSER 0x00000020 -#define ACPI_DISPATCHER 0x00000040 -#define ACPI_EXECUTER 0x00000080 -#define ACPI_RESOURCES 0x00000100 -#define ACPI_DEBUGGER 0x00000200 -#define ACPI_OS_SERVICES 0x00000400 - -#define ACPI_BUS 0x00010000 -#define ACPI_SYSTEM 0x00020000 -#define ACPI_POWER 0x00040000 -#define ACPI_EC 0x00080000 -#define ACPI_AC_ADAPTER 0x00100000 -#define ACPI_BATTERY 0x00200000 -#define ACPI_BUTTON 0x00400000 -#define ACPI_PROCESSOR 0x00800000 -#define ACPI_THERMAL 0x01000000 -#define ACPI_FAN 0x02000000 - -#define ACPI_ALL_COMPONENTS 0x0FFFFFFF - -#define ACPI_COMPONENT_DEFAULT (ACPI_ALL_COMPONENTS) - - -#define ACPI_COMPILER 0x10000000 -#define ACPI_TOOLS 0x20000000 - - -/* - * Raw debug output levels, do not use these in the DEBUG_PRINT macros - */ - -#define ACPI_LV_OK 0x00000001 -#define ACPI_LV_INFO 0x00000002 -#define ACPI_LV_WARN 0x00000004 -#define ACPI_LV_ERROR 0x00000008 -#define ACPI_LV_FATAL 0x00000010 -#define ACPI_LV_DEBUG_OBJECT 0x00000020 -#define ACPI_LV_ALL_EXCEPTIONS 0x0000003F - - -/* Trace verbosity level 1 [Standard Trace Level] */ - -#define ACPI_LV_PARSE 0x00000040 -#define ACPI_LV_LOAD 0x00000080 -#define ACPI_LV_DISPATCH 0x00000100 -#define ACPI_LV_EXEC 0x00000200 -#define ACPI_LV_NAMES 0x00000400 -#define ACPI_LV_OPREGION 0x00000800 -#define ACPI_LV_BFIELD 0x00001000 -#define ACPI_LV_TABLES 0x00002000 -#define ACPI_LV_VALUES 0x00004000 -#define ACPI_LV_OBJECTS 0x00008000 -#define ACPI_LV_RESOURCES 0x00010000 -#define ACPI_LV_USER_REQUESTS 0x00020000 -#define ACPI_LV_PACKAGE 0x00040000 -#define ACPI_LV_INIT 0x00080000 -#define ACPI_LV_VERBOSITY1 0x000FFF40 | ACPI_LV_ALL_EXCEPTIONS - -/* Trace verbosity level 2 [Function tracing and memory allocation] */ - -#define ACPI_LV_ALLOCATIONS 0x00100000 -#define ACPI_LV_FUNCTIONS 0x00200000 -#define ACPI_LV_VERBOSITY2 0x00300000 | ACPI_LV_VERBOSITY1 -#define ACPI_LV_ALL ACPI_LV_VERBOSITY2 - -/* Trace verbosity level 3 [Threading, I/O, and Interrupts] */ - -#define ACPI_LV_MUTEX 0x01000000 -#define ACPI_LV_THREADS 0x02000000 -#define ACPI_LV_IO 0x04000000 -#define ACPI_LV_INTERRUPTS 0x08000000 -#define ACPI_LV_VERBOSITY3 0x0F000000 | ACPI_LV_VERBOSITY2 - -/* - * Debug level macros that are used in the DEBUG_PRINT macros - */ - -#define ACPI_DEBUG_LEVEL(dl) dl,__LINE__,&_dbg - -/* Exception level -- used in the global "Debug_level" */ - -#define ACPI_DB_OK ACPI_DEBUG_LEVEL (ACPI_LV_OK) -#define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO) -#define ACPI_DB_WARN ACPI_DEBUG_LEVEL (ACPI_LV_WARN) -#define ACPI_DB_ERROR ACPI_DEBUG_LEVEL (ACPI_LV_ERROR) -#define ACPI_DB_FATAL ACPI_DEBUG_LEVEL (ACPI_LV_FATAL) -#define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT) -#define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS) - - -/* Trace level -- also used in the global "Debug_level" */ - -#define ACPI_DB_THREADS ACPI_DEBUG_LEVEL (ACPI_LV_THREADS) -#define ACPI_DB_PARSE ACPI_DEBUG_LEVEL (ACPI_LV_PARSE) -#define ACPI_DB_DISPATCH ACPI_DEBUG_LEVEL (ACPI_LV_DISPATCH) -#define ACPI_DB_LOAD ACPI_DEBUG_LEVEL (ACPI_LV_LOAD) -#define ACPI_DB_EXEC ACPI_DEBUG_LEVEL (ACPI_LV_EXEC) -#define ACPI_DB_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_NAMES) -#define ACPI_DB_OPREGION ACPI_DEBUG_LEVEL (ACPI_LV_OPREGION) -#define ACPI_DB_BFIELD ACPI_DEBUG_LEVEL (ACPI_LV_BFIELD) -#define ACPI_DB_TABLES ACPI_DEBUG_LEVEL (ACPI_LV_TABLES) -#define ACPI_DB_FUNCTIONS ACPI_DEBUG_LEVEL (ACPI_LV_FUNCTIONS) -#define ACPI_DB_VALUES ACPI_DEBUG_LEVEL (ACPI_LV_VALUES) -#define ACPI_DB_OBJECTS ACPI_DEBUG_LEVEL (ACPI_LV_OBJECTS) -#define ACPI_DB_ALLOCATIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALLOCATIONS) -#define ACPI_DB_RESOURCES ACPI_DEBUG_LEVEL (ACPI_LV_RESOURCES) -#define ACPI_DB_IO ACPI_DEBUG_LEVEL (ACPI_LV_IO) -#define ACPI_DB_INTERRUPTS ACPI_DEBUG_LEVEL (ACPI_LV_INTERRUPTS) -#define ACPI_DB_USER_REQUESTS ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS) -#define ACPI_DB_PACKAGE ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE) -#define ACPI_DB_MUTEX ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX) -#define ACPI_DB_INIT ACPI_DEBUG_LEVEL (ACPI_LV_INIT) - -#define ACPI_DB_ALL ACPI_DEBUG_LEVEL (0x0FFFFF80) - - -/* Exceptionally verbose output -- also used in the global "Debug_level" */ - -#define ACPI_DB_AML_DISASSEMBLE 0x10000000 -#define ACPI_DB_VERBOSE_INFO 0x20000000 -#define ACPI_DB_FULL_TABLES 0x40000000 -#define ACPI_DB_EVENTS 0x80000000 - -#define ACPI_DB_VERBOSE 0xF0000000 - - -/* Defaults for Debug_level, debug and normal */ - -#define DEBUG_DEFAULT (ACPI_LV_OK | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) -#define NORMAL_DEFAULT (ACPI_LV_OK | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) -#define DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) - -/* Misc defines */ - -#define HEX 0x01 -#define ASCII 0x02 -#define FULL_ADDRESS 0x04 -#define CHARS_PER_LINE 16 /* used in Dump_buf function */ - - -#endif /* __ACOUTPUT_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acparser.h linux-2.4.22/drivers/acpi/include/acparser.h --- linux-2.4.21/drivers/acpi/include/acparser.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acparser.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,293 +0,0 @@ -/****************************************************************************** - * - * Module Name: acparser.h - AML Parser subcomponent prototypes and defines - * $Revision: 54 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACPARSER_H__ -#define __ACPARSER_H__ - - -#define OP_HAS_RETURN_VALUE 1 - -/* variable # arguments */ - -#define ACPI_VAR_ARGS ACPI_UINT32_MAX - -/* maximum virtual address */ - -#define ACPI_MAX_AML ((u8 *)(~0UL)) - - -#define ACPI_PARSE_DELETE_TREE 0x0001 -#define ACPI_PARSE_NO_TREE_DELETE 0x0000 -#define ACPI_PARSE_TREE_MASK 0x0001 - -#define ACPI_PARSE_LOAD_PASS1 0x0010 -#define ACPI_PARSE_LOAD_PASS2 0x0020 -#define ACPI_PARSE_EXECUTE 0x0030 -#define ACPI_PARSE_MODE_MASK 0x0030 - -/* psapi - Parser external interfaces */ - -acpi_status -acpi_psx_load_table ( - u8 *pcode_addr, - u32 pcode_length); - -acpi_status -acpi_psx_execute ( - acpi_namespace_node *method_node, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc); - -/****************************************************************************** - * - * Parser interfaces - * - *****************************************************************************/ - - -/* psargs - Parse AML opcode arguments */ - -u8 * -acpi_ps_get_next_package_end ( - acpi_parse_state *parser_state); - -u32 -acpi_ps_get_next_package_length ( - acpi_parse_state *parser_state); - -NATIVE_CHAR * -acpi_ps_get_next_namestring ( - acpi_parse_state *parser_state); - -void -acpi_ps_get_next_simple_arg ( - acpi_parse_state *parser_state, - u32 arg_type, /* type of argument */ - acpi_parse_object *arg); /* (OUT) argument data */ - -void -acpi_ps_get_next_namepath ( - acpi_parse_state *parser_state, - acpi_parse_object *arg, - u32 *arg_count, - u8 method_call); - -acpi_parse_object * -acpi_ps_get_next_field ( - acpi_parse_state *parser_state); - -acpi_parse_object * -acpi_ps_get_next_arg ( - acpi_parse_state *parser_state, - u32 arg_type, - u32 *arg_count); - - -/* psopcode - AML Opcode information */ - -const acpi_opcode_info * -acpi_ps_get_opcode_info ( - u16 opcode); - -NATIVE_CHAR * -acpi_ps_get_opcode_name ( - u16 opcode); - - -/* psparse - top level parsing routines */ - -acpi_status -acpi_ps_find_object ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op); - -void -acpi_ps_delete_parse_tree ( - acpi_parse_object *root); - -acpi_status -acpi_ps_parse_loop ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ps_parse_aml ( - acpi_walk_state *walk_state); - -acpi_status -acpi_ps_parse_table ( - u8 *aml, - u32 aml_size, - acpi_parse_downwards descending_callback, - acpi_parse_upwards ascending_callback, - acpi_parse_object **root_object); - -u16 -acpi_ps_peek_opcode ( - acpi_parse_state *state); - - -/* psscope - Scope stack management routines */ - - -acpi_status -acpi_ps_init_scope ( - acpi_parse_state *parser_state, - acpi_parse_object *root); - -acpi_parse_object * -acpi_ps_get_parent_scope ( - acpi_parse_state *state); - -u8 -acpi_ps_has_completed_scope ( - acpi_parse_state *parser_state); - -void -acpi_ps_pop_scope ( - acpi_parse_state *parser_state, - acpi_parse_object **op, - u32 *arg_list, - u32 *arg_count); - -acpi_status -acpi_ps_push_scope ( - acpi_parse_state *parser_state, - acpi_parse_object *op, - u32 remaining_args, - u32 arg_count); - -void -acpi_ps_cleanup_scope ( - acpi_parse_state *state); - - -/* pstree - parse tree manipulation routines */ - -void -acpi_ps_append_arg( - acpi_parse_object *op, - acpi_parse_object *arg); - -acpi_parse_object* -acpi_ps_find ( - acpi_parse_object *scope, - NATIVE_CHAR *path, - u16 opcode, - u32 create); - -acpi_parse_object * -acpi_ps_get_arg( - acpi_parse_object *op, - u32 argn); - -acpi_parse_object * -acpi_ps_get_child ( - acpi_parse_object *op); - -acpi_parse_object * -acpi_ps_get_depth_next ( - acpi_parse_object *origin, - acpi_parse_object *op); - - -/* pswalk - parse tree walk routines */ - -acpi_status -acpi_ps_walk_parsed_aml ( - acpi_parse_object *start_op, - acpi_parse_object *end_op, - acpi_operand_object *mth_desc, - acpi_namespace_node *start_node, - acpi_operand_object **params, - acpi_operand_object **caller_return_desc, - acpi_owner_id owner_id, - acpi_parse_downwards descending_callback, - acpi_parse_upwards ascending_callback); - -acpi_status -acpi_ps_get_next_walk_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_parse_upwards ascending_callback); - - -/* psutils - parser utilities */ - -void -acpi_ps_init_op ( - acpi_parse_object *op, - u16 opcode); - -acpi_parse_object * -acpi_ps_alloc_op ( - u16 opcode); - -void -acpi_ps_free_op ( - acpi_parse_object *op); - -void -acpi_ps_delete_parse_cache ( - void); - -u8 -acpi_ps_is_leading_char ( - u32 c); - -u8 -acpi_ps_is_prefix_char ( - u32 c); - -u32 -acpi_ps_get_name( - acpi_parse_object *op); - -void -acpi_ps_set_name( - acpi_parse_object *op, - u32 name); - - -/* psdump - display parser tree */ - -u32 -acpi_ps_sprint_path ( - NATIVE_CHAR *buffer_start, - u32 buffer_size, - acpi_parse_object *op); - -u32 -acpi_ps_sprint_op ( - NATIVE_CHAR *buffer_start, - u32 buffer_size, - acpi_parse_object *op); - -void -acpi_ps_show ( - acpi_parse_object *op); - - -#endif /* __ACPARSER_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acpi.h linux-2.4.22/drivers/acpi/include/acpi.h --- linux-2.4.21/drivers/acpi/include/acpi.h 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acpi.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,51 +0,0 @@ -/****************************************************************************** - * - * Name: acpi.h - Master include file, Publics and external data. - * $Revision: 54 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACPI_H__ -#define __ACPI_H__ - -/* - * Common includes for all ACPI driver files - * We put them here because we don't want to duplicate them - * in the rest of the source code again and again. - */ -#include "acconfig.h" /* Configuration constants */ -#include "platform/acenv.h" /* Target environment specific items */ -#include "actypes.h" /* Fundamental common data types */ -#include "acexcep.h" /* ACPI exception codes */ -#include "acmacros.h" /* C macros */ -#include "actbl.h" /* ACPI table definitions */ -#include "aclocal.h" /* Internal data types */ -#include "acoutput.h" /* Error output and Debug macros */ -#include "acpiosxf.h" /* Interfaces to the ACPI-to-OS layer*/ -#include "acpixf.h" /* ACPI core subsystem external interfaces */ -#include "acobject.h" /* ACPI internal object */ -#include "acstruct.h" /* Common structures */ -#include "acglobal.h" /* All global variables */ -#include "achware.h" /* Hardware defines and interfaces */ -#include "acutils.h" /* Utility interfaces */ - - -#endif /* __ACPI_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acpiosxf.h linux-2.4.22/drivers/acpi/include/acpiosxf.h --- linux-2.4.21/drivers/acpi/include/acpiosxf.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acpiosxf.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,307 +0,0 @@ - -/****************************************************************************** - * - * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These - * interfaces must be implemented by OSL to interface the - * ACPI components to the host operating system. - * - *****************************************************************************/ - - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACPIOSXF_H__ -#define __ACPIOSXF_H__ - -#include "platform/acenv.h" -#include "actypes.h" - - -/* Priorities for Acpi_os_queue_for_execution */ - -#define OSD_PRIORITY_GPE 1 -#define OSD_PRIORITY_HIGH 2 -#define OSD_PRIORITY_MED 3 -#define OSD_PRIORITY_LO 4 - -#define ACPI_NO_UNIT_LIMIT ((u32) -1) -#define ACPI_MUTEX_SEM 1 - - -/* Functions for Acpi_os_signal */ - -#define ACPI_SIGNAL_FATAL 0 -#define ACPI_SIGNAL_BREAKPOINT 1 - -typedef struct acpi_fatal_info -{ - u32 type; - u32 code; - u32 argument; - -} ACPI_SIGNAL_FATAL_INFO; - - -/* - * Types specific to the OS service interfaces - */ - -typedef -u32 (*OSD_HANDLER) ( - void *context); - -typedef -void (*OSD_EXECUTION_CALLBACK) ( - void *context); - - -/* - * OSL Initialization and shutdown primitives - */ - -acpi_status -acpi_os_initialize ( - void); - -acpi_status -acpi_os_terminate ( - void); - -acpi_status -acpi_os_get_root_pointer ( - u32 flags, - ACPI_PHYSICAL_ADDRESS *rsdp_physical_address); - - -/* - * Synchronization primitives - */ - -acpi_status -acpi_os_create_semaphore ( - u32 max_units, - u32 initial_units, - acpi_handle *out_handle); - -acpi_status -acpi_os_delete_semaphore ( - acpi_handle handle); - -acpi_status -acpi_os_wait_semaphore ( - acpi_handle handle, - u32 units, - u32 timeout); - -acpi_status -acpi_os_signal_semaphore ( - acpi_handle handle, - u32 units); - - -/* - * Memory allocation and mapping - */ - -void * -acpi_os_allocate ( - u32 size); - -void * -acpi_os_callocate ( - u32 size); - -void -acpi_os_free ( - void * memory); - -acpi_status -acpi_os_map_memory ( - ACPI_PHYSICAL_ADDRESS physical_address, - u32 length, - void **logical_address); - -void -acpi_os_unmap_memory ( - void *logical_address, - u32 length); - -acpi_status -acpi_os_get_physical_address ( - void *logical_address, - ACPI_PHYSICAL_ADDRESS *physical_address); - - -/* - * Interrupt handlers - */ - -acpi_status -acpi_os_install_interrupt_handler ( - u32 interrupt_number, - OSD_HANDLER service_routine, - void *context); - -acpi_status -acpi_os_remove_interrupt_handler ( - u32 interrupt_number, - OSD_HANDLER service_routine); - - -/* - * Threads and Scheduling - */ - -u32 -acpi_os_get_thread_id ( - void); - -acpi_status -acpi_os_queue_for_execution ( - u32 priority, - OSD_EXECUTION_CALLBACK function, - void *context); - -void -acpi_os_sleep ( - u32 seconds, - u32 milliseconds); - -void -acpi_os_stall ( - u32 microseconds); - - -/* - * Platform and hardware-independent I/O interfaces - */ - -acpi_status -acpi_os_read_port ( - ACPI_IO_ADDRESS address, - void *value, - u32 width); - - -acpi_status -acpi_os_write_port ( - ACPI_IO_ADDRESS address, - NATIVE_UINT value, - u32 width); - - -/* - * Platform and hardware-independent physical memory interfaces - */ - -acpi_status -acpi_os_read_memory ( - ACPI_PHYSICAL_ADDRESS address, - void *value, - u32 width); - - -acpi_status -acpi_os_write_memory ( - ACPI_PHYSICAL_ADDRESS address, - NATIVE_UINT value, - u32 width); - - -/* - * Platform and hardware-independent PCI configuration space access - */ - -acpi_status -acpi_os_read_pci_configuration ( - acpi_pci_id *pci_id, - u32 register, - void *value, - u32 width); - - -acpi_status -acpi_os_write_pci_configuration ( - acpi_pci_id *pci_id, - u32 register, - NATIVE_UINT value, - u32 width); - - -/* - * Miscellaneous - */ - -u8 -acpi_os_readable ( - void *pointer, - u32 length); - - -u8 -acpi_os_writable ( - void *pointer, - u32 length); - -u32 -acpi_os_get_timer ( - void); - -acpi_status -acpi_os_signal ( - u32 function, - void *info); - -/* - * Debug print routines - */ - -s32 -acpi_os_printf ( - const NATIVE_CHAR *format, - ...); - -s32 -acpi_os_vprintf ( - const NATIVE_CHAR *format, - va_list args); - - -/* - * Debug input - */ - -u32 -acpi_os_get_line ( - NATIVE_CHAR *buffer); - - -/* - * Debug - */ - -void -acpi_os_dbg_assert( - void *failed_assertion, - void *file_name, - u32 line_number, - NATIVE_CHAR *message); - - -#endif /* __ACPIOSXF_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acpixf.h linux-2.4.22/drivers/acpi/include/acpixf.h --- linux-2.4.21/drivers/acpi/include/acpixf.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acpixf.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,326 +0,0 @@ - -/****************************************************************************** - * - * Name: acpixf.h - External interfaces to the ACPI subsystem - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACXFACE_H__ -#define __ACXFACE_H__ - -#include "actypes.h" -#include "actbl.h" - - - /* - * Global interfaces - */ - -acpi_status -acpi_initialize_subsystem ( - void); - -acpi_status -acpi_enable_subsystem ( - u32 flags); - -acpi_status -acpi_terminate ( - void); - -acpi_status -acpi_subsystem_status ( - void); - -acpi_status -acpi_enable ( - void); - -acpi_status -acpi_disable ( - void); - -acpi_status -acpi_get_system_info ( - acpi_buffer *ret_buffer); - -const char * -acpi_format_exception ( - acpi_status exception); - - -/* - * ACPI Memory manager - */ - -void * -acpi_allocate ( - u32 size); - -void * -acpi_callocate ( - u32 size); - -void -acpi_free ( - void *address); - - -/* - * ACPI table manipulation interfaces - */ - -acpi_status -acpi_find_root_pointer ( - u32 flags, - ACPI_PHYSICAL_ADDRESS *rsdp_physical_address); - -acpi_status -acpi_load_tables ( - void); - -acpi_status -acpi_load_table ( - acpi_table_header *table_ptr); - -acpi_status -acpi_unload_table ( - acpi_table_type table_type); - -acpi_status -acpi_get_table_header ( - acpi_table_type table_type, - u32 instance, - acpi_table_header *out_table_header); - -acpi_status -acpi_get_table ( - acpi_table_type table_type, - u32 instance, - acpi_buffer *ret_buffer); - -acpi_status -acpi_get_firmware_table ( - acpi_string signature, - u32 instance, - u32 flags, - acpi_table_header **table_pointer); - - -/* - * Namespace and name interfaces - */ - -acpi_status -acpi_walk_namespace ( - acpi_object_type type, - acpi_handle start_object, - u32 max_depth, - acpi_walk_callback user_function, - void *context, - void * *return_value); - -acpi_status -acpi_get_devices ( - NATIVE_CHAR *HID, - acpi_walk_callback user_function, - void *context, - void **return_value); - -acpi_status -acpi_get_name ( - acpi_handle handle, - u32 name_type, - acpi_buffer *ret_path_ptr); - -acpi_status -acpi_get_handle ( - acpi_handle parent, - acpi_string pathname, - acpi_handle *ret_handle); - - -/* - * Object manipulation and enumeration - */ - -acpi_status -acpi_evaluate_object ( - acpi_handle object, - acpi_string pathname, - acpi_object_list *parameter_objects, - acpi_buffer *return_object_buffer); - -acpi_status -acpi_get_object_info ( - acpi_handle device, - acpi_device_info *info); - -acpi_status -acpi_get_next_object ( - acpi_object_type type, - acpi_handle parent, - acpi_handle child, - acpi_handle *out_handle); - -acpi_status -acpi_get_type ( - acpi_handle object, - acpi_object_type *out_type); - -acpi_status -acpi_get_parent ( - acpi_handle object, - acpi_handle *out_handle); - - -/* - * Event handler interfaces - */ - -acpi_status -acpi_install_fixed_event_handler ( - u32 acpi_event, - acpi_event_handler handler, - void *context); - -acpi_status -acpi_remove_fixed_event_handler ( - u32 acpi_event, - acpi_event_handler handler); - -acpi_status -acpi_install_notify_handler ( - acpi_handle device, - u32 handler_type, - acpi_notify_handler handler, - void *context); - -acpi_status -acpi_remove_notify_handler ( - acpi_handle device, - u32 handler_type, - acpi_notify_handler handler); - -acpi_status -acpi_install_address_space_handler ( - acpi_handle device, - ACPI_ADR_SPACE_TYPE space_id, - acpi_adr_space_handler handler, - acpi_adr_space_setup setup, - void *context); - -acpi_status -acpi_remove_address_space_handler ( - acpi_handle device, - ACPI_ADR_SPACE_TYPE space_id, - acpi_adr_space_handler handler); - -acpi_status -acpi_install_gpe_handler ( - u32 gpe_number, - u32 type, - acpi_gpe_handler handler, - void *context); - -acpi_status -acpi_acquire_global_lock ( - void); - -acpi_status -acpi_release_global_lock ( - void); - -acpi_status -acpi_remove_gpe_handler ( - u32 gpe_number, - acpi_gpe_handler handler); - -acpi_status -acpi_enable_event ( - u32 acpi_event, - u32 type, - u32 flags); - -acpi_status -acpi_disable_event ( - u32 acpi_event, - u32 type, - u32 flags); - -acpi_status -acpi_clear_event ( - u32 acpi_event, - u32 type); - -acpi_status -acpi_get_event_status ( - u32 acpi_event, - u32 type, - acpi_event_status *event_status); - -/* - * Resource interfaces - */ - -acpi_status -acpi_get_current_resources( - acpi_handle device_handle, - acpi_buffer *ret_buffer); - -acpi_status -acpi_get_possible_resources( - acpi_handle device_handle, - acpi_buffer *ret_buffer); - -acpi_status -acpi_set_current_resources ( - acpi_handle device_handle, - acpi_buffer *in_buffer); - -acpi_status -acpi_get_irq_routing_table ( - acpi_handle bus_device_handle, - acpi_buffer *ret_buffer); - - -/* - * Hardware (ACPI device) interfaces - */ - -acpi_status -acpi_set_firmware_waking_vector ( - ACPI_PHYSICAL_ADDRESS physical_address); - -acpi_status -acpi_get_firmware_waking_vector ( - ACPI_PHYSICAL_ADDRESS *physical_address); - -acpi_status -acpi_enter_sleep_state ( - u8 sleep_state); - -acpi_status -acpi_leave_sleep_state ( - u8 sleep_state); - -#endif /* __ACXFACE_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acresrc.h linux-2.4.22/drivers/acpi/include/acresrc.h --- linux-2.4.21/drivers/acpi/include/acresrc.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acresrc.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,320 +0,0 @@ -/****************************************************************************** - * - * Name: acresrc.h - Resource Manager function prototypes - * $Revision: 25 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACRESRC_H__ -#define __ACRESRC_H__ - - -/* - * Function prototypes called from Acpi* APIs - */ - -acpi_status -acpi_rs_get_prt_method_data ( - acpi_handle handle, - acpi_buffer *ret_buffer); - - -acpi_status -acpi_rs_get_crs_method_data ( - acpi_handle handle, - acpi_buffer *ret_buffer); - -acpi_status -acpi_rs_get_prs_method_data ( - acpi_handle handle, - acpi_buffer *ret_buffer); - -acpi_status -acpi_rs_set_srs_method_data ( - acpi_handle handle, - acpi_buffer *ret_buffer); - -acpi_status -acpi_rs_create_resource_list ( - acpi_operand_object *byte_stream_buffer, - u8 *output_buffer, - u32 *output_buffer_length); - -acpi_status -acpi_rs_create_byte_stream ( - acpi_resource *linked_list_buffer, - u8 *output_buffer, - u32 *output_buffer_length); - -acpi_status -acpi_rs_create_pci_routing_table ( - acpi_operand_object *method_return_object, - u8 *output_buffer, - u32 *output_buffer_length); - - -/* - *Function prototypes called from Acpi_rs_create*APIs - */ - -void -acpi_rs_dump_resource_list ( - acpi_resource *resource); - -void -acpi_rs_dump_irq_list ( - u8 *route_table); - -acpi_status -acpi_rs_get_byte_stream_start ( - u8 *byte_stream_buffer, - u8 **byte_stream_start, - u32 *size); - -acpi_status -acpi_rs_calculate_list_length ( - u8 *byte_stream_buffer, - u32 byte_stream_buffer_length, - u32 *size_needed); - -acpi_status -acpi_rs_calculate_byte_stream_length ( - acpi_resource *linked_list_buffer, - u32 *size_needed); - -acpi_status -acpi_rs_calculate_pci_routing_table_length ( - acpi_operand_object *package_object, - u32 *buffer_size_needed); - -acpi_status -acpi_rs_byte_stream_to_list ( - u8 *byte_stream_buffer, - u32 byte_stream_buffer_length, - u8 **output_buffer); - -acpi_status -acpi_rs_list_to_byte_stream ( - acpi_resource *linked_list, - u32 byte_stream_size_needed, - u8 **output_buffer); - -acpi_status -acpi_rs_io_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_fixed_io_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_io_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_fixed_io_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_irq_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_irq_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_dma_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_dma_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_address16_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_address16_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_address32_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_address32_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_address64_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_address64_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_start_dependent_functions_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_end_dependent_functions_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_start_dependent_functions_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_end_dependent_functions_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_memory24_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_memory24_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_memory32_range_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size -); - -acpi_status -acpi_rs_fixed_memory32_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_memory32_range_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_fixed_memory32_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_extended_irq_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_extended_irq_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_end_tag_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_end_tag_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -acpi_status -acpi_rs_vendor_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size); - -acpi_status -acpi_rs_vendor_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed); - -u8 -acpi_rs_get_resource_type ( - u8 resource_start_byte); - -#endif /* __ACRESRC_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acstruct.h linux-2.4.22/drivers/acpi/include/acstruct.h --- linux-2.4.21/drivers/acpi/include/acstruct.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acstruct.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,199 +0,0 @@ -/****************************************************************************** - * - * Name: acstruct.h - Internal structs - * $Revision: 10 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACSTRUCT_H__ -#define __ACSTRUCT_H__ - - -/***************************************************************************** - * - * Tree walking typedefs and structs - * - ****************************************************************************/ - - -/* - * Walk state - current state of a parse tree walk. Used for both a leisurely stroll through - * the tree (for whatever reason), and for control method execution. - */ - -#define NEXT_OP_DOWNWARD 1 -#define NEXT_OP_UPWARD 2 - -#define WALK_NON_METHOD 0 -#define WALK_METHOD 1 -#define WALK_METHOD_RESTART 2 - -typedef struct acpi_walk_state -{ - u8 data_type; /* To differentiate various internal objs MUST BE FIRST!*/\ - acpi_owner_id owner_id; /* Owner of objects created during the walk */ - u8 last_predicate; /* Result of last predicate */ - u8 current_result; /* */ - u8 next_op_info; /* Info about Next_op */ - u8 num_operands; /* Stack pointer for Operands[] array */ - u8 return_used; - u8 walk_type; - u16 current_sync_level; /* Mutex Sync (nested acquire) level */ - u16 opcode; /* Current AML opcode */ - u32 arg_count; /* push for fixed or var args */ - u32 aml_offset; - u32 arg_types; - u32 method_breakpoint; /* For single stepping */ - u32 parse_flags; - u32 prev_arg_types; - - - u8 *aml_last_while; - struct acpi_node arguments[MTH_NUM_ARGS]; /* Control method arguments */ - union acpi_operand_obj **caller_return_desc; - acpi_generic_state *control_state; /* List of control states (nested IFs) */ - struct acpi_node local_variables[MTH_NUM_LOCALS]; /* Control method locals */ - struct acpi_node *method_call_node; /* Called method Node*/ - acpi_parse_object *method_call_op; /* Method_call Op if running a method */ - union acpi_operand_obj *method_desc; /* Method descriptor if running a method */ - struct acpi_node *method_node; /* Method Node if running a method */ - acpi_parse_object *op; /* Current parser op */ - union acpi_operand_obj *operands[OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */ - const acpi_opcode_info *op_info; /* Info on current opcode */ - acpi_parse_object *origin; /* Start of walk [Obsolete] */ - union acpi_operand_obj **params; - acpi_parse_state parser_state; /* Current state of parser */ - union acpi_operand_obj *result_obj; - acpi_generic_state *results; /* Stack of accumulated results */ - union acpi_operand_obj *return_desc; /* Return object, if any */ - acpi_generic_state *scope_info; /* Stack of nested scopes */ - -/* TBD: Obsolete with removal of WALK procedure ? */ - acpi_parse_object *prev_op; /* Last op that was processed */ - acpi_parse_object *next_op; /* next op to be processed */ - - - acpi_parse_downwards descending_callback; - acpi_parse_upwards ascending_callback; - struct acpi_walk_list *walk_list; - struct acpi_walk_state *next; /* Next Walk_state in list */ - - -} acpi_walk_state; - - -/* - * Walk list - head of a tree of walk states. Multiple walk states are created when there - * are nested control methods executing. - */ -typedef struct acpi_walk_list -{ - - acpi_walk_state *walk_state; - ACPI_OBJECT_MUTEX acquired_mutex_list; /* List of all currently acquired mutexes */ - -} acpi_walk_list; - - -/* Info used by Acpi_ps_init_objects */ - -typedef struct acpi_init_walk_info -{ - u16 method_count; - u16 op_region_count; - u16 field_count; - u16 op_region_init; - u16 field_init; - u16 object_count; - acpi_table_desc *table_desc; - -} acpi_init_walk_info; - - -/* Info used by TBD */ - -typedef struct acpi_device_walk_info -{ - u16 device_count; - u16 num_STA; - u16 num_INI; - acpi_table_desc *table_desc; - -} acpi_device_walk_info; - - -/* TBD: [Restructure] Merge with struct above */ - -typedef struct acpi_walk_info -{ - u32 debug_level; - u32 owner_id; - u8 display_type; - -} acpi_walk_info; - -/* Display Types */ - -#define ACPI_DISPLAY_SUMMARY 0 -#define ACPI_DISPLAY_OBJECTS 1 - -typedef struct acpi_get_devices_info -{ - acpi_walk_callback user_function; - void *context; - NATIVE_CHAR *hid; - -} acpi_get_devices_info; - - -typedef union acpi_aml_operands -{ - acpi_operand_object *operands[7]; - - struct - { - ACPI_OBJECT_INTEGER *type; - ACPI_OBJECT_INTEGER *code; - ACPI_OBJECT_INTEGER *argument; - - } fatal; - - struct - { - acpi_operand_object *source; - ACPI_OBJECT_INTEGER *index; - acpi_operand_object *target; - - } index; - - struct - { - acpi_operand_object *source; - ACPI_OBJECT_INTEGER *index; - ACPI_OBJECT_INTEGER *length; - acpi_operand_object *target; - - } mid; - -} ACPI_AML_OPERANDS; - - -#endif diff -urN linux-2.4.21/drivers/acpi/include/actables.h linux-2.4.22/drivers/acpi/include/actables.h --- linux-2.4.21/drivers/acpi/include/actables.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/actables.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,200 +0,0 @@ -/****************************************************************************** - * - * Name: actables.h - ACPI table management - * $Revision: 32 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACTABLES_H__ -#define __ACTABLES_H__ - - -/* Used in Acpi_tb_map_acpi_table for size parameter if table header is to be used */ - -#define SIZE_IN_HEADER 0 - - -acpi_status -acpi_tb_handle_to_object ( - u16 table_id, - acpi_table_desc **table_desc); - -/* - * tbconvrt - Table conversion routines - */ - -acpi_status -acpi_tb_convert_to_xsdt ( - acpi_table_desc *table_info, - u32 *number_of_tables); - -acpi_status -acpi_tb_convert_table_fadt ( - void); - -acpi_status -acpi_tb_build_common_facs ( - acpi_table_desc *table_info); - -u32 -acpi_tb_get_table_count ( - RSDP_DESCRIPTOR *RSDP, - acpi_table_header *RSDT); - -/* - * tbget - Table "get" routines - */ - -acpi_status -acpi_tb_get_table_ptr ( - acpi_table_type table_type, - u32 instance, - acpi_table_header **table_ptr_loc); - -acpi_status -acpi_tb_get_table ( - ACPI_PHYSICAL_ADDRESS physical_address, - acpi_table_header *buffer_ptr, - acpi_table_desc *table_info); - -acpi_status -acpi_tb_verify_rsdp ( - ACPI_PHYSICAL_ADDRESS RSDP_physical_address); - -acpi_status -acpi_tb_get_table_facs ( - acpi_table_header *buffer_ptr, - acpi_table_desc *table_info); - -ACPI_PHYSICAL_ADDRESS -acpi_tb_get_rsdt_address ( - void); - -acpi_status -acpi_tb_validate_rsdt ( - acpi_table_header *table_ptr); - -acpi_status -acpi_tb_get_table_pointer ( - ACPI_PHYSICAL_ADDRESS physical_address, - u32 flags, - u32 *size, - acpi_table_header **table_ptr); - -/* - * tbgetall - Get all firmware ACPI tables - */ - -acpi_status -acpi_tb_get_all_tables ( - u32 number_of_tables, - acpi_table_header *buffer_ptr); - - -/* - * tbinstall - Table installation - */ - -acpi_status -acpi_tb_install_table ( - acpi_table_header *table_ptr, - acpi_table_desc *table_info); - -acpi_status -acpi_tb_recognize_table ( - acpi_table_header *table_ptr, - acpi_table_desc *table_info); - -acpi_status -acpi_tb_init_table_descriptor ( - acpi_table_type table_type, - acpi_table_desc *table_info); - - -/* - * tbremove - Table removal and deletion - */ - -void -acpi_tb_delete_acpi_tables ( - void); - -void -acpi_tb_delete_acpi_table ( - acpi_table_type type); - -void -acpi_tb_delete_single_table ( - acpi_table_desc *table_desc); - -acpi_table_desc * -acpi_tb_uninstall_table ( - acpi_table_desc *table_desc); - -void -acpi_tb_free_acpi_tables_of_type ( - acpi_table_desc *table_info); - - -/* - * tbrsd - RSDP, RSDT utilities - */ - -acpi_status -acpi_tb_get_table_rsdt ( - u32 *number_of_tables); - -u8 * -acpi_tb_scan_memory_for_rsdp ( - u8 *start_address, - u32 length); - -acpi_status -acpi_tb_find_rsdp ( - acpi_table_desc *table_info, - u32 flags); - - -/* - * tbutils - common table utilities - */ - -acpi_status -acpi_tb_map_acpi_table ( - ACPI_PHYSICAL_ADDRESS physical_address, - u32 *size, - acpi_table_header **logical_address); - -acpi_status -acpi_tb_verify_table_checksum ( - acpi_table_header *table_header); - -u8 -acpi_tb_checksum ( - void *buffer, - u32 length); - -acpi_status -acpi_tb_validate_table_header ( - acpi_table_header *table_header); - - -#endif /* __ACTABLES_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/actbl.h linux-2.4.22/drivers/acpi/include/actbl.h --- linux-2.4.21/drivers/acpi/include/actbl.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/actbl.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,217 +0,0 @@ -/****************************************************************************** - * - * Name: actbl.h - Table data structures defined in ACPI specification - * $Revision: 46 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACTBL_H__ -#define __ACTBL_H__ - - -/* - * Values for description table header signatures - */ - -#define RSDP_NAME "RSDP" -#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ -#define APIC_SIG "APIC" /* Multiple APIC Description Table */ -#define DSDT_SIG "DSDT" /* Differentiated System Description Table */ -#define FADT_SIG "FACP" /* Fixed ACPI Description Table */ -#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ -#define PSDT_SIG "PSDT" /* Persistent System Description Table */ -#define RSDT_SIG "RSDT" /* Root System Description Table */ -#define XSDT_SIG "XSDT" /* Extended System Description Table */ -#define SSDT_SIG "SSDT" /* Secondary System Description Table */ -#define SBST_SIG "SBST" /* Smart Battery Specification Table */ -#define SPIC_SIG "SPIC" /* iosapic table */ -#define BOOT_SIG "BOOT" /* Boot table */ - - -#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ - -/* values of Mapic.Model */ - -#define DUAL_PIC 0 -#define MULTIPLE_APIC 1 - -/* values of Type in APIC_HEADER */ - -#define APIC_PROC 0 -#define APIC_IO 1 - - -/* - * Common table types. The base code can remain - * constant if the underlying tables are changed - */ -#define RSDT_DESCRIPTOR RSDT_DESCRIPTOR_REV2 -#define xsdt_descriptor XSDT_DESCRIPTOR_REV2 -#define FACS_DESCRIPTOR facs_descriptor_rev2 -#define FADT_DESCRIPTOR fadt_descriptor_rev2 - - -#pragma pack(1) - -/* - * Architecture-independent tables - * The architecture dependent tables are in separate files - */ - -typedef struct /* Root System Descriptor Pointer */ -{ - NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ - u8 checksum; /* to make sum of struct == 0 */ - NATIVE_CHAR oem_id [6]; /* OEM identification */ - u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */ - u32 rsdt_physical_address; /* 32-bit physical address of RSDT */ - u32 length; /* XSDT Length in bytes including hdr */ - u64 xsdt_physical_address; /* 64-bit physical address of XSDT */ - u8 extended_checksum; /* Checksum of entire table */ - NATIVE_CHAR reserved [3]; /* reserved field must be 0 */ - -} RSDP_DESCRIPTOR; - - -typedef struct /* ACPI common table header */ -{ - NATIVE_CHAR signature [4]; /* identifies type of table */ - u32 length; /* length of table, in bytes, - * including header */ - u8 revision; /* specification minor version # */ - u8 checksum; /* to make sum of entire table == 0 */ - NATIVE_CHAR oem_id [6]; /* OEM identification */ - NATIVE_CHAR oem_table_id [8]; /* OEM table identification */ - u32 oem_revision; /* OEM revision number */ - NATIVE_CHAR asl_compiler_id [4]; /* ASL compiler vendor ID */ - u32 asl_compiler_revision; /* ASL compiler revision number */ - -} acpi_table_header; - - -typedef struct /* Common FACS for internal use */ -{ - u32 *global_lock; - u64 *firmware_waking_vector; - u8 vector_width; - -} acpi_common_facs; - - -typedef struct /* APIC Table */ -{ - acpi_table_header header; /* table header */ - u32 local_apic_address; /* Physical address for accessing local APICs */ - u32 PCATcompat : 1; /* a one indicates system also has dual 8259s */ - u32 reserved1 : 31; - -} APIC_TABLE; - - -typedef struct /* APIC Header */ -{ - u8 type; /* APIC type. Either APIC_PROC or APIC_IO */ - u8 length; /* Length of APIC structure */ - -} APIC_HEADER; - - -typedef struct /* Processor APIC */ -{ - APIC_HEADER header; - u8 processor_apic_id; /* ACPI processor id */ - u8 local_apic_id; /* processor's local APIC id */ - u32 processor_enabled: 1; /* Processor is usable if set */ - u32 reserved1 : 31; - -} PROCESSOR_APIC; - - -typedef struct /* IO APIC */ -{ - APIC_HEADER header; - u8 io_apic_id; /* I/O APIC ID */ - u8 reserved; /* reserved - must be zero */ - u32 io_apic_address; /* APIC's physical address */ - u32 vector; /* interrupt vector index where INTI - * lines start */ -} IO_APIC; - - -/* -** IA64 TODO: Add SAPIC Tables -*/ - -/* -** IA64 TODO: Modify Smart Battery Description to comply with ACPI IA64 -** extensions. -*/ -typedef struct /* Smart Battery Description Table */ -{ - acpi_table_header header; - u32 warning_level; - u32 low_level; - u32 critical_level; - -} SMART_BATTERY_DESCRIPTION_TABLE; - - -#pragma pack() - - -/* - * ACPI Table information. We save the table address, length, - * and type of memory allocation (mapped or allocated) for each - * table for 1) when we exit, and 2) if a new table is installed - */ - -#define ACPI_MEM_NOT_ALLOCATED 0 -#define ACPI_MEM_ALLOCATED 1 -#define ACPI_MEM_MAPPED 2 - -/* Definitions for the Flags bitfield member of ACPI_TABLE_SUPPORT */ - -#define ACPI_TABLE_SINGLE 0 -#define ACPI_TABLE_MULTIPLE 1 - - -/* Data about each known table type */ - -typedef struct _acpi_table_support -{ - NATIVE_CHAR *name; - NATIVE_CHAR *signature; - u8 sig_length; - u8 flags; - u16 status; - void **global_ptr; - -} ACPI_TABLE_SUPPORT; - -/* - * Get the architecture-specific tables - */ - -#include "actbl1.h" /* Acpi 1.0 table defintions */ -#include "actbl71.h" /* Acpi 0.71 IA-64 Extension table defintions */ -#include "actbl2.h" /* Acpi 2.0 table definitions */ - -#endif /* __ACTBL_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/actbl1.h linux-2.4.22/drivers/acpi/include/actbl1.h --- linux-2.4.21/drivers/acpi/include/actbl1.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/actbl1.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,123 +0,0 @@ -/****************************************************************************** - * - * Name: actbl1.h - ACPI 1.0 tables - * $Revision: 17 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACTBL1_H__ -#define __ACTBL1_H__ - -#pragma pack(1) - -/*************************************/ -/* ACPI Specification Rev 1.0 for */ -/* the Root System Description Table */ -/*************************************/ -typedef struct -{ - acpi_table_header header; /* Table header */ - u32 table_offset_entry [1]; /* Array of pointers to other */ - /* ACPI tables */ -} RSDT_DESCRIPTOR_REV1; - - -/***************************************/ -/* ACPI Specification Rev 1.0 for */ -/* the Firmware ACPI Control Structure */ -/***************************************/ -typedef struct -{ - NATIVE_CHAR signature[4]; /* signature "FACS" */ - u32 length; /* length of structure, in bytes */ - u32 hardware_signature; /* hardware configuration signature */ - u32 firmware_waking_vector; /* ACPI OS waking vector */ - u32 global_lock; /* Global Lock */ - u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ - u32 reserved1 : 31; /* must be 0 */ - u8 resverved3 [40]; /* reserved - must be zero */ - -} facs_descriptor_rev1; - - -/************************************/ -/* ACPI Specification Rev 1.0 for */ -/* the Fixed ACPI Description Table */ -/************************************/ -typedef struct -{ - acpi_table_header header; /* table header */ - u32 firmware_ctrl; /* Physical address of FACS */ - u32 dsdt; /* Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 reserved1; /* reserved */ - u16 sci_int; /* System vector of SCI interrupt */ - u32 smi_cmd; /* Port address of SMI command port */ - u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 reserved2; /* reserved - must be zero */ - u32 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ - u32 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ - u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ - u32 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* offset in gpe model where gpe1 events start */ - u8 reserved3; /* reserved */ - u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Size of area read to flush caches */ - u16 flush_stride; /* Stride used in flushing caches */ - u8 duty_offset; /* bit location of duty cycle field in p_cnt reg */ - u8 duty_width; /* bit width of duty cycle field in p_cnt reg */ - u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* index to century in RTC CMOS RAM */ - u8 reserved4; /* reserved */ - u8 reserved4a; /* reserved */ - u8 reserved4b; /* reserved */ - u32 wb_invd : 1; /* wbinvd instruction works properly */ - u32 wb_invd_flush : 1; /* wbinvd flushes but does not invalidate */ - u32 proc_c1 : 1; /* all processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ - u32 reserved5 : 23; /* reserved - must be zero */ - -} fadt_descriptor_rev1; - -#pragma pack() - -#endif /* __ACTBL1_H__ */ - - diff -urN linux-2.4.21/drivers/acpi/include/actbl2.h linux-2.4.22/drivers/acpi/include/actbl2.h --- linux-2.4.21/drivers/acpi/include/actbl2.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/actbl2.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,186 +0,0 @@ -/****************************************************************************** - * - * Name: actbl2.h - ACPI Specification Revision 2.0 Tables - * $Revision: 24 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACTBL2_H__ -#define __ACTBL2_H__ - -/* - * Prefered Power Management Profiles - */ -#define PM_UNSPECIFIED 0 -#define PM_DESKTOP 1 -#define PM_MOBILE 2 -#define PM_WORKSTATION 3 -#define PM_ENTERPRISE_SERVER 4 -#define PM_SOHO_SERVER 5 -#define PM_APPLIANCE_PC 6 - -/* - * ACPI Boot Arch Flags - */ -#define BAF_LEGACY_DEVICES 0x0001 -#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 - -#define FADT2_REVISION_ID 3 - - -#pragma pack(1) - -/* - * ACPI Specification Rev 2.0 for the Root System Description Table - */ -typedef struct -{ - acpi_table_header header; /* Table header */ - u32 table_offset_entry [1]; /* Array of pointers to */ - /* other tables' headers */ -} RSDT_DESCRIPTOR_REV2; - - -/* - * ACPI Specification Rev 2.0 for the Extended System Description Table (XSDT) - */ -typedef struct -{ - acpi_table_header header; /* Table header */ - u64 table_offset_entry [1]; /* Array of pointers to */ - /* other tables' headers */ -} XSDT_DESCRIPTOR_REV2; - - -/* - * ACPI Specification Rev 2.0 for the Firmware ACPI Control Structure - */ -typedef struct -{ - NATIVE_CHAR signature[4]; /* signature "FACS" */ - u32 length; /* length of structure, in bytes */ - u32 hardware_signature; /* hardware configuration signature */ - u32 firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */ - u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */ - u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ - u32 reserved1 : 31; /* must be 0 */ - u64 Xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */ - u8 version; /* Version of this table */ - u8 reserved3 [31]; /* reserved - must be zero */ - -} facs_descriptor_rev2; - - -/* - * ACPI Specification Rev 2.0 for the Generic Address Structure (GAS) - */ -typedef struct -{ - u8 address_space_id; /* Address space where struct or register exists. */ - u8 register_bit_width; /* Size in bits of given register */ - u8 register_bit_offset; /* Bit offset within the register */ - u8 reserved; /* Must be 0 */ - u64 address; /* 64-bit address of struct or register */ - -} acpi_generic_address; - - -/* - * ACPI Specification Rev 2.0 for the Fixed ACPI Description Table - */ -typedef struct -{ - acpi_table_header header; /* table header */ - u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ - u32 V1_dsdt; /* 32-bit physical address of DSDT */ - u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ - u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ - u16 sci_int; /* System vector of SCI interrupt */ - u32 smi_cmd; /* Port address of SMI command port */ - u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 pstate_cnt; /* processor performance state control*/ - u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ - u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ - u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 V1_gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ - u32 V1_gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* offset in gpe model where gpe1 events start */ - u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ - u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* number of flush strides that need to be read */ - u16 flush_stride; /* Processor's memory cache line width, in bytes */ - u8 duty_offset; /* Processor_’s duty cycle index in processor's P_CNT reg*/ - u8 duty_width; /* Processor_’s duty cycle value bit width in P_CNT register.*/ - u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* index to century in RTC CMOS RAM */ - u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ - u8 reserved2; /* reserved */ - u32 wb_invd : 1; /* wbinvd instruction works properly */ - u32 wb_invd_flush : 1; /* wbinvd flushes but does not invalidate */ - u32 proc_c1 : 1; /* all processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ - u32 dock_cap : 1; /* Supports Docking */ - u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG*/ - u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed. */ - u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices.*/ - u32 cpu_sw_sleep : 1; /* Indicates to OSPM that a processor native instruction */ - /* must be executed after writing the SLP_TYPx register. */ - u32 reserved6 : 18; /* reserved - must be zero */ - - acpi_generic_address reset_register; /* Reset register address in GAS format */ - u8 reset_value; /* Value to write to the Reset_register port to reset the system. */ - u8 reserved7[3]; /* These three bytes must be zero */ - u64 Xfirmware_ctrl; /* 64-bit physical address of FACS */ - u64 Xdsdt; /* 64-bit physical address of DSDT */ - acpi_generic_address Xpm1a_evt_blk; /* Extended Power Mgt 1a Acpi_event Reg Blk address */ - acpi_generic_address Xpm1b_evt_blk; /* Extended Power Mgt 1b Acpi_event Reg Blk address */ - acpi_generic_address Xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ - acpi_generic_address Xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ - acpi_generic_address Xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ - acpi_generic_address Xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ - acpi_generic_address Xgpe0blk; /* Extended General Purpose Acpi_event 0 Reg Blk address */ - acpi_generic_address Xgpe1_blk; /* Extended General Purpose Acpi_event 1 Reg Blk address */ - -} fadt_descriptor_rev2; - - -#pragma pack() - -#endif /* __ACTBL2_H__ */ - diff -urN linux-2.4.21/drivers/acpi/include/actbl71.h linux-2.4.22/drivers/acpi/include/actbl71.h --- linux-2.4.21/drivers/acpi/include/actbl71.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/actbl71.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,147 +0,0 @@ -/****************************************************************************** - * - * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 - * This file includes tables specific to this - * specification revision. - * $Revision: 11 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACTBL71_H__ -#define __ACTBL71_H__ - - -/* 0.71 FADT Address_space data item bitmasks defines */ -/* If the associated bit is zero then it is in memory space else in io space */ - -#define SMI_CMD_ADDRESS_SPACE 0x01 -#define PM1_BLK_ADDRESS_SPACE 0x02 -#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 -#define PM_TMR_BLK_ADDRESS_SPACE 0x08 -#define GPE0_BLK_ADDRESS_SPACE 0x10 -#define GPE1_BLK_ADDRESS_SPACE 0x20 - -/* Only for clarity in declarations */ - -typedef u64 IO_ADDRESS; - - -#pragma pack(1) -typedef struct /* Root System Descriptor Pointer */ -{ - NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ - u8 checksum; /* to make sum of struct == 0 */ - NATIVE_CHAR oem_id [6]; /* OEM identification */ - u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */ - u64 rsdt_physical_address; /* 64-bit physical address of RSDT */ -} RSDP_DESCRIPTOR_REV071; - - -/*****************************************/ -/* IA64 Extensions to ACPI Spec Rev 0.71 */ -/* for the Root System Description Table */ -/*****************************************/ -typedef struct -{ - acpi_table_header header; /* Table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - u64 table_offset_entry [1]; /* Array of pointers to other */ - /* tables' headers */ -} RSDT_DESCRIPTOR_REV071; - - -/*******************************************/ -/* IA64 Extensions to ACPI Spec Rev 0.71 */ -/* for the Firmware ACPI Control Structure */ -/*******************************************/ -typedef struct -{ - NATIVE_CHAR signature[4]; /* signature "FACS" */ - u32 length; /* length of structure, in bytes */ - u32 hardware_signature; /* hardware configuration signature */ - u32 reserved4; /* must be 0 */ - u64 firmware_waking_vector; /* ACPI OS waking vector */ - u64 global_lock; /* Global Lock */ - u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ - u32 reserved1 : 31; /* must be 0 */ - u8 reserved3 [28]; /* reserved - must be zero */ - -} facs_descriptor_rev071; - - -/******************************************/ -/* IA64 Extensions to ACPI Spec Rev 0.71 */ -/* for the Fixed ACPI Description Table */ -/******************************************/ -typedef struct -{ - acpi_table_header header; /* table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - u64 firmware_ctrl; /* 64-bit Physical address of FACS */ - u64 dsdt; /* 64-bit Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 address_space; /* Address Space Bitmask */ - u16 sci_int; /* System vector of SCI interrupt */ - u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 reserved2; /* reserved - must be zero */ - u64 smi_cmd; /* Port address of SMI command port */ - u64 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ - u64 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ - u64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u64 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ - u64 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* offset in gpe model where gpe1 events start */ - u8 reserved3; /* reserved */ - u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ - u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* index to century in RTC CMOS RAM */ - u8 reserved4; /* reserved */ - u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */ - u32 reserved5 : 1; /* reserved - must be zero */ - u32 proc_c1 : 1; /* all processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ - u32 dock_cap : 1; /* Supports Docking */ - u32 reserved6 : 22; /* reserved - must be zero */ - -} fadt_descriptor_rev071; - -#pragma pack() - -#endif /* __ACTBL71_H__ */ - diff -urN linux-2.4.21/drivers/acpi/include/actypes.h linux-2.4.22/drivers/acpi/include/actypes.h --- linux-2.4.21/drivers/acpi/include/actypes.h 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/include/actypes.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,1118 +0,0 @@ -/****************************************************************************** - * - * Name: actypes.h - Common data types for the entire ACPI subsystem - * $Revision: 193 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACTYPES_H__ -#define __ACTYPES_H__ - -/*! [Begin] no source code translation (keep the typedefs) */ - -/* - * Data types - Fixed across all compilation models - * - * BOOLEAN Logical Boolean. - * 1 byte value containing a 0 for FALSE or a 1 for TRUE. - * Other values are undefined. - * - * INT8 8-bit (1 byte) signed value - * UINT8 8-bit (1 byte) unsigned value - * INT16 16-bit (2 byte) signed value - * UINT16 16-bit (2 byte) unsigned value - * INT32 32-bit (4 byte) signed value - * UINT32 32-bit (4 byte) unsigned value - * INT64 64-bit (8 byte) signed value - * UINT64 64-bit (8 byte) unsigned value - * NATIVE_INT 32-bit on IA-32, 64-bit on IA-64 signed value - * NATIVE_UINT 32-bit on IA-32, 64-bit on IA-64 unsigned value - * UCHAR Character. 1 byte unsigned value. - */ - -#ifndef BITS_PER_LONG -#error "define BITS_PER_LONG" -#endif - -#if BITS_PER_LONG == 64 -/* - * 64-bit type definitions - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned char UCHAR; -typedef unsigned short UINT16; -typedef int INT32; -typedef unsigned int UINT32; -typedef COMPILER_DEPENDENT_UINT64 UINT64; - -typedef UINT64 NATIVE_UINT; -typedef long long NATIVE_INT; - -typedef NATIVE_UINT ACPI_TBLPTR; -typedef UINT64 ACPI_IO_ADDRESS; -typedef UINT64 ACPI_PHYSICAL_ADDRESS; - -#define ALIGNED_ADDRESS_BOUNDARY 0x00000008 /* No hardware alignment support in IA64 */ -#define ACPI_USE_NATIVE_DIVIDE /* Native 64-bit integer support */ - - -#elif BITS_PER_LONG == 16 -/* - * 16-bit type definitions - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned char UCHAR; -typedef unsigned int UINT16; -typedef long INT32; -typedef int INT16; -typedef unsigned long UINT32; - -typedef struct -{ - UINT32 Lo; - UINT32 Hi; - -} UINT64; - -typedef UINT16 NATIVE_UINT; -typedef INT16 NATIVE_INT; - -typedef UINT32 ACPI_TBLPTR; -typedef UINT32 ACPI_IO_ADDRESS; -typedef char *ACPI_PHYSICAL_ADDRESS; - -#define ALIGNED_ADDRESS_BOUNDARY 0x00000002 -#define _HW_ALIGNMENT_SUPPORT -#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ - -/* - * (16-bit only) internal integers must be 32-bits, so - * 64-bit integers cannot be supported - */ -#define ACPI_NO_INTEGER64_SUPPORT - - -#elif BITS_PER_LONG == 32 -/* - * 32-bit type definitions (default) - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned char UCHAR; -typedef unsigned short UINT16; -typedef int INT32; -typedef unsigned int UINT32; -typedef COMPILER_DEPENDENT_UINT64 UINT64; - -typedef UINT32 NATIVE_UINT; -typedef INT32 NATIVE_INT; - -typedef NATIVE_UINT ACPI_TBLPTR; -typedef UINT32 ACPI_IO_ADDRESS; -typedef UINT64 ACPI_PHYSICAL_ADDRESS; - -#define ALIGNED_ADDRESS_BOUNDARY 0x00000004 -#define _HW_ALIGNMENT_SUPPORT - -#else -#error "unknown BITS_PER_LONG" -#endif - - - -/* - * Miscellaneous common types - */ - -typedef UINT32 UINT32_BIT; -typedef NATIVE_UINT ACPI_PTRDIFF; -typedef char NATIVE_CHAR; - - -/* - * Data type ranges - */ - -#define ACPI_UINT8_MAX (UINT8) 0xFF -#define ACPI_UINT16_MAX (UINT16) 0xFFFF -#define ACPI_UINT32_MAX (UINT32) 0xFFFFFFFF -#define ACPI_UINT64_MAX (UINT64) 0xFFFFFFFFFFFFFFFF - - -#ifdef DEFINE_ALTERNATE_TYPES -/* - * Types used only in translated source - */ -typedef INT32 s32; -typedef UINT8 u8; -typedef UINT16 u16; -typedef UINT32 u32; -typedef UINT64 u64; -#endif -/*! [End] no source code translation !*/ - - -/* - * Useful defines - */ - -#ifdef FALSE -#undef FALSE -#endif -#define FALSE (1 == 0) - -#ifdef TRUE -#undef TRUE -#endif -#define TRUE (1 == 1) - -#ifndef NULL -#define NULL (void *) 0 -#endif - - -/* - * Local datatypes - */ - -typedef u32 acpi_status; /* All ACPI Exceptions */ -typedef u32 acpi_name; /* 4-byte ACPI name */ -typedef char* acpi_string; /* Null terminated ASCII string */ -typedef void* acpi_handle; /* Actually a ptr to an Node */ - -typedef struct -{ - u32 lo; - u32 hi; - -} uint64_struct; - -typedef union -{ - u64 full; - uint64_struct part; - -} uint64_overlay; - - -/* - * Acpi integer width. In ACPI version 1, integers are - * 32 bits. In ACPI version 2, integers are 64 bits. - * Note that this pertains to the ACPI integer type only, not - * other integers used in the implementation of the ACPI CA - * subsystem. - */ -#ifdef ACPI_NO_INTEGER64_SUPPORT - -/* 32-bit integers only, no 64-bit support */ - -typedef u32 acpi_integer; -#define ACPI_INTEGER_MAX ACPI_UINT32_MAX -#define ACPI_INTEGER_BIT_SIZE 32 -#define ACPI_MAX_BCD_VALUE 99999999 -#define ACPI_MAX_BCD_DIGITS 8 -#define ACPI_MAX_DECIMAL_DIGITS 10 - -#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */ - - -#else - -/* 64-bit integers */ - -typedef u64 acpi_integer; -#define ACPI_INTEGER_MAX ACPI_UINT64_MAX -#define ACPI_INTEGER_BIT_SIZE 64 -#define ACPI_MAX_BCD_VALUE 9999999999999999 -#define ACPI_MAX_BCD_DIGITS 16 -#define ACPI_MAX_DECIMAL_DIGITS 19 - -#ifdef _IA64 -#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */ -#endif -#endif - - -/* - * Constants with special meanings - */ - -#define ACPI_ROOT_OBJECT (acpi_handle)(-1) - - -/* - * Initialization sequence - */ -#define ACPI_FULL_INITIALIZATION 0x00 -#define ACPI_NO_ADDRESS_SPACE_INIT 0x01 -#define ACPI_NO_HARDWARE_INIT 0x02 -#define ACPI_NO_EVENT_INIT 0x04 -#define ACPI_NO_ACPI_ENABLE 0x08 -#define ACPI_NO_DEVICE_INIT 0x10 -#define ACPI_NO_OBJECT_INIT 0x20 - -/* - * Initialization state - */ -#define ACPI_INITIALIZED_OK 0x01 - -/* - * Power state values - */ - -#define ACPI_STATE_UNKNOWN (u8) 0xFF - -#define ACPI_STATE_S0 (u8) 0 -#define ACPI_STATE_S1 (u8) 1 -#define ACPI_STATE_S2 (u8) 2 -#define ACPI_STATE_S3 (u8) 3 -#define ACPI_STATE_S4 (u8) 4 -#define ACPI_STATE_S5 (u8) 5 -#define ACPI_S_STATES_MAX ACPI_STATE_S5 -#define ACPI_S_STATE_COUNT 6 - -#define ACPI_STATE_D0 (u8) 0 -#define ACPI_STATE_D1 (u8) 1 -#define ACPI_STATE_D2 (u8) 2 -#define ACPI_STATE_D3 (u8) 3 -#define ACPI_D_STATES_MAX ACPI_STATE_D3 -#define ACPI_D_STATE_COUNT 4 - -/* - * Standard notify values - */ -#define ACPI_NOTIFY_BUS_CHECK (u8) 0 -#define ACPI_NOTIFY_DEVICE_CHECK (u8) 1 -#define ACPI_NOTIFY_DEVICE_WAKE (u8) 2 -#define ACPI_NOTIFY_EJECT_REQUEST (u8) 3 -#define ACPI_NOTIFY_DEVICE_CHECK_LIGHT (u8) 4 -#define ACPI_NOTIFY_FREQUENCY_MISMATCH (u8) 5 -#define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6 -#define ACPI_NOTIFY_POWER_FAULT (u8) 7 - - -/* - * Table types. These values are passed to the table related APIs - */ - -typedef u32 acpi_table_type; - -#define ACPI_TABLE_RSDP (acpi_table_type) 0 -#define ACPI_TABLE_DSDT (acpi_table_type) 1 -#define ACPI_TABLE_FADT (acpi_table_type) 2 -#define ACPI_TABLE_FACS (acpi_table_type) 3 -#define ACPI_TABLE_PSDT (acpi_table_type) 4 -#define ACPI_TABLE_SSDT (acpi_table_type) 5 -#define ACPI_TABLE_XSDT (acpi_table_type) 6 -#define ACPI_TABLE_MAX 6 -#define NUM_ACPI_TABLES (ACPI_TABLE_MAX+1) - - -/* - * Types associated with names. The first group of - * values correspond to the definition of the ACPI - * Object_type operator (See the ACPI Spec). Therefore, - * only add to the first group if the spec changes! - * - * Types must be kept in sync with the Acpi_ns_properties - * and Acpi_ns_type_names arrays - */ - -typedef u32 acpi_object_type; -typedef u8 acpi_object_type8; - - -#define ACPI_TYPE_ANY 0 /* 0x00 */ -#define ACPI_TYPE_INTEGER 1 /* 0x01 Byte/Word/Dword/Zero/One/Ones */ -#define ACPI_TYPE_STRING 2 /* 0x02 */ -#define ACPI_TYPE_BUFFER 3 /* 0x03 */ -#define ACPI_TYPE_PACKAGE 4 /* 0x04 Byte_const, multiple Data_term/Constant/Super_name */ -#define ACPI_TYPE_FIELD_UNIT 5 /* 0x05 */ -#define ACPI_TYPE_DEVICE 6 /* 0x06 Name, multiple Node */ -#define ACPI_TYPE_EVENT 7 /* 0x07 */ -#define ACPI_TYPE_METHOD 8 /* 0x08 Name, Byte_const, multiple Code */ -#define ACPI_TYPE_MUTEX 9 /* 0x09 */ -#define ACPI_TYPE_REGION 10 /* 0x0A */ -#define ACPI_TYPE_POWER 11 /* 0x0B Name,Byte_const,Word_const,multi Node */ -#define ACPI_TYPE_PROCESSOR 12 /* 0x0C Name,Byte_const,DWord_const,Byte_const,multi Nm_o */ -#define ACPI_TYPE_THERMAL 13 /* 0x0D Name, multiple Node */ -#define ACPI_TYPE_BUFFER_FIELD 14 /* 0x0E */ -#define ACPI_TYPE_DDB_HANDLE 15 /* 0x0F */ -#define ACPI_TYPE_DEBUG_OBJECT 16 /* 0x10 */ - -#define ACPI_TYPE_MAX 16 - -/* - * This section contains object types that do not relate to the ACPI Object_type operator. - * They are used for various internal purposes only. If new predefined ACPI_TYPEs are - * added (via the ACPI specification), these internal types must move upwards. - * Also, values exceeding the largest official ACPI Object_type must not overlap with - * defined AML opcodes. - */ -#define INTERNAL_TYPE_BEGIN 17 - -#define INTERNAL_TYPE_REGION_FIELD 17 /* 0x11 */ -#define INTERNAL_TYPE_BANK_FIELD 18 /* 0x12 */ -#define INTERNAL_TYPE_INDEX_FIELD 19 /* 0x13 */ -#define INTERNAL_TYPE_REFERENCE 20 /* 0x14 Arg#, Local#, Name, Debug; used only in descriptors */ -#define INTERNAL_TYPE_ALIAS 21 /* 0x15 */ -#define INTERNAL_TYPE_NOTIFY 22 /* 0x16 */ -#define INTERNAL_TYPE_ADDRESS_HANDLER 23 /* 0x17 */ -#define INTERNAL_TYPE_RESOURCE 24 /* 0x18 */ -#define INTERNAL_TYPE_RESOURCE_FIELD 25 /* 0x19 */ - - -#define INTERNAL_TYPE_NODE_MAX 25 - -/* These are pseudo-types because there are never any namespace nodes with these types */ - -#define INTERNAL_TYPE_FIELD_DEFN 26 /* 0x1A Name, Byte_const, multiple Field_element */ -#define INTERNAL_TYPE_BANK_FIELD_DEFN 27 /* 0x1B 2 Name,DWord_const,Byte_const,multi Field_element */ -#define INTERNAL_TYPE_INDEX_FIELD_DEFN 28 /* 0x1C 2 Name, Byte_const, multiple Field_element */ -#define INTERNAL_TYPE_IF 29 /* 0x1D */ -#define INTERNAL_TYPE_ELSE 30 /* 0x1E */ -#define INTERNAL_TYPE_WHILE 31 /* 0x1F */ -#define INTERNAL_TYPE_SCOPE 32 /* 0x20 Name, multiple Node */ -#define INTERNAL_TYPE_DEF_ANY 33 /* 0x21 type is Any, suppress search of enclosing scopes */ -#define INTERNAL_TYPE_EXTRA 34 /* 0x22 */ - -#define INTERNAL_TYPE_MAX 34 - -#define INTERNAL_TYPE_INVALID 35 -#define ACPI_TYPE_NOT_FOUND 0xFF - - -/* - * Bitmapped ACPI types - * Used internally only - */ -#define ACPI_BTYPE_ANY 0x00000000 -#define ACPI_BTYPE_INTEGER 0x00000001 -#define ACPI_BTYPE_STRING 0x00000002 -#define ACPI_BTYPE_BUFFER 0x00000004 -#define ACPI_BTYPE_PACKAGE 0x00000008 -#define ACPI_BTYPE_FIELD_UNIT 0x00000010 -#define ACPI_BTYPE_DEVICE 0x00000020 -#define ACPI_BTYPE_EVENT 0x00000040 -#define ACPI_BTYPE_METHOD 0x00000080 -#define ACPI_BTYPE_MUTEX 0x00000100 -#define ACPI_BTYPE_REGION 0x00000200 -#define ACPI_BTYPE_POWER 0x00000400 -#define ACPI_BTYPE_PROCESSOR 0x00000800 -#define ACPI_BTYPE_THERMAL 0x00001000 -#define ACPI_BTYPE_BUFFER_FIELD 0x00002000 -#define ACPI_BTYPE_DDB_HANDLE 0x00004000 -#define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 -#define ACPI_BTYPE_REFERENCE 0x00010000 -#define ACPI_BTYPE_RESOURCE 0x00020000 - -#define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) - -#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) -#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE) -#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) -#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */ -#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF - - -/* - * Acpi_event Types: - * ------------ - * Fixed & general purpose... - */ - -typedef u32 acpi_event_type; - -#define ACPI_EVENT_FIXED (acpi_event_type) 0 -#define ACPI_EVENT_GPE (acpi_event_type) 1 - -/* - * Fixed events - */ - -#define ACPI_EVENT_PMTIMER (acpi_event_type) 0 - /* - * There's no bus master event so index 1 is used for IRQ's that are not - * handled by the SCI handler - */ -#define ACPI_EVENT_NOT_USED (acpi_event_type) 1 -#define ACPI_EVENT_GLOBAL (acpi_event_type) 2 -#define ACPI_EVENT_POWER_BUTTON (acpi_event_type) 3 -#define ACPI_EVENT_SLEEP_BUTTON (acpi_event_type) 4 -#define ACPI_EVENT_RTC (acpi_event_type) 5 -#define ACPI_EVENT_GENERAL (acpi_event_type) 6 -#define ACPI_EVENT_MAX 6 -#define ACPI_NUM_FIXED_EVENTS (acpi_event_type) 7 - -#define ACPI_GPE_INVALID 0xFF -#define ACPI_GPE_MAX 0xFF -#define ACPI_NUM_GPE 256 - -#define ACPI_EVENT_LEVEL_TRIGGERED (acpi_event_type) 1 -#define ACPI_EVENT_EDGE_TRIGGERED (acpi_event_type) 2 - -/* - * GPEs - */ -#define ACPI_EVENT_ENABLE 0x1 -#define ACPI_EVENT_WAKE_ENABLE 0x2 - -#define ACPI_EVENT_DISABLE 0x1 -#define ACPI_EVENT_WAKE_DISABLE 0x2 - - -/* - * Acpi_event Status: - * ------------- - * The encoding of acpi_event_status is illustrated below. - * Note that a set bit (1) indicates the property is TRUE - * (e.g. if bit 0 is set then the event is enabled). - * +-------------+-+-+-+ - * | Bits 31:3 |2|1|0| - * +-------------+-+-+-+ - * | | | | - * | | | +- Enabled? - * | | +--- Enabled for wake? - * | +----- Set? - * +----------- - */ -typedef u32 acpi_event_status; - -#define ACPI_EVENT_FLAG_DISABLED (acpi_event_status) 0x00 -#define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01 -#define ACPI_EVENT_FLAG_WAKE_ENABLED (acpi_event_status) 0x02 -#define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04 - - -/* Notify types */ - -#define ACPI_SYSTEM_NOTIFY 0 -#define ACPI_DEVICE_NOTIFY 1 -#define ACPI_MAX_NOTIFY_HANDLER_TYPE 1 - -#define MAX_SYS_NOTIFY 0x7f - - -/* Address Space (Operation Region) Types */ - -typedef u8 ACPI_ADR_SPACE_TYPE; - -#define ACPI_ADR_SPACE_SYSTEM_MEMORY (ACPI_ADR_SPACE_TYPE) 0 -#define ACPI_ADR_SPACE_SYSTEM_IO (ACPI_ADR_SPACE_TYPE) 1 -#define ACPI_ADR_SPACE_PCI_CONFIG (ACPI_ADR_SPACE_TYPE) 2 -#define ACPI_ADR_SPACE_EC (ACPI_ADR_SPACE_TYPE) 3 -#define ACPI_ADR_SPACE_SMBUS (ACPI_ADR_SPACE_TYPE) 4 -#define ACPI_ADR_SPACE_CMOS (ACPI_ADR_SPACE_TYPE) 5 -#define ACPI_ADR_SPACE_PCI_BAR_TARGET (ACPI_ADR_SPACE_TYPE) 6 - - -/* - * External ACPI object definition - */ - -typedef union acpi_obj -{ - acpi_object_type type; /* See definition of Acpi_ns_type for values */ - struct - { - acpi_object_type type; - acpi_integer value; /* The actual number */ - } integer; - - struct - { - acpi_object_type type; - u32 length; /* # of bytes in string, excluding trailing null */ - NATIVE_CHAR *pointer; /* points to the string value */ - } string; - - struct - { - acpi_object_type type; - u32 length; /* # of bytes in buffer */ - u8 *pointer; /* points to the buffer */ - } buffer; - - struct - { - acpi_object_type type; - u32 fill1; - acpi_handle handle; /* object reference */ - } reference; - - struct - { - acpi_object_type type; - u32 count; /* # of elements in package */ - union acpi_obj *elements; /* Pointer to an array of ACPI_OBJECTs */ - } package; - - struct - { - acpi_object_type type; - u32 proc_id; - ACPI_IO_ADDRESS pblk_address; - u32 pblk_length; - } processor; - - struct - { - acpi_object_type type; - u32 system_level; - u32 resource_order; - } power_resource; - -} acpi_object, *PACPI_OBJECT; - - -/* - * List of objects, used as a parameter list for control method evaluation - */ - -typedef struct acpi_obj_list -{ - u32 count; - acpi_object *pointer; - -} acpi_object_list, *PACPI_OBJECT_LIST; - - -/* - * Miscellaneous common Data Structures used by the interfaces - */ - -typedef struct -{ - u32 length; /* Length in bytes of the buffer */ - void *pointer; /* pointer to buffer */ - -} acpi_buffer; - - -/* - * Name_type for Acpi_get_name - */ - -#define ACPI_FULL_PATHNAME 0 -#define ACPI_SINGLE_NAME 1 -#define ACPI_NAME_TYPE_MAX 1 - - -/* - * Structure and flags for Acpi_get_system_info - */ - -#define SYS_MODE_UNKNOWN 0x0000 -#define SYS_MODE_ACPI 0x0001 -#define SYS_MODE_LEGACY 0x0002 -#define SYS_MODES_MASK 0x0003 - - -/* - * ACPI Table Info. One per ACPI table _type_ - */ -typedef struct acpi_table_info -{ - u32 count; - -} acpi_table_info; - - -/* - * System info returned by Acpi_get_system_info() - */ - -typedef struct _acpi_sys_info -{ - u32 acpi_ca_version; - u32 flags; - u32 timer_resolution; - u32 reserved1; - u32 reserved2; - u32 debug_level; - u32 debug_layer; - u32 num_table_types; - acpi_table_info table_info [NUM_ACPI_TABLES]; - -} acpi_system_info; - - -/* - * Various handlers and callback procedures - */ - -typedef -u32 (*acpi_event_handler) ( - void *context); - -typedef -void (*acpi_gpe_handler) ( - void *context); - -typedef -void (*acpi_notify_handler) ( - acpi_handle device, - u32 value, - void *context); - - -/* Address Spaces (Operation Regions */ - -#define ACPI_READ_ADR_SPACE 1 -#define ACPI_WRITE_ADR_SPACE 2 - -typedef -acpi_status (*acpi_adr_space_handler) ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context); - -#define ACPI_DEFAULT_HANDLER ((acpi_adr_space_handler) NULL) - - -typedef -acpi_status (*acpi_adr_space_setup) ( - acpi_handle region_handle, - u32 function, - void *handler_context, - void **region_context); - -#define ACPI_REGION_ACTIVATE 0 -#define ACPI_REGION_DEACTIVATE 1 - -typedef -acpi_status (*acpi_walk_callback) ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - - -/* Interrupt handler return values */ - -#define INTERRUPT_NOT_HANDLED 0x00 -#define INTERRUPT_HANDLED 0x01 - - -/* Structure and flags for Acpi_get_device_info */ - -#define ACPI_VALID_HID 0x1 -#define ACPI_VALID_UID 0x2 -#define ACPI_VALID_ADR 0x4 -#define ACPI_VALID_STA 0x8 - - -#define ACPI_COMMON_OBJ_INFO \ - acpi_object_type type; /* ACPI object type */ \ - acpi_name name /* ACPI object Name */ - - -typedef struct -{ - ACPI_COMMON_OBJ_INFO; -} acpi_obj_info_header; - - -typedef struct -{ - ACPI_COMMON_OBJ_INFO; - - u32 valid; /* Are the next bits legit? */ - NATIVE_CHAR hardware_id[9]; /* _HID value if any */ - NATIVE_CHAR unique_id[9]; /* _UID value if any */ - acpi_integer address; /* _ADR value if any */ - u32 current_status; /* _STA value */ -} acpi_device_info; - - -/* Context structs for address space handlers */ - -typedef struct -{ - u16 segment; - u16 bus; - u16 device; - u16 function; -} acpi_pci_id; - - -typedef struct -{ - ACPI_PHYSICAL_ADDRESS mapped_physical_address; - u8 *mapped_logical_address; - u32 mapped_length; -} acpi_mem_space_context; - - -/* Sleep states */ - -#define ACPI_NUM_SLEEP_STATES 7 - - -/* - * Definitions for Resource Attributes - */ - -/* - * Memory Attributes - */ -#define READ_ONLY_MEMORY (u8) 0x00 -#define READ_WRITE_MEMORY (u8) 0x01 - -#define NON_CACHEABLE_MEMORY (u8) 0x00 -#define CACHABLE_MEMORY (u8) 0x01 -#define WRITE_COMBINING_MEMORY (u8) 0x02 -#define PREFETCHABLE_MEMORY (u8) 0x03 - -/* - * IO Attributes - * The ISA IO ranges are: n000-n0FFh, n400-n4_fFh, n800-n8_fFh, n_c00-n_cFFh. - * The non-ISA IO ranges are: n100-n3_fFh, n500-n7_fFh, n900-n_bFFh, n_cD0-n_fFFh. - */ -#define NON_ISA_ONLY_RANGES (u8) 0x01 -#define ISA_ONLY_RANGES (u8) 0x02 -#define ENTIRE_RANGE (NON_ISA_ONLY_RANGES | ISA_ONLY_RANGES) - -/* - * IO Port Descriptor Decode - */ -#define DECODE_10 (u8) 0x00 /* 10-bit IO address decode */ -#define DECODE_16 (u8) 0x01 /* 16-bit IO address decode */ - -/* - * IRQ Attributes - */ -#define EDGE_SENSITIVE (u8) 0x00 -#define LEVEL_SENSITIVE (u8) 0x01 - -#define ACTIVE_HIGH (u8) 0x00 -#define ACTIVE_LOW (u8) 0x01 - -#define EXCLUSIVE (u8) 0x00 -#define SHARED (u8) 0x01 - -/* - * DMA Attributes - */ -#define COMPATIBILITY (u8) 0x00 -#define TYPE_A (u8) 0x01 -#define TYPE_B (u8) 0x02 -#define TYPE_F (u8) 0x03 - -#define NOT_BUS_MASTER (u8) 0x00 -#define BUS_MASTER (u8) 0x01 - -#define TRANSFER_8 (u8) 0x00 -#define TRANSFER_8_16 (u8) 0x01 -#define TRANSFER_16 (u8) 0x02 - -/* - * Start Dependent Functions Priority definitions - */ -#define GOOD_CONFIGURATION (u8) 0x00 -#define ACCEPTABLE_CONFIGURATION (u8) 0x01 -#define SUB_OPTIMAL_CONFIGURATION (u8) 0x02 - -/* - * 16, 32 and 64-bit Address Descriptor resource types - */ -#define MEMORY_RANGE (u8) 0x00 -#define IO_RANGE (u8) 0x01 -#define BUS_NUMBER_RANGE (u8) 0x02 - -#define ADDRESS_NOT_FIXED (u8) 0x00 -#define ADDRESS_FIXED (u8) 0x01 - -#define POS_DECODE (u8) 0x00 -#define SUB_DECODE (u8) 0x01 - -#define PRODUCER (u8) 0x00 -#define CONSUMER (u8) 0x01 - - -/* - * Structures used to describe device resources - */ -typedef struct -{ - u32 edge_level; - u32 active_high_low; - u32 shared_exclusive; - u32 number_of_interrupts; - u32 interrupts[1]; - -} acpi_resource_irq; - -typedef struct -{ - u32 type; - u32 bus_master; - u32 transfer; - u32 number_of_channels; - u32 channels[1]; - -} acpi_resource_dma; - -typedef struct -{ - u32 compatibility_priority; - u32 performance_robustness; - -} acpi_resource_start_dpf; - -/* - * END_DEPENDENT_FUNCTIONS_RESOURCE struct is not - * needed because it has no fields - */ - -typedef struct -{ - u32 io_decode; - u32 min_base_address; - u32 max_base_address; - u32 alignment; - u32 range_length; - -} acpi_resource_io; - -typedef struct -{ - u32 base_address; - u32 range_length; - -} acpi_resource_fixed_io; - -typedef struct -{ - u32 length; - u8 reserved[1]; - -} acpi_resource_vendor; - -typedef struct -{ - u32 read_write_attribute; - u32 min_base_address; - u32 max_base_address; - u32 alignment; - u32 range_length; - -} acpi_resource_mem24; - -typedef struct -{ - u32 read_write_attribute; - u32 min_base_address; - u32 max_base_address; - u32 alignment; - u32 range_length; - -} acpi_resource_mem32; - -typedef struct -{ - u32 read_write_attribute; - u32 range_base_address; - u32 range_length; - -} acpi_resource_fixed_mem32; - -typedef struct -{ - u16 cache_attribute; - u16 read_write_attribute; - -} acpi_memory_attribute; - -typedef struct -{ - u16 range_attribute; - u16 reserved; - -} acpi_io_attribute; - -typedef struct -{ - u16 reserved1; - u16 reserved2; - -} acpi_bus_attribute; - -typedef union -{ - acpi_memory_attribute memory; - acpi_io_attribute io; - acpi_bus_attribute bus; - -} acpi_resource_attribute; - -typedef struct -{ - u32 index; - u32 string_length; - NATIVE_CHAR *string_ptr; - -} acpi_resource_source; - -typedef struct -{ - u32 resource_type; - u32 producer_consumer; - u32 decode; - u32 min_address_fixed; - u32 max_address_fixed; - acpi_resource_attribute attribute; - u32 granularity; - u32 min_address_range; - u32 max_address_range; - u32 address_translation_offset; - u32 address_length; - acpi_resource_source resource_source; - -} acpi_resource_address16; - -typedef struct -{ - u32 resource_type; - u32 producer_consumer; - u32 decode; - u32 min_address_fixed; - u32 max_address_fixed; - acpi_resource_attribute attribute; - u32 granularity; - u32 min_address_range; - u32 max_address_range; - u32 address_translation_offset; - u32 address_length; - acpi_resource_source resource_source; - -} acpi_resource_address32; - -typedef struct -{ - u32 resource_type; - u32 producer_consumer; - u32 decode; - u32 min_address_fixed; - u32 max_address_fixed; - acpi_resource_attribute attribute; - u64 granularity; - u64 min_address_range; - u64 max_address_range; - u64 address_translation_offset; - u64 address_length; - acpi_resource_source resource_source; - -} acpi_resource_address64; - -typedef struct -{ - u32 producer_consumer; - u32 edge_level; - u32 active_high_low; - u32 shared_exclusive; - u32 number_of_interrupts; - acpi_resource_source resource_source; - u32 interrupts[1]; - -} acpi_resource_ext_irq; - - -/* ACPI_RESOURCE_TYPEs */ - -#define ACPI_RSTYPE_IRQ 0 -#define ACPI_RSTYPE_DMA 1 -#define ACPI_RSTYPE_START_DPF 2 -#define ACPI_RSTYPE_END_DPF 3 -#define ACPI_RSTYPE_IO 4 -#define ACPI_RSTYPE_FIXED_IO 5 -#define ACPI_RSTYPE_VENDOR 6 -#define ACPI_RSTYPE_END_TAG 7 -#define ACPI_RSTYPE_MEM24 8 -#define ACPI_RSTYPE_MEM32 9 -#define ACPI_RSTYPE_FIXED_MEM32 10 -#define ACPI_RSTYPE_ADDRESS16 11 -#define ACPI_RSTYPE_ADDRESS32 12 -#define ACPI_RSTYPE_ADDRESS64 13 -#define ACPI_RSTYPE_EXT_IRQ 14 - -typedef u32 acpi_resource_type; - -typedef union -{ - acpi_resource_irq irq; - acpi_resource_dma dma; - acpi_resource_start_dpf start_dpf; - acpi_resource_io io; - acpi_resource_fixed_io fixed_io; - acpi_resource_vendor vendor_specific; - acpi_resource_mem24 memory24; - acpi_resource_mem32 memory32; - acpi_resource_fixed_mem32 fixed_memory32; - acpi_resource_address16 address16; - acpi_resource_address32 address32; - acpi_resource_address64 address64; - acpi_resource_ext_irq extended_irq; - -} acpi_resource_data; - -typedef struct acpi_resource -{ - acpi_resource_type id; - u32 length; - acpi_resource_data data; - -} acpi_resource; - -#define ACPI_RESOURCE_LENGTH 12 -#define ACPI_RESOURCE_LENGTH_NO_DATA 8 /* Id + Length fields */ - -#define SIZEOF_RESOURCE(type) (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type)) - -#define NEXT_RESOURCE(res) (acpi_resource *)((u8 *) res + res->length) - - -/* - * END: Definitions for Resource Attributes - */ - - -typedef struct pci_routing_table -{ - u32 length; - u32 pin; - acpi_integer address; /* here for 64-bit alignment */ - u32 source_index; - NATIVE_CHAR source[4]; /* pad to 64 bits so sizeof() works in all cases */ - -} pci_routing_table; - - -/* - * END: Definitions for PCI Routing tables - */ - -#endif /* __ACTYPES_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/acutils.h linux-2.4.22/drivers/acpi/include/acutils.h --- linux-2.4.21/drivers/acpi/include/acutils.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/acutils.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,662 +0,0 @@ -/****************************************************************************** - * - * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 117 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 _ACUTILS_H -#define _ACUTILS_H - - -typedef -acpi_status (*ACPI_PKG_CALLBACK) ( - u8 object_type, - acpi_operand_object *source_object, - acpi_generic_state *state, - void *context); - - -acpi_status -acpi_ut_walk_package_tree ( - acpi_operand_object *source_object, - void *target_object, - ACPI_PKG_CALLBACK walk_callback, - void *context); - - -typedef struct acpi_pkg_info -{ - u8 *free_space; - u32 length; - u32 object_space; - u32 num_packages; -} acpi_pkg_info; - -#define REF_INCREMENT (u16) 0 -#define REF_DECREMENT (u16) 1 -#define REF_FORCE_DELETE (u16) 2 - -/* Acpi_ut_dump_buffer */ - -#define DB_BYTE_DISPLAY 1 -#define DB_WORD_DISPLAY 2 -#define DB_DWORD_DISPLAY 4 -#define DB_QWORD_DISPLAY 8 - - -/* Global initialization interfaces */ - -void -acpi_ut_init_globals ( - void); - -void -acpi_ut_terminate ( - void); - - -/* - * Ut_init - miscellaneous initialization and shutdown - */ - -acpi_status -acpi_ut_hardware_initialize ( - void); - -acpi_status -acpi_ut_subsystem_shutdown ( - void); - -acpi_status -acpi_ut_validate_fadt ( - void); - -/* - * Ut_global - Global data structures and procedures - */ - -#ifdef ACPI_DEBUG - -NATIVE_CHAR * -acpi_ut_get_mutex_name ( - u32 mutex_id); - -NATIVE_CHAR * -acpi_ut_get_type_name ( - u32 type); - -NATIVE_CHAR * -acpi_ut_get_region_name ( - u8 space_id); - -#endif - - -u8 -acpi_ut_hex_to_ascii_char ( - acpi_integer integer, - u32 position); - -u8 -acpi_ut_valid_object_type ( - u32 type); - -acpi_owner_id -acpi_ut_allocate_owner_id ( - u32 id_type); - - -/* - * Ut_clib - Local implementations of C library functions - */ - -#ifndef ACPI_USE_SYSTEM_CLIBRARY - -u32 -acpi_ut_strlen ( - const NATIVE_CHAR *string); - -NATIVE_CHAR * -acpi_ut_strcpy ( - NATIVE_CHAR *dst_string, - const NATIVE_CHAR *src_string); - -NATIVE_CHAR * -acpi_ut_strncpy ( - NATIVE_CHAR *dst_string, - const NATIVE_CHAR *src_string, - NATIVE_UINT count); - -u32 -acpi_ut_strncmp ( - const NATIVE_CHAR *string1, - const NATIVE_CHAR *string2, - NATIVE_UINT count); - -u32 -acpi_ut_strcmp ( - const NATIVE_CHAR *string1, - const NATIVE_CHAR *string2); - -NATIVE_CHAR * -acpi_ut_strcat ( - NATIVE_CHAR *dst_string, - const NATIVE_CHAR *src_string); - -NATIVE_CHAR * -acpi_ut_strncat ( - NATIVE_CHAR *dst_string, - const NATIVE_CHAR *src_string, - NATIVE_UINT count); - -u32 -acpi_ut_strtoul ( - const NATIVE_CHAR *string, - NATIVE_CHAR **terminator, - u32 base); - -NATIVE_CHAR * -acpi_ut_strstr ( - NATIVE_CHAR *string1, - NATIVE_CHAR *string2); - -void * -acpi_ut_memcpy ( - void *dest, - const void *src, - NATIVE_UINT count); - -void * -acpi_ut_memset ( - void *dest, - NATIVE_UINT value, - NATIVE_UINT count); - -u32 -acpi_ut_to_upper ( - u32 c); - -u32 -acpi_ut_to_lower ( - u32 c); - -#endif /* ACPI_USE_SYSTEM_CLIBRARY */ - -/* - * Ut_copy - Object construction and conversion interfaces - */ - -acpi_status -acpi_ut_build_simple_object( - acpi_operand_object *obj, - acpi_object *user_obj, - u8 *data_space, - u32 *buffer_space_used); - -acpi_status -acpi_ut_build_package_object ( - acpi_operand_object *obj, - u8 *buffer, - u32 *space_used); - -acpi_status -acpi_ut_copy_iobject_to_eobject ( - acpi_operand_object *obj, - acpi_buffer *ret_buffer); - -acpi_status -acpi_ut_copy_esimple_to_isimple( - acpi_object *user_obj, - acpi_operand_object **return_obj); - -acpi_status -acpi_ut_copy_eobject_to_iobject ( - acpi_object *obj, - acpi_operand_object **internal_obj); - -acpi_status -acpi_ut_copy_isimple_to_isimple ( - acpi_operand_object *source_obj, - acpi_operand_object *dest_obj); - -acpi_status -acpi_ut_copy_ipackage_to_ipackage ( - acpi_operand_object *source_obj, - acpi_operand_object *dest_obj, - acpi_walk_state *walk_state); - - -/* - * Ut_create - Object creation - */ - -acpi_status -acpi_ut_update_object_reference ( - acpi_operand_object *object, - u16 action); - - -/* - * Ut_debug - Debug interfaces - */ - -void -acpi_ut_init_stack_ptr_trace ( - void); - -void -acpi_ut_track_stack_ptr ( - void); - -void -acpi_ut_trace ( - u32 line_number, - acpi_debug_print_info *dbg_info); - -void -acpi_ut_trace_ptr ( - u32 line_number, - acpi_debug_print_info *dbg_info, - void *pointer); - -void -acpi_ut_trace_u32 ( - u32 line_number, - acpi_debug_print_info *dbg_info, - u32 integer); - -void -acpi_ut_trace_str ( - u32 line_number, - acpi_debug_print_info *dbg_info, - NATIVE_CHAR *string); - -void -acpi_ut_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info); - -void -acpi_ut_status_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info, - acpi_status status); - -void -acpi_ut_value_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info, - acpi_integer value); - -void -acpi_ut_ptr_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info, - u8 *ptr); - -void -acpi_ut_report_info ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id); - -void -acpi_ut_report_error ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id); - -void -acpi_ut_report_warning ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id); - -void -acpi_ut_dump_buffer ( - u8 *buffer, - u32 count, - u32 display, - u32 component_id); - -void -acpi_ut_debug_print ( - u32 requested_debug_level, - u32 line_number, - acpi_debug_print_info *dbg_info, - char *format, - ...) ACPI_PRINTF_LIKE_FUNC; - -void -acpi_ut_debug_print_raw ( - u32 requested_debug_level, - u32 line_number, - acpi_debug_print_info *dbg_info, - char *format, - ...) ACPI_PRINTF_LIKE_FUNC; - - -/* - * Ut_delete - Object deletion - */ - -void -acpi_ut_delete_internal_obj ( - acpi_operand_object *object); - -void -acpi_ut_delete_internal_package_object ( - acpi_operand_object *object); - -void -acpi_ut_delete_internal_simple_object ( - acpi_operand_object *object); - -acpi_status -acpi_ut_delete_internal_object_list ( - acpi_operand_object **obj_list); - - -/* - * Ut_eval - object evaluation - */ - -/* Method name strings */ - -#define METHOD_NAME__HID "_HID" -#define METHOD_NAME__UID "_UID" -#define METHOD_NAME__ADR "_ADR" -#define METHOD_NAME__STA "_STA" -#define METHOD_NAME__REG "_REG" -#define METHOD_NAME__SEG "_SEG" -#define METHOD_NAME__BBN "_BBN" -#define METHOD_NAME__PRT "_PRT" - - -acpi_status -acpi_ut_evaluate_numeric_object ( - NATIVE_CHAR *object_name, - acpi_namespace_node *device_node, - acpi_integer *address); - -acpi_status -acpi_ut_execute_HID ( - acpi_namespace_node *device_node, - acpi_device_id *hid); - -acpi_status -acpi_ut_execute_STA ( - acpi_namespace_node *device_node, - u32 *status_flags); - -acpi_status -acpi_ut_execute_UID ( - acpi_namespace_node *device_node, - acpi_device_id *uid); - - -/* - * Ut_mutex - mutual exclusion interfaces - */ - -acpi_status -acpi_ut_mutex_initialize ( - void); - -void -acpi_ut_mutex_terminate ( - void); - -acpi_status -acpi_ut_create_mutex ( - ACPI_MUTEX_HANDLE mutex_id); - -acpi_status -acpi_ut_delete_mutex ( - ACPI_MUTEX_HANDLE mutex_id); - -acpi_status -acpi_ut_acquire_mutex ( - ACPI_MUTEX_HANDLE mutex_id); - -acpi_status -acpi_ut_release_mutex ( - ACPI_MUTEX_HANDLE mutex_id); - - -/* - * Ut_object - internal object create/delete/cache routines - */ - -acpi_operand_object * -acpi_ut_create_internal_object_dbg ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id, - acpi_object_type8 type); - -void * -acpi_ut_allocate_object_desc_dbg ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id); - -#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_THIS_MODULE,__LINE__,_COMPONENT,t) -#define acpi_ut_allocate_object_desc() acpi_ut_allocate_object_desc_dbg (_THIS_MODULE,__LINE__,_COMPONENT) - -void -acpi_ut_delete_object_desc ( - acpi_operand_object *object); - -u8 -acpi_ut_valid_internal_object ( - void *object); - - -/* - * Ut_ref_cnt - Object reference count management - */ - -void -acpi_ut_add_reference ( - acpi_operand_object *object); - -void -acpi_ut_remove_reference ( - acpi_operand_object *object); - -/* - * Ut_size - Object size routines - */ - -acpi_status -acpi_ut_get_simple_object_size ( - acpi_operand_object *obj, - u32 *obj_length); - -acpi_status -acpi_ut_get_package_object_size ( - acpi_operand_object *obj, - u32 *obj_length); - -acpi_status -acpi_ut_get_object_size( - acpi_operand_object *obj, - u32 *obj_length); - - -/* - * Ut_state - Generic state creation/cache routines - */ - -void -acpi_ut_push_generic_state ( - acpi_generic_state **list_head, - acpi_generic_state *state); - -acpi_generic_state * -acpi_ut_pop_generic_state ( - acpi_generic_state **list_head); - - -acpi_generic_state * -acpi_ut_create_generic_state ( - void); - -acpi_generic_state * -acpi_ut_create_update_state ( - acpi_operand_object *object, - u16 action); - -acpi_generic_state * -acpi_ut_create_pkg_state ( - void *internal_object, - void *external_object, - u16 index); - -acpi_status -acpi_ut_create_update_state_and_push ( - acpi_operand_object *object, - u16 action, - acpi_generic_state **state_list); - -acpi_status -acpi_ut_create_pkg_state_and_push ( - void *internal_object, - void *external_object, - u16 index, - acpi_generic_state **state_list); - -acpi_generic_state * -acpi_ut_create_control_state ( - void); - -void -acpi_ut_delete_generic_state ( - acpi_generic_state *state); - -void -acpi_ut_delete_generic_state_cache ( - void); - -void -acpi_ut_delete_object_cache ( - void); - -/* - * utmisc - */ - -acpi_status -acpi_ut_divide ( - acpi_integer *in_dividend, - acpi_integer *in_divisor, - acpi_integer *out_quotient, - acpi_integer *out_remainder); - -acpi_status -acpi_ut_short_divide ( - acpi_integer *in_dividend, - u32 divisor, - acpi_integer *out_quotient, - u32 *out_remainder); - -u8 -acpi_ut_valid_acpi_name ( - u32 name); - -u8 -acpi_ut_valid_acpi_character ( - NATIVE_CHAR character); - -NATIVE_CHAR * -acpi_ut_strupr ( - NATIVE_CHAR *src_string); - -acpi_status -acpi_ut_resolve_package_references ( - acpi_operand_object *obj_desc); - - -#ifdef ACPI_DEBUG -void -acpi_ut_display_init_pathname ( - acpi_handle obj_handle, - char *path); - -#endif - - -/* - * Utalloc - memory allocation and object caching - */ - -void * -acpi_ut_acquire_from_cache ( - u32 list_id); - -void -acpi_ut_release_to_cache ( - u32 list_id, - void *object); - -void -acpi_ut_delete_generic_cache ( - u32 list_id); - - -/* Debug Memory allocation functions */ - -void * -acpi_ut_allocate ( - u32 size, - u32 component, - NATIVE_CHAR *module, - u32 line); - -void * -acpi_ut_callocate ( - u32 size, - u32 component, - NATIVE_CHAR *module, - u32 line); - -void -acpi_ut_free ( - void *address, - u32 component, - NATIVE_CHAR *module, - u32 line); - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS -void -acpi_ut_dump_allocation_info ( - void); - -void -acpi_ut_dump_allocations ( - u32 component, - NATIVE_CHAR *module); -#endif - - -#endif /* _ACUTILS_H */ diff -urN linux-2.4.21/drivers/acpi/include/amlcode.h linux-2.4.22/drivers/acpi/include/amlcode.h --- linux-2.4.21/drivers/acpi/include/amlcode.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/amlcode.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,459 +0,0 @@ -/****************************************************************************** - * - * Name: amlcode.h - Definitions for AML, as included in "definition blocks" - * Declarations and definitions contained herein are derived - * directly from the ACPI specification. - * $Revision: 58 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __AMLCODE_H__ -#define __AMLCODE_H__ - - -/* primary opcodes */ - -#define AML_NULL_CHAR (u16) 0x00 - -#define AML_ZERO_OP (u16) 0x00 -#define AML_ONE_OP (u16) 0x01 -#define AML_UNASSIGNED (u16) 0x02 -#define AML_ALIAS_OP (u16) 0x06 -#define AML_NAME_OP (u16) 0x08 -#define AML_BYTE_OP (u16) 0x0a -#define AML_WORD_OP (u16) 0x0b -#define AML_DWORD_OP (u16) 0x0c -#define AML_STRING_OP (u16) 0x0d -#define AML_QWORD_OP (u16) 0x0e /* ACPI 2.0 */ -#define AML_SCOPE_OP (u16) 0x10 -#define AML_BUFFER_OP (u16) 0x11 -#define AML_PACKAGE_OP (u16) 0x12 -#define AML_VAR_PACKAGE_OP (u16) 0x13 /* ACPI 2.0 */ -#define AML_METHOD_OP (u16) 0x14 -#define AML_DUAL_NAME_PREFIX (u16) 0x2e -#define AML_MULTI_NAME_PREFIX_OP (u16) 0x2f -#define AML_NAME_CHAR_SUBSEQ (u16) 0x30 -#define AML_NAME_CHAR_FIRST (u16) 0x41 -#define AML_OP_PREFIX (u16) 0x5b -#define AML_ROOT_PREFIX (u16) 0x5c -#define AML_PARENT_PREFIX (u16) 0x5e -#define AML_LOCAL_OP (u16) 0x60 -#define AML_LOCAL0 (u16) 0x60 -#define AML_LOCAL1 (u16) 0x61 -#define AML_LOCAL2 (u16) 0x62 -#define AML_LOCAL3 (u16) 0x63 -#define AML_LOCAL4 (u16) 0x64 -#define AML_LOCAL5 (u16) 0x65 -#define AML_LOCAL6 (u16) 0x66 -#define AML_LOCAL7 (u16) 0x67 -#define AML_ARG_OP (u16) 0x68 -#define AML_ARG0 (u16) 0x68 -#define AML_ARG1 (u16) 0x69 -#define AML_ARG2 (u16) 0x6a -#define AML_ARG3 (u16) 0x6b -#define AML_ARG4 (u16) 0x6c -#define AML_ARG5 (u16) 0x6d -#define AML_ARG6 (u16) 0x6e -#define AML_STORE_OP (u16) 0x70 -#define AML_REF_OF_OP (u16) 0x71 -#define AML_ADD_OP (u16) 0x72 -#define AML_CONCAT_OP (u16) 0x73 -#define AML_SUBTRACT_OP (u16) 0x74 -#define AML_INCREMENT_OP (u16) 0x75 -#define AML_DECREMENT_OP (u16) 0x76 -#define AML_MULTIPLY_OP (u16) 0x77 -#define AML_DIVIDE_OP (u16) 0x78 -#define AML_SHIFT_LEFT_OP (u16) 0x79 -#define AML_SHIFT_RIGHT_OP (u16) 0x7a -#define AML_BIT_AND_OP (u16) 0x7b -#define AML_BIT_NAND_OP (u16) 0x7c -#define AML_BIT_OR_OP (u16) 0x7d -#define AML_BIT_NOR_OP (u16) 0x7e -#define AML_BIT_XOR_OP (u16) 0x7f -#define AML_BIT_NOT_OP (u16) 0x80 -#define AML_FIND_SET_LEFT_BIT_OP (u16) 0x81 -#define AML_FIND_SET_RIGHT_BIT_OP (u16) 0x82 -#define AML_DEREF_OF_OP (u16) 0x83 -#define AML_CONCAT_RES_OP (u16) 0x84 /* ACPI 2.0 */ -#define AML_MOD_OP (u16) 0x85 /* ACPI 2.0 */ -#define AML_NOTIFY_OP (u16) 0x86 -#define AML_SIZE_OF_OP (u16) 0x87 -#define AML_INDEX_OP (u16) 0x88 -#define AML_MATCH_OP (u16) 0x89 -#define AML_CREATE_DWORD_FIELD_OP (u16) 0x8a -#define AML_CREATE_WORD_FIELD_OP (u16) 0x8b -#define AML_CREATE_BYTE_FIELD_OP (u16) 0x8c -#define AML_CREATE_BIT_FIELD_OP (u16) 0x8d -#define AML_TYPE_OP (u16) 0x8e -#define AML_CREATE_QWORD_FIELD_OP (u16) 0x8f /* ACPI 2.0 */ -#define AML_LAND_OP (u16) 0x90 -#define AML_LOR_OP (u16) 0x91 -#define AML_LNOT_OP (u16) 0x92 -#define AML_LEQUAL_OP (u16) 0x93 -#define AML_LGREATER_OP (u16) 0x94 -#define AML_LLESS_OP (u16) 0x95 -#define AML_TO_BUFFER_OP (u16) 0x96 /* ACPI 2.0 */ -#define AML_TO_DECSTRING_OP (u16) 0x97 /* ACPI 2.0 */ -#define AML_TO_HEXSTRING_OP (u16) 0x98 /* ACPI 2.0 */ -#define AML_TO_INTEGER_OP (u16) 0x99 /* ACPI 2.0 */ -#define AML_TO_STRING_OP (u16) 0x9c /* ACPI 2.0 */ -#define AML_COPY_OP (u16) 0x9d /* ACPI 2.0 */ -#define AML_MID_OP (u16) 0x9e /* ACPI 2.0 */ -#define AML_CONTINUE_OP (u16) 0x9f /* ACPI 2.0 */ -#define AML_IF_OP (u16) 0xa0 -#define AML_ELSE_OP (u16) 0xa1 -#define AML_WHILE_OP (u16) 0xa2 -#define AML_NOOP_OP (u16) 0xa3 -#define AML_RETURN_OP (u16) 0xa4 -#define AML_BREAK_OP (u16) 0xa5 -#define AML_BREAK_POINT_OP (u16) 0xcc -#define AML_ONES_OP (u16) 0xff - -/* prefixed opcodes */ - -#define AML_EXTOP (u16) 0x005b - - -#define AML_MUTEX_OP (u16) 0x5b01 -#define AML_EVENT_OP (u16) 0x5b02 -#define AML_SHIFT_RIGHT_BIT_OP (u16) 0x5b10 -#define AML_SHIFT_LEFT_BIT_OP (u16) 0x5b11 -#define AML_COND_REF_OF_OP (u16) 0x5b12 -#define AML_CREATE_FIELD_OP (u16) 0x5b13 -#define AML_LOAD_TABLE_OP (u16) 0x5b1f /* ACPI 2.0 */ -#define AML_LOAD_OP (u16) 0x5b20 -#define AML_STALL_OP (u16) 0x5b21 -#define AML_SLEEP_OP (u16) 0x5b22 -#define AML_ACQUIRE_OP (u16) 0x5b23 -#define AML_SIGNAL_OP (u16) 0x5b24 -#define AML_WAIT_OP (u16) 0x5b25 -#define AML_RESET_OP (u16) 0x5b26 -#define AML_RELEASE_OP (u16) 0x5b27 -#define AML_FROM_BCD_OP (u16) 0x5b28 -#define AML_TO_BCD_OP (u16) 0x5b29 -#define AML_UNLOAD_OP (u16) 0x5b2a -#define AML_REVISION_OP (u16) 0x5b30 -#define AML_DEBUG_OP (u16) 0x5b31 -#define AML_FATAL_OP (u16) 0x5b32 -#define AML_REGION_OP (u16) 0x5b80 -#define AML_FIELD_OP (u16) 0x5b81 -#define AML_DEVICE_OP (u16) 0x5b82 -#define AML_PROCESSOR_OP (u16) 0x5b83 -#define AML_POWER_RES_OP (u16) 0x5b84 -#define AML_THERMAL_ZONE_OP (u16) 0x5b85 -#define AML_INDEX_FIELD_OP (u16) 0x5b86 -#define AML_BANK_FIELD_OP (u16) 0x5b87 -#define AML_DATA_REGION_OP (u16) 0x5b88 /* ACPI 2.0 */ - - -/* Bogus opcodes (they are actually two separate opcodes) */ - -#define AML_LGREATEREQUAL_OP (u16) 0x9295 -#define AML_LLESSEQUAL_OP (u16) 0x9294 -#define AML_LNOTEQUAL_OP (u16) 0x9293 - - -/* - * Internal opcodes - * Use only "Unknown" AML opcodes, don't attempt to use - * any valid ACPI ASCII values (A-Z, 0-9, '-') - */ - -#define AML_INT_NAMEPATH_OP (u16) 0x002d -#define AML_INT_NAMEDFIELD_OP (u16) 0x0030 -#define AML_INT_RESERVEDFIELD_OP (u16) 0x0031 -#define AML_INT_ACCESSFIELD_OP (u16) 0x0032 -#define AML_INT_BYTELIST_OP (u16) 0x0033 -#define AML_INT_STATICSTRING_OP (u16) 0x0034 -#define AML_INT_METHODCALL_OP (u16) 0x0035 -#define AML_INT_RETURN_VALUE_OP (u16) 0x0036 - - -#define ARG_NONE 0x0 - -/* - * Argument types for the AML Parser - * Each field in the Arg_types u32 is 5 bits, allowing for a maximum of 6 arguments. - * There can be up to 31 unique argument types - */ - -#define ARGP_BYTEDATA 0x01 -#define ARGP_BYTELIST 0x02 -#define ARGP_CHARLIST 0x03 -#define ARGP_DATAOBJ 0x04 -#define ARGP_DATAOBJLIST 0x05 -#define ARGP_DWORDDATA 0x06 -#define ARGP_FIELDLIST 0x07 -#define ARGP_NAME 0x08 -#define ARGP_NAMESTRING 0x09 -#define ARGP_OBJLIST 0x0A -#define ARGP_PKGLENGTH 0x0B -#define ARGP_SUPERNAME 0x0C -#define ARGP_TARGET 0x0D -#define ARGP_TERMARG 0x0E -#define ARGP_TERMLIST 0x0F -#define ARGP_WORDDATA 0x10 -#define ARGP_QWORDDATA 0x11 -#define ARGP_SIMPLENAME 0x12 - -/* - * Resolved argument types for the AML Interpreter - * Each field in the Arg_types u32 is 5 bits, allowing for a maximum of 6 arguments. - * There can be up to 31 unique argument types (0 is end-of-arg-list indicator) - */ - -/* "Standard" ACPI types are 1-15 (0x0F) */ - -#define ARGI_INTEGER ACPI_TYPE_INTEGER /* 1 */ -#define ARGI_STRING ACPI_TYPE_STRING /* 2 */ -#define ARGI_BUFFER ACPI_TYPE_BUFFER /* 3 */ -#define ARGI_PACKAGE ACPI_TYPE_PACKAGE /* 4 */ -#define ARGI_EVENT ACPI_TYPE_EVENT -#define ARGI_MUTEX ACPI_TYPE_MUTEX -#define ARGI_REGION ACPI_TYPE_REGION -#define ARGI_DDBHANDLE ACPI_TYPE_DDB_HANDLE - -/* Custom types are 0x10 through 0x1F */ - -#define ARGI_IF 0x10 -#define ARGI_ANYOBJECT 0x11 -#define ARGI_ANYTYPE 0x12 -#define ARGI_COMPUTEDATA 0x13 /* Buffer, String, or Integer */ -#define ARGI_DATAOBJECT 0x14 /* Buffer, String, package or reference to a Node - Used only by Size_of operator*/ -#define ARGI_COMPLEXOBJ 0x15 /* Buffer, String, or package (Used by INDEX op only) */ -#define ARGI_INTEGER_REF 0x16 -#define ARGI_OBJECT_REF 0x17 -#define ARGI_DEVICE_REF 0x18 -#define ARGI_REFERENCE 0x19 -#define ARGI_TARGETREF 0x1A /* Target, subject to implicit conversion */ -#define ARGI_FIXED_TARGET 0x1B /* Target, no implicit conversion */ -#define ARGI_SIMPLE_TARGET 0x1C /* Name, Local, Arg -- no implicit conversion */ -#define ARGI_BUFFERSTRING 0x1D - -#define ARGI_INVALID_OPCODE 0xFFFFFFFF - - -/* - * hash offsets - */ -#define AML_EXTOP_HASH_OFFSET 22 -#define AML_LNOT_HASH_OFFSET 19 - - -/* - * opcode groups and types - */ - -#define OPGRP_NAMED 0x01 -#define OPGRP_FIELD 0x02 -#define OPGRP_BYTELIST 0x04 - - -/* - * Opcode information - */ - -/* Opcode flags */ - -#define AML_HAS_ARGS 0x0800 -#define AML_HAS_TARGET 0x0400 -#define AML_HAS_RETVAL 0x0200 -#define AML_NSOBJECT 0x0100 -#define AML_NSOPCODE 0x0080 -#define AML_NSNODE 0x0040 -#define AML_NAMED 0x0020 -#define AML_DEFER 0x0010 -#define AML_FIELD 0x0008 -#define AML_CREATE 0x0004 -#define AML_MATH 0x0002 -#define AML_LOGICAL 0x0001 - -/* Convenient flag groupings */ - -#define AML_FLAGS_EXEC_1A_0T_0R AML_HAS_ARGS /* Monadic1 */ -#define AML_FLAGS_EXEC_1A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Monadic2 */ -#define AML_FLAGS_EXEC_1A_1T_0R AML_HAS_ARGS | AML_HAS_TARGET -#define AML_FLAGS_EXEC_1A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* Monadic2_r */ -#define AML_FLAGS_EXEC_2A_0T_0R AML_HAS_ARGS /* Dyadic1 */ -#define AML_FLAGS_EXEC_2A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Dyadic2 */ -#define AML_FLAGS_EXEC_2A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* Dyadic2_r */ -#define AML_FLAGS_EXEC_2A_2T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL -#define AML_FLAGS_EXEC_3A_0T_0R AML_HAS_ARGS -#define AML_FLAGS_EXEC_3A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL -#define AML_FLAGS_EXEC_6A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL - - -/* - * The opcode Type is used in a dispatch table, do not change - * without updating the table. - */ -#define AML_TYPE_EXEC_1A_0T_0R 0x00 /* Monadic1 */ -#define AML_TYPE_EXEC_1A_0T_1R 0x01 /* Monadic2 */ -#define AML_TYPE_EXEC_1A_1T_0R 0x02 -#define AML_TYPE_EXEC_1A_1T_1R 0x03 /* Monadic2_r */ -#define AML_TYPE_EXEC_2A_0T_0R 0x04 /* Dyadic1 */ -#define AML_TYPE_EXEC_2A_0T_1R 0x05 /* Dyadic2 */ -#define AML_TYPE_EXEC_2A_1T_1R 0x06 /* Dyadic2_r */ -#define AML_TYPE_EXEC_2A_2T_1R 0x07 -#define AML_TYPE_EXEC_3A_0T_0R 0x08 -#define AML_TYPE_EXEC_3A_1T_1R 0x09 -#define AML_TYPE_EXEC_6A_0T_1R 0x0A -/* End of types used in dispatch table */ - -#define AML_TYPE_LITERAL 0x0B -#define AML_TYPE_CONSTANT 0x0C -#define AML_TYPE_METHOD_ARGUMENT 0x0D -#define AML_TYPE_LOCAL_VARIABLE 0x0E -#define AML_TYPE_DATA_TERM 0x0F - -/* Generic for an op that returns a value */ - -#define AML_TYPE_METHOD_CALL 0x10 - -/* Misc */ - -#define AML_TYPE_CREATE_FIELD 0x11 -#define AML_TYPE_CONTROL 0x12 -#define AML_TYPE_NAMED_NO_OBJ 0x13 -#define AML_TYPE_NAMED_FIELD 0x14 -#define AML_TYPE_NAMED_SIMPLE 0x15 -#define AML_TYPE_NAMED_COMPLEX 0x16 -#define AML_TYPE_RETURN 0x17 - -#define AML_TYPE_UNDEFINED 0x18 -#define AML_TYPE_BOGUS 0x19 - - -/* - * Opcode classes - */ -#define AML_CLASS_EXECUTE 0x00 -#define AML_CLASS_CREATE 0x01 -#define AML_CLASS_ARGUMENT 0x02 -#define AML_CLASS_NAMED_OBJECT 0x03 -#define AML_CLASS_CONTROL 0x04 -#define AML_CLASS_ASCII 0x05 -#define AML_CLASS_PREFIX 0x06 -#define AML_CLASS_INTERNAL 0x07 -#define AML_CLASS_RETURN_VALUE 0x08 -#define AML_CLASS_METHOD_CALL 0x09 -#define AML_CLASS_UNKNOWN 0x0A - - -/* Predefined Operation Region Space_iDs */ - -typedef enum -{ - REGION_MEMORY = 0, - REGION_IO, - REGION_PCI_CONFIG, - REGION_EC, - REGION_SMBUS, - REGION_CMOS, - REGION_PCI_BAR, - REGION_FIXED_HW = 0x7F, - -} AML_REGION_TYPES; - - -/* Comparison operation codes for Match_op operator */ - -typedef enum -{ - MATCH_MTR = 0, - MATCH_MEQ = 1, - MATCH_MLE = 2, - MATCH_MLT = 3, - MATCH_MGE = 4, - MATCH_MGT = 5 - -} AML_MATCH_OPERATOR; - -#define MAX_MATCH_OPERATOR 5 - - -/* Field Access Types */ - -#define ACCESS_TYPE_MASK 0x0f -#define ACCESS_TYPE_SHIFT 0 - -typedef enum -{ - ACCESS_ANY_ACC = 0, - ACCESS_BYTE_ACC = 1, - ACCESS_WORD_ACC = 2, - ACCESS_DWORD_ACC = 3, - ACCESS_QWORD_ACC = 4, /* ACPI 2.0 */ - ACCESS_BLOCK_ACC = 4, - ACCESS_SMBSEND_RECV_ACC = 5, - ACCESS_SMBQUICK_ACC = 6 - -} AML_ACCESS_TYPE; - - -/* Field Lock Rules */ - -#define LOCK_RULE_MASK 0x10 -#define LOCK_RULE_SHIFT 4 - -typedef enum -{ - GLOCK_NEVER_LOCK = 0, - GLOCK_ALWAYS_LOCK = 1 - -} AML_LOCK_RULE; - - -/* Field Update Rules */ - -#define UPDATE_RULE_MASK 0x060 -#define UPDATE_RULE_SHIFT 5 - -typedef enum -{ - UPDATE_PRESERVE = 0, - UPDATE_WRITE_AS_ONES = 1, - UPDATE_WRITE_AS_ZEROS = 2 - -} AML_UPDATE_RULE; - - -/* bit fields in Method_flags byte */ - -#define METHOD_FLAGS_ARG_COUNT 0x07 -#define METHOD_FLAGS_SERIALIZED 0x08 -#define METHOD_FLAGS_SYNCH_LEVEL 0xF0 - - -/* Array sizes. Used for range checking also */ - -#define NUM_REGION_TYPES 7 -#define NUM_ACCESS_TYPES 7 -#define NUM_UPDATE_RULES 3 -#define NUM_MATCH_OPS 7 -#define NUM_OPCODES 256 -#define NUM_FIELD_NAMES 2 - - -#define USER_REGION_BEGIN 0x80 - - -#endif /* __AMLCODE_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/platform/acenv.h linux-2.4.22/drivers/acpi/include/platform/acenv.h --- linux-2.4.21/drivers/acpi/include/platform/acenv.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/include/platform/acenv.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,294 +0,0 @@ -/****************************************************************************** - * - * Name: acenv.h - Generation environment specific items - * $Revision: 77 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACENV_H__ -#define __ACENV_H__ - - -/* - * Configuration for ACPI tools and utilities - */ - -#ifdef _ACPI_DUMP_APP -#define ACPI_DEBUG -#define ACPI_APPLICATION -#define ENABLE_DEBUGGER -#define ACPI_USE_SYSTEM_CLIBRARY -#define PARSER_ONLY -#endif - -#ifdef _ACPI_EXEC_APP -#undef DEBUGGER_THREADING -#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED -#define ACPI_DEBUG -#define ACPI_APPLICATION -#define ENABLE_DEBUGGER -#define ACPI_USE_SYSTEM_CLIBRARY -#endif - -#ifdef _ACPI_ASL_COMPILER -#define ACPI_DEBUG -#define ACPI_APPLICATION -#define ENABLE_DEBUGGER -#define ACPI_USE_SYSTEM_CLIBRARY -#endif - -/* - * Memory allocation tracking. Used only if - * 1) This is the debug version - * 2) This is NOT a 16-bit version of the code (not enough real-mode memory) - */ -#ifdef ACPI_DEBUG -#ifndef _IA16 -#define ACPI_DBG_TRACK_ALLOCATIONS -#endif -#endif - -/* - * Environment configuration. The purpose of this file is to interface to the - * local generation environment. - * - * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library. - * Otherwise, local versions of string/memory functions will be used. - * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and - * the standard header files may be used. - * - * The ACPI subsystem only uses low level C library functions that do not call - * operating system services and may therefore be inlined in the code. - * - * It may be necessary to tailor these include files to the target - * generation environment. - * - * - * Functions and constants used from each header: - * - * string.h: memcpy - * memset - * strcat - * strcmp - * strcpy - * strlen - * strncmp - * strncat - * strncpy - * - * stdlib.h: strtoul - * - * stdarg.h: va_list - * va_arg - * va_start - * va_end - * - */ - -/*! [Begin] no source code translation */ - -#ifdef _LINUX -#include "aclinux.h" - -#elif _AED_EFI -#include "acefi.h" - -#elif WIN32 -#include "acwin.h" - -#elif __FreeBSD__ -#include "acfreebsd.h" - -#else - -/* All other environments */ - -#define ACPI_USE_STANDARD_HEADERS - -/* Name of host operating system (returned by the _OS_ namespace object) */ - -#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" - -/* This macro is used to tag functions as "printf-like" because - * some compilers can catch printf format string problems. MSVC - * doesn't, so this is proprocessed away. - */ -#define ACPI_PRINTF_LIKE_FUNC - -#endif - - -/*! [End] no source code translation !*/ - -/****************************************************************************** - * - * C library configuration - * - *****************************************************************************/ - -#ifdef ACPI_USE_SYSTEM_CLIBRARY -/* - * Use the standard C library headers. - * We want to keep these to a minimum. - * - */ - -#ifdef ACPI_USE_STANDARD_HEADERS -/* - * Use the standard headers from the standard locations - */ -#include -#include -#include -#include - -#endif /* ACPI_USE_STANDARD_HEADERS */ - -/* - * We will be linking to the standard Clib functions - */ - -#define STRSTR(s1,s2) strstr((s1), (s2)) -#define STRUPR(s) acpi_ut_strupr ((s)) -#define STRLEN(s) (u32) strlen((s)) -#define STRCPY(d,s) strcpy((d), (s)) -#define STRNCPY(d,s,n) strncpy((d), (s), (NATIVE_INT)(n)) -#define STRNCMP(d,s,n) strncmp((d), (s), (NATIVE_INT)(n)) -#define STRCMP(d,s) strcmp((d), (s)) -#define STRCAT(d,s) strcat((d), (s)) -#define STRNCAT(d,s,n) strncat((d), (s), (NATIVE_INT)(n)) -#define STRTOUL(d,s,n) strtoul((d), (s), (NATIVE_INT)(n)) -#define MEMCPY(d,s,n) memcpy((d), (s), (NATIVE_INT)(n)) -#define MEMSET(d,s,n) memset((d), (s), (NATIVE_INT)(n)) -#define TOUPPER toupper -#define TOLOWER tolower -#define IS_XDIGIT isxdigit - -/****************************************************************************** - * - * Not using native C library, use local implementations - * - *****************************************************************************/ -#else - -/* - * Use local definitions of C library macros and functions - * NOTE: The function implementations may not be as efficient - * as an inline or assembly code implementation provided by a - * native C library. - */ - -#ifndef va_arg - -#ifndef _VALIST -#define _VALIST -typedef char *va_list; -#endif /* _VALIST */ - -/* - * Storage alignment properties - */ - -#define _AUPBND (sizeof (NATIVE_INT) - 1) -#define _ADNBND (sizeof (NATIVE_INT) - 1) - -/* - * Variable argument list macro definitions - */ - -#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) -#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) -#define va_end(ap) (void) 0 -#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) - -#endif /* va_arg */ - - -#define STRSTR(s1,s2) acpi_ut_strstr ((s1), (s2)) -#define STRUPR(s) acpi_ut_strupr ((s)) -#define STRLEN(s) acpi_ut_strlen ((s)) -#define STRCPY(d,s) acpi_ut_strcpy ((d), (s)) -#define STRNCPY(d,s,n) acpi_ut_strncpy ((d), (s), (n)) -#define STRNCMP(d,s,n) acpi_ut_strncmp ((d), (s), (n)) -#define STRCMP(d,s) acpi_ut_strcmp ((d), (s)) -#define STRCAT(d,s) acpi_ut_strcat ((d), (s)) -#define STRNCAT(d,s,n) acpi_ut_strncat ((d), (s), (n)) -#define STRTOUL(d,s,n) acpi_ut_strtoul ((d), (s),(n)) -#define MEMCPY(d,s,n) acpi_ut_memcpy ((d), (s), (n)) -#define MEMSET(d,v,n) acpi_ut_memset ((d), (v), (n)) -#define TOUPPER acpi_ut_to_upper -#define TOLOWER acpi_ut_to_lower - -#endif /* ACPI_USE_SYSTEM_CLIBRARY */ - - -/****************************************************************************** - * - * Assembly code macros - * - *****************************************************************************/ - -/* - * Handle platform- and compiler-specific assembly language differences. - * These should already have been defined by the platform includes above. - * - * Notes: - * 1) Interrupt 3 is used to break into a debugger - * 2) Interrupts are turned off during ACPI register setup - */ - -/* Unrecognized compiler, use defaults */ -#ifndef ACPI_ASM_MACROS - -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() -#define enable() -#define halt() -#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq) -#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq) - -#endif /* ACPI_ASM_MACROS */ - - -#ifdef ACPI_APPLICATION - -/* Don't want software interrupts within a ring3 application */ - -#undef causeinterrupt -#undef BREAKPOINT3 -#define causeinterrupt(level) -#define BREAKPOINT3 -#endif - - -/****************************************************************************** - * - * Compiler-specific - * - *****************************************************************************/ - -/* this has been moved to compiler-specific headers, which are included from the - platform header. */ - - -#endif /* __ACENV_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/platform/acgcc.h linux-2.4.22/drivers/acpi/include/platform/acgcc.h --- linux-2.4.21/drivers/acpi/include/platform/acgcc.h 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/include/platform/acgcc.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,196 +0,0 @@ -/****************************************************************************** - * - * Name: acgcc.h - GCC specific defines, etc. - * $Revision: 14 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACGCC_H__ -#define __ACGCC_H__ - - -#ifdef __ia64__ -#define _IA64 - -#define COMPILER_DEPENDENT_UINT64 unsigned long -/* Single threaded */ -#define ACPI_APPLICATION - -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() __cli() -#define enable() __sti() - -/*! [Begin] no source code translation */ - -#include - -#define halt() ia64_pal_halt_light() /* PAL_HALT[_LIGHT] */ -#define safe_halt() ia64_pal_halt(1) /* PAL_HALT */ - - -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - __asm__ volatile ("1: ld4 r29=%1\n" \ - ";;\n" \ - "mov ar.ccv=r29\n" \ - "mov r2=r29\n" \ - "shr.u r30=r29,1\n" \ - "and r29=-4,r29\n" \ - ";;\n" \ - "add r29=2,r29\n" \ - "and r30=1,r30\n" \ - ";;\n" \ - "add r29=r29,r30\n" \ - ";;\n" \ - "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ - ";;\n" \ - "cmp.eq p6,p7=r2,r30\n" \ - "(p7) br.dpnt.few 1b\n" \ - "cmp.gt p8,p9=3,r29\n" \ - ";;\n" \ - "(p8) mov %0=-1\n" \ - "(p9) mov %0=r0\n" \ - :"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \ - } while (0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - __asm__ volatile ("1: ld4 r29=%1\n" \ - ";;\n" \ - "mov ar.ccv=r29\n" \ - "mov r2=r29\n" \ - "and r29=-4,r29\n" \ - ";;\n" \ - "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ - ";;\n" \ - "cmp.eq p6,p7=r2,r30\n" \ - "(p7) br.dpnt.few 1b\n" \ - "and %0=1,r2\n" \ - ";;\n" \ - :"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \ - } while (0) -/*! [End] no source code translation !*/ - - -#elif __i386__ /* DO IA32 */ -#define COMPILER_DEPENDENT_UINT64 unsigned long long -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() __cli() -#define enable() __sti() -#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") - -/*! [Begin] no source code translation - * - * A brief explanation as GNU inline assembly is a bit hairy - * %0 is the output parameter in EAX ("=a") - * %1 and %2 are the input parameters in ECX ("c") - * and an immediate value ("i") respectively - * All actual register references are preceded with "%%" as in "%%edx" - * Immediate values in the assembly are preceded by "$" as in "$0x1" - * The final asm parameter are the operation altered non-output registers. - */ -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "btsl $0x1,%%edx;" \ - "adcl $0x0,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "cmpb $0x3,%%dl;" \ - "sbbl %%eax,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ - } while(0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "andl $0x1,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ - } while(0) -#elif __x86_64__ -#define COMPILER_DEPENDENT_UINT64 unsigned long long -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() __cli() -#define enable() __sti() -#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") - -/*! [Begin] no source code translation - * - * A brief explanation as GNU inline assembly is a bit hairy - * %0 is the output parameter in RAX ("=a") - * %1 and %2 are the input parameters in RCX ("c") - * and an immediate value ("i") respectively - * All actual register references are preceded with "%%" as in "%%edx" - * Immediate values in the assembly are preceded by "$" as in "$0x1" - * The final asm parameter are the operation altered non-output registers. - */ -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - unsigned long dummy; \ - asm("1: movl (%2),%%eax;" \ - "movl %%eax,%%edx;" \ - "andq %2,%%rdx;" \ - "btsl $0x1,%%edx;" \ - "adcl $0x0,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "cmpb $0x3,%%dl;" \ - "sbbl %%eax,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ - } while(0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - unsigned long dummy; \ - asm("1: movl (%2),%%eax;" \ - "movl %%eax,%%edx;" \ - "andq %2,%%rdx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "andl $0x1,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ - } while(0) - -/*! [End] no source code translation !*/ - -#endif - -/* This macro is used to tag functions as "printf-like" because - * some compilers (like GCC) can catch printf format string problems. - */ -#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5))) - - -#endif /* __ACGCC_H__ */ diff -urN linux-2.4.21/drivers/acpi/include/platform/aclinux.h linux-2.4.22/drivers/acpi/include/platform/aclinux.h --- linux-2.4.21/drivers/acpi/include/platform/aclinux.h 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/include/platform/aclinux.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,71 +0,0 @@ -/****************************************************************************** - * - * Name: aclinux.h - OS specific defines, etc. - * $Revision: 14 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __ACLINUX_H__ -#define __ACLINUX_H__ - -#define ACPI_OS_NAME "Linux" - -#define ACPI_USE_SYSTEM_CLIBRARY - -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include -#include -#include - -#define strtoul simple_strtoul - -#else - -#include -#include -#include -#include - -#endif - -/* Linux uses GCC */ - -#include "acgcc.h" - -#undef DEBUGGER_THREADING -#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED - -#if BITS_PER_LONG < 64 -/* Linux ia32 can't do int64 well */ -#define ACPI_NO_INTEGER64_SUPPORT -/* And the ia32 kernel doesn't include 64-bit divide support */ -#define ACPI_DIV64(dividend, divisor) do_div(dividend, divisor) -#else -#define ACPI_DIV64(dividend, divisor) ACPI_DIVIDE(dividend, divisor) -#endif - - -#endif /* __ACLINUX_H__ */ diff -urN linux-2.4.21/drivers/acpi/kdb/README.txt linux-2.4.22/drivers/acpi/kdb/README.txt --- linux-2.4.21/drivers/acpi/kdb/README.txt 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/kdb/README.txt 1969-12-31 16:00:00.000000000 -0800 @@ -1,36 +0,0 @@ -Using the ACPI debugger with kdb --------------------------------- - -ACPI CA includes a full-featured debugger, which allows the examination of -a running system's ACPI tables, as well as running and stepping through -control methods. - -Configuration -------------- -1) Edit the main acpi Makefile. On the ACPI_CFLAGS line, remove the '#', thus - enabling the debugger. - -2) Download the latest kdb patch from: - - ftp://oss.sgi.com/www/projects/kdb/download/ix86/ - - Follow the instructions at http://oss.sgi.com/projects/kdb/ on how to - install the patch and configure KDB. - -3) This would probably be a good time to recompile the kernel, and make sure - kdb works (Hitting the Pause key should drop you into it. Type "go" to exit - it. - -4) The kdb <--> ACPI debugger interface is a module. Type "make modules", and - it will be built and placed in drivers/acpi/kdb. - -5) Change to that directory and type "insmod kdbm_acpi.o". This loads the - module we just built. - -6) Break back into kdb. If you type help, you should now see "acpi" listed as - a command, at the bottom. - -7) Type "acpi". You are now in the ACPI debugger. While hosted by kdb, it is - wholly separate, and has many ACPI-specific commands. Type "?" or "help" - to get a listing of the command categories, and then "help " for - a list of commands and their descriptions diff -urN linux-2.4.21/drivers/acpi/kdb/kdbm_acpi.c linux-2.4.22/drivers/acpi/kdb/kdbm_acpi.c --- linux-2.4.21/drivers/acpi/kdb/kdbm_acpi.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/kdb/kdbm_acpi.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,54 +0,0 @@ -/* - * kdbm_acpi.c - kdb debugger module interface for ACPI debugger - * - * Copyright (C) 2000 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "acpi.h" -#include "acdebug.h" - -extern int acpi_in_debugger; - -static int -kdbm_acpi(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ - acpi_in_debugger = 1; - - acpi_db_user_commands(DB_COMMAND_PROMPT, NULL); - - acpi_in_debugger = 0; - - return 0; -} - -int -init_module(void) -{ - kdb_register("acpi", kdbm_acpi, "", "Enter ACPI debugger", 0); - - return 0; -} - -void -cleanup_module(void) -{ - kdb_unregister("acpi"); -} diff -urN linux-2.4.21/drivers/acpi/namespace/Makefile linux-2.4.22/drivers/acpi/namespace/Makefile --- linux-2.4.21/drivers/acpi/namespace/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/namespace/nsaccess.c linux-2.4.22/drivers/acpi/namespace/nsaccess.c --- linux-2.4.21/drivers/acpi/namespace/nsaccess.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsaccess.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,43 +1,60 @@ /******************************************************************************* * * Module Name: nsaccess - Top-level functions for accessing ACPI namespace - * $Revision: 135 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acdispat.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsaccess") + ACPI_MODULE_NAME ("nsaccess") /******************************************************************************* * - * FUNCTION: Acpi_ns_root_initialize + * FUNCTION: acpi_ns_root_initialize * * PARAMETERS: None * @@ -52,42 +69,44 @@ acpi_status acpi_ns_root_initialize (void) { - acpi_status status = AE_OK; - const predefined_names *init_val = NULL; - acpi_namespace_node *new_node; - acpi_operand_object *obj_desc; + acpi_status status; + const struct acpi_predefined_names *init_val = NULL; + struct acpi_namespace_node *new_node; + union acpi_operand_object *obj_desc; + acpi_string val = NULL; - FUNCTION_TRACE ("Ns_root_initialize"); + ACPI_FUNCTION_TRACE ("ns_root_initialize"); - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* * The global root ptr is initially NULL, so a non-NULL value indicates - * that Acpi_ns_root_initialize() has already been called; just return. + * that acpi_ns_root_initialize() has already been called; just return. */ if (acpi_gbl_root_node) { status = AE_OK; goto unlock_and_exit; } - /* * Tell the rest of the subsystem that the root is initialized * (This is OK because the namespace is locked) */ acpi_gbl_root_node = &acpi_gbl_root_node_struct; - /* Enter the pre-defined names in the name table */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Entering predefined entries into namespace\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Entering predefined entries into namespace\n")); for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { status = acpi_ns_lookup (NULL, init_val->name, init_val->type, - IMODE_LOAD_PASS2, NS_NO_UPSEARCH, - NULL, &new_node); + ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &new_node); if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, @@ -97,10 +116,20 @@ /* * Name entered successfully. - * If entry in Pre_defined_names[] specifies an + * If entry in pre_defined_names[] specifies an * initial value, create the initial value. */ if (init_val->val) { + status = acpi_os_predefined_override (init_val, &val); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n", + init_val->name)); + } + + if (!val) { + val = init_val->val; + } + /* * Entry requests an initial value, allocate a * descriptor for it. @@ -116,13 +145,24 @@ * internal representation. Only types actually * used for initial values are implemented here. */ - switch (init_val->type) { + case ACPI_TYPE_METHOD: + obj_desc->method.param_count = + (u8) ACPI_STRTOUL (val, NULL, 10); + obj_desc->common.flags |= AOPOBJ_DATA_VALID; + +#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) + + /* Compiler cheats by putting parameter count in the owner_iD */ + + new_node->owner_id = obj_desc->method.param_count; +#endif + break; case ACPI_TYPE_INTEGER: obj_desc->integer.value = - (acpi_integer) STRTOUL (init_val->val, NULL, 10); + (acpi_integer) ACPI_STRTOUL (val, NULL, 10); break; @@ -131,25 +171,25 @@ /* * Build an object around the static string */ - obj_desc->string.length = STRLEN (init_val->val); - obj_desc->string.pointer = init_val->val; + obj_desc->string.length = (u32) ACPI_STRLEN (val); + obj_desc->string.pointer = val; obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; break; case ACPI_TYPE_MUTEX: + obj_desc->mutex.node = new_node; obj_desc->mutex.sync_level = - (u16) STRTOUL (init_val->val, NULL, 10); + (u16) ACPI_STRTOUL (val, NULL, 10); - if (STRCMP (init_val->name, "_GL_") == 0) { + if (ACPI_STRCMP (init_val->name, "_GL_") == 0) { /* * Create a counting semaphore for the * global lock */ status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 1, &obj_desc->mutex.semaphore); - if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -160,13 +200,11 @@ */ acpi_gbl_global_lock_semaphore = obj_desc->mutex.semaphore; } - else { /* Create a mutex */ status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore); - if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -175,7 +213,7 @@ default: - REPORT_ERROR (("Unsupported initial type value %X\n", + ACPI_REPORT_ERROR (("Unsupported initial type value %X\n", init_val->type)); acpi_ut_remove_reference (obj_desc); obj_desc = NULL; @@ -184,7 +222,7 @@ /* Store pointer to value descriptor in the Node */ - acpi_ns_attach_object (new_node, obj_desc, obj_desc->common.type); + status = acpi_ns_attach_object (new_node, obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc)); /* Remove local reference to the object */ @@ -194,23 +232,23 @@ unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ns_lookup + * FUNCTION: acpi_ns_lookup * - * PARAMETERS: Prefix_node - Search scope if name is not fully qualified + * PARAMETERS: prefix_node - Search scope if name is not fully qualified * Pathname - Search pathname, in internal format * (as represented in the AML stream) * Type - Type associated with name - * Interpreter_mode - IMODE_LOAD_PASS2 => add name if not found + * interpreter_mode - IMODE_LOAD_PASS2 => add name if not found * Flags - Flags describing the search restrictions - * Walk_state - Current state of the walk - * Return_node - Where the Node is placed (if found + * walk_state - Current state of the walk + * return_node - Where the Node is placed (if found * or created successfully) * * RETURN: Status @@ -224,44 +262,41 @@ acpi_status acpi_ns_lookup ( - acpi_generic_state *scope_info, - NATIVE_CHAR *pathname, - acpi_object_type8 type, - operating_mode interpreter_mode, - u32 flags, - acpi_walk_state *walk_state, - acpi_namespace_node **return_node) + union acpi_generic_state *scope_info, + char *pathname, + acpi_object_type type, + acpi_interpreter_mode interpreter_mode, + u32 flags, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node **return_node) { - acpi_status status; - acpi_namespace_node *prefix_node; - acpi_namespace_node *current_node = NULL; - acpi_namespace_node *scope_to_push = NULL; - acpi_namespace_node *this_node = NULL; - u32 num_segments; - acpi_name simple_name; - u8 null_name_path = FALSE; - acpi_object_type8 type_to_check_for; - acpi_object_type8 this_search_type; - u32 local_flags = flags & ~NS_ERROR_IF_FOUND; - - DEBUG_EXEC (u32 i;) + acpi_status status; + char *path = pathname; + struct acpi_namespace_node *prefix_node; + struct acpi_namespace_node *current_node = NULL; + struct acpi_namespace_node *this_node = NULL; + u32 num_segments; + u32 num_carats; + acpi_name simple_name; + acpi_object_type type_to_check_for; + acpi_object_type this_search_type; + u32 search_parent_flag = ACPI_NS_SEARCH_PARENT; + u32 local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | + ACPI_NS_SEARCH_PARENT); - FUNCTION_TRACE ("Ns_lookup"); + ACPI_FUNCTION_TRACE ("ns_lookup"); if (!return_node) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_gbl_ns_lookup_count++; - - *return_node = ENTRY_NOT_FOUND; - + *return_node = ACPI_ENTRY_NOT_FOUND; if (!acpi_gbl_root_node) { - return (AE_NO_NAMESPACE); + return_ACPI_STATUS (AE_NO_NAMESPACE); } /* @@ -270,248 +305,273 @@ */ if ((!scope_info) || (!scope_info->scope.node)) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Null scope prefix, using root node (%p)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Null scope prefix, using root node (%p)\n", acpi_gbl_root_node)); prefix_node = acpi_gbl_root_node; } else { prefix_node = scope_info->scope.node; - } - - - /* - * This check is explicitly split to relax the Type_to_check_for - * conditions for Bank_field_defn. Originally, both Bank_field_defn and - * Def_field_defn caused Type_to_check_for to be set to ACPI_TYPE_REGION, - * but the Bank_field_defn may also check for a Field definition as well - * as an Operation_region. - */ - if (INTERNAL_TYPE_FIELD_DEFN == type) { - /* Def_field_defn defines fields in a Region */ - - type_to_check_for = ACPI_TYPE_REGION; - } - - else if (INTERNAL_TYPE_BANK_FIELD_DEFN == type) { - /* Bank_field_defn defines data fields in a Field Object */ - - type_to_check_for = ACPI_TYPE_ANY; - } + if (ACPI_GET_DESCRIPTOR_TYPE (prefix_node) != ACPI_DESC_TYPE_NAMED) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%p] Not a namespace node\n", + prefix_node)); + return_ACPI_STATUS (AE_AML_INTERNAL); + } - else { - type_to_check_for = type; + /* + * This node might not be a actual "scope" node (such as a + * Device/Method, etc.) It could be a Package or other object node. + * Backup up the tree to find the containing scope node. + */ + while (!acpi_ns_opens_scope (prefix_node->type) && + prefix_node->type != ACPI_TYPE_ANY) { + prefix_node = acpi_ns_get_parent_node (prefix_node); + } } + /* Save type TBD: may be no longer necessary */ - /* TBD: [Restructure] - Move the pathname stuff into a new procedure */ - - /* Examine the name pointer */ + type_to_check_for = type; + /* + * Begin examination of the actual pathname + */ if (!pathname) { - /* 8-12-98 ASL Grammar Update supports null Name_path */ + /* A Null name_path is allowed and refers to the root */ - null_name_path = TRUE; num_segments = 0; - this_node = acpi_gbl_root_node; + this_node = acpi_gbl_root_node; + path = ""; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Null Pathname (Zero segments), Flags=%x\n", flags)); + "Null Pathname (Zero segments), Flags=%X\n", flags)); } - else { /* - * Valid name pointer (Internal name format) + * Name pointer is valid (and must be in internal name format) * - * Check for prefixes. As represented in the AML stream, a - * Pathname consists of an optional scope prefix followed by - * a segment part. + * Check for scope prefixes: * - * If present, the scope prefix is either a Root_prefix (in - * which case the name is fully qualified), or zero or more - * Parent_prefixes (in which case the name's scope is relative - * to the current scope). + * As represented in the AML stream, a namepath consists of an + * optional scope prefix followed by a name segment part. * - * The segment part consists of either: - * - A single 4-byte name segment, or - * - A Dual_name_prefix followed by two 4-byte name segments, or - * - A Multi_name_prefix_op, followed by a byte indicating the - * number of segments and the segments themselves. + * If present, the scope prefix is either a Root Prefix (in + * which case the name is fully qualified), or one or more + * Parent Prefixes (in which case the name's scope is relative + * to the current scope). */ - if (*pathname == AML_ROOT_PREFIX) { - /* Pathname is fully qualified, look in root name table */ - - current_node = acpi_gbl_root_node; + if (*path == (u8) AML_ROOT_PREFIX) { + /* Pathname is fully qualified, start from the root */ - /* point to segment part */ + this_node = acpi_gbl_root_node; + search_parent_flag = ACPI_NS_NO_UPSEARCH; - pathname++; + /* Point to name segment part */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching from root [%p]\n", - current_node)); + path++; - /* Direct reference to root, "\" */ - - if (!(*pathname)) { - this_node = acpi_gbl_root_node; - goto check_for_new_scope_and_exit; - } + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Path is absolute from root [%p]\n", this_node)); } - else { /* Pathname is relative to current scope, start there */ - current_node = prefix_node; - - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching relative to pfx scope [%p]\n", - prefix_node)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Searching relative to prefix scope [%4.4s] (%p)\n", + prefix_node->name.ascii, prefix_node)); /* - * Handle up-prefix (carat). More than one prefix - * is supported + * Handle multiple Parent Prefixes (carat) by just getting + * the parent node for each prefix instance. */ - while (*pathname == AML_PARENT_PREFIX) { - /* Point to segment part or next Parent_prefix */ + this_node = prefix_node; + num_carats = 0; + while (*path == (u8) AML_PARENT_PREFIX) { + /* Name is fully qualified, no search rules apply */ - pathname++; + search_parent_flag = ACPI_NS_NO_UPSEARCH; + /* + * Point past this prefix to the name segment + * part or the next Parent Prefix + */ + path++; - /* Backup to the parent's scope */ + /* Backup to the parent node */ - this_node = acpi_ns_get_parent_object (current_node); + num_carats++; + this_node = acpi_ns_get_parent_node (this_node); if (!this_node) { /* Current scope has no parent scope */ - REPORT_ERROR ( - ("Too many parent prefixes (^) - reached root\n")); + ACPI_REPORT_ERROR ( + ("ACPI path has too many parent prefixes (^) - reached beyond root node\n")); return_ACPI_STATUS (AE_NOT_FOUND); } + } - current_node = this_node; + if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Search scope is [%4.4s], path has %d carat(s)\n", + this_node->name.ascii, num_carats)); } } - /* - * Examine the name prefix opcode, if any, - * to determine the number of segments + * Determine the number of ACPI name segments in this pathname. + * + * The segment part consists of either: + * - A Null name segment (0) + * - A dual_name_prefix followed by two 4-byte name segments + * - A multi_name_prefix followed by a byte indicating the + * number of segments and the segments themselves. + * - A single 4-byte name segment + * + * Examine the name prefix opcode, if any, to determine the number of + * segments. */ - if (*pathname == AML_DUAL_NAME_PREFIX) { - num_segments = 2; + switch (*path) { + case 0: + /* + * Null name after a root or parent prefixes. We already + * have the correct target node and there are no name segments. + */ + num_segments = 0; + type = this_node->type; + + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Prefix-only Pathname (Zero name segments), Flags=%X\n", flags)); + break; + + case AML_DUAL_NAME_PREFIX: + + /* More than one name_seg, search rules do not apply */ - /* point to first segment */ + search_parent_flag = ACPI_NS_NO_UPSEARCH; - pathname++; + /* Two segments, point to first name segment */ + + num_segments = 2; + path++; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Dual Pathname (2 segments, Flags=%X)\n", flags)); - } + break; + + case AML_MULTI_NAME_PREFIX_OP: - else if (*pathname == AML_MULTI_NAME_PREFIX_OP) { - num_segments = (u32)* (u8 *) ++pathname; + /* More than one name_seg, search rules do not apply */ - /* point to first segment */ + search_parent_flag = ACPI_NS_NO_UPSEARCH; - pathname++; + /* Extract segment count, point to first name segment */ + + path++; + num_segments = (u32) (u8) *path; + path++; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Multi Pathname (%d Segments, Flags=%X) \n", num_segments, flags)); - } + break; - else { + default: /* - * No Dual or Multi prefix, hence there is only one - * segment and Pathname is already pointing to it. + * Not a Null name, no Dual or Multi prefix, hence there is + * only one name segment and Pathname is already pointing to it. */ num_segments = 1; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Simple Pathname (1 segment, Flags=%X)\n", flags)); + break; } -#ifdef ACPI_DEBUG - - /* TBD: [Restructure] Make this a procedure */ - - /* Debug only: print the entire name that we are about to lookup */ - - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[")); - - for (i = 0; i < num_segments; i++) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "%4.4s/", (char*)&pathname[i * 4])); - } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "]\n")); -#endif + ACPI_DEBUG_EXEC (acpi_ns_print_pathname (num_segments, path)); } /* - * Search namespace for each segment of the name. - * Loop through and verify/add each name segment. + * Search namespace for each segment of the name. Loop through and + * verify (or add to the namespace) each name segment. + * + * The object type is significant only at the last name + * segment. (We don't care about the types along the path, only + * the type of the final target object.) */ - while (num_segments-- && current_node) { - /* - * Search for the current name segment under the current - * named object. The Type is significant only at the last (topmost) - * level. (We don't care about the types along the path, only - * the type of the final target object.) - */ - this_search_type = ACPI_TYPE_ANY; + this_search_type = ACPI_TYPE_ANY; + current_node = this_node; + while (num_segments && current_node) { + num_segments--; if (!num_segments) { + /* + * This is the last segment, enable typechecking + */ this_search_type = type; - local_flags = flags; - } - /* Pluck one ACPI name from the front of the pathname */ + /* + * Only allow automatic parent search (search rules) if the caller + * requested it AND we have a single, non-fully-qualified name_seg + */ + if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) && + (flags & ACPI_NS_SEARCH_PARENT)) { + local_flags |= ACPI_NS_SEARCH_PARENT; + } + + /* Set error flag according to caller */ - MOVE_UNALIGNED32_TO_32 (&simple_name, pathname); + if (flags & ACPI_NS_ERROR_IF_FOUND) { + local_flags |= ACPI_NS_ERROR_IF_FOUND; + } + } - /* Try to find the ACPI name */ + /* Extract one ACPI name from the front of the pathname */ - status = acpi_ns_search_and_enter (simple_name, walk_state, - current_node, interpreter_mode, - this_search_type, local_flags, - &this_node); + ACPI_MOVE_32_TO_32 (&simple_name, path); + /* Try to find the single (4 character) ACPI name */ + + status = acpi_ns_search_and_enter (simple_name, walk_state, current_node, + interpreter_mode, this_search_type, local_flags, &this_node); if (ACPI_FAILURE (status)) { if (status == AE_NOT_FOUND) { - /* Name not found in ACPI namespace */ + /* Name not found in ACPI namespace */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Name [%4.4s] not found in scope %p\n", - (char*)&simple_name, current_node)); + "Name [%4.4s] not found in scope [%4.4s] %p\n", + (char *) &simple_name, (char *) ¤t_node->name, + current_node)); } + *return_node = this_node; return_ACPI_STATUS (status); } - /* - * If 1) This is the last segment (Num_segments == 0) - * 2) and looking for a specific type + * Sanity typecheck of the target object: + * + * If 1) This is the last segment (num_segments == 0) + * 2) And we are looking for a specific type * (Not checking for TYPE_ANY) * 3) Which is not an alias - * 4) which is not a local type (TYPE_DEF_ANY) - * 5) which is not a local type (TYPE_SCOPE) - * 6) which is not a local type (TYPE_INDEX_FIELD_DEFN) - * 7) and type of object is known (not TYPE_ANY) - * 8) and object does not match request + * 4) Which is not a local type (TYPE_SCOPE) + * 5) And the type of target object is known (not TYPE_ANY) + * 6) And target object does not match what we are looking for * * Then we have a type mismatch. Just warn and ignore it. */ if ((num_segments == 0) && (type_to_check_for != ACPI_TYPE_ANY) && - (type_to_check_for != INTERNAL_TYPE_ALIAS) && - (type_to_check_for != INTERNAL_TYPE_DEF_ANY) && - (type_to_check_for != INTERNAL_TYPE_SCOPE) && - (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) && + (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && + (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) && (this_node->type != ACPI_TYPE_ANY) && (this_node->type != type_to_check_for)) { /* Complain about a type mismatch */ - REPORT_WARNING ( - ("Ns_lookup: %4.4s, type %X, checking for type %X\n", - (char*)&simple_name, this_node->type, type_to_check_for)); + ACPI_REPORT_WARNING ( + ("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n", + (char *) &simple_name, acpi_ut_get_type_name (this_node->type), + acpi_ut_get_type_name (type_to_check_for))); } /* @@ -519,57 +579,29 @@ * specific type, but the type of found object is known, use that type * to see if it opens a scope. */ - if ((0 == num_segments) && (ACPI_TYPE_ANY == type)) { + if ((num_segments == 0) && (type == ACPI_TYPE_ANY)) { type = this_node->type; } - if ((num_segments || acpi_ns_opens_scope (type)) && - (this_node->child == NULL)) { - /* - * More segments or the type implies enclosed scope, - * and the next scope has not been allocated. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Load mode=%X This_node=%p\n", - interpreter_mode, this_node)); - } + /* Point to next name segment and make this node current */ + path += ACPI_NAME_SIZE; current_node = this_node; - - /* point to next name segment */ - - pathname += ACPI_NAME_SIZE; } - /* * Always check if we need to open a new scope */ -check_for_new_scope_and_exit: - - if (!(flags & NS_DONT_OPEN_SCOPE) && (walk_state)) { + if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) { /* - * If entry is a type which opens a scope, - * push the new scope on the scope stack. + * If entry is a type which opens a scope, push the new scope on the + * scope stack. */ - if (acpi_ns_opens_scope (type_to_check_for)) { - /* 8-12-98 ASL Grammar Update supports null Name_path */ - - if (null_name_path) { - /* TBD: [Investigate] - is this the correct thing to do? */ - - scope_to_push = NULL; - } - else { - scope_to_push = this_node; - } - - status = acpi_ds_scope_stack_push (scope_to_push, type, - walk_state); + if (acpi_ns_opens_scope (type)) { + status = acpi_ds_scope_stack_push (this_node, type, walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Set global scope to %p\n", scope_to_push)); } } diff -urN linux-2.4.21/drivers/acpi/namespace/nsalloc.c linux-2.4.22/drivers/acpi/namespace/nsalloc.c --- linux-2.4.21/drivers/acpi/namespace/nsalloc.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsalloc.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,43 +1,60 @@ /******************************************************************************* * * Module Name: nsalloc - Namespace allocation and deletion utilities - * $Revision: 60 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsalloc") + ACPI_MODULE_NAME ("nsalloc") /******************************************************************************* * - * FUNCTION: Acpi_ns_create_node + * FUNCTION: acpi_ns_create_node * - * PARAMETERS: Acpi_name - Name of the new node + * PARAMETERS: acpi_name - Name of the new node * * RETURN: None * @@ -45,26 +62,26 @@ * ******************************************************************************/ -acpi_namespace_node * +struct acpi_namespace_node * acpi_ns_create_node ( - u32 name) + u32 name) { - acpi_namespace_node *node; + struct acpi_namespace_node *node; - FUNCTION_TRACE ("Ns_create_node"); + ACPI_FUNCTION_TRACE ("ns_create_node"); - node = ACPI_MEM_CALLOCATE (sizeof (acpi_namespace_node)); + node = ACPI_MEM_CALLOCATE (sizeof (struct acpi_namespace_node)); if (!node) { return_PTR (NULL); } ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_allocated++); - node->data_type = ACPI_DESC_TYPE_NAMED; - node->name = name; + node->name.integer = name; node->reference_count = 1; + ACPI_SET_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED); return_PTR (node); } @@ -72,7 +89,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_delete_node + * FUNCTION: acpi_ns_delete_node * * PARAMETERS: Node - Node to be deleted * @@ -84,78 +101,150 @@ void acpi_ns_delete_node ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { - acpi_namespace_node *parent_node; - acpi_namespace_node *prev_node; - acpi_namespace_node *next_node; + struct acpi_namespace_node *parent_node; + struct acpi_namespace_node *prev_node; + struct acpi_namespace_node *next_node; - FUNCTION_TRACE_PTR ("Ns_delete_node", node); + ACPI_FUNCTION_TRACE_PTR ("ns_delete_node", node); - parent_node = acpi_ns_get_parent_object (node); + parent_node = acpi_ns_get_parent_node (node); prev_node = NULL; next_node = parent_node->child; + /* Find the node that is the previous peer in the parent's child list */ + while (next_node != node) { prev_node = next_node; next_node = prev_node->peer; } if (prev_node) { + /* Node is not first child, unlink it */ + prev_node->peer = next_node->peer; if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { prev_node->flags |= ANOBJ_END_OF_PEER_LIST; } } else { - parent_node->child = next_node->peer; + /* Node is first child (has no previous peer) */ + + if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { + /* No peers at all */ + + parent_node->child = NULL; + } + else { /* Link peer list to parent */ + + parent_node->child = next_node->peer; + } } ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++); /* - * Detach an object if there is one + * Detach an object if there is one then delete the node */ - if (node->object) { - acpi_ns_detach_object (node); - } - + acpi_ns_detach_object (node); ACPI_MEM_FREE (node); return_VOID; } +#ifdef ACPI_ALPHABETIC_NAMESPACE +/******************************************************************************* + * + * FUNCTION: acpi_ns_compare_names + * + * PARAMETERS: Name1 - First name to compare + * Name2 - Second name to compare + * + * RETURN: value from strncmp + * + * DESCRIPTION: Compare two ACPI names. Names that are prefixed with an + * underscore are forced to be alphabetically first. + * + ******************************************************************************/ + +int +acpi_ns_compare_names ( + char *name1, + char *name2) +{ + char reversed_name1[ACPI_NAME_SIZE]; + char reversed_name2[ACPI_NAME_SIZE]; + u32 i; + u32 j; + + + /* + * Replace all instances of "underscore" with a value that is smaller so + * that all names that are prefixed with underscore(s) are alphabetically + * first. + * + * Reverse the name bytewise so we can just do a 32-bit compare instead + * of a strncmp. + */ + for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) { + reversed_name1[j] = name1[i]; + if (name1[i] == '_') { + reversed_name1[j] = '*'; + } + + reversed_name2[j] = name2[i]; + if (name2[i] == '_') { + reversed_name2[j] = '*'; + } + } + + return (*(int *) reversed_name1 - *(int *) reversed_name2); +} +#endif + + /******************************************************************************* * - * FUNCTION: Acpi_ns_install_node + * FUNCTION: acpi_ns_install_node * - * PARAMETERS: Walk_state - Current state of the walk - * Parent_node - The parent of the new Node + * PARAMETERS: walk_state - Current state of the walk + * parent_node - The parent of the new Node * Node - The new Node to install * Type - ACPI object type of the new Node * * RETURN: None * - * DESCRIPTION: Initialize a new entry within a namespace table. + * DESCRIPTION: Initialize a new namespace node and install it amongst + * its peers. + * + * Note: Current namespace lookup is linear search. However, the + * nodes are linked in alphabetical order to 1) put all reserved + * names (start with underscore) first, and to 2) make a readable + * namespace dump. * ******************************************************************************/ void acpi_ns_install_node ( - acpi_walk_state *walk_state, - acpi_namespace_node *parent_node, /* Parent */ - acpi_namespace_node *node, /* New Child*/ - acpi_object_type8 type) + struct acpi_walk_state *walk_state, + struct acpi_namespace_node *parent_node, /* Parent */ + struct acpi_namespace_node *node, /* New Child*/ + acpi_object_type type) { - u16 owner_id = TABLE_ID_DSDT; - acpi_namespace_node *child_node; + u16 owner_id = 0; + struct acpi_namespace_node *child_node; +#ifdef ACPI_ALPHABETIC_NAMESPACE + + struct acpi_namespace_node *previous_child_node; +#endif - FUNCTION_TRACE ("Ns_install_node"); + ACPI_FUNCTION_TRACE ("ns_install_node"); /* @@ -167,17 +256,65 @@ owner_id = walk_state->owner_id; } - - /* link the new entry into the parent and existing children */ - - /* TBD: Could be first, last, or alphabetic */ + /* Link the new entry into the parent and existing children */ child_node = parent_node->child; if (!child_node) { parent_node->child = node; + node->flags |= ANOBJ_END_OF_PEER_LIST; + node->peer = parent_node; } - else { +#ifdef ACPI_ALPHABETIC_NAMESPACE + /* + * Walk the list whilst searching for the the correct + * alphabetic placement. + */ + previous_child_node = NULL; + while (acpi_ns_compare_names (child_node->name.ascii, node->name.ascii) < 0) { + if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { + /* Last peer; Clear end-of-list flag */ + + child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; + + /* This node is the new peer to the child node */ + + child_node->peer = node; + + /* This node is the new end-of-list */ + + node->flags |= ANOBJ_END_OF_PEER_LIST; + node->peer = parent_node; + break; + } + + /* Get next peer */ + + previous_child_node = child_node; + child_node = child_node->peer; + } + + /* Did the node get inserted at the end-of-list? */ + + if (!(node->flags & ANOBJ_END_OF_PEER_LIST)) { + /* + * Loop above terminated without reaching the end-of-list. + * Insert the new node at the current location + */ + if (previous_child_node) { + /* Insert node alphabetically */ + + node->peer = child_node; + previous_child_node->peer = node; + } + else { + /* Insert node alphabetically at start of list */ + + node->peer = child_node; + parent_node->child = node; + } + } +#else while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { child_node = child_node->peer; } @@ -187,61 +324,25 @@ /* Clear end-of-list flag */ child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; + node->flags |= ANOBJ_END_OF_PEER_LIST; + node->peer = parent_node; +#endif } /* Init the new entry */ - node->owner_id = owner_id; - node->flags |= ANOBJ_END_OF_PEER_LIST; - node->peer = parent_node; - - - /* - * If adding a name with unknown type, or having to - * add the region in order to define fields in it, we - * have a forward reference. - */ - if ((ACPI_TYPE_ANY == type) || - (INTERNAL_TYPE_FIELD_DEFN == type) || - (INTERNAL_TYPE_BANK_FIELD_DEFN == type)) { - /* - * We don't want to abort here, however! - * We will fill in the actual type when the - * real definition is found later. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "[%4.4s] is a forward reference\n", - (char*)&node->name)); - } - - /* - * The Def_field_defn and Bank_field_defn cases are actually - * looking up the Region in which the field will be defined - */ - if ((INTERNAL_TYPE_FIELD_DEFN == type) || - (INTERNAL_TYPE_BANK_FIELD_DEFN == type)) { - type = ACPI_TYPE_REGION; - } - - /* - * Scope, Def_any, and Index_field_defn are bogus "types" which do - * not actually have anything to do with the type of the name - * being looked up. Save any other value of Type as the type of - * the entry. - */ - if ((type != INTERNAL_TYPE_SCOPE) && - (type != INTERNAL_TYPE_DEF_ANY) && - (type != INTERNAL_TYPE_INDEX_FIELD_DEFN)) { - node->type = (u8) type; - } + node->owner_id = owner_id; + node->type = (u8) type; - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s added to %p at %p\n", - (char*)&node->name, parent_node, node)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n", + node->name.ascii, acpi_ut_get_type_name (node->type), + parent_node->name.ascii, acpi_ut_get_type_name (parent_node->type), parent_node, node)); /* * Increment the reference count(s) of all parents up to * the root! */ - while ((node = acpi_ns_get_parent_object (node)) != NULL) { + while ((node = acpi_ns_get_parent_node (node)) != NULL) { node->reference_count++; } @@ -251,27 +352,28 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_delete_children + * FUNCTION: acpi_ns_delete_children * - * PARAMETERS: Parent_node - Delete this objects children + * PARAMETERS: parent_node - Delete this objects children * * RETURN: None. * - * DESCRIPTION: Delete all children of the parent object. Deletes a - * "scope". + * DESCRIPTION: Delete all children of the parent object. In other words, + * deletes a "scope". * ******************************************************************************/ void acpi_ns_delete_children ( - acpi_namespace_node *parent_node) + struct acpi_namespace_node *parent_node) { - acpi_namespace_node *child_node; - acpi_namespace_node *next_node; - u8 flags; + struct acpi_namespace_node *child_node; + struct acpi_namespace_node *next_node; + struct acpi_namespace_node *node; + u8 flags; - FUNCTION_TRACE_PTR ("Ns_delete_children", parent_node); + ACPI_FUNCTION_TRACE_PTR ("ns_delete_children", parent_node); if (!parent_node) { @@ -305,13 +407,32 @@ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object %p, Remaining %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", child_node, acpi_gbl_current_node_count)); /* * Detach an object if there is one, then free the child node */ acpi_ns_detach_object (child_node); + + /* + * Decrement the reference count(s) of all parents up to + * the root! (counts were incremented when the node was created) + */ + node = child_node; + while ((node = acpi_ns_get_parent_node (node)) != NULL) { + node->reference_count--; + } + + /* There should be only one reference remaining on this node */ + + if (child_node->reference_count != 1) { + ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n", + child_node->reference_count, child_node)); + } + + /* Now we can delete the node */ + ACPI_MEM_FREE (child_node); /* And move on to the next child in the list */ @@ -331,30 +452,30 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_delete_namespace_subtree + * FUNCTION: acpi_ns_delete_namespace_subtree * - * PARAMETERS: Parent_node - Root of the subtree to be deleted + * PARAMETERS: parent_node - Root of the subtree to be deleted * * RETURN: None. * * DESCRIPTION: Delete a subtree of the namespace. This includes all objects - * stored within the subtree. Scope tables are deleted also + * stored within the subtree. * ******************************************************************************/ -acpi_status +void acpi_ns_delete_namespace_subtree ( - acpi_namespace_node *parent_node) + struct acpi_namespace_node *parent_node) { - acpi_namespace_node *child_node = NULL; - u32 level = 1; + struct acpi_namespace_node *child_node = NULL; + u32 level = 1; - FUNCTION_TRACE ("Ns_delete_namespace_subtree"); + ACPI_FUNCTION_TRACE ("ns_delete_namespace_subtree"); if (!parent_node) { - return_ACPI_STATUS (AE_OK); + return_VOID; } /* @@ -383,7 +504,6 @@ child_node = 0; } } - else { /* * No more children of this parent node. @@ -403,17 +523,17 @@ /* Move up the tree to the grandparent */ - parent_node = acpi_ns_get_parent_object (parent_node); + parent_node = acpi_ns_get_parent_node (parent_node); } } - return_ACPI_STATUS (AE_OK); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ns_remove_reference + * FUNCTION: acpi_ns_remove_reference * * PARAMETERS: Node - Named node whose reference count is to be * decremented @@ -426,47 +546,50 @@ * ******************************************************************************/ -static void +void acpi_ns_remove_reference ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { - acpi_namespace_node *next_node; + struct acpi_namespace_node *parent_node; + struct acpi_namespace_node *this_node; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* * Decrement the reference count(s) of this node and all * nodes up to the root, Delete anything with zero remaining references. */ - next_node = node; - while (next_node) { - /* Decrement the reference count on this node*/ + this_node = node; + while (this_node) { + /* Prepare to move up to parent */ + + parent_node = acpi_ns_get_parent_node (this_node); + + /* Decrement the reference count on this node */ - next_node->reference_count--; + this_node->reference_count--; /* Delete the node if no more references */ - if (!next_node->reference_count) { + if (!this_node->reference_count) { /* Delete all children and delete the node */ - acpi_ns_delete_children (next_node); - acpi_ns_delete_node (next_node); + acpi_ns_delete_children (this_node); + acpi_ns_delete_node (this_node); } - /* Move up to parent */ - - next_node = acpi_ns_get_parent_object (next_node); + this_node = parent_node; } } /******************************************************************************* * - * FUNCTION: Acpi_ns_delete_namespace_by_owner + * FUNCTION: acpi_ns_delete_namespace_by_owner * - * PARAMETERS: Owner_id - All nodes with this owner will be deleted + * PARAMETERS: owner_id - All nodes with this owner will be deleted * * RETURN: Status * @@ -476,65 +599,71 @@ * ******************************************************************************/ -acpi_status +void acpi_ns_delete_namespace_by_owner ( - u16 owner_id) + u16 owner_id) { - acpi_namespace_node *child_node; - u32 level; - acpi_namespace_node *parent_node; + struct acpi_namespace_node *child_node; + struct acpi_namespace_node *deletion_node; + u32 level; + struct acpi_namespace_node *parent_node; - FUNCTION_TRACE ("Ns_delete_namespace_by_owner"); + ACPI_FUNCTION_TRACE_U32 ("ns_delete_namespace_by_owner", owner_id); - parent_node = acpi_gbl_root_node; - child_node = 0; - level = 1; + parent_node = acpi_gbl_root_node; + child_node = NULL; + deletion_node = NULL; + level = 1; /* * Traverse the tree of nodes until we bubble back up * to where we started. */ while (level > 0) { - /* Get the next node in this scope (NULL if none) */ + /* + * Get the next child of this parent node. When child_node is NULL, + * the first child of the parent is returned + */ + child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node); + + if (deletion_node) { + acpi_ns_remove_reference (deletion_node); + deletion_node = NULL; + } - child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, - child_node); if (child_node) { if (child_node->owner_id == owner_id) { - /* Found a child node - detach any attached object */ + /* Found a matching child node - detach any attached object */ acpi_ns_detach_object (child_node); } /* Check if this node has any children */ - if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, 0)) { + if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) { /* * There is at least one child of this node, * visit the node */ level++; parent_node = child_node; - child_node = 0; + child_node = NULL; } - else if (child_node->owner_id == owner_id) { - acpi_ns_remove_reference (child_node); + deletion_node = child_node; } } - else { /* * No more children of this parent node. * Move up to the grandparent. */ level--; - if (level != 0) { if (parent_node->owner_id == owner_id) { - acpi_ns_remove_reference (parent_node); + deletion_node = parent_node; } } @@ -544,11 +673,11 @@ /* Move up the tree to the grandparent */ - parent_node = acpi_ns_get_parent_object (parent_node); + parent_node = acpi_ns_get_parent_node (parent_node); } } - return_ACPI_STATUS (AE_OK); + return_VOID; } diff -urN linux-2.4.21/drivers/acpi/namespace/nsdump.c linux-2.4.22/drivers/acpi/namespace/nsdump.c --- linux-2.4.21/drivers/acpi/namespace/nsdump.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/namespace/nsdump.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,45 +1,102 @@ /****************************************************************************** * * Module Name: nsdump - table dumping routines for debug - * $Revision: 105 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" -#include "acparser.h" +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsdump") + ACPI_MODULE_NAME ("nsdump") +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) -#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) /******************************************************************************* * - * FUNCTION: Acpi_ns_dump_pathname + * FUNCTION: acpi_ns_print_pathname + * + * PARAMETERS: num_segment - Number of ACPI name segments + * Pathname - The compressed (internal) path + * + * DESCRIPTION: Print an object's full namespace pathname + * + ******************************************************************************/ + +void +acpi_ns_print_pathname ( + u32 num_segments, + char *pathname) +{ + ACPI_FUNCTION_NAME ("ns_print_pathname"); + + + if (!(acpi_dbg_level & ACPI_LV_NAMES) || !(acpi_dbg_layer & ACPI_NAMESPACE)) { + return; + } + + /* Print the entire name */ + + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[")); + + while (num_segments) { + acpi_os_printf ("%4.4s", pathname); + pathname += ACPI_NAME_SIZE; + + num_segments--; + if (num_segments) { + acpi_os_printf ("."); + } + } + + acpi_os_printf ("]\n"); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_dump_pathname * * PARAMETERS: Handle - Object * Msg - Prefix message @@ -51,85 +108,65 @@ * ******************************************************************************/ -acpi_status +void acpi_ns_dump_pathname ( - acpi_handle handle, - NATIVE_CHAR *msg, - u32 level, - u32 component) + acpi_handle handle, + char *msg, + u32 level, + u32 component) { - NATIVE_CHAR *buffer; - u32 length; - - FUNCTION_TRACE ("Ns_dump_pathname"); + ACPI_FUNCTION_TRACE ("ns_dump_pathname"); /* Do this only if the requested debug level and component are enabled */ if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) { - return_ACPI_STATUS (AE_OK); - } - - buffer = ACPI_MEM_ALLOCATE (PATHNAME_MAX); - if (!buffer) { - return_ACPI_STATUS (AE_NO_MEMORY); + return_VOID; } /* Convert handle to a full pathname and print it (with supplied message) */ - length = PATHNAME_MAX; - if (ACPI_SUCCESS (acpi_ns_handle_to_pathname (handle, &length, buffer))) { - acpi_os_printf ("%s %s (%p)\n", msg, buffer, handle); - } - - ACPI_MEM_FREE (buffer); - - return_ACPI_STATUS (AE_OK); + acpi_ns_print_node_pathname (handle, msg); + acpi_os_printf ("\n"); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ns_dump_one_object + * FUNCTION: acpi_ns_dump_one_object * * PARAMETERS: Handle - Node to be dumped * Level - Nesting level of the handle - * Context - Passed into Walk_namespace + * Context - Passed into walk_namespace * * DESCRIPTION: Dump a single Node - * This procedure is a User_function called by Acpi_ns_walk_namespace. + * This procedure is a user_function called by acpi_ns_walk_namespace. * ******************************************************************************/ acpi_status acpi_ns_dump_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value) + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) { - acpi_walk_info *info = (acpi_walk_info *) context; - acpi_namespace_node *this_node; - acpi_operand_object *obj_desc = NULL; - acpi_object_type8 obj_type; - acpi_object_type8 type; - u32 bytes_to_dump; - u32 downstream_sibling_mask = 0; - u32 level_tmp; - u32 which_bit; - u32 i; - + struct acpi_walk_info *info = (struct acpi_walk_info *) context; + struct acpi_namespace_node *this_node; + union acpi_operand_object *obj_desc = NULL; + acpi_object_type obj_type; + acpi_object_type type; + u32 bytes_to_dump; + u32 dbg_level; + u32 i; - PROC_NAME ("Ns_dump_one_object"); + ACPI_FUNCTION_NAME ("ns_dump_one_object"); - this_node = acpi_ns_map_handle_to_node (obj_handle); - - level_tmp = level; - type = this_node->type; - which_bit = 1; + /* Is output enabled? */ if (!(acpi_dbg_level & info->debug_level)) { return (AE_OK); @@ -140,6 +177,9 @@ return (AE_OK); } + this_node = acpi_ns_map_handle_to_node (obj_handle); + type = this_node->type; + /* Check if the owner matches */ if ((info->owner_id != ACPI_UINT32_MAX) && @@ -147,68 +187,30 @@ return (AE_OK); } - /* Indent the object according to the level */ - while (level_tmp--) { - - /* Print appropriate characters to form tree structure */ - - if (level_tmp) { - if (downstream_sibling_mask & which_bit) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|")); - } - - else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); - } - - which_bit <<= 1; - } - - else { - if (acpi_ns_exist_downstream_sibling (this_node + 1)) { - downstream_sibling_mask |= (1 << (level - 1)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); - } - - else { - downstream_sibling_mask &= ACPI_UINT32_MAX ^ (1 << (level - 1)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); - } - - if (this_node->child == NULL) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); - } - - else if (acpi_ns_exist_downstream_sibling (this_node->child)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); - } - - else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); - } - } - } - + acpi_os_printf ("%2d%*s", (u32) level - 1, (int) level * 2, " "); - /* Check the integrity of our data */ + /* Check the node type and name */ - if (type > INTERNAL_TYPE_MAX) { - type = INTERNAL_TYPE_DEF_ANY; /* prints as *ERROR* */ + if (type > ACPI_TYPE_LOCAL_MAX) { + ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", type)); } - if (!acpi_ut_valid_acpi_name (this_node->name)) { - REPORT_WARNING (("Invalid ACPI Name %08X\n", this_node->name)); + if (!acpi_ut_valid_acpi_name (this_node->name.integer)) { + ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n", this_node->name.integer)); } /* * Now we can print out the pertinent information */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-12s %p", - (char*)&this_node->name, acpi_ut_get_type_name (type), this_node)); + acpi_os_printf ("%4.4s %-12s %p ", + this_node->name.ascii, acpi_ut_get_type_name (type), this_node); - obj_desc = this_node->object; + dbg_level = acpi_dbg_level; + acpi_dbg_level = 0; + obj_desc = acpi_ns_get_attached_object (this_node); + acpi_dbg_level = dbg_level; switch (info->display_type) { case ACPI_DISPLAY_SUMMARY: @@ -216,110 +218,148 @@ if (!obj_desc) { /* No attached object, we are done */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); + acpi_os_printf ("\n"); return (AE_OK); } - switch (type) { case ACPI_TYPE_PROCESSOR: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ID %d Addr %.4X Len %.4X\n", + + acpi_os_printf ("ID %X Len %.4X Addr %p\n", obj_desc->processor.proc_id, - obj_desc->processor.address, - (unsigned)obj_desc->processor.length)); + obj_desc->processor.length, + (char *) obj_desc->processor.address); break; + case ACPI_TYPE_DEVICE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Notification object: %p", obj_desc)); + + acpi_os_printf ("Notify object: %p", obj_desc); break; + case ACPI_TYPE_METHOD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Args %d Len %.4X Aml %p \n", - obj_desc->method.param_count, + + acpi_os_printf ("Args %X Len %.4X Aml %p\n", + (u32) obj_desc->method.param_count, obj_desc->method.aml_length, - obj_desc->method.aml_start)); + obj_desc->method.aml_start); break; + case ACPI_TYPE_INTEGER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " = %8.8X%8.8X\n", - HIDWORD (obj_desc->integer.value), - LODWORD (obj_desc->integer.value))); + + acpi_os_printf ("= %8.8X%8.8X\n", + ACPI_HIDWORD (obj_desc->integer.value), + ACPI_LODWORD (obj_desc->integer.value)); break; + case ACPI_TYPE_PACKAGE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Elements %.2X\n", - obj_desc->package.count)); + + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + acpi_os_printf ("Elements %.2X\n", + obj_desc->package.count); + } + else { + acpi_os_printf ("[Length not yet evaluated]\n"); + } break; - case ACPI_TYPE_BUFFER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Len %.2X", - obj_desc->buffer.length)); - /* Dump some of the buffer */ + case ACPI_TYPE_BUFFER: - if (obj_desc->buffer.length > 0) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " =")); - for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %.2X", - obj_desc->buffer.pointer[i])); + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + acpi_os_printf ("Len %.2X", + obj_desc->buffer.length); + + /* Dump some of the buffer */ + + if (obj_desc->buffer.length > 0) { + acpi_os_printf (" ="); + for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) { + acpi_os_printf (" %.2hX", obj_desc->buffer.pointer[i]); + } } + acpi_os_printf ("\n"); + } + else { + acpi_os_printf ("[Length not yet evaluated]\n"); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); break; + case ACPI_TYPE_STRING: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Len %.2X", - obj_desc->string.length)); - if (obj_desc->string.length > 0) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " = \"%.32s\"...", - obj_desc->string.pointer)); - } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); + acpi_os_printf ("Len %.2X ", obj_desc->string.length); + acpi_ut_print_string (obj_desc->string.pointer, 32); + acpi_os_printf ("\n"); break; + case ACPI_TYPE_REGION: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [%s]", - acpi_ut_get_region_name (obj_desc->region.space_id))); + + acpi_os_printf ("[%s]", acpi_ut_get_region_name (obj_desc->region.space_id)); if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Addr %8.8X%8.8X Len %.4X\n", - HIDWORD(obj_desc->region.address), - LODWORD(obj_desc->region.address), - obj_desc->region.length)); + acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n", + ACPI_HIDWORD (obj_desc->region.address), + ACPI_LODWORD (obj_desc->region.address), + obj_desc->region.length); } else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [Address/Length not evaluated]\n")); + acpi_os_printf (" [Address/Length not yet evaluated]\n"); } break; - case INTERNAL_TYPE_REFERENCE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [%s]\n", - acpi_ps_get_opcode_name (obj_desc->reference.opcode))); + + case ACPI_TYPE_LOCAL_REFERENCE: + + acpi_os_printf ("[%s]\n", + acpi_ps_get_opcode_name (obj_desc->reference.opcode)); break; + case ACPI_TYPE_BUFFER_FIELD: - /* TBD: print Buffer name when we can easily get it */ + if (obj_desc->buffer_field.buffer_obj && + obj_desc->buffer_field.buffer_obj->buffer.node) { + acpi_os_printf ("Buf [%4.4s]", + obj_desc->buffer_field.buffer_obj->buffer.node->name.ascii); + } break; - case INTERNAL_TYPE_REGION_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]", - (char *) &obj_desc->common_field.region_obj->region.node->name)); + + case ACPI_TYPE_LOCAL_REGION_FIELD: + + acpi_os_printf ("Rgn [%4.4s]", + obj_desc->common_field.region_obj->region.node->name.ascii); break; - case INTERNAL_TYPE_BANK_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]", - (char *) &obj_desc->common_field.region_obj->region.node->name)); + + case ACPI_TYPE_LOCAL_BANK_FIELD: + + acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]", + obj_desc->common_field.region_obj->region.node->name.ascii, + obj_desc->bank_field.bank_obj->common_field.node->name.ascii); break; - case INTERNAL_TYPE_INDEX_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]", - (char *) &obj_desc->index_field.index_obj->common_field.region_obj->region.node->name)); + + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]", + obj_desc->index_field.index_obj->common_field.node->name.ascii, + obj_desc->index_field.data_obj->common_field.node->name.ascii); + break; + + + case ACPI_TYPE_LOCAL_ALIAS: + + acpi_os_printf ("Target %4.4s (%p)\n", ((struct acpi_namespace_node *) obj_desc)->name.ascii, obj_desc); break; default: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Object %p\n", obj_desc)); + acpi_os_printf ("Object %p\n", obj_desc); break; } @@ -327,77 +367,74 @@ switch (type) { case ACPI_TYPE_BUFFER_FIELD: - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Off %.2X Len %.2X Acc %.2d\n", - (obj_desc->common_field.base_byte_offset * 8) + obj_desc->common_field.start_field_bit_offset, - obj_desc->common_field.bit_length, - obj_desc->common_field.access_bit_width)); + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + acpi_os_printf (" Off %.2X Len %.2X Acc %.2hd\n", + (obj_desc->common_field.base_byte_offset * 8) + + obj_desc->common_field.start_field_bit_offset, + obj_desc->common_field.bit_length, + obj_desc->common_field.access_byte_width); break; - } + default: + break; + } break; case ACPI_DISPLAY_OBJECTS: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p O:%p", - this_node, obj_desc)); - + acpi_os_printf ("O:%p", obj_desc); if (!obj_desc) { /* No attached object, we are done */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); + acpi_os_printf ("\n"); return (AE_OK); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(R%d)", - obj_desc->common.reference_count)); + acpi_os_printf ("(R%d)", + obj_desc->common.reference_count); switch (type) { - case ACPI_TYPE_METHOD: /* Name is a Method and its AML offset/length are set */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n", - obj_desc->method.aml_start, - obj_desc->method.aml_length)); - + acpi_os_printf (" M:%p-%X\n", obj_desc->method.aml_start, + obj_desc->method.aml_length); break; - case ACPI_TYPE_INTEGER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X%X\n", - HIDWORD(obj_desc->integer.value), - LODWORD(obj_desc->integer.value))); + acpi_os_printf (" N:%X%X\n", ACPI_HIDWORD(obj_desc->integer.value), + ACPI_LODWORD(obj_desc->integer.value)); break; - case ACPI_TYPE_STRING: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n", - obj_desc->string.pointer, - obj_desc->string.length)); + acpi_os_printf (" S:%p-%X\n", obj_desc->string.pointer, + obj_desc->string.length); break; - case ACPI_TYPE_BUFFER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n", - obj_desc->buffer.pointer, - obj_desc->buffer.length)); + acpi_os_printf (" B:%p-%X\n", obj_desc->buffer.pointer, + obj_desc->buffer.length); break; - default: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); + acpi_os_printf ("\n"); break; } break; + + + default: + acpi_os_printf ("\n"); + break; } /* If debug turned off, done */ @@ -409,48 +446,55 @@ /* If there is an attached object, display it */ - obj_desc = this_node->object; + dbg_level = acpi_dbg_level; + acpi_dbg_level = 0; + obj_desc = acpi_ns_get_attached_object (this_node); + acpi_dbg_level = dbg_level; /* Dump attached objects */ while (obj_desc) { - obj_type = INTERNAL_TYPE_INVALID; + obj_type = ACPI_TYPE_INVALID; + acpi_os_printf (" Attached Object %p: ", obj_desc); /* Decode the type of attached object and dump the contents */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Attached Object %p: ", obj_desc)); + switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) { + case ACPI_DESC_TYPE_NAMED: - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n")); - bytes_to_dump = sizeof (acpi_namespace_node); - } + acpi_os_printf ("(Ptr to Node)\n"); + bytes_to_dump = sizeof (struct acpi_namespace_node); + break; - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { - obj_type = obj_desc->common.type; + case ACPI_DESC_TYPE_OPERAND: - if (obj_type > INTERNAL_TYPE_MAX) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type)); + obj_type = ACPI_GET_OBJECT_TYPE (obj_desc); + + if (obj_type > ACPI_TYPE_LOCAL_MAX) { + acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type); bytes_to_dump = 32; } - else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %2.2X [%s])\n", - obj_type, acpi_ut_get_type_name (obj_type))); - bytes_to_dump = sizeof (acpi_operand_object); + acpi_os_printf ("(Ptr to ACPI Object type %s, %X)\n", + acpi_ut_get_type_name (obj_type), obj_type); + bytes_to_dump = sizeof (union acpi_operand_object); } - } + break; + + + default: - else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n")); + acpi_os_printf ("(String or Buffer ptr - not an object descriptor)\n"); bytes_to_dump = 16; + break; } - DUMP_BUFFER (obj_desc, bytes_to_dump); + ACPI_DUMP_BUFFER (obj_desc, bytes_to_dump); /* If value is NOT an internal object, we are done */ - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { + if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { goto cleanup; } @@ -459,78 +503,78 @@ */ switch (obj_type) { case ACPI_TYPE_STRING: - obj_desc = (acpi_operand_object *) obj_desc->string.pointer; + obj_desc = (void *) obj_desc->string.pointer; break; case ACPI_TYPE_BUFFER: - obj_desc = (acpi_operand_object *) obj_desc->buffer.pointer; + obj_desc = (void *) obj_desc->buffer.pointer; break; case ACPI_TYPE_BUFFER_FIELD: - obj_desc = (acpi_operand_object *) obj_desc->buffer_field.buffer_obj; + obj_desc = (union acpi_operand_object *) obj_desc->buffer_field.buffer_obj; break; case ACPI_TYPE_PACKAGE: - obj_desc = (acpi_operand_object *) obj_desc->package.elements; + obj_desc = (void *) obj_desc->package.elements; break; case ACPI_TYPE_METHOD: - obj_desc = (acpi_operand_object *) obj_desc->method.aml_start; + obj_desc = (void *) obj_desc->method.aml_start; break; - case INTERNAL_TYPE_REGION_FIELD: - obj_desc = (acpi_operand_object *) obj_desc->field.region_obj; + case ACPI_TYPE_LOCAL_REGION_FIELD: + obj_desc = (void *) obj_desc->field.region_obj; break; - case INTERNAL_TYPE_BANK_FIELD: - obj_desc = (acpi_operand_object *) obj_desc->bank_field.region_obj; + case ACPI_TYPE_LOCAL_BANK_FIELD: + obj_desc = (void *) obj_desc->bank_field.region_obj; break; - case INTERNAL_TYPE_INDEX_FIELD: - obj_desc = (acpi_operand_object *) obj_desc->index_field.index_obj; + case ACPI_TYPE_LOCAL_INDEX_FIELD: + obj_desc = (void *) obj_desc->index_field.index_obj; break; - default: + default: goto cleanup; } - obj_type = INTERNAL_TYPE_INVALID; /* Terminate loop after next pass */ + obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ } cleanup: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); + acpi_os_printf ("\n"); return (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ns_dump_objects + * FUNCTION: acpi_ns_dump_objects * * PARAMETERS: Type - Object type to be dumped - * Max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX + * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX * for an effectively unlimited depth. - * Owner_id - Dump only objects owned by this ID. Use + * owner_id - Dump only objects owned by this ID. Use * ACPI_UINT32_MAX to match all owners. - * Start_handle - Where in namespace to start/end search + * start_handle - Where in namespace to start/end search * * DESCRIPTION: Dump typed objects within the loaded namespace. - * Uses Acpi_ns_walk_namespace in conjunction with Acpi_ns_dump_one_object. + * Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object. * ******************************************************************************/ void acpi_ns_dump_objects ( - acpi_object_type8 type, - u8 display_type, - u32 max_depth, - u32 owner_id, - acpi_handle start_handle) + acpi_object_type type, + u8 display_type, + u32 max_depth, + u32 owner_id, + acpi_handle start_handle) { - acpi_walk_info info; + struct acpi_walk_info info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); info.debug_level = ACPI_LV_TABLES; @@ -538,97 +582,19 @@ info.display_type = display_type; - acpi_ns_walk_namespace (type, start_handle, max_depth, NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object, - (void *) &info, NULL); -} - - -#ifndef _ACPI_ASL_COMPILER -/******************************************************************************* - * - * FUNCTION: Acpi_ns_dump_one_device - * - * PARAMETERS: Handle - Node to be dumped - * Level - Nesting level of the handle - * Context - Passed into Walk_namespace - * - * DESCRIPTION: Dump a single Node that represents a device - * This procedure is a User_function called by Acpi_ns_walk_namespace. - * - ******************************************************************************/ - -acpi_status -acpi_ns_dump_one_device ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value) -{ - acpi_device_info info; - acpi_status status; - u32 i; - - - PROC_NAME ("Ns_dump_one_device"); - - - status = acpi_ns_dump_one_object (obj_handle, level, context, return_value); - - status = acpi_get_object_info (obj_handle, &info); - if (ACPI_SUCCESS (status)) { - for (i = 0; i < level; i++) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %x\n", - info.hardware_id, HIDWORD(info.address), LODWORD(info.address), info.current_status)); - } - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_dump_root_devices - * - * PARAMETERS: None - * - * DESCRIPTION: Dump all objects of type "device" - * - ******************************************************************************/ - -void -acpi_ns_dump_root_devices (void) -{ - acpi_handle sys_bus_handle; - - - PROC_NAME ("Ns_dump_root_devices"); - - - /* Only dump the table if tracing is enabled */ - - if (!(ACPI_LV_TABLES & acpi_dbg_level)) { - return; - } - - acpi_get_handle (0, NS_SYSTEM_BUS, &sys_bus_handle); - - ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n")); - acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle, ACPI_UINT32_MAX, NS_WALK_NO_UNLOCK, - acpi_ns_dump_one_device, NULL, NULL); + (void) acpi_ns_walk_namespace (type, start_handle, max_depth, + ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object, + (void *) &info, NULL); } -#endif /******************************************************************************* * - * FUNCTION: Acpi_ns_dump_tables + * FUNCTION: acpi_ns_dump_tables * - * PARAMETERS: Search_base - Root of subtree to be dumped, or + * PARAMETERS: search_base - Root of subtree to be dumped, or * NS_ALL to dump the entire namespace - * Max_depth - Maximum depth of dump. Use INT_MAX + * max_depth - Maximum depth of dump. Use INT_MAX * for an effectively unlimited depth. * * DESCRIPTION: Dump the name space, or a portion of it. @@ -637,13 +603,13 @@ void acpi_ns_dump_tables ( - acpi_handle search_base, - u32 max_depth) + acpi_handle search_base, + u32 max_depth) { - acpi_handle search_handle = search_base; + acpi_handle search_handle = search_base; - FUNCTION_TRACE ("Ns_dump_tables"); + ACPI_FUNCTION_TRACE ("ns_dump_tables"); if (!acpi_gbl_root_node) { @@ -651,11 +617,11 @@ * If the name space has not been initialized, * there is nothing to dump. */ - ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "name space not initialized!\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "namespace not initialized!\n")); return_VOID; } - if (NS_ALL == search_base) { + if (ACPI_NS_ALL == search_base) { /* entire namespace */ search_handle = acpi_gbl_root_node; @@ -671,10 +637,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_dump_entry + * FUNCTION: acpi_ns_dump_entry * * PARAMETERS: Handle - Node to be dumped - * Debug_level - Output level + * debug_level - Output level * * DESCRIPTION: Dump a single Node * @@ -682,19 +648,20 @@ void acpi_ns_dump_entry ( - acpi_handle handle, - u32 debug_level) + acpi_handle handle, + u32 debug_level) { - acpi_walk_info info; + struct acpi_walk_info info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); info.debug_level = debug_level; info.owner_id = ACPI_UINT32_MAX; + info.display_type = ACPI_DISPLAY_SUMMARY; - acpi_ns_dump_one_object (handle, 1, &info, NULL); + (void) acpi_ns_dump_one_object (handle, 1, &info, NULL); } #endif diff -urN linux-2.4.21/drivers/acpi/namespace/nsdumpdv.c linux-2.4.22/drivers/acpi/namespace/nsdumpdv.c --- linux-2.4.21/drivers/acpi/namespace/nsdumpdv.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/namespace/nsdumpdv.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,145 @@ +/****************************************************************************** + * + * Module Name: nsdump - table dumping routines for debug + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include +#include + + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsdumpdv") + + +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) + +/******************************************************************************* + * + * FUNCTION: acpi_ns_dump_one_device + * + * PARAMETERS: Handle - Node to be dumped + * Level - Nesting level of the handle + * Context - Passed into walk_namespace + * + * DESCRIPTION: Dump a single Node that represents a device + * This procedure is a user_function called by acpi_ns_walk_namespace. + * + ******************************************************************************/ + +acpi_status +acpi_ns_dump_one_device ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) +{ + struct acpi_buffer buffer; + struct acpi_device_info *info; + acpi_status status; + u32 i; + + + ACPI_FUNCTION_NAME ("ns_dump_one_device"); + + + status = acpi_ns_dump_one_object (obj_handle, level, context, return_value); + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_get_object_info (obj_handle, &buffer); + if (ACPI_SUCCESS (status)) { + info = buffer.pointer; + for (i = 0; i < level; i++) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); + } + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", + info->hardware_id.value, + ACPI_HIDWORD (info->address), ACPI_LODWORD (info->address), + info->current_status)); + ACPI_MEM_FREE (info); + } + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_dump_root_devices + * + * PARAMETERS: None + * + * DESCRIPTION: Dump all objects of type "device" + * + ******************************************************************************/ + +void +acpi_ns_dump_root_devices (void) +{ + acpi_handle sys_bus_handle; + acpi_status status; + + + ACPI_FUNCTION_NAME ("ns_dump_root_devices"); + + + /* Only dump the table if tracing is enabled */ + + if (!(ACPI_LV_TABLES & acpi_dbg_level)) { + return; + } + + status = acpi_get_handle (0, ACPI_NS_SYSTEM_BUS, &sys_bus_handle); + if (ACPI_FAILURE (status)) { + return; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n")); + + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle, + ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, + acpi_ns_dump_one_device, NULL, NULL); +} + +#endif + + diff -urN linux-2.4.21/drivers/acpi/namespace/nseval.c linux-2.4.22/drivers/acpi/namespace/nseval.c --- linux-2.4.21/drivers/acpi/namespace/nseval.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nseval.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,51 +2,68 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 102 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acparser.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nseval") + ACPI_MODULE_NAME ("nseval") /******************************************************************************* * - * FUNCTION: Acpi_ns_evaluate_relative + * FUNCTION: acpi_ns_evaluate_relative * * PARAMETERS: Handle - The relative containing object - * *Pathname - Name of method to execute, If NULL, the + * Pathname - Name of method to execute, If NULL, the * handle is the object to execute - * **Params - List of parameters to pass to the method, + * Params - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. - * *Return_object - Where to put method's return value (if + * return_object - Where to put method's return value (if * any). If NULL, no value is returned. * * RETURN: Status @@ -60,19 +77,19 @@ acpi_status acpi_ns_evaluate_relative ( - acpi_namespace_node *handle, - NATIVE_CHAR *pathname, - acpi_operand_object **params, - acpi_operand_object **return_object) + struct acpi_namespace_node *handle, + char *pathname, + union acpi_operand_object **params, + union acpi_operand_object **return_object) { - acpi_namespace_node *prefix_node; - acpi_status status; - acpi_namespace_node *node = NULL; - NATIVE_CHAR *internal_path = NULL; - acpi_generic_state scope_info; + struct acpi_namespace_node *prefix_node; + acpi_status status; + struct acpi_namespace_node *node = NULL; + char *internal_path = NULL; + union acpi_generic_state scope_info; - FUNCTION_TRACE ("Ns_evaluate_relative"); + ACPI_FUNCTION_TRACE ("ns_evaluate_relative"); /* @@ -91,11 +108,14 @@ /* Get the prefix handle and Node */ - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } prefix_node = acpi_ns_map_handle_to_node (handle); if (!prefix_node) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); status = AE_BAD_PARAMETER; goto cleanup; } @@ -104,13 +124,13 @@ scope_info.scope.node = prefix_node; status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, - IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, + ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, &node); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object [%s] not found [%s]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n", pathname, acpi_format_exception (status))); goto cleanup; } @@ -119,12 +139,12 @@ * Now that we have a handle to the object, we can attempt * to evaluate it. */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %p\n", - pathname, node, node->object)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", + pathname, node, acpi_ns_get_attached_object (node))); status = acpi_ns_evaluate_by_handle (node, params, return_object); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", pathname)); cleanup: @@ -136,12 +156,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_evaluate_by_name + * FUNCTION: acpi_ns_evaluate_by_name * * PARAMETERS: Pathname - Fully qualified pathname to the object - * *Return_object - Where to put method's return value (if + * return_object - Where to put method's return value (if * any). If NULL, no value is returned. - * **Params - List of parameters to pass to the method, + * Params - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. * @@ -156,16 +176,16 @@ acpi_status acpi_ns_evaluate_by_name ( - NATIVE_CHAR *pathname, - acpi_operand_object **params, - acpi_operand_object **return_object) + char *pathname, + union acpi_operand_object **params, + union acpi_operand_object **return_object) { - acpi_status status; - acpi_namespace_node *node = NULL; - NATIVE_CHAR *internal_path = NULL; + acpi_status status; + struct acpi_namespace_node *node = NULL; + char *internal_path = NULL; - FUNCTION_TRACE ("Ns_evaluate_by_name"); + ACPI_FUNCTION_TRACE ("ns_evaluate_by_name"); /* Build an internal name string for the method */ @@ -175,18 +195,21 @@ return_ACPI_STATUS (status); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Lookup the name in the namespace */ status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, - IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, + ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, &node); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object at [%s] was not found, status=%.4X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object at [%s] was not found, status=%.4X\n", pathname, status)); goto cleanup; } @@ -195,12 +218,12 @@ * Now that we have a handle to the object, we can attempt * to evaluate it. */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %p\n", - pathname, node, node->object)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", + pathname, node, acpi_ns_get_attached_object (node))); status = acpi_ns_evaluate_by_handle (node, params, return_object); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", pathname)); @@ -218,13 +241,13 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_evaluate_by_handle + * FUNCTION: acpi_ns_evaluate_by_handle * * PARAMETERS: Handle - Method Node to execute - * **Params - List of parameters to pass to the method, + * Params - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. - * *Return_object - Where to put method's return value (if + * return_object - Where to put method's return value (if * any). If NULL, no value is returned. * * RETURN: Status @@ -237,16 +260,16 @@ acpi_status acpi_ns_evaluate_by_handle ( - acpi_namespace_node *handle, - acpi_operand_object **params, - acpi_operand_object **return_object) + struct acpi_namespace_node *handle, + union acpi_operand_object **params, + union acpi_operand_object **return_object) { - acpi_namespace_node *node; - acpi_status status; - acpi_operand_object *local_return_object; + struct acpi_namespace_node *node; + acpi_status status; + union acpi_operand_object *local_return_object; - FUNCTION_TRACE ("Ns_evaluate_by_handle"); + ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle"); /* Check if namespace has been initialized */ @@ -269,15 +292,17 @@ /* Get the prefix handle and Node */ - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } node = acpi_ns_map_handle_to_node (handle); if (!node) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* * Two major cases here: * 1) The object is an actual control method -- execute it. @@ -285,7 +310,7 @@ * value * * In both cases, the namespace is unlocked by the - * Acpi_ns* procedure + * acpi_ns* procedure */ if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) { /* @@ -294,7 +319,6 @@ status = acpi_ns_execute_control_method (node, params, &local_return_object); } - else { /* * Case 2) Object is NOT a method, just return its @@ -303,7 +327,6 @@ status = acpi_ns_get_object_value (node, &local_return_object); } - /* * Check if there is a return value on the stack that must * be dealt with @@ -323,16 +346,13 @@ *return_object = local_return_object; } + /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ - /* Map AE_RETURN_VALUE to AE_OK, we are done with it */ - - if (status == AE_CTRL_RETURN_VALUE) { - status = AE_OK; - } + status = AE_OK; } /* - * Namespace was unlocked by the handling Acpi_ns* function, + * Namespace was unlocked by the handling acpi_ns* function, * so we just return */ return_ACPI_STATUS (status); @@ -341,13 +361,13 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_execute_control_method + * FUNCTION: acpi_ns_execute_control_method * - * PARAMETERS: Method_node - The object/method - * **Params - List of parameters to pass to the method, + * PARAMETERS: method_node - The method to execute + * Params - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. - * **Return_obj_desc - List of result objects to be returned + * return_obj_desc - List of result objects to be returned * from the method. * * RETURN: Status @@ -360,15 +380,15 @@ acpi_status acpi_ns_execute_control_method ( - acpi_namespace_node *method_node, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc) + struct acpi_namespace_node *method_node, + union acpi_operand_object **params, + union acpi_operand_object **return_obj_desc) { - acpi_status status; - acpi_operand_object *obj_desc; + acpi_status status; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE ("Ns_execute_control_method"); + ACPI_FUNCTION_TRACE ("ns_execute_control_method"); /* Verify that there is a method associated with this object */ @@ -377,21 +397,16 @@ if (!obj_desc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n")); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (AE_NULL_OBJECT); } + ACPI_DUMP_PATHNAME (method_node, "Execute Method:", + ACPI_LV_INFO, _COMPONENT); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Control method at Offset %p Length %x]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1)); - DUMP_PATHNAME (method_node, "Ns_execute_control_method: Executing", - ACPI_LV_NAMES, _COMPONENT); - - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "At offset %p\n", - obj_desc->method.aml_start + 1)); - - /* * Unlock the namespace before execution. This allows namespace access * via the external Acpi* interfaces while a method is being executed. @@ -399,7 +414,10 @@ * interpreter locks to ensure that no thread is using the portion of the * namespace that is being deleted. */ - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* * Execute the method via the interpreter. The interpreter is locked @@ -419,129 +437,79 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_get_object_value + * FUNCTION: acpi_ns_get_object_value * - * PARAMETERS: Node - The object + * PARAMETERS: Node - The object + * return_obj_desc - Where the objects value is returned * * RETURN: Status * * DESCRIPTION: Return the current value of the object * - * MUTEX: Assumes namespace is locked + * MUTEX: Assumes namespace is locked, leaves namespace unlocked * ******************************************************************************/ acpi_status acpi_ns_get_object_value ( - acpi_namespace_node *node, - acpi_operand_object **return_obj_desc) + struct acpi_namespace_node *node, + union acpi_operand_object **return_obj_desc) { - acpi_status status = AE_OK; - acpi_operand_object *obj_desc; - acpi_operand_object *source_desc; + acpi_status status = AE_OK; + struct acpi_namespace_node *resolved_node = node; - FUNCTION_TRACE ("Ns_get_object_value"); + ACPI_FUNCTION_TRACE ("ns_get_object_value"); /* - * We take the value from certain objects directly + * Objects require additional resolution steps (e.g., the + * Node may be a field that must be read, etc.) -- we can't just grab + * the object out of the node. */ - if ((node->type == ACPI_TYPE_PROCESSOR) || - (node->type == ACPI_TYPE_POWER)) { - /* - * Create a Reference object to contain the object - */ - obj_desc = acpi_ut_create_internal_object (node->type); - if (!obj_desc) { - status = AE_NO_MEMORY; - goto unlock_and_exit; - } - - /* - * Get the attached object - */ - source_desc = acpi_ns_get_attached_object (node); - if (!source_desc) { - status = AE_NULL_OBJECT; - goto unlock_and_exit; - } - - /* - * Just copy from the original to the return object - * - * TBD: [Future] - need a low-level object copy that handles - * the reference count automatically. (Don't want to copy it) - */ - MEMCPY (obj_desc, source_desc, sizeof (acpi_operand_object)); - obj_desc->common.reference_count = 1; - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - } - /* - * Other objects require a reference object wrapper which we - * then attempt to resolve. + * Use resolve_node_to_value() to get the associated value. This call + * always deletes obj_desc (allocated above). + * + * NOTE: we can get away with passing in NULL for a walk state + * because obj_desc is guaranteed to not be a reference to either + * a method local or a method argument (because this interface can only be + * called from the acpi_evaluate external interface, never called from + * a running control method.) + * + * Even though we do not directly invoke the interpreter + * for this, we must enter it because we could access an opregion. + * The opregion access code assumes that the interpreter + * is locked. + * + * We must release the namespace lock before entering the + * intepreter. */ - else { - /* Create an Reference object to contain the object */ - - obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE); - if (!obj_desc) { - status = AE_NO_MEMORY; - goto unlock_and_exit; - } - - /* Construct a descriptor pointing to the name */ - - obj_desc->reference.opcode = (u8) AML_NAME_OP; - obj_desc->reference.object = (void *) node; + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + status = acpi_ex_enter_interpreter (); + if (ACPI_SUCCESS (status)) { + status = acpi_ex_resolve_node_to_value (&resolved_node, NULL); /* - * Use Resolve_to_value() to get the associated value. This call - * always deletes Obj_desc (allocated above). - * - * NOTE: we can get away with passing in NULL for a walk state - * because Obj_desc is guaranteed to not be a reference to either - * a method local or a method argument - * - * Even though we do not directly invoke the interpreter - * for this, we must enter it because we could access an opregion. - * The opregion access code assumes that the interpreter - * is locked. - * - * We must release the namespace lock before entering the - * intepreter. + * If acpi_ex_resolve_node_to_value() succeeded, the return value was + * placed in resolved_node. */ - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - status = acpi_ex_enter_interpreter (); - if (ACPI_SUCCESS (status)) { - status = acpi_ex_resolve_to_value (&obj_desc, NULL); + acpi_ex_exit_interpreter (); - acpi_ex_exit_interpreter (); + if (ACPI_SUCCESS (status)) { + status = AE_CTRL_RETURN_VALUE; + *return_obj_desc = ACPI_CAST_PTR (union acpi_operand_object, resolved_node); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n", + *return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc))); } } - /* - * If Acpi_ex_resolve_to_value() succeeded, the return value was - * placed in Obj_desc. - */ - if (ACPI_SUCCESS (status)) { - status = AE_CTRL_RETURN_VALUE; - - *return_obj_desc = obj_desc; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Returning obj %p\n", *return_obj_desc)); - } - /* Namespace is unlocked */ return_ACPI_STATUS (status); - - -unlock_and_exit: - - /* Unlock the namespace */ - - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return_ACPI_STATUS (status); } + diff -urN linux-2.4.21/drivers/acpi/namespace/nsinit.c linux-2.4.22/drivers/acpi/namespace/nsinit.c --- linux-2.4.21/drivers/acpi/namespace/nsinit.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsinit.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,41 +1,59 @@ /****************************************************************************** * * Module Name: nsinit - namespace initialization - * $Revision: 33 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "acdispat.h" -#include "acinterp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsinit") + ACPI_MODULE_NAME ("nsinit") /******************************************************************************* * - * FUNCTION: Acpi_ns_initialize_objects + * FUNCTION: acpi_ns_initialize_objects * * PARAMETERS: None * @@ -50,24 +68,20 @@ acpi_ns_initialize_objects ( void) { - acpi_status status; - acpi_init_walk_info info; + acpi_status status; + struct acpi_init_walk_info info; - FUNCTION_TRACE ("Ns_initialize_objects"); + ACPI_FUNCTION_TRACE ("ns_initialize_objects"); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Completing Region and Field initialization:")); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Completing Region/Field/Buffer/Package initialization:")); + /* Set all init info to zero */ - info.field_count = 0; - info.field_init = 0; - info.op_region_count = 0; - info.op_region_init = 0; - info.object_count = 0; - + ACPI_MEMSET (&info, 0, sizeof (struct acpi_init_walk_info)); /* Walk entire namespace from the supplied root */ @@ -75,17 +89,21 @@ ACPI_UINT32_MAX, acpi_ns_init_one_object, &info, NULL); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed! %x\n", status)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n", + acpi_format_exception (status))); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - "\n%d/%d Regions, %d/%d Fields initialized (%d nodes total)\n", - info.op_region_init, info.op_region_count, info.field_init, - info.field_count, info.object_count)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, + "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n", + info.op_region_init, info.op_region_count, + info.field_init, info.field_count, + info.buffer_init, info.buffer_count, + info.package_init, info.package_count, info.object_count)); + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "%d Control Methods found\n", info.method_count)); + "%hd Control Methods found\n", info.method_count)); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "%d Op Regions found\n", info.op_region_count)); + "%hd Op Regions found\n", info.op_region_count)); return_ACPI_STATUS (AE_OK); } @@ -93,7 +111,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_initialize_devices + * FUNCTION: acpi_ns_initialize_devices * * PARAMETERS: None * @@ -111,30 +129,33 @@ acpi_ns_initialize_devices ( void) { - acpi_status status; - acpi_device_walk_info info; + acpi_status status; + struct acpi_device_walk_info info; + + ACPI_FUNCTION_TRACE ("ns_initialize_devices"); - FUNCTION_TRACE ("Ns_initialize_devices"); + /* Init counters */ info.device_count = 0; info.num_STA = 0; info.num_INI = 0; + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Executing all Device _STA and_INI methods:")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Executing device _INI methods:")); + /* Walk namespace for all objects of type Device */ status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, FALSE, acpi_ns_init_one_device, &info, NULL); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed! %x\n", status)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n", + acpi_format_exception (status))); } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - "\n%d Devices found: %d _STA, %d _INI\n", + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, + "\n%hd Devices found containing: %hd _STA, %hd _INI methods\n", info.device_count, info.num_STA, info.num_INI)); return_ACPI_STATUS (status); @@ -143,16 +164,16 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_init_one_object + * FUNCTION: acpi_ns_init_one_object * - * PARAMETERS: Obj_handle - Node + * PARAMETERS: obj_handle - Node * Level - Current nesting level * Context - Points to a init info struct - * Return_value - Not used + * return_value - Not used * * RETURN: Status * - * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object + * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object * within the namespace. * * Currently, the only objects that require initialization are: @@ -163,37 +184,62 @@ acpi_status acpi_ns_init_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value) + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) { - acpi_object_type8 type; - acpi_status status; - acpi_init_walk_info *info = (acpi_init_walk_info *) context; - acpi_namespace_node *node = (acpi_namespace_node *) obj_handle; - acpi_operand_object *obj_desc; + acpi_object_type type; + acpi_status status; + struct acpi_init_walk_info *info = (struct acpi_init_walk_info *) context; + struct acpi_namespace_node *node = (struct acpi_namespace_node *) obj_handle; + union acpi_operand_object *obj_desc; - PROC_NAME ("Ns_init_one_object"); + ACPI_FUNCTION_NAME ("ns_init_one_object"); info->object_count++; - /* And even then, we are only interested in a few object types */ type = acpi_ns_get_type (obj_handle); - obj_desc = node->object; + obj_desc = acpi_ns_get_attached_object (node); if (!obj_desc) { return (AE_OK); } - if ((type != ACPI_TYPE_REGION) && - (type != ACPI_TYPE_BUFFER_FIELD)) { + /* Increment counters for object types we are looking for */ + + switch (type) { + case ACPI_TYPE_REGION: + info->op_region_count++; + break; + + case ACPI_TYPE_BUFFER_FIELD: + info->field_count++; + break; + + case ACPI_TYPE_BUFFER: + info->buffer_count++; + break; + + case ACPI_TYPE_PACKAGE: + info->package_count++; + break; + + default: + + /* No init required, just exit now */ return (AE_OK); } + /* + * If the object is already initialized, nothing else to do + */ + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + return (AE_OK); + } /* * Must lock the interpreter before executing AML code @@ -203,61 +249,59 @@ return (status); } + /* + * Each of these types can contain executable AML code within + * the declaration. + */ switch (type) { - case ACPI_TYPE_REGION: - info->op_region_count++; - if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { - break; - } - info->op_region_init++; status = acpi_ds_get_region_arguments (obj_desc); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n")); - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "%s while getting region arguments [%4.4s]\n", - acpi_format_exception (status), (char*)&node->name)); - } - - if (!(acpi_dbg_level & ACPI_LV_INIT)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); - } - break; case ACPI_TYPE_BUFFER_FIELD: - info->field_count++; - if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { - break; - } - info->field_init++; status = acpi_ds_get_buffer_field_arguments (obj_desc); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n")); - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "%s while getting buffer field arguments [%4.4s]\n", - acpi_format_exception (status), (char*)&node->name)); - } - if (!(acpi_dbg_level & ACPI_LV_INIT)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); - } + break; + + case ACPI_TYPE_BUFFER: + info->buffer_init++; + status = acpi_ds_get_buffer_arguments (obj_desc); + break; + + + case ACPI_TYPE_PACKAGE: + + info->package_init++; + status = acpi_ds_get_package_arguments (obj_desc); break; default: + /* No other types can get here */ break; } + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not execute arguments for [%4.4s] (%s), %s\n", + node->name.ascii, acpi_ut_get_type_name (type), acpi_format_exception (status))); + } + + /* Print a dot for each object unless we are going to print the entire pathname */ + + if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); + } /* * We ignore errors from above, and always return OK, since - * we don't want to abort the walk on a single error. + * we don't want to abort the walk on any single error. */ acpi_ex_exit_interpreter (); return (AE_OK); @@ -266,7 +310,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_init_one_device + * FUNCTION: acpi_ns_init_one_device * * PARAMETERS: acpi_walk_callback * @@ -280,40 +324,46 @@ acpi_status acpi_ns_init_one_device ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value) { - acpi_status status; - acpi_namespace_node *node; - u32 flags; - acpi_device_walk_info *info = (acpi_device_walk_info *) context; + acpi_status status; + struct acpi_namespace_node *node; + u32 flags; + struct acpi_device_walk_info *info = (struct acpi_device_walk_info *) context; - FUNCTION_TRACE ("Ns_init_one_device"); + ACPI_FUNCTION_TRACE ("ns_init_one_device"); - if (!(acpi_dbg_level & ACPI_LV_INIT)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); + if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); } info->device_count++; - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } node = acpi_ns_map_handle_to_node (obj_handle); if (!node) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return (AE_BAD_PARAMETER); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (AE_BAD_PARAMETER); } - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* * Run _STA to determine if we can run _INI on the device. */ - DEBUG_EXEC (acpi_ut_display_init_pathname (node, "_STA [Method]")); + ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA")); status = acpi_ut_execute_STA (node, &flags); if (ACPI_FAILURE (status)) { /* Ignore error and move on to next device */ @@ -329,36 +379,41 @@ return_ACPI_STATUS(AE_CTRL_DEPTH); } - /* * The device is present. Run _INI. */ - DEBUG_EXEC (acpi_ut_display_init_pathname (obj_handle, "_INI [Method]")); + ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, obj_handle, "_INI")); status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL); - if (AE_NOT_FOUND == status) { - /* No _INI means device requires no initialization */ + if (ACPI_FAILURE (status)) { + /* No _INI (AE_NOT_FOUND) means device requires no initialization */ - status = AE_OK; - } + if (status != AE_NOT_FOUND) { + /* Ignore error and move on to next device */ - else if (ACPI_FAILURE (status)) { - /* Ignore error and move on to next device */ + #ifdef ACPI_DEBUG_OUTPUT + char *scope_name = acpi_ns_get_external_pathname (obj_handle); -#ifdef ACPI_DEBUG - NATIVE_CHAR *scope_name = acpi_ns_get_table_pathname (obj_handle); + ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n", + scope_name, acpi_format_exception (status))); - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n", - scope_name, acpi_format_exception (status))); + ACPI_MEM_FREE (scope_name); + #endif + } - ACPI_MEM_FREE (scope_name); -#endif + status = AE_OK; } - else { /* Count of successful INIs */ info->num_INI++; } - return_ACPI_STATUS (AE_OK); + if (acpi_gbl_init_handler) { + /* External initialization handler is present, call it */ + + status = acpi_gbl_init_handler (obj_handle, ACPI_INIT_DEVICE_INI); + } + + + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/namespace/nsload.c linux-2.4.22/drivers/acpi/namespace/nsload.c --- linux-2.4.21/drivers/acpi/namespace/nsload.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsload.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,239 +1,91 @@ /****************************************************************************** * * Module Name: nsload - namespace loading/expanding/contracting procedures - * $Revision: 47 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "amlcode.h" -#include "acparser.h" -#include "acdispat.h" -#include "acdebug.h" +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsload") + ACPI_MODULE_NAME ("nsload") -/******************************************************************************* - * - * FUNCTION: Acpi_load_namespace - * - * PARAMETERS: Display_aml_during_load - * - * RETURN: Status - * - * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. - * (DSDT points to either the BIOS or a buffer.) - * - ******************************************************************************/ - -acpi_status -acpi_ns_load_namespace ( - void) -{ - acpi_status status; - - - FUNCTION_TRACE ("Acpi_load_name_space"); - - - /* There must be at least a DSDT installed */ - - if (acpi_gbl_DSDT == NULL) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n")); - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } - - - /* - * Load the namespace. The DSDT is required, - * but the SSDT and PSDT tables are optional. - */ - status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Ignore exceptions from these */ - - acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); - acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); - - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - "ACPI Namespace successfully loaded at root %p\n", - acpi_gbl_root_node)); - - - return_ACPI_STATUS (status); -} - +#ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* * - * FUNCTION: Acpi_ns_one_parse_pass + * FUNCTION: acpi_ns_load_table * - * PARAMETERS: + * PARAMETERS: table_desc - Descriptor for table to be loaded + * Node - Owning NS node * * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Load one ACPI table into the namespace * ******************************************************************************/ acpi_status -acpi_ns_one_complete_parse ( - u32 pass_number, - acpi_table_desc *table_desc) +acpi_ns_load_table ( + struct acpi_table_desc *table_desc, + struct acpi_namespace_node *node) { - acpi_parse_object *parse_root; - acpi_status status; - acpi_walk_state *walk_state; + acpi_status status; - FUNCTION_TRACE ("Ns_one_complete_parse"); - - - /* Create and init a Root Node */ - - parse_root = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!parse_root) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - ((acpi_parse2_object *) parse_root)->name = ACPI_ROOT_NAME; + ACPI_FUNCTION_TRACE ("ns_load_table"); - /* Create and initialize a new walk state */ + /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - NULL, NULL, NULL); - if (!walk_state) { - acpi_ps_free_op (parse_root); - return_ACPI_STATUS (AE_NO_MEMORY); - } + if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) { + /* Just ignore this table */ - status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, table_desc->aml_start, - table_desc->aml_length, NULL, NULL, pass_number); - if (ACPI_FAILURE (status)) { - acpi_ds_delete_walk_state (walk_state); - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } - /* Parse the AML */ - - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", pass_number)); - status = acpi_ps_parse_aml (walk_state); - - acpi_ps_delete_parse_tree (parse_root); - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_parse_table - * - * PARAMETERS: Table_desc - An ACPI table descriptor for table to parse - * Start_node - Where to enter the table into the namespace - * - * RETURN: Status - * - * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops - * - ******************************************************************************/ - -acpi_status -acpi_ns_parse_table ( - acpi_table_desc *table_desc, - acpi_namespace_node *start_node) -{ - acpi_status status; - - - FUNCTION_TRACE ("Ns_parse_table"); - - - /* - * AML Parse, pass 1 - * - * In this pass, we load most of the namespace. Control methods - * are not parsed until later. A parse tree is not created. Instead, - * each Parser Op subtree is deleted when it is finished. This saves - * a great deal of memory, and allows a small cache of parse objects - * to service the entire parse. The second pass of the parse then - * performs another complete parse of the AML.. - */ - status = acpi_ns_one_complete_parse (1, table_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - - /* - * AML Parse, pass 2 - * - * In this pass, we resolve forward references and other things - * that could not be completed during the first pass. - * Another complete parse of the AML is performed, but the - * overhead of this is compensated for by the fact that the - * parse objects are all cached. - */ - status = acpi_ns_one_complete_parse (2, table_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_load_table - * - * PARAMETERS: Table_desc - Descriptor for table to be loaded - * Node - Owning NS node - * - * RETURN: Status - * - * DESCRIPTION: Load one ACPI table into the namespace - * - ******************************************************************************/ - -acpi_status -acpi_ns_load_table ( - acpi_table_desc *table_desc, - acpi_namespace_node *node) -{ - acpi_status status; - - - FUNCTION_TRACE ("Ns_load_table"); - + /* Check validity of the AML start and length */ if (!table_desc->aml_start) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null AML pointer\n")); @@ -242,13 +94,13 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n", table_desc->aml_start)); + /* Ignore table if there is no AML contained within */ if (!table_desc->aml_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Zero-length AML block\n")); - return_ACPI_STATUS (AE_BAD_PARAMETER); + ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n", table_desc->pointer->signature)); + return_ACPI_STATUS (AE_OK); } - /* * Parse the table and load the namespace with all named * objects found within. Control methods are NOT parsed @@ -260,9 +112,13 @@ */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + status = acpi_ns_parse_table (table_desc, node->child); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); @@ -288,9 +144,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_load_table_by_type + * FUNCTION: acpi_ns_load_table_by_type * - * PARAMETERS: Table_type - Id of the table type to load + * PARAMETERS: table_type - Id of the table type to load * * RETURN: Status * @@ -302,30 +158,31 @@ acpi_status acpi_ns_load_table_by_type ( - acpi_table_type table_type) + acpi_table_type table_type) { - u32 i; - acpi_status status = AE_OK; - acpi_table_desc *table_desc; - + u32 i; + acpi_status status; + struct acpi_table_desc *table_desc; - FUNCTION_TRACE ("Ns_load_table_by_type"); + ACPI_FUNCTION_TRACE ("ns_load_table_by_type"); - acpi_ut_acquire_mutex (ACPI_MTX_TABLES); + status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* * Table types supported are: * DSDT (one), SSDT/PSDT (multiple) */ switch (table_type) { - case ACPI_TABLE_DSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n")); - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_DSDT]; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next; /* If table already loaded into namespace, just return */ @@ -333,8 +190,6 @@ goto unlock_and_exit; } - table_desc->table_id = TABLE_ID_DSDT; - /* Now load the single DSDT */ status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); @@ -348,13 +203,13 @@ case ACPI_TABLE_SSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n", - acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count)); + acpi_gbl_table_lists[ACPI_TABLE_SSDT].count)); /* * Traverse list of SSDT tables */ - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT]; - for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) { + table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next; + for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) { /* * Only attempt to load table if it is not * already loaded! @@ -376,14 +231,14 @@ case ACPI_TABLE_PSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n", - acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count)); + acpi_gbl_table_lists[ACPI_TABLE_PSDT].count)); /* * Traverse list of PSDT tables */ - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT]; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next; - for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) { + for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) { /* Only attempt to load table if it is not already loaded! */ if (!table_desc->loaded_into_namespace) { @@ -408,43 +263,92 @@ unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (status); +} - acpi_ut_release_mutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (status); +/******************************************************************************* + * + * FUNCTION: acpi_load_namespace + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. + * (DSDT points to either the BIOS or a buffer.) + * + ******************************************************************************/ + +acpi_status +acpi_ns_load_namespace ( + void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE ("acpi_load_name_space"); + + + /* There must be at least a DSDT installed */ + + if (acpi_gbl_DSDT == NULL) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n")); + return_ACPI_STATUS (AE_NO_ACPI_TABLES); + } + + /* + * Load the namespace. The DSDT is required, + * but the SSDT and PSDT tables are optional. + */ + status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Ignore exceptions from these */ + + (void) acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); + (void) acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, + "ACPI Namespace successfully loaded at root %p\n", + acpi_gbl_root_node)); + + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ns_delete_subtree + * FUNCTION: acpi_ns_delete_subtree * - * PARAMETERS: Start_handle - Handle in namespace where search begins + * PARAMETERS: start_handle - Handle in namespace where search begins * * RETURNS Status * * DESCRIPTION: Walks the namespace starting at the given handle and deletes * all objects, entries, and scopes in the entire subtree. * - * TBD: [Investigate] What if any part of this subtree is in use? - * (i.e. on one of the object stacks?) + * Namespace/Interpreter should be locked or the subsystem should + * be in shutdown before this routine is called. * ******************************************************************************/ acpi_status acpi_ns_delete_subtree ( - acpi_handle start_handle) + acpi_handle start_handle) { - acpi_status status; - acpi_handle child_handle; - acpi_handle parent_handle; - acpi_handle next_child_handle; - acpi_handle dummy; - u32 level; + acpi_status status; + acpi_handle child_handle; + acpi_handle parent_handle; + acpi_handle next_child_handle; + acpi_handle dummy; + u32 level; - FUNCTION_TRACE ("Ns_delete_subtree"); + ACPI_FUNCTION_TRACE ("ns_delete_subtree"); parent_handle = start_handle; @@ -463,7 +367,6 @@ child_handle = next_child_handle; - /* Did we get a new object? */ if (ACPI_SUCCESS (status)) { @@ -480,7 +383,6 @@ child_handle = 0; } } - else { /* * No more children in this object, go back up to @@ -493,7 +395,10 @@ acpi_ns_delete_children (child_handle); child_handle = parent_handle; - acpi_get_parent (parent_handle, &parent_handle); + status = acpi_get_parent (parent_handle, &parent_handle); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } } @@ -507,7 +412,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_unload_name_space + * FUNCTION: acpi_ns_unload_name_space * * PARAMETERS: Handle - Root of namespace subtree to be deleted * @@ -521,12 +426,12 @@ acpi_status acpi_ns_unload_namespace ( - acpi_handle handle) + acpi_handle handle) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Ns_unload_name_space"); + ACPI_FUNCTION_TRACE ("ns_unload_name_space"); /* Parameter validation */ @@ -539,7 +444,6 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* This function does the real work */ status = acpi_ns_delete_subtree (handle); @@ -547,4 +451,5 @@ return_ACPI_STATUS (status); } +#endif diff -urN linux-2.4.21/drivers/acpi/namespace/nsnames.c linux-2.4.22/drivers/acpi/namespace/nsnames.c --- linux-2.4.21/drivers/acpi/namespace/nsnames.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsnames.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,126 +1,175 @@ /******************************************************************************* * * Module Name: nsnames - Name manipulation and search - * $Revision: 64 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsnames") + ACPI_MODULE_NAME ("nsnames") /******************************************************************************* * - * FUNCTION: Acpi_ns_get_table_pathname + * FUNCTION: acpi_ns_build_external_path * - * PARAMETERS: Node - Scope whose name is needed + * PARAMETERS: Node - NS node whose pathname is needed + * Size - Size of the pathname + * *name_buffer - Where to return the pathname * - * RETURN: Pointer to storage containing the fully qualified name of - * the scope, in Label format (all segments strung together - * with no separators) + * RETURN: Places the pathname into the name_buffer, in external format + * (name segments separated by path separators) * - * DESCRIPTION: Used for debug printing in Acpi_ns_search_table(). + * DESCRIPTION: Generate a full pathaname * ******************************************************************************/ -NATIVE_CHAR * -acpi_ns_get_table_pathname ( - acpi_namespace_node *node) +void +acpi_ns_build_external_path ( + struct acpi_namespace_node *node, + acpi_size size, + char *name_buffer) { - NATIVE_CHAR *name_buffer; - u32 size; - acpi_name name; - acpi_namespace_node *child_node; - acpi_namespace_node *parent_node; + acpi_size index; + struct acpi_namespace_node *parent_node; - FUNCTION_TRACE_PTR ("Ns_get_table_pathname", node); + ACPI_FUNCTION_NAME ("ns_build_external_path"); - if (!acpi_gbl_root_node || !node) { - /* - * If the name space has not been initialized, - * this function should not have been called. - */ - return_PTR (NULL); + /* Special case for root */ + + index = size - 1; + if (index < ACPI_NAME_SIZE) { + name_buffer[0] = AML_ROOT_PREFIX; + name_buffer[1] = 0; + return; } - child_node = node->child; + /* Store terminator byte, then build name backwards */ + parent_node = node; + name_buffer[index] = 0; - /* Calculate required buffer size based on depth below root */ + while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) { + index -= ACPI_NAME_SIZE; + + /* Put the name into the buffer */ - size = 1; - parent_node = child_node; - while (parent_node) { - parent_node = acpi_ns_get_parent_object (parent_node); - if (parent_node) { - size += ACPI_NAME_SIZE; - } + ACPI_MOVE_32_TO_32 ((name_buffer + index), &parent_node->name); + parent_node = acpi_ns_get_parent_node (parent_node); + + /* Prefix name with the path separator */ + + index--; + name_buffer[index] = ACPI_PATH_SEPARATOR; } + /* Overwrite final separator with the root prefix character */ - /* Allocate a buffer to be returned to caller */ + name_buffer[index] = AML_ROOT_PREFIX; - name_buffer = ACPI_MEM_CALLOCATE (size + 1); - if (!name_buffer) { - REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n")); - return_PTR (NULL); + if (index != 0) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not construct pathname; index=%X, size=%X, Path=%s\n", + (u32) index, (u32) size, &name_buffer[size])); } + return; +} - /* Store terminator byte, then build name backwards */ - name_buffer[size] = '\0'; - while ((size > ACPI_NAME_SIZE) && - acpi_ns_get_parent_object (child_node)) { - size -= ACPI_NAME_SIZE; - name = acpi_ns_find_parent_name (child_node); +#ifdef ACPI_DEBUG_OUTPUT +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_external_pathname + * + * PARAMETERS: Node - NS node whose pathname is needed + * + * RETURN: Pointer to storage containing the fully qualified name of + * the node, In external format (name segments separated by path + * separators.) + * + * DESCRIPTION: Used for debug printing in acpi_ns_search_table(). + * + ******************************************************************************/ - /* Put the name into the buffer */ +char * +acpi_ns_get_external_pathname ( + struct acpi_namespace_node *node) +{ + char *name_buffer; + acpi_size size; + + + ACPI_FUNCTION_TRACE_PTR ("ns_get_external_pathname", node); - MOVE_UNALIGNED32_TO_32 ((name_buffer + size), &name); - child_node = acpi_ns_get_parent_object (child_node); - } - name_buffer[--size] = AML_ROOT_PREFIX; + /* Calculate required buffer size based on depth below root */ + + size = acpi_ns_get_pathname_length (node); + + /* Allocate a buffer to be returned to caller */ - if (size != 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad pointer returned; size=%X\n", size)); + name_buffer = ACPI_MEM_CALLOCATE (size); + if (!name_buffer) { + ACPI_REPORT_ERROR (("ns_get_table_pathname: allocation failure\n")); + return_PTR (NULL); } + /* Build the path in the allocated buffer */ + + acpi_ns_build_external_path (node, size, name_buffer); return_PTR (name_buffer); } +#endif /******************************************************************************* * - * FUNCTION: Acpi_ns_get_pathname_length + * FUNCTION: acpi_ns_get_pathname_length * * PARAMETERS: Node - Namespace node * @@ -130,31 +179,27 @@ * ******************************************************************************/ -u32 +acpi_size acpi_ns_get_pathname_length ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { - u32 size; - acpi_namespace_node *next_node; + acpi_size size; + struct acpi_namespace_node *next_node; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* * Compute length of pathname as 5 * number of name segments. * Go back up the parent tree to the root */ - for (size = 0, next_node = node; - acpi_ns_get_parent_object (next_node); - next_node = acpi_ns_get_parent_object (next_node)) { - size += PATH_SEGMENT_LENGTH; - } - - /* Special case for size still 0 - no parent for "special" nodes */ + size = 0; + next_node = node; - if (!size) { - size = PATH_SEGMENT_LENGTH; + while (next_node && (next_node != acpi_gbl_root_node)) { + size += ACPI_PATH_SEGMENT_LENGTH; + next_node = acpi_ns_get_parent_node (next_node); } return (size + 1); @@ -163,100 +208,53 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_handle_to_pathname + * FUNCTION: acpi_ns_handle_to_pathname * - * PARAMETERS: Target_handle - Handle of named object whose name is + * PARAMETERS: target_handle - Handle of named object whose name is * to be found - * Buf_size - Size of the buffer provided - * User_buffer - Where the pathname is returned + * Buffer - Where the pathname is returned * * RETURN: Status, Buffer is filled with pathname if status is AE_OK * * DESCRIPTION: Build and return a full namespace pathname * - * MUTEX: Locks Namespace - * ******************************************************************************/ acpi_status acpi_ns_handle_to_pathname ( - acpi_handle target_handle, - u32 *buf_size, - NATIVE_CHAR *user_buffer) + acpi_handle target_handle, + struct acpi_buffer *buffer) { - acpi_status status = AE_OK; - acpi_namespace_node *node; - u32 path_length; - u32 user_buf_size; - acpi_name name; - u32 size; - - - FUNCTION_TRACE_PTR ("Ns_handle_to_pathname", target_handle); - - - if (!acpi_gbl_root_node) { - /* - * If the name space has not been initialized, - * this function should not have been called. - */ - return_ACPI_STATUS (AE_NO_NAMESPACE); - } + acpi_status status; + struct acpi_namespace_node *node; + acpi_size required_size; - node = acpi_ns_map_handle_to_node (target_handle); - if (!node) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - - /* Set return length to the required path length */ - - path_length = acpi_ns_get_pathname_length (node); - size = path_length - 1; - user_buf_size = *buf_size; - *buf_size = path_length; + ACPI_FUNCTION_TRACE_PTR ("ns_handle_to_pathname", target_handle); - /* Check if the user buffer is sufficiently large */ - if (path_length > user_buf_size) { - status = AE_BUFFER_OVERFLOW; - goto exit; + node = acpi_ns_map_handle_to_node (target_handle); + if (!node) { + return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Store null terminator */ + /* Determine size required for the caller buffer */ - user_buffer[size] = 0; - size -= ACPI_NAME_SIZE; + required_size = acpi_ns_get_pathname_length (node); - /* Put the original ACPI name at the end of the path */ + /* Validate/Allocate/Clear caller buffer */ - MOVE_UNALIGNED32_TO_32 ((user_buffer + size), - &node->name); - - user_buffer[--size] = PATH_SEPARATOR; - - /* Build name backwards, putting "." between segments */ - - while ((size > ACPI_NAME_SIZE) && node) { - size -= ACPI_NAME_SIZE; - name = acpi_ns_find_parent_name (node); - MOVE_UNALIGNED32_TO_32 ((user_buffer + size), &name); - - user_buffer[--size] = PATH_SEPARATOR; - node = acpi_ns_get_parent_object (node); + status = acpi_ut_initialize_buffer (buffer, required_size); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - /* - * Overlay the "." preceding the first segment with - * the root name "\" - */ - user_buffer[size] = '\\'; + /* Build the path in the caller buffer */ - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Len=%X, %s \n", path_length, user_buffer)); + acpi_ns_build_external_path (node, required_size, buffer->pointer); -exit: - return_ACPI_STATUS (status); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X] \n", (char *) buffer->pointer, (u32) required_size)); + return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/namespace/nsobject.c linux-2.4.22/drivers/acpi/namespace/nsobject.c --- linux-2.4.21/drivers/acpi/namespace/nsobject.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsobject.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,43 +2,58 @@ * * Module Name: nsobject - Utilities for objects attached to namespace * table entries - * $Revision: 67 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsobject") + ACPI_MODULE_NAME ("nsobject") /******************************************************************************* * - * FUNCTION: Acpi_ns_attach_object + * FUNCTION: acpi_ns_attach_object * * PARAMETERS: Node - Parent Node * Object - Object to be attached @@ -48,6 +63,8 @@ * DESCRIPTION: Record the given object as the value associated with the * name whose acpi_handle is passed. If Object is NULL * and Type is ACPI_TYPE_ANY, set the name as having no value. + * Note: Future may require that the Node->Flags field be passed + * as a parameter. * * MUTEX: Assumes namespace is locked * @@ -55,206 +72,169 @@ acpi_status acpi_ns_attach_object ( - acpi_namespace_node *node, - acpi_operand_object *object, - acpi_object_type8 type) + struct acpi_namespace_node *node, + union acpi_operand_object *object, + acpi_object_type type) { - acpi_operand_object *obj_desc; - acpi_operand_object *previous_obj_desc; - acpi_object_type8 obj_type = ACPI_TYPE_ANY; - u8 flags; + union acpi_operand_object *obj_desc; + union acpi_operand_object *last_obj_desc; + acpi_object_type object_type = ACPI_TYPE_ANY; - FUNCTION_TRACE ("Ns_attach_object"); + ACPI_FUNCTION_TRACE ("ns_attach_object"); /* * Parameter validation */ - if (!acpi_gbl_root_node) { - /* Name space not initialized */ - - REPORT_ERROR (("Ns_attach_object: Namespace not initialized\n")); - return_ACPI_STATUS (AE_NO_NAMESPACE); - } - if (!node) { /* Invalid handle */ - REPORT_ERROR (("Ns_attach_object: Null Named_obj handle\n")); + ACPI_REPORT_ERROR (("ns_attach_object: Null named_obj handle\n")); return_ACPI_STATUS (AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { /* Null object */ - REPORT_ERROR (("Ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n")); + ACPI_REPORT_ERROR (("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n")); return_ACPI_STATUS (AE_BAD_PARAMETER); } - if (!VALID_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED)) { + if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) { /* Not a name handle */ - REPORT_ERROR (("Ns_attach_object: Invalid handle\n")); + ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle\n")); return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Check if this object is already attached */ if (node->object == object) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj %p already installed in Name_obj %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj %p already installed in name_obj %p\n", object, node)); return_ACPI_STATUS (AE_OK); } - - /* Get the current flags field of the Node */ - - flags = node->flags; - flags &= ~ANOBJ_AML_ATTACHMENT; - - /* If null object, we will just install it */ if (!object) { - obj_desc = NULL; - obj_type = ACPI_TYPE_ANY; + obj_desc = NULL; + object_type = ACPI_TYPE_ANY; } /* * If the source object is a namespace Node with an attached object, * we will use that (attached) object */ - else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED) && - ((acpi_namespace_node *) object)->object) { + else if ((ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) && + ((struct acpi_namespace_node *) object)->object) { /* * Value passed is a name handle and that name has a * non-null value. Use that name's value and type. */ - obj_desc = ((acpi_namespace_node *) object)->object; - obj_type = ((acpi_namespace_node *) object)->type; - - /* - * Copy appropriate flags - */ - if (((acpi_namespace_node *) object)->flags & ANOBJ_AML_ATTACHMENT) { - flags |= ANOBJ_AML_ATTACHMENT; - } + obj_desc = ((struct acpi_namespace_node *) object)->object; + object_type = ((struct acpi_namespace_node *) object)->type; } - /* * Otherwise, we will use the parameter object, but we must type * it first */ else { - obj_desc = (acpi_operand_object *) object; + obj_desc = (union acpi_operand_object *) object; - /* If a valid type (non-ANY) was given, just use it */ - - if (ACPI_TYPE_ANY != type) { - obj_type = type; - } + /* Use the given type */ - else { - /* - * Cannot figure out the type -- set to Def_any which - * will print as an error in the name table dump - */ - if (acpi_dbg_level > 0) { - DUMP_PATHNAME (node, - "Ns_attach_object confused: setting bogus type for ", - ACPI_LV_INFO, _COMPONENT); - - if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) { - DUMP_PATHNAME (object, "name ", ACPI_LV_INFO, _COMPONENT); - } - - else { - DUMP_PATHNAME (object, "object ", ACPI_LV_INFO, _COMPONENT); - DUMP_STACK_ENTRY (object); - } - } - - obj_type = INTERNAL_TYPE_DEF_ANY; - } + object_type = type; } - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n", - obj_desc, node, (char*)&node->name)); + obj_desc, node, node->name.ascii)); + /* Detach an existing attached object if present */ - /* - * Must increment the new value's reference count - * (if it is an internal object) - */ - acpi_ut_add_reference (obj_desc); - - /* Save the existing object (if any) for deletion later */ - - previous_obj_desc = node->object; - - /* Install the object and set the type, flags */ - - node->object = obj_desc; - node->type = (u8) obj_type; - node->flags |= flags; - + if (node->object) { + acpi_ns_detach_object (node); + } - /* - * Delete an existing attached object. - */ - if (previous_obj_desc) { - /* One for the attach to the Node */ + if (obj_desc) { + /* + * Must increment the new value's reference count + * (if it is an internal object) + */ + acpi_ut_add_reference (obj_desc); - acpi_ut_remove_reference (previous_obj_desc); + /* + * Handle objects with multiple descriptors - walk + * to the end of the descriptor list + */ + last_obj_desc = obj_desc; + while (last_obj_desc->common.next_object) { + last_obj_desc = last_obj_desc->common.next_object; + } - /* Now delete */ + /* Install the object at the front of the object list */ - acpi_ut_remove_reference (previous_obj_desc); + last_obj_desc->common.next_object = node->object; } + node->type = (u8) object_type; + node->object = obj_desc; + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ns_detach_object + * FUNCTION: acpi_ns_detach_object * - * PARAMETERS: Node - An object whose Value will be deleted + * PARAMETERS: Node - An node whose object will be detached * * RETURN: None. * - * DESCRIPTION: Delete the Value associated with a namespace object. If the - * Value is an allocated object, it is freed. Otherwise, the - * field is simply cleared. + * DESCRIPTION: Detach/delete an object associated with a namespace node. + * if the object is an allocated object, it is freed. + * Otherwise, the field is simply cleared. * ******************************************************************************/ void acpi_ns_detach_object ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { - acpi_operand_object *obj_desc; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE ("Ns_detach_object"); + ACPI_FUNCTION_TRACE ("ns_detach_object"); obj_desc = node->object; - if (!obj_desc) { + + if (!obj_desc || + (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA)) { return_VOID; } /* Clear the entry in all cases */ node->object = NULL; + if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) { + node->object = obj_desc->common.next_object; + if (node->object && + (ACPI_GET_OBJECT_TYPE (node->object) != ACPI_TYPE_LOCAL_DATA)) { + node->object = node->object->common.next_object; + } + } + + /* Reset the node type to untyped */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object=%p Value=%p Name %4.4s\n", - node, obj_desc, (char*)&node->name)); + node->type = ACPI_TYPE_ANY; + + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n", + node, node->name.ascii, obj_desc)); /* Remove one reference on the object (and all subobjects) */ @@ -265,30 +245,216 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_get_attached_object + * FUNCTION: acpi_ns_get_attached_object * * PARAMETERS: Node - Parent Node to be examined * * RETURN: Current value of the object field from the Node whose * handle is passed * + * DESCRIPTION: Obtain the object attached to a namespace node. + * ******************************************************************************/ -void * +union acpi_operand_object * acpi_ns_get_attached_object ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { - FUNCTION_TRACE_PTR ("Ns_get_attached_object", node); + ACPI_FUNCTION_TRACE_PTR ("ns_get_attached_object", node); if (!node) { - /* handle invalid */ - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Null Node ptr\n")); return_PTR (NULL); } + if (!node->object || + ((ACPI_GET_DESCRIPTOR_TYPE (node->object) != ACPI_DESC_TYPE_OPERAND) && + (ACPI_GET_DESCRIPTOR_TYPE (node->object) != ACPI_DESC_TYPE_NAMED)) || + (ACPI_GET_OBJECT_TYPE (node->object) == ACPI_TYPE_LOCAL_DATA)) { + return_PTR (NULL); + } + return_PTR (node->object); } +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_secondary_object + * + * PARAMETERS: Node - Parent Node to be examined + * + * RETURN: Current value of the object field from the Node whose + * handle is passed. + * + * DESCRIPTION: Obtain a secondary object associated with a namespace node. + * + ******************************************************************************/ + +union acpi_operand_object * +acpi_ns_get_secondary_object ( + union acpi_operand_object *obj_desc) +{ + ACPI_FUNCTION_TRACE_PTR ("ns_get_secondary_object", obj_desc); + + + if ((!obj_desc) || + (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) || + (!obj_desc->common.next_object) || + (ACPI_GET_OBJECT_TYPE (obj_desc->common.next_object) == ACPI_TYPE_LOCAL_DATA)) { + return_PTR (NULL); + } + + return_PTR (obj_desc->common.next_object); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_attach_data + * + * PARAMETERS: Node - Namespace node + * Handler - Handler to be associated with the data + * Data - Data to be attached + * + * RETURN: Status + * + * DESCRIPTION: Low-level attach data. Create and attach a Data object. + * + ******************************************************************************/ + +acpi_status +acpi_ns_attach_data ( + struct acpi_namespace_node *node, + acpi_object_handler handler, + void *data) +{ + union acpi_operand_object *prev_obj_desc; + union acpi_operand_object *obj_desc; + union acpi_operand_object *data_desc; + + + /* We only allow one attachment per handler */ + + prev_obj_desc = NULL; + obj_desc = node->object; + while (obj_desc) { + if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) && + (obj_desc->data.handler == handler)) { + return (AE_ALREADY_EXISTS); + } + + prev_obj_desc = obj_desc; + obj_desc = obj_desc->common.next_object; + } + + /* Create an internal object for the data */ + + data_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_DATA); + if (!data_desc) { + return (AE_NO_MEMORY); + } + + data_desc->data.handler = handler; + data_desc->data.pointer = data; + + /* Install the data object */ + + if (prev_obj_desc) { + prev_obj_desc->common.next_object = data_desc; + } + else { + node->object = data_desc; + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_detach_data + * + * PARAMETERS: Node - Namespace node + * Handler - Handler associated with the data + * + * RETURN: Status + * + * DESCRIPTION: Low-level detach data. Delete the data node, but the caller + * is responsible for the actual data. + * + ******************************************************************************/ + +acpi_status +acpi_ns_detach_data ( + struct acpi_namespace_node *node, + acpi_object_handler handler) +{ + union acpi_operand_object *obj_desc; + union acpi_operand_object *prev_obj_desc; + + + prev_obj_desc = NULL; + obj_desc = node->object; + while (obj_desc) { + if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) && + (obj_desc->data.handler == handler)) { + if (prev_obj_desc) { + prev_obj_desc->common.next_object = obj_desc->common.next_object; + } + else { + node->object = obj_desc->common.next_object; + } + + acpi_ut_remove_reference (obj_desc); + return (AE_OK); + } + + prev_obj_desc = obj_desc; + obj_desc = obj_desc->common.next_object; + } + + return (AE_NOT_FOUND); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_attached_data + * + * PARAMETERS: Node - Namespace node + * Handler - Handler associated with the data + * Data - Where the data is returned + * + * RETURN: Status + * + * DESCRIPTION: Low level interface to obtain data previously associated with + * a namespace node. + * + ******************************************************************************/ + +acpi_status +acpi_ns_get_attached_data ( + struct acpi_namespace_node *node, + acpi_object_handler handler, + void **data) +{ + union acpi_operand_object *obj_desc; + + + obj_desc = node->object; + while (obj_desc) { + if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) && + (obj_desc->data.handler == handler)) { + *data = obj_desc->data.pointer; + return (AE_OK); + } + + obj_desc = obj_desc->common.next_object; + } + + return (AE_NOT_FOUND); +} + + diff -urN linux-2.4.21/drivers/acpi/namespace/nsparse.c linux-2.4.22/drivers/acpi/namespace/nsparse.c --- linux-2.4.21/drivers/acpi/namespace/nsparse.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/namespace/nsparse.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,170 @@ +/****************************************************************************** + * + * Module Name: nsparse - namespace interface to AML parser + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include +#include +#include +#include + + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsparse") + + +/******************************************************************************* + * + * FUNCTION: ns_one_complete_parse + * + * PARAMETERS: pass_number - 1 or 2 + * table_desc - The table to be parsed. + * + * RETURN: Status + * + * DESCRIPTION: Perform one complete parse of an ACPI/AML table. + * + ******************************************************************************/ + +acpi_status +acpi_ns_one_complete_parse ( + u32 pass_number, + struct acpi_table_desc *table_desc) +{ + union acpi_parse_object *parse_root; + acpi_status status; + struct acpi_walk_state *walk_state; + + + ACPI_FUNCTION_TRACE ("ns_one_complete_parse"); + + + /* Create and init a Root Node */ + + parse_root = acpi_ps_create_scope_op (); + if (!parse_root) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Create and initialize a new walk state */ + + walk_state = acpi_ds_create_walk_state (table_desc->table_id, + NULL, NULL, NULL); + if (!walk_state) { + acpi_ps_free_op (parse_root); + return_ACPI_STATUS (AE_NO_MEMORY); + } + + status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, table_desc->aml_start, + table_desc->aml_length, NULL, NULL, pass_number); + if (ACPI_FAILURE (status)) { + acpi_ds_delete_walk_state (walk_state); + return_ACPI_STATUS (status); + } + + /* Parse the AML */ + + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", pass_number)); + status = acpi_ps_parse_aml (walk_state); + + acpi_ps_delete_parse_tree (parse_root); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_parse_table + * + * PARAMETERS: table_desc - An ACPI table descriptor for table to parse + * start_node - Where to enter the table into the namespace + * + * RETURN: Status + * + * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops + * + ******************************************************************************/ + +acpi_status +acpi_ns_parse_table ( + struct acpi_table_desc *table_desc, + struct acpi_namespace_node *start_node) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ns_parse_table"); + + + /* + * AML Parse, pass 1 + * + * In this pass, we load most of the namespace. Control methods + * are not parsed until later. A parse tree is not created. Instead, + * each Parser Op subtree is deleted when it is finished. This saves + * a great deal of memory, and allows a small cache of parse objects + * to service the entire parse. The second pass of the parse then + * performs another complete parse of the AML.. + */ + status = acpi_ns_one_complete_parse (1, table_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* + * AML Parse, pass 2 + * + * In this pass, we resolve forward references and other things + * that could not be completed during the first pass. + * Another complete parse of the AML is performed, but the + * overhead of this is compensated for by the fact that the + * parse objects are all cached. + */ + status = acpi_ns_one_complete_parse (2, table_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + return_ACPI_STATUS (status); +} + + diff -urN linux-2.4.21/drivers/acpi/namespace/nssearch.c linux-2.4.22/drivers/acpi/namespace/nssearch.c --- linux-2.4.21/drivers/acpi/namespace/nssearch.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nssearch.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,52 +1,69 @@ /******************************************************************************* * * Module Name: nssearch - Namespace search - * $Revision: 75 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nssearch") + ACPI_MODULE_NAME ("nssearch") /******************************************************************************* * - * FUNCTION: Acpi_ns_search_node + * FUNCTION: acpi_ns_search_node * - * PARAMETERS: *Target_name - Ascii ACPI name to search for - * *Node - Starting table where search will begin + * PARAMETERS: *target_name - Ascii ACPI name to search for + * *Node - Starting node where search will begin * Type - Object type to match - * **Return_node - Where the matched Named obj is returned + * **return_node - Where the matched Named obj is returned * * RETURN: Status * - * DESCRIPTION: Search a single namespace table. Performs a simple search, - * does not add entries or search parents. + * DESCRIPTION: Search a single level of the namespace. Performs a + * simple search of the specified level, and does not add + * entries or search parents. * * * Named object lists are built (and subsequently dumped) in the @@ -62,75 +79,52 @@ acpi_status acpi_ns_search_node ( - u32 target_name, - acpi_namespace_node *node, - acpi_object_type8 type, - acpi_namespace_node **return_node) + u32 target_name, + struct acpi_namespace_node *node, + acpi_object_type type, + struct acpi_namespace_node **return_node) { - acpi_namespace_node *next_node; + struct acpi_namespace_node *next_node; - FUNCTION_TRACE ("Ns_search_node"); + ACPI_FUNCTION_TRACE ("ns_search_node"); -#ifdef ACPI_DEBUG +#ifdef ACPI_DEBUG_OUTPUT if (ACPI_LV_NAMES & acpi_dbg_level) { - NATIVE_CHAR *scope_name; + char *scope_name; - scope_name = acpi_ns_get_table_pathname (node); + scope_name = acpi_ns_get_external_pathname (node); if (scope_name) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s [%p] For %4.4s (type %X)\n", - scope_name, node, (char*)&target_name, type)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s [%p] For %4.4s (%s)\n", + scope_name, node, (char *) &target_name, acpi_ut_get_type_name (type))); ACPI_MEM_FREE (scope_name); } } #endif - /* - * Search for name in this table, which is to say that we must search - * for the name among the children of this object + * Search for name at this namespace level, which is to say that we + * must search for the name among the children of this object */ next_node = node->child; while (next_node) { /* Check for match against the name */ - if (next_node->name == target_name) { - /* - * Found matching entry. Capture the type if appropriate, before - * returning the entry. - * - * The Def_field_defn and Bank_field_defn cases are actually looking up - * the Region in which the field will be defined - */ - if ((INTERNAL_TYPE_FIELD_DEFN == type) || - (INTERNAL_TYPE_BANK_FIELD_DEFN == type)) { - type = ACPI_TYPE_REGION; - } - + if (next_node->name.integer == target_name) { /* - * Scope, Def_any, and Index_field_defn are bogus "types" which do not - * actually have anything to do with the type of the name being - * looked up. For any other value of Type, if the type stored in - * the entry is Any (i.e. unknown), save the actual type. + * Found matching entry. */ - if (type != INTERNAL_TYPE_SCOPE && - type != INTERNAL_TYPE_DEF_ANY && - type != INTERNAL_TYPE_INDEX_FIELD_DEFN && - next_node->type == ACPI_TYPE_ANY) { - next_node->type = (u8) type; - } - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Name %4.4s (actual type %X) found at %p\n", - (char*)&target_name, next_node->type, next_node)); + "Name %4.4s Type [%s] found in scope [%4.4s] %p\n", + (char *) &target_name, acpi_ut_get_type_name (next_node->type), + next_node->name.ascii, next_node)); *return_node = next_node; return_ACPI_STATUS (AE_OK); } - /* * The last entry in the list points back to the parent, * so a flag is used to indicate the end-of-list @@ -146,11 +140,12 @@ next_node = next_node->peer; } + /* Searched entire namespace level, not found */ - /* Searched entire table, not found */ - - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name %4.4s (type %X) not found at %p\n", - (char*)&target_name, type, next_node)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Name %4.4s Type [%s] not found in search in scope [%4.4s] %p first child %p\n", + (char *) &target_name, acpi_ut_get_type_name (type), + node->name.ascii, node, node->child)); return_ACPI_STATUS (AE_NOT_FOUND); } @@ -158,18 +153,18 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_search_parent_tree + * FUNCTION: acpi_ns_search_parent_tree * - * PARAMETERS: *Target_name - Ascii ACPI name to search for - * *Node - Starting table where search will begin + * PARAMETERS: *target_name - Ascii ACPI name to search for + * *Node - Starting node where search will begin * Type - Object type to match - * **Return_node - Where the matched Named Obj is returned + * **return_node - Where the matched Named Obj is returned * * RETURN: Status * * DESCRIPTION: Called when a name has not been found in the current namespace - * table. Before adding it or giving up, ACPI scope rules require - * searching enclosing scopes in cases identified by Acpi_ns_local(). + * level. Before adding it or giving up, ACPI scope rules require + * searching enclosing scopes in cases identified by acpi_ns_local(). * * "A name is located by finding the matching name in the current * name space, and then in the parent name space. If the parent @@ -183,55 +178,53 @@ static acpi_status acpi_ns_search_parent_tree ( - u32 target_name, - acpi_namespace_node *node, - acpi_object_type8 type, - acpi_namespace_node **return_node) + u32 target_name, + struct acpi_namespace_node *node, + acpi_object_type type, + struct acpi_namespace_node **return_node) { - acpi_status status; - acpi_namespace_node *parent_node; + acpi_status status; + struct acpi_namespace_node *parent_node; - FUNCTION_TRACE ("Ns_search_parent_tree"); + ACPI_FUNCTION_TRACE ("ns_search_parent_tree"); - parent_node = acpi_ns_get_parent_object (node); + parent_node = acpi_ns_get_parent_node (node); /* - * If there is no parent (at the root) or type is "local", we won't be - * searching the parent tree. + * If there is no parent (i.e., we are at the root) or + * type is "local", we won't be searching the parent tree. */ - if ((acpi_ns_local (type)) || - (!parent_node)) { - if (!parent_node) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n", - (char*)&target_name)); - } - - if (acpi_ns_local (type)) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] type %X is local(no search)\n", - (char*)&target_name, type)); - } + if (!parent_node) { + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n", + (char *) &target_name)); + return_ACPI_STATUS (AE_NOT_FOUND); + } + if (acpi_ns_local (type)) { + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "[%4.4s] type [%s] must be local to this scope (no parent search)\n", + (char *) &target_name, acpi_ut_get_type_name (type))); return_ACPI_STATUS (AE_NOT_FOUND); } - /* Search the parent tree */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching parent for %4.4s\n", (char*)&target_name)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching parent for %4.4s\n", (char *) &target_name)); /* * Search parents until found the target or we have backed up to * the root */ while (parent_node) { - /* Search parent scope */ - /* TBD: [Investigate] Why ACPI_TYPE_ANY? */ - + /* + * Search parent scope. Use TYPE_ANY because we don't care about the + * object type at this point, we only care about the existence of + * the actual name we are searching for. Typechecking comes later. + */ status = acpi_ns_search_node (target_name, parent_node, ACPI_TYPE_ANY, return_node); - if (ACPI_SUCCESS (status)) { return_ACPI_STATUS (status); } @@ -240,10 +233,9 @@ * Not found here, go up another level * (until we reach the root) */ - parent_node = acpi_ns_get_parent_object (parent_node); + parent_node = acpi_ns_get_parent_node (parent_node); } - /* Not found in parent tree */ return_ACPI_STATUS (AE_NOT_FOUND); @@ -252,71 +244,67 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_search_and_enter + * FUNCTION: acpi_ns_search_and_enter * - * PARAMETERS: Target_name - Ascii ACPI name to search for (4 chars) - * Walk_state - Current state of the walk - * *Node - Starting table where search will begin - * Interpreter_mode - Add names only in MODE_Load_pass_x. + * PARAMETERS: target_name - Ascii ACPI name to search for (4 chars) + * walk_state - Current state of the walk + * *Node - Starting node where search will begin + * interpreter_mode - Add names only in ACPI_MODE_LOAD_PASS_x. * Otherwise,search only. * Type - Object type to match * Flags - Flags describing the search restrictions - * **Return_node - Where the Node is returned + * **return_node - Where the Node is returned * * RETURN: Status * - * DESCRIPTION: Search for a name segment in a single name table, + * DESCRIPTION: Search for a name segment in a single namespace level, * optionally adding it if it is not found. If the passed * Type is not Any and the type previously stored in the * entry was Any (i.e. unknown), update the stored type. * - * In IMODE_EXECUTE, search only. + * In ACPI_IMODE_EXECUTE, search only. * In other modes, search and add if not found. * ******************************************************************************/ acpi_status acpi_ns_search_and_enter ( - u32 target_name, - acpi_walk_state *walk_state, - acpi_namespace_node *node, - operating_mode interpreter_mode, - acpi_object_type8 type, - u32 flags, - acpi_namespace_node **return_node) + u32 target_name, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node *node, + acpi_interpreter_mode interpreter_mode, + acpi_object_type type, + u32 flags, + struct acpi_namespace_node **return_node) { - acpi_status status; - acpi_namespace_node *new_node; + acpi_status status; + struct acpi_namespace_node *new_node; - FUNCTION_TRACE ("Ns_search_and_enter"); + ACPI_FUNCTION_TRACE ("ns_search_and_enter"); /* Parameter validation */ if (!node || !target_name || !return_node) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null param- Table %p Name %X Return %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null param: Node %p Name %X return_node %p\n", node, target_name, return_node)); - REPORT_ERROR (("Ns_search_and_enter: bad (null) parameter\n")); + ACPI_REPORT_ERROR (("ns_search_and_enter: Null parameter\n")); return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Name must consist of printable characters */ if (!acpi_ut_valid_acpi_name (target_name)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "*** Bad character in name: %08x *** \n", + ACPI_REPORT_ERROR (("ns_search_and_enter: Bad character in ACPI Name: %X\n", target_name)); - - REPORT_ERROR (("Ns_search_and_enter: Bad character in ACPI Name\n")); return_ACPI_STATUS (AE_BAD_CHARACTER); } + /* Try to find the name in the namespace level specified by the caller */ - /* Try to find the name in the table specified by the caller */ - - *return_node = ENTRY_NOT_FOUND; + *return_node = ACPI_ENTRY_NOT_FOUND; status = acpi_ns_search_node (target_name, node, type, return_node); if (status != AE_NOT_FOUND) { /* @@ -324,8 +312,8 @@ * return the error */ if ((status == AE_OK) && - (flags & NS_ERROR_IF_FOUND)) { - status = AE_EXIST; + (flags & ACPI_NS_ERROR_IF_FOUND)) { + status = AE_ALREADY_EXISTS; } /* @@ -335,9 +323,8 @@ return_ACPI_STATUS (status); } - /* - * Not found in the table. If we are NOT performing the + * The name was not found. If we are NOT performing the * first pass (name entry) of loading the namespace, search * the parent tree (all the way to the root if necessary.) * We don't want to perform the parent search when the @@ -345,10 +332,10 @@ * the search when namespace references are being resolved * (load pass 2) and during the execution phase. */ - if ((interpreter_mode != IMODE_LOAD_PASS1) && - (flags & NS_SEARCH_PARENT)) { + if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) && + (flags & ACPI_NS_SEARCH_PARENT)) { /* - * Not found in table - search parent tree according + * Not found at this level - search parent tree according * to ACPI specification */ status = acpi_ns_search_parent_tree (target_name, node, @@ -358,18 +345,16 @@ } } - /* * In execute mode, just search, never add names. Exit now. */ - if (interpreter_mode == IMODE_EXECUTE) { + if (interpreter_mode == ACPI_IMODE_EXECUTE) { ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s Not found in %p [Not adding]\n", - (char*)&target_name, node)); + (char *) &target_name, node)); return_ACPI_STATUS (AE_NOT_FOUND); } - /* Create the new named object */ new_node = acpi_ns_create_node (target_name); diff -urN linux-2.4.21/drivers/acpi/namespace/nsutils.c linux-2.4.22/drivers/acpi/namespace/nsutils.c --- linux-2.4.21/drivers/acpi/namespace/nsutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsutils.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,42 +2,198 @@ * * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing * parents and siblings and Scope manipulation - * $Revision: 92 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "amlcode.h" -#include "actables.h" +#include +#include +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsutils") + ACPI_MODULE_NAME ("nsutils") /******************************************************************************* * - * FUNCTION: Acpi_ns_valid_root_prefix + * FUNCTION: acpi_ns_report_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * component_id - Caller's component ID (for error output) + * Message - Error message to use on failure + * + * RETURN: None + * + * DESCRIPTION: Print warning message with full pathname + * + ******************************************************************************/ + +void +acpi_ns_report_error ( + char *module_name, + u32 line_number, + u32 component_id, + char *internal_name, + acpi_status lookup_status) +{ + acpi_status status; + char *name = NULL; + + + acpi_os_printf ("%8s-%04d: *** Error: Looking up ", + module_name, line_number); + + if (lookup_status == AE_BAD_CHARACTER) { + /* There is a non-ascii character in the name */ + + acpi_os_printf ("[0x%4.4X] (NON-ASCII)\n", *(ACPI_CAST_PTR (u32, internal_name))); + } + else { + /* Convert path to external format */ + + status = acpi_ns_externalize_name (ACPI_UINT32_MAX, internal_name, NULL, &name); + + /* Print target name */ + + if (ACPI_SUCCESS (status)) { + acpi_os_printf ("[%s]", name); + } + else { + acpi_os_printf ("[COULD NOT EXTERNALIZE NAME]"); + } + + if (name) { + ACPI_MEM_FREE (name); + } + } + + acpi_os_printf (" in namespace, %s\n", + acpi_format_exception (lookup_status)); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_report_method_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * component_id - Caller's component ID (for error output) + * Message - Error message to use on failure + * + * RETURN: None + * + * DESCRIPTION: Print warning message with full pathname + * + ******************************************************************************/ + +void +acpi_ns_report_method_error ( + char *module_name, + u32 line_number, + u32 component_id, + char *message, + struct acpi_namespace_node *prefix_node, + char *path, + acpi_status method_status) +{ + acpi_status status; + struct acpi_namespace_node *node = prefix_node; + + + if (path) { + status = acpi_ns_get_node_by_path (path, prefix_node, ACPI_NS_NO_UPSEARCH, &node); + if (ACPI_FAILURE (status)) { + acpi_os_printf ("report_method_error: Could not get node\n"); + return; + } + } + + acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number); + acpi_ns_print_node_pathname (node, message); + acpi_os_printf (", %s\n", acpi_format_exception (method_status)); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_print_node_pathname + * + * PARAMETERS: Node - Object + * Msg - Prefix message + * + * DESCRIPTION: Print an object's full namespace pathname + * Manages allocation/freeing of a pathname buffer + * + ******************************************************************************/ + +void +acpi_ns_print_node_pathname ( + struct acpi_namespace_node *node, + char *msg) +{ + struct acpi_buffer buffer; + acpi_status status; + + + /* Convert handle to a full pathname and print it (with supplied message) */ + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + + status = acpi_ns_handle_to_pathname (node, &buffer); + if (ACPI_SUCCESS (status)) { + if (msg) { + acpi_os_printf ("%s ", msg); + } + + acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node); + ACPI_MEM_FREE (buffer.pointer); + } +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_valid_root_prefix * * PARAMETERS: Prefix - Character to be checked * @@ -49,7 +205,7 @@ u8 acpi_ns_valid_root_prefix ( - NATIVE_CHAR prefix) + char prefix) { return ((u8) (prefix == '\\')); @@ -58,7 +214,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_valid_path_separator + * FUNCTION: acpi_ns_valid_path_separator * * PARAMETERS: Sep - Character to be checked * @@ -70,7 +226,7 @@ u8 acpi_ns_valid_path_separator ( - NATIVE_CHAR sep) + char sep) { return ((u8) (sep == '.')); @@ -79,7 +235,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_get_type + * FUNCTION: acpi_ns_get_type * * PARAMETERS: Handle - Parent Node to be examined * @@ -87,25 +243,25 @@ * ******************************************************************************/ -acpi_object_type8 +acpi_object_type acpi_ns_get_type ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { - FUNCTION_TRACE ("Ns_get_type"); + ACPI_FUNCTION_TRACE ("ns_get_type"); if (!node) { - REPORT_WARNING (("Ns_get_type: Null Node ptr")); + ACPI_REPORT_WARNING (("ns_get_type: Null Node ptr")); return_VALUE (ACPI_TYPE_ANY); } - return_VALUE (node->type); + return_VALUE ((acpi_object_type) node->type); } /******************************************************************************* * - * FUNCTION: Acpi_ns_local + * FUNCTION: acpi_ns_local * * PARAMETERS: Type - A namespace object type * @@ -116,25 +272,25 @@ u32 acpi_ns_local ( - acpi_object_type8 type) + acpi_object_type type) { - FUNCTION_TRACE ("Ns_local"); + ACPI_FUNCTION_TRACE ("ns_local"); if (!acpi_ut_valid_object_type (type)) { /* Type code out of range */ - REPORT_WARNING (("Ns_local: Invalid Object Type\n")); - return_VALUE (NSP_NORMAL); + ACPI_REPORT_WARNING (("ns_local: Invalid Object Type\n")); + return_VALUE (ACPI_NS_NORMAL); } - return_VALUE ((u32) acpi_gbl_ns_properties[type] & NSP_LOCAL); + return_VALUE ((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); } /******************************************************************************* * - * FUNCTION: Acpi_ns_get_internal_name_length + * FUNCTION: acpi_ns_get_internal_name_length * * PARAMETERS: Info - Info struct initialized with the * external name pointer. @@ -146,15 +302,15 @@ * ******************************************************************************/ -acpi_status +void acpi_ns_get_internal_name_length ( - acpi_namestring_info *info) + struct acpi_namestring_info *info) { - NATIVE_CHAR *next_external_char; - u32 i; + char *next_external_char; + u32 i; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); next_external_char = info->external_name; @@ -164,18 +320,17 @@ /* * For the internal name, the required length is 4 bytes - * per segment, plus 1 each for Root_prefix, Multi_name_prefix_op, + * per segment, plus 1 each for root_prefix, multi_name_prefix_op, * segment count, trailing null (which is not really needed, * but no there's harm in putting it there) * - * strlen() + 1 covers the first Name_seg, which has no + * strlen() + 1 covers the first name_seg, which has no * path separator */ if (acpi_ns_valid_root_prefix (next_external_char[0])) { info->fully_qualified = TRUE; next_external_char++; } - else { /* * Handle Carat prefixes @@ -205,14 +360,12 @@ 4 + info->num_carats; info->next_external_char = next_external_char; - - return (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ns_build_internal_name + * FUNCTION: acpi_ns_build_internal_name * * PARAMETERS: Info - Info struct fully initialized * @@ -225,16 +378,16 @@ acpi_status acpi_ns_build_internal_name ( - acpi_namestring_info *info) + struct acpi_namestring_info *info) { - u32 num_segments = info->num_segments; - NATIVE_CHAR *internal_name = info->internal_name; - NATIVE_CHAR *external_name = info->next_external_char; - NATIVE_CHAR *result = NULL; - u32 i; + u32 num_segments = info->num_segments; + char *internal_name = info->internal_name; + char *external_name = info->next_external_char; + char *result = NULL; + acpi_native_uint i; - FUNCTION_TRACE ("Ns_build_internal_name"); + ACPI_FUNCTION_TRACE ("ns_build_internal_name"); /* Setup the correct prefixes, counts, and pointers */ @@ -255,7 +408,6 @@ result = &internal_name[3]; } } - else { /* * Not fully qualified. @@ -268,23 +420,20 @@ } } - if (num_segments == 1) { + if (num_segments <= 1) { result = &internal_name[i]; } - else if (num_segments == 2) { internal_name[i] = AML_DUAL_NAME_PREFIX; - result = &internal_name[i+1]; + result = &internal_name[(acpi_native_uint) (i+1)]; } - else { internal_name[i] = AML_MULTI_NAME_PREFIX_OP; - internal_name[i+1] = (char) num_segments; - result = &internal_name[i+2]; + internal_name[(acpi_native_uint) (i+1)] = (char) num_segments; + result = &internal_name[(acpi_native_uint) (i+2)]; } } - /* Build the name (minus path separators) */ for (; num_segments; num_segments--) { @@ -295,11 +444,10 @@ result[i] = '_'; } - else { /* Convert the character to uppercase and save it */ - result[i] = (char) TOUPPER (*external_name); + result[i] = (char) ACPI_TOUPPER ((int) *external_name); external_name++; } } @@ -317,18 +465,17 @@ result += ACPI_NAME_SIZE; } - /* Terminate the string */ *result = 0; if (info->fully_qualified) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (abs) \"\\%s\"\n", - internal_name, &internal_name[0])); + internal_name, internal_name)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (rel) \"%s\"\n", - internal_name, &internal_name[2])); + internal_name, internal_name)); } return_ACPI_STATUS (AE_OK); @@ -337,9 +484,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_internalize_name + * FUNCTION: acpi_ns_internalize_name * - * PARAMETERS: *External_name - External representation of name + * PARAMETERS: *external_name - External representation of name * **Converted Name - Where to return the resulting * internal represention of the name * @@ -352,15 +499,15 @@ acpi_status acpi_ns_internalize_name ( - NATIVE_CHAR *external_name, - NATIVE_CHAR **converted_name) + char *external_name, + char **converted_name) { - NATIVE_CHAR *internal_name; - acpi_namestring_info info; - acpi_status status; + char *internal_name; + struct acpi_namestring_info info; + acpi_status status; - FUNCTION_TRACE ("Ns_internalize_name"); + ACPI_FUNCTION_TRACE ("ns_internalize_name"); if ((!external_name) || @@ -369,7 +516,6 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Get the length of the new internal name */ info.external_name = external_name; @@ -398,10 +544,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_externalize_name + * FUNCTION: acpi_ns_externalize_name * - * PARAMETERS: *Internal_name - Internal representation of name - * **Converted_name - Where to return the resulting + * PARAMETERS: *internal_name - Internal representation of name + * **converted_name - Where to return the resulting * external representation of name * * RETURN: Status @@ -413,29 +559,28 @@ acpi_status acpi_ns_externalize_name ( - u32 internal_name_length, - char *internal_name, - u32 *converted_name_length, - char **converted_name) -{ - u32 prefix_length = 0; - u32 names_index = 0; - u32 names_count = 0; - u32 i = 0; - u32 j = 0; + u32 internal_name_length, + char *internal_name, + u32 *converted_name_length, + char **converted_name) +{ + acpi_native_uint names_index = 0; + acpi_native_uint num_segments = 0; + acpi_native_uint required_length; + acpi_native_uint prefix_length = 0; + acpi_native_uint i = 0; + acpi_native_uint j = 0; - FUNCTION_TRACE ("Ns_externalize_name"); + ACPI_FUNCTION_TRACE ("ns_externalize_name"); if (!internal_name_length || !internal_name || - !converted_name_length || !converted_name) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* * Check for a prefix (one '\' | one or more '^'). */ @@ -446,9 +591,12 @@ case '^': for (i = 0; i < internal_name_length; i++) { - if (internal_name[i] != '^') { + if (internal_name[i] == '^') { prefix_length = i + 1; } + else { + break; + } } if (i == internal_name_length) { @@ -456,6 +604,9 @@ } break; + + default: + break; } /* @@ -464,62 +615,61 @@ */ if (prefix_length < internal_name_length) { switch (internal_name[prefix_length]) { + case AML_MULTI_NAME_PREFIX_OP: - /* 4-byte names */ + /* 4-byte names */ - case AML_MULTI_NAME_PREFIX_OP: names_index = prefix_length + 2; - names_count = (u32) internal_name[prefix_length + 1]; + num_segments = (acpi_native_uint) (u8) internal_name[(acpi_native_uint) (prefix_length + 1)]; break; + case AML_DUAL_NAME_PREFIX: - /* two 4-byte names */ + /* Two 4-byte names */ - case AML_DUAL_NAME_PREFIX: names_index = prefix_length + 1; - names_count = 2; + num_segments = 2; break; + case 0: - /* Null_name */ + /* null_name */ - case 0: names_index = 0; - names_count = 0; + num_segments = 0; break; + default: - /* one 4-byte name */ + /* one 4-byte name */ - default: names_index = prefix_length; - names_count = 1; + num_segments = 1; break; } } /* - * Calculate the length of Converted_name, which equals the length + * Calculate the length of converted_name, which equals the length * of the prefix, length of all object names, length of any required * punctuation ('.') between object names, plus the NULL terminator. */ - *converted_name_length = prefix_length + (4 * names_count) + - ((names_count > 0) ? (names_count - 1) : 0) + 1; + required_length = prefix_length + (4 * num_segments) + + ((num_segments > 0) ? (num_segments - 1) : 0) + 1; /* * Check to see if we're still in bounds. If not, there's a problem - * with Internal_name (invalid format). + * with internal_name (invalid format). */ - if (*converted_name_length > internal_name_length) { - REPORT_ERROR (("Ns_externalize_name: Invalid internal name\n")); + if (required_length > internal_name_length) { + ACPI_REPORT_ERROR (("ns_externalize_name: Invalid internal name\n")); return_ACPI_STATUS (AE_BAD_PATHNAME); } /* - * Build Converted_name... + * Build converted_name... */ - - (*converted_name) = ACPI_MEM_CALLOCATE (*converted_name_length); + *converted_name = ACPI_MEM_CALLOCATE (required_length); if (!(*converted_name)) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -530,8 +680,8 @@ (*converted_name)[j++] = internal_name[i]; } - if (names_count > 0) { - for (i = 0; i < names_count; i++) { + if (num_segments > 0) { + for (i = 0; i < num_segments; i++) { if (i > 0) { (*converted_name)[j++] = '.'; } @@ -543,13 +693,17 @@ } } + if (converted_name_length) { + *converted_name_length = (u32) required_length; + } + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ns_map_handle_to_node + * FUNCTION: acpi_ns_map_handle_to_node * * PARAMETERS: Handle - Handle to be converted to an Node * @@ -557,20 +711,21 @@ * * DESCRIPTION: Convert a namespace handle to a real Node * + * Note: Real integer handles allow for more verification + * and keep all pointers within this subsystem. + * ******************************************************************************/ -acpi_namespace_node * +struct acpi_namespace_node * acpi_ns_map_handle_to_node ( - acpi_handle handle) + acpi_handle handle) { - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* - * Simple implementation for now; - * TBD: [Future] Real integer handles allow for more verification - * and keep all pointers within this subsystem! + * Simple implementation. */ if (!handle) { return (NULL); @@ -580,20 +735,19 @@ return (acpi_gbl_root_node); } - /* We can at least attempt to verify the handle */ - if (!VALID_DESCRIPTOR_TYPE (handle, ACPI_DESC_TYPE_NAMED)) { + if (ACPI_GET_DESCRIPTOR_TYPE (handle) != ACPI_DESC_TYPE_NAMED) { return (NULL); } - return ((acpi_namespace_node *) handle); + return ((struct acpi_namespace_node *) handle); } /******************************************************************************* * - * FUNCTION: Acpi_ns_convert_entry_to_handle + * FUNCTION: acpi_ns_convert_entry_to_handle * * PARAMETERS: Node - Node to be converted to a Handle * @@ -605,14 +759,12 @@ acpi_handle acpi_ns_convert_entry_to_handle ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { /* * Simple implementation for now; - * TBD: [Future] Real integer handles allow for more verification - * and keep all pointers within this subsystem! */ return ((acpi_handle) node); @@ -624,7 +776,7 @@ return (NULL); } - if (Node == Acpi_gbl_Root_node) + if (Node == acpi_gbl_root_node) { return (ACPI_ROOT_OBJECT); } @@ -637,7 +789,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_terminate + * FUNCTION: acpi_ns_terminate * * PARAMETERS: none * @@ -650,39 +802,32 @@ void acpi_ns_terminate (void) { - acpi_operand_object *obj_desc; - acpi_namespace_node *this_node; + union acpi_operand_object *obj_desc; - FUNCTION_TRACE ("Ns_terminate"); + ACPI_FUNCTION_TRACE ("ns_terminate"); - this_node = acpi_gbl_root_node; - /* - * 1) Free the entire namespace -- all objects, tables, and stacks + * 1) Free the entire namespace -- all nodes and objects * - * Delete all objects linked to the root - * (additional table descriptors) + * Delete all object descriptors attached to namepsace nodes */ - acpi_ns_delete_namespace_subtree (this_node); + acpi_ns_delete_namespace_subtree (acpi_gbl_root_node); - /* Detach any object(s) attached to the root */ + /* Detach any objects attached to the root */ - obj_desc = acpi_ns_get_attached_object (this_node); + obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node); if (obj_desc) { - acpi_ns_detach_object (this_node); - acpi_ut_remove_reference (obj_desc); + acpi_ns_detach_object (acpi_gbl_root_node); } - acpi_ns_delete_children (this_node); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); - /* * 2) Now we can delete the ACPI tables */ - acpi_tb_delete_acpi_tables (); + acpi_tb_delete_all_tables (); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); return_VOID; @@ -691,7 +836,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_opens_scope + * FUNCTION: acpi_ns_opens_scope * * PARAMETERS: Type - A valid namespace type * @@ -702,34 +847,36 @@ u32 acpi_ns_opens_scope ( - acpi_object_type8 type) + acpi_object_type type) { - FUNCTION_TRACE_U32 ("Ns_opens_scope", type); + ACPI_FUNCTION_TRACE_STR ("ns_opens_scope", acpi_ut_get_type_name (type)); if (!acpi_ut_valid_object_type (type)) { /* type code out of range */ - REPORT_WARNING (("Ns_opens_scope: Invalid Object Type\n")); - return_VALUE (NSP_NORMAL); + ACPI_REPORT_WARNING (("ns_opens_scope: Invalid Object Type %X\n", type)); + return_VALUE (ACPI_NS_NORMAL); } - return_VALUE (((u32) acpi_gbl_ns_properties[type]) & NSP_NEWSCOPE); + return_VALUE (((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); } /******************************************************************************* * - * FUNCTION: Acpi_ns_get_node + * FUNCTION: acpi_ns_get_node_by_path * * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The * \ (backslash) and ^ (carat) prefixes, and the * . (period) to separate segments are supported. - * Start_node - Root of subtree to be searched, or NS_ALL for the + * start_node - Root of subtree to be searched, or NS_ALL for the * root of the name space. If Name is fully * qualified (first s8 is '\'), the passed value * of Scope will not be accessed. - * Return_node - Where the Node is returned + * Flags - Used to indicate whether to perform upsearch or + * not. + * return_node - Where the Node is returned * * DESCRIPTION: Look up a name relative to a given scope and return the * corresponding Node. NOTE: Scope can be null. @@ -739,40 +886,36 @@ ******************************************************************************/ acpi_status -acpi_ns_get_node ( - NATIVE_CHAR *pathname, - acpi_namespace_node *start_node, - acpi_namespace_node **return_node) +acpi_ns_get_node_by_path ( + char *pathname, + struct acpi_namespace_node *start_node, + u32 flags, + struct acpi_namespace_node **return_node) { - acpi_generic_state scope_info; - acpi_status status; - NATIVE_CHAR *internal_path = NULL; + union acpi_generic_state scope_info; + acpi_status status; + char *internal_path = NULL; - FUNCTION_TRACE_PTR ("Ns_get_node", pathname); + ACPI_FUNCTION_TRACE_PTR ("ns_get_node_by_path", pathname); - /* Ensure that the namespace has been initialized */ - - if (!acpi_gbl_root_node) { - return_ACPI_STATUS (AE_NO_NAMESPACE); - } + if (pathname) { + /* Convert path to internal representation */ - if (!pathname) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + status = acpi_ns_internalize_name (pathname, &internal_path); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } + /* Must lock namespace during lookup */ - /* Convert path to internal representation */ - - status = acpi_ns_internalize_name (pathname, &internal_path); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - /* Setup lookup scope (search starting point) */ scope_info.scope.node = start_node; @@ -780,30 +923,30 @@ /* Lookup the name in the namespace */ status = acpi_ns_lookup (&scope_info, internal_path, - ACPI_TYPE_ANY, IMODE_EXECUTE, - NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, + ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, return_node); - if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n", internal_path, acpi_format_exception (status))); } - - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - /* Cleanup */ - ACPI_MEM_FREE (internal_path); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + + if (internal_path) { + ACPI_MEM_FREE (internal_path); + } return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ns_find_parent_name + * FUNCTION: acpi_ns_find_parent_name * - * PARAMETERS: *Child_node - Named Obj whose name is to be found + * PARAMETERS: *child_node - Named Obj whose name is to be found * * RETURN: The ACPI name * @@ -815,75 +958,39 @@ acpi_name acpi_ns_find_parent_name ( - acpi_namespace_node *child_node) + struct acpi_namespace_node *child_node) { - acpi_namespace_node *parent_node; + struct acpi_namespace_node *parent_node; - FUNCTION_TRACE ("Ns_find_parent_name"); + ACPI_FUNCTION_TRACE ("ns_find_parent_name"); if (child_node) { /* Valid entry. Get the parent Node */ - parent_node = acpi_ns_get_parent_object (child_node); + parent_node = acpi_ns_get_parent_node (child_node); if (parent_node) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Parent of %p [%4.4s] is %p [%4.4s]\n", - child_node, (char*)&child_node->name, parent_node, (char*)&parent_node->name)); + child_node, child_node->name.ascii, + parent_node, parent_node->name.ascii)); - if (parent_node->name) { - return_VALUE (parent_node->name); + if (parent_node->name.integer) { + return_VALUE ((acpi_name) parent_node->name.integer); } } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "unable to find parent of %p (%4.4s)\n", - child_node, (char*)&child_node->name)); + child_node, child_node->name.ascii)); } return_VALUE (ACPI_UNKNOWN_NAME); } -#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) - /******************************************************************************* * - * FUNCTION: Acpi_ns_exist_downstream_sibling - * - * PARAMETERS: *Node - pointer to first Node to examine - * - * RETURN: TRUE if sibling is found, FALSE otherwise - * - * DESCRIPTION: Searches remainder of scope being processed to determine - * whether there is a downstream sibling to the current - * object. This function is used to determine what type of - * line drawing character to use when displaying namespace - * trees. - * - ******************************************************************************/ - -u8 -acpi_ns_exist_downstream_sibling ( - acpi_namespace_node *node) -{ - - if (!node) { - return (FALSE); - } - - if (node->name) { - return (TRUE); - } - - return (FALSE); -} - -#endif /* ACPI_DEBUG */ - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_get_parent_object + * FUNCTION: acpi_ns_get_parent_node * * PARAMETERS: Node - Current table entry * @@ -894,13 +1001,11 @@ ******************************************************************************/ -acpi_namespace_node * -acpi_ns_get_parent_object ( - acpi_namespace_node *node) +struct acpi_namespace_node * +acpi_ns_get_parent_node ( + struct acpi_namespace_node *node) { - - - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (!node) { @@ -925,7 +1030,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_get_next_valid_node + * FUNCTION: acpi_ns_get_next_valid_node * * PARAMETERS: Node - Current table entry * @@ -938,9 +1043,9 @@ ******************************************************************************/ -acpi_namespace_node * +struct acpi_namespace_node * acpi_ns_get_next_valid_node ( - acpi_namespace_node *node) + struct acpi_namespace_node *node) { /* If we are at the end of this peer list, return NULL */ diff -urN linux-2.4.21/drivers/acpi/namespace/nswalk.c linux-2.4.22/drivers/acpi/namespace/nswalk.c --- linux-2.4.21/drivers/acpi/namespace/nswalk.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nswalk.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,49 +1,66 @@ /****************************************************************************** * * Module Name: nswalk - Functions for walking the ACPI namespace - * $Revision: 26 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nswalk") + ACPI_MODULE_NAME ("nswalk") /******************************************************************************* * - * FUNCTION: Acpi_ns_get_next_node + * FUNCTION: acpi_ns_get_next_node * * PARAMETERS: Type - Type of node to be searched for - * Parent_node - Parent node whose children we are + * parent_node - Parent node whose children we are * getting - * Child_node - Previous child that was found. + * child_node - Previous child that was found. * The NEXT child will be returned * - * RETURN: acpi_namespace_node - Pointer to the NEXT child or NULL if + * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if * none is found. * * DESCRIPTION: Return the next peer node within the namespace. If Handle @@ -52,16 +69,16 @@ * ******************************************************************************/ -acpi_namespace_node * +struct acpi_namespace_node * acpi_ns_get_next_node ( - acpi_object_type8 type, - acpi_namespace_node *parent_node, - acpi_namespace_node *child_node) + acpi_object_type type, + struct acpi_namespace_node *parent_node, + struct acpi_namespace_node *child_node) { - acpi_namespace_node *next_node = NULL; + struct acpi_namespace_node *next_node = NULL; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (!child_node) { @@ -81,7 +98,7 @@ /* If any type is OK, we are done */ if (type == ACPI_TYPE_ANY) { - /* Next_node is NULL if we are at the end-of-list */ + /* next_node is NULL if we are at the end-of-list */ return (next_node); } @@ -108,22 +125,22 @@ /******************************************************************************* * - * FUNCTION: Acpi_ns_walk_namespace + * FUNCTION: acpi_ns_walk_namespace * * PARAMETERS: Type - acpi_object_type to search for - * Start_node - Handle in namespace where search begins - * Max_depth - Depth to which search is to reach - * Unlock_before_callback- Whether to unlock the NS before invoking + * start_node - Handle in namespace where search begins + * max_depth - Depth to which search is to reach + * unlock_before_callback- Whether to unlock the NS before invoking * the callback routine - * User_function - Called when an object of "Type" is found + * user_function - Called when an object of "Type" is found * Context - Passed to user function - * Return_value - from the User_function if terminated early. + * return_value - from the user_function if terminated early. * Otherwise, returns NULL. * RETURNS: Status * * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, - * starting (and ending) at the node specified by Start_handle. - * The User_function is called whenever a node that matches + * starting (and ending) at the node specified by start_handle. + * The user_function is called whenever a node that matches * the type parameter is found. If the user function returns * a non-zero value, the search is terminated immediately and this * value is returned to the caller. @@ -138,22 +155,23 @@ acpi_status acpi_ns_walk_namespace ( - acpi_object_type8 type, - acpi_handle start_node, - u32 max_depth, - u8 unlock_before_callback, - acpi_walk_callback user_function, - void *context, - void **return_value) + acpi_object_type type, + acpi_handle start_node, + u32 max_depth, + u8 unlock_before_callback, + acpi_walk_callback user_function, + void *context, + void **return_value) { - acpi_status status; - acpi_namespace_node *child_node; - acpi_namespace_node *parent_node; - acpi_object_type8 child_type; - u32 level; + acpi_status status; + acpi_status mutex_status; + struct acpi_namespace_node *child_node; + struct acpi_namespace_node *parent_node; + acpi_object_type child_type; + u32 level; - FUNCTION_TRACE ("Ns_walk_namespace"); + ACPI_FUNCTION_TRACE ("ns_walk_namespace"); /* Special case for the namespace Root Node */ @@ -172,7 +190,7 @@ /* * Traverse the tree of nodes until we bubble back up to where we * started. When Level is zero, the loop is done because we have - * bubbled up to (and passed) the original parent handle (Start_entry) + * bubbled up to (and passed) the original parent handle (start_entry) */ while (level > 0) { /* Get the next node in this scope. Null if not found */ @@ -194,14 +212,20 @@ * callback function */ if (unlock_before_callback) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + mutex_status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (mutex_status)) { + return_ACPI_STATUS (mutex_status); + } } status = user_function (child_node, level, context, return_value); if (unlock_before_callback) { - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + mutex_status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (mutex_status)) { + return_ACPI_STATUS (mutex_status); + } } switch (status) { @@ -216,14 +240,12 @@ /* Exit now, with OK status */ return_ACPI_STATUS (AE_OK); - break; default: /* All others are valid exceptions */ return_ACPI_STATUS (status); - break; } } @@ -247,16 +269,15 @@ } } } - else { /* - * No more children of this node (Acpi_ns_get_next_node + * No more children of this node (acpi_ns_get_next_node * failed), go back upwards in the namespace tree to * the node's parent. */ level--; child_node = parent_node; - parent_node = acpi_ns_get_parent_object (parent_node); + parent_node = acpi_ns_get_parent_node (parent_node); } } diff -urN linux-2.4.21/drivers/acpi/namespace/nsxfeval.c linux-2.4.22/drivers/acpi/namespace/nsxfeval.c --- linux-2.4.21/drivers/acpi/namespace/nsxfeval.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/namespace/nsxfeval.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,747 @@ +/******************************************************************************* + * + * Module Name: nsxfeval - Public interfaces to the ACPI subsystem + * ACPI Object evaluation interfaces + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include +#include + + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsxfeval") + + +/******************************************************************************* + * + * FUNCTION: acpi_evaluate_object_typed + * + * PARAMETERS: Handle - Object handle (optional) + * *Pathname - Object pathname (optional) + * **external_params - List of parameters to pass to method, + * terminated by NULL. May be NULL + * if no parameters are being passed. + * *return_buffer - Where to put method's return value (if + * any). If NULL, no value is returned. + * return_type - Expected type of return object + * + * RETURN: Status + * + * DESCRIPTION: Find and evaluate the given object, passing the given + * parameters if necessary. One of "Handle" or "Pathname" must + * be valid (non-null) + * + ******************************************************************************/ + +acpi_status +acpi_evaluate_object_typed ( + acpi_handle handle, + acpi_string pathname, + struct acpi_object_list *external_params, + struct acpi_buffer *return_buffer, + acpi_object_type return_type) +{ + acpi_status status; + u8 must_free = FALSE; + + + ACPI_FUNCTION_TRACE ("acpi_evaluate_object_typed"); + + + /* Return buffer must be valid */ + + if (!return_buffer) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + if (return_buffer->length == ACPI_ALLOCATE_BUFFER) { + must_free = TRUE; + } + + /* Evaluate the object */ + + status = acpi_evaluate_object (handle, pathname, external_params, return_buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Type ANY means "don't care" */ + + if (return_type == ACPI_TYPE_ANY) { + return_ACPI_STATUS (AE_OK); + } + + if (return_buffer->length == 0) { + /* Error because caller specifically asked for a return value */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No return value\n")); + + return_ACPI_STATUS (AE_NULL_OBJECT); + } + + /* Examine the object type returned from evaluate_object */ + + if (((union acpi_object *) return_buffer->pointer)->type == return_type) { + return_ACPI_STATUS (AE_OK); + } + + /* Return object type does not match requested type */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Incorrect return type [%s] requested [%s]\n", + acpi_ut_get_type_name (((union acpi_object *) return_buffer->pointer)->type), + acpi_ut_get_type_name (return_type))); + + if (must_free) { + /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ + + acpi_os_free (return_buffer->pointer); + return_buffer->pointer = NULL; + } + + return_buffer->length = 0; + return_ACPI_STATUS (AE_TYPE); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_evaluate_object + * + * PARAMETERS: Handle - Object handle (optional) + * *Pathname - Object pathname (optional) + * **external_params - List of parameters to pass to method, + * terminated by NULL. May be NULL + * if no parameters are being passed. + * *return_buffer - Where to put method's return value (if + * any). If NULL, no value is returned. + * + * RETURN: Status + * + * DESCRIPTION: Find and evaluate the given object, passing the given + * parameters if necessary. One of "Handle" or "Pathname" must + * be valid (non-null) + * + ******************************************************************************/ + +acpi_status +acpi_evaluate_object ( + acpi_handle handle, + acpi_string pathname, + struct acpi_object_list *external_params, + struct acpi_buffer *return_buffer) +{ + acpi_status status; + union acpi_operand_object **internal_params = NULL; + union acpi_operand_object *internal_return_obj = NULL; + acpi_size buffer_space_needed; + u32 i; + + + ACPI_FUNCTION_TRACE ("acpi_evaluate_object"); + + + /* + * If there are parameters to be passed to the object + * (which must be a control method), the external objects + * must be converted to internal objects + */ + if (external_params && external_params->count) { + /* + * Allocate a new parameter block for the internal objects + * Add 1 to count to allow for null terminated internal list + */ + internal_params = ACPI_MEM_CALLOCATE (((acpi_size) external_params->count + 1) * + sizeof (void *)); + if (!internal_params) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* + * Convert each external object in the list to an + * internal object + */ + for (i = 0; i < external_params->count; i++) { + status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i], + &internal_params[i]); + if (ACPI_FAILURE (status)) { + acpi_ut_delete_internal_object_list (internal_params); + return_ACPI_STATUS (status); + } + } + internal_params[external_params->count] = NULL; + } + + /* + * Three major cases: + * 1) Fully qualified pathname + * 2) No handle, not fully qualified pathname (error) + * 3) Valid handle + */ + if ((pathname) && + (acpi_ns_valid_root_prefix (pathname[0]))) { + /* + * The path is fully qualified, just evaluate by name + */ + status = acpi_ns_evaluate_by_name (pathname, internal_params, + &internal_return_obj); + } + else if (!handle) { + /* + * A handle is optional iff a fully qualified pathname + * is specified. Since we've already handled fully + * qualified names above, this is an error + */ + if (!pathname) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Both Handle and Pathname are NULL\n")); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Handle is NULL and Pathname is relative\n")); + } + + status = AE_BAD_PARAMETER; + } + else { + /* + * We get here if we have a handle -- and if we have a + * pathname it is relative. The handle will be validated + * in the lower procedures + */ + if (!pathname) { + /* + * The null pathname case means the handle is for + * the actual object to be evaluated + */ + status = acpi_ns_evaluate_by_handle (handle, internal_params, + &internal_return_obj); + } + else { + /* + * Both a Handle and a relative Pathname + */ + status = acpi_ns_evaluate_relative (handle, pathname, internal_params, + &internal_return_obj); + } + } + + + /* + * If we are expecting a return value, and all went well above, + * copy the return value to an external object. + */ + if (return_buffer) { + if (!internal_return_obj) { + return_buffer->length = 0; + } + else { + if (ACPI_GET_DESCRIPTOR_TYPE (internal_return_obj) == ACPI_DESC_TYPE_NAMED) { + /* + * If we received a NS Node as a return object, this means that + * the object we are evaluating has nothing interesting to + * return (such as a mutex, etc.) We return an error because + * these types are essentially unsupported by this interface. + * We don't check up front because this makes it easier to add + * support for various types at a later date if necessary. + */ + status = AE_TYPE; + internal_return_obj = NULL; /* No need to delete a NS Node */ + return_buffer->length = 0; + } + + if (ACPI_SUCCESS (status)) { + /* + * Find out how large a buffer is needed + * to contain the returned object + */ + status = acpi_ut_get_object_size (internal_return_obj, + &buffer_space_needed); + if (ACPI_SUCCESS (status)) { + /* Validate/Allocate/Clear caller buffer */ + + status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed); + if (ACPI_FAILURE (status)) { + /* + * Caller's buffer is too small or a new one can't be allocated + */ + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Needed buffer size %X, %s\n", + (u32) buffer_space_needed, acpi_format_exception (status))); + } + else { + /* + * We have enough space for the object, build it + */ + status = acpi_ut_copy_iobject_to_eobject (internal_return_obj, + return_buffer); + } + } + } + } + } + + /* Delete the return and parameter objects */ + + if (internal_return_obj) { + /* + * Delete the internal return object. (Or at least + * decrement the reference count by one) + */ + acpi_ut_remove_reference (internal_return_obj); + } + + /* + * Free the input parameter list (if we created one), + */ + if (internal_params) { + /* Free the allocated parameter block */ + + acpi_ut_delete_internal_object_list (internal_params); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_walk_namespace + * + * PARAMETERS: Type - acpi_object_type to search for + * start_object - Handle in namespace where search begins + * max_depth - Depth to which search is to reach + * user_function - Called when an object of "Type" is found + * Context - Passed to user function + * return_value - Location where return value of + * user_function is put if terminated early + * + * RETURNS Return value from the user_function if terminated early. + * Otherwise, returns NULL. + * + * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, + * starting (and ending) at the object specified by start_handle. + * The user_function is called whenever an object that matches + * the type parameter is found. If the user function returns + * a non-zero value, the search is terminated immediately and this + * value is returned to the caller. + * + * The point of this procedure is to provide a generic namespace + * walk routine that can be called from multiple places to + * provide multiple services; the User Function can be tailored + * to each task, whether it is a print function, a compare + * function, etc. + * + ******************************************************************************/ + +acpi_status +acpi_walk_namespace ( + acpi_object_type type, + acpi_handle start_object, + u32 max_depth, + acpi_walk_callback user_function, + void *context, + void **return_value) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("acpi_walk_namespace"); + + + /* Parameter validation */ + + if ((type > ACPI_TYPE_EXTERNAL_MAX) || + (!max_depth) || + (!user_function)) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* + * Lock the namespace around the walk. + * The namespace will be unlocked/locked around each call + * to the user function - since this function + * must be allowed to make Acpi calls itself. + */ + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_ns_walk_namespace (type, start_object, max_depth, ACPI_NS_WALK_UNLOCK, + user_function, context, return_value); + + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_device_callback + * + * PARAMETERS: Callback from acpi_get_device + * + * RETURN: Status + * + * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non- + * present devices, or if they specified a HID, it filters based + * on that. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_get_device_callback ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + struct acpi_get_devices_info *info = context; + acpi_status status; + struct acpi_namespace_node *node; + u32 flags; + struct acpi_device_id hid; + struct acpi_compatible_id_list *cid; + acpi_native_uint i; + + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + node = acpi_ns_map_handle_to_node (obj_handle); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + if (!node) { + return (AE_BAD_PARAMETER); + } + + /* Run _STA to determine if device is present */ + + status = acpi_ut_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (AE_CTRL_DEPTH); + } + + if (!(flags & 0x01)) { + /* Don't return at the device or children of the device if not there */ + + return (AE_CTRL_DEPTH); + } + + /* Filter based on device HID & CID */ + + if (info->hid != NULL) { + status = acpi_ut_execute_HID (node, &hid); + if (status == AE_NOT_FOUND) { + return (AE_OK); + } + else if (ACPI_FAILURE (status)) { + return (AE_CTRL_DEPTH); + } + + if (ACPI_STRNCMP (hid.value, info->hid, sizeof (hid.value)) != 0) { + /* Get the list of Compatible IDs */ + + status = acpi_ut_execute_CID (node, &cid); + if (status == AE_NOT_FOUND) { + return (AE_OK); + } + else if (ACPI_FAILURE (status)) { + return (AE_CTRL_DEPTH); + } + + /* Walk the CID list */ + + for (i = 0; i < cid->count; i++) { + if (ACPI_STRNCMP (cid->id[i].value, info->hid, + sizeof (struct acpi_compatible_id)) != 0) { + ACPI_MEM_FREE (cid); + return (AE_OK); + } + } + ACPI_MEM_FREE (cid); + } + } + + status = info->user_function (obj_handle, nesting_level, info->context, return_value); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_get_devices + * + * PARAMETERS: HID - HID to search for. Can be NULL. + * user_function - Called when a matching object is found + * Context - Passed to user function + * return_value - Location where return value of + * user_function is put if terminated early + * + * RETURNS Return value from the user_function if terminated early. + * Otherwise, returns NULL. + * + * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, + * starting (and ending) at the object specified by start_handle. + * The user_function is called whenever an object of type + * Device is found. If the user function returns + * a non-zero value, the search is terminated immediately and this + * value is returned to the caller. + * + * This is a wrapper for walk_namespace, but the callback performs + * additional filtering. Please see acpi_get_device_callback. + * + ******************************************************************************/ + +acpi_status +acpi_get_devices ( + char *HID, + acpi_walk_callback user_function, + void *context, + void **return_value) +{ + acpi_status status; + struct acpi_get_devices_info info; + + + ACPI_FUNCTION_TRACE ("acpi_get_devices"); + + + /* Parameter validation */ + + if (!user_function) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* + * We're going to call their callback from OUR callback, so we need + * to know what it is, and their context parameter. + */ + info.context = context; + info.user_function = user_function; + info.hid = HID; + + /* + * Lock the namespace around the walk. + * The namespace will be unlocked/locked around each call + * to the user function - since this function + * must be allowed to make Acpi calls itself. + */ + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, + acpi_ns_get_device_callback, &info, + return_value); + + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_attach_data + * + * PARAMETERS: obj_handle - Namespace node + * Handler - Handler for this attachment + * Data - Pointer to data to be attached + * + * RETURN: Status + * + * DESCRIPTION: Attach arbitrary data and handler to a namespace node. + * + ******************************************************************************/ + +acpi_status +acpi_attach_data ( + acpi_handle obj_handle, + acpi_object_handler handler, + void *data) +{ + struct acpi_namespace_node *node; + acpi_status status; + + + /* Parameter validation */ + + if (!obj_handle || + !handler || + !data) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Convert and validate the handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + status = acpi_ns_attach_data (node, handler, data); + +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_detach_data + * + * PARAMETERS: obj_handle - Namespace node handle + * Handler - Handler used in call to acpi_attach_data + * + * RETURN: Status + * + * DESCRIPTION: Remove data that was previously attached to a node. + * + ******************************************************************************/ + +acpi_status +acpi_detach_data ( + acpi_handle obj_handle, + acpi_object_handler handler) +{ + struct acpi_namespace_node *node; + acpi_status status; + + + /* Parameter validation */ + + if (!obj_handle || + !handler) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Convert and validate the handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + status = acpi_ns_detach_data (node, handler); + +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_get_data + * + * PARAMETERS: obj_handle - Namespace node + * Handler - Handler used in call to attach_data + * Data - Where the data is returned + * + * RETURN: Status + * + * DESCRIPTION: Retrieve data that was previously attached to a namespace node. + * + ******************************************************************************/ + +acpi_status +acpi_get_data ( + acpi_handle obj_handle, + acpi_object_handler handler, + void **data) +{ + struct acpi_namespace_node *node; + acpi_status status; + + + /* Parameter validation */ + + if (!obj_handle || + !handler || + !data) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Convert and validate the handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + status = acpi_ns_get_attached_data (node, handler, data); + +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); +} + + diff -urN linux-2.4.21/drivers/acpi/namespace/nsxfname.c linux-2.4.22/drivers/acpi/namespace/nsxfname.c --- linux-2.4.21/drivers/acpi/namespace/nsxfname.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsxfname.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,50 +2,63 @@ * * Module Name: nsxfname - Public interfaces to the ACPI subsystem * ACPI Namespace oriented interfaces - * $Revision: 82 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "amlcode.h" -#include "acparser.h" -#include "acdispat.h" -#include "acevents.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsxfname") + ACPI_MODULE_NAME ("nsxfname") -/**************************************************************************** +/****************************************************************************** * - * FUNCTION: Acpi_get_handle + * FUNCTION: acpi_get_handle * * PARAMETERS: Parent - Object to search under (search scope). - * Path_name - Pointer to an asciiz string containing the + * path_name - Pointer to an asciiz string containing the * name - * Ret_handle - Where the return handle is placed + * ret_handle - Where the return handle is placed * * RETURN: Status * @@ -58,16 +71,16 @@ acpi_status acpi_get_handle ( - acpi_handle parent, - acpi_string pathname, - acpi_handle *ret_handle) + acpi_handle parent, + acpi_string pathname, + acpi_handle *ret_handle) { - acpi_status status; - acpi_namespace_node *node = NULL; - acpi_namespace_node *prefix_node = NULL; + acpi_status status; + struct acpi_namespace_node *node = NULL; + struct acpi_namespace_node *prefix_node = NULL; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* Parameter Validation */ @@ -79,20 +92,26 @@ /* Convert a parent handle to a prefix node */ if (parent) { - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } prefix_node = acpi_ns_map_handle_to_node (parent); if (!prefix_node) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } } /* Special case for root, since we can't search for it */ - if (STRCMP (pathname, NS_ROOT_PATH) == 0) { + if (ACPI_STRCMP (pathname, ACPI_NS_ROOT_PATH) == 0) { *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node); return (AE_OK); } @@ -100,7 +119,8 @@ /* * Find the Node and convert to a handle */ - status = acpi_ns_get_node (pathname, prefix_node, &node); + status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH, + &node); *ret_handle = NULL; if (ACPI_SUCCESS (status)) { @@ -111,90 +131,90 @@ } -/**************************************************************************** +/****************************************************************************** * - * FUNCTION: Acpi_get_name + * FUNCTION: acpi_get_name * * PARAMETERS: Handle - Handle to be converted to a pathname - * Name_type - Full pathname or single segment - * Ret_path_ptr - Buffer for returned path + * name_type - Full pathname or single segment + * Buffer - Buffer for returned path * * RETURN: Pointer to a string containing the fully qualified Name. * * DESCRIPTION: This routine returns the fully qualified name associated with - * the Handle parameter. This and the Acpi_pathname_to_handle are + * the Handle parameter. This and the acpi_pathname_to_handle are * complementary functions. * ******************************************************************************/ acpi_status acpi_get_name ( - acpi_handle handle, - u32 name_type, - acpi_buffer *ret_path_ptr) + acpi_handle handle, + u32 name_type, + struct acpi_buffer *buffer) { - acpi_status status; - acpi_namespace_node *node; + acpi_status status; + struct acpi_namespace_node *node; - /* Buffer pointer must be valid always */ + /* Parameter validation */ - if (!ret_path_ptr || (name_type > ACPI_NAME_TYPE_MAX)) { + if (name_type > ACPI_NAME_TYPE_MAX) { return (AE_BAD_PARAMETER); } - /* Allow length to be zero and ignore the pointer */ - - if ((ret_path_ptr->length) && - (!ret_path_ptr->pointer)) { - return (AE_BAD_PARAMETER); + status = acpi_ut_validate_buffer (buffer); + if (ACPI_FAILURE (status)) { + return (status); } if (name_type == ACPI_FULL_PATHNAME) { /* Get the full pathname (From the namespace root) */ - status = acpi_ns_handle_to_pathname (handle, &ret_path_ptr->length, - ret_path_ptr->pointer); + status = acpi_ns_handle_to_pathname (handle, buffer); return (status); } /* * Wants the single segment ACPI name. - * Validate handle and convert to an Node + * Validate handle and convert to a namespace Node */ - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + node = acpi_ns_map_handle_to_node (handle); if (!node) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } - /* Check if name will fit in buffer */ + /* Validate/Allocate/Clear caller buffer */ - if (ret_path_ptr->length < PATH_SEGMENT_LENGTH) { - ret_path_ptr->length = PATH_SEGMENT_LENGTH; - status = AE_BUFFER_OVERFLOW; + status = acpi_ut_initialize_buffer (buffer, ACPI_PATH_SEGMENT_LENGTH); + if (ACPI_FAILURE (status)) { goto unlock_and_exit; } /* Just copy the ACPI name from the Node and zero terminate it */ - STRNCPY (ret_path_ptr->pointer, (NATIVE_CHAR *) &node->name, + ACPI_STRNCPY (buffer->pointer, node->name.ascii, ACPI_NAME_SIZE); - ((NATIVE_CHAR *) ret_path_ptr->pointer) [ACPI_NAME_SIZE] = 0; + ((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0; status = AE_OK; unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return (status); } -/**************************************************************************** +/****************************************************************************** * - * FUNCTION: Acpi_get_object_info + * FUNCTION: acpi_get_object_info * * PARAMETERS: Handle - Object Handle * Info - Where the info is returned @@ -209,93 +229,127 @@ acpi_status acpi_get_object_info ( - acpi_handle handle, - acpi_device_info *info) + acpi_handle handle, + struct acpi_buffer *buffer) { - acpi_device_id hid; - acpi_device_id uid; - acpi_status status; - u32 device_status = 0; - acpi_integer address = 0; - acpi_namespace_node *node; + acpi_status status; + struct acpi_namespace_node *node; + struct acpi_device_info info; + struct acpi_device_info *return_info; + struct acpi_compatible_id_list *cid_list = NULL; + acpi_size size; /* Parameter validation */ - if (!handle || !info) { + if (!handle || !buffer) { return (AE_BAD_PARAMETER); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_validate_buffer (buffer); + if (ACPI_FAILURE (status)) { + return (status); + } + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } node = acpi_ns_map_handle_to_node (handle); if (!node) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - info->type = node->type; - info->name = node->name; + /* Init return structure */ - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + size = sizeof (struct acpi_device_info); + ACPI_MEMSET (&info, 0, size); - /* - * If not a device, we are all done. - */ - if (info->type != ACPI_TYPE_DEVICE) { - return (AE_OK); + info.type = node->type; + info.name = node->name.integer; + info.valid = 0; + + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); } + /* If not a device, we are all done */ - /* - * Get extra info for ACPI devices only. Run the - * _HID, _UID, _STA, and _ADR methods. Note: none - * of these methods are required, so they may or may - * not be present. The Info->Valid bits are used - * to indicate which methods ran successfully. - */ - info->valid = 0; + if (info.type == ACPI_TYPE_DEVICE) { + /* + * Get extra info for ACPI Devices objects only: + * Run the Device _HID, _UID, _CID, _STA, and _ADR methods. + * + * Note: none of these methods are required, so they may or may + * not be present for this device. The Info.Valid bitfield is used + * to indicate which methods were found and ran successfully. + */ + + /* Execute the Device._HID method */ + + status = acpi_ut_execute_HID (node, &info.hardware_id); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_HID; + } - /* Execute the _HID method and save the result */ + /* Execute the Device._UID method */ - status = acpi_ut_execute_HID (node, &hid); - if (ACPI_SUCCESS (status)) { - STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id)); + status = acpi_ut_execute_UID (node, &info.unique_id); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_UID; + } - info->valid |= ACPI_VALID_HID; - } + /* Execute the Device._CID method */ - /* Execute the _UID method and save the result */ + status = acpi_ut_execute_CID (node, &cid_list); + if (ACPI_SUCCESS (status)) { + size += ((acpi_size) cid_list->count - 1) * + sizeof (struct acpi_compatible_id); + info.valid |= ACPI_VALID_CID; + } - status = acpi_ut_execute_UID (node, &uid); - if (ACPI_SUCCESS (status)) { - STRCPY (info->unique_id, uid.buffer); + /* Execute the Device._STA method */ - info->valid |= ACPI_VALID_UID; + status = acpi_ut_execute_STA (node, &info.current_status); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_STA; + } + + /* Execute the Device._ADR method */ + + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, + &info.address); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_ADR; + } + + status = AE_OK; } - /* - * Execute the _STA method and save the result - * _STA is not always present - */ - status = acpi_ut_execute_STA (node, &device_status); - if (ACPI_SUCCESS (status)) { - info->current_status = device_status; - info->valid |= ACPI_VALID_STA; + /* Validate/Allocate/Clear caller buffer */ + + status = acpi_ut_initialize_buffer (buffer, size); + if (ACPI_FAILURE (status)) { + goto cleanup; } - /* - * Execute the _ADR method and save result if successful - * _ADR is not always present - */ - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, - node, &address); + /* Populate the return buffer */ - if (ACPI_SUCCESS (status)) { - info->address = address; - info->valid |= ACPI_VALID_ADR; + return_info = buffer->pointer; + ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info)); + + if (cid_list) { + ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size); } - return (AE_OK); + +cleanup: + if (cid_list) { + ACPI_MEM_FREE (cid_list); + } + return (status); } diff -urN linux-2.4.21/drivers/acpi/namespace/nsxfobj.c linux-2.4.22/drivers/acpi/namespace/nsxfobj.c --- linux-2.4.21/drivers/acpi/namespace/nsxfobj.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/namespace/nsxfobj.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,345 +2,60 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 95 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acdispat.h" +#include +#include #define _COMPONENT ACPI_NAMESPACE - MODULE_NAME ("nsxfobj") - - -/******************************************************************************* - * - * FUNCTION: Acpi_evaluate_object - * - * PARAMETERS: Handle - Object handle (optional) - * *Pathname - Object pathname (optional) - * **External_params - List of parameters to pass to method, - * terminated by NULL. May be NULL - * if no parameters are being passed. - * *Return_buffer - Where to put method's return value (if - * any). If NULL, no value is returned. - * - * RETURN: Status - * - * DESCRIPTION: Find and evaluate the given object, passing the given - * parameters if necessary. One of "Handle" or "Pathname" must - * be valid (non-null) - * - ******************************************************************************/ - -acpi_status -acpi_evaluate_object ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *external_params, - acpi_buffer *return_buffer) -{ - acpi_status status; - acpi_operand_object **internal_params = NULL; - acpi_operand_object *internal_return_obj = NULL; - u32 buffer_space_needed; - u32 user_buffer_length; - u32 i; - - - FUNCTION_TRACE ("Acpi_evaluate_object"); - - - /* - * If there are parameters to be passed to the object - * (which must be a control method), the external objects - * must be converted to internal objects - */ - if (external_params && external_params->count) { - /* - * Allocate a new parameter block for the internal objects - * Add 1 to count to allow for null terminated internal list - */ - internal_params = ACPI_MEM_CALLOCATE ((external_params->count + 1) * sizeof (void *)); - if (!internal_params) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - - /* - * Convert each external object in the list to an - * internal object - */ - for (i = 0; i < external_params->count; i++) { - status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i], - &internal_params[i]); - - if (ACPI_FAILURE (status)) { - acpi_ut_delete_internal_object_list (internal_params); - return_ACPI_STATUS (status); - } - } - internal_params[external_params->count] = NULL; - } - - - /* - * Three major cases: - * 1) Fully qualified pathname - * 2) No handle, not fully qualified pathname (error) - * 3) Valid handle - */ - if ((pathname) && - (acpi_ns_valid_root_prefix (pathname[0]))) { - /* - * The path is fully qualified, just evaluate by name - */ - status = acpi_ns_evaluate_by_name (pathname, internal_params, &internal_return_obj); - } - - else if (!handle) { - /* - * A handle is optional iff a fully qualified pathname - * is specified. Since we've already handled fully - * qualified names above, this is an error - */ - if (!pathname) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Both Handle and Pathname are NULL\n")); - } - - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Handle is NULL and Pathname is relative\n")); - } - - status = AE_BAD_PARAMETER; - } - - else { - /* - * We get here if we have a handle -- and if we have a - * pathname it is relative. The handle will be validated - * in the lower procedures - */ - if (!pathname) { - /* - * The null pathname case means the handle is for - * the actual object to be evaluated - */ - status = acpi_ns_evaluate_by_handle (handle, internal_params, &internal_return_obj); - } - - else { - /* - * Both a Handle and a relative Pathname - */ - status = acpi_ns_evaluate_relative (handle, pathname, internal_params, - &internal_return_obj); - } - } - - - /* - * If we are expecting a return value, and all went well above, - * copy the return value to an external object. - */ - - if (return_buffer) { - user_buffer_length = return_buffer->length; - return_buffer->length = 0; - - if (internal_return_obj) { - if (VALID_DESCRIPTOR_TYPE (internal_return_obj, ACPI_DESC_TYPE_NAMED)) { - /* - * If we got an Node as a return object, - * this means the object we are evaluating - * has nothing interesting to return (such - * as a mutex, etc.) We return an error - * because these types are essentially - * unsupported by this interface. We - * don't check up front because this makes - * it easier to add support for various - * types at a later date if necessary. - */ - status = AE_TYPE; - internal_return_obj = NULL; /* No need to delete an Node */ - } - - if (ACPI_SUCCESS (status)) { - /* - * Find out how large a buffer is needed - * to contain the returned object - */ - status = acpi_ut_get_object_size (internal_return_obj, - &buffer_space_needed); - if (ACPI_SUCCESS (status)) { - /* - * Check if there is enough room in the - * caller's buffer - */ - if (user_buffer_length < buffer_space_needed) { - /* - * Caller's buffer is too small, can't - * give him partial results fail the call - * but return the buffer size needed - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Needed buffer size %X, received %X\n", - buffer_space_needed, user_buffer_length)); - - return_buffer->length = buffer_space_needed; - status = AE_BUFFER_OVERFLOW; - } - - else { - /* - * We have enough space for the object, build it - */ - status = acpi_ut_copy_iobject_to_eobject (internal_return_obj, - return_buffer); - return_buffer->length = buffer_space_needed; - } - } - } - } - } - - - /* Delete the return and parameter objects */ - - if (internal_return_obj) { - /* - * Delete the internal return object. (Or at least - * decrement the reference count by one) - */ - acpi_ut_remove_reference (internal_return_obj); - } - - /* - * Free the input parameter list (if we created one), - */ - if (internal_params) { - /* Free the allocated parameter block */ - - acpi_ut_delete_internal_object_list (internal_params); - } - - return_ACPI_STATUS (status); -} - + ACPI_MODULE_NAME ("nsxfobj") /******************************************************************************* * - * FUNCTION: Acpi_get_next_object - * - * PARAMETERS: Type - Type of object to be searched for - * Parent - Parent object whose children we are getting - * Last_child - Previous child that was found. - * The NEXT child will be returned - * Ret_handle - Where handle to the next object is placed - * - * RETURN: Status - * - * DESCRIPTION: Return the next peer object within the namespace. If Handle is - * valid, Scope is ignored. Otherwise, the first object within - * Scope is returned. - * - ******************************************************************************/ - -acpi_status -acpi_get_next_object ( - acpi_object_type type, - acpi_handle parent, - acpi_handle child, - acpi_handle *ret_handle) -{ - acpi_status status = AE_OK; - acpi_namespace_node *node; - acpi_namespace_node *parent_node = NULL; - acpi_namespace_node *child_node = NULL; - - - /* Parameter validation */ - - if (type > ACPI_TYPE_MAX) { - return (AE_BAD_PARAMETER); - } - - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - - /* If null handle, use the parent */ - - if (!child) { - /* Start search at the beginning of the specified scope */ - - parent_node = acpi_ns_map_handle_to_node (parent); - if (!parent_node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - } - - /* Non-null handle, ignore the parent */ - - else { - /* Convert and validate the handle */ - - child_node = acpi_ns_map_handle_to_node (child); - if (!child_node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - } - - - /* Internal function does the real work */ - - node = acpi_ns_get_next_node ((acpi_object_type8) type, - parent_node, child_node); - if (!node) { - status = AE_NOT_FOUND; - goto unlock_and_exit; - } - - if (ret_handle) { - *ret_handle = acpi_ns_convert_entry_to_handle (node); - } - - -unlock_and_exit: - - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_get_type + * FUNCTION: acpi_get_type * * PARAMETERS: Handle - Handle of object whose type is desired - * *Ret_type - Where the type will be placed + * *ret_type - Where the type will be placed * * RETURN: Status * @@ -350,10 +65,11 @@ acpi_status acpi_get_type ( - acpi_handle handle, - acpi_object_type *ret_type) + acpi_handle handle, + acpi_object_type *ret_type) { - acpi_namespace_node *node; + struct acpi_namespace_node *node; + acpi_status status; /* Parameter Validation */ @@ -371,30 +87,33 @@ return (AE_OK); } - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } /* Convert and validate the handle */ node = acpi_ns_map_handle_to_node (handle); if (!node) { - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } *ret_type = node->type; - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return (AE_OK); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); } /******************************************************************************* * - * FUNCTION: Acpi_get_parent + * FUNCTION: acpi_get_parent * * PARAMETERS: Handle - Handle of object whose parent is desired - * Ret_handle - Where the parent handle will be placed + * ret_handle - Where the parent handle will be placed * * RETURN: Status * @@ -405,11 +124,11 @@ acpi_status acpi_get_parent ( - acpi_handle handle, - acpi_handle *ret_handle) + acpi_handle handle, + acpi_handle *ret_handle) { - acpi_namespace_node *node; - acpi_status status = AE_OK; + struct acpi_namespace_node *node; + acpi_status status; if (!ret_handle) { @@ -422,8 +141,10 @@ return (AE_NULL_ENTRY); } - - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } /* Convert and validate the handle */ @@ -433,237 +154,106 @@ goto unlock_and_exit; } - /* Get the parent entry */ *ret_handle = - acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_object (node)); + acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_node (node)); - /* Return exeption if parent is null */ + /* Return exception if parent is null */ - if (!acpi_ns_get_parent_object (node)) { + if (!acpi_ns_get_parent_node (node)) { status = AE_NULL_ENTRY; } unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return (status); } /******************************************************************************* * - * FUNCTION: Acpi_walk_namespace - * - * PARAMETERS: Type - acpi_object_type to search for - * Start_object - Handle in namespace where search begins - * Max_depth - Depth to which search is to reach - * User_function - Called when an object of "Type" is found - * Context - Passed to user function - * Return_value - Location where return value of - * User_function is put if terminated early - * - * RETURNS Return value from the User_function if terminated early. - * Otherwise, returns NULL. - * - * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, - * starting (and ending) at the object specified by Start_handle. - * The User_function is called whenever an object that matches - * the type parameter is found. If the user function returns - * a non-zero value, the search is terminated immediately and this - * value is returned to the caller. - * - * The point of this procedure is to provide a generic namespace - * walk routine that can be called from multiple places to - * provide multiple services; the User Function can be tailored - * to each task, whether it is a print function, a compare - * function, etc. + * FUNCTION: acpi_get_next_object * - ******************************************************************************/ - -acpi_status -acpi_walk_namespace ( - acpi_object_type type, - acpi_handle start_object, - u32 max_depth, - acpi_walk_callback user_function, - void *context, - void **return_value) -{ - acpi_status status; - - - FUNCTION_TRACE ("Acpi_walk_namespace"); - - - /* Parameter validation */ - - if ((type > ACPI_TYPE_MAX) || - (!max_depth) || - (!user_function)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - /* - * Lock the namespace around the walk. - * The namespace will be unlocked/locked around each call - * to the user function - since this function - * must be allowed to make Acpi calls itself. - */ - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - status = acpi_ns_walk_namespace ((acpi_object_type8) type, start_object, - max_depth, NS_WALK_UNLOCK, user_function, context, - return_value); - - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_get_device_callback - * - * PARAMETERS: Callback from Acpi_get_device + * PARAMETERS: Type - Type of object to be searched for + * Parent - Parent object whose children we are getting + * last_child - Previous child that was found. + * The NEXT child will be returned + * ret_handle - Where handle to the next object is placed * * RETURN: Status * - * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non- - * present devices, or if they specified a HID, it filters based - * on that. + * DESCRIPTION: Return the next peer object within the namespace. If Handle is + * valid, Scope is ignored. Otherwise, the first object within + * Scope is returned. * ******************************************************************************/ -static acpi_status -acpi_ns_get_device_callback ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) +acpi_status +acpi_get_next_object ( + acpi_object_type type, + acpi_handle parent, + acpi_handle child, + acpi_handle *ret_handle) { - acpi_status status; - acpi_namespace_node *node; - u32 flags; - acpi_device_id device_id; - acpi_get_devices_info *info; + acpi_status status; + struct acpi_namespace_node *node; + struct acpi_namespace_node *parent_node = NULL; + struct acpi_namespace_node *child_node = NULL; - info = context; - - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - node = acpi_ns_map_handle_to_node (obj_handle); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + /* Parameter validation */ - if (!node) { + if (type > ACPI_TYPE_EXTERNAL_MAX) { return (AE_BAD_PARAMETER); } - /* - * Run _STA to determine if device is present - */ - status = acpi_ut_execute_STA (node, &flags); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - return (AE_CTRL_DEPTH); + return (status); } - if (!(flags & 0x01)) { - /* don't return at the device or children of the device if not there */ - return (AE_CTRL_DEPTH); - } + /* If null handle, use the parent */ - /* - * Filter based on device HID - */ - if (info->hid != NULL) { - status = acpi_ut_execute_HID (node, &device_id); - if (status == AE_NOT_FOUND) { - return (AE_OK); - } + if (!child) { + /* Start search at the beginning of the specified scope */ - else if (ACPI_FAILURE (status)) { - return (AE_CTRL_DEPTH); + parent_node = acpi_ns_map_handle_to_node (parent); + if (!parent_node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; } + } + else { + /* Non-null handle, ignore the parent */ + /* Convert and validate the handle */ - if (STRNCMP (device_id.buffer, info->hid, sizeof (device_id.buffer)) != 0) { - return (AE_OK); + child_node = acpi_ns_map_handle_to_node (child); + if (!child_node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; } } - info->user_function (obj_handle, nesting_level, info->context, return_value); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_get_devices - * - * PARAMETERS: HID - HID to search for. Can be NULL. - * User_function - Called when a matching object is found - * Context - Passed to user function - * Return_value - Location where return value of - * User_function is put if terminated early - * - * RETURNS Return value from the User_function if terminated early. - * Otherwise, returns NULL. - * - * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, - * starting (and ending) at the object specified by Start_handle. - * The User_function is called whenever an object that matches - * the type parameter is found. If the user function returns - * a non-zero value, the search is terminated immediately and this - * value is returned to the caller. - * - * This is a wrapper for Walk_namespace, but the callback performs - * additional filtering. Please see Acpi_get_device_callback. - * - ******************************************************************************/ - -acpi_status -acpi_get_devices ( - NATIVE_CHAR *HID, - acpi_walk_callback user_function, - void *context, - void **return_value) -{ - acpi_status status; - acpi_get_devices_info info; - - - FUNCTION_TRACE ("Acpi_get_devices"); - - - /* Parameter validation */ + /* Internal function does the real work */ - if (!user_function) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + node = acpi_ns_get_next_node (type, parent_node, child_node); + if (!node) { + status = AE_NOT_FOUND; + goto unlock_and_exit; } - /* - * We're going to call their callback from OUR callback, so we need - * to know what it is, and their context parameter. - */ - info.context = context; - info.user_function = user_function; - info.hid = HID; + if (ret_handle) { + *ret_handle = acpi_ns_convert_entry_to_handle (node); + } - /* - * Lock the namespace around the walk. - * The namespace will be unlocked/locked around each call - * to the user function - since this function - * must be allowed to make Acpi calls itself. - */ - acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, - ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - NS_WALK_UNLOCK, - acpi_ns_get_device_callback, &info, - return_value); - acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); +unlock_and_exit: - return_ACPI_STATUS (status); + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); } + + diff -urN linux-2.4.21/drivers/acpi/numa.c linux-2.4.22/drivers/acpi/numa.c --- linux-2.4.21/drivers/acpi/numa.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/numa.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,187 @@ +/* + * acpi_numa.c - ACPI NUMA support + * + * Copyright (C) 2002 Takayoshi Kochi + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 + +#define PREFIX "ACPI: " + +extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler); + +void __init +acpi_table_print_srat_entry ( + acpi_table_entry_header *header) +{ + if (!header) + return; + + switch (header->type) { + + case ACPI_SRAT_PROCESSOR_AFFINITY: + { + struct acpi_table_processor_affinity *p = + (struct acpi_table_processor_affinity*) header; + printk(KERN_INFO PREFIX "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", + p->apic_id, p->lsapic_eid, p->proximity_domain, + p->flags.enabled?"enabled":"disabled"); + } + break; + + case ACPI_SRAT_MEMORY_AFFINITY: + { + struct acpi_table_memory_affinity *p = + (struct acpi_table_memory_affinity*) header; + printk(KERN_INFO PREFIX "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n", + p->base_addr_hi, p->base_addr_lo, p->length_hi, p->length_lo, + p->memory_type, p->proximity_domain, + p->flags.enabled ? "enabled" : "disabled", + p->flags.hot_pluggable ? " hot-pluggable" : ""); + } + break; + + default: + printk(KERN_WARNING PREFIX "Found unsupported SRAT entry (type = 0x%x)\n", + header->type); + break; + } +} + + +static int __init +acpi_parse_slit (unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_slit *slit; + u32 localities; + + if (!phys_addr || !size) + return -EINVAL; + + slit = (struct acpi_table_slit *) __va(phys_addr); + + /* downcast just for %llu vs %lu for i386/ia64 */ + localities = (u32) slit->localities; + + printk(KERN_INFO PREFIX "SLIT localities %ux%u\n", localities, localities); + + acpi_numa_slit_init(slit); + + return 0; +} + + +static int __init +acpi_parse_processor_affinity (acpi_table_entry_header *header) +{ + struct acpi_table_processor_affinity *processor_affinity = NULL; + + processor_affinity = (struct acpi_table_processor_affinity*) header; + if (!processor_affinity) + return -EINVAL; + + acpi_table_print_srat_entry(header); + + /* let architecture-dependent part to do it */ + acpi_numa_processor_affinity_init(processor_affinity); + + return 0; +} + + +static int __init +acpi_parse_memory_affinity (acpi_table_entry_header *header) +{ + struct acpi_table_memory_affinity *memory_affinity = NULL; + + memory_affinity = (struct acpi_table_memory_affinity*) header; + if (!memory_affinity) + return -EINVAL; + + acpi_table_print_srat_entry(header); + + /* let architecture-dependent part to do it */ + acpi_numa_memory_affinity_init(memory_affinity); + + return 0; +} + + +static int __init +acpi_parse_srat (unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_srat *srat = NULL; + + if (!phys_addr || !size) + return -EINVAL; + + srat = (struct acpi_table_srat *) __va(phys_addr); + + printk(KERN_INFO PREFIX "SRAT revision %d\n", srat->table_revision); + + return 0; +} + + +int __init +acpi_table_parse_srat ( + enum acpi_srat_entry_id id, + acpi_madt_entry_handler handler) +{ + return acpi_table_parse_madt_family(ACPI_SRAT, sizeof(struct acpi_table_srat), + id, handler); +} + + +int __init +acpi_numa_init() +{ + int result; + + /* SRAT: Static Resource Affinity Table */ + result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat); + + if (result > 0) { + result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, + acpi_parse_processor_affinity); + result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, + acpi_parse_memory_affinity); + } else { + /* FIXME */ + printk("Warning: acpi_table_parse(ACPI_SRAT) returned %d!\n",result); + } + + /* SLIT: System Locality Information Table */ + result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit); + if (result < 1) { + /* FIXME */ + printk("Warning: acpi_table_parse(ACPI_SLIT) returned %d!\n",result); + } + + acpi_numa_arch_fixup(); + return 0; +} diff -urN linux-2.4.21/drivers/acpi/os.c linux-2.4.22/drivers/acpi/os.c --- linux-2.4.21/drivers/acpi/os.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/os.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,920 +0,0 @@ -/****************************************************************************** - * - * Module Name: os.c - Linux OSL functions - * $Revision: 49 $ - * - *****************************************************************************/ - -/* - * os.c - OS-dependent functions - * - * Copyright (C) 2000 Andrew Henroid - * Copyright (C) 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - */ -/* Changes - * - * Christopher Liebman 2001-5-15 - * - Fixed improper kernel_thread parameters - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ACPI_EFI -#include -#endif - -#ifdef _IA64 -#include -#endif - -#define _COMPONENT ACPI_OS_SERVICES - MODULE_NAME ("os") - -typedef struct -{ - OSD_EXECUTION_CALLBACK function; - void *context; -} ACPI_OS_DPC; - - -/***************************************************************************** - * Debugger Stuff - *****************************************************************************/ - -#ifdef ENABLE_DEBUGGER - -#include - -/* stuff for debugger support */ -int acpi_in_debugger = 0; -extern NATIVE_CHAR line_buf[80]; - -#endif - - -/***************************************************************************** - * Globals - *****************************************************************************/ - -static int acpi_irq_irq = 0; -static OSD_HANDLER acpi_irq_handler = NULL; -static void *acpi_irq_context = NULL; - - -/****************************************************************************** - * Functions - *****************************************************************************/ - -acpi_status -acpi_os_initialize(void) -{ - return AE_OK; -} - -acpi_status -acpi_os_terminate(void) -{ - if (acpi_irq_handler) { - acpi_os_remove_interrupt_handler(acpi_irq_irq, - acpi_irq_handler); - } - - return AE_OK; -} - -s32 -acpi_os_printf(const NATIVE_CHAR *fmt,...) -{ - s32 size; - va_list args; - va_start(args, fmt); - size = acpi_os_vprintf(fmt, args); - va_end(args); - - return size; -} - -s32 -acpi_os_vprintf(const NATIVE_CHAR *fmt, va_list args) -{ - static char buffer[512]; - int size = vsprintf(buffer, fmt, args); - -#ifdef ENABLE_DEBUGGER - if (acpi_in_debugger) { - kdb_printf("%s", buffer); - } else { - printk("%s", buffer); - } -#else - printk("%s", buffer); -#endif - - return size; -} - -void * -acpi_os_allocate(u32 size) -{ - return kmalloc(size, GFP_KERNEL); -} - -void * -acpi_os_callocate(u32 size) -{ - void *ptr = acpi_os_allocate(size); - if (ptr) - memset(ptr, 0, size); - - return ptr; -} - -void -acpi_os_free(void *ptr) -{ - kfree(ptr); -} - - -acpi_status -acpi_os_get_root_pointer(u32 flags, ACPI_PHYSICAL_ADDRESS *phys_addr) -{ -#ifndef CONFIG_ACPI_EFI - if (ACPI_FAILURE(acpi_find_root_pointer(flags, phys_addr))) { - printk(KERN_ERR "ACPI: System description tables not found\n"); - return AE_ERROR; - } -#else /*CONFIG_ACPI_EFI*/ - if (efi.acpi20) - *phys_addr = (ACPI_PHYSICAL_ADDRESS) efi.acpi20; - else if (efi.acpi) - *phys_addr = (ACPI_PHYSICAL_ADDRESS) efi.acpi; - else { - printk(KERN_ERR "ACPI: System description tables not found\n"); - *phys_addr = NULL; - return AE_ERROR; - } -#endif /*CONFIG_ACPI_EFI*/ - - return AE_OK; -} - -acpi_status -acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, u32 size, void **virt) -{ - if (phys > ULONG_MAX) { - printk(KERN_ERR "ACPI: Cannot map memory that high\n"); - return AE_ERROR; - } - - *virt = ioremap((unsigned long) phys, size); - if (!*virt) - return AE_ERROR; - - return AE_OK; -} - -void -acpi_os_unmap_memory(void *virt, u32 size) -{ - iounmap(virt); -} - -acpi_status -acpi_os_get_physical_address(void *virt, ACPI_PHYSICAL_ADDRESS *phys) -{ - if(!phys || !virt) - return AE_BAD_PARAMETER; - - *phys = virt_to_phys(virt); - - return AE_OK; -} - -static void -acpi_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - (*acpi_irq_handler)(acpi_irq_context); -} - -acpi_status -acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) -{ -#ifdef _IA64 - irq = isa_irq_to_vector(irq); -#endif /*_IA64*/ - acpi_irq_irq = irq; - acpi_irq_handler = handler; - acpi_irq_context = context; - if (request_irq(irq, - acpi_irq, - SA_SHIRQ, - "acpi", - acpi_irq)) { - printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq); - return AE_ERROR; - } - - return AE_OK; -} - -acpi_status -acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) -{ - if (acpi_irq_handler) { -#ifdef _IA64 - irq = isa_irq_to_vector(irq); -#endif /*_IA64*/ - free_irq(irq, acpi_irq); - acpi_irq_handler = NULL; - } - - return AE_OK; -} - -/* - * Running in interpreter thread context, safe to sleep - */ - -void -acpi_os_sleep(u32 sec, u32 ms) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ * sec + (ms * HZ) / 1000); -} - -void -acpi_os_stall(u32 us) -{ - if (us > 10000) { - mdelay(us / 1000); - } - else { - udelay(us); - } -} - -acpi_status -acpi_os_read_port( - ACPI_IO_ADDRESS port, - void *value, - u32 width) -{ - u32 dummy; - - if (!value) - value = &dummy; - - switch (width) - { - case 8: - *(u8*) value = inb(port); - break; - case 16: - *(u16*) value = inw(port); - break; - case 32: - *(u32*) value = inl(port); - break; - default: - BUG(); - } - - return AE_OK; -} - -acpi_status -acpi_os_write_port( - ACPI_IO_ADDRESS port, - NATIVE_UINT value, - u32 width) -{ - switch (width) - { - case 8: - outb(value, port); - break; - case 16: - outw(value, port); - break; - case 32: - outl(value, port); - break; - default: - BUG(); - } - - return AE_OK; -} - -acpi_status -acpi_os_read_memory( - ACPI_PHYSICAL_ADDRESS phys_addr, - void *value, - u32 width) -{ - u32 dummy; - - if (!value) - value = &dummy; - - switch (width) - { - case 8: - *(u8*) value = *(u8*) phys_to_virt(phys_addr); - break; - case 16: - *(u16*) value = *(u16*) phys_to_virt(phys_addr); - break; - case 32: - *(u32*) value = *(u32*) phys_to_virt(phys_addr); - break; - default: - BUG(); - } - - return AE_OK; -} - -acpi_status -acpi_os_write_memory( - ACPI_PHYSICAL_ADDRESS phys_addr, - NATIVE_UINT value, - u32 width) -{ - switch (width) - { - case 8: - *(u8*) phys_to_virt(phys_addr) = value; - break; - case 16: - *(u16*) phys_to_virt(phys_addr) = value; - break; - case 32: - *(u32*) phys_to_virt(phys_addr) = value; - break; - default: - BUG(); - } - - return AE_OK; -} - - -#ifdef CONFIG_ACPI_PCI - -/* Architecture-dependent low-level PCI configuration access functions. */ -extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *val); -extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 val); - -acpi_status -acpi_os_read_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - void *value, - u32 width) -{ - int result = 0; - if (!value) - return AE_ERROR; - - switch (width) - { - case 8: - result = pci_config_read(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 1, value); - break; - case 16: - result = pci_config_read(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 2, value); - break; - case 32: - result = pci_config_read(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 4, value); - break; - default: - BUG(); - } - - return (result ? AE_ERROR : AE_OK); -} - -ACPI_STATUS -acpi_os_write_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - NATIVE_UINT value, - u32 width) -{ - int result = 0; - - switch (width) - { - case 8: - result = pci_config_write(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 1, value); - break; - case 16: - result = pci_config_write(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 2, value); - break; - case 32: - result = pci_config_write(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 4, value); - break; - default: - BUG(); - } - - return (result ? AE_ERROR : AE_OK); -} - -#else /*CONFIG_ACPI_PCI*/ - -acpi_status -acpi_os_read_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - void *value, - u32 width) -{ - int devfn = PCI_DEVFN(pci_id->device, pci_id->function); - struct pci_dev *dev = pci_find_slot(pci_id->bus, devfn); - - if (!value || !dev) - return AE_ERROR; - - switch (width) - { - case 8: - if (pci_read_config_byte(dev, reg, (u8*) value)) - return AE_ERROR; - break; - case 16: - if (pci_read_config_word(dev, reg, (u16*) value)) - return AE_ERROR; - break; - case 32: - if (pci_read_config_dword(dev, reg, (u32*) value)) - return AE_ERROR; - break; - default: - BUG(); - } - - return AE_OK; -} - -acpi_status -acpi_os_write_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - NATIVE_UINT value, - u32 width) -{ - int devfn = PCI_DEVFN(pci_id->device, pci_id->function); - struct pci_dev *dev = pci_find_slot(pci_id->bus, devfn); - - if (!dev) - return AE_ERROR; - - switch (width) - { - case 8: - if (pci_write_config_byte(dev, reg, value)) - return AE_ERROR; - break; - case 16: - if (pci_write_config_word(dev, reg, value)) - return AE_ERROR; - break; - case 32: - if (pci_write_config_dword(dev, reg, value)) - return AE_ERROR; - break; - default: - BUG(); - } - - return AE_OK; -} - -#endif /*CONFIG_ACPI_PCI*/ - - -acpi_status -acpi_os_load_module ( - char *module_name) -{ - PROC_NAME("acpi_os_load_module"); - - if (!module_name) - return AE_BAD_PARAMETER; - - if (0 > request_module(module_name)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to load module [%s].\n", module_name)); - return AE_ERROR; - } - - return AE_OK; -} - -acpi_status -acpi_os_unload_module ( - char *module_name) -{ - if (!module_name) - return AE_BAD_PARAMETER; - - /* TODO: How on Linux? */ - /* this is done automatically for all modules with - use_count = 0, I think. see: MOD_INC_USE_COUNT -ASG */ - - return AE_OK; -} - - -/* - * See acpi_os_queue_for_execution() - */ -static int -acpi_os_queue_exec ( - void *context) -{ - ACPI_OS_DPC *dpc = (ACPI_OS_DPC*)context; - - PROC_NAME("acpi_os_queue_exec"); - - daemonize(); - strcpy(current->comm, "kacpidpc"); - - if (!dpc || !dpc->function) - return AE_BAD_PARAMETER; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Executing function [%p(%p)].\n", dpc->function, dpc->context)); - - dpc->function(dpc->context); - - kfree(dpc); - - return 1; -} - -static void -acpi_os_schedule_exec ( - void *context) -{ - ACPI_OS_DPC *dpc = NULL; - int thread_pid = -1; - - PROC_NAME("acpi_os_schedule_exec"); - - dpc = (ACPI_OS_DPC*)context; - if (!dpc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating new thread to run function [%p(%p)].\n", dpc->function, dpc->context)); - - thread_pid = kernel_thread(acpi_os_queue_exec, dpc, - (CLONE_FS | CLONE_FILES | SIGCHLD)); - if (thread_pid < 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to kernel_thread() failed.\n")); - acpi_os_free(dpc); - } -} - -acpi_status -acpi_os_queue_for_execution( - u32 priority, - OSD_EXECUTION_CALLBACK function, - void *context) -{ - acpi_status status = AE_OK; - ACPI_OS_DPC *dpc = NULL; - - PROC_NAME("acpi_os_queue_for_execution"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); - - if (!function) - return AE_BAD_PARAMETER; - - /* - * Queue via DPC: - * -------------- - * Note that we have to use two different processes for queuing DPCs: - * Interrupt-Level: Use schedule_task; can't spawn a new thread. - * Kernel-Level: Spawn a new kernel thread, as schedule_task has - * its limitations (e.g. single-threaded model), and - * all other task queues run at interrupt-level. - */ - switch (priority) { - - case OSD_PRIORITY_GPE: - { - static struct tq_struct task; - - /* - * Allocate/initialize DPC structure. Note that this memory will be - * freed by the callee. - */ - dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_ATOMIC); - if (!dpc) - return AE_NO_MEMORY; - - dpc->function = function; - dpc->context = context; - - memset(&task, 0, sizeof(struct tq_struct)); - - task.routine = acpi_os_schedule_exec; - task.data = (void*)dpc; - - if (schedule_task(&task) < 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_task() failed.\n")); - status = AE_ERROR; - } - } - break; - - default: - /* - * Allocate/initialize DPC structure. Note that this memory will be - * freed by the callee. - */ - dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_KERNEL); - if (!dpc) - return AE_NO_MEMORY; - - dpc->function = function; - dpc->context = context; - - acpi_os_schedule_exec(dpc); - break; - } - - return status; -} - - -acpi_status -acpi_os_create_semaphore( - u32 max_units, - u32 initial_units, - acpi_handle *handle) -{ - struct semaphore *sem = NULL; - - PROC_NAME("acpi_os_create_semaphore"); - - sem = acpi_os_callocate(sizeof(struct semaphore)); - if (!sem) - return AE_NO_MEMORY; - - sema_init(sem, initial_units); - - *handle = (acpi_handle*)sem; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating semaphore[%p|%d].\n", *handle, initial_units)); - - return AE_OK; -} - - -/* - * TODO: A better way to delete semaphores? Linux doesn't have a - * 'delete_semaphore()' function -- may result in an invalid - * pointer dereference for non-synchronized consumers. Should - * we at least check for blocked threads and signal/cancel them? - */ - -acpi_status -acpi_os_delete_semaphore( - acpi_handle handle) -{ - struct semaphore *sem = (struct semaphore*) handle; - - PROC_NAME("acpi_os_delete_semaphore"); - - if (!sem) - return AE_BAD_PARAMETER; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting semaphore[%p].\n", handle)); - - acpi_os_free(sem); sem = NULL; - - return AE_OK; -} - - -/* - * TODO: The kernel doesn't have a 'down_timeout' function -- had to - * improvise. The process is to sleep for one scheduler quantum - * until the semaphore becomes available. Downside is that this - * may result in starvation for timeout-based waits when there's - * lots of semaphore activity. - * - * TODO: Support for units > 1? - */ -acpi_status -acpi_os_wait_semaphore( - acpi_handle handle, - u32 units, - u32 timeout) -{ - acpi_status status = AE_OK; - struct semaphore *sem = (struct semaphore*)handle; - int ret = 0; - - PROC_NAME("acpi_os_wait_semaphore"); - - if (!sem || (units < 1)) - return AE_BAD_PARAMETER; - - if (units > 1) - return AE_SUPPORT; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); - - switch (timeout) - { - /* - * No Wait: - * -------- - * A zero timeout value indicates that we shouldn't wait - just - * acquire the semaphore if available otherwise return AE_TIME - * (a.k.a. 'would block'). - */ - case 0: - if(down_trylock(sem)) - status = AE_TIME; - break; - - /* - * Wait Indefinitely: - * ------------------ - */ - case WAIT_FOREVER: - ret = down_interruptible(sem); - if (ret < 0) - status = AE_ERROR; - break; - - /* - * Wait w/ Timeout: - * ---------------- - */ - default: - // TODO: A better timeout algorithm? - { - int i = 0; - static const int quantum_ms = 1000/HZ; - - ret = down_trylock(sem); - for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - ret = down_trylock(sem); - } - - if (ret != 0) - status = AE_TIME; - } - break; - } - - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Failed to acquire semaphore[%p|%d|%d]\n", handle, units, timeout)); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout)); - } - - return status; -} - - -/* - * TODO: Support for units > 1? - */ -acpi_status -acpi_os_signal_semaphore( - acpi_handle handle, - u32 units) -{ - struct semaphore *sem = (struct semaphore *) handle; - - PROC_NAME("acpi_os_signal_semaphore"); - - if (!sem || (units < 1)) - return AE_BAD_PARAMETER; - - if (units > 1) - return AE_SUPPORT; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Signaling semaphore[%p|%d]\n", handle, units)); - - up(sem); - - return AE_OK; -} - -u32 -acpi_os_get_line(NATIVE_CHAR *buffer) -{ - -#ifdef ENABLE_DEBUGGER - if (acpi_in_debugger) { - u32 chars; - - kdb_read(buffer, sizeof(line_buf)); - - /* remove the CR kdb includes */ - chars = strlen(buffer) - 1; - buffer[chars] = '\0'; - } -#endif - - return 0; -} - -/* - * We just have to assume we're dealing with valid memory - */ - -BOOLEAN -acpi_os_readable(void *ptr, u32 len) -{ - return 1; -} - -BOOLEAN -acpi_os_writable(void *ptr, u32 len) -{ - return 1; -} - -u32 -acpi_os_get_thread_id (void) -{ - if (!in_interrupt()) - return current->pid; - - return 0; -} - -acpi_status -acpi_os_signal ( - u32 function, - void *info) -{ - switch (function) - { - case ACPI_SIGNAL_FATAL: - printk(KERN_ERR "ACPI: Fatal opcode executed\n"); - break; - case ACPI_SIGNAL_BREAKPOINT: - { - char *bp_info = (char*) info; - - printk(KERN_ERR "ACPI breakpoint: %s\n", bp_info); - } - default: - break; - } - - return AE_OK; -} - -acpi_status -acpi_os_breakpoint(NATIVE_CHAR *msg) -{ - acpi_os_printf("breakpoint: %s", msg); - - return AE_OK; -} - diff -urN linux-2.4.21/drivers/acpi/osl.c linux-2.4.22/drivers/acpi/osl.c --- linux-2.4.21/drivers/acpi/osl.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/osl.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,1023 @@ +/* + * acpi_osl.c - OS-dependent functions ($Revision: 80 $) + * + * Copyright (C) 2000 Andrew Henroid + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ACPI_EFI +#include +u64 efi_mem_attributes (u64 phys_addr); +#endif + + +#define _COMPONENT ACPI_OS_SERVICES +ACPI_MODULE_NAME ("osl") + +#define PREFIX "ACPI: " + +struct acpi_os_dpc +{ + OSD_EXECUTION_CALLBACK function; + void *context; +}; + + +#ifdef ENABLE_DEBUGGER +#include +/* stuff for debugger support */ +int acpi_in_debugger = 0; +extern char line_buf[80]; +#endif /*ENABLE_DEBUGGER*/ + +static int acpi_irq_irq = 0; +static OSD_HANDLER acpi_irq_handler = NULL; +static void *acpi_irq_context = NULL; + + +acpi_status +acpi_os_initialize(void) +{ + /* + * Initialize PCI configuration space access, as we'll need to access + * it while walking the namespace (bus 0 and root bridges w/ _BBNs). + */ +#ifdef CONFIG_ACPI_PCI + pcibios_config_init(); + if (!pci_config_read || !pci_config_write) { + printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n"); + return AE_NULL_ENTRY; + } +#endif + + return AE_OK; +} + +acpi_status +acpi_os_terminate(void) +{ + if (acpi_irq_handler) { + acpi_os_remove_interrupt_handler(acpi_irq_irq, + acpi_irq_handler); + } + + return AE_OK; +} + +void +acpi_os_printf(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + acpi_os_vprintf(fmt, args); + va_end(args); +} + +void +acpi_os_vprintf(const char *fmt, va_list args) +{ + static char buffer[512]; + + vsprintf(buffer, fmt, args); + +#ifdef ENABLE_DEBUGGER + if (acpi_in_debugger) { + kdb_printf("%s", buffer); + } else { + printk("%s", buffer); + } +#else + printk("%s", buffer); +#endif +} + +void * +acpi_os_allocate(acpi_size size) +{ + return kmalloc(size, GFP_KERNEL); +} + +void +acpi_os_free(void *ptr) +{ + kfree(ptr); +} + +acpi_status +acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) +{ +#ifdef CONFIG_ACPI_EFI + addr->pointer_type = ACPI_PHYSICAL_POINTER; + if (efi.acpi20) + addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi20); + else if (efi.acpi) + addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi); + else { + printk(KERN_ERR PREFIX "System description tables not found\n"); + return AE_NOT_FOUND; + } +#else + if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) { + printk(KERN_ERR PREFIX "System description tables not found\n"); + return AE_NOT_FOUND; + } +#endif /*CONFIG_ACPI_EFI*/ + + return AE_OK; +} + +acpi_status +acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void **virt) +{ +#ifdef CONFIG_ACPI_EFI + if (EFI_MEMORY_WB & efi_mem_attributes(phys)) { + *virt = phys_to_virt(phys); + } else { + *virt = ioremap(phys, size); + } +#else + if (phys > ULONG_MAX) { + printk(KERN_ERR PREFIX "Cannot map memory that high\n"); + return AE_BAD_PARAMETER; + } + /* + * ioremap checks to ensure this is in reserved space + */ + *virt = ioremap((unsigned long) phys, size); +#endif + + if (!*virt) + return AE_NO_MEMORY; + + return AE_OK; +} + +void +acpi_os_unmap_memory(void *virt, acpi_size size) +{ + iounmap(virt); +} + +acpi_status +acpi_os_get_physical_address(void *virt, acpi_physical_address *phys) +{ + if(!phys || !virt) + return AE_BAD_PARAMETER; + + *phys = virt_to_phys(virt); + + return AE_OK; +} + +#define ACPI_MAX_OVERRIDE_LEN 100 + +static char __initdata acpi_os_name[ACPI_MAX_OVERRIDE_LEN]; + +acpi_status +acpi_os_predefined_override (const struct acpi_predefined_names *init_val, + acpi_string *new_val) +{ + if (!init_val || !new_val) + return AE_BAD_PARAMETER; + + *new_val = NULL; + if (!memcmp (init_val->name, "_OS_", 4) && strlen(acpi_os_name)) { + printk(KERN_INFO PREFIX "Overriding _OS definition: %s\n", + acpi_os_name); + *new_val = acpi_os_name; + } + + return AE_OK; +} + +acpi_status +acpi_os_table_override (struct acpi_table_header *existing_table, + struct acpi_table_header **new_table) +{ + if (!existing_table || !new_table) + return AE_BAD_PARAMETER; + + *new_table = NULL; + return AE_OK; +} + +static void +acpi_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + (*acpi_irq_handler)(acpi_irq_context); +} + +acpi_status +acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) +{ + /* + * Ignore the irq from the core, and use the value in our copy of the + * FADT. It may not be the same if an interrupt source override exists + * for the SCI. + */ + irq = acpi_fadt.sci_int; + +#ifdef CONFIG_IA64 + irq = acpi_irq_to_vector(irq); + if (irq < 0) { + printk(KERN_ERR PREFIX "SCI (ACPI interrupt %d) not registered\n", + acpi_fadt.sci_int); + return AE_OK; + } +#endif + acpi_irq_irq = irq; + acpi_irq_handler = handler; + acpi_irq_context = context; + if (request_irq(irq, acpi_irq, SA_SHIRQ, "acpi", acpi_irq)) { + printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); + return AE_NOT_ACQUIRED; + } + + return AE_OK; +} + +acpi_status +acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) +{ + if (acpi_irq_handler) { +#ifdef CONFIG_IA64 + irq = acpi_irq_to_vector(irq); +#endif + free_irq(irq, acpi_irq); + acpi_irq_handler = NULL; + } + + return AE_OK; +} + +/* + * Running in interpreter thread context, safe to sleep + */ + +void +acpi_os_sleep(u32 sec, u32 ms) +{ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ * sec + (ms * HZ) / 1000); +} + +void +acpi_os_stall(u32 us) +{ + while (us) { + u32 delay = 1000; + + if (delay > us) + delay = us; + udelay(delay); + touch_nmi_watchdog(); + us -= delay; + } +} + +acpi_status +acpi_os_read_port( + acpi_io_address port, + u32 *value, + u32 width) +{ + u32 dummy; + + if (!value) + value = &dummy; + + switch (width) + { + case 8: + *(u8*) value = inb(port); + break; + case 16: + *(u16*) value = inw(port); + break; + case 32: + *(u32*) value = inl(port); + break; + default: + BUG(); + } + + return AE_OK; +} + +acpi_status +acpi_os_write_port( + acpi_io_address port, + u32 value, + u32 width) +{ + switch (width) + { + case 8: + outb(value, port); + break; + case 16: + outw(value, port); + break; + case 32: + outl(value, port); + break; + default: + BUG(); + } + + return AE_OK; +} + +acpi_status +acpi_os_read_memory( + acpi_physical_address phys_addr, + u32 *value, + u32 width) +{ + u32 dummy; + void *virt_addr; + +#ifdef CONFIG_ACPI_EFI + int iomem = 0; + + if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { + virt_addr = phys_to_virt(phys_addr); + } else { + iomem = 1; + virt_addr = ioremap(phys_addr, width); + } +#else + virt_addr = phys_to_virt(phys_addr); +#endif + if (!value) + value = &dummy; + + switch (width) { + case 8: + *(u8*) value = *(u8*) virt_addr; + break; + case 16: + *(u16*) value = *(u16*) virt_addr; + break; + case 32: + *(u32*) value = *(u32*) virt_addr; + break; + default: + BUG(); + } + +#ifdef CONFIG_ACPI_EFI + if (iomem) + iounmap(virt_addr); +#endif + + return AE_OK; +} + +acpi_status +acpi_os_write_memory( + acpi_physical_address phys_addr, + u32 value, + u32 width) +{ + void *virt_addr; + +#ifdef CONFIG_ACPI_EFI + int iomem = 0; + + if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { + virt_addr = phys_to_virt(phys_addr); + } else { + iomem = 1; + virt_addr = ioremap(phys_addr, width); + } +#else + virt_addr = phys_to_virt(phys_addr); +#endif + + switch (width) { + case 8: + *(u8*) virt_addr = value; + break; + case 16: + *(u16*) virt_addr = value; + break; + case 32: + *(u32*) virt_addr = value; + break; + default: + BUG(); + } + +#ifdef CONFIG_ACPI_EFI + if (iomem) + iounmap(virt_addr); +#endif + + return AE_OK; +} + +#ifdef CONFIG_ACPI_PCI + +acpi_status +acpi_os_read_pci_configuration ( + struct acpi_pci_id *pci_id, + u32 reg, + void *value, + u32 width) +{ + int result = 0; + if (!value) + return AE_BAD_PARAMETER; + + switch (width) + { + case 8: + result = pci_config_read(pci_id->segment, pci_id->bus, + pci_id->device, pci_id->function, reg, 1, value); + break; + case 16: + result = pci_config_read(pci_id->segment, pci_id->bus, + pci_id->device, pci_id->function, reg, 2, value); + break; + case 32: + result = pci_config_read(pci_id->segment, pci_id->bus, + pci_id->device, pci_id->function, reg, 4, value); + break; + default: + BUG(); + } + + return (result ? AE_ERROR : AE_OK); +} + +acpi_status +acpi_os_write_pci_configuration ( + struct acpi_pci_id *pci_id, + u32 reg, + acpi_integer value, + u32 width) +{ + int result = 0; + + switch (width) + { + case 8: + result = pci_config_write(pci_id->segment, pci_id->bus, + pci_id->device, pci_id->function, reg, 1, value); + break; + case 16: + result = pci_config_write(pci_id->segment, pci_id->bus, + pci_id->device, pci_id->function, reg, 2, value); + break; + case 32: + result = pci_config_write(pci_id->segment, pci_id->bus, + pci_id->device, pci_id->function, reg, 4, value); + break; + default: + BUG(); + } + + return (result ? AE_ERROR : AE_OK); +} + +static void +acpi_os_derive_pci_id_2 ( + acpi_handle rhandle, /* upper bound */ + acpi_handle chandle, /* current node */ + struct acpi_pci_id **id, + int *is_bridge, + u8 *bus_number) +{ + acpi_handle handle; + struct acpi_pci_id *pci_id = *id; + acpi_status status; + unsigned long temp; + acpi_object_type type; + u8 tu8; + + acpi_get_parent(chandle, &handle); + if (handle != rhandle) { + acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, bus_number); + + status = acpi_get_type(handle, &type); + if ( (ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE) ) + return; + + status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &temp); + if (ACPI_SUCCESS(status)) { + pci_id->device = ACPI_HIWORD (ACPI_LODWORD (temp)); + pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp)); + + if (*is_bridge) + pci_id->bus = *bus_number; + + /* any nicer way to get bus number of bridge ? */ + status = acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, 8); + if (ACPI_SUCCESS(status) && + ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) { + status = acpi_os_read_pci_configuration(pci_id, 0x18, &tu8, 8); + if (!ACPI_SUCCESS(status)) { + /* Certainly broken... FIX ME */ + return; + } + *is_bridge = 1; + pci_id->bus = tu8; + status = acpi_os_read_pci_configuration(pci_id, 0x19, &tu8, 8); + if (ACPI_SUCCESS(status)) { + *bus_number = tu8; + } + } else + *is_bridge = 0; + } + } +} + +void +acpi_os_derive_pci_id ( + acpi_handle rhandle, /* upper bound */ + acpi_handle chandle, /* current node */ + struct acpi_pci_id **id) +{ + int is_bridge = 1; + u8 bus_number = (*id)->bus; + + acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); +} + +#else /*!CONFIG_ACPI_PCI*/ + +acpi_status +acpi_os_write_pci_configuration ( + struct acpi_pci_id *pci_id, + u32 reg, + acpi_integer value, + u32 width) +{ + return (AE_SUPPORT); +} + +acpi_status +acpi_os_read_pci_configuration ( + struct acpi_pci_id *pci_id, + u32 reg, + void *value, + u32 width) +{ + return (AE_SUPPORT); +} + +void +acpi_os_derive_pci_id ( + acpi_handle rhandle, /* upper bound */ + acpi_handle chandle, /* current node */ + struct acpi_pci_id **id) +{ +} + +#endif /*CONFIG_ACPI_PCI*/ + +static void +acpi_os_execute_deferred ( + void *context) +{ + struct acpi_os_dpc *dpc = NULL; + + ACPI_FUNCTION_TRACE ("os_execute_deferred"); + + dpc = (struct acpi_os_dpc *) context; + if (!dpc) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); + return_VOID; + } + + dpc->function(dpc->context); + + kfree(dpc); + + return_VOID; +} + +acpi_status +acpi_os_queue_for_execution( + u32 priority, + OSD_EXECUTION_CALLBACK function, + void *context) +{ + acpi_status status = AE_OK; + struct acpi_os_dpc *dpc = NULL; + struct tq_struct *task; + + ACPI_FUNCTION_TRACE ("os_queue_for_execution"); + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); + + if (!function) + return_ACPI_STATUS (AE_BAD_PARAMETER); + + /* + * Allocate/initialize DPC structure. Note that this memory will be + * freed by the callee. The kernel handles the tq_struct list in a + * way that allows us to also free its memory inside the callee. + * Because we may want to schedule several tasks with different + * parameters we can't use the approach some kernel code uses of + * having a static tq_struct. + * We can save time and code by allocating the DPC and tq_structs + * from the same memory. + */ + dpc = kmalloc(sizeof(struct acpi_os_dpc)+sizeof(struct tq_struct), GFP_ATOMIC); + if (!dpc) + return_ACPI_STATUS (AE_NO_MEMORY); + + dpc->function = function; + dpc->context = context; + + task = (void *)(dpc+1); + INIT_TQUEUE(task, acpi_os_execute_deferred, (void*)dpc); + + if (!schedule_task(task)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_task() failed.\n")); + kfree(dpc); + status = AE_ERROR; + } + + return_ACPI_STATUS (status); +} + +/* + * Allocate the memory for a spinlock and initialize it. + */ +acpi_status +acpi_os_create_lock ( + acpi_handle *out_handle) +{ + spinlock_t *lock_ptr; + + ACPI_FUNCTION_TRACE ("os_create_lock"); + + lock_ptr = acpi_os_allocate(sizeof(spinlock_t)); + + spin_lock_init(lock_ptr); + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating spinlock[%p].\n", lock_ptr)); + + *out_handle = lock_ptr; + + return_ACPI_STATUS (AE_OK); +} + + +/* + * Deallocate the memory for a spinlock. + */ +void +acpi_os_delete_lock ( + acpi_handle handle) +{ + ACPI_FUNCTION_TRACE ("os_create_lock"); + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting spinlock[%p].\n", handle)); + + acpi_os_free(handle); + + return_VOID; +} + +/* + * Acquire a spinlock. + * + * handle is a pointer to the spinlock_t. + * flags is *not* the result of save_flags - it is an ACPI-specific flag variable + * that indicates whether we are at interrupt level. + */ +void +acpi_os_acquire_lock ( + acpi_handle handle, + u32 flags) +{ + ACPI_FUNCTION_TRACE ("os_acquire_lock"); + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquiring spinlock[%p] from %s level\n", handle, + ((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt"))); + + if (flags & ACPI_NOT_ISR) + ACPI_DISABLE_IRQS(); + + spin_lock((spinlock_t *)handle); + + return_VOID; +} + + +/* + * Release a spinlock. See above. + */ +void +acpi_os_release_lock ( + acpi_handle handle, + u32 flags) +{ + ACPI_FUNCTION_TRACE ("os_release_lock"); + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Releasing spinlock[%p] from %s level\n", handle, + ((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt"))); + + spin_unlock((spinlock_t *)handle); + + if (flags & ACPI_NOT_ISR) + ACPI_ENABLE_IRQS(); + + return_VOID; +} + + +acpi_status +acpi_os_create_semaphore( + u32 max_units, + u32 initial_units, + acpi_handle *handle) +{ + struct semaphore *sem = NULL; + + ACPI_FUNCTION_TRACE ("os_create_semaphore"); + + sem = acpi_os_allocate(sizeof(struct semaphore)); + if (!sem) + return_ACPI_STATUS (AE_NO_MEMORY); + memset(sem, 0, sizeof(struct semaphore)); + + sema_init(sem, initial_units); + + *handle = (acpi_handle*)sem; + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n", *handle, initial_units)); + + return_ACPI_STATUS (AE_OK); +} + + +/* + * TODO: A better way to delete semaphores? Linux doesn't have a + * 'delete_semaphore()' function -- may result in an invalid + * pointer dereference for non-synchronized consumers. Should + * we at least check for blocked threads and signal/cancel them? + */ + +acpi_status +acpi_os_delete_semaphore( + acpi_handle handle) +{ + struct semaphore *sem = (struct semaphore*) handle; + + ACPI_FUNCTION_TRACE ("os_delete_semaphore"); + + if (!sem) + return_ACPI_STATUS (AE_BAD_PARAMETER); + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle)); + + acpi_os_free(sem); sem = NULL; + + return_ACPI_STATUS (AE_OK); +} + + +/* + * TODO: The kernel doesn't have a 'down_timeout' function -- had to + * improvise. The process is to sleep for one scheduler quantum + * until the semaphore becomes available. Downside is that this + * may result in starvation for timeout-based waits when there's + * lots of semaphore activity. + * + * TODO: Support for units > 1? + */ +acpi_status +acpi_os_wait_semaphore( + acpi_handle handle, + u32 units, + u16 timeout) +{ + acpi_status status = AE_OK; + struct semaphore *sem = (struct semaphore*)handle; + int ret = 0; + + ACPI_FUNCTION_TRACE ("os_wait_semaphore"); + + if (!sem || (units < 1)) + return_ACPI_STATUS (AE_BAD_PARAMETER); + + if (units > 1) + return_ACPI_STATUS (AE_SUPPORT); + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); + + if (in_interrupt()) + timeout = 0; + + switch (timeout) + { + /* + * No Wait: + * -------- + * A zero timeout value indicates that we shouldn't wait - just + * acquire the semaphore if available otherwise return AE_TIME + * (a.k.a. 'would block'). + */ + case 0: + if(down_trylock(sem)) + status = AE_TIME; + break; + + /* + * Wait Indefinitely: + * ------------------ + */ + case ACPI_WAIT_FOREVER: + down(sem); + break; + + /* + * Wait w/ Timeout: + * ---------------- + */ + default: + // TODO: A better timeout algorithm? + { + int i = 0; + static const int quantum_ms = 1000/HZ; + + ret = down_trylock(sem); + for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + ret = down_trylock(sem); + } + + if (ret != 0) + status = AE_TIME; + } + break; + } + + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Failed to acquire semaphore[%p|%d|%d], %s\n", + handle, units, timeout, acpi_format_exception(status))); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout)); + } + + return_ACPI_STATUS (status); +} + + +/* + * TODO: Support for units > 1? + */ +acpi_status +acpi_os_signal_semaphore( + acpi_handle handle, + u32 units) +{ + struct semaphore *sem = (struct semaphore *) handle; + + ACPI_FUNCTION_TRACE ("os_signal_semaphore"); + + if (!sem || (units < 1)) + return_ACPI_STATUS (AE_BAD_PARAMETER); + + if (units > 1) + return_ACPI_STATUS (AE_SUPPORT); + + ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle, units)); + + up(sem); + + return_ACPI_STATUS (AE_OK); +} + +u32 +acpi_os_get_line(char *buffer) +{ + +#ifdef ENABLE_DEBUGGER + if (acpi_in_debugger) { + u32 chars; + + kdb_read(buffer, sizeof(line_buf)); + + /* remove the CR kdb includes */ + chars = strlen(buffer) - 1; + buffer[chars] = '\0'; + } +#endif + + return 0; +} + +/* + * We just have to assume we're dealing with valid memory + */ + +u8 +acpi_os_readable(void *ptr, acpi_size len) +{ + return 1; +} + +u8 +acpi_os_writable(void *ptr, acpi_size len) +{ + return 1; +} + +u32 +acpi_os_get_thread_id (void) +{ + if (!in_interrupt()) + return current->pid; + + return 0; +} + +acpi_status +acpi_os_signal ( + u32 function, + void *info) +{ + switch (function) + { + case ACPI_SIGNAL_FATAL: + printk(KERN_ERR PREFIX "Fatal opcode executed\n"); + break; + case ACPI_SIGNAL_BREAKPOINT: + { + char *bp_info = (char*) info; + + printk(KERN_ERR "ACPI breakpoint: %s\n", bp_info); + } + default: + break; + } + + return AE_OK; +} + +int __init +acpi_os_name_setup(char *str) +{ + char *p = acpi_os_name; + int count = ACPI_MAX_OVERRIDE_LEN-1; + + if (!str || !*str) + return 0; + + for (; count-- && str && *str; str++) { + if (isalnum(*str) || *str == ' ' || *str == ':') + *p++ = *str; + else if (*str == '\'' || *str == '"') + continue; + else + break; + } + *p = 0; + + return 1; + +} + +__setup("acpi_os_name=", acpi_os_name_setup); diff -urN linux-2.4.21/drivers/acpi/ospm/Makefile linux-2.4.22/drivers/acpi/ospm/Makefile --- linux-2.4.21/drivers/acpi/ospm/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,22 +0,0 @@ -# -# Makefile for the Linux OSPM code. -# - -O_TARGET := $(notdir $(CURDIR)).o - -ACPI_CFLAGS += -I$(CURDIR)/include - -EXTRA_CFLAGS += $(ACPI_CFLAGS) - -subdir-$(CONFIG_ACPI_BUSMGR) += busmgr -subdir-$(CONFIG_ACPI_EC) += ec -subdir-$(CONFIG_ACPI_SYS) += system -subdir-$(CONFIG_ACPI_CPU) += processor -subdir-$(CONFIG_ACPI_CMBATT) += battery -subdir-$(CONFIG_ACPI_AC) += ac_adapter -subdir-$(CONFIG_ACPI_BUTTON) += button -subdir-$(CONFIG_ACPI_THERMAL) += thermal - -obj-y += $(foreach dir,$(subdir-y),$(dir)/ospm_$(dir).o) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/ac_adapter/Makefile linux-2.4.22/drivers/acpi/ospm/ac_adapter/Makefile --- linux-2.4.21/drivers/acpi/ospm/ac_adapter/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/ac_adapter/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/ac_adapter/ac.c linux-2.4.22/drivers/acpi/ospm/ac_adapter/ac.c --- linux-2.4.21/drivers/acpi/ospm/ac_adapter/ac.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/ac_adapter/ac.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,398 +0,0 @@ -/***************************************************************************** - * - * Module Name: ac.c - * $Revision: 23 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "ac.h" - - -#define _COMPONENT ACPI_AC_ADAPTER - MODULE_NAME ("ac") - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: ac_print - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Prints out information on a specific ac_adapter. - * - ****************************************************************************/ - -void -ac_print ( - AC_CONTEXT *ac_adapter) -{ -#ifdef ACPI_DEBUG - - acpi_buffer buffer; - - PROC_NAME("ac_print"); - - if (!ac_adapter) { - return; - } - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - /* - * Get the full pathname for this ACPI object. - */ - acpi_get_name(ac_adapter->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - /* - * Print out basic adapter information. - */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| AC Adapter[%02x]:[%p] %s\n", ac_adapter->device_handle, ac_adapter->acpi_handle, (char*)buffer.pointer)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); -#endif /*ACPI_DEBUG*/ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: ac_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ac_add_device( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - AC_CONTEXT *ac_adapter = NULL; - acpi_device_info info; - - FUNCTION_TRACE("ac_add_device"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding ac_adapter device [%02x].\n", device_handle)); - - if (!context || *context) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Get information on this device. - */ - status = bm_get_device_info(device_handle, &device); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Allocate a new AC_CONTEXT structure. - */ - ac_adapter = acpi_os_callocate(sizeof(AC_CONTEXT)); - if (!ac_adapter) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - ac_adapter->device_handle = device->handle; - ac_adapter->acpi_handle = device->acpi_handle; - - /* - * Get information on this object. - */ - status = acpi_get_object_info(ac_adapter->acpi_handle, &info); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to get object info for ac_adapter device.")); - goto end; - } - - /* - * _UID? - * ----- - */ - if (info.valid & ACPI_VALID_UID) { - strncpy(ac_adapter->uid, info.unique_id, sizeof(info.unique_id)); - } - else { - strncpy(ac_adapter->uid, "0", sizeof("0")); - } - - /* - * _STA? - * ----- - */ - if (!(info.valid & ACPI_VALID_STA)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Must have valid _STA.\n")); - status = AE_ERROR; - goto end; - } - - status = ac_osl_add_device(ac_adapter); - if (ACPI_FAILURE(status)) { - goto end; - } - - *context = ac_adapter; - - ac_print(ac_adapter); - -end: - if (ACPI_FAILURE(status)) { - acpi_os_free(ac_adapter); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ac_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ac_remove_device ( - void **context) -{ - acpi_status status = AE_OK; - AC_CONTEXT *ac_adapter = NULL; - - FUNCTION_TRACE("ac_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ac_adapter = (AC_CONTEXT*)*context; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing ac_adapter device [%02x].\n", ac_adapter->device_handle)); - - ac_osl_remove_device(ac_adapter); - - acpi_os_free(ac_adapter); - - *context = NULL; - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: ac_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ac_initialize (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("ac_initialize"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - driver.notify = &ac_notify; - driver.request = &ac_request; - - /* - * Register driver for AC Adapter devices. - */ - MEMCPY(criteria.hid, AC_HID_AC_ADAPTER, sizeof(AC_HID_AC_ADAPTER)); - - status = bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ac_terminate - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ac_terminate (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("ac_terminate"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Unregister driver for AC Adapter devices. - */ - MEMCPY(criteria.hid, AC_HID_AC_ADAPTER, sizeof(AC_HID_AC_ADAPTER)); - - driver.notify = &ac_notify; - driver.request = &ac_request; - - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/***************************************************************************** - * - * FUNCTION: ac_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ -acpi_status -ac_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ac_notify"); - - if (!context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - switch (notify_type) { - - case BM_NOTIFY_DEVICE_ADDED: - status = ac_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = ac_remove_device(context); - break; - - case AC_NOTIFY_STATUS_CHANGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status change event detected.\n")); - status = ac_osl_generate_event(notify_type, - ((AC_CONTEXT*)*context)); - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ac_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ac_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ac_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Handle Request: - * --------------- - */ - switch (request->command) { - - default: - status = AE_SUPPORT; - break; - } - - request->status = status; - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/ac_adapter/ac_osl.c linux-2.4.22/drivers/acpi/ospm/ac_adapter/ac_osl.c --- linux-2.4.21/drivers/acpi/ospm/ac_adapter/ac_osl.c 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/ac_adapter/ac_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,257 +0,0 @@ -/***************************************************************************** - * - * Module Name: ac_osl.c - * $Revision: 10 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "ac.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - AC Adapter Driver"); -MODULE_LICENSE("GPL"); - - -#define AC_PROC_ROOT "ac_adapter" -#define AC_PROC_STATUS "status" -#define AC_ON_LINE "on-line" -#define AC_OFF_LINE "off-line" - -extern struct proc_dir_entry *bm_proc_root; -static struct proc_dir_entry *ac_proc_root = NULL; - - -/**************************************************************************** - * - * FUNCTION: ac_osl_proc_read_status - * - ****************************************************************************/ - -static int -ac_osl_proc_read_status ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - acpi_status status = AE_OK; - AC_CONTEXT *ac_adapter = NULL; - char *p = page; - int len; - - if (!context) { - goto end; - } - - ac_adapter = (AC_CONTEXT*)context; - - /* don't get status more than once for a single proc read */ - if (off != 0) { - goto end; - } - - status = bm_evaluate_simple_integer(ac_adapter->acpi_handle, - "_PSR", &(ac_adapter->is_online)); - if (ACPI_FAILURE(status)) { - p += sprintf(p, "Error reading AC Adapter status\n"); - goto end; - } - - if (ac_adapter->is_online) { - p += sprintf(p, "Status: %s\n", - AC_ON_LINE); - } - else { - p += sprintf(p, "Status: %s\n", - AC_OFF_LINE); - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return(len); -} - - -/**************************************************************************** - * - * FUNCTION: ac_osl_add_device - * - ****************************************************************************/ - -acpi_status -ac_osl_add_device( - AC_CONTEXT *ac_adapter) -{ - struct proc_dir_entry *proc_entry = NULL; - - if (!ac_adapter) { - return(AE_BAD_PARAMETER); - } - - printk(KERN_INFO "ACPI: AC Adapter found\n"); - - proc_entry = proc_mkdir(ac_adapter->uid, ac_proc_root); - if (!proc_entry) { - return(AE_ERROR); - } - - create_proc_read_entry(AC_PROC_STATUS, S_IFREG | S_IRUGO, - proc_entry, ac_osl_proc_read_status, (void*)ac_adapter); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: ac_osl_remove_device - * - ****************************************************************************/ - -acpi_status -ac_osl_remove_device ( - AC_CONTEXT *ac_adapter) -{ - char proc_entry[64]; - - if (!ac_adapter) { - return(AE_BAD_PARAMETER); - } - - sprintf(proc_entry, "%s/%s", ac_adapter->uid, AC_PROC_STATUS); - remove_proc_entry(proc_entry, ac_proc_root); - - sprintf(proc_entry, "%s", ac_adapter->uid); - remove_proc_entry(proc_entry, ac_proc_root); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: ac_osl_generate_event - * - ****************************************************************************/ - -acpi_status -ac_osl_generate_event ( - u32 event, - AC_CONTEXT *ac_adapter) -{ - acpi_status status = AE_OK; - - if (!ac_adapter) { - return(AE_BAD_PARAMETER); - } - - switch (event) { - - case AC_NOTIFY_STATUS_CHANGE: - status = bm_osl_generate_event(ac_adapter->device_handle, - AC_PROC_ROOT, ac_adapter->uid, event, 0); - break; - - default: - return(AE_BAD_PARAMETER); - break; - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: ac_osl_init - * - * PARAMETERS: - * - * RETURN: 0: Success - * - * DESCRIPTION: Module initialization. - * - ****************************************************************************/ - -static int __init -ac_osl_init (void) -{ - acpi_status status = AE_OK; - - ac_proc_root = proc_mkdir(AC_PROC_ROOT, bm_proc_root); - if (!ac_proc_root) { - status = AE_ERROR; - } - else { - status = ac_initialize(); - if (ACPI_FAILURE(status)) { - remove_proc_entry(AC_PROC_ROOT, bm_proc_root); - } - - } - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - - -/**************************************************************************** - * - * FUNCTION: ac_osl_cleanup - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Module cleanup. - * - ****************************************************************************/ - -static void __exit -ac_osl_cleanup (void) -{ - ac_terminate(); - - if (ac_proc_root) { - remove_proc_entry(AC_PROC_ROOT, bm_proc_root); - } - - return; -} - - -module_init(ac_osl_init); -module_exit(ac_osl_cleanup); diff -urN linux-2.4.21/drivers/acpi/ospm/battery/Makefile linux-2.4.22/drivers/acpi/ospm/battery/Makefile --- linux-2.4.21/drivers/acpi/ospm/battery/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/battery/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/battery/bt.c linux-2.4.22/drivers/acpi/ospm/battery/bt.c --- linux-2.4.21/drivers/acpi/ospm/battery/bt.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/battery/bt.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,654 +0,0 @@ -/***************************************************************************** - * - * Module Name: bt.c - * $Revision: 29 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bt.h" - - -#define _COMPONENT ACPI_BATTERY - MODULE_NAME ("bt") - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bt_print - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Prints out information on a specific battery. - * - ****************************************************************************/ - -void -bt_print ( - BT_CONTEXT *battery) -{ -#ifdef ACPI_DEBUG - acpi_buffer buffer; - - PROC_NAME("bt_print"); - - if (!battery) { - return; - } - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - /* - * Get the full pathname for this ACPI object. - */ - acpi_get_name(battery->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - /* - * Print out basic battery information. - */ - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Battery[%02x]:[%p] %s\n", battery->device_handle, battery->acpi_handle, (char*)buffer.pointer)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| uid[%s] is_present[%d] power_units[%s]\n", battery->uid, battery->is_present, battery->power_units)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); -#endif /*ACPI_DEBUG*/ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: bt_get_info - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - * NOTES: Allocates battery_info - which must be freed by the caller. - * - ****************************************************************************/ - -acpi_status -bt_get_info ( - BT_CONTEXT *battery, - BT_BATTERY_INFO **battery_info) -{ - acpi_status status = AE_OK; - acpi_buffer bif_buffer, package_format, package_data; - acpi_object *package = NULL; - - FUNCTION_TRACE("bt_get_info"); - - if (!battery || !battery_info || *battery_info) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - memset(&bif_buffer, 0, sizeof(acpi_buffer)); - - /* - * Evalute _BIF: - * ------------- - * And be sure to deallocate bif_buffer.pointer! - */ - status = bm_evaluate_object(battery->acpi_handle, "_BIF", NULL, - &bif_buffer); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Extract Package Data: - * --------------------- - * Type-cast this bif_buffer to a package and use helper - * functions to convert results into BT_BATTERY_INFO structure. - * The first attempt is just to get the size of the package - * data; the second gets the data (once we know the required - * bif_buffer size). - */ - status = bm_cast_buffer(&bif_buffer, (void**)&package, - sizeof(acpi_object)); - if (ACPI_FAILURE(status)) { - goto end; - } - - package_format.length = sizeof("NNNNNNNNNSSSS"); - package_format.pointer = "NNNNNNNNNSSSS"; - - memset(&package_data, 0, sizeof(acpi_buffer)); - - status = bm_extract_package_data(package, &package_format, - &package_data); - if (status != AE_BUFFER_OVERFLOW) { - if (status == AE_OK) { - status = AE_ERROR; - } - goto end; - } - - package_data.pointer = acpi_os_callocate(package_data.length); - if (!package_data.pointer) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - status = bm_extract_package_data(package, &package_format, - &package_data); - if (ACPI_FAILURE(status)) { - acpi_os_free(package_data.pointer); - goto end; - } - - *battery_info = package_data.pointer; - -end: - acpi_os_free(bif_buffer.pointer); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bt_get_status - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_get_status ( - BT_CONTEXT *battery, - BT_BATTERY_STATUS **battery_status) -{ - acpi_status status = AE_OK; - acpi_buffer bst_buffer, package_format, package_data; - acpi_object *package = NULL; - - FUNCTION_TRACE("bt_get_status"); - - if (!battery || !battery_status || *battery_status) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - memset(&bst_buffer, 0, sizeof(acpi_buffer)); - - /* - * Evalute _BST: - * ------------- - * And be sure to deallocate bst_buffer.pointer! - */ - status = bm_evaluate_object(battery->acpi_handle, "_BST", - NULL, &bst_buffer); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Extract Package Data: - * --------------------- - * Type-cast this bst_buffer to a package and use helper - * functions to convert results into BT_BATTERY_STATUS structure. - * The first attempt is just to get the size of the package data; - * the second gets the data (once we know the required bst_buffer - * size). - */ - status = bm_cast_buffer(&bst_buffer, (void**)&package, - sizeof(acpi_object)); - if (ACPI_FAILURE(status)) { - goto end; - } - - package_format.length = sizeof("NNNN"); - package_format.pointer = "NNNN"; - - memset(&package_data, 0, sizeof(acpi_buffer)); - - status = bm_extract_package_data(package, &package_format, - &package_data); - if (status != AE_BUFFER_OVERFLOW) { - if (status == AE_OK) { - status = AE_ERROR; - } - goto end; - } - - package_data.pointer = acpi_os_callocate(package_data.length); - if (!package_data.pointer) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - status = bm_extract_package_data(package, &package_format, - &package_data); - if (ACPI_FAILURE(status)) { - acpi_os_free(package_data.pointer); - goto end; - } - - *battery_status = package_data.pointer; - -end: - acpi_os_free(bst_buffer.pointer); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bt_check_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_check_device ( - BT_CONTEXT *battery) -{ - acpi_status status = AE_OK; - BM_DEVICE_STATUS battery_status = BM_STATUS_UNKNOWN; - u32 was_present = FALSE; - BT_BATTERY_INFO *battery_info = NULL; - - FUNCTION_TRACE("bt_check_device"); - - if (!battery) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - was_present = battery->is_present; - - /* - * Battery Present? - * ---------------- - * Get the device status and check if battery slot is occupied. - */ - status = bm_get_device_status(battery->device_handle, &battery_status); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unable to get battery status.\n")); - return_ACPI_STATUS(status); - } - - if (battery_status & BM_STATUS_BATTERY_PRESENT) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Battery socket occupied.\n")); - battery->is_present = TRUE; - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Battery socket not occupied.\n")); - battery->is_present = FALSE; - } - - /* - * Battery Appeared? - * ----------------- - */ - if (!was_present && battery->is_present) { - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Battery insertion detected.\n")); - - /* - * Units of Power? - * --------------- - * Get the 'units of power', as we'll need this to report - * status information. - */ - status = bt_get_info(battery, &battery_info); - if (ACPI_SUCCESS(status)) { - battery->power_units = (battery_info->power_unit) - ? BT_POWER_UNITS_AMPS : BT_POWER_UNITS_WATTS; - acpi_os_free(battery_info); - } - } - - /* - * Battery Disappeared? - * -------------------- - */ - else if (was_present && !battery->is_present) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Battery removal detected.\n")); - battery->power_units = BT_POWER_UNITS_DEFAULT; - } - - return_ACPI_STATUS(status); -} - - -/***************************************************************************** - * - * FUNCTION: bt_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_add_device ( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - BT_CONTEXT *battery = NULL; - - FUNCTION_TRACE("bt_add_device"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding battery device [%02x].\n", device_handle)); - - if (!context || *context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Get information on this device. - */ - status = bm_get_device_info(device_handle, &device); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Allocate a new BT_CONTEXT structure. - */ - battery = acpi_os_callocate(sizeof(BT_CONTEXT)); - if (!battery) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - battery->device_handle = device->handle; - battery->acpi_handle = device->acpi_handle; - strncpy(battery->uid, device->id.uid, sizeof(battery->uid)); - - battery->power_units = BT_POWER_UNITS_DEFAULT; - battery->is_present = FALSE; - - /* - * See if battery is really present. - */ - status = bt_check_device(battery); - if (ACPI_FAILURE(status)) { - goto end; - } - - status = bt_osl_add_device(battery); - if (ACPI_FAILURE(status)) { - goto end; - } - - *context = battery; - - bt_print(battery); - -end: - if (ACPI_FAILURE(status)) { - acpi_os_free(battery); - } - - return_ACPI_STATUS(status); -} - - -/***************************************************************************** - * - * FUNCTION: bt_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_remove_device ( - void **context) -{ - acpi_status status = AE_OK; - BT_CONTEXT *battery = NULL; - - FUNCTION_TRACE("bt_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - battery = (BT_CONTEXT*)*context; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing battery device [%02x].\n", battery->device_handle)); - - bt_osl_remove_device(battery); - - acpi_os_free(battery); - - *context = NULL; - - return_ACPI_STATUS(status); -} - - -/***************************************************************************** - * External Functions - *****************************************************************************/ - -/***************************************************************************** - * - * FUNCTION: bt_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_initialize (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("bt_initialize"); - - memset(&criteria, 0, sizeof(BM_DEVICE_ID)); - memset(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Register driver for driver method battery devices. - */ - MEMCPY(criteria.hid, BT_HID_CM_BATTERY, sizeof(BT_HID_CM_BATTERY)); - - driver.notify = &bt_notify; - driver.request = &bt_request; - - status = bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bt_terminate - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_terminate (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("bt_terminate"); - - memset(&criteria, 0, sizeof(BM_DEVICE_ID)); - memset(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Unregister driver for driver method battery devices. - */ - MEMCPY(criteria.hid, BT_HID_CM_BATTERY, sizeof(BT_HID_CM_BATTERY)); - - driver.notify = &bt_notify; - driver.request = &bt_request; - - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bt_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bt_notify"); - - if (!context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - switch (notify_type) { - - case BM_NOTIFY_DEVICE_ADDED: - status = bt_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = bt_remove_device(context); - break; - - case BT_NOTIFY_STATUS_CHANGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status change (_BST) event detected.\n")); - status = bt_osl_generate_event(notify_type, - ((BT_CONTEXT*)*context)); - break; - - case BT_NOTIFY_INFORMATION_CHANGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Information change (_BIF) event detected.\n")); - status = bt_check_device((BT_CONTEXT*)*context); - if (ACPI_SUCCESS(status)) { - status = bt_osl_generate_event(notify_type, - ((BT_CONTEXT*)*context)); - } - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bt_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bt_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bt_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - /* - * Handle request: - * --------------- - */ - switch (request->command) { - - default: - status = AE_SUPPORT; - break; - } - - request->status = status; - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/battery/bt_osl.c linux-2.4.22/drivers/acpi/ospm/battery/bt_osl.c --- linux-2.4.21/drivers/acpi/ospm/battery/bt_osl.c 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/battery/bt_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,443 +0,0 @@ -/****************************************************************************** - * - * Module Name: bt_osl.c - * $Revision: 24 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - */ - -/* - * Changes: - * Brendan Burns 2000-11-15 - * - added proc battery interface - * - parse returned data from _BST and _BIF - * Andy Grover 2000-12-8 - * - improved proc interface - */ - - -#include -#include -#include -#include -#include -#include -#include "bt.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Control Method Battery Driver"); -MODULE_LICENSE("GPL"); - - -#define BT_PROC_ROOT "battery" -#define BT_PROC_STATUS "status" -#define BT_PROC_INFO "info" - -extern struct proc_dir_entry *bm_proc_root; -static struct proc_dir_entry *bt_proc_root = NULL; - - -/**************************************************************************** - * - * FUNCTION: bt_osl_proc_read_info - * - ****************************************************************************/ - -static int -bt_osl_proc_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - BT_CONTEXT *battery = NULL; - BT_BATTERY_INFO *battery_info = NULL; - char *p = page; - int len = 0; - - if (!context || (off != 0)) { - goto end; - } - - battery = (BT_CONTEXT*)context; - - /* - * Battery Present? - * ---------------- - */ - if (!battery->is_present) { - p += sprintf(p, "Present: no\n"); - goto end; - } - else { - p += sprintf(p, "Present: yes\n"); - } - - /* - * Get Battery Information: - * ------------------------ - */ - if (ACPI_FAILURE(bt_get_info(battery, &battery_info))) { - p += sprintf(p, "Error reading battery information (_BIF)\n"); - goto end; - } - - if (battery_info->design_capacity == BT_UNKNOWN) { - p += sprintf(p, "Design Capacity: unknown\n"); - } - else { - p += sprintf(p, "Design Capacity: %d %sh\n", - (u32)battery_info->design_capacity, - battery->power_units); - } - - if (battery_info->last_full_capacity == BT_UNKNOWN) { - p += sprintf(p, "Last Full Capacity: unknown\n"); - } - else { - p += sprintf(p, "Last Full Capacity: %d %sh\n", - (u32)battery_info->last_full_capacity, - battery->power_units); - } - - if (battery_info->battery_technology == 0) { - p += sprintf(p, "Battery Technology: primary (non-rechargeable)\n"); - } - else if (battery_info->battery_technology == 1) { - p += sprintf(p, "Battery Technology: secondary (rechargeable)\n"); - } - else { - p += sprintf(p, "Battery Technology: unknown\n"); - } - - if (battery_info->design_voltage == BT_UNKNOWN) { - p += sprintf(p, "Design Voltage: unknown\n"); - } - else { - p += sprintf(p, "Design Voltage: %d mV\n", - (u32)battery_info->design_voltage); - } - - p += sprintf(p, "Design Capacity Warning: %d %sh\n", - (u32)battery_info->design_capacity_warning, - battery->power_units); - p += sprintf(p, "Design Capacity Low: %d %sh\n", - (u32)battery_info->design_capacity_low, - battery->power_units); - p += sprintf(p, "Capacity Granularity 1: %d %sh\n", - (u32)battery_info->battery_capacity_granularity_1, - battery->power_units); - p += sprintf(p, "Capacity Granularity 2: %d %sh\n", - (u32)battery_info->battery_capacity_granularity_2, - battery->power_units); - p += sprintf(p, "Model Number: %s\n", - battery_info->model_number); - p += sprintf(p, "Serial Number: %s\n", - battery_info->serial_number); - p += sprintf(p, "Battery Type: %s\n", - battery_info->battery_type); - p += sprintf(p, "OEM Info: %s\n", - battery_info->oem_info); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - acpi_os_free(battery_info); - - return(len); -} - - -/**************************************************************************** - * - * FUNCTION: bt_osl_proc_read_status - * - ****************************************************************************/ - -static int -bt_osl_proc_read_status ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - BT_CONTEXT *battery = NULL; - BT_BATTERY_STATUS *battery_status = NULL; - char *p = page; - int len = 0; - - if (!context || (off != 0)) { - goto end; - } - - battery = (BT_CONTEXT*)context; - - /* - * Battery Present? - * ---------------- - */ - if (!battery->is_present) { - p += sprintf(p, "Present: no\n"); - goto end; - } - else { - p += sprintf(p, "Present: yes\n"); - } - - /* - * Get Battery Status: - * ------------------- - */ - if (ACPI_FAILURE(bt_get_status(battery, &battery_status))) { - p += sprintf(p, "Error reading battery status (_BST)\n"); - goto end; - } - - /* - * Store Data: - * ----------- - */ - - if (!battery_status->state) { - p += sprintf(p, "State: ok\n"); - } - else { - if (battery_status->state & 0x1) - p += sprintf(p, "State: discharging\n"); - if (battery_status->state & 0x2) - p += sprintf(p, "State: charging\n"); - if (battery_status->state & 0x4) - p += sprintf(p, "State: critically low\n"); - } - - if (battery_status->present_rate == BT_UNKNOWN) { - p += sprintf(p, "Present Rate: unknown\n"); - } - else { - p += sprintf(p, "Present Rate: %d %s\n", - (u32)battery_status->present_rate, - battery->power_units); - } - - if (battery_status->remaining_capacity == BT_UNKNOWN) { - p += sprintf(p, "Remaining Capacity: unknown\n"); - } - else { - p += sprintf(p, "Remaining Capacity: %d %sh\n", - (u32)battery_status->remaining_capacity, - battery->power_units); - } - - if (battery_status->present_voltage == BT_UNKNOWN) { - p += sprintf(p, "Battery Voltage: unknown\n"); - } - else { - p += sprintf(p, "Battery Voltage: %d mV\n", - (u32)battery_status->present_voltage); - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - acpi_os_free(battery_status); - - return(len); -} - - -/**************************************************************************** - * - * FUNCTION: bt_osl_add_device - * - ****************************************************************************/ - -acpi_status -bt_osl_add_device( - BT_CONTEXT *battery) -{ - struct proc_dir_entry *proc_entry = NULL; - - if (!battery) { - return(AE_BAD_PARAMETER); - } - - if (battery->is_present) { - printk("ACPI: Battery socket found, battery present\n"); - } - else { - printk("ACPI: Battery socket found, battery absent\n"); - } - - proc_entry = proc_mkdir(battery->uid, bt_proc_root); - if (!proc_entry) { - return(AE_ERROR); - } - - create_proc_read_entry(BT_PROC_STATUS, S_IFREG | S_IRUGO, - proc_entry, bt_osl_proc_read_status, (void*)battery); - - create_proc_read_entry(BT_PROC_INFO, S_IFREG | S_IRUGO, - proc_entry, bt_osl_proc_read_info, (void*)battery); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bt_osl_remove_device - * - ****************************************************************************/ - -acpi_status -bt_osl_remove_device ( - BT_CONTEXT *battery) -{ - char proc_entry[64]; - - if (!battery) { - return(AE_BAD_PARAMETER); - } - - sprintf(proc_entry, "%s/%s", battery->uid, BT_PROC_INFO); - remove_proc_entry(proc_entry, bt_proc_root); - - sprintf(proc_entry, "%s/%s", battery->uid, BT_PROC_STATUS); - remove_proc_entry(proc_entry, bt_proc_root); - - sprintf(proc_entry, "%s", battery->uid); - remove_proc_entry(proc_entry, bt_proc_root); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bt_osl_generate_event - * - ****************************************************************************/ - -acpi_status -bt_osl_generate_event ( - u32 event, - BT_CONTEXT *battery) -{ - acpi_status status = AE_OK; - - if (!battery) { - return(AE_BAD_PARAMETER); - } - - switch (event) { - - case BT_NOTIFY_STATUS_CHANGE: - case BT_NOTIFY_INFORMATION_CHANGE: - status = bm_osl_generate_event(battery->device_handle, - BT_PROC_ROOT, battery->uid, event, 0); - break; - - default: - return(AE_BAD_PARAMETER); - break; - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: bt_osl_init - * - * PARAMETERS: - * - * RETURN: 0: Success - * - * DESCRIPTION: Module initialization. - * - ****************************************************************************/ - -static int __init -bt_osl_init (void) -{ - acpi_status status = AE_OK; - - /* abort if no busmgr */ - if (!bm_proc_root) - return -ENODEV; - - bt_proc_root = proc_mkdir(BT_PROC_ROOT, bm_proc_root); - if (!bt_proc_root) { - status = AE_ERROR; - } - else { - status = bt_initialize(); - if (ACPI_FAILURE(status)) { - remove_proc_entry(BT_PROC_ROOT, bm_proc_root); - } - } - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - - -/**************************************************************************** - * - * FUNCTION: bt_osl_cleanup - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Module cleanup. - * - ****************************************************************************/ - -static void __exit -bt_osl_cleanup (void) -{ - bt_terminate(); - - if (bt_proc_root) { - remove_proc_entry(BT_PROC_ROOT, bm_proc_root); - } - - return; -} - - -module_init(bt_osl_init); -module_exit(bt_osl_cleanup); diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/Makefile linux-2.4.22/drivers/acpi/ospm/busmgr/Makefile --- linux-2.4.21/drivers/acpi/ospm/busmgr/Makefile 2001-09-02 07:48:02.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,8 +0,0 @@ -export-objs := bm_osl.o - -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bm.c linux-2.4.22/drivers/acpi/ospm/busmgr/bm.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bm.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bm.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1146 +0,0 @@ -/****************************************************************************** - * - * Module Name: bm.c - * $Revision: 48 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bm.h" - - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bm") - - -/**************************************************************************** - * Globals - ****************************************************************************/ - -extern fadt_descriptor_rev2 acpi_fadt; -/* TBD: Make dynamically sizeable. */ -BM_NODE_LIST node_list; - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/***************************************************************************** - * - * FUNCTION: bm_print_object - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -bm_print_object ( - acpi_handle handle) -{ - acpi_buffer buffer; - acpi_handle parent; - acpi_object_type type; - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); - acpi_get_parent(handle, &parent); - acpi_get_type(handle, &type); - - /* - * TBD: Hack to get around scope identification problem. - */ - if (type == ACPI_TYPE_ANY) { - if (ACPI_SUCCESS(acpi_get_next_object(ACPI_TYPE_ANY, - handle, 0, NULL))) { - type = INTERNAL_TYPE_SCOPE; - } - } - - switch (type) - { - case INTERNAL_TYPE_SCOPE: - acpi_os_printf("SCOPE: "); - break; - case ACPI_TYPE_INTEGER: - acpi_os_printf("SIMPLE (number): "); - break; - case ACPI_TYPE_STRING: - acpi_os_printf("SIMPLE (string): "); - break; - case ACPI_TYPE_BUFFER: - acpi_os_printf("SIMPLE (buffer): "); - break; - case ACPI_TYPE_PACKAGE: - acpi_os_printf("SIMPLE (package): "); - break; - case ACPI_TYPE_FIELD_UNIT: - acpi_os_printf("FIELD UNIT: "); - break; - case ACPI_TYPE_DEVICE: - acpi_os_printf("DEVICE: "); - break; - case ACPI_TYPE_EVENT: - acpi_os_printf("EVENT: "); - break; - case ACPI_TYPE_METHOD: - acpi_os_printf("CONTROL METHOD: "); - break; - case ACPI_TYPE_MUTEX: - acpi_os_printf("MUTEX: "); - break; - case ACPI_TYPE_REGION: - acpi_os_printf("OPERATION REGION: "); - break; - case ACPI_TYPE_POWER: - acpi_os_printf("POWER RESOURCE: "); - break; - case ACPI_TYPE_PROCESSOR: - acpi_os_printf("PROCESSOR: "); - break; - case ACPI_TYPE_THERMAL: - acpi_os_printf("THERMAL ZONE: "); - break; - case ACPI_TYPE_BUFFER_FIELD: - acpi_os_printf("BUFFER FIELD: "); - break; - case ACPI_TYPE_DDB_HANDLE: - acpi_os_printf("DDB HANDLE: "); - break; - default: - acpi_os_printf("OTHER (%d): ", type); - break; - } - - acpi_os_printf("Object[%p][%s] parent[%p].\n", handle, (char*)buffer.pointer, parent); - - acpi_os_free(buffer.pointer); -} - - -/**************************************************************************** - * - * FUNCTION: bm_print_node - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -bm_print_node ( - BM_NODE *node, - u32 flags) -{ -#ifdef ACPI_DEBUG - acpi_buffer buffer; - BM_DEVICE *device = NULL; - char *type_string = NULL; - - PROC_NAME("bm_print_node"); - - if (!node) { - return; - } - - device = &(node->device); - - if (flags & BM_PRINT_PRESENT) { - if (!BM_DEVICE_PRESENT(device)) { - return; - } - } - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - acpi_get_name(device->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - switch(device->id.type) { - case BM_TYPE_SYSTEM: - type_string = " System"; - break; - case BM_TYPE_SCOPE: - type_string = " Scope"; - break; - case BM_TYPE_PROCESSOR: - type_string = " Proc"; - break; - case BM_TYPE_THERMAL_ZONE: - type_string = "Thermal"; - break; - case BM_TYPE_POWER_RESOURCE: - type_string = " Power"; - break; - case BM_TYPE_FIXED_BUTTON: - type_string = " Button"; - break; - case BM_TYPE_DEVICE: - type_string = " Device"; - break; - default: - type_string = "Unknown"; - break; - } - - if (!(flags & BM_PRINT_GROUP)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+-------------------------------------------------------------------------------\n")); - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| %s[%02x]:[%p] flags[%02x] hid[%s] %s\n", type_string, device->handle, device->acpi_handle, device->flags, (device->id.hid[0] ? device->id.hid : " "), (char*)buffer.pointer)); - - if (flags & BM_PRINT_IDENTIFICATION) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| identification: uid[%s] adr[%08x]\n", device->id.uid, device->id.adr)); - } - - if (flags & BM_PRINT_LINKAGE) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| linkage: this[%p] parent[%p] next[%p]\n", node, node->parent, node->next)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| scope.head[%p] scope.tail[%p]\n", node->scope.head, node->scope.tail)); - } - - if (flags & BM_PRINT_POWER) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| power: state[D%d] flags[%08x]\n", device->power.state, device->power.flags)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| S0[%02x] S1[%02x] S2[%02x] S3[%02x] S4[%02x] S5[%02x]\n", device->power.dx_supported[0], device->power.dx_supported[1], device->power.dx_supported[2], device->power.dx_supported[3], device->power.dx_supported[4], device->power.dx_supported[5])); - } - - if (!(flags & BM_PRINT_GROUP)) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+-------------------------------------------------------------------------------\n")); - } - - acpi_os_free(buffer.pointer); -#endif /*ACPI_DEBUG*/ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: bm_print_hierarchy - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -bm_print_hierarchy (void) -{ -#ifdef ACPI_DEBUG - u32 i = 0; - - FUNCTION_TRACE("bm_print_hierarchy"); - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - for (i = 0; i < node_list.count; i++) { - bm_print_node(node_list.nodes[i], BM_PRINT_GROUP | BM_PRINT_PRESENT); - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); -#endif /*ACPI_DEBUG*/ - - return_VOID; -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_status - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_status ( - BM_DEVICE *device) -{ - acpi_status status = AE_OK; - - if (!device) { - return AE_BAD_PARAMETER; - } - - device->status = BM_STATUS_UNKNOWN; - - /* - * Dynamic Status? - * --------------- - * If _STA isn't present we just return the default status. - */ - if (!(device->flags & BM_FLAGS_DYNAMIC_STATUS)) { - device->status = BM_STATUS_DEFAULT; - return AE_OK; - } - - /* - * Evaluate _STA: - * -------------- - */ - status = bm_evaluate_simple_integer(device->acpi_handle, "_STA", - &(device->status)); - - return status; -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_identification - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_identification ( - BM_DEVICE *device) -{ - acpi_status status = AE_OK; - acpi_device_info info; - - if (!device) { - return AE_BAD_PARAMETER; - } - - if (!(device->flags & BM_FLAGS_IDENTIFIABLE)) { - return AE_OK; - } - - device->id.uid[0] = BM_UID_UNKNOWN; - device->id.hid[0] = BM_HID_UNKNOWN; - device->id.adr = BM_ADDRESS_UNKNOWN; - - /* - * Get Object Info: - * ---------------- - * Evalute _UID, _HID, and _ADR... - */ - status = acpi_get_object_info(device->acpi_handle, &info); - if (ACPI_FAILURE(status)) { - return status; - } - - if (info.valid & ACPI_VALID_UID) { - MEMCPY((void*)device->id.uid, (void*)info.unique_id, - sizeof(BM_DEVICE_UID)); - } - - if (info.valid & ACPI_VALID_HID) { - MEMCPY((void*)device->id.hid, (void*)info.hardware_id, - sizeof(BM_DEVICE_HID)); - } - - if (info.valid & ACPI_VALID_ADR) { - device->id.adr = info.address; - } - - return status; -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_flags - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_flags ( - BM_DEVICE *device) -{ - acpi_handle acpi_handle = NULL; - - if (!device) { - return AE_BAD_PARAMETER; - } - - device->flags = BM_FLAGS_UNKNOWN; - - switch (device->id.type) { - - case BM_TYPE_DEVICE: - - /* - * Presence of _DCK indicates a docking station. - */ - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_DCK", &acpi_handle))) { - device->flags |= BM_FLAGS_DOCKING_STATION; - } - - /* - * Presence of _EJD and/or _EJx indicates 'ejectable'. - * TBD: _EJx... - */ - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_EJD", &acpi_handle))) { - device->flags |= BM_FLAGS_EJECTABLE; - } - - /* - * Presence of _PR0 or _PS0 indicates 'power manageable'. - */ - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_PR0", &acpi_handle)) || - ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_PS0", &acpi_handle))) { - device->flags |= BM_FLAGS_POWER_CONTROL; - } - - /* - * Presence of _CRS indicates 'configurable'. - */ - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_CRS", &acpi_handle))) { - device->flags |= BM_FLAGS_CONFIGURABLE; - } - - /* Fall through to next case statement. */ - - case BM_TYPE_PROCESSOR: - case BM_TYPE_THERMAL_ZONE: - case BM_TYPE_POWER_RESOURCE: - /* - * Presence of _HID or _ADR indicates 'identifiable'. - */ - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_HID", &acpi_handle)) || - ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_ADR", &acpi_handle))) { - device->flags |= BM_FLAGS_IDENTIFIABLE; - } - - /* - * Presence of _STA indicates 'dynamic status'. - */ - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, - "_STA", &acpi_handle))) { - device->flags |= BM_FLAGS_DYNAMIC_STATUS; - } - - break; - } - - return AE_OK; -} - - -/**************************************************************************** - * - * FUNCTION: bm_add_namespace_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_add_namespace_device ( - acpi_handle acpi_handle, - acpi_object_type acpi_type, - BM_NODE *parent, - BM_NODE **child) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - BM_DEVICE *device = NULL; - - FUNCTION_TRACE("bm_add_namespace_device"); - - if (!parent || !child) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (node_list.count > BM_HANDLES_MAX) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - (*child) = NULL; - - /* - * Create Node: - * ------------ - */ - node = acpi_os_callocate(sizeof(BM_NODE)); - if (!node) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - node->parent = parent; - node->next = NULL; - - device = &(node->device); - - device->handle = node_list.count; - device->acpi_handle = acpi_handle; - - /* - * Device Type: - * ------------ - */ - switch (acpi_type) { - case INTERNAL_TYPE_SCOPE: - device->id.type = BM_TYPE_SCOPE; - break; - case ACPI_TYPE_PROCESSOR: - device->id.type = BM_TYPE_PROCESSOR; - break; - case ACPI_TYPE_THERMAL: - device->id.type = BM_TYPE_THERMAL_ZONE; - break; - case ACPI_TYPE_POWER: - device->id.type = BM_TYPE_POWER_RESOURCE; - break; - case ACPI_TYPE_DEVICE: - device->id.type = BM_TYPE_DEVICE; - break; - } - - /* - * Get Other Device Info: - * ---------------------- - * But only if this device's parent is present (which implies - * this device MAY be present). - */ - if (BM_NODE_PRESENT(node->parent)) { - /* - * Device Flags - */ - status = bm_get_flags(device); - if (ACPI_FAILURE(status)) { - goto end; - } - - /* - * Device Identification - */ - status = bm_get_identification(device); - if (ACPI_FAILURE(status)) { - goto end; - } - - /* - * Device Status - */ - status = bm_get_status(device); - if (ACPI_FAILURE(status)) { - goto end; - } - - /* - * Power Management: - * ----------------- - * If this node doesn't provide direct power control - * then we inherit PM capabilities from its parent. - * - * TBD: Inherit! - */ - if (BM_IS_POWER_CONTROL(device)) { - status = bm_get_pm_capabilities(node); - if (ACPI_FAILURE(status)) { - goto end; - } - } - } - -end: - if (ACPI_FAILURE(status)) { - acpi_os_free(node); - } - else { - /* - * Add to the node_list. - */ - node_list.nodes[node_list.count++] = node; - - /* - * Formulate Hierarchy: - * -------------------- - * Arrange within the namespace by assigning the parent and - * adding to the parent device's list of children (scope). - */ - if (!parent->scope.head) { - parent->scope.head = node; - } - else { - if (!parent->scope.tail) { - (parent->scope.head)->next = node; - } - else { - (parent->scope.tail)->next = node; - } - } - parent->scope.tail = node; - - (*child) = node; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_enumerate_namespace - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_enumerate_namespace (void) -{ - acpi_status status = AE_OK; - acpi_handle parent_handle = ACPI_ROOT_OBJECT; - acpi_handle child_handle = NULL; - BM_NODE *parent = NULL; - BM_NODE *child = NULL; - acpi_object_type acpi_type = 0; - u32 level = 1; - - FUNCTION_TRACE("bm_enumerate_namespace"); - - parent = node_list.nodes[0]; - - /* - * Enumerate ACPI Namespace: - * ------------------------- - * Parse through the ACPI namespace, identify all 'devices', - * and create a new entry for each in our collection. - */ - while (level > 0) { - - /* - * Get the next object at this level. - */ - status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle, child_handle, &child_handle); - if (ACPI_SUCCESS(status)) { - /* - * TBD: This is a hack to get around the problem - * identifying scope objects. Scopes - * somehow need to be uniquely identified. - */ - status = acpi_get_type(child_handle, &acpi_type); - if (ACPI_SUCCESS(status) && (acpi_type == ACPI_TYPE_ANY)) { - status = acpi_get_next_object(ACPI_TYPE_ANY, child_handle, 0, NULL); - if (ACPI_SUCCESS(status)) { - acpi_type = INTERNAL_TYPE_SCOPE; - } - } - - /* - * Device? - * ------- - * If this object is a 'device', insert into the - * ACPI Bus Manager's local hierarchy and search - * the object's scope for any child devices (a - * depth-first search). - */ - switch (acpi_type) { - case INTERNAL_TYPE_SCOPE: - case ACPI_TYPE_DEVICE: - case ACPI_TYPE_PROCESSOR: - case ACPI_TYPE_THERMAL: - case ACPI_TYPE_POWER: - status = bm_add_namespace_device(child_handle, acpi_type, parent, &child); - if (ACPI_SUCCESS(status)) { - status = acpi_get_next_object(ACPI_TYPE_ANY, child_handle, 0, NULL); - if (ACPI_SUCCESS(status)) { - level++; - parent_handle = child_handle; - child_handle = 0; - parent = child; - } - } - break; - } - } - - /* - * Scope Exhausted: - * ---------------- - * No more children in this object's scope, Go back up - * in the namespace tree to the object's parent. - */ - else { - level--; - child_handle = parent_handle; - acpi_get_parent(parent_handle, - &parent_handle); - - if (parent) { - parent = parent->parent; - } - else { - return_ACPI_STATUS(AE_NULL_ENTRY); - } - } - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_add_fixed_feature_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_add_fixed_feature_device ( - BM_NODE *parent, - BM_DEVICE_TYPE device_type, - char *device_hid) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_add_fixed_feature_device"); - - if (!parent) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (node_list.count > BM_HANDLES_MAX) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* - * Allocate the new device and add to the device array. - */ - node = acpi_os_callocate(sizeof(BM_NODE)); - if (!node) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* - * Get device info. - */ - node->device.handle = node_list.count; - node->device.acpi_handle = ACPI_ROOT_OBJECT; - node->device.id.type = BM_TYPE_FIXED_BUTTON; - if (device_hid) { - MEMCPY((void*)node->device.id.hid, device_hid, - sizeof(node->device.id.hid)); - } - node->device.flags = BM_FLAGS_FIXED_FEATURE; - node->device.status = BM_STATUS_DEFAULT; - /* TBD: Device PM capabilities */ - - /* - * Add to the node_list. - */ - node_list.nodes[node_list.count++] = node; - - /* - * Formulate Hierarchy: - * -------------------- - * Arrange within the namespace by assigning the parent and - * adding to the parent device's list of children (scope). - */ - node->parent = parent; - node->next = NULL; - - if (parent) { - if (!parent->scope.head) { - parent->scope.head = node; - } - else { - if (!parent->scope.tail) { - (parent->scope.head)->next = node; - } - else { - (parent->scope.tail)->next = node; - } - } - parent->scope.tail = node; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_enumerate_fixed_features - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_enumerate_fixed_features (void) -{ - FUNCTION_TRACE("bm_enumerate_fixed_features"); - - /* - * Root Object: - * ------------ - * Fabricate the root object, which happens to always get a - * device_handle of zero. - */ - node_list.nodes[0] = acpi_os_callocate(sizeof(BM_NODE)); - if (NULL == (node_list.nodes[0])) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - node_list.nodes[0]->device.handle = BM_HANDLE_ROOT; - node_list.nodes[0]->device.acpi_handle = ACPI_ROOT_OBJECT; - node_list.nodes[0]->device.flags = BM_FLAGS_UNKNOWN; - node_list.nodes[0]->device.status = BM_STATUS_DEFAULT; - node_list.nodes[0]->device.id.type = BM_TYPE_SYSTEM; - /* TBD: Get system PM capabilities (Sx states?) */ - - node_list.count++; - - /* - * Fixed Features: - * --------------- - * Enumerate fixed-feature devices (e.g. power and sleep buttons). - */ - if (acpi_fadt.pwr_button == 0) { - bm_add_fixed_feature_device(node_list.nodes[0], - BM_TYPE_FIXED_BUTTON, BM_HID_POWER_BUTTON); - } - - if (acpi_fadt.sleep_button == 0) { - bm_add_fixed_feature_device(node_list.nodes[0], - BM_TYPE_FIXED_BUTTON, BM_HID_SLEEP_BUTTON); - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_handle - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_handle ( - acpi_handle acpi_handle, - BM_HANDLE *device_handle) -{ - acpi_status status = AE_NOT_FOUND; - u32 i = 0; - - FUNCTION_TRACE("bm_get_handle"); - - if (!device_handle) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - *device_handle = BM_HANDLE_UNKNOWN; - - /* - * Search all devices for a match on the ACPI handle. - */ - for (i=0; idevice.acpi_handle == acpi_handle) { - *device_handle = node_list.nodes[i]->device.handle; - status = AE_OK; - break; - } - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_node - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_node ( - BM_HANDLE device_handle, - acpi_handle acpi_handle, - BM_NODE **node) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bm_get_node"); - - if (!node) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* busmgr failed to init, but we're being called by subordinate drivers */ - if (node_list.count < 1) { - return_ACPI_STATUS(AE_NOT_FOUND); - } - - /* - * If no device handle, resolve acpi handle to device handle. - */ - if (!device_handle && acpi_handle) { - status = bm_get_handle(acpi_handle, &device_handle); - if (ACPI_FAILURE(status)) - return_ACPI_STATUS(status); - } - - /* - * Valid device handle? - */ - if (device_handle > BM_HANDLES_MAX) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid node handle [%02x] detected.\n", device_handle)); - return_ACPI_STATUS(AE_ERROR); - } - - *node = node_list.nodes[device_handle]; - - /* - * Valid node? - */ - if (!(*node)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) node entry [%02x] detected.\n", device_handle)); - return_ACPI_STATUS(AE_NULL_ENTRY); - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_initialize - * - * PARAMETERS: - * - * RETURN: Exception code. - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_initialize (void) -{ - acpi_status status = AE_OK; - u32 start = 0; - u32 stop = 0; - u32 elapsed = 0; - - FUNCTION_TRACE("bm_initialize"); - - MEMSET(&node_list, 0, sizeof(BM_NODE_LIST)); - - status = acpi_get_timer(&start); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Building device hierarchy.\n")); - - /* - * Enumerate ACPI fixed-feature devices. - */ - status = bm_enumerate_fixed_features(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Enumerate the ACPI namespace. - */ - status = bm_enumerate_namespace(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - acpi_get_timer(&stop); - acpi_get_timer_duration(start, stop, &elapsed); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Building device hierarchy took [%d] microseconds.\n", elapsed)); - - /* - * Display hierarchy. - */ - bm_print_hierarchy(); - - /* - * Register for all standard and device-specific notifications. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registering for all device notifications.\n")); - - status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, - ACPI_SYSTEM_NOTIFY, &bm_notify, NULL); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to register for standard notifications.\n")); - return_ACPI_STATUS(status); - } - - status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, - ACPI_DEVICE_NOTIFY, &bm_notify, NULL); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to register for device-specific notifications.\n")); - return_ACPI_STATUS(status); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Bus Manager enabled.\n")); - - /* - * Initialize built-in power resource driver. - */ - bm_pr_initialize(); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_terminate - * - * PARAMETERS: - * - * RETURN: Exception code. - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_terminate (void) -{ - acpi_status status = AE_OK; - u32 i = 0; - - FUNCTION_TRACE("bm_terminate"); - - /* - * Terminate built-in power resource driver. - */ - bm_pr_terminate(); - - /* - * Unregister for all notifications. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unregistering for device notifications.\n")); - - status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, - ACPI_SYSTEM_NOTIFY, &bm_notify); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to un-register for standard notifications.\n")); - } - - status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, - ACPI_DEVICE_NOTIFY, &bm_notify); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to un-register for device-specific notifications.\n")); - } - - /* - * Parse through the device array, freeing all entries. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing device hierarchy.\n")); - for (i = 0; i < node_list.count; i++) { - if (node_list.nodes[i]) { - acpi_os_free(node_list.nodes[i]); - } - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Bus Manager disabled.\n")); - - return_ACPI_STATUS(AE_OK); -} diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bm_osl.c linux-2.4.22/drivers/acpi/ospm/busmgr/bm_osl.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bm_osl.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bm_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,390 +0,0 @@ -/***************************************************************************** - * - * Module Name: bm_osl.c - * $Revision: 17 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "bm.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - ACPI Bus Manager"); -MODULE_LICENSE("GPL"); - - -/***************************************************************************** - * Types & Defines - *****************************************************************************/ - -typedef struct -{ - BM_HANDLE device_handle; - char *device_type; - char *device_instance; - u32 event_type; - u32 event_data; - struct list_head list; -} BM_OSL_EVENT; - - -#define BM_PROC_ROOT "acpi" -#define BM_PROC_EVENT "event" -#define BM_PROC_DEVICES "devices" - -#define BM_MAX_STRING_LENGTH 80 - - -/**************************************************************************** - * Globals - ****************************************************************************/ - -struct proc_dir_entry *bm_proc_root = NULL; -static struct proc_dir_entry *bm_proc_event = NULL; - -#ifdef ACPI_DEBUG -static u32 save_dbg_layer; -static u32 save_dbg_level; -#endif /*ACPI_DEBUG*/ - -extern BM_NODE_LIST node_list; - -static spinlock_t bm_osl_event_lock = SPIN_LOCK_UNLOCKED; - -static LIST_HEAD(bm_event_list); - -static DECLARE_WAIT_QUEUE_HEAD(bm_event_wait_queue); - -static int event_is_open = 0; - - -/**************************************************************************** - * Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_osl_generate_event - * - * DESCRIPTION: Generates an event for user-space consumption by writing - * the event data to the 'event' file. - * - ****************************************************************************/ - -acpi_status -bm_osl_generate_event ( - BM_HANDLE device_handle, - char *device_type, - char *device_instance, - u32 event_type, - u32 event_data) -{ - BM_OSL_EVENT *event = NULL; - unsigned long flags = 0; - - /* drop event on the floor if no one's listening */ - if (!event_is_open) - return (AE_OK); - - /* - * Allocate a new event structure. - */ - event = acpi_os_callocate(sizeof(BM_OSL_EVENT)); - if (!event) - goto alloc_error; - - event->device_type = acpi_os_callocate(strlen(device_type) - + sizeof(char)); - if (!event->device_type) - goto alloc_error; - - event->device_instance = acpi_os_callocate(strlen(device_instance) - + sizeof(char)); - if (!event->device_instance) - goto alloc_error; - - /* - * Set event data. - */ - event->device_handle = device_handle; - strcpy(event->device_type, device_type); - strcpy(event->device_instance, device_instance); - event->event_type = event_type; - event->event_data = event_data; - - /* - * Add to the end of our event list. - */ - spin_lock_irqsave(&bm_osl_event_lock, flags); - list_add_tail(&event->list, &bm_event_list); - spin_unlock_irqrestore(&bm_osl_event_lock, flags); - - /* - * Signal waiting threads (if any). - */ - wake_up_interruptible(&bm_event_wait_queue); - - return(AE_OK); - -alloc_error: - if (event->device_instance) - acpi_os_free(event->device_instance); - - if (event->device_type) - acpi_os_free(event->device_type); - - if (event) - acpi_os_free(event); - - return (AE_NO_MEMORY); -} - -static int bm_osl_open_event(struct inode *inode, struct file *file) -{ - spin_lock_irq (&bm_osl_event_lock); - - if(event_is_open) - goto out_busy; - - event_is_open = 1; - - spin_unlock_irq (&bm_osl_event_lock); - return 0; - -out_busy: - spin_unlock_irq (&bm_osl_event_lock); - return -EBUSY; -} - - -static int bm_osl_close_event(struct inode *inode, struct file *file) -{ - event_is_open = 0; - return 0; -} - -/**************************************************************************** - * - * FUNCTION: bm_osl_read_event - * - * DESCRIPTION: Handles reads to the 'event' file by blocking user-mode - * threads until data (an event) is generated. - * - ****************************************************************************/ -static ssize_t -bm_osl_read_event( - struct file *file, - char *buf, - size_t count, - loff_t *ppos) -{ - BM_OSL_EVENT *event = NULL; - unsigned long flags = 0; - static char str[BM_MAX_STRING_LENGTH]; - static int chars_remaining = 0; - static char *ptr; - - if (!chars_remaining) { - DECLARE_WAITQUEUE(wait, current); - - if (list_empty(&bm_event_list)) { - - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&bm_event_wait_queue, &wait); - - if (list_empty(&bm_event_list)) { - schedule(); - } - - remove_wait_queue(&bm_event_wait_queue, &wait); - set_current_state(TASK_RUNNING); - - if (signal_pending(current)) { - return -ERESTARTSYS; - } - } - - spin_lock_irqsave(&bm_osl_event_lock, flags); - event = list_entry(bm_event_list.next, BM_OSL_EVENT, list); - list_del(&event->list); - spin_unlock_irqrestore(&bm_osl_event_lock, flags); - - chars_remaining = sprintf(str, "%s %s %08x %08x\n", - event->device_type, event->device_instance, - event->event_type, event->event_data); - ptr = str; - - acpi_os_free(event->device_type); - acpi_os_free(event->device_instance); - acpi_os_free(event); - } - - if (chars_remaining < count) - count = chars_remaining; - - if (copy_to_user(buf, ptr, count)) - return -EFAULT; - - *ppos += count; - chars_remaining -= count; - ptr += count; - - return count; -} - -/**************************************************************************** - * - * FUNCTION: bm_osl_poll_event - * - * DESCRIPTION: Handles poll() of the 'event' file by blocking user-mode - * threads until data (an event) is generated. - * - ****************************************************************************/ -static unsigned int -bm_osl_poll_event( - struct file *file, - poll_table *wait) -{ - poll_wait(file, &bm_event_wait_queue, wait); - if (!list_empty(&bm_event_list)) - return POLLIN | POLLRDNORM; - return 0; -} - -struct file_operations proc_event_operations = { - open: bm_osl_open_event, - read: bm_osl_read_event, - release: bm_osl_close_event, - poll: bm_osl_poll_event, -}; - -/**************************************************************************** - * - * FUNCTION: bm_osl_init - * - ****************************************************************************/ - -int -bm_osl_init(void) -{ - acpi_status status = AE_OK; - - status = acpi_subsystem_status(); - if (ACPI_FAILURE(status)) - return -ENODEV; - - bm_proc_root = proc_mkdir(BM_PROC_ROOT, NULL); - if (!bm_proc_root) { - return(AE_ERROR); - } - - bm_proc_event = create_proc_entry(BM_PROC_EVENT, S_IRUSR, bm_proc_root); - if (bm_proc_event) { - bm_proc_event->proc_fops = &proc_event_operations; - } - - status = bm_initialize(); - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - - -/**************************************************************************** - * - * FUNCTION: bm_osl_cleanup - * - ****************************************************************************/ - -void -bm_osl_cleanup(void) -{ - bm_terminate(); - - if (bm_proc_event) { - remove_proc_entry(BM_PROC_EVENT, bm_proc_root); - bm_proc_event = NULL; - } - - if (bm_proc_root) { - remove_proc_entry(BM_PROC_ROOT, NULL); - bm_proc_root = NULL; - } - - return; -} - - -module_init(bm_osl_init); -module_exit(bm_osl_cleanup); - - -/**************************************************************************** - * Symbols - ****************************************************************************/ - -/* bm.c */ - -EXPORT_SYMBOL(bm_get_node); - -/* bmdriver.c */ - -EXPORT_SYMBOL(bm_get_device_power_state); -EXPORT_SYMBOL(bm_set_device_power_state); -EXPORT_SYMBOL(bm_get_device_info); -EXPORT_SYMBOL(bm_get_device_status); -EXPORT_SYMBOL(bm_get_device_context); -EXPORT_SYMBOL(bm_register_driver); -EXPORT_SYMBOL(bm_unregister_driver); - -/* bmsearch.c */ - -EXPORT_SYMBOL(bm_search); - -/* bmrequest.c */ - -EXPORT_SYMBOL(bm_request); - -/* bmutils.c */ - -EXPORT_SYMBOL(bm_extract_package_data); -EXPORT_SYMBOL(bm_evaluate_object); -EXPORT_SYMBOL(bm_evaluate_simple_integer); -EXPORT_SYMBOL(bm_evaluate_reference_list); -EXPORT_SYMBOL(bm_copy_to_buffer); -EXPORT_SYMBOL(bm_cast_buffer); - -/* bm_proc.c */ - -EXPORT_SYMBOL(bm_osl_generate_event); -EXPORT_SYMBOL(bm_proc_root); diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bmdriver.c linux-2.4.22/drivers/acpi/ospm/busmgr/bmdriver.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bmdriver.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bmdriver.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,469 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmdriver.c - * $Revision: 21 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bm.h" - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bmdriver") - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_get_device_power_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_device_power_state ( - BM_HANDLE device_handle, - BM_POWER_STATE *state) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_get_device_power_state"); - - if (!state) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - *state = ACPI_STATE_UNKNOWN; - - /* - * Resolve device handle to node. - */ - status = bm_get_node(device_handle, 0, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Get the current power state. - */ - status = bm_get_power_state(node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - *state = node->device.power.state; - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_set_device_power_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_set_device_power_state ( - BM_HANDLE device_handle, - BM_POWER_STATE state) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_set_device_power_state"); - - /* - * Resolve device handle to node. - */ - status = bm_get_node(device_handle, 0, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Set the current power state. - */ - status = bm_set_power_state(node, state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_device_status - * - * PARAMETERS: - * device_handle is really an index number into the array of BM_DEVICE - * structures in info_list. This data item is passed to - * the registered program's "notify" callback. It is used - * to retrieve the specific BM_DEVICE structure instance - * associated with the callback. - * device_status is a pointer that receives the result of processing - * the device's associated ACPI _STA. - * - * RETURN: - * The acpi_status value indicates success AE_OK or failure of the function - * - * DESCRIPTION: Evaluates the device's ACPI _STA, if it is present. - * - ****************************************************************************/ - -acpi_status -bm_get_device_status ( - BM_HANDLE device_handle, - BM_DEVICE_STATUS *device_status) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_get_device_status"); - - if (!device_status) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - *device_status = BM_STATUS_UNKNOWN; - - /* - * Resolve device handle to node. - */ - status = bm_get_node(device_handle, 0, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Parent Present? - * --------------- - * If the parent isn't present we can't evalute _STA on the child. - * Return an unknown status. - */ - if (!BM_NODE_PRESENT(node->parent)) { - return_ACPI_STATUS(AE_OK); - } - - /* - * Dynamic Status? - * --------------- - * If _STA isn't present we just return the default status. - */ - if (!(node->device.flags & BM_FLAGS_DYNAMIC_STATUS)) { - *device_status = BM_STATUS_DEFAULT; - return_ACPI_STATUS(AE_OK); - } - - /* - * Evaluate _STA: - * -------------- - */ - status = bm_evaluate_simple_integer(node->device.acpi_handle, "_STA", - &(node->device.status)); - if (ACPI_SUCCESS(status)) { - *device_status = node->device.status; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_device_info - * - * PARAMETERS: - * device_handle An index used to retrieve the associated BM_DEVICE info. - * device A pointer to a BM_DEVICE structure instance pointer. - * This pointed to BM_DEVICE structure will contain the - * this device's information. - * - * RETURN: - * The acpi_status value indicates success AE_OK or failure of the function - * - * DESCRIPTION: - * Using the device_handle this function retrieves this device's - * BM_DEVICE structure instance and save's it in device. - * - ****************************************************************************/ - -acpi_status -bm_get_device_info ( - BM_HANDLE device_handle, - BM_DEVICE **device) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_get_device_info"); - - if (!device) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Resolve device handle to internal device. - */ - status = bm_get_node(device_handle, 0, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - *device = &(node->device); - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_device_context - * - * device_handle An index used to retrieve the associated BM_DEVICE info. - * context A pointer to a BM_DRIVER_CONTEXT structure instance. - * - * RETURN: - * The acpi_status value indicates success AE_OK or failure of the function - * - * DESCRIPTION: - * Using the device_handle this function retrieves this device's - * BM_DRIVER_CONTEXT structure instance and save's it in context. - * - ****************************************************************************/ - -acpi_status -bm_get_device_context ( - BM_HANDLE device_handle, - BM_DRIVER_CONTEXT *context) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_get_device_context"); - - if (!context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - *context = NULL; - - /* - * Resolve device handle to internal device. - */ - status = bm_get_node(device_handle, 0, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (!node->driver.context) { - return_ACPI_STATUS(AE_NULL_ENTRY); - } - - *context = node->driver.context; - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_register_driver - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_register_driver ( - BM_DEVICE_ID *criteria, - BM_DRIVER *driver) -{ - acpi_status status = AE_NOT_FOUND; - BM_HANDLE_LIST device_list; - BM_NODE *node = NULL; - BM_DEVICE *device = NULL; - u32 i = 0; - - FUNCTION_TRACE("bm_register_driver"); - - if (!criteria || !driver || !driver->notify || !driver->request) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(&device_list, 0, sizeof(BM_HANDLE_LIST)); - - /* - * Find Matches: - * ------------- - * Search through the entire device hierarchy for matches against - * the given device criteria. - */ - status = bm_search(BM_HANDLE_ROOT, criteria, &device_list); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Install driver: - * ---------------- - * For each match, record the driver information and execute the - * driver's Notify() funciton (if present) to notify the driver - * of the device's presence. - */ - for (i = 0; i < device_list.count; i++) { - - /* Resolve the device handle. */ - status = bm_get_node(device_list.handles[i], 0, &node); - if (ACPI_FAILURE(status)) { - continue; - } - - device = &(node->device); - - /* - * Make sure another driver hasn't already registered for - * this device. - */ - if (BM_IS_DRIVER_CONTROL(device)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Another driver has already registered for device [%02x].\n", device->handle)); - continue; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registering driver for device [%02x].\n", device->handle)); - - /* Notify driver of new device. */ - status = driver->notify(BM_NOTIFY_DEVICE_ADDED, - node->device.handle, &(node->driver.context)); - if (ACPI_SUCCESS(status)) { - node->driver.notify = driver->notify; - node->driver.request = driver->request; - node->device.flags |= BM_FLAGS_DRIVER_CONTROL; - } - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_unregister_driver - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_unregister_driver ( - BM_DEVICE_ID *criteria, - BM_DRIVER *driver) -{ - acpi_status status = AE_NOT_FOUND; - BM_HANDLE_LIST device_list; - BM_NODE *node = NULL; - BM_DEVICE *device = NULL; - u32 i = 0; - - FUNCTION_TRACE("bm_unregister_driver"); - - if (!criteria || !driver || !driver->notify || !driver->request) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(&device_list, 0, sizeof(BM_HANDLE_LIST)); - - /* - * Find Matches: - * ------------- - * Search through the entire device hierarchy for matches against - * the given device criteria. - */ - status = bm_search(BM_HANDLE_ROOT, criteria, &device_list); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Remove driver: - * --------------- - * For each match, execute the driver's Notify() function to allow - * the driver to cleanup each device instance. - */ - for (i = 0; i < device_list.count; i++) { - - /* Resolve the device handle. */ - status = bm_get_node(device_list.handles[i], 0, &node); - if (ACPI_FAILURE(status)) { - continue; - } - - device = &(node->device); - - /* - * Make sure driver has really registered for this device. - */ - if (!BM_IS_DRIVER_CONTROL(device)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Driver hasn't registered for device [%02x].\n", device->handle)); - continue; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unregistering driver for device [%02x].\n", device->handle)); - - /* Notify driver of device removal. */ - status = node->driver.notify(BM_NOTIFY_DEVICE_REMOVED, - node->device.handle, &(node->driver.context)); - if (ACPI_SUCCESS(status)) { - node->driver.notify = NULL; - node->driver.request = NULL; - node->driver.context = NULL; - node->device.flags &= ~BM_FLAGS_DRIVER_CONTROL; - } - } - - return_ACPI_STATUS(AE_OK); -} diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bmnotify.c linux-2.4.22/drivers/acpi/ospm/busmgr/bmnotify.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bmnotify.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bmnotify.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,312 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmnotify.c - * $Revision: 21 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bm.h" - - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bmnotify") - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_generate_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_generate_notify ( - BM_NODE *node, - u32 notify_type) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - - FUNCTION_TRACE("bm_generate_notify"); - - if (!node) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - device = &(node->device); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Sending notify [%02x] to device [%02x].\n", notify_type, node->device.handle)); - - if (!BM_IS_DRIVER_CONTROL(device)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No driver installed for device [%02x].\n", device->handle)); - return_ACPI_STATUS(AE_NOT_EXIST); - } - - status = node->driver.notify(notify_type, node->device.handle, - &(node->driver.context)); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_device_check - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_device_check ( - BM_NODE *node, - u32 *status_change) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - BM_DEVICE_STATUS old_status = BM_STATUS_UNKNOWN; - - FUNCTION_TRACE("bm_device_check"); - - if (!node) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - device = &(node->device); - - if (status_change) { - *status_change = FALSE; - } - - old_status = device->status; - - /* - * Parent Present? - * --------------- - * Only check this device if its parent is present (which implies - * this device MAY be present). - */ - if (!BM_NODE_PRESENT(node->parent)) { - return_ACPI_STATUS(AE_OK); - } - - /* - * Get Status: - * ----------- - * And see if the status has changed. - */ - status = bm_get_status(device); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (old_status == node->device.status) { - return_ACPI_STATUS(AE_OK); - } - - if (status_change) { - *status_change = TRUE; - } - - /* - * Device Insertion? - * ----------------- - */ - if ((device->status & BM_STATUS_PRESENT) && - !(old_status & BM_STATUS_PRESENT)) { - /* TBD: Make sure driver is loaded, and if not, load. */ - status = bm_generate_notify(node, BM_NOTIFY_DEVICE_ADDED); - } - - /* - * Device Removal? - * --------------- - */ - else if (!(device->status & BM_STATUS_PRESENT) && - (old_status & BM_STATUS_PRESENT)) { - /* TBD: Unload driver if last device instance. */ - status = bm_generate_notify(node, BM_NOTIFY_DEVICE_REMOVED); - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_bus_check - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_bus_check ( - BM_NODE *parent_node) -{ - acpi_status status = AE_OK; - u32 status_change = FALSE; - - FUNCTION_TRACE("bm_bus_check"); - - if (!parent_node) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Status Change? - * -------------- - */ - status = bm_device_check(parent_node, &status_change); - if (ACPI_FAILURE(status) || !status_change) { - return_ACPI_STATUS(status); - } - - /* - * Enumerate Scope: - * ---------------- - * TBD: Enumerate child devices within this device's scope and - * run bm_device_check()'s on them... - */ - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -bm_notify ( - acpi_handle acpi_handle, - u32 notify_value, - void *context) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_notify"); - - /* - * Resolve the ACPI handle. - */ - status = bm_get_node(0, acpi_handle, &node); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Recieved notify [%02x] for unknown device [%p].\n", notify_value, acpi_handle)); - return_VOID; - } - - /* - * Device-Specific or Standard? - * ---------------------------- - * Device-specific notifies are forwarded to the control module's - * notify() function for processing. Standard notifies are handled - * internally. - */ - if (notify_value > 0x7F) { - status = bm_generate_notify(node, notify_value); - } - else { - switch (notify_value) { - - case BM_NOTIFY_BUS_CHECK: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received BUS CHECK notification for device [%02x].\n", node->device.handle)); - status = bm_bus_check(node); - break; - - case BM_NOTIFY_DEVICE_CHECK: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received DEVICE CHECK notification for device [%02x].\n", node->device.handle)); - status = bm_device_check(node, NULL); - break; - - case BM_NOTIFY_DEVICE_WAKE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received DEVICE WAKE notification for device [%02x].\n", node->device.handle)); - /* TBD */ - break; - - case BM_NOTIFY_EJECT_REQUEST: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received EJECT REQUEST notification for device [%02x].\n", node->device.handle)); - /* TBD */ - break; - - case BM_NOTIFY_DEVICE_CHECK_LIGHT: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received DEVICE CHECK LIGHT notification for device [%02x].\n", node->device.handle)); - /* TBD: Exactly what does the 'light' mean? */ - status = bm_device_check(node, NULL); - break; - - case BM_NOTIFY_FREQUENCY_MISMATCH: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received FREQUENCY MISMATCH notification for device [%02x].\n", node->device.handle)); - /* TBD */ - break; - - case BM_NOTIFY_BUS_MODE_MISMATCH: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received BUS MODE MISMATCH notification for device [%02x].\n", node->device.handle)); - /* TBD */ - break; - - case BM_NOTIFY_POWER_FAULT: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received POWER FAULT notification.\n")); - /* TBD */ - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received unknown/unsupported notification.\n")); - break; - } - } - - return_VOID; -} - - diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bmpm.c linux-2.4.22/drivers/acpi/ospm/busmgr/bmpm.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bmpm.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bmpm.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,442 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmpm.c - * $Revision: 14 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bm.h" -#include "bmpower.h" - - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bmpm") - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_get_inferred_power_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_inferred_power_state ( - BM_DEVICE *device) -{ - acpi_status status = AE_OK; - BM_HANDLE_LIST pr_list; - BM_POWER_STATE list_state = ACPI_STATE_UNKNOWN; - char object_name[5] = {'_','P','R','0','\0'}; - u32 i = 0; - - FUNCTION_TRACE("bm_get_inferred_power_state"); - - if (!device) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(&pr_list, 0, sizeof(BM_HANDLE_LIST)); - - device->power.state = ACPI_STATE_D3; - - /* - * Calculate Power State: - * ---------------------- - * Try to infer the devices's power state by checking the state of - * the devices's power resources. We start by evaluating _PR0 - * (resource requirements at D0) and work through _PR1 and _PR2. - * We know the current devices power state when all resources (for - * a give Dx state) are ON. If no power resources are on then the - * device is assumed to be off (D3). - */ - for (i=ACPI_STATE_D0; iacpi_handle, - object_name, &pr_list); - - if (ACPI_SUCCESS(status)) { - - status = bm_pr_list_get_state(&pr_list, &list_state); - - if (ACPI_SUCCESS(status)) { - - if (list_state == ACPI_STATE_D0) { - device->power.state = i; - break; - } - } - } - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_get_power_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_power_state ( - BM_NODE *node) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - - FUNCTION_TRACE("bm_get_power_state"); - - if (!node || !node->parent) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - device = &(node->device); - - device->power.state = ACPI_STATE_UNKNOWN; - - /* - * Power Control? - * -------------- - * If this device isn't directly power manageable (e.g. doesn't - * include _PR0/_PS0) then there's nothing to do (state is static). - */ - if (!BM_IS_POWER_CONTROL(device)) { - return_ACPI_STATUS(AE_OK); - } - - /* - * Parent Present? - * --------------- - * Make sure the parent is present before mucking with the child. - */ - if (!BM_NODE_PRESENT(node->parent)) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - /* - * Get Power State: - * ---------------- - * Either directly (via _PSC) or inferred (via power resource - * dependencies). - */ - if (BM_IS_POWER_STATE(device)) { - status = bm_evaluate_simple_integer(device->acpi_handle, - "_PSC", &(device->power.state)); - } - else { - status = bm_get_inferred_power_state(device); - } - - if (ACPI_SUCCESS(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Device [%02x] is at power state [D%d].\n", device->handle, device->power.state)); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Error getting power state for device [%02x]\n", device->handle)); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_set_power_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_set_power_state ( - BM_NODE *node, - BM_POWER_STATE state) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - BM_DEVICE *parent_device = NULL; - BM_HANDLE_LIST current_list; - BM_HANDLE_LIST target_list; - char object_name[5] = {'_','P','R','0','\0'}; - - FUNCTION_TRACE("bm_set_power_state"); - - if (!node || !node->parent || (state > ACPI_STATE_D3)) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(¤t_list, 0, sizeof(BM_HANDLE_LIST)); - MEMSET(&target_list, 0, sizeof(BM_HANDLE_LIST)); - - device = &(node->device); - parent_device = &(node->parent->device); - - /* - * Power Control? - * -------------- - * If this device isn't directly power manageable (e.g. doesn't - * include _PR0/_PS0) then return an error (can't set state). - */ - if (!BM_IS_POWER_CONTROL(device)) { - return_ACPI_STATUS(AE_ERROR); - } - - /* - * Parent Present? - * --------------- - * Make sure the parent is present before mucking with the child. - */ - if (!BM_NODE_PRESENT(node->parent)) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - /* - * Check Parent's Power State: - * --------------------------- - * Can't be in a higher power state (lower Dx value) than parent. - */ - if (state < parent_device->power.state) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Cannot set device [%02x] to a higher-powered state than parent_device.\n", device->handle)); - return_ACPI_STATUS(AE_ERROR); - } - - /* - * Get Resources: - * -------------- - * Get the power resources associated with the device's current - * and target power states. - */ - if (device->power.state != ACPI_STATE_UNKNOWN) { - object_name[3] = '0' + device->power.state; - bm_evaluate_reference_list(device->acpi_handle, - object_name, ¤t_list); - } - - object_name[3] = '0' + state; - bm_evaluate_reference_list(device->acpi_handle, object_name, - &target_list); - - /* - * Transition Resources: - * --------------------- - * Transition all power resources referenced by this device to - * the correct power state (taking into consideration sequencing - * and dependencies to other devices). - */ - if (current_list.count || target_list.count) { - status = bm_pr_list_transition(¤t_list, &target_list); - } - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Execute _PSx: - * ------------- - * Execute the _PSx method corresponding to the target Dx state, - * if it exists. - */ - object_name[2] = 'S'; - object_name[3] = '0' + state; - bm_evaluate_object(device->acpi_handle, object_name, NULL, NULL); - - if (ACPI_SUCCESS(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Device [%02x] is now at [D%d].\n", device->handle, state)); - device->power.state = state; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_get_pm_capabilities - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_get_pm_capabilities ( - BM_NODE *node) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - BM_DEVICE *parent_device = NULL; - acpi_handle acpi_handle = NULL; - BM_POWER_STATE dx_supported = ACPI_STATE_UNKNOWN; - char object_name[5] = {'_','S','0','D','\0'}; - u32 i = 0; - - FUNCTION_TRACE("bm_get_pm_capabilities"); - - if (!node || !node->parent) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - device = &(node->device); - parent_device = &(node->parent->device); - - /* - * Power Management Flags: - * ----------------------- - */ - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PSC", - &acpi_handle))) { - device->power.flags |= BM_FLAGS_POWER_STATE; - } - - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_IRC", - &acpi_handle))) { - device->power.flags |= BM_FLAGS_INRUSH_CURRENT; - } - - if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PRW", - &acpi_handle))) { - device->power.flags |= BM_FLAGS_WAKE_CAPABLE; - } - - /* - * Device Power State: - * ------------------- - * Note that we can't get the device's power state until we've - * initialized all power resources, so for now we just set to - * unknown. - */ - device->power.state = ACPI_STATE_UNKNOWN; - - /* - * Dx Supported in S0: - * ------------------- - * Figure out which Dx states are supported by this device for the - * S0 (working) state. Note that D0 and D3 are required (assumed). - */ - device->power.dx_supported[ACPI_STATE_S0] = BM_FLAGS_D0_SUPPORT | - BM_FLAGS_D3_SUPPORT; - - if ((ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PR1", - &acpi_handle))) || - (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PS1", - &acpi_handle)))) { - device->power.dx_supported[ACPI_STATE_S0] |= - BM_FLAGS_D1_SUPPORT; - } - - if ((ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PR2", - &acpi_handle))) || - (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PS2", - &acpi_handle)))) { - device->power.dx_supported[ACPI_STATE_S0] |= - BM_FLAGS_D2_SUPPORT; - } - - /* - * Dx Supported in S1-S5: - * ---------------------- - * Figure out which Dx states are supported by this device for - * all other Sx states. - */ - for (i = ACPI_STATE_S1; i <= ACPI_STATE_S5; i++) { - - /* - * D3 support is assumed (off is always possible!). - */ - device->power.dx_supported[i] = BM_FLAGS_D3_SUPPORT; - - /* - * Evalute _Sx_d: - * ------------- - * Which returns the highest (power) Dx state supported in - * this system (Sx) state. We convert this value to a bit - * mask of supported states (conceptually simpler). - */ - status = bm_evaluate_simple_integer(device->acpi_handle, - object_name, &dx_supported); - if (ACPI_SUCCESS(status)) { - switch (dx_supported) { - case 0: - device->power.dx_supported[i] |= - BM_FLAGS_D0_SUPPORT; - /* fall through */ - case 1: - device->power.dx_supported[i] |= - BM_FLAGS_D1_SUPPORT; - /* fall through */ - case 2: - device->power.dx_supported[i] |= - BM_FLAGS_D2_SUPPORT; - /* fall through */ - case 3: - device->power.dx_supported[i] |= - BM_FLAGS_D3_SUPPORT; - break; - } - - /* - * Validate: - * --------- - * Mask of any states that _Sx_d falsely advertises - * (e.g.claims D1 support but neither _PR2 or _PS2 - * exist). In other words, S1-S5 can't offer a Dx - * state that isn't supported by S0. - */ - device->power.dx_supported[i] &= - device->power.dx_supported[ACPI_STATE_S0]; - } - - object_name[2]++; - } - - return_ACPI_STATUS(AE_OK); -} diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bmpower.c linux-2.4.22/drivers/acpi/ospm/busmgr/bmpower.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bmpower.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bmpower.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,664 +0,0 @@ -/**************************************************************************** - * - * Module Name: bmpower.c - Driver for ACPI Power Resource 'devices' - * $Revision: 20 $ - * - ****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - */ - -/* - * TBD: 1. Sequencing of power resource list transitions. - * 2. Global serialization of power resource transtions (see ACPI - * spec section 7.1.2/7.1.3). - * 3. Better error handling. - */ - - -#include -#include "bm.h" -#include "bmpower.h" - - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bmpower") - - -/**************************************************************************** - * Function Prototypes - ****************************************************************************/ - -acpi_status -bm_pr_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context); - -acpi_status -bm_pr_request ( - BM_REQUEST *request, - void *context); - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_pr_print - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_print ( - BM_POWER_RESOURCE *pr) -{ - acpi_buffer buffer; - - PROC_NAME("bm_pr_print"); - - if (!pr) { - return(AE_BAD_PARAMETER); - } - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return(AE_NO_MEMORY); - } - - acpi_get_name(pr->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - acpi_os_printf("Power Resource: found\n"); - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Power_resource[%02x]:[%p] %s\n", pr->device_handle, pr->acpi_handle, (char*)buffer.pointer)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| system_level[S%d] resource_order[%d]\n", pr->system_level, pr->resource_order)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| state[D%d] reference_count[%d]\n", pr->state, pr->reference_count)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_get_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_get_state ( - BM_POWER_RESOURCE *pr) -{ - acpi_status status = AE_OK; - BM_DEVICE_STATUS device_status = BM_STATUS_UNKNOWN; - - FUNCTION_TRACE("bm_pr_get_state"); - - if (!pr) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - pr->state = ACPI_STATE_UNKNOWN; - - /* - * Evaluate _STA: - * -------------- - * Evalute _STA to determine whether the power resource is ON or OFF. - * Note that if the power resource isn't present we'll get AE_OK but - * an unknown status. - */ - status = bm_get_device_status(pr->device_handle, &device_status); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Error reading status for power resource [%02x].\n", pr->device_handle)); - return_ACPI_STATUS(status); - } - - /* - * Mask off all bits but the first as some systems return non-standard - * values (e.g. 0x51). - */ - switch (device_status & 0x01) { - case 0: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Power resource [%02x] is OFF.\n", pr->device_handle)); - pr->state = ACPI_STATE_D3; - break; - case 1: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Power resource [%02x] is ON.\n", pr->device_handle)); - pr->state = ACPI_STATE_D0; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_set_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_set_state ( - BM_POWER_RESOURCE *pr, - BM_POWER_STATE target_state) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bm_pr_set_state"); - - if (!pr) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = bm_pr_get_state(pr); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (target_state == pr->state) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Power resource [%02x] already at target power state [D%d].\n", pr->device_handle, pr->state)); - return_ACPI_STATUS(AE_OK); - } - - switch (target_state) { - - case ACPI_STATE_D0: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Turning power resource [%02x] ON.\n", pr->device_handle)); - status = bm_evaluate_object(pr->acpi_handle, "_ON", NULL, NULL); - break; - - case ACPI_STATE_D3: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Turning power resource [%02x] OFF.\n", pr->device_handle)); - status = bm_evaluate_object(pr->acpi_handle, "_OFF", NULL, NULL); - break; - - default: - status = AE_BAD_PARAMETER; - break; - } - - status = bm_pr_get_state(pr); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_list_get_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_list_get_state ( - BM_HANDLE_LIST *pr_list, - BM_POWER_STATE *power_state) -{ - acpi_status status = AE_OK; - BM_POWER_RESOURCE *pr = NULL; - u32 i = 0; - - FUNCTION_TRACE("bm_pr_list_get_state"); - - if (!pr_list || !power_state) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (pr_list->count < 1) { - pr->state = ACPI_STATE_UNKNOWN; - return_ACPI_STATUS(AE_ERROR); - } - - (*power_state) = ACPI_STATE_D0; - - /* - * Calculate Current power_state: - * ----------------------------- - * The current state of a list of power resources is ON if all - * power resources are currently in the ON state. In other words, - * if any power resource in the list is OFF then the collection - * isn't fully ON. - */ - for (i = 0; i < pr_list->count; i++) { - - status = bm_get_device_context(pr_list->handles[i], - (BM_DRIVER_CONTEXT*)(&pr)); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Invalid reference to power resource [%02x].\n", pr_list->handles[i])); - (*power_state) = ACPI_STATE_UNKNOWN; - break; - } - - status = bm_pr_get_state(pr); - if (ACPI_FAILURE(status)) { - (*power_state) = ACPI_STATE_UNKNOWN; - break; - } - - if (pr->state != ACPI_STATE_D0) { - (*power_state) = pr->state; - break; - } - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_list_transition - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_list_transition ( - BM_HANDLE_LIST *current_list, - BM_HANDLE_LIST *target_list) -{ - acpi_status status = AE_OK; - BM_POWER_RESOURCE *pr = NULL; - u32 i = 0; - - FUNCTION_TRACE("bm_pr_list_transition"); - - if (!current_list || !target_list) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Reference Target: - * ----------------- - * Reference all resources for the target power state first (so - * the device doesn't get turned off while transitioning). Power - * resources that aren't on (new reference count of 1) are turned on. - */ - for (i = 0; i < target_list->count; i++) { - - status = bm_get_device_context(target_list->handles[i], - (BM_DRIVER_CONTEXT*)(&pr)); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Invalid reference to power resource [%02x].\n", target_list->handles[i])); - continue; - } - - if (++pr->reference_count == 1) { - /* TBD: Need ordering based upon resource_order */ - status = bm_pr_set_state(pr, ACPI_STATE_D0); - if (ACPI_FAILURE(status)) { - /* TBD: How do we handle this? */ - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to change power state for power resource [%02x].\n", target_list->handles[i])); - } - } - } - - /* - * Dereference Current: - * -------------------- - * Dereference all resources for the current power state. Power - * resources no longer referenced (new reference count of 0) are - * turned off. - */ - for (i = 0; i < current_list->count; i++) { - - status = bm_get_device_context(current_list->handles[i], - (BM_DRIVER_CONTEXT*)(&pr)); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Invalid reference to power resource [%02x].\n", target_list->handles[i])); - continue; - } - - if (--pr->reference_count == 0) { - /* TBD: Need ordering based upon resource_order */ - status = bm_pr_set_state(pr, ACPI_STATE_D3); - if (ACPI_FAILURE(status)) { - /* TBD: How do we handle this? */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to change power state for power resource [%02x].\n", current_list->handles[i])); - } - } - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_add_device ( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - BM_POWER_RESOURCE *pr = NULL; - BM_DEVICE *device = NULL; - acpi_buffer buffer; - acpi_object acpi_object; - - FUNCTION_TRACE("bm_pr_add_device"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding power resource [%02x].\n", device_handle)); - - if (!context || *context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - buffer.length = sizeof(acpi_object); - buffer.pointer = &acpi_object; - - /* - * Get information on this device. - */ - status = bm_get_device_info(device_handle, &device); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Allocate a new BM_POWER_RESOURCE structure. - */ - pr = acpi_os_callocate(sizeof(BM_POWER_RESOURCE)); - if (!pr) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - pr->device_handle = device->handle; - pr->acpi_handle = device->acpi_handle; - - /* - * Get information on this power resource. - */ - status = acpi_evaluate_object(pr->acpi_handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - goto end; - } - - pr->system_level = acpi_object.power_resource.system_level; - pr->resource_order = acpi_object.power_resource.resource_order; - pr->state = ACPI_STATE_UNKNOWN; - pr->reference_count = 0; - - /* - * Get the power resource's current state (ON|OFF). - */ - status = bm_pr_get_state(pr); - -end: - if (ACPI_FAILURE(status)) { - acpi_os_free(pr); - } - else { - *context = pr; - bm_pr_print(pr); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_remove_device ( - void **context) -{ - acpi_status status = AE_OK; - BM_POWER_RESOURCE *pr = NULL; - - FUNCTION_TRACE("bm_pr_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - pr = (BM_POWER_RESOURCE*)*context; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing power resource [%02x].\n", pr->device_handle)); - - acpi_os_free(pr); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_pr_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_initialize (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("bm_pr_initialize"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - criteria.type = BM_TYPE_POWER_RESOURCE; - - driver.notify = &bm_pr_notify; - driver.request = &bm_pr_request; - - status = bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_terminate - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_terminate (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("bm_pr_terminate"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - criteria.type = BM_TYPE_POWER_RESOURCE; - - driver.notify = &bm_pr_notify; - driver.request = &bm_pr_request; - - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bm_pr_notify"); - - switch (notify_type) { - - case BM_NOTIFY_DEVICE_ADDED: - status = bm_pr_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = bm_pr_remove_device(context); - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_pr_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_pr_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - BM_POWER_RESOURCE *pr = NULL; - - FUNCTION_TRACE("bm_pr_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * context contains information specific to this power resource. - */ - pr = (BM_POWER_RESOURCE*)context; - - /* - * Handle request: - * --------------- - */ - switch (request->command) { - - default: - status = AE_SUPPORT; - break; - } - - request->status = status; - - return_ACPI_STATUS(status); -} - - diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bmrequest.c linux-2.4.22/drivers/acpi/ospm/busmgr/bmrequest.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bmrequest.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bmrequest.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,164 +0,0 @@ -/****************************************************************************** - * - * Module Name: bmrequest.c - * $Revision: 16 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bm.h" - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bmrequest") - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_generate_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_generate_request ( - BM_NODE *node, - BM_REQUEST *request) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - - FUNCTION_TRACE("bm_generate_request"); - - if (!node || !request) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - device = &(node->device); - - if (!BM_IS_DRIVER_CONTROL(device)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No driver installed for device [%02x].\n", device->handle)); - return_ACPI_STATUS(AE_NOT_EXIST); - } - - status = node->driver.request(request, node->driver.context); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_request ( - BM_REQUEST *request) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - BM_DEVICE *device = NULL; - - FUNCTION_TRACE("bm_request"); - - /* - * Must have a valid request structure. - */ - if (!request) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received request for device [%02x] command [%02x].\n", request->handle, request->command)); - - /* - * Resolve the node. - */ - status = bm_get_node(request->handle, 0, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - device = &(node->device); - - /* - * Device-Specific Request? - * ------------------------ - * If a device-specific command (>=0x80) forward this request to - * the appropriate driver. - */ - if (request->command & BM_COMMAND_DEVICE_SPECIFIC) { - status = bm_generate_request(node, request); - return_ACPI_STATUS(status); - } - - /* - * Bus-Specific Requests: - * ---------------------- - */ - switch (request->command) { - - case BM_COMMAND_GET_POWER_STATE: - status = bm_get_power_state(node); - if (ACPI_FAILURE(status)) { - break; - } - status = bm_copy_to_buffer(&(request->buffer), - &(device->power.state), sizeof(BM_POWER_STATE)); - break; - - case BM_COMMAND_SET_POWER_STATE: - { - BM_POWER_STATE *power_state = NULL; - - status = bm_cast_buffer(&(request->buffer), - (void**)&power_state, sizeof(BM_POWER_STATE)); - if (ACPI_FAILURE(status)) { - break; - } - status = bm_set_power_state(node, *power_state); - } - break; - - default: - status = AE_SUPPORT; - request->status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bmsearch.c linux-2.4.22/drivers/acpi/ospm/busmgr/bmsearch.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bmsearch.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bmsearch.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,192 +0,0 @@ -/****************************************************************************** - * - * Module Name: bmsearch.c - * $Revision: 16 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bm.h" - - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bmsearch") - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_compare - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_compare ( - BM_DEVICE *device, - BM_DEVICE_ID *criteria) -{ - if (!device || !criteria) { - return AE_BAD_PARAMETER; - } - - /* - * Present? - * -------- - * We're only going to match on devices that are present. - * TBD: Optimize in bm_search (don't have to call here). - */ - if (!BM_DEVICE_PRESENT(device)) { - return AE_NOT_FOUND; - } - - /* - * Type? - */ - if (criteria->type && (criteria->type != device->id.type)) { - return AE_NOT_FOUND; - } - - /* - * HID? - */ - if ((criteria->hid[0]) && (0 != STRNCMP(criteria->hid, - device->id.hid, sizeof(BM_DEVICE_HID)))) { - return AE_NOT_FOUND; - } - - /* - * ADR? - */ - if ((criteria->adr) && (criteria->adr != device->id.adr)) { - return AE_NOT_FOUND; - } - - return AE_OK; -} - - -/**************************************************************************** - * - * FUNCTION: bm_search - * - * PARAMETERS: - * - * RETURN: AE_BAD_PARAMETER- invalid input parameter - * AE_NOT_EXIST - start_device_handle doesn't exist - * AE_NOT_FOUND - no matches to Search_info.criteria found - * AE_OK - success - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_search( - BM_HANDLE device_handle, - BM_DEVICE_ID *criteria, - BM_HANDLE_LIST *results) -{ - acpi_status status = AE_OK; - BM_NODE *node = NULL; - - FUNCTION_TRACE("bm_search"); - - if (!criteria || !results) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - results->count = 0; - - /* - * Locate Starting Point: - * ---------------------- - * Locate the node in the hierarchy where we'll begin our search. - */ - status = bm_get_node(device_handle, 0, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Parse Hierarchy: - * ---------------- - * Parse through the node hierarchy looking for matches. - */ - while (node && (results->count<=BM_HANDLES_MAX)) { - /* - * Depth-first: - * ------------ - * Searches are always performed depth-first. - */ - if (node->scope.head) { - status = bm_compare(&(node->device), criteria); - if (ACPI_SUCCESS(status)) { - results->handles[results->count++] = - node->device.handle; - } - node = node->scope.head; - } - - /* - * Now Breadth: - * ------------ - * Search all peers until scope is exhausted. - */ - else { - status = bm_compare(&(node->device), criteria); - if (ACPI_SUCCESS(status)) { - results->handles[results->count++] = - node->device.handle; - } - - /* - * Locate Next Device: - * ------------------- - * The next node is either a peer at this level - * (node->next is valid), or we work are way back - * up the tree until we either find a non-parsed - * peer or hit the top (node->parent is NULL). - */ - while (!node->next && node->parent) { - node = node->parent; - } - node = node->next; - } - } - - if (results->count == 0) { - return_ACPI_STATUS(AE_NOT_FOUND); - } - else { - return_ACPI_STATUS(AE_OK); - } -} - diff -urN linux-2.4.21/drivers/acpi/ospm/busmgr/bmutils.c linux-2.4.22/drivers/acpi/ospm/busmgr/bmutils.c --- linux-2.4.21/drivers/acpi/ospm/busmgr/bmutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/busmgr/bmutils.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,611 +0,0 @@ -/***************************************************************************** - * - * Module Name: bmutils.c - * $Revision: 43 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bm.h" - - -#define _COMPONENT ACPI_BUS - MODULE_NAME ("bmutils") - - -#ifdef ACPI_DEBUG -#define DEBUG_EVAL_ERROR(l,h,p,s) bm_print_eval_error(l,h,p,s) -#else -#define DEBUG_EVAL_ERROR(l,h,p,s) -#endif - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: bm_print_eval_error - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -bm_print_eval_error ( - u32 debug_level, - acpi_handle handle, - acpi_string pathname, - acpi_status status) -{ - acpi_buffer buffer; - acpi_status local_status; - - PROC_NAME("bm_print_eval_error"); - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - local_status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); - if (ACPI_FAILURE(local_status)) { - ACPI_DEBUG_PRINT((ACPI_DEBUG_LEVEL(debug_level), "Evaluate object [%p], %s\n", handle, - acpi_format_exception(status))); - return; - } - - if (pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate object [%s.%s], %s\n", (char*)buffer.pointer, pathname, - acpi_format_exception(status))); - } - else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate object [%s], %s\n", (char*)buffer.pointer, - acpi_format_exception(status))); - } - - acpi_os_free(buffer.pointer); -} - - -/**************************************************************************** - * - * FUNCTION: bm_copy_to_buffer - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_copy_to_buffer ( - acpi_buffer *buffer, - void *data, - u32 length) -{ - FUNCTION_TRACE("bm_copy_to_buffer"); - - if (!buffer || (!buffer->pointer) || !data || (length == 0)) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (length > buffer->length) { - buffer->length = length; - return_ACPI_STATUS(AE_BUFFER_OVERFLOW); - } - - buffer->length = length; - MEMCPY(buffer->pointer, data, length); - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_cast_buffer - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_cast_buffer ( - acpi_buffer *buffer, - void **pointer, - u32 length) -{ - FUNCTION_TRACE("bm_cast_buffer"); - - if (!buffer || !buffer->pointer || !pointer || length == 0) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (length > buffer->length) { - return_ACPI_STATUS(AE_BAD_DATA); - } - - *pointer = buffer->pointer; - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_extract_package_data - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_extract_package_data ( - acpi_object *package, - acpi_buffer *format, - acpi_buffer *buffer) -{ - u32 tail_offset = 0; - u32 size_required = 0; - char *format_string = NULL; - u32 format_count = 0; - u32 i = 0; - u8 *head = NULL; - u8 *tail = NULL; - - FUNCTION_TRACE("bm_extract_package_data"); - - if (!package || (package->type != ACPI_TYPE_PACKAGE) || (package->package.count < 1)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'package' argument\n")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (!format || !format->pointer || (format->length < 1)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'format' argument\n")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (!buffer) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'buffer' argument\n")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - format_count = (format->length/sizeof(char)) - 1; - if (format_count > package->package.count) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count)); - return_ACPI_STATUS(AE_BAD_DATA); - } - - format_string = (char*)format->pointer; - - /* - * Calculate size_required. - */ - for (i=0; ipackage.elements[i]); - - if (!element) { - return_ACPI_STATUS(AE_BAD_DATA); - } - - switch (element->type) { - - case ACPI_TYPE_INTEGER: - switch (format_string[i]) { - case 'N': - size_required += sizeof(acpi_integer); - tail_offset += sizeof(acpi_integer); - break; - case 'S': - size_required += sizeof(char*) + sizeof(acpi_integer) + sizeof(char); - tail_offset += sizeof(char*); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d]: got number, expecing [%c].\n", i, format_string[i])); - return_ACPI_STATUS(AE_BAD_DATA); - break; - } - break; - - case ACPI_TYPE_STRING: - case ACPI_TYPE_BUFFER: - switch (format_string[i]) { - case 'S': - size_required += sizeof(char*) + (element->string.length * sizeof(char)) + sizeof(char); - tail_offset += sizeof(char*); - break; - case 'B': - size_required += sizeof(u8*) + (element->buffer.length * sizeof(u8)); - tail_offset += sizeof(u8*); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d] got string/buffer, expecing [%c].\n", i, format_string[i])); - return_ACPI_STATUS(AE_BAD_DATA); - break; - } - break; - - case ACPI_TYPE_PACKAGE: - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%d\n", i)); - /* TBD: handle nested packages... */ - return_ACPI_STATUS(AE_SUPPORT); - break; - } - } - - /* - * Validate output buffer. - */ - if (buffer->length < size_required) { - buffer->length = size_required; - return_ACPI_STATUS(AE_BUFFER_OVERFLOW); - } - else if (buffer->length != size_required || !buffer->pointer) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - head = buffer->pointer; - tail = buffer->pointer + tail_offset; - - /* - * Extract package data. - */ - for (i=0; ipackage.elements[i]); - - switch (element->type) { - - case ACPI_TYPE_INTEGER: - switch (format_string[i]) { - case 'N': - *((acpi_integer*)head) = element->integer.value; - head += sizeof(acpi_integer); - break; - case 'S': - pointer = (u8**)head; - *pointer = tail; - *((acpi_integer*)tail) = element->integer.value; - head += sizeof(acpi_integer*); - tail += sizeof(acpi_integer); - /* NULL terminate string */ - *tail = (char)0; - tail += sizeof(char); - break; - default: - /* Should never get here */ - break; - } - break; - - case ACPI_TYPE_STRING: - case ACPI_TYPE_BUFFER: - switch (format_string[i]) { - case 'S': - pointer = (u8**)head; - *pointer = tail; - memcpy(tail, element->string.pointer, element->string.length); - head += sizeof(char*); - tail += element->string.length * sizeof(char); - /* NULL terminate string */ - *tail = (char)0; - tail += sizeof(char); - break; - case 'B': - pointer = (u8**)head; - *pointer = tail; - memcpy(tail, element->buffer.pointer, element->buffer.length); - head += sizeof(u8*); - tail += element->buffer.length * sizeof(u8); - break; - default: - /* Should never get here */ - break; - } - break; - - case ACPI_TYPE_PACKAGE: - /* TBD: handle nested packages... */ - default: - /* Should never get here */ - break; - } - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bm_evaluate_object - * - * PARAMETERS: - * - * RETURN: AE_OK - * AE_BUFFER_OVERFLOW Evaluated object returned data, but - * caller did not provide buffer. - * - * DESCRIPTION: Helper for acpi_evaluate_object that handles buffer - * allocation. Note that the caller is responsible for - * freeing buffer->pointer! - * - ****************************************************************************/ - -acpi_status -bm_evaluate_object ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *arguments, - acpi_buffer *buffer) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bm_evaluate_object"); - - /* If caller provided a buffer it must be unallocated/zero'd. */ - if ((buffer) && (buffer->length != 0 || buffer->pointer)) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Evalute Object: - * --------------- - * The first attempt is just to get the size of the object data - * (that is unless there's no return data, e.g. _INI); the second - * gets the data. - */ - status = acpi_evaluate_object(handle, pathname, arguments, buffer); - if (ACPI_SUCCESS(status)) { - return_ACPI_STATUS(status); - } - else if ((buffer) && (status == AE_BUFFER_OVERFLOW)) { - - /* Gotta allocate -- CALLER MUST FREE! */ - buffer->pointer = acpi_os_callocate(buffer->length); - if (!buffer->pointer) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Re-evaluate -- this time it should work */ - status = acpi_evaluate_object(handle, pathname, - arguments, buffer); - } - - if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) { - DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, - status); - } - if (buffer && buffer->pointer) { - acpi_os_free(buffer->pointer); - buffer->pointer = NULL; - buffer->length = 0; - } - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_evaluate_simple_integer - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_evaluate_simple_integer ( - acpi_handle handle, - acpi_string pathname, - u32 *data) -{ - acpi_status status = AE_OK; - acpi_object *element = NULL; - acpi_buffer buffer; - - FUNCTION_TRACE("bm_evaluate_simple_integer"); - - if (!data) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(&buffer, 0, sizeof(acpi_buffer)); - - /* - * Evaluate Object: - * ---------------- - */ - status = bm_evaluate_object(handle, pathname, NULL, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "failed to evaluate object (%s)\n", - acpi_format_exception(status))); - goto end; - } - - /* - * Validate Data: - * -------------- - */ - status = bm_cast_buffer(&buffer, (void**)&element, - sizeof(acpi_object)); - if (ACPI_FAILURE(status)) { - DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status); - goto end; - } - - if (element->type != ACPI_TYPE_INTEGER) { - status = AE_BAD_DATA; - DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status); - goto end; - } - - *data = element->integer.value; - -end: - acpi_os_free(buffer.pointer); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bm_evaluate_reference_list - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bm_evaluate_reference_list ( - acpi_handle handle, - acpi_string pathname, - BM_HANDLE_LIST *reference_list) -{ - acpi_status status = AE_OK; - acpi_object *package = NULL; - acpi_object *element = NULL; - acpi_handle reference_handle = NULL; - acpi_buffer buffer; - u32 i = 0; - - FUNCTION_TRACE("bm_evaluate_reference_list"); - - if (!reference_list) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(&buffer, 0, sizeof(acpi_buffer)); - - /* - * Evaluate Object: - * ---------------- - */ - status = bm_evaluate_object(handle, pathname, NULL, &buffer); - if (ACPI_FAILURE(status)) { - goto end; - } - - /* - * Validate Package: - * ----------------- - */ - status = bm_cast_buffer(&buffer, (void**)&package, - sizeof(acpi_object)); - if (ACPI_FAILURE(status)) { - DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status); - goto end; - } - - if (package->type != ACPI_TYPE_PACKAGE) { - status = AE_BAD_DATA; - DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status); - goto end; - } - - if (package->package.count > BM_HANDLES_MAX) { - package->package.count = BM_HANDLES_MAX; - } - - /* - * Parse Package Data: - * ------------------- - */ - for (i = 0; i < package->package.count; i++) { - - element = &(package->package.elements[i]); - - if (!element || (element->type != ACPI_TYPE_STRING)) { - status = AE_BAD_DATA; - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid element in package (not a device reference).\n")); - DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status); - break; - } - - /* - * Resolve reference string (e.g. "\_PR_.CPU_") to an - * acpi_handle. - */ - status = acpi_get_handle(handle, - element->string.pointer, &reference_handle); - if (ACPI_FAILURE(status)) { - status = AE_BAD_DATA; - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference [%s].\n", element->string.pointer)); - DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status); - break; - } - - /* - * Resolve acpi_handle to BM_HANDLE. - */ - status = bm_get_handle(reference_handle, - &(reference_list->handles[i])); - if (ACPI_FAILURE(status)) { - status = AE_BAD_DATA; - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference for [%p].\n", reference_handle)); - DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status); - break; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resolved reference [%s]->[%p]->[%02x]\n", element->string.pointer, reference_handle, reference_list->handles[i])); - - (reference_list->count)++; - } - -end: - acpi_os_free(buffer.pointer); - - return_ACPI_STATUS(status); -} - - diff -urN linux-2.4.21/drivers/acpi/ospm/button/Makefile linux-2.4.22/drivers/acpi/ospm/button/Makefile --- linux-2.4.21/drivers/acpi/ospm/button/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/button/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/button/bn.c linux-2.4.22/drivers/acpi/ospm/button/bn.c --- linux-2.4.21/drivers/acpi/ospm/button/bn.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/button/bn.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,507 +0,0 @@ -/***************************************************************************** - * - * Module Name: bn.c - * $Revision: 27 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 Plxxe, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include "bn.h" - - -#define _COMPONENT ACPI_BUTTON - MODULE_NAME ("bn") - - -/***************************************************************************** - * Internal Functions - *****************************************************************************/ - -/***************************************************************************** - * - * FUNCTION: bn_print - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Prints out information on a specific button. - * - ****************************************************************************/ - -void -bn_print ( - BN_CONTEXT *button) -{ -#ifdef ACPI_DEBUG - acpi_buffer buffer; - - PROC_NAME("bn_print"); - - if (!button) { - return; - } - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - /* - * Get the full pathname for this ACPI object. - */ - acpi_get_name(button->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - /* - * Print out basic button information. - */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - switch (button->type) { - - case BN_TYPE_POWER_BUTTON: - case BN_TYPE_POWER_BUTTON_FIXED: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Power_button[%02x]:[%p] %s\n", button->device_handle, button->acpi_handle, (char*)buffer.pointer)); - break; - - case BN_TYPE_SLEEP_BUTTON: - case BN_TYPE_SLEEP_BUTTON_FIXED: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Sleep_button[%02x]:[%p] %s\n", button->device_handle, button->acpi_handle, (char*)buffer.pointer)); - break; - - case BN_TYPE_LID_SWITCH: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Lid_switch[%02x]:[%p] %s\n", button->device_handle, button->acpi_handle, (char*)buffer.pointer)); - break; - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); -#endif /*ACPI_DEBUG*/ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: bn_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bn_add_device( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - BN_CONTEXT *button = NULL; - - FUNCTION_TRACE("bn_add_device"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding button device [%02x].\n", device_handle)); - - if (!context || *context) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid context.\n")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Get information on this device. - */ - status = bm_get_device_info( device_handle, &device ); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Allocate a new BN_CONTEXT structure. - */ - button = acpi_os_callocate(sizeof(BN_CONTEXT)); - if (!button) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - button->device_handle = device->handle; - button->acpi_handle = device->acpi_handle; - - /* - * Power Button? - * ------------- - * Either fixed-feature or generic (namespace) types. - */ - if (strncmp(device->id.hid, BN_HID_POWER_BUTTON, - sizeof(BM_DEVICE_HID)) == 0) { - - if (device->id.type == BM_TYPE_FIXED_BUTTON) { - - button->type = BN_TYPE_POWER_BUTTON_FIXED; - - /* Register for fixed-feature events. */ - status = acpi_install_fixed_event_handler( - ACPI_EVENT_POWER_BUTTON, bn_notify_fixed, - (void*)button); - } - else { - button->type = BN_TYPE_POWER_BUTTON; - } - - } - - /* - * Sleep Button? - * ------------- - * Either fixed-feature or generic (namespace) types. - */ - else if (strncmp( device->id.hid, BN_HID_SLEEP_BUTTON, - sizeof(BM_DEVICE_HID)) == 0) { - - if (device->id.type == BM_TYPE_FIXED_BUTTON) { - - button->type = BN_TYPE_SLEEP_BUTTON_FIXED; - - /* Register for fixed-feature events. */ - status = acpi_install_fixed_event_handler( - ACPI_EVENT_SLEEP_BUTTON, bn_notify_fixed, - (void*)button); - } - else { - button->type = BN_TYPE_SLEEP_BUTTON; - } - } - - /* - * LID Switch? - * ----------- - */ - else if (strncmp( device->id.hid, BN_HID_LID_SWITCH, - sizeof(BM_DEVICE_HID)) == 0) { - button->type = BN_TYPE_LID_SWITCH; - } - - status = bn_osl_add_device(button); - if (ACPI_FAILURE(status)) { - goto end; - } - - *context = button; - - bn_print(button); - -end: - if (ACPI_FAILURE(status)) { - acpi_os_free(button); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bn_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bn_remove_device( - void **context) -{ - acpi_status status = AE_OK; - BN_CONTEXT *button = NULL; - - FUNCTION_TRACE("bn_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - button = (BN_CONTEXT*)*context; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing button device [%02x].\n", button->device_handle)); - - /* - * Unregister for fixed-feature events. - */ - switch (button->type) { - case BN_TYPE_POWER_BUTTON_FIXED: - status = acpi_remove_fixed_event_handler( - ACPI_EVENT_POWER_BUTTON, bn_notify_fixed); - break; - case BN_TYPE_SLEEP_BUTTON_FIXED: - status = acpi_remove_fixed_event_handler( - ACPI_EVENT_SLEEP_BUTTON, bn_notify_fixed); - break; - } - - bn_osl_remove_device(button); - - acpi_os_free(button); - - *context = NULL; - - return_ACPI_STATUS(status); -} - - -/***************************************************************************** - * External Functions - *****************************************************************************/ - -/***************************************************************************** - * - * FUNCTION: bn_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - - ****************************************************************************/ - -acpi_status -bn_initialize (void) -{ - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("bn_initialize"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - driver.notify = &bn_notify; - driver.request = &bn_request; - - /* - * Register for power buttons. - */ - MEMCPY(criteria.hid, BN_HID_POWER_BUTTON, sizeof(BN_HID_POWER_BUTTON)); - bm_register_driver(&criteria, &driver); - - /* - * Register for sleep buttons. - */ - MEMCPY(criteria.hid, BN_HID_SLEEP_BUTTON, sizeof(BN_HID_SLEEP_BUTTON)); - bm_register_driver(&criteria, &driver); - - /* - * Register for LID switches. - */ - MEMCPY(criteria.hid, BN_HID_LID_SWITCH, sizeof(BN_HID_LID_SWITCH)); - bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bn_terminate - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bn_terminate (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("bn_terminate"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - driver.notify = &bn_notify; - driver.request = &bn_request; - - /* - * Unregister for power buttons. - */ - MEMCPY(criteria.hid, BN_HID_POWER_BUTTON, sizeof(BN_HID_POWER_BUTTON)); - status = bm_unregister_driver(&criteria, &driver); - - /* - * Unregister for sleep buttons. - */ - MEMCPY(criteria.hid, BN_HID_SLEEP_BUTTON, sizeof(BN_HID_SLEEP_BUTTON)); - status = bm_unregister_driver(&criteria, &driver); - - /* - * Unregister for LID switches. - */ - MEMCPY(criteria.hid, BN_HID_LID_SWITCH, sizeof(BN_HID_LID_SWITCH)); - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bn_notify_fixed - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bn_notify_fixed ( - void *context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bn_notify_fixed"); - - if (!context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status change event detected.\n")); - - status = bn_osl_generate_event(BN_NOTIFY_STATUS_CHANGE, - ((BN_CONTEXT*)context)); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bn_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bn_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bn_notify"); - - if (!context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - switch (notify_type) { - case BM_NOTIFY_DEVICE_ADDED: - status = bn_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = bn_remove_device(context); - break; - - case BN_NOTIFY_STATUS_CHANGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status change event detected.\n")); - status = bn_osl_generate_event(BN_NOTIFY_STATUS_CHANGE, - ((BN_CONTEXT*)*context)); - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: bn_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -bn_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("bn_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Handle Request: - * --------------- - */ - switch (request->command) { - - default: - status = AE_SUPPORT; - break; - } - - request->status = status; - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/button/bn_osl.c linux-2.4.22/drivers/acpi/ospm/button/bn_osl.c --- linux-2.4.21/drivers/acpi/ospm/button/bn_osl.c 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/button/bn_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,311 +0,0 @@ -/****************************************************************************** - * - * Module Name: bn_osl.c - * $Revision: 16 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "bn.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Button Driver"); -MODULE_LICENSE("GPL"); - - -#define BN_PROC_ROOT "button" -#define BN_PROC_POWER_BUTTON "power" -#define BN_PROC_SLEEP_BUTTON "sleep" -#define BN_PROC_LID_SWITCH "lid" - -extern struct proc_dir_entry *bm_proc_root; -static struct proc_dir_entry *bn_proc_root = NULL; - - -#define BN_TYPE_UNKNOWN 0 -#define BN_TYPE_FIXED 1 -#define BN_TYPE_GENERIC 2 - -static int bn_power_button = BN_TYPE_UNKNOWN; -static int bn_sleep_button = BN_TYPE_UNKNOWN; -static int bn_lid_switch = BN_TYPE_UNKNOWN; - - -/**************************************************************************** - * - * FUNCTION: bn_osl_add_device - * - ****************************************************************************/ - -acpi_status -bn_osl_add_device( - BN_CONTEXT *button) -{ - acpi_status status = AE_OK; - - if (!button) { - return(AE_BAD_PARAMETER); - } - - switch (button->type) { - - case BN_TYPE_POWER_BUTTON_FIXED: - bn_power_button = BN_TYPE_FIXED; - printk(KERN_INFO "ACPI: Power Button (FF) found\n"); - if (!proc_mkdir(BN_PROC_POWER_BUTTON, bn_proc_root)) { - status = AE_ERROR; - } - break; - - case BN_TYPE_POWER_BUTTON: - /* - * Avoid creating multiple /proc entries when (buggy) ACPI - * BIOS tables erroneously list both fixed- and generic- - * feature buttons. Note that fixed-feature buttons are - * always enumerated first (and there can only be one) so - * we only need to check here. - */ - switch (bn_power_button) { - case BN_TYPE_GENERIC: - printk(KERN_WARNING "ACPI: Multiple generic-space power buttons detected, using first\n"); - break; - case BN_TYPE_FIXED: - printk(KERN_WARNING "ACPI: Multiple power buttons detected, ignoring fixed-feature\n"); - default: - printk(KERN_INFO "ACPI: Power Button (CM) found\n"); - bn_power_button = BN_TYPE_GENERIC; - if (!proc_mkdir(BN_PROC_POWER_BUTTON, bn_proc_root)) { - status = AE_ERROR; - } - break; - } - break; - - case BN_TYPE_SLEEP_BUTTON_FIXED: - bn_sleep_button = BN_TYPE_FIXED; - printk(KERN_INFO "ACPI: Sleep Button (FF) found\n"); - if (!proc_mkdir(BN_PROC_SLEEP_BUTTON, bn_proc_root)) { - status = AE_ERROR; - } - break; - - case BN_TYPE_SLEEP_BUTTON: - /* - * Avoid creating multiple /proc entries when (buggy) ACPI - * BIOS tables erroneously list both fixed- and generic- - * feature buttons. Note that fixed-feature buttons are - * always enumerated first (and there can only be one) so - * we only need to check here. - */ - switch (bn_sleep_button) { - case BN_TYPE_GENERIC: - printk(KERN_WARNING "ACPI: Multiple generic-space sleep buttons detected, using first\n"); - break; - case BN_TYPE_FIXED: - printk(KERN_WARNING "ACPI: Multiple sleep buttons detected, ignoring fixed-feature\n"); - default: - bn_sleep_button = BN_TYPE_GENERIC; - printk(KERN_INFO "ACPI: Sleep Button (CM) found\n"); - if (!proc_mkdir(BN_PROC_SLEEP_BUTTON, bn_proc_root)) { - status = AE_ERROR; - } - break; - } - break; - - case BN_TYPE_LID_SWITCH: - if (bn_lid_switch) { - printk(KERN_WARNING "ACPI: Multiple generic-space lid switches detected, using first\n"); - break; - } - bn_lid_switch = BN_TYPE_GENERIC; - printk(KERN_INFO "ACPI: Lid Switch (CM) found\n"); - if (!proc_mkdir(BN_PROC_LID_SWITCH, bn_proc_root)) { - status = AE_ERROR; - } - break; - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: bn_osl_remove_device - * - ****************************************************************************/ - -acpi_status -bn_osl_remove_device ( - BN_CONTEXT *button) -{ - if (!button) { - return(AE_BAD_PARAMETER); - } - - switch (button->type) { - - case BN_TYPE_POWER_BUTTON: - case BN_TYPE_POWER_BUTTON_FIXED: - remove_proc_entry(BN_PROC_POWER_BUTTON, bn_proc_root); - break; - - case BN_TYPE_SLEEP_BUTTON: - case BN_TYPE_SLEEP_BUTTON_FIXED: - remove_proc_entry(BN_PROC_SLEEP_BUTTON, bn_proc_root); - break; - - case BN_TYPE_LID_SWITCH: - remove_proc_entry(BN_PROC_LID_SWITCH, bn_proc_root); - break; - } - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: bn_osl_generate_event - * - ****************************************************************************/ - -acpi_status -bn_osl_generate_event ( - u32 event, - BN_CONTEXT *button) -{ - acpi_status status = AE_OK; - - if (!button) { - return(AE_BAD_PARAMETER); - } - - switch (event) { - - case BN_NOTIFY_STATUS_CHANGE: - - switch(button->type) { - - case BN_TYPE_POWER_BUTTON: - case BN_TYPE_POWER_BUTTON_FIXED: - status = bm_osl_generate_event(button->device_handle, - BN_PROC_ROOT, BN_PROC_POWER_BUTTON, event, 0); - break; - - case BN_TYPE_SLEEP_BUTTON: - case BN_TYPE_SLEEP_BUTTON_FIXED: - status = bm_osl_generate_event(button->device_handle, - BN_PROC_ROOT, BN_PROC_SLEEP_BUTTON, event, 0); - break; - - case BN_TYPE_LID_SWITCH: - status = bm_osl_generate_event(button->device_handle, - BN_PROC_ROOT, BN_PROC_LID_SWITCH, event, 0); - break; - - default: - status = AE_SUPPORT; - break; - } - - break; - - default: - return(AE_BAD_PARAMETER); - break; - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: bn_osl_init - * - * PARAMETERS: - * - * RETURN: 0: Success - * - * DESCRIPTION: Module initialization. - * - ****************************************************************************/ - -static int __init -bn_osl_init (void) -{ - acpi_status status = AE_OK; - - /* abort if no busmgr */ - if (!bm_proc_root) - return -ENODEV; - - bn_proc_root = proc_mkdir(BN_PROC_ROOT, bm_proc_root); - if (!bn_proc_root) { - status = AE_ERROR; - } - else { - status = bn_initialize(); - if (ACPI_FAILURE(status)) { - remove_proc_entry(BN_PROC_ROOT, bm_proc_root); - } - } - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - - -/**************************************************************************** - * - * FUNCTION: bn_osl_cleanup - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Module cleanup. - * - ****************************************************************************/ - -static void __exit -bn_osl_cleanup (void) -{ - bn_terminate(); - - if (bn_proc_root) { - remove_proc_entry(BN_PROC_ROOT, bm_proc_root); - } - - return; -} - - -module_init(bn_osl_init); -module_exit(bn_osl_cleanup); diff -urN linux-2.4.21/drivers/acpi/ospm/ec/Makefile linux-2.4.22/drivers/acpi/ospm/ec/Makefile --- linux-2.4.21/drivers/acpi/ospm/ec/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/ec/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/ec/ec_osl.c linux-2.4.22/drivers/acpi/ospm/ec/ec_osl.c --- linux-2.4.21/drivers/acpi/ospm/ec/ec_osl.c 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/ec/ec_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,91 +0,0 @@ -/***************************************************************************** - * - * Module Name: ec_osl.c - * $Revision: 11 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include "ec.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Embedded Controller Driver"); -MODULE_LICENSE("GPL"); - -extern struct proc_dir_entry *bm_proc_root; - - -/**************************************************************************** - * - * FUNCTION: ec_osl_init - * - * PARAMETERS: - * - * RETURN: 0: Success - * - * DESCRIPTION: Module initialization. - * - ****************************************************************************/ - -static int __init -ec_osl_init (void) -{ - acpi_status status = AE_OK; - - /* abort if no busmgr */ - if (!bm_proc_root) - return -ENODEV; - - status = ec_initialize(); - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - -/**************************************************************************** - * - * FUNCTION: ec_osl_cleanup - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Module cleanup. - * - ****************************************************************************/ - -static void __exit -ec_osl_cleanup(void) -{ - ec_terminate(); - - return; -} - -module_init(ec_osl_init); -module_exit(ec_osl_cleanup); diff -urN linux-2.4.21/drivers/acpi/ospm/ec/ecgpe.c linux-2.4.22/drivers/acpi/ospm/ec/ecgpe.c --- linux-2.4.21/drivers/acpi/ospm/ec/ecgpe.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/ec/ecgpe.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,249 +0,0 @@ -/***************************************************************************** - * - * Module Name: ecgpe.c - * $Revision: 28 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "ec.h" - -#define _COMPONENT ACPI_EC - MODULE_NAME ("ecgpe") - - -/**************************************************************************** - * - * FUNCTION: ec_query_handler - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -ec_query_handler ( - void *context) -{ - EC_CONTEXT *ec = (EC_CONTEXT*)context; - static char object_name[5] = {'_','Q','0','0','\0'}; - const char hex[] = {'0','1','2','3','4','5','6','7','8', - '9','A','B','C','D','E','F'}; - - FUNCTION_TRACE("ec_query_handler"); - - if (!ec) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return_VOID; - } - - /* - * Evaluate _Qxx: - * -------------- - * Evaluate corresponding _Qxx method. Note that a zero query value - * indicates a spurious EC_SCI (no such thing as _Q00). - */ - object_name[2] = hex[((ec->query_data >> 4) & 0x0F)]; - object_name[3] = hex[(ec->query_data & 0x0F)]; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Evaluating [%s] for ec [%02x].\n", object_name, ec->device_handle)); - - bm_evaluate_object(ec->acpi_handle, object_name, NULL, NULL); - - return_VOID; -} - - -/**************************************************************************** - * - * FUNCTION: ec_gpe_handler - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -ec_gpe_handler ( - void *context) -{ - acpi_status status = AE_OK; - EC_CONTEXT *ec = (EC_CONTEXT*)context; - EC_STATUS ec_status = 0; - - FUNCTION_TRACE("ec_gpe_handler"); - - if (!ec) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return_VOID; - } - - /* TBD: synchronize w/ transaction (ectransx). */ - - /* - * EC_SCI? - * ------- - * Check the EC_SCI bit to see if this is an EC_SCI event. If not (e.g. - * OBF/IBE) just return, as we already poll to detect these events. - */ - acpi_os_read_port(ec->status_port, &ec_status, 8); - if (!(ec_status & EC_FLAG_SCI)) { - return_VOID; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "EC_SCI event detected on ec [%02x] - running query.\n", ec->device_handle)); - - /* - * Run Query: - * ---------- - * Query the EC to find out which _Qxx method we need to evaluate. - * Note that successful completion of the query causes the EC_SCI - * bit to be cleared (and thus clearing the interrupt source). - */ - status = ec_io_write(ec, ec->command_port, EC_COMMAND_QUERY, - EC_EVENT_OUTPUT_BUFFER_FULL); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'query command' to EC.\n")); - return_VOID; - } - - status = ec_io_read(ec, ec->data_port, &(ec->query_data), - EC_EVENT_NONE); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Error reading query data.\n")); - return_VOID; - } - - /* TBD: un-synchronize w/ transaction (ectransx). */ - - /* - * Spurious EC_SCI? - * ---------------- - */ - if (!ec->query_data) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Spurious EC SCI detected.\n")); - return_VOID; - } - - /* - * Defer _Qxx Execution: - * --------------------- - * Can't evaluate this method now 'cause we're at interrupt-level. - */ - status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, - ec_query_handler, ec); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to defer _Qxx method evaluation.\n")); - return_VOID; - } - - return_VOID; -} - - -/**************************************************************************** - * - * FUNCTION: ec_install_gpe_handler - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_install_gpe_handler ( - EC_CONTEXT *ec) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_install_gpe_handler"); - - if (!ec) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Evaluate _GPE: - * -------------- - * Evaluate the "_GPE" object (required) to find out which GPE bit - * is used by this EC to signal events (SCIs). - */ - status = bm_evaluate_simple_integer(ec->acpi_handle, - "_GPE", &(ec->gpe_bit)); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Install GPE Handler: - * -------------------- - * Install a handler for this EC's GPE bit. - */ - status = acpi_install_gpe_handler(ec->gpe_bit, ACPI_EVENT_EDGE_TRIGGERED, - &ec_gpe_handler, ec); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "acpi_install_gpe_handler() failed for GPE bit [%02x] with status [%08x].\n", ec->gpe_bit, status)); - ec->gpe_bit = EC_GPE_UNKNOWN; - return_ACPI_STATUS(status); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_remove_gpe_handler - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_remove_gpe_handler ( - EC_CONTEXT *ec) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_remove_gpe_handler"); - - if (!ec) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = acpi_remove_gpe_handler(ec->gpe_bit, &ec_gpe_handler); - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/ec/ecmain.c linux-2.4.22/drivers/acpi/ospm/ec/ecmain.c --- linux-2.4.21/drivers/acpi/ospm/ec/ecmain.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/ec/ecmain.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,498 +0,0 @@ -/***************************************************************************** - * - * Module Name: ecmain.c - * $Revision: 29 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "ec.h" - -#define _COMPONENT ACPI_EC - MODULE_NAME ("ecmain") - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: ec_print - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Prints out information on a specific ec. - * - ****************************************************************************/ - -void -ec_print ( - EC_CONTEXT *ec) -{ -#ifdef ACPI_DEBUG - acpi_buffer buffer; -#endif /*ACPI_DEBUG*/ - - PROC_NAME("ec_print"); - - if (!ec) { - return; - } - - acpi_os_printf("EC: found, GPE %d\n", ec->gpe_bit); - -#ifdef ACPI_DEBUG - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - /* - * Get the full pathname for this ACPI object. - */ - acpi_get_name(ec->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - /* - * Print out basic thermal zone information. - */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Embedded_controller[%02x]:[%p] %s\n", ec->device_handle, ec->acpi_handle, (char*)buffer.pointer)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| gpe_bit[%02x] status/command_port[%02x] data_port[%02x]\n", ec->gpe_bit, ec->status_port, ec->data_port)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); -#endif /*ACPI_DEBUG*/ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: ec_get_port_values - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Evaluate _CRS to get the current resources (I/O port - * addresses) for this EC. - * - ****************************************************************************/ - -acpi_status -ec_get_port_values( - EC_CONTEXT *ec) -{ - acpi_status status = AE_OK; - acpi_buffer buffer; - acpi_resource *resource = NULL; - - FUNCTION_TRACE("ec_get_port_values"); - - if (!ec) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - buffer.length = 0; - buffer.pointer = NULL; - - status = acpi_get_current_resources(ec->acpi_handle, &buffer); - if (status != AE_BUFFER_OVERFLOW) { - return_ACPI_STATUS(status); - } - - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - status = acpi_get_current_resources(ec->acpi_handle, &buffer); - if (ACPI_FAILURE(status)) { - goto end; - } - - resource = (acpi_resource *) buffer.pointer; - ec->data_port = resource->data.io.min_base_address; - - resource = NEXT_RESOURCE(resource); - - ec->status_port = ec->command_port = - resource->data.io.min_base_address; -end: - acpi_os_free(buffer.pointer); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_add_device( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - EC_CONTEXT *ec = NULL; - u8 gpe_handler = FALSE; - u8 space_handler = FALSE; - - FUNCTION_TRACE("ec_add_device"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding EC device [%02x].\n", device_handle)); - - if (!context || *context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Get information on this device. - */ - status = bm_get_device_info(device_handle, &device); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Allocate a new EC_CONTEXT structure. - */ - ec = acpi_os_callocate(sizeof(EC_CONTEXT)); - if (!ec) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - ec->device_handle = device->handle; - ec->acpi_handle = device->acpi_handle; - - /* - * Get the I/O port addresses for the command/status and data ports. - */ - status = ec_get_port_values(ec); - if (ACPI_FAILURE(status)) { - goto end; - } - - /* - * See if we need to obtain the global lock for EC transactions. - */ - status = bm_evaluate_simple_integer(ec->acpi_handle, "_GLK", - &ec->use_global_lock); - if (status == AE_NOT_FOUND) { - ec->use_global_lock = 0; - } - else if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "EC _GLK failed\n")); - goto end; - } - - /* - * Install a handler for servicing this EC's GPE. - */ - status = ec_install_gpe_handler(ec); - if (ACPI_FAILURE(status)) { - goto end; - } - else { - gpe_handler = TRUE; - } - - /* - * Install a handler for servicing this EC's address space. - */ - status = ec_install_space_handler(ec); - if (ACPI_FAILURE(status)) { - goto end; - } - else { - space_handler = TRUE; - } - - /* - * Create a semaphore to serialize EC transactions. - */ - status = acpi_os_create_semaphore(1,1, &(ec->mutex)); - if (ACPI_FAILURE(status)) { - goto end; - } - - /* - * Context now contains information specific to this EC. Note - * that we'll get this pointer back on every ec_request() and - * ec_notify(). - */ - *context = ec; - - ec_print(ec); - -end: - if (ACPI_FAILURE(status)) { - - if (gpe_handler) { - ec_remove_gpe_handler(ec); - } - - if (space_handler) { - ec_remove_space_handler(ec); - } - - if (ec->mutex) { - acpi_os_delete_semaphore(ec->mutex); - } - - acpi_os_free(ec); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_remove_device( - void **context) -{ - acpi_status status = AE_OK; - EC_CONTEXT *ec = NULL; - - FUNCTION_TRACE("ec_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ec = (EC_CONTEXT*)*context; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing EC device [%02x].\n", ec->device_handle)); - - ec_remove_space_handler(ec); - - ec_remove_gpe_handler(ec); - - if (ec->mutex) { - acpi_os_delete_semaphore(ec->mutex); - } - - acpi_os_free(ec); - - *context = NULL; - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: ec_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_initialize (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("ec_initialize"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Register driver for AC Adapter devices. - */ - MEMCPY(criteria.hid, EC_HID_EC, sizeof(EC_HID_EC)); - - driver.notify = &ec_notify; - driver.request = &ec_request; - - status = bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_terminate - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_terminate(void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("ec_terminate"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Unregister driver for AC Adapter devices. - */ - MEMCPY(criteria.hid, EC_HID_EC, sizeof(EC_HID_EC)); - - driver.notify = &ec_notify; - driver.request = &ec_request; - - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_notify ( - BM_NOTIFY notify, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_notify"); - - switch (notify) { - - case BM_NOTIFY_DEVICE_ADDED: - status = ec_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = ec_remove_device(context); - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - EC_REQUEST *ec_request = NULL; - EC_CONTEXT *ec = NULL; - - FUNCTION_TRACE("ec_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - /* - * buffer must contain a valid EC_REQUEST structure. - */ - status = bm_cast_buffer(&(request->buffer), (void**)&ec_request, - sizeof(EC_REQUEST)); - if (ACPI_FAILURE(status)) - return_ACPI_STATUS(status); - - /* - * context contains information specific to this EC. - */ - ec = (EC_CONTEXT*)context; - - /* - * Perform the Transaction. - */ - status = ec_transaction(ec, ec_request); - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/ec/ecspace.c linux-2.4.22/drivers/acpi/ospm/ec/ecspace.c --- linux-2.4.21/drivers/acpi/ospm/ec/ecspace.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/ec/ecspace.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,192 +0,0 @@ -/***************************************************************************** - * - * Module Name: ecspace.c - * $Revision: 23 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "ec.h" - -#define _COMPONENT ACPI_EC - MODULE_NAME ("ecspace") - - -/**************************************************************************** - * - * FUNCTION: ec_space_setup - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_space_setup ( - acpi_handle region_handle, - u32 function, - void *handler_context, - void **return_context) -{ - /* - * The EC object is in the handler context and is needed - * when calling the ec_space_handler. - */ - *return_context = handler_context; - - return AE_OK; -} - - -/**************************************************************************** - * - * FUNCTION: ec_space_handler - * - * PARAMETERS: function - Read or Write operation - * address - Where in the space to read or write - * bit_width - Field width in bits (should be 8) - * value - Pointer to in or out value - * context - context pointer - * - * RETURN: - * - * DESCRIPTION: Handler for the Embedded Controller (EC) address space - * (Op Region) - * - ****************************************************************************/ - -acpi_status -ec_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - u32 *value, - void *handler_context, - void *region_context) -{ - acpi_status status = AE_OK; - EC_CONTEXT *ec = NULL; - EC_REQUEST ec_request; - - FUNCTION_TRACE("ec_space_handler"); - - if (address > 0xFF || bit_width != 8 || !value || !handler_context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ec = (EC_CONTEXT*)handler_context; - - switch (function) { - - case ACPI_READ_ADR_SPACE: - ec_request.command = EC_COMMAND_READ; - ec_request.address = address; - ec_request.data = 0; - break; - - case ACPI_WRITE_ADR_SPACE: - ec_request.command = EC_COMMAND_WRITE; - ec_request.address = address; - ec_request.data = (u8)(*value); - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Received request with invalid function [%X].\n", function)); - return_ACPI_STATUS(AE_BAD_PARAMETER); - break; - } - - /* - * Perform the Transaction. - */ - status = ec_transaction(ec, &ec_request); - if (ACPI_SUCCESS(status)) { - (*value) = (u32)ec_request.data; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_install_space_handler - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_install_space_handler ( - EC_CONTEXT *ec) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_install_space_handler"); - - if (!ec) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = acpi_install_address_space_handler (ec->acpi_handle, - ACPI_ADR_SPACE_EC, &ec_space_handler, &ec_space_setup, ec); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_remove_space_handler - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_remove_space_handler ( - EC_CONTEXT *ec) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_remove_space_handler"); - - if (!ec) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = acpi_remove_address_space_handler(ec->acpi_handle, - ACPI_ADR_SPACE_EC, &ec_space_handler); - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/ec/ectransx.c linux-2.4.22/drivers/acpi/ospm/ec/ectransx.c --- linux-2.4.21/drivers/acpi/ospm/ec/ectransx.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/ec/ectransx.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,343 +0,0 @@ -/***************************************************************************** - * - * Module Name: ectransx.c - * $Revision: 24 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "ec.h" - -#define _COMPONENT ACPI_EC - MODULE_NAME ("ectransx") - - -/**************************************************************************** - * - * FUNCTION: ec_io_wait - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_io_wait ( - EC_CONTEXT *ec, - EC_EVENT wait_event) -{ - EC_STATUS ec_status = 0; - u32 i = 100; - - if (!ec || ((wait_event != EC_EVENT_OUTPUT_BUFFER_FULL) - && (wait_event != EC_EVENT_INPUT_BUFFER_EMPTY))) { - return(AE_BAD_PARAMETER); - } - - /* - * Wait for Event: - * --------------- - * Poll the EC status register waiting for the event to occur. - * Note that we'll wait a maximum of 1ms in 10us chunks. - */ - switch (wait_event) { - - case EC_EVENT_OUTPUT_BUFFER_FULL: - do { - acpi_os_read_port(ec->status_port, &ec_status, 8); - if (ec_status & EC_FLAG_OUTPUT_BUFFER) { - return(AE_OK); - } - acpi_os_stall(10); - } while (--i>0); - break; - - case EC_EVENT_INPUT_BUFFER_EMPTY: - do { - acpi_os_read_port(ec->status_port, &ec_status, 8); - if (!(ec_status & EC_FLAG_INPUT_BUFFER)) { - return(AE_OK); - } - acpi_os_stall(10); - } while (--i>0); - break; - } - - return(AE_TIME); -} - - -/**************************************************************************** - * - * FUNCTION: ec_io_read - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_io_read ( - EC_CONTEXT *ec, - u32 io_port, - u8 *data, - EC_EVENT wait_event) -{ - acpi_status status = AE_OK; - - if (!ec || !data) { - return(AE_BAD_PARAMETER); - } - - acpi_os_read_port(io_port, (u32*) data, 8); - - if (wait_event) { - status = ec_io_wait(ec, wait_event); - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_io_write - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_io_write ( - EC_CONTEXT *ec, - u32 io_port, - u8 data, - EC_EVENT wait_event) -{ - acpi_status status = AE_OK; - - if (!ec) { - return(AE_BAD_PARAMETER); - } - - acpi_os_write_port(io_port, data, 8); - - if (wait_event) { - status = ec_io_wait(ec, wait_event); - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_read - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_read ( - EC_CONTEXT *ec, - u8 address, - u8 *data) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_read"); - - if (!ec || !data) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (ec->use_global_lock) { - status = acpi_acquire_global_lock(); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not acquire Global Lock\n")); - return_ACPI_STATUS(status); - } - } - - status = ec_io_write(ec, ec->command_port, EC_COMMAND_READ, - EC_EVENT_INPUT_BUFFER_EMPTY); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'read command' to EC.\n")); - return_ACPI_STATUS(status); - } - - status = ec_io_write(ec, ec->data_port, address, - EC_EVENT_OUTPUT_BUFFER_FULL); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'read address' to EC.\n")); - return_ACPI_STATUS(status); - } - - status = ec_io_read(ec, ec->data_port, data, EC_EVENT_NONE); - - if (ec->use_global_lock) { - acpi_release_global_lock(); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Read data [%02x] from address [%02x] on ec [%02x].\n", (*data), address, ec->device_handle)); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_write - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_write ( - EC_CONTEXT *ec, - u8 address, - u8 data) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_write"); - - if (!ec) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - if (ec->use_global_lock) { - status = acpi_acquire_global_lock(); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not acquire Global Lock\n")); - return_ACPI_STATUS(status); - } - } - - status = ec_io_write(ec, ec->command_port, EC_COMMAND_WRITE, - EC_EVENT_INPUT_BUFFER_EMPTY); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'write command' to EC.\n")); - return_ACPI_STATUS(status); - } - - status = ec_io_write(ec, ec->data_port, address, - EC_EVENT_INPUT_BUFFER_EMPTY); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'write address' to EC.\n")); - return_ACPI_STATUS(status); - } - - status = ec_io_write(ec, ec->data_port, data, - EC_EVENT_INPUT_BUFFER_EMPTY); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'write data' to EC.\n")); - return_ACPI_STATUS(status); - } - - if (ec->use_global_lock) { - acpi_release_global_lock(); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Wrote data [%02x] to address [%02x] on ec [%02x].\n", data, address, ec->device_handle)); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: ec_transaction - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -ec_transaction ( - EC_CONTEXT *ec, - EC_REQUEST *request) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("ec_transaction"); - - if (!ec || !request) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Obtain mutex to serialize all EC transactions. - */ - status = acpi_os_wait_semaphore(ec->mutex, 1, EC_DEFAULT_TIMEOUT); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Perform the transaction. - */ - switch (request->command) { - - case EC_COMMAND_READ: - status = ec_read(ec, request->address, &(request->data)); - break; - - case EC_COMMAND_WRITE: - status = ec_write(ec, request->address, request->data); - break; - - default: - status = AE_SUPPORT; - break; - } - - /* - * Signal the mutex to indicate transaction completion. - */ - acpi_os_signal_semaphore(ec->mutex, 1); - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/include/ac.h linux-2.4.22/drivers/acpi/ospm/include/ac.h --- linux-2.4.21/drivers/acpi/ospm/include/ac.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/ac.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,102 +0,0 @@ -/***************************************************************************** - * - * Module Name: ac.h - * $Revision: 6 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __AC_H__ -#define __AC_H__ - -#include -#include -#include - - -/***************************************************************************** - * Types & Other Defines - *****************************************************************************/ - -/* - * Notifications: - * -------------- - */ -#define AC_NOTIFY_STATUS_CHANGE ((BM_NOTIFY) 0x80) - -/* - * Hardware IDs: - * ------------- - */ -#define AC_HID_AC_ADAPTER "ACPI0003" - - -/* - * Device Context: - * --------------- - */ -typedef struct -{ - BM_HANDLE device_handle; - acpi_handle acpi_handle; - char uid[9]; - u32 is_online; -} AC_CONTEXT; - - -/***************************************************************************** - * Function Prototypes - *****************************************************************************/ - -acpi_status -ac_initialize (void); - -acpi_status -ac_terminate (void); - -acpi_status -ac_notify ( - u32 notify_type, - u32 device, - void **context); - -acpi_status -ac_request( - BM_REQUEST *request_info, - void *context); - -/* AC Adapter Driver OSL */ - -acpi_status -ac_osl_add_device ( - AC_CONTEXT *ac_adapter); - -acpi_status -ac_osl_remove_device ( - AC_CONTEXT *ac_adapter); - -acpi_status -ac_osl_generate_event ( - u32 event, - AC_CONTEXT *ac_adapter); - - -#endif /* __AC_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/bm.h linux-2.4.22/drivers/acpi/ospm/include/bm.h --- linux-2.4.21/drivers/acpi/ospm/include/bm.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/bm.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,583 +0,0 @@ -/***************************************************************************** - * - * Module name: bm.h - * $Revision: 41 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __BM_H__ -#define __BM_H__ - -#include -#include - - -/***************************************************************************** - * Types & Defines - *****************************************************************************/ - -/* - * Output Flags (Debug): - * --------------------- - */ -#define BM_PRINT_ALL (0x00000000) -#define BM_PRINT_GROUP (0x00000001) -#define BM_PRINT_LINKAGE (0x00000002) -#define BM_PRINT_IDENTIFICATION (0x00000004) -#define BM_PRINT_POWER (0x00000008) -#define BM_PRINT_PRESENT (0x00000010) - - -/* - * BM_COMMAND: - * ----------- - */ -typedef u32 BM_COMMAND; - -#define BM_COMMAND_UNKNOWN ((BM_COMMAND) 0x00) - -#define BM_COMMAND_GET_POWER_STATE ((BM_COMMAND) 0x01) -#define BM_COMMAND_SET_POWER_STATE ((BM_COMMAND) 0x02) - -#define BM_COMMAND_DEVICE_SPECIFIC ((BM_COMMAND) 0x80) - -/* - * BM_NOTIFY: - * ---------- - * Standard ACPI notification values, from section 5.6.3 of the ACPI 2.0 - * specification. Note that the Bus Manager internally handles all - * standard ACPI notifications -- driver modules are never sent these - * values (see "Bus Manager Notifications", below). - */ -typedef u32 BM_NOTIFY; - -#define BM_NOTIFY_BUS_CHECK ((BM_NOTIFY) 0x00) -#define BM_NOTIFY_DEVICE_CHECK ((BM_NOTIFY) 0x01) -#define BM_NOTIFY_DEVICE_WAKE ((BM_NOTIFY) 0x02) -#define BM_NOTIFY_EJECT_REQUEST ((BM_NOTIFY) 0x03) -#define BM_NOTIFY_DEVICE_CHECK_LIGHT ((BM_NOTIFY) 0x04) -#define BM_NOTIFY_FREQUENCY_MISMATCH ((BM_NOTIFY) 0x05) -#define BM_NOTIFY_BUS_MODE_MISMATCH ((BM_NOTIFY) 0x06) -#define BM_NOTIFY_POWER_FAULT ((BM_NOTIFY) 0x07) - -/* - * These are a higher-level abstraction of ACPI notifications, intended - * for consumption by driver modules to facilitate Pn_p. - */ -#define BM_NOTIFY_UNKNOWN ((BM_NOTIFY) 0x00) -#define BM_NOTIFY_DEVICE_ADDED ((BM_NOTIFY) 0x01) -#define BM_NOTIFY_DEVICE_REMOVED ((BM_NOTIFY) 0x02) - - -/* - * BM_HANDLE: - * ---------- - */ -typedef u32 BM_HANDLE; - -#define BM_HANDLE_ROOT ((BM_HANDLE) 0x00000000) -#define BM_HANDLE_UNKNOWN ((BM_HANDLE) 0xFFFFFFFF) -#define BM_HANDLES_MAX 100 - - -/* - * BM_HANDLE_LIST: - * --------------- - */ -typedef struct -{ - u32 count; - BM_HANDLE handles[BM_HANDLES_MAX]; -} BM_HANDLE_LIST; - - -/* - * BM_DEVICE_TYPE: - * --------------- - */ -typedef u32 BM_DEVICE_TYPE; - -#define BM_TYPE_UNKNOWN ((BM_DEVICE_TYPE) 0x00000000) - -#define BM_TYPE_SYSTEM ((BM_DEVICE_TYPE) 0x00000001) -#define BM_TYPE_SCOPE ((BM_DEVICE_TYPE) 0x00000002) -#define BM_TYPE_PROCESSOR ((BM_DEVICE_TYPE) 0x00000003) -#define BM_TYPE_THERMAL_ZONE ((BM_DEVICE_TYPE) 0x00000004) -#define BM_TYPE_POWER_RESOURCE ((BM_DEVICE_TYPE) 0x00000005) -#define BM_TYPE_DEVICE ((BM_DEVICE_TYPE) 0x00000006) -#define BM_TYPE_FIXED_BUTTON ((BM_DEVICE_TYPE) 0x00000007) - - -/* - * BM_DEVICE_UID: - * -------------- - */ -typedef char BM_DEVICE_UID[9]; - -#define BM_UID_UNKNOWN '0' - - -/* - * BM_DEVICE_HID: - * -------------- - */ -typedef char BM_DEVICE_HID[9]; - -#define BM_HID_UNKNOWN '\0' -#define BM_HID_POWER_BUTTON "PNP0C0C" -#define BM_HID_SLEEP_BUTTON "PNP0C0E" - -/* - * BM_DEVICE_ADR: - * -------------- - */ -typedef u32 BM_DEVICE_ADR; - -#define BM_ADDRESS_UNKNOWN 0 - - -/* - * BM_DEVICE_FLAGS: - * ---------------- - * The encoding of BM_DEVICE_FLAGS is illustrated below. - * Note that a set bit (1) indicates the property is TRUE - * (e.g. if bit 0 is set then the device has dynamic status). - * +--+------------+-+-+-+-+-+-+-+ - * |31| Bits 30:7 |6|5|4|3|2|1|0| - * +--+------------+-+-+-+-+-+-+-+ - * | | | | | | | | | - * | | | | | | | | +- Dynamic status? - * | | | | | | | +--- Identifiable? - * | | | | | | +----- Configurable? - * | | | | | +------- Power Control? - * | | | | +--------- Ejectable? - * | | | +----------- Docking Station? - * | | +------------- Fixed-Feature? - * | +-------------------- - * +---------------------------- Driver Control? - * - * Dynamic status: Device has a _STA object. - * Identifiable: Device has a _HID and/or _ADR and possibly other - * identification objects defined. - * Configurable: Device has a _CRS and possibly other configuration - * objects defined. - * Power Control: Device has a _PR0 and/or _PS0 and possibly other - * power management objects defined. - * Ejectable: Device has an _EJD and/or _EJx and possibly other - * dynamic insertion/removal objects defined. - * Docking Station: Device has a _DCK object defined. - * Fixed-Feature: Device does not exist in the namespace; was - * enumerated as a fixed-feature (e.g. power button). - * Driver Control: A driver has been installed for this device. - */ -typedef u32 BM_DEVICE_FLAGS; - -#define BM_FLAGS_UNKNOWN ((BM_DEVICE_FLAGS) 0x00000000) - -#define BM_FLAGS_DYNAMIC_STATUS ((BM_DEVICE_FLAGS) 0x00000001) -#define BM_FLAGS_IDENTIFIABLE ((BM_DEVICE_FLAGS) 0x00000002) -#define BM_FLAGS_CONFIGURABLE ((BM_DEVICE_FLAGS) 0x00000004) -#define BM_FLAGS_POWER_CONTROL ((BM_DEVICE_FLAGS) 0x00000008) -#define BM_FLAGS_EJECTABLE ((BM_DEVICE_FLAGS) 0x00000010) -#define BM_FLAGS_DOCKING_STATION ((BM_DEVICE_FLAGS) 0x00000020) -#define BM_FLAGS_FIXED_FEATURE ((BM_DEVICE_FLAGS) 0x00000040) -#define BM_FLAGS_DRIVER_CONTROL ((BM_DEVICE_FLAGS) 0x80000000) - - -/* - * Device PM Flags: - * ---------------- - * +-----------+-+-+-+-+-+-+-+ - * | Bits 31:7 |6|5|4|3|2|1|0| - * +-----------+-+-+-+-+-+-+-+ - * | | | | | | | | - * | | | | | | | +- D0 Support? - * | | | | | | +--- D1 Support? - * | | | | | +----- D2 Support? - * | | | | +------- D3 Support? - * | | | +--------- Power State Queriable? - * | | +----------- Inrush Current? - * | +------------- Wake Capable? - * +-------------------- - * - * D0-D3 Support: Device supports corresponding Dx state. - * Power State: Device has a _PSC (current power state) object defined. - * Inrush Current: Device has an _IRC (inrush current) object defined. - * Wake Capable: Device has a _PRW (wake-capable) object defined. - */ -#define BM_FLAGS_D0_SUPPORT ((BM_DEVICE_FLAGS) 0x00000001) -#define BM_FLAGS_D1_SUPPORT ((BM_DEVICE_FLAGS) 0x00000002) -#define BM_FLAGS_D2_SUPPORT ((BM_DEVICE_FLAGS) 0x00000004) -#define BM_FLAGS_D3_SUPPORT ((BM_DEVICE_FLAGS) 0x00000008) -#define BM_FLAGS_POWER_STATE ((BM_DEVICE_FLAGS) 0x00000010) -#define BM_FLAGS_INRUSH_CURRENT ((BM_DEVICE_FLAGS) 0x00000020) -#define BM_FLAGS_WAKE_CAPABLE ((BM_DEVICE_FLAGS) 0x00000040) - - -/* - * BM_DEVICE_STATUS: - * ----------------- - * The encoding of BM_DEVICE_STATUS is illustrated below. - * Note that a set bit (1) indicates the property is TRUE - * (e.g. if bit 0 is set then the device is present). - * +-----------+-+-+-+-+-+ - * | Bits 31:4 |4|3|2|1|0| - * +-----------+-+-+-+-+-+ - * | | | | | | - * | | | | | +- Present? - * | | | | +--- Enabled? - * | | | +----- Show in UI? - * | | +------- Functioning? - * | +--------- Battery Present? - * +---------------- - */ -typedef u32 BM_DEVICE_STATUS; - -#define BM_STATUS_UNKNOWN ((BM_DEVICE_STATUS) 0x00000000) -#define BM_STATUS_PRESENT ((BM_DEVICE_STATUS) 0x00000001) -#define BM_STATUS_ENABLED ((BM_DEVICE_STATUS) 0x00000002) -#define BM_STATUS_SHOW_UI ((BM_DEVICE_STATUS) 0x00000004) -#define BM_STATUS_FUNCTIONING ((BM_DEVICE_STATUS) 0x00000008) -#define BM_STATUS_BATTERY_PRESENT ((BM_DEVICE_STATUS) 0x00000010) -#define BM_STATUS_DEFAULT ((BM_DEVICE_STATUS) 0x0000000F) - - -/* - * BM_POWER_STATE: - * --------------- - */ -typedef u32 BM_POWER_STATE; - - -/* - * BM_DEVICE_ID: - * ------------- - */ -typedef struct -{ - BM_DEVICE_TYPE type; - BM_DEVICE_UID uid; - BM_DEVICE_HID hid; - BM_DEVICE_ADR adr; -} BM_DEVICE_ID; - - -/* - * BM_DEVICE_POWER: - * ---------------- - * Structure containing basic device power management information. - */ -typedef struct -{ - BM_DEVICE_FLAGS flags; - BM_POWER_STATE state; - BM_DEVICE_FLAGS dx_supported[ACPI_S_STATE_COUNT]; -} BM_DEVICE_POWER; - - -/* - * BM_DEVICE: - * ---------- - */ -typedef struct -{ - BM_HANDLE handle; - acpi_handle acpi_handle; - BM_DEVICE_FLAGS flags; - BM_DEVICE_STATUS status; - BM_DEVICE_ID id; - BM_DEVICE_POWER power; -} BM_DEVICE; - - -/* - * BM_SEARCH: - * ---------- - * Structure used for searching the ACPI Bus Manager's device hierarchy. - */ -typedef struct -{ - BM_DEVICE_ID criteria; - BM_HANDLE_LIST results; -} BM_SEARCH; - - -/* - * BM_REQUEST: - * ----------- - * Structure used for sending requests to/through the ACPI Bus Manager. - */ -typedef struct -{ - acpi_status status; - BM_COMMAND command; - BM_HANDLE handle; - acpi_buffer buffer; -} BM_REQUEST; - - -/* - * Driver Registration: - * -------------------- - */ - -/* Driver Context */ -typedef void * BM_DRIVER_CONTEXT; - -/* Notification Callback Function */ -typedef -acpi_status (*BM_DRIVER_NOTIFY) ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - BM_DRIVER_CONTEXT *context); - -/* Request Callback Function */ -typedef -acpi_status (*BM_DRIVER_REQUEST) ( - BM_REQUEST *request, - BM_DRIVER_CONTEXT context); - -/* Driver Registration */ -typedef struct -{ - BM_DRIVER_NOTIFY notify; - BM_DRIVER_REQUEST request; - BM_DRIVER_CONTEXT context; -} BM_DRIVER; - - -/* - * BM_NODE: - * -------- - * Structure used to maintain the device hierarchy. - */ -typedef struct _BM_NODE -{ - BM_DEVICE device; - BM_DRIVER driver; - struct _BM_NODE *parent; - struct _BM_NODE *next; - struct - { - struct _BM_NODE *head; - struct _BM_NODE *tail; - } scope; -} BM_NODE; - - -/* - * BM_NODE_LIST: - * ------------- - * Structure used to maintain an array of node pointers. - */ -typedef struct -{ - u32 count; - BM_NODE *nodes[BM_HANDLES_MAX]; -} BM_NODE_LIST; - - -/***************************************************************************** - * Macros - *****************************************************************************/ - -/* - * Device Presence: - * ---------------- - * Note that status (_STA) means something different for power resources - * (they're assumed to always be present). - */ -#define BM_DEVICE_PRESENT(d) ((d->id.type!=BM_TYPE_POWER_RESOURCE)?(d->status & BM_STATUS_PRESENT):TRUE) -#define BM_NODE_PRESENT(n) ((n->device.id.type!=BM_TYPE_POWER_RESOURCE)?(n->device.status & BM_STATUS_PRESENT):TRUE) - -/* - * Device Flags: - * ------------- - */ -#define BM_IS_DRIVER_CONTROL(d) (d->flags & BM_FLAGS_DRIVER_CONTROL) -#define BM_IS_POWER_CONTROL(d) (d->flags & BM_FLAGS_POWER_CONTROL) - - /* - * Device Power Flags: - * ------------------- - */ -#define BM_IS_POWER_STATE(d) (d->power.flags & BM_FLAGS_POWER_STATE) - -/***************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/* bm.c */ - -acpi_status -bm_initialize (void); - -acpi_status -bm_terminate (void); - -acpi_status -bm_get_status ( - BM_DEVICE *device); - -acpi_status -bm_get_handle ( - acpi_handle acpi_handle, - BM_HANDLE *device_handle); - -acpi_status -bm_get_node ( - BM_HANDLE device_handle, - acpi_handle acpi_handle, - BM_NODE **node); - -/* bmsearch.c */ - -acpi_status -bm_search( - BM_HANDLE device_handle, - BM_DEVICE_ID *criteria, - BM_HANDLE_LIST *results); - -/* bmnotify.c */ - -void -bm_notify ( - acpi_handle acpi_handle, - u32 notify_value, - void *context); - -/* bm_request.c */ - -acpi_status -bm_request ( - BM_REQUEST *request_info); - -/* bmdriver.c */ - -acpi_status -bm_get_device_power_state ( - BM_HANDLE device_handle, - BM_POWER_STATE *state); - -acpi_status -bm_set_device_power_state ( - BM_HANDLE device_handle, - BM_POWER_STATE state); - -acpi_status -bm_get_device_status ( - BM_HANDLE device_handle, - BM_DEVICE_STATUS *device_status); - -acpi_status -bm_get_device_info ( - BM_HANDLE device_handle, - BM_DEVICE **device_info); - -acpi_status -bm_get_device_context ( - BM_HANDLE device_handle, - BM_DRIVER_CONTEXT *context); - -acpi_status -bm_register_driver ( - BM_DEVICE_ID *criteria, - BM_DRIVER *driver); - -acpi_status -bm_unregister_driver ( - BM_DEVICE_ID *criteria, - BM_DRIVER *driver); - -/* bmpm.c */ - -acpi_status -bm_get_pm_capabilities ( - BM_NODE *node); - -acpi_status -bm_get_power_state ( - BM_NODE *node); - -acpi_status -bm_set_power_state ( - BM_NODE *node, - BM_POWER_STATE target_state); - -/* bmpower.c */ - -acpi_status -bm_pr_initialize (void); - -acpi_status -bm_pr_terminate (void); - -/* bmutils.c */ - -acpi_status -bm_cast_buffer ( - acpi_buffer *buffer, - void **pointer, - u32 length); - -acpi_status -bm_copy_to_buffer ( - acpi_buffer *buffer, - void *data, - u32 length); - -acpi_status -bm_extract_package_data ( - acpi_object *package, - acpi_buffer *format, - acpi_buffer *buffer); - -acpi_status -bm_evaluate_object ( - acpi_handle acpi_handle, - acpi_string pathname, - acpi_object_list *arguments, - acpi_buffer *buffer); - -acpi_status -bm_evaluate_simple_integer ( - acpi_handle acpi_handle, - acpi_string pathname, - u32 *data); - -acpi_status -bm_evaluate_reference_list ( - acpi_handle acpi_handle, - acpi_string pathname, - BM_HANDLE_LIST *reference_list); - -/* ACPI Bus Driver OSL */ - -acpi_status -bm_osl_generate_event ( - BM_HANDLE device_handle, - char *device_type, - char *device_instance, - u32 event_type, - u32 event_data); - - -#endif /* __BM_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/bmpower.h linux-2.4.22/drivers/acpi/ospm/include/bmpower.h --- linux-2.4.21/drivers/acpi/ospm/include/bmpower.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/bmpower.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,75 +0,0 @@ -/***************************************************************************** - * - * Module name: bmpower.h - * $Revision: 9 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __BMPOWER_H__ -#define __BMPOWER_H__ - -#include "bm.h" - - -/***************************************************************************** - * Types & Defines - *****************************************************************************/ - - -/* - * BM_POWER_RESOURCE: - * ------------------ - */ -typedef struct -{ - BM_HANDLE device_handle; - acpi_handle acpi_handle; - BM_POWER_STATE system_level; - u32 resource_order; - BM_POWER_STATE state; - u32 reference_count; -} BM_POWER_RESOURCE; - - -/***************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/* bmpower.c */ - -acpi_status -bm_pr_initialize (void); - -acpi_status -bm_pr_terminate (void); - -acpi_status -bm_pr_list_get_state ( - BM_HANDLE_LIST *resource_list, - BM_POWER_STATE *power_state); - -acpi_status -bm_pr_list_transition ( - BM_HANDLE_LIST *current_list, - BM_HANDLE_LIST *target_list); - - -#endif /* __BMPOWER_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/bn.h linux-2.4.22/drivers/acpi/ospm/include/bn.h --- linux-2.4.21/drivers/acpi/ospm/include/bn.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/bn.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,122 +0,0 @@ -/****************************************************************************** - * - * Module Name: bn.h - * $Revision: 12 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __BN_H__ -#define __BN_H__ - -#include -#include -#include - - -/***************************************************************************** - * Types & Other Defines - *****************************************************************************/ - -/* - * Notifications: - * --------------------- - */ -#define BN_NOTIFY_STATUS_CHANGE ((BM_NOTIFY) 0x80) - - -/* - * Types: - * ------ - */ -#define BN_TYPE_POWER_BUTTON 0x01 -#define BN_TYPE_POWER_BUTTON_FIXED 0x02 -#define BN_TYPE_SLEEP_BUTTON 0x03 -#define BN_TYPE_SLEEP_BUTTON_FIXED 0x04 -#define BN_TYPE_LID_SWITCH 0x05 - - -/* - * Hardware IDs: - * ------------- - * TBD: Power and Sleep button HIDs also exist in . Should all - * HIDs (ACPI well-known devices) exist in one place (e.g. - * acpi_hid.h)? - */ -#define BN_HID_POWER_BUTTON "PNP0C0C" -#define BN_HID_SLEEP_BUTTON "PNP0C0E" -#define BN_HID_LID_SWITCH "PNP0C0D" - - -/* - * Device Context: - * --------------- - */ -typedef struct -{ - BM_HANDLE device_handle; - acpi_handle acpi_handle; - u32 type; -} BN_CONTEXT; - - -/****************************************************************************** - * Function Prototypes - *****************************************************************************/ - -acpi_status -bn_initialize (void); - -acpi_status -bn_terminate (void); - -acpi_status -bn_notify_fixed ( - void *context); - -acpi_status -bn_notify ( - u32 notify_type, - u32 device, - void **context); - -acpi_status -bn_request( - BM_REQUEST *request_info, - void *context); - -/* Button OSL */ - -acpi_status -bn_osl_add_device ( - BN_CONTEXT *button); - -acpi_status -bn_osl_remove_device ( - BN_CONTEXT *button); - -acpi_status -bn_osl_generate_event ( - u32 event, - BN_CONTEXT *button); - - -#endif /* __BN_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/bt.h linux-2.4.22/drivers/acpi/ospm/include/bt.h --- linux-2.4.21/drivers/acpi/ospm/include/bt.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/bt.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,164 +0,0 @@ -/****************************************************************************** - * - * Module Name: bt.h - * $Revision: 18 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __BT_H__ -#define __BT_H__ - -#include -#include -#include - - -/***************************************************************************** - * Types & Other Defines - *****************************************************************************/ - -/*! [Begin] no source code translation */ - -#define BT_UNKNOWN 0xFFFFFFFF -#define BT_POWER_UNITS_DEFAULT "?" -#define BT_POWER_UNITS_WATTS "mW" -#define BT_POWER_UNITS_AMPS "mA" - -/*! [End] no source code translation !*/ - -/* - * Battery Notifications: - * ---------------------- - */ -#define BT_NOTIFY_STATUS_CHANGE ((BM_NOTIFY) 0x80) -#define BT_NOTIFY_INFORMATION_CHANGE ((BM_NOTIFY) 0x81) - - -/* - * Hardware IDs: - * ------------- - */ -#define BT_HID_CM_BATTERY "PNP0C0A" - - -/* - * BT_CM_BATTERY_INFO: - * ------------------- - */ -typedef struct -{ - acpi_integer power_unit; - acpi_integer design_capacity; - acpi_integer last_full_capacity; - acpi_integer battery_technology; - acpi_integer design_voltage; - acpi_integer design_capacity_warning; - acpi_integer design_capacity_low; - acpi_integer battery_capacity_granularity_1; - acpi_integer battery_capacity_granularity_2; - acpi_string model_number; - acpi_string serial_number; - acpi_string battery_type; - acpi_string oem_info; - -} BT_BATTERY_INFO; - - -/* - * BT_CM_BATTERY_STATUS: - * --------------------- - */ -typedef struct -{ - acpi_integer state; - acpi_integer present_rate; - acpi_integer remaining_capacity; - acpi_integer present_voltage; - -} BT_BATTERY_STATUS; - - -/* - * BT_CONTEXT: - * ----------- - */ -typedef struct -{ - BM_HANDLE device_handle; - acpi_handle acpi_handle; - char uid[9]; - acpi_string power_units; - u8 is_present; - -} BT_CONTEXT; - - -/***************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/* bt.c */ - -acpi_status -bt_initialize (void); - -acpi_status -bt_terminate (void); - -acpi_status -bt_notify ( - u32 notify_type, - u32 device, - void **context); - -acpi_status -bt_request( - BM_REQUEST *request_info, - void *context); - -acpi_status -bt_get_status ( - BT_CONTEXT *battery, - BT_BATTERY_STATUS **battery_status); - -acpi_status -bt_get_info ( - BT_CONTEXT *battery, - BT_BATTERY_INFO **battery_info); - -/* Battery OSL */ - -acpi_status -bt_osl_add_device ( - BT_CONTEXT *battery); - -acpi_status -bt_osl_remove_device ( - BT_CONTEXT *battery); - -acpi_status -bt_osl_generate_event ( - u32 event, - BT_CONTEXT *battery); - - -#endif /* __BT_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/ec.h linux-2.4.22/drivers/acpi/ospm/include/ec.h --- linux-2.4.21/drivers/acpi/ospm/include/ec.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/ec.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,202 +0,0 @@ -/***************************************************************************** - * - * Module Name: ec.h - * $Revision: 19 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __EC_H__ -#define __EC_H__ - -#include -#include -#include -#include -#include - - -/***************************************************************************** - * Types & Other Defines - *****************************************************************************/ - -#define EC_DEFAULT_TIMEOUT 1000 /* 1 second */ -#define EC_GPE_UNKNOWN 0xFFFFFFFF -#define EC_PORT_UNKNOWN 0x00000000 -#define EC_BURST_ENABLE_ACKNOWLEDGE 0x90 - - -/* - * Commands: - * --------- - */ -typedef u8 EC_COMMAND; - -#define EC_COMMAND_UNKNOWN ((EC_COMMAND) 0x00) -#define EC_COMMAND_READ ((EC_COMMAND) 0x80) -#define EC_COMMAND_WRITE ((EC_COMMAND) 0x81) -#define EC_COMMAND_QUERY ((EC_COMMAND) 0x84) - - -/* - * EC_STATUS: - * ---------- - * The encoding of the EC status register is illustrated below. - * Note that a set bit (1) indicates the property is TRUE - * (e.g. if bit 0 is set then the output buffer is full). - * +-+-+-+-+-+-+-+-+ - * |7|6|5|4|3|2|1|0| - * +-+-+-+-+-+-+-+-+ - * | | | | | | | | - * | | | | | | | +- Output Buffer Full (OBF)? - * | | | | | | +--- Input Buffer Full (IBF)? - * | | | | | +----- - * | | | | +------- data Register is command Byte? - * | | | +--------- Burst Mode Enabled? - * | | +----------- SCI event? - * | +------------- SMI event? - * +--------------- - * - */ -typedef u32 EC_STATUS; - -#define EC_FLAG_OUTPUT_BUFFER ((EC_STATUS) 0x01) -#define EC_FLAG_INPUT_BUFFER ((EC_STATUS) 0x02) -#define EC_FLAG_BURST_MODE ((EC_STATUS) 0x10) -#define EC_FLAG_SCI ((EC_STATUS) 0x20) - - -/* - * EC_EVENT: - * --------- - */ -typedef u32 EC_EVENT; - -#define EC_EVENT_UNKNOWN ((EC_EVENT) 0x00) -#define EC_EVENT_NONE ((EC_EVENT) 0x00) -#define EC_EVENT_OUTPUT_BUFFER_FULL ((EC_EVENT) 0x01) -#define EC_EVENT_INPUT_BUFFER_EMPTY ((EC_EVENT) 0x02) -#define EC_EVENT_SCI ((EC_EVENT) 0x03) - - -/* - * Hardware IDs: - * ------------- - */ -#define EC_HID_EC "PNP0C09" - - -/* - * EC_REQUEST: - * ----------- - */ -typedef struct -{ - EC_COMMAND command; - u8 address; - u8 data; -} EC_REQUEST; - - -/* - * Device Context: - * --------------- - */ -typedef struct -{ - BM_HANDLE device_handle; - acpi_handle acpi_handle; - u32 gpe_bit; - u32 status_port; - u32 command_port; - u32 data_port; - u32 use_global_lock; - u8 query_data; - acpi_handle mutex; -} EC_CONTEXT; - - -/***************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/* ec.c */ - -acpi_status -ec_initialize(void); - -acpi_status -ec_terminate(void); - -acpi_status -ec_notify ( - u32 notify_type, - u32 device, - void **context); - -acpi_status -ec_request( - BM_REQUEST *request_info, - void *context); - -/* ectransx.c */ - -acpi_status -ec_transaction ( - EC_CONTEXT *ec, - EC_REQUEST *ec_request); - -acpi_status -ec_io_read ( - EC_CONTEXT *ec, - u32 io_port, - u8 *data, - EC_EVENT wait_event); - -acpi_status -ec_io_write ( - EC_CONTEXT *ec, - u32 io_port, - u8 data, - EC_EVENT wait_event); - -/* ecgpe.c */ - -acpi_status -ec_install_gpe_handler ( - EC_CONTEXT *ec); - -acpi_status -ec_remove_gpe_handler ( - EC_CONTEXT *ec); - -/* ecspace.c */ - -acpi_status -ec_install_space_handler ( - EC_CONTEXT *ec); - -acpi_status -ec_remove_space_handler ( - EC_CONTEXT *ec); - - -#endif /* __EC_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/pr.h linux-2.4.22/drivers/acpi/ospm/include/pr.h --- linux-2.4.21/drivers/acpi/ospm/include/pr.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/pr.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,265 +0,0 @@ -/****************************************************************************** - * - * Module Name: processor.h - * $Revision: 13 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __PR_H__ -#define __PR_H__ - -#include - - -/***************************************************************************** - * Types & Other Defines - *****************************************************************************/ - - -#define PR_MAX_POWER_STATES 4 -#define PR_MAX_THROTTLE_STATES 8 -#define PR_MAX_PERF_STATES 32 -#define PR_MAX_C2_LATENCY 100 -#define PR_MAX_C3_LATENCY 1000 - - -/* - * Commands: - * --------- - */ -#define PR_COMMAND_GET_POWER_INFO ((BM_COMMAND) 0x80) -#define PR_COMMAND_SET_POWER_INFO ((BM_COMMAND) 0x81) -#define PR_COMMAND_GET_PERF_INFO ((BM_COMMAND) 0x82) -#define PR_COMMAND_GET_PERF_STATE ((BM_COMMAND) 0x83) -#define PR_COMMAND_SET_PERF_LIMIT ((BM_COMMAND) 0x84) - - -/* - * Notifications: - * -------------- - */ -#define PR_NOTIFY_PERF_STATES ((BM_NOTIFY) 0x80) -#define PR_NOTIFY_POWER_STATES ((BM_NOTIFY) 0x81) - - -/* - * Performance Control: - * -------------------- - */ -#define PR_PERF_DEC 0x00 -#define PR_PERF_INC 0x01 -#define PR_PERF_MAX 0xFF - - -/* - * Power States: - * ------------- - */ -#define PR_C0 0x00 -#define PR_C1 0x01 -#define PR_C2 0x02 -#define PR_C3 0x03 - -#define PR_C1_FLAG 0x01; -#define PR_C2_FLAG 0x02; -#define PR_C3_FLAG 0x04; - - -/* - * PR_CX_POLICY_VALUES: - * -------------------- - */ -typedef struct -{ - u32 time_threshold; - u32 count_threshold; - u32 bm_threshold; - u32 target_state; - u32 count; -} PR_CX_POLICY_VALUES; - - -/* - * PR_CX: - * ------ - */ -typedef struct -{ - u32 latency; - u32 utilization; - u8 is_valid; - PR_CX_POLICY_VALUES promotion; - PR_CX_POLICY_VALUES demotion; -} PR_CX; - - -/* - * PR_POWER: - * --------- - */ -typedef struct -{ - ACPI_PHYSICAL_ADDRESS p_lvl2; - ACPI_PHYSICAL_ADDRESS p_lvl3; - u32 bm_activity; - u32 active_state; - u32 default_state; - u32 busy_metric; - u32 state_count; - PR_CX state[PR_MAX_POWER_STATES]; -} PR_POWER; - - -/* - * PR_PERFORMANCE_STATE: - * --------------------- - */ -typedef struct -{ - u32 performance; - u32 power; -} PR_PERFORMANCE_STATE; - - -/* - * PR_PERFORMANCE: - * --------------- - */ -typedef struct -{ - u32 active_state; - u32 thermal_limit; - u32 power_limit; - u32 state_count; - PR_PERFORMANCE_STATE state[PR_MAX_PERF_STATES]; -} PR_PERFORMANCE; - - -/* - * PR_PBLOCK: - * ---------- - */ -typedef struct -{ - u32 length; - ACPI_PHYSICAL_ADDRESS address; -} PR_PBLOCK; - - -/* - * PR_CONTEXT: - * ----------- - */ -typedef struct -{ - BM_HANDLE device_handle; - acpi_handle acpi_handle; - u32 uid; - PR_PBLOCK pblk; - PR_POWER power; - PR_PERFORMANCE performance; -} PR_CONTEXT; - - -/****************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/* processor.c */ - -acpi_status -pr_initialize(void); - -acpi_status -pr_terminate(void); - -acpi_status -pr_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context); - -acpi_status -pr_request( - BM_REQUEST *request, - void *context); - -/* prpower.c */ - -void -pr_power_idle (void); - -acpi_status -pr_power_add_device ( - PR_CONTEXT *processor); - -acpi_status -pr_power_remove_device ( - PR_CONTEXT *processor); - -acpi_status -pr_power_initialize (void); - -acpi_status -pr_power_terminate (void); - -/* prperf.c */ - -acpi_status -pr_perf_get_state ( - PR_CONTEXT *processor, - u32 *state); - -acpi_status -pr_perf_set_state ( - PR_CONTEXT *processor, - u32 state); - -acpi_status -pr_perf_set_limit ( - PR_CONTEXT *processor, - u32 limit); - -acpi_status -pr_perf_add_device ( - PR_CONTEXT *processor); - -acpi_status -pr_perf_remove_device ( - PR_CONTEXT *processor); - -/* Processor Driver OSL */ - -acpi_status -pr_osl_add_device ( - PR_CONTEXT *processor); - -acpi_status -pr_osl_remove_device ( - PR_CONTEXT *processor); - -acpi_status -pr_osl_generate_event ( - u32 event, - PR_CONTEXT *processor); - - -#endif /* __PR_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/sm.h linux-2.4.22/drivers/acpi/ospm/include/sm.h --- linux-2.4.21/drivers/acpi/ospm/include/sm.h 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/sm.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,91 +0,0 @@ -/***************************************************************************** - * - * Module Name: sm.h - * $Revision: 3 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __SM_H__ -#define __SM_H__ - -#include -#include -#include - - -/***************************************************************************** - * Types & Other Defines - *****************************************************************************/ - -#define SM_MAX_SYSTEM_STATES 6 /* S0-S5 */ - - - /* - * Device Context: - * --------------- - */ -typedef struct -{ - BM_HANDLE device_handle; - acpi_handle acpi_handle; - u8 states[SM_MAX_SYSTEM_STATES]; -} SM_CONTEXT; - - -/***************************************************************************** - * Function Prototypes - *****************************************************************************/ - -acpi_status -sm_initialize (void); - -acpi_status -sm_terminate (void); - -acpi_status -sm_notify ( - u32 notify_type, - u32 device, - void **context); - -acpi_status -sm_request( - BM_REQUEST *request_info, - void *context); - -/* System Driver OSL */ - -acpi_status -sm_osl_add_device ( - SM_CONTEXT *system); - -acpi_status -sm_osl_remove_device ( - SM_CONTEXT *system); - -acpi_status -sm_osl_generate_event ( - u32 event, - SM_CONTEXT *system); - - -#endif /* __SM_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/include/tz.h linux-2.4.22/drivers/acpi/ospm/include/tz.h --- linux-2.4.21/drivers/acpi/ospm/include/tz.h 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/include/tz.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,252 +0,0 @@ -/***************************************************************************** - * - * Module Name: tz.h - * $Revision: 24 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 __TZ_H__ -#define __TZ_H__ - -/* TBD: Linux-specific */ -#include -#include - -#include -#include - - -/***************************************************************************** - * Types & Other Defines - *****************************************************************************/ - -#define TZ_MAX_THRESHOLDS 12 /* _AC0 through _AC9 + _CRT + _PSV */ -#define TZ_MAX_ACTIVE_THRESHOLDS 10 /* _AC0 through _AC9 */ -#define TZ_MAX_COOLING_DEVICES 10 /* TBD: Make size dynamic */ - - -/* - * Notifications: - * -------------- - */ -#define TZ_NOTIFY_TEMPERATURE_CHANGE ((BM_NOTIFY) 0x80) -#define TZ_NOTIFY_THRESHOLD_CHANGE ((BM_NOTIFY) 0x81) -#define TZ_NOTIFY_DEVICE_LISTS_CHANGE ((BM_NOTIFY) 0x82) - - -/* - * TZ_THRESHOLD_TYPE: - * ------------------ - */ -typedef u32 TZ_THRESHOLD_TYPE; - -#define TZ_THRESHOLD_UNKNOWN ((TZ_THRESHOLD_TYPE) 0x00) -#define TZ_THRESHOLD_CRITICAL ((TZ_THRESHOLD_TYPE) 0x01) - -#define TZ_THRESHOLD_PASSIVE ((TZ_THRESHOLD_TYPE) 0x02) -#define TZ_THRESHOLD_ACTIVE ((TZ_THRESHOLD_TYPE) 0x03) - - -/* - * TZ_COOLING_STATE: - * ----------------- - */ -typedef u32 TZ_COOLING_STATE; - -#define TZ_COOLING_UNKNOWN ((TZ_COOLING_STATE) 0x00) -#define TZ_COOLING_ENABLED ((TZ_COOLING_STATE) 0x01) -#define TZ_COOLING_DISABLED ((TZ_COOLING_STATE) 0x02) - - -/* - * TZ_COOLING_MODE: - * ---------------- - */ -typedef u32 TZ_COOLING_MODE; - -#define TZ_COOLING_MODE_ACTIVE ((TZ_COOLING_MODE) 0x00) -#define TZ_COOLING_MODE_PASSIVE ((TZ_COOLING_MODE) 0x01) - - -/* - * Thermal State: - * -------------- - * The encoding of TZ_STATE is illustrated below. - * Note that a set bit (1) indicates the property is TRUE - * (e.g. if bit 0 is set then the device has dynamic status). - * No bits set indicates an OK cooling state. - * +--+--+--+-----------+----------+ - * |31|30|29| Bits 27:4 | Bits 3:0 | - * +--+--+--+-----------+----------+ - * | | | | | - * | | | | +------ Active Index - * | | | +----------------- - * | | +------------------------- Active - * | +---------------------------- Passive - * +------------------------------- Critical - * - * Active Index: Value representing the level of active cooling - * presently applied (e.g. 0=_AL0, 9=_AL9). Only - * valid when 'Active' is set. - * Active: If set, indicates that the system temperature - * has crossed at least one active threshold (_ALx). - * Passive: If set, indicates that the system temperature - * has crossed the passive threshold (_PSL). - * Passive: If set, indicates that the system temperature - * has crossed the critical threshold (_CRT). - */ -typedef u32 TZ_STATE; - -#define TZ_STATE_OK ((TZ_STATE) 0x00000000) -#define TZ_STATE_HOT ((TZ_STATE) 0x10000000) -#define TZ_STATE_ACTIVE ((TZ_STATE) 0x20000000) -#define TZ_STATE_PASSIVE ((TZ_STATE) 0x40000000) -#define TZ_STATE_CRITICAL ((TZ_STATE) 0x80000000) - -typedef struct { - u32 temperature; -} TZ_CRITICAL_THRESHOLD; - -typedef struct { - u8 is_valid; - u32 temperature; -} TZ_HOT_THRESHOLD; - -typedef struct { - u8 is_valid; - u32 temperature; - u32 tc1; - u32 tc2; - u32 tsp; - BM_HANDLE_LIST devices; -} TZ_PASSIVE_THRESHOLD; - -typedef struct { - u8 is_valid; - u32 temperature; - TZ_COOLING_STATE cooling_state; - BM_HANDLE_LIST devices; -} TZ_ACTIVE_THRESHOLD; - -typedef struct { - TZ_CRITICAL_THRESHOLD critical; - TZ_HOT_THRESHOLD hot; - TZ_PASSIVE_THRESHOLD passive; - TZ_ACTIVE_THRESHOLD active[TZ_MAX_ACTIVE_THRESHOLDS]; -} TZ_THRESHOLDS; - -/* - * TZ_POLICY: - * --------- - */ -typedef struct { - u32 temperature; - TZ_STATE state; - TZ_COOLING_MODE cooling_mode; - u32 polling_freq; - TZ_THRESHOLDS thresholds; - struct timer_list timer; -} TZ_POLICY; - - -/* - * TZ_CONTEXT: - * ----------- - */ -typedef struct { - BM_HANDLE device_handle; - acpi_handle acpi_handle; - char uid[9]; - TZ_POLICY policy; -} TZ_CONTEXT; - - -/***************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/* tz.c */ - -acpi_status -tz_initialize (void); - -acpi_status -tz_terminate (void); - -acpi_status -tz_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - BM_DRIVER_CONTEXT *context); - -acpi_status -tz_request ( - BM_REQUEST *request, - BM_DRIVER_CONTEXT context); - -acpi_status -tz_get_temperature ( - TZ_CONTEXT *tz); - -acpi_status -tz_get_thresholds ( - TZ_CONTEXT *tz); - -acpi_status -tz_set_cooling_preference ( - TZ_CONTEXT *tz, - TZ_COOLING_MODE cooling_mode); - -void -tz_print ( - TZ_CONTEXT *tz); - -/* tzpolicy.c */ - -acpi_status -tz_policy_add_device ( - TZ_CONTEXT *tz); - -acpi_status -tz_policy_remove_device ( - TZ_CONTEXT *tz); - -void -tz_policy_check ( - void *context); - -/* tz_osl.c */ - -acpi_status -tz_osl_add_device ( - TZ_CONTEXT *tz); - -acpi_status -tz_osl_remove_device ( - TZ_CONTEXT *tz); - -acpi_status -tz_osl_generate_event ( - u32 event, - TZ_CONTEXT *tz); - - -#endif /* __TZ_H__ */ diff -urN linux-2.4.21/drivers/acpi/ospm/processor/Makefile linux-2.4.22/drivers/acpi/ospm/processor/Makefile --- linux-2.4.21/drivers/acpi/ospm/processor/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/processor/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/processor/pr.c linux-2.4.22/drivers/acpi/ospm/processor/pr.c --- linux-2.4.21/drivers/acpi/ospm/processor/pr.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/processor/pr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,497 +0,0 @@ -/***************************************************************************** - * - * Module Name: pr.c - * $Revision: 34 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "pr.h" - - -#define _COMPONENT ACPI_PROCESSOR - MODULE_NAME ("pr") - - -/**************************************************************************** - * Globals - ****************************************************************************/ - -extern fadt_descriptor_rev2 acpi_fadt; - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: pr_print - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Prints out information on a specific thermal zone. - * - ****************************************************************************/ - -void -pr_print ( - PR_CONTEXT *processor) -{ -#ifdef ACPI_DEBUG - acpi_buffer buffer; - - FUNCTION_TRACE("pr_print"); - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - /* - * Get the full pathname for this ACPI object. - */ - acpi_get_name(processor->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - /* - * Print out basic processor information. - */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Processor[%02x]:[%p] uid[%02x] %s\n", processor->device_handle, processor->acpi_handle, processor->uid, (char*)buffer.pointer)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| power: %cC0 %cC1 %cC2[%d] %cC3[%d]\n", (processor->power.state[0].is_valid?'+':'-'), (processor->power.state[1].is_valid?'+':'-'), (processor->power.state[2].is_valid?'+':'-'), processor->power.state[2].latency, (processor->power.state[3].is_valid?'+':'-'), processor->power.state[3].latency)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| performance: states[%d]\n", processor->performance.state_count)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); -#endif /* ACPI_DEBUG */ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: pr_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_add_device( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - PR_CONTEXT *processor = NULL; - BM_DEVICE *device = NULL; - acpi_buffer buffer; - acpi_object acpi_object; - static u32 processor_count = 0; - - - FUNCTION_TRACE("pr_add_device"); - - if (!context || *context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = bm_get_device_info(device_handle, &device); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - processor = acpi_os_callocate(sizeof(PR_CONTEXT)); - if (!processor) { - return AE_NO_MEMORY; - } - - processor->device_handle = device->handle; - processor->acpi_handle = device->acpi_handle; - - /* - * Processor Block: - * ---------------- - */ - memset(&acpi_object, 0, sizeof(acpi_object)); - - buffer.length = sizeof(acpi_object); - buffer.pointer = &acpi_object; - - status = acpi_evaluate_object(processor->acpi_handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - goto end; - } - - /* - * Processor ID: - * ------------- - * TBD: We need to synchronize the processor ID values in ACPI - * with those of the APIC. For example, an IBM T20 has a - * proc_id value of '1', where the Linux value for the - * first CPU on this system is '0'. Since x86 CPUs are - * mapped 1:1 we can simply use a zero-based counter. Note - * that this assumes that processor objects are enumerated - * in the proper order. - */ - /* processor->uid = acpi_object.processor.proc_id; */ - processor->uid = processor_count++; - - processor->pblk.length = acpi_object.processor.pblk_length; - processor->pblk.address = acpi_object.processor.pblk_address; - - status = pr_power_add_device(processor); - if (ACPI_FAILURE(status)) { - goto end; - } - - status = pr_perf_add_device(processor); - if (ACPI_FAILURE(status)) { - goto end; - } - - status = pr_osl_add_device(processor); - if (ACPI_FAILURE(status)) { - goto end; - } - - *context = processor; - - pr_print(processor); - -end: - if (ACPI_FAILURE(status)) { - acpi_os_free(processor); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: pr_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_remove_device ( - void **context) -{ - acpi_status status = AE_OK; - PR_CONTEXT *processor= NULL; - - FUNCTION_TRACE("pr_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - processor = (PR_CONTEXT*)(*context); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing processor device [%02x].\n", processor->device_handle)); - - pr_osl_remove_device(processor); - - pr_perf_remove_device(processor); - - pr_power_remove_device(processor); - - acpi_os_free(processor); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: pr_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_initialize (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("pr_initialize"); - - memset(&criteria, 0, sizeof(BM_DEVICE_ID)); - memset(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Initialize power (Cx state) policy. - */ - status = pr_power_initialize(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Register driver for processor devices. - */ - criteria.type = BM_TYPE_PROCESSOR; - - driver.notify = &pr_notify; - driver.request = &pr_request; - - status = bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: pr_terminate - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_terminate (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("pr_terminate"); - - memset(&criteria, 0, sizeof(BM_DEVICE_ID)); - memset(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Terminate power (Cx state) policy. - */ - status = pr_power_terminate(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Unegister driver for processor devices. - */ - criteria.type = BM_TYPE_PROCESSOR; - - driver.notify = &pr_notify; - driver.request = &pr_request; - - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: pr_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - PR_CONTEXT *processor = NULL; - - FUNCTION_TRACE("pr_notify"); - - processor = (PR_CONTEXT*)*context; - - switch (notify_type) { - - case BM_NOTIFY_DEVICE_ADDED: - status = pr_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = pr_remove_device(context); - break; - - case PR_NOTIFY_PERF_STATES: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Performance states change event detected on processor [%02x].\n", device_handle)); - /* TBD: Streamline (this is simple but overkill). */ - status = pr_perf_remove_device(processor); - if (ACPI_SUCCESS(status)) { - status = pr_perf_add_device(processor); - } - if (ACPI_SUCCESS(status)) { - status = pr_osl_generate_event(notify_type, - (processor)); - } - break; - - case PR_NOTIFY_POWER_STATES: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Power states change event detected on processor [%02x].\n", device_handle)); - /* TBD: Streamline (this is simple but overkill). */ - status = pr_power_remove_device(processor); - if (ACPI_SUCCESS(status)) { - status = pr_power_add_device(processor); - } - if (ACPI_SUCCESS(status)) { - status = pr_osl_generate_event(notify_type, - (processor)); - } - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: pr_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - PR_CONTEXT *processor = NULL; - - FUNCTION_TRACE("pr_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - processor = (PR_CONTEXT*)context; - - /* - * Handle request: - * --------------- - */ - switch (request->command) { - - case PR_COMMAND_GET_POWER_INFO: - status = bm_copy_to_buffer(&(request->buffer), - &(processor->power), sizeof(PR_POWER)); - break; - - case PR_COMMAND_SET_POWER_INFO: - { - PR_POWER *power_info = NULL; - u32 i = 0; - - status = bm_cast_buffer(&(request->buffer), - (void**)&power_info, sizeof(PR_POWER)); - if (ACPI_SUCCESS(status)) { - for (i=0; ipower.state_count; i++) { - MEMCPY(&(processor->power.state[i].promotion), - &(power_info->state[i].promotion), - sizeof(PR_CX_POLICY_VALUES)); - MEMCPY(&(processor->power.state[i].demotion), - &(power_info->state[i].demotion), - sizeof(PR_CX_POLICY_VALUES)); - } - } - } - break; - - case PR_COMMAND_GET_PERF_INFO: - status = bm_copy_to_buffer(&(request->buffer), - &(processor->performance), sizeof(PR_PERFORMANCE)); - break; - - case PR_COMMAND_GET_PERF_STATE: - status = bm_copy_to_buffer(&(request->buffer), - &(processor->performance.active_state), sizeof(u32)); - break; - - case PR_COMMAND_SET_PERF_LIMIT: - { - u32 *limit = NULL; - - status = bm_cast_buffer(&(request->buffer), - (void**)&limit, sizeof(u32)); - if (ACPI_SUCCESS(status)) { - status = pr_perf_set_limit(processor, *limit); - } - } - break; - - default: - status = AE_SUPPORT; - break; - } - - request->status = status; - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/processor/pr_osl.c linux-2.4.22/drivers/acpi/ospm/processor/pr_osl.c --- linux-2.4.21/drivers/acpi/ospm/processor/pr_osl.c 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/processor/pr_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,344 +0,0 @@ -/****************************************************************************** - * - * Module Name: pr_osl.c - * $Revision: 21 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "pr.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - IA32 Processor Driver"); -MODULE_LICENSE("GPL"); - - -#define PR_PROC_ROOT "processor" -#define PR_PROC_STATUS "status" -#define PR_PROC_INFO "info" - -extern struct proc_dir_entry *bm_proc_root; -static struct proc_dir_entry *pr_proc_root = NULL; -extern unsigned short acpi_piix4_bmisx; - - -/**************************************************************************** - * - * FUNCTION: pr_osl_proc_read_status - * - ****************************************************************************/ - -static int -pr_osl_proc_read_status ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - PR_CONTEXT *processor = NULL; - char *p = page; - int len = 0; - - if (!context || (off != 0)) { - goto end; - } - - processor = (PR_CONTEXT*)context; - - p += sprintf(p, "Bus Mastering Activity: %08x\n", - processor->power.bm_activity); - - p += sprintf(p, "C-State Utilization: C1[%d] C2[%d] C3[%d]\n", - processor->power.state[PR_C1].utilization, - processor->power.state[PR_C2].utilization, - processor->power.state[PR_C3].utilization); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return(len); -} - - -/**************************************************************************** - * - * FUNCTION: pr_osl_proc_read_info - * - ****************************************************************************/ - -static int -pr_osl_proc_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - PR_CONTEXT *processor = NULL; - char *p = page; - int len = 0; - - if (!context || (off != 0)) { - goto end; - } - - processor = (PR_CONTEXT*)context; - - p += sprintf(p, "\n"); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return(len); -} - - -/**************************************************************************** - * - * FUNCTION: pr_osl_add_device - * - ****************************************************************************/ - -acpi_status -pr_osl_add_device( - PR_CONTEXT *processor) -{ - u32 i = 0; - struct proc_dir_entry *proc_entry = NULL, *proc; - char processor_uid[16]; - - if (!processor) { - return(AE_BAD_PARAMETER); - } - - printk("Processor[%x]:", processor->uid); - for (i=0; ipower.state_count; i++) { - if (processor->power.state[i].is_valid) { - printk(" C%d", i); - } - } - if (processor->performance.state_count > 1) - printk(", %d throttling states", processor->performance.state_count); - if (acpi_piix4_bmisx && processor->power.state[3].is_valid) - printk(" (PIIX errata enabled)"); - printk("\n"); - - sprintf(processor_uid, "%d", processor->uid); - - proc_entry = proc_mkdir(processor_uid, pr_proc_root); - if (!proc_entry) - return(AE_ERROR); - - proc = create_proc_read_entry(PR_PROC_STATUS, S_IFREG | S_IRUGO, - proc_entry, pr_osl_proc_read_status, (void*)processor); - if (!proc_entry) - return(AE_ERROR); - - proc = create_proc_read_entry(PR_PROC_INFO, S_IFREG | S_IRUGO, - proc_entry, pr_osl_proc_read_info, (void*)processor); - if (!proc_entry) - return(AE_ERROR); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: pr_osl_remove_device - * - ****************************************************************************/ - -acpi_status -pr_osl_remove_device ( - PR_CONTEXT *processor) -{ - char proc_entry[64]; - - if (!processor) { - return(AE_BAD_PARAMETER); - } - - sprintf(proc_entry, "%d/%s", processor->uid, PR_PROC_INFO); - remove_proc_entry(proc_entry, pr_proc_root); - - sprintf(proc_entry, "%d/%s", processor->uid, PR_PROC_STATUS); - remove_proc_entry(proc_entry, pr_proc_root); - - sprintf(proc_entry, "%d", processor->uid); - remove_proc_entry(proc_entry, pr_proc_root); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: pr_osl_generate_event - * - ****************************************************************************/ - -acpi_status -pr_osl_generate_event ( - u32 event, - PR_CONTEXT *processor) -{ - acpi_status status = AE_OK; - char processor_uid[16]; - - if (!processor) { - return(AE_BAD_PARAMETER); - } - - switch (event) { - - case PR_NOTIFY_PERF_STATES: - case PR_NOTIFY_POWER_STATES: - sprintf(processor_uid, "%d", processor->uid); - status = bm_osl_generate_event(processor->device_handle, - PR_PROC_ROOT, processor_uid, event, 0); - break; - - default: - return(AE_BAD_PARAMETER); - break; - } - - return(status); -} - - -/**************************************************************************** - * Errata Handling - ****************************************************************************/ - -void acpi_pr_errata (void) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, - PCI_ANY_ID, PCI_ANY_ID, dev))) { - switch (dev->device) { - case PCI_DEVICE_ID_INTEL_82801BA_8: /* PIIX4U4 */ - case PCI_DEVICE_ID_INTEL_82801BA_9: /* PIIX4U3 */ - case PCI_DEVICE_ID_INTEL_82451NX: /* PIIX4NX */ - case PCI_DEVICE_ID_INTEL_82372FB_1: /* PIIX4U2 */ - case PCI_DEVICE_ID_INTEL_82801AA_1: /* PIIX4U */ - case PCI_DEVICE_ID_INTEL_82443MX_1: /* PIIX4E2 */ - case PCI_DEVICE_ID_INTEL_82801AB_1: /* PIIX4E */ - case PCI_DEVICE_ID_INTEL_82371AB: /* PIIX4 */ - acpi_piix4_bmisx = pci_resource_start(dev, 4); - return; - } - } - - return; -} - - -/**************************************************************************** - * - * FUNCTION: pr_osl_init - * - * PARAMETERS: - * - * RETURN: 0: Success - * - * DESCRIPTION: Module initialization. - * - ****************************************************************************/ - -static int __init -pr_osl_init (void) -{ - acpi_status status = AE_OK; - - /* abort if no busmgr */ - if (!bm_proc_root) - return -ENODEV; - - acpi_pr_errata(); - - pr_proc_root = proc_mkdir(PR_PROC_ROOT, bm_proc_root); - if (!pr_proc_root) { - status = AE_ERROR; - } - else { - status = pr_initialize(); - if (ACPI_FAILURE(status)) { - remove_proc_entry(PR_PROC_ROOT, bm_proc_root); - } - - } - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - - -/**************************************************************************** - * - * FUNCTION: pr_osl_cleanup - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Module cleanup. - * - ****************************************************************************/ - -static void __exit -pr_osl_cleanup (void) -{ - pr_terminate(); - - if (pr_proc_root) { - remove_proc_entry(PR_PROC_ROOT, bm_proc_root); - } - - return; -} - - -module_init(pr_osl_init); -module_exit(pr_osl_cleanup); diff -urN linux-2.4.21/drivers/acpi/ospm/processor/prperf.c linux-2.4.22/drivers/acpi/ospm/processor/prperf.c --- linux-2.4.21/drivers/acpi/ospm/processor/prperf.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/processor/prperf.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,456 +0,0 @@ -/***************************************************************************** - * - * Module Name: prperf.c - * $Revision: 21 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - */ - -/* - * TBD: 1. Support ACPI 2.0 processor performance states (not just throttling). - * 2. Fully implement thermal -vs- power management limit control. - */ - - -#include -#include -#include "pr.h" - -#define _COMPONENT ACPI_PROCESSOR - MODULE_NAME ("prperf") - - -/**************************************************************************** - * Globals - ****************************************************************************/ - -extern fadt_descriptor_rev2 acpi_fadt; -const u32 POWER_OF_2[] = {1,2,4,8,16,32,64,128,256,512}; - - -/**************************************************************************** - * - * FUNCTION: pr_perf_get_frequency - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_perf_get_frequency ( - PR_CONTEXT *processor, - u32 *frequency) { - acpi_status status = AE_OK; - - FUNCTION_TRACE("pr_perf_get_frequency"); - - if (!processor || !frequency) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* TBD: Generic method to calculate processor frequency. */ - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: pr_perf_get_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -/* TBD: Include support for _real_ performance states (not just throttling). */ - -acpi_status -pr_perf_get_state ( - PR_CONTEXT *processor, - u32 *state) -{ - u32 pblk_value = 0; - u32 duty_mask = 0; - u32 duty_cycle = 0; - - FUNCTION_TRACE("pr_perf_get_state"); - - if (!processor || !state) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (processor->performance.state_count == 1) { - *state = 0; - return_ACPI_STATUS(AE_OK); - } - - acpi_os_read_port(processor->pblk.address, &pblk_value, 32); - - /* - * Throttling Enabled? - * ------------------- - * If so, calculate the current throttling state, otherwise return - * '100% performance' (state 0). - */ - if (pblk_value & 0x00000010) { - - duty_mask = processor->performance.state_count - 1; - duty_mask <<= acpi_fadt.duty_offset; - - duty_cycle = pblk_value & duty_mask; - duty_cycle >>= acpi_fadt.duty_offset; - - if (duty_cycle == 0) { - *state = 0; - } - else { - *state = processor->performance.state_count - - duty_cycle; - } - } - else { - *state = 0; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Processor [%02x] is at performance state [%d%%].\n", processor->device_handle, processor->performance.state[*state].performance)); - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: pr_perf_set_state - * - * PARAMETERS: - * - * RETURN: AE_OK - * AE_BAD_PARAMETER - * AE_BAD_DATA Invalid target throttling state. - * - * DESCRIPTION: - * - ****************************************************************************/ - -/* TBD: Includes support for _real_ performance states (not just throttling). */ - -acpi_status -pr_perf_set_state ( - PR_CONTEXT *processor, - u32 state) -{ - u32 pblk_value = 0; - u32 duty_mask = 0; - u32 duty_cycle = 0; - u32 i = 0; - - FUNCTION_TRACE ("pr_perf_set_state"); - - if (!processor) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (state > (processor->performance.state_count - 1)) { - return_ACPI_STATUS(AE_BAD_DATA); - } - - if ((state == processor->performance.active_state) || - (processor->performance.state_count == 1)) { - return_ACPI_STATUS(AE_OK); - } - - /* - * Calculate Duty Cycle/Mask: - * -------------------------- - * Note that we don't support duty_cycle values that span bit 4. - */ - if (state) { - duty_cycle = processor->performance.state_count - state; - duty_cycle <<= acpi_fadt.duty_offset; - } - else { - duty_cycle = 0; - } - - duty_mask = ~((u32)(processor->performance.state_count - 1)); - for (i=0; ipblk.address, &pblk_value, 32); - if (pblk_value & 0x00000010) { - pblk_value &= 0xFFFFFFEF; - acpi_os_write_port(processor->pblk.address, pblk_value, 32); - } - - /* - * Set Duty Cycle: - * --------------- - * Mask off the old duty_cycle value, mask in the new. - */ - pblk_value &= duty_mask; - pblk_value |= duty_cycle; - acpi_os_write_port(processor->pblk.address, pblk_value, 32); - - /* - * Enable Throttling: - * ------------------ - * But only for non-zero (non-100% performance) states. - */ - if (state) { - pblk_value |= 0x00000010; - acpi_os_write_port(processor->pblk.address, pblk_value, 32); - } - - processor->performance.active_state = state; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Processor [%02x] set to performance state [%d%%].\n", processor->device_handle, processor->performance.state[state].performance)); - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: pr_perf_set_limit - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_perf_set_limit ( - PR_CONTEXT *processor, - u32 limit) -{ - acpi_status status = AE_OK; - PR_PERFORMANCE *performance = NULL; - - FUNCTION_TRACE ("pr_perf_set_limit"); - - if (!processor) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - performance = &(processor->performance); - - /* - * Set Limit: - * ---------- - * TBD: Properly manage thermal and power limits (only set - * performance state iff...). - */ - switch (limit) { - - case PR_PERF_DEC: - if (performance->active_state < - (performance->state_count-1)) { - status = pr_perf_set_state(processor, - (performance->active_state+1)); - } - break; - - case PR_PERF_INC: - if (performance->active_state > 0) { - status = pr_perf_set_state(processor, - (performance->active_state-1)); - } - break; - - case PR_PERF_MAX: - if (performance->active_state != 0) { - status = pr_perf_set_state(processor, 0); - } - break; - - default: - return_ACPI_STATUS(AE_BAD_DATA); - break; - } - - if (ACPI_SUCCESS(status)) { - performance->thermal_limit = performance->active_state; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Processor [%02x] thermal performance limit set to [%d%%].\n", processor->device_handle, processor->performance.state[performance->active_state].performance)); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: pr_perf_add_device - * - * PARAMETERS: processor Our processor-specific context. - * - * RETURN: AE_OK - * AE_BAD_PARAMETER - * - * DESCRIPTION: Calculates the number of throttling states and the state - * performance/power values. - * - ****************************************************************************/ - -/* TBD: Support duty_cycle values that span bit 4. */ - -acpi_status -pr_perf_add_device ( - PR_CONTEXT *processor) -{ - acpi_status status = AE_OK; - u32 i = 0; - u32 performance_step = 0; - u32 percentage = 0; - - FUNCTION_TRACE("pr_perf_add_device"); - - if (!processor) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Valid PBLK? - * ----------- - * For SMP it is common to have the first (boot) processor have a - * valid PBLK while all others do not -- which implies that - * throttling has system-wide effects (duty_cycle programmed into - * the chipset effects all processors). - */ - if ((processor->pblk.length < 6) || !processor->pblk.address) { - processor->performance.state_count = 1; - } - - /* - * Valid Duty Offset/Width? - * ------------------------ - * We currently only support duty_cycle values that fall within - * bits 0-3, as things get complicated when this value spans bit 4 - * (the throttling enable/disable bit). - */ - else if ((acpi_fadt.duty_offset + acpi_fadt.duty_width) > 4) { - processor->performance.state_count = 1; - } - - /* - * Compute State Count: - * -------------------- - * The number of throttling states is computed as 2^duty_width, - * but limited by PR_MAX_THROTTLE_STATES. Note that a duty_width - * of zero results is one throttling state (100%). - */ - else { - processor->performance.state_count = - POWER_OF_2[acpi_fadt.duty_width]; - } - - if (processor->performance.state_count > PR_MAX_THROTTLE_STATES) { - processor->performance.state_count = PR_MAX_THROTTLE_STATES; - } - - /* - * Compute State Values: - * --------------------- - * Note that clock throttling displays a linear power/performance - * relationship (at 50% performance the CPU will consume 50% power). - */ - performance_step = (1000 / processor->performance.state_count); - - for (i=0; iperformance.state_count; i++) { - percentage = (1000 - (performance_step * i))/10; - processor->performance.state[i].performance = percentage; - processor->performance.state[i].power = percentage; - } - - /* - * Get Current State: - * ------------------ - */ - status = pr_perf_get_state(processor, &(processor->performance.active_state)); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Set to Maximum Performance: - * --------------------------- - * We'll let subsequent policy (e.g. thermal/power) decide to lower - * performance if it so chooses, but for now crank up the speed. - */ - if (0 != processor->performance.active_state) { - status = pr_perf_set_state(processor, 0); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: pr_perf_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_perf_remove_device ( - PR_CONTEXT *processor) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("pr_perf_remove_device"); - - if (!processor) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(&(processor->performance), 0, sizeof(PR_PERFORMANCE)); - - return_ACPI_STATUS(status); -} - diff -urN linux-2.4.21/drivers/acpi/ospm/processor/prpower.c linux-2.4.22/drivers/acpi/ospm/processor/prpower.c --- linux-2.4.21/drivers/acpi/ospm/processor/prpower.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/processor/prpower.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,665 +0,0 @@ -/***************************************************************************** - * - * Module Name: prpower.c - * $Revision: 32 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - */ - - -/* TBD: Linux specific */ -#include -#include -#include - -#include -#include -#include "pr.h" - -#define _COMPONENT ACPI_PROCESSOR - MODULE_NAME ("prpower") - - -/**************************************************************************** - * Globals - ****************************************************************************/ - -extern FADT_DESCRIPTOR acpi_fadt; -static u32 last_idle_jiffies = 0; -static PR_CONTEXT *processor_list[NR_CPUS]; -static void (*pr_pm_idle_save)(void) = NULL; -static u8 bm_control = 0; - - -/* Used for PIIX4 errata handling. */ -unsigned short acpi_piix4_bmisx = 0; - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: pr_power_activate_state - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -pr_power_activate_state ( - PR_CONTEXT *processor, - u32 next_state) -{ - - PROC_NAME("pr_power_activate_state"); - - if (!processor) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return; - } - - processor->power.state[processor->power.active_state].promotion.count = 0; - processor->power.state[processor->power.active_state].demotion.count = 0; - - /* - * Cleanup from old state. - */ - switch (processor->power.active_state) { - - case PR_C3: - /* Disable bus master reload */ - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, - BM_RLD, 0); - break; - } - - /* - * Prepare to use new state. - */ - switch (next_state) { - - case PR_C3: - /* Enable bus master reload */ - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, - BM_RLD, 1); - break; - } - - processor->power.active_state = next_state; - - return; -} - - -/**************************************************************************** - * - * FUNCTION: pr_power_idle - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -void -pr_power_idle (void) -{ - PR_CX *c_state = NULL; - u32 next_state = 0; - u32 start_ticks, end_ticks, time_elapsed; - PR_CONTEXT *processor = NULL; - - PROC_NAME("pr_power_idle"); - - processor = processor_list[smp_processor_id()]; - - if (!processor || processor->power.active_state == PR_C0) { - return; - } - - next_state = processor->power.active_state; - - /* - * Check OS Idleness: - * ------------------ - * If the OS has been busy (hasn't called the idle handler in a while) - * then automatically demote to the default power state (e.g. C1). - * - * TBD: Optimize by having scheduler determine business instead - * of having us try to calculate it. - */ - if (processor->power.active_state != processor->power.default_state) { - if ((jiffies - last_idle_jiffies) >= processor->power.busy_metric) { - next_state = processor->power.default_state; - if (next_state != processor->power.active_state) { - pr_power_activate_state(processor, next_state); - } - } - } - - disable(); - - /* - * Log BM Activity: - * ---------------- - * Read BM_STS and record its value for later use by C3 policy. - * (Note that we save the BM_STS values for the last 32 cycles). - */ - if (bm_control) { - processor->power.bm_activity <<= 1; - if (acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_DO_NOT_LOCK, BM_STS)) { - processor->power.bm_activity |= 1; - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, - BM_STS, 1); - } - else if (acpi_piix4_bmisx) { - /* - * PIIX4 Errata: - * ------------- - * This code is a workaround for errata #18 "C3 Power State/ - * BMIDE and Type-F DMA Livelock" from the July '01 PIIX4 - * specification update. Note that BM_STS doesn't always - * reflect the true state of bus mastering activity; forcing - * us to manually check the BMIDEA bit of each IDE channel. - */ - if ((inb_p(acpi_piix4_bmisx + 0x02) & 0x01) || - (inb_p(acpi_piix4_bmisx + 0x0A) & 0x01)) - processor->power.bm_activity |= 1; - } - } - - c_state = &(processor->power.state[processor->power.active_state]); - - c_state->utilization++; - - /* - * Sleep: - * ------ - * Invoke the current Cx state to put the processor to sleep. - */ - switch (processor->power.active_state) { - - case PR_C1: - /* Invoke C1 */ - enable(); halt(); - /* - * TBD: Can't get time duration while in C1, as resumes - * go to an ISR rather than here. - */ - time_elapsed = 0xFFFFFFFF; - break; - - case PR_C2: - /* See how long we're asleep for */ - acpi_get_timer(&start_ticks); - /* Invoke C2 */ - acpi_os_read_port(processor->power.p_lvl2, NULL, 8); - /* Dummy op - must do something useless after P_LVL2 read */ - acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_DO_NOT_LOCK, BM_STS); - /* Compute time elapsed */ - acpi_get_timer(&end_ticks); - /* Re-enable interrupts */ - enable(); - acpi_get_timer_duration(start_ticks, end_ticks, &time_elapsed); - break; - - case PR_C3: - /* Disable bus master arbitration */ - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, ARB_DIS, 1); - /* See how long we're asleep for */ - acpi_get_timer(&start_ticks); - /* Invoke C3 */ - acpi_os_read_port(processor->power.p_lvl3, NULL, 8); - /* Dummy op - must do something useless after P_LVL3 read */ - acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_DO_NOT_LOCK, BM_STS); - /* Compute time elapsed */ - acpi_get_timer(&end_ticks); - /* Enable bus master arbitration */ - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, - ARB_DIS, 0); - /* Re-enable interrupts */ - enable(); - acpi_get_timer_duration(start_ticks, end_ticks, &time_elapsed); - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Attempt to use unsupported power state C%d.\n", processor->power.active_state)); - enable(); - break; - } - - /* - * Promotion? - * ---------- - * Track the number of successful sleeps (time asleep is greater - * than time_threshold) and promote when count_threshold is - * reached. - */ - if ((c_state->promotion.target_state) && - (time_elapsed >= c_state->promotion.time_threshold)) { - - c_state->promotion.count++; - c_state->demotion.count = 0; - - if (c_state->promotion.count >= c_state->promotion.count_threshold) { - /* - * Bus Mastering Activity, if active and used - * by this state's promotion policy, prevents - * promotions from occuring. - */ - if (!bm_control || !(processor->power.bm_activity & c_state->promotion.bm_threshold)) - next_state = c_state->promotion.target_state; - } - } - - /* - * Demotion? - * --------- - * Track the number of shorts (time asleep is less than - * time_threshold) and demote when count_threshold is reached. - */ - if (c_state->demotion.target_state) { - - if (time_elapsed < c_state->demotion.time_threshold) { - - c_state->demotion.count++; - c_state->promotion.count = 0; - - if (c_state->demotion.count >= - c_state->demotion.count_threshold) { - next_state = c_state->demotion.target_state; - } - } - - /* - * Bus Mastering Activity, if active and used by this - * state's promotion policy, causes an immediate demotion - * to occur. - */ - if (bm_control && (processor->power.bm_activity & c_state->demotion.bm_threshold)) - next_state = c_state->demotion.target_state; - } - - /* - * New Cx State? - * ------------- - * If we're going to start using a new Cx state we must clean up - * from the previous and prepare to use the new. - */ - if (next_state != processor->power.active_state) { - pr_power_activate_state(processor, next_state); - processor->power.active_state = processor->power.active_state; - } - - /* - * Track OS Idleness: - * ------------------ - * Record a jiffies timestamp to compute time elapsed between calls - * to the idle handler. - */ - last_idle_jiffies = jiffies; - - return; -} - - -/***************************************************************************** - * - * FUNCTION: pr_power_set_default_policy - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Sets the default Cx state policy (OS idle handler). Our - * scheme is to promote quickly to C2 but more conservatively - * to C3. We're favoring C2 for its characteristics of low - * latency (quick response), good power savings, and ability - * to allow bus mastering activity. - * - * Note that Cx state policy is completely customizable, with - * the goal of having heuristics to alter policy dynamically. - * - ****************************************************************************/ - -acpi_status -pr_power_set_default_policy ( - PR_CONTEXT *processor) -{ - FUNCTION_TRACE("pr_power_set_default_policy"); - - if (!processor) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Busy Metric: - * ------------ - * Used to determine when the OS has been busy and thus when - * policy should return to using the default Cx state (e.g. C1). - * On Linux we use the number of jiffies (scheduler quantums) - * that transpire between calls to the idle handler. - * - * TBD: Linux-specific. - */ - processor->power.busy_metric = 2; - - /* - * C1: - * --- - * C1 serves as our default state. It must be valid. - */ - if (processor->power.state[PR_C1].is_valid) { - processor->power.active_state = - processor->power.default_state = PR_C1; - } - else { - processor->power.active_state = - processor->power.default_state = PR_C0; - return_ACPI_STATUS(AE_OK); - } - - /* - * C2: - * --- - * Set default C1 promotion and C2 demotion policies. - */ - if (processor->power.state[PR_C2].is_valid) { - /* - * Promote from C1 to C2 anytime we're asleep in C1 for - * longer than two times the C2 latency (to amortize cost - * of transition). Demote from C2 to C1 anytime we're - * asleep in C2 for less than this time. - */ - processor->power.state[PR_C1].promotion.count_threshold = 10; - processor->power.state[PR_C1].promotion.time_threshold = - 2 * processor->power.state[PR_C2].latency; - processor->power.state[PR_C1].promotion.target_state = PR_C2; - - processor->power.state[PR_C2].demotion.count_threshold = 1; - processor->power.state[PR_C2].demotion.time_threshold = - 2 * processor->power.state[PR_C2].latency; - processor->power.state[PR_C2].demotion.target_state = PR_C1; - } - - /* - * C3: - * --- - * Set default C2 promotion and C3 demotion policies. - */ - if ((processor->power.state[PR_C2].is_valid) && - (processor->power.state[PR_C3].is_valid)) { - /* - * Promote from C2 to C3 after 4 cycles of no bus - * mastering activity (while maintaining sleep time - * criteria). Demote immediately on a short or - * whenever bus mastering activity occurs. - */ - processor->power.state[PR_C2].promotion.count_threshold = 1; - processor->power.state[PR_C2].promotion.time_threshold = - 2 * processor->power.state[PR_C3].latency; - processor->power.state[PR_C2].promotion.bm_threshold = - 0x0000000F; - processor->power.state[PR_C2].promotion.target_state = - PR_C3; - - processor->power.state[PR_C3].demotion.count_threshold = 1; - processor->power.state[PR_C3].demotion.time_threshold = - 2 * processor->power.state[PR_C3].latency; - processor->power.state[PR_C3].demotion.bm_threshold = - 0x0000000F; - processor->power.state[PR_C3].demotion.target_state = - PR_C2; - } - - return_ACPI_STATUS(AE_OK); -} - -/***************************************************************************** - * - * FUNCTION: pr_power_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -/* - * TBD: 1. PROC_C1 support. - * 2. Symmetric Cx state support (different Cx states supported - * by different CPUs results in lowest common denominator). - */ - -acpi_status -pr_power_add_device ( - PR_CONTEXT *processor) -{ - FUNCTION_TRACE("pr_power_add_device"); - - if (!processor) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * State Count: - * ------------ - * Fixed at four (C0-C3). We use is_valid to determine whether or - * not a state actually gets used. - */ - processor->power.state_count = PR_MAX_POWER_STATES; - - /* - * C0: - * --- - * C0 exists only as filler in our array. (Let's assume its valid!) - */ - processor->power.state[PR_C0].is_valid = TRUE; - - /* - * C1: - * --- - * ACPI states that C1 must be supported by all processors - * with a latency so small that it can be ignored. - * - * TBD: What about PROC_C1 support? - */ - processor->power.state[PR_C1].is_valid = TRUE; - - /* - * C2: - * --- - * We're only supporting C2 on UP systems with latencies <= 100us. - * - * TBD: Support for C2 on MP (P_LVL2_UP) -- I'm taking the - * conservative approach for now. - */ - processor->power.state[PR_C2].latency = acpi_fadt.plvl2_lat; - -#ifdef CONFIG_SMP - if (smp_num_cpus == 1) { -#endif /*CONFIG_SMP*/ - if (acpi_fadt.plvl2_lat <= PR_MAX_C2_LATENCY) { - processor->power.state[PR_C2].is_valid = TRUE; - processor->power.p_lvl2 = processor->pblk.address + 4; - } -#ifdef CONFIG_SMP - } -#endif /*CONFIG_SMP*/ - - - /* - * C3: - * --- - * We're only supporting C3 on UP systems with latencies <= 1000us, - * and that include the ability to disable bus mastering while in - * C3 (ARB_DIS) but allows bus mastering requests to wake the system - * from C3 (BM_RLD). Note his method of maintaining cache coherency - * (disabling of bus mastering) cannot be used on SMP systems, and - * flushing caches (e.g. WBINVD) is simply too costly at this time. - * - * TBD: Support for C3 on MP -- I'm taking the conservative - * approach for now. - */ - processor->power.state[PR_C3].latency = acpi_fadt.plvl3_lat; - -#ifdef CONFIG_SMP - if (smp_num_cpus == 1) { -#endif /*CONFIG_SMP*/ - if ((acpi_fadt.plvl3_lat <= PR_MAX_C3_LATENCY) && bm_control) { - processor->power.state[PR_C3].is_valid = TRUE; - processor->power.p_lvl3 = processor->pblk.address + 5; - } -#ifdef CONFIG_SMP - } -#endif /*CONFIG_SMP*/ - - /* - * Set Default Policy: - * ------------------- - * Now that we know which state are supported, set the default - * policy. Note that this policy can be changed dynamically - * (e.g. encourage deeper sleeps to conserve battery life when - * not on AC). - */ - pr_power_set_default_policy(processor); - - /* - * Save Processor Context: - * ----------------------- - * TBD: Enhance Linux idle handler to take processor context - * parameter. - */ - processor_list[processor->uid] = processor; - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: pr_power_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_power_remove_device ( - PR_CONTEXT *processor) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("pr_power_remove_device"); - - if (!processor) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - MEMSET(&(processor->power), 0, sizeof(PR_POWER)); - - processor_list[processor->uid] = NULL; - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: pr_power_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_power_initialize (void) -{ - u32 i = 0; - - FUNCTION_TRACE("pr_power_initialize"); - - /* TBD: Linux-specific. */ - for (i=0; i - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -pr_power_terminate (void) -{ - FUNCTION_TRACE("pr_power_terminate"); - - /* - * Remove idle handler. - * - * TBD: Linux-specific (need OSL function). - */ - pm_idle = pr_pm_idle_save; - - return_ACPI_STATUS(AE_OK); -} diff -urN linux-2.4.21/drivers/acpi/ospm/system/Makefile linux-2.4.22/drivers/acpi/ospm/system/Makefile --- linux-2.4.21/drivers/acpi/ospm/system/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/system/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/system/sm.c linux-2.4.22/drivers/acpi/ospm/system/sm.c --- linux-2.4.21/drivers/acpi/ospm/system/sm.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/system/sm.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,373 +0,0 @@ -/***************************************************************************** - * - * Module Name: sm.c - * $Revision: 20 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "sm.h" - - -#define _COMPONENT ACPI_SYSTEM - MODULE_NAME ("sm") - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: sm_print - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Prints out information on a specific system. - * - ****************************************************************************/ - -void -sm_print ( - SM_CONTEXT *system) -{ -#ifdef ACPI_DEBUG - acpi_buffer buffer; - - PROC_NAME("sm_print"); - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) { - return; - } - - /* - * Get the full pathname for this ACPI object. - */ - acpi_get_name(system->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - /* - * Print out basic system information. - */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| System[%02x]:[%p] %s\n", system->device_handle, system->acpi_handle, (char*)buffer.pointer)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| states: %cS0 %cS1 %cS2 %cS3 %cS4 %cS5\n", (system->states[0]?'+':'-'), (system->states[1]?'+':'-'), (system->states[2]?'+':'-'), (system->states[3]?'+':'-'), (system->states[4]?'+':'-'), (system->states[5]?'+':'-'))); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); -#endif /*ACPI_DEBUG*/ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: sm_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -sm_add_device( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - BM_DEVICE *device = NULL; - SM_CONTEXT *system = NULL; - u8 i, type_a, type_b; - - - FUNCTION_TRACE("sm_add_device"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding system device [%02x].\n", device_handle)); - - if (!context || *context) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Allocate a new SM_CONTEXT structure. - */ - system = acpi_os_callocate(sizeof(SM_CONTEXT)); - if (!system) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* - * Get information on this device. - */ - status = bm_get_device_info(device_handle, &device); - if (ACPI_FAILURE(status)) { - goto end; - } - - system->device_handle = device->handle; - system->acpi_handle = device->acpi_handle; - - /* - * Sx States: - * ---------- - * Figure out which Sx states are supported. - */ - for (i=0; istates[i] = TRUE; - } - } - - status = sm_osl_add_device(system); - if (ACPI_FAILURE(status)) { - goto end; - } - - *context = system; - - sm_print(system); - -end: - if (ACPI_FAILURE(status)) { - acpi_os_free(system); - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: sm_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -sm_remove_device ( - void **context) -{ - acpi_status status = AE_OK; - SM_CONTEXT *system = NULL; - - FUNCTION_TRACE("sm_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - system = (SM_CONTEXT*)*context; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing system device [%02x].\n", system->device_handle)); - - status = sm_osl_remove_device(system); - - acpi_os_free(system); - - *context = NULL; - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: sm_initialize - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -sm_initialize (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("sm_initialize"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Register driver for the System device. - */ - criteria.type = BM_TYPE_SYSTEM; - - driver.notify = &sm_notify; - driver.request = &sm_request; - - status = bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: sm_terminate - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -sm_terminate (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("sm_terminate"); - - MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID)); - MEMSET(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Unregister driver for System devices. - */ - criteria.type = BM_TYPE_SYSTEM; - - driver.notify = &sm_notify; - driver.request = &sm_request; - - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/***************************************************************************** - * - * FUNCTION: sm_notify - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ -acpi_status -sm_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("sm_notify"); - - if (!context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - switch (notify_type) { - - case BM_NOTIFY_DEVICE_ADDED: - status = sm_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = sm_remove_device(context); - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: sm_request - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -sm_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("sm_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Handle Request: - * --------------- - */ - switch (request->command) { - - default: - status = AE_SUPPORT; - break; - } - - request->status = status; - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/system/sm_osl.c linux-2.4.22/drivers/acpi/ospm/system/sm_osl.c --- linux-2.4.21/drivers/acpi/ospm/system/sm_osl.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/system/sm_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,922 +0,0 @@ -/****************************************************************************** - * - * Module Name: sm_osl.c - * $Revision: 16 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "sm.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - ACPI System Driver"); -MODULE_LICENSE("GPL"); - - -#define SM_PROC_INFO "info" -#define SM_PROC_DSDT "dsdt" - -extern struct proc_dir_entry *bm_proc_root; -struct proc_dir_entry *sm_proc_root = NULL; -static void (*sm_pm_power_off)(void) = NULL; - -static ssize_t sm_osl_read_dsdt(struct file *, char *, size_t, loff_t *); - -static struct file_operations proc_dsdt_operations = { - read: sm_osl_read_dsdt, -}; - -static acpi_status sm_osl_suspend(u32 state); - -struct proc_dir_entry *bm_proc_sleep; -struct proc_dir_entry *bm_proc_alarm; -struct proc_dir_entry *bm_proc_gpe; - -static int -sm_osl_proc_read_sleep ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - SM_CONTEXT *system = (SM_CONTEXT*) context; - char *str = page; - int len; - int i; - - if (!system) - goto end; - - if (off != 0) - goto end; - - for (i = 0; i <= ACPI_S5; i++) { - if (system->states[i]) - str += sprintf(str,"S%d ", i); - } - - str += sprintf(str, "\n"); - -end: - - len = (str - page); - if (len < (off + count)) - *eof = 1; - - *start = page + off; - len -= off; - - if (len > count) - len = count; - - if (len < 0) - len = 0; - - return (len); -} - -int sm_osl_proc_write_sleep (struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - SM_CONTEXT *system = (SM_CONTEXT*) data; - char str[10]; - char *strend; - unsigned long value; - - if (count > (sizeof(str) - 1)) - return -EINVAL; - - if (copy_from_user(str,buffer,count)) - return -EFAULT; - - str[count] = '\0'; - - value = simple_strtoul(str,&strend,0); - if (str == strend) - return -EINVAL; - - if (value == 0 || value >= ACPI_S5) - return -EINVAL; - - /* - * make sure that the sleep state is supported - */ - if (system->states[value] != TRUE) - return -EINVAL; - - sm_osl_suspend(value); - - return (count); -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_proc_read_info - * - ****************************************************************************/ - -static int -sm_osl_proc_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - acpi_status status = AE_OK; - SM_CONTEXT *system = NULL; - char *p = page; - int len; - acpi_system_info system_info; - acpi_buffer buffer; - u32 i = 0; - - if (!context) { - goto end; - } - - system = (SM_CONTEXT*) context; - - /* don't get status more than once for a single proc read */ - if (off != 0) { - goto end; - } - - /* - * Get ACPI CA Information. - */ - buffer.length = sizeof(system_info); - buffer.pointer = &system_info; - - status = acpi_get_system_info(&buffer); - if (ACPI_FAILURE(status)) { - p += sprintf(p, "ACPI-CA Version: unknown\n"); - } - else { - p += sprintf(p, "ACPI-CA Version: %x\n", - system_info.acpi_ca_version); - } - - p += sprintf(p, "Sx States Supported: "); - for (i=0; istates[i]) { - p += sprintf(p, "S%d ", i); - } - } - p += sprintf(p, "\n"); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return(len); -} - -/**************************************************************************** - * - * FUNCTION: sm_osl_read_dsdt - * - ****************************************************************************/ - -static ssize_t -sm_osl_read_dsdt( - struct file *file, - char *buf, - size_t count, - loff_t *ppos) -{ - acpi_buffer acpi_buf; - void *data; - size_t size = 0; - - acpi_buf.length = 0; - acpi_buf.pointer = NULL; - - - /* determine what buffer size we will need */ - if (acpi_get_table(ACPI_TABLE_DSDT, 1, &acpi_buf) != AE_BUFFER_OVERFLOW) { - return 0; - } - - acpi_buf.pointer = kmalloc(acpi_buf.length, GFP_KERNEL); - if (!acpi_buf.pointer) { - return -ENOMEM; - } - - /* get the table for real */ - if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_DSDT, 1, &acpi_buf))) { - kfree(acpi_buf.pointer); - return 0; - } - - if (*ppos < acpi_buf.length) { - data = acpi_buf.pointer + file->f_pos; - size = acpi_buf.length - file->f_pos; - if (size > count) - size = count; - if (copy_to_user(buf, data, size)) { - kfree(acpi_buf.pointer); - return -EFAULT; - } - } - - kfree(acpi_buf.pointer); - - *ppos += size; - - return size; -} - -static int -sm_osl_proc_read_alarm ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - char *str = page; - int len; - u32 sec,min,hr; - u32 day,mo,yr; - - if (off != 0) goto out; - - spin_lock(&rtc_lock); - sec = CMOS_READ(RTC_SECONDS_ALARM); - min = CMOS_READ(RTC_MINUTES_ALARM); - hr = CMOS_READ(RTC_HOURS_ALARM); - -#if 0 - /* if I ever get an FACP with proper values, maybe I'll enable this code */ - if (acpi_gbl_FADT->day_alrm) - day = CMOS_READ(acpi_gbl_FADT->day_alrm); - else - day = CMOS_READ(RTC_DAY_OF_MONTH); - if (acpi_gbl_FADT->mon_alrm) - mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); - else - mo = CMOS_READ(RTC_MONTH);; - if (acpi_gbl_FADT->century) - yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR); - else - yr = CMOS_READ(RTC_YEAR); -#else - day = CMOS_READ(RTC_DAY_OF_MONTH); - mo = CMOS_READ(RTC_MONTH); - yr = CMOS_READ(RTC_YEAR); -#endif - spin_unlock(&rtc_lock); - - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hr); - BCD_TO_BIN(day); - BCD_TO_BIN(mo); - BCD_TO_BIN(yr); - - str += sprintf(str,"%4.4u-",yr); - - str += (mo > 12) ? - sprintf(str,"**-") : - sprintf(str,"%2.2u-",mo); - - str += (day > 31) ? - sprintf(str,"** ") : - sprintf(str,"%2.2u ",day); - - str += (hr > 23) ? - sprintf(str,"**:") : - sprintf(str,"%2.2u:",hr); - - str += (min > 59) ? - sprintf(str,"**:") : - sprintf(str,"%2.2u:",min); - - str += (sec > 59) ? - sprintf(str,"**\n") : - sprintf(str,"%2.2u\n",sec); - - out: - len = str - page; - - if (len < count) *eof = 1; - else if (len > count) len = count; - - if (len < 0) len = 0; - - *start = page; - - return len; -} - -static int get_date_field(char **str, u32 *value) -{ - char *next,*strend; - int error = -EINVAL; - - /* try to find delimeter, only to insert null; - * the end of string won't have one, but is still valid - */ - next = strpbrk(*str,"- :"); - if (next) *next++ = '\0'; - - *value = simple_strtoul(*str,&strend,10); - - /* signal success if we got a good digit */ - if (strend != *str) error = 0; - - if (next) *str = next; - return error; -} - - - -int sm_osl_proc_write_alarm ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - char buf[30]; - char *str = buf; - u32 sec,min,hr; - u32 day,mo,yr; - int adjust = 0; - unsigned char rtc_control; - int error = -EINVAL; - - if (count > sizeof(buf) - 1) return -EINVAL; - - if (copy_from_user(str,buffer,count)) return -EFAULT; - - str[count] = '\0'; - /* check for time adjustment */ - if (str[0] == '+') { - str++; - adjust = 1; - } - - if ((error = get_date_field(&str,&yr))) goto out; - if ((error = get_date_field(&str,&mo))) goto out; - if ((error = get_date_field(&str,&day))) goto out; - if ((error = get_date_field(&str,&hr))) goto out; - if ((error = get_date_field(&str,&min))) goto out; - if ((error = get_date_field(&str,&sec))) goto out; - - - if (sec > 59) { - min += 1; - sec -= 60; - } - if (min > 59) { - hr += 1; - min -= 60; - } - if (hr > 23) { - day += 1; - hr -= 24; - } - if (day > 31) { - mo += 1; - day -= 31; - } - if (mo > 12) { - yr += 1; - mo -= 12; - } - - spin_lock_irq(&rtc_lock); - rtc_control = CMOS_READ(RTC_CONTROL); - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } - - if (adjust) { - yr += CMOS_READ(RTC_YEAR); - mo += CMOS_READ(RTC_MONTH); - day += CMOS_READ(RTC_DAY_OF_MONTH); - hr += CMOS_READ(RTC_HOURS); - min += CMOS_READ(RTC_MINUTES); - sec += CMOS_READ(RTC_SECONDS); - } - spin_unlock_irq(&rtc_lock); - - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(yr); - BCD_TO_BIN(mo); - BCD_TO_BIN(day); - BCD_TO_BIN(hr); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); - } - - if (sec > 59) { - min++; - sec -= 60; - } - if (min > 59) { - hr++; - min -= 60; - } - if (hr > 23) { - day++; - hr -= 24; - } - if (day > 31) { - mo++; - day -= 31; - } - if (mo > 12) { - yr++; - mo -= 12; - } - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } - - spin_lock_irq(&rtc_lock); - /* write the fields the rtc knows about */ - CMOS_WRITE(hr,RTC_HOURS_ALARM); - CMOS_WRITE(min,RTC_MINUTES_ALARM); - CMOS_WRITE(sec,RTC_SECONDS_ALARM); - - /* If the system supports an enhanced alarm, it will have non-zero - * offsets into the CMOS RAM here. - * Which for some reason are pointing to the RTC area of memory. - */ -#if 0 - if (acpi_gbl_FADT->day_alrm) CMOS_WRITE(day,acpi_gbl_FADT->day_alrm); - if (acpi_gbl_FADT->mon_alrm) CMOS_WRITE(mo,acpi_gbl_FADT->mon_alrm); - if (acpi_gbl_FADT->century) CMOS_WRITE(yr / 100,acpi_gbl_FADT->century); -#endif - /* enable the rtc alarm interrupt */ - if (!(rtc_control & RTC_AIE)) { - rtc_control |= RTC_AIE; - CMOS_WRITE(rtc_control,RTC_CONTROL); - CMOS_READ(RTC_INTR_FLAGS); - } - - /* unlock the lock on the rtc now that we're done with it */ - spin_unlock_irq(&rtc_lock); - - acpi_hw_register_bit_access(ACPI_WRITE,ACPI_MTX_LOCK, RTC_EN, 1); - - file->f_pos += count; - - error = 0; - out: - return error ? error : count; -} - -static int -sm_osl_proc_read_gpe( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - char *str = page; - int size; - int length; - int i; - u32 addr,data; - - if (off) goto out; - - if (acpi_gbl_FADT->V1_gpe0blk) { - length = acpi_gbl_FADT->gpe0blk_len / 2; - - str += sprintf(str,"GPE0: "); - - for (i = length; i > 0; i--) { - addr = GPE0_EN_BLOCK | (i - 1); - data = acpi_hw_register_read(ACPI_MTX_LOCK,addr); - str += sprintf(str,"%2.2x ",data); - } - str += sprintf(str,"\n"); - - str += sprintf(str,"Status: "); - for (i = length; i > 0; i--) { - addr = GPE0_STS_BLOCK | (i - 1); - data = acpi_hw_register_read(ACPI_MTX_LOCK,addr); - str += sprintf(str,"%2.2x ",data); - } - str += sprintf(str,"\n"); - } - - if (acpi_gbl_FADT->V1_gpe1_blk) { - length = acpi_gbl_FADT->gpe1_blk_len / 2; - - - str += sprintf(str,"GPE1: "); - for (i = length; i > 0; i--) { - addr = GPE1_EN_BLOCK | (i - 1); - data = acpi_hw_register_read(ACPI_MTX_LOCK,addr); - str += sprintf(str,"%2.2x",data); - } - str += sprintf(str,"\n"); - - str += sprintf(str,"Status: "); - for (i = length; i > 0; i--) { - addr = GPE1_STS_BLOCK | (i - 1); - data = acpi_hw_register_read(ACPI_MTX_LOCK,addr); - str += sprintf(str,"%2.2x",data); - } - str += sprintf(str,"\n"); - } - out: - size = str - page; - if (size < count) *eof = 1; - else if (size > count) size = count; - - if (size < 0) size = 0; - *start = page; - - return size; -} - -static int -sm_osl_proc_write_gpe ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - char buf[256]; - char *str = buf; - char *next; - int error = -EINVAL; - u32 addr,value = 0; - - if (count > sizeof(buf) + 1) return -EINVAL; - - if (copy_from_user(str,buffer,count)) return -EFAULT; - - str[count] = '\0'; - - /* set addr to which block to refer to */ - if (!strncmp(str,"GPE0 ",5)) addr = GPE0_EN_BLOCK; - else if (!strncmp(str,"GPE1 ",5)) addr = GPE1_EN_BLOCK; - else goto out; - - str += 5; - - /* set low order bits to index of bit to set */ - addr |= simple_strtoul(str,&next,0); - if (next == str) goto out; - - if (next) { - str = ++next; - value = simple_strtoul(str,&next,0); - if (next == str) value = 1; - } - - value = acpi_hw_register_bit_access(ACPI_WRITE,ACPI_MTX_LOCK,addr,(value ? 1 : 0)); - - error = 0; - out: - return error ? error : count; -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_suspend - * - * PARAMETERS: %state: Sleep state to enter. Assumed that caller has filtered - * out bogus values, so it's one of S1, S2, S3 or S4 - * - * RETURN: ACPI_STATUS, whether or not we successfully entered and - * exited sleep. - * - * DESCRIPTION: - * This function is the meat of the sleep routine, as far as the ACPI-CA is - * concerned. - * - * See Chapter 9 of the ACPI 2.0 spec for details concerning the methodology here. - * - * It will do the following things: - * - Call arch-specific routines to save the processor and kernel state - * - Call acpi_enter_sleep_state to actually go to sleep - * .... - * When we wake back up, we will: - * - Restore the processor and kernel state - * - Return to the user - * - * By having this routine in here, it hides it from every part of the CA, - * so it can remain OS-independent. The only function that calls this is - * sm_proc_write_sleep, which gets the sleep state to enter from the user. - * - ****************************************************************************/ -static acpi_status -sm_osl_suspend(u32 state) -{ - acpi_status status = AE_ERROR; - unsigned long wakeup_address; - - /* get out if state is invalid */ - if (state < ACPI_S1 || state > ACPI_S5) - goto acpi_sleep_done; - - /* make sure we don't get any suprises */ - disable(); - - /* TODO: save device state and suspend them */ - - /* save the processor state to memory if going into S2 or S3; - * save it to disk if going into S4. - * Also, set the FWV if going into an STR state - */ - if (state == ACPI_S2 || state == ACPI_S3) { -#ifdef DONT_USE_UNTIL_LOWLEVEL_CODE_EXISTS - /* That && trick is *not going to work*. Read gcc - specs. That explicitely says: jumping from other - function is *not allowed*. */ - wakeup_address = acpi_save_state_mem((unsigned long)&&acpi_sleep_done); - - if (!wakeup_address) goto acpi_sleep_done; - - acpi_set_firmware_waking_vector( - (ACPI_PHYSICAL_ADDRESS)wakeup_address); -#endif - } else if (state == ACPI_S4) -#ifdef DONT_USE_UNTIL_LOWLEVEL_CODE_EXISTS - if (acpi_save_state_disk((unsigned long)&&acpi_sleep_done)) - goto acpi_sleep_done; -#endif - - /* set status, since acpi_enter_sleep_state won't return unless something - * goes wrong, or it's just S1. - */ - status = AE_OK; - - mdelay(10); - status = acpi_enter_sleep_state(state); - - acpi_sleep_done: - - /* pause for a bit to allow devices to come back on */ - mdelay(10); - - /* make sure that the firmware waking vector is reset */ - acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS)0); - - acpi_leave_sleep_state(state); - - /* TODO: resume devices and restore their state */ - - enable(); - return status; -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_power_down - * - ****************************************************************************/ - -void -sm_osl_power_down (void) -{ - /* Power down the system (S5 = soft off). */ - sm_osl_suspend(ACPI_S5); -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_add_device - * - ****************************************************************************/ - -acpi_status -sm_osl_add_device( - SM_CONTEXT *system) -{ - u32 i = 0; - struct proc_dir_entry *bm_proc_dsdt; - - if (!system) { - return(AE_BAD_PARAMETER); - } - - printk("ACPI: System firmware supports"); - for (i=0; istates[i]) { - printk(" S%d", i); - } - } - printk("\n"); - - if (system->states[ACPI_STATE_S5]) { - sm_pm_power_off = pm_power_off; - pm_power_off = sm_osl_power_down; - } - - create_proc_read_entry(SM_PROC_INFO, S_IRUGO, - sm_proc_root, sm_osl_proc_read_info, (void*)system); - - bm_proc_sleep = create_proc_read_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR, - sm_proc_root, sm_osl_proc_read_sleep, (void*)system); - if (bm_proc_sleep) - bm_proc_sleep->write_proc = sm_osl_proc_write_sleep; - - bm_proc_alarm = create_proc_read_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR, - sm_proc_root,sm_osl_proc_read_alarm, NULL); - if (bm_proc_alarm) - bm_proc_alarm->write_proc = sm_osl_proc_write_alarm; - - bm_proc_gpe = create_proc_read_entry("gpe", S_IFREG | S_IRUGO | S_IWUSR, - sm_proc_root,sm_osl_proc_read_gpe,NULL); - if (bm_proc_gpe) - bm_proc_gpe->write_proc = sm_osl_proc_write_gpe; - - /* - * Get a wakeup address for use when we come back from sleep. - * At least on IA-32, this needs to be in low memory. - * When sleep is supported on other arch's, then we may want - * to move this out to another place, but GFP_LOW should suffice - * for now. - */ -#if 0 - if (system->states[ACPI_S3] || system->states[ACPI_S4]) { - acpi_wakeup_address = (unsigned long)virt_to_phys(get_free_page(GFP_LOWMEM)); - printk(KERN_INFO "ACPI: Have wakeup address 0x%8.8x\n",acpi_wakeup_address); - } -#endif - - /* - * This returns more than a page, so we need to use our own file ops, - * not proc's generic ones - */ - bm_proc_dsdt = create_proc_entry(SM_PROC_DSDT, S_IRUSR, sm_proc_root); - if (bm_proc_dsdt) { - bm_proc_dsdt->proc_fops = &proc_dsdt_operations; - } - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_remove_device - * - ****************************************************************************/ - -acpi_status -sm_osl_remove_device ( - SM_CONTEXT *system) -{ - if (!system) { - return(AE_BAD_PARAMETER); - } - - remove_proc_entry(SM_PROC_INFO, sm_proc_root); - remove_proc_entry(SM_PROC_DSDT, sm_proc_root); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_generate_event - * - ****************************************************************************/ - -acpi_status -sm_osl_generate_event ( - u32 event, - SM_CONTEXT *system) -{ - acpi_status status = AE_OK; - - if (!system) { - return(AE_BAD_PARAMETER); - } - - switch (event) { - - default: - return(AE_BAD_PARAMETER); - break; - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_init - * - * PARAMETERS: - * - * RETURN: 0: Success - * - * DESCRIPTION: Module initialization. - * - ****************************************************************************/ - -static int __init -sm_osl_init (void) -{ - acpi_status status = AE_OK; - - /* abort if no busmgr */ - if (!bm_proc_root) - return -ENODEV; - - sm_proc_root = bm_proc_root; - if (!sm_proc_root) { - status = AE_ERROR; - } - else { - status = sm_initialize(); - } - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - - -/**************************************************************************** - * - * FUNCTION: sm_osl_cleanup - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Module cleanup. - * - ****************************************************************************/ - -static void __exit -sm_osl_cleanup (void) -{ - sm_terminate(); - - return; -} - - -module_init(sm_osl_init); -module_exit(sm_osl_cleanup); diff -urN linux-2.4.21/drivers/acpi/ospm/thermal/Makefile linux-2.4.22/drivers/acpi/ospm/thermal/Makefile --- linux-2.4.21/drivers/acpi/ospm/thermal/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/thermal/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -O_TARGET := ospm_$(notdir $(CURDIR)).o -obj-m := $(O_TARGET) -EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := $(patsubst %.c,%.o,$(wildcard *.c)) - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/acpi/ospm/thermal/tz.c linux-2.4.22/drivers/acpi/ospm/thermal/tz.c --- linux-2.4.21/drivers/acpi/ospm/thermal/tz.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/ospm/thermal/tz.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,642 +0,0 @@ -/***************************************************************************** - * - * Module Name: tz.c - * $Revision: 44 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "tz.h" - - -#define _COMPONENT ACPI_THERMAL - MODULE_NAME ("tz") - - -/**************************************************************************** - * Globals - ****************************************************************************/ - -extern int TZP; - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: tz_print - * - ****************************************************************************/ - -void -tz_print ( - TZ_CONTEXT *tz) -{ -#ifdef ACPI_DEBUG - acpi_buffer buffer; - u32 i,j = 0; - TZ_THRESHOLDS *thresholds = NULL; - - FUNCTION_TRACE("tz_print"); - - if (!tz) - return; - - thresholds = &(tz->policy.thresholds); - - buffer.length = 256; - buffer.pointer = acpi_os_callocate(buffer.length); - if (!buffer.pointer) - return; - - /* - * Get the full pathname for this ACPI object. - */ - acpi_get_name(tz->acpi_handle, ACPI_FULL_PATHNAME, &buffer); - - /* - * Print out basic thermal zone information. - */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Thermal_zone[%02x]:[%p] %s\n", tz->device_handle, tz->acpi_handle, (char*)buffer.pointer)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| temperature[%d] state[%08x]\n", tz->policy.temperature, tz->policy.state)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| cooling_mode[%08x] polling_freq[%d]\n", tz->policy.cooling_mode, tz->policy.polling_freq)); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| critical[%d]\n", thresholds->critical.temperature)); - if (thresholds->hot.is_valid) - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| hot[%d]\n", thresholds->hot.temperature)); - if (thresholds->passive.is_valid) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| passive[%d]: tc1[%d] tc2[%d] tsp[%d]\n", thresholds->passive.temperature, thresholds->passive.tc1, thresholds->passive.tc2, thresholds->passive.tsp)); - if (thresholds->passive.devices.count > 0) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| devices")); - for (j=0; (jpassive.devices.count && j<10); j++) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "[%02x]", thresholds->passive.devices.handles[j])); - } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); - } - } - for (i=0; iactive[i].is_valid) - break; - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| active[%d]: index[%d]\n", thresholds->active[i].temperature, i)); - if (thresholds->active[i].devices.count > 0) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| devices")); - for (j=0; (jactive[i].devices.count && j<10); j++) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "[%02x]", thresholds->active[i].devices.handles[j])); - } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); - } - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); - - acpi_os_free(buffer.pointer); -#endif /*ACPI_DEBUG*/ - - return; -} - - -/**************************************************************************** - * - * FUNCTION: tz_get_temperaturee - * - ****************************************************************************/ - -acpi_status -tz_get_temperature ( - TZ_CONTEXT *tz) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("tz_get_temperature"); - - if (!tz) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Evaluate the _TMP method to get the current temperature. - */ - status = bm_evaluate_simple_integer(tz->acpi_handle, "_TMP", &(tz->policy.temperature)); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %d d_k\n", tz->policy.temperature)); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: tz_set_cooling_preference - * - ****************************************************************************/ - -acpi_status -tz_set_cooling_preference ( - TZ_CONTEXT *tz, - TZ_COOLING_MODE cooling_mode) -{ - acpi_status status = AE_OK; - acpi_object_list arg_list; - acpi_object arg0; - - FUNCTION_TRACE("tz_set_cooling_preference"); - - if (!tz || ((cooling_mode != TZ_COOLING_MODE_ACTIVE) && (cooling_mode != TZ_COOLING_MODE_PASSIVE))) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Build the argument list, which simply consists of the current - * cooling preference. - */ - memset(&arg_list, 0, sizeof(acpi_object)); - arg_list.count = 1; - arg_list.pointer = &arg0; - - memset(&arg0, 0, sizeof(acpi_object)); - arg0.type = ACPI_TYPE_INTEGER; - arg0.integer.value = cooling_mode; - - /* - * Evaluate "_SCP" - setting the new cooling preference. - */ - status = acpi_evaluate_object(tz->acpi_handle, "_SCP", &arg_list, NULL); - if (ACPI_FAILURE(status)) { - tz->policy.cooling_mode = -1; - return_ACPI_STATUS(status); - } - - tz->policy.cooling_mode = cooling_mode; - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: tz_get_thresholds - * - ****************************************************************************/ - -acpi_status -tz_get_thresholds ( - TZ_CONTEXT *tz) -{ - acpi_status status = AE_OK; - TZ_THRESHOLDS *thresholds = NULL; - u32 value = 0; - u32 i = 0; - - FUNCTION_TRACE("acpi_tz_get_thresholds"); - - if (!tz) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - thresholds = &(tz->policy.thresholds); - - /* Critical Shutdown (required) */ - - status = bm_evaluate_simple_integer(tz->acpi_handle, "_CRT", &value); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n")); - return_ACPI_STATUS(status); - } - else { - thresholds->critical.temperature = value; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found critical threshold [%d]\n", thresholds->critical.temperature)); - - } - - /* Critical Sleep (optional) */ - - status = bm_evaluate_simple_integer(tz->acpi_handle, "_HOT", &value); - if (ACPI_FAILURE(status)) { - thresholds->hot.is_valid = 0; - thresholds->hot.temperature = 0; - } - else { - thresholds->hot.is_valid = 1; - thresholds->hot.temperature = value; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%d]\n", thresholds->hot.temperature)); - } - - /* Passive: Processors (optional) */ - - status = bm_evaluate_simple_integer(tz->acpi_handle, "_PSV", &value); - if (ACPI_FAILURE(status)) { - thresholds->passive.is_valid = 0; - thresholds->passive.temperature = 0; - } - else { - thresholds->passive.is_valid = 1; - thresholds->passive.temperature = value; - - status = bm_evaluate_simple_integer(tz->acpi_handle, "_TC1", &value); - if (ACPI_FAILURE(status)) { - thresholds->passive.is_valid = 0; - } - thresholds->passive.tc1 = value; - - status = bm_evaluate_simple_integer(tz->acpi_handle, "_TC2", &value); - if (ACPI_FAILURE(status)) { - thresholds->passive.is_valid = 0; - } - thresholds->passive.tc2 = value; - - status = bm_evaluate_simple_integer(tz->acpi_handle, "_TSP", &value); - if (ACPI_FAILURE(status)) { - thresholds->passive.is_valid = 0; - } - thresholds->passive.tsp = value; - - status = bm_evaluate_reference_list(tz->acpi_handle, "_PSL", &(thresholds->passive.devices)); - if (ACPI_FAILURE(status)) { - thresholds->passive.is_valid = 0; - } - - if (thresholds->passive.is_valid) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found passive threshold [%d]\n", thresholds->passive.temperature)); - } - else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid passive threshold\n")); - } - } - - /* Active: Fans, etc. (optional) */ - - for (i=0; iacpi_handle, name, &value); - if (ACPI_FAILURE(status)) { - thresholds->active[i].is_valid = 0; - thresholds->active[i].temperature = 0; - break; - } - - thresholds->active[i].temperature = value; - name[2] = 'L'; - - status = bm_evaluate_reference_list(tz->acpi_handle, name, &(thresholds->active[i].devices)); - if (ACPI_SUCCESS(status)) { - thresholds->active[i].is_valid = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found active threshold [%d]:[%d]\n", i, thresholds->active[i].temperature)); - } - else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid active threshold [%d]\n", i)); - } - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: tz_add_device - * - ****************************************************************************/ - -acpi_status -tz_add_device ( - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - TZ_CONTEXT *tz = NULL; - BM_DEVICE *device = NULL; - acpi_handle tmp_handle = NULL; - static u32 zone_count = 0; - - FUNCTION_TRACE("tz_add_device"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding thermal zone [%02x].\n", device_handle)); - - if (!context || *context) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Invalid context for device [%02x].\n", device_handle)); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* - * Get information on this device. - */ - status = bm_get_device_info(device_handle, &device); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Allocate a new Thermal Zone device. - */ - tz = acpi_os_callocate(sizeof(TZ_CONTEXT)); - if (!tz) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - tz->device_handle = device->handle; - tz->acpi_handle = device->acpi_handle; - - /* TBD: How to manage 'uid' when zones are Pn_p? */ - sprintf(tz->uid, "%d", zone_count++); - - /* - * Temperature: - * ------------ - * Make sure we can read the zone's current temperature (_TMP). - * If we can't, there's no use in doing any policy (abort). - */ - status = tz_get_temperature(tz); - if (ACPI_FAILURE(status)) - goto end; - - /* - * Polling Frequency: - * ------------------ - * If _TZP doesn't exist use the OS default polling frequency. - */ - status = bm_evaluate_simple_integer(tz->acpi_handle, "_TZP", &(tz->policy.polling_freq)); - if (ACPI_FAILURE(status)) { - tz->policy.polling_freq = TZP; - } - status = AE_OK; - - /* - * Cooling Preference: - * ------------------- - * Default to ACTIVE (noisy) cooling until policy decides otherwise. - * Note that _SCP is optional. - */ - tz_set_cooling_preference(tz, TZ_COOLING_MODE_ACTIVE); - - /* - * Start Policy: - * ------------- - * Thermal policy is included in the kernel (this driver) because - * of the critical role it plays in avoiding nuclear meltdown. =O - */ - status = tz_policy_add_device(tz); - if (ACPI_FAILURE(status)) - goto end; - - status = tz_osl_add_device(tz); - if (ACPI_FAILURE(status)) - goto end; - - *context = tz; - - tz_print(tz); - -end: - if (ACPI_FAILURE(status)) - acpi_os_free(tz); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: tz_remove_device - * - ****************************************************************************/ - -acpi_status -tz_remove_device ( - void **context) -{ - acpi_status status = AE_OK; - TZ_CONTEXT *tz = NULL; - - FUNCTION_TRACE("tz_remove_device"); - - if (!context || !*context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - tz = (TZ_CONTEXT*)(*context); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing thermal zone [%02x].\n", tz->device_handle)); - - status = tz_osl_remove_device(tz); - - /* - * Remove Policy: - * -------------- - * TBD: Move all thermal zone policy to user-mode daemon... - */ - status = tz_policy_remove_device(tz); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - acpi_os_free(tz); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * External Functions - ****************************************************************************/ - -/**************************************************************************** - * - * FUNCTION: tz_initialize - * - ****************************************************************************/ - -acpi_status -tz_initialize (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("tz_initialize"); - - memset(&criteria, 0, sizeof(BM_DEVICE_ID)); - memset(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Register driver for thermal zone devices. - */ - criteria.type = BM_TYPE_THERMAL_ZONE; - - driver.notify = &tz_notify; - driver.request = &tz_request; - - status = bm_register_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: tz_terminate - * - ****************************************************************************/ - -acpi_status -tz_terminate (void) -{ - acpi_status status = AE_OK; - BM_DEVICE_ID criteria; - BM_DRIVER driver; - - FUNCTION_TRACE("tz_terminate"); - - memset(&criteria, 0, sizeof(BM_DEVICE_ID)); - memset(&driver, 0, sizeof(BM_DRIVER)); - - /* - * Unregister driver for thermal zone devices. - */ - criteria.type = BM_TYPE_THERMAL_ZONE; - - driver.notify = &tz_notify; - driver.request = &tz_request; - - status = bm_unregister_driver(&criteria, &driver); - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: tz_notify - * - ****************************************************************************/ - -acpi_status -tz_notify ( - BM_NOTIFY notify_type, - BM_HANDLE device_handle, - void **context) -{ - acpi_status status = AE_OK; - TZ_CONTEXT *tz = NULL; - - FUNCTION_TRACE("tz_notify"); - - if (!context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - tz = (TZ_CONTEXT*)*context; - - switch (notify_type) { - - case BM_NOTIFY_DEVICE_ADDED: - status = tz_add_device(device_handle, context); - break; - - case BM_NOTIFY_DEVICE_REMOVED: - status = tz_remove_device(context); - break; - - case TZ_NOTIFY_TEMPERATURE_CHANGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Temperature (_TMP) change event detected.\n")); - tz_policy_check(*context); - status = tz_get_temperature(tz); - if (ACPI_SUCCESS(status)) { - status = tz_osl_generate_event(notify_type, tz); - } - break; - - case TZ_NOTIFY_THRESHOLD_CHANGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Threshold (_SCP) change event detected.\n")); - status = tz_policy_remove_device(tz); - if (ACPI_SUCCESS(status)) { - status = tz_policy_add_device(tz); - } - status = tz_osl_generate_event(notify_type, tz); - break; - - case TZ_NOTIFY_DEVICE_LISTS_CHANGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Device lists (_ALx, _PSL, _TZD) change event detected.\n")); - status = tz_policy_remove_device(tz); - if (ACPI_SUCCESS(status)) { - status = tz_policy_add_device(tz); - } - status = tz_osl_generate_event(notify_type, tz); - break; - - default: - status = AE_SUPPORT; - break; - } - - return_ACPI_STATUS(status); -} - - -/**************************************************************************** - * - * FUNCTION: tz_request - * - ****************************************************************************/ - -acpi_status -tz_request ( - BM_REQUEST *request, - void *context) -{ - acpi_status status = AE_OK; - TZ_CONTEXT *tz = NULL; - - FUNCTION_TRACE("tz_request"); - - /* - * Must have a valid request structure and context. - */ - if (!request || !context) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - tz = (TZ_CONTEXT*)context; - - /* - * Handle request: - * --------------- - */ - switch (request->command) { - - default: - status = AE_SUPPORT; - break; - } - - request->status = status; - - return_ACPI_STATUS(status); -} diff -urN linux-2.4.21/drivers/acpi/ospm/thermal/tz_osl.c linux-2.4.22/drivers/acpi/ospm/thermal/tz_osl.c --- linux-2.4.21/drivers/acpi/ospm/thermal/tz_osl.c 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/thermal/tz_osl.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,398 +0,0 @@ -/****************************************************************************** - * - * Module Name: tz_osl.c - * $Revision: 25 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 "tz.h" - - -MODULE_AUTHOR("Andrew Grover"); -MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Thermal Zone Driver"); -MODULE_LICENSE("GPL"); - -int TZP = 0; -MODULE_PARM(TZP, "i"); -MODULE_PARM_DESC(TZP, "Thermal zone polling frequency, in 1/10 seconds.\n"); - - -#define TZ_PROC_ROOT "thermal" -#define TZ_PROC_STATUS "status" -#define TZ_PROC_INFO "info" - -extern struct proc_dir_entry *bm_proc_root; -static struct proc_dir_entry *tz_proc_root = NULL; - - -/**************************************************************************** - * - * FUNCTION: tz_osl_proc_read_info - * - ****************************************************************************/ - -static int -tz_osl_proc_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - acpi_status status = AE_OK; - char name[5]; - acpi_buffer buffer = {sizeof(name), &name}; - TZ_CONTEXT *tz = NULL; - TZ_THRESHOLDS *thresholds = NULL; - char *p = page; - int len = 0; - u32 i,j; - u32 t = 0; - - if (!context || (off != 0)) - goto end; - - tz = (TZ_CONTEXT*)context; - - thresholds = &(tz->policy.thresholds); - - p += sprintf(p, "critical (S5): trip=%d\n", thresholds->critical.temperature); - - if (thresholds->hot.is_valid) - p += sprintf(p, "critical (S4): trip=%d\n", thresholds->hot.temperature); - - if (thresholds->passive.is_valid) { - p += sprintf(p, "passive: trip=%d tc1=%d tc2=%d tsp=%d devices=", thresholds->passive.temperature, thresholds->passive.tc1, thresholds->passive.tc2, thresholds->passive.tsp); - for (j=0; jpassive.devices.count; j++) - p += sprintf(p, "%08x%c", thresholds->passive.devices.handles[j], (j==thresholds->passive.devices.count-1)?'\n':','); - } - - for (i=0; iactive[i].is_valid)) - break; - p += sprintf(p, "active[%d]: trip=%d devices=", i, thresholds->active[i].temperature); - for (j=0; jactive[i].devices.count; j++) - p += sprintf(p, "%08x%c", thresholds->active[i].devices.handles[j], (j==thresholds->passive.devices.count-1)?'\n':','); - } - - p += sprintf(p, "cooling mode: "); - switch (tz->policy.cooling_mode) { - case TZ_COOLING_MODE_ACTIVE: - p += sprintf(p, "active (noisy)\n"); - break; - case TZ_COOLING_MODE_PASSIVE: - p += sprintf(p, "passive (quiet)\n"); - break; - default: - p += sprintf(p, "unknown\n"); - break; - } - - p += sprintf(p, "polling: "); - switch (tz->policy.polling_freq) { - case 0: - p += sprintf(p, "disabled\n"); - break; - default: - p += sprintf(p, "%d dS\n", tz->policy.polling_freq); - break; - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return len; -} - - -/**************************************************************************** - * - * FUNCTION: tz_osl_proc_write_info - * - ****************************************************************************/ - -static int tz_osl_proc_write_info ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - TZ_CONTEXT *tz = NULL; - u32 state = 0; - u32 size = 0; - - if (!buffer || (count==0) || !data) { - goto end; - } - - tz = (TZ_CONTEXT*)data; - - size = strlen(buffer); - if (size < 4) - goto end; - - /* Cooling preference: "scp=0" (active) or "scp=1" (passive) */ - if (0 == strncmp(buffer, "scp=", 4)) { - tz_set_cooling_preference(tz, (buffer[4] - '0')); - } - - /* Polling frequency: "tzp=X" (poll every X [0-9] seconds) */ - else if (0 == strncmp(buffer, "tzp=", 4)) { - tz->policy.polling_freq = (buffer[4] - '0') * 10; - tz_policy_check(tz); - } - -end: - return count; -} - - -/**************************************************************************** - * - * FUNCTION: tz_osl_proc_read_status - * - ****************************************************************************/ - -static int -tz_osl_proc_read_status ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - TZ_CONTEXT *tz = NULL; - char *p = page; - int len = 0; - - if (!context || (off != 0)) { - goto end; - } - - tz = (TZ_CONTEXT*)context; - - /* Temperature */ - - tz_get_temperature(tz); - - p += sprintf(p, "temperature: %d dK\n", tz->policy.temperature); - - p += sprintf(p, "state: "); - if (tz->policy.state == 0) - p += sprintf(p, "ok\n"); - else if (tz->policy.state & TZ_STATE_CRITICAL) - p += sprintf(p, "critical\n"); - else if (tz->policy.state & TZ_STATE_HOT) - p += sprintf(p, "hot\n"); - else { - if (tz->policy.state & TZ_STATE_ACTIVE) - p += sprintf(p, "active[%d] ", tz->policy.state & 0x07); - if (tz->policy.state & TZ_STATE_PASSIVE) - p += sprintf(p, "passive "); - p += sprintf(p, "\n"); - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return(len); -} - - -/**************************************************************************** - * - * FUNCTION: tz_osl_add_device - * - ****************************************************************************/ - -acpi_status -tz_osl_add_device( - TZ_CONTEXT *tz) -{ - struct proc_dir_entry *proc_entry = NULL; - struct proc_dir_entry *proc_child_entry = NULL; - - if (!tz) { - return(AE_BAD_PARAMETER); - } - - printk("ACPI: Thermal Zone found\n"); - - proc_entry = proc_mkdir(tz->uid, tz_proc_root); - if (!proc_entry) - return(AE_ERROR); - - proc_child_entry = create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO, proc_entry, tz_osl_proc_read_status, (void*)tz); - if (!proc_child_entry) - return(AE_ERROR); - - proc_child_entry = create_proc_entry(TZ_PROC_INFO, S_IFREG | 0644, proc_entry); - if (!proc_child_entry) - return(AE_ERROR); - - proc_child_entry->read_proc = tz_osl_proc_read_info; - proc_child_entry->write_proc = tz_osl_proc_write_info; - proc_child_entry->data = (void*)tz; - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: tz_osl_remove_device - * - ****************************************************************************/ - -acpi_status -tz_osl_remove_device ( - TZ_CONTEXT *tz) -{ - char proc_entry[64]; - - if (!tz) { - return(AE_BAD_PARAMETER); - } - - sprintf(proc_entry, "%s/%s", tz->uid, TZ_PROC_INFO); - remove_proc_entry(proc_entry, tz_proc_root); - - sprintf(proc_entry, "%s/%s", tz->uid, TZ_PROC_STATUS); - remove_proc_entry(proc_entry, tz_proc_root); - - sprintf(proc_entry, "%s", tz->uid); - remove_proc_entry(proc_entry, tz_proc_root); - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: tz_osl_generate_event - * - ****************************************************************************/ - -acpi_status -tz_osl_generate_event ( - u32 event, - TZ_CONTEXT *tz) -{ - acpi_status status = AE_OK; - - if (!tz) { - return(AE_BAD_PARAMETER); - } - - switch (event) { - - case TZ_NOTIFY_TEMPERATURE_CHANGE: - status = bm_osl_generate_event(tz->device_handle, - TZ_PROC_ROOT, tz->uid, event, - tz->policy.temperature); - break; - - case TZ_NOTIFY_THRESHOLD_CHANGE: - case TZ_NOTIFY_DEVICE_LISTS_CHANGE: - status = bm_osl_generate_event(tz->device_handle, - TZ_PROC_ROOT, tz->uid, event, 0); - break; - - default: - return(AE_BAD_PARAMETER); - break; - } - - return(status); -} - - -/**************************************************************************** - * - * FUNCTION: tz_osl_init - * - ****************************************************************************/ - -static int __init -tz_osl_init (void) -{ - acpi_status status = AE_OK; - - /* abort if no busmgr */ - if (!bm_proc_root) - return -ENODEV; - - tz_proc_root = proc_mkdir(TZ_PROC_ROOT, bm_proc_root); - if (!tz_proc_root) { - status = AE_ERROR; - } - else { - status = tz_initialize(); - if (ACPI_FAILURE(status)) { - remove_proc_entry(TZ_PROC_ROOT, bm_proc_root); - } - - } - - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - - -/**************************************************************************** - * - * FUNCTION: tz_osl_cleanup - * - ****************************************************************************/ - -static void __exit -tz_osl_cleanup (void) -{ - tz_terminate(); - - if (tz_proc_root) { - remove_proc_entry(TZ_PROC_ROOT, bm_proc_root); - } - - return; -} - - -module_init(tz_osl_init); -module_exit(tz_osl_cleanup); diff -urN linux-2.4.21/drivers/acpi/ospm/thermal/tzpolicy.c linux-2.4.22/drivers/acpi/ospm/thermal/tzpolicy.c --- linux-2.4.21/drivers/acpi/ospm/thermal/tzpolicy.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/ospm/thermal/tzpolicy.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,578 +0,0 @@ -/**************************************************************************** - * - * Module Name: tzpolicy.c - - * $Revision: 30 $ - * - ****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 Andrew Grover - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU 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 - */ - -/* - * TBD: 1. Support performance-limit control for non-processor devices - * (those listed in _TZD, e.g. graphics). - */ - -#include -#include -#include - -#include -#include -#include "tz.h" - - -#define _COMPONENT ACPI_THERMAL - MODULE_NAME ("tzpolicy") - - -/**************************************************************************** - * Globals - ****************************************************************************/ - -void -tz_policy_run ( - unsigned long data); - - -/**************************************************************************** - * Internal Functions - ****************************************************************************/ - -acpi_status -set_performance_limit ( - BM_HANDLE device_handle, - u32 flag) -{ - acpi_status status; - BM_REQUEST request; - - request.status = AE_OK; - request.handle = device_handle; - request.command = PR_COMMAND_SET_PERF_LIMIT; - request.buffer.length = sizeof(u32); - request.buffer.pointer = &flag; - - status = bm_request(&request); - - if (ACPI_FAILURE(status)) - return status; - else - return request.status; -} - - -/**************************************************************************** - * - * FUNCTION: tz_policy_critical - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -tz_policy_critical( - TZ_CONTEXT *tz) -{ - FUNCTION_TRACE("tz_policy_critical"); - - if (!tz) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (tz->policy.temperature >= tz->policy.thresholds.critical.temperature) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Critical (S5) threshold reached.\n")); - /* TBD: Need method for shutting down system. */ - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: tz_policy_hot - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -tz_policy_hot( - TZ_CONTEXT *tz) -{ - FUNCTION_TRACE("tz_policy_hot"); - - if (!tz || !tz->policy.thresholds.hot.is_valid) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (tz->policy.temperature >= tz->policy.thresholds.hot.temperature) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Critical (S4) threshold reached.\n")); - /* TBD: Need method for invoking OS-level critical suspend. */ - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: tz_policy_passive - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -tz_policy_passive( - TZ_CONTEXT *tz) -{ - TZ_PASSIVE_THRESHOLD *passive = NULL; - static u32 last_temperature = 0; - s32 trend = 0; - u32 i = 0; - - FUNCTION_TRACE("tz_policy_passive"); - - if (!tz || !tz->policy.thresholds.passive.is_valid) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - passive = &(tz->policy.thresholds.passive); - - if (tz->policy.temperature >= passive->temperature) { - /* - * Thermal trend? - * -------------- - * Using the passive cooling equation (see the ACPI - * Specification), calculate the current thermal trend - * (a.k.a. performance delta). - */ - trend = passive->tc1 * (tz->policy.temperature - last_temperature) + passive->tc2 * (tz->policy.temperature - passive->temperature); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "trend[%d] = TC1[%d]*(temp[%d]-last[%d]) + TC2[%d]*(temp[%d]-passive[%d])\n", trend, passive->tc1, tz->policy.temperature, last_temperature, passive->tc2, tz->policy.temperature, passive->temperature)); - - last_temperature = tz->policy.temperature; - - /* - * Heating Up? - * ----------- - * Decrease thermal performance limit on all passive - * cooling devices (processors). - */ - if (trend > 0) { - for (i=0; idevices.count; i++) - set_performance_limit(passive->devices.handles[i], PR_PERF_DEC); - } - /* - * Cooling Off? - * ------------ - * Increase thermal performance limit on all passive - * cooling devices (processors). - */ - else if (trend < 0) { - for (i=0; idevices.count; i++) - set_performance_limit(passive->devices.handles[i], PR_PERF_INC); - } - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: tz_policy_active - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -tz_policy_active( - TZ_CONTEXT *tz) -{ - acpi_status status = AE_OK; - TZ_ACTIVE_THRESHOLD *active = NULL; - u32 i,j = 0; - - FUNCTION_TRACE("tz_policy_active"); - - if (!tz || !tz->policy.thresholds.active[0].is_valid) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - for (i=0; ipolicy.thresholds.active[i]); - if (!active || !active->is_valid) - break; - - /* - * Above Threshold? - * ---------------- - * If not already enabled, turn ON all cooling devices - * associated with this active threshold. - */ - if ((tz->policy.temperature >= active->temperature) && (active->cooling_state != TZ_COOLING_ENABLED)) { - for (j = 0; j < active->devices.count; j++) { - status = bm_set_device_power_state(active->devices.handles[j], ACPI_STATE_D0); - if (ACPI_SUCCESS(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Cooling device [%02x] now ON.\n", active->devices.handles[j])); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to turn ON cooling device [%02x].\n", active->devices.handles[j])); - } - } - active->cooling_state = TZ_COOLING_ENABLED; - } - /* - * Below Threshold? - * ---------------- - * Turn OFF all cooling devices associated with this - * threshold. Note that by checking "if not disabled" we - * turn off all cooling devices for thresholds in the - * TZ_COOLING_STATE_UNKNOWN state, useful as a level-set - * during the first pass. - */ - else if (active->cooling_state != TZ_COOLING_DISABLED) { - for (j = 0; j < active->devices.count; j++) { - status = bm_set_device_power_state(active->devices.handles[j], ACPI_STATE_D3); - if (ACPI_SUCCESS(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Cooling device [%02x] now OFF.\n", active->devices.handles[j])); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unable to turn OFF cooling device [%02x].\n", active->devices.handles[j])); - } - } - active->cooling_state = TZ_COOLING_DISABLED; - } - } - - return_ACPI_STATUS(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: tz_policy_check - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: Note that this function will get called whenever: - * 1. A thermal event occurs. - * 2. The polling/sampling time period expires. - * - ****************************************************************************/ - -void -tz_policy_check ( - void *context) -{ - acpi_status status = AE_OK; - TZ_CONTEXT *tz = NULL; - TZ_POLICY *policy = NULL; - TZ_THRESHOLDS *thresholds = NULL; - u32 previous_temperature = 0; - u32 previous_state = 0; - u32 active_index = 0; - u32 i = 0; - u32 sleep_time = 0; - - FUNCTION_TRACE("tz_policy_check"); - - if (!context) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return_VOID; - } - - tz = (TZ_CONTEXT*)context; - policy = &(tz->policy); - thresholds = &(tz->policy.thresholds); - - /* - * Preserve Previous State: - * ------------------------ - */ - previous_temperature = tz->policy.temperature; - previous_state = tz->policy.state; - - /* - * Get Temperature: - * ---------------- - */ - status = tz_get_temperature(tz); - if (ACPI_FAILURE(status)) { - return_VOID; - } - - /* - * Calculate State: - * ---------------- - */ - policy->state = TZ_STATE_OK; - - /* Critical? */ - if (policy->temperature >= thresholds->critical.temperature) - policy->state |= TZ_STATE_CRITICAL; - - /* Hot? */ - if ((thresholds->hot.is_valid) && (policy->temperature >= thresholds->hot.temperature)) - policy->state |= TZ_STATE_CRITICAL; - - /* Passive? */ - if ((thresholds->passive.is_valid) && (policy->temperature >= thresholds->passive.temperature)) - policy->state |= TZ_STATE_PASSIVE; - - /* Active? */ - if (thresholds->active[0].is_valid) { - for (i=0; iactive[i].is_valid) && (policy->temperature >= thresholds->active[i].temperature)) { - policy->state |= TZ_STATE_ACTIVE; - if (i > active_index) - active_index = i; - } - } - policy->state |= active_index; - } - - /* - * Invoke Policy: - * -------------- - * Note that policy must be invoked both when 'going into' a - * policy state (e.g. to allow fans to be turned on) and 'going - * out of' a policy state (e.g. to allow fans to be turned off); - * thus we must preserve the previous state. - */ - if (policy->state & TZ_STATE_CRITICAL) - tz_policy_critical(tz); - if (policy->state & TZ_STATE_HOT) - tz_policy_hot(tz); - if ((policy->state & TZ_STATE_PASSIVE) || (previous_state & TZ_STATE_PASSIVE)) - tz_policy_passive(tz); - if ((policy->state & TZ_STATE_ACTIVE) || (previous_state & TZ_STATE_ACTIVE)) - tz_policy_active(tz); - - /* - * Calculate Sleep Time: - * --------------------- - * If we're in the passive state, use _TSP's value. Otherwise - * use _TZP or the OS's default polling frequency. If no polling - * frequency is specified then we'll wait forever (that is, until - * a thermal event occurs -- e.g. never poll). Note that _TSP - * and _TZD values are given in 1/10th seconds. - */ - if (policy->state & TZ_STATE_PASSIVE) - sleep_time = thresholds->passive.tsp * 100; - else if (policy->polling_freq > 0) - sleep_time = policy->polling_freq * 100; - else - sleep_time = WAIT_FOREVER; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Thermal_zone[%02x]: temperature[%d] state[%08x]\n", tz->device_handle, policy->temperature, policy->state)); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Scheduling next poll in [%d]ms.\n", sleep_time)); - - /* - * Schedule Next Poll: - * ------------------- - */ - if (sleep_time < WAIT_FOREVER) { - if (timer_pending(&(policy->timer))) - mod_timer(&(policy->timer), (HZ*sleep_time)/1000); - else { - policy->timer.data = (unsigned long)tz; - policy->timer.function = tz_policy_run; - policy->timer.expires = jiffies + (HZ*sleep_time)/1000; - add_timer(&(policy->timer)); - } - } - else { - if (timer_pending(&(policy->timer))) - del_timer(&(policy->timer)); - } - - return_VOID; -} - - -/**************************************************************************** - * - * FUNCTION: tz_policy_run - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - - -void -tz_policy_run ( - unsigned long data) -{ - acpi_status status = AE_OK; - - FUNCTION_TRACE("tz_policy_run"); - - if (!data) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return_VOID; - } - - /* - * Defer to Non-Interrupt Level: - * ----------------------------- - * Note that all Linux kernel timers run at interrupt-level (ack!). - */ - status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, tz_policy_check, (void*)data); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Error invoking thermal policy.\n")); - } - - return_VOID; -} - - -/**************************************************************************** - * - * FUNCTION: tz_policy_add_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -tz_policy_add_device ( - TZ_CONTEXT *tz) -{ - acpi_status status = AE_OK; - TZ_THRESHOLDS *thresholds = NULL; - u32 i,j = 0; - - FUNCTION_TRACE("tz_policy_add_device"); - - if (!tz) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding policy for thermal zone [%02x].\n", tz->device_handle)); - - /* - * Get Thresholds: - * --------------- - */ - status = tz_get_thresholds(tz); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Initialize Policies: - * -------------------- - */ - if (tz->policy.thresholds.passive.is_valid) { - for (i=0; ipolicy.thresholds.passive.devices.count; i++) - set_performance_limit(tz->policy.thresholds.passive.devices.handles[i], PR_PERF_MAX); - tz_policy_passive(tz); - } - if (tz->policy.thresholds.active[0].is_valid) - tz_policy_active(tz); - - /* - * Initialize Policy Timer: - * ------------------------ - */ - init_timer(&(tz->policy.timer)); - - /* - * Start Policy: - * ------------- - * Run an initial check using this zone's policy. - */ - tz_policy_check(tz); - - return_ACPI_STATUS(AE_OK); -} - - -/***************************************************************************** - * - * FUNCTION: tz_policy_remove_device - * - * PARAMETERS: - * - * RETURN: - * - * DESCRIPTION: - * - ****************************************************************************/ - -acpi_status -tz_policy_remove_device( - TZ_CONTEXT *tz) -{ - u32 i = 0; - - FUNCTION_TRACE("tz_remove_device"); - - if (!tz) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing policy for thermal zone [%02x].\n", tz->device_handle)); - - /* - * Delete the thermal zone policy timer entry, if exists. - */ - if (timer_pending(&(tz->policy.timer))) - del_timer(&(tz->policy.timer)); - - /* - * Reset thermal performance limit on all processors back to max. - */ - if (tz->policy.thresholds.passive.is_valid) { - for (i=0; ipolicy.thresholds.passive.devices.count; i++) - set_performance_limit(tz->policy.thresholds.passive.devices.handles[i], PR_PERF_MAX); - } - - return_ACPI_STATUS(AE_OK); -} diff -urN linux-2.4.21/drivers/acpi/parser/Makefile linux-2.4.22/drivers/acpi/parser/Makefile --- linux-2.4.21/drivers/acpi/parser/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/parser/psargs.c linux-2.4.22/drivers/acpi/parser/psargs.c --- linux-2.4.21/drivers/acpi/parser/psargs.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/psargs.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,43 +1,61 @@ /****************************************************************************** * * Module Name: psargs - Parse AML opcode arguments - * $Revision: 52 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("psargs") + ACPI_MODULE_NAME ("psargs") /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_package_length + * FUNCTION: acpi_ps_get_next_package_length * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: Decoded package length. On completion, the AML pointer points * past the length byte or bytes. @@ -48,16 +66,16 @@ u32 acpi_ps_get_next_package_length ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { - u32 encoded_length; - u32 length = 0; + u32 encoded_length; + u32 length = 0; - FUNCTION_TRACE ("Ps_get_next_package_length"); + ACPI_FUNCTION_TRACE ("ps_get_next_package_length"); - encoded_length = (u32) GET8 (parser_state->aml); + encoded_length = (u32) ACPI_GET8 (parser_state->aml); parser_state->aml++; @@ -70,7 +88,7 @@ case 1: /* 2-byte encoding (next byte + bits 0-3) */ - length = ((GET8 (parser_state->aml) << 04) | + length = ((ACPI_GET8 (parser_state->aml) << 04) | (encoded_length & 0x0F)); parser_state->aml++; break; @@ -78,8 +96,8 @@ case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */ - length = ((GET8 (parser_state->aml + 1) << 12) | - (GET8 (parser_state->aml) << 04) | + length = ((ACPI_GET8 (parser_state->aml + 1) << 12) | + (ACPI_GET8 (parser_state->aml) << 04) | (encoded_length & 0x0F)); parser_state->aml += 2; break; @@ -87,12 +105,17 @@ case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */ - length = ((GET8 (parser_state->aml + 2) << 20) | - (GET8 (parser_state->aml + 1) << 12) | - (GET8 (parser_state->aml) << 04) | + length = ((ACPI_GET8 (parser_state->aml + 2) << 20) | + (ACPI_GET8 (parser_state->aml + 1) << 12) | + (ACPI_GET8 (parser_state->aml) << 04) | (encoded_length & 0x0F)); parser_state->aml += 3; break; + + default: + + /* Can't get here, only 2 bits / 4 cases */ + break; } return_VALUE (length); @@ -101,9 +124,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_package_end + * FUNCTION: acpi_ps_get_next_package_end * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: Pointer to end-of-package +1 * @@ -114,16 +137,18 @@ u8 * acpi_ps_get_next_package_end ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { - u8 *start = parser_state->aml; - NATIVE_UINT length; + u8 *start = parser_state->aml; + acpi_native_uint length; - FUNCTION_TRACE ("Ps_get_next_package_end"); + ACPI_FUNCTION_TRACE ("ps_get_next_package_end"); - length = (NATIVE_UINT) acpi_ps_get_next_package_length (parser_state); + /* Function below changes parser_state->Aml */ + + length = (acpi_native_uint) acpi_ps_get_next_package_length (parser_state); return_PTR (start + length); /* end of package */ } @@ -131,9 +156,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_namestring + * FUNCTION: acpi_ps_get_next_namestring * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: Pointer to the start of the name string (pointer points into * the AML. @@ -144,32 +169,31 @@ * ******************************************************************************/ -NATIVE_CHAR * +char * acpi_ps_get_next_namestring ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { - u8 *start = parser_state->aml; - u8 *end = parser_state->aml; - u32 length; + u8 *start = parser_state->aml; + u8 *end = parser_state->aml; - FUNCTION_TRACE ("Ps_get_next_namestring"); + ACPI_FUNCTION_TRACE ("ps_get_next_namestring"); /* Handle multiple prefix characters */ - while (acpi_ps_is_prefix_char (GET8 (end))) { - /* include prefix '\\' or '^' */ + while (acpi_ps_is_prefix_char (ACPI_GET8 (end))) { + /* Include prefix '\\' or '^' */ end++; } /* Decode the path */ - switch (GET8 (end)) { + switch (ACPI_GET8 (end)) { case 0: - /* Null_name */ + /* null_name */ if (end == start) { start = NULL; @@ -177,183 +201,77 @@ end++; break; - case AML_DUAL_NAME_PREFIX: - /* two name segments */ + /* Two name segments */ - end += 9; + end += 1 + (2 * ACPI_NAME_SIZE); break; - case AML_MULTI_NAME_PREFIX_OP: - /* multiple name segments */ + /* Multiple name segments, 4 chars each */ - length = (u32) GET8 (end + 1) * 4; - end += 2 + length; + end += 2 + ((acpi_size) ACPI_GET8 (end + 1) * ACPI_NAME_SIZE); break; - default: - /* single name segment */ - /* assert (Acpi_ps_is_lead (GET8 (End))); */ + /* Single name segment */ - end += 4; + end += ACPI_NAME_SIZE; break; } parser_state->aml = (u8*) end; - - return_PTR ((NATIVE_CHAR *) start); + return_PTR ((char *) start); } /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_namepath + * FUNCTION: acpi_ps_get_next_namepath * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * Arg - Where the namepath will be stored - * Arg_count - If the namepath points to a control method + * arg_count - If the namepath points to a control method * the method's argument is returned here. - * Method_call - Whether the namepath can be the start - * of a method call + * method_call - Whether the namepath can possibly be the + * start of a method call * - * RETURN: None + * RETURN: Status * - * DESCRIPTION: Get next name (if method call, push appropriate # args). Names - * are looked up in either the parsed or internal namespace to - * determine if the name represents a control method. If a method + * DESCRIPTION: Get next name (if method call, return # of required args). + * Names are looked up in the internal namespace to determine + * if the name represents a control method. If a method * is found, the number of arguments to the method is returned. * This information is critical for parsing to continue correctly. * ******************************************************************************/ - -#ifdef PARSER_ONLY - -void -acpi_ps_get_next_namepath ( - acpi_parse_state *parser_state, - acpi_parse_object *arg, - u32 *arg_count, - u8 method_call) -{ - NATIVE_CHAR *path; - acpi_parse_object *name_op; - acpi_parse_object *op; - acpi_parse_object *count; - - - FUNCTION_TRACE ("Ps_get_next_namepath"); - - - path = acpi_ps_get_next_namestring (parser_state); - if (!path || !method_call) { - /* Null name case, create a null namepath object */ - - acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP); - arg->value.name = path; - return_VOID; - } - - - if (acpi_gbl_parsed_namespace_root) { - /* - * Lookup the name in the parsed namespace - */ - op = NULL; - if (method_call) { - op = acpi_ps_find (acpi_ps_get_parent_scope (parser_state), - path, AML_METHOD_OP, 0); - } - - if (op) { - if (op->opcode == AML_METHOD_OP) { - /* - * The name refers to a control method, so this namepath is a - * method invocation. We need to 1) Get the number of arguments - * associated with this method, and 2) Change the NAMEPATH - * object into a METHODCALL object. - */ - count = acpi_ps_get_arg (op, 0); - if (count && count->opcode == AML_BYTE_OP) { - name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP); - if (name_op) { - /* Change arg into a METHOD CALL and attach the name */ - - acpi_ps_init_op (arg, AML_INT_METHODCALL_OP); - - name_op->value.name = path; - - /* Point METHODCALL/NAME to the METHOD Node */ - - name_op->node = (acpi_namespace_node *) op; - acpi_ps_append_arg (arg, name_op); - - *arg_count = (u32) count->value.integer & - METHOD_FLAGS_ARG_COUNT; - } - } - - return_VOID; - } - - /* - * Else this is normal named object reference. - * Just init the NAMEPATH object with the pathname. - * (See code below) - */ - } - } - - /* - * Either we didn't find the object in the namespace, or the object is - * something other than a control method. Just initialize the Op with the - * pathname - */ - acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP); - arg->value.name = path; - - - return_VOID; -} - - -#else - - -void +acpi_status acpi_ps_get_next_namepath ( - acpi_parse_state *parser_state, - acpi_parse_object *arg, - u32 *arg_count, - u8 method_call) + struct acpi_walk_state *walk_state, + struct acpi_parse_state *parser_state, + union acpi_parse_object *arg, + u8 method_call) { - NATIVE_CHAR *path; - acpi_parse_object *name_op; - acpi_status status; - acpi_namespace_node *method_node = NULL; - acpi_namespace_node *node; - acpi_generic_state scope_info; + char *path; + union acpi_parse_object *name_op; + acpi_status status = AE_OK; + union acpi_operand_object *method_desc; + struct acpi_namespace_node *node; + union acpi_generic_state scope_info; - FUNCTION_TRACE ("Ps_get_next_namepath"); + ACPI_FUNCTION_TRACE ("ps_get_next_namepath"); path = acpi_ps_get_next_namestring (parser_state); - if (!path || !method_call) { - /* Null name case, create a null namepath object */ - acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP); - arg->value.name = path; - return_VOID; - } + /* Null path case is allowed */ - - if (method_call) { + if (path) { /* * Lookup the name in the internal namespace */ @@ -369,36 +287,48 @@ * parent tree, but don't open a new scope -- we just want to lookup the * object (MUST BE mode EXECUTE to perform upsearch) */ - status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, IMODE_EXECUTE, - NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, NULL, - &node); - if (ACPI_SUCCESS (status)) { + status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node); + if (ACPI_SUCCESS (status) && method_call) { if (node->type == ACPI_TYPE_METHOD) { - method_node = node; - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "method - %p Path=%p\n", - method_node, path)); + /* + * This name is actually a control method invocation + */ + method_desc = acpi_ns_get_attached_object (node); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Control Method - %p Desc %p Path=%p\n", + node, method_desc, path)); name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP); - if (name_op) { - /* Change arg into a METHOD CALL and attach name to it */ - - acpi_ps_init_op (arg, AML_INT_METHODCALL_OP); + if (!name_op) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - name_op->value.name = path; + /* Change arg into a METHOD CALL and attach name to it */ - /* Point METHODCALL/NAME to the METHOD Node */ + acpi_ps_init_op (arg, AML_INT_METHODCALL_OP); + name_op->common.value.name = path; - name_op->node = method_node; - acpi_ps_append_arg (arg, name_op); + /* Point METHODCALL/NAME to the METHOD Node */ - if (!method_node->object) { - return_VOID; - } + name_op->common.node = node; + acpi_ps_append_arg (arg, name_op); - *arg_count = (method_node->object)->method.param_count; + if (!method_desc) { + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Control Method - %p has no attached object\n", + node)); + return_ACPI_STATUS (AE_AML_INTERNAL); } - return_VOID; + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Control Method - %p Args %X\n", + node, method_desc->method.param_count)); + + /* Get the number of arguments to expect */ + + walk_state->arg_count = method_desc->method.param_count; + return_ACPI_STATUS (AE_OK); } /* @@ -407,28 +337,53 @@ * (See code below) */ } + + if (ACPI_FAILURE (status)) { + /* + * 1) Any error other than NOT_FOUND is always severe + * 2) NOT_FOUND is only important if we are executing a method. + * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok. + */ + if ((((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) && + (status == AE_NOT_FOUND) && + (walk_state->op->common.aml_opcode != AML_COND_REF_OF_OP)) || + + (status != AE_NOT_FOUND)) { + ACPI_REPORT_NSERROR (path, status); + + acpi_os_printf ("search_node %p start_node %p return_node %p\n", + scope_info.scope.node, parser_state->start_node, node); + + + } + else { + /* + * We got a NOT_FOUND during table load or we encountered + * a cond_ref_of(x) where the target does not exist. + * -- either case is ok + */ + status = AE_OK; + } + } } /* - * Either we didn't find the object in the namespace, or the object is - * something other than a control method. Just initialize the Op with the - * pathname. + * Regardless of success/failure above, + * Just initialize the Op with the pathname. */ acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP); - arg->value.name = path; - + arg->common.value.name = path; - return_VOID; + return_ACPI_STATUS (status); } -#endif /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_simple_arg + * FUNCTION: acpi_ps_get_next_simple_arg * - * PARAMETERS: Parser_state - Current parser state object - * Arg_type - The argument type (AML_*_ARG) + * PARAMETERS: parser_state - Current parser state object + * arg_type - The argument type (AML_*_ARG) * Arg - Where the argument is returned * * RETURN: None @@ -439,20 +394,19 @@ void acpi_ps_get_next_simple_arg ( - acpi_parse_state *parser_state, - u32 arg_type, - acpi_parse_object *arg) + struct acpi_parse_state *parser_state, + u32 arg_type, + union acpi_parse_object *arg) { - FUNCTION_TRACE_U32 ("Ps_get_next_simple_arg", arg_type); + ACPI_FUNCTION_TRACE_U32 ("ps_get_next_simple_arg", arg_type); switch (arg_type) { - case ARGP_BYTEDATA: acpi_ps_init_op (arg, AML_BYTE_OP); - arg->value.integer = (u32) GET8 (parser_state->aml); + arg->common.value.integer = (u32) ACPI_GET8 (parser_state->aml); parser_state->aml++; break; @@ -463,7 +417,7 @@ /* Get 2 bytes from the AML stream */ - MOVE_UNALIGNED16_TO_32 (&arg->value.integer, parser_state->aml); + ACPI_MOVE_16_TO_32 (&arg->common.value.integer, parser_state->aml); parser_state->aml += 2; break; @@ -474,7 +428,7 @@ /* Get 4 bytes from the AML stream */ - MOVE_UNALIGNED32_TO_32 (&arg->value.integer, parser_state->aml); + ACPI_MOVE_32_TO_32 (&arg->common.value.integer, parser_state->aml); parser_state->aml += 4; break; @@ -485,7 +439,7 @@ /* Get 8 bytes from the AML stream */ - MOVE_UNALIGNED64_TO_64 (&arg->value.integer, parser_state->aml); + ACPI_MOVE_64_TO_64 (&arg->common.value.integer, parser_state->aml); parser_state->aml += 8; break; @@ -493,9 +447,9 @@ case ARGP_CHARLIST: acpi_ps_init_op (arg, AML_STRING_OP); - arg->value.string = (char*) parser_state->aml; + arg->common.value.string = (char *) parser_state->aml; - while (GET8 (parser_state->aml) != '\0') { + while (ACPI_GET8 (parser_state->aml) != '\0') { parser_state->aml++; } parser_state->aml++; @@ -506,7 +460,13 @@ case ARGP_NAMESTRING: acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP); - arg->value.name = acpi_ps_get_next_namestring (parser_state); + arg->common.value.name = acpi_ps_get_next_namestring (parser_state); + break; + + + default: + + ACPI_REPORT_ERROR (("Invalid arg_type %X\n", arg_type)); break; } @@ -516,47 +476,44 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_field + * FUNCTION: acpi_ps_get_next_field * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: A newly allocated FIELD op * - * DESCRIPTION: Get next field (Named_field, Reserved_field, or Access_field) + * DESCRIPTION: Get next field (named_field, reserved_field, or access_field) * ******************************************************************************/ -acpi_parse_object * +union acpi_parse_object * acpi_ps_get_next_field ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { - u32 aml_offset = parser_state->aml - - parser_state->aml_start; - acpi_parse_object *field; - u16 opcode; - u32 name; + u32 aml_offset = ACPI_PTR_DIFF (parser_state->aml, + parser_state->aml_start); + union acpi_parse_object *field; + u16 opcode; + u32 name; - FUNCTION_TRACE ("Ps_get_next_field"); + ACPI_FUNCTION_TRACE ("ps_get_next_field"); /* determine field type */ - switch (GET8 (parser_state->aml)) { - + switch (ACPI_GET8 (parser_state->aml)) { default: opcode = AML_INT_NAMEDFIELD_OP; break; - case 0x00: opcode = AML_INT_RESERVEDFIELD_OP; parser_state->aml++; break; - case 0x01: opcode = AML_INT_ACCESSFIELD_OP; @@ -568,43 +525,53 @@ /* Allocate a new field op */ field = acpi_ps_alloc_op (opcode); - if (field) { - field->aml_offset = aml_offset; + if (!field) { + return_PTR (NULL); + } - /* Decode the field type */ + field->common.aml_offset = aml_offset; - switch (opcode) { - case AML_INT_NAMEDFIELD_OP: + /* Decode the field type */ - /* Get the 4-character name */ + switch (opcode) { + case AML_INT_NAMEDFIELD_OP: - MOVE_UNALIGNED32_TO_32 (&name, parser_state->aml); - acpi_ps_set_name (field, name); - parser_state->aml += 4; + /* Get the 4-character name */ - /* Get the length which is encoded as a package length */ + ACPI_MOVE_32_TO_32 (&name, parser_state->aml); + acpi_ps_set_name (field, name); + parser_state->aml += ACPI_NAME_SIZE; - field->value.size = acpi_ps_get_next_package_length (parser_state); - break; + /* Get the length which is encoded as a package length */ + field->common.value.size = acpi_ps_get_next_package_length (parser_state); + break; - case AML_INT_RESERVEDFIELD_OP: - /* Get the length which is encoded as a package length */ + case AML_INT_RESERVEDFIELD_OP: - field->value.size = acpi_ps_get_next_package_length (parser_state); - break; + /* Get the length which is encoded as a package length */ + field->common.value.size = acpi_ps_get_next_package_length (parser_state); + break; - case AML_INT_ACCESSFIELD_OP: - /* Get Access_type and Access_atrib and merge into the field Op */ + case AML_INT_ACCESSFIELD_OP: - field->value.integer = ((GET8 (parser_state->aml) << 8) | - GET8 (parser_state->aml)); - parser_state->aml += 2; - break; - } + /* + * Get access_type and access_attrib and merge into the field Op + * access_type is first operand, access_attribute is second + */ + field->common.value.integer = (ACPI_GET8 (parser_state->aml) << 8); + parser_state->aml++; + field->common.value.integer |= ACPI_GET8 (parser_state->aml); + parser_state->aml++; + break; + + default: + + /* Opcode was set in previous switch */ + break; } return_PTR (field); @@ -613,33 +580,35 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_arg + * FUNCTION: acpi_ps_get_next_arg * - * PARAMETERS: Parser_state - Current parser state object - * Arg_type - The argument type (AML_*_ARG) - * Arg_count - If the argument points to a control method + * PARAMETERS: parser_state - Current parser state object + * arg_type - The argument type (AML_*_ARG) + * arg_count - If the argument points to a control method * the method's argument is returned here. * - * RETURN: An op object containing the next argument. + * RETURN: Status, and an op object containing the next argument. * * DESCRIPTION: Get next argument (including complex list arguments that require * pushing the parser stack) * ******************************************************************************/ -acpi_parse_object * +acpi_status acpi_ps_get_next_arg ( - acpi_parse_state *parser_state, - u32 arg_type, - u32 *arg_count) + struct acpi_walk_state *walk_state, + struct acpi_parse_state *parser_state, + u32 arg_type, + union acpi_parse_object **return_arg) { - acpi_parse_object *arg = NULL; - acpi_parse_object *prev = NULL; - acpi_parse_object *field; - u32 subop; + union acpi_parse_object *arg = NULL; + union acpi_parse_object *prev = NULL; + union acpi_parse_object *field; + u32 subop; + acpi_status status = AE_OK; - FUNCTION_TRACE_PTR ("Ps_get_next_arg", parser_state); + ACPI_FUNCTION_TRACE_PTR ("ps_get_next_arg", parser_state); switch (arg_type) { @@ -653,15 +622,16 @@ /* constants, strings, and namestrings are all the same size */ arg = acpi_ps_alloc_op (AML_BYTE_OP); - if (arg) { - acpi_ps_get_next_simple_arg (parser_state, arg_type, arg); + if (!arg) { + return_ACPI_STATUS (AE_NO_MEMORY); } + acpi_ps_get_next_simple_arg (parser_state, arg_type, arg); break; case ARGP_PKGLENGTH: - /* package length, nothing returned */ + /* Package length, nothing returned */ parser_state->pkg_end = acpi_ps_get_next_package_end (parser_state); break; @@ -670,18 +640,17 @@ case ARGP_FIELDLIST: if (parser_state->aml < parser_state->pkg_end) { - /* non-empty list */ + /* Non-empty list */ while (parser_state->aml < parser_state->pkg_end) { field = acpi_ps_get_next_field (parser_state); if (!field) { - break; + return_ACPI_STATUS (AE_NO_MEMORY); } if (prev) { - prev->next = field; + prev->common.next = field; } - else { arg = field; } @@ -689,7 +658,7 @@ prev = field; } - /* skip to End of byte data */ + /* Skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } @@ -699,17 +668,20 @@ case ARGP_BYTELIST: if (parser_state->aml < parser_state->pkg_end) { - /* non-empty list */ + /* Non-empty list */ arg = acpi_ps_alloc_op (AML_INT_BYTELIST_OP); - if (arg) { - /* fill in bytelist data */ - - arg->value.size = (parser_state->pkg_end - parser_state->aml); - ((acpi_parse2_object *) arg)->data = parser_state->aml; + if (!arg) { + return_ACPI_STATUS (AE_NO_MEMORY); } - /* skip to End of byte data */ + /* Fill in bytelist data */ + + arg->common.value.size = ACPI_PTR_DIFF (parser_state->pkg_end, + parser_state->aml); + arg->named.data = parser_state->aml; + + /* Skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } @@ -717,24 +689,26 @@ case ARGP_TARGET: - case ARGP_SUPERNAME: { - subop = acpi_ps_peek_opcode (parser_state); - if (subop == 0 || - acpi_ps_is_leading_char (subop) || - acpi_ps_is_prefix_char (subop)) { - /* Null_name or Name_string */ - - arg = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP); - if (arg) { - acpi_ps_get_next_namepath (parser_state, arg, arg_count, 0); - } + case ARGP_SUPERNAME: + case ARGP_SIMPLENAME: + + subop = acpi_ps_peek_opcode (parser_state); + if (subop == 0 || + acpi_ps_is_leading_char (subop) || + acpi_ps_is_prefix_char (subop)) { + /* null_name or name_string */ + + arg = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP); + if (!arg) { + return_ACPI_STATUS (AE_NO_MEMORY); } - else { - /* single complex argument, nothing returned */ + status = acpi_ps_get_next_namepath (walk_state, parser_state, arg, 0); + } + else { + /* single complex argument, nothing returned */ - *arg_count = 1; - } + walk_state->arg_count = 1; } break; @@ -744,7 +718,7 @@ /* single complex argument, nothing returned */ - *arg_count = 1; + walk_state->arg_count = 1; break; @@ -755,10 +729,18 @@ if (parser_state->aml < parser_state->pkg_end) { /* non-empty list of variable arguments, nothing returned */ - *arg_count = ACPI_VAR_ARGS; + walk_state->arg_count = ACPI_VAR_ARGS; } break; + + + default: + + ACPI_REPORT_ERROR (("Invalid arg_type: %X\n", arg_type)); + status = AE_AML_OPERAND_TYPE; + break; } - return_PTR (arg); + *return_arg = arg; + return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/parser/psopcode.c linux-2.4.22/drivers/acpi/parser/psopcode.c --- linux-2.4.21/drivers/acpi/parser/psopcode.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/psopcode.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,36 +1,54 @@ /****************************************************************************** * * Module Name: psopcode - Parser/Interpreter opcode information table - * $Revision: 49 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("psopcode") + ACPI_MODULE_NAME ("psopcode") #define _UNK 0x6B @@ -45,14 +63,14 @@ #define _UNKNOWN_OPCODE 0x02 /* An example unknown opcode */ #define MAX_EXTENDED_OPCODE 0x88 -#define NUM_EXTENDED_OPCODE MAX_EXTENDED_OPCODE + 1 +#define NUM_EXTENDED_OPCODE (MAX_EXTENDED_OPCODE + 1) #define MAX_INTERNAL_OPCODE -#define NUM_INTERNAL_OPCODE MAX_INTERNAL_OPCODE + 1 +#define NUM_INTERNAL_OPCODE (MAX_INTERNAL_OPCODE + 1) /******************************************************************************* * - * NAME: Acpi_gbl_Aml_op_info + * NAME: acpi_gbl_aml_op_info * * DESCRIPTION: Opcode table. Each entry contains * The name is a simple ascii string, the operand specifier is an @@ -184,7 +202,7 @@ #define ARGP_TO_STRING_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) #define ARGP_TYPE_OP ARGP_LIST1 (ARGP_SUPERNAME) #define ARGP_UNLOAD_OP ARGP_LIST1 (ARGP_SUPERNAME) -#define ARGP_VAR_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_BYTEDATA, ARGP_DATAOBJLIST) +#define ARGP_VAR_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_DATAOBJLIST) #define ARGP_WAIT_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG) #define ARGP_WHILE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST) #define ARGP_WORD_OP ARGP_LIST1 (ARGP_WORDDATA) @@ -195,7 +213,7 @@ * All AML opcodes and the runtime arguments for each. Used by the AML interpreter Each list is compressed * into a 32-bit number and stored in the master opcode table at the end of this file. * - * (Used by Prep_operands procedure and the ASL Compiler) + * (Used by prep_operands procedure and the ASL Compiler) */ @@ -219,7 +237,7 @@ #define ARGI_BIT_XOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_BREAK_OP ARG_NONE #define ARGI_BREAK_POINT_OP ARG_NONE -#define ARGI_BUFFER_OP ARGI_INVALID_OPCODE +#define ARGI_BUFFER_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_BYTE_OP ARGI_INVALID_OPCODE #define ARGI_BYTELIST_OP ARGI_INVALID_OPCODE #define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF) @@ -236,7 +254,7 @@ #define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING) #define ARGI_DEBUG_OP ARG_NONE #define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF) -#define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REFERENCE) +#define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REF_OR_STRING) #define ARGI_DEVICE_OP ARGI_INVALID_OPCODE #define ARGI_DIVIDE_OP ARGI_LIST4 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF, ARGI_TARGETREF) #define ARGI_DWORD_OP ARGI_INVALID_OPCODE @@ -259,8 +277,8 @@ #define ARGI_LLESSEQUAL_OP ARGI_INVALID_OPCODE #define ARGI_LNOT_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_LNOTEQUAL_OP ARGI_INVALID_OPCODE -#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION, ARGI_TARGETREF) -#define ARGI_LOAD_TABLE_OP ARGI_LIST6 (ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_TARGETREF) +#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION_OR_FIELD,ARGI_TARGETREF) +#define ARGI_LOAD_TABLE_OP ARGI_LIST6 (ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_ANYTYPE) #define ARGI_LOCAL0 ARG_NONE #define ARGI_LOCAL1 ARG_NONE #define ARGI_LOCAL2 ARG_NONE @@ -273,7 +291,7 @@ #define ARGI_MATCH_OP ARGI_LIST6 (ARGI_PACKAGE, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER) #define ARGI_METHOD_OP ARGI_INVALID_OPCODE #define ARGI_METHODCALL_OP ARGI_INVALID_OPCODE -#define ARGI_MID_OP ARGI_LIST4 (ARGI_BUFFERSTRING,ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_MID_OP ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_MOD_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_MULTIPLY_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_MUTEX_OP ARGI_INVALID_OPCODE @@ -284,7 +302,7 @@ #define ARGI_NOTIFY_OP ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER) #define ARGI_ONE_OP ARG_NONE #define ARGI_ONES_OP ARG_NONE -#define ARGI_PACKAGE_OP ARGI_INVALID_OPCODE +#define ARGI_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_POWER_RES_OP ARGI_INVALID_OPCODE #define ARGI_PROCESSOR_OP ARGI_INVALID_OPCODE #define ARGI_QWORD_OP ARGI_INVALID_OPCODE @@ -315,7 +333,7 @@ #define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_FIXED_TARGET) #define ARGI_TYPE_OP ARGI_LIST1 (ARGI_ANYTYPE) #define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE) -#define ARGI_VAR_PACKAGE_OP ARGI_INVALID_OPCODE +#define ARGI_VAR_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER) #define ARGI_WHILE_OP ARGI_INVALID_OPCODE #define ARGI_WORD_OP ARGI_INVALID_OPCODE @@ -328,7 +346,7 @@ /****************************************************************************** - Opcodes that have associated namespace objects + Opcodes that have associated namespace objects (AML_NSOBJECT flag) AML_SCOPE_OP AML_DEVICE_OP @@ -354,7 +372,7 @@ AML_INT_METHODCALL_OP AML_INT_NAMEPATH_OP - Opcodes that are "namespace" opcodes + Opcodes that are "namespace" opcodes (AML_NSOPCODE flag) AML_SCOPE_OP AML_DEVICE_OP @@ -372,7 +390,7 @@ AML_REGION_OP AML_INT_NAMEDFIELD_OP - Opcodes that have an associated namespace node + Opcodes that have an associated namespace node (AML_NSNODE flag) AML_SCOPE_OP AML_DEVICE_OP @@ -395,7 +413,7 @@ AML_INT_METHODCALL_OP AML_INT_NAMEPATH_OP - Opcodes that define named ACPI objects + Opcodes that define named ACPI objects (AML_NAMED flag) AML_SCOPE_OP AML_DEVICE_OP @@ -410,8 +428,8 @@ AML_REGION_OP AML_INT_NAMEDFIELD_OP - Opcodes that contain executable AML as part of the definition that - must be deferred until needed + Opcodes that contain executable AML as part of the definition that + must be deferred until needed AML_METHOD_OP AML_VAR_PACKAGE_OP @@ -422,6 +440,7 @@ AML_CREATE_DWORD_FIELD_OP AML_CREATE_QWORD_FIELD_OP AML_REGION_OP + AML_BUFFER_OP Field opcodes @@ -447,146 +466,149 @@ */ -static const acpi_opcode_info aml_op_info[] = +const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { -/* Index Name Parser Args Interpreter Args Class Type Flags */ +/*! [Begin] no source code translation */ +/* Index Name Parser Args Interpreter Args ObjectType Class Type Flags */ -/* 00 */ ACPI_OP ("Zero", ARGP_ZERO_OP, ARGI_ZERO_OP, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0), -/* 01 */ ACPI_OP ("One", ARGP_ONE_OP, ARGI_ONE_OP, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0), -/* 02 */ ACPI_OP ("Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 03 */ ACPI_OP ("Name", ARGP_NAME_OP, ARGI_NAME_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 04 */ ACPI_OP ("Byte_const", ARGP_BYTE_OP, ARGI_BYTE_OP, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0), -/* 05 */ ACPI_OP ("Word_const", ARGP_WORD_OP, ARGI_WORD_OP, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0), -/* 06 */ ACPI_OP ("Dword_const", ARGP_DWORD_OP, ARGI_DWORD_OP, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0), -/* 07 */ ACPI_OP ("String", ARGP_STRING_OP, ARGI_STRING_OP, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0), -/* 08 */ ACPI_OP ("Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 09 */ ACPI_OP ("Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP, AML_CLASS_ARGUMENT, AML_TYPE_DATA_TERM, AML_HAS_ARGS), -/* 0A */ ACPI_OP ("Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP, AML_CLASS_ARGUMENT, AML_TYPE_DATA_TERM, AML_HAS_ARGS), -/* 0B */ ACPI_OP ("Method", ARGP_METHOD_OP, ARGI_METHOD_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER), -/* 0C */ ACPI_OP ("Local0", ARGP_LOCAL0, ARGI_LOCAL0, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 0D */ ACPI_OP ("Local1", ARGP_LOCAL1, ARGI_LOCAL1, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 0E */ ACPI_OP ("Local2", ARGP_LOCAL2, ARGI_LOCAL2, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 0F */ ACPI_OP ("Local3", ARGP_LOCAL3, ARGI_LOCAL3, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 10 */ ACPI_OP ("Local4", ARGP_LOCAL4, ARGI_LOCAL4, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 11 */ ACPI_OP ("Local5", ARGP_LOCAL5, ARGI_LOCAL5, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 12 */ ACPI_OP ("Local6", ARGP_LOCAL6, ARGI_LOCAL6, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 13 */ ACPI_OP ("Local7", ARGP_LOCAL7, ARGI_LOCAL7, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), -/* 14 */ ACPI_OP ("Arg0", ARGP_ARG0, ARGI_ARG0, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), -/* 15 */ ACPI_OP ("Arg1", ARGP_ARG1, ARGI_ARG1, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), -/* 16 */ ACPI_OP ("Arg2", ARGP_ARG2, ARGI_ARG2, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), -/* 17 */ ACPI_OP ("Arg3", ARGP_ARG3, ARGI_ARG3, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), -/* 18 */ ACPI_OP ("Arg4", ARGP_ARG4, ARGI_ARG4, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), -/* 19 */ ACPI_OP ("Arg5", ARGP_ARG5, ARGI_ARG5, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), -/* 1_a */ ACPI_OP ("Arg6", ARGP_ARG6, ARGI_ARG6, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), -/* 1_b */ ACPI_OP ("Store", ARGP_STORE_OP, ARGI_STORE_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 1_c */ ACPI_OP ("Ref_of", ARGP_REF_OF_OP, ARGI_REF_OF_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 1_d */ ACPI_OP ("Add", ARGP_ADD_OP, ARGI_ADD_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 1_e */ ACPI_OP ("Concatenate", ARGP_CONCAT_OP, ARGI_CONCAT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R), -/* 1_f */ ACPI_OP ("Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 20 */ ACPI_OP ("Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 21 */ ACPI_OP ("Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 22 */ ACPI_OP ("Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 23 */ ACPI_OP ("Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_2T_1R, AML_FLAGS_EXEC_2A_2T_1R), -/* 24 */ ACPI_OP ("Shift_left", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 25 */ ACPI_OP ("Shift_right", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 26 */ ACPI_OP ("And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 27 */ ACPI_OP ("NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 28 */ ACPI_OP ("Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 29 */ ACPI_OP ("NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 2_a */ ACPI_OP ("XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH), -/* 2_b */ ACPI_OP ("Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 2_c */ ACPI_OP ("Find_set_left_bit", ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 2_d */ ACPI_OP ("Find_set_right_bit", ARGP_FIND_SET_RIGHT_BIT_OP,ARGI_FIND_SET_RIGHT_BIT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 2_e */ ACPI_OP ("Deref_of", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 2_f */ ACPI_OP ("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R), -/* 30 */ ACPI_OP ("Size_of", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R), -/* 32 */ ACPI_OP ("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), -/* 33 */ ACPI_OP ("Create_dWord_field", ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), -/* 34 */ ACPI_OP ("Create_word_field", ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), -/* 35 */ ACPI_OP ("Create_byte_field", ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), -/* 36 */ ACPI_OP ("Create_bit_field", ARGP_CREATE_BIT_FIELD_OP, ARGI_CREATE_BIT_FIELD_OP, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), -/* 37 */ ACPI_OP ("Object_type", ARGP_TYPE_OP, ARGI_TYPE_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL), -/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL), -/* 3_a */ ACPI_OP ("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 3_b */ ACPI_OP ("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL), -/* 3_c */ ACPI_OP ("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL), -/* 3_d */ ACPI_OP ("LLess", ARGP_LLESS_OP, ARGI_LLESS_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL), -/* 3_e */ ACPI_OP ("If", ARGP_IF_OP, ARGI_IF_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), -/* 3_f */ ACPI_OP ("Else", ARGP_ELSE_OP, ARGI_ELSE_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), -/* 40 */ ACPI_OP ("While", ARGP_WHILE_OP, ARGI_WHILE_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), -/* 41 */ ACPI_OP ("Noop", ARGP_NOOP_OP, ARGI_NOOP_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), -/* 42 */ ACPI_OP ("Return", ARGP_RETURN_OP, ARGI_RETURN_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), -/* 43 */ ACPI_OP ("Break", ARGP_BREAK_OP, ARGI_BREAK_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), -/* 44 */ ACPI_OP ("Break_point", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), -/* 45 */ ACPI_OP ("Ones", ARGP_ONES_OP, ARGI_ONES_OP, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0), +/* 00 */ ACPI_OP ("Zero", ARGP_ZERO_OP, ARGI_ZERO_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT), +/* 01 */ ACPI_OP ("One", ARGP_ONE_OP, ARGI_ONE_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT), +/* 02 */ ACPI_OP ("Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP, ACPI_TYPE_LOCAL_ALIAS, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 03 */ ACPI_OP ("Name", ARGP_NAME_OP, ARGI_NAME_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 04 */ ACPI_OP ("ByteConst", ARGP_BYTE_OP, ARGI_BYTE_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT), +/* 05 */ ACPI_OP ("WordConst", ARGP_WORD_OP, ARGI_WORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT), +/* 06 */ ACPI_OP ("DwordConst", ARGP_DWORD_OP, ARGI_DWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT), +/* 07 */ ACPI_OP ("String", ARGP_STRING_OP, ARGI_STRING_OP, ACPI_TYPE_STRING, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT), +/* 08 */ ACPI_OP ("Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_LOCAL_SCOPE, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 09 */ ACPI_OP ("Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP, ACPI_TYPE_BUFFER, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER | AML_CONSTANT), +/* 0A */ ACPI_OP ("Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER | AML_CONSTANT), +/* 0B */ ACPI_OP ("Method", ARGP_METHOD_OP, ARGI_METHOD_OP, ACPI_TYPE_METHOD, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER), +/* 0C */ ACPI_OP ("Local0", ARGP_LOCAL0, ARGI_LOCAL0, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 0D */ ACPI_OP ("Local1", ARGP_LOCAL1, ARGI_LOCAL1, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 0E */ ACPI_OP ("Local2", ARGP_LOCAL2, ARGI_LOCAL2, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 0F */ ACPI_OP ("Local3", ARGP_LOCAL3, ARGI_LOCAL3, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 10 */ ACPI_OP ("Local4", ARGP_LOCAL4, ARGI_LOCAL4, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 11 */ ACPI_OP ("Local5", ARGP_LOCAL5, ARGI_LOCAL5, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 12 */ ACPI_OP ("Local6", ARGP_LOCAL6, ARGI_LOCAL6, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 13 */ ACPI_OP ("Local7", ARGP_LOCAL7, ARGI_LOCAL7, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LOCAL_VARIABLE, 0), +/* 14 */ ACPI_OP ("Arg0", ARGP_ARG0, ARGI_ARG0, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), +/* 15 */ ACPI_OP ("Arg1", ARGP_ARG1, ARGI_ARG1, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), +/* 16 */ ACPI_OP ("Arg2", ARGP_ARG2, ARGI_ARG2, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), +/* 17 */ ACPI_OP ("Arg3", ARGP_ARG3, ARGI_ARG3, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), +/* 18 */ ACPI_OP ("Arg4", ARGP_ARG4, ARGI_ARG4, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), +/* 19 */ ACPI_OP ("Arg5", ARGP_ARG5, ARGI_ARG5, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), +/* 1A */ ACPI_OP ("Arg6", ARGP_ARG6, ARGI_ARG6, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_METHOD_ARGUMENT, 0), +/* 1B */ ACPI_OP ("Store", ARGP_STORE_OP, ARGI_STORE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), +/* 1C */ ACPI_OP ("RefOf", ARGP_REF_OF_OP, ARGI_REF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), +/* 1D */ ACPI_OP ("Add", ARGP_ADD_OP, ARGI_ADD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 1E */ ACPI_OP ("Concatenate", ARGP_CONCAT_OP, ARGI_CONCAT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), +/* 1F */ ACPI_OP ("Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 20 */ ACPI_OP ("Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT), +/* 21 */ ACPI_OP ("Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT), +/* 22 */ ACPI_OP ("Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 23 */ ACPI_OP ("Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_2T_1R, AML_FLAGS_EXEC_2A_2T_1R | AML_CONSTANT), +/* 24 */ ACPI_OP ("ShiftLeft", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 25 */ ACPI_OP ("ShiftRight", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 26 */ ACPI_OP ("And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 27 */ ACPI_OP ("NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 28 */ ACPI_OP ("Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 29 */ ACPI_OP ("NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 2A */ ACPI_OP ("XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT), +/* 2B */ ACPI_OP ("Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 2C */ ACPI_OP ("FindSetLeftBit", ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 2D */ ACPI_OP ("FindSetRightBit", ARGP_FIND_SET_RIGHT_BIT_OP,ARGI_FIND_SET_RIGHT_BIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 2E */ ACPI_OP ("DerefOf", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), +/* 2F */ ACPI_OP ("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R), +/* 30 */ ACPI_OP ("SizeOf", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), +/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), +/* 32 */ ACPI_OP ("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT), +/* 33 */ ACPI_OP ("CreateDWordField", ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), +/* 34 */ ACPI_OP ("CreateWordField", ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), +/* 35 */ ACPI_OP ("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), +/* 36 */ ACPI_OP ("CreateBitField", ARGP_CREATE_BIT_FIELD_OP, ARGI_CREATE_BIT_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), +/* 37 */ ACPI_OP ("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), +/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), +/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), +/* 3A */ ACPI_OP ("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT), +/* 3B */ ACPI_OP ("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), +/* 3C */ ACPI_OP ("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), +/* 3D */ ACPI_OP ("LLess", ARGP_LLESS_OP, ARGI_LLESS_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), +/* 3E */ ACPI_OP ("If", ARGP_IF_OP, ARGI_IF_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), +/* 3F */ ACPI_OP ("Else", ARGP_ELSE_OP, ARGI_ELSE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), +/* 40 */ ACPI_OP ("While", ARGP_WHILE_OP, ARGI_WHILE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), +/* 41 */ ACPI_OP ("Noop", ARGP_NOOP_OP, ARGI_NOOP_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), +/* 42 */ ACPI_OP ("Return", ARGP_RETURN_OP, ARGI_RETURN_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS), +/* 43 */ ACPI_OP ("Break", ARGP_BREAK_OP, ARGI_BREAK_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), +/* 44 */ ACPI_OP ("BreakPoint", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), +/* 45 */ ACPI_OP ("Ones", ARGP_ONES_OP, ARGI_ONES_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT), /* Prefixed opcodes (Two-byte opcodes with a prefix op) */ -/* 46 */ ACPI_OP ("Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 47 */ ACPI_OP ("Event", ARGP_EVENT_OP, ARGI_EVENT_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ), -/* 48 */ ACPI_OP ("Cond_ref_of", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 49 */ ACPI_OP ("Create_field", ARGP_CREATE_FIELD_OP, ARGI_CREATE_FIELD_OP, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_FIELD | AML_CREATE), -/* 4_a */ ACPI_OP ("Load", ARGP_LOAD_OP, ARGI_LOAD_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_0R, AML_FLAGS_EXEC_1A_1T_0R), -/* 4_b */ ACPI_OP ("Stall", ARGP_STALL_OP, ARGI_STALL_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), -/* 4_c */ ACPI_OP ("Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), -/* 4_d */ ACPI_OP ("Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R), -/* 4_e */ ACPI_OP ("Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), -/* 4_f */ ACPI_OP ("Wait", ARGP_WAIT_OP, ARGI_WAIT_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R), -/* 50 */ ACPI_OP ("Reset", ARGP_RESET_OP, ARGI_RESET_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), -/* 51 */ ACPI_OP ("Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), -/* 52 */ ACPI_OP ("From_bCD", ARGP_FROM_BCD_OP, ARGI_FROM_BCD_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 53 */ ACPI_OP ("To_bCD", ARGP_TO_BCD_OP, ARGI_TO_BCD_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 54 */ ACPI_OP ("Unload", ARGP_UNLOAD_OP, ARGI_UNLOAD_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), -/* 55 */ ACPI_OP ("Revision", ARGP_REVISION_OP, ARGI_REVISION_OP, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0), -/* 56 */ ACPI_OP ("Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0), -/* 57 */ ACPI_OP ("Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_0T_0R, AML_FLAGS_EXEC_3A_0T_0R), -/* 58 */ ACPI_OP ("Op_region", ARGP_REGION_OP, ARGI_REGION_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER), -/* 59 */ ACPI_OP ("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), -/* 5_a */ ACPI_OP ("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 5_b */ ACPI_OP ("Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 5_c */ ACPI_OP ("Power_resource", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 5_d */ ACPI_OP ("Thermal_zone", ARGP_THERMAL_ZONE_OP, ARGI_THERMAL_ZONE_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 5_e */ ACPI_OP ("Index_field", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), -/* 5_f */ ACPI_OP ("Bank_field", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), +/* 46 */ ACPI_OP ("Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP, ACPI_TYPE_MUTEX, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 47 */ ACPI_OP ("Event", ARGP_EVENT_OP, ARGI_EVENT_OP, ACPI_TYPE_EVENT, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ), +/* 48 */ ACPI_OP ("CondRefOf", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), +/* 49 */ ACPI_OP ("CreateField", ARGP_CREATE_FIELD_OP, ARGI_CREATE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_FIELD | AML_CREATE), +/* 4A */ ACPI_OP ("Load", ARGP_LOAD_OP, ARGI_LOAD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_0R, AML_FLAGS_EXEC_1A_1T_0R), +/* 4B */ ACPI_OP ("Stall", ARGP_STALL_OP, ARGI_STALL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), +/* 4C */ ACPI_OP ("Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), +/* 4D */ ACPI_OP ("Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R), +/* 4E */ ACPI_OP ("Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), +/* 4F */ ACPI_OP ("Wait", ARGP_WAIT_OP, ARGI_WAIT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R), +/* 50 */ ACPI_OP ("Reset", ARGP_RESET_OP, ARGI_RESET_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), +/* 51 */ ACPI_OP ("Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), +/* 52 */ ACPI_OP ("FromBCD", ARGP_FROM_BCD_OP, ARGI_FROM_BCD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 53 */ ACPI_OP ("ToBCD", ARGP_TO_BCD_OP, ARGI_TO_BCD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 54 */ ACPI_OP ("Unload", ARGP_UNLOAD_OP, ARGI_UNLOAD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R), +/* 55 */ ACPI_OP ("Revision", ARGP_REVISION_OP, ARGI_REVISION_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0), +/* 56 */ ACPI_OP ("Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, 0), +/* 57 */ ACPI_OP ("Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_0T_0R, AML_FLAGS_EXEC_3A_0T_0R), +/* 58 */ ACPI_OP ("OperationRegion", ARGP_REGION_OP, ARGI_REGION_OP, ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER), +/* 59 */ ACPI_OP ("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), +/* 5A */ ACPI_OP ("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP, ACPI_TYPE_DEVICE, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 5B */ ACPI_OP ("Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP, ACPI_TYPE_PROCESSOR, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 5C */ ACPI_OP ("PowerResource", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP, ACPI_TYPE_POWER, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 5D */ ACPI_OP ("ThermalZone", ARGP_THERMAL_ZONE_OP, ARGI_THERMAL_ZONE_OP, ACPI_TYPE_THERMAL, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 5E */ ACPI_OP ("IndexField", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), +/* 5F */ ACPI_OP ("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), /* Internal opcodes that map to invalid AML opcodes */ -/* 60 */ ACPI_OP ("LNot_equal", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS), -/* 61 */ ACPI_OP ("LLess_equal", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS), -/* 62 */ ACPI_OP ("LGreater_equal", ARGP_LGREATEREQUAL_OP, ARGI_LGREATEREQUAL_OP, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS), -/* 63 */ ACPI_OP ("[Name_path]", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_NSOBJECT | AML_NSNODE ), -/* 64 */ ACPI_OP ("[Method_call]", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP, AML_CLASS_METHOD_CALL, AML_TYPE_METHOD_CALL, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE), -/* 65 */ ACPI_OP ("[Byte_list]", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0), -/* 66 */ ACPI_OP ("[Reserved_field]", ARGP_RESERVEDFIELD_OP, ARGI_RESERVEDFIELD_OP, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0), -/* 67 */ ACPI_OP ("[Named_field]", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ), -/* 68 */ ACPI_OP ("[Access_field]", ARGP_ACCESSFIELD_OP, ARGI_ACCESSFIELD_OP, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0), -/* 69 */ ACPI_OP ("[Static_string", ARGP_STATICSTRING_OP, ARGI_STATICSTRING_OP, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0), -/* 6_a */ ACPI_OP ("[Return Value]", ARG_NONE, ARG_NONE, AML_CLASS_RETURN_VALUE, AML_TYPE_RETURN, AML_HAS_ARGS | AML_HAS_RETVAL), -/* 6_b */ ACPI_OP ("UNKNOWN_OP!", ARG_NONE, ARG_NONE, AML_CLASS_UNKNOWN, AML_TYPE_BOGUS, AML_HAS_ARGS), -/* 6_c */ ACPI_OP ("ASCII_ONLY!", ARG_NONE, ARG_NONE, AML_CLASS_ASCII, AML_TYPE_BOGUS, AML_HAS_ARGS), -/* 6_d */ ACPI_OP ("PREFIX_ONLY!", ARG_NONE, ARG_NONE, AML_CLASS_PREFIX, AML_TYPE_BOGUS, AML_HAS_ARGS), +/* 60 */ ACPI_OP ("LNotEqual", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT), +/* 61 */ ACPI_OP ("LLessEqual", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT), +/* 62 */ ACPI_OP ("LGreaterEqual", ARGP_LGREATEREQUAL_OP, ARGI_LGREATEREQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT), +/* 63 */ ACPI_OP ("-NamePath-", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP, ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_NSOBJECT | AML_NSNODE ), +/* 64 */ ACPI_OP ("-MethodCall-", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP, ACPI_TYPE_METHOD, AML_CLASS_METHOD_CALL, AML_TYPE_METHOD_CALL, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE), +/* 65 */ ACPI_OP ("-ByteList-", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP, ACPI_TYPE_ANY, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0), +/* 66 */ ACPI_OP ("-ReservedField-", ARGP_RESERVEDFIELD_OP, ARGI_RESERVEDFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0), +/* 67 */ ACPI_OP ("-NamedField-", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ), +/* 68 */ ACPI_OP ("-AccessField-", ARGP_ACCESSFIELD_OP, ARGI_ACCESSFIELD_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0), +/* 69 */ ACPI_OP ("-StaticString", ARGP_STATICSTRING_OP, ARGI_STATICSTRING_OP, ACPI_TYPE_ANY, AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0), +/* 6A */ ACPI_OP ("-Return Value-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_RETURN_VALUE, AML_TYPE_RETURN, AML_HAS_ARGS | AML_HAS_RETVAL), +/* 6B */ ACPI_OP ("-UNKNOWN_OP-", ARG_NONE, ARG_NONE, ACPI_TYPE_INVALID, AML_CLASS_UNKNOWN, AML_TYPE_BOGUS, AML_HAS_ARGS), +/* 6C */ ACPI_OP ("-ASCII_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_ASCII, AML_TYPE_BOGUS, AML_HAS_ARGS), +/* 6D */ ACPI_OP ("-PREFIX_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_PREFIX, AML_TYPE_BOGUS, AML_HAS_ARGS), /* ACPI 2.0 opcodes */ -/* 6_e */ ACPI_OP ("Qword_const", ARGP_QWORD_OP, ARGI_QWORD_OP, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, 0), -/* 6_f */ ACPI_OP ("Var_package", ARGP_VAR_PACKAGE_OP, ARGI_VAR_PACKAGE_OP, AML_CLASS_ARGUMENT, AML_TYPE_DATA_TERM, AML_HAS_ARGS | AML_DEFER), -/* 70 */ ACPI_OP ("Concat_res", ARGP_CONCAT_RES_OP, ARGI_CONCAT_RES_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R), -/* 71 */ ACPI_OP ("Mod", ARGP_MOD_OP, ARGI_MOD_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R), -/* 72 */ ACPI_OP ("Create_qWord_field", ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), -/* 73 */ ACPI_OP ("To_buffer", ARGP_TO_BUFFER_OP, ARGI_TO_BUFFER_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 74 */ ACPI_OP ("To_decimal_string", ARGP_TO_DEC_STR_OP, ARGI_TO_DEC_STR_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 75 */ ACPI_OP ("To_hex_string", ARGP_TO_HEX_STR_OP, ARGI_TO_HEX_STR_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 76 */ ACPI_OP ("To_integer", ARGP_TO_INTEGER_OP, ARGI_TO_INTEGER_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 77 */ ACPI_OP ("To_string", ARGP_TO_STRING_OP, ARGI_TO_STRING_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R), -/* 78 */ ACPI_OP ("Copy_object", ARGP_COPY_OP, ARGI_COPY_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), -/* 79 */ ACPI_OP ("Mid", ARGP_MID_OP, ARGI_MID_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_1T_1R, AML_FLAGS_EXEC_3A_1T_1R), -/* 7_a */ ACPI_OP ("Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), -/* 7_b */ ACPI_OP ("Load_table", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), -/* 7_c */ ACPI_OP ("Data_op_region", ARGP_DATA_REGION_OP, ARGI_DATA_REGION_OP, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), +/* 6E */ ACPI_OP ("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT), +/* 6F */ ACPI_OP ("Package /*Var*/", ARGP_VAR_PACKAGE_OP, ARGI_VAR_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER), +/* 70 */ ACPI_OP ("ConcatenateResTemplate", ARGP_CONCAT_RES_OP, ARGI_CONCAT_RES_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), +/* 71 */ ACPI_OP ("Mod", ARGP_MOD_OP, ARGI_MOD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), +/* 72 */ ACPI_OP ("CreateQWordField", ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), +/* 73 */ ACPI_OP ("ToBuffer", ARGP_TO_BUFFER_OP, ARGI_TO_BUFFER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 74 */ ACPI_OP ("ToDecimalString", ARGP_TO_DEC_STR_OP, ARGI_TO_DEC_STR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 75 */ ACPI_OP ("ToHexString", ARGP_TO_HEX_STR_OP, ARGI_TO_HEX_STR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 76 */ ACPI_OP ("ToInteger", ARGP_TO_INTEGER_OP, ARGI_TO_INTEGER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT), +/* 77 */ ACPI_OP ("ToString", ARGP_TO_STRING_OP, ARGI_TO_STRING_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), +/* 78 */ ACPI_OP ("CopyObject", ARGP_COPY_OP, ARGI_COPY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R), +/* 79 */ ACPI_OP ("Mid", ARGP_MID_OP, ARGI_MID_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_1T_1R, AML_FLAGS_EXEC_3A_1T_1R | AML_CONSTANT), +/* 7A */ ACPI_OP ("Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), +/* 7B */ ACPI_OP ("LoadTable", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), +/* 7C */ ACPI_OP ("DataTableRegion", ARGP_DATA_REGION_OP, ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), +/* 7D */ ACPI_OP ("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE) +/*! [End] no source code translation !*/ }; /* @@ -594,7 +616,7 @@ * index into the table above */ -static const u8 aml_short_op_info_index[256] = +static const u8 acpi_gbl_short_op_index[256] = { /* 0 1 2 3 4 5 6 7 */ /* 8 9 A B C D E F */ @@ -604,7 +626,7 @@ /* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX, -/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, _UNK, +/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D, /* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, /* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, @@ -633,7 +655,7 @@ }; -static const u8 aml_long_op_info_index[NUM_EXTENDED_OPCODE] = +static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = { /* 0 1 2 3 4 5 6 7 */ /* 8 9 A B C D E F */ @@ -660,7 +682,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_get_opcode_info + * FUNCTION: acpi_ps_get_opcode_info * * PARAMETERS: Opcode - The AML opcode * @@ -672,67 +694,50 @@ * ******************************************************************************/ -const acpi_opcode_info * +const struct acpi_opcode_info * acpi_ps_get_opcode_info ( - u16 opcode) + u16 opcode) { - const acpi_opcode_info *op_info; - u8 upper_opcode; - u8 lower_opcode; - - - PROC_NAME ("Ps_get_opcode_info"); - - - /* Split the 16-bit opcode into separate bytes */ - - upper_opcode = (u8) (opcode >> 8); - lower_opcode = (u8) opcode; - - /* Default is "unknown opcode" */ - - op_info = &aml_op_info [_UNK]; + ACPI_FUNCTION_NAME ("ps_get_opcode_info"); /* * Detect normal 8-bit opcode or extended 16-bit opcode */ - - switch (upper_opcode) { + switch ((u8) (opcode >> 8)) { case 0: /* Simple (8-bit) opcode: 0-255, can't index beyond table */ - op_info = &aml_op_info [aml_short_op_info_index [lower_opcode]]; - break; - + return (&acpi_gbl_aml_op_info [acpi_gbl_short_op_index [(u8) opcode]]); case AML_EXTOP: /* Extended (16-bit, prefix+opcode) opcode */ - if (lower_opcode <= MAX_EXTENDED_OPCODE) { - op_info = &aml_op_info [aml_long_op_info_index [lower_opcode]]; + if (((u8) opcode) <= MAX_EXTENDED_OPCODE) { + return (&acpi_gbl_aml_op_info [acpi_gbl_long_op_index [(u8) opcode]]); } - break; + /* Else fall through to error case below */ + /*lint -fallthrough */ default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown extended opcode=%X\n", opcode)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown extended opcode [%X]\n", opcode)); break; } - /* Get the Op info pointer for this opcode */ + /* Default is "unknown opcode" */ - return (op_info); + return (&acpi_gbl_aml_op_info [_UNK]); } /******************************************************************************* * - * FUNCTION: Acpi_ps_get_opcode_name + * FUNCTION: acpi_ps_get_opcode_name * * PARAMETERS: Opcode - The AML opcode * @@ -743,22 +748,24 @@ * ******************************************************************************/ -NATIVE_CHAR * +char * acpi_ps_get_opcode_name ( - u16 opcode) + u16 opcode) { - const acpi_opcode_info *op; +#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT) + + const struct acpi_opcode_info *op; op = acpi_ps_get_opcode_info (opcode); /* Always guaranteed to return a valid pointer */ -#ifdef ACPI_DEBUG return (op->name); + #else return ("AE_NOT_CONFIGURED"); + #endif } - diff -urN linux-2.4.21/drivers/acpi/parser/psparse.c linux-2.4.22/drivers/acpi/parser/psparse.c --- linux-2.4.21/drivers/acpi/parser/psparse.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/psparse.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,26 +1,44 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 104 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ @@ -30,28 +48,26 @@ * generated parser to tightly constrain stack and dynamic memory * usage. At the same time, parsing is kept flexible and the code * fairly compact by parsing based on a list of AML opcode - * templates in Aml_op_info[] + * templates in aml_op_info[] */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acdebug.h" -#include "acinterp.h" +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("psparse") + ACPI_MODULE_NAME ("psparse") -u32 acpi_gbl_depth = 0; -extern u32 acpi_gbl_scope_depth; +static u32 acpi_gbl_depth = 0; /******************************************************************************* * - * FUNCTION: Acpi_ps_get_opcode_size + * FUNCTION: acpi_ps_get_opcode_size * * PARAMETERS: Opcode - An AML opcode * @@ -61,9 +77,9 @@ * ******************************************************************************/ -static u32 +u32 acpi_ps_get_opcode_size ( - u32 opcode) + u32 opcode) { /* Extended (2-byte) opcode if > 255 */ @@ -80,9 +96,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_peek_opcode + * FUNCTION: acpi_ps_peek_opcode * - * PARAMETERS: Parser_state - A parser state object + * PARAMETERS: parser_state - A parser state object * * RETURN: Status * @@ -92,122 +108,59 @@ u16 acpi_ps_peek_opcode ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { - u8 *aml; - u16 opcode; + u8 *aml; + u16 opcode; aml = parser_state->aml; - opcode = (u16) GET8 (aml); + opcode = (u16) ACPI_GET8 (aml); - aml++; - - /* - * Original code special cased LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL. - * These opcodes are no longer recognized. Instead, they are broken into - * two opcodes. - * - * - * if (Opcode == AML_EXTOP - * || (Opcode == AML_LNOT - * && (GET8 (Aml) == AML_LEQUAL - * || GET8 (Aml) == AML_LGREATER - * || GET8 (Aml) == AML_LLESS))) - * - * extended Opcode, !=, <=, or >= - */ if (opcode == AML_EXTOP) { /* Extended opcode */ - opcode = (u16) ((opcode << 8) | GET8 (aml)); + aml++; + opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml)); } - return (opcode); } /******************************************************************************* * - * FUNCTION: Acpi_ps_find_object - * - * PARAMETERS: Opcode - Current opcode - * Parser_state - Current state - * Walk_state - Current state - * *Op - Where found/new op is returned - * - * RETURN: Status - * - * DESCRIPTION: Find a named object. Two versions - one to search the parse - * tree (for parser-only applications such as acpidump), another - * to search the ACPI internal namespace (the parse tree may no - * longer exist) - * - ******************************************************************************/ - -#ifdef PARSER_ONLY - -acpi_status -acpi_ps_find_object ( - acpi_walk_state *walk_state, - acpi_parse_object **out_op) -{ - NATIVE_CHAR *path; - - - /* We are only interested in opcodes that have an associated name */ - - if (!(walk_state->op_info->flags & AML_NAMED)) { - *out_op = walk_state->op; - return (AE_OK); - } - - /* Find the name in the parse tree */ - - path = acpi_ps_get_next_namestring (&walk_state->parser_state); - - *out_op = acpi_ps_find (acpi_ps_get_parent_scope (&walk_state->parser_state), - path, walk_state->opcode, 1); - - if (!(*out_op)) { - return (AE_NOT_FOUND); - } - - return (AE_OK); -} - -#endif - - -/******************************************************************************* + * FUNCTION: acpi_ps_complete_this_op * - * FUNCTION: Acpi_ps_complete_this_op - * - * PARAMETERS: Walk_state - Current State + * PARAMETERS: walk_state - Current State * Op - Op to complete * - * RETURN: TRUE if Op and subtree was deleted + * RETURN: None. * * DESCRIPTION: Perform any cleanup at the completion of an Op. * ******************************************************************************/ -static u8 +void acpi_ps_complete_this_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op) + struct acpi_walk_state *walk_state, + union acpi_parse_object *op) { -#ifndef PARSER_ONLY - acpi_parse_object *prev; - acpi_parse_object *next; - const acpi_opcode_info *parent_info; - acpi_parse_object *replacement_op = NULL; + union acpi_parse_object *prev; + union acpi_parse_object *next; + const struct acpi_opcode_info *parent_info; + union acpi_parse_object *replacement_op = NULL; + + ACPI_FUNCTION_TRACE_PTR ("ps_complete_this_op", op); - FUNCTION_TRACE_PTR ("Ps_complete_this_op", op); + /* Check for null Op, can happen if AML code is corrupt */ + + if (!op) { + return_VOID; + } /* Delete this op and the subtree below it if asked to */ @@ -215,60 +168,84 @@ (walk_state->op_info->class != AML_CLASS_ARGUMENT)) { /* Make sure that we only delete this subtree */ - if (op->parent) { + if (op->common.parent) { /* * Check if we need to replace the operator and its subtree * with a return value op (placeholder op) */ - parent_info = acpi_ps_get_opcode_info (op->parent->opcode); + parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode); switch (parent_info->class) { - case AML_CLASS_CONTROL: /* IF, ELSE, WHILE only */ + case AML_CLASS_CONTROL: break; - case AML_CLASS_NAMED_OBJECT: /* Scope, method, etc. */ case AML_CLASS_CREATE: /* - * These opcodes contain Term_arg operands. The current - * op must be replace by a placeholder return op + * These opcodes contain term_arg operands. The current + * op must be replaced by a placeholder return op */ - if ((op->parent->opcode == AML_REGION_OP) || - (op->parent->opcode == AML_CREATE_FIELD_OP) || - (op->parent->opcode == AML_CREATE_BIT_FIELD_OP) || - (op->parent->opcode == AML_CREATE_BYTE_FIELD_OP) || - (op->parent->opcode == AML_CREATE_WORD_FIELD_OP) || - (op->parent->opcode == AML_CREATE_DWORD_FIELD_OP) || - (op->parent->opcode == AML_CREATE_QWORD_FIELD_OP)) { + replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); + if (!replacement_op) { + return_VOID; + } + break; + + case AML_CLASS_NAMED_OBJECT: + + /* + * These opcodes contain term_arg operands. The current + * op must be replaced by a placeholder return op + */ + if ((op->common.parent->common.aml_opcode == AML_REGION_OP) || + (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) || + (op->common.parent->common.aml_opcode == AML_BUFFER_OP) || + (op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || + (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); if (!replacement_op) { - return_VALUE (FALSE); + return_VOID; } } + if ((op->common.parent->common.aml_opcode == AML_NAME_OP) && + (walk_state->descending_callback != acpi_ds_exec_begin_op)) { + if ((op->common.aml_opcode == AML_BUFFER_OP) || + (op->common.aml_opcode == AML_PACKAGE_OP) || + (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) { + replacement_op = acpi_ps_alloc_op (op->common.aml_opcode); + if (!replacement_op) { + return_VOID; + } + + replacement_op->named.data = op->named.data; + replacement_op->named.length = op->named.length; + } + } break; default: replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); if (!replacement_op) { - return_VALUE (FALSE); + return_VOID; } } /* We must unlink this op from the parent tree */ - prev = op->parent->value.arg; + prev = op->common.parent->common.value.arg; if (prev == op) { /* This op is the first in the list */ if (replacement_op) { - replacement_op->parent = op->parent; - replacement_op->value.arg = NULL; - op->parent->value.arg = replacement_op; - replacement_op->next = op->next; + replacement_op->common.parent = op->common.parent; + replacement_op->common.value.arg = NULL; + replacement_op->common.node = op->common.node; + op->common.parent->common.value.arg = replacement_op; + replacement_op->common.next = op->common.next; } else { - op->parent->value.arg = op->next; + op->common.parent->common.value.arg = op->common.next; } } @@ -277,66 +254,61 @@ else while (prev) { /* Traverse all siblings in the parent's argument list */ - next = prev->next; + next = prev->common.next; if (next == op) { if (replacement_op) { - replacement_op->parent = op->parent; - replacement_op->value.arg = NULL; - prev->next = replacement_op; - replacement_op->next = op->next; + replacement_op->common.parent = op->common.parent; + replacement_op->common.value.arg = NULL; + replacement_op->common.node = op->common.node; + prev->common.next = replacement_op; + replacement_op->common.next = op->common.next; next = NULL; } else { - prev->next = op->next; + prev->common.next = op->common.next; next = NULL; } } prev = next; } - } /* Now we can actually delete the subtree rooted at op */ acpi_ps_delete_parse_tree (op); - return_VALUE (TRUE); + return_VOID; } - return_VALUE (FALSE); - -#else - return (FALSE); -#endif + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ps_next_parse_state + * FUNCTION: acpi_ps_next_parse_state * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * - * RETURN: + * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Update the parser state based upon the return exception from + * the parser callback. * ******************************************************************************/ -static acpi_status +acpi_status acpi_ps_next_parse_state ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_status callback_status) + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + acpi_status callback_status) { - acpi_parse_state *parser_state = &walk_state->parser_state; - acpi_status status = AE_CTRL_PENDING; - u8 *start; - u32 package_length; + struct acpi_parse_state *parser_state = &walk_state->parser_state; + acpi_status status = AE_CTRL_PENDING; - FUNCTION_TRACE_PTR ("Ps_next_parse_state", op); + ACPI_FUNCTION_TRACE_PTR ("ps_next_parse_state", op); switch (callback_status) { @@ -351,32 +323,40 @@ break; - case AE_CTRL_PENDING: + case AE_CTRL_BREAK: + + parser_state->aml = walk_state->aml_last_while; + walk_state->control_state->common.value = FALSE; + status = AE_CTRL_BREAK; + break; + + case AE_CTRL_CONTINUE: - /* - * Predicate of a WHILE was true and the loop just completed an - * execution. Go back to the start of the loop and reevaluate the - * predicate. - */ - /* TBD: How to handle a break within a while. */ - /* This code attempts it */ + parser_state->aml = walk_state->aml_last_while; + status = AE_CTRL_CONTINUE; + break; + + case AE_CTRL_PENDING: parser_state->aml = walk_state->aml_last_while; break; +#if 0 + case AE_CTRL_SKIP: + + parser_state->aml = parser_state->scope->parse_scope.pkg_end; + status = AE_OK; + break; +#endif case AE_CTRL_TRUE: + /* * Predicate of an IF was true, and we are at the matching ELSE. * Just close out this package - * - * Note: Parser_state->Aml is modified by the package length procedure - * TBD: [Investigate] perhaps it shouldn't, too much trouble */ - start = parser_state->aml; - package_length = acpi_ps_get_next_package_length (parser_state); - parser_state->aml = start + package_length; + parser_state->aml = acpi_ps_get_next_package_end (parser_state); break; @@ -406,7 +386,7 @@ status = AE_CTRL_TRANSFER; walk_state->prev_op = op; walk_state->method_call_op = op; - walk_state->method_call_node = (op->value.arg)->node; + walk_state->method_call_node = (op->common.value.arg)->common.node; /* Will return value (if any) be used by the caller? */ @@ -428,9 +408,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_parse_loop + * FUNCTION: acpi_ps_parse_loop * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: Status * @@ -441,24 +421,28 @@ acpi_status acpi_ps_parse_loop ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; - acpi_parse_object *op = NULL; /* current op */ - acpi_parse_object *arg = NULL; - acpi_parse_object pre_op; - acpi_parse_state *parser_state; - u8 *aml_op_start; + acpi_status status = AE_OK; + union acpi_parse_object *op = NULL; /* current op */ + union acpi_parse_object *arg = NULL; + union acpi_parse_object pre_op; + struct acpi_parse_state *parser_state; + u8 *aml_op_start = NULL; + + ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state); - FUNCTION_TRACE_PTR ("Ps_parse_loop", walk_state); + if (walk_state->descending_callback == NULL) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } parser_state = &walk_state->parser_state; walk_state->arg_types = 0; -#ifndef PARSER_ONLY - if (walk_state->walk_type & WALK_METHOD_RESTART) { +#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) + if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { /* We are restarting a preempted control method */ if (acpi_ps_has_completed_scope (parser_state)) { @@ -467,18 +451,17 @@ * was just completed */ if ((parser_state->scope->parse_scope.op) && - ((parser_state->scope->parse_scope.op->opcode == AML_IF_OP) || - (parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) && + ((parser_state->scope->parse_scope.op->common.aml_opcode == AML_IF_OP) || + (parser_state->scope->parse_scope.op->common.aml_opcode == AML_WHILE_OP)) && (walk_state->control_state) && (walk_state->control_state->common.state == - CONTROL_PREDICATE_EXECUTING)) { - + ACPI_CONTROL_PREDICATE_EXECUTING)) { /* * A predicate was just completed, get the value of the * predicate and branch based on that value */ walk_state->op = NULL; - status = acpi_ds_get_predicate_value (walk_state, TRUE); + status = acpi_ds_get_predicate_value (walk_state, ACPI_TO_POINTER (TRUE)); if (ACPI_FAILURE (status) && ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) { if (status == AE_AML_NO_RETURN_VALUE) { @@ -487,7 +470,7 @@ acpi_format_exception (status))); } - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Get_predicate Failed, %s\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "get_predicate Failed, %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); } @@ -495,10 +478,10 @@ status = acpi_ps_next_parse_state (walk_state, op, status); } - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op)); } - else if (walk_state->prev_op) { /* We were in the middle of an op */ @@ -512,12 +495,13 @@ * Iterative parsing loop, while there is more aml to process: */ while ((parser_state->aml < parser_state->aml_end) || (op)) { + aml_op_start = parser_state->aml; if (!op) { /* Get the next opcode from the AML stream */ - aml_op_start = parser_state->aml; - walk_state->aml_offset = parser_state->aml - parser_state->aml_start; - walk_state->opcode = acpi_ps_peek_opcode (parser_state); + walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml, + parser_state->aml_start); + walk_state->opcode = acpi_ps_peek_opcode (parser_state); /* * First cut to determine what we have found: @@ -542,10 +526,10 @@ /* The opcode is unrecognized. Just skip unknown opcodes */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Found unknown opcode %X at AML offset %X, ignoring\n", - walk_state->opcode, walk_state->aml_offset)); + "Found unknown opcode %X at AML address %p offset %X, ignoring\n", + walk_state->opcode, parser_state->aml, walk_state->aml_offset)); - DUMP_BUFFER (parser_state->aml, 128); + ACPI_DUMP_BUFFER (parser_state->aml, 128); /* Assume one-byte bad opcode */ @@ -559,70 +543,76 @@ parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode); walk_state->arg_types = walk_state->op_info->parse_args; break; - } - /* Create Op structure and append to parent's argument list */ if (walk_state->op_info->flags & AML_NAMED) { - pre_op.value.arg = NULL; - pre_op.opcode = walk_state->opcode; + pre_op.common.value.arg = NULL; + pre_op.common.aml_opcode = walk_state->opcode; + + /* + * Get and append arguments until we find the node that contains + * the name (the type ARGP_NAME). + */ + while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && + (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) { + status = acpi_ps_get_next_arg (walk_state, parser_state, + GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg); + if (ACPI_FAILURE (status)) { + goto close_this_op; + } - while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME) { - arg = acpi_ps_get_next_arg (parser_state, - GET_CURRENT_ARG_TYPE (walk_state->arg_types), - &walk_state->arg_count); acpi_ps_append_arg (&pre_op, arg); INCREMENT_ARG_LIST (walk_state->arg_types); } + /* Make sure that we found a NAME and didn't run out of arguments */ + + if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) { + return_ACPI_STATUS (AE_AML_NO_OPERAND); + } /* We know that this arg is a name, move to next arg */ INCREMENT_ARG_LIST (walk_state->arg_types); - if (walk_state->descending_callback != NULL) { - /* - * Find the object. This will either insert the object into - * the namespace or simply look it up - */ - walk_state->op = NULL; - - status = walk_state->descending_callback (walk_state, &op); + /* + * Find the object. This will either insert the object into + * the namespace or simply look it up + */ + walk_state->op = NULL; - /* TBD: check status here? */ + status = walk_state->descending_callback (walk_state, &op); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n", + acpi_format_exception (status))); + goto close_this_op; + } - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n", - acpi_format_exception (status))); - goto close_this_op; - } + if (op == NULL) { + continue; + } - if (op == NULL) { - continue; - } - status = acpi_ps_next_parse_state (walk_state, op, status); - if (status == AE_CTRL_PENDING) { - status = AE_OK; - goto close_this_op; - } + status = acpi_ps_next_parse_state (walk_state, op, status); + if (status == AE_CTRL_PENDING) { + status = AE_OK; + goto close_this_op; + } - if (ACPI_FAILURE (status)) { - goto close_this_op; - } + if (ACPI_FAILURE (status)) { + goto close_this_op; } - acpi_ps_append_arg (op, pre_op.value.arg); + acpi_ps_append_arg (op, pre_op.common.value.arg); acpi_gbl_depth++; - - if (op->opcode == AML_REGION_OP) { + if (op->common.aml_opcode == AML_REGION_OP) { /* - * Defer final parsing of an Operation_region body, + * Defer final parsing of an operation_region body, * because we don't have enough info in the first pass * to parse it correctly (i.e., there may be method - * calls within the Term_arg elements of the body. + * calls within the term_arg elements of the body.) * * However, we must continue parsing because * the opregion is not a standalone package -- @@ -630,12 +620,10 @@ * * (Length is unknown until parse of the body complete) */ - ((acpi_parse2_object * ) op)->data = aml_op_start; - ((acpi_parse2_object * ) op)->length = 0; + op->named.data = aml_op_start; + op->named.length = 0; } } - - else { /* Not a named opcode, just allocate Op and append to parent */ @@ -645,14 +633,13 @@ return_ACPI_STATUS (AE_NO_MEMORY); } - if (walk_state->op_info->flags & AML_CREATE) { /* - * Backup to beginning of Create_xXXfield declaration - * Body_length is unknown until we parse the body + * Backup to beginning of create_xXXfield declaration + * body_length is unknown until we parse the body */ - ((acpi_parse2_object * ) op)->data = aml_op_start; - ((acpi_parse2_object * ) op)->length = 0; + op->named.data = aml_op_start; + op->named.length = 0; } acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op); @@ -662,7 +649,7 @@ * Find the object. This will either insert the object into * the namespace or simply look it up */ - walk_state->op = op; + walk_state->op = op; status = walk_state->descending_callback (walk_state, &op); status = acpi_ps_next_parse_state (walk_state, op, status); @@ -677,40 +664,44 @@ } } - op->aml_offset = walk_state->aml_offset; + op->common.aml_offset = walk_state->aml_offset; if (walk_state->op_info) { ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "Op=%p Opcode=%4.4X Aml %p Oft=%5.5X\n", - op, op->opcode, parser_state->aml, op->aml_offset)); + "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n", + (u32) op->common.aml_opcode, walk_state->op_info->name, + op, parser_state->aml, op->common.aml_offset)); } } - /* Start Arg_count at zero because we don't know if there are any args yet */ + /* Start arg_count at zero because we don't know if there are any args yet */ walk_state->arg_count = 0; - if (walk_state->arg_types) /* Are there any arguments that must be processed? */ { - /* get arguments */ + /* Get arguments */ - switch (op->opcode) { + switch (op->common.aml_opcode) { case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ case AML_WORD_OP: /* AML_WORDDATA_ARG */ case AML_DWORD_OP: /* AML_DWORDATA_ARG */ case AML_QWORD_OP: /* AML_QWORDATA_ARG */ case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ - /* fill in constant or string argument directly */ + /* Fill in constant or string argument directly */ acpi_ps_get_next_simple_arg (parser_state, - GET_CURRENT_ARG_TYPE (walk_state->arg_types), op); + GET_CURRENT_ARG_TYPE (walk_state->arg_types), op); break; case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ - acpi_ps_get_next_namepath (parser_state, op, &walk_state->arg_count, 1); + status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1); + if (ACPI_FAILURE (status)) { + goto close_this_op; + } + walk_state->arg_types = 0; break; @@ -719,202 +710,268 @@ /* Op is not a constant or string, append each argument */ - while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && !walk_state->arg_count) { - walk_state->aml_offset = parser_state->aml - parser_state->aml_start; - arg = acpi_ps_get_next_arg (parser_state, - GET_CURRENT_ARG_TYPE (walk_state->arg_types), - &walk_state->arg_count); + while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && + !walk_state->arg_count) { + walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml, + parser_state->aml_start); + status = acpi_ps_get_next_arg (walk_state, parser_state, + GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg); + if (ACPI_FAILURE (status)) { + goto close_this_op; + } + if (arg) { - arg->aml_offset = walk_state->aml_offset; + arg->common.aml_offset = walk_state->aml_offset; acpi_ps_append_arg (op, arg); } - INCREMENT_ARG_LIST (walk_state->arg_types); } + switch (op->common.aml_opcode) { + case AML_METHOD_OP: - /* For a method, save the length and address of the body */ + /* For a method, save the length and address of the body */ - if (op->opcode == AML_METHOD_OP) { /* * Skip parsing of control method or opregion body, * because we don't have enough info in the first pass * to parse them correctly. */ - ((acpi_parse2_object * ) op)->data = parser_state->aml; - ((acpi_parse2_object * ) op)->length = (u32) (parser_state->pkg_end - - parser_state->aml); - + op->named.data = parser_state->aml; + op->named.length = (u32) (parser_state->pkg_end - parser_state->aml); /* - * Skip body of method. For Op_regions, we must continue + * Skip body of method. For op_regions, we must continue * parsing because the opregion is not a standalone * package (We don't know where the end is). */ parser_state->aml = parser_state->pkg_end; - walk_state->arg_count = 0; - } + walk_state->arg_count = 0; + break; + + case AML_BUFFER_OP: + case AML_PACKAGE_OP: + case AML_VAR_PACKAGE_OP: + + if ((op->common.parent) && + (op->common.parent->common.aml_opcode == AML_NAME_OP) && + (walk_state->descending_callback != acpi_ds_exec_begin_op)) { + /* + * Skip parsing of + * because we don't have enough info in the first pass + * to parse them correctly. + */ + op->named.data = aml_op_start; + op->named.length = (u32) (parser_state->pkg_end - aml_op_start); + /* + * Skip body + */ + parser_state->aml = parser_state->pkg_end; + walk_state->arg_count = 0; + } + break; + + case AML_WHILE_OP: + + if (walk_state->control_state) { + walk_state->control_state->control.package_end = parser_state->pkg_end; + } + break; + default: + /* No action for all other opcodes */ + break; + } break; } } + /* Check for arguments that need to be processed */ - /* - * Zero Arg_count means that all arguments for this op have been processed - */ - if (!walk_state->arg_count) { - /* completed Op, prepare for next */ + if (walk_state->arg_count) { + /* There are arguments (complex ones), push Op and prepare for argument */ - walk_state->op_info = acpi_ps_get_opcode_info (op->opcode); - if (walk_state->op_info->flags & AML_NAMED) { - if (acpi_gbl_depth) { - acpi_gbl_depth--; - } + status = acpi_ps_push_scope (parser_state, op, + walk_state->arg_types, walk_state->arg_count); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + op = NULL; + continue; + } - if (op->opcode == AML_REGION_OP) { - /* - * Skip parsing of control method or opregion body, - * because we don't have enough info in the first pass - * to parse them correctly. - * - * Completed parsing an Op_region declaration, we now - * know the length. - */ - ((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml - - ((acpi_parse2_object * ) op)->data); - } + /* All arguments have been processed -- Op is complete, prepare for next */ + + walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); + if (walk_state->op_info->flags & AML_NAMED) { + if (acpi_gbl_depth) { + acpi_gbl_depth--; } - if (walk_state->op_info->flags & AML_CREATE) { + if (op->common.aml_opcode == AML_REGION_OP) { /* - * Backup to beginning of Create_xXXfield declaration (1 for - * Opcode) + * Skip parsing of control method or opregion body, + * because we don't have enough info in the first pass + * to parse them correctly. * - * Body_length is unknown until we parse the body + * Completed parsing an op_region declaration, we now + * know the length. */ - ((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml - - ((acpi_parse2_object * ) op)->data); + op->named.length = (u32) (parser_state->aml - op->named.data); } + } - /* This op complete, notify the dispatcher */ + if (walk_state->op_info->flags & AML_CREATE) { + /* + * Backup to beginning of create_xXXfield declaration (1 for + * Opcode) + * + * body_length is unknown until we parse the body + */ + op->named.length = (u32) (parser_state->aml - op->named.data); + } - if (walk_state->ascending_callback != NULL) { - walk_state->op = op; - walk_state->opcode = op->opcode; + /* This op complete, notify the dispatcher */ - status = walk_state->ascending_callback (walk_state); - status = acpi_ps_next_parse_state (walk_state, op, status); - if (status == AE_CTRL_PENDING) { - status = AE_OK; - goto close_this_op; - } + if (walk_state->ascending_callback != NULL) { + walk_state->op = op; + walk_state->opcode = op->common.aml_opcode; + + status = walk_state->ascending_callback (walk_state); + status = acpi_ps_next_parse_state (walk_state, op, status); + if (status == AE_CTRL_PENDING) { + status = AE_OK; + goto close_this_op; } + } close_this_op: + /* + * Finished one argument of the containing scope + */ + parser_state->scope->parse_scope.arg_count--; - /* - * Finished one argument of the containing scope - */ - parser_state->scope->parse_scope.arg_count--; - - /* Close this Op (may result in parse subtree deletion) */ - - if (acpi_ps_complete_this_op (walk_state, op)) { - op = NULL; - } + /* Close this Op (will result in parse subtree deletion) */ + acpi_ps_complete_this_op (walk_state, op); + op = NULL; - switch (status) { - case AE_OK: - break; + switch (status) { + case AE_OK: + break; - case AE_CTRL_TRANSFER: + case AE_CTRL_TRANSFER: - /* - * We are about to transfer to a called method. - */ - walk_state->prev_op = op; - walk_state->prev_arg_types = walk_state->arg_types; - return_ACPI_STATUS (status); - break; + /* + * We are about to transfer to a called method. + */ + walk_state->prev_op = op; + walk_state->prev_arg_types = walk_state->arg_types; + return_ACPI_STATUS (status); - case AE_CTRL_END: + case AE_CTRL_END: - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); + if (op) { walk_state->op = op; - walk_state->op_info = acpi_ps_get_opcode_info (op->opcode); - walk_state->opcode = op->opcode; + walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); + walk_state->opcode = op->common.aml_opcode; status = walk_state->ascending_callback (walk_state); status = acpi_ps_next_parse_state (walk_state, op, status); acpi_ps_complete_this_op (walk_state, op); op = NULL; - status = AE_OK; - break; + } + status = AE_OK; + break; - case AE_CTRL_TERMINATE: + case AE_CTRL_BREAK: + case AE_CTRL_CONTINUE: - status = AE_OK; + /* Pop off scopes until we find the While */ - /* Clean up */ - do { - if (op) { - acpi_ps_complete_this_op (walk_state, op); - } + while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); + } - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); - } while (op); + /* Close this iteration of the While loop */ - return_ACPI_STATUS (status); - break; + walk_state->op = op; + walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); + walk_state->opcode = op->common.aml_opcode; + + status = walk_state->ascending_callback (walk_state); + status = acpi_ps_next_parse_state (walk_state, op, status); + + acpi_ps_complete_this_op (walk_state, op); + op = NULL; + status = AE_OK; + break; - default: /* All other non-AE_OK status */ - if (op == NULL) { - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); + case AE_CTRL_TERMINATE: + + status = AE_OK; + + /* Clean up */ + do { + if (op) { + acpi_ps_complete_this_op (walk_state, op); } - walk_state->prev_op = op; - walk_state->prev_arg_types = walk_state->arg_types; + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); - /* - * TEMP: - */ + } while (op); - return_ACPI_STATUS (status); - break; - } + return_ACPI_STATUS (status); - /* This scope complete? */ - if (acpi_ps_has_completed_scope (parser_state)) { - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op)); - } + default: /* All other non-AE_OK status */ - else { - op = NULL; - } + do { + if (op) { + acpi_ps_complete_this_op (walk_state, op); + } + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); - } + } while (op); - /* Arg_count is non-zero */ + /* + * TBD: Cleanup parse ops on error + */ +#if 0 + if (op == NULL) { + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); + } +#endif + walk_state->prev_op = op; + walk_state->prev_arg_types = walk_state->arg_types; + return_ACPI_STATUS (status); + } - else { - /* complex argument, push Op and prepare for argument */ + /* This scope complete? */ - acpi_ps_push_scope (parser_state, op, walk_state->arg_types, walk_state->arg_count); + if (acpi_ps_has_completed_scope (parser_state)) { + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op)); + } + else { op = NULL; } - } /* while Parser_state->Aml */ + } /* while parser_state->Aml */ /* @@ -928,8 +985,8 @@ if (op) { if (walk_state->ascending_callback != NULL) { walk_state->op = op; - walk_state->op_info = acpi_ps_get_opcode_info (op->opcode); - walk_state->opcode = op->opcode; + walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); + walk_state->opcode = op->common.aml_opcode; status = walk_state->ascending_callback (walk_state); status = acpi_ps_next_parse_state (walk_state, op, status); @@ -947,7 +1004,8 @@ acpi_ps_complete_this_op (walk_state, op); } - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); + acpi_ps_pop_scope (parser_state, &op, + &walk_state->arg_types, &walk_state->arg_count); } while (op); @@ -963,7 +1021,8 @@ acpi_ps_complete_this_op (walk_state, op); } - acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); + acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, + &walk_state->arg_count); } while (op); @@ -973,12 +1032,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_parse_aml + * FUNCTION: acpi_ps_parse_aml * - * PARAMETERS: Start_scope - The starting point of the parse. Becomes the + * PARAMETERS: start_scope - The starting point of the parse. Becomes the * root of the parsed op tree. * Aml - Pointer to the raw AML code to parse - * Aml_size - Length of the AML to parse + * aml_size - Length of the AML to parse * * * RETURN: Status @@ -989,33 +1048,36 @@ acpi_status acpi_ps_parse_aml ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { - acpi_status status; - acpi_walk_list walk_list; - acpi_walk_list *prev_walk_list = acpi_gbl_current_walk_list; - acpi_walk_state *previous_walk_state; + acpi_status status; + acpi_status terminate_status; + struct acpi_thread_state *thread; + struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; + struct acpi_walk_state *previous_walk_state; - FUNCTION_TRACE ("Ps_parse_aml"); + ACPI_FUNCTION_TRACE ("ps_parse_aml"); - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with Walk_state=%p Aml=%p size=%X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with walk_state=%p Aml=%p size=%X\n", walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size)); - /* Create and initialize a new walk list */ + /* Create and initialize a new thread state */ - walk_list.walk_state = NULL; - walk_list.acquired_mutex_list.prev = NULL; - walk_list.acquired_mutex_list.next = NULL; - - walk_state->walk_list = &walk_list; - acpi_ds_push_walk_state (walk_state, &walk_list); + thread = acpi_ut_create_thread_state (); + if (!thread) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + walk_state->thread = thread; + acpi_ds_push_walk_state (walk_state, thread); - /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter + /* + * This global allows the AML debugger to get a handle to the currently + * executing control method. */ - acpi_gbl_current_walk_list = &walk_list; + acpi_gbl_current_walk_list = thread; /* * Execute the walk loop as long as there is a valid Walk State. This @@ -1027,37 +1089,41 @@ while (walk_state) { if (ACPI_SUCCESS (status)) { /* - * The Parse_loop executes AML until the method terminates + * The parse_loop executes AML until the method terminates * or calls another method. */ status = acpi_ps_parse_loop (walk_state); } ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "Completed one call to walk loop, State=%p\n", walk_state)); + "Completed one call to walk loop, %s State=%p\n", + acpi_format_exception (status), walk_state)); if (status == AE_CTRL_TRANSFER) { /* * A method call was detected. * Transfer control to the called control method */ - status = acpi_ds_call_control_method (&walk_list, walk_state, NULL); + status = acpi_ds_call_control_method (thread, walk_state, NULL); /* * If the transfer to the new method method call worked, a new walk * state was created -- get it */ - walk_state = acpi_ds_get_current_walk_state (&walk_list); + walk_state = acpi_ds_get_current_walk_state (thread); continue; } - else if (status == AE_CTRL_TERMINATE) { status = AE_OK; } + else if (status != AE_OK) { + ACPI_REPORT_METHOD_ERROR ("Method execution failed", + walk_state->method_node, NULL, status); + } /* We are done with this walk, move on to the parent if any */ - walk_state = acpi_ds_pop_walk_state (&walk_list); + walk_state = acpi_ds_pop_walk_state (thread); /* Reset the current scope to the beginning of scope stack */ @@ -1068,7 +1134,13 @@ * there's lots of cleanup to do */ if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { - acpi_ds_terminate_control_method (walk_state); + terminate_status = acpi_ds_terminate_control_method (walk_state); + if (ACPI_FAILURE (terminate_status)) { + ACPI_REPORT_ERROR (( + "Could not terminate control method properly\n")); + + /* Ignore error and continue */ + } } /* Delete this walk state and all linked control states */ @@ -1077,22 +1149,29 @@ previous_walk_state = walk_state; - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Return_value=%p, State=%p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, State=%p\n", walk_state->return_desc, walk_state)); /* Check if we have restarted a preempted walk */ - walk_state = acpi_ds_get_current_walk_state (&walk_list); + walk_state = acpi_ds_get_current_walk_state (thread); if (walk_state) { if (ACPI_SUCCESS (status)) { - /* There is another walk state, restart it */ - /* - * If the method returned value is not used by the parent, + * There is another walk state, restart it. + * If the method return value is not used by the parent, * The object is deleted */ - acpi_ds_restart_control_method (walk_state, previous_walk_state->return_desc); - walk_state->walk_type |= WALK_METHOD_RESTART; + status = acpi_ds_restart_control_method (walk_state, + previous_walk_state->return_desc); + if (ACPI_SUCCESS (status)) { + walk_state->walk_type |= ACPI_WALK_METHOD_RESTART; + } + } + else { + /* On error, delete any return object */ + + acpi_ut_remove_reference (previous_walk_state->return_desc); } } @@ -1103,7 +1182,6 @@ else if (previous_walk_state->caller_return_desc) { *(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc; /* NULL if no return value */ } - else if (previous_walk_state->return_desc) { /* Caller doesn't want it, must delete it */ @@ -1113,10 +1191,10 @@ acpi_ds_delete_walk_state (previous_walk_state); } - /* Normal exit */ - acpi_ex_release_all_mutexes ((acpi_operand_object *) &walk_list.acquired_mutex_list); + acpi_ex_release_all_mutexes (thread); + acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread)); acpi_gbl_current_walk_list = prev_walk_list; return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/parser/psscope.c linux-2.4.22/drivers/acpi/parser/psscope.c --- linux-2.4.21/drivers/acpi/parser/psscope.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/psscope.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,41 +1,59 @@ /****************************************************************************** * * Module Name: psscope - Parser scope stack management routines - * $Revision: 30 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("psscope") + ACPI_MODULE_NAME ("psscope") /******************************************************************************* * - * FUNCTION: Acpi_ps_get_parent_scope + * FUNCTION: acpi_ps_get_parent_scope * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: Pointer to an Op object * @@ -43,9 +61,9 @@ * ******************************************************************************/ -acpi_parse_object * +union acpi_parse_object * acpi_ps_get_parent_scope ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { return (parser_state->scope->parse_scope.op); } @@ -53,9 +71,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_has_completed_scope + * FUNCTION: acpi_ps_has_completed_scope * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: Boolean, TRUE = scope completed. * @@ -67,7 +85,7 @@ u8 acpi_ps_has_completed_scope ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { return ((u8) ((parser_state->aml >= parser_state->scope->parse_scope.arg_end || !parser_state->scope->parse_scope.arg_count))); @@ -76,9 +94,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_init_scope + * FUNCTION: acpi_ps_init_scope * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * Root - the Root Node of this new scope * * RETURN: Status @@ -89,13 +107,13 @@ acpi_status acpi_ps_init_scope ( - acpi_parse_state *parser_state, - acpi_parse_object *root_op) + struct acpi_parse_state *parser_state, + union acpi_parse_object *root_op) { - acpi_generic_state *scope; + union acpi_generic_state *scope; - FUNCTION_TRACE_PTR ("Ps_init_scope", root_op); + ACPI_FUNCTION_TRACE_PTR ("ps_init_scope", root_op); scope = acpi_ut_create_generic_state (); @@ -118,12 +136,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_push_scope + * FUNCTION: acpi_ps_push_scope * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * Op - Current op to be pushed - * Remaining_args - List of args remaining - * Arg_count - Fixed or variable number of args + * remaining_args - List of args remaining + * arg_count - Fixed or variable number of args * * RETURN: Status * @@ -133,20 +151,20 @@ acpi_status acpi_ps_push_scope ( - acpi_parse_state *parser_state, - acpi_parse_object *op, - u32 remaining_args, - u32 arg_count) + struct acpi_parse_state *parser_state, + union acpi_parse_object *op, + u32 remaining_args, + u32 arg_count) { - acpi_generic_state *scope; + union acpi_generic_state *scope; - FUNCTION_TRACE_PTR ("Ps_push_scope", op); + ACPI_FUNCTION_TRACE_PTR ("ps_push_scope", op); scope = acpi_ut_create_generic_state (); if (!scope) { - return (AE_NO_MEMORY); + return_ACPI_STATUS (AE_NO_MEMORY); } @@ -170,7 +188,7 @@ else { /* single argument */ - scope->parse_scope.arg_end = ACPI_MAX_AML; + scope->parse_scope.arg_end = ACPI_TO_POINTER (ACPI_MAX_PTR); } return_ACPI_STATUS (AE_OK); @@ -179,13 +197,13 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_pop_scope + * FUNCTION: acpi_ps_pop_scope * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * Op - Where the popped op is returned - * Arg_list - Where the popped "next argument" is + * arg_list - Where the popped "next argument" is * returned - * Arg_count - Count of objects in Arg_list + * arg_count - Count of objects in arg_list * * RETURN: Status * @@ -195,15 +213,15 @@ void acpi_ps_pop_scope ( - acpi_parse_state *parser_state, - acpi_parse_object **op, - u32 *arg_list, - u32 *arg_count) + struct acpi_parse_state *parser_state, + union acpi_parse_object **op, + u32 *arg_list, + u32 *arg_count) { - acpi_generic_state *scope = parser_state->scope; + union acpi_generic_state *scope = parser_state->scope; - FUNCTION_TRACE ("Ps_pop_scope"); + ACPI_FUNCTION_TRACE ("ps_pop_scope"); /* @@ -240,9 +258,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_cleanup_scope + * FUNCTION: acpi_ps_cleanup_scope * - * PARAMETERS: Parser_state - Current parser state object + * PARAMETERS: parser_state - Current parser state object * * RETURN: Status * @@ -253,11 +271,11 @@ void acpi_ps_cleanup_scope ( - acpi_parse_state *parser_state) + struct acpi_parse_state *parser_state) { - acpi_generic_state *scope; + union acpi_generic_state *scope; - FUNCTION_TRACE_PTR ("Ps_cleanup_scope", parser_state); + ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state); if (!parser_state) { diff -urN linux-2.4.21/drivers/acpi/parser/pstree.c linux-2.4.22/drivers/acpi/parser/pstree.c --- linux-2.4.21/drivers/acpi/parser/pstree.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/pstree.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,40 +1,58 @@ /****************************************************************************** * * Module Name: pstree - Parser op tree manipulation/traversal/search - * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("pstree") + ACPI_MODULE_NAME ("pstree") /******************************************************************************* * - * FUNCTION: Acpi_ps_get_arg + * FUNCTION: acpi_ps_get_arg * * PARAMETERS: Op - Get an argument for this op * Argn - Nth argument to get @@ -45,21 +63,21 @@ * ******************************************************************************/ -acpi_parse_object * +union acpi_parse_object * acpi_ps_get_arg ( - acpi_parse_object *op, - u32 argn) + union acpi_parse_object *op, + u32 argn) { - acpi_parse_object *arg = NULL; - const acpi_opcode_info *op_info; + union acpi_parse_object *arg = NULL; + const struct acpi_opcode_info *op_info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* Get the info structure for this opcode */ - op_info = acpi_ps_get_opcode_info (op->opcode); + op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); if (op_info->class == AML_CLASS_UNKNOWN) { /* Invalid opcode or ASCII character */ @@ -76,10 +94,10 @@ /* Get the requested argument object */ - arg = op->value.arg; + arg = op->common.value.arg; while (arg && argn) { argn--; - arg = arg->next; + arg = arg->common.next; } return (arg); @@ -88,7 +106,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_append_arg + * FUNCTION: acpi_ps_append_arg * * PARAMETERS: Op - Append an argument to this Op. * Arg - Argument Op to append @@ -101,14 +119,14 @@ void acpi_ps_append_arg ( - acpi_parse_object *op, - acpi_parse_object *arg) + union acpi_parse_object *op, + union acpi_parse_object *arg) { - acpi_parse_object *prev_arg; - const acpi_opcode_info *op_info; + union acpi_parse_object *prev_arg; + const struct acpi_opcode_info *op_info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (!op) { @@ -117,11 +135,12 @@ /* Get the info structure for this opcode */ - op_info = acpi_ps_get_opcode_info (op->opcode); + op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); if (op_info->class == AML_CLASS_UNKNOWN) { /* Invalid opcode */ - REPORT_ERROR (("Ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", op->opcode)); + ACPI_REPORT_ERROR (("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", + op->common.aml_opcode)); return; } @@ -136,35 +155,35 @@ /* Append the argument to the linked argument list */ - if (op->value.arg) { + if (op->common.value.arg) { /* Append to existing argument list */ - prev_arg = op->value.arg; - while (prev_arg->next) { - prev_arg = prev_arg->next; + prev_arg = op->common.value.arg; + while (prev_arg->common.next) { + prev_arg = prev_arg->common.next; } - prev_arg->next = arg; + prev_arg->common.next = arg; } else { /* No argument list, this will be the first argument */ - op->value.arg = arg; + op->common.value.arg = arg; } /* Set the parent in this arg and any args linked after it */ while (arg) { - arg->parent = op; - arg = arg->next; + arg->common.parent = op; + arg = arg->common.next; } } /******************************************************************************* * - * FUNCTION: Acpi_ps_get_child + * FUNCTION: acpi_ps_get_child * * PARAMETERS: Op - Get the child of this Op * @@ -174,17 +193,17 @@ * ******************************************************************************/ -acpi_parse_object * +union acpi_parse_object * acpi_ps_get_child ( - acpi_parse_object *op) + union acpi_parse_object *op) { - acpi_parse_object *child = NULL; + union acpi_parse_object *child = NULL; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); - switch (op->opcode) { + switch (op->common.aml_opcode) { case AML_SCOPE_OP: case AML_ELSE_OP: case AML_DEVICE_OP: @@ -219,6 +238,10 @@ child = acpi_ps_get_arg (op, 3); break; + + default: + /* All others have no children */ + break; } return (child); @@ -227,7 +250,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_get_depth_next + * FUNCTION: acpi_ps_get_depth_next * * PARAMETERS: Origin - Root of subtree to search * Op - Last (previous) Op that was found @@ -239,17 +262,17 @@ * ******************************************************************************/ -acpi_parse_object * +union acpi_parse_object * acpi_ps_get_depth_next ( - acpi_parse_object *origin, - acpi_parse_object *op) + union acpi_parse_object *origin, + union acpi_parse_object *op) { - acpi_parse_object *next = NULL; - acpi_parse_object *parent; - acpi_parse_object *arg; + union acpi_parse_object *next = NULL; + union acpi_parse_object *parent; + union acpi_parse_object *arg; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (!op) { @@ -265,19 +288,19 @@ /* look for a sibling */ - next = op->next; + next = op->common.next; if (next) { return (next); } /* look for a sibling of parent */ - parent = op->parent; + parent = op->common.parent; while (parent) { arg = acpi_ps_get_arg (parent, 0); while (arg && (arg != origin) && (arg != op)) { - arg = arg->next; + arg = arg->common.next; } if (arg == origin) { @@ -286,13 +309,14 @@ return (NULL); } - if (parent->next) { + if (parent->common.next) { /* found sibling of parent */ - return (parent->next); + + return (parent->common.next); } op = parent; - parent = parent->parent; + parent = parent->common.parent; } return (next); diff -urN linux-2.4.21/drivers/acpi/parser/psutils.c linux-2.4.22/drivers/acpi/parser/psutils.c --- linux-2.4.21/drivers/acpi/parser/psutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/psutils.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,47 +1,89 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 44 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("psutils") + ACPI_MODULE_NAME ("psutils") -#define PARSEOP_GENERIC 0x01 -#define PARSEOP_NAMED 0x02 -#define PARSEOP_DEFERRED 0x04 -#define PARSEOP_BYTELIST 0x08 -#define PARSEOP_IN_CACHE 0x80 +/******************************************************************************* + * + * FUNCTION: acpi_ps_create_scope_op + * + * PARAMETERS: None + * + * RETURN: scope_op + * + * DESCRIPTION: Create a Scope and associated namepath op with the root name + * + ******************************************************************************/ + +union acpi_parse_object * +acpi_ps_create_scope_op ( + void) +{ + union acpi_parse_object *scope_op; + + + scope_op = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!scope_op) { + return (NULL); + } + + + scope_op->named.name = ACPI_ROOT_NAME; + return (scope_op); +} /******************************************************************************* * - * FUNCTION: Acpi_ps_init_op + * FUNCTION: acpi_ps_init_op * * PARAMETERS: Op - A newly allocated Op object * Opcode - Opcode to store in the Op @@ -55,28 +97,23 @@ void acpi_ps_init_op ( - acpi_parse_object *op, - u16 opcode) + union acpi_parse_object *op, + u16 opcode) { - const acpi_opcode_info *aml_op; - - - FUNCTION_ENTRY (); - + ACPI_FUNCTION_ENTRY (); - op->data_type = ACPI_DESC_TYPE_PARSER; - op->opcode = opcode; - aml_op = acpi_ps_get_opcode_info (opcode); + op->common.data_type = ACPI_DESC_TYPE_PARSER; + op->common.aml_opcode = opcode; - DEBUG_ONLY_MEMBERS (STRNCPY (op->op_name, aml_op->name, - sizeof (op->op_name))); + ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name, + (acpi_ps_get_opcode_info (opcode))->name, sizeof (op->common.aml_op_name))); } /******************************************************************************* * - * FUNCTION: Acpi_ps_alloc_op + * FUNCTION: acpi_ps_alloc_op * * PARAMETERS: Opcode - Opcode that will be stored in the new Op * @@ -88,17 +125,17 @@ * ******************************************************************************/ -acpi_parse_object* +union acpi_parse_object* acpi_ps_alloc_op ( - u16 opcode) + u16 opcode) { - acpi_parse_object *op = NULL; - u32 size; - u8 flags; - const acpi_opcode_info *op_info; + union acpi_parse_object *op = NULL; + u32 size; + u8 flags; + const struct acpi_opcode_info *op_info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); op_info = acpi_ps_get_opcode_info (opcode); @@ -106,33 +143,28 @@ /* Allocate the minimum required size object */ if (op_info->flags & AML_DEFER) { - size = sizeof (acpi_parse2_object); - flags = PARSEOP_DEFERRED; + size = sizeof (struct acpi_parse_obj_named); + flags = ACPI_PARSEOP_DEFERRED; } - else if (op_info->flags & AML_NAMED) { - size = sizeof (acpi_parse2_object); - flags = PARSEOP_NAMED; + size = sizeof (struct acpi_parse_obj_named); + flags = ACPI_PARSEOP_NAMED; } - else if (opcode == AML_INT_BYTELIST_OP) { - size = sizeof (acpi_parse2_object); - flags = PARSEOP_BYTELIST; + size = sizeof (struct acpi_parse_obj_named); + flags = ACPI_PARSEOP_BYTELIST; } - else { - size = sizeof (acpi_parse_object); - flags = PARSEOP_GENERIC; + size = sizeof (struct acpi_parse_obj_common); + flags = ACPI_PARSEOP_GENERIC; } - - if (size == sizeof (acpi_parse_object)) { + if (size == sizeof (struct acpi_parse_obj_common)) { /* * The generic op is by far the most common (16 to 1) */ op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE); } - else { op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT); } @@ -141,7 +173,7 @@ if (op) { acpi_ps_init_op (op, opcode); - op->flags = flags; + op->common.flags = flags; } return (op); @@ -150,7 +182,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_free_op + * FUNCTION: acpi_ps_free_op * * PARAMETERS: Op - Op to be freed * @@ -163,19 +195,18 @@ void acpi_ps_free_op ( - acpi_parse_object *op) + union acpi_parse_object *op) { - PROC_NAME ("Ps_free_op"); + ACPI_FUNCTION_NAME ("ps_free_op"); - if (op->opcode == AML_INT_RETURN_VALUE_OP) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Free retval op: %p\n", op)); + if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n", op)); } - if (op->flags == PARSEOP_GENERIC) { + if (op->common.flags & ACPI_PARSEOP_GENERIC) { acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op); } - else { acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE_EXT, op); } @@ -184,7 +215,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_delete_parse_cache + * FUNCTION: acpi_ps_delete_parse_cache * * PARAMETERS: None * @@ -198,7 +229,7 @@ acpi_ps_delete_parse_cache ( void) { - FUNCTION_TRACE ("Ps_delete_parse_cache"); + ACPI_FUNCTION_TRACE ("ps_delete_parse_cache"); acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE); @@ -221,7 +252,7 @@ */ u8 acpi_ps_is_leading_char ( - u32 c) + u32 c) { return ((u8) (c == '_' || (c >= 'A' && c <= 'Z'))); } @@ -232,7 +263,7 @@ */ u8 acpi_ps_is_prefix_char ( - u32 c) + u32 c) { return ((u8) (c == '\\' || c == '^')); } @@ -243,19 +274,19 @@ */ u32 acpi_ps_get_name ( - acpi_parse_object *op) + union acpi_parse_object *op) { /* The "generic" object has no name associated with it */ - if (op->flags & PARSEOP_GENERIC) { + if (op->common.flags & ACPI_PARSEOP_GENERIC) { return (0); } /* Only the "Extended" parse objects have a name */ - return (((acpi_parse2_object *) op)->name); + return (op->named.name); } @@ -264,16 +295,16 @@ */ void acpi_ps_set_name ( - acpi_parse_object *op, - u32 name) + union acpi_parse_object *op, + u32 name) { /* The "generic" object has no name associated with it */ - if (op->flags & PARSEOP_GENERIC) { + if (op->common.flags & ACPI_PARSEOP_GENERIC) { return; } - ((acpi_parse2_object *) op)->name = name; + op->named.name = name; } diff -urN linux-2.4.21/drivers/acpi/parser/pswalk.c linux-2.4.22/drivers/acpi/parser/pswalk.c --- linux-2.4.21/drivers/acpi/parser/pswalk.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/pswalk.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,47 +1,62 @@ /****************************************************************************** * * Module Name: pswalk - Parser routines to walk parsed op tree(s) - * $Revision: 58 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "amlcode.h" -#include "acparser.h" -#include "acdispat.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("pswalk") + ACPI_MODULE_NAME ("pswalk") /******************************************************************************* * - * FUNCTION: Acpi_ps_get_next_walk_op + * FUNCTION: acpi_ps_get_next_walk_op * - * PARAMETERS: Walk_state - Current state of the walk + * PARAMETERS: walk_state - Current state of the walk * Op - Current Op to be walked - * Ascending_callback - Procedure called when Op is complete + * ascending_callback - Procedure called when Op is complete * * RETURN: Status * @@ -51,22 +66,22 @@ acpi_status acpi_ps_get_next_walk_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - acpi_parse_upwards ascending_callback) + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + acpi_parse_upwards ascending_callback) { - acpi_parse_object *next; - acpi_parse_object *parent; - acpi_parse_object *grand_parent; - acpi_status status; + union acpi_parse_object *next; + union acpi_parse_object *parent; + union acpi_parse_object *grand_parent; + acpi_status status; - FUNCTION_TRACE_PTR ("Ps_get_next_walk_op", op); + ACPI_FUNCTION_TRACE_PTR ("ps_get_next_walk_op", op); /* Check for a argument only if we are descending in the tree */ - if (walk_state->next_op_info != NEXT_OP_UPWARD) { + if (walk_state->next_op_info != ACPI_NEXT_OP_UPWARD) { /* Look for an argument or child of the current op */ next = acpi_ps_get_arg (op, 0); @@ -75,22 +90,21 @@ walk_state->prev_op = op; walk_state->next_op = next; - walk_state->next_op_info = NEXT_OP_DOWNWARD; + walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD; return_ACPI_STATUS (AE_OK); } - /* * No more children, this Op is complete. Save Next and Parent * in case the Op object gets deleted by the callback routine */ - next = op->next; - parent = op->parent; + next = op->common.next; + parent = op->common.parent; walk_state->op = op; - walk_state->op_info = acpi_ps_get_opcode_info (op->opcode); - walk_state->opcode = op->opcode; + walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); + walk_state->opcode = op->common.aml_opcode; status = ascending_callback (walk_state); @@ -115,7 +129,7 @@ walk_state->prev_op = op; walk_state->next_op = next; - walk_state->next_op_info = NEXT_OP_DOWNWARD; + walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD; /* Continue downward */ @@ -127,7 +141,6 @@ * the tree */ } - else { /* * We are resuming a walk, and we were (are) going upward in the tree. @@ -136,7 +149,6 @@ parent = op; } - /* * Look for a sibling of the current Op's parent * Continue moving up the tree until we find a node that has not been @@ -145,12 +157,12 @@ while (parent) { /* We are moving up the tree, therefore this parent Op is complete */ - grand_parent = parent->parent; - next = parent->next; + grand_parent = parent->common.parent; + next = parent->common.next; walk_state->op = parent; - walk_state->op_info = acpi_ps_get_opcode_info (parent->opcode); - walk_state->opcode = parent->opcode; + walk_state->op_info = acpi_ps_get_opcode_info (parent->common.aml_opcode); + walk_state->opcode = parent->common.aml_opcode; status = ascending_callback (walk_state); @@ -175,7 +187,7 @@ walk_state->prev_op = parent; walk_state->next_op = next; - walk_state->next_op_info = NEXT_OP_DOWNWARD; + walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD; return_ACPI_STATUS (status); } @@ -188,9 +200,10 @@ } - /* Got all the way to the top of the tree, we must be done! */ - /* However, the code should have terminated in the loop above */ - + /* + * Got all the way to the top of the tree, we must be done! + * However, the code should have terminated in the loop above + */ walk_state->next_op = NULL; return_ACPI_STATUS (AE_OK); @@ -199,22 +212,22 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_delete_completed_op + * FUNCTION: acpi_ps_delete_completed_op * * PARAMETERS: State - Walk state * Op - Completed op * * RETURN: AE_OK * - * DESCRIPTION: Callback function for Acpi_ps_get_next_walk_op(). Used during - * Acpi_ps_delete_parse tree to delete Op objects when all sub-objects + * DESCRIPTION: Callback function for acpi_ps_get_next_walk_op(). Used during + * acpi_ps_delete_parse tree to delete Op objects when all sub-objects * have been visited (and deleted.) * ******************************************************************************/ -static acpi_status +acpi_status acpi_ps_delete_completed_op ( - acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state) { acpi_ps_free_op (walk_state->op); @@ -224,9 +237,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_delete_parse_tree + * FUNCTION: acpi_ps_delete_parse_tree * - * PARAMETERS: Subtree_root - Root of tree (or subtree) to delete + * PARAMETERS: subtree_root - Root of tree (or subtree) to delete * * RETURN: None * @@ -236,13 +249,14 @@ void acpi_ps_delete_parse_tree ( - acpi_parse_object *subtree_root) + union acpi_parse_object *subtree_root) { - acpi_walk_state *walk_state; - acpi_walk_list walk_list; + struct acpi_walk_state *walk_state; + struct acpi_thread_state *thread; + acpi_status status; - FUNCTION_TRACE_PTR ("Ps_delete_parse_tree", subtree_root); + ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root); if (!subtree_root) { @@ -251,11 +265,12 @@ /* Create and initialize a new walk list */ - walk_list.walk_state = NULL; - walk_list.acquired_mutex_list.prev = NULL; - walk_list.acquired_mutex_list.next = NULL; + thread = acpi_ut_create_thread_state (); + if (!thread) { + return_VOID; + } - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread); if (!walk_state) { return_VOID; } @@ -264,25 +279,26 @@ walk_state->descending_callback = NULL; walk_state->ascending_callback = NULL; - walk_state->origin = subtree_root; walk_state->next_op = subtree_root; - /* Head downward in the tree */ - walk_state->next_op_info = NEXT_OP_DOWNWARD; + walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD; /* Visit all nodes in the subtree */ while (walk_state->next_op) { - acpi_ps_get_next_walk_op (walk_state, walk_state->next_op, + status = acpi_ps_get_next_walk_op (walk_state, walk_state->next_op, acpi_ps_delete_completed_op); + if (ACPI_FAILURE (status)) { + break; + } } /* We are done with this walk */ - acpi_ex_release_all_mutexes ((acpi_operand_object *) &walk_list.acquired_mutex_list); + acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread)); acpi_ds_delete_walk_state (walk_state); return_VOID; diff -urN linux-2.4.21/drivers/acpi/parser/psxface.c linux-2.4.22/drivers/acpi/parser/psxface.c --- linux-2.4.21/drivers/acpi/parser/psxface.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/parser/psxface.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,51 +1,68 @@ /****************************************************************************** * * Module Name: psxface - Parser external interfaces - * $Revision: 52 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include +#include #define _COMPONENT ACPI_PARSER - MODULE_NAME ("psxface") + ACPI_MODULE_NAME ("psxface") /******************************************************************************* * - * FUNCTION: Acpi_psx_execute + * FUNCTION: acpi_psx_execute * - * PARAMETERS: Method_node - A method object containing both the AML + * PARAMETERS: method_node - A method object containing both the AML * address and length. * **Params - List of parameters to pass to method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. - * **Return_obj_desc - Return object from execution of the + * **return_obj_desc - Return object from execution of the * method. * * RETURN: Status @@ -56,18 +73,18 @@ acpi_status acpi_psx_execute ( - acpi_namespace_node *method_node, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc) + struct acpi_namespace_node *method_node, + union acpi_operand_object **params, + union acpi_operand_object **return_obj_desc) { - acpi_status status; - acpi_operand_object *obj_desc; - u32 i; - acpi_parse_object *op; - acpi_walk_state *walk_state; + acpi_status status; + union acpi_operand_object *obj_desc; + u32 i; + union acpi_parse_object *op; + struct acpi_walk_state *walk_state; - FUNCTION_TRACE ("Psx_execute"); + ACPI_FUNCTION_TRACE ("psx_execute"); /* Validate the Node and get the attached object */ @@ -102,20 +119,27 @@ * 1) Perform the first pass parse of the method to enter any * named objects that it creates into the namespace */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Parse **** Entry=%p obj=%p\n", method_node, obj_desc)); /* Create and init a Root Node */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); + op = acpi_ps_create_scope_op (); if (!op) { return_ACPI_STATUS (AE_NO_MEMORY); } + /* + * Get a new owner_id for objects created by this method. Namespace + * objects (such as Operation Regions) can be created during the + * first pass parse. + */ + obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); + /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, + walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); @@ -124,7 +148,7 @@ status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, NULL, NULL, 1); if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ + acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); } @@ -133,30 +157,28 @@ status = acpi_ps_parse_aml (walk_state); acpi_ps_delete_parse_tree (op); - /* * 2) Execute the method. Performs second pass parse simultaneously */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Execution **** Entry=%p obj=%p\n", method_node, obj_desc)); /* Create and init a Root Node */ - op = acpi_ps_alloc_op (AML_SCOPE_OP); + op = acpi_ps_create_scope_op (); if (!op) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Init new op with the method name and pointer back to the NS node */ - acpi_ps_set_name (op, method_node->name); - op->node = method_node; + acpi_ps_set_name (op, method_node->name.integer); + op->common.node = method_node; /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -164,7 +186,7 @@ status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, params, return_obj_desc, 3); if (ACPI_FAILURE (status)) { - /* TBD: delete walk state */ + acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); } @@ -178,30 +200,24 @@ /* Take away the extra reference that we gave the parameters above */ for (i = 0; params[i]; i++) { - acpi_ut_update_object_reference (params[i], REF_DECREMENT); - } - } - + /* Ignore errors, just do them all */ - if (ACPI_FAILURE (status)) { - DUMP_PATHNAME (method_node, "Ps_execute: method failed -", - ACPI_LV_ERROR, _COMPONENT); + (void) acpi_ut_update_object_reference (params[i], REF_DECREMENT); + } } - /* * If the method has returned an object, signal this to the caller with * a control exception code */ if (*return_obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Method returned Obj_desc=%p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", *return_obj_desc)); - DUMP_STACK_ENTRY (*return_obj_desc); + ACPI_DUMP_STACK_ENTRY (*return_obj_desc); status = AE_CTRL_RETURN_VALUE; } - return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/pci_bind.c linux-2.4.22/drivers/acpi/pci_bind.c --- linux-2.4.21/drivers/acpi/pci_bind.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/pci_bind.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,309 @@ +/* + * pci_bind.c - ACPI PCI Device Binding ($Revision: 3 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_PCI_COMPONENT +ACPI_MODULE_NAME ("pci_bind") + +#define PREFIX "ACPI: " + + +struct acpi_pci_data { + struct acpi_pci_id id; + struct pci_bus *bus; + struct pci_dev *dev; +}; + + +void +acpi_pci_data_handler ( + acpi_handle handle, + u32 function, + void *context) +{ + ACPI_FUNCTION_TRACE("acpi_pci_data_handler"); + + /* TBD: Anything we need to do here? */ + + return_VOID; +} + + +/** + * acpi_os_get_pci_id + * ------------------ + * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) + * to resolve PCI information for ACPI-PCI devices defined in the namespace. + * This typically occurs when resolving PCI operation region information. + */ +acpi_status +acpi_os_get_pci_id ( + acpi_handle handle, + struct acpi_pci_id *id) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_device *device = NULL; + struct acpi_pci_data *data = NULL; + + ACPI_FUNCTION_TRACE("acpi_os_get_pci_id"); + + if (!id) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + result = acpi_bus_get_device(handle, &device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid ACPI Bus context for device %s\n", + acpi_device_bid(device))); + return_ACPI_STATUS(AE_NOT_EXIST); + } + + status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data); + if (ACPI_FAILURE(status) || !data || !data->dev) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid ACPI-PCI context for device %s\n", + acpi_device_bid(device))); + return_ACPI_STATUS(status); + } + + *id = data->id; + + /* + id->segment = data->id.segment; + id->bus = data->id.bus; + id->device = data->id.device; + id->function = data->id.function; + */ + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Device %s has PCI address %02x:%02x:%02x.%02x\n", + acpi_device_bid(device), id->segment, id->bus, + id->device, id->function)); + + return_ACPI_STATUS(AE_OK); +} + + +int +acpi_pci_bind ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_pci_data *data = NULL; + struct acpi_pci_data *pdata = NULL; + char pathname[ACPI_PATHNAME_MAX] = {0}; + struct acpi_buffer buffer = {ACPI_PATHNAME_MAX, pathname}; + acpi_handle handle = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_bind"); + + if (!device || !device->parent) + return_VALUE(-EINVAL); + + data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); + if (!data) + return_VALUE(-ENOMEM); + memset(data, 0, sizeof(struct acpi_pci_data)); + + acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", + pathname)); + + /* + * Segment & Bus + * ------------- + * These are obtained via the parent device's ACPI-PCI context. + */ + status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, + (void**) &pdata); + if (ACPI_FAILURE(status) || !pdata || !pdata->bus) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid ACPI-PCI context for parent device %s\n", + acpi_device_bid(device->parent))); + result = -ENODEV; + goto end; + } + data->id.segment = pdata->id.segment; + data->id.bus = pdata->bus->number; + + /* + * Device & Function + * ----------------- + * These are simply obtained from the device's _ADR method. Note + * that a value of zero is valid. + */ + data->id.device = device->pnp.bus_address >> 16; + data->id.function = device->pnp.bus_address & 0xFFFF; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n", + data->id.segment, data->id.bus, data->id.device, + data->id.function)); + + /* + * TBD: Support slot devices (e.g. function=0xFFFF). + */ + + /* + * Locate PCI Device + * ----------------- + * Locate matching device in PCI namespace. If it doesn't exist + * this typically means that the device isn't currently inserted + * (e.g. docking station, port replicator, etc.). + */ + data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); + if (!data->dev) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", + data->id.segment, data->id.bus, + data->id.device, data->id.function)); + result = -ENODEV; + goto end; + } + if (!data->dev->bus) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n", + data->id.segment, data->id.bus, + data->id.device, data->id.function)); + result = -ENODEV; + goto end; + } + + /* + * PCI Bridge? + * ----------- + * If so, set the 'bus' field and install the 'bind' function to + * facilitate callbacks for all of its children. + */ + if (data->dev->subordinate) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Device %02x:%02x:%02x.%02x is a PCI bridge\n", + data->id.segment, data->id.bus, + data->id.device, data->id.function)); + data->bus = data->dev->subordinate; + device->ops.bind = acpi_pci_bind; + } + + /* + * Attach ACPI-PCI Context + * ----------------------- + * Thus binding the ACPI and PCI devices. + */ + status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to attach ACPI-PCI context to device %s\n", + acpi_device_bid(device))); + result = -ENODEV; + goto end; + } + + /* + * PCI Routing Table + * ----------------- + * Evaluate and parse _PRT, if exists. This code is independent of + * PCI bridges (above) to allow parsing of _PRT objects within the + * scope of non-bridge devices. Note that _PRTs within the scope of + * a PCI bridge assume the bridge's subordinate bus number. + * + * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? + */ + status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); + if (ACPI_SUCCESS(status)) { + if (data->bus) /* PCI-PCI bridge */ + acpi_pci_irq_add_prt(device->handle, data->id.segment, + data->bus->number); + else /* non-bridge PCI device */ + acpi_pci_irq_add_prt(device->handle, data->id.segment, + data->id.bus); + } + +end: + if (result) + kfree(data); + + return_VALUE(result); +} + + +int +acpi_pci_bind_root ( + struct acpi_device *device, + struct acpi_pci_id *id, + struct pci_bus *bus) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_pci_data *data = NULL; + char pathname[ACPI_PATHNAME_MAX] = {0}; + struct acpi_buffer buffer = {ACPI_PATHNAME_MAX, pathname}; + + ACPI_FUNCTION_TRACE("acpi_pci_bind_root"); + + if (!device || !id || !bus) + return_VALUE(-EINVAL); + + data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); + if (!data) + return_VALUE(-ENOMEM); + memset(data, 0, sizeof(struct acpi_pci_data)); + + data->id = *id; + data->bus = bus; + device->ops.bind = acpi_pci_bind; + + acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " + "%02x:%02x\n", pathname, id->segment, id->bus)); + + status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to attach ACPI-PCI context to device %s\n", + pathname)); + result = -ENODEV; + goto end; + } + +end: + if (result != 0) + kfree(data); + + return_VALUE(result); +} diff -urN linux-2.4.21/drivers/acpi/pci_irq.c linux-2.4.22/drivers/acpi/pci_irq.c --- linux-2.4.21/drivers/acpi/pci_irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/pci_irq.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,422 @@ +/* + * pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 11 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2002 Dominik Brodowski + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_X86_IO_APIC +#include +#endif +#ifdef CONFIG_IOSAPIC +# include +#endif +#include +#include + + +#define _COMPONENT ACPI_PCI_COMPONENT +ACPI_MODULE_NAME ("pci_irq") + +#define PREFIX "PCI: " + +struct acpi_prt_list acpi_prt; + +#ifdef CONFIG_X86 +extern void eisa_set_level_irq(unsigned int irq); +#endif + + +/* -------------------------------------------------------------------------- + PCI IRQ Routing Table (PRT) Support + -------------------------------------------------------------------------- */ + +static struct acpi_prt_entry * +acpi_pci_irq_find_prt_entry ( + int segment, + int bus, + int device, + int pin) +{ + struct list_head *node = NULL; + struct acpi_prt_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry"); + + /* + * Parse through all PRT entries looking for a match on the specified + * PCI device's segment, bus, device, and pin (don't care about func). + * + * TBD: Acquire/release lock + */ + list_for_each(node, &acpi_prt.entries) { + entry = list_entry(node, struct acpi_prt_entry, node); + if ((segment == entry->id.segment) + && (bus == entry->id.bus) + && (device == entry->id.device) + && (pin == entry->pin)) { + return_PTR(entry); + } + } + + return_PTR(NULL); +} + + +static int +acpi_pci_irq_add_entry ( + acpi_handle handle, + int segment, + int bus, + struct acpi_pci_routing_table *prt) +{ + struct acpi_prt_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_add_entry"); + + if (!prt) + return_VALUE(-EINVAL); + + entry = kmalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); + if (!entry) + return_VALUE(-ENOMEM); + memset(entry, 0, sizeof(struct acpi_prt_entry)); + + entry->id.segment = segment; + entry->id.bus = bus; + entry->id.device = (prt->address >> 16) & 0xFFFF; + entry->id.function = prt->address & 0xFFFF; + entry->pin = prt->pin; + + /* + * Type 1: Dynamic + * --------------- + * The 'source' field specifies the PCI interrupt link device used to + * configure the IRQ assigned to this slot|dev|pin. The 'source_index' + * indicates which resource descriptor in the resource template (of + * the link device) this interrupt is allocated from. + * + * NOTE: Don't query the Link Device for IRQ information at this time + * because Link Device enumeration may not have occurred yet + * (e.g. exists somewhere 'below' this _PRT entry in the ACPI + * namespace). + */ + if (prt->source[0]) { + acpi_get_handle(handle, prt->source, &entry->link.handle); + entry->link.index = prt->source_index; + } + /* + * Type 2: Static + * -------------- + * The 'source' field is NULL, and the 'source_index' field specifies + * the IRQ value, which is hardwired to specific interrupt inputs on + * the interrupt controller. + */ + else + entry->link.index = prt->source_index; + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, + " %02X:%02X:%02X[%c] -> %s[%d]\n", + entry->id.segment, entry->id.bus, entry->id.device, + ('A' + entry->pin), prt->source, entry->link.index)); + + /* TBD: Acquire/release lock */ + list_add_tail(&entry->node, &acpi_prt.entries); + acpi_prt.count++; + + return_VALUE(0); +} + + +int +acpi_pci_irq_add_prt ( + acpi_handle handle, + int segment, + int bus) +{ + acpi_status status = AE_OK; + char pathname[ACPI_PATHNAME_MAX] = {0}; + struct acpi_buffer buffer = {0, NULL}; + struct acpi_pci_routing_table *prt = NULL; + struct acpi_pci_routing_table *entry = NULL; + static int first_time = 1; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt"); + + if (first_time) { + acpi_prt.count = 0; + INIT_LIST_HEAD(&acpi_prt.entries); + first_time = 0; + } + + /* + * NOTE: We're given a 'handle' to the _PRT object's parent device + * (either a PCI root bridge or PCI-PCI bridge). + */ + + buffer.length = sizeof(pathname); + buffer.pointer = pathname; + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + + printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", + pathname); + + /* + * Evaluate this _PRT and add its entries to our global list (acpi_prt). + */ + + buffer.length = 0; + buffer.pointer = NULL; + status = acpi_get_irq_routing_table(handle, &buffer); + if (status != AE_BUFFER_OVERFLOW) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", + acpi_format_exception(status))); + return_VALUE(-ENODEV); + } + + prt = kmalloc(buffer.length, GFP_KERNEL); + if (!prt) + return_VALUE(-ENOMEM); + memset(prt, 0, buffer.length); + buffer.pointer = prt; + + status = acpi_get_irq_routing_table(handle, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", + acpi_format_exception(status))); + kfree(buffer.pointer); + return_VALUE(-ENODEV); + } + + entry = prt; + + while (entry && (entry->length > 0)) { + acpi_pci_irq_add_entry(handle, segment, bus, entry); + entry = (struct acpi_pci_routing_table *) + ((unsigned long) entry + entry->length); + } + + kfree(prt); + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + PCI Interrupt Routing Support + -------------------------------------------------------------------------- */ + +int +acpi_pci_irq_lookup ( + int segment, + int bus, + int device, + int pin) +{ + struct acpi_prt_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Searching for PRT entry for %02x:%02x:%02x[%c]\n", + segment, bus, device, ('A' + pin))); + + entry = acpi_pci_irq_find_prt_entry(segment, bus, device, pin); + if (!entry) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); + return_VALUE(0); + } + + if (!entry->irq && entry->link.handle) { + entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL); + if (!entry->irq) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); + return_VALUE(0); + } + } + else if (!entry->irq) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry (IRQ 0)\n")); + return_VALUE(0); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq)); + + return_VALUE(entry->irq); +} + + +static int +acpi_pci_irq_derive ( + struct pci_dev *dev, + int pin) +{ + struct pci_dev *bridge = dev; + int irq = 0; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_derive"); + + if (!dev) + return_VALUE(-EINVAL); + + /* + * Attempt to derive an IRQ for this device from a parent bridge's + * PCI interrupt routing entry (a.k.a. the "bridge swizzle"). + */ + while (!irq && bridge->bus->self) { + pin = (pin + PCI_SLOT(bridge->devfn)) % 4; + bridge = bridge->bus->self; + irq = acpi_pci_irq_lookup(0, bridge->bus->number, PCI_SLOT(bridge->devfn), pin); + } + + if (!irq) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to derive IRQ for device %s\n", dev->slot_name)); + return_VALUE(0); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived IRQ %d\n", irq)); + + return_VALUE(irq); +} + + +int +acpi_pci_irq_enable ( + struct pci_dev *dev) +{ + int irq = 0; + u8 pin = 0; + static u16 irq_mask = 0; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); + + if (!dev) + return_VALUE(-EINVAL); + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (!pin) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", dev->slot_name)); + return_VALUE(0); + } + pin--; + + if (!dev->bus) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) 'bus' field\n")); + return_VALUE(-ENODEV); + } + + /* + * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT + * values override any BIOS-assigned IRQs set during boot. + */ + irq = acpi_pci_irq_lookup(0, dev->bus->number, PCI_SLOT(dev->devfn), pin); + + /* + * If no PRT entry was found, we'll try to derive an IRQ from the + * device's parent bridge. + */ + if (!irq) + irq = acpi_pci_irq_derive(dev, pin); + + /* + * No IRQ known to the ACPI subsystem - maybe the BIOS / + * driver reported one, then use it. Exit in any case. + */ + if (!irq) { + printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), dev->slot_name); + /* Interrupt Line values above 0xF are forbidden */ + if (dev->irq && dev->irq >= 0xF) { + printk(" - using IRQ %d\n", dev->irq); + return_VALUE(dev->irq); + } + else { + printk("\n"); + return_VALUE(0); + } + } + + dev->irq = irq; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", dev->slot_name, dev->irq)); + + /* + * Make sure all (legacy) PCI IRQs are set as level-triggered. + */ +#ifdef CONFIG_X86 + if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq)); + irq_mask |= (1 << dev->irq); + eisa_set_level_irq(dev->irq); + } +#endif +#ifdef CONFIG_IOSAPIC + if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC) + iosapic_enable_intr(dev->irq); +#endif + + return_VALUE(dev->irq); +} + + +int __init +acpi_pci_irq_init (void) +{ + struct pci_dev *dev = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_init"); + + if (!acpi_prt.count) { + printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ " + "routing entries\n"); + return_VALUE(-ENODEV); + } + + /* Make sure all link devices have a valid IRQ. */ + if (acpi_pci_link_check()) { + return_VALUE(-ENODEV); + } + +#ifdef CONFIG_X86_IO_APIC + /* Program IOAPICs using data from PRT entries. */ + if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) + mp_parse_prt(); +#endif +#ifdef CONFIG_IOSAPIC + if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC) + iosapic_parse_prt(); +#endif + + pci_for_each_dev(dev) + acpi_pci_irq_enable(dev); + + return_VALUE(0); +} diff -urN linux-2.4.21/drivers/acpi/pci_link.c linux-2.4.22/drivers/acpi/pci_link.c --- linux-2.4.21/drivers/acpi/pci_link.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/pci_link.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,629 @@ +/* + * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 35 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2002 Dominik Brodowski + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * TBD: + * 1. Support more than one IRQ resource entry per link device (index). + * 2. Implement start/stop mechanism and use ACPI Bus Driver facilities + * for IRQ management (e.g. start()->_SRS). + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#define _COMPONENT ACPI_PCI_COMPONENT +ACPI_MODULE_NAME ("pci_link") + +#define PREFIX "ACPI: " + + +#define ACPI_PCI_LINK_MAX_POSSIBLE 16 + +static int acpi_pci_link_add (struct acpi_device *device); +static int acpi_pci_link_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_pci_link_driver = { + .name = ACPI_PCI_LINK_DRIVER_NAME, + .class = ACPI_PCI_LINK_CLASS, + .ids = ACPI_PCI_LINK_HID, + .ops = { + .add = acpi_pci_link_add, + .remove = acpi_pci_link_remove, + }, +}; + +struct acpi_pci_link_irq { + u8 active; /* Current IRQ */ + u8 edge_level; /* All IRQs */ + u8 active_high_low; /* All IRQs */ + u8 setonboot; + u8 possible_count; + u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; +}; + +struct acpi_pci_link { + struct list_head node; + struct acpi_device *device; + acpi_handle handle; + struct acpi_pci_link_irq irq; +}; + +static struct { + int count; + struct list_head entries; +} acpi_link; + + +/* -------------------------------------------------------------------------- + PCI Link Device Management + -------------------------------------------------------------------------- */ + +static acpi_status +acpi_pci_link_check_possible ( + struct acpi_resource *resource, + void *context) +{ + struct acpi_pci_link *link = (struct acpi_pci_link *) context; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible"); + + switch (resource->id) { + case ACPI_RSTYPE_START_DPF: + return AE_OK; + case ACPI_RSTYPE_IRQ: + { + struct acpi_resource_irq *p = &resource->data.irq; + if (!p || !p->number_of_interrupts) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n")); + return AE_OK; + } + for (i = 0; (inumber_of_interrupts && iinterrupts[i]) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i])); + continue; + } + link->irq.possible[i] = p->interrupts[i]; + link->irq.possible_count++; + } + link->irq.edge_level = p->edge_level; + link->irq.active_high_low = p->active_high_low; + break; + } + case ACPI_RSTYPE_EXT_IRQ: + { + struct acpi_resource_ext_irq *p = &resource->data.extended_irq; + if (!p || !p->number_of_interrupts) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Blank IRQ resource\n")); + return AE_OK; + } + for (i = 0; (inumber_of_interrupts && iinterrupts[i]) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i])); + continue; + } + link->irq.possible[i] = p->interrupts[i]; + link->irq.possible_count++; + } + link->irq.edge_level = p->edge_level; + link->irq.active_high_low = p->active_high_low; + break; + } + default: + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Resource is not an IRQ entry\n")); + return AE_OK; + } + + return AE_CTRL_TERMINATE; +} + + +static int +acpi_pci_link_get_possible ( + struct acpi_pci_link *link) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible"); + + if (!link) + return_VALUE(-EINVAL); + + status = acpi_walk_resources(link->handle, METHOD_NAME__PRS, + acpi_pci_link_check_possible, link); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n")); + return_VALUE(-ENODEV); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Found %d possible IRQs\n", link->irq.possible_count)); + + return_VALUE(0); +} + + +static acpi_status +acpi_pci_link_check_current ( + struct acpi_resource *resource, + void *context) +{ + int *irq = (int *) context; + + ACPI_FUNCTION_TRACE("acpi_pci_link_check_current"); + + switch (resource->id) { + case ACPI_RSTYPE_IRQ: + { + struct acpi_resource_irq *p = &resource->data.irq; + if (!p || !p->number_of_interrupts) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Blank IRQ resource\n")); + return AE_OK; + } + *irq = p->interrupts[0]; + break; + } + case ACPI_RSTYPE_EXT_IRQ: + { + struct acpi_resource_ext_irq *p = &resource->data.extended_irq; + if (!p || !p->number_of_interrupts) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Blank IRQ resource\n")); + return AE_OK; + } + *irq = p->interrupts[0]; + break; + } + default: + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Resource isn't an IRQ\n")); + return AE_OK; + } + return AE_CTRL_TERMINATE; +} + + +static int +acpi_pci_link_get_current ( + struct acpi_pci_link *link) +{ + int result = 0; + acpi_status status = AE_OK; + int irq = 0; + + ACPI_FUNCTION_TRACE("acpi_pci_link_get_current"); + + if (!link || !link->handle) + return_VALUE(-EINVAL); + + link->irq.active = 0; + + /* Make sure the link is enabled (no use querying if it isn't). */ + result = acpi_bus_get_status(link->device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n")); + goto end; + } + if (!link->device->status.enabled) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n")); + return_VALUE(0); + } + + /* + * Query and parse _CRS to get the current IRQ assignment. + */ + + status = acpi_walk_resources(link->handle, METHOD_NAME__CRS, + acpi_pci_link_check_current, &irq); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n")); + result = -ENODEV; + goto end; + } + + if (!irq) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No IRQ resource found\n")); + result = -ENODEV; + goto end; + } + + /* + * Note that we don't validate that the current IRQ (_CRS) exists + * within the possible IRQs (_PRS): we blindly assume that whatever + * IRQ a boot-enabled Link device is set to is the correct one. + * (Required to support systems such as the Toshiba 5005-S504.) + */ + link->irq.active = irq; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active)); + +end: + return_VALUE(result); +} + + +static int +acpi_pci_link_set ( + struct acpi_pci_link *link, + int irq) +{ + int result = 0; + acpi_status status = AE_OK; + struct { + struct acpi_resource res; + struct acpi_resource end; + } resource; + struct acpi_buffer buffer = {sizeof(resource)+1, &resource}; + int i = 0; + int valid = 0; + + ACPI_FUNCTION_TRACE("acpi_pci_link_set"); + + if (!link || !irq) + return_VALUE(-EINVAL); + + /* We don't check irqs the first time around */ + if (link->irq.setonboot) { + /* See if we're already at the target IRQ. */ + if (irq == link->irq.active) + return_VALUE(0); + + /* Make sure the target IRQ in the list of possible IRQs. */ + for (i=0; iirq.possible_count; i++) { + if (irq == link->irq.possible[i]) + valid = 1; + } + if (!valid) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq)); + return_VALUE(-EINVAL); + } + } + + memset(&resource, 0, sizeof(resource)); + + /* NOTE: PCI interrupts are always level / active_low / shared. But not all + interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for + parameters */ + if (irq <= 15) { + resource.res.id = ACPI_RSTYPE_IRQ; + resource.res.length = sizeof(struct acpi_resource); + resource.res.data.irq.edge_level = link->irq.edge_level; + resource.res.data.irq.active_high_low = link->irq.active_high_low; + resource.res.data.irq.shared_exclusive = ACPI_SHARED; + resource.res.data.irq.number_of_interrupts = 1; + resource.res.data.irq.interrupts[0] = irq; + } + else { + resource.res.id = ACPI_RSTYPE_EXT_IRQ; + resource.res.length = sizeof(struct acpi_resource); + resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER; + resource.res.data.extended_irq.edge_level = link->irq.edge_level; + resource.res.data.extended_irq.active_high_low = link->irq.active_high_low; + resource.res.data.extended_irq.shared_exclusive = ACPI_SHARED; + resource.res.data.extended_irq.number_of_interrupts = 1; + resource.res.data.extended_irq.interrupts[0] = irq; + /* ignore resource_source, it's optional */ + } + resource.end.id = ACPI_RSTYPE_END_TAG; + + /* Attempt to set the resource */ + status = acpi_set_current_resources(link->handle, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n")); + return_VALUE(-ENODEV); + } + + /* Make sure the device is enabled. */ + result = acpi_bus_get_status(link->device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n")); + return_VALUE(result); + } + if (!link->device->status.enabled) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); + return_VALUE(-ENODEV); + } + + /* Make sure the active IRQ is the one we requested. */ + result = acpi_pci_link_get_current(link); + if (result) { + return_VALUE(result); + } + + if (link->irq.active != irq) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Attempt to enable at IRQ %d resulted in IRQ %d\n", + irq, link->irq.active)); + link->irq.active = 0; + acpi_ut_evaluate_object (link->handle, "_DIS", 0, NULL); + return_VALUE(-ENODEV); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active)); + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + PCI Link IRQ Management + -------------------------------------------------------------------------- */ + +#define ACPI_MAX_IRQS 256 +#define ACPI_MAX_ISA_IRQ 16 + +/* + * IRQ penalties are used to promote PCI IRQ balancing. We set each ISA- + * possible IRQ (0-15) with a default penalty relative to its feasibility + * for PCI's use: + * + * Never use: 0, 1, 2 (timer, keyboard, and cascade) + * Avoid using: 13, 14, and 15 (FP error and IDE) + * Penalize: 3, 4, 6, 7, 12 (known ISA uses) + * + * Thus we're left with IRQs 5, 9, 10, 11, and everything above 15 (IO[S]APIC) + * as 'best bets' for PCI use. + */ + +static int acpi_irq_penalty[ACPI_MAX_IRQS] = { + 1000000, 1000000, 1000000, 10000, + 10000, 0, 10000, 10000, + 10000, 0, 0, 0, + 10000, 100000, 100000, 100000, +}; + + +int +acpi_pci_link_check (void) +{ + struct list_head *node = NULL; + struct acpi_pci_link *link = NULL; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_pci_link_check"); + + /* + * Update penalties to facilitate IRQ balancing. + */ + list_for_each(node, &acpi_link.entries) { + + link = list_entry(node, struct acpi_pci_link, node); + if (!link) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); + continue; + } + + if (link->irq.active) + acpi_irq_penalty[link->irq.active] += 100; + else if (link->irq.possible_count) { + int penalty = 100 / link->irq.possible_count; + for (i=0; iirq.possible_count; i++) { + if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ) + acpi_irq_penalty[link->irq.possible[i]] += penalty; + } + } + } + + return_VALUE(0); +} + +static int acpi_pci_link_allocate(struct acpi_pci_link* link) { + int irq; + int i; + + ACPI_FUNCTION_TRACE("acpi_pci_link_allocate"); + + if (link->irq.setonboot) + return_VALUE(0); + + if (link->irq.active) { + irq = link->irq.active; + } else { + irq = link->irq.possible[0]; + } + + /* + * Select the best IRQ. This is done in reverse to promote + * the use of IRQs 9, 10, 11, and >15. + */ + for (i=(link->irq.possible_count-1); i>0; i--) { + if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]]) + irq = link->irq.possible[i]; + } + + /* Attempt to enable the link device at this IRQ. */ + if (acpi_pci_link_set(link, irq)) { + printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS). Aborting ACPI-based IRQ routing. Try pci=noacpi or acpi=off\n", + acpi_device_name(link->device), + acpi_device_bid(link->device)); + return_VALUE(-ENODEV); + } else { + acpi_irq_penalty[link->irq.active] += 100; + printk(PREFIX "%s [%s] enabled at IRQ %d\n", + acpi_device_name(link->device), + acpi_device_bid(link->device), link->irq.active); + } + + link->irq.setonboot = 1; + return_VALUE(0); +} + + +int +acpi_pci_link_get_irq ( + acpi_handle handle, + int index, + int* edge_level, + int* active_high_low) +{ + int result = 0; + struct acpi_device *device = NULL; + struct acpi_pci_link *link = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_link_get_irq"); + + result = acpi_bus_get_device(handle, &device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n")); + return_VALUE(0); + } + + link = (struct acpi_pci_link *) acpi_driver_data(device); + if (!link) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); + return_VALUE(0); + } + + /* TBD: Support multiple index (IRQ) entries per Link Device */ + if (index) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid index %d\n", index)); + return_VALUE(0); + } + + if (acpi_pci_link_allocate(link)) { + return -ENODEV; + } + + if (!link->irq.active) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); + return_VALUE(0); + } + + if (edge_level) *edge_level = link->irq.edge_level; + if (active_high_low) *active_high_low = link->irq.active_high_low; + return_VALUE(link->irq.active); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +static int +acpi_pci_link_add ( + struct acpi_device *device) +{ + int result = 0; + struct acpi_pci_link *link = NULL; + int i = 0; + int found = 0; + + ACPI_FUNCTION_TRACE("acpi_pci_link_add"); + + if (!device) + return_VALUE(-EINVAL); + + link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); + if (!link) + return_VALUE(-ENOMEM); + memset(link, 0, sizeof(struct acpi_pci_link)); + + link->device = device; + link->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_PCI_LINK_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_PCI_LINK_CLASS); + acpi_driver_data(device) = link; + + result = acpi_pci_link_get_possible(link); + if (result) + goto end; + + acpi_pci_link_get_current(link); + + printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), acpi_device_bid(device)); + for (i = 0; i < link->irq.possible_count; i++) { + if (link->irq.active == link->irq.possible[i]) { + printk(" *%d", link->irq.possible[i]); + found = 1; + } + else + printk(" %d", link->irq.possible[i]); + } + if (!link->irq.active) + printk(", disabled"); + else if (!found) + printk(", enabled at IRQ %d", link->irq.active); + printk(")\n"); + + /* TBD: Acquire/release lock */ + list_add_tail(&link->node, &acpi_link.entries); + acpi_link.count++; + +end: + if (result) + kfree(link); + + return_VALUE(result); +} + + +static int +acpi_pci_link_remove ( + struct acpi_device *device, + int type) +{ + struct acpi_pci_link *link = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_link_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + link = (struct acpi_pci_link *) acpi_driver_data(device); + + /* TBD: Acquire/release lock */ + list_del(&link->node); + + kfree(link); + + return_VALUE(0); +} + + +int __init +acpi_pci_link_init (void) +{ + ACPI_FUNCTION_TRACE("acpi_pci_link_init"); + + acpi_link.count = 0; + INIT_LIST_HEAD(&acpi_link.entries); + + if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0) + return_VALUE(-ENODEV); + + return_VALUE(0); +} diff -urN linux-2.4.21/drivers/acpi/pci_root.c linux-2.4.22/drivers/acpi/pci_root.c --- linux-2.4.21/drivers/acpi/pci_root.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/pci_root.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,394 @@ +/* + * pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 41 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_PCI_COMPONENT +ACPI_MODULE_NAME ("pci_root") + +extern struct pci_ops *pci_root_ops; + +#define PREFIX "ACPI: " + +static int acpi_pci_root_add (struct acpi_device *device); +static int acpi_pci_root_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_pci_root_driver = { + .name = ACPI_PCI_ROOT_DRIVER_NAME, + .class = ACPI_PCI_ROOT_CLASS, + .ids = ACPI_PCI_ROOT_HID, + .ops = { + .add = acpi_pci_root_add, + .remove = acpi_pci_root_remove, + }, +}; + +struct acpi_pci_root { + struct list_head node; + acpi_handle handle; + struct acpi_pci_id id; + struct pci_bus *bus; + u64 mem_tra; + u64 io_tra; +}; + +struct list_head acpi_pci_roots; + +static struct acpi_pci_driver *sub_driver; + +int acpi_pci_register_driver(struct acpi_pci_driver *driver) +{ + int n = 0; + struct list_head *entry; + + struct acpi_pci_driver **pptr = &sub_driver; + while (*pptr) + pptr = &(*pptr)->next; + *pptr = driver; + + if (!driver->add) + return 0; + + list_for_each(entry, &acpi_pci_roots) { + struct acpi_pci_root *root; + root = list_entry(entry, struct acpi_pci_root, node); + driver->add(root->handle); + n++; + } + + return n; +} + +void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) +{ + struct list_head *entry; + + struct acpi_pci_driver **pptr = &sub_driver; + while (*pptr) { + if (*pptr != driver) + continue; + *pptr = (*pptr)->next; + break; + } + + if (!driver->remove) + return; + + list_for_each(entry, &acpi_pci_roots) { + struct acpi_pci_root *root; + root = list_entry(entry, struct acpi_pci_root, node); + driver->remove(root->handle); + } +} + +void +acpi_pci_get_translations ( + struct acpi_pci_id *id, + u64 *mem_tra, + u64 *io_tra) +{ + struct list_head *node = NULL; + struct acpi_pci_root *entry; + + /* TBD: Locking */ + list_for_each(node, &acpi_pci_roots) { + entry = list_entry(node, struct acpi_pci_root, node); + if ((id->segment == entry->id.segment) + && (id->bus == entry->id.bus)) { + *mem_tra = entry->mem_tra; + *io_tra = entry->io_tra; + return; + } + } + + *mem_tra = 0; + *io_tra = 0; +} + + +static u64 +acpi_pci_root_bus_tra ( + struct acpi_resource *resource, + int type) +{ + struct acpi_resource_address16 *address16; + struct acpi_resource_address32 *address32; + struct acpi_resource_address64 *address64; + + while (1) { + switch (resource->id) { + case ACPI_RSTYPE_END_TAG: + return 0; + + case ACPI_RSTYPE_ADDRESS16: + address16 = (struct acpi_resource_address16 *) &resource->data; + if (type == address16->resource_type) { + return address16->address_translation_offset; + } + break; + + case ACPI_RSTYPE_ADDRESS32: + address32 = (struct acpi_resource_address32 *) &resource->data; + if (type == address32->resource_type) { + return address32->address_translation_offset; + } + break; + + case ACPI_RSTYPE_ADDRESS64: + address64 = (struct acpi_resource_address64 *) &resource->data; + if (type == address64->resource_type) { + return address64->address_translation_offset; + } + break; + } + resource = ACPI_PTR_ADD (struct acpi_resource, + resource, resource->length); + } + + return 0; +} + + +static int +acpi_pci_evaluate_crs ( + struct acpi_pci_root *root) +{ + acpi_status status; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + + ACPI_FUNCTION_TRACE("acpi_pci_evaluate_crs"); + + status = acpi_get_current_resources (root->handle, &buffer); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + root->io_tra = acpi_pci_root_bus_tra ((struct acpi_resource *) + buffer.pointer, ACPI_IO_RANGE); + root->mem_tra = acpi_pci_root_bus_tra ((struct acpi_resource *) + buffer.pointer, ACPI_MEMORY_RANGE); + + acpi_os_free(buffer.pointer); + return_VALUE(0); +} + + +static int +acpi_pci_root_add ( + struct acpi_device *device) +{ + int result = 0; + struct acpi_pci_root *root = NULL; + acpi_status status = AE_OK; + unsigned long value = 0; + acpi_handle handle = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_root_add"); + + if (!device) + return_VALUE(-EINVAL); + + root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); + if (!root) + return_VALUE(-ENOMEM); + memset(root, 0, sizeof(struct acpi_pci_root)); + + root->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_PCI_ROOT_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_PCI_ROOT_CLASS); + acpi_driver_data(device) = root; + + /* + * TBD: Doesn't the bus driver automatically set this? + */ + device->ops.bind = acpi_pci_bind; + + /* + * Segment + * ------- + * Obtained via _SEG, if exists, otherwise assumed to be zero (0). + */ + status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL, + &value); + switch (status) { + case AE_OK: + root->id.segment = (u16) value; + printk("_SEG exists! Unsupported. Abort.\n"); + BUG(); + break; + case AE_NOT_FOUND: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Assuming segment 0 (no _SEG)\n")); + root->id.segment = 0; + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SEG\n")); + result = -ENODEV; + goto end; + } + + /* + * Bus + * --- + * Obtained via _BBN, if exists, otherwise assumed to be zero (0). + */ + status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL, + &value); + switch (status) { + case AE_OK: + root->id.bus = (u16) value; + break; + case AE_NOT_FOUND: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n")); + root->id.bus = 0; + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BBN\n")); + result = -ENODEV; + goto end; + } + + /* + * Device & Function + * ----------------- + * Obtained from _ADR (which has already been evaluated for us). + */ + root->id.device = device->pnp.bus_address >> 16; + root->id.function = device->pnp.bus_address & 0xFFFF; + + /* + * Evaluate _CRS to get root bridge resources + * TBD: Need PCI interface for enumeration/configuration of roots. + */ + acpi_pci_evaluate_crs(root); + + /* TBD: Locking */ + list_add_tail(&root->node, &acpi_pci_roots); + + printk(KERN_INFO PREFIX "%s [%s] (%02x:%02x)\n", + acpi_device_name(device), acpi_device_bid(device), + root->id.segment, root->id.bus); + + /* + * Scan the Root Bridge + * -------------------- + * Must do this prior to any attempt to bind the root device, as the + * PCI namespace does not get created until this call is made (and + * thus the root bridge's pci_dev does not exist). + */ + root->bus = pcibios_scan_root(root->id.bus); + if (!root->bus) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Bus %02x:%02x not present in PCI namespace\n", + root->id.segment, root->id.bus)); + result = -ENODEV; + goto end; + } + + /* + * Attach ACPI-PCI Context + * ----------------------- + * Thus binding the ACPI and PCI devices. + */ + result = acpi_pci_bind_root(device, &root->id, root->bus); + if (result) + goto end; + + /* + * PCI Routing Table + * ----------------- + * Evaluate and parse _PRT, if exists. + */ + status = acpi_get_handle(root->handle, METHOD_NAME__PRT, &handle); + if (ACPI_SUCCESS(status)) + result = acpi_pci_irq_add_prt(root->handle, root->id.segment, + root->id.bus); + +end: + if (result) + kfree(root); + + return_VALUE(result); +} + + +static int +acpi_pci_root_remove ( + struct acpi_device *device, + int type) +{ + struct acpi_pci_root *root = NULL; + + ACPI_FUNCTION_TRACE("acpi_pci_root_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + root = (struct acpi_pci_root *) acpi_driver_data(device); + + kfree(root); + + return_VALUE(0); +} + + +int __init +acpi_pci_root_init (void) +{ + ACPI_FUNCTION_TRACE("acpi_pci_root_init"); + + /* DEBUG: + acpi_dbg_layer = ACPI_PCI_COMPONENT; + acpi_dbg_level = 0xFFFFFFFF; + */ + + INIT_LIST_HEAD(&acpi_pci_roots); + + if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) + return_VALUE(-ENODEV); + + return_VALUE(0); +} + + +void __exit +acpi_pci_root_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_pci_root_exit"); + + acpi_bus_unregister_driver(&acpi_pci_root_driver); + + return_VOID; +} diff -urN linux-2.4.21/drivers/acpi/power.c linux-2.4.22/drivers/acpi/power.c --- linux-2.4.21/drivers/acpi/power.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/power.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,604 @@ +/* + * acpi_power.c - ACPI Bus Power Management ($Revision: 38 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_POWER_COMPONENT +ACPI_MODULE_NAME ("acpi_power") + +#define PREFIX "ACPI: " + + +int acpi_power_add (struct acpi_device *device); +int acpi_power_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_power_driver = { + .name = ACPI_POWER_DRIVER_NAME, + .class = ACPI_POWER_CLASS, + .ids = ACPI_POWER_HID, + .ops = { + .add = acpi_power_add, + .remove = acpi_power_remove, + }, +}; + +struct acpi_power_resource +{ + acpi_handle handle; + acpi_bus_id name; + u32 system_level; + u32 order; + int state; + int references; +}; + +static struct list_head acpi_power_resource_list; + + +/* -------------------------------------------------------------------------- + Power Resource Management + -------------------------------------------------------------------------- */ + +static int +acpi_power_get_context ( + acpi_handle handle, + struct acpi_power_resource **resource) +{ + int result = 0; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_power_get_context"); + + if (!resource) + return_VALUE(-ENODEV); + + result = acpi_bus_get_device(handle, &device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context [%p]\n", + handle)); + return_VALUE(result); + } + + *resource = (struct acpi_power_resource *) acpi_driver_data(device); + if (!resource) + return_VALUE(-ENODEV); + + return_VALUE(0); +} + + +static int +acpi_power_get_state ( + struct acpi_power_resource *resource) +{ + acpi_status status = AE_OK; + unsigned long sta = 0; + + ACPI_FUNCTION_TRACE("acpi_power_get_state"); + + if (!resource) + return_VALUE(-EINVAL); + + status = acpi_evaluate_integer(resource->handle, "_STA", NULL, &sta); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + if (sta & 0x01) + resource->state = ACPI_POWER_RESOURCE_STATE_ON; + else + resource->state = ACPI_POWER_RESOURCE_STATE_OFF; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", + resource->name, resource->state?"on":"off")); + + return_VALUE(0); +} + + +static int +acpi_power_get_list_state ( + struct acpi_handle_list *list, + int *state) +{ + int result = 0; + struct acpi_power_resource *resource = NULL; + u32 i = 0; + + ACPI_FUNCTION_TRACE("acpi_power_get_list_state"); + + if (!list || !state) + return_VALUE(-EINVAL); + + /* The state of the list is 'on' IFF all resources are 'on'. */ + + for (i=0; icount; i++) { + result = acpi_power_get_context(list->handles[i], &resource); + if (result) + return_VALUE(result); + result = acpi_power_get_state(resource); + if (result) + return_VALUE(result); + + *state = resource->state; + + if (*state != ACPI_POWER_RESOURCE_STATE_ON) + break; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", + *state?"on":"off")); + + return_VALUE(result); +} + + +static int +acpi_power_on ( + acpi_handle handle) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_device *device = NULL; + struct acpi_power_resource *resource = NULL; + + ACPI_FUNCTION_TRACE("acpi_power_on"); + + result = acpi_power_get_context(handle, &resource); + if (result) + return_VALUE(result); + + resource->references++; + + if ((resource->references > 1) + || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n", + resource->name)); + return_VALUE(0); + } + + status = acpi_evaluate_object(resource->handle, "_ON", NULL, NULL); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + result = acpi_power_get_state(resource); + if (result) + return_VALUE(result); + if (resource->state != ACPI_POWER_RESOURCE_STATE_ON) + return_VALUE(-ENOEXEC); + + /* Update the power resource's _device_ power state */ + result = acpi_bus_get_device(resource->handle, &device); + if (result) + return_VALUE(result); + device->power.state = ACPI_STATE_D0; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", + resource->name)); + + return_VALUE(0); +} + + +static int +acpi_power_off_device ( + acpi_handle handle) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_device *device = NULL; + struct acpi_power_resource *resource = NULL; + + ACPI_FUNCTION_TRACE("acpi_power_off_device"); + + result = acpi_power_get_context(handle, &resource); + if (result) + return_VALUE(result); + + if (resource->references) + resource->references--; + + if (resource->references) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Resource [%s] is still in use, dereferencing\n", + device->pnp.bus_id)); + return_VALUE(0); + } + + if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", + device->pnp.bus_id)); + return_VALUE(0); + } + + status = acpi_evaluate_object(resource->handle, "_OFF", NULL, NULL); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + result = acpi_power_get_state(resource); + if (result) + return_VALUE(result); + if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF) + return_VALUE(-ENOEXEC); + + /* Update the power resource's _device_ power state */ + result = acpi_bus_get_device(resource->handle, &device); + if (result) + return_VALUE(result); + device->power.state = ACPI_STATE_D3; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", + resource->name)); + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Device Power Management + -------------------------------------------------------------------------- */ + +int +acpi_power_get_inferred_state ( + struct acpi_device *device) +{ + int result = 0; + struct acpi_handle_list *list = NULL; + int list_state = 0; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_power_get_inferred_state"); + + if (!device) + return_VALUE(-EINVAL); + + device->power.state = ACPI_STATE_UNKNOWN; + + /* + * We know a device's inferred power state when all the resources + * required for a given D-state are 'on'. + */ + for (i=ACPI_STATE_D0; ipower.states[i].resources; + if (list->count < 1) + continue; + + result = acpi_power_get_list_state(list, &list_state); + if (result) + return_VALUE(result); + + if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { + device->power.state = i; + return_VALUE(0); + } + } + + device->power.state = ACPI_STATE_D3; + + return_VALUE(0); +} + + +int +acpi_power_transition ( + struct acpi_device *device, + int state) +{ + int result = 0; + struct acpi_handle_list *cl = NULL; /* Current Resources */ + struct acpi_handle_list *tl = NULL; /* Target Resources */ + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_power_transition"); + + if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) + return_VALUE(-EINVAL); + + cl = &device->power.states[device->power.state].resources; + tl = &device->power.states[state].resources; + + device->power.state = ACPI_STATE_UNKNOWN; + + if (!cl->count && !tl->count) { + result = -ENODEV; + goto end; + } + + /* TBD: Resources must be ordered. */ + + /* + * First we reference all power resources required in the target list + * (e.g. so the device doesn't loose power while transitioning). + */ + for (i=0; icount; i++) { + result = acpi_power_on(tl->handles[i]); + if (result) + goto end; + } + + device->power.state = state; + + /* + * Then we dereference all power resources used in the current list. + */ + for (i=0; icount; i++) { + result = acpi_power_off_device(cl->handles[i]); + if (result) + goto end; + } + +end: + if (result) + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Error transitioning device [%s] to D%d\n", + device->pnp.bus_id, state)); + + return_VALUE(result); +} + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_power_dir = NULL; + + +static int +acpi_power_read_status ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_power_resource *resource = NULL; + char *p = page; + int len; + + ACPI_FUNCTION_TRACE("acpi_power_read_status"); + + if (!data || (off != 0)) + goto end; + + resource = (struct acpi_power_resource *) data; + + p += sprintf(p, "state: "); + switch (resource->state) { + case ACPI_POWER_RESOURCE_STATE_ON: + p += sprintf(p, "on\n"); + break; + case ACPI_POWER_RESOURCE_STATE_OFF: + p += sprintf(p, "off\n"); + break; + default: + p += sprintf(p, "unknown\n"); + break; + } + + p += sprintf(p, "system level: S%d\n", + resource->system_level); + p += sprintf(p, "order: %d\n", + resource->order); + p += sprintf(p, "reference count: %d\n", + resource->references); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_power_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_power_add_fs"); + + if (!device) + return_VALUE(-EINVAL); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_power_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + /* 'status' [R] */ + entry = create_proc_entry(ACPI_POWER_FILE_STATUS, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_POWER_FILE_STATUS)); + else { + entry->read_proc = acpi_power_read_status; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + + +static int +acpi_power_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_power_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_power_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +int +acpi_power_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_power_resource *resource = NULL; + union acpi_object acpi_object; + struct acpi_buffer buffer = {sizeof(acpi_object), &acpi_object}; + + ACPI_FUNCTION_TRACE("acpi_power_add"); + + if (!device) + return_VALUE(-EINVAL); + + resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); + if (!resource) + return_VALUE(-ENOMEM); + memset(resource, 0, sizeof(struct acpi_power_resource)); + + resource->handle = device->handle; + sprintf(resource->name, "%s", device->pnp.bus_id); + sprintf(acpi_device_name(device), "%s", ACPI_POWER_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_POWER_CLASS); + acpi_driver_data(device) = resource; + + /* Evalute the object to get the system level and resource order. */ + status = acpi_evaluate_object(resource->handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto end; + } + resource->system_level = acpi_object.power_resource.system_level; + resource->order = acpi_object.power_resource.resource_order; + + result = acpi_power_get_state(resource); + if (result) + goto end; + + switch (resource->state) { + case ACPI_POWER_RESOURCE_STATE_ON: + device->power.state = ACPI_STATE_D0; + break; + case ACPI_POWER_RESOURCE_STATE_OFF: + device->power.state = ACPI_STATE_D3; + break; + default: + device->power.state = ACPI_STATE_UNKNOWN; + break; + } + + result = acpi_power_add_fs(device); + if (result) + goto end; + + printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), + acpi_device_bid(device), resource->state?"on":"off"); + +end: + if (result) + kfree(resource); + + return_VALUE(result); +} + + +int +acpi_power_remove ( + struct acpi_device *device, + int type) +{ + struct acpi_power_resource *resource = NULL; + + ACPI_FUNCTION_TRACE("acpi_power_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + resource = (struct acpi_power_resource *) acpi_driver_data(device); + + acpi_power_remove_fs(device); + + kfree(resource); + + return_VALUE(0); +} + + +int __init +acpi_power_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_power_init"); + + INIT_LIST_HEAD(&acpi_power_resource_list); + + acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir); + if (!acpi_power_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_power_driver); + if (result < 0) { + remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +void __exit +acpi_power_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_power_exit"); + + /* TBD: Empty acpi_power_resource_list */ + + acpi_bus_unregister_driver(&acpi_power_driver); + + remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir); + + return_VOID; +} diff -urN linux-2.4.21/drivers/acpi/processor.c linux-2.4.22/drivers/acpi/processor.c --- linux-2.4.21/drivers/acpi/processor.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/processor.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,2328 @@ +/* + * acpi_processor.c - ACPI Processor Driver ($Revision: 69 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * TBD: + * 1. Make # power/performance states dynamic. + * 2. Support duty_cycle values that span bit 4. + * 3. Optimize by having scheduler determine business instead of + * having us try to calculate it here. + * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_PROCESSOR_COMPONENT +ACPI_MODULE_NAME ("acpi_processor") + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +#define PREFIX "ACPI: " + +#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) +#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ +#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ + +#define ACPI_PROCESSOR_BUSY_METRIC 10 + +#define ACPI_PROCESSOR_MAX_POWER ACPI_C_STATE_COUNT +#define ACPI_PROCESSOR_MAX_C2_LATENCY 100 +#define ACPI_PROCESSOR_MAX_C3_LATENCY 1000 + +#define ACPI_PROCESSOR_MAX_PERFORMANCE 8 + +#define ACPI_PROCESSOR_MAX_THROTTLING 16 +#define ACPI_PROCESSOR_MAX_THROTTLE 250 /* 25% */ +#define ACPI_PROCESSOR_MAX_DUTY_WIDTH 4 + +const u32 POWER_OF_2[] = {1,2,4,8,16,32,64}; + +#define ACPI_PROCESSOR_LIMIT_USER 0 +#define ACPI_PROCESSOR_LIMIT_THERMAL 1 + +static int acpi_processor_add (struct acpi_device *device); +static int acpi_processor_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_processor_driver = { + .name = ACPI_PROCESSOR_DRIVER_NAME, + .class = ACPI_PROCESSOR_CLASS, + .ids = ACPI_PROCESSOR_HID, + .ops = { + .add = acpi_processor_add, + .remove = acpi_processor_remove, + }, +}; + +/* Power Management */ + +struct acpi_processor_cx_policy { + u32 count; + int state; + struct { + u32 time; + u32 ticks; + u32 count; + u32 bm; + } threshold; +}; + +struct acpi_processor_cx { + u8 valid; + u32 address; + u32 latency; + u32 latency_ticks; + u32 power; + u32 usage; + struct acpi_processor_cx_policy promotion; + struct acpi_processor_cx_policy demotion; +}; + +struct acpi_processor_power { + int state; + int default_state; + u32 bm_activity; + struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; +}; + +/* Performance Management */ + +struct acpi_pct_register { + u8 descriptor; + u16 length; + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 reserved; + u64 address; +} __attribute__ ((packed)); + +struct acpi_processor_px { + acpi_integer core_frequency; /* megahertz */ + acpi_integer power; /* milliWatts */ + acpi_integer transition_latency; /* microseconds */ + acpi_integer bus_master_latency; /* microseconds */ + acpi_integer control; /* control value */ + acpi_integer status; /* success indicator */ +}; + +struct acpi_processor_performance { + int state; + int platform_limit; + u16 control_register; + u16 status_register; + int state_count; + struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE]; +}; + + +/* Throttling Control */ + +struct acpi_processor_tx { + u16 power; + u16 performance; +}; + +struct acpi_processor_throttling { + int state; + u32 address; + u8 duty_offset; + u8 duty_width; + int state_count; + struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; +}; + +/* Limit Interface */ + +struct acpi_processor_lx { + int px; /* performace state */ + int tx; /* throttle level */ +}; + +struct acpi_processor_limit { + struct acpi_processor_lx state; /* current limit */ + struct acpi_processor_lx thermal; /* thermal limit */ + struct acpi_processor_lx user; /* user limit */ +}; + + +struct acpi_processor_flags { + u8 power:1; + u8 performance:1; + u8 throttling:1; + u8 limit:1; + u8 bm_control:1; + u8 bm_check:1; + u8 reserved:2; +}; + +struct acpi_processor { + acpi_handle handle; + u32 acpi_id; + u32 id; + struct acpi_processor_flags flags; + struct acpi_processor_power power; + struct acpi_processor_performance performance; + struct acpi_processor_throttling throttling; + struct acpi_processor_limit limit; +}; + +struct acpi_processor_errata { + u8 smp; + struct { + u8 throttle:1; + u8 fdma:1; + u8 reserved:6; + u32 bmisx; + } piix4; +}; + +static struct acpi_processor *processors[NR_CPUS]; +static struct acpi_processor_errata errata; +static void (*pm_idle_save)(void) = NULL; + + +/* -------------------------------------------------------------------------- + Errata Handling + -------------------------------------------------------------------------- */ + +int +acpi_processor_errata_piix4 ( + struct pci_dev *dev) +{ + u8 rev = 0; + u8 value1 = 0; + u8 value2 = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_errata_piix4"); + + if (!dev) + return_VALUE(-EINVAL); + + /* + * Note that 'dev' references the PIIX4 ACPI Controller. + */ + + pci_read_config_byte(dev, PCI_REVISION_ID, &rev); + + switch (rev) { + case 0: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n")); + break; + case 1: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n")); + break; + case 2: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n")); + break; + case 3: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n")); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n")); + break; + } + + switch (rev) { + + case 0: /* PIIX4 A-step */ + case 1: /* PIIX4 B-step */ + /* + * See specification changes #13 ("Manual Throttle Duty Cycle") + * and #14 ("Enabling and Disabling Manual Throttle"), plus + * erratum #5 ("STPCLK# Deassertion Time") from the January + * 2002 PIIX4 specification update. Applies to only older + * PIIX4 models. + */ + errata.piix4.throttle = 1; + + case 2: /* PIIX4E */ + case 3: /* PIIX4M */ + /* + * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA + * Livelock") from the January 2002 PIIX4 specification update. + * Applies to all PIIX4 models. + */ + + /* + * BM-IDE + * ------ + * Find the PIIX4 IDE Controller and get the Bus Master IDE + * Status register address. We'll use this later to read + * each IDE controller's DMA status to make sure we catch all + * DMA activity. + */ + dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB, + PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev) + errata.piix4.bmisx = pci_resource_start(dev, 4); + + /* + * Type-F DMA + * ---------- + * Find the PIIX4 ISA Controller and read the Motherboard + * DMA controller's status to see if Type-F (Fast) DMA mode + * is enabled (bit 7) on either channel. Note that we'll + * disable C3 support if this is enabled, as some legacy + * devices won't operate well if fast DMA is disabled. + */ + dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_0, + PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev) { + pci_read_config_byte(dev, 0x76, &value1); + pci_read_config_byte(dev, 0x77, &value2); + if ((value1 & 0x80) || (value2 & 0x80)) + errata.piix4.fdma = 1; + } + + break; + } + + if (errata.piix4.bmisx) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Bus master activity detection (BM-IDE) erratum enabled\n")); + if (errata.piix4.fdma) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Type-F DMA livelock erratum (C3 disabled)\n")); + + return_VALUE(0); +} + + +int +acpi_processor_errata ( + struct acpi_processor *pr) +{ + int result = 0; + struct pci_dev *dev = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_errata"); + + if (!pr) + return_VALUE(-EINVAL); + + /* + * PIIX4 + */ + dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev) + result = acpi_processor_errata_piix4(dev); + + return_VALUE(result); +} + + +/* -------------------------------------------------------------------------- + Power Management + -------------------------------------------------------------------------- */ + +static inline u32 +ticks_elapsed ( + u32 t1, + u32 t2) +{ + if (t2 >= t1) + return (t2 - t1); + else if (!acpi_fadt.tmr_val_ext) + return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); + else + return ((0xFFFFFFFF - t1) + t2); +} + + +static void +acpi_processor_power_activate ( + struct acpi_processor *pr, + int state) +{ + if (!pr) + return; + + pr->power.states[pr->power.state].promotion.count = 0; + pr->power.states[pr->power.state].demotion.count = 0; + + /* Cleanup from old state. */ + switch (pr->power.state) { + case ACPI_STATE_C3: + /* Disable bus master reload */ + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK); + break; + } + + /* Prepare to use new state. */ + switch (state) { + case ACPI_STATE_C3: + /* Enable bus master reload */ + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK); + break; + } + + pr->power.state = state; + + return; +} + + +static void +acpi_processor_idle (void) +{ + struct acpi_processor *pr = NULL; + struct acpi_processor_cx *cx = NULL; + int next_state = 0; + int sleep_ticks = 0; + u32 t1, t2 = 0; + + pr = processors[smp_processor_id()]; + if (!pr) + return; + + /* + * Interrupts must be disabled during bus mastering calculations and + * for C2/C3 transitions. + */ + __cli(); + + cx = &(pr->power.states[pr->power.state]); + + /* + * Check BM Activity + * ----------------- + * Check for bus mastering activity (if required), record, and check + * for demotion. + */ + if (pr->flags.bm_check) { + u32 bm_status = 0; + + pr->power.bm_activity <<= 1; + + acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, + &bm_status, ACPI_MTX_DO_NOT_LOCK); + if (bm_status) { + pr->power.bm_activity++; + acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, + 1, ACPI_MTX_DO_NOT_LOCK); + } + /* + * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect + * the true state of bus mastering activity; forcing us to + * manually check the BMIDEA bit of each IDE channel. + */ + else if (errata.piix4.bmisx) { + if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) + || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) + pr->power.bm_activity++; + } + /* + * Apply bus mastering demotion policy. Automatically demote + * to avoid a faulty transition. Note that the processor + * won't enter a low-power state during this call (to this + * funciton) but should upon the next. + * + * TBD: A better policy might be to fallback to the demotion + * state (use it for this quantum only) istead of + * demoting -- and rely on duration as our sole demotion + * qualification. This may, however, introduce DMA + * issues (e.g. floppy DMA transfer overrun/underrun). + */ + if (pr->power.bm_activity & cx->demotion.threshold.bm) { + __sti(); + next_state = cx->demotion.state; + goto end; + } + } + + cx->usage++; + + /* + * Sleep: + * ------ + * Invoke the current Cx state to put the processor to sleep. + */ + switch (pr->power.state) { + + case ACPI_STATE_C1: + /* Invoke C1. */ + safe_halt(); + /* + * TBD: Can't get time duration while in C1, as resumes + * go to an ISR rather than here. Need to instrument + * base interrupt handler. + */ + sleep_ticks = 0xFFFFFFFF; + break; + + case ACPI_STATE_C2: + /* Get start time (ticks) */ + t1 = inl(acpi_fadt.xpm_tmr_blk.address); + /* Invoke C2 */ + inb(pr->power.states[ACPI_STATE_C2].address); + /* Dummy op - must do something useless after P_LVL2 read */ + t2 = inl(acpi_fadt.xpm_tmr_blk.address); + /* Get end time (ticks) */ + t2 = inl(acpi_fadt.xpm_tmr_blk.address); + /* Re-enable interrupts */ + __sti(); + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; + break; + + case ACPI_STATE_C3: + /* Disable bus master arbitration */ + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); + /* Get start time (ticks) */ + t1 = inl(acpi_fadt.xpm_tmr_blk.address); + /* Invoke C3 */ + inb(pr->power.states[ACPI_STATE_C3].address); + /* Dummy op - must do something useless after P_LVL3 read */ + t2 = inl(acpi_fadt.xpm_tmr_blk.address); + /* Get end time (ticks) */ + t2 = inl(acpi_fadt.xpm_tmr_blk.address); + /* Enable bus master arbitration */ + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK); + /* Re-enable interrupts */ + __sti(); + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; + break; + + default: + __sti(); + return; + } + + next_state = pr->power.state; + + /* + * Promotion? + * ---------- + * Track the number of longs (time asleep is greater than threshold) + * and promote when the count threshold is reached. Note that bus + * mastering activity may prevent promotions. + */ + if (cx->promotion.state) { + if (sleep_ticks > cx->promotion.threshold.ticks) { + cx->promotion.count++; + cx->demotion.count = 0; + if (cx->promotion.count >= cx->promotion.threshold.count) { + if (pr->flags.bm_check) { + if (!(pr->power.bm_activity & cx->promotion.threshold.bm)) { + next_state = cx->promotion.state; + goto end; + } + } + else { + next_state = cx->promotion.state; + goto end; + } + } + } + } + + /* + * Demotion? + * --------- + * Track the number of shorts (time asleep is less than time threshold) + * and demote when the usage threshold is reached. + */ + if (cx->demotion.state) { + if (sleep_ticks < cx->demotion.threshold.ticks) { + cx->demotion.count++; + cx->promotion.count = 0; + if (cx->demotion.count >= cx->demotion.threshold.count) { + next_state = cx->demotion.state; + goto end; + } + } + } + +end: + /* + * New Cx State? + * ------------- + * If we're going to start using a new Cx state we must clean up + * from the previous and prepare to use the new. + */ + if (next_state != pr->power.state) + acpi_processor_power_activate(pr, next_state); + + return; +} + + +static int +acpi_processor_set_power_policy ( + struct acpi_processor *pr) +{ + ACPI_FUNCTION_TRACE("acpi_processor_set_power_policy"); + + /* + * This function sets the default Cx state policy (OS idle handler). + * Our scheme is to promote quickly to C2 but more conservatively + * to C3. We're favoring C2 for its characteristics of low latency + * (quick response), good power savings, and ability to allow bus + * mastering activity. Note that the Cx state policy is completely + * customizable and can be altered dynamically. + */ + + if (!pr) + return_VALUE(-EINVAL); + + /* + * C0/C1 + * ----- + */ + pr->power.state = ACPI_STATE_C1; + pr->power.default_state = ACPI_STATE_C1; + + /* + * C1/C2 + * ----- + * Set the default C1 promotion and C2 demotion policies, where we + * promote from C1 to C2 after several (10) successive C1 transitions, + * as we cannot (currently) measure the time spent in C1. Demote from + * C2 to C1 anytime we experience a 'short' (time spent in C2 is less + * than the C2 transtion latency). Note the simplifying assumption + * that the 'cost' of a transition is amortized when we sleep for at + * least as long as the transition's latency (thus the total transition + * time is two times the latency). + * + * TBD: Measure C1 sleep times by instrumenting the core IRQ handler. + * TBD: Demote to default C-State after long periods of activity. + * TBD: Investigate policy's use of CPU utilization -vs- sleep duration. + */ + if (pr->power.states[ACPI_STATE_C2].valid) { + pr->power.states[ACPI_STATE_C1].promotion.threshold.count = 10; + pr->power.states[ACPI_STATE_C1].promotion.threshold.ticks = + pr->power.states[ACPI_STATE_C2].latency_ticks; + pr->power.states[ACPI_STATE_C1].promotion.state = ACPI_STATE_C2; + + pr->power.states[ACPI_STATE_C2].demotion.threshold.count = 1; + pr->power.states[ACPI_STATE_C2].demotion.threshold.ticks = + pr->power.states[ACPI_STATE_C2].latency_ticks; + pr->power.states[ACPI_STATE_C2].demotion.state = ACPI_STATE_C1; + } + + /* + * C2/C3 + * ----- + * Set default C2 promotion and C3 demotion policies, where we promote + * from C2 to C3 after several (4) cycles of no bus mastering activity + * while maintaining sleep time criteria. Demote immediately on a + * short or whenever bus mastering activity occurs. + */ + if ((pr->power.states[ACPI_STATE_C2].valid) && + (pr->power.states[ACPI_STATE_C3].valid)) { + pr->power.states[ACPI_STATE_C2].promotion.threshold.count = 4; + pr->power.states[ACPI_STATE_C2].promotion.threshold.ticks = + pr->power.states[ACPI_STATE_C3].latency_ticks; + pr->power.states[ACPI_STATE_C2].promotion.threshold.bm = 0x0F; + pr->power.states[ACPI_STATE_C2].promotion.state = ACPI_STATE_C3; + + pr->power.states[ACPI_STATE_C3].demotion.threshold.count = 1; + pr->power.states[ACPI_STATE_C3].demotion.threshold.ticks = + pr->power.states[ACPI_STATE_C3].latency_ticks; + pr->power.states[ACPI_STATE_C3].demotion.threshold.bm = 0x0F; + pr->power.states[ACPI_STATE_C3].demotion.state = ACPI_STATE_C2; + } + + return_VALUE(0); +} + + +int +acpi_processor_get_power_info ( + struct acpi_processor *pr) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_get_power_info"); + + if (!pr) + return_VALUE(-EINVAL); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "lvl2[0x%08x] lvl3[0x%08x]\n", + pr->power.states[ACPI_STATE_C2].address, + pr->power.states[ACPI_STATE_C3].address)); + + /* TBD: Support ACPI 2.0 objects */ + + /* + * C0 + * -- + * This state exists only as filler in our array. + */ + pr->power.states[ACPI_STATE_C0].valid = 1; + + /* + * C1 + * -- + * ACPI requires C1 support for all processors. + * + * TBD: What about PROC_C1? + */ + pr->power.states[ACPI_STATE_C1].valid = 1; + + /* + * C2 + * -- + * We're (currently) only supporting C2 on UP systems. + * + * TBD: Support for C2 on MP (P_LVL2_UP). + */ + if (pr->power.states[ACPI_STATE_C2].address) { + + pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat; + + /* + * C2 latency must be less than or equal to 100 microseconds. + */ + if (acpi_fadt.plvl2_lat > ACPI_PROCESSOR_MAX_C2_LATENCY) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C2 latency too large [%d]\n", + acpi_fadt.plvl2_lat)); + /* + * Only support C2 on UP systems (see TBD above). + */ + else if (errata.smp) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C2 not supported in SMP mode\n")); + /* + * Otherwise we've met all of our C2 requirements. + * Normalize the C2 latency to expidite policy. + */ + else { + pr->power.states[ACPI_STATE_C2].valid = 1; + pr->power.states[ACPI_STATE_C2].latency_ticks = + US_TO_PM_TIMER_TICKS(acpi_fadt.plvl2_lat); + } + } + + /* + * C3 + * -- + * TBD: Investigate use of WBINVD on UP/SMP system in absence of + * bm_control. + */ + if (pr->power.states[ACPI_STATE_C3].address) { + + pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat; + + /* + * C3 latency must be less than or equal to 1000 microseconds. + */ + if (acpi_fadt.plvl3_lat > ACPI_PROCESSOR_MAX_C3_LATENCY) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C3 latency too large [%d]\n", + acpi_fadt.plvl3_lat)); + /* + * Only support C3 when bus mastering arbitration control + * is present (able to disable bus mastering to maintain + * cache coherency while in C3). + */ + else if (!pr->flags.bm_control) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C3 support requires bus mastering control\n")); + /* + * Only support C3 on UP systems, as bm_control is only viable + * on a UP system and flushing caches (e.g. WBINVD) is simply + * too costly (at this time). + */ + else if (errata.smp) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C3 not supported in SMP mode\n")); + /* + * PIIX4 Erratum #18: We don't support C3 when Type-F (fast) + * DMA transfers are used by any ISA device to avoid livelock. + * Note that we could disable Type-F DMA (as recommended by + * the erratum), but this is known to disrupt certain ISA + * devices thus we take the conservative approach. + */ + else if (errata.piix4.fdma) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "C3 not supported on PIIX4 with Type-F DMA\n")); + } + /* + * Otherwise we've met all of our C3 requirements. + * Normalize the C2 latency to expidite policy. Enable + * checking of bus mastering status (bm_check) so we can + * use this in our C3 policy. + */ + else { + pr->power.states[ACPI_STATE_C3].valid = 1; + pr->power.states[ACPI_STATE_C3].latency_ticks = + US_TO_PM_TIMER_TICKS(acpi_fadt.plvl3_lat); + pr->flags.bm_check = 1; + } + } + + /* + * Set Default Policy + * ------------------ + * Now that we know which state are supported, set the default + * policy. Note that this policy can be changed dynamically + * (e.g. encourage deeper sleeps to conserve battery life when + * not on AC). + */ + result = acpi_processor_set_power_policy(pr); + if (result) + return_VALUE(result); + + /* + * If this processor supports C2 or C3 we denote it as being 'power + * manageable'. Note that there's really no policy involved for + * when only C1 is supported. + */ + if (pr->power.states[ACPI_STATE_C2].valid + || pr->power.states[ACPI_STATE_C3].valid) + pr->flags.power = 1; + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Performance Management + -------------------------------------------------------------------------- */ + +static int +acpi_processor_get_platform_limit ( + struct acpi_processor* pr) +{ + acpi_status status = 0; + unsigned long ppc = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_get_platform_limit"); + + if (!pr) + return_VALUE(-EINVAL); + + /* + * _PPC indicates the maximum state currently supported by the platform + * (e.g. 0 = states 0..n; 1 = states 1..n; etc. + */ + status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc); + if(ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n")); + return_VALUE(-ENODEV); + } + + pr->performance.platform_limit = (int) ppc; + + return_VALUE(0); +} + + +static int +acpi_processor_get_performance_control ( + struct acpi_processor *pr) +{ + int result = 0; + acpi_status status = 0; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *pct = NULL; + union acpi_object obj = {0}; + struct acpi_pct_register *reg = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control"); + + status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); + if(ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n")); + return_VALUE(-ENODEV); + } + + pct = (union acpi_object *) buffer.pointer; + if (!pct || (pct->type != ACPI_TYPE_PACKAGE) + || (pct->package.count != 2)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n")); + result = -EFAULT; + goto end; + } + + /* + * control_register + */ + + obj = pct->package.elements[0]; + + if ((obj.type != ACPI_TYPE_BUFFER) + || (obj.buffer.length < sizeof(struct acpi_pct_register)) + || (obj.buffer.pointer == NULL)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid _PCT data (control_register)\n")); + result = -EFAULT; + goto end; + } + + reg = (struct acpi_pct_register *) (obj.buffer.pointer); + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unsupported address space [%d] (control_register)\n", + (u32) reg->space_id)); + result = -EFAULT; + goto end; + } + + pr->performance.control_register = (u16) reg->address; + + /* + * status_register + */ + + obj = pct->package.elements[1]; + + if ((obj.type != ACPI_TYPE_BUFFER) + || (obj.buffer.length < sizeof(struct acpi_pct_register)) + || (obj.buffer.pointer == NULL)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid _PCT data (status_register)\n")); + result = -EFAULT; + goto end; + } + + reg = (struct acpi_pct_register *) (obj.buffer.pointer); + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unsupported address space [%d] (status_register)\n", + (u32) reg->space_id)); + result = -EFAULT; + goto end; + } + + pr->performance.status_register = (u16) reg->address; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "control_register[0x%04x] status_register[0x%04x]\n", + pr->performance.control_register, + pr->performance.status_register)); + +end: + acpi_os_free(buffer.pointer); + + return_VALUE(result); +} + + +static int +acpi_processor_get_performance_states ( + struct acpi_processor* pr) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_buffer format = {sizeof("NNNNNN"), "NNNNNN"}; + struct acpi_buffer state = {0, NULL}; + union acpi_object *pss = NULL; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states"); + + status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); + if(ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n")); + return_VALUE(-ENODEV); + } + + pss = (union acpi_object *) buffer.pointer; + if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); + result = -EFAULT; + goto end; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", + pss->package.count)); + + if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) { + pr->performance.state_count = ACPI_PROCESSOR_MAX_PERFORMANCE; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Limiting number of states to max (%d)\n", + ACPI_PROCESSOR_MAX_PERFORMANCE)); + } + else + pr->performance.state_count = pss->package.count; + + if (pr->performance.state_count > 1) + pr->flags.performance = 1; + + for (i = 0; i < pr->performance.state_count; i++) { + + struct acpi_processor_px *px = &(pr->performance.states[i]); + + state.length = sizeof(struct acpi_processor_px); + state.pointer = px; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i)); + + status = acpi_extract_package(&(pss->package.elements[i]), + &format, &state); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); + result = -EFAULT; + goto end; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", + i, + (u32) px->core_frequency, + (u32) px->power, + (u32) px->transition_latency, + (u32) px->bus_master_latency, + (u32) px->control, + (u32) px->status)); + } + +end: + acpi_os_free(buffer.pointer); + + return_VALUE(result); +} + + +static int +acpi_processor_set_performance ( + struct acpi_processor *pr, + int state) +{ + u16 port = 0; + u8 value = 0; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); + + if (!pr) + return_VALUE(-EINVAL); + + if (!pr->flags.performance) + return_VALUE(-ENODEV); + + if (state >= pr->performance.state_count) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Invalid target state (P%d)\n", state)); + return_VALUE(-ENODEV); + } + + if (state < pr->performance.platform_limit) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Platform limit (P%d) overrides target state (P%d)\n", + pr->performance.platform_limit, state)); + return_VALUE(-ENODEV); + } + + if (state == pr->performance.state) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Already at target state (P%d)\n", state)); + return_VALUE(0); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n", + pr->performance.state, state)); + + /* + * First we write the target state's 'control' value to the + * control_register. + */ + + port = pr->performance.control_register; + value = (u16) pr->performance.states[state].control; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Writing 0x%02x to port 0x%04x\n", value, port)); + + outb(value, port); + + /* + * Then we read the 'status_register' and compare the value with the + * target state's 'status' to make sure the transition was successful. + * Note that we'll poll for up to 1ms (100 cycles of 10us) before + * giving up. + */ + + port = pr->performance.status_register; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Looking for 0x%02x from port 0x%04x\n", + (u8) pr->performance.states[state].status, port)); + + for (i=0; i<100; i++) { + value = inb(port); + if (value == (u8) pr->performance.states[state].status) + break; + udelay(10); + } + + if (value != pr->performance.states[state].status) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); + return_VALUE(-ENODEV); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Transition successful after %d microseconds\n", + i * 10)); + + pr->performance.state = state; + + return_VALUE(0); +} + + +static int +acpi_processor_get_performance_info ( + struct acpi_processor *pr) +{ + int result = 0; + acpi_status status = AE_OK; + acpi_handle handle = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info"); + + if (!pr) + return_VALUE(-EINVAL); + + status = acpi_get_handle(pr->handle, "_PCT", &handle); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "ACPI-based processor performance control unavailable\n")); + return_VALUE(0); + } + + result = acpi_processor_get_performance_control(pr); + if (result) + return_VALUE(result); + + result = acpi_processor_get_performance_states(pr); + if (result) + return_VALUE(result); + + result = acpi_processor_get_platform_limit(pr); + if (result) + return_VALUE(result); + + /* + * TBD: Don't trust the latency values we get from BIOS, but rather + * measure the latencies during run-time (e.g. get_latencies). + */ + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Throttling Control + -------------------------------------------------------------------------- */ + +static int +acpi_processor_get_throttling ( + struct acpi_processor *pr) +{ + int state = 0; + u32 value = 0; + u32 duty_mask = 0; + u32 duty_value = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_get_throttling"); + + if (!pr) + return_VALUE(-EINVAL); + + if (!pr->flags.throttling) + return_VALUE(-ENODEV); + + pr->throttling.state = 0; + + __cli(); + + duty_mask = pr->throttling.state_count - 1; + + duty_mask <<= pr->throttling.duty_offset; + + value = inl(pr->throttling.address); + + /* + * Compute the current throttling state when throttling is enabled + * (bit 4 is on). + */ + if (value & 0x10) { + duty_value = value & duty_mask; + duty_value >>= pr->throttling.duty_offset; + + if (duty_value) + state = pr->throttling.state_count-duty_value; + } + + pr->throttling.state = state; + + __sti(); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Throttling state is T%d (%d%% throttling applied)\n", + state, pr->throttling.states[state].performance)); + + return_VALUE(0); +} + + +static int +acpi_processor_set_throttling ( + struct acpi_processor *pr, + int state) +{ + u32 value = 0; + u32 duty_mask = 0; + u32 duty_value = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_set_throttling"); + + if (!pr) + return_VALUE(-EINVAL); + + if ((state < 0) || (state > (pr->throttling.state_count - 1))) + return_VALUE(-EINVAL); + + if (!pr->flags.throttling) + return_VALUE(-ENODEV); + + if (state == pr->throttling.state) + return_VALUE(0); + + __cli(); + + /* + * Calculate the duty_value and duty_mask. + */ + if (state) { + duty_value = pr->throttling.state_count - state; + + duty_value <<= pr->throttling.duty_offset; + + /* Used to clear all duty_value bits */ + duty_mask = pr->throttling.state_count - 1; + + duty_mask <<= acpi_fadt.duty_offset; + duty_mask = ~duty_mask; + } + + /* + * Disable throttling by writing a 0 to bit 4. Note that we must + * turn it off before you can change the duty_value. + */ + value = inl(pr->throttling.address); + if (value & 0x10) { + value &= 0xFFFFFFEF; + outl(value, pr->throttling.address); + } + + /* + * Write the new duty_value and then enable throttling. Note + * that a state value of 0 leaves throttling disabled. + */ + if (state) { + value &= duty_mask; + value |= duty_value; + outl(value, pr->throttling.address); + + value |= 0x00000010; + outl(value, pr->throttling.address); + } + + pr->throttling.state = state; + + __sti(); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Throttling state set to T%d (%d%%)\n", state, + (pr->throttling.states[state].performance?pr->throttling.states[state].performance/10:0))); + + return_VALUE(0); +} + + +static int +acpi_processor_get_throttling_info ( + struct acpi_processor *pr) +{ + int result = 0; + int step = 0; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_get_throttling_info"); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", + pr->throttling.address, + pr->throttling.duty_offset, + pr->throttling.duty_width)); + + if (!pr) + return_VALUE(-EINVAL); + + /* TBD: Support ACPI 2.0 objects */ + + if (!pr->throttling.address) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); + return_VALUE(0); + } + else if (!pr->throttling.duty_width) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n")); + return_VALUE(0); + } + /* TBD: Support duty_cycle values that span bit 4. */ + else if ((pr->throttling.duty_offset + + pr->throttling.duty_width) > 4) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "duty_cycle spans bit 4\n")); + return_VALUE(0); + } + + /* + * PIIX4 Errata: We don't support throttling on the original PIIX4. + * This shouldn't be an issue as few (if any) mobile systems ever + * used this part. + */ + if (errata.piix4.throttle) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Throttling not supported on PIIX4 A- or B-step\n")); + return_VALUE(0); + } + + pr->throttling.state_count = POWER_OF_2[acpi_fadt.duty_width]; + + /* + * Compute state values. Note that throttling displays a linear power/ + * performance relationship (at 50% performance the CPU will consume + * 50% power). Values are in 1/10th of a percent to preserve accuracy. + */ + + step = (1000 / pr->throttling.state_count); + + for (i=0; ithrottling.state_count; i++) { + pr->throttling.states[i].performance = step * i; + pr->throttling.states[i].power = step * i; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n", + pr->throttling.state_count)); + + pr->flags.throttling = 1; + + /* + * Disable throttling (if enabled). We'll let subsequent policy (e.g. + * thermal) decide to lower performance if it so chooses, but for now + * we'll crank up the speed. + */ + + result = acpi_processor_get_throttling(pr); + if (result) + goto end; + + if (pr->throttling.state) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabling throttling (was T%d)\n", + pr->throttling.state)); + result = acpi_processor_set_throttling(pr, 0); + if (result) + goto end; + } + +end: + if (result) + pr->flags.throttling = 0; + + return_VALUE(result); +} + + +/* -------------------------------------------------------------------------- + Limit Interface + -------------------------------------------------------------------------- */ + +static int +acpi_processor_apply_limit ( + struct acpi_processor* pr) +{ + int result = 0; + u16 px = 0; + u16 tx = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_apply_limit"); + + if (!pr) + return_VALUE(-EINVAL); + + if (!pr->flags.limit) + return_VALUE(-ENODEV); + + if (pr->flags.performance) { + px = pr->performance.platform_limit; + if (pr->limit.user.px > px) + px = pr->limit.user.px; + if (pr->limit.thermal.px > px) + px = pr->limit.thermal.px; + + result = acpi_processor_set_performance(pr, px); + if (result) + goto end; + } + + if (pr->flags.throttling) { + if (pr->limit.user.tx > tx) + tx = pr->limit.user.tx; + if (pr->limit.thermal.tx > tx) + tx = pr->limit.thermal.tx; + + result = acpi_processor_set_throttling(pr, tx); + if (result) + goto end; + } + + pr->limit.state.px = px; + pr->limit.state.tx = tx; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d] limit set to (P%d:T%d)\n", + pr->id, + pr->limit.state.px, + pr->limit.state.tx)); + +end: + if (result) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n")); + + return_VALUE(result); +} + + +int +acpi_processor_set_thermal_limit ( + acpi_handle handle, + int type) +{ + int result = 0; + struct acpi_processor *pr = NULL; + struct acpi_device *device = NULL; + int px = 0; + int tx = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit"); + + if ((type < ACPI_PROCESSOR_LIMIT_NONE) + || (type > ACPI_PROCESSOR_LIMIT_DECREMENT)) + return_VALUE(-EINVAL); + + result = acpi_bus_get_device(handle, &device); + if (result) + return_VALUE(result); + + pr = (struct acpi_processor *) acpi_driver_data(device); + if (!pr) + return_VALUE(-ENODEV); + + if (!pr->flags.limit) + return_VALUE(-ENODEV); + + /* Thermal limits are always relative to the current Px/Tx state. */ + if (pr->flags.performance) + pr->limit.thermal.px = pr->performance.state; + if (pr->flags.throttling) + pr->limit.thermal.tx = pr->throttling.state; + + /* + * Our default policy is to only use throttling at the lowest + * performance state. + */ + + px = pr->limit.thermal.px; + tx = pr->limit.thermal.tx; + + switch (type) { + + case ACPI_PROCESSOR_LIMIT_NONE: + px = 0; + tx = 0; + break; + + case ACPI_PROCESSOR_LIMIT_INCREMENT: + if (pr->flags.performance) { + if (px == (pr->performance.state_count - 1)) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "At maximum performance state\n")); + else { + px++; + goto end; + } + } + if (pr->flags.throttling) { + if (tx == (pr->throttling.state_count - 1)) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "At maximum throttling state\n")); + else + tx++; + } + break; + + case ACPI_PROCESSOR_LIMIT_DECREMENT: + if (pr->flags.performance) { + if (px == pr->performance.platform_limit) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "At minimum performance state\n")); + else { + px--; + goto end; + } + } + if (pr->flags.throttling) { + if (tx == 0) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "At minimum throttling state\n")); + else + tx--; + } + break; + } + +end: + pr->limit.thermal.px = px; + pr->limit.thermal.tx = tx; + + result = acpi_processor_apply_limit(pr); + if (result) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to set thermal limit\n")); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n", + pr->limit.thermal.px, + pr->limit.thermal.tx)); + + return_VALUE(result); +} + + +static int +acpi_processor_get_limit_info ( + struct acpi_processor *pr) +{ + ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info"); + + if (!pr) + return_VALUE(-EINVAL); + + if (pr->flags.performance || pr->flags.throttling) + pr->flags.limit = 1; + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_processor_dir = NULL; + +static int +acpi_processor_read_info ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_processor *pr = (struct acpi_processor *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_read_info"); + + if (!pr || (off != 0)) + goto end; + + p += sprintf(p, "processor id: %d\n", + pr->id); + + p += sprintf(p, "acpi id: %d\n", + pr->acpi_id); + + p += sprintf(p, "bus mastering control: %s\n", + pr->flags.bm_control ? "yes" : "no"); + + p += sprintf(p, "power management: %s\n", + pr->flags.power ? "yes" : "no"); + + p += sprintf(p, "throttling control: %s\n", + pr->flags.throttling ? "yes" : "no"); + + p += sprintf(p, "performance management: %s\n", + pr->flags.performance ? "yes" : "no"); + + p += sprintf(p, "limit interface: %s\n", + pr->flags.limit ? "yes" : "no"); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_processor_read_power ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_processor *pr = (struct acpi_processor *) data; + char *p = page; + int len = 0; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_read_power"); + + if (!pr || (off != 0)) + goto end; + + p += sprintf(p, "active state: C%d\n", + pr->power.state); + + p += sprintf(p, "default state: C%d\n", + pr->power.default_state); + + p += sprintf(p, "bus master activity: %08x\n", + pr->power.bm_activity); + + p += sprintf(p, "states:\n"); + + for (i=1; ipower.state?'*':' '), i); + + if (!pr->power.states[i].valid) { + p += sprintf(p, "\n"); + continue; + } + + if (pr->power.states[i].promotion.state) + p += sprintf(p, "promotion[C%d] ", + pr->power.states[i].promotion.state); + else + p += sprintf(p, "promotion[--] "); + + if (pr->power.states[i].demotion.state) + p += sprintf(p, "demotion[C%d] ", + pr->power.states[i].demotion.state); + else + p += sprintf(p, "demotion[--] "); + + p += sprintf(p, "latency[%03d] usage[%08d]\n", + pr->power.states[i].latency, + pr->power.states[i].usage); + } + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_processor_read_performance ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_processor *pr = (struct acpi_processor *) data; + char *p = page; + int len = 0; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_read_performance"); + + if (!pr || (off != 0)) + goto end; + + if (!pr->flags.performance) { + p += sprintf(p, "\n"); + goto end; + } + + p += sprintf(p, "state count: %d\n", + pr->performance.state_count); + + p += sprintf(p, "active state: P%d\n", + pr->performance.state); + + p += sprintf(p, "states:\n"); + + for (i=0; iperformance.state_count; i++) + p += sprintf(p, " %cP%d: %d MHz, %d mW, %d uS\n", + (i == pr->performance.state?'*':' '), i, + (u32) pr->performance.states[i].core_frequency, + (u32) pr->performance.states[i].power, + (u32) pr->performance.states[i].transition_latency); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_processor_write_performance ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_processor *pr = (struct acpi_processor *) data; + char state_string[12] = {'\0'}; + + ACPI_FUNCTION_TRACE("acpi_processor_write_performance"); + + if (!pr || (count > sizeof(state_string) - 1)) + return_VALUE(-EINVAL); + + if (copy_from_user(state_string, buffer, count)) + return_VALUE(-EFAULT); + + state_string[count] = '\0'; + + result = acpi_processor_set_performance(pr, + simple_strtoul(state_string, NULL, 0)); + if (result) + return_VALUE(result); + + return_VALUE(count); +} + + +static int +acpi_processor_read_throttling ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_processor *pr = (struct acpi_processor *) data; + char *p = page; + int len = 0; + int i = 0; + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_read_throttling"); + + if (!pr || (off != 0)) + goto end; + + if (!(pr->throttling.state_count > 0)) { + p += sprintf(p, "\n"); + goto end; + } + + result = acpi_processor_get_throttling(pr); + + if (result) { + p += sprintf(p, "Could not determine current throttling state.\n"); + goto end; + } + + p += sprintf(p, "state count: %d\n", + pr->throttling.state_count); + + p += sprintf(p, "active state: T%d\n", + pr->throttling.state); + + p += sprintf(p, "states:\n"); + + for (i=0; ithrottling.state_count; i++) + p += sprintf(p, " %cT%d: %02d%%\n", + (i == pr->throttling.state?'*':' '), i, + (pr->throttling.states[i].performance?pr->throttling.states[i].performance/10:0)); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_processor_write_throttling ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_processor *pr = (struct acpi_processor *) data; + char state_string[12] = {'\0'}; + + ACPI_FUNCTION_TRACE("acpi_processor_write_throttling"); + + if (!pr || (count > sizeof(state_string) - 1)) + return_VALUE(-EINVAL); + + if (copy_from_user(state_string, buffer, count)) + return_VALUE(-EFAULT); + + state_string[count] = '\0'; + + result = acpi_processor_set_throttling(pr, + simple_strtoul(state_string, NULL, 0)); + if (result) + return_VALUE(result); + + return_VALUE(count); +} + + +static int +acpi_processor_read_limit ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_processor *pr = (struct acpi_processor *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_read_limit"); + + if (!pr || (off != 0)) + goto end; + + if (!pr->flags.limit) { + p += sprintf(p, "\n"); + goto end; + } + + p += sprintf(p, "active limit: P%d:T%d\n", + pr->limit.state.px, pr->limit.state.tx); + + p += sprintf(p, "platform limit: P%d:T0\n", + pr->flags.performance?pr->performance.platform_limit:0); + + p += sprintf(p, "user limit: P%d:T%d\n", + pr->limit.user.px, pr->limit.user.tx); + + p += sprintf(p, "thermal limit: P%d:T%d\n", + pr->limit.thermal.px, pr->limit.thermal.tx); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_processor_write_limit ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_processor *pr = (struct acpi_processor *) data; + char limit_string[25] = {'\0'}; + int px = 0; + int tx = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_write_limit"); + + if (!pr || (count > sizeof(limit_string) - 1)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n")); + return_VALUE(-EINVAL); + } + + if (copy_from_user(limit_string, buffer, count)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n")); + return_VALUE(-EFAULT); + } + + limit_string[count] = '\0'; + + if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n")); + return_VALUE(-EINVAL); + } + + if (pr->flags.performance) { + if ((px < pr->performance.platform_limit) + || (px > (pr->performance.state_count - 1))) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid px\n")); + return_VALUE(-EINVAL); + } + pr->limit.user.px = px; + } + + if (pr->flags.throttling) { + if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n")); + return_VALUE(-EINVAL); + } + pr->limit.user.tx = tx; + } + + result = acpi_processor_apply_limit(pr); + + return_VALUE(count); +} + + +static int +acpi_processor_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_add_fs"); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_processor_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + /* 'info' [R] */ + entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_PROCESSOR_FILE_INFO)); + else { + entry->read_proc = acpi_processor_read_info; + entry->data = acpi_driver_data(device); + } + + /* 'power' [R] */ + entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_PROCESSOR_FILE_POWER)); + else { + entry->read_proc = acpi_processor_read_power; + entry->data = acpi_driver_data(device); + } + + /* 'performance' [R/W] */ + entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_PROCESSOR_FILE_PERFORMANCE)); + else { + entry->read_proc = acpi_processor_read_performance; + entry->write_proc = acpi_processor_write_performance; + entry->data = acpi_driver_data(device); + } + + /* 'throttling' [R/W] */ + entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_PROCESSOR_FILE_THROTTLING)); + else { + entry->read_proc = acpi_processor_read_throttling; + entry->write_proc = acpi_processor_write_throttling; + entry->data = acpi_driver_data(device); + } + + /* 'limit' [R/W] */ + entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_PROCESSOR_FILE_LIMIT)); + else { + entry->read_proc = acpi_processor_read_limit; + entry->write_proc = acpi_processor_write_limit; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + + +static int +acpi_processor_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_processor_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +static int +acpi_processor_get_info ( + struct acpi_processor *pr) +{ + acpi_status status = 0; + union acpi_object object = {0}; + struct acpi_buffer buffer = {sizeof(union acpi_object), &object}; + static int cpu_index = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_get_info"); + + if (!pr) + return_VALUE(-EINVAL); + +#ifdef CONFIG_SMP + if (smp_num_cpus > 1) + errata.smp = smp_num_cpus; + + /* + * Extra Processor objects may be enumerated on MP systems with + * less than the max # of CPUs. They should be ignored. + */ + if ((cpu_index + 1) > smp_num_cpus) + return_VALUE(-ENODEV); +#endif + + acpi_processor_errata(pr); + + /* + * Check to see if we have bus mastering arbitration control. This + * is required for proper C3 usage (to maintain cache coherency). + */ + if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) { + pr->flags.bm_control = 1; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Bus mastering arbitration control present\n")); + } + else + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "No bus mastering arbitration control\n")); + + /* + * Evalute the processor object. Note that it is common on SMP to + * have the first (boot) processor with a valid PBLK address while + * all others have a NULL address. + */ + status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error evaluating processor object\n")); + return_VALUE(-ENODEV); + } + + /* + * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. + * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c + */ + pr->id = cpu_index++; + pr->acpi_id = object.processor.proc_id; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, + pr->acpi_id)); + + if (!object.processor.pblk_address) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); + else if (object.processor.pblk_length != 6) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n", + object.processor.pblk_length)); + else { + pr->throttling.address = object.processor.pblk_address; + pr->throttling.duty_offset = acpi_fadt.duty_offset; + pr->throttling.duty_width = acpi_fadt.duty_width; + pr->power.states[ACPI_STATE_C2].address = + object.processor.pblk_address + 4; + pr->power.states[ACPI_STATE_C3].address = + object.processor.pblk_address + 5; + } + + acpi_processor_get_power_info(pr); + acpi_processor_get_performance_info(pr); + acpi_processor_get_throttling_info(pr); + acpi_processor_get_limit_info(pr); + + return_VALUE(0); +} + + +static void +acpi_processor_notify ( + acpi_handle handle, + u32 event, + void *data) +{ + int result = 0; + struct acpi_processor *pr = (struct acpi_processor *) data; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_notify"); + + if (!pr) + return_VOID; + + if (acpi_bus_get_device(pr->handle, &device)) + return_VOID; + + switch (event) { + case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: + result = acpi_processor_get_platform_limit(pr); + if (!result) + acpi_processor_apply_limit(pr); + + acpi_bus_generate_event(device, event, + pr->performance.platform_limit); + break; + case ACPI_PROCESSOR_NOTIFY_POWER: + /* TBD */ + acpi_bus_generate_event(device, event, 0); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return_VOID; +} + + +static int +acpi_processor_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_processor *pr = NULL; + u32 i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_add"); + + if (!device) + return_VALUE(-EINVAL); + + pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL); + if (!pr) + return_VALUE(-ENOMEM); + memset(pr, 0, sizeof(struct acpi_processor)); + + pr->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_PROCESSOR_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_PROCESSOR_CLASS); + acpi_driver_data(device) = pr; + + result = acpi_processor_get_info(pr); + if (result) + goto end; + + result = acpi_processor_add_fs(device); + if (result) + goto end; + + status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, + acpi_processor_notify, pr); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + result = -ENODEV; + goto end; + } + + processors[pr->id] = pr; + + /* + * Install the idle handler if processor power management is supported. + * Note that the default idle handler (default_idle) will be used on + * platforms that only support C1. + */ + if ((pr->id == 0) && (pr->flags.power)) { + pm_idle_save = pm_idle; + pm_idle = acpi_processor_idle; + } + + printk(KERN_INFO PREFIX "%s [%s] (supports", + acpi_device_name(device), acpi_device_bid(device)); + for (i=1; ipower.states[i].valid) + printk(" C%d", i); + if (pr->flags.performance) + printk(", %d performance states", pr->performance.state_count); + if (pr->flags.throttling) + printk(", %d throttling states", pr->throttling.state_count); + printk(")\n"); + +end: + if (result) { + acpi_processor_remove_fs(device); + kfree(pr); + } + + return_VALUE(result); +} + + +static int +acpi_processor_remove ( + struct acpi_device *device, + int type) +{ + acpi_status status = AE_OK; + struct acpi_processor *pr = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + pr = (struct acpi_processor *) acpi_driver_data(device); + + /* Unregister the idle handler when processor #0 is removed. */ + if (pr->id == 0) + pm_idle = pm_idle_save; + + status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, + acpi_processor_notify); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + } + + acpi_processor_remove_fs(device); + + processors[pr->id] = NULL; + + kfree(pr); + + return_VALUE(0); +} + + +static int __init +acpi_processor_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_init"); + + memset(&processors, 0, sizeof(processors)); + memset(&errata, 0, sizeof(errata)); + + acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); + if (!acpi_processor_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_processor_driver); + if (result < 0) { + remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +static void __exit +acpi_processor_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_processor_exit"); + + acpi_bus_unregister_driver(&acpi_processor_driver); + + remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); + + return_VOID; +} + + +module_init(acpi_processor_init); +module_exit(acpi_processor_exit); + +EXPORT_SYMBOL(acpi_processor_set_thermal_limit); diff -urN linux-2.4.21/drivers/acpi/resources/Makefile linux-2.4.22/drivers/acpi/resources/Makefile --- linux-2.4.21/drivers/acpi/resources/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/resources/rsaddr.c linux-2.4.22/drivers/acpi/resources/rsaddr.c --- linux-2.4.21/drivers/acpi/resources/rsaddr.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsaddr.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,81 +1,98 @@ /******************************************************************************* * * Module Name: rsaddr - Address resource descriptors (16/32/64) - * $Revision: 19 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsaddr") + ACPI_MODULE_NAME ("rsaddr") /******************************************************************************* * - * FUNCTION: Acpi_rs_address16_resource + * FUNCTION: acpi_rs_address16_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_address16_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - NATIVE_CHAR *temp_ptr; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_address16); - u32 index; - u16 temp16; - u8 temp8; + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u8 *temp_ptr; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16); + u32 index; + u16 temp16; + u8 temp8; - FUNCTION_TRACE ("Rs_address16_resource"); + ACPI_FUNCTION_TRACE ("rs_address16_resource"); /* * Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS16; @@ -87,6 +104,7 @@ temp8 = *buffer; /* Values 0-2 are valid */ + if (temp8 > 2) { return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } @@ -99,24 +117,20 @@ buffer += 1; temp8 = *buffer; - /* - * Producer / Consumer - */ + /* Producer / Consumer */ + output_struct->data.address16.producer_consumer = temp8 & 0x01; - /* - * Decode - */ + /* Decode */ + output_struct->data.address16.decode = (temp8 >> 1) & 0x01; - /* - * Min Address Fixed - */ + /* Min Address Fixed */ + output_struct->data.address16.min_address_fixed = (temp8 >> 2) & 0x01; - /* - * Max Address Fixed - */ + /* Max Address Fixed */ + output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01; /* @@ -125,21 +139,21 @@ buffer += 1; temp8 = *buffer; - if (MEMORY_RANGE == output_struct->data.address16.resource_type) { + if (ACPI_MEMORY_RANGE == output_struct->data.address16.resource_type) { output_struct->data.address16.attribute.memory.read_write_attribute = (u16) (temp8 & 0x01); output_struct->data.address16.attribute.memory.cache_attribute = (u16) ((temp8 >> 1) & 0x0F); } - else { - if (IO_RANGE == output_struct->data.address16.resource_type) { + if (ACPI_IO_RANGE == output_struct->data.address16.resource_type) { output_struct->data.address16.attribute.io.range_attribute = (u16) (temp8 & 0x03); + output_struct->data.address16.attribute.io.translation_attribute = + (u16) ((temp8 >> 4) & 0x03); } - else { - /* BUS_NUMBER_RANGE == Address16.Data->Resource_type */ + /* BUS_NUMBER_RANGE == Address16.Data->resource_type */ /* Nothing needs to be filled in */ } } @@ -148,36 +162,31 @@ * Get Granularity (Bytes 6-7) */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.granularity, - buffer); + ACPI_MOVE_16_TO_32 (&output_struct->data.address16.granularity, buffer); /* - * Get Min_address_range (Bytes 8-9) + * Get min_address_range (Bytes 8-9) */ buffer += 2; - MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.min_address_range, - buffer); + ACPI_MOVE_16_TO_32 (&output_struct->data.address16.min_address_range, buffer); /* - * Get Max_address_range (Bytes 10-11) + * Get max_address_range (Bytes 10-11) */ buffer += 2; - MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.max_address_range, - buffer); + ACPI_MOVE_16_TO_32 (&output_struct->data.address16.max_address_range, buffer); /* - * Get Address_translation_offset (Bytes 12-13) + * Get address_translation_offset (Bytes 12-13) */ buffer += 2; - MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.address_translation_offset, - buffer); + ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset, buffer); /* - * Get Address_length (Bytes 14-15) + * Get address_length (Bytes 14-15) */ buffer += 2; - MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.address_length, - buffer); + ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_length, buffer); /* * Resource Source Index (if present) @@ -204,9 +213,9 @@ /* Point the String pointer to the end of this structure */ output_struct->data.address16.resource_source.string_ptr = - (NATIVE_CHAR *)((u8 * )output_struct + struct_size); + (char *)((u8 * )output_struct + struct_size); - temp_ptr = output_struct->data.address16.resource_source.string_ptr; + temp_ptr = (u8 *) output_struct->data.address16.resource_source.string_ptr; /* Copy the string into the buffer */ @@ -228,14 +237,13 @@ output_struct->data.address16.resource_source.string_length = index + 1; /* - * In order for the Struct_size to fall on a 32-bit boundary, + * In order for the struct_size to fall on a 32-bit boundary, * calculate the length of the string and expand the - * Struct_size to the next 32-bit boundary. + * struct_size to the next 32-bit boundary. */ temp8 = (u8) (index + 1); - struct_size += ROUND_UP_TO_32_bITS (temp8); + struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); } - else { output_struct->data.address16.resource_source.index = 0x00; output_struct->data.address16.resource_source.string_length = 0; @@ -245,7 +253,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -257,13 +265,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_address16_stream + * FUNCTION: acpi_rs_address16_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -274,18 +281,18 @@ acpi_status acpi_rs_address16_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u8 *length_field; - u8 temp8; - NATIVE_CHAR *temp_pointer = NULL; - u32 actual_bytes; + u8 *buffer = *output_buffer; + u8 *length_field; + u8 temp8; + char *temp_pointer = NULL; + acpi_size actual_bytes; - FUNCTION_TRACE ("Rs_address16_stream"); + ACPI_FUNCTION_TRACE ("rs_address16_stream"); /* @@ -301,7 +308,7 @@ buffer += 2; /* - * Set the Resource Type (Memory, Io, Bus_number) + * Set the Resource Type (Memory, Io, bus_number) */ temp8 = (u8) (linked_list->data.address16.resource_type & 0x03); *buffer = temp8; @@ -324,7 +331,7 @@ */ temp8 = 0; - if (MEMORY_RANGE == linked_list->data.address16.resource_type) { + if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) { temp8 = (u8) (linked_list->data.address16.attribute.memory.read_write_attribute & 0x01); @@ -333,11 +340,13 @@ (linked_list->data.address16.attribute.memory.cache_attribute & 0x0F) << 1; } - - else if (IO_RANGE == linked_list->data.address16.resource_type) { + else if (ACPI_IO_RANGE == linked_list->data.address16.resource_type) { temp8 = (u8) (linked_list->data.address16.attribute.io.range_attribute & 0x03); + temp8 |= + (linked_list->data.address16.attribute.io.translation_attribute & + 0x03) << 4; } *buffer = temp8; @@ -346,36 +355,31 @@ /* * Set the address space granularity */ - MOVE_UNALIGNED16_TO_16 (buffer, - &linked_list->data.address16.granularity); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.granularity); buffer += 2; /* * Set the address range minimum */ - MOVE_UNALIGNED16_TO_16 (buffer, - &linked_list->data.address16.min_address_range); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.min_address_range); buffer += 2; /* * Set the address range maximum */ - MOVE_UNALIGNED16_TO_16 (buffer, - &linked_list->data.address16.max_address_range); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.max_address_range); buffer += 2; /* * Set the address translation offset */ - MOVE_UNALIGNED16_TO_16 (buffer, - &linked_list->data.address16.address_translation_offset); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_translation_offset); buffer += 2; /* * Set the address length */ - MOVE_UNALIGNED16_TO_16 (buffer, - &linked_list->data.address16.address_length); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_length); buffer += 2; /* @@ -387,26 +391,25 @@ *buffer = temp8; buffer += 1; - temp_pointer = (NATIVE_CHAR *) buffer; + temp_pointer = (char *) buffer; /* * Copy the string */ - STRCPY (temp_pointer, + ACPI_STRCPY (temp_pointer, linked_list->data.address16.resource_source.string_ptr); /* * Buffer needs to be set to the length of the sting + one for the * terminating null */ - buffer += (STRLEN (linked_list->data.address16.resource_source.string_ptr) - + 1); + buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address16.resource_source.string_ptr) + 1); } /* * Return the number of bytes consumed in this operation */ - actual_bytes = POINTER_DIFF (buffer, *output_buffer); + actual_bytes = ACPI_PTR_DIFF (buffer, *output_buffer); *bytes_consumed = actual_bytes; /* @@ -414,63 +417,59 @@ * minus the header size (3 bytes) */ actual_bytes -= 3; - MOVE_UNALIGNED16_TO_16 (length_field, &actual_bytes); + ACPI_MOVE_SIZE_TO_16 (length_field, &actual_bytes); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_address32_resource + * FUNCTION: acpi_rs_address32_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_address32_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer; - acpi_resource *output_struct; - u16 temp16; - u8 temp8; - NATIVE_CHAR *temp_ptr; - u32 struct_size; - u32 index; + u8 *buffer; + struct acpi_resource *output_struct= (void *) *output_buffer; + u16 temp16; + u8 temp8; + u8 *temp_ptr; + acpi_size struct_size; + u32 index; - FUNCTION_TRACE ("Rs_address32_resource"); + ACPI_FUNCTION_TRACE ("rs_address32_resource"); buffer = byte_stream_buffer; - output_struct = (acpi_resource *) *output_buffer; - - struct_size = SIZEOF_RESOURCE (acpi_resource_address32); + struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32); /* * Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + ACPI_MOVE_16_TO_16 (&temp16, buffer); *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS32; @@ -520,22 +519,22 @@ buffer += 1; temp8 = *buffer; - if (MEMORY_RANGE == output_struct->data.address32.resource_type) { + if (ACPI_MEMORY_RANGE == output_struct->data.address32.resource_type) { output_struct->data.address32.attribute.memory.read_write_attribute = (u16) (temp8 & 0x01); output_struct->data.address32.attribute.memory.cache_attribute = (u16) ((temp8 >> 1) & 0x0F); } - else { - if (IO_RANGE == output_struct->data.address32.resource_type) { + if (ACPI_IO_RANGE == output_struct->data.address32.resource_type) { output_struct->data.address32.attribute.io.range_attribute = (u16) (temp8 & 0x03); + output_struct->data.address32.attribute.io.translation_attribute = + (u16) ((temp8 >> 4) & 0x03); } - else { - /* BUS_NUMBER_RANGE == Output_struct->Data.Address32.Resource_type */ + /* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */ /* Nothing needs to be filled in */ } } @@ -544,36 +543,31 @@ * Get Granularity (Bytes 6-9) */ buffer += 1; - MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.granularity, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer); /* - * Get Min_address_range (Bytes 10-13) + * Get min_address_range (Bytes 10-13) */ buffer += 4; - MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.min_address_range, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer); /* - * Get Max_address_range (Bytes 14-17) + * Get max_address_range (Bytes 14-17) */ buffer += 4; - MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.max_address_range, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer); /* - * Get Address_translation_offset (Bytes 18-21) + * Get address_translation_offset (Bytes 18-21) */ buffer += 4; - MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.address_translation_offset, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset, buffer); /* - * Get Address_length (Bytes 22-25) + * Get address_length (Bytes 22-25) */ buffer += 4; - MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.address_length, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer); /* * Resource Source Index (if present) @@ -599,14 +593,13 @@ /* Point the String pointer to the end of this structure */ output_struct->data.address32.resource_source.string_ptr = - (NATIVE_CHAR *)((u8 *)output_struct + struct_size); + (char *)((u8 *)output_struct + struct_size); - temp_ptr = output_struct->data.address32.resource_source.string_ptr; + temp_ptr = (u8 *) output_struct->data.address32.resource_source.string_ptr; /* Copy the string into the buffer */ index = 0; - while (0x00 != *buffer) { *temp_ptr = *buffer; @@ -622,14 +615,13 @@ output_struct->data.address32.resource_source.string_length = index + 1; /* - * In order for the Struct_size to fall on a 32-bit boundary, + * In order for the struct_size to fall on a 32-bit boundary, * calculate the length of the string and expand the - * Struct_size to the next 32-bit boundary. + * struct_size to the next 32-bit boundary. */ temp8 = (u8) (index + 1); - struct_size += ROUND_UP_TO_32_bITS (temp8); + struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); } - else { output_struct->data.address32.resource_source.index = 0x00; output_struct->data.address32.resource_source.string_length = 0; @@ -639,7 +631,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -651,13 +643,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_address32_stream + * FUNCTION: acpi_rs_address32_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -668,17 +659,17 @@ acpi_status acpi_rs_address32_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer; - u16 *length_field; - u8 temp8; - NATIVE_CHAR *temp_pointer; + u8 *buffer; + u16 *length_field; + u8 temp8; + char *temp_pointer; - FUNCTION_TRACE ("Rs_address32_stream"); + ACPI_FUNCTION_TRACE ("rs_address32_stream"); buffer = *output_buffer; @@ -692,12 +683,11 @@ /* * Set a pointer to the Length field - to be filled in later */ - - length_field = (u16 *) buffer; + length_field = ACPI_CAST_PTR (u16, buffer); buffer += 2; /* - * Set the Resource Type (Memory, Io, Bus_number) + * Set the Resource Type (Memory, Io, bus_number) */ temp8 = (u8) (linked_list->data.address32.resource_type & 0x03); @@ -720,7 +710,7 @@ */ temp8 = 0; - if(MEMORY_RANGE == linked_list->data.address32.resource_type) { + if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) { temp8 = (u8) (linked_list->data.address32.attribute.memory.read_write_attribute & 0x01); @@ -729,11 +719,13 @@ (linked_list->data.address32.attribute.memory.cache_attribute & 0x0F) << 1; } - - else if (IO_RANGE == linked_list->data.address32.resource_type) { + else if (ACPI_IO_RANGE == linked_list->data.address32.resource_type) { temp8 = (u8) (linked_list->data.address32.attribute.io.range_attribute & 0x03); + temp8 |= + (linked_list->data.address32.attribute.io.translation_attribute & + 0x03) << 4; } *buffer = temp8; @@ -742,36 +734,31 @@ /* * Set the address space granularity */ - MOVE_UNALIGNED32_TO_32 (buffer, - &linked_list->data.address32.granularity); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity); buffer += 4; /* * Set the address range minimum */ - MOVE_UNALIGNED32_TO_32 (buffer, - &linked_list->data.address32.min_address_range); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range); buffer += 4; /* * Set the address range maximum */ - MOVE_UNALIGNED32_TO_32 (buffer, - &linked_list->data.address32.max_address_range); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range); buffer += 4; /* * Set the address translation offset */ - MOVE_UNALIGNED32_TO_32 (buffer, - &linked_list->data.address32.address_translation_offset); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset); buffer += 4; /* * Set the address length */ - MOVE_UNALIGNED32_TO_32 (buffer, - &linked_list->data.address32.address_length); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length); buffer += 4; /* @@ -783,25 +770,25 @@ *buffer = temp8; buffer += 1; - temp_pointer = (NATIVE_CHAR *) buffer; + temp_pointer = (char *) buffer; /* * Copy the string */ - STRCPY (temp_pointer, + ACPI_STRCPY (temp_pointer, linked_list->data.address32.resource_source.string_ptr); /* * Buffer needs to be set to the length of the sting + one for the * terminating null */ - buffer += (STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1); + buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1); } /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); /* * Set the length field to the number of bytes consumed @@ -814,55 +801,52 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_address64_resource + * FUNCTION: acpi_rs_address64_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_address64_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer; - acpi_resource *output_struct; - u16 temp16; - u8 temp8; - NATIVE_CHAR *temp_ptr; - u32 struct_size; - u32 index; + u8 *buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16; + u8 temp8; + u8 *temp_ptr; + acpi_size struct_size; + u32 index; - FUNCTION_TRACE ("Rs_address64_resource"); + ACPI_FUNCTION_TRACE ("rs_address64_resource"); buffer = byte_stream_buffer; - output_struct = (acpi_resource *) *output_buffer; - - struct_size = SIZEOF_RESOURCE (acpi_resource_address64); + struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64); /* * Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS64; @@ -874,6 +858,7 @@ temp8 = *buffer; /* Values 0-2 are valid */ + if(temp8 > 2) { return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } @@ -912,22 +897,22 @@ buffer += 1; temp8 = *buffer; - if (MEMORY_RANGE == output_struct->data.address64.resource_type) { + if (ACPI_MEMORY_RANGE == output_struct->data.address64.resource_type) { output_struct->data.address64.attribute.memory.read_write_attribute = (u16) (temp8 & 0x01); output_struct->data.address64.attribute.memory.cache_attribute = (u16) ((temp8 >> 1) & 0x0F); } - else { - if (IO_RANGE == output_struct->data.address64.resource_type) { + if (ACPI_IO_RANGE == output_struct->data.address64.resource_type) { output_struct->data.address64.attribute.io.range_attribute = (u16) (temp8 & 0x03); + output_struct->data.address64.attribute.io.translation_attribute = + (u16) ((temp8 >> 4) & 0x03); } - else { - /* BUS_NUMBER_RANGE == Output_struct->Data.Address64.Resource_type */ + /* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */ /* Nothing needs to be filled in */ } } @@ -936,36 +921,31 @@ * Get Granularity (Bytes 6-13) */ buffer += 1; - MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.granularity, - buffer); + ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer); /* - * Get Min_address_range (Bytes 14-21) + * Get min_address_range (Bytes 14-21) */ buffer += 8; - MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.min_address_range, - buffer); + ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer); /* - * Get Max_address_range (Bytes 22-29) + * Get max_address_range (Bytes 22-29) */ buffer += 8; - MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.max_address_range, - buffer); + ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer); /* - * Get Address_translation_offset (Bytes 30-37) + * Get address_translation_offset (Bytes 30-37) */ buffer += 8; - MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.address_translation_offset, - buffer); + ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer); /* - * Get Address_length (Bytes 38-45) + * Get address_length (Bytes 38-45) */ buffer += 8; - MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.address_length, - buffer); + ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer); /* * Resource Source Index (if present) @@ -993,14 +973,13 @@ /* Point the String pointer to the end of this structure */ output_struct->data.address64.resource_source.string_ptr = - (NATIVE_CHAR *)((u8 *)output_struct + struct_size); + (char *)((u8 *)output_struct + struct_size); - temp_ptr = output_struct->data.address64.resource_source.string_ptr; + temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr; /* Copy the string into the buffer */ index = 0; - while (0x00 != *buffer) { *temp_ptr = *buffer; @@ -1017,14 +996,13 @@ output_struct->data.address64.resource_source.string_length = index + 1; /* - * In order for the Struct_size to fall on a 32-bit boundary, + * In order for the struct_size to fall on a 32-bit boundary, * calculate the length of the string and expand the - * Struct_size to the next 32-bit boundary. + * struct_size to the next 32-bit boundary. */ temp8 = (u8) (index + 1); - struct_size += ROUND_UP_TO_32_bITS (temp8); + struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); } - else { output_struct->data.address64.resource_source.index = 0x00; output_struct->data.address64.resource_source.string_length = 0; @@ -1034,7 +1012,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -1046,13 +1024,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_address64_stream + * FUNCTION: acpi_rs_address64_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -1063,17 +1040,17 @@ acpi_status acpi_rs_address64_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer; - u16 *length_field; - u8 temp8; - NATIVE_CHAR *temp_pointer; + u8 *buffer; + u16 *length_field; + u8 temp8; + char *temp_pointer; - FUNCTION_TRACE ("Rs_address64_stream"); + ACPI_FUNCTION_TRACE ("rs_address64_stream"); buffer = *output_buffer; @@ -1088,11 +1065,11 @@ * Set a pointer to the Length field - to be filled in later */ - length_field = (u16 *)buffer; + length_field = ACPI_CAST_PTR (u16, buffer); buffer += 2; /* - * Set the Resource Type (Memory, Io, Bus_number) + * Set the Resource Type (Memory, Io, bus_number) */ temp8 = (u8) (linked_list->data.address64.resource_type & 0x03); @@ -1115,7 +1092,7 @@ */ temp8 = 0; - if(MEMORY_RANGE == linked_list->data.address64.resource_type) { + if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) { temp8 = (u8) (linked_list->data.address64.attribute.memory.read_write_attribute & 0x01); @@ -1124,11 +1101,13 @@ (linked_list->data.address64.attribute.memory.cache_attribute & 0x0F) << 1; } - - else if (IO_RANGE == linked_list->data.address64.resource_type) { + else if (ACPI_IO_RANGE == linked_list->data.address64.resource_type) { temp8 = (u8) (linked_list->data.address64.attribute.io.range_attribute & 0x03); + temp8 |= + (linked_list->data.address64.attribute.io.range_attribute & + 0x03) << 4; } *buffer = temp8; @@ -1137,36 +1116,31 @@ /* * Set the address space granularity */ - MOVE_UNALIGNED64_TO_64 (buffer, - &linked_list->data.address64.granularity); + ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity); buffer += 8; /* * Set the address range minimum */ - MOVE_UNALIGNED64_TO_64 (buffer, - &linked_list->data.address64.min_address_range); + ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range); buffer += 8; /* * Set the address range maximum */ - MOVE_UNALIGNED64_TO_64 (buffer, - &linked_list->data.address64.max_address_range); + ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range); buffer += 8; /* * Set the address translation offset */ - MOVE_UNALIGNED64_TO_64 (buffer, - &linked_list->data.address64.address_translation_offset); + ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_translation_offset); buffer += 8; /* * Set the address length */ - MOVE_UNALIGNED64_TO_64 (buffer, - &linked_list->data.address64.address_length); + ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length); buffer += 8; /* @@ -1178,24 +1152,24 @@ *buffer = temp8; buffer += 1; - temp_pointer = (NATIVE_CHAR *) buffer; + temp_pointer = (char *) buffer; /* * Copy the string */ - STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr); + ACPI_STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr); /* * Buffer needs to be set to the length of the sting + one for the * terminating null */ - buffer += (STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1); + buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1); } /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); /* * Set the length field to the number of bytes consumed diff -urN linux-2.4.21/drivers/acpi/resources/rscalc.c linux-2.4.22/drivers/acpi/resources/rscalc.c --- linux-2.4.21/drivers/acpi/resources/rscalc.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rscalc.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,44 +1,62 @@ /******************************************************************************* * * Module Name: rscalc - Calculate stream and list lengths - * $Revision: 32 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rscalc") + ACPI_MODULE_NAME ("rscalc") /******************************************************************************* * - * FUNCTION: Acpi_rs_calculate_byte_stream_length + * FUNCTION: acpi_rs_get_byte_stream_length * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Size_needed - u32 pointer of the size buffer needed + * PARAMETERS: linked_list - Pointer to the resource linked list + * size_needed - u32 pointer of the size buffer needed * to properly return the parsed data * * RETURN: Status @@ -50,17 +68,17 @@ ******************************************************************************/ acpi_status -acpi_rs_calculate_byte_stream_length ( - acpi_resource *linked_list, - u32 *size_needed) +acpi_rs_get_byte_stream_length ( + struct acpi_resource *linked_list, + acpi_size *size_needed) { - u32 byte_stream_size_needed = 0; - u32 segment_size; - acpi_resource_ext_irq *ex_irq = NULL; - u8 done = FALSE; + acpi_size byte_stream_size_needed = 0; + acpi_size segment_size; + struct acpi_resource_ext_irq *ex_irq = NULL; + u8 done = FALSE; - FUNCTION_TRACE ("Rs_calculate_byte_stream_length"); + ACPI_FUNCTION_TRACE ("rs_get_byte_stream_length"); while (!done) { @@ -90,7 +108,7 @@ case ACPI_RSTYPE_START_DPF: /* * Start Dependent Functions Resource - * For a Start_dependent_functions Resource, Byte 1, + * For a start_dependent_functions Resource, Byte 1, * although optional, will always be created. */ segment_size = 2; @@ -180,9 +198,9 @@ */ segment_size = 16; - if (NULL != linked_list->data.address16.resource_source.string_ptr) { - segment_size += (1 + - linked_list->data.address16.resource_source.string_length); + if (linked_list->data.address16.resource_source.string_ptr) { + segment_size += linked_list->data.address16.resource_source.string_length; + segment_size++; } break; @@ -196,9 +214,9 @@ */ segment_size = 26; - if (NULL != linked_list->data.address32.resource_source.string_ptr) { - segment_size += (1 + - linked_list->data.address32.resource_source.string_length); + if (linked_list->data.address32.resource_source.string_ptr) { + segment_size += linked_list->data.address32.resource_source.string_length; + segment_size++; } break; @@ -212,9 +230,9 @@ */ segment_size = 46; - if (NULL != linked_list->data.address64.resource_source.string_ptr) { - segment_size += (1 + - linked_list->data.address64.resource_source.string_length); + if (linked_list->data.address64.resource_source.string_ptr) { + segment_size += linked_list->data.address64.resource_source.string_length; + segment_size++; } break; @@ -229,11 +247,11 @@ * Resource Source + 1 for the null. */ segment_size = 9 + - ((linked_list->data.extended_irq.number_of_interrupts - 1) * 4); + (((acpi_size) linked_list->data.extended_irq.number_of_interrupts - 1) * 4); - if (NULL != ex_irq->resource_source.string_ptr) { - segment_size += (1 + - linked_list->data.extended_irq.resource_source.string_length); + if (ex_irq && ex_irq->resource_source.string_ptr) { + segment_size += linked_list->data.extended_irq.resource_source.string_length; + segment_size++; } break; @@ -243,9 +261,8 @@ * so exit with an error */ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); - break; - } /* switch (Linked_list->Id) */ + } /* switch (linked_list->Id) */ /* * Update the total @@ -255,7 +272,7 @@ /* * Point to the next object */ - linked_list = POINTER_ADD (acpi_resource, + linked_list = ACPI_PTR_ADD (struct acpi_resource, linked_list, linked_list->length); } @@ -269,11 +286,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_calculate_list_length + * FUNCTION: acpi_rs_get_list_length * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream - * Byte_stream_buffer_length - Size of Byte_stream_buffer - * Size_needed - u32 pointer of the size buffer + * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream + * byte_stream_buffer_length - Size of byte_stream_buffer + * size_needed - u32 pointer of the size buffer * needed to properly return the * parsed data * @@ -286,26 +303,26 @@ ******************************************************************************/ acpi_status -acpi_rs_calculate_list_length ( - u8 *byte_stream_buffer, - u32 byte_stream_buffer_length, - u32 *size_needed) +acpi_rs_get_list_length ( + u8 *byte_stream_buffer, + u32 byte_stream_buffer_length, + acpi_size *size_needed) { - u32 buffer_size = 0; - u32 bytes_parsed = 0; - u8 number_of_interrupts = 0; - u8 number_of_channels = 0; - u8 resource_type; - u32 structure_size; - u32 bytes_consumed; - u8 *buffer; - u8 temp8; - u16 temp16; - u8 index; - u8 additional_bytes; + u32 buffer_size = 0; + u32 bytes_parsed = 0; + u8 number_of_interrupts = 0; + u8 number_of_channels = 0; + u8 resource_type; + u32 structure_size; + u32 bytes_consumed; + u8 *buffer; + u8 temp8; + u16 temp16; + u8 index; + u8 additional_bytes; - FUNCTION_TRACE ("Rs_calculate_list_length"); + ACPI_FUNCTION_TRACE ("rs_get_list_length"); while (bytes_parsed < byte_stream_buffer_length) { @@ -315,65 +332,65 @@ resource_type = acpi_rs_get_resource_type (*byte_stream_buffer); switch (resource_type) { - case RESOURCE_DESC_MEMORY_24: + case ACPI_RDESC_TYPE_MEMORY_24: /* * 24-Bit Memory Resource */ bytes_consumed = 12; - structure_size = SIZEOF_RESOURCE (acpi_resource_mem24); + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24); break; - case RESOURCE_DESC_LARGE_VENDOR: + case ACPI_RDESC_TYPE_LARGE_VENDOR: /* * Vendor Defined Resource */ buffer = byte_stream_buffer; ++buffer; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; /* * Ensure a 32-bit boundary for the structure */ - temp16 = (u16) ROUND_UP_TO_32_bITS (temp16); + temp16 = (u16) ACPI_ROUND_UP_to_32_bITS (temp16); - structure_size = SIZEOF_RESOURCE (acpi_resource_vendor) + + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) + (temp16 * sizeof (u8)); break; - case RESOURCE_DESC_MEMORY_32: + case ACPI_RDESC_TYPE_MEMORY_32: /* * 32-Bit Memory Range Resource */ bytes_consumed = 20; - structure_size = SIZEOF_RESOURCE (acpi_resource_mem32); + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32); break; - case RESOURCE_DESC_FIXED_MEMORY_32: + case ACPI_RDESC_TYPE_FIXED_MEMORY_32: /* * 32-Bit Fixed Memory Resource */ bytes_consumed = 12; - structure_size = SIZEOF_RESOURCE (acpi_resource_fixed_mem32); + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32); break; - case RESOURCE_DESC_QWORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: /* * 64-Bit Address Resource */ buffer = byte_stream_buffer; ++buffer; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; @@ -397,21 +414,21 @@ /* * Ensure a 64-bit boundary for the structure */ - temp8 = (u8) ROUND_UP_TO_64_bITS (temp8); + temp8 = (u8) ACPI_ROUND_UP_to_64_bITS (temp8); - structure_size = SIZEOF_RESOURCE (acpi_resource_address64) + + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64) + (temp8 * sizeof (u8)); break; - case RESOURCE_DESC_DWORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: /* * 32-Bit Address Resource */ buffer = byte_stream_buffer; ++buffer; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; @@ -435,21 +452,21 @@ /* * Ensure a 32-bit boundary for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); - structure_size = SIZEOF_RESOURCE (acpi_resource_address32) + + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32) + (temp8 * sizeof (u8)); break; - case RESOURCE_DESC_WORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: /* * 16-Bit Address Resource */ buffer = byte_stream_buffer; ++buffer; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; @@ -473,21 +490,21 @@ /* * Ensure a 32-bit boundary for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); - structure_size = SIZEOF_RESOURCE (acpi_resource_address16) + + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16) + (temp8 * sizeof (u8)); break; - case RESOURCE_DESC_EXTENDED_XRUPT: + case ACPI_RDESC_TYPE_EXTENDED_XRUPT: /* * Extended IRQ */ buffer = byte_stream_buffer; ++buffer; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; @@ -518,7 +535,6 @@ if (9 + additional_bytes < temp16) { temp8 = (u8) (temp16 - (9 + additional_bytes)); } - else { temp8 = 0; } @@ -526,15 +542,15 @@ /* * Ensure a 32-bit boundary for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); - structure_size = SIZEOF_RESOURCE (acpi_resource_ext_irq) + + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq) + (additional_bytes * sizeof (u8)) + (temp8 * sizeof (u8)); break; - case RESOURCE_DESC_IRQ_FORMAT: + case ACPI_RDESC_TYPE_IRQ_FORMAT: /* * IRQ Resource. * Determine if it there are two or three trailing bytes @@ -545,7 +561,6 @@ if(temp8 & 0x01) { bytes_consumed = 4; } - else { bytes_consumed = 3; } @@ -558,7 +573,7 @@ /* * Look at the number of bits set */ - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); for (index = 0; index < 16; index++) { if (temp16 & 0x1) { @@ -568,12 +583,12 @@ temp16 >>= 1; } - structure_size = SIZEOF_RESOURCE (acpi_resource_io) + + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io) + (number_of_interrupts * sizeof (u32)); break; - case RESOURCE_DESC_DMA_FORMAT: + case ACPI_RDESC_TYPE_DMA_FORMAT: /* * DMA Resource */ @@ -598,12 +613,12 @@ temp8 >>= 1; } - structure_size = SIZEOF_RESOURCE (acpi_resource_dma) + + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma) + (number_of_channels * sizeof (u32)); break; - case RESOURCE_DESC_START_DEPENDENT: + case ACPI_RDESC_TYPE_START_DEPENDENT: /* * Start Dependent Functions Resource * Determine if it there are two or three trailing bytes @@ -618,11 +633,11 @@ bytes_consumed = 1; } - structure_size = SIZEOF_RESOURCE (acpi_resource_start_dpf); + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf); break; - case RESOURCE_DESC_END_DEPENDENT: + case ACPI_RDESC_TYPE_END_DEPENDENT: /* * End Dependent Functions Resource */ @@ -631,25 +646,25 @@ break; - case RESOURCE_DESC_IO_PORT: + case ACPI_RDESC_TYPE_IO_PORT: /* * IO Port Resource */ bytes_consumed = 8; - structure_size = SIZEOF_RESOURCE (acpi_resource_io); + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io); break; - case RESOURCE_DESC_FIXED_IO_PORT: + case ACPI_RDESC_TYPE_FIXED_IO_PORT: /* * Fixed IO Port Resource */ bytes_consumed = 4; - structure_size = SIZEOF_RESOURCE (acpi_resource_fixed_io); + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io); break; - case RESOURCE_DESC_SMALL_VENDOR: + case ACPI_RDESC_TYPE_SMALL_VENDOR: /* * Vendor Specific Resource */ @@ -662,13 +677,13 @@ /* * Ensure a 32-bit boundary for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); - structure_size = SIZEOF_RESOURCE (acpi_resource_vendor) + + temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) + (temp8 * sizeof (u8)); break; - case RESOURCE_DESC_END_TAG: + case ACPI_RDESC_TYPE_END_TAG: /* * End Tag */ @@ -684,14 +699,12 @@ * so exit with an error */ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); - break; } - /* * Update the return value and counter */ - buffer_size += structure_size; + buffer_size += ACPI_ALIGN_RESOURCE_SIZE(structure_size); bytes_parsed += bytes_consumed; /* @@ -700,7 +713,6 @@ byte_stream_buffer += bytes_consumed; } - /* * This is the data the caller needs */ @@ -711,10 +723,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_calculate_pci_routing_table_length + * FUNCTION: acpi_rs_get_pci_routing_table_length * - * PARAMETERS: Package_object - Pointer to the package object - * Buffer_size_needed - u32 pointer of the size buffer + * PARAMETERS: package_object - Pointer to the package object + * buffer_size_needed - u32 pointer of the size buffer * needed to properly return the * parsed data * @@ -727,21 +739,21 @@ ******************************************************************************/ acpi_status -acpi_rs_calculate_pci_routing_table_length ( - acpi_operand_object *package_object, - u32 *buffer_size_needed) +acpi_rs_get_pci_routing_table_length ( + union acpi_operand_object *package_object, + acpi_size *buffer_size_needed) { - u32 number_of_elements; - u32 temp_size_needed = 0; - acpi_operand_object **top_object_list; - u32 index; - acpi_operand_object *package_element; - acpi_operand_object **sub_object_list; - u8 name_found; - u32 table_index; + u32 number_of_elements; + acpi_size temp_size_needed = 0; + union acpi_operand_object **top_object_list; + u32 index; + union acpi_operand_object *package_element; + union acpi_operand_object **sub_object_list; + u8 name_found; + u32 table_index; - FUNCTION_TRACE ("Rs_calculate_pci_routing_table_length"); + ACPI_FUNCTION_TRACE ("rs_get_pci_routing_table_length"); number_of_elements = package_object->package.count; @@ -765,23 +777,22 @@ package_element = *top_object_list; /* - * The Sub_object_list will now point to an array of the - * four IRQ elements: Address, Pin, Source and Source_index + * The sub_object_list will now point to an array of the + * four IRQ elements: Address, Pin, Source and source_index */ sub_object_list = package_element->package.elements; /* - * Scan the Irq_table_elements for the Source Name String + * Scan the irq_table_elements for the Source Name String */ name_found = FALSE; for (table_index = 0; table_index < 4 && !name_found; table_index++) { - if ((ACPI_TYPE_STRING == (*sub_object_list)->common.type) || - ((INTERNAL_TYPE_REFERENCE == (*sub_object_list)->common.type) && + if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*sub_object_list)) || + ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*sub_object_list)) && ((*sub_object_list)->reference.opcode == AML_INT_NAMEPATH_OP))) { name_found = TRUE; } - else { /* * Look at the next element @@ -790,26 +801,24 @@ } } - temp_size_needed += (sizeof (pci_routing_table) - 4); + temp_size_needed += (sizeof (struct acpi_pci_routing_table) - 4); /* * Was a String type found? */ - if (TRUE == name_found) { - if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) { + if (name_found) { + if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) { /* - * The length String.Length field includes the - * terminating NULL + * The length String.Length field does not include the + * terminating NULL, add 1 */ - temp_size_needed += (*sub_object_list)->string.length; + temp_size_needed += ((acpi_size) (*sub_object_list)->string.length + 1); } - else { temp_size_needed += acpi_ns_get_pathname_length ( (*sub_object_list)->reference.node); } } - else { /* * If no name was found, then this is a NULL, which is @@ -820,18 +829,17 @@ /* Round up the size since each element must be aligned */ - temp_size_needed = ROUND_UP_TO_64_bITS (temp_size_needed); + temp_size_needed = ACPI_ROUND_UP_to_64_bITS (temp_size_needed); /* - * Point to the next acpi_operand_object + * Point to the next union acpi_operand_object */ top_object_list++; } - /* * Adding an extra element to the end of the list, essentially a NULL terminator */ - *buffer_size_needed = temp_size_needed + sizeof (pci_routing_table); + *buffer_size_needed = temp_size_needed + sizeof (struct acpi_pci_routing_table); return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/resources/rscreate.c linux-2.4.22/drivers/acpi/resources/rscreate.c --- linux-2.4.21/drivers/acpi/resources/rscreate.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rscreate.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,50 +1,67 @@ /******************************************************************************* * * Module Name: rscreate - Create resource lists/tables - * $Revision: 36 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" -#include "amlcode.h" -#include "acnamesp.h" +#include +#include +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rscreate") + ACPI_MODULE_NAME ("rscreate") /******************************************************************************* * - * FUNCTION: Acpi_rs_create_resource_list + * FUNCTION: acpi_rs_create_resource_list * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream - * Output_buffer - Pointer to the user's buffer - * Output_buffer_length - Pointer to the size of Output_buffer + * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream + * output_buffer - Pointer to the user's buffer * * RETURN: Status - AE_OK if okay, else a valid acpi_status code - * If Output_buffer is not large enough, Output_buffer_length - * indicates how large Output_buffer should be, else it - * indicates how may u8 elements of Output_buffer are valid. + * If output_buffer is not large enough, output_buffer_length + * indicates how large output_buffer should be, else it + * indicates how may u8 elements of output_buffer are valid. * * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method * execution and parses the stream to create a linked list @@ -54,21 +71,21 @@ acpi_status acpi_rs_create_resource_list ( - acpi_operand_object *byte_stream_buffer, - u8 *output_buffer, - u32 *output_buffer_length) + union acpi_operand_object *byte_stream_buffer, + struct acpi_buffer *output_buffer) { - acpi_status status; - u8 *byte_stream_start; - u32 list_size_needed = 0; - u32 byte_stream_buffer_length; + acpi_status status; + u8 *byte_stream_start; + acpi_size list_size_needed = 0; + u32 byte_stream_buffer_length; - FUNCTION_TRACE ("Rs_create_resource_list"); + ACPI_FUNCTION_TRACE ("rs_create_resource_list"); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Byte_stream_buffer = %p\n", byte_stream_buffer)); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_buffer = %p\n", + byte_stream_buffer)); /* * Params already validated, so we don't re-validate here @@ -77,300 +94,280 @@ byte_stream_start = byte_stream_buffer->buffer.pointer; /* - * Pass the Byte_stream_buffer into a module that can calculate + * Pass the byte_stream_buffer into a module that can calculate * the buffer size needed for the linked list */ - status = acpi_rs_calculate_list_length (byte_stream_start, byte_stream_buffer_length, + status = acpi_rs_get_list_length (byte_stream_start, byte_stream_buffer_length, &list_size_needed); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status=%X List_size_needed=%X\n", - status, list_size_needed)); - - /* - * Exit with the error passed back - */ + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n", + status, (u32) list_size_needed)); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* - * If the linked list will fit into the available buffer - * call to fill in the list - */ - if (list_size_needed <= *output_buffer_length) { - /* - * Zero out the return buffer before proceeding - */ - MEMSET (output_buffer, 0x00, *output_buffer_length); - - status = acpi_rs_byte_stream_to_list (byte_stream_start, byte_stream_buffer_length, - &output_buffer); + /* Validate/Allocate/Clear caller buffer */ - /* - * Exit with the error passed back - */ - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Output_buffer = %p\n", output_buffer)); + status = acpi_ut_initialize_buffer (output_buffer, list_size_needed); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - else { - *output_buffer_length = list_size_needed; - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); + /* Do the conversion */ + + status = acpi_rs_byte_stream_to_list (byte_stream_start, byte_stream_buffer_length, + output_buffer->pointer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - *output_buffer_length = list_size_needed; + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n", + output_buffer->pointer, (u32) output_buffer->length)); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_create_pci_routing_table + * FUNCTION: acpi_rs_create_pci_routing_table * - * PARAMETERS: Package_object - Pointer to an acpi_operand_object + * PARAMETERS: package_object - Pointer to an union acpi_operand_object * package - * Output_buffer - Pointer to the user's buffer - * Output_buffer_length - Size of Output_buffer + * output_buffer - Pointer to the user's buffer * * RETURN: Status AE_OK if okay, else a valid acpi_status code. - * If the Output_buffer is too small, the error will be - * AE_BUFFER_OVERFLOW and Output_buffer_length will point + * If the output_buffer is too small, the error will be + * AE_BUFFER_OVERFLOW and output_buffer->Length will point * to the size buffer needed. * - * DESCRIPTION: Takes the acpi_operand_object package and creates a + * DESCRIPTION: Takes the union acpi_operand_object package and creates a * linked list of PCI interrupt descriptions * + * NOTE: It is the caller's responsibility to ensure that the start of the + * output buffer is aligned properly (if necessary). + * ******************************************************************************/ acpi_status acpi_rs_create_pci_routing_table ( - acpi_operand_object *package_object, - u8 *output_buffer, - u32 *output_buffer_length) + union acpi_operand_object *package_object, + struct acpi_buffer *output_buffer) { - u8 *buffer = output_buffer; - acpi_operand_object **top_object_list = NULL; - acpi_operand_object **sub_object_list = NULL; - acpi_operand_object *package_element = NULL; - u32 buffer_size_needed = 0; - u32 number_of_elements = 0; - u32 index = 0; - pci_routing_table *user_prt = NULL; - acpi_namespace_node *node; - acpi_status status; + u8 *buffer; + union acpi_operand_object **top_object_list; + union acpi_operand_object **sub_object_list; + union acpi_operand_object *obj_desc; + acpi_size buffer_size_needed = 0; + u32 number_of_elements; + u32 index; + struct acpi_pci_routing_table *user_prt; + struct acpi_namespace_node *node; + acpi_status status; + struct acpi_buffer path_buffer; - FUNCTION_TRACE ("Rs_create_pci_routing_table"); + ACPI_FUNCTION_TRACE ("rs_create_pci_routing_table"); + /* Params already validated, so we don't re-validate here */ + /* - * Params already validated, so we don't re-validate here + * Get the required buffer length */ - status = acpi_rs_calculate_pci_routing_table_length (package_object, + status = acpi_rs_get_pci_routing_table_length (package_object, &buffer_size_needed); - - if (!ACPI_SUCCESS(status)) { + if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Buffer_size_needed = %X\n", buffer_size_needed)); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "buffer_size_needed = %X\n", + (u32) buffer_size_needed)); + + /* Validate/Allocate/Clear caller buffer */ + + status = acpi_ut_initialize_buffer (output_buffer, buffer_size_needed); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* - * If the data will fit into the available buffer - * call to fill in the list + * Loop through the ACPI_INTERNAL_OBJECTS - Each object + * should be a package that in turn contains an + * acpi_integer Address, a u8 Pin, a Name and a u8 source_index. */ - if (buffer_size_needed <= *output_buffer_length) { + top_object_list = package_object->package.elements; + number_of_elements = package_object->package.count; + buffer = output_buffer->pointer; + user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); + + for (index = 0; index < number_of_elements; index++) { /* - * Zero out the return buffer before proceeding + * Point user_prt past this current structure + * + * NOTE: On the first iteration, user_prt->Length will + * be zero because we cleared the return buffer earlier */ - MEMSET (output_buffer, 0x00, *output_buffer_length); + buffer += user_prt->length; + user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); /* - * Loop through the ACPI_INTERNAL_OBJECTS - Each object should - * contain a u32 Address, a u8 Pin, a Name and a u8 - * Source_index. + * Fill in the Length field with the information we have at this point. + * The minus four is to subtract the size of the u8 Source[4] member + * because it is added below. */ - top_object_list = package_object->package.elements; - number_of_elements = package_object->package.count; - user_prt = (pci_routing_table *) buffer; - - - buffer = ROUND_PTR_UP_TO_8 (buffer, u8); - - for (index = 0; index < number_of_elements; index++) { - /* - * Point User_prt past this current structure - * - * NOTE: On the first iteration, User_prt->Length will - * be zero because we cleared the return buffer earlier - */ - buffer += user_prt->length; - user_prt = (pci_routing_table *) buffer; + user_prt->length = (sizeof (struct acpi_pci_routing_table) - 4); + /* + * Each element of the top-level package must also be a package + */ + if (ACPI_GET_OBJECT_TYPE (*top_object_list) != ACPI_TYPE_PACKAGE) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "(PRT[%X]) Need sub-package, found %s\n", + index, acpi_ut_get_object_type_name (*top_object_list))); + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + } - /* - * Fill in the Length field with the information we - * have at this point. - * The minus four is to subtract the size of the - * u8 Source[4] member because it is added below. - */ - user_prt->length = (sizeof (pci_routing_table) -4); - - /* - * Dereference the sub-package - */ - package_element = *top_object_list; - - /* - * The Sub_object_list will now point to an array of - * the four IRQ elements: Address, Pin, Source and - * Source_index - */ - sub_object_list = package_element->package.elements; + /* Each sub-package must be of length 4 */ - /* - * 1) First subobject: Dereference the Address - */ - if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { - user_prt->address = (*sub_object_list)->integer.value; - } + if ((*top_object_list)->package.count != 4) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "(PRT[%X]) Need package of length 4, found length %d\n", + index, (*top_object_list)->package.count)); + return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT); + } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n", - acpi_ut_get_type_name ((*sub_object_list)->common.type))); - return_ACPI_STATUS (AE_BAD_DATA); - } + /* + * Dereference the sub-package. + * The sub_object_list will now point to an array of the four IRQ + * elements: [Address, Pin, Source, source_index] + */ + sub_object_list = (*top_object_list)->package.elements; - /* - * 2) Second subobject: Dereference the Pin - */ - sub_object_list++; + /* + * 1) First subobject: Dereference the PRT.Address + */ + obj_desc = sub_object_list[0]; + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { + user_prt->address = obj_desc->integer.value; + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "(PRT[%X].Address) Need Integer, found %s\n", + index, acpi_ut_get_object_type_name (obj_desc))); + return_ACPI_STATUS (AE_BAD_DATA); + } - if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { - user_prt->pin = (u32) (*sub_object_list)->integer.value; - } + /* + * 2) Second subobject: Dereference the PRT.Pin + */ + obj_desc = sub_object_list[1]; + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { + user_prt->pin = (u32) obj_desc->integer.value; + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "(PRT[%X].Pin) Need Integer, found %s\n", + index, acpi_ut_get_object_type_name (obj_desc))); + return_ACPI_STATUS (AE_BAD_DATA); + } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n", - acpi_ut_get_type_name ((*sub_object_list)->common.type))); + /* + * 3) Third subobject: Dereference the PRT.source_name + */ + obj_desc = sub_object_list[2]; + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_LOCAL_REFERENCE: + + if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "(PRT[%X].Source) Need name, found reference op %X\n", + index, obj_desc->reference.opcode)); return_ACPI_STATUS (AE_BAD_DATA); } - /* - * 3) Third subobject: Dereference the Source Name - */ - sub_object_list++; + node = obj_desc->reference.node; - switch ((*sub_object_list)->common.type) { - case INTERNAL_TYPE_REFERENCE: + /* Use *remaining* length of the buffer as max for pathname */ - if ((*sub_object_list)->reference.opcode != AML_INT_NAMEPATH_OP) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need name, found reference op %X\n", - (*sub_object_list)->reference.opcode)); - return_ACPI_STATUS (AE_BAD_DATA); - } + path_buffer.length = output_buffer->length - + (u32) ((u8 *) user_prt->source - + (u8 *) output_buffer->pointer); + path_buffer.pointer = user_prt->source; - node = (*sub_object_list)->reference.node; + status = acpi_ns_handle_to_pathname ((acpi_handle) node, &path_buffer); - /* TBD: use *remaining* length of the buffer! */ + user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1; /* include null terminator */ + break; - status = acpi_ns_handle_to_pathname ((acpi_handle *) node, - output_buffer_length, user_prt->source); - user_prt->length += STRLEN (user_prt->source) + 1; /* include null terminator */ - break; + case ACPI_TYPE_STRING: + ACPI_STRCPY (user_prt->source, obj_desc->string.pointer); - case ACPI_TYPE_STRING: + /* Add to the Length field the length of the string (add 1 for terminator) */ - STRCPY (user_prt->source, - (*sub_object_list)->string.pointer); + user_prt->length += obj_desc->string.length + 1; + break; - /* - * Add to the Length field the length of the string - */ - user_prt->length += (*sub_object_list)->string.length; - break; - - - case ACPI_TYPE_INTEGER: - /* - * If this is a number, then the Source Name - * is NULL, since the entire buffer was zeroed - * out, we can leave this alone. - */ - /* - * Add to the Length field the length of - * the u32 NULL - */ - user_prt->length += sizeof (u32); - break; - - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n", - acpi_ut_get_type_name ((*sub_object_list)->common.type))); - return_ACPI_STATUS (AE_BAD_DATA); - break; - } - - /* Now align the current length */ - - user_prt->length = ROUND_UP_TO_64_bITS (user_prt->length); + case ACPI_TYPE_INTEGER: /* - * 4) Fourth subobject: Dereference the Source Index + * If this is a number, then the Source Name is NULL, since the + * entire buffer was zeroed out, we can leave this alone. + * + * Add to the Length field the length of the u32 NULL */ - sub_object_list++; + user_prt->length += sizeof (u32); + break; - if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { - user_prt->source_index = (u32) (*sub_object_list)->integer.value; - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need Integer, found %s\n", - acpi_ut_get_type_name ((*sub_object_list)->common.type))); - return_ACPI_STATUS (AE_BAD_DATA); - } + default: - /* - * Point to the next acpi_operand_object - */ - top_object_list++; + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "(PRT[%X].Source) Need Ref/String/Integer, found %s\n", + index, acpi_ut_get_object_type_name (obj_desc))); + return_ACPI_STATUS (AE_BAD_DATA); } - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Output_buffer = %p\n", output_buffer)); - } + /* Now align the current length */ + + user_prt->length = ACPI_ROUND_UP_to_64_bITS (user_prt->length); + + /* + * 4) Fourth subobject: Dereference the PRT.source_index + */ + obj_desc = sub_object_list[3]; + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { + user_prt->source_index = (u32) obj_desc->integer.value; + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "(PRT[%X].source_index) Need Integer, found %s\n", + index, acpi_ut_get_object_type_name (obj_desc))); + return_ACPI_STATUS (AE_BAD_DATA); + } - else { - *output_buffer_length = buffer_size_needed; + /* Point to the next union acpi_operand_object in the top level package */ - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); + top_object_list++; } - /* - * Report the amount of buffer used - */ - *output_buffer_length = buffer_size_needed; + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n", + output_buffer->pointer, (u32) output_buffer->length)); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_create_byte_stream + * FUNCTION: acpi_rs_create_byte_stream * - * PARAMETERS: Linked_list_buffer - Pointer to the resource linked list - * Output_buffer - Pointer to the user's buffer - * Output_buffer_length - Size of Output_buffer + * PARAMETERS: linked_list_buffer - Pointer to the resource linked list + * output_buffer - Pointer to the user's buffer * * RETURN: Status AE_OK if okay, else a valid acpi_status code. - * If the Output_buffer is too small, the error will be - * AE_BUFFER_OVERFLOW and Output_buffer_length will point + * If the output_buffer is too small, the error will be + * AE_BUFFER_OVERFLOW and output_buffer->Length will point * to the size buffer needed. * * DESCRIPTION: Takes the linked list of device resources and @@ -381,66 +378,51 @@ acpi_status acpi_rs_create_byte_stream ( - acpi_resource *linked_list_buffer, - u8 *output_buffer, - u32 *output_buffer_length) + struct acpi_resource *linked_list_buffer, + struct acpi_buffer *output_buffer) { - acpi_status status; - u32 byte_stream_size_needed = 0; + acpi_status status; + acpi_size byte_stream_size_needed = 0; - FUNCTION_TRACE ("Rs_create_byte_stream"); + ACPI_FUNCTION_TRACE ("rs_create_byte_stream"); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Linked_list_buffer = %p\n", linked_list_buffer)); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "linked_list_buffer = %p\n", + linked_list_buffer)); /* * Params already validated, so we don't re-validate here * - * Pass the Linked_list_buffer into a module that can calculate + * Pass the linked_list_buffer into a module that calculates * the buffer size needed for the byte stream. */ - status = acpi_rs_calculate_byte_stream_length (linked_list_buffer, + status = acpi_rs_get_byte_stream_length (linked_list_buffer, &byte_stream_size_needed); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Byte_stream_size_needed=%X, %s\n", - byte_stream_size_needed, acpi_format_exception (status))); - - /* - * Exit with the error passed back - */ + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n", + (u32) byte_stream_size_needed, acpi_format_exception (status))); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* - * If the linked list will fit into the available buffer - * call to fill in the list - */ - if (byte_stream_size_needed <= *output_buffer_length) { - /* - * Zero out the return buffer before proceeding - */ - MEMSET (output_buffer, 0x00, *output_buffer_length); - - status = acpi_rs_list_to_byte_stream (linked_list_buffer, byte_stream_size_needed, - &output_buffer); + /* Validate/Allocate/Clear caller buffer */ - /* - * Exit with the error passed back - */ - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Output_buffer = %p\n", output_buffer)); + status = acpi_ut_initialize_buffer (output_buffer, byte_stream_size_needed); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - else { - *output_buffer_length = byte_stream_size_needed; - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); + /* Do the conversion */ + + status = acpi_rs_list_to_byte_stream (linked_list_buffer, byte_stream_size_needed, + output_buffer->pointer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n", + output_buffer->pointer, (u32) output_buffer->length)); return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/resources/rsdump.c linux-2.4.22/drivers/acpi/resources/rsdump.c --- linux-2.4.21/drivers/acpi/resources/rsdump.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsdump.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,41 +1,59 @@ /******************************************************************************* * * Module Name: rsdump - Functions to display the resource structures. - * $Revision: 23 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsdump") + ACPI_MODULE_NAME ("rsdump") -#ifdef ACPI_DEBUG +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_irq + * FUNCTION: acpi_rs_dump_irq * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -47,25 +65,25 @@ void acpi_rs_dump_irq ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_irq *irq_data = (acpi_resource_irq *) data; - u8 index = 0; + struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *) data; + u8 index = 0; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("IRQ Resource\n"); acpi_os_printf (" %s Triggered\n", - LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge"); + ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge"); acpi_os_printf (" Active %s\n", - ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High"); + ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High"); acpi_os_printf (" %s\n", - SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive"); + ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive"); acpi_os_printf (" %X Interrupts ( ", irq_data->number_of_interrupts); @@ -80,7 +98,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_dma + * FUNCTION: acpi_rs_dump_dma * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -92,31 +110,31 @@ void acpi_rs_dump_dma ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_dma *dma_data = (acpi_resource_dma *) data; - u8 index = 0; + struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *) data; + u8 index = 0; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("DMA Resource\n"); switch (dma_data->type) { - case COMPATIBILITY: + case ACPI_COMPATIBILITY: acpi_os_printf (" Compatibility mode\n"); break; - case TYPE_A: + case ACPI_TYPE_A: acpi_os_printf (" Type A\n"); break; - case TYPE_B: + case ACPI_TYPE_B: acpi_os_printf (" Type B\n"); break; - case TYPE_F: + case ACPI_TYPE_F: acpi_os_printf (" Type F\n"); break; @@ -126,19 +144,19 @@ } acpi_os_printf (" %sBus Master\n", - BUS_MASTER == dma_data->bus_master ? "" : "Not a "); + ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a "); switch (dma_data->transfer) { - case TRANSFER_8: + case ACPI_TRANSFER_8: acpi_os_printf (" 8-bit only transfer\n"); break; - case TRANSFER_8_16: + case ACPI_TRANSFER_8_16: acpi_os_printf (" 8 and 16-bit transfer\n"); break; - case TRANSFER_16: + case ACPI_TRANSFER_16: acpi_os_printf (" 16 bit only transfer\n"); break; @@ -160,7 +178,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_start_dependent_functions + * FUNCTION: acpi_rs_dump_start_depend_fns * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -171,27 +189,27 @@ ******************************************************************************/ void -acpi_rs_dump_start_dependent_functions ( - acpi_resource_data *data) +acpi_rs_dump_start_depend_fns ( + union acpi_resource_data *data) { - acpi_resource_start_dpf *sdf_data = (acpi_resource_start_dpf *) data; + struct acpi_resource_start_dpf *sdf_data = (struct acpi_resource_start_dpf *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("Start Dependent Functions Resource\n"); switch (sdf_data->compatibility_priority) { - case GOOD_CONFIGURATION: + case ACPI_GOOD_CONFIGURATION: acpi_os_printf (" Good configuration\n"); break; - case ACCEPTABLE_CONFIGURATION: + case ACPI_ACCEPTABLE_CONFIGURATION: acpi_os_printf (" Acceptable configuration\n"); break; - case SUB_OPTIMAL_CONFIGURATION: + case ACPI_SUB_OPTIMAL_CONFIGURATION: acpi_os_printf (" Sub-optimal configuration\n"); break; @@ -201,15 +219,15 @@ } switch(sdf_data->performance_robustness) { - case GOOD_CONFIGURATION: + case ACPI_GOOD_CONFIGURATION: acpi_os_printf (" Good configuration\n"); break; - case ACCEPTABLE_CONFIGURATION: + case ACPI_ACCEPTABLE_CONFIGURATION: acpi_os_printf (" Acceptable configuration\n"); break; - case SUB_OPTIMAL_CONFIGURATION: + case ACPI_SUB_OPTIMAL_CONFIGURATION: acpi_os_printf (" Sub-optimal configuration\n"); break; @@ -225,7 +243,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_io + * FUNCTION: acpi_rs_dump_io * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -237,18 +255,18 @@ void acpi_rs_dump_io ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_io *io_data = (acpi_resource_io *) data; + struct acpi_resource_io *io_data = (struct acpi_resource_io *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("Io Resource\n"); acpi_os_printf (" %d bit decode\n", - DECODE_16 == io_data->io_decode ? 16 : 10); + ACPI_DECODE_16 == io_data->io_decode ? 16 : 10); acpi_os_printf (" Range minimum base: %08X\n", io_data->min_base_address); @@ -268,7 +286,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_fixed_io + * FUNCTION: acpi_rs_dump_fixed_io * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -280,12 +298,12 @@ void acpi_rs_dump_fixed_io ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_fixed_io *fixed_io_data = (acpi_resource_fixed_io *) data; + struct acpi_resource_fixed_io *fixed_io_data = (struct acpi_resource_fixed_io *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("Fixed Io Resource\n"); @@ -301,7 +319,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_vendor_specific + * FUNCTION: acpi_rs_dump_vendor_specific * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -313,13 +331,13 @@ void acpi_rs_dump_vendor_specific ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_vendor *vendor_data = (acpi_resource_vendor *) data; - u16 index = 0; + struct acpi_resource_vendor *vendor_data = (struct acpi_resource_vendor *) data; + u16 index = 0; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("Vendor Specific Resource\n"); @@ -337,7 +355,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_memory24 + * FUNCTION: acpi_rs_dump_memory24 * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -349,18 +367,18 @@ void acpi_rs_dump_memory24 ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_mem24 *memory24_data = (acpi_resource_mem24 *) data; + struct acpi_resource_mem24 *memory24_data = (struct acpi_resource_mem24 *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("24-Bit Memory Range Resource\n"); acpi_os_printf (" Read%s\n", - READ_WRITE_MEMORY == + ACPI_READ_WRITE_MEMORY == memory24_data->read_write_attribute ? "/Write" : " only"); @@ -382,7 +400,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_memory32 + * FUNCTION: acpi_rs_dump_memory32 * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -394,18 +412,18 @@ void acpi_rs_dump_memory32 ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_mem32 *memory32_data = (acpi_resource_mem32 *) data; + struct acpi_resource_mem32 *memory32_data = (struct acpi_resource_mem32 *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("32-Bit Memory Range Resource\n"); acpi_os_printf (" Read%s\n", - READ_WRITE_MEMORY == + ACPI_READ_WRITE_MEMORY == memory32_data->read_write_attribute ? "/Write" : " only"); @@ -427,7 +445,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_fixed_memory32 + * FUNCTION: acpi_rs_dump_fixed_memory32 * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -439,18 +457,18 @@ void acpi_rs_dump_fixed_memory32 ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_fixed_mem32 *fixed_memory32_data = (acpi_resource_fixed_mem32 *) data; + struct acpi_resource_fixed_mem32 *fixed_memory32_data = (struct acpi_resource_fixed_mem32 *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("32-Bit Fixed Location Memory Range Resource\n"); acpi_os_printf (" Read%s\n", - READ_WRITE_MEMORY == + ACPI_READ_WRITE_MEMORY == fixed_memory32_data->read_write_attribute ? "/Write" : " Only"); @@ -466,7 +484,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_address16 + * FUNCTION: acpi_rs_dump_address16 * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -478,39 +496,39 @@ void acpi_rs_dump_address16 ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_address16 *address16_data = (acpi_resource_address16 *) data; + struct acpi_resource_address16 *address16_data = (struct acpi_resource_address16 *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("16-Bit Address Space Resource\n"); acpi_os_printf (" Resource Type: "); switch (address16_data->resource_type) { - case MEMORY_RANGE: + case ACPI_MEMORY_RANGE: acpi_os_printf ("Memory Range\n"); switch (address16_data->attribute.memory.cache_attribute) { - case NON_CACHEABLE_MEMORY: + case ACPI_NON_CACHEABLE_MEMORY: acpi_os_printf (" Type Specific: " "Noncacheable memory\n"); break; - case CACHABLE_MEMORY: + case ACPI_CACHABLE_MEMORY: acpi_os_printf (" Type Specific: " "Cacheable memory\n"); break; - case WRITE_COMBINING_MEMORY: + case ACPI_WRITE_COMBINING_MEMORY: acpi_os_printf (" Type Specific: " "Write-combining memory\n"); break; - case PREFETCHABLE_MEMORY: + case ACPI_PREFETCHABLE_MEMORY: acpi_os_printf (" Type Specific: " "Prefetchable memory\n"); break; @@ -522,27 +540,27 @@ } acpi_os_printf (" Type Specific: Read%s\n", - READ_WRITE_MEMORY == + ACPI_READ_WRITE_MEMORY == address16_data->attribute.memory.read_write_attribute ? "/Write" : " Only"); break; - case IO_RANGE: + case ACPI_IO_RANGE: acpi_os_printf ("I/O Range\n"); switch (address16_data->attribute.io.range_attribute) { - case NON_ISA_ONLY_RANGES: + case ACPI_NON_ISA_ONLY_RANGES: acpi_os_printf (" Type Specific: " "Non-ISA Io Addresses\n"); break; - case ISA_ONLY_RANGES: + case ACPI_ISA_ONLY_RANGES: acpi_os_printf (" Type Specific: " "ISA Io Addresses\n"); break; - case ENTIRE_RANGE: + case ACPI_ENTIRE_RANGE: acpi_os_printf (" Type Specific: " "ISA and non-ISA Io Addresses\n"); break; @@ -552,9 +570,14 @@ "Invalid range attribute\n"); break; } + + acpi_os_printf (" Type Specific: %s Translation\n", + ACPI_SPARSE_TRANSLATION == + address16_data->attribute.io.translation_attribute ? + "Sparse" : "Dense"); break; - case BUS_NUMBER_RANGE: + case ACPI_BUS_NUMBER_RANGE: acpi_os_printf ("Bus Number Range\n"); break; @@ -566,19 +589,19 @@ } acpi_os_printf (" Resource %s\n", - CONSUMER == address16_data->producer_consumer ? + ACPI_CONSUMER == address16_data->producer_consumer ? "Consumer" : "Producer"); acpi_os_printf (" %s decode\n", - SUB_DECODE == address16_data->decode ? + ACPI_SUB_DECODE == address16_data->decode ? "Subtractive" : "Positive"); acpi_os_printf (" Min address is %s fixed\n", - ADDRESS_FIXED == address16_data->min_address_fixed ? + ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ? "" : "not"); acpi_os_printf (" Max address is %s fixed\n", - ADDRESS_FIXED == address16_data->max_address_fixed ? + ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ? "" : "not"); acpi_os_printf (" Granularity: %08X\n", @@ -609,7 +632,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_address32 + * FUNCTION: acpi_rs_dump_address32 * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -621,38 +644,38 @@ void acpi_rs_dump_address32 ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_address32 *address32_data = (acpi_resource_address32 *) data; + struct acpi_resource_address32 *address32_data = (struct acpi_resource_address32 *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("32-Bit Address Space Resource\n"); switch (address32_data->resource_type) { - case MEMORY_RANGE: + case ACPI_MEMORY_RANGE: acpi_os_printf (" Resource Type: Memory Range\n"); switch (address32_data->attribute.memory.cache_attribute) { - case NON_CACHEABLE_MEMORY: + case ACPI_NON_CACHEABLE_MEMORY: acpi_os_printf (" Type Specific: " "Noncacheable memory\n"); break; - case CACHABLE_MEMORY: + case ACPI_CACHABLE_MEMORY: acpi_os_printf (" Type Specific: " "Cacheable memory\n"); break; - case WRITE_COMBINING_MEMORY: + case ACPI_WRITE_COMBINING_MEMORY: acpi_os_printf (" Type Specific: " "Write-combining memory\n"); break; - case PREFETCHABLE_MEMORY: + case ACPI_PREFETCHABLE_MEMORY: acpi_os_printf (" Type Specific: " "Prefetchable memory\n"); break; @@ -664,39 +687,44 @@ } acpi_os_printf (" Type Specific: Read%s\n", - READ_WRITE_MEMORY == + ACPI_READ_WRITE_MEMORY == address32_data->attribute.memory.read_write_attribute ? "/Write" : " Only"); break; - case IO_RANGE: + case ACPI_IO_RANGE: acpi_os_printf (" Resource Type: Io Range\n"); switch (address32_data->attribute.io.range_attribute) { - case NON_ISA_ONLY_RANGES: - acpi_os_printf (" Type Specific: " - "Non-ISA Io Addresses\n"); - break; + case ACPI_NON_ISA_ONLY_RANGES: + acpi_os_printf (" Type Specific: " + "Non-ISA Io Addresses\n"); + break; - case ISA_ONLY_RANGES: - acpi_os_printf (" Type Specific: " - "ISA Io Addresses\n"); - break; + case ACPI_ISA_ONLY_RANGES: + acpi_os_printf (" Type Specific: " + "ISA Io Addresses\n"); + break; - case ENTIRE_RANGE: - acpi_os_printf (" Type Specific: " - "ISA and non-ISA Io Addresses\n"); - break; + case ACPI_ENTIRE_RANGE: + acpi_os_printf (" Type Specific: " + "ISA and non-ISA Io Addresses\n"); + break; - default: - acpi_os_printf (" Type Specific: " - "Invalid Range attribute"); - break; - } + default: + acpi_os_printf (" Type Specific: " + "Invalid Range attribute"); + break; + } + + acpi_os_printf (" Type Specific: %s Translation\n", + ACPI_SPARSE_TRANSLATION == + address32_data->attribute.io.translation_attribute ? + "Sparse" : "Dense"); break; - case BUS_NUMBER_RANGE: + case ACPI_BUS_NUMBER_RANGE: acpi_os_printf (" Resource Type: Bus Number Range\n"); break; @@ -708,19 +736,19 @@ } acpi_os_printf (" Resource %s\n", - CONSUMER == address32_data->producer_consumer ? + ACPI_CONSUMER == address32_data->producer_consumer ? "Consumer" : "Producer"); acpi_os_printf (" %s decode\n", - SUB_DECODE == address32_data->decode ? + ACPI_SUB_DECODE == address32_data->decode ? "Subtractive" : "Positive"); acpi_os_printf (" Min address is %s fixed\n", - ADDRESS_FIXED == address32_data->min_address_fixed ? + ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ? "" : "not "); acpi_os_printf (" Max address is %s fixed\n", - ADDRESS_FIXED == address32_data->max_address_fixed ? + ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ? "" : "not "); acpi_os_printf (" Granularity: %08X\n", @@ -751,7 +779,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_address64 + * FUNCTION: acpi_rs_dump_address64 * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -763,38 +791,38 @@ void acpi_rs_dump_address64 ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_address64 *address64_data = (acpi_resource_address64 *) data; + struct acpi_resource_address64 *address64_data = (struct acpi_resource_address64 *) data; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("64-Bit Address Space Resource\n"); switch (address64_data->resource_type) { - case MEMORY_RANGE: + case ACPI_MEMORY_RANGE: acpi_os_printf (" Resource Type: Memory Range\n"); switch (address64_data->attribute.memory.cache_attribute) { - case NON_CACHEABLE_MEMORY: + case ACPI_NON_CACHEABLE_MEMORY: acpi_os_printf (" Type Specific: " "Noncacheable memory\n"); break; - case CACHABLE_MEMORY: + case ACPI_CACHABLE_MEMORY: acpi_os_printf (" Type Specific: " "Cacheable memory\n"); break; - case WRITE_COMBINING_MEMORY: + case ACPI_WRITE_COMBINING_MEMORY: acpi_os_printf (" Type Specific: " "Write-combining memory\n"); break; - case PREFETCHABLE_MEMORY: + case ACPI_PREFETCHABLE_MEMORY: acpi_os_printf (" Type Specific: " "Prefetchable memory\n"); break; @@ -806,39 +834,44 @@ } acpi_os_printf (" Type Specific: Read%s\n", - READ_WRITE_MEMORY == + ACPI_READ_WRITE_MEMORY == address64_data->attribute.memory.read_write_attribute ? "/Write" : " Only"); break; - case IO_RANGE: + case ACPI_IO_RANGE: acpi_os_printf (" Resource Type: Io Range\n"); switch (address64_data->attribute.io.range_attribute) { - case NON_ISA_ONLY_RANGES: - acpi_os_printf (" Type Specific: " - "Non-ISA Io Addresses\n"); - break; + case ACPI_NON_ISA_ONLY_RANGES: + acpi_os_printf (" Type Specific: " + "Non-ISA Io Addresses\n"); + break; - case ISA_ONLY_RANGES: - acpi_os_printf (" Type Specific: " - "ISA Io Addresses\n"); - break; + case ACPI_ISA_ONLY_RANGES: + acpi_os_printf (" Type Specific: " + "ISA Io Addresses\n"); + break; - case ENTIRE_RANGE: - acpi_os_printf (" Type Specific: " - "ISA and non-ISA Io Addresses\n"); - break; + case ACPI_ENTIRE_RANGE: + acpi_os_printf (" Type Specific: " + "ISA and non-ISA Io Addresses\n"); + break; - default: - acpi_os_printf (" Type Specific: " - "Invalid Range attribute"); - break; - } + default: + acpi_os_printf (" Type Specific: " + "Invalid Range attribute"); + break; + } + + acpi_os_printf (" Type Specific: %s Translation\n", + ACPI_SPARSE_TRANSLATION == + address64_data->attribute.io.translation_attribute ? + "Sparse" : "Dense"); break; - case BUS_NUMBER_RANGE: + case ACPI_BUS_NUMBER_RANGE: acpi_os_printf (" Resource Type: Bus Number Range\n"); break; @@ -850,35 +883,40 @@ } acpi_os_printf (" Resource %s\n", - CONSUMER == address64_data->producer_consumer ? + ACPI_CONSUMER == address64_data->producer_consumer ? "Consumer" : "Producer"); acpi_os_printf (" %s decode\n", - SUB_DECODE == address64_data->decode ? + ACPI_SUB_DECODE == address64_data->decode ? "Subtractive" : "Positive"); acpi_os_printf (" Min address is %s fixed\n", - ADDRESS_FIXED == address64_data->min_address_fixed ? + ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ? "" : "not "); acpi_os_printf (" Max address is %s fixed\n", - ADDRESS_FIXED == address64_data->max_address_fixed ? + ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ? "" : "not "); - acpi_os_printf (" Granularity: %16X\n", - address64_data->granularity); - - acpi_os_printf (" Address range min: %16X\n", - address64_data->min_address_range); - - acpi_os_printf (" Address range max: %16X\n", - address64_data->max_address_range); - - acpi_os_printf (" Address translation offset: %16X\n", - address64_data->address_translation_offset); - - acpi_os_printf (" Address Length: %16X\n", - address64_data->address_length); + acpi_os_printf (" Granularity: %8.8X%8.8X\n", + ACPI_HIDWORD (address64_data->granularity), + ACPI_LODWORD (address64_data->granularity)); + + acpi_os_printf (" Address range min: %8.8X%8.8X\n", + ACPI_HIDWORD (address64_data->min_address_range), + ACPI_HIDWORD (address64_data->min_address_range)); + + acpi_os_printf (" Address range max: %8.8X%8.8X\n", + ACPI_HIDWORD (address64_data->max_address_range), + ACPI_HIDWORD (address64_data->max_address_range)); + + acpi_os_printf (" Address translation offset: %8.8X%8.8X\n", + ACPI_HIDWORD (address64_data->address_translation_offset), + ACPI_HIDWORD (address64_data->address_translation_offset)); + + acpi_os_printf (" Address Length: %8.8X%8.8X\n", + ACPI_HIDWORD (address64_data->address_length), + ACPI_HIDWORD (address64_data->address_length)); if(0xFF != address64_data->resource_source.index) { acpi_os_printf (" Resource Source Index: %X\n", @@ -893,7 +931,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_extended_irq + * FUNCTION: acpi_rs_dump_extended_irq * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -905,31 +943,31 @@ void acpi_rs_dump_extended_irq ( - acpi_resource_data *data) + union acpi_resource_data *data) { - acpi_resource_ext_irq *ext_irq_data = (acpi_resource_ext_irq *) data; - u8 index = 0; + struct acpi_resource_ext_irq *ext_irq_data = (struct acpi_resource_ext_irq *) data; + u8 index = 0; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); acpi_os_printf ("Extended IRQ Resource\n"); acpi_os_printf (" Resource %s\n", - CONSUMER == ext_irq_data->producer_consumer ? + ACPI_CONSUMER == ext_irq_data->producer_consumer ? "Consumer" : "Producer"); acpi_os_printf (" %s\n", - LEVEL_SENSITIVE == ext_irq_data->edge_level ? + ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ? "Level" : "Edge"); acpi_os_printf (" Active %s\n", - ACTIVE_LOW == ext_irq_data->active_high_low ? + ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ? "low" : "high"); acpi_os_printf (" %s\n", - SHARED == ext_irq_data->shared_exclusive ? + ACPI_SHARED == ext_irq_data->shared_exclusive ? "Shared" : "Exclusive"); acpi_os_printf (" Interrupts : %X ( ", @@ -954,7 +992,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_resource_list + * FUNCTION: acpi_rs_dump_resource_list * * PARAMETERS: Data - pointer to the resource structure to dump. * @@ -966,18 +1004,18 @@ void acpi_rs_dump_resource_list ( - acpi_resource *resource) + struct acpi_resource *resource) { - u8 count = 0; - u8 done = FALSE; + u8 count = 0; + u8 done = FALSE; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { while (!done) { - acpi_os_printf ("Resource structure %x.\n", count++); + acpi_os_printf ("Resource structure %X.\n", count++); switch (resource->id) { case ACPI_RSTYPE_IRQ: @@ -989,12 +1027,12 @@ break; case ACPI_RSTYPE_START_DPF: - acpi_rs_dump_start_dependent_functions (&resource->data); + acpi_rs_dump_start_depend_fns (&resource->data); break; case ACPI_RSTYPE_END_DPF: - acpi_os_printf ("End_dependent_functions Resource\n"); - /* Acpi_rs_dump_end_dependent_functions (Resource->Data);*/ + acpi_os_printf ("end_dependent_functions Resource\n"); + /* acpi_rs_dump_end_dependent_functions (Resource->Data);*/ break; case ACPI_RSTYPE_IO: @@ -1010,8 +1048,8 @@ break; case ACPI_RSTYPE_END_TAG: - /*Rs_dump_end_tag (Resource->Data);*/ - acpi_os_printf ("End_tag Resource\n"); + /*rs_dump_end_tag (Resource->Data);*/ + acpi_os_printf ("end_tag Resource\n"); done = TRUE; break; @@ -1049,7 +1087,7 @@ } - resource = POINTER_ADD (acpi_resource, resource, resource->length); + resource = ACPI_PTR_ADD (struct acpi_resource, resource, resource->length); } } @@ -1058,7 +1096,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dump_irq_list + * FUNCTION: acpi_rs_dump_irq_list * * PARAMETERS: Data - pointer to the routing table to dump. * @@ -1070,36 +1108,37 @@ void acpi_rs_dump_irq_list ( - u8 *route_table) + u8 *route_table) { - u8 *buffer = route_table; - u8 count = 0; - u8 done = FALSE; - pci_routing_table *prt_element; + u8 *buffer = route_table; + u8 count = 0; + u8 done = FALSE; + struct acpi_pci_routing_table *prt_element; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { - prt_element = (pci_routing_table *) buffer; + prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); while (!done) { acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++); - acpi_os_printf (" Address: %X\n", - prt_element->address); + acpi_os_printf (" Address: %8.8X%8.8X\n", + ACPI_HIDWORD (prt_element->address), + ACPI_LODWORD (prt_element->address)); acpi_os_printf (" Pin: %X\n", prt_element->pin); acpi_os_printf (" Source: %s\n", prt_element->source); - acpi_os_printf (" Source_index: %X\n", + acpi_os_printf (" source_index: %X\n", prt_element->source_index); buffer += prt_element->length; - prt_element = (pci_routing_table *) buffer; + prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); if(0 == prt_element->length) { done = TRUE; diff -urN linux-2.4.21/drivers/acpi/resources/rsio.c linux-2.4.22/drivers/acpi/resources/rsio.c --- linux-2.4.21/drivers/acpi/resources/rsio.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsio.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,73 +1,90 @@ /******************************************************************************* * * Module Name: rsio - IO and DMA resource descriptors - * $Revision: 14 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsio") + ACPI_MODULE_NAME ("rsio") /******************************************************************************* * - * FUNCTION: Acpi_rs_io_resource + * FUNCTION: acpi_rs_io_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_io_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_io); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io); - FUNCTION_TRACE ("Rs_io_resource"); + ACPI_FUNCTION_TRACE ("rs_io_resource"); /* @@ -86,18 +103,18 @@ output_struct->data.io.io_decode = temp8 & 0x01; /* - * Check Min_base Address + * Check min_base Address */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); output_struct->data.io.min_base_address = temp16; /* - * Check Max_base Address + * Check max_base Address */ buffer += 2; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); output_struct->data.io.max_base_address = temp16; @@ -110,7 +127,7 @@ output_struct->data.io.alignment = temp8; /* - * Check Range_length + * Check range_length */ buffer += 1; temp8 = *buffer; @@ -120,7 +137,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -132,41 +149,40 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_fixed_io_resource + * FUNCTION: acpi_rs_fixed_io_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_fixed_io_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_fixed_io); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io); - FUNCTION_TRACE ("Rs_fixed_io_resource"); + ACPI_FUNCTION_TRACE ("rs_fixed_io_resource"); /* @@ -180,12 +196,12 @@ * Check Range Base Address */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); output_struct->data.fixed_io.base_address = temp16; /* - * Check Range_length + * Check range_length */ buffer += 2; temp8 = *buffer; @@ -195,7 +211,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -207,13 +223,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_io_stream + * FUNCTION: acpi_rs_io_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -224,16 +239,16 @@ acpi_status acpi_rs_io_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; - FUNCTION_TRACE ("Rs_io_stream"); + ACPI_FUNCTION_TRACE ("rs_io_stream"); /* @@ -255,7 +270,7 @@ */ temp16 = (u16) linked_list->data.io.min_base_address; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -263,7 +278,7 @@ */ temp16 = (u16) linked_list->data.io.max_base_address; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -285,20 +300,19 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_fixed_io_stream + * FUNCTION: acpi_rs_fixed_io_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -309,16 +323,16 @@ acpi_status acpi_rs_fixed_io_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; - FUNCTION_TRACE ("Rs_fixed_io_stream"); + ACPI_FUNCTION_TRACE ("rs_fixed_io_stream"); /* @@ -333,7 +347,7 @@ */ temp16 = (u16) linked_list->data.fixed_io.base_address; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -347,49 +361,48 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_dma_resource + * FUNCTION: acpi_rs_dma_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_dma_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u8 temp8 = 0; - u8 index; - u8 i; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_dma); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u8 temp8 = 0; + u8 index; + u8 i; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma); - FUNCTION_TRACE ("Rs_dma_resource"); + ACPI_FUNCTION_TRACE ("rs_dma_resource"); /* @@ -404,7 +417,7 @@ buffer += 1; temp8 = *buffer; - /* Decode the IRQ bits */ + /* Decode the DMA channel bits */ for (i = 0, index = 0; index < 8; index++) { if ((temp8 >> index) & 0x01) { @@ -412,13 +425,16 @@ i++; } } - output_struct->data.dma.number_of_channels = i; + /* Zero DMA channels is valid */ - /* - * Calculate the structure size based upon the number of interrupts - */ - struct_size += (output_struct->data.dma.number_of_channels - 1) * 4; + output_struct->data.dma.number_of_channels = i; + if (i > 0) { + /* + * Calculate the structure size based upon the number of interrupts + */ + struct_size += ((acpi_size) i - 1) * 4; + } /* * Point to Byte 2 @@ -432,6 +448,7 @@ output_struct->data.dma.transfer = temp8 & 0x03; if (0x03 == output_struct->data.dma.transfer) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n")); return_ACPI_STATUS (AE_BAD_DATA); } @@ -448,7 +465,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -460,13 +477,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_dma_stream + * FUNCTION: acpi_rs_dma_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -477,17 +493,17 @@ acpi_status acpi_rs_dma_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + u8 index; - FUNCTION_TRACE ("Rs_dma_stream"); + ACPI_FUNCTION_TRACE ("rs_dma_stream"); /* @@ -523,7 +539,7 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/resources/rsirq.c linux-2.4.22/drivers/acpi/resources/rsirq.c --- linux-2.4.21/drivers/acpi/resources/rsirq.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsirq.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,75 +1,92 @@ /******************************************************************************* * * Module Name: rsirq - IRQ resource descriptors - * $Revision: 18 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsirq") + ACPI_MODULE_NAME ("rsirq") /******************************************************************************* * - * FUNCTION: Acpi_rs_irq_resource + * FUNCTION: acpi_rs_irq_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_irq_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - u8 i; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_irq); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + u8 index; + u8 i; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_irq); - FUNCTION_TRACE ("Rs_irq_resource"); + ACPI_FUNCTION_TRACE ("rs_irq_resource"); /* @@ -84,24 +101,28 @@ * Point to the 16-bits of Bytes 1 and 2 */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); output_struct->data.irq.number_of_interrupts = 0; /* Decode the IRQ bits */ for (i = 0, index = 0; index < 16; index++) { - if((temp16 >> index) & 0x01) { + if ((temp16 >> index) & 0x01) { output_struct->data.irq.interrupts[i] = index; i++; } } - output_struct->data.irq.number_of_interrupts = i; - /* - * Calculate the structure size based upon the number of interrupts - */ - struct_size += (output_struct->data.irq.number_of_interrupts - 1) * 4; + /* Zero interrupts is valid */ + + output_struct->data.irq.number_of_interrupts = i; + if (i > 0) { + /* + * Calculate the structure size based upon the number of interrupts + */ + struct_size += ((acpi_size) i - 1) * 4; + } /* * Point to Byte 3 if it is used @@ -114,22 +135,21 @@ * Check for HE, LL or HL */ if (temp8 & 0x01) { - output_struct->data.irq.edge_level = EDGE_SENSITIVE; - output_struct->data.irq.active_high_low = ACTIVE_HIGH; + output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; + output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; } - else { if (temp8 & 0x8) { - output_struct->data.irq.edge_level = LEVEL_SENSITIVE; - output_struct->data.irq.active_high_low = ACTIVE_LOW; + output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE; + output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW; } - else { /* * Only _LL and _HE polarity/trigger interrupts * are allowed (ACPI spec v1.0b ection 6.4.2.1), * so an error will occur if we reach this point */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list\n")); return_ACPI_STATUS (AE_BAD_DATA); } } @@ -139,21 +159,20 @@ */ output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; } - else { /* * Assume Edge Sensitive, Active High, Non-Sharable * per ACPI Specification */ - output_struct->data.irq.edge_level = EDGE_SENSITIVE; - output_struct->data.irq.active_high_low = ACTIVE_HIGH; - output_struct->data.irq.shared_exclusive = EXCLUSIVE; + output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; + output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; + output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE; } /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -165,13 +184,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_irq_stream + * FUNCTION: acpi_rs_irq_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -182,34 +200,33 @@ acpi_status acpi_rs_irq_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - u8 IRQinfo_byte_needed; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + u8 index; + u8 IRqinfo_byte_needed; - FUNCTION_TRACE ("Rs_irq_stream"); + ACPI_FUNCTION_TRACE ("rs_irq_stream"); /* * The descriptor field is set based upon whether a third byte is * needed to contain the IRQ Information. */ - if (EDGE_SENSITIVE == linked_list->data.irq.edge_level && - ACTIVE_HIGH == linked_list->data.irq.active_high_low && - EXCLUSIVE == linked_list->data.irq.shared_exclusive) { + if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level && + ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low && + ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) { *buffer = 0x22; - IRQinfo_byte_needed = FALSE; + IRqinfo_byte_needed = FALSE; } - else { *buffer = 0x23; - IRQinfo_byte_needed = TRUE; + IRqinfo_byte_needed = TRUE; } buffer += 1; @@ -225,22 +242,21 @@ temp16 |= 0x1 << temp8; } - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; /* * Set the IRQ Info byte if needed. */ - if (IRQinfo_byte_needed) { + if (IRqinfo_byte_needed) { temp8 = 0; temp8 = (u8) ((linked_list->data.irq.shared_exclusive & 0x01) << 4); - if (LEVEL_SENSITIVE == linked_list->data.irq.edge_level && - ACTIVE_LOW == linked_list->data.irq.active_high_low) { + if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level && + ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) { temp8 |= 0x08; } - else { temp8 |= 0x01; } @@ -252,57 +268,56 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_extended_irq_resource + * FUNCTION: acpi_rs_extended_irq_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_extended_irq_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - NATIVE_CHAR *temp_ptr; - u8 index; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_ext_irq); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + u8 *temp_ptr; + u8 index; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq); - FUNCTION_TRACE ("Rs_extended_irq_resource"); + ACPI_FUNCTION_TRACE ("rs_extended_irq_resource"); /* * Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_EXT_IRQ; @@ -316,28 +331,20 @@ output_struct->data.extended_irq.producer_consumer = temp8 & 0x01; /* - * Check for HE, LL or HL + * Check for Interrupt Mode + * + * The definition of an Extended IRQ changed between ACPI spec v1.0b + * and ACPI spec 2.0 (section 6.4.3.6 in both). + * + * - Edge/Level are defined opposite in the table vs the headers */ - if(temp8 & 0x02) { - output_struct->data.extended_irq.edge_level = EDGE_SENSITIVE; - output_struct->data.extended_irq.active_high_low = ACTIVE_HIGH; - } + output_struct->data.extended_irq.edge_level = + (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; - else { - if(temp8 & 0x4) { - output_struct->data.extended_irq.edge_level = LEVEL_SENSITIVE; - output_struct->data.extended_irq.active_high_low = ACTIVE_LOW; - } - - else { - /* - * Only _LL and _HE polarity/trigger interrupts - * are allowed (ACPI spec v1.0b ection 6.4.2.1), - * so an error will occur if we reach this point - */ - return_ACPI_STATUS (AE_BAD_DATA); - } - } + /* + * Check Interrupt Polarity + */ + output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1; /* * Check for sharable @@ -367,8 +374,8 @@ * Cycle through every IRQ in the table */ for (index = 0; index < temp8; index++) { - output_struct->data.extended_irq.interrupts[index] = - (u32)*buffer; + ACPI_MOVE_32_TO_32 ( + &output_struct->data.extended_irq.interrupts[index], buffer); /* Point to the next IRQ */ @@ -383,7 +390,7 @@ * stream that are default. */ if (*bytes_consumed > - (u32)(output_struct->data.extended_irq.number_of_interrupts * 4) + 5) { + ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + 5) { /* Dereference the Index */ temp8 = *buffer; @@ -397,14 +404,13 @@ * Point the String pointer to the end of this structure. */ output_struct->data.extended_irq.resource_source.string_ptr = - (NATIVE_CHAR *)(output_struct + struct_size); + (char *)(output_struct + struct_size); - temp_ptr = output_struct->data.extended_irq.resource_source.string_ptr; + temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr; /* Copy the string into the buffer */ index = 0; - while (0x00 != *buffer) { *temp_ptr = *buffer; @@ -420,14 +426,13 @@ output_struct->data.extended_irq.resource_source.string_length = index + 1; /* - * In order for the Struct_size to fall on a 32-bit boundary, + * In order for the struct_size to fall on a 32-bit boundary, * calculate the length of the string and expand the - * Struct_size to the next 32-bit boundary. + * struct_size to the next 32-bit boundary. */ temp8 = (u8) (index + 1); - struct_size += ROUND_UP_TO_32_bITS (temp8); + struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); } - else { output_struct->data.extended_irq.resource_source.index = 0x00; output_struct->data.extended_irq.resource_source.string_length = 0; @@ -437,7 +442,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -449,13 +454,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_extended_irq_stream + * FUNCTION: acpi_rs_extended_irq_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -466,18 +470,18 @@ acpi_status acpi_rs_extended_irq_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 *length_field; - u8 temp8 = 0; - u8 index; - NATIVE_CHAR *temp_pointer = NULL; + u8 *buffer = *output_buffer; + u16 *length_field; + u8 temp8 = 0; + u8 index; + char *temp_pointer = NULL; - FUNCTION_TRACE ("Rs_extended_irq_stream"); + ACPI_FUNCTION_TRACE ("rs_extended_irq_stream"); /* @@ -489,7 +493,7 @@ /* * Set a pointer to the Length field - to be filled in later */ - length_field = (u16 *)buffer; + length_field = ACPI_CAST_PTR (u16, buffer); buffer += 2; /* @@ -498,14 +502,24 @@ temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01); temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3); - if (LEVEL_SENSITIVE == linked_list->data.extended_irq.edge_level && - ACTIVE_LOW == linked_list->data.extended_irq.active_high_low) { - temp8 |= 0x04; - } - else { - temp8 |= 0x02; + /* + * Set the Interrupt Mode + * + * The definition of an Extended IRQ changed between ACPI spec v1.0b + * and ACPI spec 2.0 (section 6.4.3.6 in both). This code does not + * implement the more restrictive definition of 1.0b + * + * - Edge/Level are defined opposite in the table vs the headers + */ + if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) { + temp8 |= 0x2; } + /* + * Set the Interrupt Polarity + */ + temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2); + *buffer = temp8; buffer += 1; @@ -519,7 +533,7 @@ for (index = 0; index < linked_list->data.extended_irq.number_of_interrupts; index++) { - MOVE_UNALIGNED32_TO_32 (buffer, + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.extended_irq.interrupts[index]); buffer += 4; } @@ -531,25 +545,25 @@ *buffer = (u8) linked_list->data.extended_irq.resource_source.index; buffer += 1; - temp_pointer = (NATIVE_CHAR *) buffer; + temp_pointer = (char *) buffer; /* * Copy the string */ - STRCPY (temp_pointer, + ACPI_STRCPY (temp_pointer, linked_list->data.extended_irq.resource_source.string_ptr); /* * Buffer needs to be set to the length of the sting + one for the * terminating null */ - buffer += (STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1); + buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1); } /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); /* * Set the length field to the number of bytes consumed diff -urN linux-2.4.21/drivers/acpi/resources/rslist.c linux-2.4.22/drivers/acpi/resources/rslist.c --- linux-2.4.21/drivers/acpi/resources/rslist.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rslist.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,41 +1,59 @@ /******************************************************************************* * * Module Name: rslist - Linked list utilities - * $Revision: 19 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rslist") + ACPI_MODULE_NAME ("rslist") /******************************************************************************* * - * FUNCTION: Acpi_rs_get_resource_type + * FUNCTION: acpi_rs_get_resource_type * - * PARAMETERS: Resource_start_byte - Byte 0 of a resource descriptor + * PARAMETERS: resource_start_byte - Byte 0 of a resource descriptor * * RETURN: The Resource Type (Name) with no extraneous bits * @@ -46,31 +64,34 @@ u8 acpi_rs_get_resource_type ( - u8 resource_start_byte) + u8 resource_start_byte) { - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* * Determine if this is a small or large resource */ - switch (resource_start_byte & RESOURCE_DESC_TYPE_MASK) { - case RESOURCE_DESC_TYPE_SMALL: + switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) { + case ACPI_RDESC_TYPE_SMALL: /* * Small Resource Type -- Only bits 6:3 are valid */ - return ((u8) (resource_start_byte & RESOURCE_DESC_SMALL_MASK)); - break; + return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK)); - case RESOURCE_DESC_TYPE_LARGE: + case ACPI_RDESC_TYPE_LARGE: /* * Large Resource Type -- All bits are valid */ return (resource_start_byte); + + + default: + /* No other types of resource descriptor */ break; } @@ -80,11 +101,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_byte_stream_to_list + * FUNCTION: acpi_rs_byte_stream_to_list * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream - * Byte_stream_buffer_length - Length of Byte_stream_buffer - * Output_buffer - Pointer to the buffer that will + * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream + * byte_stream_buffer_length - Length of byte_stream_buffer + * output_buffer - Pointer to the buffer that will * contain the output structures * * RETURN: Status @@ -96,185 +117,184 @@ acpi_status acpi_rs_byte_stream_to_list ( - u8 *byte_stream_buffer, - u32 byte_stream_buffer_length, - u8 **output_buffer) + u8 *byte_stream_buffer, + u32 byte_stream_buffer_length, + u8 *output_buffer) { - acpi_status status; - u32 bytes_parsed = 0; - u8 resource_type = 0; - u32 bytes_consumed = 0; - u8 **buffer = output_buffer; - u32 structure_size = 0; - u8 end_tag_processed = FALSE; + acpi_status status; + acpi_size bytes_parsed = 0; + u8 resource_type = 0; + acpi_size bytes_consumed = 0; + u8 *buffer = output_buffer; + acpi_size structure_size = 0; + u8 end_tag_processed = FALSE; + struct acpi_resource *resource; - - FUNCTION_TRACE ("Rs_byte_stream_to_list"); + ACPI_FUNCTION_TRACE ("rs_byte_stream_to_list"); while (bytes_parsed < byte_stream_buffer_length && - FALSE == end_tag_processed) { + !end_tag_processed) { /* * The next byte in the stream is the resource type */ resource_type = acpi_rs_get_resource_type (*byte_stream_buffer); switch (resource_type) { - case RESOURCE_DESC_MEMORY_24: + case ACPI_RDESC_TYPE_MEMORY_24: /* * 24-Bit Memory Resource */ status = acpi_rs_memory24_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_LARGE_VENDOR: + case ACPI_RDESC_TYPE_LARGE_VENDOR: /* * Vendor Defined Resource */ status = acpi_rs_vendor_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_MEMORY_32: + case ACPI_RDESC_TYPE_MEMORY_32: /* * 32-Bit Memory Range Resource */ status = acpi_rs_memory32_range_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_FIXED_MEMORY_32: + case ACPI_RDESC_TYPE_FIXED_MEMORY_32: /* * 32-Bit Fixed Memory Resource */ status = acpi_rs_fixed_memory32_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_QWORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: /* * 64-Bit Address Resource */ status = acpi_rs_address64_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_DWORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: /* * 32-Bit Address Resource */ status = acpi_rs_address32_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_WORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: /* * 16-Bit Address Resource */ status = acpi_rs_address16_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_EXTENDED_XRUPT: + case ACPI_RDESC_TYPE_EXTENDED_XRUPT: /* * Extended IRQ */ status = acpi_rs_extended_irq_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_IRQ_FORMAT: + case ACPI_RDESC_TYPE_IRQ_FORMAT: /* * IRQ Resource */ status = acpi_rs_irq_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_DMA_FORMAT: + case ACPI_RDESC_TYPE_DMA_FORMAT: /* * DMA Resource */ status = acpi_rs_dma_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_START_DEPENDENT: + case ACPI_RDESC_TYPE_START_DEPENDENT: /* * Start Dependent Functions Resource */ - status = acpi_rs_start_dependent_functions_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + status = acpi_rs_start_depend_fns_resource (byte_stream_buffer, + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_END_DEPENDENT: + case ACPI_RDESC_TYPE_END_DEPENDENT: /* * End Dependent Functions Resource */ - status = acpi_rs_end_dependent_functions_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + status = acpi_rs_end_depend_fns_resource (byte_stream_buffer, + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_IO_PORT: + case ACPI_RDESC_TYPE_IO_PORT: /* * IO Port Resource */ status = acpi_rs_io_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_FIXED_IO_PORT: + case ACPI_RDESC_TYPE_FIXED_IO_PORT: /* * Fixed IO Port Resource */ status = acpi_rs_fixed_io_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_SMALL_VENDOR: + case ACPI_RDESC_TYPE_SMALL_VENDOR: /* * Vendor Specific Resource */ status = acpi_rs_vendor_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; - case RESOURCE_DESC_END_TAG: + case ACPI_RDESC_TYPE_END_TAG: /* * End Tag */ end_tag_processed = TRUE; status = acpi_rs_end_tag_resource (byte_stream_buffer, - &bytes_consumed, buffer, &structure_size); + &bytes_consumed, &buffer, &structure_size); break; default: /* - * Invalid/Unknowns resource type + * Invalid/Unknown resource type */ - status = AE_AML_ERROR; + status = AE_AML_INVALID_RESOURCE_TYPE; break; } - - if (!ACPI_SUCCESS(status)) { + if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -291,15 +311,17 @@ /* * Set the Buffer to the next structure */ - *buffer += structure_size; + resource = ACPI_CAST_PTR (struct acpi_resource, buffer); + resource->length = ACPI_ALIGN_RESOURCE_SIZE(resource->length); + buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); } /* end while */ /* * Check the reason for exiting the while loop */ - if (TRUE != end_tag_processed) { - return_ACPI_STATUS (AE_AML_ERROR); + if (!end_tag_processed) { + return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); } return_ACPI_STATUS (AE_OK); @@ -308,16 +330,16 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_list_to_byte_stream + * FUNCTION: acpi_rs_list_to_byte_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Byte_steam_size_needed - Calculated size of the byte stream + * PARAMETERS: linked_list - Pointer to the resource linked list + * byte_steam_size_needed - Calculated size of the byte stream * needed from calling - * Acpi_rs_calculate_byte_stream_length() - * The size of the Output_buffer is + * acpi_rs_get_byte_stream_length() + * The size of the output_buffer is * guaranteed to be >= - * Byte_stream_size_needed - * Output_buffer - Pointer to the buffer that will + * byte_stream_size_needed + * output_buffer - Pointer to the buffer that will * contain the byte stream * * RETURN: Status @@ -329,17 +351,17 @@ acpi_status acpi_rs_list_to_byte_stream ( - acpi_resource *linked_list, - u32 byte_stream_size_needed, - u8 **output_buffer) + struct acpi_resource *linked_list, + acpi_size byte_stream_size_needed, + u8 *output_buffer) { - acpi_status status; - u8 *buffer = *output_buffer; - u32 bytes_consumed = 0; - u8 done = FALSE; + acpi_status status; + u8 *buffer = output_buffer; + acpi_size bytes_consumed = 0; + u8 done = FALSE; - FUNCTION_TRACE ("Rs_list_to_byte_stream"); + ACPI_FUNCTION_TRACE ("rs_list_to_byte_stream"); while (!done) { @@ -362,7 +384,7 @@ /* * Start Dependent Functions Resource */ - status = acpi_rs_start_dependent_functions_stream (linked_list, + status = acpi_rs_start_depend_fns_stream (linked_list, &buffer, &bytes_consumed); break; @@ -370,7 +392,7 @@ /* * End Dependent Functions Resource */ - status = acpi_rs_end_dependent_functions_stream (linked_list, + status = acpi_rs_end_depend_fns_stream (linked_list, &buffer, &bytes_consumed); break; @@ -467,13 +489,14 @@ * If we get here, everything is out of sync, * so exit with an error */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n", + linked_list->id)); status = AE_BAD_DATA; break; - } /* switch (Linked_list->Id) */ - + } /* switch (linked_list->Id) */ - if (!ACPI_SUCCESS(status)) { + if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -485,7 +508,7 @@ /* * Point to the next object */ - linked_list = POINTER_ADD (acpi_resource, + linked_list = ACPI_PTR_ADD (struct acpi_resource, linked_list, linked_list->length); } diff -urN linux-2.4.21/drivers/acpi/resources/rsmemory.c linux-2.4.22/drivers/acpi/resources/rsmemory.c --- linux-2.4.21/drivers/acpi/resources/rsmemory.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsmemory.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,73 +1,90 @@ /******************************************************************************* * * Module Name: rsmem24 - Memory resource descriptors - * $Revision: 14 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsmemory") + ACPI_MODULE_NAME ("rsmemory") /******************************************************************************* * - * FUNCTION: Acpi_rs_memory24_resource + * FUNCTION: acpi_rs_memory24_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_memory24_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_mem24); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24); - FUNCTION_TRACE ("Rs_memory24_resource"); + ACPI_FUNCTION_TRACE ("rs_memory24_resource"); /* @@ -75,9 +92,9 @@ */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); buffer += 2; - *bytes_consumed = temp16 + 3; + *bytes_consumed = (acpi_size) temp16 + 3; output_struct->id = ACPI_RSTYPE_MEM24; /* @@ -88,36 +105,36 @@ output_struct->data.memory24.read_write_attribute = temp8 & 0x01; /* - * Get Min_base_address (Bytes 4-5) + * Get min_base_address (Bytes 4-5) */ - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); buffer += 2; output_struct->data.memory24.min_base_address = temp16; /* - * Get Max_base_address (Bytes 6-7) + * Get max_base_address (Bytes 6-7) */ - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); buffer += 2; output_struct->data.memory24.max_base_address = temp16; /* * Get Alignment (Bytes 8-9) */ - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); buffer += 2; output_struct->data.memory24.alignment = temp16; /* - * Get Range_length (Bytes 10-11) + * Get range_length (Bytes 10-11) */ - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); output_struct->data.memory24.range_length = temp16; /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -129,13 +146,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_memory24_stream + * FUNCTION: acpi_rs_memory24_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -146,16 +162,16 @@ acpi_status acpi_rs_memory24_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; - FUNCTION_TRACE ("Rs_memory24_stream"); + ACPI_FUNCTION_TRACE ("rs_memory24_stream"); /* @@ -168,7 +184,7 @@ * The length field is static */ temp16 = 0x09; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -181,72 +197,71 @@ /* * Set the Range minimum base address */ - MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.memory24.min_base_address); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.min_base_address); buffer += 2; /* * Set the Range maximum base address */ - MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.memory24.max_base_address); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.max_base_address); buffer += 2; /* * Set the base alignment */ - MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.memory24.alignment); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.alignment); buffer += 2; /* * Set the range length */ - MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.memory24.range_length); + ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.range_length); buffer += 2; /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_memory32_range_resource + * FUNCTION: acpi_rs_memory32_range_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_memory32_range_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_mem32); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32); - FUNCTION_TRACE ("Rs_memory32_range_resource"); + ACPI_FUNCTION_TRACE ("rs_memory32_range_resource"); /* @@ -254,19 +269,19 @@ */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); buffer += 2; - *bytes_consumed = temp16 + 3; + *bytes_consumed = (acpi_size) temp16 + 3; output_struct->id = ACPI_RSTYPE_MEM32; /* * Point to the place in the output buffer where the data portion will * begin. - * 1. Set the RESOURCE_DATA * Data to point to it's own address, then + * 1. Set the RESOURCE_DATA * Data to point to its own address, then * 2. Set the pointer to the next address. * - * NOTE: Output_struct->Data is cast to u8, otherwise, this addition adds + * NOTE: output_struct->Data is cast to u8, otherwise, this addition adds * 4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8) */ @@ -279,34 +294,32 @@ output_struct->data.memory32.read_write_attribute = temp8 & 0x01; /* - * Get Min_base_address (Bytes 4-7) + * Get min_base_address (Bytes 4-7) */ - MOVE_UNALIGNED32_TO_32 (&output_struct->data.memory32.min_base_address, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.min_base_address, buffer); buffer += 4; /* - * Get Max_base_address (Bytes 8-11) + * Get max_base_address (Bytes 8-11) */ - MOVE_UNALIGNED32_TO_32 (&output_struct->data.memory32.max_base_address, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.max_base_address, buffer); buffer += 4; /* * Get Alignment (Bytes 12-15) */ - MOVE_UNALIGNED32_TO_32 (&output_struct->data.memory32.alignment, buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.alignment, buffer); buffer += 4; /* - * Get Range_length (Bytes 16-19) + * Get range_length (Bytes 16-19) */ - MOVE_UNALIGNED32_TO_32 (&output_struct->data.memory32.range_length, buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.range_length, buffer); /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -318,51 +331,50 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_fixed_memory32_resource + * FUNCTION: acpi_rs_fixed_memory32_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_fixed_memory32_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_fixed_mem32); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32); - FUNCTION_TRACE ("Rs_fixed_memory32_resource"); + ACPI_FUNCTION_TRACE ("rs_fixed_memory32_resource"); /* * Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); buffer += 2; - *bytes_consumed = temp16 + 3; + *bytes_consumed = (acpi_size) temp16 + 3; output_struct->id = ACPI_RSTYPE_FIXED_MEM32; @@ -374,22 +386,20 @@ output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01; /* - * Get Range_base_address (Bytes 4-7) + * Get range_base_address (Bytes 4-7) */ - MOVE_UNALIGNED32_TO_32 (&output_struct->data.fixed_memory32.range_base_address, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address, buffer); buffer += 4; /* - * Get Range_length (Bytes 8-11) + * Get range_length (Bytes 8-11) */ - MOVE_UNALIGNED32_TO_32 (&output_struct->data.fixed_memory32.range_length, - buffer); + ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_length, buffer); /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -401,13 +411,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_memory32_range_stream + * FUNCTION: acpi_rs_memory32_range_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -418,16 +427,16 @@ acpi_status acpi_rs_memory32_range_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; - FUNCTION_TRACE ("Rs_memory32_range_stream"); + ACPI_FUNCTION_TRACE ("rs_memory32_range_stream"); /* @@ -441,7 +450,7 @@ */ temp16 = 0x11; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -454,44 +463,43 @@ /* * Set the Range minimum base address */ - MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.memory32.min_base_address); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.min_base_address); buffer += 4; /* * Set the Range maximum base address */ - MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.memory32.max_base_address); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.max_base_address); buffer += 4; /* * Set the base alignment */ - MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.memory32.alignment); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.alignment); buffer += 4; /* * Set the range length */ - MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.memory32.range_length); + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.range_length); buffer += 4; /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_fixed_memory32_stream + * FUNCTION: acpi_rs_fixed_memory32_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -502,16 +510,16 @@ acpi_status acpi_rs_fixed_memory32_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; - FUNCTION_TRACE ("Rs_fixed_memory32_stream"); + ACPI_FUNCTION_TRACE ("rs_fixed_memory32_stream"); /* @@ -525,7 +533,7 @@ */ temp16 = 0x09; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -538,21 +546,21 @@ /* * Set the Range base address */ - MOVE_UNALIGNED32_TO_32 (buffer, + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.fixed_memory32.range_base_address); buffer += 4; /* * Set the range length */ - MOVE_UNALIGNED32_TO_32 (buffer, + ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.fixed_memory32.range_length); buffer += 4; /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/resources/rsmisc.c linux-2.4.22/drivers/acpi/resources/rsmisc.c --- linux-2.4.21/drivers/acpi/resources/rsmisc.c 2001-09-23 09:42:32.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsmisc.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,70 +1,87 @@ /******************************************************************************* * * Module Name: rsmisc - Miscellaneous resource descriptors - * $Revision: 16 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsmisc") + ACPI_MODULE_NAME ("rsmisc") /******************************************************************************* * - * FUNCTION: Acpi_rs_end_tag_resource + * FUNCTION: acpi_rs_end_tag_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_end_tag_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u32 struct_size = ACPI_RESOURCE_LENGTH; + struct acpi_resource *output_struct = (void *) *output_buffer; + acpi_size struct_size = ACPI_RESOURCE_LENGTH; - FUNCTION_TRACE ("Rs_end_tag_resource"); + ACPI_FUNCTION_TRACE ("rs_end_tag_resource"); /* @@ -92,13 +109,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_end_tag_stream + * FUNCTION: acpi_rs_end_tag_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -109,15 +125,15 @@ acpi_status acpi_rs_end_tag_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u8 temp8 = 0; + u8 *buffer = *output_buffer; + u8 temp8 = 0; - FUNCTION_TRACE ("Rs_end_tag_stream"); + ACPI_FUNCTION_TRACE ("rs_end_tag_stream"); /* @@ -138,49 +154,48 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_vendor_resource + * FUNCTION: acpi_rs_vendor_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status acpi_rs_vendor_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_vendor); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + u8 index; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor); - FUNCTION_TRACE ("Rs_vendor_resource"); + ACPI_FUNCTION_TRACE ("rs_vendor_resource"); /* @@ -190,34 +205,31 @@ if (temp8 & 0x80) { /* - * Large Item - * Point to the length field + * Large Item, point to the length field */ buffer += 1; /* Dereference */ - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); + ACPI_MOVE_16_TO_16 (&temp16, buffer); /* Calculate bytes consumed */ - *bytes_consumed = temp16 + 3; + *bytes_consumed = (acpi_size) temp16 + 3; /* Point to the first vendor byte */ buffer += 2; } - else { /* - * Small Item - * Dereference the size + * Small Item, dereference the size */ temp16 = (u8)(*buffer & 0x07); /* Calculate bytes consumed */ - *bytes_consumed = temp16 + 1; + *bytes_consumed = (acpi_size) temp16 + 1; /* Point to the first vendor byte */ @@ -233,16 +245,16 @@ } /* - * In order for the Struct_size to fall on a 32-bit boundary, + * In order for the struct_size to fall on a 32-bit boundary, * calculate the length of the vendor string and expand the - * Struct_size to the next 32-bit boundary. + * struct_size to the next 32-bit boundary. */ - struct_size += ROUND_UP_TO_32_bITS (temp16); + struct_size += ACPI_ROUND_UP_to_32_bITS (temp16); /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -254,13 +266,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_vendor_stream + * FUNCTION: acpi_rs_vendor_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -271,17 +282,17 @@ acpi_status acpi_rs_vendor_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; + u8 *buffer = *output_buffer; + u16 temp16 = 0; + u8 temp8 = 0; + u8 index; - FUNCTION_TRACE ("Rs_vendor_stream"); + ACPI_FUNCTION_TRACE ("rs_vendor_stream"); /* @@ -289,25 +300,22 @@ */ if(linked_list->data.vendor_specific.length > 7) { /* - * Large Item - * Set the descriptor field and length bytes + * Large Item, Set the descriptor field and length bytes */ *buffer = 0x84; buffer += 1; temp16 = (u16) linked_list->data.vendor_specific.length; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); + ACPI_MOVE_16_TO_16 (buffer, &temp16); buffer += 2; } - else { /* - * Small Item - * Set the descriptor field + * Small Item, Set the descriptor field */ temp8 = 0x70; - temp8 |= linked_list->data.vendor_specific.length; + temp8 |= (u8) linked_list->data.vendor_specific.length; *buffer = temp8; buffer += 1; @@ -326,47 +334,46 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_start_dependent_functions_resource + * FUNCTION: acpi_rs_start_depend_fns_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status -acpi_rs_start_dependent_functions_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) +acpi_rs_start_depend_fns_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - u8 *buffer = byte_stream_buffer; - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u8 temp8 = 0; - u32 struct_size = SIZEOF_RESOURCE (acpi_resource_start_dpf); + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *) *output_buffer; + u8 temp8 = 0; + acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf); - FUNCTION_TRACE ("Rs_start_dependent_functions_resource"); + ACPI_FUNCTION_TRACE ("rs_start_depend_fns_resource"); /* @@ -391,7 +398,7 @@ output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03; if (3 == output_struct->data.start_dpf.compatibility_priority) { - return_ACPI_STATUS (AE_AML_ERROR); + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE); } /* @@ -400,22 +407,21 @@ output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03; if (3 == output_struct->data.start_dpf.performance_robustness) { - return_ACPI_STATUS (AE_AML_ERROR); + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE); } } - else { output_struct->data.start_dpf.compatibility_priority = - ACCEPTABLE_CONFIGURATION; + ACPI_ACCEPTABLE_CONFIGURATION; output_struct->data.start_dpf.performance_robustness = - ACCEPTABLE_CONFIGURATION; + ACPI_ACCEPTABLE_CONFIGURATION; } /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -427,38 +433,37 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_end_dependent_functions_resource + * FUNCTION: acpi_rs_end_depend_fns_resource * - * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes consumed from - * the Byte_stream_buffer - * Output_buffer - Pointer to the user's return buffer - * Structure_size - u32 pointer that is filled with - * the number of bytes in the filled - * in structure + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned * * RETURN: Status * * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the Output_buffer. Return the + * structure pointed to by the output_buffer. Return the * number of bytes consumed from the byte stream. * ******************************************************************************/ acpi_status -acpi_rs_end_dependent_functions_resource ( - u8 *byte_stream_buffer, - u32 *bytes_consumed, - u8 **output_buffer, - u32 *structure_size) +acpi_rs_end_depend_fns_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size) { - acpi_resource *output_struct = (acpi_resource *) *output_buffer; - u32 struct_size = ACPI_RESOURCE_LENGTH; + struct acpi_resource *output_struct = (void *) *output_buffer; + acpi_size struct_size = ACPI_RESOURCE_LENGTH; - FUNCTION_TRACE ("Rs_end_dependent_functions_resource"); + ACPI_FUNCTION_TRACE ("rs_end_depend_fns_resource"); /* @@ -474,7 +479,7 @@ /* * Set the Length parameter */ - output_struct->length = struct_size; + output_struct->length = (u32) struct_size; /* * Return the final size of the structure @@ -486,13 +491,13 @@ /******************************************************************************* * - * FUNCTION: Acpi_rs_start_dependent_functions_stream + * FUNCTION: acpi_rs_start_depend_fns_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - u32 pointer that is filled with * the number of bytes of the - * Output_buffer used + * output_buffer used * * RETURN: Status * @@ -502,25 +507,25 @@ ******************************************************************************/ acpi_status -acpi_rs_start_dependent_functions_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed) +acpi_rs_start_depend_fns_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; - u8 temp8 = 0; + u8 *buffer = *output_buffer; + u8 temp8 = 0; - FUNCTION_TRACE ("Rs_start_dependent_functions_stream"); + ACPI_FUNCTION_TRACE ("rs_start_depend_fns_stream"); /* * The descriptor field is set based upon whether a byte is needed * to contain Priority data. */ - if (ACCEPTABLE_CONFIGURATION == + if (ACPI_ACCEPTABLE_CONFIGURATION == linked_list->data.start_dpf.compatibility_priority && - ACCEPTABLE_CONFIGURATION == + ACPI_ACCEPTABLE_CONFIGURATION == linked_list->data.start_dpf.performance_robustness) { *buffer = 0x30; } @@ -544,20 +549,19 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_rs_end_dependent_functions_stream + * FUNCTION: acpi_rs_end_depend_fns_stream * - * PARAMETERS: Linked_list - Pointer to the resource linked list - * Output_buffer - Pointer to the user's return buffer - * Bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * Output_buffer used + * PARAMETERS: linked_list - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned * * RETURN: Status * @@ -567,16 +571,15 @@ ******************************************************************************/ acpi_status -acpi_rs_end_dependent_functions_stream ( - acpi_resource *linked_list, - u8 **output_buffer, - u32 *bytes_consumed - ) +acpi_rs_end_depend_fns_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed) { - u8 *buffer = *output_buffer; + u8 *buffer = *output_buffer; - FUNCTION_TRACE ("Rs_end_dependent_functions_stream"); + ACPI_FUNCTION_TRACE ("rs_end_depend_fns_stream"); /* @@ -588,7 +591,7 @@ /* * Return the number of bytes consumed in this operation */ - *bytes_consumed = POINTER_DIFF (buffer, *output_buffer); + *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/resources/rsutils.c linux-2.4.22/drivers/acpi/resources/rsutils.c --- linux-2.4.21/drivers/acpi/resources/rsutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsutils.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,44 +1,62 @@ /******************************************************************************* * * Module Name: rsutils - Utilities for the resource manager - * $Revision: 23 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "acresrc.h" +#include +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsutils") + ACPI_MODULE_NAME ("rsutils") /******************************************************************************* * - * FUNCTION: Acpi_rs_get_prt_method_data + * FUNCTION: acpi_rs_get_prt_method_data * * PARAMETERS: Handle - a handle to the containing object - * Ret_buffer - a pointer to a buffer structure for the + * ret_buffer - a pointer to a buffer structure for the * results * * RETURN: Status @@ -53,78 +71,45 @@ acpi_status acpi_rs_get_prt_method_data ( - acpi_handle handle, - acpi_buffer *ret_buffer) + acpi_handle handle, + struct acpi_buffer *ret_buffer) { - acpi_operand_object *ret_obj; - acpi_status status; - u32 buffer_space_needed; + union acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE ("Rs_get_prt_method_data"); + ACPI_FUNCTION_TRACE ("rs_get_prt_method_data"); - /* already validated params, so we won't repeat here */ - - buffer_space_needed = ret_buffer->length; + /* Parameters guaranteed valid by caller */ /* - * Execute the method, no parameters + * Execute the method, no parameters */ - status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &ret_obj); + status = acpi_ut_evaluate_object (handle, "_PRT", ACPI_BTYPE_PACKAGE, &obj_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - if (!ret_obj) { - /* Return object is required */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRT\n")); - return_ACPI_STATUS (AE_TYPE); - } - - - /* - * The return object will be a package, so check the - * parameters. If the return object is not a package, - * then the underlying AML code is corrupt or improperly - * written. - */ - if (ACPI_TYPE_PACKAGE != ret_obj->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - /* - * Make the call to create a resource linked list from the - * byte stream buffer that comes back from the _CRS method - * execution. - */ - status = acpi_rs_create_pci_routing_table (ret_obj, ret_buffer->pointer, - &buffer_space_needed); - /* - * Tell the user how much of the buffer we have used or is needed - * and return the final status. + * Create a resource linked list from the byte stream buffer that comes + * back from the _CRS method execution. */ - ret_buffer->length = buffer_space_needed; - + status = acpi_rs_create_pci_routing_table (obj_desc, ret_buffer); /* On exit, we must delete the object returned by evaluate_object */ -cleanup: - - acpi_ut_remove_reference (ret_obj); + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_rs_get_crs_method_data + * FUNCTION: acpi_rs_get_crs_method_data * * PARAMETERS: Handle - a handle to the containing object - * Ret_buffer - a pointer to a buffer structure for the + * ret_buffer - a pointer to a buffer structure for the * results * * RETURN: Status @@ -139,76 +124,46 @@ acpi_status acpi_rs_get_crs_method_data ( - acpi_handle handle, - acpi_buffer *ret_buffer) + acpi_handle handle, + struct acpi_buffer *ret_buffer) { - acpi_operand_object *ret_obj; - acpi_status status; - u32 buffer_space_needed = ret_buffer->length; + union acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE ("Rs_get_crs_method_data"); + ACPI_FUNCTION_TRACE ("rs_get_crs_method_data"); - /* already validated params, so we won't repeat here */ + /* Parameters guaranteed valid by caller */ /* - * Execute the method, no parameters + * Execute the method, no parameters */ - status = acpi_ns_evaluate_relative (handle, "_CRS", NULL, &ret_obj); + status = acpi_ut_evaluate_object (handle, "_CRS", ACPI_BTYPE_BUFFER, &obj_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - if (!ret_obj) { - /* Return object is required */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _CRS\n")); - return_ACPI_STATUS (AE_TYPE); - } - - /* - * The return object will be a buffer, but check the - * parameters. If the return object is not a buffer, - * then the underlying AML code is corrupt or improperly - * written. - */ - if (ACPI_TYPE_BUFFER != ret_obj->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - /* * Make the call to create a resource linked list from the - * byte stream buffer that comes back from the _CRS method - * execution. + * byte stream buffer that comes back from the _CRS method + * execution. */ - status = acpi_rs_create_resource_list (ret_obj, ret_buffer->pointer, - &buffer_space_needed); + status = acpi_rs_create_resource_list (obj_desc, ret_buffer); + /* on exit, we must delete the object returned by evaluate_object */ - /* - * Tell the user how much of the buffer we have used or is needed - * and return the final status. - */ - ret_buffer->length = buffer_space_needed; - - - /* On exit, we must delete the object returned by evaluate_object */ - -cleanup: - - acpi_ut_remove_reference (ret_obj); + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_rs_get_prs_method_data + * FUNCTION: acpi_rs_get_prs_method_data * * PARAMETERS: Handle - a handle to the containing object - * Ret_buffer - a pointer to a buffer structure for the + * ret_buffer - a pointer to a buffer structure for the * results * * RETURN: Status @@ -223,75 +178,100 @@ acpi_status acpi_rs_get_prs_method_data ( - acpi_handle handle, - acpi_buffer *ret_buffer) + acpi_handle handle, + struct acpi_buffer *ret_buffer) { - acpi_operand_object *ret_obj; - acpi_status status; - u32 buffer_space_needed = ret_buffer->length; + union acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE ("Rs_get_prs_method_data"); + ACPI_FUNCTION_TRACE ("rs_get_prs_method_data"); - /* already validated params, so we won't repeat here */ + /* Parameters guaranteed valid by caller */ /* - * Execute the method, no parameters + * Execute the method, no parameters */ - status = acpi_ns_evaluate_relative (handle, "_PRS", NULL, &ret_obj); + status = acpi_ut_evaluate_object (handle, "_PRS", ACPI_BTYPE_BUFFER, &obj_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - if (!ret_obj) { - /* Return object is required */ + /* + * Make the call to create a resource linked list from the + * byte stream buffer that comes back from the _CRS method + * execution. + */ + status = acpi_rs_create_resource_list (obj_desc, ret_buffer); - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRS\n")); - return_ACPI_STATUS (AE_TYPE); - } + /* on exit, we must delete the object returned by evaluate_object */ + + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); +} - /* - * The return object will be a buffer, but check the - * parameters. If the return object is not a buffer, - * then the underlying AML code is corrupt or improperly - * written.. - */ - if (ACPI_TYPE_BUFFER != ret_obj->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_method_data + * + * PARAMETERS: Handle - a handle to the containing object + * ret_buffer - a pointer to a buffer structure for the + * results + * + * RETURN: Status + * + * DESCRIPTION: This function is called to get the _CRS or _PRS value of an + * object contained in an object specified by the handle passed in + * + * If the function fails an appropriate status will be returned + * and the contents of the callers buffer is undefined. + * + ******************************************************************************/ + +acpi_status +acpi_rs_get_method_data ( + acpi_handle handle, + char *path, + struct acpi_buffer *ret_buffer) +{ + union acpi_operand_object *obj_desc; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("rs_get_method_data"); + + + /* Parameters guaranteed valid by caller */ /* - * Make the call to create a resource linked list from the - * byte stream buffer that comes back from the _CRS method - * execution. + * Execute the method, no parameters */ - status = acpi_rs_create_resource_list (ret_obj, ret_buffer->pointer, - &buffer_space_needed); + status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* - * Tell the user how much of the buffer we have used or is needed - * and return the final status. + * Make the call to create a resource linked list from the + * byte stream buffer that comes back from the method + * execution. */ - ret_buffer->length = buffer_space_needed; - + status = acpi_rs_create_resource_list (obj_desc, ret_buffer); /* On exit, we must delete the object returned by evaluate_object */ -cleanup: - - acpi_ut_remove_reference (ret_obj); + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } - /******************************************************************************* * - * FUNCTION: Acpi_rs_set_srs_method_data + * FUNCTION: acpi_rs_set_srs_method_data * * PARAMETERS: Handle - a handle to the containing object - * In_buffer - a pointer to a buffer structure of the + * in_buffer - a pointer to a buffer structure of the * parameter * * RETURN: Status @@ -306,55 +286,30 @@ acpi_status acpi_rs_set_srs_method_data ( - acpi_handle handle, - acpi_buffer *in_buffer) + acpi_handle handle, + struct acpi_buffer *in_buffer) { - acpi_operand_object *params[2]; - acpi_status status; - u8 *byte_stream = NULL; - u32 buffer_size_needed = 0; + union acpi_operand_object *params[2]; + acpi_status status; + struct acpi_buffer buffer; - FUNCTION_TRACE ("Rs_set_srs_method_data"); + ACPI_FUNCTION_TRACE ("rs_set_srs_method_data"); - /* already validated params, so we won't repeat here */ + /* Parameters guaranteed valid by caller */ /* - * The In_buffer parameter will point to a linked list of + * The in_buffer parameter will point to a linked list of * resource parameters. It needs to be formatted into a - * byte stream to be sent in as an input parameter. - */ - buffer_size_needed = 0; - - /* - * First call is to get the buffer size needed - */ - status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, - &buffer_size_needed); - /* - * We expect a return of AE_BUFFER_OVERFLOW - * if not, exit with the error - */ - if (AE_BUFFER_OVERFLOW != status) { - return_ACPI_STATUS (status); - } - - /* - * Allocate the buffer needed + * byte stream to be sent in as an input parameter to _SRS + * + * Convert the linked list into a byte stream */ - byte_stream = ACPI_MEM_CALLOCATE (buffer_size_needed); - if (NULL == byte_stream) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* - * Now call to convert the linked list into a byte stream - */ - status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, - &buffer_size_needed); + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_rs_create_byte_stream (in_buffer->pointer, &buffer); if (ACPI_FAILURE (status)) { - goto cleanup; + return_ACPI_STATUS (status); } /* @@ -362,28 +317,27 @@ */ params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); if (!params[0]) { - status = AE_NO_MEMORY; - goto cleanup; + acpi_os_free (buffer.pointer); + return_ACPI_STATUS (AE_NO_MEMORY); } - params [1] = NULL; /* - * Set up the parameter object + * Set up the parameter object */ - params[0]->buffer.length = buffer_size_needed; - params[0]->buffer.pointer = byte_stream; + params[0]->buffer.length = (u32) buffer.length; + params[0]->buffer.pointer = buffer.pointer; + params[0]->common.flags = AOPOBJ_DATA_VALID; + params[1] = NULL; /* * Execute the method, no return value */ status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL); - acpi_ut_remove_reference (params[0]); /* - * Clean up and return the status from Acpi_ns_evaluate_relative + * Clean up and return the status from acpi_ns_evaluate_relative */ -cleanup: - + acpi_ut_remove_reference (params[0]); return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/resources/rsxface.c linux-2.4.22/drivers/acpi/resources/rsxface.c --- linux-2.4.21/drivers/acpi/resources/rsxface.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/resources/rsxface.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,44 +1,60 @@ /******************************************************************************* * * Module Name: rsxface - Public interfaces to the resource manager - * $Revision: 15 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acresrc.h" +#include +#include #define _COMPONENT ACPI_RESOURCES - MODULE_NAME ("rsxface") + ACPI_MODULE_NAME ("rsxface") /******************************************************************************* * - * FUNCTION: Acpi_get_irq_routing_table + * FUNCTION: acpi_get_irq_routing_table * - * PARAMETERS: Device_handle - a handle to the Bus device we are querying - * Ret_buffer - a pointer to a buffer to receive the + * PARAMETERS: device_handle - a handle to the Bus device we are querying + * ret_buffer - a pointer to a buffer to receive the * current resources for the device * * RETURN: Status @@ -46,25 +62,25 @@ * DESCRIPTION: This function is called to get the IRQ routing table for a * specific bus. The caller must first acquire a handle for the * desired bus. The routine table is placed in the buffer pointed - * to by the Ret_buffer variable parameter. + * to by the ret_buffer variable parameter. * * If the function fails an appropriate status will be returned - * and the value of Ret_buffer is undefined. + * and the value of ret_buffer is undefined. * * This function attempts to execute the _PRT method contained in - * the object indicated by the passed Device_handle. + * the object indicated by the passed device_handle. * ******************************************************************************/ acpi_status acpi_get_irq_routing_table ( - acpi_handle device_handle, - acpi_buffer *ret_buffer) + acpi_handle device_handle, + struct acpi_buffer *ret_buffer) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Acpi_get_irq_routing_table "); + ACPI_FUNCTION_TRACE ("acpi_get_irq_routing_table "); /* @@ -73,12 +89,15 @@ * we also need a valid pointer in the buffer. If it's a zero buffer length, * we'll be returning the needed buffer size, so keep going. */ - if ((!device_handle) || - (!ret_buffer) || - ((!ret_buffer->pointer) && (ret_buffer->length))) { + if (!device_handle) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_ut_validate_buffer (ret_buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + status = acpi_rs_get_prt_method_data (device_handle, ret_buffer); return_ACPI_STATUS (status); } @@ -86,11 +105,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_get_current_resources + * FUNCTION: acpi_get_current_resources * - * PARAMETERS: Device_handle - a handle to the device object for the + * PARAMETERS: device_handle - a handle to the device object for the * device we are querying - * Ret_buffer - a pointer to a buffer to receive the + * ret_buffer - a pointer to a buffer to receive the * current resources for the device * * RETURN: Status @@ -98,25 +117,25 @@ * DESCRIPTION: This function is called to get the current resources for a * specific device. The caller must first acquire a handle for * the desired device. The resource data is placed in the buffer - * pointed to by the Ret_buffer variable parameter. + * pointed to by the ret_buffer variable parameter. * * If the function fails an appropriate status will be returned - * and the value of Ret_buffer is undefined. + * and the value of ret_buffer is undefined. * * This function attempts to execute the _CRS method contained in - * the object indicated by the passed Device_handle. + * the object indicated by the passed device_handle. * ******************************************************************************/ acpi_status acpi_get_current_resources ( - acpi_handle device_handle, - acpi_buffer *ret_buffer) + acpi_handle device_handle, + struct acpi_buffer *ret_buffer) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Acpi_get_current_resources"); + ACPI_FUNCTION_TRACE ("acpi_get_current_resources"); /* @@ -125,12 +144,15 @@ * we also need a valid pointer in the buffer. If it's a zero buffer length, * we'll be returning the needed buffer size, so keep going. */ - if ((!device_handle) || - (!ret_buffer) || - ((ret_buffer->length) && (!ret_buffer->pointer))) { + if (!device_handle) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_ut_validate_buffer (ret_buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + status = acpi_rs_get_crs_method_data (device_handle, ret_buffer); return_ACPI_STATUS (status); } @@ -138,11 +160,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_get_possible_resources + * FUNCTION: acpi_get_possible_resources * - * PARAMETERS: Device_handle - a handle to the device object for the + * PARAMETERS: device_handle - a handle to the device object for the * device we are querying - * Ret_buffer - a pointer to a buffer to receive the + * ret_buffer - a pointer to a buffer to receive the * resources for the device * * RETURN: Status @@ -150,22 +172,22 @@ * DESCRIPTION: This function is called to get a list of the possible resources * for a specific device. The caller must first acquire a handle * for the desired device. The resource data is placed in the - * buffer pointed to by the Ret_buffer variable. + * buffer pointed to by the ret_buffer variable. * * If the function fails an appropriate status will be returned - * and the value of Ret_buffer is undefined. + * and the value of ret_buffer is undefined. * ******************************************************************************/ acpi_status acpi_get_possible_resources ( - acpi_handle device_handle, - acpi_buffer *ret_buffer) + acpi_handle device_handle, + struct acpi_buffer *ret_buffer) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Acpi_get_possible_resources"); + ACPI_FUNCTION_TRACE ("acpi_get_possible_resources"); /* @@ -174,12 +196,15 @@ * we also need a valid pointer in the buffer. If it's a zero buffer length, * we'll be returning the needed buffer size, so keep going. */ - if ((!device_handle) || - (!ret_buffer) || - ((ret_buffer->length) && (!ret_buffer->pointer))) { + if (!device_handle) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_ut_validate_buffer (ret_buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + status = acpi_rs_get_prs_method_data (device_handle, ret_buffer); return_ACPI_STATUS (status); } @@ -187,11 +212,96 @@ /******************************************************************************* * - * FUNCTION: Acpi_set_current_resources + * FUNCTION: acpi_walk_resources + * + * PARAMETERS: device_handle - a handle to the device object for the + * device we are querying + * Path - method name of the resources we want + * (METHOD_NAME__CRS or METHOD_NAME__PRS) + * user_function - called for each resource + * Context - passed to user_function + * + * RETURN: Status + * + * DESCRIPTION: Retrieves the current or possible resource list for the + * specified device. The user_function is called once for + * each resource in the list. * - * PARAMETERS: Device_handle - a handle to the device object for the + ******************************************************************************/ + +acpi_status +acpi_walk_resources ( + acpi_handle device_handle, + char *path, + ACPI_WALK_RESOURCE_CALLBACK user_function, + void *context) +{ + acpi_status status; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_resource *resource; + + + ACPI_FUNCTION_TRACE ("acpi_walk_resources"); + + + if (!device_handle || + (ACPI_STRNCMP (path, METHOD_NAME__CRS, sizeof (METHOD_NAME__CRS)) && + ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + status = acpi_rs_get_method_data (device_handle, path, &buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + resource = (struct acpi_resource *) buffer.pointer; + for (;;) { + if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { + break; + } + + status = user_function (resource, context); + + switch (status) { + case AE_OK: + case AE_CTRL_DEPTH: + + /* Just keep going */ + status = AE_OK; + break; + + case AE_CTRL_TERMINATE: + + /* Exit now, with OK stats */ + + status = AE_OK; + goto cleanup; + + default: + + /* All others are valid exceptions */ + + goto cleanup; + } + + resource = ACPI_NEXT_RESOURCE (resource); + } + +cleanup: + + acpi_os_free (buffer.pointer); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_set_current_resources + * + * PARAMETERS: device_handle - a handle to the device object for the * device we are changing the resources of - * In_buffer - a pointer to a buffer containing the + * in_buffer - a pointer to a buffer containing the * resources to be set for the device * * RETURN: Status @@ -199,19 +309,19 @@ * DESCRIPTION: This function is called to set the current resources for a * specific device. The caller must first acquire a handle for * the desired device. The resource data is passed to the routine - * the buffer pointed to by the In_buffer variable. + * the buffer pointed to by the in_buffer variable. * ******************************************************************************/ acpi_status acpi_set_current_resources ( - acpi_handle device_handle, - acpi_buffer *in_buffer) + acpi_handle device_handle, + struct acpi_buffer *in_buffer) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Acpi_set_current_resources"); + ACPI_FUNCTION_TRACE ("acpi_set_current_resources"); /* @@ -227,3 +337,76 @@ status = acpi_rs_set_srs_method_data (device_handle, in_buffer); return_ACPI_STATUS (status); } + + +#define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field) +#define ACPI_COPY_ADDRESS(out, in) \ + ACPI_COPY_FIELD(out, in, resource_type); \ + ACPI_COPY_FIELD(out, in, producer_consumer); \ + ACPI_COPY_FIELD(out, in, decode); \ + ACPI_COPY_FIELD(out, in, min_address_fixed); \ + ACPI_COPY_FIELD(out, in, max_address_fixed); \ + ACPI_COPY_FIELD(out, in, attribute); \ + ACPI_COPY_FIELD(out, in, granularity); \ + ACPI_COPY_FIELD(out, in, min_address_range); \ + ACPI_COPY_FIELD(out, in, max_address_range); \ + ACPI_COPY_FIELD(out, in, address_translation_offset); \ + ACPI_COPY_FIELD(out, in, address_length); \ + ACPI_COPY_FIELD(out, in, resource_source); + +/****************************************************************************** + * + * FUNCTION: acpi_resource_to_address64 + * + * PARAMETERS: resource - Pointer to a resource + * out - Pointer to the users's return + * buffer (a struct + * struct acpi_resource_address64) + * + * RETURN: Status + * + * DESCRIPTION: If the resource is an address16, address32, or address64, + * copy it to the address64 return buffer. This saves the + * caller from having to duplicate code for different-sized + * addresses. + * + ******************************************************************************/ + +acpi_status +acpi_resource_to_address64 ( + struct acpi_resource *resource, + struct acpi_resource_address64 *out) +{ + struct acpi_resource_address16 *address16; + struct acpi_resource_address32 *address32; + + + switch (resource->id) { + case ACPI_RSTYPE_ADDRESS16: + + address16 = (struct acpi_resource_address16 *) &resource->data; + ACPI_COPY_ADDRESS(out, address16); + break; + + + case ACPI_RSTYPE_ADDRESS32: + + address32 = (struct acpi_resource_address32 *) &resource->data; + ACPI_COPY_ADDRESS(out, address32); + break; + + + case ACPI_RSTYPE_ADDRESS64: + + /* Simple copy for 64 bit source */ + + ACPI_MEMCPY (out, &resource->data, sizeof (struct acpi_resource_address64)); + break; + + + default: + return (AE_BAD_PARAMETER); + } + + return (AE_OK); +} diff -urN linux-2.4.21/drivers/acpi/system.c linux-2.4.22/drivers/acpi/system.c --- linux-2.4.21/drivers/acpi/system.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/system.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,1327 @@ +/* + * acpi_system.c - ACPI System Driver ($Revision: 57 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_X86 +#ifdef CONFIG_ACPI_SLEEP +#include +#include +#include +#endif +#endif + + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME ("acpi_system") + +#define PREFIX "ACPI: " + +extern FADT_DESCRIPTOR acpi_fadt; + +static int acpi_system_add (struct acpi_device *device); +static int acpi_system_remove (struct acpi_device *device, int type); + +acpi_status acpi_suspend (u32 state); + +static struct acpi_driver acpi_system_driver = { + .name = ACPI_SYSTEM_DRIVER_NAME, + .class = ACPI_SYSTEM_CLASS, + .ids = ACPI_SYSTEM_HID, + .ops = { + .add = acpi_system_add, + .remove = acpi_system_remove + }, +}; + +struct acpi_system +{ + acpi_handle handle; + u8 states[ACPI_S_STATE_COUNT]; +}; + +/* Global vars for handling event proc entry */ +static spinlock_t acpi_system_event_lock = SPIN_LOCK_UNLOCKED; +int event_is_open = 0; +extern struct list_head acpi_bus_event_list; +extern wait_queue_head_t acpi_bus_event_queue; + +/* -------------------------------------------------------------------------- + System Sleep + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_PM + +static void +acpi_power_off (void) +{ + acpi_suspend(ACPI_STATE_S5); +} + +#endif /*CONFIG_PM*/ + + +#ifdef CONFIG_ACPI_SLEEP + +/** + * acpi_system_restore_state - OS-specific restoration of state + * @state: sleep state we're exiting + * + * Note that if we're coming back from S4, the memory image should have + * already been loaded from the disk and is already in place. (Otherwise how + * else would we be here?). + */ +acpi_status +acpi_system_restore_state( + u32 state) +{ + /* + * We should only be here if we're coming back from STR or STD. + * And, in the case of the latter, the memory image should have already + * been loaded from disk. + */ + if (state > ACPI_STATE_S1) { + acpi_restore_state_mem(); + + /* Do _early_ resume for irqs. Required by + * ACPI specs. + */ + /* TBD: call arch dependant reinitialization of the + * interrupts. + */ +#ifdef CONFIG_X86 + init_8259A(0); +#endif + /* wait for power to come back */ + mdelay(1000); + + } + + /* Be really sure that irqs are disabled. */ + ACPI_DISABLE_IRQS(); + + /* Wait a little again, just in case... */ + mdelay(1000); + + /* enable interrupts once again */ + ACPI_ENABLE_IRQS(); + + /* turn all the devices back on */ + if (state > ACPI_STATE_S1) + pm_send_all(PM_RESUME, (void *)0); + + return AE_OK; +} + + +/** + * acpi_system_save_state - save OS specific state and power down devices + * @state: sleep state we're entering. + * + * This handles saving all context to memory, and possibly disk. + * First, we call to the device driver layer to save device state. + * Once we have that, we save whatevery processor and kernel state we + * need to memory. + * If we're entering S4, we then write the memory image to disk. + * + * Only then it is safe for us to power down devices, since we may need + * the disks and upstream buses to write to. + */ +acpi_status +acpi_system_save_state( + u32 state) +{ + int error = 0; + + /* Send notification to devices that they will be suspended. + * If any device or driver cannot make the transition, either up + * or down, we'll get an error back. + */ + if (state > ACPI_STATE_S1) { + error = pm_send_all(PM_SAVE_STATE, (void *)3); + if (error) + return AE_ERROR; + } + + if (state <= ACPI_STATE_S5) { + /* Tell devices to stop I/O and actually save their state. + * It is theoretically possible that something could fail, + * so handle that gracefully.. + */ + if (state > ACPI_STATE_S1 && state != ACPI_STATE_S5) { + error = pm_send_all(PM_SUSPEND, (void *)3); + if (error) { + /* Tell devices to restore state if they have + * it saved and to start taking I/O requests. + */ + pm_send_all(PM_RESUME, (void *)0); + return error; + } + } + + /* flush caches */ + ACPI_FLUSH_CPU_CACHE(); + + /* Do arch specific saving of state. */ + if (state > ACPI_STATE_S1) { + error = acpi_save_state_mem(); + + /* TBD: if no s4bios, write codes for + * acpi_save_state_disk()... + */ +#if 0 + if (!error && (state == ACPI_STATE_S4)) + error = acpi_save_state_disk(); +#endif + if (error) { + pm_send_all(PM_RESUME, (void *)0); + return error; + } + } + } + /* disable interrupts + * Note that acpi_suspend -- our caller -- will do this once we return. + * But, we want it done early, so we don't get any suprises during + * the device suspend sequence. + */ + ACPI_DISABLE_IRQS(); + + /* Unconditionally turn off devices. + * Obvious if we enter a sleep state. + * If entering S5 (soft off), this should put devices in a + * quiescent state. + */ + + if (state > ACPI_STATE_S1) { + error = pm_send_all(PM_SUSPEND, (void *)3); + + /* We're pretty screwed if we got an error from this. + * We try to recover by simply calling our own restore_state + * function; see above for definition. + * + * If it's S5 though, go through with it anyway.. + */ + if (error && state != ACPI_STATE_S5) + acpi_system_restore_state(state); + } + return error ? AE_ERROR : AE_OK; +} + + +/**************************************************************************** + * + * FUNCTION: acpi_system_suspend + * + * PARAMETERS: %state: Sleep state to enter. + * + * RETURN: acpi_status, whether or not we successfully entered and + * exited sleep. + * + * DESCRIPTION: Perform OS-specific action to enter sleep state. + * This is the final step in going to sleep, per spec. If we + * know we're coming back (i.e. not entering S5), we save the + * processor flags. [ We'll have to save and restore them anyway, + * so we use the arch-agnostic save_flags and restore_flags + * here.] We then set the place to return to in arch-specific + * globals using arch_set_return_point. Finally, we call the + * ACPI function to write the proper values to I/O ports. + * + ****************************************************************************/ + +acpi_status +acpi_system_suspend( + u32 state) +{ + acpi_status status = AE_ERROR; + unsigned long flags = 0; + + local_irq_save(flags); + /* kernel_fpu_begin(); */ + + switch (state) { + case ACPI_STATE_S1: + case ACPI_STATE_S5: + barrier(); + status = acpi_enter_sleep_state(state); + break; + case ACPI_STATE_S4: + do_suspend_lowlevel_s4bios(0); + break; + } + + /* kernel_fpu_end(); */ + local_irq_restore(flags); + + return status; +} + + + +/** + * acpi_suspend - OS-agnostic system suspend/resume support (S? states) + * @state: state we're entering + * + */ +acpi_status +acpi_suspend ( + u32 state) +{ + acpi_status status; + + /* only support S1 and S5 on kernel 2.4 */ + if (state != ACPI_STATE_S1 && state != ACPI_STATE_S4 + && state != ACPI_STATE_S5) + return AE_ERROR; + + + if (ACPI_STATE_S4 == state) { + /* For s4bios, we need a wakeup address. */ + if (1 == acpi_gbl_FACS->S4bios_f && + 0 != acpi_gbl_FADT->smi_cmd) { + if (!acpi_wakeup_address) + return AE_ERROR; + acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address); + } else + /* We don't support S4 under 2.4. Give up */ + return AE_ERROR; + } + + status = acpi_system_save_state(state); + if (!ACPI_SUCCESS(status) && state != ACPI_STATE_S5) + return status; + + acpi_enter_sleep_state_prep(state); + + /* disable interrupts and flush caches */ + ACPI_DISABLE_IRQS(); + ACPI_FLUSH_CPU_CACHE(); + + /* perform OS-specific sleep actions */ + status = acpi_system_suspend(state); + + /* Even if we failed to go to sleep, all of the devices are in an suspended + * mode. So, we run these unconditionaly to make sure we have a usable system + * no matter what. + */ + acpi_leave_sleep_state(state); + acpi_system_restore_state(state); + + /* make sure interrupts are enabled */ + ACPI_ENABLE_IRQS(); + + /* reset firmware waking vector */ + acpi_set_firmware_waking_vector((acpi_physical_address) 0); + + return status; +} + +#endif /* CONFIG_ACPI_SLEEP */ + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +static int +acpi_system_read_info ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_system *system = (struct acpi_system *) data; + char *p = page; + int size = 0; + u32 i = 0; + + ACPI_FUNCTION_TRACE("acpi_system_read_info"); + + if (!system || (off != 0)) + goto end; + + p += sprintf(p, "version: %x\n", ACPI_CA_VERSION); + + p += sprintf(p, "states: "); + for (i=0; istates[i]) { + p += sprintf(p, "S%d ", i); + if (i == ACPI_STATE_S4 && + acpi_gbl_FACS->S4bios_f && + 0 != acpi_gbl_FADT->smi_cmd) + p += sprintf(p, "S4Bios "); + } + } + p += sprintf(p, "\n"); + +end: + size = (p - page); + if (size <= off+count) *eof = 1; + *start = page + off; + size -= off; + if (size>count) size = count; + if (size<0) size = 0; + + return_VALUE(size); +} + +static int acpi_system_open_event(struct inode *inode, struct file *file); +static ssize_t acpi_system_read_event (struct file*, char*, size_t, loff_t*); +static int acpi_system_close_event(struct inode *inode, struct file *file); +static unsigned int acpi_system_poll_event(struct file *file, poll_table *wait); + + +static struct file_operations acpi_system_event_ops = { + .open = acpi_system_open_event, + .read = acpi_system_read_event, + .release = acpi_system_close_event, + .poll = acpi_system_poll_event, +}; + +static int +acpi_system_open_event(struct inode *inode, struct file *file) +{ + spin_lock_irq (&acpi_system_event_lock); + + if(event_is_open) + goto out_busy; + + event_is_open = 1; + + spin_unlock_irq (&acpi_system_event_lock); + return 0; + +out_busy: + spin_unlock_irq (&acpi_system_event_lock); + return -EBUSY; +} + +static ssize_t +acpi_system_read_event ( + struct file *file, + char *buffer, + size_t count, + loff_t *ppos) +{ + int result = 0; + struct acpi_bus_event event; + static char str[ACPI_MAX_STRING]; + static int chars_remaining = 0; + static char *ptr; + + + ACPI_FUNCTION_TRACE("acpi_system_read_event"); + + if (!chars_remaining) { + memset(&event, 0, sizeof(struct acpi_bus_event)); + + if ((file->f_flags & O_NONBLOCK) + && (list_empty(&acpi_bus_event_list))) + return_VALUE(-EAGAIN); + + result = acpi_bus_receive_event(&event); + if (result) { + return_VALUE(-EIO); + } + + chars_remaining = sprintf(str, "%s %s %08x %08x\n", + event.device_class?event.device_class:"", + event.bus_id?event.bus_id:"", + event.type, event.data); + ptr = str; + } + + if (chars_remaining < count) { + count = chars_remaining; + } + + if (copy_to_user(buffer, ptr, count)) + return_VALUE(-EFAULT); + + *ppos += count; + chars_remaining -= count; + ptr += count; + + return_VALUE(count); +} + +static int +acpi_system_close_event(struct inode *inode, struct file *file) +{ + spin_lock_irq (&acpi_system_event_lock); + event_is_open = 0; + spin_unlock_irq (&acpi_system_event_lock); + return 0; +} + +static unsigned int +acpi_system_poll_event( + struct file *file, + poll_table *wait) +{ + poll_wait(file, &acpi_bus_event_queue, wait); + if (!list_empty(&acpi_bus_event_list)) + return POLLIN | POLLRDNORM; + return 0; +} + +static ssize_t acpi_system_read_dsdt (struct file*, char*, size_t, loff_t*); + +static struct file_operations acpi_system_dsdt_ops = { + .read = acpi_system_read_dsdt, +}; + +static ssize_t +acpi_system_read_dsdt ( + struct file *file, + char *buffer, + size_t count, + loff_t *ppos) +{ + acpi_status status = AE_OK; + struct acpi_buffer dsdt = {ACPI_ALLOCATE_BUFFER, NULL}; + void *data = 0; + size_t size = 0; + + ACPI_FUNCTION_TRACE("acpi_system_read_dsdt"); + + status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + if (*ppos < dsdt.length) { + data = dsdt.pointer + file->f_pos; + size = dsdt.length - file->f_pos; + if (size > count) + size = count; + if (copy_to_user(buffer, data, size)) { + acpi_os_free(dsdt.pointer); + return_VALUE(-EFAULT); + } + } + + acpi_os_free(dsdt.pointer); + + *ppos += size; + + return_VALUE(size); +} + + +static ssize_t acpi_system_read_fadt (struct file*, char*, size_t, loff_t*); + +static struct file_operations acpi_system_fadt_ops = { + .read = acpi_system_read_fadt, +}; + +static ssize_t +acpi_system_read_fadt ( + struct file *file, + char *buffer, + size_t count, + loff_t *ppos) +{ + acpi_status status = AE_OK; + struct acpi_buffer fadt = {ACPI_ALLOCATE_BUFFER, NULL}; + void *data = 0; + size_t size = 0; + + ACPI_FUNCTION_TRACE("acpi_system_read_fadt"); + + status = acpi_get_table(ACPI_TABLE_FADT, 1, &fadt); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + if (*ppos < fadt.length) { + data = fadt.pointer + file->f_pos; + size = fadt.length - file->f_pos; + if (size > count) + size = count; + if (copy_to_user(buffer, data, size)) { + acpi_os_free(fadt.pointer); + return_VALUE(-EFAULT); + } + } + + acpi_os_free(fadt.pointer); + + *ppos += size; + + return_VALUE(size); +} + + +#ifdef ACPI_DEBUG_OUTPUT + +static int +acpi_system_read_debug ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + char *p = page; + int size = 0; + + if (off != 0) + goto end; + + switch ((unsigned long) data) { + case 0: + p += sprintf(p, "0x%08x\n", acpi_dbg_layer); + break; + case 1: + p += sprintf(p, "0x%08x\n", acpi_dbg_level); + break; + default: + p += sprintf(p, "Invalid debug option\n"); + break; + } + +end: + size = (p - page); + if (size <= off+count) *eof = 1; + *start = page + off; + size -= off; + if (size>count) size = count; + if (size<0) size = 0; + + return size; +} + + +static int +acpi_system_write_debug ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + char debug_string[12] = {'\0'}; + + ACPI_FUNCTION_TRACE("acpi_system_write_debug"); + + if (count > sizeof(debug_string) - 1) + return_VALUE(-EINVAL); + + if (copy_from_user(debug_string, buffer, count)) + return_VALUE(-EFAULT); + + debug_string[count] = '\0'; + + switch ((unsigned long) data) { + case 0: + acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); + break; + case 1: + acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); + break; + default: + return_VALUE(-EINVAL); + } + + return_VALUE(count); +} + +#endif /* ACPI_DEBUG_OUTPUT */ + + +#ifdef CONFIG_ACPI_SLEEP + +static int +acpi_system_read_sleep ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_system *system = (struct acpi_system *) data; + char *p = page; + int size; + int i; + + ACPI_FUNCTION_TRACE("acpi_system_read_sleep"); + + if (!system || (off != 0)) + goto end; + + for (i = 0; i <= ACPI_STATE_S5; i++) { + if (system->states[i]) { + p += sprintf(p,"S%d ", i); + if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f && + acpi_gbl_FADT->smi_cmd != 0) + p += sprintf(p, "S4Bios "); + } + } + + p += sprintf(p, "\n"); + +end: + size = (p - page); + if (size <= off+count) *eof = 1; + *start = page + off; + size -= off; + if (size>count) size = count; + if (size<0) size = 0; + + return_VALUE(size); +} + + +static int +acpi_system_write_sleep ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + acpi_status status = AE_OK; + struct acpi_system *system = (struct acpi_system *) data; + char state_string[12] = {'\0'}; + u32 state = 0; + + ACPI_FUNCTION_TRACE("acpi_system_write_sleep"); + + if (!system || (count > sizeof(state_string) - 1)) + return_VALUE(-EINVAL); + + if (copy_from_user(state_string, buffer, count)) + return_VALUE(-EFAULT); + + state_string[count] = '\0'; + + state = simple_strtoul(state_string, NULL, 0); + + if (!system->states[state]) + return_VALUE(-ENODEV); + + /* + * If S4 is supported by the OS, then we should assume that + * echo 4b > /proc/acpi/sleep is for s4bios. + * Since we have only s4bios, we assume that acpi_suspend failed + * if no s4bios support. + */ + status = acpi_suspend(state); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + return_VALUE(count); +} + + +static int +acpi_system_read_alarm ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *context) +{ + char *p = page; + int size = 0; + u32 sec, min, hr; + u32 day, mo, yr; + + ACPI_FUNCTION_TRACE("acpi_system_read_alarm"); + + if (off != 0) + goto end; + + spin_lock(&rtc_lock); + + sec = CMOS_READ(RTC_SECONDS_ALARM); + min = CMOS_READ(RTC_MINUTES_ALARM); + hr = CMOS_READ(RTC_HOURS_ALARM); + +#if 0 /* If we ever get an FACP with proper values... */ + if (acpi_gbl_FADT->day_alrm) + day = CMOS_READ(acpi_gbl_FADT->day_alrm); + else + day = CMOS_READ(RTC_DAY_OF_MONTH); + if (acpi_gbl_FADT->mon_alrm) + mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); + else + mo = CMOS_READ(RTC_MONTH);; + if (acpi_gbl_FADT->century) + yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR); + else + yr = CMOS_READ(RTC_YEAR); +#else + day = CMOS_READ(RTC_DAY_OF_MONTH); + mo = CMOS_READ(RTC_MONTH); + yr = CMOS_READ(RTC_YEAR); +#endif + + spin_unlock(&rtc_lock); + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hr); + BCD_TO_BIN(day); + BCD_TO_BIN(mo); + BCD_TO_BIN(yr); + +#if 0 + /* we're trusting the FADT (see above)*/ +#else + /* If we're not trusting the FADT, we should at least make it + * right for _this_ century... ehm, what is _this_ century? + * + * TBD: + * ASAP: find piece of code in the kernel, e.g. star tracker driver, + * which we can trust to determine the century correctly. Atom + * watch driver would be nice, too... + * + * if that has not happened, change for first release in 2050: + * if (yr<50) + * yr += 2100; + * else + * yr += 2000; // current line of code + * + * if that has not happened either, please do on 2099/12/31:23:59:59 + * s/2000/2100 + * + */ + yr += 2000; +#endif + + p += sprintf(p,"%4.4u-", yr); + p += (mo > 12) ? sprintf(p, "**-") : sprintf(p, "%2.2u-", mo); + p += (day > 31) ? sprintf(p, "** ") : sprintf(p, "%2.2u ", day); + p += (hr > 23) ? sprintf(p, "**:") : sprintf(p, "%2.2u:", hr); + p += (min > 59) ? sprintf(p, "**:") : sprintf(p, "%2.2u:", min); + p += (sec > 59) ? sprintf(p, "**\n") : sprintf(p, "%2.2u\n", sec); + + end: + size = p - page; + if (size < count) *eof = 1; + else if (size > count) size = count; + if (size < 0) size = 0; + *start = page; + + return_VALUE(size); +} + + +static int +get_date_field ( + char **p, + u32 *value) +{ + char *next = NULL; + char *string_end = NULL; + int result = -EINVAL; + + /* + * Try to find delimeter, only to insert null. The end of the + * string won't have one, but is still valid. + */ + next = strpbrk(*p, "- :"); + if (next) + *next++ = '\0'; + + *value = simple_strtoul(*p, &string_end, 10); + + /* Signal success if we got a good digit */ + if (string_end != *p) + result = 0; + + if (next) + *p = next; + + return result; +} + + +static int +acpi_system_write_alarm ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + char alarm_string[30] = {'\0'}; + char *p = alarm_string; + u32 sec, min, hr, day, mo, yr; + int adjust = 0; + unsigned char rtc_control = 0; + + ACPI_FUNCTION_TRACE("acpi_system_write_alarm"); + + if (count > sizeof(alarm_string) - 1) + return_VALUE(-EINVAL); + + if (copy_from_user(alarm_string, buffer, count)) + return_VALUE(-EFAULT); + + alarm_string[count] = '\0'; + + /* check for time adjustment */ + if (alarm_string[0] == '+') { + p++; + adjust = 1; + } + + if ((result = get_date_field(&p, &yr))) + goto end; + if ((result = get_date_field(&p, &mo))) + goto end; + if ((result = get_date_field(&p, &day))) + goto end; + if ((result = get_date_field(&p, &hr))) + goto end; + if ((result = get_date_field(&p, &min))) + goto end; + if ((result = get_date_field(&p, &sec))) + goto end; + + if (sec > 59) { + min += 1; + sec -= 60; + } + if (min > 59) { + hr += 1; + min -= 60; + } + if (hr > 23) { + day += 1; + hr -= 24; + } + if (day > 31) { + mo += 1; + day -= 31; + } + if (mo > 12) { + yr += 1; + mo -= 12; + } + + spin_lock_irq(&rtc_lock); + + rtc_control = CMOS_READ(RTC_CONTROL); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(yr); + BIN_TO_BCD(mo); + BIN_TO_BCD(day); + BIN_TO_BCD(hr); + BIN_TO_BCD(min); + BIN_TO_BCD(sec); + } + + if (adjust) { + yr += CMOS_READ(RTC_YEAR); + mo += CMOS_READ(RTC_MONTH); + day += CMOS_READ(RTC_DAY_OF_MONTH); + hr += CMOS_READ(RTC_HOURS); + min += CMOS_READ(RTC_MINUTES); + sec += CMOS_READ(RTC_SECONDS); + } + + spin_unlock_irq(&rtc_lock); + + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(yr); + BCD_TO_BIN(mo); + BCD_TO_BIN(day); + BCD_TO_BIN(hr); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + } + + if (sec > 59) { + min++; + sec -= 60; + } + if (min > 59) { + hr++; + min -= 60; + } + if (hr > 23) { + day++; + hr -= 24; + } + if (day > 31) { + mo++; + day -= 31; + } + if (mo > 12) { + yr++; + mo -= 12; + } + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(yr); + BIN_TO_BCD(mo); + BIN_TO_BCD(day); + BIN_TO_BCD(hr); + BIN_TO_BCD(min); + BIN_TO_BCD(sec); + } + + spin_lock_irq(&rtc_lock); + + /* write the fields the rtc knows about */ + CMOS_WRITE(hr, RTC_HOURS_ALARM); + CMOS_WRITE(min, RTC_MINUTES_ALARM); + CMOS_WRITE(sec, RTC_SECONDS_ALARM); + + /* + * If the system supports an enhanced alarm it will have non-zero + * offsets into the CMOS RAM here -- which for some reason are pointing + * to the RTC area of memory. + */ +#if 0 + if (acpi_gbl_FADT->day_alrm) + CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); + if (acpi_gbl_FADT->mon_alrm) + CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); + if (acpi_gbl_FADT->century) + CMOS_WRITE(yr/100, acpi_gbl_FADT->century); +#endif + /* enable the rtc alarm interrupt */ + if (!(rtc_control & RTC_AIE)) { + rtc_control |= RTC_AIE; + CMOS_WRITE(rtc_control,RTC_CONTROL); + CMOS_READ(RTC_INTR_FLAGS); + } + + spin_unlock_irq(&rtc_lock); + + acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK); + + file->f_pos += count; + + result = 0; +end: + return_VALUE(result ? result : count); +} + +#endif /*CONFIG_ACPI_SLEEP*/ + + +static int +acpi_system_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_system_add_fs"); + + if (!device) + return_VALUE(-EINVAL); + + /* 'info' [R] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_INFO, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_INFO)); + else { + entry->read_proc = acpi_system_read_info; + entry->data = acpi_driver_data(device); + } + + /* 'dsdt' [R] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_DSDT, + S_IRUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_DSDT)); + else + entry->proc_fops = &acpi_system_dsdt_ops; + + /* 'fadt' [R] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_FADT, + S_IRUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_FADT)); + else + entry->proc_fops = &acpi_system_fadt_ops; + + /* 'event' [R] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_EVENT, + S_IRUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_EVENT)); + else + entry->proc_fops = &acpi_system_event_ops; + +#ifdef CONFIG_ACPI_SLEEP + + /* 'sleep' [R/W]*/ + entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_SLEEP)); + else { + entry->read_proc = acpi_system_read_sleep; + entry->write_proc = acpi_system_write_sleep; + entry->data = acpi_driver_data(device); + } + + /* 'alarm' [R/W] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_ALARM)); + else { + entry->read_proc = acpi_system_read_alarm; + entry->write_proc = acpi_system_write_alarm; + entry->data = acpi_driver_data(device); + } + +#endif /*CONFIG_ACPI_SLEEP*/ + +#ifdef ACPI_DEBUG_OUTPUT + + /* 'debug_layer' [R/W] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_DEBUG_LAYER)); + else { + entry->read_proc = acpi_system_read_debug; + entry->write_proc = acpi_system_write_debug; + entry->data = (void *) 0; + } + + /* 'debug_level' [R/W] */ + entry = create_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_SYSTEM_FILE_DEBUG_LEVEL)); + else { + entry->read_proc = acpi_system_read_debug; + entry->write_proc = acpi_system_write_debug; + entry->data = (void *) 1; + } + +#endif /*ACPI_DEBUG_OUTPUT */ + + return_VALUE(0); +} + + +static int +acpi_system_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_system_remove_fs"); + + if (!device) + return_VALUE(-EINVAL); + + remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_device_dir(device)); + remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_device_dir(device)); + remove_proc_entry(ACPI_SYSTEM_FILE_EVENT, acpi_device_dir(device)); +#ifdef CONFIG_ACPI_SLEEP + remove_proc_entry(ACPI_SYSTEM_FILE_SLEEP, acpi_device_dir(device)); + remove_proc_entry(ACPI_SYSTEM_FILE_ALARM, acpi_device_dir(device)); +#endif +#ifdef ACPI_DEBUG_OUTPUT + remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, + acpi_device_dir(device)); + remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, + acpi_device_dir(device)); +#endif + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +#if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_PM) + +/* Simple wrapper calling power down function. */ +static void acpi_sysrq_power_off(int key, struct pt_regs *pt_regs, + struct kbd_struct *kbd, struct tty_struct *tty) +{ + acpi_power_off(); +} + +struct sysrq_key_op sysrq_acpi_poweroff_op = { + .handler = &acpi_sysrq_power_off, + .help_msg = "Off", + .action_msg = "Power Off\n" +}; + +#endif /* CONFIG_MAGIC_SYSRQ */ + +static int +acpi_system_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_system *system = NULL; + u8 i = 0; + + ACPI_FUNCTION_TRACE("acpi_system_add"); + + if (!device) + return_VALUE(-EINVAL); + + system = kmalloc(sizeof(struct acpi_system), GFP_KERNEL); + if (!system) + return_VALUE(-ENOMEM); + memset(system, 0, sizeof(struct acpi_system)); + + system->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_SYSTEM_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_SYSTEM_CLASS); + acpi_driver_data(device) = system; + + result = acpi_system_add_fs(device); + if (result) + goto end; + + printk(KERN_INFO PREFIX "%s [%s] (supports", + acpi_device_name(device), acpi_device_bid(device)); + for (i=0; iS4bios_f && + 0 != acpi_gbl_FADT->smi_cmd) { + printk(" S4bios"); + system->states[i] = 1; + } + /* no break */ + default: + if (ACPI_SUCCESS(status)) { + system->states[i] = 1; + printk(" S%d", i); + } + } + } + printk(")\n"); + +#ifdef CONFIG_PM + /* Install the soft-off (S5) handler. */ + if (system->states[ACPI_STATE_S5]) { + pm_power_off = acpi_power_off; + register_sysrq_key('o', &sysrq_acpi_poweroff_op); + } +#endif + +end: + if (result) + kfree(system); + + return_VALUE(result); +} + + +static int +acpi_system_remove ( + struct acpi_device *device, + int type) +{ + struct acpi_system *system = NULL; + + ACPI_FUNCTION_TRACE("acpi_system_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + system = (struct acpi_system *) acpi_driver_data(device); + +#ifdef CONFIG_PM + /* Remove the soft-off (S5) handler. */ + if (system->states[ACPI_STATE_S5]) { + unregister_sysrq_key('o', &sysrq_acpi_poweroff_op); + pm_power_off = NULL; + } +#endif + + acpi_system_remove_fs(device); + + kfree(system); + + return 0; +} + + +int __init +acpi_system_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_system_init"); + + result = acpi_bus_register_driver(&acpi_system_driver); + if (result < 0) + return_VALUE(-ENODEV); + + return_VALUE(0); +} + + +void __exit +acpi_system_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_system_exit"); + acpi_bus_unregister_driver(&acpi_system_driver); + return_VOID; +} diff -urN linux-2.4.21/drivers/acpi/tables/Makefile linux-2.4.22/drivers/acpi/tables/Makefile --- linux-2.4.21/drivers/acpi/tables/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/tables/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/tables/tbconvrt.c linux-2.4.22/drivers/acpi/tables/tbconvrt.c --- linux-2.4.21/drivers/acpi/tables/tbconvrt.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/tables/tbconvrt.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,71 +1,84 @@ /****************************************************************************** * * Module Name: tbconvrt - ACPI Table conversion utilities - * $Revision: 28 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "actables.h" -#include "actbl.h" +#include +#include #define _COMPONENT ACPI_TABLES - MODULE_NAME ("tbconvrt") + ACPI_MODULE_NAME ("tbconvrt") /******************************************************************************* * - * FUNCTION: Acpi_tb_get_table_count + * FUNCTION: acpi_tb_get_table_count * - * PARAMETERS: + * PARAMETERS: RSDP - Pointer to the RSDP + * RSDT - Pointer to the RSDT/XSDT * - * RETURN: + * RETURN: The number of tables pointed to by the RSDT or XSDT. * - * DESCRIPTION: Calculate the number of tables + * DESCRIPTION: Calculate the number of tables. Automatically handles either + * an RSDT or XSDT. * ******************************************************************************/ u32 acpi_tb_get_table_count ( - RSDP_DESCRIPTOR *RSDP, - acpi_table_header *RSDT) + struct rsdp_descriptor *RSDP, + struct acpi_table_header *RSDT) { - u32 pointer_size; + u32 pointer_size; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); -#ifndef _IA64 - if (RSDP->revision < 2) { pointer_size = sizeof (u32); } - - else -#endif - { + else { pointer_size = sizeof (u64); } @@ -75,17 +88,17 @@ * pointers contained within the RSDT/XSDT. The size of the pointers * is architecture-dependent. */ - return ((RSDT->length - sizeof (acpi_table_header)) / pointer_size); + return ((RSDT->length - sizeof (struct acpi_table_header)) / pointer_size); } /******************************************************************************* * - * FUNCTION: Acpi_tb_convert_to_xsdt + * FUNCTION: acpi_tb_convert_to_xsdt * - * PARAMETERS: + * PARAMETERS: table_info - Info about the RSDT * - * RETURN: + * RETURN: Status * * DESCRIPTION: Convert an RSDT to an XSDT (internal common format) * @@ -93,24 +106,20 @@ acpi_status acpi_tb_convert_to_xsdt ( - acpi_table_desc *table_info, - u32 *number_of_tables) + struct acpi_table_desc *table_info) { - u32 table_size; - u32 i; - xsdt_descriptor *new_table; - - - FUNCTION_ENTRY (); + acpi_size table_size; + u32 i; + XSDT_DESCRIPTOR *new_table; - *number_of_tables = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info->pointer); + ACPI_FUNCTION_ENTRY (); /* Compute size of the converted XSDT */ - table_size = (*number_of_tables * sizeof (u64)) + sizeof (acpi_table_header); - + table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) + + sizeof (struct acpi_table_header); /* Allocate an XSDT */ @@ -121,37 +130,29 @@ /* Copy the header and set the length */ - MEMCPY (new_table, table_info->pointer, sizeof (acpi_table_header)); - new_table->header.length = table_size; + ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header)); + new_table->header.length = (u32) table_size; /* Copy the table pointers */ - for (i = 0; i < *number_of_tables; i++) { + for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { if (acpi_gbl_RSDP->revision < 2) { -#ifdef _IA64 - new_table->table_offset_entry[i] = - ((RSDT_DESCRIPTOR_REV071 *) table_info->pointer)->table_offset_entry[i]; -#else ACPI_STORE_ADDRESS (new_table->table_offset_entry[i], - ((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]); -#endif + ((struct rsdt_descriptor_rev1 *) table_info->pointer)->table_offset_entry[i]); } else { new_table->table_offset_entry[i] = - ((xsdt_descriptor *) table_info->pointer)->table_offset_entry[i]; + ((XSDT_DESCRIPTOR *) table_info->pointer)->table_offset_entry[i]; } } - /* Delete the original table (either mapped or in a buffer) */ acpi_tb_delete_single_table (table_info); - /* Point the table descriptor to the new table */ - table_info->pointer = (acpi_table_header *) new_table; - table_info->base_pointer = (acpi_table_header *) new_table; + table_info->pointer = (struct acpi_table_header *) new_table; table_info->length = table_size; table_info->allocation = ACPI_MEM_ALLOCATED; @@ -159,327 +160,325 @@ } -/******************************************************************************* +/****************************************************************************** * - * FUNCTION: Acpi_tb_convert_table_fadt + * FUNCTION: acpi_tb_init_generic_address * - * PARAMETERS: + * PARAMETERS: new_gas_struct - GAS struct to be initialized + * register_bit_width - Width of this register + * Address - Address of the register * - * RETURN: + * RETURN: None * - * DESCRIPTION: - * Converts BIOS supplied 1.0 and 0.71 ACPI FADT to an intermediate - * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply - * copied to the intermediate FADT. The ACPI CA software uses this - * intermediate FADT. Thus a significant amount of special #ifdef - * type codeing is saved. This intermediate FADT will need to be - * freed at some point. + * DESCRIPTION: Initialize a GAS structure. * ******************************************************************************/ -acpi_status -acpi_tb_convert_table_fadt (void) +static void +acpi_tb_init_generic_address ( + struct acpi_generic_address *new_gas_struct, + u8 register_bit_width, + acpi_physical_address address) { -#ifdef _IA64 - fadt_descriptor_rev071 *FADT71; - u8 pm1_address_space; - u8 pm2_address_space; - u8 pm_timer_address_space; - u8 gpe0address_space; - u8 gpe1_address_space; -#else - fadt_descriptor_rev1 *FADT1; -#endif - - fadt_descriptor_rev2 *FADT2; - acpi_table_desc *table_desc; - - - FUNCTION_TRACE ("Tb_convert_table_fadt"); - - - /* Acpi_gbl_FADT is valid */ - /* Allocate and zero the 2.0 buffer */ - - FADT2 = ACPI_MEM_CALLOCATE (sizeof (fadt_descriptor_rev2)); - if (FADT2 == NULL) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - - /* The ACPI FADT revision number is FADT2_REVISION_ID=3 */ - /* So, if the current table revision is less than 3 it is type 1.0 or 0.71 */ - - if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) { - /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ - - *FADT2 = *((fadt_descriptor_rev2*) acpi_gbl_FADT); - - } - - else { - -#ifdef _IA64 - /* - * For the 64-bit case only, a revision ID less than V2.0 means the - * tables are the 0.71 extensions - */ - - /* The BIOS stored FADT should agree with Revision 0.71 */ - - FADT71 = (fadt_descriptor_rev071 *) acpi_gbl_FADT; - - /* Copy the table header*/ + ACPI_STORE_ADDRESS (new_gas_struct->address, address); - FADT2->header = FADT71->header; - - /* Copy the common fields */ - - FADT2->sci_int = FADT71->sci_int; - FADT2->acpi_enable = FADT71->acpi_enable; - FADT2->acpi_disable = FADT71->acpi_disable; - FADT2->S4bios_req = FADT71->S4bios_req; - FADT2->plvl2_lat = FADT71->plvl2_lat; - FADT2->plvl3_lat = FADT71->plvl3_lat; - FADT2->day_alrm = FADT71->day_alrm; - FADT2->mon_alrm = FADT71->mon_alrm; - FADT2->century = FADT71->century; - FADT2->gpe1_base = FADT71->gpe1_base; - - /* - * We still use the block length registers even though - * the GAS structure should obsolete them. This is because - * these registers are byte lengths versus the GAS which - * contains a bit width - */ - FADT2->pm1_evt_len = FADT71->pm1_evt_len; - FADT2->pm1_cnt_len = FADT71->pm1_cnt_len; - FADT2->pm2_cnt_len = FADT71->pm2_cnt_len; - FADT2->pm_tm_len = FADT71->pm_tm_len; - FADT2->gpe0blk_len = FADT71->gpe0blk_len; - FADT2->gpe1_blk_len = FADT71->gpe1_blk_len; - FADT2->gpe1_base = FADT71->gpe1_base; - - /* Copy the existing 0.71 flags to 2.0. The other bits are zero.*/ - - FADT2->wb_invd = FADT71->flush_cash; - FADT2->proc_c1 = FADT71->proc_c1; - FADT2->plvl2_up = FADT71->plvl2_up; - FADT2->pwr_button = FADT71->pwr_button; - FADT2->sleep_button = FADT71->sleep_button; - FADT2->fixed_rTC = FADT71->fixed_rTC; - FADT2->rtcs4 = FADT71->rtcs4; - FADT2->tmr_val_ext = FADT71->tmr_val_ext; - FADT2->dock_cap = FADT71->dock_cap; - - - /* We should not use these next two addresses */ - /* Since our buffer is pre-zeroed nothing to do for */ - /* the next three data items in the structure */ - /* FADT2->Firmware_ctrl = 0; */ - /* FADT2->Dsdt = 0; */ - - /* System Interrupt Model isn't used in ACPI 2.0*/ - /* FADT2->Reserved1 = 0; */ - - /* This field is set by the OEM to convey the preferred */ - /* power management profile to OSPM. It doesn't have any*/ - /* 0.71 equivalence. Since we don't know what kind of */ - /* 64-bit system this is, we will pick unspecified. */ - - FADT2->prefer_PM_profile = PM_UNSPECIFIED; - - - /* Port address of SMI command port */ - /* We shouldn't use this port because IA64 doesn't */ - /* have or use SMI. It has PMI. */ + new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; + new_gas_struct->register_bit_width = register_bit_width; + new_gas_struct->register_bit_offset = 0; + new_gas_struct->reserved = 0; +} - FADT2->smi_cmd = (u32)(FADT71->smi_cmd & 0xFFFFFFFF); +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_fadt1 + * + * PARAMETERS: local_fadt - Pointer to new FADT + * original_fadt - Pointer to old FADT + * + * RETURN: Populates local_fadt + * + * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format + * + ******************************************************************************/ - /* processor performance state control*/ - /* The value OSPM writes to the SMI_CMD register to assume */ - /* processor performance state control responsibility. */ - /* There isn't any equivalence in 0.71 */ - /* Again this should be meaningless for IA64 */ - /* FADT2->Pstate_cnt = 0; */ +static void +acpi_tb_convert_fadt1 ( + struct fadt_descriptor_rev2 *local_fadt, + struct fadt_descriptor_rev1 *original_fadt) +{ - /* The 32-bit Power management and GPE registers are */ - /* not valid in IA-64 and we are not going to use them */ - /* so leaving them pre-zeroed. */ - /* Support for the _CST object and C States change notification.*/ - /* This data item hasn't any 0.71 equivalence so leaving it zero.*/ - /* FADT2->Cst_cnt = 0; */ + /* ACPI 1.0 FACS */ + /* The BIOS stored FADT should agree with Revision 1.0 */ - /* number of flush strides that need to be read */ - /* No 0.71 equivalence. Leave pre-zeroed. */ - /* FADT2->Flush_size = 0; */ + /* + * Copy the table header and the common part of the tables. + * + * The 2.0 table is an extension of the 1.0 table, so the entire 1.0 + * table can be copied first, then expand some fields to 64 bits. + */ + ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev1)); - /* Processor's memory cache line width, in bytes */ - /* No 0.71 equivalence. Leave pre-zeroed. */ - /* FADT2->Flush_stride = 0; */ + /* Convert table pointers to 64-bit fields */ - /* Processor's duty cycle index in processor's P_CNT reg*/ - /* No 0.71 equivalence. Leave pre-zeroed. */ - /* FADT2->Duty_offset = 0; */ + ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl); + ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt); - /* Processor's duty cycle value bit width in P_CNT register.*/ - /* No 0.71 equivalence. Leave pre-zeroed. */ - /* FADT2->Duty_width = 0; */ + /* + * System Interrupt Model isn't used in ACPI 2.0 (local_fadt->Reserved1 = 0;) + */ + /* + * This field is set by the OEM to convey the preferred power management + * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't + * know what kind of 32-bit system this is, we will use "unspecified". + */ + local_fadt->prefer_PM_profile = PM_UNSPECIFIED; - /* Since there isn't any equivalence in 0.71 */ - /* and since Big_sur had to support legacy */ + /* + * Processor Performance State Control. This is the value OSPM writes to + * the SMI_CMD register to assume processor performance state control + * responsibility. There isn't any equivalence in 1.0, leave it zeroed. + */ + local_fadt->pstate_cnt = 0; - FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; + /* + * Support for the _CST object and C States change notification. + * This data item hasn't any 1.0 equivalence so leave it zero. + */ + local_fadt->cst_cnt = 0; - /* Copy to ACPI 2.0 64-BIT Extended Addresses */ + /* + * Since there isn't any equivalence in 1.0 and since it highly likely + * that a 1.0 system has legacy support. + */ + local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; - FADT2->Xfirmware_ctrl = FADT71->firmware_ctrl; - FADT2->Xdsdt = FADT71->dsdt; + /* + * Convert the V1.0 block addresses to V2.0 GAS structures + */ + acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt->V1_pm1a_evt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt->V1_pm1b_evt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, + (acpi_physical_address) local_fadt->V1_pm2_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, + (acpi_physical_address) local_fadt->V1_pm_tmr_blk); + acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0, + (acpi_physical_address) local_fadt->V1_gpe0_blk); + acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0, + (acpi_physical_address) local_fadt->V1_gpe1_blk); + + /* Create separate GAS structs for the PM1 Enable registers */ + + acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); + + /* PM1B is optional; leave null if not present */ + + if (local_fadt->xpm1b_evt_blk.address) { + acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); + } +} - /* Extract the address space IDs */ +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_fadt2 + * + * PARAMETERS: local_fadt - Pointer to new FADT + * original_fadt - Pointer to old FADT + * + * RETURN: Populates local_fadt + * + * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format. + * Handles optional "X" fields. + * + ******************************************************************************/ - pm1_address_space = (u8)((FADT71->address_space & PM1_BLK_ADDRESS_SPACE) >> 1); - pm2_address_space = (u8)((FADT71->address_space & PM2_CNT_BLK_ADDRESS_SPACE) >> 2); - pm_timer_address_space = (u8)((FADT71->address_space & PM_TMR_BLK_ADDRESS_SPACE) >> 3); - gpe0address_space = (u8)((FADT71->address_space & GPE0_BLK_ADDRESS_SPACE) >> 4); - gpe1_address_space = (u8)((FADT71->address_space & GPE1_BLK_ADDRESS_SPACE) >> 5); +static void +acpi_tb_convert_fadt2 ( + struct fadt_descriptor_rev2 *local_fadt, + struct fadt_descriptor_rev2 *original_fadt) +{ - /* - * Convert the 0.71 (non-GAS style) Block addresses to V2.0 GAS structures, - * in this order: - * - * PM 1_a Events - * PM 1_b Events - * PM 1_a Control - * PM 1_b Control - * PM 2 Control - * PM Timer Control - * GPE Block 0 - * GPE Block 1 - */ + /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_evt_blk, FADT71->pm1_evt_len, FADT71->pm1a_evt_blk, pm1_address_space); - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_evt_blk, FADT71->pm1_evt_len, FADT71->pm1b_evt_blk, pm1_address_space); - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1a_cnt_blk, pm1_address_space); - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1b_cnt_blk, pm1_address_space); - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm2_cnt_blk, FADT71->pm2_cnt_len, FADT71->pm2_cnt_blk, pm2_address_space); - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm_tmr_blk, FADT71->pm_tm_len, FADT71->pm_tmr_blk, pm_timer_address_space); - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe0blk, FADT71->gpe0blk_len, FADT71->gpe0blk, gpe0address_space); - ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe1_blk, FADT71->gpe1_blk_len, FADT71->gpe1_blk, gpe1_address_space); + ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev2)); -#else + /* + * "X" fields are optional extensions to the original V1.0 fields, so + * we must selectively expand V1.0 fields if the corresponding X field + * is zero. + */ + if (!(local_fadt->xfirmware_ctrl)) { + ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl); + } - /* ACPI 1.0 FACS */ + if (!(local_fadt->Xdsdt)) { + ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt); + } + if (!(local_fadt->xpm1a_evt_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, + local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk); + } - /* The BIOS stored FADT should agree with Revision 1.0 */ + if (!(local_fadt->xpm1b_evt_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, + local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk); + } - FADT1 = (fadt_descriptor_rev1*) acpi_gbl_FADT; + if (!(local_fadt->xpm1a_cnt_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, + local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk); + } - /* - * Copy the table header and the common part of the tables - * The 2.0 table is an extension of the 1.0 table, so the - * entire 1.0 table can be copied first, then expand some - * fields to 64 bits. - */ - MEMCPY (FADT2, FADT1, sizeof (fadt_descriptor_rev1)); + if (!(local_fadt->xpm1b_cnt_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, + local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk); + } + if (!(local_fadt->xpm2_cnt_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, + local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk); + } - /* Convert table pointers to 64-bit fields */ + if (!(local_fadt->xpm_tmr_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, + local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk); + } - ACPI_STORE_ADDRESS (FADT2->Xfirmware_ctrl, FADT1->firmware_ctrl); - ACPI_STORE_ADDRESS (FADT2->Xdsdt, FADT1->dsdt); + if (!(local_fadt->xgpe0_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, + 0, (acpi_physical_address) local_fadt->V1_gpe0_blk); + } - /* System Interrupt Model isn't used in ACPI 2.0*/ - /* FADT2->Reserved1 = 0; */ + if (!(local_fadt->xgpe1_blk.address)) { + acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, + 0, (acpi_physical_address) local_fadt->V1_gpe1_blk); + } - /* This field is set by the OEM to convey the preferred */ - /* power management profile to OSPM. It doesn't have any*/ - /* 1.0 equivalence. Since we don't know what kind of */ - /* 32-bit system this is, we will pick unspecified. */ + /* Create separate GAS structs for the PM1 Enable registers */ - FADT2->prefer_PM_profile = PM_UNSPECIFIED; + acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); + acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id; + + /* PM1B is optional; leave null if not present */ + + if (local_fadt->xpm1b_evt_blk.address) { + acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); + acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id; + } +} - /* Processor Performance State Control. This is the value */ - /* OSPM writes to the SMI_CMD register to assume processor */ - /* performance state control responsibility. There isn't */ - /* any equivalence in 1.0. So leave it zeroed. */ +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_table_fadt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local + * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply + * copied to the local FADT. The ACPI CA software uses this + * local FADT. Thus a significant amount of special #ifdef + * type codeing is saved. + * + ******************************************************************************/ - FADT2->pstate_cnt = 0; +acpi_status +acpi_tb_convert_table_fadt (void) +{ + struct fadt_descriptor_rev2 *local_fadt; + struct acpi_table_desc *table_desc; - /* Support for the _CST object and C States change notification.*/ - /* This data item hasn't any 1.0 equivalence so leaving it zero.*/ + ACPI_FUNCTION_TRACE ("tb_convert_table_fadt"); - FADT2->cst_cnt = 0; + /* + * acpi_gbl_FADT is valid + * Allocate and zero the 2.0 FADT buffer + */ + local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2)); + if (local_fadt == NULL) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - /* Since there isn't any equivalence in 1.0 and since it */ - /* is highly likely that a 1.0 system has legacy support. */ + /* + * FADT length and version validation. The table must be at least as + * long as the version 1.0 FADT + */ + if (acpi_gbl_FADT->header.length < sizeof (struct fadt_descriptor_rev1)) { + ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", acpi_gbl_FADT->header.length)); + return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); + } - FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; + if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) { + if (acpi_gbl_FADT->header.length < sizeof (struct fadt_descriptor_rev2)) { + /* Length is too short to be a V2.0 table */ + ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", + acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.revision)); - /* - * Convert the V1.0 Block addresses to V2.0 GAS structures - * in this order: - * - * PM 1_a Events - * PM 1_b Events - * PM 1_a Control - * PM 1_b Control - * PM 2 Control - * PM Timer Control - * GPE Block 0 - * GPE Block 1 - */ + acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT); + } + else { + /* Valid V2.0 table */ - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_evt_blk, FADT1->pm1_evt_len, FADT1->pm1a_evt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_evt_blk, FADT1->pm1_evt_len, FADT1->pm1b_evt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1a_cnt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1b_cnt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm2_cnt_blk, FADT1->pm2_cnt_len, FADT1->pm2_cnt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm_tmr_blk, FADT1->pm_tm_len, FADT1->pm_tmr_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe0blk, FADT1->gpe0blk_len, FADT1->gpe0blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe1_blk, FADT1->gpe1_blk_len, FADT1->gpe1_blk); -#endif + acpi_tb_convert_fadt2 (local_fadt, acpi_gbl_FADT); + } } + else { + /* Valid V1.0 table */ + acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT); + } /* - * Global FADT pointer will point to the common V2.0 FADT + * Global FADT pointer will point to the new common V2.0 FADT */ - acpi_gbl_FADT = FADT2; + acpi_gbl_FADT = local_fadt; acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR); - /* Free the original table */ - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT]; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next; acpi_tb_delete_single_table (table_desc); - /* Install the new table */ - table_desc->pointer = (acpi_table_header *) acpi_gbl_FADT; - table_desc->base_pointer = acpi_gbl_FADT; - table_desc->allocation = ACPI_MEM_ALLOCATED; - table_desc->length = sizeof (fadt_descriptor_rev2); - + table_desc->pointer = (struct acpi_table_header *) acpi_gbl_FADT; + table_desc->allocation = ACPI_MEM_ALLOCATED; + table_desc->length = sizeof (struct fadt_descriptor_rev2); /* Dump the entire FADT */ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Hex dump of common internal FADT, size %d (%X)\n", acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.length)); - DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->header.length); - + ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->header.length); return_ACPI_STATUS (AE_OK); } @@ -487,82 +486,57 @@ /******************************************************************************* * - * FUNCTION: Acpi_tb_convert_table_facs + * FUNCTION: acpi_tb_convert_table_facs * - * PARAMETERS: + * PARAMETERS: table_info - Info for currently installad FACS * - * RETURN: + * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal + * table format. * ******************************************************************************/ acpi_status acpi_tb_build_common_facs ( - acpi_table_desc *table_info) + struct acpi_table_desc *table_info) { - acpi_common_facs *common_facs; - -#ifdef _IA64 - facs_descriptor_rev071 *FACS71; -#else - facs_descriptor_rev1 *FACS1; -#endif - - facs_descriptor_rev2 *FACS2; - - FUNCTION_TRACE ("Tb_build_common_facs"); + ACPI_FUNCTION_TRACE ("tb_build_common_facs"); - /* Allocate a common FACS */ + /* Absolute minimum length is 24, but the ACPI spec says 64 */ - common_facs = ACPI_MEM_CALLOCATE (sizeof (acpi_common_facs)); - if (!common_facs) { - return_ACPI_STATUS (AE_NO_MEMORY); + if (acpi_gbl_FACS->length < 24) { + ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n", acpi_gbl_FACS->length)); + return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); } + if (acpi_gbl_FACS->length < 64) { + ACPI_REPORT_WARNING (("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n", + acpi_gbl_FACS->length)); + } /* Copy fields to the new FACS */ - if (acpi_gbl_RSDP->revision < 2) { -#ifdef _IA64 - /* 0.71 FACS */ - - FACS71 = (facs_descriptor_rev071 *) acpi_gbl_FACS; - - common_facs->global_lock = (u32 *) &(FACS71->global_lock); - common_facs->firmware_waking_vector = &FACS71->firmware_waking_vector; - common_facs->vector_width = 64; -#else - /* ACPI 1.0 FACS */ + acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock); - FACS1 = (facs_descriptor_rev1 *) acpi_gbl_FACS; + if ((acpi_gbl_RSDP->revision < 2) || + (acpi_gbl_FACS->length < 32) || + (!(acpi_gbl_FACS->xfirmware_waking_vector))) { + /* ACPI 1.0 FACS or short table or optional X_ field is zero */ - common_facs->global_lock = &(FACS1->global_lock); - common_facs->firmware_waking_vector = (u64 *) &FACS1->firmware_waking_vector; - common_facs->vector_width = 32; - -#endif + acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64, &(acpi_gbl_FACS->firmware_waking_vector)); + acpi_gbl_common_fACS.vector_width = 32; } - else { - /* ACPI 2.0 FACS */ + /* ACPI 2.0 FACS with valid X_ field */ - FACS2 = (facs_descriptor_rev2 *) acpi_gbl_FACS; - - common_facs->global_lock = &(FACS2->global_lock); - common_facs->firmware_waking_vector = &FACS2->Xfirmware_waking_vector; - common_facs->vector_width = 64; + acpi_gbl_common_fACS.firmware_waking_vector = &acpi_gbl_FACS->xfirmware_waking_vector; + acpi_gbl_common_fACS.vector_width = 64; } - - /* Set the global FACS pointer to point to the common FACS */ - - - acpi_gbl_FACS = common_facs; - - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/tables/tbget.c linux-2.4.22/drivers/acpi/tables/tbget.c --- linux-2.4.21/drivers/acpi/tables/tbget.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/tables/tbget.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,754 +1,492 @@ /****************************************************************************** * * Module Name: tbget - ACPI Table get* routines - * $Revision: 56 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES - MODULE_NAME ("tbget") - -#define RSDP_CHECKSUM_LENGTH 20 + ACPI_MODULE_NAME ("tbget") /******************************************************************************* * - * FUNCTION: Acpi_tb_get_table_ptr + * FUNCTION: acpi_tb_get_table * - * PARAMETERS: Table_type - one of the defined table types - * Instance - Which table of this type - * Table_ptr_loc - pointer to location to place the pointer for - * return + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * table_info - Where table info is returned * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: This function is called to get the pointer to an ACPI table. + * DESCRIPTION: Get entire table of unknown size. * ******************************************************************************/ acpi_status -acpi_tb_get_table_ptr ( - acpi_table_type table_type, - u32 instance, - acpi_table_header **table_ptr_loc) +acpi_tb_get_table ( + struct acpi_pointer *address, + struct acpi_table_desc *table_info) { - acpi_table_desc *table_desc; - u32 i; - - - FUNCTION_TRACE ("Tb_get_table_ptr"); - + acpi_status status; + struct acpi_table_header header; - if (!acpi_gbl_DSDT) { - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } - if (table_type > ACPI_TABLE_MAX) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + ACPI_FUNCTION_TRACE ("tb_get_table"); /* - * For all table types (Single/Multiple), the first - * instance is always in the list head. + * Get the header in order to get signature and table size */ - if (instance == 1) { - /* - * Just pluck the pointer out of the global table! - * Will be null if no table is present - */ - *table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer; - return_ACPI_STATUS (AE_OK); + status = acpi_tb_get_table_header (address, &header); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + /* Get the entire table */ - /* - * Check for instance out of range - */ - if (instance > acpi_gbl_acpi_tables[table_type].count) { - return_ACPI_STATUS (AE_NOT_EXIST); - } - - /* Walk the list to get the desired table - * Since the if (Instance == 1) check above checked for the - * first table, setting Table_desc equal to the .Next member - * is actually pointing to the second table. Therefore, we - * need to walk from the 2nd table until we reach the Instance - * that the user is looking for and return its table pointer. - */ - table_desc = acpi_gbl_acpi_tables[table_type].next; - for (i = 2; i < instance; i++) { - table_desc = table_desc->next; + status = acpi_tb_get_table_body (address, &header, table_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n", + header.length, acpi_format_exception (status))); + return_ACPI_STATUS (status); } - /* We are now pointing to the requested table's descriptor */ - - *table_ptr_loc = table_desc->pointer; - return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_tb_get_table + * FUNCTION: acpi_tb_get_table_header * - * PARAMETERS: Physical_address - Physical address of table to retrieve - * *Buffer_ptr - If Buffer_ptr is valid, read data from - * buffer rather than searching memory - * *Table_info - Where the table info is returned + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * return_header - Where the table header is returned * * RETURN: Status * - * DESCRIPTION: Maps the physical address of table into a logical address + * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. * ******************************************************************************/ acpi_status -acpi_tb_get_table ( - ACPI_PHYSICAL_ADDRESS physical_address, - acpi_table_header *buffer_ptr, - acpi_table_desc *table_info) +acpi_tb_get_table_header ( + struct acpi_pointer *address, + struct acpi_table_header *return_header) { - acpi_table_header *table_header = NULL; - acpi_table_header *full_table = NULL; - u32 size; - u8 allocation; - acpi_status status = AE_OK; - - - FUNCTION_TRACE ("Tb_get_table"); - - - if (!table_info) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - - if (buffer_ptr) { - /* - * Getting data from a buffer, not BIOS tables - */ - table_header = buffer_ptr; - status = acpi_tb_validate_table_header (table_header); - if (ACPI_FAILURE (status)) { - /* Table failed verification, map all errors to BAD_DATA */ + acpi_status status = AE_OK; + struct acpi_table_header *header = NULL; - return_ACPI_STATUS (AE_BAD_DATA); - } - /* Allocate buffer for the entire table */ + ACPI_FUNCTION_TRACE ("tb_get_table_header"); - full_table = ACPI_MEM_ALLOCATE (table_header->length); - if (!full_table) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - /* Copy the entire table (including header) to the local buffer */ + /* + * Flags contains the current processor mode (Virtual or Physical addressing) + * The pointer_type is either Logical or Physical + */ + switch (address->pointer_type) { + case ACPI_PHYSMODE_PHYSPTR: + case ACPI_LOGMODE_LOGPTR: - size = table_header->length; - MEMCPY (full_table, buffer_ptr, size); + /* Pointer matches processor mode, copy the header */ - /* Save allocation type */ + ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (struct acpi_table_header)); + break; - allocation = ACPI_MEM_ALLOCATED; - } + case ACPI_LOGMODE_PHYSPTR: - /* - * Not reading from a buffer, just map the table's physical memory - * into our address space. - */ - else { - size = SIZE_IN_HEADER; + /* Create a logical address for the physical pointer*/ - status = acpi_tb_map_acpi_table (physical_address, &size, &full_table); + status = acpi_os_map_memory (address->pointer.physical, sizeof (struct acpi_table_header), + (void *) &header); if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n", + ACPI_HIDWORD (address->pointer.physical), + ACPI_LODWORD (address->pointer.physical), + sizeof (struct acpi_table_header))); return_ACPI_STATUS (status); } - /* Save allocation type */ + /* Copy header and delete mapping */ - allocation = ACPI_MEM_MAPPED; - } + ACPI_MEMCPY (return_header, header, sizeof (struct acpi_table_header)); + acpi_os_unmap_memory (header, sizeof (struct acpi_table_header)); + break; - /* Return values */ + default: - table_info->pointer = full_table; - table_info->length = size; - table_info->allocation = allocation; - table_info->base_pointer = full_table; + ACPI_REPORT_ERROR (("Invalid address flags %X\n", + address->pointer_type)); + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_tb_get_all_tables + * FUNCTION: acpi_tb_get_table_body * - * PARAMETERS: Number_of_tables - Number of tables to get - * Table_ptr - Input buffer pointer, optional + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * Header - Header of the table to retrieve + * table_info - Where the table info is returned * * RETURN: Status * - * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must - * already be loaded and validated. + * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to + * replace the table with a newer version (table override.) + * Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. * ******************************************************************************/ acpi_status -acpi_tb_get_all_tables ( - u32 number_of_tables, - acpi_table_header *table_ptr) +acpi_tb_get_table_body ( + struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info) { - acpi_status status = AE_OK; - u32 index; - acpi_table_desc table_info; - - - FUNCTION_TRACE ("Tb_get_all_tables"); + acpi_status status; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Number of tables: %d\n", number_of_tables)); + ACPI_FUNCTION_TRACE ("tb_get_table_body"); - /* - * Loop through all table pointers found in RSDT. - * This will NOT include the FACS and DSDT - we must get - * them after the loop - */ - for (index = 0; index < number_of_tables; index++) { - /* Clear the Table_info each time */ - - MEMSET (&table_info, 0, sizeof (acpi_table_desc)); - - /* Get the table via the XSDT */ - - status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) - ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[index]), - table_ptr, &table_info); - - /* Ignore a table that failed verification */ - - if (status == AE_BAD_DATA) { - continue; - } - - /* However, abort on serious errors */ - - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Recognize and install the table */ - - status = acpi_tb_install_table (table_ptr, &table_info); - if (ACPI_FAILURE (status)) { - /* - * Unrecognized or unsupported table, delete it and ignore the - * error. Just get as many tables as we can, later we will - * determine if there are enough tables to continue. - */ - acpi_tb_uninstall_table (&table_info); - } - } - - - /* - * Convert the FADT to a common format. This allows earlier revisions of the - * table to coexist with newer versions, using common access code. - */ - status = acpi_tb_convert_table_fadt (); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - - /* - * Get the minimum set of ACPI tables, namely: - * - * 1) FADT (via RSDT in loop above) - * 2) FACS - * 3) DSDT - * - */ - - /* - * Get the FACS (must have the FADT first, from loop above) - * Acpi_tb_get_table_facs will fail if FADT pointer is not valid - */ - status = acpi_tb_get_table_facs (table_ptr, &table_info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Install the FACS */ - - status = acpi_tb_install_table (table_ptr, &table_info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - /* - * Create the common FACS pointer table - * (Contains pointers to the original table) - */ - status = acpi_tb_build_common_facs (&table_info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + if (!table_info || !address) { + return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* - * Get the DSDT (We know that the FADT is valid now) + * Attempt table override. */ - status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt), - table_ptr, &table_info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Install the DSDT */ + status = acpi_tb_table_override (header, table_info); + if (ACPI_SUCCESS (status)) { + /* Table was overridden by the host OS */ - status = acpi_tb_install_table (table_ptr, &table_info); - if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* Dump the DSDT Header */ - - ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Hex dump of DSDT Header:\n")); - DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, sizeof (acpi_table_header)); - - /* Dump the entire DSDT */ - - ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, - "Hex dump of DSDT (After header), size %d (%x)\n", - acpi_gbl_DSDT->length, acpi_gbl_DSDT->length)); - DUMP_BUFFER ((u8 *) (acpi_gbl_DSDT + 1), acpi_gbl_DSDT->length); - - /* - * Initialize the capabilities flags. - * Assumes that platform supports ACPI_MODE since we have tables! - */ - acpi_gbl_system_flags |= acpi_hw_get_mode_capabilities (); - - - /* Always delete the RSDP mapping, we are done with it */ - - acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP); + /* No override, get the original table */ + status = acpi_tb_get_this_table (address, header, table_info); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_tb_verify_rsdp + * FUNCTION: acpi_tb_table_override * - * PARAMETERS: Number_of_tables - Where the table count is placed + * PARAMETERS: Header - Pointer to table header + * table_info - Return info if table is overridden * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * DESCRIPTION: Attempts override of current table with a new one if provided + * by the host OS. * ******************************************************************************/ acpi_status -acpi_tb_verify_rsdp ( - ACPI_PHYSICAL_ADDRESS rsdp_physical_address) +acpi_tb_table_override ( + struct acpi_table_header *header, + struct acpi_table_desc *table_info) { - acpi_table_desc table_info; - acpi_status status; - u8 *table_ptr; + struct acpi_table_header *new_table; + acpi_status status; + struct acpi_pointer address; - FUNCTION_TRACE ("Tb_verify_rsdp"); + ACPI_FUNCTION_TRACE ("tb_table_override"); /* - * Obtain access to the RSDP structure + * The OSL will examine the header and decide whether to override this + * table. If it decides to override, a table will be returned in new_table, + * which we will then copy. */ - status = acpi_os_map_memory (rsdp_physical_address, sizeof (RSDP_DESCRIPTOR), - (void **) &table_ptr); + status = acpi_os_table_override (header, &new_table); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* - * The signature and checksum must both be correct - */ - if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { - /* Nope, BAD Signature */ + /* Some severe error from the OSL, but we basically ignore it */ - status = AE_BAD_SIGNATURE; - goto cleanup; + ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n", + acpi_format_exception (status))); + return_ACPI_STATUS (status); } - if (acpi_tb_checksum (table_ptr, RSDP_CHECKSUM_LENGTH) != 0) { - /* Nope, BAD Checksum */ + if (!new_table) { + /* No table override */ - status = AE_BAD_CHECKSUM; - goto cleanup; + return_ACPI_STATUS (AE_NO_ACPI_TABLES); } - /* TBD: Check extended checksum if table version >= 2 */ - - /* The RSDP supplied is OK */ - - table_info.pointer = (acpi_table_header *) table_ptr; - table_info.length = sizeof (RSDP_DESCRIPTOR); - table_info.allocation = ACPI_MEM_MAPPED; - table_info.base_pointer = table_ptr; - - /* Save the table pointers and allocation info */ + /* + * We have a new table to override the old one. Get a copy of + * the new one. We know that the new table has a logical pointer. + */ + address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; + address.pointer.logical = new_table; - status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info); + status = acpi_tb_get_this_table (&address, new_table, table_info); if (ACPI_FAILURE (status)) { - goto cleanup; + ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n", + acpi_format_exception (status))); + return_ACPI_STATUS (status); } + /* Copy the table info */ - /* Save the RSDP in a global for easy access */ - - acpi_gbl_RSDP = (RSDP_DESCRIPTOR *) table_info.pointer; - return_ACPI_STATUS (status); - - - /* Error exit */ -cleanup: + ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n", + table_info->pointer->signature)); - acpi_os_unmap_memory (table_ptr, sizeof (RSDP_DESCRIPTOR)); - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_get_rsdt_address - * - * PARAMETERS: None - * - * RETURN: RSDT physical address - * - * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the - * version of the RSDP - * - ******************************************************************************/ - -ACPI_PHYSICAL_ADDRESS -acpi_tb_get_rsdt_address (void) -{ - ACPI_PHYSICAL_ADDRESS physical_address; - - - FUNCTION_ENTRY (); - - - /* - * For RSDP revision 0 or 1, we use the RSDT. - * For RSDP revision 2 (and above), we use the XSDT - */ - if (acpi_gbl_RSDP->revision < 2) { -#ifdef _IA64 - /* 0.71 RSDP has 64bit Rsdt address field */ - physical_address = ((RSDP_DESCRIPTOR_REV071 *)acpi_gbl_RSDP)->rsdt_physical_address; -#else - physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->rsdt_physical_address; -#endif - } - - else { - physical_address = (ACPI_PHYSICAL_ADDRESS) - ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address); - } - - return (physical_address); + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_tb_validate_rsdt + * FUNCTION: acpi_tb_get_this_table * - * PARAMETERS: Table_ptr - Addressable pointer to the RSDT. + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * Header - Header of the table to retrieve + * table_info - Where the table info is returned * * RETURN: Status * - * DESCRIPTION: Validate signature for the RSDT or XSDT + * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. * ******************************************************************************/ acpi_status -acpi_tb_validate_rsdt ( - acpi_table_header *table_ptr) +acpi_tb_get_this_table ( + struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info) { - u32 no_match; + struct acpi_table_header *full_table = NULL; + u8 allocation; + acpi_status status = AE_OK; - PROC_NAME ("Tb_validate_rsdt"); + ACPI_FUNCTION_TRACE ("tb_get_this_table"); /* - * For RSDP revision 0 or 1, we use the RSDT. - * For RSDP revision 2 (and above), we use the XSDT + * Flags contains the current processor mode (Virtual or Physical addressing) + * The pointer_type is either Logical or Physical */ - if (acpi_gbl_RSDP->revision < 2) { - no_match = STRNCMP ((char *) table_ptr, RSDT_SIG, - sizeof (RSDT_SIG) -1); - } - else { - no_match = STRNCMP ((char *) table_ptr, XSDT_SIG, - sizeof (XSDT_SIG) -1); - } - - - if (no_match) { - /* Invalid RSDT or XSDT signature */ - - REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n")); - - DUMP_BUFFER (acpi_gbl_RSDP, 20); - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, - "RSDT/XSDT signature at %X is invalid\n", - acpi_gbl_RSDP->rsdt_physical_address)); - - return (AE_BAD_SIGNATURE); - } - - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_get_table_pointer - * - * PARAMETERS: Physical_address - Address from RSDT - * Flags - virtual or physical addressing - * Table_ptr - Addressable address (output) - * - * RETURN: Status - * - * DESCRIPTION: Create an addressable pointer to an ACPI table - * - ******************************************************************************/ - -acpi_status -acpi_tb_get_table_pointer ( - ACPI_PHYSICAL_ADDRESS physical_address, - u32 flags, - u32 *size, - acpi_table_header **table_ptr) -{ - acpi_status status; - - - FUNCTION_ENTRY (); - - - if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { - *size = SIZE_IN_HEADER; - status = acpi_tb_map_acpi_table (physical_address, size, table_ptr); - } - - else { - *size = 0; - *table_ptr = (acpi_table_header *) (ACPI_TBLPTR) physical_address; - - status = AE_OK; - } - - return (status); -} - + switch (address->pointer_type) { + case ACPI_PHYSMODE_PHYSPTR: + case ACPI_LOGMODE_LOGPTR: -/******************************************************************************* - * - * FUNCTION: Acpi_tb_get_table_rsdt - * - * PARAMETERS: Number_of_tables - Where the table count is placed - * - * RETURN: Status - * - * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) - * - ******************************************************************************/ + /* Pointer matches processor mode, copy the table to a new buffer */ -acpi_status -acpi_tb_get_table_rsdt ( - u32 *number_of_tables) -{ - acpi_table_desc table_info; - acpi_status status; - ACPI_PHYSICAL_ADDRESS physical_address; + full_table = ACPI_MEM_ALLOCATE (header->length); + if (!full_table) { + ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n", + header->signature, header->length)); + return_ACPI_STATUS (AE_NO_MEMORY); + } + /* Copy the entire table (including header) to the local buffer */ - FUNCTION_TRACE ("Tb_get_table_rsdt"); + ACPI_MEMCPY (full_table, address->pointer.logical, header->length); + /* Save allocation type */ - /* - * Get the RSDT from the RSDP - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", - acpi_gbl_RSDP, HIDWORD(acpi_gbl_RSDP->rsdt_physical_address), - LODWORD(acpi_gbl_RSDP->rsdt_physical_address))); + allocation = ACPI_MEM_ALLOCATED; + break; - physical_address = acpi_tb_get_rsdt_address (); + case ACPI_LOGMODE_PHYSPTR: + /* + * Just map the table's physical memory + * into our address space. + */ + status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length, + (void *) &full_table); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n", + header->signature, + ACPI_HIDWORD (address->pointer.physical), + ACPI_LODWORD (address->pointer.physical), header->length)); + return (status); + } - /* Get the RSDT/XSDT */ + /* Save allocation type */ - status = acpi_tb_get_table (physical_address, NULL, &table_info); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT, %s\n", - acpi_format_exception (status))); - return_ACPI_STATUS (status); - } + allocation = ACPI_MEM_MAPPED; + break; - /* Check the RSDT or XSDT signature */ + default: - status = acpi_tb_validate_rsdt (table_info.pointer); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n", + address->pointer_type)); + return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* - * Valid RSDT signature, verify the checksum. If it fails, just - * print a warning and ignore it. + * Validate checksum for _most_ tables, + * even the ones whose signature we don't recognize */ - status = acpi_tb_verify_table_checksum (table_info.pointer); + if (table_info->type != ACPI_TABLE_FACS) { + status = acpi_tb_verify_table_checksum (full_table); +#if (!ACPI_CHECKSUM_ABORT) + if (ACPI_FAILURE (status)) { + /* Ignore the error if configuration says so */ - /* Convert and/or copy to an XSDT structure */ - - status = acpi_tb_convert_to_xsdt (&table_info, number_of_tables); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + status = AE_OK; + } +#endif } - /* Save the table pointers and allocation info */ - - status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + /* Return values */ - acpi_gbl_XSDT = (xsdt_descriptor *) table_info.pointer; + table_info->pointer = full_table; + table_info->length = (acpi_size) header->length; + table_info->allocation = allocation; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", + full_table->signature, + ACPI_HIDWORD (address->pointer.physical), + ACPI_LODWORD (address->pointer.physical), full_table)); return_ACPI_STATUS (status); } -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_tb_get_table_facs + * FUNCTION: acpi_tb_get_table_ptr * - * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from - * buffer rather than searching memory - * *Table_info - Where the table info is returned + * PARAMETERS: table_type - one of the defined table types + * Instance - Which table of this type + * table_ptr_loc - pointer to location to place the pointer for + * return * * RETURN: Status * - * DESCRIPTION: Returns a pointer to the FACS as defined in FADT. This - * function assumes the global variable FADT has been - * correctly initialized. The value of FADT->Firmware_ctrl - * into a far pointer which is returned. + * DESCRIPTION: This function is called to get the pointer to an ACPI table. * - *****************************************************************************/ + ******************************************************************************/ acpi_status -acpi_tb_get_table_facs ( - acpi_table_header *buffer_ptr, - acpi_table_desc *table_info) +acpi_tb_get_table_ptr ( + acpi_table_type table_type, + u32 instance, + struct acpi_table_header **table_ptr_loc) { - acpi_table_header *table_ptr = NULL; - u32 size; - u8 allocation; - acpi_status status = AE_OK; + struct acpi_table_desc *table_desc; + u32 i; - FUNCTION_TRACE ("Tb_get_table_facs"); + ACPI_FUNCTION_TRACE ("tb_get_table_ptr"); - /* Must have a valid FADT pointer */ - - if (!acpi_gbl_FADT) { + if (!acpi_gbl_DSDT) { return_ACPI_STATUS (AE_NO_ACPI_TABLES); } - size = sizeof (FACS_DESCRIPTOR); - if (buffer_ptr) { - /* - * Getting table from a file -- allocate a buffer and - * read the table. - */ - table_ptr = ACPI_MEM_ALLOCATE (size); - if(!table_ptr) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - MEMCPY (table_ptr, buffer_ptr, size); - - /* Save allocation type */ - - allocation = ACPI_MEM_ALLOCATED; + if (table_type > ACPI_TABLE_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); } - else { - /* Just map the physical memory to our address space */ + /* + * For all table types (Single/Multiple), the first + * instance is always in the list head. + */ + if (instance == 1) { + /* Get the first */ - status = acpi_tb_map_acpi_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl), - &size, &table_ptr); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + if (acpi_gbl_table_lists[table_type].next) { + *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer; } + return_ACPI_STATUS (AE_OK); + } - /* Save allocation type */ - - allocation = ACPI_MEM_MAPPED; + /* + * Check for instance out of range + */ + if (instance > acpi_gbl_table_lists[table_type].count) { + return_ACPI_STATUS (AE_NOT_EXIST); } + /* Walk the list to get the desired table + * Since the if (Instance == 1) check above checked for the + * first table, setting table_desc equal to the .Next member + * is actually pointing to the second table. Therefore, we + * need to walk from the 2nd table until we reach the Instance + * that the user is looking for and return its table pointer. + */ + table_desc = acpi_gbl_table_lists[table_type].next; + for (i = 2; i < instance; i++) { + table_desc = table_desc->next; + } - /* Return values */ + /* We are now pointing to the requested table's descriptor */ - table_info->pointer = table_ptr; - table_info->length = size; - table_info->allocation = allocation; - table_info->base_pointer = table_ptr; + *table_ptr_loc = table_desc->pointer; - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/tables/tbgetall.c linux-2.4.22/drivers/acpi/tables/tbgetall.c --- linux-2.4.21/drivers/acpi/tables/tbgetall.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/tables/tbgetall.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,314 @@ +/****************************************************************************** + * + * Module Name: tbgetall - Get all required ACPI tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include +#include + + +#define _COMPONENT ACPI_TABLES + ACPI_MODULE_NAME ("tbgetall") + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_primary_table + * + * PARAMETERS: Address - Physical address of table to retrieve + * *table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Maps the physical address of table into a logical address + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_primary_table ( + struct acpi_pointer *address, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + + ACPI_FUNCTION_TRACE ("tb_get_primary_table"); + + + /* Ignore a NULL address in the RSDT */ + + if (!address->pointer.value) { + return_ACPI_STATUS (AE_OK); + } + + /* + * Get the header in order to get signature and table size + */ + status = acpi_tb_get_table_header (address, &header); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Clear the table_info */ + + ACPI_MEMSET (table_info, 0, sizeof (struct acpi_table_desc)); + + /* + * Check the table signature and make sure it is recognized. + * Also checks the header checksum + */ + table_info->pointer = &header; + status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body (address, &header, table_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Install the table */ + + status = acpi_tb_install_table (table_info); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_secondary_table + * + * PARAMETERS: Address - Physical address of table to retrieve + * *table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Maps the physical address of table into a logical address + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_secondary_table ( + struct acpi_pointer *address, + acpi_string signature, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + + ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature); + + + /* Get the header in order to match the signature */ + + status = acpi_tb_get_table_header (address, &header); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Signature must match request */ + + if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) { + ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n", + signature, header.signature)); + return_ACPI_STATUS (AE_BAD_SIGNATURE); + } + + /* + * Check the table signature and make sure it is recognized. + * Also checks the header checksum + */ + table_info->pointer = &header; + status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body (address, &header, table_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Install the table */ + + status = acpi_tb_install_table (table_info); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_required_tables + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must + * already be loaded and validated. + * + * Get the minimum set of ACPI tables, namely: + * + * 1) FADT (via RSDT in loop below) + * 2) FACS (via FADT) + * 3) DSDT (via FADT) + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_required_tables ( + void) +{ + acpi_status status = AE_OK; + u32 i; + struct acpi_table_desc table_info; + struct acpi_pointer address; + + + ACPI_FUNCTION_TRACE ("tb_get_required_tables"); + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n", + acpi_gbl_rsdt_table_count)); + + + address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; + + /* + * Loop through all table pointers found in RSDT. + * This will NOT include the FACS and DSDT - we must get + * them after the loop. + * + * The only tables we are interested in getting here is the FADT and + * any SSDTs. + */ + for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { + /* Get the table address from the common internal XSDT */ + + address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i]; + + /* + * Get the tables needed by this subsystem (FADT and any SSDTs). + * NOTE: All other tables are completely ignored at this time. + */ + status = acpi_tb_get_primary_table (&address, &table_info); + if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { + ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n", + acpi_format_exception (status), + ACPI_HIDWORD (address.pointer.value), + ACPI_LODWORD (address.pointer.value))); + } + } + + /* We must have a FADT to continue */ + + if (!acpi_gbl_FADT) { + ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n")); + return_ACPI_STATUS (AE_NO_ACPI_TABLES); + } + + /* + * Convert the FADT to a common format. This allows earlier revisions of the + * table to coexist with newer versions, using common access code. + */ + status = acpi_tb_convert_table_fadt (); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n")); + return_ACPI_STATUS (status); + } + + /* + * Get the FACS (Pointed to by the FADT) + */ + address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl; + + status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n", + acpi_format_exception (status))); + return_ACPI_STATUS (status); + } + + /* + * Create the common FACS pointer table + * (Contains pointers to the original table) + */ + status = acpi_tb_build_common_facs (&table_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* + * Get/install the DSDT (Pointed to by the FADT) + */ + address.pointer.value = acpi_gbl_FADT->Xdsdt; + + status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not get/install the DSDT\n")); + return_ACPI_STATUS (status); + } + + /* Set Integer Width (32/64) based upon DSDT revision */ + + acpi_ut_set_integer_width (acpi_gbl_DSDT->revision); + + /* Dump the entire DSDT */ + + ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, + "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n", + acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width)); + ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length); + + /* Always delete the RSDP mapping, we are done with it */ + + acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP); + return_ACPI_STATUS (status); +} + + diff -urN linux-2.4.21/drivers/acpi/tables/tbinstal.c linux-2.4.22/drivers/acpi/tables/tbinstal.c --- linux-2.4.21/drivers/acpi/tables/tbinstal.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/tables/tbinstal.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,44 +1,118 @@ /****************************************************************************** * * Module Name: tbinstal - ACPI table installation and removal - * $Revision: 45 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES - MODULE_NAME ("tbinstal") + ACPI_MODULE_NAME ("tbinstal") /******************************************************************************* * - * FUNCTION: Acpi_tb_install_table + * FUNCTION: acpi_tb_match_signature * - * PARAMETERS: Table_ptr - Input buffer pointer, optional - * Table_info - Return value from Acpi_tb_get_table + * PARAMETERS: Signature - Table signature to match + * table_info - Return data + * + * RETURN: Status + * + * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" + * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match. + * + ******************************************************************************/ + +acpi_status +acpi_tb_match_signature ( + char *signature, + struct acpi_table_desc *table_info, + u8 search_type) +{ + acpi_native_uint i; + + + ACPI_FUNCTION_TRACE ("tb_match_signature"); + + + /* + * Search for a signature match among the known table types + */ + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { + if (!(acpi_gbl_table_data[i].flags & search_type)) { + continue; + } + + if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature, + acpi_gbl_table_data[i].sig_length)) { + /* Found a signature match, return index if requested */ + + if (table_info) { + table_info->type = (u8) i; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", + (char *) acpi_gbl_table_data[i].signature)); + + return_ACPI_STATUS (AE_OK); + } + } + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", + (char *) signature)); + + return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_install_table + * + * PARAMETERS: table_info - Return value from acpi_tb_get_table_body * * RETURN: Status * @@ -50,45 +124,43 @@ acpi_status acpi_tb_install_table ( - acpi_table_header *table_ptr, - acpi_table_desc *table_info) + struct acpi_table_desc *table_info) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Tb_install_table"); + ACPI_FUNCTION_TRACE ("tb_install_table"); - /* - * Check the table signature and make sure it is recognized - * Also checks the header checksum - */ - status = acpi_tb_recognize_table (table_ptr, table_info); + /* Lock tables while installing */ + + status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES); if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n", + table_info->pointer->signature, acpi_format_exception (status))); return_ACPI_STATUS (status); } - /* Lock tables while installing */ - - acpi_ut_acquire_mutex (ACPI_MTX_TABLES); - /* Install the table into the global data structure */ status = acpi_tb_init_table_descriptor (table_info->type, table_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n", + table_info->pointer->signature, acpi_format_exception (status))); + } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n", - acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer)); + acpi_gbl_table_data[table_info->type].name, table_info->pointer)); - acpi_ut_release_mutex (ACPI_MTX_TABLES); + (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_tb_recognize_table + * FUNCTION: acpi_tb_recognize_table * - * PARAMETERS: Table_ptr - Input buffer pointer, optional - * Table_info - Return value from Acpi_tb_get_table + * PARAMETERS: table_info - Return value from acpi_tb_get_table_body * * RETURN: Status * @@ -106,73 +178,44 @@ acpi_status acpi_tb_recognize_table ( - acpi_table_header *table_ptr, - acpi_table_desc *table_info) + struct acpi_table_desc *table_info, + u8 search_type) { - acpi_table_header *table_header; - acpi_status status; - acpi_table_type table_type = 0; - u32 i; + struct acpi_table_header *table_header; + acpi_status status; - FUNCTION_TRACE ("Tb_recognize_table"); + ACPI_FUNCTION_TRACE ("tb_recognize_table"); /* Ensure that we have a valid table pointer */ - table_header = (acpi_table_header *) table_info->pointer; + table_header = (struct acpi_table_header *) table_info->pointer; if (!table_header) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* - * Search for a signature match among the known table types - * Start at index one -> Skip the RSDP + * We only "recognize" a limited number of ACPI tables -- namely, the + * ones that are used by the subsystem (DSDT, FADT, etc.) + * + * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. + * This can be any one of many valid ACPI tables, it just isn't one of + * the tables that is consumed by the core subsystem */ - status = AE_SUPPORT; - for (i = 1; i < NUM_ACPI_TABLES; i++) { - if (!STRNCMP (table_header->signature, - acpi_gbl_acpi_table_data[i].signature, - acpi_gbl_acpi_table_data[i].sig_length)) { - /* - * Found a signature match, get the pertinent info from the - * Table_data structure - */ - table_type = i; - status = acpi_gbl_acpi_table_data[i].status; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Found %4.4s\n", - (char*)acpi_gbl_acpi_table_data[i].signature)); - break; - } + status = acpi_tb_match_signature (table_header->signature, table_info, search_type); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - /* Return the table type and length via the info struct */ - - table_info->type = (u8) table_type; - table_info->length = table_header->length; - - - /* - * Validate checksum for _most_ tables, - * even the ones whose signature we don't recognize - */ - if (table_type != ACPI_TABLE_FACS) { - /* But don't abort if the checksum is wrong */ - /* TBD: [Future] make this a configuration option? */ - - acpi_tb_verify_table_checksum (table_header); + status = acpi_tb_validate_table_header (table_header); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - /* - * An AE_SUPPORT means that the table was not recognized. - * We basically ignore this; just print a debug message - */ - if (status == AE_SUPPORT) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Unsupported table %s (Type %X) was found and discarded\n", - acpi_gbl_acpi_table_data[table_type].name, table_type)); - } + /* Return the table type and length via the info struct */ + + table_info->length = (acpi_size) table_header->length; return_ACPI_STATUS (status); } @@ -180,10 +223,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_tb_init_table_descriptor + * FUNCTION: acpi_tb_init_table_descriptor * - * PARAMETERS: Table_type - The type of the table - * Table_info - A table info struct + * PARAMETERS: table_type - The type of the table + * table_info - A table info struct * * RETURN: None. * @@ -193,94 +236,96 @@ acpi_status acpi_tb_init_table_descriptor ( - acpi_table_type table_type, - acpi_table_desc *table_info) + acpi_table_type table_type, + struct acpi_table_desc *table_info) { - acpi_table_desc *list_head; - acpi_table_desc *table_desc; + struct acpi_table_list *list_head; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type); - FUNCTION_TRACE_U32 ("Tb_init_table_descriptor", table_type); + + /* Allocate a descriptor for this table */ + + table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc)); + if (!table_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } /* * Install the table into the global data structure */ - list_head = &acpi_gbl_acpi_tables[table_type]; - table_desc = list_head; - + list_head = &acpi_gbl_table_lists[table_type]; /* * Two major types of tables: 1) Only one instance is allowed. This * includes most ACPI tables such as the DSDT. 2) Multiple instances of * the table are allowed. This includes SSDT and PSDTs. */ - if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) { + if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) { /* * Only one table allowed, and a table has alread been installed * at this location, so return an error. */ - if (list_head->pointer) { - return_ACPI_STATUS (AE_EXIST); + if (list_head->next) { + return_ACPI_STATUS (AE_ALREADY_EXISTS); } - table_desc->count = 1; - } + table_desc->next = list_head->next; + list_head->next = table_desc; + if (table_desc->next) { + table_desc->next->prev = table_desc; + } + list_head->count++; + } else { /* - * Multiple tables allowed for this table type, we must link - * the new table in to the list of tables of this type. + * Link the new table in to the list of tables of this type. + * Insert at the end of the list, order IS IMPORTANT. + * + * table_desc->Prev & Next are already NULL from calloc() */ - if (list_head->pointer) { - table_desc = ACPI_MEM_CALLOCATE (sizeof (acpi_table_desc)); - if (!table_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - list_head->count++; + list_head->count++; - /* Update the original previous */ - - list_head->prev->next = table_desc; - - /* Update new entry */ - - table_desc->prev = list_head->prev; - table_desc->next = list_head; - - /* Update list head */ - - list_head->prev = table_desc; + if (!list_head->next) { + list_head->next = table_desc; } - else { - table_desc->count = 1; + table_desc->next = list_head->next; + + while (table_desc->next->next) { + table_desc->next = table_desc->next->next; + } + + table_desc->next->next = table_desc; + table_desc->prev = table_desc->next; + table_desc->next = NULL; } } + /* Finish initialization of the table descriptor */ - /* Common initialization of the table descriptor */ - + table_desc->type = (u8) table_type; table_desc->pointer = table_info->pointer; - table_desc->base_pointer = table_info->base_pointer; table_desc->length = table_info->length; table_desc->allocation = table_info->allocation; table_desc->aml_start = (u8 *) (table_desc->pointer + 1), table_desc->aml_length = (u32) (table_desc->length - - (u32) sizeof (acpi_table_header)); - table_desc->table_id = acpi_ut_allocate_owner_id (OWNER_TYPE_TABLE); + (u32) sizeof (struct acpi_table_header)); + table_desc->table_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_TABLE); table_desc->loaded_into_namespace = FALSE; /* * Set the appropriate global pointer (if there is one) to point to the * newly installed table */ - if (acpi_gbl_acpi_table_data[table_type].global_ptr) { - *(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer; + if (acpi_gbl_table_data[table_type].global_ptr) { + *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer; } - /* Return Data */ table_info->table_id = table_desc->table_id; @@ -292,7 +337,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_tb_delete_acpi_tables + * FUNCTION: acpi_tb_delete_all_tables * * PARAMETERS: None. * @@ -303,25 +348,24 @@ ******************************************************************************/ void -acpi_tb_delete_acpi_tables (void) +acpi_tb_delete_all_tables (void) { - acpi_table_type type; + acpi_table_type type; /* * Free memory allocated for ACPI tables * Memory can either be mapped or allocated */ - for (type = 0; type < NUM_ACPI_TABLES; type++) { - acpi_tb_delete_acpi_table (type); + for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) { + acpi_tb_delete_tables_by_type (type); } - } /******************************************************************************* * - * FUNCTION: Acpi_tb_delete_acpi_table + * FUNCTION: acpi_tb_delete_tables_by_type * * PARAMETERS: Type - The table type to be deleted * @@ -333,23 +377,24 @@ ******************************************************************************/ void -acpi_tb_delete_acpi_table ( - acpi_table_type type) +acpi_tb_delete_tables_by_type ( + acpi_table_type type) { - FUNCTION_TRACE_U32 ("Tb_delete_acpi_table", type); + struct acpi_table_desc *table_desc; + u32 count; + u32 i; + + + ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type); if (type > ACPI_TABLE_MAX) { return_VOID; } - - acpi_ut_acquire_mutex (ACPI_MTX_TABLES); - - /* Free the table */ - - acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables[type]); - + if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_TABLES))) { + return; + } /* Clear the appropriate "typed" global table pointer */ @@ -380,41 +425,11 @@ break; } - acpi_ut_release_mutex (ACPI_MTX_TABLES); - - return_VOID; -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_free_acpi_tables_of_type - * - * PARAMETERS: Table_info - A table info struct - * - * RETURN: None. - * - * DESCRIPTION: Free the memory associated with an internal ACPI table - * Table mutex should be locked. - * - ******************************************************************************/ - -void -acpi_tb_free_acpi_tables_of_type ( - acpi_table_desc *list_head) -{ - acpi_table_desc *table_desc; - u32 count; - u32 i; - - - FUNCTION_TRACE_PTR ("Tb_free_acpi_tables_of_type", list_head); - - + /* Free the table */ /* Get the head of the list */ - table_desc = list_head; - count = list_head->count; + table_desc = acpi_gbl_table_lists[type].next; + count = acpi_gbl_table_lists[type].count; /* * Walk the entire list, deleting both the allocated tables @@ -424,15 +439,16 @@ table_desc = acpi_tb_uninstall_table (table_desc); } + (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_tb_delete_single_table + * FUNCTION: acpi_tb_delete_single_table * - * PARAMETERS: Table_info - A table info struct + * PARAMETERS: table_info - A table info struct * * RETURN: None. * @@ -443,44 +459,45 @@ void acpi_tb_delete_single_table ( - acpi_table_desc *table_desc) + struct acpi_table_desc *table_desc) { - if (!table_desc) { + /* Must have a valid table descriptor and pointer */ + + if ((!table_desc) || + (!table_desc->pointer)) { return; } - if (table_desc->pointer) { - /* Valid table, determine type of memory allocation */ - - switch (table_desc->allocation) { - - case ACPI_MEM_NOT_ALLOCATED: - break; + /* Valid table, determine type of memory allocation */ + switch (table_desc->allocation) { + case ACPI_MEM_NOT_ALLOCATED: + break; - case ACPI_MEM_ALLOCATED: + case ACPI_MEM_ALLOCATED: - ACPI_MEM_FREE (table_desc->base_pointer); - break; + ACPI_MEM_FREE (table_desc->pointer); + break; + case ACPI_MEM_MAPPED: - case ACPI_MEM_MAPPED: + acpi_os_unmap_memory (table_desc->pointer, table_desc->length); + break; - acpi_os_unmap_memory (table_desc->base_pointer, table_desc->length); - break; - } + default: + break; } } /******************************************************************************* * - * FUNCTION: Acpi_tb_uninstall_table + * FUNCTION: acpi_tb_uninstall_table * - * PARAMETERS: Table_info - A table info struct + * PARAMETERS: table_info - A table info struct * - * RETURN: None. + * RETURN: Pointer to the next table in the list (of same type) * * DESCRIPTION: Free the memory associated with an internal ACPI table that * is either installed or has never been installed. @@ -488,58 +505,45 @@ * ******************************************************************************/ -acpi_table_desc * +struct acpi_table_desc * acpi_tb_uninstall_table ( - acpi_table_desc *table_desc) + struct acpi_table_desc *table_desc) { - acpi_table_desc *next_desc; + struct acpi_table_desc *next_desc; - FUNCTION_TRACE_PTR ("Tb_delete_single_table", table_desc); + ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc); if (!table_desc) { return_PTR (NULL); } - - /* Unlink the descriptor */ + /* Unlink the descriptor from the doubly linked list */ if (table_desc->prev) { table_desc->prev->next = table_desc->next; } + else { + /* Is first on list, update list head */ + + acpi_gbl_table_lists[table_desc->type].next = table_desc->next; + } if (table_desc->next) { table_desc->next->prev = table_desc->prev; } - /* Free the memory allocated for the table itself */ acpi_tb_delete_single_table (table_desc); + /* Free the table descriptor */ - /* Free the table descriptor (Don't delete the list head, tho) */ - - if ((table_desc->prev) == (table_desc->next)) { - - next_desc = NULL; - - /* Clear the list head */ - - table_desc->pointer = NULL; - table_desc->length = 0; - table_desc->count = 0; - - } - - else { - /* Free the table descriptor */ - - next_desc = table_desc->next; - ACPI_MEM_FREE (table_desc); - } + next_desc = table_desc->next; + ACPI_MEM_FREE (table_desc); + /* Return pointer to the next descriptor */ return_PTR (next_desc); } diff -urN linux-2.4.21/drivers/acpi/tables/tbrsdt.c linux-2.4.22/drivers/acpi/tables/tbrsdt.c --- linux-2.4.21/drivers/acpi/tables/tbrsdt.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/tables/tbrsdt.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,315 @@ +/****************************************************************************** + * + * Module Name: tbrsdt - ACPI RSDT table utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include +#include + + +#define _COMPONENT ACPI_TABLES + ACPI_MODULE_NAME ("tbrsdt") + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_verify_rsdp + * + * PARAMETERS: Address - RSDP (Pointer to RSDT) + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +acpi_status +acpi_tb_verify_rsdp ( + struct acpi_pointer *address) +{ + struct acpi_table_desc table_info; + acpi_status status; + struct rsdp_descriptor *rsdp; + + + ACPI_FUNCTION_TRACE ("tb_verify_rsdp"); + + + switch (address->pointer_type) { + case ACPI_LOGICAL_POINTER: + + rsdp = address->pointer.logical; + break; + + case ACPI_PHYSICAL_POINTER: + /* + * Obtain access to the RSDP structure + */ + status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor), + (void *) &rsdp); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + break; + + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* + * The signature and checksum must both be correct + */ + if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { + /* Nope, BAD Signature */ + + status = AE_BAD_SIGNATURE; + goto cleanup; + } + + /* Check the standard checksum */ + + if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { + status = AE_BAD_CHECKSUM; + goto cleanup; + } + + /* Check extended checksum if table version >= 2 */ + + if (rsdp->revision >= 2) { + if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) { + status = AE_BAD_CHECKSUM; + goto cleanup; + } + } + + /* The RSDP supplied is OK */ + + table_info.pointer = ACPI_CAST_PTR (struct acpi_table_header, rsdp); + table_info.length = sizeof (struct rsdp_descriptor); + table_info.allocation = ACPI_MEM_MAPPED; + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* Save the RSDP in a global for easy access */ + + acpi_gbl_RSDP = ACPI_CAST_PTR (struct rsdp_descriptor, table_info.pointer); + return_ACPI_STATUS (status); + + + /* Error exit */ +cleanup: + + if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { + acpi_os_unmap_memory (rsdp, sizeof (struct rsdp_descriptor)); + } + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_rsdt_address + * + * PARAMETERS: None + * + * RETURN: RSDT physical address + * + * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the + * version of the RSDP + * + ******************************************************************************/ + +void +acpi_tb_get_rsdt_address ( + struct acpi_pointer *out_address) +{ + + ACPI_FUNCTION_ENTRY (); + + + out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; + + /* + * For RSDP revision 0 or 1, we use the RSDT. + * For RSDP revision 2 (and above), we use the XSDT + */ + if (acpi_gbl_RSDP->revision < 2) { + out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address; + } + else { + out_address->pointer.value = acpi_gbl_RSDP->xsdt_physical_address; + } +} + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_validate_rsdt + * + * PARAMETERS: table_ptr - Addressable pointer to the RSDT. + * + * RETURN: Status + * + * DESCRIPTION: Validate signature for the RSDT or XSDT + * + ******************************************************************************/ + +acpi_status +acpi_tb_validate_rsdt ( + struct acpi_table_header *table_ptr) +{ + int no_match; + + + ACPI_FUNCTION_NAME ("tb_validate_rsdt"); + + + /* + * For RSDP revision 0 or 1, we use the RSDT. + * For RSDP revision 2 and above, we use the XSDT + */ + if (acpi_gbl_RSDP->revision < 2) { + no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG, + sizeof (RSDT_SIG) -1); + } + else { + no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG, + sizeof (XSDT_SIG) -1); + } + + if (no_match) { + /* Invalid RSDT or XSDT signature */ + + ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n")); + + ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20); + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, + "RSDT/XSDT signature at %X (%p) is invalid\n", + acpi_gbl_RSDP->rsdt_physical_address, + (void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address)); + + return (AE_BAD_SIGNATURE); + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_rsdt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table_rsdt ( + void) +{ + struct acpi_table_desc table_info; + acpi_status status; + struct acpi_pointer address; + + + ACPI_FUNCTION_TRACE ("tb_get_table_rsdt"); + + + /* Get the RSDT/XSDT via the RSDP */ + + acpi_tb_get_rsdt_address (&address); + + status = acpi_tb_get_table (&address, &table_info); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n", + acpi_format_exception (status))); + return_ACPI_STATUS (status); + } + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n", + acpi_gbl_RSDP, + ACPI_HIDWORD (address.pointer.value), + ACPI_LODWORD (address.pointer.value))); + + /* Check the RSDT or XSDT signature */ + + status = acpi_tb_validate_rsdt (table_info.pointer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Get the number of tables defined in the RSDT or XSDT */ + + acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer); + + /* Convert and/or copy to an XSDT structure */ + + status = acpi_tb_convert_to_xsdt (&table_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + acpi_gbl_XSDT = (XSDT_DESCRIPTOR *) table_info.pointer; + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); + return_ACPI_STATUS (status); +} + + diff -urN linux-2.4.21/drivers/acpi/tables/tbutils.c linux-2.4.22/drivers/acpi/tables/tbutils.c --- linux-2.4.21/drivers/acpi/tables/tbutils.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/tables/tbutils.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,162 +1,102 @@ /****************************************************************************** * * Module Name: tbutils - Table manipulation utilities - * $Revision: 42 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "actables.h" -#include "acinterp.h" +#include +#include #define _COMPONENT ACPI_TABLES - MODULE_NAME ("tbutils") + ACPI_MODULE_NAME ("tbutils") /******************************************************************************* * - * FUNCTION: Acpi_tb_handle_to_object + * FUNCTION: acpi_tb_handle_to_object * - * PARAMETERS: Table_id - Id for which the function is searching - * Table_desc - Pointer to return the matching table + * PARAMETERS: table_id - Id for which the function is searching + * table_desc - Pointer to return the matching table * descriptor. * - * RETURN: Search the tables to find one with a matching Table_id and + * RETURN: Search the tables to find one with a matching table_id and * return a pointer to that table descriptor. * ******************************************************************************/ acpi_status acpi_tb_handle_to_object ( - u16 table_id, - acpi_table_desc **table_desc) + u16 table_id, + struct acpi_table_desc **return_table_desc) { - u32 i; - acpi_table_desc *list_head; + u32 i; + struct acpi_table_desc *table_desc; - PROC_NAME ("Tb_handle_to_object"); + ACPI_FUNCTION_NAME ("tb_handle_to_object"); for (i = 0; i < ACPI_TABLE_MAX; i++) { - list_head = &acpi_gbl_acpi_tables[i]; - do { - if (list_head->table_id == table_id) { - *table_desc = list_head; + table_desc = acpi_gbl_table_lists[i].next; + while (table_desc) { + if (table_desc->table_id == table_id) { + *return_table_desc = table_desc; return (AE_OK); } - list_head = list_head->next; - - } while (list_head != &acpi_gbl_acpi_tables[i]); - } - - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Table_id=%X does not exist\n", table_id)); - return (AE_BAD_PARAMETER); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_system_table_pointer - * - * PARAMETERS: *Where - Pointer to be examined - * - * RETURN: TRUE if Where is within the AML stream (in one of the ACPI - * system tables such as the DSDT or an SSDT.) - * FALSE otherwise - * - ******************************************************************************/ - -u8 -acpi_tb_system_table_pointer ( - void *where) -{ - u32 i; - acpi_table_desc *table_desc; - acpi_table_header *table; - - - /* No function trace, called too often! */ - - - /* Ignore null pointer */ - - if (!where) { - return (FALSE); - } - - - /* Check for a pointer within the DSDT */ - - if ((acpi_gbl_DSDT) && - (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT))) { - return (TRUE); - } - - - /* Check each of the loaded SSDTs (if any)*/ - - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT]; - - for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) { - table = table_desc->pointer; - - if (IS_IN_ACPI_TABLE (where, table)) { - return (TRUE); + table_desc = table_desc->next; } - - table_desc = table_desc->next; } - - /* Check each of the loaded PSDTs (if any)*/ - - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT]; - - for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) { - table = table_desc->pointer; - - if (IS_IN_ACPI_TABLE (where, table)) { - return (TRUE); - } - - table_desc = table_desc->next; - } - - - /* Pointer does not point into any system table */ - - return (FALSE); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id)); + return (AE_BAD_PARAMETER); } /******************************************************************************* * - * FUNCTION: Acpi_tb_validate_table_header + * FUNCTION: acpi_tb_validate_table_header * - * PARAMETERS: Table_header - Logical pointer to the table + * PARAMETERS: table_header - Logical pointer to the table * * RETURN: Status * @@ -168,52 +108,52 @@ * name * 3) Table must be readable for length specified in the header * 4) Table checksum must be valid (with the exception of the FACS - * which has no checksum for some odd reason) + * which has no checksum because it contains variable fields) * ******************************************************************************/ acpi_status acpi_tb_validate_table_header ( - acpi_table_header *table_header) + struct acpi_table_header *table_header) { - acpi_name signature; + acpi_name signature; - PROC_NAME ("Tb_validate_table_header"); + ACPI_FUNCTION_NAME ("tb_validate_table_header"); /* Verify that this is a valid address */ - if (!acpi_os_readable (table_header, sizeof (acpi_table_header))) { + if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Cannot read table header at %p\n", table_header)); return (AE_BAD_ADDRESS); } - /* Ensure that the signature is 4 ASCII characters */ - MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature); + ACPI_MOVE_32_TO_32 (&signature, table_header->signature); if (!acpi_ut_valid_acpi_name (signature)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Table signature at %p [%p] has invalid characters\n", table_header, &signature)); - REPORT_WARNING (("Invalid table signature %4.4s found\n", (char*)&signature)); - DUMP_BUFFER (table_header, sizeof (acpi_table_header)); + ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n", + (char *) &signature)); + ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header)); return (AE_BAD_SIGNATURE); } - /* Validate the table length */ - if (table_header->length < sizeof (acpi_table_header)) { + if (table_header->length < sizeof (struct acpi_table_header)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid length in table header %p name %4.4s\n", - table_header, (char*)&signature)); + table_header, (char *) &signature)); - REPORT_WARNING (("Invalid table header length found\n")); - DUMP_BUFFER (table_header, sizeof (acpi_table_header)); + ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n", + (u32) table_header->length)); + ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header)); return (AE_BAD_HEADER); } @@ -223,90 +163,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_tb_map_acpi_table - * - * PARAMETERS: Physical_address - Physical address of table to map - * *Size - Size of the table. If zero, the size - * from the table header is used. - * Actual size is returned here. - * **Logical_address - Logical address of mapped table - * - * RETURN: Logical address of the mapped table. - * - * DESCRIPTION: Maps the physical address of table into a logical address - * - ******************************************************************************/ - -acpi_status -acpi_tb_map_acpi_table ( - ACPI_PHYSICAL_ADDRESS physical_address, - u32 *size, - acpi_table_header **logical_address) -{ - acpi_table_header *table; - u32 table_size = *size; - acpi_status status = AE_OK; - - - PROC_NAME ("Tb_map_acpi_table"); - - - /* If size is zero, look at the table header to get the actual size */ - - if ((*size) == 0) { - /* Get the table header so we can extract the table length */ - - status = acpi_os_map_memory (physical_address, sizeof (acpi_table_header), - (void **) &table); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Extract the full table length before we delete the mapping */ - - table_size = table->length; - - /* - * Validate the header and delete the mapping. - * We will create a mapping for the full table below. - */ - status = acpi_tb_validate_table_header (table); - - /* Always unmap the memory for the header */ - - acpi_os_unmap_memory (table, sizeof (acpi_table_header)); - - /* Exit if header invalid */ - - if (ACPI_FAILURE (status)) { - return (status); - } - } - - - /* Map the physical memory for the correct length */ - - status = acpi_os_map_memory (physical_address, table_size, (void **) &table); - if (ACPI_FAILURE (status)) { - return (status); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Mapped memory for ACPI table, length=%d(%X) at %p\n", - table_size, table_size, table)); - - *size = table_size; - *logical_address = table; - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_verify_table_checksum + * FUNCTION: acpi_tb_verify_table_checksum * - * PARAMETERS: *Table_header - ACPI table to verify + * PARAMETERS: *table_header - ACPI table to verify * * RETURN: 8 bit checksum of table * @@ -317,13 +176,13 @@ acpi_status acpi_tb_verify_table_checksum ( - acpi_table_header *table_header) + struct acpi_table_header *table_header) { - u8 checksum; - acpi_status status = AE_OK; + u8 checksum; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Tb_verify_table_checksum"); + ACPI_FUNCTION_TRACE ("tb_verify_table_checksum"); /* Compute the checksum on the table */ @@ -333,20 +192,18 @@ /* Return the appropriate exception */ if (checksum) { - REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n", - checksum, (char*)&table_header->signature)); + ACPI_REPORT_WARNING (("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n", + table_header->signature, (u32) table_header->checksum, (u32) checksum)); status = AE_BAD_CHECKSUM; } - - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_tb_checksum + * FUNCTION: acpi_tb_checksum * * PARAMETERS: Buffer - Buffer to checksum * Length - Size of the buffer @@ -359,12 +216,12 @@ u8 acpi_tb_checksum ( - void *buffer, - u32 length) + void *buffer, + u32 length) { - u8 *limit; - u8 *rover; - u8 sum = 0; + const u8 *limit; + const u8 *rover; + u8 sum = 0; if (buffer && length) { @@ -376,7 +233,6 @@ sum = (u8) (sum + *rover); } } - return (sum); } diff -urN linux-2.4.21/drivers/acpi/tables/tbxface.c linux-2.4.22/drivers/acpi/tables/tbxface.c --- linux-2.4.21/drivers/acpi/tables/tbxface.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/tables/tbxface.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,42 +2,59 @@ * * Module Name: tbxface - Public interfaces to the ACPI subsystem * ACPI table oriented interfaces - * $Revision: 45 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "actables.h" +#include +#include +#include #define _COMPONENT ACPI_TABLES - MODULE_NAME ("tbxface") + ACPI_MODULE_NAME ("tbxface") /******************************************************************************* * - * FUNCTION: Acpi_load_tables + * FUNCTION: acpi_load_tables * * PARAMETERS: None * @@ -51,59 +68,60 @@ acpi_status acpi_load_tables (void) { - ACPI_PHYSICAL_ADDRESS rsdp_physical_address; - acpi_status status; - u32 number_of_tables = 0; + struct acpi_pointer rsdp_address; + acpi_status status; - FUNCTION_TRACE ("Acpi_load_tables"); + ACPI_FUNCTION_TRACE ("acpi_load_tables"); /* Get the RSDP */ status = acpi_os_get_root_pointer (ACPI_LOGICAL_ADDRESSING, - &rsdp_physical_address); + &rsdp_address); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("Acpi_load_tables: Could not get RSDP, %s\n", + ACPI_REPORT_ERROR (("acpi_load_tables: Could not get RSDP, %s\n", acpi_format_exception (status))); goto error_exit; } /* Map and validate the RSDP */ - status = acpi_tb_verify_rsdp (rsdp_physical_address); + acpi_gbl_table_flags = rsdp_address.pointer_type; + + status = acpi_tb_verify_rsdp (&rsdp_address); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("Acpi_load_tables: RSDP Failed validation: %s\n", + ACPI_REPORT_ERROR (("acpi_load_tables: RSDP Failed validation: %s\n", acpi_format_exception (status))); goto error_exit; } /* Get the RSDT via the RSDP */ - status = acpi_tb_get_table_rsdt (&number_of_tables); + status = acpi_tb_get_table_rsdt (); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("Acpi_load_tables: Could not load RSDT: %s\n", + ACPI_REPORT_ERROR (("acpi_load_tables: Could not load RSDT: %s\n", acpi_format_exception (status))); goto error_exit; } - /* Now get the rest of the tables */ + /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ - status = acpi_tb_get_all_tables (number_of_tables, NULL); + status = acpi_tb_get_required_tables (); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("Acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n", + ACPI_REPORT_ERROR (("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n", acpi_format_exception (status))); goto error_exit; } - ACPI_DEBUG_PRINT ((ACPI_DB_OK, "ACPI Tables successfully loaded\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); /* Load the namespace from the tables */ status = acpi_ns_load_namespace (); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("Acpi_load_tables: Could not load namespace: %s\n", + ACPI_REPORT_ERROR (("acpi_load_tables: Could not load namespace: %s\n", acpi_format_exception (status))); goto error_exit; } @@ -112,7 +130,7 @@ error_exit: - REPORT_ERROR (("Acpi_load_tables: Could not load tables: %s\n", + ACPI_REPORT_ERROR (("acpi_load_tables: Could not load tables: %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); @@ -121,9 +139,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_load_table + * FUNCTION: acpi_load_table * - * PARAMETERS: Table_ptr - pointer to a buffer containing the entire + * PARAMETERS: table_ptr - pointer to a buffer containing the entire * table to be loaded * * RETURN: Status @@ -137,13 +155,14 @@ acpi_status acpi_load_table ( - acpi_table_header *table_ptr) + struct acpi_table_header *table_ptr) { - acpi_status status; - acpi_table_desc table_info; + acpi_status status; + struct acpi_table_desc table_info; + struct acpi_pointer address; - FUNCTION_TRACE ("Acpi_load_table"); + ACPI_FUNCTION_TRACE ("acpi_load_table"); if (!table_ptr) { @@ -152,40 +171,59 @@ /* Copy the table to a local buffer */ - status = acpi_tb_get_table (0, table_ptr, &table_info); + address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; + address.pointer.logical = table_ptr; + + status = acpi_tb_get_table_body (&address, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the new table into the local data structures */ - status = acpi_tb_install_table (NULL, &table_info); + status = acpi_tb_install_table (&table_info); if (ACPI_FAILURE (status)) { - /* Free table allocated by Acpi_tb_get_table */ + /* Free table allocated by acpi_tb_get_table_body */ acpi_tb_delete_single_table (&table_info); return_ACPI_STATUS (status); } + /* Convert the table to common format if necessary */ + + switch (table_info.type) { + case ACPI_TABLE_FADT: + + status = acpi_tb_convert_table_fadt (); + break; + + case ACPI_TABLE_FACS: + + status = acpi_tb_build_common_facs (&table_info); + break; + + default: + /* Load table into namespace if it contains executable AML */ + + status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); + break; + } - status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); if (ACPI_FAILURE (status)) { /* Uninstall table and free the buffer */ - acpi_tb_uninstall_table (table_info.installed_desc); - return_ACPI_STATUS (status); + (void) acpi_tb_uninstall_table (table_info.installed_desc); } - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_unload_table + * FUNCTION: acpi_unload_table * - * PARAMETERS: Table_type - Type of table to be unloaded + * PARAMETERS: table_type - Type of table to be unloaded * * RETURN: Status * @@ -195,12 +233,12 @@ acpi_status acpi_unload_table ( - acpi_table_type table_type) + acpi_table_type table_type) { - acpi_table_desc *list_head; + struct acpi_table_desc *table_desc; - FUNCTION_TRACE ("Acpi_unload_table"); + ACPI_FUNCTION_TRACE ("acpi_unload_table"); /* Parameter validation */ @@ -212,39 +250,39 @@ /* Find all tables of the requested type */ - list_head = &acpi_gbl_acpi_tables[table_type]; - do { + table_desc = acpi_gbl_table_lists[table_type].next; + while (table_desc); { /* * Delete all namespace entries owned by this table. Note that these * entries can appear anywhere in the namespace by virtue of the AML * "Scope" operator. Thus, we need to track ownership by an ID, not * simply a position within the hierarchy */ - acpi_ns_delete_namespace_by_owner (list_head->table_id); - - /* Delete (or unmap) the actual table */ + acpi_ns_delete_namespace_by_owner (table_desc->table_id); - acpi_tb_delete_acpi_table (table_type); + table_desc = table_desc->next; + } - } while (list_head != &acpi_gbl_acpi_tables[table_type]); + /* Delete (or unmap) all tables of this type */ + acpi_tb_delete_tables_by_type (table_type); return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_get_table_header + * FUNCTION: acpi_get_table_header * - * PARAMETERS: Table_type - one of the defined table types + * PARAMETERS: table_type - one of the defined table types * Instance - the non zero instance of the table, allows * support for multiple tables of the same type - * see Acpi_gbl_Acpi_table_flag - * Out_table_header - pointer to the acpi_table_header if successful + * see acpi_gbl_acpi_table_flag + * out_table_header - pointer to the struct acpi_table_header if successful * * DESCRIPTION: This function is called to get an ACPI table header. The caller * supplies an pointer to a data area sufficient to contain an ACPI - * acpi_table_header structure. + * struct acpi_table_header structure. * * The header contains a length field that can be used to determine * the size of the buffer needed to contain the entire table. This @@ -255,15 +293,15 @@ acpi_status acpi_get_table_header ( - acpi_table_type table_type, - u32 instance, - acpi_table_header *out_table_header) + acpi_table_type table_type, + u32 instance, + struct acpi_table_header *out_table_header) { - acpi_table_header *tbl_ptr; - acpi_status status; + struct acpi_table_header *tbl_ptr; + acpi_status status; - FUNCTION_TRACE ("Acpi_get_table_header"); + ACPI_FUNCTION_TRACE ("acpi_get_table_header"); if ((instance == 0) || @@ -275,7 +313,7 @@ /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || - (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) && + (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -298,8 +336,8 @@ /* * Copy the header to the caller's buffer */ - MEMCPY ((void *) out_table_header, (void *) tbl_ptr, - sizeof (acpi_table_header)); + ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr, + sizeof (struct acpi_table_header)); return_ACPI_STATUS (status); } @@ -307,54 +345,56 @@ /******************************************************************************* * - * FUNCTION: Acpi_get_table + * FUNCTION: acpi_get_table * - * PARAMETERS: Table_type - one of the defined table types + * PARAMETERS: table_type - one of the defined table types * Instance - the non zero instance of the table, allows * support for multiple tables of the same type - * see Acpi_gbl_Acpi_table_flag - * Ret_buffer - pointer to a structure containing a buffer to + * see acpi_gbl_acpi_table_flag + * ret_buffer - pointer to a structure containing a buffer to * receive the table * * RETURN: Status * * DESCRIPTION: This function is called to get an ACPI table. The caller - * supplies an Out_buffer large enough to contain the entire ACPI - * table. The caller should call the Acpi_get_table_header function + * supplies an out_buffer large enough to contain the entire ACPI + * table. The caller should call the acpi_get_table_header function * first to determine the buffer size needed. Upon completion - * the Out_buffer->Length field will indicate the number of bytes - * copied into the Out_buffer->Buf_ptr buffer. This table will be + * the out_buffer->Length field will indicate the number of bytes + * copied into the out_buffer->buf_ptr buffer. This table will be * a complete table including the header. * ******************************************************************************/ acpi_status acpi_get_table ( - acpi_table_type table_type, - u32 instance, - acpi_buffer *ret_buffer) + acpi_table_type table_type, + u32 instance, + struct acpi_buffer *ret_buffer) { - acpi_table_header *tbl_ptr; - acpi_status status; - u32 ret_buf_len; + struct acpi_table_header *tbl_ptr; + acpi_status status; + acpi_size table_length; - FUNCTION_TRACE ("Acpi_get_table"); + ACPI_FUNCTION_TRACE ("acpi_get_table"); - /* - * If we have a buffer, we must have a length too - */ - if ((instance == 0) || - (!ret_buffer) || - ((!ret_buffer->pointer) && (ret_buffer->length))) { + /* Parameter validation */ + + if (instance == 0) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_ut_validate_buffer (ret_buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || - (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) && + (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -368,38 +408,35 @@ } /* - * Acpi_tb_get_table_ptr will return a NULL pointer if the + * acpi_tb_get_table_ptr will return a NULL pointer if the * table is not loaded. */ if (tbl_ptr == NULL) { return_ACPI_STATUS (AE_NOT_EXIST); } - /* - * Got a table ptr, assume it's ok and copy it to the user's buffer - */ + /* Get the table length */ + if (table_type == ACPI_TABLE_RSDP) { /* * RSD PTR is the only "table" without a header */ - ret_buf_len = sizeof (RSDP_DESCRIPTOR); + table_length = sizeof (struct rsdp_descriptor); } else { - ret_buf_len = tbl_ptr->length; + table_length = (acpi_size) tbl_ptr->length; } - /* - * Verify we have space in the caller's buffer for the table - */ - if (ret_buffer->length < ret_buf_len) { - ret_buffer->length = ret_buf_len; - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); - } + /* Validate/Allocate/Clear caller buffer */ - ret_buffer->length = ret_buf_len; + status = acpi_ut_initialize_buffer (ret_buffer, table_length); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, ret_buf_len); + /* Copy the table to the buffer */ + ACPI_MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, table_length); return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.21/drivers/acpi/tables/tbxfroot.c linux-2.4.22/drivers/acpi/tables/tbxfroot.c --- linux-2.4.21/drivers/acpi/tables/tbxfroot.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/tables/tbxfroot.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,46 +1,302 @@ /****************************************************************************** * * Module Name: tbxfroot - Find the root ACPI table (RSDT) - * $Revision: 52 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "actables.h" +#include +#include #define _COMPONENT ACPI_TABLES - MODULE_NAME ("tbxfroot") + ACPI_MODULE_NAME ("tbxfroot") -#define RSDP_CHECKSUM_LENGTH 20 + +/******************************************************************************* + * + * FUNCTION: acpi_tb_find_table + * + * PARAMETERS: Signature - String with ACPI table signature + * oem_id - String with the table OEM ID + * oem_table_id - String with the OEM Table ID. + * + * RETURN: Status + * + * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the + * Signature, OEM ID and OEM Table ID. + * + ******************************************************************************/ + +acpi_status +acpi_tb_find_table ( + char *signature, + char *oem_id, + char *oem_table_id, + struct acpi_table_header **table_ptr) +{ + acpi_status status; + struct acpi_table_header *table; + + + ACPI_FUNCTION_TRACE ("tb_find_table"); + + + /* Validate string lengths */ + + if ((ACPI_STRLEN (signature) > ACPI_NAME_SIZE) || + (ACPI_STRLEN (oem_id) > sizeof (table->oem_id)) || + (ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) { + return_ACPI_STATUS (AE_AML_STRING_LIMIT); + } + + /* Find the table */ + + status = acpi_get_firmware_table (signature, 1, + ACPI_LOGICAL_ADDRESSING, &table); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Check oem_id and oem_table_id */ + + if ((oem_id[0] && ACPI_STRCMP (oem_id, table->oem_id)) || + (oem_table_id[0] && ACPI_STRCMP (oem_table_id, table->oem_table_id))) { + return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND); + } + + *table_ptr = table; + return_ACPI_STATUS (AE_OK); +} /******************************************************************************* * - * FUNCTION: Acpi_find_root_pointer + * FUNCTION: acpi_get_firmware_table * - * PARAMETERS: **Rsdp_physical_address - Where to place the RSDP address - * Flags - Logical/Physical addressing + * PARAMETERS: Signature - Any ACPI table signature + * Instance - the non zero instance of the table, allows + * support for multiple tables of the same type + * Flags - Physical/Virtual support + * ret_buffer - pointer to a structure containing a buffer to + * receive the table + * + * RETURN: Status + * + * DESCRIPTION: This function is called to get an ACPI table. The caller + * supplies an out_buffer large enough to contain the entire ACPI + * table. Upon completion + * the out_buffer->Length field will indicate the number of bytes + * copied into the out_buffer->buf_ptr buffer. This table will be + * a complete table including the header. + * + ******************************************************************************/ + +acpi_status +acpi_get_firmware_table ( + acpi_string signature, + u32 instance, + u32 flags, + struct acpi_table_header **table_pointer) +{ + struct acpi_pointer rsdp_address; + struct acpi_pointer address; + acpi_status status; + struct acpi_table_header header; + struct acpi_table_desc table_info; + struct acpi_table_desc rsdt_info; + u32 table_count; + u32 i; + u32 j; + + + ACPI_FUNCTION_TRACE ("acpi_get_firmware_table"); + + + /* + * Ensure that at least the table manager is initialized. We don't + * require that the entire ACPI subsystem is up for this interface + */ + + /* + * If we have a buffer, we must have a length too + */ + if ((instance == 0) || + (!signature) || + (!table_pointer)) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + rsdt_info.pointer = NULL; + + if (!acpi_gbl_RSDP) { + /* Get the RSDP */ + + status = acpi_os_get_root_pointer (flags, &rsdp_address); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); + return_ACPI_STATUS (AE_NO_ACPI_TABLES); + } + + /* Map and validate the RSDP */ + + if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { + status = acpi_os_map_memory (rsdp_address.pointer.physical, sizeof (struct rsdp_descriptor), + (void *) &acpi_gbl_RSDP); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + else { + acpi_gbl_RSDP = rsdp_address.pointer.logical; + } + + /* + * The signature and checksum must both be correct + */ + if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { + /* Nope, BAD Signature */ + + return_ACPI_STATUS (AE_BAD_SIGNATURE); + } + + if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { + /* Nope, BAD Checksum */ + + return_ACPI_STATUS (AE_BAD_CHECKSUM); + } + } + + /* Get the RSDT and validate it */ + + acpi_tb_get_rsdt_address (&address); + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", + acpi_gbl_RSDP, + ACPI_HIDWORD (address.pointer.value), + ACPI_LODWORD (address.pointer.value))); + + /* Insert processor_mode flags */ + + address.pointer_type |= flags; + + status = acpi_tb_get_table (&address, &rsdt_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_tb_validate_rsdt (rsdt_info.pointer); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* Get the number of table pointers within the RSDT */ + + table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info.pointer); + + address.pointer_type = acpi_gbl_table_flags | flags; + + /* + * Search the RSDT/XSDT for the correct instance of the + * requested table + */ + for (i = 0, j = 0; i < table_count; i++) { + /* Get the next table pointer, handle RSDT vs. XSDT */ + + if (acpi_gbl_RSDP->revision < 2) { + address.pointer.value = ((RSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i]; + } + else { + address.pointer.value = + ((XSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i]; + } + + /* Get the table header */ + + status = acpi_tb_get_table_header (&address, &header); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* Compare table signatures and table instance */ + + if (!ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) { + /* An instance of the table was found */ + + j++; + if (j >= instance) { + /* Found the correct instance, get the entire table */ + + status = acpi_tb_get_table_body (&address, &header, &table_info); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + *table_pointer = table_info.pointer; + goto cleanup; + } + } + } + + /* Did not find the table */ + + status = AE_NOT_EXIST; + + +cleanup: + acpi_os_unmap_memory (rsdt_info.pointer, (acpi_size) rsdt_info.pointer->length); + return_ACPI_STATUS (status); +} + + +/* TBD: Move to a new file */ + +#if ACPI_MACHINE_WIDTH != 16 + +/******************************************************************************* + * + * FUNCTION: acpi_find_root_pointer + * + * PARAMETERS: **rsdp_address - Where to place the RSDP address + * Flags - Logical/Physical addressing * * RETURN: Status, Physical address of the RSDP * @@ -50,35 +306,36 @@ acpi_status acpi_find_root_pointer ( - u32 flags, - ACPI_PHYSICAL_ADDRESS *rsdp_physical_address) + u32 flags, + struct acpi_pointer *rsdp_address) { - acpi_table_desc table_info; - acpi_status status; + struct acpi_table_desc table_info; + acpi_status status; - FUNCTION_TRACE ("Acpi_find_root_pointer"); + ACPI_FUNCTION_TRACE ("acpi_find_root_pointer"); /* Get the RSDP */ status = acpi_tb_find_rsdp (&table_info, flags); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "RSDP structure not found\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "RSDP structure not found, %s Flags=%X\n", + acpi_format_exception (status), flags)); return_ACPI_STATUS (AE_NO_ACPI_TABLES); } - *rsdp_physical_address = table_info.physical_address; - + rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; + rsdp_address->pointer.physical = table_info.physical_address; return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_tb_scan_memory_for_rsdp + * FUNCTION: acpi_tb_scan_memory_for_rsdp * - * PARAMETERS: Start_address - Starting pointer for search + * PARAMETERS: start_address - Starting pointer for search * Length - Maximum length to search * * RETURN: Pointer to the RSDP if found, otherwise NULL. @@ -89,27 +346,27 @@ u8 * acpi_tb_scan_memory_for_rsdp ( - u8 *start_address, - u32 length) + u8 *start_address, + u32 length) { - u32 offset; - u8 *mem_rover; + u32 offset; + u8 *mem_rover; - FUNCTION_TRACE ("Tb_scan_memory_for_rsdp"); + ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); /* Search from given start addr for the requested length */ for (offset = 0, mem_rover = start_address; offset < length; - offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) { + offset += ACPI_RSDP_SCAN_STEP, mem_rover += ACPI_RSDP_SCAN_STEP) { /* The signature and checksum must both be correct */ - if (STRNCMP ((NATIVE_CHAR *) mem_rover, + if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 && - acpi_tb_checksum (mem_rover, RSDP_CHECKSUM_LENGTH) == 0) { + acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH) == 0) { /* If so, we have found the RSDP */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, @@ -121,25 +378,24 @@ /* Searched entire block, no RSDP was found */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,"Searched entire block, no RSDP was found.\n")); - return_PTR (NULL); } /******************************************************************************* * - * FUNCTION: Acpi_tb_find_rsdp + * FUNCTION: acpi_tb_find_rsdp * - * PARAMETERS: *Table_info - Where the table info is returned + * PARAMETERS: *table_info - Where the table info is returned * Flags - Current memory mode (logical vs. * physical addressing) * * RETURN: Status * - * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor + * DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor * pointer structure. If it is found, set *RSDP to point to it. * - * NOTE: The RSDP must be either in the first 1_k of the Extended + * NOTE: The RSDp must be either in the first 1_k of the Extended * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section * 5.2.2; assertion #421). * @@ -147,16 +403,16 @@ acpi_status acpi_tb_find_rsdp ( - acpi_table_desc *table_info, - u32 flags) + struct acpi_table_desc *table_info, + u32 flags) { - u8 *table_ptr; - u8 *mem_rover; - u64 phys_addr; - acpi_status status = AE_OK; + u8 *table_ptr; + u8 *mem_rover; + u64 phys_addr; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Tb_find_rsdp"); + ACPI_FUNCTION_TRACE ("tb_find_rsdp"); /* @@ -166,51 +422,52 @@ /* * 1) Search EBDA (low memory) paragraphs */ - status = acpi_os_map_memory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE, - (void **) &table_ptr); + status = acpi_os_map_memory ((u64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE, + (void *) &table_ptr); if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", + ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (status); } - mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, LO_RSDP_WINDOW_SIZE); - acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE); + mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE); + acpi_os_unmap_memory (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ - phys_addr = LO_RSDP_WINDOW_BASE; - phys_addr += (mem_rover - table_ptr); + phys_addr = ACPI_LO_RSDP_WINDOW_BASE; + phys_addr += ACPI_PTR_DIFF (mem_rover,table_ptr); table_info->physical_address = phys_addr; - return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ - status = acpi_os_map_memory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE, - (void **) &table_ptr); + status = acpi_os_map_memory ((u64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE, + (void *) &table_ptr); if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", + ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (status); } - mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, HI_RSDP_WINDOW_SIZE); - acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE); + mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ - phys_addr = HI_RSDP_WINDOW_BASE; - phys_addr += (mem_rover - table_ptr); + phys_addr = ACPI_HI_RSDP_WINDOW_BASE; + phys_addr += ACPI_PTR_DIFF (mem_rover, table_ptr); table_info->physical_address = phys_addr; - return_ACPI_STATUS (AE_OK); } } - /* * Physical addressing */ @@ -218,212 +475,32 @@ /* * 1) Search EBDA (low memory) paragraphs */ - mem_rover = acpi_tb_scan_memory_for_rsdp ((u8 *) LO_RSDP_WINDOW_BASE, - LO_RSDP_WINDOW_SIZE); + mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE), + ACPI_LO_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ - table_info->physical_address = (ACPI_TBLPTR) mem_rover; + table_info->physical_address = ACPI_TO_INTEGER (mem_rover); return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ - mem_rover = acpi_tb_scan_memory_for_rsdp ((u8 *) HI_RSDP_WINDOW_BASE, - HI_RSDP_WINDOW_SIZE); + mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), + ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ - table_info->physical_address = (ACPI_TBLPTR) mem_rover; + table_info->physical_address = ACPI_TO_INTEGER (mem_rover); return_ACPI_STATUS (AE_OK); } } - /* RSDP signature was not found */ return_ACPI_STATUS (AE_NOT_FOUND); } - -/******************************************************************************* - * - * FUNCTION: Acpi_get_firmware_table - * - * PARAMETERS: Signature - Any ACPI table signature - * Instance - the non zero instance of the table, allows - * support for multiple tables of the same type - * Flags - 0: Physical/Virtual support - * Ret_buffer - pointer to a structure containing a buffer to - * receive the table - * - * RETURN: Status - * - * DESCRIPTION: This function is called to get an ACPI table. The caller - * supplies an Out_buffer large enough to contain the entire ACPI - * table. Upon completion - * the Out_buffer->Length field will indicate the number of bytes - * copied into the Out_buffer->Buf_ptr buffer. This table will be - * a complete table including the header. - * - ******************************************************************************/ - -acpi_status -acpi_get_firmware_table ( - acpi_string signature, - u32 instance, - u32 flags, - acpi_table_header **table_pointer) -{ - ACPI_PHYSICAL_ADDRESS physical_address; - acpi_table_header *rsdt_ptr = NULL; - acpi_table_header *table_ptr; - acpi_status status; - u32 rsdt_size = 0; - u32 table_size; - u32 table_count; - u32 i; - u32 j; - - - FUNCTION_TRACE ("Acpi_get_firmware_table"); - - - /* - * Ensure that at least the table manager is initialized. We don't - * require that the entire ACPI subsystem is up for this interface - */ - - /* - * If we have a buffer, we must have a length too - */ - if ((instance == 0) || - (!signature) || - (!table_pointer)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - if (!acpi_gbl_RSDP) { - /* Get the RSDP */ - - status = acpi_os_get_root_pointer (flags, &physical_address); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } - - /* Map and validate the RSDP */ - - if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { - status = acpi_os_map_memory (physical_address, sizeof (RSDP_DESCRIPTOR), - (void **) &acpi_gbl_RSDP); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - } - else { - acpi_gbl_RSDP = (void *) (NATIVE_UINT) physical_address; - } - - /* - * The signature and checksum must both be correct - */ - if (STRNCMP ((NATIVE_CHAR *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { - /* Nope, BAD Signature */ - - status = AE_BAD_SIGNATURE; - goto cleanup; - } - - if (acpi_tb_checksum (acpi_gbl_RSDP, RSDP_CHECKSUM_LENGTH) != 0) { - /* Nope, BAD Checksum */ - - status = AE_BAD_CHECKSUM; - goto cleanup; - } - } - - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", - acpi_gbl_RSDP, HIDWORD(acpi_gbl_RSDP->rsdt_physical_address), - LODWORD(acpi_gbl_RSDP->rsdt_physical_address))); - - - /* Get the RSDT and validate it */ - - physical_address = acpi_tb_get_rsdt_address (); - status = acpi_tb_get_table_pointer (physical_address, flags, &rsdt_size, &rsdt_ptr); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - status = acpi_tb_validate_rsdt (rsdt_ptr); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - - /* Get the number of table pointers within the RSDT */ - - table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_ptr); - - - /* - * Search the RSDT/XSDT for the correct instance of the - * requested table - */ - for (i = 0, j = 0; i < table_count; i++) { - /* Get the next table pointer */ - - if (acpi_gbl_RSDP->revision < 2) { - physical_address = ((RSDT_DESCRIPTOR *) rsdt_ptr)->table_offset_entry[i]; - } - else { - physical_address = (ACPI_PHYSICAL_ADDRESS) - ACPI_GET_ADDRESS (((xsdt_descriptor *) rsdt_ptr)->table_offset_entry[i]); - } - - /* Get addressibility if necessary */ - - status = acpi_tb_get_table_pointer (physical_address, flags, &table_size, &table_ptr); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - /* Compare table signatures and table instance */ - - if (!STRNCMP ((char *) table_ptr, signature, STRLEN (signature))) { - /* An instance of the table was found */ - - j++; - if (j >= instance) { - /* Found the correct instance */ - - *table_pointer = table_ptr; - goto cleanup; - } - } - - /* Delete table mapping if using virtual addressing */ - - if ((table_size) && - ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)) { - acpi_os_unmap_memory (table_ptr, table_size); - } - } - - /* Did not find the table */ - - status = AE_NOT_EXIST; - - -cleanup: - if (rsdt_size) { - acpi_os_unmap_memory (rsdt_ptr, rsdt_size); - } - return_ACPI_STATUS (status); -} - +#endif diff -urN linux-2.4.21/drivers/acpi/tables.c linux-2.4.22/drivers/acpi/tables.c --- linux-2.4.21/drivers/acpi/tables.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/tables.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,578 @@ +/* + * acpi_tables.c - ACPI Boot-Time Table Parsing + * + * Copyright (C) 2001 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PREFIX "ACPI: " + +#define ACPI_MAX_TABLES 256 + +static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { + [ACPI_TABLE_UNKNOWN] = "????", + [ACPI_APIC] = "APIC", + [ACPI_BOOT] = "BOOT", + [ACPI_DBGP] = "DBGP", + [ACPI_DSDT] = "DSDT", + [ACPI_ECDT] = "ECDT", + [ACPI_ETDT] = "ETDT", + [ACPI_FADT] = "FACP", + [ACPI_FACS] = "FACS", + [ACPI_OEMX] = "OEM", + [ACPI_PSDT] = "PSDT", + [ACPI_SBST] = "SBST", + [ACPI_SLIT] = "SLIT", + [ACPI_SPCR] = "SPCR", + [ACPI_SRAT] = "SRAT", + [ACPI_SSDT] = "SSDT", + [ACPI_SPMI] = "SPMI", + [ACPI_HPET] = "HPET", +}; + +/* System Description Table (RSDT/XSDT) */ +struct acpi_table_sdt { + unsigned long pa; + enum acpi_table_id id; + unsigned long size; +} __attribute__ ((packed)); + +static unsigned long sdt_pa; /* Physical Address */ +static unsigned long sdt_count; /* Table count */ +static struct acpi_table_sdt *sdt_entry; + +void +acpi_table_print ( + struct acpi_table_header *header, + unsigned long phys_addr) +{ + char *name = NULL; + + if (!header) + return; + + /* Some table signatures aren't good table names */ + + if (!strncmp((char *) &header->signature, + acpi_table_signatures[ACPI_APIC], + sizeof(header->signature))) { + name = "MADT"; + } + else if (!strncmp((char *) &header->signature, + acpi_table_signatures[ACPI_FADT], + sizeof(header->signature))) { + name = "FADT"; + } + else + name = header->signature; + + printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", + name, header->revision, header->oem_id, + header->oem_table_id, header->oem_revision, + header->asl_compiler_id, header->asl_compiler_revision, + (void *) phys_addr); +} + + +void +acpi_table_print_madt_entry ( + acpi_table_entry_header *header) +{ + if (!header) + return; + + switch (header->type) { + + case ACPI_MADT_LAPIC: + { + struct acpi_table_lapic *p = + (struct acpi_table_lapic*) header; + printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", + p->acpi_id, p->id, p->flags.enabled?"enabled":"disabled"); + } + break; + + case ACPI_MADT_IOAPIC: + { + struct acpi_table_ioapic *p = + (struct acpi_table_ioapic*) header; + printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] global_irq_base[0x%x])\n", + p->id, p->address, p->global_irq_base); + } + break; + + case ACPI_MADT_INT_SRC_OVR: + { + struct acpi_table_int_src_ovr *p = + (struct acpi_table_int_src_ovr*) header; + printk(KERN_INFO PREFIX "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n", + p->bus, p->bus_irq, p->global_irq, p->flags.polarity, p->flags.trigger); + } + break; + + case ACPI_MADT_NMI_SRC: + { + struct acpi_table_nmi_src *p = + (struct acpi_table_nmi_src*) header; + printk(KERN_INFO PREFIX "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n", + p->flags.polarity, p->flags.trigger, p->global_irq); + } + break; + + case ACPI_MADT_LAPIC_NMI: + { + struct acpi_table_lapic_nmi *p = + (struct acpi_table_lapic_nmi*) header; + printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n", + p->acpi_id, p->flags.polarity, p->flags.trigger, p->lint); + } + break; + + case ACPI_MADT_LAPIC_ADDR_OVR: + { + struct acpi_table_lapic_addr_ovr *p = + (struct acpi_table_lapic_addr_ovr*) header; + printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n", + (void *) (unsigned long) p->address); + } + break; + + case ACPI_MADT_IOSAPIC: + { + struct acpi_table_iosapic *p = + (struct acpi_table_iosapic*) header; + printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] global_irq_base[0x%x] address[%p])\n", + p->id, p->global_irq_base, (void *) (unsigned long) p->address); + } + break; + + case ACPI_MADT_LSAPIC: + { + struct acpi_table_lsapic *p = + (struct acpi_table_lsapic*) header; + printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", + p->acpi_id, p->id, p->eid, p->flags.enabled?"enabled":"disabled"); + } + break; + + case ACPI_MADT_PLAT_INT_SRC: + { + struct acpi_table_plat_int_src *p = + (struct acpi_table_plat_int_src*) header; + printk(KERN_INFO PREFIX "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", + p->flags.polarity, p->flags.trigger, p->type, p->id, p->eid, p->iosapic_vector, p->global_irq); + } + break; + + default: + printk(KERN_WARNING PREFIX "Found unsupported MADT entry (type = 0x%x)\n", + header->type); + break; + } +} + + +static int +acpi_table_compute_checksum ( + void *table_pointer, + unsigned long length) +{ + u8 *p = (u8 *) table_pointer; + unsigned long remains = length; + unsigned long sum = 0; + + if (!p || !length) + return -EINVAL; + + while (remains--) + sum += *p++; + + return (sum & 0xFF); +} + +/* + * acpi_get_table_header_early() + * for acpi_blacklisted(), acpi_table_get_sdt() + */ +int __init +acpi_get_table_header_early ( + enum acpi_table_id id, + struct acpi_table_header **header) +{ + unsigned int i; + enum acpi_table_id temp_id; + + /* DSDT is different from the rest */ + if (id == ACPI_DSDT) + temp_id = ACPI_FADT; + else + temp_id = id; + + /* Locate the table. */ + + for (i = 0; i < sdt_count; i++) { + if (sdt_entry[i].id != temp_id) + continue; + *header = (void *) + __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); + if (!*header) { + printk(KERN_WARNING PREFIX "Unable to map %s\n", + acpi_table_signatures[temp_id]); + return -ENODEV; + } + break; + } + + if (!*header) { + printk(KERN_WARNING PREFIX "%s not present\n", + acpi_table_signatures[id]); + return -ENODEV; + } + + /* Map the DSDT header via the pointer in the FADT */ + if (id == ACPI_DSDT) { + struct acpi_table_fadt *fadt = (struct acpi_table_fadt *) *header; + + *header = (void *) __acpi_map_table(fadt->dsdt_addr, + sizeof(struct acpi_table_header)); + if (!*header) { + printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); + return -ENODEV; + } + } + + return 0; +} + + +int __init +acpi_table_parse_madt_family ( + enum acpi_table_id id, + unsigned long madt_size, + int entry_id, + acpi_madt_entry_handler handler) +{ + void *madt = NULL; + acpi_table_entry_header *entry = NULL; + unsigned long count = 0; + unsigned long madt_end = 0; + unsigned int i = 0; + + if (!handler) + return -EINVAL; + + /* Locate the MADT (if exists). There should only be one. */ + + for (i = 0; i < sdt_count; i++) { + if (sdt_entry[i].id != id) + continue; + madt = (void *) + __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); + if (!madt) { + printk(KERN_WARNING PREFIX "Unable to map %s\n", + acpi_table_signatures[id]); + return -ENODEV; + } + break; + } + + if (!madt) { + printk(KERN_WARNING PREFIX "%s not present\n", + acpi_table_signatures[id]); + return -ENODEV; + } + + madt_end = (unsigned long) madt + sdt_entry[i].size; + + /* Parse all entries looking for a match. */ + + entry = (acpi_table_entry_header *) + ((unsigned long) madt + madt_size); + + while (((unsigned long) entry) < madt_end) { + if (entry->type == entry_id) { + count++; + handler(entry); + } + entry = (acpi_table_entry_header *) + ((unsigned long) entry + entry->length); + } + + return count; +} + + +int __init +acpi_table_parse_madt ( + enum acpi_madt_entry_id id, + acpi_madt_entry_handler handler) +{ + return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt), + id, handler); +} + + +int __init +acpi_table_parse ( + enum acpi_table_id id, + acpi_table_handler handler) +{ + int count = 0; + unsigned int i = 0; + + if (!handler) + return -EINVAL; + + for (i = 0; i < sdt_count; i++) { + if (sdt_entry[i].id != id) + continue; + handler(sdt_entry[i].pa, sdt_entry[i].size); + count++; + } + + return count; +} + + +static int __init +acpi_table_get_sdt ( + struct acpi_table_rsdp *rsdp) +{ + struct acpi_table_header *header = NULL; + unsigned int i, id = 0; + + if (!rsdp) + return -EINVAL; + + /* First check XSDT (but only on ACPI 2.0-compatible systems) */ + + if ((rsdp->revision >= 2) && + (((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) { + + struct acpi_table_xsdt *mapped_xsdt = NULL; + + sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + + if (!header) { + printk(KERN_WARNING PREFIX "Unable to map XSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_xsdt = (struct acpi_table_xsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_xsdt) { + printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); + return -ENODEV; + } + header = &mapped_xsdt->header; + + if (strncmp(header->signature, "XSDT", 4)) { + printk(KERN_WARNING PREFIX "XSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); + return -ENODEV; + } + + sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3; + if (sdt_count > ACPI_MAX_TABLES) { + printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n", + (sdt_count - ACPI_MAX_TABLES)); + sdt_count = ACPI_MAX_TABLES; + } + + sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt)); + if (!sdt_entry) { + printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n"); + return -ENOMEM; + } + + for (i = 0; i < sdt_count; i++) + sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i]; + } + + /* Then check RSDT */ + + else if (rsdp->rsdt_address) { + + struct acpi_table_rsdt *mapped_rsdt = NULL; + + sdt_pa = rsdp->rsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + if (!header) { + printk(KERN_WARNING PREFIX "Unable to map RSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_rsdt = (struct acpi_table_rsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_rsdt) { + printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); + return -ENODEV; + } + header = &mapped_rsdt->header; + + if (strncmp(header->signature, "RSDT", 4)) { + printk(KERN_WARNING PREFIX "RSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n"); + return -ENODEV; + } + + sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 2; + if (sdt_count > ACPI_MAX_TABLES) { + printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n", + (sdt_count - ACPI_MAX_TABLES)); + sdt_count = ACPI_MAX_TABLES; + } + + sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt)); + if (!sdt_entry) { + printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n"); + return -ENOMEM; + } + + for (i = 0; i < sdt_count; i++) + sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; + } + + else { + printk(KERN_WARNING PREFIX "No System Description Table (RSDT/XSDT) specified in RSDP\n"); + return -ENODEV; + } + + acpi_table_print(header, sdt_pa); + + for (i = 0; i < sdt_count; i++) { + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_entry[i].pa, + sizeof(struct acpi_table_header)); + if (!header) + continue; + + /* remap in the entire table before processing */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_entry[i].pa, + header->length); + if (!header) + continue; + + acpi_table_print(header, sdt_entry[i].pa); + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); + continue; + } + + sdt_entry[i].size = header->length; + + for (id = 0; id < ACPI_TABLE_COUNT; id++) { + if (!strncmp((char *) &header->signature, + acpi_table_signatures[id], + sizeof(header->signature))) { + sdt_entry[i].id = id; + } + } + } + + /* + * The DSDT is *not* in the RSDT (why not? no idea.) but we want + * to print its info, because this is what people usually blacklist + * against. Unfortunately, we don't know the phys_addr, so just + * print 0. Maybe no one will notice. + */ + if(!acpi_get_table_header_early(ACPI_DSDT, &header)) + acpi_table_print(header, 0); + + return 0; +} + + +int __init +acpi_table_init (void) +{ + struct acpi_table_rsdp *rsdp = NULL; + unsigned long rsdp_phys = 0; + int result = 0; + + /* Locate and map the Root System Description Table (RSDP) */ + + rsdp_phys = acpi_find_rsdp(); + if (!rsdp_phys) { + printk(KERN_ERR PREFIX "Unable to locate RSDP\n"); + return -ENODEV; + } + + rsdp = (struct acpi_table_rsdp *) __va(rsdp_phys); + if (!rsdp) { + printk(KERN_WARNING PREFIX "Unable to map RSDP\n"); + return -ENODEV; + } + + printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n", + rsdp->revision, rsdp->oem_id, (void *) rsdp_phys); + + if (rsdp->revision < 2) + result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp)); + else + result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length); + + if (result) { + printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); + return -ENODEV; + } + + /* Locate and map the System Description table (RSDT/XSDT) */ + + if (acpi_table_get_sdt(rsdp)) + return -ENODEV; + + return 0; +} + diff -urN linux-2.4.21/drivers/acpi/thermal.c linux-2.4.22/drivers/acpi/thermal.c --- linux-2.4.21/drivers/acpi/thermal.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/thermal.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,1359 @@ +/* + * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 40 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This driver fully implements the ACPI thermal policy as described in the + * ACPI 2.0 Specification. + * + * TBD: 1. Implement passive cooling hysteresis. + * 2. Enhance passive cooling (CPU) states/limit interface to support + * concepts of 'multiple limiters', upper/lower limits, etc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_THERMAL_COMPONENT +ACPI_MODULE_NAME ("acpi_thermal") + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +static int tzp = 0; +MODULE_PARM(tzp, "i"); +MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); + +#define PREFIX "ACPI: " + + +#define ACPI_THERMAL_MAX_ACTIVE 10 + +#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10) +#define CELSIUS_TO_KELVIN(t) ((t+273)*10) + +static int acpi_thermal_add (struct acpi_device *device); +static int acpi_thermal_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_thermal_driver = { + .name = ACPI_THERMAL_DRIVER_NAME, + .class = ACPI_THERMAL_CLASS, + .ids = ACPI_THERMAL_HID, + .ops = { + .add = acpi_thermal_add, + .remove = acpi_thermal_remove, + }, +}; + +struct acpi_thermal_state { + u8 critical:1; + u8 hot:1; + u8 passive:1; + u8 active:1; + u8 reserved:4; + int active_index; +}; + +struct acpi_thermal_state_flags { + u8 valid:1; + u8 enabled:1; + u8 reserved:6; +}; + +struct acpi_thermal_critical { + struct acpi_thermal_state_flags flags; + unsigned long temperature; +}; + +struct acpi_thermal_hot { + struct acpi_thermal_state_flags flags; + unsigned long temperature; +}; + +struct acpi_thermal_passive { + struct acpi_thermal_state_flags flags; + unsigned long temperature; + unsigned long tc1; + unsigned long tc2; + unsigned long tsp; + struct acpi_handle_list devices; +}; + +struct acpi_thermal_active { + struct acpi_thermal_state_flags flags; + unsigned long temperature; + struct acpi_handle_list devices; +}; + +struct acpi_thermal_trips { + struct acpi_thermal_critical critical; + struct acpi_thermal_hot hot; + struct acpi_thermal_passive passive; + struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; +}; + +struct acpi_thermal_flags { + u8 cooling_mode:1; /* _SCP */ + u8 devices:1; /* _TZD */ + u8 reserved:6; +}; + +struct acpi_thermal { + acpi_handle handle; + acpi_bus_id name; + unsigned long temperature; + unsigned long last_temperature; + unsigned long polling_frequency; + u8 cooling_mode; + struct acpi_thermal_flags flags; + struct acpi_thermal_state state; + struct acpi_thermal_trips trips; + struct acpi_handle_list devices; + struct timer_list timer; +}; + + +/* -------------------------------------------------------------------------- + Thermal Zone Management + -------------------------------------------------------------------------- */ + +static int +acpi_thermal_get_temperature ( + struct acpi_thermal *tz) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE("acpi_thermal_get_temperature"); + + if (!tz) + return_VALUE(-EINVAL); + + tz->last_temperature = tz->temperature; + + status = acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature); + if (ACPI_FAILURE(status)) + return -ENODEV; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", tz->temperature)); + + return_VALUE(0); +} + + +static int +acpi_thermal_get_polling_frequency ( + struct acpi_thermal *tz) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE("acpi_thermal_get_polling_frequency"); + + if (!tz) + return_VALUE(-EINVAL); + + status = acpi_evaluate_integer(tz->handle, "_TZP", NULL, &tz->polling_frequency); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", tz->polling_frequency)); + + return_VALUE(0); +} + + +static int +acpi_thermal_set_polling ( + struct acpi_thermal *tz, + int seconds) +{ + ACPI_FUNCTION_TRACE("acpi_thermal_set_polling"); + + if (!tz) + return_VALUE(-EINVAL); + + tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency set to %lu seconds\n", tz->polling_frequency)); + + return_VALUE(0); +} + + +static int +acpi_thermal_set_cooling_mode ( + struct acpi_thermal *tz, + int mode) +{ + acpi_status status = AE_OK; + union acpi_object arg0 = {ACPI_TYPE_INTEGER}; + struct acpi_object_list arg_list = {1, &arg0}; + acpi_handle handle = NULL; + + ACPI_FUNCTION_TRACE("acpi_thermal_set_cooling_mode"); + + if (!tz) + return_VALUE(-EINVAL); + + status = acpi_get_handle(tz->handle, "_SCP", &handle); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); + return_VALUE(-ENODEV); + } + + arg0.integer.value = mode; + + status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + tz->cooling_mode = mode; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", + mode?"passive":"active")); + + return_VALUE(0); +} + + +static int +acpi_thermal_get_trip_points ( + struct acpi_thermal *tz) +{ + acpi_status status = AE_OK; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_get_trip_points"); + + if (!tz) + return_VALUE(-EINVAL); + + /* Critical Shutdown (required) */ + + status = acpi_evaluate_integer(tz->handle, "_CRT", NULL, + &tz->trips.critical.temperature); + if (ACPI_FAILURE(status)) { + tz->trips.critical.flags.valid = 0; + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n")); + return -ENODEV; + } + else { + tz->trips.critical.flags.valid = 1; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found critical threshold [%lu]\n", tz->trips.critical.temperature)); + } + + /* Critical Sleep (optional) */ + + status = acpi_evaluate_integer(tz->handle, "_HOT", NULL, &tz->trips.hot.temperature); + if (ACPI_FAILURE(status)) { + tz->trips.hot.flags.valid = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n")); + } + else { + tz->trips.hot.flags.valid = 1; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n", tz->trips.hot.temperature)); + } + + /* Passive: Processors (optional) */ + + status = acpi_evaluate_integer(tz->handle, "_PSV", NULL, &tz->trips.passive.temperature); + if (ACPI_FAILURE(status)) { + tz->trips.passive.flags.valid = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n")); + } + else { + tz->trips.passive.flags.valid = 1; + + status = acpi_evaluate_integer(tz->handle, "_TC1", NULL, &tz->trips.passive.tc1); + if (ACPI_FAILURE(status)) + tz->trips.passive.flags.valid = 0; + + status = acpi_evaluate_integer(tz->handle, "_TC2", NULL, &tz->trips.passive.tc2); + if (ACPI_FAILURE(status)) + tz->trips.passive.flags.valid = 0; + + status = acpi_evaluate_integer(tz->handle, "_TSP", NULL, &tz->trips.passive.tsp); + if (ACPI_FAILURE(status)) + tz->trips.passive.flags.valid = 0; + + status = acpi_evaluate_reference(tz->handle, "_PSL", NULL, &tz->trips.passive.devices); + if (ACPI_FAILURE(status)) + tz->trips.passive.flags.valid = 0; + + if (!tz->trips.passive.flags.valid) + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid passive threshold\n")); + else + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found passive threshold [%lu]\n", tz->trips.passive.temperature)); + } + + /* Active: Fans, etc. (optional) */ + + for (i=0; ihandle, name, NULL, &tz->trips.active[i].temperature); + if (ACPI_FAILURE(status)) + break; + + name[2] = 'L'; + status = acpi_evaluate_reference(tz->handle, name, NULL, &tz->trips.active[i].devices); + if (ACPI_SUCCESS(status)) { + tz->trips.active[i].flags.valid = 1; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found active threshold [%d]:[%lu]\n", i, tz->trips.active[i].temperature)); + } + else + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid active threshold [%d]\n", i)); + } + + return_VALUE(0); +} + + +static int +acpi_thermal_get_devices ( + struct acpi_thermal *tz) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE("acpi_thermal_get_devices"); + + if (!tz) + return_VALUE(-EINVAL); + + status = acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + return_VALUE(0); +} + + +static int +acpi_thermal_call_usermode ( + char *path) +{ + char *argv[2] = {NULL, NULL}; + char *envp[3] = {NULL, NULL, NULL}; + + ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode"); + + if (!path) + return_VALUE(-EINVAL); + + argv[0] = path; + + /* minimal command environment */ + envp[0] = "HOME=/"; + envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + + call_usermodehelper(argv[0], argv, envp); + + return_VALUE(0); +} + + +static int +acpi_thermal_critical ( + struct acpi_thermal *tz) +{ + int result = 0; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_thermal_critical"); + + if (!tz || !tz->trips.critical.flags.valid) + return_VALUE(-EINVAL); + + if (tz->temperature >= tz->trips.critical.temperature) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Critical trip point\n")); + tz->trips.critical.flags.enabled = 1; + } + else if (tz->trips.critical.flags.enabled) + tz->trips.critical.flags.enabled = 0; + + result = acpi_bus_get_device(tz->handle, &device); + if (result) + return_VALUE(result); + + acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); + + acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); + + return_VALUE(0); +} + + +static int +acpi_thermal_hot ( + struct acpi_thermal *tz) +{ + int result = 0; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_thermal_hot"); + + if (!tz || !tz->trips.hot.flags.valid) + return_VALUE(-EINVAL); + + if (tz->temperature >= tz->trips.hot.temperature) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n")); + tz->trips.hot.flags.enabled = 1; + } + else if (tz->trips.hot.flags.enabled) + tz->trips.hot.flags.enabled = 0; + + result = acpi_bus_get_device(tz->handle, &device); + if (result) + return_VALUE(result); + + acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); + + /* TBD: Call user-mode "sleep(S4)" function */ + + return_VALUE(0); +} + + +static int +acpi_thermal_passive ( + struct acpi_thermal *tz) +{ + int result = 0; + struct acpi_thermal_passive *passive = NULL; + int trend = 0; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_passive"); + + if (!tz || !tz->trips.passive.flags.valid) + return_VALUE(-EINVAL); + + passive = &(tz->trips.passive); + + /* + * Above Trip? + * ----------- + * Calculate the thermal trend (using the passive cooling equation) + * and modify the performance limit for all passive cooling devices + * accordingly. Note that we assume symmetry. + */ + if (tz->temperature >= passive->temperature) { + trend = (passive->tc1 * (tz->temperature - tz->last_temperature)) + (passive->tc2 * (tz->temperature - passive->temperature)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", + trend, passive->tc1, tz->temperature, + tz->last_temperature, passive->tc2, + tz->temperature, passive->temperature)); + tz->trips.passive.flags.enabled = 1; + /* Heating up? */ + if (trend > 0) + for (i=0; idevices.count; i++) + acpi_processor_set_thermal_limit( + passive->devices.handles[i], + ACPI_PROCESSOR_LIMIT_INCREMENT); + /* Cooling off? */ + else if (trend < 0) + for (i=0; idevices.count; i++) + acpi_processor_set_thermal_limit( + passive->devices.handles[i], + ACPI_PROCESSOR_LIMIT_DECREMENT); + } + + /* + * Below Trip? + * ----------- + * Implement passive cooling hysteresis to slowly increase performance + * and avoid thrashing around the passive trip point. Note that we + * assume symmetry. + */ + else if (tz->trips.passive.flags.enabled) { + for (i=0; idevices.count; i++) + result = acpi_processor_set_thermal_limit( + passive->devices.handles[i], + ACPI_PROCESSOR_LIMIT_DECREMENT); + if (result == 1) { + tz->trips.passive.flags.enabled = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Disabling passive cooling (zone is cool)\n")); + } + } + + return_VALUE(0); +} + + +static int +acpi_thermal_active ( + struct acpi_thermal *tz) +{ + int result = 0; + struct acpi_thermal_active *active = NULL; + int i = 0; + int j = 0; + unsigned long maxtemp = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_active"); + + if (!tz) + return_VALUE(-EINVAL); + + for (i=0; itrips.active[i]); + if (!active || !active->flags.valid) + break; + + /* + * Above Threshold? + * ---------------- + * If not already enabled, turn ON all cooling devices + * associated with this active threshold. + */ + if (tz->temperature >= active->temperature) { + if (active->temperature > maxtemp) + tz->state.active_index = i, maxtemp = active->temperature; + if (!active->flags.enabled) { + for (j = 0; j < active->devices.count; j++) { + result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D0); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'on'\n", active->devices.handles[j])); + continue; + } + active->flags.enabled = 1; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'on'\n", active->devices.handles[j])); + } + } + } + /* + * Below Threshold? + * ---------------- + * Turn OFF all cooling devices associated with this + * threshold. + */ + else if (active->flags.enabled) { + for (j = 0; j < active->devices.count; j++) { + result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D3); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'off'\n", active->devices.handles[j])); + continue; + } + active->flags.enabled = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'off'\n", active->devices.handles[j])); + } + } + } + + return_VALUE(0); +} + + +static void acpi_thermal_check (void *context); + +static void +acpi_thermal_run ( + unsigned long data) +{ + acpi_os_queue_for_execution(OSD_PRIORITY_GPE, acpi_thermal_check, (void *) data); +} + + +static void +acpi_thermal_check ( + void *data) +{ + int result = 0; + struct acpi_thermal *tz = (struct acpi_thermal *) data; + unsigned long sleep_time = 0; + int i = 0; + struct acpi_thermal_state state = tz->state; + + ACPI_FUNCTION_TRACE("acpi_thermal_check"); + + if (!tz) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); + return_VOID; + } + + result = acpi_thermal_get_temperature(tz); + if (result) + return_VOID; + + memset(&tz->state, 0, sizeof(tz->state)); + + /* + * Check Trip Points + * ----------------- + * Compare the current temperature to the trip point values to see + * if we've entered one of the thermal policy states. Note that + * this function determines when a state is entered, but the + * individual policy decides when it is exited (e.g. hysteresis). + */ + if (tz->trips.critical.flags.valid) + state.critical |= (tz->temperature >= tz->trips.critical.temperature); + if (tz->trips.hot.flags.valid) + state.hot |= (tz->temperature >= tz->trips.hot.temperature); + if (tz->trips.passive.flags.valid) + state.passive |= (tz->temperature >= tz->trips.passive.temperature); + for (i=0; itrips.active[i].flags.valid) + state.active |= (tz->temperature >= tz->trips.active[i].temperature); + + /* + * Invoke Policy + * ------------- + * Separated from the above check to allow individual policy to + * determine when to exit a given state. + */ + if (state.critical) + acpi_thermal_critical(tz); + if (state.hot) + acpi_thermal_hot(tz); + if (state.passive) + acpi_thermal_passive(tz); + if (state.active) + acpi_thermal_active(tz); + + /* + * Calculate State + * --------------- + * Again, separated from the above two to allow independent policy + * decisions. + */ + if (tz->trips.critical.flags.enabled) + tz->state.critical = 1; + if (tz->trips.hot.flags.enabled) + tz->state.hot = 1; + if (tz->trips.passive.flags.enabled) + tz->state.passive = 1; + for (i=0; itrips.active[i].flags.enabled) + tz->state.active = 1; + + /* + * Calculate Sleep Time + * -------------------- + * If we're in the passive state, use _TSP's value. Otherwise + * use the default polling frequency (e.g. _TZP). If no polling + * frequency is specified then we'll wait forever (at least until + * a thermal event occurs). Note that _TSP and _TZD values are + * given in 1/10th seconds (we must covert to milliseconds). + */ + if (tz->state.passive) + sleep_time = tz->trips.passive.tsp * 100; + else if (tz->polling_frequency > 0) + sleep_time = tz->polling_frequency * 100; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", + tz->name, tz->temperature, sleep_time)); + + /* + * Schedule Next Poll + * ------------------ + */ + if (!sleep_time) { + if (timer_pending(&(tz->timer))) + del_timer(&(tz->timer)); + } + else { + if (timer_pending(&(tz->timer))) + mod_timer(&(tz->timer), (HZ * sleep_time) / 1000); + else { + tz->timer.data = (unsigned long) tz; + tz->timer.function = acpi_thermal_run; + tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; + add_timer(&(tz->timer)); + } + } + + return_VOID; +} + + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_thermal_dir = NULL; + + +static int +acpi_thermal_read_state ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_read_state"); + + if (!tz || (off != 0)) + goto end; + + p += sprintf(p, "state: "); + + if (!tz->state.critical && !tz->state.hot && !tz->state.passive && !tz->state.active) + p += sprintf(p, "ok\n"); + else { + if (tz->state.critical) + p += sprintf(p, "critical "); + if (tz->state.hot) + p += sprintf(p, "hot "); + if (tz->state.passive) + p += sprintf(p, "passive "); + if (tz->state.active) + p += sprintf(p, "active[%d]", tz->state.active_index); + p += sprintf(p, "\n"); + } + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_thermal_read_temperature ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + int result = 0; + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_read_temperature"); + + if (!tz || (off != 0)) + goto end; + + result = acpi_thermal_get_temperature(tz); + if (result) + goto end; + + p += sprintf(p, "temperature: %ld C\n", + KELVIN_TO_CELSIUS(tz->temperature)); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_thermal_read_trip_points ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char *p = page; + int len = 0; + int i = 0; + int j = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_read_trip_points"); + + if (!tz || (off != 0)) + goto end; + + if (tz->trips.critical.flags.valid) + p += sprintf(p, "critical (S5): %ld C\n", + KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); + + if (tz->trips.hot.flags.valid) + p += sprintf(p, "hot (S4): %ld C\n", + KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); + + if (tz->trips.passive.flags.valid) { + p += sprintf(p, "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", + KELVIN_TO_CELSIUS(tz->trips.passive.temperature), + tz->trips.passive.tc1, + tz->trips.passive.tc2, + tz->trips.passive.tsp); + for (j=0; jtrips.passive.devices.count; j++) { + + p += sprintf(p, "0x%p ", tz->trips.passive.devices.handles[j]); + } + p += sprintf(p, "\n"); + } + + for (i=0; itrips.active[i].flags.valid)) + break; + p += sprintf(p, "active[%d]: %ld C: devices=", + i, KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); + for (j=0; jtrips.active[i].devices.count; j++) + p += sprintf(p, "0x%p ", + tz->trips.active[i].devices.handles[j]); + p += sprintf(p, "\n"); + } + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_thermal_write_trip_points ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char limit_string[25] = {'\0'}; + int critical, hot, passive, active0, active1; + + ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points"); + + if (!tz || (count > sizeof(limit_string) - 1)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n")); + return_VALUE(-EINVAL); + } + + if (copy_from_user(limit_string, buffer, count)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n")); + return_VALUE(-EFAULT); + } + + limit_string[count] = '\0'; + + if (sscanf(limit_string, "%d:%d:%d:%d:%d", &critical, &hot, &passive, &active0, &active1) != 5) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n")); + return_VALUE(-EINVAL); + } + + tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical); + tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot); + tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive); + tz->trips.active[0].temperature = CELSIUS_TO_KELVIN(active0); + tz->trips.active[1].temperature = CELSIUS_TO_KELVIN(active1); + + return_VALUE(count); +} + + +static int +acpi_thermal_read_cooling_mode ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_read_cooling_mode"); + + if (!tz || (off != 0)) + goto end; + + if (!tz->flags.cooling_mode) { + p += sprintf(p, "\n"); + goto end; + } + + p += sprintf(p, "cooling mode: %s\n", + tz->cooling_mode?"passive":"active"); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_thermal_write_cooling_mode ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char mode_string[12] = {'\0'}; + + ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode"); + + if (!tz || (count > sizeof(mode_string) - 1)) + return_VALUE(-EINVAL); + + if (!tz->flags.cooling_mode) + return_VALUE(-ENODEV); + + if (copy_from_user(mode_string, buffer, count)) + return_VALUE(-EFAULT); + + mode_string[count] = '\0'; + + result = acpi_thermal_set_cooling_mode(tz, + simple_strtoul(mode_string, NULL, 0)); + if (result) + return_VALUE(result); + + return_VALUE(count); +} + + +static int +acpi_thermal_read_polling ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char *p = page; + int len = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_read_polling"); + + if (!tz || (off != 0)) + goto end; + + if (!tz->polling_frequency) { + p += sprintf(p, "\n"); + goto end; + } + + p += sprintf(p, "polling frequency: %lu seconds\n", + (tz->polling_frequency / 10)); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return_VALUE(len); +} + + +static int +acpi_thermal_write_polling ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_thermal *tz = (struct acpi_thermal *) data; + char polling_string[12] = {'\0'}; + int seconds = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_write_polling"); + + if (!tz || (count > sizeof(polling_string) - 1)) + return_VALUE(-EINVAL); + + if (copy_from_user(polling_string, buffer, count)) + return_VALUE(-EFAULT); + + polling_string[count] = '\0'; + + seconds = simple_strtoul(polling_string, NULL, 0); + + result = acpi_thermal_set_polling(tz, seconds); + if (result) + return_VALUE(result); + + acpi_thermal_check(tz); + + return_VALUE(count); +} + + +static int +acpi_thermal_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + ACPI_FUNCTION_TRACE("acpi_thermal_add_fs"); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_thermal_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + /* 'state' [R] */ + entry = create_proc_entry(ACPI_THERMAL_FILE_STATE, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_THERMAL_FILE_STATE)); + else { + entry->read_proc = acpi_thermal_read_state; + entry->data = acpi_driver_data(device); + } + + /* 'temperature' [R] */ + entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_THERMAL_FILE_TEMPERATURE)); + else { + entry->read_proc = acpi_thermal_read_temperature; + entry->data = acpi_driver_data(device); + } + + /* 'trip_points' [R/W] */ + entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_THERMAL_FILE_POLLING_FREQ)); + else { + entry->read_proc = acpi_thermal_read_trip_points; + entry->write_proc = acpi_thermal_write_trip_points; + entry->data = acpi_driver_data(device); + } + + /* 'cooling_mode' [R/W] */ + entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_THERMAL_FILE_COOLING_MODE)); + else { + entry->read_proc = acpi_thermal_read_cooling_mode; + entry->write_proc = acpi_thermal_write_cooling_mode; + entry->data = acpi_driver_data(device); + } + + /* 'polling_frequency' [R/W] */ + entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_THERMAL_FILE_POLLING_FREQ)); + else { + entry->read_proc = acpi_thermal_read_polling; + entry->write_proc = acpi_thermal_write_polling; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + + +static int +acpi_thermal_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +static void +acpi_thermal_notify ( + acpi_handle handle, + u32 event, + void *data) +{ + struct acpi_thermal *tz = (struct acpi_thermal *) data; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_thermal_notify"); + + if (!tz) + return_VOID; + + if (acpi_bus_get_device(tz->handle, &device)) + return_VOID; + + switch (event) { + case ACPI_THERMAL_NOTIFY_TEMPERATURE: + acpi_thermal_check(tz); + break; + case ACPI_THERMAL_NOTIFY_THRESHOLDS: + acpi_thermal_get_trip_points(tz); + acpi_thermal_check(tz); + acpi_bus_generate_event(device, event, 0); + break; + case ACPI_THERMAL_NOTIFY_DEVICES: + if (tz->flags.devices) + acpi_thermal_get_devices(tz); + acpi_bus_generate_event(device, event, 0); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return_VOID; +} + + +static int +acpi_thermal_get_info ( + struct acpi_thermal *tz) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_get_info"); + + if (!tz) + return_VALUE(-EINVAL); + + /* Get temperature [_TMP] (required) */ + result = acpi_thermal_get_temperature(tz); + if (result) + return_VALUE(result); + + /* Set the cooling mode [_SCP] to active cooling (default) */ + result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); + if (!result) + tz->flags.cooling_mode = 1; + + /* Get trip points [_CRT, _PSV, etc.] (required) */ + result = acpi_thermal_get_trip_points(tz); + if (result) + return_VALUE(result); + + /* Get default polling frequency [_TZP] (optional) */ + if (tzp) + tz->polling_frequency = tzp; + else + acpi_thermal_get_polling_frequency(tz); + + /* Get devices in this thermal zone [_TZD] (optional) */ + result = acpi_thermal_get_devices(tz); + if (!result) + tz->flags.devices = 1; + + return_VALUE(0); +} + + +static int +acpi_thermal_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_thermal *tz = NULL; + + ACPI_FUNCTION_TRACE("acpi_thermal_add"); + + if (!device) + return_VALUE(-EINVAL); + + tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL); + if (!tz) + return_VALUE(-ENOMEM); + memset(tz, 0, sizeof(struct acpi_thermal)); + + tz->handle = device->handle; + sprintf(tz->name, "%s", device->pnp.bus_id); + sprintf(acpi_device_name(device), "%s", ACPI_THERMAL_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_THERMAL_CLASS); + acpi_driver_data(device) = tz; + + result = acpi_thermal_get_info(tz); + if (result) + goto end; + + result = acpi_thermal_add_fs(device); + if (result) + return_VALUE(result); + + init_timer(&tz->timer); + + acpi_thermal_check(tz); + + status = acpi_install_notify_handler(tz->handle, + ACPI_DEVICE_NOTIFY, acpi_thermal_notify, tz); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + result = -ENODEV; + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", + acpi_device_name(device), acpi_device_bid(device), + KELVIN_TO_CELSIUS(tz->temperature)); + +end: + if (result) { + acpi_thermal_remove_fs(device); + kfree(tz); + } + + return_VALUE(result); +} + + +static int +acpi_thermal_remove ( + struct acpi_device *device, + int type) +{ + acpi_status status = AE_OK; + struct acpi_thermal *tz = NULL; + + ACPI_FUNCTION_TRACE("acpi_thermal_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + tz = (struct acpi_thermal *) acpi_driver_data(device); + + if (timer_pending(&(tz->timer))) + del_timer(&(tz->timer)); + + status = acpi_remove_notify_handler(tz->handle, + ACPI_DEVICE_NOTIFY, acpi_thermal_notify); + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + + /* Terminate policy */ + if (tz->trips.passive.flags.valid + && tz->trips.passive.flags.enabled) { + tz->trips.passive.flags.enabled = 0; + acpi_thermal_passive(tz); + } + if (tz->trips.active[0].flags.valid + && tz->trips.active[0].flags.enabled) { + tz->trips.active[0].flags.enabled = 0; + acpi_thermal_active(tz); + } + + acpi_thermal_remove_fs(device); + + return_VALUE(0); +} + + +static int __init +acpi_thermal_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_thermal_init"); + + acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); + if (!acpi_thermal_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_thermal_driver); + if (result < 0) { + remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + + +static void __exit +acpi_thermal_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_thermal_exit"); + + acpi_bus_unregister_driver(&acpi_thermal_driver); + + remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); + + return_VOID; +} + + +module_init(acpi_thermal_init); +module_exit(acpi_thermal_exit); diff -urN linux-2.4.21/drivers/acpi/toshiba_acpi.c linux-2.4.22/drivers/acpi/toshiba_acpi.c --- linux-2.4.21/drivers/acpi/toshiba_acpi.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/toshiba_acpi.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,541 @@ +/* + * toshiba_acpi.c - Toshiba Laptop ACPI Extras + * + * + * Copyright (C) 2002-2003 John Belmonte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * The devolpment page for this driver is located at + * http://memebeam.org/toys/ToshibaAcpiDriver. + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 + * Rob Miller - TV out and hotkeys help + * + * + * TODO + * + */ + +#define TOSHIBA_ACPI_VERSION "0.16" +#define PROC_INTERFACE_VERSION 1 + +#include +#include +#include +#include +#include +#include + +#include + +MODULE_AUTHOR("John Belmonte"); +MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); +MODULE_LICENSE("GPL"); + +/* Toshiba ACPI method paths */ +#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" +#define METHOD_HCI "\\_SB_.VALD.GHCI" +#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" + +/* Toshiba HCI interface definitions + * + * HCI is Toshiba's "Hardware Control Interface" which is supposed to + * be uniform across all their models. Ideally we would just call + * dedicated ACPI methods instead of using this primitive interface. + * However the ACPI methods seem to be incomplete in some areas (for + * example they allow setting, but not reading, the LCD brightness value), + * so this is still useful. + */ + +#define HCI_WORDS 6 + +/* operations */ +#define HCI_SET 0xff00 +#define HCI_GET 0xfe00 + +/* return codes */ +#define HCI_SUCCESS 0x0000 +#define HCI_FAILURE 0x1000 +#define HCI_NOT_SUPPORTED 0x8000 +#define HCI_EMPTY 0x8c00 + +/* registers */ +#define HCI_FAN 0x0004 +#define HCI_SYSTEM_EVENT 0x0016 +#define HCI_VIDEO_OUT 0x001c +#define HCI_HOTKEY_EVENT 0x001e +#define HCI_LCD_BRIGHTNESS 0x002a + +/* field definitions */ +#define HCI_LCD_BRIGHTNESS_BITS 3 +#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) +#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) +#define HCI_VIDEO_OUT_LCD 0x1 +#define HCI_VIDEO_OUT_CRT 0x2 +#define HCI_VIDEO_OUT_TV 0x4 + +/* utility + */ + +static __inline__ void +_set_bit(u32* word, u32 mask, int value) +{ + *word = (*word & ~mask) | (mask * value); +} + +/* an sscanf that takes explicit string length */ +static int +snscanf(const char* str, int n, const char* format, ...) +{ + va_list args; + int result; + char* str2 = kmalloc(n + 1, GFP_KERNEL); + if (str2 == 0) return 0; + /* NOTE: don't even _think_ about replacing this with strlcpy */ + strncpy(str2, str, n); + str2[n] = 0; + va_start(args, format); + result = vsscanf(str2, format, args); + va_end(args); + kfree(str2); + return result; +} + +/* acpi interface wrappers + */ + +static int +write_acpi_int(const char* methodName, int val) +{ + struct acpi_object_list params; + union acpi_object in_objs[1]; + acpi_status status; + + params.count = sizeof(in_objs)/sizeof(in_objs[0]); + params.pointer = in_objs; + in_objs[0].type = ACPI_TYPE_INTEGER; + in_objs[0].integer.value = val; + + status = acpi_evaluate_object(0, (char*)methodName, ¶ms, 0); + return (status == AE_OK); +} + +#if 0 +static int +read_acpi_int(const char* methodName, int* pVal) +{ + struct acpi_buffer results; + union acpi_object out_objs[1]; + acpi_status status; + + results.length = sizeof(out_objs); + results.pointer = out_objs; + + status = acpi_evaluate_object(0, (char*)methodName, 0, &results); + *pVal = out_objs[0].integer.value; + + return (status == AE_OK) && (out_objs[0].type == ACPI_TYPE_INTEGER); +} +#endif + +/* Perform a raw HCI call. Here we don't care about input or output buffer + * format. + */ +static acpi_status +hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS]) +{ + struct acpi_object_list params; + union acpi_object in_objs[HCI_WORDS]; + struct acpi_buffer results; + union acpi_object out_objs[HCI_WORDS+1]; + acpi_status status; + int i; + + params.count = HCI_WORDS; + params.pointer = in_objs; + for (i = 0; i < HCI_WORDS; ++i) { + in_objs[i].type = ACPI_TYPE_INTEGER; + in_objs[i].integer.value = in[i]; + } + + results.length = sizeof(out_objs); + results.pointer = out_objs; + + status = acpi_evaluate_object(0, METHOD_HCI, ¶ms, + &results); + if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) { + for (i = 0; i < out_objs->package.count; ++i) { + out[i] = out_objs->package.elements[i].integer.value; + } + } + + return status; +} + +/* common hci tasks (get or set one value) + * + * In addition to the ACPI status, the HCI system returns a result which + * may be useful (such as "not supported"). + */ + +static acpi_status +hci_write1(u32 reg, u32 in1, u32* result) +{ + u32 in[HCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 }; + u32 out[HCI_WORDS]; + acpi_status status = hci_raw(in, out); + *result = (status == AE_OK) ? out[0] : HCI_FAILURE; + return status; +} + +static acpi_status +hci_read1(u32 reg, u32* out1, u32* result) +{ + u32 in[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 }; + u32 out[HCI_WORDS]; + acpi_status status = hci_raw(in, out); + *out1 = out[2]; + *result = (status == AE_OK) ? out[0] : HCI_FAILURE; + return status; +} + +static struct proc_dir_entry* toshiba_proc_dir = NULL; +static int force_fan; +static int last_key_event; +static int key_event_valid; + +typedef struct _ProcItem +{ + const char* name; + char* (*read_func)(char*); + unsigned long (*write_func)(const char*, unsigned long); +} ProcItem; + +/* proc file handlers + */ + +static int +dispatch_read(char* page, char** start, off_t off, int count, int* eof, + ProcItem* item) +{ + char* p = page; + int len; + + if (off == 0) + p = item->read_func(p); + + /* ISSUE: I don't understand this code */ + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static int +dispatch_write(struct file* file, const char* buffer, unsigned long count, + ProcItem* item) +{ + return item->write_func(buffer, count); +} + +static char* +read_lcd(char* p) +{ + u32 hci_result; + u32 value; + + hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + value = value >> HCI_LCD_BRIGHTNESS_SHIFT; + p += sprintf(p, "brightness: %d\n", value); + p += sprintf(p, "brightness_levels: %d\n", + HCI_LCD_BRIGHTNESS_LEVELS); + } else { + p += sprintf(p, "ERROR\n"); + } + + return p; +} + +static unsigned long +write_lcd(const char* buffer, unsigned long count) +{ + int value; + u32 hci_result; + + if (snscanf(buffer, count, " brightness : %i", &value) == 1 && + value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { + value = value << HCI_LCD_BRIGHTNESS_SHIFT; + hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); + if (hci_result != HCI_SUCCESS) + return -EFAULT; + } else { + return -EINVAL; + } + + return count; +} + +static char* +read_video(char* p) +{ + u32 hci_result; + u32 value; + + hci_read1(HCI_VIDEO_OUT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; + int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; + int is_tv = (value & HCI_VIDEO_OUT_TV ) ? 1 : 0; + p += sprintf(p, "lcd_out: %d\n", is_lcd); + p += sprintf(p, "crt_out: %d\n", is_crt); + p += sprintf(p, "tv_out: %d\n", is_tv); + } else { + p += sprintf(p, "ERROR\n"); + } + + return p; +} + +static unsigned long +write_video(const char* buffer, unsigned long count) +{ + int value; + const char* buffer_end = buffer + count; + int lcd_out = -1; + int crt_out = -1; + int tv_out = -1; + u32 hci_result; + int video_out; + + /* scan expression. Multiple expressions may be delimited with ; */ + do { + if (snscanf(buffer, count, " lcd_out : %i", &value) == 1) + lcd_out = value & 1; + else if (snscanf(buffer, count, " crt_out : %i", &value) == 1) + crt_out = value & 1; + else if (snscanf(buffer, count, " tv_out : %i", &value) == 1) + tv_out = value & 1; + /* advance to one character past the next ; */ + do ++buffer; + while ((buffer < buffer_end) && (*(buffer-1) != ';')); + } while (buffer < buffer_end); + + hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); + if (hci_result == HCI_SUCCESS) { + int new_video_out = video_out; + if (lcd_out != -1) + _set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out); + if (crt_out != -1) + _set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out); + if (tv_out != -1) + _set_bit(&new_video_out, HCI_VIDEO_OUT_TV, tv_out); + /* To avoid unnecessary video disruption, only write the new + * video setting if something changed. */ + if (new_video_out != video_out) + write_acpi_int(METHOD_VIDEO_OUT, new_video_out); + } + + return count; +} + +static char* +read_fan(char* p) +{ + u32 hci_result; + u32 value; + + hci_read1(HCI_FAN, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + p += sprintf(p, "running: %d\n", (value > 0)); + p += sprintf(p, "force_on: %d\n", force_fan); + } else { + p += sprintf(p, "ERROR\n"); + } + + return p; +} + +static unsigned long +write_fan(const char* buffer, unsigned long count) +{ + int value; + u32 hci_result; + + if (snscanf(buffer, count, " force_on : %i", &value) == 1 && + value >= 0 && value <= 1) { + hci_write1(HCI_FAN, value, &hci_result); + if (hci_result != HCI_SUCCESS) + return -EFAULT; + else + force_fan = value; + } else { + return -EINVAL; + } + + return count; +} + +static char* +read_keys(char* p) +{ + u32 hci_result; + u32 value; + + if (!key_event_valid) { + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + key_event_valid = 1; + last_key_event = value; + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an unresolved issue on + * some machines where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + } else { + p += sprintf(p, "ERROR\n"); + goto end; + } + } + + p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); + p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); + +end: + return p; +} + +static unsigned long +write_keys(const char* buffer, unsigned long count) +{ + int value; + + if (snscanf(buffer, count, " hotkey_ready : %i", &value) == 1 && + value == 0) { + key_event_valid = 0; + } else { + return -EINVAL; + } + + return count; +} + +static char* +read_version(char* p) +{ + p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION); + p += sprintf(p, "proc_interface: %d\n", + PROC_INTERFACE_VERSION); + return p; +} + +/* proc and module init + */ + +#define PROC_TOSHIBA "toshiba" + +ProcItem proc_items[] = +{ + { "lcd" , read_lcd , write_lcd }, + { "video" , read_video , write_video }, + { "fan" , read_fan , write_fan }, + { "keys" , read_keys , write_keys }, + { "version" , read_version , 0 }, + { 0 , 0 , 0 }, +}; + +static acpi_status +add_device(void) +{ + struct proc_dir_entry* proc; + ProcItem* item; + + for (item = proc_items; item->name; ++item) + { + proc = create_proc_read_entry(item->name, + S_IFREG | S_IRUGO | S_IWUSR, + toshiba_proc_dir, (read_proc_t*)dispatch_read, item); + if (proc && item->write_func) + proc->write_proc = (write_proc_t*)dispatch_write; + } + + return(AE_OK); +} + +static acpi_status +remove_device(void) +{ + ProcItem* item; + + for (item = proc_items; item->name; ++item) + remove_proc_entry(item->name, toshiba_proc_dir); + return(AE_OK); +} + +static int __init +toshiba_acpi_init(void) +{ + acpi_status status = AE_OK; + int value; + u32 hci_result; + + /* simple device detection: try reading an HCI register */ + hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); + if (hci_result != HCI_SUCCESS) + return -ENODEV; + + printk("Toshiba Laptop ACPI Extras version %s\n", TOSHIBA_ACPI_VERSION); + + force_fan = 0; + key_event_valid = 0; + + /* enable event fifo */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + + toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); + if (!toshiba_proc_dir) { + status = AE_ERROR; + } else { + status = add_device(); + if (ACPI_FAILURE(status)) + remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + } + + return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; +} + +static void __exit +toshiba_acpi_exit(void) +{ + remove_device(); + + if (toshiba_proc_dir) + remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + + return; +} + +module_init(toshiba_acpi_init); +module_exit(toshiba_acpi_exit); diff -urN linux-2.4.21/drivers/acpi/utilities/Makefile linux-2.4.22/drivers/acpi/utilities/Makefile --- linux-2.4.21/drivers/acpi/utilities/Makefile 2001-06-20 17:47:40.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -1,11 +1,10 @@ # # Makefile for all Linux ACPI interpreter subdirectories -# EXCEPT for the ospm directory # O_TARGET := $(notdir $(CURDIR)).o -obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -urN linux-2.4.21/drivers/acpi/utilities/utalloc.c linux-2.4.22/drivers/acpi/utilities/utalloc.c --- linux-2.4.21/drivers/acpi/utilities/utalloc.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utalloc.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,44 +1,58 @@ /****************************************************************************** * * Module Name: utalloc - local cache and memory allocation routines - * $Revision: 106 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acparser.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "acglobal.h" +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utalloc") + ACPI_MODULE_NAME ("utalloc") /****************************************************************************** * - * FUNCTION: Acpi_ut_release_to_cache + * FUNCTION: acpi_ut_release_to_cache * - * PARAMETERS: List_id - Memory list/cache ID + * PARAMETERS: list_id - Memory list/cache ID * Object - The object to be released * * RETURN: None @@ -50,13 +64,13 @@ void acpi_ut_release_to_cache ( - u32 list_id, - void *object) + u32 list_id, + void *object) { - ACPI_MEMORY_LIST *cache_info; + struct acpi_memory_list *cache_info; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* If walk cache is full, just free this wallkstate object */ @@ -70,29 +84,31 @@ /* Otherwise put this object back into the cache */ else { - acpi_ut_acquire_mutex (ACPI_MTX_CACHES); + if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) { + return; + } /* Mark the object as cached */ - MEMSET (object, 0xCA, cache_info->object_size); - ((acpi_operand_object *) object)->common.data_type = ACPI_CACHED_OBJECT; + ACPI_MEMSET (object, 0xCA, cache_info->object_size); + ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED); /* Put the object at the head of the cache list */ - * (char **) (((char *) object) + cache_info->link_offset) = cache_info->list_head; + * (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head; cache_info->list_head = object; cache_info->cache_depth++; - acpi_ut_release_mutex (ACPI_MTX_CACHES); + (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); } } /****************************************************************************** * - * FUNCTION: Acpi_ut_acquire_from_cache + * FUNCTION: acpi_ut_acquire_from_cache * - * PARAMETERS: List_id - Memory list ID + * PARAMETERS: list_id - Memory list ID * * RETURN: A requested object. NULL if the object could not be * allocated. @@ -104,17 +120,20 @@ void * acpi_ut_acquire_from_cache ( - u32 list_id) + u32 list_id) { - ACPI_MEMORY_LIST *cache_info; - void *object; + struct acpi_memory_list *cache_info; + void *object; - PROC_NAME ("Ut_acquire_from_cache"); + ACPI_FUNCTION_NAME ("ut_acquire_from_cache"); cache_info = &acpi_gbl_memory_lists[list_id]; - acpi_ut_acquire_mutex (ACPI_MTX_CACHES); + if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) { + return (NULL); + } + ACPI_MEM_TRACKING (cache_info->cache_requests++); /* Check the cache first */ @@ -123,7 +142,7 @@ /* There is an object available, use it */ object = cache_info->list_head; - cache_info->list_head = * (char **) (((char *) object) + cache_info->link_offset); + cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))); ACPI_MEM_TRACKING (cache_info->cache_hits++); cache_info->cache_depth--; @@ -133,11 +152,13 @@ object, acpi_gbl_memory_lists[list_id].list_name)); #endif - acpi_ut_release_mutex (ACPI_MTX_CACHES); + if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) { + return (NULL); + } /* Clear (zero) the previously used Object */ - MEMSET (object, 0, cache_info->object_size); + ACPI_MEMSET (object, 0, cache_info->object_size); } else { @@ -145,7 +166,9 @@ /* Avoid deadlock with ACPI_MEM_CALLOCATE */ - acpi_ut_release_mutex (ACPI_MTX_CACHES); + if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) { + return (NULL); + } object = ACPI_MEM_CALLOCATE (cache_info->object_size); ACPI_MEM_TRACKING (cache_info->total_allocated++); @@ -157,9 +180,9 @@ /****************************************************************************** * - * FUNCTION: Acpi_ut_delete_generic_cache + * FUNCTION: acpi_ut_delete_generic_cache * - * PARAMETERS: List_id - Memory list ID + * PARAMETERS: list_id - Memory list ID * * RETURN: None * @@ -169,20 +192,20 @@ void acpi_ut_delete_generic_cache ( - u32 list_id) + u32 list_id) { - ACPI_MEMORY_LIST *cache_info; - char *next; + struct acpi_memory_list *cache_info; + char *next; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); cache_info = &acpi_gbl_memory_lists[list_id]; while (cache_info->list_head) { /* Delete one cached state object */ - next = * (char **) (((char *) cache_info->list_head) + cache_info->link_offset); + next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset]))); ACPI_MEM_FREE (cache_info->list_head); cache_info->list_head = next; @@ -191,26 +214,396 @@ } -#ifdef ACPI_DBG_TRACK_ALLOCATIONS +/******************************************************************************* + * + * FUNCTION: acpi_ut_validate_buffer + * + * PARAMETERS: Buffer - Buffer descriptor to be validated + * + * RETURN: Status + * + * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer + * + ******************************************************************************/ + +acpi_status +acpi_ut_validate_buffer ( + struct acpi_buffer *buffer) +{ + + /* Obviously, the structure pointer must be valid */ + + if (!buffer) { + return (AE_BAD_PARAMETER); + } + + /* Special semantics for the length */ + + if ((buffer->length == ACPI_NO_BUFFER) || + (buffer->length == ACPI_ALLOCATE_BUFFER) || + (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) { + return (AE_OK); + } + + /* Length is valid, the buffer pointer must be also */ + if (!buffer->pointer) { + return (AE_BAD_PARAMETER); + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_initialize_buffer + * + * PARAMETERS: required_length - Length needed + * Buffer - Buffer to be validated + * + * RETURN: Status + * + * DESCRIPTION: Validate that the buffer is of the required length or + * allocate a new buffer. + * + ******************************************************************************/ + +acpi_status +acpi_ut_initialize_buffer ( + struct acpi_buffer *buffer, + acpi_size required_length) +{ + acpi_status status = AE_OK; + + + switch (buffer->length) { + case ACPI_NO_BUFFER: + + /* Set the exception and returned the required length */ + + status = AE_BUFFER_OVERFLOW; + break; + + + case ACPI_ALLOCATE_BUFFER: + + /* Allocate a new buffer */ + + buffer->pointer = acpi_os_allocate (required_length); + if (!buffer->pointer) { + return (AE_NO_MEMORY); + } + + /* Clear the buffer */ + + ACPI_MEMSET (buffer->pointer, 0, required_length); + break; + + + case ACPI_ALLOCATE_LOCAL_BUFFER: + + /* Allocate a new buffer with local interface to allow tracking */ + + buffer->pointer = ACPI_MEM_ALLOCATE (required_length); + if (!buffer->pointer) { + return (AE_NO_MEMORY); + } + + /* Clear the buffer */ + + ACPI_MEMSET (buffer->pointer, 0, required_length); + break; + + + default: + + /* Validate the size of the buffer */ + + if (buffer->length < required_length) { + status = AE_BUFFER_OVERFLOW; + } + break; + } + + buffer->length = required_length; + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_allocate + * + * PARAMETERS: Size - Size of the allocation + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: The subsystem's equivalent of malloc. + * + ******************************************************************************/ + +void * +acpi_ut_allocate ( + acpi_size size, + u32 component, + char *module, + u32 line) +{ + void *allocation; + + + ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size); + + + /* Check for an inadvertent size of zero bytes */ + + if (!size) { + _ACPI_REPORT_ERROR (module, line, component, + ("ut_allocate: Attempt to allocate zero bytes\n")); + size = 1; + } + + allocation = acpi_os_allocate (size); + if (!allocation) { + /* Report allocation error */ + _ACPI_REPORT_ERROR (module, line, component, + ("ut_allocate: Could not allocate size %X\n", (u32) size)); + + return_PTR (NULL); + } + + return_PTR (allocation); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_callocate + * + * PARAMETERS: Size - Size of the allocation + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: Subsystem equivalent of calloc. + * + ******************************************************************************/ + +void * +acpi_ut_callocate ( + acpi_size size, + u32 component, + char *module, + u32 line) +{ + void *allocation; + + + ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size); + + + /* Check for an inadvertent size of zero bytes */ + + if (!size) { + _ACPI_REPORT_ERROR (module, line, component, + ("ut_callocate: Attempt to allocate zero bytes\n")); + return_PTR (NULL); + } + + allocation = acpi_os_allocate (size); + if (!allocation) { + /* Report allocation error */ + + _ACPI_REPORT_ERROR (module, line, component, + ("ut_callocate: Could not allocate size %X\n", (u32) size)); + return_PTR (NULL); + } + + /* Clear the memory block */ + + ACPI_MEMSET (allocation, 0, size); + return_PTR (allocation); +} + + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS /* * These procedures are used for tracking memory leaks in the subsystem, and * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. * * Each memory allocation is tracked via a doubly linked list. Each * element contains the caller's component, module name, function name, and - * line number. Acpi_ut_allocate and Acpi_ut_callocate call - * Acpi_ut_track_allocation to add an element to the list; deletion - * occurs in the body of Acpi_ut_free. + * line number. acpi_ut_allocate and acpi_ut_callocate call + * acpi_ut_track_allocation to add an element to the list; deletion + * occurs in the body of acpi_ut_free. */ /******************************************************************************* * - * FUNCTION: Acpi_ut_find_allocation + * FUNCTION: acpi_ut_allocate_and_track + * + * PARAMETERS: Size - Size of the allocation + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: The subsystem's equivalent of malloc. + * + ******************************************************************************/ + +void * +acpi_ut_allocate_and_track ( + acpi_size size, + u32 component, + char *module, + u32 line) +{ + struct acpi_debug_mem_block *allocation; + acpi_status status; + + + allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_block), component, + module, line); + if (!allocation) { + return (NULL); + } + + status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, + ACPI_MEM_MALLOC, component, module, line); + if (ACPI_FAILURE (status)) { + acpi_os_free (allocation); + return (NULL); + } + + acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; + acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; + + return ((void *) &allocation->user_space); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_callocate_and_track + * + * PARAMETERS: Size - Size of the allocation + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: Subsystem equivalent of calloc. + * + ******************************************************************************/ + +void * +acpi_ut_callocate_and_track ( + acpi_size size, + u32 component, + char *module, + u32 line) +{ + struct acpi_debug_mem_block *allocation; + acpi_status status; + + + allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_block), component, + module, line); + if (!allocation) { + /* Report allocation error */ + + _ACPI_REPORT_ERROR (module, line, component, + ("ut_callocate: Could not allocate size %X\n", (u32) size)); + return (NULL); + } + + status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, + ACPI_MEM_CALLOC, component, module, line); + if (ACPI_FAILURE (status)) { + acpi_os_free (allocation); + return (NULL); + } + + acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; + acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; + + return ((void *) &allocation->user_space); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_free_and_track + * + * PARAMETERS: Allocation - Address of the memory to deallocate + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: None + * + * DESCRIPTION: Frees the memory at Allocation + * + ******************************************************************************/ + +void +acpi_ut_free_and_track ( + void *allocation, + u32 component, + char *module, + u32 line) +{ + struct acpi_debug_mem_block *debug_block; + acpi_status status; + + + ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation); + + + if (NULL == allocation) { + _ACPI_REPORT_ERROR (module, line, component, + ("acpi_ut_free: Attempt to delete a NULL address\n")); + + return_VOID; + } + + debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block, + (((char *) allocation) - sizeof (struct acpi_debug_mem_header))); + + acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++; + acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size; + + status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block, + component, module, line); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n", + acpi_format_exception (status))); + } + + acpi_os_free (debug_block); + + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); + + return_VOID; +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_find_allocation * - * PARAMETERS: Address - Address of allocated memory + * PARAMETERS: Allocation - Address of allocated memory * * RETURN: A list element if found; NULL otherwise. * @@ -218,15 +611,15 @@ * ******************************************************************************/ -acpi_debug_mem_block * +struct acpi_debug_mem_block * acpi_ut_find_allocation ( - u32 list_id, - void *address) + u32 list_id, + void *allocation) { - acpi_debug_mem_block *element; + struct acpi_debug_mem_block *element; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); if (list_id > ACPI_MEM_LIST_MAX) { @@ -238,7 +631,7 @@ /* Search for the address. */ while (element) { - if (element == address) { + if (element == allocation) { return (element); } @@ -251,11 +644,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_track_allocation + * FUNCTION: acpi_ut_track_allocation * - * PARAMETERS: Address - Address of allocated memory + * PARAMETERS: Allocation - Address of allocated memory * Size - Size of the allocation - * Alloc_type - MEM_MALLOC or MEM_CALLOC + * alloc_type - MEM_MALLOC or MEM_CALLOC * Component - Component type of caller * Module - Source file name of caller * Line - Line number of caller @@ -268,20 +661,20 @@ acpi_status acpi_ut_track_allocation ( - u32 list_id, - acpi_debug_mem_block *address, - u32 size, - u8 alloc_type, - u32 component, - NATIVE_CHAR *module, - u32 line) -{ - ACPI_MEMORY_LIST *mem_list; - acpi_debug_mem_block *element; - acpi_status status = AE_OK; + u32 list_id, + struct acpi_debug_mem_block *allocation, + acpi_size size, + u8 alloc_type, + u32 component, + char *module, + u32 line) +{ + struct acpi_memory_list *mem_list; + struct acpi_debug_mem_block *element; + acpi_status status = AE_OK; - FUNCTION_TRACE_PTR ("Ut_track_allocation", address); + ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation); if (list_id > ACPI_MEM_LIST_MAX) { @@ -289,55 +682,58 @@ } mem_list = &acpi_gbl_memory_lists[list_id]; - acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); + status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* * Search list for this address to make sure it is not already on the list. * This will catch several kinds of problems. */ - element = acpi_ut_find_allocation (list_id, address); + element = acpi_ut_find_allocation (list_id, allocation); if (element) { - REPORT_ERROR (("Ut_track_allocation: Address already present in list! (%p)\n", - address)); + ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n", + allocation)); - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, address)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation)); goto unlock_and_exit; } /* Fill in the instance data. */ - address->size = size; - address->alloc_type = alloc_type; - address->component = component; - address->line = line; + allocation->size = (u32) size; + allocation->alloc_type = alloc_type; + allocation->component = component; + allocation->line = line; - STRNCPY (address->module, module, MAX_MODULE_NAME); + ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME); /* Insert at list head */ if (mem_list->list_head) { - ((acpi_debug_mem_block *)(mem_list->list_head))->previous = address; + ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation; } - address->next = mem_list->list_head; - address->previous = NULL; + allocation->next = mem_list->list_head; + allocation->previous = NULL; - mem_list->list_head = address; + mem_list->list_head = allocation; unlock_and_exit: - acpi_ut_release_mutex (ACPI_MTX_MEMORY); + status = acpi_ut_release_mutex (ACPI_MTX_MEMORY); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_remove_allocation + * FUNCTION: acpi_ut_remove_allocation * - * PARAMETERS: Address - Address of allocated memory + * PARAMETERS: Allocation - Address of allocated memory * Component - Component type of caller * Module - Source file name of caller * Line - Line number of caller @@ -350,16 +746,17 @@ acpi_status acpi_ut_remove_allocation ( - u32 list_id, - acpi_debug_mem_block *address, - u32 component, - NATIVE_CHAR *module, - u32 line) + u32 list_id, + struct acpi_debug_mem_block *allocation, + u32 component, + char *module, + u32 line) { - ACPI_MEMORY_LIST *mem_list; + struct acpi_memory_list *mem_list; + acpi_status status; - FUNCTION_TRACE ("Ut_remove_allocation"); + ACPI_FUNCTION_TRACE ("ut_remove_allocation"); if (list_id > ACPI_MEM_LIST_MAX) { @@ -370,43 +767,44 @@ if (NULL == mem_list->list_head) { /* No allocations! */ - _REPORT_ERROR (module, line, component, - ("Ut_remove_allocation: Empty allocation list, nothing to free!\n")); + _ACPI_REPORT_ERROR (module, line, component, + ("ut_remove_allocation: Empty allocation list, nothing to free!\n")); return_ACPI_STATUS (AE_OK); } - - acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); + status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* Unlink */ - if (address->previous) { - (address->previous)->next = address->next; + if (allocation->previous) { + (allocation->previous)->next = allocation->next; } else { - mem_list->list_head = address->next; + mem_list->list_head = allocation->next; } - if (address->next) { - (address->next)->previous = address->previous; + if (allocation->next) { + (allocation->next)->previous = allocation->previous; } - /* Mark the segment as deleted */ - MEMSET (&address->user_space, 0xEA, address->size); + ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size); - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size %X\n", address->size)); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size %X\n", allocation->size)); - acpi_ut_release_mutex (ACPI_MTX_MEMORY); - return_ACPI_STATUS (AE_OK); + status = acpi_ut_release_mutex (ACPI_MTX_MEMORY); + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_dump_allocation_info + * FUNCTION: acpi_ut_dump_allocation_info * * PARAMETERS: * @@ -421,43 +819,43 @@ void) { /* - ACPI_MEMORY_LIST *Mem_list; + struct acpi_memory_list *mem_list; */ - FUNCTION_TRACE ("Ut_dump_allocation_info"); + ACPI_FUNCTION_TRACE ("ut_dump_allocation_info"); /* ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, ("%30s: %4d (%3d Kb)\n", "Current allocations", - Mem_list->Current_count, - ROUND_UP_TO_1K (Mem_list->Current_size))); + mem_list->current_count, + ROUND_UP_TO_1K (mem_list->current_size))); ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", - Mem_list->Max_concurrent_count, - ROUND_UP_TO_1K (Mem_list->Max_concurrent_size))); + mem_list->max_concurrent_count, + ROUND_UP_TO_1K (mem_list->max_concurrent_size))); ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", - Running_object_count, - ROUND_UP_TO_1K (Running_object_size))); + running_object_count, + ROUND_UP_TO_1K (running_object_size))); ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", - Running_alloc_count, - ROUND_UP_TO_1K (Running_alloc_size))); + running_alloc_count, + ROUND_UP_TO_1K (running_alloc_size))); ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, ("%30s: %4d (%3d Kb)\n", "Current Nodes", - Acpi_gbl_Current_node_count, - ROUND_UP_TO_1K (Acpi_gbl_Current_node_size))); + acpi_gbl_current_node_count, + ROUND_UP_TO_1K (acpi_gbl_current_node_size))); ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, ("%30s: %4d (%3d Kb)\n", "Max Nodes", - Acpi_gbl_Max_concurrent_node_count, - ROUND_UP_TO_1K ((Acpi_gbl_Max_concurrent_node_count * sizeof (acpi_namespace_node))))); + acpi_gbl_max_concurrent_node_count, + ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node))))); */ return_VOID; } @@ -465,7 +863,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_dump_allocations + * FUNCTION: acpi_ut_dump_allocations * * PARAMETERS: Component - Component(s) to dump info for. * Module - Module to dump info for. NULL means all. @@ -478,306 +876,124 @@ void acpi_ut_dump_allocations ( - u32 component, - NATIVE_CHAR *module) + u32 component, + char *module) { - acpi_debug_mem_block *element; - u32 i; - + struct acpi_debug_mem_block *element; + union acpi_descriptor *descriptor; + u32 num_outstanding = 0; - FUNCTION_TRACE ("Ut_dump_allocations"); - - element = acpi_gbl_memory_lists[0].list_head; - if (element == NULL) { - ACPI_DEBUG_PRINT ((ACPI_DB_OK, - "No outstanding allocations.\n")); - return_VOID; - } + ACPI_FUNCTION_TRACE ("ut_dump_allocations"); /* * Walk the allocation list. */ - acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); - - ACPI_DEBUG_PRINT ((ACPI_DB_OK, - "Outstanding allocations:\n")); + if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) { + return; + } - for (i = 1; ; i++) /* Just a counter */ { + element = acpi_gbl_memory_lists[0].list_head; + while (element) { if ((element->component & component) && - ((module == NULL) || (0 == STRCMP (module, element->module)))) { - if (((acpi_operand_object *)(&element->user_space))->common.type != ACPI_CACHED_OBJECT) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - "%p Len %04X %9.9s-%d", - &element->user_space, element->size, element->module, - element->line)); + ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) { + /* Ignore allocated objects that are in a cache */ + + descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space); + if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) { + acpi_os_printf ("%p Len %04X %9.9s-%d ", + descriptor, element->size, element->module, + element->line); /* Most of the elements will be internal objects. */ - switch (((acpi_operand_object *) - (&element->user_space))->common.data_type) { - case ACPI_DESC_TYPE_INTERNAL: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " Obj_type %12.12s R%d", - acpi_ut_get_type_name (((acpi_operand_object *)(&element->user_space))->common.type), - ((acpi_operand_object *)(&element->user_space))->common.reference_count)); + switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) { + case ACPI_DESC_TYPE_OPERAND: + acpi_os_printf ("obj_type %12.12s R%hd", + acpi_ut_get_type_name (descriptor->object.common.type), + descriptor->object.common.reference_count); break; case ACPI_DESC_TYPE_PARSER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " Parse_obj Opcode %04X", - ((acpi_parse_object *)(&element->user_space))->opcode)); + acpi_os_printf ("parse_obj aml_opcode %04hX", + descriptor->op.asl.aml_opcode); break; case ACPI_DESC_TYPE_NAMED: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " Node %4.4s", - (char*)&((acpi_namespace_node *)(&element->user_space))->name)); + acpi_os_printf ("Node %4.4s", + descriptor->node.name.ascii); break; case ACPI_DESC_TYPE_STATE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " Untyped State_obj")); + acpi_os_printf ("Untyped state_obj"); break; case ACPI_DESC_TYPE_STATE_UPDATE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " UPDATE State_obj")); + acpi_os_printf ("UPDATE state_obj"); break; case ACPI_DESC_TYPE_STATE_PACKAGE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " PACKAGE State_obj")); + acpi_os_printf ("PACKAGE state_obj"); break; case ACPI_DESC_TYPE_STATE_CONTROL: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " CONTROL State_obj")); + acpi_os_printf ("CONTROL state_obj"); break; case ACPI_DESC_TYPE_STATE_RPSCOPE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " ROOT-PARSE-SCOPE State_obj")); + acpi_os_printf ("ROOT-PARSE-SCOPE state_obj"); break; case ACPI_DESC_TYPE_STATE_PSCOPE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " PARSE-SCOPE State_obj")); + acpi_os_printf ("PARSE-SCOPE state_obj"); break; case ACPI_DESC_TYPE_STATE_WSCOPE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " WALK-SCOPE State_obj")); + acpi_os_printf ("WALK-SCOPE state_obj"); break; case ACPI_DESC_TYPE_STATE_RESULT: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " RESULT State_obj")); + acpi_os_printf ("RESULT state_obj"); break; case ACPI_DESC_TYPE_STATE_NOTIFY: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - " NOTIFY State_obj")); + acpi_os_printf ("NOTIFY state_obj"); + break; + + case ACPI_DESC_TYPE_STATE_THREAD: + acpi_os_printf ("THREAD state_obj"); + break; + + default: + /* All types should appear above */ break; } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "\n")); + acpi_os_printf ( "\n"); + num_outstanding++; } } - - if (element->next == NULL) { - break; - } - element = element->next; } - acpi_ut_release_mutex (ACPI_MTX_MEMORY); - - ACPI_DEBUG_PRINT ((ACPI_DB_OK, - "Total number of unfreed allocations = %d(%X)\n", i,i)); - - - return_VOID; - -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ut_allocate - * - * PARAMETERS: Size - Size of the allocation - * Component - Component type of caller - * Module - Source file name of caller - * Line - Line number of caller - * - * RETURN: Address of the allocated memory on success, NULL on failure. - * - * DESCRIPTION: The subsystem's equivalent of malloc. - * - ******************************************************************************/ - -void * -acpi_ut_allocate ( - u32 size, - u32 component, - NATIVE_CHAR *module, - u32 line) -{ - acpi_debug_mem_block *address; - acpi_status status; + (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY); + /* Print summary */ - FUNCTION_TRACE_U32 ("Ut_allocate", size); - - - /* Check for an inadvertent size of zero bytes */ - - if (!size) { - _REPORT_ERROR (module, line, component, - ("Ut_allocate: Attempt to allocate zero bytes\n")); - size = 1; - } - - address = acpi_os_allocate (size + sizeof (acpi_debug_mem_block)); - if (!address) { - /* Report allocation error */ - - _REPORT_ERROR (module, line, component, - ("Ut_allocate: Could not allocate size %X\n", size)); - - return_PTR (NULL); - } - - status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, address, size, - MEM_MALLOC, component, module, line); - if (ACPI_FAILURE (status)) { - acpi_os_free (address); - return_PTR (NULL); - } - - acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; - acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += size; - - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", address, size)); - - return_PTR ((void *) &address->user_space); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ut_callocate - * - * PARAMETERS: Size - Size of the allocation - * Component - Component type of caller - * Module - Source file name of caller - * Line - Line number of caller - * - * RETURN: Address of the allocated memory on success, NULL on failure. - * - * DESCRIPTION: Subsystem equivalent of calloc. - * - ******************************************************************************/ - -void * -acpi_ut_callocate ( - u32 size, - u32 component, - NATIVE_CHAR *module, - u32 line) -{ - acpi_debug_mem_block *address; - acpi_status status; - - - FUNCTION_TRACE_U32 ("Ut_callocate", size); - - - /* Check for an inadvertent size of zero bytes */ - - if (!size) { - _REPORT_ERROR (module, line, component, - ("Ut_callocate: Attempt to allocate zero bytes\n")); - return_PTR (NULL); - } - - - address = acpi_os_callocate (size + sizeof (acpi_debug_mem_block)); - if (!address) { - /* Report allocation error */ - - _REPORT_ERROR (module, line, component, - ("Ut_callocate: Could not allocate size %X\n", size)); - return_PTR (NULL); - } - - status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, address, size, - MEM_CALLOC, component, module, line); - if (ACPI_FAILURE (status)) { - acpi_os_free (address); - return_PTR (NULL); + if (!num_outstanding) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No outstanding allocations.\n")); } - - acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; - acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += size; - - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", address, size)); - return_PTR ((void *) &address->user_space); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ut_free - * - * PARAMETERS: Address - Address of the memory to deallocate - * Component - Component type of caller - * Module - Source file name of caller - * Line - Line number of caller - * - * RETURN: None - * - * DESCRIPTION: Frees the memory at Address - * - ******************************************************************************/ - -void -acpi_ut_free ( - void *address, - u32 component, - NATIVE_CHAR *module, - u32 line) -{ - acpi_debug_mem_block *debug_block; - - - FUNCTION_TRACE_PTR ("Ut_free", address); - - - if (NULL == address) { - _REPORT_ERROR (module, line, component, - ("Acpi_ut_free: Trying to delete a NULL address\n")); - - return_VOID; + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "%d(%X) Outstanding allocations\n", + num_outstanding, num_outstanding)); } - debug_block = (acpi_debug_mem_block *) - (((char *) address) - sizeof (acpi_debug_mem_header)); - - acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++; - acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size; - - acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block, - component, module, line); - acpi_os_free (debug_block); - - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", address)); - return_VOID; } + #endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */ diff -urN linux-2.4.21/drivers/acpi/utilities/utcopy.c linux-2.4.22/drivers/acpi/utilities/utcopy.c --- linux-2.4.21/drivers/acpi/utilities/utcopy.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utcopy.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,46 +1,62 @@ /****************************************************************************** * * Module Name: utcopy - Internal to external object translation utilities - * $Revision: 83 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "amlcode.h" +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utcopy") + ACPI_MODULE_NAME ("utcopy") /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_isimple_to_esimple + * FUNCTION: acpi_ut_copy_isimple_to_esimple * - * PARAMETERS: *Internal_object - Pointer to the object we are examining + * PARAMETERS: *internal_object - Pointer to the object we are examining * *Buffer - Where the object is returned - * *Space_used - Where the data length is returned + * *space_used - Where the data length is returned * * RETURN: Status * @@ -53,106 +69,77 @@ static acpi_status acpi_ut_copy_isimple_to_esimple ( - acpi_operand_object *internal_object, - acpi_object *external_object, - u8 *data_space, - u32 *buffer_space_used) + union acpi_operand_object *internal_object, + union acpi_object *external_object, + u8 *data_space, + acpi_size *buffer_space_used) { - u32 length = 0; - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ut_copy_isimple_to_esimple"); + ACPI_FUNCTION_TRACE ("ut_copy_isimple_to_esimple"); + *buffer_space_used = 0; + /* * Check for NULL object case (could be an uninitialized - * package element + * package element) */ if (!internal_object) { - *buffer_space_used = 0; return_ACPI_STATUS (AE_OK); } /* Always clear the external object */ - MEMSET (external_object, 0, sizeof (acpi_object)); + ACPI_MEMSET (external_object, 0, sizeof (union acpi_object)); /* * In general, the external object will be the same type as * the internal object */ - external_object->type = internal_object->common.type; + external_object->type = ACPI_GET_OBJECT_TYPE (internal_object); /* However, only a limited number of external types are supported */ - switch (internal_object->common.type) { - + switch (ACPI_GET_OBJECT_TYPE (internal_object)) { case ACPI_TYPE_STRING: - length = internal_object->string.length + 1; + external_object->string.pointer = (char *) data_space; external_object->string.length = internal_object->string.length; - external_object->string.pointer = (NATIVE_CHAR *) data_space; - MEMCPY ((void *) data_space, (void *) internal_object->string.pointer, length); + *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD ((acpi_size) internal_object->string.length + 1); + + ACPI_MEMCPY ((void *) data_space, (void *) internal_object->string.pointer, + (acpi_size) internal_object->string.length + 1); break; case ACPI_TYPE_BUFFER: - length = internal_object->buffer.length; - external_object->buffer.length = internal_object->buffer.length; external_object->buffer.pointer = data_space; - MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer, length); + external_object->buffer.length = internal_object->buffer.length; + *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (internal_object->string.length); + + ACPI_MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer, + internal_object->buffer.length); break; case ACPI_TYPE_INTEGER: - external_object->integer.value= internal_object->integer.value; + external_object->integer.value = internal_object->integer.value; break; - case INTERNAL_TYPE_REFERENCE: + case ACPI_TYPE_LOCAL_REFERENCE: /* * This is an object reference. Attempt to dereference it. */ switch (internal_object->reference.opcode) { - case AML_ZERO_OP: - external_object->type = ACPI_TYPE_INTEGER; - external_object->integer.value = 0; - break; - - case AML_ONE_OP: - external_object->type = ACPI_TYPE_INTEGER; - external_object->integer.value = 1; - break; - - case AML_ONES_OP: - external_object->type = ACPI_TYPE_INTEGER; - external_object->integer.value = ACPI_INTEGER_MAX; - break; - - case AML_REVISION_OP: - external_object->type = ACPI_TYPE_INTEGER; - external_object->integer.value = ACPI_CA_SUPPORT_LEVEL; - break; - case AML_INT_NAMEPATH_OP: - /* - * This is a named reference, get the string. We already know that - * we have room for it, use max length - */ - length = MAX_STRING_LENGTH; - external_object->type = ACPI_TYPE_STRING; - external_object->string.pointer = (NATIVE_CHAR *) data_space; - status = acpi_ns_handle_to_pathname ((acpi_handle *) internal_object->reference.node, - &length, (char *) data_space); - - /* Converted (external) string length is returned from above */ - external_object->string.length = length; - break; + /* For namepath, return the object handle ("reference") */ default: /* @@ -168,7 +155,7 @@ case ACPI_TYPE_PROCESSOR: - external_object->processor.proc_id = internal_object->processor.proc_id; + external_object->processor.proc_id = internal_object->processor.proc_id; external_object->processor.pblk_address = internal_object->processor.address; external_object->processor.pblk_length = internal_object->processor.length; break; @@ -189,21 +176,17 @@ * There is no corresponding external object type */ return_ACPI_STATUS (AE_SUPPORT); - break; } - - *buffer_space_used = (u32) ROUND_UP_TO_NATIVE_WORD (length); - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_ielement_to_eelement + * FUNCTION: acpi_ut_copy_ielement_to_eelement * - * PARAMETERS: ACPI_PKG_CALLBACK + * PARAMETERS: acpi_pkg_callback * * RETURN: Status * @@ -213,39 +196,39 @@ acpi_status acpi_ut_copy_ielement_to_eelement ( - u8 object_type, - acpi_operand_object *source_object, - acpi_generic_state *state, - void *context) -{ - acpi_status status = AE_OK; - acpi_pkg_info *info = (acpi_pkg_info *) context; - u32 object_space; - u32 this_index; - acpi_object *target_object; + u8 object_type, + union acpi_operand_object *source_object, + union acpi_generic_state *state, + void *context) +{ + acpi_status status = AE_OK; + struct acpi_pkg_info *info = (struct acpi_pkg_info *) context; + acpi_size object_space; + u32 this_index; + union acpi_object *target_object; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); this_index = state->pkg.index; - target_object = (acpi_object *) - &((acpi_object *)(state->pkg.dest_object))->package.elements[this_index]; + target_object = (union acpi_object *) + &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index]; switch (object_type) { case ACPI_COPY_TYPE_SIMPLE: /* - * This is a simple or null object -- get the size + * This is a simple or null object */ status = acpi_ut_copy_isimple_to_esimple (source_object, target_object, info->free_space, &object_space); if (ACPI_FAILURE (status)) { return (status); } - break; + case ACPI_COPY_TYPE_PACKAGE: /* @@ -253,7 +236,7 @@ */ target_object->type = ACPI_TYPE_PACKAGE; target_object->package.count = source_object->package.count; - target_object->package.elements = (acpi_object *) info->free_space; + target_object->package.elements = ACPI_CAST_PTR (union acpi_object, info->free_space); /* * Pass the new package object back to the package walk routine @@ -264,29 +247,28 @@ * Save space for the array of objects (Package elements) * update the buffer length counter */ - object_space = (u32) ROUND_UP_TO_NATIVE_WORD ( - target_object->package.count * sizeof (acpi_object)); + object_space = ACPI_ROUND_UP_TO_NATIVE_WORD ( + (acpi_size) target_object->package.count * sizeof (union acpi_object)); break; + default: return (AE_BAD_PARAMETER); } - info->free_space += object_space; info->length += object_space; - return (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_ipackage_to_epackage + * FUNCTION: acpi_ut_copy_ipackage_to_epackage * - * PARAMETERS: *Internal_object - Pointer to the object we are returning + * PARAMETERS: *internal_object - Pointer to the object we are returning * *Buffer - Where the object is returned - * *Space_used - Where the object length is returned + * *space_used - Where the object length is returned * * RETURN: Status * @@ -295,66 +277,64 @@ * * The buffer is assumed to have sufficient space for the object. * The caller must have verified the buffer length needed using the - * Acpi_ut_get_object_size function before calling this function. + * acpi_ut_get_object_size function before calling this function. * ******************************************************************************/ static acpi_status acpi_ut_copy_ipackage_to_epackage ( - acpi_operand_object *internal_object, - u8 *buffer, - u32 *space_used) + union acpi_operand_object *internal_object, + u8 *buffer, + acpi_size *space_used) { - acpi_object *external_object; - acpi_status status; - acpi_pkg_info info; + union acpi_object *external_object; + acpi_status status; + struct acpi_pkg_info info; - FUNCTION_TRACE ("Ut_copy_ipackage_to_epackage"); + ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_epackage"); /* * First package at head of the buffer */ - external_object = (acpi_object *) buffer; + external_object = ACPI_CAST_PTR (union acpi_object, buffer); /* * Free space begins right after the first package */ - info.length = 0; + info.length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); + info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); info.object_space = 0; info.num_packages = 1; - info.free_space = buffer + ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object)); - - - external_object->type = internal_object->common.type; - external_object->package.count = internal_object->package.count; - external_object->package.elements = (acpi_object *) info.free_space; + external_object->type = ACPI_GET_OBJECT_TYPE (internal_object); + external_object->package.count = internal_object->package.count; + external_object->package.elements = ACPI_CAST_PTR (union acpi_object, info.free_space); /* - * Build an array of ACPI_OBJECTS in the buffer + * Leave room for an array of ACPI_OBJECTS in the buffer * and move the free space past it */ + info.length += (acpi_size) external_object->package.count * + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); info.free_space += external_object->package.count * - ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object)); - + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); status = acpi_ut_walk_package_tree (internal_object, external_object, acpi_ut_copy_ielement_to_eelement, &info); *space_used = info.length; - return_ACPI_STATUS (status); - } + /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_iobject_to_eobject + * FUNCTION: acpi_ut_copy_iobject_to_eobject * - * PARAMETERS: *Internal_object - The internal object to be converted - * *Buffer_ptr - Where the object is returned + * PARAMETERS: *internal_object - The internal object to be converted + * *buffer_ptr - Where the object is returned * * RETURN: Status * @@ -365,16 +345,16 @@ acpi_status acpi_ut_copy_iobject_to_eobject ( - acpi_operand_object *internal_object, - acpi_buffer *ret_buffer) + union acpi_operand_object *internal_object, + struct acpi_buffer *ret_buffer) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Ut_copy_iobject_to_eobject"); + ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_eobject"); - if (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE)) { + if (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE) { /* * Package object: Copy all subobjects (including * nested packages) @@ -382,21 +362,20 @@ status = acpi_ut_copy_ipackage_to_epackage (internal_object, ret_buffer->pointer, &ret_buffer->length); } - else { /* * Build a simple object (no nested objects) */ status = acpi_ut_copy_isimple_to_esimple (internal_object, - (acpi_object *) ret_buffer->pointer, + (union acpi_object *) ret_buffer->pointer, ((u8 *) ret_buffer->pointer + - ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object))), + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))), &ret_buffer->length); /* * build simple does not include the object size in the length * so we add it in here */ - ret_buffer->length += sizeof (acpi_object); + ret_buffer->length += sizeof (union acpi_object); } return_ACPI_STATUS (status); @@ -405,10 +384,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_esimple_to_isimple + * FUNCTION: acpi_ut_copy_esimple_to_isimple * - * PARAMETERS: *External_object - The external object to be converted - * *Internal_object - Where the internal object is returned + * PARAMETERS: *external_object - The external object to be converted + * *internal_object - Where the internal object is returned * * RETURN: Status * @@ -421,13 +400,13 @@ acpi_status acpi_ut_copy_esimple_to_isimple ( - acpi_object *external_object, - acpi_operand_object **ret_internal_object) + union acpi_object *external_object, + union acpi_operand_object **ret_internal_object) { - acpi_operand_object *internal_object; + union acpi_operand_object *internal_object; - FUNCTION_TRACE ("Ut_copy_esimple_to_isimple"); + ACPI_FUNCTION_TRACE ("ut_copy_esimple_to_isimple"); /* @@ -449,7 +428,6 @@ * Whatever other type -- it is not supported */ return_ACPI_STATUS (AE_SUPPORT); - break; } @@ -459,14 +437,15 @@ case ACPI_TYPE_STRING: - internal_object->string.pointer = ACPI_MEM_CALLOCATE (external_object->string.length + 1); + internal_object->string.pointer = + ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1); if (!internal_object->string.pointer) { return_ACPI_STATUS (AE_NO_MEMORY); } - MEMCPY (internal_object->string.pointer, - external_object->string.pointer, - external_object->string.length); + ACPI_MEMCPY (internal_object->string.pointer, + external_object->string.pointer, + external_object->string.length); internal_object->string.length = external_object->string.length; break; @@ -474,14 +453,15 @@ case ACPI_TYPE_BUFFER: - internal_object->buffer.pointer = ACPI_MEM_CALLOCATE (external_object->buffer.length); + internal_object->buffer.pointer = + ACPI_MEM_CALLOCATE (external_object->buffer.length); if (!internal_object->buffer.pointer) { return_ACPI_STATUS (AE_NO_MEMORY); } - MEMCPY (internal_object->buffer.pointer, - external_object->buffer.pointer, - external_object->buffer.length); + ACPI_MEMCPY (internal_object->buffer.pointer, + external_object->buffer.pointer, + external_object->buffer.length); internal_object->buffer.length = external_object->buffer.length; break; @@ -491,8 +471,11 @@ internal_object->integer.value = external_object->integer.value; break; - } + default: + /* Other types can't get here */ + break; + } *ret_internal_object = internal_object; return_ACPI_STATUS (AE_OK); @@ -505,65 +488,64 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_epackage_to_ipackage + * FUNCTION: acpi_ut_copy_epackage_to_ipackage * - * PARAMETERS: *Internal_object - Pointer to the object we are returning - * *Buffer - Where the object is returned - * *Space_used - Where the length of the object is returned + * PARAMETERS: *internal_object - Pointer to the object we are returning + * *Buffer - Where the object is returned + * *space_used - Where the length of the object is returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function is called to place a package object in a user * buffer. A package object by definition contains other objects. * * The buffer is assumed to have sufficient space for the object. * The caller must have verified the buffer length needed using the - * Acpi_ut_get_object_size function before calling this function. + * acpi_ut_get_object_size function before calling this function. * ******************************************************************************/ static acpi_status acpi_ut_copy_epackage_to_ipackage ( - acpi_operand_object *internal_object, - u8 *buffer, - u32 *space_used) -{ - u8 *free_space; - acpi_object *external_object; - u32 length = 0; - u32 this_index; - u32 object_space = 0; - acpi_operand_object *this_internal_obj; - acpi_object *this_external_obj; + union acpi_operand_object *internal_object, + u8 *buffer, + u32 *space_used) +{ + u8 *free_space; + union acpi_object *external_object; + u32 length = 0; + u32 this_index; + u32 object_space = 0; + union acpi_operand_object *this_internal_obj; + union acpi_object *this_external_obj; - FUNCTION_TRACE ("Ut_copy_epackage_to_ipackage"); + ACPI_FUNCTION_TRACE ("ut_copy_epackage_to_ipackage"); /* * First package at head of the buffer */ - external_object = (acpi_object *)buffer; + external_object = (union acpi_object *)buffer; /* * Free space begins right after the first package */ - free_space = buffer + sizeof(acpi_object); + free_space = buffer + sizeof(union acpi_object); - external_object->type = internal_object->common.type; + external_object->type = ACPI_GET_OBJECT_TYPE (internal_object); external_object->package.count = internal_object->package.count; - external_object->package.elements = (acpi_object *)free_space; - + external_object->package.elements = (union acpi_object *)free_space; /* * Build an array of ACPI_OBJECTS in the buffer * and move the free space past it */ - free_space += external_object->package.count * sizeof(acpi_object); + free_space += external_object->package.count * sizeof(union acpi_object); - /* Call Walk_package */ + /* Call walk_package */ } @@ -572,10 +554,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_eobject_to_iobject + * FUNCTION: acpi_ut_copy_eobject_to_iobject * - * PARAMETERS: *Internal_object - The external object to be converted - * *Buffer_ptr - Where the internal object is returned + * PARAMETERS: *internal_object - The external object to be converted + * *buffer_ptr - Where the internal object is returned * * RETURN: Status - the status of the call * @@ -585,29 +567,19 @@ acpi_status acpi_ut_copy_eobject_to_iobject ( - acpi_object *external_object, - acpi_operand_object **internal_object) + union acpi_object *external_object, + union acpi_operand_object **internal_object) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Ut_copy_eobject_to_iobject"); + ACPI_FUNCTION_TRACE ("ut_copy_eobject_to_iobject"); if (external_object->type == ACPI_TYPE_PACKAGE) { /* - * Package objects contain other objects (which can be objects) - * buildpackage does it all - * - * TBD: Package conversion must be completed and tested - * NOTE: this code converts packages as input parameters to - * control methods only. This is a very, very rare case. + * Packages as external input to control methods are not supported, */ -/* - Status = Acpi_ut_copy_epackage_to_ipackage(Internal_object, - Ret_buffer->Pointer, - &Ret_buffer->Length); -*/ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Packages as parameters not implemented!\n")); @@ -627,11 +599,112 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_ielement_to_ielement + * FUNCTION: acpi_ut_copy_simple_object * - * PARAMETERS: ACPI_PKG_CALLBACK + * PARAMETERS: source_desc - The internal object to be copied + * dest_desc - New target object * - * RETURN: Status - the status of the call + * RETURN: Status + * + * DESCRIPTION: Simple copy of one internal object to another. Reference count + * of the destination object is preserved. + * + ******************************************************************************/ + +acpi_status +acpi_ut_copy_simple_object ( + union acpi_operand_object *source_desc, + union acpi_operand_object *dest_desc) +{ + u16 reference_count; + union acpi_operand_object *next_object; + + + /* Save fields from destination that we don't want to overwrite */ + + reference_count = dest_desc->common.reference_count; + next_object = dest_desc->common.next_object; + + /* Copy the entire source object over the destination object*/ + + ACPI_MEMCPY ((char *) dest_desc, (char *) source_desc, + sizeof (union acpi_operand_object)); + + /* Restore the saved fields */ + + dest_desc->common.reference_count = reference_count; + dest_desc->common.next_object = next_object; + + /* Handle the objects with extra data */ + + switch (ACPI_GET_OBJECT_TYPE (dest_desc)) { + case ACPI_TYPE_BUFFER: + + dest_desc->buffer.node = NULL; + dest_desc->common.flags = source_desc->common.flags; + + /* + * Allocate and copy the actual buffer if and only if: + * 1) There is a valid buffer pointer + * 2) The buffer is not static (not in an ACPI table) (in this case, + * the actual pointer was already copied above) + */ + if ((source_desc->buffer.pointer) && + (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { + dest_desc->buffer.pointer = NULL; + + /* Create an actual buffer only if length > 0 */ + + if (source_desc->buffer.length) { + dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length); + if (!dest_desc->buffer.pointer) { + return (AE_NO_MEMORY); + } + + /* Copy the actual buffer data */ + + ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer, + source_desc->buffer.length); + } + } + break; + + case ACPI_TYPE_STRING: + + /* + * Allocate and copy the actual string if and only if: + * 1) There is a valid string pointer + * 2) The string is not static (not in an ACPI table) (in this case, + * the actual pointer was already copied above) + */ + if ((source_desc->string.pointer) && + (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { + dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1); + if (!dest_desc->string.pointer) { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer, + (acpi_size) source_desc->string.length + 1); + } + break; + + default: + /* Nothing to do for other simple objects */ + break; + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_copy_ielement_to_ielement + * + * PARAMETERS: acpi_pkg_callback + * + * RETURN: Status * * DESCRIPTION: Copy one package element to another package element * @@ -639,58 +712,78 @@ acpi_status acpi_ut_copy_ielement_to_ielement ( - u8 object_type, - acpi_operand_object *source_object, - acpi_generic_state *state, - void *context) -{ - acpi_status status = AE_OK; - u32 this_index; - acpi_operand_object **this_target_ptr; - acpi_operand_object *target_object; + u8 object_type, + union acpi_operand_object *source_object, + union acpi_generic_state *state, + void *context) +{ + acpi_status status = AE_OK; + u32 this_index; + union acpi_operand_object **this_target_ptr; + union acpi_operand_object *target_object; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); this_index = state->pkg.index; - this_target_ptr = (acpi_operand_object **) + this_target_ptr = (union acpi_operand_object **) &state->pkg.dest_object->package.elements[this_index]; switch (object_type) { - case 0: + case ACPI_COPY_TYPE_SIMPLE: - /* - * This is a simple object, just copy it - */ - target_object = acpi_ut_create_internal_object (source_object->common.type); - if (!target_object) { - return (AE_NO_MEMORY); - } + /* A null source object indicates a (legal) null package element */ - status = acpi_ex_store_object_to_object (source_object, target_object, - (acpi_walk_state *) context); - if (ACPI_FAILURE (status)) { - return (status); + if (source_object) { + /* + * This is a simple object, just copy it + */ + target_object = acpi_ut_create_internal_object ( + ACPI_GET_OBJECT_TYPE (source_object)); + if (!target_object) { + return (AE_NO_MEMORY); + } + + status = acpi_ut_copy_simple_object (source_object, target_object); + if (ACPI_FAILURE (status)) { + return (status); + } + + *this_target_ptr = target_object; } + else { + /* Pass through a null element */ - *this_target_ptr = target_object; + *this_target_ptr = NULL; + } break; - case 1: + case ACPI_COPY_TYPE_PACKAGE: + /* * This object is a package - go down another nesting level * Create and build the package object */ target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE); if (!target_object) { - /* TBD: must delete package created up to this point */ - return (AE_NO_MEMORY); } target_object->package.count = source_object->package.count; + target_object->common.flags = source_object->common.flags; + + /* + * Create the object array + */ + target_object->package.elements = + ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) * + sizeof (void *)); + if (!target_object->package.elements) { + ACPI_MEM_FREE (target_object); + return (AE_NO_MEMORY); + } /* * Pass the new package object back to the package walk routine @@ -703,21 +796,21 @@ *this_target_ptr = target_object; break; + default: return (AE_BAD_PARAMETER); } - return (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_copy_ipackage_to_ipackage + * FUNCTION: acpi_ut_copy_ipackage_to_ipackage * - * PARAMETERS: *Source_obj - Pointer to the source package object - * *Dest_obj - Where the internal object is returned + * PARAMETERS: *source_obj - Pointer to the source package object + * *dest_obj - Where the internal object is returned * * RETURN: Status - the status of the call * @@ -728,37 +821,92 @@ acpi_status acpi_ut_copy_ipackage_to_ipackage ( - acpi_operand_object *source_obj, - acpi_operand_object *dest_obj, - acpi_walk_state *walk_state) + union acpi_operand_object *source_obj, + union acpi_operand_object *dest_obj, + struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE ("Ut_copy_ipackage_to_ipackage"); + ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage"); - dest_obj->common.type = source_obj->common.type; + dest_obj->common.type = ACPI_GET_OBJECT_TYPE (source_obj); + dest_obj->common.flags = source_obj->common.flags; dest_obj->package.count = source_obj->package.count; - /* * Create the object array and walk the source package tree */ - dest_obj->package.elements = ACPI_MEM_CALLOCATE ((source_obj->package.count + 1) * - sizeof (void *)); - dest_obj->package.next_element = dest_obj->package.elements; - + dest_obj->package.elements = ACPI_MEM_CALLOCATE ( + ((acpi_size) source_obj->package.count + 1) * + sizeof (void *)); if (!dest_obj->package.elements) { - REPORT_ERROR ( - ("Aml_build_copy_internal_package_object: Package allocation failure\n")); + ACPI_REPORT_ERROR ( + ("aml_build_copy_internal_package_object: Package allocation failure\n")); return_ACPI_STATUS (AE_NO_MEMORY); } - + /* + * Copy the package element-by-element by walking the package "tree". + * This handles nested packages of arbitrary depth. + */ status = acpi_ut_walk_package_tree (source_obj, dest_obj, acpi_ut_copy_ielement_to_ielement, walk_state); + if (ACPI_FAILURE (status)) { + /* On failure, delete the destination package object */ + + acpi_ut_remove_reference (dest_obj); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_copy_iobject_to_iobject + * + * PARAMETERS: walk_state - Current walk state + * source_desc - The internal object to be copied + * dest_desc - Where the copied object is returned + * + * RETURN: Status + * + * DESCRIPTION: Copy an internal object to a new internal object + * + ******************************************************************************/ + +acpi_status +acpi_ut_copy_iobject_to_iobject ( + union acpi_operand_object *source_desc, + union acpi_operand_object **dest_desc, + struct acpi_walk_state *walk_state) +{ + acpi_status status = AE_OK; + + + ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_iobject"); + + + /* Create the top level object */ + + *dest_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (source_desc)); + if (!*dest_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Copy the object and possible subobjects */ + + if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_PACKAGE) { + status = acpi_ut_copy_ipackage_to_ipackage (source_desc, *dest_desc, + walk_state); + } + else { + status = acpi_ut_copy_simple_object (source_desc, *dest_desc); + } return_ACPI_STATUS (status); } + diff -urN linux-2.4.21/drivers/acpi/utilities/utdebug.c linux-2.4.22/drivers/acpi/utilities/utdebug.c --- linux-2.4.21/drivers/acpi/utilities/utdebug.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/acpi/utilities/utdebug.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,46 +1,63 @@ /****************************************************************************** * * Module Name: utdebug - Debug print routines - * $Revision: 90 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utdebug") + ACPI_MODULE_NAME ("utdebug") -u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF; -char *acpi_gbl_fn_entry_str = "----Entry"; -char *acpi_gbl_fn_exit_str = "----Exit-"; +#ifdef ACPI_DEBUG_OUTPUT - -#ifdef ACPI_DEBUG +static u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF; +static char *acpi_gbl_fn_entry_str = "----Entry"; +static char *acpi_gbl_fn_exit_str = "----Exit-"; /***************************************************************************** * - * FUNCTION: Acpi_ut_init_stack_ptr_trace + * FUNCTION: acpi_ut_init_stack_ptr_trace * * PARAMETERS: None * @@ -54,16 +71,16 @@ acpi_ut_init_stack_ptr_trace ( void) { - u32 current_sp; + u32 current_sp; - acpi_gbl_entry_stack_pointer = (unsigned long) ¤t_sp; + acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF (¤t_sp, NULL); } /***************************************************************************** * - * FUNCTION: Acpi_ut_track_stack_ptr + * FUNCTION: acpi_ut_track_stack_ptr * * PARAMETERS: None * @@ -77,9 +94,10 @@ acpi_ut_track_stack_ptr ( void) { - u32 current_sp; + acpi_size current_sp; + - current_sp = (u32) ¤t_sp; + current_sp = ACPI_PTR_DIFF (¤t_sp, NULL); if (current_sp < acpi_gbl_lowest_stack_pointer) { acpi_gbl_lowest_stack_pointer = current_sp; @@ -93,13 +111,13 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_debug_print + * FUNCTION: acpi_ut_debug_print * - * PARAMETERS: Debug_level - Requested debug print level - * Proc_name - Caller's procedure name - * Module_name - Caller's module name (for error output) - * Line_number - Caller's line number (for error output) - * Component_id - Caller's component ID (for error output) + * PARAMETERS: debug_level - Requested debug print level + * proc_name - Caller's procedure name + * module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * component_id - Caller's component ID (for error output) * * Format - Printf format field * ... - Optional printf arguments @@ -111,15 +129,15 @@ * ****************************************************************************/ -void +void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print ( - u32 requested_debug_level, - u32 line_number, - acpi_debug_print_info *dbg_info, - char *format, + u32 requested_debug_level, + u32 line_number, + struct acpi_debug_print_info *dbg_info, + char *format, ...) { - u32 thread_id; + u32 thread_id; va_list args; @@ -131,7 +149,6 @@ return; } - /* * Thread tracking and context switch notification */ @@ -150,14 +167,13 @@ * Display the module name, current line number, thread ID (if requested), * current procedure nesting level, and the current procedure name */ - acpi_os_printf ("%8s-%04d ", dbg_info->module_name, line_number); + acpi_os_printf ("%8s-%04ld ", dbg_info->module_name, line_number); if (ACPI_LV_THREADS & acpi_dbg_level) { - acpi_os_printf ("[%04X] ", thread_id, acpi_gbl_nesting_level, dbg_info->proc_name); + acpi_os_printf ("[%04lX] ", thread_id); } - acpi_os_printf ("[%02d] %-22.22s: ", acpi_gbl_nesting_level, dbg_info->proc_name); - + acpi_os_printf ("[%02ld] %-22.22s: ", acpi_gbl_nesting_level, dbg_info->proc_name); va_start (args, format); acpi_os_vprintf (format, args); @@ -166,30 +182,30 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_debug_print_raw + * FUNCTION: acpi_ut_debug_print_raw * - * PARAMETERS: Requested_debug_level - Requested debug print level - * Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: requested_debug_level - Requested debug print level + * line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * Format - Printf format field * ... - Optional printf arguments * * RETURN: None * * DESCRIPTION: Print message with no headers. Has same interface as - * Debug_print so that the same macros can be used. + * debug_print so that the same macros can be used. * ****************************************************************************/ -void +void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print_raw ( - u32 requested_debug_level, - u32 line_number, - acpi_debug_print_info *dbg_info, - char *format, + u32 requested_debug_level, + u32 line_number, + struct acpi_debug_print_info *dbg_info, + char *format, ...) { va_list args; @@ -201,32 +217,31 @@ } va_start (args, format); - acpi_os_vprintf (format, args); } /***************************************************************************** * - * FUNCTION: Acpi_ut_trace + * FUNCTION: acpi_ut_trace * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * * RETURN: None * * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level + * set in debug_level * ****************************************************************************/ void acpi_ut_trace ( - u32 line_number, - acpi_debug_print_info *dbg_info) + u32 line_number, + struct acpi_debug_print_info *dbg_info) { acpi_gbl_nesting_level++; @@ -239,27 +254,27 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_trace_ptr + * FUNCTION: acpi_ut_trace_ptr * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * Pointer - Pointer to display * * RETURN: None * * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level + * set in debug_level * ****************************************************************************/ void acpi_ut_trace_ptr ( - u32 line_number, - acpi_debug_print_info *dbg_info, - void *pointer) + u32 line_number, + struct acpi_debug_print_info *dbg_info, + void *pointer) { acpi_gbl_nesting_level++; acpi_ut_track_stack_ptr (); @@ -271,27 +286,27 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_trace_str + * FUNCTION: acpi_ut_trace_str * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * String - Additional string to display * * RETURN: None * * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level + * set in debug_level * ****************************************************************************/ void acpi_ut_trace_str ( - u32 line_number, - acpi_debug_print_info *dbg_info, - NATIVE_CHAR *string) + u32 line_number, + struct acpi_debug_print_info *dbg_info, + char *string) { acpi_gbl_nesting_level++; @@ -304,27 +319,27 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_trace_u32 + * FUNCTION: acpi_ut_trace_u32 * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * Integer - Integer to display * * RETURN: None * * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level + * set in debug_level * ****************************************************************************/ void acpi_ut_trace_u32 ( - u32 line_number, - acpi_debug_print_info *dbg_info, - u32 integer) + u32 line_number, + struct acpi_debug_print_info *dbg_info, + u32 integer) { acpi_gbl_nesting_level++; @@ -337,25 +352,25 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_exit + * FUNCTION: acpi_ut_exit * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * * RETURN: None * * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level + * set in debug_level * ****************************************************************************/ void acpi_ut_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info) + u32 line_number, + struct acpi_debug_print_info *dbg_info) { acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, @@ -367,27 +382,27 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_status_exit + * FUNCTION: acpi_ut_status_exit * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * Status - Exit status code * * RETURN: None * * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level. Prints exit status also. + * set in debug_level. Prints exit status also. * ****************************************************************************/ void acpi_ut_status_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info, - acpi_status status) + u32 line_number, + struct acpi_debug_print_info *dbg_info, + acpi_status status) { if (ACPI_SUCCESS (status)) { @@ -407,31 +422,32 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_value_exit + * FUNCTION: acpi_ut_value_exit * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * Value - Value to be printed with exit msg * * RETURN: None * * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level. Prints exit value also. + * set in debug_level. Prints exit value also. * ****************************************************************************/ void acpi_ut_value_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info, - acpi_integer value) + u32 line_number, + struct acpi_debug_print_info *dbg_info, + acpi_integer value) { acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, - "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str, HIDWORD(value), LODWORD(value)); + "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str, + ACPI_HIDWORD (value), ACPI_LODWORD (value)); acpi_gbl_nesting_level--; } @@ -439,27 +455,27 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_ptr_exit + * FUNCTION: acpi_ut_ptr_exit * - * PARAMETERS: Line_number - Caller's line number - * Dbg_info - Contains: - * Proc_name - Caller's procedure name - * Module_name - Caller's module name - * Component_id - Caller's component ID + * PARAMETERS: line_number - Caller's line number + * dbg_info - Contains: + * proc_name - Caller's procedure name + * module_name - Caller's module name + * component_id - Caller's component ID * Value - Value to be printed with exit msg * * RETURN: None * * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is - * set in Debug_level. Prints exit value also. + * set in debug_level. Prints exit value also. * ****************************************************************************/ void acpi_ut_ptr_exit ( - u32 line_number, - acpi_debug_print_info *dbg_info, - u8 *ptr) + u32 line_number, + struct acpi_debug_print_info *dbg_info, + u8 *ptr) { acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, @@ -473,12 +489,12 @@ /***************************************************************************** * - * FUNCTION: Acpi_ut_dump_buffer + * FUNCTION: acpi_ut_dump_buffer * * PARAMETERS: Buffer - Buffer to dump * Count - Amount to dump, in bytes * Display - BYTE, WORD, DWORD, or QWORD display - * Component_iD - Caller's component ID + * component_iD - Caller's component ID * * RETURN: None * @@ -488,15 +504,15 @@ void acpi_ut_dump_buffer ( - u8 *buffer, - u32 count, - u32 display, - u32 component_id) -{ - u32 i = 0; - u32 j; - u32 temp32; - u8 buf_char; + u8 *buffer, + u32 count, + u32 display, + u32 component_id) +{ + acpi_native_uint i = 0; + acpi_native_uint j; + u32 temp32; + u8 buf_char; /* Only dump the buffer if tracing is enabled */ @@ -506,6 +522,11 @@ return; } + if ((count < 4) || (count & 0x01)) { + display = DB_BYTE_DISPLAY; + } + + acpi_os_printf ("\nOffset Value\n"); /* * Nasty little dump buffer routine! @@ -513,8 +534,7 @@ while (i < count) { /* Print current offset */ - acpi_os_printf ("%05X ", i); - + acpi_os_printf ("%05X ", (u32) i); /* Print 16 hex chars */ @@ -539,8 +559,7 @@ case DB_WORD_DISPLAY: - MOVE_UNALIGNED16_TO_32 (&temp32, - &buffer[i + j]); + ACPI_MOVE_16_TO_32 (&temp32, &buffer[i + j]); acpi_os_printf ("%04X ", temp32); j += 2; break; @@ -548,8 +567,7 @@ case DB_DWORD_DISPLAY: - MOVE_UNALIGNED32_TO_32 (&temp32, - &buffer[i + j]); + ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]); acpi_os_printf ("%08X ", temp32); j += 4; break; @@ -557,24 +575,20 @@ case DB_QWORD_DISPLAY: - MOVE_UNALIGNED32_TO_32 (&temp32, - &buffer[i + j]); + ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]); acpi_os_printf ("%08X", temp32); - MOVE_UNALIGNED32_TO_32 (&temp32, - &buffer[i + j + 4]); + ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j + 4]); acpi_os_printf ("%08X ", temp32); j += 8; break; } } - /* * Print the ASCII equivalent characters * But watch out for the bad unprintable ones... */ - for (j = 0; j < 16; j++) { if (i + j >= count) { acpi_os_printf ("\n"); diff -urN linux-2.4.21/drivers/acpi/utilities/utdelete.c linux-2.4.22/drivers/acpi/utilities/utdelete.c --- linux-2.4.21/drivers/acpi/utilities/utdelete.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utdelete.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,42 +1,59 @@ /******************************************************************************* * * Module Name: utdelete - object deletion and reference count utilities - * $Revision: 81 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" -#include "acparser.h" +#include +#include +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utdelete") + ACPI_MODULE_NAME ("utdelete") /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_internal_obj + * FUNCTION: acpi_ut_delete_internal_obj * * PARAMETERS: *Object - Pointer to the list to be deleted * @@ -49,13 +66,15 @@ void acpi_ut_delete_internal_obj ( - acpi_operand_object *object) + union acpi_operand_object *object) { - void *obj_pointer = NULL; - acpi_operand_object *handler_desc; + void *obj_pointer = NULL; + union acpi_operand_object *handler_desc; + union acpi_operand_object *second_desc; + union acpi_operand_object *next_desc; - FUNCTION_TRACE_PTR ("Ut_delete_internal_obj", object); + ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object); if (!object) { @@ -66,16 +85,17 @@ * Must delete or free any pointers within the object that are not * actual ACPI objects (for example, a raw buffer pointer). */ - switch (object->common.type) { - + switch (ACPI_GET_OBJECT_TYPE (object)) { case ACPI_TYPE_STRING: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** String %p, ptr %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n", object, object->string.pointer)); /* Free the actual string buffer */ if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { + /* But only if it is NOT a pointer into an ACPI table */ + obj_pointer = object->string.pointer; } break; @@ -83,18 +103,22 @@ case ACPI_TYPE_BUFFER: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Buffer %p, ptr %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n", object, object->buffer.pointer)); /* Free the actual buffer */ - obj_pointer = object->buffer.pointer; + if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { + /* But only if it is NOT a pointer into an ACPI table */ + + obj_pointer = object->buffer.pointer; + } break; case ACPI_TYPE_PACKAGE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, " **** Package of count %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n", object->package.count)); /* @@ -108,124 +132,137 @@ break; + case ACPI_TYPE_DEVICE: + + if (object->device.gpe_block) { + (void) acpi_ev_delete_gpe_block (object->device.gpe_block); + } + + /* Walk the handler list for this device */ + + handler_desc = object->device.address_space; + while (handler_desc) { + next_desc = handler_desc->address_space.next; + acpi_ut_remove_reference (handler_desc); + handler_desc = next_desc; + } + break; + + case ACPI_TYPE_MUTEX: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "***** Mutex %p, Semaphore %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n", object, object->mutex.semaphore)); acpi_ex_unlink_mutex (object); - acpi_os_delete_semaphore (object->mutex.semaphore); + (void) acpi_os_delete_semaphore (object->mutex.semaphore); break; case ACPI_TYPE_EVENT: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "***** Event %p, Semaphore %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n", object, object->event.semaphore)); - acpi_os_delete_semaphore (object->event.semaphore); + (void) acpi_os_delete_semaphore (object->event.semaphore); object->event.semaphore = NULL; break; case ACPI_TYPE_METHOD: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "***** Method %p\n", object)); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", object)); /* Delete the method semaphore if it exists */ if (object->method.semaphore) { - acpi_os_delete_semaphore (object->method.semaphore); + (void) acpi_os_delete_semaphore (object->method.semaphore); object->method.semaphore = NULL; } - break; case ACPI_TYPE_REGION: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "***** Region %p\n", object)); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", object)); - if (object->region.extra) { + second_desc = acpi_ns_get_secondary_object (object); + if (second_desc) { /* - * Free the Region_context if and only if the handler is one of the + * Free the region_context if and only if the handler is one of the * default handlers -- and therefore, we created the context object * locally, it was not created by an external caller. */ - handler_desc = object->region.addr_handler; - if ((handler_desc) && - (handler_desc->addr_handler.hflags == ADDR_HANDLER_DEFAULT_INSTALLED)) { - obj_pointer = object->region.extra->extra.region_context; + handler_desc = object->region.address_space; + if (handler_desc) { + if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { + obj_pointer = second_desc->extra.region_context; + } + + acpi_ut_remove_reference (handler_desc); } /* Now we can free the Extra object */ - acpi_ut_delete_object_desc (object->region.extra); + acpi_ut_delete_object_desc (second_desc); } break; case ACPI_TYPE_BUFFER_FIELD: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "***** Buffer Field %p\n", object)); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", object)); - if (object->buffer_field.extra) { - acpi_ut_delete_object_desc (object->buffer_field.extra); + second_desc = acpi_ns_get_secondary_object (object); + if (second_desc) { + acpi_ut_delete_object_desc (second_desc); } break; + default: break; } + /* Free any allocated memory (pointer within the object) found above */ - /* - * Delete any allocated memory found above - */ if (obj_pointer) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting Obj Ptr %p \n", obj_pointer)); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n", + obj_pointer)); ACPI_MEM_FREE (obj_pointer); } - /* Only delete the object if it was dynamically allocated */ - - if (object->common.flags & AOPOBJ_STATIC_ALLOCATION) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object %p [%s] static allocation, no delete\n", - object, acpi_ut_get_type_name (object->common.type))); - } - - if (!(object->common.flags & AOPOBJ_STATIC_ALLOCATION)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting object %p [%s]\n", - object, acpi_ut_get_type_name (object->common.type))); + /* Now the object can be safely deleted */ - acpi_ut_delete_object_desc (object); - } + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n", + object, acpi_ut_get_object_type_name (object))); + acpi_ut_delete_object_desc (object); return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_internal_object_list + * FUNCTION: acpi_ut_delete_internal_object_list * - * PARAMETERS: *Obj_list - Pointer to the list to be deleted + * PARAMETERS: *obj_list - Pointer to the list to be deleted * - * RETURN: Status - the status of the call + * RETURN: None * * DESCRIPTION: This function deletes an internal object list, including both * simple objects and package objects * ******************************************************************************/ -acpi_status +void acpi_ut_delete_internal_object_list ( - acpi_operand_object **obj_list) + union acpi_operand_object **obj_list) { - acpi_operand_object **internal_obj; + union acpi_operand_object **internal_obj; - FUNCTION_TRACE ("Ut_delete_internal_object_list"); + ACPI_FUNCTION_TRACE ("ut_delete_internal_object_list"); /* Walk the null-terminated internal list */ @@ -237,14 +274,13 @@ /* Free the combined parameter pointer list and object array */ ACPI_MEM_FREE (obj_list); - - return_ACPI_STATUS (AE_OK); + return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ut_update_ref_count + * FUNCTION: acpi_ut_update_ref_count * * PARAMETERS: *Object - Object whose ref count is to be updated * Action - What to do @@ -257,25 +293,25 @@ static void acpi_ut_update_ref_count ( - acpi_operand_object *object, - u32 action) + union acpi_operand_object *object, + u32 action) { - u16 count; - u16 new_count; + u16 count; + u16 new_count; + + ACPI_FUNCTION_NAME ("ut_update_ref_count"); - PROC_NAME ("Ut_update_ref_count"); if (!object) { return; } - count = object->common.reference_count; new_count = count; /* - * Reference count action (increment, decrement, or force delete) + * Perform the reference count action (increment, decrement, or force delete) */ switch (action) { @@ -284,7 +320,7 @@ new_count++; object->common.reference_count = new_count; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Obj %p Refs=%X, [Incremented]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n", object, new_count)); break; @@ -292,21 +328,20 @@ case REF_DECREMENT: if (count < 1) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Obj %p Refs=%X, can't decrement! (Set to 0)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n", object, new_count)); new_count = 0; } - else { new_count--; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Obj %p Refs=%X, [Decremented]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n", object, new_count)); } - if (object->common.type == ACPI_TYPE_METHOD) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Method Obj %p Refs=%X, [Decremented]\n", + if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) { + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n", object, new_count)); } @@ -320,7 +355,7 @@ case REF_FORCE_DELETE: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Obj %p Refs=%X, Force delete! (Set to 0)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n", object, count)); new_count = 0; @@ -335,12 +370,11 @@ break; } - /* * Sanity check the reference count, for debug purposes only. * (A deleted object will have a huge reference count) */ - if (count > MAX_REFERENCE_COUNT) { + if (count > ACPI_MAX_REFERENCE_COUNT) { ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "**** Warning **** Large Reference Count (%X) in object %p\n\n", @@ -353,7 +387,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_update_object_reference + * FUNCTION: acpi_ut_update_object_reference * * PARAMETERS: *Object - Increment ref count for this object * and all sub-objects @@ -375,18 +409,16 @@ acpi_status acpi_ut_update_object_reference ( - acpi_operand_object *object, - u16 action) + union acpi_operand_object *object, + u16 action) { - acpi_status status; - u32 i; - acpi_operand_object *next; - acpi_operand_object *new; - acpi_generic_state *state_list = NULL; - acpi_generic_state *state; + acpi_status status; + u32 i; + union acpi_generic_state *state_list = NULL; + union acpi_generic_state *state; - FUNCTION_TRACE_PTR ("Ut_update_object_reference", object); + ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object); /* Ignore a null object ptr */ @@ -395,16 +427,13 @@ return_ACPI_STATUS (AE_OK); } + /* Make sure that this isn't a namespace handle */ - /* - * Make sure that this isn't a namespace handle or an AML pointer - */ - if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object %p is NS handle\n", object)); + if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) { + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object)); return_ACPI_STATUS (AE_OK); } - state = acpi_ut_create_update_state (object, action); while (state) { @@ -416,32 +445,11 @@ * All sub-objects must have their reference count incremented also. * Different object types have different subobjects. */ - switch (object->common.type) { - + switch (ACPI_GET_OBJECT_TYPE (object)) { case ACPI_TYPE_DEVICE: - status = acpi_ut_create_update_state_and_push (object->device.addr_handler, - action, &state_list); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - acpi_ut_update_ref_count (object->device.sys_handler, action); - acpi_ut_update_ref_count (object->device.drv_handler, action); - break; - - - case INTERNAL_TYPE_ADDRESS_HANDLER: - - /* Must walk list of address handlers */ - - next = object->addr_handler.next; - while (next) { - new = next->addr_handler.next; - acpi_ut_update_ref_count (next, action); - - next = new; - } + acpi_ut_update_ref_count (object->device.system_notify, action); + acpi_ut_update_ref_count (object->device.device_notify, action); break; @@ -460,7 +468,7 @@ status = acpi_ut_create_update_state_and_push ( object->package.elements[i], action, &state_list); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto error_exit; } } break; @@ -470,63 +478,62 @@ status = acpi_ut_create_update_state_and_push ( object->buffer_field.buffer_obj, action, &state_list); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto error_exit; } break; - case INTERNAL_TYPE_REGION_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: status = acpi_ut_create_update_state_and_push ( object->field.region_obj, action, &state_list); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto error_exit; } break; - case INTERNAL_TYPE_BANK_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: status = acpi_ut_create_update_state_and_push ( - object->bank_field.bank_register_obj, action, &state_list); + object->bank_field.bank_obj, action, &state_list); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto error_exit; } status = acpi_ut_create_update_state_and_push ( object->bank_field.region_obj, action, &state_list); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto error_exit; } break; - case INTERNAL_TYPE_INDEX_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: status = acpi_ut_create_update_state_and_push ( object->index_field.index_obj, action, &state_list); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto error_exit; } status = acpi_ut_create_update_state_and_push ( object->index_field.data_obj, action, &state_list); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto error_exit; } break; case ACPI_TYPE_REGION: - case INTERNAL_TYPE_REFERENCE: + case ACPI_TYPE_LOCAL_REFERENCE: + default: /* No subobjects */ break; } - /* * Now we can update the count in the main object. This can only * happen after we update the sub-objects in case this causes the @@ -534,20 +541,26 @@ */ acpi_ut_update_ref_count (object, action); - /* Move on to the next object to be updated */ state = acpi_ut_pop_generic_state (&state_list); } - return_ACPI_STATUS (AE_OK); + + +error_exit: + + ACPI_REPORT_ERROR (("Could not update object reference count, %s\n", + acpi_format_exception (status))); + + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_add_reference + * FUNCTION: acpi_ut_add_reference * * PARAMETERS: *Object - Object whose reference count is to be * incremented @@ -560,31 +573,28 @@ void acpi_ut_add_reference ( - acpi_operand_object *object) + union acpi_operand_object *object) { - FUNCTION_TRACE_PTR ("Ut_add_reference", object); + ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object); - /* - * Ensure that we have a valid object - */ + /* Ensure that we have a valid object */ + if (!acpi_ut_valid_internal_object (object)) { return_VOID; } - /* - * We have a valid ACPI internal object, now increment the reference count - */ - acpi_ut_update_object_reference (object, REF_INCREMENT); + /* Increment the reference count */ + (void) acpi_ut_update_object_reference (object, REF_INCREMENT); return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ut_remove_reference + * FUNCTION: acpi_ut_remove_reference * * PARAMETERS: *Object - Object whose ref count will be decremented * @@ -596,10 +606,11 @@ void acpi_ut_remove_reference ( - acpi_operand_object *object) + union acpi_operand_object *object) { - FUNCTION_TRACE_PTR ("Ut_remove_reference", object); + ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object); + /* * Allow a NULL pointer to be passed in, just ignore it. This saves @@ -607,18 +618,17 @@ * */ if (!object || - (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED))) { + (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED)) { return_VOID; } - /* - * Ensure that we have a valid object - */ + /* Ensure that we have a valid object */ + if (!acpi_ut_valid_internal_object (object)) { return_VOID; } - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Obj %p Refs=%X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X\n", object, object->common.reference_count)); /* @@ -626,7 +636,7 @@ * if the reference count becomes 0. (Must also decrement the ref count * of all subobjects!) */ - acpi_ut_update_object_reference (object, REF_DECREMENT); + (void) acpi_ut_update_object_reference (object, REF_DECREMENT); return_VOID; } diff -urN linux-2.4.21/drivers/acpi/utilities/uteval.c linux-2.4.22/drivers/acpi/utilities/uteval.c --- linux-2.4.21/drivers/acpi/utilities/uteval.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/uteval.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,123 +1,258 @@ /****************************************************************************** * * Module Name: uteval - Object evaluation - * $Revision: 31 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acnamesp.h" -#include "acinterp.h" +#include +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("uteval") + ACPI_MODULE_NAME ("uteval") /******************************************************************************* * - * FUNCTION: Acpi_ut_evaluate_numeric_object + * FUNCTION: acpi_ut_evaluate_object * - * PARAMETERS: *Object_name - Object name to be evaluated - * Device_node - Node for the device - * *Address - Where the value is returned + * PARAMETERS: prefix_node - Starting node + * Path - Path to object from starting node + * expected_return_types - Bitmap of allowed return types + * return_desc - Where a return value is stored * * RETURN: Status * - * DESCRIPTION: evaluates a numeric namespace object for a selected device - * and stores results in *Address. + * DESCRIPTION: Evaluates a namespace object and verifies the type of the + * return object. Common code that simplifies accessing objects + * that have required return objects of fixed types. * * NOTE: Internal function, no parameter validation * ******************************************************************************/ acpi_status -acpi_ut_evaluate_numeric_object ( - NATIVE_CHAR *object_name, - acpi_namespace_node *device_node, - acpi_integer *address) +acpi_ut_evaluate_object ( + struct acpi_namespace_node *prefix_node, + char *path, + u32 expected_return_btypes, + union acpi_operand_object **return_desc) { - acpi_operand_object *obj_desc; - acpi_status status; + union acpi_operand_object *obj_desc; + acpi_status status; + u32 return_btype; - FUNCTION_TRACE ("Ut_evaluate_numeric_object"); + ACPI_FUNCTION_TRACE ("ut_evaluate_object"); - /* Execute the method */ + /* Evaluate the object/method */ - status = acpi_ns_evaluate_relative (device_node, object_name, NULL, &obj_desc); + status = acpi_ns_evaluate_relative (prefix_node, path, NULL, &obj_desc); if (ACPI_FAILURE (status)) { if (status == AE_NOT_FOUND) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s on %4.4s was not found\n", - object_name, (char*)&device_node->name)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n", + prefix_node->name.ascii, path)); } else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s on %4.4s failed with status %s\n", - object_name, (char*)&device_node->name, - acpi_format_exception (status))); + ACPI_REPORT_METHOD_ERROR ("Method execution failed", + prefix_node, path, status); } return_ACPI_STATUS (status); } - /* Did we get a return object? */ if (!obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from %s\n", - object_name)); - return_ACPI_STATUS (AE_TYPE); + if (expected_return_btypes) { + ACPI_REPORT_METHOD_ERROR ("No object was returned from", + prefix_node, path, AE_NOT_EXIST); + + return_ACPI_STATUS (AE_NOT_EXIST); + } + + return_ACPI_STATUS (AE_OK); } - /* Is the return object of the correct type? */ + /* Map the return object type to the bitmapped type */ + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_INTEGER: + return_btype = ACPI_BTYPE_INTEGER; + break; + + case ACPI_TYPE_BUFFER: + return_btype = ACPI_BTYPE_BUFFER; + break; + + case ACPI_TYPE_STRING: + return_btype = ACPI_BTYPE_STRING; + break; + + case ACPI_TYPE_PACKAGE: + return_btype = ACPI_BTYPE_PACKAGE; + break; + + default: + return_btype = 0; + break; + } + + /* Is the return object one of the expected types? */ + + if (!(expected_return_btypes & return_btype)) { + ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect", + prefix_node, path, AE_TYPE); - if (obj_desc->common.type != ACPI_TYPE_INTEGER) { - status = AE_TYPE; ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Type returned from %s was not a number: %X \n", - object_name, obj_desc->common.type)); + "Type returned from %s was incorrect: %X\n", + path, ACPI_GET_OBJECT_TYPE (obj_desc))); + + /* On error exit, we must delete the return object */ + + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (AE_TYPE); } - else { - /* - * Since the structure is a union, setting any field will set all - * of the variables in the union - */ - *address = obj_desc->integer.value; + + /* Object type is OK, return it */ + + *return_desc = obj_desc; + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_evaluate_numeric_object + * + * PARAMETERS: *object_name - Object name to be evaluated + * device_node - Node for the device + * *Address - Where the value is returned + * + * RETURN: Status + * + * DESCRIPTION: Evaluates a numeric namespace object for a selected device + * and stores result in *Address. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ + +acpi_status +acpi_ut_evaluate_numeric_object ( + char *object_name, + struct acpi_namespace_node *device_node, + acpi_integer *address) +{ + union acpi_operand_object *obj_desc; + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object"); + + + status = acpi_ut_evaluate_object (device_node, object_name, + ACPI_BTYPE_INTEGER, &obj_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } + /* Get the returned Integer */ + + *address = obj_desc->integer.value; + /* On exit, we must delete the return object */ acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_execute_HID + * FUNCTION: acpi_ut_copy_id_string * - * PARAMETERS: Device_node - Node for the device + * PARAMETERS: Destination - Where to copy the string + * Source - Source string + * max_length - Length of the destination buffer + * + * RETURN: None + * + * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. + * Performs removal of a leading asterisk if present -- workaround + * for a known issue on a bunch of machines. + * + ******************************************************************************/ + +static void +acpi_ut_copy_id_string ( + char *destination, + char *source, + acpi_size max_length) +{ + + + /* + * Workaround for ID strings that have a leading asterisk. This construct + * is not allowed by the ACPI specification (ID strings must be + * alphanumeric), but enough existing machines have this embedded in their + * ID strings that the following code is useful. + */ + if (*source == '*') { + source++; + } + + /* Do the actual copy */ + + ACPI_STRNCPY (destination, source, max_length); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_HID + * + * PARAMETERS: device_node - Node for the device * *Hid - Where the HID is returned * * RETURN: Status @@ -131,239 +266,299 @@ acpi_status acpi_ut_execute_HID ( - acpi_namespace_node *device_node, - acpi_device_id *hid) + struct acpi_namespace_node *device_node, + struct acpi_device_id *hid) { - acpi_operand_object *obj_desc; - acpi_status status; - + union acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE ("Ut_execute_HID"); + ACPI_FUNCTION_TRACE ("ut_execute_HID"); - /* Execute the method */ - status = acpi_ns_evaluate_relative (device_node, - METHOD_NAME__HID, NULL, &obj_desc); + status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc); if (ACPI_FAILURE (status)) { - if (status == AE_NOT_FOUND) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "_HID on %4.4s was not found\n", - (char*)&device_node->name)); - } - - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_HID on %4.4s failed %s\n", - (char*)&device_node->name, acpi_format_exception (status))); - } - return_ACPI_STATUS (status); } - /* Did we get a return object? */ + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { + /* Convert the Numeric HID to string */ - if (!obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _HID\n")); - return_ACPI_STATUS (AE_TYPE); + acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value); } + else { + /* Copy the String HID from the returned object */ - /* - * A _HID can return either a Number (32 bit compressed EISA ID) or - * a string - */ - if ((obj_desc->common.type != ACPI_TYPE_INTEGER) && - (obj_desc->common.type != ACPI_TYPE_STRING)) { - status = AE_TYPE; - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Type returned from _HID not a number or string: %s(%X) \n", - acpi_ut_get_type_name (obj_desc->common.type), obj_desc->common.type)); + acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer, + sizeof (hid->value)); } - else { - if (obj_desc->common.type == ACPI_TYPE_INTEGER) { - /* Convert the Numeric HID to string */ + /* On exit, we must delete the return object */ - acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer); - } + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); +} - else { - /* Copy the String HID from the returned object */ - STRNCPY(hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer)); +/******************************************************************************* + * + * FUNCTION: acpi_ut_translate_one_cid + * + * PARAMETERS: obj_desc - _CID object, must be integer or string + * one_cid - Where the CID string is returned + * + * RETURN: Status + * + * DESCRIPTION: Return a numeric or string _CID value as a string. + * (Compatible ID) + * + * NOTE: Assumes a maximum _CID string length of + * ACPI_MAX_CID_LENGTH. + * + ******************************************************************************/ + +static acpi_status +acpi_ut_translate_one_cid ( + union acpi_operand_object *obj_desc, + struct acpi_compatible_id *one_cid) +{ + + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_INTEGER: + + /* Convert the Numeric CID to string */ + + acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value); + return (AE_OK); + + case ACPI_TYPE_STRING: + + if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { + return (AE_AML_STRING_LIMIT); } - } + /* Copy the String CID from the returned object */ - /* On exit, we must delete the return object */ + acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer, + ACPI_MAX_CID_LENGTH); + return (AE_OK); - acpi_ut_remove_reference (obj_desc); + default: - return_ACPI_STATUS (status); + return (AE_TYPE); + } } /******************************************************************************* * - * FUNCTION: Acpi_ut_execute_UID + * FUNCTION: acpi_ut_execute_CID * - * PARAMETERS: Device_node - Node for the device - * *Uid - Where the UID is returned + * PARAMETERS: device_node - Node for the device + * *Cid - Where the CID is returned * * RETURN: Status * - * DESCRIPTION: Executes the _UID control method that returns the hardware - * ID of the device. + * DESCRIPTION: Executes the _CID control method that returns one or more + * compatible hardware IDs for the device. * * NOTE: Internal function, no parameter validation * ******************************************************************************/ acpi_status -acpi_ut_execute_UID ( - acpi_namespace_node *device_node, - acpi_device_id *uid) +acpi_ut_execute_CID ( + struct acpi_namespace_node *device_node, + struct acpi_compatible_id_list **return_cid_list) { - acpi_operand_object *obj_desc; - acpi_status status; + union acpi_operand_object *obj_desc; + acpi_status status; + u32 count; + u32 size; + struct acpi_compatible_id_list *cid_list; + acpi_native_uint i; - PROC_NAME ("Ut_execute_UID"); + ACPI_FUNCTION_TRACE ("ut_execute_CID"); - /* Execute the method */ + /* Evaluate the _CID method for this device */ - status = acpi_ns_evaluate_relative (device_node, - METHOD_NAME__UID, NULL, &obj_desc); + status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, + &obj_desc); if (ACPI_FAILURE (status)) { - if (status == AE_NOT_FOUND) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "_UID on %4.4s was not found\n", - (char*)&device_node->name)); - } + return_ACPI_STATUS (status); + } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "_UID on %4.4s failed %s\n", - (char*)&device_node->name, acpi_format_exception (status))); - } + /* Get the number of _CIDs returned */ - return (status); + count = 1; + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) { + count = obj_desc->package.count; } - /* Did we get a return object? */ + /* Allocate a worst-case buffer for the _CIDs */ - if (!obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _UID\n")); - return (AE_TYPE); + size = (((count - 1) * sizeof (struct acpi_compatible_id)) + + sizeof (struct acpi_compatible_id_list)); + + cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size); + if (!cid_list) { + return_ACPI_STATUS (AE_NO_MEMORY); } + /* Init CID list */ + + cid_list->count = count; + cid_list->size = size; + /* - * A _UID can return either a Number (32 bit compressed EISA ID) or - * a string + * A _CID can return either a single compatible ID or a package of compatible + * IDs. Each compatible ID can be one of the following: + * -- Number (32 bit compressed EISA ID) or + * -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss"). */ - if ((obj_desc->common.type != ACPI_TYPE_INTEGER) && - (obj_desc->common.type != ACPI_TYPE_STRING)) { - status = AE_TYPE; - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Type returned from _UID was not a number or string: %X \n", - obj_desc->common.type)); - } - else { - if (obj_desc->common.type == ACPI_TYPE_INTEGER) { - /* Convert the Numeric UID to string */ - - acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer); - } + /* The _CID object can be either a single CID or a package (list) of CIDs */ - else { - /* Copy the String UID from the returned object */ + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) { + /* Translate each package element */ - STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer)); + for (i = 0; i < count; i++) { + status = acpi_ut_translate_one_cid (obj_desc->package.elements[i], + &cid_list->id[i]); + if (ACPI_FAILURE (status)) { + break; + } } } + else { + /* Only one CID, translate to a string */ + status = acpi_ut_translate_one_cid (obj_desc, cid_list->id); + } - /* On exit, we must delete the return object */ + /* Cleanup on error */ - acpi_ut_remove_reference (obj_desc); + if (ACPI_FAILURE (status)) { + ACPI_MEM_FREE (cid_list); + } + else { + *return_cid_list = cid_list; + } - return (status); + /* On exit, we must delete the _CID return object */ + + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_execute_STA + * FUNCTION: acpi_ut_execute_UID * - * PARAMETERS: Device_node - Node for the device - * *Flags - Where the status flags are returned + * PARAMETERS: device_node - Node for the device + * *Uid - Where the UID is returned * * RETURN: Status * - * DESCRIPTION: Executes _STA for selected device and stores results in - * *Flags. + * DESCRIPTION: Executes the _UID control method that returns the hardware + * ID of the device. * * NOTE: Internal function, no parameter validation * ******************************************************************************/ acpi_status -acpi_ut_execute_STA ( - acpi_namespace_node *device_node, - u32 *flags) +acpi_ut_execute_UID ( + struct acpi_namespace_node *device_node, + struct acpi_device_id *uid) { - acpi_operand_object *obj_desc; - acpi_status status; + union acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE ("Ut_execute_STA"); + ACPI_FUNCTION_TRACE ("ut_execute_UID"); - /* Execute the method */ + status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - status = acpi_ns_evaluate_relative (device_node, - METHOD_NAME__STA, NULL, &obj_desc); - if (AE_NOT_FOUND == status) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "_STA on %4.4s was not found, assuming present.\n", - (char*)&device_node->name)); + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { + /* Convert the Numeric UID to string */ - *flags = 0x0F; - status = AE_OK; + acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value); } + else { + /* Copy the String UID from the returned object */ - else if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_STA on %4.4s failed %s\n", - (char*)&device_node->name, - acpi_format_exception (status))); + acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer, + sizeof (uid->value)); } - else /* success */ { - /* Did we get a return object? */ + /* On exit, we must delete the return object */ - if (!obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _STA\n")); - return_ACPI_STATUS (AE_TYPE); - } + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); +} - /* Is the return object of the correct type? */ - if (obj_desc->common.type != ACPI_TYPE_INTEGER) { - status = AE_TYPE; - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Type returned from _STA was not a number: %X \n", - obj_desc->common.type)); - } +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_STA + * + * PARAMETERS: device_node - Node for the device + * *Flags - Where the status flags are returned + * + * RETURN: Status + * + * DESCRIPTION: Executes _STA for selected device and stores results in + * *Flags. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ - else { - /* Extract the status flags */ +acpi_status +acpi_ut_execute_STA ( + struct acpi_namespace_node *device_node, + u32 *flags) +{ + union acpi_operand_object *obj_desc; + acpi_status status; - *flags = (u32) obj_desc->integer.value; - } - /* On exit, we must delete the return object */ + ACPI_FUNCTION_TRACE ("ut_execute_STA"); - acpi_ut_remove_reference (obj_desc); + + status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA, + ACPI_BTYPE_INTEGER, &obj_desc); + if (ACPI_FAILURE (status)) { + if (AE_NOT_FOUND == status) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "_STA on %4.4s was not found, assuming device is present\n", + device_node->name.ascii)); + + *flags = 0x0F; + status = AE_OK; + } + + return_ACPI_STATUS (status); } + /* Extract the status flags */ + + *flags = (u32) obj_desc->integer.value; + + /* On exit, we must delete the return object */ + + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } diff -urN linux-2.4.21/drivers/acpi/utilities/utglobal.c linux-2.4.22/drivers/acpi/utilities/utglobal.c --- linux-2.4.21/drivers/acpi/utilities/utglobal.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utglobal.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,44 +1,58 @@ /****************************************************************************** * * Module Name: utglobal - Global variables for the ACPI subsystem - * $Revision: 133 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ #define DEFINE_ACPI_GLOBALS -#include "acpi.h" -#include "acevents.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "amlcode.h" - +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utglobal") + ACPI_MODULE_NAME ("utglobal") /****************************************************************************** * - * FUNCTION: Acpi_format_exception + * FUNCTION: acpi_format_exception * * PARAMETERS: Status - The acpi_status code to be formatted * @@ -50,57 +64,69 @@ const char * acpi_format_exception ( - acpi_status status) + acpi_status status) { - const char *exception = "UNKNOWN_STATUS_CODE"; - acpi_status sub_status; + const char *exception = "UNKNOWN_STATUS_CODE"; + acpi_status sub_status; - sub_status = (status & ~AE_CODE_MASK); + ACPI_FUNCTION_NAME ("format_exception"); + sub_status = (status & ~AE_CODE_MASK); + switch (status & AE_CODE_MASK) { case AE_CODE_ENVIRONMENTAL: if (sub_status <= AE_CODE_ENV_MAX) { exception = acpi_gbl_exception_names_env [sub_status]; + break; } - break; + goto unknown; case AE_CODE_PROGRAMMER: if (sub_status <= AE_CODE_PGM_MAX) { exception = acpi_gbl_exception_names_pgm [sub_status -1]; + break; } - break; + goto unknown; case AE_CODE_ACPI_TABLES: if (sub_status <= AE_CODE_TBL_MAX) { exception = acpi_gbl_exception_names_tbl [sub_status -1]; + break; } - break; + goto unknown; case AE_CODE_AML: if (sub_status <= AE_CODE_AML_MAX) { exception = acpi_gbl_exception_names_aml [sub_status -1]; + break; } - break; + goto unknown; case AE_CODE_CONTROL: if (sub_status <= AE_CODE_CTRL_MAX) { exception = acpi_gbl_exception_names_ctrl [sub_status -1]; + break; } - break; + goto unknown; default: - break; + goto unknown; } return ((const char *) exception); + +unknown: + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown exception code: 0x%8.8X\n", status)); + return ((const char *) exception); } @@ -117,37 +143,41 @@ /* Debug switch - level and trace mask */ -#ifdef ACPI_DEBUG -u32 acpi_dbg_level = DEBUG_DEFAULT; +#ifdef ACPI_DEBUG_OUTPUT +u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT; #else -u32 acpi_dbg_level = NORMAL_DEFAULT; +u32 acpi_dbg_level = ACPI_NORMAL_DEFAULT; #endif /* Debug switch - layer (component) mask */ -u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT; -u32 acpi_gbl_nesting_level = 0; +u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT; +u32 acpi_gbl_nesting_level = 0; /* Debugger globals */ -u8 acpi_gbl_db_terminate_threads = FALSE; -u8 acpi_gbl_method_executing = FALSE; +u8 acpi_gbl_db_terminate_threads = FALSE; +u8 acpi_gbl_abort_method = FALSE; +u8 acpi_gbl_method_executing = FALSE; /* System flags */ -u32 acpi_gbl_system_flags = 0; -u32 acpi_gbl_startup_flags = 0; +u32 acpi_gbl_startup_flags = 0; -/* System starts unitialized! */ +/* System starts uninitialized */ -u8 acpi_gbl_shutdown = TRUE; +u8 acpi_gbl_shutdown = TRUE; -const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; +const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; -const NATIVE_CHAR *acpi_gbl_db_sleep_states[ACPI_NUM_SLEEP_STATES] = { - "\\_S0_","\\_S1_","\\_S2_","\\_S3_", - "\\_S4_","\\_S5_","\\_S4B"}; +const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT] = { + "\\_S0_", + "\\_S1_", + "\\_S2_", + "\\_S3_", + "\\_S4_", + "\\_S5_"}; /****************************************************************************** @@ -158,86 +188,82 @@ /* - * Names built-in to the interpreter + * Predefined ACPI Names (Built-in to the Interpreter) * * Initial values are currently supported only for types String and Number. - * To avoid type punning, both are specified as strings in this table. + * Both are specified as strings in this table. * * NOTES: * 1) _SB_ is defined to be a device to allow _SB_/_INI to be run * during the initialization sequence. */ -const predefined_names acpi_gbl_pre_defined_names[] = -{ {"_GPE", INTERNAL_TYPE_DEF_ANY}, - {"_PR_", INTERNAL_TYPE_DEF_ANY}, - {"_SB_", ACPI_TYPE_DEVICE}, - {"_SI_", INTERNAL_TYPE_DEF_ANY}, - {"_TZ_", INTERNAL_TYPE_DEF_ANY}, - {"_REV", ACPI_TYPE_INTEGER, "2"}, - {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, - {"_GL_", ACPI_TYPE_MUTEX, "0"}, - {NULL, ACPI_TYPE_ANY} /* Table terminator */ +const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = +{ {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_SB_", ACPI_TYPE_DEVICE, NULL}, + {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_TZ_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_REV", ACPI_TYPE_INTEGER, "2"}, + {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, + {"_GL_", ACPI_TYPE_MUTEX, "0"}, + +#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) + {"_OSI", ACPI_TYPE_METHOD, "1"}, +#endif + {NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */ }; /* * Properties of the ACPI Object Types, both internal and external. - * - * Elements of Acpi_ns_properties are bit significant - * and the table is indexed by values of acpi_object_type + * The table is indexed by values of acpi_object_type */ -const u8 acpi_gbl_ns_properties[] = +const u8 acpi_gbl_ns_properties[] = { - NSP_NORMAL, /* 00 Any */ - NSP_NORMAL, /* 01 Number */ - NSP_NORMAL, /* 02 String */ - NSP_NORMAL, /* 03 Buffer */ - NSP_LOCAL, /* 04 Package */ - NSP_NORMAL, /* 05 Field_unit */ - NSP_NEWSCOPE | NSP_LOCAL, /* 06 Device */ - NSP_LOCAL, /* 07 Acpi_event */ - NSP_NEWSCOPE | NSP_LOCAL, /* 08 Method */ - NSP_LOCAL, /* 09 Mutex */ - NSP_LOCAL, /* 10 Region */ - NSP_NEWSCOPE | NSP_LOCAL, /* 11 Power */ - NSP_NEWSCOPE | NSP_LOCAL, /* 12 Processor */ - NSP_NEWSCOPE | NSP_LOCAL, /* 13 Thermal */ - NSP_NORMAL, /* 14 Buffer_field */ - NSP_NORMAL, /* 15 Ddb_handle */ - NSP_NORMAL, /* 16 Debug Object */ - NSP_NORMAL, /* 17 Def_field */ - NSP_NORMAL, /* 18 Bank_field */ - NSP_NORMAL, /* 19 Index_field */ - NSP_NORMAL, /* 20 Reference */ - NSP_NORMAL, /* 21 Alias */ - NSP_NORMAL, /* 22 Notify */ - NSP_NORMAL, /* 23 Address Handler */ - NSP_NEWSCOPE | NSP_LOCAL, /* 24 Resource Desc */ - NSP_NEWSCOPE | NSP_LOCAL, /* 25 Resource Field */ - NSP_NORMAL, /* 26 Def_field_defn */ - NSP_NORMAL, /* 27 Bank_field_defn */ - NSP_NORMAL, /* 28 Index_field_defn */ - NSP_NORMAL, /* 29 If */ - NSP_NORMAL, /* 30 Else */ - NSP_NORMAL, /* 31 While */ - NSP_NEWSCOPE, /* 32 Scope */ - NSP_LOCAL, /* 33 Def_any */ - NSP_NORMAL, /* 34 Extra */ - NSP_NORMAL /* 35 Invalid */ + ACPI_NS_NORMAL, /* 00 Any */ + ACPI_NS_NORMAL, /* 01 Number */ + ACPI_NS_NORMAL, /* 02 String */ + ACPI_NS_NORMAL, /* 03 Buffer */ + ACPI_NS_NORMAL, /* 04 Package */ + ACPI_NS_NORMAL, /* 05 field_unit */ + ACPI_NS_NEWSCOPE, /* 06 Device */ + ACPI_NS_NORMAL, /* 07 Event */ + ACPI_NS_NEWSCOPE, /* 08 Method */ + ACPI_NS_NORMAL, /* 09 Mutex */ + ACPI_NS_NORMAL, /* 10 Region */ + ACPI_NS_NEWSCOPE, /* 11 Power */ + ACPI_NS_NEWSCOPE, /* 12 Processor */ + ACPI_NS_NEWSCOPE, /* 13 Thermal */ + ACPI_NS_NORMAL, /* 14 buffer_field */ + ACPI_NS_NORMAL, /* 15 ddb_handle */ + ACPI_NS_NORMAL, /* 16 Debug Object */ + ACPI_NS_NORMAL, /* 17 def_field */ + ACPI_NS_NORMAL, /* 18 bank_field */ + ACPI_NS_NORMAL, /* 19 index_field */ + ACPI_NS_NORMAL, /* 20 Reference */ + ACPI_NS_NORMAL, /* 21 Alias */ + ACPI_NS_NORMAL, /* 22 Notify */ + ACPI_NS_NORMAL, /* 23 Address Handler */ + ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 24 Resource Desc */ + ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Field */ + ACPI_NS_NEWSCOPE, /* 26 Scope */ + ACPI_NS_NORMAL, /* 27 Extra */ + ACPI_NS_NORMAL, /* 28 Data */ + ACPI_NS_NORMAL /* 29 Invalid */ }; /* Hex to ASCII conversion table */ -const NATIVE_CHAR acpi_gbl_hex_to_ascii[] = +static const char acpi_gbl_hex_to_ascii[] = {'0','1','2','3','4','5','6','7', - '8','9','A','B','C','D','E','F'}; + '8','9','A','B','C','D','E','F'}; /***************************************************************************** * - * FUNCTION: Acpi_ut_hex_to_ascii_char + * FUNCTION: acpi_ut_hex_to_ascii_char * * PARAMETERS: Integer - Contains the hex digit * Position - bit position of the digit within the @@ -249,10 +275,10 @@ * ****************************************************************************/ -u8 +char acpi_ut_hex_to_ascii_char ( - acpi_integer integer, - u32 position) + acpi_integer integer, + u32 position) { return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); @@ -261,68 +287,180 @@ /****************************************************************************** * - * Table globals + * Table name globals * * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables * that are not used by the subsystem are simply ignored. * + * Do NOT add any table to this list that is not consumed directly by this + * subsystem. + * ******************************************************************************/ -acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; +struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES]; + +struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] = +{ + /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ + + /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}, + /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE}, + /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE}, + /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE}, + /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE}, + /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE}, + /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}, +}; + + +/****************************************************************************** + * + * Event and Hardware globals + * + ******************************************************************************/ -ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] = +struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = { - /*********** Name, Signature, Signature size, How many allowed?, Supported? Global typed pointer */ + /* Name Parent Register Register Bit Position Register Bit Mask */ + + /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_TIMER_STATUS, ACPI_BITMASK_TIMER_STATUS}, + /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_BUS_MASTER_STATUS, ACPI_BITMASK_BUS_MASTER_STATUS}, + /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_STATUS}, + /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_STATUS}, + /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_STATUS}, + /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS}, + /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_WAKE_STATUS, ACPI_BITMASK_WAKE_STATUS}, + + /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_TIMER_ENABLE, ACPI_BITMASK_TIMER_ENABLE}, + /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, + /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_ENABLE}, + /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, + /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE}, + /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0}, + + /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SCI_ENABLE, ACPI_BITMASK_SCI_ENABLE}, + /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_BUS_MASTER_RLD, ACPI_BITMASK_BUS_MASTER_RLD}, + /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, ACPI_BITMASK_GLOBAL_LOCK_RELEASE}, + /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X}, + /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X}, + /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_ENABLE, ACPI_BITMASK_SLEEP_ENABLE}, - /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, - /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_DSDT}, - /* FADT 2 */ {FADT_SIG, FADT_SIG, sizeof (FADT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FADT}, - /* FACS 3 */ {FACS_SIG, FACS_SIG, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FACS}, - /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, - /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, - /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, + /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL, ACPI_BITPOSITION_ARB_DISABLE, ACPI_BITMASK_ARB_DISABLE} }; -#ifdef ACPI_DEBUG +struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = +{ + /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS, ACPI_BITREG_TIMER_ENABLE, ACPI_BITMASK_TIMER_STATUS, ACPI_BITMASK_TIMER_ENABLE}, + /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS, ACPI_BITREG_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, + /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS, ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_ENABLE}, + /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS, ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, + /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, 0, 0}, +}; -/* - * Strings and procedures used for debug only +/***************************************************************************** * - */ + * FUNCTION: acpi_ut_get_region_name + * + * PARAMETERS: None. + * + * RETURN: Status + * + * DESCRIPTION: Translate a Space ID into a name string (Debug only) + * + ****************************************************************************/ + +/* Region type decoding */ + +const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = +{ +/*! [Begin] no source code translation (keep these ASL Keywords as-is) */ + "SystemMemory", + "SystemIO", + "PCI_Config", + "EmbeddedControl", + "SMBus", + "CMOS", + "PCIBARTarget", + "DataTable" +/*! [End] no source code translation !*/ +}; + + +char * +acpi_ut_get_region_name ( + u8 space_id) +{ + + if (space_id >= ACPI_USER_REGION_BEGIN) + { + return ("user_defined_region"); + } + + else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) + { + return ("invalid_space_id"); + } + + return ((char *) acpi_gbl_region_types[space_id]); +} /***************************************************************************** * - * FUNCTION: Acpi_ut_get_mutex_name + * FUNCTION: acpi_ut_get_event_name * * PARAMETERS: None. * * RETURN: Status * - * DESCRIPTION: Translate a mutex ID into a name string (Debug only) + * DESCRIPTION: Translate a Event ID into a name string (Debug only) * ****************************************************************************/ -NATIVE_CHAR * -acpi_ut_get_mutex_name ( - u32 mutex_id) +/* Event type decoding */ + +static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = { + "PM_Timer", + "global_lock", + "power_button", + "sleep_button", + "real_time_clock", +}; + - if (mutex_id > MAX_MTX) +char * +acpi_ut_get_event_name ( + u32 event_id) +{ + + if (event_id > ACPI_EVENT_MAX) { - return ("Invalid Mutex ID"); + return ("invalid_event_iD"); } - return (acpi_gbl_mutex_names[mutex_id]); + return ((char *) acpi_gbl_event_types[event_id]); } +/***************************************************************************** + * + * FUNCTION: acpi_ut_get_type_name + * + * PARAMETERS: None. + * + * RETURN: Status + * + * DESCRIPTION: Translate a Type ID into a name string (Debug only) + * + ****************************************************************************/ + /* - * Elements of Acpi_gbl_Ns_type_names below must match + * Elements of acpi_gbl_ns_type_names below must match * one-to-one with values of acpi_object_type * * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when @@ -330,17 +468,17 @@ * indicatewhat type is actually going to be stored for this entry. */ -static const NATIVE_CHAR acpi_gbl_bad_type[] = "UNDEFINED"; +static const char acpi_gbl_bad_type[] = "UNDEFINED"; #define TYPE_NAME_LENGTH 12 /* Maximum length of each string */ -static const NATIVE_CHAR *acpi_gbl_ns_type_names[] = /* printable names of ACPI types */ +static const char *acpi_gbl_ns_type_names[] = /* printable names of ACPI types */ { /* 00 */ "Untyped", /* 01 */ "Integer", /* 02 */ "String", /* 03 */ "Buffer", /* 04 */ "Package", - /* 05 */ "Field_unit", + /* 05 */ "field_unit", /* 06 */ "Device", /* 07 */ "Event", /* 08 */ "Method", @@ -349,154 +487,91 @@ /* 11 */ "Power", /* 12 */ "Processor", /* 13 */ "Thermal", - /* 14 */ "Buffer_field", - /* 15 */ "Ddb_handle", - /* 16 */ "Debug_object", - /* 17 */ "Region_field", - /* 18 */ "Bank_field", - /* 19 */ "Index_field", + /* 14 */ "buffer_field", + /* 15 */ "ddb_handle", + /* 16 */ "debug_object", + /* 17 */ "region_field", + /* 18 */ "bank_field", + /* 19 */ "index_field", /* 20 */ "Reference", /* 21 */ "Alias", /* 22 */ "Notify", - /* 23 */ "Addr_handler", - /* 24 */ "Resource_desc", - /* 25 */ "Resource_fld", - /* 26 */ "Region_fld_dfn", - /* 27 */ "Bank_fld_dfn", - /* 28 */ "Index_fld_dfn", - /* 29 */ "If", - /* 30 */ "Else", - /* 31 */ "While", - /* 32 */ "Scope", - /* 33 */ "Def_any", - /* 34 */ "Extra", - /* 35 */ "Invalid" + /* 23 */ "addr_handler", + /* 24 */ "resource_desc", + /* 25 */ "resource_fld", + /* 26 */ "Scope", + /* 27 */ "Extra", + /* 28 */ "Data", + /* 39 */ "Invalid" }; -/***************************************************************************** - * - * FUNCTION: Acpi_ut_get_type_name - * - * PARAMETERS: None. - * - * RETURN: Status - * - * DESCRIPTION: Translate a Type ID into a name string (Debug only) - * - ****************************************************************************/ - -NATIVE_CHAR * +char * acpi_ut_get_type_name ( - u32 type) + acpi_object_type type) { - if (type > INTERNAL_TYPE_INVALID) + if (type > ACPI_TYPE_INVALID) { - return ((NATIVE_CHAR *) acpi_gbl_bad_type); + return ((char *) acpi_gbl_bad_type); } - return ((NATIVE_CHAR *) acpi_gbl_ns_type_names[type]); + return ((char *) acpi_gbl_ns_type_names[type]); } -/* Region type decoding */ - -const NATIVE_CHAR *acpi_gbl_region_types[NUM_REGION_TYPES] = +char * +acpi_ut_get_object_type_name ( + union acpi_operand_object *obj_desc) { - "System_memory", - "System_iO", - "PCIConfig", - "Embedded_control", - "SMBus", - "CMOS", - "PCIBar_target", -}; + + if (!obj_desc) + { + return ("[NULL Object Descriptor]"); + } + + return (acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc))); +} +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +/* + * Strings and procedures used for debug only + */ + /***************************************************************************** * - * FUNCTION: Acpi_ut_get_region_name + * FUNCTION: acpi_ut_get_mutex_name * * PARAMETERS: None. * * RETURN: Status * - * DESCRIPTION: Translate a Space ID into a name string (Debug only) + * DESCRIPTION: Translate a mutex ID into a name string (Debug only) * ****************************************************************************/ -NATIVE_CHAR * -acpi_ut_get_region_name ( - u8 space_id) +char * +acpi_ut_get_mutex_name ( + u32 mutex_id) { - if (space_id >= USER_REGION_BEGIN) - { - return ("User_defined_region"); - } - - else if (space_id >= NUM_REGION_TYPES) + if (mutex_id > MAX_MUTEX) { - return ("Invalid_space_iD"); + return ("Invalid Mutex ID"); } - return ((NATIVE_CHAR *) acpi_gbl_region_types[space_id]); + return (acpi_gbl_mutex_names[mutex_id]); } - -/* Data used in keeping track of fields */ - -const NATIVE_CHAR *acpi_gbl_FEnames[NUM_FIELD_NAMES] = -{ - "skip", - "?access?" -}; /* FE = Field Element */ - - -const NATIVE_CHAR *acpi_gbl_match_ops[NUM_MATCH_OPS] = -{ - "Error", - "MTR", - "MEQ", - "MLE", - "MLT", - "MGE", - "MGT" -}; - - -/* Access type decoding */ - -const NATIVE_CHAR *acpi_gbl_access_types[NUM_ACCESS_TYPES] = -{ - "Any_acc", - "Byte_acc", - "Word_acc", - "DWord_acc", - "Block_acc", - "SMBSend_recv_acc", - "SMBQuick_acc" -}; - - -/* Update rule decoding */ - -const NATIVE_CHAR *acpi_gbl_update_rules[NUM_UPDATE_RULES] = -{ - "Preserve", - "Write_as_ones", - "Write_as_zeros" -}; - #endif /***************************************************************************** * - * FUNCTION: Acpi_ut_valid_object_type + * FUNCTION: acpi_ut_valid_object_type * - * PARAMETERS: None. + * PARAMETERS: Type - Object type to be validated * * RETURN: TRUE if valid object type * @@ -506,16 +581,14 @@ u8 acpi_ut_valid_object_type ( - u32 type) + acpi_object_type type) { - if (type > ACPI_TYPE_MAX) + if (type > ACPI_TYPE_LOCAL_MAX) { - if ((type < INTERNAL_TYPE_BEGIN) || - (type > INTERNAL_TYPE_MAX)) - { - return (FALSE); - } + /* Note: Assumes all TYPEs are contiguous (external/local) */ + + return (FALSE); } return (TRUE); @@ -524,9 +597,9 @@ /**************************************************************************** * - * FUNCTION: Acpi_ut_allocate_owner_id + * FUNCTION: acpi_ut_allocate_owner_id * - * PARAMETERS: Id_type - Type of ID (method or table) + * PARAMETERS: id_type - Type of ID (method or table) * * DESCRIPTION: Allocate a table or method owner id * @@ -534,52 +607,61 @@ acpi_owner_id acpi_ut_allocate_owner_id ( - u32 id_type) + u32 id_type) { - acpi_owner_id owner_id = 0xFFFF; + acpi_owner_id owner_id = 0xFFFF; - FUNCTION_TRACE ("Ut_allocate_owner_id"); + ACPI_FUNCTION_TRACE ("ut_allocate_owner_id"); - acpi_ut_acquire_mutex (ACPI_MTX_CACHES); + if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) + { + return (0); + } switch (id_type) { - case OWNER_TYPE_TABLE: + case ACPI_OWNER_TYPE_TABLE: owner_id = acpi_gbl_next_table_owner_id; acpi_gbl_next_table_owner_id++; - if (acpi_gbl_next_table_owner_id == FIRST_METHOD_ID) + /* Check for wraparound */ + + if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID) { - acpi_gbl_next_table_owner_id = FIRST_TABLE_ID; + acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID; + ACPI_REPORT_WARNING (("Table owner ID wraparound\n")); } break; - case OWNER_TYPE_METHOD: + case ACPI_OWNER_TYPE_METHOD: owner_id = acpi_gbl_next_method_owner_id; acpi_gbl_next_method_owner_id++; - if (acpi_gbl_next_method_owner_id == FIRST_TABLE_ID) + if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID) { - acpi_gbl_next_method_owner_id = FIRST_METHOD_ID; + /* Check for wraparound */ + + acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID; } break; - } + default: + break; + } - acpi_ut_release_mutex (ACPI_MTX_CACHES); - + (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); return_VALUE (owner_id); } /**************************************************************************** * - * FUNCTION: Acpi_ut_init_globals + * FUNCTION: acpi_ut_init_globals * * PARAMETERS: none * @@ -592,33 +674,33 @@ acpi_ut_init_globals ( void) { - u32 i; + u32 i; - FUNCTION_TRACE ("Ut_init_globals"); + ACPI_FUNCTION_TRACE ("ut_init_globals"); /* Memory allocation and cache lists */ - MEMSET (acpi_gbl_memory_lists, 0, sizeof (ACPI_MEMORY_LIST) * ACPI_NUM_MEM_LISTS); + ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS); - acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].link_offset = (u16) (NATIVE_UINT) &(((acpi_generic_state *) NULL)->common.next); - acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].link_offset = (u16) (NATIVE_UINT) &(((acpi_parse_object *) NULL)->next); - acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].link_offset = (u16) (NATIVE_UINT) &(((acpi_parse2_object *) NULL)->next); - acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].link_offset = (u16) (NATIVE_UINT) &(((acpi_operand_object *) NULL)->cache.next); - acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].link_offset = (u16) (NATIVE_UINT) &(((acpi_walk_state *) NULL)->next); - - acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].object_size = sizeof (acpi_namespace_node); - acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].object_size = sizeof (acpi_generic_state); - acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].object_size = sizeof (acpi_parse_object); - acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].object_size = sizeof (acpi_parse2_object); - acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size = sizeof (acpi_operand_object); - acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size = sizeof (acpi_walk_state); - - acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth = MAX_STATE_CACHE_DEPTH; - acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = MAX_PARSE_CACHE_DEPTH; - acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = MAX_EXTPARSE_CACHE_DEPTH; - acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = MAX_OBJECT_CACHE_DEPTH; - acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth = MAX_WALK_CACHE_DEPTH; + acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_generic_state *) NULL)->common.next), NULL); + acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL); + acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL); + acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_operand_object *) NULL)->cache.next), NULL); + acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].link_offset = (u16) ACPI_PTR_DIFF (&(((struct acpi_walk_state *) NULL)->next), NULL); + + acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].object_size = sizeof (struct acpi_namespace_node); + acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].object_size = sizeof (union acpi_generic_state); + acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].object_size = sizeof (struct acpi_parse_obj_common); + acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].object_size = sizeof (struct acpi_parse_obj_named); + acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size = sizeof (union acpi_operand_object); + acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size = sizeof (struct acpi_walk_state); + + acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth = ACPI_MAX_STATE_CACHE_DEPTH; + acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = ACPI_MAX_PARSE_CACHE_DEPTH; + acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = ACPI_MAX_EXTPARSE_CACHE_DEPTH; + acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = ACPI_MAX_OBJECT_CACHE_DEPTH; + acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth = ACPI_MAX_WALK_CACHE_DEPTH; ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].list_name = "Global Memory Allocation"); ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].list_name = "Namespace Nodes"); @@ -630,38 +712,32 @@ /* ACPI table structure */ - for (i = 0; i < NUM_ACPI_TABLES; i++) + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { - acpi_gbl_acpi_tables[i].prev = &acpi_gbl_acpi_tables[i]; - acpi_gbl_acpi_tables[i].next = &acpi_gbl_acpi_tables[i]; - acpi_gbl_acpi_tables[i].pointer = NULL; - acpi_gbl_acpi_tables[i].length = 0; - acpi_gbl_acpi_tables[i].allocation = ACPI_MEM_NOT_ALLOCATED; - acpi_gbl_acpi_tables[i].count = 0; + acpi_gbl_table_lists[i].next = NULL; + acpi_gbl_table_lists[i].count = 0; } + /* Mutex locked flags */ - /* Address Space handler array */ - - for (i = 0; i < ACPI_NUM_ADDRESS_SPACES; i++) + for (i = 0; i < NUM_MUTEX; i++) { - acpi_gbl_address_spaces[i].handler = NULL; - acpi_gbl_address_spaces[i].context = NULL; + acpi_gbl_mutex_info[i].mutex = NULL; + acpi_gbl_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[i].use_count = 0; } - /* Mutex locked flags */ + /* GPE support */ - for (i = 0; i < NUM_MTX; i++) - { - acpi_gbl_acpi_mutex_info[i].mutex = NULL; - acpi_gbl_acpi_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED; - acpi_gbl_acpi_mutex_info[i].use_count = 0; - } + acpi_gbl_gpe_xrupt_list_head = NULL; + acpi_gbl_gpe_fadt_blocks[0] = NULL; + acpi_gbl_gpe_fadt_blocks[1] = NULL; /* Global notify handlers */ - acpi_gbl_sys_notify.handler = NULL; - acpi_gbl_drv_notify.handler = NULL; + acpi_gbl_system_notify.handler = NULL; + acpi_gbl_device_notify.handler = NULL; + acpi_gbl_init_handler = NULL; /* Global "typed" ACPI table pointers */ @@ -675,11 +751,11 @@ acpi_gbl_global_lock_acquired = FALSE; acpi_gbl_global_lock_thread_count = 0; + acpi_gbl_global_lock_handle = 0; /* Miscellaneous variables */ - acpi_gbl_system_flags = 0; - acpi_gbl_startup_flags = 0; + acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER; acpi_gbl_rsdp_original_location = 0; acpi_gbl_cm_single_step = FALSE; acpi_gbl_db_terminate_threads = FALSE; @@ -687,33 +763,30 @@ acpi_gbl_ns_lookup_count = 0; acpi_gbl_ps_find_count = 0; acpi_gbl_acpi_hardware_present = TRUE; - acpi_gbl_next_table_owner_id = FIRST_TABLE_ID; - acpi_gbl_next_method_owner_id = FIRST_METHOD_ID; + acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID; + acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID; acpi_gbl_debugger_configuration = DEBUGGER_THREADING; + acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; /* Hardware oriented */ - acpi_gbl_gpe0enable_register_save = NULL; - acpi_gbl_gpe1_enable_register_save = NULL; - acpi_gbl_original_mode = SYS_MODE_UNKNOWN; /* original ACPI/legacy mode */ - acpi_gbl_gpe_registers = NULL; - acpi_gbl_gpe_info = NULL; + acpi_gbl_events_initialized = FALSE; /* Namespace */ acpi_gbl_root_node = NULL; - acpi_gbl_root_node_struct.name = ACPI_ROOT_NAME; - acpi_gbl_root_node_struct.data_type = ACPI_DESC_TYPE_NAMED; - acpi_gbl_root_node_struct.type = ACPI_TYPE_ANY; + acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; + acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED; + acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; acpi_gbl_root_node_struct.child = NULL; acpi_gbl_root_node_struct.peer = NULL; acpi_gbl_root_node_struct.object = NULL; acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; -#ifdef ACPI_DEBUG - acpi_gbl_lowest_stack_pointer = ACPI_UINT32_MAX; +#ifdef ACPI_DEBUG_OUTPUT + acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; #endif return_VOID; diff -urN linux-2.4.21/drivers/acpi/utilities/utinit.c linux-2.4.22/drivers/acpi/utilities/utinit.c --- linux-2.4.21/drivers/acpi/utilities/utinit.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utinit.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,52 +1,63 @@ /****************************************************************************** * * Module Name: utinit - Common ACPI subsystem initialization - * $Revision: 102 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "achware.h" -#include "acnamesp.h" -#include "acevents.h" -#include "acparser.h" -#include "acdispat.h" +#include +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utinit") - - -#define ACPI_OFFSET(d,o) ((u32) &(((d *)0)->o)) -#define ACPI_FADT_OFFSET(o) ACPI_OFFSET (FADT_DESCRIPTOR, o) + ACPI_MODULE_NAME ("utinit") /******************************************************************************* * - * FUNCTION: Acpi_ut_fadt_register_error + * FUNCTION: acpi_ut_fadt_register_error * - * PARAMETERS: *Register_name - Pointer to string identifying register + * PARAMETERS: *register_name - Pointer to string identifying register * Value - Actual register contents value - * Acpi_test_spec_section - TDS section containing assertion - * Acpi_assertion - Assertion number being tested + * acpi_test_spec_section - TDS section containing assertion + * acpi_assertion - Assertion number being tested * * RETURN: AE_BAD_VALUE * @@ -54,25 +65,22 @@ * ******************************************************************************/ -static acpi_status +static void acpi_ut_fadt_register_error ( - NATIVE_CHAR *register_name, - u32 value, - u32 offset) + char *register_name, + u32 value, + acpi_size offset) { - REPORT_ERROR ( - ("Invalid FADT value %s=%lX at offset %lX FADT=%p\n", - register_name, value, offset, acpi_gbl_FADT)); - - - return (AE_BAD_VALUE); + ACPI_REPORT_WARNING ( + ("Invalid FADT value %s=%X at offset %X FADT=%p\n", + register_name, value, (u32) offset, acpi_gbl_FADT)); } /****************************************************************************** * - * FUNCTION: Acpi_ut_validate_fadt + * FUNCTION: acpi_ut_validate_fadt * * PARAMETERS: None * @@ -86,101 +94,114 @@ acpi_ut_validate_fadt ( void) { - acpi_status status = AE_OK; - /* * Verify Fixed ACPI Description Table fields, * but don't abort on any problems, just display error */ if (acpi_gbl_FADT->pm1_evt_len < 4) { - status = acpi_ut_fadt_register_error ("PM1_EVT_LEN", + acpi_ut_fadt_register_error ("PM1_EVT_LEN", (u32) acpi_gbl_FADT->pm1_evt_len, ACPI_FADT_OFFSET (pm1_evt_len)); } if (!acpi_gbl_FADT->pm1_cnt_len) { - status = acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0, + acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0, ACPI_FADT_OFFSET (pm1_cnt_len)); } - if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address)) { - status = acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0, - ACPI_FADT_OFFSET (Xpm1a_evt_blk.address)); + if (!acpi_gbl_FADT->xpm1a_evt_blk.address) { + acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0, + ACPI_FADT_OFFSET (xpm1a_evt_blk.address)); } - if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_cnt_blk.address)) { - status = acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0, - ACPI_FADT_OFFSET (Xpm1a_cnt_blk.address)); + if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) { + acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0, + ACPI_FADT_OFFSET (xpm1a_cnt_blk.address)); } - if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address)) { - status = acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0, - ACPI_FADT_OFFSET (Xpm_tmr_blk.address)); + if (!acpi_gbl_FADT->xpm_tmr_blk.address) { + acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0, + ACPI_FADT_OFFSET (xpm_tmr_blk.address)); } - if ((ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm2_cnt_blk.address) && + if ((acpi_gbl_FADT->xpm2_cnt_blk.address && !acpi_gbl_FADT->pm2_cnt_len)) { - status = acpi_ut_fadt_register_error ("PM2_CNT_LEN", + acpi_ut_fadt_register_error ("PM2_CNT_LEN", (u32) acpi_gbl_FADT->pm2_cnt_len, ACPI_FADT_OFFSET (pm2_cnt_len)); } if (acpi_gbl_FADT->pm_tm_len < 4) { - status = acpi_ut_fadt_register_error ("PM_TM_LEN", + acpi_ut_fadt_register_error ("PM_TM_LEN", (u32) acpi_gbl_FADT->pm_tm_len, ACPI_FADT_OFFSET (pm_tm_len)); } - /* length of GPE blocks must be a multiple of 2 */ + /* Length of GPE blocks must be a multiple of 2 */ - if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) && - (acpi_gbl_FADT->gpe0blk_len & 1)) { - status = acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN", - (u32) acpi_gbl_FADT->gpe0blk_len, - ACPI_FADT_OFFSET (gpe0blk_len)); + if (acpi_gbl_FADT->xgpe0_blk.address && + (acpi_gbl_FADT->gpe0_blk_len & 1)) { + acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN", + (u32) acpi_gbl_FADT->gpe0_blk_len, + ACPI_FADT_OFFSET (gpe0_blk_len)); } - if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) && + if (acpi_gbl_FADT->xgpe1_blk.address && (acpi_gbl_FADT->gpe1_blk_len & 1)) { - status = acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN", + acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN", (u32) acpi_gbl_FADT->gpe1_blk_len, ACPI_FADT_OFFSET (gpe1_blk_len)); } - return (status); + return (AE_OK); } /****************************************************************************** * - * FUNCTION: Acpi_ut_terminate + * FUNCTION: acpi_ut_terminate * * PARAMETERS: none * * RETURN: none * - * DESCRIPTION: free memory allocated for table storage. + * DESCRIPTION: free global memory * ******************************************************************************/ void acpi_ut_terminate (void) { + struct acpi_gpe_block_info *gpe_block; + struct acpi_gpe_block_info *next_gpe_block; + struct acpi_gpe_xrupt_info *gpe_xrupt_info; + struct acpi_gpe_xrupt_info *next_gpe_xrupt_info; - FUNCTION_TRACE ("Ut_terminate"); + + ACPI_FUNCTION_TRACE ("ut_terminate"); /* Free global tables, etc. */ - if (acpi_gbl_gpe0enable_register_save) { - ACPI_MEM_FREE (acpi_gbl_gpe0enable_register_save); - } - if (acpi_gbl_gpe1_enable_register_save) { - ACPI_MEM_FREE (acpi_gbl_gpe1_enable_register_save); - } + /* Free global GPE blocks and related info structures */ + gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; + while (gpe_xrupt_info) { + gpe_block = gpe_xrupt_info->gpe_block_list_head; + while (gpe_block) { + next_gpe_block = gpe_block->next; + ACPI_MEM_FREE (gpe_block->event_info); + ACPI_MEM_FREE (gpe_block->register_info); + ACPI_MEM_FREE (gpe_block); + + gpe_block = next_gpe_block; + } + next_gpe_xrupt_info = gpe_xrupt_info->next; + ACPI_MEM_FREE (gpe_xrupt_info); + gpe_xrupt_info = next_gpe_xrupt_info; + } return_VOID; } @@ -188,7 +209,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_subsystem_shutdown + * FUNCTION: acpi_ut_subsystem_shutdown * * PARAMETERS: none * @@ -199,17 +220,17 @@ * ******************************************************************************/ -acpi_status +void acpi_ut_subsystem_shutdown (void) { - FUNCTION_TRACE ("Ut_subsystem_shutdown"); + ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown"); /* Just exit if subsystem is already shutdown */ if (acpi_gbl_shutdown) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "ACPI Subsystem is already terminated\n")); - return_ACPI_STATUS (AE_OK); + return_VOID; } /* Subsystem appears active, go ahead and shut it down */ @@ -217,30 +238,21 @@ acpi_gbl_shutdown = TRUE; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n")); + /* Close the acpi_event Handling */ + + acpi_ev_terminate (); /* Close the Namespace */ acpi_ns_terminate (); - /* Close the Acpi_event Handling */ - - acpi_ev_terminate (); - /* Close the globals */ acpi_ut_terminate (); - /* Flush the local cache(s) */ - - acpi_ut_delete_generic_state_cache (); - acpi_ut_delete_object_cache (); - acpi_ds_delete_walk_state_cache (); - - /* Close the Parser */ + /* Purge the local caches */ - /* TBD: [Restructure] Acpi_ps_terminate () */ - - acpi_ps_delete_parse_cache (); + (void) acpi_purge_cached_objects (); /* Debug only - display leftover memory allocation, if any */ @@ -248,7 +260,7 @@ acpi_ut_dump_allocations (ACPI_UINT32_MAX, NULL); #endif - return_ACPI_STATUS (AE_OK); + return_VOID; } diff -urN linux-2.4.21/drivers/acpi/utilities/utmath.c linux-2.4.22/drivers/acpi/utilities/utmath.c --- linux-2.4.21/drivers/acpi/utilities/utmath.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utmath.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,34 +1,52 @@ /******************************************************************************* * * Module Name: utmath - Integer math support routines - * $Revision: 7 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utmath") + ACPI_MODULE_NAME ("utmath") /* * Support for double-precision integer divide. This code is included here @@ -39,12 +57,12 @@ #ifndef ACPI_USE_NATIVE_DIVIDE /******************************************************************************* * - * FUNCTION: Acpi_ut_short_divide + * FUNCTION: acpi_ut_short_divide * - * PARAMETERS: In_dividend - Pointer to the dividend + * PARAMETERS: in_dividend - Pointer to the dividend * Divisor - 32-bit divisor - * Out_quotient - Pointer to where the quotient is returned - * Out_remainder - Pointer to where the remainder is returned + * out_quotient - Pointer to where the quotient is returned + * out_remainder - Pointer to where the remainder is returned * * RETURN: Status (Checks for divide-by-zero) * @@ -56,24 +74,24 @@ acpi_status acpi_ut_short_divide ( - acpi_integer *in_dividend, - u32 divisor, - acpi_integer *out_quotient, - u32 *out_remainder) + acpi_integer *in_dividend, + u32 divisor, + acpi_integer *out_quotient, + u32 *out_remainder) { - uint64_overlay dividend; - uint64_overlay quotient; - u32 remainder32; + union uint64_overlay dividend; + union uint64_overlay quotient; + u32 remainder32; - FUNCTION_TRACE ("Ut_short_divide"); + ACPI_FUNCTION_TRACE ("ut_short_divide"); dividend.full = *in_dividend; /* Always check for a zero divisor */ if (divisor == 0) { - REPORT_ERROR (("Acpi_ut_short_divide: Divide by zero\n")); + ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n")); return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); } @@ -101,12 +119,12 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_divide + * FUNCTION: acpi_ut_divide * - * PARAMETERS: In_dividend - Pointer to the dividend - * In_divisor - Pointer to the divisor - * Out_quotient - Pointer to where the quotient is returned - * Out_remainder - Pointer to where the remainder is returned + * PARAMETERS: in_dividend - Pointer to the dividend + * in_divisor - Pointer to the divisor + * out_quotient - Pointer to where the quotient is returned + * out_remainder - Pointer to where the remainder is returned * * RETURN: Status (Checks for divide-by-zero) * @@ -116,29 +134,29 @@ acpi_status acpi_ut_divide ( - acpi_integer *in_dividend, - acpi_integer *in_divisor, - acpi_integer *out_quotient, - acpi_integer *out_remainder) + acpi_integer *in_dividend, + acpi_integer *in_divisor, + acpi_integer *out_quotient, + acpi_integer *out_remainder) { - uint64_overlay dividend; - uint64_overlay divisor; - uint64_overlay quotient; - uint64_overlay remainder; - uint64_overlay normalized_dividend; - uint64_overlay normalized_divisor; - u32 partial1; - uint64_overlay partial2; - uint64_overlay partial3; + union uint64_overlay dividend; + union uint64_overlay divisor; + union uint64_overlay quotient; + union uint64_overlay remainder; + union uint64_overlay normalized_dividend; + union uint64_overlay normalized_divisor; + u32 partial1; + union uint64_overlay partial2; + union uint64_overlay partial3; - FUNCTION_TRACE ("Ut_divide"); + ACPI_FUNCTION_TRACE ("ut_divide"); /* Always check for a zero divisor */ if (*in_divisor == 0) { - REPORT_ERROR (("Acpi_ut_divide: Divide by zero\n")); + ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n")); return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); } @@ -193,7 +211,7 @@ */ partial1 = quotient.part.lo * divisor.part.hi; partial2.full = (acpi_integer) quotient.part.lo * divisor.part.lo; - partial3.full = partial2.part.hi + partial1; + partial3.full = (acpi_integer) partial2.part.hi + partial1; remainder.part.hi = partial3.part.lo; remainder.part.lo = partial2.part.lo; @@ -213,8 +231,8 @@ } remainder.full = remainder.full - dividend.full; - remainder.part.hi = -((s32) remainder.part.hi); - remainder.part.lo = -((s32) remainder.part.lo); + remainder.part.hi = (u32) -((s32) remainder.part.hi); + remainder.part.lo = (u32) -((s32) remainder.part.lo); if (remainder.part.lo) { remainder.part.hi--; @@ -238,9 +256,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_short_divide, Acpi_ut_divide + * FUNCTION: acpi_ut_short_divide, acpi_ut_divide * - * DESCRIPTION: Native versions of the Ut_divide functions. Use these if either + * DESCRIPTION: Native versions of the ut_divide functions. Use these if either * 1) The target is a 64-bit platform and therefore 64-bit * integer math is supported directly by the machine. * 2) The target is a 32-bit or 16-bit platform, and the @@ -251,19 +269,19 @@ acpi_status acpi_ut_short_divide ( - acpi_integer *in_dividend, - u32 divisor, - acpi_integer *out_quotient, - u32 *out_remainder) + acpi_integer *in_dividend, + u32 divisor, + acpi_integer *out_quotient, + u32 *out_remainder) { - FUNCTION_TRACE ("Ut_short_divide"); + ACPI_FUNCTION_TRACE ("ut_short_divide"); /* Always check for a zero divisor */ if (divisor == 0) { - REPORT_ERROR (("Acpi_ut_short_divide: Divide by zero\n")); + ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n")); return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); } @@ -281,18 +299,18 @@ acpi_status acpi_ut_divide ( - acpi_integer *in_dividend, - acpi_integer *in_divisor, - acpi_integer *out_quotient, - acpi_integer *out_remainder) + acpi_integer *in_dividend, + acpi_integer *in_divisor, + acpi_integer *out_quotient, + acpi_integer *out_remainder) { - FUNCTION_TRACE ("Ut_divide"); + ACPI_FUNCTION_TRACE ("ut_divide"); /* Always check for a zero divisor */ if (*in_divisor == 0) { - REPORT_ERROR (("Acpi_ut_divide: Divide by zero\n")); + ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n")); return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); } diff -urN linux-2.4.21/drivers/acpi/utilities/utmisc.c linux-2.4.22/drivers/acpi/utilities/utmisc.c --- linux-2.4.21/drivers/acpi/utilities/utmisc.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utmisc.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,45 +1,292 @@ /******************************************************************************* * * Module Name: utmisc - common utility procedures - * $Revision: 52 $ * ******************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acevents.h" -#include "achware.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acdebug.h" +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utmisc") + ACPI_MODULE_NAME ("utmisc") /******************************************************************************* * - * FUNCTION: Acpi_ut_valid_acpi_name + * FUNCTION: acpi_ut_print_string + * + * PARAMETERS: String - Null terminated ASCII string + * + * RETURN: None + * + * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape + * sequences. + * + ******************************************************************************/ + +void +acpi_ut_print_string ( + char *string, + u8 max_length) +{ + u32 i; + + + if (!string) { + acpi_os_printf ("<\"NULL STRING PTR\">"); + return; + } + + acpi_os_printf ("\""); + for (i = 0; string[i] && (i < max_length); i++) { + /* Escape sequences */ + + switch (string[i]) { + case 0x07: + acpi_os_printf ("\\a"); /* BELL */ + break; + + case 0x08: + acpi_os_printf ("\\b"); /* BACKSPACE */ + break; + + case 0x0C: + acpi_os_printf ("\\f"); /* FORMFEED */ + break; + + case 0x0A: + acpi_os_printf ("\\n"); /* LINEFEED */ + break; + + case 0x0D: + acpi_os_printf ("\\r"); /* CARRIAGE RETURN*/ + break; + + case 0x09: + acpi_os_printf ("\\t"); /* HORIZONTAL TAB */ + break; + + case 0x0B: + acpi_os_printf ("\\v"); /* VERTICAL TAB */ + break; + + case '\'': /* Single Quote */ + case '\"': /* Double Quote */ + case '\\': /* Backslash */ + acpi_os_printf ("\\%c", (int) string[i]); + break; + + default: + + /* Check for printable character or hex escape */ + + if (ACPI_IS_PRINT (string[i])) + { + /* This is a normal character */ + + acpi_os_printf ("%c", (int) string[i]); + } + else + { + /* All others will be Hex escapes */ + + acpi_os_printf ("\\x%2.2X", (s32) string[i]); + } + break; + } + } + acpi_os_printf ("\""); + + if (i == max_length && string[i]) { + acpi_os_printf ("..."); + } +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_dword_byte_swap + * + * PARAMETERS: Value - Value to be converted + * + * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) + * + ******************************************************************************/ + +u32 +acpi_ut_dword_byte_swap ( + u32 value) +{ + union { + u32 value; + u8 bytes[4]; + } out; + + union { + u32 value; + u8 bytes[4]; + } in; + + + ACPI_FUNCTION_ENTRY (); + + + in.value = value; + + out.bytes[0] = in.bytes[3]; + out.bytes[1] = in.bytes[2]; + out.bytes[2] = in.bytes[1]; + out.bytes[3] = in.bytes[0]; + + return (out.value); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_set_integer_width + * + * PARAMETERS: Revision From DSDT header + * + * RETURN: None + * + * DESCRIPTION: Set the global integer bit width based upon the revision + * of the DSDT. For Revision 1 and 0, Integers are 32 bits. + * For Revision 2 and above, Integers are 64 bits. Yes, this + * makes a difference. + * + ******************************************************************************/ + +void +acpi_ut_set_integer_width ( + u8 revision) +{ + + if (revision <= 1) { + acpi_gbl_integer_bit_width = 32; + acpi_gbl_integer_nybble_width = 8; + acpi_gbl_integer_byte_width = 4; + } + else { + acpi_gbl_integer_bit_width = 64; + acpi_gbl_integer_nybble_width = 16; + acpi_gbl_integer_byte_width = 8; + } +} + + +#ifdef ACPI_DEBUG_OUTPUT +/******************************************************************************* + * + * FUNCTION: acpi_ut_display_init_pathname + * + * PARAMETERS: obj_handle - Handle whose pathname will be displayed + * Path - Additional path string to be appended. + * (NULL if no extra path) + * + * RETURN: acpi_status + * + * DESCRIPTION: Display full pathname of an object, DEBUG ONLY + * + ******************************************************************************/ + +void +acpi_ut_display_init_pathname ( + u8 type, + struct acpi_namespace_node *obj_handle, + char *path) +{ + acpi_status status; + struct acpi_buffer buffer; + + + ACPI_FUNCTION_ENTRY (); + + + /* Only print the path if the appropriate debug level is enabled */ + + if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { + return; + } + + /* Get the full pathname to the node */ + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_ns_handle_to_pathname (obj_handle, &buffer); + if (ACPI_FAILURE (status)) { + return; + } + + /* Print what we're doing */ + + switch (type) { + case ACPI_TYPE_METHOD: + acpi_os_printf ("Executing "); + break; + + default: + acpi_os_printf ("Initializing "); + break; + } + + /* Print the object type and pathname */ + + acpi_os_printf ("%-12s %s", acpi_ut_get_type_name (type), (char *) buffer.pointer); + + /* Extra path is used to append names like _STA, _INI, etc. */ + + if (path) { + acpi_os_printf (".%s", path); + } + acpi_os_printf ("\n"); + + ACPI_MEM_FREE (buffer.pointer); +} +#endif + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_valid_acpi_name * * PARAMETERS: Character - The character to be examined * @@ -54,13 +301,13 @@ u8 acpi_ut_valid_acpi_name ( - u32 name) + u32 name) { - NATIVE_CHAR *name_ptr = (NATIVE_CHAR *) &name; - u32 i; + char *name_ptr = (char *) &name; + u32 i; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); for (i = 0; i < ACPI_NAME_SIZE; i++) { @@ -77,7 +324,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_valid_acpi_character + * FUNCTION: acpi_ut_valid_acpi_character * * PARAMETERS: Character - The character to be examined * @@ -89,10 +336,10 @@ u8 acpi_ut_valid_acpi_character ( - NATIVE_CHAR character) + char character) { - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); return ((u8) ((character == '_') || (character >= 'A' && character <= 'Z') || @@ -102,40 +349,185 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_strupr + * FUNCTION: acpi_ut_strtoul64 + * + * PARAMETERS: String - Null terminated string + * Terminater - Where a pointer to the terminating byte is returned + * Base - Radix of the string + * + * RETURN: Converted value + * + * DESCRIPTION: Convert a string into an unsigned value. + * + ******************************************************************************/ +#define NEGATIVE 1 +#define POSITIVE 0 + +acpi_status +acpi_ut_strtoul64 ( + char *string, + u32 base, + acpi_integer *ret_integer) +{ + u32 index; + acpi_integer return_value = 0; + acpi_status status = AE_OK; + acpi_integer dividend; + acpi_integer quotient; + + + *ret_integer = 0; + + switch (base) { + case 0: + case 8: + case 10: + case 16: + break; + + default: + /* + * The specified Base parameter is not in the domain of + * this function: + */ + return (AE_BAD_PARAMETER); + } + + /* + * skip over any white space in the buffer: + */ + while (ACPI_IS_SPACE (*string) || *string == '\t') { + ++string; + } + + /* + * If the input parameter Base is zero, then we need to + * determine if it is octal, decimal, or hexadecimal: + */ + if (base == 0) { + if (*string == '0') { + if (ACPI_TOLOWER (*(++string)) == 'x') { + base = 16; + ++string; + } + else { + base = 8; + } + } + else { + base = 10; + } + } + + /* + * For octal and hexadecimal bases, skip over the leading + * 0 or 0x, if they are present. + */ + if (base == 8 && *string == '0') { + string++; + } + + if (base == 16 && + *string == '0' && + ACPI_TOLOWER (*(++string)) == 'x') { + string++; + } + + /* Main loop: convert the string to an unsigned long */ + + while (*string) { + if (ACPI_IS_DIGIT (*string)) { + index = ((u8) *string) - '0'; + } + else { + index = (u8) ACPI_TOUPPER (*string); + if (ACPI_IS_UPPER ((char) index)) { + index = index - 'A' + 10; + } + else { + goto error_exit; + } + } + + if (index >= base) { + goto error_exit; + } + + /* Check to see if value is out of range: */ + + dividend = ACPI_INTEGER_MAX - (acpi_integer) index; + (void) acpi_ut_short_divide (÷nd, base, "ient, NULL); + if (return_value > quotient) { + goto error_exit; + } + + return_value *= base; + return_value += index; + ++string; + } + + *ret_integer = return_value; + return (status); + + +error_exit: + switch (base) { + case 8: + status = AE_BAD_OCTAL_CONSTANT; + break; + + case 10: + status = AE_BAD_DECIMAL_CONSTANT; + break; + + case 16: + status = AE_BAD_HEX_CONSTANT; + break; + + default: + /* Base validated above */ + break; + } + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strupr * - * PARAMETERS: Src_string - The source string to convert to + * PARAMETERS: src_string - The source string to convert to * - * RETURN: Src_string + * RETURN: src_string * * DESCRIPTION: Convert string to uppercase * ******************************************************************************/ -NATIVE_CHAR * +char * acpi_ut_strupr ( - NATIVE_CHAR *src_string) + char *src_string) { - NATIVE_CHAR *string; + char *string; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* Walk entire string, uppercasing the letters */ for (string = src_string; *string; ) { - *string = (char) TOUPPER (*string); + *string = (char) ACPI_TOUPPER (*string); string++; } - return (src_string); } /******************************************************************************* * - * FUNCTION: Acpi_ut_mutex_initialize + * FUNCTION: acpi_ut_mutex_initialize * * PARAMETERS: None. * @@ -149,30 +541,33 @@ acpi_ut_mutex_initialize ( void) { - u32 i; - acpi_status status; + u32 i; + acpi_status status; - FUNCTION_TRACE ("Ut_mutex_initialize"); + ACPI_FUNCTION_TRACE ("ut_mutex_initialize"); /* * Create each of the predefined mutex objects */ - for (i = 0; i < NUM_MTX; i++) { + for (i = 0; i < NUM_MUTEX; i++) { status = acpi_ut_create_mutex (i); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } + + status = acpi_os_create_lock (&acpi_gbl_gpe_lock); + return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ut_mutex_terminate + * FUNCTION: acpi_ut_mutex_terminate * * PARAMETERS: None. * @@ -186,28 +581,29 @@ acpi_ut_mutex_terminate ( void) { - u32 i; + u32 i; - FUNCTION_TRACE ("Ut_mutex_terminate"); + ACPI_FUNCTION_TRACE ("ut_mutex_terminate"); /* * Delete each predefined mutex object */ - for (i = 0; i < NUM_MTX; i++) { - acpi_ut_delete_mutex (i); + for (i = 0; i < NUM_MUTEX; i++) { + (void) acpi_ut_delete_mutex (i); } + acpi_os_delete_lock (acpi_gbl_gpe_lock); return_VOID; } /******************************************************************************* * - * FUNCTION: Acpi_ut_create_mutex + * FUNCTION: acpi_ut_create_mutex * - * PARAMETERS: Mutex_iD - ID of the mutex to be created + * PARAMETERS: mutex_iD - ID of the mutex to be created * * RETURN: Status * @@ -217,24 +613,23 @@ acpi_status acpi_ut_create_mutex ( - ACPI_MUTEX_HANDLE mutex_id) + acpi_mutex_handle mutex_id) { - acpi_status status = AE_OK; + acpi_status status = AE_OK; - FUNCTION_TRACE_U32 ("Ut_create_mutex", mutex_id); + ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - - if (!acpi_gbl_acpi_mutex_info[mutex_id].mutex) { + if (!acpi_gbl_mutex_info[mutex_id].mutex) { status = acpi_os_create_semaphore (1, 1, - &acpi_gbl_acpi_mutex_info[mutex_id].mutex); - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; - acpi_gbl_acpi_mutex_info[mutex_id].use_count = 0; + &acpi_gbl_mutex_info[mutex_id].mutex); + acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[mutex_id].use_count = 0; } return_ACPI_STATUS (status); @@ -243,9 +638,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_mutex + * FUNCTION: acpi_ut_delete_mutex * - * PARAMETERS: Mutex_iD - ID of the mutex to be deleted + * PARAMETERS: mutex_iD - ID of the mutex to be deleted * * RETURN: Status * @@ -255,23 +650,22 @@ acpi_status acpi_ut_delete_mutex ( - ACPI_MUTEX_HANDLE mutex_id) + acpi_mutex_handle mutex_id) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE_U32 ("Ut_delete_mutex", mutex_id); + ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex); - status = acpi_os_delete_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex); - - acpi_gbl_acpi_mutex_info[mutex_id].mutex = NULL; - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[mutex_id].mutex = NULL; + acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; return_ACPI_STATUS (status); } @@ -279,9 +673,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_acquire_mutex + * FUNCTION: acpi_ut_acquire_mutex * - * PARAMETERS: Mutex_iD - ID of the mutex to be acquired + * PARAMETERS: mutex_iD - ID of the mutex to be acquired * * RETURN: Status * @@ -291,21 +685,20 @@ acpi_status acpi_ut_acquire_mutex ( - ACPI_MUTEX_HANDLE mutex_id) + acpi_mutex_handle mutex_id) { - acpi_status status; - u32 i; - u32 this_thread_id; + acpi_status status; + u32 i; + u32 this_thread_id; - PROC_NAME ("Ut_acquire_mutex"); + ACPI_FUNCTION_NAME ("ut_acquire_mutex"); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return (AE_BAD_PARAMETER); } - this_thread_id = acpi_os_get_thread_id (); /* @@ -314,8 +707,8 @@ * the mutex ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < MAX_MTX; i++) { - if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) { + for (i = mutex_id; i < MAX_MUTEX; i++) { + if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { if (i == mutex_id) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] already acquired by this thread [%X]\n", @@ -333,22 +726,19 @@ } } - ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X attempting to acquire Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); - status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, - 1, WAIT_FOREVER); - + status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, + 1, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); - acpi_gbl_acpi_mutex_info[mutex_id].use_count++; - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = this_thread_id; + acpi_gbl_mutex_info[mutex_id].use_count++; + acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id; } - else { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id), @@ -361,9 +751,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_release_mutex + * FUNCTION: acpi_ut_release_mutex * - * PARAMETERS: Mutex_iD - ID of the mutex to be released + * PARAMETERS: mutex_iD - ID of the mutex to be released * * RETURN: Status * @@ -373,14 +763,14 @@ acpi_status acpi_ut_release_mutex ( - ACPI_MUTEX_HANDLE mutex_id) + acpi_mutex_handle mutex_id) { - acpi_status status; - u32 i; - u32 this_thread_id; + acpi_status status; + u32 i; + u32 this_thread_id; - PROC_NAME ("Ut_release_mutex"); + ACPI_FUNCTION_NAME ("ut_release_mutex"); this_thread_id = acpi_os_get_thread_id (); @@ -388,15 +778,14 @@ "Thread %X releasing Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return (AE_BAD_PARAMETER); } - /* * Mutex must be acquired in order to release it! */ - if (acpi_gbl_acpi_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { + if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] is not acquired, cannot release\n", acpi_ut_get_mutex_name (mutex_id))); @@ -404,15 +793,14 @@ return (AE_NOT_ACQUIRED); } - /* * Deadlock prevention. Check if this thread owns any mutexes of value * greater than this one. If so, the thread has violated the mutex * ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < MAX_MTX; i++) { - if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) { + for (i = mutex_id; i < MAX_MUTEX; i++) { + if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { if (i == mutex_id) { continue; } @@ -425,12 +813,11 @@ } } - /* Mark unlocked FIRST */ - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; - status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1); + status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n", @@ -448,11 +835,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_update_state_and_push + * FUNCTION: acpi_ut_create_update_state_and_push * * PARAMETERS: *Object - Object to be added to the new state * Action - Increment/Decrement - * State_list - List the state will be added to + * state_list - List the state will be added to * * RETURN: None * @@ -462,14 +849,14 @@ acpi_status acpi_ut_create_update_state_and_push ( - acpi_operand_object *object, - u16 action, - acpi_generic_state **state_list) + union acpi_operand_object *object, + u16 action, + union acpi_generic_state **state_list) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); /* Ignore null objects; these are expected */ @@ -483,7 +870,6 @@ return (AE_NO_MEMORY); } - acpi_ut_push_generic_state (state_list, state); return (AE_OK); } @@ -491,11 +877,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_pkg_state_and_push + * FUNCTION: acpi_ut_create_pkg_state_and_push * * PARAMETERS: *Object - Object to be added to the new state * Action - Increment/Decrement - * State_list - List the state will be added to + * state_list - List the state will be added to * * RETURN: None * @@ -505,15 +891,15 @@ acpi_status acpi_ut_create_pkg_state_and_push ( - void *internal_object, - void *external_object, - u16 index, - acpi_generic_state **state_list) + void *internal_object, + void *external_object, + u16 index, + union acpi_generic_state **state_list) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); state = acpi_ut_create_pkg_state (internal_object, external_object, index); @@ -521,7 +907,6 @@ return (AE_NO_MEMORY); } - acpi_ut_push_generic_state (state_list, state); return (AE_OK); } @@ -529,9 +914,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_push_generic_state + * FUNCTION: acpi_ut_push_generic_state * - * PARAMETERS: List_head - Head of the state stack + * PARAMETERS: list_head - Head of the state stack * State - State object to push * * RETURN: Status @@ -542,10 +927,10 @@ void acpi_ut_push_generic_state ( - acpi_generic_state **list_head, - acpi_generic_state *state) + union acpi_generic_state **list_head, + union acpi_generic_state *state) { - FUNCTION_TRACE ("Ut_push_generic_state"); + ACPI_FUNCTION_TRACE ("ut_push_generic_state"); /* Push the state object onto the front of the list (stack) */ @@ -559,9 +944,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_pop_generic_state + * FUNCTION: acpi_ut_pop_generic_state * - * PARAMETERS: List_head - Head of the state stack + * PARAMETERS: list_head - Head of the state stack * * RETURN: Status * @@ -569,14 +954,14 @@ * ******************************************************************************/ -acpi_generic_state * +union acpi_generic_state * acpi_ut_pop_generic_state ( - acpi_generic_state **list_head) + union acpi_generic_state **list_head) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_TRACE ("Ut_pop_generic_state"); + ACPI_FUNCTION_TRACE ("ut_pop_generic_state"); /* Remove the state object at the head of the list (stack) */ @@ -594,7 +979,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_generic_state + * FUNCTION: acpi_ut_create_generic_state * * PARAMETERS: None * @@ -605,13 +990,13 @@ * ******************************************************************************/ -acpi_generic_state * +union acpi_generic_state * acpi_ut_create_generic_state (void) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE); @@ -628,7 +1013,46 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_update_state + * FUNCTION: acpi_ut_create_thread_state + * + * PARAMETERS: None + * + * RETURN: Thread State + * + * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used + * to track per-thread info during method execution + * + ******************************************************************************/ + +struct acpi_thread_state * +acpi_ut_create_thread_state ( + void) +{ + union acpi_generic_state *state; + + + ACPI_FUNCTION_TRACE ("ut_create_thread_state"); + + + /* Create the generic state object */ + + state = acpi_ut_create_generic_state (); + if (!state) { + return_PTR (NULL); + } + + /* Init fields specific to the update struct */ + + state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD; + state->thread.thread_id = acpi_os_get_thread_id (); + + return_PTR ((struct acpi_thread_state *) state); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_create_update_state * * PARAMETERS: Object - Initial Object to be installed in the * state @@ -642,22 +1066,22 @@ * ******************************************************************************/ -acpi_generic_state * +union acpi_generic_state * acpi_ut_create_update_state ( - acpi_operand_object *object, - u16 action) + union acpi_operand_object *object, + u16 action) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_TRACE_PTR ("Ut_create_update_state", object); + ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object); /* Create the generic state object */ state = acpi_ut_create_generic_state (); if (!state) { - return (NULL); + return_PTR (NULL); } /* Init fields specific to the update struct */ @@ -672,7 +1096,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_pkg_state + * FUNCTION: acpi_ut_create_pkg_state * * PARAMETERS: Object - Initial Object to be installed in the * state @@ -684,29 +1108,29 @@ * ******************************************************************************/ -acpi_generic_state * +union acpi_generic_state * acpi_ut_create_pkg_state ( - void *internal_object, - void *external_object, - u16 index) + void *internal_object, + void *external_object, + u16 index) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_TRACE_PTR ("Ut_create_pkg_state", internal_object); + ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object); /* Create the generic state object */ state = acpi_ut_create_generic_state (); if (!state) { - return (NULL); + return_PTR (NULL); } /* Init fields specific to the update struct */ state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE; - state->pkg.source_object = (acpi_operand_object *) internal_object; + state->pkg.source_object = (union acpi_operand_object *) internal_object; state->pkg.dest_object = external_object; state->pkg.index = index; state->pkg.num_packages = 1; @@ -717,7 +1141,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_create_control_state + * FUNCTION: acpi_ut_create_control_state * * PARAMETERS: None * @@ -728,28 +1152,27 @@ * ******************************************************************************/ -acpi_generic_state * +union acpi_generic_state * acpi_ut_create_control_state ( void) { - acpi_generic_state *state; + union acpi_generic_state *state; - FUNCTION_TRACE ("Ut_create_control_state"); + ACPI_FUNCTION_TRACE ("ut_create_control_state"); /* Create the generic state object */ state = acpi_ut_create_generic_state (); if (!state) { - return (NULL); + return_PTR (NULL); } - /* Init fields specific to the control struct */ state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL; - state->common.state = CONTROL_CONDITIONAL_EXECUTING; + state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; return_PTR (state); } @@ -757,7 +1180,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_generic_state + * FUNCTION: acpi_ut_delete_generic_state * * PARAMETERS: State - The state object to be deleted * @@ -770,9 +1193,9 @@ void acpi_ut_delete_generic_state ( - acpi_generic_state *state) + union acpi_generic_state *state) { - FUNCTION_TRACE ("Ut_delete_generic_state"); + ACPI_FUNCTION_TRACE ("ut_delete_generic_state"); acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state); @@ -782,7 +1205,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_generic_state_cache + * FUNCTION: acpi_ut_delete_generic_state_cache * * PARAMETERS: None * @@ -797,7 +1220,7 @@ acpi_ut_delete_generic_state_cache ( void) { - FUNCTION_TRACE ("Ut_delete_generic_state_cache"); + ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache"); acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE); @@ -807,106 +1230,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_resolve_package_references - * - * PARAMETERS: Obj_desc - The Package object on which to resolve refs - * - * RETURN: Status - * - * DESCRIPTION: Walk through a package and turn internal references into values - * - ******************************************************************************/ - -acpi_status -acpi_ut_resolve_package_references ( - acpi_operand_object *obj_desc) -{ - u32 count; - acpi_operand_object *sub_object; - - - FUNCTION_TRACE ("Ut_resolve_package_references"); - - - if (obj_desc->common.type != ACPI_TYPE_PACKAGE) { - /* The object must be a package */ - - REPORT_ERROR (("Must resolve Package Refs on a Package\n")); - return_ACPI_STATUS(AE_ERROR); - } - - /* - * TBD: what about nested packages? */ - - for (count = 0; count < obj_desc->package.count; count++) { - sub_object = obj_desc->package.elements[count]; - - if (sub_object->common.type == INTERNAL_TYPE_REFERENCE) { - if (sub_object->reference.opcode == AML_ZERO_OP) { - sub_object->common.type = ACPI_TYPE_INTEGER; - sub_object->integer.value = 0; - } - - else if (sub_object->reference.opcode == AML_ONE_OP) { - sub_object->common.type = ACPI_TYPE_INTEGER; - sub_object->integer.value = 1; - } - - else if (sub_object->reference.opcode == AML_ONES_OP) { - sub_object->common.type = ACPI_TYPE_INTEGER; - sub_object->integer.value = ACPI_INTEGER_MAX; - } - } - } - - return_ACPI_STATUS(AE_OK); -} - -#ifdef ACPI_DEBUG - -/******************************************************************************* - * - * FUNCTION: Acpi_ut_display_init_pathname - * - * PARAMETERS: Obj_handle - Handle whose pathname will be displayed - * Path - Additional path string to be appended - * - * RETURN: acpi_status - * - * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY - * - ******************************************************************************/ - -void -acpi_ut_display_init_pathname ( - acpi_handle obj_handle, - char *path) -{ - acpi_status status; - u32 length = 128; - char buffer[128]; - - - PROC_NAME ("Ut_display_init_pathname"); - - - status = acpi_ns_handle_to_pathname (obj_handle, &length, buffer); - if (ACPI_SUCCESS (status)) { - if (path) { - ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", buffer, path)); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", buffer)); - } - } -} -#endif - -/******************************************************************************* - * - * FUNCTION: Acpi_ut_walk_package_tree + * FUNCTION: acpi_ut_walk_package_tree * - * PARAMETERS: Obj_desc - The Package object on which to resolve refs + * PARAMETERS: obj_desc - The Package object on which to resolve refs * * RETURN: Status * @@ -916,19 +1242,19 @@ acpi_status acpi_ut_walk_package_tree ( - acpi_operand_object *source_object, - void *target_object, - ACPI_PKG_CALLBACK walk_callback, - void *context) -{ - acpi_status status = AE_OK; - acpi_generic_state *state_list = NULL; - acpi_generic_state *state; - u32 this_index; - acpi_operand_object *this_source_obj; + union acpi_operand_object *source_object, + void *target_object, + acpi_pkg_callback walk_callback, + void *context) +{ + acpi_status status = AE_OK; + union acpi_generic_state *state_list = NULL; + union acpi_generic_state *state; + u32 this_index; + union acpi_operand_object *this_source_obj; - FUNCTION_TRACE ("Ut_walk_package_tree"); + ACPI_FUNCTION_TRACE ("ut_walk_package_tree"); state = acpi_ut_create_pkg_state (source_object, target_object, 0); @@ -937,29 +1263,26 @@ } while (state) { + /* Get one element of the package */ + this_index = state->pkg.index; - this_source_obj = (acpi_operand_object *) + this_source_obj = (union acpi_operand_object *) state->pkg.source_object->package.elements[this_index]; /* - * Check for + * Check for: * 1) An uninitialized package element. It is completely - * legal to declare a package and leave it uninitialized + * legal to declare a package and leave it uninitialized * 2) Not an internal object - can be a namespace node instead * 3) Any type other than a package. Packages are handled in else - * case below. + * case below. */ if ((!this_source_obj) || - (!VALID_DESCRIPTOR_TYPE ( - this_source_obj, ACPI_DESC_TYPE_INTERNAL)) || - (!IS_THIS_OBJECT_TYPE ( - this_source_obj, ACPI_TYPE_PACKAGE))) { - + (ACPI_GET_DESCRIPTOR_TYPE (this_source_obj) != ACPI_DESC_TYPE_OPERAND) || + (ACPI_GET_OBJECT_TYPE (this_source_obj) != ACPI_TYPE_PACKAGE)) { status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj, state, context); if (ACPI_FAILURE (status)) { - /* TBD: must delete package created up to this point */ - return_ACPI_STATUS (status); } @@ -975,7 +1298,6 @@ acpi_ut_delete_generic_state (state); state = acpi_ut_pop_generic_state (&state_list); - /* Finished when there are no more states */ if (!state) { @@ -994,32 +1316,23 @@ state->pkg.index++; } } - else { - /* This is a sub-object of type package */ + /* This is a subobject of type package */ status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj, state, context); if (ACPI_FAILURE (status)) { - /* TBD: must delete package created up to this point */ - return_ACPI_STATUS (status); } - - /* - * The callback above returned a new target package object. - */ - /* * Push the current state and create a new one + * The callback above returned a new target package object. */ acpi_ut_push_generic_state (&state_list, state); state = acpi_ut_create_pkg_state (this_source_obj, state->pkg.this_target_obj, 0); if (!state) { - /* TBD: must delete package created up to this point */ - return_ACPI_STATUS (AE_NO_MEMORY); } } @@ -1027,17 +1340,100 @@ /* We should never get here */ - return (AE_AML_INTERNAL); + return_ACPI_STATUS (AE_AML_INTERNAL); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_generate_checksum + * + * PARAMETERS: Buffer - Buffer to be scanned + * Length - number of bytes to examine + * + * RETURN: checksum + * + * DESCRIPTION: Generate a checksum on a raw buffer + * + ******************************************************************************/ + +u8 +acpi_ut_generate_checksum ( + u8 *buffer, + u32 length) +{ + u32 i; + signed char sum = 0; + + + for (i = 0; i < length; i++) { + sum = (signed char) (sum + buffer[i]); + } + + return ((u8) (0 - sum)); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_end_tag + * + * PARAMETERS: obj_desc - The resource template buffer object + * + * RETURN: Pointer to the end tag + * + * DESCRIPTION: Find the END_TAG resource descriptor in a resource template + * + ******************************************************************************/ + + +u8 * +acpi_ut_get_resource_end_tag ( + union acpi_operand_object *obj_desc) +{ + u8 buffer_byte; + u8 *buffer; + u8 *end_buffer; + + + buffer = obj_desc->buffer.pointer; + end_buffer = buffer + obj_desc->buffer.length; + + while (buffer < end_buffer) { + buffer_byte = *buffer; + if (buffer_byte & ACPI_RDESC_TYPE_MASK) { + /* Large Descriptor - Length is next 2 bytes */ + + buffer += ((*(buffer+1) | (*(buffer+2) << 8)) + 3); + } + else { + /* Small Descriptor. End Tag will be found here */ + + if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) { + /* Found the end tag descriptor, all done. */ + + return (buffer); + } + + /* Length is in the header */ + + buffer += ((buffer_byte & 0x07) + 1); + } + } + + /* End tag not found */ + + return (NULL); } /******************************************************************************* * - * FUNCTION: Acpi_ut_report_error + * FUNCTION: acpi_ut_report_error * - * PARAMETERS: Module_name - Caller's module name (for error output) - * Line_number - Caller's line number (for error output) - * Component_id - Caller's component ID (for error output) + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * component_id - Caller's component ID (for error output) * Message - Error message to use on failure * * RETURN: None @@ -1048,9 +1444,9 @@ void acpi_ut_report_error ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id) + char *module_name, + u32 line_number, + u32 component_id) { @@ -1060,11 +1456,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_report_warning + * FUNCTION: acpi_ut_report_warning * - * PARAMETERS: Module_name - Caller's module name (for error output) - * Line_number - Caller's line number (for error output) - * Component_id - Caller's component ID (for error output) + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * component_id - Caller's component ID (for error output) * Message - Error message to use on failure * * RETURN: None @@ -1075,9 +1471,9 @@ void acpi_ut_report_warning ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id) + char *module_name, + u32 line_number, + u32 component_id) { acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number); @@ -1086,11 +1482,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_report_info + * FUNCTION: acpi_ut_report_info * - * PARAMETERS: Module_name - Caller's module name (for error output) - * Line_number - Caller's line number (for error output) - * Component_id - Caller's component ID (for error output) + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * component_id - Caller's component ID (for error output) * Message - Error message to use on failure * * RETURN: None @@ -1101,9 +1497,9 @@ void acpi_ut_report_info ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id) + char *module_name, + u32 line_number, + u32 component_id) { acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number); diff -urN linux-2.4.21/drivers/acpi/utilities/utobject.c linux-2.4.22/drivers/acpi/utilities/utobject.c --- linux-2.4.21/drivers/acpi/utilities/utobject.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utobject.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,48 +1,63 @@ /****************************************************************************** * * Module Name: utobject - ACPI object create/delete/size/cache routines - * $Revision: 57 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" -#include "amlcode.h" +#include +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utobject") + ACPI_MODULE_NAME ("utobject") /******************************************************************************* * - * FUNCTION: Acpi_ut_create_internal_object_dbg + * FUNCTION: acpi_ut_create_internal_object_dbg * - * PARAMETERS: Address - Address of the memory to deallocate - * Component - Component type of caller - * Module - Source file name of caller - * Line - Line number of caller + * PARAMETERS: module_name - Source file name of caller + * line_number - Line number of caller + * component_id - Component type of caller * Type - ACPI Type of the new object * * RETURN: Object - The new object. Null on failure @@ -57,31 +72,55 @@ * ******************************************************************************/ -acpi_operand_object * +union acpi_operand_object * acpi_ut_create_internal_object_dbg ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id, - acpi_object_type8 type) + char *module_name, + u32 line_number, + u32 component_id, + acpi_object_type type) { - acpi_operand_object *object; + union acpi_operand_object *object; + union acpi_operand_object *second_object; - FUNCTION_TRACE_STR ("Ut_create_internal_object_dbg", acpi_ut_get_type_name (type)); + ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg", acpi_ut_get_type_name (type)); /* Allocate the raw object descriptor */ object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id); if (!object) { - /* Allocation failure */ - return_PTR (NULL); } + switch (type) { + case ACPI_TYPE_REGION: + case ACPI_TYPE_BUFFER_FIELD: + + /* These types require a secondary object */ + + second_object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id); + if (!second_object) { + acpi_ut_delete_object_desc (object); + return_PTR (NULL); + } + + second_object->common.type = ACPI_TYPE_LOCAL_EXTRA; + second_object->common.reference_count = 1; + + /* Link the second object to the first */ + + object->common.next_object = second_object; + break; + + default: + /* All others have no secondary object */ + break; + } + /* Save the object type in the object descriptor */ - object->common.type = type; + object->common.type = (u8) type; /* Init the reference count */ @@ -95,68 +134,132 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_valid_internal_object + * FUNCTION: acpi_ut_create_buffer_object + * + * PARAMETERS: buffer_size - Size of buffer to be created + * + * RETURN: Pointer to a new Buffer object + * + * DESCRIPTION: Create a fully initialized buffer object + * + ******************************************************************************/ + +union acpi_operand_object * +acpi_ut_create_buffer_object ( + acpi_size buffer_size) +{ + union acpi_operand_object *buffer_desc; + u8 *buffer = NULL; + + + ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size); + + + /* + * Create a new Buffer object + */ + buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + if (!buffer_desc) { + return_PTR (NULL); + } + + /* Create an actual buffer only if size > 0 */ + + if (buffer_size > 0) { + /* Allocate the actual buffer */ + + buffer = ACPI_MEM_CALLOCATE (buffer_size); + if (!buffer) { + ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n", + (u32) buffer_size)); + acpi_ut_remove_reference (buffer_desc); + return_PTR (NULL); + } + } + + /* Complete buffer object initialization */ + + buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID; + buffer_desc->buffer.pointer = buffer; + buffer_desc->buffer.length = (u32) buffer_size; + + /* Return the new buffer descriptor */ + + return_PTR (buffer_desc); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_valid_internal_object * - * PARAMETERS: Operand - Object to be validated + * PARAMETERS: Object - Object to be validated * - * RETURN: Validate a pointer to be an acpi_operand_object + * RETURN: Validate a pointer to be an union acpi_operand_object * ******************************************************************************/ u8 acpi_ut_valid_internal_object ( - void *object) + void *object) { - PROC_NAME ("Ut_valid_internal_object"); + ACPI_FUNCTION_NAME ("ut_valid_internal_object"); /* Check for a null pointer */ if (!object) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "**** Null Object Ptr\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n")); return (FALSE); } /* Check the descriptor type field */ - if (!VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)) { - /* Not an ACPI internal object, do some further checking */ + switch (ACPI_GET_DESCRIPTOR_TYPE (object)) { + case ACPI_DESC_TYPE_OPERAND: - if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "**** Obj %p is a named obj, not ACPI obj\n", object)); - } + /* The object appears to be a valid union acpi_operand_object */ - else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_PARSER)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "**** Obj %p is a parser obj, not ACPI obj\n", object)); - } + return (TRUE); - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "**** Obj %p is of unknown type\n", object)); - } + case ACPI_DESC_TYPE_NAMED: - return (FALSE); - } + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "**** Obj %p is a named obj, not ACPI obj\n", object)); + break; + + case ACPI_DESC_TYPE_PARSER: + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "**** Obj %p is a parser obj, not ACPI obj\n", object)); + break; + case ACPI_DESC_TYPE_CACHED: - /* The object appears to be a valid acpi_operand_object */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "**** Obj %p has already been released to internal cache\n", object)); + break; + + default: - return (TRUE); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "**** Obj %p has unknown descriptor type %X\n", object, + ACPI_GET_DESCRIPTOR_TYPE (object))); + break; + } + + return (FALSE); } /******************************************************************************* * - * FUNCTION: Acpi_ut_allocate_object_desc_dbg + * FUNCTION: acpi_ut_allocate_object_desc_dbg * - * PARAMETERS: Module_name - Caller's module name (for error output) - * Line_number - Caller's line number (for error output) - * Component_id - Caller's component ID (for error output) - * Message - Error message to use on failure + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * component_id - Caller's component ID (for error output) * * RETURN: Pointer to newly allocated object descriptor. Null on error * @@ -167,31 +270,30 @@ void * acpi_ut_allocate_object_desc_dbg ( - NATIVE_CHAR *module_name, - u32 line_number, - u32 component_id) + char *module_name, + u32 line_number, + u32 component_id) { - acpi_operand_object *object; + union acpi_operand_object *object; - FUNCTION_TRACE ("Ut_allocate_object_desc_dbg"); + ACPI_FUNCTION_TRACE ("ut_allocate_object_desc_dbg"); object = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_OPERAND); if (!object) { - _REPORT_ERROR (module_name, line_number, component_id, + _ACPI_REPORT_ERROR (module_name, line_number, component_id, ("Could not allocate an object descriptor\n")); return_PTR (NULL); } - /* Mark the descriptor type */ - object->common.data_type = ACPI_DESC_TYPE_INTERNAL; + ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND); ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", - object, sizeof (acpi_operand_object))); + object, (u32) sizeof (union acpi_operand_object))); return_PTR (object); } @@ -199,9 +301,9 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_object_desc + * FUNCTION: acpi_ut_delete_object_desc * - * PARAMETERS: Object - Acpi internal object to be deleted + * PARAMETERS: Object - An Acpi internal object to be deleted * * RETURN: None. * @@ -211,14 +313,14 @@ void acpi_ut_delete_object_desc ( - acpi_operand_object *object) + union acpi_operand_object *object) { - FUNCTION_TRACE_PTR ("Ut_delete_object_desc", object); + ACPI_FUNCTION_TRACE_PTR ("ut_delete_object_desc", object); - /* Object must be an acpi_operand_object */ + /* Object must be an union acpi_operand_object */ - if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) { + if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Obj %p is not an ACPI object\n", object)); return_VOID; @@ -232,11 +334,11 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_delete_object_cache + * FUNCTION: acpi_ut_delete_object_cache * * PARAMETERS: None * - * RETURN: Status + * RETURN: None * * DESCRIPTION: Purge the global state object cache. Used during subsystem * termination. @@ -247,7 +349,7 @@ acpi_ut_delete_object_cache ( void) { - FUNCTION_TRACE ("Ut_delete_object_cache"); + ACPI_FUNCTION_TRACE ("ut_delete_object_cache"); acpi_ut_delete_generic_cache (ACPI_MEM_LIST_OPERAND); @@ -257,15 +359,15 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_get_simple_object_size + * FUNCTION: acpi_ut_get_simple_object_size * - * PARAMETERS: *Internal_object - Pointer to the object we are examining - * *Ret_length - Where the length is returned + * PARAMETERS: *internal_object - Pointer to the object we are examining + * *obj_length - Where the length is returned * * RETURN: Status * * DESCRIPTION: This function is called to determine the space required to - * contain a simple object for return to an API user. + * contain a simple object for return to an external user. * * The length includes the object structure plus any additional * needed space. @@ -274,14 +376,14 @@ acpi_status acpi_ut_get_simple_object_size ( - acpi_operand_object *internal_object, - u32 *obj_length) + union acpi_operand_object *internal_object, + acpi_size *obj_length) { - u32 length; - acpi_status status = AE_OK; + acpi_size length; + acpi_status status = AE_OK; - FUNCTION_TRACE_PTR ("Ut_get_simple_object_size", internal_object); + ACPI_FUNCTION_TRACE_PTR ("ut_get_simple_object_size", internal_object); /* Handle a null object (Could be a uninitialized package element -- which is legal) */ @@ -291,37 +393,33 @@ return_ACPI_STATUS (AE_OK); } - /* Start with the length of the Acpi object */ - length = sizeof (acpi_object); + length = sizeof (union acpi_object); - if (VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_NAMED)) { + if (ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_NAMED) { /* Object is a named object (reference), just return the length */ - *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length); + *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length); return_ACPI_STATUS (status); } - /* * The final length depends on the object type * Strings and Buffers are packed right up against the parent object and * must be accessed bytewise or there may be alignment problems on * certain processors */ - - switch (internal_object->common.type) { - + switch (ACPI_GET_OBJECT_TYPE (internal_object)) { case ACPI_TYPE_STRING: - length += internal_object->string.length + 1; + length += (acpi_size) internal_object->string.length + 1; break; case ACPI_TYPE_BUFFER: - length += internal_object->buffer.length; + length += (acpi_size) internal_object->buffer.length; break; @@ -335,25 +433,30 @@ break; - case INTERNAL_TYPE_REFERENCE: + case ACPI_TYPE_LOCAL_REFERENCE: - /* - * The only type that should be here is internal opcode NAMEPATH_OP -- since - * this means an object reference - */ - if (internal_object->reference.opcode != AML_INT_NAMEPATH_OP) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unsupported Reference opcode=%X in object %p\n", - internal_object->reference.opcode, internal_object)); - status = AE_TYPE; - } + switch (internal_object->reference.opcode) { + case AML_INT_NAMEPATH_OP: - else { /* * Get the actual length of the full pathname to this object. * The reference will be converted to the pathname to the object */ - length += ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node)); + length += ACPI_ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node)); + break; + + default: + + /* + * No other reference opcodes are supported. + * Notably, Locals and Args are not supported, but this may be + * required eventually. + */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unsupported Reference opcode=%X in object %p\n", + internal_object->reference.opcode, internal_object)); + status = AE_TYPE; + break; } break; @@ -361,31 +464,29 @@ default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n", - internal_object->common.type, internal_object)); + ACPI_GET_OBJECT_TYPE (internal_object), internal_object)); status = AE_TYPE; break; } - /* * Account for the space required by the object rounded up to the next * multiple of the machine word size. This keeps each object aligned * on a machine word boundary. (preventing alignment faults on some * machines.) */ - *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length); - + *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length); return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_get_element_length + * FUNCTION: acpi_ut_get_element_length * - * PARAMETERS: ACPI_PKG_CALLBACK + * PARAMETERS: acpi_pkg_callback * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: Get the length of one package element. * @@ -393,18 +494,18 @@ acpi_status acpi_ut_get_element_length ( - u8 object_type, - acpi_operand_object *source_object, - acpi_generic_state *state, - void *context) + u8 object_type, + union acpi_operand_object *source_object, + union acpi_generic_state *state, + void *context) { - acpi_status status = AE_OK; - acpi_pkg_info *info = (acpi_pkg_info *) context; - u32 object_space; + acpi_status status = AE_OK; + struct acpi_pkg_info *info = (struct acpi_pkg_info *) context; + acpi_size object_space; switch (object_type) { - case 0: + case ACPI_COPY_TYPE_SIMPLE: /* * Simple object - just get the size (Null object/entry is handled @@ -419,33 +520,37 @@ break; - case 1: - /* Package - nothing much to do here, let the walk handle it */ + case ACPI_COPY_TYPE_PACKAGE: + + /* Package object - nothing much to do here, let the walk handle it */ info->num_packages++; state->pkg.this_target_obj = NULL; break; + default: + + /* No other types allowed */ + return (AE_BAD_PARAMETER); } - return (status); } /******************************************************************************* * - * FUNCTION: Acpi_ut_get_package_object_size + * FUNCTION: acpi_ut_get_package_object_size * - * PARAMETERS: *Internal_object - Pointer to the object we are examining - * *Ret_length - Where the length is returned + * PARAMETERS: *internal_object - Pointer to the object we are examining + * *obj_length - Where the length is returned * * RETURN: Status * * DESCRIPTION: This function is called to determine the space required to - * contain a package object for return to an API user. + * contain a package object for return to an external user. * * This is moderately complex since a package contains other * objects including packages. @@ -454,14 +559,14 @@ acpi_status acpi_ut_get_package_object_size ( - acpi_operand_object *internal_object, - u32 *obj_length) + union acpi_operand_object *internal_object, + acpi_size *obj_length) { - acpi_status status; - acpi_pkg_info info; + acpi_status status; + struct acpi_pkg_info info; - FUNCTION_TRACE_PTR ("Ut_get_package_object_size", internal_object); + ACPI_FUNCTION_TRACE_PTR ("ut_get_package_object_size", internal_object); info.length = 0; @@ -470,14 +575,17 @@ status = acpi_ut_walk_package_tree (internal_object, NULL, acpi_ut_get_element_length, &info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } /* * We have handled all of the objects in all levels of the package. * just add the length of the package objects themselves. * Round up to the next machine word. */ - info.length += ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object)) * - info.num_packages; + info.length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)) * + (acpi_size) info.num_packages; /* Return the total package length */ @@ -488,10 +596,10 @@ /******************************************************************************* * - * FUNCTION: Acpi_ut_get_object_size + * FUNCTION: acpi_ut_get_object_size * - * PARAMETERS: *Internal_object - Pointer to the object we are examining - * *Ret_length - Where the length will be returned + * PARAMETERS: *internal_object - Pointer to the object we are examining + * *obj_length - Where the length will be returned * * RETURN: Status * @@ -502,20 +610,19 @@ acpi_status acpi_ut_get_object_size( - acpi_operand_object *internal_object, - u32 *obj_length) + union acpi_operand_object *internal_object, + acpi_size *obj_length) { - acpi_status status; + acpi_status status; - FUNCTION_ENTRY (); + ACPI_FUNCTION_ENTRY (); - if ((VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_INTERNAL)) && - (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE))) { + if ((ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_OPERAND) && + (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE)) { status = acpi_ut_get_package_object_size (internal_object, obj_length); } - else { status = acpi_ut_get_simple_object_size (internal_object, obj_length); } diff -urN linux-2.4.21/drivers/acpi/utilities/utxface.c linux-2.4.22/drivers/acpi/utilities/utxface.c --- linux-2.4.21/drivers/acpi/utilities/utxface.c 2001-10-24 14:06:22.000000000 -0700 +++ linux-2.4.22/drivers/acpi/utilities/utxface.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,46 +1,61 @@ /****************************************************************************** * * Module Name: utxface - External interfaces for "global" ACPI functions - * $Revision: 82 $ * *****************************************************************************/ /* - * Copyright (C) 2000, 2001 R. Byron Moore + * Copyright (C) 2000 - 2003, R. Byron Moore + * 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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" -#include "acevents.h" -#include "achware.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acdebug.h" -#include "acexcep.h" - +#include +#include +#include +#include +#include +#include #define _COMPONENT ACPI_UTILITIES - MODULE_NAME ("utxface") + ACPI_MODULE_NAME ("utxface") /******************************************************************************* * - * FUNCTION: Acpi_initialize_subsystem + * FUNCTION: acpi_initialize_subsystem * * PARAMETERS: None * @@ -55,12 +70,12 @@ acpi_initialize_subsystem ( void) { - acpi_status status; + acpi_status status; - FUNCTION_TRACE ("Acpi_initialize_subsystem"); + ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem"); - DEBUG_EXEC(acpi_ut_init_stack_ptr_trace ()); + ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ()); /* Initialize all globals used by the subsystem */ @@ -71,7 +86,7 @@ status = acpi_os_initialize (); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("OSD failed to initialize, %s\n", + ACPI_REPORT_ERROR (("OSD failed to initialize, %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); } @@ -80,7 +95,7 @@ status = acpi_ut_mutex_initialize (); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("Global mutex creation failure, %s\n", + ACPI_REPORT_ERROR (("Global mutex creation failure, %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); } @@ -92,7 +107,7 @@ status = acpi_ns_root_initialize (); if (ACPI_FAILURE (status)) { - REPORT_ERROR (("Namespace initialization failure, %s\n", + ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); } @@ -100,7 +115,7 @@ /* If configured, initialize the AML debugger */ - DEBUGGER_EXEC (acpi_db_initialize ()); + ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ()); return_ACPI_STATUS (status); } @@ -108,7 +123,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_enable_subsystem + * FUNCTION: acpi_enable_subsystem * * PARAMETERS: Flags - Init/enable Options * @@ -121,37 +136,17 @@ acpi_status acpi_enable_subsystem ( - u32 flags) + u32 flags) { - acpi_status status = AE_OK; - - - FUNCTION_TRACE ("Acpi_enable_subsystem"); - + acpi_status status = AE_OK; - /* Sanity check the FADT for valid values */ - status = acpi_ut_validate_fadt (); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + ACPI_FUNCTION_TRACE ("acpi_enable_subsystem"); - /* - * Install the default Op_region handlers. These are - * installed unless other handlers have already been - * installed via the Install_address_space_handler interface - */ - if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n")); - - status = acpi_ev_install_default_address_space_handlers (); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - } /* * We must initialize the hardware before we can enable ACPI. + * The values from the FADT are validated here. */ if (!(flags & ACPI_NO_HARDWARE_INIT)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n")); @@ -163,21 +158,24 @@ } /* - * Enable ACPI on this platform + * Enable ACPI mode */ if (!(flags & ACPI_NO_ACPI_ENABLE)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n")); + acpi_gbl_original_mode = acpi_hw_get_mode(); + status = acpi_enable (); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Acpi_enable failed.\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_enable failed.\n")); return_ACPI_STATUS (status); } } /* - * Note: - * We must have the hardware AND events initialized before we can execute + * Initialize ACPI Event handling + * + * NOTE: We must have the hardware AND events initialized before we can execute * ANY control methods SAFELY. Any control method can require ACPI hardware * support, so the hardware MUST be initialized before execution! */ @@ -190,25 +188,65 @@ } } + /* Install the SCI handler, Global Lock handler, and GPE handlers */ + + if (!(flags & ACPI_NO_HANDLER_INIT)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n")); + + status = acpi_ev_handler_initialize (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + return_ACPI_STATUS (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_initialize_objects + * + * PARAMETERS: Flags - Init/enable Options + * + * RETURN: Status + * + * DESCRIPTION: Completes namespace initialization by initializing device + * objects and executing AML code for Regions, buffers, etc. + * + ******************************************************************************/ + +acpi_status +acpi_initialize_objects ( + u32 flags) +{ + acpi_status status = AE_OK; + + + ACPI_FUNCTION_TRACE ("acpi_initialize_objects"); + /* - * Initialize all device objects in the namespace - * This runs the _STA and _INI methods. + * Install the default op_region handlers. These are installed unless + * other handlers have already been installed via the + * install_address_space_handler interface. + * + * NOTE: This will cause _REG methods to be run. Any objects accessed + * by the _REG methods will be automatically initialized, even if they + * contain executable AML (see call to acpi_ns_initialize_objects below). */ - if (!(flags & ACPI_NO_DEVICE_INIT)) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n")); + if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n")); - status = acpi_ns_initialize_devices (); + status = acpi_ev_init_address_spaces (); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } - /* * Initialize the objects that remain uninitialized. This - * runs the executable AML that is part of the declaration of Op_regions - * and Fields. + * runs the executable AML that may be part of the declaration of these + * objects: operation_regions, buffer_fields, Buffers, and Packages. */ if (!(flags & ACPI_NO_OBJECT_INIT)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n")); @@ -219,15 +257,34 @@ } } - acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK; + /* + * Initialize all device objects in the namespace + * This runs the _STA and _INI methods. + */ + if (!(flags & ACPI_NO_DEVICE_INIT)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n")); + status = acpi_ns_initialize_devices (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + /* + * Empty the caches (delete the cached objects) on the assumption that + * the table load filled them up more than they will be at runtime -- + * thus wasting non-paged memory. + */ + status = acpi_purge_cached_objects (); + + acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK; return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: Acpi_terminate + * FUNCTION: acpi_terminate * * PARAMETERS: None * @@ -240,16 +297,15 @@ acpi_status acpi_terminate (void) { - FUNCTION_TRACE ("Acpi_terminate"); + acpi_status status; - /* Terminate the AML Debugger if present */ + ACPI_FUNCTION_TRACE ("acpi_terminate"); - DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); - /* TBD: [Investigate] This is no longer needed?*/ -/* Acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */ + /* Terminate the AML Debugger if present */ + ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); /* Shutdown and free all resources */ @@ -261,7 +317,7 @@ acpi_ut_mutex_terminate (); -#ifdef ENABLE_DEBUGGER +#ifdef ACPI_DEBUGGER /* Shut down the debugger */ @@ -270,16 +326,14 @@ /* Now we can shutdown the OS-dependent layer */ - acpi_os_terminate (); - - - return_ACPI_STATUS (AE_OK); + status = acpi_os_terminate (); + return_ACPI_STATUS (status); } /***************************************************************************** * - * FUNCTION: Acpi_subsystem_status + * FUNCTION: acpi_subsystem_status * * PARAMETERS: None * @@ -305,65 +359,62 @@ /****************************************************************************** * - * FUNCTION: Acpi_get_system_info + * FUNCTION: acpi_get_system_info * - * PARAMETERS: Out_buffer - a pointer to a buffer to receive the + * PARAMETERS: out_buffer - a pointer to a buffer to receive the * resources for the device - * Buffer_length - the number of bytes available in the buffer + * buffer_length - the number of bytes available in the buffer * * RETURN: Status - the status of the call * * DESCRIPTION: This function is called to get information about the current * state of the ACPI subsystem. It will return system information - * in the Out_buffer. + * in the out_buffer. * * If the function fails an appropriate status will be returned - * and the value of Out_buffer is undefined. + * and the value of out_buffer is undefined. * ******************************************************************************/ acpi_status acpi_get_system_info ( - acpi_buffer *out_buffer) + struct acpi_buffer *out_buffer) { - acpi_system_info *info_ptr; - u32 i; + struct acpi_system_info *info_ptr; + u32 i; + acpi_status status; - FUNCTION_TRACE ("Acpi_get_system_info"); + ACPI_FUNCTION_TRACE ("acpi_get_system_info"); - /* - * Must have a valid buffer - */ - if ((!out_buffer) || - (!out_buffer->pointer)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + /* Parameter validation */ + + status = acpi_ut_validate_buffer (out_buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - if (out_buffer->length < sizeof (acpi_system_info)) { - /* - * Caller's buffer is too small - */ - out_buffer->length = sizeof (acpi_system_info); + /* Validate/Allocate/Clear caller buffer */ - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); + status = acpi_ut_initialize_buffer (out_buffer, sizeof (struct acpi_system_info)); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - /* - * Set return length and get data + * Populate the return buffer */ - out_buffer->length = sizeof (acpi_system_info); - info_ptr = (acpi_system_info *) out_buffer->pointer; + info_ptr = (struct acpi_system_info *) out_buffer->pointer; info_ptr->acpi_ca_version = ACPI_CA_VERSION; /* System flags (ACPI capabilities) */ - info_ptr->flags = acpi_gbl_system_flags; + info_ptr->flags = ACPI_SYS_MODE_ACPI; /* Timer resolution - 24 or 32 bits */ + if (!acpi_gbl_FADT) { info_ptr->timer_resolution = 0; } @@ -386,12 +437,70 @@ /* Current status of the ACPI tables, per table type */ - info_ptr->num_table_types = NUM_ACPI_TABLES; - for (i = 0; i < NUM_ACPI_TABLES; i++) { - info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count; + info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES; + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { + info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; } return_ACPI_STATUS (AE_OK); } +/***************************************************************************** + * + * FUNCTION: acpi_install_initialization_handler + * + * PARAMETERS: Handler - Callback procedure + * + * RETURN: Status + * + * DESCRIPTION: Install an initialization handler + * + * TBD: When a second function is added, must save the Function also. + * + ****************************************************************************/ + +acpi_status +acpi_install_initialization_handler ( + acpi_init_handler handler, + u32 function) +{ + + if (!handler) { + return (AE_BAD_PARAMETER); + } + + if (acpi_gbl_init_handler) { + return (AE_ALREADY_EXISTS); + } + + acpi_gbl_init_handler = handler; + return AE_OK; +} + + +/***************************************************************************** + * + * FUNCTION: acpi_purge_cached_objects + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Empty all caches (delete the cached objects) + * + ****************************************************************************/ + +acpi_status +acpi_purge_cached_objects (void) +{ + ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects"); + + + acpi_ut_delete_generic_state_cache (); + acpi_ut_delete_object_cache (); + acpi_ds_delete_walk_state_cache (); + acpi_ps_delete_parse_cache (); + + return_ACPI_STATUS (AE_OK); +} diff -urN linux-2.4.21/drivers/acpi/utils.c linux-2.4.22/drivers/acpi/utils.c --- linux-2.4.21/drivers/acpi/utils.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/acpi/utils.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,413 @@ +/* + * acpi_utils.c - ACPI Utility Functions ($Revision: 8 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 + + +#define _COMPONENT ACPI_BUS_COMPONENT +ACPI_MODULE_NAME ("acpi_utils") + + +/* -------------------------------------------------------------------------- + Object Evaluation Helpers + -------------------------------------------------------------------------- */ + +#ifdef ACPI_DEBUG_OUTPUT +#define acpi_util_eval_error(h,p,s) {\ + char prefix[80] = {'\0'};\ + struct acpi_buffer buffer = {sizeof(prefix), prefix};\ + acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\ + (char *) prefix, p, acpi_format_exception(s))); } +#else +#define acpi_util_eval_error(h,p,s) +#endif + + +acpi_status +acpi_extract_package ( + union acpi_object *package, + struct acpi_buffer *format, + struct acpi_buffer *buffer) +{ + u32 size_required = 0; + u32 tail_offset = 0; + char *format_string = NULL; + u32 format_count = 0; + u32 i = 0; + u8 *head = NULL; + u8 *tail = NULL; + + ACPI_FUNCTION_TRACE("acpi_extract_package"); + + if (!package || (package->type != ACPI_TYPE_PACKAGE) || (package->package.count < 1)) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'package' argument\n")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + if (!format || !format->pointer || (format->length < 1)) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'format' argument\n")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + if (!buffer) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'buffer' argument\n")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + format_count = (format->length/sizeof(char)) - 1; + if (format_count > package->package.count) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count)); + return_ACPI_STATUS(AE_BAD_DATA); + } + + format_string = (char*)format->pointer; + + /* + * Calculate size_required. + */ + for (i=0; ipackage.elements[i]); + + if (!element) { + return_ACPI_STATUS(AE_BAD_DATA); + } + + switch (element->type) { + + case ACPI_TYPE_INTEGER: + switch (format_string[i]) { + case 'N': + size_required += sizeof(acpi_integer); + tail_offset += sizeof(acpi_integer); + break; + case 'S': + size_required += sizeof(char*) + sizeof(acpi_integer) + sizeof(char); + tail_offset += sizeof(char*); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d]: got number, expecing [%c].\n", i, format_string[i])); + return_ACPI_STATUS(AE_BAD_DATA); + break; + } + break; + + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + switch (format_string[i]) { + case 'S': + size_required += sizeof(char*) + (element->string.length * sizeof(char)) + sizeof(char); + tail_offset += sizeof(char*); + break; + case 'B': + size_required += sizeof(u8*) + (element->buffer.length * sizeof(u8)); + tail_offset += sizeof(u8*); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d] got string/buffer, expecing [%c].\n", i, format_string[i])); + return_ACPI_STATUS(AE_BAD_DATA); + break; + } + break; + + case ACPI_TYPE_PACKAGE: + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%d\n", i)); + /* TBD: handle nested packages... */ + return_ACPI_STATUS(AE_SUPPORT); + break; + } + } + + /* + * Validate output buffer. + */ + if (buffer->length < size_required) { + buffer->length = size_required; + return_ACPI_STATUS(AE_BUFFER_OVERFLOW); + } + else if (buffer->length != size_required || !buffer->pointer) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + head = buffer->pointer; + tail = buffer->pointer + tail_offset; + + /* + * Extract package data. + */ + for (i=0; ipackage.elements[i]); + + if (!element) { + return_ACPI_STATUS(AE_BAD_DATA); + } + + switch (element->type) { + + case ACPI_TYPE_INTEGER: + switch (format_string[i]) { + case 'N': + *((acpi_integer*)head) = element->integer.value; + head += sizeof(acpi_integer); + break; + case 'S': + pointer = (u8**)head; + *pointer = tail; + *((acpi_integer*)tail) = element->integer.value; + head += sizeof(acpi_integer*); + tail += sizeof(acpi_integer); + /* NULL terminate string */ + *tail = (char)0; + tail += sizeof(char); + break; + default: + /* Should never get here */ + break; + } + break; + + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + switch (format_string[i]) { + case 'S': + pointer = (u8**)head; + *pointer = tail; + memcpy(tail, element->string.pointer, element->string.length); + head += sizeof(char*); + tail += element->string.length * sizeof(char); + /* NULL terminate string */ + *tail = (char)0; + tail += sizeof(char); + break; + case 'B': + pointer = (u8**)head; + *pointer = tail; + memcpy(tail, element->buffer.pointer, element->buffer.length); + head += sizeof(u8*); + tail += element->buffer.length * sizeof(u8); + break; + default: + /* Should never get here */ + break; + } + break; + + case ACPI_TYPE_PACKAGE: + /* TBD: handle nested packages... */ + default: + /* Should never get here */ + break; + } + } + + return_ACPI_STATUS(AE_OK); +} + + +acpi_status +acpi_evaluate_integer ( + acpi_handle handle, + acpi_string pathname, + struct acpi_object_list *arguments, + unsigned long *data) +{ + acpi_status status = AE_OK; + union acpi_object element; + struct acpi_buffer buffer = {sizeof(union acpi_object), &element}; + + ACPI_FUNCTION_TRACE("acpi_evaluate_integer"); + + if (!data) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + status = acpi_evaluate_object(handle, pathname, arguments, &buffer); + if (ACPI_FAILURE(status)) { + acpi_util_eval_error(handle, pathname, status); + return_ACPI_STATUS(status); + } + + if (element.type != ACPI_TYPE_INTEGER) { + acpi_util_eval_error(handle, pathname, AE_BAD_DATA); + return_ACPI_STATUS(AE_BAD_DATA); + } + + *data = element.integer.value; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data)); + + return_ACPI_STATUS(AE_OK); +} + + +#if 0 +acpi_status +acpi_evaluate_string ( + acpi_handle handle, + acpi_string pathname, + acpi_object_list *arguments, + acpi_string *data) +{ + acpi_status status = AE_OK; + acpi_object *element = NULL; + acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + + ACPI_FUNCTION_TRACE("acpi_evaluate_string"); + + if (!data) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + status = acpi_evaluate_object(handle, pathname, arguments, &buffer); + if (ACPI_FAILURE(status)) { + acpi_util_eval_error(handle, pathname, status); + return_ACPI_STATUS(status); + } + + element = (acpi_object *) buffer.pointer; + + if ((element->type != ACPI_TYPE_STRING) + || (element->type != ACPI_TYPE_BUFFER) + || !element->string.length) { + acpi_util_eval_error(handle, pathname, AE_BAD_DATA); + return_ACPI_STATUS(AE_BAD_DATA); + } + + *data = kmalloc(element->string.length + 1, GFP_KERNEL); + if (!data) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n")); + return_VALUE(-ENOMEM); + } + memset(*data, 0, element->string.length + 1); + + memcpy(*data, element->string.pointer, element->string.length); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data)); + + acpi_os_free(buffer.pointer); + + return_ACPI_STATUS(AE_OK); +} +#endif + + +acpi_status +acpi_evaluate_reference ( + acpi_handle handle, + acpi_string pathname, + struct acpi_object_list *arguments, + struct acpi_handle_list *list) +{ + acpi_status status = AE_OK; + union acpi_object *package = NULL; + union acpi_object *element = NULL; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + u32 i = 0; + + ACPI_FUNCTION_TRACE("acpi_evaluate_reference"); + + if (!list) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Evaluate object. */ + + status = acpi_evaluate_object(handle, pathname, arguments, &buffer); + if (ACPI_FAILURE(status)) + goto end; + + package = (union acpi_object *) buffer.pointer; + + if ((buffer.length == 0) || !package) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "No return object (len %X ptr %p)\n", + buffer.length, package)); + status = AE_BAD_DATA; + acpi_util_eval_error(handle, pathname, status); + goto end; + } + if (package->type != ACPI_TYPE_PACKAGE) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Expecting a [Package], found type %X\n", + package->type)); + status = AE_BAD_DATA; + acpi_util_eval_error(handle, pathname, status); + goto end; + } + if (!package->package.count) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "[Package] has zero elements (%p)\n", + package)); + status = AE_BAD_DATA; + acpi_util_eval_error(handle, pathname, status); + goto end; + } + + if (package->package.count > ACPI_MAX_HANDLES) { + return AE_NO_MEMORY; + } + list->count = package->package.count; + + /* Extract package data. */ + + for (i = 0; i < list->count; i++) { + + element = &(package->package.elements[i]); + + if (element->type != ACPI_TYPE_ANY) { + status = AE_BAD_DATA; + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Expecting a [Reference] package element, found type %X\n", + element->type)); + acpi_util_eval_error(handle, pathname, status); + break; + } + + /* Get the acpi_handle. */ + + list->handles[i] = element->reference.handle; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n", + list->handles[i])); + } + +end: + if (ACPI_FAILURE(status)) { + list->count = 0; + //kfree(list->handles); + } + + acpi_os_free(buffer.pointer); + + return_ACPI_STATUS(status); +} + + diff -urN linux-2.4.21/drivers/atm/Config.in linux-2.4.22/drivers/atm/Config.in --- linux-2.4.21/drivers/atm/Config.in 2001-11-13 09:19:41.000000000 -0800 +++ linux-2.4.22/drivers/atm/Config.in 2003-08-25 04:44:41.000000000 -0700 @@ -4,11 +4,11 @@ mainmenu_option next_comment comment 'ATM drivers' if [ "$CONFIG_INET" = "y" ]; then - tristate 'ATM over TCP' CONFIG_ATM_TCP + dep_tristate 'ATM over TCP' CONFIG_ATM_TCP $CONFIG_ATM fi if [ "$CONFIG_PCI" = "y" ]; then - tristate 'Efficient Networks Speedstream 3010' CONFIG_ATM_LANAI - tristate 'Efficient Networks ENI155P' CONFIG_ATM_ENI + dep_tristate 'Efficient Networks Speedstream 3010' CONFIG_ATM_LANAI $CONFIG_ATM + dep_tristate 'Efficient Networks ENI155P' CONFIG_ATM_ENI $CONFIG_ATM if [ "$CONFIG_ATM_ENI" != "n" ]; then bool ' Enable extended debugging' CONFIG_ATM_ENI_DEBUG bool ' Fine-tune burst settings' CONFIG_ATM_ENI_TUNE_BURST @@ -23,8 +23,8 @@ bool ' Enable 2W RX bursts (optional)' CONFIG_ATM_ENI_BURST_RX_2W fi fi - tristate 'Fujitsu FireStream (FS50/FS155) ' CONFIG_ATM_FIRESTREAM - tristate 'ZeitNet ZN1221/ZN1225' CONFIG_ATM_ZATM + dep_tristate 'Fujitsu FireStream (FS50/FS155) ' CONFIG_ATM_FIRESTREAM $CONFIG_ATM + dep_tristate 'ZeitNet ZN1221/ZN1225' CONFIG_ATM_ZATM $CONFIG_ATM if [ "$CONFIG_ATM_ZATM" != "n" ]; then bool ' Enable extended debugging' CONFIG_ATM_ZATM_DEBUG if [ "$CONFIG_X86" = "y" ]; then @@ -35,32 +35,32 @@ # if [ "$CONFIG_ATM_TNETA1570" = "y" ]; then # bool ' Enable extended debugging' CONFIG_ATM_TNETA1570_DEBUG n # fi - tristate 'IDT 77201 (NICStAR) (ForeRunnerLE)' CONFIG_ATM_NICSTAR + dep_tristate 'IDT 77201 (NICStAR) (ForeRunnerLE)' CONFIG_ATM_NICSTAR $CONFIG_ATM if [ "$CONFIG_ATM_NICSTAR" != "n" ]; then bool ' Use suni PHY driver (155Mbps)' CONFIG_ATM_NICSTAR_USE_SUNI bool ' Use IDT77015 PHY driver (25Mbps)' CONFIG_ATM_NICSTAR_USE_IDT77105 fi - tristate 'IDT 77252 (NICStAR II)' CONFIG_ATM_IDT77252 + dep_tristate 'IDT 77252 (NICStAR II)' CONFIG_ATM_IDT77252 $CONFIG_ATM if [ "$CONFIG_ATM_IDT77252" != "n" ]; then bool ' Enable debugging messages' CONFIG_ATM_IDT77252_DEBUG bool ' Receive ALL cells in raw queue' CONFIG_ATM_IDT77252_RCV_ALL define_bool CONFIG_ATM_IDT77252_USE_SUNI y fi - tristate 'Madge Ambassador (Collage PCI 155 Server)' CONFIG_ATM_AMBASSADOR + dep_tristate 'Madge Ambassador (Collage PCI 155 Server)' CONFIG_ATM_AMBASSADOR $CONFIG_ATM if [ "$CONFIG_ATM_AMBASSADOR" != "n" ]; then bool ' Enable debugging messages' CONFIG_ATM_AMBASSADOR_DEBUG fi - tristate 'Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)' CONFIG_ATM_HORIZON + dep_tristate 'Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)' CONFIG_ATM_HORIZON $CONFIG_ATM if [ "$CONFIG_ATM_HORIZON" != "n" ]; then bool ' Enable debugging messages' CONFIG_ATM_HORIZON_DEBUG fi - tristate 'Interphase ATM PCI x575/x525/x531' CONFIG_ATM_IA - if [ "$CONFIG_ATM_IA" != "n" ]; then - bool ' Enable debugging messages' CONFIG_ATM_IA_DEBUG - fi + dep_tristate 'Interphase ATM PCI x575/x525/x531' CONFIG_ATM_IA $CONFIG_ATM + if [ "$CONFIG_ATM_IA" != "n" ]; then + bool ' Enable debugging messages' CONFIG_ATM_IA_DEBUG + fi fi if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then - tristate 'FORE Systems 200E-series' CONFIG_ATM_FORE200E_MAYBE + dep_tristate 'FORE Systems 200E-series' CONFIG_ATM_FORE200E_MAYBE $CONFIG_ATM if [ "$CONFIG_ATM_FORE200E_MAYBE" != "n" ]; then if [ "$CONFIG_PCI" = "y" ]; then bool ' PCA-200E support' CONFIG_ATM_FORE200E_PCA @@ -92,4 +92,10 @@ fi fi fi +if [ "$CONFIG_PCI" = "y" ]; then + dep_tristate 'ForeRunner HE Series' CONFIG_ATM_HE $CONFIG_ATM + if [ "$CONFIG_ATM_HE" != "n" ]; then + bool 'Use S/UNI PHY driver' CONFIG_ATM_HE_USE_SUNI + fi +fi endmenu diff -urN linux-2.4.21/drivers/atm/Makefile linux-2.4.22/drivers/atm/Makefile --- linux-2.4.21/drivers/atm/Makefile 2001-11-07 14:39:36.000000000 -0800 +++ linux-2.4.22/drivers/atm/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -52,9 +52,13 @@ CONFIG_ATM_FORE200E_SBA_FW := sba200e_ecd.bin2 endif endif - obj-$(CONFIG_ATM_FORE200E) += fore_200e.o +obj-$(CONFIG_ATM_HE) += he.o +ifeq ($(CONFIG_ATM_HE_USE_SUNI),y) + obj-$(CONFIG_ATM_HE) += suni.o +endif + EXTRA_CFLAGS=-g list-multi := fore_200e.o diff -urN linux-2.4.21/drivers/atm/ambassador.c linux-2.4.22/drivers/atm/ambassador.c --- linux-2.4.21/drivers/atm/ambassador.c 2001-09-13 15:21:32.000000000 -0700 +++ linux-2.4.22/drivers/atm/ambassador.c 2003-08-25 04:44:41.000000000 -0700 @@ -290,12 +290,11 @@ /********** microcode **********/ #ifdef AMB_NEW_MICROCODE -#define UCODE(x) UCODE1(atmsar12.,x) +#define UCODE(x) UCODE2(atmsar12.x) #else -#define UCODE(x) UCODE1(atmsar11.,x) +#define UCODE(x) UCODE2(atmsar11.x) #endif #define UCODE2(x) #x -#define UCODE1(x,y) UCODE2(x ## y) static u32 __initdata ucode_start = #include UCODE(start) diff -urN linux-2.4.21/drivers/atm/atmtcp.c linux-2.4.22/drivers/atm/atmtcp.c --- linux-2.4.21/drivers/atm/atmtcp.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/atm/atmtcp.c 2003-08-25 04:44:41.000000000 -0700 @@ -153,6 +153,7 @@ static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) { + unsigned long flags; struct atm_cirange ci; struct atm_vcc *vcc; @@ -162,9 +163,14 @@ if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS; if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 || ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL; + spin_lock_irqsave(&dev->lock, flags); for (vcc = dev->vccs; vcc; vcc = vcc->next) if ((vcc->vpi >> ci.vpi_bits) || - (vcc->vci >> ci.vci_bits)) return -EBUSY; + (vcc->vci >> ci.vci_bits)) { + spin_unlock_irqrestore(&dev->lock, flags); + return -EBUSY; + } + spin_unlock_irqrestore(&dev->lock, flags); dev->ci_range = ci; return 0; } @@ -227,6 +233,7 @@ static void atmtcp_c_close(struct atm_vcc *vcc) { + unsigned long flags; struct atm_dev *atmtcp_dev; struct atmtcp_dev_data *dev_data; struct atm_vcc *walk; @@ -239,13 +246,16 @@ kfree(dev_data); shutdown_atm_dev(atmtcp_dev); vcc->dev_data = NULL; + spin_lock_irqsave(&atmtcp_dev->lock, flags); for (walk = atmtcp_dev->vccs; walk; walk = walk->next) wake_up(&walk->sleep); + spin_unlock_irqrestore(&atmtcp_dev->lock, flags); } static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb) { + unsigned long flags; struct atm_dev *dev; struct atmtcp_hdr *hdr; struct atm_vcc *out_vcc; @@ -260,11 +270,13 @@ (struct atmtcp_control *) skb->data); goto done; } + spin_lock_irqsave(&dev->lock, flags); for (out_vcc = dev->vccs; out_vcc; out_vcc = out_vcc->next) if (out_vcc->vpi == ntohs(hdr->vpi) && out_vcc->vci == ntohs(hdr->vci) && out_vcc->qos.rxtp.traffic_class != ATM_NONE) break; + spin_unlock_irqrestore(&dev->lock, flags); if (!out_vcc) { atomic_inc(&vcc->stats->tx_err); goto done; @@ -293,13 +305,13 @@ static struct atmdev_ops atmtcp_v_dev_ops = { - dev_close: atmtcp_v_dev_close, - open: atmtcp_v_open, - close: atmtcp_v_close, - ioctl: atmtcp_v_ioctl, - send: atmtcp_v_send, - proc_read: atmtcp_v_proc, - owner: THIS_MODULE + .dev_close = atmtcp_v_dev_close, + .open = atmtcp_v_open, + .close = atmtcp_v_close, + .ioctl = atmtcp_v_ioctl, + .send = atmtcp_v_send, + .proc_read = atmtcp_v_proc, + .owner = THIS_MODULE }; @@ -309,21 +321,16 @@ static struct atmdev_ops atmtcp_c_dev_ops = { - close: atmtcp_c_close, - send: atmtcp_c_send + .close = atmtcp_c_close, + .send = atmtcp_c_send }; static struct atm_dev atmtcp_control_dev = { - &atmtcp_c_dev_ops, - NULL, /* no PHY */ - "atmtcp", /* type */ - 999, /* dummy device number */ - NULL,NULL, /* pretend not to have any VCCs */ - NULL,NULL, /* no data */ - { 0 }, /* no flags */ - NULL, /* no local address */ - { 0 } /* no ESI, no statistics */ + .ops = &atmtcp_c_dev_ops, + .type = "atmtcp", + .number = 999, + .lock = SPIN_LOCK_UNLOCKED }; @@ -356,9 +363,12 @@ struct atm_dev *dev; dev = NULL; - if (itf != -1) dev = atm_find_dev(itf); + if (itf != -1) dev = atm_dev_lookup(itf); if (dev) { - if (dev->ops != &atmtcp_v_dev_ops) return -EMEDIUMTYPE; + if (dev->ops != &atmtcp_v_dev_ops) { + atm_dev_release(dev); + return -EMEDIUMTYPE; + } if (PRIV(dev)->vcc) return -EBUSY; } else { @@ -389,14 +399,18 @@ struct atm_dev *dev; struct atmtcp_dev_data *dev_data; - dev = atm_find_dev(itf); + dev = atm_dev_lookup(itf); if (!dev) return -ENODEV; - if (dev->ops != &atmtcp_v_dev_ops) return -EMEDIUMTYPE; + if (dev->ops != &atmtcp_v_dev_ops) { + atm_dev_release(dev); + return -EMEDIUMTYPE; + } dev_data = PRIV(dev); if (!dev_data->persist) return 0; dev_data->persist = 0; if (PRIV(dev)->vcc) return 0; kfree(dev_data); + atm_dev_release(dev); shutdown_atm_dev(dev); return 0; } diff -urN linux-2.4.21/drivers/atm/eni.c linux-2.4.22/drivers/atm/eni.c --- linux-2.4.21/drivers/atm/eni.c 2001-12-21 09:41:53.000000000 -0800 +++ linux-2.4.22/drivers/atm/eni.c 2003-08-25 04:44:41.000000000 -0700 @@ -1101,9 +1101,9 @@ dma_rd = eni_in(MID_DMA_RD_TX); dma_size = 3; /* JK for descriptor and final fill, plus final size mis-alignment fix */ -DPRINTK("iovcnt = %d\n",ATM_SKB(skb)->iovcnt); - if (!ATM_SKB(skb)->iovcnt) dma_size += 5; - else dma_size += 5*ATM_SKB(skb)->iovcnt; +DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags); + if (!skb_shinfo(skb)->nr_frags) dma_size += 5; + else dma_size += 5*(skb_shinfo(skb)->nr_frags+1); if (dma_size > TX_DMA_BUF) { printk(KERN_CRIT DEV_LABEL "(itf %d): needs %d DMA entries " "(got only %d)\n",vcc->dev->number,dma_size,TX_DMA_BUF); @@ -1124,15 +1124,20 @@ MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) | MID_DT_JK; j++; - if (!ATM_SKB(skb)->iovcnt) + if (!skb_shinfo(skb)->nr_frags) if (aal5) put_dma(tx->index,eni_dev->dma,&j,paddr,skb->len); else put_dma(tx->index,eni_dev->dma,&j,paddr+4,skb->len-4); else { DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */ - for (i = 0; i < ATM_SKB(skb)->iovcnt; i++) - put_dma(tx->index,eni_dev->dma,&j,(unsigned long) - ((struct iovec *) skb->data)[i].iov_base, - ((struct iovec *) skb->data)[i].iov_len); + for (i = -1; i < skb_shinfo(skb)->nr_frags; i++) + if (i == -1) + put_dma(tx->index,eni_dev->dma,&j,(unsigned long) + skb->data, + skb->len - skb->data_len); + else + put_dma(tx->index,eni_dev->dma,&j,(unsigned long) + skb_shinfo(skb)->frags[i].page + skb_shinfo(skb)->frags[i].page_offset, + skb_shinfo(skb)->frags[i].size); } if (skb->len & 3) put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3)); @@ -1882,8 +1887,10 @@ static int get_ci(struct atm_vcc *vcc,short *vpi,int *vci) { + unsigned long flags; struct atm_vcc *walk; + spin_lock_irqsave(&vcc->dev->lock, flags); if (*vpi == ATM_VPI_ANY) *vpi = 0; if (*vci == ATM_VCI_ANY) { for (*vci = ATM_NOT_RSV_VCI; *vci < NR_VCI; (*vci)++) { @@ -1902,17 +1909,29 @@ } break; } + spin_unlock_irqrestore(&vcc->dev->lock, flags); return *vci == NR_VCI ? -EADDRINUSE : 0; } - if (*vci == ATM_VCI_UNSPEC) return 0; + if (*vci == ATM_VCI_UNSPEC) { + spin_unlock_irqrestore(&vcc->dev->lock, flags); + return 0; + } if (vcc->qos.rxtp.traffic_class != ATM_NONE && - ENI_DEV(vcc->dev)->rx_map[*vci]) + ENI_DEV(vcc->dev)->rx_map[*vci]) { + spin_unlock_irqrestore(&vcc->dev->lock, flags); return -EADDRINUSE; - if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0; + } + if (vcc->qos.txtp.traffic_class == ATM_NONE) { + spin_unlock_irqrestore(&vcc->dev->lock, flags); + return 0; + } for (walk = vcc->dev->vccs; walk; walk = walk->next) if (test_bit(ATM_VF_ADDR,&walk->flags) && walk->vci == *vci && - walk->qos.txtp.traffic_class != ATM_NONE) + walk->qos.txtp.traffic_class != ATM_NONE) { + spin_unlock_irqrestore(&vcc->dev->lock, flags); return -EADDRINUSE; + } + spin_unlock_irqrestore(&vcc->dev->lock, flags); return 0; } @@ -2120,6 +2139,7 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page) { + unsigned long flags; static const char *signal[] = { "LOST","unknown","okay" }; struct eni_dev *eni_dev = ENI_DEV(dev); struct atm_vcc *vcc; @@ -2192,6 +2212,7 @@ return sprintf(page,"%10sbacklog %u packets\n","", skb_queue_len(&tx->backlog)); } + spin_lock_irqsave(&dev->lock, flags); for (vcc = dev->vccs; vcc; vcc = vcc->next) { struct eni_vcc *eni_vcc = ENI_VCC(vcc); int length; @@ -2210,8 +2231,10 @@ length += sprintf(page+length,"tx[%d], txing %d bytes", eni_vcc->tx->index,eni_vcc->txing); page[length] = '\n'; + spin_unlock_irqrestore(&dev->lock, flags); return length+1; } + spin_unlock_irqrestore(&dev->lock, flags); for (i = 0; i < eni_dev->free_len; i++) { struct eni_free *fe = eni_dev->free_list+i; unsigned long offset; diff -urN linux-2.4.21/drivers/atm/fore200e.c linux-2.4.22/drivers/atm/fore200e.c --- linux-2.4.21/drivers/atm/fore200e.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/atm/fore200e.c 2003-08-25 04:44:41.000000000 -0700 @@ -1077,13 +1077,16 @@ static struct atm_vcc* fore200e_find_vcc(struct fore200e* fore200e, struct rpd* rpd) { + unsigned long flags; struct atm_vcc* vcc; + spin_lock_irqsave(&fore200e->atm_dev->lock, flags); for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) break; } + spin_unlock_irqrestore(&fore200e->atm_dev->lock, flags); return vcc; } @@ -1354,9 +1357,13 @@ static int fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci) { + unsigned long flags; struct atm_vcc* walk; /* find a free VPI */ + + spin_lock_irqsave(&vcc->dev->lock, flags); + if (*vpi == ATM_VPI_ANY) { for (*vpi = 0, walk = vcc->dev->vccs; walk; walk = walk->next) { @@ -1380,6 +1387,8 @@ } } + spin_unlock_irqrestore(&vcc->dev->lock, flags); + return 0; } @@ -2640,6 +2649,7 @@ static int fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page) { + unsigned long flags; struct fore200e* fore200e = FORE200E_DEV(dev); int len, left = *pos; @@ -2886,6 +2896,7 @@ len = sprintf(page,"\n" " VCCs:\n address\tVPI.VCI:AAL\t(min/max tx PDU size) (min/max rx PDU size)\n"); + spin_lock_irqsave(&fore200e->atm_dev->lock, flags); for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { fore200e_vcc = FORE200E_VCC(vcc); @@ -2900,6 +2911,7 @@ fore200e_vcc->rx_max_pdu ); } + spin_unlock_irqrestore(&fore200e->atm_dev->lock, flags); return len; } diff -urN linux-2.4.21/drivers/atm/he.c linux-2.4.22/drivers/atm/he.c --- linux-2.4.21/drivers/atm/he.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/atm/he.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,3121 @@ +/* $Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $ */ + +/* + + he.c + + ForeRunnerHE ATM Adapter driver for ATM on Linux + Copyright (C) 1999-2001 Naval Research Laboratory + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + + he.c + + ForeRunnerHE ATM Adapter driver for ATM on Linux + Copyright (C) 1999-2001 Naval Research Laboratory + + Permission to use, copy, modify and distribute this software and its + documentation is hereby granted, provided that both the copyright + notice and this permission notice appear in all copies of the software, + derivative works or modified versions, and any portions thereof, and + that both notices appear in supporting documentation. + + NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER + RESULTING FROM THE USE OF THIS SOFTWARE. + + This driver was written using the "Programmer's Reference Manual for + ForeRunnerHE(tm)", MANU0361-01 - Rev. A, 08/21/98. + + AUTHORS: + chas williams + eric kinzie + + NOTES: + 4096 supported 'connections' + group 0 is used for all traffic + interrupt queue 0 is used for all interrupts + aal0 support (based on work from ulrich.u.muller@nokia.com) + + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define USE_TASKLET +#undef USE_SCATTERGATHER +#undef USE_CHECKSUM_HW /* still confused about this */ +#define USE_RBPS +#undef USE_RBPS_POOL /* if memory is tight try this */ +#undef USE_RBPL_POOL /* if memory is tight try this */ +#define USE_TPD_POOL +/* #undef CONFIG_ATM_HE_USE_SUNI */ + +/* compatibility */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69) +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) +#define __devexit_p(func) func +#endif + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) +#define pci_set_drvdata(pci_dev, data) (pci_dev)->driver_data = (data) +#define pci_get_drvdata(pci_dev) (pci_dev)->driver_data +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44) +#define pci_pool_create(a, b, c, d, e) pci_pool_create(a, b, c, d, e, SLAB_KERNEL) +#endif + +#include "he.h" + +#include "suni.h" + +#include + +#define hprintk(fmt,args...) printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number , ##args) + +#undef DEBUG +#ifdef DEBUG +#define HPRINTK(fmt,args...) printk(KERN_DEBUG DEV_LABEL "%d: " fmt, he_dev->number , ##args) +#else +#define HPRINTK(fmt,args...) do { } while (0) +#endif /* DEBUG */ + + +/* version definition */ + +static char *version = "$Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $"; + +/* declarations */ + +static int he_open(struct atm_vcc *vcc, short vpi, int vci); +static void he_close(struct atm_vcc *vcc); +static int he_send(struct atm_vcc *vcc, struct sk_buff *skb); +static int he_sg_send(struct atm_vcc *vcc, unsigned long start, unsigned long size); +static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg); +static irqreturn_t he_irq_handler(int irq, void *dev_id, struct pt_regs *regs); +static void he_tasklet(unsigned long data); +static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page); +static int he_start(struct atm_dev *dev); +static void he_stop(struct he_dev *dev); +static void he_phy_put(struct atm_dev *, unsigned char, unsigned long); +static unsigned char he_phy_get(struct atm_dev *, unsigned long); + +static u8 read_prom_byte(struct he_dev *he_dev, int addr); + +/* globals */ + +struct he_dev *he_devs = NULL; +static short disable64 = -1; +static short nvpibits = -1; +static short nvcibits = -1; +static short rx_skb_reserve = 16; +static short irq_coalesce = 1; +static short sdh = 1; + +static struct atmdev_ops he_ops = +{ + .open = he_open, + .close = he_close, + .ioctl = he_ioctl, + .send = he_send, + .sg_send = he_sg_send, + .phy_put = he_phy_put, + .phy_get = he_phy_get, + .proc_read = he_proc_read, + .owner = THIS_MODULE +}; + +#define he_writel(dev, val, reg) do { writel(val, (dev)->membase + (reg)); wmb(); } while (0) +#define he_readl(dev, reg) readl((dev)->membase + (reg)) + +/* section 2.12 connection memory access */ + +static __inline__ void +he_writel_internal(struct he_dev *he_dev, unsigned val, unsigned addr, + unsigned flags) +{ + he_writel(he_dev, val, CON_DAT); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, CON_DAT); +#endif + he_writel(he_dev, flags | CON_CTL_WRITE | CON_CTL_ADDR(addr), CON_CTL); + while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY); +} + +#define he_writel_rcm(dev, val, reg) \ + he_writel_internal(dev, val, reg, CON_CTL_RCM) + +#define he_writel_tcm(dev, val, reg) \ + he_writel_internal(dev, val, reg, CON_CTL_TCM) + +#define he_writel_mbox(dev, val, reg) \ + he_writel_internal(dev, val, reg, CON_CTL_MBOX) + +static unsigned +he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags) +{ + he_writel(he_dev, flags | CON_CTL_READ | CON_CTL_ADDR(addr), CON_CTL); + while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY); + return he_readl(he_dev, CON_DAT); +} + +#define he_readl_rcm(dev, reg) \ + he_readl_internal(dev, reg, CON_CTL_RCM) + +#define he_readl_tcm(dev, reg) \ + he_readl_internal(dev, reg, CON_CTL_TCM) + +#define he_readl_mbox(dev, reg) \ + he_readl_internal(dev, reg, CON_CTL_MBOX) + + +/* figure 2.2 connection id */ + +#define he_mkcid(dev, vpi, vci) (((vpi << (dev)->vcibits) | vci) & 0x1fff) + +/* 2.5.1 per connection transmit state registers */ + +#define he_writel_tsr0(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 0) +#define he_readl_tsr0(dev, cid) \ + he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 0) + +#define he_writel_tsr1(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 1) + +#define he_writel_tsr2(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 2) + +#define he_writel_tsr3(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 3) + +#define he_writel_tsr4(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 4) + + /* from page 2-20 + * + * NOTE While the transmit connection is active, bits 23 through 0 + * of this register must not be written by the host. Byte + * enables should be used during normal operation when writing + * the most significant byte. + */ + +#define he_writel_tsr4_upper(dev, val, cid) \ + he_writel_internal(dev, val, CONFIG_TSRA | (cid << 3) | 4, \ + CON_CTL_TCM \ + | CON_BYTE_DISABLE_2 \ + | CON_BYTE_DISABLE_1 \ + | CON_BYTE_DISABLE_0) + +#define he_readl_tsr4(dev, cid) \ + he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 4) + +#define he_writel_tsr5(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 5) + +#define he_writel_tsr6(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 6) + +#define he_writel_tsr7(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 7) + + +#define he_writel_tsr8(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 0) + +#define he_writel_tsr9(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 1) + +#define he_writel_tsr10(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 2) + +#define he_writel_tsr11(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 3) + + +#define he_writel_tsr12(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 0) + +#define he_writel_tsr13(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 1) + + +#define he_writel_tsr14(dev, val, cid) \ + he_writel_tcm(dev, val, CONFIG_TSRD | cid) + +#define he_writel_tsr14_upper(dev, val, cid) \ + he_writel_internal(dev, val, CONFIG_TSRD | cid, \ + CON_CTL_TCM \ + | CON_BYTE_DISABLE_2 \ + | CON_BYTE_DISABLE_1 \ + | CON_BYTE_DISABLE_0) + +/* 2.7.1 per connection receive state registers */ + +#define he_writel_rsr0(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 0) +#define he_readl_rsr0(dev, cid) \ + he_readl_rcm(dev, 0x00000 | (cid << 3) | 0) + +#define he_writel_rsr1(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 1) + +#define he_writel_rsr2(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 2) + +#define he_writel_rsr3(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 3) + +#define he_writel_rsr4(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 4) + +#define he_writel_rsr5(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 5) + +#define he_writel_rsr6(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 6) + +#define he_writel_rsr7(dev, val, cid) \ + he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7) + +static __inline__ struct atm_vcc* +he_find_vcc(struct he_dev *he_dev, unsigned cid) +{ + unsigned long flags; + struct atm_vcc *vcc; + short vpi; + int vci; + + vpi = cid >> he_dev->vcibits; + vci = cid & ((1 << he_dev->vcibits) - 1); + + spin_lock_irqsave(&he_dev->atm_dev->lock, flags); + for (vcc = he_dev->atm_dev->vccs; vcc; vcc = vcc->next) + if (vcc->vci == vci && vcc->vpi == vpi + && vcc->qos.rxtp.traffic_class != ATM_NONE) { + spin_unlock_irqrestore(&he_dev->atm_dev->lock, flags); + return vcc; + } + + spin_unlock_irqrestore(&he_dev->atm_dev->lock, flags); + return NULL; +} + +static int __devinit +he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) +{ + struct atm_dev *atm_dev = NULL; + struct he_dev *he_dev = NULL; + int err = 0; + + printk(KERN_INFO "he: %s\n", version); + + if (pci_enable_device(pci_dev)) + return -EIO; + if (pci_set_dma_mask(pci_dev, HE_DMA_MASK) != 0) { + printk(KERN_WARNING "he: no suitable dma available\n"); + err = -EIO; + goto init_one_failure; + } + + atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, 0); + if (!atm_dev) { + err = -ENODEV; + goto init_one_failure; + } + pci_set_drvdata(pci_dev, atm_dev); + + he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev), + GFP_KERNEL); + if (!he_dev) { + err = -ENOMEM; + goto init_one_failure; + } + memset(he_dev, 0, sizeof(struct he_dev)); + + he_dev->pci_dev = pci_dev; + he_dev->atm_dev = atm_dev; + he_dev->atm_dev->dev_data = he_dev; + HE_DEV(atm_dev) = he_dev; + he_dev->number = atm_dev->number; + if (he_start(atm_dev)) { + he_stop(he_dev); + err = -ENODEV; + goto init_one_failure; + } + he_dev->next = NULL; + if (he_devs) + he_dev->next = he_devs; + he_devs = he_dev; + return 0; + +init_one_failure: + if (atm_dev) + atm_dev_deregister(atm_dev); + if (he_dev) + kfree(he_dev); + pci_disable_device(pci_dev); + return err; +} + +static void __devexit +he_remove_one (struct pci_dev *pci_dev) +{ + struct atm_dev *atm_dev; + struct he_dev *he_dev; + + atm_dev = pci_get_drvdata(pci_dev); + he_dev = HE_DEV(atm_dev); + + /* need to remove from he_devs */ + + he_stop(he_dev); + atm_dev_deregister(atm_dev); + kfree(he_dev); + + pci_set_drvdata(pci_dev, NULL); + pci_disable_device(pci_dev); +} + + +static unsigned +rate_to_atmf(unsigned rate) /* cps to atm forum format */ +{ +#define NONZERO (1 << 14) + + unsigned exp = 0; + + if (rate == 0) + return 0; + + rate <<= 9; + while (rate > 0x3ff) { + ++exp; + rate >>= 1; + } + + return (NONZERO | (exp << 9) | (rate & 0x1ff)); +} + +static void __init +he_init_rx_lbfp0(struct he_dev *he_dev) +{ + unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count; + unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf; + unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD; + unsigned row_offset = he_dev->r0_startrow * he_dev->bytes_per_row; + + lbufd_index = 0; + lbm_offset = he_readl(he_dev, RCMLBM_BA); + + he_writel(he_dev, lbufd_index, RLBF0_H); + + for (i = 0, lbuf_count = 0; i < he_dev->r0_numbuffs; ++i) { + lbufd_index += 2; + lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32; + + he_writel_rcm(he_dev, lbuf_addr, lbm_offset); + he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1); + + if (++lbuf_count == lbufs_per_row) { + lbuf_count = 0; + row_offset += he_dev->bytes_per_row; + } + lbm_offset += 4; + } + + he_writel(he_dev, lbufd_index - 2, RLBF0_T); + he_writel(he_dev, he_dev->r0_numbuffs, RLBF0_C); +} + +static void __init +he_init_rx_lbfp1(struct he_dev *he_dev) +{ + unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count; + unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf; + unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD; + unsigned row_offset = he_dev->r1_startrow * he_dev->bytes_per_row; + + lbufd_index = 1; + lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index); + + he_writel(he_dev, lbufd_index, RLBF1_H); + + for (i = 0, lbuf_count = 0; i < he_dev->r1_numbuffs; ++i) { + lbufd_index += 2; + lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32; + + he_writel_rcm(he_dev, lbuf_addr, lbm_offset); + he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1); + + if (++lbuf_count == lbufs_per_row) { + lbuf_count = 0; + row_offset += he_dev->bytes_per_row; + } + lbm_offset += 4; + } + + he_writel(he_dev, lbufd_index - 2, RLBF1_T); + he_writel(he_dev, he_dev->r1_numbuffs, RLBF1_C); +} + +static void __init +he_init_tx_lbfp(struct he_dev *he_dev) +{ + unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count; + unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf; + unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD; + unsigned row_offset = he_dev->tx_startrow * he_dev->bytes_per_row; + + lbufd_index = he_dev->r0_numbuffs + he_dev->r1_numbuffs; + lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index); + + he_writel(he_dev, lbufd_index, TLBF_H); + + for (i = 0, lbuf_count = 0; i < he_dev->tx_numbuffs; ++i) { + lbufd_index += 1; + lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32; + + he_writel_rcm(he_dev, lbuf_addr, lbm_offset); + he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1); + + if (++lbuf_count == lbufs_per_row) { + lbuf_count = 0; + row_offset += he_dev->bytes_per_row; + } + lbm_offset += 2; + } + + he_writel(he_dev, lbufd_index - 1, TLBF_T); +} + +static int __init +he_init_tpdrq(struct he_dev *he_dev) +{ + he_dev->tpdrq_base = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq), &he_dev->tpdrq_phys); + if (he_dev->tpdrq_base == NULL) { + hprintk("failed to alloc tpdrq\n"); + return -ENOMEM; + } + memset(he_dev->tpdrq_base, 0, + CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq)); + + he_dev->tpdrq_tail = he_dev->tpdrq_base; + he_dev->tpdrq_head = he_dev->tpdrq_base; + + he_writel(he_dev, he_dev->tpdrq_phys, TPDRQ_B_H); + he_writel(he_dev, 0, TPDRQ_T); + he_writel(he_dev, CONFIG_TPDRQ_SIZE - 1, TPDRQ_S); + + return 0; +} + +static void __init +he_init_cs_block(struct he_dev *he_dev) +{ + unsigned clock, rate, delta; + int reg; + + /* 5.1.7 cs block initialization */ + + for (reg = 0; reg < 0x20; ++reg) + he_writel_mbox(he_dev, 0x0, CS_STTIM0 + reg); + + /* rate grid timer reload values */ + + clock = he_is622(he_dev) ? 66667000 : 50000000; + rate = he_dev->atm_dev->link_rate; + delta = rate / 16 / 2; + + for (reg = 0; reg < 0x10; ++reg) { + /* 2.4 internal transmit function + * + * we initialize the first row in the rate grid. + * values are period (in clock cycles) of timer + */ + unsigned period = clock / rate; + + he_writel_mbox(he_dev, period, CS_TGRLD0 + reg); + rate -= delta; + } + + if (he_is622(he_dev)) { + /* table 5.2 (4 cells per lbuf) */ + he_writel_mbox(he_dev, 0x000800fa, CS_ERTHR0); + he_writel_mbox(he_dev, 0x000c33cb, CS_ERTHR1); + he_writel_mbox(he_dev, 0x0010101b, CS_ERTHR2); + he_writel_mbox(he_dev, 0x00181dac, CS_ERTHR3); + he_writel_mbox(he_dev, 0x00280600, CS_ERTHR4); + + /* table 5.3, 5.4, 5.5, 5.6, 5.7 */ + he_writel_mbox(he_dev, 0x023de8b3, CS_ERCTL0); + he_writel_mbox(he_dev, 0x1801, CS_ERCTL1); + he_writel_mbox(he_dev, 0x68b3, CS_ERCTL2); + he_writel_mbox(he_dev, 0x1280, CS_ERSTAT0); + he_writel_mbox(he_dev, 0x68b3, CS_ERSTAT1); + he_writel_mbox(he_dev, 0x14585, CS_RTFWR); + + he_writel_mbox(he_dev, 0x4680, CS_RTATR); + + /* table 5.8 */ + he_writel_mbox(he_dev, 0x00159ece, CS_TFBSET); + he_writel_mbox(he_dev, 0x68b3, CS_WCRMAX); + he_writel_mbox(he_dev, 0x5eb3, CS_WCRMIN); + he_writel_mbox(he_dev, 0xe8b3, CS_WCRINC); + he_writel_mbox(he_dev, 0xdeb3, CS_WCRDEC); + he_writel_mbox(he_dev, 0x68b3, CS_WCRCEIL); + + /* table 5.9 */ + he_writel_mbox(he_dev, 0x5, CS_OTPPER); + he_writel_mbox(he_dev, 0x14, CS_OTWPER); + } else { + /* table 5.1 (4 cells per lbuf) */ + he_writel_mbox(he_dev, 0x000400ea, CS_ERTHR0); + he_writel_mbox(he_dev, 0x00063388, CS_ERTHR1); + he_writel_mbox(he_dev, 0x00081018, CS_ERTHR2); + he_writel_mbox(he_dev, 0x000c1dac, CS_ERTHR3); + he_writel_mbox(he_dev, 0x0014051a, CS_ERTHR4); + + /* table 5.3, 5.4, 5.5, 5.6, 5.7 */ + he_writel_mbox(he_dev, 0x0235e4b1, CS_ERCTL0); + he_writel_mbox(he_dev, 0x4701, CS_ERCTL1); + he_writel_mbox(he_dev, 0x64b1, CS_ERCTL2); + he_writel_mbox(he_dev, 0x1280, CS_ERSTAT0); + he_writel_mbox(he_dev, 0x64b1, CS_ERSTAT1); + he_writel_mbox(he_dev, 0xf424, CS_RTFWR); + + he_writel_mbox(he_dev, 0x4680, CS_RTATR); + + /* table 5.8 */ + he_writel_mbox(he_dev, 0x000563b7, CS_TFBSET); + he_writel_mbox(he_dev, 0x64b1, CS_WCRMAX); + he_writel_mbox(he_dev, 0x5ab1, CS_WCRMIN); + he_writel_mbox(he_dev, 0xe4b1, CS_WCRINC); + he_writel_mbox(he_dev, 0xdab1, CS_WCRDEC); + he_writel_mbox(he_dev, 0x64b1, CS_WCRCEIL); + + /* table 5.9 */ + he_writel_mbox(he_dev, 0x6, CS_OTPPER); + he_writel_mbox(he_dev, 0x1e, CS_OTWPER); + } + + he_writel_mbox(he_dev, 0x8, CS_OTTLIM); + + for (reg = 0; reg < 0x8; ++reg) + he_writel_mbox(he_dev, 0x0, CS_HGRRT0 + reg); + +} + +static int __init +he_init_cs_block_rcm(struct he_dev *he_dev) +{ + unsigned (*rategrid)[16][16]; + unsigned rate, delta; + int i, j, reg; + + unsigned rate_atmf, exp, man; + unsigned long long rate_cps; + int mult, buf, buf_limit = 4; + + rategrid = kmalloc( sizeof(unsigned) * 16 * 16, GFP_KERNEL); + if (!rategrid) + return -ENOMEM; + + /* initialize rate grid group table */ + + for (reg = 0x0; reg < 0xff; ++reg) + he_writel_rcm(he_dev, 0x0, CONFIG_RCMABR + reg); + + /* initialize rate controller groups */ + + for (reg = 0x100; reg < 0x1ff; ++reg) + he_writel_rcm(he_dev, 0x0, CONFIG_RCMABR + reg); + + /* initialize tNrm lookup table */ + + /* the manual makes reference to a routine in a sample driver + for proper configuration; fortunately, we only need this + in order to support abr connection */ + + /* initialize rate to group table */ + + rate = he_dev->atm_dev->link_rate; + delta = rate / 32; + + /* + * 2.4 transmit internal functions + * + * we construct a copy of the rate grid used by the scheduler + * in order to construct the rate to group table below + */ + + for (j = 0; j < 16; j++) { + (*rategrid)[0][j] = rate; + rate -= delta; + } + + for (i = 1; i < 16; i++) + for (j = 0; j < 16; j++) + if (i > 14) + (*rategrid)[i][j] = (*rategrid)[i - 1][j] / 4; + else + (*rategrid)[i][j] = (*rategrid)[i - 1][j] / 2; + + /* + * 2.4 transmit internal function + * + * this table maps the upper 5 bits of exponent and mantissa + * of the atm forum representation of the rate into an index + * on rate grid + */ + + rate_atmf = 0; + while (rate_atmf < 0x400) { + man = (rate_atmf & 0x1f) << 4; + exp = rate_atmf >> 5; + + /* + instead of '/ 512', use '>> 9' to prevent a call + to divdu3 on x86 platforms + */ + rate_cps = (unsigned long long) (1 << exp) * (man + 512) >> 9; + + if (rate_cps < 10) + rate_cps = 10; /* 2.2.1 minimum payload rate is 10 cps */ + + for (i = 255; i > 0; i--) + if ((*rategrid)[i/16][i%16] >= rate_cps) + break; /* pick nearest rate instead? */ + + /* + * each table entry is 16 bits: (rate grid index (8 bits) + * and a buffer limit (8 bits) + * there are two table entries in each 32-bit register + */ + +#ifdef notdef + buf = rate_cps * he_dev->tx_numbuffs / + (he_dev->atm_dev->link_rate * 2); +#else + /* this is pretty, but avoids _divdu3 and is mostly correct */ + mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR; + if (rate_cps > (272 * mult)) + buf = 4; + else if (rate_cps > (204 * mult)) + buf = 3; + else if (rate_cps > (136 * mult)) + buf = 2; + else if (rate_cps > (68 * mult)) + buf = 1; + else + buf = 0; +#endif + if (buf > buf_limit) + buf = buf_limit; + reg = (reg << 16) | ((i << 8) | buf); + +#define RTGTBL_OFFSET 0x400 + + if (rate_atmf & 0x1) + he_writel_rcm(he_dev, reg, + CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf >> 1)); + + ++rate_atmf; + } + + kfree(rategrid); + return 0; +} + +static int __init +he_init_group(struct he_dev *he_dev, int group) +{ + int i; + +#ifdef USE_RBPS + /* small buffer pool */ +#ifdef USE_RBPS_POOL + he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev, + CONFIG_RBPS_BUFSIZE, 8, 0); + if (he_dev->rbps_pool == NULL) { + hprintk("unable to create rbps pages\n"); + return -ENOMEM; + } +#else /* !USE_RBPS_POOL */ + he_dev->rbps_pages = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPS_SIZE * CONFIG_RBPS_BUFSIZE, &he_dev->rbps_pages_phys); + if (he_dev->rbps_pages == NULL) { + hprintk("unable to create rbps page pool\n"); + return -ENOMEM; + } +#endif /* USE_RBPS_POOL */ + + he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys); + if (he_dev->rbps_base == NULL) { + hprintk("failed to alloc rbps\n"); + return -ENOMEM; + } + memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp)); + he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL); + + for (i = 0; i < CONFIG_RBPS_SIZE; ++i) { + dma_addr_t dma_handle; + void *cpuaddr; + +#ifdef USE_RBPS_POOL + cpuaddr = pci_pool_alloc(he_dev->rbps_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle); + if (cpuaddr == NULL) + return -ENOMEM; +#else + cpuaddr = he_dev->rbps_pages + (i * CONFIG_RBPS_BUFSIZE); + dma_handle = he_dev->rbps_pages_phys + (i * CONFIG_RBPS_BUFSIZE); +#endif + + he_dev->rbps_virt[i].virt = cpuaddr; + he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF); + he_dev->rbps_base[i].phys = dma_handle; + + } + he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE - 1]; + + he_writel(he_dev, he_dev->rbps_phys, G0_RBPS_S + (group * 32)); + he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), + G0_RBPS_T + (group * 32)); + he_writel(he_dev, CONFIG_RBPS_BUFSIZE/4, + G0_RBPS_BS + (group * 32)); + he_writel(he_dev, + RBP_THRESH(CONFIG_RBPS_THRESH) | + RBP_QSIZE(CONFIG_RBPS_SIZE - 1) | + RBP_INT_ENB, + G0_RBPS_QI + (group * 32)); +#else /* !USE_RBPS */ + he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32)); + he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0), + G0_RBPS_BS + (group * 32)); +#endif /* USE_RBPS */ + + /* large buffer pool */ +#ifdef USE_RBPL_POOL + he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev, + CONFIG_RBPL_BUFSIZE, 8, 0); + if (he_dev->rbpl_pool == NULL) { + hprintk("unable to create rbpl pool\n"); + return -ENOMEM; + } +#else /* !USE_RBPL_POOL */ + he_dev->rbpl_pages = (void *) pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPL_SIZE * CONFIG_RBPL_BUFSIZE, &he_dev->rbpl_pages_phys); + if (he_dev->rbpl_pages == NULL) { + hprintk("unable to create rbpl pages\n"); + return -ENOMEM; + } +#endif /* USE_RBPL_POOL */ + + he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPL_SIZE * sizeof(struct he_rbp), &he_dev->rbpl_phys); + if (he_dev->rbpl_base == NULL) { + hprintk("failed to alloc rbpl\n"); + return -ENOMEM; + } + memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp)); + he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL); + + for (i = 0; i < CONFIG_RBPL_SIZE; ++i) { + dma_addr_t dma_handle; + void *cpuaddr; + +#ifdef USE_RBPL_POOL + cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle); + if (cpuaddr == NULL) + return -ENOMEM; +#else + cpuaddr = he_dev->rbpl_pages + (i * CONFIG_RBPL_BUFSIZE); + dma_handle = he_dev->rbpl_pages_phys + (i * CONFIG_RBPL_BUFSIZE); +#endif + + he_dev->rbpl_virt[i].virt = cpuaddr; + he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF); + he_dev->rbpl_base[i].phys = dma_handle; + } + he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1]; + + he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32)); + he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), + G0_RBPL_T + (group * 32)); + he_writel(he_dev, CONFIG_RBPL_BUFSIZE/4, + G0_RBPL_BS + (group * 32)); + he_writel(he_dev, + RBP_THRESH(CONFIG_RBPL_THRESH) | + RBP_QSIZE(CONFIG_RBPL_SIZE - 1) | + RBP_INT_ENB, + G0_RBPL_QI + (group * 32)); + + /* rx buffer ready queue */ + + he_dev->rbrq_base = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys); + if (he_dev->rbrq_base == NULL) { + hprintk("failed to allocate rbrq\n"); + return -ENOMEM; + } + memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq)); + + he_dev->rbrq_head = he_dev->rbrq_base; + he_writel(he_dev, he_dev->rbrq_phys, G0_RBRQ_ST + (group * 16)); + he_writel(he_dev, 0, G0_RBRQ_H + (group * 16)); + he_writel(he_dev, + RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE - 1), + G0_RBRQ_Q + (group * 16)); + if (irq_coalesce) { + hprintk("coalescing interrupts\n"); + he_writel(he_dev, RBRQ_TIME(768) | RBRQ_COUNT(7), + G0_RBRQ_I + (group * 16)); + } else + he_writel(he_dev, RBRQ_TIME(0) | RBRQ_COUNT(1), + G0_RBRQ_I + (group * 16)); + + /* tx buffer ready queue */ + + he_dev->tbrq_base = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), &he_dev->tbrq_phys); + if (he_dev->tbrq_base == NULL) { + hprintk("failed to allocate tbrq\n"); + return -ENOMEM; + } + memset(he_dev->tbrq_base, 0, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq)); + + he_dev->tbrq_head = he_dev->tbrq_base; + + he_writel(he_dev, he_dev->tbrq_phys, G0_TBRQ_B_T + (group * 16)); + he_writel(he_dev, 0, G0_TBRQ_H + (group * 16)); + he_writel(he_dev, CONFIG_TBRQ_SIZE - 1, G0_TBRQ_S + (group * 16)); + he_writel(he_dev, CONFIG_TBRQ_THRESH, G0_TBRQ_THRESH + (group * 16)); + + return 0; +} + +static int __init +he_init_irq(struct he_dev *he_dev) +{ + int i; + + /* 2.9.3.5 tail offset for each interrupt queue is located after the + end of the interrupt queue */ + + he_dev->irq_base = pci_alloc_consistent(he_dev->pci_dev, + (CONFIG_IRQ_SIZE+1) * sizeof(struct he_irq), &he_dev->irq_phys); + if (he_dev->irq_base == NULL) { + hprintk("failed to allocate irq\n"); + return -ENOMEM; + } + he_dev->irq_tailoffset = (unsigned *) + &he_dev->irq_base[CONFIG_IRQ_SIZE]; + *he_dev->irq_tailoffset = 0; + he_dev->irq_head = he_dev->irq_base; + he_dev->irq_tail = he_dev->irq_base; + + for (i = 0; i < CONFIG_IRQ_SIZE; ++i) + he_dev->irq_base[i].isw = ITYPE_INVALID; + + he_writel(he_dev, he_dev->irq_phys, IRQ0_BASE); + he_writel(he_dev, + IRQ_SIZE(CONFIG_IRQ_SIZE) | IRQ_THRESH(CONFIG_IRQ_THRESH), + IRQ0_HEAD); + he_writel(he_dev, IRQ_INT_A | IRQ_TYPE_LINE, IRQ0_CNTL); + he_writel(he_dev, 0x0, IRQ0_DATA); + + he_writel(he_dev, 0x0, IRQ1_BASE); + he_writel(he_dev, 0x0, IRQ1_HEAD); + he_writel(he_dev, 0x0, IRQ1_CNTL); + he_writel(he_dev, 0x0, IRQ1_DATA); + + he_writel(he_dev, 0x0, IRQ2_BASE); + he_writel(he_dev, 0x0, IRQ2_HEAD); + he_writel(he_dev, 0x0, IRQ2_CNTL); + he_writel(he_dev, 0x0, IRQ2_DATA); + + he_writel(he_dev, 0x0, IRQ3_BASE); + he_writel(he_dev, 0x0, IRQ3_HEAD); + he_writel(he_dev, 0x0, IRQ3_CNTL); + he_writel(he_dev, 0x0, IRQ3_DATA); + + /* 2.9.3.2 interrupt queue mapping registers */ + + he_writel(he_dev, 0x0, GRP_10_MAP); + he_writel(he_dev, 0x0, GRP_32_MAP); + he_writel(he_dev, 0x0, GRP_54_MAP); + he_writel(he_dev, 0x0, GRP_76_MAP); + + if (request_irq(he_dev->pci_dev->irq, he_irq_handler, SA_INTERRUPT|SA_SHIRQ, DEV_LABEL, he_dev)) { + hprintk("irq %d already in use\n", he_dev->pci_dev->irq); + return -EINVAL; + } + + he_dev->irq = he_dev->pci_dev->irq; + + return 0; +} + +static int __init +he_start(struct atm_dev *dev) +{ + struct he_dev *he_dev; + struct pci_dev *pci_dev; + + u16 command; + u32 gen_cntl_0, host_cntl, lb_swap; + u8 cache_size, timer; + + unsigned err; + unsigned int status, reg; + int i, group; + + he_dev = HE_DEV(dev); + pci_dev = he_dev->pci_dev; + + he_dev->membase = pci_dev->resource[0].start; + HPRINTK("membase = 0x%lx irq = %d.\n", he_dev->membase, pci_dev->irq); + + /* + * pci bus controller initialization + */ + + /* 4.3 pci bus controller-specific initialization */ + if (pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0) != 0) { + hprintk("can't read GEN_CNTL_0\n"); + return -EINVAL; + } + gen_cntl_0 |= (MRL_ENB | MRM_ENB | IGNORE_TIMEOUT); + if (pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0) != 0) { + hprintk("can't write GEN_CNTL_0.\n"); + return -EINVAL; + } + + if (pci_read_config_word(pci_dev, PCI_COMMAND, &command) != 0) { + hprintk("can't read PCI_COMMAND.\n"); + return -EINVAL; + } + + command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE); + if (pci_write_config_word(pci_dev, PCI_COMMAND, command) != 0) { + hprintk("can't enable memory.\n"); + return -EINVAL; + } + + if (pci_read_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, &cache_size)) { + hprintk("can't read cache line size?\n"); + return -EINVAL; + } + + if (cache_size < 16) { + cache_size = 16; + if (pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, cache_size)) + hprintk("can't set cache line size to %d\n", cache_size); + } + + if (pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &timer)) { + hprintk("can't read latency timer?\n"); + return -EINVAL; + } + + /* from table 3.9 + * + * LAT_TIMER = 1 + AVG_LAT + BURST_SIZE/BUS_SIZE + * + * AVG_LAT: The average first data read/write latency [maximum 16 clock cycles] + * BURST_SIZE: 1536 bytes (read) for 622, 768 bytes (read) for 155 [192 clock cycles] + * + */ +#define LAT_TIMER 209 + if (timer < LAT_TIMER) { + HPRINTK("latency timer was %d, setting to %d\n", timer, LAT_TIMER); + timer = LAT_TIMER; + if (pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, timer)) + hprintk("can't set latency timer to %d\n", timer); + } + + if (!(he_dev->membase = (unsigned long) ioremap(he_dev->membase, HE_REGMAP_SIZE))) { + hprintk("can't set up page mapping\n"); + return -EINVAL; + } + + /* 4.4 card reset */ + he_writel(he_dev, 0x0, RESET_CNTL); + he_writel(he_dev, 0xff, RESET_CNTL); + + udelay(16*1000); /* 16 ms */ + status = he_readl(he_dev, RESET_CNTL); + if ((status & BOARD_RST_STATUS) == 0) { + hprintk("reset failed\n"); + return -EINVAL; + } + + /* 4.5 set bus width */ + host_cntl = he_readl(he_dev, HOST_CNTL); + if (host_cntl & PCI_BUS_SIZE64) + gen_cntl_0 |= ENBL_64; + else + gen_cntl_0 &= ~ENBL_64; + + if (disable64 == 1) { + hprintk("disabling 64-bit pci bus transfers\n"); + gen_cntl_0 &= ~ENBL_64; + } + + if (gen_cntl_0 & ENBL_64) + hprintk("64-bit transfers enabled\n"); + + pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0); + + /* 4.7 read prom contents */ + for (i = 0; i < PROD_ID_LEN; ++i) + he_dev->prod_id[i] = read_prom_byte(he_dev, PROD_ID + i); + + he_dev->media = read_prom_byte(he_dev, MEDIA); + + for (i = 0; i < 6; ++i) + dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i); + + hprintk("%s%s, %x:%x:%x:%x:%x:%x\n", + he_dev->prod_id, + he_dev->media & 0x40 ? "SM" : "MM", + dev->esi[0], + dev->esi[1], + dev->esi[2], + dev->esi[3], + dev->esi[4], + dev->esi[5]); + he_dev->atm_dev->link_rate = he_is622(he_dev) ? + ATM_OC12_PCR : ATM_OC3_PCR; + + /* 4.6 set host endianess */ + lb_swap = he_readl(he_dev, LB_SWAP); + if (he_is622(he_dev)) + lb_swap &= ~XFER_SIZE; /* 4 cells */ + else + lb_swap |= XFER_SIZE; /* 8 cells */ +#ifdef __BIG_ENDIAN + lb_swap |= DESC_WR_SWAP | INTR_SWAP | BIG_ENDIAN_HOST; +#else + lb_swap &= ~(DESC_WR_SWAP | INTR_SWAP | BIG_ENDIAN_HOST | + DATA_WR_SWAP | DATA_RD_SWAP | DESC_RD_SWAP); +#endif /* __BIG_ENDIAN */ + he_writel(he_dev, lb_swap, LB_SWAP); + + /* 4.8 sdram controller initialization */ + he_writel(he_dev, he_is622(he_dev) ? LB_64_ENB : 0x0, SDRAM_CTL); + + /* 4.9 initialize rnum value */ + lb_swap |= SWAP_RNUM_MAX(0xf); + he_writel(he_dev, lb_swap, LB_SWAP); + + /* 4.10 initialize the interrupt queues */ + if ((err = he_init_irq(he_dev)) != 0) + return err; + +#ifdef USE_TASKLET + tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev); +#endif + spin_lock_init(&he_dev->global_lock); + + /* 4.11 enable pci bus controller state machines */ + host_cntl |= (OUTFF_ENB | CMDFF_ENB | + QUICK_RD_RETRY | QUICK_WR_RETRY | PERR_INT_ENB); + he_writel(he_dev, host_cntl, HOST_CNTL); + + gen_cntl_0 |= INT_PROC_ENBL|INIT_ENB; + pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0); + + /* + * atm network controller initialization + */ + + /* 5.1.1 generic configuration state */ + + /* + * local (cell) buffer memory map + * + * HE155 HE622 + * + * 0 ____________1023 bytes 0 _______________________2047 bytes + * | | | | | + * | utility | | rx0 | | + * 5|____________| 255|___________________| u | + * 6| | 256| | t | + * | | | | i | + * | rx0 | row | tx | l | + * | | | | i | + * | | 767|___________________| t | + * 517|____________| 768| | y | + * row 518| | | rx1 | | + * | | 1023|___________________|___| + * | | + * | tx | + * | | + * | | + * 1535|____________| + * 1536| | + * | rx1 | + * 2047|____________| + * + */ + + /* total 4096 connections */ + he_dev->vcibits = CONFIG_DEFAULT_VCIBITS; + he_dev->vpibits = CONFIG_DEFAULT_VPIBITS; + + if (nvpibits != -1 && nvcibits != -1 && nvpibits+nvcibits != HE_MAXCIDBITS) { + hprintk("nvpibits + nvcibits != %d\n", HE_MAXCIDBITS); + return -ENODEV; + } + + if (nvpibits != -1) { + he_dev->vpibits = nvpibits; + he_dev->vcibits = HE_MAXCIDBITS - nvpibits; + } + + if (nvcibits != -1) { + he_dev->vcibits = nvcibits; + he_dev->vpibits = HE_MAXCIDBITS - nvcibits; + } + + + if (he_is622(he_dev)) { + he_dev->cells_per_row = 40; + he_dev->bytes_per_row = 2048; + he_dev->r0_numrows = 256; + he_dev->tx_numrows = 512; + he_dev->r1_numrows = 256; + he_dev->r0_startrow = 0; + he_dev->tx_startrow = 256; + he_dev->r1_startrow = 768; + } else { + he_dev->cells_per_row = 20; + he_dev->bytes_per_row = 1024; + he_dev->r0_numrows = 512; + he_dev->tx_numrows = 1018; + he_dev->r1_numrows = 512; + he_dev->r0_startrow = 6; + he_dev->tx_startrow = 518; + he_dev->r1_startrow = 1536; + } + + he_dev->cells_per_lbuf = 4; + he_dev->buffer_limit = 4; + he_dev->r0_numbuffs = he_dev->r0_numrows * + he_dev->cells_per_row / he_dev->cells_per_lbuf; + if (he_dev->r0_numbuffs > 2560) + he_dev->r0_numbuffs = 2560; + + he_dev->r1_numbuffs = he_dev->r1_numrows * + he_dev->cells_per_row / he_dev->cells_per_lbuf; + if (he_dev->r1_numbuffs > 2560) + he_dev->r1_numbuffs = 2560; + + he_dev->tx_numbuffs = he_dev->tx_numrows * + he_dev->cells_per_row / he_dev->cells_per_lbuf; + if (he_dev->tx_numbuffs > 5120) + he_dev->tx_numbuffs = 5120; + + /* 5.1.2 configure hardware dependent registers */ + + he_writel(he_dev, + SLICE_X(0x2) | ARB_RNUM_MAX(0xf) | TH_PRTY(0x3) | + RH_PRTY(0x3) | TL_PRTY(0x2) | RL_PRTY(0x1) | + (he_is622(he_dev) ? BUS_MULTI(0x28) : BUS_MULTI(0x46)) | + (he_is622(he_dev) ? NET_PREF(0x50) : NET_PREF(0x8c)), + LBARB); + + he_writel(he_dev, BANK_ON | + (he_is622(he_dev) ? (REF_RATE(0x384) | WIDE_DATA) : REF_RATE(0x150)), + SDRAMCON); + + he_writel(he_dev, + (he_is622(he_dev) ? RM_BANK_WAIT(1) : RM_BANK_WAIT(0)) | + RM_RW_WAIT(1), RCMCONFIG); + he_writel(he_dev, + (he_is622(he_dev) ? TM_BANK_WAIT(2) : TM_BANK_WAIT(1)) | + TM_RW_WAIT(1), TCMCONFIG); + + he_writel(he_dev, he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD, LB_CONFIG); + + he_writel(he_dev, + (he_is622(he_dev) ? UT_RD_DELAY(8) : UT_RD_DELAY(0)) | + (he_is622(he_dev) ? RC_UT_MODE(0) : RC_UT_MODE(1)) | + RX_VALVP(he_dev->vpibits) | + RX_VALVC(he_dev->vcibits), RC_CONFIG); + + he_writel(he_dev, DRF_THRESH(0x20) | + (he_is622(he_dev) ? TX_UT_MODE(0) : TX_UT_MODE(1)) | + TX_VCI_MASK(he_dev->vcibits) | + LBFREE_CNT(he_dev->tx_numbuffs), TX_CONFIG); + + he_writel(he_dev, 0x0, TXAAL5_PROTO); + + he_writel(he_dev, PHY_INT_ENB | + (he_is622(he_dev) ? PTMR_PRE(67 - 1) : PTMR_PRE(50 - 1)), + RH_CONFIG); + + /* 5.1.3 initialize connection memory */ + + for (i = 0; i < TCM_MEM_SIZE; ++i) + he_writel_tcm(he_dev, 0, i); + + for (i = 0; i < RCM_MEM_SIZE; ++i) + he_writel_rcm(he_dev, 0, i); + + /* + * transmit connection memory map + * + * tx memory + * 0x0 ___________________ + * | | + * | | + * | TSRa | + * | | + * | | + * 0x8000|___________________| + * | | + * | TSRb | + * 0xc000|___________________| + * | | + * | TSRc | + * 0xe000|___________________| + * | TSRd | + * 0xf000|___________________| + * | tmABR | + * 0x10000|___________________| + * | | + * | tmTPD | + * |___________________| + * | | + * .... + * 0x1ffff|___________________| + * + * + */ + + he_writel(he_dev, CONFIG_TSRB, TSRB_BA); + he_writel(he_dev, CONFIG_TSRC, TSRC_BA); + he_writel(he_dev, CONFIG_TSRD, TSRD_BA); + he_writel(he_dev, CONFIG_TMABR, TMABR_BA); + he_writel(he_dev, CONFIG_TPDBA, TPD_BA); + + + /* + * receive connection memory map + * + * 0x0 ___________________ + * | | + * | | + * | RSRa | + * | | + * | | + * 0x8000|___________________| + * | | + * | rx0/1 | + * | LBM | link lists of local + * | tx | buffer memory + * | | + * 0xd000|___________________| + * | | + * | rmABR | + * 0xe000|___________________| + * | | + * | RSRb | + * |___________________| + * | | + * .... + * 0xffff|___________________| + */ + + he_writel(he_dev, 0x08000, RCMLBM_BA); + he_writel(he_dev, 0x0e000, RCMRSRB_BA); + he_writel(he_dev, 0x0d800, RCMABR_BA); + + /* 5.1.4 initialize local buffer free pools linked lists */ + + he_init_rx_lbfp0(he_dev); + he_init_rx_lbfp1(he_dev); + + he_writel(he_dev, 0x0, RLBC_H); + he_writel(he_dev, 0x0, RLBC_T); + he_writel(he_dev, 0x0, RLBC_H2); + + he_writel(he_dev, 512, RXTHRSH); /* 10% of r0+r1 buffers */ + he_writel(he_dev, 256, LITHRSH); /* 5% of r0+r1 buffers */ + + he_init_tx_lbfp(he_dev); + + he_writel(he_dev, he_is622(he_dev) ? 0x104780 : 0x800, UBUFF_BA); + + /* 5.1.5 initialize intermediate receive queues */ + + if (he_is622(he_dev)) { + he_writel(he_dev, 0x000f, G0_INMQ_S); + he_writel(he_dev, 0x200f, G0_INMQ_L); + + he_writel(he_dev, 0x001f, G1_INMQ_S); + he_writel(he_dev, 0x201f, G1_INMQ_L); + + he_writel(he_dev, 0x002f, G2_INMQ_S); + he_writel(he_dev, 0x202f, G2_INMQ_L); + + he_writel(he_dev, 0x003f, G3_INMQ_S); + he_writel(he_dev, 0x203f, G3_INMQ_L); + + he_writel(he_dev, 0x004f, G4_INMQ_S); + he_writel(he_dev, 0x204f, G4_INMQ_L); + + he_writel(he_dev, 0x005f, G5_INMQ_S); + he_writel(he_dev, 0x205f, G5_INMQ_L); + + he_writel(he_dev, 0x006f, G6_INMQ_S); + he_writel(he_dev, 0x206f, G6_INMQ_L); + + he_writel(he_dev, 0x007f, G7_INMQ_S); + he_writel(he_dev, 0x207f, G7_INMQ_L); + } else { + he_writel(he_dev, 0x0000, G0_INMQ_S); + he_writel(he_dev, 0x0008, G0_INMQ_L); + + he_writel(he_dev, 0x0001, G1_INMQ_S); + he_writel(he_dev, 0x0009, G1_INMQ_L); + + he_writel(he_dev, 0x0002, G2_INMQ_S); + he_writel(he_dev, 0x000a, G2_INMQ_L); + + he_writel(he_dev, 0x0003, G3_INMQ_S); + he_writel(he_dev, 0x000b, G3_INMQ_L); + + he_writel(he_dev, 0x0004, G4_INMQ_S); + he_writel(he_dev, 0x000c, G4_INMQ_L); + + he_writel(he_dev, 0x0005, G5_INMQ_S); + he_writel(he_dev, 0x000d, G5_INMQ_L); + + he_writel(he_dev, 0x0006, G6_INMQ_S); + he_writel(he_dev, 0x000e, G6_INMQ_L); + + he_writel(he_dev, 0x0007, G7_INMQ_S); + he_writel(he_dev, 0x000f, G7_INMQ_L); + } + + /* 5.1.6 application tunable parameters */ + + he_writel(he_dev, 0x0, MCC); + he_writel(he_dev, 0x0, OEC); + he_writel(he_dev, 0x0, DCC); + he_writel(he_dev, 0x0, CEC); + + /* 5.1.7 cs block initialization */ + + he_init_cs_block(he_dev); + + /* 5.1.8 cs block connection memory initialization */ + + if (he_init_cs_block_rcm(he_dev) < 0) + return -ENOMEM; + + /* 5.1.10 initialize host structures */ + + he_init_tpdrq(he_dev); + +#ifdef USE_TPD_POOL + he_dev->tpd_pool = pci_pool_create("tpd", he_dev->pci_dev, + sizeof(struct he_tpd), TPD_ALIGNMENT, 0); + if (he_dev->tpd_pool == NULL) { + hprintk("unable to create tpd pci_pool\n"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&he_dev->outstanding_tpds); +#else + he_dev->tpd_base = (void *) pci_alloc_consistent(he_dev->pci_dev, + CONFIG_NUMTPDS * sizeof(struct he_tpd), &he_dev->tpd_base_phys); + if (!he_dev->tpd_base) + return -ENOMEM; + + for (i = 0; i < CONFIG_NUMTPDS; ++i) { + he_dev->tpd_base[i].status = (i << TPD_ADDR_SHIFT); + he_dev->tpd_base[i].inuse = 0; + } + + he_dev->tpd_head = he_dev->tpd_base; + he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS - 1]; +#endif + + if (he_init_group(he_dev, 0) != 0) + return -ENOMEM; + + for (group = 1; group < HE_NUM_GROUPS; ++group) { + he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32)); + he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0), + G0_RBPS_BS + (group * 32)); + + he_writel(he_dev, 0x0, G0_RBPL_S + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPL_T + (group * 32)); + he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0), + G0_RBPL_QI + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPL_BS + (group * 32)); + + he_writel(he_dev, 0x0, G0_RBRQ_ST + (group * 16)); + he_writel(he_dev, 0x0, G0_RBRQ_H + (group * 16)); + he_writel(he_dev, RBRQ_THRESH(0x1) | RBRQ_SIZE(0x0), + G0_RBRQ_Q + (group * 16)); + he_writel(he_dev, 0x0, G0_RBRQ_I + (group * 16)); + + he_writel(he_dev, 0x0, G0_TBRQ_B_T + (group * 16)); + he_writel(he_dev, 0x0, G0_TBRQ_H + (group * 16)); + he_writel(he_dev, TBRQ_THRESH(0x1), + G0_TBRQ_THRESH + (group * 16)); + he_writel(he_dev, 0x0, G0_TBRQ_S + (group * 16)); + } + + /* host status page */ + + he_dev->hsp = pci_alloc_consistent(he_dev->pci_dev, + sizeof(struct he_hsp), &he_dev->hsp_phys); + if (he_dev->hsp == NULL) { + hprintk("failed to allocate host status page\n"); + return -ENOMEM; + } + memset(he_dev->hsp, 0, sizeof(struct he_hsp)); + he_writel(he_dev, he_dev->hsp_phys, HSP_BA); + + /* initialize framer */ + +#ifdef CONFIG_ATM_HE_USE_SUNI + suni_init(he_dev->atm_dev); + if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->start) + he_dev->atm_dev->phy->start(he_dev->atm_dev); +#endif /* CONFIG_ATM_HE_USE_SUNI */ + + if (sdh) { + /* this really should be in suni.c but for now... */ + + int val; + + val = he_phy_get(he_dev->atm_dev, SUNI_TPOP_APM); + val = (val & ~SUNI_TPOP_APM_S) | ( 0x2 << SUNI_TPOP_APM_S_SHIFT); + he_phy_put(he_dev->atm_dev, val, SUNI_TPOP_APM); + } + + /* 5.1.12 enable transmit and receive */ + + reg = he_readl_mbox(he_dev, CS_ERCTL0); + reg |= TX_ENABLE|ER_ENABLE; + he_writel_mbox(he_dev, reg, CS_ERCTL0); + + reg = he_readl(he_dev, RC_CONFIG); + reg |= RX_ENABLE; + he_writel(he_dev, reg, RC_CONFIG); + + for (i = 0; i < HE_NUM_CS_STPER; ++i) { + he_dev->cs_stper[i].inuse = 0; + he_dev->cs_stper[i].pcr = -1; + } + he_dev->total_bw = 0; + + + /* atm linux initialization */ + + he_dev->atm_dev->ci_range.vpi_bits = he_dev->vpibits; + he_dev->atm_dev->ci_range.vci_bits = he_dev->vcibits; + + he_dev->irq_peak = 0; + he_dev->rbrq_peak = 0; + he_dev->rbpl_peak = 0; + he_dev->tbrq_peak = 0; + + HPRINTK("hell bent for leather!\n"); + + return 0; +} + +static void +he_stop(struct he_dev *he_dev) +{ + u16 command; + u32 gen_cntl_0, reg; + struct pci_dev *pci_dev; + + pci_dev = he_dev->pci_dev; + + /* disable interrupts */ + + if (he_dev->membase) { + pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0); + gen_cntl_0 &= ~(INT_PROC_ENBL | INIT_ENB); + pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0); + +#ifdef USE_TASKLET + tasklet_disable(&he_dev->tasklet); +#endif + + /* disable recv and transmit */ + + reg = he_readl_mbox(he_dev, CS_ERCTL0); + reg &= ~(TX_ENABLE|ER_ENABLE); + he_writel_mbox(he_dev, reg, CS_ERCTL0); + + reg = he_readl(he_dev, RC_CONFIG); + reg &= ~(RX_ENABLE); + he_writel(he_dev, reg, RC_CONFIG); + } + +#ifdef CONFIG_ATM_HE_USE_SUNI + if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->stop) + he_dev->atm_dev->phy->stop(he_dev->atm_dev); +#endif /* CONFIG_ATM_HE_USE_SUNI */ + + if (he_dev->irq) + free_irq(he_dev->irq, he_dev); + + if (he_dev->irq_base) + pci_free_consistent(he_dev->pci_dev, (CONFIG_IRQ_SIZE+1) + * sizeof(struct he_irq), he_dev->irq_base, he_dev->irq_phys); + + if (he_dev->hsp) + pci_free_consistent(he_dev->pci_dev, sizeof(struct he_hsp), + he_dev->hsp, he_dev->hsp_phys); + + if (he_dev->rbpl_base) { +#ifdef USE_RBPL_POOL + for (i = 0; i < CONFIG_RBPL_SIZE; ++i) { + void *cpuaddr = he_dev->rbpl_virt[i].virt; + dma_addr_t dma_handle = he_dev->rbpl_base[i].phys; + + pci_pool_free(he_dev->rbpl_pool, cpuaddr, dma_handle); + } +#else + pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE + * CONFIG_RBPL_BUFSIZE, he_dev->rbpl_pages, he_dev->rbpl_pages_phys); +#endif + pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE + * sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys); + } + +#ifdef USE_RBPL_POOL + if (he_dev->rbpl_pool) + pci_pool_destroy(he_dev->rbpl_pool); +#endif + +#ifdef USE_RBPS + if (he_dev->rbps_base) { +#ifdef USE_RBPS_POOL + for (i = 0; i < CONFIG_RBPS_SIZE; ++i) { + void *cpuaddr = he_dev->rbps_virt[i].virt; + dma_addr_t dma_handle = he_dev->rbps_base[i].phys; + + pci_pool_free(he_dev->rbps_pool, cpuaddr, dma_handle); + } +#else + pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE + * CONFIG_RBPS_BUFSIZE, he_dev->rbps_pages, he_dev->rbps_pages_phys); +#endif + pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE + * sizeof(struct he_rbp), he_dev->rbps_base, he_dev->rbps_phys); + } + +#ifdef USE_RBPS_POOL + if (he_dev->rbps_pool) + pci_pool_destroy(he_dev->rbps_pool); +#endif + +#endif /* USE_RBPS */ + + if (he_dev->rbrq_base) + pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), + he_dev->rbrq_base, he_dev->rbrq_phys); + + if (he_dev->tbrq_base) + pci_free_consistent(he_dev->pci_dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), + he_dev->tbrq_base, he_dev->tbrq_phys); + + if (he_dev->tpdrq_base) + pci_free_consistent(he_dev->pci_dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), + he_dev->tpdrq_base, he_dev->tpdrq_phys); + +#ifdef USE_TPD_POOL + if (he_dev->tpd_pool) + pci_pool_destroy(he_dev->tpd_pool); +#else + if (he_dev->tpd_base) + pci_free_consistent(he_dev->pci_dev, CONFIG_NUMTPDS * sizeof(struct he_tpd), + he_dev->tpd_base, he_dev->tpd_base_phys); +#endif + + if (he_dev->pci_dev) { + pci_read_config_word(he_dev->pci_dev, PCI_COMMAND, &command); + command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + pci_write_config_word(he_dev->pci_dev, PCI_COMMAND, command); + } + + if (he_dev->membase) + iounmap((void *) he_dev->membase); +} + +static struct he_tpd * +__alloc_tpd(struct he_dev *he_dev) +{ +#ifdef USE_TPD_POOL + struct he_tpd *tpd; + dma_addr_t dma_handle; + + tpd = pci_pool_alloc(he_dev->tpd_pool, SLAB_ATOMIC|SLAB_DMA, &dma_handle); + if (tpd == NULL) + return NULL; + + tpd->status = TPD_ADDR(dma_handle); + tpd->reserved = 0; + tpd->iovec[0].addr = 0; tpd->iovec[0].len = 0; + tpd->iovec[1].addr = 0; tpd->iovec[1].len = 0; + tpd->iovec[2].addr = 0; tpd->iovec[2].len = 0; + + return tpd; +#else + int i; + + for (i = 0; i < CONFIG_NUMTPDS; ++i) { + ++he_dev->tpd_head; + if (he_dev->tpd_head > he_dev->tpd_end) { + he_dev->tpd_head = he_dev->tpd_base; + } + + if (!he_dev->tpd_head->inuse) { + he_dev->tpd_head->inuse = 1; + he_dev->tpd_head->status &= TPD_MASK; + he_dev->tpd_head->iovec[0].addr = 0; he_dev->tpd_head->iovec[0].len = 0; + he_dev->tpd_head->iovec[1].addr = 0; he_dev->tpd_head->iovec[1].len = 0; + he_dev->tpd_head->iovec[2].addr = 0; he_dev->tpd_head->iovec[2].len = 0; + return he_dev->tpd_head; + } + } + hprintk("out of tpds -- increase CONFIG_NUMTPDS (%d)\n", CONFIG_NUMTPDS); + return NULL; +#endif +} + +#define AAL5_LEN(buf,len) \ + ((((unsigned char *)(buf))[(len)-6] << 8) | \ + (((unsigned char *)(buf))[(len)-5])) + +/* 2.10.1.2 receive + * + * aal5 packets can optionally return the tcp checksum in the lower + * 16 bits of the crc (RSR0_TCP_CKSUM) + */ + +#define TCP_CKSUM(buf,len) \ + ((((unsigned char *)(buf))[(len)-2] << 8) | \ + (((unsigned char *)(buf))[(len-1)])) + +static int +he_service_rbrq(struct he_dev *he_dev, int group) +{ + struct he_rbrq *rbrq_tail = (struct he_rbrq *) + ((unsigned long)he_dev->rbrq_base | + he_dev->hsp->group[group].rbrq_tail); + struct he_rbp *rbp = NULL; + unsigned cid, lastcid = -1; + unsigned buf_len = 0; + struct sk_buff *skb; + struct atm_vcc *vcc = NULL; + struct he_vcc *he_vcc; + struct he_iovec *iov; + int pdus_assembled = 0; + int updated = 0; + + while (he_dev->rbrq_head != rbrq_tail) { + ++updated; + + HPRINTK("%p rbrq%d 0x%x len=%d cid=0x%x %s%s%s%s%s%s\n", + he_dev->rbrq_head, group, + RBRQ_ADDR(he_dev->rbrq_head), + RBRQ_BUFLEN(he_dev->rbrq_head), + RBRQ_CID(he_dev->rbrq_head), + RBRQ_CRC_ERR(he_dev->rbrq_head) ? " CRC_ERR" : "", + RBRQ_LEN_ERR(he_dev->rbrq_head) ? " LEN_ERR" : "", + RBRQ_END_PDU(he_dev->rbrq_head) ? " END_PDU" : "", + RBRQ_AAL5_PROT(he_dev->rbrq_head) ? " AAL5_PROT" : "", + RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "", + RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : ""); + +#ifdef USE_RBPS + if (RBRQ_ADDR(he_dev->rbrq_head) & RBP_SMALLBUF) + rbp = &he_dev->rbps_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; + else +#endif + rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; + + buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4; + cid = RBRQ_CID(he_dev->rbrq_head); + + if (cid != lastcid) + vcc = he_find_vcc(he_dev, cid); + lastcid = cid; + + if (vcc == NULL) { + hprintk("vcc == NULL (cid 0x%x)\n", cid); + if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) + rbp->status &= ~RBP_LOANED; + + goto next_rbrq_entry; + } + + he_vcc = HE_VCC(vcc); + if (he_vcc == NULL) { + hprintk("he_vcc == NULL (cid 0x%x)\n", cid); + if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) + rbp->status &= ~RBP_LOANED; + goto next_rbrq_entry; + } + + if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) { + hprintk("HBUF_ERR! (cid 0x%x)\n", cid); + atomic_inc(&vcc->stats->rx_drop); + goto return_host_buffers; + } + + he_vcc->iov_tail->iov_base = RBRQ_ADDR(he_dev->rbrq_head); + he_vcc->iov_tail->iov_len = buf_len; + he_vcc->pdu_len += buf_len; + ++he_vcc->iov_tail; + + if (RBRQ_CON_CLOSED(he_dev->rbrq_head)) { + lastcid = -1; + HPRINTK("wake_up rx_waitq (cid 0x%x)\n", cid); + wake_up(&he_vcc->rx_waitq); + goto return_host_buffers; + } + +#ifdef notdef + if ((he_vcc->iov_tail - he_vcc->iov_head) > HE_MAXIOV) { + hprintk("iovec full! cid 0x%x\n", cid); + goto return_host_buffers; + } +#endif + if (!RBRQ_END_PDU(he_dev->rbrq_head)) + goto next_rbrq_entry; + + if (RBRQ_LEN_ERR(he_dev->rbrq_head) + || RBRQ_CRC_ERR(he_dev->rbrq_head)) { + HPRINTK("%s%s (%d.%d)\n", + RBRQ_CRC_ERR(he_dev->rbrq_head) + ? "CRC_ERR " : "", + RBRQ_LEN_ERR(he_dev->rbrq_head) + ? "LEN_ERR" : "", + vcc->vpi, vcc->vci); + atomic_inc(&vcc->stats->rx_err); + goto return_host_buffers; + } + + skb = atm_alloc_charge(vcc, he_vcc->pdu_len + rx_skb_reserve, + GFP_ATOMIC); + if (!skb) { + HPRINTK("charge failed (%d.%d)\n", vcc->vpi, vcc->vci); + goto return_host_buffers; + } + + if (rx_skb_reserve > 0) + skb_reserve(skb, rx_skb_reserve); + + do_gettimeofday(&skb->stamp); + + for (iov = he_vcc->iov_head; + iov < he_vcc->iov_tail; ++iov) { +#ifdef USE_RBPS + if (iov->iov_base & RBP_SMALLBUF) + memcpy(skb_put(skb, iov->iov_len), + he_dev->rbps_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len); + else +#endif + memcpy(skb_put(skb, iov->iov_len), + he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len); + } + + switch (vcc->qos.aal) { + case ATM_AAL0: + /* 2.10.1.5 raw cell receive */ + skb->len = ATM_AAL0_SDU; + skb->tail = skb->data + skb->len; + break; + case ATM_AAL5: + /* 2.10.1.2 aal5 receive */ + + skb->len = AAL5_LEN(skb->data, he_vcc->pdu_len); + skb->tail = skb->data + skb->len; +#ifdef USE_CHECKSUM_HW + if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) { + skb->ip_summed = CHECKSUM_HW; + skb->csum = TCP_CKSUM(skb->data, + he_vcc->pdu_len); + } +#endif + break; + } + +#ifdef should_never_happen + if (skb->len > vcc->qos.rxtp.max_sdu) + hprintk("pdu_len (%d) > vcc->qos.rxtp.max_sdu (%d)! cid 0x%x\n", skb->len, vcc->qos.rxtp.max_sdu, cid); +#endif + +#ifdef notdef + ATM_SKB(skb)->vcc = vcc; +#endif + vcc->push(vcc, skb); + + atomic_inc(&vcc->stats->rx); + +return_host_buffers: + ++pdus_assembled; + + for (iov = he_vcc->iov_head; + iov < he_vcc->iov_tail; ++iov) { +#ifdef USE_RBPS + if (iov->iov_base & RBP_SMALLBUF) + rbp = &he_dev->rbps_base[RBP_INDEX(iov->iov_base)]; + else +#endif + rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)]; + + rbp->status &= ~RBP_LOANED; + } + + he_vcc->iov_tail = he_vcc->iov_head; + he_vcc->pdu_len = 0; + +next_rbrq_entry: + he_dev->rbrq_head = (struct he_rbrq *) + ((unsigned long) he_dev->rbrq_base | + RBRQ_MASK(++he_dev->rbrq_head)); + + } + + if (updated) { + if (updated > he_dev->rbrq_peak) + he_dev->rbrq_peak = updated; + + he_writel(he_dev, RBRQ_MASK(he_dev->rbrq_head), + G0_RBRQ_H + (group * 16)); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, G0_RBRQ_H + (group * 16)); +#endif + } + + return pdus_assembled; +} + +static void +he_service_tbrq(struct he_dev *he_dev, int group) +{ + struct he_tbrq *tbrq_tail = (struct he_tbrq *) + ((unsigned long)he_dev->tbrq_base | + he_dev->hsp->group[group].tbrq_tail); + struct he_tpd *tpd; + int slot, updated = 0; +#ifdef USE_TPD_POOL + struct list_head *p; +#endif + + /* 2.1.6 transmit buffer return queue */ + + while (he_dev->tbrq_head != tbrq_tail) { + ++updated; + + HPRINTK("tbrq%d 0x%x%s%s\n", + group, + TBRQ_TPD(he_dev->tbrq_head), + TBRQ_EOS(he_dev->tbrq_head) ? " EOS" : "", + TBRQ_MULTIPLE(he_dev->tbrq_head) ? " MULTIPLE" : ""); +#ifdef USE_TPD_POOL + tpd = NULL; + p = &he_dev->outstanding_tpds; + while ((p = p->next) != &he_dev->outstanding_tpds) { + struct he_tpd *__tpd = list_entry(p, struct he_tpd, entry); + if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head)) { + tpd = __tpd; + list_del(&__tpd->entry); + break; + } + } + + if (tpd == NULL) { + hprintk("unable to locate tpd for dma buffer %x\n", + TBRQ_TPD(he_dev->tbrq_head)); + goto next_tbrq_entry; + } +#else + tpd = &he_dev->tpd_base[ TPD_INDEX(TBRQ_TPD(he_dev->tbrq_head)) ]; +#endif + + if (TBRQ_EOS(he_dev->tbrq_head)) { + HPRINTK("wake_up(tx_waitq) cid 0x%x\n", + he_mkcid(he_dev, tpd->vcc->vpi, tpd->vcc->vci)); + if (tpd->vcc) + wake_up(&HE_VCC(tpd->vcc)->tx_waitq); + + goto next_tbrq_entry; + } + + for (slot = 0; slot < TPD_MAXIOV; ++slot) { + if (tpd->iovec[slot].addr) + pci_unmap_single(he_dev->pci_dev, + tpd->iovec[slot].addr, + tpd->iovec[slot].len & TPD_LEN_MASK, + PCI_DMA_TODEVICE); + if (tpd->iovec[slot].len & TPD_LST) + break; + + } + + if (tpd->skb) { /* && !TBRQ_MULTIPLE(he_dev->tbrq_head) */ + if (tpd->vcc && tpd->vcc->pop) + tpd->vcc->pop(tpd->vcc, tpd->skb); + else + dev_kfree_skb_any(tpd->skb); + } + +next_tbrq_entry: +#ifdef USE_TPD_POOL + if (tpd) + pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status)); +#else + tpd->inuse = 0; +#endif + he_dev->tbrq_head = (struct he_tbrq *) + ((unsigned long) he_dev->tbrq_base | + TBRQ_MASK(++he_dev->tbrq_head)); + } + + if (updated) { + if (updated > he_dev->tbrq_peak) + he_dev->tbrq_peak = updated; + + he_writel(he_dev, TBRQ_MASK(he_dev->tbrq_head), + G0_TBRQ_H + (group * 16)); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, G0_TBRQ_H + (group * 16)); +#endif + } +} + + +static void +he_service_rbpl(struct he_dev *he_dev, int group) +{ + struct he_rbp *newtail; + struct he_rbp *rbpl_head; + int moved = 0; + + rbpl_head = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base | + RBPL_MASK(he_readl(he_dev, G0_RBPL_S))); + + for (;;) { + newtail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base | + RBPL_MASK(he_dev->rbpl_tail+1)); + + /* table 3.42 -- rbpl_tail should never be set to rbpl_head */ + if ((newtail == rbpl_head) || (newtail->status & RBP_LOANED)) + break; + + newtail->status |= RBP_LOANED; + he_dev->rbpl_tail = newtail; + ++moved; + } + + if (moved) { + he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, G0_RBPL_T); +#endif + } +} + +#ifdef USE_RBPS +static void +he_service_rbps(struct he_dev *he_dev, int group) +{ + struct he_rbp *newtail; + struct he_rbp *rbps_head; + int moved = 0; + + rbps_head = (struct he_rbp *) ((unsigned long)he_dev->rbps_base | + RBPS_MASK(he_readl(he_dev, G0_RBPS_S))); + + for (;;) { + newtail = (struct he_rbp *) ((unsigned long)he_dev->rbps_base | + RBPS_MASK(he_dev->rbps_tail+1)); + + /* table 3.42 -- rbps_tail should never be set to rbps_head */ + if ((newtail == rbps_head) || (newtail->status & RBP_LOANED)) + break; + + newtail->status |= RBP_LOANED; + he_dev->rbps_tail = newtail; + ++moved; + } + + if (moved) { + he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, G0_RBPS_T); +#endif + } +} +#endif /* USE_RBPS */ + +static void +he_tasklet(unsigned long data) +{ + unsigned long flags; + struct he_dev *he_dev = (struct he_dev *) data; + int group, type; + int updated = 0; + + HPRINTK("tasklet (0x%lx)\n", data); +#ifdef USE_TASKLET + spin_lock_irqsave(&he_dev->global_lock, flags); +#endif + + while (he_dev->irq_head != he_dev->irq_tail) { + ++updated; + + type = ITYPE_TYPE(he_dev->irq_head->isw); + group = ITYPE_GROUP(he_dev->irq_head->isw); + + switch (type) { + case ITYPE_RBRQ_THRESH: + HPRINTK("rbrq%d threshold\n", group); + /* fall through */ + case ITYPE_RBRQ_TIMER: + if (he_service_rbrq(he_dev, group)) { + he_service_rbpl(he_dev, group); +#ifdef USE_RBPS + he_service_rbps(he_dev, group); +#endif /* USE_RBPS */ + } + break; + case ITYPE_TBRQ_THRESH: + HPRINTK("tbrq%d threshold\n", group); + /* fall through */ + case ITYPE_TPD_COMPLETE: + he_service_tbrq(he_dev, group); + break; + case ITYPE_RBPL_THRESH: + he_service_rbpl(he_dev, group); + break; + case ITYPE_RBPS_THRESH: +#ifdef USE_RBPS + he_service_rbps(he_dev, group); +#endif /* USE_RBPS */ + break; + case ITYPE_PHY: + HPRINTK("phy interrupt\n"); +#ifdef CONFIG_ATM_HE_USE_SUNI + spin_unlock_irqrestore(&he_dev->global_lock, flags); + if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->interrupt) + he_dev->atm_dev->phy->interrupt(he_dev->atm_dev); + spin_lock_irqsave(&he_dev->global_lock, flags); +#endif + break; + case ITYPE_OTHER: + switch (type|group) { + case ITYPE_PARITY: + hprintk("parity error\n"); + break; + case ITYPE_ABORT: + hprintk("abort 0x%x\n", he_readl(he_dev, ABORT_ADDR)); + break; + } + break; + case ITYPE_TYPE(ITYPE_INVALID): + /* see 8.1.1 -- check all queues */ + + HPRINTK("isw not updated 0x%x\n", he_dev->irq_head->isw); + + he_service_rbrq(he_dev, 0); + he_service_rbpl(he_dev, 0); +#ifdef USE_RBPS + he_service_rbps(he_dev, 0); +#endif /* USE_RBPS */ + he_service_tbrq(he_dev, 0); + break; + default: + hprintk("bad isw 0x%x?\n", he_dev->irq_head->isw); + } + + he_dev->irq_head->isw = ITYPE_INVALID; + + he_dev->irq_head = (struct he_irq *) NEXT_ENTRY(he_dev->irq_base, he_dev->irq_head, IRQ_MASK); + } + + if (updated) { + if (updated > he_dev->irq_peak) + he_dev->irq_peak = updated; + + he_writel(he_dev, + IRQ_SIZE(CONFIG_IRQ_SIZE) | + IRQ_THRESH(CONFIG_IRQ_THRESH) | + IRQ_TAIL(he_dev->irq_tail), IRQ0_HEAD); + (void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata */ + } +#ifdef USE_TASKLET + spin_unlock_irqrestore(&he_dev->global_lock, flags); +#endif +} + +static irqreturn_t +he_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long flags; + struct he_dev *he_dev = (struct he_dev * )dev_id; + int handled = 0; + + if (he_dev == NULL) + return IRQ_NONE; + + spin_lock_irqsave(&he_dev->global_lock, flags); + + he_dev->irq_tail = (struct he_irq *) (((unsigned long)he_dev->irq_base) | + (*he_dev->irq_tailoffset << 2)); + + if (he_dev->irq_tail == he_dev->irq_head) { + HPRINTK("tailoffset not updated?\n"); + he_dev->irq_tail = (struct he_irq *) ((unsigned long)he_dev->irq_base | + ((he_readl(he_dev, IRQ0_BASE) & IRQ_MASK) << 2)); + (void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata */ + } + +#ifdef DEBUG + if (he_dev->irq_head == he_dev->irq_tail /* && !IRQ_PENDING */) + hprintk("spurious (or shared) interrupt?\n"); +#endif + + if (he_dev->irq_head != he_dev->irq_tail) { + handled = 1; +#ifdef USE_TASKLET + tasklet_schedule(&he_dev->tasklet); +#else + he_tasklet((unsigned long) he_dev); +#endif + he_writel(he_dev, INT_CLEAR_A, INT_FIFO); + /* clear interrupt */ +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, INT_FIFO); +#endif + } + spin_unlock_irqrestore(&he_dev->global_lock, flags); + return IRQ_RETVAL(handled); + +} + +static __inline__ void +__enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid) +{ + struct he_tpdrq *new_tail; + + HPRINTK("tpdrq %p cid 0x%x -> tpdrq_tail %p\n", + tpd, cid, he_dev->tpdrq_tail); + + /* new_tail = he_dev->tpdrq_tail; */ + new_tail = (struct he_tpdrq *) ((unsigned long) he_dev->tpdrq_base | + TPDRQ_MASK(he_dev->tpdrq_tail+1)); + + /* + * check to see if we are about to set the tail == head + * if true, update the head pointer from the adapter + * to see if this is really the case (reading the queue + * head for every enqueue would be unnecessarily slow) + */ + + if (new_tail == he_dev->tpdrq_head) { + he_dev->tpdrq_head = (struct he_tpdrq *) + (((unsigned long)he_dev->tpdrq_base) | + TPDRQ_MASK(he_readl(he_dev, TPDRQ_B_H))); + + if (new_tail == he_dev->tpdrq_head) { + hprintk("tpdrq full (cid 0x%x)\n", cid); + /* + * FIXME + * push tpd onto a transmit backlog queue + * after service_tbrq, service the backlog + * for now, we just drop the pdu + */ + if (tpd->skb) { + if (tpd->vcc->pop) + tpd->vcc->pop(tpd->vcc, tpd->skb); + else + dev_kfree_skb_any(tpd->skb); + atomic_inc(&tpd->vcc->stats->tx_err); + } +#ifdef USE_TPD_POOL + pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status)); +#else + tpd->inuse = 0; +#endif + return; + } + } + + /* 2.1.5 transmit packet descriptor ready queue */ +#ifdef USE_TPD_POOL + list_add_tail(&tpd->entry, &he_dev->outstanding_tpds); + he_dev->tpdrq_tail->tpd = TPD_ADDR(tpd->status); +#else + he_dev->tpdrq_tail->tpd = he_dev->tpd_base_phys + + (TPD_INDEX(tpd->status) * sizeof(struct he_tpd)); +#endif + he_dev->tpdrq_tail->cid = cid; + wmb(); + + he_dev->tpdrq_tail = new_tail; + + he_writel(he_dev, TPDRQ_MASK(he_dev->tpdrq_tail), TPDRQ_T); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, TPDRQ_T); +#endif +} + +static int +he_open(struct atm_vcc *vcc, short vpi, int vci) +{ + unsigned long flags; + struct he_dev *he_dev = HE_DEV(vcc->dev); + struct he_vcc *he_vcc; + int err = 0; + unsigned cid, rsr0, rsr1, rsr4, tsr0, tsr0_aal, tsr4, period, reg, clock; + + + if ((err = atm_find_ci(vcc, &vpi, &vci))) { + HPRINTK("atm_find_ci err = %d\n", err); + return err; + } + if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) + return 0; + vcc->vpi = vpi; + vcc->vci = vci; + + HPRINTK("open vcc %p %d.%d\n", vcc, vpi, vci); + + set_bit(ATM_VF_ADDR, &vcc->flags); + + cid = he_mkcid(he_dev, vpi, vci); + + he_vcc = (struct he_vcc *) kmalloc(sizeof(struct he_vcc), GFP_ATOMIC); + if (he_vcc == NULL) { + hprintk("unable to allocate he_vcc during open\n"); + return -ENOMEM; + } + + he_vcc->iov_tail = he_vcc->iov_head; + he_vcc->pdu_len = 0; + he_vcc->rc_index = -1; + + init_waitqueue_head(&he_vcc->rx_waitq); + init_waitqueue_head(&he_vcc->tx_waitq); + + HE_VCC(vcc) = he_vcc; + + if (vcc->qos.txtp.traffic_class != ATM_NONE) { + int pcr_goal; + + pcr_goal = atm_pcr_goal(&vcc->qos.txtp); + if (pcr_goal == 0) + pcr_goal = he_dev->atm_dev->link_rate; + if (pcr_goal < 0) /* means round down, technically */ + pcr_goal = -pcr_goal; + + HPRINTK("open tx cid 0x%x pcr_goal %d\n", cid, pcr_goal); + + switch (vcc->qos.aal) { + case ATM_AAL5: + tsr0_aal = TSR0_AAL5; + tsr4 = TSR4_AAL5; + break; + case ATM_AAL0: + tsr0_aal = TSR0_AAL0_SDU; + tsr4 = TSR4_AAL0_SDU; + break; + default: + err = -EINVAL; + goto open_failed; + } + + spin_lock_irqsave(&he_dev->global_lock, flags); + tsr0 = he_readl_tsr0(he_dev, cid); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + if (TSR0_CONN_STATE(tsr0) != 0) { + hprintk("cid 0x%x not idle (tsr0 = 0x%x)\n", cid, tsr0); + err = -EBUSY; + goto open_failed; + } + + switch (vcc->qos.txtp.traffic_class) { + case ATM_UBR: + /* 2.3.3.1 open connection ubr */ + + tsr0 = TSR0_UBR | TSR0_GROUP(0) | tsr0_aal | + TSR0_USE_WMIN | TSR0_UPDATE_GER; + break; + + case ATM_CBR: + /* 2.3.3.2 open connection cbr */ + + /* 8.2.3 cbr scheduler wrap problem -- limit to 90% total link rate */ + if ((he_dev->total_bw + pcr_goal) + > (he_dev->atm_dev->link_rate * 9 / 10)) + { + err = -EBUSY; + goto open_failed; + } + + spin_lock_irqsave(&he_dev->global_lock, flags); /* also protects he_dev->cs_stper[] */ + + /* find an unused cs_stper register */ + for (reg = 0; reg < HE_NUM_CS_STPER; ++reg) + if (he_dev->cs_stper[reg].inuse == 0 || + he_dev->cs_stper[reg].pcr == pcr_goal) + break; + + if (reg == HE_NUM_CS_STPER) { + err = -EBUSY; + spin_unlock_irqrestore(&he_dev->global_lock, flags); + goto open_failed; + } + + he_dev->total_bw += pcr_goal; + + he_vcc->rc_index = reg; + ++he_dev->cs_stper[reg].inuse; + he_dev->cs_stper[reg].pcr = pcr_goal; + + clock = he_is622(he_dev) ? 66667000 : 50000000; + period = clock / pcr_goal; + + HPRINTK("rc_index = %d period = %d\n", + reg, period); + + he_writel_mbox(he_dev, rate_to_atmf(period/2), + CS_STPER0 + reg); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + tsr0 = TSR0_CBR | TSR0_GROUP(0) | tsr0_aal | + TSR0_RC_INDEX(reg); + + break; + default: + err = -EINVAL; + goto open_failed; + } + + spin_lock_irqsave(&he_dev->global_lock, flags); + + he_writel_tsr0(he_dev, tsr0, cid); + he_writel_tsr4(he_dev, tsr4 | 1, cid); + he_writel_tsr1(he_dev, TSR1_MCR(rate_to_atmf(0)) | + TSR1_PCR(rate_to_atmf(pcr_goal)), cid); + he_writel_tsr2(he_dev, TSR2_ACR(rate_to_atmf(pcr_goal)), cid); + he_writel_tsr9(he_dev, TSR9_OPEN_CONN, cid); + + he_writel_tsr3(he_dev, 0x0, cid); + he_writel_tsr5(he_dev, 0x0, cid); + he_writel_tsr6(he_dev, 0x0, cid); + he_writel_tsr7(he_dev, 0x0, cid); + he_writel_tsr8(he_dev, 0x0, cid); + he_writel_tsr10(he_dev, 0x0, cid); + he_writel_tsr11(he_dev, 0x0, cid); + he_writel_tsr12(he_dev, 0x0, cid); + he_writel_tsr13(he_dev, 0x0, cid); + he_writel_tsr14(he_dev, 0x0, cid); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl_tsr0(he_dev, cid); +#endif + spin_unlock_irqrestore(&he_dev->global_lock, flags); + } + + if (vcc->qos.rxtp.traffic_class != ATM_NONE) { + unsigned aal; + + HPRINTK("open rx cid 0x%x (rx_waitq %p)\n", cid, + &HE_VCC(vcc)->rx_waitq); + + switch (vcc->qos.aal) { + case ATM_AAL5: + aal = RSR0_AAL5; + break; + case ATM_AAL0: + aal = RSR0_RAWCELL; + break; + default: + err = -EINVAL; + goto open_failed; + } + + spin_lock_irqsave(&he_dev->global_lock, flags); + + rsr0 = he_readl_rsr0(he_dev, cid); + if (rsr0 & RSR0_OPEN_CONN) { + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + hprintk("cid 0x%x not idle (rsr0 = 0x%x)\n", cid, rsr0); + err = -EBUSY; + goto open_failed; + } + +#ifdef USE_RBPS + rsr1 = RSR1_GROUP(0); + rsr4 = RSR4_GROUP(0); +#else /* !USE_RBPS */ + rsr1 = RSR1_GROUP(0)|RSR1_RBPL_ONLY; + rsr4 = RSR4_GROUP(0)|RSR4_RBPL_ONLY; +#endif /* USE_RBPS */ + rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? + (RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0; + +#ifdef USE_CHECKSUM_HW + if (vpi == 0 && vci >= ATM_NOT_RSV_VCI) + rsr0 |= RSR0_TCP_CKSUM; +#endif + + he_writel_rsr4(he_dev, rsr4, cid); + he_writel_rsr1(he_dev, rsr1, cid); + /* 5.1.11 last parameter initialized should be + the open/closed indication in rsr0 */ + he_writel_rsr0(he_dev, + rsr0 | RSR0_START_PDU | RSR0_OPEN_CONN | aal, cid); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl_rsr0(he_dev, cid); +#endif + + spin_unlock_irqrestore(&he_dev->global_lock, flags); + } + +open_failed: + + if (err) { + if (he_vcc) + kfree(he_vcc); + clear_bit(ATM_VF_ADDR, &vcc->flags); + } + else + set_bit(ATM_VF_READY, &vcc->flags); + + return err; +} + +static void +he_close(struct atm_vcc *vcc) +{ + unsigned long flags; + DECLARE_WAITQUEUE(wait, current); + struct he_dev *he_dev = HE_DEV(vcc->dev); + struct he_tpd *tpd; + unsigned cid; + struct he_vcc *he_vcc = HE_VCC(vcc); +#define MAX_RETRY 30 + int retry = 0, sleep = 1, tx_inuse; + + HPRINTK("close vcc %p %d.%d\n", vcc, vcc->vpi, vcc->vci); + + clear_bit(ATM_VF_READY, &vcc->flags); + cid = he_mkcid(he_dev, vcc->vpi, vcc->vci); + + if (vcc->qos.rxtp.traffic_class != ATM_NONE) { + int timeout; + + HPRINTK("close rx cid 0x%x\n", cid); + + /* 2.7.2.2 close receive operation */ + + /* wait for previous close (if any) to finish */ + + spin_lock_irqsave(&he_dev->global_lock, flags); + while (he_readl(he_dev, RCC_STAT) & RCC_BUSY) { + HPRINTK("close cid 0x%x RCC_BUSY\n", cid); + udelay(250); + } + + add_wait_queue(&he_vcc->rx_waitq, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); + + he_writel_rsr0(he_dev, RSR0_CLOSE_CONN, cid); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl_rsr0(he_dev, cid); +#endif + he_writel_mbox(he_dev, cid, RXCON_CLOSE); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + timeout = schedule_timeout(30*HZ); + + remove_wait_queue(&he_vcc->rx_waitq, &wait); + set_current_state(TASK_RUNNING); + + if (timeout == 0) + hprintk("close rx timeout cid 0x%x\n", cid); + + HPRINTK("close rx cid 0x%x complete\n", cid); + + } + + if (vcc->qos.txtp.traffic_class != ATM_NONE) { + volatile unsigned tsr4, tsr0; + int timeout; + + HPRINTK("close tx cid 0x%x\n", cid); + + /* 2.1.2 + * + * ... the host must first stop queueing packets to the TPDRQ + * on the connection to be closed, then wait for all outstanding + * packets to be transmitted and their buffers returned to the + * TBRQ. When the last packet on the connection arrives in the + * TBRQ, the host issues the close command to the adapter. + */ + + while (((tx_inuse = atomic_read(&vcc->sk->wmem_alloc)) > 0) && + (retry < MAX_RETRY)) { + set_current_state(TASK_UNINTERRUPTIBLE); + (void) schedule_timeout(sleep); + set_current_state(TASK_RUNNING); + if (sleep < HZ) + sleep = sleep * 2; + + ++retry; + } + + if (tx_inuse) + hprintk("close tx cid 0x%x tx_inuse = %d\n", cid, tx_inuse); + + /* 2.3.1.1 generic close operations with flush */ + + spin_lock_irqsave(&he_dev->global_lock, flags); + he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid); + /* also clears TSR4_SESSION_ENDED */ +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl_tsr4(he_dev, cid); +#endif + + switch (vcc->qos.txtp.traffic_class) { + case ATM_UBR: + he_writel_tsr1(he_dev, + TSR1_MCR(rate_to_atmf(200000)) + | TSR1_PCR(0), cid); + break; + case ATM_CBR: + he_writel_tsr14_upper(he_dev, TSR14_DELETE, cid); + break; + } + + tpd = __alloc_tpd(he_dev); + if (tpd == NULL) { + hprintk("close tx he_alloc_tpd failed cid 0x%x\n", cid); + goto close_tx_incomplete; + } + tpd->status |= TPD_EOS | TPD_INT; + tpd->skb = NULL; + tpd->vcc = vcc; + wmb(); + + add_wait_queue(&he_vcc->tx_waitq, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); + __enqueue_tpd(he_dev, tpd, cid); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + timeout = schedule_timeout(30*HZ); + + remove_wait_queue(&he_vcc->tx_waitq, &wait); + set_current_state(TASK_RUNNING); + + spin_lock_irqsave(&he_dev->global_lock, flags); + + if (timeout == 0) { + hprintk("close tx timeout cid 0x%x\n", cid); + goto close_tx_incomplete; + } + + while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) { + HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4); + udelay(250); + } + + while (TSR0_CONN_STATE(tsr0 = he_readl_tsr0(he_dev, cid)) != 0) { + HPRINTK("close tx cid 0x%x TSR0_CONN_STATE != 0 (tsr0 = 0x%x)\n", cid, tsr0); + udelay(250); + } + +close_tx_incomplete: + + if (vcc->qos.txtp.traffic_class == ATM_CBR) { + int reg = he_vcc->rc_index; + + HPRINTK("cs_stper reg = %d\n", reg); + + if (he_dev->cs_stper[reg].inuse == 0) + hprintk("cs_stper[%d].inuse = 0!\n", reg); + else + --he_dev->cs_stper[reg].inuse; + + he_dev->total_bw -= he_dev->cs_stper[reg].pcr; + } + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + HPRINTK("close tx cid 0x%x complete\n", cid); + } + + kfree(he_vcc); + + clear_bit(ATM_VF_ADDR, &vcc->flags); +} + +static int +he_sg_send(struct atm_vcc *vcc, unsigned long start, unsigned long size) +{ +#ifdef USE_SCATTERGATHER + return 1; +#else + return 0; +#endif +} + +static int +he_send(struct atm_vcc *vcc, struct sk_buff *skb) +{ + unsigned long flags; + struct he_dev *he_dev = HE_DEV(vcc->dev); + unsigned cid = he_mkcid(he_dev, vcc->vpi, vcc->vci); + struct he_tpd *tpd; +#ifdef USE_SCATTERGATHER + int i, slot = 0; +#endif + +#define HE_TPD_BUFSIZE 0xffff + + HPRINTK("send %d.%d\n", vcc->vpi, vcc->vci); + + if ((skb->len > HE_TPD_BUFSIZE) || + ((vcc->qos.aal == ATM_AAL0) && (skb->len != ATM_AAL0_SDU))) { + hprintk("buffer too large (or small) -- %d bytes\n", skb->len ); + if (vcc->pop) + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); + atomic_inc(&vcc->stats->tx_err); + return -EINVAL; + } + +#ifndef USE_SCATTERGATHER + if (skb_shinfo(skb)->nr_frags) { + hprintk("no scatter/gather support\n"); + if (vcc->pop) + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); + atomic_inc(&vcc->stats->tx_err); + return -EINVAL; + } +#endif + spin_lock_irqsave(&he_dev->global_lock, flags); + + tpd = __alloc_tpd(he_dev); + if (tpd == NULL) { + if (vcc->pop) + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); + atomic_inc(&vcc->stats->tx_err); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + return -ENOMEM; + } + + if (vcc->qos.aal == ATM_AAL5) + tpd->status |= TPD_CELLTYPE(TPD_USERCELL); + else { + char *pti_clp = (void *) (skb->data + 3); + int clp, pti; + + pti = (*pti_clp & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT; + clp = (*pti_clp & ATM_HDR_CLP); + tpd->status |= TPD_CELLTYPE(pti); + if (clp) + tpd->status |= TPD_CLP; + + skb_pull(skb, ATM_AAL0_SDU - ATM_CELL_PAYLOAD); + } + +#ifdef USE_SCATTERGATHER + tpd->iovec[slot].addr = pci_map_single(he_dev->pci_dev, skb->data, + skb->len - skb->data_len, PCI_DMA_TODEVICE); + tpd->iovec[slot].len = skb->len - skb->data_len; + ++slot; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + if (slot == TPD_MAXIOV) { /* queue tpd; start new tpd */ + tpd->vcc = vcc; + tpd->skb = NULL; /* not the last fragment + so dont ->push() yet */ + wmb(); + + __enqueue_tpd(he_dev, tpd, cid); + tpd = __alloc_tpd(he_dev); + if (tpd == NULL) { + if (vcc->pop) + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); + atomic_inc(&vcc->stats->tx_err); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + return -ENOMEM; + } + tpd->status |= TPD_USERCELL; + slot = 0; + } + + tpd->iovec[slot].addr = pci_map_single(he_dev->pci_dev, + (void *) page_address(frag->page) + frag->page_offset, + frag->size, PCI_DMA_TODEVICE); + tpd->iovec[slot].len = frag->size; + ++slot; + + } + + tpd->iovec[slot - 1].len |= TPD_LST; +#else + tpd->address0 = pci_map_single(he_dev->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); + tpd->length0 = skb->len | TPD_LST; +#endif + tpd->status |= TPD_INT; + + tpd->vcc = vcc; + tpd->skb = skb; + wmb(); + ATM_SKB(skb)->vcc = vcc; + + __enqueue_tpd(he_dev, tpd, cid); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + atomic_inc(&vcc->stats->tx); + + return 0; +} + +static int +he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg) +{ + unsigned long flags; + struct he_dev *he_dev = HE_DEV(atm_dev); + struct he_ioctl_reg reg; + int err = 0; + + switch (cmd) { + case HE_GET_REG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + copy_from_user(®, (struct he_ioctl_reg *) arg, + sizeof(struct he_ioctl_reg)); + spin_lock_irqsave(&he_dev->global_lock, flags); + switch (reg.type) { + case HE_REGTYPE_PCI: + reg.val = he_readl(he_dev, reg.addr); + break; + case HE_REGTYPE_RCM: + reg.val = + he_readl_rcm(he_dev, reg.addr); + break; + case HE_REGTYPE_TCM: + reg.val = + he_readl_tcm(he_dev, reg.addr); + break; + case HE_REGTYPE_MBOX: + reg.val = + he_readl_mbox(he_dev, reg.addr); + break; + default: + err = -EINVAL; + break; + } + spin_unlock_irqrestore(&he_dev->global_lock, flags); + if (err == 0) + copy_to_user((struct he_ioctl_reg *) arg, ®, + sizeof(struct he_ioctl_reg)); + break; + default: +#ifdef CONFIG_ATM_HE_USE_SUNI + if (atm_dev->phy && atm_dev->phy->ioctl) + err = atm_dev->phy->ioctl(atm_dev, cmd, arg); +#else /* CONFIG_ATM_HE_USE_SUNI */ + err = -EINVAL; +#endif /* CONFIG_ATM_HE_USE_SUNI */ + break; + } + + return err; +} + +static void +he_phy_put(struct atm_dev *atm_dev, unsigned char val, unsigned long addr) +{ + unsigned long flags; + struct he_dev *he_dev = HE_DEV(atm_dev); + + HPRINTK("phy_put(val 0x%x, addr 0x%lx)\n", val, addr); + + spin_lock_irqsave(&he_dev->global_lock, flags); + he_writel(he_dev, val, FRAMER + (addr*4)); +#ifdef CONFIG_IA64_SGI_SN2 + (void) he_readl(he_dev, FRAMER + (addr*4)); +#endif + spin_unlock_irqrestore(&he_dev->global_lock, flags); +} + + +static unsigned char +he_phy_get(struct atm_dev *atm_dev, unsigned long addr) +{ + unsigned long flags; + struct he_dev *he_dev = HE_DEV(atm_dev); + unsigned reg; + + spin_lock_irqsave(&he_dev->global_lock, flags); + reg = he_readl(he_dev, FRAMER + (addr*4)); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + HPRINTK("phy_get(addr 0x%lx) =0x%x\n", addr, reg); + return reg; +} + +static int +he_proc_read(struct atm_dev *dev, loff_t *pos, char *page) +{ + unsigned long flags; + struct he_dev *he_dev = HE_DEV(dev); + int left, i; +#ifdef notdef + struct he_rbrq *rbrq_tail; + struct he_tpdrq *tpdrq_head; + int rbpl_head, rbpl_tail; +#endif + static long mcc = 0, oec = 0, dcc = 0, cec = 0; + + + left = *pos; + if (!left--) + return sprintf(page, "%s\n", version); + + if (!left--) + return sprintf(page, "%s%s\n\n", + he_dev->prod_id, he_dev->media & 0x40 ? "SM" : "MM"); + + if (!left--) + return sprintf(page, "Mismatched Cells VPI/VCI Not Open Dropped Cells RCM Dropped Cells\n"); + + spin_lock_irqsave(&he_dev->global_lock, flags); + mcc += he_readl(he_dev, MCC); + oec += he_readl(he_dev, OEC); + dcc += he_readl(he_dev, DCC); + cec += he_readl(he_dev, CEC); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + + if (!left--) + return sprintf(page, "%16ld %16ld %13ld %17ld\n\n", + mcc, oec, dcc, cec); + + if (!left--) + return sprintf(page, "irq_size = %d inuse = ? peak = %d\n", + CONFIG_IRQ_SIZE, he_dev->irq_peak); + + if (!left--) + return sprintf(page, "tpdrq_size = %d inuse = ?\n", + CONFIG_TPDRQ_SIZE); + + if (!left--) + return sprintf(page, "rbrq_size = %d inuse = ? peak = %d\n", + CONFIG_RBRQ_SIZE, he_dev->rbrq_peak); + + if (!left--) + return sprintf(page, "tbrq_size = %d peak = %d\n", + CONFIG_TBRQ_SIZE, he_dev->tbrq_peak); + + +#ifdef notdef + rbpl_head = RBPL_MASK(he_readl(he_dev, G0_RBPL_S)); + rbpl_tail = RBPL_MASK(he_readl(he_dev, G0_RBPL_T)); + + inuse = rbpl_head - rbpl_tail; + if (inuse < 0) + inuse += CONFIG_RBPL_SIZE * sizeof(struct he_rbp); + inuse /= sizeof(struct he_rbp); + + if (!left--) + return sprintf(page, "rbpl_size = %d inuse = %d\n\n", + CONFIG_RBPL_SIZE, inuse); +#endif + + if (!left--) + return sprintf(page, "rate controller periods (cbr)\n pcr #vc\n"); + + for (i = 0; i < HE_NUM_CS_STPER; ++i) + if (!left--) + return sprintf(page, "cs_stper%-2d %8ld %3d\n", i, + he_dev->cs_stper[i].pcr, + he_dev->cs_stper[i].inuse); + + if (!left--) + return sprintf(page, "total bw (cbr): %d (limit %d)\n", + he_dev->total_bw, he_dev->atm_dev->link_rate * 10 / 9); + + return 0; +} + +/* eeprom routines -- see 4.7 */ + +u8 +read_prom_byte(struct he_dev *he_dev, int addr) +{ + u32 val = 0, tmp_read = 0; + int i, j = 0; + u8 byte_read = 0; + + val = readl(he_dev->membase + HOST_CNTL); + val &= 0xFFFFE0FF; + + /* Turn on write enable */ + val |= 0x800; + he_writel(he_dev, val, HOST_CNTL); + + /* Send READ instruction */ + for (i = 0; i < sizeof(readtab)/sizeof(readtab[0]); i++) { + he_writel(he_dev, val | readtab[i], HOST_CNTL); + udelay(EEPROM_DELAY); + } + + /* Next, we need to send the byte address to read from */ + for (i = 7; i >= 0; i--) { + he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL); + udelay(EEPROM_DELAY); + he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL); + udelay(EEPROM_DELAY); + } + + j = 0; + + val &= 0xFFFFF7FF; /* Turn off write enable */ + he_writel(he_dev, val, HOST_CNTL); + + /* Now, we can read data from the EEPROM by clocking it in */ + for (i = 7; i >= 0; i--) { + he_writel(he_dev, val | clocktab[j++], HOST_CNTL); + udelay(EEPROM_DELAY); + tmp_read = he_readl(he_dev, HOST_CNTL); + byte_read |= (unsigned char) + ((tmp_read & ID_DOUT) >> ID_DOFFSET << i); + he_writel(he_dev, val | clocktab[j++], HOST_CNTL); + udelay(EEPROM_DELAY); + } + + he_writel(he_dev, val | ID_CS, HOST_CNTL); + udelay(EEPROM_DELAY); + + return byte_read; +} + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("chas williams "); +MODULE_DESCRIPTION("ForeRunnerHE ATM Adapter driver"); +MODULE_PARM(disable64, "h"); +MODULE_PARM_DESC(disable64, "disable 64-bit pci bus transfers"); +MODULE_PARM(nvpibits, "i"); +MODULE_PARM_DESC(nvpibits, "numbers of bits for vpi (default 0)"); +MODULE_PARM(nvcibits, "i"); +MODULE_PARM_DESC(nvcibits, "numbers of bits for vci (default 12)"); +MODULE_PARM(rx_skb_reserve, "i"); +MODULE_PARM_DESC(rx_skb_reserve, "padding for receive skb (default 16)"); +MODULE_PARM(irq_coalesce, "i"); +MODULE_PARM_DESC(irq_coalesce, "use interrupt coalescing (default 1)"); +MODULE_PARM(sdh, "i"); +MODULE_PARM_DESC(sdh, "use SDH framing (default 0)"); + +static struct pci_device_id he_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_HE, PCI_ANY_ID, PCI_ANY_ID, + 0, 0, 0 }, + { 0, } +}; + +static struct pci_driver he_driver = { + .name = "he", + .probe = he_init_one, + .remove = __devexit_p(he_remove_one), + .id_table = he_pci_tbl, +}; + +static int __init he_init(void) +{ + return pci_module_init(&he_driver); +} + +static void __exit he_cleanup(void) +{ + pci_unregister_driver(&he_driver); +} + +module_init(he_init); +module_exit(he_cleanup); diff -urN linux-2.4.21/drivers/atm/he.h linux-2.4.22/drivers/atm/he.h --- linux-2.4.21/drivers/atm/he.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/atm/he.h 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,938 @@ +/* $Id: he.h,v 1.4 2003/05/06 22:48:00 chas Exp $ */ + +/* + + he.h + + ForeRunnerHE ATM Adapter driver for ATM on Linux + Copyright (C) 1999-2001 Naval Research Laboratory + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + + he.h + + ForeRunnerHE ATM Adapter driver for ATM on Linux + Copyright (C) 1999-2000 Naval Research Laboratory + + Permission to use, copy, modify and distribute this software and its + documentation is hereby granted, provided that both the copyright + notice and this permission notice appear in all copies of the software, + derivative works or modified versions, and any portions thereof, and + that both notices appear in supporting documentation. + + NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER + RESULTING FROM THE USE OF THIS SOFTWARE. + + */ + +#ifndef _HE_H_ +#define _HE_H_ + +#define DEV_LABEL "he" + +#define CONFIG_DEFAULT_VCIBITS 12 +#define CONFIG_DEFAULT_VPIBITS 0 + +#define CONFIG_IRQ_SIZE 128 +#define CONFIG_IRQ_THRESH (CONFIG_IRQ_SIZE/2) + +#define CONFIG_NUMTPDS 256 + +#define CONFIG_TPDRQ_SIZE 512 +#define TPDRQ_MASK(x) (((unsigned long)(x))&((CONFIG_TPDRQ_SIZE<<3)-1)) + +#define CONFIG_RBRQ_SIZE 512 +#define CONFIG_RBRQ_THRESH 400 +#define RBRQ_MASK(x) (((unsigned long)(x))&((CONFIG_RBRQ_SIZE<<3)-1)) + +#define CONFIG_TBRQ_SIZE 512 +#define CONFIG_TBRQ_THRESH 400 +#define TBRQ_MASK(x) (((unsigned long)(x))&((CONFIG_TBRQ_SIZE<<2)-1)) + +#define CONFIG_RBPL_SIZE 512 +#define CONFIG_RBPL_THRESH 64 +#define CONFIG_RBPL_BUFSIZE 4096 +#define RBPL_MASK(x) (((unsigned long)(x))&((CONFIG_RBPL_SIZE<<3)-1)) + +#define CONFIG_RBPS_SIZE 1024 +#define CONFIG_RBPS_THRESH 64 +#define CONFIG_RBPS_BUFSIZE 128 +#define RBPS_MASK(x) (((unsigned long)(x))&((CONFIG_RBPS_SIZE<<3)-1)) + +/* 5.1.3 initialize connection memory */ + +#define CONFIG_RSRA 0x00000 +#define CONFIG_RCMLBM 0x08000 +#define CONFIG_RCMABR 0x0d800 +#define CONFIG_RSRB 0x0e000 + +#define CONFIG_TSRA 0x00000 +#define CONFIG_TSRB 0x08000 +#define CONFIG_TSRC 0x0c000 +#define CONFIG_TSRD 0x0e000 +#define CONFIG_TMABR 0x0f000 +#define CONFIG_TPDBA 0x10000 + +#define HE_MAXCIDBITS 12 + +/* 2.9.3.3 interrupt encodings */ + +struct he_irq { + volatile u32 isw; +}; + +#define IRQ_ALIGNMENT 0x1000 + +#define NEXT_ENTRY(base, tail, mask) \ + (((unsigned long)base)|(((unsigned long)(tail+1))&mask)) + +#define ITYPE_INVALID 0xffffffff +#define ITYPE_TBRQ_THRESH (0<<3) +#define ITYPE_TPD_COMPLETE (1<<3) +#define ITYPE_RBPS_THRESH (2<<3) +#define ITYPE_RBPL_THRESH (3<<3) +#define ITYPE_RBRQ_THRESH (4<<3) +#define ITYPE_RBRQ_TIMER (5<<3) +#define ITYPE_PHY (6<<3) +#define ITYPE_OTHER 0x80 +#define ITYPE_PARITY 0x81 +#define ITYPE_ABORT 0x82 + +#define ITYPE_GROUP(x) (x & 0x7) +#define ITYPE_TYPE(x) (x & 0xf8) + +#define HE_NUM_GROUPS 8 + +/* 2.1.4 transmit packet descriptor */ + +struct he_tpd { + + /* read by the adapter */ + + volatile u32 status; + volatile u32 reserved; + +#define TPD_MAXIOV 3 + struct { + u32 addr, len; + } iovec[TPD_MAXIOV]; + +#define address0 iovec[0].addr +#define length0 iovec[0].len + + /* linux-atm extensions */ + + struct sk_buff *skb; + struct atm_vcc *vcc; + +#ifdef USE_TPD_POOL + struct list_head entry; +#else + u32 inuse; + char padding[32 - sizeof(u32) - (2*sizeof(void*))]; +#endif +}; + +#define TPD_ALIGNMENT 64 +#define TPD_LEN_MASK 0xffff + +#define TPD_ADDR_SHIFT 6 +#define TPD_MASK 0xffffffc0 +#define TPD_ADDR(x) ((x) & TPD_MASK) +#define TPD_INDEX(x) (TPD_ADDR(x) >> TPD_ADDR_SHIFT) + + +/* table 2.3 transmit buffer return elements */ + +struct he_tbrq { + volatile u32 tbre; +}; + +#define TBRQ_ALIGNMENT CONFIG_TBRQ_SIZE + +#define TBRQ_TPD(tbrq) ((tbrq)->tbre & 0xffffffc0) +#define TBRQ_EOS(tbrq) ((tbrq)->tbre & (1<<3)) +#define TBRQ_MULTIPLE(tbrq) ((tbrq)->tbre & (1)) + +/* table 2.21 receive buffer return queue element field organization */ + +struct he_rbrq { + volatile u32 addr; + volatile u32 cidlen; +}; + +#define RBRQ_ALIGNMENT CONFIG_RBRQ_SIZE + +#define RBRQ_ADDR(rbrq) ((rbrq)->addr & 0xffffffc0) +#define RBRQ_CRC_ERR(rbrq) ((rbrq)->addr & (1<<5)) +#define RBRQ_LEN_ERR(rbrq) ((rbrq)->addr & (1<<4)) +#define RBRQ_END_PDU(rbrq) ((rbrq)->addr & (1<<3)) +#define RBRQ_AAL5_PROT(rbrq) ((rbrq)->addr & (1<<2)) +#define RBRQ_CON_CLOSED(rbrq) ((rbrq)->addr & (1<<1)) +#define RBRQ_HBUF_ERR(rbrq) ((rbrq)->addr & 1) +#define RBRQ_CID(rbrq) (((rbrq)->cidlen >> 16) & 0x1fff) +#define RBRQ_BUFLEN(rbrq) ((rbrq)->cidlen & 0xffff) + +/* figure 2.3 transmit packet descriptor ready queue */ + +struct he_tpdrq { + volatile u32 tpd; + volatile u32 cid; +}; + +#define TPDRQ_ALIGNMENT CONFIG_TPDRQ_SIZE + +/* table 2.30 host status page detail */ + +#define HSP_ALIGNMENT 0x400 /* must align on 1k boundary */ + +struct he_hsp { + struct he_hsp_entry { + volatile u32 tbrq_tail; + volatile u32 reserved1[15]; + volatile u32 rbrq_tail; + volatile u32 reserved2[15]; + } group[HE_NUM_GROUPS]; +}; + +/* figure 2.9 receive buffer pools */ + +struct he_rbp { + volatile u32 phys; + volatile u32 status; +}; + +/* NOTE: it is suggested that virt be the virtual address of the host + buffer. on a 64-bit machine, this would not work. Instead, we + store the real virtual address in another list, and store an index + (and buffer status) in the virt member. +*/ + +#define RBP_INDEX_OFF 6 +#define RBP_INDEX(x) (((long)(x) >> RBP_INDEX_OFF) & 0xffff) +#define RBP_LOANED 0x80000000 +#define RBP_SMALLBUF 0x40000000 + +struct he_virt { + void *virt; +}; + +#define RBPL_ALIGNMENT CONFIG_RBPL_SIZE +#define RBPS_ALIGNMENT CONFIG_RBPS_SIZE + +#ifdef notyet +struct he_group { + u32 rpbs_size, rpbs_qsize; + struct he_rbp rbps_ba; + + u32 rpbl_size, rpbl_qsize; + struct he_rpb_entry *rbpl_ba; +}; +#endif + +#define HE_LOOKUP_VCC(dev, cid) ((dev)->he_vcc_table[(cid)].vcc) + +struct he_vcc_table +{ + struct atm_vcc *vcc; +}; + +struct he_cs_stper +{ + long pcr; + int inuse; +}; + +#define HE_NUM_CS_STPER 16 + +struct he_dev { + unsigned int number; + unsigned int irq; + unsigned long membase; + + char prod_id[30]; + char mac_addr[6]; + int media; /* + * 0x26 = HE155 MM + * 0x27 = HE622 MM + * 0x46 = HE155 SM + * 0x47 = HE622 SM + */ + + + unsigned int vcibits, vpibits; + unsigned int cells_per_row; + unsigned int bytes_per_row; + unsigned int cells_per_lbuf; + unsigned int r0_numrows, r0_startrow, r0_numbuffs; + unsigned int r1_numrows, r1_startrow, r1_numbuffs; + unsigned int tx_numrows, tx_startrow, tx_numbuffs; + unsigned int buffer_limit; + + struct he_vcc_table *he_vcc_table; + +#ifdef notyet + struct he_group group[HE_NUM_GROUPS]; +#endif + struct he_cs_stper cs_stper[HE_NUM_CS_STPER]; + unsigned total_bw; + + dma_addr_t irq_phys; + struct he_irq *irq_base, *irq_head, *irq_tail; + volatile unsigned *irq_tailoffset; + int irq_peak; + +#ifdef USE_TASKLET + struct tasklet_struct tasklet; +#endif +#ifdef USE_TPD_POOL + struct pci_pool *tpd_pool; + struct list_head outstanding_tpds; +#else + struct he_tpd *tpd_head, *tpd_base, *tpd_end; + dma_addr_t tpd_base_phys; +#endif + + dma_addr_t tpdrq_phys; + struct he_tpdrq *tpdrq_base, *tpdrq_tail, *tpdrq_head; + + spinlock_t global_lock; /* 8.1.5 pci transaction ordering + error problem */ + dma_addr_t rbrq_phys; + struct he_rbrq *rbrq_base, *rbrq_head; + int rbrq_peak; + +#ifdef USE_RBPL_POOL + struct pci_pool *rbpl_pool; +#else + void *rbpl_pages; + dma_addr_t rbpl_pages_phys; +#endif + dma_addr_t rbpl_phys; + struct he_rbp *rbpl_base, *rbpl_tail; + struct he_virt *rbpl_virt; + int rbpl_peak; + +#ifdef USE_RBPS +#ifdef USE_RBPS_POOL + struct pci_pool *rbps_pool; +#else + void *rbps_pages; + dma_addr_t rbps_pages_phys; +#endif +#endif + dma_addr_t rbps_phys; + struct he_rbp *rbps_base, *rbps_tail; + struct he_virt *rbps_virt; + int rbps_peak; + + dma_addr_t tbrq_phys; + struct he_tbrq *tbrq_base, *tbrq_head; + int tbrq_peak; + + dma_addr_t hsp_phys; + struct he_hsp *hsp; + + struct pci_dev *pci_dev; + struct atm_dev *atm_dev; + struct he_dev *next; +}; + +struct he_iovec +{ + u32 iov_base; + u32 iov_len; +}; + +#define HE_MAXIOV 20 + +struct he_vcc +{ + struct he_iovec iov_head[HE_MAXIOV]; + struct he_iovec *iov_tail; + int pdu_len; + + int rc_index; + + wait_queue_head_t rx_waitq; + wait_queue_head_t tx_waitq; +}; + +#define HE_VCC(vcc) ((struct he_vcc *)(vcc->dev_data)) + +#define PCI_VENDOR_ID_FORE 0x1127 +#define PCI_DEVICE_ID_FORE_HE 0x400 + +#define HE_DMA_MASK 0xffffffff + +#define GEN_CNTL_0 0x40 +#define INT_PROC_ENBL (1<<25) +#define SLAVE_ENDIAN_MODE (1<<16) +#define MRL_ENB (1<<5) +#define MRM_ENB (1<<4) +#define INIT_ENB (1<<2) +#define IGNORE_TIMEOUT (1<<1) +#define ENBL_64 (1<<0) + +#define MIN_PCI_LATENCY 32 /* errata 8.1.3 */ + +#define HE_DEV(dev) ((struct he_dev *) (dev)->dev_data) + +#define he_is622(dev) ((dev)->media & 0x1) + +#define HE_REGMAP_SIZE 0x100000 + +#define RESET_CNTL 0x80000 +#define BOARD_RST_STATUS (1<<6) + +#define HOST_CNTL 0x80004 +#define PCI_BUS_SIZE64 (1<<27) +#define DESC_RD_STATIC_64 (1<<26) +#define DATA_RD_STATIC_64 (1<<25) +#define DATA_WR_STATIC_64 (1<<24) +#define ID_CS (1<<12) +#define ID_WREN (1<<11) +#define ID_DOUT (1<<10) +#define ID_DOFFSET 10 +#define ID_DIN (1<<9) +#define ID_CLOCK (1<<8) +#define QUICK_RD_RETRY (1<<7) +#define QUICK_WR_RETRY (1<<6) +#define OUTFF_ENB (1<<5) +#define CMDFF_ENB (1<<4) +#define PERR_INT_ENB (1<<2) +#define IGNORE_INTR (1<<0) + +#define LB_SWAP 0x80008 +#define SWAP_RNUM_MAX(x) (x<<27) +#define DATA_WR_SWAP (1<<20) +#define DESC_RD_SWAP (1<<19) +#define DATA_RD_SWAP (1<<18) +#define INTR_SWAP (1<<17) +#define DESC_WR_SWAP (1<<16) +#define SDRAM_INIT (1<<15) +#define BIG_ENDIAN_HOST (1<<14) +#define XFER_SIZE (1<<7) + +#define LB_MEM_ADDR 0x8000c +#define LB_MEM_DATA 0x80010 + +#define LB_MEM_ACCESS 0x80014 +#define LB_MEM_HNDSHK (1<<30) +#define LM_MEM_WRITE (0x7) +#define LM_MEM_READ (0x3) + +#define SDRAM_CTL 0x80018 +#define LB_64_ENB (1<<3) +#define LB_TWR (1<<2) +#define LB_TRP (1<<1) +#define LB_TRAS (1<<0) + +#define INT_FIFO 0x8001c +#define INT_MASK_D (1<<15) +#define INT_MASK_C (1<<14) +#define INT_MASK_B (1<<13) +#define INT_MASK_A (1<<12) +#define INT_CLEAR_D (1<<11) +#define INT_CLEAR_C (1<<10) +#define INT_CLEAR_B (1<<9) +#define INT_CLEAR_A (1<<8) + +#define ABORT_ADDR 0x80020 + +#define IRQ0_BASE 0x80080 +#define IRQ_BASE(x) (x<<12) +#define IRQ_MASK ((CONFIG_IRQ_SIZE<<2)-1) /* was 0x3ff */ +#define IRQ_TAIL(x) (((unsigned long)(x)) & IRQ_MASK) +#define IRQ0_HEAD 0x80084 +#define IRQ_SIZE(x) (x<<22) +#define IRQ_THRESH(x) (x<<12) +#define IRQ_HEAD(x) (x<<2) +/* #define IRQ_PENDING (1) conflict with linux/irq.h */ +#define IRQ0_CNTL 0x80088 +#define IRQ_ADDRSEL(x) (x<<2) +#define IRQ_INT_A (0<<2) +#define IRQ_INT_B (1<<2) +#define IRQ_INT_C (2<<2) +#define IRQ_INT_D (3<<2) +#define IRQ_TYPE_ADDR 0x1 +#define IRQ_TYPE_LINE 0x0 +#define IRQ0_DATA 0x8008c + +#define IRQ1_BASE 0x80090 +#define IRQ1_HEAD 0x80094 +#define IRQ1_CNTL 0x80098 +#define IRQ1_DATA 0x8009c + +#define IRQ2_BASE 0x800a0 +#define IRQ2_HEAD 0x800a4 +#define IRQ2_CNTL 0x800a8 +#define IRQ2_DATA 0x800ac + +#define IRQ3_BASE 0x800b0 +#define IRQ3_HEAD 0x800b4 +#define IRQ3_CNTL 0x800b8 +#define IRQ3_DATA 0x800bc + +#define GRP_10_MAP 0x800c0 +#define GRP_32_MAP 0x800c4 +#define GRP_54_MAP 0x800c8 +#define GRP_76_MAP 0x800cc + +#define G0_RBPS_S 0x80400 +#define G0_RBPS_T 0x80404 +#define RBP_TAIL(x) ((x)<<3) +#define RBP_MASK(x) ((x)|0x1fff) +#define G0_RBPS_QI 0x80408 +#define RBP_QSIZE(x) ((x)<<14) +#define RBP_INT_ENB (1<<13) +#define RBP_THRESH(x) (x) +#define G0_RBPS_BS 0x8040c +#define G0_RBPL_S 0x80410 +#define G0_RBPL_T 0x80414 +#define G0_RBPL_QI 0x80418 +#define G0_RBPL_BS 0x8041c + +#define G1_RBPS_S 0x80420 +#define G1_RBPS_T 0x80424 +#define G1_RBPS_QI 0x80428 +#define G1_RBPS_BS 0x8042c +#define G1_RBPL_S 0x80430 +#define G1_RBPL_T 0x80434 +#define G1_RBPL_QI 0x80438 +#define G1_RBPL_BS 0x8043c + +#define G2_RBPS_S 0x80440 +#define G2_RBPS_T 0x80444 +#define G2_RBPS_QI 0x80448 +#define G2_RBPS_BS 0x8044c +#define G2_RBPL_S 0x80450 +#define G2_RBPL_T 0x80454 +#define G2_RBPL_QI 0x80458 +#define G2_RBPL_BS 0x8045c + +#define G3_RBPS_S 0x80460 +#define G3_RBPS_T 0x80464 +#define G3_RBPS_QI 0x80468 +#define G3_RBPS_BS 0x8046c +#define G3_RBPL_S 0x80470 +#define G3_RBPL_T 0x80474 +#define G3_RBPL_QI 0x80478 +#define G3_RBPL_BS 0x8047c + +#define G4_RBPS_S 0x80480 +#define G4_RBPS_T 0x80484 +#define G4_RBPS_QI 0x80488 +#define G4_RBPS_BS 0x8048c +#define G4_RBPL_S 0x80490 +#define G4_RBPL_T 0x80494 +#define G4_RBPL_QI 0x80498 +#define G4_RBPL_BS 0x8049c + +#define G5_RBPS_S 0x804a0 +#define G5_RBPS_T 0x804a4 +#define G5_RBPS_QI 0x804a8 +#define G5_RBPS_BS 0x804ac +#define G5_RBPL_S 0x804b0 +#define G5_RBPL_T 0x804b4 +#define G5_RBPL_QI 0x804b8 +#define G5_RBPL_BS 0x804bc + +#define G6_RBPS_S 0x804c0 +#define G6_RBPS_T 0x804c4 +#define G6_RBPS_QI 0x804c8 +#define G6_RBPS_BS 0x804cc +#define G6_RBPL_S 0x804d0 +#define G6_RBPL_T 0x804d4 +#define G6_RBPL_QI 0x804d8 +#define G6_RBPL_BS 0x804dc + +#define G7_RBPS_S 0x804e0 +#define G7_RBPS_T 0x804e4 +#define G7_RBPS_QI 0x804e8 +#define G7_RBPS_BS 0x804ec + +#define G7_RBPL_S 0x804f0 +#define G7_RBPL_T 0x804f4 +#define G7_RBPL_QI 0x804f8 +#define G7_RBPL_BS 0x804fc + +#define G0_RBRQ_ST 0x80500 +#define G0_RBRQ_H 0x80504 +#define G0_RBRQ_Q 0x80508 +#define RBRQ_THRESH(x) ((x)<<13) +#define RBRQ_SIZE(x) (x) +#define G0_RBRQ_I 0x8050c +#define RBRQ_TIME(x) ((x)<<8) +#define RBRQ_COUNT(x) (x) + +/* fill in 1 ... 7 later */ + +#define G0_TBRQ_B_T 0x80600 +#define G0_TBRQ_H 0x80604 +#define G0_TBRQ_S 0x80608 +#define G0_TBRQ_THRESH 0x8060c +#define TBRQ_THRESH(x) (x) + +/* fill in 1 ... 7 later */ + +#define RH_CONFIG 0x805c0 +#define PHY_INT_ENB (1<<10) +#define OAM_GID(x) (x<<7) +#define PTMR_PRE(x) (x) + +#define G0_INMQ_S 0x80580 +#define G0_INMQ_L 0x80584 +#define G1_INMQ_S 0x80588 +#define G1_INMQ_L 0x8058c +#define G2_INMQ_S 0x80590 +#define G2_INMQ_L 0x80594 +#define G3_INMQ_S 0x80598 +#define G3_INMQ_L 0x8059c +#define G4_INMQ_S 0x805a0 +#define G4_INMQ_L 0x805a4 +#define G5_INMQ_S 0x805a8 +#define G5_INMQ_L 0x805ac +#define G6_INMQ_S 0x805b0 +#define G6_INMQ_L 0x805b4 +#define G7_INMQ_S 0x805b8 +#define G7_INMQ_L 0x805bc + +#define TPDRQ_B_H 0x80680 +#define TPDRQ_T 0x80684 +#define TPDRQ_S 0x80688 + +#define UBUFF_BA 0x8068c + +#define RLBF0_H 0x806c0 +#define RLBF0_T 0x806c4 +#define RLBF1_H 0x806c8 +#define RLBF1_T 0x806cc +#define RLBC_H 0x806d0 +#define RLBC_T 0x806d4 +#define RLBC_H2 0x806d8 +#define TLBF_H 0x806e0 +#define TLBF_T 0x806e4 +#define RLBF0_C 0x806e8 +#define RLBF1_C 0x806ec +#define RXTHRSH 0x806f0 +#define LITHRSH 0x806f4 + +#define LBARB 0x80700 +#define SLICE_X(x) (x<<28) +#define ARB_RNUM_MAX(x) (x<<23) +#define TH_PRTY(x) (x<<21) +#define RH_PRTY(x) (x<<19) +#define TL_PRTY(x) (x<<17) +#define RL_PRTY(x) (x<<15) +#define BUS_MULTI(x) (x<<8) +#define NET_PREF(x) (x) + +#define SDRAMCON 0x80704 +#define BANK_ON (1<<14) +#define WIDE_DATA (1<<13) +#define TWR_WAIT (1<<12) +#define TRP_WAIT (1<<11) +#define TRAS_WAIT (1<<10) +#define REF_RATE(x) (x) + +#define LBSTAT 0x80708 + +#define RCC_STAT 0x8070c +#define RCC_BUSY (1) + +#define TCMCONFIG 0x80740 +#define TM_DESL2 (1<<10) +#define TM_BANK_WAIT(x) (x<<6) +#define TM_ADD_BANK4(x) (x<<4) +#define TM_PAR_CHECK(x) (x<<3) +#define TM_RW_WAIT(x) (x<<2) +#define TM_SRAM_TYPE(x) (x) + +#define TSRB_BA 0x80744 +#define TSRC_BA 0x80748 +#define TMABR_BA 0x8074c +#define TPD_BA 0x80750 +#define TSRD_BA 0x80758 + +#define TX_CONFIG 0x80760 +#define DRF_THRESH(x) (x<<22) +#define TX_UT_MODE(x) (x<<21) +#define TX_VCI_MASK(x) (x<<17) +#define LBFREE_CNT(x) (x) + +#define TXAAL5_PROTO 0x80764 +#define CPCS_UU(x) (x<<8) +#define CPI(x) (x) + +#define RCMCONFIG 0x80780 +#define RM_DESL2(x) (x<<10) +#define RM_BANK_WAIT(x) (x<<6) +#define RM_ADD_BANK(x) (x<<4) +#define RM_PAR_CHECK(x) (x<<3) +#define RM_RW_WAIT(x) (x<<2) +#define RM_SRAM_TYPE(x) (x) + +#define RCMRSRB_BA 0x80784 +#define RCMLBM_BA 0x80788 +#define RCMABR_BA 0x8078c + +#define RC_CONFIG 0x807c0 +#define UT_RD_DELAY(x) (x<<11) +#define WRAP_MODE(x) (x<<10) +#define RC_UT_MODE(x) (x<<9) +#define RX_ENABLE (1<<8) +#define RX_VALVP(x) (x<<4) +#define RX_VALVC(x) (x) + +#define MCC 0x807c4 +#define OEC 0x807c8 +#define DCC 0x807cc +#define CEC 0x807d0 + +#define HSP_BA 0x807f0 + +#define LB_CONFIG 0x807f4 +#define LB_SIZE(x) (x) + +#define CON_DAT 0x807f8 +#define CON_CTL 0x807fc +#define CON_CTL_MBOX (2<<30) +#define CON_CTL_TCM (1<<30) +#define CON_CTL_RCM (0<<30) +#define CON_CTL_WRITE (1<<29) +#define CON_CTL_READ (0<<29) +#define CON_CTL_BUSY (1<<28) +#define CON_BYTE_DISABLE_3 (1<<22) /* 24..31 */ +#define CON_BYTE_DISABLE_2 (1<<21) /* 16..23 */ +#define CON_BYTE_DISABLE_1 (1<<20) /* 8..15 */ +#define CON_BYTE_DISABLE_0 (1<<19) /* 0..7 */ +#define CON_CTL_ADDR(x) (x) + +#define FRAMER 0x80800 /* to 0x80bfc */ + +/* 3.3 network controller (internal) mailbox registers */ + +#define CS_STPER0 0x0 + /* ... */ +#define CS_STPER31 0x01f + +#define CS_STTIM0 0x020 + /* ... */ +#define CS_STTIM31 0x03f + +#define CS_TGRLD0 0x040 + /* ... */ +#define CS_TGRLD15 0x04f + +#define CS_ERTHR0 0x050 +#define CS_ERTHR1 0x051 +#define CS_ERTHR2 0x052 +#define CS_ERTHR3 0x053 +#define CS_ERTHR4 0x054 +#define CS_ERCTL0 0x055 +#define TX_ENABLE (1<<28) +#define ER_ENABLE (1<<27) +#define CS_ERCTL1 0x056 +#define CS_ERCTL2 0x057 +#define CS_ERSTAT0 0x058 +#define CS_ERSTAT1 0x059 + +#define CS_RTCCT 0x060 +#define CS_RTFWC 0x061 +#define CS_RTFWR 0x062 +#define CS_RTFTC 0x063 +#define CS_RTATR 0x064 + +#define CS_TFBSET 0x070 +#define CS_TFBADD 0x071 +#define CS_TFBSUB 0x072 +#define CS_WCRMAX 0x073 +#define CS_WCRMIN 0x074 +#define CS_WCRINC 0x075 +#define CS_WCRDEC 0x076 +#define CS_WCRCEIL 0x077 +#define CS_BWDCNT 0x078 + +#define CS_OTPPER 0x080 +#define CS_OTWPER 0x081 +#define CS_OTTLIM 0x082 +#define CS_OTTCNT 0x083 + +#define CS_HGRRT0 0x090 + /* ... */ +#define CS_HGRRT7 0x097 + +#define CS_ORPTRS 0x0a0 + +#define RXCON_CLOSE 0x100 + + +#define RCM_MEM_SIZE 0x10000 /* 1M of 32-bit registers */ +#define TCM_MEM_SIZE 0x20000 /* 2M of 32-bit registers */ + +/* 2.5 transmit connection memory registers */ + +#define TSR0_CONN_STATE(x) ((x>>28) & 0x7) +#define TSR0_USE_WMIN (1<<23) +#define TSR0_GROUP(x) ((x & 0x7)<<18) +#define TSR0_ABR (2<<16) +#define TSR0_UBR (1<<16) +#define TSR0_CBR (0<<16) +#define TSR0_PROT (1<<15) +#define TSR0_AAL0_SDU (2<<12) +#define TSR0_AAL0 (1<<12) +#define TSR0_AAL5 (0<<12) +#define TSR0_HALT_ER (1<<11) +#define TSR0_MARK_CI (1<<10) +#define TSR0_MARK_ER (1<<9) +#define TSR0_UPDATE_GER (1<<8) +#define TSR0_RC_INDEX(x) (x & 0x1F) + +#define TSR1_PCR(x) ((x & 0x7FFF)<<16) +#define TSR1_MCR(x) (x & 0x7FFF) + +#define TSR2_ACR(x) ((x & 0x7FFF)<<16) + +#define TSR3_NRM_CNT(x) ((x & 0xFF)<<24) +#define TSR3_CRM_CNT(x) (x & 0xFFFF) + +#define TSR4_FLUSH_CONN (1<<31) +#define TSR4_SESSION_ENDED (1<<30) +#define TSR4_CRC10 (1<<28) +#define TSR4_NULL_CRC10 (1<<27) +#define TSR4_PROT (1<<26) +#define TSR4_AAL0_SDU (2<<23) +#define TSR4_AAL0 (1<<23) +#define TSR4_AAL5 (0<<23) + +#define TSR9_OPEN_CONN (1<<20) + +#define TSR11_ICR(x) ((x & 0x7FFF)<<16) +#define TSR11_TRM(x) ((x & 0x7)<<13) +#define TSR11_NRM(x) ((x & 0x7)<<10) +#define TSR11_ADTF(x) (x & 0x3FF) + +#define TSR13_RDF(x) ((x & 0xF)<<23) +#define TSR13_RIF(x) ((x & 0xF)<<19) +#define TSR13_CDF(x) ((x & 0x7)<<16) +#define TSR13_CRM(x) (x & 0xFFFF) + +#define TSR14_DELETE (1<<31) +#define TSR14_ABR_CLOSE (1<<16) + +/* 2.7.1 per connection receieve state registers */ + +#define RSR0_START_PDU (1<<10) +#define RSR0_OPEN_CONN (1<<6) +#define RSR0_CLOSE_CONN (0<<6) +#define RSR0_PPD_ENABLE (1<<5) +#define RSR0_EPD_ENABLE (1<<4) +#define RSR0_TCP_CKSUM (1<<3) +#define RSR0_AAL5 (0) +#define RSR0_AAL0 (1) +#define RSR0_AAL0_SDU (2) +#define RSR0_RAWCELL (3) +#define RSR0_RAWCELL_CRC10 (4) + +#define RSR1_AQI_ENABLE (1<<20) +#define RSR1_RBPL_ONLY (1<<19) +#define RSR1_GROUP(x) ((x)<<16) + +#define RSR4_AQI_ENABLE (1<<30) +#define RSR4_GROUP(x) ((x)<<27) +#define RSR4_RBPL_ONLY (1<<26) + +/* 2.1.4 transmit packet descriptor */ + +#define TPD_USERCELL 0x0 +#define TPD_SEGMENT_OAMF5 0x4 +#define TPD_END2END_OAMF5 0x5 +#define TPD_RMCELL 0x6 +#define TPD_CELLTYPE(x) (x<<3) +#define TPD_EOS (1<<2) +#define TPD_CLP (1<<1) +#define TPD_INT (1<<0) +#define TPD_LST (1<<31) + +/* table 4.3 serial eeprom information */ + +#define PROD_ID 0x08 /* char[] */ +#define PROD_ID_LEN 30 +#define HW_REV 0x26 /* char[] */ +#define M_SN 0x3a /* integer */ +#define MEDIA 0x3e /* integer */ +#define HE155MM 0x26 +#define HE155SM 0x27 +#define HE622MM 0x46 +#define HE622SM 0x47 +#define MAC_ADDR 0x42 /* char[] */ + +#define CS_LOW 0x0 +#define CS_HIGH ID_CS /* HOST_CNTL_ID_PROM_SEL */ +#define CLK_LOW 0x0 +#define CLK_HIGH ID_CLOCK /* HOST_CNTL_ID_PROM_CLOCK */ +#define SI_HIGH ID_DIN /* HOST_CNTL_ID_PROM_DATA_IN */ +#define EEPROM_DELAY 400 /* microseconds */ + +/* Read from EEPROM = 0000 0011b */ +unsigned int readtab[] = { + CS_HIGH | CLK_HIGH, + CS_LOW | CLK_LOW, + CLK_HIGH, /* 0 */ + CLK_LOW, + CLK_HIGH, /* 0 */ + CLK_LOW, + CLK_HIGH, /* 0 */ + CLK_LOW, + CLK_HIGH, /* 0 */ + CLK_LOW, + CLK_HIGH, /* 0 */ + CLK_LOW, + CLK_HIGH, /* 0 */ + CLK_LOW | SI_HIGH, + CLK_HIGH | SI_HIGH, /* 1 */ + CLK_LOW | SI_HIGH, + CLK_HIGH | SI_HIGH /* 1 */ +}; + +/* Clock to read from/write to the EEPROM */ +unsigned int clocktab[] = { + CLK_LOW, + CLK_HIGH, + CLK_LOW, + CLK_HIGH, + CLK_LOW, + CLK_HIGH, + CLK_LOW, + CLK_HIGH, + CLK_LOW, + CLK_HIGH, + CLK_LOW, + CLK_HIGH, + CLK_LOW, + CLK_HIGH, + CLK_LOW, + CLK_HIGH, + CLK_LOW +}; + + +#endif /* _HE_H_ */ diff -urN linux-2.4.21/drivers/atm/horizon.c linux-2.4.22/drivers/atm/horizon.c --- linux-2.4.21/drivers/atm/horizon.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/atm/horizon.c 2003-08-25 04:44:41.000000000 -0700 @@ -1765,17 +1765,20 @@ { unsigned int tx_len = skb->len; - unsigned int tx_iovcnt = ATM_SKB(skb)->iovcnt; + unsigned int tx_iovcnt = skb_shinfo(skb)->nr_frags; // remember this so we can free it later dev->tx_skb = skb; if (tx_iovcnt) { // scatter gather transfer dev->tx_regions = tx_iovcnt; - dev->tx_iovec = (struct iovec *) skb->data; + dev->tx_iovec = 0; /* @@@ needs rewritten */ dev->tx_bytes = 0; PRINTD (DBG_TX|DBG_BUS, "TX start scatter-gather transfer (iovec %p, len %d)", skb->data, tx_len); + tx_release (dev); + hrz_kfree_skb (skb); + return -EIO; } else { // simple transfer dev->tx_regions = 0; diff -urN linux-2.4.21/drivers/atm/idt77252.c linux-2.4.22/drivers/atm/idt77252.c --- linux-2.4.21/drivers/atm/idt77252.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/atm/idt77252.c 2003-08-25 04:44:41.000000000 -0700 @@ -1988,7 +1988,7 @@ return -EINVAL; } - if (ATM_SKB(skb)->iovcnt != 0) { + if (skb_shinfo(skb)->nr_frags != 0) { printk("%s: No scatter-gather yet.\n", card->name); atomic_inc(&vcc->stats->tx_err); dev_kfree_skb(skb); @@ -2025,8 +2025,7 @@ atomic_inc(&vcc->stats->tx_err); return -ENOMEM; } - atomic_add(skb->truesize + ATM_PDU_OVHD, &vcc->sk->wmem_alloc); - ATM_SKB(skb)->iovcnt = 0; + atomic_add(skb->truesize, &vcc->sk->wmem_alloc); memcpy(skb_put(skb, 52), cell, 52); @@ -2405,8 +2404,10 @@ static int idt77252_find_vcc(struct atm_vcc *vcc, short *vpi, int *vci) { + unsigned long flags; struct atm_vcc *walk; + spin_lock_irqsave(&vcc->dev->lock, flags); if (*vpi == ATM_VPI_ANY) { *vpi = 0; walk = vcc->dev->vccs; @@ -2433,6 +2434,7 @@ } } + spin_unlock_irqrestore(&vcc->dev->lock, flags); return 0; } diff -urN linux-2.4.21/drivers/atm/iphase.c linux-2.4.22/drivers/atm/iphase.c --- linux-2.4.21/drivers/atm/iphase.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/atm/iphase.c 2003-08-25 04:44:41.000000000 -0700 @@ -1186,7 +1186,6 @@ skb_put(skb,len); // pwang_test ATM_SKB(skb)->vcc = vcc; - ATM_SKB(skb)->iovcnt = 0; ATM_DESC(skb) = desc; skb_queue_tail(&iadev->rx_dma_q, skb); @@ -2827,11 +2826,15 @@ break; case MEMDUMP_FFL: { - ia_regs_t regs_local; - ffredn_t *ffL = ®s_local.ffredn; - rfredn_t *rfL = ®s_local.rfredn; + ia_regs_t *regs_local; + ffredn_t *ffL; + rfredn_t *rfL; if (!capable(CAP_NET_ADMIN)) return -EPERM; + regs_local = kmalloc(sizeof(*regs_local), GFP_KERNEL); + if (!regs_local) return -ENOMEM; + ffL = ®s_local->ffredn; + rfL = ®s_local->rfredn; /* Copy real rfred registers into the local copy */ for (i=0; i<(sizeof (rfredn_t))/4; i++) ((u_int *)rfL)[i] = ((u_int *)iadev->reass_reg)[i] & 0xffff; @@ -2839,8 +2842,11 @@ for (i=0; i<(sizeof (ffredn_t))/4; i++) ((u_int *)ffL)[i] = ((u_int *)iadev->seg_reg)[i] & 0xffff; - if (copy_to_user(ia_cmds.buf, ®s_local,sizeof(ia_regs_t))) + if (copy_to_user(ia_cmds.buf, regs_local,sizeof(ia_regs_t))) { + kfree(regs_local); return -EFAULT; + } + kfree(regs_local); printk("Board %d registers dumped\n", board); ia_cmds.status = 0; } @@ -2965,7 +2971,7 @@ dev_kfree_skb_any(skb); return 0; } - kfree(skb); + dev_kfree_skb_any(skb); skb = newskb; } /* Get a descriptor number from our free descriptor queue diff -urN linux-2.4.21/drivers/atm/lanai.c linux-2.4.22/drivers/atm/lanai.c --- linux-2.4.21/drivers/atm/lanai.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/atm/lanai.c 2003-08-25 04:44:41.000000000 -0700 @@ -2842,7 +2842,6 @@ phy_get: NULL, feedback: NULL, change_qos: lanai_change_qos, - free_rx_skb: NULL, proc_read: lanai_proc_read }; diff -urN linux-2.4.21/drivers/atm/nicstar.c linux-2.4.22/drivers/atm/nicstar.c --- linux-2.4.21/drivers/atm/nicstar.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/atm/nicstar.c 2003-08-25 04:44:41.000000000 -0700 @@ -941,9 +941,14 @@ return error; } - if (ns_parse_mac(mac[i], card->atmdev->esi)) + if (ns_parse_mac(mac[i], card->atmdev->esi)) { nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET, card->atmdev->esi, 6); + if (memcmp(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00", 6) == 0) { + nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT, + card->atmdev->esi, 6); + } + } printk("nicstar%d: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", i, card->atmdev->esi[0], card->atmdev->esi[1], card->atmdev->esi[2], @@ -1659,9 +1664,9 @@ card->index); iovb = vc->rx_iov; recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, - ATM_SKB(iovb)->iovcnt); - ATM_SKB(iovb)->iovcnt = 0; - ATM_SKB(iovb)->vcc = NULL; + NS_SKB(iovb)->iovcnt); + NS_SKB(iovb)->iovcnt = 0; + NS_SKB(iovb)->vcc = NULL; ns_grab_int_lock(card, flags); recycle_iov_buf(card, iovb); spin_unlock_irqrestore(&card->int_lock, flags); @@ -1859,7 +1864,7 @@ return -EINVAL; } - if (ATM_SKB(skb)->iovcnt != 0) + if (skb_shinfo(skb)->nr_frags != 0) { printk("nicstar%d: No scatter-gather yet.\n", card->index); atomic_inc(&vcc->stats->tx_err); @@ -2284,30 +2289,30 @@ } } vc->rx_iov = iovb; - ATM_SKB(iovb)->iovcnt = 0; + NS_SKB(iovb)->iovcnt = 0; iovb->len = 0; iovb->tail = iovb->data = iovb->head; - ATM_SKB(iovb)->vcc = vcc; + NS_SKB(iovb)->vcc = vcc; /* IMPORTANT: a pointer to the sk_buff containing the small or large buffer is stored as iovec base, NOT a pointer to the small or large buffer itself. */ } - else if (ATM_SKB(iovb)->iovcnt >= NS_MAX_IOVECS) + else if (NS_SKB(iovb)->iovcnt >= NS_MAX_IOVECS) { printk("nicstar%d: received too big AAL5 SDU.\n", card->index); atomic_inc(&vcc->stats->rx_err); recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, NS_MAX_IOVECS); - ATM_SKB(iovb)->iovcnt = 0; + NS_SKB(iovb)->iovcnt = 0; iovb->len = 0; iovb->tail = iovb->data = iovb->head; - ATM_SKB(iovb)->vcc = vcc; + NS_SKB(iovb)->vcc = vcc; } - iov = &((struct iovec *) iovb->data)[ATM_SKB(iovb)->iovcnt++]; + iov = &((struct iovec *) iovb->data)[NS_SKB(iovb)->iovcnt++]; iov->iov_base = (void *) skb; iov->iov_len = ns_rsqe_cellcount(rsqe) * 48; iovb->len += iov->iov_len; - if (ATM_SKB(iovb)->iovcnt == 1) + if (NS_SKB(iovb)->iovcnt == 1) { if (skb->list != &card->sbpool.queue) { @@ -2321,7 +2326,7 @@ return; } } - else /* ATM_SKB(iovb)->iovcnt >= 2 */ + else /* NS_SKB(iovb)->iovcnt >= 2 */ { if (skb->list != &card->lbpool.queue) { @@ -2330,7 +2335,7 @@ which_list(card, skb); atomic_inc(&vcc->stats->rx_err); recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, - ATM_SKB(iovb)->iovcnt); + NS_SKB(iovb)->iovcnt); vc->rx_iov = NULL; recycle_iov_buf(card, iovb); return; @@ -2354,7 +2359,7 @@ printk(".\n"); atomic_inc(&vcc->stats->rx_err); recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, - ATM_SKB(iovb)->iovcnt); + NS_SKB(iovb)->iovcnt); vc->rx_iov = NULL; recycle_iov_buf(card, iovb); return; @@ -2362,7 +2367,7 @@ /* By this point we (hopefully) have a complete SDU without errors. */ - if (ATM_SKB(iovb)->iovcnt == 1) /* Just a small buffer */ + if (NS_SKB(iovb)->iovcnt == 1) /* Just a small buffer */ { /* skb points to a small buffer */ if (!atm_charge(vcc, skb->truesize)) @@ -2384,7 +2389,7 @@ atomic_inc(&vcc->stats->rx); } } - else if (ATM_SKB(iovb)->iovcnt == 2) /* One small plus one large buffer */ + else if (NS_SKB(iovb)->iovcnt == 2) /* One small plus one large buffer */ { struct sk_buff *sb; @@ -2461,7 +2466,7 @@ printk("nicstar%d: Out of huge buffers.\n", card->index); atomic_inc(&vcc->stats->rx_drop); recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, - ATM_SKB(iovb)->iovcnt); + NS_SKB(iovb)->iovcnt); vc->rx_iov = NULL; recycle_iov_buf(card, iovb); return; @@ -2499,7 +2504,7 @@ if (!atm_charge(vcc, hb->truesize)) { - recycle_iovec_rx_bufs(card, iov, ATM_SKB(iovb)->iovcnt); + recycle_iovec_rx_bufs(card, iov, NS_SKB(iovb)->iovcnt); if (card->hbpool.count < card->hbnr.max) { skb_queue_tail(&card->hbpool.queue, hb); @@ -2522,7 +2527,7 @@ 0, 0); /* Copy all large buffers to the huge buffer and free them */ - for (j = 1; j < ATM_SKB(iovb)->iovcnt; j++) + for (j = 1; j < NS_SKB(iovb)->iovcnt; j++) { lb = (struct sk_buff *) iov->iov_base; tocopy = MIN(remaining, iov->iov_len); diff -urN linux-2.4.21/drivers/atm/nicstar.h linux-2.4.22/drivers/atm/nicstar.h --- linux-2.4.21/drivers/atm/nicstar.h 2001-10-25 13:53:46.000000000 -0700 +++ linux-2.4.22/drivers/atm/nicstar.h 2003-08-25 04:44:41.000000000 -0700 @@ -96,6 +96,7 @@ /* ESI stuff ******************************************************************/ #define NICSTAR_EPROM_MAC_ADDR_OFFSET 0x6C +#define NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT 0xF6 /* #defines *******************************************************************/ @@ -749,6 +750,15 @@ } vc_map; +struct ns_skb_data +{ + struct atm_vcc *vcc; + int iovcnt; +}; + +#define NS_SKB(skb) (((struct ns_skb_data *) (skb)->cb)) + + typedef struct ns_dev { int index; /* Card ID to the device driver */ diff -urN linux-2.4.21/drivers/atm/zatm.c linux-2.4.22/drivers/atm/zatm.c --- linux-2.4.21/drivers/atm/zatm.c 2001-09-14 14:40:00.000000000 -0700 +++ linux-2.4.22/drivers/atm/zatm.c 2003-08-25 04:44:41.000000000 -0700 @@ -827,10 +827,10 @@ vcc = ATM_SKB(skb)->vcc; zatm_dev = ZATM_DEV(vcc->dev); zatm_vcc = ZATM_VCC(vcc); - EVENT("iovcnt=%d\n",ATM_SKB(skb)->iovcnt,0); + EVENT("iovcnt=%d\n",skb_shinfo(skb)->nr_frags,0); save_flags(flags); cli(); - if (!ATM_SKB(skb)->iovcnt) { + if (!skb_shinfo(skb)->nr_frags) { if (zatm_vcc->txing == RING_ENTRIES-1) { restore_flags(flags); return RING_BUSY; diff -urN linux-2.4.21/drivers/block/cciss.c linux-2.4.22/drivers/block/cciss.c --- linux-2.4.21/drivers/block/cciss.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/block/cciss.c 2003-08-25 04:44:41.000000000 -0700 @@ -44,12 +44,12 @@ #include #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -#define DRIVER_NAME "HP CISS Driver (v 2.4.42)" -#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,42) +#define DRIVER_NAME "HP CISS Driver (v 2.4.47)" +#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,47) /* Embedded module documentation macros - see modules.h */ -MODULE_AUTHOR("Charles M. White III - Hewlett-Packard Company"); -MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.42"); +MODULE_AUTHOR("Hewlett-Packard Company"); +MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.47"); MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"); MODULE_LICENSE("GPL"); @@ -73,6 +73,8 @@ 0x0E11, 0x409B, 0, 0, 0}, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409C, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x409D, 0, 0, 0}, {0,} }; MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); @@ -91,10 +93,12 @@ { 0x409A0E11, "Smart Array 641", &SA5_access}, { 0x409B0E11, "Smart Array 642", &SA5_access}, { 0x409C0E11, "Smart Array 6400", &SA5_access}, + { 0x409D0E11, "Smart Array 6400 EM", &SA5_access}, }; /* How long to wait (in millesconds) for board to go into simple mode */ -#define MAX_CONFIG_WAIT 1000 +#define MAX_CONFIG_WAIT 30000 +#define MAX_IOCTL_CONFIG_WAIT 1000 /*define how many times we will try a command because of bus resets */ #define MAX_CMD_RETRIES 3 @@ -103,7 +107,7 @@ #define NR_CMDS 128 /* #commands that can be outstanding */ #define MAX_CTLR 8 -#define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */ +#define CCISS_DMA_MASK 0xFFFFFFFFFFFFFFFF /* 64 bit DMA */ static ctlr_info_t *hba[MAX_CTLR]; @@ -578,7 +582,7 @@ &(c->cfgtable->HostWrite.CoalIntCount)); writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); - for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; @@ -586,8 +590,11 @@ udelay(1000); } spin_unlock_irqrestore(&io_request_lock, flags); - if (i >= MAX_CONFIG_WAIT) - return -EFAULT; + if (i >= MAX_IOCTL_CONFIG_WAIT) + /* there is an unlikely case where this can happen, + * involving hot replacing a failed 144 GB drive in a + * RAID 5 set just as we attempt this ioctl. */ + return -EAGAIN; return 0; } case CCISS_GETNODENAME: @@ -627,7 +634,7 @@ writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); - for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; @@ -635,8 +642,11 @@ udelay(1000); } spin_unlock_irqrestore(&io_request_lock, flags); - if (i >= MAX_CONFIG_WAIT) - return -EFAULT; + if (i >= MAX_IOCTL_CONFIG_WAIT) + /* there is an unlikely case where this can happen, + * involving hot replacing a failed 144 GB drive in a + * RAID 5 set just as we attempt this ioctl. */ + return -EAGAIN; return 0; } @@ -1345,15 +1355,7 @@ sizeof(ReportLunData_struct), 0, 0, 0 ); if (return_code == IO_OK) { - /* printk("LUN Data\n--------------------------\n"); */ - listlength |= (0xff & - (unsigned int)(ld_buff->LUNListLength[0])) << 24; - listlength |= (0xff & - (unsigned int)(ld_buff->LUNListLength[1])) << 16; - listlength |= (0xff & - (unsigned int)(ld_buff->LUNListLength[2])) << 8; - listlength |= 0xff & - (unsigned int)(ld_buff->LUNListLength[3]); + listlength = be32_to_cpu(*((__u32 *) &ld_buff->LUNListLength[0])); } else { /* reading number of logical volumes failed */ printk(KERN_WARNING "cciss: report logical volume" @@ -2339,7 +2341,7 @@ /* Is this interrupt for us? */ - if (h->access.intr_pending(h) == 0) + if ((h->access.intr_pending(h) == 0) || (h->interrupts_enabled == 0)) return; /* @@ -2435,25 +2437,58 @@ c->io_mem_addr = 0; c->io_mem_length = 0; } +static int find_PCI_BAR_index(struct pci_dev *pdev, + unsigned long pci_bar_addr) +{ + int i, offset, mem_type, bar_type; + if (pci_bar_addr == PCI_BASE_ADDRESS_0) /* looking for BAR zero? */ + return 0; + offset = 0; + for (i=0; iirq; __u32 board_id; - int cfg_offset; - int cfg_base_addr; - int cfg_base_addr_index; + __u64 cfg_offset; + __u32 cfg_base_addr; + __u64 cfg_base_addr_index; int i; - vendor_id = pdev->vendor; - device_id = pdev->device; - irq = pdev->irq; - - for(i=0; i<6; i++) - addr[i] = pdev->resource[i].start; - + /* check to see if controller has been disabled */ + /* BEFORE we try to enable it */ + (void) pci_read_config_word(pdev, PCI_COMMAND,&command); + if (!(command & 0x02)) { + printk(KERN_WARNING "cciss: controller appears to be disabled\n"); + return -1; + } if (pci_enable_device(pdev)) { printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); return -1; @@ -2463,28 +2498,19 @@ return -1; } - (void) pci_read_config_word(pdev, PCI_COMMAND,&command); - (void) pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); - (void) pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, - &cache_line_size); - (void) pci_read_config_byte(pdev, PCI_LATENCY_TIMER, - &latency_timer); + subsystem_vendor_id = pdev->subsystem_vendor; + subsystem_device_id = pdev->subsystem_device; + board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | + subsystem_vendor_id ); - (void) pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID, - &board_id); - /* check to see if controller has been disabled */ - if (!(command & 0x02)) { - printk(KERN_WARNING "cciss: controller appears to be disabled\n"); - return -1; - } /* search for our IO range so we can protect it */ - for (i=0; i<6; i++) { + for (i=0; iresource[i].flags & 0x01) { - c->io_mem_addr = pdev->resource[i].start; - c->io_mem_length = pdev->resource[i].end - - pdev->resource[i].start +1; + if (pci_resource_flags(pdev, i) & 0x01) { + c->io_mem_addr = pci_resource_start(pdev, i); + c->io_mem_length = pci_resource_end(pdev, i) - + pci_resource_start(pdev, i) + 1; #ifdef CCISS_DEBUG printk("IO value found base_addr[%d] %lx %lx\n", i, c->io_mem_addr, c->io_mem_length); @@ -2504,15 +2530,8 @@ } #ifdef CCISS_DEBUG - printk("vendor_id = %x\n", vendor_id); - printk("device_id = %x\n", device_id); printk("command = %x\n", command); - for(i=0; i<6; i++) - printk("addr[%d] = %x\n", i, addr[i]); - printk("revision = %x\n", revision); printk("irq = %x\n", irq); - printk("cache_line_size = %x\n", cache_line_size); - printk("latency_timer = %x\n", latency_timer); printk("board_id = %x\n", board_id); #endif /* CCISS_DEBUG */ @@ -2523,7 +2542,7 @@ * table */ - c->paddr = addr[0] ; /* addressing mode bits already removed */ + c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */ #ifdef CCISS_DEBUG printk("address 0 = %x\n", c->paddr); #endif /* CCISS_DEBUG */ @@ -2532,21 +2551,27 @@ /* get the address index number */ cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET); /* I am not prepared to deal with a 64 bit address value */ - cfg_base_addr &= 0xffff; + cfg_base_addr &= (__u32) 0x0000ffff; #ifdef CCISS_DEBUG printk("cfg base address = %x\n", cfg_base_addr); #endif /* CCISS_DEBUG */ - cfg_base_addr_index = (cfg_base_addr - PCI_BASE_ADDRESS_0)/4; + cfg_base_addr_index = + find_PCI_BAR_index(pdev, cfg_base_addr); #ifdef CCISS_DEBUG printk("cfg base address index = %x\n", cfg_base_addr_index); #endif /* CCISS_DEBUG */ + if (cfg_base_addr_index == -1) { + printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); + release_io_mem(hba[i]); + return -1; + } cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); #ifdef CCISS_DEBUG printk("cfg offset = %x\n", cfg_offset); #endif /* CCISS_DEBUG */ c->cfgtable = (CfgTable_struct *) - remap_pci_mem((addr[cfg_base_addr_index] & 0xfffffff0) + remap_pci_mem(pci_resource_start(pdev, cfg_base_addr_index) + cfg_offset, sizeof(CfgTable_struct)); c->board_id = board_id; @@ -2583,11 +2608,17 @@ &(c->cfgtable->HostWrite.TransportRequest)); writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); + /* Here, we wait, possibly for a long time, (4 secs or more). + * In some unlikely cases, (e.g. A failed 144 GB drive in a + * RAID 5 set was hot replaced just as we're coming in here) it + * can take that long. Normally (almost always) we will wait + * less than 1 sec. */ for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; /* delay and try again */ - udelay(1000); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); } #ifdef CCISS_DEBUG @@ -2661,10 +2692,7 @@ printk("LUN Data\n--------------------------\n"); #endif /* CCISS_DEBUG */ - listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; - listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; - listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; - listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); + listlength = be32_to_cpu(*((__u32 *) &ld_buff->LUNListLength[0])); } else { /* reading number of logical volumes failed */ printk(KERN_WARNING "cciss: report logical volume" " command failed\n"); @@ -2834,17 +2862,6 @@ hba[i]->ctlr = i; hba[i]->pdev = pdev; - /* configure PCI DMA stuff */ - if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) - printk("cciss: using DAC cycles\n"); - else if (!pci_set_dma_mask(pdev, (u64) 0xffffffff)) - printk("cciss: not using DAC cycles\n"); - else { - printk("cciss: no suitable DMA available\n"); - free_hba(i); - return -ENODEV; - } - if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops)) { printk(KERN_ERR "cciss: Unable to get major number " "%d for %s\n", MAJOR_NR+i, hba[i]->devname); @@ -3021,12 +3038,8 @@ printk(KERN_INFO DRIVER_NAME "\n"); /* Register for out PCI devices */ - if (pci_register_driver(&cciss_pci_driver) > 0 ) - return 0; - else - return -ENODEV; - - } + return pci_module_init(&cciss_pci_driver); +} EXPORT_NO_SYMBOLS; static int __init init_cciss_module(void) diff -urN linux-2.4.21/drivers/block/cciss.h linux-2.4.22/drivers/block/cciss.h --- linux-2.4.21/drivers/block/cciss.h 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/block/cciss.h 2003-08-25 04:44:41.000000000 -0700 @@ -45,13 +45,13 @@ char firm_ver[4]; // Firmware version struct pci_dev *pdev; __u32 board_id; - ulong vaddr; - __u32 paddr; + unsigned long vaddr; + unsigned long paddr; unsigned long io_mem_addr; unsigned long io_mem_length; CfgTable_struct *cfgtable; int intr; - + int interrupts_enabled; int max_commands; int commands_outstanding; int max_outstanding; /* Debug */ @@ -139,9 +139,11 @@ { if (val) { /* Turn interrupts on */ + h->interrupts_enabled = 1; writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); } else /* Turn them off */ { + h->interrupts_enabled = 0; writel( SA5_INTR_OFF, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); } @@ -155,9 +157,11 @@ { if (val) { /* Turn interrupts on */ + h->interrupts_enabled = 1; writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); } else /* Turn them off */ { + h->interrupts_enabled = 0; writel( SA5B_INTR_OFF, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); } diff -urN linux-2.4.21/drivers/block/cciss_scsi.c linux-2.4.22/drivers/block/cciss_scsi.c --- linux-2.4.21/drivers/block/cciss_scsi.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/block/cciss_scsi.c 2003-08-25 04:44:41.000000000 -0700 @@ -1182,6 +1182,12 @@ { case 0x01: /* sequential access, (tape) */ case 0x08: /* medium changer */ + if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { + printk(KERN_INFO "cciss%d: %s ignored, " + "too many devices.\n", cntl_num, + DEVICETYPE(devtype)); + break; + } memcpy(¤tsd[ncurrent].scsi3addr[0], &scsi3addr[0], 8); currentsd[ncurrent].devtype = devtype; diff -urN linux-2.4.21/drivers/block/floppy.c linux-2.4.22/drivers/block/floppy.c --- linux-2.4.21/drivers/block/floppy.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/block/floppy.c 2003-08-25 04:44:41.000000000 -0700 @@ -482,6 +482,7 @@ static int floppy_sizes[256]; static int floppy_blocksizes[256]; +static int floppy_maxsectors[256]; /* * The driver is trying to determine the correct media format @@ -622,7 +623,8 @@ static void is_alive(const char *message) { /* this routine checks whether the floppy driver is "alive" */ - if (fdc_busy && command_status < 2 && !timer_pending(&fd_timeout)){ + if (test_bit(0, &fdc_busy) && command_status < 2 + && !timer_pending(&fd_timeout)){ DPRINT("timeout handler died: %s\n",message); } } @@ -650,7 +652,7 @@ #define CURRENTD -1 #define MAXTIMEOUT -2 -static void reschedule_timeout(int drive, const char *message, int marg) +static void __reschedule_timeout(int drive, const char *message, int marg) { if (drive == CURRENTD) drive = current_drive; @@ -669,6 +671,16 @@ timeout_message = message; } + +static void reschedule_timeout(int drive, const char *message, int marg) +{ + unsigned long flags; + + spin_lock_irqsave(&io_request_lock, flags); + __reschedule_timeout(drive, message, marg); + spin_unlock_irqrestore(&io_request_lock, flags); +} + static int maximum(int a, int b) { if (a > b) @@ -897,7 +909,7 @@ } command_status = FD_COMMAND_NONE; - reschedule_timeout(drive, "lock fdc", 0); + __reschedule_timeout(drive, "lock fdc", 0); set_fdc(drive); return 0; } @@ -911,17 +923,23 @@ /* unlocks the driver */ static inline void unlock_fdc(void) { + unsigned long flags; + raw_cmd = 0; - if (!fdc_busy) + if (!test_bit(0, &fdc_busy)) DPRINT("FDC access conflict!\n"); if (DEVICE_INTR) DPRINT("device interrupt still active at FDC release: %p!\n", DEVICE_INTR); command_status = FD_COMMAND_NONE; + spin_lock_irqsave(&io_request_lock, flags); del_timer(&fd_timeout); cont = NULL; clear_bit(0, &fdc_busy); + if (!QUEUE_EMPTY) + do_fd_request(BLK_DEFAULT_QUEUE(MAJOR_NR)); + spin_unlock_irqrestore(&io_request_lock, flags); floppy_release_irq_and_dma(); wake_up(&fdc_wait); } @@ -1000,9 +1018,13 @@ static void cancel_activity(void) { + unsigned long flags; + + spin_lock_irqsave(&io_request_lock, flags); CLEAR_INTR; floppy_tq.routine = (void *)(void *) empty; del_timer(&fd_timer); + spin_unlock_irqrestore(&io_request_lock, flags); } /* this function makes sure that the disk stays in the drive during the @@ -2986,7 +3008,7 @@ printk("sect=%ld cmd=%d\n", CURRENT->sector, CURRENT->cmd); return; } - if (fdc_busy){ + if (test_bit(0, &fdc_busy)) { /* fdc busy, this new request will be treated when the current one is done */ is_alive("do fd request, old request running"); @@ -3878,7 +3900,7 @@ /* auto-sensing */ int size = floppy_blocksizes[MINOR(dev)]; if (!size) - size = 1024; + size = 512; if (!(bh = getblk(dev,0,size))){ process_fd_request(); return -ENXIO; @@ -4170,14 +4192,19 @@ return -EBUSY; } - for (i=0; i<256; i++) + for (i=0; i<256; i++) { if (ITYPE(i)) floppy_sizes[i] = (floppy_type[ITYPE(i)].size+1) >> 1; else floppy_sizes[i] = MAX_DISK_SIZE; + floppy_blocksizes[i] = 512; + floppy_maxsectors[i] = 64; + } + blk_size[MAJOR_NR] = floppy_sizes; blksize_size[MAJOR_NR] = floppy_blocksizes; + max_sectors[MAJOR_NR] = floppy_maxsectors; blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT); config_types(); diff -urN linux-2.4.21/drivers/block/ll_rw_blk.c linux-2.4.22/drivers/block/ll_rw_blk.c --- linux-2.4.21/drivers/block/ll_rw_blk.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/block/ll_rw_blk.c 2003-08-25 04:44:41.000000000 -0700 @@ -176,11 +176,12 @@ { int count = q->nr_requests; - count -= __blk_cleanup_queue(&q->rq[READ]); - count -= __blk_cleanup_queue(&q->rq[WRITE]); + count -= __blk_cleanup_queue(&q->rq); if (count) printk("blk_cleanup_queue: leaked requests (%d)\n", count); + if (atomic_read(&q->nr_sectors)) + printk("blk_cleanup_queue: leaked sectors (%d)\n", atomic_read(&q->nr_sectors)); memset(q, 0, sizeof(*q)); } @@ -215,6 +216,24 @@ } /** + * blk_queue_throttle_sectors - indicates you will call sector throttling funcs + * @q: The queue which this applies to. + * @active: A flag indication if you want sector throttling on + * + * Description: + * The sector throttling code allows us to put a limit on the number of + * sectors pending io to the disk at a given time, sending @active nonzero + * indicates you will call blk_started_sectors and blk_finished_sectors in + * addition to calling blk_started_io and blk_finished_io in order to + * keep track of the number of sectors in flight. + **/ + +void blk_queue_throttle_sectors(request_queue_t * q, int active) +{ + q->can_throttle = active; +} + +/** * blk_queue_make_request - define an alternate make_request function for a device * @q: the request queue for the device to be affected * @mfn: the alternate make_request function @@ -389,7 +408,7 @@ * * Returns the (new) number of requests which the queue has available. */ -int blk_grow_request_list(request_queue_t *q, int nr_requests) +int blk_grow_request_list(request_queue_t *q, int nr_requests, int max_queue_sectors) { unsigned long flags; /* Several broken drivers assume that this function doesn't sleep, @@ -399,21 +418,34 @@ spin_lock_irqsave(&io_request_lock, flags); while (q->nr_requests < nr_requests) { struct request *rq; - int rw; rq = kmem_cache_alloc(request_cachep, SLAB_ATOMIC); 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++; + list_add(&rq->queue, &q->rq.free); + q->rq.count++; + q->nr_requests++; } + + /* + * Wakeup waiters after both one quarter of the + * max-in-fligh queue and one quarter of the requests + * are available again. + */ + q->batch_requests = q->nr_requests / 4; if (q->batch_requests > 32) q->batch_requests = 32; + q->batch_sectors = max_queue_sectors / 4; + + q->max_queue_sectors = max_queue_sectors; + + BUG_ON(!q->batch_sectors); + atomic_set(&q->nr_sectors, 0); + spin_unlock_irqrestore(&io_request_lock, flags); return q->nr_requests; } @@ -422,23 +454,28 @@ { struct sysinfo si; int megs; /* Total memory, in megabytes */ - int nr_requests; - - INIT_LIST_HEAD(&q->rq[READ].free); - INIT_LIST_HEAD(&q->rq[WRITE].free); - q->rq[READ].count = 0; - q->rq[WRITE].count = 0; + int nr_requests, max_queue_sectors = MAX_QUEUE_SECTORS; + + INIT_LIST_HEAD(&q->rq.free); + q->rq.count = 0; + q->rq.pending[READ] = q->rq.pending[WRITE] = 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); + nr_requests = MAX_NR_REQUESTS; + if (megs < 30) { + nr_requests /= 2; + max_queue_sectors /= 2; + } + /* notice early if anybody screwed the defaults */ + BUG_ON(!nr_requests); + BUG_ON(!max_queue_sectors); + + blk_grow_request_list(q, nr_requests, max_queue_sectors); + + init_waitqueue_head(&q->wait_for_requests); - init_waitqueue_head(&q->wait_for_requests[0]); - init_waitqueue_head(&q->wait_for_requests[1]); spin_lock_init(&q->queue_lock); } @@ -491,6 +528,8 @@ q->plug_tq.routine = &generic_unplug_device; q->plug_tq.data = q; q->plugged = 0; + q->can_throttle = 0; + /* * These booleans describe the queue properties. We set the * default (and most common) values here. Other drivers can @@ -511,12 +550,29 @@ static struct request *get_request(request_queue_t *q, int rw) { struct request *rq = NULL; - struct request_list *rl = q->rq + rw; + struct request_list *rl = &q->rq; + if (blk_oversized_queue(q)) { + int rlim = q->nr_requests >> 5; + + if (rlim < 4) + rlim = 4; + + /* + * if its a write, or we have more than a handful of reads + * pending, bail out + */ + if ((rw == WRITE) || (rw == READ && rl->pending[READ] > rlim)) + return NULL; + if (blk_oversized_queue_reads(q)) + return NULL; + } + if (!list_empty(&rl->free)) { rq = blkdev_free_rq(&rl->free); list_del(&rq->queue); rl->count--; + rl->pending[rw]++; rq->rq_status = RQ_ACTIVE; rq->cmd = rw; rq->special = NULL; @@ -527,29 +583,19 @@ } /* - * Here's the request allocation design: + * Here's the request allocation design, low latency version: * * 1: Blocking on request exhaustion is a key part of I/O throttling. * * 2: We want to be `fair' to all requesters. We must avoid starvation, and * attempt to ensure that all requesters sleep for a similar duration. Hence * no stealing requests when there are other processes waiting. - * - * 3: We also wish to support `batching' of requests. So when a process is - * woken, we want to allow it to allocate a decent number of requests - * before it blocks again, so they can be nicely merged (this only really - * matters if the process happens to be adding requests near the head of - * the queue). - * - * 4: We want to avoid scheduling storms. This isn't really important, because - * the system will be I/O bound anyway. But it's easy. - * - * There is tension between requirements 2 and 3. Once a task has woken, - * we don't want to allow it to sleep as soon as it takes its second request. - * But we don't want currently-running tasks to steal all the requests - * from the sleepers. We handle this with wakeup hysteresis around - * 0 .. batch_requests and with the assumption that request taking is much, - * much faster than request freeing. + * + * There used to be more here, attempting to allow a process to send in a + * number of requests once it has woken up. But, there's no way to + * tell if a process has just been woken up, or if it is a new process + * coming in to steal requests from the waiters. So, we give up and force + * everyone to wait fairly. * * So here's what we do: * @@ -561,28 +607,23 @@ * * When a process wants a new request: * - * b) If free_requests == 0, the requester sleeps in FIFO manner. - * - * b) If 0 < free_requests < batch_requests and there are waiters, - * we still take a request non-blockingly. This provides batching. - * - * c) If free_requests >= batch_requests, the caller is immediately - * granted a new request. + * b) If free_requests == 0, the requester sleeps in FIFO manner, and + * the queue full condition is set. The full condition is not + * cleared until there are no longer any waiters. Once the full + * condition is set, all new io must wait, hopefully for a very + * short period of time. * * When a request is released: * - * d) If free_requests < batch_requests, do nothing. - * - * f) If free_requests >= batch_requests, wake up a single waiter. + * c) If free_requests < batch_requests, do nothing. * - * The net effect is that when a process is woken at the batch_requests level, - * it will be able to take approximately (batch_requests) requests before - * blocking again (at the tail of the queue). - * - * This all assumes that the rate of taking requests is much, much higher - * than the rate of releasing them. Which is very true. + * d) If free_requests >= batch_requests, wake up a single waiter. * - * -akpm, Feb 2002. + * As each waiter gets a request, he wakes another waiter. We do this + * to prevent a race where an unplug might get run before a request makes + * it's way onto the queue. The result is a cascade of wakeups, so delaying + * the initial wakeup until we've got batch_requests available helps avoid + * wakeups where there aren't any requests available yet. */ static struct request *__get_request_wait(request_queue_t *q, int rw) @@ -590,21 +631,37 @@ register struct request *rq; DECLARE_WAITQUEUE(wait, current); - add_wait_queue(&q->wait_for_requests[rw], &wait); + add_wait_queue_exclusive(&q->wait_for_requests, &wait); + do { set_current_state(TASK_UNINTERRUPTIBLE); - generic_unplug_device(q); - if (q->rq[rw].count == 0) - schedule(); spin_lock_irq(&io_request_lock); + if (blk_oversized_queue(q) || q->rq.count == 0) { + __generic_unplug_device(q); + spin_unlock_irq(&io_request_lock); + schedule(); + spin_lock_irq(&io_request_lock); + } rq = get_request(q, rw); spin_unlock_irq(&io_request_lock); } while (rq == NULL); - remove_wait_queue(&q->wait_for_requests[rw], &wait); + remove_wait_queue(&q->wait_for_requests, &wait); current->state = TASK_RUNNING; + return rq; } +static void get_request_wait_wakeup(request_queue_t *q, int rw) +{ + /* + * avoid losing an unplug if a second __get_request_wait did the + * generic_unplug_device while our __get_request_wait was running + * w/o the queue_lock held and w/ our request out of the queue. + */ + if (waitqueue_active(&q->wait_for_requests)) + wake_up(&q->wait_for_requests); +} + /* RO fail safe mechanism */ static long ro_bits[MAX_BLKDEV][8]; @@ -818,7 +875,6 @@ void blkdev_release_request(struct request *req) { request_queue_t *q = req->q; - int rw = req->cmd; req->rq_status = RQ_INACTIVE; req->q = NULL; @@ -828,9 +884,29 @@ * assume it has free buffers and check waiters */ if (q) { - list_add(&req->queue, &q->rq[rw].free); - if (++q->rq[rw].count >= q->batch_requests) - wake_up(&q->wait_for_requests[rw]); + struct request_list *rl = &q->rq; + int oversized_batch = 0; + + if (q->can_throttle) + oversized_batch = blk_oversized_queue_batch(q); + rl->count++; + /* + * paranoia check + */ + if (req->cmd == READ || req->cmd == WRITE) + rl->pending[req->cmd]--; + if (rl->pending[READ] > q->nr_requests) + printk("blk: reads: %u\n", rl->pending[READ]); + if (rl->pending[WRITE] > q->nr_requests) + printk("blk: writes: %u\n", rl->pending[WRITE]); + if (rl->pending[READ] + rl->pending[WRITE] > q->nr_requests) + printk("blk: r/w: %u + %u > %u\n", rl->pending[READ], rl->pending[WRITE], q->nr_requests); + list_add(&req->queue, &rl->free); + if (rl->count >= q->batch_requests && !oversized_batch) { + smp_mb(); + if (waitqueue_active(&q->wait_for_requests)) + wake_up(&q->wait_for_requests); + } } } @@ -901,16 +977,18 @@ static int __make_request(request_queue_t * q, int rw, struct buffer_head * bh) { - unsigned int sector, count; + unsigned int sector, count, sync; int max_segments = MAX_SEGMENTS; struct request * req, *freereq = NULL; int rw_ahead, max_sectors, el_ret; struct list_head *head, *insert_here; int latency; elevator_t *elevator = &q->elevator; + int should_wake = 0; count = bh->b_size >> 9; sector = bh->b_rsector; + sync = test_and_clear_bit(BH_Sync, &bh->b_state); rw_ahead = 0; /* normal case; gets changed below for READA */ switch (rw) { @@ -948,7 +1026,6 @@ */ max_sectors = get_max_sectors(bh->b_rdev); -again: req = NULL; head = &q->queue_head; /* @@ -957,7 +1034,9 @@ */ spin_lock_irq(&io_request_lock); +again: insert_here = head->prev; + if (list_empty(head)) { q->plug_device_fn(q, bh->b_rdev); /* is atomic */ goto get_rq; @@ -976,6 +1055,7 @@ req->bhtail = bh; req->nr_sectors = req->hard_nr_sectors += count; blk_started_io(count); + blk_started_sectors(req, 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); @@ -998,6 +1078,7 @@ req->sector = req->hard_sector = sector; req->nr_sectors = req->hard_nr_sectors += count; blk_started_io(count); + blk_started_sectors(req, 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); @@ -1030,7 +1111,7 @@ * See description above __get_request_wait() */ if (rw_ahead) { - if (q->rq[rw].count < q->batch_requests) { + if (q->rq.count < q->batch_requests || blk_oversized_queue_batch(q)) { spin_unlock_irq(&io_request_lock); goto end_io; } @@ -1042,6 +1123,9 @@ if (req == NULL) { spin_unlock_irq(&io_request_lock); freereq = __get_request_wait(q, rw); + head = &q->queue_head; + spin_lock_irq(&io_request_lock); + should_wake = 1; goto again; } } @@ -1064,10 +1148,15 @@ req->start_time = jiffies; req_new_io(req, 0, count); blk_started_io(count); + blk_started_sectors(req, count); add_request(q, req, insert_here); out: if (freereq) blkdev_release_request(freereq); + if (should_wake) + get_request_wait_wakeup(q, rw); + if (sync) + __generic_unplug_device(q); spin_unlock_irq(&io_request_lock); return 0; end_io: @@ -1196,8 +1285,15 @@ bh->b_rdev = bh->b_dev; bh->b_rsector = bh->b_blocknr * count; + get_bh(bh); generic_make_request(rw, bh); + /* fix race condition with wait_on_buffer() */ + smp_mb(); /* spin_unlock may have inclusive semantics */ + if (waitqueue_active(&bh->b_wait)) + wake_up(&bh->b_wait); + + put_bh(bh); switch (rw) { case WRITE: kstat.pgpgout += count; @@ -1350,6 +1446,7 @@ if ((bh = req->bh) != NULL) { nsect = bh->b_size >> 9; blk_finished_io(nsect); + blk_finished_sectors(req, nsect); req->bh = bh->b_reqnext; bh->b_reqnext = NULL; bh->b_end_io(bh, uptodate); @@ -1509,6 +1606,7 @@ EXPORT_SYMBOL(blk_get_queue); EXPORT_SYMBOL(blk_cleanup_queue); EXPORT_SYMBOL(blk_queue_headactive); +EXPORT_SYMBOL(blk_queue_throttle_sectors); EXPORT_SYMBOL(blk_queue_make_request); EXPORT_SYMBOL(generic_make_request); EXPORT_SYMBOL(blkdev_release_request); diff -urN linux-2.4.21/drivers/block/loop.c linux-2.4.22/drivers/block/loop.c --- linux-2.4.21/drivers/block/loop.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/block/loop.c 2003-08-25 04:44:41.000000000 -0700 @@ -682,7 +682,7 @@ lo->ioctl = NULL; figure_loop_size(lo); lo->old_gfp_mask = inode->i_mapping->gfp_mask; - inode->i_mapping->gfp_mask = GFP_NOIO; + inode->i_mapping->gfp_mask &= ~(__GFP_IO|__GFP_FS); bs = 0; if (blksize_size[MAJOR(lo_device)]) @@ -893,6 +893,7 @@ break; case BLKBSZGET: case BLKBSZSET: + case BLKSSZGET: err = blk_ioctl(inode->i_rdev, cmd, arg); break; default: diff -urN linux-2.4.21/drivers/block/nbd.c linux-2.4.22/drivers/block/nbd.c --- linux-2.4.21/drivers/block/nbd.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/block/nbd.c 2003-08-25 04:44:41.000000000 -0700 @@ -428,23 +428,24 @@ return 0 ; case NBD_CLEAR_SOCK: + error = 0; + down(&lo->tx_lock); + lo->sock = NULL; + up(&lo->tx_lock); + spin_lock(&lo->queue_lock); + file = lo->file; + lo->file = NULL; + spin_unlock(&lo->queue_lock); nbd_clear_que(lo); spin_lock(&lo->queue_lock); if (!list_empty(&lo->queue_head)) { - spin_unlock(&lo->queue_lock); - printk(KERN_ERR "nbd: Some requests are in progress -> can not turn off.\n"); - return -EBUSY; - } - file = lo->file; - if (!file) { - spin_unlock(&lo->queue_lock); - return -EINVAL; + printk(KERN_ERR "nbd: disconnect: some requests are in progress -> please try again.\n"); + error = -EBUSY; } - lo->file = NULL; - lo->sock = NULL; spin_unlock(&lo->queue_lock); - fput(file); - return 0; + if (file) + fput(file); + return error; case NBD_SET_SOCK: if (lo->file) return -EBUSY; @@ -491,9 +492,12 @@ * there should be a more generic interface rather than * calling socket ops directly here */ down(&lo->tx_lock); - printk(KERN_WARNING "nbd: shutting down socket\n"); - lo->sock->ops->shutdown(lo->sock, SEND_SHUTDOWN|RCV_SHUTDOWN); - lo->sock = NULL; + if (lo->sock) { + printk(KERN_WARNING "nbd: shutting down socket\n"); + lo->sock->ops->shutdown(lo->sock, + SEND_SHUTDOWN|RCV_SHUTDOWN); + lo->sock = NULL; + } up(&lo->tx_lock); spin_lock(&lo->queue_lock); file = lo->file; @@ -505,6 +509,13 @@ fput(file); return lo->harderror; case NBD_CLEAR_QUE: + down(&lo->tx_lock); + if (lo->sock) { + up(&lo->tx_lock); + return 0; /* probably should be error, but that would + * break "nbd-client -d", so just return 0 */ + } + up(&lo->tx_lock); nbd_clear_que(lo); return 0; #ifdef PARANOIA diff -urN linux-2.4.21/drivers/block/paride/bpck6.c linux-2.4.22/drivers/block/paride/bpck6.c --- linux-2.4.21/drivers/block/paride/bpck6.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/block/paride/bpck6.c 2003-08-25 04:44:41.000000000 -0700 @@ -194,11 +194,11 @@ if(out) { ppc6_close(PPCSTRUCT(pi)); - return(1); if(verbose) { printk(KERN_DEBUG "leaving probe\n"); } + return(1); } else { diff -urN linux-2.4.21/drivers/block/swim3.c linux-2.4.22/drivers/block/swim3.c --- linux-2.4.21/drivers/block/swim3.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/block/swim3.c 2003-08-25 04:44:41.000000000 -0700 @@ -2,7 +2,7 @@ * Driver for the SWIM3 (Super Woz Integrated Machine 3) * floppy controller found on Power Macintoshes. * - * Copyright (C) 1996 Paul Mackerras. + * Copyright (C) 1996-2003 Paul Mackerras. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -146,7 +146,7 @@ #define RELAX 3 /* also eject in progress */ #define READ_DATA_0 4 #define TWOMEG_DRIVE 5 -#define SINGLE_SIDED 6 +#define SINGLE_SIDED 6 /* drive or diskette is 4MB type? */ #define DRIVE_PRESENT 7 #define DISK_IN 8 #define WRITE_PROT 9 @@ -186,6 +186,7 @@ int req_sector; /* sector number ditto */ int scount; /* # sectors we're transferring at present */ int retries; + int settle_time; int secpercyl; /* disk geometry information */ int secpertrack; int total_secs; @@ -233,6 +234,7 @@ static void act(struct floppy_state *fs); static void scan_timeout(unsigned long data); static void seek_timeout(unsigned long data); +static void settle_timeout(unsigned long data); static void xfer_timeout(unsigned long data); static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs); /*static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);*/ @@ -275,7 +277,6 @@ udelay(2); out_8(&sw->select, sw->select & ~LSTRB); udelay(1); - out_8(&sw->select, RELAX); } static int swim3_readbit(struct floppy_state *fs, int bit) @@ -284,9 +285,8 @@ int stat; swim3_select(fs, bit); - udelay(10); + udelay(1); stat = in_8(&sw->status); - out_8(&sw->select, RELAX); return (stat & DATA) == 0; } @@ -377,13 +377,13 @@ static inline void scan_track(struct floppy_state *fs) { volatile struct swim3 *sw = fs->swim3; - int xx; swim3_select(fs, READ_DATA_0); - xx = sw->intr; /* clear SEEN_SECTOR bit */ + in_8(&sw->intr); /* clear SEEN_SECTOR bit */ + in_8(&sw->error); + out_8(&sw->intr_enable, SEEN_SECTOR); out_8(&sw->control_bis, DO_ACTION); /* enable intr when track found */ - out_8(&sw->intr_enable, ERROR_INTR | SEEN_SECTOR); set_timeout(fs, HZ, scan_timeout); /* enable timeout */ } @@ -398,12 +398,14 @@ swim3_action(fs, SEEK_NEGATIVE); sw->nseek = -n; } - fs->expect_cyl = (fs->cur_cyl > 0)? fs->cur_cyl + n: -1; + fs->expect_cyl = (fs->cur_cyl >= 0)? fs->cur_cyl + n: -1; swim3_select(fs, STEP); - out_8(&sw->control_bis, DO_SEEK); + in_8(&sw->error); /* enable intr when seek finished */ - out_8(&sw->intr_enable, ERROR_INTR | SEEK_DONE); - set_timeout(fs, HZ/2, seek_timeout); /* enable timeout */ + out_8(&sw->intr_enable, SEEK_DONE); + out_8(&sw->control_bis, DO_SEEK); + set_timeout(fs, 3*HZ, seek_timeout); /* enable timeout */ + fs->settle_time = 0; } static inline void init_dma(struct dbdma_cmd *cp, int cmd, @@ -451,18 +453,21 @@ } ++cp; out_le16(&cp->command, DBDMA_STOP); + out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); + in_8(&sw->error); + out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); + if (CURRENT->cmd == WRITE) + out_8(&sw->control_bis, WRITE_SECTORS); + in_8(&sw->intr); out_le32(&dr->control, (RUN << 16) | RUN); - out_8(&sw->control_bis, - (CURRENT->cmd == WRITE? WRITE_SECTORS: 0) | DO_ACTION); /* enable intr when transfer complete */ - out_8(&sw->intr_enable, ERROR_INTR | TRANSFER_DONE); + out_8(&sw->intr_enable, TRANSFER_DONE); + out_8(&sw->control_bis, DO_ACTION); set_timeout(fs, 2*HZ, xfer_timeout); /* enable timeout */ } static void act(struct floppy_state *fs) { - volatile struct swim3 *sw = fs->swim3; - for (;;) { switch (fs->state) { case idle: @@ -495,20 +500,10 @@ return; case settling: - /* wait for SEEK_COMPLETE to become true */ - swim3_select(fs, SEEK_COMPLETE); - udelay(10); - out_8(&sw->intr_enable, ERROR_INTR | DATA_CHANGED); - in_8(&sw->intr); /* clear DATA_CHANGED */ - if (in_8(&sw->status) & DATA) { - /* seek_complete is not yet true */ - set_timeout(fs, HZ/2, seek_timeout); - return; - } - out_8(&sw->intr_enable, 0); - in_8(&sw->intr); - fs->state = locating; - break; + /* check for SEEK_COMPLETE after 30ms */ + fs->settle_time = (HZ + 32) / 33; + set_timeout(fs, fs->settle_time, settle_timeout); + return; case do_transfer: if (fs->cur_cyl != fs->req_cyl) { @@ -540,7 +535,7 @@ volatile struct swim3 *sw = fs->swim3; fs->timeout_pending = 0; - out_8(&sw->control_bic, DO_ACTION); + out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); out_8(&sw->select, RELAX); out_8(&sw->intr_enable, 0); fs->cur_cyl = -1; @@ -560,20 +555,34 @@ volatile struct swim3 *sw = fs->swim3; fs->timeout_pending = 0; - if (fs->state == settling) { - printk(KERN_ERR "swim3: MSI sel=%x ctrl=%x stat=%x intr=%x ie=%x\n", - sw->select, sw->control, sw->status, sw->intr, sw->intr_enable); - } out_8(&sw->control_bic, DO_SEEK); out_8(&sw->select, RELAX); out_8(&sw->intr_enable, 0); - if (fs->state == settling && swim3_readbit(fs, SEEK_COMPLETE)) { - /* printk(KERN_DEBUG "swim3: missed settling interrupt\n"); */ + printk(KERN_ERR "swim3: seek timeout\n"); + end_request(0); + fs->state = idle; + start_request(fs); +} + +static void settle_timeout(unsigned long data) +{ + struct floppy_state *fs = (struct floppy_state *) data; + volatile struct swim3 *sw = fs->swim3; + + fs->timeout_pending = 0; + if (swim3_readbit(fs, SEEK_COMPLETE)) { + out_8(&sw->select, RELAX); fs->state = locating; act(fs); return; } - printk(KERN_ERR "swim3: seek timeout\n"); + out_8(&sw->select, RELAX); + if (fs->settle_time < 2*HZ) { + ++fs->settle_time; + set_timeout(fs, 1, settle_timeout); + return; + } + printk(KERN_ERR "swim3: seek settle timeout\n"); end_request(0); fs->state = idle; start_request(fs); @@ -586,9 +595,13 @@ struct dbdma_regs *dr = fs->dma; struct dbdma_cmd *cp = fs->dma_cmd; unsigned long s; + int n; fs->timeout_pending = 0; st_le32(&dr->control, RUN << 16); + /* We must wait a bit for dbdma to stop */ + for (n = 0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++) + udelay(1); out_8(&sw->intr_enable, 0); out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); out_8(&sw->select, RELAX); @@ -616,18 +629,15 @@ struct dbdma_regs *dr; struct dbdma_cmd *cp; - err = in_8(&sw->error); intr = in_8(&sw->intr); -#if 0 - printk("swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err); -#endif + err = (intr & ERROR_INTR)? in_8(&sw->error): 0; if ((intr & ERROR_INTR) && fs->state != do_transfer) printk(KERN_ERR "swim3_interrupt, state=%d, cmd=%x, intr=%x, err=%x\n", fs->state, CURRENT->cmd, intr, err); switch (fs->state) { case locating: if (intr & SEEN_SECTOR) { - out_8(&sw->control_bic, DO_ACTION); + out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); out_8(&sw->select, RELAX); out_8(&sw->intr_enable, 0); del_timer(&fs->timeout); @@ -677,19 +687,33 @@ case do_transfer: if ((intr & (ERROR_INTR | TRANSFER_DONE)) == 0) break; - dr = fs->dma; - cp = fs->dma_cmd; - /* We must wait a bit for dbdma to complete */ - for (n=0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++) - udelay(10); - DBDMA_DO_STOP(dr); out_8(&sw->intr_enable, 0); out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); out_8(&sw->select, RELAX); del_timer(&fs->timeout); fs->timeout_pending = 0; + dr = fs->dma; + cp = fs->dma_cmd; if (CURRENT->cmd == WRITE) ++cp; + /* + * Check that the main data transfer has finished. + * On writing, the swim3 sometimes doesn't use + * up all the bytes of the postamble, so we can still + * see DMA active here. That doesn't matter as long + * as all the sector data has been transferred. + */ + if ((intr & ERROR_INTR) == 0 && cp->xfer_status == 0) { + /* wait a little while for DMA to complete */ + for (n = 0; n < 100; ++n) { + if (cp->xfer_status != 0) + break; + udelay(1); + barrier(); + } + } + /* turn off DMA */ + out_le32(&dr->control, (RUN | PAUSE) << 16); stat = ld_le16(&cp->xfer_status); resid = ld_le16(&cp->res_count); if (intr & ERROR_INTR) { @@ -796,16 +820,19 @@ if (err) return err; swim3_action(fs, EJECT); - for (n = 2*HZ; n > 0; --n) { - if (swim3_readbit(fs, RELAX)) - break; + for (n = 20; n > 0; --n) { if (signal_pending(current)) { err = -EINTR; break; } + swim3_select(fs, RELAX); current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); + if (swim3_readbit(fs, DISK_IN) == 0) + break; } + swim3_select(fs, RELAX); + udelay(150); fs->ejected = 1; release_drive(fs); return err; @@ -865,29 +892,31 @@ if (fs->ref_count == 0) { if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD)) return -ENXIO; - out_8(&sw->mode, 0x95); - out_8(&sw->control_bic, 0xff); out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2); + out_8(&sw->control_bic, 0xff); + out_8(&sw->mode, 0x95); udelay(10); out_8(&sw->intr_enable, 0); out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE); swim3_action(fs, MOTOR_ON); fs->write_prot = -1; fs->cur_cyl = -1; - for (n = HZ; n > 0; --n) { - if (swim3_readbit(fs, SEEK_COMPLETE)) + for (n = 0; n < 2 * HZ; ++n) { + if (n >= HZ/30 && swim3_readbit(fs, SEEK_COMPLETE)) break; if (signal_pending(current)) { err = -EINTR; break; } + swim3_select(fs, RELAX); current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); } if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0 || swim3_readbit(fs, DISK_IN) == 0)) err = -ENXIO; - swim3_action(fs, 9); + swim3_action(fs, SETMFM); + swim3_select(fs, RELAX); } else if (fs->ref_count == -1 || filp->f_flags & O_EXCL) return -EBUSY; @@ -910,6 +939,7 @@ if (fs->ref_count == 0) { swim3_action(fs, MOTOR_OFF); out_8(&sw->control_bic, DRIVE_ENABLE | INTR_ENABLE); + swim3_select(fs, RELAX); } return err; } @@ -936,6 +966,7 @@ if (fs->ref_count > 0 && --fs->ref_count == 0) { swim3_action(fs, MOTOR_OFF); out_8(&sw->control_bic, 0xff); + swim3_select(fs, RELAX); } return 0; } @@ -970,15 +1001,17 @@ sw = fs->swim3; grab_drive(fs, revalidating, 0); out_8(&sw->intr_enable, 0); - out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE); - swim3_action(fs, MOTOR_ON); + out_8(&sw->control_bis, DRIVE_ENABLE); + swim3_action(fs, MOTOR_ON); /* necessary? */ fs->write_prot = -1; fs->cur_cyl = -1; + mdelay(1); for (n = HZ; n > 0; --n) { if (swim3_readbit(fs, SEEK_COMPLETE)) break; if (signal_pending(current)) break; + swim3_select(fs, RELAX); current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); } @@ -988,8 +1021,9 @@ swim3_action(fs, MOTOR_OFF); else { fs->ejected = 0; - swim3_action(fs, 9); + swim3_action(fs, SETMFM); } + swim3_select(fs, RELAX); release_drive(fs); return ret; diff -urN linux-2.4.21/drivers/bluetooth/Config.in linux-2.4.22/drivers/bluetooth/Config.in --- linux-2.4.21/drivers/bluetooth/Config.in 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/bluetooth/Config.in 2003-08-25 04:44:41.000000000 -0700 @@ -18,6 +18,8 @@ dep_bool ' Transmit CRC with every BCSP packet' CONFIG_BLUEZ_HCIUART_BCSP_TXCRC $CONFIG_BLUEZ_HCIUART_BCSP fi +dep_tristate 'HCI BlueFRITZ! USB driver' CONFIG_BLUEZ_HCIBFUSB $CONFIG_BLUEZ $CONFIG_USB + dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ diff -urN linux-2.4.21/drivers/bluetooth/Makefile linux-2.4.22/drivers/bluetooth/Makefile --- linux-2.4.21/drivers/bluetooth/Makefile 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/bluetooth/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -14,6 +14,8 @@ uart-$(CONFIG_BLUEZ_HCIUART_H4) += hci_h4.o uart-$(CONFIG_BLUEZ_HCIUART_BCSP) += hci_bcsp.o +obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o + obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o diff -urN linux-2.4.21/drivers/bluetooth/bfusb.c linux-2.4.22/drivers/bluetooth/bfusb.c --- linux-2.4.21/drivers/bluetooth/bfusb.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/bluetooth/bfusb.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,773 @@ +/* + * + * AVM BlueFRITZ! USB driver + * + * Copyright (C) 2003 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "bfusb.h" + +#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG +#undef BT_DBG +#define BT_DBG(D...) +#endif + +#define VERSION "1.0" + +static struct usb_driver bfusb_driver; + +static struct usb_device_id bfusb_table[] = { + /* AVM BlueFRITZ! USB */ + { USB_DEVICE(0x057c, 0x2200) }, + + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, bfusb_table); + + +#define BFUSB_MAX_BLOCK_SIZE 256 + +#define BFUSB_BLOCK_TIMEOUT (HZ * 3) + +#define BFUSB_TX_PROCESS 1 +#define BFUSB_TX_WAKEUP 2 + +#define BFUSB_MAX_BULK_TX 1 +#define BFUSB_MAX_BULK_RX 1 + +struct bfusb { + struct hci_dev hdev; + + unsigned long state; + + struct usb_device *udev; + + unsigned int bulk_in_ep; + unsigned int bulk_out_ep; + unsigned int bulk_pkt_size; + + rwlock_t lock; + + struct sk_buff_head transmit_q; + + struct sk_buff *reassembly; + + atomic_t pending_tx; + struct sk_buff_head pending_q; + struct sk_buff_head completed_q; +}; + +struct bfusb_scb { + struct urb *urb; +}; + +static void bfusb_tx_complete(struct urb *urb); +static void bfusb_rx_complete(struct urb *urb); + +static struct urb *bfusb_get_completed(struct bfusb *bfusb) +{ + struct sk_buff *skb; + struct urb *urb = NULL; + + BT_DBG("bfusb %p", bfusb); + + skb = skb_dequeue(&bfusb->completed_q); + if (skb) { + urb = ((struct bfusb_scb *) skb->cb)->urb; + kfree_skb(skb); + } + + return urb; +} + +static inline void bfusb_unlink_urbs(struct bfusb *bfusb) +{ + struct sk_buff *skb; + struct urb *urb; + + BT_DBG("bfusb %p", bfusb); + + while ((skb = skb_dequeue(&bfusb->pending_q))) { + urb = ((struct bfusb_scb *) skb->cb)->urb; + usb_unlink_urb(urb); + skb_queue_tail(&bfusb->completed_q, skb); + } + + while ((urb = bfusb_get_completed(bfusb))) + usb_free_urb(urb); +} + + +static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb) +{ + struct bfusb_scb *scb = (void *) skb->cb; + struct urb *urb = bfusb_get_completed(bfusb); + int err, pipe; + + BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len); + + if (!urb && !(urb = usb_alloc_urb(0))) + return -ENOMEM; + + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); + + FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len, + bfusb_tx_complete, skb); + + urb->transfer_flags = USB_QUEUE_BULK; + + scb->urb = urb; + + skb_queue_tail(&bfusb->pending_q, skb); + + err = usb_submit_urb(urb); + if (err) { + BT_ERR("%s bulk tx submit failed urb %p err %d", + bfusb->hdev.name, urb, err); + skb_unlink(skb); + usb_free_urb(urb); + } else + atomic_inc(&bfusb->pending_tx); + + return err; +} + +static void bfusb_tx_wakeup(struct bfusb *bfusb) +{ + struct sk_buff *skb; + + BT_DBG("bfusb %p", bfusb); + + if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) { + set_bit(BFUSB_TX_WAKEUP, &bfusb->state); + return; + } + + do { + clear_bit(BFUSB_TX_WAKEUP, &bfusb->state); + + while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) && + (skb = skb_dequeue(&bfusb->transmit_q))) { + if (bfusb_send_bulk(bfusb, skb) < 0) { + skb_queue_head(&bfusb->transmit_q, skb); + break; + } + } + + } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state)); + + clear_bit(BFUSB_TX_PROCESS, &bfusb->state); +} + +static void bfusb_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *) urb->context; + struct bfusb *bfusb = (struct bfusb *) skb->dev; + + BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); + + atomic_dec(&bfusb->pending_tx); + + if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags)) + return; + + if (!urb->status) + bfusb->hdev.stat.byte_tx += skb->len; + else + bfusb->hdev.stat.err_tx++; + + read_lock(&bfusb->lock); + + skb_unlink(skb); + skb_queue_tail(&bfusb->completed_q, skb); + + bfusb_tx_wakeup(bfusb); + + read_unlock(&bfusb->lock); +} + + +static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) +{ + struct bfusb_scb *scb; + struct sk_buff *skb; + int err, pipe, size = HCI_MAX_FRAME_SIZE + 32; + + BT_DBG("bfusb %p urb %p", bfusb, urb); + + if (!urb && !(urb = usb_alloc_urb(0))) + return -ENOMEM; + + if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) { + usb_free_urb(urb); + return -ENOMEM; + } + + skb->dev = (void *) bfusb; + + scb = (struct bfusb_scb *) skb->cb; + scb->urb = urb; + + pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep); + + FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size, + bfusb_rx_complete, skb); + + urb->transfer_flags = USB_QUEUE_BULK; + + skb_queue_tail(&bfusb->pending_q, skb); + + err = usb_submit_urb(urb); + if (err) { + BT_ERR("%s bulk rx submit failed urb %p err %d", + bfusb->hdev.name, urb, err); + skb_unlink(skb); + kfree_skb(skb); + usb_free_urb(urb); + } + + return err; +} + +static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len) +{ + BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len); + + if (hdr & 0x10) { + BT_ERR("%s error in block", bfusb->hdev.name); + if (bfusb->reassembly) + kfree_skb(bfusb->reassembly); + bfusb->reassembly = NULL; + return -EIO; + } + + if (hdr & 0x04) { + struct sk_buff *skb; + unsigned char pkt_type; + int pkt_len = 0; + + if (bfusb->reassembly) { + BT_ERR("%s unexpected start block", bfusb->hdev.name); + kfree_skb(bfusb->reassembly); + bfusb->reassembly = NULL; + } + + if (len < 1) { + BT_ERR("%s no packet type found", bfusb->hdev.name); + return -EPROTO; + } + + pkt_type = *data++; len--; + + switch (pkt_type) { + case HCI_EVENT_PKT: + if (len >= HCI_EVENT_HDR_SIZE) { + hci_event_hdr *hdr = (hci_event_hdr *) data; + pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen; + } else { + BT_ERR("%s event block is too short", bfusb->hdev.name); + return -EILSEQ; + } + break; + + case HCI_ACLDATA_PKT: + if (len >= HCI_ACL_HDR_SIZE) { + hci_acl_hdr *hdr = (hci_acl_hdr *) data; + pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen); + } else { + BT_ERR("%s data block is too short", bfusb->hdev.name); + return -EILSEQ; + } + break; + + case HCI_SCODATA_PKT: + if (len >= HCI_SCO_HDR_SIZE) { + hci_sco_hdr *hdr = (hci_sco_hdr *) data; + pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen; + } else { + BT_ERR("%s audio block is too short", bfusb->hdev.name); + return -EILSEQ; + } + break; + } + + skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC); + if (!skb) { + BT_ERR("%s no memory for the packet", bfusb->hdev.name); + return -ENOMEM; + } + + skb->dev = (void *) &bfusb->hdev; + skb->pkt_type = pkt_type; + + bfusb->reassembly = skb; + } else { + if (!bfusb->reassembly) { + BT_ERR("%s unexpected continuation block", bfusb->hdev.name); + return -EIO; + } + } + + if (len > 0) + memcpy(skb_put(bfusb->reassembly, len), data, len); + + if (hdr & 0x08) { + hci_recv_frame(bfusb->reassembly); + bfusb->reassembly = NULL; + } + + return 0; +} + +static void bfusb_rx_complete(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *) urb->context; + struct bfusb *bfusb = (struct bfusb *) skb->dev; + unsigned char *buf = urb->transfer_buffer; + int count = urb->actual_length; + int err, hdr, len; + + BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); + + if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags)) + return; + + read_lock(&bfusb->lock); + + if (urb->status || !count) + goto resubmit; + + bfusb->hdev.stat.byte_rx += count; + + skb_put(skb, count); + + while (count) { + hdr = buf[0] | (buf[1] << 8); + + if (hdr & 0x4000) { + len = 0; + count -= 2; + buf += 2; + } else { + len = (buf[2] == 0) ? 256 : buf[2]; + count -= 3; + buf += 3; + } + + if (count < len) { + BT_ERR("%s block extends over URB buffer ranges", + bfusb->hdev.name); + } + + if ((hdr & 0xe1) == 0xc1) + bfusb_recv_block(bfusb, hdr, buf, len); + + count -= len; + buf += len; + } + + skb_unlink(skb); + kfree_skb(skb); + + bfusb_rx_submit(bfusb, urb); + + read_unlock(&bfusb->lock); + + return; + +resubmit: + urb->dev = bfusb->udev; + + err = usb_submit_urb(urb); + if (err) { + BT_ERR("%s bulk resubmit failed urb %p err %d", + bfusb->hdev.name, urb, err); + } + + read_unlock(&bfusb->lock); +} + + +static int bfusb_open(struct hci_dev *hdev) +{ + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + unsigned long flags; + int i, err; + + BT_DBG("hdev %p bfusb %p", hdev, bfusb); + + if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) + return 0; + + MOD_INC_USE_COUNT; + + write_lock_irqsave(&bfusb->lock, flags); + + err = bfusb_rx_submit(bfusb, NULL); + if (!err) { + for (i = 1; i < BFUSB_MAX_BULK_RX; i++) + bfusb_rx_submit(bfusb, NULL); + } else { + clear_bit(HCI_RUNNING, &hdev->flags); + MOD_DEC_USE_COUNT; + } + + write_unlock_irqrestore(&bfusb->lock, flags); + + return err; +} + +static int bfusb_flush(struct hci_dev *hdev) +{ + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + + BT_DBG("hdev %p bfusb %p", hdev, bfusb); + + skb_queue_purge(&bfusb->transmit_q); + + return 0; +} + +static int bfusb_close(struct hci_dev *hdev) +{ + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + unsigned long flags; + + BT_DBG("hdev %p bfusb %p", hdev, bfusb); + + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) + return 0; + + write_lock_irqsave(&bfusb->lock, flags); + + bfusb_unlink_urbs(bfusb); + bfusb_flush(hdev); + + write_unlock_irqrestore(&bfusb->lock, flags); + + MOD_DEC_USE_COUNT; + + return 0; +} + +static int bfusb_send_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + struct bfusb *bfusb; + struct sk_buff *nskb; + unsigned char buf[3]; + int sent = 0, size, count; + + BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len); + + if (!hdev) { + BT_ERR("Frame for unknown HCI device (hdev=NULL)"); + return -ENODEV; + } + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return -EBUSY; + + bfusb = (struct bfusb *) hdev->driver_data; + + switch (skb->pkt_type) { + case HCI_COMMAND_PKT: + hdev->stat.cmd_tx++; + break; + case HCI_ACLDATA_PKT: + hdev->stat.acl_tx++; + break; + case HCI_SCODATA_PKT: + hdev->stat.sco_tx++; + break; + }; + + /* Prepend skb with frame type */ + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1); + + count = skb->len; + + /* Max HCI frame size seems to be 1511 + 1 */ + if (!(nskb = bluez_skb_alloc(count + 32, GFP_ATOMIC))) { + BT_ERR("Can't allocate memory for new packet"); + return -ENOMEM; + } + + nskb->dev = (void *) bfusb; + + while (count) { + size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE); + + buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0); + buf[1] = 0x00; + buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size; + + memcpy(skb_put(nskb, 3), buf, 3); + memcpy(skb_put(nskb, size), skb->data + sent, size); + + sent += size; + count -= size; + } + + /* Don't send frame with multiple size of bulk max packet */ + if ((nskb->len % bfusb->bulk_pkt_size) == 0) { + buf[0] = 0xdd; + buf[1] = 0x00; + memcpy(skb_put(nskb, 2), buf, 2); + } + + read_lock(&bfusb->lock); + + skb_queue_tail(&bfusb->transmit_q, nskb); + bfusb_tx_wakeup(bfusb); + + read_unlock(&bfusb->lock); + + kfree_skb(skb); + + return 0; +} + +static void bfusb_destruct(struct hci_dev *hdev) +{ + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + + BT_DBG("hdev %p bfusb %p", hdev, bfusb); + + kfree(bfusb); +} + +static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} + + +static int bfusb_load_firmware(struct bfusb *bfusb) +{ + unsigned char *buf, *ptr; + int err, pipe, len, count, size, sent = 0; + + BT_DBG("bfusb %p udev %p", bfusb, bfusb->udev); + + BT_INFO("BlueFRITZ! USB loading firmware"); + + if (usb_set_configuration(bfusb->udev, 1) < 0) { + BT_ERR("Can't change to loading configuration"); + return -EBUSY; + } + + buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC); + if (!buf) { + BT_ERR("Can't allocate memory chunk for firmware"); + return -ENOMEM; + } + + count = BFUSB_FIRMWARE_SIZE; + ptr = &bfusb_firmware[0]; + + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); + + while (count) { + size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3); + + memcpy(buf, ptr + sent, size); + + err = usb_bulk_msg(bfusb->udev, pipe, buf, size, + &len, BFUSB_BLOCK_TIMEOUT); + + if (err || (len != size)) { + BT_ERR("Error in firmware loading"); + goto error; + } + + sent += size; + count -= size; + } + + if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0, + &len, BFUSB_BLOCK_TIMEOUT)) < 0) { + BT_ERR("Error in null packet request"); + goto error; + } + + if ((err = usb_set_configuration(bfusb->udev, 2)) < 0) { + BT_ERR("Can't change to running configuration"); + goto error; + } + + BT_INFO("BlueFRITZ! USB device ready"); + + kfree(buf); + return 0; + +error: + kfree(buf); + + pipe = usb_sndctrlpipe(bfusb->udev, 0); + + usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, + 0, 0, 0, NULL, 0, BFUSB_BLOCK_TIMEOUT); + + return err; +} + +static void *bfusb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +{ + struct usb_interface *iface; + struct usb_interface_descriptor *iface_desc; + struct usb_endpoint_descriptor *bulk_out_ep; + struct usb_endpoint_descriptor *bulk_in_ep; + struct hci_dev *hdev; + struct bfusb *bfusb; + + BT_DBG("udev %p ifnum %d id %p", udev, ifnum, id); + + /* Check number of endpoints */ + iface = &udev->actconfig->interface[0]; + iface_desc = &iface->altsetting[0]; + + if (iface_desc->bNumEndpoints < 2) + return NULL; + + bulk_out_ep = &iface_desc->endpoint[0]; + bulk_in_ep = &iface_desc->endpoint[1]; + + if (!bulk_out_ep || !bulk_in_ep) { + BT_ERR("Bulk endpoints not found"); + goto done; + } + + /* Initialize control structure and load firmware */ + if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) { + BT_ERR("Can't allocate memory for control structure"); + goto done; + } + + memset(bfusb, 0, sizeof(struct bfusb)); + + bfusb->udev = udev; + bfusb->bulk_in_ep = bulk_in_ep->bEndpointAddress; + bfusb->bulk_out_ep = bulk_out_ep->bEndpointAddress; + bfusb->bulk_pkt_size = bulk_out_ep->wMaxPacketSize; + + bfusb->lock = RW_LOCK_UNLOCKED; + + bfusb->reassembly = NULL; + + skb_queue_head_init(&bfusb->transmit_q); + skb_queue_head_init(&bfusb->pending_q); + skb_queue_head_init(&bfusb->completed_q); + + if (bfusb_load_firmware(bfusb) < 0) { + BT_ERR("Firmware loading failed"); + goto error; + } + + /* Initialize and register HCI device */ + hdev = &bfusb->hdev; + + hdev->type = HCI_USB; + hdev->driver_data = bfusb; + + hdev->open = bfusb_open; + hdev->close = bfusb_close; + hdev->flush = bfusb_flush; + hdev->send = bfusb_send_frame; + hdev->destruct = bfusb_destruct; + hdev->ioctl = bfusb_ioctl; + + if (hci_register_dev(hdev) < 0) { + BT_ERR("Can't register HCI device"); + goto error; + } + + return bfusb; + +error: + kfree(bfusb); + +done: + return NULL; +} + +static void bfusb_disconnect(struct usb_device *udev, void *ptr) +{ + struct bfusb *bfusb = (struct bfusb *) ptr; + struct hci_dev *hdev = &bfusb->hdev; + + BT_DBG("udev %p ptr %p", udev, ptr); + + if (!hdev) + return; + + bfusb_close(hdev); + + if (hci_unregister_dev(hdev) < 0) + BT_ERR("Can't unregister HCI device %s", hdev->name); +} + +static struct usb_driver bfusb_driver = { + name: "bfusb", + probe: bfusb_probe, + disconnect: bfusb_disconnect, + id_table: bfusb_table, +}; + +static int __init bfusb_init(void) +{ + int err; + + BT_INFO("BlueFRITZ! USB driver ver %s", VERSION); + BT_INFO("Copyright (C) 2003 Marcel Holtmann "); + + if ((err = usb_register(&bfusb_driver)) < 0) + BT_ERR("Failed to register BlueFRITZ! USB driver"); + + return err; +} + +static void __exit bfusb_cleanup(void) +{ + usb_deregister(&bfusb_driver); +} + +module_init(bfusb_init); +module_exit(bfusb_cleanup); + +MODULE_AUTHOR("Marcel Holtmann "); +MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/bluetooth/bfusb.h linux-2.4.22/drivers/bluetooth/bfusb.h --- linux-2.4.21/drivers/bluetooth/bfusb.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/bluetooth/bfusb.h 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,52261 @@ +/* + * + * AVM BlueFRITZ! USB firmware + * + * Version 03.17.46 + * + * Copyright (C) 2002-2003 AVM GmbH. All rights reserved. + * + * + * You may only use and redistribute this Software in binary form provided + * that the following conditions are met: + * + * Redistribution of this Software in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * The name of AVM may not be used to endorse or promote products derived + * from this Software without specific prior written permission by AVM. + * + * Disclaimer/Limitation of Liablity + * This Software has been produced with due care and checked for correctness + * in accordance with available technology. The information in this Software + * is subject to change without notice for the purpose of technical + * improvement. You bear all risk with regard to hazards and impairments of + * quality which may arise in connection with the use of this Software. + * + * THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY + * APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + * HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "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 SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU + * ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + * + * 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 SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR + * DAMAGES, INCLUDING ANY DIRECT, INDIRECT, GENERAL, SPECIAL, EXEMPLARY, + * INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY + * TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, BUSINESS INTERRUPTION, + * PROFITS, DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY + * YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY + * OTHER SOFTWARE), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGES. YOU ACKNOWLEDGE AND AGREE THAT PURCHASE OR USE OF THIS SOFTWARE + * WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, + * OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT, + * TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN ANY + * OTHER AVM HARDWARE OR SOFTWARE EITHER SOLELY OR IN COMBINATION WITH THIS + * SOFTWARE. + * + */ + +#define BFUSB_FIRMWARE_SIZE 417605 + +static unsigned char bfusb_firmware[] = { + 0xed, 0x09, 0x00, 0x00, 0x00, 0x71, 0x56, 0xaf, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x8c, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x00, 0xff, 0x21, 0x46, + 0x22, 0x0f, 0xff, 0xff, 0xff, 0xaa, 0x99, 0x55, + 0x66, 0x30, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x30, 0x01, 0x60, 0x01, 0x00, 0x00, 0x00, + 0x11, 0x30, 0x01, 0x20, 0x01, 0x00, 0x80, 0x3f, + 0x2d, 0x30, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x01, + 0xc6, 0x30, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, + 0x09, 0x30, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x30, 0x00, 0x40, 0x00, 0x50, 0x00, 0x99, + 0xc6, 0x00, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x04, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x04, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x90, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x10, 0x00, 0x68, 0x00, + 0x1e, 0x00, 0x07, 0x80, 0x01, 0xe0, 0x00, 0x78, + 0x00, 0x1e, 0x00, 0x07, 0x80, 0x01, 0xe0, 0x00, + 0x78, 0x00, 0x1e, 0x00, 0x07, 0xe0, 0x01, 0xe8, + 0x00, 0x78, 0x00, 0x1e, 0x80, 0x07, 0xa0, 0x01, + 0xa8, 0x00, 0x7a, 0x00, 0x1a, 0x80, 0x06, 0x80, + 0x01, 0xa0, 0x00, 0x6a, 0x00, 0x18, 0x80, 0x07, + 0xa0, 0x01, 0x88, 0x00, 0x60, 0x00, 0x18, 0x00, + 0x06, 0x00, 0x01, 0x80, 0x3f, 0xc4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x05, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x21, 0x37, 0xc0, 0x0b, 0xf0, 0x03, 0x3d, + 0x00, 0xcf, 0x00, 0xb3, 0xd1, 0x0f, 0xc1, 0x03, + 0xf4, 0x00, 0x4d, 0x00, 0x3b, 0xc8, 0x0f, 0xf2, + 0x03, 0x7c, 0x00, 0xff, 0x00, 0x37, 0x00, 0x8f, + 0xc0, 0x43, 0x14, 0x00, 0xef, 0x01, 0x3f, 0xcc, + 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xc7, 0x20, 0x33, + 0xc4, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x10, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x0c, + 0xbf, 0xed, 0x09, 0x00, 0x03, 0x00, 0x10, 0x23, + 0xc4, 0x0b, 0xf5, 0x06, 0x0c, 0x00, 0x8f, 0x40, + 0x32, 0xc0, 0x0b, 0x90, 0x03, 0xa4, 0x00, 0x88, + 0x00, 0x22, 0xd0, 0x0e, 0xa4, 0x02, 0xe9, 0x40, + 0xba, 0x50, 0x3a, 0xc0, 0x0b, 0x82, 0x02, 0x24, + 0x00, 0xa7, 0x50, 0x2e, 0xc0, 0x0b, 0x97, 0x82, + 0xe1, 0xe0, 0x8b, 0x40, 0x36, 0xc8, 0x0b, 0xb0, + 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x09, 0x30, 0x02, 0x8c, 0x80, 0x83, 0x40, + 0x20, 0xc8, 0x0b, 0x00, 0x02, 0xe4, 0x00, 0x83, + 0x00, 0x28, 0xc4, 0x0b, 0x11, 0x02, 0x84, 0x14, + 0xb1, 0x00, 0x24, 0xc0, 0x0b, 0x80, 0x8e, 0x04, + 0x00, 0x83, 0x01, 0x24, 0xcc, 0x8b, 0x10, 0x12, + 0xc4, 0x00, 0x83, 0x10, 0x20, 0xc0, 0x0b, 0x30, + 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2a, + 0xc0, 0x0b, 0xb0, 0x02, 0xac, 0x00, 0x8b, 0x00, + 0x26, 0xc0, 0x0b, 0x90, 0x02, 0xa4, 0x24, 0x8b, + 0x18, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2a, 0xe0, 0x0b, 0x90, 0x02, 0x24, + 0x00, 0xab, 0x02, 0x2e, 0xc0, 0x0b, 0x98, 0x02, + 0xe2, 0x00, 0x8b, 0x00, 0x26, 0xc0, 0x0b, 0xb0, + 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf3, 0x01, 0x3e, + 0xc1, 0x0d, 0xb0, 0x02, 0xac, 0x00, 0xcb, 0x00, + 0x32, 0xc0, 0x0f, 0x90, 0x03, 0xc9, 0x00, 0xc9, + 0x40, 0x3a, 0x80, 0x5f, 0xb0, 0x43, 0xec, 0x00, + 0xfb, 0x00, 0x36, 0x70, 0x0f, 0x88, 0x03, 0x21, + 0x80, 0x4b, 0x00, 0x3e, 0xed, 0x09, 0x00, 0x04, + 0x00, 0xc0, 0x0f, 0x8e, 0x03, 0xe6, 0x02, 0xcb, + 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xbc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x04, 0xff, 0x00, 0x37, 0xc0, 0x0f, 0xf0, + 0x03, 0x7c, 0x00, 0xff, 0x02, 0x3b, 0xc0, 0x4f, + 0xd0, 0x23, 0xbe, 0x40, 0xfc, 0x04, 0x3f, 0xa4, + 0x0e, 0xa0, 0x03, 0xf8, 0x00, 0xfe, 0x00, 0x3b, + 0xc0, 0x8f, 0xc2, 0x03, 0xf0, 0x00, 0xff, 0x00, + 0x3e, 0xc0, 0x0f, 0xc0, 0x23, 0xf4, 0x00, 0xf7, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x20, 0x3e, 0xc0, 0x0f, 0x30, + 0x03, 0x2c, 0x00, 0xeb, 0x80, 0x3e, 0xc0, 0x8f, + 0xb0, 0x03, 0xa9, 0x20, 0xfb, 0xc0, 0x32, 0xc0, + 0x0f, 0x90, 0x03, 0x64, 0x02, 0xc9, 0x00, 0x3e, + 0x82, 0x0f, 0xb0, 0x43, 0xe8, 0x00, 0xeb, 0x00, + 0x32, 0xc0, 0x2c, 0x94, 0x03, 0xe4, 0x80, 0xfb, + 0x08, 0x32, 0xc2, 0x0c, 0xb0, 0x03, 0xd0, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0xbf, 0x60, 0x2f, 0xc0, 0x8b, 0xf8, + 0x02, 0x2c, 0x00, 0x87, 0x00, 0x0f, 0xc0, 0x0b, + 0x90, 0x02, 0xae, 0x00, 0xbb, 0x80, 0x22, 0xc0, + 0x0e, 0xb0, 0x82, 0x2e, 0x00, 0x8b, 0x00, 0x06, + 0xc0, 0x4b, 0x30, 0x02, 0xc8, 0x00, 0x0f, 0x00, + 0x23, 0xc0, 0x48, 0x98, 0x02, 0xe7, 0x80, 0xbf, + 0x80, 0x36, 0xf2, 0x0a, 0xb0, 0x02, 0xf2, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x80, 0x2c, 0xc0, 0x0b, 0xed, + 0x09, 0x00, 0x05, 0x00, 0x38, 0x00, 0x2c, 0x04, + 0x83, 0x00, 0x0c, 0xc0, 0x03, 0x00, 0x02, 0xce, + 0x00, 0xb8, 0x00, 0x20, 0x41, 0x0a, 0x38, 0x02, + 0x4c, 0x00, 0xa3, 0x00, 0x2c, 0xc0, 0x1b, 0x00, + 0x42, 0xc4, 0x00, 0xa3, 0x00, 0xa0, 0xc0, 0x08, + 0x00, 0x82, 0xe3, 0x04, 0xb3, 0x80, 0x20, 0xc0, + 0x08, 0x30, 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x01, 0x1e, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, + 0x81, 0x2d, 0xe0, 0x0b, 0x78, 0x82, 0x1e, 0x00, + 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x58, 0x02, 0xde, + 0x00, 0x34, 0xc0, 0x21, 0xe0, 0x0a, 0x68, 0x00, + 0x0a, 0x20, 0xa6, 0x80, 0x25, 0xa0, 0x0b, 0x48, + 0x00, 0xf6, 0x00, 0xa7, 0xe1, 0x21, 0xe0, 0x08, + 0x79, 0x02, 0xda, 0x00, 0xb7, 0x88, 0x25, 0xe0, + 0x0a, 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x08, 0x0c, 0x00, 0xf3, 0x00, + 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, + 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0x0c, 0x00, + 0xa3, 0x00, 0x3c, 0xc0, 0x0f, 0x80, 0x03, 0xcc, + 0xe0, 0xfa, 0x00, 0x30, 0x40, 0x0e, 0x10, 0x03, + 0x44, 0x00, 0xe1, 0x00, 0x3c, 0xd0, 0x0f, 0x22, + 0x02, 0xc4, 0x20, 0xe3, 0x00, 0x30, 0xc4, 0x0c, + 0x20, 0x83, 0xcc, 0x40, 0xf3, 0x20, 0x32, 0xc0, + 0x0c, 0x30, 0x43, 0xd2, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xd4, 0x0b, 0x74, 0x03, 0xfc, 0x40, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xd1, 0x03, 0xbc, + 0x48, 0xfc, 0x10, 0x3f, 0xc0, 0x0e, 0xf0, 0x03, + 0xfc, 0x00, 0xdf, 0x02, 0x37, 0xc4, 0x0f, 0xf0, + 0x03, 0xf4, 0x00, 0xdf, 0x22, 0xbf, 0xc0, 0x0f, + 0xf0, 0x43, 0xed, 0x09, 0x00, 0x06, 0x00, 0xf8, + 0x00, 0xff, 0x08, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, + 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0xc8, 0x32, 0xc1, + 0x8f, 0xb3, 0x01, 0xec, 0x00, 0xdb, 0x60, 0x3e, + 0xe0, 0x0c, 0x90, 0x03, 0xe8, 0x00, 0xf9, 0x80, + 0x32, 0x00, 0x0f, 0xb0, 0x03, 0x2c, 0x01, 0xfb, + 0x80, 0x72, 0xc0, 0x0c, 0x80, 0x03, 0xc6, 0x00, + 0x6b, 0x24, 0x22, 0xc5, 0x0f, 0xa8, 0x03, 0x28, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xdc, 0x00, 0xb3, 0x60, 0xa1, 0xd8, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xe7, 0x14, 0x2f, + 0xc8, 0x08, 0x50, 0x02, 0xdc, 0x00, 0xbd, 0x00, + 0x21, 0x80, 0x0b, 0x60, 0x02, 0x18, 0x00, 0xb6, + 0x00, 0x23, 0xc0, 0x0d, 0x40, 0x03, 0xd4, 0x04, + 0xf3, 0x68, 0x35, 0xc0, 0x0b, 0xf0, 0x43, 0x5c, + 0x00, 0xb7, 0x20, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x21, 0xe0, + 0x0b, 0x7a, 0x02, 0xde, 0x00, 0x97, 0x90, 0x2d, + 0xe4, 0x28, 0x78, 0x02, 0xdf, 0x00, 0xb7, 0xc0, + 0x61, 0x60, 0x0b, 0x18, 0x02, 0x16, 0x00, 0xb1, + 0x84, 0x21, 0xc0, 0x09, 0x78, 0x02, 0xfe, 0x00, + 0x97, 0xa0, 0x25, 0xe8, 0x0b, 0x68, 0x02, 0x1e, + 0x00, 0xb7, 0xa0, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xed, 0x09, 0x00, + 0x07, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x10, + 0x02, 0xce, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0b, + 0x30, 0x0a, 0x0c, 0x00, 0xb3, 0x01, 0xa0, 0x92, + 0x09, 0xb9, 0x82, 0x8e, 0x00, 0xb3, 0x00, 0x24, + 0xc0, 0x8b, 0x39, 0x02, 0x4c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x8b, 0x30, 0x02, 0xd2, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xa8, 0x00, + 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, + 0x00, 0xfa, 0x02, 0x32, 0x80, 0x0b, 0xa0, 0x23, + 0xe8, 0x00, 0xda, 0x00, 0x3e, 0x80, 0x0c, 0xec, + 0x13, 0xdb, 0x00, 0xfe, 0xc3, 0xb3, 0x80, 0x0f, + 0xe0, 0x03, 0x38, 0x00, 0xfe, 0x00, 0x73, 0x80, + 0x0d, 0xec, 0x02, 0xfb, 0x28, 0xda, 0x00, 0xb6, + 0x80, 0x0f, 0xe0, 0x03, 0x39, 0x10, 0xfa, 0x00, + 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xfa, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x02, + 0xe0, 0x00, 0xe8, 0x00, 0x3e, 0x00, 0x0f, 0x89, + 0x03, 0xe2, 0x00, 0xf8, 0xc0, 0x3e, 0x10, 0x07, + 0x00, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x10, + 0x0f, 0x80, 0x01, 0xe2, 0x00, 0xf8, 0x40, 0x3e, + 0x00, 0x0f, 0x82, 0x03, 0xe1, 0x65, 0xf8, 0x00, + 0x3e, 0x10, 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x80, 0x3c, 0x40, 0x8c, 0x10, 0x0b, + 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x02, 0x64, 0x00, 0xc9, 0x00, 0x3c, 0x42, 0x2c, + 0x90, 0x03, 0x44, 0x00, 0xd9, 0x40, 0x3c, 0x44, + 0x0d, 0x90, 0x03, 0x24, 0x00, 0xf1, 0x02, 0x32, + 0x40, 0x0f, 0x98, 0x03, 0xe4, 0x00, 0xf1, 0x00, + 0xed, 0x09, 0x00, 0x08, 0x00, 0x32, 0x40, 0x0f, + 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x01, + 0x2e, 0x40, 0x08, 0x90, 0x02, 0x24, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x10, 0x02, 0x25, 0x00, + 0x89, 0x40, 0x2e, 0x50, 0x08, 0x94, 0x02, 0x24, + 0x00, 0x89, 0xc0, 0x26, 0x50, 0x08, 0x90, 0x02, + 0x24, 0x00, 0xb9, 0x00, 0x2a, 0x40, 0x0b, 0x94, + 0x42, 0xe7, 0x20, 0xb9, 0x00, 0x2a, 0x48, 0x0b, + 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x10, + 0x2e, 0x40, 0x08, 0x91, 0x02, 0x24, 0x00, 0xb9, + 0x80, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe6, 0x00, + 0x89, 0x88, 0x2e, 0x40, 0x09, 0x90, 0x82, 0x64, + 0x02, 0x99, 0x08, 0x2a, 0x42, 0x09, 0x90, 0x0a, + 0x24, 0x00, 0xb9, 0x08, 0x22, 0x40, 0x0b, 0x92, + 0x82, 0xec, 0x84, 0xb9, 0x02, 0x22, 0x40, 0x0b, + 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x29, + 0x2c, 0x40, 0x08, 0x12, 0x82, 0x04, 0x00, 0xb1, + 0x28, 0x2c, 0x59, 0x0b, 0x90, 0x02, 0xa7, 0x00, + 0x81, 0x40, 0x2c, 0xc0, 0x09, 0x10, 0x02, 0x04, + 0x00, 0x81, 0x00, 0x24, 0x51, 0x18, 0x14, 0x06, + 0x04, 0x00, 0xb1, 0x42, 0x68, 0x50, 0x4b, 0x14, + 0x02, 0xc5, 0x00, 0xb1, 0x01, 0x28, 0x50, 0x0b, + 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb8, 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x20, + 0x3e, 0x00, 0x2c, 0x82, 0x03, 0x20, 0x00, 0xf8, + 0x23, 0x3e, 0x00, 0xed, 0x09, 0x00, 0x09, 0x00, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xc8, 0x00, 0x3e, + 0x01, 0x4d, 0x80, 0x03, 0x60, 0x00, 0xd8, 0x00, + 0x3e, 0x00, 0x0d, 0x80, 0x03, 0x20, 0x00, 0xf8, + 0x00, 0x32, 0x00, 0x8f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, 0xee, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1d, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x50, 0x1f, + 0x90, 0x03, 0xe4, 0xa0, 0xf9, 0x00, 0x3e, 0x45, + 0x4f, 0xd2, 0x93, 0x74, 0x02, 0xfd, 0x00, 0x3f, + 0x50, 0x0e, 0xd4, 0x03, 0xf5, 0x00, 0xfd, 0x41, + 0x37, 0x50, 0xcf, 0xd0, 0x03, 0xf4, 0x00, 0xf9, + 0x40, 0x3e, 0x50, 0x0f, 0xd4, 0x43, 0x7d, 0x00, + 0xf9, 0x40, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe6, + 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0d, 0x90, + 0x03, 0xe4, 0x00, 0xfd, 0x20, 0x32, 0x48, 0x0f, + 0xd2, 0x03, 0xe4, 0x00, 0xfd, 0x00, 0x3e, 0x50, + 0x0f, 0x90, 0x03, 0xf5, 0x00, 0xfd, 0x00, 0x3a, + 0x41, 0x0e, 0x90, 0x03, 0xe4, 0x80, 0xf9, 0x20, + 0x3b, 0x58, 0x0f, 0x94, 0x03, 0xf4, 0x00, 0xed, + 0x21, 0x32, 0x51, 0x0c, 0xd6, 0x03, 0xf4, 0xa0, + 0xfd, 0x00, 0x3f, 0x50, 0x0f, 0x90, 0x03, 0xc6, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, + 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, + 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x22, 0x10, 0x0b, + 0x81, 0x02, 0xe0, 0x20, 0xb8, 0x00, 0x2e, 0x04, + 0x0b, 0x82, 0x82, 0xe0, 0x84, 0xb8, 0x2a, 0x22, + 0x00, 0x0d, 0x80, 0x02, 0xe1, 0x00, 0x9c, 0x41, + 0x32, 0x10, 0x0b, 0x82, 0x02, 0xe0, 0x00, 0xa8, + 0x40, 0xb6, 0x08, 0x0a, 0x86, 0x02, 0xe1, 0x80, + 0xb8, 0x40, 0x2e, 0x08, 0x0b, 0x80, 0xed, 0x09, + 0x00, 0x0a, 0x00, 0x02, 0xce, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, + 0xb1, 0x10, 0x20, 0x44, 0x0b, 0x10, 0x02, 0xc4, + 0x80, 0xb1, 0x10, 0x2c, 0x48, 0x43, 0x12, 0x02, + 0xc4, 0x00, 0xb1, 0x00, 0xa5, 0x70, 0x09, 0x5c, + 0x02, 0xd7, 0x00, 0xb5, 0xc0, 0x28, 0x78, 0x0a, + 0x10, 0x06, 0xe4, 0x00, 0x81, 0x48, 0x24, 0x50, + 0x08, 0x11, 0x02, 0xc4, 0x20, 0xb1, 0x40, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x22, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x01, 0x2e, 0x40, 0x0b, 0x90, 0x02, + 0xe4, 0x10, 0xb9, 0x20, 0x26, 0x40, 0x09, 0xd0, + 0x06, 0xf4, 0x00, 0x9d, 0x00, 0xa6, 0x40, 0x0b, + 0x92, 0x12, 0xe4, 0x00, 0xa9, 0x00, 0x24, 0x40, + 0x0a, 0x90, 0x02, 0xe4, 0x80, 0xbb, 0x01, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0d, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x12, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe5, 0x20, 0xf9, 0x08, 0x36, 0x50, 0x4d, 0x9c, + 0x43, 0xe5, 0x50, 0xf9, 0x50, 0x2a, 0x60, 0x0f, + 0x9a, 0x03, 0xe4, 0x00, 0xe9, 0x01, 0x36, 0x41, + 0x0c, 0x92, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf1, 0x01, 0xbe, 0x40, 0x0f, 0x90, 0x01, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x8f, 0x92, 0x03, + 0xe4, 0xed, 0x09, 0x00, 0x0b, 0x00, 0x00, 0xf9, + 0x00, 0x30, 0x40, 0x0f, 0x99, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3a, 0x48, 0x8f, 0x90, 0x03, 0xe7, + 0x00, 0xf1, 0x00, 0x3a, 0x40, 0x0f, 0x94, 0x03, + 0xe4, 0x00, 0xf9, 0x08, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0e, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0c, 0x80, 0x02, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x2e, 0x80, 0x03, 0x21, 0x00, 0xc8, + 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, 0xa0, 0x80, + 0xf0, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x40, 0xf8, 0x20, 0x32, 0x00, 0x0c, 0x84, 0x03, + 0xe3, 0x42, 0xc8, 0x04, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, + 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xbe, 0x00, 0x2e, + 0x80, 0x08, 0xa2, 0x02, 0xe8, 0x00, 0xba, 0x80, + 0x2e, 0x80, 0x08, 0xa0, 0x02, 0x38, 0x40, 0xae, + 0xd0, 0x02, 0xa0, 0x0b, 0xa0, 0x02, 0xe9, 0x10, + 0xba, 0x00, 0x33, 0x84, 0x4b, 0xa0, 0x02, 0xca, + 0x10, 0xbe, 0xc0, 0xa2, 0x80, 0x0d, 0xec, 0x02, + 0xf8, 0x10, 0x8e, 0x00, 0x2f, 0xb0, 0x0b, 0xa0, + 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0a, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x60, 0x2c, + 0xc0, 0x09, 0x18, 0x02, 0x4c, 0x08, 0x21, 0x80, + 0x2c, 0xc0, 0x0a, 0x30, 0x02, 0x0f, 0x40, 0x8b, + 0x90, 0xa0, 0xc0, 0x1b, 0x30, 0x02, 0x8d, 0x04, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x00, 0xc4, + 0x00, 0xb3, 0x80, 0x20, 0xc0, 0x08, 0x3c, 0x82, + 0xce, 0x10, 0x83, 0x80, 0x2c, 0xc2, 0x0b, 0x30, + 0x02, 0xca, 0x00, 0x50, 0xed, 0x09, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xdc, 0x00, 0xb5, 0x00, 0x2d, 0xe0, 0x09, 0x70, + 0x02, 0xdc, 0xc0, 0xb7, 0x08, 0x2c, 0xec, 0x48, + 0xfa, 0x02, 0x16, 0x00, 0xa5, 0x00, 0x21, 0xd0, + 0x0b, 0x50, 0x02, 0xd4, 0x00, 0xb7, 0x00, 0x21, + 0x80, 0x0b, 0x73, 0x02, 0xdc, 0x00, 0xb3, 0x0a, + 0x20, 0xc8, 0x09, 0x74, 0x02, 0xce, 0x04, 0x86, + 0x40, 0x2d, 0x82, 0x8b, 0x70, 0x02, 0xe8, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x1e, + 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0e, 0x78, 0x03, + 0xde, 0x00, 0xf7, 0x80, 0x3c, 0xe0, 0x2d, 0x78, + 0x43, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0e, + 0x7e, 0x02, 0x3e, 0x00, 0xcf, 0x82, 0x31, 0xa0, + 0x0f, 0x68, 0x03, 0x9e, 0x00, 0xb4, 0x80, 0x3d, + 0xe0, 0x0f, 0x78, 0x03, 0xd6, 0x00, 0xf7, 0x80, + 0x31, 0xe0, 0x0c, 0x78, 0x03, 0xde, 0x00, 0xc7, + 0x84, 0x3d, 0xe0, 0x07, 0x78, 0x03, 0xea, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0e, 0xb0, + 0x03, 0xed, 0x00, 0xfb, 0x00, 0x3e, 0xc8, 0x0f, + 0x30, 0x0b, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x80, + 0x0f, 0x80, 0x03, 0xe4, 0x00, 0xf8, 0x00, 0x36, + 0xc0, 0x0f, 0xb0, 0x02, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xdc, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfa, + 0x04, 0x3e, 0x80, 0x0f, 0xb0, 0x03, 0xc2, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, + 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, + 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, + 0x01, 0x7f, 0x00, 0xff, 0x80, 0x33, 0xf0, 0x0c, + 0xf8, 0x43, 0xfe, 0x02, 0xdf, 0x80, 0x3f, 0xed, + 0x09, 0x00, 0x0d, 0x00, 0x60, 0x0c, 0xf9, 0x03, + 0xba, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, + 0x03, 0x14, 0x80, 0xcd, 0x80, 0x3b, 0xf0, 0x2c, + 0xf8, 0x03, 0xfa, 0x00, 0xff, 0x84, 0x3f, 0xe0, + 0x0f, 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb4, + 0x11, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, + 0xb7, 0x00, 0x21, 0xc0, 0x28, 0x70, 0x03, 0xfc, + 0x42, 0xd6, 0x00, 0x39, 0x40, 0x0d, 0x50, 0x4b, + 0x10, 0x00, 0xc7, 0x10, 0x39, 0xc1, 0x0f, 0xf0, + 0x02, 0x14, 0x00, 0xd5, 0x02, 0x23, 0xc0, 0x08, + 0x70, 0x03, 0xd8, 0x00, 0xb4, 0x00, 0x3d, 0x40, + 0x0f, 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x0b, 0x51, 0x02, 0xdc, 0x00, + 0xb1, 0x00, 0x21, 0xc0, 0x09, 0x70, 0x82, 0xdc, + 0x00, 0x96, 0x00, 0x2c, 0x00, 0x09, 0x20, 0x42, + 0x08, 0x00, 0xa4, 0x00, 0x2d, 0xd0, 0x0b, 0x70, + 0x02, 0x34, 0x00, 0x95, 0x00, 0x25, 0xc0, 0x08, + 0x60, 0x02, 0xd8, 0x00, 0xb7, 0x10, 0x2d, 0x80, + 0x0b, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x14, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb2, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x20, 0xc0, 0x09, 0x38, 0x22, 0x8d, + 0x00, 0x0b, 0xc0, 0x28, 0x00, 0x29, 0x04, 0x02, + 0x01, 0x10, 0x90, 0x40, 0x28, 0xe0, 0x0a, 0x36, + 0x02, 0x04, 0x00, 0x81, 0x00, 0xa4, 0xc0, 0x88, + 0x1e, 0x02, 0xc1, 0x00, 0xb0, 0x00, 0x28, 0x00, + 0x0a, 0x30, 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x0e, 0x00, 0xa8, + 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xf2, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x02, 0xfc, 0x00, 0xfb, 0x00, 0xb3, + 0xc0, 0x0d, 0xfc, 0x02, 0xe0, 0x12, 0x59, 0xd0, + 0x3e, 0xe0, 0x0d, 0xbc, 0x03, 0x2e, 0x00, 0xeb, + 0x80, 0x3e, 0xc2, 0x0b, 0xf4, 0x03, 0x0c, 0x00, + 0x92, 0x04, 0xbf, 0xc0, 0x08, 0x84, 0x03, 0xe5, + 0x00, 0xf1, 0x00, 0x2e, 0x40, 0x0b, 0xb0, 0x03, + 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xf8, 0x00, 0x3e, 0xc0, + 0x0f, 0x90, 0x02, 0xec, 0x00, 0xf9, 0x00, 0x3e, + 0xc0, 0x0e, 0xb0, 0x03, 0xe1, 0x90, 0xf9, 0x50, + 0x78, 0xe0, 0x0e, 0x9a, 0x03, 0xa6, 0x00, 0xeb, + 0x80, 0x3e, 0x80, 0x0f, 0xb0, 0x0b, 0xec, 0x00, + 0xfb, 0x40, 0x3a, 0xc0, 0x8f, 0x81, 0x13, 0xa5, + 0xc1, 0xf8, 0x40, 0x3e, 0x00, 0x0f, 0xb0, 0x03, + 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xfc, 0x00, 0x3b, 0xc0, + 0x0f, 0xf8, 0x03, 0xbc, 0x00, 0xe7, 0x10, 0x33, + 0xc0, 0x0b, 0xf0, 0x83, 0x30, 0x00, 0xfd, 0x00, + 0x37, 0x81, 0x4c, 0xe0, 0x43, 0x7c, 0x20, 0xf4, + 0x08, 0x37, 0x40, 0x0d, 0xf0, 0x02, 0x3c, 0x80, + 0xdf, 0x00, 0x33, 0xc0, 0x0c, 0x40, 0x03, 0x30, + 0x00, 0xfd, 0x83, 0xb3, 0x44, 0x8c, 0xf0, 0x03, + 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, + 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xec, 0x00, 0xb8, 0x08, 0x22, 0xc0, + 0x0b, 0xb8, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, + 0xc0, 0x0b, 0x30, 0x22, 0x27, 0x00, 0xb9, 0xc0, + 0x22, 0x80, 0x0a, 0x80, 0x03, 0xed, 0x09, 0x00, + 0x0f, 0x00, 0xe4, 0x00, 0xb8, 0x00, 0x20, 0x60, + 0x0f, 0x30, 0x0a, 0xac, 0x00, 0xfb, 0x08, 0x3e, + 0xc0, 0x08, 0x8c, 0x82, 0x27, 0x90, 0xb8, 0xc0, + 0x22, 0x01, 0x08, 0xb0, 0x02, 0xe0, 0x40, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0xbb, 0x80, 0x2a, 0xc0, 0x0b, 0xb2, 0x02, + 0xec, 0x00, 0xab, 0x00, 0x22, 0xc0, 0x0b, 0xb0, + 0x0a, 0x63, 0x18, 0x99, 0x88, 0x22, 0x41, 0x18, + 0xb0, 0x06, 0xe8, 0x01, 0xbb, 0x04, 0x26, 0xe1, + 0x0b, 0xb0, 0x12, 0xa4, 0x10, 0x89, 0x00, 0x20, + 0xc0, 0x48, 0x98, 0x12, 0x26, 0x00, 0xb8, 0x20, + 0x20, 0xc0, 0x08, 0xb0, 0x42, 0xe0, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xb0, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0xa0, 0xc0, 0x0b, 0xb0, + 0x02, 0x00, 0x00, 0xb1, 0x00, 0x20, 0x40, 0x0a, + 0x10, 0x02, 0x80, 0x00, 0xb3, 0x00, 0x20, 0xc0, + 0x09, 0xb0, 0x02, 0x04, 0x00, 0x91, 0x00, 0x2c, + 0xc0, 0x48, 0x10, 0x02, 0x04, 0x00, 0xb0, 0x00, + 0x20, 0x40, 0x28, 0x30, 0x00, 0xc2, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xf9, 0x00, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, + 0xfc, 0x00, 0xeb, 0x00, 0x21, 0xc0, 0x0f, 0xb0, + 0x03, 0x64, 0x04, 0xb9, 0x00, 0x36, 0x01, 0x08, + 0xa0, 0x02, 0x68, 0x00, 0xf8, 0x00, 0x36, 0x40, + 0xaf, 0xb0, 0x03, 0xa4, 0x08, 0xc1, 0x00, 0x33, + 0xc0, 0x0c, 0x80, 0x0b, 0x20, 0x00, 0xf8, 0x00, + 0x32, 0x80, 0x0c, 0xb0, 0x03, 0xc0, 0x03, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, + 0xed, 0x09, 0x00, 0x10, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xfc, 0x00, + 0x3f, 0xc0, 0x0f, 0xd0, 0x03, 0xfc, 0x00, 0xfd, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x07, 0xf4, 0x00, + 0xfd, 0x00, 0xbf, 0x00, 0x0f, 0xc0, 0x03, 0xf0, + 0x00, 0xfc, 0x00, 0x3f, 0x40, 0x0f, 0xf0, 0x03, + 0xf4, 0x00, 0xfd, 0x00, 0x3f, 0xc1, 0x0f, 0xd0, + 0x03, 0xf4, 0x08, 0xfc, 0x00, 0x3f, 0x00, 0x0f, + 0xf0, 0x03, 0x68, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xc0, 0x03, 0x3c, 0xc8, 0xff, 0x00, + 0x3f, 0xc0, 0xcc, 0xd0, 0x02, 0xf5, 0x00, 0xff, + 0x21, 0x33, 0xc0, 0x0e, 0xf2, 0x03, 0xf4, 0x00, + 0xfd, 0x10, 0x33, 0x04, 0x0c, 0xf0, 0x0b, 0x34, + 0x00, 0xff, 0x01, 0x3f, 0xc0, 0x8f, 0xf1, 0x03, + 0xf4, 0x00, 0xff, 0x44, 0x33, 0xc1, 0x0c, 0xc0, + 0x03, 0x3c, 0x40, 0xff, 0x00, 0x3f, 0xc4, 0x4f, + 0xf0, 0x22, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0x3d, 0x88, 0xbf, 0x40, + 0x22, 0xd0, 0x08, 0xb0, 0x02, 0xee, 0x00, 0xbf, + 0x9c, 0x23, 0xc4, 0x08, 0xf4, 0x02, 0xe4, 0x00, + 0xba, 0x01, 0x22, 0x88, 0x08, 0xb4, 0x02, 0x2c, + 0x00, 0xbb, 0x00, 0x3e, 0x40, 0x08, 0xf0, 0x02, + 0xe4, 0x00, 0xbb, 0x00, 0x2a, 0xc0, 0x0d, 0x82, + 0x12, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc8, 0x0b, + 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x88, 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0xa0, 0x02, 0x0d, 0x80, 0xb3, 0x10, + 0x24, 0xc4, 0x08, 0x30, 0x02, 0x4c, 0x80, 0xb3, + 0x20, 0x20, 0xc0, 0x08, 0x34, 0x02, 0xc4, 0x00, + 0xb1, 0x20, 0x20, 0x00, 0x28, 0x21, 0x02, 0x44, + 0x00, 0xb3, 0x00, 0xed, 0x09, 0x00, 0x11, 0x00, + 0x2e, 0xc0, 0x8a, 0x32, 0x42, 0xc4, 0xa0, 0xb3, + 0x20, 0x20, 0xc0, 0x28, 0x80, 0x82, 0x0c, 0x80, + 0xb3, 0x00, 0x2c, 0xc8, 0x0b, 0x30, 0x02, 0xe2, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, + 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x26, 0xc1, 0x28, + 0x92, 0x02, 0xec, 0x80, 0xbb, 0x00, 0x22, 0xc0, + 0x28, 0xb0, 0x02, 0xe6, 0x10, 0xb9, 0x80, 0x26, + 0xa2, 0x09, 0xb0, 0x82, 0x6c, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x88, 0xb0, 0x02, 0xe4, 0x40, 0xbb, + 0x00, 0x0a, 0xc0, 0x09, 0xb0, 0x0a, 0x2c, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xf0, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xbc, + 0x83, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0c, + 0xb0, 0x03, 0x6e, 0x00, 0xfb, 0x00, 0x32, 0xc0, + 0x04, 0xb0, 0x02, 0xe2, 0x10, 0xb9, 0x80, 0x32, + 0x70, 0x0c, 0xbc, 0x03, 0x64, 0x40, 0xfb, 0x02, + 0x3e, 0x60, 0x0e, 0xb0, 0x43, 0xe6, 0x00, 0xbb, + 0x00, 0x30, 0xc0, 0x0c, 0x08, 0x07, 0x2c, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, + 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xda, + 0x03, 0xfc, 0x08, 0xf7, 0x00, 0x3b, 0xc0, 0x0f, + 0xf8, 0x03, 0xfc, 0x00, 0xfb, 0x02, 0x3f, 0xc0, + 0x0d, 0xf0, 0x03, 0xf4, 0x00, 0xfa, 0x00, 0x38, + 0xc0, 0x0e, 0xf1, 0x03, 0xbe, 0x00, 0xff, 0x00, + 0x3b, 0x30, 0x0e, 0xf0, 0x03, 0xf4, 0x00, 0xff, + 0x02, 0x3f, 0xc0, 0x0f, 0xd2, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, + 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0xed, 0x09, + 0x00, 0x12, 0x00, 0x0f, 0xb8, 0x03, 0x2c, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb8, 0x03, 0xe4, + 0x00, 0xc3, 0x08, 0x32, 0xc0, 0x0e, 0xb1, 0x07, + 0xa5, 0x00, 0xcb, 0x00, 0x72, 0xd0, 0x2d, 0xa0, + 0x03, 0x64, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0e, + 0xb0, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x2e, 0xc0, + 0x0f, 0x80, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x4b, 0x34, 0x02, 0x3c, 0x00, + 0xbf, 0xf0, 0x2d, 0xc8, 0x0b, 0xb5, 0x02, 0xec, + 0x00, 0x8f, 0x00, 0x21, 0xe8, 0x03, 0xfd, 0x02, + 0xe4, 0x94, 0x8b, 0x00, 0x22, 0xc0, 0x08, 0x38, + 0x02, 0xef, 0x00, 0x3f, 0x02, 0x2c, 0xa0, 0x08, + 0xf0, 0x03, 0x6c, 0x00, 0x3f, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x0a, 0x2c, 0x00, 0xbb, 0x00, 0x2e, + 0xc2, 0x0b, 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x05, 0x4c, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x82, 0x0c, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x34, 0x00, 0xcc, + 0x00, 0xa3, 0x00, 0x20, 0xc0, 0x0b, 0x34, 0x02, + 0x84, 0x00, 0x8b, 0x00, 0x60, 0x00, 0x08, 0x08, + 0x02, 0xcf, 0x20, 0xb3, 0x00, 0x28, 0x68, 0x08, + 0x30, 0x02, 0x04, 0x00, 0xbb, 0x02, 0x2c, 0xcc, + 0x0b, 0x00, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0xd2, 0x0b, 0x30, 0x02, 0xf8, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x00, 0xb7, + 0x80, 0x2d, 0xe1, 0x0b, 0xf8, 0x02, 0x1e, 0x08, + 0xb7, 0x82, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xd6, + 0x00, 0xa7, 0x80, 0x21, 0xe0, 0x0b, 0x78, 0x00, + 0xdc, 0x00, 0x86, 0x84, 0x21, 0xa0, 0x18, 0x78, + 0x02, 0xde, 0x20, 0xb7, 0x80, 0x2f, 0x64, 0x08, + 0x78, 0xed, 0x09, 0x00, 0x13, 0x00, 0x02, 0x56, + 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x68, 0x02, + 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe4, 0x0b, 0x78, + 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, + 0x0f, 0x10, 0x03, 0x0c, 0x00, 0xf3, 0x00, 0x1c, + 0xc5, 0x0f, 0x30, 0x03, 0xec, 0x82, 0xe3, 0x00, + 0x30, 0xc0, 0x0e, 0x30, 0x03, 0xad, 0x40, 0xc3, + 0x00, 0x80, 0x00, 0x0c, 0x10, 0x83, 0xcc, 0x00, + 0xf3, 0x00, 0x3c, 0xc2, 0x8e, 0xb0, 0x03, 0x04, + 0x00, 0xf3, 0x10, 0x3c, 0xc4, 0x0f, 0x81, 0x03, + 0x0c, 0x00, 0xf3, 0x20, 0x3c, 0xc0, 0x0f, 0x30, + 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0x70, 0x03, 0xfd, 0x60, 0xff, 0x00, 0x3f, + 0xc4, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xdf, 0x10, + 0x3f, 0xd0, 0x0f, 0xf0, 0x03, 0xfc, 0x80, 0xff, + 0x00, 0x3f, 0x84, 0x2e, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3d, 0xc0, 0x0f, 0xf4, 0x03, 0xf4, + 0x40, 0xff, 0x10, 0x37, 0xc5, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc1, 0x0f, 0xf0, + 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x01, 0xec, 0x00, 0xeb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xed, 0x80, 0xcb, 0x01, 0x3e, + 0xc0, 0x0f, 0x98, 0x07, 0xac, 0x00, 0xcb, 0xd8, + 0x32, 0xd0, 0x07, 0xb1, 0x03, 0x6c, 0x00, 0xfb, + 0x00, 0x32, 0x80, 0x8e, 0x80, 0x03, 0xac, 0x00, + 0xeb, 0x10, 0x3c, 0x40, 0x0c, 0xb5, 0x03, 0x2e, + 0x02, 0xeb, 0x00, 0x3e, 0xc0, 0x0f, 0x80, 0x03, + 0xec, 0x00, 0x7b, 0x00, 0x3e, 0xe0, 0x0d, 0xb0, + 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xcc, 0xed, 0x09, 0x00, 0x14, + 0x00, 0x00, 0x87, 0x29, 0x2d, 0xc0, 0x0b, 0x70, + 0x42, 0x1c, 0x02, 0x8f, 0x20, 0xa1, 0xd8, 0x5b, + 0x71, 0x03, 0x9c, 0x00, 0xb6, 0x00, 0x21, 0x80, + 0x08, 0x70, 0x4a, 0x1c, 0x00, 0xc7, 0x00, 0x2d, + 0x00, 0x0f, 0x70, 0x03, 0xbc, 0x00, 0x87, 0x40, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xf7, + 0x00, 0x2f, 0xc0, 0x08, 0x70, 0x02, 0xd2, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, + 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0xde, 0x80, 0x87, 0xb0, 0x2d, 0xe4, 0x0b, 0x78, + 0x02, 0x9e, 0x04, 0x87, 0xa4, 0x21, 0xe8, 0x0b, + 0x78, 0x02, 0x5f, 0x00, 0xa3, 0x80, 0x24, 0xe0, + 0x0b, 0x18, 0x02, 0xde, 0x00, 0xb7, 0xa0, 0x2f, + 0xe0, 0x09, 0x7a, 0x02, 0xde, 0x00, 0xa7, 0x80, + 0x2d, 0xe0, 0x0b, 0x48, 0x02, 0xde, 0x00, 0xb7, + 0x80, 0x2d, 0xe0, 0x09, 0x78, 0x02, 0xf0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x1e, 0x02, + 0xcc, 0x00, 0x83, 0x02, 0x2c, 0xc0, 0x0b, 0x18, + 0x02, 0x86, 0x40, 0x83, 0x00, 0x20, 0xc1, 0x0b, + 0x30, 0x22, 0xcd, 0x80, 0xb3, 0x90, 0x20, 0xf8, + 0x0b, 0x30, 0x02, 0x0c, 0x00, 0x8b, 0x00, 0x6c, + 0xa0, 0x0b, 0x30, 0x00, 0x8c, 0x00, 0xa3, 0x00, + 0x2c, 0xc0, 0x0b, 0xb6, 0x02, 0xcc, 0x10, 0xb3, + 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xd2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xa8, + 0x00, 0xea, 0x00, 0x3e, 0x80, 0x0f, 0xec, 0x03, + 0xe8, 0x02, 0xc2, 0x00, 0x3e, 0x80, 0x0f, 0xaa, + 0x03, 0xa8, 0x00, 0xca, 0x00, 0x32, 0x80, 0x0f, + 0xa0, 0x03, 0x79, 0x00, 0xee, 0x00, 0x37, 0xb2, + 0x6f, 0xe0, 0x03, 0xa8, 0x00, 0xfa, 0x00, 0x3f, + 0x98, 0x0d, 0xa0, 0x23, 0x28, 0x28, 0xea, 0xed, + 0x09, 0x00, 0x15, 0x00, 0x00, 0x3e, 0x80, 0x0f, + 0xe0, 0x03, 0xe8, 0x11, 0xfa, 0x00, 0x3e, 0x80, + 0x1d, 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x81, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x2e, 0x00, 0x0f, 0x80, 0x02, 0x60, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x84, 0x03, 0xa0, + 0x00, 0xf8, 0x00, 0xbe, 0x00, 0x0c, 0x00, 0x03, + 0xe0, 0x00, 0xe8, 0x04, 0x3e, 0x20, 0x0d, 0x80, + 0x03, 0xa0, 0x00, 0xd8, 0x00, 0x3e, 0x10, 0x0f, + 0x80, 0x03, 0xe0, 0x05, 0xe8, 0x01, 0x36, 0x10, + 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xa4, 0x00, 0xc9, + 0x00, 0x3a, 0x60, 0x0f, 0x90, 0x03, 0xe6, 0x00, + 0xd9, 0x02, 0x3e, 0x40, 0x0f, 0x98, 0x07, 0xe4, + 0x00, 0xf1, 0x00, 0x34, 0x40, 0x05, 0x90, 0x03, + 0x44, 0x00, 0xc9, 0x00, 0x22, 0x40, 0x29, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x05, 0x3a, 0x50, 0x0b, + 0x90, 0x02, 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, 0xe9, 0x00, + 0x2e, 0x40, 0x4b, 0x14, 0x02, 0x24, 0x00, 0x89, + 0x00, 0x22, 0x64, 0x4b, 0x94, 0x02, 0xc6, 0x40, + 0x89, 0x00, 0x2e, 0x40, 0x4b, 0x93, 0x02, 0xe6, + 0x00, 0xb9, 0x00, 0x26, 0x40, 0x00, 0x90, 0x03, + 0x65, 0x00, 0x89, 0x00, 0x38, 0x50, 0x18, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x02, 0x2e, 0x60, 0x0b, + 0x90, 0x0a, 0xa4, 0x00, 0xb9, 0x02, 0x0e, 0x58, + 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x98, 0x02, 0x84, 0x00, 0x89, + 0x00, 0x2a, 0xed, 0x09, 0x00, 0x16, 0x00, 0x40, + 0x0b, 0x98, 0x02, 0xe4, 0x00, 0x19, 0x00, 0x2e, + 0x44, 0x0b, 0x90, 0x02, 0xe4, 0xa0, 0xb9, 0x00, + 0xa2, 0x40, 0x0b, 0x91, 0x02, 0x64, 0x02, 0x89, + 0x00, 0x2a, 0x48, 0x0b, 0x90, 0x00, 0xe4, 0x00, + 0xa9, 0x00, 0x6e, 0x40, 0x0b, 0x90, 0x02, 0xa4, + 0x01, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, + 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x04, 0x00, 0xa1, 0x00, 0x2c, 0x40, 0x0b, + 0x18, 0x02, 0x05, 0x02, 0x81, 0x00, 0x20, 0x40, + 0x0b, 0x18, 0x02, 0xe4, 0x00, 0x81, 0x00, 0x2c, + 0x4a, 0x0b, 0x12, 0x86, 0xc5, 0x00, 0xb1, 0x01, + 0x04, 0x50, 0x0a, 0x10, 0x02, 0x46, 0xa0, 0x81, + 0x2a, 0x68, 0xc0, 0x18, 0x14, 0x02, 0xc5, 0x00, + 0xb1, 0x40, 0x2c, 0x40, 0x01, 0x14, 0x22, 0x85, + 0x00, 0xb1, 0x00, 0x2c, 0x50, 0x0b, 0x10, 0x02, + 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, + 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xa0, 0x00, 0xc8, 0x00, 0x3a, 0x01, + 0x0f, 0x80, 0x03, 0xc1, 0x40, 0xd8, 0x50, 0x2e, + 0x08, 0x0f, 0x82, 0x12, 0xe0, 0x00, 0xf8, 0x00, + 0x32, 0x00, 0x0f, 0x80, 0x03, 0x60, 0x80, 0xc8, + 0x20, 0x3a, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xe8, 0x00, 0x3a, 0x81, 0x0f, 0x80, 0x03, 0xa0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0xd0, 0x03, 0xe5, 0x00, 0xf9, 0x41, 0x3e, 0x50, + 0x0f, 0x50, 0x03, 0xf4, 0x08, 0xf9, 0x40, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xf5, 0x00, 0xfd, 0x68, + 0x3b, 0xd0, 0x0d, 0xd4, 0x01, 0x94, 0xa0, 0xf9, + 0x28, 0x3b, 0x40, 0x0f, 0x94, 0x13, 0xf4, 0x04, + 0xf9, 0x40, 0x3e, 0x40, 0x07, 0xed, 0x09, 0x00, + 0x17, 0x00, 0xd0, 0x03, 0x64, 0x08, 0xd9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xd0, 0x13, 0xe4, + 0x90, 0xcd, 0x28, 0x37, 0x48, 0x0f, 0xd0, 0x03, + 0xf4, 0x00, 0xfd, 0x00, 0x3b, 0x48, 0x0f, 0x50, + 0x03, 0x74, 0xc0, 0xf9, 0x10, 0x36, 0x40, 0x0f, + 0xd0, 0x03, 0xf4, 0xc0, 0xf9, 0x00, 0x2b, 0x40, + 0x0f, 0x90, 0x03, 0xc4, 0x00, 0xc9, 0x10, 0x3d, + 0x40, 0x0c, 0x90, 0x03, 0xe4, 0x40, 0xc9, 0x00, + 0x7f, 0x40, 0x0f, 0x90, 0x03, 0xc6, 0x01, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x00, + 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, + 0xa0, 0x88, 0x05, 0x22, 0x04, 0x0b, 0x80, 0x03, + 0xa0, 0xa0, 0xb0, 0x30, 0x2e, 0x05, 0x0b, 0x84, + 0x02, 0x20, 0xc0, 0xb8, 0x40, 0x22, 0x02, 0x0e, + 0x81, 0x02, 0xe0, 0xc0, 0xb8, 0x48, 0x66, 0x00, + 0x09, 0x84, 0x80, 0xe0, 0x20, 0x88, 0x14, 0x2e, + 0x00, 0x0d, 0x82, 0x02, 0xe0, 0x80, 0xd8, 0x01, + 0x3a, 0x02, 0x0b, 0x80, 0x02, 0xce, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, + 0xc0, 0x81, 0x00, 0x2c, 0x40, 0x0b, 0x30, 0x02, + 0xc4, 0x80, 0xb1, 0x28, 0x28, 0x40, 0x1b, 0x11, + 0x28, 0x04, 0x80, 0xb1, 0x10, 0x20, 0x45, 0x09, + 0x10, 0x02, 0xc4, 0x80, 0xb1, 0x30, 0x22, 0x40, + 0x0a, 0x13, 0x12, 0xc4, 0x03, 0xa1, 0x01, 0x2c, + 0x40, 0x00, 0x12, 0x82, 0xc4, 0x90, 0x81, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, + 0xb9, 0x00, 0x6e, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0x8b, 0x00, 0x2a, 0x40, 0x0b, 0x90, 0x02, + 0xed, 0x09, 0x00, 0x18, 0x00, 0xa6, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x27, 0x00, + 0xb1, 0x40, 0x20, 0x40, 0x0a, 0x90, 0x82, 0xe4, + 0x00, 0xb9, 0x00, 0x26, 0x60, 0x0b, 0x90, 0x52, + 0x64, 0x80, 0xa9, 0x00, 0x2e, 0x40, 0x09, 0x90, + 0x82, 0xe4, 0x00, 0x99, 0x06, 0x2a, 0x40, 0x0b, + 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x41, 0x0f, 0x91, 0x03, 0xe4, 0x02, 0xc1, 0x00, + 0x3e, 0x40, 0x0f, 0x98, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3a, 0x40, 0x0f, 0x90, 0x12, 0x25, 0x00, + 0xf9, 0x50, 0x32, 0x50, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x32, 0x60, 0x8e, 0x90, 0x03, + 0xe4, 0x00, 0xe9, 0x00, 0x1e, 0x40, 0x48, 0x9c, + 0x03, 0xe4, 0x00, 0xc9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xc4, 0x00, 0xf9, 0x04, + 0x36, 0x40, 0x0f, 0x94, 0x03, 0xe4, 0x20, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x10, 0x03, 0xa4, 0x00, + 0xf9, 0x82, 0xba, 0x48, 0x05, 0x90, 0x13, 0xe4, + 0x10, 0xf9, 0x00, 0x36, 0x40, 0x0c, 0x90, 0x03, + 0xe6, 0x00, 0xd9, 0x00, 0x3e, 0x40, 0x0f, 0x99, + 0x03, 0xe4, 0x04, 0xf9, 0x00, 0x12, 0x40, 0x0f, + 0x90, 0x03, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x88, 0x03, 0xe0, 0x02, 0xc8, 0x00, + 0x3a, 0x00, 0x0f, 0x88, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x32, 0x00, 0x0c, 0x88, 0x03, 0x60, 0x28, + 0xe8, 0x40, 0x32, 0x11, 0x07, 0x84, 0x03, 0xe2, + 0x00, 0xc8, 0x00, 0x3a, 0x20, 0x0f, 0x80, 0x03, + 0xe0, 0x10, 0xc8, 0x00, 0x3e, 0x02, 0x0c, 0x80, + 0x43, 0xe0, 0x00, 0xed, 0x09, 0x00, 0x19, 0x00, + 0xf8, 0x00, 0x3e, 0x04, 0x0f, 0x80, 0x03, 0xca, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x43, 0xe6, + 0x02, 0xe8, 0x00, 0x8e, 0x40, 0x0e, 0x80, 0x0b, + 0xe4, 0x03, 0xb8, 0x80, 0xbe, 0xf0, 0x22, 0x80, + 0x08, 0xec, 0x02, 0x3a, 0x00, 0x8a, 0x01, 0xa2, + 0x80, 0x0b, 0xa0, 0x02, 0xfb, 0x80, 0x8a, 0x00, + 0x29, 0x92, 0x0b, 0xa0, 0x03, 0xa8, 0x08, 0x0a, + 0x02, 0x2d, 0x80, 0x48, 0xa0, 0x02, 0xe8, 0x00, + 0xba, 0x00, 0x2f, 0x80, 0x0b, 0xa0, 0x02, 0xca, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x18, + 0x02, 0xcc, 0x00, 0x83, 0xf0, 0x28, 0x44, 0x0b, + 0x10, 0x02, 0x82, 0x00, 0xb0, 0x00, 0xa4, 0x60, + 0x09, 0x18, 0x0a, 0x0c, 0x00, 0xb3, 0x02, 0x20, + 0xc0, 0x4b, 0x11, 0x02, 0x8c, 0x00, 0x83, 0x00, + 0x20, 0xc0, 0x09, 0x30, 0x02, 0xac, 0x00, 0xb3, + 0x00, 0x2c, 0xe0, 0x08, 0x30, 0x32, 0xec, 0x08, + 0xb3, 0x00, 0x2c, 0xe0, 0x0b, 0x30, 0x02, 0xca, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, + 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xdc, 0xc0, 0x84, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0x90, 0x00, 0xb5, 0x80, 0x20, 0xf0, + 0x89, 0x70, 0x82, 0x0e, 0x28, 0x9f, 0x30, 0xa9, + 0xc8, 0x09, 0x50, 0x02, 0xde, 0x00, 0x83, 0xa0, + 0x29, 0xc0, 0x0b, 0x70, 0x02, 0xbc, 0x80, 0x97, + 0x00, 0x2d, 0xd0, 0xe8, 0x72, 0x02, 0xdc, 0x80, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xe8, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, + 0x1e, 0x00, 0xf7, 0x80, 0x2d, 0xe0, 0x0f, 0x78, + 0x03, 0xfe, 0xc0, 0xc7, 0x80, 0x39, 0xe0, 0x0f, + 0x78, 0x03, 0x92, 0x00, 0xf4, 0x80, 0xed, 0x09, + 0x00, 0x1a, 0x00, 0x35, 0xe0, 0x2d, 0x78, 0x03, + 0x5e, 0x00, 0xf7, 0xa8, 0x21, 0xf4, 0x0f, 0x58, + 0x03, 0xfe, 0x00, 0xc7, 0xe2, 0x39, 0xe0, 0x0f, + 0x7e, 0x03, 0x9e, 0x08, 0xf7, 0x80, 0x3d, 0xe0, + 0x08, 0x7e, 0x03, 0xdf, 0x00, 0xf7, 0x80, 0x2d, + 0xe0, 0x4f, 0x78, 0x23, 0xea, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x4d, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x80, + 0xf8, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xb0, + 0x00, 0xfd, 0x00, 0x3e, 0xc0, 0x0e, 0xb0, 0x01, + 0xec, 0x00, 0xe3, 0x60, 0xb6, 0xc0, 0x8f, 0x90, + 0x03, 0xec, 0x12, 0xdb, 0x04, 0x3e, 0xc0, 0x8f, + 0xb0, 0x03, 0xac, 0x42, 0xeb, 0x00, 0x36, 0x00, + 0x47, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0x80, 0x0d, 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, + 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, + 0xff, 0x80, 0x3f, 0xe4, 0x0f, 0xf1, 0x03, 0xfa, + 0x00, 0xce, 0x80, 0x33, 0xe1, 0x8f, 0xf8, 0x42, + 0x3e, 0x00, 0x6f, 0x80, 0x1b, 0xe0, 0x6c, 0xd9, + 0x03, 0xbc, 0x80, 0xff, 0x80, 0x2f, 0xe4, 0x0e, + 0xf9, 0x03, 0x3e, 0x00, 0xff, 0x88, 0x33, 0xa0, + 0x0f, 0xf9, 0x03, 0x3e, 0x00, 0xff, 0x80, 0x3f, + 0xe0, 0x0d, 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xb7, + 0x00, 0x2d, 0xc4, 0x0b, 0x50, 0x82, 0xdc, 0x40, + 0xb4, 0x10, 0x2d, 0x40, 0x0b, 0x70, 0x02, 0xf8, + 0x00, 0x8e, 0x10, 0x25, 0xc0, 0x0b, 0x70, 0x02, + 0x5d, 0x88, 0xb7, 0x00, 0x21, 0xc4, 0x08, 0x50, + 0x02, 0x11, 0x40, 0xb7, 0x00, 0x2d, 0xc0, 0x28, + 0x70, 0x03, 0x5c, 0x00, 0xb7, 0x00, 0x21, 0x88, + 0x0b, 0xf0, 0x02, 0x9c, 0x00, 0xf7, 0x00, 0x2d, + 0x40, 0xed, 0x09, 0x00, 0x1b, 0x00, 0x0b, 0x70, + 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x1b, 0x51, 0x06, 0x90, 0x02, 0x86, 0x00, + 0x2d, 0x40, 0x0b, 0x10, 0x02, 0x5c, 0x08, 0xa7, + 0x10, 0x29, 0xc2, 0x0a, 0x10, 0x82, 0x9c, 0x40, + 0xb7, 0x00, 0x2f, 0xd1, 0x0a, 0x70, 0x26, 0x9c, + 0x00, 0x97, 0x00, 0x25, 0x80, 0x1b, 0x70, 0x02, + 0x1c, 0x00, 0xb7, 0x10, 0x2d, 0xc0, 0x09, 0x70, + 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x34, 0x02, 0xcc, 0x00, 0xb0, 0x00, 0x2c, + 0xc0, 0x0b, 0x38, 0x02, 0xc0, 0x00, 0x82, 0x00, + 0x2c, 0xc0, 0x83, 0x30, 0x02, 0x4d, 0x20, 0xb3, + 0x40, 0x22, 0xe0, 0x08, 0x18, 0x02, 0x80, 0x41, + 0xb3, 0x00, 0x2c, 0x44, 0x28, 0x30, 0x06, 0xcc, + 0x00, 0xbb, 0x02, 0x24, 0x80, 0x0b, 0x3c, 0x0a, + 0x2c, 0x00, 0xb3, 0x00, 0x6c, 0x01, 0x0b, 0x30, + 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb4, 0x03, 0xfc, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb8, 0x83, 0xa4, 0x00, 0xc8, 0x00, + 0x3a, 0xc0, 0x8f, 0xb0, 0x0b, 0x2e, 0x00, 0xef, + 0x00, 0x7b, 0xc0, 0x0e, 0xb4, 0x23, 0xac, 0x00, + 0xff, 0x00, 0x3c, 0xd0, 0x8e, 0xf0, 0x02, 0xbc, + 0x00, 0xdf, 0x00, 0x36, 0xc0, 0x0b, 0x78, 0x83, + 0x3c, 0x00, 0xfb, 0x00, 0x3e, 0x00, 0x0d, 0xb0, + 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc1, + 0x0f, 0xb4, 0x03, 0xec, 0x00, 0xf3, 0x40, 0x3e, + 0xc0, 0x07, 0x90, 0x03, 0xf7, 0x00, 0xfd, 0x00, + 0x10, 0x40, 0x0f, 0x90, 0xed, 0x09, 0x00, 0x1c, + 0x00, 0x03, 0xaf, 0x10, 0xbb, 0xa2, 0x7e, 0xc0, + 0x0f, 0xb0, 0x8b, 0x6d, 0x00, 0x7b, 0x00, 0x3e, + 0xc0, 0x0f, 0x30, 0x02, 0x6c, 0x00, 0xdb, 0x00, + 0x3a, 0xd1, 0x0f, 0xb0, 0x83, 0xec, 0x00, 0xeb, + 0x00, 0x2e, 0x00, 0x0d, 0xb0, 0x03, 0xe0, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xd0, 0x83, + 0x3c, 0x00, 0xff, 0xc0, 0xb1, 0x68, 0x0c, 0xf1, + 0x23, 0xb4, 0x02, 0xcc, 0xc0, 0x33, 0xe0, 0x2c, + 0xf9, 0x03, 0x5a, 0x04, 0xe3, 0x00, 0x32, 0xc0, + 0x0c, 0x70, 0x03, 0x38, 0x00, 0xff, 0x00, 0x37, + 0xd0, 0x0d, 0xb0, 0x03, 0x3c, 0x00, 0xdb, 0x00, + 0x23, 0x88, 0x0f, 0xf0, 0x03, 0xbc, 0x00, 0xcf, + 0x01, 0x3f, 0x44, 0x0e, 0xf0, 0x03, 0xc0, 0x44, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x36, 0x02, + 0x2c, 0x00, 0xbb, 0x00, 0x2a, 0xc0, 0x4d, 0xb8, + 0x02, 0xe5, 0x00, 0xd9, 0x82, 0x22, 0xc0, 0x08, + 0xbc, 0x82, 0xea, 0x02, 0xab, 0x00, 0x22, 0xc0, + 0x4d, 0x90, 0x23, 0xe8, 0x00, 0xbb, 0x00, 0x26, + 0xf0, 0x88, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2a, 0xb8, 0x8b, 0xb0, 0x0a, 0x2c, 0x02, 0xab, + 0x00, 0x2e, 0x00, 0x0a, 0xb0, 0x02, 0xe0, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb1, 0x06, + 0x2c, 0x00, 0xb8, 0x00, 0x22, 0xc0, 0x09, 0xb0, + 0x02, 0xc8, 0x20, 0xa0, 0x00, 0x62, 0xc8, 0x08, + 0xb0, 0x02, 0xe8, 0x82, 0xab, 0x02, 0x22, 0xc0, + 0x48, 0xb2, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, + 0xd0, 0x0b, 0xb0, 0x12, 0x6c, 0x00, 0xbb, 0x04, + 0x6a, 0x80, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0x8b, + 0x00, 0x2c, 0x80, 0x08, 0xb0, 0x02, 0xe0, 0xed, + 0x09, 0x00, 0x1d, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x0a, 0x0c, 0x00, 0xb0, + 0x00, 0x68, 0xc0, 0x09, 0x38, 0x02, 0xc8, 0x10, + 0xa0, 0x04, 0x20, 0xc0, 0x08, 0x30, 0x02, 0xc8, + 0x00, 0xa3, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x4a, + 0xc0, 0x00, 0xb3, 0x04, 0x2e, 0xc0, 0x09, 0x30, + 0x00, 0xcc, 0x00, 0xb3, 0x00, 0x28, 0x80, 0x1b, + 0xb0, 0x02, 0x0c, 0x00, 0xa3, 0x00, 0x2c, 0x20, + 0x28, 0x30, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xbb, 0x00, + 0x3e, 0xc0, 0x0b, 0xb0, 0x03, 0x3c, 0x00, 0xf8, + 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0xe0, 0x00, + 0xa8, 0x00, 0x22, 0xc0, 0x4c, 0xb0, 0x03, 0x68, + 0x00, 0xef, 0x00, 0x33, 0xc0, 0x0c, 0xb0, 0x23, + 0x28, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x21, 0x6c, 0x00, 0x7b, 0x00, 0x3a, 0x80, 0x0f, + 0xb0, 0x23, 0x2c, 0x00, 0xcb, 0x00, 0x3e, 0xc0, + 0x0e, 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xc0, 0x03, 0xfc, 0x00, 0xfc, + 0x00, 0x37, 0x40, 0x8f, 0xc0, 0x07, 0xf0, 0x00, + 0xdc, 0x00, 0x3f, 0x40, 0x0f, 0xc0, 0x22, 0xf0, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, + 0xb0, 0x00, 0xff, 0x00, 0x35, 0x80, 0x0e, 0xf0, + 0x03, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0x80, 0x1f, + 0xf0, 0x23, 0xfc, 0x08, 0xdf, 0x00, 0x3f, 0x00, + 0x0b, 0xf0, 0x03, 0xe8, 0x06, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x15, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x30, 0x37, 0xc2, 0x0f, 0xf2, 0x33, 0xfc, 0x80, + 0xee, 0x21, 0x3f, 0xc1, 0x0d, 0xf1, 0xa3, 0x5c, + 0x00, 0xcf, 0xed, 0x09, 0x00, 0x1e, 0x00, 0x00, + 0x2f, 0xca, 0x0f, 0xf0, 0x03, 0x3c, 0x20, 0xef, + 0x00, 0x37, 0x10, 0x0c, 0xf0, 0x03, 0xb0, 0x00, + 0xfc, 0x00, 0x31, 0x01, 0x0f, 0xd0, 0x03, 0xbc, + 0x00, 0xef, 0x20, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xec, 0x00, 0x37, 0x70, 0x22, 0x90, + 0x0b, 0xa1, 0x12, 0xe8, 0x40, 0x8a, 0x10, 0x2f, + 0xd0, 0x08, 0xb4, 0x12, 0x3c, 0x52, 0x8b, 0x10, + 0x26, 0xd0, 0x0b, 0xf4, 0x02, 0x3c, 0x00, 0xdf, + 0x00, 0x20, 0x00, 0x8a, 0xb4, 0x42, 0xa0, 0x10, + 0xbb, 0x00, 0xa2, 0x00, 0x0b, 0x90, 0x02, 0xed, + 0xa0, 0x8f, 0x40, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, + 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x01, 0x04, 0x40, + 0x8b, 0x10, 0x20, 0xc4, 0x00, 0xa1, 0x00, 0x2c, + 0xd0, 0x0b, 0x32, 0x06, 0xcc, 0x00, 0x83, 0x00, + 0x2c, 0xc0, 0x0b, 0x34, 0x02, 0x0c, 0x00, 0x83, + 0x02, 0x2c, 0x08, 0x09, 0x34, 0x20, 0x80, 0x00, + 0xb1, 0x00, 0x20, 0x00, 0x1b, 0x10, 0x02, 0xcc, + 0x40, 0x83, 0x40, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xec, 0x04, 0xbb, 0x00, 0x26, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x02, 0xab, 0x00, 0x2e, + 0xc0, 0x18, 0xb0, 0x02, 0x2c, 0x00, 0x8b, 0x00, + 0x26, 0xc0, 0x0b, 0xb0, 0x0a, 0x2c, 0x00, 0x93, + 0x04, 0x22, 0xc0, 0x09, 0xb0, 0x02, 0x20, 0x20, + 0xbb, 0x80, 0x2a, 0xa0, 0x0b, 0x90, 0x02, 0xec, + 0x10, 0x8b, 0x04, 0x6e, 0xc1, 0x0b, 0xb0, 0x02, + 0xf0, 0x04, 0x60, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x40, 0x05, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x36, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xea, 0x20, 0x3e, 0xc0, 0x0f, 0xb0, + 0x13, 0xec, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0x2c, 0x00, 0xcb, 0x05, 0x36, 0x10, + 0x0d, 0xb0, 0x03, 0xa7, 0x04, 0xf8, 0x01, 0x32, + 0x08, 0x47, 0x98, 0x03, 0xac, 0x00, 0x6b, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xbc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0x77, 0x00, 0x3b, 0x80, 0x0f, 0xe0, 0x03, + 0xd8, 0x00, 0xde, 0x00, 0x3d, 0xc0, 0x0f, 0x70, + 0x11, 0xdc, 0x00, 0xff, 0x00, 0x37, 0xc0, 0x4f, + 0xb0, 0x03, 0xec, 0x00, 0xdf, 0x00, 0x3f, 0x28, + 0x0a, 0x30, 0x03, 0xfd, 0x00, 0xf7, 0x00, 0x27, + 0x80, 0x0f, 0xfa, 0x07, 0xfc, 0x00, 0xff, 0x00, + 0x37, 0xc0, 0x0f, 0xf0, 0x63, 0xf8, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xac, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xac, 0x00, 0xcb, 0x08, 0x3e, 0xc0, 0x0f, + 0x30, 0x03, 0x0c, 0x00, 0xcb, 0x00, 0x3e, 0xc0, + 0x0c, 0xb0, 0x0b, 0x2e, 0x00, 0xf9, 0x00, 0x32, + 0x10, 0x0c, 0xb0, 0x03, 0xec, 0x04, 0xfb, 0x00, + 0xf6, 0xc0, 0x0f, 0xb0, 0x03, 0x50, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0xbf, 0x04, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0x2f, 0xc0, 0x0b, 0xf0, + 0x02, 0xfe, 0x20, 0x8f, 0x20, 0x2f, 0xc0, 0x0b, + 0xed, 0x09, 0x00, 0x20, 0x00, 0xf5, 0x82, 0x3e, + 0x28, 0xaf, 0x00, 0x22, 0xc1, 0x08, 0xfd, 0x02, + 0x2e, 0x50, 0xbb, 0x00, 0x0a, 0x96, 0x0a, 0xb8, + 0x12, 0xfc, 0x18, 0xbf, 0x88, 0x22, 0xc0, 0x0b, + 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x20, 0xc0, 0x0b, 0x30, 0x02, 0x4c, 0x00, 0xb3, + 0x04, 0x0c, 0xc0, 0x0b, 0x30, 0x02, 0x8c, 0x00, + 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x38, 0x22, 0x0e, + 0x00, 0x23, 0x01, 0x26, 0x00, 0x09, 0x30, 0x42, + 0x04, 0x00, 0xb0, 0x00, 0x28, 0x00, 0x0b, 0x11, + 0x02, 0x6d, 0x20, 0xb3, 0x80, 0x00, 0xc0, 0x0b, + 0x30, 0x02, 0x78, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, + 0x21, 0xa8, 0x0b, 0x69, 0x02, 0xda, 0x00, 0xb7, + 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xdf, 0x00, + 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x12, 0x1e, + 0x00, 0xa3, 0x90, 0x21, 0xe0, 0x09, 0x78, 0xa2, + 0x1e, 0x00, 0xbf, 0x98, 0x29, 0x20, 0x0b, 0x78, + 0x02, 0xde, 0x00, 0xb3, 0x80, 0x25, 0xe0, 0x0b, + 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, + 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, + 0x30, 0x40, 0x0f, 0x10, 0x03, 0x44, 0x00, 0xf1, + 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x13, 0x8c, 0xc2, + 0xc3, 0x00, 0x3c, 0xc0, 0x8f, 0x30, 0x03, 0x0c, + 0x00, 0xc3, 0x10, 0x3c, 0x10, 0x8d, 0x31, 0x03, + 0x0c, 0x00, 0xf1, 0x00, 0x38, 0x84, 0x0f, 0x30, + 0x01, 0xcc, 0xa4, 0xf3, 0x00, 0xb0, 0xc0, 0x0f, + 0x30, 0x03, 0x52, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x1d, 0xed, 0x09, 0x00, 0x21, 0x00, + 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x10, 0x3f, 0xc8, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xd0, + 0x0f, 0xf0, 0x83, 0xfd, 0x44, 0xff, 0x10, 0x37, + 0xc2, 0x0f, 0xf4, 0x0b, 0xfc, 0x00, 0xbf, 0x10, + 0x3f, 0xc4, 0x0e, 0xf0, 0x03, 0xfc, 0x00, 0xf7, + 0x06, 0x3f, 0x84, 0x1e, 0xf1, 0x03, 0xfc, 0x04, + 0xff, 0x00, 0x3b, 0xc0, 0x0f, 0xf0, 0x03, 0xd0, + 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x08, 0x76, 0xc0, 0x0c, + 0xb8, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x32, 0xfc, + 0x0c, 0xb0, 0x03, 0xec, 0x80, 0xf3, 0x80, 0xa2, + 0xe0, 0x0c, 0xb2, 0x23, 0x2c, 0x00, 0xfb, 0x90, + 0x3a, 0xe0, 0x0c, 0xb0, 0x03, 0xe4, 0x00, 0xf8, + 0x00, 0x32, 0x80, 0x0b, 0x90, 0x07, 0xec, 0x04, + 0xfb, 0x20, 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xea, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, + 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x20, 0x2d, 0x80, 0x08, + 0x60, 0x02, 0x18, 0x00, 0xb7, 0x04, 0x23, 0xc0, + 0x08, 0x72, 0x02, 0xdd, 0x80, 0xb7, 0x40, 0x21, + 0xc0, 0x08, 0x30, 0x03, 0x5c, 0xc8, 0x37, 0x10, + 0x23, 0xc0, 0x08, 0x74, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x29, 0x80, 0x0b, 0x70, 0x02, 0xdd, 0x08, + 0xb7, 0x08, 0x29, 0xc0, 0x0b, 0x70, 0x02, 0xd2, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x9e, 0x00, 0xb7, 0x80, 0x29, 0xe0, 0x0b, 0x78, + 0x02, 0xde, 0x10, 0x37, 0x90, 0x2c, 0x60, 0x88, + 0x18, 0x02, 0x96, 0x00, 0xb1, 0x80, 0x25, 0xe8, + 0x28, 0x7a, 0x02, 0xde, 0x80, 0xb7, 0xa2, 0x20, + 0xe0, 0x08, 0x7b, 0x02, 0x1e, 0xc0, 0xed, 0x09, + 0x00, 0x22, 0x00, 0xb7, 0xa0, 0x29, 0xf0, 0x08, + 0x7a, 0x10, 0x5e, 0x00, 0xb7, 0x80, 0x21, 0xa1, + 0x0b, 0x78, 0x42, 0x5e, 0x08, 0xb3, 0x90, 0x61, + 0xe0, 0x0b, 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x28, 0x30, 0x0a, 0x8c, + 0x00, 0xb3, 0x00, 0xa4, 0xc0, 0x88, 0x30, 0x22, + 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x08, 0x30, + 0x02, 0x4c, 0x00, 0xb3, 0x01, 0x28, 0xd0, 0x08, + 0x30, 0x02, 0xcc, 0x80, 0xb3, 0x00, 0x28, 0xc0, + 0x0b, 0x38, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x28, + 0xc0, 0x0b, 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x0b, 0xa0, 0x03, 0xe8, 0x00, + 0xfa, 0x00, 0x37, 0x80, 0x0c, 0xe0, 0x03, 0x38, + 0x00, 0xfe, 0x00, 0x36, 0x80, 0x0c, 0xa0, 0x03, + 0xe8, 0x00, 0xfa, 0x00, 0x32, 0x80, 0x0c, 0xa0, + 0x03, 0x28, 0x00, 0xfa, 0x04, 0x3b, 0xa0, 0x2c, + 0xa0, 0x03, 0x78, 0x80, 0xf6, 0x89, 0x33, 0x90, + 0x0f, 0xa0, 0x03, 0xe8, 0x10, 0xfa, 0x00, 0x32, + 0x80, 0x0f, 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xb8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x01, 0x40, + 0x00, 0xf8, 0x00, 0x3a, 0x00, 0x0f, 0x80, 0x13, + 0xe1, 0x01, 0xf8, 0x00, 0x36, 0x00, 0x2f, 0x80, + 0x43, 0xe0, 0x00, 0xf8, 0x02, 0x32, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x20, + 0x09, 0x81, 0x07, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0d, 0x80, 0x03, 0xd2, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, + 0x00, 0xed, 0x09, 0x00, 0x23, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x01, 0x3c, + 0x40, 0x0d, 0x90, 0x03, 0xe4, 0x00, 0xd1, 0x00, + 0x36, 0x40, 0x0f, 0x90, 0x03, 0x25, 0x00, 0xf9, + 0x00, 0x3e, 0x68, 0x0f, 0x1a, 0x03, 0x24, 0x00, + 0xf9, 0x01, 0x3a, 0x42, 0x0f, 0x1c, 0x03, 0x24, + 0x00, 0xc9, 0x80, 0xb2, 0x60, 0x4f, 0x98, 0x03, + 0xe4, 0x08, 0xf1, 0x00, 0x32, 0x40, 0x05, 0x90, + 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x0e, + 0x50, 0x08, 0x94, 0x00, 0xe4, 0x00, 0xa9, 0x40, + 0x22, 0x40, 0x0b, 0x90, 0x02, 0xa5, 0x00, 0xb9, + 0x00, 0x26, 0x48, 0x0b, 0x98, 0x0a, 0x24, 0x01, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x0a, 0x04, + 0x40, 0xa9, 0x80, 0x22, 0x73, 0x0f, 0x98, 0x02, + 0xe7, 0xc8, 0xb9, 0x10, 0x22, 0x40, 0x0b, 0x90, + 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, + 0x42, 0x09, 0x90, 0x82, 0x64, 0x00, 0xa9, 0x08, + 0x26, 0x40, 0x0b, 0x10, 0x52, 0x25, 0x01, 0xb9, + 0x20, 0x2e, 0x40, 0x0a, 0x90, 0x02, 0x24, 0x40, + 0xb9, 0x00, 0x2e, 0x41, 0x0b, 0x90, 0x02, 0x24, + 0x00, 0xa9, 0x20, 0x02, 0x48, 0x0b, 0x96, 0x02, + 0xe4, 0x04, 0xb9, 0x00, 0x26, 0x40, 0x09, 0x90, + 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x40, 0x2c, + 0x41, 0x08, 0x10, 0x02, 0xc4, 0x00, 0xa1, 0x02, + 0x20, 0x4a, 0x0b, 0x10, 0x02, 0x84, 0xa0, 0xb1, + 0x00, 0x24, 0x40, 0x0b, 0x10, 0x02, 0x04, 0xa0, + 0xb1, 0x40, 0x2c, 0x50, 0xed, 0x09, 0x00, 0x24, + 0x00, 0x0b, 0x10, 0x02, 0x04, 0x08, 0xa9, 0x00, + 0x20, 0x40, 0x4b, 0x10, 0x20, 0xc5, 0x00, 0xb1, + 0x00, 0x84, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0c, 0x60, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0d, 0x80, + 0x03, 0xe0, 0x00, 0xe8, 0x00, 0x36, 0x1c, 0x0f, + 0x80, 0x01, 0x20, 0x80, 0xf8, 0x00, 0x1e, 0x00, + 0x0f, 0x80, 0x03, 0x20, 0x80, 0xb0, 0x00, 0x7e, + 0x00, 0x0f, 0x80, 0x03, 0x28, 0x00, 0xe8, 0x00, + 0x32, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x02, 0x36, 0x00, 0x0d, 0x80, 0x03, 0xee, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1d, 0xa4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x40, 0x3f, 0x50, 0x0f, 0xd4, + 0x03, 0xf5, 0x00, 0xfd, 0x40, 0x3e, 0x40, 0x0b, + 0x96, 0x93, 0xe4, 0x00, 0xf9, 0x40, 0x3e, 0x50, + 0x0f, 0x94, 0x03, 0xe4, 0x08, 0xf9, 0x40, 0x3f, + 0x40, 0x05, 0x94, 0x03, 0xf4, 0x00, 0xf5, 0x42, + 0x3f, 0x40, 0x0e, 0xd0, 0x03, 0xe5, 0x00, 0xd9, + 0x40, 0x3a, 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x06, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x48, 0x0f, 0x90, + 0x13, 0xe4, 0x04, 0xf9, 0x00, 0x26, 0x4c, 0x0e, + 0x92, 0x83, 0xf4, 0x02, 0xc5, 0x02, 0x3d, 0x40, + 0x0c, 0xd0, 0x03, 0x34, 0x80, 0xf9, 0x28, 0x34, + 0x44, 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xcd, 0x00, + 0x33, 0xc1, 0x0b, 0xd0, 0x03, 0x74, 0xc0, 0xfd, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc6, 0x05, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, + 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0xed, + 0x09, 0x00, 0x25, 0x00, 0x02, 0xe0, 0x00, 0xb8, + 0x20, 0x2e, 0x04, 0x0b, 0x84, 0x02, 0xe0, 0x00, + 0xbc, 0x10, 0x22, 0x0c, 0x08, 0x80, 0x82, 0xe0, + 0x10, 0x88, 0x40, 0x2e, 0x00, 0x8c, 0x81, 0x02, + 0xa0, 0x40, 0xb8, 0x20, 0x22, 0x08, 0x0b, 0x84, + 0x02, 0xe0, 0x10, 0xd8, 0x11, 0x36, 0x00, 0x0b, + 0x80, 0x42, 0xe0, 0xd0, 0xb8, 0x40, 0x2e, 0x00, + 0x0b, 0x80, 0x02, 0xce, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, 0xb1, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, + 0x28, 0x2d, 0x60, 0x09, 0x59, 0x02, 0xd6, 0x40, + 0xb5, 0x00, 0x24, 0x48, 0x0a, 0x12, 0x02, 0xc4, + 0x40, 0x81, 0x10, 0x2c, 0x44, 0x09, 0x10, 0x12, + 0x04, 0x00, 0xb1, 0x28, 0x2c, 0x48, 0x09, 0x11, + 0x42, 0xc4, 0x00, 0x91, 0x00, 0x28, 0x40, 0x09, + 0x10, 0x02, 0xc4, 0x80, 0xb1, 0x10, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x02, 0x2e, 0x40, 0x8b, 0xd0, 0x02, 0xf4, 0x00, + 0xbd, 0x00, 0x02, 0x40, 0x08, 0x90, 0x02, 0xe4, + 0x00, 0xab, 0x02, 0x2e, 0x40, 0x28, 0x90, 0x02, + 0xa4, 0x00, 0xb9, 0x02, 0x2a, 0x48, 0x0b, 0x90, + 0x42, 0xec, 0x40, 0x9b, 0x04, 0x2e, 0x46, 0x0b, + 0x90, 0x02, 0xe4, 0x04, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xc6, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0b, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x54, 0x0d, 0x94, 0x03, 0xe5, 0x00, + 0xf9, 0x22, 0x36, 0x40, 0x0e, 0x90, 0x03, 0xe4, + 0x08, 0xc9, 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x0b, + 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x78, 0x09, 0x90, + 0x03, 0xe4, 0xed, 0x09, 0x00, 0x26, 0x00, 0x00, + 0xd9, 0xda, 0x3a, 0x40, 0x1d, 0x91, 0x03, 0xe4, + 0x09, 0xf9, 0x00, 0x1e, 0x40, 0x07, 0x90, 0x03, + 0xe8, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x92, 0x03, 0xe4, 0x80, 0xf9, 0x20, 0x36, + 0x40, 0x4f, 0x90, 0x03, 0xe4, 0x02, 0x99, 0x00, + 0x3c, 0x42, 0x0e, 0x90, 0x03, 0x64, 0x00, 0xf9, + 0x00, 0x32, 0x40, 0x5f, 0x90, 0x42, 0xe6, 0x20, + 0xf9, 0x00, 0x36, 0x40, 0x0f, 0x98, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x10, 0xa0, 0x00, 0xe8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x32, 0x01, + 0x0f, 0x80, 0x43, 0x60, 0x00, 0xc8, 0x00, 0x3c, + 0x00, 0x0f, 0x80, 0x03, 0xa2, 0x00, 0xd8, 0x00, + 0x32, 0x00, 0x0c, 0x80, 0x03, 0x20, 0x00, 0xd0, + 0x00, 0x3a, 0x00, 0x4f, 0x81, 0x03, 0xe0, 0x00, + 0xf8, 0x08, 0x3a, 0x34, 0x0f, 0x80, 0x13, 0x20, + 0x42, 0xc8, 0x02, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, + 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x22, 0x80, + 0x0b, 0xa0, 0x03, 0x29, 0x40, 0x82, 0x00, 0x26, + 0x80, 0x0b, 0xa0, 0x03, 0x99, 0x02, 0x0e, 0x40, + 0x2b, 0x90, 0x08, 0x60, 0x02, 0xaa, 0x00, 0xaa, + 0x00, 0x2a, 0x81, 0x0a, 0xec, 0x03, 0x99, 0x80, + 0xb6, 0x48, 0x23, 0x90, 0x0b, 0xe8, 0x02, 0xb8, + 0x00, 0x8a, 0xa0, 0x2e, 0x80, 0x0b, 0xa0, 0x02, + 0x4a, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x4c, 0x00, 0xa3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0xed, 0x09, 0x00, + 0x27, 0x00, 0x00, 0xa0, 0xc0, 0x0a, 0x38, 0x02, + 0x0f, 0x00, 0x83, 0x00, 0x24, 0xc0, 0x0b, 0x30, + 0x02, 0x88, 0x00, 0x83, 0x48, 0x28, 0xe0, 0x08, + 0x39, 0x02, 0x8c, 0x00, 0x93, 0x00, 0x28, 0xc0, + 0x00, 0x30, 0x82, 0x0d, 0x00, 0xb3, 0xc0, 0x68, + 0xc0, 0x0b, 0x30, 0x02, 0x0f, 0x24, 0x03, 0x80, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x04, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x80, 0x21, 0xc0, 0x0b, 0x7c, 0x02, + 0x1f, 0x00, 0x87, 0x00, 0x6d, 0xc0, 0x0b, 0x70, + 0x02, 0x90, 0x00, 0x87, 0x88, 0x29, 0xc2, 0x08, + 0x70, 0x02, 0x8f, 0x00, 0x13, 0x20, 0x2b, 0xe0, + 0x0a, 0x70, 0x12, 0x9c, 0x00, 0x93, 0x01, 0x29, + 0xc0, 0x1b, 0x7c, 0x02, 0x8e, 0x00, 0x87, 0x00, + 0x2d, 0xc0, 0x4b, 0x70, 0x02, 0xe8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, + 0xe7, 0x80, 0x2d, 0xe0, 0x0f, 0x78, 0x03, 0xde, + 0x00, 0xff, 0x80, 0x21, 0xa0, 0x0f, 0x28, 0x0b, + 0x0e, 0x02, 0xc6, 0x80, 0x3d, 0xe0, 0x0f, 0x7f, + 0x03, 0x82, 0x00, 0xd7, 0x82, 0x29, 0xe0, 0x2c, + 0x38, 0x03, 0x9e, 0x00, 0xd7, 0xb4, 0x39, 0xf2, + 0x0f, 0x78, 0x03, 0x9e, 0x00, 0xf7, 0x80, 0x39, + 0xe0, 0x0b, 0x78, 0x03, 0x1e, 0x10, 0xc7, 0x80, + 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xea, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x30, 0x3e, 0x80, 0x03, 0xa0, 0x03, + 0xac, 0x00, 0xfa, 0x00, 0x36, 0xc4, 0x0f, 0xb0, + 0x03, 0xe0, 0x04, 0x5b, 0x02, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xeb, 0x10, 0x36, 0xd0, + 0x0f, 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x04, 0x36, + 0xed, 0x09, 0x00, 0x28, 0x00, 0x80, 0x5f, 0x10, + 0x03, 0xe8, 0x00, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0x42, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, + 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0xc0, + 0x73, 0xe4, 0x0e, 0xd2, 0x43, 0xb2, 0x00, 0xf7, + 0x80, 0x13, 0xe0, 0x0c, 0xf8, 0x03, 0xba, 0x00, + 0x7e, 0xa0, 0x3f, 0xe0, 0x0c, 0xf8, 0x03, 0x3c, + 0x80, 0xdf, 0x80, 0x39, 0xe0, 0x2c, 0x78, 0x03, + 0x7e, 0x40, 0xe7, 0x80, 0x3b, 0xa0, 0x8f, 0xf8, + 0x03, 0xbe, 0x00, 0xc7, 0x80, 0x33, 0xe0, 0x0f, + 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0xa1, 0xc0, 0x0d, 0x52, 0x02, 0x10, 0x00, 0xb7, + 0x00, 0x35, 0xc0, 0x08, 0x70, 0x03, 0x50, 0x40, + 0xb4, 0x00, 0x2d, 0xc8, 0x0a, 0x52, 0x0a, 0x14, + 0x40, 0xdf, 0x12, 0x21, 0xc0, 0x0d, 0x60, 0x03, + 0x58, 0x00, 0xd7, 0x00, 0x3d, 0x80, 0x4b, 0x72, + 0x03, 0x9c, 0x40, 0xa7, 0x00, 0x29, 0xc0, 0x0f, + 0x70, 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb3, 0x00, + 0x20, 0x80, 0x4a, 0x01, 0x22, 0x90, 0x00, 0xbe, + 0x00, 0x20, 0xc0, 0x08, 0x70, 0x02, 0x90, 0x00, + 0xb6, 0x22, 0x2d, 0x00, 0x00, 0x70, 0x40, 0x0c, + 0x02, 0x87, 0x00, 0x2b, 0xc0, 0x0a, 0x50, 0x02, + 0x34, 0x08, 0x9d, 0x10, 0x21, 0x00, 0x0b, 0x70, + 0x22, 0x5c, 0x00, 0x87, 0x00, 0x29, 0xc0, 0x0b, + 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x20, 0x92, 0x08, 0xed, 0x09, 0x00, 0x29, 0x00, + 0x02, 0x02, 0x00, 0x80, 0xb2, 0x00, 0x24, 0xc0, + 0x28, 0xb0, 0x02, 0x00, 0x00, 0xb0, 0x00, 0x2c, + 0x00, 0x08, 0x10, 0x02, 0x04, 0x00, 0x83, 0x00, + 0x20, 0xe2, 0x0a, 0x00, 0x02, 0x42, 0x08, 0x91, + 0xa0, 0x24, 0x39, 0x0b, 0x18, 0x02, 0x84, 0x00, + 0xa1, 0x00, 0x28, 0xc0, 0x0a, 0x30, 0x02, 0x88, + 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, + 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xff, 0x00, 0x32, 0x60, 0x0a, + 0xb8, 0x03, 0xae, 0x00, 0xf9, 0x80, 0x33, 0xc0, + 0x0c, 0xf0, 0x02, 0xa4, 0x00, 0xfb, 0x00, 0x3c, + 0x00, 0x0c, 0xb0, 0x03, 0x0c, 0x00, 0x8f, 0x00, + 0x3b, 0xc2, 0x0a, 0xb0, 0x03, 0x2e, 0x00, 0x9b, + 0x48, 0x20, 0xa8, 0x9f, 0xb8, 0x25, 0xe0, 0x00, + 0xcb, 0x00, 0x3a, 0xc0, 0x0b, 0xb0, 0x02, 0xea, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3c, 0x60, 0x0f, + 0xb8, 0x03, 0xee, 0x00, 0xf9, 0x80, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xe0, 0x00, 0xfa, 0x40, 0x3e, + 0x00, 0x2f, 0xa0, 0x07, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0d, 0x90, 0x03, 0xe4, 0x40, 0xf9, + 0x00, 0x2e, 0x80, 0x4f, 0xb5, 0x03, 0xe0, 0x00, + 0xf3, 0x00, 0x1e, 0xc0, 0x0f, 0xb0, 0x03, 0x60, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x04, 0x0c, + 0x60, 0x03, 0x3c, 0x00, 0xfc, 0x80, 0x3f, 0xc0, + 0x0f, 0xb0, 0x03, 0x36, 0x00, 0xf5, 0xc0, 0x36, + 0x05, 0x4e, 0x94, 0x23, 0x36, 0x08, 0xd7, 0x00, + 0x37, 0xc0, 0x0c, 0xf0, 0x03, 0x78, 0x40, 0xef, + 0x80, 0x3f, 0xa0, 0x0c, 0xec, 0x03, 0xed, 0x09, + 0x00, 0x2a, 0x00, 0x24, 0x00, 0xdf, 0x00, 0x33, + 0xc0, 0x05, 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2e, 0x00, 0x08, 0xa0, 0x02, 0xac, + 0x00, 0xb8, 0x80, 0x26, 0xc0, 0x09, 0xb0, 0x02, + 0xa2, 0x60, 0xb8, 0x81, 0x22, 0x32, 0x2a, 0x04, + 0xd2, 0x24, 0x00, 0xab, 0x00, 0x2a, 0xc0, 0x0a, + 0x10, 0x02, 0x23, 0x00, 0xb9, 0x40, 0x2e, 0xa6, + 0x08, 0x04, 0x82, 0x23, 0x04, 0x99, 0x90, 0x22, + 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2e, 0x40, 0x08, 0x90, 0x02, 0x60, + 0x00, 0xb9, 0x20, 0x2a, 0xc0, 0x0b, 0xb0, 0x02, + 0x20, 0x00, 0xba, 0x00, 0x26, 0x00, 0x48, 0xb0, + 0x02, 0x2c, 0x80, 0x9b, 0x00, 0x24, 0xc0, 0x08, + 0xb1, 0x02, 0x2c, 0x00, 0xba, 0x10, 0x2e, 0x80, + 0x08, 0x90, 0x02, 0x22, 0x24, 0xb9, 0x00, 0x22, + 0xc0, 0x09, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0x40, 0x28, 0x10, 0x02, 0xc0, + 0x00, 0xb1, 0x00, 0x24, 0xc0, 0x09, 0x30, 0x02, + 0x80, 0x00, 0xb0, 0x00, 0x20, 0x00, 0x0a, 0x00, + 0x0a, 0x84, 0x00, 0x83, 0x00, 0x20, 0xc0, 0x08, + 0x00, 0x0a, 0x40, 0x00, 0xb0, 0x04, 0x2e, 0x00, + 0x18, 0x90, 0x02, 0x80, 0x00, 0x91, 0x00, 0xa0, + 0xc0, 0x0b, 0x30, 0x00, 0xc2, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xff, 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0x60, + 0x00, 0xed, 0x09, 0x00, 0x2b, 0x00, 0xf8, 0x00, + 0x3a, 0xc0, 0x0f, 0xf0, 0x03, 0x24, 0x00, 0xf8, + 0x00, 0x36, 0x00, 0x0c, 0x90, 0x03, 0x24, 0x08, + 0xdf, 0x00, 0x37, 0xc0, 0x0c, 0x90, 0x03, 0x60, + 0x00, 0xf8, 0x00, 0x3e, 0x01, 0x0c, 0x80, 0x0b, + 0x24, 0x00, 0xd9, 0x00, 0x32, 0xc0, 0x0d, 0xb0, + 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x0d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0x00, 0x0f, 0xc0, 0x03, 0xb0, 0x00, 0xfc, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x02, 0xf0, 0x00, 0xfc, + 0x02, 0x3f, 0x00, 0x0d, 0xc0, 0x03, 0x74, 0x00, + 0xef, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x13, 0x90, + 0x00, 0x7c, 0x02, 0x0f, 0x00, 0x07, 0x40, 0x03, + 0x74, 0x00, 0xdd, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x05, 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0x40, + 0x0c, 0xd0, 0x03, 0x7c, 0x00, 0xcd, 0x00, 0x3f, + 0x22, 0x0e, 0xf4, 0x03, 0x3d, 0x80, 0xcf, 0x00, + 0x37, 0x00, 0x0c, 0xf0, 0x03, 0xf5, 0x10, 0xed, + 0x00, 0x3b, 0xda, 0x0c, 0xf0, 0x03, 0xfc, 0x80, + 0xcc, 0x00, 0xb3, 0x40, 0x0d, 0x70, 0x03, 0xfc, + 0x00, 0xfc, 0x40, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xef, 0x00, 0x3f, 0xd0, 0x0f, 0xf0, + 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0x56, + 0x28, 0xb2, 0x82, 0x2e, 0xa0, 0x8b, 0x00, 0x2e, + 0x00, 0x48, 0xb8, 0x02, 0x29, 0x80, 0x8b, 0x40, + 0x2e, 0xc0, 0x0d, 0xf4, 0x02, 0xec, 0x00, 0x8b, + 0x00, 0x21, 0xf0, 0x08, 0xf4, 0x02, 0xfd, 0x00, + 0xa9, 0x00, 0x22, 0x00, 0x0a, 0x90, 0x02, 0xed, + 0x40, 0xba, 0x20, 0x2e, 0xc0, 0x0b, 0xb0, 0x12, + 0xec, 0x00, 0xbb, 0x00, 0xed, 0x09, 0x00, 0x2c, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0x89, 0x28, 0x90, 0x02, + 0x4c, 0x80, 0x83, 0x00, 0x2c, 0x20, 0x08, 0x30, + 0x02, 0x8f, 0x00, 0x82, 0x40, 0x2e, 0xc0, 0x08, + 0x34, 0x02, 0xec, 0x80, 0x83, 0x00, 0x28, 0xc8, + 0x08, 0x34, 0x02, 0x4c, 0x40, 0xa0, 0x00, 0xa0, + 0x00, 0x4a, 0x30, 0x02, 0xcc, 0x10, 0xb2, 0x20, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x0c, 0x00, 0xb3, + 0x00, 0x2c, 0xc8, 0x0b, 0x30, 0x02, 0xe2, 0x01, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, + 0x00, 0xbb, 0x00, 0x2e, 0x82, 0x08, 0xb2, 0x02, + 0x2c, 0x02, 0x89, 0x00, 0x2e, 0x00, 0x08, 0x30, + 0x02, 0xac, 0x08, 0x8b, 0x88, 0x2e, 0xc8, 0x09, + 0xb0, 0x02, 0xee, 0x06, 0x8b, 0x00, 0x22, 0xc0, + 0x08, 0xb0, 0x02, 0xec, 0x04, 0xa8, 0x80, 0xa2, + 0x30, 0x0a, 0xb0, 0x02, 0xec, 0x00, 0xba, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xf0, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xec, + 0x00, 0xdb, 0x00, 0x3e, 0x94, 0x0c, 0x92, 0x0b, + 0x4c, 0x00, 0xcb, 0x80, 0x3e, 0x80, 0x0e, 0xb0, + 0x07, 0xa6, 0x00, 0xcb, 0xc4, 0x3e, 0xd0, 0x4c, + 0xb0, 0x03, 0xcc, 0x00, 0xeb, 0x90, 0x3a, 0xc0, + 0x0c, 0xb0, 0x01, 0x6c, 0x00, 0x69, 0xa0, 0x22, + 0x10, 0x0d, 0xb9, 0x83, 0xec, 0x04, 0xfb, 0x02, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xeb, + 0x00, 0x3e, 0xc0, 0x07, 0xb0, 0x03, 0xd0, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xbc, + 0x00, 0xff, 0x00, 0x3e, 0xa0, 0x0f, 0xf8, 0x83, + 0xfc, 0x20, 0xff, 0x90, 0x3d, 0x80, 0x0f, 0xf0, + 0x03, 0x5e, 0x40, 0xff, 0x00, 0x3f, 0x40, 0xed, + 0x09, 0x00, 0x2d, 0x00, 0x0b, 0xf0, 0x23, 0xfc, + 0x00, 0xfd, 0x81, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xf9, 0x00, 0x35, 0x40, 0xcf, 0xe0, + 0x03, 0xfc, 0x00, 0xbf, 0x00, 0x3f, 0xc1, 0x8f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x10, 0xac, 0x00, 0xfb, 0x00, + 0x7e, 0xc4, 0x0c, 0x90, 0x0b, 0x2c, 0x00, 0xfb, + 0x00, 0x3f, 0x00, 0x0c, 0xb0, 0x03, 0x2c, 0x00, + 0xeb, 0x44, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xe4, + 0x02, 0xeb, 0x00, 0xb2, 0xe0, 0x0c, 0xb0, 0x0b, + 0xae, 0x00, 0xf9, 0x01, 0x36, 0x18, 0x2e, 0xb4, + 0x83, 0x6c, 0x00, 0xfa, 0x00, 0x32, 0xc0, 0x0f, + 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc6, + 0x0c, 0xb0, 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, 0xbb, 0x00, + 0x2e, 0xd0, 0x08, 0x34, 0x02, 0x2d, 0x01, 0xbb, + 0x50, 0x2e, 0x21, 0x08, 0xb8, 0x03, 0x6c, 0x10, + 0x8b, 0x20, 0x24, 0xc3, 0x0e, 0xfa, 0x02, 0xec, + 0x00, 0x8b, 0x50, 0x3f, 0xc0, 0x08, 0xf8, 0x02, + 0x1c, 0x00, 0xb9, 0x80, 0x22, 0x70, 0x08, 0xbc, + 0x02, 0x3c, 0x00, 0xba, 0x20, 0x37, 0xc0, 0x0b, + 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xd0, + 0x28, 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x05, 0x4c, 0x00, 0xb3, 0x00, + 0x2e, 0x72, 0x28, 0x30, 0x02, 0x8d, 0x00, 0xb3, + 0xc0, 0x2c, 0x44, 0x08, 0x31, 0x00, 0x0c, 0x20, + 0x91, 0x00, 0x2c, 0xe0, 0x0b, 0x30, 0x16, 0xcc, + 0x00, 0x8b, 0x40, 0x22, 0xc1, 0x08, 0x30, 0x42, + 0x0c, 0x00, 0x3a, 0x00, 0xa0, 0x70, 0x89, 0x3c, + 0x02, 0x4c, 0x00, 0xb0, 0x48, 0x28, 0xc8, 0x0b, + 0x30, 0x02, 0x8c, 0x00, 0xa3, 0x00, 0x28, 0xe0, + 0x0a, 0x30, 0xed, 0x09, 0x00, 0x2e, 0x00, 0x02, + 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0x60, 0x28, + 0x78, 0x02, 0x9e, 0x01, 0xb7, 0x80, 0x2c, 0x60, + 0x08, 0x7c, 0x42, 0x0e, 0xe0, 0x87, 0x84, 0x25, + 0xe0, 0x1a, 0x78, 0x42, 0xd6, 0x00, 0x87, 0x88, + 0xad, 0xe0, 0x08, 0x38, 0x82, 0x1e, 0x00, 0xb5, + 0xc0, 0x20, 0x20, 0x28, 0x78, 0x82, 0x1e, 0x00, + 0x96, 0x84, 0x2d, 0xe6, 0x0b, 0x78, 0x02, 0xde, + 0x00, 0x37, 0x80, 0x2d, 0xe0, 0x1a, 0x78, 0x06, + 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x2c, 0x40, 0x0c, + 0xb0, 0x03, 0x8c, 0x00, 0xb3, 0x08, 0x3c, 0x40, + 0x0c, 0xb0, 0x02, 0x0c, 0xc0, 0xe1, 0x00, 0x3c, + 0x40, 0x0f, 0x30, 0x03, 0xec, 0x00, 0xc1, 0x00, + 0x30, 0xc0, 0x0c, 0x30, 0x02, 0x0c, 0x00, 0xf0, + 0x08, 0x30, 0x82, 0x0f, 0x30, 0x03, 0x4c, 0x00, + 0xfa, 0x10, 0x38, 0xc0, 0x0f, 0x30, 0x03, 0x8c, + 0x00, 0xf3, 0x00, 0x3e, 0xc4, 0x0e, 0x30, 0x03, + 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x6f, + 0xe1, 0x03, 0x7c, 0x00, 0xff, 0x10, 0x3f, 0x40, + 0x0f, 0xf0, 0x03, 0xfc, 0xc0, 0xff, 0x10, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xd7, 0x00, + 0x27, 0xd0, 0x0f, 0xf0, 0x83, 0xfd, 0x20, 0xfd, + 0x00, 0xbb, 0x00, 0x0f, 0xf1, 0x03, 0xfc, 0x20, + 0xfe, 0x04, 0x37, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, + 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x1c, + 0x38, 0x23, 0x2c, 0x00, 0xf9, 0x00, 0x3f, 0x80, + 0x0f, 0xb0, 0x03, 0x6c, 0x00, 0xc9, 0x00, 0x3c, + 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0xed, 0x09, 0x00, + 0x2f, 0x00, 0x00, 0xfb, 0x00, 0x3e, 0xc8, 0x0c, + 0xb4, 0x03, 0xac, 0x80, 0xfb, 0x00, 0x72, 0xc0, + 0x4c, 0x30, 0x03, 0xbc, 0x00, 0xfb, 0x00, 0x3e, + 0xc4, 0x2c, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xea, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x2d, 0x70, 0x02, 0x1c, + 0x00, 0xb7, 0x00, 0x2d, 0x80, 0x8b, 0x70, 0x02, + 0xfc, 0x14, 0x87, 0x01, 0x2d, 0xc1, 0x0a, 0x75, + 0x12, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x08, + 0x73, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x20, 0xc0, + 0x0a, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x04, + 0x3d, 0xc0, 0x0b, 0x70, 0x02, 0xd2, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, + 0xa7, 0x80, 0x2d, 0x60, 0x18, 0xf8, 0x02, 0x1e, + 0x00, 0xb7, 0x80, 0x2d, 0x20, 0x0b, 0x78, 0x02, + 0x5e, 0x00, 0x85, 0x80, 0x2f, 0xe0, 0x0a, 0x7a, + 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe4, 0x08, + 0x78, 0x02, 0xde, 0x80, 0x93, 0x80, 0x29, 0xe1, + 0x28, 0x78, 0x02, 0x9e, 0x80, 0xb6, 0xc0, 0x2d, + 0xe8, 0x09, 0x78, 0x02, 0x5e, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xf0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0xd0, 0x09, 0x30, 0x02, 0x2c, + 0x00, 0xb1, 0x00, 0x2c, 0x10, 0x0b, 0x30, 0x02, + 0xcd, 0x04, 0x83, 0x00, 0x2c, 0x60, 0x28, 0x30, + 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2e, 0xc0, 0x08, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x80, 0x20, 0xe2, + 0x0a, 0x3c, 0x82, 0x0c, 0x08, 0xb2, 0xc0, 0x2e, + 0xc0, 0x09, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc1, 0x0b, 0x30, 0x02, 0xd2, 0x04, 0x30, + 0xed, 0x09, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xea, 0x00, 0x2f, + 0x98, 0x0c, 0xe4, 0x0b, 0x28, 0x00, 0xfa, 0xa0, + 0x3f, 0x94, 0x0f, 0xa0, 0x03, 0x79, 0x40, 0xce, + 0x40, 0x3d, 0xb0, 0x0c, 0xa0, 0x03, 0xe8, 0x00, + 0xfa, 0xa0, 0x3e, 0x80, 0x0c, 0xa0, 0x03, 0xe8, + 0x00, 0xfe, 0xa0, 0x33, 0x80, 0x0c, 0xee, 0x0b, + 0xa8, 0x00, 0xfe, 0x00, 0x3e, 0x80, 0x0d, 0xa0, + 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x2e, 0x80, 0x0f, + 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x02, 0x0f, 0x88, 0x03, 0xe0, 0x10, 0xf8, 0x01, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x46, 0xf8, + 0x20, 0x3e, 0x24, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x2f, 0x80, 0x03, 0xe0, + 0x00, 0xd8, 0xc0, 0xbe, 0x04, 0x0f, 0x04, 0x03, + 0xe0, 0x00, 0xf8, 0x08, 0x3e, 0x00, 0x0e, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3a, 0x10, 0x0f, + 0x80, 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3c, + 0x40, 0x0c, 0x92, 0x03, 0xe4, 0x00, 0xc9, 0xa0, + 0x3c, 0x60, 0x0c, 0x90, 0x03, 0xc5, 0x08, 0xc9, + 0xa0, 0x3e, 0x60, 0x0e, 0x10, 0x03, 0x24, 0x00, + 0xf9, 0xa0, 0x3e, 0x40, 0x0c, 0x9a, 0x03, 0xc4, + 0x00, 0xc1, 0x40, 0x32, 0x48, 0x0c, 0x9c, 0x02, + 0x64, 0x00, 0xb9, 0x00, 0x3e, 0x50, 0x28, 0x90, + 0x03, 0xe4, 0x00, 0xd9, 0x00, 0x3e, 0x60, 0x0f, + 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, + 0x68, 0x28, 0x92, 0x02, 0xe5, 0x00, 0xd9, 0x40, + 0x2e, 0x44, 0x28, 0x90, 0x12, 0xe5, 0x80, 0x89, + 0x80, 0x2e, 0x60, 0x28, 0x90, 0x02, 0x24, 0x00, + 0xb9, 0x40, 0x26, 0xed, 0x09, 0x00, 0x31, 0x00, + 0x40, 0x08, 0x98, 0x02, 0xe4, 0x00, 0x89, 0xc0, + 0x22, 0x40, 0x08, 0x98, 0x02, 0xa4, 0x00, 0xb9, + 0x80, 0x2e, 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2e, 0x7c, 0x09, 0x90, 0x02, 0xe0, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, + 0x24, 0x00, 0xb9, 0x00, 0x6e, 0x48, 0x08, 0x90, + 0x02, 0xe5, 0x00, 0xa9, 0x00, 0x2e, 0x40, 0x08, + 0x90, 0x02, 0xe4, 0x00, 0x89, 0x01, 0x2e, 0xc4, + 0x08, 0x92, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x26, + 0x40, 0x08, 0x90, 0x02, 0x66, 0x02, 0x89, 0x08, + 0x00, 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x88, 0x2e, 0x40, 0x0a, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x50, 0x28, 0x14, + 0x02, 0xc4, 0x00, 0x91, 0x80, 0x2c, 0x48, 0x08, + 0x10, 0x02, 0x45, 0x00, 0x81, 0x00, 0x2e, 0x40, + 0x08, 0x10, 0x02, 0x05, 0x00, 0xb1, 0x80, 0x24, + 0x6a, 0x08, 0x12, 0x82, 0xc4, 0xa0, 0x81, 0x40, + 0x20, 0x70, 0x08, 0x10, 0x02, 0x84, 0xa0, 0xb1, + 0x44, 0x2c, 0x50, 0x08, 0x10, 0x00, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x50, 0x09, 0x10, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, + 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, 0x80, + 0x03, 0xe1, 0x40, 0xe8, 0x00, 0x3e, 0x00, 0x0c, + 0x85, 0x03, 0xe0, 0x00, 0xc8, 0x00, 0x3e, 0x00, + 0x0c, 0x80, 0x0b, 0x20, 0x00, 0xf8, 0x50, 0x34, + 0x1c, 0x0c, 0x82, 0x03, 0x60, 0x80, 0xc8, 0x00, + 0xb2, 0x00, 0x4c, 0xa0, 0x03, 0xe0, 0x80, 0xf8, + 0x00, 0x3c, 0x80, 0x0e, 0x80, 0x03, 0xe0, 0x00, + 0xd8, 0x01, 0x7e, 0x01, 0x8f, 0x80, 0x03, 0xee, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x32, 0x00, 0x98, 0x1d, 0xe4, 0x00, 0xf9, + 0x00, 0x3d, 0x50, 0x0f, 0xd0, 0x03, 0xe4, 0x04, + 0xfd, 0x00, 0x3f, 0x44, 0x0f, 0x90, 0x03, 0xf5, + 0x06, 0xfd, 0x40, 0x3f, 0x40, 0x0d, 0x94, 0x03, + 0xf4, 0x00, 0xfd, 0x00, 0x3e, 0x40, 0x2f, 0x90, + 0x03, 0xe4, 0x00, 0xfd, 0x40, 0x3f, 0x50, 0x6f, + 0xd4, 0x03, 0xe4, 0x00, 0xfd, 0x00, 0x3e, 0x50, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x76, + 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, 0xf9, + 0x00, 0x3f, 0x42, 0x2c, 0xd0, 0x03, 0x34, 0x40, + 0xcd, 0x00, 0x3b, 0xc0, 0x0f, 0xd1, 0x03, 0xf5, + 0x80, 0xdd, 0x00, 0x13, 0x40, 0x0f, 0xd2, 0x03, + 0xed, 0x04, 0xfd, 0x10, 0x3f, 0x48, 0x0f, 0xd2, + 0x83, 0x34, 0x90, 0xbd, 0x20, 0x0b, 0x48, 0x0c, + 0xd2, 0x03, 0xa4, 0x90, 0xfd, 0x40, 0x37, 0x58, + 0x0c, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f, + 0x40, 0x0f, 0x90, 0x03, 0xc6, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x00, 0xb8, + 0x00, 0x2e, 0x18, 0x28, 0x82, 0x82, 0x20, 0x82, + 0x88, 0x00, 0x22, 0x00, 0x0b, 0x80, 0x02, 0xe0, + 0x00, 0x88, 0x51, 0x22, 0x00, 0x0e, 0x84, 0x03, + 0xe0, 0x80, 0xb8, 0x00, 0x26, 0x0a, 0x8b, 0x80, + 0x02, 0x20, 0x40, 0xb8, 0x68, 0x28, 0x9a, 0x0a, + 0x84, 0x02, 0x20, 0x00, 0xba, 0x20, 0x2c, 0x10, + 0x08, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, + 0x0a, 0x0b, 0x80, 0x02, 0xce, 0x06, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x42, 0x38, 0x10, 0x22, 0x04, 0x80, + 0x81, 0x00, 0x28, 0x44, 0x0b, 0x10, 0x02, 0xc5, + 0x00, 0x83, 0x00, 0x68, 0x60, 0x0b, 0x11, 0x02, + 0xc4, 0x80, 0xb1, 0x00, 0x2c, 0x4c, 0x0b, 0x10, + 0x0a, 0xed, 0x09, 0x00, 0x33, 0x00, 0x04, 0x0c, + 0x91, 0x12, 0x24, 0x44, 0x28, 0x11, 0x02, 0x84, + 0x40, 0xb1, 0x00, 0x2c, 0x4c, 0x09, 0x10, 0x02, + 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, + 0x02, 0xc2, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0xa4, 0x00, 0xb9, 0x01, 0x2e, 0x50, + 0x28, 0x10, 0x02, 0x24, 0x00, 0x89, 0x20, 0x22, + 0x44, 0x0b, 0x90, 0x02, 0x65, 0x14, 0x99, 0x08, + 0xaa, 0x40, 0x0a, 0x90, 0x02, 0xe4, 0x80, 0xb9, + 0x80, 0x26, 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, + 0xb9, 0x18, 0x22, 0x60, 0x2a, 0x94, 0x02, 0xa4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x89, 0x90, 0x02, + 0xe4, 0x00, 0x39, 0x04, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xc6, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x60, + 0x0c, 0x92, 0x0b, 0x24, 0x00, 0xc1, 0x00, 0x2a, + 0x60, 0x0f, 0x90, 0x03, 0xe5, 0x06, 0xc9, 0x00, + 0x3a, 0x50, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x07, 0x24, 0x00, + 0xd9, 0x01, 0x3a, 0x70, 0x0c, 0x90, 0x03, 0xa4, + 0x00, 0xf9, 0x40, 0x36, 0x40, 0x2d, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe8, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x50, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x04, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x40, 0xe9, 0x01, + 0x36, 0x70, 0x0f, 0x90, 0x23, 0xa6, 0x00, 0xf9, + 0x00, 0x36, 0x40, 0x0f, 0x10, 0x07, 0xe4, 0x00, + 0xf9, 0x80, 0xac, 0x40, 0x8f, 0x92, 0x03, 0x64, + 0x00, 0xf9, 0xc0, 0x2c, 0x42, 0x0e, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0xa0, 0x00, 0xed, 0x09, 0x00, 0x34, + 0x00, 0xf8, 0x00, 0x3c, 0x02, 0x0c, 0x8c, 0x03, + 0x20, 0x00, 0xf8, 0x80, 0x3e, 0x00, 0x0f, 0x81, + 0x03, 0xc0, 0x34, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0x60, 0x00, 0xf8, 0x09, 0x3e, 0x00, + 0x2c, 0x80, 0x03, 0xe0, 0x10, 0x78, 0x08, 0x3e, + 0x11, 0x0c, 0x88, 0x03, 0x60, 0x00, 0xc8, 0x30, + 0x3e, 0x00, 0x2c, 0x80, 0x23, 0xe0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xca, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x15, 0x28, + 0x00, 0xba, 0x00, 0x2f, 0xb0, 0x08, 0xe8, 0x02, + 0x3b, 0x60, 0xbe, 0x40, 0x2e, 0x88, 0x0b, 0xec, + 0x02, 0xfa, 0x20, 0xb2, 0x00, 0x2a, 0x80, 0x0b, + 0xa0, 0x82, 0x28, 0x00, 0xbe, 0x60, 0x2f, 0x80, + 0x08, 0xa0, 0x02, 0xea, 0x00, 0xbe, 0x61, 0x2f, + 0x94, 0x0a, 0x64, 0x00, 0x28, 0x00, 0x8e, 0xc0, + 0x2f, 0x91, 0x08, 0xa0, 0x02, 0xe8, 0x00, 0xba, + 0x00, 0x2f, 0x80, 0x0b, 0xa0, 0x02, 0xca, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, + 0x00, 0xb3, 0x00, 0x2c, 0xe0, 0x09, 0x38, 0x02, + 0x24, 0x00, 0xb1, 0x10, 0x28, 0x40, 0x0b, 0x00, + 0x82, 0xcc, 0x00, 0xb1, 0x00, 0x2c, 0x60, 0x0b, + 0x10, 0x02, 0x0c, 0x01, 0xb3, 0x40, 0x2c, 0x00, + 0x08, 0x18, 0x02, 0xc6, 0x00, 0xbb, 0x00, 0x28, + 0xc0, 0x09, 0x10, 0x02, 0xcc, 0x00, 0x83, 0x80, + 0x2c, 0xc4, 0x1a, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, + 0x00, 0xb7, 0x00, 0x2d, 0xc2, 0x29, 0x70, 0x82, + 0x14, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x09, 0x40, + 0x02, 0xdc, 0x10, 0xbf, 0x00, 0x2d, 0xc2, 0x0b, + 0x78, 0x02, 0x1c, 0x80, 0xb7, 0x00, 0x2c, 0x20, + 0x08, 0x70, 0x82, 0xdd, 0x00, 0xb5, 0x02, 0xed, + 0x09, 0x00, 0x35, 0x00, 0x2d, 0x40, 0x09, 0x30, + 0x02, 0x8c, 0x00, 0x87, 0x00, 0x2d, 0xc0, 0x00, + 0x70, 0x02, 0xdc, 0x00, 0x37, 0x00, 0x2d, 0x00, + 0x0b, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xf7, 0x80, + 0x3f, 0xa0, 0x0d, 0xf8, 0x0b, 0x16, 0x00, 0xf7, + 0x80, 0x3d, 0xe0, 0x0f, 0x48, 0x03, 0xde, 0x00, + 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x09, 0x5e, + 0x00, 0xf7, 0x80, 0x3d, 0x20, 0x0c, 0x78, 0x03, + 0xde, 0x00, 0xf7, 0x80, 0x3d, 0x20, 0x2d, 0x68, + 0x03, 0xdc, 0x00, 0xc7, 0x81, 0x3d, 0x80, 0x0e, + 0x78, 0x03, 0xde, 0x00, 0x77, 0x80, 0x3d, 0xe0, + 0x0f, 0x78, 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x0d, 0xac, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0e, 0xb0, 0x13, 0xf4, 0x00, 0xbb, + 0x00, 0x3e, 0xc0, 0x0f, 0xc0, 0x13, 0xec, 0x00, + 0xf3, 0x04, 0x3a, 0xc0, 0x0f, 0x10, 0x03, 0xed, + 0xe0, 0xfb, 0x00, 0x3f, 0x00, 0x0f, 0x90, 0x01, + 0xec, 0x00, 0xf9, 0x00, 0x3e, 0x00, 0x0e, 0xa0, + 0x03, 0x6c, 0x08, 0xf9, 0x01, 0x3e, 0xc0, 0x2f, + 0xb0, 0x03, 0xec, 0x00, 0xdb, 0x00, 0x3e, 0x40, + 0x0b, 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, 0x80, + 0x3f, 0xe0, 0x0d, 0xf8, 0x03, 0x3a, 0x40, 0xff, + 0x90, 0x3d, 0xe0, 0x0c, 0xf8, 0x03, 0x3e, 0x48, + 0xcf, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0x7e, + 0x04, 0xf7, 0x81, 0x3b, 0x20, 0x0c, 0xf8, 0x03, + 0xfe, 0x00, 0xff, 0x80, 0x33, 0xe0, 0x8c, 0xd8, + 0x03, 0xfe, 0x00, 0xf5, 0x90, 0x33, 0xe0, 0x0f, + 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x85, 0x3f, 0xe0, + 0x0f, 0xf8, 0x03, 0xc0, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0xed, 0x09, 0x00, 0x36, 0x00, 0x08, + 0xf0, 0x42, 0x1c, 0x00, 0xb5, 0x44, 0x2d, 0x40, + 0x08, 0xc0, 0x02, 0x3d, 0x48, 0x87, 0x10, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x4c, + 0x21, 0x00, 0x08, 0x71, 0x13, 0xd4, 0x00, 0xb4, + 0x10, 0xa1, 0x40, 0x0a, 0x64, 0x02, 0xdc, 0x00, + 0xb6, 0x00, 0x21, 0x48, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0x00, 0x0b, 0x70, 0x02, + 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0x80, 0x09, + 0x50, 0x82, 0x1c, 0x04, 0xb7, 0x00, 0x2d, 0xc0, + 0x08, 0x70, 0x02, 0x1c, 0x00, 0x85, 0x08, 0x2d, + 0x42, 0x0b, 0x30, 0x02, 0x1c, 0x00, 0xb7, 0x10, + 0x28, 0x00, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x21, 0x00, 0x2a, 0x60, 0x02, 0xdc, 0x00, + 0xbd, 0x00, 0x61, 0x40, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2e, 0xc0, 0x08, + 0x0c, 0x02, 0x08, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x08, 0x00, 0x02, 0x0a, 0x10, 0x83, 0xe0, 0x2c, + 0xd0, 0x0b, 0x30, 0x22, 0x0e, 0x00, 0xb3, 0x00, + 0x20, 0x00, 0x08, 0x30, 0x02, 0x8c, 0x00, 0xbb, + 0x89, 0x20, 0x00, 0x0a, 0x2c, 0x02, 0xcc, 0x08, + 0xb1, 0x00, 0x62, 0x40, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0x40, 0x0b, 0x30, 0x02, + 0xc8, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x15, 0xac, 0x00, 0xfb, 0x00, 0x2e, 0xa0, 0x2d, + 0xb8, 0x0a, 0x24, 0x00, 0xfb, 0xa0, 0x3e, 0xc0, + 0x2c, 0x80, 0x43, 0x2c, 0x22, 0xcb, 0xc4, 0x2e, + 0xf0, 0x0f, 0xb0, 0x0b, 0x3e, 0x80, 0xfb, 0x80, + 0x3a, 0xc0, 0x2c, 0x30, 0x02, 0xec, 0x00, 0xf9, + 0xe0, 0x32, 0xc0, 0x0c, 0xb8, 0xed, 0x09, 0x00, + 0x37, 0x00, 0xa2, 0xec, 0x00, 0xfa, 0x80, 0xa2, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x13, 0xea, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0x30, 0x0f, 0xb0, 0x03, 0xe4, + 0x00, 0xfb, 0x40, 0x3c, 0xc0, 0x0f, 0xc0, 0x03, + 0xec, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xb0, + 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3f, 0x40, 0x0f, + 0xb0, 0x03, 0xcc, 0x00, 0xf8, 0x00, 0x3e, 0x62, + 0x2d, 0xb4, 0x83, 0xec, 0x00, 0xf8, 0x50, 0x3e, + 0xd0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0x90, 0x07, 0xb0, 0x03, 0xe0, 0x10, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, + 0xff, 0x00, 0x3e, 0x80, 0x0c, 0xc0, 0x83, 0x34, + 0x00, 0xfd, 0x00, 0x3f, 0x40, 0x0c, 0xc0, 0x03, + 0x3e, 0x20, 0xd7, 0x00, 0x33, 0xc2, 0x0f, 0xf0, + 0x03, 0xfc, 0x04, 0xcf, 0x01, 0x3f, 0x80, 0x0f, + 0xf9, 0x03, 0x34, 0x40, 0x49, 0x00, 0x33, 0x00, + 0x2c, 0xe8, 0x03, 0xfc, 0x04, 0xfe, 0x00, 0x3f, + 0xc0, 0x0c, 0xf0, 0x03, 0x7c, 0x00, 0xff, 0x00, + 0x3f, 0x24, 0x0c, 0xf0, 0x03, 0xc0, 0x40, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, + 0xbb, 0x00, 0x2e, 0x20, 0x28, 0x80, 0x12, 0x24, + 0x00, 0xbb, 0xd2, 0x2e, 0xc0, 0x28, 0x80, 0x12, + 0x2e, 0x04, 0x8b, 0x02, 0x2a, 0xe0, 0x0b, 0xb0, + 0x42, 0xec, 0x00, 0x8b, 0xc0, 0x2e, 0x00, 0x0b, + 0xb8, 0x02, 0xac, 0x00, 0x89, 0xe1, 0x2a, 0x00, + 0x08, 0xa4, 0x02, 0xec, 0x00, 0x38, 0x80, 0x2e, + 0xe4, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0x30, 0x28, 0xb0, 0x12, 0xe0, 0x44, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, + 0xbb, 0x00, 0x2e, 0xf0, 0x08, 0x38, 0x82, 0x20, + 0xed, 0x09, 0x00, 0x38, 0x00, 0x80, 0xbb, 0x00, + 0x2e, 0xc8, 0x08, 0x30, 0x02, 0x0c, 0x80, 0x9b, + 0x80, 0x22, 0xc4, 0x0b, 0x91, 0x06, 0xcc, 0x00, + 0x8b, 0x80, 0x2e, 0xd8, 0x0b, 0x90, 0x02, 0x2c, + 0x00, 0xa9, 0x80, 0x20, 0xc0, 0x40, 0xa2, 0x02, + 0xec, 0x00, 0xb9, 0x88, 0x2e, 0x42, 0x88, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2c, 0xd0, 0x08, + 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0x40, 0x08, 0x30, 0x0a, 0x04, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x88, 0x00, 0x02, 0x04, 0x00, 0x83, + 0x00, 0x28, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x02, + 0xa3, 0x00, 0x2c, 0x40, 0x0b, 0x30, 0x02, 0x8c, + 0x02, 0xa0, 0x00, 0x20, 0x20, 0x08, 0x20, 0x02, + 0xcc, 0x00, 0xb0, 0x00, 0x24, 0x40, 0x48, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x04, 0x2c, 0x81, 0x08, + 0x30, 0x42, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, + 0x00, 0x0c, 0xa0, 0x03, 0x24, 0x04, 0xfb, 0x00, + 0x3e, 0xc1, 0x0c, 0xb0, 0x03, 0x2c, 0x02, 0xdb, + 0x00, 0x72, 0xc0, 0x8f, 0xb0, 0x03, 0xfc, 0x00, + 0xcb, 0x00, 0x3e, 0x80, 0x4f, 0xb0, 0x0b, 0x2c, + 0x00, 0xe9, 0x00, 0x30, 0x00, 0x2c, 0xa0, 0x03, + 0xec, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x2c, 0xb0, + 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0x00, 0x0c, + 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0xfc, 0x00, + 0x3f, 0x40, 0x0f, 0xc0, 0x13, 0xfc, 0x00, 0xfd, + 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0xfc, 0x00, + 0xdc, 0x00, 0x3f, 0x00, 0x0f, 0xd0, 0x03, 0x74, + 0x00, 0xdd, 0x00, 0xbf, 0x00, 0x0f, 0xe0, 0x07, + 0xfc, 0x00, 0xfd, 0xed, 0x09, 0x00, 0x39, 0x00, + 0x00, 0x3f, 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0x01, 0x0f, 0xf0, 0x03, 0xe8, + 0x12, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x05, + 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x40, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0x7c, 0x00, 0xdf, 0x00, 0x3f, 0x00, + 0x0e, 0xf0, 0x03, 0xb0, 0x00, 0xfc, 0x41, 0x3f, + 0x0e, 0x0d, 0xf0, 0x03, 0xdc, 0x10, 0xf7, 0x00, + 0x3f, 0x00, 0x0c, 0xf2, 0x03, 0xb0, 0x0c, 0xfc, + 0x10, 0x2f, 0x00, 0x0e, 0xf1, 0x43, 0x70, 0x02, + 0xcc, 0x10, 0x33, 0x00, 0x0f, 0xf0, 0x03, 0xf0, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, + 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x20, 0x2f, 0xd0, 0x0b, + 0xf6, 0x82, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0x80, + 0x08, 0xb0, 0x02, 0x21, 0x00, 0xb8, 0x40, 0x2e, + 0x18, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xbf, 0x40, + 0x2e, 0xc0, 0x0c, 0xf5, 0x02, 0x2c, 0x00, 0x98, + 0x20, 0x2e, 0x00, 0x0c, 0xb3, 0x03, 0x6d, 0x00, + 0x8b, 0x60, 0xa2, 0xd0, 0x0b, 0xb0, 0x02, 0xe0, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x04, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc4, 0x8b, + 0x34, 0x02, 0xcc, 0x00, 0x93, 0x00, 0x2c, 0x00, + 0x0a, 0x10, 0x02, 0x81, 0x00, 0xb0, 0x60, 0x24, + 0x00, 0x09, 0x30, 0x02, 0xcc, 0x11, 0xb3, 0x10, + 0x2c, 0x40, 0x1b, 0x30, 0x02, 0x04, 0x00, 0xb0, + 0x00, 0x2c, 0x00, 0x0a, 0x32, 0x02, 0x01, 0x00, + 0x80, 0x10, 0x28, 0x04, 0x0b, 0x30, 0x02, 0xe2, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, + 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xed, 0x09, + 0x00, 0x3a, 0x00, 0xc1, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0xbb, 0x00, 0x2e, 0xa0, 0x08, 0x90, 0x02, + 0x66, 0x00, 0xb8, 0x80, 0x2c, 0x20, 0x09, 0xa4, + 0x42, 0x68, 0x20, 0xbb, 0x00, 0x2e, 0xe0, 0x08, + 0xb0, 0x02, 0x2c, 0x20, 0xba, 0x40, 0x2e, 0x08, + 0x18, 0xb0, 0x42, 0x6c, 0x00, 0x8b, 0x00, 0x22, + 0xc0, 0x0b, 0xb0, 0x02, 0xf8, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x15, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc1, 0x0f, 0xb0, 0x03, 0x6c, + 0x00, 0xdb, 0x00, 0x3e, 0xe0, 0x0e, 0x10, 0x03, + 0xa3, 0x80, 0xf8, 0xa0, 0x3e, 0x20, 0x0d, 0xb0, + 0x03, 0xee, 0x00, 0xfb, 0x00, 0x3e, 0xe0, 0x1d, + 0xb0, 0x0b, 0xad, 0x00, 0xf8, 0xd0, 0x1e, 0x30, + 0x0e, 0xb0, 0x63, 0x00, 0x00, 0xc8, 0x00, 0x3a, + 0x00, 0x0f, 0xb0, 0x03, 0xc0, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x01, 0xbc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x7f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0x3c, 0xc2, 0x07, 0xf4, 0x03, + 0xb0, 0x00, 0xbd, 0x02, 0x3f, 0x00, 0x06, 0xf4, + 0x03, 0xfb, 0x00, 0xff, 0x08, 0x3d, 0xc2, 0x2d, + 0xb0, 0x83, 0xec, 0x08, 0xdd, 0x00, 0x36, 0x20, + 0x0e, 0x70, 0x03, 0x7c, 0x00, 0xff, 0x00, 0xbf, + 0xc0, 0x0f, 0xf0, 0x43, 0xf8, 0x40, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xac, + 0x00, 0xfb, 0x00, 0x3e, 0xd0, 0x0c, 0x90, 0x07, + 0xe5, 0x00, 0xe9, 0x20, 0x3e, 0x00, 0x0e, 0xb8, + 0x03, 0xed, 0x00, 0xfb, 0x12, 0x32, 0x80, 0x0f, + 0x30, 0x0b, 0x2d, 0x40, 0xeb, 0x40, 0x32, 0x00, + 0x0c, 0xed, 0x09, 0x00, 0x3b, 0x00, 0xb0, 0x03, + 0x20, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0xb0, + 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2f, + 0xc0, 0x0b, 0xf0, 0x02, 0x2c, 0x00, 0xfb, 0x00, + 0x2e, 0xc0, 0x08, 0x92, 0x02, 0xe4, 0x00, 0xb9, + 0x00, 0x2e, 0x00, 0x4f, 0xb8, 0x06, 0xeb, 0x00, + 0x8f, 0x81, 0x36, 0xf1, 0x0b, 0xfa, 0x02, 0x2d, + 0x04, 0xab, 0x01, 0x34, 0x00, 0x28, 0xf0, 0x02, + 0x2c, 0xc0, 0xbb, 0x00, 0x36, 0xc0, 0x09, 0xb0, + 0x02, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x12, 0x8c, 0x00, 0xb3, 0x00, + 0x2c, 0x80, 0x08, 0x30, 0x02, 0xc0, 0x04, 0xa0, + 0x44, 0x2c, 0x00, 0x08, 0x12, 0x12, 0xce, 0x00, + 0xb3, 0x01, 0x24, 0xf0, 0x0b, 0x3c, 0x06, 0x04, + 0x80, 0x82, 0x00, 0x2c, 0x20, 0x0b, 0x30, 0x02, + 0x00, 0x10, 0xb8, 0x00, 0x2c, 0x00, 0x0b, 0x30, + 0x02, 0x78, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x6d, + 0xe0, 0x0b, 0x78, 0x02, 0x1e, 0x00, 0xa7, 0x80, + 0x2d, 0xa0, 0x0a, 0x78, 0x02, 0xd6, 0x50, 0xb5, + 0x80, 0x2d, 0x21, 0x83, 0x58, 0x02, 0xff, 0x6a, + 0x97, 0x80, 0x25, 0xa2, 0x09, 0x78, 0x02, 0x1e, + 0x00, 0xa7, 0x80, 0x2d, 0x62, 0x0b, 0x79, 0x02, + 0x1e, 0x04, 0xb7, 0x80, 0x05, 0xe0, 0x09, 0x78, + 0x02, 0xc8, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, + 0x0b, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x10, 0x3c, + 0xc4, 0x0f, 0xb0, 0x03, 0xed, 0x09, 0x00, 0x3c, + 0x00, 0x8c, 0x00, 0xb3, 0x00, 0x3c, 0x80, 0x2c, + 0x10, 0x22, 0xc8, 0x00, 0xe3, 0x00, 0x3e, 0x00, + 0x1c, 0x32, 0x02, 0xc8, 0x40, 0xf3, 0x00, 0x14, + 0xd8, 0x0f, 0x32, 0x02, 0x04, 0x18, 0xeb, 0x00, + 0x3c, 0x14, 0x0f, 0xb0, 0x0b, 0x00, 0x00, 0xf0, + 0x00, 0x3c, 0x00, 0x0f, 0x30, 0x03, 0xd2, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, 0xbc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xd2, 0x0f, 0xf0, + 0x03, 0xfc, 0x40, 0xff, 0x00, 0x3f, 0x80, 0x0d, + 0xd0, 0x03, 0xfc, 0x18, 0xbf, 0x10, 0x3f, 0x84, + 0x0d, 0xf0, 0x03, 0xf8, 0x40, 0xef, 0x12, 0x2f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x40, 0xff, 0x00, + 0x37, 0x40, 0x04, 0xf0, 0x23, 0xfc, 0x00, 0xff, + 0x00, 0x3b, 0xe0, 0x0f, 0xf1, 0x03, 0xd0, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb4, + 0x03, 0x6c, 0x00, 0xdb, 0x00, 0x3e, 0xc0, 0x0c, + 0xb0, 0x07, 0xcc, 0x00, 0xda, 0x80, 0x32, 0x40, + 0x0f, 0x90, 0x03, 0x62, 0x00, 0xcb, 0x20, 0x12, + 0xc0, 0x8d, 0xb4, 0x03, 0xec, 0x00, 0xca, 0x00, + 0x32, 0x40, 0x0b, 0xb0, 0x03, 0x22, 0x00, 0xc8, + 0x00, 0x7e, 0x00, 0x0f, 0xb0, 0x03, 0xe2, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x34, + 0xa3, 0x1c, 0x00, 0xb7, 0x00, 0x2f, 0x80, 0x08, + 0x70, 0x02, 0xdc, 0x00, 0xa7, 0x06, 0x21, 0xc0, + 0x0b, 0xd0, 0x0a, 0x50, 0x00, 0xa3, 0x50, 0xa1, + 0xc0, 0x0b, 0x74, 0x82, 0x5c, 0x00, 0xe7, 0x00, + 0x29, 0x40, 0x0e, 0xf6, 0x03, 0x5c, 0x00, 0xed, + 0x09, 0x00, 0x3d, 0x00, 0xd7, 0x00, 0x25, 0xc0, + 0x0b, 0x70, 0x02, 0xd2, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, + 0x80, 0x2d, 0xe8, 0x0b, 0x78, 0x02, 0x1e, 0x00, + 0xb7, 0x80, 0x2d, 0xe0, 0x09, 0x58, 0x02, 0xde, + 0x28, 0x83, 0x80, 0x65, 0x61, 0x0b, 0x58, 0x82, + 0x1a, 0x00, 0x87, 0x80, 0x21, 0xe0, 0x49, 0x78, + 0x06, 0xdf, 0x00, 0x97, 0x80, 0x61, 0x60, 0x0b, + 0x78, 0x22, 0x42, 0x09, 0x84, 0x80, 0x2d, 0x20, + 0x8b, 0x78, 0x42, 0xf8, 0x40, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x14, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xbb, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x0a, 0x0c, 0x00, + 0xb3, 0x00, 0x2c, 0xf0, 0x49, 0x18, 0x02, 0xce, + 0x00, 0xa3, 0xa0, 0x24, 0xfc, 0x0b, 0x98, 0x02, + 0x08, 0x00, 0xa3, 0x00, 0x20, 0xb8, 0x0b, 0x30, + 0x02, 0x4e, 0x00, 0xa3, 0x40, 0x28, 0xc0, 0x4a, + 0x30, 0x02, 0x4c, 0x10, 0x93, 0x00, 0x24, 0xc0, + 0x0b, 0x30, 0x02, 0xd2, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xfa, 0x00, + 0x3e, 0x80, 0x0d, 0xa0, 0x03, 0xe8, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0x28, 0x00, + 0xda, 0x00, 0x3f, 0x81, 0x0d, 0xaa, 0x03, 0xfb, + 0x00, 0xce, 0xc0, 0xa7, 0x80, 0x0f, 0xe4, 0x03, + 0x7b, 0x00, 0xca, 0x00, 0x21, 0xa9, 0x0d, 0xa0, + 0x02, 0xf9, 0x00, 0x9e, 0x60, 0x31, 0x90, 0x0f, + 0xa0, 0x03, 0x68, 0x00, 0xca, 0x00, 0x3e, 0x80, + 0x0f, 0xa0, 0x03, 0xfa, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xa0, 0x00, + 0xf8, 0x00, 0xed, 0x09, 0x00, 0x3e, 0x00, 0x3e, + 0x06, 0x6e, 0x80, 0x03, 0x60, 0x20, 0xe8, 0x50, + 0x7a, 0x01, 0x0f, 0x88, 0x23, 0xe3, 0x40, 0xf8, + 0x01, 0x3e, 0x00, 0x43, 0x84, 0x03, 0xc2, 0x10, + 0xf8, 0x08, 0x3e, 0x20, 0x07, 0x80, 0x23, 0xf0, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0b, 0x80, 0x03, + 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x2a, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3c, + 0x60, 0x0c, 0x98, 0x03, 0xe4, 0x00, 0xc9, 0x80, + 0x3e, 0x40, 0x4f, 0x90, 0x03, 0x24, 0x84, 0xf1, + 0x82, 0x32, 0x44, 0x8c, 0x91, 0x43, 0xe4, 0x08, + 0xd9, 0x00, 0x12, 0x40, 0x0e, 0x90, 0x03, 0x26, + 0x00, 0xf9, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x23, + 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x02, 0x40, + 0x09, 0x90, 0x02, 0x24, 0x00, 0x99, 0x00, 0x2e, + 0x42, 0x00, 0x98, 0x02, 0xc4, 0x01, 0xf9, 0x40, + 0x2e, 0x41, 0x0b, 0x94, 0x21, 0xe7, 0x00, 0xe9, + 0x02, 0x22, 0x60, 0x4d, 0x98, 0x02, 0xe5, 0x00, + 0xa9, 0x00, 0x36, 0x60, 0x48, 0x90, 0x12, 0xa5, + 0x81, 0xb9, 0x00, 0x36, 0x40, 0x0b, 0x90, 0x02, + 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x10, 0x02, 0xa4, 0x00, 0xb9, 0x00, 0x0e, + 0xc4, 0x28, 0x91, 0x02, 0x65, 0x90, 0x89, 0x22, + 0x2e, 0xc0, 0x09, 0x90, 0x82, 0x24, 0x04, 0xb9, + 0x50, 0x26, 0x40, 0x08, 0x94, 0x02, 0xe4, 0x88, + 0xb1, 0x04, 0x2a, 0x44, 0x0a, 0x10, 0x06, 0x24, + 0x40, 0xa5, 0x00, 0x27, 0x40, 0xed, 0x09, 0x00, + 0x3f, 0x00, 0x0b, 0x90, 0x02, 0xc6, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, + 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, + 0x00, 0xb1, 0x00, 0x24, 0x4a, 0x0b, 0x12, 0x82, + 0x04, 0x04, 0x91, 0x01, 0x6c, 0x50, 0x08, 0x10, + 0x02, 0xc4, 0xa1, 0xb1, 0x2c, 0x6c, 0x50, 0x8b, + 0x14, 0x0a, 0x84, 0x00, 0xa1, 0x00, 0xa0, 0x60, + 0x09, 0x14, 0x02, 0xc7, 0x01, 0x81, 0x45, 0x2e, + 0x4a, 0x08, 0x14, 0x06, 0x14, 0x00, 0xb5, 0x40, + 0x25, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x08, 0x0b, 0x82, 0x03, + 0xa0, 0x00, 0xf8, 0x00, 0x2e, 0x00, 0x08, 0x80, + 0x03, 0xe0, 0x80, 0x8a, 0x20, 0x3e, 0x00, 0x0f, + 0x80, 0x02, 0x28, 0x08, 0xf8, 0x00, 0x36, 0x00, + 0x0c, 0x80, 0x06, 0xc0, 0x04, 0xd0, 0x00, 0xba, + 0x08, 0x0e, 0x80, 0x0b, 0x20, 0x10, 0xe8, 0x00, + 0x37, 0x00, 0x0f, 0x80, 0x03, 0xee, 0x02, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x98, 0x0d, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x2c, 0x32, 0x40, 0x0d, 0x92, 0xa7, + 0xe4, 0x00, 0xd9, 0x00, 0x3f, 0x51, 0x0f, 0xd0, + 0x43, 0xf4, 0x00, 0xed, 0x28, 0x2f, 0x50, 0x0f, + 0xd0, 0x03, 0x54, 0x00, 0x69, 0x41, 0x73, 0x50, + 0x47, 0x94, 0x23, 0xf5, 0x00, 0xfd, 0x00, 0x33, + 0x41, 0x07, 0x94, 0x03, 0xe5, 0x00, 0xf9, 0x40, + 0x3e, 0x50, 0x0d, 0x90, 0x03, 0xe6, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xd9, 0x01, 0x36, 0x40, 0x8d, 0x91, 0x43, + 0x24, 0x00, 0xf9, 0x00, 0x37, 0x48, 0x0c, 0x50, + 0xed, 0x09, 0x00, 0x40, 0x00, 0x03, 0xb4, 0x0d, + 0xfd, 0x10, 0x1e, 0x48, 0x0f, 0xd1, 0x03, 0xf4, + 0x00, 0xfd, 0x28, 0x37, 0x48, 0x0d, 0xd0, 0x5b, + 0x74, 0x00, 0xb9, 0x10, 0x23, 0xc8, 0x0f, 0x92, + 0x83, 0xf4, 0x80, 0xf9, 0x00, 0x32, 0x40, 0x0f, + 0x90, 0x03, 0xc6, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, + 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb0, 0x0c, + 0x2e, 0x00, 0x0b, 0x81, 0x0a, 0x20, 0x00, 0xb8, + 0x00, 0x2e, 0x0a, 0x88, 0x80, 0x02, 0x20, 0x00, + 0xb8, 0x11, 0x2e, 0x02, 0x09, 0x80, 0x00, 0xe8, + 0x00, 0x98, 0x00, 0x2e, 0x04, 0x0f, 0x84, 0x82, + 0x20, 0x20, 0x98, 0x00, 0x22, 0x04, 0x0b, 0x82, + 0x42, 0xe0, 0x48, 0xb0, 0x48, 0x22, 0x00, 0x0b, + 0x80, 0x02, 0xce, 0x44, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0x91, 0x20, + 0x28, 0x44, 0x09, 0x10, 0x02, 0x04, 0x00, 0xb1, + 0x00, 0x2c, 0x4c, 0x08, 0x10, 0x42, 0x84, 0x40, + 0x81, 0x00, 0x2c, 0x44, 0x09, 0x10, 0x42, 0xc4, + 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x8b, 0x13, 0x02, + 0x06, 0x40, 0x99, 0x00, 0x24, 0x40, 0x0b, 0x12, + 0x82, 0xc4, 0x00, 0xb1, 0x30, 0x28, 0x44, 0x0b, + 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x00, 0x24, 0x00, 0x99, + 0x02, 0x2e, 0x50, 0x28, 0x98, 0x02, 0x24, 0x61, + 0xb9, 0x18, 0x2e, 0x40, 0x09, 0x92, 0x82, 0xe4, + 0x00, 0x99, 0x00, 0x2e, 0x40, 0x0a, 0x90, 0x02, + 0x24, 0x00, 0x99, 0x00, 0xa6, 0x40, 0x8b, 0x90, + 0x02, 0xe4, 0x10, 0xb9, 0x00, 0x2a, 0x40, 0x0b, + 0x90, 0x02, 0xc6, 0xed, 0x09, 0x00, 0x41, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, + 0xe4, 0x00, 0xf9, 0x00, 0x2e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xd9, 0x00, 0x36, 0x40, 0x0d, + 0x90, 0x03, 0x24, 0x00, 0x79, 0x00, 0x36, 0x50, + 0x08, 0x18, 0x03, 0xa6, 0x00, 0x79, 0x00, 0x3e, + 0x64, 0x8d, 0x98, 0x41, 0xe6, 0x04, 0xf9, 0x02, + 0x36, 0x42, 0x09, 0x90, 0x03, 0x24, 0x00, 0xf9, + 0x9a, 0x16, 0x60, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0xba, 0x40, 0x0f, 0x90, 0x03, 0xe8, + 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, + 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x10, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x34, 0x42, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x83, 0xe6, 0x80, 0xd9, 0x00, + 0x3e, 0x42, 0x0f, 0x90, 0x03, 0xa4, 0x08, 0xc9, + 0x00, 0x22, 0x44, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x36, 0x40, 0x0f, 0x90, 0x03, 0xca, + 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, + 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0d, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3a, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x10, + 0x4c, 0x80, 0x03, 0x60, 0x00, 0xf8, 0x42, 0x3e, + 0x01, 0x0d, 0x84, 0x03, 0xe3, 0x00, 0xd8, 0x90, + 0x3e, 0x10, 0x0c, 0x81, 0x8b, 0x60, 0x00, 0xc8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x01, 0xe0, 0x00, + 0xc8, 0x04, 0x32, 0x00, 0x0f, 0x80, 0x03, 0xca, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, + 0x02, 0xe8, 0x00, 0xba, 0x00, 0x32, 0x80, 0x03, + 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2f, 0x90, + 0x08, 0xee, 0x02, 0x39, 0x80, 0x3e, 0xed, 0x09, + 0x00, 0x42, 0x00, 0x10, 0x2e, 0x80, 0x0b, 0xe6, + 0x02, 0xfb, 0x00, 0xbe, 0x41, 0x2f, 0xa0, 0x48, + 0xe8, 0x03, 0x1b, 0x00, 0xa2, 0x00, 0x2e, 0x80, + 0x0b, 0xa0, 0x02, 0xf8, 0x00, 0x8a, 0x00, 0xa2, + 0x80, 0x0b, 0xa0, 0x02, 0xc8, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x0c, + 0x33, 0x02, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x8c, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x28, 0x1e, 0x02, + 0x0e, 0x20, 0xb3, 0x50, 0x2c, 0xc0, 0x0b, 0x2c, + 0x02, 0xc6, 0x40, 0xb1, 0x84, 0x28, 0xa4, 0x2a, + 0xa8, 0x02, 0x04, 0x80, 0x83, 0x00, 0x2c, 0xc4, + 0x0b, 0x30, 0x02, 0xcc, 0x04, 0x9b, 0x02, 0x84, + 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x04, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, + 0xb7, 0x80, 0x25, 0xc0, 0x0b, 0x72, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xd0, 0x08, 0xf0, 0x22, + 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x09, 0x70, + 0x02, 0xd4, 0x00, 0xb4, 0x00, 0x0c, 0xa0, 0x08, + 0x70, 0x22, 0x05, 0x00, 0xa7, 0x20, 0x25, 0xc0, + 0x0b, 0x72, 0x00, 0xd6, 0x00, 0x97, 0x20, 0x25, + 0xc0, 0x8b, 0x70, 0x02, 0xc8, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xf7, + 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, + 0xf7, 0xc8, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0x9e, + 0x00, 0xf7, 0x80, 0x3f, 0xa0, 0x0c, 0x78, 0x03, + 0x5e, 0x00, 0xf7, 0x80, 0x2d, 0xfc, 0x0d, 0x78, + 0x03, 0xd2, 0x00, 0xd5, 0x80, 0x3d, 0xa0, 0x0c, + 0x38, 0x03, 0x16, 0x01, 0xc7, 0xa0, 0x3d, 0xe0, + 0x0f, 0x7b, 0x03, 0xde, 0x02, 0xd7, 0xa0, 0x25, + 0xe0, 0x07, 0x78, 0x03, 0xca, 0x02, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x08, 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x1a, + 0xc0, 0x07, 0xb3, 0x07, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x01, 0x6c, 0x04, 0xfb, + 0x02, 0x1e, 0xc8, 0x0f, 0xb0, 0x23, 0xe8, 0x10, + 0xf8, 0x02, 0x1e, 0xc0, 0x0b, 0xb0, 0x03, 0xa4, + 0x00, 0xfb, 0x68, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0x40, 0x00, 0xeb, 0x48, 0x3a, 0xc0, 0x0f, 0xb0, + 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, + 0x0f, 0xf8, 0x03, 0x7e, 0x00, 0xff, 0x80, 0x3f, + 0xe0, 0x0d, 0xf6, 0x03, 0x7e, 0x00, 0xff, 0x80, + 0x3f, 0xe0, 0x0e, 0xd0, 0x37, 0xfa, 0x40, 0x4f, + 0x90, 0x33, 0xe4, 0x0d, 0xf8, 0x19, 0xb6, 0x50, + 0xfd, 0x90, 0x33, 0xa0, 0x03, 0xf8, 0x03, 0x36, + 0x00, 0xdf, 0x88, 0x33, 0xe4, 0x0f, 0xf8, 0x83, + 0xfe, 0x00, 0xcf, 0x88, 0x37, 0xe0, 0x0c, 0xf8, + 0x03, 0xd0, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x3d, + 0xc0, 0x08, 0x71, 0x06, 0xdc, 0x00, 0xb7, 0x00, + 0x2f, 0xc0, 0x08, 0x51, 0x02, 0xd9, 0x18, 0x8f, + 0x10, 0x21, 0xc6, 0x0b, 0x60, 0x02, 0x14, 0x00, + 0xb4, 0x01, 0x29, 0x08, 0x49, 0x66, 0x03, 0xd4, + 0x00, 0xbf, 0x18, 0x21, 0xc0, 0x0b, 0x70, 0x03, + 0xd4, 0x08, 0xd7, 0x00, 0x35, 0xc0, 0x0d, 0x70, + 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x71, 0x02, 0xdc, 0x00, 0x97, 0x00, + 0x2d, 0xc0, 0x0a, 0x51, 0x02, 0xd4, 0x0a, 0xa4, + 0x00, 0x21, 0xc4, 0x1b, 0xed, 0x09, 0x00, 0x44, + 0x00, 0xf0, 0x02, 0x90, 0x04, 0xb3, 0x00, 0x69, + 0x80, 0x19, 0x70, 0x02, 0x54, 0x00, 0xb7, 0x00, + 0x29, 0x42, 0x1b, 0x70, 0x02, 0xcc, 0x00, 0x83, + 0x08, 0x20, 0xc0, 0x0b, 0x70, 0x02, 0x60, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x0a, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2e, 0xd8, 0x08, + 0x11, 0x02, 0xc5, 0x00, 0x80, 0x00, 0x20, 0xc0, + 0x0b, 0x30, 0x02, 0x08, 0x00, 0xb2, 0x00, 0x20, + 0x44, 0x0b, 0xb0, 0x22, 0x85, 0xc0, 0xb3, 0x40, + 0x20, 0x70, 0x0b, 0x30, 0x02, 0x82, 0x40, 0x93, + 0x40, 0x24, 0xd2, 0x0b, 0x30, 0x02, 0xd8, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xac, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0x6c, 0x00, 0xff, 0x00, 0x2e, 0xc0, 0x0f, 0xf0, + 0x02, 0x6c, 0x00, 0xdb, 0x00, 0x3e, 0xb8, 0x0e, + 0x80, 0x03, 0xe4, 0x00, 0xc9, 0x10, 0xb3, 0xe0, + 0x0d, 0x30, 0x03, 0xa4, 0x04, 0xb9, 0x00, 0xba, + 0x90, 0x0f, 0xb0, 0x22, 0x24, 0x04, 0x7f, 0xc4, + 0xba, 0xf0, 0x0b, 0xf0, 0x02, 0xe8, 0x00, 0xcf, + 0x80, 0x62, 0xd2, 0x0f, 0xb0, 0x03, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3c, 0xc0, 0x0d, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x80, 0x0f, + 0x80, 0x23, 0xe5, 0x28, 0xd8, 0x00, 0x3e, 0xc0, + 0x0f, 0xb6, 0x03, 0xe4, 0x80, 0xfa, 0x40, 0x3e, + 0x92, 0x0d, 0xb4, 0x03, 0xe4, 0x10, 0x7b, 0x20, + 0x3e, 0x48, 0x8f, 0xb0, 0x03, 0x61, 0x28, 0xfb, + 0x08, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, 0xe0, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xed, + 0x09, 0x00, 0x45, 0x00, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3e, 0xc0, 0xc6, 0xf0, 0x43, 0xfc, 0x00, + 0xff, 0x00, 0x2f, 0x80, 0x0c, 0xe0, 0x03, 0xe8, + 0x00, 0xfd, 0x00, 0x3d, 0xc0, 0x0e, 0xe0, 0x11, + 0xf2, 0x84, 0xd5, 0xa0, 0x3b, 0x00, 0x0c, 0xa0, + 0x0b, 0x36, 0x04, 0xff, 0x00, 0x23, 0xc0, 0x0f, + 0xf0, 0x03, 0xb0, 0x00, 0x77, 0x00, 0x31, 0xc1, + 0x0e, 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, 0x9b, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x0e, 0xc1, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2e, 0xb2, 0x08, 0xa4, 0x22, 0xeb, + 0x40, 0xb8, 0xe0, 0x2e, 0xc0, 0x8a, 0xbc, 0x02, + 0x28, 0x00, 0xba, 0x00, 0x20, 0x78, 0x0a, 0xbc, + 0x02, 0x2e, 0x00, 0x93, 0x00, 0x22, 0x44, 0x0f, + 0xb0, 0x00, 0xe1, 0x80, 0xbb, 0x00, 0x2a, 0xc0, + 0x0a, 0xb0, 0x02, 0xf0, 0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0a, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x26, 0xa0, 0x08, 0x9c, 0x02, 0xe0, + 0x00, 0x99, 0x80, 0x2e, 0xc0, 0x08, 0xbc, 0x0a, + 0xec, 0x08, 0xb9, 0x08, 0x22, 0xc4, 0x0a, 0xb8, + 0x02, 0xec, 0x80, 0xbb, 0x02, 0x2a, 0xc0, 0x1b, + 0xb0, 0x12, 0xa8, 0x80, 0xbb, 0x00, 0x2a, 0xc0, + 0x18, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0x80, 0x0a, 0x10, 0x02, 0xc0, + 0x00, 0xb0, 0x00, 0x0c, 0xc0, 0x08, 0x90, 0x02, + 0x0a, 0x00, 0xed, 0x09, 0x00, 0x46, 0x00, 0x32, + 0x00, 0x20, 0x40, 0xb8, 0x10, 0x06, 0x0e, 0x00, + 0x1b, 0x00, 0x08, 0x40, 0x1a, 0x30, 0x02, 0x40, + 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x02, 0x30, 0x02, + 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0x3e, 0xc0, + 0x0e, 0xf0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x36, + 0x00, 0x2c, 0x90, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3f, 0xc0, 0x2e, 0xb0, 0x43, 0xe8, 0x08, 0x9a, + 0x00, 0xb2, 0x40, 0x0e, 0xb0, 0x23, 0x60, 0x00, + 0xff, 0x00, 0x3a, 0x40, 0x0b, 0xf0, 0x03, 0xa0, + 0x00, 0xff, 0x00, 0x32, 0xc0, 0x0e, 0xb0, 0x03, + 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x1d, 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0x00, 0x0d, 0xd0, 0x03, 0xf0, 0x00, 0xfc, 0x00, + 0x3f, 0xc0, 0x07, 0x40, 0x03, 0x7c, 0x00, 0xbf, + 0x00, 0x37, 0x40, 0x0f, 0xe0, 0x03, 0xbc, 0x00, + 0xbf, 0x00, 0x37, 0x40, 0x0f, 0xf0, 0x03, 0xf0, + 0x00, 0xff, 0x00, 0x2f, 0xc0, 0x0f, 0xf0, 0x03, + 0xe8, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x05, 0xf8, 0x00, 0xec, 0x11, 0x33, 0x04, 0x4c, + 0xc1, 0x03, 0xf1, 0x00, 0xfc, 0x10, 0x3f, 0x00, + 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xcc, 0x00, 0x33, + 0x00, 0x0c, 0xc1, 0x23, 0xf0, 0x00, 0xfc, 0x00, + 0x33, 0x00, 0x0f, 0xc0, 0x03, 0x3c, 0x00, 0x4f, + 0x03, 0x3f, 0xc0, 0x8f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x33, 0xc0, 0x0f, 0xf0, 0x23, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0x01, 0x8d, 0xc3, 0x13, + 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x10, 0xe8, 0x00, 0xb0, 0xa0, 0xed, 0x09, 0x00, + 0x47, 0x00, 0x22, 0x28, 0x08, 0x8a, 0x22, 0xe2, + 0x00, 0xb8, 0x80, 0x2e, 0x80, 0x1b, 0x90, 0x12, + 0xec, 0x00, 0x89, 0x01, 0x2a, 0x00, 0x08, 0x88, + 0x02, 0xe2, 0x20, 0xb8, 0x00, 0x22, 0x80, 0x0b, + 0x80, 0x02, 0x3e, 0x80, 0x8f, 0x00, 0x2e, 0xc1, + 0x0b, 0xb0, 0x22, 0xec, 0x00, 0xbb, 0x00, 0xa2, + 0xc1, 0x8b, 0xb0, 0x02, 0xec, 0x10, 0xbb, 0x00, + 0x2e, 0x96, 0x08, 0x83, 0x02, 0x20, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, 0x00, + 0xa0, 0x20, 0x20, 0x08, 0x08, 0x22, 0x02, 0xc0, + 0x80, 0xb0, 0x20, 0x2c, 0x40, 0x0b, 0x20, 0x02, + 0xe0, 0x02, 0x82, 0x04, 0x2a, 0x20, 0x08, 0x02, + 0x02, 0xc0, 0x80, 0xb8, 0x80, 0x20, 0x40, 0x4b, + 0xa0, 0x06, 0x0c, 0x20, 0x93, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x14, 0xb3, 0x01, + 0x2c, 0x08, 0x09, 0x00, 0x02, 0x22, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, 0x00, + 0xb0, 0x00, 0x20, 0x00, 0x08, 0xa0, 0x02, 0xe0, + 0x00, 0xb8, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x06, + 0xec, 0x00, 0xab, 0x04, 0x2a, 0x00, 0x08, 0x80, + 0x02, 0xe0, 0x10, 0xb8, 0x00, 0x22, 0xc0, 0x0b, + 0xa0, 0x0a, 0x2c, 0x10, 0x9b, 0x04, 0x2e, 0x50, + 0x8b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0x44, 0x08, 0x90, 0x02, 0x30, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xe8, 0x00, + 0xea, 0x20, 0xb2, 0x90, 0x2c, 0x82, 0x03, 0xe8, + 0x90, 0xfa, 0x40, 0x3e, 0x00, 0x0b, 0x80, 0x03, + 0xe0, 0x08, 0xc0, 0x00, 0x30, 0x80, 0x8c, 0xa2, + 0x03, 0xe8, 0x80, 0xf2, 0x00, 0x32, 0x00, 0x0f, + 0x00, 0x03, 0x2c, 0x02, 0xdb, 0x00, 0x3e, 0x90, + 0xed, 0x09, 0x00, 0x48, 0x00, 0x0f, 0xb0, 0x23, + 0xec, 0x10, 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xbb, 0x03, 0x3e, 0x61, 0x0d, + 0x98, 0x0b, 0x10, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x01, 0xb8, 0x00, 0xfe, 0x02, 0x3f, + 0x80, 0x0f, 0xc0, 0x03, 0xf8, 0x00, 0xfe, 0x00, + 0x3f, 0x80, 0x0f, 0xd0, 0x03, 0xfc, 0x00, 0xdd, + 0x00, 0x37, 0x81, 0x0b, 0xe0, 0x03, 0xf8, 0x00, + 0xfe, 0x01, 0x3f, 0x80, 0x0f, 0xc0, 0x03, 0xfc, + 0x10, 0xef, 0x01, 0x3f, 0xc2, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xf7, 0x00, 0x3f, 0xc1, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3d, 0xa2, 0x0f, + 0xcc, 0x43, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x10, 0xac, 0x00, 0xfa, 0x80, 0x36, + 0xb0, 0x2c, 0xa8, 0x03, 0xea, 0x00, 0xfa, 0xc0, + 0xba, 0x40, 0x0e, 0xa1, 0x03, 0x20, 0x00, 0xfa, + 0x00, 0x32, 0x82, 0x0c, 0xa8, 0x03, 0xea, 0x00, + 0xfa, 0x00, 0x32, 0x40, 0x0f, 0xa1, 0x03, 0x2c, + 0x00, 0xfb, 0x11, 0x3e, 0x80, 0x4e, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x2c, + 0x31, 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x05, 0x2c, 0x00, 0xba, 0x80, 0x22, + 0xa0, 0x08, 0xa8, 0x02, 0xea, 0x14, 0xba, 0x80, + 0x22, 0xc0, 0x09, 0xb0, 0x0a, 0x0c, 0x08, 0xbb, + 0x00, 0x22, 0x91, 0x48, 0xa8, 0x02, 0xea, 0x00, + 0x9a, 0x01, 0x22, 0xc0, 0x0b, 0xa8, 0x42, 0x3d, + 0x40, 0xbf, 0x00, 0x2e, 0xd0, 0x08, 0xb0, 0x02, + 0xec, 0x00, 0xbf, 0x00, 0xa3, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0x42, 0x88, + 0xb5, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x05, 0x48, 0x00, 0xb1, 0x00, 0x24, + 0x40, 0x08, 0x10, 0xed, 0x09, 0x00, 0x49, 0x00, + 0x02, 0xc4, 0x11, 0xb1, 0x00, 0x24, 0x00, 0x09, + 0x08, 0x02, 0x40, 0x00, 0xb0, 0x00, 0x60, 0x40, + 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x20, + 0x00, 0x0b, 0x10, 0x02, 0x6d, 0x00, 0xb3, 0x80, + 0x2c, 0x80, 0x0a, 0x30, 0x22, 0xcc, 0x00, 0xb3, + 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0x20, 0x08, 0x2c, 0x02, 0xf8, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, + 0x1a, 0x00, 0xb5, 0x80, 0x21, 0x60, 0x08, 0x58, + 0x02, 0xd6, 0x00, 0xb5, 0x80, 0x25, 0xa0, 0x09, + 0xd8, 0x02, 0x5e, 0x00, 0xb5, 0xc0, 0x23, 0x60, + 0x08, 0x58, 0x02, 0xd6, 0x00, 0x9d, 0x80, 0x21, + 0xa0, 0x0b, 0xdc, 0x00, 0x5e, 0x20, 0xb7, 0x80, + 0x2d, 0xe4, 0x28, 0x78, 0x02, 0xde, 0x00, 0xb7, + 0x90, 0x21, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, + 0xb7, 0x80, 0x2d, 0xa4, 0x08, 0x68, 0x02, 0xc8, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, + 0x0c, 0x00, 0xf1, 0x00, 0x36, 0x54, 0x0c, 0x30, + 0x03, 0xc4, 0x00, 0xf9, 0x40, 0x3c, 0x44, 0x0f, + 0x21, 0x03, 0x40, 0x00, 0xf2, 0x00, 0x30, 0x40, + 0x0c, 0x10, 0x03, 0xc4, 0x00, 0xf1, 0x04, 0x30, + 0x40, 0x0f, 0x34, 0x03, 0x4c, 0x80, 0xf3, 0x00, + 0x3e, 0x86, 0x0e, 0x30, 0x03, 0xcc, 0x00, 0xfb, + 0x00, 0x30, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, + 0xf3, 0x00, 0x3e, 0x80, 0x0c, 0x00, 0x03, 0xd2, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, + 0xbc, 0x00, 0xfd, 0x00, 0x3f, 0x41, 0x0f, 0xf0, + 0x03, 0xf4, 0x00, 0xfd, 0x00, 0x3b, 0xc1, 0x1d, + 0x70, 0x03, 0xbc, 0x00, 0xf7, 0x00, 0x3d, 0x40, + 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xf5, 0x00, 0x3f, + 0xc0, 0x0f, 0x70, 0x0b, 0xbd, 0x00, 0xff, 0x08, + 0x3f, 0x44, 0x2f, 0xf0, 0x03, 0xfc, 0xed, 0x09, + 0x00, 0x4a, 0x00, 0x00, 0xff, 0x00, 0x3f, 0xc2, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x10, 0x3f, + 0xc1, 0x0f, 0xd0, 0x03, 0xd0, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x05, 0xe8, 0x00, 0xfb, + 0x80, 0x3a, 0xc0, 0x0f, 0x90, 0x03, 0xec, 0x00, + 0xeb, 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xc8, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x0a, + 0x2c, 0x00, 0xfb, 0x00, 0x2e, 0x00, 0x0f, 0x90, + 0x03, 0xec, 0xc0, 0xcb, 0x40, 0x32, 0xa0, 0x0c, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0xb2, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0x60, 0x0c, 0xb0, 0x03, 0xea, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x11, 0x98, 0x00, 0xbf, + 0x00, 0x21, 0xc0, 0x0b, 0x50, 0x02, 0xdc, 0x00, + 0x8f, 0x00, 0x21, 0x80, 0x0b, 0x50, 0x02, 0xdc, + 0x00, 0x85, 0x00, 0x2d, 0xc0, 0x0b, 0xf0, 0x02, + 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0x80, 0x0b, 0x50, + 0x02, 0xdc, 0x80, 0x83, 0x28, 0x35, 0xc0, 0x2a, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x40, 0x21, 0xc8, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2c, + 0x80, 0x08, 0x60, 0x02, 0xd2, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, 0xb7, + 0x80, 0x29, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, + 0xa7, 0x80, 0x2d, 0x60, 0x0b, 0x68, 0x02, 0xf2, + 0x00, 0x86, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0x1e, 0x10, 0xb7, 0x80, 0x2d, 0x61, 0x0b, 0x78, + 0x02, 0xde, 0x00, 0x87, 0x80, 0x23, 0xa0, 0x08, + 0x78, 0x02, 0xde, 0x00, 0xa3, 0x80, 0x21, 0xe0, + 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, + 0xe0, 0x08, 0x78, 0x62, 0xf0, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, 0x00, 0xb3, + 0x10, 0x22, 0xc4, 0x0b, 0x30, 0x02, 0xce, 0x00, + 0x83, 0xed, 0x09, 0x00, 0x4b, 0x00, 0x80, 0xa4, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x02, 0x83, 0x00, + 0x2c, 0xc0, 0x0b, 0x38, 0x02, 0x0e, 0x04, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0x83, 0x00, 0x24, 0xc4, 0x0a, 0x30, 0x02, 0xcc, + 0x00, 0xbb, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0xb1, + 0x82, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xe8, 0x15, 0xa8, 0x00, 0xfa, 0x82, 0x3a, 0xa0, + 0x0f, 0xa0, 0x03, 0xea, 0x80, 0xea, 0xa0, 0x3e, + 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x04, 0xca, 0x02, + 0x3e, 0x80, 0x0f, 0xaa, 0x03, 0x2a, 0x80, 0x7a, + 0x00, 0x3c, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x02, + 0xca, 0x00, 0x33, 0x90, 0x2c, 0xa0, 0x03, 0xe8, + 0x00, 0xea, 0x00, 0x32, 0x80, 0x0f, 0xa0, 0x03, + 0xe8, 0x00, 0xfa, 0x00, 0x3f, 0x90, 0x0c, 0xe8, + 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3a, + 0x10, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x4f, 0x80, 0x03, 0x60, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x30, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x01, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x08, 0x2f, 0x84, + 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x50, + 0x0d, 0x94, 0x03, 0x24, 0x00, 0x89, 0x00, 0x32, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0x89, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xc9, + 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xc4, 0x00, + 0xc1, 0x00, 0x32, 0x70, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x30, 0xed, 0x09, 0x00, 0x4c, + 0x00, 0x40, 0x0e, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x04, 0x3e, 0x68, 0x0f, 0x98, 0x03, 0x02, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, + 0x00, 0xb9, 0x40, 0x2e, 0x70, 0x08, 0x9c, 0x02, + 0x25, 0x00, 0x89, 0x40, 0x22, 0x40, 0x0b, 0x90, + 0x42, 0x44, 0x02, 0x89, 0x00, 0x2e, 0x40, 0x0b, + 0x94, 0x02, 0x25, 0x00, 0x89, 0x00, 0x2e, 0x40, + 0x0a, 0x98, 0x02, 0xe4, 0x00, 0xa9, 0x60, 0x2a, + 0x68, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, + 0x2a, 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x02, 0x2e, 0x60, 0x0b, 0x9f, 0x02, 0x20, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, + 0x00, 0xbd, 0x00, 0x2f, 0x40, 0x09, 0x50, 0x02, + 0x14, 0x00, 0xa5, 0x00, 0x23, 0x40, 0x0b, 0xd0, + 0x02, 0xf4, 0x00, 0xad, 0x80, 0x2f, 0x40, 0x0b, + 0x50, 0x02, 0x14, 0x00, 0xad, 0x00, 0x2f, 0x40, + 0x08, 0xd2, 0x02, 0x64, 0x40, 0x89, 0x00, 0x22, + 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, + 0x22, 0x40, 0x0a, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x06, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, + 0x00, 0xb5, 0x80, 0x2d, 0x60, 0x08, 0x58, 0x0a, + 0x16, 0x00, 0xa5, 0x80, 0x61, 0x40, 0x0b, 0x50, + 0x42, 0x54, 0x00, 0xa5, 0x00, 0x2d, 0x40, 0x0b, + 0x58, 0x02, 0x16, 0x00, 0x85, 0x00, 0x2d, 0x40, + 0x0a, 0x50, 0x02, 0xc4, 0x00, 0xa1, 0x00, 0x28, + 0x50, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x40, + 0x28, 0x4a, 0x08, 0x14, 0x02, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x50, 0x0b, 0x14, 0x0a, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, + 0x00, 0xf8, 0x50, 0x3e, 0x14, 0x0d, 0x85, 0x03, + 0x01, 0x42, 0xe8, 0x50, 0xb2, 0x80, 0x0f, 0xed, + 0x09, 0x00, 0x4d, 0x00, 0x80, 0x03, 0xe0, 0x00, + 0xe8, 0x00, 0x3e, 0x00, 0x0f, 0x85, 0x0b, 0x21, + 0x42, 0xe8, 0x00, 0x3e, 0x00, 0x0c, 0xc0, 0x03, + 0x41, 0x40, 0xc8, 0x00, 0x32, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x32, 0x08, 0x0e, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0x2e, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x98, 0x1d, 0xec, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xd9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc4, 0x00, + 0x19, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe5, 0x00, 0xf9, 0x42, 0x3d, 0x40, 0x0f, 0x90, + 0x43, 0xe4, 0x00, 0xd9, 0x40, 0x3e, 0x4a, 0x0f, + 0x90, 0x03, 0xe4, 0x08, 0xf9, 0x00, 0x3f, 0x50, + 0x0f, 0xd4, 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x05, 0xe4, 0x00, 0xed, 0x10, + 0x33, 0x40, 0x0f, 0xd0, 0x03, 0x34, 0x40, 0xcd, + 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0x24, 0x18, + 0xd1, 0x00, 0x32, 0xc0, 0x0d, 0xd0, 0x13, 0x34, + 0x00, 0xcb, 0x00, 0x3c, 0x40, 0x0f, 0x90, 0x03, + 0xf4, 0x80, 0xcd, 0x28, 0x33, 0x44, 0x0f, 0x90, + 0x03, 0xe4, 0x01, 0xf9, 0x10, 0x3e, 0x4a, 0x0c, + 0x90, 0x03, 0xe4, 0x00, 0xe9, 0x00, 0x3f, 0x40, + 0x0f, 0xd1, 0x03, 0x06, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x10, 0xe0, 0x00, 0x88, 0x20, + 0x22, 0x02, 0x08, 0x80, 0x82, 0x20, 0x00, 0xa8, + 0x28, 0x2e, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, + 0xb8, 0x00, 0xa3, 0x00, 0x09, 0x82, 0x82, 0x20, + 0x80, 0x88, 0x01, 0x2e, 0x00, 0x0b, 0xc0, 0x12, + 0xe0, 0x80, 0xd8, 0x01, 0x36, 0x08, 0x0b, 0x80, + 0x02, 0xe0, 0x00, 0xb8, 0x10, 0x2e, 0x08, 0x08, + 0x82, 0x02, 0xed, 0x09, 0x00, 0x4e, 0x00, 0xe0, + 0x00, 0xb8, 0x00, 0x2e, 0x02, 0x0b, 0x01, 0x02, + 0x0e, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x05, 0xe4, 0x00, 0xa1, 0x20, 0x20, 0x48, 0x0a, + 0x10, 0x12, 0x04, 0x0c, 0x01, 0x20, 0x2c, 0x60, + 0x08, 0x50, 0x42, 0xd4, 0x08, 0xbd, 0x00, 0x21, + 0x40, 0x09, 0x12, 0x02, 0x04, 0xa0, 0x81, 0x00, + 0x2c, 0x60, 0x09, 0x50, 0x02, 0xc4, 0xe0, 0x83, + 0x00, 0x20, 0xc8, 0x8b, 0x10, 0x02, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x4a, 0x09, 0x12, 0x82, 0xc4, + 0x00, 0xb1, 0x00, 0x2c, 0x44, 0x0b, 0x10, 0x02, + 0x02, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x15, 0xa4, 0x00, 0x89, 0x04, 0x20, 0x40, 0x08, + 0x92, 0x00, 0x24, 0x00, 0x89, 0x00, 0x0e, 0x40, + 0x28, 0xd8, 0x0a, 0xf4, 0x00, 0xbd, 0x00, 0x23, + 0x40, 0x09, 0x90, 0x02, 0x24, 0x00, 0x89, 0x00, + 0x0e, 0x40, 0x0b, 0xd0, 0x02, 0xe4, 0x04, 0x99, + 0x00, 0xe2, 0x60, 0x0b, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x09, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x94, 0x02, + 0x06, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x15, 0xe4, 0x00, 0xe9, 0x00, 0xb2, 0x40, 0x0f, + 0x90, 0x0b, 0x24, 0x02, 0x89, 0x00, 0x3c, 0x40, + 0x0c, 0x10, 0x03, 0xe4, 0x00, 0xd9, 0x80, 0x32, + 0x40, 0x0d, 0x90, 0x0b, 0x24, 0x02, 0xc9, 0x00, + 0x3e, 0x40, 0x0f, 0x98, 0x03, 0xe4, 0x00, 0xc1, + 0x01, 0x22, 0x40, 0x0b, 0x90, 0x03, 0xe4, 0x00, + 0xb9, 0x00, 0x3e, 0x40, 0x2d, 0x90, 0x03, 0xe4, + 0x00, 0xe9, 0x00, 0x3e, 0x42, 0x0f, 0x90, 0x0b, + 0x28, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0x24, 0x00, 0xed, 0x09, 0x00, + 0x4f, 0x00, 0xf9, 0xa0, 0x3e, 0x41, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x01, 0x3e, 0x40, 0x0f, + 0x94, 0x03, 0xe4, 0x00, 0xb9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x0e, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x46, 0x0f, 0x11, 0x03, 0xca, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0e, 0x80, 0x03, 0x20, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0x22, 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, + 0xc2, 0x03, 0xc0, 0x00, 0xf8, 0x80, 0xb6, 0x20, + 0x0e, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x04, 0x32, + 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x0a, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x08, 0x00, + 0xbe, 0x02, 0x2f, 0x80, 0x0e, 0xe0, 0x0a, 0x38, + 0x00, 0xbe, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x0a, + 0x28, 0x00, 0xb2, 0x00, 0xa2, 0xa2, 0x03, 0xe2, + 0x02, 0xf8, 0x80, 0xba, 0x00, 0x2e, 0x80, 0x0a, + 0xa0, 0x02, 0xf8, 0x00, 0xbe, 0x00, 0x23, 0x80, + 0x0f, 0xa0, 0x03, 0xa8, 0x00, 0xba, 0x00, 0xa2, + 0x80, 0x08, 0xa0, 0x02, 0xe8, 0x10, 0xba, 0x00, + 0x2f, 0x90, 0x0b, 0xe0, 0x02, 0x8a, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, 0x00, + 0xb8, 0x00, 0x2c, 0x00, 0x0b, 0x80, 0x02, 0xa0, + 0x00, 0xb0, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x00, + 0x0c, 0x00, 0xa3, 0x00, 0x20, 0xc0, 0x0b, 0x82, + 0x02, 0xe0, 0x80, 0xb3, 0x00, 0x2c, 0x00, 0x08, + 0x29, 0x02, 0xc1, 0x20, 0xb2, 0x00, 0x28, 0xc0, + 0x8b, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x22, + 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0xed, 0x09, 0x00, 0x50, 0x00, 0x2c, 0xd0, 0x0b, + 0x38, 0x02, 0x0a, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x01, 0x1c, 0x00, 0xb4, 0x00, 0x2d, + 0x00, 0x0b, 0x40, 0x12, 0x90, 0x00, 0xb4, 0x00, + 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0x1c, 0x00, 0xbe, + 0x00, 0x21, 0x80, 0x0b, 0x40, 0x12, 0xd0, 0x00, + 0xb7, 0x00, 0x2d, 0x20, 0x0a, 0x60, 0x02, 0x58, + 0x04, 0x34, 0x00, 0x29, 0x40, 0x0b, 0x70, 0x02, + 0x9c, 0x00, 0xb3, 0xa0, 0x20, 0xc4, 0x08, 0x72, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x74, 0x02, 0xa8, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xf4, 0x80, 0x3d, + 0xa0, 0x0f, 0xe8, 0x03, 0x92, 0x00, 0xf4, 0x80, + 0x3d, 0xa0, 0x9f, 0x78, 0x13, 0x1e, 0x10, 0xf5, + 0x80, 0x31, 0xe0, 0x0f, 0x48, 0x03, 0xd2, 0x00, + 0xb7, 0x80, 0x2d, 0x20, 0x0c, 0x68, 0x03, 0xd2, + 0x00, 0x77, 0x80, 0x39, 0xe0, 0x0e, 0x78, 0x03, + 0x9e, 0x00, 0xf7, 0xe0, 0x31, 0xe8, 0x2c, 0x7a, + 0x03, 0xde, 0x00, 0xf7, 0x80, 0x2d, 0xe0, 0x0f, + 0x68, 0x0b, 0x2a, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x1d, 0xac, 0x00, 0xfc, 0x00, 0x2f, + 0x00, 0x0e, 0xc0, 0x03, 0x70, 0x00, 0xfc, 0x00, + 0x3e, 0x80, 0x0f, 0x10, 0x02, 0xec, 0x00, 0xf8, + 0x00, 0x3e, 0x80, 0x0f, 0xc0, 0x03, 0xf0, 0x00, + 0xfb, 0x00, 0x3e, 0x00, 0x0f, 0xa0, 0x43, 0xf0, + 0x00, 0xf1, 0x00, 0x32, 0xc0, 0x0e, 0xb0, 0x03, + 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb6, + 0x83, 0xec, 0x00, 0xfb, 0x04, 0x3e, 0x40, 0x0f, + 0x80, 0x03, 0x42, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xfe, 0x00, 0xfc, 0x80, 0x3f, + 0x20, 0x0f, 0xc8, 0x03, 0xf2, 0x00, 0xec, 0x80, + 0x33, 0xe0, 0x0c, 0xf0, 0x03, 0x1a, 0x00, 0xcf, + 0x80, 0x3d, 0x60, 0xed, 0x09, 0x00, 0x51, 0x00, + 0x0c, 0xf8, 0x03, 0xfe, 0x00, 0xcf, 0x80, 0x3d, + 0x20, 0x0c, 0x78, 0x03, 0xb6, 0x00, 0xcf, 0x80, + 0x33, 0xa0, 0x0c, 0xf8, 0x03, 0xfe, 0x00, 0xff, + 0x80, 0x1f, 0xe0, 0x0d, 0xf8, 0x83, 0x3e, 0x00, + 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xd8, 0x23, 0xc0, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, + 0x9c, 0x00, 0xb4, 0x40, 0x2d, 0x04, 0x0b, 0x40, + 0x02, 0xf0, 0x00, 0x84, 0x00, 0x21, 0xc0, 0x88, + 0x50, 0x02, 0x18, 0x40, 0x96, 0x00, 0x2d, 0x00, + 0x48, 0x50, 0x02, 0xf4, 0x00, 0xd7, 0x11, 0x2d, + 0x00, 0x0d, 0x74, 0x03, 0xf8, 0x00, 0x87, 0x11, + 0x21, 0x40, 0x08, 0x70, 0x03, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x08, 0xf0, 0x03, 0x5c, 0x00, + 0xb7, 0x01, 0x2d, 0x80, 0x0b, 0x70, 0x02, 0xea, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x00, 0xb4, 0x00, 0x2d, 0x80, 0x0b, 0x60, + 0x02, 0xd0, 0x00, 0xa4, 0x00, 0x2b, 0x80, 0x08, + 0xf4, 0x02, 0x18, 0x00, 0x95, 0x00, 0x25, 0x40, + 0x28, 0x60, 0x02, 0xd8, 0x00, 0xa7, 0x00, 0x2f, + 0x00, 0x08, 0x79, 0x02, 0x14, 0x00, 0x97, 0x00, + 0x21, 0x80, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x25, 0xc0, 0x09, 0x70, 0x02, 0x1c, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x40, 0x02, 0xc0, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, + 0xcc, 0x00, 0xb0, 0x00, 0x2c, 0x00, 0x0b, 0x00, + 0x02, 0xc0, 0x00, 0x80, 0x00, 0x28, 0x80, 0x08, + 0x10, 0x02, 0x09, 0x20, 0x90, 0x24, 0x2c, 0x00, + 0x08, 0x00, 0x02, 0xc0, 0x05, 0xa3, 0x00, 0x2c, + 0x00, 0x08, 0x30, 0x02, 0xc0, 0x00, 0x93, 0x04, + 0x20, 0xd2, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x01, 0x2c, 0xc0, 0x18, 0x30, 0x02, 0x4c, 0x00, + 0xb3, 0x00, 0x2c, 0x2c, 0x0b, 0x04, 0xed, 0x09, + 0x00, 0x52, 0x00, 0x82, 0xc8, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x15, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xec, 0x00, + 0xeb, 0x00, 0x38, 0xc0, 0x04, 0xa0, 0x03, 0x26, + 0x80, 0x8b, 0x40, 0x36, 0xc0, 0x0c, 0x80, 0x02, + 0xe0, 0x00, 0xab, 0x00, 0x3e, 0x00, 0x08, 0xb0, + 0x02, 0xa0, 0x00, 0xd9, 0x00, 0x30, 0xc0, 0x0c, + 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0d, 0xf0, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, + 0x30, 0x0f, 0xb4, 0x03, 0xea, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, 0xfd, + 0x40, 0x3f, 0x50, 0x4f, 0xd4, 0x03, 0xf5, 0x00, + 0xfd, 0x40, 0x96, 0xe0, 0x0f, 0x84, 0x03, 0xe4, + 0x08, 0xea, 0x00, 0x3e, 0x80, 0x0f, 0xc0, 0x03, + 0xf0, 0x00, 0xdb, 0x00, 0x3e, 0x20, 0x0f, 0xb0, + 0x02, 0x78, 0x00, 0xeb, 0x00, 0x3e, 0x60, 0x0f, + 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0x40, 0x0f, 0xa4, 0x03, 0xe0, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, 0xfe, + 0x80, 0x3f, 0x80, 0x0f, 0xe0, 0x03, 0x3a, 0x00, + 0xfe, 0x80, 0x3f, 0x80, 0x0c, 0xe0, 0x03, 0xf4, + 0x00, 0xfd, 0x00, 0x3f, 0xc0, 0x2c, 0xc0, 0x03, + 0x30, 0x00, 0xcf, 0x00, 0x37, 0x00, 0x0c, 0xd2, + 0x03, 0x30, 0x10, 0xcd, 0x00, 0x33, 0x80, 0x0c, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3e, 0xc0, + 0x0f, 0xf0, 0x03, 0x3c, 0x00, 0xff, 0x01, 0x3f, + 0x80, 0x0c, 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, 0xb8, + 0x00, 0x2e, 0x00, 0xcb, 0x80, 0x0a, 0x20, 0x00, + 0xb8, 0x00, 0x2e, 0x80, 0x08, 0x80, 0x02, 0x64, + 0x10, 0xb8, 0x00, 0x2c, 0x80, 0x08, 0x80, 0x0b, + 0x20, 0xed, 0x09, 0x00, 0x53, 0x00, 0x00, 0xc3, + 0x01, 0x20, 0x00, 0x08, 0x18, 0x02, 0xa0, 0x00, + 0x83, 0x04, 0x22, 0x80, 0x08, 0xb0, 0x02, 0xec, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xac, 0x00, 0xbb, 0x00, 0x2e, 0x7c, 0x08, 0x84, + 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x05, 0x2c, 0x00, 0xbb, 0x10, 0x2e, 0x50, + 0x0b, 0x14, 0x02, 0x2d, 0x80, 0xbb, 0x60, 0x2e, + 0xc0, 0x08, 0xa0, 0x82, 0xe2, 0x01, 0xbb, 0x02, + 0x6e, 0x40, 0x08, 0x30, 0x02, 0x0c, 0x00, 0xab, + 0x00, 0x26, 0x00, 0x0a, 0x90, 0x02, 0x04, 0x00, + 0x8b, 0x80, 0x22, 0xa0, 0x0a, 0xb0, 0x02, 0xec, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x30, 0x02, + 0x2c, 0x00, 0xbb, 0x00, 0x2c, 0x00, 0x08, 0x94, + 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x0c, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0x04, 0x10, 0xb1, 0x00, 0x2e, + 0xc0, 0x08, 0x00, 0x02, 0x40, 0x00, 0xb2, 0x00, + 0x6c, 0x00, 0x08, 0x10, 0x02, 0x44, 0x00, 0xa3, + 0x00, 0x22, 0x00, 0x08, 0x10, 0x02, 0x88, 0x00, + 0x83, 0x80, 0x22, 0x20, 0x0a, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x4b, 0x30, 0x02, + 0x8c, 0x00, 0xb3, 0x00, 0x2c, 0x00, 0x08, 0x20, + 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x6c, 0x00, 0xfa, 0x00, 0x3e, 0x80, + 0x0f, 0xa0, 0x03, 0x28, 0x00, 0xf2, 0x00, 0x2e, + 0x80, 0x88, 0xa0, 0x03, 0xe0, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0c, 0xa0, 0x03, 0x28, 0x00, 0xeb, + 0x00, 0x36, 0x00, 0x8c, 0x90, 0x03, 0x24, 0x00, + 0xcb, 0x00, 0x32, 0x40, 0x0e, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xf0, 0x03, + 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0x80, 0x2c, 0x90, + 0x03, 0xc0, 0x03, 0x50, 0xed, 0x09, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, + 0xf0, 0x00, 0xfc, 0x00, 0x3d, 0x80, 0x0f, 0x40, + 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, + 0xc0, 0x03, 0xb0, 0x00, 0xcf, 0x00, 0x3f, 0x00, + 0x0f, 0xd0, 0x03, 0xf0, 0x00, 0xf7, 0x00, 0x3d, + 0x40, 0x0d, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x08, 0xff, + 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0xe8, 0x02, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x05, 0xfc, + 0x00, 0xff, 0x20, 0x3b, 0xc0, 0x0f, 0xd1, 0x03, + 0xf8, 0x00, 0xff, 0x00, 0x33, 0xc0, 0x0d, 0xf1, + 0x03, 0xfc, 0x00, 0xdf, 0x0a, 0x3f, 0x00, 0x8e, + 0xc0, 0x01, 0xf0, 0xc0, 0xfc, 0x30, 0x33, 0x04, + 0x8f, 0xc0, 0x03, 0xdc, 0xa0, 0xfc, 0x30, 0x23, + 0xd0, 0x0c, 0xf0, 0x03, 0x70, 0x08, 0xcc, 0x40, + 0x3f, 0xcc, 0x0f, 0xd0, 0x23, 0xf0, 0x02, 0xcc, + 0x10, 0x3d, 0xca, 0x0c, 0xf0, 0x03, 0xf0, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0xec, + 0x08, 0xbb, 0x50, 0x22, 0xc0, 0x0b, 0xb2, 0x02, + 0xe8, 0x00, 0xbf, 0x40, 0xa3, 0xd4, 0x00, 0xb0, + 0x02, 0xfd, 0x00, 0xdb, 0x00, 0x2e, 0x00, 0x08, + 0xa0, 0x00, 0xe0, 0x80, 0xb0, 0x02, 0x22, 0x00, + 0x0b, 0x84, 0x02, 0xed, 0x04, 0xb8, 0x70, 0x2a, + 0x80, 0x0a, 0xb0, 0x12, 0xac, 0x00, 0xa8, 0x20, + 0x2e, 0xd4, 0x0b, 0x84, 0x82, 0xe1, 0x20, 0x88, + 0x22, 0x2e, 0xd0, 0x08, 0xb0, 0x02, 0xe0, 0x06, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, + 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x0b, 0x10, 0x02, + 0xc8, 0x00, 0xb3, 0x40, 0x20, 0xc0, 0x41, 0x32, + 0x02, 0xcd, 0x00, 0xa2, 0x00, 0x2c, 0x80, 0x0a, + 0x10, 0x46, 0x80, 0xc0, 0xb0, 0x61, 0xa0, 0xed, + 0x09, 0x00, 0x55, 0x00, 0x18, 0x8b, 0x01, 0x02, + 0xcc, 0x00, 0x90, 0x00, 0x22, 0xc8, 0x08, 0xb0, + 0x02, 0x6c, 0x00, 0xa0, 0x40, 0x2c, 0xc8, 0x0b, + 0x13, 0x02, 0xe1, 0x80, 0x90, 0x00, 0x6c, 0xc0, + 0x08, 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x15, 0xac, 0x00, 0xbb, 0x00, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xe9, 0x00, 0xbb, + 0x00, 0x22, 0xc0, 0x08, 0xb0, 0x82, 0xec, 0x00, + 0xbb, 0x80, 0x2e, 0xa0, 0x08, 0xb8, 0x02, 0xe2, + 0x00, 0x99, 0x80, 0x22, 0x22, 0x1b, 0x88, 0x02, + 0xec, 0x00, 0xb8, 0x80, 0x2a, 0x84, 0x0a, 0x90, + 0x22, 0xac, 0x24, 0xa8, 0x80, 0x2e, 0xc0, 0x0b, + 0x98, 0x02, 0xe8, 0xa0, 0x9a, 0x15, 0x2e, 0xc0, + 0x08, 0xb0, 0x02, 0xf0, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x15, 0xec, 0x00, 0xfb, 0x00, + 0x3a, 0xc0, 0x0f, 0xb8, 0x03, 0xef, 0x00, 0xfb, + 0x01, 0x32, 0xc0, 0x8d, 0xb0, 0x03, 0xec, 0x00, + 0xeb, 0x80, 0x3e, 0xb0, 0x0e, 0xa8, 0x03, 0xa3, + 0x80, 0xf8, 0x83, 0x32, 0x20, 0x0f, 0x8c, 0x23, + 0xec, 0x00, 0xf8, 0xc8, 0x32, 0xc0, 0x0c, 0x38, + 0x11, 0x4e, 0x00, 0xe8, 0xc0, 0x3e, 0xc0, 0x8f, + 0x98, 0x03, 0xeb, 0x00, 0xda, 0xc8, 0x3e, 0xc0, + 0x2c, 0xb0, 0x03, 0xd0, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x01, 0xbc, 0x00, 0xf7, 0x00, + 0x3f, 0xc0, 0x0f, 0xdc, 0x03, 0xf2, 0x40, 0xf7, + 0x00, 0x3d, 0xc0, 0x8f, 0xe9, 0x03, 0xfc, 0x00, + 0xdf, 0x00, 0x3c, 0x80, 0x0f, 0xe0, 0x23, 0xf0, + 0x00, 0xf5, 0x00, 0x3f, 0x40, 0x0b, 0xd0, 0x03, + 0xfc, 0x20, 0x7d, 0x00, 0x3f, 0x61, 0x0f, 0xdc, + 0x13, 0x77, 0x04, 0x9c, 0x00, 0x3e, 0xc1, 0x0f, + 0xc0, 0x03, 0xf8, 0x00, 0xef, 0x80, 0x3d, 0xc0, + 0x0d, 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x56, 0x00, 0x40, + 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xe8, 0x00, 0xdb, 0x10, 0x3e, 0xc0, + 0x0f, 0x94, 0x03, 0xac, 0x00, 0xcb, 0xa0, 0x3a, + 0x90, 0x2e, 0xb0, 0x03, 0x20, 0x10, 0xf8, 0x44, + 0x3a, 0x50, 0x0e, 0x90, 0x03, 0xec, 0x00, 0xc9, + 0x40, 0x36, 0xc0, 0x0c, 0xb2, 0x43, 0x29, 0x00, + 0xc8, 0x04, 0x3e, 0xc0, 0x0c, 0x90, 0x83, 0x29, + 0x0c, 0xfb, 0x00, 0x3e, 0xc1, 0x0c, 0xb0, 0x03, + 0xd0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0x05, 0x2c, 0x00, 0xbf, 0x00, 0x2e, 0xc0, 0x0b, + 0x90, 0x02, 0xeb, 0x00, 0x8f, 0xc0, 0x2f, 0xc0, + 0x0b, 0xb0, 0x02, 0x1e, 0x82, 0x8b, 0xc4, 0x02, + 0x80, 0x08, 0xa4, 0x02, 0x20, 0x00, 0xb9, 0x00, + 0x2a, 0x40, 0x1b, 0x92, 0x02, 0xfc, 0x00, 0x89, + 0xc0, 0x2c, 0xc0, 0x0a, 0x9c, 0x03, 0x6e, 0x00, + 0x89, 0x02, 0x2f, 0xc0, 0x0d, 0x94, 0x02, 0x88, + 0x00, 0xbb, 0x00, 0x2f, 0xd0, 0x08, 0xb0, 0x02, + 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcb, 0x24, 0xb3, 0xa0, 0x24, 0xc0, + 0x09, 0x30, 0x02, 0x8e, 0x00, 0x81, 0x00, 0x20, + 0xe8, 0x08, 0x22, 0x02, 0x40, 0x00, 0xb0, 0x00, + 0x20, 0x00, 0x0a, 0x0e, 0x02, 0x8d, 0x00, 0x88, + 0xf0, 0x6c, 0xc1, 0x08, 0x3d, 0x02, 0x8d, 0x80, + 0x20, 0x01, 0x2c, 0xc0, 0x08, 0x08, 0x02, 0x08, + 0x00, 0xb0, 0x00, 0x2c, 0xc8, 0x08, 0x30, 0x02, + 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x02, 0xfa, 0x20, 0x87, 0x80, 0x2d, 0xe0, + 0x0b, 0x71, 0x02, 0x0e, 0x00, 0x97, 0x80, 0x25, + 0xe4, 0x08, 0x68, 0x02, 0x12, 0x08, 0xb4, 0x80, + 0x29, 0xe4, 0x0b, 0x58, 0x02, 0xed, 0x09, 0x00, + 0x57, 0x00, 0xde, 0x20, 0x07, 0x80, 0x2d, 0xe0, + 0x0a, 0x78, 0x06, 0xfa, 0x20, 0x84, 0x80, 0x2d, + 0xec, 0x09, 0x68, 0x02, 0x9a, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x08, 0x78, 0x02, 0xc8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x0c, 0x00, + 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xc8, + 0x00, 0xf3, 0x10, 0x3c, 0xc0, 0x0f, 0xb1, 0x03, + 0x8c, 0x40, 0xc8, 0x00, 0xb0, 0xd7, 0x1e, 0xb0, + 0x03, 0x4c, 0x00, 0xf3, 0x40, 0x20, 0xc0, 0x0e, + 0x34, 0x03, 0xcc, 0x58, 0x83, 0x00, 0x36, 0xd0, + 0x0c, 0x11, 0x43, 0x84, 0x80, 0xe0, 0x40, 0x3c, + 0xc8, 0x1c, 0xa0, 0x8b, 0x04, 0x80, 0xf1, 0x04, + 0x3c, 0xc0, 0x2c, 0x30, 0x03, 0xd2, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, + 0xff, 0x02, 0x3f, 0xc0, 0x8f, 0xf0, 0x03, 0xd8, + 0x40, 0xff, 0x44, 0x3f, 0xd4, 0x0f, 0xf0, 0x03, + 0xfc, 0x40, 0xef, 0x10, 0x3b, 0xc4, 0x0f, 0xf1, + 0x23, 0xbc, 0x04, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x10, 0x7f, 0x00, 0x27, 0xc0, + 0x0f, 0x50, 0x03, 0x5c, 0x08, 0xfd, 0x12, 0x3f, + 0xc9, 0x0f, 0xe1, 0x01, 0x7c, 0x00, 0xff, 0x10, + 0x3f, 0xc6, 0x0f, 0xf0, 0x03, 0xd0, 0x06, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc4, 0x0f, 0xb0, 0x03, + 0xec, 0x80, 0xf1, 0x00, 0xb2, 0xe0, 0x0c, 0xa0, + 0x07, 0x6c, 0x00, 0xfb, 0x02, 0x3a, 0x00, 0x2c, + 0x28, 0x03, 0x2c, 0x40, 0xfa, 0x00, 0x16, 0xe0, + 0x0c, 0x90, 0x03, 0xce, 0x00, 0xc8, 0x00, 0x22, + 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x00, 0xc2, 0x00, + 0x12, 0xc0, 0x0f, 0xb0, 0x03, 0xea, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, 0x00, + 0xed, 0x09, 0x00, 0x58, 0x00, 0xb7, 0x40, 0x2d, + 0xc0, 0x0b, 0x70, 0x20, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc8, 0x0b, 0x70, 0x22, 0xdd, 0xa0, 0xb7, + 0x00, 0x29, 0x80, 0x48, 0x60, 0x02, 0xdc, 0x00, + 0xb7, 0x05, 0x6d, 0xc0, 0x08, 0x70, 0x03, 0x5c, + 0x00, 0xb7, 0x00, 0x3d, 0xc1, 0x0d, 0x50, 0x02, + 0xdc, 0x00, 0xa6, 0x04, 0x2b, 0xc0, 0x0a, 0x70, + 0x42, 0xfc, 0x00, 0x87, 0x00, 0x29, 0xc8, 0x0b, + 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x00, 0x9e, 0x00, 0xb7, 0xa0, 0x2d, + 0xe0, 0x4b, 0x78, 0x30, 0xda, 0x04, 0xb7, 0x90, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x80, 0xbd, + 0x80, 0x20, 0xe0, 0x08, 0x78, 0x02, 0xde, 0x00, + 0xb7, 0x81, 0x2d, 0xe0, 0x00, 0x78, 0x82, 0x1e, + 0x80, 0x37, 0x80, 0x2d, 0xe0, 0x09, 0x5c, 0x02, + 0xde, 0x20, 0x80, 0x80, 0x61, 0xe4, 0x08, 0x7c, + 0x06, 0xde, 0x22, 0x8f, 0x80, 0x21, 0xe8, 0x0b, + 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0xb8, 0x02, 0x48, 0x80, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x3e, 0x02, 0xcc, 0x00, 0xb3, + 0x08, 0x28, 0xf0, 0x08, 0xbc, 0x02, 0xee, 0x80, + 0xb3, 0x10, 0x2c, 0xd0, 0x08, 0x38, 0x02, 0x4c, + 0x01, 0xb3, 0x90, 0x28, 0xc4, 0x49, 0x10, 0x02, + 0xc2, 0x20, 0xab, 0x42, 0x28, 0xc0, 0x0a, 0x3c, + 0x02, 0xcd, 0x08, 0x8b, 0xc2, 0x28, 0xc0, 0x0b, + 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, + 0x80, 0x0f, 0xaa, 0x03, 0xf8, 0x80, 0xfa, 0x00, + 0x3e, 0x80, 0x0f, 0xee, 0x03, 0xe8, 0x00, 0xfe, + 0x40, 0x33, 0x94, 0x0c, 0xe5, 0x03, 0x78, 0x10, + 0xfe, 0x10, 0x3f, 0x80, 0x0c, 0xe1, 0x23, 0x28, + 0x08, 0xfe, 0x10, 0xed, 0x09, 0x00, 0x59, 0x00, + 0x27, 0x90, 0x0d, 0xa8, 0x03, 0xf9, 0x00, 0xce, + 0x00, 0x32, 0x80, 0x0c, 0xe0, 0x03, 0xfb, 0x00, + 0xce, 0x80, 0x32, 0x80, 0x0f, 0xa0, 0x03, 0xfa, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xe1, 0x00, 0xf0, 0x40, 0x3e, 0x00, 0x0f, + 0x80, 0x13, 0xe0, 0x00, 0xb8, 0x40, 0x3e, 0x14, + 0x2f, 0x85, 0x01, 0xe0, 0x40, 0xf8, 0x00, 0x3e, + 0x08, 0x0f, 0x80, 0x03, 0xe0, 0x10, 0xf8, 0x00, + 0x36, 0x20, 0x0f, 0x84, 0x03, 0xe0, 0x00, 0xf8, + 0x20, 0x3e, 0x00, 0x0f, 0x80, 0x83, 0xe0, 0x20, + 0xf8, 0x32, 0x3e, 0x00, 0x4f, 0x80, 0x03, 0xd2, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0x06, 0x00, 0xc9, 0x20, 0x32, 0x40, 0x8f, + 0x90, 0x03, 0xa5, 0x04, 0xd9, 0x80, 0x32, 0x50, + 0x4f, 0x98, 0x23, 0x24, 0x00, 0xc9, 0x00, 0x3c, + 0x40, 0x06, 0x90, 0x07, 0xe6, 0x00, 0xf9, 0x10, + 0x3e, 0x40, 0x0f, 0x9c, 0x03, 0xa6, 0x44, 0x79, + 0x01, 0x30, 0x40, 0x8c, 0x90, 0x03, 0xc4, 0x02, + 0xc9, 0x00, 0x30, 0x60, 0x0c, 0x90, 0x03, 0xc2, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, + 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0x27, 0x00, 0xd9, 0x40, 0xa2, 0x40, 0x89, + 0x90, 0x22, 0x24, 0x00, 0xb9, 0xf0, 0x22, 0x40, + 0x0b, 0x90, 0x02, 0x24, 0x00, 0x89, 0x00, 0x2e, + 0x40, 0x0a, 0x90, 0x02, 0xe6, 0xc0, 0xb9, 0x80, + 0x0e, 0x40, 0x0b, 0x14, 0x02, 0x26, 0x20, 0xb9, + 0x00, 0x32, 0x40, 0x0a, 0x9a, 0x02, 0xe4, 0x00, + 0x89, 0x00, 0x22, 0x40, 0x08, 0x90, 0x02, 0xe0, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, + 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0xed, 0x09, + 0x00, 0x5a, 0x00, 0x0b, 0x90, 0x02, 0x24, 0x40, + 0x89, 0x40, 0x22, 0x40, 0x0b, 0x10, 0x02, 0xe4, + 0x00, 0xb1, 0x00, 0x22, 0x40, 0x0b, 0xb1, 0x02, + 0x24, 0x00, 0x89, 0x00, 0x2e, 0x40, 0x00, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x8b, + 0x90, 0x92, 0xe4, 0x04, 0xb9, 0x00, 0x22, 0x40, + 0x08, 0xb2, 0x42, 0xe4, 0x08, 0x89, 0x00, 0x22, + 0x54, 0x08, 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, 0xb1, + 0x28, 0x6c, 0x40, 0x0b, 0x10, 0x02, 0x84, 0xa0, + 0x91, 0x28, 0x20, 0x4a, 0x09, 0x12, 0x82, 0x44, + 0xa0, 0xb1, 0x28, 0xa0, 0xd0, 0x0b, 0x34, 0x0a, + 0x85, 0x02, 0x81, 0x2a, 0x2c, 0x4a, 0x0a, 0x12, + 0x92, 0xc4, 0xa0, 0xb1, 0x28, 0x24, 0x51, 0x0b, + 0x90, 0x02, 0x44, 0x00, 0xb1, 0x40, 0xa0, 0x50, + 0x8a, 0x14, 0x02, 0xc5, 0x00, 0x81, 0x40, 0xa0, + 0x40, 0x28, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, 0x00, 0xf8, + 0x20, 0x3e, 0x00, 0x0f, 0x80, 0x0b, 0x28, 0x80, + 0xc8, 0x20, 0x32, 0x08, 0x0f, 0x82, 0x43, 0xe0, + 0x84, 0xd8, 0x20, 0x32, 0x00, 0x0f, 0x80, 0x43, + 0x20, 0x00, 0xc8, 0x20, 0x3c, 0x08, 0x0c, 0x82, + 0x02, 0xe0, 0x80, 0xfa, 0x21, 0x3c, 0x00, 0x8f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x32, 0x00, + 0x0c, 0x80, 0x01, 0xe0, 0x00, 0xc8, 0x00, 0x32, + 0x00, 0x0c, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x1d, 0xe4, 0x10, 0xb9, + 0x00, 0x3e, 0x40, 0x0f, 0xd2, 0xa3, 0x74, 0xa0, + 0xf9, 0x28, 0x3e, 0x40, 0x05, 0xd2, 0x83, 0xa4, + 0x00, 0xff, 0x28, 0x3f, 0x51, 0x0f, 0xd4, 0x03, + 0x75, 0x00, 0xff, 0x2c, 0x3f, 0x4b, 0x25, 0xd0, + 0x03, 0xe4, 0x00, 0xfd, 0x28, 0x3f, 0x40, 0x0b, + 0xd0, 0xed, 0x09, 0x00, 0x5b, 0x00, 0x13, 0xb4, + 0x00, 0xfd, 0x44, 0x3a, 0x50, 0x9b, 0xd4, 0x13, + 0xf5, 0x04, 0xfd, 0x03, 0x3e, 0x50, 0x0f, 0x90, + 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0xe4, 0x00, 0xf9, 0x20, 0x36, 0x40, + 0x0d, 0x90, 0x03, 0xf4, 0x40, 0xcd, 0x20, 0x3e, + 0x4a, 0x0d, 0x93, 0x03, 0xf4, 0x00, 0xfd, 0x00, + 0x3f, 0x48, 0x0e, 0xd2, 0x93, 0xa4, 0xe0, 0xb9, + 0x30, 0x3e, 0x40, 0x0d, 0xd0, 0x03, 0x34, 0x00, + 0xdd, 0x20, 0x2e, 0x45, 0x0f, 0x50, 0x03, 0x74, + 0x00, 0xfb, 0x30, 0x3e, 0x48, 0x0f, 0xd2, 0xd3, + 0xe4, 0xc0, 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0x90, + 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x10, 0xe0, 0x00, 0xb8, 0x10, 0x2e, 0x00, + 0x0b, 0x80, 0x82, 0xe0, 0x40, 0x88, 0x28, 0x2e, + 0x00, 0x88, 0x83, 0x12, 0xe1, 0x00, 0xb8, 0x08, + 0x2e, 0x0a, 0x08, 0x82, 0x02, 0x20, 0x80, 0x98, + 0x30, 0x2e, 0x12, 0x0b, 0x80, 0x02, 0xa0, 0x50, + 0xf8, 0x28, 0x6e, 0x08, 0x8b, 0x80, 0x02, 0x20, + 0x00, 0xe8, 0x00, 0x2c, 0x0a, 0x0b, 0xa2, 0x02, + 0xe0, 0xc4, 0xb8, 0x08, 0x2e, 0x00, 0x0b, 0x80, + 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x24, 0x40, + 0x08, 0x10, 0x02, 0xc4, 0x08, 0x83, 0x30, 0x2c, + 0x40, 0x09, 0x1a, 0x02, 0xc4, 0x40, 0xb1, 0x10, + 0x2c, 0x4c, 0x0a, 0x12, 0x82, 0x84, 0x80, 0xb1, + 0x20, 0x2c, 0x4c, 0x0b, 0x11, 0x02, 0x44, 0x00, + 0xb1, 0x30, 0x2c, 0x49, 0x4b, 0x10, 0x42, 0x44, + 0x00, 0x91, 0x90, 0x2c, 0x4c, 0x0b, 0x12, 0x82, + 0xc4, 0x80, 0xb1, 0x20, 0x2c, 0x45, 0x0b, 0x10, + 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0x65, 0xed, 0x09, 0x00, 0x5c, + 0x00, 0x80, 0x89, 0x00, 0x2e, 0x40, 0x08, 0x92, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x26, 0xd0, 0x08, + 0x90, 0x02, 0x25, 0x00, 0x99, 0x00, 0x2e, 0x46, + 0x0b, 0x95, 0x02, 0xa4, 0x04, 0xa9, 0x20, 0x2e, + 0x40, 0x0b, 0x92, 0x02, 0x24, 0x40, 0xa9, 0x00, + 0x2e, 0x40, 0x4b, 0x90, 0x00, 0xe4, 0x24, 0xb9, + 0xc0, 0x2e, 0x40, 0x8b, 0x90, 0x42, 0xc6, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe4, + 0x00, 0xf9, 0x00, 0x36, 0x40, 0x0d, 0x90, 0x03, + 0xe4, 0x02, 0xc9, 0x00, 0x3e, 0x40, 0x0d, 0x98, + 0x13, 0xe4, 0x00, 0xf9, 0x40, 0x3e, 0x50, 0x0e, + 0x92, 0x03, 0xa4, 0x40, 0xf9, 0x80, 0x3e, 0x70, + 0x07, 0x10, 0x03, 0x24, 0x00, 0xb9, 0x22, 0x6e, + 0x44, 0x0f, 0x10, 0x03, 0x65, 0x80, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x94, 0x03, 0xe6, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xc6, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x07, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x1e, 0x70, 0x2b, + 0x90, 0x83, 0xe6, 0x00, 0xd9, 0xa0, 0x3e, 0x60, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x01, 0x7e, + 0x60, 0x0f, 0x90, 0x02, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x99, 0x93, 0xe5, 0x00, 0xf9, + 0x00, 0x7e, 0x40, 0x0f, 0x90, 0x03, 0xca, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0e, 0x80, 0x03, + 0xe3, 0x00, 0xf8, 0x00, 0x3c, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x10, 0xf8, 0x90, 0x36, 0x00, 0x0c, + 0x84, 0x03, 0x60, 0x10, 0xf8, 0x00, 0x3e, 0x10, + 0x2d, 0x84, 0x03, 0xe2, 0x40, 0xf8, 0x01, 0x3a, + 0x00, 0x4e, 0x80, 0x03, 0xa0, 0x00, 0xf8, 0xed, + 0x09, 0x00, 0x5d, 0x00, 0x00, 0x3a, 0x00, 0x0c, + 0x84, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x04, + 0x0f, 0x80, 0x01, 0xca, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x01, 0x28, 0x00, 0xba, 0x00, + 0x2e, 0x80, 0x0e, 0xa0, 0x06, 0xfa, 0x00, 0xbe, + 0x00, 0x26, 0x80, 0x0b, 0xa0, 0x02, 0xea, 0x00, + 0xbe, 0x00, 0x37, 0x84, 0x18, 0xe8, 0x02, 0x28, + 0x00, 0xba, 0x00, 0x3a, 0x80, 0x08, 0xe4, 0x02, + 0xf9, 0x00, 0xde, 0x00, 0x2e, 0x80, 0x4b, 0xe9, + 0x12, 0x38, 0x60, 0xba, 0x00, 0x2e, 0x80, 0x08, + 0xe0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x3b, 0x80, + 0x0b, 0xa0, 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x05, 0x4c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x12, 0xce, 0x00, 0xb3, + 0x60, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc6, 0x00, + 0x83, 0x00, 0x22, 0xd0, 0x48, 0xbc, 0x4a, 0x4c, + 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0a, 0x38, 0xb2, + 0xc2, 0x08, 0xb3, 0x0c, 0x28, 0xc0, 0x0b, 0x2d, + 0x06, 0x88, 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x08, + 0x38, 0x02, 0xcc, 0x11, 0xb3, 0x00, 0x28, 0xc0, + 0x0b, 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x01, 0x1c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x20, 0xb7, + 0x00, 0x25, 0xc0, 0x0b, 0x72, 0x00, 0xdc, 0x20, + 0xb3, 0x84, 0x24, 0x80, 0x48, 0x34, 0x02, 0x1c, + 0xd0, 0xb7, 0x20, 0x29, 0xe8, 0x0b, 0x70, 0x82, + 0xda, 0x00, 0x17, 0x00, 0x0d, 0xc0, 0x0b, 0x60, + 0x36, 0x18, 0x01, 0xb7, 0x20, 0x2d, 0xe0, 0x08, + 0x70, 0x82, 0xdc, 0x00, 0xb7, 0x00, 0x29, 0xc0, + 0x0b, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xf7, 0x80, + 0x3d, 0xe0, 0x0f, 0x7a, 0x02, 0xde, 0x00, 0xf7, + 0x80, 0x3d, 0xed, 0x09, 0x00, 0x5e, 0x00, 0xe0, + 0x0f, 0x78, 0x02, 0xde, 0x00, 0xf7, 0x80, 0x35, + 0xe0, 0x08, 0x78, 0x0b, 0x5e, 0x40, 0xf7, 0xe0, + 0x3b, 0xea, 0x0f, 0x78, 0x03, 0xda, 0x00, 0xf7, + 0x80, 0x19, 0xec, 0x0e, 0x68, 0x02, 0x9a, 0x09, + 0xf7, 0x81, 0x39, 0xf8, 0x2c, 0x68, 0x03, 0xde, + 0x00, 0xf7, 0xa4, 0x39, 0xe0, 0x0f, 0x78, 0x03, + 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x1d, 0xac, 0x00, 0xbb, 0x00, 0x3e, 0xc0, 0x0e, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb2, 0x03, 0x64, 0x00, 0xfb, 0x00, 0x1e, + 0xc0, 0x2f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x46, + 0x3a, 0xcc, 0x8c, 0xb0, 0x03, 0xc8, 0x00, 0xf9, + 0x00, 0x3e, 0xd8, 0x4f, 0xb0, 0x03, 0xe8, 0x00, + 0xfb, 0x10, 0x3e, 0xd8, 0x0f, 0xa0, 0x03, 0xec, + 0x00, 0xfb, 0x14, 0x3a, 0x80, 0x0f, 0xb0, 0x03, + 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3b, 0xe0, 0x0f, + 0xf8, 0x83, 0x3e, 0x00, 0xcf, 0x80, 0x33, 0xe0, + 0x0f, 0xfc, 0x83, 0x3e, 0x00, 0xcf, 0x80, 0x33, + 0xe0, 0x8f, 0xe8, 0x43, 0xfe, 0x40, 0xcf, 0xc0, + 0x3f, 0xe0, 0x0f, 0xe9, 0x03, 0x3a, 0x00, 0xff, + 0x81, 0x37, 0xe2, 0x0d, 0xe8, 0x03, 0xfa, 0x40, + 0xcf, 0x80, 0x33, 0xf1, 0x0c, 0xf8, 0x03, 0x3e, + 0x20, 0xcf, 0x90, 0x33, 0xe0, 0x2c, 0xf8, 0x03, + 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x21, 0xc0, 0x0b, + 0x70, 0x82, 0x19, 0x00, 0x8d, 0x00, 0x21, 0xc4, + 0x0b, 0x70, 0x02, 0x1c, 0x00, 0x8e, 0x00, 0x21, + 0xc0, 0x0b, 0x62, 0x02, 0xdc, 0x48, 0xf7, 0x10, + 0x2d, 0xc8, 0x0f, 0x50, 0x21, 0xdc, 0x10, 0xe7, + 0x00, 0x21, 0xc0, 0x4b, 0x66, 0x02, 0xd8, 0x21, + 0xaf, 0x00, 0x37, 0xc0, 0x08, 0xed, 0x09, 0x00, + 0x5f, 0x00, 0x74, 0x43, 0x7c, 0x44, 0x8f, 0x18, + 0x21, 0xc0, 0x08, 0x70, 0x02, 0xea, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, + 0xb7, 0x00, 0x29, 0xc0, 0x0b, 0xf0, 0x02, 0x1c, + 0x20, 0x87, 0x00, 0x21, 0xc0, 0x0b, 0x31, 0x02, + 0x1c, 0x00, 0x87, 0x18, 0x21, 0xc4, 0x0b, 0x60, + 0x12, 0xdc, 0x41, 0xb7, 0x00, 0x2d, 0xc1, 0x1b, + 0x64, 0x08, 0x98, 0x00, 0xb6, 0x00, 0x23, 0xc0, + 0x08, 0x40, 0x92, 0xd8, 0x00, 0x87, 0x00, 0x21, + 0xc0, 0x09, 0x60, 0x02, 0x1c, 0x00, 0x97, 0x42, + 0x61, 0x40, 0x08, 0x70, 0x02, 0xc0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, 0xcc, 0x00, + 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x0a, 0x2f, + 0x00, 0x83, 0x00, 0x20, 0xc0, 0x0b, 0x34, 0x02, + 0x0c, 0x00, 0x83, 0x60, 0x20, 0xc8, 0x0b, 0x2a, + 0x02, 0xcc, 0x00, 0x8b, 0x41, 0x2c, 0xf0, 0x0a, + 0x10, 0x06, 0x4c, 0x09, 0xa0, 0x20, 0x20, 0xe8, + 0x2b, 0x18, 0x02, 0xcb, 0x00, 0xa3, 0xc0, 0x24, + 0xc0, 0x09, 0x0c, 0x02, 0x0e, 0x08, 0x93, 0x00, + 0x20, 0x00, 0x08, 0x30, 0x02, 0xc8, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xac, 0x00, + 0xfb, 0x00, 0x3a, 0xc0, 0x0f, 0xf0, 0x03, 0x2e, + 0x00, 0xcb, 0x00, 0x32, 0xc0, 0x0f, 0xf4, 0x03, + 0x2c, 0x02, 0xcb, 0x80, 0x32, 0x80, 0x0f, 0xaa, + 0x13, 0xfc, 0x00, 0xbf, 0x00, 0x3f, 0xe0, 0x0b, + 0x90, 0x02, 0xa8, 0x00, 0xf9, 0x80, 0xb3, 0xf8, + 0x0d, 0xa8, 0x02, 0xeb, 0x00, 0xcf, 0x40, 0x33, + 0xc0, 0x2d, 0x91, 0x82, 0x3e, 0x80, 0xdf, 0x80, + 0x30, 0x00, 0x0c, 0xb0, 0x03, 0xea, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x10, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xba, 0x03, + 0xed, 0x09, 0x00, 0x60, 0x00, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0x90, 0x0f, 0xb4, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc6, 0x1f, 0xa0, 0x03, 0xa9, + 0x00, 0xe8, 0x50, 0x3a, 0xc0, 0x0e, 0x80, 0x07, + 0xe1, 0x84, 0xfb, 0x30, 0x36, 0xc0, 0x0e, 0x84, + 0x03, 0xec, 0x00, 0xeb, 0x04, 0x3e, 0x00, 0x0f, + 0xb0, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x10, 0xfc, 0x00, 0xfb, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x20, 0xce, 0x10, + 0x33, 0xc0, 0x0f, 0x70, 0x03, 0x2f, 0x00, 0xfd, + 0x00, 0x33, 0x80, 0x0f, 0xf0, 0x43, 0xdc, 0x00, + 0xcf, 0x08, 0x37, 0xc0, 0x0f, 0x98, 0x03, 0x98, + 0x84, 0xc9, 0x00, 0x3f, 0xc0, 0x0f, 0xe9, 0x33, + 0xbe, 0x00, 0xff, 0x01, 0x3f, 0xc0, 0x0c, 0x90, + 0x03, 0xfc, 0x10, 0xff, 0x00, 0x32, 0x28, 0x0c, + 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xed, 0x00, 0x8b, 0x00, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, + 0x40, 0x22, 0x30, 0x0b, 0xbc, 0x82, 0xec, 0x00, + 0x8b, 0x00, 0x2a, 0xc1, 0x0e, 0xac, 0x03, 0x2a, + 0x80, 0x88, 0xc8, 0x3a, 0xc0, 0x0b, 0x90, 0x02, + 0xe6, 0x00, 0xfb, 0x00, 0x2e, 0xc0, 0x08, 0x88, + 0x02, 0xec, 0x00, 0xb3, 0x02, 0x2a, 0x22, 0x28, + 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xe6, 0x00, 0xa3, 0x00, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xa4, 0x00, 0xb3, + 0xc0, 0x22, 0xa0, 0x0b, 0xa8, 0x02, 0xec, 0x01, + 0x8b, 0x01, 0x22, 0xc0, 0x1b, 0x85, 0x02, 0xe8, + 0x00, 0x89, 0x80, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xe9, 0x80, 0xbb, 0x01, 0x28, 0xc0, 0x18, 0x98, + 0x02, 0xec, 0x01, 0xed, 0x09, 0x00, 0x61, 0x00, + 0xbb, 0x00, 0x26, 0x00, 0xc8, 0xb0, 0x02, 0xe0, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xa3, 0x80, 0x20, 0xc0, 0x0b, + 0x30, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x20, 0x80, + 0x0b, 0x20, 0x42, 0xcc, 0x00, 0x83, 0x00, 0x2c, + 0xc0, 0x0a, 0x00, 0x42, 0x88, 0x02, 0x80, 0x00, + 0x68, 0xc0, 0x0b, 0x10, 0x02, 0xcc, 0x04, 0xb3, + 0x00, 0x0c, 0xc0, 0x28, 0x10, 0x02, 0x4c, 0x00, + 0xbb, 0x00, 0x2c, 0x00, 0x08, 0x30, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xcc, 0x00, 0xeb, 0x00, 0x32, 0xc0, 0x0f, + 0xf0, 0x03, 0x2c, 0x00, 0xbb, 0x00, 0x22, 0x80, + 0x0f, 0x80, 0x02, 0xdc, 0x00, 0xcf, 0x00, 0x33, + 0xc0, 0x0b, 0x80, 0x03, 0xec, 0x00, 0xc8, 0x00, + 0x3f, 0xc0, 0x0f, 0x90, 0x03, 0xe0, 0x10, 0xfb, + 0x00, 0x3f, 0xc0, 0x0c, 0x90, 0x03, 0xec, 0x08, + 0xfb, 0x00, 0x36, 0x00, 0x0c, 0xb0, 0x03, 0xc0, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0x70, + 0x23, 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xf4, 0x00, 0xff, 0x06, 0x1f, 0x00, + 0x4f, 0xc0, 0x03, 0xfc, 0x06, 0x7f, 0x00, 0x3b, + 0xc0, 0x0e, 0xc0, 0x03, 0x3c, 0x00, 0xfc, 0x00, + 0x29, 0xc0, 0x07, 0xd0, 0x03, 0xd4, 0x08, 0xef, + 0x00, 0x3f, 0xc0, 0x0f, 0xd0, 0x23, 0xfc, 0x00, + 0xff, 0x00, 0x3b, 0x00, 0x0f, 0xf0, 0x03, 0xe8, + 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x05, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x00, 0x2c, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xbc, 0x80, 0xff, 0x01, 0xed, 0x09, + 0x00, 0x62, 0x00, 0x33, 0xd0, 0x0b, 0xf0, 0x03, + 0xdc, 0x00, 0xff, 0x00, 0x3d, 0x00, 0x0c, 0xd1, + 0x03, 0xfc, 0x00, 0xcf, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x02, 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0xc0, + 0x06, 0xf0, 0x03, 0xfc, 0x00, 0xdc, 0x34, 0x3b, + 0x06, 0x0c, 0xf0, 0x03, 0xf0, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x10, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0x02, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x03, 0xb0, 0x0a, 0xac, + 0x00, 0xbb, 0x28, 0xa2, 0x60, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0xbf, 0xa1, 0x22, 0x01, 0x0b, 0xd6, + 0x22, 0xec, 0x00, 0x9b, 0x00, 0x2f, 0xc0, 0x09, + 0xf0, 0x02, 0xec, 0x00, 0xb9, 0x00, 0x2e, 0xc0, + 0x0b, 0xf0, 0x02, 0xec, 0x00, 0xb8, 0x60, 0x22, + 0x90, 0x08, 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, 0x00, 0xb3, + 0x00, 0x2e, 0x28, 0x08, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x8d, + 0x00, 0xb3, 0x20, 0x20, 0x8c, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x08, 0x2a, 0x00, 0x08, 0x16, + 0x02, 0xc8, 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb1, 0x30, 0x24, + 0x40, 0x08, 0x30, 0x42, 0xe2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, 0x00, 0xbb, + 0x00, 0x2e, 0x20, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x05, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xac, + 0x00, 0xbb, 0x00, 0x22, 0xd8, 0x0b, 0xb0, 0x02, + 0xec, 0x01, 0x9b, 0x00, 0x22, 0x08, 0x0a, 0x90, + 0x02, 0xe0, 0x00, 0x9b, 0x04, 0x2e, 0xc0, 0x09, + 0xb0, 0x02, 0xec, 0x00, 0xb9, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xb9, 0x00, 0x22, + 0x80, 0xed, 0x09, 0x00, 0x63, 0x00, 0x08, 0xb0, + 0x00, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3c, 0x00, + 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xa4, 0x00, 0xfb, 0x00, + 0x32, 0xc0, 0x07, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3a, 0xb8, 0x0c, 0x90, 0x03, 0xe5, 0x00, + 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x02, 0xec, + 0x00, 0xdb, 0x00, 0x3e, 0xc0, 0x0e, 0xb0, 0x03, + 0xec, 0x00, 0xf8, 0x08, 0xb2, 0x20, 0x2c, 0xb0, + 0x01, 0xd0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0x00, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xee, 0x80, 0xff, 0x08, + 0x3e, 0xc0, 0x4f, 0xf0, 0x03, 0xfc, 0x00, 0xf7, + 0x01, 0x3b, 0xa0, 0x8f, 0xd0, 0x03, 0xfc, 0x02, + 0xaf, 0x10, 0x3f, 0xc0, 0x0f, 0xb0, 0x03, 0xfc, + 0x00, 0xfb, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xfc, 0x10, 0x37, 0xe4, 0x0f, 0xf0, + 0x01, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0x00, + 0x1e, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x4f, 0xb0, 0x03, 0xac, 0x40, 0xcb, 0x00, + 0x3e, 0xc0, 0x0c, 0xb0, 0x03, 0xac, 0x00, 0xcb, + 0x00, 0x3a, 0xd0, 0x0c, 0x90, 0x03, 0xac, 0x00, + 0xdb, 0x70, 0x3e, 0xc0, 0x0c, 0xb0, 0x03, 0x6c, + 0x00, 0xeb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x03, + 0x6c, 0x00, 0xfb, 0x70, 0x30, 0x60, 0x0c, 0xb0, + 0x03, 0xd0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0x38, + 0x08, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0x38, 0x03, 0xec, 0x00, 0xdb, 0x00, + 0x2e, 0xc1, 0x28, 0xb0, 0xed, 0x09, 0x00, 0x64, + 0x00, 0x02, 0xec, 0x00, 0xdf, 0x00, 0x20, 0xc0, + 0x0d, 0xd0, 0x02, 0x2c, 0x00, 0x89, 0x00, 0x2f, + 0xc0, 0x0a, 0xf0, 0x02, 0x2c, 0x00, 0xbb, 0x00, + 0xa2, 0xc0, 0x0b, 0xf0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x22, 0xc4, 0x28, 0xb0, 0x02, 0x72, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, + 0x00, 0xb3, 0x00, 0x2c, 0x08, 0x0a, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0x8e, 0x00, 0xab, 0x50, 0x2c, 0xc1, 0x08, + 0x30, 0x02, 0x8c, 0x00, 0x93, 0x00, 0x28, 0x40, + 0x08, 0x10, 0x02, 0xac, 0x01, 0xb3, 0x80, 0x2c, + 0xc0, 0x88, 0x30, 0x02, 0x4c, 0x00, 0x83, 0x00, + 0x20, 0xc0, 0x0b, 0x30, 0x06, 0x4c, 0x00, 0xba, + 0x40, 0x20, 0x00, 0x08, 0x30, 0x02, 0x78, 0x04, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x1e, + 0x00, 0xb7, 0x80, 0x2d, 0x24, 0x08, 0x78, 0x02, + 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, + 0x82, 0xde, 0x00, 0x87, 0x80, 0x2d, 0xe4, 0x0a, + 0x78, 0x42, 0xde, 0x00, 0x93, 0x80, 0x27, 0xe0, + 0x19, 0x18, 0x02, 0x1e, 0x04, 0xa7, 0x80, 0x6c, + 0xe0, 0x0a, 0x78, 0x02, 0x1e, 0x00, 0xb5, 0x80, + 0x21, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb2, + 0x81, 0x21, 0x20, 0x80, 0x78, 0x02, 0x48, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x0c, + 0x00, 0xf3, 0x00, 0x2e, 0x00, 0x0a, 0x30, 0x03, + 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc4, 0x0b, 0x30, + 0x13, 0x8c, 0x02, 0xa3, 0x04, 0x3c, 0xc0, 0x0c, + 0x30, 0x03, 0x8c, 0x00, 0xd3, 0x00, 0x38, 0x48, + 0x1c, 0x10, 0x03, 0xa9, 0x80, 0xf3, 0x40, 0x3c, + 0xc0, 0x0c, 0x30, 0x03, 0x4c, 0x00, 0xe3, 0x10, + 0x30, 0xc0, 0x0f, 0x30, 0x03, 0x4c, 0x00, 0xf0, + 0x00, 0xb2, 0x4c, 0x04, 0x30, 0x03, 0xd2, 0xed, + 0x09, 0x00, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x00, + 0x3f, 0x80, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0x7f, + 0x00, 0x3f, 0xc0, 0x0f, 0x70, 0x03, 0xfc, 0x00, + 0xff, 0x10, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x01, 0x3b, 0xc0, 0x0f, 0xd0, 0x03, + 0xf4, 0x00, 0xdf, 0x00, 0x3f, 0xd0, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xfd, 0x00, 0x3f, 0xc0, 0x07, + 0xf0, 0x03, 0xfc, 0x00, 0xfc, 0x00, 0x3f, 0x04, + 0x0f, 0xf0, 0x02, 0xd0, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x15, 0xec, 0x00, 0xfb, 0x00, + 0x3a, 0x00, 0x2c, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0x30, 0x0b, 0xac, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0c, 0xb0, 0x03, 0xec, + 0x04, 0xfb, 0x00, 0x36, 0x00, 0x0f, 0x12, 0x8b, + 0x44, 0x00, 0xaa, 0x80, 0x32, 0xdc, 0x8f, 0xbb, + 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb2, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x80, + 0x0f, 0xb0, 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x11, 0x9c, 0x00, 0xb7, 0x00, + 0x2f, 0x80, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, + 0xb7, 0x00, 0x2c, 0xc0, 0x08, 0x70, 0x02, 0xdc, + 0x00, 0xb3, 0x50, 0x31, 0x80, 0xcb, 0x54, 0x02, + 0x1c, 0x00, 0x8f, 0x04, 0x35, 0xc8, 0x0b, 0x72, + 0x83, 0x1c, 0x00, 0xe7, 0x00, 0x2d, 0xc0, 0x0b, + 0x72, 0x82, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, 0xb7, 0x80, + 0x2d, 0x60, 0x08, 0x78, 0x02, 0xde, 0x00, 0xb7, + 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0x9e, 0x00, + 0xb7, 0x80, 0x2d, 0xe0, 0x09, 0x78, 0x02, 0xde, + 0x00, 0xb7, 0xed, 0x09, 0x00, 0x66, 0x00, 0xa0, + 0x25, 0x60, 0x09, 0xda, 0x02, 0x3e, 0x00, 0xa7, + 0x80, 0x21, 0xe0, 0x0b, 0x3a, 0x46, 0x5e, 0x00, + 0xb7, 0xc0, 0x29, 0xe0, 0x0b, 0x79, 0x02, 0xde, + 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x1b, 0x78, 0x02, + 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x04, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0x90, 0x08, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x8b, 0x30, 0x02, 0x0e, 0x00, 0xb3, 0x00, 0x2e, + 0xf0, 0x29, 0x30, 0x02, 0xcc, 0x10, 0xb3, 0x00, + 0x20, 0xec, 0x0b, 0x10, 0x02, 0x4e, 0x00, 0x83, + 0x20, 0x24, 0xc0, 0x0b, 0x30, 0x02, 0x0c, 0x00, + 0xa3, 0x80, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x90, 0x2c, 0xc4, 0x0b, 0x30, 0x02, + 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, + 0x05, 0xa8, 0x00, 0xfa, 0x00, 0x3f, 0x90, 0x08, + 0xa0, 0x03, 0xe8, 0x00, 0xba, 0x00, 0x3e, 0x80, + 0x0f, 0x20, 0x02, 0xaa, 0x20, 0xfa, 0x00, 0x3f, + 0xb6, 0x0d, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, + 0x37, 0x80, 0x0d, 0xe0, 0x03, 0x39, 0x00, 0xee, + 0x60, 0x32, 0x80, 0x0f, 0xa0, 0x03, 0x68, 0x00, + 0xfa, 0x02, 0x3a, 0x80, 0x0b, 0xa0, 0x03, 0xe8, + 0x00, 0xfe, 0x40, 0x3f, 0xa0, 0x0f, 0xa0, 0x03, + 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x08, 0x0f, + 0x80, 0x01, 0xe0, 0x00, 0xf8, 0x00, 0x1e, 0x00, + 0x0f, 0x80, 0x23, 0xe1, 0x00, 0xf8, 0x00, 0x3e, + 0x10, 0x0e, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x7a, 0x00, 0x0f, 0x80, 0x03, 0xa2, 0x40, 0xf8, + 0x44, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xa0, 0x00, + 0xe8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x08, 0x3e, 0x20, 0x0f, 0x80, 0x03, + 0xd2, 0x00, 0x30, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x67, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0e, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0x66, 0x00, 0xf9, 0x00, 0x3e, 0x68, 0x04, 0x90, + 0x03, 0xe4, 0x00, 0xf1, 0x00, 0x3a, 0x40, 0x8f, + 0x10, 0x03, 0x24, 0x08, 0xe9, 0x00, 0x2e, 0x40, + 0x0f, 0x90, 0x02, 0xe4, 0x00, 0xf9, 0x00, 0x36, + 0x40, 0x0f, 0x10, 0x03, 0x24, 0x00, 0xf9, 0x80, + 0x3e, 0x64, 0x0f, 0x90, 0x03, 0xc2, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, + 0xb9, 0x00, 0x2c, 0x70, 0x08, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x0b, + 0x65, 0x20, 0xb9, 0x00, 0x2e, 0x48, 0x0a, 0x90, + 0x02, 0xe5, 0x00, 0xb9, 0x00, 0x26, 0x40, 0x0b, + 0x90, 0x02, 0x24, 0x00, 0x89, 0x80, 0x2e, 0x40, + 0x1b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xa4, 0x00, 0xb9, 0x60, + 0x2e, 0x48, 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0x24, 0x00, + 0xb9, 0x00, 0x2e, 0x54, 0x0a, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x98, 0x02, + 0x64, 0x80, 0xb9, 0x60, 0x2e, 0x40, 0x1a, 0x90, + 0x02, 0xe4, 0x00, 0xa9, 0x00, 0x2e, 0x40, 0x03, + 0x90, 0x02, 0x44, 0x00, 0xa9, 0x20, 0x2e, 0x40, + 0x1a, 0x90, 0x02, 0xe4, 0x00, 0x39, 0x00, 0x2e, + 0x40, 0x09, 0x90, 0x02, 0x64, 0x00, 0xb9, 0x10, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, + 0xb1, 0x00, 0x2e, 0x50, 0x08, 0x10, 0x02, 0xc4, + 0x10, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, + 0x44, 0x00, 0xb1, 0x40, 0x2c, 0x40, 0x0a, 0x10, + 0x02, 0xcc, 0x00, 0xb1, 0x00, 0x24, 0x51, 0x0b, + 0xed, 0x09, 0x00, 0x68, 0x00, 0x14, 0x0a, 0x05, + 0x00, 0x81, 0x40, 0x2c, 0x50, 0x0b, 0x10, 0x02, + 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x14, + 0x02, 0xc4, 0x00, 0xb1, 0x40, 0x2c, 0x50, 0x0b, + 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb8, 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x2e, + 0x00, 0x0e, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x60, 0x00, 0xf8, + 0x00, 0x3e, 0x14, 0x4e, 0x80, 0x43, 0xe0, 0x00, + 0xe8, 0x50, 0x3a, 0x00, 0x0f, 0x80, 0x03, 0x60, + 0x00, 0xea, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x36, 0x00, 0x0f, 0x80, + 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3f, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xf5, 0x14, 0xf9, + 0x00, 0x3f, 0xd0, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x40, 0x3b, 0x40, 0x0f, 0xd4, 0x13, 0xf4, + 0x00, 0xfd, 0x40, 0x3e, 0x50, 0x0f, 0x94, 0x03, + 0xe4, 0x00, 0xdd, 0x40, 0x3e, 0x40, 0x0f, 0x94, + 0x03, 0xa4, 0x00, 0xdd, 0x45, 0x3f, 0x50, 0x0f, + 0x90, 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3f, + 0xc0, 0x0c, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0xd0, 0x03, 0x34, 0x01, 0xed, + 0x10, 0x3b, 0x4c, 0x0c, 0x90, 0x03, 0xf4, 0x00, + 0xfd, 0x40, 0x32, 0x40, 0x1e, 0x91, 0x03, 0x64, + 0x00, 0xfd, 0x2c, 0x32, 0x4c, 0x0d, 0x90, 0x03, + 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x92, + 0x83, 0x24, 0x00, 0xfd, 0x04, 0x3f, 0x40, 0x0f, + 0x90, 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x10, 0xed, 0x09, 0x00, 0x69, 0x00, + 0xe0, 0x00, 0xb8, 0x00, 0x1a, 0x02, 0x28, 0x80, + 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, + 0x80, 0x06, 0xa0, 0x04, 0x80, 0x00, 0x2e, 0x08, + 0x0d, 0x80, 0x02, 0xe0, 0x00, 0x18, 0x60, 0xa0, + 0x02, 0x0b, 0x81, 0x22, 0xa8, 0xa0, 0xb8, 0x20, + 0x2a, 0x0c, 0x0d, 0x84, 0x02, 0x20, 0x00, 0xb8, + 0x10, 0x2e, 0x00, 0x0b, 0x82, 0x02, 0x20, 0x00, + 0xb8, 0x48, 0x2c, 0x82, 0x0b, 0x80, 0x02, 0xce, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, + 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x08, 0x10, + 0x02, 0xc4, 0x04, 0xb1, 0x00, 0x6c, 0x40, 0x0b, + 0x10, 0x02, 0x04, 0x40, 0xa3, 0x00, 0x28, 0x4c, + 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x30, 0x24, + 0x40, 0x18, 0x10, 0x02, 0x84, 0x88, 0xb9, 0x28, + 0x2c, 0x48, 0x0a, 0x11, 0x02, 0x44, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x12, 0x82, 0x44, 0x00, + 0xb1, 0x30, 0x2c, 0x44, 0x9b, 0x10, 0x02, 0xc2, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, + 0xa4, 0x00, 0xb9, 0x04, 0x2e, 0x40, 0x08, 0x90, + 0x02, 0xe4, 0x04, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xa4, 0x80, 0x89, 0x00, 0x24, 0x48, + 0x09, 0x90, 0x02, 0xe4, 0x00, 0x93, 0x00, 0x26, + 0x43, 0x0b, 0x10, 0x22, 0xa4, 0x48, 0xb9, 0x08, + 0x2c, 0x40, 0x19, 0x90, 0x02, 0x24, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x1b, 0x90, 0x02, 0x64, 0x00, + 0xb9, 0x0a, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x42, 0x0c, 0x90, + 0x02, 0xe4, 0x00, 0xf9, 0x00, 0x2e, 0x40, 0x0f, + 0x90, 0x03, 0x04, 0x00, 0xa9, 0x00, 0x3a, 0x70, + 0x08, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x36, + 0x40, 0x0e, 0x90, 0x03, 0xa6, 0x00, 0xed, 0x09, + 0x00, 0x6a, 0x00, 0xf1, 0x00, 0x2e, 0x40, 0x04, + 0x90, 0x03, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x03, 0x64, 0x00, 0xf9, 0x00, 0x2e, + 0x50, 0x0f, 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, + 0x00, 0x3a, 0x50, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x0b, 0xa4, + 0x00, 0xf9, 0x00, 0x3e, 0x60, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x01, 0x3a, 0x40, 0x07, 0x90, + 0x47, 0xa6, 0x00, 0xb9, 0x20, 0x7a, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xa4, 0x00, 0xf9, 0x20, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xca, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, + 0x00, 0x3e, 0x08, 0x0c, 0x80, 0x03, 0x60, 0x00, + 0xf8, 0x00, 0x1e, 0x00, 0x0f, 0x80, 0x03, 0x60, + 0x80, 0xd8, 0x04, 0x32, 0x30, 0x0c, 0x80, 0x03, + 0xa0, 0x00, 0xf8, 0x80, 0x3e, 0x10, 0x0d, 0x80, + 0x43, 0xe1, 0x00, 0xf8, 0x10, 0x3e, 0x00, 0x0c, + 0x00, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x08, 0x3e, + 0x18, 0x0e, 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x28, 0x00, 0xba, + 0x00, 0x2f, 0x80, 0x08, 0xa0, 0x12, 0xe8, 0x00, + 0xba, 0x00, 0x2e, 0x80, 0x0b, 0x20, 0x03, 0x3a, + 0x00, 0x8e, 0x50, 0x23, 0x80, 0x28, 0xa0, 0x02, + 0xf9, 0x28, 0xbe, 0xa0, 0x2e, 0x80, 0x0a, 0xa0, + 0x02, 0xe8, 0x00, 0xbe, 0xc1, 0x2e, 0x80, 0x0a, + 0xa0, 0x03, 0xa8, 0x00, 0xba, 0x00, 0x26, 0x80, + 0x0b, 0xa0, 0x42, 0xe8, 0x10, 0xbe, 0xc0, 0x2f, + 0xa2, 0x08, 0xa0, 0x02, 0xca, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, 0x00, 0xb3, + 0x00, 0xed, 0x09, 0x00, 0x6b, 0x00, 0x2e, 0xc0, + 0x08, 0x30, 0x22, 0xcc, 0x00, 0xb3, 0x00, 0x28, + 0xc0, 0x0b, 0x30, 0x02, 0x0d, 0x00, 0x93, 0x00, + 0x24, 0x00, 0x08, 0x30, 0x06, 0x8b, 0x20, 0xb0, + 0x80, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x88, 0x2c, 0xc0, 0x89, 0x30, 0x02, 0x8c, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0xb0, 0x02, + 0xcc, 0x00, 0xb3, 0xc0, 0x2c, 0xe0, 0x4b, 0x30, + 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2f, 0xc2, + 0x28, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x09, 0x70, 0x02, 0x0d, 0x00, 0x87, 0x80, + 0x21, 0x00, 0x08, 0x70, 0x02, 0xd8, 0x00, 0xb4, + 0x00, 0x2d, 0xe9, 0x0a, 0x73, 0x02, 0xdc, 0x00, + 0xb7, 0x00, 0x2d, 0xc8, 0x0b, 0x70, 0x02, 0x9c, + 0x00, 0x97, 0x00, 0x05, 0xc0, 0x0b, 0x79, 0x02, + 0xdc, 0x00, 0xb7, 0x08, 0x2d, 0x61, 0x09, 0x70, + 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x2d, 0xe1, + 0x0c, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x39, + 0xe0, 0x0f, 0x70, 0x03, 0x1e, 0x00, 0xd7, 0x80, + 0x34, 0xe0, 0x0c, 0x78, 0x03, 0x9a, 0x00, 0xf4, + 0x80, 0x2d, 0xec, 0x0c, 0x7a, 0x03, 0xde, 0x20, + 0xf7, 0x80, 0x3f, 0xec, 0x0d, 0x78, 0x03, 0x9e, + 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x72, 0x03, + 0xde, 0x00, 0xf7, 0x81, 0x2d, 0xa0, 0x4f, 0x78, + 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3c, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0x7b, 0x00, 0x3e, + 0xc0, 0x0f, 0x10, 0x03, 0xac, 0x00, 0xfb, 0x00, + 0x8b, 0xc0, 0x0f, 0xb0, 0x03, 0xe8, 0x00, 0xfc, + 0x00, 0x3e, 0xc0, 0x06, 0xb6, 0x03, 0xed, 0x08, + 0xfb, 0x00, 0x36, 0xc0, 0xed, 0x09, 0x00, 0x6c, + 0x00, 0x0e, 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb6, 0x03, 0x6c, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0e, 0xb0, 0x03, 0xc2, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, + 0x00, 0xff, 0x80, 0x3d, 0xe0, 0x0c, 0xf8, 0x03, + 0xfe, 0x00, 0xff, 0x20, 0x3f, 0xe0, 0x0f, 0x72, + 0x03, 0x7e, 0x00, 0xdf, 0x80, 0x33, 0x20, 0x8c, + 0xf8, 0x03, 0x72, 0x00, 0xce, 0x80, 0xb3, 0xe2, + 0x0f, 0xfc, 0x03, 0x3e, 0x20, 0xaf, 0x90, 0x3b, + 0xe2, 0x0f, 0xf8, 0x03, 0xbe, 0x00, 0xff, 0x80, + 0x3f, 0xe0, 0x47, 0xfc, 0x03, 0x3e, 0x00, 0xfc, + 0x80, 0x73, 0xe4, 0x87, 0xf8, 0x03, 0xc0, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, + 0x00, 0xb7, 0x00, 0x2d, 0xc4, 0x08, 0x70, 0x02, + 0xdc, 0x04, 0xb7, 0x10, 0x39, 0xc0, 0x0b, 0x71, + 0x07, 0x9c, 0x40, 0xbf, 0x00, 0x23, 0x00, 0x0a, + 0x70, 0x02, 0xd1, 0x00, 0xae, 0x00, 0x21, 0xc4, + 0x0b, 0x70, 0x02, 0x1c, 0x40, 0xe7, 0x04, 0x29, + 0xc0, 0x0b, 0x70, 0x03, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0f, 0x70, 0x03, 0x5c, 0x00, 0xb5, + 0x00, 0x35, 0x8d, 0x09, 0x70, 0x02, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, + 0x00, 0xb7, 0x00, 0x2f, 0x40, 0x08, 0x70, 0x02, + 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0x18, 0x00, 0x97, 0x00, 0x21, 0x80, 0x09, + 0x70, 0x02, 0x50, 0x00, 0xa6, 0x00, 0x21, 0xc2, + 0x0b, 0xf0, 0x02, 0x1c, 0x00, 0xa3, 0x40, 0x25, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x30, 0x02, 0x9c, 0x00, 0xb6, + 0x00, 0x21, 0x40, 0x8b, 0x70, 0x02, 0xc0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0x48, 0xa8, 0x30, 0xed, + 0x09, 0x00, 0x6d, 0x00, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x28, 0xc0, 0x0b, 0x10, 0x12, 0x88, 0x00, + 0xb3, 0x00, 0x20, 0xb6, 0x0b, 0x30, 0x02, 0xc0, + 0x00, 0xa2, 0x00, 0x22, 0xe0, 0x0b, 0xb0, 0x02, + 0x0e, 0x00, 0xa2, 0x80, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x80, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0x30, 0x00, 0x24, 0x10, + 0x09, 0x30, 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x15, 0xac, 0x00, 0xfb, 0x00, + 0x1c, 0xb0, 0x04, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0x30, 0x03, 0x0e, 0x20, + 0xdb, 0x03, 0x32, 0x00, 0x8d, 0xb0, 0x13, 0x4c, + 0x00, 0xe9, 0x00, 0x73, 0xe0, 0x0b, 0xf0, 0x43, + 0x1d, 0xc0, 0xeb, 0x40, 0x3f, 0xc0, 0x8f, 0xb0, + 0x07, 0xac, 0x00, 0xfb, 0x00, 0x2e, 0xc0, 0x0f, + 0xf0, 0x03, 0xac, 0x00, 0x7b, 0x00, 0xe2, 0xe6, + 0x0f, 0xb0, 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0x70, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xac, 0x00, + 0xfb, 0x02, 0x3f, 0x00, 0x0c, 0xb0, 0x03, 0xed, + 0x00, 0x3d, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x13, + 0xec, 0x00, 0xfb, 0x10, 0x3a, 0xc0, 0x0f, 0xb0, + 0x07, 0xac, 0x00, 0xfb, 0x10, 0x3e, 0xc0, 0x4e, + 0xb0, 0x02, 0x6c, 0x00, 0xfb, 0x00, 0x3a, 0x40, + 0x0f, 0xb0, 0x17, 0xe0, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0c, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x7f, 0x00, + 0xcf, 0x00, 0x33, 0x40, 0x0c, 0xf0, 0x03, 0xba, + 0x00, 0xcd, 0x00, 0x37, 0xc0, 0x0c, 0xf0, 0x03, + 0x3c, 0x00, 0xdd, 0x00, 0x31, 0xc0, 0x0c, 0xf0, + 0x03, 0x7c, 0xed, 0x09, 0x00, 0x6e, 0x00, 0x18, + 0xff, 0x00, 0x3b, 0xc0, 0x0f, 0xf0, 0x03, 0xbc, + 0x10, 0xf7, 0x00, 0x39, 0x80, 0x0c, 0xf0, 0x03, + 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, + 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0x60, 0x28, + 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0x90, 0x02, 0x6c, 0x00, 0xdb, 0x00, 0x02, + 0x40, 0x08, 0xb0, 0x02, 0x69, 0x00, 0xa9, 0x00, + 0x2a, 0xc0, 0x0a, 0xb0, 0x00, 0x2c, 0x00, 0x83, + 0x80, 0x2a, 0xc0, 0x0a, 0xb0, 0x02, 0xec, 0x00, + 0x9b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xac, + 0x00, 0xb8, 0x00, 0x22, 0x00, 0x00, 0xb0, 0x02, + 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xe2, 0x08, + 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0x6c, 0x00, 0x83, 0x10, 0x20, + 0x20, 0x08, 0xb0, 0x02, 0xe8, 0x40, 0x80, 0x80, + 0x2a, 0xc0, 0x1b, 0xb0, 0x42, 0x2c, 0x01, 0x9b, + 0x80, 0xe6, 0xc0, 0x08, 0xb0, 0x02, 0xac, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x1b, 0x30, 0x02, 0x2c, + 0x00, 0xb8, 0x00, 0x2a, 0xc0, 0x0a, 0xb0, 0x02, + 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2e, 0x00, 0x08, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0x4c, 0x00, 0x90, 0x80, 0x20, + 0x00, 0x18, 0x30, 0x02, 0xc8, 0x00, 0xa0, 0x00, + 0x28, 0xc0, 0x9a, 0x30, 0x02, 0x2c, 0x01, 0x83, + 0x00, 0x2c, 0xc0, 0x0a, 0x30, 0x02, 0xcc, 0x00, + 0x93, 0x00, 0x2c, 0xc0, 0x1b, 0x30, 0x02, 0x8c, + 0x00, 0xb1, 0x00, 0x20, 0x80, 0x08, 0x30, 0x12, + 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x08, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0xed, 0x09, 0x00, + 0x6f, 0x00, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0x68, 0x00, 0xcb, 0x00, 0x32, 0x00, 0x0c, 0xb0, + 0x03, 0xa8, 0x00, 0xc8, 0x00, 0x37, 0xc0, 0x07, + 0xf0, 0x0b, 0x3c, 0x00, 0xdb, 0x00, 0x37, 0xc0, + 0x0c, 0xb0, 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xf0, 0x03, 0x2c, 0x00, 0xf2, 0x00, + 0x3a, 0x40, 0x2c, 0xb0, 0x03, 0xc0, 0x03, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0x40, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0x7f, 0x00, 0x3f, 0xc0, 0x0f, 0xd0, 0x06, + 0xb0, 0x00, 0xff, 0x00, 0x1f, 0x00, 0x0f, 0xf0, + 0x03, 0x58, 0x04, 0xfc, 0x00, 0x37, 0xc0, 0x0f, + 0x70, 0x03, 0xfc, 0x00, 0xfe, 0x00, 0x3b, 0xc0, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xfc, 0x00, + 0x3f, 0x00, 0x0f, 0xf0, 0x23, 0xe8, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x05, 0xf8, 0x40, + 0xfc, 0x00, 0x3f, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x00, 0xc4, 0x00, 0x33, 0x00, 0x0f, 0xc0, 0x03, + 0x30, 0x00, 0xfc, 0x10, 0x33, 0x00, 0x6c, 0xc4, + 0x03, 0x30, 0x00, 0xfc, 0x01, 0x3f, 0x00, 0x0f, + 0xc0, 0x03, 0x70, 0x80, 0x7f, 0x00, 0x33, 0x00, + 0x0f, 0xf0, 0x53, 0xfc, 0x80, 0xcc, 0x01, 0x23, + 0xc4, 0x0e, 0xf2, 0x83, 0x70, 0x08, 0xcf, 0x20, + 0x37, 0x40, 0x0c, 0xd0, 0x03, 0xf0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0xec, 0x80, + 0xb8, 0x00, 0x2e, 0x00, 0x08, 0x80, 0x02, 0x20, + 0x00, 0x88, 0x00, 0x22, 0x00, 0x0b, 0x80, 0x02, + 0x28, 0x00, 0xb8, 0x02, 0x22, 0x00, 0x08, 0x82, + 0x02, 0x20, 0x20, 0xb8, 0x02, 0x2c, 0x00, 0x4e, + 0xa2, 0x82, 0xe1, 0x00, 0xbb, 0x04, 0x3e, 0x12, + 0x0b, 0xb4, 0x02, 0xdd, 0xa2, 0x88, 0x00, 0x2a, + 0xed, 0x09, 0x00, 0x70, 0x00, 0xc8, 0x0b, 0xb4, + 0x80, 0x24, 0x00, 0xdf, 0x01, 0x22, 0x44, 0x0a, + 0x91, 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x88, 0x05, 0xc8, 0x00, 0xb0, 0x00, 0x2c, + 0x00, 0x08, 0x00, 0x02, 0x20, 0x00, 0xa8, 0x80, + 0x28, 0x40, 0x0b, 0x80, 0x12, 0x04, 0x10, 0xb8, + 0x80, 0x20, 0x00, 0x09, 0x90, 0x02, 0x40, 0x80, + 0xb0, 0x03, 0x24, 0x80, 0x0b, 0x10, 0x02, 0xc0, + 0x40, 0xb3, 0x00, 0xa8, 0x0d, 0x0a, 0x31, 0x02, + 0xcd, 0x00, 0x90, 0x00, 0x20, 0xc8, 0x0a, 0x32, + 0x02, 0xe2, 0x00, 0xa3, 0x12, 0x28, 0x40, 0x08, + 0x00, 0x02, 0xe2, 0x11, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x15, 0xac, 0x00, 0xb8, 0x00, 0x2c, + 0x00, 0x08, 0x00, 0x02, 0x22, 0x00, 0xa8, 0x00, + 0x2a, 0x40, 0x0b, 0x88, 0x22, 0x2c, 0x08, 0x98, + 0x00, 0x20, 0x00, 0x09, 0x90, 0x02, 0xa0, 0x00, + 0xb8, 0x00, 0x2e, 0x80, 0x02, 0xb0, 0x02, 0xe3, + 0x01, 0xbb, 0x00, 0x2e, 0x60, 0x0b, 0xb0, 0x02, + 0xec, 0x01, 0x9b, 0x00, 0x22, 0xc0, 0x0b, 0xb0, + 0x02, 0xee, 0x00, 0xbb, 0x00, 0x2a, 0x60, 0x0a, + 0x98, 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x14, 0xa8, 0x00, 0xfa, 0x20, 0x3e, + 0x08, 0x0c, 0x84, 0x03, 0x04, 0x00, 0xea, 0x00, + 0x3a, 0x80, 0x0f, 0x10, 0x03, 0x20, 0x00, 0xf2, + 0x00, 0x32, 0x40, 0x49, 0x80, 0x0b, 0x66, 0x50, + 0xfa, 0x42, 0x36, 0x08, 0x0f, 0x80, 0x03, 0x63, + 0x00, 0xfa, 0x02, 0x3a, 0x20, 0x47, 0xb0, 0x03, + 0xec, 0x00, 0xd0, 0xa0, 0x32, 0xc0, 0x0e, 0xb0, + 0x03, 0xc0, 0x00, 0x6b, 0x00, 0x3a, 0x38, 0x0c, + 0x8a, 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xe1, 0x00, 0xbc, 0x00, 0xfe, 0x08, 0x3f, + 0x06, 0x0f, 0xc1, 0x03, 0xf4, 0x00, 0xde, 0x00, + 0x37, 0x80, 0x1f, 0xed, 0x09, 0x00, 0x71, 0x00, + 0xd0, 0x03, 0xf8, 0x00, 0xfe, 0x02, 0x1f, 0x44, + 0x0e, 0xc9, 0x03, 0x74, 0x01, 0xfe, 0x02, 0x37, + 0x00, 0x08, 0xe0, 0x83, 0xf0, 0x00, 0xff, 0x20, + 0x3f, 0x00, 0x0f, 0xb0, 0x01, 0xfc, 0x00, 0x6c, + 0xc8, 0x3f, 0xc0, 0x0d, 0x70, 0x03, 0x34, 0x00, + 0xd7, 0x00, 0x35, 0xc0, 0x0f, 0xc0, 0x03, 0xf8, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, + 0xa8, 0x00, 0xfa, 0x80, 0x3e, 0x20, 0x0f, 0x8c, + 0x0b, 0x26, 0x00, 0xca, 0x80, 0x32, 0xe0, 0x1f, + 0x9a, 0x03, 0x24, 0x03, 0xea, 0x04, 0x2a, 0x60, + 0x0f, 0x90, 0x03, 0xe4, 0x40, 0xfa, 0xc0, 0xb2, + 0xa0, 0x0c, 0x90, 0x01, 0x21, 0x00, 0xda, 0x22, + 0x3e, 0x01, 0x8f, 0xb0, 0x03, 0x0c, 0x10, 0xcb, + 0x56, 0x3e, 0xc0, 0x0c, 0xba, 0x03, 0xe8, 0x00, + 0xfb, 0x80, 0x32, 0x10, 0x0f, 0xa6, 0x03, 0xd0, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xca, 0x04, + 0x2c, 0x00, 0x8a, 0xc0, 0x2e, 0x30, 0x0b, 0x8c, + 0x12, 0x24, 0x00, 0x82, 0x00, 0x22, 0xe0, 0x0b, + 0x94, 0x02, 0x2c, 0x20, 0x8a, 0x01, 0x22, 0x74, + 0x0b, 0x15, 0x22, 0xe6, 0x00, 0xba, 0xd4, 0x22, + 0xb4, 0x0d, 0xb0, 0x02, 0x20, 0x40, 0xb3, 0x40, + 0x2e, 0x64, 0x0b, 0xf4, 0x48, 0xbc, 0x00, 0x8b, + 0x00, 0x2f, 0xc1, 0x0a, 0xf4, 0x02, 0xee, 0x88, + 0x9f, 0x50, 0x2a, 0xc0, 0x0b, 0xa4, 0x02, 0xf2, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x05, + 0x48, 0x00, 0xb1, 0x43, 0x2c, 0xd0, 0x0b, 0x30, + 0x86, 0x08, 0x00, 0x81, 0x04, 0x00, 0x08, 0x0a, + 0x24, 0x02, 0x00, 0x00, 0x81, 0x00, 0x60, 0x90, + 0x09, 0x20, 0x02, 0x0a, 0x00, 0x21, 0x00, 0x20, + 0x50, 0x0a, 0x00, 0x06, 0x01, 0x40, 0x91, 0xc0, + 0x2c, 0x10, 0x09, 0x36, 0x02, 0x0c, 0x00, 0xb0, + 0x80, 0x24, 0xc0, 0x08, 0x30, 0x40, 0xed, 0x09, + 0x00, 0x72, 0x00, 0xc4, 0x10, 0x33, 0x40, 0x28, + 0x00, 0x8b, 0x14, 0x02, 0xf8, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x62, 0x01, 0x1e, 0x02, 0x85, + 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x06, 0x3a, 0x00, + 0x8d, 0x80, 0x21, 0x20, 0x0b, 0xe8, 0x02, 0x1a, + 0x00, 0xad, 0x92, 0x61, 0xa0, 0x0b, 0x68, 0x22, + 0xdb, 0x00, 0xb5, 0x90, 0x21, 0x60, 0x0b, 0x68, + 0x02, 0x12, 0x10, 0xb7, 0x88, 0x2d, 0x20, 0x09, + 0x79, 0x22, 0x9e, 0x00, 0x97, 0x90, 0x2d, 0xe0, + 0x0a, 0x79, 0x02, 0xde, 0x00, 0x93, 0x90, 0x29, + 0x20, 0x0b, 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x48, 0x28, 0x10, 0xf1, + 0x02, 0x7c, 0xc0, 0x0f, 0xb4, 0x03, 0x08, 0x00, + 0xc1, 0x00, 0x30, 0x40, 0x0f, 0x21, 0x03, 0x04, + 0x40, 0xa1, 0x00, 0x38, 0x88, 0x0f, 0x32, 0x03, + 0x08, 0x40, 0xf9, 0x44, 0x30, 0xc8, 0x0e, 0x90, + 0x23, 0x00, 0x00, 0xd3, 0x02, 0x3c, 0x0a, 0x0f, + 0x30, 0x03, 0x0c, 0x00, 0xf0, 0x10, 0x3e, 0xc0, + 0x0c, 0x31, 0x03, 0xc4, 0x00, 0xf3, 0x00, 0x30, + 0xc0, 0xcf, 0x00, 0x03, 0xd2, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xfd, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xd8, 0x00, + 0xfd, 0x00, 0x1f, 0x40, 0x0f, 0x60, 0x03, 0xdc, + 0x00, 0xd5, 0x00, 0x3f, 0x80, 0x4b, 0xf0, 0x03, + 0xf8, 0x40, 0xfd, 0x00, 0x3f, 0xc0, 0x05, 0xf1, + 0x03, 0xfc, 0x40, 0xff, 0x00, 0x3f, 0x40, 0x0f, + 0xf0, 0x81, 0x7c, 0x02, 0xef, 0x10, 0x3f, 0xc0, + 0x0e, 0xf1, 0x03, 0xfc, 0x40, 0xff, 0x00, 0x37, + 0xc0, 0x0f, 0xf0, 0x03, 0xd0, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x05, 0xe8, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0x80, 0x0f, 0xb0, 0x03, 0x60, + 0x00, 0xed, 0x09, 0x00, 0x73, 0x00, 0xbb, 0x00, + 0x3a, 0xc0, 0x0f, 0xa8, 0x02, 0x2c, 0x00, 0xfb, + 0x00, 0x3a, 0x40, 0x0c, 0x80, 0x03, 0xe2, 0x00, + 0xca, 0x00, 0x36, 0x00, 0x0c, 0xb8, 0x03, 0xac, + 0x84, 0xf3, 0x80, 0xb2, 0xe0, 0x0d, 0xb8, 0x03, + 0x2c, 0x00, 0xfb, 0x00, 0x32, 0x00, 0x1f, 0x90, + 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x12, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0x80, 0x0b, 0x70, 0x00, 0xd8, 0x00, 0x3f, 0x00, + 0x29, 0xc0, 0x0b, 0x60, 0x42, 0x1c, 0x00, 0xb7, + 0x00, 0x2b, 0x40, 0x4a, 0x60, 0x12, 0x54, 0x00, + 0xa7, 0x00, 0x21, 0x00, 0x08, 0x70, 0x02, 0x1c, + 0x40, 0x97, 0x00, 0x23, 0xd0, 0x0b, 0xf6, 0x02, + 0x1c, 0x00, 0xb7, 0x10, 0x35, 0x80, 0x0e, 0x50, + 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x00, 0x9a, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0b, 0x78, 0x00, 0xde, 0x00, 0xb7, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x02, 0xd6, 0x00, 0xa7, 0x81, + 0x29, 0xe0, 0x8b, 0xf8, 0x06, 0x9e, 0x08, 0xb7, + 0x84, 0x21, 0xe0, 0x08, 0x58, 0x02, 0x42, 0x00, + 0x86, 0x80, 0x24, 0x20, 0x08, 0x38, 0x02, 0x5e, + 0x40, 0xa7, 0x80, 0x29, 0xe1, 0x1a, 0x7a, 0x02, + 0x1e, 0x00, 0xb3, 0xb0, 0x21, 0x60, 0x0b, 0x78, + 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x14, 0xcc, 0x00, 0xb3, 0x80, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xe0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x22, 0xd8, 0x0b, 0x30, 0x02, 0x8d, 0x20, 0xb3, + 0x80, 0x28, 0xc0, 0x0a, 0x30, 0x46, 0xcc, 0x80, + 0xa3, 0x80, 0x26, 0xe4, 0x08, 0x30, 0x0a, 0x4c, + 0x00, 0xb3, 0x80, 0x28, 0xc0, 0x0a, 0x30, 0x0a, + 0x0e, 0x10, 0xb3, 0x00, 0xed, 0x09, 0x00, 0x74, + 0x00, 0x24, 0xe6, 0x02, 0x3d, 0x02, 0xd2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xa8, + 0x00, 0xfa, 0xa0, 0x3e, 0x80, 0x0b, 0xa0, 0x03, + 0xe8, 0x10, 0xf2, 0x00, 0x3e, 0xa8, 0x4f, 0xa0, + 0x03, 0x68, 0x00, 0xea, 0x00, 0x3a, 0x90, 0x0f, + 0xa0, 0x0b, 0xa9, 0x00, 0xfa, 0xa2, 0x3a, 0x80, + 0x0c, 0xa0, 0x07, 0xf9, 0x00, 0xce, 0xe4, 0x37, + 0xa0, 0x2c, 0xa0, 0x03, 0xe8, 0x00, 0xee, 0x24, + 0x3a, 0x80, 0x8f, 0xa0, 0x07, 0x38, 0x00, 0xfa, + 0x00, 0x03, 0x90, 0x0f, 0xe0, 0x13, 0xfa, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xe0, + 0x00, 0xf8, 0x02, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe2, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x88, + 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x8f, + 0x80, 0x01, 0x61, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x84, 0x03, 0x60, 0x04, 0xf8, 0x82, 0x3a, + 0x10, 0x0f, 0x80, 0x03, 0xa0, 0x00, 0xd8, 0x20, + 0x36, 0x00, 0x0b, 0x80, 0x07, 0xe0, 0x40, 0xf8, + 0x40, 0x3e, 0x00, 0x0f, 0x82, 0x03, 0xd2, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, + 0x00, 0xf9, 0x10, 0x32, 0x68, 0x0f, 0x98, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x32, 0x64, 0x0c, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x36, 0x40, 0x4c, + 0x94, 0x03, 0xe5, 0x10, 0xc9, 0x40, 0x32, 0x71, + 0x4c, 0x90, 0x03, 0xe7, 0x00, 0xd9, 0x00, 0x3e, + 0x70, 0x0c, 0x98, 0x03, 0xe4, 0x00, 0xf9, 0x42, + 0x3e, 0x40, 0x05, 0x9a, 0x03, 0xe4, 0x00, 0xf9, + 0x40, 0x32, 0x40, 0x0f, 0x92, 0x03, 0xc2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0xe4, + 0x00, 0xb9, 0xc2, 0x22, 0x70, 0x09, 0x94, 0x02, + 0xe4, 0x00, 0xb9, 0x00, 0x22, 0x50, 0x88, 0x94, + 0x02, 0xe6, 0x00, 0xb9, 0x00, 0x02, 0x50, 0xed, + 0x09, 0x00, 0x75, 0x00, 0x08, 0x98, 0x62, 0xc4, + 0x00, 0x89, 0x44, 0x22, 0x70, 0x08, 0x94, 0x02, + 0xe4, 0x05, 0xb1, 0x80, 0x2a, 0x48, 0x08, 0x9c, + 0x02, 0xe4, 0x00, 0xe9, 0x00, 0x2e, 0x40, 0x0f, + 0x94, 0x02, 0xe4, 0x04, 0xb1, 0x20, 0x36, 0x40, + 0x0b, 0x90, 0x82, 0xe0, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x04, 0x24, 0x00, 0xb5, 0x00, + 0x23, 0x41, 0x0b, 0xd1, 0x02, 0xf6, 0x00, 0x9d, + 0x80, 0xa1, 0x40, 0x08, 0xd8, 0x80, 0x74, 0x80, + 0xb5, 0x00, 0x27, 0x44, 0x08, 0xd0, 0x02, 0xf5, + 0x00, 0xa5, 0x00, 0x21, 0x40, 0x08, 0xd2, 0x02, + 0xe4, 0x24, 0xb9, 0x10, 0x6e, 0x40, 0x02, 0x92, + 0x82, 0xe4, 0x10, 0x39, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xa4, 0x00, 0xb9, 0x00, 0x22, 0x40, + 0x0b, 0x90, 0x22, 0xc6, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, 0xb5, 0x80, + 0x21, 0x60, 0x09, 0x58, 0x42, 0xd4, 0x00, 0xb5, + 0x00, 0x21, 0x60, 0x08, 0x50, 0x22, 0x54, 0x00, + 0xb5, 0x40, 0x21, 0x61, 0x08, 0x54, 0x02, 0xf5, + 0x00, 0xa5, 0x80, 0x21, 0x60, 0x2a, 0x54, 0x00, + 0xc4, 0x00, 0xb9, 0x00, 0x28, 0x51, 0x2a, 0x10, + 0x00, 0xc5, 0xa0, 0xb1, 0x01, 0x0c, 0x5a, 0x1b, + 0x14, 0x02, 0xc4, 0x04, 0xb1, 0x00, 0x24, 0x40, + 0x9b, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb8, 0x08, 0x20, 0x00, 0xf8, 0x00, + 0xb2, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xd8, + 0x00, 0x32, 0x00, 0x2c, 0x80, 0x43, 0xe0, 0x00, + 0xf8, 0x00, 0x36, 0x00, 0x2c, 0x80, 0x03, 0xe0, + 0x02, 0xe0, 0x00, 0xb2, 0x00, 0x08, 0xe0, 0x03, + 0xe0, 0x00, 0xba, 0x00, 0x3e, 0x01, 0x0e, 0x80, + 0x02, 0xe0, 0x80, 0xfa, 0x00, 0x3e, 0x08, 0xcd, + 0xa0, 0x03, 0xe0, 0x00, 0xf8, 0x02, 0x32, 0x00, + 0x0f, 0x80, 0xed, 0x09, 0x00, 0x76, 0x00, 0x03, + 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x1d, 0xe4, 0xb0, 0xf9, 0x28, 0x3e, 0x4a, 0x0f, + 0x92, 0x83, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x4a, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x02, 0x3e, + 0x4a, 0x0f, 0x10, 0x03, 0xe4, 0x00, 0x59, 0x2a, + 0x2e, 0x4b, 0x0d, 0x90, 0x13, 0x75, 0x00, 0xf5, + 0x02, 0x3f, 0x50, 0x0d, 0x94, 0x03, 0xe4, 0x00, + 0xef, 0x00, 0x3e, 0x40, 0x4c, 0x94, 0x23, 0xf4, + 0x00, 0xf9, 0x40, 0x3f, 0x50, 0x0f, 0xf4, 0x03, + 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x51, 0xe4, 0x04, 0xfd, 0x14, 0x33, 0x40, 0x0c, + 0xd0, 0x03, 0xf4, 0x00, 0xff, 0x00, 0x3f, 0x40, + 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xfb, 0x00, 0x3f, + 0x44, 0x1c, 0xd0, 0x03, 0xf4, 0x00, 0x6d, 0x12, + 0x2f, 0x40, 0x0c, 0xd0, 0x11, 0xb4, 0x81, 0xed, + 0x06, 0x3f, 0x4a, 0x09, 0xd0, 0x83, 0xa4, 0x00, + 0xcd, 0x00, 0x3e, 0x50, 0x0f, 0xd6, 0x43, 0xf4, + 0x00, 0xfd, 0x00, 0x32, 0x40, 0x0f, 0xd2, 0x03, + 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x39, + 0x10, 0xe0, 0x20, 0xb8, 0x00, 0x22, 0x0a, 0x08, + 0x82, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x3e, 0x82, + 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x20, 0x2e, + 0x08, 0x0a, 0x80, 0x80, 0xe0, 0x20, 0x88, 0x00, + 0x2e, 0x0b, 0x08, 0x82, 0x0a, 0x28, 0x40, 0xb8, + 0x01, 0x2e, 0x08, 0x0b, 0x84, 0x02, 0xa1, 0x02, + 0x88, 0x00, 0x2e, 0x04, 0x0b, 0x84, 0x02, 0xe0, + 0x08, 0xb8, 0x40, 0x22, 0x94, 0x0b, 0x85, 0x02, + 0x4e, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x05, 0xc4, 0x00, 0xa1, 0x00, 0x20, 0x48, 0x08, + 0x12, 0x82, 0xcc, 0x08, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc6, 0x00, 0xb1, 0x08, 0x24, + 0x48, 0x08, 0x12, 0x02, 0xc4, 0xed, 0x09, 0x00, + 0x77, 0x00, 0x00, 0xa1, 0x00, 0x2c, 0x49, 0x88, + 0xb2, 0x82, 0x04, 0x00, 0x91, 0x00, 0x2c, 0x4a, + 0x09, 0x10, 0x12, 0x04, 0xf0, 0x03, 0x00, 0x2c, + 0x40, 0x4b, 0x11, 0x22, 0xc4, 0x00, 0xb1, 0x44, + 0x20, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xa4, 0x00, + 0xb9, 0x05, 0x22, 0x40, 0x08, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x41, 0x4b, 0x90, 0x42, + 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0xc0, 0xca, 0x94, + 0x22, 0xcc, 0x00, 0x29, 0x00, 0x2e, 0x48, 0x48, + 0x94, 0x00, 0xa4, 0x80, 0xb9, 0x10, 0x6e, 0x48, + 0x8b, 0x90, 0x02, 0xa4, 0x00, 0x89, 0x10, 0x2e, + 0x40, 0x8b, 0xb0, 0x02, 0xe4, 0x40, 0xbb, 0x00, + 0x22, 0x40, 0x0b, 0x98, 0x12, 0x46, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x04, 0xa4, 0x00, + 0xf9, 0x00, 0xb2, 0x40, 0x2c, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x51, 0x0f, 0x90, 0x43, + 0xe4, 0x00, 0xf9, 0x00, 0x36, 0x40, 0x08, 0x90, + 0x02, 0xe4, 0x00, 0xe9, 0x00, 0x3e, 0x40, 0x2c, + 0x14, 0x03, 0xa7, 0x00, 0xd9, 0x80, 0x3e, 0x69, + 0x05, 0x10, 0x03, 0x24, 0x00, 0xc9, 0x80, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0xb2, 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0xa4, 0x00, + 0xf9, 0x00, 0x3e, 0x42, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3a, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x42, 0x4f, 0x90, + 0x03, 0xe4, 0x00, 0xd9, 0x00, 0x3e, 0x41, 0x0f, + 0x90, 0xc2, 0x66, 0x00, 0xf9, 0x88, 0x26, 0x60, + 0x0f, 0x90, 0x03, 0xc4, 0x00, 0xb9, 0x00, 0x3e, + 0x41, 0x0f, 0x90, 0x83, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x64, 0x0d, 0x90, 0x03, 0x4a, 0x00, 0x60, + 0xed, 0x09, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2a, 0x00, 0xa0, 0x00, 0xd8, 0x04, 0x3e, + 0x00, 0x0f, 0x81, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3a, 0x10, 0x2c, 0x88, 0x33, 0xe0, 0x04, 0xf8, + 0x01, 0x3e, 0x00, 0x0f, 0x81, 0x03, 0xe0, 0x82, + 0xc8, 0x14, 0x3e, 0x00, 0x0e, 0x80, 0x23, 0xe3, + 0x00, 0xf8, 0x00, 0x3a, 0x04, 0x0d, 0x89, 0x13, + 0xe0, 0x00, 0xd8, 0x20, 0x36, 0x01, 0x02, 0x80, + 0x63, 0xe0, 0x00, 0xa8, 0x04, 0xb2, 0x00, 0x0f, + 0x81, 0x0b, 0x0a, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x14, 0x28, 0x00, 0x8e, 0xe0, 0x2f, + 0x90, 0x0b, 0xed, 0x22, 0xe8, 0x00, 0xba, 0x00, + 0x3f, 0xb6, 0x08, 0xe4, 0x02, 0x6a, 0x80, 0xba, + 0x00, 0x2f, 0x90, 0x0b, 0xe8, 0x22, 0xf9, 0x00, + 0x8e, 0x54, 0x3f, 0x82, 0x0b, 0xe0, 0x00, 0xf8, + 0x20, 0xbe, 0x88, 0x23, 0x80, 0x4b, 0xe4, 0x02, + 0xe8, 0x00, 0x8e, 0x40, 0x3a, 0x80, 0x0b, 0xec, + 0x02, 0xe8, 0x08, 0xa6, 0x50, 0x22, 0x80, 0x0b, + 0xe0, 0x02, 0x0a, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x85, 0x4c, 0x00, 0x9b, 0x20, 0x2e, + 0xe0, 0x0b, 0x34, 0x02, 0xc4, 0x00, 0xb1, 0x00, + 0x2c, 0xf0, 0x08, 0x10, 0x02, 0xc6, 0x00, 0xb3, + 0x01, 0x0e, 0xc0, 0x5b, 0x3e, 0x22, 0x8f, 0x40, + 0x83, 0xc0, 0x2e, 0xd8, 0x0a, 0x30, 0x02, 0xce, + 0x00, 0xb3, 0xc0, 0x2c, 0xc0, 0x19, 0x30, 0x02, + 0xcc, 0x00, 0x83, 0x01, 0x2c, 0xc0, 0x0a, 0x34, + 0x02, 0xcc, 0x00, 0x83, 0x10, 0x20, 0xc0, 0x0b, + 0x30, 0x82, 0x0a, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x21, 0x01, 0x3e, 0x80, 0x87, 0x00, 0x2d, + 0xc2, 0x0b, 0x70, 0x06, 0xdc, 0x00, 0xb7, 0x40, + 0x2d, 0xe0, 0x08, 0x70, 0x82, 0x5c, 0x00, 0xb7, + 0x20, 0x2d, 0xd0, 0x4b, 0x70, 0x02, 0xfc, 0x04, + 0xa7, 0x00, 0x2d, 0xed, 0x09, 0x00, 0x79, 0x00, + 0xc0, 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xbf, 0x86, + 0x25, 0x00, 0x0b, 0x70, 0x02, 0xdc, 0x06, 0x97, + 0x00, 0x29, 0xc4, 0x03, 0x40, 0xc2, 0xde, 0x00, + 0xa3, 0x00, 0x61, 0xc0, 0x0b, 0x38, 0x02, 0x28, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, 0x48, + 0x1e, 0x80, 0xd7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, + 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3b, 0xe1, 0x1c, + 0x78, 0x02, 0xde, 0x00, 0xf7, 0xc0, 0x3d, 0xe0, + 0x0f, 0x78, 0x03, 0xde, 0x00, 0xc7, 0x80, 0x3d, + 0xe0, 0x0e, 0x58, 0x02, 0xde, 0x00, 0xf7, 0x80, + 0x3d, 0x20, 0x8d, 0x78, 0x03, 0xff, 0x82, 0xd7, + 0x82, 0x3d, 0xe0, 0x4e, 0x78, 0x23, 0xde, 0x00, + 0x47, 0x80, 0x31, 0xe0, 0x0f, 0x78, 0x13, 0x2a, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, + 0x8c, 0x40, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xb0, + 0x03, 0xec, 0x10, 0xfb, 0x00, 0x3a, 0xc0, 0x0f, + 0xb0, 0x03, 0x6c, 0x00, 0xfb, 0x48, 0x3e, 0x00, + 0x0f, 0xb0, 0x03, 0xc4, 0x00, 0xd9, 0x04, 0x3a, + 0x80, 0x0f, 0x80, 0x03, 0xec, 0x00, 0x73, 0x00, + 0x3a, 0x00, 0x0f, 0xb0, 0x03, 0xed, 0xa0, 0xe9, + 0x00, 0x3e, 0xc0, 0x0f, 0x80, 0x03, 0xcc, 0x00, + 0x7b, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xc2, + 0x12, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, + 0xfe, 0x00, 0xff, 0x80, 0x33, 0xe0, 0x0c, 0xf8, + 0x03, 0x1e, 0x00, 0xef, 0x80, 0x3f, 0xe0, 0x0c, + 0xf8, 0x03, 0xfe, 0x00, 0xcf, 0x80, 0x37, 0xe0, + 0x0f, 0xe8, 0x02, 0x3e, 0x00, 0xff, 0x90, 0x33, + 0xe0, 0x0f, 0x48, 0x02, 0x3e, 0x50, 0xf5, 0x10, + 0x3b, 0x60, 0x0f, 0xf9, 0x13, 0xfe, 0x08, 0xff, + 0x80, 0x33, 0xe0, 0x4d, 0xf8, 0x23, 0xde, 0x04, + 0x8f, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0x40, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x7a, 0x00, 0xa8, 0x19, 0x9c, 0x00, 0xbf, + 0x00, 0x23, 0xc0, 0x08, 0xf4, 0x02, 0x1c, 0x00, + 0x85, 0x00, 0x2f, 0x44, 0x08, 0x51, 0x00, 0xd4, + 0x00, 0x87, 0x00, 0x21, 0xc0, 0x4b, 0xe0, 0x02, + 0x1c, 0x80, 0xbf, 0x00, 0x29, 0x50, 0x0e, 0x44, + 0x03, 0x58, 0x04, 0x37, 0x60, 0x21, 0x04, 0x0b, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x01, 0x69, 0xc0, + 0x0b, 0x61, 0x02, 0x5c, 0x40, 0x85, 0x20, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0x6a, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x00, 0x9c, 0x00, 0xb7, + 0x00, 0x21, 0xc0, 0x08, 0x60, 0x02, 0x14, 0x00, + 0xa7, 0x00, 0x2d, 0x80, 0x08, 0x70, 0x02, 0xfc, + 0x00, 0x87, 0x00, 0x21, 0xc0, 0x0b, 0x40, 0x02, + 0x18, 0x04, 0xb6, 0x04, 0x21, 0xc0, 0x09, 0xc0, + 0x02, 0x15, 0x04, 0xb7, 0x40, 0x29, 0x00, 0x0b, + 0x60, 0x06, 0xdc, 0x00, 0xbe, 0x00, 0x25, 0xc0, + 0x0b, 0x50, 0x02, 0x7c, 0x00, 0x87, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0x40, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x62, 0x04, 0xcd, 0x80, 0xb3, + 0x00, 0x20, 0xc0, 0x08, 0x30, 0x42, 0x0c, 0x00, + 0x83, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xcc, + 0x00, 0x83, 0x00, 0x40, 0xc0, 0x0b, 0x00, 0x02, + 0x20, 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x0a, 0x00, + 0x0a, 0x00, 0x40, 0xb3, 0x80, 0x20, 0x20, 0x0b, + 0x20, 0x22, 0xcc, 0x08, 0xb0, 0xc4, 0x6c, 0xc0, + 0x09, 0x00, 0x42, 0x4e, 0x40, 0x80, 0x00, 0x2c, + 0xe2, 0x0b, 0x26, 0x22, 0x48, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0x05, 0xbd, 0x10, 0xfb, + 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0x2c, 0x00, + 0xeb, 0x00, 0x3e, 0xc0, 0x0c, 0xb0, 0x03, 0xcc, + 0x00, 0xcf, 0x00, 0xb2, 0xc0, 0x0f, 0x90, 0x03, + 0x2c, 0x04, 0xfb, 0x02, 0x32, 0xc0, 0x0d, 0x90, + 0x02, 0xed, 0x09, 0x00, 0x7b, 0x00, 0x0d, 0x00, + 0xfb, 0xc0, 0x1a, 0x58, 0x0f, 0x30, 0x03, 0xfc, + 0x04, 0xf3, 0x8a, 0x37, 0xc0, 0x0f, 0xb0, 0x03, + 0x6d, 0x00, 0xcb, 0x00, 0x3e, 0xf8, 0x0f, 0x3c, + 0x03, 0x6a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x10, 0xec, 0x00, 0xf9, 0x40, 0x3e, 0x50, + 0x0f, 0x94, 0x13, 0xe4, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb4, 0x03, 0xee, 0x04, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0x80, 0x0b, 0xe9, 0x00, 0xfb, + 0x40, 0x3e, 0xc0, 0x0f, 0x88, 0x03, 0xec, 0x00, + 0xfb, 0x10, 0x3e, 0x08, 0x07, 0xa4, 0x03, 0xec, + 0x00, 0xfa, 0x48, 0x3a, 0xc0, 0x0b, 0x90, 0x23, + 0x64, 0x80, 0xf3, 0x00, 0x3e, 0xc0, 0x0f, 0xb8, + 0x13, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x90, 0xfc, 0x00, 0xff, 0x10, 0x33, 0xe0, + 0x0c, 0xf1, 0x03, 0x3c, 0x00, 0xfd, 0x80, 0x3f, + 0xc8, 0x0c, 0xdc, 0x02, 0xb4, 0x00, 0xcf, 0x00, + 0x3f, 0xd0, 0x0c, 0xd0, 0x07, 0xfe, 0x00, 0xcf, + 0x80, 0x3f, 0xf0, 0x0f, 0xc0, 0x03, 0xff, 0x01, + 0xcf, 0x00, 0x2f, 0x00, 0x0c, 0xf2, 0x03, 0x3c, + 0x00, 0xdf, 0xa0, 0x31, 0xc0, 0x0c, 0x70, 0x03, + 0x3e, 0x00, 0xfe, 0x10, 0x33, 0xc0, 0x8f, 0xf4, + 0x23, 0x00, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x04, 0x6c, 0x00, 0xbb, 0xc8, 0x22, 0xd6, + 0x08, 0xb8, 0x02, 0x2c, 0x00, 0xbb, 0x90, 0x2e, + 0xf8, 0x08, 0x38, 0x02, 0x2e, 0x00, 0x8b, 0x00, + 0x2e, 0xc0, 0x0d, 0x88, 0x02, 0xe0, 0x40, 0x8b, + 0xd0, 0x2e, 0xd0, 0x0b, 0x8c, 0x02, 0xed, 0x04, + 0x8b, 0x00, 0x1e, 0x21, 0x0b, 0xac, 0x02, 0xac, + 0x04, 0x98, 0x48, 0x3e, 0xc0, 0x0d, 0x9c, 0x03, + 0xe6, 0x48, 0xb8, 0x40, 0x2a, 0xc0, 0x09, 0xb8, + 0x02, 0x20, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x04, 0x2c, 0x00, 0xed, 0x09, 0x00, 0x7c, + 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x08, 0x30, 0x02, + 0x2e, 0x00, 0xbb, 0x00, 0x2c, 0xc0, 0x08, 0xb0, + 0x82, 0x2c, 0x80, 0x8b, 0x00, 0x28, 0xc0, 0x08, + 0x88, 0x00, 0xe4, 0x00, 0x8b, 0x08, 0x2e, 0xc0, + 0x0b, 0x88, 0x02, 0xec, 0x20, 0x89, 0x00, 0x2e, + 0x60, 0x0b, 0xb4, 0x0a, 0x2c, 0x05, 0x99, 0x02, + 0x2a, 0xc0, 0x08, 0x88, 0x02, 0x2c, 0x00, 0xab, + 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x06, 0xa0, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x0c, + 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x08, 0x30, 0x12, + 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30, + 0x06, 0x2c, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x09, + 0x08, 0x02, 0xc0, 0x01, 0x83, 0x00, 0x2c, 0xc0, + 0x0b, 0x00, 0x62, 0x40, 0x02, 0x83, 0x02, 0x2c, + 0x00, 0x1b, 0x20, 0x02, 0x8c, 0x00, 0x98, 0x00, + 0x24, 0xc0, 0x09, 0x00, 0x02, 0xc4, 0x00, 0xb1, + 0x00, 0xa8, 0xc0, 0x09, 0x30, 0x02, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x6c, + 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, + 0x2c, 0x00, 0xbb, 0x00, 0x3e, 0xc0, 0x0c, 0xb0, + 0x03, 0x2c, 0x00, 0xc7, 0x00, 0x3a, 0xc0, 0x0c, + 0x80, 0x02, 0xe0, 0x10, 0xcb, 0x00, 0x3e, 0xc0, + 0x0f, 0x80, 0x02, 0xe0, 0x00, 0x8b, 0x02, 0x2e, + 0x00, 0x0e, 0x80, 0x03, 0x3c, 0x00, 0xd8, 0x00, + 0x3a, 0xc0, 0x0c, 0x90, 0x03, 0x2c, 0x00, 0xfa, + 0x01, 0x32, 0xc1, 0x0f, 0x90, 0x0b, 0x80, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xbc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xf4, 0x00, 0xfd, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, + 0x03, 0x54, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xc0, 0x03, 0xf0, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfe, 0x00, 0xed, + 0x09, 0x00, 0x7d, 0x00, 0x3b, 0x00, 0x07, 0xc0, + 0x0b, 0xfc, 0x00, 0xd4, 0x00, 0x3f, 0xc0, 0x0f, + 0xd0, 0x03, 0xb4, 0x00, 0xbc, 0x01, 0x1f, 0xc0, + 0x8f, 0xc0, 0x03, 0xe8, 0x02, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x05, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0x80, 0x81, 0xc1, 0x0b, 0x30, 0xc0, 0xef, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xef, 0x00, 0x33, 0xc0, 0x0c, 0xf0, 0x03, 0xfc, + 0x00, 0xfc, 0x00, 0x37, 0x80, 0x0f, 0xf0, 0x03, + 0x7c, 0x00, 0xdf, 0x00, 0x33, 0xc0, 0x0c, 0xf4, + 0x13, 0xbc, 0x40, 0xff, 0x00, 0x33, 0xd0, 0x0e, + 0xf0, 0x03, 0x70, 0x44, 0xec, 0x35, 0x33, 0x0c, + 0x0c, 0xc2, 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x10, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0x80, 0x0b, 0x82, 0x02, 0x01, 0xc0, 0x8b, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0xa0, 0xc0, 0x08, 0xb0, 0x06, 0xec, + 0x10, 0xb8, 0x00, 0x22, 0x80, 0x08, 0xb0, 0x02, + 0x3c, 0x04, 0x87, 0x00, 0x23, 0xc0, 0x08, 0xf2, + 0x02, 0x3c, 0x80, 0xbb, 0x00, 0x22, 0xc0, 0x0b, + 0xb0, 0x02, 0xc1, 0x80, 0xb9, 0x30, 0xa2, 0x18, + 0x48, 0x96, 0x82, 0xe0, 0x06, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x88, 0x05, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0x40, 0x0b, 0x88, 0x06, 0x0a, 0x04, 0x83, + 0x04, 0x28, 0xc0, 0x0b, 0x30, 0x02, 0xc4, 0x00, + 0xb3, 0x00, 0x20, 0xc0, 0x08, 0x30, 0x02, 0xcc, + 0x00, 0xb8, 0x00, 0x24, 0x80, 0x0a, 0x30, 0x02, + 0xcc, 0x00, 0x93, 0x00, 0x24, 0xc1, 0x08, 0x32, + 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x20, 0xc8, 0x0b, + 0x30, 0x02, 0x81, 0x80, 0x90, 0x20, 0x20, 0x0c, + 0x08, 0x21, 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x15, 0xac, 0x00, 0xbb, 0x00, + 0x2e, 0xc8, 0xed, 0x09, 0x00, 0x7e, 0x00, 0x8b, + 0x80, 0x02, 0x22, 0x10, 0x8b, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x10, 0xec, 0x48, 0xbb, 0x00, 0x22, + 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xba, 0x00, + 0x22, 0xe0, 0x08, 0xb2, 0x02, 0x8c, 0x00, 0x83, + 0x00, 0xa6, 0xc0, 0x1a, 0xb0, 0x02, 0x2c, 0x00, + 0xbb, 0x00, 0x22, 0xc0, 0x03, 0xb0, 0x02, 0xe8, + 0x01, 0xb3, 0x00, 0x20, 0x00, 0x08, 0x95, 0x02, + 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0x88, 0x03, 0x22, 0x02, 0xcb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xe9, 0x00, 0xe3, 0x00, 0x32, + 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xf0, 0xd8, + 0x34, 0x88, 0x0e, 0x30, 0x03, 0xec, 0x00, 0xdb, + 0x04, 0x16, 0xc0, 0x0c, 0xb0, 0x12, 0xac, 0x00, + 0xfb, 0x00, 0xb2, 0xc0, 0x0e, 0xb0, 0x43, 0x64, + 0x20, 0xea, 0x04, 0x32, 0x30, 0x24, 0x88, 0x03, + 0xd0, 0x44, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc2, 0x8f, + 0xc9, 0x03, 0xd4, 0x20, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xfa, 0x00, 0xff, 0x08, 0x3f, + 0xc0, 0x4f, 0xf0, 0x03, 0xfc, 0x00, 0xfc, 0x01, + 0x3f, 0xc0, 0x0e, 0xf8, 0x23, 0x7c, 0x00, 0xff, + 0x00, 0x0b, 0xc0, 0x2d, 0x70, 0x0b, 0xfc, 0x20, + 0xfb, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x02, 0x77, + 0x00, 0xfc, 0x01, 0x3f, 0xa4, 0x4f, 0xc8, 0x01, + 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0d, + 0x81, 0x83, 0x28, 0x00, 0xcb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xed, 0x00, 0xeb, 0x00, 0x3e, + 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xf8, 0x40, + 0x3a, 0xb2, 0x0c, 0xba, 0x03, 0x2c, 0x00, 0xdb, + 0x00, 0x3a, 0xc0, 0x0d, 0xb2, 0xed, 0x09, 0x00, + 0x7f, 0x00, 0x03, 0xec, 0x02, 0xcb, 0x00, 0x32, + 0xc0, 0x0d, 0xb0, 0x03, 0xe4, 0x22, 0xca, 0x00, + 0x3e, 0x50, 0x0c, 0xa4, 0x0b, 0x10, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, + 0xbb, 0x00, 0x2e, 0xe0, 0x88, 0x0c, 0x02, 0x25, + 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0xf0, 0x02, + 0xec, 0x00, 0x8b, 0x40, 0x2e, 0xc0, 0x08, 0xb0, + 0x02, 0xec, 0x08, 0xba, 0x00, 0x22, 0xc0, 0x08, + 0xb0, 0x00, 0xbc, 0x00, 0x8f, 0x00, 0x23, 0xc0, + 0x00, 0xf4, 0x82, 0xfe, 0x00, 0x8f, 0x00, 0x22, + 0xc0, 0x0b, 0xb0, 0x02, 0xef, 0x00, 0x8a, 0x00, + 0x2e, 0xd6, 0x08, 0x85, 0x02, 0x32, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, 0x00, + 0xb3, 0x00, 0x2c, 0xb4, 0x09, 0x0c, 0x02, 0x43, + 0x40, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xa3, 0x00, 0x2e, 0xc0, 0x08, 0x30, + 0x42, 0xcc, 0x00, 0xb1, 0x00, 0x28, 0x80, 0x08, + 0x34, 0x00, 0x0c, 0x00, 0x93, 0x00, 0x2a, 0xc0, + 0x09, 0x34, 0x02, 0xcf, 0x08, 0x8b, 0x00, 0x28, + 0xc0, 0x89, 0x30, 0x12, 0x48, 0x00, 0x80, 0x00, + 0x2c, 0xc0, 0x08, 0x00, 0x06, 0x30, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x1e, 0x00, + 0xb7, 0x80, 0x2d, 0xa4, 0x08, 0x48, 0x0a, 0x52, + 0x00, 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0xfe, 0x00, 0x07, 0x80, 0x2d, 0xe0, 0x28, 0x78, + 0x02, 0xde, 0x00, 0xbc, 0x90, 0x23, 0xac, 0x08, + 0xd9, 0x02, 0x1e, 0x00, 0x87, 0x80, 0x25, 0xe0, + 0x09, 0x78, 0x02, 0xde, 0x20, 0x87, 0x80, 0x29, + 0xf4, 0x8b, 0x78, 0x02, 0xd6, 0x20, 0x05, 0x80, + 0x2c, 0xe0, 0x2a, 0x38, 0x06, 0x88, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x0c, 0x00, + 0xf3, 0x00, 0x3c, 0xc0, 0x0d, 0x80, 0x03, 0x48, + 0xed, 0x09, 0x00, 0x80, 0x00, 0x42, 0xc3, 0x00, + 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcd, 0x40, 0xe3, + 0x00, 0x3c, 0xc0, 0x0c, 0x30, 0x03, 0xcc, 0x00, + 0xf1, 0x00, 0x38, 0xcc, 0x0c, 0x31, 0x13, 0x2c, + 0x00, 0xd3, 0x00, 0x7a, 0xc8, 0x0d, 0x30, 0x03, + 0xec, 0x00, 0xc3, 0x00, 0x38, 0xc0, 0x0d, 0x30, + 0x03, 0xc8, 0x00, 0xc0, 0x40, 0x3c, 0xc9, 0x8c, + 0x20, 0x03, 0x12, 0x02, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3d, + 0xc0, 0x0f, 0xc1, 0x03, 0xb8, 0x10, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x83, 0xd4, 0x10, 0xff, + 0x00, 0x3f, 0xc0, 0xaf, 0xf0, 0x03, 0xfc, 0x00, + 0xf4, 0x04, 0x3d, 0xcd, 0xaf, 0x71, 0x53, 0xfc, + 0x40, 0xff, 0x00, 0x33, 0xc0, 0x0e, 0xf0, 0x03, + 0xfc, 0x00, 0x7f, 0x00, 0x37, 0xc0, 0x0f, 0xf0, + 0x17, 0xfc, 0x0c, 0xef, 0x10, 0x3f, 0xc0, 0x0d, + 0xf0, 0x03, 0x50, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0c, 0x88, 0x03, 0x20, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0c, 0xb0, 0x43, 0xec, 0x00, + 0xfa, 0x80, 0x30, 0xe0, 0x0a, 0xa8, 0x03, 0xac, + 0xa0, 0xfb, 0xa8, 0x3e, 0xe6, 0x0e, 0xb3, 0x03, + 0x2c, 0xc0, 0xcb, 0x00, 0x3e, 0xe0, 0x84, 0xb0, + 0x01, 0xe8, 0x00, 0xfb, 0x00, 0x2e, 0x00, 0x0f, + 0x90, 0x03, 0xc2, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0d, 0xc0, 0x02, 0x10, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x72, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2f, 0xc0, 0x28, 0x70, 0x12, 0xdc, 0x00, + 0xb6, 0x00, 0x29, 0xc0, 0x28, 0x50, 0x02, 0x1d, + 0x00, 0xb7, 0x40, 0x2d, 0xc8, 0x08, 0x32, 0xea, + 0x0c, 0x20, 0xa7, 0xed, 0x09, 0x00, 0x81, 0x00, + 0x40, 0x2f, 0xc0, 0x88, 0x70, 0x02, 0xd4, 0x00, + 0x85, 0x00, 0x2d, 0x80, 0x0b, 0x70, 0x02, 0xd2, + 0x26, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x9e, 0x00, 0xb7, 0x80, 0x2b, 0xe0, 0x08, 0x48, + 0x02, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x28, 0x78, 0x42, 0xde, 0x00, 0xbc, 0x80, 0x29, + 0xe0, 0x2a, 0xf8, 0x02, 0x1e, 0x08, 0xb7, 0x00, + 0x25, 0xe8, 0x0a, 0x78, 0x02, 0x1c, 0x80, 0x87, + 0xa0, 0x2d, 0xe0, 0x08, 0x78, 0x02, 0xca, 0x10, + 0x97, 0x8e, 0x6d, 0x60, 0x0b, 0x78, 0x02, 0xc8, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, + 0xcc, 0x00, 0xb3, 0x00, 0x6c, 0xe4, 0x29, 0x30, + 0x12, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcd, 0x80, 0xb3, 0x00, 0x2e, 0xc0, + 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb0, 0x10, 0x28, + 0x40, 0x88, 0x34, 0x06, 0x0c, 0x04, 0xb3, 0x00, + 0x2c, 0xc0, 0x08, 0xb0, 0x02, 0x0c, 0x00, 0xa3, + 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xcd, 0x00, + 0xa3, 0xa0, 0x6c, 0xf4, 0x0b, 0x34, 0x02, 0xda, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x11, + 0xa8, 0x00, 0xfa, 0x00, 0x3d, 0x90, 0x08, 0xe4, + 0x8b, 0x38, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, + 0xa0, 0x03, 0xfb, 0x80, 0xfa, 0x00, 0x3e, 0x80, + 0x0c, 0xa0, 0x03, 0xe8, 0x00, 0xfe, 0xd0, 0x3b, + 0x90, 0x0e, 0xe4, 0x4b, 0x28, 0x00, 0xba, 0x00, + 0x36, 0x80, 0x0a, 0xa0, 0x03, 0x28, 0x00, 0xca, + 0x00, 0x3e, 0x80, 0x0c, 0xa0, 0x03, 0xf8, 0x41, + 0xfe, 0x01, 0x3f, 0x80, 0x47, 0xe0, 0x03, 0xfa, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x20, 0x0f, 0x8c, + 0x03, 0xe1, 0x80, 0xf8, 0x00, 0x3e, 0xed, 0x09, + 0x00, 0x82, 0x00, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x40, 0x3e, 0x00, 0x4f, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x21, 0x2f, 0x82, + 0x00, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x4f, + 0x84, 0x03, 0xe1, 0x00, 0xd8, 0x00, 0x3e, 0x00, + 0x2f, 0x80, 0x03, 0xc0, 0x01, 0xd0, 0x00, 0x3e, + 0x02, 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0e, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0x64, + 0x00, 0xf9, 0xa0, 0x3e, 0x40, 0x0e, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0d, 0x98, + 0x03, 0xe4, 0x02, 0xc1, 0x00, 0x22, 0x40, 0x0e, + 0x9c, 0x03, 0x27, 0x00, 0xb9, 0x00, 0x3e, 0x70, + 0x0f, 0x90, 0x03, 0x64, 0x00, 0xc9, 0x01, 0x32, + 0x44, 0x8f, 0x10, 0x81, 0x02, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, 0xb9, + 0x00, 0x2e, 0x60, 0x0c, 0x94, 0x82, 0xe5, 0x2c, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x12, 0xe4, + 0x00, 0xb9, 0x40, 0x2e, 0x40, 0x08, 0x90, 0x02, + 0xe4, 0x08, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xe4, 0x08, 0x89, 0x00, 0x22, 0x41, 0x0b, + 0x90, 0x02, 0x25, 0x00, 0xb9, 0x00, 0x2e, 0x60, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0x89, 0x30, 0x22, + 0x48, 0x0b, 0x90, 0x8a, 0x20, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, 0xb9, + 0x00, 0x2e, 0x48, 0x0a, 0x90, 0x02, 0xe6, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x08, 0x90, 0x42, + 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x61, 0x0b, 0xb2, + 0x02, 0xc4, 0x00, 0x89, 0x00, 0x2a, 0x40, 0x0b, + 0x94, 0x0a, 0x25, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0xed, 0x09, 0x00, 0x83, 0x00, 0x90, 0x02, + 0xe4, 0x00, 0x89, 0x00, 0x26, 0xc0, 0x01, 0x92, + 0x02, 0x0e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2e, 0xc0, + 0x09, 0x14, 0x02, 0xc5, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0x14, 0x02, 0xc4, 0x00, 0xb3, 0x00, + 0x2c, 0x50, 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc5, 0x04, + 0x81, 0x40, 0x28, 0x50, 0x8b, 0x14, 0x02, 0x05, + 0x00, 0xb1, 0x28, 0x2c, 0xd0, 0x0b, 0x10, 0x02, + 0xc5, 0x12, 0x81, 0x42, 0xa4, 0x50, 0x0b, 0x14, + 0x02, 0x8a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0e, 0x80, 0x43, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x88, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x02, 0x3e, 0x00, 0x0f, 0xa0, 0x13, 0xe0, 0x08, + 0xc8, 0x04, 0x38, 0x00, 0x0e, 0x80, 0x03, 0x20, + 0x00, 0xf8, 0x22, 0x3e, 0x00, 0x0f, 0x80, 0x23, + 0x60, 0x00, 0xc8, 0x00, 0x36, 0x00, 0x0f, 0x80, + 0x03, 0x2e, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3d, 0x40, + 0x0e, 0xd0, 0x43, 0xf5, 0x10, 0xf9, 0x00, 0x3e, + 0x40, 0x0f, 0x9c, 0x03, 0xf4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x2b, 0x90, 0x03, 0xe4, 0x00, 0xf5, + 0x01, 0x3f, 0xc0, 0x0f, 0x50, 0x13, 0xe5, 0x01, + 0xf9, 0x42, 0x36, 0x50, 0x0f, 0x94, 0x03, 0xe5, + 0x00, 0xf9, 0x28, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0x75, 0x00, 0xfd, 0x40, 0x3b, 0xd0, 0x0f, 0xd4, + 0x03, 0x66, 0x24, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x01, 0xe4, 0x00, 0xf9, 0x00, 0x3d, 0x40, + 0x0c, 0xd1, 0x03, 0x34, 0x80, 0xc9, 0x00, 0x3e, + 0x40, 0x07, 0x93, 0x03, 0xed, 0x09, 0x00, 0x84, + 0x00, 0x24, 0x00, 0xfd, 0x00, 0x3f, 0x40, 0x2c, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x31, 0xc0, + 0x0e, 0xd0, 0x03, 0xe4, 0x80, 0xf9, 0x28, 0x36, + 0x4c, 0x0e, 0xd0, 0x03, 0x74, 0x00, 0xc9, 0x28, + 0x3f, 0x40, 0x0f, 0x90, 0x03, 0xf4, 0xc0, 0xfd, + 0x01, 0x2f, 0x40, 0x8f, 0xd1, 0x03, 0xc6, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, + 0x00, 0xb8, 0x00, 0x2e, 0x01, 0x0d, 0x00, 0x02, + 0x20, 0xa0, 0x88, 0x00, 0x2e, 0x00, 0x0b, 0x83, + 0x22, 0x20, 0x00, 0xb8, 0x00, 0x2e, 0x0a, 0x08, + 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2a, 0x00, + 0x08, 0xa0, 0x02, 0xe0, 0xa5, 0xb8, 0x20, 0x2c, + 0x0d, 0x0e, 0x84, 0x82, 0xa0, 0x20, 0x88, 0x20, + 0x2e, 0x0a, 0x0b, 0x80, 0x02, 0xe0, 0xc0, 0xb8, + 0x48, 0x2e, 0x02, 0x0b, 0x01, 0x02, 0xce, 0x06, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, + 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x08, 0x90, 0x02, + 0x04, 0xc0, 0x81, 0x00, 0x2c, 0x40, 0x0b, 0x12, + 0x02, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x48, 0x08, + 0x10, 0x02, 0xc4, 0x00, 0xb9, 0x00, 0x20, 0x40, + 0x8a, 0x10, 0x02, 0xc4, 0xc0, 0xb1, 0x28, 0x28, + 0x48, 0x0a, 0x13, 0x02, 0x44, 0x50, 0x81, 0x28, + 0x2c, 0x48, 0x0b, 0x10, 0x40, 0x44, 0x80, 0xb1, + 0x30, 0x2c, 0x44, 0x0b, 0x10, 0x02, 0xd2, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, + 0x00, 0xb9, 0x04, 0x2e, 0x40, 0x09, 0xb0, 0x02, + 0x26, 0x0c, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0x25, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x08, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x01, 0x2a, 0x49, + 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x0e, + 0x40, 0x4a, 0x90, 0x02, 0xa4, 0x00, 0x89, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x84, 0xed, + 0x09, 0x00, 0x85, 0x00, 0xb9, 0x20, 0x2e, 0x40, + 0x03, 0x90, 0x02, 0xc6, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, 0x00, + 0x3c, 0x56, 0x0c, 0x94, 0x8b, 0x26, 0x82, 0xc9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x0b, 0x26, 0x04, + 0xb9, 0x04, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xe4, + 0x00, 0xf1, 0x10, 0x20, 0x50, 0x0a, 0x98, 0x03, + 0xe4, 0x00, 0xb9, 0x00, 0x36, 0x40, 0x0e, 0x90, + 0x03, 0x64, 0x02, 0xc9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x07, 0x98, 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x00, + 0x3e, 0x60, 0x0f, 0x99, 0x03, 0xc4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x40, + 0xf9, 0x00, 0x1e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x41, 0x0f, 0x94, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x1e, 0x40, 0x07, 0x90, + 0x07, 0x64, 0x00, 0xf9, 0x00, 0x1e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x91, 0x03, 0xd2, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, 0x00, + 0x3e, 0x08, 0x0c, 0x84, 0x03, 0x21, 0x20, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x23, 0xe1, 0x00, + 0xf8, 0x80, 0x32, 0x01, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x20, 0x4c, 0x88, 0x0b, + 0x20, 0x10, 0xf8, 0x00, 0x3a, 0x00, 0x0e, 0x00, + 0x23, 0xe0, 0x20, 0xc8, 0x00, 0x32, 0x08, 0x0f, + 0x80, 0x03, 0xe0, 0x20, 0xc8, 0x22, 0x3e, 0x11, + 0x0f, 0x82, 0x0b, 0x02, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x05, 0x28, 0x00, 0xba, 0x00, + 0x2f, 0x80, 0x28, 0x68, 0x82, 0x3a, 0x00, 0xba, + 0x00, 0x3a, 0x80, 0x0b, 0xa0, 0x03, 0xa8, 0x00, + 0xee, 0x40, 0xed, 0x09, 0x00, 0x86, 0x00, 0x2a, + 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x01, + 0x27, 0x91, 0x08, 0xe4, 0x02, 0x28, 0x00, 0x9a, + 0x00, 0x22, 0x81, 0x08, 0xe1, 0x03, 0xb9, 0x00, + 0xaa, 0x05, 0x23, 0x80, 0x0b, 0xa0, 0x02, 0xfb, + 0x10, 0x8e, 0xc0, 0x2f, 0x90, 0x0b, 0xec, 0x02, + 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xd4, 0x18, + 0x38, 0x02, 0x0f, 0x40, 0xb3, 0x04, 0x2c, 0xc0, + 0x0b, 0xb0, 0x02, 0x8c, 0x04, 0xb3, 0x00, 0x02, + 0xe4, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xe0, 0x08, 0x38, 0x02, 0x0c, 0x00, 0xb3, + 0x00, 0x28, 0xc0, 0x0a, 0x30, 0x02, 0xad, 0x00, + 0xa3, 0x00, 0xa0, 0xe0, 0x0b, 0x30, 0x02, 0xcf, + 0x00, 0x83, 0x81, 0x2c, 0xc8, 0x0b, 0x30, 0x02, + 0x0a, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x08, + 0x50, 0x02, 0x18, 0x00, 0xb7, 0x00, 0x29, 0xc0, + 0x0b, 0x72, 0x02, 0x9c, 0x00, 0xa7, 0x80, 0x29, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc2, 0x08, 0xf8, 0x82, 0x1c, 0x80, 0x97, + 0x80, 0x21, 0xe0, 0x08, 0x70, 0x02, 0x8c, 0x08, + 0xa3, 0xa0, 0x21, 0x90, 0x0b, 0x70, 0x00, 0xd6, + 0x2a, 0x87, 0x41, 0x2d, 0xc0, 0x0b, 0x68, 0x82, + 0x20, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x2d, 0xe0, 0x08, + 0x78, 0x03, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, + 0x0f, 0x7c, 0x03, 0x9e, 0x08, 0xf7, 0x82, 0x31, + 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, + 0x2d, 0xe0, 0x0c, 0x78, 0x03, 0x1f, 0x40, 0xff, + 0xf0, 0x39, 0xe8, 0x0e, 0x78, 0x03, 0x9e, 0x00, + 0xe7, 0xa4, 0x31, 0xe1, 0x0f, 0x78, 0x03, 0xfe, + 0x00, 0xc5, 0x80, 0x2d, 0xa0, 0xed, 0x09, 0x00, + 0x87, 0x00, 0x0f, 0x78, 0x03, 0x22, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, + 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0x80, 0x0b, 0xe4, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xac, 0x00, 0xf3, 0x00, 0x3e, 0xd0, 0x07, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x36, 0xc0, 0x2f, + 0x20, 0x03, 0xec, 0x80, 0xdb, 0x20, 0x3a, 0xd0, + 0x0f, 0x80, 0x03, 0xa0, 0x00, 0xfb, 0x10, 0x3e, + 0x80, 0x0f, 0xb0, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0xa0, 0x13, 0xc2, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xfe, 0x00, + 0xff, 0x80, 0x3d, 0xe0, 0x0c, 0xf8, 0x03, 0x3e, + 0x10, 0xcf, 0x80, 0x3f, 0xe0, 0x0f, 0xf2, 0x03, + 0xfe, 0x00, 0xef, 0x80, 0x33, 0x70, 0x2c, 0xf8, + 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0x60, 0x0f, + 0xe8, 0x43, 0xfe, 0x00, 0xcf, 0x80, 0x3f, 0xf2, + 0x0c, 0xe8, 0x03, 0xfa, 0x00, 0xff, 0x94, 0x3f, + 0xe0, 0x0f, 0xf8, 0x03, 0xfa, 0x00, 0xfe, 0x90, + 0x33, 0xe0, 0x0c, 0xd8, 0x03, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x19, 0x9c, 0x00, + 0xb7, 0x00, 0x2d, 0xc8, 0x08, 0x71, 0x8a, 0x18, + 0x40, 0x87, 0x00, 0x2d, 0xc0, 0x0e, 0x70, 0x42, + 0xdc, 0x10, 0xb7, 0x00, 0x21, 0x40, 0x28, 0x70, + 0x03, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0x82, 0x0b, + 0x40, 0x02, 0xdc, 0x40, 0xd7, 0x00, 0x2d, 0xc4, + 0x0d, 0x70, 0x02, 0xdc, 0x80, 0xf7, 0x30, 0x39, + 0xc4, 0x0b, 0x70, 0x02, 0xd4, 0x00, 0xb6, 0x00, + 0x23, 0x81, 0x0f, 0xd0, 0x03, 0xe2, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, + 0xb7, 0x00, 0x2f, 0xc0, 0x18, 0x70, 0x02, 0x18, + 0x02, 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x71, 0x02, + 0xdc, 0x00, 0xa6, 0x10, 0x21, 0x60, 0x09, 0x70, + 0xed, 0x09, 0x00, 0x88, 0x00, 0x02, 0xdc, 0x00, + 0xb7, 0x00, 0x2d, 0xc4, 0x0b, 0x60, 0x02, 0xcc, + 0x00, 0x87, 0x10, 0x2c, 0xc0, 0x08, 0x60, 0x02, + 0xd8, 0x04, 0xb7, 0x00, 0x6d, 0x40, 0x0b, 0x70, + 0x02, 0xd8, 0x00, 0xb5, 0x0e, 0x21, 0x82, 0x09, + 0x60, 0x02, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x04, 0xcc, 0x00, 0xb3, 0x00, 0x6c, + 0x40, 0x08, 0x24, 0x06, 0x0a, 0x00, 0x83, 0x00, + 0x2c, 0xc0, 0x0a, 0x30, 0x22, 0xce, 0x00, 0xb3, + 0x00, 0x22, 0x40, 0x09, 0x30, 0x02, 0x8c, 0x00, + 0xb3, 0x54, 0x2c, 0x88, 0x0b, 0x26, 0x02, 0xcc, + 0x00, 0x93, 0x04, 0x2c, 0xc0, 0x09, 0x80, 0x42, + 0xc0, 0x00, 0xa3, 0x00, 0x6a, 0x40, 0x0b, 0x30, + 0x02, 0xc5, 0x80, 0xb9, 0x0c, 0xa0, 0x00, 0x0b, + 0x2d, 0x02, 0x88, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x05, 0xac, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0c, 0xa0, 0x03, 0x2d, 0x80, 0xcb, 0x00, + 0x2e, 0xc0, 0x0f, 0xf0, 0x02, 0xec, 0x20, 0x69, + 0x02, 0xb2, 0x40, 0x2d, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x10, 0x3e, 0xe0, 0x0b, 0xb4, 0x83, 0xfc, + 0x18, 0xcf, 0x04, 0x3f, 0xc0, 0x08, 0x90, 0x03, + 0xe4, 0x00, 0xbf, 0x00, 0x3e, 0x40, 0x0f, 0xb0, + 0x42, 0xec, 0x20, 0xfb, 0x40, 0x32, 0x40, 0x0d, + 0xb0, 0x02, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xe0, 0x0f, 0x84, 0x83, 0xe8, 0x80, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf9, + 0x40, 0x36, 0x40, 0x2e, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x04, 0xf3, 0x02, 0x3e, 0xc1, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xfb, 0x00, 0x3e, 0x50, 0x4f, 0xb0, + 0x00, 0xe8, 0x00, 0xfb, 0x40, 0x3e, 0x40, 0x4c, + 0xa0, 0x23, 0xe0, 0xed, 0x09, 0x00, 0x89, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0c, 0xf9, + 0x03, 0x3c, 0x00, 0xcf, 0x00, 0x3f, 0xc0, 0xcf, + 0x70, 0x03, 0x7c, 0x00, 0xdf, 0x00, 0x33, 0x44, + 0x0c, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x33, + 0xf0, 0x0e, 0xfc, 0x13, 0xdc, 0x00, 0xcf, 0x00, + 0x31, 0xc0, 0x0c, 0xd0, 0x03, 0x34, 0x00, 0xf7, + 0x00, 0xb3, 0x00, 0x0c, 0xf0, 0x03, 0xbe, 0x04, + 0xda, 0xc2, 0x31, 0x80, 0x0e, 0xd1, 0x83, 0xc8, + 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, + 0x6c, 0x00, 0xbb, 0x00, 0x2c, 0xc0, 0x08, 0x8c, + 0x02, 0x26, 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x22, 0x0c, 0x00, 0x83, 0xf4, 0x36, 0x40, + 0x08, 0xb0, 0x03, 0xec, 0x00, 0xb3, 0x00, 0x36, + 0xe2, 0x0b, 0x80, 0x02, 0xec, 0x00, 0xab, 0x00, + 0x2a, 0xc1, 0x0a, 0x8c, 0x02, 0x23, 0x00, 0xbb, + 0x00, 0x22, 0x20, 0x08, 0xb0, 0x22, 0x69, 0x60, + 0x3a, 0x60, 0x22, 0x40, 0x08, 0x88, 0x02, 0xe8, + 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, + 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0x60, 0x08, 0x00, + 0x02, 0x0c, 0x80, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0x2c, 0x00, 0x99, 0x00, 0x22, 0xc0, + 0x18, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, + 0x80, 0x0b, 0xa0, 0x02, 0xec, 0x00, 0x8b, 0x00, + 0x22, 0xc0, 0x89, 0x9c, 0x02, 0x66, 0x20, 0xab, + 0x00, 0x22, 0x70, 0x08, 0xb0, 0x02, 0xe0, 0x00, + 0xb8, 0x00, 0x2a, 0x48, 0x88, 0x90, 0x12, 0xe0, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xe0, 0x08, 0x00, + 0x0a, 0x00, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0x2c, 0x08, 0x81, 0x00, 0x24, 0xc0, + 0x28, 0x30, 0x02, 0xcc, 0x00, 0xbb, 0xed, 0x09, + 0x00, 0x8a, 0x00, 0x00, 0x24, 0x80, 0x0b, 0x00, + 0x02, 0xcc, 0x08, 0xa3, 0x00, 0x28, 0xc0, 0x0a, + 0x10, 0x0a, 0x44, 0x00, 0xb3, 0x00, 0x20, 0x40, + 0x08, 0x30, 0x02, 0x40, 0x00, 0xb0, 0x00, 0x20, + 0x00, 0x18, 0x10, 0x02, 0xc2, 0x15, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xfb, + 0x00, 0x3e, 0x40, 0x0c, 0x10, 0x02, 0x08, 0x02, + 0xcb, 0x04, 0x2e, 0xc0, 0x0f, 0xb0, 0x02, 0x2c, + 0x04, 0xdb, 0x00, 0x31, 0xc0, 0x0c, 0xb0, 0x43, + 0xec, 0x00, 0xfb, 0x00, 0x32, 0x80, 0x0f, 0xa0, + 0x03, 0xfc, 0x00, 0xcf, 0x00, 0x33, 0xc0, 0x0d, + 0x90, 0x03, 0x64, 0x00, 0xfb, 0x01, 0x32, 0x00, + 0x2c, 0xb0, 0x03, 0xa0, 0x00, 0xd8, 0x00, 0xb2, + 0x80, 0x0e, 0x80, 0x03, 0xc0, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0x80, 0x0f, 0xc0, 0x03, 0xf0, 0x00, + 0xff, 0x00, 0x7f, 0xc0, 0x0b, 0xf0, 0x17, 0xbc, + 0x08, 0xf7, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xbc, 0x00, 0xff, 0x00, 0x3f, 0x80, 0x8f, 0xc0, + 0x03, 0xfc, 0x00, 0xff, 0x02, 0x3f, 0xc0, 0x0f, + 0xc0, 0x03, 0xb0, 0x00, 0xff, 0x00, 0x3f, 0x00, + 0x0f, 0xf0, 0x00, 0x70, 0x00, 0x7c, 0x00, 0x3f, + 0x00, 0x0f, 0xc0, 0x03, 0xe8, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x85, 0xfc, 0x00, 0xd5, + 0x12, 0x31, 0x44, 0x8f, 0xf0, 0x03, 0xfd, 0x00, + 0xcf, 0x00, 0x37, 0xc8, 0x0d, 0xf2, 0x03, 0xfc, + 0x80, 0xcf, 0x00, 0x33, 0x00, 0x0f, 0xf0, 0x03, + 0xd0, 0x00, 0xec, 0x01, 0x3f, 0xc8, 0x0c, 0xc0, + 0x03, 0x7c, 0xc0, 0xfc, 0x22, 0x33, 0x84, 0x0e, + 0xf3, 0x03, 0x30, 0x40, 0x3f, 0x20, 0x7b, 0xc2, + 0x0f, 0xf0, 0x83, 0xf0, 0x00, 0xcc, 0x00, 0x2f, + 0xca, 0x0b, 0xd2, 0x43, 0x30, 0x01, 0x70, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x8b, 0x00, 0x00, 0x00, + 0xc2, 0x18, 0xec, 0x00, 0xbb, 0x20, 0x22, 0xc8, + 0x0b, 0xf5, 0x03, 0x8c, 0x00, 0x8b, 0x02, 0x2f, + 0xd4, 0x0b, 0xf5, 0x22, 0xdc, 0x40, 0x8b, 0x04, + 0x22, 0x00, 0x0b, 0xb2, 0x82, 0xe0, 0x80, 0xb8, + 0x50, 0x2f, 0xce, 0x2a, 0x00, 0x02, 0x2d, 0xc0, + 0xc8, 0x68, 0x3e, 0x80, 0x0b, 0xf7, 0x42, 0x20, + 0x84, 0xbf, 0x40, 0x22, 0xd0, 0x0b, 0xb4, 0x02, + 0xe0, 0x02, 0x88, 0x20, 0x2e, 0xd2, 0x09, 0x91, + 0x02, 0x20, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x00, 0x8c, 0x08, 0x93, 0x20, 0x20, 0xc8, + 0x0b, 0x30, 0x22, 0xcc, 0x80, 0x83, 0x00, 0x2c, + 0xc0, 0x0a, 0x30, 0x02, 0xcc, 0x00, 0x83, 0x00, + 0x24, 0x00, 0x0b, 0x30, 0x10, 0xc0, 0xa0, 0xa0, + 0x00, 0x2c, 0xc8, 0x0b, 0x80, 0x02, 0x0c, 0x90, + 0x90, 0x10, 0x2c, 0x88, 0x0a, 0x30, 0x0e, 0x40, + 0x00, 0xb3, 0x10, 0x20, 0xc0, 0x0b, 0x30, 0x06, + 0xe2, 0x00, 0xa0, 0x08, 0x2c, 0xc8, 0x0b, 0x00, + 0x02, 0xa2, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x05, 0xec, 0x00, 0xb3, 0x80, 0x22, 0xe0, + 0x0b, 0xb0, 0x00, 0xec, 0x00, 0x8b, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0x8b, 0x20, + 0x26, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x80, 0xb9, + 0x80, 0x2e, 0xc0, 0x8b, 0xa0, 0x02, 0x2c, 0x00, + 0x89, 0x88, 0x2e, 0x90, 0x0b, 0x30, 0x22, 0x61, + 0x08, 0xbb, 0x00, 0x26, 0xc0, 0x1b, 0xb0, 0x46, + 0xe8, 0x40, 0x88, 0x08, 0x2e, 0xc0, 0x0b, 0x88, + 0x00, 0xb0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x15, 0xec, 0x00, 0xdb, 0x00, 0x32, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x01, 0xcb, 0x00, 0x36, + 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x04, 0xcb, 0x08, + 0x96, 0x26, 0x0f, 0xb8, 0x83, 0xed, 0x20, 0xe8, + 0xa0, 0x3e, 0xc0, 0x0d, 0xed, 0x09, 0x00, 0x8c, + 0x00, 0x84, 0x03, 0x6c, 0x00, 0xd8, 0x80, 0x2e, + 0xa0, 0x0e, 0xb0, 0x03, 0x66, 0x04, 0xfb, 0x00, + 0x32, 0xc0, 0x0b, 0xb0, 0x03, 0xc2, 0x00, 0xe8, + 0x80, 0x3e, 0xc0, 0x1f, 0x9c, 0x01, 0x90, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xbc, + 0x00, 0xff, 0x00, 0xbf, 0x40, 0x0f, 0xf0, 0x83, + 0xbc, 0x00, 0xff, 0x00, 0x37, 0xc0, 0x0f, 0xf0, + 0x23, 0xfc, 0x00, 0xf7, 0x80, 0x3b, 0x20, 0x0f, + 0xfa, 0x03, 0xfe, 0x10, 0xfd, 0x00, 0x3d, 0xc0, + 0x0c, 0xfc, 0x43, 0x9c, 0x00, 0xfc, 0x01, 0x3b, + 0xf0, 0x0f, 0xf0, 0x23, 0xb6, 0x40, 0xf7, 0x01, + 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xf4, 0x00, 0xfe, + 0x94, 0x3e, 0xc8, 0x4d, 0x50, 0x03, 0x78, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, + 0x00, 0xf9, 0x00, 0x32, 0xc0, 0x0c, 0xb8, 0x03, + 0xec, 0x00, 0xcb, 0x00, 0x3e, 0xe0, 0x0f, 0xb0, + 0x83, 0x2c, 0x00, 0xeb, 0x00, 0x32, 0xc0, 0x0f, + 0xb0, 0x03, 0x60, 0x80, 0xc8, 0x40, 0x3e, 0xc4, + 0x0e, 0x94, 0x03, 0x2c, 0x00, 0xf9, 0x40, 0x3a, + 0xd0, 0x0f, 0xb0, 0x03, 0xe5, 0x04, 0xeb, 0x00, + 0x32, 0xc1, 0x0f, 0xb1, 0x03, 0x6c, 0x20, 0xfa, + 0x41, 0x7e, 0xc0, 0x2c, 0xb0, 0x03, 0xd0, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x05, 0x2c, + 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x08, 0xf4, 0x02, + 0xec, 0x00, 0x8b, 0x00, 0x2f, 0xc0, 0x0b, 0xf6, + 0x02, 0x3e, 0x00, 0x8b, 0x80, 0x22, 0xd0, 0x0b, + 0xb0, 0x02, 0x20, 0x14, 0xa9, 0x00, 0x2f, 0xe0, + 0x1b, 0x3d, 0x82, 0x3e, 0x20, 0xb9, 0x09, 0x2e, + 0xc0, 0x48, 0xf0, 0x02, 0xec, 0x00, 0xbf, 0x5b, + 0x23, 0xe0, 0x1b, 0xfd, 0x02, 0xec, 0x80, 0xba, + 0x00, 0x22, 0xd4, 0x08, 0xb0, 0x02, 0xf2, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x04, 0xed, + 0x09, 0x00, 0x8d, 0x00, 0x4c, 0x00, 0xb3, 0x00, + 0x20, 0xc0, 0x48, 0x34, 0x02, 0xec, 0x00, 0x83, + 0x00, 0x2c, 0xc0, 0xcb, 0x30, 0x00, 0x2e, 0x04, + 0x83, 0x82, 0xac, 0x0c, 0x0b, 0x30, 0x02, 0x00, + 0x01, 0x80, 0x04, 0x2c, 0xc8, 0x0a, 0x00, 0x02, + 0x0f, 0x80, 0xb8, 0x20, 0x6c, 0x80, 0x0a, 0x30, + 0x42, 0xc8, 0x08, 0xa3, 0x80, 0xa0, 0xe0, 0x0b, + 0x3c, 0x02, 0x83, 0x00, 0xb0, 0x06, 0x28, 0xc0, + 0x18, 0x00, 0x20, 0xf8, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0x10, 0x5e, 0x00, 0xbd, 0x80, + 0xa3, 0xe0, 0x08, 0x78, 0x02, 0xde, 0x00, 0x87, + 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x0a, 0x1f, 0x28, + 0xa0, 0x80, 0x2d, 0xe0, 0x0b, 0x68, 0x22, 0x72, + 0x00, 0xa4, 0x80, 0x2d, 0xe4, 0x0b, 0x58, 0x02, + 0x1e, 0x00, 0xb7, 0x81, 0x2d, 0xe0, 0x08, 0x78, + 0x02, 0xda, 0x41, 0xb3, 0xb0, 0x21, 0xe2, 0x03, + 0x79, 0x00, 0xde, 0x00, 0xbe, 0x82, 0x21, 0x60, + 0x58, 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x08, 0x4c, 0x40, 0xf3, 0x00, + 0x30, 0x40, 0x0c, 0x31, 0x03, 0xcc, 0x00, 0xc3, + 0x00, 0x3c, 0xc0, 0x0f, 0xb0, 0x03, 0x0c, 0x00, + 0xe3, 0x09, 0x38, 0x00, 0x8f, 0xb0, 0x01, 0x0c, + 0x00, 0xc1, 0x04, 0x3c, 0xc1, 0x1e, 0x36, 0x23, + 0x0c, 0x40, 0xf2, 0x00, 0x3e, 0xc4, 0x0e, 0x31, + 0x03, 0xc8, 0x40, 0xe3, 0x30, 0x30, 0xc0, 0x0b, + 0x30, 0x03, 0x44, 0x10, 0xf2, 0x00, 0x78, 0x40, + 0x2c, 0x04, 0x43, 0xd2, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x15, 0xbc, 0x00, 0xff, 0x00, + 0x3f, 0xc4, 0x2b, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xd0, 0x0f, 0xf0, 0x0b, 0xfc, 0x08, + 0xdf, 0x02, 0x33, 0xc4, 0x0f, 0xf0, 0x03, 0xbc, + 0x08, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x20, 0xed, 0x09, 0x00, 0x8e, 0x00, 0xff, + 0x10, 0x37, 0xc0, 0x0e, 0xf4, 0x03, 0xfc, 0x40, + 0xff, 0x31, 0x3f, 0xc0, 0x8f, 0xf0, 0x46, 0xfc, + 0x00, 0xf6, 0x10, 0x3f, 0x44, 0x0f, 0xf1, 0x03, + 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0xac, 0x00, 0xfb, 0x80, 0xb2, 0xc0, 0x2c, + 0xb6, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc8, + 0x0f, 0xb2, 0x83, 0xed, 0x10, 0x8b, 0x04, 0x3e, + 0xe0, 0x0d, 0x90, 0x03, 0x0e, 0x10, 0xc9, 0x02, + 0x3a, 0xfc, 0x0c, 0xa0, 0x03, 0xec, 0x00, 0xdb, + 0x80, 0x1a, 0x00, 0x0f, 0xb1, 0x03, 0xec, 0x00, + 0xcb, 0x08, 0x32, 0xc4, 0x0f, 0xb0, 0x03, 0xa8, + 0x01, 0xf8, 0x00, 0x32, 0x40, 0x07, 0x80, 0x03, + 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0x98, 0x9c, 0x00, 0xbf, 0x00, 0x21, 0xc0, 0x08, + 0x76, 0xb2, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xd0, + 0x0b, 0x70, 0x13, 0x9d, 0xa0, 0xa7, 0x00, 0x2d, + 0xc0, 0x08, 0x30, 0x20, 0x1c, 0x00, 0xa7, 0x04, + 0x2f, 0xca, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x02, 0x19, 0xc1, 0x0f, 0x70, 0x02, 0xf4, 0x00, + 0x83, 0x41, 0x21, 0xc0, 0x8b, 0x74, 0x02, 0x9c, + 0x00, 0xf6, 0x00, 0x21, 0xc0, 0x0b, 0x50, 0x02, + 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x1e, 0x00, 0xb7, 0x80, 0x21, 0xe0, 0x0a, + 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe8, + 0x0b, 0x79, 0x02, 0x9e, 0x00, 0xa7, 0xc0, 0x2d, + 0xe0, 0x0b, 0x78, 0x4e, 0x3e, 0x00, 0x85, 0x80, + 0x29, 0xe0, 0x0a, 0x7c, 0x02, 0xde, 0x00, 0xb3, + 0x80, 0x61, 0xe2, 0x0b, 0x78, 0x32, 0xdb, 0x01, + 0x87, 0xa0, 0x21, 0xe8, 0x19, 0x7a, 0x06, 0x1e, + 0x10, 0xb6, 0xc2, 0x21, 0xe0, 0x0b, 0x68, 0x02, + 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x68, + 0x04, 0x8c, 0x00, 0xb1, 0x00, 0xed, 0x09, 0x00, + 0x8f, 0x00, 0x22, 0x40, 0x0a, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xac, 0x08, 0xa3, 0x00, 0x2c, 0xc6, 0x0b, 0x34, + 0x02, 0x0c, 0x48, 0xa3, 0x30, 0x2c, 0xc0, 0x4a, + 0x38, 0x02, 0xcc, 0x00, 0xb3, 0x24, 0x2c, 0xe0, + 0x4a, 0x30, 0x02, 0xcf, 0x89, 0x83, 0x01, 0x24, + 0xc0, 0x0b, 0x30, 0x02, 0x8c, 0x28, 0xb3, 0x00, + 0x22, 0xe4, 0x8b, 0x38, 0x02, 0xd2, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x15, 0xe8, 0x00, + 0xfa, 0x00, 0x32, 0x80, 0x0e, 0xa0, 0x03, 0xe8, + 0x04, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, + 0xe8, 0x04, 0xce, 0xc0, 0x3f, 0xa0, 0x0f, 0xee, + 0x02, 0x39, 0x00, 0xce, 0x00, 0x3a, 0x80, 0x4e, + 0xe1, 0x03, 0xe8, 0x00, 0x9e, 0x00, 0x3b, 0x90, + 0x03, 0xa0, 0x02, 0xfb, 0x02, 0xca, 0x05, 0xb2, + 0x80, 0x0f, 0xa0, 0x01, 0x98, 0x01, 0xbe, 0x40, + 0xb2, 0x80, 0x0f, 0xee, 0x03, 0xfa, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0xa0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0d, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x01, 0x1e, 0x00, 0x0f, 0x80, 0x03, + 0xa0, 0x00, 0xf8, 0x24, 0x2e, 0x00, 0x0c, 0x80, + 0x83, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x10, 0x29, + 0x84, 0x03, 0xe0, 0x10, 0xf8, 0x10, 0x3a, 0x20, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x02, 0x3a, + 0x00, 0x0f, 0x80, 0x13, 0xe0, 0x40, 0xe8, 0x80, + 0x7e, 0x00, 0x0f, 0x82, 0x07, 0xd2, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xa4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x82, 0x90, 0x03, 0x64, + 0x00, 0xe9, 0x00, 0x3e, 0x40, 0x0f, 0x10, 0x03, + 0x64, 0x00, 0xe9, 0x80, 0x3e, 0x44, 0x0f, 0x10, + 0x0a, 0xa4, 0x20, 0xf9, 0x00, 0x3e, 0x40, 0x0d, + 0x9c, 0x03, 0xe4, 0x80, 0xf9, 0x84, 0x3e, 0x40, + 0xed, 0x09, 0x00, 0x90, 0x00, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xc1, 0x40, 0xb6, 0x64, 0x0f, 0x90, + 0x03, 0x24, 0x80, 0xc9, 0x00, 0x32, 0x40, 0x48, + 0x90, 0x63, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x08, 0x10, 0x02, 0x24, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x09, 0x94, 0x02, 0x24, 0x00, 0xd9, + 0x80, 0x2e, 0x60, 0x8b, 0x90, 0x02, 0x64, 0x40, + 0xb9, 0x04, 0x2e, 0x40, 0x09, 0x9c, 0x42, 0xe6, + 0x00, 0x39, 0x89, 0x2c, 0x40, 0x08, 0x90, 0x02, + 0xe4, 0x00, 0xa9, 0x00, 0x22, 0x60, 0x0b, 0x19, + 0x22, 0x24, 0x00, 0x89, 0x00, 0x3a, 0x50, 0x68, + 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x08, 0x98, 0x02, 0x64, 0x00, 0xb9, 0x00, + 0x2e, 0x60, 0x1b, 0x98, 0x8a, 0x26, 0x00, 0x89, + 0x10, 0x2e, 0x40, 0x4a, 0x90, 0x02, 0x64, 0x08, + 0xb9, 0x00, 0x6e, 0x40, 0x09, 0x90, 0x02, 0xe4, + 0x00, 0xa9, 0x11, 0x2e, 0x40, 0x0b, 0x90, 0x02, + 0x44, 0x00, 0xa9, 0x00, 0x22, 0x42, 0x09, 0x90, + 0x02, 0x65, 0x04, 0x81, 0x00, 0x26, 0x50, 0x08, + 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x14, 0x04, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x28, 0x12, 0xa2, 0x04, 0x00, 0xb1, 0x00, + 0x6c, 0x4a, 0x0b, 0x12, 0x82, 0x04, 0xa4, 0x91, + 0x28, 0x2c, 0x40, 0x1b, 0x16, 0x82, 0x46, 0x00, + 0xb1, 0x00, 0x2c, 0xc0, 0x81, 0x30, 0x02, 0xc5, + 0x00, 0xb1, 0x28, 0x2e, 0x40, 0x28, 0x14, 0x06, + 0xc5, 0x00, 0xa3, 0x00, 0x60, 0x40, 0x4b, 0x10, + 0x02, 0x64, 0x00, 0x81, 0x40, 0x28, 0x50, 0x0a, + 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3c, + 0x00, 0x08, 0xa2, 0xed, 0x09, 0x00, 0x91, 0x00, + 0x03, 0x60, 0x00, 0xe8, 0x00, 0x3e, 0x08, 0x0f, + 0x82, 0x03, 0x08, 0x80, 0xc8, 0x20, 0x3e, 0x00, + 0x0f, 0x82, 0x07, 0x20, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0d, 0x80, 0x43, 0xe0, 0x00, 0xe8, 0x20, + 0x3e, 0x00, 0x2f, 0x80, 0x02, 0xe0, 0x02, 0xe8, + 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, 0x60, 0x02, + 0xc0, 0x00, 0x36, 0x00, 0x0c, 0x80, 0x03, 0xee, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x95, + 0xe4, 0x00, 0xfd, 0x28, 0x3f, 0x4a, 0x0d, 0x90, + 0x03, 0xe4, 0xa0, 0xf9, 0x00, 0x16, 0x40, 0x0d, + 0x92, 0x83, 0xe4, 0xa0, 0xfd, 0x00, 0x3d, 0x40, + 0x0f, 0xd0, 0x03, 0x34, 0xa0, 0xfd, 0x40, 0x3e, + 0x5a, 0x4f, 0xd2, 0x83, 0xe5, 0x00, 0xfd, 0x28, + 0x3f, 0x4a, 0x0f, 0x94, 0x03, 0xf5, 0x08, 0xd9, + 0x40, 0x3e, 0x50, 0x0f, 0x14, 0x0b, 0xb4, 0x00, + 0xfd, 0x00, 0x3b, 0x50, 0x0d, 0xd4, 0x13, 0xe6, + 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x11, + 0xe4, 0x00, 0xfb, 0x10, 0x3e, 0xc0, 0x0f, 0xd2, + 0x83, 0xe4, 0x44, 0xf9, 0x01, 0x3f, 0x40, 0x0c, + 0xd1, 0x0b, 0xb4, 0x90, 0xcd, 0x28, 0x33, 0x41, + 0x0e, 0x90, 0x23, 0x34, 0x10, 0xf9, 0x00, 0x3f, + 0x40, 0x0d, 0xd0, 0x0b, 0x74, 0xc0, 0xfd, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xbd, + 0x04, 0x35, 0x48, 0x1e, 0xd2, 0x83, 0x34, 0x01, + 0xd9, 0x00, 0x73, 0x40, 0x0e, 0x90, 0x23, 0xc6, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, + 0xe0, 0x00, 0xb8, 0x00, 0x0e, 0x0a, 0x0b, 0x80, + 0x02, 0xe0, 0x80, 0xb8, 0x00, 0x2e, 0x01, 0x08, + 0x81, 0x06, 0xa0, 0xa0, 0x8a, 0x00, 0x22, 0x00, + 0x88, 0x86, 0x02, 0x20, 0x20, 0xba, 0x10, 0x2e, + 0x0a, 0x1b, 0x02, 0x02, 0xa0, 0x80, 0xba, 0x49, + 0x2e, 0x00, 0x09, 0x84, 0x8a, 0x20, 0xed, 0x09, + 0x00, 0x92, 0x00, 0x24, 0xb8, 0x10, 0x22, 0x01, + 0x0d, 0x80, 0x0a, 0xa0, 0x04, 0xb8, 0x0a, 0x62, + 0x02, 0x28, 0x81, 0x02, 0xce, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x84, 0x00, 0xb1, + 0x00, 0x2c, 0x48, 0x0b, 0x10, 0x02, 0xc4, 0x80, + 0xb1, 0x04, 0x24, 0x44, 0x08, 0x30, 0x42, 0x84, + 0xc0, 0x81, 0x02, 0x0a, 0x41, 0x0a, 0x13, 0x82, + 0xc4, 0x00, 0xa1, 0x00, 0x24, 0x4c, 0x0b, 0x12, + 0x82, 0x04, 0xc0, 0xb1, 0x30, 0x2c, 0x4a, 0x0b, + 0x13, 0x02, 0x04, 0x4c, 0x91, 0x00, 0x28, 0x44, + 0x8a, 0x10, 0x00, 0x84, 0x00, 0xb1, 0x20, 0xa0, + 0x44, 0x00, 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x04, 0xa4, 0x00, 0xb9, + 0x00, 0x2e, 0x48, 0x0b, 0x90, 0x02, 0x64, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x68, 0x90, 0x06, 0xa4, + 0x00, 0x89, 0x00, 0xa2, 0x44, 0x00, 0x94, 0x02, + 0xec, 0x20, 0xb9, 0x00, 0x6e, 0x40, 0x8b, 0xb0, + 0x02, 0xe4, 0x00, 0xb9, 0x20, 0x6e, 0x58, 0x09, + 0x90, 0x02, 0x24, 0x00, 0xb9, 0x04, 0xaa, 0x40, + 0x09, 0x90, 0x00, 0xa4, 0x20, 0xb9, 0x40, 0x20, + 0x60, 0x0a, 0x98, 0x02, 0xc6, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x05, 0xe4, 0x00, 0xf9, + 0x80, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x02, 0xa4, + 0x04, 0x49, 0x84, 0x38, 0x48, 0x0e, 0x91, 0x0b, + 0xe4, 0x10, 0xf9, 0x00, 0x3e, 0x40, 0x09, 0x9c, + 0x83, 0x64, 0x00, 0xf9, 0x02, 0x3e, 0x60, 0x07, + 0x90, 0x03, 0xa4, 0x20, 0xf9, 0x00, 0x3a, 0x40, + 0x0a, 0x90, 0x03, 0xa4, 0x40, 0xb9, 0x80, 0x22, + 0x40, 0x0e, 0x92, 0x01, 0xe8, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x01, 0xa4, 0x00, 0xf9, + 0x20, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0xed, 0x09, 0x00, 0x93, 0x00, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x43, 0xc4, 0x22, 0xf1, 0x20, + 0x3e, 0x40, 0xcf, 0x10, 0x03, 0x24, 0x40, 0xf9, + 0x40, 0x3e, 0x40, 0x0f, 0x91, 0x03, 0xa4, 0x00, + 0xf9, 0x88, 0x3e, 0x40, 0x0f, 0x90, 0x23, 0xa4, + 0x48, 0xf9, 0x00, 0x36, 0x40, 0x0f, 0x10, 0x02, + 0xe6, 0x00, 0xf9, 0x20, 0x3e, 0x43, 0x0d, 0x90, + 0x03, 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x88, 0x03, 0x20, 0x00, 0xf8, 0x00, 0x3a, + 0x00, 0x0e, 0x82, 0x13, 0x60, 0x00, 0xc8, 0x40, + 0x3e, 0x20, 0x0f, 0x80, 0x03, 0x60, 0x00, 0xd8, + 0x00, 0x3e, 0x04, 0x0f, 0x84, 0xc3, 0x20, 0x00, + 0xf8, 0x40, 0x26, 0x10, 0x8e, 0x80, 0x43, 0xe1, + 0x00, 0xf8, 0x00, 0xb6, 0x20, 0x0c, 0x80, 0x43, + 0xa0, 0x40, 0xf8, 0x04, 0x32, 0x00, 0x08, 0x80, + 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x15, 0xa8, 0x00, 0x9a, 0x00, 0x2e, 0x80, + 0x0b, 0xe4, 0x02, 0x28, 0x04, 0xba, 0x00, 0x18, + 0x80, 0x08, 0xe4, 0x02, 0x39, 0x00, 0x8a, 0x80, + 0x6f, 0xb2, 0x0b, 0xa0, 0x02, 0x38, 0x82, 0x8a, + 0x00, 0x2f, 0x94, 0x0b, 0xe0, 0x03, 0x78, 0x80, + 0xbe, 0x00, 0x4e, 0x80, 0x08, 0xa0, 0x03, 0xa8, + 0x00, 0xb6, 0xa0, 0x21, 0x90, 0x88, 0xe0, 0x43, + 0x7a, 0x00, 0xba, 0x02, 0x23, 0xb0, 0x0a, 0xa0, + 0x02, 0xca, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x04, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x18, 0x02, 0x0c, 0x00, 0x93, 0x00, 0x28, + 0x60, 0x08, 0xb0, 0x02, 0x0e, 0x02, 0xa1, 0x12, + 0x2c, 0xc0, 0x0b, 0x30, 0x10, 0x0c, 0x28, 0xa3, + 0x00, 0x2c, 0xc0, 0x09, 0xbd, 0x02, 0x0e, 0x00, + 0xb3, 0x90, 0x2c, 0xc0, 0x09, 0xb0, 0x02, 0x8c, + 0x00, 0xb3, 0x88, 0x20, 0xed, 0x09, 0x00, 0x94, + 0x00, 0xe0, 0x1a, 0x39, 0x02, 0x0c, 0x00, 0xbb, + 0x00, 0x20, 0x40, 0x22, 0x30, 0x02, 0xca, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x5c, + 0x00, 0x97, 0x00, 0x2d, 0xc0, 0x0b, 0x7c, 0x02, + 0x9c, 0x00, 0xb7, 0x00, 0x28, 0xd0, 0x08, 0x70, + 0x02, 0x1d, 0x00, 0xa7, 0x00, 0x2d, 0x00, 0x0b, + 0x73, 0x02, 0x1e, 0x00, 0x87, 0x00, 0x0d, 0xc0, + 0x0b, 0x70, 0x22, 0x58, 0x00, 0x37, 0x01, 0x2f, + 0xe0, 0x0b, 0x71, 0x02, 0x9c, 0x04, 0xb3, 0x01, + 0x21, 0xc2, 0x1a, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x01, 0x02, 0x0a, 0x70, 0x02, 0xe8, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x5e, + 0x00, 0xf7, 0xf0, 0x3d, 0xe4, 0x0f, 0x38, 0x0b, + 0x1e, 0x20, 0xd7, 0x80, 0x39, 0xe0, 0x2c, 0x38, + 0x03, 0x0e, 0x00, 0xe7, 0x82, 0x2d, 0x60, 0x4f, + 0x3b, 0x0b, 0x7e, 0x00, 0xc7, 0x80, 0x0d, 0xe0, + 0x0f, 0x78, 0x13, 0x16, 0x10, 0xf7, 0x81, 0x2d, + 0xe2, 0x2e, 0x7a, 0x03, 0x9e, 0xa8, 0xf7, 0x80, + 0x31, 0xa0, 0x0e, 0x78, 0x03, 0x1e, 0x00, 0xff, + 0xe8, 0xa3, 0x20, 0x0c, 0x78, 0x03, 0xea, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1d, 0xac, + 0x00, 0xdb, 0x00, 0x3e, 0xc4, 0x0f, 0xb0, 0x03, + 0x6d, 0x80, 0x7b, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x0b, 0xac, 0x00, 0xd9, 0x00, 0x3e, 0x00, 0x0f, + 0xb2, 0x03, 0xec, 0x00, 0xeb, 0x01, 0x3e, 0xc0, + 0x0f, 0xb0, 0x00, 0xe0, 0x00, 0xfb, 0x00, 0x3c, + 0xd0, 0x4c, 0xb4, 0x83, 0xad, 0x00, 0xd8, 0x00, + 0x3a, 0x80, 0x6d, 0x30, 0x27, 0x68, 0x00, 0xfb, + 0x20, 0x3e, 0x40, 0x0f, 0xb0, 0x03, 0xc2, 0x06, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xbe, + 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, + 0xfe, 0x20, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xed, + 0x09, 0x00, 0x95, 0x00, 0xf0, 0x03, 0x7e, 0x04, + 0xd7, 0x80, 0x33, 0x20, 0x0d, 0xf8, 0x03, 0x3e, + 0x00, 0xff, 0x80, 0x7f, 0xe4, 0x4f, 0xf9, 0x23, + 0xfe, 0x00, 0xff, 0x02, 0x3f, 0xe2, 0x0d, 0xf9, + 0x03, 0x3e, 0x20, 0xcf, 0x80, 0xf3, 0xe1, 0x8d, + 0xf8, 0x03, 0xfe, 0x50, 0xff, 0x80, 0x3f, 0xe0, + 0x0e, 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xa9, 0x08, 0x9c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0e, 0x74, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0x40, 0x0b, 0x76, 0x12, 0xdc, 0x00, + 0xb7, 0x00, 0x21, 0x00, 0x0b, 0x70, 0x82, 0x1c, + 0x00, 0xb7, 0x18, 0x2d, 0x10, 0x0a, 0x73, 0x03, + 0x90, 0x00, 0xb7, 0x00, 0x2f, 0xc0, 0x09, 0x70, + 0x03, 0x5c, 0x40, 0xa7, 0x00, 0x21, 0xd8, 0x08, + 0x76, 0x02, 0x5c, 0x40, 0xb7, 0x00, 0x2f, 0xc0, + 0x0a, 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x09, 0x71, 0x06, 0x5c, 0x40, + 0xb7, 0x00, 0x21, 0x00, 0x09, 0x70, 0x02, 0x10, + 0x00, 0xb7, 0x00, 0x2c, 0xc0, 0x0a, 0x70, 0x42, + 0xd4, 0x40, 0xb6, 0x00, 0x29, 0xc0, 0x08, 0x70, + 0x06, 0x0c, 0x00, 0x83, 0x00, 0x21, 0x00, 0x89, + 0x50, 0x12, 0xd4, 0x00, 0xb7, 0x40, 0x2d, 0xc0, + 0x08, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x04, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0a, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x0c, 0xc0, 0x0b, 0x30, 0x12, 0xcc, 0x00, + 0xb3, 0x0a, 0x20, 0x08, 0x0b, 0x30, 0x02, 0x80, + 0x00, 0xb3, 0x48, 0x2c, 0x00, 0x0a, 0x32, 0x02, + 0xa0, 0x10, 0xb0, 0x10, 0x2c, 0xc2, 0x09, 0x30, + 0x06, 0x0d, 0x20, 0xa0, 0x00, 0x20, 0x80, 0x08, + 0x10, 0x00, 0xed, 0x09, 0x00, 0x96, 0x00, 0x40, + 0x00, 0x3b, 0x10, 0x2c, 0xc0, 0x08, 0x30, 0x82, + 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x15, 0xec, 0x00, 0xff, 0xa0, 0x3f, 0xe8, 0xcf, + 0xb0, 0x03, 0xfc, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0d, 0xb0, 0x03, 0x6c, 0x00, 0x5b, 0x48, 0xb0, + 0x10, 0x8d, 0xf0, 0x07, 0x24, 0x00, 0xfb, 0xc0, + 0x3e, 0x40, 0x07, 0xbe, 0x03, 0xe0, 0x01, 0xf9, + 0xd0, 0x3b, 0xd0, 0x0c, 0xf0, 0x02, 0x3e, 0x00, + 0xcb, 0x01, 0x72, 0xc0, 0x8d, 0xb0, 0x03, 0xce, + 0x00, 0xbf, 0x00, 0x3e, 0xc0, 0x0e, 0xb4, 0x03, + 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0x90, 0x00, 0xec, 0x04, 0xfb, 0x02, 0x3c, 0xc0, + 0x0f, 0xb4, 0x03, 0xe8, 0x00, 0xf3, 0x00, 0x3e, + 0x14, 0x0f, 0xb0, 0x8b, 0x60, 0x10, 0xfb, 0x00, + 0x3e, 0x40, 0x2d, 0xb4, 0x03, 0xa1, 0x10, 0xf8, + 0x00, 0x3e, 0xc4, 0x0e, 0x30, 0x33, 0xec, 0x40, + 0xfb, 0x40, 0x3e, 0xd0, 0x0f, 0x84, 0x03, 0xe6, + 0x20, 0xfb, 0x00, 0x3e, 0xa0, 0x0f, 0xb8, 0x13, + 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x10, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0x70, 0x07, 0x3c, 0x00, 0xff, 0x00, 0x3b, 0x40, + 0x0c, 0xf0, 0x03, 0xf4, 0x04, 0xff, 0x80, 0x33, + 0x24, 0x0d, 0xf0, 0x02, 0xf4, 0x08, 0xf7, 0x00, + 0x73, 0x00, 0x0f, 0xc0, 0x03, 0x70, 0x00, 0xcd, + 0x00, 0x3f, 0xc0, 0x0c, 0xb0, 0x03, 0x1c, 0x00, + 0xef, 0x00, 0x30, 0x80, 0x0c, 0xf8, 0x03, 0xfe, + 0x80, 0xcf, 0x00, 0x33, 0x90, 0x0e, 0xf0, 0x03, + 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa1, + 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb9, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x3e, 0xe4, + 0x08, 0xbc, 0x23, 0xad, 0x00, 0xed, 0x09, 0x00, + 0x97, 0x00, 0xbb, 0x80, 0x32, 0x28, 0x08, 0xb0, + 0x02, 0xe2, 0x00, 0xbb, 0x02, 0x22, 0x30, 0x4b, + 0x34, 0x62, 0x23, 0x00, 0x08, 0xe0, 0x26, 0xc0, + 0x08, 0xb0, 0x02, 0xec, 0x08, 0xa0, 0x90, 0x2a, + 0x84, 0x08, 0x81, 0x20, 0xe0, 0x00, 0x8b, 0x00, + 0x22, 0xc0, 0x0a, 0xb0, 0x02, 0xe0, 0x40, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, + 0x01, 0xbb, 0x00, 0x2e, 0xc0, 0x48, 0xb8, 0x42, + 0xec, 0x60, 0xb9, 0x20, 0x2a, 0x00, 0x0b, 0xb0, + 0x02, 0xe6, 0x00, 0xbb, 0x01, 0x2e, 0x60, 0x0b, + 0xb1, 0x02, 0x62, 0x20, 0x89, 0x82, 0x2c, 0xc0, + 0x08, 0xb0, 0x22, 0x2c, 0x08, 0x08, 0x40, 0x22, + 0x80, 0x08, 0xb0, 0x00, 0xec, 0x00, 0x8b, 0x00, + 0x20, 0xc0, 0x08, 0xb0, 0x02, 0xe0, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x0c, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x1b, 0x30, 0x02, 0x0c, + 0x01, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x12, + 0x8c, 0x00, 0xb3, 0x00, 0x22, 0x00, 0x0a, 0x30, + 0x02, 0xc0, 0x00, 0xb3, 0x00, 0x20, 0x00, 0x0b, + 0xb0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, + 0x08, 0x30, 0x12, 0x0c, 0x10, 0xa0, 0x00, 0x20, + 0x80, 0x08, 0x00, 0x42, 0x44, 0x00, 0x83, 0x01, + 0xa0, 0xc0, 0x0a, 0x30, 0x02, 0xc2, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x6c, 0x00, + 0xff, 0x00, 0x2f, 0xc0, 0x0f, 0xb0, 0x0a, 0x3c, + 0x00, 0xfb, 0x00, 0x3a, 0xc0, 0x2c, 0xb0, 0x03, + 0xec, 0x04, 0xfb, 0x00, 0xba, 0x00, 0x0f, 0x70, + 0x03, 0xe0, 0x10, 0xfb, 0x00, 0x1a, 0x00, 0x8f, + 0xb0, 0x03, 0x60, 0x02, 0xc8, 0x00, 0x3f, 0xc0, + 0x0c, 0xf0, 0x03, 0x3c, 0x00, 0xe8, 0x00, 0x32, + 0x80, 0x0c, 0x90, 0x03, 0xe4, 0x01, 0xcf, 0x00, + 0xed, 0x09, 0x00, 0x98, 0x00, 0x32, 0xc0, 0x0e, + 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa1, 0x11, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xc0, 0x23, 0xfc, 0x00, 0xff, 0x00, + 0x3b, 0x40, 0x0f, 0xc0, 0x03, 0xbc, 0x00, 0xfd, + 0x00, 0x3b, 0x00, 0x0d, 0xf0, 0x13, 0xf0, 0x00, + 0xff, 0x00, 0x3f, 0x00, 0x0f, 0xf0, 0x43, 0xf0, + 0x04, 0xfc, 0x01, 0x37, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xbc, 0x00, 0x3f, 0x80, 0x0f, 0xc0, + 0x03, 0xf0, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x43, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x05, 0xfc, 0x00, 0xfd, 0x24, 0x33, + 0x41, 0x0f, 0xc2, 0x03, 0x34, 0x41, 0xfd, 0x00, + 0x3f, 0xc0, 0x0d, 0xc0, 0x02, 0x3c, 0x00, 0xf7, + 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xf4, 0x00, + 0xfc, 0x00, 0x37, 0x84, 0x0c, 0x60, 0x03, 0xb0, + 0xd0, 0x3c, 0x00, 0x3f, 0xc4, 0x07, 0xf0, 0x02, + 0xfc, 0x00, 0xff, 0x00, 0x33, 0x00, 0x0f, 0xc0, + 0xa3, 0xf0, 0x20, 0xcc, 0x60, 0x33, 0x10, 0x2d, + 0xc2, 0x23, 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x10, 0xec, 0x00, 0xba, 0x10, 0x22, + 0xc0, 0x0b, 0x85, 0x02, 0x2c, 0x80, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0x80, 0x03, 0x6c, 0x00, 0xbb, + 0x20, 0x2c, 0x40, 0x08, 0xb0, 0x02, 0xe4, 0x00, + 0xba, 0x00, 0x22, 0x44, 0x08, 0xa0, 0x02, 0xe5, + 0x08, 0xb8, 0x50, 0x2f, 0xc8, 0x89, 0xb0, 0x12, + 0xec, 0x00, 0xb9, 0x00, 0x22, 0x54, 0x4b, 0xb4, + 0x02, 0xe5, 0x00, 0x89, 0x60, 0x22, 0x18, 0x08, + 0x90, 0x02, 0x20, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x88, 0x05, 0xcc, 0x00, 0xb1, 0x00, 0x20, + 0x40, 0x0b, 0x00, 0x02, 0x0c, 0x08, 0xb3, 0x00, + 0x2c, 0xc0, 0x48, 0x80, 0x42, 0x0c, 0x00, 0x93, + 0x08, 0x2c, 0x40, 0xed, 0x09, 0x00, 0x99, 0x00, + 0x09, 0x30, 0x02, 0xc0, 0x00, 0xba, 0x07, 0x20, + 0xc0, 0x89, 0x20, 0x02, 0x84, 0xc0, 0x90, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xbb, + 0x01, 0x24, 0x00, 0x0b, 0x02, 0x82, 0xc8, 0xa8, + 0x80, 0x40, 0x22, 0x8c, 0x08, 0x09, 0x02, 0x22, + 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, + 0xac, 0x01, 0xbb, 0x20, 0xa2, 0x70, 0x0b, 0x98, + 0x02, 0x24, 0x10, 0xbb, 0x40, 0x2e, 0xc0, 0x1b, + 0x90, 0x02, 0x6c, 0x00, 0xbb, 0x10, 0x0e, 0x40, + 0x09, 0xb2, 0x00, 0xe1, 0x00, 0xba, 0x88, 0x20, + 0x50, 0x09, 0xa2, 0x02, 0xe6, 0x20, 0xb8, 0x88, + 0x2e, 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00, 0xb9, + 0x00, 0x26, 0x62, 0x0b, 0xb0, 0x12, 0xe0, 0x00, + 0x88, 0x10, 0x22, 0x0a, 0x08, 0x90, 0x02, 0x30, + 0x05, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, + 0xec, 0x00, 0xf9, 0x84, 0x32, 0x30, 0x0f, 0x08, + 0x13, 0x2a, 0x30, 0xb8, 0x00, 0x2e, 0xc0, 0x0c, + 0xa0, 0x03, 0x2c, 0x00, 0xda, 0xa0, 0x3e, 0x40, + 0x0d, 0xb4, 0x82, 0xe4, 0x00, 0xf8, 0x80, 0x32, + 0x34, 0x0d, 0xae, 0x03, 0xa2, 0x10, 0xd9, 0xc0, + 0x3e, 0xc0, 0x0f, 0xb0, 0x41, 0xec, 0x00, 0xfa, + 0x00, 0x36, 0x30, 0x0f, 0x86, 0x03, 0xe0, 0x02, + 0xc8, 0x88, 0x32, 0x10, 0x2c, 0x88, 0x0b, 0x10, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, + 0xbc, 0x00, 0xfc, 0x00, 0x3f, 0x80, 0x0f, 0xc0, + 0x03, 0xf7, 0x00, 0xff, 0x20, 0x3f, 0xc0, 0x0f, + 0xf9, 0x03, 0xfc, 0x00, 0x7e, 0x00, 0x3f, 0xc0, + 0x0e, 0xf8, 0x03, 0x7c, 0x01, 0xfe, 0x01, 0xbb, + 0xe0, 0x2e, 0xe8, 0x43, 0xf4, 0x00, 0xf9, 0x00, + 0x3f, 0xc2, 0x8f, 0xf0, 0x13, 0xfc, 0x00, 0x7d, + 0xc0, 0x3b, 0x41, 0x0f, 0xa9, 0x03, 0xfc, 0x00, + 0xf9, 0x80, 0xbf, 0x20, 0x0f, 0xec, 0xed, 0x09, + 0x00, 0x9a, 0x00, 0x03, 0xf8, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, 0x00, 0xf9, + 0x00, 0x32, 0x00, 0x0f, 0x90, 0x03, 0xe0, 0x20, + 0xfa, 0xc6, 0x36, 0xc0, 0x0e, 0xa0, 0x07, 0xec, + 0x00, 0xba, 0xc0, 0x3a, 0xc0, 0x0c, 0xb0, 0x03, + 0x21, 0x00, 0xfa, 0x08, 0x32, 0x40, 0x2c, 0xb6, + 0x03, 0xa5, 0x00, 0xc9, 0x44, 0x32, 0xc0, 0x4f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32, 0x10, + 0x0f, 0x84, 0x0b, 0x0c, 0x04, 0xe2, 0x00, 0x32, + 0x90, 0x0d, 0x00, 0x03, 0xd0, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, 0xb1, + 0x00, 0x22, 0x34, 0x0b, 0x94, 0x02, 0xed, 0x01, + 0xbb, 0x80, 0x2e, 0xc0, 0x0b, 0x30, 0x02, 0xec, + 0x00, 0xba, 0x90, 0x36, 0xe2, 0x8d, 0xbd, 0x03, + 0x68, 0x00, 0xb2, 0x20, 0x36, 0xf8, 0x88, 0xb8, + 0x92, 0x25, 0x46, 0xa9, 0x00, 0x23, 0xd3, 0x0b, + 0xb0, 0x02, 0xec, 0x04, 0xb1, 0x00, 0x22, 0x40, + 0x4b, 0xa8, 0x02, 0x2e, 0x20, 0xba, 0x00, 0x20, + 0x08, 0x08, 0xa0, 0x02, 0xf2, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, 0x00, 0xb1, + 0x10, 0x20, 0x14, 0x0b, 0x30, 0x82, 0xca, 0x44, + 0xb1, 0x08, 0x2c, 0xc0, 0x0a, 0x00, 0x02, 0xcc, + 0x00, 0xb1, 0x00, 0x6a, 0xd2, 0x08, 0x20, 0x02, + 0x84, 0x00, 0xb2, 0x80, 0x20, 0x48, 0x88, 0x0c, + 0x02, 0x82, 0x40, 0xa1, 0x21, 0x20, 0xd0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0x93, 0x00, 0x20, 0x40, + 0x0b, 0x00, 0x02, 0x02, 0x00, 0xa2, 0x00, 0x20, + 0x40, 0x08, 0x20, 0x02, 0xf8, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x01, 0x1e, 0x00, 0xb2, + 0x80, 0x21, 0xa0, 0x0b, 0x78, 0x42, 0xde, 0x00, + 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x48, 0x02, 0xde, + 0x00, 0xbd, 0x80, 0x2d, 0x40, 0x09, 0x79, 0x0a, + 0xd6, 0xed, 0x09, 0x00, 0x9b, 0x00, 0x00, 0xb6, + 0x80, 0xa4, 0x60, 0x08, 0x78, 0x02, 0x16, 0x02, + 0xa6, 0x10, 0x21, 0xe0, 0x8b, 0x78, 0x02, 0xde, + 0x00, 0xb7, 0x80, 0x21, 0x61, 0x83, 0x58, 0x82, + 0x16, 0x00, 0xb7, 0xc0, 0xa1, 0xe0, 0x08, 0x58, + 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x08, 0x0c, 0x00, 0xf1, 0x00, 0x30, 0x00, + 0x0f, 0x34, 0x82, 0xc8, 0xc0, 0xb3, 0x00, 0x2c, + 0xc0, 0x0e, 0x20, 0x22, 0xcc, 0x48, 0xf3, 0x00, + 0x38, 0x44, 0x0c, 0x90, 0x83, 0x80, 0x00, 0xf2, + 0x10, 0x30, 0x44, 0xac, 0x01, 0x03, 0xa8, 0x44, + 0xc1, 0x10, 0xb0, 0xc0, 0x0f, 0x30, 0x03, 0xcc, + 0x40, 0xfb, 0x00, 0xb0, 0x88, 0x07, 0x21, 0x02, + 0x08, 0xc0, 0xe3, 0x00, 0x32, 0xc8, 0x0c, 0x20, + 0x23, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x10, 0x3f, 0x00, + 0x0f, 0xf0, 0x03, 0xfc, 0x40, 0xff, 0x10, 0x7f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x37, 0x40, 0x2f, 0xf0, 0x03, 0x70, 0x00, 0xf6, + 0x10, 0x3f, 0x44, 0x0f, 0xf0, 0x51, 0xf8, 0x40, + 0xdf, 0x34, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x10, 0xff, 0x00, 0x3f, 0x80, 0x0f, 0xf0, 0x03, + 0xf0, 0x40, 0xff, 0x10, 0x3f, 0xc0, 0x0e, 0xd0, + 0x13, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x05, 0xec, 0x00, 0xfb, 0x80, 0x32, 0x40, + 0x0f, 0x90, 0x03, 0xec, 0x04, 0xf1, 0x84, 0x32, + 0xc0, 0x0f, 0xa0, 0x03, 0xec, 0x00, 0xbb, 0x00, + 0x3e, 0x40, 0x0f, 0xa0, 0x1b, 0x86, 0x00, 0xca, + 0x81, 0x3e, 0xc0, 0x8f, 0x80, 0x03, 0xe8, 0x00, + 0xfb, 0x00, 0x2a, 0xc8, 0x0c, 0xb8, 0x01, 0x2c, + 0x00, 0xfa, 0x00, 0x3e, 0xc0, 0x0f, 0x90, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x20, 0x0c, 0xb0, + 0x03, 0xea, 0x00, 0x70, 0xed, 0x09, 0x00, 0x9c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, + 0x00, 0xb2, 0x00, 0x21, 0xc0, 0x0b, 0x50, 0x22, + 0xdc, 0x00, 0xb5, 0x00, 0x21, 0xc0, 0x0e, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x88, + 0x70, 0x02, 0x1c, 0x00, 0x86, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xbe, 0x00, 0x23, + 0xca, 0x28, 0xf0, 0x13, 0x5c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0xdc, 0x00, 0xb5, + 0x00, 0x2d, 0x80, 0x08, 0x70, 0x02, 0xd2, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, + 0x00, 0xb7, 0x88, 0x21, 0xe0, 0x0b, 0x58, 0x02, + 0xde, 0x20, 0xbf, 0x80, 0x25, 0xe0, 0x0b, 0x68, + 0x02, 0xde, 0x00, 0xb7, 0x86, 0x2d, 0xc0, 0x8b, + 0x18, 0x02, 0xb2, 0x00, 0xa6, 0x00, 0x2d, 0xe2, + 0x0b, 0x58, 0x02, 0x9e, 0x00, 0xb7, 0x80, 0x2d, + 0xe4, 0x88, 0x78, 0x02, 0x1e, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, + 0x80, 0x2c, 0xa0, 0x08, 0x78, 0x02, 0xf0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, + 0x00, 0xb3, 0x80, 0x24, 0xd8, 0x4b, 0x35, 0x02, + 0xcd, 0x00, 0xb3, 0x80, 0x20, 0xc0, 0x1b, 0x31, + 0x06, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xe0, 0x08, + 0x30, 0x02, 0x0e, 0x00, 0xa3, 0x60, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcd, 0x50, 0xb3, 0x00, 0x26, + 0xc0, 0x08, 0x30, 0x02, 0x4c, 0x00, 0xb3, 0x40, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xec, 0x50, 0xbb, + 0x80, 0x2c, 0x80, 0x68, 0x35, 0x02, 0xd2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xa8, + 0x00, 0xfe, 0x80, 0xb3, 0xa0, 0x0f, 0xe8, 0x03, + 0xf9, 0x00, 0xfe, 0x40, 0xb6, 0x80, 0x0f, 0xec, + 0x03, 0xe8, 0x00, 0xfe, 0xe0, 0x3e, 0xa8, 0x0f, + 0xe0, 0x03, 0xbb, 0x00, 0xee, 0x40, 0x3f, 0xed, + 0x09, 0x00, 0x9d, 0x00, 0xa0, 0x0f, 0xe4, 0x03, + 0xba, 0x00, 0xfe, 0x40, 0x3e, 0x80, 0x0c, 0xa0, + 0x03, 0x28, 0x00, 0xfe, 0x00, 0x3f, 0xa8, 0x0f, + 0xe0, 0x03, 0xfa, 0x00, 0xfe, 0x00, 0x3f, 0x94, + 0x0c, 0xec, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x00, + 0x3a, 0x04, 0x0f, 0x80, 0x83, 0xe0, 0x20, 0xf8, + 0xd0, 0x3e, 0x00, 0x0e, 0x88, 0x03, 0xe0, 0x00, + 0xf8, 0x80, 0x3e, 0x00, 0x4f, 0x80, 0x03, 0xe2, + 0x42, 0x98, 0x04, 0x3e, 0x00, 0x0f, 0x8c, 0x00, + 0xe1, 0x20, 0xf8, 0x58, 0x3a, 0x10, 0x0f, 0x80, + 0x03, 0xe0, 0x04, 0xf8, 0x08, 0x3e, 0x20, 0x07, + 0x04, 0x17, 0xe2, 0x00, 0xf8, 0x10, 0x3e, 0x10, + 0x0f, 0x80, 0x83, 0xd2, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x00, + 0x3c, 0x40, 0x0e, 0x10, 0x0b, 0x24, 0x04, 0xf9, + 0xc0, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3c, 0x40, 0x0d, 0x1a, 0x03, 0xa4, + 0x00, 0xf1, 0x01, 0x22, 0x44, 0x0f, 0x90, 0x03, + 0xc4, 0x00, 0xc9, 0xa0, 0x36, 0x40, 0x0c, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x83, 0x24, 0x04, 0xc9, 0x81, 0x32, 0x64, + 0x0f, 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, 0xb9, 0x02, + 0x2e, 0x60, 0x08, 0x9e, 0x02, 0x25, 0x00, 0xb9, + 0x48, 0x2e, 0x40, 0x0b, 0x98, 0x02, 0xe4, 0x00, + 0xb9, 0xd0, 0x2e, 0x40, 0xac, 0x98, 0x02, 0xa4, + 0x00, 0xb9, 0x04, 0x2a, 0x40, 0x1b, 0x9c, 0x02, + 0xe4, 0x02, 0x89, 0x20, 0x22, 0x40, 0x28, 0x90, + 0x02, 0xe4, 0x00, 0xe9, 0x00, 0x2e, 0x40, 0x0b, + 0x93, 0x02, 0x24, 0x00, 0x89, 0x40, 0xa2, 0x40, + 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x9e, 0x00, 0x18, + 0x04, 0x24, 0x00, 0xb9, 0x80, 0x2e, 0x44, 0x0a, + 0x91, 0x02, 0x26, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x98, 0x06, 0xe4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x08, 0x90, 0x02, 0xa4, 0x00, 0xb9, 0x20, + 0x2a, 0x40, 0x0b, 0x98, 0x02, 0xe4, 0x08, 0x81, + 0x00, 0x26, 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x24, + 0x00, 0x89, 0x10, 0x22, 0x50, 0x0b, 0x90, 0x02, + 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x60, 0x08, + 0x10, 0x02, 0x07, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x18, 0x02, 0xc4, 0x00, 0xb1, 0xc0, 0x2c, + 0x50, 0x49, 0x34, 0x02, 0x84, 0x00, 0xb1, 0x00, + 0x28, 0x50, 0x8b, 0x10, 0x02, 0xc5, 0x00, 0x01, + 0x40, 0x04, 0x50, 0x08, 0x14, 0x02, 0xc5, 0x00, + 0xa1, 0x04, 0x2c, 0x40, 0x0b, 0x14, 0x08, 0x0d, + 0x02, 0x81, 0x40, 0x20, 0x50, 0x0b, 0x10, 0x02, + 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, + 0x09, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0e, + 0x80, 0x03, 0x20, 0x00, 0xb8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3c, + 0x00, 0x2c, 0x80, 0x03, 0xa0, 0x00, 0xfa, 0x00, + 0x3a, 0x00, 0x0b, 0xa0, 0x03, 0xe8, 0x00, 0xc8, + 0x00, 0x36, 0x80, 0x0c, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x20, + 0x00, 0xca, 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, + 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x1d, 0xe4, 0x00, 0xfd, 0x40, 0x3f, 0x50, 0x0f, + 0xd4, 0x53, 0xf4, 0x14, 0xfd, 0x00, 0x3e, 0x40, + 0x0f, 0xd0, 0x03, 0xe4, 0x00, 0xfd, 0x00, 0x3f, + 0x50, 0x2e, 0xd4, 0x03, 0xf4, 0x00, 0xfd, 0x40, + 0x37, 0x50, 0x0f, 0xf0, 0x03, 0xed, 0x09, 0x00, + 0x9f, 0x00, 0xfd, 0x04, 0xfd, 0x40, 0x3a, 0x50, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xed, 0x6a, 0x3f, + 0x50, 0x0f, 0xd4, 0x03, 0xf5, 0x00, 0xfd, 0x40, + 0x3f, 0x50, 0x0f, 0xd4, 0x03, 0xe6, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, 0x00, + 0xfd, 0x28, 0x3f, 0x41, 0x0f, 0xd2, 0x03, 0xf4, + 0x00, 0xcd, 0x00, 0x32, 0x40, 0x07, 0xd0, 0x12, + 0x64, 0x00, 0xfd, 0x00, 0x2f, 0x50, 0x0f, 0xd0, + 0x03, 0x64, 0x00, 0xfd, 0x08, 0x3f, 0x42, 0x0c, + 0xd0, 0x03, 0xf5, 0x20, 0xfd, 0x60, 0x33, 0x4a, + 0x0f, 0x90, 0x42, 0xe4, 0x40, 0xf9, 0x08, 0x3e, + 0x42, 0x0f, 0x56, 0x03, 0xf4, 0xa0, 0xfd, 0x08, + 0x3f, 0x42, 0x0c, 0x90, 0x83, 0xc6, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x00, + 0xba, 0x40, 0x2e, 0x00, 0x0b, 0xa5, 0x12, 0xe0, + 0x84, 0x88, 0x00, 0x22, 0x00, 0x0b, 0x80, 0x02, + 0xe0, 0x00, 0xb8, 0x21, 0x2e, 0x14, 0x0b, 0x86, + 0x82, 0x28, 0x00, 0xb8, 0x40, 0x2e, 0x18, 0x28, + 0x80, 0x02, 0xe1, 0x88, 0xb8, 0x61, 0x36, 0x18, + 0x4b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x68, 0x2e, + 0x10, 0x0b, 0x86, 0x02, 0xc1, 0x80, 0xba, 0x40, + 0x2e, 0x10, 0x08, 0x84, 0x02, 0xce, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x50, 0x0b, 0x10, 0x12, 0xe4, + 0x30, 0x81, 0x00, 0xa8, 0x40, 0x09, 0x10, 0x02, + 0xc4, 0x00, 0xb1, 0x08, 0x2c, 0xc8, 0x0b, 0x14, + 0x02, 0x44, 0x00, 0xb1, 0x00, 0x2c, 0x42, 0x08, + 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x40, 0x20, 0x42, + 0x0b, 0x12, 0x82, 0x44, 0x88, 0xb1, 0x20, 0x2c, + 0x40, 0x0b, 0x14, 0x02, 0xc4, 0x20, 0xb1, 0x28, + 0x2c, 0x4a, 0x08, 0x10, 0x22, 0xc2, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, + 0xed, 0x09, 0x00, 0xa0, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x12, 0xe4, 0x01, 0x8b, 0x00, + 0x22, 0x40, 0x0b, 0x91, 0x82, 0xe4, 0x00, 0xb9, + 0x00, 0x2e, 0x60, 0x0b, 0x94, 0x0a, 0x64, 0x00, + 0xb9, 0x40, 0x2e, 0x42, 0x08, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x26, 0x40, 0x1b, 0x90, 0x02, + 0xe4, 0x08, 0xb9, 0x02, 0x2e, 0x40, 0x0b, 0x92, + 0x02, 0xe4, 0x64, 0xb9, 0x00, 0x2c, 0x41, 0x08, + 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, 0x40, 0x3e, + 0x60, 0x0f, 0x90, 0x02, 0xe6, 0x02, 0xc1, 0x90, + 0x3a, 0x40, 0x0d, 0x98, 0x02, 0x64, 0x08, 0xf9, + 0x00, 0x0e, 0x40, 0x0f, 0x90, 0x03, 0x64, 0x00, + 0xb9, 0xc0, 0x3e, 0x50, 0x0c, 0x94, 0x03, 0xe5, + 0x40, 0xf9, 0x48, 0x32, 0x40, 0x4f, 0x90, 0x03, + 0x64, 0x00, 0xf9, 0x60, 0x3e, 0x7c, 0x07, 0x90, + 0x03, 0xe5, 0x00, 0xf9, 0x80, 0x3e, 0x60, 0x2c, + 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, + 0x70, 0x0f, 0x9c, 0x03, 0xe4, 0x80, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x20, 0x3e, 0x40, 0x0f, 0x91, 0x03, 0xa4, 0x00, + 0xf9, 0x40, 0x3c, 0x40, 0x2f, 0x90, 0x03, 0xe6, + 0x00, 0xf1, 0x00, 0x3e, 0x41, 0x8f, 0x90, 0x43, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x21, 0x3e, 0x70, 0x4f, + 0x90, 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, 0x50, 0xb2, + 0x20, 0x0f, 0x8c, 0x03, 0xe0, 0x28, 0xc8, 0x80, + 0x3e, 0x00, 0x0f, 0x84, 0x53, 0x20, 0x08, 0xd8, + 0x00, 0x3e, 0x20, 0x0c, 0x00, 0x03, 0xe1, 0x00, + 0xf8, 0x83, 0x3e, 0x08, 0x0c, 0x88, 0x03, 0x20, + 0x08, 0xf8, 0x60, 0xed, 0x09, 0x00, 0xa1, 0x00, + 0x3e, 0x08, 0x0f, 0x80, 0x23, 0xe0, 0x00, 0xf8, + 0x40, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x21, 0x20, + 0xc8, 0x43, 0x3e, 0x00, 0x4e, 0x80, 0x03, 0xca, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x28, 0x00, 0xba, 0x80, 0x23, 0x90, 0x0b, 0xe4, + 0x82, 0xd8, 0x00, 0x8e, 0x40, 0x2e, 0x80, 0x0b, + 0xe6, 0x02, 0xa8, 0x00, 0xbe, 0x00, 0x2f, 0x80, + 0x08, 0xe0, 0x02, 0xe8, 0x00, 0xbe, 0x48, 0x2f, + 0x91, 0x28, 0xe6, 0x02, 0x38, 0x60, 0xbe, 0x00, + 0x2f, 0xb9, 0x0b, 0xa0, 0x22, 0xe8, 0x00, 0xba, + 0x00, 0x2e, 0x80, 0x0b, 0xe5, 0x52, 0x38, 0x00, + 0xce, 0xc0, 0x2f, 0x90, 0x08, 0xa0, 0x02, 0xca, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x4c, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x38, + 0x02, 0xcc, 0x04, 0x93, 0x04, 0x2c, 0xc0, 0x0b, + 0x36, 0x02, 0x0c, 0x00, 0x93, 0x80, 0x2c, 0xc0, + 0x0a, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0x40, 0x28, 0x18, 0x02, 0x0c, 0x00, 0xb3, 0xc0, + 0x2c, 0xe0, 0x8b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x24, 0x02, 0x0f, 0x00, + 0x93, 0xc8, 0x2c, 0xc8, 0xca, 0x30, 0x22, 0xca, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, + 0x1c, 0x00, 0xb1, 0x80, 0x21, 0x00, 0x0b, 0x60, + 0x02, 0xdc, 0x00, 0x95, 0x40, 0x2d, 0xc0, 0x0b, + 0xf8, 0x02, 0x9c, 0x00, 0xb7, 0x40, 0x2c, 0xe0, + 0x0a, 0x50, 0x00, 0xdc, 0x00, 0xb7, 0x00, 0x2c, + 0x90, 0x08, 0xd8, 0x02, 0x18, 0x00, 0xb7, 0x40, + 0x2d, 0x80, 0x0b, 0x72, 0x02, 0xdc, 0x80, 0xb7, + 0x34, 0x2d, 0xc0, 0x0b, 0x48, 0x02, 0x1f, 0x00, + 0x86, 0x09, 0x2f, 0x40, 0x08, 0x70, 0x02, 0xe8, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, + 0x1e, 0x00, 0xf5, 0x80, 0x31, 0x20, 0xed, 0x09, + 0x00, 0xa2, 0x00, 0x0f, 0x78, 0x03, 0xf2, 0x02, + 0xd7, 0x84, 0x3d, 0xe1, 0x0f, 0x78, 0x03, 0x1e, + 0x00, 0xd7, 0x80, 0x3d, 0xe0, 0x0e, 0x78, 0x03, + 0xde, 0x00, 0x77, 0x80, 0x3d, 0xe0, 0x2c, 0x78, + 0x0b, 0x1e, 0x04, 0xf7, 0x80, 0x3d, 0xe0, 0x5b, + 0x7a, 0x23, 0xde, 0xa0, 0xf7, 0x80, 0x3d, 0xe0, + 0x0f, 0x68, 0x03, 0x1e, 0x02, 0xd7, 0x80, 0x3d, + 0xe0, 0x0e, 0x78, 0x03, 0xea, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, 0xf9, + 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x13, 0xe0, 0x10, + 0xe9, 0x00, 0x3e, 0xc0, 0x0f, 0x30, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc1, 0x2d, 0xa0, 0x03, + 0xec, 0x00, 0xfb, 0x04, 0x3e, 0x80, 0x0f, 0x10, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb4, 0x03, 0xec, 0x00, 0xfb, 0x01, 0x3e, 0xc0, + 0x0f, 0xa0, 0x0b, 0xec, 0x00, 0xfa, 0x00, 0x3c, + 0xc0, 0x0f, 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xfd, + 0x80, 0x3f, 0xa0, 0x0f, 0xe8, 0x03, 0x3a, 0x80, + 0xc7, 0x90, 0xb3, 0xe4, 0x0b, 0x68, 0x03, 0x3e, + 0x00, 0xff, 0x80, 0x3b, 0xe0, 0x0c, 0xf8, 0x03, + 0x3e, 0x00, 0xff, 0x86, 0x3f, 0x20, 0x0c, 0xe8, + 0x03, 0x3e, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0c, + 0xfc, 0x83, 0xfe, 0x20, 0xcf, 0x80, 0x3f, 0xe4, + 0x0c, 0xf8, 0x03, 0xb2, 0x06, 0xad, 0x90, 0x31, + 0xe0, 0x0c, 0xf8, 0x03, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xb5, + 0x00, 0x2d, 0x10, 0x0b, 0x44, 0x92, 0x38, 0xa0, + 0x84, 0x18, 0xa9, 0xc4, 0x0b, 0x62, 0x03, 0x5c, + 0x00, 0xbf, 0x10, 0x29, 0x40, 0x88, 0xd0, 0x03, + 0x5c, 0x00, 0xb7, 0x00, 0x2d, 0xc4, 0x28, 0x40, + 0x02, 0x94, 0x00, 0xb7, 0x14, 0x2d, 0x00, 0x0d, + 0x70, 0xed, 0x09, 0x00, 0xa3, 0x00, 0x02, 0xfc, + 0x00, 0xd7, 0x10, 0x2d, 0xc0, 0x0d, 0x50, 0x02, + 0x18, 0xa0, 0x85, 0x04, 0x35, 0x50, 0x2d, 0x70, + 0x02, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x00, 0xb5, 0x00, 0x2d, 0x00, + 0x0b, 0x41, 0x02, 0x10, 0xc0, 0x86, 0x04, 0xa1, + 0xc0, 0x8b, 0x40, 0x62, 0x1c, 0x00, 0xb7, 0x00, + 0x29, 0xc0, 0x09, 0x70, 0x02, 0x1c, 0x00, 0xb7, + 0x40, 0x2d, 0x00, 0x2b, 0xe0, 0x02, 0x1c, 0x00, + 0xb7, 0x00, 0x2c, 0x84, 0x08, 0x70, 0x02, 0xdc, + 0x00, 0x87, 0x00, 0x2d, 0xc0, 0x19, 0x60, 0x02, + 0x94, 0x10, 0x86, 0x02, 0x23, 0x80, 0x08, 0x70, + 0x82, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x14, 0xcc, 0x00, 0xb1, 0x00, 0x2c, 0x80, + 0x0b, 0x20, 0x20, 0x22, 0x00, 0x81, 0x42, 0xa8, + 0xc0, 0x0b, 0x00, 0x02, 0x4c, 0x01, 0xb3, 0x00, + 0x20, 0x40, 0x09, 0x2d, 0x02, 0x4f, 0x40, 0xb3, + 0x10, 0x2e, 0xf4, 0x2b, 0x14, 0x06, 0x84, 0x20, + 0xb2, 0x04, 0x2c, 0x00, 0x09, 0x30, 0x02, 0xcc, + 0x00, 0x93, 0x00, 0x2c, 0xd0, 0x09, 0xac, 0x02, + 0x0e, 0x00, 0x82, 0x40, 0x24, 0xa0, 0x08, 0x38, + 0x42, 0x08, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x15, 0xac, 0x00, 0xf9, 0x60, 0x3e, 0xa0, + 0x8f, 0xb4, 0x03, 0x27, 0x00, 0x4b, 0x80, 0xb2, + 0xc0, 0x0f, 0x90, 0x02, 0x2c, 0x00, 0xfb, 0x00, + 0x2a, 0xc0, 0x8d, 0xb0, 0x03, 0x2d, 0x00, 0xfb, + 0x40, 0x3e, 0x50, 0x2f, 0xb0, 0x03, 0x25, 0x00, + 0xfb, 0xd8, 0x7e, 0x40, 0x0c, 0xf0, 0x03, 0xfc, + 0x00, 0xcf, 0x40, 0x2e, 0xc4, 0x0d, 0xa4, 0x43, + 0xae, 0x04, 0xcb, 0x04, 0xb2, 0x82, 0x08, 0xb9, + 0x0b, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0xec, 0x00, 0xf9, 0x00, 0x3e, 0x30, + 0x0f, 0xb0, 0x2b, 0xe8, 0xed, 0x09, 0x00, 0xa4, + 0x00, 0x00, 0xf9, 0x08, 0x3e, 0xc0, 0x0f, 0x92, + 0x03, 0xec, 0x00, 0xfb, 0x40, 0x3e, 0xe0, 0x6e, + 0xb4, 0x03, 0xec, 0x04, 0xfa, 0x40, 0x3e, 0x88, + 0x0c, 0xb7, 0x03, 0xe0, 0x08, 0xfb, 0x00, 0x3e, + 0x40, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0xa0, + 0x3e, 0xc0, 0x8f, 0x81, 0x8b, 0xe5, 0x28, 0xfa, + 0x08, 0x3a, 0x10, 0x0f, 0xb0, 0x43, 0xe0, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, + 0x00, 0xf5, 0x18, 0x33, 0x00, 0x8f, 0xa8, 0xa3, + 0xf0, 0x24, 0xcf, 0x00, 0x7f, 0xc0, 0x0f, 0xc2, + 0x03, 0x7c, 0x00, 0xff, 0x00, 0x30, 0xc0, 0x0c, + 0xf0, 0x83, 0x7c, 0x20, 0xcf, 0x80, 0x3f, 0x70, + 0x2c, 0xf0, 0x03, 0xd0, 0x00, 0xcf, 0x00, 0x3d, + 0x40, 0x0c, 0xf0, 0x03, 0x7c, 0x00, 0xc7, 0x00, + 0x32, 0xc0, 0x0f, 0xc4, 0x03, 0x28, 0x00, 0xfd, + 0x40, 0x3f, 0x00, 0x05, 0xb0, 0x01, 0xc0, 0x44, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, + 0x00, 0xb9, 0x00, 0x22, 0x90, 0x0b, 0xad, 0x42, + 0xe3, 0x20, 0x89, 0x80, 0x2e, 0xc0, 0x0b, 0x0a, + 0x02, 0x2c, 0x00, 0xb8, 0x18, 0x2a, 0xc0, 0x28, + 0xbd, 0x03, 0x4c, 0x00, 0x09, 0xa0, 0x2e, 0xa0, + 0x08, 0xb0, 0x82, 0xe2, 0x02, 0x8b, 0x86, 0x2e, + 0x69, 0x0a, 0xb0, 0x02, 0xac, 0x00, 0xab, 0x00, + 0x2a, 0xc0, 0x0b, 0x88, 0x02, 0x22, 0x04, 0xb8, + 0x80, 0x2e, 0x14, 0x0b, 0xb0, 0x02, 0xe0, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, + 0x00, 0xb9, 0x00, 0x22, 0x80, 0x0b, 0x80, 0x02, + 0xe6, 0x04, 0x9a, 0x10, 0x2e, 0xc0, 0x0b, 0x80, + 0x02, 0x6c, 0x00, 0xb3, 0x00, 0x22, 0xe0, 0x08, + 0x34, 0x02, 0x6c, 0x02, 0xab, 0x10, 0x2a, 0x00, + 0x0a, 0xa8, 0x02, 0xe6, 0x00, 0x9b, 0x21, 0x2e, + 0x60, 0x08, 0x30, 0x02, 0x0c, 0x00, 0x8b, 0xed, + 0x09, 0x00, 0xa5, 0x00, 0x00, 0x22, 0xc0, 0x0b, + 0xb0, 0x1a, 0x61, 0x80, 0xb9, 0x00, 0x2e, 0xc0, + 0x09, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb1, 0x04, + 0xa0, 0x00, 0x0b, 0x20, 0x02, 0xc8, 0x00, 0x93, + 0x00, 0x2c, 0xc0, 0x0b, 0x00, 0x02, 0x0c, 0x00, + 0xb3, 0x00, 0x28, 0xa0, 0x08, 0x30, 0x02, 0x6c, + 0x00, 0x83, 0x00, 0x2c, 0xc0, 0xb8, 0x20, 0x02, + 0x46, 0x00, 0x93, 0x00, 0x2c, 0x40, 0x0a, 0x30, + 0x02, 0x8c, 0x00, 0xa3, 0x00, 0x28, 0xc0, 0x8b, + 0x10, 0x02, 0x40, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x30, 0x02, 0xc2, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xf9, 0x00, + 0x32, 0x00, 0x0f, 0xa0, 0x03, 0xe0, 0x00, 0xdb, + 0x00, 0x2e, 0xc0, 0x0f, 0x80, 0x47, 0x6c, 0x08, + 0xf9, 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0x6c, + 0x00, 0xeb, 0x00, 0x3c, 0x00, 0x0c, 0xa0, 0x03, + 0xe0, 0x00, 0xd9, 0x00, 0x3e, 0x01, 0x0c, 0xf0, + 0x03, 0x7c, 0x00, 0xcb, 0x00, 0x32, 0xc0, 0x0f, + 0x80, 0x03, 0x60, 0x04, 0xf0, 0x00, 0x3e, 0x00, + 0x0d, 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xfd, 0x00, + 0x3f, 0x80, 0x03, 0xc0, 0x33, 0xf0, 0x0c, 0xec, + 0x00, 0x3f, 0xc0, 0x0b, 0xc0, 0x07, 0xfc, 0x00, + 0xfc, 0x00, 0x3f, 0x80, 0x2f, 0xf0, 0x0b, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0x60, 0x03, + 0xf0, 0x00, 0xec, 0x00, 0x3f, 0x00, 0x8f, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0x40, 0x03, 0xb0, 0x00, 0xfc, 0x00, 0x3f, 0x00, + 0x0f, 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x05, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc8, 0x4f, 0xf2, 0x43, 0xfc, 0x00, 0x7f, + 0x20, 0x3f, 0xed, 0x09, 0x00, 0xa6, 0x00, 0xc8, + 0x0f, 0xc1, 0x03, 0x34, 0x40, 0xdd, 0x10, 0x3f, + 0x40, 0x0e, 0xc3, 0x07, 0xfc, 0x01, 0xff, 0x42, + 0x2f, 0x08, 0x1f, 0xc0, 0x03, 0x7c, 0x00, 0xdc, + 0x20, 0x7f, 0x0a, 0x08, 0xc0, 0x03, 0xf0, 0x80, + 0xff, 0x34, 0x33, 0x00, 0x4c, 0xd3, 0x82, 0x30, + 0x80, 0xfc, 0x06, 0x33, 0xc0, 0x0c, 0x41, 0x43, + 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2f, 0xc4, 0x0b, + 0xf1, 0x02, 0xec, 0x00, 0xbf, 0x51, 0x2f, 0xd4, + 0x0b, 0xb2, 0x42, 0x2c, 0x80, 0xcb, 0x20, 0x3e, + 0x49, 0x0c, 0x82, 0x03, 0xfd, 0x04, 0xbf, 0x60, + 0x2e, 0x00, 0x4f, 0x80, 0x82, 0xbd, 0x40, 0xb8, + 0x69, 0x66, 0x08, 0x08, 0x80, 0x02, 0xe0, 0xa0, + 0x3f, 0x40, 0x2a, 0x00, 0x0d, 0x84, 0x02, 0x20, + 0xa0, 0xb8, 0x20, 0x22, 0xd4, 0x0a, 0xa2, 0x02, + 0x20, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, + 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x12, 0xcc, 0x10, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0xb0, 0x02, 0x2c, 0x01, 0x83, 0x00, 0x2c, + 0x4a, 0x0b, 0x04, 0x02, 0xcc, 0x40, 0xa3, 0x30, + 0x2c, 0x04, 0x0b, 0x90, 0x12, 0x0c, 0x20, 0x90, + 0x10, 0x2c, 0x0a, 0x08, 0x00, 0x02, 0xc0, 0xc0, + 0xb3, 0x10, 0x20, 0x81, 0x08, 0x10, 0x02, 0x80, + 0xd0, 0xb0, 0x08, 0x20, 0xc0, 0x08, 0x12, 0x12, + 0x22, 0x11, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0x89, 0x00, 0x22, + 0xc4, 0x1a, 0x8c, 0x22, 0xac, 0x00, 0xbb, 0x02, + 0x2e, 0x62, 0x08, 0x80, 0x22, 0xec, 0x04, 0xb9, + 0x80, 0x26, 0x60, 0x08, 0x88, 0x80, 0xe3, 0x00, + 0xbb, 0x02, 0x2e, 0xc0, 0x09, 0xed, 0x09, 0x00, + 0xa7, 0x00, 0x88, 0x22, 0x22, 0x00, 0xba, 0x08, + 0x22, 0x22, 0x0a, 0xb0, 0x22, 0x30, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0x0c, 0x02, 0xcb, 0x80, 0x6e, 0x40, 0x0f, 0x88, + 0x02, 0xec, 0x00, 0xfb, 0x00, 0x1e, 0x20, 0x0b, + 0x28, 0x03, 0x6c, 0x04, 0xd8, 0xc1, 0x2e, 0x30, + 0x2c, 0x94, 0x03, 0xe2, 0x00, 0xfb, 0x00, 0x30, + 0x10, 0x0c, 0x9a, 0x0b, 0xa3, 0x00, 0xf8, 0x50, + 0x22, 0xd0, 0x0c, 0xb1, 0x83, 0x10, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xbc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf1, 0x03, + 0xf5, 0x00, 0xef, 0x40, 0x3f, 0x60, 0x0d, 0xd0, + 0x03, 0xfc, 0x00, 0xff, 0x02, 0x3f, 0x00, 0x8f, + 0xc4, 0x03, 0xbc, 0x10, 0xfc, 0x0a, 0x35, 0x02, + 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xdb, 0x04, 0x3b, + 0x08, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0xff, 0x00, + 0xbf, 0x40, 0x0f, 0xf8, 0x03, 0xf8, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, 0x00, + 0xfb, 0x00, 0x3e, 0xc1, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x10, 0x3e, 0xc0, 0x2c, 0x90, 0x43, + 0xec, 0x00, 0xdb, 0x00, 0x32, 0xc8, 0x0f, 0x94, + 0x03, 0xec, 0x98, 0xfb, 0x02, 0x3e, 0x51, 0x4f, + 0xb0, 0xa3, 0xec, 0x20, 0xf9, 0x01, 0x3e, 0x70, + 0x0f, 0x94, 0x03, 0xe4, 0x00, 0xfb, 0x00, 0xb2, + 0xc0, 0x0f, 0x94, 0x83, 0xe1, 0x80, 0xf9, 0x40, + 0x30, 0xf0, 0x0c, 0xbc, 0x03, 0x10, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, + 0xbb, 0x00, 0x2f, 0xf4, 0x0b, 0xf0, 0x42, 0xec, + 0x00, 0xbf, 0x00, 0x2f, 0xe0, 0x08, 0x30, 0x42, + 0xed, 0x09, 0x00, 0xa8, 0x00, 0xec, 0x00, 0x8b, + 0x00, 0x32, 0xc0, 0x0b, 0x90, 0x03, 0xbc, 0x28, + 0xbf, 0xd8, 0x2e, 0x41, 0x43, 0x88, 0x02, 0xfc, + 0x20, 0xb9, 0x48, 0x2e, 0x50, 0x0b, 0xb1, 0x83, + 0xe4, 0x00, 0xbf, 0xc8, 0x32, 0xf4, 0x0b, 0xb0, + 0x23, 0xa6, 0x00, 0xbb, 0x05, 0x22, 0x80, 0x08, + 0xb9, 0x02, 0x32, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x02, + 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xa3, + 0x00, 0x2e, 0x40, 0x8b, 0x00, 0x00, 0x8d, 0x00, + 0xb3, 0x40, 0x2c, 0x00, 0x03, 0x04, 0x02, 0xcf, + 0x00, 0xb0, 0x00, 0x2c, 0x00, 0x0b, 0x20, 0x02, + 0xc0, 0x80, 0x9b, 0x08, 0x20, 0x90, 0x0b, 0x8c, + 0x02, 0xc1, 0x00, 0xba, 0x00, 0x20, 0xc0, 0x08, + 0xb0, 0x02, 0x38, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x01, 0x1e, 0x00, 0xb7, 0x84, 0x2d, + 0xe3, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, + 0x2c, 0xe2, 0x08, 0x58, 0x02, 0xde, 0x00, 0x87, + 0x80, 0x25, 0xe0, 0x0b, 0x79, 0x02, 0x9e, 0x01, + 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x82, 0xde, + 0x01, 0xb7, 0x80, 0x2d, 0xe0, 0x1b, 0x68, 0x02, + 0xde, 0x00, 0xb7, 0x90, 0x25, 0xe2, 0x0b, 0x48, + 0x82, 0x92, 0x20, 0xbf, 0x80, 0x21, 0x20, 0x08, + 0xf8, 0x02, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, + 0xc0, 0x0f, 0x30, 0x02, 0xcc, 0x00, 0xf3, 0x00, + 0x2c, 0xc0, 0x0c, 0x30, 0x03, 0xe4, 0x02, 0xeb, + 0x00, 0xb4, 0x44, 0x0f, 0x10, 0x03, 0x8c, 0x00, + 0xf3, 0x10, 0x2c, 0x80, 0x0f, 0x15, 0x02, 0xcc, + 0x00, 0xf0, 0x40, 0x2c, 0x18, 0x0f, 0x22, 0x03, + 0xcc, 0x00, 0xd3, 0x02, 0x70, 0x84, 0x0f, 0x31, + 0x03, 0xc1, 0x00, 0xed, 0x09, 0x00, 0xa9, 0x00, + 0xf3, 0x02, 0x70, 0xc0, 0x0c, 0x31, 0x03, 0x12, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, + 0xbc, 0x00, 0x7f, 0x00, 0x3f, 0xd2, 0x0f, 0xf1, + 0x03, 0xfc, 0x00, 0xff, 0x08, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xef, 0x00, 0x3b, 0xc0, + 0x0f, 0xf0, 0x03, 0xbc, 0x40, 0xff, 0x00, 0x3f, + 0xc0, 0x07, 0xf1, 0x03, 0xfc, 0x45, 0xff, 0x12, + 0x3f, 0xc0, 0x07, 0xd0, 0x13, 0xbc, 0x40, 0xff, + 0x01, 0x3b, 0xc0, 0x0f, 0xc0, 0x13, 0xb4, 0x00, + 0xf7, 0x10, 0x3d, 0xc4, 0x0f, 0xf0, 0x03, 0xd0, + 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc8, 0x4c, 0xb0, + 0xc0, 0xec, 0x00, 0xfb, 0x20, 0x36, 0xdc, 0x0b, + 0xb0, 0x03, 0xec, 0x00, 0xf9, 0x00, 0x3e, 0xc0, + 0x0f, 0x80, 0x22, 0xed, 0x41, 0xfb, 0x18, 0x3e, + 0x60, 0x0c, 0xa0, 0x03, 0xed, 0x80, 0xdb, 0x81, + 0x36, 0xc1, 0x1d, 0xb8, 0x03, 0xe2, 0x00, 0xcb, + 0x30, 0x32, 0xc0, 0x0f, 0x80, 0x03, 0xe2, 0x00, + 0xca, 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0xea, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, + 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc8, 0x08, 0x70, + 0x02, 0xdc, 0x10, 0xb7, 0x30, 0x2d, 0xc2, 0x0b, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x04, 0x2d, 0xc0, + 0x46, 0x70, 0x02, 0x1c, 0xa0, 0xb7, 0x24, 0x6d, + 0xc0, 0x05, 0x70, 0x02, 0xdd, 0xa5, 0x87, 0x00, + 0x29, 0xc0, 0x03, 0x60, 0x02, 0xdc, 0x00, 0xa3, + 0x30, 0x25, 0xc0, 0x0b, 0x70, 0x02, 0xd0, 0x00, + 0xaf, 0x00, 0x20, 0x00, 0x08, 0x70, 0x02, 0xd2, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x08, 0x79, + 0x02, 0x5e, 0x04, 0xb7, 0xa2, 0x2d, 0xe0, 0x09, + 0x78, 0x72, 0xde, 0x08, 0xb7, 0x80, 0xed, 0x09, + 0x00, 0xaa, 0x00, 0x2d, 0xf1, 0x03, 0x18, 0x02, + 0x1e, 0x18, 0x97, 0x82, 0x2d, 0xc0, 0x0a, 0x78, + 0x82, 0xce, 0x80, 0xb3, 0x82, 0x21, 0xe0, 0x19, + 0x70, 0x02, 0xce, 0x00, 0x87, 0xa2, 0xa5, 0xe0, + 0x1b, 0x78, 0x02, 0xca, 0x00, 0x87, 0x80, 0x21, + 0xe0, 0x08, 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x28, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x98, 0x02, 0xc6, + 0x40, 0xb1, 0x90, 0x2c, 0xe0, 0x0a, 0xb0, 0x02, + 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xd0, 0xcb, 0x30, + 0x02, 0xec, 0x00, 0x83, 0x00, 0x28, 0xc8, 0x0b, + 0x39, 0x02, 0xcd, 0x00, 0xa3, 0x00, 0x24, 0xd0, + 0x0b, 0x31, 0x02, 0xcc, 0x80, 0xa3, 0xc0, 0x20, + 0xc0, 0x08, 0x39, 0x02, 0xd2, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x0c, 0xa0, 0x03, 0x68, 0x00, + 0xf2, 0x00, 0x36, 0x80, 0x4d, 0xee, 0x03, 0xe8, + 0x00, 0xba, 0x00, 0x3e, 0xa1, 0x4f, 0xe5, 0x03, + 0xa8, 0x00, 0xfa, 0x00, 0x3d, 0x80, 0x1e, 0xe8, + 0x03, 0xe8, 0x00, 0xde, 0x50, 0x37, 0x91, 0x09, + 0xe8, 0x02, 0xf9, 0x00, 0x8a, 0x00, 0x21, 0x90, + 0x0f, 0xed, 0x02, 0xf8, 0x00, 0xce, 0x00, 0xb3, + 0x80, 0x2c, 0xed, 0x03, 0xfa, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf8, + 0x00, 0x3c, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x88, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x10, 0x0e, 0x80, 0x09, + 0xa0, 0x00, 0xf8, 0x04, 0x3e, 0x18, 0x1d, 0x80, + 0x22, 0xe1, 0x02, 0x78, 0x10, 0x2e, 0x00, 0x1f, + 0x8c, 0x41, 0xe1, 0x00, 0xf0, 0x00, 0x3a, 0x08, + 0x0f, 0x80, 0x01, 0xe0, 0x00, 0xf8, 0x18, 0x3e, + 0x00, 0xed, 0x09, 0x00, 0xab, 0x00, 0x0f, 0x80, + 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0c, 0x90, 0x43, 0xe4, 0x00, 0xf9, 0x90, 0x32, + 0x68, 0x0b, 0x90, 0x03, 0x24, 0x00, 0xc9, 0x00, + 0x0e, 0x40, 0x0f, 0x90, 0x03, 0xa4, 0x50, 0xf1, + 0x00, 0x32, 0x70, 0x04, 0x90, 0x01, 0xe4, 0x04, + 0xc9, 0x00, 0x3e, 0x41, 0x1e, 0x10, 0x13, 0x24, + 0x30, 0xf9, 0x00, 0x12, 0x40, 0x0c, 0x98, 0x03, + 0xe6, 0x00, 0xf9, 0x00, 0x30, 0x40, 0x0c, 0x9a, + 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x70, + 0x28, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x02, + 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, 0x89, 0x00, + 0x2e, 0x60, 0x0b, 0x90, 0x02, 0x27, 0x00, 0xb9, + 0x00, 0xa2, 0x40, 0x0a, 0x90, 0x02, 0xe5, 0x20, + 0x89, 0x00, 0x2e, 0x50, 0x0e, 0x9c, 0x82, 0x27, + 0x80, 0xb9, 0x0a, 0x02, 0x50, 0x08, 0x95, 0x02, + 0xe4, 0x00, 0xb9, 0x00, 0x22, 0x40, 0x08, 0x90, + 0x82, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x44, + 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0xa2, + 0x40, 0x0b, 0xb0, 0x02, 0x04, 0x00, 0x99, 0x00, + 0x2e, 0x60, 0x4b, 0x90, 0x42, 0x65, 0x10, 0xb9, + 0x04, 0x22, 0x41, 0x0a, 0x90, 0x82, 0xe4, 0x00, + 0x89, 0x00, 0x0e, 0x50, 0x0b, 0x92, 0x02, 0xa4, + 0x84, 0xb9, 0x80, 0x2a, 0xe0, 0x08, 0x90, 0x12, + 0xe4, 0x40, 0xb1, 0x00, 0x22, 0x60, 0x08, 0x90, + 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x28, 0x20, + 0x4a, 0x0b, 0x10, 0x42, 0x04, 0x06, 0xa1, 0x00, + 0x2c, 0xd0, 0x0b, 0x14, 0xed, 0x09, 0x00, 0xac, + 0x00, 0x02, 0x44, 0xa4, 0x31, 0xaa, 0x20, 0xca, + 0x0a, 0x10, 0x46, 0xc4, 0xa2, 0x81, 0x28, 0x2c, + 0x4a, 0x0b, 0x14, 0x02, 0x84, 0xa0, 0xb1, 0x40, + 0xaa, 0x61, 0x00, 0x14, 0x02, 0xc5, 0x00, 0xb1, + 0x40, 0xa0, 0x40, 0x28, 0x14, 0x02, 0xc2, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, + 0x00, 0xf8, 0x00, 0x3e, 0x80, 0x0c, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x20, 0x32, 0x08, 0x0f, 0x80, + 0x0b, 0x20, 0x00, 0xd8, 0x00, 0x1e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x88, 0x38, 0x20, 0x32, 0x08, + 0x0c, 0x80, 0x03, 0xe0, 0x80, 0xca, 0x22, 0x3e, + 0x08, 0x0e, 0x80, 0x03, 0xa0, 0x85, 0xf8, 0x00, + 0x3a, 0x00, 0xcc, 0xa0, 0x03, 0xe0, 0x08, 0xf8, + 0x00, 0x32, 0x00, 0x0c, 0x80, 0x03, 0xee, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1d, 0xe4, + 0x00, 0xf9, 0x00, 0x3c, 0x50, 0x4f, 0x94, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x41, 0x0f, 0xd2, + 0xc3, 0xf4, 0xa0, 0x9d, 0x28, 0x3f, 0x40, 0x0f, + 0xf4, 0x2b, 0xa4, 0x00, 0xf9, 0x28, 0x2d, 0xc0, + 0x05, 0xd2, 0x83, 0xe4, 0xa4, 0xfd, 0x28, 0x3f, + 0x4a, 0x1e, 0xf4, 0x07, 0x74, 0xb1, 0xf9, 0x40, + 0x37, 0x40, 0x2f, 0xd4, 0x03, 0xf5, 0x00, 0xfd, + 0x00, 0x3f, 0x50, 0x0f, 0xd0, 0x03, 0xe6, 0x06, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, + 0x00, 0xf9, 0x00, 0x3f, 0x48, 0x0f, 0x92, 0x03, + 0x24, 0x00, 0xfd, 0x20, 0x3f, 0x4a, 0x0c, 0x91, + 0x13, 0xe4, 0x00, 0xf9, 0x00, 0x33, 0x44, 0x0f, + 0x92, 0x43, 0xd4, 0xa0, 0xcd, 0x34, 0x33, 0x40, + 0x1f, 0xd0, 0x07, 0x74, 0xc1, 0xfd, 0x00, 0x3f, + 0xc0, 0x8f, 0xd6, 0x22, 0x34, 0x80, 0xdd, 0x28, + 0xb3, 0x40, 0x0f, 0xd4, 0x03, 0xfc, 0x00, 0xf9, + 0x40, 0x33, 0xc8, 0x0f, 0xd1, 0x03, 0xc6, 0xed, + 0x09, 0x00, 0xad, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x10, 0xe0, 0x00, 0xb8, 0x00, + 0x2e, 0x14, 0x0b, 0x84, 0x02, 0x20, 0x00, 0xb8, + 0x00, 0x26, 0x00, 0x08, 0x82, 0x42, 0x60, 0x20, + 0x98, 0x08, 0x22, 0x01, 0x0b, 0x80, 0x02, 0xe0, + 0x00, 0xc8, 0x30, 0x22, 0x10, 0x0b, 0x82, 0x02, + 0xa0, 0xc0, 0xb8, 0x48, 0x2e, 0x02, 0x8b, 0x86, + 0x02, 0xa0, 0xa4, 0xb8, 0x60, 0x22, 0x00, 0x0b, + 0x82, 0x02, 0x61, 0xa8, 0xb8, 0x02, 0x2a, 0x14, + 0x0b, 0x82, 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, 0xb1, 0x00, + 0x2c, 0xc0, 0x0b, 0x14, 0x0a, 0x04, 0x00, 0xb1, + 0x14, 0x2c, 0x40, 0x0a, 0x12, 0x02, 0xc4, 0x81, + 0xb9, 0x00, 0x28, 0x40, 0x0b, 0x13, 0x82, 0xc4, + 0x00, 0x81, 0x20, 0x28, 0x44, 0x0b, 0x9a, 0x82, + 0x04, 0x80, 0xa1, 0x30, 0x2c, 0x44, 0x0a, 0x14, + 0x02, 0x84, 0xc0, 0xb1, 0x2a, 0x20, 0x40, 0x0b, + 0x14, 0x02, 0xcc, 0xc0, 0xb9, 0x20, 0x20, 0x60, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, 0xb9, + 0x00, 0x26, 0x40, 0x28, 0x90, 0x02, 0x64, 0x80, + 0x99, 0x00, 0x2a, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0x99, 0x00, 0xa2, 0x40, 0x0b, 0x90, 0x02, + 0xa4, 0x00, 0xb9, 0x00, 0x6e, 0x42, 0x0b, 0x90, + 0x42, 0xa4, 0x01, 0xb9, 0x00, 0x22, 0x48, 0x0b, + 0x92, 0xc0, 0xed, 0x00, 0xb9, 0x40, 0x2a, 0x48, + 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x41, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0e, 0x9c, 0x83, 0xe4, 0x04, + 0xf1, 0x90, 0xba, 0x41, 0x0f, 0x94, 0x03, 0xe4, + 0x02, 0xc9, 0xed, 0x09, 0x00, 0xae, 0x00, 0x00, + 0x3a, 0x54, 0x0b, 0x90, 0x03, 0x64, 0x00, 0xf9, + 0x62, 0x2e, 0x41, 0x0e, 0x9c, 0x13, 0xa6, 0x80, + 0xd9, 0x03, 0x22, 0x78, 0x8f, 0x94, 0x23, 0xe6, + 0x00, 0xf1, 0x80, 0x32, 0x50, 0x9f, 0x90, 0x83, + 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x42, 0x03, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x36, 0x41, + 0x0f, 0x92, 0x03, 0xe4, 0x00, 0xf9, 0x80, 0x36, + 0x50, 0x0f, 0x90, 0x02, 0xe4, 0x08, 0xe9, 0x00, + 0x3e, 0x60, 0x0f, 0x90, 0x23, 0xe4, 0x00, 0xf9, + 0x03, 0x3e, 0x40, 0x0f, 0x99, 0x43, 0xe4, 0x84, + 0xf9, 0x04, 0x3e, 0x60, 0x0f, 0x98, 0x03, 0x64, + 0x80, 0xf9, 0x20, 0x2e, 0x40, 0x0f, 0x90, 0x03, + 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x10, 0xa0, 0x08, 0xf8, 0x00, 0x36, 0x00, 0x2e, + 0x00, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x32, 0x00, + 0x0f, 0x80, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e, + 0x03, 0x4f, 0x80, 0x03, 0xa0, 0x40, 0xc0, 0x20, + 0x32, 0x00, 0x0f, 0x81, 0x43, 0x20, 0x00, 0xe8, + 0x44, 0x3e, 0x18, 0x0c, 0x04, 0x83, 0xe0, 0xc1, + 0xe0, 0x00, 0x32, 0x31, 0x0f, 0x84, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, 0x84, 0x03, + 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x45, 0x28, 0x00, 0xba, 0x00, 0x2f, 0x90, 0x08, + 0xa0, 0x02, 0xe8, 0x08, 0xba, 0x00, 0x20, 0x82, + 0x0b, 0xa0, 0x10, 0xe8, 0x00, 0xba, 0x00, 0x27, + 0x90, 0x0b, 0xa0, 0x02, 0xdb, 0x02, 0x8e, 0x48, + 0x23, 0x90, 0x0b, 0x69, 0x0a, 0x3a, 0x00, 0x9e, + 0x80, 0x2f, 0xb0, 0x08, 0xe0, 0x62, 0xf9, 0x18, + 0xfe, 0x00, 0xa3, 0x98, 0x09, 0xe0, 0x02, 0xf8, + 0x00, 0xea, 0x00, 0x2e, 0xa0, 0x28, 0xe0, 0x02, + 0xca, 0x00, 0x40, 0x00, 0x00, 0xed, 0x09, 0x00, + 0xaf, 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, 0x00, + 0xb3, 0x00, 0x2c, 0x40, 0x08, 0x30, 0x02, 0xcc, + 0x00, 0xb1, 0x80, 0x20, 0x40, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xa3, 0x00, 0x2c, 0xd1, 0x03, 0x30, + 0x42, 0x8f, 0x80, 0x83, 0x40, 0x20, 0xe6, 0x0b, + 0x38, 0x02, 0x4e, 0xd0, 0x23, 0xd8, 0x28, 0xd0, + 0x08, 0x31, 0x02, 0xcc, 0x00, 0xa3, 0x98, 0x20, + 0xc0, 0x4b, 0x34, 0x90, 0xcc, 0x10, 0xb3, 0x00, + 0x2c, 0xe0, 0x08, 0x38, 0x82, 0xca, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, 0x00, + 0xb7, 0x00, 0x2c, 0xa0, 0x09, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0xc0, 0x21, 0xc0, 0x0b, 0x72, 0x42, + 0xdc, 0x80, 0xb7, 0x02, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xdc, 0x00, 0x87, 0x00, 0xa1, 0xc0, 0x8b, + 0x70, 0x12, 0x1c, 0x00, 0x97, 0x00, 0x6d, 0xf0, + 0x08, 0x70, 0x06, 0xdc, 0x00, 0xb0, 0x00, 0x21, + 0xc0, 0x09, 0x70, 0x82, 0xd8, 0x08, 0xa7, 0x24, + 0x2c, 0xe2, 0x08, 0x74, 0x02, 0xe8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, + 0xf7, 0x80, 0x3d, 0xa1, 0x0e, 0x78, 0x03, 0xde, + 0x00, 0xf3, 0x80, 0xb1, 0xe0, 0x0f, 0x7a, 0x03, + 0xdf, 0xc0, 0xf7, 0xc0, 0x3d, 0x61, 0x0f, 0x78, + 0x03, 0x9e, 0x00, 0xcf, 0x80, 0x31, 0xe0, 0x0b, + 0xf8, 0x03, 0x1e, 0x04, 0xe7, 0x81, 0x3f, 0xe0, + 0x28, 0x58, 0x03, 0xde, 0x00, 0xe4, 0x80, 0x31, + 0xa0, 0x0f, 0x68, 0x43, 0xde, 0x00, 0xf7, 0x90, + 0x3d, 0xe0, 0x0c, 0x78, 0x03, 0xea, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0a, 0xb0, 0x01, 0xec, + 0x00, 0xfb, 0x04, 0x1e, 0xc0, 0x0f, 0xb2, 0x83, + 0xec, 0x00, 0xdb, 0x28, 0x36, 0x40, 0x0f, 0xb4, + 0x83, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0xc0, 0x0f, + 0xed, 0x09, 0x00, 0xb0, 0x00, 0xa0, 0x03, 0xec, + 0x00, 0xda, 0x00, 0x3e, 0xc0, 0x0f, 0xa0, 0x03, + 0xec, 0x00, 0x68, 0x00, 0x3a, 0x01, 0x0d, 0x90, + 0x03, 0xe0, 0x00, 0xfb, 0x70, 0x3e, 0xc0, 0xcf, + 0x90, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3d, + 0xa0, 0x0e, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, + 0x3f, 0xe0, 0x0f, 0xf8, 0x83, 0xfe, 0x00, 0xff, + 0x80, 0x3f, 0xe0, 0x0f, 0xf9, 0x83, 0xfe, 0x00, + 0xcf, 0x82, 0x1f, 0x60, 0x0d, 0xf8, 0x01, 0xfe, + 0x00, 0xdf, 0x00, 0x37, 0xe0, 0x1f, 0xf9, 0x03, + 0x3e, 0x00, 0xdc, 0x80, 0x33, 0xa0, 0x0f, 0xd9, + 0x03, 0xb6, 0x00, 0xcf, 0x80, 0x13, 0xe0, 0x0c, + 0xd9, 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, + 0x04, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0x40, 0x09, 0x71, 0x02, 0xdc, 0x20, 0xb7, + 0x00, 0x2d, 0xc5, 0x0b, 0x71, 0x86, 0xd4, 0x01, + 0xc5, 0x00, 0x6d, 0x44, 0x04, 0x52, 0x02, 0xd0, + 0x02, 0x8d, 0x00, 0x29, 0x00, 0x0c, 0xf1, 0x02, + 0xb8, 0x00, 0xa4, 0x04, 0x21, 0x80, 0x0b, 0x55, + 0x92, 0x30, 0x40, 0xa7, 0x08, 0x21, 0xc4, 0x0d, + 0x45, 0x82, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, + 0x80, 0x0a, 0x70, 0x02, 0xdc, 0x00, 0xb5, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0x00, 0x0b, 0x70, 0x06, 0xcc, 0x00, + 0x97, 0x00, 0x2d, 0x82, 0x28, 0x70, 0x06, 0xcc, + 0x00, 0x87, 0x00, 0x21, 0xc0, 0x0b, 0x61, 0x02, + 0x54, 0x40, 0x84, 0x00, 0x21, 0x80, 0x0b, 0x60, + 0x42, 0x94, 0x00, 0x87, 0x10, 0x21, 0xc0, 0x08, + 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x14, 0xed, 0x09, 0x00, 0xb1, 0x00, + 0xcc, 0x00, 0xb3, 0x02, 0x2c, 0x80, 0x08, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x09, + 0x3c, 0x02, 0xce, 0x00, 0xb3, 0x80, 0x2c, 0x00, + 0x0b, 0x32, 0x02, 0xc0, 0x00, 0x80, 0x00, 0x2c, + 0xa0, 0x00, 0x0e, 0x42, 0xc0, 0x10, 0x80, 0xe0, + 0x28, 0x20, 0x08, 0x24, 0x00, 0xc3, 0x04, 0xa0, + 0x00, 0x00, 0x00, 0x0b, 0x18, 0xe2, 0x00, 0x20, + 0xab, 0x88, 0x20, 0x44, 0x88, 0x10, 0x02, 0xc8, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, + 0xac, 0x00, 0xfb, 0x00, 0x3e, 0x80, 0x0e, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xfc, 0x83, 0xfc, 0x00, 0xff, 0x88, 0x3e, 0x68, + 0x0f, 0xf4, 0x02, 0xec, 0x08, 0x99, 0x00, 0x2e, + 0xb0, 0x08, 0x92, 0x02, 0xe4, 0x00, 0x89, 0x88, + 0x22, 0x66, 0x1b, 0xa4, 0x83, 0x67, 0x00, 0x08, + 0x00, 0x12, 0xc0, 0x0f, 0xb0, 0x02, 0xa0, 0x00, + 0xcf, 0x02, 0x22, 0xf0, 0x28, 0xa8, 0x03, 0xea, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0xec, 0x00, 0xbb, 0x00, 0x3e, 0x80, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xf9, 0x02, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x10, + 0x0f, 0xb0, 0x03, 0xed, 0x10, 0xf9, 0x40, 0x3e, + 0x88, 0x8f, 0x94, 0x03, 0x64, 0x00, 0xe9, 0x04, + 0x3a, 0x50, 0x0e, 0x96, 0x07, 0xa5, 0x40, 0xe8, + 0x42, 0x3e, 0x99, 0x0f, 0xa0, 0x03, 0xe1, 0x00, + 0xfb, 0x00, 0x3e, 0xc2, 0x0f, 0xb0, 0x03, 0xe0, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, + 0xfc, 0x00, 0xff, 0x02, 0x3f, 0x00, 0x0f, 0x70, + 0x03, 0x3c, 0x00, 0xf7, 0x00, 0x71, 0x40, 0x0c, + 0xf0, 0x83, 0x3c, 0x00, 0xff, 0x00, 0x33, 0x40, + 0x0f, 0xf0, 0x03, 0x14, 0x80, 0xed, 0x00, 0x3a, + 0x40, 0x0f, 0xd0, 0x03, 0xf0, 0x00, 0xed, 0x09, + 0x00, 0xb2, 0x00, 0xfd, 0x00, 0x3b, 0x00, 0x0f, + 0xcc, 0x03, 0x30, 0x34, 0xf8, 0x04, 0x3f, 0xa0, + 0x0f, 0x80, 0x03, 0xf0, 0x00, 0xff, 0x00, 0x32, + 0xc0, 0x0b, 0xc0, 0x03, 0xc0, 0x44, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, 0xbb, + 0x00, 0x2e, 0x82, 0x0b, 0xb0, 0x02, 0x2c, 0x00, + 0xbb, 0x90, 0x22, 0xe4, 0x18, 0xb0, 0x22, 0x2c, + 0x00, 0xbb, 0x01, 0x22, 0x30, 0x0b, 0xb0, 0x03, + 0x20, 0x18, 0xc8, 0x80, 0x2e, 0x50, 0x0b, 0x8e, + 0x03, 0xa3, 0x80, 0x98, 0xa0, 0x3a, 0x30, 0x0e, + 0x8c, 0x02, 0xa2, 0x20, 0xb8, 0xe0, 0x2e, 0x36, + 0x0b, 0x88, 0x22, 0xe3, 0x00, 0xbb, 0x06, 0x22, + 0xc0, 0x4b, 0x98, 0x02, 0xe0, 0x40, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, 0xbb, + 0x00, 0x2e, 0xe0, 0x0b, 0xb0, 0x02, 0x2c, 0x08, + 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0x30, 0x02, 0x2c, + 0x00, 0xb3, 0x00, 0x22, 0x70, 0x0b, 0x30, 0x02, + 0x28, 0x20, 0x88, 0x8c, 0x2e, 0x18, 0x0a, 0x88, + 0x42, 0xe6, 0x00, 0xa8, 0x80, 0x2e, 0x62, 0x8b, + 0x10, 0x86, 0x26, 0x11, 0xb8, 0x80, 0x2e, 0x80, + 0x8b, 0x98, 0x12, 0xe2, 0x00, 0xbb, 0x00, 0x22, + 0xc0, 0x0b, 0x88, 0x02, 0xe0, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb3, + 0x00, 0x2c, 0x80, 0x4b, 0x30, 0x02, 0x0c, 0x04, + 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x42, 0x0c, + 0x00, 0xb3, 0x00, 0x20, 0x00, 0x0b, 0x30, 0x42, + 0x40, 0x01, 0x80, 0x00, 0x2c, 0x00, 0x0b, 0x00, + 0x02, 0xc0, 0x00, 0x90, 0x00, 0x68, 0x00, 0x08, + 0x10, 0x06, 0x80, 0x01, 0xb0, 0x00, 0x24, 0x81, + 0x0b, 0x10, 0x02, 0xc0, 0x08, 0xb3, 0x00, 0x20, + 0xc0, 0x0b, 0x00, 0x02, 0x42, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xfb, + 0x00, 0xed, 0x09, 0x00, 0xb3, 0x00, 0x3e, 0x80, + 0x0f, 0xb0, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0xae, + 0xc0, 0x28, 0xf0, 0x0b, 0x3c, 0x00, 0xff, 0x00, + 0xa2, 0x00, 0x0f, 0xf0, 0x0a, 0x20, 0x00, 0x88, + 0x04, 0x3e, 0x00, 0x0e, 0x80, 0x03, 0xe0, 0x00, + 0xe8, 0x07, 0x7e, 0x00, 0x0f, 0x80, 0x23, 0x20, + 0x11, 0xf8, 0x06, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x10, 0xf7, 0x02, 0x72, 0xc0, 0x4f, 0x80, + 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x40, + 0x0f, 0xf0, 0x01, 0x7c, 0x00, 0xfd, 0x00, 0x33, + 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0x00, 0x0f, 0xf0, 0x03, 0xb0, 0x00, 0xec, + 0x04, 0x3f, 0x00, 0x07, 0xc0, 0x06, 0xb0, 0x00, + 0xdc, 0x00, 0x3f, 0x00, 0x1e, 0xc0, 0x03, 0xf0, + 0x00, 0xfc, 0x00, 0x2f, 0x00, 0x4f, 0xd0, 0x07, + 0xf0, 0x00, 0xff, 0x00, 0x7f, 0x40, 0x0f, 0xd0, + 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x05, 0xfc, 0x00, 0xff, 0x00, 0x33, 0x4c, + 0x0c, 0xe1, 0x03, 0x30, 0x90, 0xf5, 0x00, 0x37, + 0x80, 0x0f, 0xd0, 0x02, 0xdc, 0x01, 0xfc, 0x05, + 0x3f, 0x4c, 0x0f, 0xf0, 0x21, 0xfc, 0x00, 0xff, + 0x22, 0x37, 0x08, 0x0b, 0xc0, 0x03, 0xb0, 0x80, + 0xac, 0x24, 0x3f, 0x00, 0x0d, 0xc0, 0x03, 0x31, + 0x80, 0xcf, 0x01, 0x3f, 0x0e, 0x0f, 0xc2, 0x01, + 0xf0, 0x80, 0xec, 0x08, 0x33, 0x0e, 0x0e, 0xf0, + 0x02, 0x70, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x10, 0xec, 0x00, 0xbb, 0x08, 0x22, 0x10, + 0x08, 0xa2, 0x02, 0x29, 0x44, 0xb8, 0x00, 0xa2, + 0x80, 0x0b, 0x90, 0x00, 0xec, 0x00, 0x98, 0x00, + 0x2e, 0x98, 0x0b, 0xb0, 0x03, 0xac, 0x00, 0xeb, + 0x14, 0x2a, 0x44, 0x08, 0x80, 0x02, 0x64, 0xe0, + 0x98, 0x40, 0x2e, 0x56, 0xed, 0x09, 0x00, 0xb4, + 0x00, 0x0b, 0x97, 0x22, 0x21, 0x08, 0xdb, 0x00, + 0x2e, 0x10, 0x0b, 0x94, 0x02, 0x41, 0x90, 0x88, + 0x40, 0x22, 0x50, 0x08, 0xb2, 0x02, 0xe0, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, + 0x00, 0xb3, 0x10, 0x20, 0x50, 0x8a, 0xa0, 0x02, + 0x00, 0x10, 0x99, 0x00, 0x20, 0x80, 0x0b, 0x10, + 0x02, 0xc8, 0x00, 0xb2, 0x00, 0x2c, 0xcc, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x28, 0x60, + 0x0a, 0x20, 0x02, 0x80, 0x00, 0xb0, 0x38, 0x2c, + 0x08, 0x0b, 0x10, 0x86, 0x40, 0xc0, 0xa3, 0x00, + 0x2c, 0x40, 0x0b, 0x01, 0x02, 0xcc, 0x60, 0x80, + 0x28, 0x60, 0xa0, 0x08, 0x30, 0x82, 0x62, 0x01, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, + 0x00, 0xb3, 0x00, 0xa2, 0x00, 0x0a, 0xa0, 0x02, + 0x22, 0x08, 0xb9, 0x00, 0x22, 0x86, 0x0b, 0x90, + 0x00, 0xe4, 0x00, 0x9b, 0x00, 0x26, 0xc0, 0x0b, + 0xb0, 0x02, 0x2c, 0x00, 0xab, 0x00, 0x28, 0x60, + 0x08, 0xa0, 0x02, 0x66, 0x34, 0xb8, 0x88, 0x26, + 0x60, 0x0b, 0x98, 0x02, 0x22, 0x00, 0xbb, 0x00, + 0x0e, 0x20, 0x0b, 0x80, 0x02, 0xe4, 0x00, 0x88, + 0x00, 0x22, 0x80, 0x08, 0xb0, 0x00, 0xf0, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xec, + 0x00, 0xf8, 0x40, 0x32, 0x48, 0x2e, 0xb2, 0x0b, + 0x23, 0x80, 0xd3, 0x90, 0x36, 0x90, 0x0f, 0x92, + 0x23, 0xed, 0x00, 0xba, 0x08, 0x3e, 0xe2, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3a, 0x20, + 0x4e, 0x80, 0x83, 0xa7, 0x00, 0xe9, 0x80, 0x3e, + 0x28, 0x0d, 0x8a, 0x0b, 0x26, 0x00, 0xeb, 0x04, + 0x3e, 0x28, 0x0f, 0xae, 0x03, 0xe2, 0x00, 0xc9, + 0x24, 0x32, 0x20, 0x2e, 0xb0, 0x03, 0x50, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xbc, + 0x00, 0xfa, 0x00, 0xbf, 0x10, 0x0d, 0xd1, 0xed, + 0x09, 0x00, 0xb5, 0x00, 0x03, 0xf8, 0x00, 0xfd, + 0x00, 0x3f, 0x80, 0x0f, 0xdc, 0x03, 0xfd, 0x00, + 0xff, 0x40, 0x3f, 0xe4, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xef, 0x00, 0x3b, 0x00, 0x0e, 0xe0, 0x02, + 0xd4, 0x04, 0xcc, 0x00, 0x3f, 0x41, 0x8f, 0xd0, + 0x03, 0x94, 0x00, 0xdf, 0x00, 0x3e, 0x00, 0x0f, + 0xd2, 0x03, 0x56, 0x40, 0xfd, 0x10, 0xbf, 0x67, + 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x10, 0xac, 0x00, 0xf8, 0x50, + 0xb0, 0x60, 0x0c, 0xb4, 0x03, 0x21, 0x80, 0xfb, + 0x00, 0xb2, 0x80, 0x0a, 0x90, 0x07, 0xed, 0x30, + 0xca, 0x44, 0x32, 0xd8, 0x0f, 0xb0, 0x03, 0xec, + 0x10, 0xfb, 0x10, 0x36, 0x40, 0x0e, 0xa4, 0x03, + 0xe4, 0x00, 0xf9, 0x4a, 0x32, 0x19, 0x0f, 0x96, + 0x03, 0xe4, 0x20, 0xfb, 0x10, 0x32, 0x42, 0x0c, + 0xa4, 0x03, 0x28, 0x10, 0xe2, 0x00, 0x38, 0x80, + 0x0f, 0xb0, 0x82, 0x50, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, 0xba, 0x80, + 0x22, 0x00, 0x08, 0x30, 0x23, 0x60, 0x84, 0xb9, + 0x84, 0x22, 0xc0, 0x08, 0x90, 0x02, 0xec, 0x20, + 0x8b, 0x00, 0x36, 0xd2, 0x01, 0xb0, 0x02, 0xec, + 0x00, 0xb7, 0x80, 0x36, 0x00, 0x08, 0xa9, 0x03, + 0xe4, 0x00, 0xb9, 0x41, 0xaa, 0x41, 0x0b, 0x98, + 0x02, 0x65, 0x10, 0x3f, 0x80, 0x2a, 0x50, 0x0a, + 0x80, 0x02, 0x24, 0x00, 0x8a, 0x20, 0x22, 0x80, + 0x0b, 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x05, 0x4c, 0x00, 0xb3, 0x85, + 0x20, 0x40, 0x00, 0x32, 0x02, 0x80, 0x00, 0xb1, + 0x10, 0x20, 0x40, 0x0a, 0x10, 0x00, 0xcf, 0x00, + 0x82, 0x00, 0x20, 0xf0, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x24, 0x00, 0x0a, 0x11, 0x02, + 0xc2, 0x40, 0xb1, 0x00, 0x28, 0x50, 0x0b, 0x8d, + 0x02, 0xc4, 0xed, 0x09, 0x00, 0xb6, 0x00, 0x00, + 0xb3, 0x04, 0x28, 0x74, 0x0b, 0x08, 0x02, 0x80, + 0x20, 0xa2, 0x80, 0x2c, 0x04, 0x0b, 0x30, 0x40, + 0x78, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x20, 0x60, 0x08, + 0xd8, 0x22, 0x5a, 0x80, 0xb4, 0xe0, 0x23, 0xe0, + 0x18, 0x58, 0x02, 0xde, 0x00, 0x8e, 0x80, 0x25, + 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x84, + 0x25, 0xe0, 0x08, 0x58, 0x02, 0xdf, 0x00, 0xb5, + 0x90, 0x29, 0xe0, 0x0b, 0x78, 0x02, 0x5e, 0x00, + 0xb7, 0x80, 0x29, 0xe0, 0x4b, 0x38, 0x02, 0x1a, + 0x00, 0x86, 0x80, 0x25, 0x60, 0xc3, 0x78, 0x02, + 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x08, 0x0c, 0x00, 0xf3, 0x40, 0x30, 0x44, 0x2c, + 0x30, 0x22, 0x84, 0x40, 0xf1, 0x00, 0x30, 0x44, + 0x0e, 0x30, 0x02, 0xcd, 0x00, 0xc3, 0x00, 0x20, + 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, + 0x36, 0x41, 0x0e, 0x31, 0x03, 0xc0, 0x00, 0xfb, + 0x00, 0x30, 0x40, 0x0f, 0x00, 0x03, 0xc8, 0x40, + 0xf3, 0x00, 0x38, 0x40, 0x8f, 0x10, 0x83, 0x8c, + 0x80, 0xeb, 0x00, 0x3c, 0x48, 0x8f, 0x33, 0x03, + 0x52, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0x40, 0x0f, + 0x71, 0x13, 0xf8, 0xc4, 0xfd, 0x20, 0x1d, 0xc1, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0x77, 0x00, 0x3f, + 0xc4, 0x0d, 0xf0, 0x03, 0xfc, 0x00, 0xf7, 0x12, + 0x3f, 0xc4, 0x4f, 0xf1, 0x03, 0xbc, 0x00, 0xff, + 0x00, 0x17, 0xc0, 0x0f, 0xe0, 0x03, 0xfc, 0x10, + 0xf7, 0x08, 0x3f, 0x84, 0x0e, 0xf0, 0x0b, 0x7c, + 0x00, 0xff, 0x00, 0x23, 0x40, 0x07, 0xf1, 0x03, + 0xd0, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x05, 0xec, 0x00, 0xf9, 0x00, 0xb2, 0x40, 0x0f, + 0xb0, 0x03, 0xe0, 0x00, 0xc9, 0xed, 0x09, 0x00, + 0xb7, 0x00, 0x04, 0x32, 0x40, 0x0f, 0x80, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x2e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xbf, 0x10, 0x7a, 0x80, 0x07, + 0x80, 0x02, 0xe8, 0x00, 0xfb, 0x80, 0xb2, 0x80, + 0x0f, 0xa0, 0x03, 0xe4, 0x00, 0xfb, 0x00, 0x32, + 0xc0, 0x0f, 0x28, 0x03, 0x62, 0x00, 0xc9, 0x80, + 0x22, 0x80, 0x0f, 0xb0, 0x01, 0xea, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, 0x01, + 0xbf, 0x00, 0x21, 0x40, 0x0b, 0x70, 0x12, 0xdc, + 0x00, 0x85, 0x00, 0x21, 0xc1, 0x0b, 0x50, 0x02, + 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x80, 0x61, 0xc0, 0x0b, + 0x70, 0x42, 0xd8, 0x00, 0xb6, 0x00, 0x21, 0x80, + 0x4b, 0x70, 0x42, 0xdc, 0x00, 0xb7, 0x20, 0x21, + 0xc0, 0x0b, 0x70, 0x08, 0x0c, 0x00, 0x8d, 0x00, + 0xa1, 0xc0, 0x0b, 0x70, 0x02, 0xd2, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, + 0xa5, 0x8d, 0x61, 0x61, 0x0b, 0x78, 0x02, 0xc6, + 0x00, 0x85, 0x82, 0x21, 0xe0, 0x0b, 0x48, 0x06, + 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xf1, 0x0b, 0x78, + 0x02, 0xde, 0x00, 0xb3, 0x80, 0x29, 0xe0, 0x0b, + 0x78, 0x12, 0x5e, 0x1c, 0xb3, 0xc0, 0x21, 0xf0, + 0x0b, 0x78, 0x02, 0xda, 0x00, 0xb3, 0xa0, 0xa9, + 0xe0, 0x0b, 0x78, 0x02, 0x1a, 0x00, 0x87, 0x80, + 0x21, 0xe1, 0x0b, 0x78, 0x02, 0xf0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, 0x00, + 0xb3, 0x00, 0x22, 0xe5, 0x9b, 0x34, 0x02, 0xcc, + 0x82, 0x81, 0x00, 0x20, 0xd0, 0x0b, 0x18, 0x02, + 0xcd, 0x00, 0xb3, 0x00, 0x2c, 0xd0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x68, 0xf0, 0x0b, + 0x30, 0x02, 0xcc, 0x80, 0xb3, 0x20, 0x22, 0xf0, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xb3, 0x00, 0x6a, + 0xed, 0x09, 0x00, 0xb8, 0x00, 0xf8, 0x1b, 0x39, + 0x02, 0x0c, 0x04, 0x83, 0x62, 0x20, 0xc4, 0x0b, + 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xfe, 0x00, 0x23, + 0x80, 0x0f, 0xec, 0x83, 0xf8, 0x02, 0xc6, 0xe0, + 0xb3, 0xb8, 0x0f, 0x6e, 0x22, 0xd8, 0x60, 0xfe, + 0xe0, 0x3f, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, + 0xfa, 0x00, 0xbb, 0x82, 0x0f, 0xe4, 0x93, 0x78, + 0x20, 0xfe, 0x80, 0x33, 0x80, 0x0f, 0xe4, 0x03, + 0xf9, 0x14, 0xfa, 0x00, 0x3b, 0x92, 0x0f, 0xe0, + 0x03, 0x39, 0x02, 0x4e, 0x04, 0x33, 0xa0, 0x0f, + 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf0, 0x40, 0x3e, + 0x00, 0x0b, 0x80, 0x53, 0xe1, 0x00, 0xf8, 0xc0, + 0x3e, 0x00, 0x0f, 0x88, 0x03, 0xe0, 0x00, 0xf8, + 0x80, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x26, 0x01, 0x0f, 0x88, 0x03, 0xe1, + 0x00, 0x78, 0x00, 0x3e, 0x18, 0x0f, 0x81, 0x83, + 0xe0, 0x20, 0xf8, 0x00, 0x06, 0x00, 0x0f, 0x84, + 0x03, 0xe0, 0x80, 0xf8, 0x10, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, 0xc8, 0x32, + 0x40, 0x0c, 0x98, 0x83, 0xc4, 0x00, 0xd9, 0x00, + 0x32, 0x42, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xe9, + 0x00, 0x3e, 0x62, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf1, 0x20, 0xb0, 0x42, 0x4c, 0x99, 0x03, 0xc4, + 0x00, 0xc9, 0xc0, 0x3e, 0x68, 0x00, 0x90, 0x03, + 0x26, 0x40, 0xc9, 0x00, 0x3a, 0x69, 0x8c, 0x91, + 0x03, 0xe4, 0x00, 0xf9, 0xc0, 0x3e, 0x60, 0xcf, + 0x9c, 0x63, 0xc2, 0x04, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x04, 0x64, 0x00, 0xb9, 0x00, 0x26, + 0x50, 0x48, 0x94, 0x12, 0xe5, 0x00, 0x89, 0x60, + 0x22, 0x40, 0x0b, 0xed, 0x09, 0x00, 0xb9, 0x00, + 0x90, 0x4a, 0x64, 0x20, 0x89, 0x00, 0x2e, 0x68, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x22, + 0x40, 0x0a, 0x9c, 0x02, 0xe5, 0x20, 0x89, 0xa0, + 0x2e, 0x48, 0x08, 0x90, 0x02, 0xa7, 0x00, 0x81, + 0x80, 0x22, 0x42, 0x0a, 0x9e, 0x02, 0xe4, 0x00, + 0xb9, 0x48, 0x2e, 0x64, 0x0b, 0x98, 0x02, 0xe0, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, + 0x24, 0x00, 0xb9, 0x00, 0xa6, 0x60, 0x08, 0x92, + 0x02, 0xe4, 0x40, 0x89, 0x80, 0x02, 0x40, 0x0b, + 0x90, 0x06, 0x64, 0x00, 0xa9, 0x00, 0x2e, 0x44, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x26, + 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0x99, 0x01, + 0x2e, 0x40, 0x0a, 0x90, 0x22, 0x6c, 0x00, 0x89, + 0x11, 0x2a, 0x40, 0x08, 0x90, 0x02, 0xe6, 0x10, + 0xb9, 0x00, 0x2e, 0x42, 0x0b, 0x90, 0x02, 0xc6, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x04, 0x00, 0xb3, 0x40, 0x24, 0x50, 0x28, 0x1c, + 0x02, 0xc4, 0x02, 0x91, 0x02, 0xa0, 0x41, 0x0b, + 0x90, 0x22, 0x64, 0x10, 0x81, 0x02, 0x2c, 0x50, + 0x1b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x24, + 0x50, 0x0a, 0x18, 0x02, 0xc5, 0x00, 0x91, 0x40, + 0x2c, 0x50, 0x0a, 0x1c, 0x02, 0xc5, 0x00, 0x81, + 0x28, 0x20, 0x50, 0x0a, 0x10, 0x02, 0xc5, 0x00, + 0xb1, 0x40, 0x2c, 0x50, 0x0b, 0x14, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, + 0x60, 0x00, 0xf8, 0x00, 0x32, 0x80, 0x0c, 0x80, + 0x23, 0xe8, 0x04, 0xc8, 0x00, 0x32, 0x00, 0x0f, + 0x80, 0x47, 0x60, 0x00, 0xe8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x36, + 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xd8, 0x00, + 0x3e, 0x00, 0x0e, 0x80, 0x03, 0x68, 0x00, 0xc8, + 0x20, 0x3a, 0x00, 0x2c, 0x80, 0x07, 0xed, 0x09, + 0x00, 0xba, 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x1d, 0xe4, 0x00, 0xfd, + 0x40, 0x3b, 0x50, 0x4f, 0xd0, 0x13, 0xfd, 0x10, + 0xe5, 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0xb4, + 0x00, 0xfd, 0x01, 0x3f, 0xd0, 0x0f, 0x90, 0x03, + 0xe4, 0x08, 0xf9, 0x40, 0x3b, 0xd0, 0x4f, 0xd0, + 0x03, 0xf5, 0x02, 0xed, 0x40, 0x3f, 0x50, 0x2d, + 0xd4, 0x03, 0xb5, 0x02, 0xf9, 0x00, 0x3f, 0x50, + 0x0d, 0xf4, 0x43, 0xf5, 0x00, 0xfd, 0x45, 0x3f, + 0x50, 0x0f, 0x90, 0x03, 0xe6, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x15, 0xe4, 0x00, 0xfd, + 0x00, 0x33, 0x40, 0x0c, 0xd1, 0x03, 0x34, 0x90, + 0xcd, 0x01, 0x22, 0x40, 0x0f, 0x90, 0x03, 0xf4, + 0x00, 0xf9, 0x04, 0x3d, 0x48, 0x0e, 0x90, 0x03, + 0xe4, 0x00, 0xfd, 0x00, 0x7e, 0x40, 0x0e, 0x50, + 0x03, 0xf4, 0x80, 0xfd, 0x2a, 0x3f, 0x4c, 0x0c, + 0xd0, 0x03, 0x34, 0x00, 0xed, 0x28, 0x3f, 0x48, + 0x0c, 0xd2, 0x83, 0xf4, 0xc0, 0xfd, 0x04, 0x33, + 0x40, 0x0e, 0xd1, 0x03, 0xc6, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x00, 0xb8, + 0x48, 0x22, 0x03, 0x08, 0x80, 0x0a, 0x20, 0x08, + 0xaa, 0x00, 0x22, 0x01, 0x0b, 0x80, 0x02, 0xe0, + 0x00, 0xba, 0x01, 0x2e, 0x0a, 0x08, 0x80, 0x03, + 0xa0, 0x00, 0xb8, 0x40, 0x2e, 0x02, 0x08, 0x80, + 0x02, 0xe0, 0xa0, 0xb8, 0x20, 0x2e, 0x0c, 0x88, + 0x84, 0x82, 0x20, 0x20, 0x88, 0x01, 0x2e, 0x0a, + 0x0d, 0x80, 0x02, 0xe0, 0xc0, 0xba, 0x48, 0x32, + 0x02, 0x0d, 0x80, 0x02, 0xce, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, 0xb1, + 0x30, 0x20, 0x44, 0x08, 0x30, 0x02, 0x84, 0x40, + 0x81, 0x00, 0xe4, 0x40, 0x0b, 0x10, 0x02, 0xc4, + 0x00, 0xed, 0x09, 0x00, 0xbb, 0x00, 0xb1, 0x00, + 0x2c, 0x4c, 0x1a, 0x10, 0x02, 0xc4, 0x00, 0xb1, + 0x10, 0x2c, 0x44, 0x0b, 0x10, 0x02, 0xc4, 0xc0, + 0x91, 0x28, 0x2c, 0x48, 0x0b, 0x13, 0x02, 0x44, + 0x42, 0x83, 0x00, 0x6c, 0x4c, 0x08, 0x10, 0x42, + 0xc4, 0x80, 0xb1, 0x30, 0x20, 0x44, 0x48, 0x10, + 0x42, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x11, 0xa4, 0x00, 0xb9, 0x02, 0xa2, 0x48, + 0x08, 0x90, 0x06, 0x24, 0x10, 0xa9, 0x01, 0x26, + 0x40, 0x03, 0x90, 0x16, 0xe4, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x08, 0x90, 0x02, 0xa4, 0x00, 0xb9, + 0x00, 0x2c, 0x40, 0x09, 0x94, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2e, 0xd0, 0x0b, 0xb0, 0x0a, 0x64, + 0x01, 0x89, 0x00, 0x2e, 0x50, 0x19, 0x90, 0x00, + 0xe4, 0x10, 0xb1, 0x00, 0x62, 0x50, 0x09, 0x90, + 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x32, 0x40, + 0x2c, 0x98, 0x03, 0xa7, 0x48, 0xc1, 0x40, 0xb6, + 0x58, 0x0f, 0x99, 0x03, 0xe4, 0xd0, 0xb9, 0x00, + 0x3e, 0x70, 0x0e, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x2e, 0x40, 0x0f, 0x98, 0x02, 0xe4, 0x90, + 0xf9, 0x70, 0x1e, 0x40, 0x0f, 0x92, 0x43, 0x67, + 0x80, 0xe9, 0x01, 0x3e, 0x50, 0x0c, 0x90, 0x43, + 0xe5, 0x20, 0xf9, 0x80, 0xb2, 0x75, 0x5c, 0x90, + 0x43, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x9a, 0x23, 0x46, 0x00, 0xf9, 0x02, 0x3a, + 0x50, 0x0f, 0x98, 0x23, 0xe4, 0x00, 0xf9, 0x24, + 0x3e, 0x70, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0e, 0x92, 0x83, 0xe4, 0x00, + 0xf9, 0x80, 0x34, 0x40, 0x2c, 0x10, 0x03, 0xa4, + 0x80, 0xf9, 0x00, 0x3e, 0x42, 0x0f, 0x90, 0x23, + 0xe4, 0x98, 0xf9, 0x21, 0xed, 0x09, 0x00, 0xbc, + 0x00, 0x32, 0x61, 0x1d, 0x90, 0x03, 0xca, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xa0, + 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, + 0x20, 0x00, 0xc8, 0x0a, 0x32, 0x10, 0x4f, 0x80, + 0x01, 0xe0, 0xc2, 0xd8, 0x40, 0x3c, 0x10, 0x2e, + 0x80, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x4f, 0x81, 0x03, 0x21, 0x00, 0xc8, 0x40, 0x3a, + 0x06, 0x0f, 0x81, 0x03, 0xe0, 0x80, 0xe8, 0x80, + 0x3e, 0x00, 0x0f, 0x84, 0x03, 0x20, 0x80, 0xf8, + 0x51, 0x3e, 0x00, 0x2c, 0x81, 0x83, 0xca, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x28, + 0x00, 0xbe, 0x00, 0xa3, 0xa0, 0x0b, 0xe4, 0x02, + 0x38, 0x60, 0xde, 0x20, 0x22, 0x80, 0x0b, 0xa0, + 0x13, 0xba, 0x00, 0x8a, 0x00, 0x2f, 0x88, 0x08, + 0xa0, 0x42, 0xe8, 0x00, 0xbe, 0xc0, 0x2e, 0x81, + 0x0b, 0xe0, 0x02, 0x39, 0x20, 0x8e, 0x08, 0x23, + 0x81, 0x03, 0xe8, 0x43, 0xb8, 0x04, 0xbe, 0x40, + 0x2f, 0x80, 0x0b, 0xe8, 0x82, 0x3b, 0x00, 0xbe, + 0x04, 0x2f, 0x80, 0x00, 0xec, 0x02, 0xca, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x0c, + 0x00, 0xbb, 0x00, 0x62, 0xc0, 0x0b, 0xb2, 0x02, + 0x4f, 0x00, 0x82, 0x40, 0x24, 0xc0, 0x0b, 0x30, + 0x02, 0x8d, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x2b, + 0x30, 0x42, 0xcc, 0x00, 0xb3, 0x48, 0x2c, 0xc0, + 0x0b, 0x38, 0x02, 0x0f, 0x28, 0x83, 0x08, 0x28, + 0xd0, 0x0b, 0x3a, 0x02, 0xac, 0x00, 0xa2, 0x00, + 0x2e, 0xd0, 0x08, 0x30, 0x02, 0x8e, 0x00, 0xb3, + 0xcb, 0x2e, 0xc0, 0x08, 0x30, 0x02, 0xcb, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, + 0x00, 0xb5, 0x00, 0x21, 0xc2, 0x4b, 0xf0, 0x02, + 0x4c, 0x00, 0x9e, 0x00, 0x25, 0xc0, 0x0b, 0x70, + 0x02, 0x92, 0x00, 0x87, 0x00, 0x2d, 0xc0, 0xed, + 0x09, 0x00, 0xbd, 0x00, 0x09, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x40, 0x2d, 0xc8, 0x0b, 0x68, 0x4a, + 0x1a, 0x00, 0x87, 0x80, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0x9d, 0x00, 0xb6, 0x00, 0x2d, 0xc0, 0x0b, + 0x18, 0x02, 0x9d, 0x00, 0xb5, 0x00, 0x2c, 0x80, + 0x08, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xf3, 0x80, + 0x21, 0x60, 0x4f, 0x68, 0x0b, 0x5e, 0x04, 0xc6, + 0x80, 0xb5, 0xe0, 0x0f, 0x78, 0x03, 0x9a, 0x00, + 0xc7, 0x80, 0x3d, 0xa0, 0x0f, 0x78, 0x03, 0xde, + 0x00, 0xf5, 0x80, 0x2d, 0xe0, 0x0f, 0x58, 0x03, + 0x3e, 0x02, 0xcf, 0x80, 0x39, 0xe0, 0x0f, 0x68, + 0x03, 0x9e, 0x00, 0xe6, 0x80, 0x3d, 0xe0, 0x0c, + 0x68, 0x03, 0x96, 0x00, 0xf7, 0x80, 0x2d, 0xe0, + 0x0c, 0x78, 0x23, 0xea, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, 0xfb, 0x00, + 0x2e, 0x40, 0x0f, 0x20, 0x43, 0xac, 0x00, 0xf3, + 0x00, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, 0x80, 0x00, + 0xeb, 0x00, 0x3e, 0xc0, 0x0e, 0xb0, 0x03, 0xec, + 0x00, 0xf9, 0x04, 0x3e, 0xda, 0x0d, 0x80, 0x03, + 0xec, 0x00, 0xfa, 0x00, 0x32, 0xc0, 0x0f, 0xb0, + 0x23, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x40, 0x8f, + 0x80, 0x0b, 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, 0x20, + 0x33, 0xe4, 0x0f, 0xd8, 0x03, 0xfe, 0x00, 0xc7, + 0x80, 0x33, 0xe0, 0x0f, 0xf1, 0x03, 0x72, 0x00, + 0x5f, 0x80, 0x3f, 0xc8, 0x0c, 0xf8, 0x03, 0xfe, + 0x01, 0xff, 0x90, 0x37, 0xe2, 0x0e, 0x78, 0x02, + 0x3e, 0x44, 0xff, 0x81, 0x37, 0xe0, 0x0c, 0xf8, + 0x02, 0xbe, 0x40, 0xdc, 0x80, 0x3f, 0xa0, 0x0f, + 0xf8, 0x03, 0x7e, 0x00, 0xdf, 0x80, 0x33, 0xe0, + 0x89, 0xe9, 0xed, 0x09, 0x00, 0xbe, 0x00, 0x01, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x11, 0x9c, 0x00, 0xb5, 0x10, 0x01, 0x40, 0x0b, + 0x40, 0x22, 0xdc, 0x00, 0x87, 0x00, 0x21, 0xc4, + 0x0b, 0x70, 0x22, 0x9c, 0x00, 0x97, 0x10, 0x2f, + 0xc0, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x08, 0x61, 0x82, 0x14, 0xc0, 0xb7, + 0x20, 0x2f, 0x84, 0x08, 0x50, 0x03, 0x5c, 0x00, + 0xa4, 0x10, 0x2d, 0x80, 0x0f, 0x52, 0x02, 0xd8, + 0x00, 0xb7, 0x44, 0x21, 0x98, 0x0a, 0xf1, 0x02, + 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x21, 0xc2, 0x8b, + 0x60, 0x82, 0xd0, 0x00, 0x8e, 0x08, 0x21, 0xc0, + 0x0b, 0xf1, 0x06, 0xd4, 0x00, 0xb7, 0x00, 0x2d, + 0x82, 0x09, 0x70, 0x02, 0xdc, 0x00, 0xb5, 0x02, + 0x25, 0xc0, 0x0b, 0x50, 0x02, 0x1c, 0x04, 0xb5, + 0x04, 0x2d, 0x40, 0x08, 0x70, 0x02, 0x94, 0x00, + 0xa4, 0x00, 0x2d, 0xc2, 0x0b, 0x40, 0xc2, 0xdc, + 0x00, 0xb4, 0x00, 0x29, 0xc0, 0x4b, 0x41, 0x02, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x14, 0xcc, 0x00, 0xb3, 0x02, 0x20, 0x70, 0x0b, + 0xa0, 0x12, 0xc1, 0x00, 0x83, 0xc8, 0x20, 0xe4, + 0x0b, 0x34, 0x9a, 0x8d, 0x00, 0xb3, 0x60, 0x2c, + 0xe0, 0x09, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x02, + 0x2c, 0xe0, 0x09, 0x04, 0x02, 0x26, 0x65, 0x30, + 0x00, 0x2c, 0x10, 0x08, 0x1a, 0x16, 0xc1, 0x00, + 0xa0, 0x00, 0x2c, 0x50, 0x4b, 0x0c, 0x82, 0xe8, + 0x00, 0xb0, 0x00, 0x68, 0x40, 0x0a, 0x10, 0x42, + 0x08, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x15, 0xac, 0x00, 0xfa, 0x00, 0x22, 0x70, 0x0f, + 0xa8, 0x03, 0xce, 0x00, 0xca, 0xc0, 0xb2, 0xe4, + 0x0f, 0x34, 0x03, 0xe6, 0x20, 0xdb, 0x40, 0x3e, + 0xf4, 0x0d, 0xb0, 0x03, 0xec, 0xed, 0x09, 0x00, + 0xbf, 0x00, 0x00, 0xfb, 0x01, 0x37, 0xe5, 0x0b, + 0x30, 0x03, 0x26, 0x00, 0xb8, 0x50, 0x36, 0x22, + 0x0c, 0x9c, 0x03, 0xa3, 0x22, 0xc3, 0x00, 0x3e, + 0x74, 0x0f, 0xa8, 0x03, 0xe9, 0x80, 0xfa, 0x04, + 0x3a, 0x50, 0x0d, 0x90, 0x07, 0x2a, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, + 0xf8, 0x80, 0xbe, 0x52, 0x0f, 0xa0, 0x03, 0xef, + 0x02, 0xf8, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x0b, + 0xe5, 0x00, 0xdb, 0x00, 0x3e, 0xc0, 0x0e, 0xb0, + 0x03, 0xec, 0x01, 0xfb, 0x00, 0x0e, 0xc4, 0x0e, + 0xa0, 0x8b, 0xe0, 0x04, 0xf8, 0x00, 0x3e, 0x58, + 0x2f, 0x91, 0x43, 0x20, 0x00, 0xc9, 0x00, 0x3e, + 0x00, 0x0e, 0x80, 0x03, 0xed, 0x28, 0xf8, 0x40, + 0x16, 0x80, 0x05, 0x84, 0x03, 0xe0, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, + 0xf7, 0x00, 0x37, 0x00, 0x0c, 0xc0, 0x03, 0x2e, + 0xa4, 0xcd, 0x80, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, + 0x34, 0x22, 0xcf, 0x00, 0x3d, 0x80, 0x01, 0xf0, + 0x03, 0xfc, 0x00, 0xfd, 0x02, 0x36, 0xc1, 0x0e, + 0xc4, 0x03, 0x34, 0x00, 0xd5, 0x00, 0x29, 0x40, + 0x0c, 0x80, 0x03, 0xe4, 0x20, 0xdf, 0x00, 0xb5, + 0x40, 0x0c, 0xe0, 0x03, 0x30, 0x00, 0xca, 0x00, + 0x3f, 0x02, 0x0d, 0xf0, 0x11, 0x00, 0x44, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, + 0xbb, 0x40, 0x20, 0x20, 0x48, 0x8c, 0x8a, 0x2e, + 0x00, 0x8a, 0x48, 0x3c, 0xc0, 0x08, 0xb0, 0x12, + 0x44, 0x00, 0x8b, 0x00, 0x2e, 0x60, 0x08, 0xb0, + 0x03, 0xec, 0x00, 0xb1, 0x50, 0x22, 0xc0, 0x0b, + 0x80, 0x82, 0x26, 0x80, 0xa8, 0xc0, 0xb6, 0x70, + 0x28, 0x9c, 0x02, 0xe3, 0x20, 0xbb, 0x88, 0x22, + 0x30, 0x08, 0x0c, 0x03, 0xe7, 0x80, 0x88, 0x00, + 0x3a, 0x11, 0x01, 0xa9, 0x02, 0x20, 0x40, 0x10, + 0xed, 0x09, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x05, 0x2c, 0x00, 0xba, 0x40, 0x22, + 0x62, 0x08, 0x98, 0x02, 0x2c, 0x20, 0x89, 0x10, + 0x2e, 0xc0, 0x09, 0xb0, 0x02, 0x69, 0x40, 0x8b, + 0x00, 0x2e, 0xe0, 0x1b, 0xb0, 0x22, 0xec, 0x00, + 0xba, 0x08, 0x26, 0xc0, 0x0b, 0xb0, 0x22, 0x22, + 0x00, 0xa9, 0xc0, 0x62, 0x20, 0x08, 0x88, 0x02, + 0xe6, 0x00, 0xb8, 0x20, 0x22, 0x62, 0x1b, 0xa6, + 0x02, 0xa0, 0x45, 0x8b, 0x00, 0x2e, 0x60, 0x09, + 0x04, 0x02, 0xa0, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb0, 0x00, 0x22, + 0x40, 0x08, 0x00, 0x02, 0x00, 0x00, 0x83, 0x00, + 0x2a, 0xc0, 0x08, 0xb0, 0x02, 0x68, 0x00, 0x83, + 0x00, 0x2c, 0xc0, 0x09, 0x30, 0x02, 0x8c, 0x00, + 0xb2, 0x00, 0x24, 0xc0, 0x0b, 0x80, 0x12, 0x00, + 0x00, 0xa1, 0x05, 0x28, 0x00, 0x48, 0x00, 0x10, + 0xc4, 0x00, 0xb0, 0x00, 0x20, 0x00, 0x49, 0x00, + 0x02, 0xc0, 0x00, 0x83, 0x00, 0x28, 0x80, 0x01, + 0x00, 0x02, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xf3, 0x00, 0x32, + 0x01, 0x0c, 0x80, 0x03, 0x2c, 0x00, 0xcb, 0x00, + 0x2e, 0xc0, 0x0d, 0xb0, 0x03, 0x68, 0x04, 0xcb, + 0x04, 0x3e, 0x80, 0x0f, 0xb0, 0x02, 0xec, 0x00, + 0xf8, 0x00, 0x37, 0xc0, 0x0f, 0x90, 0x2b, 0x20, + 0x08, 0xf9, 0x00, 0x2a, 0x40, 0x0c, 0x80, 0x10, + 0xe4, 0x00, 0xd8, 0x00, 0x32, 0x40, 0x8f, 0xa0, + 0x01, 0x20, 0x00, 0xc8, 0x00, 0x3c, 0x00, 0x0d, + 0x80, 0x0b, 0x80, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x19, 0xfc, 0x00, 0xff, 0x00, 0x3b, + 0x01, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x3c, 0x00, + 0x2f, 0xc0, 0x0f, 0x70, 0x03, 0xb8, 0x00, 0xff, + 0x00, 0x3f, 0xc1, 0x0e, 0xf0, 0x03, 0xfc, 0x00, + 0xfc, 0x00, 0x3b, 0xed, 0x09, 0x00, 0xc1, 0x00, + 0xc0, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, + 0x27, 0x00, 0x0f, 0xc0, 0x13, 0xf0, 0x00, 0xfc, + 0x00, 0x3f, 0x00, 0x8e, 0xc0, 0x01, 0x70, 0x00, + 0xfc, 0x00, 0x3f, 0x00, 0x09, 0xc0, 0x13, 0x68, + 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, + 0xfc, 0x44, 0xfc, 0x01, 0x3b, 0xc6, 0x8c, 0xe0, + 0x03, 0xfc, 0x22, 0xcf, 0x23, 0x33, 0xc8, 0x0f, + 0xf0, 0x03, 0x7c, 0x20, 0xff, 0x10, 0x3b, 0xd0, + 0x0f, 0xf6, 0x03, 0x30, 0x00, 0xfc, 0x08, 0x3f, + 0x00, 0x0f, 0xf1, 0x03, 0xb0, 0x80, 0xff, 0x00, + 0x3f, 0xc0, 0x09, 0xf3, 0x03, 0x30, 0x40, 0xdc, + 0x10, 0x37, 0x00, 0x8d, 0xc3, 0x03, 0x30, 0x20, + 0x4c, 0x00, 0x1f, 0xc2, 0x0f, 0xf0, 0x03, 0xf0, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x90, + 0x8c, 0x80, 0xb3, 0x08, 0x23, 0xc8, 0x08, 0x90, + 0x82, 0xfd, 0x00, 0x8f, 0x50, 0x23, 0xc4, 0x8b, + 0x32, 0x02, 0xfc, 0x00, 0xbb, 0x20, 0xa3, 0xd4, + 0x0b, 0xf6, 0x02, 0x20, 0x20, 0xb8, 0x00, 0x2e, + 0x4a, 0x0e, 0xf0, 0x02, 0x20, 0xa0, 0xbf, 0x00, + 0x0f, 0xc0, 0x0b, 0xf2, 0x02, 0xa0, 0x80, 0xc8, + 0x01, 0x2e, 0x14, 0x08, 0x81, 0x02, 0xa0, 0x00, + 0x88, 0x00, 0x2e, 0xd8, 0x0b, 0xb0, 0x02, 0xe0, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xca, 0x04, + 0x8c, 0x80, 0xbb, 0x20, 0x28, 0xc0, 0x08, 0x12, + 0x02, 0xcc, 0x00, 0x83, 0x00, 0x20, 0xc0, 0x0b, + 0x30, 0x82, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc8, + 0x0b, 0x31, 0x02, 0x00, 0x40, 0xb0, 0x08, 0x0c, + 0x40, 0x8b, 0x33, 0x02, 0x00, 0x40, 0xb3, 0x00, + 0x2c, 0xc1, 0x49, 0x36, 0x02, 0x80, 0x00, 0xa0, + 0xa5, 0x2c, 0x00, 0x0b, 0x02, 0x02, 0x00, 0x01, + 0x82, 0x82, 0x64, 0xc2, 0x0b, 0x30, 0x02, 0xe2, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0xc2, 0x00, 0xc0, 0x14, 0xac, 0x00, 0xb9, + 0x50, 0x62, 0xc0, 0x88, 0xb0, 0x02, 0xec, 0x00, + 0x8b, 0x02, 0x22, 0xc0, 0x0b, 0xb0, 0x22, 0xec, + 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0x26, 0x20, 0xb9, 0x80, 0x2e, 0xc1, 0x0a, 0xb0, + 0x42, 0x22, 0x00, 0xbb, 0x00, 0x2e, 0xc1, 0x0b, + 0xb0, 0x02, 0xa8, 0x20, 0xab, 0x00, 0x2e, 0x20, + 0x2a, 0x8c, 0x02, 0xa3, 0x00, 0x2a, 0x80, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xf0, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x44, 0xac, 0x08, 0xf3, + 0x80, 0x3a, 0xc0, 0x0c, 0x95, 0x03, 0xec, 0x00, + 0x4b, 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x43, 0xec, + 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x03, + 0x22, 0x00, 0xf8, 0xc0, 0x3e, 0x74, 0x0f, 0xb0, + 0x03, 0x23, 0x80, 0xbb, 0x00, 0x3e, 0xc0, 0x0d, + 0xb0, 0x13, 0xa1, 0x03, 0xe8, 0x80, 0x34, 0x30, + 0x4f, 0x88, 0x03, 0x03, 0x00, 0xc8, 0x00, 0x36, + 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x11, 0xbc, 0x00, 0xfe, + 0x80, 0x3d, 0xc0, 0x0f, 0xd8, 0x13, 0xdc, 0x00, + 0xf7, 0x00, 0xbf, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x01, 0x37, 0xc0, 0x0f, 0xf0, 0x0b, + 0xf4, 0x00, 0x9d, 0x00, 0x3f, 0xc0, 0x1f, 0xb0, + 0x03, 0x64, 0x00, 0xff, 0x00, 0x3f, 0xc1, 0x0f, + 0xf0, 0x43, 0xf2, 0x40, 0xdf, 0x24, 0x3e, 0x01, + 0x09, 0x40, 0x03, 0xf0, 0x20, 0xde, 0x08, 0x1f, + 0xc0, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x44, 0x10, 0xac, 0x00, 0xcb, + 0x40, 0xb2, 0xc1, 0x0c, 0x84, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, 0x2c, + 0x20, 0xcb, 0x00, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, + 0x62, 0x00, 0xf8, 0x60, 0x3e, 0x50, 0x0f, 0xb0, + 0x83, 0xed, 0x09, 0x00, 0xc3, 0x00, 0x24, 0x02, + 0xcb, 0x00, 0x3e, 0xc4, 0x0f, 0xb2, 0x03, 0xe9, + 0x00, 0xf8, 0x80, 0x3e, 0x00, 0x84, 0x84, 0x03, + 0x60, 0x40, 0xda, 0x12, 0x7e, 0xc0, 0x4c, 0xb0, + 0x43, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xd8, 0x05, 0x2c, 0x00, 0x8b, 0x00, 0x23, 0xc0, + 0x08, 0x90, 0x02, 0xfc, 0x00, 0xbf, 0x88, 0x2b, + 0xc0, 0x0b, 0xb0, 0x02, 0x3c, 0x00, 0x8b, 0x02, + 0x3b, 0xd0, 0x08, 0xf0, 0x02, 0xe5, 0x08, 0xb9, + 0x48, 0x2e, 0xc4, 0x0e, 0xf0, 0x02, 0x24, 0x00, + 0x8f, 0x0f, 0x33, 0xf4, 0x0b, 0xfc, 0x83, 0xa8, + 0x00, 0xfb, 0x80, 0x2e, 0x60, 0x0d, 0x80, 0x02, + 0xe0, 0x00, 0x9b, 0x00, 0x2f, 0xc0, 0x08, 0xb0, + 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x04, 0x4c, 0x08, 0x83, 0x00, 0x24, 0xc0, + 0x08, 0x10, 0x02, 0xce, 0xc0, 0x93, 0x48, 0x28, + 0xc0, 0x0b, 0x30, 0x40, 0x0c, 0x40, 0x8b, 0x00, + 0x2c, 0xc2, 0x0b, 0xb0, 0x02, 0xc1, 0x80, 0x90, + 0xc4, 0x6c, 0x40, 0x0b, 0xb0, 0x0a, 0x00, 0x00, + 0x83, 0x20, 0x28, 0xe0, 0x09, 0xbc, 0x02, 0x20, + 0x08, 0xb0, 0x00, 0x24, 0x20, 0x08, 0x00, 0x02, + 0x82, 0x00, 0xb0, 0xc0, 0x20, 0xc0, 0x08, 0x30, + 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xb0, 0x50, 0x5e, 0x02, 0x87, 0x80, 0x24, 0xe4, + 0x08, 0x49, 0x02, 0xde, 0x00, 0xb3, 0x90, 0x29, + 0xe0, 0x0b, 0x78, 0x02, 0x0e, 0x00, 0x87, 0x82, + 0x29, 0xe0, 0x0a, 0x78, 0x02, 0xd2, 0x10, 0xb4, + 0x80, 0x0d, 0x60, 0x1a, 0x78, 0x02, 0x16, 0x00, + 0x83, 0x80, 0x21, 0xe4, 0x0b, 0x78, 0x06, 0x9a, + 0x00, 0xb4, 0x80, 0x2d, 0x24, 0x09, 0x48, 0x42, + 0xd6, 0x00, 0xb6, 0x80, 0x2d, 0xe0, 0x08, 0x78, + 0x02, 0xc8, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x08, 0x4c, 0x00, 0xed, 0x09, 0x00, 0xc4, + 0x00, 0xc2, 0x00, 0x34, 0xc0, 0x0c, 0x14, 0x02, + 0xcc, 0x40, 0xf3, 0x10, 0x38, 0xc0, 0x0f, 0x31, + 0x03, 0x0c, 0x02, 0x83, 0x00, 0x3e, 0xc2, 0x0f, + 0x30, 0x02, 0x4c, 0x80, 0xf3, 0x00, 0x2c, 0xc4, + 0x0b, 0x31, 0x03, 0x0c, 0x00, 0x83, 0x00, 0x3c, + 0xc0, 0x8f, 0x30, 0x03, 0x80, 0x80, 0xf3, 0x00, + 0x3c, 0x12, 0x5c, 0x01, 0x13, 0x00, 0x00, 0x52, + 0x10, 0x3a, 0xc0, 0x2c, 0x30, 0x43, 0xd2, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xbc, + 0x40, 0xff, 0x00, 0x3b, 0xd0, 0x0f, 0xd0, 0x03, + 0xfc, 0x20, 0xff, 0x10, 0x37, 0xc0, 0x0f, 0xf0, + 0x0b, 0xfc, 0x40, 0xff, 0x00, 0x2b, 0xc0, 0x4d, + 0xf1, 0x13, 0xfc, 0x00, 0xff, 0x10, 0x3f, 0xc0, + 0x8f, 0xf5, 0x83, 0xfc, 0x00, 0xff, 0x18, 0x3f, + 0xc2, 0x0f, 0xf0, 0x83, 0xb8, 0x00, 0xef, 0x00, + 0x17, 0x80, 0x5f, 0xc0, 0x43, 0xfc, 0x40, 0xde, + 0x00, 0x3f, 0xc0, 0x0f, 0xf1, 0x01, 0xd0, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0xac, + 0x00, 0xf9, 0x00, 0x3e, 0xd0, 0x08, 0xb8, 0x03, + 0x2d, 0x00, 0xfb, 0x70, 0x3e, 0xcc, 0x0f, 0xb0, + 0x03, 0xed, 0x80, 0xfb, 0x00, 0x3e, 0xc2, 0x07, + 0xbb, 0x23, 0xec, 0x04, 0xfb, 0x86, 0x32, 0xc0, + 0x0f, 0xb2, 0x41, 0x60, 0x00, 0xfb, 0xca, 0x3a, + 0xf0, 0x0e, 0xbc, 0x03, 0x0a, 0x00, 0xeb, 0x00, + 0x7c, 0x00, 0x4d, 0x80, 0x23, 0xa2, 0x04, 0xc8, + 0x00, 0x3e, 0xc4, 0x0f, 0xb0, 0x03, 0xea, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x98, 0x9c, + 0x00, 0xb7, 0x00, 0x2d, 0xd8, 0x08, 0x50, 0x02, + 0x1c, 0x48, 0xb3, 0x10, 0x21, 0xcc, 0x0b, 0x70, + 0x02, 0xdc, 0xc0, 0xb7, 0x04, 0x2d, 0xd8, 0x49, + 0x70, 0x92, 0x1c, 0x10, 0xbf, 0x00, 0x21, 0xc0, + 0x0e, 0x72, 0x02, 0xd4, 0x00, 0xb7, 0x00, 0xed, + 0x09, 0x00, 0xc5, 0x00, 0x28, 0xca, 0x08, 0x31, + 0x02, 0x9c, 0x00, 0x87, 0x00, 0x2d, 0x41, 0x08, + 0x40, 0x02, 0xd4, 0x00, 0xa7, 0x00, 0x2d, 0xc8, + 0x0b, 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x1e, 0x00, 0xb7, 0xc0, + 0x29, 0xe0, 0x08, 0xd8, 0x22, 0x1e, 0x80, 0xb7, + 0x80, 0x25, 0xe0, 0x0b, 0x78, 0x02, 0x1e, 0x40, + 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x06, 0x9e, + 0x00, 0xb7, 0x80, 0x21, 0xe0, 0x0b, 0x78, 0x02, + 0x5e, 0x00, 0xb3, 0xa2, 0x29, 0xe8, 0x0a, 0x7a, + 0x02, 0x3e, 0x00, 0xa7, 0x80, 0x2d, 0x21, 0x09, + 0x48, 0x12, 0xca, 0x00, 0xa6, 0x80, 0x6d, 0xe0, + 0x0b, 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x04, 0xcc, 0x00, 0xb0, 0x80, + 0x2e, 0xc0, 0x28, 0x24, 0x02, 0x0c, 0x00, 0xbb, + 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x09, 0x30, 0x02, 0x0c, + 0x84, 0xb3, 0xc8, 0x22, 0xe0, 0x0a, 0x30, 0x02, + 0xec, 0x20, 0xb3, 0x02, 0x28, 0xc0, 0x08, 0x30, + 0x02, 0x8c, 0x00, 0xa3, 0x80, 0x2c, 0xd0, 0x08, + 0x39, 0x02, 0xcc, 0x05, 0xa3, 0x01, 0x2c, 0xc0, + 0x1b, 0x30, 0x02, 0xd2, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x15, 0xe8, 0x00, 0xfe, 0x40, + 0x3e, 0x80, 0x0c, 0xe4, 0x03, 0x28, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x13, 0x28, 0x08, + 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xf8, + 0x00, 0xfe, 0x84, 0x33, 0xb6, 0x0f, 0xa0, 0x02, + 0x79, 0x00, 0xfa, 0x00, 0x3a, 0x80, 0x06, 0xa0, + 0x03, 0x3b, 0x00, 0x6e, 0x0b, 0x3d, 0x80, 0x0d, + 0xec, 0x03, 0xfa, 0x20, 0xc6, 0xc8, 0x3e, 0x80, + 0x0f, 0xa0, 0x03, 0xfa, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x01, 0xa0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0xed, 0x09, 0x00, 0xc6, 0x00, 0x0f, + 0x82, 0x0b, 0xe1, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x01, 0xe0, 0x00, 0xf8, 0x02, 0x3e, + 0x00, 0x09, 0x80, 0x13, 0xe0, 0x00, 0xb8, 0x10, + 0xbe, 0x00, 0x0f, 0x84, 0x13, 0xe0, 0x00, 0xf8, + 0x40, 0x36, 0x00, 0x0f, 0x80, 0x03, 0xe2, 0x40, + 0xd8, 0x00, 0x3e, 0x08, 0x4f, 0x80, 0x82, 0xe0, + 0x00, 0xf8, 0xc0, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x10, 0xa4, 0x08, 0xf9, 0x08, 0x3e, 0x40, 0x0c, + 0x90, 0x03, 0xe5, 0x00, 0xf9, 0x02, 0x32, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x40, 0x79, 0x00, 0x32, + 0x40, 0x0f, 0x90, 0x43, 0xa4, 0x04, 0xf9, 0x00, + 0x3e, 0x40, 0x04, 0x90, 0x03, 0xe4, 0x00, 0xc9, + 0x22, 0x3e, 0x64, 0x0f, 0x90, 0x03, 0xe4, 0x08, + 0xf9, 0x08, 0x3e, 0x40, 0x0e, 0x90, 0x01, 0xa4, + 0x80, 0xf9, 0x00, 0x30, 0x40, 0x0e, 0x90, 0x03, + 0xc2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x28, + 0x90, 0x02, 0xe5, 0x80, 0xb9, 0x80, 0xaa, 0x40, + 0x0b, 0x90, 0x02, 0xe4, 0x04, 0xb9, 0x00, 0xa2, + 0x50, 0x0b, 0x90, 0x02, 0xe5, 0x00, 0x99, 0x00, + 0x2e, 0x40, 0x08, 0x9c, 0x02, 0xe4, 0x02, 0x89, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x80, 0x2e, 0x40, 0x08, 0x90, 0x02, 0xe4, + 0x08, 0xb9, 0x00, 0x22, 0x40, 0x08, 0x90, 0x02, + 0x60, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0a, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x20, 0x2a, 0x40, + 0x4b, 0x90, 0x42, 0x64, 0x00, 0xb1, 0x00, 0x26, + 0x40, 0x8b, 0x90, 0x02, 0x24, 0x40, 0xbb, 0x19, + 0x2e, 0xc0, 0x1a, 0x91, 0x02, 0xe4, 0x00, 0x89, + 0x40, 0x2e, 0x50, 0x0b, 0x90, 0xed, 0x09, 0x00, + 0xc7, 0x00, 0x82, 0xe4, 0x00, 0x39, 0x28, 0x26, + 0x40, 0x0a, 0x90, 0x02, 0xa4, 0x20, 0xb9, 0x80, + 0x26, 0x40, 0x0a, 0x90, 0x02, 0xc6, 0x04, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x14, 0x05, 0x00, + 0xb1, 0x40, 0x2c, 0x50, 0x0a, 0x14, 0x02, 0xc4, + 0x00, 0xb1, 0x68, 0x28, 0x40, 0x0b, 0x14, 0x02, + 0xc4, 0x00, 0xb1, 0x40, 0x24, 0xd0, 0x0b, 0x14, + 0x02, 0xc4, 0xa0, 0xb1, 0x28, 0x0c, 0xd0, 0x28, + 0x12, 0x82, 0xc5, 0x10, 0x81, 0x40, 0x2c, 0x51, + 0x0b, 0x12, 0x82, 0xc5, 0x00, 0xb1, 0x40, 0x0c, + 0x40, 0x08, 0x14, 0x02, 0xc4, 0x00, 0xbb, 0x00, + 0x24, 0x50, 0x08, 0x10, 0x02, 0x42, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0d, 0x60, 0x00, + 0xf8, 0x00, 0x3c, 0x00, 0x0e, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x20, 0x12, 0x00, 0x4f, 0x80, 0x07, + 0xe8, 0x00, 0xf8, 0x00, 0x36, 0x00, 0x0f, 0x00, + 0x03, 0xa8, 0x80, 0xf8, 0x20, 0x3e, 0x00, 0x4e, + 0xa2, 0x23, 0xe0, 0x00, 0xc8, 0x00, 0x3e, 0x00, + 0x0f, 0x82, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0e, 0x80, 0x03, 0xa0, 0x00, 0xf8, 0x00, + 0xb6, 0x00, 0x2e, 0x80, 0x03, 0xee, 0x03, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x98, 0x95, 0xe4, 0x00, + 0xfd, 0x00, 0x3e, 0x50, 0x0d, 0x50, 0x03, 0xe5, + 0x04, 0xf9, 0x00, 0x3e, 0x50, 0x0f, 0x90, 0x21, + 0xe5, 0x00, 0xf9, 0x00, 0x3a, 0x50, 0x0f, 0x94, + 0x13, 0xf4, 0xa0, 0xdd, 0x28, 0x3f, 0x40, 0x4d, + 0x92, 0x83, 0xf5, 0x00, 0x79, 0x40, 0x3e, 0x50, + 0x0f, 0x92, 0xc3, 0xf4, 0x10, 0xfd, 0x00, 0x2f, + 0x50, 0x0f, 0xf4, 0x13, 0xf5, 0x10, 0xff, 0x00, + 0x3a, 0x50, 0x8f, 0x90, 0x03, 0xe6, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, 0x40, + 0xf9, 0x00, 0x32, 0x40, 0x0f, 0xb1, 0x03, 0xf4, + 0xed, 0x09, 0x00, 0xc8, 0x00, 0x80, 0xfd, 0x20, + 0x3e, 0x48, 0x0c, 0x90, 0x02, 0x34, 0x00, 0xc9, + 0x10, 0x3f, 0x4c, 0x0c, 0x92, 0x83, 0x3c, 0x00, + 0xfd, 0x12, 0x3d, 0x41, 0x0f, 0xd2, 0x83, 0xe4, + 0x80, 0xfd, 0x28, 0x3f, 0x4c, 0x0c, 0xd1, 0x03, + 0xe4, 0x00, 0xfd, 0x00, 0x3f, 0x48, 0x0d, 0x90, + 0x07, 0xb4, 0x00, 0xdd, 0x00, 0x32, 0x40, 0x0f, + 0x90, 0x03, 0xc6, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x18, 0xe0, 0x80, 0xb8, 0x08, 0x22, + 0x03, 0x0b, 0x20, 0x02, 0xe0, 0x00, 0xb8, 0x20, + 0x2e, 0x04, 0x08, 0x80, 0x82, 0x20, 0x00, 0x88, + 0x02, 0x2e, 0x08, 0x08, 0x82, 0x02, 0x28, 0x20, + 0x3a, 0x10, 0x26, 0x0b, 0x0f, 0x82, 0x02, 0xc8, + 0xe0, 0xb8, 0x20, 0x2e, 0x0c, 0x0a, 0x81, 0x02, + 0xe8, 0x21, 0xb8, 0x20, 0x2e, 0x04, 0x08, 0x86, + 0x22, 0xe0, 0x40, 0xb8, 0x00, 0x22, 0x02, 0x0b, + 0x80, 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x84, 0x80, 0xb1, 0x20, 0x20, + 0x44, 0x0b, 0x10, 0x02, 0xc4, 0x40, 0xb1, 0x38, + 0x2c, 0x40, 0x28, 0x12, 0x02, 0x04, 0x40, 0x81, + 0x00, 0x2c, 0x4c, 0x28, 0x12, 0xca, 0x04, 0x51, + 0xb1, 0x00, 0x2c, 0x48, 0x0b, 0x12, 0x82, 0xc4, + 0x80, 0xb1, 0x28, 0x28, 0x48, 0x09, 0x10, 0x02, + 0xc4, 0x00, 0xb1, 0x28, 0x2c, 0x41, 0x19, 0x13, + 0x92, 0xc4, 0x00, 0xb1, 0x00, 0x20, 0x44, 0x0b, + 0x10, 0x02, 0xc2, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x04, 0xa4, 0x00, 0xb9, 0x00, 0x22, + 0x40, 0x0b, 0x91, 0x02, 0xe4, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x08, 0x90, 0x0a, 0x24, 0x00, 0x89, + 0x00, 0x2e, 0x40, 0x08, 0x90, 0x02, 0x24, 0x04, + 0xb9, 0x00, 0x2e, 0x41, 0x8b, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x22, + 0xe4, 0x00, 0xb9, 0xed, 0x09, 0x00, 0xc9, 0x00, + 0x40, 0x2e, 0x40, 0x88, 0x90, 0x02, 0xee, 0x00, + 0xb9, 0x00, 0x22, 0x40, 0x0b, 0x90, 0x00, 0xc6, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, + 0xe4, 0x00, 0xf9, 0x70, 0x32, 0x40, 0x07, 0x94, + 0x13, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0c, + 0x90, 0x03, 0x24, 0x00, 0xc9, 0x00, 0x3e, 0x40, + 0x4c, 0x90, 0x03, 0x26, 0x00, 0xf9, 0xc0, 0x3e, + 0x78, 0x0b, 0x90, 0x03, 0xe7, 0x00, 0xf9, 0x01, + 0x3a, 0x41, 0x4d, 0x90, 0x03, 0xe7, 0x10, 0xb9, + 0xc0, 0x2c, 0x4c, 0x0d, 0x9d, 0x03, 0xe6, 0x04, + 0xf9, 0x40, 0xb2, 0x40, 0x0f, 0x90, 0x03, 0xe8, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, + 0xa4, 0x00, 0xf9, 0x80, 0xbe, 0x40, 0x0f, 0x98, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x2c, 0x41, 0x0f, + 0x90, 0x03, 0xc4, 0x12, 0xf9, 0x00, 0x3c, 0x40, + 0x0f, 0x10, 0x03, 0xe4, 0xa0, 0xf9, 0x28, 0x36, + 0x48, 0x0e, 0x90, 0x03, 0xe4, 0x40, 0xf9, 0x00, + 0x3e, 0x40, 0x04, 0x90, 0x03, 0xe6, 0x40, 0xf9, + 0x92, 0x3e, 0x42, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x90, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xca, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0x20, 0x00, 0xc8, 0x40, 0x3e, 0x00, 0x0e, 0x84, + 0x0b, 0x22, 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x80, 0xd8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe1, 0x04, 0xd8, 0x45, 0x3e, + 0x11, 0x0d, 0x80, 0x47, 0xe1, 0x02, 0xc8, 0x00, + 0x34, 0x00, 0x0e, 0x80, 0x0b, 0x61, 0x00, 0xb8, + 0x00, 0x32, 0x00, 0x0f, 0x84, 0x01, 0xe0, 0x20, + 0xf8, 0x40, 0x3e, 0x00, 0x0f, 0x80, 0x41, 0xca, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x28, 0x00, 0x8a, 0x00, 0x2e, 0x80, 0x0b, 0xa0, + 0x02, 0x3b, 0x80, 0xbe, 0x90, 0x2a, 0xed, 0x09, + 0x00, 0xca, 0x00, 0x80, 0x0b, 0xa0, 0x03, 0xb8, + 0x00, 0x8a, 0x00, 0x0f, 0x80, 0x0b, 0xa0, 0x02, + 0xf9, 0x00, 0x3e, 0x40, 0x2f, 0x90, 0x08, 0xe9, + 0x02, 0xe8, 0x00, 0x8e, 0xcc, 0x2b, 0xa9, 0x08, + 0xe8, 0x03, 0x28, 0x00, 0xbe, 0x00, 0x37, 0x80, + 0x8b, 0xa0, 0x02, 0xfb, 0x00, 0xb6, 0xa0, 0x2e, + 0x80, 0x0b, 0xa0, 0x02, 0xca, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x04, 0x0c, 0x00, 0x9b, + 0x00, 0x2c, 0xc0, 0x0a, 0x30, 0x02, 0x0e, 0x00, + 0xb3, 0xd0, 0x20, 0xc0, 0x0b, 0xb0, 0x02, 0x87, + 0x40, 0x93, 0x00, 0x24, 0xe8, 0x0b, 0x30, 0x02, + 0x8c, 0x00, 0xb3, 0x00, 0x2c, 0xdc, 0x09, 0x30, + 0x02, 0x4c, 0x00, 0x83, 0x48, 0x20, 0xc2, 0x0a, + 0x30, 0x82, 0x8c, 0x00, 0xb3, 0x80, 0x28, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x40, 0x33, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x10, 0x5e, 0xc2, 0x97, + 0x20, 0x2d, 0xcc, 0x0b, 0x78, 0x02, 0x10, 0x08, + 0xb3, 0x00, 0x2d, 0xc0, 0x0b, 0x72, 0x02, 0x98, + 0x00, 0x87, 0x01, 0x2d, 0xc2, 0x8b, 0x72, 0x12, + 0xdc, 0x00, 0xb7, 0x00, 0x2f, 0xe0, 0x08, 0x74, + 0x12, 0xde, 0x40, 0x87, 0x80, 0x28, 0xe0, 0x08, + 0x38, 0x82, 0x1c, 0x80, 0xb5, 0xc2, 0x2d, 0xc0, + 0x1b, 0x72, 0x02, 0xdc, 0x00, 0x37, 0x02, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x88, 0x3e, 0xc0, 0xd7, + 0x81, 0x2d, 0xe8, 0x0e, 0x78, 0x03, 0x12, 0x00, + 0xf7, 0x00, 0x31, 0xe0, 0x0f, 0x7d, 0x03, 0x9a, + 0x00, 0xd7, 0x90, 0x3d, 0xe0, 0x8f, 0x7a, 0x13, + 0xde, 0x10, 0xf7, 0x80, 0x2d, 0xe0, 0x0d, 0x78, + 0x02, 0x5e, 0x80, 0xce, 0x80, 0x35, 0xc0, 0x0e, + 0x78, 0x03, 0x1e, 0xc9, 0xfc, 0x80, 0x79, 0xe0, + 0x0b, 0xed, 0x09, 0x00, 0xcb, 0x00, 0x78, 0x03, + 0xde, 0x00, 0xf7, 0x80, 0x2d, 0xf8, 0x0f, 0x78, + 0x03, 0xe2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x15, 0xac, 0x80, 0xeb, 0x78, 0x3e, 0xda, + 0x0f, 0xb7, 0x83, 0xe8, 0x00, 0xfb, 0x00, 0x3a, + 0xc0, 0x0f, 0xb0, 0x03, 0x84, 0x00, 0xfb, 0x20, + 0x3e, 0xc0, 0x0b, 0xb6, 0x03, 0x60, 0x04, 0xf9, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x02, 0xec, 0x90, + 0xf9, 0x04, 0x3e, 0x00, 0x0f, 0xb0, 0x03, 0xad, + 0x80, 0xf8, 0x00, 0x36, 0xc0, 0x0f, 0xb0, 0x03, + 0xe4, 0x00, 0xf8, 0x00, 0x36, 0xc0, 0x0f, 0xb0, + 0x03, 0xc2, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x04, 0xbe, 0x00, 0xff, 0x80, 0x3f, 0xe0, + 0x0f, 0x72, 0x03, 0x32, 0x00, 0xef, 0x00, 0x3f, + 0xe1, 0x8c, 0xf2, 0x03, 0xfa, 0x00, 0xff, 0x88, + 0x3f, 0xe0, 0x0f, 0xfc, 0x83, 0xfe, 0x00, 0xef, + 0x10, 0x35, 0x60, 0x0c, 0xf8, 0x03, 0x3f, 0x00, + 0xff, 0x80, 0x37, 0xa0, 0x0c, 0xf8, 0x02, 0xfe, + 0x60, 0xfd, 0x80, 0x3f, 0xe4, 0x0e, 0xf8, 0x83, + 0x3e, 0x00, 0xff, 0x80, 0x1f, 0xe5, 0x0f, 0xf8, + 0x01, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0x18, 0x9c, 0x00, 0xb7, 0x18, 0x2d, 0xc0, + 0x0b, 0x71, 0x02, 0x10, 0x00, 0x87, 0x50, 0x21, + 0xc0, 0x0d, 0x70, 0x03, 0xd8, 0x40, 0xb7, 0x00, + 0x2d, 0x00, 0x0b, 0x70, 0x03, 0xdd, 0x00, 0x86, + 0x10, 0x2d, 0x48, 0x0d, 0x64, 0x02, 0x9c, 0x00, + 0xb5, 0x00, 0x2f, 0x44, 0x0d, 0x51, 0x02, 0xdc, + 0x60, 0xb5, 0x29, 0x2d, 0xc0, 0x88, 0xf0, 0x0a, + 0x18, 0x40, 0xb7, 0x10, 0x2d, 0xc0, 0x0d, 0x70, + 0x02, 0x6a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0xf0, 0x02, 0x10, 0x00, 0xb1, 0x10, 0x28, + 0xc0, 0x08, 0x71, 0x02, 0xed, 0x09, 0x00, 0xcc, + 0x00, 0xd8, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xdc, 0x40, 0x87, 0x01, 0x27, 0x00, + 0x08, 0x10, 0x02, 0x9c, 0x00, 0xb7, 0x00, 0x2d, + 0x80, 0x08, 0x60, 0x02, 0x5c, 0x04, 0x94, 0x02, + 0x2d, 0xc0, 0x8a, 0x70, 0x0a, 0x1c, 0x20, 0xb7, + 0x40, 0x2d, 0xc1, 0x0b, 0x70, 0x02, 0xc0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0xcc, + 0x01, 0xb3, 0x40, 0x2c, 0xc0, 0x8b, 0xb4, 0x02, + 0x00, 0x10, 0x93, 0x00, 0x20, 0xc0, 0x08, 0x30, + 0x22, 0xc8, 0x00, 0xb3, 0x00, 0x2c, 0x00, 0x0b, + 0x30, 0x02, 0xa1, 0x80, 0x80, 0x20, 0x2c, 0x00, + 0x09, 0x00, 0x0a, 0x8d, 0x00, 0x31, 0x02, 0x2c, + 0x00, 0x01, 0x00, 0x02, 0xce, 0x20, 0xb0, 0xc0, + 0x2c, 0xc2, 0x08, 0x3c, 0x02, 0x03, 0x00, 0xb0, + 0x80, 0x2e, 0xc0, 0x08, 0x30, 0x02, 0x40, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xfc, + 0x00, 0xf7, 0x80, 0x3f, 0xc0, 0x0f, 0xf5, 0x23, + 0x20, 0x00, 0xfb, 0x00, 0x3a, 0xc0, 0x08, 0xf0, + 0x03, 0xe8, 0x00, 0xff, 0x00, 0x0e, 0x40, 0x07, + 0xf0, 0x02, 0xe5, 0x00, 0xc9, 0x00, 0x36, 0x64, + 0x0c, 0x90, 0x43, 0x3d, 0x40, 0xb9, 0x00, 0x1e, + 0x40, 0x48, 0x90, 0x42, 0xfe, 0x00, 0x98, 0xc0, + 0x2e, 0xc0, 0x0e, 0xf0, 0x82, 0x2e, 0x00, 0xfb, + 0xc0, 0x3f, 0xc0, 0x0b, 0xb0, 0x02, 0xe2, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xac, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb1, 0x0b, + 0xc0, 0x00, 0xe3, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xa9, 0x00, 0xfb, 0x00, 0x3c, 0x50, 0x0f, + 0x30, 0x03, 0xe4, 0x00, 0x99, 0x00, 0x3e, 0x14, + 0x0e, 0x94, 0x02, 0x6c, 0x00, 0xf8, 0x40, 0x3e, + 0x40, 0x0f, 0x80, 0x03, 0xec, 0x04, 0xf8, 0x09, + 0x2e, 0x71, 0x0f, 0xb0, 0x03, 0xed, 0x00, 0xed, + 0x09, 0x00, 0xcd, 0x00, 0xfb, 0x12, 0x3e, 0xc0, + 0x0d, 0xb0, 0x03, 0x60, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x10, 0xbc, 0x00, 0xff, 0x08, + 0x37, 0xc0, 0x0f, 0xf0, 0x03, 0x30, 0x40, 0xcf, + 0x00, 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xfb, 0x00, + 0xdf, 0x00, 0x3f, 0x00, 0x0c, 0xf0, 0x03, 0x24, + 0x00, 0xc4, 0x00, 0x33, 0x41, 0x0f, 0xc0, 0x03, + 0xfc, 0x10, 0xfe, 0x00, 0x33, 0xa0, 0x0e, 0xd0, + 0x03, 0xfc, 0x00, 0xec, 0x00, 0x33, 0xe0, 0x8d, + 0xf0, 0x81, 0xfa, 0x28, 0xff, 0xc0, 0x1f, 0xc0, + 0x0c, 0xf0, 0x03, 0x40, 0x44, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xa1, 0x04, 0x6c, 0x00, 0xbb, 0x00, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0x21, 0x80, 0x8b, + 0x82, 0x2e, 0xc1, 0x0b, 0xb0, 0x02, 0xca, 0x00, + 0x8b, 0x00, 0x2e, 0x31, 0x08, 0xb0, 0x02, 0x22, + 0x00, 0x88, 0xc0, 0x22, 0x32, 0x0b, 0x88, 0x02, + 0xec, 0x00, 0x98, 0x58, 0x2a, 0x18, 0x0a, 0x8e, + 0x22, 0xec, 0x00, 0x80, 0xc8, 0xa2, 0x50, 0x0b, + 0xb0, 0x02, 0xe1, 0x40, 0xb8, 0x80, 0x2e, 0xc0, + 0x08, 0xb0, 0x02, 0xe8, 0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, 0xbb, 0x00, + 0x26, 0xc0, 0x0b, 0xb0, 0x02, 0x68, 0x00, 0x89, + 0x80, 0x26, 0xc0, 0x0b, 0xb0, 0x02, 0xe5, 0x00, + 0xbb, 0x00, 0x2e, 0x62, 0x08, 0xb0, 0x02, 0x22, + 0x10, 0x89, 0x88, 0x26, 0x60, 0x4b, 0x98, 0x22, + 0xec, 0x00, 0xb2, 0x00, 0x24, 0xc4, 0x00, 0x98, + 0x12, 0xcc, 0x00, 0x88, 0x80, 0x22, 0x98, 0x09, + 0xb0, 0x12, 0xe4, 0x00, 0x99, 0x00, 0x2e, 0xc0, + 0x88, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x14, 0x0c, 0x00, 0xbb, 0x00, + 0x24, 0xc0, 0x8b, 0x30, 0x02, 0x40, 0x02, 0x82, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x00, + 0x83, 0x00, 0xed, 0x09, 0x00, 0xce, 0x00, 0x2c, + 0x00, 0x00, 0x30, 0x02, 0x00, 0x04, 0x80, 0x00, + 0x24, 0x00, 0x0b, 0x00, 0x02, 0xcc, 0x00, 0x90, + 0x02, 0x2c, 0x40, 0x0a, 0x00, 0x02, 0xcc, 0x02, + 0x88, 0x00, 0x20, 0x00, 0x0b, 0x30, 0x02, 0xc0, + 0x00, 0xb1, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, + 0xca, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x0d, 0x7c, 0x00, 0xff, 0x00, 0x37, 0xc0, 0x0f, + 0xf0, 0x0b, 0x60, 0x08, 0xc9, 0x00, 0x32, 0xc0, + 0x1f, 0xf0, 0x03, 0xe8, 0x00, 0xff, 0x00, 0x3e, + 0x00, 0x0c, 0xf0, 0x01, 0x20, 0x00, 0xc8, 0x00, + 0x36, 0x00, 0x0f, 0x80, 0x03, 0xfc, 0x08, 0xfa, + 0x00, 0x36, 0x80, 0x9e, 0x80, 0x03, 0xfc, 0x04, + 0xc8, 0x00, 0x32, 0x80, 0x0d, 0xb0, 0x01, 0xe0, + 0x00, 0xf9, 0x00, 0x3e, 0xc0, 0x2c, 0xb0, 0x03, + 0x40, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, + 0x15, 0xfc, 0x00, 0xff, 0x00, 0x3b, 0xc0, 0x0f, + 0xf0, 0x03, 0x98, 0x00, 0xfe, 0x00, 0x3b, 0xc0, + 0x8f, 0xf0, 0x03, 0xf4, 0x00, 0xff, 0x00, 0x3f, + 0x00, 0x0f, 0xf0, 0x03, 0xf0, 0x04, 0xfc, 0x00, + 0xbb, 0x00, 0x0f, 0xc0, 0x03, 0xfc, 0x01, 0xfc, + 0x00, 0x3b, 0x00, 0x0f, 0xc0, 0x03, 0xfc, 0x01, + 0xdc, 0x00, 0x3d, 0x00, 0x0f, 0xf0, 0x26, 0xf0, + 0x00, 0x7c, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x07, + 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x05, 0xfc, 0x00, 0xfe, 0x00, 0x33, 0x44, 0x0d, + 0xf0, 0x03, 0x3c, 0x00, 0xc5, 0x00, 0x37, 0x02, + 0x0f, 0xc0, 0x03, 0xf4, 0x00, 0xce, 0x00, 0x37, + 0xc0, 0x0c, 0xf0, 0x03, 0xf8, 0x00, 0xc4, 0x08, + 0x3b, 0x0a, 0x0f, 0xc0, 0x23, 0xd8, 0x00, 0xfc, + 0x00, 0x3b, 0x05, 0x4c, 0xc1, 0x03, 0xb8, 0x08, + 0xce, 0x08, 0xb3, 0x40, 0x0f, 0xf0, 0x03, 0xf0, + 0x80, 0xfc, 0x30, 0x33, 0x00, 0xed, 0x09, 0x00, + 0xcf, 0x00, 0x0c, 0xc2, 0xa7, 0xb0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0xec, 0x00, + 0xba, 0x52, 0x22, 0x08, 0x08, 0xa0, 0x02, 0x2c, + 0x08, 0x89, 0x00, 0x2a, 0x10, 0x0b, 0xb0, 0x26, + 0xec, 0x10, 0x88, 0x00, 0x22, 0x80, 0x08, 0xb0, + 0x00, 0x6c, 0x00, 0x88, 0x40, 0x22, 0x12, 0x0b, + 0x80, 0x02, 0xe8, 0xa0, 0xb9, 0x04, 0x36, 0x5d, + 0x08, 0x87, 0x02, 0xa8, 0x00, 0x8a, 0x44, 0x22, + 0x00, 0x0b, 0x92, 0x82, 0xe1, 0xa0, 0xb2, 0x40, + 0x20, 0x8c, 0x08, 0xa6, 0x16, 0x20, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, 0x00, + 0xb0, 0x04, 0x20, 0x80, 0x09, 0x30, 0x02, 0x0c, + 0x00, 0x81, 0x01, 0x88, 0x80, 0x0b, 0x00, 0x02, + 0xc4, 0x00, 0xba, 0x00, 0x26, 0x80, 0x19, 0x30, + 0x40, 0xc0, 0x10, 0x80, 0x00, 0x28, 0x09, 0x4b, + 0x00, 0x22, 0xc8, 0x00, 0xb0, 0x81, 0x20, 0x00, + 0x28, 0x12, 0x06, 0x28, 0x02, 0x92, 0x00, 0x20, + 0x40, 0x0a, 0x30, 0x02, 0xc8, 0x40, 0xb0, 0x30, + 0x20, 0x02, 0x8a, 0x00, 0xc2, 0x22, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, 0x00, + 0xb8, 0x80, 0x22, 0xd0, 0x08, 0xa2, 0x02, 0x2c, + 0x00, 0x89, 0x00, 0x2a, 0xa0, 0x0b, 0xb5, 0x02, + 0xec, 0x02, 0x3a, 0x40, 0x22, 0x00, 0x19, 0xb0, + 0x02, 0xe0, 0x80, 0x8a, 0xc0, 0x2a, 0x44, 0x8b, + 0x80, 0x02, 0xe8, 0x20, 0xb9, 0x00, 0x2e, 0x61, + 0x08, 0x98, 0x02, 0xa8, 0x00, 0x9a, 0x20, 0x22, + 0x30, 0x0b, 0x90, 0x06, 0xe8, 0x01, 0xbb, 0x00, + 0x22, 0x82, 0x08, 0x20, 0x92, 0x30, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xec, 0x00, + 0xfa, 0xc0, 0x30, 0xe0, 0x0d, 0x1e, 0x03, 0x0c, + 0x02, 0xc1, 0x40, 0xba, 0x30, 0x0b, 0xa4, 0x02, + 0xc4, 0x10, 0xf3, 0x42, 0x36, 0xd0, 0x0d, 0xb0, + 0xed, 0x09, 0x00, 0xd0, 0x00, 0x13, 0xcf, 0x20, + 0xc8, 0x80, 0x3a, 0x12, 0x0f, 0x85, 0x93, 0xe9, + 0x08, 0xf2, 0x80, 0x32, 0x23, 0x0c, 0x98, 0x03, + 0xa8, 0x00, 0xda, 0x80, 0x22, 0xe0, 0x0e, 0x90, + 0x03, 0xe7, 0x90, 0xf9, 0x00, 0x32, 0x70, 0x0e, + 0x9c, 0x02, 0x00, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x01, 0xbc, 0x00, 0xf2, 0x00, 0xbf, + 0xa8, 0x0f, 0xf8, 0x0b, 0xfc, 0x00, 0xfd, 0x10, + 0x3f, 0x00, 0x0f, 0xe8, 0x23, 0xee, 0x40, 0x4f, + 0xa0, 0x3f, 0xc0, 0x0e, 0xf0, 0x03, 0x7e, 0x00, + 0xf4, 0x00, 0x37, 0x41, 0x0f, 0xd8, 0x13, 0xf8, + 0x00, 0xfe, 0x18, 0x34, 0x42, 0x0f, 0xc0, 0xd3, + 0xf2, 0x40, 0xed, 0x80, 0x3f, 0x80, 0x0f, 0xf0, + 0x03, 0xfc, 0x50, 0xfd, 0x90, 0xbf, 0xe5, 0x4f, + 0xb9, 0x03, 0x78, 0x40, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x10, 0xac, 0x00, 0xfa, 0x40, 0x32, + 0x00, 0x0c, 0x97, 0x03, 0x2c, 0x04, 0xe9, 0x80, + 0xb6, 0xb0, 0x0f, 0xb4, 0x03, 0xe4, 0x20, 0xcb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x43, 0x64, 0x00, + 0xc8, 0x40, 0xb2, 0x08, 0x0f, 0x82, 0x03, 0x21, + 0x00, 0xc8, 0x00, 0x3e, 0x00, 0x4c, 0x90, 0x63, + 0xec, 0x00, 0xca, 0x00, 0x3e, 0x40, 0x0d, 0x90, + 0x03, 0xe5, 0x00, 0xf8, 0x00, 0x30, 0x52, 0x0e, + 0x96, 0x03, 0x10, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x01, 0x2c, 0x00, 0xba, 0x00, 0x22, + 0x60, 0x0e, 0xb8, 0x0a, 0x2c, 0x12, 0xa9, 0x80, + 0x22, 0x80, 0x0b, 0xb7, 0x06, 0xee, 0x00, 0xdb, + 0xd0, 0x2c, 0x54, 0x0b, 0xb0, 0x02, 0xe7, 0x00, + 0x8e, 0x19, 0x36, 0x62, 0x0b, 0x90, 0x02, 0x20, + 0x64, 0x8b, 0xc4, 0x2e, 0x70, 0x08, 0x8c, 0x02, + 0xce, 0x00, 0xa2, 0x00, 0x2e, 0x80, 0x0b, 0xbe, + 0x02, 0xef, 0x89, 0xb9, 0x01, 0x36, 0xc0, 0x08, + 0xb4, 0x02, 0x32, 0xed, 0x09, 0x00, 0xd1, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, + 0x4c, 0x00, 0xb2, 0x04, 0x20, 0xe0, 0x08, 0x2c, + 0x02, 0x0e, 0xc0, 0xa3, 0x00, 0x60, 0x00, 0x0b, + 0x08, 0x12, 0xc6, 0x00, 0xb2, 0x50, 0x2c, 0x90, + 0x0b, 0x30, 0x12, 0xce, 0x80, 0xa0, 0xc0, 0x04, + 0x30, 0x09, 0x24, 0x02, 0x48, 0x00, 0xb0, 0xc2, + 0x2c, 0x40, 0x08, 0x80, 0x02, 0xca, 0x80, 0x82, + 0x24, 0x2c, 0x00, 0x09, 0x3e, 0x02, 0xc3, 0x20, + 0xa8, 0x00, 0x20, 0x04, 0x02, 0x01, 0x00, 0x38, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, + 0x1c, 0x40, 0xb7, 0x80, 0x21, 0x60, 0x0a, 0xf9, + 0x02, 0x1e, 0x00, 0xa7, 0x80, 0x21, 0xa4, 0x0b, + 0x78, 0x12, 0xd6, 0x30, 0xb6, 0x82, 0x2d, 0xa0, + 0x0b, 0x78, 0x02, 0xfe, 0x20, 0x8e, 0x00, 0x25, + 0x24, 0x4b, 0x68, 0x02, 0x7e, 0x00, 0xb5, 0x80, + 0x2d, 0xe2, 0x08, 0x68, 0x82, 0xda, 0x12, 0xa6, + 0x80, 0x2d, 0x20, 0x0b, 0x58, 0x02, 0xd2, 0x14, + 0xb6, 0x80, 0x25, 0x20, 0x48, 0x58, 0x02, 0x18, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, + 0x0c, 0x00, 0xf2, 0x00, 0x32, 0xc3, 0x08, 0x20, + 0x03, 0x0c, 0x40, 0xe1, 0x50, 0x30, 0x80, 0x0f, + 0x20, 0x02, 0xcc, 0x44, 0xf2, 0x01, 0x3c, 0x80, + 0x0f, 0x30, 0x03, 0xc4, 0x00, 0xc1, 0x10, 0x34, + 0xc0, 0x0d, 0x21, 0x43, 0x4c, 0x00, 0xf0, 0x18, + 0x3c, 0x80, 0x8c, 0x10, 0x02, 0xc8, 0x60, 0xc2, + 0x00, 0x3c, 0x00, 0x0d, 0x30, 0x03, 0xcc, 0x01, + 0xe0, 0x00, 0x30, 0xc4, 0x4e, 0x20, 0x03, 0x12, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, + 0xbc, 0x80, 0xfd, 0x00, 0x3f, 0x40, 0x0a, 0x70, + 0x13, 0xdc, 0x00, 0xfd, 0x00, 0x3b, 0x80, 0x0f, + 0xf0, 0x03, 0xfc, 0x40, 0xde, 0x00, 0x3f, 0x00, + 0x0f, 0xf0, 0x03, 0xd4, 0x00, 0xff, 0xed, 0x09, + 0x00, 0xd2, 0x00, 0x20, 0x3f, 0xc0, 0x47, 0x60, + 0x0b, 0xbc, 0x40, 0x8d, 0x00, 0x3f, 0x80, 0xaf, + 0xf0, 0x03, 0xd8, 0x00, 0xfe, 0x10, 0x3f, 0x00, + 0x0f, 0xd0, 0x11, 0xfc, 0x00, 0xff, 0x10, 0x3f, + 0xc4, 0x0f, 0xf1, 0x03, 0xd0, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x05, 0xec, 0x00, 0xfa, + 0x80, 0x32, 0xc0, 0x0c, 0x30, 0x0b, 0x2c, 0x00, + 0xfb, 0x00, 0x3c, 0xa0, 0x0f, 0xa0, 0x03, 0xe4, + 0x00, 0xf2, 0x00, 0x32, 0xc0, 0x4e, 0xb0, 0x01, + 0xe6, 0x00, 0xc9, 0x00, 0x2e, 0xc0, 0x0c, 0x90, + 0x03, 0xec, 0x04, 0xfa, 0x00, 0x3e, 0x40, 0x0f, + 0xb0, 0x03, 0xe8, 0x00, 0xfa, 0x02, 0x3e, 0x80, + 0x0e, 0x90, 0x03, 0x68, 0x00, 0xfb, 0x02, 0x32, + 0x00, 0x0f, 0x80, 0x03, 0x6a, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, 0x09, 0xb7, + 0x00, 0x35, 0x40, 0x08, 0x70, 0x02, 0x1c, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x08, 0x70, 0x02, 0xd4, + 0x00, 0x37, 0x00, 0x29, 0xc0, 0x08, 0x70, 0x42, + 0xd4, 0x00, 0x87, 0xa0, 0x2c, 0xc0, 0x08, 0x70, + 0x02, 0xdc, 0x18, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xd8, 0x00, 0xb7, 0x00, 0x2d, 0x80, + 0x0b, 0x70, 0x12, 0xd8, 0x00, 0xb7, 0x00, 0x35, + 0x00, 0x0b, 0x10, 0x02, 0x12, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, 0xb2, + 0x80, 0x23, 0xe0, 0x0a, 0xf8, 0x82, 0x1e, 0x08, + 0xb4, 0x80, 0x2d, 0xe0, 0x0b, 0x68, 0x02, 0xde, + 0x00, 0xbf, 0x80, 0x21, 0xe0, 0x0a, 0x78, 0x42, + 0xde, 0x02, 0x85, 0x90, 0x2d, 0xe1, 0x0a, 0x78, + 0x22, 0xd6, 0x10, 0xb6, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x12, 0xde, 0x00, 0xb6, 0x80, 0x2d, 0xa0, + 0x0a, 0x58, 0x02, 0x1f, 0x04, 0xb6, 0x80, 0x25, + 0xe0, 0x0b, 0x68, 0x02, 0xf0, 0x40, 0x20, 0x00, + 0x00, 0xed, 0x09, 0x00, 0xd3, 0x00, 0x00, 0x00, + 0x48, 0x14, 0xcc, 0x00, 0xb3, 0x80, 0x64, 0x44, + 0x2a, 0x38, 0x0a, 0x0c, 0x00, 0xb1, 0x01, 0x2c, + 0xf0, 0x09, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x01, + 0x28, 0x40, 0x4a, 0x30, 0x02, 0xce, 0x00, 0x83, + 0x00, 0x2c, 0xc0, 0x28, 0x34, 0x82, 0xc4, 0x00, + 0xb3, 0xf0, 0x2e, 0xc0, 0x9b, 0x33, 0x02, 0xce, + 0x00, 0xb2, 0x80, 0x2c, 0x84, 0x8b, 0x31, 0x02, + 0xed, 0x00, 0xb3, 0x04, 0x24, 0xc0, 0x0b, 0x30, + 0x82, 0x92, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xe8, 0x15, 0xa8, 0x00, 0xfe, 0x00, 0x31, 0xa0, + 0x0e, 0xe4, 0x43, 0x28, 0x00, 0xfe, 0x40, 0x3f, + 0x98, 0x0f, 0xec, 0x01, 0xe8, 0x00, 0xfe, 0xe0, + 0x31, 0x90, 0x06, 0xa0, 0x03, 0xfb, 0x20, 0xce, + 0x50, 0x3f, 0x94, 0x0e, 0x60, 0x23, 0xfb, 0x84, + 0xbe, 0xc0, 0x3f, 0x81, 0x0f, 0xe8, 0x03, 0xf9, + 0x30, 0xfe, 0x40, 0x3f, 0xa0, 0x06, 0xa0, 0x03, + 0x3b, 0x40, 0xfe, 0x00, 0xf3, 0x80, 0x07, 0xe4, + 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x10, 0x3e, 0x00, + 0x05, 0x8c, 0x03, 0xe0, 0x00, 0xf8, 0xc0, 0x3e, + 0x18, 0x4e, 0x8d, 0x01, 0xe0, 0x00, 0xf8, 0x80, + 0x3e, 0x30, 0x05, 0x80, 0x03, 0xe2, 0x00, 0xf8, + 0x40, 0x3c, 0x00, 0x0f, 0x80, 0x03, 0xe2, 0x00, + 0xf8, 0x00, 0x3e, 0x20, 0x0f, 0x80, 0x03, 0xe2, + 0x00, 0xf8, 0xd0, 0x3e, 0x00, 0x0f, 0x80, 0x23, + 0xe1, 0x10, 0xf0, 0x18, 0x7a, 0x02, 0x07, 0x00, + 0x01, 0x52, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x60, + 0x0c, 0x90, 0x03, 0x26, 0x80, 0xf9, 0xc0, 0x32, + 0x40, 0x0f, 0x90, 0x03, 0x25, 0x00, 0xf9, 0x40, + 0x22, 0x64, 0x0e, 0x90, 0x03, 0xe6, 0x00, 0xf9, + 0x00, 0x1e, 0x40, 0x0c, 0xed, 0x09, 0x00, 0xd4, + 0x00, 0x92, 0x03, 0x24, 0x10, 0xf9, 0x80, 0x32, + 0x40, 0x0c, 0x98, 0x03, 0xe6, 0x40, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xa5, 0x00, 0xc9, + 0x84, 0x72, 0x68, 0x47, 0x90, 0x03, 0x02, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, + 0x00, 0xb9, 0x00, 0x2e, 0x64, 0x28, 0x10, 0x0a, + 0x25, 0x08, 0x31, 0x01, 0x22, 0x58, 0x0b, 0x10, + 0x02, 0xa4, 0x04, 0xb1, 0x80, 0x36, 0x62, 0x08, + 0x90, 0x02, 0xe7, 0x00, 0xb9, 0x40, 0x2e, 0x74, + 0x0a, 0x90, 0x02, 0x25, 0x00, 0xb1, 0x80, 0x2a, + 0x41, 0x08, 0x98, 0x02, 0xe5, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x99, 0x22, 0xa7, 0x02, 0x09, + 0xb0, 0x7a, 0x40, 0x8b, 0x94, 0x02, 0x20, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, + 0x00, 0xbb, 0x00, 0x2e, 0x40, 0x09, 0x90, 0x02, + 0x24, 0x04, 0xb9, 0x00, 0x22, 0xe0, 0x0b, 0x98, + 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2a, 0xc0, 0x0a, + 0x90, 0x02, 0xe4, 0x80, 0xb9, 0x00, 0x0e, 0x42, + 0x09, 0x90, 0x8a, 0x24, 0x00, 0xb9, 0x10, 0x22, + 0x42, 0x28, 0xb2, 0x02, 0xe4, 0x00, 0xb9, 0x20, + 0x2e, 0x40, 0x1b, 0x10, 0x02, 0xa4, 0x04, 0x99, + 0x04, 0x22, 0x40, 0x0b, 0x94, 0x02, 0x06, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, + 0x00, 0xb1, 0x00, 0x2e, 0x50, 0x09, 0xb0, 0x0a, + 0x04, 0x04, 0xb1, 0x00, 0xa0, 0x40, 0x0b, 0xb0, + 0x02, 0x84, 0x00, 0xb1, 0x05, 0x2c, 0x40, 0x08, + 0x10, 0x02, 0xcc, 0x00, 0xb1, 0x00, 0x2c, 0x51, + 0x0b, 0x10, 0x02, 0x0d, 0x00, 0xb9, 0x02, 0x28, + 0x50, 0x08, 0x14, 0x02, 0xc4, 0x00, 0xb3, 0x28, + 0x2c, 0x4a, 0x09, 0x14, 0x0a, 0x8d, 0x00, 0x91, + 0x44, 0x28, 0x50, 0x0b, 0x14, 0x0a, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0xed, + 0x09, 0x00, 0xd5, 0x00, 0x60, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0d, 0x80, 0x0a, 0x28, 0x00, 0xfa, + 0x00, 0xb2, 0x00, 0x0f, 0x80, 0x03, 0x20, 0x00, + 0xfa, 0x02, 0x3a, 0x00, 0x0e, 0x80, 0x03, 0xe0, + 0x00, 0xfa, 0x00, 0x3e, 0x00, 0x0d, 0x80, 0x03, + 0x20, 0x00, 0xfa, 0x04, 0x32, 0x00, 0x0c, 0xa0, + 0x02, 0xe8, 0x00, 0xf8, 0x20, 0x3e, 0x1c, 0x0f, + 0x80, 0x07, 0xa0, 0x00, 0xd0, 0x00, 0x32, 0x00, + 0x0f, 0x80, 0x03, 0x2e, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x98, 0x1d, 0xe4, 0x00, 0xfd, 0x40, + 0x3d, 0x40, 0x0e, 0xd0, 0x03, 0xe4, 0x00, 0xfd, + 0x00, 0x3f, 0x50, 0x0b, 0xd0, 0x13, 0xf5, 0x00, + 0xfd, 0x00, 0x35, 0x40, 0x0f, 0x90, 0x03, 0xd4, + 0x00, 0xfd, 0x40, 0x3f, 0x50, 0x0e, 0xd0, 0x13, + 0xf4, 0x01, 0xfd, 0x00, 0x3f, 0x50, 0x0f, 0xd4, + 0x03, 0xf4, 0xa8, 0xfd, 0x00, 0x3f, 0x41, 0x0f, + 0xd0, 0x43, 0x75, 0x00, 0xef, 0x42, 0x3f, 0x50, + 0x0f, 0xd4, 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x11, 0xe4, 0x00, 0xf9, 0x00, + 0x3f, 0x50, 0x0f, 0xd0, 0x03, 0xb4, 0x00, 0xf5, + 0x00, 0xb7, 0x40, 0x07, 0x50, 0x03, 0x34, 0xa0, + 0xfd, 0x00, 0x3f, 0x40, 0x0d, 0x90, 0x03, 0xf4, + 0x00, 0xf5, 0x08, 0x3f, 0xc2, 0x0c, 0x70, 0x03, + 0x34, 0x01, 0xbd, 0x00, 0x3b, 0x52, 0x0c, 0xd0, + 0x83, 0x14, 0x00, 0xfd, 0x04, 0x32, 0x44, 0x0d, + 0x50, 0x02, 0x74, 0x00, 0xfd, 0x08, 0x2f, 0x4a, + 0x0f, 0xd0, 0x03, 0x26, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0xe0, 0x00, 0xb8, 0x40, + 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, + 0x00, 0x3e, 0x90, 0x5b, 0x80, 0x02, 0x21, 0x00, + 0xb8, 0x04, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, + 0x00, 0xb8, 0x00, 0x2e, 0x9a, 0x08, 0x80, 0x0a, + 0x20, 0x05, 0xed, 0x09, 0x00, 0xd6, 0x00, 0xb8, + 0x00, 0x22, 0x08, 0x08, 0x84, 0x02, 0x20, 0x20, + 0xba, 0x00, 0xa2, 0x04, 0x0b, 0x82, 0x00, 0x00, + 0x80, 0xb8, 0x00, 0x2e, 0x18, 0x0b, 0x82, 0x0a, + 0x0e, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x05, 0xc4, 0x00, 0xb1, 0x40, 0x2c, 0x48, 0x0b, + 0x10, 0x02, 0xc4, 0x00, 0xb9, 0x04, 0x24, 0x50, + 0x0b, 0x90, 0x1a, 0x04, 0x01, 0xb1, 0x00, 0x2c, + 0x40, 0x4b, 0x10, 0x42, 0xc4, 0x00, 0xb1, 0x00, + 0x6c, 0x40, 0x28, 0x90, 0x02, 0x04, 0xa0, 0xb9, + 0x00, 0x68, 0x40, 0x28, 0x12, 0x8a, 0x44, 0x80, + 0x91, 0x10, 0x20, 0x40, 0x0b, 0x10, 0x82, 0x47, + 0x20, 0xb1, 0x09, 0x2c, 0x42, 0x0b, 0x14, 0x82, + 0x02, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x05, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x4a, 0x0b, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x40, 0x2e, 0x40, + 0x0b, 0x94, 0x02, 0x26, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x8b, 0x90, 0x02, 0xe4, 0x40, 0xb9, 0x88, + 0x2e, 0x40, 0x48, 0x90, 0x02, 0x24, 0x00, 0xb9, + 0x41, 0x2a, 0x40, 0x1a, 0x90, 0x02, 0x24, 0x00, + 0xbb, 0x00, 0x22, 0x40, 0x0b, 0xb0, 0x00, 0x24, + 0x40, 0xb9, 0x00, 0x0e, 0x46, 0x0b, 0x92, 0x02, + 0x06, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x05, 0xe4, 0x00, 0xf9, 0x80, 0x3e, 0x60, 0x4f, + 0x90, 0x13, 0xe4, 0x04, 0xf1, 0x40, 0xb6, 0x40, + 0x0b, 0x1c, 0x03, 0x26, 0x00, 0xf9, 0x08, 0x3e, + 0x72, 0x8f, 0x90, 0x03, 0xe7, 0x20, 0xb9, 0xc0, + 0x3e, 0x64, 0x0c, 0x99, 0x03, 0x27, 0x20, 0xb9, + 0x80, 0x3a, 0x46, 0x0c, 0x92, 0x03, 0x66, 0x94, + 0xd9, 0x40, 0x32, 0x60, 0x0b, 0x90, 0x03, 0x64, + 0x00, 0xf9, 0x40, 0x3e, 0x60, 0x0f, 0x90, 0x03, + 0x28, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x01, 0xa4, 0x00, 0xf9, 0x20, 0xed, 0x09, 0x00, + 0xd7, 0x00, 0x3e, 0x60, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x90, 0xbe, 0x50, 0x0f, 0x9a, 0x13, + 0xe4, 0x10, 0xf9, 0x20, 0x3e, 0x70, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x98, 0x23, 0xe7, 0x00, 0xf9, 0xa0, 0x36, 0x60, + 0x0d, 0x90, 0x43, 0xe6, 0x40, 0xf1, 0x90, 0x3e, + 0x64, 0x0f, 0x90, 0x0b, 0xe6, 0x00, 0xf9, 0x00, + 0x7e, 0x60, 0x0f, 0x10, 0x03, 0xca, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xa0, 0x00, + 0xf8, 0x00, 0x32, 0x08, 0x2c, 0x88, 0x03, 0x22, + 0x40, 0xf8, 0x80, 0x32, 0x30, 0x0f, 0x89, 0x37, + 0x22, 0x08, 0xf8, 0x80, 0x3e, 0x01, 0x02, 0x80, + 0x43, 0xe3, 0x00, 0xf8, 0x20, 0x32, 0x10, 0x8e, + 0x82, 0x01, 0x21, 0x08, 0xd8, 0x54, 0x22, 0x15, + 0x0f, 0x80, 0x23, 0xa0, 0x00, 0xd8, 0x80, 0x32, + 0x00, 0x0e, 0x80, 0x03, 0xe0, 0x20, 0xc8, 0x00, + 0x32, 0x18, 0x2c, 0x80, 0x03, 0xca, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x28, 0x00, + 0xba, 0x00, 0x23, 0xb2, 0x08, 0xe4, 0x8a, 0x39, + 0x04, 0xbe, 0xc8, 0x37, 0x90, 0x0b, 0xe4, 0x06, + 0x39, 0x00, 0xbe, 0x40, 0x2f, 0xa4, 0x08, 0xa0, + 0x02, 0xf9, 0x00, 0xbe, 0xc0, 0x37, 0x84, 0x0b, + 0x60, 0x42, 0x3b, 0x00, 0xa6, 0x40, 0x03, 0x80, + 0x03, 0xe4, 0x02, 0xfa, 0x00, 0x8e, 0x60, 0x22, + 0x80, 0x0b, 0xe0, 0x02, 0x38, 0x00, 0x8e, 0x81, + 0x23, 0xb2, 0x08, 0xe8, 0x02, 0xca, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, 0x00, + 0xb3, 0x00, 0xa0, 0xd1, 0x18, 0x30, 0x02, 0x0c, + 0x00, 0xb3, 0x80, 0x20, 0xc0, 0x0b, 0x10, 0x02, + 0x0c, 0x04, 0xb3, 0x90, 0x2c, 0xa4, 0x8a, 0x30, + 0x02, 0xcc, 0x40, 0xb0, 0x80, 0x2e, 0xc0, 0x8a, + 0x34, 0x02, 0x0f, 0x28, 0x83, 0x60, 0x26, 0xc8, + 0xed, 0x09, 0x00, 0xd8, 0x00, 0x0b, 0xb2, 0x22, + 0x8f, 0xc0, 0xa3, 0x00, 0x28, 0xc0, 0x0b, 0xba, + 0x02, 0x4f, 0x00, 0x83, 0xb0, 0x68, 0xf0, 0x08, + 0x38, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x01, 0x1c, 0x00, 0xbf, 0x80, 0xa1, + 0x60, 0x08, 0xf8, 0x02, 0x1c, 0x00, 0xb7, 0x00, + 0x25, 0xc0, 0x09, 0xf0, 0x0a, 0x1c, 0x04, 0xb6, + 0x00, 0x2d, 0xa0, 0x08, 0x70, 0x02, 0xd4, 0x00, + 0xb4, 0xc0, 0x2d, 0xc0, 0x0b, 0xf4, 0x0a, 0x1e, + 0x20, 0x27, 0x02, 0x25, 0xc0, 0x0b, 0x70, 0x02, + 0xde, 0x08, 0xaf, 0x01, 0x29, 0xc0, 0x0b, 0xf0, + 0x92, 0x1f, 0x04, 0x07, 0x81, 0x21, 0xe0, 0x08, + 0x70, 0x82, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x33, + 0x60, 0x0c, 0x78, 0x03, 0x12, 0x00, 0xf7, 0x80, + 0x31, 0x60, 0x0f, 0x58, 0x02, 0x16, 0x10, 0xf4, + 0x80, 0x3d, 0xe0, 0x0e, 0x78, 0x13, 0xde, 0x00, + 0xf4, 0x80, 0x3d, 0xa0, 0x0e, 0x68, 0x63, 0x3e, + 0x08, 0xc7, 0x80, 0x35, 0xe0, 0x0f, 0x68, 0x03, + 0x9e, 0x00, 0xf7, 0x80, 0x39, 0xe0, 0x0f, 0x78, + 0x03, 0x5e, 0x02, 0xcf, 0x80, 0x38, 0x60, 0x0c, + 0x68, 0x23, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x1d, 0xac, 0x00, 0xf3, 0x00, 0xbe, + 0x40, 0x07, 0x30, 0x03, 0xec, 0x00, 0xf9, 0x00, + 0x3e, 0xc0, 0x0f, 0x90, 0x03, 0xec, 0x10, 0xfb, + 0x00, 0x3c, 0xc1, 0x8f, 0xb0, 0x03, 0xec, 0x00, + 0xf8, 0x00, 0x36, 0x00, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xe3, 0x04, 0xba, 0xc0, 0x0d, 0x90, 0x03, + 0xec, 0x00, 0xd3, 0x01, 0xb6, 0xc4, 0x4f, 0x90, + 0x43, 0x60, 0x00, 0xfb, 0x02, 0xbe, 0xc0, 0x0f, + 0xa0, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, 0x80, 0x33, + 0xe0, 0x0c, 0x48, 0xed, 0x09, 0x00, 0xd9, 0x00, + 0x03, 0x3e, 0x40, 0xce, 0x80, 0x33, 0xa4, 0x0e, + 0x48, 0x13, 0xba, 0x40, 0x3e, 0x90, 0x3f, 0x20, + 0x87, 0xf9, 0x03, 0xfe, 0x40, 0xfc, 0x80, 0x3f, + 0xe0, 0x4d, 0xd8, 0x43, 0xfe, 0x00, 0xcf, 0x80, + 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0x7c, 0x00, 0xdc, + 0x80, 0x1f, 0xe4, 0x0d, 0xc9, 0x03, 0xf2, 0x02, + 0xcc, 0x80, 0x33, 0xec, 0x0c, 0xd9, 0x03, 0x10, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, + 0x9c, 0x00, 0xb7, 0x08, 0x35, 0x40, 0x88, 0x64, + 0x03, 0x5c, 0x00, 0x84, 0x10, 0x21, 0x84, 0x08, + 0x42, 0x02, 0x98, 0x44, 0xb7, 0x14, 0x3d, 0x00, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb4, 0x00, 0x2f, + 0x90, 0x08, 0x50, 0x03, 0xf5, 0x00, 0x86, 0x00, + 0x0d, 0x40, 0x0b, 0x70, 0x03, 0x7c, 0xc0, 0xa5, + 0x00, 0x3f, 0xc0, 0x08, 0x73, 0x02, 0xd8, 0x00, + 0x84, 0x44, 0x2b, 0x04, 0x08, 0x74, 0x02, 0x2a, + 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x00, 0xb7, 0x00, 0xa3, 0xc0, 0x08, 0xc0, + 0x02, 0x18, 0x08, 0x97, 0x00, 0x21, 0x50, 0x4b, + 0x40, 0x26, 0x90, 0x41, 0xb6, 0x06, 0x2d, 0xc0, + 0x0b, 0x70, 0x12, 0xdc, 0x00, 0x95, 0x00, 0x2d, + 0xc0, 0x08, 0x75, 0x02, 0xd8, 0x40, 0x87, 0x00, + 0x2d, 0x80, 0x0b, 0x60, 0x02, 0x1c, 0x50, 0x87, + 0x50, 0x2d, 0xc0, 0x08, 0x40, 0x06, 0xd4, 0x00, + 0x84, 0x08, 0x2d, 0x48, 0x48, 0x40, 0x42, 0x44, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, + 0xcc, 0x00, 0xb3, 0x60, 0x24, 0x66, 0x08, 0x28, + 0x82, 0x4c, 0x00, 0x93, 0x00, 0x20, 0xe0, 0x09, + 0x10, 0x82, 0x88, 0x00, 0xb3, 0x00, 0x28, 0x80, + 0x0b, 0x30, 0x12, 0xcc, 0x00, 0xb0, 0x80, 0x2c, + 0x00, 0x08, 0x30, 0x12, 0x81, 0x00, 0x81, 0x61, + 0x2c, 0x20, 0x0b, 0x10, 0x02, 0x4c, 0xed, 0x09, + 0x00, 0xda, 0x00, 0x00, 0xa3, 0x80, 0x2c, 0xf1, + 0x08, 0x18, 0x02, 0x42, 0x00, 0xa0, 0x48, 0x2c, + 0x20, 0x0a, 0xac, 0x02, 0x59, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x15, 0xac, 0x00, 0xfb, + 0x40, 0x30, 0xa0, 0x0c, 0xb4, 0x03, 0x2c, 0x02, + 0xd9, 0x00, 0x32, 0xd2, 0x0f, 0x2c, 0x03, 0xa4, + 0x00, 0xb3, 0xc0, 0x2e, 0x82, 0x0f, 0xb0, 0x01, + 0xed, 0x00, 0xf8, 0x0c, 0x7e, 0x50, 0x00, 0xb4, + 0xc6, 0xc0, 0x04, 0x88, 0xc2, 0x0e, 0x20, 0x0f, + 0x9d, 0xa3, 0x2e, 0x20, 0xcb, 0x24, 0x6f, 0xd2, + 0x1c, 0xb8, 0x83, 0xee, 0x00, 0xcb, 0x00, 0x3e, + 0xa0, 0x4c, 0xb0, 0x0b, 0x68, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0x00, 0x0f, 0x85, 0x03, 0xed, 0x08, + 0xe9, 0x02, 0x3e, 0xc0, 0x0e, 0xa8, 0x13, 0xe2, + 0x08, 0xfa, 0x34, 0x3e, 0xd0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xf8, 0x04, 0x7e, 0x40, 0x4e, 0xb0, + 0x07, 0xe4, 0x80, 0xf8, 0x50, 0x3e, 0x4c, 0x0f, + 0x94, 0x03, 0xe0, 0x00, 0xeb, 0x40, 0x7a, 0xc2, + 0x2e, 0xa4, 0x03, 0xcc, 0x40, 0x5b, 0x00, 0x3a, + 0xd4, 0x4d, 0x87, 0x03, 0xa1, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, 0xfb, + 0x00, 0x3f, 0xa0, 0x0c, 0xf0, 0x03, 0x74, 0x00, + 0xcc, 0x98, 0x32, 0x40, 0x0f, 0xc0, 0x03, 0x7e, + 0x80, 0xfd, 0x04, 0x37, 0x82, 0x0f, 0xf0, 0x03, + 0xfc, 0x60, 0xfc, 0x01, 0x3f, 0x42, 0x0c, 0xe0, + 0x13, 0x70, 0x08, 0xdc, 0xa0, 0x3f, 0x40, 0x0f, + 0x10, 0x03, 0x3e, 0x40, 0xff, 0x00, 0x31, 0xc0, + 0xfc, 0xf0, 0x03, 0xec, 0x00, 0xc0, 0x00, 0x31, + 0x00, 0x2e, 0xf0, 0x0a, 0x20, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, 0xbb, + 0x00, 0x2e, 0x38, 0x28, 0x14, 0x22, 0x0c, 0x00, + 0x82, 0xed, 0x09, 0x00, 0xdb, 0x00, 0x40, 0x22, + 0xc0, 0x0b, 0x98, 0x23, 0x21, 0x38, 0xba, 0x00, + 0x2a, 0x80, 0x4b, 0xb0, 0x03, 0xec, 0x20, 0xb8, + 0x10, 0x2c, 0x60, 0x28, 0x30, 0x12, 0x27, 0x00, + 0x88, 0xe0, 0x36, 0x70, 0x0b, 0x98, 0x82, 0x2f, + 0x24, 0xb3, 0x40, 0x2a, 0xc0, 0x08, 0x80, 0x03, + 0xe0, 0x00, 0x88, 0xc0, 0xa2, 0xd0, 0x08, 0x84, + 0x02, 0x20, 0x50, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc8, + 0x08, 0x92, 0x02, 0x6c, 0x21, 0x88, 0x08, 0x22, + 0x80, 0x4b, 0x86, 0x1a, 0x24, 0x04, 0xbb, 0x40, + 0x2a, 0xc6, 0x9b, 0xb0, 0x02, 0xec, 0x08, 0xba, + 0x00, 0x2e, 0x60, 0x48, 0x90, 0x02, 0xa6, 0x00, + 0x98, 0x00, 0x2e, 0x30, 0x1b, 0x88, 0x22, 0x2c, + 0x00, 0xb9, 0x00, 0x22, 0xc0, 0x18, 0x80, 0x42, + 0x60, 0x00, 0x9b, 0x10, 0x2a, 0x91, 0x88, 0x91, + 0x66, 0xa0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2e, 0x40, + 0x08, 0x00, 0x02, 0x0c, 0x03, 0x82, 0x00, 0xa0, + 0x80, 0x0b, 0x80, 0x02, 0x00, 0x01, 0xb2, 0x01, + 0xa8, 0xc0, 0x0b, 0x30, 0x02, 0x8c, 0x00, 0xb0, + 0x00, 0x0e, 0x00, 0x08, 0x10, 0x0a, 0xa4, 0x00, + 0x80, 0x00, 0x20, 0x40, 0x9b, 0x00, 0x02, 0x4c, + 0x08, 0xb1, 0x01, 0x28, 0xc0, 0x38, 0x20, 0x02, + 0xc8, 0x08, 0x83, 0x04, 0x20, 0x00, 0x08, 0x00, + 0x02, 0x82, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x2e, 0xc0, + 0x0c, 0x80, 0x03, 0x68, 0x04, 0xc8, 0x00, 0xa2, + 0x41, 0x0f, 0x80, 0x03, 0x2c, 0x00, 0xfb, 0x00, + 0xbe, 0x80, 0x0f, 0xb0, 0x02, 0xe8, 0x00, 0xfb, + 0x00, 0x3e, 0x40, 0x0c, 0xb0, 0x03, 0xe0, 0x01, + 0xd8, 0x04, 0x6e, 0x00, 0x0f, 0x80, 0x03, 0x2c, + 0x04, 0xfb, 0x05, 0x32, 0xed, 0x09, 0x00, 0xdc, + 0x00, 0xc0, 0x28, 0x80, 0x03, 0xe4, 0x00, 0xc8, + 0x00, 0x32, 0x00, 0x2c, 0x10, 0x0b, 0xa0, 0x01, + 0x10, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, + 0x00, 0xff, 0x00, 0x3d, 0x40, 0x0f, 0xc0, 0x03, + 0xdc, 0x00, 0xb4, 0x00, 0x3f, 0xc0, 0x0f, 0xd0, + 0x03, 0xb0, 0x08, 0xfe, 0x00, 0x3f, 0x80, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xfc, 0x00, 0x3f, 0x00, + 0x8f, 0xf0, 0x03, 0x70, 0x1c, 0xfc, 0x00, 0x37, + 0x00, 0x0f, 0xc0, 0x43, 0xbc, 0x00, 0xff, 0x02, + 0x3f, 0xc0, 0xab, 0xc0, 0x03, 0xb0, 0x00, 0xfc, + 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0x68, 0x05, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0xfc, + 0x80, 0xcf, 0x28, 0x3f, 0xc4, 0x0c, 0xf2, 0x03, + 0x30, 0x40, 0xdf, 0x00, 0x3d, 0x00, 0x0c, 0xf0, + 0x03, 0xf0, 0x48, 0xdf, 0x04, 0x37, 0x00, 0x8f, + 0xe0, 0x07, 0xb0, 0x00, 0xff, 0x18, 0x3f, 0xc1, + 0x0f, 0xc0, 0x03, 0xfc, 0x00, 0xfc, 0x40, 0x3f, + 0xc0, 0x1f, 0xf2, 0x13, 0x7c, 0xe4, 0xee, 0x00, + 0xb1, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0xa0, 0xcc, + 0x00, 0x3f, 0x00, 0x0f, 0xf0, 0x03, 0xf0, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xfd, + 0x02, 0x8f, 0x40, 0x2d, 0xdc, 0x08, 0xf5, 0x02, + 0x2c, 0x80, 0xbf, 0x50, 0x3a, 0xca, 0x08, 0xf1, + 0x02, 0xec, 0x84, 0xbf, 0x00, 0xa2, 0x10, 0x0b, + 0x82, 0xa2, 0xe0, 0x00, 0xbf, 0x40, 0x2e, 0xc0, + 0x0b, 0x80, 0x02, 0xec, 0x00, 0xb8, 0x20, 0x2a, + 0xc0, 0x0b, 0xf5, 0x02, 0x2d, 0x00, 0xb8, 0x40, + 0x23, 0xd0, 0x0b, 0xf4, 0x02, 0xe1, 0x00, 0xe9, + 0x00, 0x2e, 0x08, 0x0b, 0xb0, 0x03, 0xa0, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x45, 0xcd, + 0x08, 0xa3, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, + 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc8, 0x0a, 0xed, + 0x09, 0x00, 0xdd, 0x00, 0x30, 0x02, 0xcc, 0x80, + 0x93, 0x41, 0x28, 0x1a, 0x1b, 0x00, 0x10, 0xc0, + 0x00, 0xb3, 0x20, 0x2c, 0xc0, 0x0a, 0x00, 0x02, + 0xcc, 0x04, 0xb0, 0x42, 0x20, 0xc0, 0x0b, 0x30, + 0x02, 0x4c, 0x84, 0xa8, 0x14, 0x2c, 0xc4, 0x0b, + 0x34, 0x02, 0x40, 0x00, 0x80, 0x00, 0x2c, 0x02, + 0x0b, 0x30, 0x02, 0xe3, 0x01, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x15, 0xac, 0x00, 0x8b, 0x00, + 0x2e, 0xc0, 0x28, 0xb0, 0x38, 0xac, 0x00, 0xbb, + 0x04, 0x2c, 0x20, 0x08, 0xb0, 0x02, 0xe4, 0x20, + 0xbb, 0x04, 0x2a, 0x62, 0x0b, 0xb2, 0x82, 0xe2, + 0x00, 0xbb, 0x02, 0x2e, 0xd1, 0x0b, 0xb0, 0x02, + 0xe8, 0x21, 0xb8, 0x80, 0x6a, 0x82, 0x09, 0xb0, + 0x46, 0x6c, 0x00, 0xb9, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x06, 0xe2, 0x28, 0xb9, 0x10, 0x2e, 0x00, + 0x0b, 0xb0, 0x42, 0xb0, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x15, 0xec, 0x00, 0xcb, 0x01, + 0x3e, 0xc0, 0x0c, 0x30, 0x03, 0x2d, 0x60, 0xdb, + 0x00, 0x3e, 0xd0, 0x2c, 0xb0, 0x03, 0xed, 0x00, + 0xdb, 0x00, 0x3e, 0x30, 0x0f, 0x84, 0x03, 0xa5, + 0x20, 0xfb, 0x00, 0x3e, 0xe0, 0x0f, 0x81, 0x83, + 0xec, 0x00, 0xf8, 0xc0, 0x32, 0xe0, 0x0b, 0x30, + 0x03, 0x6c, 0x00, 0xea, 0x40, 0x3e, 0xc0, 0x0b, + 0xb0, 0x02, 0xe2, 0x08, 0xc8, 0x60, 0x3e, 0x00, + 0x07, 0xb0, 0x03, 0xd0, 0x05, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x01, 0x9c, 0x00, 0xff, 0x00, + 0x3f, 0xc1, 0x03, 0xf0, 0xa3, 0x7c, 0x04, 0xff, + 0x00, 0x1b, 0xc0, 0x07, 0xf0, 0x03, 0xf9, 0x08, + 0x77, 0x00, 0x36, 0x40, 0x0f, 0xd8, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xd0, 0x0f, 0xf0, 0x03, + 0xfc, 0x20, 0xfd, 0x00, 0x3b, 0xe4, 0x0f, 0xf0, + 0x03, 0xbc, 0x00, 0xfb, 0x00, 0x13, 0xc0, 0x07, + 0xf0, 0x03, 0xed, 0x09, 0x00, 0xde, 0x00, 0xd0, + 0x00, 0xef, 0x80, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xb8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x10, 0xac, 0x00, 0xfb, 0x00, 0xb2, 0xc0, 0x0c, + 0xb0, 0x43, 0x24, 0x00, 0xfb, 0x10, 0xb2, 0xc0, + 0x0c, 0xb0, 0x03, 0x6d, 0x00, 0xfb, 0x08, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xdb, 0x20, + 0x3e, 0x40, 0x05, 0x80, 0x83, 0xe4, 0x00, 0xf9, + 0x64, 0x3a, 0xc1, 0x07, 0xb1, 0x43, 0xec, 0x00, + 0xba, 0x20, 0x3a, 0xc8, 0x0c, 0xb2, 0x03, 0x21, + 0x00, 0xfa, 0xc8, 0xb2, 0xc0, 0x0f, 0xb0, 0x03, + 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0x05, 0x3c, 0x00, 0xbf, 0x82, 0x23, 0xc0, 0x08, + 0xfc, 0x80, 0x2c, 0x18, 0xbf, 0x00, 0x32, 0xc0, + 0x02, 0xf0, 0x02, 0xec, 0x08, 0xbf, 0x80, 0x1a, + 0x40, 0x08, 0x90, 0x02, 0xea, 0x14, 0xbf, 0x40, + 0x2e, 0x40, 0x0b, 0xb0, 0x02, 0xe8, 0x04, 0xb9, + 0x40, 0x3a, 0x80, 0x03, 0xfc, 0x02, 0xfc, 0x40, + 0xb3, 0x00, 0x0b, 0xe0, 0x08, 0xf4, 0x00, 0xe1, + 0x40, 0xbb, 0xc0, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x05, 0x4c, 0x00, 0x93, 0x00, 0x22, 0xc0, 0x18, + 0x3c, 0x00, 0xcc, 0x08, 0xb3, 0x80, 0x20, 0xc0, + 0x0b, 0x30, 0x02, 0x4c, 0x00, 0xb3, 0xc0, 0x0c, + 0x00, 0x09, 0x00, 0x00, 0xc8, 0x00, 0x33, 0x00, + 0x0c, 0xc1, 0x0b, 0x0d, 0x02, 0xcc, 0x00, 0xb8, + 0x00, 0x2c, 0xc4, 0x09, 0x3c, 0x82, 0xce, 0x49, + 0x92, 0x00, 0x28, 0xe4, 0x88, 0x39, 0x42, 0x00, + 0x00, 0xb1, 0x00, 0x24, 0x00, 0x0b, 0x30, 0x02, + 0x78, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x1e, 0x00, 0xb3, 0x88, 0x21, 0xe0, 0x08, + 0x78, 0x0a, 0xd6, 0x00, 0xb7, 0x80, 0x23, 0xe0, + 0x03, 0x78, 0x02, 0xde, 0x00, 0xed, 0x09, 0x00, + 0xdf, 0x00, 0xb7, 0x88, 0x2d, 0xa0, 0x09, 0x48, + 0x02, 0xd2, 0x20, 0xb7, 0x90, 0x6d, 0xf0, 0x03, + 0x49, 0x02, 0xde, 0x00, 0xb5, 0x80, 0x29, 0x60, + 0x0b, 0x78, 0x12, 0xde, 0x00, 0x94, 0x80, 0x29, + 0xe4, 0x08, 0x38, 0x22, 0x92, 0x20, 0xb7, 0x80, + 0x25, 0x20, 0x4b, 0x78, 0x02, 0xc8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x0c, 0x40, + 0xf3, 0x00, 0x30, 0xc0, 0x0c, 0x31, 0x02, 0xcc, + 0x00, 0xf3, 0x00, 0x30, 0xc0, 0x87, 0x31, 0x03, + 0x48, 0x00, 0xf3, 0x00, 0x1c, 0x44, 0x0f, 0x10, + 0x02, 0xcc, 0x00, 0xf3, 0x18, 0x3c, 0xcf, 0x0d, + 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x70, 0x38, 0xc8, + 0x8f, 0x30, 0x03, 0xcc, 0xc0, 0xf1, 0x48, 0x38, + 0xc0, 0x0c, 0x30, 0x37, 0x00, 0x50, 0xb3, 0x24, + 0x34, 0x00, 0x0f, 0x30, 0x03, 0xd2, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xbc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x6f, 0x71, 0x00, 0x3c, + 0x44, 0xf7, 0x00, 0x7f, 0xc4, 0x0e, 0xf0, 0x43, + 0xfc, 0x40, 0xff, 0x00, 0x3b, 0xc4, 0x0e, 0xd0, + 0x03, 0x74, 0x40, 0xff, 0x50, 0x3f, 0xc4, 0x1d, + 0xf0, 0x07, 0xfc, 0x00, 0xff, 0x10, 0x3f, 0x40, + 0x5f, 0xf1, 0x03, 0xfc, 0x48, 0xfd, 0x00, 0x3f, + 0xc3, 0x1f, 0xf0, 0x07, 0xf8, 0x00, 0xf7, 0x00, + 0x3b, 0x04, 0x0f, 0xf1, 0x03, 0xd0, 0x06, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, 0xed, 0x40, + 0xfb, 0x00, 0x3e, 0xca, 0x0f, 0xb4, 0x03, 0xec, + 0x00, 0xfb, 0x48, 0x3e, 0x00, 0x0f, 0xb2, 0x43, + 0x64, 0x00, 0xcb, 0x08, 0x3e, 0xc0, 0x0d, 0xb0, + 0x07, 0xec, 0x00, 0xfb, 0x60, 0x32, 0x81, 0x0f, + 0xb0, 0x43, 0x2c, 0x00, 0xda, 0x00, 0x3e, 0xc0, + 0x0c, 0xb0, 0x87, 0x2c, 0x00, 0xdb, 0x00, 0x3e, + 0xf0, 0x4c, 0xbf, 0x43, 0x20, 0x00, 0xf9, 0x00, + 0xed, 0x09, 0x00, 0xe0, 0x00, 0x02, 0x00, 0x0c, + 0xb0, 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x11, 0x9c, 0xa0, 0xb7, 0x70, 0x2d, + 0xd8, 0x0b, 0x72, 0x82, 0xdc, 0x04, 0xb7, 0x02, + 0x0d, 0xc0, 0x0b, 0x76, 0x82, 0xdc, 0x00, 0x87, + 0x24, 0x2d, 0xc0, 0x0b, 0x50, 0x26, 0xdc, 0x00, + 0xb3, 0x01, 0x21, 0x80, 0x0b, 0x70, 0x03, 0x5c, + 0x00, 0xd7, 0x00, 0x6f, 0xc0, 0x0d, 0x70, 0x03, + 0x5d, 0x80, 0x97, 0x00, 0x2c, 0xca, 0x08, 0x70, + 0x8a, 0x14, 0x00, 0xb7, 0x00, 0x23, 0xc0, 0x08, + 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x00, 0x9e, 0x80, 0xb7, 0x80, 0x2d, + 0xe8, 0x0b, 0x79, 0x46, 0xdf, 0x00, 0xb7, 0xb0, + 0x65, 0xe2, 0x0b, 0x78, 0x02, 0x5e, 0x00, 0xa7, + 0xb0, 0x2d, 0xe0, 0x09, 0x58, 0x12, 0x1e, 0x08, + 0xb7, 0xb0, 0x29, 0xe0, 0x01, 0x7c, 0x02, 0x16, + 0x20, 0xa7, 0x86, 0x29, 0xe2, 0x08, 0x39, 0x2a, + 0x9e, 0x88, 0xb7, 0x80, 0x29, 0xe0, 0x0b, 0x32, + 0x02, 0x56, 0x00, 0xb7, 0x80, 0x25, 0xe2, 0x08, + 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x46, 0xe4, 0x00, 0xb3, 0x00, + 0x6e, 0x20, 0x0b, 0x30, 0x02, 0xc0, 0x40, 0xa3, + 0x00, 0x2e, 0xe0, 0x0b, 0xb0, 0x82, 0xcc, 0x00, + 0xb3, 0x00, 0x6a, 0xe8, 0x4b, 0x3c, 0x00, 0x4c, + 0x01, 0x93, 0x00, 0x4c, 0xc0, 0x09, 0x30, 0x02, + 0xcc, 0x10, 0xb3, 0x60, 0x2c, 0xc0, 0x2b, 0x30, + 0x00, 0x4d, 0x01, 0xb3, 0x81, 0x22, 0xc2, 0x08, + 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, + 0x80, 0x0f, 0xa0, 0x03, 0xf9, 0x00, 0xfa, 0x02, + 0x37, 0xb0, 0x0f, 0xa0, 0x02, 0x78, 0x02, 0xca, + 0x00, 0x3f, 0xa0, 0xed, 0x09, 0x00, 0xe1, 0x00, + 0x0d, 0xe4, 0x23, 0xf8, 0x00, 0xfa, 0x00, 0xbb, + 0x81, 0x0f, 0x68, 0x03, 0x3a, 0x00, 0xee, 0x40, + 0x3b, 0xa0, 0x0c, 0xa0, 0x03, 0xa8, 0x00, 0xbe, + 0x20, 0x3a, 0x80, 0x0b, 0xa0, 0x02, 0x79, 0x00, + 0xbe, 0x80, 0xb3, 0x80, 0x3c, 0xa0, 0x03, 0xfa, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, + 0xc0, 0x00, 0xf8, 0x00, 0x3c, 0x00, 0x4f, 0x80, + 0x03, 0xe2, 0x00, 0xf8, 0x00, 0x76, 0x02, 0x0f, + 0x80, 0x03, 0xe0, 0x20, 0xd0, 0x40, 0x3e, 0x24, + 0x0f, 0x80, 0x13, 0x63, 0x40, 0xf8, 0x00, 0x26, + 0x04, 0x0f, 0x80, 0x83, 0xe0, 0x10, 0xf8, 0x18, + 0x36, 0x10, 0x0d, 0x04, 0x07, 0x21, 0x10, 0xd8, + 0x40, 0x3e, 0x00, 0x0c, 0x84, 0x03, 0xa0, 0x20, + 0xf8, 0x10, 0x3e, 0x01, 0x9f, 0x80, 0x03, 0xd2, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0xe4, 0x00, 0xc9, 0xc0, 0x3e, 0x40, 0x0e, 0x90, + 0x13, 0xe4, 0x08, 0xc9, 0xc0, 0x36, 0x40, 0x0d, + 0x10, 0x03, 0x64, 0x00, 0x29, 0x00, 0x3a, 0x40, + 0x8e, 0x90, 0x03, 0x66, 0x44, 0xf1, 0x00, 0x36, + 0x41, 0x0f, 0x90, 0x03, 0x85, 0x00, 0xc9, 0x82, + 0x3c, 0x40, 0xcc, 0x90, 0x03, 0x64, 0x00, 0xf9, + 0x90, 0x2e, 0x60, 0x0f, 0x99, 0x00, 0x64, 0x00, + 0xf9, 0x10, 0x36, 0x40, 0x0c, 0x90, 0x03, 0xc2, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, + 0x64, 0x02, 0x89, 0x00, 0x2e, 0x41, 0x08, 0x92, + 0x02, 0xe4, 0x02, 0x89, 0x00, 0x2e, 0x40, 0x08, + 0x90, 0x02, 0x04, 0x04, 0xa9, 0x10, 0x22, 0x40, + 0x28, 0x90, 0x02, 0x27, 0x00, 0xb9, 0x40, 0x22, + 0x60, 0x08, 0x90, 0x02, 0x26, 0x10, 0xa9, 0x90, + 0x2e, 0x52, 0x0a, 0x9c, 0x02, 0x24, 0x20, 0x39, + 0xa0, 0x2e, 0x54, 0x0b, 0x96, 0x02, 0x25, 0x28, + 0xb1, 0x48, 0x22, 0x40, 0x08, 0x90, 0xed, 0x09, + 0x00, 0xe2, 0x00, 0x02, 0xe0, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, 0x89, + 0x00, 0x2e, 0x40, 0x08, 0x91, 0x02, 0xe4, 0x00, + 0x89, 0x00, 0x2e, 0xc0, 0x08, 0x90, 0x0a, 0x24, + 0x00, 0x89, 0x40, 0x62, 0x40, 0x08, 0x90, 0x02, + 0x25, 0x00, 0xb9, 0x08, 0xaa, 0x49, 0x09, 0x90, + 0x02, 0xa4, 0x00, 0x89, 0x08, 0x2e, 0x40, 0x09, + 0x91, 0x8a, 0xa4, 0x80, 0xa9, 0x00, 0x0e, 0x42, + 0x0b, 0x10, 0x42, 0xa4, 0x40, 0xb9, 0x00, 0x22, + 0x40, 0x08, 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x81, + 0x00, 0x2c, 0x50, 0x48, 0x10, 0x02, 0xc5, 0x00, + 0x81, 0x00, 0x2c, 0x50, 0x29, 0x10, 0x02, 0x25, + 0x00, 0xa1, 0x00, 0xa0, 0x50, 0x08, 0x14, 0x08, + 0x04, 0x00, 0x91, 0x40, 0x0c, 0xd0, 0x08, 0x90, + 0x02, 0x05, 0x00, 0xa1, 0x28, 0x2c, 0x50, 0x0b, + 0x10, 0x02, 0x05, 0x00, 0x91, 0x02, 0x2c, 0x40, + 0x83, 0x14, 0x02, 0x84, 0x00, 0xb9, 0x00, 0x20, + 0x50, 0x20, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0x0c, 0x60, 0x00, 0xc8, + 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x00, + 0xc8, 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0x00, + 0x00, 0xc8, 0x01, 0x3a, 0x00, 0x0e, 0x80, 0x03, + 0x20, 0x00, 0xf8, 0x00, 0x1e, 0x00, 0x0f, 0x80, + 0x23, 0x80, 0x00, 0x48, 0x20, 0x3e, 0x00, 0x0d, + 0x80, 0x03, 0xe0, 0x00, 0x78, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x13, 0xa0, 0x01, 0xf8, 0x00, 0xb2, + 0x00, 0x04, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x1d, 0xe5, 0x00, 0xf9, + 0x40, 0x3e, 0x50, 0x6f, 0x94, 0x03, 0xf4, 0x00, + 0xf9, 0x41, 0x3f, 0x40, 0x0e, 0x94, 0x03, 0xfc, + 0x00, 0x79, 0x41, 0x3f, 0xd0, 0x0d, 0xf0, 0x03, + 0x34, 0xed, 0x09, 0x00, 0xe3, 0x00, 0x00, 0xf9, + 0x40, 0x13, 0x50, 0x0b, 0x50, 0x03, 0xf5, 0x08, + 0xfd, 0x2d, 0x0f, 0xd0, 0x0e, 0x94, 0x13, 0xe5, + 0x00, 0xff, 0x40, 0x3e, 0x50, 0x0f, 0x94, 0x03, + 0x35, 0x04, 0xf5, 0x00, 0x3b, 0x40, 0x8f, 0x90, + 0x03, 0xe6, 0x02, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0xe4, 0x90, 0xbd, 0x00, 0x3e, 0x40, + 0x4c, 0xd0, 0x03, 0xe4, 0x00, 0xfd, 0x28, 0x3e, + 0x44, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xcd, 0x00, + 0x32, 0x48, 0x0f, 0xb0, 0x03, 0x14, 0x00, 0xdd, + 0x10, 0x3b, 0x40, 0x0c, 0x50, 0x03, 0xb4, 0x80, + 0xfd, 0x01, 0x3b, 0x4c, 0x8d, 0xd0, 0x03, 0xf4, + 0x00, 0x95, 0x02, 0x3f, 0x49, 0x0f, 0xd2, 0x83, + 0x34, 0x00, 0xfd, 0x00, 0x1e, 0x40, 0x0f, 0x90, + 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x10, 0xe0, 0x40, 0x38, 0x40, 0x2e, 0x02, + 0x08, 0x81, 0x02, 0x40, 0xa0, 0xb8, 0x00, 0x0e, + 0x08, 0x09, 0x84, 0x07, 0x20, 0x30, 0x88, 0x10, + 0x36, 0x0e, 0x4b, 0x82, 0x0a, 0xa0, 0x00, 0xa8, + 0x40, 0x2e, 0x82, 0x0d, 0x80, 0x03, 0x68, 0xb0, + 0xba, 0x48, 0x2e, 0x0c, 0x1b, 0x84, 0x02, 0x60, + 0xa8, 0x88, 0x10, 0x2e, 0x00, 0x0b, 0x82, 0x13, + 0xa8, 0x00, 0xb8, 0x00, 0x2e, 0x82, 0x09, 0x80, + 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x05, 0xc4, 0x00, 0xb1, 0x10, 0x2c, 0x44, + 0x0a, 0x10, 0x02, 0xc4, 0x80, 0xb1, 0x02, 0x08, + 0x48, 0x0b, 0x11, 0x02, 0x04, 0x02, 0x81, 0x00, + 0x24, 0x48, 0x0b, 0x92, 0xa2, 0x64, 0x00, 0x81, + 0x10, 0x28, 0x44, 0x09, 0x10, 0x02, 0x44, 0xc0, + 0xb1, 0x32, 0x28, 0x48, 0x0b, 0x11, 0x06, 0xc4, + 0xc0, 0x91, 0x00, 0x28, 0x45, 0x0b, 0x12, 0x82, + 0xc4, 0x41, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, + 0x02, 0xc2, 0x01, 0x60, 0xed, 0x09, 0x00, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, + 0x00, 0xb9, 0x00, 0x0e, 0x40, 0x2a, 0x90, 0x02, + 0x64, 0x00, 0xb9, 0x01, 0x26, 0x54, 0x0b, 0x90, + 0x0a, 0xa4, 0x40, 0x89, 0x00, 0x26, 0x40, 0x03, + 0x92, 0x22, 0xe4, 0x00, 0xa9, 0x00, 0x26, 0x41, + 0x8b, 0x90, 0x02, 0x64, 0x05, 0xb9, 0x10, 0x2e, + 0x41, 0x0b, 0x90, 0x02, 0x6c, 0x00, 0x89, 0x00, + 0x4e, 0x40, 0x0b, 0x90, 0x12, 0xa6, 0x00, 0xb9, + 0x00, 0x2e, 0x44, 0x09, 0x90, 0x02, 0xc6, 0x05, + 0x20, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0e, 0x90, 0x03, + 0xe4, 0x20, 0xf9, 0x04, 0x3e, 0x40, 0x8f, 0x90, + 0x43, 0x25, 0x00, 0xc1, 0x00, 0x36, 0x40, 0x0f, + 0x14, 0x03, 0x65, 0x84, 0xd9, 0x00, 0x3a, 0x54, + 0x0c, 0x9d, 0x83, 0x66, 0x00, 0xf9, 0x44, 0x3a, + 0x50, 0x49, 0x90, 0x23, 0xe4, 0x10, 0xd9, 0x04, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0x66, 0x04, 0xf9, + 0x84, 0x3e, 0x50, 0x0f, 0x90, 0x23, 0xe8, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x24, + 0x00, 0xf9, 0x04, 0x3c, 0x40, 0x0d, 0x90, 0x83, + 0x66, 0x80, 0xf9, 0x00, 0x1e, 0x60, 0x0d, 0x90, + 0x03, 0x64, 0x00, 0xf9, 0x00, 0x1e, 0x40, 0x1f, + 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x2c, 0x40, + 0x0d, 0x90, 0x83, 0x65, 0x00, 0xf9, 0x80, 0x36, + 0x40, 0x0b, 0x90, 0x03, 0xc4, 0x08, 0xb9, 0x91, + 0x3e, 0x41, 0x0f, 0x90, 0x83, 0xe4, 0x00, 0xb9, + 0x40, 0x3e, 0x40, 0x0d, 0x90, 0x13, 0xca, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa0, + 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0f, 0x81, 0x03, + 0xe1, 0x00, 0xc8, 0x00, 0x32, 0x00, 0x8f, 0x00, + 0x03, 0xe1, 0x00, 0xf8, 0x20, 0x3e, 0x00, 0x0f, + 0x80, 0x01, 0xe1, 0x20, 0xd8, 0x34, 0x3e, 0xed, + 0x09, 0x00, 0xe5, 0x00, 0x1c, 0x07, 0x81, 0x43, + 0xa1, 0x00, 0xc8, 0x20, 0x36, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x00, 0xc8, 0x60, 0x3e, 0x00, 0x4f, + 0x80, 0x0b, 0x21, 0x28, 0xf8, 0x18, 0x3e, 0x10, + 0x8e, 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x05, 0x28, 0x00, 0xba, 0x00, + 0x22, 0x80, 0x01, 0xe8, 0x02, 0xe8, 0x00, 0x8a, + 0x00, 0x22, 0x80, 0x09, 0xa0, 0x03, 0xa8, 0x00, + 0xbe, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x42, 0x5a, + 0x00, 0xbe, 0x40, 0x2f, 0xa0, 0x09, 0x60, 0x02, + 0x38, 0x85, 0xae, 0x80, 0x27, 0xb8, 0x4b, 0xec, + 0x03, 0xbb, 0x80, 0xae, 0xc0, 0x0b, 0xa0, 0x06, + 0xe8, 0x02, 0x38, 0x00, 0xbe, 0x40, 0x2e, 0x81, + 0x08, 0xa0, 0x02, 0xca, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x04, 0x0c, 0x00, 0xb1, 0x81, + 0x28, 0xc0, 0x03, 0x0c, 0x02, 0xcc, 0x00, 0x81, + 0x80, 0x0c, 0xc0, 0x0b, 0x30, 0x02, 0xac, 0x00, + 0xb0, 0x80, 0x24, 0xc0, 0x0b, 0x30, 0x02, 0x0d, + 0x00, 0x83, 0x80, 0x2c, 0xf0, 0x0b, 0x38, 0x00, + 0xcf, 0x80, 0x93, 0x40, 0x20, 0xe8, 0x09, 0x3e, + 0x02, 0x8e, 0x80, 0x83, 0x00, 0x28, 0xe8, 0x0b, + 0xbd, 0x02, 0x4f, 0x40, 0xb3, 0x40, 0x2c, 0xc0, + 0x0a, 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x01, 0x1c, 0x00, 0xb3, 0xc0, + 0x29, 0xc0, 0x09, 0x70, 0x02, 0xde, 0x00, 0x97, + 0xc0, 0x29, 0xc0, 0x0b, 0x70, 0x06, 0x9c, 0x40, + 0xb7, 0x08, 0x2d, 0xc9, 0x0b, 0x70, 0x02, 0xfc, + 0x20, 0xa7, 0x04, 0x0d, 0xc0, 0x09, 0xf0, 0x12, + 0x5e, 0x00, 0xb7, 0x08, 0x2d, 0xc0, 0x0b, 0x54, + 0x02, 0x80, 0x00, 0xa7, 0xc4, 0x21, 0xc2, 0x8a, + 0x00, 0x02, 0x5c, 0x00, 0x37, 0x00, 0x2d, 0xe0, + 0x08, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0xe6, 0x00, 0xa8, + 0x08, 0x1e, 0x00, 0xf7, 0x80, 0xa9, 0xea, 0x0f, + 0x78, 0x03, 0xdf, 0x42, 0xc3, 0x80, 0xbd, 0xe0, + 0x0f, 0x78, 0x03, 0x9e, 0x00, 0xf7, 0x80, 0x3d, + 0xe4, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xd7, 0x80, + 0x2d, 0xe0, 0x0f, 0x78, 0x03, 0xfe, 0x04, 0x97, + 0x80, 0x35, 0xa0, 0x0f, 0x58, 0x03, 0x92, 0x00, + 0xc7, 0x80, 0x39, 0xe0, 0x0f, 0x78, 0x02, 0x5e, + 0x04, 0xf7, 0x82, 0x2f, 0xf0, 0x0e, 0x78, 0x03, + 0xe2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x1d, 0xac, 0x00, 0xbb, 0x01, 0x36, 0xcc, 0x0d, + 0xb0, 0x03, 0xed, 0x80, 0xeb, 0x00, 0x36, 0xd4, + 0x0d, 0xb0, 0x03, 0xac, 0x00, 0xf9, 0x00, 0x3e, + 0xd8, 0x0b, 0xb1, 0x03, 0x6c, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x8d, 0xb0, 0x13, 0xac, 0x04, 0xeb, + 0x04, 0x36, 0x80, 0x4f, 0x80, 0x27, 0xa0, 0x10, + 0xfa, 0x00, 0x3a, 0xc0, 0x0f, 0xa0, 0x52, 0xa8, + 0x00, 0xf8, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xc2, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0xfe, 0x00, 0xf7, 0x80, 0x3b, 0xe4, 0x0f, + 0xf8, 0x03, 0x3e, 0x00, 0xff, 0x80, 0x3d, 0xf4, + 0x0c, 0xf3, 0x03, 0xff, 0x00, 0xff, 0x82, 0x1b, + 0xe2, 0x0f, 0xfc, 0x03, 0x3c, 0x80, 0xcf, 0x80, + 0xb3, 0xe0, 0x0f, 0xe8, 0x07, 0xfe, 0x00, 0xff, + 0x94, 0x33, 0xe4, 0x1c, 0x59, 0x02, 0x32, 0x80, + 0xd7, 0x80, 0x33, 0xe1, 0x0c, 0xf8, 0x13, 0x3e, + 0x40, 0xff, 0x81, 0x3d, 0xe0, 0x04, 0xf9, 0x03, + 0xc0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x01, 0x9c, 0x00, 0xb7, 0x04, 0x21, 0xc0, 0x0b, + 0x60, 0x02, 0x1c, 0x10, 0xb7, 0x00, 0x2d, 0xc0, + 0x18, 0x71, 0x07, 0x9c, 0x00, 0xb7, 0x00, 0x2d, + 0xc4, 0x0d, 0x70, 0x03, 0x5c, 0x00, 0xdd, 0x10, + 0x21, 0xc1, 0x0b, 0x52, 0x23, 0xed, 0x09, 0x00, + 0xe7, 0x00, 0x9c, 0x80, 0xb7, 0x00, 0x25, 0xd0, + 0x0a, 0x70, 0x03, 0x50, 0x00, 0xb7, 0x00, 0xa9, + 0x80, 0x48, 0x50, 0x02, 0x95, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x08, 0x70, 0x03, 0xaa, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0xb5, 0x00, 0x29, 0xc0, 0x1b, 0x10, 0x02, 0x9c, + 0x00, 0xb5, 0x10, 0x2f, 0xc0, 0x48, 0x70, 0x06, + 0x9c, 0x20, 0xb6, 0x10, 0x29, 0xc0, 0x0b, 0x70, + 0x02, 0x58, 0x00, 0xa6, 0x00, 0x21, 0xc0, 0x0b, + 0x60, 0x06, 0xdc, 0x00, 0xb4, 0x01, 0x24, 0xc0, + 0x1a, 0x50, 0x02, 0x90, 0x80, 0x95, 0x10, 0x21, + 0x40, 0x0a, 0x01, 0x02, 0x9c, 0x21, 0xb7, 0x08, + 0x2f, 0xc0, 0x0a, 0x70, 0x42, 0xc0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, 0xcc, 0x00, + 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0x0d, + 0x00, 0xb3, 0x00, 0x2c, 0xc2, 0x11, 0x30, 0x22, + 0x8e, 0x00, 0xb3, 0x00, 0x2c, 0xc8, 0x09, 0x30, + 0x02, 0x88, 0x00, 0x90, 0x01, 0x28, 0xc0, 0x0b, + 0x1c, 0x10, 0x8e, 0x00, 0xb0, 0x40, 0x24, 0xf2, + 0x4a, 0x00, 0x26, 0xe0, 0x00, 0xb0, 0x70, 0x28, + 0x00, 0x0a, 0x00, 0x22, 0x03, 0x00, 0xb0, 0x00, + 0x0c, 0xf0, 0x02, 0x30, 0x02, 0x80, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xac, 0x08, + 0xfb, 0x00, 0x3b, 0xc0, 0x0f, 0xb0, 0x03, 0x1d, + 0x20, 0xfb, 0x00, 0x2f, 0xf0, 0x0c, 0xb0, 0x03, + 0x9e, 0x00, 0xf3, 0x01, 0x3b, 0xd2, 0x0f, 0x7e, + 0x03, 0x0e, 0x20, 0xe9, 0x04, 0x32, 0xc0, 0x07, + 0x96, 0x03, 0xe2, 0x00, 0xf9, 0x50, 0xb2, 0x40, + 0x04, 0x90, 0x02, 0xa0, 0x00, 0xdb, 0x40, 0x30, + 0xc1, 0x2e, 0xb0, 0x1a, 0xae, 0x00, 0xbb, 0x11, + 0x2f, 0xd0, 0x0a, 0xb0, 0x03, 0xe2, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, + 0xed, 0x09, 0x00, 0xe8, 0x00, 0x79, 0x00, 0x3e, + 0xc0, 0x0f, 0x94, 0x03, 0xec, 0x30, 0xf9, 0x00, + 0x7e, 0xc4, 0x0e, 0xb0, 0x03, 0xac, 0x20, 0xba, + 0x40, 0x2e, 0xc0, 0x06, 0xb0, 0x42, 0x6d, 0x00, + 0xe8, 0x00, 0x34, 0xd0, 0x0f, 0xa0, 0xa3, 0x84, + 0x60, 0xf8, 0x00, 0x3a, 0xd4, 0x0f, 0x90, 0x01, + 0x61, 0x00, 0xb9, 0x02, 0x36, 0x40, 0x05, 0xb4, + 0x22, 0xed, 0x80, 0xfb, 0x00, 0x3e, 0xc6, 0x2d, + 0xb0, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x03, 0x6c, 0x07, 0xbc, 0x00, 0xb7, 0x20, + 0x77, 0xc0, 0x03, 0xf0, 0x03, 0xfc, 0x00, 0xcf, + 0x44, 0x33, 0xc1, 0x0c, 0xf0, 0x83, 0xbc, 0x00, + 0xcd, 0x00, 0x3f, 0xc0, 0x0a, 0xd8, 0x03, 0xf8, + 0x44, 0x89, 0x00, 0x3f, 0x40, 0x0c, 0xfa, 0x13, + 0xf0, 0x00, 0xcf, 0x94, 0x2e, 0xb0, 0x0c, 0x68, + 0x02, 0x36, 0x10, 0xcf, 0x14, 0x3f, 0xc0, 0x0a, + 0xf0, 0x03, 0xc0, 0x40, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x00, 0x2c, 0x00, 0x8b, 0x81, + 0xa2, 0xc0, 0x1b, 0xb0, 0x02, 0xec, 0x00, 0xab, + 0xc8, 0x3e, 0xc0, 0x8a, 0xb0, 0x22, 0x2f, 0xc9, + 0xd8, 0xc8, 0x2e, 0xf0, 0x0a, 0xa8, 0x82, 0x6c, + 0x80, 0xa8, 0xc0, 0x2e, 0xc0, 0x0f, 0x82, 0x02, + 0xe3, 0x00, 0xf8, 0x00, 0x2e, 0x00, 0x08, 0xaf, + 0x01, 0x83, 0x04, 0x88, 0x80, 0x2c, 0xc0, 0x68, + 0xb0, 0x02, 0xe8, 0x40, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x05, 0x2c, 0x00, 0xbb, 0x20, 0x2e, + 0xc0, 0x0b, 0xb4, 0x00, 0x2c, 0x00, 0x9b, 0x01, + 0x2a, 0xc0, 0x4b, 0xb0, 0x42, 0x6c, 0x00, 0x89, + 0x00, 0x20, 0xc0, 0x0a, 0xb0, 0x02, 0xac, 0x02, + 0xb9, 0x80, 0x2e, 0xe2, 0x08, 0x81, 0x02, 0xec, + 0x00, 0x29, 0xc0, 0xed, 0x09, 0x00, 0xe9, 0x00, + 0x2c, 0xc4, 0x08, 0x80, 0x02, 0xe2, 0x01, 0x8a, + 0x04, 0x2e, 0xc3, 0x00, 0x90, 0x02, 0x28, 0x80, + 0x88, 0x05, 0x2e, 0xc0, 0x48, 0xb0, 0x02, 0xe0, + 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x0c, 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x1b, 0x30, + 0x42, 0x2c, 0x00, 0x83, 0x00, 0x20, 0xc0, 0x0b, + 0x30, 0x02, 0xec, 0x10, 0xa3, 0x00, 0x6c, 0xc0, + 0x4a, 0xb0, 0x02, 0x0c, 0x00, 0x80, 0x00, 0x2c, + 0xc0, 0x0a, 0x00, 0x02, 0x4c, 0x08, 0xa0, 0x00, + 0x6c, 0xc0, 0x0b, 0x00, 0x02, 0xc0, 0x00, 0x90, + 0x80, 0x2c, 0x00, 0x08, 0x10, 0x02, 0x00, 0x02, + 0x80, 0x82, 0x2e, 0xc0, 0x42, 0x30, 0x02, 0xca, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x2c, 0x00, 0xfb, 0x00, 0x3f, 0xc0, 0x0f, 0xb0, + 0x42, 0xbc, 0x00, 0xdb, 0x01, 0x7f, 0xc0, 0x0b, + 0xb0, 0x03, 0x7c, 0x00, 0xcb, 0x00, 0x33, 0xc0, + 0x0c, 0x70, 0x07, 0xac, 0x00, 0x98, 0x00, 0x3e, + 0xc0, 0x0a, 0x80, 0x03, 0xec, 0x00, 0xe8, 0x02, + 0x2e, 0xc0, 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xc8, + 0x00, 0x3e, 0x00, 0x4c, 0x80, 0x0b, 0x20, 0x01, + 0xc8, 0x02, 0x3e, 0xc0, 0x86, 0xb0, 0x03, 0xc0, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, + 0xfc, 0x00, 0xfd, 0x00, 0x3f, 0xc1, 0x0f, 0xc0, + 0x03, 0xfc, 0x00, 0xdd, 0x00, 0x3b, 0xc0, 0x1f, + 0xf0, 0x06, 0xfc, 0x00, 0xfc, 0x04, 0x0b, 0xc0, + 0x0d, 0xf0, 0x03, 0xd4, 0x00, 0xfc, 0x00, 0x3f, + 0x01, 0x0f, 0xc0, 0x03, 0x7c, 0x00, 0xfc, 0x04, + 0x3f, 0xc0, 0x86, 0xe0, 0x23, 0xf0, 0x00, 0xfc, + 0x00, 0x3f, 0x00, 0x4f, 0xc0, 0x07, 0xb0, 0x00, + 0xec, 0x00, 0x7f, 0xc0, 0x1d, 0xf0, 0x03, 0xe8, + 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, + 0xfc, 0x00, 0xff, 0x00, 0x33, 0x80, 0xed, 0x09, + 0x00, 0xea, 0x00, 0x0f, 0xf0, 0x03, 0xf4, 0x00, + 0xef, 0x00, 0x3d, 0x00, 0x0d, 0xe0, 0x43, 0x70, + 0x04, 0x3c, 0x24, 0x3d, 0x80, 0x0e, 0x70, 0x0b, + 0x30, 0x10, 0xe4, 0x00, 0x3b, 0x00, 0x0f, 0xe0, + 0x03, 0xf0, 0x00, 0xed, 0x00, 0x3f, 0x00, 0x0c, + 0xc3, 0x03, 0xfc, 0x00, 0xc4, 0x06, 0x33, 0x08, + 0x0c, 0xc0, 0x03, 0x10, 0x60, 0xdc, 0x30, 0x37, + 0x1a, 0x0d, 0xc3, 0x83, 0xf0, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x10, 0xec, 0x00, 0x3b, + 0x00, 0x22, 0x40, 0x0b, 0xb0, 0x22, 0xe4, 0x10, + 0x8b, 0x04, 0x2e, 0x10, 0x0f, 0x90, 0x02, 0xe8, + 0x10, 0x9a, 0x40, 0x2e, 0x80, 0x0a, 0xa0, 0x02, + 0x28, 0x10, 0x89, 0x00, 0x22, 0x41, 0x8b, 0xa0, + 0x12, 0xe0, 0x00, 0x89, 0x00, 0x2e, 0x5f, 0x08, + 0x86, 0x02, 0xec, 0x42, 0x88, 0x00, 0x22, 0x56, + 0x08, 0x80, 0x02, 0x24, 0x80, 0xda, 0x52, 0x22, + 0x10, 0x08, 0x06, 0x22, 0xe0, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, 0x00, 0xb3, + 0x00, 0x20, 0x80, 0x0b, 0x30, 0x02, 0xcc, 0x02, + 0xa3, 0x00, 0x6c, 0x10, 0x18, 0x20, 0x22, 0x84, + 0x00, 0x90, 0x10, 0x2e, 0x40, 0x1a, 0xb0, 0x02, + 0x20, 0x00, 0xab, 0x00, 0xa8, 0x80, 0x0b, 0x20, + 0x02, 0xc0, 0x00, 0xa1, 0x00, 0x24, 0x40, 0x08, + 0x01, 0x12, 0xcc, 0x00, 0x0b, 0x00, 0x20, 0x00, + 0x69, 0x00, 0x42, 0x00, 0x00, 0x91, 0x02, 0x24, + 0x08, 0x28, 0x02, 0x02, 0xe2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, 0x00, 0xbb, + 0x00, 0x22, 0x40, 0x0b, 0xb0, 0x02, 0xee, 0x14, + 0x8b, 0x00, 0x2e, 0x00, 0x2b, 0xa0, 0xc2, 0xec, + 0x00, 0x9a, 0x8a, 0x2e, 0x40, 0x12, 0xa1, 0x00, + 0x28, 0x48, 0x8b, 0x08, 0x22, 0xd1, 0x0b, 0xa8, + 0x00, 0xe4, 0x00, 0x29, 0x00, 0x2e, 0x60, 0x08, + 0x88, 0xed, 0x09, 0x00, 0xeb, 0x00, 0x02, 0xec, + 0x00, 0x2a, 0x06, 0xa2, 0x44, 0x09, 0x8c, 0x02, + 0x28, 0x12, 0x9a, 0x00, 0x22, 0x44, 0x0a, 0xb2, + 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x15, 0xec, 0x00, 0xf3, 0x00, 0x32, 0x86, + 0x0f, 0xb0, 0x03, 0xcf, 0x80, 0xeb, 0x01, 0x7e, + 0x82, 0x0d, 0xa4, 0x03, 0xae, 0x00, 0xda, 0x80, + 0x3e, 0x72, 0x0e, 0x3e, 0x01, 0x2a, 0x80, 0xeb, + 0x00, 0x3a, 0xf0, 0x0f, 0xa2, 0x01, 0xc2, 0x60, + 0x69, 0x80, 0x36, 0x38, 0x2c, 0x9c, 0x80, 0xe4, + 0x00, 0xc0, 0x40, 0x72, 0xa0, 0x0d, 0x88, 0x09, + 0x20, 0x80, 0xd8, 0x00, 0x36, 0x20, 0x0d, 0x82, + 0x13, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x01, 0xbc, 0x00, 0xff, 0x00, 0xbe, 0x60, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x40, 0x1f, + 0xa8, 0x0b, 0xf0, 0x43, 0xfc, 0x80, 0xde, 0x00, + 0x3f, 0x48, 0x0f, 0xf0, 0x2b, 0xfe, 0x00, 0xff, + 0x20, 0x3f, 0xd0, 0x0f, 0xe0, 0x13, 0xf2, 0x0c, + 0xdd, 0x90, 0x3e, 0x40, 0x0f, 0xd0, 0x03, 0xdc, + 0x00, 0xdc, 0x98, 0x3d, 0x80, 0x0e, 0x40, 0x43, + 0xd6, 0x40, 0xe9, 0x20, 0x3f, 0x80, 0x8d, 0xf8, + 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x10, 0xac, 0x00, 0xdb, 0x00, 0x3e, 0x9c, + 0x0e, 0xb0, 0x03, 0xec, 0x20, 0xca, 0x00, 0x32, + 0x90, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xea, 0x01, + 0x32, 0x60, 0x0c, 0xb6, 0x03, 0x6c, 0x04, 0xfb, + 0x04, 0x3a, 0xd0, 0x0c, 0x85, 0x03, 0xa7, 0x00, + 0xf9, 0x40, 0x3e, 0x40, 0x0c, 0x96, 0x03, 0x24, + 0xc0, 0xfa, 0x40, 0x32, 0x49, 0x0d, 0x87, 0x03, + 0x20, 0x10, 0x49, 0x16, 0x32, 0xc9, 0x0d, 0x81, + 0x03, 0x90, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0x41, + 0x08, 0xb0, 0x02, 0xec, 0xed, 0x09, 0x00, 0xec, + 0x00, 0x08, 0x8b, 0x81, 0x30, 0xc0, 0x09, 0xbe, + 0x02, 0x6c, 0x00, 0xaa, 0x20, 0x34, 0xd0, 0x8d, + 0xbc, 0x83, 0x0c, 0x08, 0xb3, 0xd0, 0x22, 0xe0, + 0x08, 0xa0, 0x02, 0xe5, 0x10, 0x9b, 0xc1, 0x2e, + 0x54, 0x0a, 0x90, 0x02, 0xad, 0x10, 0x3a, 0x00, + 0x22, 0x70, 0x08, 0x80, 0x02, 0x28, 0x00, 0xd9, + 0x50, 0x22, 0xd0, 0x08, 0xb9, 0x02, 0x32, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, + 0x00, 0xb3, 0x00, 0x2c, 0x60, 0x0a, 0x30, 0x02, + 0xc7, 0x40, 0x93, 0x20, 0xa4, 0x41, 0x18, 0x2a, + 0x22, 0x48, 0x81, 0xa1, 0x00, 0x20, 0xd2, 0x0b, + 0x2c, 0x02, 0x4c, 0x00, 0xb3, 0x44, 0x28, 0xe0, + 0x18, 0x28, 0x02, 0x81, 0x80, 0xb1, 0xf0, 0x2e, + 0x00, 0x08, 0x10, 0x42, 0xcf, 0x00, 0xb0, 0xc0, + 0x20, 0x10, 0x49, 0x0c, 0x0a, 0x88, 0x00, 0x88, + 0x00, 0x22, 0x24, 0x88, 0x08, 0x02, 0xb8, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x1e, + 0x00, 0xb7, 0x88, 0x2d, 0xe0, 0x08, 0x78, 0x02, + 0xd2, 0x00, 0x9f, 0x8c, 0x21, 0xe0, 0x28, 0x41, + 0x02, 0x7a, 0x00, 0xa7, 0x80, 0x25, 0xe0, 0x0b, + 0x78, 0x02, 0x9e, 0x60, 0xb7, 0x0c, 0x2b, 0xe8, + 0x08, 0x6c, 0x42, 0xd2, 0x04, 0x95, 0x80, 0x2d, + 0x20, 0x02, 0x78, 0x40, 0x9e, 0x00, 0xb4, 0x88, + 0xe1, 0x60, 0x08, 0x49, 0x02, 0x96, 0x04, 0x96, + 0x91, 0x20, 0xe0, 0x28, 0x48, 0x02, 0x08, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x0c, + 0x00, 0xf3, 0x00, 0x3c, 0x41, 0x0e, 0x31, 0x02, + 0xc4, 0x80, 0x93, 0x20, 0x24, 0x40, 0x1f, 0x31, + 0x03, 0x4c, 0x00, 0xe2, 0x10, 0x30, 0xc0, 0x07, + 0x20, 0x03, 0x44, 0x40, 0xf3, 0x11, 0x38, 0xc2, + 0x24, 0x20, 0x03, 0x8c, 0x00, 0xf1, 0x60, 0x3c, + 0xc2, 0x08, 0x80, 0x81, 0xcc, 0x00, 0xf3, 0xed, + 0x09, 0x00, 0xed, 0x00, 0x10, 0x32, 0x82, 0x0d, + 0x00, 0x03, 0x8c, 0x00, 0xc1, 0x00, 0x30, 0x90, + 0x0c, 0x30, 0x03, 0x92, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x00, 0xd4, 0x00, 0xe7, + 0x02, 0x07, 0xc0, 0x8f, 0xf0, 0x03, 0xdc, 0x00, + 0xd6, 0x00, 0x3f, 0xc0, 0x0d, 0xd0, 0x03, 0x7c, + 0x40, 0xff, 0x10, 0x35, 0xc9, 0x0f, 0xe0, 0x03, + 0xf4, 0x00, 0xfd, 0x00, 0x3f, 0x80, 0x4f, 0xf0, + 0x03, 0xfc, 0x00, 0xfe, 0x00, 0x3f, 0xc0, 0x8f, + 0x60, 0x03, 0x7c, 0x00, 0xfe, 0x04, 0x3f, 0xc0, + 0xce, 0xf0, 0x03, 0xd0, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x05, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0x40, 0x09, 0xb0, 0x43, 0xec, 0x00, 0xeb, + 0x04, 0x2e, 0xc0, 0x4a, 0xa8, 0x13, 0xac, 0x00, + 0xfb, 0x00, 0x1e, 0xc0, 0x0f, 0xb0, 0x03, 0xce, + 0x00, 0xeb, 0x00, 0x12, 0xe0, 0x6c, 0xb0, 0x03, + 0xe8, 0x04, 0xfa, 0x02, 0x3e, 0x80, 0x0f, 0xb0, + 0x13, 0x26, 0x00, 0xe8, 0x00, 0x3e, 0x80, 0x0f, + 0xa0, 0x03, 0x2a, 0x08, 0x1a, 0x00, 0x36, 0x40, + 0x0f, 0xb0, 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x01, 0x9c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x04, 0x87, + 0x00, 0x2c, 0xc0, 0x2d, 0x60, 0x03, 0x1c, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0x87, 0x00, 0x21, 0xc0, 0x08, 0x70, 0x02, + 0xd8, 0x00, 0xb6, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0x1c, 0x00, 0x84, 0x00, 0x2d, 0x80, 0x0b, + 0x70, 0x12, 0xb4, 0x00, 0x87, 0x01, 0x21, 0xc0, + 0x0b, 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, 0xb7, 0x82, + 0x6d, 0x60, 0x09, 0x78, 0x42, 0xce, 0x00, 0xa7, + 0x88, 0x2d, 0xed, 0x09, 0x00, 0xee, 0x00, 0xe2, + 0x0a, 0xf8, 0x02, 0xde, 0x00, 0xb6, 0x81, 0x2d, + 0xe2, 0x1b, 0x7c, 0x02, 0xfe, 0x00, 0xa3, 0x80, + 0x27, 0xe2, 0x09, 0x78, 0x22, 0xde, 0x00, 0xb6, + 0xc0, 0x2d, 0xe0, 0x0b, 0x28, 0x22, 0x06, 0x20, + 0xa5, 0x80, 0x2d, 0xf0, 0x0b, 0x28, 0x42, 0x1c, + 0x00, 0x93, 0x81, 0x25, 0xe0, 0x0b, 0x78, 0x02, + 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x6c, 0xc0, 0x0b, + 0x30, 0x42, 0xcd, 0x48, 0x80, 0x4a, 0x0e, 0xe8, + 0x29, 0x3c, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x40, 0x83, 0x80, + 0x24, 0xe0, 0x09, 0x30, 0x02, 0xcc, 0x00, 0xb2, + 0x80, 0x2c, 0xc4, 0x0b, 0x38, 0x0a, 0x0e, 0x10, + 0x82, 0x80, 0x2c, 0xc2, 0x0b, 0x30, 0x02, 0x8c, + 0x00, 0x83, 0x04, 0x20, 0xd8, 0x0b, 0xb0, 0x02, + 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, + 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3f, 0x80, 0x09, + 0xa0, 0x03, 0xfb, 0x00, 0xee, 0x45, 0x3f, 0xb0, + 0x0a, 0xe4, 0x03, 0xf9, 0x20, 0xfe, 0xc4, 0x3f, + 0xb0, 0x0f, 0x64, 0x02, 0xf9, 0x00, 0xe6, 0xc0, + 0x37, 0x90, 0x0d, 0xee, 0x03, 0xfb, 0x80, 0xfe, + 0x40, 0x3f, 0x90, 0x0f, 0xe1, 0x83, 0x2a, 0x10, + 0xee, 0x70, 0x7f, 0xb0, 0x8b, 0xe0, 0x83, 0x38, + 0x00, 0xde, 0x00, 0x37, 0xb8, 0x0f, 0xed, 0xa3, + 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0xe0, 0x00, 0xf8, 0x04, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x24, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x81, 0x4b, 0xa2, 0x00, 0xf8, 0x1c, 0x3e, + 0x20, 0x0f, 0x8c, 0x12, 0xe2, 0x00, 0xf8, 0x18, + 0x3a, 0x30, 0x2e, 0x88, 0x03, 0xe2, 0x00, 0xf8, + 0x84, 0x3e, 0x12, 0x0f, 0x80, 0x03, 0xe1, 0x00, + 0xf8, 0x00, 0x3e, 0x10, 0x0f, 0xed, 0x09, 0x00, + 0xef, 0x00, 0x88, 0x03, 0xe0, 0x08, 0xf0, 0x70, + 0x3e, 0x10, 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, + 0xf9, 0x20, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xe6, + 0x87, 0xc9, 0x02, 0xb2, 0x40, 0x0d, 0x90, 0x82, + 0xe4, 0x00, 0xc9, 0x80, 0x3e, 0x68, 0x0d, 0x90, + 0x03, 0x64, 0x04, 0xf9, 0xa1, 0x32, 0x68, 0x0f, + 0x98, 0x00, 0xe4, 0x00, 0xf9, 0x80, 0x32, 0x40, + 0x0f, 0x18, 0x03, 0x24, 0x00, 0xf9, 0x80, 0x3e, + 0x44, 0x0f, 0x18, 0x02, 0x24, 0x00, 0xe9, 0x20, + 0x3c, 0x40, 0x0c, 0x91, 0x0b, 0x02, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, + 0xb9, 0x40, 0x2c, 0x54, 0x08, 0x90, 0x02, 0xc5, + 0x00, 0x81, 0x80, 0x32, 0x40, 0x0d, 0x94, 0x02, + 0xc5, 0x02, 0xf9, 0x90, 0x2e, 0x40, 0x1e, 0x92, + 0x02, 0x24, 0x04, 0xb9, 0x80, 0x22, 0x50, 0x0b, + 0x93, 0x02, 0xe5, 0x00, 0xb1, 0x80, 0x2a, 0x50, + 0x0b, 0x9c, 0x02, 0xa6, 0x00, 0xb9, 0x01, 0x2e, + 0x70, 0x4b, 0x9c, 0x82, 0x04, 0x40, 0x89, 0x00, + 0x22, 0x74, 0x08, 0x9e, 0x02, 0x20, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x18, 0x90, 0x06, 0xe4, + 0x00, 0x8b, 0x18, 0x6a, 0x50, 0x08, 0x91, 0x06, + 0xe4, 0x4a, 0x89, 0x02, 0x2e, 0x40, 0x08, 0x92, + 0x02, 0x64, 0x88, 0xb9, 0x00, 0xa6, 0x40, 0x0b, + 0x90, 0x02, 0xa6, 0x04, 0xb9, 0x11, 0x22, 0x42, + 0x8b, 0x92, 0xa2, 0x64, 0x40, 0xbb, 0x10, 0x2e, + 0x40, 0x0b, 0x92, 0x02, 0xa5, 0x00, 0xa9, 0x0d, + 0x2a, 0x51, 0x08, 0x90, 0x02, 0x06, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x28, 0x10, 0x02, 0xc4, + 0x18, 0x81, 0x02, 0x28, 0x50, 0x09, 0x18, 0x02, + 0xed, 0x09, 0x00, 0xf0, 0x00, 0xec, 0x02, 0xb1, + 0x00, 0x2c, 0x41, 0x0a, 0x90, 0x02, 0x04, 0x00, + 0x31, 0x00, 0x24, 0xd0, 0x1b, 0x10, 0x02, 0xc6, + 0x00, 0xb1, 0x00, 0x28, 0x50, 0x43, 0x14, 0x02, + 0xc4, 0xa0, 0xb1, 0x00, 0x2c, 0x50, 0x0b, 0x12, + 0x82, 0x85, 0x00, 0x81, 0x40, 0x20, 0x51, 0x08, + 0x14, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb8, 0x05, 0x60, 0x00, 0xb8, 0x00, 0x3e, + 0x00, 0x08, 0x80, 0x03, 0xe8, 0x00, 0x88, 0x00, + 0x3a, 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x04, 0x48, + 0x04, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0x60, 0x00, + 0xf8, 0x00, 0x36, 0x00, 0x0f, 0x80, 0x23, 0xa0, + 0x00, 0xf8, 0x00, 0x32, 0x00, 0x07, 0x80, 0x03, + 0x68, 0x80, 0xf8, 0x00, 0x3e, 0x80, 0x4f, 0x82, + 0x0b, 0xa0, 0x00, 0xe8, 0x00, 0x3a, 0x00, 0x2c, + 0x80, 0x03, 0x2e, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x19, 0xe4, 0x00, 0xf9, 0x00, 0x3f, + 0x50, 0x0f, 0x90, 0x13, 0xfd, 0x10, 0xfd, 0x00, + 0x33, 0x50, 0x0f, 0x50, 0x03, 0xf4, 0x00, 0xfd, + 0x40, 0x3f, 0x40, 0x0e, 0xd0, 0x03, 0xf4, 0x00, + 0xdd, 0x40, 0x39, 0x40, 0x0f, 0xd0, 0x03, 0xf4, + 0x08, 0xfd, 0x00, 0x3f, 0x50, 0x0f, 0xd4, 0x03, + 0xb4, 0x00, 0x3d, 0x04, 0x3f, 0x50, 0x0f, 0xd0, + 0x03, 0x75, 0x10, 0xfd, 0x44, 0x3b, 0x50, 0x0f, + 0xd4, 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x05, 0xe4, 0x00, 0xfd, 0x00, 0x3f, + 0x40, 0x0f, 0x90, 0x03, 0xd4, 0x84, 0xc5, 0x02, + 0x3b, 0x4c, 0x0f, 0x50, 0x02, 0xf4, 0x00, 0xfd, + 0x00, 0x37, 0x40, 0x0f, 0xd0, 0x43, 0xf4, 0x00, + 0xed, 0x00, 0x3f, 0x40, 0x0f, 0x50, 0x03, 0xf4, + 0x00, 0xfd, 0x00, 0xbf, 0x4c, 0x0c, 0xd0, 0x03, + 0xd4, 0x00, 0xcd, 0x00, 0x3d, 0x48, 0x0d, 0xd2, + 0x03, 0xf4, 0xc0, 0xed, 0x09, 0x00, 0xf1, 0x00, + 0xdd, 0x00, 0x33, 0x41, 0x4c, 0xd1, 0x03, 0x06, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, + 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, + 0x02, 0xe0, 0x00, 0xd8, 0x00, 0x22, 0x0c, 0x08, + 0x80, 0x02, 0xe0, 0x14, 0xb8, 0x10, 0xa2, 0x00, + 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x40, 0x2e, + 0x02, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, + 0x32, 0x0c, 0x0d, 0x84, 0x82, 0xe0, 0x40, 0xd8, + 0x01, 0x2e, 0x0a, 0x08, 0x81, 0x22, 0xe0, 0xc0, + 0x80, 0x48, 0x22, 0x02, 0x28, 0x81, 0x02, 0x0e, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, + 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x44, 0x8b, 0x10, + 0x42, 0xc4, 0x40, 0x89, 0x00, 0x28, 0x48, 0x0b, + 0x10, 0x12, 0xc4, 0x08, 0xb9, 0x00, 0x60, 0xc0, + 0x0b, 0x10, 0x16, 0xc6, 0x04, 0xb1, 0x10, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb9, 0x00, + 0x2c, 0x48, 0x49, 0x13, 0x42, 0xc4, 0x00, 0x91, + 0x02, 0x2c, 0x4c, 0x49, 0x10, 0x02, 0xc4, 0x80, + 0x91, 0x30, 0x20, 0x64, 0x0a, 0x18, 0x02, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, + 0xa4, 0x00, 0xbb, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x06, 0xe4, 0x04, 0x99, 0x11, 0x22, 0x42, 0x28, + 0x91, 0x06, 0xed, 0x00, 0xb9, 0x40, 0x22, 0xc0, + 0x8b, 0xb2, 0x06, 0xe4, 0x01, 0xb9, 0x00, 0x2e, + 0xc4, 0x0b, 0x90, 0x02, 0xe5, 0x40, 0xb9, 0x00, + 0xa2, 0x40, 0x49, 0x90, 0x02, 0xe4, 0x02, 0x1b, + 0xc0, 0x2e, 0x40, 0x49, 0xb1, 0x02, 0xe4, 0x00, + 0x89, 0x40, 0x20, 0xc8, 0x0a, 0xb2, 0x02, 0x06, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xc6, 0x04, 0xc9, 0xa0, 0x3a, 0x41, 0x0f, + 0x90, 0x83, 0xe5, 0x00, 0x79, 0x00, 0xed, 0x09, + 0x00, 0xf2, 0x00, 0x12, 0x6c, 0x0f, 0x90, 0x03, + 0xe6, 0x40, 0xe9, 0xc8, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe6, 0x00, 0xf1, 0x00, 0x3e, 0x72, 0x0d, + 0x96, 0x03, 0xe4, 0x00, 0xd9, 0xc0, 0x3e, 0x68, + 0x0d, 0x90, 0x03, 0xe4, 0x20, 0xd9, 0x00, 0xb2, + 0x60, 0x0e, 0x98, 0x0b, 0x28, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x43, 0xe5, 0x00, + 0xf9, 0x80, 0x3c, 0x41, 0x2f, 0x98, 0x03, 0xe4, + 0x00, 0xf9, 0xa0, 0x3e, 0x40, 0x0f, 0x98, 0x03, + 0xe6, 0x00, 0xf9, 0x40, 0x3e, 0x40, 0x0f, 0x99, + 0x03, 0xe6, 0x00, 0xf9, 0x10, 0x3a, 0x70, 0x0f, + 0x90, 0x83, 0xc4, 0x22, 0xf9, 0x00, 0x3e, 0x70, + 0x0e, 0x90, 0x03, 0xe6, 0x80, 0xf9, 0x09, 0x3e, + 0x60, 0x4d, 0x18, 0x03, 0xca, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, + 0x80, 0x3e, 0x20, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xc8, 0xd0, 0x36, 0x30, 0x07, 0x88, 0x03, 0x23, + 0x40, 0xc8, 0x10, 0x36, 0x30, 0x0f, 0x80, 0x03, + 0xa0, 0x40, 0xf8, 0xc0, 0x3e, 0x00, 0x0f, 0x88, + 0x02, 0x20, 0x50, 0xf8, 0x90, 0x3e, 0x02, 0x0f, + 0x80, 0x03, 0x60, 0x00, 0xc8, 0x58, 0x30, 0x10, + 0x0e, 0x80, 0x0b, 0x01, 0x00, 0xc0, 0x00, 0x36, + 0x00, 0x0f, 0x80, 0x03, 0x0a, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x28, 0x00, 0xbe, + 0xa0, 0x2f, 0xb0, 0x0b, 0xa0, 0x02, 0xfb, 0x50, + 0x86, 0xc0, 0x23, 0x91, 0x0a, 0xe4, 0x02, 0xb9, + 0x00, 0x82, 0x00, 0x27, 0x90, 0x0b, 0xe8, 0x02, + 0x2a, 0x00, 0xbe, 0xc0, 0x3b, 0xb9, 0x0b, 0xe4, + 0x82, 0xbb, 0x00, 0xbe, 0xc0, 0x2f, 0xb0, 0x0b, + 0xe4, 0x02, 0xfa, 0x80, 0xde, 0x81, 0x23, 0x80, + 0x08, 0xe4, 0x02, 0x38, 0x30, 0xce, 0x4c, 0x33, + 0xa8, 0xed, 0x09, 0x00, 0xf3, 0x00, 0x03, 0xe4, + 0x02, 0x0a, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x05, 0x4c, 0x00, 0xb3, 0x80, 0x28, 0xe0, + 0x0b, 0x30, 0x02, 0xc5, 0x02, 0x83, 0x80, 0x24, + 0xe0, 0x4b, 0x31, 0x0a, 0x4e, 0x00, 0xa3, 0x00, + 0x64, 0xc0, 0x0b, 0x32, 0x02, 0xcc, 0x00, 0xb3, + 0x10, 0x28, 0xc8, 0x0b, 0x38, 0x02, 0x0f, 0x28, + 0xb3, 0x00, 0x2e, 0xd0, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xa3, 0xc0, 0x20, 0x80, 0x2a, 0x32, 0x32, + 0x08, 0x08, 0x83, 0x40, 0x20, 0xe2, 0x0b, 0x3e, + 0x12, 0x0a, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0x42, + 0x0b, 0x70, 0x02, 0xd5, 0x10, 0x8f, 0x00, 0xa1, + 0xd0, 0x0a, 0x68, 0x02, 0x7a, 0x03, 0xa5, 0x00, + 0x25, 0xc0, 0x0b, 0xf8, 0x82, 0x5c, 0x18, 0x36, + 0x00, 0x29, 0xc0, 0x0b, 0x78, 0x0a, 0x98, 0x00, + 0xb6, 0x00, 0x2d, 0xd0, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0xbf, 0x84, 0x21, 0x50, 0x68, 0x3c, 0x02, + 0x18, 0x00, 0x87, 0x00, 0xa1, 0xc0, 0x0b, 0x74, + 0x02, 0x28, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x08, 0x1e, 0x00, 0xf5, 0x80, 0x39, 0x21, + 0x0f, 0x78, 0x03, 0xde, 0x00, 0xc7, 0x80, 0x34, + 0xa0, 0x2f, 0x68, 0x02, 0x5a, 0x08, 0xe5, 0x80, + 0x35, 0xe1, 0x0f, 0x78, 0x03, 0xde, 0x00, 0x77, + 0x80, 0x39, 0xe0, 0x0b, 0x48, 0x23, 0x1e, 0x10, + 0xf7, 0x80, 0x3d, 0xe0, 0x0b, 0x68, 0x02, 0x5e, + 0x00, 0xe7, 0x80, 0xb1, 0x80, 0x0e, 0x78, 0x03, + 0x02, 0x02, 0xc7, 0x80, 0x31, 0xe0, 0x0f, 0x38, + 0x0b, 0x2a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0x41, + 0x0f, 0xb0, 0x13, 0xe4, 0x00, 0xfb, 0x00, 0x3e, + 0x80, 0x4f, 0xa0, 0x03, 0x88, 0x00, 0xd9, 0x04, + 0x3e, 0xc0, 0x8f, 0x30, 0xed, 0x09, 0x00, 0xf4, + 0x00, 0x03, 0xac, 0x00, 0xfa, 0x00, 0x3a, 0xc0, + 0x0f, 0x80, 0x03, 0x68, 0x00, 0xfa, 0x00, 0x3e, + 0xc0, 0x0f, 0x90, 0x03, 0x64, 0x00, 0xd3, 0x00, + 0x3e, 0x80, 0x0f, 0xb0, 0x43, 0xe0, 0x00, 0xe8, + 0x00, 0x3a, 0xc0, 0x0f, 0xa0, 0x03, 0xc2, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, + 0x00, 0xf7, 0x80, 0x33, 0x21, 0x0f, 0xf8, 0x03, + 0xd6, 0x80, 0xc7, 0x82, 0x3b, 0xec, 0x2e, 0x68, + 0x03, 0x3a, 0x00, 0xdd, 0x80, 0x3b, 0xe0, 0x0f, + 0x78, 0x03, 0x1e, 0x00, 0xd6, 0x86, 0x3b, 0xe0, + 0x0d, 0x78, 0x03, 0x92, 0x00, 0xc6, 0x80, 0x33, + 0xa0, 0x0f, 0xf8, 0x03, 0xde, 0x14, 0xef, 0x82, + 0x33, 0xa0, 0x4e, 0xd8, 0x03, 0xfa, 0x00, 0xff, + 0x80, 0xb3, 0xe0, 0x0d, 0xf8, 0x03, 0xc0, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, + 0x00, 0xb7, 0x00, 0x21, 0x04, 0x0b, 0x70, 0x02, + 0xdc, 0x80, 0x87, 0x00, 0x01, 0xc4, 0x08, 0x42, + 0x02, 0x18, 0x40, 0x45, 0x00, 0x21, 0x40, 0x0b, + 0x72, 0x43, 0x5c, 0x00, 0xc6, 0x00, 0x23, 0x44, + 0x0f, 0x70, 0x03, 0x58, 0x60, 0x86, 0x00, 0x21, + 0x50, 0x0b, 0x70, 0x02, 0xdc, 0x40, 0x86, 0x11, + 0x21, 0x40, 0x08, 0x71, 0x02, 0xd8, 0x00, 0xbf, + 0x00, 0x21, 0x41, 0x08, 0x71, 0x82, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, + 0x00, 0xb5, 0x00, 0x21, 0x10, 0x0b, 0x70, 0x02, + 0xf4, 0xc8, 0x86, 0x00, 0x28, 0xcb, 0x2a, 0x60, + 0x02, 0x18, 0x00, 0x95, 0x00, 0x2d, 0xc4, 0x0b, + 0x70, 0x42, 0x1c, 0x40, 0x9c, 0x00, 0xa9, 0x00, + 0x0a, 0xc0, 0x02, 0x9c, 0x00, 0x8e, 0x00, 0x21, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xaf, 0x00, + 0x21, 0x00, 0x0a, 0x74, 0x82, 0xd8, 0x00, 0xb7, + 0x00, 0x20, 0x82, 0x0b, 0x50, 0x02, 0xc0, 0xed, + 0x09, 0x00, 0xf5, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x14, 0xcc, 0x00, 0xb1, 0x04, + 0xa0, 0x00, 0x0b, 0x30, 0x02, 0xc1, 0x84, 0x83, + 0x40, 0x20, 0xc2, 0x08, 0x04, 0x86, 0x08, 0x00, + 0x01, 0x08, 0x64, 0xe0, 0x0b, 0x20, 0x02, 0xcd, + 0x20, 0x82, 0x40, 0x20, 0x00, 0x0b, 0x08, 0x22, + 0x4b, 0x20, 0x80, 0x80, 0x20, 0x50, 0x0b, 0x9d, + 0x02, 0xcc, 0x00, 0x82, 0x90, 0xa0, 0x12, 0x08, + 0x38, 0x02, 0xc9, 0x20, 0x30, 0x89, 0x20, 0x10, + 0x0a, 0x04, 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x15, 0xac, 0x00, 0xfb, 0x00, + 0x12, 0xc0, 0x0f, 0xb0, 0x03, 0xe4, 0x00, 0xc9, + 0x10, 0xba, 0x70, 0x2a, 0x0c, 0xaa, 0x08, 0x20, + 0x59, 0xa0, 0x3e, 0xc2, 0x0f, 0xbc, 0x83, 0x2d, + 0x00, 0xdb, 0x40, 0x38, 0x14, 0x0e, 0x38, 0x81, + 0x87, 0x00, 0xcb, 0x02, 0x32, 0x50, 0x0f, 0x94, + 0x03, 0xcc, 0x00, 0xe9, 0x50, 0x12, 0x90, 0x0e, + 0x3c, 0x03, 0xef, 0x00, 0xbb, 0x88, 0x32, 0xf0, + 0x0f, 0xb8, 0x03, 0xea, 0x01, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0xec, 0x00, 0xfb, 0x40, + 0x3c, 0xe0, 0x0f, 0xb0, 0x03, 0xe4, 0x02, 0xfb, + 0x10, 0x3e, 0x40, 0x0f, 0x84, 0x03, 0xe8, 0x00, + 0xf9, 0x00, 0x3a, 0xd0, 0x0f, 0xb0, 0x23, 0x6e, + 0x15, 0xfa, 0x00, 0xbe, 0x10, 0x0d, 0x90, 0x03, + 0xa0, 0x02, 0xfa, 0x10, 0x7e, 0x08, 0xcf, 0x94, + 0x83, 0xeb, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x2f, + 0xb4, 0x03, 0xec, 0x40, 0xfb, 0x40, 0x3e, 0x88, + 0x0d, 0x90, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, 0xfd, 0x00, + 0x3f, 0x24, 0x0c, 0xf0, 0x03, 0xdc, 0x00, 0xcf, + 0x20, 0x35, 0x00, 0x2d, 0xe0, 0x03, 0x38, 0x40, + 0x69, 0x00, 0x1f, 0xc0, 0x0f, 0xf8, 0x83, 0x7f, + 0x04, 0xff, 0xed, 0x09, 0x00, 0xf6, 0x00, 0x08, + 0x33, 0x00, 0x0c, 0xca, 0x03, 0x34, 0x40, 0x0f, + 0x80, 0x3d, 0x40, 0x08, 0xc0, 0x03, 0x3c, 0x00, + 0xcf, 0x80, 0x3f, 0x80, 0x0f, 0xe8, 0x01, 0x32, + 0x40, 0xff, 0x00, 0x1b, 0x40, 0x0f, 0xf0, 0xa3, + 0xc1, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x81, + 0x04, 0x6c, 0x00, 0xb9, 0x00, 0x2e, 0x60, 0x28, + 0xb0, 0x02, 0xe5, 0x04, 0x83, 0x82, 0x22, 0x26, + 0x0a, 0xa4, 0x82, 0x6b, 0x00, 0xa9, 0x00, 0x2e, + 0xf0, 0x0b, 0x24, 0x02, 0x2c, 0x00, 0xb2, 0x00, + 0x22, 0x30, 0x08, 0x8c, 0x82, 0x22, 0x00, 0x8a, + 0x84, 0x2e, 0x30, 0x08, 0x9c, 0x82, 0x25, 0x00, + 0x89, 0x80, 0x2e, 0x80, 0x4b, 0xbc, 0x02, 0x03, + 0x08, 0xaa, 0x88, 0x62, 0x00, 0x0b, 0x84, 0x02, + 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x05, 0x2c, 0x00, 0xba, 0x80, 0x2e, 0x00, 0x08, + 0xb0, 0x02, 0xe5, 0x00, 0x8b, 0x01, 0x26, 0x80, + 0x69, 0x82, 0x02, 0x68, 0x00, 0x89, 0x20, 0x2a, + 0x44, 0x0b, 0xb1, 0x02, 0x6c, 0x01, 0xba, 0x16, + 0x26, 0x21, 0x08, 0xa0, 0x42, 0x24, 0x02, 0xaa, + 0x10, 0x2e, 0x20, 0x0a, 0x88, 0x02, 0x6d, 0x00, + 0x89, 0x20, 0x2a, 0x80, 0x0b, 0xb2, 0x0a, 0xa4, + 0x20, 0xa0, 0x10, 0x2e, 0xe0, 0x0b, 0xa8, 0x02, + 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x0c, 0x00, 0xb2, 0x00, 0x2c, 0x00, 0x08, + 0x30, 0x02, 0xcc, 0x00, 0x83, 0x00, 0x20, 0x80, + 0x0a, 0x80, 0x02, 0x48, 0x04, 0xa1, 0x00, 0x2c, + 0x00, 0x0b, 0x30, 0x12, 0x04, 0x00, 0x32, 0x00, + 0x26, 0x00, 0x18, 0x30, 0x02, 0x22, 0x00, 0xa2, + 0x00, 0x2c, 0x00, 0x0a, 0x00, 0x00, 0x4c, 0x04, + 0x81, 0x01, 0x2c, 0x40, 0x0b, 0x30, 0x02, 0x84, + 0x01, 0xa1, 0x00, 0x2c, 0x00, 0x8b, 0x00, 0x02, + 0xc2, 0x01, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, + 0xf9, 0x00, 0x3e, 0x00, 0x0c, 0xb0, 0x03, 0xe4, + 0x00, 0xca, 0x00, 0x36, 0x80, 0x2d, 0xa0, 0x13, + 0x20, 0x02, 0xc9, 0x00, 0x3a, 0xc0, 0x0f, 0xb0, + 0x03, 0x6c, 0x00, 0x7a, 0x00, 0x36, 0x01, 0x4c, + 0x80, 0x03, 0x24, 0x10, 0xca, 0x02, 0x3e, 0x40, + 0x0e, 0x80, 0x0b, 0x6c, 0x00, 0xcb, 0x00, 0x3a, + 0x00, 0x0f, 0xb0, 0x03, 0xa0, 0x00, 0xe8, 0x00, + 0x2e, 0x00, 0x0f, 0x80, 0x03, 0xc0, 0x03, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, + 0xfd, 0x02, 0x3f, 0x00, 0x0f, 0xf0, 0x03, 0xf4, + 0x06, 0xff, 0x01, 0x3f, 0x80, 0x0f, 0xc0, 0x07, + 0x90, 0x00, 0xdd, 0x00, 0x3f, 0x80, 0x4f, 0xc0, + 0x03, 0xfc, 0x10, 0xfe, 0x00, 0xbb, 0x00, 0x0f, + 0xc0, 0x03, 0xf0, 0x00, 0xde, 0x00, 0x3f, 0x00, + 0x0d, 0xc0, 0x03, 0xbc, 0x02, 0xf7, 0x00, 0x3d, + 0x01, 0x0f, 0xf0, 0x03, 0x70, 0x04, 0xec, 0x00, + 0x33, 0x00, 0x0f, 0xc0, 0x03, 0xe8, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x05, 0xf0, 0x00, + 0xfd, 0x00, 0x3f, 0xc8, 0x4f, 0xc1, 0x43, 0x3c, + 0xa2, 0xcc, 0x00, 0x3f, 0x00, 0x0c, 0xf3, 0x43, + 0xf0, 0x00, 0xcd, 0x00, 0x3f, 0x04, 0x0f, 0xc0, + 0x03, 0x30, 0xc2, 0xcf, 0x28, 0x3b, 0x04, 0x0f, + 0xc2, 0xc3, 0xfc, 0x00, 0xef, 0x00, 0x3f, 0x0e, + 0x0c, 0xc0, 0x0b, 0x3c, 0x00, 0xff, 0x20, 0x3b, + 0xc8, 0x0f, 0xc4, 0x03, 0xfc, 0x80, 0xff, 0x00, + 0x33, 0x00, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0xec, 0x20, + 0xbb, 0x20, 0x2f, 0xc4, 0x0b, 0x32, 0x02, 0x3d, + 0x00, 0x83, 0x00, 0x2e, 0xc2, 0x88, 0xf7, 0x02, + 0xec, 0x30, 0x8a, 0x28, 0x2c, 0xc8, 0x0b, 0x80, + 0x02, 0xa0, 0x80, 0x8f, 0x40, 0xb2, 0x00, 0x0e, + 0xed, 0x09, 0x00, 0xf8, 0x00, 0x86, 0x02, 0xe8, + 0x08, 0xdb, 0x00, 0x2e, 0x18, 0x0b, 0x80, 0x03, + 0x2c, 0x00, 0xef, 0x52, 0x2f, 0xdc, 0x0b, 0xa2, + 0x22, 0xfd, 0xe8, 0xbf, 0x10, 0x22, 0x40, 0x0b, + 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x88, 0x45, 0xcc, 0x88, 0xb3, 0x08, 0x2c, + 0xc0, 0x8b, 0x3a, 0x02, 0x0c, 0x00, 0x83, 0x28, + 0x2c, 0xe8, 0x0a, 0x30, 0x02, 0xcc, 0x80, 0x82, + 0x20, 0x2c, 0xc0, 0x0a, 0x80, 0x02, 0x80, 0x40, + 0x83, 0x08, 0x20, 0x00, 0x03, 0x00, 0x82, 0xcc, + 0x00, 0xb3, 0x02, 0x2c, 0x00, 0x09, 0x80, 0x02, + 0x0c, 0x00, 0xa3, 0x04, 0x2c, 0xca, 0x18, 0x22, + 0x42, 0xcc, 0x80, 0xb3, 0x00, 0x20, 0x00, 0x0b, + 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x15, 0xac, 0x90, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0x91, 0x02, 0x2c, 0x00, 0x89, 0x14, + 0x2c, 0xc4, 0x0a, 0xb0, 0x02, 0xed, 0x06, 0x8b, + 0x01, 0x2e, 0x45, 0x1b, 0x81, 0x82, 0xa6, 0x00, + 0x8b, 0x00, 0x26, 0x02, 0x19, 0x80, 0x42, 0xec, + 0x00, 0x9b, 0x00, 0x2c, 0xc2, 0x0b, 0xb0, 0x22, + 0xe4, 0x02, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0xe2, 0xec, 0x00, 0xbb, 0x00, 0x02, 0x40, 0x0b, + 0xb0, 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x15, 0xef, 0x00, 0xfb, 0x90, 0x3e, + 0xc0, 0x0f, 0xb8, 0x03, 0x2c, 0x00, 0xcb, 0xa0, + 0x3e, 0xe0, 0x2e, 0xb0, 0x43, 0xec, 0x00, 0x8a, + 0x4c, 0x3e, 0xf8, 0x0f, 0x80, 0x43, 0xa2, 0x80, + 0xcb, 0x00, 0x32, 0x60, 0x0f, 0x88, 0x83, 0xef, + 0x20, 0xfb, 0x00, 0x3e, 0x00, 0x0c, 0x0c, 0x01, + 0x2c, 0x00, 0xeb, 0x00, 0x3a, 0xc0, 0x0f, 0x84, + 0x01, 0xec, 0x00, 0xfb, 0x00, 0x92, 0x00, 0x0f, + 0xb0, 0x43, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x01, 0xed, 0x09, 0x00, 0xf9, 0x00, + 0xb2, 0x00, 0xfd, 0x80, 0x3f, 0xc0, 0x0f, 0xf8, + 0x0b, 0xdc, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0d, + 0xf0, 0x03, 0xf5, 0x00, 0xfc, 0x10, 0x3f, 0xe1, + 0x0f, 0xc8, 0x23, 0xf4, 0x00, 0xff, 0x02, 0x3b, + 0x44, 0x8e, 0xf2, 0x03, 0xfe, 0x40, 0xfe, 0x00, + 0x6f, 0xd0, 0x0e, 0xf4, 0x23, 0x38, 0x20, 0xeb, + 0x00, 0x3f, 0xc0, 0x0f, 0xf2, 0x23, 0xfc, 0x00, + 0xf7, 0x00, 0x3f, 0x44, 0x0f, 0xf0, 0x03, 0xf9, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, + 0xad, 0x00, 0xcb, 0x00, 0x3e, 0xc2, 0x0f, 0xa0, + 0x0b, 0x2c, 0x00, 0xfb, 0x40, 0xb2, 0x40, 0x2e, + 0xb0, 0x03, 0x2c, 0x00, 0xea, 0x04, 0x3a, 0x80, + 0x0f, 0x8e, 0x03, 0xa0, 0x00, 0xf3, 0x18, 0x32, + 0x8c, 0x0c, 0xb0, 0x03, 0xed, 0x80, 0xf9, 0x00, + 0x3e, 0x00, 0x0f, 0x81, 0x03, 0xec, 0x04, 0xfb, + 0x00, 0x36, 0xc0, 0x0f, 0xa4, 0x03, 0xac, 0x24, + 0xcb, 0x00, 0x32, 0x00, 0x0f, 0xb0, 0x03, 0xd0, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, + 0x2c, 0x00, 0x8b, 0x04, 0x2f, 0xe8, 0x0b, 0xb0, + 0x02, 0x3c, 0x40, 0xbb, 0x00, 0x22, 0xc0, 0x00, + 0xf0, 0x02, 0x2c, 0x00, 0xba, 0x00, 0x2e, 0xc0, + 0x08, 0x04, 0x00, 0xe4, 0x00, 0xbf, 0x81, 0x22, + 0xb1, 0x0a, 0xb1, 0x02, 0xce, 0x00, 0xbb, 0x01, + 0x2e, 0xc1, 0x1b, 0xb0, 0x02, 0xcd, 0x00, 0xbf, + 0xd8, 0x23, 0xd4, 0x03, 0xbc, 0xc3, 0x7f, 0x00, + 0xdf, 0x00, 0x22, 0x80, 0x0b, 0xb0, 0x02, 0xf2, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, + 0x4c, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0xb0, + 0x02, 0x0e, 0x40, 0xb3, 0x00, 0x28, 0xc0, 0x09, + 0x30, 0x02, 0x2c, 0x00, 0xa2, 0x00, 0x28, 0xc0, + 0x08, 0x00, 0x02, 0x20, 0x00, 0xb3, 0x00, 0x20, + 0xa0, 0x0b, 0x0c, 0x00, 0x8e, 0x04, 0xed, 0x09, + 0x00, 0xfa, 0x00, 0x93, 0x00, 0x2c, 0x00, 0x0b, + 0x08, 0x02, 0x4c, 0x00, 0x93, 0xc0, 0x20, 0xd0, + 0x0b, 0x20, 0x02, 0x0d, 0x40, 0x83, 0xb0, 0x2c, + 0x80, 0x0b, 0x30, 0x02, 0xf8, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x01, 0x1e, 0x00, 0x87, + 0x80, 0x2d, 0xe4, 0x0b, 0x68, 0x02, 0x1e, 0x00, + 0x97, 0x80, 0x21, 0x60, 0x48, 0x38, 0x02, 0x1e, + 0x00, 0xb6, 0x80, 0x2d, 0xa1, 0x08, 0x48, 0x02, + 0xd2, 0x01, 0xb7, 0x80, 0x23, 0xa0, 0x1b, 0x78, + 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0x20, 0x0b, + 0x48, 0x12, 0xde, 0x00, 0xb7, 0x80, 0x21, 0xe0, + 0x0b, 0x6d, 0x02, 0xde, 0x00, 0x93, 0x80, 0x0d, + 0xe0, 0x03, 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x08, 0x20, 0x42, 0xc1, + 0x00, 0x3c, 0xc4, 0x0f, 0x30, 0x03, 0x0c, 0x80, + 0xf3, 0x00, 0x3a, 0xc0, 0x0e, 0x30, 0x0b, 0x04, + 0x00, 0xe0, 0x10, 0x38, 0xc8, 0x2e, 0x01, 0x43, + 0x04, 0x00, 0xfb, 0x20, 0x30, 0x40, 0x0f, 0x30, + 0x93, 0xcc, 0x20, 0xf3, 0x10, 0x2c, 0xc0, 0x0b, + 0x31, 0x03, 0xcc, 0x00, 0xf3, 0x10, 0x74, 0xc0, + 0x0f, 0xb1, 0x03, 0xac, 0x80, 0xc3, 0x10, 0x3c, + 0x90, 0x0f, 0x30, 0x03, 0xd2, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xff, + 0x00, 0x3f, 0xd6, 0x0f, 0xf1, 0x07, 0xfc, 0x00, + 0xff, 0x10, 0x3f, 0xc4, 0x0f, 0xf1, 0x03, 0xfc, + 0x00, 0xfe, 0x10, 0x3f, 0xc0, 0x46, 0xc0, 0x03, + 0xf4, 0x40, 0xff, 0x40, 0xbd, 0x40, 0x4e, 0xf0, + 0x01, 0xfc, 0x40, 0xff, 0x02, 0x1f, 0xc0, 0x0f, + 0xf0, 0x03, 0xf4, 0x04, 0xff, 0x08, 0x3b, 0xc4, + 0x4f, 0xf1, 0x03, 0x7d, 0x00, 0xff, 0x00, 0x33, + 0xc0, 0x0f, 0xf0, 0x03, 0xd0, 0x02, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x05, 0xec, 0x00, 0xfb, + 0x00, 0xed, 0x09, 0x00, 0xfb, 0x00, 0x3e, 0xe8, + 0x0e, 0x90, 0x03, 0xed, 0x20, 0xf9, 0x00, 0x3e, + 0xc0, 0x0d, 0xb6, 0x03, 0x6c, 0x00, 0xfb, 0x00, + 0x3e, 0x40, 0x2c, 0x80, 0x03, 0xa6, 0x02, 0xcb, + 0x20, 0x7e, 0xe0, 0x0c, 0x80, 0x03, 0xc4, 0x08, + 0xcb, 0x04, 0x3e, 0xc0, 0x0e, 0xb0, 0x13, 0xec, + 0x10, 0xcb, 0x20, 0x3e, 0xd0, 0x0c, 0xb8, 0x03, + 0xaf, 0x42, 0xcb, 0x00, 0x3e, 0x80, 0x0f, 0xb0, + 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x0d, 0xc8, + 0x08, 0x70, 0x02, 0xdd, 0x80, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x75, 0x03, 0x9c, 0x00, 0xb6, 0x00, + 0x2f, 0xc0, 0x0a, 0x50, 0x02, 0xdc, 0x00, 0x87, + 0x40, 0x2f, 0xc1, 0x28, 0x70, 0x21, 0xdc, 0x00, + 0xa6, 0x03, 0x2d, 0xc0, 0x08, 0x70, 0x02, 0xd8, + 0x00, 0xa7, 0x10, 0x27, 0xd2, 0x0a, 0x70, 0x02, + 0x8c, 0x80, 0x87, 0x30, 0x2d, 0x40, 0x0b, 0x70, + 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0a, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x88, 0x6d, + 0xe0, 0x09, 0x78, 0x02, 0xde, 0x00, 0xb6, 0xc0, + 0x2d, 0xe0, 0x08, 0x48, 0x02, 0x9e, 0x04, 0x87, + 0x81, 0x29, 0xe0, 0x09, 0x78, 0x06, 0xfe, 0x00, + 0xa5, 0x80, 0x2c, 0xe0, 0x0a, 0x78, 0x82, 0xde, + 0x24, 0x87, 0xa0, 0x2d, 0xe8, 0x09, 0xf8, 0x02, + 0x5e, 0x80, 0x87, 0x90, 0x2d, 0xe0, 0x0b, 0x78, + 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x10, 0xc2, 0x40, 0xb1, 0x80, 0x2c, 0xc0, + 0x08, 0x00, 0x02, 0xcc, 0x00, 0xb1, 0x00, 0x2c, + 0x44, 0x8b, 0xb0, 0x02, 0x84, 0x20, 0xb1, 0xc0, + 0x2c, 0x10, 0x18, 0x30, 0x02, 0xcd, 0x20, 0x83, + 0x00, 0x2c, 0xf6, 0x89, 0x3b, 0x02, 0x8e, 0x00, + 0xa3, 0x90, 0x24, 0xc8, 0xed, 0x09, 0x00, 0xfc, + 0x00, 0x08, 0x38, 0x82, 0xcd, 0x24, 0xa3, 0x00, + 0x24, 0xc0, 0x0a, 0x30, 0x02, 0xcc, 0x00, 0x83, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xd2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xb8, + 0x00, 0xfa, 0xa0, 0x7e, 0x80, 0x0e, 0xe8, 0x03, + 0xe8, 0x05, 0xfe, 0xc0, 0x3f, 0xb0, 0x0d, 0xa0, + 0x03, 0x7a, 0x00, 0xfe, 0xc0, 0x3f, 0x80, 0x0c, + 0xe6, 0x03, 0xb8, 0x80, 0xca, 0x02, 0x3f, 0xb0, + 0x0d, 0xec, 0x02, 0xda, 0x20, 0xee, 0x80, 0x0f, + 0x88, 0x0a, 0xec, 0x03, 0xfb, 0x00, 0xca, 0x00, + 0x3e, 0x80, 0x0c, 0xe4, 0x03, 0x68, 0x00, 0xca, + 0x00, 0x3f, 0xb0, 0x0f, 0xa0, 0x03, 0xfa, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x10, 0x0f, 0x89, 0x03, + 0xe1, 0x11, 0xf8, 0x80, 0x0e, 0x20, 0x0f, 0x80, + 0x13, 0x60, 0x40, 0xf8, 0x21, 0x3e, 0x02, 0x0f, + 0x88, 0x03, 0xe0, 0x00, 0xf8, 0x41, 0x3e, 0x10, + 0x0e, 0x80, 0x02, 0xe0, 0x20, 0xf8, 0x40, 0x3c, + 0x00, 0x8f, 0x84, 0x03, 0xe1, 0x00, 0xf8, 0x00, + 0x3c, 0x10, 0x1f, 0x8c, 0x12, 0xa1, 0x00, 0xf8, + 0x44, 0x3c, 0x0c, 0x4f, 0x80, 0x03, 0xd2, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, + 0x20, 0xc9, 0x00, 0x32, 0x71, 0x0f, 0x90, 0x13, + 0xe5, 0x09, 0xf9, 0x00, 0x2e, 0x40, 0x4f, 0x90, + 0x03, 0x24, 0x00, 0xf9, 0x01, 0x32, 0x40, 0x0a, + 0x9a, 0x03, 0x64, 0x0c, 0xf1, 0x00, 0x32, 0x40, + 0x0d, 0x91, 0x03, 0xa4, 0x00, 0xf1, 0x18, 0x32, + 0x40, 0x0e, 0x90, 0x03, 0xc7, 0x00, 0xc9, 0x00, + 0x1e, 0x40, 0x6c, 0x92, 0x43, 0x66, 0x40, 0xf9, + 0xc0, 0x7a, 0x40, 0x0c, 0x90, 0x03, 0xc2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, + 0x00, 0x89, 0x00, 0x36, 0x70, 0x0b, 0x90, 0xed, + 0x09, 0x00, 0xfd, 0x00, 0x02, 0xe7, 0x20, 0xf9, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, + 0xb9, 0x02, 0x00, 0x40, 0x0e, 0x90, 0x22, 0xe4, + 0x00, 0xb9, 0x10, 0x26, 0x42, 0x0e, 0x14, 0x32, + 0x25, 0x02, 0xd9, 0x80, 0x3e, 0x41, 0x08, 0x90, + 0x82, 0xe5, 0x01, 0x79, 0x40, 0x2e, 0x40, 0x0a, + 0x92, 0x12, 0xe5, 0x90, 0xb9, 0x40, 0x2e, 0x40, + 0x0f, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x01, 0x0c, 0x00, 0x91, 0x00, + 0x26, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x0a, 0x24, 0x00, + 0xb1, 0x00, 0x2a, 0x40, 0x08, 0x90, 0x06, 0xe4, + 0x00, 0xb9, 0x42, 0x66, 0x40, 0x0b, 0x90, 0x00, + 0xa4, 0x20, 0xb9, 0x00, 0x2a, 0x40, 0x0a, 0xb1, + 0x02, 0x64, 0x10, 0x89, 0x60, 0x2e, 0x70, 0x08, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2a, 0x40, + 0x89, 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x05, 0x02, 0x91, 0x40, + 0x2c, 0x40, 0x0b, 0x14, 0x02, 0xc4, 0x10, 0xb1, + 0x40, 0x2c, 0x50, 0x0b, 0x14, 0x02, 0x05, 0x00, + 0xb1, 0x40, 0xaa, 0x50, 0x0a, 0x30, 0x02, 0xc5, + 0x00, 0xb1, 0x28, 0x24, 0x40, 0x1a, 0x34, 0x02, + 0x04, 0x00, 0x93, 0x42, 0x6c, 0x50, 0x08, 0x14, + 0x02, 0xcc, 0x00, 0xa1, 0x00, 0x2c, 0x50, 0x08, + 0x14, 0x02, 0xc5, 0x00, 0xb1, 0x40, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb8, 0x0d, 0x60, 0x00, 0xd8, 0x00, + 0xb6, 0x80, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xb8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x20, 0x08, + 0xb8, 0x02, 0x3a, 0x01, 0x08, 0x80, 0x02, 0xc0, + 0x08, 0x78, 0x20, 0x32, 0x00, 0x0b, 0x80, 0x03, + 0xa0, 0x02, 0xf8, 0x00, 0x3a, 0x00, 0x0e, 0x80, + 0x03, 0x60, 0xed, 0x09, 0x00, 0xfe, 0x00, 0x00, + 0x88, 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0x60, + 0x00, 0xfa, 0x00, 0x3a, 0x00, 0x0d, 0x80, 0x03, + 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x1d, 0xf4, 0x00, 0xed, 0x00, 0x30, 0x50, 0x4f, + 0xf0, 0x13, 0xe5, 0x04, 0xed, 0x00, 0x3f, 0x40, + 0x0f, 0x94, 0x42, 0xf4, 0x04, 0xfd, 0x00, 0x37, + 0x40, 0x0e, 0xd0, 0x03, 0xf5, 0x00, 0xf9, 0x28, + 0xbb, 0x4a, 0x0f, 0xd4, 0x03, 0xfc, 0x00, 0xfd, + 0x40, 0x7b, 0x50, 0x0f, 0xd0, 0x03, 0xdd, 0x10, + 0xf9, 0x40, 0x3e, 0x50, 0x0f, 0x50, 0x43, 0xe5, + 0x00, 0xf9, 0x40, 0x3f, 0x50, 0x0e, 0x90, 0x03, + 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x05, 0xe4, 0x40, 0xf9, 0x00, 0x3f, 0x40, 0x4f, + 0x91, 0x03, 0xf4, 0x80, 0xf9, 0x00, 0x3e, 0x44, + 0x0f, 0x90, 0x03, 0x24, 0x10, 0xe9, 0x10, 0x32, + 0xc0, 0x0f, 0xd0, 0x03, 0xe4, 0xe0, 0xfd, 0x30, + 0x3f, 0x40, 0x8f, 0xd1, 0x03, 0x14, 0x00, 0xcd, + 0x28, 0x36, 0x4c, 0x0f, 0xd0, 0x03, 0xf4, 0x00, + 0xe5, 0x00, 0x37, 0x49, 0x07, 0x51, 0x63, 0xf4, + 0x80, 0xed, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x10, 0xe0, 0x80, 0xb8, 0x08, 0x2e, 0x00, 0x18, + 0x80, 0x02, 0xe0, 0x04, 0xb8, 0x24, 0x2e, 0x08, + 0x0b, 0x84, 0xc2, 0x08, 0x20, 0x88, 0x00, 0x36, + 0x0a, 0x0b, 0x80, 0x42, 0xe8, 0x80, 0xb8, 0x30, + 0x2e, 0x02, 0x0b, 0xa1, 0x02, 0xa0, 0x10, 0xa0, + 0x20, 0x2e, 0x0c, 0x0b, 0xa0, 0x82, 0xe0, 0x00, + 0x88, 0x10, 0x22, 0x08, 0x0e, 0x82, 0x02, 0xe0, + 0x60, 0xb8, 0x48, 0x2e, 0x00, 0x0b, 0x80, 0x02, + 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x05, 0xc4, 0x80, 0xb1, 0x20, 0x2c, 0x44, 0x0a, + 0x10, 0x02, 0xc4, 0x40, 0xb1, 0xed, 0x09, 0x00, + 0xff, 0x00, 0x2a, 0x2c, 0x48, 0x0b, 0x13, 0x02, + 0xe4, 0x00, 0xa9, 0x04, 0x20, 0x48, 0x0b, 0x10, + 0x02, 0x84, 0x80, 0xb1, 0x20, 0x2c, 0x48, 0x0b, + 0x10, 0x0a, 0x24, 0x04, 0x81, 0x2c, 0x28, 0x68, + 0x0b, 0x12, 0x02, 0xc4, 0x40, 0xa1, 0x00, 0x28, + 0x4e, 0x0b, 0x12, 0x02, 0xc4, 0x80, 0xb1, 0x30, + 0x2c, 0x44, 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, 0x80, + 0xb9, 0x00, 0x2e, 0x40, 0x0a, 0x90, 0x02, 0xe4, + 0x10, 0xb9, 0x42, 0x2e, 0x44, 0x0b, 0x90, 0x02, + 0x64, 0x50, 0x89, 0x20, 0x26, 0x51, 0x03, 0xb0, + 0x02, 0xe4, 0x00, 0xb9, 0x01, 0x2e, 0x42, 0x0b, + 0x90, 0x02, 0xa4, 0x00, 0xa9, 0x41, 0x2e, 0x44, + 0x0b, 0x92, 0x02, 0xe4, 0x04, 0xa9, 0x00, 0x6a, + 0x40, 0x0a, 0xb0, 0x80, 0xe4, 0x00, 0xb9, 0x01, + 0x2e, 0x58, 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe5, 0x80, + 0xf9, 0x90, 0x3e, 0x40, 0x8f, 0x9c, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x1e, 0x68, 0x0f, 0x90, 0x03, + 0x64, 0x04, 0xe1, 0x09, 0x32, 0x60, 0x0f, 0x90, + 0x03, 0xa5, 0x00, 0xf9, 0x00, 0x3e, 0x70, 0x4f, + 0x9c, 0x43, 0x04, 0x00, 0x89, 0xc0, 0x32, 0x40, + 0x0f, 0x90, 0x07, 0xe7, 0x00, 0xa9, 0x00, 0xba, + 0x40, 0x4f, 0x9c, 0x03, 0xe4, 0x00, 0xe9, 0x04, + 0x3e, 0x60, 0x0f, 0x90, 0x03, 0xe8, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, + 0xf9, 0x04, 0x3e, 0x43, 0x8d, 0x92, 0x03, 0xe4, + 0x00, 0x59, 0xa4, 0x3e, 0x60, 0x0b, 0x10, 0x43, + 0xa4, 0x00, 0xe9, 0x00, 0x3e, 0x48, 0x0f, 0x92, + 0x03, 0xe5, 0x00, 0xf9, 0x00, 0x3e, 0x64, 0x8b, + 0x9a, 0x83, 0xe7, 0x00, 0xf9, 0x90, 0x2e, 0x40, + 0x0f, 0x90, 0x01, 0xe6, 0x40, 0x59, 0x00, 0x16, + 0xed, 0x09, 0x00, 0x00, 0x01, 0x40, 0x0e, 0x94, + 0x83, 0xe4, 0x00, 0xf9, 0x08, 0x3e, 0x60, 0x0f, + 0x90, 0x03, 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0e, 0x84, 0x03, 0xe2, 0x00, 0xc8, 0x00, + 0x32, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x40, 0x32, 0x10, 0x0f, 0x89, 0x43, 0xe1, 0x04, + 0xe8, 0x0c, 0x3e, 0x10, 0x4f, 0x84, 0x03, 0xe3, + 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0d, 0x82, 0x03, + 0xe3, 0x00, 0xc0, 0x00, 0xb6, 0x02, 0x0f, 0x80, + 0x03, 0xa0, 0x20, 0xf8, 0x01, 0x3e, 0x11, 0x0f, + 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x05, 0x28, 0x00, 0xba, 0x00, 0x2d, + 0x80, 0x03, 0xa0, 0x02, 0xf9, 0x00, 0x8a, 0x00, + 0x22, 0x80, 0x0b, 0xa0, 0x03, 0x88, 0x08, 0x8a, + 0x00, 0x2a, 0x80, 0x03, 0xe4, 0x02, 0xe8, 0x00, + 0xbe, 0x40, 0x2f, 0x80, 0x0b, 0xe2, 0x02, 0xfb, + 0x20, 0x8e, 0x10, 0x2a, 0x80, 0x08, 0xe0, 0x83, + 0x19, 0x00, 0xde, 0x24, 0x03, 0xa2, 0x8b, 0xe4, + 0x00, 0x39, 0x80, 0xbe, 0xc0, 0x2e, 0x80, 0x0b, + 0xa0, 0x02, 0xca, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0x24, 0x0b, 0x30, 0x02, 0xc6, 0x00, 0x83, 0x00, + 0x28, 0xc0, 0x09, 0x30, 0x22, 0x0c, 0x00, 0x83, + 0x00, 0x28, 0xc0, 0x09, 0x38, 0x12, 0xcc, 0x08, + 0xa3, 0x40, 0x24, 0xe9, 0x03, 0xb0, 0x02, 0xce, + 0x00, 0xa3, 0x50, 0x20, 0xc0, 0x08, 0x3c, 0x02, + 0x8c, 0x00, 0xa3, 0xe0, 0x20, 0xf0, 0x0b, 0x30, + 0x02, 0x8c, 0x00, 0xb3, 0x40, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x8b, 0x70, 0x22, 0xdf, 0x00, 0x87, 0xa0, + 0x29, 0xcc, 0x0b, 0xed, 0x09, 0x00, 0x01, 0x01, + 0x7a, 0x22, 0x1c, 0x02, 0x8f, 0x00, 0x29, 0xc8, + 0x0b, 0x40, 0x02, 0xdc, 0xc0, 0xb7, 0x02, 0x2d, + 0xc3, 0x0b, 0x70, 0x06, 0xdc, 0x00, 0x87, 0x80, + 0x29, 0xe0, 0x29, 0xf8, 0x42, 0x1c, 0x20, 0xb7, + 0x00, 0x21, 0x80, 0x4b, 0xc8, 0x02, 0x94, 0x00, + 0xb7, 0x08, 0x2d, 0xc0, 0x8b, 0x70, 0x02, 0xe8, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, + 0x1e, 0x40, 0xf7, 0xb2, 0x6d, 0xe0, 0xcf, 0x7a, + 0x03, 0xce, 0x02, 0xcf, 0xe0, 0xb9, 0xe8, 0x0f, + 0x72, 0x03, 0x9e, 0x00, 0xf7, 0xe0, 0x39, 0xe5, + 0x1f, 0x48, 0x23, 0xde, 0x20, 0xe7, 0x80, 0x05, + 0xe0, 0x03, 0x68, 0x03, 0xde, 0x04, 0xe5, 0x80, + 0x73, 0xe8, 0x0c, 0x68, 0x23, 0x9e, 0x02, 0xe7, + 0x80, 0x31, 0x60, 0x0f, 0x48, 0x03, 0x96, 0x00, + 0xf4, 0x80, 0x2d, 0xe0, 0x0f, 0x78, 0x03, 0xea, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, + 0xad, 0xc0, 0xfb, 0x20, 0x2e, 0x40, 0x0f, 0xb6, + 0x83, 0xec, 0x09, 0xfb, 0x20, 0x36, 0xc8, 0x0f, + 0xb5, 0x43, 0xac, 0x08, 0xf3, 0x00, 0xb6, 0xc8, + 0x0d, 0xa0, 0x03, 0xed, 0x00, 0xd8, 0x00, 0x3e, + 0xc0, 0x0f, 0x80, 0x03, 0xec, 0x04, 0xe9, 0x01, + 0x3e, 0xd4, 0x4e, 0x20, 0x23, 0x88, 0x10, 0xc8, + 0x00, 0x3a, 0x00, 0x0f, 0x80, 0x23, 0x64, 0x00, + 0xf9, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xc2, + 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0xfe, 0x00, 0xef, 0x98, 0x33, 0xe0, 0x2c, 0xf8, + 0x81, 0xbe, 0x10, 0xef, 0xc4, 0x3f, 0xf4, 0x4f, + 0xf4, 0x43, 0xff, 0x20, 0xcf, 0xc0, 0x3f, 0xe6, + 0x4f, 0xc8, 0x03, 0xbe, 0x40, 0xdf, 0x90, 0x3f, + 0xe5, 0x0f, 0xf8, 0x03, 0x9e, 0x00, 0xce, 0x80, + 0x33, 0xf4, 0x08, 0xd9, 0x03, 0x3c, 0x40, 0xe7, + 0x90, 0x3b, 0x20, 0x0f, 0xe8, 0x03, 0xed, 0x09, + 0x00, 0x02, 0x01, 0x36, 0x40, 0xff, 0x80, 0x33, + 0xe4, 0x0f, 0xf8, 0x01, 0xc0, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, 0x8f, + 0x08, 0xa1, 0xc0, 0x08, 0x70, 0x82, 0x1c, 0x40, + 0x87, 0x20, 0x2d, 0xc1, 0x0b, 0x70, 0x03, 0xdc, + 0x00, 0x97, 0x21, 0x3d, 0xc5, 0x0b, 0x41, 0x03, + 0xdc, 0x00, 0xf7, 0x00, 0x2d, 0x44, 0x0e, 0x60, + 0x02, 0x14, 0x00, 0xfe, 0x20, 0x35, 0xcc, 0x08, + 0xf3, 0x03, 0x5c, 0xc0, 0xb7, 0x34, 0x35, 0x00, + 0x0b, 0x40, 0x02, 0x14, 0x00, 0xbd, 0x40, 0x29, + 0xc0, 0x0b, 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xb7, + 0x04, 0x20, 0x80, 0x08, 0xf0, 0x02, 0xd4, 0x00, + 0xb7, 0x01, 0x2d, 0xc0, 0x01, 0x70, 0x02, 0xfc, + 0x00, 0x97, 0x01, 0x2d, 0xc0, 0x03, 0x44, 0x02, + 0x9c, 0x15, 0xb7, 0x01, 0x2d, 0x80, 0x0b, 0x20, + 0x02, 0xb8, 0x00, 0x97, 0x09, 0x24, 0xc1, 0x19, + 0x70, 0x02, 0x1c, 0x48, 0xa7, 0x00, 0x65, 0x00, + 0x0b, 0xc1, 0x02, 0x50, 0x01, 0xb7, 0x00, 0x21, + 0xc2, 0x1b, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x14, 0x4f, 0x00, 0x93, + 0x80, 0x20, 0xc0, 0x08, 0x38, 0x82, 0x4c, 0x00, + 0x93, 0x20, 0x2c, 0xe2, 0x89, 0x30, 0x02, 0xcc, + 0x00, 0x9b, 0xd0, 0x2c, 0xe8, 0x4b, 0x01, 0x02, + 0xcc, 0xc0, 0xb0, 0x00, 0x2c, 0x00, 0x1a, 0x00, + 0x22, 0x80, 0x00, 0xb3, 0x60, 0x24, 0xc2, 0x58, + 0x3c, 0x02, 0x49, 0x00, 0xb0, 0x00, 0x20, 0x00, + 0x0b, 0x0c, 0x00, 0x40, 0x00, 0xb1, 0x02, 0x28, + 0xd2, 0x0b, 0x30, 0x02, 0xc8, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x15, 0x9e, 0x40, 0xff, + 0x80, 0x32, 0xc0, 0x0c, 0x74, 0x23, 0xec, 0x00, + 0xf7, 0xc0, 0x3d, 0xc2, 0x0f, 0xf0, 0x03, 0xfd, + 0x00, 0xed, 0x09, 0x00, 0x03, 0x01, 0xcf, 0x00, + 0x3d, 0xd2, 0x0f, 0x8c, 0x03, 0xbd, 0x00, 0x99, + 0x00, 0x3e, 0x40, 0x0b, 0xb0, 0x02, 0xaf, 0x64, + 0x9b, 0x40, 0x37, 0xf0, 0x0d, 0xb2, 0x03, 0x2d, + 0x20, 0xeb, 0x00, 0x26, 0x40, 0x0f, 0x84, 0x02, + 0x64, 0x19, 0xfb, 0x00, 0x32, 0xf0, 0x0f, 0xb0, + 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0xec, 0x48, 0xeb, 0x00, 0x3e, 0x90, + 0x0f, 0xb0, 0x03, 0x25, 0x00, 0xeb, 0x10, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xae, 0x20, 0xeb, 0x00, + 0x3a, 0xc0, 0x0f, 0x84, 0x03, 0xac, 0x00, 0xc9, + 0x41, 0x3e, 0x10, 0x0f, 0xb1, 0x03, 0x69, 0x00, + 0xf3, 0x40, 0x3e, 0xc4, 0x0f, 0xb4, 0x03, 0xcc, + 0x20, 0xfb, 0x40, 0xbe, 0x00, 0x0f, 0x85, 0x0b, + 0xa0, 0x01, 0xf8, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x10, 0xfc, 0x00, 0xdf, 0x00, 0x35, 0xe4, + 0x28, 0xf0, 0x03, 0x7c, 0x00, 0xff, 0x00, 0x37, + 0xc0, 0x4d, 0xf0, 0x03, 0x3c, 0x00, 0xef, 0x08, + 0x33, 0xc0, 0x0c, 0xc4, 0x03, 0xdc, 0x00, 0xcd, + 0x00, 0x3f, 0x40, 0x0c, 0x60, 0x8b, 0x3e, 0x80, + 0xcf, 0xa1, 0x31, 0xc0, 0x0d, 0xf0, 0x83, 0x3e, + 0x00, 0xcf, 0x80, 0x3d, 0x00, 0x0c, 0xc0, 0x83, + 0xd4, 0x0c, 0x4e, 0x81, 0x31, 0xc0, 0x4c, 0xf0, + 0x03, 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x6c, 0x00, 0x83, 0x04, 0x22, 0xf2, + 0x08, 0xb0, 0x03, 0x6e, 0x20, 0xbb, 0x00, 0x22, + 0xc0, 0x0a, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, + 0x22, 0xc0, 0x0a, 0x8c, 0x00, 0xec, 0x00, 0x88, + 0xa0, 0x2c, 0x28, 0x0a, 0x88, 0x02, 0x09, 0x20, + 0xab, 0xe0, 0x36, 0xc0, 0x09, 0xb0, 0x83, 0x6b, + 0x84, 0xd8, 0xb0, 0x2e, 0x20, 0x88, 0x8c, 0x03, + 0xe3, 0x00, 0x88, 0x80, 0xed, 0x09, 0x00, 0x04, + 0x01, 0x36, 0xc0, 0x0d, 0xb0, 0x02, 0xe0, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, + 0x00, 0xbb, 0x02, 0x26, 0x40, 0x0a, 0xb0, 0x02, + 0xec, 0x80, 0xbb, 0x00, 0x26, 0xc0, 0x0a, 0x30, + 0x02, 0xec, 0x00, 0xab, 0x00, 0x2a, 0xc0, 0x08, + 0xa0, 0x02, 0xec, 0x02, 0x88, 0x80, 0x2e, 0x60, + 0x08, 0x91, 0x00, 0xac, 0x00, 0x8b, 0x00, 0x22, + 0xc0, 0x08, 0x10, 0x02, 0x68, 0x80, 0x88, 0x00, + 0x2e, 0x30, 0x08, 0x88, 0x02, 0xe7, 0x00, 0xa2, + 0x10, 0x22, 0xc0, 0x08, 0xb0, 0x02, 0xe0, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x2c, + 0x01, 0x8b, 0x00, 0x20, 0xc0, 0x0a, 0xb0, 0x02, + 0xcc, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0xaa, 0xc0, 0x0a, + 0x00, 0x02, 0xcc, 0x00, 0x80, 0x04, 0x2e, 0x00, + 0x0a, 0x00, 0x02, 0x28, 0x10, 0xa3, 0x00, 0x24, + 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x08, 0x90, 0x00, + 0x6c, 0x00, 0x28, 0x00, 0x02, 0xc0, 0x00, 0xa0, + 0x01, 0x24, 0xc0, 0x09, 0x30, 0x02, 0xc2, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x7c, + 0x00, 0xff, 0x00, 0x36, 0xc0, 0x0e, 0xf0, 0x03, + 0xec, 0x00, 0xff, 0x00, 0x37, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xef, 0x00, 0x3b, 0xc0, 0x0c, + 0x80, 0x02, 0xfc, 0x11, 0xc8, 0x00, 0x2e, 0x00, + 0x88, 0x80, 0x03, 0xa8, 0x00, 0xcb, 0x00, 0x23, + 0xc0, 0x0c, 0xb0, 0x22, 0x60, 0x00, 0x88, 0x02, + 0x3e, 0x01, 0x0c, 0x80, 0x07, 0xe0, 0x10, 0xea, + 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0xc0, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xdc, + 0x00, 0x7f, 0x00, 0x3f, 0x00, 0x0d, 0x70, 0x03, + 0x10, 0x00, 0xff, 0x01, 0x3f, 0xc1, 0x0e, 0xf0, + 0x03, 0x1c, 0x00, 0xff, 0x01, 0x37, 0xc0, 0xed, + 0x09, 0x00, 0x05, 0x01, 0x0f, 0xe0, 0x03, 0xfc, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, + 0xf8, 0x04, 0xff, 0x00, 0x3f, 0xc0, 0x0c, 0xf0, + 0x03, 0x70, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, + 0x40, 0x03, 0xb0, 0x00, 0xdc, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x05, 0xfc, 0x00, 0xfc, 0x22, + 0x3d, 0x40, 0x8c, 0xc0, 0x03, 0x98, 0x00, 0xd7, + 0x00, 0x33, 0x00, 0x0c, 0xc0, 0x5b, 0x75, 0x00, + 0xec, 0x00, 0x33, 0x80, 0x28, 0xe0, 0x03, 0xb8, + 0x00, 0xf7, 0x00, 0x31, 0x00, 0x2c, 0xd0, 0x03, + 0x38, 0x00, 0xcc, 0x00, 0x31, 0x01, 0x0f, 0xe0, + 0x03, 0x3c, 0x00, 0xcc, 0x00, 0x3d, 0x40, 0x0f, + 0xf0, 0x03, 0x30, 0xc4, 0x8c, 0x20, 0xb3, 0x0c, + 0x2c, 0xc3, 0x53, 0x30, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x10, 0xec, 0x00, 0xb8, 0x10, + 0x2e, 0xc0, 0x08, 0xa0, 0x42, 0x28, 0x00, 0xbb, + 0x00, 0x22, 0x00, 0x08, 0x80, 0x42, 0x25, 0x00, + 0xa8, 0x00, 0x22, 0x40, 0x08, 0xb0, 0x12, 0x2c, + 0x00, 0xbb, 0x00, 0x22, 0x80, 0x08, 0x90, 0x0a, + 0x24, 0x00, 0x8a, 0x00, 0x22, 0x80, 0x0b, 0x80, + 0x13, 0x6c, 0x00, 0x88, 0x00, 0x2e, 0x4a, 0x8b, + 0xb0, 0x0a, 0xa1, 0x40, 0x82, 0x30, 0x22, 0x58, + 0x08, 0x85, 0x02, 0x20, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x05, 0xcc, 0x00, 0xb1, 0x00, + 0x2e, 0x00, 0x28, 0x10, 0x22, 0x80, 0x04, 0xb3, + 0x00, 0x62, 0x00, 0x2a, 0x00, 0x02, 0x4c, 0xc4, + 0xa0, 0x01, 0x26, 0x40, 0x08, 0xb0, 0x02, 0xcc, + 0x00, 0xba, 0x00, 0xae, 0xc0, 0x8b, 0x10, 0x02, + 0x48, 0x02, 0x82, 0x00, 0xa4, 0x80, 0x0b, 0x20, + 0x02, 0x0c, 0x00, 0x80, 0x00, 0x2c, 0x40, 0x0a, + 0x30, 0x0a, 0xc0, 0x00, 0xa0, 0x08, 0x28, 0x04, + 0x08, 0x02, 0xed, 0x09, 0x00, 0x06, 0x01, 0x22, + 0xa2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x15, 0xac, 0x10, 0xb9, 0x00, 0x2e, 0x82, 0x08, + 0xb0, 0xa2, 0xa8, 0x00, 0xbb, 0x01, 0xa2, 0x00, + 0x0a, 0x82, 0x02, 0x6c, 0x00, 0xa8, 0x51, 0xa6, + 0xd0, 0x08, 0xb0, 0x00, 0x6c, 0x00, 0xbb, 0x50, + 0x26, 0x81, 0x0b, 0x90, 0x02, 0x60, 0x40, 0x8a, + 0x00, 0x26, 0xc0, 0x0b, 0xa0, 0x02, 0x6c, 0x00, + 0x8a, 0x08, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe8, + 0x08, 0xa8, 0x02, 0x22, 0x40, 0x0a, 0x16, 0x02, + 0xb0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xd1, + 0x15, 0xec, 0x00, 0xf8, 0x60, 0x3c, 0xc0, 0x8c, + 0x14, 0x03, 0xa9, 0x00, 0xf3, 0x80, 0x32, 0x34, + 0x0e, 0x80, 0x0b, 0x6c, 0x02, 0xe0, 0x00, 0x36, + 0xf0, 0x0c, 0xb4, 0x83, 0xec, 0x04, 0xf1, 0x40, + 0xb6, 0xb6, 0x0b, 0x9c, 0xa3, 0x6a, 0x00, 0xc2, + 0x00, 0x36, 0x12, 0x0f, 0x28, 0x03, 0x0c, 0x00, + 0xca, 0x40, 0x7e, 0x66, 0x0f, 0xb4, 0x03, 0xec, + 0x00, 0xe9, 0x40, 0x3a, 0xb2, 0x0c, 0x8c, 0x0b, + 0x90, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x01, 0xbc, 0x00, 0xfe, 0x00, 0x3f, 0xc0, 0x0b, + 0xd0, 0x03, 0x7c, 0x00, 0xff, 0xc1, 0x3f, 0x60, + 0x8d, 0xf8, 0x0b, 0xbe, 0x42, 0xfe, 0x80, 0x3b, + 0x70, 0x0f, 0xfa, 0x43, 0xbe, 0x40, 0xfd, 0x80, + 0xbb, 0x80, 0x0c, 0xec, 0x03, 0xb4, 0x08, 0xff, + 0x90, 0x3b, 0xe4, 0x0f, 0xec, 0x03, 0xfc, 0x02, + 0xfe, 0xa0, 0x3f, 0x41, 0x0f, 0xc0, 0x02, 0x94, + 0x00, 0xd7, 0x20, 0x35, 0x66, 0x0d, 0xb0, 0x13, + 0x78, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x10, 0xac, 0x00, 0xf8, 0x40, 0x32, 0xd2, 0x0c, + 0xb4, 0x83, 0x29, 0x80, 0xcb, 0x30, 0x3a, 0x10, + 0x0d, 0xb0, 0x83, 0xea, 0x00, 0xfa, 0x00, 0x3e, + 0x50, 0x2c, 0xb6, 0x03, 0xae, 0xed, 0x09, 0x00, + 0x07, 0x01, 0x00, 0xc9, 0x60, 0x32, 0xd1, 0x0c, + 0xa4, 0x43, 0xa9, 0x00, 0xca, 0x10, 0x3e, 0x94, + 0x0c, 0xb0, 0x03, 0xec, 0x80, 0xfa, 0x00, 0x3e, + 0x40, 0x0c, 0xb6, 0x03, 0xa8, 0x00, 0xe9, 0x42, + 0x32, 0x80, 0x1d, 0xa6, 0x02, 0x10, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xd8, 0x05, 0x2c, 0x00, + 0xba, 0x00, 0x22, 0xc0, 0x08, 0xb0, 0x02, 0x28, + 0x00, 0xab, 0xc0, 0x20, 0x72, 0x0b, 0x34, 0x02, + 0x69, 0x00, 0xbb, 0x14, 0x2c, 0xf8, 0x08, 0x34, + 0x02, 0x2e, 0x00, 0x89, 0x48, 0x20, 0xd0, 0x0a, + 0x25, 0x02, 0xc4, 0x00, 0xab, 0x00, 0x2e, 0xc0, + 0x28, 0xb8, 0x42, 0xee, 0x00, 0xba, 0x52, 0x2e, + 0x40, 0x00, 0xbc, 0x02, 0x28, 0x00, 0xa9, 0x8a, + 0x22, 0x72, 0x08, 0xb6, 0x00, 0xb2, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, 0x04, + 0xb0, 0x02, 0x20, 0x50, 0x08, 0x1c, 0x08, 0x0b, + 0x00, 0x83, 0x00, 0x24, 0x32, 0x09, 0x00, 0x02, + 0xec, 0x10, 0xb0, 0x00, 0x2c, 0x88, 0x08, 0x34, + 0x02, 0x88, 0x00, 0x83, 0xc0, 0x20, 0x92, 0x8a, + 0x10, 0x02, 0x89, 0x80, 0xa2, 0x82, 0x2c, 0xa0, + 0x08, 0x28, 0x02, 0xcd, 0x40, 0xb3, 0x80, 0x2c, + 0x40, 0xc8, 0xa0, 0x00, 0x00, 0x00, 0xa0, 0x00, + 0x20, 0x00, 0x08, 0x04, 0x02, 0x38, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x1e, 0x00, + 0xb4, 0x80, 0x21, 0xe0, 0x08, 0xf9, 0x02, 0x3a, + 0x04, 0xaf, 0x81, 0x25, 0x20, 0x0b, 0x48, 0x02, + 0x5f, 0x00, 0xb4, 0x80, 0x2f, 0x20, 0x08, 0xf8, + 0x02, 0x3e, 0x00, 0x87, 0x80, 0xa1, 0xa0, 0x0a, + 0x58, 0x82, 0xf6, 0x00, 0xa6, 0x80, 0x2d, 0xe0, + 0x08, 0x68, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2f, + 0xa0, 0x08, 0x68, 0x02, 0x32, 0x00, 0x87, 0x90, + 0x20, 0xa4, 0x08, 0x69, 0x12, 0x08, 0x00, 0x40, + 0xed, 0x09, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x4a, 0x08, 0x0c, 0x00, 0xf1, 0x00, 0x30, + 0x41, 0x0c, 0x11, 0x83, 0x01, 0x20, 0xc3, 0x12, + 0x34, 0x10, 0x0d, 0x00, 0x03, 0xcc, 0x10, 0xf0, + 0x00, 0x3c, 0x40, 0x0c, 0x30, 0x03, 0x8c, 0x00, + 0xc3, 0x00, 0x30, 0xc6, 0x0e, 0x12, 0x03, 0x89, + 0x20, 0xe2, 0x00, 0x1c, 0x84, 0x0c, 0x20, 0x83, + 0xcc, 0x00, 0xf2, 0x08, 0x3c, 0x40, 0x4c, 0xb0, + 0x8b, 0x80, 0x40, 0xe2, 0x40, 0xb0, 0x44, 0x0c, + 0x30, 0x0b, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xf5, 0x00, 0x3f, + 0xc0, 0x0f, 0x71, 0x43, 0xf8, 0x00, 0xff, 0x10, + 0x0b, 0x80, 0x0f, 0xc1, 0x03, 0xfc, 0x04, 0xfc, + 0x00, 0x3d, 0xc0, 0x0f, 0x70, 0x03, 0xdc, 0x40, + 0xff, 0x00, 0xbf, 0xc4, 0x0f, 0xd0, 0x13, 0xd4, + 0x00, 0xfe, 0x00, 0x3f, 0xc0, 0x0f, 0xe0, 0x23, + 0xfc, 0x00, 0x3f, 0x00, 0x3f, 0x84, 0x27, 0xf0, + 0x11, 0x58, 0x00, 0xff, 0x00, 0x3f, 0xc4, 0x2f, + 0xf0, 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x05, 0xec, 0x00, 0xe9, 0x00, 0x3c, + 0xc1, 0x0c, 0x18, 0x03, 0x88, 0x00, 0xc9, 0x00, + 0x3e, 0x40, 0x0f, 0xa8, 0x03, 0x6c, 0x00, 0xfa, + 0x00, 0x3c, 0xc0, 0x0c, 0xb0, 0x03, 0x24, 0x00, + 0xf3, 0x00, 0x36, 0x81, 0x0f, 0xb0, 0x13, 0x28, + 0x00, 0x7a, 0x01, 0x3e, 0x80, 0x0f, 0xa0, 0x07, + 0xec, 0x00, 0xfb, 0x00, 0x32, 0x40, 0x0e, 0xa0, + 0x03, 0xec, 0x00, 0x98, 0x00, 0x32, 0x80, 0x84, + 0x90, 0x03, 0x2a, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x91, 0x9c, 0x00, 0xb7, 0x00, 0x6d, + 0xc0, 0x0d, 0x50, 0x02, 0x18, 0x00, 0xd5, 0x00, + 0x2d, 0xc0, 0xcb, 0x70, 0x13, 0x5c, 0x00, 0xb6, + 0x01, 0x2d, 0x40, 0x02, 0x70, 0x0a, 0x1c, 0x00, + 0xb7, 0x00, 0xa1, 0xed, 0x09, 0x00, 0x09, 0x01, + 0x80, 0x0b, 0x70, 0x02, 0x14, 0x00, 0x97, 0x00, + 0x2d, 0xc0, 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0xa9, 0x80, 0x0e, 0x40, 0x02, 0xd4, 0x00, + 0xb7, 0x00, 0x20, 0x80, 0x08, 0xf0, 0x02, 0x12, + 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x9e, 0x01, 0xa5, 0xc0, 0x6d, 0xe0, 0x08, 0x7c, + 0x02, 0xba, 0x00, 0x97, 0x80, 0x2d, 0x60, 0x0b, + 0x78, 0x26, 0x1a, 0x00, 0xb7, 0x80, 0x27, 0xe2, + 0x08, 0xf8, 0x02, 0x1e, 0x00, 0xb7, 0x8c, 0x25, + 0xe2, 0x0b, 0x78, 0x82, 0x1a, 0x00, 0xb6, 0x88, + 0x2d, 0xa0, 0x0b, 0x78, 0x02, 0x9e, 0x00, 0xbf, + 0xc1, 0x29, 0x60, 0x02, 0x78, 0x82, 0xda, 0x00, + 0xb2, 0x82, 0xa5, 0xf0, 0x08, 0x78, 0x02, 0x30, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, + 0xcc, 0x00, 0xb3, 0x01, 0x2c, 0xd2, 0x09, 0x3c, + 0x42, 0x08, 0x14, 0x93, 0x00, 0x2c, 0xe4, 0x0b, + 0x30, 0x02, 0x48, 0x20, 0xb3, 0x84, 0x2c, 0xe0, + 0x0a, 0x10, 0x1a, 0x0c, 0x00, 0xb3, 0x00, 0x20, + 0xc0, 0x0b, 0x30, 0x02, 0x0c, 0x00, 0x93, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xbb, + 0x42, 0x28, 0x20, 0x0a, 0x32, 0x02, 0xe8, 0x00, + 0xb3, 0x60, 0x22, 0xe0, 0x08, 0x35, 0x0a, 0x12, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, + 0xa8, 0x00, 0xee, 0x80, 0x0d, 0xb3, 0x88, 0xec, + 0x03, 0xbb, 0x88, 0xda, 0x00, 0x3f, 0xb0, 0x0f, + 0xe4, 0x0b, 0x38, 0x00, 0xbe, 0xe0, 0x3f, 0x90, + 0x0c, 0xe4, 0x43, 0x3b, 0x80, 0xf6, 0xc0, 0x37, + 0x90, 0x0f, 0xe0, 0x0b, 0x39, 0x20, 0xfe, 0x40, + 0x3f, 0x90, 0x0f, 0xe4, 0x83, 0xe8, 0x00, 0x3e, + 0x00, 0x3b, 0x88, 0x0e, 0xec, 0x03, 0xf8, 0x80, + 0xfe, 0x40, 0x33, 0xa0, 0x2c, 0xe8, 0x03, 0x3a, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x0a, 0x01, 0x48, 0x00, 0xe0, 0x00, 0xf8, + 0x84, 0x3e, 0x00, 0x0f, 0x86, 0x03, 0xe3, 0x00, + 0xf8, 0x13, 0x3e, 0x20, 0x0f, 0x8c, 0x43, 0xa1, + 0x44, 0x78, 0xc0, 0x3e, 0x21, 0x0f, 0x87, 0x03, + 0xe2, 0x00, 0xf8, 0x80, 0x3e, 0x20, 0x0f, 0x84, + 0x03, 0xe3, 0x00, 0xd8, 0x80, 0x3e, 0x31, 0x0f, + 0x88, 0x03, 0xe1, 0x08, 0xf8, 0x0c, 0x26, 0x10, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf0, 0x40, 0x3e, + 0x00, 0x0f, 0x00, 0x93, 0xd2, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, + 0x20, 0x3e, 0x64, 0x2d, 0x98, 0x03, 0xe6, 0x00, + 0xe9, 0x22, 0x3e, 0x68, 0x0f, 0x91, 0x03, 0xe4, + 0x00, 0xf9, 0x20, 0x32, 0x60, 0x0c, 0x98, 0x03, + 0x26, 0x00, 0xc9, 0x20, 0x32, 0x70, 0x8f, 0x90, + 0x83, 0x26, 0x40, 0xf9, 0x40, 0x3a, 0x70, 0x0f, + 0x91, 0x03, 0xa4, 0x00, 0xf9, 0x40, 0x32, 0x68, + 0x0e, 0x90, 0x03, 0xe6, 0x22, 0xc9, 0x10, 0x3a, + 0x40, 0x0c, 0x98, 0x02, 0x82, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x64, 0x00, 0xb9, + 0x00, 0x2e, 0x70, 0x08, 0x9a, 0x03, 0x86, 0x80, + 0x89, 0xc0, 0x2e, 0x50, 0x8b, 0x98, 0x42, 0xe7, + 0x44, 0xb1, 0x00, 0x28, 0x44, 0x28, 0x10, 0x03, + 0x46, 0x02, 0x89, 0x08, 0x22, 0x70, 0x0b, 0x10, + 0x82, 0xa6, 0x80, 0xb9, 0x80, 0x2e, 0x48, 0x0b, + 0x98, 0x02, 0xe7, 0x00, 0xb9, 0x80, 0x22, 0x60, + 0x08, 0x94, 0x02, 0xe6, 0x00, 0x89, 0x00, 0x22, + 0x40, 0x08, 0x99, 0x02, 0x20, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, 0xb9, + 0x00, 0x2a, 0x50, 0x08, 0x91, 0x02, 0xe4, 0x80, + 0xa9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x04, 0xb9, 0x40, 0x22, 0x40, 0x08, 0x91, 0x22, + 0x24, 0x82, 0xa9, 0x00, 0x22, 0x40, 0x4b, 0x90, + 0x42, 0xed, 0x09, 0x00, 0x0b, 0x01, 0x64, 0x00, + 0x99, 0x00, 0x2a, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x80, 0xb9, 0x00, 0x20, 0x40, 0x88, 0xb1, 0x02, + 0xe4, 0x40, 0x89, 0x0c, 0x2a, 0x40, 0x09, 0x90, + 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2e, 0x40, + 0x08, 0x10, 0x02, 0x84, 0x01, 0x81, 0x00, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xcd, 0x04, 0xb1, 0x01, + 0xa8, 0x40, 0x08, 0x90, 0x02, 0x64, 0x00, 0x89, + 0x00, 0x20, 0x60, 0x0b, 0x10, 0x02, 0xc4, 0x04, + 0xb1, 0x00, 0x2c, 0x41, 0x4b, 0x10, 0x02, 0xc4, + 0x00, 0xb1, 0x00, 0xa0, 0x50, 0x08, 0x18, 0x02, + 0xcd, 0x00, 0x81, 0x41, 0x28, 0x50, 0xe9, 0x14, + 0x02, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3a, 0x00, + 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xea, 0x00, 0x2e, + 0x80, 0x0f, 0xa0, 0x43, 0xe0, 0x00, 0xf8, 0x00, + 0x32, 0x01, 0x0c, 0xa0, 0x03, 0x20, 0x00, 0xe8, + 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, 0x60, 0x00, + 0xf8, 0x00, 0x3a, 0x00, 0x0f, 0x80, 0x03, 0xa8, + 0x00, 0xf8, 0x00, 0x32, 0x80, 0x2e, 0x80, 0x03, + 0xe0, 0x00, 0xc8, 0x01, 0x3a, 0x01, 0x0d, 0xa0, + 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xd8, 0x9d, 0xe4, 0x00, 0xfd, 0x40, 0x3f, 0x40, + 0x4e, 0xd0, 0x03, 0xf4, 0x00, 0xfd, 0x00, 0x3f, + 0x40, 0x8f, 0x70, 0x06, 0xf5, 0x00, 0xfd, 0x00, + 0x3f, 0x40, 0x0f, 0x70, 0x53, 0xf4, 0x00, 0xfd, + 0x01, 0xbf, 0x40, 0x8d, 0x50, 0x03, 0xb4, 0x00, + 0xfd, 0x00, 0x3f, 0x40, 0x07, 0xd0, 0x03, 0xe4, + 0x00, 0xf5, 0x2a, 0x3f, 0x40, 0x0f, 0xd2, 0x83, + 0xf5, 0x12, 0xfd, 0x40, 0x37, 0x50, 0x2e, 0xd4, + 0x03, 0xa6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0xe4, 0x00, 0xed, 0x09, 0x00, 0x0c, + 0x01, 0xf5, 0x20, 0x33, 0x40, 0x0e, 0xd0, 0x03, + 0x34, 0x10, 0xfd, 0x00, 0x33, 0x40, 0x0f, 0x70, + 0x00, 0x34, 0x00, 0xed, 0x00, 0x33, 0x40, 0x4e, + 0x50, 0x03, 0x34, 0x00, 0xf5, 0x00, 0x03, 0x40, + 0x0f, 0xd0, 0x03, 0x74, 0x09, 0xfd, 0x00, 0x3f, + 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x0c, 0xfd, 0x00, + 0x33, 0x45, 0x0f, 0xd0, 0x43, 0xf4, 0xa0, 0x7d, + 0x30, 0x33, 0x40, 0x0c, 0xd0, 0x23, 0xc6, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x78, 0x10, 0xe0, + 0x00, 0xb8, 0x10, 0x22, 0x00, 0x08, 0xa0, 0x03, + 0x60, 0x00, 0xb8, 0x00, 0x32, 0x01, 0x4b, 0x80, + 0x02, 0x21, 0x22, 0xd8, 0x00, 0x2a, 0x00, 0x0e, + 0x80, 0x02, 0x28, 0x10, 0xb8, 0x00, 0x22, 0x00, + 0x8b, 0x80, 0x02, 0x20, 0x00, 0xb8, 0x00, 0x3a, + 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xe8, 0x20, + 0xb4, 0x00, 0x0e, 0x80, 0x86, 0xc0, 0x80, 0xb0, + 0x30, 0x36, 0x12, 0x08, 0x80, 0x82, 0xce, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x48, 0x05, 0xc4, + 0x00, 0xb9, 0x00, 0x20, 0x40, 0x0a, 0x90, 0x02, + 0x04, 0x00, 0xb1, 0x00, 0x20, 0x40, 0x8b, 0x10, + 0x02, 0x04, 0xc1, 0xa1, 0x00, 0x22, 0x60, 0x08, + 0x10, 0x02, 0x84, 0x04, 0xb9, 0x00, 0x24, 0x40, + 0x0b, 0x10, 0x02, 0x44, 0x00, 0xb1, 0x01, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x28, + 0x24, 0x40, 0x0a, 0x1a, 0x00, 0x44, 0xa0, 0xb1, + 0x20, 0x20, 0x4c, 0x28, 0x11, 0x02, 0xc2, 0x01, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, + 0x00, 0xb9, 0x08, 0x22, 0x40, 0x08, 0x90, 0x02, + 0x65, 0x10, 0xb9, 0x80, 0xa6, 0x40, 0x0b, 0xb0, + 0x22, 0x24, 0x00, 0x99, 0x00, 0x2a, 0x44, 0x0a, + 0x90, 0x08, 0xa4, 0x80, 0xb9, 0x00, 0x26, 0x40, + 0x0b, 0x90, 0x02, 0x64, 0x00, 0xb9, 0x04, 0xed, + 0x09, 0x00, 0x0d, 0x01, 0x2e, 0xc0, 0x0b, 0xb6, + 0x02, 0xe4, 0x00, 0xab, 0x00, 0xa6, 0x48, 0x0a, + 0x98, 0x02, 0xec, 0x40, 0xb9, 0x15, 0x24, 0x50, + 0x20, 0x92, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf1, 0x40, + 0x32, 0x48, 0x0e, 0x19, 0x03, 0x26, 0x00, 0xf1, + 0x80, 0x32, 0x60, 0x0f, 0x19, 0x0a, 0x24, 0xc0, + 0xe1, 0x98, 0x32, 0x70, 0x0c, 0x1d, 0x03, 0xa7, + 0x00, 0xf9, 0x08, 0xa6, 0x62, 0x0f, 0x9e, 0x43, + 0x64, 0x80, 0xb9, 0x90, 0x3e, 0x62, 0x8f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0xa0, 0xf6, 0x60, 0x0e, + 0x90, 0x02, 0x66, 0x20, 0xf9, 0x80, 0xf2, 0x40, + 0xc4, 0x92, 0x02, 0xe8, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x68, 0x00, 0xa4, 0x00, 0xf9, 0x00, + 0xbe, 0x40, 0x0f, 0x90, 0x02, 0xe5, 0x04, 0xf9, + 0x00, 0x3a, 0x48, 0x8f, 0x90, 0x13, 0x64, 0x00, + 0xf9, 0x80, 0x3e, 0x40, 0x0e, 0x98, 0x03, 0x66, + 0x10, 0xf9, 0x00, 0x3a, 0x48, 0x0f, 0x91, 0x03, + 0xa4, 0x44, 0xf9, 0x80, 0x7a, 0x44, 0x03, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x40, 0x3e, 0x40, 0x8e, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3a, 0x42, + 0x8f, 0x90, 0x83, 0xca, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, 0x00, + 0x32, 0x10, 0x0f, 0x80, 0x03, 0xe1, 0x00, 0xd8, + 0x80, 0x36, 0x20, 0x0f, 0x88, 0x03, 0xe1, 0x24, + 0xe8, 0x80, 0x3a, 0x08, 0x0c, 0x80, 0x03, 0x60, + 0x00, 0xf8, 0xc0, 0x36, 0x30, 0x0f, 0x89, 0x13, + 0xa0, 0x50, 0xf8, 0x86, 0x32, 0x20, 0x0c, 0x8c, + 0x03, 0xa2, 0x00, 0xf8, 0x18, 0x32, 0x08, 0x0c, + 0x80, 0x02, 0xe1, 0x20, 0xc0, 0x02, 0x3a, 0x00, + 0x0f, 0x80, 0x03, 0xca, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x04, 0x28, 0x00, 0xba, 0x82, + 0x21, 0xb6, 0xed, 0x09, 0x00, 0x0e, 0x01, 0x0b, + 0xe9, 0x02, 0xfa, 0x00, 0x8e, 0xc0, 0x23, 0x90, + 0x0b, 0xe4, 0x42, 0x3b, 0x00, 0xce, 0xc0, 0xa1, + 0xb0, 0x00, 0xe4, 0x02, 0x2a, 0x10, 0xb6, 0xc2, + 0x23, 0xb8, 0x0b, 0x6c, 0x02, 0xf9, 0x40, 0xbe, + 0x40, 0x23, 0x92, 0x08, 0xe4, 0x02, 0xf9, 0x00, + 0xbe, 0x80, 0x23, 0x98, 0x08, 0xec, 0x03, 0xb9, + 0x12, 0x8e, 0x54, 0x2b, 0x90, 0x0b, 0xe0, 0x02, + 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x4c, 0x00, 0xb3, 0x80, 0x20, 0xf0, 0x0b, + 0x0c, 0x02, 0xcc, 0x00, 0x91, 0x00, 0x2c, 0xe0, + 0x8b, 0x30, 0x06, 0x6f, 0x00, 0xb3, 0x00, 0xa8, + 0xd0, 0x08, 0x00, 0x80, 0xce, 0x40, 0xb0, 0x80, + 0x20, 0xc0, 0x0b, 0x10, 0x02, 0x88, 0x00, 0xb3, + 0x10, 0x20, 0xe0, 0x88, 0x30, 0x22, 0xc4, 0x00, + 0xab, 0xc0, 0x20, 0xc0, 0x28, 0x34, 0x82, 0xcd, + 0x02, 0x83, 0x40, 0x28, 0xc0, 0x0b, 0x30, 0x02, + 0xca, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x01, 0x1c, 0x00, 0xbf, 0x40, 0x21, 0xc0, 0x0b, + 0x54, 0x02, 0xdb, 0x00, 0x85, 0x40, 0x21, 0xc2, + 0x09, 0x70, 0x02, 0x3c, 0x21, 0x87, 0x09, 0x23, + 0x50, 0x08, 0x50, 0x02, 0x94, 0x00, 0xb4, 0x08, + 0x21, 0x80, 0x03, 0x70, 0x02, 0xdc, 0x10, 0xbf, + 0x80, 0xa3, 0xe1, 0x28, 0x74, 0x02, 0xd4, 0x20, + 0xbf, 0x00, 0x21, 0xe0, 0x98, 0x74, 0x02, 0x9e, + 0x20, 0x87, 0x00, 0x29, 0x90, 0x0b, 0x74, 0x02, + 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x88, 0x1e, 0x00, 0xf7, 0x80, 0x31, 0xe0, 0x0b, + 0x58, 0x03, 0xde, 0x00, 0xd5, 0x80, 0x3d, 0xe0, + 0x0f, 0x78, 0x03, 0x5e, 0x10, 0xf7, 0x80, 0x39, + 0xe0, 0x2c, 0x78, 0x03, 0xde, 0x00, 0xf4, 0x80, + 0x31, 0xe0, 0x0f, 0x58, 0x03, 0x92, 0x00, 0xf7, + 0x82, 0x21, 0xa0, 0x0c, 0x78, 0xed, 0x09, 0x00, + 0x0f, 0x01, 0x27, 0x92, 0x00, 0xe5, 0x80, 0x31, + 0x60, 0x0c, 0x58, 0x03, 0xd6, 0x00, 0xc5, 0x82, + 0x39, 0xe0, 0x0b, 0x78, 0x03, 0xea, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1d, 0xac, 0x00, + 0xfb, 0x00, 0xbe, 0xc0, 0x0f, 0x90, 0x03, 0xcc, + 0x00, 0x31, 0x00, 0x3e, 0xc0, 0x07, 0xb0, 0x03, + 0xc8, 0x00, 0xe3, 0x00, 0x3c, 0x40, 0x0f, 0xb0, + 0x03, 0x64, 0x04, 0xf8, 0x01, 0xba, 0x80, 0x0f, + 0xb0, 0x23, 0xe4, 0x08, 0xf3, 0x00, 0x3c, 0x80, + 0x0f, 0xb0, 0x03, 0xe4, 0x00, 0xd3, 0x00, 0x3e, + 0x40, 0x0f, 0xa0, 0x03, 0xa4, 0x04, 0xf9, 0x00, + 0x36, 0x80, 0x0f, 0x90, 0x03, 0xc2, 0x06, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xfe, 0x00, + 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xe8, 0x03, 0xfe, + 0x00, 0xcf, 0x80, 0x3f, 0xa0, 0x07, 0xf8, 0x07, + 0xb8, 0x40, 0xef, 0x80, 0x3f, 0xe0, 0x0c, 0x58, + 0x03, 0x36, 0x00, 0xfd, 0x80, 0x33, 0xe4, 0x4f, + 0xf9, 0x43, 0x3a, 0x48, 0x7e, 0x91, 0x37, 0xe8, + 0x0f, 0xe9, 0x23, 0x7a, 0x00, 0xdf, 0x00, 0x3f, + 0xe0, 0x0d, 0xd8, 0x02, 0xfa, 0x00, 0xef, 0x80, + 0x33, 0xe4, 0x0f, 0xf8, 0x03, 0xc0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, + 0xb7, 0x18, 0x2d, 0xc0, 0x0b, 0x44, 0x02, 0xd8, + 0x00, 0x87, 0x00, 0x2d, 0x01, 0x0b, 0x70, 0x06, + 0x10, 0x80, 0x87, 0x00, 0x2d, 0x83, 0x08, 0x51, + 0x02, 0x14, 0x00, 0xb5, 0x20, 0x21, 0x80, 0x4e, + 0x64, 0x02, 0x15, 0x41, 0x86, 0x30, 0x2d, 0xc0, + 0x0b, 0x60, 0x86, 0xd4, 0x00, 0xb7, 0x12, 0x7b, + 0xc0, 0x28, 0x50, 0x02, 0xd8, 0x80, 0x8f, 0x20, + 0xb5, 0x00, 0x0b, 0x64, 0x02, 0xea, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, + 0xb5, 0x00, 0x2d, 0x02, 0x0b, 0x50, 0x02, 0xdd, + 0xed, 0x09, 0x00, 0x10, 0x01, 0x02, 0x86, 0x00, + 0x2d, 0x04, 0x0b, 0x71, 0x02, 0x18, 0x40, 0xa7, + 0x00, 0x2d, 0xc4, 0x08, 0x70, 0x02, 0x14, 0x00, + 0xb5, 0x02, 0xa1, 0xc0, 0x19, 0xf0, 0x12, 0x34, + 0x41, 0x86, 0x08, 0x25, 0x88, 0x4b, 0x60, 0x22, + 0xd0, 0x00, 0x95, 0x10, 0x2d, 0x82, 0x09, 0x50, + 0x02, 0xd4, 0x08, 0xa4, 0x40, 0x21, 0xc1, 0x1b, + 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x14, 0xcc, 0x00, 0xb1, 0x80, 0x6c, + 0x60, 0x0b, 0x10, 0x02, 0xcc, 0x40, 0x83, 0x00, + 0x2c, 0x11, 0x0b, 0x38, 0x82, 0x28, 0x00, 0x83, + 0x21, 0x2c, 0x10, 0x08, 0x38, 0x42, 0x04, 0x90, + 0xb3, 0x40, 0x20, 0x20, 0x0a, 0x34, 0x02, 0x04, + 0x21, 0x80, 0x88, 0x2c, 0xa4, 0x0b, 0x28, 0x02, + 0xc4, 0x00, 0xb3, 0xf0, 0x28, 0xb0, 0x00, 0x01, + 0x02, 0xc4, 0x00, 0x88, 0x00, 0x20, 0x20, 0x0b, + 0x0c, 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x15, 0xac, 0x00, 0xfb, 0x80, 0x2e, + 0x60, 0x0f, 0x82, 0x03, 0xe4, 0x00, 0xc9, 0x00, + 0x3e, 0x60, 0x0f, 0x36, 0x08, 0x28, 0x00, 0xe3, + 0x80, 0x3c, 0xe4, 0x0c, 0x24, 0x0b, 0x0c, 0x24, + 0xf0, 0x42, 0x32, 0xfd, 0x8f, 0x30, 0x83, 0x2b, + 0x00, 0xda, 0xc0, 0x36, 0xd0, 0x0f, 0x28, 0x03, + 0x6c, 0x04, 0xdb, 0x81, 0x3c, 0xb0, 0x0d, 0x1c, + 0x03, 0xce, 0x08, 0xea, 0xa0, 0x22, 0x56, 0x0f, + 0xbc, 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0xec, 0x00, 0xf3, 0x00, 0x3e, + 0x50, 0x0f, 0x90, 0x03, 0xe0, 0x00, 0xfb, 0x00, + 0x3e, 0x79, 0x0f, 0xb4, 0x13, 0x69, 0x04, 0xfb, + 0x80, 0x3e, 0x40, 0x8f, 0xb3, 0x03, 0xe4, 0x00, + 0xf8, 0x44, 0x3e, 0x90, 0x0e, 0xb4, 0x83, 0xef, + 0x08, 0xfa, 0x00, 0x3e, 0xc1, 0x0f, 0xa0, 0x03, + 0xe4, 0x00, 0xfb, 0xed, 0x09, 0x00, 0x11, 0x01, + 0x40, 0x3a, 0x90, 0x0f, 0x90, 0x83, 0xec, 0x40, + 0xf8, 0x00, 0x3e, 0x50, 0x0b, 0x31, 0x03, 0xe0, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, + 0xfc, 0x00, 0xff, 0x00, 0x33, 0x48, 0x0c, 0xc0, + 0x03, 0xf6, 0x44, 0xfd, 0x94, 0x3f, 0x40, 0x0f, + 0xd0, 0x03, 0x28, 0x00, 0xcf, 0x90, 0x33, 0xc0, + 0x0a, 0xfc, 0x0b, 0x34, 0x00, 0xcc, 0xaa, 0x33, + 0xc4, 0x0f, 0xfa, 0x03, 0x32, 0x14, 0xce, 0xc0, + 0x3f, 0xa2, 0x0f, 0xe9, 0x20, 0x3a, 0x00, 0xfd, + 0x00, 0x3f, 0x6b, 0x0c, 0xd0, 0x03, 0x2a, 0x00, + 0xce, 0x00, 0x31, 0x64, 0x0c, 0xe1, 0xc3, 0x80, + 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, + 0x6c, 0x00, 0xbb, 0x00, 0x28, 0x70, 0x0a, 0x94, + 0x02, 0xec, 0x10, 0xb9, 0x01, 0x2e, 0x34, 0x0b, + 0x90, 0x02, 0x2a, 0x10, 0xab, 0x46, 0x22, 0x40, + 0x08, 0xb0, 0x22, 0x26, 0x40, 0x88, 0x60, 0x22, + 0x81, 0x0b, 0xbc, 0x02, 0x87, 0x00, 0x8a, 0xc0, + 0x2e, 0xb1, 0x8b, 0xa4, 0x12, 0xa5, 0xc0, 0xbb, + 0x80, 0x2e, 0x41, 0x08, 0x8c, 0x02, 0x2b, 0x40, + 0xa8, 0xc4, 0x22, 0x72, 0x8a, 0x80, 0x02, 0x20, + 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, + 0x2c, 0x00, 0xbb, 0x00, 0x22, 0xd0, 0x08, 0xb0, + 0x02, 0xe4, 0x00, 0xbb, 0x00, 0x2e, 0x10, 0x0b, + 0xb2, 0x02, 0x23, 0x00, 0x99, 0x08, 0x26, 0xc0, + 0x0a, 0xb0, 0x22, 0xe4, 0x00, 0x89, 0x04, 0x02, + 0x90, 0x0b, 0xb0, 0x12, 0x2c, 0x90, 0x8a, 0x08, + 0x2e, 0x88, 0x4b, 0xa0, 0x40, 0xac, 0x00, 0xb9, + 0x80, 0x2e, 0x02, 0x88, 0x8c, 0x00, 0x60, 0x00, + 0x8b, 0x18, 0x22, 0x80, 0x00, 0x90, 0x02, 0xa0, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x0c, 0x00, 0xb3, 0x00, 0x2a, 0xc0, 0x0a, 0x10, + 0x02, 0xc8, 0x00, 0xb3, 0x04, 0x2c, 0xed, 0x09, + 0x00, 0x12, 0x01, 0x00, 0x4b, 0xb0, 0x0a, 0x00, + 0x08, 0xb9, 0x00, 0x26, 0x80, 0x0a, 0xb0, 0x22, + 0xc4, 0x18, 0x88, 0x00, 0x00, 0x80, 0x4b, 0xb0, + 0x12, 0x8c, 0x00, 0x82, 0x00, 0x2c, 0x80, 0x0b, + 0xa0, 0x02, 0x84, 0x00, 0xb0, 0x00, 0x2e, 0x00, + 0x2a, 0x80, 0x00, 0xe0, 0x00, 0xa1, 0x00, 0x20, + 0x00, 0x88, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xf9, + 0x00, 0x32, 0x00, 0x0c, 0x90, 0x03, 0xe4, 0x00, + 0xfa, 0x00, 0x3e, 0x00, 0x0f, 0x90, 0x03, 0x20, + 0x00, 0xdb, 0x00, 0xb6, 0xc1, 0x0e, 0xb0, 0x03, + 0xe4, 0x00, 0xc9, 0x00, 0xb2, 0xc0, 0x0f, 0xb0, + 0x03, 0x24, 0x00, 0xca, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x23, 0x28, 0x08, 0xf9, 0x00, 0x3e, 0x00, + 0x0c, 0x80, 0x03, 0x60, 0x00, 0xca, 0x00, 0xb2, + 0x80, 0x0c, 0x80, 0x43, 0x80, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xfd, + 0x00, 0x3f, 0x00, 0x0f, 0xd0, 0x03, 0xdc, 0x00, + 0x7f, 0x00, 0x3f, 0x00, 0x4f, 0x40, 0x53, 0xf0, + 0x00, 0xee, 0x00, 0x39, 0x00, 0x8d, 0xf0, 0x03, + 0x34, 0x06, 0xf5, 0x00, 0x3f, 0x80, 0x0f, 0x70, + 0x63, 0xd4, 0x02, 0xfe, 0x00, 0x3f, 0x80, 0x8f, + 0xe0, 0x03, 0xf4, 0x00, 0xfc, 0x02, 0x3f, 0x00, + 0x0d, 0xc0, 0x03, 0x30, 0x00, 0xfc, 0x00, 0x3f, + 0x00, 0x2f, 0xc0, 0x03, 0xe8, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc2, 0x05, 0xfc, 0xe0, 0xec, + 0x10, 0x37, 0xd8, 0x0f, 0xc0, 0x03, 0xf0, 0x08, + 0xfe, 0x11, 0x33, 0xc8, 0x0f, 0xf2, 0x03, 0x70, + 0x00, 0xfc, 0x00, 0x3f, 0x0a, 0x0c, 0xc2, 0x03, + 0xb0, 0x80, 0xec, 0x00, 0x33, 0x42, 0x0c, 0x40, + 0x03, 0x30, 0x00, 0xcc, 0x00, 0x39, 0x0a, 0x0f, + 0xc0, 0x03, 0xb0, 0x20, 0xcc, 0x00, 0x3b, 0x00, + 0x4c, 0xed, 0x09, 0x00, 0x13, 0x01, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x2c, 0x3b, 0x0a, 0x0c, 0xf0, + 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc2, 0x08, 0xbd, 0x00, 0x8b, 0x20, 0x23, 0xd0, + 0x4b, 0xb2, 0x82, 0xec, 0x00, 0xb8, 0x20, 0x23, + 0xc4, 0x0b, 0xf5, 0x02, 0xcc, 0x80, 0xb8, 0x40, + 0x2e, 0x00, 0x2d, 0x80, 0x02, 0x20, 0x02, 0xc8, + 0x00, 0xa2, 0x00, 0x8a, 0x90, 0x02, 0x21, 0x00, + 0x88, 0x40, 0x22, 0x50, 0x08, 0x80, 0x0a, 0x20, + 0x12, 0xa8, 0x01, 0x2a, 0x14, 0x28, 0xb0, 0x12, + 0xec, 0x00, 0x9f, 0x48, 0x2e, 0x48, 0x0a, 0xb0, + 0x02, 0x60, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xca, 0x44, 0xcc, 0x10, 0xb3, 0x21, 0x20, 0xcc, + 0x8b, 0x30, 0x02, 0xcc, 0xa0, 0xb3, 0x22, 0x28, + 0xc0, 0x89, 0x30, 0x02, 0xce, 0x20, 0xb0, 0x40, + 0x2c, 0x00, 0x08, 0x04, 0x0a, 0x00, 0x40, 0x80, + 0x10, 0x20, 0x40, 0x08, 0x90, 0x02, 0x81, 0x0e, + 0xa0, 0x43, 0xa8, 0x40, 0x88, 0x01, 0x02, 0x00, + 0x00, 0x80, 0x40, 0xa0, 0x00, 0x0a, 0x30, 0x02, + 0x8c, 0x00, 0xb3, 0x20, 0x2c, 0x0a, 0x08, 0x30, + 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x05, 0xac, 0x00, 0x93, 0x20, 0x22, 0xc0, + 0x0b, 0xb0, 0x82, 0xe8, 0x00, 0xb8, 0x02, 0x22, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xb9, 0x00, + 0x2e, 0xc8, 0x09, 0x80, 0x42, 0xa8, 0x00, 0xb9, + 0x40, 0x22, 0xe0, 0x28, 0x90, 0x1a, 0x28, 0x00, + 0x8a, 0x10, 0x22, 0xc0, 0x0a, 0xb0, 0x12, 0x20, + 0x01, 0x0a, 0x40, 0x2a, 0x04, 0x4a, 0xb1, 0x42, + 0xec, 0x00, 0x9b, 0x04, 0x2e, 0x60, 0x0a, 0xb0, + 0x02, 0x70, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x15, 0xec, 0x00, 0xfb, 0x48, 0xb2, 0xc0, + 0x0f, 0xb4, 0x03, 0xee, 0x00, 0xfb, 0x48, 0x32, + 0xc0, 0x0f, 0xb0, 0x03, 0xed, 0x09, 0x00, 0x14, + 0x01, 0x6c, 0x00, 0xf8, 0x90, 0x3e, 0x29, 0x0c, + 0x88, 0x83, 0xa1, 0x80, 0xe8, 0xc0, 0x32, 0x30, + 0x08, 0x98, 0x09, 0xa0, 0x80, 0xc8, 0x00, 0x2a, + 0x64, 0x0f, 0x8c, 0x03, 0x23, 0x00, 0xc8, 0xc0, + 0x3a, 0x00, 0x0e, 0xba, 0x03, 0xec, 0x20, 0xbb, + 0x00, 0x3a, 0x38, 0x0c, 0xb0, 0x03, 0xd0, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x9c, + 0x10, 0xed, 0x80, 0x3f, 0xc0, 0x0f, 0xc2, 0x03, + 0xfc, 0x89, 0xf3, 0x10, 0xbf, 0xc0, 0x8f, 0xf0, + 0x83, 0xfd, 0x00, 0xff, 0x80, 0x3d, 0xc0, 0x0e, + 0x71, 0x03, 0x56, 0x80, 0xc7, 0x21, 0x3c, 0x80, + 0x0f, 0xda, 0x23, 0xd6, 0x40, 0xf5, 0x80, 0x3f, + 0xc0, 0x0d, 0x7a, 0x03, 0x5d, 0x00, 0xf7, 0x94, + 0x75, 0xe0, 0x0d, 0xd8, 0x03, 0xfc, 0x60, 0xdb, + 0x00, 0x3e, 0x40, 0x0f, 0xf0, 0x03, 0xf8, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x44, 0x10, 0xac, + 0x00, 0xca, 0x00, 0x3e, 0xc0, 0x4f, 0xb4, 0x43, + 0xe4, 0x00, 0xd9, 0x40, 0x32, 0xc0, 0x0f, 0xb0, + 0x03, 0xe4, 0x00, 0x8a, 0x00, 0x36, 0x00, 0x0d, + 0xb6, 0x23, 0xec, 0x00, 0xca, 0x00, 0x3a, 0x40, + 0x0c, 0xb8, 0x03, 0x6c, 0xc2, 0xcb, 0x20, 0x3e, + 0x60, 0x0e, 0x80, 0x21, 0x6c, 0x04, 0xf9, 0x62, + 0x36, 0xd0, 0x0b, 0xb4, 0x83, 0xec, 0x00, 0xfb, + 0x04, 0x32, 0x20, 0x0c, 0xb0, 0x03, 0xd0, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x05, 0x3c, + 0x04, 0x8b, 0x00, 0x2f, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0x8b, 0x00, 0x23, 0xc0, 0x0b, 0xfc, + 0x42, 0xec, 0x00, 0x8b, 0x00, 0x6e, 0xc0, 0x09, + 0xb4, 0x02, 0xec, 0x30, 0x8b, 0x20, 0x22, 0xc0, + 0x08, 0x10, 0x03, 0x6d, 0x00, 0x8b, 0x40, 0x2c, + 0xc0, 0x08, 0xb0, 0x42, 0x2c, 0x02, 0x8b, 0x40, + 0x26, 0xc0, 0x0b, 0x94, 0x02, 0xee, 0x10, 0xed, + 0x09, 0x00, 0x15, 0x01, 0x4f, 0x24, 0xa2, 0x70, + 0x28, 0xb0, 0x02, 0xf2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x04, 0x4c, 0x08, 0x83, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x00, 0x82, + 0x00, 0x20, 0xe8, 0x4b, 0x3d, 0x22, 0x4c, 0x00, + 0xa0, 0x48, 0x24, 0x00, 0x09, 0x00, 0x40, 0xc0, + 0x02, 0x80, 0x00, 0x28, 0x40, 0x28, 0x00, 0x02, + 0x82, 0x04, 0x80, 0x00, 0x2c, 0x00, 0x28, 0x00, + 0x02, 0x40, 0x00, 0x80, 0x00, 0x24, 0x00, 0x09, + 0x34, 0x02, 0xce, 0x10, 0xb3, 0xe0, 0x22, 0x40, + 0x08, 0x30, 0x42, 0xf9, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0x40, 0x5e, 0x02, 0x86, 0x81, + 0x6d, 0xe4, 0x0b, 0x78, 0x02, 0xd6, 0x00, 0x87, + 0x90, 0x21, 0xe2, 0x4b, 0x78, 0x06, 0xd6, 0x00, + 0x86, 0x80, 0x2d, 0x20, 0x09, 0x78, 0x02, 0xce, + 0x00, 0x02, 0x80, 0x21, 0x60, 0x08, 0xd8, 0x2a, + 0x4e, 0x00, 0x87, 0x80, 0x2d, 0x64, 0x02, 0x08, + 0x02, 0x8e, 0x40, 0x95, 0x80, 0x6d, 0xe0, 0x4b, + 0x79, 0x06, 0xda, 0x28, 0x87, 0x80, 0x21, 0x70, + 0x08, 0x78, 0x00, 0xc8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x18, 0x6c, 0x00, 0xc1, 0x00, + 0x3c, 0xc4, 0x0f, 0x00, 0x03, 0xec, 0x02, 0xd3, + 0x00, 0xb0, 0xc4, 0x0f, 0x30, 0x03, 0xcc, 0x40, + 0xe3, 0x50, 0x24, 0xc8, 0x0d, 0x32, 0x01, 0xc4, + 0x00, 0xc3, 0x00, 0x38, 0xd0, 0x0c, 0x30, 0x03, + 0xc4, 0x50, 0xc1, 0x10, 0x3c, 0xc4, 0x0a, 0x31, + 0x03, 0x4c, 0x00, 0xf3, 0x00, 0x34, 0xd4, 0x0f, + 0x31, 0x03, 0xcc, 0x00, 0x73, 0x10, 0x20, 0x44, + 0x0c, 0x30, 0x01, 0xd2, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x40, 0xff, 0x00, + 0x3f, 0xc5, 0x0f, 0xf1, 0x03, 0xf8, 0x00, 0xff, + 0x00, 0x3f, 0xc2, 0x0f, 0xf0, 0xa3, 0xfc, 0x00, + 0xdf, 0x04, 0xed, 0x09, 0x00, 0x16, 0x01, 0x3f, + 0xc0, 0x0f, 0xf0, 0x07, 0xfc, 0x00, 0xff, 0x10, + 0x3f, 0xc0, 0x0c, 0xd0, 0x03, 0xfc, 0x40, 0xff, + 0x01, 0x3f, 0xc4, 0x0d, 0xf1, 0x43, 0x7c, 0x00, + 0xcf, 0x10, 0x17, 0xc4, 0x0f, 0xf1, 0x43, 0xfc, + 0x40, 0xdf, 0x10, 0x3f, 0x44, 0x0f, 0xf0, 0x03, + 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0xac, 0x80, 0xfb, 0x00, 0x3e, 0xca, 0x0c, + 0xb8, 0x0b, 0x2c, 0x00, 0xfb, 0x02, 0x22, 0xc8, + 0x0f, 0xb0, 0x03, 0x6c, 0x00, 0xf9, 0x00, 0x3e, + 0xc0, 0x0f, 0x88, 0x03, 0x68, 0x04, 0xf9, 0x00, + 0x3c, 0xc0, 0x06, 0x90, 0x03, 0xe8, 0x04, 0xfa, + 0x00, 0x3e, 0xe0, 0x0c, 0xb0, 0x03, 0xe2, 0x00, + 0xea, 0x80, 0x3a, 0x00, 0x0f, 0xa0, 0x03, 0x06, + 0x00, 0xfb, 0x0e, 0x3e, 0xc0, 0x0f, 0xb0, 0x13, + 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0x98, 0x9d, 0x20, 0xb7, 0x03, 0x2d, 0xc8, 0x0c, + 0xf0, 0x02, 0x1c, 0x00, 0xb7, 0x02, 0x21, 0xcc, + 0x0f, 0x73, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x30, 0x02, 0x1c, 0x00, 0x17, 0x00, + 0x2d, 0xc0, 0x08, 0x50, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x25, 0xc0, 0x0f, 0x70, 0x02, 0xcc, 0x08, + 0x87, 0x00, 0x29, 0xc0, 0x0b, 0xf0, 0x43, 0xd0, + 0x00, 0x87, 0x40, 0x25, 0xc0, 0x8b, 0x70, 0x02, + 0x52, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe4, 0x09, + 0x78, 0x82, 0x5e, 0x00, 0xb7, 0x80, 0x21, 0xe8, + 0x0b, 0x7a, 0x06, 0x5e, 0x10, 0xb7, 0x81, 0x2d, + 0xe0, 0x4b, 0x78, 0x10, 0xde, 0x28, 0xb7, 0x81, + 0x2f, 0xe0, 0x1a, 0x7c, 0x02, 0xde, 0x00, 0xb7, + 0xc2, 0x2c, 0xe0, 0x18, 0x78, 0x02, 0xde, 0x00, + 0xa3, 0x88, 0x2d, 0xe0, 0x0b, 0x68, 0x02, 0x5e, + 0x00, 0x97, 0x84, 0x2d, 0xe0, 0xed, 0x09, 0x00, + 0x17, 0x01, 0x0b, 0x78, 0x02, 0xf0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x04, 0xcc, 0x00, + 0xb0, 0x80, 0x2c, 0xc0, 0x08, 0x0e, 0x02, 0x47, + 0x60, 0xb3, 0x90, 0x20, 0xc0, 0x5b, 0x30, 0x02, + 0xe6, 0x00, 0xb3, 0x40, 0x2c, 0xd0, 0x0b, 0x32, + 0x02, 0x8e, 0x80, 0x93, 0x40, 0x6c, 0xf0, 0x08, + 0x10, 0x02, 0x4f, 0x00, 0xb3, 0x80, 0x24, 0xd0, + 0x0b, 0x38, 0x82, 0xce, 0x00, 0xa3, 0x00, 0x24, + 0xd8, 0x4b, 0x30, 0x22, 0xce, 0x40, 0x83, 0x00, + 0x26, 0xe0, 0x0b, 0x30, 0x02, 0x52, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x15, 0xe8, 0x00, + 0xfe, 0xc8, 0x3e, 0x80, 0x0d, 0xec, 0x03, 0x78, + 0x00, 0xfe, 0x02, 0x32, 0x80, 0x0f, 0xa0, 0x03, + 0x7b, 0x80, 0xfe, 0x20, 0x3f, 0x88, 0x0f, 0xe2, + 0x03, 0xf8, 0x00, 0xfe, 0x20, 0x3d, 0x80, 0x4e, + 0x60, 0x43, 0xfa, 0x80, 0xfe, 0x40, 0x1f, 0xa0, + 0x0c, 0xee, 0x03, 0xf8, 0x00, 0xee, 0x00, 0x3f, + 0x80, 0x07, 0xe1, 0x83, 0x78, 0x00, 0xda, 0x00, + 0x2f, 0xa8, 0x0b, 0xa0, 0x03, 0xfa, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0x80, 0x00, + 0xf8, 0x08, 0x2c, 0x00, 0x2f, 0x80, 0x03, 0xa0, + 0x04, 0xf0, 0x06, 0xb6, 0x10, 0x06, 0x00, 0x03, + 0xe2, 0x00, 0x78, 0x00, 0x3e, 0x00, 0xcb, 0x80, + 0x03, 0x60, 0x01, 0xd8, 0x00, 0x3e, 0x06, 0x0f, + 0x82, 0x03, 0xe0, 0x80, 0xf8, 0x00, 0x0e, 0x07, + 0x1e, 0x80, 0x23, 0xe0, 0x61, 0xd8, 0x00, 0x3a, + 0x04, 0x0f, 0x80, 0x03, 0x61, 0x01, 0xf0, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x52, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xa4, 0x08, + 0xd9, 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x63, 0xe4, + 0x00, 0xf9, 0x08, 0x30, 0x60, 0x0d, 0x90, 0x03, + 0xa4, 0x00, 0xc9, 0x48, 0x3e, 0x43, 0x49, 0x90, + 0xed, 0x09, 0x00, 0x18, 0x01, 0x03, 0xe4, 0x00, + 0xf1, 0x0a, 0x36, 0x48, 0x0d, 0x90, 0x03, 0x04, + 0x00, 0xd9, 0x08, 0x0e, 0x41, 0x0f, 0x90, 0x43, + 0xe5, 0x00, 0xf9, 0x09, 0x3e, 0x41, 0x8f, 0x98, + 0x23, 0x24, 0x04, 0x79, 0x04, 0x32, 0x40, 0x8c, + 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x04, 0x64, 0x00, 0x89, 0x05, 0x2e, + 0x40, 0x28, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, + 0x36, 0x58, 0x08, 0x92, 0x00, 0x24, 0x08, 0x89, + 0x80, 0x2e, 0x62, 0x09, 0x90, 0x12, 0xe4, 0x20, + 0xb9, 0x08, 0x22, 0x60, 0x08, 0x90, 0x13, 0xe4, + 0x00, 0x89, 0x00, 0x26, 0x40, 0x4b, 0x90, 0x82, + 0xe4, 0x21, 0xb9, 0x00, 0x2e, 0x42, 0x0b, 0x91, + 0x42, 0xa5, 0x20, 0xb9, 0x00, 0x22, 0x40, 0x08, + 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x05, 0x24, 0x00, 0x99, 0x00, 0x2e, + 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, + 0x22, 0x44, 0x08, 0x98, 0x02, 0x64, 0x00, 0x99, + 0x00, 0x26, 0x48, 0x09, 0x90, 0x42, 0xe4, 0x00, + 0x89, 0x00, 0x26, 0x40, 0x29, 0x90, 0x46, 0xa4, + 0x11, 0x9b, 0x00, 0x2e, 0x40, 0x08, 0xb0, 0x06, + 0xec, 0x00, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x10, + 0x02, 0xa6, 0x00, 0xb9, 0x20, 0x22, 0x40, 0x08, + 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x14, 0x05, 0xa0, 0x81, 0x40, 0x2c, + 0x50, 0x18, 0x14, 0x02, 0xc5, 0x14, 0xb1, 0x44, + 0x24, 0x40, 0x08, 0x10, 0x02, 0x45, 0x00, 0x91, + 0x00, 0x2c, 0x40, 0x09, 0x10, 0x02, 0xc4, 0x01, + 0xb1, 0x00, 0x22, 0x40, 0x08, 0x98, 0x02, 0xc4, + 0x18, 0x81, 0x00, 0x64, 0x60, 0x0b, 0x10, 0x02, + 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x14, + 0x02, 0x84, 0x00, 0xb3, 0x40, 0x20, 0xd0, 0x40, + 0x10, 0x02, 0xc2, 0xed, 0x09, 0x00, 0x19, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0d, + 0x60, 0x80, 0xd8, 0x00, 0x3c, 0x00, 0x0c, 0x80, + 0x03, 0xe0, 0x00, 0xf0, 0x00, 0x32, 0x00, 0x0d, + 0x80, 0x0b, 0xe0, 0x02, 0xd8, 0x00, 0x26, 0x00, + 0x0d, 0x80, 0x63, 0xe0, 0x00, 0xd8, 0x00, 0x16, + 0x00, 0x0d, 0x80, 0x03, 0x20, 0x00, 0xd8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xd8, + 0x01, 0x3e, 0x00, 0xcf, 0x80, 0x03, 0x20, 0x00, + 0xf8, 0x00, 0x32, 0x00, 0x2c, 0x80, 0x03, 0xee, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x91, + 0xe4, 0x00, 0xfd, 0x00, 0x3e, 0x50, 0x05, 0xd0, + 0x03, 0xf4, 0x00, 0xfd, 0x40, 0x3e, 0x50, 0x2f, + 0x94, 0x43, 0xb4, 0x00, 0xed, 0x40, 0x3f, 0x50, + 0x0f, 0xd4, 0x03, 0xf5, 0x00, 0xbd, 0x40, 0x3f, + 0x50, 0x2b, 0xd0, 0x33, 0x75, 0x00, 0xfd, 0x40, + 0x37, 0x50, 0x0b, 0xd4, 0x03, 0xf5, 0x08, 0xfd, + 0x42, 0x27, 0x50, 0x8b, 0xd4, 0x63, 0xf5, 0x08, + 0xb9, 0x41, 0xbf, 0x50, 0x0f, 0x90, 0x03, 0xe6, + 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, + 0xe5, 0xa0, 0xd9, 0x40, 0x32, 0x40, 0x0c, 0x94, + 0x03, 0x24, 0x40, 0xc9, 0x31, 0x39, 0x48, 0x6c, + 0xd0, 0x03, 0x24, 0x00, 0xf9, 0x00, 0xb2, 0x40, + 0x0c, 0x92, 0x81, 0xe4, 0x08, 0xd9, 0x08, 0x32, + 0x41, 0x0f, 0x10, 0x03, 0xa4, 0x80, 0xf9, 0x20, + 0x32, 0x42, 0x0c, 0x90, 0xa3, 0xa4, 0x20, 0xf9, + 0x00, 0x3e, 0x40, 0x0c, 0xd0, 0x03, 0xd4, 0x00, + 0xfd, 0x40, 0x3f, 0x40, 0x0c, 0x90, 0x03, 0xc6, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, + 0xe0, 0x00, 0x88, 0x00, 0x22, 0x0a, 0x0d, 0x80, + 0x42, 0x20, 0x02, 0x08, 0x72, 0x3e, 0x10, 0x08, + 0x84, 0x0a, 0x28, 0x80, 0xb8, 0x04, 0x22, 0x14, + 0xa2, 0x84, 0x02, 0xe0, 0x00, 0x48, 0xed, 0x09, + 0x00, 0x1a, 0x01, 0x40, 0x22, 0x94, 0x09, 0x80, + 0x42, 0x20, 0x00, 0x98, 0x00, 0x22, 0x00, 0x28, + 0x80, 0x02, 0x20, 0x00, 0xb8, 0x01, 0x2f, 0x00, + 0x0e, 0x82, 0x02, 0xe1, 0x00, 0xb0, 0x42, 0x2e, + 0x18, 0x08, 0x80, 0x02, 0xce, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x84, 0x80, 0x91, + 0x20, 0x20, 0x50, 0x0b, 0x12, 0x12, 0x26, 0x80, + 0x81, 0x00, 0x20, 0x44, 0x09, 0x14, 0x02, 0x04, + 0x30, 0xb5, 0xc0, 0x21, 0x60, 0x09, 0x58, 0x02, + 0xd7, 0x00, 0x95, 0x80, 0x21, 0x41, 0x0b, 0x50, + 0x02, 0x17, 0x00, 0xb5, 0xc4, 0x69, 0x41, 0x0a, + 0x58, 0x02, 0x96, 0x00, 0xb5, 0xc0, 0x2d, 0x70, + 0x0a, 0x14, 0x82, 0xc5, 0x00, 0xb3, 0x60, 0x2c, + 0x52, 0x08, 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x04, 0xa4, 0x00, 0x89, + 0x08, 0x22, 0x40, 0x29, 0x12, 0x82, 0x26, 0x00, + 0x89, 0x00, 0x2e, 0x40, 0x48, 0x90, 0x02, 0x24, + 0x04, 0xb9, 0x00, 0xab, 0x40, 0x09, 0xd1, 0x02, + 0xf4, 0x40, 0x9d, 0x00, 0x23, 0x48, 0x0b, 0xd0, + 0x02, 0x34, 0x00, 0x9d, 0x02, 0xa3, 0x50, 0x08, + 0xd2, 0x02, 0x34, 0x00, 0x3d, 0x20, 0x2f, 0x48, + 0x0a, 0xb0, 0x02, 0xe4, 0x80, 0xb9, 0x02, 0x0c, + 0x40, 0x08, 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x45, 0xe4, 0x00, 0xd9, + 0x90, 0x32, 0x40, 0x06, 0x98, 0x0b, 0x04, 0x08, + 0xc9, 0xe0, 0x22, 0x40, 0x0d, 0x10, 0x03, 0x27, + 0x00, 0xf9, 0x40, 0x32, 0x54, 0x0d, 0x9c, 0x43, + 0xe7, 0x00, 0xd9, 0x40, 0xb2, 0x40, 0x0f, 0x94, + 0xc3, 0xa5, 0x00, 0xf9, 0xc0, 0x3a, 0x50, 0x0e, + 0x94, 0x03, 0xa7, 0x00, 0xf9, 0xc0, 0x3e, 0x70, + 0x0e, 0x90, 0x03, 0xe7, 0x80, 0xf9, 0x00, 0x3e, + 0x40, 0x2c, 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x1b, 0x01, 0x00, 0x00, + 0x48, 0x01, 0xa4, 0x00, 0xf9, 0x00, 0xbe, 0x40, + 0x0e, 0x90, 0x03, 0xe4, 0x08, 0xf1, 0x10, 0x3e, + 0x40, 0x0f, 0x90, 0x83, 0xe6, 0x80, 0xf9, 0xa0, + 0x36, 0x60, 0x4e, 0x90, 0x43, 0xc6, 0x00, 0xe9, + 0x40, 0x3e, 0x40, 0x8d, 0x92, 0x0b, 0xe5, 0x00, + 0xf9, 0x42, 0x3c, 0x48, 0x0f, 0x10, 0x03, 0xe5, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x13, + 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x80, 0x00, 0xf8, 0x40, 0x3e, 0x00, + 0x0f, 0x84, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0xb2, + 0x02, 0x0c, 0x80, 0x13, 0x21, 0x00, 0xf0, 0x00, + 0x38, 0x00, 0x0f, 0x80, 0x03, 0x20, 0x00, 0xd0, + 0x02, 0x3e, 0x00, 0x0c, 0x84, 0x03, 0xa0, 0x00, + 0xf0, 0x00, 0xb2, 0x00, 0x8e, 0x80, 0x0b, 0x20, + 0x00, 0xf8, 0x00, 0xb2, 0x00, 0x0c, 0x82, 0x63, + 0x21, 0x80, 0xe8, 0x08, 0x32, 0x20, 0x2c, 0x80, + 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x11, 0xa8, 0x00, 0xba, 0x00, 0x2e, 0x81, + 0x0c, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x21, + 0x88, 0x8a, 0xe0, 0x22, 0x28, 0x00, 0xba, 0x04, + 0x2a, 0x80, 0x0b, 0xa0, 0x02, 0x28, 0x00, 0xba, + 0x02, 0x2e, 0x94, 0x08, 0x20, 0x02, 0x28, 0x01, + 0xba, 0x80, 0x22, 0x80, 0x08, 0xa8, 0x02, 0x28, + 0x00, 0xba, 0x80, 0x22, 0x80, 0x8d, 0xe0, 0x02, + 0xb8, 0x20, 0xae, 0x00, 0x23, 0x80, 0x08, 0xa0, + 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x04, 0x4c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x28, + 0x10, 0x08, 0x0c, 0x02, 0x0c, 0x00, 0xb3, 0x00, + 0x28, 0xc0, 0x0b, 0x38, 0x02, 0x0c, 0x00, 0x93, + 0x00, 0x2c, 0xd0, 0x29, 0xed, 0x09, 0x00, 0x1c, + 0x01, 0x30, 0x4a, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0a, 0x30, 0x12, 0x0c, 0x04, 0x93, 0x00, + 0x24, 0xe0, 0x0a, 0x34, 0x02, 0x0c, 0x00, 0xa3, + 0x40, 0x28, 0xe0, 0x0a, 0x30, 0x02, 0xca, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x5c, + 0x40, 0xb7, 0x00, 0x2d, 0xc8, 0x08, 0x70, 0x02, + 0xdc, 0x10, 0xb7, 0x02, 0x29, 0xc0, 0x0a, 0x34, + 0x12, 0x1c, 0x80, 0x32, 0x00, 0x29, 0xc0, 0x8b, + 0x6c, 0x02, 0x14, 0x00, 0xb5, 0x00, 0x2d, 0xe1, + 0x09, 0x50, 0x02, 0x10, 0x00, 0xb6, 0x08, 0x2f, + 0x40, 0x08, 0x70, 0x82, 0x1c, 0x00, 0xb6, 0x8a, + 0x05, 0xf0, 0x0b, 0x78, 0x82, 0x9e, 0x00, 0x85, + 0x80, 0xab, 0xc2, 0x08, 0x70, 0x02, 0xe8, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x5e, + 0x88, 0xf7, 0xf1, 0x3d, 0xe4, 0x0f, 0x7a, 0x13, + 0xde, 0x80, 0xff, 0xa8, 0x39, 0xe0, 0x0c, 0x78, + 0x0b, 0x1e, 0x40, 0xf5, 0x80, 0x39, 0x20, 0x0f, + 0x38, 0x09, 0x1a, 0x00, 0xd6, 0x80, 0x3d, 0x60, + 0x0d, 0x68, 0x03, 0x1e, 0x00, 0xb3, 0x80, 0x3d, + 0xa1, 0x0e, 0x28, 0x03, 0x12, 0x04, 0xd3, 0x80, + 0x14, 0xa0, 0x2e, 0x38, 0x43, 0x1e, 0x00, 0xe5, + 0x80, 0x19, 0xa0, 0x2c, 0x78, 0x03, 0xea, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x45, 0xad, + 0x20, 0xfb, 0x20, 0x3e, 0xdd, 0x0a, 0xb6, 0x83, + 0xed, 0xe0, 0xfb, 0x34, 0x36, 0xc0, 0x0f, 0x90, + 0x01, 0xed, 0x80, 0xf8, 0x00, 0x36, 0x00, 0x0f, + 0xa0, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x34, 0x40, + 0x0e, 0x80, 0x01, 0xe0, 0x00, 0xfa, 0x00, 0x30, + 0x00, 0x0f, 0xa0, 0x03, 0xe0, 0x00, 0xba, 0x00, + 0x3a, 0x80, 0x8c, 0xb0, 0x03, 0xe4, 0x00, 0xf8, + 0x01, 0x34, 0xc0, 0x0f, 0xb0, 0x03, 0xc2, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xed, + 0x09, 0x00, 0x1d, 0x01, 0xbe, 0x00, 0xef, 0x80, + 0x3b, 0xc0, 0x2c, 0x78, 0x83, 0x9e, 0x00, 0xef, + 0x80, 0x33, 0xe0, 0x2c, 0xf8, 0x03, 0xfe, 0x24, + 0x7f, 0x82, 0x3f, 0xe0, 0x0f, 0xd8, 0x13, 0xfe, + 0x00, 0xff, 0x80, 0x3f, 0xa0, 0x0f, 0xf8, 0x43, + 0xbe, 0x00, 0xfd, 0x80, 0x3f, 0xe0, 0x0e, 0xd8, + 0x03, 0xfe, 0x00, 0xdd, 0x80, 0x37, 0x60, 0x0c, + 0xda, 0x03, 0xfe, 0x00, 0xec, 0x21, 0xb3, 0xe0, + 0x0f, 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x18, 0x9c, 0x00, 0xb7, 0x10, + 0x21, 0xc0, 0x0d, 0x70, 0x02, 0x1c, 0x40, 0x87, + 0x00, 0xa1, 0x88, 0x08, 0x60, 0x02, 0xdc, 0x00, + 0xb6, 0x00, 0x2d, 0xc0, 0x0e, 0x40, 0x02, 0xd4, + 0x00, 0xb5, 0x00, 0x2d, 0x84, 0x0b, 0x51, 0x03, + 0x50, 0x00, 0xb4, 0x00, 0x2d, 0x46, 0x0a, 0x50, + 0x42, 0xdc, 0x00, 0xb4, 0x10, 0x29, 0x48, 0x4c, + 0x50, 0x02, 0xdc, 0x00, 0xad, 0x10, 0x21, 0x08, + 0x0b, 0x70, 0x02, 0x6a, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xaf, 0x00, + 0x29, 0xc0, 0x09, 0xf0, 0x02, 0xbc, 0x20, 0xb3, + 0x00, 0xa0, 0x40, 0x19, 0x70, 0x02, 0x5c, 0x00, + 0x95, 0x00, 0x2d, 0x00, 0x09, 0x50, 0x02, 0xd8, + 0x00, 0xb6, 0x00, 0x29, 0x00, 0x0b, 0xe0, 0x82, + 0xdc, 0x00, 0xb5, 0x00, 0x2d, 0x80, 0x0a, 0x40, + 0x02, 0xd0, 0x00, 0xb1, 0x00, 0x25, 0x00, 0x68, + 0x72, 0x86, 0xc8, 0x00, 0x86, 0x00, 0x21, 0x80, + 0x1b, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x04, 0x8c, 0x00, 0xb3, 0x81, + 0x20, 0xc0, 0x89, 0x30, 0x82, 0x0f, 0x80, 0x93, + 0x00, 0x24, 0xc0, 0x09, 0x30, 0x02, 0xcd, 0x08, + 0xb0, 0x00, 0x2c, 0x00, 0x0a, 0x04, 0x82, 0xc1, + 0x00, 0xb0, 0x20, 0x2c, 0x00, 0x0b, 0x06, 0x02, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x1e, 0x01, 0xb0, + 0x42, 0x2c, 0x08, 0x08, 0x04, 0x02, 0xc0, 0x01, + 0xb0, 0x00, 0x24, 0x02, 0x08, 0x34, 0x80, 0xc1, + 0x20, 0xa0, 0x02, 0x22, 0x02, 0x0b, 0x30, 0x02, + 0x48, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x15, 0xbc, 0x00, 0xe7, 0x61, 0x3b, 0xc0, 0x1d, + 0xfe, 0x03, 0xbf, 0x00, 0xff, 0x18, 0x32, 0xc0, + 0x0d, 0x30, 0x03, 0xdc, 0x00, 0xdb, 0x90, 0x3e, + 0xe4, 0x0f, 0xbc, 0x03, 0xee, 0x00, 0xfb, 0x80, + 0x3c, 0xe0, 0x0b, 0x30, 0x02, 0xee, 0x40, 0xfb, + 0x90, 0x3e, 0xe0, 0x0e, 0xb8, 0x13, 0xee, 0x08, + 0xdb, 0x80, 0x36, 0xf0, 0x4c, 0xa4, 0x43, 0xed, + 0x00, 0xcb, 0x00, 0x32, 0x40, 0x0f, 0xb0, 0x03, + 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0xec, 0x00, 0xfb, 0x20, 0x3e, 0xc0, 0x0e, + 0xb0, 0x13, 0xec, 0x00, 0xe3, 0x00, 0x3a, 0x40, + 0x0e, 0xb4, 0x03, 0xee, 0x80, 0xfa, 0x80, 0x3e, + 0xe1, 0x0f, 0xa8, 0x03, 0xc6, 0x80, 0xf9, 0x80, + 0x3e, 0xe8, 0x0f, 0x90, 0x0b, 0xc2, 0x00, 0xfa, + 0x80, 0x3e, 0x40, 0x0f, 0xba, 0x03, 0xee, 0x20, + 0xfa, 0x88, 0x38, 0xe0, 0x0e, 0xb0, 0x03, 0xe9, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x10, 0xfc, 0x00, 0xcf, 0x00, 0x36, 0xc0, 0x02, + 0xf0, 0x03, 0x3c, 0x00, 0xcf, 0x00, 0x33, 0xa0, + 0x0f, 0xe1, 0x03, 0x7c, 0x01, 0xc5, 0x00, 0x71, + 0x00, 0x0d, 0x70, 0x02, 0xb8, 0x00, 0xee, 0x00, + 0x27, 0x40, 0x0c, 0xe0, 0x03, 0x3c, 0x00, 0xcf, + 0x00, 0x3c, 0x80, 0x06, 0xe0, 0x03, 0xd0, 0x00, + 0xdf, 0x00, 0x36, 0x80, 0x2c, 0x6c, 0x03, 0x1e, + 0x90, 0xcd, 0x00, 0x3f, 0x00, 0x0c, 0xf0, 0x03, + 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa1, + 0x04, 0x6c, 0x00, 0x8b, 0x02, 0xed, 0x09, 0x00, + 0x1f, 0x01, 0x22, 0xc0, 0x0b, 0x30, 0x02, 0xac, + 0x00, 0x8b, 0x00, 0x3e, 0xe8, 0x0b, 0xb8, 0x02, + 0x2c, 0x10, 0xa8, 0x00, 0xb6, 0x00, 0x08, 0xa0, + 0x02, 0x20, 0x00, 0x88, 0x01, 0x2e, 0x40, 0x0d, + 0x80, 0x13, 0x60, 0x02, 0x8a, 0x00, 0x2e, 0x00, + 0x0f, 0xa0, 0x02, 0xe0, 0x00, 0x8a, 0x00, 0x2e, + 0x80, 0x08, 0xbc, 0x02, 0xa0, 0x20, 0xda, 0x00, + 0x2e, 0xc0, 0x08, 0xb0, 0x02, 0xe0, 0x40, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x0c, 0x02, + 0x8b, 0x00, 0x26, 0xc0, 0x0a, 0xb0, 0x02, 0x0c, + 0x00, 0xab, 0x00, 0x22, 0xc8, 0x0b, 0x94, 0x0a, + 0xac, 0x00, 0x8b, 0x00, 0x22, 0xc0, 0x4b, 0x90, + 0x26, 0xac, 0x00, 0xab, 0x01, 0x6e, 0x80, 0x09, + 0xb0, 0x02, 0xac, 0x00, 0x89, 0x00, 0x26, 0xc0, + 0x08, 0x90, 0x02, 0xec, 0x00, 0x99, 0x00, 0x0e, + 0x40, 0x08, 0xb0, 0x02, 0xa4, 0x00, 0x88, 0x80, + 0x2e, 0x48, 0x09, 0xb0, 0x02, 0xe0, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x14, 0x0c, 0x00, + 0x8b, 0x00, 0x24, 0xc0, 0x1b, 0xb0, 0x12, 0x8c, + 0x00, 0xa3, 0x00, 0x0c, 0xc0, 0x1b, 0x30, 0x02, + 0xac, 0x00, 0xa2, 0x00, 0x20, 0xc0, 0x0a, 0x00, + 0x26, 0x84, 0x01, 0x81, 0x00, 0x2e, 0x80, 0x29, + 0x90, 0x02, 0x40, 0x00, 0x80, 0x00, 0x2c, 0x40, + 0x0a, 0x10, 0x02, 0xcc, 0x00, 0x80, 0x00, 0x24, + 0x40, 0x08, 0x30, 0x26, 0x80, 0x00, 0x13, 0x00, + 0x2c, 0x00, 0x29, 0x30, 0x02, 0xc2, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x8d, 0x7c, 0x00, + 0xcf, 0x00, 0x37, 0xc0, 0x8e, 0xf0, 0x02, 0x3c, + 0x02, 0xef, 0x01, 0x32, 0xc0, 0x8f, 0xb0, 0x03, + 0xfc, 0x00, 0x89, 0x00, 0x22, 0x00, 0x0f, 0x90, + 0x03, 0xa8, 0x00, 0xaa, 0x00, 0x36, 0x00, 0x1c, + 0xa0, 0x03, 0xac, 0x00, 0xc9, 0x00, 0x3e, 0x80, + 0xed, 0x09, 0x00, 0x20, 0x01, 0x0a, 0x80, 0x03, + 0xe0, 0x00, 0xd9, 0x00, 0x3e, 0x00, 0x0c, 0xb0, + 0x03, 0xa0, 0x00, 0xca, 0x00, 0x3e, 0x00, 0x0d, + 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x01, 0xfc, 0x10, 0xf7, 0x00, 0x3b, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xdf, 0x00, + 0x3f, 0x00, 0x0d, 0xc0, 0x03, 0x7c, 0x00, 0xfc, + 0x00, 0x3f, 0x00, 0x0d, 0xc0, 0x03, 0x70, 0x00, + 0xfc, 0x00, 0x37, 0x00, 0x0f, 0x40, 0x03, 0x70, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, + 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xf0, + 0x23, 0xf0, 0x00, 0x7e, 0x00, 0x3f, 0x00, 0x0e, + 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x05, 0xfc, 0x40, 0xfe, 0x00, 0x3d, + 0xc0, 0x0c, 0xc0, 0x03, 0x50, 0x00, 0xdc, 0x00, + 0x1b, 0x00, 0x0c, 0xc0, 0x03, 0x50, 0x02, 0xd6, + 0x00, 0x21, 0xc0, 0x0f, 0xf0, 0x03, 0xb8, 0x00, + 0xce, 0x00, 0x37, 0x00, 0x0f, 0xc0, 0x23, 0xf0, + 0x00, 0xfd, 0x00, 0x37, 0x80, 0x0f, 0xf0, 0x03, + 0x38, 0x00, 0xff, 0x00, 0x3f, 0x08, 0x09, 0xc3, + 0x83, 0xf0, 0xd1, 0xfc, 0x24, 0x33, 0x08, 0x0d, + 0xc1, 0x03, 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x08, 0xa0, 0x02, 0x24, 0x00, 0xb8, 0x04, + 0x22, 0x00, 0x88, 0x81, 0x12, 0xa0, 0x04, 0xaa, + 0x00, 0x22, 0x40, 0x0e, 0xb0, 0x03, 0x24, 0x00, + 0x8a, 0x02, 0x22, 0x01, 0x49, 0x80, 0x02, 0xe0, + 0x00, 0xbb, 0x00, 0x2e, 0x80, 0x0b, 0xb0, 0x03, + 0x68, 0x04, 0xbb, 0x00, 0x2c, 0x58, 0x08, 0x06, + 0x42, 0xe0, 0xc0, 0xba, 0x30, 0x20, 0x50, 0x48, + 0x83, 0x22, 0xa0, 0x06, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x88, 0x05, 0xcc, 0x00, 0xb1, 0x00, 0x2c, + 0xc0, 0x48, 0x80, 0xed, 0x09, 0x00, 0x21, 0x01, + 0x12, 0x40, 0x10, 0x90, 0x02, 0x2c, 0x04, 0x18, + 0x20, 0x02, 0x40, 0x0a, 0x82, 0x00, 0xa0, 0x40, + 0x8b, 0xa0, 0x02, 0xac, 0x00, 0xa8, 0x00, 0x20, + 0x00, 0x0b, 0x08, 0x02, 0x82, 0x00, 0xb3, 0x00, + 0x2c, 0x80, 0x0b, 0x30, 0x02, 0x08, 0x00, 0xb3, + 0x00, 0x2c, 0x86, 0x0a, 0x00, 0x02, 0xc0, 0x80, + 0xa1, 0x08, 0x20, 0x07, 0x0b, 0x00, 0x76, 0x22, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, + 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x18, 0xb4, + 0x0a, 0x25, 0x80, 0xba, 0x40, 0x26, 0x20, 0x48, + 0xac, 0x1a, 0xaa, 0x10, 0xaa, 0x00, 0x22, 0x48, + 0x0a, 0xa6, 0x02, 0xa4, 0x40, 0xa9, 0x20, 0xa2, + 0x20, 0x89, 0x98, 0x02, 0xe0, 0x00, 0xbb, 0x80, + 0x2e, 0x80, 0x0b, 0xb0, 0x02, 0x60, 0x80, 0x3b, + 0x00, 0x2e, 0x42, 0x8a, 0x98, 0x82, 0xe9, 0x80, + 0xb3, 0x00, 0x22, 0x41, 0x0a, 0x91, 0x06, 0xb8, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, + 0xec, 0x00, 0xfa, 0x08, 0x3e, 0x40, 0x2c, 0x30, + 0x03, 0x66, 0x00, 0xd8, 0xc4, 0x3c, 0xb2, 0x2c, + 0x88, 0x43, 0x44, 0x04, 0xda, 0xe0, 0x32, 0xc0, + 0x0f, 0x90, 0x42, 0xac, 0x00, 0xea, 0xa2, 0x76, + 0x20, 0x0f, 0x88, 0x03, 0xe0, 0x00, 0xb8, 0xc0, + 0x36, 0xa4, 0x0f, 0x30, 0x03, 0x2a, 0x00, 0xfb, + 0x00, 0x3e, 0x20, 0x0f, 0x80, 0x03, 0xe3, 0x00, + 0xf8, 0x00, 0x32, 0x86, 0x0f, 0x80, 0x2b, 0x10, + 0x44, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, + 0xbc, 0x00, 0xfe, 0x00, 0x3f, 0x40, 0x0f, 0xf0, + 0x13, 0xfe, 0x00, 0xfc, 0x10, 0x3b, 0x80, 0x0f, + 0x00, 0x03, 0xf8, 0x10, 0x9e, 0x91, 0x3f, 0x40, + 0x0e, 0xd0, 0x03, 0x3c, 0x00, 0xdf, 0x81, 0x3f, + 0x00, 0x0f, 0xd0, 0x03, 0xf0, 0x00, 0xff, 0x00, + 0x3f, 0x20, 0x0f, 0xf0, 0x03, 0xf8, 0xed, 0x09, + 0x00, 0x22, 0x01, 0x00, 0xff, 0x00, 0x3f, 0x24, + 0x0d, 0xf0, 0x82, 0xe6, 0x00, 0xfd, 0x00, 0x3d, + 0xc2, 0x49, 0x70, 0x83, 0xf8, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x10, 0xae, 0x20, 0xf9, + 0x42, 0x3e, 0xd1, 0x2c, 0xb4, 0x03, 0x25, 0x40, + 0xc8, 0x40, 0x3e, 0x80, 0x8f, 0xa0, 0x0b, 0x64, + 0x08, 0xc9, 0x50, 0x36, 0x40, 0x0e, 0x90, 0x03, + 0xec, 0x00, 0xda, 0x20, 0x3e, 0x30, 0x0d, 0x80, + 0x43, 0x20, 0x00, 0xcb, 0x80, 0xb2, 0xc0, 0x0f, + 0xb1, 0x03, 0xe8, 0x00, 0xdb, 0x00, 0x3a, 0x9c, + 0x0f, 0xa0, 0x03, 0x2d, 0x20, 0xea, 0x01, 0x76, + 0x80, 0x0c, 0xa8, 0x03, 0x10, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2d, 0x00, 0xbb, + 0x41, 0x2c, 0xf0, 0x28, 0xb6, 0x02, 0x26, 0x00, + 0x00, 0x80, 0x2e, 0x80, 0x0b, 0xa4, 0x82, 0x2a, + 0x80, 0xd3, 0x01, 0x22, 0xc8, 0x08, 0x10, 0x02, + 0xcf, 0x84, 0x83, 0xc8, 0x2e, 0x34, 0x06, 0x95, + 0x02, 0xa8, 0x00, 0x8b, 0x00, 0x22, 0xe0, 0x0b, + 0xb4, 0x02, 0xe8, 0x00, 0xbb, 0x00, 0x2e, 0x20, + 0x08, 0xb8, 0x02, 0x2f, 0x00, 0xdb, 0x50, 0x76, + 0xd0, 0x08, 0xb4, 0x42, 0x32, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, 0x00, 0xb3, + 0xc8, 0x2c, 0x86, 0x29, 0x08, 0x02, 0x03, 0x20, + 0x00, 0x80, 0x2c, 0x01, 0x0b, 0x0e, 0x02, 0xc1, + 0x38, 0x82, 0xc8, 0x24, 0xe2, 0x1a, 0x30, 0x20, + 0xca, 0x01, 0x12, 0xc0, 0x2c, 0x10, 0x09, 0x00, + 0x02, 0x00, 0x20, 0x83, 0x08, 0x20, 0xa0, 0x0b, + 0x3a, 0x02, 0xc8, 0x00, 0x93, 0x00, 0x6a, 0x30, + 0x18, 0x00, 0x02, 0x80, 0x40, 0x80, 0x00, 0x20, + 0x04, 0x08, 0x04, 0x0a, 0x78, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x01, 0x1e, 0x00, 0xb6, + 0x8a, 0x2f, 0xe0, 0x69, 0xfc, 0x02, 0x16, 0x00, + 0x84, 0xed, 0x09, 0x00, 0x23, 0x01, 0x80, 0x2d, + 0xa0, 0x0b, 0x49, 0x02, 0x9a, 0x40, 0x96, 0x80, + 0x25, 0xe5, 0x00, 0x78, 0x02, 0xdf, 0x01, 0x86, + 0x90, 0x2d, 0x25, 0x8a, 0x48, 0x06, 0xb2, 0x20, + 0x8f, 0x80, 0x21, 0xa0, 0x4b, 0x78, 0x02, 0xda, + 0x00, 0xb7, 0x80, 0x2d, 0xe4, 0x28, 0x6a, 0x8a, + 0x1e, 0x04, 0x96, 0x80, 0x25, 0x20, 0x28, 0x28, + 0x02, 0x48, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x08, 0x0c, 0x00, 0xf1, 0x00, 0x3c, 0xc4, + 0x09, 0x01, 0x03, 0x08, 0x00, 0xc2, 0x18, 0x7c, + 0x80, 0x0f, 0x21, 0x03, 0xc0, 0x00, 0x82, 0x20, + 0x34, 0x90, 0x0e, 0x30, 0x03, 0xcc, 0x00, 0xd3, + 0x04, 0x7c, 0x10, 0x0d, 0x91, 0x13, 0x00, 0x02, + 0xc3, 0x05, 0x30, 0x82, 0x0b, 0x30, 0x02, 0xc8, + 0x40, 0xd3, 0x00, 0x38, 0x84, 0x1e, 0x30, 0x43, + 0x04, 0x02, 0xc9, 0x04, 0x30, 0x81, 0xcc, 0x31, + 0x03, 0x5a, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x01, 0x3f, 0xc0, + 0x0e, 0x70, 0x03, 0xf8, 0x40, 0x3e, 0x00, 0x2f, + 0xc0, 0x0f, 0xf1, 0x43, 0x38, 0x00, 0xde, 0x00, + 0x3b, 0x80, 0x8f, 0xf0, 0x00, 0xd4, 0x00, 0xff, + 0x04, 0x3f, 0x41, 0x0e, 0xf0, 0x53, 0xd0, 0x00, + 0xf7, 0x00, 0x3f, 0x80, 0x0f, 0xf0, 0x03, 0xf8, + 0x00, 0xff, 0x01, 0x3f, 0xc4, 0x1e, 0xf2, 0x03, + 0xfc, 0x08, 0xef, 0x10, 0x3f, 0x84, 0x0f, 0xf0, + 0x03, 0x90, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x05, 0xec, 0x00, 0xfa, 0x00, 0x3e, 0x40, + 0x06, 0xb0, 0x03, 0xe4, 0x00, 0xc8, 0x00, 0x3e, + 0x80, 0x0c, 0x80, 0x0a, 0x24, 0x00, 0xda, 0x00, + 0x3c, 0xe0, 0x2a, 0xb0, 0x23, 0xec, 0x00, 0xeb, + 0x00, 0x30, 0xa0, 0x2c, 0x90, 0x13, 0xe0, 0x00, + 0x7b, 0x80, 0x3a, 0xa0, 0x0c, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xed, 0x09, 0x00, 0x24, + 0x01, 0x40, 0x08, 0x98, 0x03, 0x28, 0x00, 0xf8, + 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xca, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, + 0x00, 0xb6, 0x01, 0x2d, 0x40, 0x0f, 0x70, 0x02, + 0xd4, 0x00, 0x85, 0x02, 0x2d, 0x80, 0x08, 0x60, + 0x02, 0x98, 0x00, 0x86, 0x00, 0x2d, 0xc0, 0x08, + 0x50, 0x02, 0xdc, 0x00, 0x87, 0x01, 0x21, 0xc0, + 0x0a, 0x50, 0x02, 0xd0, 0x00, 0xe7, 0x00, 0x21, + 0x80, 0x4d, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2c, 0xc0, 0x08, 0x30, 0x10, 0x1c, 0x10, 0xb5, + 0x00, 0x2c, 0x40, 0x00, 0x70, 0x02, 0xd3, 0x26, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, + 0x00, 0xb5, 0x80, 0x2d, 0xe0, 0x8b, 0x7c, 0x12, + 0xd6, 0x30, 0x85, 0x8c, 0x2d, 0xe2, 0x08, 0x38, + 0x02, 0x36, 0x10, 0x86, 0x80, 0x2f, 0x60, 0x08, + 0x58, 0x22, 0xd7, 0x00, 0xa7, 0x88, 0x23, 0xa0, + 0x08, 0x58, 0x02, 0xd2, 0x01, 0xb7, 0x80, 0x2d, + 0xe0, 0x08, 0x78, 0x02, 0xdf, 0x00, 0xb7, 0x85, + 0x2d, 0xe0, 0x98, 0x78, 0x12, 0x9e, 0x08, 0xb6, + 0x80, 0x6d, 0xe0, 0x08, 0x78, 0x06, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xe0, 0x0b, 0x38, 0x02, + 0xc4, 0x08, 0x81, 0x02, 0x2c, 0xd0, 0x58, 0x3c, + 0x02, 0x8c, 0x02, 0x83, 0x10, 0x2c, 0xe0, 0x0a, + 0x11, 0x02, 0xce, 0x00, 0x83, 0x00, 0x20, 0xe0, + 0x0a, 0x30, 0x02, 0xcc, 0x01, 0xa3, 0x00, 0x24, + 0xe0, 0x09, 0x30, 0x02, 0xcc, 0x00, 0x33, 0x01, + 0x2c, 0xc8, 0x18, 0x38, 0x02, 0x8d, 0x04, 0xb3, + 0x24, 0x6c, 0xc4, 0x48, 0xb6, 0x02, 0xd3, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x11, 0xa8, + 0x00, 0xfe, 0x40, 0x3d, 0x90, 0x4e, 0xec, 0x43, + 0xfb, 0x02, 0xce, 0x42, 0x3d, 0x80, 0x0c, 0xed, + 0x09, 0x00, 0x25, 0x01, 0x63, 0x1b, 0x1b, 0x20, + 0xce, 0xc1, 0x3f, 0x90, 0x0c, 0xe5, 0x03, 0xf9, + 0x00, 0xee, 0xc0, 0x33, 0xb8, 0x0c, 0xe4, 0x03, + 0xf9, 0x00, 0xfe, 0x04, 0x3f, 0xb8, 0x0c, 0xa0, + 0x33, 0xfb, 0x00, 0xfa, 0x00, 0x3f, 0x80, 0x28, + 0xe0, 0xc3, 0x38, 0x28, 0xfe, 0x20, 0x3f, 0xa0, + 0x0c, 0xe6, 0x53, 0xfa, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0xe1, 0x10, 0xf8, 0xc0, + 0x3e, 0x24, 0x0e, 0x8c, 0x03, 0xe3, 0x00, 0xf8, + 0x84, 0x3e, 0x02, 0x6f, 0x80, 0x43, 0xe3, 0x00, + 0xe8, 0xc0, 0x3e, 0x24, 0x05, 0x80, 0x03, 0xe2, + 0x00, 0xf8, 0x80, 0xbe, 0x02, 0x0d, 0x84, 0x83, + 0xe3, 0x10, 0xf8, 0x00, 0x3a, 0x30, 0x0f, 0x80, + 0x03, 0xe2, 0x00, 0xf8, 0x00, 0x3c, 0x00, 0x0f, + 0x80, 0x89, 0x41, 0x21, 0xf0, 0x00, 0x3e, 0x20, + 0x2f, 0x84, 0x03, 0xd2, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, 0xa0, + 0x3a, 0x48, 0x0d, 0x92, 0x0b, 0x27, 0x00, 0xc9, + 0x00, 0x7e, 0x40, 0x0c, 0x9c, 0x03, 0x26, 0x00, + 0xc9, 0x90, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0x26, + 0x00, 0xc9, 0x00, 0x26, 0x60, 0x0e, 0x9c, 0x01, + 0xe7, 0x00, 0xc9, 0x08, 0x3e, 0x44, 0x0e, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x64, 0x0e, + 0x99, 0x43, 0x66, 0x80, 0xe9, 0x02, 0x30, 0x44, + 0x0c, 0x90, 0x0b, 0x82, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, 0xb1, 0x40, + 0x22, 0x42, 0x4c, 0x14, 0x02, 0x06, 0x00, 0xd9, + 0x80, 0x2e, 0x70, 0x08, 0x9c, 0x08, 0x24, 0x82, + 0x89, 0x20, 0x2e, 0x70, 0x4b, 0x18, 0x03, 0x47, + 0x40, 0x81, 0x80, 0x22, 0x64, 0x0b, 0x9c, 0x22, + 0xc5, 0x00, 0x89, 0x02, 0x2e, 0x48, 0x0b, 0x94, + 0x02, 0xe4, 0x00, 0xb9, 0x01, 0x2e, 0x72, 0x08, + 0x98, 0x02, 0xed, 0x09, 0x00, 0x26, 0x01, 0xe7, + 0x00, 0x89, 0xd0, 0x22, 0x40, 0x02, 0x95, 0x02, + 0x28, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x26, 0x00, 0xb9, 0x00, 0xae, 0xc0, 0x08, + 0x94, 0x02, 0x25, 0x10, 0x89, 0x80, 0x2e, 0x58, + 0x08, 0x94, 0x02, 0x2c, 0x80, 0x89, 0x00, 0x2e, + 0x44, 0x4b, 0x91, 0x42, 0x24, 0x22, 0x89, 0x84, + 0x2e, 0x40, 0x0a, 0x90, 0x02, 0xe4, 0x00, 0x8b, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x82, 0xec, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0a, 0x90, 0x80, 0xe5, + 0x00, 0xa9, 0x00, 0x26, 0x42, 0xcb, 0xb0, 0x02, + 0x06, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x05, 0x00, 0xb9, 0x00, 0xe6, 0x50, 0x08, + 0x10, 0x02, 0x04, 0x00, 0x91, 0x00, 0x2c, 0x41, + 0x28, 0x10, 0x02, 0x24, 0x00, 0x81, 0x00, 0x2c, + 0x40, 0x0b, 0x90, 0x02, 0x44, 0x00, 0x89, 0x80, + 0x24, 0xd0, 0x0b, 0x14, 0x02, 0xec, 0x0c, 0x01, + 0xc2, 0x2c, 0x40, 0x8b, 0x10, 0x02, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x50, 0x08, 0x14, 0x02, 0xc5, + 0x00, 0x83, 0x41, 0xa4, 0x50, 0x8b, 0x34, 0x02, + 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, + 0x0d, 0x68, 0x00, 0xfa, 0x00, 0x3e, 0x00, 0x2c, + 0x80, 0x13, 0x20, 0x02, 0xc8, 0x00, 0x2e, 0x00, + 0x0c, 0x80, 0x43, 0x20, 0x04, 0xc8, 0x02, 0x3e, + 0x80, 0x0f, 0x80, 0x03, 0x20, 0x08, 0xc8, 0x00, + 0x3e, 0x00, 0x0e, 0xa0, 0x03, 0xe0, 0x02, 0xc0, + 0x00, 0x3e, 0x00, 0x0e, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x1e, 0x80, 0x03, 0x60, + 0x00, 0xe8, 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03, + 0xae, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x1d, 0xe4, 0x00, 0xfd, 0x00, 0x3b, 0x40, 0x0f, + 0xf0, 0x13, 0xd4, 0x00, 0x7d, 0x04, 0x3d, 0x50, + 0x4f, 0xd4, 0x03, 0xdc, 0x08, 0xed, 0x09, 0x00, + 0x27, 0x01, 0xfd, 0x00, 0x3f, 0x40, 0x0f, 0xd0, + 0x03, 0x54, 0x00, 0xf5, 0x00, 0xbb, 0x50, 0x0f, + 0xd4, 0x03, 0xf4, 0x00, 0xfd, 0x40, 0x3d, 0xc0, + 0x0f, 0x90, 0x03, 0xf4, 0x00, 0xf9, 0x00, 0x3f, + 0x50, 0x8f, 0xd4, 0x03, 0xf5, 0x00, 0xfd, 0x42, + 0x3b, 0x50, 0x0e, 0xd4, 0x43, 0xe6, 0x24, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xf4, 0x40, + 0xf5, 0x00, 0x3f, 0x40, 0x4f, 0xd0, 0x02, 0xf4, + 0x00, 0xed, 0x00, 0x1f, 0x48, 0x0f, 0xd0, 0x03, + 0x54, 0x00, 0xcd, 0x00, 0x31, 0x40, 0xc3, 0xd0, + 0x23, 0xd4, 0x00, 0xfd, 0x00, 0x2f, 0x40, 0x0d, + 0xd1, 0x03, 0xfc, 0x00, 0xcd, 0x2a, 0x07, 0x40, + 0x0f, 0xd0, 0x03, 0xe4, 0x10, 0xf9, 0x00, 0x3f, + 0x48, 0x05, 0xd2, 0x83, 0xf4, 0xd0, 0xfd, 0x01, + 0x33, 0x40, 0x4c, 0xd1, 0x03, 0xc6, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x80, + 0xb8, 0x02, 0x2e, 0x02, 0x0b, 0x80, 0x02, 0xe0, + 0x00, 0xba, 0x00, 0x2e, 0x04, 0x0b, 0x84, 0x0a, + 0x20, 0x04, 0xda, 0x00, 0x22, 0x00, 0x09, 0x80, + 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x3a, 0x02, 0x0c, + 0x81, 0x02, 0xe0, 0x04, 0xd8, 0x20, 0x2e, 0x00, + 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, + 0x0a, 0x08, 0x82, 0x02, 0xc0, 0xc0, 0xb8, 0x48, + 0x22, 0x02, 0x08, 0x81, 0x02, 0xce, 0x06, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0x80, + 0xb1, 0x00, 0x28, 0x40, 0x4b, 0x10, 0x06, 0xc4, + 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x8b, 0x11, 0x0a, + 0x44, 0x10, 0x89, 0x00, 0xa0, 0x60, 0x0b, 0x10, + 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x44, 0x48, + 0x10, 0x02, 0xc4, 0x09, 0x81, 0x29, 0x2c, 0x40, + 0x8b, 0x10, 0x02, 0x84, 0x00, 0xb1, 0x00, 0x2c, + 0x4c, 0x09, 0x12, 0xc6, 0xc6, 0x88, 0xb1, 0x30, + 0xed, 0x09, 0x00, 0x28, 0x01, 0x20, 0x45, 0x28, + 0x10, 0x02, 0xd2, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x11, 0xa4, 0x04, 0xb9, 0x10, 0x2e, + 0x42, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x10, + 0x2e, 0x55, 0x0b, 0xb0, 0x02, 0x64, 0x00, 0x99, + 0x00, 0x22, 0x40, 0x09, 0x90, 0x82, 0xe4, 0xa1, + 0xb9, 0x00, 0x2a, 0x50, 0x09, 0x90, 0x02, 0xe4, + 0x01, 0x99, 0x40, 0x2e, 0x48, 0x0b, 0x90, 0x02, + 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x44, 0x08, 0x90, + 0x02, 0xe4, 0x44, 0xbb, 0x20, 0x20, 0x44, 0x08, + 0x92, 0x02, 0xc6, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, 0x60, 0x3a, + 0x71, 0x0f, 0x94, 0x03, 0xe7, 0xc0, 0xe9, 0x04, + 0x3e, 0x70, 0x0b, 0x96, 0x13, 0x64, 0x02, 0xc1, + 0x80, 0x32, 0x70, 0x0f, 0x94, 0x03, 0xe4, 0x00, + 0xf9, 0x20, 0x3e, 0x40, 0x8c, 0x92, 0x02, 0xc4, + 0x22, 0xc9, 0x14, 0x36, 0x60, 0x0f, 0x90, 0x03, + 0xe6, 0x00, 0xf9, 0x00, 0x3e, 0x60, 0x0d, 0x94, + 0x83, 0xe6, 0x00, 0xf9, 0x48, 0x32, 0x60, 0x0c, + 0x94, 0x83, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x82, 0x3e, + 0x48, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x60, 0x4f, 0x1c, 0x03, 0xa6, 0x40, 0xf9, + 0x20, 0x3e, 0x44, 0x0d, 0x9c, 0x03, 0xe6, 0x10, + 0xf9, 0x20, 0x3a, 0x42, 0xce, 0x99, 0x03, 0xe7, + 0x04, 0xf9, 0x04, 0x3e, 0x60, 0x0f, 0x90, 0x23, + 0xe6, 0x40, 0xf9, 0x00, 0x3c, 0x40, 0x4f, 0x99, + 0x47, 0xe6, 0x04, 0xf9, 0x00, 0xbe, 0x60, 0x8f, + 0x90, 0x03, 0xda, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x10, 0xa0, 0x00, 0xf8, 0x90, 0x02, + 0x10, 0x0f, 0x88, 0x03, 0xe3, 0x02, 0xc8, 0x40, + 0x3e, 0x10, 0x0f, 0x86, 0x03, 0x20, 0x20, 0xc8, + 0x40, 0x3e, 0x00, 0xed, 0x09, 0x00, 0x29, 0x01, + 0x2c, 0x80, 0x63, 0xe2, 0x0a, 0xc8, 0xc0, 0x3e, + 0x00, 0x0f, 0x82, 0x03, 0xe3, 0x00, 0xc8, 0x00, + 0x36, 0x20, 0x8f, 0x88, 0x03, 0xe0, 0x00, 0xc8, + 0x00, 0x3e, 0x00, 0x0f, 0x84, 0x43, 0x20, 0x02, + 0xc0, 0x14, 0x32, 0x00, 0x2c, 0x80, 0x03, 0xc2, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x3a, 0x60, 0xbe, 0x42, 0x23, 0x80, 0x0b, 0xe4, + 0x02, 0xf9, 0x00, 0xda, 0x01, 0x2f, 0x80, 0x4b, + 0xec, 0x03, 0x1a, 0x00, 0xde, 0xa0, 0x2f, 0xac, + 0x08, 0xa0, 0x02, 0xf9, 0x02, 0x8e, 0x42, 0x2f, + 0x81, 0x0b, 0xe0, 0x22, 0xf9, 0x04, 0xfe, 0xd8, + 0x23, 0xb0, 0x0b, 0xe4, 0x03, 0xa8, 0x00, 0xaa, + 0x00, 0x2f, 0x81, 0x08, 0xe0, 0x02, 0xbb, 0x10, + 0x8e, 0x80, 0x2b, 0x90, 0x08, 0xed, 0x02, 0xca, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, + 0x0c, 0x00, 0xb3, 0x80, 0x20, 0xc0, 0x0b, 0x30, + 0x02, 0xc2, 0x02, 0x83, 0x00, 0x6c, 0xc0, 0x0b, + 0x30, 0x02, 0x0a, 0x00, 0x83, 0x82, 0x2c, 0xf0, + 0x08, 0x10, 0x02, 0xcc, 0x40, 0x93, 0x10, 0x6e, + 0xc4, 0x0b, 0x34, 0x02, 0xc4, 0x12, 0x93, 0x01, + 0x24, 0xe4, 0x0b, 0x30, 0x02, 0x8c, 0x10, 0x83, + 0x00, 0x2c, 0xc0, 0x4a, 0x30, 0x02, 0x4e, 0x20, + 0x83, 0x00, 0x20, 0xd8, 0x08, 0x3c, 0x02, 0xca, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, + 0x1c, 0x10, 0xb7, 0x80, 0x61, 0xc0, 0x0b, 0x64, + 0x42, 0xfe, 0x20, 0x97, 0x08, 0x2d, 0xc0, 0x0b, + 0x74, 0x0a, 0x18, 0x22, 0x97, 0x00, 0x2f, 0xe0, + 0x88, 0x50, 0x12, 0xfa, 0x00, 0x96, 0x00, 0x2d, + 0x20, 0x0b, 0x60, 0x02, 0xdc, 0x0e, 0xb3, 0x80, + 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xbe, 0x00, 0xa7, + 0x00, 0x2d, 0xc0, 0x08, 0x6c, 0x02, 0xde, 0x30, + 0x82, 0x00, 0x29, 0xc0, 0x48, 0x74, 0xed, 0x09, + 0x00, 0x2a, 0x01, 0x02, 0xe0, 0x04, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x08, 0x16, 0x00, 0xf7, + 0x80, 0xa1, 0xe0, 0x0b, 0x68, 0x03, 0xd6, 0x12, + 0xc5, 0x80, 0x3d, 0x60, 0x0f, 0x78, 0x03, 0x1a, + 0x02, 0xc6, 0x80, 0x3d, 0xe0, 0x28, 0x58, 0x43, + 0xda, 0x00, 0xd7, 0x80, 0x2d, 0xc0, 0x0f, 0x58, + 0x03, 0xde, 0x02, 0xd7, 0x80, 0x35, 0xa0, 0x8f, + 0x68, 0x03, 0x9e, 0x00, 0xc7, 0x80, 0x3f, 0x61, + 0x0e, 0xd8, 0x03, 0x5e, 0x00, 0xc7, 0x80, 0x20, + 0xe0, 0x0c, 0x78, 0x03, 0xe2, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x1d, 0xa4, 0x00, 0xf9, + 0x01, 0x3e, 0xc0, 0x0f, 0x80, 0x03, 0xc4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0d, 0x30, 0x01, 0xa8, + 0x10, 0xeb, 0x04, 0x3e, 0xc0, 0x8f, 0x90, 0x03, + 0xe8, 0x02, 0xe8, 0x02, 0x3e, 0x00, 0x0f, 0x80, + 0x23, 0xcc, 0x08, 0xfb, 0x00, 0x3e, 0x80, 0x0f, + 0xa0, 0x23, 0x8c, 0x00, 0xfb, 0x00, 0x3e, 0x00, + 0x0e, 0x90, 0x03, 0xa4, 0x00, 0xfa, 0x00, 0x3e, + 0x00, 0x0f, 0xb0, 0x03, 0xc2, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xef, + 0x81, 0x3d, 0xe4, 0x0c, 0xc8, 0x01, 0xf2, 0x00, + 0x4f, 0x82, 0x1d, 0xe4, 0x0c, 0xf2, 0x03, 0x1a, + 0x80, 0xcf, 0x80, 0x39, 0xe0, 0x2d, 0x59, 0x20, + 0x3a, 0x00, 0xbe, 0x92, 0x3f, 0x64, 0x0c, 0xf8, + 0x03, 0xf6, 0x50, 0xef, 0x80, 0x0d, 0xa4, 0x0e, + 0xf8, 0x03, 0xbe, 0x00, 0xff, 0x80, 0x3f, 0xe0, + 0x0a, 0xf8, 0x03, 0x3e, 0x00, 0x4d, 0x82, 0x33, + 0xa0, 0x0c, 0xf8, 0x09, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x11, 0xb5, 0x00, 0x87, + 0x00, 0x2d, 0xc0, 0x08, 0x41, 0x02, 0xd4, 0x22, + 0x85, 0x00, 0x39, 0xd2, 0x48, 0x52, 0x0b, 0x58, + 0x80, 0xa7, 0x04, 0x21, 0x80, 0x08, 0x51, 0x8a, + 0x18, 0xed, 0x09, 0x00, 0x2b, 0x01, 0xa0, 0xb6, + 0x10, 0x2d, 0x00, 0x0d, 0x60, 0x22, 0xdc, 0xc4, + 0xb7, 0x20, 0x25, 0x80, 0x4d, 0x70, 0x22, 0xdc, + 0x80, 0xf7, 0x02, 0x2d, 0xc0, 0x4b, 0xc2, 0x03, + 0x78, 0x40, 0x84, 0x18, 0x2b, 0x80, 0x28, 0x40, + 0x03, 0x6a, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x40, 0xa7, 0x00, 0x2d, 0xc0, + 0x08, 0x40, 0x02, 0xd0, 0x40, 0x85, 0x00, 0x2d, + 0x40, 0x48, 0x71, 0xa2, 0x18, 0xe1, 0x86, 0x10, + 0x2f, 0xc2, 0x08, 0x51, 0x00, 0x18, 0x00, 0xb6, + 0x00, 0x2d, 0x00, 0x09, 0x40, 0x02, 0xdc, 0x04, + 0xa7, 0x00, 0x6f, 0x82, 0x8b, 0x60, 0x02, 0x9c, + 0x00, 0xb7, 0x00, 0x2d, 0x46, 0x0b, 0x70, 0x42, + 0x9c, 0x02, 0x95, 0x00, 0xa9, 0xc0, 0x0b, 0x70, + 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x14, 0xc0, 0x00, 0x81, 0xc0, 0x2c, 0xc2, + 0x08, 0x07, 0x22, 0xc4, 0x10, 0x81, 0x00, 0x28, + 0x50, 0x08, 0x18, 0x82, 0x4b, 0x04, 0x21, 0x26, + 0x24, 0xe0, 0x48, 0x18, 0x02, 0x0a, 0x28, 0xb0, + 0x00, 0x2c, 0x01, 0x19, 0x0c, 0x22, 0xc8, 0x00, + 0xba, 0x42, 0x64, 0xa0, 0x09, 0x20, 0x02, 0xce, + 0x00, 0xb3, 0x00, 0x6c, 0x10, 0x0b, 0x1c, 0x12, + 0xc1, 0x00, 0x90, 0xe0, 0x2a, 0x10, 0x0b, 0x00, + 0x22, 0x48, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x15, 0xa8, 0x00, 0xe3, 0x90, 0x3e, 0xc0, + 0x28, 0xac, 0x03, 0xec, 0x40, 0xc3, 0xc0, 0x3e, + 0x10, 0x28, 0xbc, 0x03, 0x2d, 0x40, 0x43, 0x40, + 0x3c, 0xc0, 0x0c, 0x98, 0x03, 0x29, 0x00, 0xfb, + 0x40, 0x2e, 0x80, 0x09, 0x84, 0x83, 0xc7, 0x00, + 0xeb, 0x60, 0x3e, 0xe0, 0x0f, 0xb0, 0x03, 0xac, + 0x20, 0xfb, 0x00, 0x3e, 0x80, 0x0e, 0xbd, 0x11, + 0xac, 0x84, 0xdb, 0x00, 0x3a, 0x44, 0x0f, 0xbc, + 0x03, 0x2a, 0x04, 0x60, 0xed, 0x09, 0x00, 0x2c, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xe9, + 0x00, 0xfa, 0x10, 0x3e, 0xc0, 0x0f, 0xa0, 0x13, + 0xec, 0x00, 0xf9, 0x10, 0x3e, 0x12, 0x0f, 0xb0, + 0x13, 0xe8, 0x00, 0xfb, 0x10, 0x3a, 0x50, 0x0e, + 0x90, 0x0b, 0xe8, 0x00, 0xfa, 0x20, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xef, 0x20, 0xfb, 0x00, 0x36, + 0xc0, 0x0e, 0x90, 0x03, 0xec, 0x00, 0xeb, 0x00, + 0x3e, 0x40, 0x1f, 0xa1, 0x39, 0x2d, 0x30, 0xeb, + 0x40, 0x36, 0x40, 0x04, 0xb1, 0x93, 0xa0, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xf0, + 0x00, 0xfe, 0x01, 0x33, 0xe0, 0x0c, 0xc0, 0x03, + 0x3e, 0x00, 0xcd, 0x0c, 0x31, 0xc0, 0x0d, 0xb4, + 0x37, 0x3b, 0x00, 0xce, 0xa2, 0x3b, 0xe0, 0x8c, + 0xfc, 0x07, 0xf8, 0x80, 0x9e, 0x20, 0x39, 0x22, + 0x0d, 0x40, 0x83, 0x7c, 0x00, 0xcf, 0x28, 0x37, + 0x80, 0x0f, 0xe2, 0x03, 0xfc, 0x10, 0xff, 0x00, + 0x3f, 0xb2, 0x0f, 0x40, 0x43, 0x3a, 0x00, 0xf4, + 0xc0, 0x3b, 0xe4, 0x0c, 0xca, 0x03, 0xc8, 0x44, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x63, + 0x08, 0xb8, 0x48, 0x22, 0x20, 0x0a, 0x08, 0x22, + 0x0f, 0x00, 0xd9, 0x00, 0xa2, 0xe0, 0x08, 0x30, + 0x22, 0x0b, 0x20, 0xeb, 0x80, 0x22, 0xf6, 0x0a, + 0xb8, 0x02, 0xc8, 0x00, 0x88, 0x80, 0x3e, 0x10, + 0x08, 0x8e, 0x02, 0x2c, 0x00, 0x8b, 0x00, 0x32, + 0x80, 0x0b, 0x84, 0x82, 0xec, 0x00, 0xbb, 0x00, + 0x26, 0x10, 0x0b, 0x80, 0x42, 0x23, 0x20, 0xb8, + 0x00, 0x22, 0x20, 0x00, 0x80, 0x82, 0xe8, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x22, + 0x00, 0xb8, 0x80, 0x60, 0xc8, 0x08, 0x81, 0x42, + 0xa8, 0x60, 0x8b, 0x80, 0x22, 0x08, 0x09, 0xb0, + 0x52, 0x68, 0x00, 0x9b, 0x00, 0x2a, 0xc0, 0x08, + 0x90, 0x02, 0xe8, 0x00, 0xa8, 0x04, 0x2e, 0xed, + 0x09, 0x00, 0x2d, 0x01, 0x18, 0x09, 0x88, 0x02, + 0x65, 0x01, 0x9b, 0x00, 0x26, 0x88, 0x0b, 0xa0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2a, 0x82, 0x09, + 0xb4, 0x02, 0xe4, 0x80, 0xbb, 0x00, 0x22, 0x00, + 0x28, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0xb8, 0x00, + 0x20, 0xe0, 0x0a, 0x08, 0x0a, 0x84, 0x00, 0x99, + 0x00, 0x20, 0x00, 0x00, 0x10, 0x02, 0x48, 0x02, + 0xa9, 0x00, 0x20, 0xc0, 0x0a, 0x10, 0x22, 0xca, + 0x00, 0xa0, 0x80, 0x2c, 0x00, 0x18, 0x00, 0x02, + 0x2c, 0x00, 0x81, 0x00, 0x20, 0x00, 0x0b, 0x10, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x24, 0x40, 0x0b, + 0x00, 0x02, 0x00, 0x00, 0xb3, 0x00, 0xa0, 0x00, + 0x18, 0x00, 0x02, 0xc2, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x60, 0x00, 0xf8, 0x00, + 0x32, 0xc0, 0x08, 0x80, 0x03, 0xa0, 0x02, 0xc9, + 0x00, 0x32, 0xc0, 0x0d, 0xb0, 0x02, 0x68, 0x00, + 0xda, 0x01, 0x3a, 0xc1, 0x0c, 0xb0, 0x02, 0xe8, + 0x10, 0xf8, 0x00, 0x38, 0x00, 0x0d, 0x80, 0x03, + 0x6c, 0x02, 0xcb, 0x00, 0x36, 0x80, 0x0f, 0xa0, + 0x23, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x80, 0x0d, + 0xa0, 0x0b, 0x20, 0x00, 0xf0, 0x00, 0x3a, 0xc0, + 0x0c, 0x00, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x1d, 0xf0, 0x00, 0xfc, 0x00, + 0x3f, 0x00, 0x1f, 0xc0, 0x03, 0x54, 0x00, 0xfd, + 0x00, 0x1f, 0xc0, 0x4f, 0xe0, 0x03, 0xb0, 0x04, + 0xf5, 0x01, 0x3f, 0xc0, 0x0f, 0xf0, 0x13, 0xf0, + 0x02, 0xdc, 0x00, 0x3b, 0x00, 0x0f, 0xc0, 0x03, + 0xfc, 0x00, 0xfc, 0x00, 0x3b, 0x80, 0x0f, 0xc0, + 0x23, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x00, 0x0f, + 0xc0, 0x13, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, + 0x0f, 0xc0, 0x03, 0xe8, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x2e, 0x01, 0xc0, + 0x01, 0xfc, 0x00, 0xcf, 0x08, 0x31, 0x01, 0x0f, + 0xc1, 0x03, 0xf0, 0x80, 0xec, 0x20, 0x3b, 0x08, + 0x04, 0xc2, 0x03, 0xf0, 0x84, 0xfc, 0x25, 0x3f, + 0x08, 0x0f, 0xc2, 0x1b, 0x30, 0x80, 0xfc, 0x20, + 0x3f, 0x08, 0x4f, 0xc2, 0xb3, 0xf0, 0x08, 0xec, + 0x28, 0x3b, 0x0a, 0x0f, 0xd0, 0x03, 0x34, 0x00, + 0xfc, 0x00, 0x31, 0x80, 0x0f, 0xc0, 0x22, 0x30, + 0x00, 0xfc, 0x00, 0x37, 0xc8, 0x0c, 0xf0, 0x03, + 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0xe8, 0x00, 0x8f, 0x68, 0x22, 0x00, 0x0b, + 0xb2, 0x42, 0xe1, 0x00, 0x88, 0x50, 0x2e, 0x04, + 0x8e, 0x85, 0x22, 0xe1, 0x44, 0xb8, 0x40, 0x36, + 0x10, 0x08, 0x81, 0x22, 0xa0, 0x40, 0x28, 0x50, + 0x22, 0x14, 0x0b, 0x84, 0x02, 0x20, 0x40, 0x88, + 0x40, 0x2e, 0x10, 0x8a, 0x95, 0x02, 0x28, 0x00, + 0xb8, 0x78, 0x2a, 0x80, 0x8b, 0x82, 0x03, 0x60, + 0x20, 0xb0, 0x20, 0x23, 0xd4, 0x08, 0xb0, 0x02, + 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, + 0x05, 0xc4, 0x02, 0x83, 0x00, 0x20, 0x40, 0x0b, + 0x32, 0x02, 0xc1, 0x02, 0xa0, 0x00, 0x28, 0x00, + 0x0b, 0x00, 0x02, 0xc0, 0x00, 0xb0, 0x40, 0x2c, + 0x10, 0x0b, 0x00, 0x1a, 0xc0, 0x10, 0xa0, 0x00, + 0x28, 0x00, 0x8a, 0x00, 0x00, 0x80, 0x00, 0xb0, + 0x00, 0x2c, 0x00, 0x0a, 0x10, 0x02, 0x4c, 0x08, + 0xb1, 0x00, 0x28, 0x80, 0x0b, 0x00, 0x82, 0xc0, + 0x80, 0xb0, 0x18, 0x20, 0xc0, 0x08, 0x30, 0x06, + 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x15, 0xad, 0x00, 0xa3, 0x02, 0xa2, 0x04, 0x0b, + 0x80, 0x00, 0xe8, 0x24, 0xaa, 0x00, 0x66, 0x54, + 0x8a, 0x94, 0x06, 0xe0, 0x20, 0xbb, 0x08, 0x2e, + 0xca, 0x0a, 0x80, 0x22, 0xec, 0x90, 0x8a, 0x08, + 0x26, 0x84, 0x1b, 0x80, 0x02, 0xed, 0x09, 0x00, + 0x2f, 0x01, 0x61, 0x80, 0x99, 0x20, 0x26, 0xc8, + 0x0a, 0xa8, 0x0a, 0x2c, 0x00, 0xbb, 0x00, 0xaa, + 0x90, 0x0b, 0xb0, 0x06, 0xec, 0x61, 0xbb, 0x00, + 0x22, 0xc0, 0x08, 0xb0, 0x02, 0xf0, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xe1, 0x06, + 0xcb, 0x01, 0x32, 0x72, 0x0f, 0xb8, 0x02, 0xe0, + 0x02, 0xe8, 0x42, 0x3a, 0x20, 0x0f, 0x80, 0x13, + 0xe0, 0x00, 0xf8, 0xd0, 0x3e, 0x20, 0x4f, 0x8c, + 0x23, 0xe0, 0x04, 0xe8, 0x90, 0x7e, 0x18, 0x0f, + 0x8c, 0xc3, 0xe3, 0x04, 0xb8, 0xa0, 0x2a, 0x28, + 0x0e, 0x98, 0x03, 0x2c, 0x00, 0xf9, 0x08, 0x32, + 0x90, 0x0f, 0x89, 0x03, 0x23, 0x08, 0xf8, 0xa6, + 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0xd0, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x95, 0x00, + 0xdf, 0x02, 0x3f, 0x40, 0x0f, 0xf4, 0x43, 0xd6, + 0x42, 0xdf, 0x22, 0x3f, 0xa1, 0x0e, 0xe9, 0x03, + 0xff, 0x00, 0xf8, 0x80, 0x31, 0x40, 0x4d, 0x79, + 0x23, 0xac, 0x10, 0xe5, 0x02, 0x6b, 0x60, 0x0f, + 0x72, 0x03, 0x9e, 0x00, 0xea, 0x80, 0x29, 0x20, + 0x0e, 0x30, 0x23, 0xbe, 0x80, 0xf3, 0x40, 0x37, + 0xc8, 0x0f, 0xf0, 0x03, 0x7a, 0x00, 0xfc, 0x40, + 0x3d, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, 0x90, + 0xcb, 0x00, 0x7e, 0x49, 0x0c, 0xb0, 0x03, 0xac, + 0x81, 0xf9, 0x41, 0x3c, 0xc1, 0x0e, 0xb0, 0x03, + 0xad, 0x00, 0xeb, 0x40, 0x3a, 0x90, 0x0d, 0xb6, + 0x13, 0x80, 0x10, 0xeb, 0x40, 0x3e, 0xc0, 0x1f, + 0xb0, 0x03, 0xed, 0x40, 0xd3, 0x00, 0x26, 0xc0, + 0x0f, 0x90, 0x03, 0x6c, 0x80, 0xc9, 0x01, 0x32, + 0x50, 0x2d, 0x80, 0x03, 0xe4, 0x02, 0xc0, 0x00, + 0x76, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xc8, 0x45, 0x25, 0x00, + 0xed, 0x09, 0x00, 0x30, 0x01, 0x8f, 0x00, 0x6e, + 0x50, 0x02, 0xb0, 0x02, 0xed, 0x00, 0xbb, 0x00, + 0x36, 0xc0, 0x08, 0xb0, 0x83, 0xac, 0x00, 0x8b, + 0x00, 0x2a, 0xc0, 0x4e, 0xb4, 0x03, 0xec, 0x04, + 0x8b, 0x00, 0x2a, 0xc0, 0x09, 0xb0, 0x02, 0xec, + 0x00, 0x8b, 0x00, 0x22, 0xc0, 0x8b, 0xb0, 0x02, + 0x2e, 0x14, 0xdb, 0x00, 0x22, 0xf4, 0x88, 0xb0, + 0x02, 0x2c, 0x04, 0x8b, 0x00, 0x63, 0xc0, 0x8b, + 0xb0, 0x03, 0xb2, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x05, 0x48, 0x00, 0x83, 0x00, 0x2c, + 0x40, 0x08, 0x30, 0x02, 0x40, 0x10, 0xb0, 0x00, + 0x28, 0x00, 0x2a, 0x0c, 0x82, 0x80, 0x00, 0x80, + 0x00, 0x24, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x2c, 0x00, 0x0b, 0x00, 0x02, 0xc2, + 0x00, 0xb0, 0x00, 0x24, 0x00, 0x09, 0x10, 0x02, + 0xce, 0x40, 0xa1, 0x00, 0x20, 0xb0, 0x08, 0x80, + 0x00, 0x80, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0b, + 0x30, 0x42, 0xf9, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x01, 0x0a, 0x00, 0x87, 0x80, 0x2d, + 0x20, 0x1a, 0x78, 0x02, 0xde, 0x01, 0xb1, 0x80, + 0x20, 0xe0, 0x00, 0x78, 0x02, 0x8e, 0x00, 0x87, + 0x80, 0x2c, 0xa0, 0x02, 0x38, 0x22, 0xd2, 0x00, + 0x83, 0x80, 0x29, 0xe1, 0x09, 0x78, 0x02, 0xce, + 0x00, 0xa7, 0x90, 0x29, 0xe0, 0x0b, 0x58, 0x20, + 0xba, 0x40, 0xb5, 0x84, 0xa9, 0xe2, 0x19, 0xc8, + 0x40, 0x16, 0x00, 0x97, 0x80, 0x61, 0xe0, 0x0b, + 0x78, 0x00, 0x88, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x0c, 0x02, 0xc3, 0x10, 0x2c, + 0x01, 0x0c, 0x34, 0x07, 0x44, 0x00, 0xb3, 0x40, + 0x28, 0x84, 0x0e, 0x20, 0x03, 0x8c, 0x18, 0xc0, + 0x00, 0x34, 0x40, 0x0c, 0x37, 0xa7, 0x8c, 0x00, + 0xe1, 0x00, 0x3c, 0x44, 0x4b, 0x30, 0x03, 0xcc, + 0x00, 0xf2, 0x00, 0xed, 0x09, 0x00, 0x31, 0x01, + 0x34, 0x00, 0x45, 0x30, 0x13, 0xcc, 0x40, 0xe3, + 0x22, 0x00, 0xc8, 0x05, 0x30, 0x01, 0xa8, 0x88, + 0xf0, 0x00, 0x30, 0xc0, 0x0f, 0x30, 0x03, 0xd2, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, + 0xbc, 0x00, 0xff, 0x58, 0x3f, 0x00, 0x87, 0xf0, + 0x02, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x4b, + 0xf0, 0x03, 0xfc, 0x04, 0xdf, 0x10, 0x1b, 0xc0, + 0x0f, 0xf1, 0x0b, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc4, 0x09, 0xf1, 0x02, 0xfc, 0x00, 0xdf, 0x01, + 0x37, 0xc0, 0x0f, 0xe0, 0x03, 0x5c, 0x48, 0xdf, + 0x00, 0x37, 0xc0, 0x0e, 0x70, 0x03, 0xbc, 0x00, + 0xef, 0x00, 0x3f, 0xc2, 0x0f, 0xf0, 0x03, 0xd0, + 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, + 0xec, 0x00, 0xfb, 0x60, 0x3e, 0x40, 0x0f, 0x80, + 0x03, 0xa8, 0x00, 0xfa, 0x04, 0x32, 0x40, 0x0e, + 0x90, 0x03, 0xe0, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0x80, 0x03, 0xec, 0x01, 0xfa, 0x00, 0x36, + 0x80, 0x0f, 0x80, 0x03, 0x20, 0x08, 0xd9, 0x06, + 0x36, 0xc0, 0x0f, 0xb0, 0x43, 0xee, 0x01, 0xcb, + 0x82, 0x36, 0x80, 0x0f, 0xb8, 0x4f, 0x2c, 0x00, + 0xcb, 0x00, 0x3e, 0xd0, 0x0f, 0xb0, 0x03, 0xea, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, + 0x9c, 0x10, 0x37, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x42, 0xdc, 0x00, 0xb7, 0x00, 0x85, 0xc0, 0x0b, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x21, 0xc1, + 0x0b, 0x70, 0x02, 0x5c, 0x04, 0x97, 0x00, 0x21, + 0xc0, 0x0e, 0x70, 0x02, 0x1c, 0x00, 0x87, 0x00, + 0x29, 0xc0, 0x0b, 0x70, 0x02, 0x5c, 0x01, 0x87, + 0x00, 0x21, 0xc0, 0x8b, 0x70, 0x02, 0x1c, 0x12, + 0x87, 0x00, 0x2d, 0xcc, 0x4b, 0x70, 0x02, 0xd2, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x9e, 0x00, 0xb7, 0xa0, 0x2d, 0xe0, 0xed, 0x09, + 0x00, 0x32, 0x01, 0x0b, 0x78, 0x02, 0x9e, 0x20, + 0xb3, 0x00, 0xa9, 0xe0, 0x0b, 0x78, 0x46, 0xde, + 0x20, 0x93, 0xc0, 0x2d, 0xe2, 0x0b, 0x7c, 0x02, + 0xde, 0x20, 0xb3, 0x84, 0x2d, 0xe0, 0x09, 0x38, + 0x02, 0x0e, 0x00, 0x83, 0x80, 0x21, 0xe2, 0x0b, + 0x78, 0x02, 0xfe, 0x00, 0xb7, 0x80, 0xa9, 0xe2, + 0x0b, 0x78, 0x02, 0x1e, 0x28, 0x84, 0x80, 0x2d, + 0xe1, 0x1b, 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x14, 0xed, 0x40, 0xb3, + 0x02, 0x2c, 0x64, 0x8b, 0x86, 0x02, 0xcd, 0x00, + 0xb3, 0x48, 0x2c, 0xc1, 0x09, 0x34, 0x06, 0xce, + 0x80, 0xb3, 0x20, 0x28, 0xc0, 0x0b, 0x38, 0x02, + 0x4e, 0x20, 0xb3, 0xc2, 0xa8, 0xf0, 0x82, 0x30, + 0x0a, 0x0e, 0x02, 0x83, 0x41, 0xa8, 0xc8, 0x0b, + 0x30, 0x26, 0x4e, 0x00, 0xb3, 0xc0, 0x20, 0xe0, + 0x0b, 0x30, 0x06, 0x0c, 0x00, 0x83, 0x00, 0x2c, + 0xc1, 0x0b, 0x30, 0x02, 0xd3, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xe8, 0x15, 0xba, 0x04, 0xfa, + 0x01, 0x3f, 0xb0, 0x0f, 0xe6, 0x03, 0xb8, 0x00, + 0xfe, 0xe0, 0x3b, 0x90, 0x0e, 0xec, 0x02, 0xfb, + 0x00, 0xde, 0x80, 0x3f, 0x80, 0x0f, 0xe8, 0x43, + 0xfb, 0x04, 0xfe, 0xe0, 0x3f, 0xa8, 0x0d, 0xe0, + 0x03, 0x3b, 0x80, 0xde, 0x40, 0x27, 0xa0, 0x0b, + 0x64, 0x03, 0xfb, 0x0e, 0x7e, 0xa0, 0x3b, 0x90, + 0x0f, 0xec, 0x03, 0x3b, 0x00, 0x8e, 0x00, 0x3e, + 0x80, 0x0f, 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0xe0, 0x28, 0xb0, + 0x00, 0x3e, 0x30, 0x07, 0x80, 0x43, 0xe0, 0x00, + 0xf0, 0x00, 0x32, 0x16, 0x0f, 0x01, 0x03, 0xe0, + 0x00, 0xd8, 0x40, 0x36, 0x00, 0x0f, 0x80, 0x81, + 0xe1, 0x00, 0xd8, 0x08, 0x54, 0x00, 0x0f, 0x88, + 0x03, 0xe0, 0x20, 0xf0, 0x30, 0x3a, 0x10, 0x8f, + 0x85, 0xed, 0x09, 0x00, 0x33, 0x01, 0x83, 0x62, + 0x41, 0xc8, 0x22, 0x3a, 0x30, 0x4d, 0x81, 0x83, + 0xe0, 0x20, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xe6, 0x80, 0xc9, 0x04, 0x72, 0x64, + 0x0f, 0x90, 0x03, 0x26, 0x60, 0xf9, 0x00, 0x30, + 0x40, 0x2c, 0x90, 0x83, 0xc4, 0x00, 0xe1, 0x04, + 0x30, 0x42, 0x0e, 0x90, 0x02, 0xc4, 0x00, 0x81, + 0x00, 0x3e, 0x72, 0x6d, 0x10, 0x63, 0x04, 0x00, + 0xe9, 0x00, 0x30, 0x40, 0x2e, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x01, 0x3e, 0x40, 0x0e, 0x90, 0x03, + 0xe4, 0x10, 0xc9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x04, 0x65, 0x00, 0x89, 0x00, 0x62, 0x51, + 0x0b, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x40, 0x2a, + 0x58, 0x0d, 0x90, 0x2b, 0x24, 0x00, 0xf9, 0x60, + 0x22, 0x40, 0x0a, 0x90, 0x02, 0xe5, 0x80, 0xa9, + 0x41, 0x2a, 0x72, 0x0a, 0x94, 0x02, 0xa5, 0x00, + 0xa9, 0x42, 0x3e, 0x50, 0x08, 0x96, 0x2a, 0x25, + 0x00, 0xb9, 0x00, 0x2c, 0x72, 0x08, 0x90, 0x12, + 0xc4, 0x00, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0x25, 0x00, 0x89, 0x06, 0x26, 0x50, + 0x0b, 0x90, 0x02, 0x24, 0x05, 0xb9, 0x00, 0x62, + 0x40, 0x08, 0x90, 0x52, 0xa4, 0x08, 0xb9, 0x00, + 0x22, 0x40, 0x1a, 0x90, 0x02, 0xec, 0x00, 0xa9, + 0x28, 0x2a, 0x40, 0x09, 0x90, 0x82, 0x24, 0x20, + 0x89, 0x08, 0x2e, 0x40, 0x09, 0x90, 0x0a, 0x64, + 0x01, 0xb9, 0x00, 0x2e, 0x60, 0x3a, 0xb0, 0x22, + 0xe4, 0x10, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x05, 0x0a, 0x81, 0x40, 0x24, 0x40, + 0x0b, 0x14, 0x06, 0x04, 0xed, 0x09, 0x00, 0x34, + 0x01, 0x01, 0xb1, 0x00, 0xe0, 0x40, 0x09, 0x10, + 0x02, 0x04, 0x00, 0xb1, 0x00, 0x20, 0x40, 0x3a, + 0x10, 0x02, 0xc4, 0x00, 0xa1, 0x00, 0x28, 0x40, + 0x1a, 0x10, 0x02, 0x84, 0x00, 0xa1, 0x00, 0x2c, + 0xc0, 0x08, 0x90, 0x0a, 0x0c, 0x00, 0xb1, 0x40, + 0x6e, 0x40, 0x18, 0x14, 0x02, 0xe5, 0x00, 0x81, + 0x40, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, + 0x00, 0x88, 0x00, 0x26, 0x00, 0x0b, 0x80, 0x0b, + 0x20, 0x00, 0xfa, 0x00, 0x32, 0x00, 0x2c, 0x80, + 0x13, 0xa0, 0x08, 0xf8, 0x00, 0xb2, 0x00, 0x0e, + 0x80, 0x02, 0xe0, 0x02, 0xe8, 0x01, 0x3a, 0x00, + 0x8d, 0x80, 0x03, 0x20, 0x04, 0xe8, 0x00, 0x7e, + 0x00, 0x4d, 0x80, 0x03, 0x60, 0x04, 0x70, 0x00, + 0x3e, 0x00, 0x0e, 0x00, 0x01, 0xc0, 0x02, 0xc8, + 0x06, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xee, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1d, 0xfd, + 0x00, 0xf9, 0x40, 0xbb, 0x40, 0x0f, 0xd0, 0x03, + 0xf5, 0x00, 0xfd, 0x40, 0x1f, 0x50, 0x2f, 0xd4, + 0x03, 0xb5, 0x08, 0x7d, 0x40, 0x3f, 0x50, 0x4f, + 0xd4, 0x03, 0xf5, 0x00, 0xfd, 0x42, 0x3b, 0x50, + 0x07, 0xd4, 0x03, 0xf5, 0x00, 0x7d, 0x40, 0x3f, + 0x50, 0x1f, 0xf4, 0x03, 0x54, 0x00, 0xfd, 0x40, + 0x3f, 0x40, 0x2f, 0xd0, 0x03, 0xf4, 0x00, 0xfd, + 0x40, 0x3e, 0x50, 0x0f, 0x90, 0x03, 0xe6, 0x06, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xf4, + 0xc0, 0xf9, 0x04, 0x3f, 0x40, 0x0f, 0x91, 0x03, + 0xe4, 0x82, 0xd9, 0x28, 0x22, 0x48, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xe9, 0x00, 0x36, 0x48, 0x0c, + 0x92, 0x83, 0xe4, 0x80, 0xd9, 0x00, 0x3e, 0x40, + 0x0e, 0xb0, 0x03, 0xe4, 0x80, 0xe9, 0x28, 0x32, + 0x48, 0x0f, 0x90, 0x03, 0x34, 0x00, 0x49, 0xed, + 0x09, 0x00, 0x35, 0x01, 0x10, 0x37, 0x40, 0x0f, + 0x90, 0x03, 0x64, 0x40, 0xd9, 0x00, 0x32, 0x40, + 0x0f, 0x90, 0x03, 0xc6, 0x01, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x10, 0xe0, 0xc0, 0x30, 0x48, + 0x2e, 0x00, 0x0b, 0x20, 0x02, 0xe0, 0x04, 0x88, + 0x00, 0x2a, 0x04, 0x09, 0x84, 0x12, 0xe0, 0x00, + 0xa8, 0x10, 0x2e, 0x01, 0x0d, 0x80, 0x12, 0x60, + 0x40, 0x88, 0x40, 0x2e, 0x00, 0x09, 0x81, 0x42, + 0xe0, 0x10, 0xb8, 0x00, 0x36, 0x05, 0x0a, 0xc4, + 0x02, 0x20, 0x0a, 0xa8, 0x10, 0x22, 0x00, 0x0b, + 0x02, 0x03, 0x60, 0x80, 0x88, 0x48, 0x22, 0x00, + 0x0b, 0x80, 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x05, 0xc4, 0x80, 0xb1, 0x30, + 0x2c, 0x40, 0x09, 0x10, 0x02, 0xd6, 0x40, 0x95, + 0x80, 0x09, 0x60, 0x0b, 0x59, 0x02, 0xd6, 0x40, + 0xa5, 0x82, 0x25, 0x64, 0x08, 0x58, 0x02, 0x56, + 0x00, 0x85, 0x90, 0x2d, 0x64, 0x0b, 0x58, 0x02, + 0x96, 0x40, 0xb5, 0x80, 0x29, 0x60, 0x0a, 0x51, + 0x02, 0x04, 0x10, 0xa1, 0x00, 0x20, 0x40, 0x0b, + 0x12, 0x82, 0x64, 0x80, 0xb1, 0x31, 0x20, 0x44, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x02, + 0x2e, 0x48, 0x0b, 0x90, 0x12, 0xe4, 0x00, 0x8d, + 0x00, 0x2b, 0x40, 0x0b, 0xd2, 0x06, 0xf4, 0x02, + 0xad, 0x00, 0x2f, 0x48, 0x09, 0xd0, 0x22, 0x74, + 0x40, 0x9d, 0x00, 0x2f, 0x40, 0x09, 0xd0, 0x02, + 0xf4, 0x00, 0xbd, 0x00, 0x2f, 0x41, 0x08, 0xd0, + 0x02, 0x25, 0x00, 0xa9, 0x29, 0x26, 0x58, 0x0b, + 0x92, 0x06, 0x64, 0x48, 0x89, 0x00, 0x22, 0x40, + 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x11, 0xe6, 0x00, 0xf9, 0x00, + 0x3e, 0x48, 0x0d, 0x94, 0x03, 0xe5, 0x40, 0xd9, + 0x52, 0x3a, 0xed, 0x09, 0x00, 0x36, 0x01, 0x50, + 0x0f, 0x9c, 0x03, 0xe7, 0x10, 0xe9, 0xd0, 0x36, + 0x50, 0x0c, 0x9c, 0x43, 0xe7, 0x00, 0xd9, 0x40, + 0x3e, 0x70, 0x0e, 0x94, 0x03, 0xe5, 0x04, 0xe9, + 0xc3, 0x3a, 0x50, 0x0e, 0x94, 0x0b, 0x24, 0x40, + 0xc9, 0x41, 0x32, 0x40, 0x0b, 0x92, 0x03, 0x65, + 0x30, 0xf9, 0x58, 0xb2, 0x40, 0x8f, 0x90, 0x03, + 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x01, 0xa6, 0x80, 0xf9, 0x02, 0x3e, 0x40, 0x0f, + 0x99, 0x03, 0xe6, 0x10, 0xf9, 0x83, 0xbe, 0x48, + 0x0d, 0x90, 0x03, 0xe5, 0x00, 0xf9, 0x80, 0x3e, + 0x62, 0x0f, 0x9a, 0x11, 0xe6, 0x12, 0xe9, 0x20, + 0x3c, 0x48, 0x0c, 0x9c, 0x03, 0xe7, 0x00, 0xf9, + 0xa1, 0x36, 0x44, 0x0e, 0x91, 0x03, 0xa6, 0x00, + 0xd9, 0x00, 0xba, 0x40, 0x8f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x01, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x10, 0xa2, 0x00, 0xc8, 0x00, 0x32, 0x25, 0x0e, + 0x84, 0x0b, 0x00, 0x02, 0xc0, 0x00, 0xba, 0x00, + 0x0f, 0x80, 0x03, 0xc0, 0x20, 0xe8, 0x00, 0x30, + 0x04, 0x0d, 0x80, 0x03, 0xc0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x1c, 0x81, 0x03, 0x60, 0x00, 0xc0, + 0x00, 0x30, 0x00, 0x0d, 0x80, 0x03, 0xe3, 0x40, + 0xc8, 0x42, 0x36, 0x30, 0x4e, 0x80, 0x01, 0xe0, + 0x00, 0xf8, 0x40, 0x2e, 0x00, 0x0c, 0x80, 0x03, + 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x38, 0x00, 0x0a, 0x00, 0x23, 0xb0, 0x08, + 0xa0, 0x03, 0x68, 0x08, 0x8a, 0x80, 0x3e, 0x80, + 0x0b, 0xa0, 0x03, 0x29, 0x00, 0xaa, 0x00, 0x22, + 0xa0, 0x08, 0xa0, 0x02, 0x68, 0x00, 0xda, 0x00, + 0x2e, 0x80, 0x08, 0xa8, 0x02, 0xe8, 0x00, 0xaa, + 0x80, 0x3e, 0xa0, 0x08, 0x20, 0x23, 0x9b, 0x08, + 0xda, 0x00, 0x2f, 0x80, 0x18, 0xed, 0x09, 0x00, + 0x37, 0x01, 0xa0, 0x02, 0x08, 0x04, 0xba, 0x02, + 0x2e, 0x80, 0x08, 0xa0, 0x02, 0xca, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x0e, 0x01, + 0x83, 0x01, 0x20, 0xc0, 0x08, 0x30, 0x02, 0x0c, + 0x02, 0x83, 0x00, 0x24, 0xe4, 0x0b, 0x30, 0x02, + 0x8d, 0x00, 0x83, 0x80, 0x24, 0xd0, 0x09, 0x30, + 0x40, 0xcc, 0x00, 0x83, 0x00, 0x6c, 0xc0, 0x19, + 0x30, 0x22, 0xcc, 0x00, 0x83, 0x80, 0x28, 0xc0, + 0x0b, 0x30, 0x02, 0x0e, 0x04, 0x8b, 0x01, 0x24, + 0xa0, 0x0a, 0xb0, 0x02, 0x8c, 0x00, 0xbb, 0x00, + 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xca, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1a, 0x22, + 0x87, 0xa2, 0x21, 0xe0, 0x18, 0x78, 0x02, 0x58, + 0x00, 0x87, 0x08, 0x25, 0xc0, 0x0b, 0x08, 0x02, + 0x0c, 0x00, 0xa7, 0xc0, 0x65, 0xc0, 0x08, 0x40, + 0x02, 0x5c, 0x00, 0x97, 0x00, 0x2d, 0xc0, 0x29, + 0x70, 0x00, 0xd6, 0x00, 0xa3, 0x08, 0x2c, 0xd1, + 0x08, 0x70, 0x42, 0xbc, 0x00, 0x97, 0x20, 0x2f, + 0xf0, 0x18, 0x70, 0x02, 0x1c, 0x80, 0xb7, 0x00, + 0x2d, 0xe0, 0x08, 0x70, 0x02, 0xe8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x0e, 0x00, + 0xc7, 0xa0, 0xa1, 0xe0, 0x0c, 0x7a, 0x03, 0x06, + 0x02, 0xc2, 0x80, 0x35, 0xa0, 0x4b, 0x78, 0x23, + 0x9e, 0x00, 0x62, 0x80, 0xb4, 0xe0, 0x8d, 0x78, + 0x02, 0xca, 0x00, 0xc4, 0x80, 0x2c, 0x20, 0x81, + 0x68, 0x03, 0x4a, 0x00, 0xc6, 0x82, 0x19, 0xa0, + 0x0f, 0x68, 0x03, 0x9e, 0x00, 0x47, 0xe0, 0x35, + 0xe0, 0x0a, 0x7e, 0x93, 0x9e, 0x20, 0xf7, 0x80, + 0x2c, 0xe0, 0x2c, 0x78, 0x03, 0xea, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, 0xa8, 0x00, + 0xfb, 0x70, 0x3c, 0xc0, 0x07, 0xb4, 0x03, 0xa0, + 0x00, 0xfa, 0x00, 0x0e, 0x81, 0x8f, 0x80, 0x63, + 0xed, 0x09, 0x00, 0x38, 0x01, 0xac, 0x00, 0xba, + 0x00, 0x3a, 0xc0, 0x0f, 0x80, 0x03, 0x68, 0x00, + 0xd8, 0x00, 0x3e, 0x00, 0x0e, 0xa0, 0x02, 0xe0, + 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, + 0x8c, 0x00, 0xfb, 0x20, 0x3c, 0xc0, 0x0f, 0xb6, + 0x03, 0xac, 0x80, 0xfb, 0x50, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x15, 0xfe, 0x04, 0x4f, 0xc0, 0x31, + 0x80, 0x0c, 0xfc, 0x83, 0xbe, 0x00, 0xfd, 0x90, + 0x3b, 0x60, 0x2f, 0xf1, 0x0b, 0x7a, 0x00, 0xcd, + 0x80, 0x3b, 0x20, 0x0f, 0xf9, 0x03, 0xfe, 0x00, + 0xef, 0x80, 0x3f, 0xe0, 0x0d, 0xd8, 0x23, 0x3e, + 0x00, 0xcd, 0x80, 0x33, 0x60, 0x8c, 0xf8, 0x03, + 0x3e, 0x00, 0x67, 0xd0, 0x35, 0xe0, 0x0d, 0xf8, + 0x02, 0x3e, 0x60, 0xef, 0xc0, 0x3f, 0xe0, 0x0f, + 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x01, 0xbc, 0x00, 0xa7, 0x00, 0x21, + 0xc4, 0x0d, 0x70, 0x82, 0x18, 0x40, 0xb5, 0x30, + 0x21, 0x40, 0x08, 0x42, 0x0a, 0x18, 0x80, 0x85, + 0x00, 0x35, 0x04, 0x08, 0x41, 0x02, 0xdc, 0x40, + 0xf7, 0x00, 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0x14, + 0x00, 0x85, 0x00, 0x31, 0x40, 0x0a, 0x70, 0x02, + 0x18, 0x80, 0x87, 0x10, 0x21, 0xc0, 0x28, 0x70, + 0x42, 0x9c, 0x00, 0xb7, 0x18, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x95, 0x00, 0xa7, 0x00, 0x23, + 0xc4, 0x08, 0xf0, 0x02, 0x94, 0x00, 0xb0, 0x04, + 0x28, 0x00, 0x2b, 0x31, 0x0e, 0x58, 0x10, 0x80, + 0x00, 0x2c, 0x00, 0x28, 0x70, 0x42, 0xc8, 0x00, + 0x94, 0x00, 0x29, 0x00, 0x08, 0x00, 0x0a, 0x58, + 0x00, 0xa0, 0x00, 0x24, 0x04, 0x0b, 0x61, 0x02, + 0x1c, 0x14, 0xbf, 0x10, 0x2d, 0x42, 0x0a, 0xf0, + 0x0a, 0xdc, 0x30, 0xed, 0x09, 0x00, 0x39, 0x01, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xc0, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, + 0x60, 0x00, 0xab, 0x00, 0x20, 0xc0, 0x0b, 0x3e, + 0x02, 0x80, 0x00, 0xb0, 0x42, 0x20, 0x00, 0x08, + 0x02, 0x02, 0x08, 0x00, 0x80, 0x01, 0x24, 0x10, + 0x08, 0x04, 0x02, 0xc8, 0x00, 0x90, 0x40, 0x2c, + 0x00, 0x09, 0x00, 0x02, 0x40, 0x00, 0xa0, 0x00, + 0x20, 0x10, 0x2a, 0x2b, 0x02, 0x0c, 0x10, 0x93, + 0x00, 0x24, 0x72, 0x4a, 0x3c, 0x82, 0x0e, 0x10, + 0xb3, 0x40, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc8, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, + 0xad, 0x00, 0xcf, 0x00, 0x32, 0xd4, 0x88, 0x74, + 0x03, 0xae, 0x00, 0xfb, 0xc0, 0x3a, 0xf4, 0x0f, + 0xbc, 0x03, 0x66, 0x08, 0xcb, 0xc0, 0x7e, 0xf0, + 0x0c, 0xbc, 0x03, 0xe7, 0x40, 0xfb, 0x90, 0x5e, + 0xe0, 0x0d, 0xb8, 0x22, 0x6e, 0x02, 0xeb, 0x90, + 0xb6, 0xf0, 0x1e, 0x9c, 0x0a, 0x24, 0x00, 0xff, + 0x00, 0x1e, 0xd0, 0x0e, 0xf6, 0x01, 0x3d, 0x41, + 0xef, 0xd2, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xea, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0xea, 0x02, 0x9b, 0x00, 0x3e, 0xe0, 0x05, 0xb0, + 0x03, 0x6a, 0x80, 0xf3, 0xa0, 0x3e, 0xe0, 0x8e, + 0x88, 0x2b, 0xc6, 0x22, 0xf3, 0x80, 0x3c, 0xe8, + 0x0e, 0x0a, 0x03, 0xc6, 0x04, 0xf3, 0x80, 0x3e, + 0xe2, 0x0f, 0x3a, 0x03, 0x86, 0x80, 0xdb, 0x80, + 0x3e, 0xe2, 0x0f, 0x90, 0x03, 0xee, 0x20, 0xcb, + 0x80, 0x3a, 0x40, 0x0c, 0xb0, 0x03, 0xec, 0x01, + 0xfb, 0x00, 0x1e, 0xc0, 0x0f, 0xb0, 0x03, 0xe0, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0xf4, 0x02, 0xcb, 0x04, 0x33, 0x40, 0x0b, 0xf0, + 0x03, 0x74, 0x00, 0xfe, 0x00, 0xb3, 0x80, 0x0f, + 0x70, 0x0b, 0x64, 0x40, 0xee, 0x08, 0xed, 0x09, + 0x00, 0x3a, 0x01, 0x3b, 0xc0, 0x0c, 0xf0, 0x03, + 0xb0, 0x40, 0x9c, 0x00, 0x39, 0x00, 0x0c, 0xe0, + 0x12, 0x28, 0x00, 0xce, 0x00, 0x3b, 0x80, 0x4e, + 0x48, 0x03, 0x74, 0x00, 0xe7, 0x00, 0x33, 0xd0, + 0x8d, 0xf0, 0x03, 0x7c, 0x00, 0xf7, 0x00, 0x33, + 0xc0, 0x0d, 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x04, 0x62, 0x00, 0x8b, + 0x00, 0xa2, 0x44, 0x0b, 0xb0, 0x02, 0x20, 0x00, + 0xba, 0x00, 0x22, 0x80, 0x0b, 0x80, 0x0a, 0x64, + 0x00, 0x8a, 0x00, 0x22, 0xc0, 0x0a, 0x80, 0x02, + 0x20, 0x00, 0x88, 0x00, 0x2a, 0x00, 0x0a, 0xa0, + 0x02, 0xa0, 0x02, 0x8a, 0x00, 0x2e, 0x81, 0x0b, + 0x88, 0x02, 0x4e, 0x00, 0x2b, 0x00, 0x22, 0x60, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x04, 0x22, + 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x15, 0x2e, 0x00, 0xab, + 0x00, 0x22, 0xd0, 0x0b, 0xb0, 0x02, 0x6c, 0x00, + 0xb9, 0x02, 0x2a, 0x40, 0x0a, 0xb0, 0x1a, 0x20, + 0x00, 0xa9, 0x00, 0x2e, 0x00, 0x0a, 0xb0, 0x02, + 0xa4, 0x00, 0xab, 0x00, 0x2a, 0xc0, 0x28, 0x90, + 0x22, 0xac, 0x00, 0xa9, 0x04, 0x2e, 0x40, 0x0b, + 0x92, 0x02, 0xed, 0x40, 0xab, 0x00, 0x22, 0xc0, + 0x1b, 0xb0, 0x22, 0x6c, 0x00, 0xbb, 0x00, 0x22, + 0xc0, 0x09, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x0c, 0x04, 0x83, + 0x00, 0x20, 0xc1, 0x0b, 0xb0, 0x12, 0x08, 0x00, + 0xb1, 0x01, 0x20, 0x40, 0x0b, 0x00, 0x02, 0x40, + 0x02, 0x81, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x04, 0x03, 0x83, 0x00, 0x28, 0xc0, 0x0a, 0x10, + 0x06, 0x84, 0x00, 0x81, 0x00, 0x64, 0x40, 0x0b, + 0x10, 0x02, 0x4c, 0x00, 0x03, 0x00, 0x20, 0x60, + 0x0b, 0x30, 0x02, 0xcc, 0x04, 0xb3, 0x00, 0x20, + 0xc0, 0xed, 0x09, 0x00, 0x3b, 0x01, 0x0b, 0x30, + 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x6c, 0x00, 0xcf, 0x01, 0x32, 0xc0, + 0x8f, 0xf0, 0x03, 0x64, 0x08, 0xf8, 0x00, 0x3a, + 0x00, 0x0e, 0xb0, 0x03, 0x20, 0x08, 0xe8, 0x00, + 0x3a, 0x00, 0x0c, 0xb0, 0x03, 0xa0, 0x00, 0xf8, + 0x00, 0x3a, 0x00, 0x0c, 0x80, 0x03, 0x28, 0x00, + 0x48, 0x00, 0x3a, 0x00, 0x0f, 0x80, 0x03, 0x6c, + 0x00, 0xef, 0x00, 0x32, 0x40, 0x0d, 0xf0, 0x03, + 0x7c, 0x00, 0xff, 0x00, 0xb2, 0xc0, 0x0d, 0xb0, + 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x15, 0xf8, 0x00, 0x9f, 0x00, 0x3f, 0xc0, + 0x4f, 0x70, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f, + 0x00, 0x0f, 0xc0, 0x03, 0xb0, 0x00, 0xdc, 0x01, + 0x37, 0x00, 0x0f, 0xc0, 0x43, 0x70, 0x00, 0xdc, + 0x04, 0xbf, 0x00, 0x8e, 0xc0, 0x01, 0xf0, 0x00, + 0xfc, 0x02, 0x2f, 0x00, 0x07, 0x40, 0x23, 0x9c, + 0x00, 0xff, 0x00, 0x3f, 0x40, 0x0f, 0x70, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x05, 0xf4, 0x00, 0x0c, 0x00, 0x33, 0x80, + 0x8b, 0xc0, 0x13, 0xf0, 0x00, 0xcc, 0x00, 0x3d, + 0x40, 0x08, 0xc0, 0x03, 0x30, 0x00, 0xcf, 0x00, + 0x1b, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0xfd, + 0x00, 0x3f, 0x40, 0x4f, 0xf0, 0x23, 0xfc, 0x00, + 0xd5, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xfc, 0x00, 0x33, 0x00, 0x0c, 0xd2, 0x8b, + 0x70, 0xc0, 0xcc, 0x14, 0x73, 0x00, 0xac, 0xc1, + 0x03, 0xb0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x10, 0xe4, 0x00, 0x8a, 0x04, 0xa2, 0xc0, + 0x0b, 0x96, 0x22, 0xe0, 0x00, 0xc8, 0x00, 0x3a, + 0x40, 0x08, 0xa0, 0x22, 0x24, 0x28, 0x8b, 0x01, + 0x22, 0xc0, 0x0b, 0xb0, 0xed, 0x09, 0x00, 0x3c, + 0x01, 0x03, 0xa0, 0x00, 0xbb, 0x01, 0x2e, 0x40, + 0x0b, 0xa0, 0x02, 0xec, 0x00, 0xb9, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x04, 0xb3, 0x6c, + 0x22, 0x12, 0x08, 0x96, 0x02, 0xa0, 0xc0, 0x88, + 0x61, 0x62, 0x54, 0x08, 0x86, 0x02, 0x20, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xc4, + 0x00, 0xa3, 0x00, 0x20, 0x80, 0x0b, 0x14, 0x82, + 0xe0, 0x00, 0x80, 0x00, 0x2c, 0x40, 0x0a, 0x20, + 0x02, 0xa4, 0x92, 0xab, 0x00, 0x20, 0x01, 0x0b, + 0x30, 0x02, 0xc8, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc8, 0x00, 0xb1, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb0, 0x90, + 0x20, 0x0d, 0x28, 0x90, 0x8a, 0x40, 0x08, 0x80, + 0x60, 0x20, 0x2b, 0x08, 0x0c, 0x0a, 0x22, 0x11, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x11, 0xa4, + 0xa8, 0xab, 0x00, 0x22, 0x82, 0x0b, 0xb0, 0x82, + 0xe4, 0x08, 0x9a, 0x08, 0x2a, 0x40, 0x4a, 0xa0, + 0xa2, 0xac, 0x10, 0xab, 0x00, 0xa2, 0x04, 0x0b, + 0xb1, 0x22, 0xac, 0x20, 0x3b, 0x00, 0x2e, 0x50, + 0x0b, 0x80, 0x02, 0xec, 0x80, 0xb9, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x00, 0xec, 0x00, 0xb9, 0x00, + 0x22, 0x80, 0x48, 0xb8, 0x4a, 0xa4, 0x44, 0x8b, + 0x53, 0x20, 0x44, 0x18, 0x10, 0x02, 0x30, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xe0, + 0x00, 0xe0, 0x40, 0x32, 0x90, 0x0f, 0x90, 0x03, + 0xe4, 0x03, 0xc8, 0x40, 0x3e, 0x80, 0x0e, 0x20, + 0x03, 0xa4, 0x20, 0xeb, 0x00, 0x72, 0xe8, 0x0f, + 0xba, 0x03, 0xe5, 0x40, 0xb9, 0x00, 0x3e, 0xd0, + 0x0f, 0xb0, 0x03, 0xee, 0x00, 0xd8, 0xc8, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xb8, 0x01, + 0x32, 0x34, 0x4c, 0x9a, 0x0b, 0x62, 0x20, 0xc8, + 0x80, 0x22, 0x80, 0x0c, 0x89, 0x03, 0x10, 0xed, + 0x09, 0x00, 0x3d, 0x01, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x01, 0xb4, 0x00, 0xde, 0x96, + 0x3f, 0xe4, 0x8f, 0xb1, 0x03, 0xf2, 0x40, 0xee, + 0xa2, 0x33, 0xf0, 0x0d, 0xe1, 0x03, 0x74, 0x10, + 0xdf, 0x18, 0x1f, 0x60, 0x0f, 0xf8, 0x03, 0xf6, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xe0, 0x03, + 0xfe, 0x00, 0xfd, 0x10, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xfe, 0x20, 0xbe, 0x40, 0x0f, + 0xf0, 0x5b, 0xfa, 0x20, 0xfe, 0x80, 0x3f, 0x00, + 0x0f, 0xa8, 0x43, 0x78, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x10, 0xa1, 0x20, 0xfb, 0x40, + 0x3e, 0x82, 0x0c, 0x94, 0x23, 0x64, 0x80, 0xc9, + 0x04, 0x3e, 0xc2, 0x0c, 0xa4, 0x13, 0xe5, 0x02, + 0xcb, 0x40, 0x32, 0x48, 0xcf, 0xb4, 0xa3, 0x27, + 0x00, 0xf9, 0x08, 0x36, 0xe0, 0x0f, 0x98, 0x03, + 0xed, 0x20, 0xf8, 0x00, 0x36, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xf8, 0x00, 0x32, 0xdc, 0x2c, + 0x98, 0x43, 0xed, 0x04, 0xf1, 0x01, 0x3e, 0x83, + 0x0f, 0xb0, 0x03, 0x10, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x05, 0x05, 0x00, 0x3b, 0x40, + 0xa2, 0xc0, 0x28, 0xb8, 0x22, 0x0c, 0x00, 0xdb, + 0x00, 0x2c, 0xc0, 0x40, 0xad, 0x42, 0xcd, 0x80, + 0x73, 0x44, 0x22, 0x60, 0x0f, 0xb0, 0x82, 0x26, + 0x00, 0xbb, 0x40, 0x82, 0xe0, 0x4b, 0x8d, 0x42, + 0xec, 0x04, 0xb9, 0x58, 0x2a, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xb8, 0xc8, 0x22, 0xd0, 0x08, + 0x3c, 0x02, 0xee, 0x80, 0xbb, 0x08, 0x3a, 0x10, + 0x0b, 0xb0, 0x80, 0x32, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x05, 0x48, 0x00, 0xb3, 0x60, + 0x2c, 0x10, 0x08, 0x10, 0x22, 0x42, 0x40, 0x80, + 0x00, 0x2c, 0x50, 0x01, 0x2c, 0x06, 0xc7, 0x80, + 0xa3, 0xc4, 0x20, 0xc0, 0x0b, 0x0c, 0x02, 0x09, + 0x80, 0xb0, 0xed, 0x09, 0x00, 0x3e, 0x01, 0x80, + 0x24, 0x00, 0x0b, 0x34, 0x02, 0x4d, 0x01, 0x91, + 0xc0, 0x24, 0xc0, 0x8b, 0x30, 0x02, 0xcc, 0x01, + 0xb8, 0x48, 0x22, 0x20, 0x18, 0x10, 0x02, 0xe0, + 0x00, 0xb0, 0xa4, 0x2c, 0x34, 0x0b, 0x0c, 0x82, + 0x38, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x12, 0x00, 0x37, 0x90, 0x61, 0xe2, 0x88, + 0x7c, 0x82, 0x32, 0x09, 0x84, 0xd0, 0x6d, 0x60, + 0x39, 0x69, 0x82, 0xd6, 0x02, 0xbf, 0x88, 0x21, + 0xe0, 0x0b, 0xd8, 0x02, 0x1e, 0x00, 0xb6, 0x88, + 0x21, 0x24, 0x0b, 0x68, 0x12, 0xde, 0x01, 0xbf, + 0x00, 0xa9, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, + 0xb7, 0x80, 0x21, 0xe0, 0x18, 0x4c, 0x22, 0xde, + 0x00, 0xb5, 0x90, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x08, 0x04, 0x40, 0xf3, 0x00, 0xbc, 0x04, 0x08, + 0x10, 0x03, 0x40, 0x40, 0x80, 0x00, 0x3c, 0x40, + 0x5d, 0x20, 0x43, 0xe4, 0x80, 0xc1, 0x20, 0x30, + 0xc2, 0x0f, 0x11, 0x03, 0x08, 0x10, 0xf0, 0x10, + 0x34, 0x00, 0x0f, 0x11, 0x03, 0xcc, 0x00, 0xf1, + 0x10, 0x34, 0xc0, 0x0f, 0x30, 0x02, 0xcc, 0x00, + 0xf2, 0x10, 0x30, 0x54, 0x0c, 0x30, 0x03, 0xc8, + 0xc0, 0xf2, 0x14, 0x3c, 0x00, 0x9f, 0x20, 0x0b, + 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x1d, 0xb4, 0x00, 0xf7, 0x02, 0xbd, 0xc4, 0x0f, + 0xf0, 0x03, 0xd4, 0x18, 0xfc, 0x04, 0x3f, 0xc0, + 0x0e, 0xf0, 0x03, 0xfc, 0x00, 0xf7, 0x00, 0x3f, + 0x40, 0xce, 0x50, 0x03, 0xf4, 0x40, 0xf6, 0x00, + 0x3f, 0x00, 0x0f, 0xc8, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0xbf, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0x7f, 0x10, 0x3f, 0xc1, 0x0f, 0xe1, 0x03, 0xfc, + 0x40, 0xff, 0x11, 0x3b, 0xc4, 0x0f, 0xf0, 0x13, + 0xd0, 0x06, 0x60, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x3f, 0x01, 0x00, 0x00, 0xa8, 0x05, 0xe8, 0x00, + 0xf3, 0x82, 0x32, 0x80, 0x8d, 0x90, 0x03, 0xe4, + 0x00, 0xf1, 0x80, 0x1a, 0x80, 0x2c, 0xa0, 0x03, + 0x24, 0x00, 0xca, 0x00, 0x2e, 0xc0, 0x0f, 0xb0, + 0x12, 0x64, 0x00, 0x78, 0x00, 0x3e, 0xa0, 0x0c, + 0xb0, 0x03, 0xc6, 0x00, 0xc3, 0x00, 0x3a, 0xc0, + 0x8f, 0xb0, 0x03, 0xec, 0x00, 0xf9, 0x00, 0x3e, + 0x80, 0x0f, 0xb0, 0x03, 0x24, 0x00, 0xfb, 0x00, + 0x32, 0xc0, 0x0c, 0x90, 0x03, 0xea, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x98, 0x00, + 0xb7, 0x00, 0xa1, 0xc0, 0x0b, 0x70, 0x02, 0xd0, + 0x00, 0xb6, 0x02, 0x21, 0xc0, 0x08, 0x60, 0x0a, + 0x34, 0x00, 0xa6, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xdc, 0x00, 0xb6, 0x00, 0x2d, 0x80, 0x08, + 0x60, 0x02, 0xd4, 0x00, 0xa7, 0x00, 0x21, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0xf0, 0x02, 0x1c, 0x00, 0xb7, 0x00, + 0x21, 0xc1, 0x08, 0x70, 0x02, 0xd2, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x9a, 0x00, + 0xbf, 0x80, 0x21, 0xa0, 0x9b, 0x58, 0x02, 0xdf, + 0x00, 0xbd, 0x89, 0x29, 0xe0, 0x18, 0x78, 0x82, + 0x16, 0x00, 0x96, 0x80, 0x2d, 0xe0, 0x8b, 0x78, + 0x06, 0xde, 0x10, 0xb4, 0x80, 0x2f, 0xb0, 0x08, + 0x58, 0x02, 0xf7, 0x00, 0x87, 0x80, 0x29, 0xe0, + 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x0a, 0x1e, 0x20, 0xb3, 0x84, + 0x69, 0xe1, 0x48, 0x78, 0x22, 0xf0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xce, 0x0c, + 0xb3, 0x00, 0x20, 0xe0, 0x0b, 0x3e, 0x02, 0xcc, + 0x00, 0xb3, 0x80, 0x20, 0xc2, 0x08, 0x30, 0x02, + 0x0c, 0x00, 0xb2, 0x00, 0x2c, 0xe0, 0x0b, 0x30, + 0x06, 0xce, 0x40, 0xb6, 0x00, 0x2c, 0x80, 0x28, + 0xed, 0x09, 0x00, 0x40, 0x01, 0x40, 0x02, 0xc6, + 0x00, 0xa3, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x40, 0x2c, 0xd0, 0x0b, 0x28, + 0x02, 0x0f, 0x80, 0xb3, 0x00, 0x28, 0xe0, 0x08, + 0x34, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x15, 0xbb, 0x20, 0xfe, 0x00, 0x33, + 0x90, 0x0d, 0xec, 0x03, 0xfb, 0x00, 0xfe, 0x40, + 0x39, 0xa0, 0x0c, 0x6c, 0x03, 0x19, 0x00, 0xd6, + 0x18, 0x2f, 0x98, 0x0f, 0xe6, 0x23, 0x79, 0x00, + 0xfa, 0x00, 0x3e, 0xa0, 0x0c, 0xa0, 0x03, 0xf9, + 0x00, 0xce, 0x48, 0x3a, 0x80, 0x0f, 0xa0, 0x03, + 0xe8, 0x00, 0xfe, 0x40, 0x3f, 0x84, 0x0f, 0xe6, + 0x03, 0x39, 0x00, 0xbe, 0xa0, 0x3b, 0x94, 0x0c, + 0xe0, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0xe2, 0x00, 0xf8, 0x00, 0x3e, + 0x34, 0x0f, 0x81, 0x03, 0xe3, 0x00, 0xf8, 0x82, + 0x3e, 0x04, 0x0f, 0x8c, 0x33, 0xe3, 0x04, 0xe8, + 0x40, 0x3e, 0x20, 0x07, 0x8c, 0x07, 0xe2, 0x00, + 0xf8, 0x40, 0x3f, 0x00, 0x0f, 0x84, 0x03, 0xe2, + 0x08, 0xf8, 0x80, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x20, 0x3e, 0x10, 0x0f, 0x82, + 0x03, 0xe0, 0x00, 0xb8, 0x00, 0xa6, 0x04, 0x2f, + 0x84, 0x83, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x10, 0xe6, 0x00, 0xf9, 0x00, 0x3e, + 0x61, 0x0c, 0x98, 0x03, 0xe5, 0x00, 0xf9, 0x80, + 0x3a, 0x40, 0x0c, 0x90, 0x03, 0x24, 0x10, 0x49, + 0x92, 0x32, 0x40, 0x0c, 0x9a, 0x03, 0x26, 0x80, + 0xf9, 0x00, 0x32, 0x50, 0x07, 0x90, 0x03, 0xe6, + 0x80, 0xf9, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0x31, 0x82, 0x3a, 0x60, 0x0f, 0x11, + 0x23, 0x04, 0x04, 0xc9, 0x88, 0x38, 0x40, 0x2c, + 0x98, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x04, 0xed, 0x09, 0x00, 0x41, 0x01, + 0x64, 0xc0, 0xb9, 0x00, 0x2c, 0x51, 0x8a, 0x9d, + 0x02, 0xe6, 0x00, 0xb9, 0xd8, 0x26, 0x76, 0x8a, + 0x91, 0x02, 0x25, 0x00, 0x89, 0x40, 0x28, 0x44, + 0x08, 0x14, 0x8a, 0x24, 0x00, 0xb1, 0x00, 0xa2, + 0x40, 0x4b, 0x91, 0x02, 0xe7, 0x00, 0xb1, 0x50, + 0x22, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x10, 0xb9, + 0x80, 0x22, 0x76, 0x0b, 0x9c, 0x02, 0x26, 0x10, + 0xa9, 0x10, 0x22, 0x54, 0x08, 0x9e, 0x02, 0xe0, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, + 0x24, 0x00, 0xbb, 0x00, 0x2e, 0x54, 0x48, 0x94, + 0x42, 0xe4, 0x00, 0xb9, 0x00, 0x2a, 0x40, 0x48, + 0x90, 0x82, 0x27, 0x00, 0xab, 0x40, 0x22, 0x40, + 0x28, 0x90, 0x02, 0x24, 0x00, 0xbb, 0x28, 0x23, + 0x40, 0x0b, 0xd0, 0x82, 0xec, 0x00, 0xb9, 0x00, + 0x26, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x20, 0x2a, 0x40, 0x0b, 0x90, 0x02, 0x24, 0x80, + 0x81, 0x00, 0x2a, 0x42, 0x08, 0x91, 0x02, 0xc6, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x04, 0x00, 0xb1, 0x80, 0x2c, 0x40, 0x0a, 0x14, + 0x02, 0xcc, 0x00, 0xb1, 0x00, 0x26, 0x40, 0x0a, + 0x90, 0x0a, 0x25, 0x00, 0xa1, 0x00, 0xaa, 0x60, + 0x48, 0x10, 0x02, 0x06, 0x10, 0xb5, 0x00, 0x21, + 0x50, 0x0b, 0x54, 0x02, 0xc7, 0x00, 0xb1, 0x80, + 0x84, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, + 0xc0, 0x20, 0x50, 0x0b, 0x14, 0x0a, 0x07, 0x00, + 0x83, 0x40, 0x20, 0x50, 0x08, 0x14, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, + 0x60, 0x00, 0xf8, 0x02, 0x3e, 0x00, 0x0c, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3a, 0x00, 0x0c, + 0x80, 0x13, 0x20, 0x02, 0xe8, 0x00, 0x32, 0x00, + 0x4c, 0x80, 0x0b, 0x20, 0x00, 0xf8, 0x00, 0x32, + 0x00, 0x8f, 0xc0, 0x13, 0xe0, 0x00, 0xed, 0x09, + 0x00, 0x42, 0x01, 0xf8, 0x00, 0x36, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x0c, 0xf8, 0x00, 0x3a, 0x00, + 0x8f, 0xa0, 0x03, 0x20, 0x02, 0xc8, 0x00, 0x38, + 0x00, 0x0c, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x1d, 0xf4, 0x00, 0xfd, + 0x42, 0x3f, 0x40, 0x0f, 0xd4, 0x43, 0xf4, 0x00, + 0xfd, 0x00, 0x1d, 0x41, 0x0f, 0x50, 0x03, 0xf4, + 0x08, 0xdd, 0x00, 0x37, 0x40, 0x0f, 0xd0, 0x43, + 0xf4, 0x00, 0xf9, 0x00, 0x34, 0x40, 0x0f, 0x90, + 0x03, 0xf4, 0x00, 0xfd, 0x00, 0x3a, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x08, 0xfd, 0x40, 0x3f, 0x50, + 0x8f, 0xd4, 0x13, 0xf5, 0x01, 0xfd, 0x41, 0x3f, + 0x50, 0x0f, 0xf4, 0x03, 0xe6, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x05, 0xd4, 0x00, 0xcd, + 0x20, 0x33, 0x40, 0x0f, 0xd4, 0xa3, 0xb4, 0x00, + 0xfd, 0x01, 0x3f, 0x40, 0x0b, 0xd0, 0x43, 0x34, + 0x00, 0xc5, 0x02, 0x33, 0x40, 0x0c, 0xd0, 0x72, + 0x54, 0x10, 0x7d, 0x00, 0x3f, 0x40, 0x0f, 0xd0, + 0x03, 0xf4, 0x00, 0xcd, 0x00, 0x32, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x01, 0xfd, 0x00, 0x33, 0xd0, + 0x0f, 0xd0, 0x83, 0xf5, 0x00, 0xcd, 0x40, 0x33, + 0x50, 0x0d, 0xf3, 0x03, 0xc6, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x02, 0x88, + 0x00, 0x22, 0x00, 0x0b, 0x86, 0x03, 0x60, 0x04, + 0xba, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x03, 0x68, + 0x00, 0x88, 0x00, 0xb6, 0x00, 0x0a, 0x80, 0x02, + 0xe0, 0x00, 0xe8, 0x02, 0x2e, 0x00, 0x0b, 0x80, + 0x02, 0xe0, 0x02, 0x88, 0x00, 0x22, 0x00, 0x0b, + 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x20, 0x22, 0x00, + 0x8b, 0xa2, 0x02, 0xe1, 0x80, 0x88, 0x40, 0x22, + 0x10, 0x0a, 0x87, 0x02, 0xce, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, 0x81, + 0xc0, 0xed, 0x09, 0x00, 0x43, 0x01, 0x20, 0x40, + 0x0b, 0x10, 0x02, 0x84, 0x00, 0xb1, 0x00, 0x0c, + 0x40, 0x09, 0x10, 0x02, 0x24, 0x22, 0x81, 0x00, + 0x2a, 0x40, 0x09, 0x10, 0x00, 0x4c, 0x01, 0xb1, + 0x00, 0x2c, 0x4a, 0x0b, 0x12, 0x82, 0xe4, 0x26, + 0x89, 0x03, 0x20, 0x40, 0x4b, 0x10, 0x42, 0xc4, + 0x00, 0xb1, 0x48, 0x24, 0xd0, 0x0b, 0x10, 0x82, + 0xc5, 0x81, 0x81, 0x60, 0x20, 0x58, 0x09, 0x10, + 0x22, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x15, 0xa5, 0x00, 0x89, 0x80, 0xa2, 0x40, + 0x0b, 0x94, 0x02, 0x64, 0x04, 0xb9, 0x00, 0x2e, + 0x60, 0x03, 0x90, 0x02, 0x64, 0x40, 0x89, 0x00, + 0x4e, 0x40, 0x0b, 0x90, 0x82, 0x64, 0x60, 0xa9, + 0x00, 0x2e, 0x40, 0x03, 0x90, 0x02, 0xe4, 0x08, + 0x89, 0x00, 0x6a, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x10, 0x26, 0x40, 0x0b, 0x90, 0x02, + 0xc4, 0x06, 0x89, 0x00, 0x22, 0xc0, 0x0a, 0x90, + 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x15, 0xc7, 0x00, 0xc9, 0xc0, 0x32, 0x52, + 0x0f, 0x9d, 0x03, 0xa5, 0xc0, 0xf9, 0xc0, 0x3e, + 0x42, 0x0d, 0x9f, 0x03, 0x05, 0x10, 0xc1, 0x80, + 0x3a, 0x68, 0x5d, 0x94, 0x22, 0x64, 0x04, 0xf9, + 0x04, 0x3e, 0x40, 0xcf, 0x90, 0x47, 0xc5, 0x24, + 0xc9, 0x00, 0xb2, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xb9, 0x00, 0xb6, 0x58, 0x0f, 0x98, 0x03, + 0xe5, 0x80, 0xc9, 0x18, 0xb2, 0x40, 0x0d, 0x95, + 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x01, 0xa4, 0x60, 0xf1, 0x00, 0x3e, 0x40, + 0x0f, 0x10, 0x03, 0xe4, 0x04, 0xf9, 0xc0, 0x3e, + 0x40, 0x0f, 0x90, 0x13, 0xe4, 0x10, 0x79, 0x10, + 0x36, 0x65, 0x0e, 0x90, 0x03, 0xe6, 0x00, 0xe9, + 0x00, 0x3e, 0x41, 0x4f, 0x92, 0x37, 0xe4, 0x00, + 0xf9, 0x00, 0x36, 0x40, 0xed, 0x09, 0x00, 0x44, + 0x01, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3a, 0x44, 0x1f, 0x9c, 0x23, 0xe4, 0x80, 0xf9, + 0x00, 0x3e, 0x40, 0x05, 0x90, 0x03, 0xca, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa0, + 0x00, 0xd8, 0x80, 0x3e, 0x30, 0x0f, 0x84, 0x13, + 0xa0, 0x30, 0xd8, 0xc0, 0x3e, 0x00, 0x0f, 0x80, + 0x23, 0x20, 0x00, 0xc8, 0x00, 0x32, 0x20, 0x0f, + 0x8c, 0x03, 0xe2, 0x00, 0xe8, 0x90, 0x3e, 0x00, + 0xcf, 0x81, 0x83, 0xe1, 0x20, 0xd8, 0x80, 0xb2, + 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xd0, 0x24, + 0x32, 0x18, 0x0f, 0x82, 0x03, 0xe1, 0x20, 0xf8, + 0xc1, 0x3c, 0x00, 0x2c, 0x87, 0x03, 0xca, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x38, + 0x00, 0x8e, 0xc4, 0x2f, 0xb2, 0x0b, 0xe6, 0x02, + 0x39, 0x00, 0x8e, 0x40, 0x2f, 0x83, 0x03, 0x62, + 0x02, 0xb8, 0x42, 0x8e, 0x84, 0x81, 0xb8, 0x0b, + 0xe4, 0xa2, 0xf9, 0x00, 0x8e, 0xc1, 0x2f, 0x90, + 0x4b, 0xe4, 0x02, 0xf9, 0x80, 0x86, 0xe0, 0x22, + 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xbe, 0x00, + 0x23, 0x90, 0x4b, 0xe0, 0x02, 0xf9, 0x30, 0xbe, + 0x08, 0x2f, 0xa0, 0x48, 0xec, 0x02, 0xca, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, + 0x00, 0x90, 0x00, 0x2c, 0x40, 0x0b, 0x34, 0x86, + 0x88, 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x0b, 0x38, + 0x02, 0x0f, 0x00, 0x83, 0x80, 0x2c, 0x20, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x80, 0x2c, 0xdc, + 0x09, 0x34, 0x02, 0xcc, 0x00, 0x93, 0x00, 0x24, + 0xc0, 0x0b, 0x30, 0x00, 0xcc, 0x00, 0xb3, 0x80, + 0x20, 0xc0, 0x0b, 0x3c, 0x02, 0x4c, 0x00, 0xbb, + 0x00, 0x2c, 0xc0, 0x08, 0x38, 0x02, 0xca, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1d, + 0x00, 0x84, 0x40, 0x2d, 0x40, 0x0b, 0xf0, 0xed, + 0x09, 0x00, 0x45, 0x01, 0x02, 0x16, 0x08, 0x86, + 0x0a, 0x2d, 0xc0, 0x0b, 0xd0, 0x02, 0xbc, 0x28, + 0x87, 0x40, 0x2d, 0x00, 0x0b, 0x70, 0x22, 0xda, + 0x00, 0x17, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xdc, 0x08, 0x8f, 0x00, 0x25, 0xc0, 0x0b, 0x70, + 0x12, 0xdc, 0x00, 0xb7, 0x40, 0x21, 0xc0, 0x8b, + 0x70, 0x92, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0x51, + 0x88, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xd4, 0x80, + 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0x92, 0x00, 0xd7, + 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0x1e, 0x00, + 0xc7, 0x80, 0x39, 0x20, 0x0f, 0x78, 0x03, 0xda, + 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0d, 0x58, 0x03, + 0xfe, 0x00, 0xd7, 0x80, 0x35, 0xe0, 0x0f, 0x78, + 0x03, 0xde, 0x00, 0xf3, 0x80, 0xb1, 0xe0, 0x0f, + 0x78, 0x13, 0x5e, 0x08, 0xf7, 0x80, 0x3c, 0xe0, + 0x0c, 0x78, 0x43, 0xea, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x1d, 0xa8, 0x10, 0xf8, 0x04, + 0x3e, 0x40, 0x0f, 0x20, 0x03, 0xc0, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x0f, 0x30, 0x00, 0xc8, 0x00, + 0xfa, 0x00, 0x32, 0x80, 0x0f, 0xb0, 0x03, 0xe8, + 0x00, 0xeb, 0x02, 0x3e, 0x40, 0x0f, 0x80, 0x03, + 0xec, 0x00, 0xf2, 0x00, 0x3a, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xf9, 0x00, 0x3e, 0x00, 0x0f, + 0xa0, 0x23, 0xe4, 0x04, 0xfa, 0x01, 0x3e, 0x80, + 0x0f, 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xcf, 0x80, + 0x3d, 0x60, 0x0c, 0xe8, 0x43, 0x3e, 0x00, 0xfc, + 0x90, 0x1f, 0xe4, 0x24, 0xd8, 0x43, 0x3e, 0x00, + 0xef, 0x84, 0x21, 0x25, 0x6c, 0x79, 0x03, 0x3a, + 0x00, 0xfe, 0x80, 0x33, 0x64, 0x0f, 0xe8, 0x03, + 0x3e, 0x00, 0xc5, 0x80, 0x33, 0xe0, 0x0f, 0xf8, + 0x03, 0xfe, 0xed, 0x09, 0x00, 0x46, 0x01, 0x00, + 0xff, 0x80, 0x33, 0xe0, 0x0e, 0xf8, 0x01, 0x3e, + 0x40, 0xdf, 0x94, 0x3f, 0xe4, 0x04, 0xf8, 0x03, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x11, 0x9c, 0x00, 0x86, 0x00, 0x2d, 0x46, 0x08, + 0x60, 0x02, 0x10, 0x44, 0xb4, 0x00, 0x2d, 0xc0, + 0x08, 0x50, 0x03, 0x74, 0x10, 0x85, 0x00, 0x35, + 0x10, 0x08, 0x60, 0x22, 0x10, 0x00, 0xb7, 0x00, + 0x21, 0x40, 0x0b, 0x40, 0x02, 0x1c, 0x08, 0x85, + 0x00, 0x21, 0xc0, 0x8b, 0x70, 0x02, 0xdc, 0x00, + 0xb6, 0x08, 0x35, 0xc0, 0x08, 0x54, 0x42, 0x19, + 0x00, 0xb7, 0x00, 0x2f, 0x4c, 0x4f, 0x75, 0x02, + 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb4, 0x00, 0x87, 0x08, 0x2f, 0xc0, 0x08, + 0x60, 0x02, 0x11, 0x00, 0xb6, 0x01, 0x2f, 0xc0, + 0x19, 0xd0, 0x82, 0x54, 0x40, 0xaf, 0x00, 0x23, + 0x00, 0xc8, 0x74, 0x0a, 0x18, 0x00, 0xbf, 0x00, + 0x21, 0x40, 0x0b, 0xc0, 0x02, 0x1c, 0x00, 0xad, + 0x00, 0x25, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, + 0xb7, 0x00, 0x21, 0xc0, 0x0a, 0x70, 0x02, 0x5c, + 0x18, 0x95, 0x0a, 0x2d, 0x40, 0x08, 0x00, 0x02, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x14, 0xc6, 0x20, 0x82, 0x00, 0x2c, 0xd0, 0x08, + 0x80, 0x8a, 0x02, 0x00, 0xb2, 0x48, 0x2c, 0x82, + 0x09, 0x12, 0x02, 0x43, 0x01, 0x80, 0x80, 0x24, + 0x00, 0x08, 0x30, 0x02, 0x02, 0x01, 0xb3, 0x00, + 0x22, 0x60, 0x0b, 0x84, 0x02, 0x0c, 0x20, 0xa1, + 0x00, 0x24, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb0, 0x88, 0x24, 0x12, 0x08, 0x0a, 0x20, 0xc0, + 0x00, 0xb0, 0x88, 0x2e, 0x00, 0x1b, 0x84, 0x02, + 0x08, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x15, 0x8f, 0x00, 0xca, 0x82, 0x3e, 0x70, 0x2c, + 0x88, 0x03, 0x24, 0x00, 0xfb, 0xed, 0x09, 0x00, + 0x47, 0x01, 0xc0, 0x3e, 0xc1, 0x0d, 0xbc, 0x2a, + 0x6d, 0x00, 0xeb, 0x80, 0xb2, 0x42, 0x0c, 0xb4, + 0x03, 0x2b, 0x80, 0xf1, 0xa0, 0x32, 0x5c, 0x8f, + 0x84, 0x03, 0x0d, 0x02, 0xeb, 0x00, 0x26, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xbb, 0x00, 0x32, + 0xf0, 0x0e, 0xb4, 0x01, 0x6e, 0x00, 0xdb, 0x84, + 0x3e, 0x90, 0x0c, 0xb4, 0x83, 0x2a, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x40, + 0xfa, 0x40, 0x3e, 0x50, 0x0f, 0x88, 0x03, 0xe0, + 0x44, 0xfa, 0x80, 0x3e, 0xc4, 0x0e, 0x90, 0x03, + 0xec, 0x60, 0xfb, 0x50, 0x3a, 0x00, 0x0f, 0xb4, + 0x03, 0xe8, 0x20, 0xfb, 0x00, 0xbe, 0x50, 0x0d, + 0x80, 0x03, 0xec, 0x04, 0xdb, 0x30, 0x3a, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3c, + 0xc4, 0x4f, 0xb1, 0x03, 0x0c, 0x40, 0x79, 0x00, + 0x1e, 0x47, 0x2c, 0x80, 0x03, 0xe0, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, + 0xc6, 0x90, 0x33, 0xc2, 0x0f, 0x80, 0x03, 0x76, + 0x00, 0xce, 0x00, 0x3f, 0xe8, 0x8c, 0xf2, 0x03, + 0xf8, 0x04, 0xfd, 0x80, 0x3f, 0x20, 0x0c, 0xf2, + 0x02, 0xf8, 0x00, 0xff, 0x00, 0x33, 0x40, 0x0d, + 0xc0, 0x83, 0x3c, 0x00, 0xcf, 0x00, 0x33, 0xc0, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xfa, 0x00, 0x3f, + 0xc0, 0x0c, 0xd9, 0x03, 0xf8, 0x60, 0xcf, 0x00, + 0x13, 0x80, 0x0e, 0xf0, 0x81, 0x00, 0x44, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x68, 0x00, + 0x8a, 0x88, 0x22, 0x08, 0x0b, 0x88, 0x02, 0x80, + 0xc0, 0xaa, 0x40, 0x2c, 0xa0, 0x48, 0xac, 0x42, + 0xeb, 0x20, 0xb9, 0x00, 0x2c, 0x14, 0x0d, 0xbc, + 0x02, 0xe8, 0x00, 0xbb, 0x10, 0x22, 0x60, 0x88, + 0x8e, 0x02, 0xaf, 0x00, 0x80, 0x10, 0x22, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x08, 0xb8, 0xd8, 0x2e, + 0xed, 0x09, 0x00, 0x48, 0x01, 0x00, 0x28, 0x84, + 0x02, 0xe1, 0x00, 0x88, 0x08, 0x22, 0x90, 0x00, + 0x8d, 0x0a, 0x20, 0x40, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x05, 0x2c, 0x00, 0x8b, 0x00, 0xa2, + 0x40, 0x0b, 0x88, 0x02, 0x64, 0x08, 0x88, 0x08, + 0x2e, 0xc0, 0x08, 0x90, 0x82, 0xe6, 0x00, 0xbb, + 0x18, 0x2e, 0x00, 0x08, 0xb4, 0x02, 0xe8, 0x80, + 0xba, 0x00, 0x22, 0x30, 0x49, 0x88, 0x02, 0x2e, + 0x20, 0x89, 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0x89, 0x00, 0x2e, 0x04, 0x08, 0xa0, + 0x02, 0xe4, 0x00, 0x82, 0x80, 0x2a, 0x80, 0x08, + 0xb0, 0x22, 0xa0, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x2c, 0x10, 0x82, 0x00, 0x20, + 0x40, 0x4b, 0x08, 0x02, 0x84, 0x04, 0xa0, 0x00, + 0x2c, 0xc0, 0x28, 0x10, 0x02, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x00, 0x09, 0x30, 0x02, 0xc2, 0x00, + 0xbb, 0x04, 0x20, 0x00, 0x08, 0x00, 0x02, 0xac, + 0x00, 0x81, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x08, 0xb0, 0x00, 0x2c, 0x20, 0x08, 0x00, + 0x42, 0xc0, 0x02, 0x80, 0x00, 0xa8, 0x40, 0x08, + 0x00, 0x02, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x64, 0x00, 0xca, 0x00, 0x32, + 0x80, 0x0f, 0x80, 0x03, 0x64, 0x00, 0x8a, 0x00, + 0x3e, 0x40, 0x0c, 0xb0, 0x13, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x00, 0x0c, 0xb0, 0x03, 0xe8, 0x00, + 0xfb, 0x00, 0x32, 0x00, 0x85, 0x80, 0x43, 0x24, + 0x04, 0xc9, 0x00, 0xb2, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x11, 0xd8, 0x00, 0x3c, 0x00, 0x0c, 0x00, + 0x03, 0xe0, 0x00, 0xc8, 0x00, 0x3a, 0x00, 0x0e, + 0x80, 0x03, 0x80, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1d, 0xd4, 0x00, 0xfe, 0x00, 0x3f, + 0x80, 0x0f, 0xc0, 0x03, 0xf4, 0x00, 0xfe, 0x01, + 0x1d, 0x01, 0x8f, 0xed, 0x09, 0x00, 0x49, 0x01, + 0x60, 0x07, 0xf0, 0x00, 0xf5, 0x00, 0x3f, 0x00, + 0x0f, 0xd0, 0x01, 0xf8, 0x00, 0xf7, 0x00, 0x3f, + 0x00, 0x0f, 0x40, 0x13, 0xd0, 0x00, 0xfd, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x01, 0xfc, + 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x02, 0xf0, 0x00, + 0xfc, 0x00, 0x37, 0x00, 0x0f, 0xc0, 0x03, 0x68, + 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x85, + 0xd0, 0x00, 0xcf, 0x20, 0x3f, 0xcc, 0x0e, 0xc4, + 0x03, 0x30, 0x40, 0xfc, 0x14, 0x33, 0xc0, 0x2c, + 0xc0, 0x03, 0x9c, 0x80, 0xff, 0x28, 0x33, 0xc0, + 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xff, 0x20, 0x33, + 0xc2, 0x0c, 0xc0, 0x03, 0xfc, 0x00, 0xd4, 0x00, + 0x33, 0x04, 0x0f, 0xc4, 0x03, 0x70, 0x00, 0xdc, + 0x00, 0x37, 0x00, 0x0c, 0x40, 0x03, 0x38, 0x00, + 0xff, 0x10, 0x37, 0x00, 0x0c, 0xf0, 0x03, 0xf0, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x18, + 0xac, 0x00, 0x8f, 0x10, 0x2f, 0xd9, 0x08, 0xb0, + 0x02, 0x2c, 0x80, 0x9b, 0x00, 0x23, 0xd4, 0x08, + 0xb2, 0x02, 0x3c, 0x10, 0xbf, 0x40, 0x23, 0xd4, + 0x0b, 0xb0, 0x02, 0xec, 0x80, 0x8f, 0x10, 0x23, + 0xd0, 0x08, 0x32, 0x02, 0xec, 0x20, 0xb8, 0x20, + 0x22, 0x00, 0x08, 0x82, 0x02, 0xe0, 0xa0, 0xb8, + 0x00, 0x20, 0x80, 0xc8, 0x80, 0x02, 0x21, 0x80, + 0xb3, 0x42, 0x22, 0x18, 0x0a, 0xb0, 0x02, 0xe0, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x04, + 0x8c, 0x00, 0x83, 0x00, 0x2c, 0xd0, 0x08, 0xb0, + 0x02, 0x8c, 0x00, 0xb3, 0x23, 0x20, 0xc0, 0x0a, + 0xb2, 0x82, 0x8d, 0x00, 0xb3, 0x00, 0xa0, 0xc0, + 0x4b, 0x30, 0x22, 0xec, 0x20, 0xa3, 0x00, 0x20, + 0xc0, 0x28, 0x30, 0x82, 0x8c, 0x80, 0x8b, 0x08, + 0x28, 0x08, 0x0a, 0x02, 0x02, 0x48, 0x80, 0x90, + 0x00, 0x24, 0x02, 0x08, 0x80, 0x0a, 0xed, 0x09, + 0x00, 0x4a, 0x01, 0x89, 0x24, 0xb3, 0x60, 0x24, + 0x12, 0x08, 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x04, 0xa8, 0x00, 0x8b, + 0x00, 0x2e, 0xc0, 0x08, 0xa1, 0x0a, 0xac, 0x00, + 0x9b, 0x00, 0x22, 0xc0, 0x0a, 0xb0, 0x02, 0x2c, + 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x03, 0xb0, 0x02, + 0xec, 0x00, 0x8b, 0x00, 0x22, 0xc0, 0x08, 0xa4, + 0x02, 0xec, 0x05, 0xb8, 0x40, 0xa8, 0x00, 0x08, + 0x80, 0x12, 0xe8, 0x00, 0xb8, 0x00, 0x22, 0x81, + 0x08, 0xb5, 0x00, 0xa0, 0x00, 0xbb, 0x00, 0x22, + 0x22, 0x0a, 0xb0, 0x02, 0xf0, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x11, 0xcd, 0x40, 0xcb, + 0x00, 0x3e, 0xc0, 0x2e, 0x3c, 0x03, 0xad, 0x60, + 0xfb, 0x48, 0x92, 0xc0, 0x0e, 0xbc, 0x83, 0xac, + 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb8, 0x02, + 0xcc, 0x98, 0xfb, 0x00, 0xb2, 0xc0, 0x08, 0xbd, + 0x63, 0xec, 0x00, 0xd0, 0x82, 0x3a, 0x88, 0x0e, + 0x8a, 0x01, 0x60, 0x80, 0xd3, 0x00, 0x16, 0x08, + 0x00, 0x88, 0x43, 0xaa, 0x00, 0xfb, 0x00, 0x36, + 0x70, 0x2c, 0xb0, 0x03, 0xd0, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x01, 0xb0, 0x10, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xd0, 0x03, 0x7e, 0x00, + 0xdd, 0x90, 0x3d, 0xc0, 0x0d, 0xfa, 0x03, 0xfc, + 0x00, 0xf7, 0x08, 0x3f, 0xc1, 0x0f, 0xf4, 0x42, + 0xfe, 0x50, 0xff, 0x01, 0x3d, 0xc0, 0x0f, 0xf8, + 0x03, 0xfc, 0x00, 0xfc, 0x98, 0x37, 0x80, 0x0e, + 0xc9, 0x13, 0xf0, 0x00, 0xff, 0x00, 0x3f, 0x80, + 0x0f, 0xe0, 0x03, 0x7e, 0x40, 0xf7, 0x00, 0x3f, + 0x40, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x10, 0xa8, 0x00, 0xcb, + 0x88, 0x3c, 0xc0, 0x0c, 0xb0, 0x03, 0x64, 0x00, + 0xca, 0x42, 0x3e, 0xc0, 0x0c, 0x90, 0x03, 0xee, + 0x00, 0xed, 0x09, 0x00, 0x4b, 0x01, 0xcb, 0x05, + 0x3e, 0xc8, 0x4f, 0xb0, 0xa3, 0x69, 0x00, 0xf3, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x2c, 0x00, + 0xf9, 0x54, 0x36, 0xa2, 0x4f, 0x88, 0xa3, 0xaa, + 0x10, 0xcb, 0x00, 0x32, 0x20, 0x0d, 0x92, 0x03, + 0x29, 0x00, 0xcb, 0x01, 0x32, 0x60, 0x8f, 0xb0, + 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x05, 0x2e, 0x80, 0x8f, 0x40, 0x27, 0xc0, + 0x08, 0xb0, 0x03, 0x2c, 0x00, 0x8b, 0x00, 0x2f, + 0xc0, 0x4b, 0x30, 0x02, 0xfc, 0x00, 0x8f, 0xc0, + 0x2f, 0xc0, 0x0b, 0xb6, 0x02, 0xec, 0x00, 0xbf, + 0x80, 0x2f, 0xe8, 0x0b, 0xb0, 0x02, 0x2c, 0x00, + 0xb9, 0xc0, 0x02, 0xa0, 0x0b, 0x88, 0x02, 0x2a, + 0x00, 0x8b, 0x70, 0x62, 0xb1, 0x08, 0x32, 0x22, + 0x2c, 0x00, 0x8f, 0x00, 0x22, 0x74, 0x0b, 0xb0, + 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x04, 0x4c, 0x80, 0x83, 0x00, 0x2c, 0xc0, + 0x08, 0x30, 0x02, 0x4c, 0x02, 0x8b, 0x00, 0x2c, + 0xf6, 0x08, 0x30, 0x02, 0xcc, 0x20, 0x83, 0x40, + 0x2c, 0xd0, 0x0b, 0x24, 0x02, 0xcc, 0x00, 0xb3, + 0xc8, 0x24, 0xc2, 0x0b, 0x30, 0x02, 0x0c, 0x00, + 0xa0, 0x40, 0x04, 0x50, 0x0b, 0x34, 0x02, 0xc5, + 0x20, 0xb0, 0x80, 0x2e, 0x42, 0x0a, 0x08, 0x02, + 0xc0, 0x00, 0x83, 0x00, 0x22, 0x40, 0x0b, 0x30, + 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xb0, 0x00, 0x56, 0x00, 0x87, 0x80, 0x24, 0xe0, + 0x08, 0xf8, 0x02, 0x16, 0x00, 0x86, 0x90, 0x2d, + 0xe0, 0x1b, 0x58, 0x02, 0xde, 0x02, 0x87, 0x80, + 0x2d, 0xe2, 0x0b, 0x79, 0x02, 0xda, 0x00, 0xb7, + 0x80, 0x2d, 0xe0, 0x0b, 0x79, 0x0a, 0x9e, 0x10, + 0xbc, 0x80, 0x21, 0x60, 0x0b, 0x78, 0x06, 0xd6, + 0x09, 0x9c, 0x80, 0x29, 0xe0, 0x0a, 0xd8, 0x0a, + 0xf6, 0x02, 0x87, 0x80, 0xed, 0x09, 0x00, 0x4c, + 0x01, 0x21, 0x60, 0x0b, 0x78, 0x02, 0xc8, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x4d, + 0x00, 0xc3, 0x00, 0x3c, 0xc0, 0x0c, 0x14, 0x03, + 0x6c, 0x00, 0xc1, 0x00, 0x3c, 0xc0, 0x0c, 0x30, + 0x03, 0xcc, 0x80, 0xc3, 0x08, 0x3c, 0xc0, 0x0f, + 0x30, 0x03, 0x4c, 0x00, 0xf3, 0x08, 0x3c, 0xc4, + 0x0f, 0x30, 0x03, 0x0c, 0x00, 0xe2, 0x20, 0x34, + 0x49, 0x0f, 0xb2, 0x03, 0xec, 0x00, 0xf0, 0x00, + 0x38, 0x40, 0x0c, 0x20, 0x03, 0xc0, 0x00, 0x43, + 0x00, 0x30, 0x40, 0x0f, 0x30, 0x03, 0xd2, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, 0xbc, + 0x00, 0xff, 0x00, 0x37, 0xc4, 0x0f, 0x70, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc4, 0x0f, 0xf0, + 0x03, 0xfc, 0x20, 0xff, 0x18, 0x3f, 0xc2, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x48, 0x3f, 0xc2, + 0x0f, 0xf0, 0x03, 0x7c, 0x00, 0xfe, 0x00, 0x3f, + 0x40, 0x0f, 0xf0, 0x03, 0x3c, 0x44, 0xe4, 0x10, + 0x33, 0xc0, 0x0c, 0xf0, 0x03, 0x14, 0x48, 0xff, + 0x10, 0xbf, 0x40, 0x0f, 0xf0, 0x03, 0xd0, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0xa4, + 0x00, 0xfb, 0x68, 0x2e, 0xd0, 0x0f, 0xa0, 0x03, + 0xec, 0x00, 0xfb, 0x80, 0x36, 0xd3, 0x0f, 0xb0, + 0x03, 0xed, 0xa0, 0xfb, 0xc8, 0x3a, 0xda, 0x0f, + 0xb0, 0x03, 0x2c, 0x00, 0xfb, 0x20, 0x3e, 0xd9, + 0x0f, 0xa0, 0x23, 0x6c, 0x00, 0xf0, 0x00, 0x36, + 0xc0, 0x0f, 0xb0, 0x03, 0x64, 0x00, 0xdb, 0x01, + 0x3e, 0x60, 0x04, 0xb8, 0x03, 0x2a, 0x04, 0xcb, + 0x00, 0x3c, 0xc0, 0x2c, 0xb0, 0x03, 0xea, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x98, 0x9c, + 0x00, 0xb7, 0x00, 0x2d, 0xd2, 0x0b, 0x70, 0x00, + 0xdc, 0x00, 0xb7, 0x01, 0x21, 0xc0, 0x8b, 0x70, + 0x02, 0xdc, 0x80, 0xb7, 0x20, 0x21, 0xc8, 0xed, + 0x09, 0x00, 0x4d, 0x01, 0x0b, 0x70, 0x02, 0x9c, + 0x00, 0xb7, 0x20, 0x2d, 0xc2, 0x0f, 0x70, 0x02, + 0xbc, 0x00, 0x84, 0x00, 0x29, 0xc0, 0x0b, 0x70, + 0x12, 0x14, 0x10, 0x97, 0x00, 0x2f, 0xc0, 0x08, + 0x70, 0x12, 0xbc, 0x00, 0x87, 0x24, 0x2d, 0xc0, + 0x08, 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x9e, 0x20, 0xb7, 0x90, + 0x2d, 0xe8, 0x8b, 0x78, 0x02, 0xde, 0x00, 0xbf, + 0x86, 0x0d, 0xec, 0x0b, 0x78, 0x02, 0xde, 0x98, + 0xb7, 0x80, 0x29, 0xe8, 0x0b, 0x70, 0x40, 0x1e, + 0x00, 0xa7, 0xa0, 0x29, 0xe0, 0x0b, 0xfc, 0x02, + 0xde, 0x00, 0xac, 0x88, 0x29, 0xe0, 0x0a, 0x78, + 0x02, 0x1e, 0x00, 0x97, 0x80, 0x2d, 0x60, 0x28, + 0x78, 0x82, 0x1a, 0x20, 0x87, 0x90, 0x2f, 0xe0, + 0x08, 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x68, 0x04, 0x8d, 0x80, 0xb3, 0x00, + 0x2e, 0xc0, 0x0b, 0x86, 0x12, 0xc6, 0x00, 0xb0, + 0x80, 0x20, 0xc0, 0x0b, 0x90, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x38, 0x02, 0x0b, + 0x80, 0xb3, 0x00, 0x2c, 0xc0, 0x0a, 0x28, 0x02, + 0x8c, 0x04, 0x80, 0x80, 0x68, 0xe0, 0x0b, 0xb0, + 0x02, 0x0c, 0x05, 0x93, 0x00, 0x2c, 0xc0, 0x08, + 0x38, 0x02, 0x8d, 0x00, 0x83, 0x00, 0x2c, 0xc6, + 0x08, 0x30, 0x02, 0xd3, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x15, 0xfa, 0x00, 0xfa, 0x00, + 0x3e, 0x80, 0x0f, 0xe4, 0x03, 0xfb, 0x20, 0xfe, + 0xc8, 0x36, 0x80, 0x0f, 0xe4, 0x03, 0xe8, 0x04, + 0xfa, 0x00, 0x3a, 0x80, 0x0b, 0x64, 0x03, 0x39, + 0x00, 0xfa, 0x00, 0x7e, 0x81, 0x0b, 0x68, 0x43, + 0xe8, 0x01, 0xfe, 0xc0, 0x3e, 0xa9, 0x0f, 0xa0, + 0x0b, 0x68, 0x00, 0xda, 0x20, 0x3e, 0x80, 0x0c, + 0xe5, 0x03, 0x38, 0x02, 0xca, 0x00, 0x3f, 0xa0, + 0x0c, 0xa0, 0xed, 0x09, 0x00, 0x4e, 0x01, 0x03, + 0xfb, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x01, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x81, 0x03, 0xe2, 0x00, 0xf8, 0x08, 0x3e, 0x00, + 0x0f, 0x88, 0x03, 0xc1, 0x00, 0xf8, 0x40, 0x1e, + 0x10, 0x0f, 0x89, 0x43, 0xe0, 0x40, 0xf8, 0x00, + 0x3e, 0x10, 0x0f, 0x80, 0x83, 0x60, 0x01, 0xe8, + 0x20, 0x0e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0x38, 0xc0, 0x36, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x10, 0xa4, 0x00, 0xf9, 0x40, 0x32, 0x40, 0x8c, + 0x90, 0x03, 0x24, 0x00, 0xc9, 0x00, 0x3e, 0x60, + 0x8f, 0x90, 0x03, 0x66, 0x04, 0x89, 0x80, 0x3e, + 0x50, 0x0e, 0x98, 0x03, 0xa4, 0x00, 0xc9, 0x80, + 0x3e, 0x60, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xf9, + 0x84, 0x3a, 0x71, 0x0c, 0x90, 0x0b, 0x26, 0x88, + 0xc9, 0x82, 0x3e, 0x60, 0x0f, 0x98, 0x03, 0x64, + 0x20, 0xf9, 0x00, 0x3c, 0x40, 0x0c, 0x90, 0x03, + 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x04, 0x64, 0x40, 0xb1, 0x80, 0x2a, 0x40, 0x08, + 0x90, 0x02, 0x24, 0x00, 0x89, 0x00, 0x0e, 0x60, + 0x09, 0x90, 0x62, 0x27, 0xc4, 0x89, 0xa0, 0x2e, + 0x62, 0x0b, 0x98, 0x02, 0x24, 0x00, 0x89, 0xc0, + 0x2e, 0x64, 0x0b, 0x90, 0x02, 0xa4, 0x00, 0x81, + 0x90, 0x22, 0x70, 0x08, 0x9c, 0x12, 0x27, 0x00, + 0x89, 0xe0, 0x0e, 0x74, 0x0b, 0x9c, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x28, 0x90, 0x02, + 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x05, 0x24, 0x00, 0xb9, 0x00, 0x22, 0x40, 0x08, + 0x90, 0x02, 0x04, 0x00, 0x99, 0x00, 0x06, 0x44, + 0x09, 0x90, 0x02, 0x24, 0x00, 0xa9, 0x20, 0x2e, + 0x40, 0x0b, 0x92, 0x02, 0x84, 0xed, 0x09, 0x00, + 0x4f, 0x01, 0x00, 0xa9, 0x20, 0x2a, 0x42, 0x0b, + 0x90, 0x02, 0x84, 0x00, 0xa9, 0x08, 0xa0, 0x40, + 0x08, 0xd2, 0x02, 0x94, 0x00, 0x8d, 0x10, 0x07, + 0x40, 0x0b, 0x92, 0x02, 0x6c, 0x00, 0xb9, 0x00, + 0x2e, 0x44, 0x08, 0x90, 0x02, 0xc6, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x14, 0x04, 0x00, + 0xb1, 0x80, 0x28, 0x50, 0x08, 0x14, 0x02, 0x05, + 0x02, 0x91, 0x40, 0x2c, 0x40, 0x09, 0x14, 0x4a, + 0x04, 0x02, 0xa1, 0x00, 0x2c, 0x40, 0x0b, 0x90, + 0x02, 0x05, 0x10, 0xa1, 0x02, 0x2c, 0x40, 0x8b, + 0x94, 0x00, 0x85, 0x11, 0x89, 0x40, 0x21, 0x70, + 0x08, 0x5c, 0x22, 0x97, 0x02, 0x85, 0x04, 0x2d, + 0x70, 0x0b, 0x30, 0x02, 0xc5, 0x00, 0xb1, 0x40, + 0x2c, 0x50, 0x08, 0x10, 0x02, 0xc2, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0d, 0x60, 0x10, + 0xf8, 0x00, 0x32, 0x00, 0x0c, 0x80, 0x0b, 0x20, + 0x00, 0xd8, 0x00, 0x3e, 0x80, 0x0d, 0x80, 0x03, + 0x20, 0x00, 0xe8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xa0, 0x02, 0xea, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xa0, 0x00, 0xe8, 0x00, 0x32, 0x00, + 0x2c, 0x00, 0x03, 0xa0, 0x00, 0xc8, 0x02, 0x3f, + 0x00, 0x8f, 0x80, 0x03, 0x60, 0x08, 0xf8, 0x00, + 0x3e, 0x00, 0x0c, 0x80, 0x03, 0xee, 0x03, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x98, 0x95, 0xf5, 0x00, + 0xf9, 0x41, 0x3e, 0x50, 0x2f, 0xd0, 0x03, 0xf4, + 0x00, 0xe5, 0x04, 0x36, 0x51, 0x01, 0xd0, 0x13, + 0xe5, 0x04, 0x91, 0x40, 0x3e, 0x50, 0x0f, 0x50, + 0x03, 0xf4, 0x10, 0x59, 0x40, 0x3e, 0x50, 0x0b, + 0x70, 0x03, 0xe4, 0x00, 0xed, 0x00, 0x36, 0x40, + 0x0f, 0x90, 0x13, 0x64, 0x00, 0xb9, 0x00, 0x3e, + 0x40, 0x0f, 0x50, 0x03, 0xf5, 0x04, 0xf9, 0x40, + 0x3f, 0x50, 0x0f, 0x90, 0x03, 0xe6, 0x06, 0x70, + 0xed, 0x09, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x05, 0xf4, 0x00, 0xed, 0x08, 0x36, + 0x4a, 0x0c, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x40, + 0x33, 0x48, 0x0f, 0xb0, 0x03, 0xf4, 0x80, 0xfd, + 0x00, 0x3d, 0x42, 0x07, 0xd0, 0x03, 0xe4, 0x00, + 0xed, 0x00, 0x33, 0x48, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf5, 0x40, 0xbb, 0x44, 0x0d, 0xd0, 0x03, + 0x34, 0x00, 0xcd, 0x00, 0x3b, 0x50, 0x0c, 0xd0, + 0x03, 0xe5, 0x00, 0xc9, 0x40, 0x3f, 0x51, 0x0f, + 0x90, 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x08, 0xe1, 0x44, 0x88, 0x42, 0x2e, + 0x18, 0x08, 0x00, 0x02, 0xe0, 0x00, 0xb8, 0x20, + 0x22, 0x10, 0x0b, 0x82, 0xc2, 0xe1, 0x00, 0xb8, + 0x00, 0x2e, 0x10, 0x0b, 0xa0, 0x00, 0xe0, 0x00, + 0xd8, 0x40, 0x2e, 0x00, 0x09, 0x82, 0x82, 0xe0, + 0x00, 0xb8, 0x20, 0xbe, 0x00, 0x08, 0x82, 0x82, + 0x20, 0x80, 0x88, 0x00, 0x2c, 0x00, 0x08, 0x80, + 0x42, 0xe1, 0x00, 0x88, 0x40, 0x2e, 0x10, 0x0b, + 0x80, 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x86, 0x00, 0xa1, 0x00, 0x24, + 0x42, 0x88, 0x12, 0x82, 0xc4, 0xa0, 0xb9, 0x04, + 0x20, 0x44, 0x09, 0x10, 0x02, 0xc4, 0x40, 0xb1, + 0x40, 0x2c, 0x40, 0x0b, 0x10, 0x20, 0xe4, 0x30, + 0x81, 0x40, 0x24, 0x51, 0x8b, 0x10, 0x02, 0x84, + 0xa0, 0xa1, 0x20, 0x28, 0x41, 0x0a, 0x12, 0x02, + 0xc4, 0xa0, 0x81, 0x00, 0x28, 0x40, 0x08, 0x10, + 0x02, 0xc5, 0x84, 0x81, 0x60, 0x2c, 0x58, 0x0b, + 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x05, 0xa4, 0x42, 0x89, 0x00, 0x2c, + 0x40, 0x20, 0x92, 0x02, 0xe4, 0x80, 0x39, 0x81, + 0xaa, 0x40, 0x0b, 0x92, 0x82, 0xe4, 0x00, 0xb9, + 0x00, 0x4e, 0xc0, 0x0b, 0xb1, 0x42, 0xe4, 0x80, + 0x99, 0x00, 0x2e, 0xed, 0x09, 0x00, 0x51, 0x01, + 0x40, 0x09, 0x90, 0x10, 0xe4, 0x08, 0xb9, 0x40, + 0x2e, 0x40, 0x08, 0x90, 0x42, 0xe4, 0x80, 0xa9, + 0x00, 0x2e, 0x40, 0x08, 0x90, 0x00, 0xe4, 0x00, + 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, + 0xe7, 0x02, 0xe9, 0x00, 0x36, 0x40, 0x04, 0x92, + 0x23, 0xe4, 0x20, 0xf9, 0x48, 0x32, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x14, 0xf9, 0x00, 0x3e, 0x40, + 0x4f, 0x9c, 0x03, 0xe5, 0x21, 0xa1, 0x00, 0x32, + 0x40, 0x0f, 0x9d, 0x03, 0xe4, 0x10, 0xf9, 0x50, + 0x3a, 0x40, 0x2d, 0x90, 0x0b, 0xe4, 0x02, 0xc9, + 0x00, 0x3a, 0x40, 0x2c, 0x96, 0x03, 0xe4, 0x02, + 0xc9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe8, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, + 0xa6, 0x04, 0xf9, 0x00, 0x3e, 0x40, 0x0b, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x04, 0x36, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0x79, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x07, 0xe4, 0x00, 0x79, 0x00, 0x3a, + 0x40, 0x0f, 0x98, 0x23, 0xe4, 0x00, 0xf9, 0x80, + 0x3e, 0x42, 0x0f, 0x90, 0x03, 0x24, 0x20, 0xd9, + 0x00, 0x3e, 0x43, 0x0f, 0x99, 0x03, 0xc4, 0x01, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xca, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0x82, 0x10, 0xd8, 0x84, 0x32, 0x01, 0x8d, 0x84, + 0x13, 0x21, 0x10, 0xf8, 0x44, 0x7e, 0x20, 0x0d, + 0x84, 0x03, 0xe0, 0x20, 0x78, 0x80, 0x3e, 0x21, + 0x0f, 0x8c, 0x07, 0xa1, 0x00, 0xd8, 0x80, 0x32, + 0x08, 0x8e, 0x84, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x32, 0x00, 0x0d, 0x89, 0x23, 0xe0, 0x00, 0xe8, + 0x90, 0x36, 0x04, 0x0c, 0x82, 0x03, 0xa0, 0x00, + 0xc8, 0x00, 0x36, 0x02, 0x1e, 0x80, 0x03, 0xca, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x52, 0x01, 0x28, 0x01, 0xb9, 0x02, 0x8e, + 0xc8, 0x22, 0x80, 0x0e, 0xa0, 0x02, 0x28, 0x04, + 0xb2, 0x00, 0x2f, 0x98, 0x20, 0xa0, 0x02, 0xfb, + 0x00, 0x9e, 0xc8, 0x2f, 0xb0, 0x8a, 0xe4, 0x03, + 0x48, 0x00, 0x8e, 0x40, 0x23, 0xb0, 0x08, 0xa0, + 0x02, 0xe8, 0x00, 0xbe, 0xc0, 0x37, 0xa0, 0x08, + 0xe8, 0x02, 0xfa, 0x90, 0x8e, 0xc0, 0x2f, 0x80, + 0x0e, 0xea, 0x02, 0x28, 0x00, 0x8a, 0x00, 0x0f, + 0x90, 0x0e, 0xa0, 0x02, 0xca, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x04, 0x4e, 0x00, 0x91, + 0x02, 0x84, 0xc0, 0x09, 0x30, 0x02, 0x8c, 0x0c, + 0xb3, 0x00, 0x0c, 0x40, 0x08, 0x30, 0x02, 0xc3, + 0x00, 0xb1, 0x00, 0x2c, 0x60, 0x08, 0x30, 0x02, + 0x8c, 0x02, 0x82, 0x84, 0x60, 0xa0, 0x0a, 0x30, + 0x06, 0xcc, 0x00, 0xbb, 0x60, 0xa6, 0xc0, 0x09, + 0xb0, 0x02, 0xec, 0x00, 0xa3, 0x00, 0x66, 0xc0, + 0x29, 0x3c, 0x06, 0x8c, 0x00, 0x83, 0x00, 0x2c, + 0xc0, 0x0a, 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x45, 0x04, 0x87, + 0x81, 0x25, 0xc0, 0x0a, 0x7a, 0x02, 0x9c, 0xc0, + 0xb7, 0x24, 0x2d, 0xe0, 0x08, 0x70, 0x42, 0xdc, + 0x21, 0x97, 0x00, 0x25, 0xe2, 0x0b, 0xfc, 0x02, + 0x1c, 0x80, 0x80, 0x40, 0x21, 0xf0, 0x18, 0x70, + 0x22, 0xdc, 0x80, 0x97, 0x08, 0x25, 0xd0, 0x08, + 0x70, 0x02, 0xdc, 0x00, 0xa6, 0x00, 0x2d, 0xc0, + 0x0a, 0x78, 0x02, 0x9c, 0x00, 0x87, 0x20, 0x2d, + 0x80, 0x0a, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x98, 0x5e, 0x04, 0xd1, + 0x80, 0x75, 0xf0, 0x0d, 0x78, 0x0b, 0x9e, 0xa0, + 0xf7, 0x80, 0x0c, 0xe0, 0x0d, 0x7c, 0x83, 0xde, + 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x8c, 0x78, 0x02, + 0xbf, 0x50, 0xd4, 0x80, 0xb1, 0xe0, 0x0e, 0x7c, + 0x83, 0xed, 0x09, 0x00, 0x53, 0x01, 0xdf, 0xa0, + 0xb7, 0x80, 0x37, 0xe0, 0x0d, 0x78, 0x03, 0xfe, + 0x00, 0xa7, 0x80, 0x35, 0xe0, 0x0d, 0x78, 0x01, + 0xbf, 0x82, 0xc7, 0xb0, 0x35, 0xe0, 0x0e, 0x78, + 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x1d, 0xac, 0x00, 0xf9, 0x00, 0x3a, 0xd2, + 0x0f, 0xb5, 0x03, 0x6d, 0x80, 0xfb, 0x20, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xe8, 0x00, 0xf9, 0x00, + 0x3e, 0xc0, 0x0e, 0x30, 0x01, 0x6d, 0x00, 0xfa, + 0x00, 0x3c, 0xc0, 0x0b, 0xb2, 0x23, 0xec, 0x00, + 0xfa, 0x00, 0xbe, 0xc0, 0x0f, 0xb0, 0x03, 0xe4, + 0x00, 0xda, 0x00, 0x3e, 0xc0, 0x0d, 0x30, 0x03, + 0x6c, 0x00, 0xfb, 0x60, 0x3e, 0x00, 0x0f, 0xb0, + 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xba, 0x00, 0xcc, 0x80, 0x3f, 0xe0, + 0x2c, 0xfc, 0x03, 0xfe, 0x00, 0xff, 0xc8, 0x3f, + 0xe1, 0x4f, 0xf8, 0x43, 0xfe, 0x04, 0xcf, 0x80, + 0x3f, 0xc8, 0x0d, 0xf8, 0x13, 0xfe, 0x48, 0xfc, + 0x80, 0x3f, 0xe0, 0x0c, 0xf8, 0x00, 0xfe, 0x40, + 0xff, 0x80, 0x3f, 0xe1, 0x0f, 0xf8, 0x03, 0xbe, + 0x00, 0xfe, 0x80, 0x37, 0xe0, 0x0f, 0xf8, 0x03, + 0xfe, 0x10, 0xcf, 0x9c, 0x33, 0xe0, 0x0f, 0xf8, + 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x18, 0x94, 0x40, 0x84, 0x00, 0x2d, 0xc0, + 0x08, 0x70, 0x02, 0xdc, 0x40, 0xb7, 0x10, 0x2d, + 0x40, 0x0b, 0x70, 0x02, 0xd4, 0x40, 0x87, 0x00, + 0x2d, 0xc4, 0x0d, 0x70, 0x02, 0xdc, 0xc0, 0xb4, + 0x20, 0x2d, 0x90, 0x08, 0x70, 0x02, 0xdc, 0x00, + 0xe5, 0x00, 0x2d, 0xc0, 0x0b, 0x60, 0x32, 0x1c, + 0x00, 0x86, 0x00, 0x21, 0xc0, 0x0b, 0x50, 0x02, + 0xdc, 0x00, 0xaf, 0x00, 0x21, 0x80, 0x0b, 0x70, + 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x91, 0x00, 0xed, 0x09, 0x00, 0x54, + 0x01, 0x84, 0x00, 0x2d, 0xc0, 0x08, 0x70, 0x82, + 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x71, + 0x02, 0xdc, 0x00, 0x87, 0x00, 0x2d, 0x40, 0x08, + 0x71, 0x02, 0x9c, 0x04, 0x34, 0x02, 0x28, 0xc0, + 0x08, 0x70, 0x02, 0x9c, 0x00, 0x97, 0x40, 0x2d, + 0x00, 0x0b, 0x50, 0x02, 0x98, 0x40, 0xac, 0x00, + 0x21, 0x00, 0x09, 0x70, 0x02, 0xdc, 0x00, 0x97, + 0x04, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xc0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x8e, + 0x08, 0x81, 0x00, 0x2c, 0xc0, 0x08, 0x38, 0x02, + 0xce, 0x00, 0xb3, 0x40, 0x2c, 0xc0, 0x0b, 0x3e, + 0x02, 0xcc, 0x10, 0x83, 0x00, 0x6c, 0xc0, 0x09, + 0x34, 0x02, 0xcf, 0x00, 0xb0, 0x00, 0x2c, 0xc0, + 0x28, 0xbc, 0x02, 0xcc, 0x00, 0xa1, 0x00, 0x2c, + 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x64, 0x20, 0x8b, 0x18, 0x02, 0xed, 0x10, 0xa3, + 0x00, 0x20, 0x00, 0x0b, 0x30, 0x02, 0xc8, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xe8, + 0x00, 0xcb, 0x00, 0x3f, 0xc0, 0x2c, 0xf8, 0x03, + 0xdf, 0x80, 0xff, 0x04, 0x3e, 0xc0, 0x4f, 0xfc, + 0x13, 0xcc, 0x02, 0xcb, 0x00, 0x3e, 0xc0, 0x2c, + 0xb1, 0x33, 0xff, 0x00, 0xb8, 0x01, 0x3e, 0xc0, + 0x48, 0xf8, 0x43, 0xfc, 0x00, 0xd3, 0x00, 0x3e, + 0xc0, 0x0b, 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x00, + 0xb2, 0xe2, 0x0f, 0xb0, 0x03, 0xfc, 0x60, 0xcf, + 0x00, 0x32, 0x40, 0x0b, 0xb0, 0x03, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xac, + 0x44, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x80, 0xfb, 0x88, 0x3e, 0xd0, 0x0f, 0xb1, + 0x03, 0xed, 0x00, 0xf3, 0x40, 0x3c, 0x40, 0x0e, + 0xbc, 0x03, 0xec, 0xc0, 0x78, 0x44, 0x3e, 0xd0, + 0x0f, 0xb1, 0x93, 0xec, 0x00, 0xfb, 0x80, 0xed, + 0x09, 0x00, 0x55, 0x01, 0x3e, 0x10, 0x0f, 0x94, + 0x03, 0xe9, 0x00, 0xf8, 0x00, 0x3a, 0x00, 0x0f, + 0xa5, 0x83, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x10, 0xa0, 0x00, 0xf5, 0x80, + 0x32, 0xc0, 0x0f, 0xf0, 0x83, 0xfc, 0x00, 0xdf, + 0x00, 0x33, 0x40, 0x0c, 0xf0, 0x03, 0x24, 0x40, + 0xcf, 0x00, 0x32, 0xc0, 0x0d, 0xf1, 0x03, 0xfc, + 0x00, 0xfd, 0xa0, 0x3f, 0x84, 0x8c, 0xf0, 0x03, + 0xbc, 0x00, 0xfd, 0x00, 0x33, 0xe0, 0x0e, 0xe8, + 0x03, 0xfc, 0x04, 0xde, 0x00, 0x3f, 0xc8, 0x08, + 0xd0, 0x02, 0xec, 0x00, 0xcf, 0x00, 0x1f, 0x40, + 0x0c, 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xa1, 0x04, 0x64, 0x00, 0x39, 0x84, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0x8b, + 0x00, 0x20, 0xc0, 0x0a, 0xb0, 0x42, 0x2c, 0x80, + 0x8b, 0x40, 0x22, 0xf4, 0x08, 0xbc, 0x02, 0xec, + 0x00, 0xb8, 0xa0, 0x2c, 0xd0, 0x0d, 0xb0, 0x12, + 0x2c, 0x00, 0xe9, 0x84, 0xa2, 0x18, 0x0b, 0x8d, + 0x83, 0xa1, 0x20, 0x88, 0x80, 0x2e, 0x00, 0x08, + 0x90, 0x42, 0xec, 0x00, 0x8b, 0x02, 0x2e, 0x74, + 0x08, 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x05, 0x28, 0x40, 0x38, 0x18, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0x93, + 0x00, 0x22, 0xd5, 0x08, 0x30, 0x02, 0x28, 0x00, + 0x89, 0xc0, 0x22, 0xc0, 0x08, 0xb0, 0x02, 0xec, + 0x00, 0xba, 0x00, 0x2e, 0xc0, 0x08, 0xb0, 0x02, + 0x2c, 0x00, 0xbb, 0x80, 0x22, 0xc9, 0x0b, 0xb0, + 0x02, 0xc4, 0x80, 0x9a, 0x10, 0x2c, 0xc2, 0x8b, + 0xb1, 0x86, 0xec, 0x08, 0x8b, 0x02, 0x2c, 0x10, + 0x08, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x14, 0x0a, 0x08, 0xb1, 0x00, + 0xa0, 0xc0, 0xed, 0x09, 0x00, 0x56, 0x01, 0x0b, + 0x30, 0x02, 0xec, 0x00, 0x83, 0x04, 0xa0, 0xc0, + 0x0a, 0x30, 0x42, 0x0c, 0x00, 0x83, 0x00, 0x20, + 0xc0, 0x08, 0x20, 0x06, 0xcc, 0x00, 0xb0, 0x00, + 0x6c, 0xc0, 0x09, 0x30, 0x1a, 0x0c, 0x00, 0x89, + 0x80, 0x20, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x00, + 0x80, 0x80, 0x2c, 0x00, 0x0b, 0x10, 0x02, 0xcc, + 0x00, 0x83, 0x00, 0x2c, 0x80, 0x08, 0x30, 0x02, + 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x33, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xdf, 0x00, 0x32, 0xc0, + 0x0c, 0xf0, 0x03, 0x2c, 0x02, 0x8b, 0x00, 0xb2, + 0xc0, 0x28, 0xb0, 0x03, 0xfc, 0x00, 0xf8, 0x00, + 0x2e, 0xc0, 0x0c, 0xf0, 0x03, 0x3c, 0x04, 0xf9, + 0x00, 0xb2, 0x00, 0x0f, 0x00, 0x03, 0xc0, 0x00, + 0xd8, 0x00, 0x3e, 0x00, 0x2f, 0x90, 0x03, 0xec, + 0x02, 0xcf, 0x00, 0x3e, 0x00, 0x0c, 0xb0, 0x03, + 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, + 0x15, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0xc0, 0x4f, + 0xf0, 0x43, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x00, + 0x0f, 0xf0, 0x0b, 0xf0, 0x00, 0xfc, 0x00, 0x3f, + 0x00, 0x1e, 0xc0, 0x13, 0xfc, 0x00, 0xfe, 0x01, + 0x3f, 0x00, 0x8f, 0xf0, 0x03, 0xfc, 0x00, 0x6d, + 0x00, 0xbf, 0x01, 0x0f, 0xc0, 0x13, 0xb0, 0x00, + 0xf4, 0x00, 0x7f, 0x00, 0x0c, 0xd0, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0x00, 0x0f, 0xf0, 0x03, + 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x05, 0xfc, 0x00, 0xcc, 0x00, 0x3f, 0xc0, 0x00, + 0xe0, 0x03, 0x30, 0x80, 0xcf, 0x00, 0x39, 0x01, + 0x0f, 0xc0, 0x43, 0x30, 0x00, 0xcd, 0x00, 0x33, + 0x80, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xcd, 0x10, + 0x3b, 0xc0, 0x0c, 0x50, 0x03, 0xf1, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0xed, 0x09, 0x00, + 0x57, 0x01, 0x03, 0xdc, 0x00, 0xdc, 0x20, 0x33, + 0x02, 0x0c, 0xc1, 0x03, 0xb0, 0x40, 0xdc, 0x35, + 0x37, 0x18, 0x0c, 0x42, 0x83, 0x30, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xfc, 0x01, + 0x88, 0x00, 0x2e, 0x81, 0x08, 0xb0, 0x02, 0x2d, + 0x08, 0x8b, 0x00, 0x22, 0x40, 0x09, 0x92, 0x00, + 0x20, 0x00, 0xc9, 0x00, 0x22, 0xc0, 0x0b, 0xb0, + 0x42, 0xec, 0x00, 0x81, 0x00, 0x2a, 0x81, 0x0a, + 0x90, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xb8, 0x40, 0x22, + 0x13, 0x08, 0x87, 0x12, 0x28, 0x40, 0xb8, 0x30, + 0x22, 0x0d, 0x28, 0x84, 0x02, 0x20, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, 0xa0, + 0x80, 0x00, 0x2c, 0x80, 0x48, 0x30, 0x0a, 0x04, + 0x40, 0x89, 0x00, 0x2c, 0x20, 0x4b, 0x80, 0xde, + 0x00, 0x00, 0x88, 0x00, 0x20, 0xc0, 0x0b, 0x20, + 0x02, 0xec, 0x04, 0x9b, 0x20, 0x2c, 0xc0, 0x19, + 0x10, 0x02, 0xcc, 0x80, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb0, 0xb8, 0x20, + 0x08, 0x1a, 0x00, 0x02, 0x00, 0x80, 0x90, 0x20, + 0x24, 0x00, 0x09, 0x10, 0x02, 0x22, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, 0x08, + 0x88, 0x80, 0x2e, 0x80, 0x08, 0xb1, 0x42, 0x2c, + 0x88, 0x8b, 0x01, 0x2e, 0x48, 0x09, 0x90, 0x46, + 0x20, 0x80, 0x0b, 0x44, 0x22, 0xca, 0x0b, 0xb0, + 0x52, 0xec, 0x00, 0x9b, 0x52, 0x2e, 0x82, 0x0b, + 0x90, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x08, 0xb3, 0x10, 0x22, + 0x03, 0x88, 0xbc, 0x02, 0x28, 0x20, 0xba, 0x00, + 0x22, 0xc8, 0x08, 0x90, 0x02, 0x30, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xec, 0x02, + 0x89, 0xc0, 0x3c, 0xe2, 0x0c, 0x2a, 0x13, 0x25, + 0xed, 0x09, 0x00, 0x58, 0x01, 0x02, 0xcb, 0xe1, + 0x3e, 0x00, 0x0f, 0x10, 0x03, 0x05, 0x38, 0xca, + 0x40, 0xb2, 0xd0, 0x0f, 0xa0, 0x43, 0xed, 0x02, + 0xd3, 0x40, 0x3c, 0xc1, 0x0d, 0x98, 0x03, 0xec, + 0x80, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xe4, 0x00, 0xf8, 0x84, 0x32, 0x74, 0x28, 0x84, + 0x11, 0x25, 0x08, 0x98, 0x20, 0x36, 0x28, 0x0c, + 0xa0, 0x03, 0x10, 0x44, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xe1, 0x01, 0x9c, 0x00, 0xf9, 0x00, 0x3f, + 0xe4, 0x2f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0xcc, + 0x33, 0xe0, 0x0b, 0xfa, 0x03, 0xf2, 0x10, 0xee, + 0x00, 0x3f, 0xe0, 0x0f, 0xf1, 0x03, 0xfe, 0x80, + 0xef, 0x00, 0x3b, 0xc0, 0x0e, 0xdc, 0x43, 0xfe, + 0x40, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x88, 0xbf, 0xc0, 0x0f, 0xd0, + 0x03, 0x74, 0x00, 0xfd, 0xa0, 0x3f, 0x80, 0x0f, + 0xf1, 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x10, 0xac, 0x80, 0xc9, 0x40, 0xb2, + 0xc2, 0x0f, 0x94, 0x03, 0xed, 0x00, 0xf9, 0x40, + 0x36, 0xc2, 0x8c, 0x90, 0x03, 0x2c, 0x04, 0xfa, + 0x48, 0xb2, 0xc4, 0x8f, 0xb8, 0x03, 0xec, 0x20, + 0xfb, 0x00, 0x32, 0x41, 0x0f, 0x90, 0x03, 0x2c, + 0x40, 0xdb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xf8, 0x00, 0x30, 0x48, 0x0e, 0xa0, + 0x03, 0xed, 0x00, 0xe3, 0x00, 0x2e, 0x42, 0x0c, + 0xa0, 0x83, 0x10, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x05, 0x3c, 0x00, 0x88, 0x05, 0x22, + 0xe2, 0x0b, 0x95, 0x02, 0xcc, 0x10, 0xb3, 0xc4, + 0x82, 0xd0, 0x4a, 0xb4, 0x02, 0x2d, 0x80, 0xb2, + 0x44, 0x22, 0xf0, 0x09, 0xb8, 0x10, 0xcf, 0x00, + 0xbb, 0x00, 0x22, 0xfd, 0x0b, 0x99, 0x02, 0x2c, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0x8b, 0xed, 0x09, 0x00, 0x59, 0x01, + 0x00, 0x22, 0xf0, 0x4b, 0xb8, 0x12, 0xec, 0x00, + 0xab, 0x90, 0x26, 0xc2, 0x08, 0x34, 0x02, 0x32, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, + 0x4e, 0x00, 0x82, 0x00, 0x20, 0xb0, 0x0b, 0x04, + 0x12, 0xc6, 0x08, 0xb0, 0x00, 0x24, 0x20, 0x08, + 0x20, 0x02, 0xc3, 0x21, 0xb1, 0xd0, 0x20, 0x72, + 0x0b, 0x00, 0x02, 0xcd, 0x00, 0xb3, 0x10, 0xa0, + 0xd0, 0x09, 0x18, 0x02, 0x0c, 0x04, 0x93, 0x02, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb0, + 0x40, 0x20, 0x80, 0x0b, 0x80, 0x14, 0xc0, 0x10, + 0x80, 0x80, 0x26, 0x00, 0x08, 0x00, 0x02, 0x30, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x11, + 0x0e, 0x20, 0x86, 0x80, 0x21, 0xa0, 0x0b, 0x48, + 0x02, 0xde, 0x40, 0xb7, 0xb0, 0xa1, 0xe0, 0x0a, + 0x7c, 0x02, 0x52, 0x08, 0xbd, 0x80, 0x21, 0xe4, + 0x09, 0x7c, 0x02, 0xda, 0x20, 0xb7, 0xf0, 0x21, + 0xe0, 0x4b, 0xd8, 0x22, 0x1e, 0x40, 0xb7, 0x81, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xf8, 0x40, 0x80, + 0x80, 0x21, 0x24, 0x0b, 0x68, 0x82, 0xfa, 0x20, + 0xa7, 0x90, 0x64, 0x60, 0x88, 0x69, 0x02, 0x88, + 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x0c, 0x40, 0xc2, 0x00, 0x30, 0x80, 0x0f, 0x10, + 0x03, 0xcc, 0x20, 0xf0, 0x38, 0x34, 0x82, 0x4c, + 0x80, 0x0b, 0xc0, 0x00, 0xf0, 0x00, 0x30, 0xc4, + 0x0f, 0x20, 0x03, 0xcd, 0x00, 0xf3, 0x20, 0x30, + 0xc0, 0x0f, 0x10, 0x83, 0x0c, 0x00, 0xd3, 0x00, + 0x3c, 0xc0, 0x0f, 0x30, 0x17, 0xcd, 0x40, 0xf3, + 0x01, 0x30, 0xc3, 0x0f, 0x10, 0x03, 0xc0, 0x00, + 0xe1, 0x08, 0x3c, 0x81, 0x4c, 0x10, 0x03, 0x12, + 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, + 0xbd, 0x04, 0xfe, 0x00, 0x3f, 0x04, 0x4f, 0xd0, + 0x01, 0xfc, 0x00, 0xf7, 0x30, 0x3f, 0xed, 0x09, + 0x00, 0x5a, 0x01, 0xc0, 0x0f, 0xd0, 0x03, 0xb0, + 0x00, 0xf7, 0x00, 0x3f, 0xc4, 0x01, 0xf1, 0x01, + 0xfc, 0x40, 0xfe, 0x20, 0x3f, 0xc0, 0x4f, 0xf0, + 0x0b, 0xfc, 0x10, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xf8, 0x80, 0xff, 0x00, 0x3f, 0x40, + 0x0f, 0xf0, 0x03, 0xd8, 0x40, 0xff, 0x00, 0x3f, + 0xc4, 0x0f, 0xf0, 0x43, 0x50, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x05, 0xed, 0x00, 0x7b, + 0x80, 0x10, 0xc0, 0x2c, 0x80, 0x02, 0x24, 0x00, + 0xc1, 0x80, 0x32, 0x40, 0x0f, 0xb0, 0x03, 0x00, + 0x00, 0xcb, 0x00, 0x3c, 0xc0, 0x08, 0xb0, 0x03, + 0xec, 0x00, 0xc3, 0x00, 0x30, 0xe0, 0x0c, 0x90, + 0x03, 0xcc, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xe4, 0x00, 0xfb, 0x00, 0x3e, 0xa0, + 0x0d, 0xb8, 0x0b, 0x20, 0x00, 0xda, 0x80, 0xba, + 0xc0, 0x0f, 0x88, 0x0b, 0x02, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x11, 0x9d, 0x00, 0xb7, + 0x01, 0x35, 0x40, 0xa8, 0x50, 0x02, 0x1c, 0x00, + 0x87, 0x01, 0x21, 0xc0, 0x0b, 0xf0, 0x23, 0x50, + 0x00, 0x87, 0x04, 0x2d, 0xc0, 0x08, 0x70, 0x02, + 0xd4, 0x04, 0x87, 0x00, 0x29, 0xc0, 0x0a, 0x70, + 0x02, 0xdc, 0x00, 0x87, 0x01, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2c, 0x81, + 0x08, 0x70, 0x02, 0x30, 0x00, 0x87, 0x00, 0x21, + 0xc0, 0x0b, 0x30, 0x02, 0x12, 0x26, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xc1, 0x00, 0x9e, 0x00, 0xb1, + 0x80, 0x61, 0xe0, 0x08, 0xd8, 0x0a, 0x3e, 0x0a, + 0xbd, 0x80, 0x21, 0xf0, 0x0b, 0x58, 0x82, 0x36, + 0x04, 0x06, 0x80, 0x2d, 0xf0, 0x09, 0x78, 0x12, + 0xfe, 0x00, 0x8f, 0x80, 0x63, 0x60, 0x08, 0x58, + 0x02, 0xfe, 0x22, 0x87, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x02, 0xde, 0x00, 0xb7, 0xc0, 0x2d, 0xe0, + 0x0a, 0xed, 0x09, 0x00, 0x5b, 0x01, 0x38, 0x02, + 0x5a, 0x00, 0x97, 0x80, 0x21, 0xe0, 0x0b, 0x48, + 0x02, 0x88, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x14, 0xcc, 0x00, 0xb3, 0x88, 0x24, 0x60, + 0x98, 0x10, 0x02, 0x0c, 0x00, 0xb3, 0x40, 0x20, + 0xe0, 0x0b, 0xb8, 0x02, 0x4e, 0x02, 0x83, 0x80, + 0x2c, 0xe0, 0x09, 0x30, 0x02, 0xcd, 0x00, 0x8b, + 0x90, 0x28, 0xe0, 0x0a, 0x31, 0x02, 0xee, 0x00, + 0xa3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xca, + 0x41, 0xb3, 0xe0, 0x2c, 0xd4, 0x2a, 0x31, 0x02, + 0x4a, 0x00, 0x83, 0x00, 0x60, 0xd8, 0x0b, 0x3d, + 0x02, 0x9a, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xe8, 0x15, 0xa8, 0x00, 0xfe, 0x00, 0x31, 0x92, + 0x08, 0xe6, 0x03, 0x38, 0x00, 0xfe, 0x10, 0x33, + 0x90, 0x0f, 0xe4, 0x03, 0x39, 0x10, 0xc6, 0xc8, + 0x3d, 0xb0, 0x2d, 0xe4, 0x03, 0xda, 0x62, 0xce, + 0xc0, 0x33, 0x90, 0x4c, 0xe8, 0x03, 0xf9, 0x00, + 0xca, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xf9, + 0x00, 0xfe, 0x40, 0x2f, 0xa0, 0x0e, 0xe9, 0x03, + 0x59, 0x00, 0xde, 0xd8, 0x33, 0xb2, 0x0f, 0xe1, + 0x03, 0xba, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0xe0, 0x14, 0xf8, 0x10, 0x3e, 0x20, + 0x2f, 0x88, 0x0b, 0xe2, 0x00, 0x08, 0x42, 0xbe, + 0x30, 0x0f, 0x8c, 0x03, 0xe3, 0x40, 0xf8, 0x80, + 0x3e, 0x20, 0x0e, 0x8d, 0x03, 0xe0, 0x00, 0xf8, + 0x80, 0x3e, 0x24, 0x0f, 0x84, 0x03, 0xe2, 0x00, + 0xd8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x23, 0xe2, + 0x00, 0xf8, 0x04, 0x3e, 0x08, 0x0c, 0x84, 0x03, + 0xa0, 0xc0, 0xf8, 0x00, 0x56, 0x00, 0x0f, 0x80, + 0x03, 0x52, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x80, 0x3e, 0x40, + 0x2e, 0x90, 0x03, 0x24, 0x02, 0xc9, 0x00, 0x3e, + 0x60, 0x0f, 0x91, 0x03, 0xed, 0x09, 0x00, 0x5c, + 0x01, 0x26, 0x42, 0xd9, 0x20, 0x32, 0x40, 0x0c, + 0x9a, 0x23, 0xe4, 0x80, 0xc9, 0x00, 0x3a, 0x40, + 0x0f, 0x92, 0x03, 0x24, 0x00, 0xe9, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf1, 0x80, + 0x32, 0x40, 0x0f, 0x9a, 0x03, 0xe4, 0x80, 0xc9, + 0x80, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xc2, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x65, + 0x00, 0xb9, 0x00, 0x6e, 0x50, 0x08, 0x10, 0x0a, + 0x86, 0x00, 0x89, 0x48, 0x2e, 0x52, 0x0b, 0x9e, + 0x23, 0x04, 0x98, 0x89, 0x03, 0x36, 0x76, 0x08, + 0x90, 0x82, 0xe5, 0x80, 0xd9, 0x08, 0x36, 0x40, + 0x0b, 0x14, 0x02, 0x24, 0x00, 0xa9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x10, + 0x22, 0x50, 0x4b, 0x98, 0x02, 0xe6, 0x10, 0xa9, + 0x88, 0x2e, 0x40, 0x0a, 0x94, 0x02, 0xe0, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, + 0x40, 0xbb, 0x20, 0x2e, 0x40, 0x0a, 0x90, 0x02, + 0x2c, 0x80, 0x89, 0x20, 0x2e, 0x48, 0x4b, 0x90, + 0x0a, 0xa4, 0x00, 0x89, 0x00, 0x62, 0x41, 0x98, + 0xb0, 0x02, 0xe4, 0x00, 0x89, 0x80, 0xae, 0x40, + 0xcb, 0x90, 0x02, 0x24, 0x00, 0x89, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xa4, 0x00, 0xa9, 0x00, + 0x22, 0x4a, 0x8b, 0x90, 0x06, 0xe4, 0x00, 0x89, + 0x10, 0x2c, 0x48, 0x0a, 0x95, 0x02, 0xce, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x05, + 0x00, 0xb1, 0x00, 0x2e, 0x40, 0x08, 0x90, 0x02, + 0xa6, 0x01, 0x81, 0x00, 0x2c, 0x40, 0x1b, 0x14, + 0x0a, 0x04, 0x00, 0x91, 0x00, 0x26, 0x41, 0x08, + 0x10, 0x06, 0xc4, 0x00, 0x91, 0x40, 0x24, 0x40, + 0x0b, 0x30, 0x02, 0x05, 0x00, 0xa1, 0x00, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0xc0, + 0x20, 0x50, 0x03, 0x14, 0x02, 0xe5, 0x00, 0xed, + 0x09, 0x00, 0x5d, 0x01, 0xa1, 0x40, 0x2c, 0x70, + 0x0a, 0x10, 0x02, 0xca, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb8, 0x0d, 0x68, 0x00, 0xf8, 0x02, + 0x2e, 0x80, 0x0e, 0x80, 0x42, 0x20, 0x10, 0xc8, + 0x00, 0x3e, 0x00, 0x4b, 0x80, 0x02, 0xa0, 0x04, + 0xca, 0x00, 0xb2, 0x00, 0x0c, 0x80, 0x03, 0xe0, + 0x00, 0xc8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0x20, 0x00, 0xe8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xa0, 0x00, 0xe8, 0x00, 0xb2, 0x01, 0x0f, + 0xa0, 0x03, 0xe0, 0x00, 0xc0, 0x00, 0x3e, 0x00, + 0x2c, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x98, 0x1d, 0xe5, 0x00, 0xfd, 0x42, + 0x3f, 0x40, 0x0f, 0x70, 0x03, 0xdd, 0x00, 0xfd, + 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0xb4, 0x00, + 0xed, 0x00, 0x3f, 0xc0, 0x2b, 0xd0, 0x01, 0xd4, + 0x04, 0xfd, 0x00, 0xbf, 0x40, 0x0f, 0xd0, 0x0b, + 0xf4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xfc, 0x00, 0xff, 0x40, 0x3f, 0x50, 0x0f, + 0xd4, 0x13, 0xf5, 0x00, 0xfd, 0x40, 0x3f, 0x51, + 0x0d, 0xd4, 0x03, 0xe6, 0x24, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x98, 0x05, 0xf4, 0xc0, 0xfd, 0x00, + 0x33, 0x40, 0x83, 0xd0, 0x03, 0x3c, 0x80, 0xe5, + 0x00, 0x3f, 0x40, 0x0c, 0xd0, 0x13, 0x34, 0x08, + 0xe5, 0x00, 0x33, 0x40, 0x07, 0xd0, 0x43, 0xf4, + 0x00, 0xfd, 0x00, 0x37, 0x40, 0x0f, 0xd0, 0x03, + 0xf4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xed, 0x10, 0x3f, 0x48, 0x0c, + 0xd2, 0x83, 0x34, 0xc0, 0xcd, 0x00, 0x33, 0x40, + 0x0c, 0xd0, 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x39, 0x10, 0xe0, 0xc0, 0xba, 0x40, + 0x22, 0x00, 0x0b, 0x80, 0x02, 0x20, 0x00, 0x88, + 0x00, 0x0e, 0x00, 0x08, 0x80, 0x82, 0x20, 0x00, + 0xd8, 0x00, 0xed, 0x09, 0x00, 0x5e, 0x01, 0x22, + 0x00, 0x0b, 0x80, 0x02, 0xe8, 0x00, 0xb2, 0x08, + 0x32, 0x00, 0x0b, 0x80, 0x03, 0xa0, 0xa0, 0xb8, + 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, + 0x80, 0x10, 0x2e, 0x0b, 0x08, 0x02, 0x02, 0x20, + 0xc0, 0x88, 0x48, 0x22, 0x82, 0x48, 0xc1, 0x02, + 0xce, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x05, 0xc4, 0x80, 0xb1, 0x10, 0x20, 0x60, 0x0b, + 0x10, 0x02, 0x04, 0x48, 0xa1, 0x00, 0x2e, 0x60, + 0xa8, 0x12, 0x02, 0xc4, 0x00, 0x81, 0x00, 0xac, + 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x20, + 0xa4, 0x40, 0x0b, 0x10, 0x12, 0xc4, 0x80, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xe4, 0x00, + 0xa1, 0x00, 0x2c, 0x4c, 0x18, 0x12, 0x8a, 0x4c, + 0x80, 0x83, 0x30, 0x28, 0x44, 0x08, 0x10, 0x22, + 0xd2, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x22, 0x60, 0x8b, + 0x91, 0x0a, 0x24, 0x10, 0x89, 0x00, 0x2e, 0x60, + 0x08, 0x90, 0x04, 0xac, 0x40, 0x99, 0x00, 0x26, + 0x40, 0x0b, 0x90, 0x02, 0x64, 0x40, 0xb1, 0x05, + 0xe2, 0xc4, 0x0b, 0x90, 0x06, 0xa4, 0x80, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x80, + 0x89, 0x00, 0x2e, 0x42, 0x38, 0x92, 0x82, 0x64, + 0x80, 0x89, 0x00, 0x2a, 0x40, 0x08, 0x90, 0x02, + 0xc6, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x15, 0xe4, 0x00, 0xf9, 0xd0, 0x32, 0x70, 0x0f, + 0x18, 0x03, 0x27, 0x08, 0xe9, 0x90, 0x3e, 0x50, + 0x4c, 0x90, 0x0b, 0xe6, 0x2c, 0xc1, 0x9c, 0x3e, + 0x60, 0x0f, 0x9e, 0x03, 0xe6, 0x00, 0xf9, 0x50, + 0x36, 0x61, 0x0f, 0x90, 0x03, 0xe4, 0x80, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe5, 0x00, + 0xe9, 0xc0, 0x3e, 0x50, 0x0c, 0x94, 0x63, 0x66, + 0x01, 0x89, 0x18, 0xba, 0x70, 0xed, 0x09, 0x00, + 0x5f, 0x01, 0x2c, 0x94, 0x83, 0xe8, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, + 0xf1, 0x00, 0xbe, 0x40, 0x0f, 0x98, 0x03, 0xe7, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x92, 0x03, + 0x24, 0x30, 0xd9, 0x80, 0x3a, 0x50, 0x0f, 0x94, + 0x03, 0xe4, 0x00, 0xf9, 0x80, 0xbe, 0x60, 0x8f, + 0x92, 0xd3, 0xe4, 0x00, 0xf9, 0x00, 0x36, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x20, 0x3c, + 0x40, 0x07, 0x98, 0x03, 0x84, 0x02, 0xf1, 0x00, + 0x34, 0x64, 0x0f, 0x90, 0x03, 0xd2, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa2, 0x00, + 0xc8, 0x50, 0xb2, 0x21, 0x0f, 0x88, 0x03, 0x00, + 0x00, 0xf8, 0x90, 0x32, 0x20, 0x0f, 0x88, 0x03, + 0x60, 0x00, 0xf8, 0xc0, 0xb2, 0x11, 0x0b, 0x88, + 0x13, 0xe0, 0x00, 0xf8, 0x40, 0xb6, 0x20, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xe8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe1, 0x00, 0xf8, 0x40, 0x72, + 0x12, 0x2c, 0x80, 0x83, 0x20, 0x00, 0xc8, 0x00, + 0x3a, 0x00, 0x0d, 0x8c, 0x03, 0x82, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x38, 0x02, + 0x8a, 0x00, 0xa3, 0x90, 0x4e, 0xe4, 0x0a, 0x39, + 0x00, 0xbe, 0x41, 0x21, 0x92, 0x0b, 0xe0, 0x83, + 0x99, 0x20, 0x1e, 0x60, 0x83, 0x84, 0x0b, 0xe4, + 0x12, 0xfa, 0x44, 0xbe, 0x00, 0x2b, 0xb1, 0x4b, + 0xe0, 0x02, 0xea, 0x00, 0x8e, 0x00, 0x2e, 0x80, + 0x0b, 0xa0, 0x03, 0x88, 0x00, 0xbe, 0x51, 0x23, + 0xa1, 0x08, 0xe4, 0x02, 0x28, 0x02, 0xee, 0x40, + 0x23, 0x81, 0x4b, 0xa4, 0x03, 0x0a, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x0e, 0x40, + 0x83, 0x00, 0x20, 0xc0, 0x0b, 0x11, 0x0a, 0x03, + 0xc0, 0xb3, 0x00, 0x20, 0xe0, 0x0b, 0xb0, 0x00, + 0x8f, 0x04, 0xb3, 0x80, 0x00, 0x50, 0x0b, 0x38, + 0xed, 0x09, 0x00, 0x60, 0x01, 0x02, 0xc5, 0x00, + 0xb3, 0x04, 0xa0, 0xc0, 0xcb, 0x15, 0x02, 0xcc, + 0x00, 0xa2, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x06, + 0x8c, 0x00, 0xb3, 0xc0, 0x60, 0xd0, 0x09, 0xb8, + 0x02, 0xcc, 0x00, 0x83, 0x48, 0x08, 0xc0, 0x0b, + 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x01, 0x1e, 0x00, 0x83, 0x00, 0x21, + 0xc0, 0x0a, 0x50, 0x0a, 0x10, 0x00, 0xbd, 0x80, + 0x21, 0xc0, 0x0b, 0x60, 0x02, 0x90, 0x00, 0x9e, + 0x00, 0x21, 0x82, 0x0b, 0x50, 0x82, 0xdc, 0x20, + 0xb7, 0x40, 0xa9, 0xc2, 0x0b, 0x70, 0x02, 0xdf, + 0x00, 0x96, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0x9c, 0x00, 0xb7, 0xc1, 0x20, 0xc2, 0x09, 0x74, + 0x02, 0x7c, 0x08, 0xb7, 0x00, 0x21, 0xc0, 0x83, + 0x28, 0x02, 0x20, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x08, 0x3e, 0x00, 0xc7, 0x80, 0x21, + 0xa0, 0x4f, 0x58, 0x0b, 0x1e, 0x00, 0xf7, 0x80, + 0x31, 0xe0, 0x0f, 0xf8, 0x03, 0x9a, 0x00, 0xf6, + 0x84, 0x31, 0xa0, 0x0f, 0x58, 0x03, 0xde, 0x00, + 0xf7, 0x80, 0x21, 0xe0, 0x0f, 0x78, 0x03, 0xfe, + 0x00, 0xe6, 0x84, 0x3d, 0xe0, 0x0b, 0x78, 0x03, + 0x9e, 0x00, 0xf6, 0x80, 0xa1, 0xe0, 0x0d, 0x78, + 0x0b, 0xde, 0x00, 0xcf, 0x81, 0x29, 0xa1, 0x05, + 0x48, 0x83, 0xe2, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x1d, 0xa4, 0x00, 0xfb, 0x00, 0xbe, + 0x80, 0x4e, 0x10, 0x03, 0xec, 0x00, 0xfa, 0x00, + 0xbe, 0xc0, 0x0b, 0xa0, 0x03, 0xa0, 0x00, 0xda, + 0x00, 0x3e, 0x80, 0x0f, 0x90, 0x03, 0xe8, 0x00, + 0xfb, 0x00, 0x32, 0xc0, 0x4f, 0xb0, 0x13, 0xec, + 0x04, 0xea, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xac, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x0e, 0x90, + 0x03, 0x84, 0x00, 0xe9, 0x05, 0x3e, 0x00, 0x0f, + 0x92, 0x03, 0xc2, 0xed, 0x09, 0x00, 0x61, 0x01, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, + 0xfe, 0x00, 0xff, 0x84, 0x35, 0xe0, 0x4c, 0x78, + 0x03, 0x32, 0x00, 0x4e, 0x80, 0x33, 0xe0, 0x4f, + 0xf0, 0x03, 0xbe, 0x00, 0xff, 0x80, 0x3f, 0xa0, + 0x0e, 0xc8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0xb5, + 0xa0, 0x0d, 0x79, 0x0b, 0x3e, 0x40, 0xee, 0x90, + 0x37, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xdd, + 0x80, 0x33, 0xe1, 0x2c, 0xd8, 0x23, 0x3e, 0x00, + 0xcf, 0x86, 0x3f, 0xe4, 0x08, 0xe8, 0x03, 0x00, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, + 0x9d, 0x00, 0xb7, 0x08, 0x35, 0x80, 0x08, 0x62, + 0x02, 0x10, 0x02, 0x86, 0x00, 0x21, 0xc3, 0x0b, + 0xe2, 0x42, 0x50, 0x40, 0xb7, 0x10, 0x2d, 0x84, + 0x0b, 0x40, 0x12, 0xd4, 0x00, 0xbf, 0x10, 0xa9, + 0xc4, 0x0d, 0x70, 0x02, 0x1c, 0xe0, 0xf6, 0x11, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x28, 0xbc, + 0x00, 0x23, 0x90, 0x08, 0x51, 0x02, 0x1c, 0x40, + 0x86, 0x00, 0x2f, 0xc4, 0x88, 0x72, 0x12, 0x2a, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x94, 0x00, 0xb7, 0x10, 0x27, 0x80, 0x28, 0xf0, + 0x02, 0x38, 0x00, 0x96, 0x08, 0x21, 0x40, 0x0b, + 0x41, 0x0e, 0x98, 0x00, 0xb7, 0x00, 0x2d, 0x80, + 0x0b, 0x40, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x25, + 0x80, 0x09, 0xe0, 0x02, 0x1c, 0x05, 0xb6, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb4, + 0x00, 0x21, 0xc0, 0x1a, 0x60, 0x0a, 0x9c, 0x00, + 0x87, 0x00, 0x2d, 0x80, 0x88, 0x10, 0x42, 0x80, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, + 0xc4, 0x10, 0xb3, 0x61, 0x24, 0xa0, 0x88, 0x20, + 0x02, 0x0a, 0x00, 0x92, 0x40, 0x20, 0xf0, 0x0b, + 0x8c, 0x02, 0x89, 0x80, 0xb3, 0xa4, 0x2c, 0xa8, + 0x0b, 0x0d, 0x82, 0xcd, 0x00, 0xb1, 0xed, 0x09, + 0x00, 0x62, 0x01, 0x40, 0x28, 0xd0, 0x09, 0x39, + 0x02, 0x2d, 0x08, 0xa2, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcf, 0x00, 0x38, 0x40, 0x20, 0x20, + 0x08, 0x03, 0x02, 0xa4, 0x40, 0x88, 0x48, 0x2c, + 0x34, 0x08, 0x04, 0x02, 0x88, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0x15, 0xa4, 0x00, 0xf3, + 0xc0, 0x36, 0xd6, 0x0c, 0xb0, 0x03, 0x2b, 0x20, + 0xdb, 0x40, 0x30, 0xf0, 0x0f, 0xa4, 0x83, 0x8b, + 0x20, 0xfb, 0xa0, 0x3e, 0x82, 0x1e, 0x90, 0x43, + 0xef, 0x20, 0xfb, 0x40, 0x76, 0xf2, 0x0d, 0x38, + 0x03, 0x2f, 0x00, 0xea, 0x00, 0x36, 0xc0, 0x0f, + 0xb0, 0x03, 0xed, 0x40, 0xdb, 0x00, 0x32, 0xc2, + 0x1e, 0xa4, 0x03, 0xac, 0x00, 0xcb, 0xa0, 0x3e, + 0x50, 0x0c, 0xaa, 0x03, 0xaa, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0xe4, 0x08, 0xfb, + 0x01, 0xfe, 0x40, 0x0f, 0xb6, 0x03, 0xe0, 0x20, + 0xeb, 0x09, 0x3e, 0xd2, 0x0f, 0xa6, 0x03, 0x61, + 0x08, 0xfa, 0x02, 0x3e, 0x80, 0x87, 0x90, 0x03, + 0xed, 0x00, 0xfb, 0x40, 0x3a, 0xd0, 0x2f, 0xb0, + 0x43, 0xec, 0x00, 0xfa, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x02, 0xec, 0x00, 0xfb, 0x81, 0x3e, 0xc0, + 0x4f, 0x24, 0x03, 0x6c, 0x02, 0xfb, 0x00, 0x3e, + 0x92, 0x4f, 0xb4, 0x01, 0x60, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x10, 0xf4, 0x00, 0xfb, + 0x20, 0x33, 0xc0, 0x8f, 0xf8, 0x03, 0xf8, 0x02, + 0xcf, 0x00, 0x3f, 0xd0, 0x0c, 0xc0, 0x03, 0x78, + 0x00, 0xce, 0x00, 0x3f, 0xb0, 0x0c, 0xd0, 0x0b, + 0x35, 0x20, 0xcf, 0x08, 0x33, 0xc2, 0x0f, 0xf0, + 0x03, 0x3c, 0x20, 0xde, 0x00, 0x33, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x10, 0xfc, 0x88, 0x33, 0x80, + 0x0c, 0xf0, 0x43, 0x2d, 0x00, 0xce, 0x40, 0x33, + 0x40, 0x0c, 0x70, 0x83, 0x08, 0x44, 0x30, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x63, 0x01, 0x00, 0x00, + 0x81, 0x04, 0x63, 0x10, 0xbb, 0x00, 0x32, 0x74, + 0x0b, 0xb4, 0x02, 0xc8, 0x00, 0x8b, 0x70, 0x2e, + 0xe8, 0x6a, 0x8c, 0x03, 0xa3, 0x40, 0x8a, 0x05, + 0x6c, 0xb2, 0x1d, 0x00, 0x82, 0x0c, 0x20, 0x8a, + 0x48, 0x22, 0xd4, 0x0b, 0xb0, 0x03, 0x6c, 0x48, + 0xf2, 0x04, 0x36, 0xc0, 0x0b, 0xb0, 0x12, 0xec, + 0x00, 0x99, 0x92, 0x22, 0x00, 0x08, 0x90, 0x22, + 0xa6, 0x00, 0x88, 0x80, 0x22, 0x36, 0x08, 0xa2, + 0x02, 0x28, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x05, 0x22, 0x00, 0xbb, 0x01, 0x22, 0xc3, + 0x0b, 0xb6, 0x02, 0xe8, 0x80, 0x8a, 0x00, 0x2e, + 0xc0, 0x48, 0xac, 0x02, 0x2c, 0x10, 0x8b, 0x80, + 0x2e, 0x80, 0x0a, 0x88, 0x02, 0x2c, 0x00, 0x83, + 0x00, 0x62, 0xc0, 0x4b, 0xb2, 0x82, 0x2c, 0x00, + 0x8a, 0x06, 0x22, 0xc0, 0x0b, 0xb0, 0x06, 0xec, + 0x00, 0xbb, 0x00, 0x20, 0x44, 0x08, 0x84, 0x02, + 0xa4, 0x00, 0x89, 0x08, 0x20, 0x40, 0x89, 0xb1, + 0x02, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x00, 0xb3, 0x00, 0x20, 0x40, + 0x4b, 0x30, 0x02, 0xca, 0x05, 0x82, 0x04, 0x2c, + 0xc0, 0x0a, 0x20, 0x0a, 0xa0, 0x00, 0x83, 0x04, + 0x2c, 0x80, 0x0a, 0x00, 0x02, 0x0c, 0x00, 0x83, + 0x00, 0x00, 0x00, 0x1b, 0x30, 0x02, 0x44, 0x02, + 0xb2, 0x00, 0x24, 0xc0, 0x0b, 0x30, 0x22, 0xcc, + 0x00, 0x92, 0x00, 0x20, 0x00, 0x08, 0x00, 0x0a, + 0x04, 0x00, 0x80, 0x01, 0xa0, 0x80, 0x09, 0x20, + 0x02, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x0d, 0x60, 0x08, 0xf9, 0x00, 0x22, 0xc0, + 0x0f, 0xb0, 0x03, 0xe8, 0x08, 0x8a, 0x00, 0x3e, + 0x80, 0x0c, 0x80, 0x13, 0x28, 0x00, 0xc9, 0x00, + 0x2e, 0x80, 0x4a, 0x80, 0x22, 0x2c, 0x00, 0xcb, + 0x00, 0x32, 0xc0, 0x0f, 0xed, 0x09, 0x00, 0x64, + 0x01, 0xb0, 0x53, 0x2c, 0x10, 0xca, 0x04, 0x32, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf8, 0x00, + 0x32, 0x01, 0x0c, 0x20, 0x03, 0xa4, 0x10, 0xc8, + 0x04, 0x32, 0x40, 0x25, 0xa0, 0x03, 0x00, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xf0, + 0x00, 0xfd, 0x00, 0x3b, 0x40, 0x0f, 0xf0, 0x03, + 0xd8, 0x00, 0x76, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, + 0x13, 0xb0, 0x10, 0xff, 0x00, 0x3f, 0x80, 0x09, + 0xc0, 0x03, 0xf4, 0x00, 0xfc, 0x00, 0xbf, 0x00, + 0x0f, 0xf0, 0x03, 0xf4, 0x00, 0xfe, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x02, 0xfc, 0x00, 0xfc, 0x00, + 0x3f, 0x00, 0x8f, 0xc0, 0x43, 0xf4, 0x00, 0xfc, + 0x07, 0x3f, 0x00, 0x0e, 0xf0, 0x03, 0xe8, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xf8, + 0x00, 0xff, 0x08, 0x33, 0x04, 0x0f, 0xc0, 0x03, + 0xfc, 0x80, 0xcf, 0x20, 0x3b, 0xc0, 0x0f, 0xf2, + 0x13, 0x7c, 0x04, 0xfc, 0x10, 0x3f, 0xc0, 0x07, + 0x72, 0x03, 0xf0, 0x00, 0xfc, 0x10, 0x33, 0xc8, + 0x0f, 0xc4, 0x43, 0x38, 0x00, 0xcc, 0x00, 0xb3, + 0xc1, 0x0a, 0xe1, 0x03, 0xb0, 0x00, 0xfc, 0x12, + 0x3f, 0x00, 0x2f, 0xe0, 0x0b, 0x30, 0x40, 0x9e, + 0x10, 0xb3, 0x0e, 0x0c, 0xf0, 0x03, 0xf0, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0xe0, + 0x04, 0xbf, 0x60, 0x22, 0x08, 0x0b, 0x82, 0x22, + 0xfd, 0xe0, 0x8f, 0x50, 0x23, 0xd0, 0x0b, 0xf1, + 0x02, 0xec, 0x80, 0xb2, 0x20, 0x2f, 0xc4, 0x0b, + 0xf4, 0x42, 0xec, 0x20, 0xbb, 0x20, 0x23, 0xc4, + 0x0b, 0xb2, 0x02, 0xac, 0x00, 0xaa, 0x08, 0x22, + 0xc1, 0x0a, 0xa0, 0x02, 0x28, 0x00, 0xb0, 0x20, + 0x26, 0x00, 0x08, 0xa4, 0x82, 0x2c, 0x80, 0xaa, + 0x10, 0x22, 0x10, 0x08, 0xb0, 0x02, 0xe0, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xed, + 0x09, 0x00, 0x65, 0x01, 0xce, 0x00, 0xb3, 0x08, + 0x20, 0x40, 0x0b, 0x10, 0x82, 0xcc, 0x00, 0x83, + 0x00, 0x24, 0xc4, 0x0b, 0x30, 0x02, 0x4c, 0x20, + 0xb2, 0x20, 0x2c, 0xc0, 0x0b, 0x34, 0x02, 0xcc, + 0x80, 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, + 0x20, 0x00, 0xa9, 0x22, 0x22, 0xc0, 0x43, 0x82, + 0x02, 0x88, 0x00, 0xb0, 0x20, 0x24, 0x00, 0x09, + 0x86, 0x02, 0x2c, 0x04, 0x92, 0xa1, 0x20, 0xc8, + 0x08, 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x05, 0xa4, 0x80, 0xbb, 0x00, + 0xa2, 0x00, 0x0b, 0x80, 0x02, 0xcc, 0x00, 0x8b, + 0x00, 0x26, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0xba, 0x80, 0x2e, 0xc1, 0x09, 0xb0, 0x02, 0xec, + 0x04, 0xb1, 0x40, 0x22, 0xc0, 0x0b, 0x30, 0x82, + 0x2c, 0x00, 0xaa, 0x08, 0x22, 0xc0, 0x8b, 0xa1, + 0x02, 0x2c, 0x40, 0xbb, 0x00, 0x66, 0x88, 0x02, + 0x82, 0x82, 0x2c, 0x00, 0x2a, 0x00, 0x00, 0xc2, + 0x08, 0xb0, 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x05, 0xee, 0x08, 0xfb, 0x00, + 0xb2, 0x72, 0x0f, 0x90, 0x03, 0xec, 0x02, 0xcb, + 0x00, 0x36, 0xc1, 0x8f, 0xb0, 0x03, 0x6c, 0x00, + 0xf9, 0x80, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xed, + 0x40, 0xfb, 0xc0, 0x32, 0xc0, 0x0b, 0xbc, 0x0b, + 0x0f, 0x10, 0xe8, 0x50, 0x32, 0xc0, 0x0f, 0xbc, + 0x0b, 0xa9, 0x00, 0xb8, 0x24, 0x36, 0x02, 0x0f, + 0x8c, 0x03, 0x20, 0x00, 0xda, 0x80, 0x32, 0x30, + 0x0c, 0xb0, 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x41, 0xb4, 0x00, 0x7f, 0x00, + 0x3f, 0x64, 0x0f, 0xdc, 0x03, 0xec, 0x00, 0xf7, + 0x00, 0x33, 0xc0, 0x0f, 0xf0, 0x23, 0xfc, 0x00, + 0xfe, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x83, 0xfe, + 0x00, 0xff, 0x92, 0xbf, 0xc0, 0x0f, 0xf4, 0x13, + 0xff, 0x00, 0xed, 0x09, 0x00, 0x66, 0x01, 0xfe, + 0x80, 0x3f, 0xf0, 0x0c, 0xf0, 0x03, 0xf8, 0x00, + 0xfc, 0x42, 0x37, 0x02, 0x2d, 0x90, 0x03, 0xfc, + 0x00, 0xfc, 0x90, 0x3f, 0x04, 0x6f, 0xf0, 0x03, + 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x00, 0xac, 0x00, 0xc3, 0x00, 0x32, 0x40, 0x0f, + 0x90, 0x03, 0xec, 0x00, 0xcb, 0x00, 0x32, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xcb, 0x40, 0x32, + 0xc0, 0x4f, 0xb1, 0x23, 0xa5, 0x02, 0xeb, 0x04, + 0x3e, 0xc6, 0x0f, 0x94, 0x03, 0xe5, 0x80, 0xc9, + 0x40, 0x32, 0xd0, 0x0d, 0xb4, 0x03, 0xad, 0x60, + 0xfb, 0x40, 0x22, 0x90, 0x0e, 0x90, 0x03, 0x2c, + 0x00, 0xd1, 0x00, 0x76, 0xc0, 0x0f, 0xb0, 0x03, + 0x50, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0x05, 0x24, 0x00, 0x8f, 0x04, 0x22, 0xc0, 0x0b, + 0x90, 0x02, 0xfc, 0x00, 0x8f, 0x90, 0x2b, 0xf8, + 0x0b, 0xf0, 0x02, 0xec, 0x00, 0x8a, 0x00, 0x23, + 0xc2, 0x0b, 0xf8, 0x02, 0x2c, 0x00, 0x8b, 0x00, + 0x2f, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0x82, + 0x10, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0x2e, 0x00, + 0xbb, 0x00, 0x20, 0xb0, 0x08, 0x1a, 0x22, 0x0c, + 0x00, 0xbb, 0x00, 0x6e, 0xc0, 0x1b, 0xb0, 0x02, + 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x15, 0x40, 0x00, 0x83, 0x00, 0x20, 0x40, 0x0b, + 0x10, 0x02, 0xcc, 0x00, 0xa3, 0xc0, 0x20, 0xe8, + 0x8b, 0x30, 0x02, 0xcc, 0x00, 0x93, 0x02, 0x20, + 0xe8, 0x0b, 0x30, 0x02, 0x4c, 0x00, 0x93, 0x00, + 0x2c, 0xd0, 0x0b, 0x30, 0x02, 0xcd, 0x00, 0x82, + 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0x8a, 0x00, + 0xb0, 0x00, 0x24, 0x34, 0x0a, 0x20, 0x42, 0x40, + 0x00, 0x91, 0x00, 0x20, 0x00, 0x0a, 0x30, 0x02, + 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x3a, 0x00, 0x87, 0x90, 0xed, 0x09, 0x00, + 0x67, 0x01, 0x21, 0x20, 0x0b, 0x48, 0x02, 0xde, + 0x02, 0x83, 0x98, 0x21, 0xe0, 0x8b, 0x78, 0x02, + 0xde, 0x02, 0x96, 0x80, 0x21, 0xe0, 0x0b, 0x79, + 0x02, 0x56, 0x00, 0x97, 0x82, 0x2d, 0xe0, 0x0b, + 0x58, 0x02, 0xdc, 0x00, 0x86, 0xa0, 0x21, 0xa4, + 0x0b, 0x78, 0x02, 0x9e, 0x00, 0xb7, 0x90, 0x2f, + 0xa0, 0x02, 0x70, 0x02, 0x5e, 0x00, 0xb5, 0x80, + 0x2d, 0x04, 0x0b, 0x78, 0x02, 0xc8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x08, 0x40, + 0xcb, 0x10, 0x30, 0x08, 0x0f, 0x00, 0x03, 0xcc, + 0x00, 0xe3, 0x00, 0x30, 0xc8, 0x0f, 0x30, 0x03, + 0xec, 0x00, 0xd3, 0x00, 0x30, 0xc0, 0x0f, 0x30, + 0x03, 0xe9, 0x00, 0xd3, 0x00, 0x1c, 0xc0, 0x0f, + 0x30, 0x03, 0xec, 0x40, 0xca, 0x00, 0x30, 0xd4, + 0x0f, 0xb4, 0x03, 0x88, 0x80, 0xf0, 0x00, 0x34, + 0x00, 0x0e, 0x31, 0x43, 0x4c, 0x00, 0xd1, 0x00, + 0x30, 0x00, 0x0e, 0x30, 0x03, 0x52, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x0d, 0x90, 0x00, + 0xff, 0x12, 0xbf, 0x00, 0x0f, 0xe1, 0x03, 0xfc, + 0x00, 0xff, 0x04, 0x3f, 0xc2, 0x0f, 0xf0, 0x83, + 0xfc, 0x00, 0xee, 0x10, 0x3f, 0xd4, 0x0f, 0xf0, + 0x43, 0xbc, 0x00, 0xef, 0x10, 0x37, 0xc0, 0x0f, + 0xf1, 0x33, 0xfc, 0x80, 0xfe, 0x20, 0x3f, 0xc4, + 0x0b, 0xf0, 0x03, 0x7c, 0x00, 0xff, 0x00, 0x31, + 0x80, 0x0d, 0xf2, 0x03, 0xbc, 0x00, 0xfd, 0x10, + 0x3f, 0x08, 0x0f, 0xf0, 0x03, 0xd0, 0x06, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, 0xe0, 0x00, + 0xfb, 0x28, 0x32, 0x40, 0x4f, 0x98, 0x03, 0x2d, + 0x20, 0xf3, 0xc8, 0x30, 0xd0, 0x0d, 0xbe, 0x03, + 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc8, 0x0f, 0xbe, + 0x03, 0x2c, 0x00, 0xf9, 0x00, 0x32, 0xcb, 0x0f, + 0x38, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x22, 0x40, + 0xed, 0x09, 0x00, 0x68, 0x01, 0x2d, 0xb8, 0x03, + 0x0c, 0x00, 0xdb, 0x00, 0x26, 0x80, 0x0f, 0xa0, + 0x03, 0x22, 0x00, 0xca, 0x00, 0x32, 0xc0, 0x0f, + 0xb0, 0x03, 0xea, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x11, 0x98, 0x00, 0xb7, 0x40, 0x21, + 0xc0, 0x0b, 0x50, 0x02, 0x1c, 0x80, 0xb7, 0x00, + 0x31, 0xc2, 0x08, 0x33, 0x02, 0x1c, 0x00, 0xb7, + 0x00, 0x2d, 0xc8, 0x0b, 0x32, 0x8a, 0x1c, 0x00, + 0xbf, 0x00, 0x21, 0xd0, 0x0b, 0x70, 0x03, 0x5c, + 0x00, 0xbe, 0x00, 0x29, 0x40, 0x08, 0x70, 0x0a, + 0x1c, 0x00, 0x87, 0x04, 0x21, 0xc0, 0x03, 0xf0, + 0x02, 0xbc, 0x10, 0xa4, 0x00, 0x21, 0xc0, 0x0b, + 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x00, 0x9e, 0x00, 0xb7, 0xa0, 0x21, + 0x60, 0x1b, 0x78, 0x02, 0x1e, 0xc0, 0x97, 0xb6, + 0xa1, 0xe0, 0x09, 0x7a, 0x02, 0x5e, 0x00, 0xb7, + 0x80, 0x2d, 0xe4, 0x0b, 0x79, 0x02, 0x5e, 0x00, + 0xb7, 0x80, 0x21, 0xe0, 0x0b, 0xf8, 0x02, 0x1e, + 0x00, 0xb7, 0x80, 0x23, 0xe0, 0x0b, 0xf8, 0x0a, + 0x7e, 0x08, 0x9f, 0x80, 0x2d, 0xe0, 0x4b, 0x78, + 0x02, 0x9e, 0x00, 0x85, 0x80, 0x21, 0xe0, 0x0b, + 0x78, 0x02, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x14, 0xc4, 0x00, 0xb3, 0x00, 0x26, + 0x40, 0x0b, 0x18, 0x02, 0x2c, 0x00, 0xb3, 0x00, + 0x00, 0xc0, 0x08, 0x30, 0x02, 0x8c, 0x00, 0xb3, + 0x08, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x06, 0x00, + 0xb1, 0x80, 0x24, 0xc0, 0x0b, 0x11, 0x02, 0x4d, + 0x08, 0xb2, 0x00, 0x20, 0xc0, 0x0a, 0x38, 0x02, + 0x4c, 0x08, 0x8b, 0xe0, 0x20, 0xc4, 0x99, 0xb4, + 0x42, 0x8c, 0x00, 0xab, 0x50, 0x20, 0xd9, 0x0b, + 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x15, 0xb9, 0x00, 0xfa, 0x00, 0xb3, + 0x98, 0x4f, 0xec, 0xed, 0x09, 0x00, 0x69, 0x01, + 0x0b, 0x28, 0x04, 0xfa, 0x00, 0x32, 0x80, 0x0d, + 0xa0, 0x03, 0x68, 0x00, 0xfe, 0x40, 0x3e, 0x80, + 0x0f, 0xa0, 0x03, 0x3b, 0x80, 0xf6, 0xc8, 0xb2, + 0x80, 0x0b, 0xec, 0x03, 0x18, 0x08, 0xfe, 0x40, + 0xb3, 0xb0, 0x2f, 0xec, 0x83, 0x5b, 0x20, 0xde, + 0xa4, 0x3f, 0xb0, 0x0f, 0xe6, 0x03, 0xb8, 0x00, + 0xce, 0x00, 0xb3, 0x90, 0x0f, 0xa0, 0x03, 0xfa, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x62, 0x00, 0xf8, 0x00, 0x3a, 0x20, 0x0f, 0x89, + 0x03, 0xe0, 0x00, 0xf8, 0x44, 0x3a, 0x11, 0x0f, + 0x80, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x10, + 0x0f, 0x80, 0x43, 0xe2, 0x00, 0xf8, 0x80, 0x3a, + 0x00, 0x0f, 0x88, 0x03, 0xe0, 0x80, 0xf8, 0x80, + 0x3e, 0x24, 0x0d, 0x88, 0x03, 0xa3, 0x00, 0xf8, + 0x00, 0x3e, 0x20, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xd2, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0xe4, 0x00, 0xf1, 0x01, 0x36, 0x40, 0x0c, 0x90, + 0x03, 0xe4, 0x00, 0xc9, 0x00, 0x3e, 0x41, 0x0e, + 0x90, 0x02, 0x64, 0x00, 0xe9, 0x01, 0x3e, 0x70, + 0x0d, 0x9c, 0x03, 0x64, 0x00, 0xc9, 0x00, 0x36, + 0x60, 0x0f, 0x90, 0x03, 0xe4, 0x01, 0xc9, 0x00, + 0x3a, 0x40, 0x0e, 0x90, 0x03, 0xe4, 0x00, 0xe9, + 0x00, 0x3a, 0x40, 0x0c, 0x90, 0x83, 0x24, 0x00, + 0x59, 0x08, 0x38, 0x40, 0x0c, 0x90, 0x03, 0xc3, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, + 0x64, 0x4c, 0xb9, 0x00, 0x22, 0x40, 0x08, 0x90, + 0x02, 0xe4, 0x02, 0xc9, 0xd2, 0x2c, 0x50, 0x08, + 0x90, 0x02, 0xe4, 0x00, 0x89, 0x00, 0x2e, 0x42, + 0x0b, 0x94, 0x03, 0xa4, 0x00, 0x89, 0x00, 0x22, + 0x51, 0x0b, 0x90, 0x02, 0xe4, 0x20, 0xf1, 0x00, + 0x20, 0x4c, 0x0a, 0x90, 0x02, 0xe5, 0xed, 0x09, + 0x00, 0x6a, 0x01, 0x40, 0x89, 0x01, 0x20, 0x54, + 0x0c, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x22, + 0x40, 0x08, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x01, 0x24, 0x00, 0xb9, + 0x00, 0xa2, 0x40, 0x09, 0xb0, 0x02, 0xe4, 0x00, + 0x99, 0x00, 0x2e, 0x48, 0x4a, 0x90, 0x42, 0x44, + 0x01, 0xab, 0x00, 0x2e, 0x40, 0x09, 0x90, 0x02, + 0xc4, 0x04, 0x89, 0x00, 0x22, 0x59, 0x0b, 0x90, + 0x02, 0xec, 0x00, 0x99, 0x08, 0x2a, 0x40, 0x08, + 0x90, 0x02, 0xec, 0x02, 0xa9, 0x00, 0x22, 0x50, + 0x88, 0x90, 0x02, 0x64, 0x00, 0x99, 0x00, 0x26, + 0x40, 0x09, 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, 0xb1, + 0x40, 0x20, 0x50, 0x09, 0x14, 0x42, 0xc5, 0x00, + 0x83, 0x00, 0x24, 0xc0, 0x08, 0x10, 0x02, 0xc5, + 0x00, 0x81, 0x40, 0x2c, 0x40, 0x0b, 0x10, 0x02, + 0x85, 0x00, 0x89, 0x40, 0x80, 0x40, 0x0b, 0x14, + 0x52, 0xe5, 0x00, 0xa1, 0x40, 0x20, 0x40, 0x0a, + 0x14, 0x02, 0xcc, 0x00, 0x81, 0x40, 0x20, 0x40, + 0x08, 0x14, 0x42, 0x45, 0x00, 0xb1, 0x40, 0x24, + 0x50, 0x09, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, 0x00, 0xf0, + 0x00, 0x32, 0x00, 0x0d, 0x00, 0x03, 0xe0, 0x00, + 0xd8, 0x04, 0x2e, 0x01, 0x0e, 0x80, 0x03, 0x60, + 0x08, 0xe8, 0x00, 0x3e, 0x00, 0x09, 0xa0, 0x03, + 0xe0, 0x02, 0xc8, 0x00, 0x12, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x00, 0x98, 0x00, 0x3a, 0x00, 0x0c, + 0x80, 0x03, 0xe0, 0x00, 0xe8, 0x00, 0x92, 0x00, + 0x2c, 0x80, 0x0b, 0x60, 0x00, 0xd0, 0x00, 0x36, + 0x00, 0x2d, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x1d, 0xf4, 0x00, 0xf9, + 0x40, 0x3b, 0x40, 0x2e, 0xd0, 0x03, 0xe5, 0x10, + 0xf9, 0xed, 0x09, 0x00, 0x6b, 0x01, 0x40, 0x3e, + 0x50, 0x0f, 0x94, 0x03, 0xe4, 0x04, 0xfd, 0x40, + 0x3e, 0x51, 0x0f, 0x94, 0x03, 0xf4, 0x00, 0xfd, + 0x00, 0x3a, 0x50, 0x4b, 0xd0, 0x03, 0xf4, 0x00, + 0xfd, 0x02, 0x3d, 0x40, 0x0f, 0x50, 0x21, 0xf4, + 0x00, 0xf5, 0x00, 0x3f, 0x40, 0x0e, 0xd4, 0x03, + 0xb4, 0x00, 0xfd, 0x40, 0xbb, 0x50, 0x0e, 0x90, + 0x03, 0xe7, 0x02, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x01, 0xf4, 0x00, 0xc9, 0x00, 0x32, 0x40, + 0x07, 0x91, 0x03, 0x24, 0x80, 0xf5, 0x28, 0x3f, + 0x48, 0x0f, 0x90, 0x0b, 0x24, 0x00, 0xf9, 0x10, + 0x3d, 0x48, 0x0c, 0xd2, 0x83, 0xe4, 0x40, 0xc9, + 0x00, 0x3f, 0x40, 0x1c, 0x91, 0x03, 0xf4, 0x00, + 0xcd, 0x00, 0x1b, 0x40, 0x0f, 0x90, 0x0b, 0x14, + 0x00, 0xd9, 0x12, 0x37, 0x40, 0x0f, 0xd2, 0x83, + 0xe4, 0x44, 0xe9, 0x00, 0x3e, 0xc0, 0x0f, 0x90, + 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x10, 0xe0, 0x00, 0x88, 0x48, 0xa2, 0x02, + 0x0b, 0x80, 0x02, 0x20, 0xa0, 0xb8, 0x02, 0x26, + 0x04, 0x0b, 0x84, 0x02, 0x20, 0x30, 0xb8, 0x10, + 0x2e, 0x00, 0x08, 0x80, 0x02, 0x68, 0x82, 0x88, + 0x08, 0x2e, 0x00, 0x28, 0xa0, 0x02, 0xe0, 0xa0, + 0xd8, 0x20, 0x2e, 0x00, 0x0b, 0x80, 0x82, 0xa0, + 0x00, 0x88, 0x00, 0x22, 0x00, 0x0b, 0x82, 0x02, + 0xe0, 0x80, 0xaa, 0x48, 0x2e, 0x02, 0x0b, 0x80, + 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x05, 0xc4, 0x00, 0x81, 0x30, 0x20, 0x40, + 0x0b, 0x10, 0x02, 0x04, 0xc0, 0xb1, 0x02, 0x6c, + 0x40, 0x09, 0x11, 0x02, 0x44, 0x00, 0xb1, 0x00, + 0x24, 0x44, 0x08, 0x10, 0x02, 0xe4, 0x80, 0x81, + 0x20, 0x2c, 0xc4, 0x09, 0x10, 0x02, 0xe4, 0x80, + 0x81, 0xa8, 0x28, 0x40, 0x09, 0x92, 0x02, 0x04, + 0x00, 0xb9, 0x00, 0x24, 0xed, 0x09, 0x00, 0x6c, + 0x01, 0x60, 0x0b, 0x12, 0x82, 0xe4, 0x80, 0x81, + 0x30, 0x2c, 0x44, 0x0b, 0x10, 0x02, 0xc2, 0x01, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa5, + 0x00, 0x89, 0x00, 0x22, 0x50, 0x0b, 0x94, 0x02, + 0x24, 0x00, 0xb9, 0x00, 0x6e, 0x41, 0x0b, 0x90, + 0x02, 0x64, 0x08, 0xb9, 0x20, 0x2e, 0xc0, 0x08, + 0x90, 0x12, 0x64, 0x10, 0x89, 0x00, 0x26, 0x40, + 0x09, 0x90, 0x02, 0xe4, 0x00, 0x99, 0x04, 0x2e, + 0x54, 0x0b, 0x90, 0x02, 0xa5, 0x80, 0xb9, 0x51, + 0x22, 0x48, 0x0b, 0x91, 0x02, 0xe4, 0x00, 0xa9, + 0x00, 0x2e, 0x50, 0x0b, 0x90, 0x02, 0xc6, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe7, + 0x40, 0xc9, 0x00, 0x32, 0x60, 0x0f, 0x98, 0x03, + 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0d, 0x90, + 0x03, 0x64, 0x00, 0xf9, 0x01, 0x16, 0x40, 0x0c, + 0x90, 0x03, 0xe7, 0x00, 0xc9, 0xc8, 0x3e, 0x40, + 0x09, 0x99, 0x03, 0xe6, 0x40, 0xc9, 0x00, 0x3a, + 0x70, 0x0d, 0x98, 0x03, 0x05, 0x00, 0xf9, 0x80, + 0x36, 0x70, 0x0f, 0x9a, 0x03, 0xc4, 0x80, 0xc9, + 0xc0, 0x3e, 0x60, 0x0f, 0x90, 0x03, 0xe0, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xa6, + 0x02, 0xf1, 0x00, 0x3e, 0x50, 0x0f, 0x99, 0x1b, + 0xe4, 0x00, 0xf9, 0x00, 0x36, 0x40, 0x0f, 0x10, + 0x03, 0xa4, 0x00, 0xf9, 0x80, 0x3e, 0x40, 0x2f, + 0x90, 0x03, 0x66, 0x44, 0xf9, 0x20, 0x3c, 0x40, + 0x0e, 0x98, 0x03, 0xe4, 0x00, 0xf9, 0x01, 0x3e, + 0x60, 0x0f, 0x99, 0x0b, 0x66, 0x00, 0xc9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x80, 0xf9, + 0x20, 0x3e, 0x48, 0x0f, 0x90, 0x03, 0xca, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa0, + 0x00, 0xc8, 0x00, 0x3e, 0x10, 0x0f, 0x80, 0x03, + 0xe0, 0x00, 0xc8, 0x80, 0x3a, 0x20, 0x0f, 0xed, + 0x09, 0x00, 0x6d, 0x01, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x01, 0x38, 0x24, 0x0c, 0x88, 0x03, 0xe1, + 0x00, 0xf8, 0x40, 0x3e, 0x20, 0x4f, 0x84, 0x03, + 0xe0, 0x30, 0xe8, 0x00, 0x36, 0x20, 0x8e, 0x80, + 0x03, 0x63, 0x00, 0xd8, 0x40, 0x3e, 0x20, 0x0f, + 0x84, 0x13, 0xe1, 0x02, 0xc8, 0x40, 0xa2, 0x00, + 0x0f, 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x05, 0x0a, 0x00, 0xaa, 0x00, + 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xae, + 0x20, 0x33, 0xa0, 0x0b, 0xa0, 0x03, 0xa8, 0x00, + 0x9a, 0x00, 0x23, 0xb0, 0x28, 0xec, 0x82, 0xc8, + 0x00, 0xba, 0x00, 0x2f, 0x90, 0x0b, 0xa0, 0x02, + 0xda, 0x00, 0x8e, 0x80, 0x23, 0xb0, 0x08, 0x20, + 0x03, 0x3b, 0x00, 0x02, 0x05, 0x3b, 0xb0, 0x0e, + 0xa8, 0x12, 0xe8, 0x00, 0x0a, 0x00, 0x22, 0x80, + 0x0b, 0xa0, 0x02, 0x4a, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x04, 0x0c, 0x02, 0x83, 0x00, + 0x2c, 0xc0, 0x1b, 0xb0, 0x42, 0xcc, 0x00, 0x81, + 0x80, 0x2c, 0x20, 0x0b, 0x30, 0x02, 0x8c, 0x00, + 0xb3, 0x00, 0x28, 0x40, 0x08, 0x10, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0x40, 0x0b, 0x30, 0x02, + 0xcd, 0x00, 0xa3, 0x80, 0x24, 0xc4, 0x1a, 0x30, + 0x06, 0x0e, 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x0b, + 0x38, 0x06, 0xcc, 0x00, 0x83, 0x00, 0x20, 0xc0, + 0x0b, 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x01, 0x1d, 0x00, 0xa7, 0x24, + 0x2d, 0xcc, 0x0b, 0x72, 0x02, 0xde, 0x80, 0xa6, + 0x80, 0x21, 0xc2, 0x0b, 0x70, 0x02, 0x9c, 0xc0, + 0x93, 0xa0, 0x29, 0xc0, 0x08, 0x70, 0x02, 0xdc, + 0xc8, 0xb7, 0x20, 0x2d, 0xc0, 0x0b, 0x72, 0x00, + 0xfd, 0x00, 0x87, 0x88, 0x21, 0xe0, 0x08, 0x72, + 0x0a, 0x3c, 0x21, 0x87, 0x30, 0x29, 0xc2, 0x1a, + 0x54, 0x06, 0xed, 0x09, 0x00, 0x6e, 0x01, 0xdc, + 0x00, 0x03, 0x80, 0x21, 0xc0, 0x0b, 0x70, 0x02, + 0x68, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x08, 0x1e, 0x00, 0xc7, 0xc0, 0x2d, 0xea, 0x0f, + 0x7a, 0x03, 0xff, 0x20, 0xc6, 0x80, 0x3d, 0xe0, + 0x0f, 0x78, 0x03, 0x9e, 0x80, 0xf7, 0x82, 0x39, + 0xe0, 0x0c, 0x78, 0x03, 0xde, 0x40, 0xf7, 0xe8, + 0x2d, 0xe0, 0x0f, 0x7a, 0x82, 0xde, 0x04, 0xaf, + 0x84, 0x35, 0x60, 0x0e, 0xfa, 0x23, 0x1e, 0x00, + 0xd7, 0xa0, 0x3d, 0xe0, 0x0f, 0x78, 0x13, 0xfe, + 0x80, 0xc7, 0x80, 0x21, 0xe4, 0x8f, 0x78, 0x03, + 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x1d, 0x8c, 0x00, 0xdb, 0x2a, 0x3e, 0xd0, 0x43, + 0xb6, 0xa3, 0xec, 0x80, 0xf8, 0x02, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xac, 0x90, 0xdb, 0x20, 0x36, + 0xc0, 0x07, 0x90, 0x03, 0xec, 0x90, 0xfb, 0x20, + 0x3e, 0xc0, 0x0f, 0xb3, 0x03, 0xcc, 0x00, 0x7b, + 0x00, 0x3c, 0x40, 0x8f, 0xb1, 0x03, 0xac, 0x02, + 0xfb, 0x08, 0x2a, 0xc0, 0x0f, 0x90, 0x03, 0xec, + 0x00, 0xfb, 0x78, 0x3e, 0xd4, 0x0f, 0xb0, 0x03, + 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0xf6, 0x00, 0xcf, 0x80, 0x33, 0xe4, 0x0c, + 0xf9, 0x83, 0xfe, 0x04, 0xce, 0x80, 0x0f, 0xe4, + 0x0c, 0xf2, 0x03, 0xff, 0x00, 0xff, 0xc8, 0x33, + 0xe0, 0x4c, 0xf9, 0x23, 0xfe, 0x50, 0xff, 0x84, + 0x0f, 0xe4, 0x0c, 0xf9, 0x03, 0xde, 0x00, 0xcf, + 0x80, 0x33, 0xe0, 0x0f, 0x7b, 0x23, 0x7e, 0x00, + 0xef, 0x84, 0x33, 0xe0, 0x0f, 0xf8, 0x03, 0xbe, + 0x20, 0xff, 0x80, 0x3f, 0xe0, 0x0c, 0xf8, 0x03, + 0xc0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x11, 0x94, 0x00, 0x87, 0x00, 0x21, 0xc1, 0x08, + 0x71, 0x82, 0xdc, 0x80, 0x87, 0x00, 0x25, 0xc0, + 0x08, 0x70, 0x02, 0xdc, 0x00, 0xed, 0x09, 0x00, + 0x6f, 0x01, 0xbf, 0x00, 0x21, 0x44, 0x28, 0x70, + 0x02, 0xdc, 0x0c, 0x37, 0x00, 0x39, 0x00, 0x08, + 0x70, 0x02, 0x5c, 0x00, 0xdf, 0x50, 0x21, 0xc0, + 0x0d, 0x73, 0x0a, 0x1c, 0x00, 0xb7, 0x00, 0x21, + 0x00, 0x0b, 0x50, 0x42, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x08, 0x70, 0x02, 0xea, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x42, + 0x87, 0x10, 0x21, 0xc0, 0x88, 0x71, 0x02, 0x5c, + 0x10, 0x96, 0x00, 0x2d, 0x00, 0x08, 0x71, 0x02, + 0xdc, 0x00, 0xb7, 0x00, 0x25, 0xc0, 0x08, 0x70, + 0x12, 0xdc, 0x00, 0x37, 0x08, 0x2d, 0xc0, 0x88, + 0x70, 0x26, 0xfc, 0x00, 0x87, 0x00, 0x29, 0x80, + 0x0b, 0xf3, 0x0a, 0x18, 0x20, 0xa7, 0x00, 0xa9, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x20, 0xb7, 0x08, + 0x2c, 0xc0, 0x08, 0x70, 0x02, 0xc0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, 0xcc, 0x00, + 0x8b, 0x00, 0x20, 0xf8, 0x18, 0x34, 0x02, 0xcc, + 0x00, 0x92, 0x02, 0x24, 0xc0, 0x08, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0xc0, 0x24, 0xc1, 0x88, 0x30, + 0x02, 0xcd, 0x00, 0x93, 0xe0, 0x28, 0xc1, 0x88, + 0xbf, 0x02, 0x4c, 0x20, 0x13, 0x98, 0x20, 0x90, + 0x08, 0x30, 0x02, 0x09, 0x00, 0xb3, 0x50, 0x28, + 0x90, 0x1b, 0x12, 0x12, 0xcf, 0x04, 0xb3, 0x00, + 0x2e, 0xc0, 0x08, 0x30, 0x02, 0xc8, 0x05, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xae, 0x20, + 0xcf, 0x00, 0xb1, 0xc0, 0x2c, 0x7d, 0x03, 0x7c, + 0x02, 0xda, 0x00, 0x1e, 0xc0, 0xa8, 0xb0, 0x02, + 0xfc, 0x00, 0x7f, 0xc0, 0x36, 0xc0, 0x0c, 0xb0, + 0x02, 0xfd, 0x40, 0xff, 0x40, 0x3e, 0xc1, 0x08, + 0xf4, 0x03, 0xcc, 0x04, 0xc9, 0x40, 0xb8, 0xd4, + 0x0b, 0x70, 0x83, 0x2c, 0x00, 0xef, 0x40, 0x3a, + 0xe0, 0x0f, 0xb4, 0x03, 0xbd, 0x00, 0xff, 0x80, + 0xed, 0x09, 0x00, 0x70, 0x01, 0x3f, 0xc0, 0x28, + 0xb0, 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc4, 0x0f, 0xb0, 0x03, 0xcc, 0x00, 0xea, 0x00, + 0x34, 0x01, 0x8f, 0xb0, 0x13, 0xec, 0x00, 0xfb, + 0x30, 0x3a, 0xc0, 0x0f, 0xb0, 0x02, 0xee, 0x00, + 0xfb, 0x00, 0x3c, 0xd0, 0x0f, 0xb0, 0x03, 0x6d, + 0x40, 0xf9, 0x40, 0x16, 0xc0, 0x0d, 0xb0, 0x03, + 0xa9, 0x00, 0xfb, 0x0c, 0x36, 0xd6, 0x0f, 0x90, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x10, 0xfc, 0x00, 0xff, 0x00, 0x37, + 0xc0, 0x0c, 0xf0, 0x03, 0x3c, 0x00, 0xcf, 0xa0, + 0x3e, 0xc4, 0x0e, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3e, 0x70, 0x1f, 0x71, 0x03, 0x3c, 0x10, + 0xff, 0x00, 0x3f, 0x44, 0x0c, 0xf0, 0x03, 0x3c, + 0x01, 0xcd, 0x00, 0x37, 0x40, 0x0e, 0xf0, 0x03, + 0x3f, 0x20, 0xff, 0x00, 0x3f, 0x80, 0x0f, 0x72, + 0x03, 0x3c, 0x20, 0xef, 0x00, 0x3f, 0xc0, 0x2c, + 0xf0, 0x03, 0x40, 0x44, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x22, + 0xc0, 0x8a, 0xb0, 0x02, 0xac, 0x01, 0x8a, 0x00, + 0x2e, 0xc0, 0x48, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x01, 0x26, 0xf0, 0x8f, 0xb4, 0xa2, 0x2c, 0x04, + 0xbb, 0x01, 0x2e, 0xc9, 0x08, 0xb0, 0x02, 0x2e, + 0x81, 0xf0, 0x82, 0x2a, 0x40, 0x0a, 0xb0, 0x02, + 0x29, 0x00, 0x9b, 0x00, 0x2e, 0x98, 0x0e, 0x90, + 0x12, 0x0c, 0x12, 0x8b, 0x00, 0x2e, 0xc1, 0x18, + 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x05, 0x2c, 0x40, 0xbb, 0x00, 0x26, + 0xc0, 0x08, 0xb0, 0x02, 0x2c, 0x06, 0x88, 0x02, + 0x2e, 0xc0, 0x09, 0xb0, 0x46, 0xec, 0x00, 0xbb, + 0x00, 0x6e, 0xc0, 0xed, 0x09, 0x00, 0x71, 0x01, + 0x8b, 0x90, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x08, 0xb0, 0x02, 0x26, 0x04, 0x8b, 0x80, + 0x26, 0xc0, 0x0a, 0xb0, 0x02, 0x6c, 0x30, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, + 0xab, 0x00, 0x2e, 0xc0, 0x08, 0xb0, 0x02, 0xe0, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x0c, 0x00, 0xb3, 0x00, 0x22, 0xc0, 0x0a, 0xb0, + 0x02, 0x8c, 0x01, 0x82, 0x84, 0x24, 0xe0, 0x28, + 0x30, 0x02, 0xcc, 0x00, 0x93, 0x00, 0x2c, 0xc0, + 0x0a, 0x30, 0x0a, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x28, 0x30, 0x0a, 0x20, 0x08, 0xb3, 0x00, + 0x24, 0xc0, 0x08, 0xb0, 0x26, 0x40, 0x00, 0x93, + 0x00, 0x2c, 0x00, 0x0a, 0x30, 0x02, 0x2c, 0x00, + 0x83, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0x6c, 0x00, 0xf7, 0x00, 0x35, 0xc1, 0x0c, 0xf0, + 0x03, 0x1c, 0x00, 0x8a, 0x00, 0x3e, 0xc0, 0x0d, + 0xb0, 0x07, 0xfc, 0x00, 0xff, 0x00, 0x1e, 0xc0, + 0x8b, 0xb0, 0x03, 0x3c, 0x00, 0xff, 0x02, 0x3e, + 0xc0, 0x1c, 0xf0, 0x03, 0x24, 0x00, 0x8b, 0x00, + 0x36, 0x80, 0x0e, 0xb0, 0x03, 0x68, 0x00, 0xf7, + 0x00, 0x3e, 0x80, 0x0f, 0xb0, 0x03, 0x2c, 0x02, + 0xef, 0x00, 0x3f, 0xc0, 0x08, 0xb0, 0x03, 0x40, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, + 0xdc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x07, 0xf0, + 0x43, 0xfc, 0x00, 0xfd, 0x00, 0x3f, 0x00, 0x0d, + 0xf0, 0x03, 0xfc, 0x08, 0xff, 0x00, 0x17, 0x00, + 0x0f, 0xc0, 0x07, 0xfc, 0x00, 0xff, 0x00, 0x3d, + 0x00, 0x0f, 0xf0, 0x00, 0xf4, 0x00, 0xfe, 0x00, + 0x3b, 0x80, 0x0f, 0xf0, 0x2b, 0xb8, 0x08, 0xff, + 0x00, 0x3f, 0x80, 0x0e, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0xed, 0x09, + 0x00, 0x72, 0x01, 0x03, 0xe8, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x05, 0xf0, 0x02, 0xcc, + 0x00, 0x2f, 0x08, 0x8c, 0xc0, 0x0b, 0x30, 0x00, + 0xf7, 0x04, 0x33, 0x80, 0x0c, 0xd0, 0x43, 0x30, + 0x00, 0xf5, 0x00, 0x1f, 0x01, 0x2c, 0xe0, 0x43, + 0xf0, 0x00, 0xcc, 0x00, 0x3f, 0x10, 0x2c, 0xc0, + 0x03, 0xf1, 0x00, 0xfc, 0x00, 0x3b, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xfc, 0x1c, 0x37, 0x08, + 0x2d, 0xc1, 0x83, 0x30, 0x80, 0xcc, 0x20, 0x17, + 0x00, 0x0c, 0xc0, 0x03, 0x30, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x10, 0xe4, 0x20, 0x89, + 0x00, 0x2e, 0x44, 0x08, 0x90, 0x82, 0x24, 0x00, + 0xbb, 0x00, 0x22, 0xc1, 0x0d, 0xa0, 0x03, 0x60, + 0x00, 0x3b, 0x20, 0x2e, 0x00, 0x08, 0xb0, 0x22, + 0xe0, 0x20, 0x8a, 0x02, 0x2e, 0x80, 0x0a, 0x80, + 0x02, 0xc0, 0x80, 0xb8, 0x28, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xec, 0xa0, 0xb0, 0x40, 0x32, 0x58, + 0x08, 0x92, 0x22, 0xa1, 0xb2, 0x80, 0x60, 0xa2, + 0x18, 0x08, 0x97, 0x83, 0x60, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x05, 0xe4, 0x80, 0x90, + 0x00, 0x2c, 0x40, 0x48, 0x92, 0x06, 0x00, 0x04, + 0xbb, 0x00, 0x22, 0x40, 0x88, 0x00, 0x02, 0x00, + 0x00, 0xb1, 0x28, 0x2e, 0xc0, 0x8a, 0x30, 0x02, + 0xc8, 0x00, 0x81, 0x00, 0x6c, 0x00, 0x2a, 0x30, + 0x02, 0xc0, 0x81, 0xb1, 0x20, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb0, 0x00, 0x24, 0x12, + 0x0a, 0x22, 0x02, 0x82, 0xc0, 0xa0, 0x18, 0x20, + 0x06, 0x08, 0x00, 0x02, 0x22, 0x11, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x15, 0xa4, 0x00, 0x9b, + 0x00, 0x2e, 0x60, 0x08, 0x98, 0x06, 0x24, 0x00, + 0xbb, 0x8c, 0xa2, 0x40, 0x09, 0x80, 0x86, 0x61, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0a, 0xb0, 0x06, + 0xc8, 0xed, 0x09, 0x00, 0x73, 0x01, 0x00, 0x8b, + 0x01, 0x6c, 0x82, 0x0a, 0xb0, 0x12, 0xe0, 0x60, + 0xb9, 0x20, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0xb9, 0x50, 0x22, 0x42, 0x08, 0xb1, 0x02, + 0x8c, 0x01, 0xa8, 0x00, 0x02, 0x00, 0x18, 0x98, + 0x02, 0x70, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x15, 0xca, 0x00, 0xda, 0x00, 0x3c, 0x20, + 0x0c, 0x18, 0x13, 0x25, 0x40, 0xf9, 0x00, 0x32, + 0xd0, 0x0c, 0x1c, 0x03, 0x20, 0x44, 0xbb, 0xc8, + 0x3e, 0xd8, 0x0e, 0xbd, 0x03, 0xe1, 0x00, 0x88, + 0x00, 0x2e, 0x10, 0x8e, 0x80, 0x03, 0xe3, 0x00, + 0xf8, 0x80, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xf8, 0xc0, 0x36, 0xb0, 0x0f, 0x88, 0x43, + 0xa0, 0x00, 0xeb, 0x84, 0x12, 0x94, 0x0c, 0x1c, + 0x83, 0x10, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x01, 0xb7, 0x00, 0xef, 0xc0, 0x3f, 0x42, + 0x0f, 0xd0, 0x03, 0xfe, 0x20, 0xfd, 0x00, 0x3f, + 0xd2, 0x0f, 0xec, 0x03, 0xf0, 0x00, 0xfe, 0xc1, + 0x3f, 0xe4, 0x0d, 0xf0, 0x03, 0xf0, 0x02, 0xfe, + 0x01, 0x3f, 0x80, 0x2f, 0xc0, 0x13, 0xf2, 0x00, + 0xfc, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x80, 0x39, 0xc5, 0x2d, 0x48, 0x03, + 0xf1, 0x00, 0xdc, 0x94, 0x3f, 0xe0, 0x6b, 0xd0, + 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x10, 0xac, 0x08, 0x4a, 0x00, 0x3e, 0x44, + 0x4f, 0x93, 0x0b, 0x2d, 0x08, 0xf9, 0x48, 0x32, + 0xd0, 0x0f, 0x88, 0x03, 0xe1, 0x04, 0x5b, 0x04, + 0x32, 0x49, 0x0f, 0xb1, 0xa3, 0x6b, 0x82, 0xe9, + 0x10, 0x3e, 0x30, 0x2f, 0xb1, 0x83, 0xe2, 0x02, + 0xe9, 0xa0, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x20, 0xe2, 0x00, 0xb2, 0x81, 0x06, 0x91, 0x0b, + 0x2c, 0x84, 0xf3, 0x00, 0xb2, 0x92, 0x0f, 0x94, + 0x03, 0x10, 0x04, 0x20, 0xed, 0x09, 0x00, 0x74, + 0x01, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, + 0x00, 0x8b, 0xc3, 0x2e, 0x41, 0x8b, 0x94, 0x22, + 0x2d, 0x80, 0xb1, 0x00, 0x28, 0xc8, 0x0b, 0xa8, + 0x42, 0xe0, 0x08, 0x8a, 0x41, 0xa8, 0x50, 0x4b, + 0xbc, 0x42, 0x2a, 0x10, 0x8b, 0x80, 0x2e, 0xb0, + 0x20, 0xbc, 0x02, 0xe2, 0x02, 0x89, 0xc0, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x80, 0x0b, 0x00, + 0x22, 0xc4, 0x0a, 0x95, 0x02, 0x2d, 0x20, 0xe8, + 0xf0, 0x22, 0xf0, 0x8b, 0x90, 0x03, 0x32, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x48, + 0x00, 0x83, 0x90, 0x2c, 0xb0, 0x0b, 0x14, 0x42, + 0x4f, 0x00, 0xb1, 0x40, 0x20, 0x61, 0x0b, 0x26, + 0x02, 0xc1, 0x80, 0x33, 0x00, 0x20, 0xc4, 0x0b, + 0x30, 0x02, 0x45, 0x00, 0xa0, 0x61, 0x2c, 0x58, + 0x8a, 0x04, 0x22, 0xcd, 0x80, 0xb2, 0x40, 0x6c, + 0xc0, 0x0b, 0x30, 0x02, 0xce, 0x00, 0xa0, 0x80, + 0x20, 0x20, 0x09, 0x08, 0x10, 0x00, 0x08, 0xb0, + 0x80, 0x2a, 0x54, 0x0b, 0x20, 0x02, 0x38, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x16, + 0x58, 0x85, 0xc0, 0x2d, 0x20, 0x4b, 0x59, 0x02, + 0x5e, 0x04, 0xb7, 0x80, 0x29, 0x60, 0x0b, 0x68, + 0x02, 0xf6, 0x08, 0x8f, 0xd0, 0x29, 0xe8, 0x0b, + 0xd8, 0x06, 0x56, 0x02, 0x86, 0x80, 0x2d, 0xe4, + 0x28, 0x48, 0x02, 0xde, 0x40, 0x96, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0x86, 0x88, + 0x21, 0x22, 0x0a, 0x18, 0x02, 0x1c, 0x40, 0xa7, + 0x84, 0x29, 0x60, 0x0b, 0x69, 0x02, 0x08, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x2c, + 0x02, 0xc3, 0x00, 0x3c, 0xc4, 0x9f, 0x91, 0x03, + 0x4c, 0x80, 0xf0, 0x00, 0x30, 0x44, 0x0f, 0x00, + 0x03, 0xc0, 0x90, 0xf3, 0x00, 0x70, 0xc0, 0x0f, + 0x31, 0x03, 0x6d, 0x02, 0xe1, 0x02, 0x3e, 0xed, + 0x09, 0x00, 0x75, 0x01, 0x44, 0x0f, 0x30, 0x13, + 0xcc, 0x02, 0xf3, 0x00, 0x3c, 0xc0, 0x0b, 0x30, + 0x03, 0xec, 0x00, 0xe3, 0x00, 0x22, 0x80, 0x0e, + 0x20, 0x03, 0x00, 0xc0, 0xf0, 0x40, 0x38, 0xd0, + 0x0f, 0x91, 0x03, 0x12, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x01, + 0x3f, 0xc1, 0x0f, 0xf1, 0x03, 0xbc, 0x00, 0xff, + 0x00, 0xff, 0x40, 0x0f, 0xe0, 0x03, 0xdc, 0x00, + 0xef, 0x00, 0x3f, 0xc8, 0x0f, 0x70, 0x02, 0xbc, + 0x00, 0xff, 0x00, 0x3f, 0xc4, 0x0f, 0xf0, 0x03, + 0xfc, 0x02, 0xef, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x40, 0x7f, 0x02, 0x3f, 0x80, 0x8e, + 0xf0, 0x03, 0xfc, 0x00, 0xef, 0x11, 0x37, 0xc0, + 0x8f, 0xf1, 0x43, 0x90, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x05, 0xe8, 0x04, 0xcb, 0x01, + 0x36, 0x80, 0x0f, 0x90, 0x03, 0x0e, 0x00, 0xc9, + 0x00, 0xb2, 0xc0, 0x4f, 0xb0, 0x03, 0xe4, 0x00, + 0xfb, 0x00, 0x38, 0xa0, 0x2c, 0xb0, 0x13, 0xe4, + 0x02, 0x58, 0x00, 0x3e, 0x40, 0x0d, 0x80, 0x03, + 0xec, 0x00, 0xca, 0x02, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xac, 0x00, 0xf9, 0x00, 0x3e, 0x00, 0x1f, + 0xa0, 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x72, 0x00, + 0x2c, 0xb8, 0x03, 0x2a, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x11, 0x84, 0x00, 0x87, 0x00, + 0x2d, 0xc0, 0x8b, 0xd0, 0x22, 0x1c, 0x00, 0x85, + 0x00, 0x21, 0xc0, 0x0b, 0x40, 0x02, 0xd4, 0x00, + 0xb7, 0x00, 0x21, 0x80, 0x08, 0x70, 0x02, 0xd4, + 0x00, 0x86, 0x00, 0x2f, 0xc0, 0x28, 0x40, 0x02, + 0xfc, 0x02, 0xf6, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0x00, 0x58, + 0x60, 0x02, 0xdc, 0x00, 0xb3, 0x00, 0x60, 0x40, + 0x08, 0xf0, 0x02, 0x12, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x76, 0x01, 0xc0, + 0x00, 0x9e, 0x00, 0x87, 0x80, 0x25, 0xe2, 0x0b, + 0x78, 0x02, 0x3e, 0x08, 0x87, 0x80, 0x21, 0xe2, + 0x0a, 0x68, 0x02, 0xd6, 0x00, 0xb7, 0x80, 0x29, + 0xe0, 0x09, 0x7c, 0x02, 0xde, 0x00, 0x95, 0x80, + 0x2d, 0x60, 0x29, 0x78, 0x02, 0xde, 0x00, 0x97, + 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, + 0xb7, 0x80, 0x2d, 0xa0, 0x49, 0x78, 0x72, 0x5e, + 0x18, 0xb7, 0x80, 0x25, 0xa1, 0x48, 0x78, 0x0a, + 0xb0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x14, 0xce, 0x42, 0x83, 0x02, 0x2c, 0xe0, 0x0b, + 0xb1, 0x42, 0x0c, 0x40, 0x83, 0x10, 0x20, 0xe0, + 0x0b, 0x21, 0x02, 0xcc, 0x08, 0xb3, 0x10, 0x20, + 0xf4, 0x09, 0x38, 0x22, 0xec, 0x08, 0x83, 0x00, + 0x2c, 0xc0, 0x88, 0x30, 0x02, 0xcc, 0x10, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x08, 0x2c, 0xa0, 0x08, 0x32, 0x02, 0xcc, + 0x00, 0xbb, 0x80, 0x24, 0xc9, 0x08, 0x31, 0x02, + 0x92, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, + 0x15, 0xb8, 0x00, 0xce, 0x83, 0x37, 0x80, 0x4f, + 0xe8, 0x0b, 0x3b, 0x02, 0xc6, 0x40, 0x33, 0xb0, + 0x0f, 0xec, 0x01, 0xf9, 0x00, 0xf6, 0xc0, 0x1b, + 0xb0, 0x89, 0xec, 0x03, 0xe8, 0x00, 0xda, 0x04, + 0x2e, 0x80, 0x2d, 0xa0, 0x03, 0xe8, 0x00, 0xda, + 0x00, 0x2e, 0x80, 0x0f, 0xa0, 0x03, 0xa8, 0x00, + 0xfe, 0x08, 0x3d, 0xa2, 0x0d, 0xe2, 0x43, 0x79, + 0x00, 0xfe, 0x60, 0xb7, 0xa2, 0x0c, 0xec, 0x03, + 0xba, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0xc0, 0x00, 0xf8, 0x50, 0x1e, 0x20, 0x0f, + 0x84, 0x83, 0xe0, 0x20, 0xf8, 0x80, 0x3e, 0x20, + 0x0f, 0x88, 0x03, 0xe3, 0x00, 0xf8, 0x09, 0x3e, + 0x02, 0x4e, 0x88, 0x03, 0xe0, 0x00, 0xf8, 0x40, + 0x3e, 0x00, 0x0f, 0x84, 0x03, 0xed, 0x09, 0x00, + 0x77, 0x01, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x07, 0xe0, 0x00, 0xf8, 0x40, 0x3e, + 0x01, 0x6d, 0x00, 0x22, 0xe0, 0x20, 0x78, 0x08, + 0x3a, 0x00, 0x0f, 0x86, 0x03, 0x52, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, + 0xe9, 0xc0, 0x3c, 0x48, 0x0c, 0x94, 0x03, 0xa6, + 0x00, 0xb9, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, + 0x64, 0x08, 0xf9, 0x00, 0x32, 0x60, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0x19, 0x80, 0x3e, 0x60, 0x0e, + 0x92, 0x03, 0x66, 0x80, 0xc9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xe7, 0x10, 0xe1, 0x80, 0x32, + 0x40, 0x0d, 0x98, 0x03, 0x24, 0x00, 0xc9, 0x80, + 0x32, 0x64, 0x08, 0x92, 0x43, 0xc2, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, 0x04, + 0x89, 0xc8, 0x2e, 0x40, 0x0a, 0x90, 0x82, 0x24, + 0x00, 0xb9, 0xc0, 0x36, 0x40, 0x0b, 0x18, 0x0a, + 0xa4, 0x84, 0xb9, 0x00, 0xa2, 0x40, 0x09, 0x98, + 0x02, 0xe5, 0x00, 0x89, 0x48, 0x2e, 0x70, 0x48, + 0x9e, 0x02, 0xe5, 0x00, 0xa9, 0x40, 0x2e, 0x40, + 0x0b, 0x90, 0x03, 0xe7, 0x80, 0x89, 0xc0, 0x22, + 0x44, 0x0a, 0x9c, 0x2a, 0x24, 0xc2, 0x89, 0x98, + 0xa2, 0x40, 0x08, 0x94, 0x02, 0xe0, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x18, 0xb0, 0x02, 0xec, + 0x40, 0xb9, 0x80, 0xa2, 0xc0, 0x0b, 0x98, 0x02, + 0x64, 0x00, 0xb9, 0x20, 0x22, 0x4a, 0x0b, 0xb5, + 0x02, 0xe4, 0x02, 0xbd, 0x10, 0x2d, 0x48, 0x4a, + 0xd0, 0x12, 0xd4, 0x0c, 0x8d, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xc4, 0x00, 0xa9, 0x10, 0x22, + 0x40, 0x29, 0x95, 0x42, 0x04, 0x00, 0x99, 0x00, + 0x20, 0x40, 0x0a, 0x90, 0x02, 0xc6, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x05, 0x00, + 0xed, 0x09, 0x00, 0x78, 0x01, 0x91, 0x00, 0x2c, + 0x40, 0x1a, 0x14, 0x02, 0x44, 0x00, 0xb9, 0x80, + 0x24, 0x40, 0x0b, 0x90, 0x02, 0x84, 0x00, 0xb9, + 0x44, 0x20, 0x40, 0x1b, 0x10, 0x02, 0xd7, 0x04, + 0xa5, 0x00, 0x2d, 0x70, 0x08, 0x54, 0x06, 0xd7, + 0x08, 0xa5, 0xc0, 0x2c, 0x40, 0x0b, 0x10, 0x02, + 0xc5, 0x02, 0x83, 0x40, 0xa2, 0x50, 0x0a, 0x14, + 0x02, 0x05, 0x00, 0x91, 0x40, 0x20, 0x50, 0x28, + 0x14, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb8, 0x0d, 0x60, 0x00, 0xf8, 0x01, 0x3e, + 0x00, 0x2c, 0x80, 0x0b, 0xe0, 0x00, 0xf8, 0x00, + 0x32, 0x00, 0x0f, 0xa0, 0x03, 0x60, 0x00, 0xfa, + 0x01, 0x32, 0x00, 0x1f, 0x80, 0x03, 0xc0, 0x00, + 0xf8, 0x00, 0x2e, 0x00, 0x0e, 0x80, 0x01, 0x60, + 0x00, 0xcc, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x00, 0xe8, 0x02, 0x30, 0x01, 0x0d, 0x80, + 0x03, 0x20, 0x00, 0xd8, 0x00, 0x32, 0x80, 0x0e, + 0xa0, 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x19, 0xf5, 0x00, 0xed, 0x00, 0x3f, + 0x50, 0x4f, 0xd0, 0x13, 0xb4, 0x00, 0xf5, 0x00, + 0xbb, 0x40, 0x0f, 0xf0, 0x13, 0xf4, 0x00, 0xf5, + 0x02, 0x3f, 0x41, 0x0d, 0xd0, 0x03, 0xe4, 0x00, + 0xc9, 0x02, 0x1e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xa4, 0x00, 0xfd, 0x40, 0x3f, 0x50, 0x0f, 0xd4, + 0x03, 0xf5, 0x00, 0xed, 0x40, 0x3f, 0x50, 0x8f, + 0xd4, 0x03, 0xe6, 0x02, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x05, 0xf5, 0x80, 0xc5, 0x00, 0x37, + 0x48, 0x0c, 0xd4, 0x03, 0x74, 0x00, 0xcd, 0x00, + 0x33, 0x40, 0x0c, 0xd0, 0x03, 0xf4, 0x00, 0xf5, + 0x00, 0x3f, 0x40, 0x0e, 0xd0, 0x03, 0xf4, 0x02, + 0xd5, 0x00, 0x3f, 0x40, 0x0c, 0x50, 0x03, 0xf4, + 0x02, 0xdd, 0x00, 0xed, 0x09, 0x00, 0x79, 0x01, + 0x32, 0x40, 0x0f, 0x90, 0x03, 0xf5, 0x00, 0xfd, + 0x4c, 0x3f, 0x40, 0x0d, 0xd2, 0x83, 0x3d, 0x00, + 0xcd, 0x25, 0x3f, 0x4a, 0xac, 0xd6, 0x03, 0xc6, + 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, + 0xe1, 0x80, 0x88, 0x00, 0x22, 0x00, 0x08, 0x82, + 0x02, 0xa0, 0x00, 0x08, 0x00, 0x22, 0x00, 0x0d, + 0x80, 0x42, 0xe0, 0x08, 0x38, 0x22, 0x22, 0x00, + 0x82, 0x80, 0x02, 0xc0, 0x10, 0xf8, 0x01, 0x2c, + 0x08, 0x8a, 0x80, 0x02, 0xe0, 0x08, 0xf8, 0x00, + 0xa2, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x80, 0xb0, + 0x40, 0x2e, 0x14, 0x8c, 0x86, 0x0a, 0x20, 0x04, + 0x88, 0x28, 0x2e, 0x08, 0x08, 0x87, 0x02, 0xce, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, + 0xcc, 0xc0, 0x81, 0x00, 0x64, 0x50, 0x08, 0x10, + 0x02, 0x64, 0x01, 0x89, 0x00, 0xa0, 0x40, 0x18, + 0x10, 0x02, 0xc4, 0x04, 0xb1, 0x08, 0xac, 0x40, + 0x0b, 0x10, 0x02, 0xc4, 0xa2, 0x91, 0x00, 0x2c, + 0x42, 0x28, 0x12, 0x86, 0xc4, 0xb0, 0x91, 0x28, + 0x20, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x4a, 0x0b, 0x18, 0x82, 0x45, 0x02, + 0x81, 0x31, 0x2c, 0x4b, 0x08, 0x18, 0x22, 0xc2, + 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, + 0xa6, 0x00, 0x89, 0x00, 0x22, 0x4a, 0x28, 0x90, + 0x82, 0xa4, 0x10, 0x8b, 0x1c, 0x22, 0x50, 0x09, + 0x90, 0x06, 0xe6, 0x08, 0xb9, 0x00, 0xa2, 0x44, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0x39, 0x08, 0x2c, + 0x40, 0x0a, 0x95, 0x22, 0xc4, 0x08, 0xb9, 0x08, + 0x22, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x40, 0x2e, 0x40, 0x0b, 0x90, 0x12, 0x64, 0x00, + 0x89, 0x02, 0x2e, 0x48, 0x08, 0x92, 0x02, 0xc6, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, + 0xe4, 0x80, 0xc9, 0x10, 0x36, 0x40, 0xed, 0x09, + 0x00, 0x7a, 0x01, 0x4c, 0x91, 0x23, 0x46, 0x40, + 0xc1, 0x00, 0x30, 0x70, 0x0c, 0x94, 0x03, 0xe4, + 0x00, 0xf9, 0x01, 0x3c, 0x72, 0x0f, 0x98, 0x92, + 0xe6, 0x02, 0xd9, 0x02, 0x1e, 0x40, 0x0c, 0x94, + 0x13, 0xe4, 0x02, 0xd9, 0x00, 0xb2, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x80, 0x3e, 0x40, + 0x4f, 0x98, 0x03, 0x65, 0x20, 0xc9, 0x00, 0x3e, + 0x40, 0x0c, 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, 0x02, 0xf9, + 0x80, 0xbe, 0x60, 0x0f, 0x98, 0x13, 0xe4, 0x02, + 0xf9, 0x80, 0x3e, 0x67, 0x0f, 0x92, 0x03, 0xe4, + 0x00, 0xf9, 0x01, 0x3e, 0x60, 0x08, 0x9c, 0x83, + 0xe4, 0x80, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x98, + 0x03, 0xe4, 0x22, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0xc2, 0x3e, 0x48, + 0x0c, 0x94, 0x83, 0x84, 0x40, 0xf9, 0x00, 0x7c, + 0x60, 0x0f, 0x98, 0x13, 0xca, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x10, 0xa1, 0x00, 0xc8, + 0x80, 0x36, 0x10, 0x0e, 0x84, 0x03, 0x22, 0x00, + 0xf8, 0x40, 0x32, 0x10, 0x0f, 0x8c, 0x03, 0xe2, + 0x00, 0xf8, 0x08, 0xf2, 0x18, 0x07, 0x80, 0x03, + 0xe0, 0x04, 0xe8, 0x83, 0x32, 0x00, 0x4c, 0x84, + 0x03, 0x20, 0x00, 0xf8, 0x20, 0x32, 0x00, 0x0f, + 0x80, 0x03, 0xa0, 0x20, 0xf8, 0x01, 0x32, 0x00, + 0x8d, 0x80, 0x03, 0x21, 0x22, 0xe8, 0x20, 0x02, + 0x08, 0x0f, 0x80, 0x02, 0xca, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x08, 0x00, 0x86, + 0xc0, 0xa1, 0x81, 0x08, 0xe5, 0x12, 0xb9, 0x00, + 0xbe, 0x10, 0x2b, 0x80, 0x4b, 0xee, 0x22, 0xf9, + 0x00, 0xbe, 0xa0, 0x23, 0x82, 0x49, 0xe8, 0x42, + 0xfb, 0x60, 0x8e, 0xc0, 0x23, 0x90, 0x28, 0xef, + 0x13, 0xf8, 0x00, 0xbe, 0x00, 0x3e, 0x80, 0x0b, + 0xa0, 0xed, 0x09, 0x00, 0x7b, 0x01, 0x02, 0xf9, + 0x00, 0x3e, 0x40, 0xa3, 0x90, 0x2a, 0xe0, 0x8a, + 0x39, 0x04, 0x8e, 0x81, 0x23, 0xa1, 0x0b, 0xe8, + 0x82, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x05, 0x4c, 0x00, 0x83, 0x80, 0x20, 0x80, + 0x0a, 0xb0, 0x12, 0x04, 0x10, 0xb3, 0x40, 0x20, + 0xd0, 0x0b, 0x38, 0x02, 0xc4, 0x40, 0xbb, 0xc0, + 0x20, 0x90, 0x0b, 0x09, 0x02, 0xef, 0x02, 0xa1, + 0x02, 0x28, 0xf2, 0x18, 0x3c, 0x02, 0x4d, 0x40, + 0xbb, 0xc0, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0x8e, + 0x00, 0xb3, 0x09, 0x22, 0xd2, 0x20, 0xb4, 0x02, + 0x0f, 0x00, 0xa3, 0x00, 0x20, 0xc0, 0x0b, 0x30, + 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x01, 0x1c, 0x00, 0x87, 0x08, 0x20, 0xd0, + 0x28, 0x70, 0x82, 0x9c, 0x00, 0xbf, 0x00, 0xa9, + 0xc0, 0x8b, 0x70, 0x02, 0xd4, 0x00, 0xbe, 0x00, + 0x21, 0xc0, 0x0b, 0x70, 0x22, 0xdc, 0x02, 0xa7, + 0xc0, 0x21, 0xc2, 0x08, 0xf8, 0x00, 0xdc, 0x00, + 0xb7, 0x08, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, + 0x20, 0xb7, 0x82, 0x23, 0x00, 0x08, 0x30, 0x02, + 0x1c, 0x20, 0x83, 0x88, 0xa1, 0xc2, 0x4b, 0x70, + 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x08, 0x3e, 0x02, 0xc7, 0x80, 0x31, 0xa0, + 0x4e, 0xf8, 0x0b, 0x1e, 0x00, 0xf5, 0x80, 0x71, + 0xe0, 0x0f, 0x78, 0x03, 0xd6, 0x04, 0xf6, 0x80, + 0xa1, 0xe0, 0x0f, 0x78, 0x02, 0xde, 0x04, 0xe7, + 0x80, 0xb9, 0xe0, 0x2c, 0x78, 0x03, 0x5e, 0x00, + 0xff, 0x84, 0x31, 0xe0, 0x0f, 0x78, 0x27, 0x9a, + 0x04, 0xf5, 0x80, 0x31, 0xe0, 0x28, 0x78, 0x23, + 0x06, 0x00, 0xe7, 0x80, 0x31, 0xe0, 0x8f, 0x68, + 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x1d, 0xac, 0x00, 0xba, 0x00, 0x3a, 0xc1, + 0x0f, 0xb0, 0x07, 0xec, 0xed, 0x09, 0x00, 0x7c, + 0x01, 0x00, 0xf1, 0x00, 0xbe, 0xc0, 0x4d, 0xb0, + 0x01, 0xe0, 0x08, 0xfa, 0x00, 0x2e, 0xc0, 0x0d, + 0xb0, 0x22, 0xec, 0x00, 0xdb, 0x00, 0x36, 0xc0, + 0x0f, 0xa0, 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x07, 0xe4, 0x00, 0xfb, 0x03, + 0x3c, 0x00, 0x8e, 0x90, 0x03, 0xe8, 0x00, 0xf9, + 0x00, 0x3e, 0xc0, 0x0f, 0xa0, 0x03, 0xc2, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf6, + 0x00, 0xee, 0x80, 0x3f, 0xa0, 0x4e, 0xf8, 0x43, + 0x36, 0x00, 0xf7, 0x80, 0xb9, 0xe4, 0x0c, 0xe9, + 0x43, 0xf6, 0x40, 0x8f, 0x80, 0x3f, 0xe0, 0x0c, + 0x78, 0x03, 0x7e, 0x10, 0xcf, 0x90, 0x33, 0xe0, + 0x0c, 0xf8, 0x03, 0x3e, 0x40, 0xcf, 0x80, 0xb3, + 0xe0, 0x0f, 0xf8, 0x03, 0xf6, 0x00, 0xfe, 0x00, + 0x31, 0xe4, 0x2c, 0xf8, 0x03, 0x3a, 0x00, 0xff, + 0x80, 0x37, 0xe0, 0x0c, 0xd8, 0x0b, 0x00, 0x02, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0x94, + 0x00, 0x84, 0x00, 0x2d, 0x40, 0x08, 0xf0, 0x0a, + 0x18, 0x44, 0xb7, 0x10, 0x21, 0xc5, 0x08, 0x40, + 0x02, 0xd1, 0x00, 0xdf, 0x20, 0x35, 0x80, 0x08, + 0x50, 0x00, 0x1c, 0x80, 0xa7, 0x30, 0x23, 0xc0, + 0x0f, 0xe0, 0x53, 0x5c, 0x44, 0xdf, 0x10, 0x3d, + 0xc0, 0x0b, 0x70, 0x02, 0xd0, 0x00, 0xbe, 0x00, + 0x35, 0x0c, 0x08, 0x72, 0x42, 0x10, 0x40, 0xb6, + 0x01, 0x2d, 0xc0, 0x08, 0x54, 0x02, 0x2a, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, + 0x40, 0xb6, 0x10, 0x2d, 0x00, 0x0a, 0x70, 0x02, + 0x1c, 0x00, 0xb4, 0x00, 0x29, 0xc0, 0x18, 0x60, + 0x92, 0xf4, 0x00, 0x96, 0x0a, 0x2f, 0xc0, 0x08, + 0x64, 0x82, 0x1c, 0x04, 0x8c, 0x00, 0x65, 0xc0, + 0x29, 0x70, 0x02, 0x1c, 0x01, 0x87, 0x00, 0x21, + 0xc0, 0x0b, 0x70, 0x02, 0xd8, 0x00, 0xa5, 0xed, + 0x09, 0x00, 0x7d, 0x01, 0x00, 0x23, 0xc0, 0x1a, + 0x60, 0x22, 0x94, 0x20, 0xb7, 0x00, 0x24, 0x00, + 0x08, 0x64, 0x82, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x14, 0xc5, 0x00, 0x90, 0x81, + 0x2c, 0xd1, 0x08, 0x84, 0x02, 0x08, 0x84, 0xb1, + 0x80, 0xa0, 0xd0, 0x18, 0x0e, 0x02, 0xc1, 0x80, + 0x9a, 0xc0, 0x2c, 0x40, 0x08, 0x38, 0x02, 0x08, + 0x00, 0xa3, 0x00, 0x24, 0x24, 0x2b, 0x00, 0x02, + 0x40, 0x01, 0x92, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x22, 0xc0, 0x00, 0xbb, 0x40, 0x20, 0x00, 0x00, + 0x04, 0x02, 0xa2, 0x00, 0xb0, 0x02, 0x2c, 0x10, + 0x08, 0x28, 0x02, 0x08, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x15, 0xad, 0x40, 0xfb, 0x02, + 0x3e, 0xe0, 0x0a, 0x94, 0x83, 0x07, 0x00, 0xfb, + 0x48, 0x38, 0xc0, 0x0c, 0xb8, 0x13, 0xee, 0x00, + 0xda, 0xd0, 0x1e, 0xc0, 0x2c, 0xbc, 0x03, 0x2c, + 0x00, 0xc3, 0x00, 0x36, 0xc0, 0x0d, 0x30, 0x02, + 0x2c, 0x02, 0xcb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xeb, 0x40, 0x22, 0xc0, 0x02, + 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x18, 0x36, 0xc0, + 0x6c, 0xb8, 0x23, 0x2a, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0xce, 0x00, 0xeb, 0x74, + 0x3e, 0xa8, 0x8f, 0x86, 0x03, 0xee, 0x00, 0xfb, + 0x60, 0x3e, 0x50, 0x0f, 0xa4, 0x03, 0xea, 0x00, + 0xda, 0x40, 0x16, 0xd0, 0x0f, 0xa0, 0x03, 0xac, + 0x00, 0xf9, 0xc0, 0x3a, 0xc0, 0x0f, 0xa4, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x23, 0xec, 0x00, 0xf9, 0xa0, 0x3e, 0xd2, 0x8d, + 0xa2, 0x01, 0x6c, 0x20, 0xfb, 0x00, 0x3e, 0x00, + 0x0f, 0xb4, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x10, 0xfc, 0x02, 0xec, 0x01, + 0x30, 0xc8, 0x0e, 0xd0, 0x03, 0xbc, 0x02, 0xce, + 0x40, 0x17, 0xed, 0x09, 0x00, 0x7e, 0x01, 0xe2, + 0x0c, 0xf0, 0x03, 0xfe, 0x80, 0xbe, 0x01, 0xb7, + 0xa0, 0x0f, 0xdc, 0x23, 0xfe, 0x02, 0x0f, 0x00, + 0x33, 0xc0, 0x2e, 0xf0, 0x03, 0x3c, 0x00, 0xcf, + 0xc0, 0xb3, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, 0x00, + 0xfc, 0x10, 0x35, 0x60, 0x0e, 0xf8, 0x03, 0xf4, + 0x00, 0xc6, 0x10, 0x01, 0xc2, 0x0c, 0x54, 0x33, + 0x00, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, + 0x00, 0x6c, 0x02, 0x80, 0x80, 0x22, 0xa0, 0xa8, + 0x88, 0x33, 0x6c, 0x00, 0xa3, 0xc2, 0x2a, 0x60, + 0x28, 0xb4, 0x82, 0xe8, 0x00, 0xba, 0xa0, 0xa2, + 0xc0, 0x1b, 0xb6, 0x02, 0x6e, 0x44, 0xab, 0xb1, + 0x22, 0xc0, 0x0c, 0xa8, 0x12, 0x2c, 0x00, 0xcb, + 0x80, 0xbe, 0xc0, 0x0b, 0xb0, 0x02, 0xe4, 0x00, + 0xb8, 0xe0, 0x22, 0x46, 0x8a, 0x89, 0x02, 0xe8, + 0x00, 0xa8, 0x0c, 0x22, 0x10, 0x08, 0x94, 0x02, + 0xa0, 0x50, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x05, 0x2e, 0x03, 0xaa, 0x60, 0xa2, 0xc2, 0x0a, + 0x9c, 0x02, 0xa4, 0x08, 0x8b, 0x00, 0x2e, 0xd8, + 0x09, 0xa2, 0x02, 0xe4, 0x01, 0xba, 0x80, 0x22, + 0xd4, 0x0b, 0xb0, 0x02, 0xcc, 0x00, 0xab, 0x00, + 0x20, 0xc0, 0x0a, 0xbc, 0x02, 0x0c, 0x08, 0x83, + 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xe4, 0x04, + 0xba, 0x00, 0x22, 0x80, 0x0a, 0x90, 0x82, 0xe8, + 0x00, 0x89, 0x00, 0x0a, 0xf0, 0x08, 0x90, 0x02, + 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x0c, 0x00, 0x88, 0x00, 0x20, 0x80, 0x28, + 0x00, 0x02, 0x48, 0x00, 0xa3, 0x00, 0x28, 0x01, + 0x09, 0x00, 0x02, 0xc0, 0x00, 0xb2, 0x00, 0x20, + 0xc0, 0x0b, 0x30, 0x06, 0xc4, 0x16, 0xab, 0x00, + 0x20, 0xc0, 0x38, 0x80, 0x00, 0x0c, 0x00, 0x81, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc0, 0x00, + 0xb0, 0x00, 0x20, 0x80, 0x08, 0xed, 0x09, 0x00, + 0x7f, 0x01, 0x00, 0x02, 0xc0, 0x00, 0xa0, 0x01, + 0xa8, 0x00, 0x08, 0x10, 0x02, 0x82, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x0c, + 0xe8, 0x02, 0x32, 0x40, 0x0e, 0x90, 0x13, 0xac, + 0x02, 0xcb, 0x00, 0x3e, 0xc0, 0x0d, 0x80, 0x03, + 0xe4, 0x00, 0xb8, 0x02, 0x32, 0xc0, 0x0b, 0xb0, + 0x02, 0xcc, 0x02, 0xeb, 0x00, 0x32, 0xc0, 0x4e, + 0xb0, 0x07, 0x0c, 0x02, 0xcb, 0x00, 0x32, 0xc0, + 0x0f, 0xb0, 0x03, 0xe8, 0x00, 0xf8, 0x00, 0x32, + 0x00, 0x9e, 0x00, 0x23, 0xe4, 0x00, 0xc8, 0x02, + 0x3a, 0x00, 0x0c, 0x90, 0x03, 0x00, 0x01, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x04, + 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0xf8, + 0x00, 0xff, 0x00, 0x1f, 0x00, 0x0e, 0xc0, 0x43, + 0xd0, 0x04, 0xfc, 0x00, 0x19, 0x80, 0x8f, 0xc0, + 0x00, 0x70, 0x00, 0xf4, 0x00, 0x3f, 0x00, 0x04, + 0xc0, 0x1b, 0xf0, 0x00, 0xec, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x7b, + 0x00, 0x1f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, + 0x37, 0x00, 0x0f, 0x50, 0x62, 0xe8, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x4d, 0xfc, 0x80, + 0xff, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x13, 0xbc, + 0x20, 0xcc, 0x00, 0x33, 0xcc, 0x0c, 0xf0, 0x03, + 0xb1, 0x00, 0x1f, 0x20, 0x3f, 0x04, 0x09, 0xf2, + 0x03, 0x70, 0x40, 0xfc, 0x02, 0x37, 0x00, 0x09, + 0xd0, 0x03, 0x78, 0x44, 0xe6, 0x00, 0x23, 0x80, + 0x0d, 0x60, 0x0b, 0x14, 0x40, 0xc6, 0x08, 0x37, + 0xc8, 0x0c, 0xf2, 0x03, 0xbc, 0x80, 0x8f, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0xbc, 0x40, + 0xbf, 0x50, 0x2e, 0x00, 0x0b, 0x00, 0x12, 0x3d, + 0x00, 0xa0, 0x00, 0x23, 0xdc, 0x08, 0xf5, 0x03, + 0xed, 0x09, 0x00, 0x80, 0x01, 0xac, 0x88, 0xbf, + 0x00, 0xa6, 0xc8, 0x0b, 0xf1, 0x0b, 0x2c, 0x00, + 0xbb, 0x20, 0x20, 0xc8, 0x0a, 0x90, 0x02, 0x28, + 0x0c, 0xe8, 0x00, 0x22, 0xc0, 0x08, 0xa0, 0x82, + 0xa4, 0x0c, 0xfa, 0x44, 0x2e, 0xd0, 0x0a, 0xf0, + 0x02, 0xed, 0xc0, 0xfb, 0x00, 0x2e, 0xc1, 0x8b, + 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xca, 0x44, 0x0c, 0xa4, 0xb3, 0x00, 0x2c, + 0x40, 0x09, 0x30, 0x02, 0x8c, 0x00, 0x80, 0x08, + 0x20, 0xc8, 0x08, 0x30, 0x42, 0x8c, 0x80, 0xb3, + 0x40, 0x20, 0xc0, 0x02, 0x30, 0x02, 0x88, 0x84, + 0xb3, 0x2c, 0x28, 0x6a, 0x00, 0x10, 0x02, 0x40, + 0x00, 0xaa, 0x02, 0x2c, 0xc0, 0x09, 0xa2, 0x02, + 0xac, 0x00, 0xa0, 0x00, 0x24, 0xc4, 0x09, 0x31, + 0x06, 0xcc, 0x20, 0x83, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x14, 0xac, 0x00, 0xbb, 0x00, 0x2e, + 0x0a, 0x1b, 0x30, 0x0a, 0x2c, 0x00, 0xa8, 0x00, + 0x20, 0xc0, 0x08, 0xb0, 0x02, 0xa8, 0x68, 0x9b, + 0x01, 0x26, 0x44, 0x4b, 0xb0, 0x02, 0x6c, 0x00, + 0xb1, 0x02, 0x2a, 0xe0, 0x09, 0x92, 0x02, 0x48, + 0x40, 0x8a, 0x00, 0x26, 0xc0, 0x0b, 0xb4, 0x02, + 0xac, 0x00, 0xba, 0x20, 0x6e, 0xc4, 0x0a, 0xb0, + 0x02, 0xec, 0x00, 0x3b, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x84, 0xac, 0x00, 0xfb, 0x00, 0x3e, + 0x20, 0x05, 0x90, 0x83, 0xac, 0x00, 0xc9, 0x00, + 0x22, 0xc0, 0x0c, 0xb0, 0x03, 0xae, 0x00, 0xdb, + 0x00, 0x3a, 0xf2, 0x0e, 0xb0, 0x03, 0x2d, 0x08, + 0x7b, 0xc0, 0x3a, 0xe0, 0x0c, 0x10, 0x03, 0x69, + 0x00, 0xeb, 0x34, 0x3c, 0x48, 0x0d, 0x84, 0x03, + 0x08, 0x80, 0xea, 0x80, 0x36, 0x60, 0x04, 0xb0, + 0x07, 0xac, 0x00, 0xed, 0x09, 0x00, 0x81, 0x01, + 0x8b, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x02, 0xd0, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, + 0xbc, 0x04, 0xff, 0x00, 0x3f, 0x00, 0x0f, 0xf0, + 0x83, 0xdc, 0x00, 0xfc, 0x04, 0x3f, 0xc0, 0x0f, + 0xb0, 0x13, 0xf6, 0x00, 0xff, 0x02, 0x3b, 0xe0, + 0x8f, 0xf0, 0x03, 0x3e, 0x40, 0xff, 0x94, 0xb3, + 0xc0, 0x0e, 0xd8, 0x43, 0xba, 0x00, 0xed, 0x08, + 0x33, 0xc0, 0x0c, 0xf4, 0x03, 0x7c, 0x00, 0xff, + 0x81, 0x3d, 0x40, 0x0f, 0xf0, 0x03, 0xdc, 0x00, + 0xaf, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, + 0xac, 0x00, 0xeb, 0x20, 0x32, 0x42, 0x0c, 0xb4, + 0x03, 0x2c, 0x02, 0xca, 0x00, 0x3a, 0xc0, 0x1e, + 0xb0, 0x07, 0x2d, 0x02, 0xcb, 0x00, 0x3e, 0xc0, + 0x0d, 0x31, 0x02, 0x6d, 0x00, 0xcb, 0x40, 0x7e, + 0xc0, 0x2a, 0x90, 0x83, 0xe9, 0x00, 0xdb, 0x40, + 0x36, 0x50, 0x0c, 0xa0, 0x03, 0x2d, 0x00, 0xf9, + 0x04, 0x1a, 0xc0, 0x0e, 0xb0, 0x41, 0x6c, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x1f, 0xb0, 0x03, 0xd0, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x04, + 0x3c, 0x00, 0x8f, 0x80, 0x22, 0x08, 0x00, 0x94, + 0x02, 0x3e, 0x00, 0x8a, 0x00, 0x2b, 0xc0, 0x0c, + 0xf0, 0x02, 0x2c, 0x08, 0x87, 0x20, 0x2e, 0xc0, + 0x0b, 0xf8, 0x00, 0xec, 0x00, 0x5b, 0x01, 0x3e, + 0xc0, 0x09, 0x90, 0xc2, 0x68, 0x04, 0x83, 0x00, + 0x36, 0xe2, 0x0d, 0x30, 0x43, 0x6c, 0x00, 0xab, + 0x00, 0x22, 0xd0, 0x08, 0xff, 0x02, 0x7c, 0x00, + 0x9b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xf2, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x04, + 0x0c, 0x00, 0xa3, 0x54, 0x20, 0xb0, 0x0b, 0x05, + 0x2a, 0x4e, 0x40, 0xa8, 0x00, 0x20, 0xc0, 0x09, + 0x30, 0x02, 0x0c, 0x00, 0xa3, 0x80, 0xed, 0x09, + 0x00, 0x82, 0x01, 0x2c, 0xc0, 0x0b, 0x38, 0x02, + 0xcc, 0x00, 0xa3, 0x00, 0x2e, 0xc0, 0x09, 0x14, + 0x02, 0xc8, 0x00, 0x93, 0x40, 0x20, 0xd2, 0x8b, + 0x20, 0x02, 0x84, 0x00, 0x90, 0x48, 0x2c, 0x62, + 0x0a, 0x30, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0a, 0x30, 0x02, 0x78, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xd8, 0x00, 0x0c, 0x02, 0x83, + 0x80, 0x23, 0xa0, 0x29, 0x48, 0x02, 0x4e, 0x08, + 0x84, 0x80, 0x29, 0xe0, 0x0a, 0x78, 0x02, 0x1e, + 0x48, 0x07, 0xc2, 0x2d, 0xe0, 0x1b, 0x78, 0x02, + 0xde, 0x00, 0x87, 0x91, 0x29, 0xe0, 0x09, 0x58, + 0x20, 0x7a, 0x08, 0x8f, 0x93, 0x25, 0xe1, 0x09, + 0xe8, 0x82, 0xf6, 0x01, 0xa7, 0x80, 0x25, 0x60, + 0x0a, 0x78, 0x02, 0x5e, 0x00, 0x97, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x0c, 0x40, 0xa3, + 0x00, 0x30, 0x04, 0x0f, 0x20, 0x03, 0x4c, 0x00, + 0xc0, 0x00, 0x32, 0xc8, 0x0b, 0x30, 0x02, 0x24, + 0x40, 0xe3, 0x00, 0x3c, 0xc0, 0x0f, 0x31, 0x02, + 0xec, 0x80, 0x83, 0x10, 0x2c, 0xc4, 0x0e, 0x30, + 0x03, 0xc8, 0x00, 0x53, 0x00, 0x34, 0xc8, 0x0f, + 0x30, 0x03, 0x8c, 0x00, 0xf1, 0x04, 0x3c, 0xc3, + 0x0e, 0x30, 0x03, 0x4c, 0x00, 0xf3, 0x00, 0x3c, + 0xc0, 0x0e, 0x30, 0x03, 0xd2, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x14, 0xbd, 0x90, 0xff, + 0x40, 0x9d, 0x40, 0x0c, 0xe1, 0x03, 0xbd, 0x00, + 0xfc, 0x00, 0x17, 0xc2, 0x0d, 0xf1, 0x8b, 0xfc, + 0x40, 0xbf, 0x50, 0x3f, 0xc0, 0x0f, 0xf0, 0x01, + 0xfc, 0x00, 0xdf, 0x10, 0x3f, 0xc0, 0x0e, 0xf0, + 0x03, 0x58, 0x00, 0xdf, 0x01, 0x3d, 0xc0, 0x0f, + 0xf0, 0x03, 0x7c, 0x00, 0xdf, 0x00, 0x39, 0xc0, + 0x0d, 0xf4, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0xed, 0x09, 0x00, 0x83, 0x01, 0x0f, 0xf0, + 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0xac, 0x40, 0xfb, 0xb0, 0x32, 0x80, + 0x0f, 0x08, 0x03, 0x2c, 0x80, 0xf9, 0x00, 0x1e, + 0xd2, 0x0d, 0xb4, 0x83, 0xc8, 0x00, 0xab, 0x51, + 0x3e, 0x40, 0x07, 0xb7, 0x03, 0x8e, 0x00, 0xf9, + 0x80, 0x32, 0xc0, 0x0b, 0x90, 0x03, 0xe8, 0x00, + 0x73, 0x00, 0x32, 0x41, 0x0f, 0xb8, 0x01, 0x2c, + 0x00, 0xd8, 0x00, 0x3e, 0x40, 0x0f, 0xb6, 0x03, + 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0e, 0xb0, + 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x98, 0x9c, 0x00, 0xb7, 0x00, 0x21, 0x80, + 0x0b, 0x60, 0x02, 0x9c, 0x80, 0xb4, 0x00, 0x2d, + 0xc8, 0x0b, 0x70, 0x03, 0x9c, 0x00, 0xd7, 0x20, + 0x2d, 0xc0, 0x0b, 0x70, 0x82, 0xdc, 0x00, 0xaf, + 0x00, 0x29, 0xc0, 0x83, 0x50, 0x03, 0x9c, 0x00, + 0xd7, 0x00, 0x2d, 0xc0, 0x0f, 0xf0, 0x02, 0x9c, + 0x00, 0xd7, 0x00, 0x25, 0x40, 0x0b, 0x76, 0x02, + 0xdd, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x9e, 0x80, 0xb3, 0x80, 0x21, 0x20, + 0x0b, 0xf8, 0x02, 0x5e, 0x40, 0xb6, 0x80, 0x2d, + 0xe0, 0x0b, 0x7a, 0x02, 0xbe, 0x00, 0x87, 0x80, + 0x2d, 0xe0, 0x0b, 0x7a, 0x02, 0xfe, 0x00, 0x87, + 0x80, 0x21, 0xe0, 0x09, 0x78, 0x22, 0x5e, 0x00, + 0xb7, 0x80, 0x25, 0x60, 0x59, 0x78, 0x02, 0x3e, + 0x00, 0x85, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0x9e, 0x80, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, + 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x04, 0xac, 0x00, 0xb3, 0x00, 0xa0, 0x40, + 0x0b, 0x11, 0x02, 0xcc, 0x00, 0xb2, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0x83, 0x20, 0x93, 0x00, + 0x2c, 0x60, 0x0b, 0x30, 0xed, 0x09, 0x00, 0x84, + 0x01, 0x02, 0x4e, 0x40, 0xa1, 0x80, 0x20, 0xc0, + 0x9b, 0x30, 0x02, 0x2c, 0x10, 0x83, 0x00, 0x2c, + 0xe0, 0x4a, 0x34, 0x02, 0xac, 0x00, 0xb3, 0x00, + 0x6c, 0xe0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xd2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x04, 0xa8, + 0x00, 0xfa, 0x00, 0x31, 0x80, 0x0f, 0xec, 0x03, + 0x68, 0x00, 0xfe, 0x19, 0x3e, 0x80, 0x0d, 0xa0, + 0x23, 0xbb, 0x80, 0xca, 0x00, 0x3f, 0xb8, 0x0f, + 0xa0, 0x43, 0xfb, 0x00, 0xce, 0xc8, 0xb3, 0xa2, + 0x0d, 0xa0, 0x02, 0x7b, 0x00, 0xb6, 0x40, 0x37, + 0xb2, 0x0b, 0xe6, 0x02, 0x3b, 0xc0, 0x4e, 0x40, + 0x3e, 0x88, 0x0f, 0xa0, 0x17, 0xa8, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x1f, 0xa0, 0x03, 0xfa, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x40, 0xa0, + 0x00, 0xf8, 0x04, 0x3e, 0x00, 0x0b, 0x88, 0x03, + 0xa0, 0x00, 0xf8, 0x00, 0x2e, 0x00, 0x0d, 0x80, + 0x03, 0xa0, 0x00, 0xf8, 0x01, 0x3e, 0x20, 0x0f, + 0x84, 0x02, 0xe2, 0x00, 0xe8, 0x80, 0x3e, 0x08, + 0x0f, 0x80, 0x03, 0xe2, 0x40, 0xd8, 0xc0, 0x3a, + 0x20, 0x4f, 0x80, 0x83, 0xe0, 0x00, 0xd8, 0x00, + 0x36, 0x10, 0x0f, 0x00, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xd2, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xa4, + 0x00, 0xc9, 0x00, 0x3e, 0x50, 0x0e, 0x98, 0x03, + 0xc4, 0x00, 0xc9, 0x00, 0x34, 0x41, 0x4c, 0x90, + 0x03, 0xe4, 0x04, 0xe9, 0xc0, 0x3a, 0x40, 0x0e, + 0x90, 0x03, 0xe4, 0x10, 0xe9, 0x00, 0x7c, 0x40, + 0x0f, 0x12, 0x01, 0xa4, 0x00, 0xc9, 0x90, 0x3e, + 0x60, 0x8f, 0x91, 0x03, 0xe4, 0x00, 0xf9, 0x88, + 0x34, 0x68, 0x2c, 0x90, 0x03, 0x24, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc2, 0xed, + 0x09, 0x00, 0x85, 0x01, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x24, 0x00, 0x89, 0xd0, + 0x2e, 0x40, 0x18, 0x94, 0x03, 0xe4, 0x10, 0x89, + 0x00, 0x2e, 0x40, 0x2d, 0x90, 0x02, 0xe4, 0x00, + 0xd1, 0xa0, 0xbe, 0x40, 0x08, 0x91, 0x02, 0xe4, + 0x08, 0xb9, 0x00, 0x2e, 0x40, 0x08, 0x90, 0x03, + 0xa4, 0x00, 0xa9, 0xa0, 0x22, 0x54, 0x0b, 0x90, + 0x03, 0xa4, 0x00, 0xa9, 0xc0, 0x3a, 0x40, 0x88, + 0x94, 0x0a, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x04, 0xa4, 0x00, 0xb9, 0x08, + 0x2e, 0x40, 0x0b, 0x91, 0x02, 0xe4, 0x02, 0x89, + 0x00, 0x2e, 0x40, 0x00, 0x90, 0x02, 0xc4, 0x00, + 0x89, 0x00, 0x20, 0x40, 0x08, 0x90, 0x02, 0x6c, + 0x00, 0xab, 0x00, 0x26, 0x40, 0x09, 0x90, 0x82, + 0x2c, 0x03, 0x89, 0x00, 0x26, 0x40, 0x0b, 0x90, + 0x02, 0xe4, 0x02, 0xab, 0x60, 0x26, 0x40, 0x48, + 0x9c, 0x42, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x14, 0x05, 0xa0, 0x91, 0x00, + 0x2e, 0x40, 0x09, 0x1c, 0x06, 0x84, 0x00, 0x81, + 0x40, 0x2c, 0x50, 0x49, 0x10, 0x02, 0xc5, 0x00, + 0x91, 0x00, 0x28, 0x50, 0x08, 0x30, 0x02, 0xc5, + 0x00, 0x91, 0x40, 0x2c, 0x50, 0x09, 0x10, 0x02, + 0xc5, 0x01, 0x81, 0x00, 0x20, 0x61, 0x19, 0x14, + 0x02, 0xc5, 0x04, 0x01, 0x00, 0x28, 0x40, 0x08, + 0x10, 0x22, 0x05, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd8, 0x08, 0x60, 0x80, 0xb8, 0x00, + 0x3e, 0x80, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xc8, + 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x02, + 0xe8, 0x00, 0x22, 0x00, 0x2c, 0x80, 0x03, 0xe0, + 0x00, 0xe8, 0xed, 0x09, 0x00, 0x86, 0x01, 0x02, + 0x2e, 0x00, 0x05, 0x80, 0x02, 0x20, 0x00, 0xc8, + 0x00, 0x36, 0x01, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x16, 0x80, 0x0c, 0x80, 0x43, 0x20, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x95, 0xa4, 0x02, 0x69, 0x40, 0x3f, 0x40, 0x0e, + 0xd0, 0x03, 0xe5, 0x10, 0xff, 0x00, 0x1e, 0x50, + 0x0f, 0x94, 0x37, 0xf4, 0x00, 0xe9, 0x40, 0x37, + 0x40, 0x0b, 0x94, 0x03, 0xf4, 0x00, 0x7d, 0x00, + 0x1f, 0xd0, 0x0e, 0xd4, 0x03, 0xbc, 0x10, 0xfd, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x94, 0x12, + 0xfd, 0x40, 0x3b, 0x50, 0x0f, 0x94, 0x03, 0xe5, + 0x10, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe7, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x15, 0xe4, 0x00, 0xed, 0x20, 0x3f, 0x41, 0x0c, + 0xd0, 0x53, 0xf4, 0x00, 0xf1, 0x00, 0x3a, 0x4a, + 0x0c, 0x92, 0x03, 0x24, 0x00, 0x7d, 0x00, 0x32, + 0x44, 0x0f, 0xd2, 0x02, 0xe4, 0x00, 0xe9, 0x14, + 0x3e, 0x40, 0x0b, 0xd0, 0x03, 0xe4, 0x40, 0xbd, + 0x00, 0xb3, 0x40, 0x0f, 0xd1, 0x03, 0xe4, 0x00, + 0xcd, 0x04, 0x37, 0x41, 0x0f, 0x52, 0x03, 0x24, + 0xa0, 0xc9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x19, + 0x00, 0xe0, 0x80, 0x88, 0x11, 0x2e, 0x00, 0x0d, + 0x80, 0x82, 0xe0, 0x40, 0xb8, 0x28, 0x06, 0x08, + 0x08, 0x81, 0x02, 0x20, 0x20, 0xb8, 0x00, 0x62, + 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x84, 0x88, 0x20, + 0x2e, 0x12, 0x0f, 0x80, 0x02, 0xe0, 0x00, 0xb8, + 0x00, 0x32, 0x00, 0x0b, 0x82, 0x42, 0x20, 0x20, + 0xc8, 0x00, 0x2a, 0x04, 0x4b, 0x80, 0x0a, 0x20, + 0x80, 0x88, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, + 0xce, 0x04, 0x30, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x87, 0x01, 0x00, 0x00, 0x68, 0x00, 0x84, 0xe0, + 0xa1, 0x00, 0x2e, 0x40, 0x02, 0x10, 0x02, 0xc4, + 0x00, 0xb1, 0x20, 0x2c, 0x4a, 0x08, 0x10, 0x02, + 0x04, 0x80, 0xb1, 0x10, 0x20, 0x40, 0x0b, 0x11, + 0x02, 0xc4, 0xa2, 0x91, 0x20, 0x2c, 0x4c, 0x0b, + 0x11, 0x02, 0xc4, 0x00, 0xb9, 0x00, 0x20, 0x40, + 0x0b, 0x12, 0x02, 0x44, 0x80, 0x81, 0x90, 0x64, + 0x40, 0x0b, 0x11, 0x06, 0x44, 0xa2, 0x81, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xb8, 0x14, 0xa4, 0x10, + 0x89, 0x00, 0x2e, 0x50, 0x0b, 0x90, 0x80, 0xe4, + 0x00, 0xb9, 0x00, 0x26, 0x40, 0x48, 0x90, 0x0a, + 0x24, 0x00, 0x9b, 0x00, 0x22, 0x40, 0x0b, 0x90, + 0x02, 0xc4, 0x00, 0x89, 0x08, 0x2e, 0x40, 0x08, + 0x90, 0x02, 0x64, 0x40, 0xb9, 0x00, 0x22, 0x40, + 0x4b, 0x90, 0x02, 0x47, 0x00, 0xa9, 0x20, 0x2e, + 0x41, 0x0b, 0x90, 0x02, 0x64, 0x00, 0x89, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x90, 0xa4, 0x00, + 0xe9, 0x00, 0x1c, 0x60, 0x0e, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x10, 0x3a, 0x40, 0x2c, 0x90, 0x02, + 0x25, 0x60, 0xf9, 0x00, 0x22, 0x62, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xd9, 0xc0, 0x3e, 0x50, 0x0b, + 0x99, 0x02, 0xe6, 0x00, 0xf9, 0x81, 0x32, 0x50, + 0x4f, 0x98, 0x23, 0x65, 0x02, 0xc9, 0x40, 0xb6, + 0x40, 0x0f, 0x90, 0x02, 0x64, 0x00, 0xc9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe0, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, + 0xf9, 0x04, 0x3e, 0x44, 0x0d, 0x91, 0x13, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe6, 0x00, 0xf9, 0x00, 0xae, 0x45, 0x0f, 0x90, + 0x03, 0x66, 0x48, 0xd9, 0x20, 0x3e, 0x40, 0x0f, + 0xed, 0x09, 0x00, 0x88, 0x01, 0x98, 0x03, 0xe6, + 0x00, 0xd9, 0x48, 0x32, 0x40, 0x0f, 0x9a, 0x03, + 0x24, 0x10, 0xc1, 0x00, 0x3a, 0x50, 0x0f, 0x10, + 0x83, 0x84, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x10, 0xa0, 0x00, 0xe8, 0x81, 0x3e, + 0x34, 0x07, 0x84, 0x03, 0xe0, 0x00, 0xc8, 0x40, + 0x38, 0x01, 0x0f, 0x00, 0x03, 0xe0, 0x00, 0xf0, + 0x08, 0x3e, 0x10, 0x0c, 0x88, 0x02, 0xa0, 0x00, + 0xf8, 0x44, 0x3e, 0x10, 0x07, 0x88, 0x43, 0xe0, + 0x18, 0xf8, 0x11, 0x32, 0x1c, 0x2f, 0x84, 0x13, + 0xe0, 0x08, 0xf8, 0x80, 0x16, 0x00, 0x0f, 0x81, + 0x03, 0x60, 0x00, 0xe8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x28, 0x00, 0x8e, 0x42, 0x2f, + 0xb0, 0x09, 0xed, 0x01, 0xe8, 0x80, 0x8a, 0x00, + 0x22, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xee, + 0x80, 0x3e, 0x80, 0x08, 0xe4, 0x03, 0x68, 0x00, + 0xba, 0x00, 0x26, 0x80, 0x0b, 0xe4, 0x03, 0xa8, + 0x08, 0xb6, 0x40, 0x3b, 0xb0, 0x08, 0xa0, 0x02, + 0xe8, 0x04, 0xee, 0xe0, 0x2b, 0xb4, 0x0b, 0xe8, + 0x03, 0x68, 0x00, 0x8a, 0x00, 0x2e, 0x80, 0x0b, + 0xa0, 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x0c, 0x00, 0xa1, 0x80, 0x2c, + 0x40, 0x83, 0x34, 0x02, 0xc4, 0x0c, 0x83, 0x00, + 0x08, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xa0, + 0x00, 0x24, 0xc0, 0x29, 0x18, 0x02, 0x0c, 0x00, + 0x33, 0x00, 0x24, 0xc0, 0x1b, 0x38, 0x00, 0xcc, + 0x00, 0xb3, 0xc0, 0xac, 0xc0, 0x0b, 0xb0, 0x42, + 0xcc, 0x00, 0xa3, 0x00, 0x20, 0xd4, 0x0b, 0x2c, + 0x02, 0x0c, 0x00, 0xa3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0xed, 0x09, 0x00, 0x89, 0x01, + 0x1c, 0x80, 0x87, 0x0a, 0x2d, 0xc0, 0x0b, 0x74, + 0x02, 0x96, 0x00, 0x8f, 0x80, 0x21, 0xc0, 0x09, + 0x70, 0x02, 0xdc, 0x01, 0xa7, 0x0a, 0x29, 0xe0, + 0x09, 0x3c, 0x02, 0x5c, 0x80, 0xb7, 0x10, 0x25, + 0xc0, 0x0b, 0x70, 0x82, 0xdc, 0x80, 0xbf, 0x00, + 0x23, 0xe0, 0x28, 0x50, 0x12, 0xfc, 0x80, 0xaf, + 0x00, 0x69, 0xc0, 0x0b, 0x70, 0x02, 0x5c, 0xc8, + 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xe8, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x98, + 0x0e, 0x00, 0xe5, 0x80, 0x3d, 0x60, 0x0b, 0x78, + 0x12, 0xc6, 0x02, 0xc7, 0xe8, 0x29, 0xfa, 0x07, + 0x78, 0x03, 0xdf, 0x80, 0xe7, 0x82, 0x2f, 0xe8, + 0x0d, 0x58, 0x0a, 0x9f, 0x20, 0xf7, 0xa8, 0x3d, + 0xe4, 0x0b, 0x78, 0x03, 0xde, 0x80, 0xf7, 0x81, + 0x25, 0xe0, 0x0f, 0x78, 0x03, 0xdf, 0xa0, 0xe7, + 0x81, 0x31, 0xe0, 0x0f, 0x78, 0x03, 0x3e, 0x00, + 0xe7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xea, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x1d, + 0xac, 0x28, 0xf9, 0x04, 0x3e, 0x40, 0x05, 0xa0, + 0x03, 0xe4, 0x00, 0xfb, 0x40, 0x36, 0xd0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0x6a, 0x00, 0x3e, 0xd1, + 0x0e, 0x90, 0x03, 0xad, 0x08, 0x7b, 0x40, 0x36, + 0xc0, 0x0b, 0xb0, 0x03, 0xad, 0x40, 0xf3, 0x00, + 0x3c, 0xc0, 0x0f, 0x90, 0x03, 0xcd, 0x00, 0xc3, + 0x00, 0xb2, 0x40, 0x0f, 0x90, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x42, + 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0d, + 0xbe, 0x20, 0xae, 0x94, 0x3f, 0x21, 0x0c, 0xf8, + 0x03, 0xd6, 0x00, 0xcf, 0x80, 0x1f, 0xe0, 0x0d, + 0xf8, 0x47, 0xfd, 0x40, 0xef, 0x90, 0x3f, 0xf2, + 0x07, 0xc8, 0x41, 0xbe, 0x40, 0xff, 0x90, 0x3f, + 0xe2, 0x0f, 0xf8, 0x03, 0xff, 0x00, 0xed, 0x09, + 0x00, 0x8a, 0x01, 0xdf, 0x80, 0x3f, 0xe0, 0x0f, + 0xf8, 0x03, 0xfe, 0x08, 0xcf, 0x80, 0x37, 0xe0, + 0x0f, 0xf8, 0x03, 0x7e, 0x00, 0xff, 0x84, 0x3f, + 0xe0, 0x0f, 0xf8, 0x03, 0xc0, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xa9, 0x00, 0x9c, 0x00, 0x84, + 0x10, 0x2d, 0x00, 0x0f, 0x64, 0x02, 0xd4, 0x00, + 0x87, 0x10, 0x25, 0xc0, 0x08, 0x70, 0x06, 0xdc, + 0x00, 0x87, 0x10, 0x2d, 0xc2, 0x0b, 0x60, 0x0b, + 0x5c, 0x40, 0x97, 0x08, 0x2d, 0xc4, 0x0b, 0x70, + 0x02, 0xdc, 0x20, 0x97, 0x00, 0x2d, 0xc0, 0x0b, + 0x50, 0x02, 0xdc, 0x00, 0xa7, 0x0a, 0x2d, 0x84, + 0x03, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0x00, 0x9c, 0x00, 0xb4, + 0x10, 0x2f, 0x00, 0x08, 0x70, 0x02, 0xd4, 0x00, + 0x87, 0x00, 0x24, 0xc0, 0x08, 0x70, 0x02, 0xfc, + 0x40, 0xa5, 0x10, 0x65, 0xc0, 0x0b, 0x50, 0x02, + 0x1c, 0x10, 0xb7, 0x00, 0x2d, 0xd0, 0x09, 0x70, + 0x02, 0x5c, 0x00, 0xb7, 0x08, 0x2d, 0xc0, 0x0a, + 0x70, 0x02, 0xdc, 0x00, 0xa6, 0x10, 0x2d, 0xc0, + 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0x40, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x42, 0x04, 0x8c, 0x00, 0x90, + 0x00, 0x2c, 0x53, 0x0b, 0xb0, 0x02, 0xc4, 0x00, + 0x83, 0x00, 0x24, 0xc0, 0x09, 0x30, 0x02, 0xcd, + 0x00, 0x83, 0x00, 0x4c, 0xe0, 0x0b, 0x10, 0x02, + 0x8f, 0x40, 0xb3, 0x80, 0x2c, 0xe0, 0x0b, 0x30, + 0x12, 0xcd, 0x80, 0xb3, 0x84, 0x6c, 0xd0, 0x0b, + 0x10, 0x02, 0xcc, 0x00, 0xa2, 0x21, 0x2c, 0x00, + 0x0b, 0x10, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x82, 0x05, 0xbc, 0x00, 0xf9, + 0x00, 0xed, 0x09, 0x00, 0x8b, 0x01, 0x3e, 0xc1, + 0x0c, 0xb2, 0x03, 0xc4, 0x02, 0xc7, 0x40, 0x37, + 0xc0, 0x0d, 0xb0, 0x02, 0xfd, 0x00, 0x6b, 0x05, + 0x75, 0xf4, 0x4b, 0xa0, 0x02, 0x3c, 0x00, 0xb7, + 0x00, 0x3f, 0xe9, 0x0d, 0xb0, 0x06, 0x7d, 0x00, + 0xdb, 0x82, 0x3c, 0xf8, 0x0e, 0xbc, 0x92, 0xfc, + 0x08, 0xc3, 0x80, 0x36, 0xc0, 0x0f, 0x30, 0x03, + 0x7c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0xac, 0x00, 0xe9, 0x40, 0x3e, 0x40, + 0x0d, 0x84, 0x23, 0xec, 0x00, 0xfb, 0x20, 0x36, + 0xc0, 0x0e, 0xb0, 0x23, 0xec, 0x40, 0xf9, 0x42, + 0x3e, 0xc0, 0x0f, 0xa0, 0x02, 0x6c, 0x00, 0xdb, + 0x09, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xdb, 0x40, 0x3e, 0xc2, 0x0f, 0x90, 0x03, 0x6c, + 0x92, 0xda, 0x00, 0x2e, 0xc0, 0x0f, 0xa0, 0x03, + 0xec, 0x00, 0xbb, 0x00, 0x36, 0xc0, 0x0f, 0xb0, + 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x00, 0xac, 0x00, 0x8d, 0x80, 0x33, 0x45, + 0x0e, 0xd1, 0x02, 0x74, 0x40, 0xcf, 0x00, 0x33, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x20, 0xf7, 0x01, + 0x37, 0xc0, 0x0c, 0xda, 0x03, 0xfc, 0x21, 0xff, + 0x00, 0x73, 0xc0, 0x05, 0xf2, 0x03, 0xfc, 0x00, + 0xff, 0x80, 0x33, 0xc0, 0x0d, 0xf2, 0x81, 0xbc, + 0x04, 0xcf, 0x02, 0x3b, 0x80, 0x2c, 0xf8, 0x03, + 0xbc, 0x00, 0xff, 0x01, 0x3f, 0xc1, 0x0d, 0xf0, + 0x03, 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x90, 0x2c, 0x00, 0x81, 0xd8, 0x28, 0x40, + 0x0a, 0xbc, 0x03, 0x2c, 0x00, 0x8b, 0x00, 0x2a, + 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00, 0x9b, 0xc0, + 0x22, 0xc0, 0x0a, 0xb0, 0x22, 0x6c, 0x00, 0xcb, + 0x00, 0x22, 0xc0, 0x0b, 0xb4, 0x02, 0xec, 0x00, + 0xb3, 0x18, 0x36, 0x11, 0xed, 0x09, 0x00, 0x8c, + 0x01, 0x8f, 0x38, 0x03, 0x4c, 0x00, 0x8a, 0x4a, + 0x20, 0x24, 0x08, 0x99, 0x02, 0x2c, 0x10, 0x9b, + 0x00, 0x0e, 0xc0, 0x4b, 0xb0, 0x02, 0xe0, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x0c, + 0x01, 0x88, 0x01, 0x22, 0x00, 0x08, 0x90, 0x02, + 0x6c, 0x00, 0x8b, 0x00, 0x22, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x10, 0xba, 0x20, 0x22, 0xc0, 0x48, + 0x80, 0x12, 0xec, 0x00, 0xbb, 0x00, 0x22, 0xc0, + 0x0b, 0xb4, 0x02, 0xec, 0x00, 0x9b, 0x00, 0x2a, + 0xe2, 0x08, 0xb0, 0x00, 0x2c, 0x00, 0x99, 0x80, + 0x22, 0x50, 0x4a, 0x90, 0x82, 0xac, 0x00, 0xbb, + 0x00, 0x26, 0xc0, 0x09, 0xb0, 0x02, 0xe0, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x0c, + 0x00, 0xa1, 0x00, 0x28, 0x60, 0x0a, 0x30, 0x02, + 0x04, 0x00, 0x8b, 0x00, 0x28, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0x93, 0x00, 0x62, 0xc0, 0x08, + 0x28, 0x02, 0x4c, 0x10, 0x8b, 0x00, 0x20, 0xc0, + 0x09, 0x30, 0x02, 0x4c, 0x14, 0x93, 0x00, 0x24, + 0xc0, 0x8b, 0x90, 0x42, 0x6c, 0x00, 0x90, 0x00, + 0x20, 0x00, 0x0a, 0x10, 0x02, 0x0c, 0x00, 0x93, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc2, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x7c, + 0x00, 0xc9, 0x00, 0x32, 0x00, 0x0e, 0xb0, 0x03, + 0x6c, 0x02, 0xcf, 0x00, 0x33, 0xc0, 0x0b, 0xb0, + 0x03, 0xfc, 0x00, 0xfb, 0x00, 0x37, 0xc0, 0x0c, + 0x80, 0x02, 0xfc, 0x01, 0xbf, 0x00, 0xa3, 0xc0, + 0x0d, 0xb0, 0x03, 0xfc, 0x00, 0xd9, 0x00, 0x3a, + 0xc0, 0x0c, 0xb0, 0x13, 0x1c, 0x02, 0x5a, 0x00, + 0x1a, 0x00, 0x0c, 0x90, 0x03, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0d, 0xb0, 0x07, 0xc0, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x95, 0xbc, + 0x02, 0xdc, 0x00, 0x3d, 0x00, 0x0b, 0xc0, 0xed, + 0x09, 0x00, 0x8d, 0x01, 0x4b, 0xb4, 0x00, 0xff, + 0x04, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xdc, 0x04, + 0xbc, 0x00, 0x3f, 0xc0, 0x1f, 0x40, 0x03, 0xfc, + 0x00, 0xef, 0x00, 0x37, 0xc0, 0x0f, 0xc0, 0x23, + 0xfc, 0x04, 0xfc, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x07, 0x7c, 0x00, 0xee, 0x01, 0x3f, 0x00, 0x05, + 0xc0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xe8, 0x02, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x05, 0xf0, 0x00, 0xde, 0x00, + 0x37, 0x04, 0x0c, 0xc1, 0x83, 0x70, 0x00, 0xcf, + 0x60, 0xbf, 0xc8, 0x2e, 0xf0, 0x03, 0x14, 0x08, + 0xfe, 0x00, 0x3f, 0x40, 0x0f, 0xc0, 0x03, 0xf0, + 0x00, 0xb4, 0x00, 0x3f, 0x00, 0x0b, 0xe0, 0x03, + 0xf0, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf1, + 0x03, 0xf0, 0x20, 0xcc, 0x00, 0x33, 0x10, 0x8c, + 0xc0, 0x83, 0x30, 0x40, 0xcc, 0x20, 0xb7, 0x18, + 0x0c, 0xc3, 0x03, 0xf0, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x10, 0xe0, 0x00, 0xb9, 0x00, + 0x2c, 0x80, 0x88, 0xa6, 0x02, 0xa1, 0x00, 0xaf, + 0x30, 0x23, 0xd4, 0x08, 0xb0, 0x02, 0x2c, 0x00, + 0xba, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe4, + 0x00, 0xb8, 0x00, 0x2e, 0xc0, 0x8b, 0xb0, 0x02, + 0xec, 0x10, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb2, + 0x03, 0x81, 0x20, 0x81, 0x68, 0x20, 0x01, 0x08, + 0x86, 0xc2, 0x2d, 0x40, 0x8b, 0x72, 0x22, 0x04, + 0x08, 0x01, 0x02, 0xf0, 0x02, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x88, 0x05, 0xc8, 0x00, 0xb1, 0x02, + 0x24, 0x00, 0x08, 0x00, 0x02, 0x41, 0x00, 0x83, + 0x00, 0x2c, 0xc0, 0x2a, 0x30, 0x52, 0x0c, 0x00, + 0xb0, 0x00, 0x2c, 0x80, 0x0b, 0x00, 0x02, 0xc4, + 0x01, 0x90, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x12, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xc4, 0xed, 0x09, 0x00, 0x8e, 0x01, 0x80, + 0x90, 0x40, 0x20, 0x50, 0x49, 0x00, 0x06, 0x00, + 0x80, 0x80, 0x09, 0x60, 0x08, 0xa8, 0x02, 0x02, + 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x15, 0xa9, 0x00, 0xba, 0x40, 0x2e, 0x00, 0x08, + 0x81, 0x08, 0xa2, 0x00, 0xab, 0x00, 0x22, 0xc0, + 0x28, 0xa0, 0x02, 0x2c, 0x30, 0x3b, 0x00, 0x2e, + 0xc0, 0x0b, 0xb8, 0x82, 0xe0, 0x60, 0xb8, 0x54, + 0x2e, 0xd0, 0x0b, 0xb2, 0x00, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x12, 0xac, 0x01, + 0x99, 0x00, 0x22, 0xc6, 0x09, 0xa0, 0x06, 0x28, + 0x00, 0x8b, 0x00, 0x60, 0x48, 0x08, 0xa1, 0x02, + 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x15, 0xe1, 0x40, 0xdb, 0x40, 0x36, 0xc0, 0x4c, + 0xac, 0x21, 0x67, 0x20, 0x4b, 0x00, 0x3e, 0xc0, + 0x4e, 0xb4, 0x03, 0x24, 0x40, 0xba, 0x80, 0x1e, + 0xc8, 0x0f, 0xb4, 0x03, 0xe4, 0x00, 0xf8, 0x42, + 0x3e, 0xc0, 0x0b, 0xb4, 0x01, 0xe9, 0x80, 0xfb, + 0x04, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xe1, 0x80, + 0xd8, 0x64, 0x32, 0x10, 0x0d, 0x89, 0x03, 0x20, + 0x00, 0xc8, 0xa0, 0x36, 0x28, 0x0c, 0x8a, 0x03, + 0xd1, 0x40, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x01, 0xb4, 0x00, 0xfc, 0x00, 0x3f, 0xe8, 0x2f, + 0x60, 0x4b, 0xc4, 0x30, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf4, 0x00, 0xfc, 0x00, 0xff, 0xc0, 0x3f, + 0xc4, 0x0f, 0xf0, 0x01, 0xf4, 0x00, 0xfe, 0x80, + 0x3f, 0xe4, 0x0f, 0xf8, 0x43, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x43, 0xb2, 0x40, + 0xed, 0xa4, 0x3f, 0x00, 0x4e, 0xd0, 0x3b, 0xee, + 0x42, 0xf8, 0x94, 0x3f, 0xe1, 0x4f, 0xf0, 0x03, + 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x10, 0xa9, 0x00, 0xc8, 0x50, 0x3e, 0x50, 0x0e, + 0xa4, 0x33, 0xe6, 0x00, 0xeb, 0xed, 0x09, 0x00, + 0x8f, 0x01, 0x00, 0x3c, 0xc8, 0x0c, 0xb4, 0x03, + 0xed, 0x00, 0xca, 0x80, 0x36, 0xd2, 0x0f, 0xb0, + 0x03, 0xe5, 0x00, 0xca, 0x00, 0x3a, 0xd0, 0x0f, + 0xb3, 0x03, 0xec, 0x20, 0xfb, 0x00, 0x3e, 0xc0, + 0x0d, 0xb0, 0x03, 0x24, 0x00, 0xc2, 0x00, 0x32, + 0x44, 0x0c, 0xb0, 0x03, 0xe0, 0x00, 0xc0, 0x10, + 0x32, 0x80, 0x0c, 0x90, 0x03, 0x10, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x28, 0x04, + 0xab, 0xc0, 0x2e, 0x40, 0x2a, 0xa0, 0x02, 0xe5, + 0x00, 0x8f, 0x00, 0x2f, 0xd0, 0x0a, 0x38, 0x82, + 0xef, 0x40, 0x8b, 0x10, 0x22, 0xd3, 0x0b, 0xb4, + 0x22, 0xe4, 0x90, 0x8a, 0x24, 0x22, 0xf0, 0x8b, + 0xb0, 0x02, 0xef, 0x20, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0x2e, 0x00, 0x8b, 0x0a, 0x22, + 0xc0, 0x0d, 0xb5, 0x22, 0xe9, 0x00, 0xa8, 0xd4, + 0x32, 0xe4, 0x88, 0xb0, 0x0a, 0x36, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x40, 0x00, + 0x83, 0x86, 0x2e, 0x00, 0x08, 0x20, 0x42, 0xc0, + 0x08, 0xab, 0x48, 0x2c, 0xc4, 0x08, 0x38, 0x02, + 0xcb, 0x02, 0x22, 0x00, 0x2c, 0xe0, 0x0b, 0x32, + 0x02, 0xc4, 0x01, 0x90, 0x81, 0x28, 0xe0, 0x0b, + 0x38, 0x02, 0xc3, 0x00, 0x33, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0x28, 0x00, 0x82, 0x80, 0x22, + 0xa2, 0x18, 0x8c, 0x06, 0xe0, 0x20, 0x80, 0xc1, + 0x20, 0x00, 0x08, 0x01, 0x02, 0x38, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x32, 0x00, + 0xa5, 0xc0, 0x2d, 0xa4, 0x2a, 0x78, 0x02, 0xda, + 0x00, 0xa7, 0x80, 0x2d, 0xe0, 0x0a, 0x78, 0x02, + 0xde, 0x20, 0xaf, 0x80, 0x21, 0xe0, 0x0b, 0x69, + 0x42, 0xf6, 0x0a, 0x14, 0x80, 0x21, 0x70, 0x0b, + 0x78, 0x02, 0xda, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x03, 0x78, 0x02, 0x1e, 0x60, 0x96, 0x86, 0x21, + 0xed, 0x09, 0x00, 0x90, 0x01, 0x60, 0x09, 0x78, + 0x96, 0xd6, 0x00, 0xa7, 0x90, 0x21, 0xa0, 0x08, + 0x5c, 0x02, 0x28, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x08, 0x00, 0x00, 0xc1, 0x30, 0x3c, + 0x00, 0x2e, 0x20, 0x03, 0xc0, 0x00, 0xe3, 0x11, + 0x3c, 0xc8, 0x1c, 0x30, 0x07, 0xc4, 0x00, 0xe2, + 0x00, 0x3c, 0xc0, 0x4f, 0x30, 0x03, 0xc4, 0x00, + 0xd0, 0x00, 0x38, 0xc2, 0x0f, 0x34, 0x03, 0xcc, + 0x00, 0xb3, 0x00, 0x3c, 0xc0, 0x0d, 0xb0, 0x02, + 0x00, 0x40, 0xc3, 0x20, 0x30, 0x80, 0x0c, 0x14, + 0x03, 0xc4, 0x20, 0xc0, 0x10, 0x32, 0xc6, 0x0c, + 0x33, 0x03, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x1d, 0x90, 0x40, 0x7f, 0x10, 0x1f, + 0x80, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0xdf, 0x00, + 0x3d, 0xc2, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xd7, + 0x00, 0x3f, 0xc4, 0x0f, 0xe0, 0x43, 0xd4, 0x40, + 0xec, 0x00, 0x3f, 0xc4, 0x0f, 0xd0, 0x03, 0xfc, + 0x00, 0xff, 0x10, 0x3f, 0xc4, 0x4f, 0xf0, 0x03, + 0xfc, 0x40, 0xef, 0x00, 0x3f, 0xc0, 0x0e, 0xf0, + 0x03, 0xf4, 0x01, 0xff, 0x14, 0x3f, 0xc0, 0x0f, + 0xf1, 0x03, 0xd0, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x05, 0xe0, 0x00, 0xfa, 0x00, 0x3e, + 0xc0, 0x0c, 0xa0, 0x03, 0x68, 0x00, 0xcb, 0x30, + 0x3e, 0xd2, 0x0e, 0xb0, 0x03, 0xec, 0x00, 0xfa, + 0x00, 0x3e, 0x40, 0x0b, 0x98, 0x21, 0xa0, 0x00, + 0xfa, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x08, 0xfb, 0x00, 0x1a, 0xc0, 0x0f, 0xb8, 0x03, + 0x28, 0x00, 0xc8, 0x01, 0x3e, 0xc0, 0x8f, 0xa0, + 0x03, 0xe8, 0x04, 0xfb, 0x02, 0x32, 0x40, 0x0f, + 0xa0, 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x11, 0x90, 0x00, 0xb5, 0x00, 0x2f, + 0xc0, 0x0d, 0x60, 0x02, 0x1c, 0x00, 0xa7, 0x28, + 0x2d, 0xc8, 0x2d, 0xed, 0x09, 0x00, 0x91, 0x01, + 0x50, 0x22, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x03, 0x54, 0x00, 0xb6, 0x01, 0x2d, + 0xc0, 0x8b, 0x70, 0x22, 0xdc, 0x00, 0xb7, 0x00, + 0x25, 0xc0, 0x0b, 0xf0, 0x0a, 0x1c, 0x08, 0x04, + 0x00, 0x2d, 0x40, 0x4e, 0x70, 0x02, 0xdc, 0x11, + 0xb3, 0x01, 0x21, 0xc0, 0x09, 0x70, 0x02, 0xf2, + 0x24, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x92, 0x00, 0xb5, 0x80, 0x2d, 0xa0, 0x08, 0x28, + 0x02, 0x4e, 0x00, 0x87, 0x80, 0x2c, 0xe8, 0x2a, + 0x78, 0x82, 0xd6, 0x00, 0xb6, 0x80, 0x2d, 0xe2, + 0x0b, 0x58, 0x12, 0x96, 0x00, 0x96, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x22, 0x12, 0x02, 0x87, + 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, + 0xb7, 0xc4, 0x29, 0xe0, 0x0b, 0x78, 0x02, 0xe0, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, + 0xc0, 0x00, 0xb2, 0x01, 0x2e, 0xe0, 0x09, 0xbd, + 0x02, 0x0e, 0x08, 0xa3, 0x00, 0x2c, 0xc0, 0xa9, + 0x1e, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x6c, 0xc0, + 0x0b, 0x38, 0x02, 0x4a, 0x20, 0xb3, 0x80, 0x2c, + 0xc0, 0x0b, 0x31, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x24, 0xc0, 0x0b, 0x30, 0x02, 0x0c, 0x00, 0x83, + 0x80, 0x2c, 0xd0, 0x0a, 0x36, 0x02, 0xee, 0x40, + 0xb3, 0xc0, 0x28, 0xc5, 0x09, 0x3c, 0x42, 0xf2, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, + 0xb9, 0x00, 0xfe, 0x40, 0x3f, 0x98, 0x0c, 0xec, + 0x03, 0x7a, 0x80, 0xca, 0x00, 0x3e, 0x80, 0x6e, + 0xe4, 0x03, 0xf9, 0x00, 0xfe, 0x4a, 0x2f, 0x90, + 0x8f, 0xee, 0x23, 0xbb, 0x00, 0xf6, 0xc0, 0x3f, + 0x90, 0x0f, 0xec, 0x03, 0xfb, 0x80, 0xfa, 0x00, + 0x7a, 0x80, 0x0f, 0xa0, 0x03, 0x38, 0x00, 0xce, + 0x80, 0x1f, 0x80, 0x0f, 0xe4, 0x03, 0xed, 0x09, + 0x00, 0x92, 0x01, 0xfa, 0x00, 0xbe, 0xc0, 0xbb, + 0xb0, 0x0f, 0xe4, 0x83, 0xfa, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0xe2, 0x00, 0xf8, + 0x80, 0x3e, 0x20, 0x8f, 0x80, 0x2b, 0xe3, 0x00, + 0xf8, 0x40, 0x3e, 0x00, 0x2f, 0x80, 0x03, 0xe3, + 0x00, 0xf8, 0xc0, 0x3e, 0x30, 0x0f, 0x88, 0x07, + 0xa0, 0x40, 0xf8, 0x90, 0x3e, 0x20, 0x0f, 0x8c, + 0x03, 0xe2, 0x00, 0xf8, 0x00, 0x76, 0x00, 0x0f, + 0x84, 0x03, 0xc0, 0x00, 0xf0, 0x50, 0x3c, 0x02, + 0x0e, 0x84, 0x03, 0xe0, 0x10, 0xf8, 0x20, 0x36, + 0x02, 0x0d, 0x84, 0x83, 0xd2, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x10, 0xf9, + 0x22, 0x3e, 0x40, 0x0c, 0x90, 0x83, 0x85, 0x00, + 0xc1, 0x40, 0xbe, 0x40, 0x0d, 0x9a, 0x07, 0xe6, + 0x00, 0xf9, 0x00, 0x3e, 0x44, 0x8f, 0x98, 0x03, + 0xe4, 0x80, 0xd9, 0xa0, 0x32, 0x51, 0x06, 0x90, + 0x01, 0x66, 0x80, 0xf9, 0x01, 0x3e, 0x40, 0x0f, + 0x98, 0x03, 0xe4, 0x04, 0xe9, 0x80, 0x32, 0x60, + 0x0c, 0x1c, 0x03, 0x24, 0x00, 0xc1, 0x00, 0x32, + 0x44, 0x0f, 0x90, 0x43, 0xc2, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x44, 0x64, 0x00, 0xb9, + 0xc0, 0x2e, 0x40, 0x08, 0x90, 0x02, 0x26, 0x20, + 0x89, 0x00, 0xa8, 0x70, 0x08, 0x9c, 0x42, 0xe5, + 0xc8, 0xb9, 0x60, 0x26, 0x78, 0x8b, 0x90, 0x02, + 0x44, 0x08, 0xa9, 0xc0, 0x34, 0x60, 0x28, 0x90, + 0x92, 0xe7, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x98, 0x02, 0xe6, 0x00, 0x89, 0x40, 0x22, 0x74, + 0x08, 0x90, 0x02, 0x24, 0x00, 0x89, 0x40, 0x22, + 0x60, 0x0b, 0x94, 0x02, 0xe0, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, 0xb9, + 0x00, 0x2e, 0xc0, 0x08, 0xb0, 0x02, 0xa4, 0x00, + 0x89, 0x00, 0xae, 0x4b, 0xc9, 0xb0, 0x82, 0xe4, + 0x01, 0xed, 0x09, 0x00, 0x93, 0x01, 0xbb, 0x80, + 0x2e, 0x40, 0x0b, 0x91, 0x82, 0xa4, 0x00, 0x89, + 0x40, 0x26, 0x50, 0x08, 0x90, 0x02, 0x64, 0x20, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x91, 0x02, 0xe4, + 0x40, 0xa9, 0x10, 0x22, 0x50, 0x08, 0x90, 0x02, + 0x2c, 0x00, 0x89, 0x20, 0x26, 0x40, 0x0b, 0x98, + 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x04, 0x00, 0xb1, 0xc0, 0x2c, 0xd0, + 0x28, 0x14, 0x12, 0x04, 0x02, 0x83, 0x40, 0x28, + 0x40, 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, + 0x24, 0x41, 0x0b, 0x10, 0x02, 0xe4, 0x00, 0x29, + 0x02, 0x24, 0x40, 0x0a, 0x10, 0x16, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x14, 0x02, 0xcd, + 0x00, 0x81, 0x40, 0xa0, 0x50, 0x28, 0x34, 0x42, + 0x05, 0x00, 0x83, 0x40, 0xa4, 0x50, 0x0b, 0x34, + 0x42, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0c, 0x80, 0x03, 0xa0, 0x00, 0xc8, 0x00, 0x3e, + 0x00, 0x0d, 0x80, 0x12, 0xe0, 0x00, 0xf8, 0x01, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xd8, + 0x00, 0x36, 0x00, 0x0c, 0x80, 0x03, 0x60, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0xa0, 0x03, 0xc0, + 0x00, 0xea, 0x00, 0x32, 0x00, 0x0c, 0x80, 0x0b, + 0x28, 0x02, 0xc8, 0x00, 0x36, 0x00, 0x0f, 0x80, + 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x1d, 0xfc, 0x00, 0xfd, 0x00, 0x0f, 0x40, + 0x0f, 0xd4, 0x03, 0xf5, 0x00, 0xf9, 0x42, 0xbe, + 0x50, 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xfd, 0x01, + 0x3f, 0x40, 0x0f, 0x50, 0x23, 0x74, 0x00, 0xfd, + 0x06, 0x3f, 0xc0, 0x0d, 0xd0, 0x03, 0xfc, 0x00, + 0xf9, 0x01, 0x3e, 0x40, 0x0f, 0x90, 0x13, 0xfd, + 0x00, 0xfd, 0x40, 0x3f, 0x50, 0x0f, 0xd4, 0x03, + 0xf5, 0x01, 0xfd, 0x40, 0xed, 0x09, 0x00, 0x94, + 0x01, 0x3b, 0x50, 0x8f, 0xd4, 0x03, 0xe6, 0x26, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, + 0x18, 0xfd, 0x03, 0x3f, 0x41, 0x2c, 0x91, 0x03, + 0x74, 0x98, 0xc5, 0x28, 0x33, 0x48, 0x2c, 0xd0, + 0x03, 0x74, 0x00, 0xf5, 0x00, 0x3f, 0x40, 0x0c, + 0xd0, 0x03, 0xf4, 0x00, 0x8d, 0x00, 0x3f, 0xc0, + 0x0b, 0xd0, 0x0b, 0x34, 0x00, 0xf9, 0x00, 0x2e, + 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xed, 0x10, + 0xb3, 0x48, 0x0c, 0xf2, 0xc3, 0x74, 0xc6, 0xcd, + 0x04, 0x3b, 0x40, 0x0c, 0xd1, 0x03, 0x06, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, + 0x00, 0xb8, 0x08, 0x2e, 0x02, 0x08, 0x81, 0x42, + 0x20, 0x00, 0x88, 0x22, 0x22, 0x04, 0x28, 0x80, + 0x02, 0x20, 0x00, 0xb8, 0x00, 0x2e, 0x80, 0x08, + 0x80, 0x02, 0xe0, 0x00, 0x8a, 0x00, 0x2e, 0x00, + 0x0b, 0x80, 0x02, 0x20, 0x04, 0xb8, 0x00, 0x2e, + 0x00, 0x0b, 0x00, 0x82, 0xe0, 0x20, 0x8a, 0x12, + 0x22, 0x0a, 0x28, 0x02, 0x02, 0x08, 0xc8, 0x80, + 0x48, 0x2e, 0x02, 0x08, 0x81, 0x02, 0x0e, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, + 0x00, 0xb1, 0x20, 0x2c, 0x60, 0x28, 0x10, 0x22, + 0xc6, 0x40, 0x81, 0x28, 0x20, 0x40, 0x28, 0x90, + 0x02, 0x04, 0x00, 0xb1, 0x80, 0x2c, 0x40, 0x08, + 0x10, 0x02, 0xcc, 0x00, 0x81, 0x01, 0x2c, 0x40, + 0x0b, 0x10, 0x12, 0x04, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0x12, 0x62, 0xc4, 0x40, 0x81, 0x00, + 0x20, 0x4c, 0x09, 0x12, 0x82, 0xc4, 0x80, 0x91, + 0x30, 0x2c, 0x44, 0x18, 0x38, 0x02, 0x12, 0x01, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, + 0x00, 0xb9, 0x41, 0x2c, 0x40, 0x08, 0x96, 0x22, + 0xa4, 0x00, 0x8b, 0x00, 0x22, 0x40, 0x28, 0x94, + 0x0a, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x60, 0xed, + 0x09, 0x00, 0x95, 0x01, 0x28, 0x90, 0x06, 0xe6, + 0x0a, 0xa9, 0x81, 0x2e, 0x44, 0x0b, 0x90, 0x80, + 0x24, 0x10, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x22, 0xe4, 0x41, 0xa9, 0x20, 0x22, 0x48, 0x09, + 0x12, 0x00, 0xa4, 0x00, 0x99, 0x00, 0x2c, 0x48, + 0x08, 0xb8, 0x02, 0x06, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x15, 0xe7, 0x00, 0xf9, 0xc0, + 0x3e, 0x44, 0x0c, 0x90, 0x03, 0xe5, 0x02, 0xc9, + 0x00, 0xb2, 0x40, 0x8c, 0x90, 0x03, 0x27, 0x20, + 0xb9, 0xc0, 0x3c, 0x70, 0x0c, 0x90, 0x43, 0xe4, + 0x80, 0xc9, 0xc0, 0x3e, 0x60, 0x1f, 0x90, 0x03, + 0x25, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe7, 0x02, 0xc9, 0x42, 0x32, 0x52, 0x0d, + 0x9e, 0x03, 0xe4, 0x00, 0xd9, 0x00, 0x3a, 0x48, + 0x2c, 0x90, 0x0b, 0x28, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x01, 0xa5, 0x00, 0xf9, 0x10, + 0x3e, 0x62, 0x0f, 0x90, 0x03, 0x44, 0x00, 0xf9, + 0x08, 0x3e, 0x42, 0x2b, 0x90, 0x03, 0xa4, 0x60, + 0xf9, 0x90, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x08, 0xd9, 0x00, 0x3e, 0x40, 0x0f, 0x92, 0x07, + 0xe4, 0x50, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe6, 0x00, 0xd1, 0x00, 0x3c, 0x40, 0x82, + 0x90, 0x03, 0x64, 0x00, 0xe9, 0x00, 0x3e, 0x62, + 0x0f, 0x10, 0x03, 0xda, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x10, 0xa1, 0x00, 0xf8, 0x64, + 0x3e, 0x00, 0x04, 0x80, 0x03, 0x22, 0x10, 0xe8, + 0x00, 0x30, 0x00, 0x0c, 0x88, 0x03, 0xe1, 0x00, + 0xd8, 0x00, 0x36, 0x08, 0x4f, 0x89, 0x0b, 0x20, + 0x00, 0xf8, 0x40, 0x3e, 0x30, 0x8f, 0x81, 0x03, + 0xe2, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0x60, 0x28, 0xc8, 0x60, 0xb2, 0x10, 0x0e, + 0x86, 0x03, 0x00, 0x82, 0xc8, 0x00, 0x32, 0x14, + 0x0c, 0x88, 0xed, 0x09, 0x00, 0x96, 0x01, 0x03, + 0x0a, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x28, 0x00, 0xbe, 0x00, 0x2f, 0x80, 0x28, + 0xa0, 0x02, 0x39, 0x08, 0x86, 0xa0, 0x23, 0x80, + 0x2a, 0x64, 0x03, 0xb8, 0x00, 0x8e, 0x81, 0x23, + 0xa3, 0x0b, 0xec, 0x02, 0x88, 0x00, 0xbe, 0x04, + 0x2f, 0xb8, 0x03, 0x60, 0x42, 0xf9, 0x00, 0xba, + 0x00, 0x2e, 0x80, 0x0b, 0xed, 0x03, 0x38, 0x00, + 0x8e, 0x00, 0x23, 0x80, 0x08, 0xe8, 0x00, 0x39, + 0x00, 0x8e, 0x00, 0x23, 0xa0, 0x08, 0xe0, 0x02, + 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xf0, 0x48, + 0xb0, 0x00, 0x0c, 0x08, 0xa3, 0x00, 0x20, 0x70, + 0x08, 0x38, 0x12, 0xc4, 0x00, 0x90, 0x8a, 0x24, + 0x00, 0x0b, 0x30, 0x02, 0xc4, 0x00, 0xb0, 0xa0, + 0x2c, 0xe0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x38, 0x0a, 0x2c, 0x08, + 0x13, 0x00, 0xa0, 0xc0, 0x08, 0x38, 0x4a, 0x8e, + 0x00, 0x93, 0x98, 0x20, 0xe0, 0x89, 0x30, 0x0e, + 0x0a, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x01, 0x1c, 0x04, 0xb6, 0x0c, 0x2d, 0xd0, 0x08, + 0xf2, 0x02, 0x04, 0x3c, 0x87, 0x00, 0x21, 0x02, + 0x2a, 0x70, 0x82, 0xbe, 0x20, 0x87, 0xc0, 0x21, + 0xc0, 0x0b, 0xf8, 0x02, 0xdc, 0x08, 0xb6, 0x40, + 0x2d, 0x80, 0x8b, 0x70, 0x02, 0x5c, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x0b, 0x78, 0x82, 0x0c, 0x0a, + 0x95, 0x02, 0x20, 0x40, 0x28, 0x70, 0x82, 0x99, + 0x18, 0x87, 0x82, 0xa0, 0x40, 0x09, 0x70, 0x02, + 0x28, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x2f, 0xe0, 0x2c, + 0x78, 0x0b, 0x1e, 0x00, 0xe7, 0x80, 0xb0, 0xe0, + 0x1c, 0x78, 0x03, 0xde, 0x00, 0xd7, 0x80, 0x35, + 0xe0, 0x0f, 0x78, 0x03, 0x5e, 0xed, 0x09, 0x00, + 0x97, 0x01, 0x00, 0xf7, 0x80, 0x2d, 0xa0, 0x0f, + 0x68, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, + 0x0f, 0x78, 0x03, 0x12, 0x00, 0xdf, 0x82, 0x31, + 0xa0, 0x1e, 0x78, 0x03, 0x9e, 0x02, 0xc7, 0x80, + 0x21, 0xe0, 0x2d, 0xf8, 0x03, 0x2a, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, + 0xf8, 0x00, 0x3e, 0xc0, 0x0f, 0x31, 0x43, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x90, 0x03, + 0x0c, 0x04, 0xfa, 0x00, 0x3e, 0x40, 0x0f, 0x30, + 0x43, 0x2c, 0x00, 0xd9, 0x00, 0x3e, 0x80, 0x0f, + 0xa0, 0x03, 0xe4, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x53, 0xa0, 0x00, 0xe9, 0x00, 0x3e, + 0x00, 0x1f, 0x90, 0x03, 0x6c, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0e, 0xb0, 0x43, 0xc2, 0x06, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, + 0xff, 0x80, 0x3f, 0xe0, 0x0c, 0xf8, 0x43, 0x7a, + 0x08, 0xdd, 0x80, 0x3b, 0x64, 0x2e, 0xd0, 0x03, + 0x3e, 0x00, 0xff, 0x80, 0x2d, 0xe4, 0x0c, 0xf8, + 0x11, 0xfe, 0x00, 0xff, 0x80, 0x33, 0xa0, 0x0f, + 0x58, 0x43, 0x3a, 0x00, 0xff, 0x80, 0x3f, 0xe0, + 0x0f, 0xd8, 0x03, 0x3e, 0xc0, 0xdf, 0x80, 0x3b, + 0xe1, 0x0c, 0xf8, 0x00, 0x36, 0x44, 0xcf, 0x80, + 0x3f, 0xa0, 0x04, 0xf8, 0x21, 0xc0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, + 0xbc, 0x00, 0x23, 0xc0, 0x08, 0x70, 0x12, 0x10, + 0x40, 0x85, 0x00, 0x21, 0xcc, 0x2d, 0x70, 0x03, + 0x5c, 0x10, 0xb5, 0x20, 0x2d, 0xc0, 0x08, 0x72, + 0x02, 0xdc, 0x04, 0xb7, 0x40, 0x21, 0x90, 0x0b, + 0x70, 0x02, 0x1c, 0x40, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x50, 0x02, 0x1d, 0x40, 0x85, 0x00, 0xa1, + 0x40, 0x08, 0x61, 0x02, 0x18, 0xc0, 0xc7, 0x00, + 0x2f, 0xc6, 0x08, 0x60, 0x02, 0xea, 0x04, 0x60, + 0xed, 0x09, 0x00, 0x98, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0xb6, 0x18, 0x29, + 0xc4, 0x28, 0x70, 0x02, 0x5c, 0x00, 0x91, 0x00, + 0xa9, 0xc1, 0x0a, 0xe0, 0x82, 0x1c, 0x00, 0xb7, + 0x00, 0x27, 0x82, 0x89, 0x70, 0xa2, 0xdd, 0x00, + 0xb7, 0x00, 0x21, 0x80, 0x0b, 0xc0, 0x02, 0x1c, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x60, 0x02, + 0x15, 0x80, 0xb6, 0x00, 0x20, 0x84, 0x28, 0x30, + 0x02, 0x00, 0x08, 0xa6, 0x00, 0x2d, 0x00, 0x08, + 0x54, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x14, 0xcd, 0x80, 0xb0, 0x48, 0x20, + 0xe0, 0x08, 0x30, 0x02, 0x4c, 0x04, 0x99, 0x02, + 0x20, 0x40, 0x29, 0x2c, 0x02, 0x4f, 0x40, 0xb3, + 0x80, 0x2c, 0xe0, 0x09, 0x34, 0xc2, 0xcc, 0x00, + 0xb3, 0xa0, 0x20, 0x10, 0x0b, 0x27, 0x02, 0x04, + 0x20, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x20, 0x02, + 0x06, 0x41, 0xa0, 0x45, 0x20, 0x18, 0x08, 0x01, + 0x02, 0x0a, 0x00, 0x88, 0x70, 0x2c, 0x70, 0x08, + 0x00, 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x15, 0xad, 0x00, 0xfa, 0x80, 0x38, + 0x70, 0x0c, 0x78, 0x8b, 0x6a, 0x00, 0xdb, 0x00, + 0x3a, 0xc0, 0x4a, 0x98, 0x42, 0x0b, 0x00, 0xfb, + 0xe0, 0x36, 0xe0, 0x2d, 0x98, 0x03, 0xec, 0x00, + 0x73, 0x88, 0x82, 0x10, 0x0b, 0xb0, 0x4b, 0x0e, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xa0, 0x0b, + 0x2c, 0x00, 0xfa, 0x40, 0x32, 0xe8, 0x0c, 0xbc, + 0x0b, 0x2e, 0x40, 0xcb, 0x00, 0x3e, 0xc0, 0x2c, + 0xb8, 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0xec, 0x00, 0xfa, 0x40, 0x3a, + 0x46, 0x0f, 0xb0, 0x83, 0xa6, 0x20, 0xeb, 0x40, + 0xbc, 0x00, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xdb, + 0x00, 0x3e, 0x88, 0x0e, 0x94, 0x03, 0xee, 0x00, + 0xfb, 0x00, 0x3e, 0xed, 0x09, 0x00, 0x99, 0x01, + 0x30, 0x0f, 0xa4, 0x03, 0xee, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xa0, 0x03, 0xc4, 0x00, 0x9a, + 0x08, 0x3e, 0x80, 0x0f, 0xb6, 0x03, 0xe0, 0x40, + 0xea, 0x00, 0x3c, 0x08, 0x0f, 0x11, 0x03, 0xe0, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, + 0xfc, 0x01, 0xfe, 0x00, 0x33, 0x20, 0x4c, 0xb0, + 0x03, 0x0b, 0x00, 0xcc, 0xc0, 0xb2, 0xc0, 0x2c, + 0xd0, 0x87, 0x3c, 0x20, 0x4d, 0x08, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xfe, 0x04, 0xff, 0x80, 0x33, + 0x22, 0x0f, 0xea, 0x03, 0x3c, 0x00, 0xcf, 0x00, + 0x3f, 0xc0, 0x0d, 0xc0, 0x03, 0xea, 0x00, 0xc4, + 0x14, 0x33, 0x40, 0x0c, 0xe0, 0x03, 0xde, 0x40, + 0xcf, 0x10, 0x33, 0xc0, 0x0c, 0xe0, 0x01, 0x00, + 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, + 0x6c, 0x00, 0xb0, 0xc8, 0x2a, 0x10, 0x48, 0xb0, + 0x02, 0x2c, 0x00, 0xd8, 0x01, 0x22, 0x64, 0x0f, + 0x39, 0x03, 0xec, 0x08, 0xab, 0xd0, 0x26, 0xe6, + 0x8b, 0xb9, 0x02, 0xee, 0x00, 0xbb, 0xc0, 0x36, + 0x34, 0x8b, 0x20, 0x02, 0xa5, 0x20, 0x0b, 0x00, + 0x3a, 0xc0, 0x0b, 0x87, 0x02, 0xe0, 0x00, 0x88, + 0x80, 0x2a, 0x30, 0x28, 0x86, 0x02, 0x66, 0x00, + 0x88, 0x4a, 0x22, 0x12, 0x0a, 0x89, 0x02, 0x20, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, + 0x2c, 0x00, 0xba, 0x80, 0x62, 0x86, 0x08, 0xb0, + 0x02, 0x21, 0x00, 0xab, 0x00, 0xa2, 0x40, 0x48, + 0xb0, 0x42, 0x2c, 0xb0, 0xaa, 0x40, 0x2e, 0x40, + 0x0b, 0xb4, 0x02, 0xe4, 0x80, 0xb9, 0x20, 0x22, + 0x00, 0x0b, 0xb0, 0x92, 0x28, 0x00, 0x8b, 0x00, + 0x2e, 0xc0, 0x0b, 0x90, 0x02, 0xe8, 0x40, 0x8b, + 0x40, 0x20, 0xd8, 0x08, 0x91, 0x02, 0xe4, 0x00, + 0xa9, 0x02, 0x22, 0x80, 0x08, 0xb0, 0x02, 0xa0, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x9a, 0x01, 0x08, 0x04, 0x0c, 0x00, 0xb2, + 0x00, 0x2a, 0x80, 0x08, 0xb0, 0x02, 0x00, 0x05, + 0xb2, 0x00, 0x20, 0x40, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xa3, 0x00, 0x24, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0x3b, 0x00, 0x24, 0x00, 0x1b, 0x00, + 0x00, 0xac, 0x02, 0x83, 0x00, 0x28, 0xc0, 0x0b, + 0x10, 0x02, 0xc0, 0x02, 0x83, 0x00, 0x28, 0x80, + 0x08, 0x00, 0x02, 0x40, 0x00, 0x80, 0x02, 0x20, + 0x80, 0x28, 0x00, 0x02, 0x82, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xba, + 0x05, 0x22, 0xc0, 0x8c, 0xb0, 0x0b, 0x20, 0x00, + 0xe8, 0x00, 0x32, 0xc0, 0x4c, 0xa0, 0x22, 0x2c, + 0x00, 0xeb, 0x01, 0x3e, 0xc0, 0x0f, 0x90, 0x02, + 0xec, 0x00, 0xfb, 0x00, 0x72, 0x00, 0x0f, 0xa0, + 0x13, 0x2c, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0d, + 0x00, 0x03, 0xe8, 0x00, 0xc0, 0x00, 0x32, 0x40, + 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xe8, 0x00, 0xb2, + 0x00, 0x0c, 0x80, 0x0b, 0x80, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xfc, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf4, 0x00, + 0xdd, 0x00, 0xb7, 0x40, 0x0e, 0x60, 0x03, 0xbc, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, + 0xfc, 0x00, 0xf5, 0x00, 0x3f, 0x00, 0x0f, 0xc0, + 0x03, 0xf0, 0x00, 0xff, 0x00, 0x3b, 0xc0, 0x0f, + 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, + 0x0f, 0xc0, 0x01, 0x70, 0x00, 0xfc, 0x00, 0x3f, + 0x00, 0x07, 0xc0, 0x03, 0x68, 0x06, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x05, 0xfc, 0x70, 0xcf, + 0x00, 0x33, 0xd8, 0x0f, 0xc0, 0x0b, 0x7c, 0xc8, + 0xcf, 0x21, 0x3f, 0x00, 0x0c, 0xf1, 0x03, 0xf0, + 0x00, 0xfc, 0x00, 0x3b, 0x00, 0x0d, 0xf0, 0x23, + 0xfc, 0x00, 0xcf, 0x05, 0x31, 0xc8, 0x0f, 0xf0, + 0x03, 0xed, 0x09, 0x00, 0x9b, 0x01, 0xd0, 0x00, + 0xcf, 0x00, 0xb3, 0xc0, 0x0f, 0xc0, 0x03, 0xfc, + 0x04, 0xcc, 0x00, 0xb7, 0x80, 0x0d, 0xf4, 0x03, + 0x7c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc2, 0x98, 0xfd, 0x82, 0x87, 0x38, 0x23, 0xd0, + 0x0b, 0x92, 0x8a, 0x1d, 0x00, 0x8f, 0x10, 0x2e, + 0x00, 0x0b, 0xf7, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x22, 0xc0, 0x08, 0xf4, 0x82, 0xfd, 0x48, 0xaf, + 0x50, 0x37, 0xc4, 0x0f, 0xb0, 0x82, 0xec, 0x00, + 0xaa, 0x08, 0x22, 0x81, 0x0b, 0xb0, 0x03, 0xe8, + 0x00, 0xf8, 0x00, 0x22, 0xc0, 0x08, 0xb5, 0x02, + 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xca, 0x40, 0xcc, 0x90, 0x83, 0x00, 0x20, 0xcc, + 0x0b, 0x10, 0x02, 0x0c, 0x40, 0x83, 0x01, 0x2c, + 0x4a, 0x0b, 0x30, 0x42, 0xcc, 0x00, 0xb3, 0x00, + 0x2a, 0x80, 0x0b, 0x36, 0x02, 0xcc, 0x04, 0x83, + 0x04, 0x28, 0xc1, 0x0b, 0x32, 0x02, 0xcc, 0x04, + 0xab, 0x24, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xec, + 0x04, 0x80, 0x00, 0x66, 0xc0, 0x09, 0x32, 0x02, + 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x05, 0xac, 0x00, 0x8b, 0x00, 0x22, 0xc0, + 0x8b, 0x81, 0x12, 0x2c, 0x00, 0x8b, 0x00, 0x2e, + 0x20, 0x0b, 0xb0, 0x02, 0xe4, 0x40, 0xbb, 0x40, + 0x22, 0xc2, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xab, + 0x00, 0xaa, 0xc0, 0x0a, 0xb0, 0x42, 0xed, 0x80, + 0xa9, 0x00, 0x22, 0xc9, 0x0b, 0xb5, 0x40, 0xac, + 0x00, 0xaa, 0x00, 0x22, 0xc8, 0x69, 0xb0, 0x02, + 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x15, 0xec, 0x00, 0xed, 0x09, 0x00, 0x9c, + 0x01, 0xcb, 0x00, 0xb2, 0xc0, 0x0f, 0x9c, 0x03, + 0x2c, 0x02, 0xcb, 0x00, 0x3e, 0x52, 0x0e, 0xb0, + 0x03, 0xee, 0x00, 0xf3, 0x50, 0x3a, 0xc0, 0x1f, + 0xb0, 0x03, 0xcc, 0x00, 0xc3, 0x00, 0x0a, 0xc0, + 0x0b, 0xb0, 0x03, 0xec, 0x00, 0x8b, 0x40, 0x32, + 0x40, 0x0f, 0xb0, 0x10, 0xec, 0x00, 0x80, 0x80, + 0x36, 0x58, 0x0d, 0xb0, 0x03, 0x6c, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xf0, 0x44, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x9c, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xd8, 0x03, + 0xfc, 0x00, 0xff, 0x02, 0x3f, 0x40, 0x0f, 0xf0, + 0x03, 0xfe, 0x00, 0xfe, 0x82, 0x3f, 0xe4, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0x27, 0xc0, + 0x0f, 0xf0, 0x03, 0xfe, 0x00, 0x7f, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x23, 0xfc, 0x80, 0x3e, 0x40, + 0x3f, 0xe0, 0x4e, 0x70, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x07, 0xf0, 0x03, 0xf8, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, + 0x00, 0xf3, 0x00, 0x36, 0xc0, 0x2c, 0x94, 0x03, + 0x0c, 0x00, 0xdb, 0x00, 0x3e, 0x40, 0x0d, 0xb0, + 0x03, 0x28, 0x08, 0xc9, 0x14, 0x3e, 0xc8, 0x0c, + 0xb0, 0x03, 0x2c, 0x00, 0xcb, 0x08, 0x3e, 0xc0, + 0x0c, 0xb0, 0x03, 0xed, 0x00, 0xeb, 0x00, 0x3a, + 0x40, 0x0c, 0xb4, 0x03, 0xad, 0x20, 0xf9, 0x00, + 0x36, 0xd0, 0x8c, 0xb0, 0x03, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x05, 0x3c, + 0x00, 0xbf, 0x00, 0x23, 0xc0, 0x08, 0x90, 0x02, + 0xbc, 0x04, 0x8f, 0xd0, 0x2e, 0xc0, 0x0b, 0xf0, + 0x02, 0x2e, 0x00, 0x8b, 0x40, 0x2c, 0xd0, 0x0b, + 0xf0, 0x02, 0xbc, 0x00, 0x8f, 0xe0, 0x2f, 0xd0, + 0x08, 0xb0, 0x02, 0xcf, 0x60, 0x93, 0x00, 0xed, + 0x09, 0x00, 0x9d, 0x01, 0x22, 0xd0, 0x08, 0xb6, + 0x03, 0x4f, 0x00, 0xbb, 0x80, 0x20, 0xdd, 0x08, + 0xf0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x04, 0x4c, 0x00, 0xa3, 0x00, + 0x24, 0xc0, 0x89, 0x80, 0x22, 0x0c, 0x00, 0x83, + 0x80, 0x2c, 0x40, 0x0b, 0x30, 0x02, 0x0d, 0xc0, + 0x83, 0x80, 0x2c, 0xd0, 0x0a, 0x30, 0x02, 0x0f, + 0x20, 0xb3, 0x00, 0x2c, 0xe8, 0x08, 0x30, 0x02, + 0xcf, 0x00, 0x93, 0x00, 0x28, 0xd2, 0x08, 0x3a, + 0x42, 0x8f, 0x00, 0x90, 0xb0, 0xa0, 0xc0, 0x88, + 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xb8, 0x10, 0x5e, 0x00, 0xb7, 0x80, + 0x20, 0xe4, 0x09, 0xc8, 0x02, 0x9e, 0x07, 0x87, + 0x8a, 0x2d, 0x20, 0x0b, 0x31, 0x02, 0x3a, 0x00, + 0x85, 0xc0, 0x2d, 0xe2, 0x0b, 0x78, 0x02, 0x9e, + 0x20, 0x37, 0x80, 0x6d, 0xe3, 0x08, 0x78, 0x02, + 0xdc, 0x15, 0x97, 0x80, 0x21, 0xa0, 0x28, 0xf8, + 0x02, 0xde, 0x10, 0xb4, 0x80, 0xa3, 0xe0, 0x20, + 0x78, 0x02, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0b, 0x78, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x08, 0x4c, 0x00, 0xe3, 0x00, + 0x34, 0xc4, 0x0d, 0x04, 0x03, 0x0c, 0x00, 0xd3, + 0x10, 0x3c, 0x00, 0x0f, 0x31, 0x13, 0x0c, 0x11, + 0xc2, 0x14, 0x3c, 0xc0, 0x0e, 0x30, 0x03, 0x0c, + 0x40, 0xf3, 0x00, 0x2c, 0xc0, 0x0c, 0x31, 0x01, + 0xcc, 0x40, 0xeb, 0x01, 0x38, 0xc0, 0x2c, 0x30, + 0x03, 0x8d, 0xa0, 0xf2, 0x20, 0x30, 0xc8, 0x0c, + 0xb0, 0x03, 0x8c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, + 0x0f, 0x30, 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x15, 0xbc, 0x00, 0xff, 0x00, + 0x3f, 0xc5, 0xed, 0x09, 0x00, 0x9e, 0x01, 0x0e, + 0x40, 0x03, 0xfc, 0x00, 0xff, 0x08, 0x3f, 0x00, + 0x0f, 0xf0, 0x8b, 0xdc, 0x06, 0xff, 0x10, 0x3f, + 0xc0, 0x0f, 0xf1, 0x03, 0x7c, 0x22, 0xcf, 0x08, + 0x3f, 0xd2, 0x0f, 0xf1, 0x03, 0xfc, 0x80, 0xed, + 0x02, 0x1d, 0xc0, 0x0f, 0x71, 0x03, 0x74, 0x08, + 0xf6, 0x00, 0x39, 0xc0, 0x0f, 0xf1, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xd0, 0x26, 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0xae, 0xf2, 0xdb, 0x20, 0x3a, 0xf8, 0x0c, + 0x90, 0x03, 0xec, 0x80, 0xcb, 0x00, 0x3e, 0x60, + 0x24, 0xb2, 0x03, 0x24, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb4, 0x83, 0xed, 0x20, 0xfb, 0x02, + 0x3a, 0xc1, 0x0f, 0xb0, 0x13, 0xec, 0x00, 0xcb, + 0x01, 0x26, 0xc0, 0x0f, 0xb8, 0x03, 0x2c, 0x00, + 0xd2, 0x80, 0x32, 0xe0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0xd8, 0xbc, 0x80, 0x8f, 0x48, 0x21, 0xcd, 0x08, + 0x70, 0x02, 0xcd, 0x40, 0x87, 0x28, 0x2d, 0x40, + 0x08, 0x72, 0x82, 0x9c, 0x00, 0xb7, 0x01, 0x2d, + 0xc0, 0x83, 0x74, 0x02, 0xdc, 0x00, 0xb7, 0x08, + 0x2d, 0xc8, 0x09, 0x70, 0x20, 0xdc, 0x00, 0xaf, + 0x00, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0x9c, 0x00, + 0x86, 0x00, 0x29, 0xc0, 0x0b, 0x72, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xf2, 0x24, 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x9e, 0x80, 0x87, 0xa0, 0x28, 0xe4, 0x08, + 0x78, 0x82, 0xde, 0x80, 0xa7, 0x80, 0x25, 0xe0, + 0x09, 0x3a, 0x62, 0x5e, 0x00, 0xb7, 0xc0, 0x2d, + 0xe1, 0x03, 0x78, 0x02, 0xde, 0x80, 0xb7, 0xa0, + 0x2d, 0xe8, 0x0b, 0x78, 0x02, 0xfe, 0x20, 0x87, + 0x81, 0x25, 0xe0, 0x0b, 0x78, 0xed, 0x09, 0x00, + 0x9f, 0x01, 0x02, 0x7e, 0x00, 0x97, 0x80, 0x69, + 0xc0, 0x0b, 0x79, 0x02, 0xde, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xe0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x04, 0xcc, 0x02, + 0x83, 0x00, 0x20, 0xc0, 0x08, 0x18, 0x02, 0xcc, + 0x00, 0x83, 0x00, 0x2c, 0x40, 0x89, 0x30, 0x02, + 0x42, 0x10, 0x90, 0x80, 0x2c, 0xc0, 0x03, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x24, 0xc0, 0x0b, + 0xb0, 0x02, 0xce, 0x04, 0xab, 0x80, 0x20, 0xe0, + 0x0b, 0x30, 0x02, 0xc4, 0x00, 0x83, 0x00, 0x28, + 0xc2, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x22, 0xd2, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x15, 0xe8, 0x00, + 0xca, 0x00, 0x3a, 0x80, 0x2c, 0xec, 0x03, 0xe8, + 0x00, 0xea, 0x00, 0x37, 0xb8, 0x0c, 0xa0, 0x02, + 0x7b, 0x00, 0xfe, 0x80, 0x3f, 0x90, 0x0f, 0xa0, + 0x03, 0xe8, 0x00, 0xf2, 0x00, 0x3c, 0x80, 0x0f, + 0xa0, 0x02, 0xf8, 0x08, 0xce, 0x60, 0x37, 0xb0, + 0x0f, 0xec, 0x13, 0x59, 0x00, 0xde, 0x40, 0xbb, + 0xb0, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, + 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xf8, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0xa0, 0x00, + 0xe8, 0x00, 0x3e, 0x00, 0x4f, 0x88, 0x03, 0xe0, + 0x02, 0xf0, 0x40, 0x3e, 0x20, 0x0e, 0x80, 0x0b, + 0xa0, 0xc0, 0xf8, 0x80, 0x3e, 0x20, 0x57, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0d, + 0x80, 0x03, 0xe0, 0x80, 0xf8, 0x80, 0x3e, 0x24, + 0x0f, 0x8d, 0x13, 0xa2, 0x04, 0xf8, 0x82, 0x3e, + 0x04, 0x1f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xa4, 0x00, + 0xe1, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, 0xc4, + 0xed, 0x09, 0x00, 0xa0, 0x01, 0x00, 0x89, 0x40, + 0x32, 0x40, 0x0f, 0x90, 0x03, 0x66, 0x80, 0xf9, + 0x24, 0x36, 0x60, 0x0f, 0x90, 0x03, 0xe5, 0x00, + 0xf9, 0x00, 0x32, 0x60, 0x0c, 0x90, 0x43, 0x26, + 0x00, 0xc9, 0x00, 0xba, 0x40, 0x2c, 0x98, 0x13, + 0xa6, 0x08, 0xe9, 0x80, 0x3e, 0x44, 0x4c, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x64, 0x00, 0xb9, 0x00, 0xa2, + 0x40, 0x09, 0x90, 0x03, 0xe4, 0x00, 0x89, 0x60, + 0xa2, 0x41, 0x0b, 0x90, 0x02, 0x27, 0x00, 0xb9, + 0x00, 0x3e, 0x40, 0x09, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0xd8, 0x22, 0x50, 0x08, 0x90, 0x03, 0x05, + 0x00, 0xd9, 0x04, 0x28, 0x51, 0x20, 0x9c, 0x02, + 0xe7, 0x00, 0xa9, 0x00, 0x2c, 0x78, 0x08, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x05, 0x24, 0x00, 0xa9, 0x00, 0x22, + 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xa9, 0x00, + 0x22, 0x40, 0x0b, 0x10, 0x0a, 0xac, 0x00, 0xb9, + 0x00, 0x2e, 0x48, 0x0b, 0x90, 0x22, 0xe4, 0x04, + 0xb9, 0x01, 0x22, 0x54, 0x08, 0x90, 0x02, 0xa4, + 0x40, 0x9b, 0x00, 0x22, 0x40, 0x00, 0x95, 0x06, + 0xa4, 0x80, 0xa9, 0x10, 0x0e, 0x40, 0x08, 0x90, + 0x22, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x14, 0x05, 0x00, 0xb1, 0x40, 0x20, + 0x50, 0x0b, 0x14, 0x12, 0x85, 0x00, 0xb1, 0x00, + 0x20, 0x50, 0x0b, 0x14, 0x02, 0x06, 0x00, 0xb1, + 0x00, 0x28, 0x40, 0x89, 0x14, 0x22, 0xc4, 0x00, + 0xb1, 0x00, 0x20, 0x40, 0x28, 0x14, 0x42, 0x4c, + 0x00, 0x91, 0x40, 0x22, 0x61, 0x08, 0x10, 0x02, + 0xc6, 0x00, 0x81, 0xed, 0x09, 0x00, 0xa1, 0x01, + 0x02, 0x2e, 0x40, 0x18, 0x14, 0x02, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x40, 0x09, 0x10, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0d, + 0x60, 0x00, 0xe8, 0x00, 0x32, 0x00, 0x0f, 0x80, + 0x12, 0xe0, 0x02, 0xe8, 0x00, 0x30, 0x00, 0x0f, + 0x80, 0x03, 0xa0, 0x00, 0xfa, 0x00, 0x26, 0x00, + 0x03, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0xb2, + 0x00, 0x0c, 0x80, 0x0b, 0xa0, 0x00, 0xc8, 0x00, + 0x3a, 0x00, 0x0c, 0x80, 0x23, 0xa0, 0x00, 0xea, + 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xee, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x95, + 0xe5, 0x00, 0xf9, 0x41, 0x3e, 0x50, 0x0d, 0xd0, + 0x03, 0xe5, 0x00, 0x89, 0x40, 0x3f, 0x40, 0x0f, + 0x94, 0x03, 0x34, 0x00, 0xfd, 0x00, 0x3f, 0x40, + 0x4d, 0x94, 0x03, 0xe5, 0x00, 0xf9, 0x40, 0x3e, + 0x50, 0x0f, 0x90, 0x43, 0x94, 0x00, 0xfd, 0x00, + 0x3f, 0xc0, 0x0b, 0x50, 0x03, 0xd4, 0x04, 0xfd, + 0x03, 0x3f, 0x40, 0x0f, 0x94, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xf6, + 0x26, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, + 0xe4, 0xc0, 0xf9, 0x00, 0x36, 0x40, 0x0d, 0x91, + 0x03, 0x64, 0x80, 0xc5, 0x28, 0x3e, 0x45, 0x0f, + 0x90, 0x03, 0xf4, 0x00, 0xf5, 0x00, 0x3d, 0xc0, + 0x06, 0x92, 0x83, 0xb4, 0x90, 0xcd, 0x00, 0x3f, + 0x40, 0x0c, 0x91, 0x63, 0xd4, 0x00, 0xc9, 0x04, + 0x35, 0x41, 0x0c, 0xd0, 0x03, 0x14, 0x08, 0xcf, + 0x00, 0x3d, 0x41, 0x2e, 0x92, 0xa3, 0xe4, 0x10, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc6, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, + 0xc0, 0xc0, 0xb8, 0x48, 0x00, 0x03, 0x08, 0x00, + 0x02, 0xe0, 0xa0, 0xa8, 0x00, 0x2e, 0xed, 0x09, + 0x00, 0xa2, 0x01, 0x08, 0x0b, 0x84, 0xc2, 0xe0, + 0x00, 0xb8, 0x04, 0x2e, 0x00, 0x0b, 0x82, 0x02, + 0x20, 0x48, 0xa8, 0x40, 0x2e, 0x00, 0x08, 0x80, + 0x02, 0xe0, 0x10, 0xb8, 0x22, 0x22, 0x00, 0x28, + 0x80, 0x4b, 0x60, 0x0c, 0xa8, 0x01, 0x2e, 0x00, + 0x0c, 0x82, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, + 0x00, 0x0b, 0x80, 0x02, 0xde, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x84, 0x80, 0xb1, + 0x30, 0x28, 0x44, 0x0a, 0x18, 0x02, 0xc4, 0xc2, + 0x11, 0x00, 0x24, 0x68, 0x0b, 0x13, 0x02, 0xc4, + 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x1b, 0x12, 0x82, + 0x04, 0x00, 0xa1, 0x10, 0x2c, 0x44, 0x0a, 0x10, + 0x02, 0xe4, 0x00, 0x91, 0x2a, 0x24, 0x41, 0x0b, + 0x10, 0x02, 0xa4, 0x10, 0xb1, 0x00, 0x2c, 0x40, + 0x09, 0x12, 0x82, 0xc4, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0a, 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x04, 0xa4, 0x00, 0xb9, + 0x05, 0x22, 0x40, 0x0a, 0x90, 0x02, 0xe4, 0x00, + 0x89, 0x00, 0x2e, 0x44, 0x0b, 0x90, 0x42, 0xed, + 0x00, 0xb9, 0x80, 0x2e, 0xc0, 0x89, 0x90, 0x22, + 0xa4, 0x01, 0xa9, 0x01, 0x2e, 0xc0, 0x80, 0x90, + 0x02, 0xe4, 0x20, 0xb9, 0x00, 0x62, 0x40, 0x4b, + 0x91, 0x02, 0xe4, 0x10, 0xb9, 0x08, 0x2e, 0x4a, + 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, + 0x00, 0x9a, 0x40, 0x2f, 0x98, 0x03, 0x64, 0x00, + 0xc9, 0x04, 0x3e, 0x40, 0x07, 0x90, 0x13, 0xe7, + 0x00, 0xf9, 0x60, 0x2e, 0x40, 0x4f, 0x90, 0x0b, + 0xa4, 0x00, 0xe9, 0x00, 0x3e, 0x40, 0x2e, 0x90, + 0x03, 0xe7, 0x00, 0xc9, 0x20, 0xb4, 0x50, 0x0f, + 0x14, 0x87, 0xa5, 0x88, 0xd9, 0x15, 0x3e, 0x40, + 0x09, 0xed, 0x09, 0x00, 0xa3, 0x01, 0x90, 0x01, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x01, 0x24, 0x00, 0xf9, 0x00, 0x3c, 0x40, + 0x0d, 0x92, 0x03, 0xc4, 0x00, 0xf9, 0x00, 0x1e, + 0x40, 0x0f, 0x90, 0x03, 0x65, 0x00, 0xf9, 0x00, + 0x3e, 0x70, 0x0f, 0x90, 0x03, 0x64, 0x00, 0xf9, + 0x00, 0x3c, 0x42, 0x07, 0x90, 0x03, 0xe6, 0x8c, + 0xe9, 0x14, 0x3e, 0x40, 0x04, 0x90, 0x07, 0x66, + 0x80, 0xe9, 0x82, 0x3e, 0x41, 0x2e, 0x90, 0x23, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xda, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xa0, 0x00, 0xc8, 0x00, 0xbe, 0x00, + 0x4d, 0x80, 0x03, 0x20, 0x12, 0xc8, 0x80, 0x3a, + 0x00, 0x0d, 0x80, 0x03, 0xe3, 0x00, 0xd8, 0xd2, + 0x32, 0x20, 0x0e, 0x00, 0x03, 0xc2, 0x01, 0x78, + 0x00, 0x36, 0x00, 0x0c, 0x80, 0x13, 0xe0, 0x10, + 0xc8, 0x00, 0x3e, 0x21, 0x0c, 0x88, 0x0b, 0xa2, + 0x00, 0xe8, 0xc0, 0x3a, 0x20, 0x0c, 0x80, 0x03, + 0x20, 0x00, 0xf8, 0x00, 0x36, 0x00, 0x0f, 0x80, + 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x01, 0xa8, 0x00, 0x8a, 0x00, 0x3a, 0x80, + 0x2c, 0xa0, 0x22, 0x28, 0x00, 0x8e, 0xc2, 0x82, + 0x80, 0x0b, 0xa0, 0x02, 0x79, 0x28, 0x9e, 0x40, + 0x23, 0xb2, 0x01, 0xa0, 0x00, 0x79, 0x04, 0xfe, + 0x40, 0x3b, 0x98, 0x08, 0xa0, 0x02, 0xd9, 0x00, + 0xaa, 0x04, 0x2f, 0xb0, 0x0d, 0xe4, 0x02, 0x19, + 0x00, 0x8e, 0x40, 0x21, 0x90, 0x28, 0xa0, 0x02, + 0x28, 0x00, 0xba, 0x00, 0x3a, 0x80, 0x0b, 0xa0, + 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x4c, 0x00, 0x8b, 0x00, 0x20, 0xc0, + 0x0a, 0x30, 0x02, 0x0c, 0x00, 0x81, 0x00, 0x20, + 0xc0, 0x09, 0x30, 0x02, 0xed, 0x09, 0x00, 0xa4, + 0x01, 0x44, 0x00, 0x91, 0x00, 0x60, 0xc0, 0x0b, + 0x30, 0x02, 0xce, 0x00, 0xb0, 0x60, 0x20, 0x20, + 0x28, 0x30, 0x02, 0xcd, 0x80, 0x9b, 0x00, 0x24, + 0xe0, 0x09, 0x30, 0x18, 0x84, 0x04, 0xa3, 0x80, + 0x28, 0xc0, 0x08, 0x30, 0x12, 0x8c, 0x10, 0xb3, + 0x00, 0x24, 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x5e, + 0x80, 0x83, 0x24, 0x29, 0xc0, 0x08, 0x7a, 0x02, + 0x1c, 0x80, 0xa7, 0xc2, 0x21, 0xc8, 0x0b, 0x72, + 0x02, 0x5c, 0x00, 0x9f, 0x84, 0x21, 0xe0, 0x09, + 0x70, 0x02, 0x5c, 0x20, 0xa7, 0xc0, 0x29, 0xc1, + 0x08, 0x72, 0x02, 0xdd, 0x00, 0xb7, 0x00, 0x05, + 0xd1, 0x09, 0x50, 0x82, 0x1c, 0x00, 0x8d, 0xc2, + 0x23, 0xc0, 0x08, 0x38, 0x02, 0x9c, 0x00, 0xb7, + 0x00, 0x29, 0xc0, 0x0b, 0x70, 0x02, 0xe8, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x5e, + 0xa2, 0xc7, 0xc0, 0x31, 0xf2, 0x0e, 0x7a, 0x0b, + 0x3f, 0x40, 0xc5, 0x84, 0x39, 0xf0, 0x09, 0x7a, + 0x02, 0xde, 0x00, 0xd7, 0x80, 0xb1, 0xe0, 0x0e, + 0x78, 0x83, 0xde, 0x08, 0xb3, 0x80, 0x30, 0xe0, + 0x0c, 0x7f, 0x03, 0xde, 0x00, 0xd7, 0x81, 0x35, + 0xc0, 0x4d, 0x78, 0x0a, 0x9c, 0x04, 0xe7, 0x80, + 0x79, 0xe0, 0x4c, 0x78, 0x0b, 0x9e, 0x00, 0xf7, + 0x80, 0x35, 0xe0, 0x0f, 0x78, 0x03, 0xea, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x15, 0xad, + 0x40, 0xfb, 0x00, 0x02, 0xd0, 0x0f, 0xb7, 0x03, + 0xec, 0x00, 0xd9, 0x00, 0x3e, 0xda, 0x0f, 0xb0, + 0x00, 0x64, 0x00, 0xfb, 0x00, 0x2e, 0xc0, 0x0e, + 0xb1, 0x03, 0x6c, 0x00, 0xf9, 0x00, 0xb2, 0xc0, + 0x0f, 0xb4, 0x03, 0xec, 0x00, 0xeb, 0x10, 0x3e, + 0xc0, 0x0f, 0x30, 0x03, 0xec, 0x00, 0xf3, 0x03, + 0x3e, 0xc0, 0x0f, 0xb1, 0x03, 0x6c, 0x00, 0xed, + 0x09, 0x00, 0xa5, 0x01, 0xfb, 0x00, 0x3a, 0xc0, + 0x0f, 0xb0, 0x03, 0xc2, 0x86, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x85, 0xbe, 0x00, 0xcf, 0xc4, + 0x33, 0xe0, 0x4c, 0xfc, 0x03, 0xfe, 0x00, 0xcc, + 0x80, 0x3f, 0xe0, 0x4e, 0xfc, 0xc3, 0x7e, 0x00, + 0xef, 0x80, 0x37, 0xe0, 0x4f, 0xf8, 0x03, 0x3e, + 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0d, 0xf8, 0x03, + 0x7e, 0x00, 0xcf, 0x80, 0x31, 0xc0, 0x0c, 0xf8, + 0x03, 0x76, 0x00, 0xdf, 0x80, 0x3f, 0xe4, 0x0c, + 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, + 0x0f, 0xf8, 0x03, 0xc0, 0x80, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x18, 0x9c, 0x00, 0x87, 0x10, + 0x23, 0xc0, 0x08, 0x70, 0x02, 0xdc, 0x00, 0x84, + 0x40, 0x2f, 0xc0, 0x0c, 0xf0, 0x03, 0x5c, 0x00, + 0x85, 0x10, 0x2d, 0xc0, 0x0b, 0xf0, 0x02, 0x1c, + 0x40, 0xb6, 0x00, 0x2d, 0x44, 0x0d, 0x70, 0x02, + 0xdc, 0x30, 0xdf, 0x00, 0x35, 0xc4, 0x0f, 0x70, + 0x02, 0xdc, 0x41, 0x87, 0x11, 0x2d, 0xcc, 0x08, + 0x71, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xea, 0x84, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0xa7, 0x00, + 0x21, 0xc0, 0x0a, 0x70, 0x02, 0xdc, 0x00, 0xa4, + 0x10, 0x2d, 0xc0, 0x08, 0x70, 0x02, 0x9c, 0x00, + 0xa7, 0x08, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0x1c, + 0x00, 0xb7, 0x00, 0x2d, 0x80, 0x0b, 0x70, 0x02, + 0xdc, 0x00, 0x87, 0x00, 0xa3, 0x86, 0x08, 0x70, + 0x82, 0xfc, 0x22, 0x97, 0x00, 0x2f, 0x80, 0x08, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x04, 0x8c, 0x00, 0xa3, 0x01, + 0x20, 0xc0, 0x0a, 0x34, 0x02, 0xec, 0x00, 0xa0, + 0x02, 0x2c, 0xd0, 0x09, 0x30, 0x02, 0x0c, 0x20, + 0x83, 0xe0, 0xed, 0x09, 0x00, 0xa6, 0x01, 0x2c, + 0xd0, 0x0b, 0x30, 0x22, 0x0c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xce, 0x08, 0x93, + 0xe0, 0x20, 0xd0, 0x0b, 0x38, 0x02, 0xcf, 0x08, + 0x82, 0x00, 0x2c, 0x82, 0x28, 0xb0, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x15, 0xfc, 0x00, 0xef, 0x00, 0xb3, 0xc0, 0x0e, + 0xf0, 0x03, 0xfc, 0x02, 0xeb, 0x00, 0x3d, 0xf8, + 0x0c, 0xf0, 0x02, 0xac, 0x00, 0xeb, 0x80, 0x2e, + 0xd0, 0x0f, 0xf0, 0x02, 0x2c, 0x00, 0xbb, 0x00, + 0x3e, 0xc1, 0x09, 0xf0, 0x03, 0x6c, 0x50, 0x8f, + 0xc2, 0x22, 0xe0, 0x0c, 0xb4, 0x02, 0x6c, 0x02, + 0xdb, 0x80, 0x2e, 0xf8, 0x0c, 0xf0, 0x23, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x8c, 0x00, 0xd3, 0x00, 0x3e, 0xc0, 0x09, + 0xb8, 0x83, 0xec, 0x00, 0x59, 0x40, 0x3e, 0xc0, + 0x0e, 0xb0, 0x0b, 0xef, 0x00, 0xfb, 0x42, 0x3e, + 0xc4, 0x0f, 0xb0, 0x03, 0xed, 0x00, 0xfb, 0x00, + 0x3e, 0x80, 0x0f, 0xb0, 0x03, 0xed, 0x00, 0xfb, + 0x10, 0x3e, 0xd8, 0x0f, 0xb0, 0x83, 0xed, 0x80, + 0xfb, 0x80, 0x3e, 0x81, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x10, 0xbc, 0x00, 0xcf, 0x00, 0x33, 0xc0, 0x0f, + 0xf0, 0x43, 0x3c, 0x00, 0xc5, 0x00, 0x33, 0xc2, + 0x0c, 0xf0, 0x03, 0xfe, 0x80, 0xfd, 0x00, 0x2f, + 0xe2, 0x17, 0xf0, 0x02, 0xbf, 0x00, 0x56, 0x80, + 0xb3, 0x60, 0x0f, 0xf0, 0x03, 0xb4, 0x00, 0xcf, + 0x00, 0x23, 0xc0, 0x03, 0xf0, 0x13, 0xbc, 0x00, + 0xcf, 0x00, 0x3f, 0xe0, 0x08, 0xf0, 0x03, 0x3c, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0xed, 0x09, 0x00, + 0xa7, 0x01, 0x0f, 0xf0, 0x03, 0xc0, 0x44, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xa1, 0x04, 0x6c, 0x00, + 0x8b, 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, + 0x02, 0x89, 0x00, 0x22, 0xc0, 0x0a, 0xb0, 0x02, + 0xee, 0x00, 0xbb, 0xd9, 0x2e, 0xd1, 0x9f, 0xb0, + 0x02, 0x2e, 0x80, 0x9b, 0x60, 0x22, 0xe0, 0x8b, + 0xb0, 0x22, 0x8c, 0x44, 0xe3, 0x00, 0x02, 0xc4, + 0x0b, 0x33, 0x02, 0x8c, 0x20, 0x8b, 0x00, 0x2c, + 0x20, 0x08, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, + 0x8b, 0x02, 0x26, 0xc0, 0x0b, 0x30, 0x02, 0x2c, + 0x00, 0x88, 0x80, 0x22, 0xc0, 0x09, 0xb0, 0x06, + 0xe4, 0x00, 0xbb, 0x00, 0x2e, 0xc4, 0x0b, 0x30, + 0x02, 0x2c, 0x00, 0xb9, 0x20, 0x66, 0xc8, 0x0b, + 0x30, 0x00, 0x2c, 0x20, 0x8b, 0x00, 0x0a, 0x42, + 0x0b, 0xb0, 0x02, 0xac, 0x40, 0x8b, 0x24, 0x2e, + 0xc8, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x0c, 0x00, + 0x83, 0x00, 0xa4, 0xc0, 0x0b, 0x30, 0x4a, 0x0c, + 0x00, 0x81, 0x00, 0x22, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x01, 0x2c, 0x80, 0x4a, 0x30, + 0x22, 0x88, 0x00, 0xb3, 0x00, 0x24, 0xc0, 0x09, + 0x30, 0x02, 0x0c, 0x08, 0xbb, 0x00, 0xa8, 0x40, + 0x0b, 0x30, 0x32, 0x0c, 0x00, 0x83, 0x00, 0x2c, + 0xa1, 0x0b, 0x30, 0x0a, 0x0c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc2, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x0d, 0x5c, 0x00, + 0xc7, 0x00, 0x37, 0xc0, 0x0f, 0xf0, 0x03, 0x1c, + 0x00, 0x89, 0x00, 0x33, 0xc0, 0x0d, 0xf0, 0x03, + 0xec, 0x04, 0xfb, 0x00, 0x3e, 0xc0, 0x8b, 0xf0, + 0xed, 0x09, 0x00, 0xa8, 0x01, 0x07, 0x2c, 0x00, + 0xfb, 0x00, 0x36, 0xc0, 0x0f, 0xf0, 0x13, 0xa8, + 0x01, 0xcb, 0x00, 0xba, 0x40, 0x0f, 0xb0, 0x03, + 0xa8, 0x00, 0xcb, 0x00, 0x3e, 0x80, 0x2f, 0xb0, + 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x95, 0xfc, 0x00, 0xff, 0x00, 0x3b, + 0xc0, 0x0f, 0xf0, 0x43, 0xfc, 0x00, 0xfc, 0x01, + 0x3f, 0xc0, 0x0e, 0xf0, 0x03, 0xd0, 0x00, 0xfc, + 0x00, 0x3f, 0x00, 0x0f, 0xf0, 0x03, 0x70, 0x11, + 0xdc, 0x03, 0x3b, 0x00, 0x0f, 0xf0, 0x03, 0xdc, + 0x01, 0xef, 0x00, 0x37, 0x41, 0x0f, 0xe0, 0x03, + 0xdc, 0x02, 0xfe, 0x00, 0x3d, 0x00, 0x0c, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x05, 0xfc, 0x40, 0xc7, 0x00, 0x2f, + 0x4a, 0x8c, 0x40, 0x23, 0x34, 0x40, 0xcf, 0x00, + 0x3f, 0x84, 0x4e, 0xe0, 0x23, 0xf8, 0x00, 0xfe, + 0x00, 0x3f, 0x40, 0x0c, 0x70, 0x03, 0x3c, 0x00, + 0xef, 0x00, 0x31, 0xc0, 0x0d, 0xf0, 0x03, 0xf0, + 0x40, 0xdf, 0x00, 0x33, 0xc0, 0x0f, 0xc1, 0x0b, + 0xb1, 0x80, 0xfc, 0x20, 0x3f, 0x00, 0x2c, 0xc1, + 0x83, 0x30, 0x48, 0xcc, 0x39, 0x1b, 0x0c, 0x0c, + 0xc6, 0xa3, 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x10, 0xec, 0x80, 0x8b, 0x01, 0x22, + 0x18, 0x08, 0x90, 0x02, 0x24, 0x80, 0xab, 0x00, + 0x2e, 0xc8, 0x08, 0xa0, 0x02, 0xec, 0x00, 0xba, + 0x00, 0x2e, 0x00, 0x48, 0x80, 0x00, 0xa0, 0x00, + 0xb8, 0x00, 0x22, 0x00, 0x0d, 0xb0, 0x42, 0xec, + 0x00, 0x87, 0x58, 0x2a, 0xc0, 0x0b, 0x25, 0x02, + 0x20, 0x80, 0xb0, 0x28, 0x2e, 0x00, 0x08, 0x82, + 0x02, 0x21, 0x40, 0xa8, 0x64, 0x22, 0x18, 0x08, + 0x84, 0x02, 0x20, 0xed, 0x09, 0x00, 0xa9, 0x01, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, + 0xcc, 0x02, 0x89, 0x02, 0xa8, 0x02, 0x08, 0x10, + 0x02, 0x0c, 0x00, 0x83, 0x00, 0x2c, 0x88, 0x0a, + 0x20, 0x02, 0xcc, 0x00, 0xb2, 0x00, 0x2e, 0x40, + 0x28, 0xb0, 0x00, 0x0c, 0x00, 0xb3, 0x00, 0xa6, + 0xc0, 0x08, 0x30, 0x02, 0xe4, 0x94, 0xa3, 0x20, + 0x24, 0xc0, 0xc3, 0x12, 0x02, 0xc1, 0x80, 0x90, + 0x31, 0x2c, 0x0e, 0x08, 0x00, 0x02, 0x40, 0x81, + 0xa1, 0x00, 0x20, 0x18, 0x48, 0x22, 0x0a, 0xa2, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x11, + 0xac, 0x00, 0x89, 0x00, 0x22, 0x20, 0x08, 0x90, + 0x8a, 0x2c, 0x00, 0x2b, 0x00, 0x2c, 0xc1, 0x28, + 0xb1, 0xa2, 0xec, 0x20, 0xba, 0x00, 0x0e, 0x00, + 0x08, 0x80, 0x1a, 0x20, 0x00, 0xb8, 0x00, 0x26, + 0x00, 0x0b, 0xb0, 0x02, 0xec, 0x84, 0xab, 0x04, + 0x2e, 0xc0, 0x0b, 0x80, 0x02, 0x6c, 0x94, 0xba, + 0x08, 0x2c, 0x80, 0x08, 0xb0, 0x02, 0x68, 0x00, + 0xab, 0x00, 0x6a, 0x50, 0x08, 0x20, 0x02, 0xb0, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, + 0xec, 0x00, 0xc2, 0xc0, 0x3a, 0x20, 0x2c, 0x88, + 0x03, 0x2a, 0x40, 0xcb, 0x00, 0x3e, 0xc8, 0x2e, + 0xb4, 0x02, 0xec, 0x00, 0xfa, 0x00, 0x3c, 0x40, + 0x0c, 0xb0, 0x03, 0x2c, 0x00, 0xe3, 0x00, 0x36, + 0xc0, 0x0c, 0xb8, 0x03, 0xc8, 0x02, 0xeb, 0x00, + 0x36, 0xc0, 0x0f, 0x82, 0x03, 0xe1, 0x00, 0xf8, + 0xd0, 0x3e, 0x26, 0x04, 0x8c, 0x03, 0x63, 0x08, + 0xca, 0x40, 0x72, 0x00, 0x0c, 0x84, 0xa1, 0x90, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, + 0xbc, 0x00, 0xff, 0xa0, 0x3c, 0x81, 0x0f, 0xcc, + 0x83, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf8, 0x83, 0xfc, 0x54, 0xfe, 0x05, 0x3f, 0x00, + 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0xed, 0x09, + 0x00, 0xaa, 0x01, 0x00, 0x3b, 0x02, 0x0d, 0xf9, + 0x03, 0xf6, 0x00, 0xc7, 0x00, 0x3b, 0xc0, 0x0f, + 0x60, 0x03, 0xa6, 0x00, 0xfd, 0x00, 0x3f, 0x40, + 0x0f, 0x7c, 0x8b, 0xae, 0x48, 0x9c, 0x00, 0xf7, + 0x28, 0x8f, 0xd9, 0x03, 0x78, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, 0x00, 0xf9, + 0x88, 0x3a, 0x80, 0x0c, 0x80, 0x03, 0x28, 0x00, + 0xcb, 0x00, 0x3e, 0x40, 0x0d, 0xb4, 0x03, 0xed, + 0x08, 0xfa, 0x08, 0x3e, 0x48, 0x0f, 0xb0, 0x03, + 0x2c, 0x08, 0xfb, 0x00, 0x3e, 0xc0, 0x0c, 0xb2, + 0x03, 0xec, 0x04, 0xcb, 0x00, 0xba, 0xc0, 0x0f, + 0xb0, 0x03, 0x29, 0x22, 0xcb, 0x42, 0x32, 0xc0, + 0x0f, 0x84, 0x03, 0x05, 0x02, 0xc2, 0x40, 0xb2, + 0x95, 0x9d, 0xa0, 0x83, 0x10, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x04, 0xb9, + 0xc0, 0x22, 0xb4, 0x0a, 0x04, 0x02, 0x2f, 0x80, + 0xdb, 0x00, 0x2e, 0x40, 0x08, 0xb8, 0x81, 0xac, + 0x00, 0xba, 0x40, 0x2e, 0x30, 0x0b, 0x0d, 0x8a, + 0x23, 0x40, 0xb8, 0x00, 0x2c, 0x00, 0x08, 0xbc, + 0x02, 0xe4, 0x00, 0x8f, 0x00, 0x36, 0xc1, 0x0b, + 0xa1, 0x02, 0x2d, 0x24, 0x8b, 0x90, 0x22, 0xc0, + 0x0b, 0xbc, 0x82, 0x2f, 0xc0, 0xca, 0x14, 0x22, + 0xd4, 0x08, 0xbc, 0x02, 0x32, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x05, 0x6c, 0x00, 0xb3, + 0x40, 0x20, 0x60, 0x48, 0x1d, 0x02, 0x2c, 0x00, + 0xa3, 0x00, 0x2c, 0xc0, 0x29, 0x38, 0x42, 0xcc, + 0x00, 0x92, 0x40, 0x2c, 0x74, 0x0b, 0x34, 0x02, + 0x8d, 0x40, 0xb3, 0x00, 0x2c, 0xf0, 0x18, 0x3c, + 0x02, 0xc8, 0x00, 0x03, 0x00, 0x28, 0xc0, 0x0b, + 0x04, 0x0a, 0x42, 0x00, 0x80, 0x10, 0x20, 0x00, + 0x0b, 0x04, 0x02, 0x80, 0x10, 0x90, 0x50, 0x06, + 0xd0, 0x08, 0x1d, 0x00, 0xb8, 0x00, 0x50, 0x00, + 0x00, 0xed, 0x09, 0x00, 0xab, 0x01, 0x00, 0x00, + 0x20, 0x01, 0x1e, 0x08, 0xbd, 0x90, 0xa1, 0xe0, + 0x0a, 0x58, 0x02, 0x1f, 0x00, 0xb7, 0x81, 0x2d, + 0xe0, 0x08, 0x78, 0x62, 0xde, 0x00, 0xb6, 0x80, + 0x2d, 0x24, 0x0b, 0xc9, 0x02, 0x12, 0x00, 0x34, + 0x80, 0x2f, 0x22, 0x18, 0x78, 0xc2, 0xde, 0x00, + 0x87, 0x82, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0x1a, + 0x10, 0x87, 0x80, 0x21, 0xe0, 0x0b, 0x08, 0x2a, + 0x96, 0x44, 0xa4, 0x90, 0x24, 0xe4, 0x09, 0x18, + 0x02, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x08, 0x0c, 0x40, 0xf1, 0x10, 0x20, 0xc2, + 0x0c, 0x00, 0x03, 0x2c, 0x00, 0xe3, 0x00, 0x3e, + 0xc8, 0x2d, 0x33, 0x03, 0xc4, 0x00, 0xd2, 0x00, + 0x3c, 0x44, 0x0f, 0x30, 0x02, 0x8c, 0x00, 0xf3, + 0x00, 0x3c, 0xc0, 0x2c, 0x32, 0x13, 0xec, 0x02, + 0xc3, 0x00, 0x38, 0xc4, 0x0b, 0x10, 0x03, 0x05, + 0x00, 0xc1, 0x20, 0x30, 0x40, 0xcf, 0x30, 0x03, + 0x8d, 0x40, 0xd9, 0x50, 0xb4, 0x80, 0x04, 0x10, + 0x0b, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x1d, 0xbc, 0x00, 0xfd, 0x12, 0x1f, 0xc4, + 0x2f, 0xd1, 0x0b, 0xfc, 0x00, 0xdf, 0x00, 0x3f, + 0xc0, 0x0f, 0xd1, 0x03, 0xbc, 0x40, 0xbe, 0x00, + 0x3f, 0x05, 0x0f, 0xc0, 0x23, 0xf0, 0x00, 0xfc, + 0x10, 0x3f, 0x24, 0x0f, 0xf0, 0x23, 0xfc, 0x40, + 0xff, 0x00, 0xb7, 0xc0, 0x0f, 0xd0, 0x03, 0xfc, + 0x04, 0xff, 0x00, 0x2f, 0xc0, 0x0f, 0xf0, 0x03, + 0x7c, 0x50, 0xdf, 0x10, 0x3b, 0xc1, 0x0e, 0xd1, + 0x03, 0x50, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x05, 0xec, 0x00, 0xfb, 0x00, 0x36, 0x40, + 0x0c, 0x80, 0x03, 0xe8, 0x00, 0xdb, 0x00, 0x3e, + 0xc0, 0x0c, 0xb0, 0x03, 0xce, 0x00, 0x42, 0x80, + 0x30, 0x40, 0x2c, 0x38, 0x0a, 0x2c, 0x00, 0xf3, + 0x00, 0xb0, 0xe0, 0x0c, 0xed, 0x09, 0x00, 0xac, + 0x01, 0xb8, 0x03, 0x28, 0x08, 0xdb, 0x58, 0x36, + 0xc0, 0x0f, 0x80, 0x03, 0xee, 0x00, 0xca, 0x80, + 0x32, 0x80, 0x9d, 0xb0, 0x0b, 0x28, 0x00, 0xcb, + 0x80, 0x72, 0x40, 0x0c, 0xa0, 0x03, 0xea, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, + 0x01, 0xb5, 0x00, 0x31, 0xc0, 0x0d, 0x40, 0x02, + 0xfc, 0x00, 0x87, 0x00, 0x2d, 0xc0, 0xc8, 0x70, + 0x02, 0xdc, 0x00, 0xd6, 0x00, 0x21, 0x00, 0x08, + 0x40, 0x02, 0x10, 0x00, 0xb4, 0x00, 0x21, 0x01, + 0x0a, 0x70, 0x0a, 0x3c, 0x00, 0xaf, 0x00, 0x29, + 0xc0, 0x0b, 0x70, 0x22, 0xdc, 0x00, 0xc7, 0x00, + 0x21, 0xc0, 0x8b, 0xf0, 0x02, 0x1c, 0x00, 0x85, + 0x04, 0x21, 0x40, 0x08, 0x70, 0x00, 0xd2, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, + 0x00, 0xbd, 0x88, 0x20, 0xe0, 0x1a, 0x48, 0x02, + 0xda, 0x00, 0x97, 0x80, 0x27, 0x60, 0x08, 0x78, + 0x02, 0xfe, 0x20, 0x8e, 0x82, 0x27, 0x60, 0x08, + 0x78, 0x02, 0x1e, 0x14, 0xbf, 0x80, 0x29, 0xe0, + 0x08, 0x78, 0x82, 0x5e, 0x04, 0xb7, 0x84, 0x25, + 0xe0, 0x0b, 0x7c, 0x02, 0xde, 0x02, 0x83, 0x84, + 0x61, 0xe0, 0x0b, 0x78, 0x02, 0x1e, 0x00, 0x97, + 0xc0, 0x21, 0xa2, 0xaa, 0x68, 0x02, 0xf0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xec, + 0x00, 0xb3, 0xc0, 0x26, 0xc4, 0x0b, 0x28, 0x02, + 0xed, 0x00, 0x83, 0x00, 0x2e, 0x55, 0x08, 0x10, + 0x02, 0xcc, 0x00, 0x92, 0x00, 0x24, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0xb0, 0x02, 0x28, 0x00, + 0x0a, 0x18, 0x12, 0x4c, 0x00, 0xa3, 0x04, 0x28, + 0xc0, 0x0b, 0x30, 0x02, 0xcd, 0x00, 0x83, 0xa0, + 0x60, 0xf4, 0x0b, 0x3d, 0x02, 0x2f, 0x04, 0x93, + 0x40, 0x20, 0xe0, 0x0a, 0x39, 0x42, 0xd2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xed, + 0x09, 0x00, 0xad, 0x01, 0xa8, 0x00, 0xf6, 0xc0, + 0x33, 0xb0, 0x0e, 0xec, 0x23, 0xfa, 0x8c, 0xda, + 0x02, 0x37, 0xa0, 0x2c, 0x64, 0x03, 0xf9, 0x00, + 0xca, 0x00, 0x36, 0x80, 0x0c, 0xa0, 0x03, 0x28, + 0x11, 0xf2, 0x00, 0x3a, 0x80, 0x4c, 0xa0, 0x03, + 0x7a, 0x82, 0xda, 0x01, 0x36, 0x81, 0x1f, 0xe0, + 0x03, 0xf8, 0x40, 0xce, 0xa0, 0xb3, 0x94, 0x0d, + 0xe0, 0x03, 0x3a, 0x02, 0xde, 0x40, 0xb3, 0xa0, + 0x0e, 0xe5, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0xe0, 0x10, 0xf8, 0x41, + 0xba, 0x00, 0x01, 0x89, 0x03, 0xe1, 0x80, 0xf8, + 0x00, 0x3e, 0x02, 0x0f, 0x88, 0x02, 0xe2, 0x04, + 0xf8, 0x00, 0xbb, 0x00, 0x0f, 0xc0, 0x03, 0xf0, + 0x01, 0xfc, 0x00, 0x07, 0x00, 0x4f, 0x84, 0x43, + 0xa0, 0x00, 0xf0, 0x00, 0x3e, 0x00, 0x0f, 0x84, + 0x03, 0xe0, 0x02, 0xe8, 0x00, 0x3c, 0x10, 0x0f, + 0x84, 0x83, 0xe1, 0xc0, 0xe8, 0x20, 0x3e, 0x00, + 0x89, 0x80, 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xc9, 0x0a, + 0xba, 0x72, 0xac, 0x90, 0x03, 0x24, 0x00, 0xc9, + 0x00, 0x3e, 0x40, 0x4f, 0x90, 0x03, 0x24, 0x10, + 0x79, 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xe5, + 0x00, 0xf9, 0x80, 0x3a, 0x49, 0x0f, 0x92, 0x13, + 0xe4, 0x00, 0xc9, 0x00, 0xba, 0x40, 0x0f, 0x91, + 0x02, 0x26, 0x00, 0xf9, 0x20, 0x3e, 0x40, 0x0c, + 0x92, 0x03, 0x26, 0x00, 0xc9, 0x40, 0x3c, 0x60, + 0x2c, 0x90, 0x23, 0x02, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, 0x64, 0x04, 0xa9, 0x08, + 0x2a, 0x70, 0x28, 0x1c, 0x22, 0xa4, 0x00, 0xd9, + 0x00, 0x2e, 0x41, 0x08, 0x90, 0x0a, 0x24, 0x00, + 0xb9, 0x00, 0x2c, 0x40, 0x0a, 0x90, 0x02, 0xe7, + 0x00, 0xb9, 0x40, 0x22, 0x78, 0x0b, 0x9c, 0x02, + 0xe4, 0x00, 0xed, 0x09, 0x00, 0xae, 0x01, 0x89, + 0x00, 0x22, 0x40, 0x0b, 0x9c, 0x02, 0x27, 0x40, + 0xb9, 0x00, 0x2e, 0x42, 0x08, 0x90, 0x0a, 0x27, + 0x42, 0x89, 0x00, 0x2e, 0x50, 0x08, 0x94, 0x02, + 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x24, 0x00, 0x8b, 0x10, 0x2a, 0xd0, 0x09, + 0x98, 0x0a, 0x24, 0x40, 0x89, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x08, 0xd0, 0x02, 0xf4, 0x00, 0xad, 0x10, + 0xa3, 0x40, 0x0b, 0x90, 0x02, 0xc4, 0x00, 0x89, + 0x00, 0x2a, 0x40, 0x0b, 0x10, 0x02, 0xa5, 0x00, + 0xb9, 0x00, 0x2a, 0x44, 0x08, 0x34, 0x02, 0x24, + 0x21, 0x89, 0x00, 0x2e, 0x58, 0x09, 0x11, 0x00, + 0x06, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x05, 0x00, 0xa1, 0x00, 0xe8, 0x51, 0x29, + 0x98, 0x22, 0x8d, 0x00, 0x91, 0x00, 0x2c, 0x50, + 0x28, 0xb0, 0x02, 0x04, 0x00, 0xb1, 0x02, 0x6d, + 0x40, 0x0a, 0x50, 0x42, 0xd6, 0x00, 0xb5, 0x80, + 0x21, 0x40, 0x0b, 0x10, 0x02, 0xc5, 0x06, 0x81, + 0x40, 0x20, 0x40, 0x0b, 0x14, 0x0a, 0x85, 0x00, + 0x91, 0x40, 0x2c, 0x50, 0x00, 0x14, 0x02, 0x05, + 0x01, 0x83, 0x40, 0x2c, 0x50, 0x09, 0x14, 0x2a, + 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, + 0x0d, 0x60, 0x00, 0xc8, 0x00, 0xba, 0x00, 0x4d, + 0x80, 0x23, 0x20, 0x02, 0xc8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0x20, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x8c, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x33, 0x00, 0x0f, 0xa0, 0x23, 0xe0, 0x00, 0xc8, + 0x00, 0x3a, 0x00, 0x0f, 0xa0, 0x03, 0x80, 0x00, + 0xfa, 0x00, 0x3a, 0x00, 0x0c, 0x80, 0x03, 0x00, + 0x00, 0xc0, 0x00, 0x3c, 0x00, 0x0d, 0xa0, 0x03, + 0x2e, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x1d, 0xe4, 0x00, 0xf7, 0x04, 0xed, 0x09, 0x00, + 0xaf, 0x01, 0x3f, 0x51, 0x2e, 0xd0, 0x03, 0xf4, + 0x00, 0xf9, 0x00, 0x3d, 0x40, 0x0f, 0xd0, 0x03, + 0xf4, 0x00, 0xf9, 0x03, 0x3e, 0x40, 0x0f, 0x90, + 0x41, 0xe4, 0x04, 0xf9, 0x00, 0x3e, 0x40, 0x0b, + 0x50, 0x13, 0xf4, 0x00, 0xf9, 0x44, 0x3e, 0x40, + 0x0f, 0xd4, 0x03, 0x75, 0x00, 0xfd, 0x44, 0x3f, + 0x50, 0x2f, 0xd4, 0x03, 0xf5, 0x00, 0xfd, 0x40, + 0x3f, 0x50, 0x0e, 0xd4, 0x03, 0xe6, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, 0x00, + 0xf5, 0x00, 0x33, 0x40, 0x0c, 0xd0, 0x03, 0xf4, + 0x40, 0xc9, 0x00, 0x3e, 0x40, 0x0f, 0xd0, 0x01, + 0x84, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x07, 0x90, + 0x03, 0xd4, 0x00, 0x6d, 0x00, 0x3f, 0x40, 0x07, + 0x50, 0x03, 0xe4, 0x40, 0xc9, 0x20, 0x3e, 0x40, + 0x0f, 0xd3, 0x03, 0x3c, 0x00, 0xcd, 0x00, 0x3f, + 0x44, 0x0f, 0xd2, 0x03, 0x34, 0xa0, 0xfd, 0x30, + 0x33, 0x40, 0x0c, 0xd0, 0x03, 0x06, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x80, + 0xb8, 0x00, 0xa2, 0x12, 0x28, 0x80, 0x02, 0xe0, + 0x00, 0xa8, 0x00, 0x2e, 0x08, 0x88, 0x80, 0x07, + 0xa0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0xc0, + 0x02, 0xe0, 0x00, 0x88, 0x04, 0x3e, 0x00, 0x0b, + 0x80, 0x02, 0xc0, 0x00, 0xd8, 0x28, 0x2e, 0x00, + 0x0b, 0x83, 0x02, 0x21, 0x22, 0x80, 0x08, 0x2e, + 0x04, 0x4b, 0x82, 0x8b, 0x60, 0x88, 0xb8, 0x34, + 0x22, 0x92, 0x28, 0x80, 0x83, 0x4e, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0xa0, + 0xb9, 0x00, 0x20, 0xec, 0x08, 0x30, 0x02, 0xc4, + 0x00, 0x81, 0x00, 0x2c, 0x4b, 0x0b, 0x18, 0x02, + 0x84, 0x00, 0xb5, 0x00, 0x2d, 0x40, 0x0b, 0x50, + 0x02, 0xc4, 0x00, 0xa1, 0x00, 0x68, 0x40, 0x0b, + 0x10, 0x02, 0xe4, 0x00, 0xa1, 0x30, 0x2c, 0x40, + 0xed, 0x09, 0x00, 0xb0, 0x01, 0x0b, 0x12, 0x22, + 0x0c, 0xc0, 0x81, 0x90, 0x2c, 0x40, 0x0b, 0x13, + 0x02, 0x44, 0xb0, 0xb1, 0x20, 0x28, 0x4c, 0x0a, + 0x11, 0x02, 0x82, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x22, + 0x40, 0x08, 0xb2, 0xa2, 0xe4, 0x40, 0xa9, 0x00, + 0x2c, 0x49, 0x08, 0x90, 0x02, 0xa4, 0x00, 0xb9, + 0x00, 0x2f, 0x40, 0x0b, 0xd0, 0x22, 0xe4, 0x00, + 0x8b, 0x00, 0x6e, 0xc0, 0x0b, 0xb0, 0x42, 0xe5, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, + 0x24, 0x00, 0x89, 0x21, 0x2e, 0x62, 0x0b, 0x12, + 0x02, 0x2d, 0x01, 0xb1, 0x00, 0x2a, 0x44, 0x0a, + 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf1, 0x40, 0x32, + 0x60, 0x0c, 0x90, 0x03, 0xe6, 0x00, 0xc9, 0x00, + 0x3e, 0x40, 0x3f, 0x91, 0x43, 0xa6, 0x80, 0xf9, + 0x00, 0x1e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x09, + 0xe9, 0x00, 0x3a, 0x40, 0x0f, 0x91, 0x01, 0xe5, + 0x00, 0xe9, 0x00, 0x3e, 0x40, 0x0f, 0x97, 0x0b, + 0x26, 0x80, 0xc9, 0x80, 0x3e, 0x40, 0x0f, 0x96, + 0x02, 0x64, 0x00, 0xf9, 0xc8, 0x3a, 0x60, 0x4e, + 0x90, 0x0b, 0xa8, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0xa4, 0x00, 0xf9, 0x90, 0x3c, + 0x50, 0x0f, 0x90, 0x03, 0xe6, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x2f, 0x98, 0x43, 0xe6, 0x80, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3a, 0x40, 0x0f, 0x98, 0x03, 0xe4, + 0x00, 0xd9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x23, + 0xe4, 0x80, 0xf9, 0x08, 0x3e, 0x40, 0x0f, 0x90, + 0x13, 0xe6, 0x60, 0xf9, 0x24, 0xb4, 0x61, 0x0d, + 0x92, 0x83, 0x4a, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x10, 0xa0, 0x00, 0xd8, 0x80, 0x32, + 0x20, 0x0c, 0x80, 0xed, 0x09, 0x00, 0xb1, 0x01, + 0x03, 0xe0, 0x20, 0xc8, 0x00, 0x3e, 0x00, 0x0d, + 0x88, 0x03, 0xa0, 0x08, 0xcc, 0x00, 0x3f, 0x00, + 0x0c, 0xc0, 0x23, 0xe0, 0x82, 0xc8, 0x04, 0x3e, + 0x08, 0x0f, 0x89, 0x23, 0x20, 0x04, 0xc8, 0x00, + 0xba, 0x00, 0x0f, 0x80, 0x03, 0x20, 0x80, 0xf8, + 0x00, 0x32, 0x30, 0x2e, 0x81, 0x03, 0xe1, 0x00, + 0xf8, 0x00, 0xb2, 0x00, 0x2c, 0x80, 0x03, 0x0a, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, + 0x28, 0x00, 0x8e, 0x40, 0x23, 0x80, 0xaa, 0xe0, + 0x02, 0xfb, 0x00, 0x8a, 0x02, 0x2e, 0x80, 0x0a, + 0xe4, 0x02, 0xe8, 0x02, 0xca, 0x00, 0x6e, 0x80, + 0x0a, 0xa0, 0x02, 0xdb, 0x08, 0x8e, 0xa1, 0x2f, + 0xa0, 0x0b, 0xec, 0x03, 0x48, 0x00, 0xda, 0x00, + 0x36, 0x80, 0x0b, 0xe0, 0x02, 0x38, 0x00, 0xee, + 0xe1, 0x23, 0xa0, 0x88, 0xe8, 0x02, 0xf8, 0x00, + 0xbe, 0x00, 0x03, 0xb0, 0x00, 0xe0, 0x0a, 0x0a, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x4c, 0x00, 0x93, 0x10, 0x20, 0xc0, 0x08, 0x00, + 0x02, 0xec, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x09, + 0x30, 0x12, 0xc8, 0x04, 0x80, 0x00, 0x2c, 0x00, + 0x08, 0x00, 0x02, 0xc3, 0x00, 0x80, 0x01, 0x2c, + 0x21, 0x0b, 0x10, 0x52, 0x8c, 0x00, 0x03, 0x00, + 0x28, 0xc0, 0x0b, 0xb8, 0x02, 0x2c, 0x10, 0xa3, + 0xc0, 0x20, 0xe0, 0x0a, 0x38, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x20, 0xf2, 0x00, 0xb0, 0x00, 0x0a, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, + 0x1e, 0x08, 0x8f, 0x00, 0x21, 0xc0, 0x0a, 0x40, + 0x02, 0xdc, 0x24, 0x87, 0x02, 0x2d, 0xc8, 0x4a, + 0x74, 0x02, 0xda, 0x00, 0x85, 0x00, 0x2d, 0xe0, + 0x0a, 0x70, 0x12, 0xdd, 0x00, 0x84, 0x02, 0x6d, + 0xc2, 0x1b, 0xf8, 0x02, 0xdc, 0x80, 0x97, 0x90, + 0x25, 0xc0, 0x0b, 0x70, 0x8a, 0x1c, 0xed, 0x09, + 0x00, 0xb2, 0x01, 0x00, 0xa7, 0x80, 0x21, 0xe3, + 0x08, 0x50, 0x22, 0x5c, 0x20, 0xb5, 0x00, 0x21, + 0xc2, 0x08, 0x30, 0x02, 0x28, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x08, 0x3f, 0x80, 0xd7, + 0x80, 0x33, 0xe0, 0x28, 0x78, 0x13, 0xfe, 0x02, + 0xc7, 0x80, 0x3f, 0xf0, 0x0d, 0x78, 0x03, 0x9a, + 0x00, 0xc4, 0x80, 0x2d, 0x20, 0x08, 0x48, 0x02, + 0xde, 0x00, 0x47, 0x80, 0x3d, 0xe0, 0x0b, 0x78, + 0x43, 0x9e, 0xa2, 0xcf, 0xa0, 0x39, 0xe0, 0x0f, + 0x38, 0x03, 0x1e, 0x00, 0xe7, 0x80, 0xb3, 0xe0, + 0x0e, 0x68, 0x03, 0xde, 0x00, 0xf3, 0x80, 0x30, + 0xa0, 0x08, 0x68, 0x03, 0x2a, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, 0xfb, + 0x00, 0x8e, 0x40, 0x0f, 0xa0, 0x03, 0xec, 0x08, + 0xfb, 0x00, 0x3e, 0xd8, 0x2d, 0xb0, 0x03, 0xe8, + 0x00, 0xe9, 0x00, 0x3c, 0xc1, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x23, 0x6d, 0x40, 0xfb, 0x08, 0x3e, 0xc0, 0x0f, + 0xa0, 0x43, 0xe8, 0x00, 0xeb, 0x00, 0x3e, 0xc0, + 0x0f, 0x90, 0x03, 0xec, 0x00, 0xfa, 0x02, 0x3e, + 0x00, 0x0f, 0x90, 0x03, 0xc2, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xe7, + 0x80, 0xbb, 0xe0, 0x4c, 0xc8, 0x03, 0xde, 0x00, + 0xcf, 0x90, 0x3f, 0xf1, 0x0c, 0xe8, 0x07, 0x78, + 0x08, 0xf4, 0x90, 0x33, 0x20, 0x0f, 0xc8, 0x13, + 0x1e, 0x06, 0xce, 0x90, 0x3f, 0xe0, 0x07, 0xf8, + 0x03, 0xfe, 0x00, 0xff, 0x80, 0x33, 0xe0, 0x0f, + 0xd8, 0x03, 0x7e, 0x00, 0xcf, 0x80, 0x33, 0x20, + 0x0c, 0xf8, 0x03, 0xfe, 0x00, 0x7f, 0x80, 0x33, + 0x60, 0x0c, 0xf8, 0x03, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x11, 0xbc, 0x00, 0x86, + 0x20, 0x35, 0xc0, 0x08, 0x41, 0x02, 0xdd, 0x00, + 0x87, 0xed, 0x09, 0x00, 0xb3, 0x01, 0x00, 0x2d, + 0xc4, 0x48, 0x74, 0x07, 0x18, 0x88, 0xb5, 0x00, + 0x21, 0xc8, 0x4b, 0x70, 0x02, 0x55, 0x00, 0x86, + 0x00, 0x2d, 0x84, 0x0b, 0x61, 0x02, 0xdc, 0x80, + 0xb7, 0x00, 0x21, 0xc0, 0x0b, 0x51, 0x82, 0xdc, + 0x02, 0x8c, 0x00, 0x21, 0x00, 0x0a, 0x74, 0x02, + 0xd8, 0x00, 0xb5, 0x00, 0x35, 0x08, 0x08, 0x60, + 0x02, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x00, 0xae, 0x00, 0x69, 0xd0, + 0x08, 0x70, 0x82, 0xfc, 0x00, 0x87, 0x04, 0x2d, + 0xc0, 0x28, 0x60, 0x0a, 0x18, 0x40, 0xb4, 0x01, + 0x21, 0x00, 0x1b, 0x48, 0x02, 0x78, 0x00, 0x85, + 0x04, 0x6d, 0x42, 0x0b, 0x50, 0x02, 0xdc, 0x01, + 0xb7, 0x00, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xc4, + 0x00, 0x87, 0x08, 0x21, 0x96, 0x08, 0x40, 0x02, + 0xd4, 0x20, 0xb7, 0x10, 0x21, 0xd1, 0x08, 0x20, + 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x14, 0xcc, 0x00, 0x80, 0x00, 0x24, 0x40, + 0x48, 0x28, 0x02, 0xc0, 0x00, 0x83, 0x00, 0x2c, + 0xd0, 0x08, 0x24, 0x02, 0x0a, 0x00, 0xb1, 0x00, + 0x20, 0xd0, 0x0b, 0x31, 0x02, 0x4c, 0x20, 0x81, + 0x51, 0x6c, 0xe0, 0x1b, 0x38, 0x02, 0xcd, 0x00, + 0xb3, 0x00, 0xa0, 0xc0, 0x0b, 0xa4, 0x02, 0xc0, + 0x04, 0x80, 0x60, 0x20, 0xa0, 0x0a, 0x95, 0x02, + 0xc3, 0x80, 0xb2, 0x00, 0x26, 0x00, 0x08, 0x04, + 0x02, 0x08, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x15, 0xbc, 0x00, 0xeb, 0x40, 0x3a, 0xe0, + 0x2c, 0x08, 0x03, 0xe1, 0x40, 0xcb, 0x00, 0x3d, + 0xd4, 0x2c, 0x28, 0x03, 0x28, 0xc0, 0xf8, 0x00, + 0x32, 0x04, 0x0f, 0x88, 0x03, 0x6c, 0x20, 0xc9, + 0x00, 0x3e, 0xe0, 0x0f, 0xba, 0x03, 0xfe, 0x90, + 0xff, 0x00, 0x32, 0xc0, 0x0f, 0xac, 0x03, 0x6c, + 0x68, 0xcb, 0x00, 0xb2, 0xed, 0x09, 0x00, 0xb4, + 0x01, 0xe0, 0x2c, 0xb4, 0x03, 0xef, 0x08, 0xfa, + 0xa0, 0x32, 0xc0, 0x2c, 0x90, 0x03, 0x2a, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, + 0x00, 0xfb, 0x11, 0x3e, 0xe0, 0x8f, 0x84, 0x83, + 0xe1, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xa5, + 0x13, 0xa8, 0x00, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, + 0xb2, 0x03, 0xa9, 0x00, 0xf9, 0x00, 0x3e, 0x50, + 0x0f, 0x90, 0x03, 0xec, 0x04, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xa0, 0x03, 0xe4, 0x00, 0xf3, 0x00, + 0x3e, 0xc0, 0x5d, 0x80, 0x03, 0xe4, 0x00, 0xf8, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xe0, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, + 0x00, 0xff, 0x88, 0xb0, 0xc0, 0x0c, 0xd8, 0x02, + 0x30, 0x00, 0xcf, 0x00, 0x3f, 0xc0, 0x0c, 0xe8, + 0x83, 0x38, 0x01, 0xfc, 0x00, 0x33, 0x00, 0x0f, + 0xc0, 0x03, 0xf5, 0x00, 0xde, 0x0d, 0x3f, 0x92, + 0x0c, 0xf9, 0x03, 0xfc, 0x20, 0xeb, 0x00, 0x3f, + 0xc0, 0x0f, 0xd0, 0x8b, 0x3e, 0x00, 0xfc, 0x10, + 0x31, 0x20, 0x08, 0xe0, 0x83, 0x38, 0x18, 0xf1, + 0x82, 0x33, 0x80, 0x0c, 0x41, 0x83, 0x00, 0x44, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, + 0x00, 0xb3, 0x80, 0x22, 0x40, 0x08, 0xbc, 0x02, + 0x02, 0x00, 0x8b, 0x02, 0x2e, 0xc0, 0x88, 0xa8, + 0x02, 0xa8, 0x10, 0xb1, 0x04, 0x22, 0xc0, 0x8b, + 0xb0, 0x02, 0xec, 0x00, 0xba, 0x40, 0x38, 0xd0, + 0x0c, 0xb8, 0x12, 0xec, 0x00, 0x8b, 0x01, 0x2e, + 0xc0, 0x0b, 0x81, 0x02, 0x20, 0x40, 0xb8, 0x00, + 0x22, 0x34, 0x05, 0x80, 0x02, 0x23, 0x00, 0xb8, + 0x10, 0x22, 0x00, 0x0a, 0x90, 0x02, 0x20, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, + 0x00, 0xbb, 0x20, 0x22, 0xe0, 0x08, 0x82, 0x02, + 0xa2, 0x00, 0xab, 0x00, 0x2e, 0xc0, 0x08, 0xed, + 0x09, 0x00, 0xb5, 0x01, 0xa2, 0x42, 0x28, 0x00, + 0xb8, 0x00, 0x22, 0x00, 0x0b, 0x80, 0x02, 0xec, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0, 0x02, + 0xcc, 0x00, 0xab, 0x00, 0x2e, 0xc0, 0x0b, 0x80, + 0x00, 0x28, 0x00, 0xbb, 0x00, 0x22, 0x50, 0x2a, + 0xb0, 0x00, 0x2c, 0x80, 0xba, 0x00, 0x22, 0x40, + 0x0a, 0x90, 0x02, 0x20, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb2, 0x00, + 0x20, 0x20, 0x08, 0x80, 0x0a, 0xa0, 0x00, 0x83, + 0x00, 0x2e, 0xc0, 0x08, 0x80, 0x02, 0x88, 0x04, + 0xb1, 0x00, 0x20, 0xc0, 0x1b, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x08, 0x30, 0x32, + 0xcc, 0x02, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x08, + 0x06, 0x02, 0x00, 0xb0, 0x81, 0xa0, 0x40, 0x09, + 0x20, 0x02, 0x00, 0x00, 0xb0, 0x81, 0x20, 0x00, + 0x4a, 0x20, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xfa, 0x00, + 0x32, 0xc0, 0x2c, 0xb0, 0x03, 0xa0, 0x00, 0xeb, + 0x00, 0x3d, 0xc0, 0x0c, 0xa0, 0x12, 0x28, 0x10, + 0xb8, 0x00, 0x32, 0x00, 0x0f, 0x80, 0x43, 0xec, + 0x00, 0xd8, 0x00, 0x3e, 0xc0, 0x0c, 0xb0, 0x03, + 0xfc, 0x02, 0xaf, 0x00, 0x3e, 0xc0, 0x8f, 0x90, + 0x03, 0x20, 0x00, 0xf8, 0x00, 0x30, 0x00, 0x0e, + 0x80, 0x23, 0x20, 0x00, 0xf9, 0x00, 0xb0, 0xc0, + 0x0c, 0x80, 0x03, 0x00, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xfe, 0x00, + 0x3f, 0xc0, 0x0f, 0xd0, 0x03, 0x70, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x2f, 0x40, 0x03, 0xf8, 0x10, + 0xfd, 0x00, 0x3f, 0xc0, 0x0f, 0x70, 0x03, 0xf0, + 0x00, 0xfc, 0x00, 0x3b, 0x00, 0x0e, 0xc0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, + 0x01, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x8e, + 0xc0, 0x23, 0xed, 0x09, 0x00, 0xb6, 0x01, 0xf0, + 0x04, 0xfc, 0x00, 0x3f, 0x00, 0x2d, 0xc0, 0x03, + 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x05, 0xf0, 0x00, 0xfc, 0x10, 0x3d, 0xca, 0x0f, + 0xf4, 0x03, 0x3c, 0x80, 0xff, 0x20, 0x37, 0x04, + 0x0c, 0xf4, 0x03, 0xbd, 0x01, 0xcf, 0x31, 0x33, + 0xc9, 0x0f, 0xe1, 0x03, 0x7c, 0x90, 0xfc, 0x00, + 0x37, 0xc0, 0x0c, 0xc0, 0x03, 0x3c, 0x00, 0xfc, + 0x14, 0x3f, 0xc0, 0x0d, 0x50, 0x03, 0xfc, 0x10, + 0xff, 0x00, 0x37, 0xc0, 0x0c, 0x72, 0x03, 0x7c, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0xa4, 0x04, 0xb9, 0x20, 0x2f, 0xd0, 0x0b, + 0xf3, 0x02, 0x3d, 0x00, 0xbf, 0x40, 0x26, 0x48, + 0x08, 0xf3, 0x02, 0x2c, 0x00, 0xbf, 0x60, 0x23, + 0xd0, 0x0f, 0x12, 0x42, 0x3c, 0x40, 0xfb, 0x01, + 0x2f, 0xd6, 0x88, 0xb0, 0x02, 0xbd, 0x28, 0xbb, + 0x00, 0x2f, 0xd0, 0x08, 0xb0, 0x02, 0xcc, 0xa0, + 0xba, 0x00, 0x22, 0xd4, 0x0a, 0xb4, 0x02, 0x2c, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, + 0x04, 0xc2, 0xa0, 0xb0, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0x0d, 0x00, 0xb3, 0x10, 0x2c, 0x08, + 0x88, 0x32, 0x02, 0x8c, 0x80, 0xb3, 0x64, 0x20, + 0xd0, 0x0b, 0x90, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc8, 0x0a, 0x30, 0x02, 0x0c, 0xc0, 0xb2, + 0x00, 0x2c, 0xc4, 0x09, 0x32, 0xe2, 0xc4, 0x80, + 0xbb, 0x28, 0x24, 0xcb, 0x09, 0x31, 0x02, 0x4c, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x15, 0xa0, 0x00, 0xb8, 0x00, 0x2e, 0xc0, 0x0b, + 0x30, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2c, 0x22, + 0x08, 0xb0, 0x02, 0x2c, 0x00, 0xed, 0x09, 0x00, + 0xb7, 0x01, 0xbb, 0x03, 0x22, 0xc0, 0x02, 0x98, + 0x00, 0xac, 0x00, 0xab, 0x20, 0x2e, 0xc0, 0x2a, + 0x82, 0x02, 0xac, 0x00, 0x39, 0x10, 0x2c, 0xc0, + 0x08, 0xb0, 0x42, 0xec, 0xa0, 0xb8, 0x10, 0x22, + 0xc0, 0x0b, 0xb0, 0x02, 0x6c, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xf0, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xe6, 0x00, + 0xf9, 0x80, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x2c, + 0x04, 0xfb, 0x02, 0x36, 0x50, 0x0c, 0xb0, 0x03, + 0xac, 0x00, 0xfb, 0x00, 0x32, 0xc0, 0xcb, 0x14, + 0x03, 0xec, 0x00, 0xbb, 0x00, 0x3e, 0xc0, 0x0e, + 0x34, 0x83, 0x2c, 0x00, 0xfb, 0x80, 0x3e, 0xc0, + 0x0d, 0xb8, 0x03, 0xee, 0x00, 0xfb, 0xa0, 0x36, + 0xc0, 0x0d, 0xb0, 0x03, 0x6c, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xb6, 0x80, + 0xfd, 0x20, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x03, 0x37, 0x40, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xd0, + 0x03, 0x7c, 0x00, 0xff, 0x81, 0x3d, 0xc0, 0x0d, + 0xf8, 0x03, 0xfc, 0x08, 0xff, 0x80, 0x3f, 0xc0, + 0x0f, 0xf4, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3d, + 0xc0, 0x0e, 0x70, 0x03, 0xbc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xa4, 0x00, + 0xf9, 0x40, 0x3e, 0xc0, 0x8c, 0xb0, 0x03, 0x2c, + 0x00, 0xcb, 0x00, 0x3e, 0x50, 0x0f, 0xb0, 0x03, + 0xac, 0x00, 0xcb, 0x00, 0x7e, 0xc0, 0x0f, 0xa4, + 0x0b, 0x2c, 0x20, 0xfb, 0x30, 0x3e, 0xc0, 0x4c, + 0xb2, 0x00, 0xec, 0x00, 0xdb, 0x40, 0xb2, 0xc0, + 0x0e, 0x90, 0x03, 0x25, 0x00, 0xeb, 0x00, 0x3a, + 0xc0, 0x0e, 0xb0, 0x03, 0x2c, 0x00, 0xfb, 0x00, + 0xed, 0x09, 0x00, 0xb8, 0x01, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2f, + 0xe0, 0x08, 0xf0, 0x02, 0x3c, 0x02, 0x8f, 0x20, + 0x22, 0xc0, 0x0b, 0xf0, 0x03, 0x6c, 0x04, 0x8f, + 0x00, 0x2f, 0xd0, 0x0b, 0x90, 0x02, 0x3c, 0x00, + 0xbb, 0x81, 0x6f, 0xc0, 0x08, 0xba, 0x03, 0xbc, + 0x00, 0xbb, 0x00, 0x23, 0xc0, 0x08, 0xb0, 0x03, + 0x6c, 0x00, 0x83, 0x00, 0x23, 0xc0, 0x08, 0xf2, + 0x03, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x05, 0x44, 0x00, 0xb1, 0x00, 0x2c, + 0xc4, 0x08, 0x30, 0x02, 0x0d, 0x81, 0x83, 0xe0, + 0x20, 0x40, 0x0b, 0xb0, 0x02, 0x8c, 0x10, 0xab, + 0x00, 0x2c, 0xe8, 0x0b, 0x10, 0x02, 0x8f, 0x00, + 0xb2, 0x40, 0x2c, 0xc0, 0x00, 0x3c, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0a, 0x30, 0x02, + 0x0c, 0x00, 0xa3, 0x00, 0x28, 0xc1, 0x0a, 0x32, + 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x01, 0x12, 0x08, 0xb4, 0x80, 0x2d, + 0xf0, 0x48, 0x38, 0x52, 0x0e, 0x10, 0x83, 0x80, + 0x21, 0x20, 0x0b, 0x78, 0x02, 0x5e, 0x00, 0xa7, + 0x90, 0x2d, 0xe2, 0x8b, 0x68, 0x02, 0x9e, 0x10, + 0xb7, 0x80, 0x2d, 0xe0, 0xa8, 0x78, 0x02, 0x9e, + 0x00, 0xb7, 0x80, 0x21, 0xe0, 0x08, 0xd8, 0x02, + 0x5a, 0x00, 0x87, 0x80, 0x21, 0xe0, 0x08, 0x78, + 0x02, 0x5e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x2c, + 0xc0, 0x0c, 0x30, 0x03, 0x0c, 0x60, 0xc3, 0x00, + 0x3c, 0x04, 0x4f, 0xb2, 0x0b, 0xac, 0x00, 0xe3, + 0x00, 0x2c, 0xc0, 0xed, 0x09, 0x00, 0xb9, 0x01, + 0x0f, 0x14, 0x43, 0x8c, 0x20, 0xf3, 0x00, 0x2e, + 0xc0, 0x0c, 0x31, 0x03, 0xcc, 0x00, 0xfb, 0x40, + 0x22, 0xc0, 0x0e, 0x31, 0x03, 0x0c, 0x00, 0xeb, + 0x10, 0x3a, 0xc0, 0x0e, 0x30, 0x03, 0x0c, 0x00, + 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xd2, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, + 0xb8, 0x00, 0xfe, 0x00, 0x3f, 0xc0, 0x23, 0xf0, + 0x83, 0xfd, 0x00, 0xff, 0x10, 0x3f, 0x04, 0x0f, + 0xf0, 0x03, 0xbc, 0x00, 0xdf, 0x04, 0x3f, 0xc0, + 0x0f, 0xd0, 0x03, 0x7c, 0x00, 0x7f, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x43, 0xfc, 0x40, 0xff, 0x00, + 0x3f, 0xc2, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x83, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xd0, + 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, + 0xc4, 0x00, 0xe9, 0x80, 0x92, 0xc9, 0x0f, 0xb0, + 0xa3, 0xec, 0xc0, 0xfb, 0x0c, 0x0e, 0x40, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0xa0, 0x32, 0xee, + 0x0e, 0x90, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc8, 0x0f, 0x80, 0x43, 0x6c, 0x40, 0xc9, 0x80, + 0xb2, 0xf8, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xe4, 0x1d, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xea, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, + 0x9c, 0x04, 0x85, 0x00, 0x21, 0xda, 0x0b, 0x72, + 0x02, 0xdc, 0x00, 0x37, 0x02, 0x25, 0x40, 0x0f, + 0x73, 0x03, 0xdc, 0x00, 0xb7, 0x28, 0xa1, 0xc8, + 0x08, 0x50, 0x02, 0xdd, 0x20, 0xb7, 0x00, 0x2d, + 0xca, 0x0b, 0x70, 0x02, 0xcc, 0x40, 0x87, 0x00, + 0x20, 0xc4, 0x0f, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0xc8, 0x1c, 0x72, 0x03, 0xdc, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0xed, 0x09, + 0x00, 0xba, 0x01, 0x02, 0xd2, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0xb6, 0x00, 0xa7, + 0x88, 0x21, 0xe0, 0x0b, 0x7a, 0x02, 0xde, 0x00, + 0xb7, 0xb0, 0x2d, 0xe1, 0x0b, 0x7b, 0x02, 0xde, + 0x00, 0xa7, 0x90, 0x20, 0xc8, 0x0a, 0x58, 0x02, + 0xde, 0x88, 0x37, 0x80, 0x2d, 0xe4, 0x4b, 0x78, + 0x06, 0xde, 0x00, 0x8f, 0x80, 0x21, 0xe8, 0x08, + 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2c, 0xe8, + 0x28, 0x7a, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x02, 0xf0, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x14, 0xc4, 0x00, 0x81, + 0x80, 0x20, 0xc0, 0x03, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x02, 0x24, 0x40, 0x0a, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x20, 0xc1, 0x1a, 0x20, 0x02, + 0xcc, 0x00, 0xb3, 0x10, 0x2c, 0xc0, 0x0b, 0x00, + 0x02, 0xec, 0x00, 0x81, 0x00, 0x20, 0xc0, 0x0a, + 0x10, 0x02, 0xcc, 0x00, 0xb3, 0x10, 0x2c, 0xc0, + 0x08, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xe8, 0x15, 0xb9, 0x00, 0xee, + 0x40, 0x32, 0x80, 0x8b, 0xa0, 0x03, 0xe8, 0x00, + 0xfa, 0x00, 0x3f, 0x98, 0x0b, 0xa0, 0x03, 0xe8, + 0x00, 0xea, 0x00, 0x32, 0x80, 0x0e, 0xe5, 0x03, + 0xe8, 0x00, 0xfe, 0x40, 0x3e, 0x80, 0x0f, 0xec, + 0x83, 0xe8, 0x02, 0xce, 0xc8, 0x32, 0x80, 0x08, + 0xa8, 0x93, 0xf9, 0x04, 0xf6, 0x40, 0x3e, 0x80, + 0x0c, 0x20, 0x02, 0xe8, 0x00, 0xfa, 0x00, 0x3e, + 0x80, 0x0f, 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0xe2, 0x04, 0xf8, + 0x80, 0x3e, 0x10, 0x0f, 0x80, 0x03, 0xe0, 0x04, + 0xf8, 0x00, 0x36, 0x20, 0x0f, 0x80, 0x03, 0xa0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0d, 0x80, 0x03, + 0xe0, 0xed, 0x09, 0x00, 0xbb, 0x01, 0x00, 0xf8, + 0x80, 0x3e, 0x00, 0x0f, 0x80, 0x83, 0xe0, 0x00, + 0xf8, 0x08, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe2, + 0x00, 0xf8, 0x80, 0x3e, 0x00, 0x0e, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xe4, 0x00, 0xc9, 0x00, 0x3e, 0x44, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x01, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xa4, 0x00, 0xf9, 0x00, + 0x3e, 0x60, 0x0c, 0x90, 0x03, 0xc4, 0x00, 0xc9, + 0x00, 0x22, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xc9, 0x00, 0x3e, 0x40, 0x0b, 0x90, 0x03, 0x24, + 0x00, 0xf9, 0x00, 0x32, 0x40, 0x0f, 0x92, 0x03, + 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x04, 0x64, 0x00, 0x89, 0x01, 0x2e, 0x78, + 0x0b, 0x90, 0x02, 0xe6, 0x40, 0xb9, 0x00, 0x3a, + 0x40, 0x0b, 0x90, 0x03, 0x64, 0x08, 0xb9, 0x00, + 0x2c, 0x64, 0x0a, 0x90, 0x02, 0xe4, 0x22, 0x81, + 0x98, 0x22, 0x40, 0x0b, 0x94, 0x02, 0xe4, 0x00, + 0x89, 0x02, 0x2e, 0x40, 0x09, 0x90, 0x42, 0x24, + 0x00, 0xb9, 0x02, 0x22, 0x40, 0x0b, 0x92, 0x02, + 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0x04, 0x00, 0x8b, 0x00, 0x2e, 0x40, + 0x1b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x10, 0x2e, + 0x40, 0x0b, 0x10, 0x02, 0xa4, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x08, 0x90, 0x22, 0xe4, 0x80, 0x89, + 0x00, 0x2a, 0x40, 0x8b, 0x98, 0x02, 0xe4, 0x00, + 0x89, 0x00, 0x2e, 0x40, 0x01, 0x10, 0x02, 0x24, + 0x08, 0xb9, 0x00, 0x22, 0x41, 0x0b, 0x90, 0x02, + 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xc6, 0x00, 0x40, 0xed, 0x09, 0x00, 0xbc, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x05, + 0x02, 0x01, 0x40, 0x2c, 0x40, 0x1b, 0x14, 0x02, + 0xc4, 0x01, 0xb1, 0x80, 0x28, 0x50, 0x03, 0x10, + 0x02, 0x45, 0x00, 0xb1, 0x40, 0x2c, 0x40, 0x08, + 0x14, 0x02, 0xc4, 0x00, 0x81, 0x00, 0x28, 0x50, + 0x0b, 0x18, 0x02, 0xc5, 0x02, 0x81, 0x40, 0x2c, + 0x50, 0x09, 0x14, 0x0a, 0x05, 0x00, 0xb9, 0x40, + 0x20, 0x50, 0x0b, 0x10, 0x02, 0x04, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, + 0x00, 0x40, 0x00, 0x2e, 0x00, 0x0f, 0x80, 0x03, + 0xe8, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x8f, 0x80, + 0x03, 0xa0, 0x09, 0xf0, 0x01, 0x3e, 0x00, 0x0c, + 0x80, 0x23, 0xe0, 0x00, 0xc8, 0x00, 0x3a, 0x00, + 0x0f, 0x80, 0x03, 0xe0, 0x08, 0xc8, 0x00, 0x3e, + 0x00, 0x5f, 0x80, 0x03, 0x20, 0x00, 0xf8, 0x00, + 0x32, 0x00, 0x8f, 0x80, 0x03, 0xa0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xee, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x19, 0xf4, + 0x00, 0xfd, 0x00, 0x3e, 0x50, 0x0f, 0x94, 0x03, + 0xe5, 0x04, 0xf9, 0x40, 0x3b, 0x40, 0x4f, 0x96, + 0x83, 0xe4, 0x00, 0xf9, 0x40, 0x3e, 0x50, 0x0f, + 0xd0, 0x03, 0xe5, 0x00, 0xff, 0x00, 0xb6, 0x50, + 0x0f, 0xd0, 0x03, 0xe5, 0x00, 0xf5, 0x00, 0x3e, + 0x51, 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xfd, 0x00, + 0xbe, 0x50, 0x0f, 0x94, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x06, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xed, + 0x08, 0x09, 0x40, 0x3b, 0x40, 0x0f, 0x90, 0x03, + 0xf4, 0x00, 0xbd, 0x20, 0x3e, 0x50, 0x0f, 0x91, + 0x03, 0xa4, 0x00, 0xf9, 0x08, 0x3f, 0x40, 0x0f, + 0xb4, 0x03, 0xf4, 0x2c, 0xcd, 0x01, 0x3e, 0xed, + 0x09, 0x00, 0xbd, 0x01, 0x50, 0x0f, 0xd0, 0x43, + 0xe5, 0x20, 0xf9, 0x00, 0x32, 0x42, 0x0f, 0x90, + 0x03, 0xe4, 0x42, 0xe9, 0x00, 0x32, 0x40, 0x0f, + 0xd0, 0x83, 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x42, 0xc6, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x10, 0xc0, 0x00, 0x80, 0x00, + 0x22, 0x10, 0x0b, 0x86, 0x02, 0xe1, 0x40, 0xb8, + 0x50, 0x2e, 0x00, 0x0b, 0x86, 0x02, 0x20, 0x80, + 0xb8, 0x60, 0x2e, 0x00, 0x09, 0x82, 0x02, 0xe1, + 0x09, 0xd8, 0x00, 0x2e, 0x1c, 0x4b, 0x80, 0x02, + 0xe1, 0x10, 0xb0, 0x00, 0x22, 0x08, 0x0b, 0x80, + 0x02, 0xe0, 0x00, 0xa8, 0x20, 0x22, 0x01, 0x0b, + 0x84, 0x02, 0x20, 0x00, 0xb8, 0x00, 0x2e, 0x00, + 0x0b, 0x80, 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x05, 0xc4, 0x82, 0x99, 0x20, + 0x28, 0x50, 0x0b, 0x14, 0x82, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x16, 0x02, 0x84, 0x20, + 0xb1, 0x08, 0x2c, 0x50, 0x0b, 0x12, 0x02, 0xc4, + 0x00, 0x81, 0x00, 0x2c, 0x41, 0x8b, 0x10, 0x02, + 0xc4, 0x00, 0xb9, 0x28, 0x20, 0x42, 0x0b, 0x10, + 0x82, 0xe4, 0x80, 0xa1, 0x0c, 0x20, 0x5a, 0x0b, + 0x10, 0x02, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x05, 0xa4, 0x88, 0x99, 0x00, + 0x22, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0x39, + 0x00, 0x2e, 0x40, 0x0b, 0x10, 0x12, 0x24, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x92, 0x02, 0xec, + 0x00, 0x89, 0x10, 0x2e, 0x40, 0x8b, 0x90, 0x02, + 0xe4, 0x00, 0xb9, 0x00, 0x22, 0x40, 0x8b, 0x92, + 0x02, 0xe5, 0x02, 0xa9, 0x10, 0x22, 0x40, 0x0b, + 0x90, 0x00, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0xbe, 0x01, 0xa0, + 0x05, 0xe4, 0x80, 0xd9, 0x0d, 0x3a, 0x40, 0x0b, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x2e, 0x48, + 0x0f, 0x90, 0x13, 0xa4, 0x00, 0xf9, 0x01, 0x3e, + 0x40, 0x07, 0x92, 0x13, 0xc4, 0x02, 0x89, 0x41, + 0x3e, 0x40, 0x0f, 0x9a, 0x03, 0xe4, 0x00, 0xf9, + 0x80, 0xb2, 0x40, 0x0f, 0x90, 0x03, 0xc4, 0x06, + 0xe9, 0x00, 0x32, 0x40, 0x4b, 0x90, 0x01, 0x24, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x01, 0xa4, 0x00, 0xe9, 0x40, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x68, + 0x0f, 0x90, 0x02, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x01, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x01, + 0x3e, 0x40, 0x0f, 0x94, 0x03, 0xe4, 0x00, 0xf9, + 0x90, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe5, 0x02, + 0xf9, 0x80, 0xbe, 0x40, 0x0f, 0x10, 0x0a, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0xa0, 0x00, 0xc8, 0x40, 0x32, 0x20, 0x4e, + 0x80, 0x43, 0x22, 0x00, 0xf8, 0x80, 0x3e, 0x10, + 0x0c, 0x80, 0x03, 0xe0, 0x04, 0xf8, 0x00, 0x32, + 0x20, 0x0f, 0x84, 0x23, 0x22, 0x04, 0xf8, 0x42, + 0x22, 0x00, 0x2c, 0x88, 0x13, 0xe0, 0x05, 0xf8, + 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x32, 0x01, 0x4f, 0x80, 0x03, 0xa0, + 0x00, 0xd8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x15, 0x28, 0x00, 0x82, 0x00, 0x23, 0xb0, 0x0b, + 0xa0, 0x02, 0x39, 0x84, 0xbe, 0xc0, 0x2e, 0x80, + 0x0a, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x23, + 0xb2, 0x0b, 0xa0, 0x02, 0xb9, 0x00, 0xbe, 0x02, + 0x22, 0x80, 0x08, 0xee, 0x02, 0xed, 0x09, 0x00, + 0xbf, 0x01, 0xe8, 0x00, 0xb2, 0x04, 0x22, 0x80, + 0x0b, 0xa0, 0x00, 0xe8, 0x00, 0xba, 0x00, 0x22, + 0x80, 0x0e, 0xee, 0x02, 0xa8, 0x00, 0xba, 0x00, + 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xca, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x6c, 0x00, + 0x83, 0x00, 0x20, 0x60, 0x0b, 0x30, 0x02, 0x04, + 0x00, 0xb1, 0x80, 0x2c, 0xc0, 0x08, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0xa0, 0xc0, 0x0b, 0x30, + 0x02, 0x06, 0x40, 0xb0, 0x08, 0x20, 0xc0, 0x08, + 0x10, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0xa0, 0xc0, + 0x0b, 0x30, 0x12, 0xcc, 0x00, 0x9b, 0x00, 0xa0, + 0xc0, 0x0b, 0x3e, 0x0a, 0x0c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, 0x80, + 0x87, 0x20, 0x21, 0x42, 0x0b, 0x3a, 0x02, 0x14, + 0x00, 0xb5, 0x08, 0x2f, 0xe8, 0x0a, 0x72, 0x02, + 0xdc, 0x00, 0xb7, 0xa1, 0x21, 0xc1, 0x0b, 0x78, + 0x02, 0x9c, 0x00, 0xb7, 0xc0, 0x21, 0xe4, 0x08, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x20, 0x21, 0xc8, + 0x0b, 0x70, 0x46, 0xdc, 0x04, 0xbf, 0x00, 0x21, + 0xc8, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xe8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x82, + 0xc7, 0xa8, 0xb1, 0x60, 0x8f, 0x79, 0x03, 0x16, + 0x00, 0xf5, 0x81, 0x3d, 0xf9, 0x0c, 0x7c, 0x03, + 0xde, 0x80, 0xf3, 0xa0, 0x31, 0xe0, 0x8f, 0xfa, + 0x0b, 0x1e, 0x00, 0xf7, 0x80, 0x30, 0xea, 0x0c, + 0x78, 0x03, 0xde, 0x80, 0xb7, 0x80, 0x31, 0xe1, + 0x0f, 0x79, 0x03, 0xde, 0x28, 0xf7, 0xa0, 0x31, + 0xe0, 0x0f, 0x78, 0x03, 0x9e, 0x00, 0xd7, 0x80, + 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xea, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, 0xac, 0xe0, + 0xed, 0x09, 0x00, 0xc0, 0x01, 0xfb, 0x50, 0x3e, + 0x40, 0x0f, 0xb3, 0x0b, 0xe4, 0x00, 0xf9, 0x01, + 0x3c, 0xc8, 0x0f, 0xb0, 0x01, 0xec, 0x00, 0xfb, + 0x52, 0x3e, 0xc0, 0x0f, 0xb6, 0x43, 0x64, 0x00, + 0xf2, 0x02, 0xbe, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0xa8, 0xfb, 0x38, 0x1e, 0xd8, 0x0f, 0xb1, 0x43, + 0xec, 0x80, 0xf3, 0x00, 0x3e, 0xc4, 0x0e, 0x30, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, 0x82, 0x33, + 0xa1, 0x0d, 0xf8, 0x03, 0x3a, 0x00, 0xce, 0x81, + 0x1b, 0xf8, 0x0f, 0xfc, 0x03, 0x3f, 0x20, 0x8f, + 0xc0, 0x3f, 0xe4, 0x0f, 0x7c, 0x83, 0x3e, 0x00, + 0xc7, 0x80, 0x37, 0xec, 0x4c, 0x78, 0x03, 0x3e, + 0x20, 0xcf, 0x90, 0x3f, 0xf2, 0x8c, 0xf8, 0x03, + 0x5e, 0x20, 0xc7, 0x88, 0x33, 0xe1, 0x0f, 0xf8, + 0x2b, 0x3e, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, + 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xbf, 0x00, 0x21, + 0x10, 0x08, 0xf0, 0x02, 0x10, 0x00, 0xd4, 0x00, + 0x21, 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0x87, + 0x20, 0x2d, 0xc4, 0x0b, 0x70, 0x02, 0x1c, 0x40, + 0x85, 0x00, 0x21, 0xc4, 0x08, 0x71, 0x82, 0x1c, + 0x00, 0x87, 0x39, 0x2d, 0xc4, 0x08, 0x71, 0x42, + 0xdc, 0x40, 0xa7, 0x10, 0xa1, 0xc0, 0x0b, 0x71, + 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x21, + 0x00, 0x08, 0x70, 0x02, 0x10, 0x00, 0x84, 0x00, + 0x21, 0xc8, 0x8b, 0x30, 0x02, 0x1c, 0x02, 0xb7, + 0x03, 0x2d, 0xc0, 0x0b, 0xf0, 0x02, 0x4c, 0x00, + 0x8f, 0x40, 0x25, 0xc9, 0x08, 0xd0, 0x02, 0x1c, + 0x00, 0x87, 0x00, 0xed, 0x09, 0x00, 0xc1, 0x01, + 0x2d, 0xc0, 0x0a, 0x70, 0x02, 0xfc, 0x00, 0x8f, + 0x00, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xc0, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, + 0xee, 0x20, 0xbb, 0x01, 0x20, 0x00, 0x08, 0x30, + 0x12, 0x04, 0x00, 0x91, 0x01, 0x02, 0xf0, 0x0b, + 0x30, 0x12, 0x0c, 0x08, 0x93, 0x02, 0x2c, 0xc1, + 0x0b, 0x34, 0x02, 0x4c, 0x00, 0x83, 0x00, 0x20, + 0xc0, 0x08, 0x36, 0x02, 0x0c, 0x00, 0x83, 0x80, + 0x2c, 0xc0, 0x08, 0xb9, 0x02, 0xef, 0x00, 0xa3, + 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0x0c, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc8, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x15, + 0xbe, 0x80, 0xff, 0xf0, 0x32, 0xc0, 0x28, 0xf0, + 0x03, 0x2c, 0x00, 0xcb, 0x02, 0x93, 0xd6, 0x0f, + 0xf0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3e, 0xc0, + 0x0b, 0xf0, 0x03, 0x6c, 0x00, 0xcb, 0x08, 0x37, + 0xc0, 0x2c, 0xb8, 0x02, 0x3c, 0x00, 0xcf, 0xc1, + 0x3f, 0xc0, 0x0e, 0xf0, 0x03, 0x7d, 0x20, 0xcf, + 0xa0, 0x33, 0xc0, 0x4b, 0xb0, 0x03, 0x2c, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xea, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0xec, 0x00, 0xfb, 0x00, 0xbc, 0x40, 0x0e, 0xb0, + 0x0b, 0xe4, 0x00, 0xf9, 0x41, 0x7e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x10, 0xab, 0x00, 0x3c, 0xc0, + 0x0f, 0xb3, 0x23, 0xad, 0x08, 0xfb, 0x40, 0x3e, + 0xc0, 0x8f, 0x94, 0x03, 0xec, 0x00, 0xfb, 0x20, + 0x3e, 0xc0, 0x0f, 0xb0, 0x13, 0xec, 0x80, 0xfb, + 0x20, 0x3e, 0xc0, 0x1f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xe0, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, + 0xfc, 0x00, 0xcf, 0x00, 0x32, 0x40, 0xed, 0x09, + 0x00, 0xc2, 0x01, 0x0c, 0xf0, 0x03, 0xd6, 0x00, + 0xc9, 0x00, 0x37, 0xc0, 0x4c, 0x70, 0x03, 0x3c, + 0x00, 0xb7, 0x00, 0x33, 0xe9, 0x0c, 0xf0, 0x03, + 0x7d, 0x00, 0xfd, 0x80, 0x3f, 0xc0, 0x0f, 0xf0, + 0x43, 0xdc, 0x00, 0xdf, 0x00, 0x3e, 0xc0, 0x0f, + 0xf0, 0x03, 0x3c, 0x00, 0xef, 0x00, 0x9b, 0xc0, + 0x0b, 0xfa, 0x0b, 0x3c, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, 0x8b, + 0x00, 0x22, 0x74, 0x08, 0xb0, 0x02, 0xe7, 0x24, + 0x81, 0x90, 0x22, 0xc0, 0x0a, 0xb0, 0x02, 0x2c, + 0x00, 0xbb, 0x01, 0x22, 0xf8, 0x08, 0xb0, 0x02, + 0xef, 0x00, 0xbb, 0xe0, 0x2e, 0xc0, 0x0b, 0xbc, + 0x02, 0xec, 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x00, 0x2c, 0x04, 0x83, 0x00, 0x2a, 0xc0, + 0x0b, 0x30, 0x02, 0xac, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, 0x8b, + 0x00, 0x22, 0x00, 0x08, 0xb0, 0x02, 0xe0, 0x80, + 0x88, 0x40, 0x22, 0xc0, 0x88, 0xb0, 0x02, 0x2c, + 0x00, 0xab, 0x00, 0x22, 0xc0, 0x08, 0xb0, 0x06, + 0xe4, 0x04, 0xba, 0x12, 0x2e, 0xc0, 0x0b, 0xb5, + 0x02, 0xec, 0x00, 0x8b, 0x00, 0x06, 0xc0, 0x0b, + 0xb0, 0x02, 0x2c, 0x00, 0xab, 0x00, 0xaa, 0xc0, + 0x4b, 0xb0, 0x82, 0x2c, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x83, + 0x00, 0x20, 0x40, 0x28, 0x30, 0x02, 0xc4, 0x00, + 0x81, 0x00, 0x20, 0xc0, 0x08, 0x30, 0x02, 0x0c, + 0x01, 0xb3, 0x00, 0xa0, 0x80, 0x88, 0x30, 0x06, + 0xcc, 0x00, 0xb3, 0x02, 0x24, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x08, 0x83, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0xed, 0x09, 0x00, 0xc3, 0x01, 0x0a, 0x0c, + 0x00, 0x8b, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, + 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x7c, 0x00, 0xcf, 0x00, 0xb2, 0x40, + 0x0c, 0xf0, 0x03, 0xe0, 0x00, 0xc8, 0x00, 0x33, + 0xc0, 0x2c, 0xf0, 0x03, 0x1c, 0x00, 0xef, 0x00, + 0x32, 0xc0, 0x2c, 0xf0, 0x03, 0x6c, 0x00, 0xfb, + 0x00, 0x3d, 0xc0, 0x0f, 0xb0, 0x03, 0xdc, 0x00, + 0xcf, 0x01, 0x37, 0xc0, 0x8f, 0xf0, 0x03, 0x3c, + 0x00, 0xeb, 0x01, 0x3a, 0xc1, 0x1f, 0xa0, 0x03, + 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x00, + 0x0f, 0xf0, 0x03, 0xd0, 0x00, 0xfc, 0x00, 0xaf, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x01, + 0x3f, 0x00, 0x1f, 0xf0, 0x03, 0x70, 0x00, 0xfc, + 0x00, 0x3f, 0xc0, 0x8f, 0xc0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0xbf, 0xc0, 0x8f, 0x50, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x05, 0xf4, 0x00, 0xcc, 0x00, 0x33, 0x84, + 0x0d, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0x80, 0x0c, 0x70, 0x03, 0x1c, 0x10, 0xf6, 0x00, + 0x3d, 0x40, 0x0c, 0xf0, 0x03, 0xdc, 0x00, 0xfc, + 0x00, 0x3b, 0x80, 0x0f, 0xc0, 0x02, 0xd0, 0x00, + 0xcf, 0x04, 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xf1, + 0x82, 0xcc, 0x04, 0x33, 0x49, 0x0d, 0xf1, 0x43, + 0xf0, 0x00, 0xff, 0x00, 0x33, 0x00, 0x0f, 0xf0, + 0x03, 0xf0, 0x05, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x10, 0xec, 0x00, 0x8b, 0x00, 0xa2, 0xc8, + 0x08, 0xb0, 0x02, 0xec, 0xed, 0x09, 0x00, 0xc4, + 0x01, 0x00, 0xbb, 0x00, 0x2e, 0x80, 0x08, 0xb0, + 0x02, 0x2c, 0x00, 0x3a, 0x04, 0x2e, 0x00, 0x2a, + 0x80, 0x03, 0xa0, 0x00, 0x9b, 0x00, 0x22, 0x80, + 0x49, 0x80, 0x12, 0xe0, 0x00, 0xdb, 0x00, 0x22, + 0xc0, 0x0b, 0xb0, 0x22, 0xe1, 0x84, 0x88, 0x40, + 0x22, 0x46, 0x0b, 0x80, 0x02, 0xe1, 0x20, 0xbb, + 0x04, 0x20, 0x02, 0x0b, 0xb0, 0x02, 0xe0, 0x02, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, 0xe4, + 0x00, 0x80, 0x00, 0x22, 0xc0, 0x09, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2e, 0xc0, 0x08, 0xb0, + 0x02, 0x4c, 0x00, 0xa2, 0x00, 0x2e, 0x40, 0x00, + 0x30, 0x02, 0xcc, 0x09, 0xb3, 0x00, 0x28, 0xc0, + 0x0b, 0x00, 0x02, 0xe8, 0x00, 0xa3, 0x00, 0x64, + 0xc0, 0x0b, 0x30, 0x02, 0xc1, 0x00, 0xb0, 0x10, + 0x20, 0x48, 0x0b, 0x20, 0x12, 0xc1, 0x88, 0xb3, + 0x00, 0x20, 0x04, 0x0b, 0x30, 0x02, 0xe2, 0x01, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xa8, + 0x00, 0x8b, 0x00, 0x22, 0x40, 0x08, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0, + 0x02, 0x6c, 0x11, 0xba, 0x00, 0x2e, 0x00, 0x08, + 0x80, 0x12, 0xe0, 0x00, 0x9b, 0x88, 0x62, 0xd0, + 0x09, 0xa2, 0x82, 0xec, 0x00, 0x1b, 0x00, 0x26, + 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x80, 0xbb, 0x40, + 0x62, 0x44, 0x0b, 0x90, 0x02, 0xec, 0x20, 0xbb, + 0x00, 0x22, 0x08, 0x0b, 0xb0, 0x02, 0xf0, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0xed, + 0x00, 0xc8, 0x88, 0x32, 0xd0, 0x0d, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3c, 0xe8, 0x0c, 0x1c, + 0x03, 0x6a, 0x00, 0xfa, 0x02, 0x3e, 0x40, 0x0c, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3a, 0xf0, + 0x8f, 0x88, 0x03, 0xe9, 0x00, 0xe3, 0xc0, 0x36, + 0xc0, 0x0f, 0xb0, 0x03, 0xe1, 0x00, 0xf0, 0xed, + 0x09, 0x00, 0xc5, 0x01, 0xc4, 0x32, 0x60, 0x4d, + 0xa8, 0x03, 0xe0, 0x00, 0xfb, 0x00, 0x12, 0x32, + 0x0f, 0xb0, 0x03, 0xd0, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x01, 0xbc, 0x00, 0xff, 0xc0, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xd0, 0x4f, 0xe4, 0x03, 0xbd, 0x00, + 0xfe, 0x00, 0x3f, 0x00, 0x0b, 0xc0, 0x03, 0xb0, + 0x04, 0xfc, 0x00, 0x3f, 0xe4, 0x0f, 0xd0, 0x03, + 0xf8, 0x40, 0xff, 0x10, 0xbb, 0xc0, 0x0f, 0xf0, + 0x23, 0xec, 0x00, 0x8b, 0x10, 0xbf, 0xe0, 0x0f, + 0xd2, 0x43, 0xfe, 0x40, 0x7f, 0x00, 0x3f, 0xe0, + 0x4f, 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x10, 0xad, 0x00, 0xea, 0x40, + 0x32, 0xf0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xd0, 0x0f, 0xb4, 0x23, 0x28, 0x40, + 0xda, 0x00, 0x32, 0x40, 0x0c, 0xb0, 0x83, 0xec, + 0x08, 0xcb, 0x00, 0x32, 0xd0, 0x0f, 0xb4, 0x03, + 0xec, 0x00, 0xcb, 0x42, 0x32, 0xc0, 0x0f, 0xb0, + 0x07, 0xcd, 0x22, 0xc8, 0x40, 0x32, 0xe8, 0x2c, + 0xb0, 0x03, 0xe1, 0x20, 0xcb, 0x00, 0x7e, 0xc4, + 0x0c, 0xb0, 0x03, 0xd0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x01, 0x0c, 0x00, 0x83, 0x10, + 0x28, 0x40, 0x0d, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xf4, 0x0b, 0xb2, 0x02, 0x2c, 0x00, + 0x8a, 0x01, 0x28, 0x14, 0x28, 0x88, 0x02, 0xe0, + 0x70, 0x83, 0x20, 0x22, 0xe1, 0x0b, 0xb1, 0x02, + 0xcf, 0x00, 0x0b, 0x00, 0x22, 0xc0, 0x0b, 0xb0, + 0x02, 0xed, 0x18, 0x0b, 0x50, 0x22, 0xd0, 0x08, + 0x8c, 0x82, 0xef, 0x00, 0xd3, 0x05, 0x72, 0xd4, + 0x28, 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x05, 0x44, 0x00, 0xa1, 0xc0, + 0x20, 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xed, 0x09, 0x00, 0xc6, 0x01, 0xe0, + 0x0b, 0x34, 0x82, 0x06, 0x00, 0xa2, 0x00, 0x20, + 0x40, 0x0a, 0x3c, 0x02, 0xcd, 0x00, 0x93, 0x20, + 0x24, 0xe8, 0x03, 0x00, 0x02, 0xc8, 0xc0, 0xa2, + 0xc8, 0x24, 0xc0, 0x0b, 0x30, 0x02, 0xc3, 0x40, + 0x80, 0x42, 0x64, 0x50, 0x11, 0x28, 0x02, 0xc3, + 0x50, 0x83, 0x18, 0x28, 0x30, 0x08, 0x30, 0x02, + 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x3e, 0x04, 0x8f, 0xa2, 0x29, 0xe0, 0x09, + 0x78, 0x02, 0xde, 0x00, 0xb7, 0x82, 0x2d, 0xe0, + 0x0b, 0x78, 0x02, 0x1e, 0x04, 0x86, 0x80, 0x2b, + 0x20, 0x08, 0x48, 0x02, 0xf2, 0x40, 0x9f, 0x80, + 0x25, 0xe2, 0x0b, 0x48, 0x12, 0xda, 0x00, 0xaf, + 0x80, 0x25, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x50, + 0x84, 0xa0, 0x25, 0xe0, 0x99, 0x7c, 0x02, 0xc2, + 0x00, 0x97, 0x84, 0x21, 0xe4, 0x08, 0x78, 0x02, + 0xc8, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x08, 0x04, 0x00, 0xe1, 0x08, 0x32, 0xc0, 0x2c, + 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0x82, + 0x0f, 0x30, 0x03, 0x0c, 0x08, 0xe2, 0x00, 0x30, + 0x44, 0x0e, 0x30, 0x83, 0xcc, 0x02, 0xd0, 0x00, + 0x34, 0x40, 0x0f, 0x20, 0x03, 0xcd, 0x02, 0xe3, + 0x48, 0x34, 0xc0, 0x0b, 0x30, 0x02, 0xcd, 0x00, + 0xc3, 0x00, 0xb6, 0xc0, 0x99, 0x30, 0x03, 0xcc, + 0x40, 0xc3, 0x00, 0x38, 0xc0, 0x0c, 0x30, 0x03, + 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x1d, 0x9c, 0x00, 0xf7, 0x24, 0x3f, 0x44, 0x0e, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x80, + 0x8f, 0xf0, 0x10, 0xfc, 0x00, 0xee, 0x00, 0x1f, + 0x04, 0x8f, 0xc1, 0x03, 0xf2, 0x00, 0xe7, 0x00, + 0xbb, 0xc4, 0x0f, 0xe1, 0x07, 0xfc, 0x00, 0xd7, + 0x00, 0x3b, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x24, 0x3b, 0xc0, 0x0e, 0xed, 0x09, 0x00, + 0xc7, 0x01, 0xe5, 0x03, 0xfc, 0x00, 0xff, 0x10, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xd0, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, 0xec, 0x00, + 0xf3, 0x80, 0x32, 0xe1, 0x0c, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3c, 0x40, 0x4e, 0xb0, 0x03, + 0xe4, 0x00, 0x7a, 0x00, 0x3e, 0x40, 0x0f, 0x38, + 0x03, 0x2c, 0x00, 0xcb, 0x00, 0x3e, 0xe0, 0x4c, + 0x90, 0x03, 0xe8, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xe2, 0x02, 0xcb, 0x80, 0x32, + 0x40, 0x0c, 0xb4, 0x03, 0xec, 0x10, 0xfb, 0x00, + 0x3e, 0x00, 0x0c, 0xb0, 0x03, 0xea, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, 0x04, + 0xb7, 0x00, 0x23, 0xc0, 0x08, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x08, 0x70, 0x02, + 0xdc, 0x00, 0xb6, 0x00, 0x2d, 0x00, 0x0b, 0x40, + 0x02, 0x10, 0x00, 0xa7, 0x00, 0x2d, 0xc0, 0x08, + 0x50, 0x12, 0xd8, 0x00, 0xb7, 0x01, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xfc, 0x00, 0x83, 0x02, 0x21, + 0xc0, 0x0d, 0x60, 0x02, 0xdc, 0x10, 0xb7, 0x00, + 0x2f, 0xc0, 0x08, 0x70, 0x02, 0xd2, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, 0x00, + 0xbf, 0x88, 0x21, 0xe0, 0x08, 0x78, 0x02, 0xde, + 0x00, 0xb7, 0x80, 0x2f, 0xe0, 0x82, 0x78, 0x02, + 0xde, 0x00, 0xb6, 0x80, 0x2d, 0x60, 0x0b, 0xf8, + 0x42, 0x1e, 0x00, 0x87, 0x82, 0x6d, 0xe0, 0x0a, + 0x78, 0x02, 0xde, 0x04, 0xb5, 0x80, 0x6d, 0xe0, + 0x0b, 0x78, 0x02, 0xde, 0x00, 0xa7, 0x80, 0x21, + 0xe0, 0x08, 0x68, 0x02, 0xde, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x08, 0x78, 0x02, 0xf0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xce, 0x00, + 0xb3, 0x81, 0xa0, 0x40, 0x08, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xe0, 0x58, 0x3a, 0x02, + 0xed, 0x09, 0x00, 0xc8, 0x01, 0xcd, 0x20, 0xb2, + 0x00, 0x2c, 0x00, 0x0b, 0x00, 0x22, 0x00, 0x11, + 0xa0, 0x40, 0x2c, 0xe0, 0x2a, 0x38, 0x42, 0xcc, + 0x00, 0xb3, 0xc8, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xcd, 0x40, 0xa3, 0xc2, 0xa0, 0xe0, 0x19, 0x30, + 0x02, 0xcc, 0x20, 0xb3, 0x00, 0x2c, 0xdc, 0x28, + 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x15, 0xb9, 0x90, 0xfe, 0x00, 0x33, + 0x90, 0x2c, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, + 0x3d, 0xb0, 0x8e, 0x68, 0x03, 0xf9, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x4f, 0xa0, 0x0b, 0x08, 0x00, + 0xce, 0x80, 0x3f, 0xb2, 0x0e, 0xec, 0x03, 0xf9, + 0x10, 0xfe, 0x20, 0x3e, 0x80, 0x0f, 0xa0, 0x03, + 0xf9, 0x00, 0xee, 0x81, 0x32, 0x80, 0x0c, 0xa4, + 0x43, 0xfb, 0x00, 0xfa, 0x00, 0x3f, 0xb0, 0x0c, + 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0xe2, 0x00, 0x38, 0x00, 0x3e, + 0x20, 0x0f, 0x80, 0x01, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x24, 0x0f, 0x85, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, + 0xf8, 0x70, 0x3e, 0x30, 0x01, 0x89, 0x03, 0xe3, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x80, 0x98, 0x18, 0x3e, 0x14, 0x0f, 0x88, + 0x03, 0xe0, 0x40, 0xf8, 0x41, 0x3e, 0x00, 0x0f, + 0x80, 0x13, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x40, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x64, 0x0c, 0x98, 0x03, 0x24, 0x40, 0xf9, + 0x00, 0x2e, 0x40, 0x4f, 0x90, 0x03, 0xe4, 0x00, + 0xc9, 0x10, 0x3e, 0x40, 0x0f, 0x92, 0x03, 0xe6, + 0x40, 0xf9, 0x20, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe6, 0x00, 0xf9, 0x04, 0x3c, 0x60, 0x0e, 0x90, + 0x03, 0xe4, 0x40, 0xed, 0x09, 0x00, 0xc9, 0x01, + 0xc9, 0x00, 0xb0, 0x40, 0x0c, 0x90, 0x03, 0xc2, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, + 0x64, 0x10, 0xb9, 0xc8, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x50, 0x08, + 0x90, 0x02, 0x26, 0x80, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xa9, 0x09, 0x2e, + 0x50, 0x0b, 0x9c, 0x02, 0xe4, 0x00, 0xb9, 0x80, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe7, 0x40, 0xb9, + 0x40, 0x2e, 0x58, 0x00, 0x94, 0x00, 0xe7, 0x00, + 0x81, 0x20, 0x22, 0x50, 0x08, 0x90, 0x00, 0xe0, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, + 0x2c, 0x00, 0xb9, 0x00, 0x2e, 0xc4, 0x0b, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x42, 0x08, + 0xb2, 0x2a, 0x2c, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0xd0, 0x02, 0xf4, 0x00, 0x89, 0x00, 0x2e, + 0x60, 0x0b, 0x94, 0x02, 0xe4, 0x28, 0xb9, 0x40, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x08, 0x2e, 0x48, 0x2a, 0xb1, 0x02, 0xc4, 0x20, + 0x89, 0x00, 0x22, 0x46, 0x08, 0x90, 0x02, 0xc6, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x50, 0x0b, 0x10, + 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x08, + 0xb0, 0x02, 0x04, 0x00, 0xb1, 0x02, 0x2d, 0x40, + 0x0b, 0x50, 0x02, 0xf4, 0x00, 0xa1, 0x00, 0x2c, + 0xc0, 0x0b, 0x10, 0x22, 0xc4, 0x00, 0xb1, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xcd, 0x10, 0x91, + 0x00, 0x2c, 0x50, 0x08, 0x1c, 0x02, 0xc5, 0x02, + 0x81, 0x00, 0x24, 0x50, 0x08, 0x10, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, + 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, + 0x80, 0x03, 0x20, 0x00, 0xf8, 0x00, 0xed, 0x09, + 0x00, 0xca, 0x01, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xf0, 0x00, 0xc8, 0x00, 0x3e, 0x00, 0x8f, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x04, 0x3c, 0x00, + 0x2e, 0xc0, 0x03, 0xe0, 0x00, 0xc8, 0x00, 0x32, + 0x00, 0x2c, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x1d, 0xf4, 0x04, 0xfd, + 0x01, 0x3f, 0xc0, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3f, 0x40, 0x2f, 0xd0, 0x03, 0xf4, + 0x00, 0xf9, 0x01, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xc4, 0x10, 0xff, 0x01, 0x3d, 0x41, 0x0f, 0xd0, + 0x43, 0xf4, 0x00, 0xfd, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xf5, 0x00, 0xff, 0x40, 0x3f, 0x50, + 0x4f, 0xd0, 0x03, 0xf5, 0x04, 0xf9, 0x00, 0x3b, + 0x50, 0x0f, 0x90, 0x03, 0xe6, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, 0x00, 0xfd, + 0x00, 0xb3, 0x41, 0x0d, 0x90, 0x23, 0xe4, 0x00, + 0xf9, 0x00, 0x3d, 0x40, 0x0c, 0xd0, 0x03, 0x14, + 0x00, 0xc9, 0x00, 0x3c, 0x40, 0x0f, 0x90, 0x03, + 0xa4, 0x00, 0xfd, 0x00, 0x3b, 0x40, 0x07, 0xd0, + 0x03, 0x3c, 0x00, 0xfd, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xf4, 0x00, 0xfd, 0x00, 0x33, 0x48, + 0x0f, 0xd0, 0x03, 0xf4, 0xd0, 0xfd, 0x02, 0x1b, + 0x40, 0x0f, 0x90, 0x03, 0xc6, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 0xb8, + 0x00, 0x22, 0x02, 0x08, 0x80, 0x02, 0xe0, 0x00, + 0xb8, 0x00, 0x2e, 0x00, 0x8d, 0x80, 0x42, 0x20, + 0x00, 0x88, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, + 0x30, 0x00, 0xb8, 0x04, 0x22, 0x00, 0x4b, 0x80, + 0x03, 0x60, 0x10, 0xba, 0x00, 0x2e, 0x00, 0x0b, + 0x80, 0x22, 0xe0, 0x20, 0xbc, 0x10, 0x22, 0x0a, + 0x0b, 0x82, 0x02, 0xe8, 0xc0, 0xbc, 0x00, 0x2e, + 0x82, 0xed, 0x09, 0x00, 0xcb, 0x01, 0x0b, 0x80, + 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x05, 0xc4, 0x00, 0xb9, 0x02, 0x22, 0x40, + 0x49, 0x10, 0x06, 0xc4, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x08, 0x90, 0x02, 0x24, 0x00, 0x81, 0x04, + 0x6d, 0x40, 0x0b, 0x50, 0x02, 0x94, 0x00, 0x91, + 0x01, 0x28, 0x60, 0x0b, 0x90, 0x02, 0x04, 0x00, + 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, + 0x40, 0xb1, 0x04, 0xa0, 0x4c, 0x0a, 0x12, 0x82, + 0xcc, 0x80, 0xb1, 0x00, 0x2c, 0x44, 0x0b, 0x10, + 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x15, 0xa4, 0x00, 0x39, 0x80, 0x22, 0x44, + 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x0e, + 0x40, 0x89, 0xb4, 0x02, 0x2c, 0x40, 0x89, 0x00, + 0x2e, 0x40, 0x0b, 0xd0, 0x06, 0x34, 0x01, 0xb9, + 0x00, 0x22, 0x40, 0x03, 0xb0, 0x00, 0x64, 0x45, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x20, 0x22, 0x40, 0x1b, 0x90, 0x02, + 0xe4, 0x80, 0xb9, 0x00, 0x2e, 0x60, 0x0b, 0x90, + 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x15, 0xe5, 0x80, 0xf1, 0x80, 0x72, 0x60, + 0x0d, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x42, 0x0c, 0x1c, 0x03, 0x24, 0x02, 0xc9, 0x00, + 0x3e, 0x40, 0x0f, 0x10, 0x03, 0xa4, 0x08, 0xd1, + 0x80, 0x3a, 0x74, 0x0f, 0x90, 0x83, 0x25, 0x20, + 0x79, 0x04, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe7, + 0x80, 0xf9, 0x80, 0x32, 0x60, 0x0e, 0x96, 0x03, + 0xe5, 0x00, 0xf9, 0x00, 0x3e, 0x50, 0x0f, 0x90, + 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x02, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x44, 0x0f, 0x9c, 0x0b, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0xed, 0x09, 0x00, 0xcc, + 0x01, 0x03, 0xe4, 0x01, 0xf9, 0xa0, 0x3e, 0x60, + 0x0f, 0x9a, 0x03, 0xe6, 0x00, 0xf9, 0x98, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x80, 0xb9, 0x04, + 0x3e, 0x64, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x42, 0x4f, 0x90, 0x03, 0xca, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa1, + 0x00, 0xf8, 0x20, 0x32, 0x00, 0x0c, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x12, 0x0d, 0x88, + 0x03, 0xe2, 0x00, 0xd8, 0x00, 0x33, 0x00, 0x0c, + 0xc0, 0x03, 0xf0, 0x00, 0xc8, 0x00, 0x3e, 0x00, + 0x0f, 0x88, 0x23, 0xe0, 0x00, 0xe8, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xe0, 0xc0, 0xf0, 0xd0, + 0x32, 0x00, 0x0f, 0x84, 0x03, 0xe1, 0x22, 0xc8, + 0x80, 0x3e, 0x10, 0x8f, 0x80, 0x03, 0xca, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x28, + 0x00, 0xbe, 0x40, 0x38, 0xa0, 0x00, 0xa0, 0x02, + 0xe8, 0x00, 0xba, 0x00, 0x2d, 0xb8, 0x08, 0xec, + 0x03, 0x99, 0x00, 0x8a, 0x00, 0x22, 0x80, 0x28, + 0xa0, 0x02, 0xe8, 0x00, 0x0e, 0x00, 0x2f, 0x81, + 0x0b, 0x6e, 0x12, 0xf8, 0x40, 0x8e, 0xc1, 0x2e, + 0x80, 0x0b, 0xa0, 0x02, 0xf8, 0x00, 0xba, 0x40, + 0x23, 0x88, 0x0b, 0xe4, 0x02, 0xf8, 0x00, 0x8a, + 0x40, 0x2f, 0xb0, 0x0b, 0xa0, 0x02, 0xca, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x4c, + 0x00, 0xb3, 0x92, 0x24, 0xe0, 0x20, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x09, 0x30, + 0x12, 0xce, 0x40, 0x92, 0x00, 0x24, 0x00, 0x08, + 0x00, 0x06, 0xc0, 0x00, 0x90, 0x32, 0x2c, 0x1c, + 0x0b, 0x30, 0x12, 0xce, 0x00, 0xb3, 0x90, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0x8e, 0x00, 0xb3, 0x00, + 0xa0, 0xe8, 0x0b, 0x38, 0x92, 0xcd, 0x00, 0x03, + 0x10, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xca, 0xed, + 0x09, 0x00, 0xcd, 0x01, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x11, 0x1c, 0x00, 0xbf, 0x00, + 0x2b, 0xc2, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x08, 0x70, 0x82, 0xb4, 0x00, + 0x8e, 0x80, 0x25, 0x60, 0x08, 0x70, 0x02, 0xde, + 0x02, 0x97, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xde, 0x20, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x22, 0xdc, 0x00, 0xb6, 0x00, 0x21, 0xc0, 0x1b, + 0x74, 0x02, 0xce, 0x00, 0x86, 0x00, 0x2d, 0xc2, + 0x0b, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x00, 0x1e, 0x00, 0xf5, 0x80, + 0x25, 0xe0, 0x0c, 0x78, 0x03, 0xde, 0x00, 0xf7, + 0x80, 0x3d, 0xe0, 0x0d, 0x78, 0x13, 0xde, 0x08, + 0xd6, 0x80, 0xb5, 0x20, 0x0c, 0x48, 0x03, 0xd2, + 0x00, 0xd7, 0x80, 0x3d, 0xe0, 0x4f, 0x78, 0x03, + 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, + 0x03, 0x9e, 0x00, 0xf6, 0x90, 0x31, 0xe0, 0x4f, + 0x78, 0x03, 0xde, 0x10, 0xc6, 0x80, 0x2d, 0xe0, + 0x0f, 0x78, 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x15, 0xac, 0x00, 0xf3, 0x02, + 0x3c, 0x40, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xa0, 0x03, 0xac, 0x00, + 0xf2, 0x02, 0x3a, 0x40, 0x0f, 0xb0, 0x03, 0xcc, + 0x00, 0xea, 0x01, 0x3e, 0x40, 0x0f, 0xb0, 0x03, + 0xcc, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x04, 0xf3, 0x00, 0x3e, 0xc0, 0x9f, + 0xb0, 0x03, 0xec, 0x04, 0xfb, 0x08, 0x3e, 0x00, + 0x0f, 0xb0, 0x13, 0xc2, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xcf, 0x80, + 0x33, 0xe0, 0x0c, 0xf8, 0x03, 0xfe, 0x00, 0xff, + 0x80, 0x3d, 0xe0, 0x0c, 0xe2, 0x03, 0xfa, 0x00, + 0xfe, 0x80, 0x3d, 0x20, 0x2c, 0x49, 0x0a, 0x32, + 0x80, 0xff, 0xed, 0x09, 0x00, 0xce, 0x01, 0x90, + 0x11, 0xe4, 0x0c, 0xd8, 0x03, 0xfa, 0x00, 0xff, + 0x80, 0x33, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, + 0xfc, 0xa0, 0x3f, 0xe4, 0x1d, 0xf9, 0x03, 0xfe, + 0x02, 0xcc, 0x90, 0x3f, 0xe0, 0x0c, 0xf8, 0x03, + 0xc0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x11, 0x9c, 0x10, 0x87, 0x03, 0x21, 0x48, 0x0d, + 0x70, 0x02, 0x5c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x8d, 0x60, 0x02, 0xd8, 0x80, 0xb6, 0x20, 0x2d, + 0x48, 0x08, 0x70, 0x82, 0x1c, 0x20, 0xb5, 0x40, + 0x35, 0x85, 0x0d, 0x50, 0x02, 0xdd, 0x00, 0xb7, + 0x44, 0x29, 0xc0, 0x0b, 0x70, 0x16, 0xd0, 0x00, + 0xb5, 0x08, 0x2d, 0x00, 0x0b, 0x51, 0x02, 0xfc, + 0x40, 0x87, 0x41, 0x2d, 0xc0, 0x08, 0x70, 0x02, + 0xea, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbc, 0x40, 0xa7, 0x00, 0x23, 0xc0, 0x1a, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0x00, + 0x08, 0x61, 0x82, 0xdc, 0x04, 0xb6, 0x01, 0x2d, + 0x00, 0x48, 0x40, 0x00, 0x52, 0x84, 0xbf, 0x00, + 0x23, 0xc6, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xbf, + 0x00, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, + 0xb5, 0x21, 0x2d, 0xc2, 0x09, 0x70, 0x02, 0xd0, + 0x00, 0x85, 0x00, 0x2c, 0xc0, 0x08, 0x70, 0x02, + 0xc0, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x14, 0xcd, 0x80, 0xa3, 0x08, 0x22, 0x68, 0x0b, + 0x30, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xe1, + 0x09, 0x2c, 0x62, 0xcf, 0x40, 0xb2, 0x01, 0x6c, + 0x40, 0x08, 0x3a, 0x02, 0x4d, 0x00, 0xb3, 0xc9, + 0x24, 0xe0, 0x0b, 0x30, 0x02, 0xcd, 0x00, 0xb3, + 0x00, 0x28, 0xc0, 0x0b, 0x30, 0x02, 0xc2, 0x10, + 0xb0, 0x00, 0x6c, 0x00, 0x0b, 0xb4, 0x02, 0xc1, + 0x00, 0x82, 0x00, 0x2c, 0x22, 0x08, 0x30, 0x02, + 0xc8, 0x00, 0x30, 0x00, 0x00, 0xed, 0x09, 0x00, + 0xcf, 0x01, 0x00, 0x00, 0xa8, 0x15, 0xae, 0x30, + 0xeb, 0xc0, 0x32, 0xd0, 0x4e, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc8, 0x0c, 0xb4, 0x03, + 0xcf, 0x00, 0xfa, 0x00, 0x3e, 0x04, 0x4c, 0x84, + 0x03, 0x63, 0x40, 0xfb, 0x88, 0x32, 0xe0, 0x0e, + 0xb9, 0x23, 0xed, 0x00, 0xf3, 0x50, 0x32, 0xc0, + 0x0f, 0xb0, 0x03, 0xee, 0x20, 0xfa, 0xc0, 0x3e, + 0xc0, 0x0d, 0x92, 0x23, 0xef, 0x00, 0xca, 0x00, + 0x3e, 0xc0, 0x2c, 0xb0, 0x03, 0xea, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0x02, + 0x1b, 0x10, 0xbe, 0xc4, 0x09, 0xb0, 0x01, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x84, 0x83, + 0xec, 0x20, 0xfa, 0x04, 0x3e, 0x40, 0x0f, 0xb0, + 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x09, + 0xbc, 0x03, 0xed, 0x00, 0xfb, 0x14, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x20, 0xfb, 0x00, 0x3e, + 0xd0, 0x0f, 0x94, 0x03, 0xe0, 0x60, 0xfb, 0x40, + 0x3c, 0xc4, 0x0f, 0xb0, 0x03, 0xe0, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, 0x00, + 0xfd, 0x05, 0x3f, 0x40, 0x0c, 0xf0, 0x23, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0c, 0xd1, 0x03, + 0xfc, 0x00, 0xde, 0x00, 0x3f, 0x00, 0x0f, 0xc0, + 0x03, 0x30, 0x00, 0xfd, 0x80, 0x3f, 0xa0, 0x0f, + 0xf9, 0x03, 0xfe, 0xa8, 0xff, 0x00, 0x33, 0xc0, + 0x0f, 0xf0, 0x03, 0xf2, 0x00, 0xcf, 0x08, 0x3f, + 0x08, 0x8f, 0xc0, 0x83, 0x3c, 0x00, 0xff, 0x00, + 0x1f, 0xc4, 0x0c, 0xf0, 0x03, 0xc0, 0x40, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, 0x00, + 0xbb, 0x48, 0x2e, 0xe4, 0x08, 0xb0, 0x02, 0xec, + 0x00, 0xbb, 0x00, 0x2c, 0xf0, 0x08, 0x80, 0x02, + 0xec, 0x00, 0xaa, 0x00, 0x2e, 0x40, 0x0b, 0x30, + 0x22, 0x2c, 0x04, 0xbb, 0x80, 0x2e, 0xf0, 0x0b, + 0xed, 0x09, 0x00, 0xd0, 0x01, 0xb8, 0x42, 0xec, + 0x00, 0xba, 0xc0, 0x36, 0xc0, 0x0b, 0xb0, 0x22, + 0xe3, 0x00, 0x8a, 0x80, 0x2e, 0x32, 0x0f, 0x8c, + 0x80, 0xa2, 0x80, 0xba, 0x40, 0x2e, 0x20, 0x28, + 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0xd4, 0x08, 0x80, 0x02, 0xec, 0x80, 0x9a, + 0x00, 0x2e, 0x00, 0x4b, 0x80, 0x02, 0x20, 0x00, + 0xba, 0x20, 0x2e, 0x46, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0xbb, 0x20, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0xcd, 0x80, 0x8b, 0x20, 0x2e, 0xc0, 0x02, 0x98, + 0x02, 0x2c, 0x40, 0xb9, 0x00, 0x0e, 0x00, 0x08, + 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0x40, 0x28, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x08, 0x00, 0x02, 0xcc, 0x00, 0xa2, + 0x02, 0x2c, 0x40, 0x0b, 0xb0, 0x0a, 0x0c, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x22, 0xcc, + 0x00, 0xb1, 0x00, 0x24, 0xc0, 0x0b, 0x30, 0x06, + 0xc0, 0x00, 0x82, 0x80, 0x2c, 0x00, 0x0b, 0x00, + 0x02, 0x80, 0x00, 0xb2, 0x04, 0x6c, 0x20, 0x08, + 0x30, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xfb, 0x02, 0x3e, + 0x40, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0c, 0x80, 0x03, 0xe8, 0x00, 0xda, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x02, 0x20, 0x10, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x80, 0x03, 0xec, + 0x00, 0xbb, 0x00, 0x32, 0xc0, 0x8f, 0xb0, 0x03, + 0xe0, 0x00, 0xca, 0x00, 0x3e, 0x00, 0x0e, 0x90, + 0x03, 0x20, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, + 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1d, 0xed, 0x09, 0x00, 0xd1, 0x01, + 0xdc, 0x00, 0x76, 0x00, 0x3d, 0x40, 0x8f, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x2f, + 0xc0, 0x03, 0xf8, 0x00, 0xfe, 0x00, 0x3f, 0x40, + 0x0f, 0xf0, 0x03, 0xfc, 0x0c, 0xf4, 0x00, 0x3f, + 0x00, 0x0f, 0xd0, 0x13, 0xf4, 0x00, 0xf7, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0xff, + 0x00, 0x3f, 0x00, 0x0e, 0xc0, 0x03, 0xf0, 0x00, + 0xff, 0x00, 0x3f, 0x00, 0x0f, 0xf0, 0x03, 0xe8, + 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, + 0xf0, 0x00, 0xff, 0x48, 0x39, 0x01, 0x4d, 0xf0, + 0x83, 0xdc, 0x80, 0xcf, 0x04, 0x33, 0xc8, 0x0c, + 0xc0, 0x03, 0xfc, 0x20, 0xdf, 0x20, 0x37, 0xc1, + 0x0c, 0xc0, 0x03, 0xf0, 0x00, 0xe7, 0x20, 0x3f, + 0xc0, 0x4f, 0xc0, 0x2b, 0x7c, 0x00, 0xff, 0x08, + 0x35, 0x00, 0x0e, 0xf2, 0x83, 0x30, 0x40, 0x4f, + 0x11, 0x37, 0x10, 0x4c, 0x40, 0x02, 0x3c, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0xc4, 0x00, 0xbf, 0x60, 0x32, 0x00, 0x08, 0xf4, + 0x22, 0xfd, 0x48, 0xdf, 0x42, 0x03, 0xc4, 0x88, + 0x80, 0x22, 0xfd, 0xa4, 0xbf, 0x40, 0x2f, 0xd4, + 0x28, 0xb0, 0x02, 0x2c, 0x00, 0x0f, 0x50, 0x27, + 0xc0, 0x08, 0xb0, 0x02, 0x3d, 0x40, 0xbf, 0x40, + 0x2e, 0xc2, 0x0a, 0xf0, 0x02, 0xac, 0x00, 0xab, + 0x20, 0x22, 0xc0, 0x08, 0xb2, 0x02, 0xac, 0x00, + 0x9b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, + 0xc0, 0xa0, 0xb3, 0x20, 0x28, 0x00, 0x09, 0x30, + 0x02, 0x8c, 0x00, 0x83, 0x40, 0x20, 0xca, 0x28, + 0x00, 0x26, 0xcc, 0x80, 0x93, 0x10, 0x2c, 0xc0, + 0x00, 0xb8, 0x02, 0x4c, 0x00, 0x93, 0x00, 0x28, + 0xcf, 0x08, 0x38, 0x82, 0x0c, 0x01, 0xed, 0x09, + 0x00, 0xd2, 0x01, 0x93, 0x29, 0x20, 0xc0, 0x19, + 0x30, 0x06, 0xcc, 0x81, 0xa3, 0x00, 0x24, 0xc8, + 0x08, 0xb0, 0x82, 0x4c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x15, 0xa0, 0x60, 0xbb, + 0x00, 0xa6, 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0x9b, 0x03, 0x22, 0xc0, 0x0a, 0xa4, 0x06, 0xec, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x48, 0xb2, 0x02, + 0xec, 0x80, 0x9b, 0x00, 0x2e, 0xc0, 0x29, 0x30, + 0x02, 0x6c, 0x00, 0xbb, 0x00, 0x24, 0x20, 0x0b, + 0xb0, 0x42, 0xcd, 0x5d, 0xab, 0x00, 0x46, 0x41, + 0x08, 0xa0, 0x02, 0xec, 0x00, 0x9b, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xf0, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x15, 0xe7, 0x00, 0xfb, + 0x00, 0x38, 0xd2, 0x0d, 0xb0, 0x03, 0x8c, 0x04, + 0x43, 0x00, 0xb2, 0xc0, 0x08, 0x94, 0x13, 0xec, + 0x00, 0x5b, 0x00, 0x2e, 0xc0, 0x0c, 0xb0, 0x03, + 0x6d, 0x20, 0xfb, 0x00, 0x7e, 0xc0, 0x0f, 0xb9, + 0x03, 0x6c, 0x00, 0xdb, 0x00, 0x16, 0xc0, 0x0f, + 0xb0, 0x01, 0xee, 0x02, 0xcb, 0x02, 0x36, 0xe1, + 0x0c, 0xb0, 0x02, 0x6c, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xc0, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x01, 0xb4, 0x00, 0xf7, + 0x00, 0x3b, 0xd2, 0x0f, 0xf0, 0x03, 0xfc, 0x20, + 0xff, 0x00, 0x37, 0xc1, 0x0d, 0xf9, 0x83, 0xfc, + 0x00, 0xff, 0x04, 0x3d, 0xc2, 0x8f, 0xd0, 0x83, + 0x3e, 0x02, 0xef, 0x02, 0x77, 0xc0, 0x0e, 0xf0, + 0x03, 0xbc, 0x00, 0xdf, 0x00, 0x3f, 0xc0, 0x0e, + 0xf0, 0x03, 0xbe, 0x10, 0xdf, 0x00, 0x3b, 0xa4, + 0x2f, 0xdc, 0x03, 0xbc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x43, 0xf8, 0x40, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x10, 0xa4, 0x00, 0xcb, + 0x00, 0xed, 0x09, 0x00, 0xd3, 0x01, 0xf2, 0xc0, + 0x0e, 0xb0, 0x83, 0xec, 0x00, 0xcb, 0x00, 0x7c, + 0xc0, 0x0c, 0x98, 0x03, 0xac, 0x02, 0xcb, 0x04, + 0x02, 0xc5, 0x13, 0xb0, 0x03, 0x64, 0x40, 0xdb, + 0x04, 0x10, 0xc0, 0x0f, 0x90, 0x03, 0x2e, 0x00, + 0xfb, 0x00, 0x32, 0xd0, 0x0c, 0xb0, 0x03, 0xe5, + 0x02, 0xcb, 0x00, 0x36, 0xd0, 0x0c, 0xb4, 0x03, + 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x05, 0x24, 0x00, 0x8f, 0x00, 0x62, 0xf8, + 0x08, 0xf2, 0x02, 0xfe, 0x00, 0x8f, 0xf0, 0x5f, + 0xc0, 0x0d, 0x90, 0x03, 0xbc, 0x00, 0x8f, 0x00, + 0x23, 0xd0, 0x0b, 0x3c, 0x67, 0x0c, 0x00, 0xbf, + 0x08, 0x23, 0xc1, 0x0f, 0xb0, 0x02, 0x3d, 0x44, + 0xef, 0x00, 0x36, 0xc0, 0x0c, 0x7d, 0x82, 0xec, + 0x00, 0xcb, 0x00, 0x26, 0xc0, 0x08, 0x30, 0x02, + 0x2c, 0x00, 0xeb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x05, 0x44, 0x00, 0x83, 0x00, 0x20, 0x30, + 0x1a, 0x30, 0x02, 0xce, 0x10, 0xa3, 0x00, 0x2c, + 0xc0, 0x40, 0x24, 0x52, 0x8c, 0x08, 0xa3, 0x00, + 0x28, 0xf0, 0x1b, 0x39, 0x12, 0xcc, 0x00, 0x93, + 0x88, 0x28, 0xc0, 0x0b, 0x30, 0x06, 0x8c, 0x00, + 0xb3, 0x01, 0x20, 0xc1, 0x09, 0x38, 0x12, 0xcc, + 0x00, 0xbb, 0x00, 0x26, 0xc1, 0x08, 0x30, 0x02, + 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x12, 0x04, 0x83, 0x80, 0xa1, 0xa0, + 0x48, 0x78, 0x02, 0xde, 0x01, 0xa7, 0x90, 0x29, + 0xe0, 0x09, 0x79, 0x02, 0x8e, 0x00, 0xa3, 0x80, + 0xa9, 0xe0, 0x4b, 0x78, 0x06, 0x17, 0x00, 0xb7, + 0x90, 0x21, 0xe0, 0x82, 0x58, 0x02, 0x1e, 0x40, + 0xa3, 0x90, 0x27, 0xe0, 0xed, 0x09, 0x00, 0xd4, + 0x01, 0x20, 0x78, 0x02, 0xd6, 0x08, 0xa7, 0x80, + 0x27, 0xc0, 0x08, 0xf0, 0x02, 0x1e, 0x00, 0xa7, + 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xc8, 0x80, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x20, 0x40, 0x0e, 0x32, 0x03, + 0xcc, 0x62, 0xe3, 0x00, 0x2e, 0xc0, 0x0c, 0x30, + 0x03, 0x8c, 0x98, 0xa3, 0x11, 0x38, 0xc4, 0x8b, + 0x10, 0x52, 0xcc, 0x08, 0x93, 0x06, 0x38, 0xc1, + 0xc3, 0xb0, 0x43, 0x8c, 0x54, 0xf3, 0x04, 0x30, + 0xc0, 0x49, 0x30, 0x43, 0xec, 0x40, 0x73, 0x10, + 0x34, 0x84, 0x0c, 0x11, 0x03, 0x0c, 0x00, 0xf3, + 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xd2, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, 0xb8, + 0x02, 0xff, 0x00, 0x3f, 0x04, 0x0f, 0xf0, 0x03, + 0xfc, 0x10, 0xdf, 0x00, 0x3f, 0xd0, 0x4f, 0xe0, + 0x03, 0xfc, 0x00, 0xdf, 0x05, 0x37, 0xc0, 0x0b, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x1b, 0xfc, 0x40, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf1, 0x03, 0xfc, 0x40, 0xdf, 0x04, + 0x35, 0xcc, 0x0f, 0xf3, 0x03, 0xfc, 0x40, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xd0, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, 0xe4, + 0x00, 0xeb, 0x21, 0x3e, 0xc0, 0x0c, 0xb0, 0x03, + 0xec, 0x28, 0xfb, 0x70, 0x32, 0xd0, 0x0f, 0x38, + 0x03, 0x6d, 0x20, 0xeb, 0x70, 0x3e, 0xdc, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0xd8, 0x3a, 0xc0, + 0x2c, 0xb0, 0x03, 0xcd, 0x40, 0xdb, 0x30, 0x32, + 0x00, 0x0e, 0xb6, 0x03, 0xec, 0x00, 0xab, 0x04, + 0x3e, 0x60, 0x0c, 0xa0, 0x03, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xea, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0xbc, + 0x18, 0x87, 0x28, 0x0d, 0xc0, 0x08, 0x76, 0xed, + 0x09, 0x00, 0xd5, 0x01, 0xc2, 0xdd, 0x80, 0x37, + 0x11, 0x09, 0xc0, 0x09, 0x70, 0x02, 0xdc, 0x80, + 0xa7, 0x30, 0x2d, 0xcc, 0x09, 0x70, 0x02, 0x5c, + 0x00, 0xb3, 0x20, 0x03, 0xda, 0x09, 0x70, 0x02, + 0xdc, 0xc0, 0x87, 0x29, 0x21, 0xc0, 0x0b, 0x75, + 0x02, 0x5c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x08, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x00, 0x96, 0x08, 0x27, 0x95, + 0x2d, 0xe1, 0x08, 0x78, 0x02, 0xde, 0x81, 0xb7, + 0xa0, 0x21, 0xe4, 0x0b, 0xf8, 0x46, 0x0e, 0x40, + 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x32, 0xde, + 0x00, 0xa7, 0x80, 0xa1, 0xe0, 0x09, 0x78, 0x02, + 0xde, 0x8c, 0x83, 0xa6, 0x21, 0xf0, 0x0a, 0x78, + 0x02, 0xde, 0x00, 0xa7, 0x82, 0x29, 0xf0, 0x08, + 0x78, 0x82, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0b, 0x78, 0x02, 0xf0, 0x40, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x14, 0xe4, 0x10, 0x83, 0x00, + 0x2c, 0xc0, 0x08, 0x30, 0x22, 0xcc, 0x00, 0xb3, + 0x00, 0x28, 0xc0, 0x09, 0x30, 0x06, 0x8c, 0x01, + 0x83, 0x00, 0x2c, 0xc0, 0x01, 0x19, 0x12, 0x44, + 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x0b, 0x10, 0x10, + 0xcc, 0x00, 0x03, 0x00, 0x00, 0x18, 0x0b, 0x30, + 0x02, 0x44, 0x49, 0xb3, 0x00, 0x2c, 0x10, 0x08, + 0x0e, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xe8, 0x15, 0xb9, 0x00, 0xea, 0x01, + 0x3f, 0xb2, 0x0c, 0xa0, 0x03, 0xe8, 0x00, 0xfa, + 0x00, 0x32, 0x80, 0x0f, 0xe4, 0x13, 0x68, 0x02, + 0xca, 0x00, 0x3e, 0x80, 0x17, 0xec, 0x03, 0xf9, + 0x80, 0x7a, 0x00, 0x12, 0x80, 0x08, 0xec, 0x01, + 0xe8, 0x02, 0xda, 0x00, 0x11, 0x90, 0x0e, 0xa0, + 0x03, 0xfb, 0xed, 0x09, 0x00, 0xd6, 0x01, 0x00, + 0xea, 0x00, 0x3b, 0x80, 0xac, 0xe4, 0x03, 0xa8, + 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, + 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0xe2, 0x00, 0xf8, 0x00, 0x3e, 0x30, 0x2f, + 0x04, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x88, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x8c, 0x03, 0xe2, 0x00, 0xf8, 0x00, + 0x16, 0x00, 0x0c, 0x89, 0x03, 0xc0, 0x00, 0xf8, + 0x02, 0xbe, 0x00, 0x0f, 0x00, 0x02, 0xe2, 0x04, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x07, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x10, 0xe4, 0x00, 0xc9, 0x00, 0x3e, 0x40, 0x8e, + 0x94, 0x03, 0x24, 0x40, 0xc1, 0x00, 0x30, 0x40, + 0x0c, 0x94, 0x03, 0xe4, 0x00, 0xe9, 0x00, 0x3e, + 0x40, 0x0f, 0x98, 0x07, 0xe4, 0x40, 0xf9, 0x00, + 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xe4, 0x00, 0xe9, + 0x00, 0x36, 0x40, 0x0d, 0x9c, 0x13, 0x24, 0x00, + 0xf9, 0x00, 0x3e, 0x42, 0x0d, 0x90, 0x13, 0x64, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x04, 0x64, 0x00, 0x89, 0x00, 0x2c, 0x40, 0x08, + 0x9e, 0x02, 0x06, 0x00, 0xa9, 0x92, 0xa2, 0x40, + 0x0a, 0x98, 0x03, 0xa4, 0x00, 0xa9, 0x00, 0x2e, + 0x4c, 0x0e, 0x9a, 0x02, 0xe4, 0x00, 0xb9, 0x80, + 0x2e, 0x40, 0x0a, 0x90, 0x02, 0xe4, 0x02, 0x99, + 0x00, 0x36, 0x40, 0x08, 0x90, 0x1a, 0x24, 0x00, + 0xb9, 0x00, 0x3a, 0x40, 0x0b, 0x90, 0x02, 0x24, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, + 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x05, 0x24, 0x02, 0x89, 0x00, 0x2e, 0x54, 0x0a, + 0x90, 0x02, 0xa4, 0x01, 0x99, 0xed, 0x09, 0x00, + 0xd7, 0x01, 0x40, 0x2a, 0x40, 0x28, 0x94, 0x02, + 0xc4, 0x00, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x91, + 0x02, 0x64, 0x20, 0xb9, 0x10, 0x2c, 0x40, 0x08, + 0x90, 0x02, 0xe6, 0x00, 0x91, 0x00, 0x22, 0xc0, + 0x49, 0x90, 0x82, 0x24, 0x00, 0xb9, 0x00, 0x2e, + 0xc0, 0x0b, 0x30, 0x02, 0x24, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x05, 0x00, + 0x81, 0x40, 0x2c, 0x40, 0x08, 0x10, 0x4a, 0x06, + 0x11, 0xb1, 0x00, 0x20, 0x50, 0x4a, 0x10, 0x02, + 0x85, 0x00, 0xa1, 0x00, 0x2c, 0x40, 0x0a, 0x10, + 0x02, 0xc4, 0x00, 0xb3, 0x00, 0x2c, 0x50, 0x08, + 0x14, 0x02, 0xc4, 0x00, 0x91, 0x40, 0x26, 0x50, + 0x08, 0x10, 0x02, 0x05, 0x00, 0xb1, 0x44, 0x6c, + 0x50, 0x0b, 0x14, 0x02, 0x04, 0x00, 0xb1, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x60, 0x00, + 0xc8, 0x00, 0x2e, 0x00, 0x0e, 0x80, 0x03, 0xa0, + 0x00, 0x98, 0x00, 0x3a, 0x00, 0x0c, 0x80, 0x03, + 0xe0, 0x02, 0xc8, 0x00, 0x3e, 0x00, 0xcf, 0x80, + 0x02, 0x60, 0x04, 0xf8, 0x01, 0x3e, 0x00, 0x2c, + 0x80, 0x02, 0xe8, 0x00, 0xc8, 0x00, 0x32, 0x00, + 0x0d, 0x80, 0x03, 0x20, 0x01, 0xf8, 0x00, 0x3c, + 0x00, 0x0f, 0x80, 0x0b, 0x20, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xee, 0x02, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x98, 0x1d, 0xf4, 0x00, + 0xf9, 0x40, 0x3d, 0x40, 0x8d, 0x94, 0x03, 0xe5, + 0x00, 0xe1, 0x44, 0x1e, 0x50, 0x2d, 0xd0, 0x23, + 0xa5, 0x00, 0xd9, 0x40, 0x3e, 0x50, 0x0b, 0xd0, + 0x03, 0xf4, 0x00, 0xf9, 0x40, 0x3e, 0x50, 0x0f, + 0xd0, 0x13, 0xe5, 0x00, 0xc9, 0x40, 0x3f, 0x40, + 0x0f, 0x94, 0x03, 0xf4, 0x00, 0xf9, 0x00, 0x3b, + 0xed, 0x09, 0x00, 0xd8, 0x01, 0x40, 0x0f, 0xd0, + 0x23, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x05, 0xec, 0x40, 0xf9, 0x05, 0x3f, + 0x40, 0x0a, 0xd0, 0x03, 0xf4, 0x80, 0xcd, 0x28, + 0x3e, 0x4c, 0x0c, 0xf0, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3f, 0x49, 0x9e, 0x50, 0x63, 0xf4, 0x00, + 0xdd, 0x00, 0x36, 0x40, 0x0c, 0x91, 0x03, 0x74, + 0x80, 0xd9, 0x28, 0x36, 0x44, 0x0f, 0x50, 0x03, + 0x24, 0x08, 0xb9, 0x10, 0x14, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x10, 0xe0, 0x90, 0xb8, 0x48, 0x2e, + 0x00, 0x28, 0x81, 0x02, 0xe0, 0x00, 0x88, 0x02, + 0x26, 0x0c, 0x08, 0x80, 0x02, 0xe0, 0x20, 0xf8, + 0x10, 0x2e, 0x00, 0x08, 0x80, 0x02, 0xe0, 0x00, + 0xb8, 0x40, 0x2e, 0x02, 0x08, 0x80, 0x02, 0xe0, + 0x00, 0xb8, 0x20, 0x2e, 0x88, 0x0b, 0x84, 0x02, + 0x20, 0x30, 0xb8, 0x00, 0x22, 0x0a, 0x0b, 0xa2, + 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, + 0x80, 0x02, 0xce, 0x44, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x05, 0xc4, 0x80, 0x91, 0x30, 0x2e, + 0x40, 0x18, 0x10, 0x02, 0xc4, 0x43, 0x83, 0x00, + 0x2c, 0x48, 0x08, 0x18, 0x06, 0xc4, 0x44, 0xb1, + 0x00, 0x2c, 0x44, 0x0a, 0x10, 0x02, 0xcc, 0x00, + 0xa3, 0x10, 0x2c, 0x44, 0x09, 0x10, 0x02, 0x84, + 0x40, 0xb1, 0x28, 0x2c, 0x48, 0x0b, 0x11, 0x0e, + 0x46, 0x01, 0x91, 0x00, 0x24, 0x48, 0x8b, 0x12, + 0x82, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, + 0x10, 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x02, 0x2e, + 0x40, 0x08, 0x90, 0x42, 0xe4, 0x00, 0x89, 0x00, + 0x24, 0x40, 0x08, 0xed, 0x09, 0x00, 0xd9, 0x01, + 0x92, 0x06, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x08, 0x90, 0x42, 0xe4, 0x20, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x30, 0xe4, 0x00, 0x39, 0x00, + 0x6e, 0x44, 0x03, 0x90, 0x20, 0x64, 0x00, 0xb9, + 0x00, 0x22, 0x40, 0x0b, 0x98, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, + 0xe6, 0x20, 0xf9, 0x00, 0x3e, 0x52, 0x6c, 0x90, + 0x03, 0xc4, 0x00, 0xc9, 0x00, 0x3e, 0x40, 0x2c, + 0x90, 0x03, 0xe4, 0x15, 0xf9, 0x04, 0x3e, 0x40, + 0x0a, 0x90, 0x83, 0xe5, 0x00, 0xf9, 0x00, 0x1e, + 0x40, 0x0d, 0x92, 0x03, 0xe4, 0x00, 0xf9, 0x04, + 0x2e, 0x41, 0x0f, 0x90, 0x03, 0x64, 0x00, 0xd9, + 0x00, 0x36, 0x78, 0x0f, 0x94, 0x02, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe8, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, + 0xa4, 0x80, 0xf9, 0x00, 0x3e, 0x64, 0x8f, 0x90, + 0x03, 0xe4, 0x04, 0xf9, 0x00, 0x36, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x01, 0xe9, 0x00, 0x3e, 0x42, + 0x0f, 0x99, 0x03, 0xe6, 0x60, 0xf9, 0x00, 0x3c, + 0x41, 0x2c, 0x99, 0x03, 0xe4, 0x00, 0xf9, 0x02, + 0x3e, 0x60, 0x0f, 0x10, 0x93, 0xa6, 0x80, 0xf9, + 0x00, 0x3e, 0x48, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xca, + 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, + 0xa0, 0x00, 0xf8, 0x00, 0x32, 0x30, 0x2e, 0x88, + 0x03, 0xa2, 0x00, 0xf8, 0x80, 0x36, 0x00, 0x0c, + 0x88, 0x03, 0xe0, 0x02, 0xc8, 0x00, 0x3e, 0x00, + 0x0f, 0x88, 0x73, 0xa1, 0x10, 0xe8, 0x80, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xa0, 0x88, 0x38, 0x01, + 0x12, 0x10, 0x4f, 0x80, 0x03, 0xe0, 0x10, 0xc8, + 0x00, 0x3e, 0x10, 0x8c, 0x80, 0x03, 0xed, 0x09, + 0x00, 0xda, 0x01, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x28, 0x00, 0xba, + 0x00, 0x21, 0x90, 0x08, 0xe6, 0x02, 0x39, 0x00, + 0xbe, 0x40, 0x2e, 0x80, 0x48, 0xec, 0x03, 0xa8, + 0x00, 0x8a, 0x00, 0x2d, 0x92, 0x0b, 0xec, 0x02, + 0x39, 0x00, 0x8e, 0x40, 0x0e, 0x81, 0x0f, 0xa0, + 0x02, 0x3a, 0x00, 0x3a, 0x00, 0x26, 0x80, 0x0b, + 0xe4, 0x03, 0x28, 0x00, 0xda, 0x05, 0x2e, 0x80, + 0x08, 0xa0, 0x02, 0x68, 0x00, 0xba, 0x00, 0x2e, + 0x80, 0x0b, 0xa0, 0x02, 0xc8, 0x20, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x04, 0x0c, 0x00, 0xb3, + 0x00, 0x20, 0xc4, 0x08, 0x20, 0x02, 0x8e, 0x00, + 0xb3, 0x00, 0x64, 0xc0, 0x08, 0x38, 0x02, 0x8c, + 0x00, 0x93, 0x00, 0x2c, 0x30, 0x0b, 0x19, 0x02, + 0x80, 0x00, 0xa1, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0x81, 0x40, 0xb3, 0x00, 0x24, 0xc0, 0x0b, + 0x18, 0x42, 0x8c, 0x00, 0xbb, 0x05, 0x2c, 0xc0, + 0x88, 0x30, 0x42, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x01, 0x1c, 0xc0, 0xb7, + 0x80, 0xa3, 0xc0, 0x09, 0x58, 0x02, 0x95, 0x08, + 0xb7, 0x01, 0x2d, 0xc8, 0x28, 0x70, 0x82, 0x9e, + 0x80, 0x97, 0x00, 0x2d, 0xc0, 0x0b, 0x78, 0x26, + 0x3e, 0x00, 0x87, 0x00, 0x2d, 0xc8, 0x88, 0xf8, + 0x02, 0x9c, 0x09, 0xb7, 0xa0, 0xa5, 0xc0, 0x03, + 0x60, 0x80, 0xbe, 0x00, 0xb7, 0x30, 0x0f, 0xe8, + 0x18, 0x71, 0x00, 0x5c, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xc8, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x08, 0x1e, 0xa0, 0x7f, + 0xe8, 0x21, 0xe0, 0x0c, 0x58, 0x13, 0x9e, 0x08, + 0xf5, 0x80, 0x34, 0xf4, 0x04, 0x78, 0x03, 0xbe, + 0xc0, 0xed, 0x09, 0x00, 0xdb, 0x01, 0x17, 0x80, + 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0x9e, 0x04, 0xe7, + 0x81, 0x2d, 0xea, 0x0b, 0x7b, 0x13, 0x9e, 0x00, + 0xff, 0xa8, 0x31, 0xe0, 0x0f, 0x68, 0x01, 0x9f, + 0x40, 0xf7, 0xa0, 0x3d, 0xe0, 0x4c, 0x7a, 0x21, + 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, + 0x03, 0xca, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x1d, 0xad, 0x80, 0xfb, 0x20, 0x3c, 0xc1, + 0x0e, 0x30, 0x03, 0x6c, 0x10, 0xf9, 0x02, 0x3e, + 0xc8, 0x8f, 0xb0, 0x03, 0xac, 0x80, 0xeb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x4c, 0x00, 0xf9, + 0x00, 0x3e, 0xc0, 0x0f, 0x32, 0x03, 0x6c, 0x00, + 0xfb, 0x00, 0x3a, 0xc8, 0x1f, 0x90, 0x43, 0x0c, + 0x80, 0xdb, 0x08, 0x3e, 0xcc, 0x8f, 0xb2, 0x13, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0xfe, 0x00, 0xcf, 0x80, 0x3f, 0xa1, + 0x0f, 0xd8, 0x41, 0xfa, 0x10, 0xce, 0x80, 0x0b, + 0xe0, 0x0c, 0xc1, 0x03, 0x7e, 0x20, 0xdf, 0x80, + 0x3f, 0xe0, 0x0c, 0xf8, 0x02, 0xfe, 0x48, 0xbf, + 0x94, 0x3f, 0xe2, 0x0f, 0xf8, 0x83, 0xfe, 0x00, + 0xcf, 0x88, 0x17, 0xf2, 0x07, 0xe8, 0x13, 0xfe, + 0x00, 0xff, 0x80, 0x33, 0xd0, 0x0b, 0xfd, 0x13, + 0xfe, 0x40, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, + 0x03, 0xd0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x11, 0x9c, 0x60, 0x87, 0x00, 0x0d, 0xc8, + 0x09, 0x70, 0x02, 0x11, 0x00, 0x87, 0x00, 0x21, + 0xc8, 0x08, 0x70, 0x02, 0x9c, 0x00, 0xa7, 0x00, + 0x2d, 0x80, 0x08, 0x70, 0x02, 0xd8, 0xc0, 0x37, + 0x00, 0x2d, 0xc4, 0x09, 0x70, 0x02, 0xdc, 0x00, + 0x87, 0x00, 0x2d, 0xc0, 0x19, 0x60, 0x42, 0xdc, + 0x80, 0xb7, 0x00, 0x21, 0xc4, 0x0b, 0x70, 0x02, + 0xdc, 0x00, 0x97, 0x00, 0xed, 0x09, 0x00, 0xdc, + 0x01, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, + 0x02, 0x87, 0x00, 0x2d, 0x82, 0x19, 0x70, 0x02, + 0x4c, 0x00, 0x93, 0x00, 0x25, 0xc0, 0x08, 0x41, + 0x86, 0x0c, 0x00, 0x87, 0x00, 0x2d, 0x40, 0x09, + 0x50, 0x02, 0xd5, 0x00, 0xb7, 0x04, 0x29, 0xc0, + 0x0a, 0x70, 0x02, 0xd0, 0x00, 0xa7, 0x00, 0x2d, + 0xc0, 0x09, 0x60, 0x02, 0xdc, 0x28, 0xb7, 0x00, + 0xa1, 0xc4, 0x0b, 0x70, 0x02, 0xdc, 0x08, 0xb7, + 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xe0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, 0xcc, + 0x00, 0x83, 0x00, 0x2c, 0xb0, 0x19, 0x10, 0x02, + 0x40, 0x00, 0x90, 0x00, 0x26, 0xc0, 0x08, 0x06, + 0x02, 0x8c, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x09, + 0x3e, 0x22, 0xce, 0x00, 0xb3, 0x02, 0x2c, 0xc0, + 0x0b, 0x38, 0x00, 0xcc, 0x00, 0x83, 0x00, 0x2e, + 0xf4, 0x09, 0x20, 0x22, 0xcf, 0x00, 0x33, 0x02, + 0x28, 0xec, 0x0b, 0xb4, 0x02, 0xcc, 0x00, 0x93, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xd8, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x05, 0x9e, + 0x00, 0xcf, 0x00, 0x3e, 0x60, 0x09, 0x80, 0x03, + 0xec, 0x00, 0xdb, 0x00, 0x37, 0xc1, 0x3c, 0x3c, + 0x03, 0x3c, 0x00, 0xcb, 0x00, 0x2e, 0xc0, 0x1d, + 0xb8, 0x07, 0xef, 0x00, 0xbb, 0x00, 0x5f, 0xc0, + 0x07, 0xfe, 0x03, 0xec, 0x02, 0xef, 0x00, 0x2f, + 0xc0, 0x4d, 0xa0, 0x03, 0xfd, 0x00, 0xff, 0x00, + 0x33, 0xd0, 0x0f, 0xf5, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x07, 0xb0, 0x03, + 0xac, 0x00, 0xeb, 0x40, 0x32, 0xc0, 0x0f, 0xb0, + 0x43, 0xac, 0x01, 0xeb, 0x00, 0x3c, 0x50, 0xed, + 0x09, 0x00, 0xdd, 0x01, 0xae, 0x91, 0x03, 0xe5, + 0x40, 0xfb, 0x41, 0x3e, 0xc0, 0x0d, 0xb0, 0x23, + 0xe0, 0x00, 0x7b, 0x00, 0x3e, 0xc0, 0x0d, 0xa4, + 0x00, 0xec, 0x00, 0xfb, 0x00, 0x16, 0xc0, 0x0f, + 0xb8, 0x03, 0xec, 0x00, 0xdb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0xfc, 0x08, 0xdf, 0x00, + 0x33, 0xc2, 0x0f, 0x78, 0x03, 0x1c, 0x40, 0xcf, + 0x80, 0x3b, 0xc0, 0x08, 0xf0, 0x03, 0x5c, 0x04, + 0x67, 0x00, 0x33, 0x80, 0x0c, 0xf9, 0x03, 0xf8, + 0x00, 0xf7, 0xc0, 0x33, 0xc0, 0x0f, 0xf0, 0x83, + 0xdc, 0x40, 0xcf, 0x00, 0x3f, 0xc2, 0x0c, 0xe8, + 0x02, 0xfc, 0x30, 0x1f, 0x00, 0x2b, 0xc0, 0x0f, + 0xf0, 0x03, 0x3c, 0x00, 0x9f, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xc0, 0x44, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x81, 0x44, 0x6c, 0x00, 0x8b, 0x00, + 0x22, 0x64, 0x0b, 0x91, 0x02, 0x25, 0x00, 0x89, + 0x40, 0x2e, 0xc0, 0x08, 0xb0, 0x03, 0x6c, 0x02, + 0x8b, 0x04, 0x22, 0xec, 0x2c, 0xb4, 0x92, 0xed, + 0x20, 0xbb, 0x40, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x08, 0xa4, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, + 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xf0, 0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x05, 0x2c, 0x00, 0xb3, 0x00, + 0x22, 0x42, 0x0a, 0xb0, 0x02, 0x2c, 0x00, 0x9a, + 0x50, 0x2a, 0xc0, 0x0a, 0xb2, 0x02, 0x2c, 0x10, + 0x8b, 0x00, 0xa6, 0xc0, 0x09, 0xb0, 0x42, 0x6e, + 0x00, 0xb9, 0x40, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x34, 0x9b, 0x04, 0x2e, 0xc0, 0x08, 0x92, + 0x82, 0xec, 0x00, 0xb3, 0x00, 0x2a, 0xc0, 0x4b, + 0xb0, 0x12, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0xed, 0x09, 0x00, 0xde, 0x01, 0x02, + 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x2c, 0x00, 0xa3, 0x04, 0x28, 0x00, 0x0b, + 0x10, 0x00, 0x00, 0x02, 0x92, 0x00, 0x2c, 0xc0, + 0x28, 0x88, 0x02, 0x4c, 0x00, 0x03, 0x00, 0x20, + 0xc0, 0x0a, 0x30, 0x02, 0xcc, 0x01, 0xb3, 0x00, + 0x20, 0xc0, 0x0b, 0x30, 0x22, 0x4c, 0x00, 0x93, + 0x04, 0x24, 0xc0, 0x28, 0x20, 0x02, 0xcc, 0x08, + 0xb3, 0x00, 0x28, 0xc0, 0x03, 0x30, 0x00, 0x0c, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x12, + 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x5c, 0x00, 0xff, 0x00, 0x22, 0x00, 0x1e, + 0x90, 0x0b, 0x28, 0x00, 0x98, 0x00, 0x39, 0xc0, + 0x0e, 0x80, 0x03, 0x3c, 0x00, 0xcb, 0x03, 0x76, + 0xc0, 0x0d, 0xb0, 0x03, 0x6c, 0x15, 0xfb, 0x04, + 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xec, 0x02, 0xdf, + 0x00, 0x3f, 0xc0, 0x0c, 0xa0, 0x03, 0xfc, 0x00, + 0xd7, 0x00, 0x3b, 0xc0, 0x0f, 0xf0, 0x09, 0x2c, + 0x00, 0xdb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x0d, 0xfc, 0x00, 0xdf, 0x00, 0xb7, 0x00, 0x0b, + 0x70, 0x03, 0xf0, 0x00, 0xec, 0x00, 0x2f, 0xc0, + 0x4f, 0x40, 0x03, 0xfc, 0x00, 0xdf, 0x02, 0x7d, + 0x00, 0x0d, 0xc0, 0x03, 0xf0, 0x01, 0xfc, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xd0, 0x00, 0xef, + 0x00, 0x3f, 0xc0, 0x0f, 0xd0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x17, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x05, 0xf0, 0x90, 0xcc, 0x04, 0x33, 0x08, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x00, + 0x0f, 0xc0, 0x03, 0xf8, 0x00, 0xfe, 0x00, 0x13, + 0x80, 0x0f, 0xd0, 0x03, 0xfc, 0xed, 0x09, 0x00, + 0xdf, 0x01, 0x10, 0xc7, 0x00, 0x39, 0xc0, 0x0c, + 0xf0, 0x03, 0x38, 0x00, 0xf6, 0x02, 0x33, 0xc0, + 0x0f, 0xf0, 0x03, 0xfd, 0x10, 0xcc, 0x00, 0x3f, + 0x00, 0x0c, 0xc1, 0x03, 0xf4, 0x00, 0xfc, 0x20, + 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0xe0, 0xe0, + 0x88, 0x20, 0x22, 0x14, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0x9b, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, + 0xe8, 0x00, 0xba, 0x00, 0x22, 0x80, 0x0b, 0x80, + 0x02, 0xe0, 0x00, 0xd8, 0x00, 0x2e, 0x01, 0x28, + 0x80, 0x0a, 0x2c, 0x10, 0xb9, 0x00, 0x22, 0xc0, + 0x0b, 0xb0, 0x02, 0xcc, 0x82, 0xd8, 0x49, 0x2e, + 0x04, 0x08, 0x81, 0x02, 0xe4, 0x04, 0xb9, 0x68, + 0xb6, 0xc2, 0x0b, 0xb5, 0x02, 0xe0, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0xc4, 0x00, + 0x80, 0x0a, 0x20, 0x20, 0x0b, 0x30, 0x06, 0xcc, + 0x00, 0xb3, 0x01, 0x6c, 0x40, 0x0b, 0x00, 0x02, + 0xc0, 0x01, 0xbb, 0x00, 0x20, 0x80, 0x0b, 0x10, + 0x12, 0xcc, 0x00, 0x93, 0x00, 0x2a, 0xc0, 0x99, + 0x30, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x20, 0xc0, + 0x0b, 0x30, 0x02, 0xe8, 0x02, 0x80, 0x36, 0x2c, + 0x00, 0x08, 0x00, 0x02, 0xc0, 0x04, 0xb0, 0x10, + 0xe0, 0xc8, 0x8b, 0x30, 0x02, 0xe2, 0x11, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0xa6, 0x20, + 0x88, 0x00, 0x22, 0xa0, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0x9b, 0x00, 0x6e, 0x40, 0x0b, 0xa0, 0x02, + 0xec, 0x10, 0xbb, 0x00, 0x22, 0x80, 0x0b, 0x80, + 0x02, 0xe0, 0x00, 0x98, 0x04, 0x2e, 0x00, 0x09, + 0x80, 0x02, 0x6d, 0x10, 0xbb, 0x08, 0x22, 0xc0, + 0x0b, 0xb0, 0x02, 0xe9, 0x02, 0x9a, 0x24, 0x2c, + 0xc1, 0x28, 0xa0, 0x82, 0xe0, 0x10, 0xb9, 0xc0, + 0xa6, 0xc0, 0x0b, 0xb0, 0x02, 0xf0, 0x04, 0x60, + 0xed, 0x09, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0x15, 0xe2, 0x00, 0xc8, 0xca, 0x32, + 0x60, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0x13, 0x0f, 0x8d, 0x83, 0xe9, 0xc4, 0xfb, + 0x40, 0xb2, 0x80, 0x0f, 0x90, 0x07, 0xec, 0x00, + 0xcb, 0x00, 0x3a, 0xc0, 0x0d, 0x30, 0x23, 0x6c, + 0x40, 0xf3, 0x40, 0x32, 0xc0, 0x0f, 0xb0, 0x03, + 0xcd, 0x00, 0xc8, 0x4c, 0x3e, 0x10, 0x0c, 0x85, + 0x03, 0xe4, 0x20, 0xf0, 0x80, 0x32, 0xc0, 0x0f, + 0xb0, 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x01, 0xb0, 0x08, 0xfd, 0x10, 0x2f, + 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0x50, 0x0f, 0xc8, 0x03, 0xfe, 0x00, 0xff, + 0x00, 0x3f, 0x80, 0x0f, 0xc0, 0x37, 0xf0, 0x00, + 0xfc, 0x00, 0x3f, 0x00, 0x0e, 0xc0, 0x43, 0xbe, + 0x00, 0xff, 0xc0, 0xbf, 0xc0, 0x0f, 0xf0, 0x23, + 0xfe, 0x40, 0xfd, 0x80, 0x3e, 0x68, 0x0f, 0xf0, + 0x03, 0xf5, 0x00, 0xfd, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x10, 0xa4, 0x00, 0xc8, 0x08, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3a, 0x40, 0x0d, 0xa1, 0x03, 0xe9, 0x00, 0xfb, + 0x60, 0x3e, 0x80, 0x0f, 0x90, 0x03, 0xec, 0x80, + 0xcb, 0x08, 0x32, 0xc8, 0x0c, 0xb3, 0x03, 0xaf, + 0x20, 0xfb, 0x40, 0x32, 0xc0, 0x0f, 0xb0, 0x03, + 0xe9, 0xc0, 0xcb, 0x00, 0x32, 0x98, 0x2c, 0x94, + 0x03, 0xe1, 0x00, 0xc9, 0x48, 0x3e, 0xc1, 0x0f, + 0xb0, 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x05, 0x25, 0x40, 0x88, 0x00, 0x2e, + 0xc0, 0x4b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0x40, 0x88, 0xb8, 0x02, 0xed, 0x40, 0xb1, + 0x08, 0x2e, 0x80, 0x4b, 0x81, 0x26, 0xc2, 0x00, + 0xa8, 0x60, 0x20, 0xed, 0x09, 0x00, 0xe1, 0x01, + 0x20, 0x0a, 0x80, 0x02, 0x2d, 0x00, 0xbb, 0xe0, + 0x36, 0xc0, 0x0b, 0xb0, 0x02, 0xe9, 0x00, 0x8b, + 0x00, 0x22, 0xf1, 0x08, 0xbd, 0x02, 0xe3, 0x92, + 0x89, 0x08, 0x2e, 0xc0, 0x4b, 0xf0, 0x02, 0xf2, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, + 0x62, 0x00, 0x88, 0xc0, 0x2c, 0x00, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0x33, 0x00, 0x28, 0x40, 0x09, + 0x18, 0x02, 0xc9, 0x04, 0xb3, 0xc1, 0x2c, 0x80, + 0x4b, 0x10, 0x02, 0xcd, 0x00, 0x83, 0x00, 0x20, + 0xd0, 0x89, 0x3c, 0x02, 0x0d, 0x00, 0xb3, 0x20, + 0x20, 0xc0, 0x03, 0x30, 0x02, 0xc5, 0x00, 0x80, + 0x00, 0xa0, 0x00, 0x08, 0x05, 0x02, 0xc7, 0x80, + 0x83, 0x82, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xf8, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, + 0x1a, 0x00, 0x84, 0x84, 0x2d, 0xa0, 0x0b, 0x78, + 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2f, 0x60, 0x08, + 0x7c, 0x02, 0xde, 0x00, 0xb7, 0x90, 0x2d, 0xa0, + 0x0b, 0x48, 0x02, 0xf2, 0x00, 0xac, 0x80, 0xa3, + 0x20, 0x0b, 0xc8, 0x02, 0x1e, 0x00, 0xbf, 0x80, + 0x25, 0xe0, 0x0b, 0x78, 0x02, 0xd6, 0x02, 0x87, + 0x82, 0x21, 0xa0, 0x08, 0x58, 0x02, 0xd6, 0x40, + 0x85, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xc8, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x08, + 0x2c, 0x20, 0xc0, 0x18, 0x3c, 0x44, 0x0f, 0x30, + 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x38, 0xc0, 0x0d, + 0x11, 0x03, 0xc8, 0x20, 0xf2, 0x00, 0x3c, 0x80, + 0x0f, 0x10, 0x02, 0xcc, 0x20, 0xc3, 0x00, 0x30, + 0xc6, 0x0d, 0x31, 0x03, 0x84, 0x40, 0xf3, 0x00, + 0x30, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xc9, + 0x18, 0x30, 0x52, 0xcc, 0x30, 0x67, 0xec, 0x40, + 0xc3, 0x00, 0x3c, 0xc4, 0x0f, 0x30, 0x03, 0xd2, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0xe2, 0x01, 0x42, 0x1d, 0xbc, 0x00, 0xfc, + 0x00, 0x1f, 0xc0, 0x4f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3d, 0xc4, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xfe, 0x04, 0x3f, 0x80, 0x0f, 0xc0, 0x03, + 0xd0, 0x00, 0xfc, 0x01, 0x3f, 0x00, 0x0e, 0x48, + 0x4b, 0xfc, 0x54, 0xff, 0x10, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x40, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf1, 0x07, 0xfc, 0x40, 0xff, 0x10, 0x3f, + 0xc0, 0x0f, 0xf0, 0x83, 0xd0, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x05, 0xe4, 0x08, 0xf9, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xb0, 0x02, 0xe8, + 0x00, 0xfb, 0x00, 0x12, 0x80, 0x0e, 0x90, 0x03, + 0xec, 0x00, 0xf3, 0x80, 0x32, 0xc0, 0x0d, 0xb0, + 0x03, 0xec, 0x04, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xc4, 0x02, 0xea, 0x00, 0x3e, 0xc0, + 0x0c, 0xa8, 0x03, 0x36, 0x00, 0xca, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xea, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0x91, 0x98, 0x00, 0xb5, + 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x42, 0xdc, 0x00, + 0xb7, 0x00, 0x2d, 0x40, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x35, 0x80, 0x08, 0x40, 0x02, + 0xd0, 0x00, 0xb4, 0x00, 0x21, 0x00, 0x0b, 0x40, + 0x22, 0xdc, 0x00, 0xb7, 0x02, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xd4, 0x00, 0x87, 0x01, 0x2f, 0xc0, + 0x08, 0x70, 0x02, 0x14, 0x00, 0xd7, 0x00, 0x2d, + 0xc0, 0x0b, 0x7a, 0x02, 0xd2, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x9e, 0x00, 0xb6, + 0x80, 0x2d, 0xe0, 0x4b, 0x78, 0x06, 0xde, 0x00, + 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xda, + 0x00, 0xb7, 0xc0, 0x61, 0xa0, 0x0a, 0x58, 0x02, + 0xde, 0x00, 0xbf, 0x80, 0x21, 0xe1, 0x09, 0x78, + 0x02, 0xed, 0x09, 0x00, 0xe3, 0x01, 0xde, 0x20, + 0xb7, 0x80, 0x6d, 0xe0, 0x0b, 0x78, 0x02, 0xfe, + 0x00, 0xa7, 0xc0, 0x25, 0xe2, 0x08, 0x38, 0x02, + 0x0e, 0x00, 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x7a, + 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x14, 0xcd, 0x00, 0xb2, 0x00, 0x2c, 0xf0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x31, 0x02, 0xce, 0x00, 0xb1, 0x80, + 0x24, 0x80, 0x08, 0x00, 0x02, 0xc0, 0x00, 0xb0, + 0x00, 0xa0, 0x00, 0x0b, 0x00, 0x02, 0xce, 0x00, + 0xb3, 0x40, 0x6c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xa3, 0xc8, 0x2e, 0xc2, 0x88, 0x34, 0x42, + 0x0c, 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x15, 0xb8, 0x40, 0xf6, 0x40, 0x3f, 0x98, + 0x4f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3f, + 0x90, 0x0f, 0xe4, 0x03, 0xfb, 0x20, 0xf6, 0xc0, + 0x30, 0x80, 0x0e, 0xa0, 0x03, 0xe8, 0x00, 0xfa, + 0x00, 0x32, 0x80, 0x0d, 0xa0, 0x03, 0xf9, 0x00, + 0xf6, 0x70, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xd8, + 0x00, 0xee, 0x80, 0x37, 0xb0, 0x0c, 0xe0, 0x9b, + 0x38, 0x02, 0xce, 0x08, 0x3e, 0x80, 0x0f, 0xa0, + 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x80, 0x3e, 0x08, + 0x0f, 0x80, 0x01, 0xe0, 0x00, 0xf8, 0x00, 0x2e, + 0x20, 0x0f, 0x88, 0x03, 0xe2, 0x00, 0xf8, 0x80, + 0x3e, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, + 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x02, 0xe3, 0x00, + 0xf8, 0x40, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0x50, 0x01, 0x3e, 0x10, 0x2f, 0x80, 0x93, + 0xe0, 0x00, 0xf8, 0xc0, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0xe6, 0x80, 0xed, 0x09, 0x00, 0xe4, + 0x01, 0xc9, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x8f, 0x98, + 0x03, 0xe4, 0x00, 0xf9, 0x20, 0x32, 0x40, 0x0c, + 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x2e, 0x40, + 0x0e, 0x90, 0x03, 0xe4, 0x4c, 0xf9, 0x00, 0xa2, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x08, 0xc9, 0x00, + 0x32, 0x40, 0x0c, 0x9a, 0x01, 0xe4, 0x00, 0xb9, + 0x10, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x67, + 0x00, 0x89, 0x40, 0x22, 0x40, 0x0b, 0x90, 0x02, + 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x9d, + 0x02, 0xe4, 0x80, 0xb9, 0x40, 0x22, 0x40, 0x0a, + 0x10, 0x02, 0xa4, 0x00, 0xb9, 0x04, 0x2c, 0x40, + 0x08, 0x90, 0x02, 0xe6, 0x00, 0xb9, 0x40, 0x2a, + 0x40, 0x0b, 0x90, 0x02, 0xe7, 0x00, 0x89, 0x82, + 0xa2, 0x50, 0x08, 0x9c, 0x02, 0xe4, 0x00, 0x99, + 0x80, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe0, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0x05, + 0x00, 0x89, 0x00, 0x22, 0x40, 0x0b, 0x90, 0x02, + 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0x82, 0xe6, 0x00, 0xbb, 0x08, 0x22, 0x40, 0x08, + 0x90, 0x02, 0x34, 0x00, 0xbd, 0x00, 0x2f, 0x40, + 0x0a, 0xd0, 0x02, 0xe5, 0x00, 0xb9, 0x50, 0x2a, + 0x40, 0x0b, 0x90, 0x02, 0xe6, 0x00, 0x89, 0x11, + 0x02, 0x40, 0x28, 0x94, 0x02, 0xe4, 0x00, 0xb9, + 0x04, 0x0e, 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x05, + 0x00, 0x89, 0xc0, 0x20, 0x40, 0x0b, 0x10, 0x02, + 0xc4, 0x00, 0xb1, 0x04, 0x2c, 0x40, 0x0b, 0x10, + 0x02, 0xc4, 0x00, 0xb1, 0x00, 0xa2, 0x40, 0x0a, + 0x50, 0x02, 0x94, 0x00, 0xb5, 0x00, 0x2d, 0x40, + 0x08, 0x50, 0x02, 0xc4, 0x00, 0xb9, 0x00, 0xed, + 0x09, 0x00, 0xe5, 0x01, 0x28, 0x40, 0x0b, 0x10, + 0x02, 0xe7, 0x00, 0x81, 0x42, 0x20, 0x50, 0x08, + 0x14, 0x02, 0xc5, 0x00, 0x91, 0x42, 0x2c, 0x50, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb8, 0x0d, 0x60, 0x02, 0xc8, 0x00, + 0x32, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x32, 0x00, 0x0c, 0x80, 0x03, 0x20, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0e, 0xc0, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3a, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x00, 0xc8, 0x01, 0x32, 0x80, 0x8c, + 0x80, 0x03, 0xe0, 0x00, 0xfa, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xd8, 0x9d, 0xf5, 0x00, 0xff, 0x00, + 0xbf, 0xd0, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x00, + 0xf5, 0x00, 0x3c, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xf4, 0x00, 0xfd, 0x00, 0x36, 0x40, 0x0f, 0x90, + 0x13, 0xf4, 0x02, 0xff, 0x40, 0x3f, 0x50, 0x0f, + 0xf4, 0x03, 0xfd, 0x04, 0xfd, 0x40, 0x3e, 0x40, + 0x0d, 0x94, 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x05, 0xf5, 0x00, 0xcf, 0x00, + 0x3e, 0x48, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x00, + 0xfd, 0x01, 0x3e, 0x40, 0x0b, 0x90, 0x03, 0x04, + 0x00, 0xf1, 0x00, 0x3e, 0x40, 0x0d, 0x90, 0x03, + 0x34, 0x00, 0xfd, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xf4, 0x00, 0xcd, 0x68, 0x3f, 0x53, 0x4f, + 0xd0, 0x83, 0x35, 0x00, 0xcd, 0x40, 0x3e, 0x50, + 0x0c, 0x92, 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x10, 0xe1, 0x12, 0x88, 0x28, + 0x2e, 0x00, 0xed, 0x09, 0x00, 0xe6, 0x01, 0x0b, + 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, + 0x0b, 0x80, 0x12, 0xe0, 0x00, 0xb8, 0x00, 0x2e, + 0x00, 0x0b, 0x80, 0x03, 0x60, 0x08, 0xb8, 0x00, + 0x2e, 0x00, 0x8b, 0xc0, 0x02, 0x28, 0x00, 0xba, + 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x80, + 0xd8, 0x41, 0x2e, 0x10, 0x0b, 0x86, 0x0a, 0x21, + 0x04, 0x88, 0x40, 0x2e, 0x00, 0x0a, 0x85, 0x02, + 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x05, 0xc5, 0x80, 0x81, 0x00, 0x2c, 0x50, 0x0b, + 0x10, 0x06, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x60, + 0x0b, 0x10, 0x02, 0xc4, 0x01, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0xd0, 0x02, 0x54, 0x00, 0xb5, 0x00, + 0x2d, 0x40, 0x0b, 0xd0, 0x02, 0x04, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xe4, 0x20, + 0xa1, 0x00, 0x2c, 0x40, 0x0b, 0x12, 0x86, 0x85, + 0x82, 0x81, 0xe0, 0x2c, 0x48, 0x08, 0x10, 0x02, + 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x15, 0xa4, 0x00, 0x89, 0x00, 0x2e, 0x48, 0x0b, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x44, + 0x0b, 0x98, 0x02, 0xe4, 0x00, 0xb9, 0x08, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0x74, 0x00, 0xbd, 0x00, + 0x2f, 0x40, 0x0b, 0xd0, 0x22, 0x24, 0x00, 0xb9, + 0x10, 0x0e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, + 0x99, 0x00, 0x2e, 0x50, 0x0b, 0x90, 0x02, 0x24, + 0x00, 0x89, 0x20, 0x2e, 0x40, 0x02, 0x90, 0x02, + 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x15, 0xe7, 0x80, 0xc9, 0x01, 0x3e, 0x40, 0x8f, + 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x92, 0x03, 0xe4, 0x80, 0xf9, 0xc0, 0x3e, + 0x40, 0x0f, 0x10, 0x03, 0x64, 0x00, 0xf9, 0x01, + 0x3e, 0x41, 0x0d, 0x10, 0x0b, 0x27, 0x00, 0xf9, + 0x80, 0x3e, 0x40, 0x0f, 0x90, 0xed, 0x09, 0x00, + 0xe7, 0x01, 0x03, 0xe7, 0x20, 0xc9, 0x00, 0x3e, + 0x40, 0x0f, 0x9d, 0x03, 0x24, 0x00, 0xc9, 0x00, + 0x3e, 0x40, 0x0c, 0x90, 0x03, 0xe8, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x01, 0x84, 0x80, + 0xf9, 0xc0, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x43, + 0xe6, 0x88, 0xf9, 0x10, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x4f, + 0x90, 0x03, 0xe4, 0x40, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x80, 0xf9, 0xc1, 0x3e, + 0x64, 0x0f, 0x90, 0x03, 0xe7, 0x00, 0xf9, 0x80, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xca, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0xa3, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x8d, 0x03, + 0xe2, 0x00, 0xf8, 0x48, 0x3e, 0x01, 0x0f, 0xc0, + 0x03, 0xf0, 0x00, 0xcc, 0x00, 0x33, 0x00, 0x0f, + 0xc0, 0x03, 0xe2, 0x10, 0xf8, 0x44, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe1, 0x00, 0xc8, 0x40, 0x32, + 0x01, 0x4f, 0x82, 0x03, 0xc1, 0x00, 0xc8, 0x00, + 0x32, 0x00, 0x0f, 0x80, 0x03, 0xca, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x3a, 0x20, + 0xbe, 0xc0, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, + 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xec, 0x02, + 0xfb, 0x00, 0xbe, 0x48, 0x2e, 0x80, 0x0b, 0xa0, + 0x02, 0xe8, 0x00, 0xaa, 0x00, 0xa2, 0x80, 0x0b, + 0xa0, 0x42, 0xf9, 0x10, 0xbe, 0xa4, 0x26, 0x80, + 0x0b, 0xa0, 0x02, 0xd8, 0x12, 0xaa, 0x80, 0x23, + 0x80, 0x03, 0xe8, 0x02, 0x78, 0x02, 0x8e, 0x10, + 0x32, 0x80, 0x0b, 0xa0, 0x02, 0xca, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, 0x4c, 0x00, + 0xb3, 0x30, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, + 0xed, 0x09, 0x00, 0xe8, 0x01, 0x00, 0x33, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xce, 0x00, 0xb0, + 0x00, 0x2c, 0x80, 0x0b, 0x00, 0x02, 0xc0, 0x00, + 0x80, 0x00, 0x20, 0x00, 0x4b, 0x00, 0x22, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xcd, 0x60, 0x83, 0x80, 0x20, 0xc1, 0x0b, 0xb8, + 0x02, 0xcc, 0x00, 0x82, 0x80, 0x26, 0xc0, 0x0b, + 0x30, 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x01, 0x1c, 0x00, 0xb7, 0x02, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0xdc, 0x20, 0xb7, + 0x00, 0x2d, 0x80, 0x0b, 0x50, 0x02, 0xfe, 0x00, + 0xa7, 0x80, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xdc, + 0x08, 0xb6, 0x02, 0x05, 0xc0, 0x0b, 0x70, 0x02, + 0xfc, 0x00, 0xa7, 0x88, 0xa1, 0x00, 0x0b, 0x70, + 0x82, 0x44, 0x00, 0x83, 0xc0, 0x21, 0xc8, 0x0b, + 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x88, 0x1e, 0x00, 0xf7, 0x80, 0x3d, + 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, + 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, + 0x80, 0x3d, 0xa0, 0x0f, 0x48, 0x03, 0xd2, 0x00, + 0xc4, 0x80, 0x31, 0x20, 0x0f, 0x48, 0x03, 0xde, + 0x00, 0xf7, 0x80, 0x1d, 0xe0, 0x0f, 0x78, 0x02, + 0xde, 0x00, 0xcf, 0x80, 0x31, 0xa0, 0x0f, 0x78, + 0x13, 0xde, 0x10, 0xc6, 0x80, 0xb5, 0xe8, 0x0f, + 0x78, 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x1d, 0xa0, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x4f, 0xb0, 0x13, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x04, 0xfa, + 0x00, 0x3e, 0x80, 0x0f, 0x90, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xc8, 0x02, 0xfb, 0xed, 0x09, 0x00, 0xe9, 0x01, + 0x00, 0x3f, 0x00, 0x0f, 0xb0, 0x02, 0xf4, 0x00, + 0xf9, 0x00, 0x3e, 0xe0, 0x0f, 0xb0, 0x03, 0xc2, + 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, + 0xfe, 0x00, 0xfe, 0x80, 0x3f, 0xe0, 0x0c, 0xf9, + 0x03, 0xfe, 0x40, 0xff, 0x80, 0x3f, 0xe0, 0x0f, + 0x78, 0x03, 0x1e, 0x00, 0xef, 0x90, 0x3f, 0xa0, + 0x0f, 0x48, 0x03, 0xb2, 0x00, 0xf4, 0x80, 0x33, + 0x20, 0x0f, 0xc8, 0x03, 0xde, 0x00, 0xc7, 0x81, + 0x33, 0xe0, 0x0f, 0xf8, 0x03, 0xde, 0x00, 0xef, + 0x81, 0x33, 0xe0, 0x0c, 0xf8, 0x03, 0x3e, 0x00, + 0xcf, 0x80, 0x33, 0xe2, 0x0d, 0xf8, 0x03, 0xc0, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, + 0x99, 0x40, 0xb4, 0x40, 0x2d, 0xc0, 0x08, 0x70, + 0x42, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x03, 0x5c, 0x00, 0x85, 0x00, 0x2d, 0x80, + 0x0b, 0x50, 0x02, 0x1c, 0x00, 0xb7, 0x0c, 0x21, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x02, 0x86, 0x00, + 0x35, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x80, 0xd7, + 0x10, 0x21, 0x00, 0x08, 0x50, 0x02, 0x34, 0x00, + 0xaf, 0x00, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xea, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x9c, 0x00, 0xb6, 0x00, 0x2d, 0xc0, 0x08, 0x70, + 0x06, 0xdc, 0x01, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0xf5, 0x02, 0x3d, 0x20, 0xa7, 0x00, 0x2d, 0x80, + 0x0b, 0x40, 0x02, 0xd0, 0x00, 0xb4, 0x00, 0x21, + 0x00, 0x0b, 0x48, 0x02, 0xf8, 0x00, 0x87, 0x00, + 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xf4, 0x01, 0xa5, + 0x00, 0x20, 0x80, 0x08, 0x20, 0x82, 0x5c, 0x40, + 0x86, 0x40, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xc0, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x14, + 0xc6, 0x00, 0xb8, 0x00, 0x2c, 0xc4, 0x08, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xed, 0x09, + 0x00, 0xea, 0x01, 0xd2, 0x1b, 0x18, 0x06, 0x4e, + 0x00, 0x83, 0x80, 0x2c, 0x80, 0x0b, 0x10, 0x82, + 0x4e, 0x60, 0xb3, 0x04, 0x20, 0xe0, 0x0b, 0x30, + 0x82, 0xce, 0x20, 0x83, 0x00, 0x24, 0xc0, 0x0b, + 0x30, 0x02, 0xe0, 0x00, 0x99, 0xd0, 0x20, 0x04, + 0x88, 0x0c, 0x02, 0x44, 0x00, 0xa1, 0x80, 0xa0, + 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x15, 0xad, 0x00, 0xf9, + 0x10, 0x3e, 0xe0, 0x0c, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x2f, + 0x00, 0xeb, 0xa2, 0x3e, 0x80, 0x0f, 0x00, 0x03, + 0xe2, 0x00, 0xf8, 0x12, 0x70, 0x22, 0x0f, 0x08, + 0x03, 0xe4, 0x20, 0xcb, 0xa0, 0x32, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xeb, 0x80, 0xb2, 0x60, + 0x0c, 0xbc, 0x2b, 0x60, 0x00, 0xcb, 0x48, 0x33, + 0xc0, 0x0d, 0xb0, 0x03, 0xea, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, 0xc0, 0xf9, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x91, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0x80, 0x0f, 0x90, 0x03, + 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc2, 0x0f, 0xb1, + 0x03, 0xed, 0x00, 0xf9, 0x40, 0x3e, 0xc0, 0x07, + 0xb0, 0x03, 0xe4, 0x00, 0xf9, 0x08, 0x3f, 0x00, + 0x0f, 0xa4, 0x83, 0xa5, 0x00, 0xfb, 0x40, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xe0, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x10, 0xf0, 0x40, 0xfd, + 0x00, 0x32, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x74, + 0x09, 0xfd, 0x80, 0x33, 0x80, 0x0f, 0xc0, 0x03, + 0x30, 0x00, 0xcc, 0x00, 0x3f, 0x00, 0x08, 0xc0, + 0x03, 0xbe, 0x00, 0xcf, 0x0c, 0x33, 0xc0, 0x0f, + 0xf0, 0x03, 0xfe, 0x00, 0xcb, 0x00, 0x33, 0x02, + 0x0c, 0xed, 0x09, 0x00, 0xeb, 0x01, 0xd8, 0x00, + 0xb0, 0x40, 0xcf, 0x00, 0x3f, 0xc0, 0x0f, 0x70, + 0x03, 0x00, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x63, 0x04, 0xb9, 0xc4, 0x22, 0xc0, + 0x0b, 0xb0, 0x03, 0xac, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x4b, 0x34, 0x82, 0x2d, 0x08, 0xb3, 0x48, + 0x2a, 0x80, 0x0b, 0x90, 0x02, 0x8c, 0x02, 0x8b, + 0x04, 0x2e, 0xc0, 0x0c, 0xb0, 0x02, 0x07, 0x80, + 0x82, 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xe1, + 0x20, 0x89, 0x00, 0x22, 0x24, 0x08, 0x8d, 0x82, + 0x25, 0x00, 0x89, 0xcc, 0x2e, 0xc0, 0x09, 0xb0, + 0x02, 0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x05, 0x24, 0x00, 0xb9, 0x80, 0x22, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0x6e, 0x20, 0xba, 0x10, + 0x22, 0x80, 0x0b, 0x80, 0x02, 0xa0, 0x00, 0x88, + 0x00, 0x2e, 0x00, 0x0a, 0x80, 0x02, 0xa4, 0x40, + 0x8b, 0x88, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xe8, + 0x40, 0x9b, 0x10, 0x20, 0x40, 0x08, 0x30, 0x02, + 0x00, 0x20, 0x89, 0x80, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x01, 0xb0, 0x00, 0x20, 0xc0, + 0x0b, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0x08, 0x00, 0xbb, 0x00, + 0x28, 0x80, 0x0b, 0x90, 0x02, 0x8c, 0x10, 0x83, + 0x00, 0x2c, 0xc0, 0x0a, 0x30, 0x02, 0x0c, 0x00, + 0x8b, 0x02, 0xa0, 0xc0, 0x0b, 0x30, 0x02, 0xc0, + 0x00, 0x81, 0x00, 0xa0, 0x01, 0x08, 0x00, 0x06, + 0x04, 0x02, 0x81, 0x00, 0x2c, 0xc0, 0x09, 0x30, + 0x02, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x68, 0x00, 0xf8, 0x00, 0xb2, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xed, 0x09, 0x00, 0xec, + 0x01, 0x6c, 0x00, 0xbb, 0x04, 0x32, 0x80, 0x0f, + 0x80, 0x03, 0xa0, 0x00, 0xc8, 0x00, 0x3e, 0x00, + 0x8e, 0x80, 0x03, 0xac, 0x00, 0xcb, 0x00, 0x32, + 0xc0, 0x0f, 0xb0, 0x03, 0xe0, 0x02, 0xc9, 0x00, + 0x32, 0x00, 0x2c, 0x80, 0x0b, 0x20, 0x00, 0xc9, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x00, 0x03, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xf0, + 0x00, 0xfc, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, + 0x03, 0xf4, 0x00, 0xfc, 0x00, 0x3f, 0x80, 0x0f, + 0xd0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0c, 0xf0, 0x43, 0xf4, 0x00, 0xfc, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0xfd, 0x00, + 0x37, 0x00, 0x0f, 0xc0, 0x03, 0xf4, 0x04, 0xfd, + 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xe8, 0x06, + 0x50, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x85, 0xfc, + 0x00, 0xfc, 0x00, 0x33, 0x00, 0x0c, 0xd0, 0x01, + 0xfc, 0x80, 0xcf, 0x08, 0x33, 0xcd, 0x0c, 0xf3, + 0x23, 0x30, 0x00, 0xff, 0x28, 0x3f, 0x00, 0x0e, + 0xf2, 0x03, 0x3c, 0x00, 0xdd, 0x10, 0x33, 0xcc, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x33, + 0xd0, 0x0f, 0xe1, 0x03, 0x30, 0x40, 0xcf, 0x24, + 0x3b, 0xc0, 0x0c, 0xf4, 0x13, 0x3c, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x80, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x08, 0xbd, + 0x00, 0xba, 0x02, 0x22, 0x00, 0x18, 0x90, 0x12, + 0xfc, 0x40, 0x8f, 0x41, 0x23, 0xc4, 0x08, 0xf6, + 0x02, 0x20, 0x00, 0xbf, 0x40, 0x2e, 0xc0, 0x0b, + 0xf4, 0x4a, 0x3d, 0xc0, 0x83, 0x20, 0x27, 0xc0, + 0x0e, 0xf1, 0x02, 0xfc, 0x00, 0xbf, 0x10, 0x2a, + 0xc0, 0x0b, 0x80, 0x02, 0xac, 0x80, 0x8f, 0x10, + 0x2f, 0xd0, 0x28, 0xb0, 0x02, 0x2c, 0x00, 0xed, + 0x09, 0x00, 0xed, 0x01, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x04, 0x8c, 0x40, 0xb8, 0x00, + 0x22, 0x00, 0x09, 0x10, 0x02, 0xcc, 0x02, 0x83, + 0x00, 0x20, 0xc9, 0x08, 0x36, 0x02, 0x00, 0xa0, + 0xb3, 0x00, 0x2c, 0xc0, 0x0a, 0x31, 0x42, 0x0c, + 0x20, 0x83, 0x00, 0x2c, 0xd0, 0x0b, 0x30, 0x22, + 0x8c, 0x40, 0xa3, 0x00, 0x20, 0xc0, 0x0b, 0x80, + 0x02, 0x6c, 0x10, 0xa3, 0x00, 0x28, 0xc4, 0x08, + 0x32, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xe2, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x04, 0xac, 0x00, 0xbb, 0x02, + 0x22, 0x00, 0x08, 0x92, 0x02, 0xec, 0x00, 0x8b, + 0x00, 0x22, 0xc0, 0x08, 0xb0, 0x02, 0x2e, 0x01, + 0xbb, 0x05, 0x2e, 0xd4, 0x0b, 0xb0, 0x42, 0x2c, + 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0a, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0x2a, 0xc0, 0x0b, 0x80, + 0xa2, 0xec, 0xa0, 0xab, 0x04, 0x2e, 0xc0, 0x08, + 0x30, 0x02, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xf0, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x41, 0x15, 0xec, 0x00, 0xf3, 0x40, + 0xb0, 0x32, 0x2d, 0x90, 0x03, 0xec, 0x00, 0xcb, + 0x00, 0x32, 0xc0, 0x2c, 0xb0, 0x03, 0x2c, 0x88, + 0xfb, 0x00, 0x3e, 0xe0, 0x0e, 0xb0, 0x03, 0x2c, + 0x10, 0xdb, 0x80, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xf3, 0x00, 0x32, 0xc0, 0x0f, 0x88, + 0x03, 0x4e, 0x00, 0xeb, 0x00, 0x3a, 0xc0, 0x0c, + 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xd0, 0x44, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x01, 0xac, 0x00, 0xfd, 0xa0, + 0x3f, 0xb0, 0x0f, 0xf0, 0x43, 0xcc, 0x00, 0xf7, + 0x00, 0x3f, 0xc0, 0x0f, 0x70, 0x03, 0xfc, 0x14, + 0xff, 0x00, 0xed, 0x09, 0x00, 0xee, 0x01, 0x3f, + 0x43, 0x0f, 0xf0, 0x03, 0xdc, 0x00, 0xfd, 0x20, + 0x32, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x01, 0x3f, 0xc0, 0x0f, 0xe9, 0x03, 0xb6, 0x00, + 0xdf, 0x00, 0x3d, 0xc0, 0x0f, 0xf0, 0x03, 0x7c, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x43, + 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x10, 0xac, 0x40, 0xcb, 0x44, 0x1e, 0xc0, 0x2c, + 0x90, 0x03, 0xee, 0x28, 0xcb, 0x00, 0x3c, 0xc0, + 0x0c, 0xb0, 0x03, 0x2c, 0x00, 0xcb, 0x00, 0x32, + 0xc1, 0x9f, 0x30, 0xc3, 0x6c, 0x10, 0xcb, 0x00, + 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0x80, 0xcb, + 0x00, 0x3e, 0xc0, 0x0f, 0x80, 0x03, 0xe8, 0x10, + 0xfb, 0x10, 0x3e, 0xc1, 0x0f, 0xb0, 0x03, 0x2c, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x05, 0x3f, 0x40, 0x88, 0x22, 0x2e, 0x21, 0x28, + 0xb0, 0x02, 0xfd, 0x02, 0x8f, 0xa0, 0x2f, 0xc0, + 0x08, 0xf0, 0x02, 0x2c, 0x02, 0x8f, 0x00, 0x22, + 0xf0, 0x0b, 0xf4, 0x92, 0xfc, 0x00, 0x8b, 0x00, + 0x23, 0xc0, 0x48, 0xf4, 0x82, 0xff, 0x00, 0xff, + 0x60, 0x2e, 0xc0, 0x0e, 0x00, 0x22, 0xec, 0x00, + 0xbf, 0x00, 0x2f, 0xfc, 0x0b, 0xb0, 0x00, 0x2c, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0x04, 0x4e, 0x00, 0x82, 0x80, 0x2c, 0x38, 0x08, + 0x10, 0x02, 0xcc, 0x00, 0x83, 0x00, 0x2c, 0xc0, + 0x08, 0x30, 0x02, 0x00, 0x00, 0x93, 0x90, 0x20, + 0xf0, 0x0b, 0x3c, 0x02, 0xcc, 0x00, 0x8b, 0x00, + 0x0c, 0xc0, 0x09, 0x3e, 0x02, 0xcd, 0x40, 0x83, + 0x08, 0x2c, 0xc0, 0x8b, 0x00, 0x02, 0xcc, 0x00, + 0xb3, 0x88, 0x2c, 0xc0, 0x4b, 0x30, 0x02, 0x0c, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0xed, 0x09, 0x00, + 0xef, 0x01, 0x0b, 0x30, 0x02, 0xf8, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x5e, 0x40, + 0x85, 0x80, 0x2d, 0x20, 0x08, 0x78, 0x02, 0xde, + 0x40, 0x87, 0xc0, 0x2d, 0xc0, 0x08, 0x38, 0x02, + 0x1a, 0x00, 0x97, 0x80, 0xa1, 0xe0, 0xcb, 0x78, + 0x02, 0xce, 0x08, 0x87, 0x80, 0x25, 0xe0, 0x09, + 0x78, 0x02, 0xce, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0a, 0x49, 0x22, 0xda, 0x00, 0xb7, 0x90, 0x2d, + 0xe0, 0x0b, 0x78, 0x12, 0x1e, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xc8, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x18, 0x4c, 0x00, + 0xc1, 0x10, 0x3c, 0x47, 0x0c, 0x10, 0x03, 0xcc, + 0x50, 0xc3, 0x21, 0x3e, 0xc4, 0x2c, 0x30, 0x03, + 0x24, 0x40, 0xd3, 0x10, 0x30, 0x46, 0x0b, 0x30, + 0x43, 0xcc, 0x00, 0x81, 0x00, 0x3c, 0xc0, 0x0d, + 0x31, 0x03, 0xcc, 0x00, 0xc3, 0x10, 0x3c, 0xc0, + 0x0f, 0x21, 0x03, 0xc4, 0x00, 0xf3, 0x00, 0x3c, + 0xc0, 0x0f, 0xb0, 0x03, 0x0c, 0x00, 0xf3, 0x00, + 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xd2, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x00, + 0xff, 0x00, 0x3d, 0x00, 0x0f, 0xf0, 0x03, 0xfc, + 0x60, 0xff, 0x48, 0x3f, 0xc0, 0x0f, 0xf0, 0x83, + 0xf0, 0x00, 0xe7, 0x45, 0x3f, 0xc1, 0x4f, 0xf0, + 0x03, 0xfc, 0x20, 0xff, 0x00, 0xbb, 0xc2, 0x2e, + 0xf4, 0x83, 0xfc, 0x68, 0xdf, 0x4c, 0x3f, 0xc0, + 0x8f, 0xc1, 0x03, 0xfc, 0x40, 0xff, 0x40, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xd0, 0x06, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xaf, 0x40, + 0xc9, 0x00, 0x3e, 0x80, 0x0f, 0xb0, 0x03, 0xed, + 0xa2, 0xcb, 0x00, 0x32, 0xd8, 0x4c, 0xb0, 0x43, + 0xec, 0x00, 0xfb, 0x50, 0x3e, 0xc0, 0x0f, 0x36, + 0xed, 0x09, 0x00, 0xf0, 0x01, 0x03, 0x2d, 0x00, + 0xfb, 0x04, 0x3e, 0xd2, 0x0f, 0xb2, 0x13, 0xee, + 0x30, 0xfb, 0x00, 0x3e, 0xc0, 0x0d, 0x80, 0x03, + 0x4c, 0x00, 0x4b, 0x90, 0x34, 0xca, 0x0c, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x98, 0x8c, 0x20, 0x86, 0x01, 0x2d, + 0x00, 0x0b, 0x70, 0x02, 0xdc, 0x80, 0x87, 0x00, + 0x21, 0xd4, 0x08, 0x73, 0x02, 0xdc, 0x00, 0xb7, + 0x20, 0x2d, 0xc0, 0x0b, 0x72, 0x82, 0x1c, 0xc0, + 0xb7, 0x00, 0x2d, 0xc8, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0x87, 0x04, 0x2d, 0xc0, 0x0b, 0x40, 0x02, + 0x1c, 0x00, 0x87, 0x04, 0x29, 0xd8, 0x4a, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x02, 0xd2, 0x24, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x9e, 0x02, 0x86, 0x80, 0x2d, + 0x22, 0x0b, 0x78, 0x02, 0xde, 0x00, 0x97, 0xa0, + 0x24, 0xe8, 0x08, 0x78, 0x02, 0xde, 0x20, 0xb7, + 0x80, 0x2d, 0xe0, 0x89, 0x79, 0x1a, 0x5e, 0x88, + 0xa7, 0x80, 0x29, 0xe8, 0x0b, 0x7a, 0x02, 0xce, + 0x82, 0x87, 0xa0, 0x69, 0xe0, 0x08, 0x48, 0x42, + 0x3e, 0x00, 0x97, 0xa0, 0x29, 0xe8, 0x08, 0x78, + 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x68, 0x04, 0x8c, 0x00, 0x80, 0x00, 0x2c, + 0x80, 0x0b, 0x38, 0x22, 0xcc, 0x04, 0x93, 0x00, + 0x26, 0xc0, 0x08, 0xb0, 0x02, 0xce, 0x00, 0xb3, + 0x00, 0x2c, 0x60, 0x8b, 0x30, 0x02, 0x4c, 0x00, + 0xb1, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x00, 0xcc, + 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0xb8, 0x02, + 0x62, 0x80, 0x93, 0x00, 0x28, 0xc0, 0x0a, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xd2, 0xed, 0x09, 0x00, 0xf1, 0x01, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x11, + 0xe8, 0x00, 0xce, 0xc8, 0x1f, 0x90, 0x0f, 0xa0, + 0x03, 0xe8, 0x00, 0xda, 0x00, 0xb6, 0x80, 0x0c, + 0xa0, 0x03, 0xfb, 0x00, 0xfa, 0x00, 0x3d, 0xb3, + 0x0d, 0xa0, 0x03, 0x68, 0x00, 0xfa, 0x00, 0x3e, + 0x80, 0x0b, 0xa0, 0x13, 0xe8, 0x00, 0xfa, 0x00, + 0x3e, 0x80, 0x0d, 0xee, 0x0b, 0x7b, 0x80, 0xda, + 0x00, 0x3a, 0x80, 0x0c, 0xa0, 0x03, 0xe8, 0x00, + 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xf8, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, + 0xa0, 0x00, 0xf8, 0x80, 0x3e, 0x30, 0x0f, 0x81, + 0x03, 0xe0, 0x00, 0xe8, 0x40, 0x3a, 0x00, 0x0f, + 0x80, 0x03, 0xe2, 0x00, 0xf8, 0x00, 0x3e, 0x30, + 0x4f, 0x80, 0x03, 0xa0, 0x00, 0xf8, 0x00, 0x3e, + 0x01, 0x4f, 0x80, 0x03, 0xe0, 0x04, 0xf8, 0x40, + 0x3e, 0x00, 0x0f, 0x88, 0x03, 0xa0, 0x02, 0xe8, + 0x40, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xd2, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0xa5, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe6, 0x04, 0xc9, 0x80, 0x32, 0x40, 0x2c, + 0x90, 0x03, 0x24, 0x00, 0xf9, 0x40, 0x3e, 0x60, + 0x0e, 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x2e, + 0x40, 0x0f, 0x94, 0x03, 0x64, 0x10, 0xf9, 0x00, + 0x7e, 0x40, 0x0f, 0x90, 0x02, 0x24, 0x10, 0xc9, + 0x00, 0x36, 0x40, 0x0c, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc2, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, + 0x64, 0x00, 0xb9, 0x80, 0x2e, 0x56, 0x0f, 0x90, + 0x02, 0xc4, 0x42, 0xa1, 0x88, 0x22, 0x40, 0x08, + 0x90, 0x03, 0x64, 0x04, 0xf9, 0x00, 0x2e, 0x60, + 0x08, 0x11, 0x02, 0x24, 0x10, 0xb9, 0xed, 0x09, + 0x00, 0xf2, 0x01, 0x00, 0x26, 0x41, 0x0e, 0x9c, + 0x02, 0xe6, 0x01, 0xb9, 0x20, 0x6e, 0x40, 0x0b, + 0x90, 0x02, 0x24, 0x00, 0x89, 0xe2, 0x2c, 0x54, + 0x0d, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x05, 0x25, 0x00, 0xbb, + 0x80, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe5, 0x01, + 0x89, 0x10, 0x2a, 0x40, 0x09, 0x90, 0x02, 0x24, + 0x00, 0xb9, 0x00, 0x2e, 0x44, 0x0a, 0x94, 0x02, + 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, + 0xa2, 0xe5, 0x40, 0xb9, 0x21, 0x2a, 0x41, 0x0b, + 0x90, 0x02, 0xa4, 0x01, 0x89, 0x20, 0x26, 0x50, + 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x14, 0x04, 0x00, 0xb1, + 0x04, 0x2c, 0x40, 0x0a, 0x10, 0x02, 0xc4, 0x00, + 0xa1, 0x00, 0x20, 0x50, 0x09, 0x14, 0x02, 0x45, + 0x00, 0xa1, 0x00, 0x2e, 0xc0, 0x08, 0x10, 0x02, + 0x05, 0x00, 0xb1, 0x44, 0x24, 0x51, 0x0b, 0x10, + 0x02, 0xc4, 0x04, 0xb1, 0x00, 0x2c, 0x50, 0x0b, + 0x14, 0x02, 0x85, 0x09, 0x81, 0x00, 0x2c, 0x40, + 0x09, 0x14, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0x0d, 0x60, 0x10, 0xf8, + 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x03, 0xe0, 0x04, + 0xc8, 0x00, 0xb2, 0x00, 0x0d, 0x80, 0x0b, 0x20, + 0x00, 0xb8, 0x00, 0x3e, 0x00, 0x0e, 0x80, 0x0b, + 0x20, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x08, 0xb8, 0x02, 0x3a, 0x00, 0x0f, + 0x00, 0x0b, 0xa0, 0x02, 0xc8, 0x00, 0x36, 0x00, + 0x8c, 0x80, 0x23, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xfe, 0x03, 0x50, 0x00, + 0x00, 0xed, 0x09, 0x00, 0xf3, 0x01, 0x00, 0x00, + 0x98, 0x95, 0xe5, 0x00, 0xfd, 0x00, 0x3f, 0x40, + 0x0f, 0xd0, 0x23, 0xc5, 0x00, 0xd1, 0x40, 0x3e, + 0x50, 0x0e, 0x94, 0x03, 0xf4, 0x00, 0xf9, 0x40, + 0x3f, 0x40, 0x0f, 0x94, 0x03, 0xe5, 0x00, 0xfd, + 0x04, 0x3e, 0x50, 0x0e, 0x94, 0x63, 0xe5, 0x00, + 0xf9, 0x40, 0x3e, 0x40, 0x0f, 0xd0, 0x01, 0x74, + 0x10, 0xf1, 0x40, 0x3e, 0x50, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe6, 0x26, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x05, 0x74, 0x00, 0xfd, 0x00, 0x35, 0x40, + 0x04, 0xd0, 0x03, 0x14, 0x30, 0x8d, 0x20, 0x3e, + 0x48, 0x0c, 0x92, 0x01, 0x24, 0x00, 0xed, 0x00, + 0x3f, 0x40, 0x0d, 0xd2, 0x02, 0xe4, 0xa8, 0xfb, + 0x01, 0x2e, 0x46, 0x06, 0xd2, 0x43, 0x54, 0x00, + 0xfd, 0x00, 0x22, 0x50, 0x0f, 0x94, 0x03, 0xe4, + 0x00, 0xfd, 0x28, 0x33, 0x40, 0x8f, 0x94, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xc6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x18, 0xe0, 0x00, 0xb8, 0x04, 0x2a, 0x00, + 0x0b, 0x80, 0x02, 0x21, 0x00, 0x88, 0x40, 0x26, + 0x0a, 0x08, 0x86, 0x02, 0x08, 0xa0, 0x88, 0x00, + 0x2e, 0x00, 0x00, 0x80, 0x00, 0xe1, 0x80, 0xb8, + 0x00, 0x2c, 0x10, 0x0a, 0x84, 0x02, 0xa0, 0x10, + 0xb8, 0x00, 0x2a, 0x00, 0x0b, 0x80, 0x02, 0xc0, + 0x94, 0xb8, 0x40, 0xa2, 0x00, 0x0b, 0x80, 0x02, + 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, + 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x05, 0x85, 0x00, 0xb1, 0x00, 0x24, 0x40, + 0x09, 0x10, 0x02, 0x84, 0x02, 0x81, 0x40, 0x24, + 0x50, 0x08, 0x11, 0x82, 0x04, 0x00, 0x81, 0x40, + 0x2c, 0x60, 0x09, 0x14, 0x06, 0x44, 0x20, 0xb1, + 0x28, 0x2c, 0x48, 0x08, 0xed, 0x09, 0x00, 0xf4, + 0x01, 0x11, 0x02, 0x05, 0x10, 0x81, 0x40, 0x20, + 0x48, 0x0a, 0x12, 0x26, 0xc6, 0xa0, 0xb1, 0x00, + 0x28, 0x51, 0x03, 0x10, 0x02, 0xc4, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xd2, 0x01, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x98, 0x04, 0xa4, + 0x00, 0xb9, 0x10, 0x22, 0x70, 0x4b, 0x90, 0x12, + 0xa4, 0x00, 0x8b, 0x00, 0x24, 0x40, 0x08, 0x90, + 0x22, 0x06, 0x00, 0x89, 0x00, 0x2e, 0x41, 0x08, + 0x90, 0x06, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x8a, 0x90, 0x02, 0xac, 0x00, 0x99, 0x00, 0x0a, + 0x40, 0x0b, 0x94, 0x02, 0xe4, 0x40, 0xb9, 0x00, + 0x22, 0x40, 0x09, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe6, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe4, + 0x00, 0xf9, 0x88, 0x36, 0x70, 0x4c, 0x90, 0x0b, + 0xa4, 0x02, 0xc9, 0x01, 0x3e, 0x40, 0x2c, 0x90, + 0x0b, 0x25, 0x02, 0xc9, 0x00, 0x3c, 0x64, 0x0d, + 0x90, 0x03, 0xe4, 0x04, 0xb9, 0x90, 0x3e, 0x40, + 0x0c, 0x10, 0x03, 0x64, 0x00, 0xd9, 0x00, 0x22, + 0x40, 0x0f, 0x9d, 0x03, 0xe6, 0x04, 0xf9, 0x00, + 0x3a, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0xa4, + 0x00, 0xf9, 0x80, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0x64, 0x04, 0xf9, 0x00, 0x3e, 0x41, 0x0f, + 0x90, 0x43, 0xe4, 0x00, 0xf9, 0x80, 0x3e, 0x41, + 0x0f, 0x90, 0x13, 0xe4, 0x14, 0xf9, 0x01, 0x3e, + 0x40, 0x4f, 0x98, 0x03, 0xe6, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x4f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xda, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xed, + 0x09, 0x00, 0xf5, 0x01, 0xa2, 0x00, 0xf8, 0x01, + 0x3a, 0x20, 0x2f, 0x80, 0x43, 0xc2, 0x50, 0xc8, + 0x80, 0x36, 0x01, 0x0c, 0x00, 0x03, 0x20, 0x00, + 0xc8, 0x00, 0x3e, 0x20, 0x0d, 0x82, 0x03, 0x60, + 0x00, 0xf8, 0x03, 0x3c, 0x00, 0x0e, 0x88, 0x03, + 0xe0, 0x22, 0x90, 0x80, 0x3e, 0x00, 0x2e, 0x80, + 0x03, 0xe0, 0x02, 0xc0, 0x80, 0x3e, 0x04, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x01, 0xbb, 0x00, 0xb2, 0x00, + 0x23, 0xb8, 0x0c, 0x2a, 0x02, 0xf9, 0x02, 0x8e, + 0xc0, 0xa2, 0x80, 0x08, 0xa0, 0x42, 0x28, 0x00, + 0x8a, 0x80, 0x2f, 0xb0, 0x4b, 0xe0, 0x82, 0xe8, + 0x00, 0xba, 0x00, 0x2e, 0x80, 0x00, 0xec, 0x82, + 0xfb, 0x80, 0x8e, 0x40, 0x26, 0x80, 0x08, 0xa0, + 0x02, 0xe8, 0x00, 0x8e, 0x4c, 0x0f, 0xb4, 0x0e, + 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, + 0x0b, 0xa0, 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x04, 0x4a, 0x40, 0xb1, 0x00, + 0x20, 0xe1, 0x28, 0x38, 0x02, 0xcc, 0x10, 0x83, + 0x90, 0x20, 0xc0, 0x08, 0x30, 0x02, 0x0c, 0x01, + 0x81, 0x80, 0x2c, 0x40, 0x09, 0x00, 0x02, 0x4c, + 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x0a, 0x10, 0x02, + 0xc2, 0x08, 0x81, 0x10, 0x2c, 0xc0, 0x08, 0x30, + 0x22, 0x4c, 0x04, 0x81, 0x00, 0x2c, 0x80, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xca, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x10, 0x54, 0x00, 0xbd, 0x08, + 0xa1, 0x20, 0x2a, 0x70, 0x02, 0xdc, 0x04, 0x87, + 0x81, 0x28, 0xc8, 0x08, 0x32, 0x02, 0x1c, 0x80, + 0x87, 0x08, 0x25, 0xd0, 0x0b, 0x70, 0x62, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xc8, 0xc0, 0x70, 0x22, + 0xde, 0x00, 0xed, 0x09, 0x00, 0xf6, 0x01, 0x87, + 0x00, 0x25, 0xe4, 0x08, 0x70, 0x02, 0xde, 0x80, + 0x87, 0x00, 0x2d, 0x40, 0x8a, 0x71, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xe8, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x88, + 0x88, 0x52, 0x00, 0xf5, 0x80, 0x31, 0x21, 0x0c, + 0x78, 0x23, 0xde, 0x00, 0x43, 0x80, 0x35, 0xf2, + 0x2c, 0x7d, 0x03, 0x1e, 0x82, 0x47, 0x80, 0x3d, + 0xe0, 0x0d, 0x78, 0x03, 0x5e, 0x00, 0xd7, 0xb0, + 0x3d, 0xea, 0x0e, 0x78, 0x23, 0xde, 0x00, 0x87, + 0x80, 0x3f, 0xe4, 0x4c, 0x7c, 0x03, 0x5f, 0x00, + 0xc7, 0x80, 0x3d, 0x60, 0x07, 0x7a, 0x83, 0xde, + 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, + 0xea, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x15, 0xa4, 0x00, 0xf1, 0x00, 0x36, 0xc0, 0x05, + 0xb0, 0x03, 0xec, 0x00, 0x5b, 0x00, 0x36, 0xc8, + 0x8f, 0xb2, 0x0b, 0xed, 0xc0, 0xdb, 0x02, 0x3e, + 0xc0, 0x0f, 0xb0, 0x01, 0xec, 0x40, 0xfb, 0x20, + 0x3e, 0xc0, 0x0f, 0x90, 0x43, 0xec, 0x04, 0xeb, + 0x00, 0x3e, 0xc8, 0x0b, 0xb2, 0x00, 0xed, 0x80, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb6, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xc2, 0x86, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x92, 0x00, 0xc7, 0x80, 0x3b, 0x20, 0x0f, + 0xd9, 0x03, 0xfa, 0x00, 0xfe, 0x81, 0x37, 0xe0, + 0x0c, 0xf8, 0x03, 0x3f, 0x00, 0xcf, 0x80, 0x33, + 0xe4, 0x1f, 0xf9, 0x03, 0x7f, 0x00, 0x6f, 0x88, + 0x3f, 0xe2, 0x0c, 0xf8, 0x01, 0xfe, 0x00, 0x7f, + 0x90, 0x3f, 0xe0, 0x0f, 0xfc, 0x03, 0xff, 0x08, + 0xff, 0x80, 0x3f, 0x60, 0x0f, 0xf8, 0x03, 0xfe, + 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, + 0xc0, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x18, 0x94, 0x00, 0x85, 0x00, 0xed, 0x09, 0x00, + 0xf7, 0x01, 0x21, 0xc6, 0x0b, 0x50, 0x22, 0xdc, + 0x00, 0xb7, 0x00, 0x21, 0xc0, 0x08, 0x72, 0x02, + 0x3c, 0x20, 0x87, 0x00, 0x21, 0x46, 0x0e, 0x75, + 0x0a, 0x1c, 0x00, 0x87, 0x00, 0x2f, 0xc0, 0x08, + 0x70, 0x4a, 0x18, 0x00, 0x97, 0x00, 0x2d, 0xc1, + 0x0b, 0x70, 0xc2, 0x5c, 0x60, 0xb7, 0x00, 0x2d, + 0x00, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xea, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, + 0x8d, 0x00, 0x29, 0xd0, 0x0b, 0x50, 0xa2, 0xd8, + 0x00, 0xb6, 0x10, 0x21, 0xc0, 0x08, 0x70, 0x00, + 0x1c, 0x00, 0x85, 0x00, 0x21, 0xc0, 0x83, 0x41, + 0x02, 0x9c, 0x00, 0x87, 0x00, 0x29, 0xc0, 0x0a, + 0x70, 0x02, 0x14, 0x00, 0xb5, 0x02, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xdd, 0x00, 0xa5, 0x00, 0x2d, + 0x40, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, + 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xc0, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x80, 0x00, + 0x81, 0x00, 0x20, 0x20, 0x09, 0x10, 0x02, 0xc8, + 0x00, 0xb2, 0x01, 0x20, 0xc0, 0x08, 0x30, 0x02, + 0x0f, 0x20, 0xa3, 0x00, 0x20, 0xd0, 0x0a, 0x30, + 0x42, 0x2c, 0x00, 0x83, 0x80, 0x24, 0xc0, 0x0a, + 0x30, 0x22, 0x8c, 0x19, 0x13, 0x00, 0x2c, 0xc0, + 0x1b, 0x38, 0x20, 0x4c, 0x00, 0xb3, 0x00, 0x2c, + 0x40, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0xe0, 0x00, + 0xcb, 0x80, 0x38, 0x10, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0xb3, 0xc0, 0x2c, 0xf0, 0x0b, + 0x1e, 0x00, 0xcb, 0x00, 0xb2, 0xe4, 0x0b, 0xb0, + 0x23, 0xfc, 0x0a, 0xcf, 0x08, 0x3f, 0xc0, 0x0e, + 0xb0, 0x03, 0x4c, 0x00, 0xbb, 0x00, 0x3f, 0xc0, + 0xed, 0x09, 0x00, 0xf8, 0x01, 0x0f, 0xf8, 0x03, + 0xfe, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xf0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xea, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0xa4, 0x08, 0xf9, 0x30, 0x3e, + 0xd0, 0x0f, 0x90, 0x23, 0xec, 0x00, 0xf9, 0x40, + 0x38, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xd1, + 0x00, 0x3e, 0xc0, 0x0f, 0x84, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0d, 0x34, 0x03, 0x64, + 0x00, 0xd9, 0x40, 0x3e, 0xc0, 0x0f, 0xb0, 0x82, + 0xec, 0x00, 0xf9, 0x00, 0x3c, 0x40, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xe0, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x21, 0x10, 0xba, 0x80, 0xed, 0x90, 0x3f, + 0xc0, 0x1c, 0xd0, 0x03, 0x35, 0x04, 0xcf, 0xa0, + 0x33, 0xc0, 0x0c, 0xf0, 0x03, 0x7c, 0x00, 0xcb, + 0x10, 0x33, 0x40, 0x0e, 0xb1, 0x03, 0xfc, 0x00, + 0xcf, 0x00, 0x37, 0xc0, 0x09, 0xb1, 0x02, 0x38, + 0x00, 0xd7, 0xa0, 0x33, 0xc0, 0x0c, 0xf0, 0x03, + 0xfc, 0x00, 0xf7, 0x00, 0x33, 0x00, 0x0c, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xc0, 0x44, 0x20, 0x00, 0x00, 0x00, + 0x00, 0xa1, 0x04, 0x46, 0x00, 0x89, 0x00, 0x2e, + 0x28, 0x0c, 0x10, 0x22, 0x05, 0x80, 0x81, 0xc0, + 0x22, 0xc0, 0x00, 0xb0, 0x03, 0x6c, 0x10, 0xdb, + 0x00, 0x22, 0xc0, 0x0b, 0xbc, 0x02, 0xec, 0x00, + 0x83, 0x00, 0x22, 0xc0, 0x0b, 0xb6, 0x02, 0x2c, + 0x00, 0x8b, 0xa0, 0x22, 0xc0, 0x08, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0xa2, 0x64, 0x08, 0xb0, + 0x02, 0xec, 0x00, 0xeb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x05, 0x20, 0x00, 0xb9, 0x01, 0x2e, + 0xc4, 0x0a, 0xb2, 0xed, 0x09, 0x00, 0xf9, 0x01, + 0x02, 0x2c, 0x00, 0x8b, 0x04, 0x22, 0xc1, 0x08, + 0x30, 0x02, 0x2c, 0x00, 0x8b, 0x00, 0x22, 0xc4, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0x9b, 0x00, 0x66, + 0xc0, 0x09, 0x90, 0x02, 0xac, 0x82, 0x8b, 0x00, + 0x20, 0xc0, 0x0a, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x20, 0x62, 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x14, + 0x04, 0x00, 0xb1, 0x04, 0x2e, 0x00, 0x28, 0xb0, + 0x00, 0x00, 0x03, 0xa0, 0x00, 0x20, 0xc0, 0x08, + 0x30, 0x02, 0x6c, 0x00, 0x93, 0x00, 0xa0, 0xe0, + 0x0b, 0x30, 0x32, 0xcc, 0x02, 0x9b, 0x00, 0x20, + 0xc0, 0x0b, 0x30, 0x0a, 0x8c, 0x01, 0x83, 0x00, + 0xa0, 0xc0, 0x2a, 0x30, 0x06, 0xcc, 0x00, 0xb3, + 0x80, 0x00, 0x60, 0x08, 0x30, 0x02, 0xcc, 0x00, + 0xa3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x12, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0x64, 0x00, 0xf9, 0x02, 0x2e, 0x00, 0x0a, 0xb0, + 0x03, 0x20, 0x04, 0xc8, 0x00, 0xb1, 0xc0, 0x2c, + 0x70, 0x03, 0x3c, 0x00, 0xcb, 0x00, 0x32, 0xc0, + 0x0f, 0xb0, 0x03, 0xdc, 0x00, 0xdf, 0x00, 0x37, + 0xc0, 0x0d, 0xb0, 0x03, 0xac, 0x00, 0xcb, 0x00, + 0x33, 0xc0, 0x0a, 0xf0, 0x03, 0xfc, 0x00, 0xfb, + 0x00, 0x32, 0x40, 0x2c, 0xf0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xc0, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x15, + 0xf0, 0x00, 0xcd, 0x00, 0x3f, 0xc0, 0x0e, 0xf0, + 0x23, 0xf0, 0x00, 0xd4, 0x00, 0x1f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xfd, 0x00, 0x3f, 0x00, + 0x0f, 0xc0, 0x03, 0xfc, 0x00, 0xef, 0x00, 0x1f, + 0xc0, 0x0f, 0xc0, 0x03, 0x70, 0x01, 0xfc, 0x00, + 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xfc, 0xed, 0x09, + 0x00, 0xfa, 0x01, 0x00, 0xfc, 0x04, 0x3f, 0x80, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x05, 0xd0, 0x52, 0xcc, + 0x28, 0x33, 0x80, 0x0c, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x03, 0xf4, + 0x10, 0xfd, 0x00, 0x3f, 0x00, 0x0f, 0xe0, 0x03, + 0x74, 0x10, 0xff, 0x00, 0x3d, 0xc0, 0x0c, 0xf0, + 0x03, 0xbc, 0x04, 0xfc, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x20, 0xfc, 0x20, 0x3f, 0xc4, + 0x4c, 0x70, 0x03, 0xd0, 0x08, 0xcf, 0x00, 0x3f, + 0xc8, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x10, 0xe0, 0x88, 0xd8, + 0x40, 0x62, 0x80, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, + 0x00, 0xb9, 0x00, 0x2e, 0xc0, 0x0b, 0xa0, 0x02, + 0xe0, 0x00, 0xb8, 0x04, 0x2e, 0x00, 0x08, 0x80, + 0x02, 0x20, 0x00, 0xba, 0x01, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xed, 0x04, 0xb9, 0x28, 0x2e, 0xc8, + 0x0d, 0xa0, 0x02, 0xe0, 0x04, 0xdb, 0x18, 0x2e, + 0xd0, 0x0b, 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x05, 0xcc, 0x80, 0x80, + 0x00, 0x6e, 0x80, 0x88, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x38, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x20, 0x12, + 0x44, 0x01, 0xb3, 0x01, 0x2e, 0xc0, 0x19, 0x30, + 0x12, 0xcc, 0x00, 0xb2, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb0, 0x30, 0x2c, 0xc0, + 0x08, 0x20, 0x02, 0xe0, 0x02, 0x83, 0x20, 0x2c, + 0xc4, 0x0b, 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x15, 0xac, 0x40, 0x98, + 0xc0, 0x6a, 0x80, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0xed, 0x09, 0x00, 0xfb, 0x01, 0x00, 0x2e, + 0xc1, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xba, 0x02, + 0x2e, 0x44, 0x0b, 0xa0, 0x02, 0xe0, 0x01, 0xb8, + 0x00, 0x2e, 0x00, 0x31, 0x80, 0x02, 0x60, 0x00, + 0xbb, 0x08, 0x2e, 0xc0, 0x03, 0xb0, 0x02, 0xec, + 0x00, 0xb9, 0xc0, 0x2e, 0xc0, 0x09, 0xb0, 0x82, + 0xe0, 0x00, 0x9b, 0x00, 0x2e, 0xc1, 0x0b, 0xb0, + 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x15, 0xe0, 0x00, 0xc9, 0xc0, 0xbe, 0xa1, + 0x0c, 0xb0, 0x23, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb8, 0x13, 0xec, 0x48, 0xfb, 0xa0, + 0x3e, 0xf0, 0x0f, 0xa0, 0x03, 0x64, 0x00, 0xfb, + 0x05, 0x3e, 0xc0, 0x05, 0xb0, 0x43, 0xec, 0x00, + 0xf8, 0x40, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x04, 0xf9, 0x81, 0x3e, 0xc1, 0x0c, 0xa4, 0x03, + 0xc2, 0x88, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x01, 0xb6, 0x00, 0xf1, 0x00, 0x37, 0xf0, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xd1, 0x00, 0xfe, 0x20, 0xff, 0x10, + 0x3f, 0xe0, 0x0f, 0xe0, 0x03, 0xf0, 0x00, 0xfc, + 0x00, 0x3f, 0x00, 0x0e, 0xc0, 0x43, 0xb0, 0x08, + 0x7f, 0x40, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xec, + 0x00, 0xb9, 0x02, 0x3f, 0xc0, 0x0f, 0xf0, 0x43, + 0xf2, 0x80, 0xbf, 0x00, 0x3e, 0xc0, 0x0f, 0xf0, + 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x10, 0xac, 0x40, 0xc9, 0x58, 0x32, 0xc2, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc2, 0x0f, 0xa0, 0x83, 0xe4, 0x00, 0xfb, 0x00, + 0x3e, 0x88, 0x0f, 0xa0, 0x03, 0xe4, 0x20, 0xfb, + 0x00, 0x3e, 0xc2, 0x0c, 0xb2, 0x03, 0x2c, 0x00, + 0xfa, 0x50, 0x3e, 0xc1, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xc9, 0x40, 0x32, 0xed, 0x09, 0x00, 0xfc, + 0x01, 0xc8, 0x0c, 0xb4, 0x83, 0x22, 0x00, 0xcb, + 0x20, 0x36, 0xc0, 0x0c, 0xb0, 0x03, 0xd0, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2d, + 0x04, 0x89, 0x80, 0x0c, 0x90, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb2, + 0x42, 0xed, 0x00, 0xbb, 0x00, 0x2e, 0xd0, 0x0b, + 0xa5, 0x90, 0xe3, 0x00, 0xb8, 0xd9, 0x2c, 0x08, + 0x08, 0x06, 0x02, 0x21, 0x40, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xfc, 0x01, 0x89, 0xa0, + 0x22, 0xf0, 0x08, 0xa4, 0x02, 0x24, 0x00, 0xdf, + 0xc8, 0x6b, 0xc1, 0x0d, 0xb0, 0x02, 0xf2, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x60, + 0x00, 0x80, 0xc0, 0x04, 0x10, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xd0, 0x0b, 0x30, + 0x02, 0xcf, 0x10, 0x33, 0x00, 0x2c, 0xc0, 0x0b, + 0x2c, 0x00, 0xc7, 0x00, 0xb3, 0x80, 0x2c, 0xc0, + 0x0b, 0x34, 0x02, 0x0d, 0x40, 0xb2, 0x20, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x06, 0x82, 0x80, + 0x22, 0xc0, 0x08, 0x24, 0x02, 0x00, 0x00, 0x83, + 0x40, 0x20, 0xc0, 0x08, 0x30, 0x02, 0xf8, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x33, + 0x00, 0x87, 0x80, 0x2d, 0xa4, 0x0b, 0x78, 0x02, + 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x68, + 0x42, 0xd6, 0x00, 0xb7, 0x80, 0x2d, 0xa0, 0x0b, + 0x68, 0x02, 0xd2, 0x00, 0xb4, 0x80, 0x2f, 0x20, + 0x0b, 0xc8, 0x02, 0x12, 0x00, 0xb7, 0x81, 0x0d, + 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0x87, 0xc0, + 0x21, 0xe0, 0x08, 0x79, 0x02, 0x32, 0x00, 0x97, + 0x80, 0x29, 0xe0, 0x09, 0x78, 0x02, 0xc8, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x0c, + 0x00, 0xc2, 0x10, 0x30, 0xd0, 0x0f, 0x30, 0x03, + 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0xed, + 0x09, 0x00, 0xfd, 0x01, 0x12, 0x03, 0xcc, 0x20, + 0xf1, 0x10, 0x3c, 0xc0, 0x0f, 0x20, 0x03, 0xc4, + 0x20, 0xf3, 0x10, 0x3c, 0xc0, 0x4f, 0x31, 0x03, + 0x0c, 0x40, 0xf2, 0x00, 0x3c, 0xc0, 0x0b, 0x30, + 0x03, 0xcc, 0x40, 0x81, 0x00, 0xb2, 0xc2, 0x2c, + 0x31, 0x03, 0x00, 0x00, 0xc3, 0x01, 0x30, 0xc0, + 0x1c, 0x30, 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x1d, 0xbc, 0x02, 0xfe, 0x00, + 0x3b, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xfd, 0x00, 0x3f, 0xc0, 0x4f, 0xe0, 0x03, 0xf0, + 0x00, 0xfc, 0x00, 0x3f, 0x04, 0x2c, 0x41, 0x4b, + 0xf2, 0x44, 0xff, 0x10, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x30, 0xff, 0x10, 0x3f, 0xc0, 0x0f, + 0xe5, 0x0b, 0xf0, 0x00, 0xf7, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x05, 0xe8, 0x00, 0xf9, 0x00, + 0x3e, 0xe0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x04, + 0xfb, 0x00, 0x3c, 0x40, 0x0e, 0x20, 0x03, 0x86, + 0x00, 0xeb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x04, 0xfa, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfa, 0x80, 0xb2, 0xc0, 0x0f, + 0xb8, 0x03, 0x20, 0x01, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x11, 0x9c, 0x10, 0xb7, 0x01, + 0x2d, 0xc0, 0x0d, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x0d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0xc8, 0x60, 0x10, 0x90, + 0x00, 0x84, 0x00, 0x2d, 0x00, 0x0b, 0x40, 0x02, + 0xd0, 0x00, 0xb7, 0x00, 0x25, 0xc0, 0x0b, 0x70, + 0x02, 0xde, 0x00, 0xb7, 0x00, 0x35, 0xc0, 0x0b, + 0x60, 0x02, 0xed, 0x09, 0x00, 0xfe, 0x01, 0x18, + 0x10, 0xb7, 0xa0, 0x2d, 0xe8, 0x0b, 0x70, 0x02, + 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x9e, 0x20, 0xb7, 0x80, 0x2d, 0xe0, 0x08, + 0x78, 0x12, 0xde, 0x01, 0xb7, 0x80, 0x2d, 0xe0, + 0x09, 0x78, 0x82, 0xde, 0x00, 0xb7, 0x80, 0x2f, + 0xe2, 0x0b, 0xe8, 0x00, 0xd6, 0x00, 0xa7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x04, 0xb6, + 0x80, 0x6d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x80, + 0xb7, 0x80, 0xa1, 0xe0, 0x0b, 0x68, 0x0a, 0x52, + 0x04, 0xb7, 0xb0, 0x2d, 0xec, 0x0b, 0x78, 0x02, + 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x14, 0xce, 0x20, 0xb3, 0x48, 0x2c, 0xe0, 0x09, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x08, 0x02, 0xc4, 0x00, 0xb3, 0x80, 0x2c, + 0x20, 0x09, 0x20, 0x02, 0x40, 0x00, 0x80, 0x02, + 0x2c, 0x00, 0x0b, 0x00, 0x02, 0xc0, 0x05, 0xb3, + 0x00, 0x24, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x04, 0xa4, 0xc0, 0x0b, 0x34, 0x02, 0x42, + 0x20, 0xb3, 0x03, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, + 0x15, 0xb9, 0x00, 0xfe, 0x40, 0x3f, 0x98, 0x0c, + 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, + 0x0d, 0xe8, 0x03, 0xe8, 0x20, 0xfe, 0xc0, 0x3f, + 0x90, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xea, 0x00, + 0x3e, 0x80, 0x4f, 0xa0, 0x03, 0xc8, 0x00, 0xfe, + 0x40, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, + 0xfe, 0x52, 0xb2, 0x80, 0x0f, 0xa4, 0x23, 0x59, + 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, + 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0xe0, 0x00, 0xf8, 0x02, 0x1e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0b, 0x88, 0x03, 0xe0, 0x00, 0xed, 0x09, 0x00, + 0xff, 0x01, 0xf8, 0x90, 0x3e, 0x08, 0x0e, 0x80, + 0x03, 0xb0, 0x00, 0xfc, 0x00, 0x2f, 0x00, 0x0f, + 0xc0, 0x03, 0xf1, 0x01, 0xf8, 0x80, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x40, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xa0, 0x48, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, + 0xf9, 0x40, 0x3e, 0x42, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x43, + 0xe4, 0x00, 0xf9, 0x00, 0x1e, 0x40, 0x0d, 0x90, + 0x03, 0x64, 0x00, 0xf9, 0x00, 0x7a, 0x40, 0x4c, + 0x91, 0x01, 0xe6, 0x00, 0xe9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x07, 0xc4, 0x00, 0xd9, 0x10, 0x3e, + 0x40, 0x0c, 0x98, 0x83, 0xe4, 0x00, 0xc9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc2, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x26, 0x40, 0x0b, 0x90, 0x02, + 0xe4, 0x01, 0x99, 0x00, 0x2c, 0x40, 0x08, 0x10, + 0x02, 0x24, 0x00, 0xb9, 0x00, 0x3c, 0x40, 0xcd, + 0x90, 0x02, 0xe4, 0x50, 0x89, 0x80, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0x89, 0x40, 0x2e, + 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0x89, 0x05, + 0x3a, 0x40, 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0x24, 0x00, + 0xb9, 0x00, 0x2e, 0x41, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, + 0xe4, 0x04, 0xb9, 0x00, 0x2e, 0xc0, 0x09, 0x90, + 0x02, 0xe4, 0x00, 0xbd, 0x00, 0x0f, 0x40, 0x1a, + 0xd0, 0x02, 0xf4, 0x02, 0x89, 0x10, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xe4, 0x00, 0x99, 0x40, 0x2c, + 0x40, 0x18, 0x92, 0x06, 0xe4, 0x42, 0x89, 0x24, + 0xed, 0x09, 0x00, 0x00, 0x02, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x07, 0x00, 0xb1, 0x80, 0x2c, + 0xc0, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x12, 0xc4, 0x00, 0x91, + 0x00, 0x2e, 0x40, 0x18, 0x10, 0x42, 0x94, 0x00, + 0xb5, 0x00, 0x2d, 0x40, 0x0b, 0x50, 0x02, 0xd4, + 0x00, 0x01, 0x00, 0x0c, 0x40, 0x0b, 0x10, 0x02, + 0xc4, 0x08, 0x81, 0x40, 0x2c, 0x50, 0x38, 0x10, + 0x02, 0xc4, 0x00, 0x81, 0x40, 0x28, 0x40, 0x0b, + 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb8, 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x02, 0xe0, 0x00, 0xb8, + 0x00, 0x3e, 0x00, 0x0d, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3a, 0x00, 0x0e, 0xa0, 0x03, 0xf8, + 0x00, 0xea, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x02, + 0xe0, 0x00, 0xd8, 0x00, 0x3e, 0x00, 0x0c, 0xc0, + 0x03, 0xe0, 0x00, 0xc8, 0x00, 0x3e, 0x00, 0xcf, + 0x80, 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x1d, 0xfc, 0x00, 0xfd, 0x40, 0x3d, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x36, 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x10, 0x9d, + 0x00, 0x3f, 0x40, 0x0f, 0x90, 0x03, 0x64, 0x00, + 0xf9, 0x00, 0x3a, 0x40, 0x45, 0x90, 0x13, 0xe4, + 0x00, 0xfd, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe5, 0x08, 0xf5, 0x44, 0x3e, 0x40, 0x8f, 0x10, + 0x03, 0xf4, 0x10, 0xf9, 0x40, 0x3e, 0x50, 0x0f, + 0x90, 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x05, 0xf4, 0x40, 0xfd, 0x00, 0x33, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x10, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0xed, 0x09, 0x00, 0x01, 0x02, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xe1, 0x00, 0x76, + 0x40, 0x0e, 0xd0, 0x03, 0x34, 0x00, 0xcd, 0x04, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xef, + 0x10, 0x33, 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x00, + 0xcd, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, 0xc6, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, + 0xe0, 0x88, 0xb8, 0x40, 0x22, 0x80, 0x0b, 0x80, + 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, + 0x80, 0x22, 0xf0, 0x00, 0xb8, 0x00, 0x2e, 0x00, + 0x03, 0x80, 0x02, 0xe0, 0x00, 0x88, 0x00, 0x23, + 0x01, 0x08, 0x80, 0x02, 0x20, 0x10, 0xa8, 0x00, + 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0x88, + 0x10, 0xa2, 0x0a, 0x0b, 0xa0, 0x42, 0xe0, 0x02, + 0xd0, 0x48, 0x22, 0x00, 0x0b, 0x80, 0x02, 0xce, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, + 0xcc, 0x80, 0xb1, 0x90, 0x20, 0x40, 0x0b, 0x10, + 0x22, 0xc4, 0x00, 0xb1, 0x00, 0x2d, 0x40, 0x0b, + 0x50, 0x02, 0xd4, 0x00, 0xb1, 0x00, 0x2d, 0x40, + 0x0b, 0x50, 0x02, 0xd4, 0x00, 0xbd, 0x00, 0x21, + 0x40, 0x4b, 0x10, 0x0a, 0x44, 0x06, 0x91, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x40, 0xa1, + 0x00, 0x20, 0x48, 0x0b, 0x10, 0x02, 0xe4, 0x00, + 0x81, 0x30, 0x20, 0x44, 0x0b, 0x10, 0x02, 0xc2, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, + 0xa4, 0x00, 0xb9, 0x80, 0x22, 0x60, 0x0b, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x1b, + 0xd8, 0x02, 0xf4, 0x00, 0xb9, 0x28, 0x2e, 0x40, + 0x09, 0xd0, 0x02, 0xf4, 0x00, 0x9d, 0x00, 0xe3, + 0x40, 0x09, 0x90, 0x00, 0x64, 0x00, 0xb9, 0x80, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0x89, + 0x00, 0x22, 0x40, 0x0b, 0x90, 0x00, 0xe4, 0x00, + 0x91, 0x00, 0x22, 0x40, 0x0b, 0x90, 0xed, 0x09, + 0x00, 0x02, 0x02, 0x02, 0xc6, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe4, 0x00, 0xf9, + 0x00, 0xb2, 0x70, 0x0f, 0x90, 0x23, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x9c, 0xc3, 0xe6, + 0x04, 0xf9, 0x00, 0x3e, 0x52, 0x0f, 0x90, 0x03, + 0xc4, 0x00, 0xf9, 0x00, 0x76, 0x40, 0x1f, 0x10, + 0x03, 0x44, 0x00, 0xd9, 0x88, 0x1e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xe9, 0x60, 0x32, 0x40, + 0x0f, 0x90, 0x03, 0xe5, 0x20, 0xc9, 0x00, 0xb2, + 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x01, 0xa5, 0x00, 0xf1, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe6, + 0x40, 0xf9, 0x00, 0x3e, 0x68, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xe9, 0x00, 0x3a, 0x40, 0x0e, 0x90, + 0xa7, 0xa4, 0x08, 0x49, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xc4, 0x00, 0xf9, 0x90, 0x3e, 0x40, + 0x0f, 0x90, 0x23, 0xe4, 0x80, 0xf9, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xca, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x10, 0xa2, 0x00, 0xf8, + 0x80, 0x3e, 0x20, 0x2c, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3f, 0x00, 0x0e, 0xc4, 0x03, 0xf0, + 0x00, 0xd8, 0x40, 0x37, 0x10, 0x0f, 0xc0, 0x03, + 0xf0, 0x00, 0xfc, 0x00, 0x37, 0x00, 0x4e, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x48, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xc8, 0x48, 0x3e, 0x02, + 0x0f, 0x8c, 0x03, 0xe1, 0x00, 0xf8, 0x20, 0x32, + 0x00, 0x0f, 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x38, 0x00, 0xbe, + 0xc8, 0x2f, 0x92, 0x08, 0xa0, 0x02, 0xe8, 0x00, + 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0x28, + 0x00, 0x8a, 0x00, 0x22, 0x80, 0x09, 0xa0, 0x02, + 0xe8, 0xed, 0x09, 0x00, 0x03, 0x02, 0x00, 0xb2, + 0x00, 0x20, 0x80, 0x0b, 0xe4, 0x02, 0xf9, 0x80, + 0xbe, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, + 0x00, 0x8e, 0xc0, 0x2f, 0xa0, 0x0b, 0xe4, 0x82, + 0xc8, 0x00, 0xbe, 0x80, 0x22, 0x80, 0x0b, 0xa0, + 0x02, 0xca, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x04, 0x0c, 0x00, 0xb2, 0x80, 0x2c, 0xe0, + 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb2, 0x00, 0x2c, + 0x00, 0x0a, 0x00, 0x02, 0x40, 0x00, 0x92, 0x00, + 0x24, 0x00, 0x0b, 0x00, 0x02, 0xc0, 0x00, 0xb0, + 0x00, 0x24, 0x00, 0x0b, 0x01, 0x02, 0xc1, 0x81, + 0xb0, 0x10, 0x6c, 0xc0, 0x0b, 0x30, 0x02, 0x8c, + 0x02, 0x8a, 0x40, 0x2c, 0xf0, 0x03, 0x08, 0x02, + 0xc4, 0x40, 0xb1, 0x80, 0x20, 0xc0, 0x0b, 0x30, + 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x01, 0x18, 0x04, 0xb7, 0x00, 0x2d, 0xe0, + 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb6, 0x00, 0x2d, + 0x40, 0x0b, 0xf8, 0x02, 0x5e, 0x00, 0x8e, 0x80, + 0x61, 0x40, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x08, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xcc, + 0x00, 0x87, 0x40, 0x2d, 0xd0, 0x0b, 0x50, 0x02, + 0xdc, 0x00, 0xb4, 0x09, 0x21, 0xc0, 0x03, 0x70, + 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x08, 0x1e, 0x00, 0xf6, 0x80, 0x3d, 0xe0, + 0x0c, 0x78, 0x03, 0xde, 0x00, 0xf6, 0x80, 0x3d, + 0x20, 0x0e, 0x48, 0x07, 0x52, 0x00, 0xd6, 0x80, + 0x35, 0x20, 0x0f, 0x48, 0x43, 0xd2, 0x10, 0xf4, + 0x81, 0x75, 0x21, 0x0e, 0x78, 0x03, 0xde, 0x00, + 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0x9e, + 0x00, 0xc6, 0x80, 0x3d, 0xe0, 0x0f, 0x68, 0x03, + 0xde, 0x04, 0xf7, 0x80, 0xa1, 0xe1, 0x0f, 0x78, + 0x03, 0xea, 0x02, 0x00, 0xed, 0x09, 0x00, 0x04, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0xa8, + 0x10, 0xfa, 0x00, 0x3c, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfa, 0x00, 0x3e, 0x40, 0x0f, 0xb0, + 0x16, 0x0c, 0x10, 0xf2, 0x00, 0x3e, 0x40, 0x0d, + 0xb0, 0x03, 0xec, 0x00, 0xdb, 0x00, 0x7a, 0xc0, + 0x0d, 0x80, 0x03, 0xe4, 0x04, 0xfa, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x13, 0xe4, 0x00, 0xf8, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xc2, 0x06, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, + 0x00, 0xff, 0x80, 0x33, 0xe0, 0x0c, 0xf8, 0x03, + 0xfe, 0x00, 0xfe, 0x80, 0x3d, 0x20, 0x0e, 0x40, + 0x03, 0x32, 0x00, 0xfe, 0x80, 0x3f, 0x20, 0x0f, + 0xc8, 0x03, 0xd2, 0x02, 0xc4, 0x80, 0x7b, 0x24, + 0x0f, 0xf9, 0x03, 0x1e, 0x01, 0xc7, 0x90, 0x33, + 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xef, 0x84, + 0x3f, 0xe0, 0x0f, 0xe8, 0x03, 0xfe, 0x40, 0xcd, + 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xc0, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0x94, + 0x00, 0xb7, 0x00, 0x21, 0x80, 0x08, 0x70, 0x02, + 0xdc, 0x00, 0xb6, 0x00, 0x2d, 0x40, 0x08, 0x72, + 0x12, 0x1c, 0x80, 0x86, 0x00, 0x2d, 0x40, 0x0b, + 0x71, 0x02, 0xdc, 0x00, 0x87, 0x08, 0x21, 0xc4, + 0x0b, 0x71, 0x02, 0x18, 0x28, 0x85, 0x00, 0x29, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0x85, 0x00, + 0x2d, 0x00, 0x0b, 0x60, 0x02, 0xd4, 0x40, 0xa5, + 0x06, 0x2d, 0xc4, 0x0b, 0x70, 0x02, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, + 0x00, 0xb6, 0x40, 0x23, 0x80, 0x08, 0x70, 0x02, + 0xdc, 0x00, 0xb6, 0x00, 0x2d, 0x00, 0x0a, 0xc1, + 0x06, 0x12, 0x00, 0xa6, 0x40, 0x2d, 0x00, 0x0b, + 0x40, 0x02, 0xf0, 0x40, 0xa4, 0x00, 0x29, 0xed, + 0x09, 0x00, 0x05, 0x02, 0x21, 0x4b, 0xf0, 0x02, + 0x7c, 0x40, 0xaf, 0x08, 0x21, 0xc0, 0x0b, 0x70, + 0x02, 0xdc, 0x00, 0xa7, 0x48, 0x2d, 0xc0, 0x0b, + 0x40, 0x02, 0xfc, 0x60, 0x85, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x14, 0xc0, 0x00, 0xb2, 0x80, + 0x20, 0x80, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb2, + 0x00, 0x2c, 0x40, 0x48, 0x30, 0x02, 0x0e, 0x00, + 0x82, 0x05, 0x2c, 0x52, 0x0b, 0x30, 0x06, 0xcd, + 0x00, 0xa3, 0xc8, 0x20, 0xe0, 0x0b, 0x39, 0x02, + 0x4e, 0x10, 0xa3, 0xc0, 0x28, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0x81, 0x00, 0x2c, 0x00, 0x0b, + 0x00, 0x12, 0xc4, 0x04, 0xa1, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x15, 0xa4, 0x00, 0xf2, 0xc0, + 0xb2, 0x46, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfa, + 0x00, 0x3e, 0x00, 0x0e, 0x8c, 0x03, 0x20, 0x20, + 0xea, 0x40, 0x3c, 0x30, 0x0f, 0x00, 0x03, 0xe1, + 0x14, 0xe8, 0x40, 0x3a, 0x16, 0x0f, 0xb9, 0x03, + 0x6c, 0x00, 0xeb, 0x80, 0x32, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xeb, 0x40, 0x3e, 0x00, 0x0f, + 0x31, 0x03, 0xcc, 0x02, 0xc9, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0xe1, 0x00, 0xfb, 0x10, + 0x3e, 0x40, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfa, + 0x00, 0x3e, 0x40, 0x0f, 0xb8, 0x03, 0xec, 0x00, + 0xea, 0x00, 0x3e, 0x60, 0x0f, 0xb0, 0x03, 0xec, + 0x21, 0x5b, 0x00, 0x3e, 0xc0, 0x4f, 0xb4, 0x0b, + 0xac, 0x04, 0x1b, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb4, 0x03, 0xe4, 0x00, 0xf9, 0x40, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x06, 0x02, 0x01, + 0x10, 0xf4, 0x00, 0xfe, 0xa0, 0x73, 0x40, 0x0c, + 0xf0, 0x03, 0xfc, 0x00, 0xfe, 0x00, 0x37, 0x00, + 0x0d, 0xc0, 0x83, 0xf0, 0x08, 0xce, 0x00, 0x3f, + 0x00, 0x0c, 0xc0, 0x03, 0xf0, 0x00, 0xdc, 0x02, + 0x33, 0x00, 0x0f, 0xf8, 0x03, 0xf8, 0xa0, 0x4d, + 0x88, 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xcc, 0x00, + 0xcc, 0x00, 0x3f, 0x04, 0x0c, 0xd0, 0x03, 0x3c, + 0xa8, 0xc5, 0xc0, 0x33, 0xc0, 0x0f, 0xf0, 0x03, + 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, + 0x04, 0x63, 0x28, 0xba, 0x86, 0x20, 0x5c, 0x08, + 0xb0, 0x02, 0xec, 0x00, 0xb2, 0x00, 0x20, 0x41, + 0x08, 0xb0, 0x03, 0x8c, 0x00, 0x8a, 0x00, 0x2e, + 0x40, 0x08, 0xb0, 0x02, 0x0c, 0x00, 0x83, 0x00, + 0xa2, 0xc0, 0x09, 0xb9, 0x02, 0xcd, 0x28, 0x83, + 0x80, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0xa9, 0x80, 0x2e, 0xc0, 0x88, 0x98, 0x82, 0xa6, + 0x00, 0xa9, 0x48, 0x22, 0xc0, 0x0b, 0xb0, 0x02, + 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x05, 0x26, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x08, + 0xb0, 0x02, 0xec, 0x00, 0xba, 0x00, 0x26, 0x00, + 0x09, 0x80, 0x02, 0xe0, 0x00, 0x8a, 0x00, 0x2e, + 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x98, 0x00, + 0x22, 0x00, 0x1b, 0x84, 0x02, 0xe4, 0x00, 0xaa, + 0x28, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0x8b, 0x88, 0x2c, 0x10, 0x08, 0x81, 0x02, 0xac, + 0x00, 0x89, 0x00, 0x22, 0xc0, 0x4b, 0xb0, 0x02, + 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0xb3, 0x00, 0xa2, 0xc0, 0x48, + 0x30, 0x02, 0xcc, 0x00, 0xb2, 0x00, 0x20, 0x40, + 0x08, 0x30, 0x02, 0xac, 0x00, 0x82, 0x00, 0x2c, + 0x40, 0x08, 0x30, 0x4a, 0x2c, 0x00, 0x8b, 0x00, + 0x20, 0xc0, 0x09, 0x30, 0x46, 0xed, 0x09, 0x00, + 0x07, 0x02, 0xec, 0x00, 0xa3, 0x00, 0x20, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xa1, 0x00, 0x2c, + 0x00, 0x28, 0x90, 0x02, 0xa4, 0x00, 0xa1, 0x00, + 0x20, 0xc0, 0x03, 0x30, 0x02, 0xc2, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x64, 0x00, + 0xf8, 0x00, 0xa2, 0xc0, 0x2c, 0xb0, 0x03, 0xec, + 0x00, 0xfa, 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03, + 0xe0, 0x00, 0xca, 0x00, 0x3e, 0x00, 0x2c, 0x80, + 0x03, 0x60, 0x00, 0xd8, 0x00, 0x32, 0x00, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xeb, 0x00, 0xb2, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xc9, 0x00, 0x3e, + 0x00, 0x8c, 0xa0, 0x13, 0xa4, 0x02, 0xc9, 0x00, + 0x32, 0xc0, 0x07, 0xb0, 0x03, 0xc0, 0x03, 0x50, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xf0, 0x18, + 0xf6, 0x00, 0x3d, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0xfe, 0x00, 0x3f, 0x40, 0x0f, 0xf0, 0x03, + 0x9c, 0x00, 0xfe, 0x00, 0x3f, 0x40, 0x0f, 0xf0, + 0x03, 0x7c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0d, + 0x40, 0x03, 0xf0, 0x06, 0xdc, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xfc, 0x02, 0xfd, 0x00, 0x1f, + 0x00, 0x0f, 0xf0, 0x03, 0xdc, 0x14, 0xfd, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xe8, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x11, 0xf0, 0x00, + 0xfc, 0x00, 0x33, 0x01, 0x0f, 0xf0, 0x03, 0x3c, + 0x80, 0xfc, 0x00, 0x3b, 0xc6, 0x0f, 0xc1, 0x13, + 0xf0, 0x48, 0xcf, 0x30, 0x3f, 0x05, 0x0c, 0x60, + 0x0b, 0x30, 0x40, 0xcf, 0x00, 0x33, 0x05, 0x0c, + 0xf2, 0x03, 0x70, 0x40, 0xcf, 0x08, 0x33, 0x40, + 0x0c, 0xf2, 0x43, 0x3c, 0x80, 0xcf, 0x24, 0x33, + 0xc8, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0xe0, 0x00, + 0xed, 0x09, 0x00, 0x08, 0x02, 0xba, 0x00, 0x22, + 0x00, 0x0b, 0x90, 0x02, 0x3c, 0x40, 0xb8, 0x08, + 0x23, 0xd8, 0x0b, 0x80, 0x12, 0xe0, 0x80, 0x8f, + 0x40, 0x2e, 0xc8, 0x08, 0x92, 0x82, 0x2c, 0x80, + 0x8f, 0x48, 0x22, 0xc8, 0x08, 0xf4, 0x00, 0x2c, + 0x10, 0x8f, 0x40, 0x2a, 0xc0, 0x08, 0xf5, 0x02, + 0x1c, 0xe0, 0x8f, 0x10, 0x2b, 0xce, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x88, 0x05, 0xc2, 0x00, 0xb2, 0x00, 0x20, + 0x00, 0x0b, 0x10, 0x02, 0x0c, 0x00, 0xb2, 0x20, + 0x20, 0xc8, 0x0b, 0x22, 0x22, 0xca, 0x00, 0xa3, + 0x10, 0x2e, 0xc8, 0x98, 0x90, 0x02, 0x0c, 0x00, + 0x83, 0x30, 0x20, 0xc0, 0x09, 0x31, 0x02, 0x4c, + 0x00, 0x83, 0x00, 0x24, 0xca, 0x08, 0x30, 0x02, + 0x0c, 0x00, 0x93, 0x00, 0x20, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x15, 0xa4, 0x00, 0xb9, 0x20, 0xa2, + 0xc0, 0x0b, 0xb4, 0x42, 0x2c, 0x00, 0xbb, 0x20, + 0x22, 0xc0, 0x0b, 0xa5, 0x02, 0xcc, 0x00, 0x8b, + 0x01, 0x2e, 0x58, 0x08, 0x80, 0x00, 0x0c, 0x41, + 0x8b, 0x00, 0xa2, 0x20, 0x09, 0xb0, 0x12, 0x0c, + 0x10, 0x8b, 0x00, 0x2c, 0xc0, 0x08, 0xb0, 0x02, + 0x2c, 0x00, 0xbb, 0x01, 0x2a, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x05, 0xee, 0x00, 0xfb, 0x48, 0x32, + 0x12, 0x4f, 0x19, 0x0b, 0x2c, 0x00, 0xf9, 0x80, + 0x32, 0xc0, 0x0f, 0x9c, 0x03, 0xe6, 0x00, 0xeb, + 0x00, 0x3c, 0xf0, 0x0c, 0x9c, 0x03, 0x2e, 0x82, + 0xcb, 0x02, 0x32, 0xd2, 0x0d, 0x30, 0x03, 0x6f, + 0x02, 0xc3, 0x02, 0xed, 0x09, 0x00, 0x09, 0x02, + 0x36, 0xe0, 0x0c, 0xb0, 0x03, 0x2c, 0x00, 0xd3, + 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, + 0xbd, 0x00, 0xfd, 0x00, 0x3f, 0x52, 0x0f, 0xf8, + 0x43, 0xec, 0x00, 0xfd, 0x02, 0xb7, 0xc1, 0x0f, + 0xf8, 0x23, 0xfe, 0x40, 0xfb, 0x00, 0x3f, 0xa0, + 0x0f, 0xf9, 0x03, 0xfa, 0x00, 0xf7, 0x00, 0x3f, + 0xc0, 0x2e, 0xf0, 0x03, 0xfe, 0x50, 0xff, 0x00, + 0x3b, 0xe4, 0xaf, 0xf0, 0x4b, 0xfc, 0x00, 0xcf, + 0x04, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0xac, 0x00, 0xe9, 0x00, 0x3e, 0x00, 0x4f, 0xb4, + 0x0b, 0x2c, 0x00, 0xdb, 0x00, 0x32, 0xc0, 0x0c, + 0xb0, 0x0b, 0x2c, 0x00, 0xcb, 0x00, 0x32, 0xd0, + 0x4c, 0x94, 0x03, 0xa4, 0x02, 0xcb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xe5, 0x00, 0xcb, 0x08, + 0x3e, 0x40, 0x0f, 0x30, 0x07, 0xec, 0x00, 0xcb, + 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, + 0x2c, 0x08, 0x82, 0xe4, 0x2e, 0x60, 0x1b, 0x94, + 0x02, 0x3f, 0x10, 0x8b, 0x00, 0x37, 0xc0, 0x08, + 0xb0, 0x02, 0x2c, 0x00, 0xdf, 0x00, 0x22, 0xc0, + 0x08, 0x10, 0x02, 0x2c, 0x00, 0x8f, 0x00, 0x2e, + 0xc0, 0x0b, 0xf7, 0x02, 0xec, 0x00, 0xdf, 0x60, + 0x2e, 0xc0, 0x0b, 0xfa, 0x06, 0xfc, 0x00, 0x8f, + 0x88, 0x23, 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x3a, 0xc0, 0x0b, 0xb0, 0x02, 0xf2, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, + 0x40, 0x00, 0xa2, 0xc8, 0x2c, 0x34, 0xed, 0x09, + 0x00, 0x0a, 0x02, 0x4b, 0x0e, 0x02, 0x0e, 0x80, + 0x98, 0x00, 0x20, 0xc0, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x83, 0x00, 0x20, 0xc0, 0x09, 0x10, 0x02, + 0x8c, 0x00, 0x93, 0x00, 0x2e, 0xc0, 0x09, 0x30, + 0x02, 0xcc, 0x00, 0x83, 0x40, 0x2c, 0xc0, 0x0b, + 0x34, 0x82, 0xec, 0x00, 0x83, 0x08, 0x20, 0xc0, + 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xf8, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x01, 0x3a, 0x08, 0x85, + 0x81, 0x2d, 0x60, 0x1b, 0xf8, 0x82, 0x1e, 0x00, + 0x8f, 0x80, 0x24, 0xe4, 0x08, 0x59, 0x06, 0x3a, + 0x40, 0x97, 0x80, 0x23, 0xe0, 0x09, 0xd8, 0x02, + 0x16, 0x00, 0x97, 0x80, 0x2d, 0xe0, 0x0b, 0x78, + 0x02, 0xf6, 0x40, 0x97, 0x80, 0x2d, 0x64, 0x0b, + 0x78, 0x12, 0xde, 0x00, 0x87, 0x90, 0x20, 0xe0, + 0x08, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x29, + 0xe0, 0x0b, 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x08, 0x0c, 0x00, 0xe1, + 0x14, 0x3c, 0x08, 0x8b, 0x30, 0x03, 0x0c, 0x20, + 0xd2, 0x01, 0x30, 0xc4, 0x2c, 0xb0, 0x03, 0x0c, + 0x40, 0xc3, 0x00, 0xb0, 0x84, 0x09, 0x35, 0x03, + 0xa8, 0x80, 0xd3, 0x00, 0x3c, 0xc0, 0x05, 0x30, + 0x13, 0xcd, 0x44, 0xc3, 0x00, 0x3c, 0xc4, 0x0f, + 0x30, 0x22, 0xcc, 0x00, 0xc3, 0x00, 0x30, 0xc0, + 0x0c, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, + 0xc0, 0x0f, 0x30, 0x03, 0xd2, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x0d, 0x9c, 0x04, 0xff, + 0x04, 0x3f, 0xc0, 0x0f, 0x41, 0x23, 0xfd, 0x60, + 0xf6, 0x02, 0x3f, 0xc4, 0x0f, 0xe0, 0x03, 0xd8, + 0x50, 0xff, 0x10, 0x3d, 0xc0, 0x0e, 0xd1, 0x03, + 0x7c, 0x00, 0xef, 0x50, 0x3f, 0xc0, 0x0f, 0xf4, + 0x83, 0xdc, 0x40, 0xff, 0x09, 0x2f, 0xc4, 0x8f, + 0xf4, 0xed, 0x09, 0x00, 0x0b, 0x02, 0x03, 0xfc, + 0x40, 0xf7, 0x44, 0x3f, 0xc0, 0x0f, 0xf1, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3b, 0xc0, 0x0f, 0xf0, + 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x05, 0xec, 0x00, 0xfb, 0x01, 0x3e, 0x01, + 0x0f, 0x30, 0x03, 0x2c, 0x00, 0xcb, 0x00, 0x36, + 0xe4, 0x0c, 0x30, 0x03, 0x26, 0x00, 0xcb, 0xb0, + 0x32, 0x40, 0x0e, 0x80, 0x03, 0xec, 0x00, 0xfb, + 0x20, 0x36, 0x00, 0x0f, 0xb0, 0x23, 0xee, 0x00, + 0xcb, 0x68, 0x3e, 0xe0, 0x08, 0xb0, 0x03, 0xef, + 0xc0, 0xcb, 0x10, 0x32, 0xcc, 0x0c, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x01, 0x9c, 0x00, 0xb4, 0x00, 0x2d, 0x40, + 0x0b, 0x40, 0x02, 0x0c, 0x84, 0x85, 0x00, 0x2f, + 0xcc, 0x08, 0x50, 0x02, 0xb4, 0x00, 0x87, 0x08, + 0x21, 0xc0, 0x0b, 0x50, 0x02, 0xdc, 0x00, 0xb7, + 0x60, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xfc, 0x00, + 0x87, 0x00, 0x2f, 0xc1, 0x08, 0x76, 0x02, 0xdc, + 0x20, 0x87, 0x00, 0x23, 0xc4, 0x28, 0x70, 0x02, + 0x5c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, + 0x02, 0xd2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x9e, 0x20, 0xb4, 0x82, 0x2d, 0x20, + 0x0b, 0xc8, 0x12, 0x1e, 0x08, 0x87, 0x8b, 0x2d, + 0xe0, 0x18, 0xf8, 0x82, 0x1e, 0x00, 0xb7, 0x80, + 0x25, 0xe0, 0x09, 0x58, 0x02, 0xde, 0x00, 0xb7, + 0xa0, 0x2d, 0xe2, 0x0b, 0x7a, 0x02, 0xde, 0x00, + 0x87, 0xa0, 0x2d, 0xe0, 0x1a, 0x78, 0x02, 0xce, + 0x80, 0xb3, 0xa0, 0xa1, 0xe8, 0x0a, 0x78, 0x02, + 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, + 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x14, 0xce, 0x04, 0xb2, 0x04, 0x2c, 0xc1, + 0x0b, 0x38, 0x02, 0x0c, 0xed, 0x09, 0x00, 0x0c, + 0x02, 0x02, 0x83, 0x80, 0x2c, 0xc0, 0x08, 0xb0, + 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x24, 0x22, 0x4b, + 0x2f, 0x02, 0xc1, 0x60, 0xbb, 0x00, 0x2c, 0x00, + 0x8b, 0x30, 0x02, 0xc4, 0x40, 0x83, 0x00, 0x2c, + 0x40, 0x12, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x20, 0xc0, 0x0a, 0x30, 0x02, 0x4c, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xd2, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xb9, + 0x00, 0xf6, 0xc8, 0x3f, 0xb2, 0x0f, 0xe4, 0x8b, + 0x28, 0x00, 0xce, 0x40, 0x2e, 0x80, 0x2c, 0xe4, + 0x03, 0x39, 0x22, 0xfa, 0x00, 0x37, 0xb8, 0x0d, + 0xe4, 0x03, 0xfa, 0x00, 0xfa, 0x00, 0x3f, 0x80, + 0x0f, 0xa0, 0x02, 0xfb, 0x02, 0x4a, 0x00, 0x3e, + 0xa2, 0x2e, 0xa0, 0x43, 0xe8, 0x06, 0xfa, 0x01, + 0x32, 0x80, 0x0e, 0xa0, 0x03, 0xe8, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xfa, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xe2, + 0x00, 0xf8, 0x80, 0x3e, 0x20, 0x0f, 0x88, 0x03, + 0xe0, 0x00, 0xf8, 0x80, 0x3e, 0x00, 0x0f, 0x88, + 0x03, 0xe2, 0x00, 0x88, 0x00, 0xba, 0x00, 0x4f, + 0x80, 0x03, 0xe0, 0x01, 0xf8, 0x00, 0x3e, 0x08, + 0x0f, 0x80, 0x03, 0xe2, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0d, 0x80, 0x03, 0xe0, 0x00, 0x40, 0x00, + 0x3e, 0x00, 0x09, 0x80, 0x03, 0x60, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xd2, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xe4, + 0x00, 0xf9, 0x10, 0x32, 0x40, 0x4c, 0x90, 0x03, + 0x04, 0x08, 0xc9, 0x00, 0x3a, 0x40, 0x0f, 0x90, + 0x0b, 0x24, 0x00, 0xf9, 0x04, 0x3e, 0x40, 0x0f, + 0x90, 0x53, 0x64, 0x02, 0xc9, 0x04, 0x12, 0x40, + 0x0c, 0x94, 0x03, 0xe4, 0x00, 0xb1, 0xc0, 0xf2, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0xed, + 0x09, 0x00, 0x0d, 0x02, 0x00, 0x30, 0x40, 0x0c, + 0x90, 0x43, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, 0x66, 0x04, 0xb9, 0xc0, + 0x20, 0x40, 0x08, 0x12, 0x02, 0x27, 0x00, 0x89, + 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x04, + 0x00, 0x89, 0x04, 0x20, 0x40, 0x08, 0x98, 0x02, + 0xe4, 0x00, 0xb9, 0x80, 0x22, 0x40, 0x0b, 0x94, + 0x02, 0xe4, 0x00, 0xb9, 0xc0, 0xa2, 0x41, 0x28, + 0x90, 0x03, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x05, 0x24, 0x40, 0xb9, 0x40, + 0x26, 0x50, 0x48, 0x98, 0x02, 0x24, 0x72, 0x8b, + 0x00, 0x2e, 0x40, 0x0a, 0x90, 0x02, 0x24, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x10, 0x02, 0x24, + 0x00, 0x89, 0x00, 0x2e, 0x40, 0x08, 0x94, 0x12, + 0xe4, 0x00, 0xb9, 0x40, 0x22, 0x40, 0x0b, 0x96, + 0x02, 0xe4, 0x00, 0xb9, 0x10, 0x22, 0x40, 0x08, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, 0xb9, 0x04, + 0x26, 0x40, 0x08, 0x10, 0x2a, 0x04, 0x00, 0x81, + 0x40, 0x2c, 0x50, 0x0b, 0x14, 0x02, 0x05, 0x00, + 0xb1, 0x40, 0x2c, 0x50, 0x0b, 0x14, 0x00, 0x25, + 0x00, 0x81, 0x40, 0x2e, 0x50, 0x18, 0x10, 0x02, + 0xc5, 0x04, 0xb1, 0x00, 0x20, 0x50, 0x8b, 0x10, + 0x22, 0xc5, 0x00, 0xb3, 0x01, 0x20, 0x50, 0x08, + 0x10, 0x02, 0x84, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb8, 0x04, 0x60, 0x00, 0xf8, 0x00, + 0xb6, 0x00, 0x2c, 0x80, 0x0b, 0x20, 0x10, 0xc8, + 0x00, 0x3a, 0xed, 0x09, 0x00, 0x0e, 0x02, 0x00, + 0x0e, 0x80, 0x03, 0x20, 0x00, 0xf0, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x0b, 0x60, 0x00, 0xc8, 0x00, + 0x3e, 0x00, 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x22, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x32, 0x00, 0x0c, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, + 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, + 0x1d, 0xb4, 0x00, 0xfd, 0x04, 0x3b, 0x40, 0x0f, + 0xf0, 0x43, 0xe5, 0x00, 0x3f, 0x00, 0x3e, 0x50, + 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xf9, 0x40, 0x3f, + 0x40, 0x4f, 0xf0, 0x03, 0xf4, 0x00, 0xf9, 0x40, + 0xb3, 0x40, 0x2f, 0x94, 0x03, 0xf4, 0x00, 0xf9, + 0x40, 0x3f, 0x40, 0x0f, 0x94, 0x43, 0xe5, 0x00, + 0x79, 0x40, 0x3e, 0x50, 0x0f, 0x90, 0x03, 0xa4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x05, 0xf4, 0x00, 0xf5, 0x00, 0x31, 0x40, 0x0f, + 0xd0, 0x03, 0x34, 0x90, 0xc9, 0x00, 0x32, 0x4c, + 0x07, 0x90, 0x03, 0x24, 0x00, 0xf9, 0x11, 0x3e, + 0x40, 0x4f, 0x90, 0x11, 0xe4, 0x40, 0xc9, 0x00, + 0x32, 0x40, 0x0f, 0xd0, 0x03, 0x24, 0x00, 0xfd, + 0x28, 0x3e, 0x44, 0x8f, 0xd0, 0x03, 0x24, 0x00, + 0xfd, 0x00, 0x3e, 0x48, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xc6, 0x02, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x10, 0xe0, 0x00, 0xb8, 0x02, 0x22, 0x00, 0x0b, + 0x80, 0x02, 0x20, 0x00, 0x88, 0x20, 0x30, 0x0c, + 0x0b, 0xa0, 0x82, 0xa8, 0x28, 0xb8, 0x10, 0x2e, + 0x0b, 0x0b, 0x82, 0x02, 0xe0, 0x80, 0x88, 0x48, + 0x2a, 0x02, 0x0b, 0x81, 0x02, 0x20, 0xb1, 0x98, + 0x00, 0x2e, 0x08, 0x0b, 0x84, 0x0a, 0x20, 0x20, + 0xb8, 0x10, 0x2c, 0x0a, 0x0b, 0xed, 0x09, 0x00, + 0x0f, 0x02, 0x80, 0x02, 0x60, 0x00, 0xb8, 0x00, + 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xce, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xcc, 0x00, + 0xb1, 0x00, 0x20, 0x40, 0x0b, 0x30, 0x02, 0x04, + 0x40, 0x81, 0x28, 0xa4, 0x48, 0x0b, 0x92, 0x02, + 0x84, 0x00, 0xb1, 0x00, 0x2c, 0x48, 0x03, 0x12, + 0x82, 0xe6, 0x80, 0x81, 0x30, 0x20, 0x41, 0x0b, + 0x10, 0x02, 0x04, 0x90, 0xb1, 0x00, 0x2c, 0x48, + 0x0b, 0x11, 0x02, 0x04, 0x40, 0xb1, 0x02, 0x2c, + 0x4c, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, + 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc2, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa6, 0x20, + 0xbb, 0x82, 0xa2, 0x40, 0x4b, 0x90, 0x02, 0x24, + 0x00, 0x89, 0x00, 0x22, 0x40, 0x0b, 0x91, 0x42, + 0xa4, 0x80, 0xb9, 0x00, 0x2e, 0x51, 0x0b, 0x98, + 0x22, 0xe4, 0x05, 0x89, 0x00, 0x2a, 0x50, 0x0b, + 0x90, 0x22, 0x25, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0x64, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc6, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x15, 0xe6, 0x00, + 0xf1, 0xe0, 0x32, 0x68, 0x4f, 0x9c, 0x0b, 0x24, + 0x02, 0xc9, 0x40, 0x32, 0x40, 0x0f, 0x98, 0x03, + 0xa5, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x94, + 0x13, 0xe4, 0x00, 0xc9, 0x03, 0x32, 0x60, 0x0f, + 0x90, 0x0b, 0x26, 0x00, 0xb9, 0x00, 0x3e, 0x60, + 0x0f, 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x1f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x04, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, + 0xf9, 0x02, 0x3e, 0x68, 0x0f, 0x92, 0x03, 0xe4, + 0x00, 0xf9, 0xa0, 0x3e, 0x40, 0x0f, 0x98, 0x03, + 0xed, 0x09, 0x00, 0x10, 0x02, 0xe6, 0x00, 0xf9, + 0x00, 0x3e, 0x70, 0x0f, 0x90, 0x03, 0xe6, 0x82, + 0xf9, 0x02, 0x3e, 0x48, 0x0f, 0x10, 0x03, 0xe4, + 0x40, 0xd9, 0x04, 0x3e, 0x48, 0x0f, 0x10, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x10, 0xa1, 0x00, 0xf8, 0x00, 0x32, + 0x20, 0x3c, 0x88, 0x23, 0xc2, 0x08, 0xf8, 0x01, + 0x3e, 0x00, 0x2c, 0x80, 0x03, 0xe0, 0x00, 0xc8, + 0x00, 0x32, 0x10, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xe0, 0x02, 0x3e, 0x00, 0x0f, 0x88, 0x03, 0xe0, + 0x08, 0xe8, 0x80, 0x3e, 0x00, 0x0f, 0x82, 0x03, + 0x60, 0x00, 0xf8, 0x90, 0x3e, 0x00, 0x0c, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x05, 0x28, 0x00, 0xbe, 0x30, 0x23, + 0x90, 0x28, 0x60, 0x42, 0xfb, 0x10, 0xba, 0x00, + 0x2e, 0x80, 0x08, 0x20, 0x03, 0xa8, 0x00, 0xda, + 0x02, 0x22, 0x80, 0x03, 0xa0, 0x02, 0xc8, 0x00, + 0xba, 0x02, 0x2e, 0x80, 0x0b, 0xec, 0x82, 0xe8, + 0x00, 0xbe, 0x4c, 0x2e, 0x80, 0x0b, 0xe2, 0x43, + 0xa8, 0x00, 0xbe, 0x01, 0x2e, 0x80, 0x08, 0xa0, + 0x42, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, + 0xa0, 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x05, 0x44, 0x00, 0xb3, 0x80, 0x20, + 0x84, 0x08, 0x20, 0x02, 0xce, 0x48, 0xbb, 0x00, + 0x2c, 0xc0, 0x08, 0x30, 0x02, 0x8c, 0x00, 0x83, + 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xa3, 0x00, 0x2c, 0xc0, 0x0b, 0x10, 0x12, 0xcc, + 0x00, 0xb1, 0x80, 0x2c, 0xc0, 0x0b, 0x08, 0x02, + 0x8c, 0x00, 0xb0, 0x80, 0x2c, 0xc0, 0x28, 0x30, + 0x02, 0xcc, 0x00, 0xed, 0x09, 0x00, 0x11, 0x02, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xca, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, + 0x14, 0x00, 0xbc, 0x00, 0x21, 0x60, 0x08, 0x70, + 0x22, 0xdc, 0x00, 0xb7, 0x22, 0x2d, 0xe0, 0x08, + 0x72, 0x02, 0xbe, 0x04, 0x97, 0x80, 0x21, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x80, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x06, 0xdc, 0x41, 0xb7, 0x00, + 0x2d, 0xc4, 0x0b, 0x70, 0x02, 0x9c, 0x00, 0xb7, + 0x00, 0x2d, 0xe0, 0x18, 0x70, 0x02, 0xdc, 0x00, + 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xe8, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, + 0x16, 0x00, 0xf4, 0x80, 0xa1, 0xe0, 0x08, 0x58, + 0x03, 0xd6, 0x08, 0xf7, 0xc0, 0x3d, 0xec, 0x0c, + 0x7c, 0x83, 0x9f, 0x80, 0xc3, 0xa8, 0xb1, 0xea, + 0x0f, 0x7a, 0x03, 0xdf, 0x20, 0xe7, 0xa0, 0x2d, + 0xea, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, + 0x3d, 0xe4, 0x0f, 0x78, 0x23, 0x1e, 0xc0, 0xf7, + 0x80, 0x3d, 0xec, 0x0c, 0x78, 0x03, 0xde, 0x00, + 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xea, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, + 0xa4, 0x00, 0xfb, 0x00, 0x3e, 0x00, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xbb, 0x4a, 0x3e, 0xd0, 0x0f, + 0xb6, 0x03, 0x8c, 0x00, 0xfb, 0x10, 0x3e, 0xc4, + 0x07, 0xb6, 0x03, 0xec, 0x04, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0x90, 0x03, 0xec, 0xb0, 0xf9, 0x00, + 0x3e, 0xd0, 0x8f, 0xb0, 0x03, 0xad, 0x00, 0xbb, + 0x02, 0x3e, 0xc8, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xc2, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, + 0xfe, 0x00, 0xfd, 0x80, 0x3d, 0x60, 0x0c, 0xf8, + 0x03, 0xfa, 0x10, 0xcf, 0x80, 0x37, 0xe2, 0x03, + 0xf3, 0x43, 0x3f, 0x00, 0xef, 0x80, 0xed, 0x09, + 0x00, 0x12, 0x02, 0x3f, 0xe0, 0x0c, 0xfc, 0xc5, + 0xfe, 0x40, 0xff, 0xd8, 0x3d, 0xe2, 0x0c, 0xf9, + 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x4f, + 0xf9, 0x43, 0x3e, 0x20, 0xff, 0x80, 0x2f, 0xe6, + 0x0f, 0xf8, 0x21, 0xfe, 0x00, 0xff, 0x80, 0x3f, + 0xe0, 0x0f, 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x11, 0x9c, 0x00, 0xb6, + 0x00, 0x2d, 0x08, 0x08, 0x40, 0x42, 0xd8, 0x00, + 0x87, 0x00, 0x21, 0xc8, 0x0b, 0x70, 0x02, 0x1c, + 0xa0, 0x97, 0x00, 0x2d, 0xc2, 0x08, 0x70, 0x07, + 0x5c, 0x40, 0xb7, 0x00, 0x2d, 0xc0, 0x08, 0x70, + 0x40, 0xdc, 0x00, 0xb7, 0x40, 0x2d, 0xc1, 0x0b, + 0x40, 0x02, 0x1c, 0x40, 0xb7, 0x10, 0x25, 0xcc, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0xb7, + 0x00, 0x2d, 0x01, 0x08, 0x50, 0x02, 0xdc, 0x00, + 0x87, 0x00, 0x29, 0xc0, 0x49, 0x71, 0x02, 0x1c, + 0x10, 0xa7, 0x00, 0x2d, 0xc0, 0x09, 0x70, 0x02, + 0xdd, 0x0c, 0xb7, 0x00, 0x27, 0xc0, 0x08, 0x70, + 0x42, 0xdd, 0x20, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x42, 0x9c, 0x00, 0xb4, 0x00, 0x25, 0xc0, + 0x8b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x14, 0xc5, 0x20, 0xb1, + 0x48, 0x2c, 0x50, 0x00, 0x18, 0x02, 0xc0, 0x01, + 0x83, 0x58, 0x2c, 0xc0, 0x0b, 0x30, 0x82, 0x0e, + 0x04, 0xbb, 0x05, 0x0e, 0xf0, 0x09, 0xb4, 0x12, + 0x4e, 0x00, 0xb3, 0x04, 0x2c, 0xf0, 0x08, 0x30, + 0x02, 0x4e, 0x00, 0xb3, 0x00, 0x0c, 0xe0, 0x43, + 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x24, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0xed, 0x09, 0x00, 0x13, 0x02, 0x0b, 0x30, + 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xac, 0x05, 0xad, 0x00, 0xf1, 0x80, 0x3c, 0x70, + 0x2c, 0x39, 0x01, 0xec, 0x02, 0xcf, 0x00, 0xbb, + 0xc0, 0x0d, 0xf4, 0x0b, 0x1e, 0x00, 0xef, 0x00, + 0x3f, 0xc0, 0x2d, 0xf0, 0x03, 0xfc, 0x20, 0xff, + 0x00, 0x27, 0xc6, 0x0c, 0xb0, 0x03, 0xfe, 0x00, + 0x3b, 0x00, 0x3f, 0xc0, 0x0b, 0x30, 0x4b, 0xbc, + 0x00, 0xfb, 0x02, 0x37, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0xee, 0x00, 0xf9, 0xc0, 0x3e, 0x20, + 0x0f, 0x81, 0x13, 0xed, 0x00, 0xfb, 0x00, 0x22, + 0xc0, 0x0f, 0xb8, 0x43, 0xec, 0x00, 0xdb, 0x00, + 0x3e, 0xc2, 0x0e, 0xb8, 0x87, 0x2c, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x2f, 0x30, 0x03, 0xec, 0x00, + 0xf3, 0x40, 0x3e, 0xc4, 0x0f, 0xb0, 0x13, 0x4c, + 0x10, 0xf8, 0x00, 0x36, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xf6, 0x40, 0xfc, 0x80, 0x33, 0x22, + 0x1c, 0xda, 0x03, 0x3f, 0x00, 0xcf, 0x00, 0x31, + 0xc0, 0x8c, 0xf0, 0x03, 0xfc, 0x20, 0xef, 0x04, + 0x3b, 0xc0, 0x0c, 0xf0, 0x03, 0x3c, 0x00, 0xff, + 0x00, 0x33, 0xc0, 0x0c, 0xf1, 0x03, 0x3c, 0x00, + 0xbf, 0x12, 0x33, 0xc0, 0x4c, 0xc4, 0x03, 0x3c, + 0x00, 0xcf, 0x80, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xc0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x04, 0x64, 0x00, 0xb8, 0x80, 0x22, 0x50, + 0x08, 0x9a, 0x12, 0x05, 0x80, 0x8b, 0x00, 0x22, + 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xdb, 0x00, + 0x22, 0xc0, 0x08, 0xb0, 0xed, 0x09, 0x00, 0x14, + 0x02, 0x02, 0x2c, 0x04, 0xbb, 0x00, 0x36, 0xc0, + 0x0d, 0xb4, 0x92, 0x2c, 0x00, 0xbb, 0x40, 0x20, + 0xc0, 0x08, 0xb0, 0x03, 0x6c, 0x00, 0x8b, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x24, + 0x00, 0xb9, 0x11, 0x22, 0x86, 0x08, 0x80, 0x02, + 0x2c, 0x00, 0x83, 0x00, 0x26, 0xc0, 0x08, 0xb0, + 0x02, 0xec, 0x08, 0x8b, 0x00, 0xa2, 0xc0, 0x18, + 0xb0, 0x06, 0x2c, 0x00, 0xb3, 0x03, 0x20, 0xc0, + 0x88, 0x90, 0x02, 0x2c, 0x08, 0xb9, 0x00, 0x22, + 0xc0, 0x08, 0xb4, 0x02, 0x6c, 0x00, 0x8b, 0x22, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, + 0x00, 0xb9, 0x00, 0x22, 0x40, 0x28, 0x90, 0x0a, + 0x08, 0x00, 0x83, 0x00, 0x20, 0xc0, 0x28, 0x30, + 0x02, 0xec, 0x04, 0x93, 0x00, 0x20, 0xc0, 0x28, + 0x30, 0x1a, 0x0c, 0x00, 0xb3, 0x01, 0x24, 0xc0, + 0x09, 0x30, 0x0a, 0x0c, 0x01, 0xb3, 0x00, 0xa2, + 0xc0, 0xa8, 0x30, 0x02, 0x4c, 0x12, 0x83, 0x80, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x10, 0xc2, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x64, + 0x00, 0xf8, 0x00, 0xb2, 0xc0, 0x08, 0x90, 0x03, + 0x20, 0x02, 0xc7, 0x00, 0xb3, 0xc0, 0x0c, 0x70, + 0x02, 0xfc, 0x00, 0x8f, 0x00, 0x31, 0xc0, 0x4c, + 0xf0, 0x43, 0x3c, 0x00, 0x7f, 0x00, 0x63, 0xc0, + 0x0c, 0xb0, 0x03, 0x3c, 0x01, 0xfb, 0x02, 0x33, + 0xc0, 0x0c, 0xb0, 0x03, 0x7c, 0x00, 0xcb, 0x00, + 0x3f, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xc0, 0xed, + 0x09, 0x00, 0x15, 0x02, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x1d, 0xf4, 0x00, 0xfc, 0x04, + 0x3f, 0x00, 0xcf, 0xd0, 0x13, 0xd0, 0x00, 0xff, + 0x04, 0x17, 0xc0, 0x0f, 0xf0, 0x23, 0xfc, 0x08, + 0xff, 0x00, 0x37, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x00, 0x7f, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x03, + 0xfc, 0x04, 0xfc, 0x00, 0x3f, 0xc0, 0x1f, 0x40, + 0x03, 0xfc, 0x00, 0xfc, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x05, 0xdc, 0x00, 0xfd, 0x00, + 0x3d, 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0x00, 0x0f, 0xe0, 0x03, 0xd4, 0x00, + 0xcf, 0x01, 0x3f, 0xc0, 0x0f, 0xe0, 0x43, 0xf4, + 0x00, 0xc7, 0x00, 0x31, 0xc0, 0x0f, 0x70, 0x03, + 0xfc, 0x00, 0xfc, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xfc, 0x00, 0xfe, 0x01, 0x33, 0x00, 0x0e, + 0xe0, 0x03, 0x3c, 0xc8, 0xcf, 0x00, 0x33, 0x00, + 0x0c, 0xf0, 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x10, 0xec, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xa0, 0x02, 0xe0, 0x10, + 0xd8, 0x00, 0x2e, 0x00, 0x0b, 0xa0, 0x02, 0xe0, + 0x00, 0xd8, 0x00, 0x36, 0x00, 0x0b, 0x80, 0x02, + 0xe0, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x08, 0xba, 0x00, 0x22, 0x80, 0x08, + 0xb0, 0x02, 0x2d, 0x00, 0x8b, 0x02, 0x22, 0x00, + 0x08, 0xb0, 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x88, 0x05, 0xcc, 0x00, 0xb1, 0x01, + 0x2c, 0x40, 0x1b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x20, 0x02, 0xe4, 0x00, + 0xb3, 0x00, 0x2c, 0xc1, 0x8b, 0x20, 0x02, 0xc4, + 0x00, 0x83, 0xed, 0x09, 0x00, 0x16, 0x02, 0x00, + 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x08, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb0, 0x00, 0x22, 0x01, 0x8b, 0xb0, 0x02, 0x4d, + 0x00, 0x8a, 0x00, 0x20, 0xa0, 0x28, 0x30, 0x02, + 0xe2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x15, 0xa4, 0x90, 0xb9, 0x02, 0x2e, 0x42, 0x0b, + 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc8, + 0x0b, 0xa0, 0x02, 0xe0, 0x01, 0xb8, 0x00, 0x2e, + 0x00, 0x0b, 0xa0, 0x02, 0xe0, 0x10, 0x98, 0x04, + 0x26, 0x00, 0x0b, 0x80, 0x42, 0xe0, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x08, + 0xbb, 0x00, 0x22, 0x80, 0x09, 0xb8, 0xa2, 0x6c, + 0x40, 0x8b, 0x40, 0x22, 0xe0, 0x08, 0xb0, 0x02, + 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x15, 0xef, 0x00, 0xf9, 0x00, 0x3e, 0xa0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xe0, + 0x4f, 0xa0, 0x13, 0xe4, 0x08, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xa0, 0x03, 0xe4, 0x00, 0xc3, 0x00, + 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfa, 0x00, 0xb0, 0x00, 0x0f, 0xb0, 0x0b, 0x6e, + 0x02, 0xca, 0x00, 0x90, 0x01, 0x0c, 0xb0, 0x03, + 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x01, 0xb8, 0x00, 0xfd, 0x90, 0x3f, 0xd0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xe0, + 0x0f, 0xe0, 0x83, 0xf0, 0x10, 0x9c, 0x00, 0x3f, + 0x00, 0x0f, 0xe0, 0x03, 0xf0, 0x00, 0xfc, 0x00, + 0x3f, 0x00, 0x07, 0xc0, 0x03, 0xf0, 0x00, 0x7f, + 0x20, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x08, + 0xf2, 0x40, 0x3f, 0xa4, 0x2e, 0xf0, 0x03, 0xbc, + 0x04, 0xfe, 0x01, 0x3f, 0x40, 0x0f, 0xf0, 0x03, + 0xf8, 0x00, 0x60, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x17, 0x02, 0x00, 0x00, 0x40, 0x10, 0xaf, 0x20, + 0xc9, 0x00, 0x3e, 0xe0, 0x2c, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0x08, 0x0f, 0xa0, 0x03, + 0xe4, 0x80, 0xcb, 0x00, 0x3e, 0xc2, 0x0f, 0xa2, + 0x03, 0xe4, 0x00, 0xfb, 0x00, 0x32, 0xc8, 0x0c, + 0xb0, 0x03, 0x2e, 0x00, 0xc8, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf8, 0x00, 0xb2, + 0x04, 0x4c, 0xb0, 0x8b, 0x28, 0x02, 0xc8, 0x30, + 0x3e, 0xa0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2e, 0x00, + 0x29, 0x00, 0x2e, 0xa0, 0x08, 0xb0, 0x02, 0xec, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xa4, 0x02, + 0xc1, 0x00, 0xa8, 0x00, 0x2e, 0x10, 0x03, 0xa4, + 0x02, 0xc2, 0x00, 0xb8, 0x80, 0x36, 0x00, 0x08, + 0x8a, 0x22, 0xa0, 0x00, 0x8b, 0xe4, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, + 0xb4, 0x0a, 0x32, 0x22, 0x2f, 0x60, 0x80, 0x40, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xf2, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4d, 0x00, + 0x81, 0x00, 0x2c, 0xc0, 0x09, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xd0, 0x0b, 0x25, 0x22, + 0xc6, 0x00, 0x13, 0x00, 0x2c, 0xd0, 0x13, 0x21, + 0x02, 0xc7, 0x80, 0xb3, 0x20, 0x20, 0xd0, 0x08, + 0x32, 0x02, 0x0c, 0x00, 0x83, 0x80, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb2, 0x00, 0x20, + 0x30, 0x08, 0x18, 0x02, 0x2e, 0x00, 0x83, 0x40, + 0x2c, 0x00, 0x0b, 0x30, 0x02, 0xf8, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x1e, 0x00, + 0xa5, 0x90, 0x2d, 0xe0, 0x09, 0x78, 0x02, 0xde, + 0x00, 0xb7, 0x80, 0x2d, 0x20, 0x0b, 0x68, 0x02, + 0xf2, 0x00, 0xb4, 0x80, 0x2d, 0x28, 0x0b, 0x68, + 0x02, 0xd2, 0x20, 0xbc, 0x80, 0x27, 0x22, 0x08, + 0xed, 0x09, 0x00, 0x18, 0x02, 0x49, 0x42, 0x92, + 0x40, 0x84, 0xc0, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0xde, 0x00, 0xb7, 0x80, 0x23, 0x24, 0x0a, 0xfa, + 0x02, 0x16, 0x00, 0x87, 0x80, 0x2d, 0x70, 0x0b, + 0x78, 0x02, 0xc8, 0x10, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x08, 0x0c, 0x00, 0xc1, 0x10, 0x3c, + 0xc8, 0x0d, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, + 0x3c, 0xd0, 0x0f, 0x20, 0x02, 0xc4, 0x20, 0xd3, + 0x00, 0x3c, 0xc0, 0x0f, 0x20, 0x03, 0xc4, 0x00, + 0xf3, 0x08, 0x30, 0xc0, 0x0c, 0x30, 0x03, 0x0c, + 0x00, 0xc3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, + 0xcc, 0x40, 0xf2, 0x00, 0x30, 0x00, 0x1c, 0x30, + 0x03, 0x2c, 0x04, 0xc2, 0x23, 0x7c, 0x81, 0x4f, + 0x30, 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x1d, 0xbc, 0x00, 0xfd, 0x10, 0x3f, + 0xc0, 0x0e, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xe1, 0x03, 0xf0, 0x00, 0xec, + 0x00, 0x3f, 0x28, 0x0f, 0xe1, 0x03, 0xf0, 0x00, + 0xfc, 0x00, 0x3f, 0x00, 0x2f, 0xc0, 0x43, 0xd2, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3d, 0x00, 0x0f, 0x72, + 0x03, 0xf4, 0x40, 0xfe, 0x00, 0x3f, 0x40, 0x0f, + 0xf0, 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x05, 0xcc, 0x02, 0xc9, 0x80, 0xb2, + 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x80, + 0x3a, 0xc0, 0x0f, 0xa0, 0x03, 0xe4, 0x00, 0xfb, + 0x00, 0x3e, 0xe0, 0x0c, 0xa0, 0x03, 0xe6, 0x00, + 0xe3, 0x80, 0x32, 0xc0, 0x1d, 0xb8, 0x03, 0x2c, + 0x04, 0xcb, 0x80, 0x32, 0xc0, 0x0f, 0xb0, 0x07, + 0xec, 0x00, 0xfa, 0x00, 0x3a, 0x00, 0x0c, 0x38, + 0x03, 0x2c, 0x06, 0xca, 0x00, 0x10, 0x20, 0x0c, + 0xb0, 0x03, 0xea, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x11, 0xed, 0x09, 0x00, 0x19, 0x02, + 0x9c, 0x00, 0x85, 0x00, 0x21, 0x80, 0x08, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x21, 0xc0, 0x0b, + 0x60, 0x22, 0xd0, 0x00, 0xb4, 0x02, 0x2d, 0x00, + 0x0d, 0x60, 0x22, 0xd0, 0x00, 0x84, 0x00, 0x35, + 0x00, 0x0b, 0x40, 0x02, 0x10, 0x00, 0x87, 0x00, + 0x35, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, + 0x00, 0x21, 0x40, 0x28, 0x70, 0x02, 0x1c, 0x00, + 0x86, 0x00, 0x21, 0x40, 0x08, 0x70, 0x42, 0xd2, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0xbe, 0x00, 0x8d, 0x80, 0x23, 0xa0, 0x08, 0x78, + 0x02, 0xde, 0x00, 0xb7, 0x80, 0x29, 0xe0, 0x0b, + 0x68, 0x02, 0xd6, 0x00, 0xb7, 0x80, 0x2f, 0xe0, + 0x08, 0x68, 0x02, 0xf6, 0x00, 0xa7, 0x80, 0x21, + 0xe0, 0x0b, 0xf8, 0x7a, 0x3e, 0x08, 0x87, 0x80, + 0x21, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x08, 0xb2, + 0x80, 0x2b, 0x20, 0x2a, 0x78, 0x02, 0x0a, 0x00, + 0x8c, 0x80, 0x27, 0xa0, 0x28, 0x78, 0x02, 0xf0, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, + 0xcf, 0x00, 0x83, 0x81, 0x20, 0xa4, 0x08, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0x1c, 0x0b, + 0x20, 0x02, 0xc0, 0x00, 0xb0, 0x00, 0x2c, 0x00, + 0x09, 0x20, 0x02, 0xc0, 0x00, 0x80, 0x00, 0x24, + 0x00, 0x0b, 0x00, 0x02, 0x00, 0x10, 0x80, 0x64, + 0x24, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x02, 0x22, 0x10, 0x0a, 0x30, 0x12, 0x0d, 0x44, + 0x80, 0x90, 0x24, 0xc0, 0x08, 0x30, 0x02, 0xd2, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, + 0x98, 0x00, 0xca, 0x20, 0x33, 0x90, 0x2c, 0xa0, + 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3b, 0xa0, 0x0f, + 0x20, 0x03, 0xe8, 0x00, 0xf2, 0x00, 0x3e, 0x80, + 0x0c, 0xa0, 0x03, 0xe8, 0x00, 0xea, 0x00, 0x32, + 0x80, 0x0d, 0xa0, 0x03, 0x28, 0x0c, 0xed, 0x09, + 0x00, 0x1a, 0x02, 0xce, 0x44, 0x32, 0x80, 0x0f, + 0xa0, 0x03, 0xe8, 0x00, 0xfe, 0x00, 0x3b, 0x90, + 0x0e, 0xe4, 0x03, 0x3a, 0x00, 0xce, 0x40, 0xb7, + 0x80, 0x0c, 0xa0, 0x03, 0xfa, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x00, 0xe0, 0x40, 0xf8, + 0x00, 0x3e, 0x20, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xf0, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0x80, 0x03, + 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0, + 0x03, 0xf0, 0x12, 0xf8, 0x10, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x08, + 0x49, 0x88, 0x0b, 0xc0, 0x20, 0xf8, 0x80, 0x3a, + 0x20, 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0xe6, 0x20, 0xc9, + 0x01, 0x3e, 0x44, 0x0c, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x23, 0x24, + 0x00, 0xf9, 0x00, 0x32, 0x40, 0x4f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xc9, 0x00, 0x2e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xf1, 0x00, 0x32, 0x40, + 0x0d, 0x98, 0x13, 0xe6, 0x80, 0x89, 0x90, 0x32, + 0x44, 0x0f, 0x90, 0x03, 0xc2, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x04, 0x65, 0x02, 0x89, + 0x00, 0x2c, 0x52, 0x28, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2c, 0x40, 0x08, 0x90, 0x02, 0xa4, + 0x10, 0x99, 0x04, 0x2a, 0x40, 0x0b, 0x90, 0x02, + 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x41, 0x03, 0x98, + 0x00, 0xc4, 0x62, 0x89, 0x10, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x22, 0x40, + 0x08, 0x90, 0x02, 0xe7, 0x02, 0x81, 0x00, 0x22, + 0x40, 0x0b, 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x05, 0x2c, 0x80, 0x09, + 0x00, 0xed, 0x09, 0x00, 0x1b, 0x02, 0x2e, 0x40, + 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x08, 0x90, 0x22, 0x24, 0x00, 0xbd, 0x00, + 0x23, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xbd, + 0x00, 0x2f, 0x40, 0x0b, 0xd2, 0x00, 0xf4, 0x00, + 0x8b, 0x00, 0x2e, 0x40, 0x4b, 0x90, 0x02, 0xe4, + 0x00, 0xbb, 0x00, 0xa2, 0xc0, 0x09, 0x92, 0x02, + 0xe5, 0x00, 0xa9, 0x00, 0x62, 0x42, 0x0b, 0x90, + 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x2c, 0x08, 0x81, 0x00, 0x2c, 0x40, + 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2e, + 0x40, 0x08, 0x90, 0x02, 0x94, 0x00, 0x9d, 0x00, + 0x29, 0x40, 0x0b, 0x10, 0x02, 0xd4, 0x00, 0xb5, + 0x00, 0x2d, 0x40, 0x0b, 0x50, 0x42, 0xd4, 0x00, + 0x81, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, + 0x10, 0xb1, 0x00, 0x20, 0x50, 0x08, 0x10, 0x02, + 0xc5, 0x10, 0xa1, 0x00, 0x20, 0x40, 0x0b, 0x10, + 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x0d, 0x60, 0x00, 0xc8, 0x00, 0x3e, 0x00, + 0x0c, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, + 0x00, 0x0c, 0x80, 0x03, 0x20, 0x00, 0xf8, 0x00, + 0x33, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0xa0, 0x03, 0xf0, 0x00, + 0xca, 0x00, 0x3e, 0x00, 0x07, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0d, 0x80, 0x03, + 0xe0, 0x00, 0xe8, 0x00, 0x32, 0x00, 0x8f, 0x80, + 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x1d, 0xfc, 0x06, 0xf5, 0x00, 0x3d, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf1, 0x00, 0x3f, + 0x41, 0x2f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x02, + 0x3c, 0x40, 0x0f, 0x90, 0x03, 0xc4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x10, 0x03, 0xc4, 0x00, + 0xf5, 0x00, 0x3e, 0x40, 0xed, 0x09, 0x00, 0x1c, + 0x02, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xfd, 0x40, + 0x3d, 0x40, 0x0f, 0xd0, 0x23, 0xf5, 0x00, 0xd7, + 0x00, 0xbf, 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x06, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xd4, + 0x00, 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xc4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0x04, 0x00, 0xf9, 0x00, 0x3e, 0x40, + 0x0c, 0xd0, 0x23, 0xf4, 0x00, 0xfd, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x09, + 0x33, 0x44, 0x0e, 0x70, 0x03, 0xf5, 0x80, 0xcd, + 0x00, 0x3f, 0xc0, 0x0c, 0x90, 0x03, 0xc6, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, + 0x00, 0xb8, 0x00, 0x2e, 0x80, 0x0b, 0x80, 0x02, + 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, + 0x02, 0xf0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, + 0x80, 0x23, 0x60, 0x08, 0xb8, 0x00, 0x2f, 0x00, + 0x88, 0x80, 0x02, 0xe0, 0x0c, 0x9a, 0x00, 0x2e, + 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x40, + 0x22, 0x00, 0x08, 0xa0, 0x02, 0xe0, 0x02, 0x88, + 0x00, 0x2e, 0x00, 0x28, 0x80, 0x02, 0xce, 0x04, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, + 0x00, 0xb1, 0x01, 0x2c, 0xc0, 0x1b, 0x10, 0x02, + 0xc4, 0x00, 0xb1, 0x00, 0x2d, 0x60, 0x0b, 0x50, + 0x22, 0xd4, 0x00, 0xb1, 0x00, 0x2d, 0x40, 0x0b, + 0x50, 0x02, 0x14, 0x00, 0xb5, 0x00, 0x2f, 0x40, + 0x48, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, + 0x20, 0x48, 0x0a, 0x10, 0x02, 0xc5, 0x80, 0x81, + 0x00, 0x2e, 0x40, 0x08, 0x10, 0x02, 0xc2, 0x01, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, + 0x40, 0xb9, 0x20, 0x2e, 0xc0, 0x0b, 0x90, 0xed, + 0x09, 0x00, 0x1d, 0x02, 0x02, 0xe4, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0xd0, 0x02, 0xf4, 0x00, + 0xb9, 0x00, 0x2e, 0x41, 0x0b, 0xd0, 0x02, 0x74, + 0x00, 0xbd, 0x02, 0x2f, 0x40, 0x08, 0x90, 0x02, + 0xe4, 0x08, 0x99, 0x20, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xe4, 0x04, 0xb9, 0x00, 0xa2, 0x40, 0x18, + 0x90, 0x02, 0xe4, 0x20, 0x89, 0x00, 0x4e, 0x40, + 0x08, 0x90, 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x15, 0xe5, 0x00, 0xf9, 0x01, + 0x3e, 0x50, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x74, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x10, 0x03, 0x24, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x40, 0x7e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x98, 0x30, 0x48, 0x0e, + 0x90, 0x43, 0xe5, 0x00, 0xc9, 0x00, 0x3e, 0x63, + 0x0c, 0x90, 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0b, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x60, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0x99, 0x00, 0x3e, 0x40, 0xaf, 0x90, 0x03, + 0xe4, 0x10, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x08, 0xf1, 0x00, 0x3e, 0x40, 0x0f, + 0x9c, 0x03, 0xe4, 0x10, 0xf9, 0x20, 0x3e, 0x48, + 0x0f, 0x90, 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x10, 0xa2, 0x00, 0xc8, 0x01, + 0x3e, 0x20, 0x2c, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, + 0xc8, 0x00, 0x3f, 0x00, 0x0c, 0xc0, 0x03, 0x70, + 0x00, 0xcc, 0x00, 0x33, 0x00, 0x4c, 0x80, 0x03, + 0x20, 0x80, 0xf8, 0xc0, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0xed, 0x09, 0x00, 0x1e, 0x02, 0x00, + 0xf8, 0x40, 0x32, 0x00, 0x0d, 0x84, 0x03, 0x20, + 0x02, 0xc8, 0xc0, 0x32, 0x02, 0x0f, 0x80, 0x03, + 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x3b, 0x22, 0x8a, 0x00, 0x2f, 0x90, 0x08, + 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, + 0x0b, 0xa0, 0x02, 0xe8, 0x02, 0x8a, 0x04, 0x2e, + 0x80, 0x0a, 0xa0, 0x02, 0x28, 0x08, 0xaa, 0x01, + 0x20, 0x80, 0x0a, 0xe8, 0x02, 0x38, 0x04, 0x3e, + 0xe0, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, + 0xba, 0x00, 0xa3, 0x80, 0x4a, 0xe2, 0x0a, 0x38, + 0x80, 0x8e, 0x49, 0x21, 0x80, 0x0b, 0xa0, 0x02, + 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x46, 0x00, 0x83, 0x00, 0x2c, 0x40, 0x09, + 0x30, 0x02, 0xcc, 0x00, 0xb2, 0x00, 0x2c, 0x00, + 0x0b, 0x00, 0x02, 0xc0, 0x00, 0x82, 0x00, 0x2c, + 0x00, 0x08, 0x00, 0x02, 0x40, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x48, 0x02, 0x02, 0x0c, 0x04, 0xb3, + 0x80, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x20, 0xc0, 0x09, 0x08, 0x82, 0x2e, + 0x00, 0x81, 0x80, 0x6c, 0xe0, 0x0b, 0x30, 0x02, + 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x01, 0x3e, 0x08, 0x87, 0x00, 0x2d, 0x60, 0x09, + 0x70, 0x02, 0xdc, 0x00, 0xb6, 0x00, 0x2d, 0x40, + 0x0b, 0x70, 0x02, 0xde, 0x00, 0x86, 0x00, 0x2f, + 0x60, 0x0a, 0xf0, 0x02, 0x1e, 0x00, 0xaf, 0x80, + 0xa1, 0xc0, 0x0a, 0xf8, 0x8a, 0x1d, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, + 0xbf, 0x00, 0x23, 0x40, 0x0b, 0x48, 0x02, 0x18, + 0x00, 0x8f, 0x80, 0x25, 0xc2, 0x4b, 0x70, 0x02, + 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0x08, 0x16, 0x00, 0xc7, 0x82, 0x7d, 0xa0, 0x0d, + 0x78, 0x07, 0xde, 0x00, 0xf6, 0xed, 0x09, 0x00, + 0x1f, 0x02, 0x80, 0x3d, 0x20, 0x0f, 0x48, 0x03, + 0xd2, 0x04, 0xc6, 0x80, 0x7d, 0x20, 0x0c, 0x48, + 0x13, 0x52, 0x01, 0xc4, 0x80, 0x31, 0x20, 0x0c, + 0x78, 0x03, 0x12, 0x00, 0xf7, 0x80, 0x3d, 0xe0, + 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x31, + 0xe0, 0x0d, 0x48, 0x03, 0x3a, 0x02, 0xc7, 0x80, + 0xbd, 0x20, 0x0f, 0x78, 0x03, 0xea, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0xa0, 0x00, + 0xfb, 0x00, 0x7c, 0x00, 0x0e, 0xb0, 0x03, 0xec, + 0x00, 0xfa, 0x00, 0x3e, 0x40, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfa, 0x00, 0x2c, 0x40, 0x0f, 0x30, + 0x03, 0xec, 0x04, 0xf3, 0x00, 0x1c, 0xc0, 0x0f, + 0x10, 0x03, 0xe8, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf3, 0x00, 0x3c, + 0x40, 0x0e, 0xa0, 0x03, 0xec, 0x00, 0xf3, 0x01, + 0x3a, 0x00, 0x0f, 0xb0, 0x03, 0x42, 0x06, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, + 0xff, 0x84, 0x3f, 0x60, 0x0c, 0xf8, 0x03, 0xfe, + 0x00, 0xfe, 0x80, 0x3f, 0x20, 0x0f, 0x48, 0x03, + 0x12, 0x00, 0xce, 0x80, 0x3b, 0x20, 0x0e, 0xc8, + 0x03, 0xf2, 0x00, 0xfc, 0x80, 0x3f, 0x24, 0x0f, + 0x78, 0x23, 0x1e, 0x00, 0xcf, 0x80, 0x3f, 0xe0, + 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x39, + 0xe0, 0x0d, 0x48, 0x03, 0x3e, 0x00, 0xc7, 0x80, + 0x31, 0xe4, 0x0c, 0xf8, 0x03, 0xc0, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x11, 0x98, 0x20, + 0xb7, 0x00, 0x2d, 0x44, 0x0d, 0x70, 0x02, 0xdc, + 0x00, 0xb6, 0x00, 0x2d, 0x40, 0x0b, 0x70, 0x12, + 0x1c, 0x00, 0x86, 0x00, 0x21, 0x40, 0x08, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x20, 0x2d, 0xcc, 0x0b, + 0x70, 0x03, 0x5c, 0x40, 0x87, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x01, 0xb7, 0x00, 0x35, + 0xed, 0x09, 0x00, 0x20, 0x02, 0x40, 0x0d, 0x70, + 0x02, 0x10, 0x00, 0x87, 0x00, 0x21, 0xc0, 0x08, + 0x70, 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x94, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb6, 0x00, + 0x2d, 0x10, 0x0b, 0x40, 0x02, 0x12, 0x00, 0x86, + 0x00, 0x29, 0x00, 0x0a, 0x40, 0x02, 0xd0, 0x00, + 0xb4, 0x09, 0x2d, 0x20, 0x1b, 0x60, 0x02, 0x3c, + 0x00, 0x87, 0x08, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xdc, 0x00, 0xb7, 0x08, 0x2b, 0xc0, 0x08, 0xe0, + 0x82, 0x10, 0x20, 0x8f, 0x00, 0x21, 0x00, 0x08, + 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x14, 0xc0, 0x08, 0xb3, 0x80, 0x2c, + 0x58, 0x89, 0x30, 0x02, 0xcc, 0x00, 0xb2, 0x00, + 0x2c, 0x60, 0x0b, 0x30, 0x22, 0x0c, 0x08, 0x82, + 0x50, 0x20, 0x68, 0x88, 0x30, 0x02, 0xcd, 0x88, + 0xb3, 0xe0, 0x2c, 0xe0, 0x0b, 0x38, 0x82, 0x46, + 0x72, 0x82, 0xc0, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x24, 0x78, 0x09, 0x3c, + 0x22, 0x0d, 0x20, 0x83, 0x08, 0x20, 0x24, 0x08, + 0x30, 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0x15, 0x80, 0x00, 0xfb, 0xa2, 0x3e, + 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfa, 0x00, + 0x3c, 0x10, 0x0f, 0x80, 0x03, 0x21, 0x42, 0xca, + 0x10, 0x38, 0x30, 0x0e, 0x00, 0x03, 0xc0, 0x00, + 0xf8, 0x80, 0x3e, 0x16, 0x0f, 0xb2, 0x03, 0x2e, + 0x01, 0xcb, 0x80, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0xd0, 0x3a, 0xa0, 0x0c, 0xad, + 0x0b, 0x28, 0x00, 0xcb, 0x00, 0xb2, 0x80, 0x2c, + 0xb0, 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0xe4, 0x90, 0xfb, 0x00, 0x3e, + 0x50, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfa, 0x00, + 0x3e, 0x44, 0x0f, 0xed, 0x09, 0x00, 0x21, 0x02, + 0xb0, 0x03, 0xec, 0x00, 0xfa, 0x00, 0x3e, 0x44, + 0x8f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xa0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xd4, 0x0f, 0xb4, 0x03, 0xec, 0x00, + 0xfb, 0x04, 0x3e, 0xd0, 0x0f, 0xb0, 0x03, 0xe0, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, + 0xf2, 0x80, 0xcf, 0x00, 0x33, 0xe4, 0x0c, 0xf0, + 0x03, 0xfc, 0x00, 0xfe, 0x00, 0x3f, 0x00, 0x0c, + 0xc0, 0x03, 0x30, 0x00, 0xfe, 0x00, 0x33, 0x00, + 0x0d, 0xc0, 0x03, 0x30, 0x00, 0xcc, 0x00, 0x3f, + 0x00, 0x0c, 0xf8, 0x03, 0xf4, 0x00, 0xfd, 0x18, + 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xf3, + 0x00, 0x33, 0x80, 0x4c, 0xe8, 0x03, 0xec, 0x00, + 0xbf, 0xa2, 0x33, 0x22, 0xac, 0xf0, 0x03, 0xc0, + 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, + 0x63, 0x00, 0x83, 0x02, 0x20, 0x50, 0x08, 0xb0, + 0x02, 0xec, 0x00, 0xba, 0x00, 0x2e, 0x40, 0x28, + 0x30, 0x02, 0x2c, 0x10, 0xb2, 0x00, 0x2a, 0x40, + 0x08, 0xb0, 0x02, 0xac, 0x00, 0x8b, 0x00, 0x24, + 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x04, 0xb3, 0x80, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x20, 0xc0, 0x4a, 0x96, 0x02, 0xeb, 0x04, + 0xb3, 0x48, 0x34, 0x08, 0x08, 0xb0, 0x02, 0xe0, + 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, + 0x21, 0x00, 0x0b, 0x00, 0x22, 0x40, 0x00, 0xb0, + 0x02, 0xec, 0x00, 0xba, 0x00, 0x2e, 0x00, 0x08, + 0x80, 0x02, 0x20, 0x00, 0xba, 0x00, 0x22, 0x00, + 0x09, 0x80, 0x12, 0x20, 0x00, 0xa8, 0x00, 0x2e, + 0x00, 0x08, 0x96, 0x12, 0xec, 0x20, 0xbb, 0x00, + 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x22, 0x94, 0x18, 0xb1, 0x02, 0xed, 0x09, + 0x00, 0x22, 0x02, 0xe3, 0x00, 0xbb, 0x00, 0xa2, + 0xc8, 0x08, 0xb0, 0x02, 0xe0, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x8b, + 0x00, 0x20, 0x40, 0x88, 0x30, 0x02, 0xcc, 0x00, + 0xb2, 0x00, 0x2e, 0x40, 0x08, 0x30, 0x02, 0x0c, + 0x00, 0xba, 0x00, 0x28, 0x40, 0x08, 0x30, 0x02, + 0xac, 0x02, 0xa3, 0x00, 0x24, 0xc0, 0x48, 0x30, + 0x00, 0xcc, 0x00, 0xbb, 0x00, 0x20, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc0, + 0x0a, 0x10, 0x02, 0xcc, 0x10, 0xb2, 0x00, 0x26, + 0x40, 0x08, 0x30, 0x02, 0xc2, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x60, 0x00, 0xcb, + 0x00, 0x32, 0x40, 0x2c, 0xb0, 0x03, 0xec, 0x00, + 0xfa, 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0x20, + 0x00, 0xfa, 0x00, 0x32, 0x00, 0x0d, 0x80, 0x03, + 0x20, 0x00, 0xe8, 0x00, 0x3e, 0x00, 0x0c, 0xb0, + 0x03, 0xe8, 0x00, 0xfb, 0x00, 0xb2, 0xc0, 0x0f, + 0xb0, 0x02, 0xec, 0x00, 0xfb, 0x00, 0x32, 0x80, + 0x0c, 0x90, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32, + 0x00, 0x0c, 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x1d, 0xf0, 0x00, 0xff, + 0x00, 0x3d, 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xfe, 0x00, 0x3f, 0x40, 0x0f, 0xf0, 0x23, 0xfc, + 0x00, 0xf6, 0x00, 0x3d, 0x40, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0xc0, 0x2f, 0xc0, + 0x03, 0xf0, 0x10, 0xfe, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, + 0x0f, 0xd0, 0x03, 0xf0, 0x00, 0xfe, 0x00, 0x3b, + 0x00, 0x0f, 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x0d, 0xdc, 0x00, 0xcc, + 0x00, 0x33, 0xc0, 0x0c, 0x40, 0x03, 0x30, 0x00, + 0xff, 0x00, 0x33, 0xc8, 0x0c, 0xf2, 0x43, 0xfd, + 0x00, 0xed, 0x09, 0x00, 0x23, 0x02, 0xcf, 0x00, + 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xbc, 0x00, 0xcf, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x20, + 0xff, 0x02, 0x2b, 0xc0, 0x1c, 0xf3, 0x03, 0x7c, + 0x00, 0xff, 0x28, 0x27, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, + 0x03, 0xf0, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0xec, 0x00, 0x8a, 0x04, 0x23, 0xd1, + 0x08, 0x80, 0x02, 0x20, 0x00, 0xbf, 0x40, 0x23, + 0xd2, 0x08, 0xf5, 0x02, 0xdc, 0x40, 0x83, 0x08, + 0x2e, 0xc0, 0x8b, 0x75, 0x02, 0x0c, 0x80, 0x8b, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x22, 0xfd, 0x00, + 0xbf, 0x08, 0x23, 0xd0, 0x0b, 0xf3, 0x22, 0x3c, + 0x00, 0xbf, 0x40, 0x2a, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0x9b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x05, 0x4c, 0x00, 0x80, 0x00, 0x68, 0xc4, + 0x08, 0x00, 0x02, 0x80, 0x01, 0x93, 0x68, 0x28, + 0xd8, 0x08, 0x30, 0x02, 0xcc, 0x80, 0x83, 0x04, + 0x2c, 0xc0, 0x0b, 0x30, 0x82, 0x0c, 0x20, 0x83, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x62, 0x4c, 0x00, + 0x93, 0x20, 0x2c, 0xd0, 0x0b, 0x32, 0x42, 0x4c, + 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x09, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xea, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x11, 0xac, 0x00, 0x89, 0x40, 0x62, 0xc1, + 0x08, 0xb4, 0x02, 0x2c, 0x04, 0xbb, 0x04, 0x22, + 0xc0, 0x28, 0xb0, 0x62, 0xec, 0x00, 0x2b, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x10, 0x8b, + 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x22, 0xec, 0x00, + 0xbb, 0x00, 0x26, 0xc0, 0x0b, 0xb0, 0x50, 0x6c, + 0x00, 0xbb, 0x00, 0x06, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0xed, 0x09, 0x00, 0x24, + 0x02, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x78, 0x04, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xac, + 0x00, 0xcb, 0x40, 0x3a, 0xc0, 0x0c, 0x98, 0x13, + 0xae, 0x00, 0xfb, 0x00, 0xba, 0xc0, 0x0c, 0xb0, + 0x40, 0xec, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x12, 0x2c, 0x10, 0xcb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0x6c, 0x10, 0xbb, 0x00, 0x3e, + 0xc1, 0x4f, 0xb0, 0x23, 0x6c, 0x00, 0xbb, 0x00, + 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xbb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x44, + 0x70, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x3c, + 0x00, 0xff, 0xc0, 0xbf, 0xc0, 0x2f, 0xf2, 0x03, + 0xfe, 0x80, 0xff, 0x00, 0x3e, 0xc1, 0x0f, 0xb0, + 0x03, 0xdc, 0x02, 0xdf, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x01, 0x3f, 0xc0, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xf7, 0x01, 0x3b, + 0xc0, 0x8f, 0xf0, 0x43, 0xbc, 0x10, 0xf7, 0x00, + 0x3b, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xdf, + 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x43, 0xf8, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, + 0x80, 0xc9, 0x40, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0x2c, 0x00, 0xc3, 0x00, 0xf8, 0xc0, 0x0e, 0xb8, + 0x83, 0x2c, 0x10, 0xeb, 0x00, 0x32, 0xc0, 0x0f, + 0xb0, 0x03, 0xac, 0x00, 0xcb, 0x00, 0x3e, 0xc0, + 0x0b, 0xb0, 0x03, 0xec, 0x00, 0xcb, 0x00, 0x3a, + 0xc0, 0x1f, 0xb0, 0x03, 0x6c, 0x00, 0xeb, 0x00, + 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x50, 0x04, + 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x04, 0x0c, + 0x00, 0x82, 0x88, 0x2d, 0xc0, 0x0b, 0x24, 0x02, + 0x2c, 0x40, 0xdf, 0x00, 0x63, 0xc0, 0x48, 0xf0, + 0x02, 0x3c, 0x08, 0x8b, 0x00, 0x22, 0xc0, 0xed, + 0x09, 0x00, 0x25, 0x02, 0x4b, 0xf0, 0x03, 0x2c, + 0x00, 0xdb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xfc, 0x40, 0x8f, 0x00, 0x23, 0xf8, 0x9f, 0xf0, + 0x02, 0xfc, 0x00, 0x8f, 0x00, 0x2a, 0xc0, 0x0b, + 0xb0, 0x02, 0xec, 0x00, 0xeb, 0x00, 0x2e, 0xc0, + 0x0b, 0xb0, 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0xe2, 0x05, 0x4c, 0x00, 0x82, 0x80, + 0x2c, 0xc0, 0x0b, 0x0b, 0x02, 0x03, 0x40, 0xb3, + 0x00, 0x20, 0xc0, 0x0a, 0x30, 0x32, 0x8c, 0x00, + 0xa3, 0x00, 0x20, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, + 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0x8e, 0x00, 0x83, 0x00, 0x2c, 0xe2, 0x1b, 0xb0, + 0x22, 0x4c, 0x00, 0xa3, 0x00, 0x28, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0x93, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x62, 0x01, 0x1e, 0x20, 0x84, 0x80, + 0x6d, 0xe0, 0x0b, 0x78, 0x02, 0x36, 0x00, 0xb7, + 0x80, 0x21, 0xe0, 0x0a, 0x7b, 0x40, 0x9e, 0x01, + 0xa7, 0x80, 0x21, 0xe0, 0x03, 0x78, 0x02, 0x5e, + 0x00, 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, + 0xde, 0x00, 0x83, 0x80, 0x05, 0xe0, 0x0a, 0x78, + 0x02, 0xce, 0x00, 0xa3, 0x80, 0x29, 0xe0, 0x0b, + 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0b, 0x78, 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x0c, 0x00, 0xc3, 0x00, + 0x3c, 0xc0, 0x0f, 0x20, 0x0b, 0x09, 0x00, 0xfb, + 0x00, 0x00, 0xc0, 0x0a, 0x32, 0x03, 0x8c, 0x04, + 0xe3, 0x00, 0x90, 0xc4, 0x0f, 0x31, 0x03, 0x8c, + 0x00, 0x83, 0x00, 0x3c, 0xc4, 0x0f, 0x31, 0x03, + 0x8c, 0x60, 0x43, 0x11, 0x3c, 0xc1, 0x0b, 0x31, + 0x03, 0x4c, 0x80, 0xe3, 0x00, 0x10, 0xc0, 0x0f, + 0x30, 0x03, 0xcc, 0x00, 0xd3, 0x00, 0x3c, 0xc0, + 0x0f, 0x30, 0xed, 0x09, 0x00, 0x26, 0x02, 0x03, + 0x52, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x15, 0xac, 0x00, 0xfa, 0x00, 0x3e, 0xc6, 0x0f, + 0xa0, 0x03, 0xc0, 0x00, 0xdb, 0x00, 0x3e, 0xd0, + 0x0d, 0xb2, 0x93, 0x6d, 0x40, 0xdb, 0x00, 0x3e, + 0xc1, 0x0f, 0xb4, 0x43, 0xac, 0x00, 0xfb, 0x10, + 0x3e, 0xc4, 0x0f, 0xb0, 0x03, 0xcc, 0x30, 0xfb, + 0x40, 0x3a, 0xc4, 0x07, 0xb1, 0x03, 0xec, 0x00, + 0xdb, 0x18, 0x16, 0xc4, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xeb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x88, + 0x0d, 0xce, 0x00, 0xc1, 0x04, 0x30, 0xe0, 0x08, + 0xb0, 0x01, 0xee, 0x00, 0x5b, 0x50, 0x3e, 0xc1, + 0x0b, 0xb6, 0x03, 0x2c, 0x00, 0x4b, 0x00, 0x3e, + 0xc0, 0x8f, 0xb2, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0b, 0xb0, 0x03, 0xec, 0x90, 0x5b, + 0x30, 0x3a, 0xe0, 0x0c, 0xb2, 0x03, 0xee, 0x80, + 0xfb, 0x80, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xc2, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x01, 0x9c, 0x00, 0x85, 0x00, 0x21, 0xca, 0x08, + 0x60, 0x02, 0xdc, 0x00, 0xa7, 0x28, 0x2d, 0xc8, + 0x0b, 0x73, 0x02, 0x8c, 0x80, 0x87, 0x00, 0x2d, + 0xc0, 0x0b, 0x74, 0x00, 0xdc, 0x00, 0xf7, 0x00, + 0x39, 0xc0, 0x0b, 0x70, 0x12, 0x5c, 0x40, 0x97, + 0x00, 0x2d, 0xd4, 0xa0, 0x77, 0x02, 0xdd, 0x40, + 0xbf, 0x28, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0x97, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0xd2, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0xe1, + 0x00, 0x9e, 0x02, 0x8e, 0x88, 0xa1, 0xe8, 0x08, + 0x78, 0x02, 0xde, 0x00, 0x97, 0x80, 0x2d, 0xec, + 0x0b, 0x7a, 0x12, 0x1e, 0xc0, 0x87, 0x80, 0x2d, + 0xe0, 0x0b, 0x78, 0x02, 0xde, 0xed, 0x09, 0x00, + 0x27, 0x02, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, + 0x78, 0x12, 0xde, 0x10, 0xb7, 0xa0, 0x28, 0xe0, + 0x08, 0x7a, 0x02, 0xdc, 0x80, 0xb7, 0x00, 0x29, + 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xc0, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, 0x00, + 0x81, 0x00, 0x20, 0xc0, 0x48, 0x18, 0x02, 0xcc, + 0x40, 0xa3, 0x00, 0x2e, 0xc0, 0x0b, 0x30, 0x02, + 0xac, 0x00, 0x8b, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x0b, + 0x30, 0x00, 0xcc, 0x08, 0x93, 0x04, 0x2c, 0xc0, + 0x08, 0x30, 0x02, 0xcc, 0x00, 0x93, 0x00, 0x20, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xd2, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0xa8, 0x00, + 0xc6, 0x40, 0x32, 0x80, 0x2c, 0x64, 0x23, 0xfb, + 0x00, 0xda, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x02, + 0x28, 0x02, 0x8a, 0x00, 0x3e, 0x80, 0x0f, 0xa0, + 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, + 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x02, 0x1a, 0x80, + 0x08, 0xa0, 0x03, 0xe8, 0x00, 0xba, 0x00, 0x3a, + 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, + 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xf8, 0x04, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xe1, 0x00, + 0xf8, 0x83, 0x3e, 0x01, 0x0f, 0x89, 0x03, 0xe3, + 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x00, 0x43, + 0xe0, 0x02, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x00, + 0x03, 0xe0, 0x00, 0xe8, 0x00, 0x2e, 0x00, 0x0f, + 0x80, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00, + 0x4f, 0x00, 0x03, 0xe0, 0x01, 0xf8, 0x00, 0x3e, + 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xd8, 0x00, + 0x3e, 0x00, 0x0d, 0x80, 0x03, 0xd2, 0x00, 0x30, + 0xed, 0x09, 0x00, 0x28, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x10, 0xe7, 0x00, 0xf9, 0x00, 0xb2, + 0x60, 0x0f, 0x92, 0x03, 0x26, 0x00, 0xf9, 0x00, + 0x32, 0x40, 0x0f, 0x94, 0x12, 0x24, 0x00, 0xf9, + 0x00, 0x32, 0x40, 0x0d, 0x90, 0x03, 0xa4, 0x01, + 0xf9, 0x01, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xc9, 0x00, 0x3e, 0x40, 0x8f, 0x90, 0x42, + 0x04, 0x04, 0xc9, 0x01, 0x32, 0x41, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x04, 0x66, 0x00, 0xb9, 0x00, 0x22, + 0x64, 0x0b, 0x94, 0x82, 0x25, 0x60, 0xb9, 0x00, + 0x22, 0x40, 0x88, 0x98, 0x02, 0x24, 0x00, 0x89, + 0x00, 0x22, 0x40, 0x0b, 0x90, 0x42, 0x24, 0x00, + 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x12, 0xc7, + 0x40, 0xc9, 0x00, 0x2e, 0x41, 0x0e, 0x90, 0x42, + 0x24, 0x00, 0x89, 0x00, 0x22, 0x40, 0x0b, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x04, 0x24, 0x00, 0xb9, 0x20, 0x22, + 0x41, 0x43, 0x90, 0x02, 0x64, 0x00, 0xb1, 0x00, + 0x22, 0x40, 0x0b, 0x90, 0x0a, 0xa4, 0x04, 0xb9, + 0x00, 0x22, 0x40, 0x0b, 0x90, 0x02, 0xa4, 0x08, + 0xb9, 0x06, 0x26, 0x40, 0x0a, 0x90, 0x02, 0xe4, + 0x00, 0x89, 0x00, 0x2e, 0x4a, 0x0b, 0x90, 0x02, + 0xa4, 0x00, 0x81, 0x00, 0x22, 0x40, 0x0b, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb9, 0x00, 0x20, + 0x40, 0x0b, 0x90, 0x0a, 0x44, 0x00, 0xb1, 0x40, + 0xa0, 0x4a, 0x08, 0x30, 0x02, 0x84, 0x00, 0x81, + 0x40, 0xa0, 0x40, 0x0b, 0x16, 0x82, 0x05, 0x00, + 0xb1, 0x00, 0x2c, 0xed, 0x09, 0x00, 0x29, 0x02, + 0x40, 0x4b, 0x10, 0x02, 0xcc, 0x04, 0x91, 0x40, + 0x2c, 0x40, 0x4b, 0x14, 0x0a, 0x84, 0x00, 0x81, + 0x40, 0x20, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, + 0x60, 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0f, 0x80, + 0x03, 0x60, 0x10, 0xf8, 0x00, 0x32, 0x08, 0x0f, + 0x80, 0x03, 0xa0, 0x02, 0xf8, 0x00, 0x32, 0x00, + 0x0b, 0x82, 0x23, 0xa0, 0x00, 0xb8, 0x00, 0x36, + 0x00, 0xcf, 0x80, 0x07, 0xe0, 0x02, 0xc8, 0x02, + 0x7e, 0x00, 0x0f, 0x80, 0x03, 0x20, 0x00, 0xc8, + 0x00, 0x32, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xfe, + 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x98, 0x14, + 0xe4, 0x00, 0xfd, 0x00, 0x2e, 0x50, 0x0f, 0xd0, + 0x03, 0x94, 0x00, 0xb9, 0x40, 0x3e, 0x4a, 0x0f, + 0x14, 0x07, 0x65, 0xa0, 0xf9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x0b, 0xe4, 0x04, 0x79, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe5, 0x00, 0xe9, 0x41, + 0x1e, 0x50, 0x8e, 0x94, 0x03, 0x65, 0x00, 0xf9, + 0x40, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe6, + 0x26, 0x70, 0x00, 0x00, 0x00, 0x00, 0x98, 0x05, + 0xf4, 0x00, 0xfd, 0x00, 0x3f, 0x40, 0x1c, 0x50, + 0x03, 0x14, 0x00, 0xd9, 0x22, 0x32, 0x44, 0x0e, + 0xd2, 0x03, 0xa4, 0x10, 0xd9, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x08, 0xf9, 0x00, 0x36, + 0x40, 0x5b, 0x90, 0x23, 0xf4, 0x18, 0xf9, 0x20, + 0x3d, 0x4a, 0x0c, 0x93, 0x03, 0x64, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xc6, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x2a, 0x02, 0x39, 0x10, 0xe0, 0x00, 0xba, + 0x00, 0x2e, 0x10, 0x08, 0x80, 0x02, 0x28, 0x00, + 0x88, 0x29, 0x22, 0x14, 0x0a, 0x81, 0x02, 0xe1, + 0x80, 0x88, 0x08, 0x2e, 0x00, 0x0b, 0x82, 0x82, + 0xe0, 0x80, 0x98, 0x00, 0x2e, 0x00, 0x0b, 0x80, + 0x22, 0xe0, 0x40, 0x98, 0x28, 0x2e, 0x00, 0x08, + 0x83, 0x22, 0x21, 0x08, 0xb8, 0x08, 0x2e, 0x00, + 0x0b, 0x80, 0x02, 0x60, 0x00, 0xb8, 0x00, 0x2e, + 0x00, 0x0b, 0x80, 0x02, 0xce, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0xc4, 0x00, 0x31, + 0x00, 0x2c, 0x44, 0x08, 0x18, 0x12, 0x24, 0x00, + 0x91, 0x30, 0x20, 0x49, 0x0a, 0x10, 0x02, 0x84, + 0x61, 0x81, 0x00, 0x2c, 0x40, 0x0b, 0x16, 0x02, + 0x44, 0xa0, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, + 0x02, 0xc4, 0x00, 0xb1, 0x30, 0x0c, 0x40, 0x09, + 0x12, 0x22, 0x44, 0x40, 0xb1, 0x10, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, + 0x40, 0x0b, 0x10, 0x02, 0xd2, 0x01, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x28, 0x91, 0x02, 0x24, 0x40, + 0xa9, 0x02, 0x22, 0x40, 0x08, 0xb0, 0x42, 0xc4, + 0x00, 0x89, 0x00, 0x2e, 0x41, 0x0b, 0x90, 0x02, + 0xe4, 0x00, 0xb9, 0x02, 0x2e, 0x40, 0x0b, 0x90, + 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x10, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0x64, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xe6, 0x04, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x94, 0xe4, 0x00, 0xf9, + 0xc0, 0x3e, 0x40, 0x08, 0x14, 0x0b, 0x26, 0x10, + 0xd9, 0x00, 0xb2, 0x40, 0x0e, 0x90, 0x01, 0xa4, + 0x00, 0xc9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0x64, 0x00, 0xf9, 0x00, 0x36, 0x40, 0x0b, 0x90, + 0x03, 0xed, 0x09, 0x00, 0x2b, 0x02, 0xe4, 0x08, + 0xf9, 0x00, 0x2e, 0x40, 0x0d, 0x90, 0x03, 0x64, + 0x10, 0xb9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0xa4, 0x00, 0xf9, 0x40, 0x3e, 0x40, + 0x0f, 0x98, 0x03, 0xe6, 0x00, 0xd1, 0x00, 0x7e, + 0x40, 0x0f, 0x90, 0x43, 0xe4, 0x02, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x43, 0xe4, 0x00, 0xd9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xd9, 0x00, 0x3e, 0x40, 0x3c, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xda, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x10, 0xa0, 0x80, 0xf8, 0x00, 0x30, 0x00, + 0x0c, 0x88, 0x53, 0x23, 0x00, 0xc8, 0x00, 0x3e, + 0x00, 0x07, 0x88, 0x03, 0xe0, 0x00, 0xd8, 0x00, + 0x36, 0x00, 0x8f, 0x80, 0x03, 0xa0, 0x00, 0xf8, + 0x04, 0x1e, 0x00, 0x4f, 0x80, 0x03, 0xe0, 0x20, + 0xd8, 0x02, 0x1e, 0x08, 0x0c, 0x80, 0x03, 0xe0, + 0x00, 0xf8, 0x04, 0x0e, 0x00, 0x0f, 0x80, 0x03, + 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x04, 0x3b, 0x00, 0xba, 0x88, 0x22, 0x82, + 0x2a, 0xec, 0x82, 0x1b, 0x00, 0x0a, 0x00, 0x2e, + 0x80, 0x0b, 0xec, 0x02, 0xe8, 0x00, 0xca, 0x00, + 0x2e, 0x80, 0x0b, 0xa0, 0x03, 0x68, 0x00, 0xba, + 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xfb, 0x00, + 0xba, 0x00, 0x2d, 0x80, 0x0d, 0xa0, 0x02, 0xe8, + 0x00, 0xea, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, + 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, + 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x05, 0x40, 0x00, 0xed, 0x09, 0x00, 0x2c, + 0x02, 0xb1, 0x00, 0xa0, 0xe0, 0x08, 0x38, 0x02, + 0x0c, 0x00, 0x83, 0x00, 0x2e, 0xc0, 0x0b, 0x38, + 0x02, 0xcc, 0x04, 0x83, 0x00, 0x04, 0xc0, 0x0b, + 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x24, 0xc0, + 0x83, 0x30, 0x02, 0xc3, 0x0c, 0x93, 0x00, 0x0c, + 0x70, 0x09, 0x30, 0x42, 0xcc, 0x00, 0xa3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xca, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x1d, + 0x00, 0xb5, 0x80, 0x21, 0xc0, 0x08, 0x40, 0x02, + 0x1c, 0x20, 0x87, 0x24, 0x25, 0xc8, 0x0b, 0x74, + 0x02, 0xdc, 0x40, 0x87, 0x20, 0x2d, 0xc0, 0x0b, + 0x3a, 0x02, 0x5c, 0x80, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x30, 0xb7, 0x00, 0x6d, + 0x90, 0x29, 0x72, 0x02, 0xdc, 0x08, 0xa7, 0x20, + 0x25, 0xc0, 0x0b, 0x70, 0x06, 0xdc, 0x00, 0xb7, + 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xe8, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x1e, + 0x00, 0xf7, 0x80, 0x30, 0x60, 0x08, 0x48, 0x0b, + 0x16, 0x02, 0xc7, 0xd0, 0x2d, 0xf0, 0x0f, 0x78, + 0x23, 0xfe, 0x80, 0xc7, 0x80, 0x35, 0xe0, 0x0f, + 0x7f, 0x0b, 0x9e, 0x00, 0xb7, 0x80, 0x3d, 0xe0, + 0x0b, 0x78, 0x03, 0xde, 0x00, 0xd7, 0xa0, 0x1d, + 0xa0, 0x4d, 0x7e, 0x03, 0xde, 0x00, 0xe7, 0x80, + 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, + 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xea, 0x22, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, 0xa0, + 0x00, 0xf1, 0x00, 0x3e, 0x40, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xed, 0x02, 0xeb, 0x60, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0xe0, 0xfb, 0x00, 0x2e, 0xc0, + 0x0f, 0xb0, 0x42, 0xec, 0x10, 0xfb, 0x4a, 0xed, + 0x09, 0x00, 0x2d, 0x02, 0x3e, 0x80, 0x0e, 0xb2, + 0x03, 0xec, 0x04, 0xeb, 0x76, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x05, 0xf2, 0x00, 0xfd, 0x90, + 0x03, 0x61, 0x0f, 0xc8, 0x03, 0xda, 0x00, 0xcf, + 0x80, 0x3f, 0xe0, 0x0d, 0xe8, 0x07, 0xfd, 0x40, + 0xff, 0xc8, 0x3f, 0xe0, 0x0f, 0xf8, 0x43, 0xfe, + 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, + 0xfe, 0x00, 0xef, 0x88, 0x23, 0xa8, 0x0f, 0xfc, + 0x23, 0xfe, 0x00, 0xff, 0xd0, 0x3f, 0xe4, 0x0f, + 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, + 0x0f, 0xf8, 0x03, 0xc0, 0x80, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0x11, 0x91, 0x00, 0xb5, 0x30, + 0x21, 0x48, 0x08, 0x70, 0x02, 0xd8, 0x00, 0xa7, + 0x00, 0x25, 0xc0, 0x08, 0x70, 0x27, 0x9c, 0x80, + 0x37, 0x00, 0x2d, 0xc0, 0x09, 0x70, 0x03, 0xdc, + 0x00, 0xb7, 0x00, 0x0d, 0xc0, 0x0b, 0x70, 0x02, + 0xdd, 0x00, 0x07, 0x00, 0x21, 0xc0, 0x0f, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x70, 0x12, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0x6a, 0x84, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x92, 0x00, 0x90, 0x00, 0xbd, 0x01, + 0xa1, 0xc1, 0x0a, 0x70, 0x02, 0xf4, 0x20, 0x87, + 0x10, 0x2c, 0xc0, 0x09, 0x60, 0x02, 0x9c, 0x40, + 0xb7, 0x00, 0x2d, 0xc0, 0x09, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, + 0x50, 0x40, 0x87, 0x00, 0x21, 0x08, 0x0b, 0x71, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x0d, 0xc1, 0x09, + 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x62, 0x14, 0xc0, 0x00, 0xb1, 0x80, + 0x20, 0xc0, 0xed, 0x09, 0x00, 0x2e, 0x02, 0x48, + 0x08, 0x12, 0xc2, 0x00, 0xa3, 0x00, 0x0c, 0xc0, + 0x08, 0x20, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x89, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, + 0x0c, 0xc0, 0x03, 0x30, 0x00, 0xcc, 0x04, 0x8b, + 0x01, 0x28, 0x80, 0x4b, 0x30, 0x02, 0xcc, 0x10, + 0xb3, 0x00, 0x2c, 0xc0, 0x09, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0xaa, + 0x15, 0xa0, 0x00, 0xf9, 0xc0, 0xb0, 0x40, 0x0a, + 0xa8, 0x03, 0xef, 0x50, 0xcf, 0x06, 0x3f, 0xc0, + 0x05, 0x90, 0x03, 0xbc, 0x00, 0x7f, 0x00, 0x3e, + 0xc0, 0x0d, 0xf0, 0x02, 0xfc, 0x00, 0xfb, 0x00, + 0x7e, 0xc0, 0x0f, 0xb0, 0x03, 0x6c, 0x02, 0x6f, + 0x04, 0x92, 0x80, 0x0f, 0xf0, 0x03, 0xec, 0x00, + 0xff, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xea, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x90, + 0x00, 0xe9, 0x08, 0xf9, 0x18, 0x3e, 0x40, 0x2e, + 0x97, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x74, 0xc0, + 0x0f, 0xb4, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x02, + 0x3e, 0xc0, 0x0d, 0xb0, 0x03, 0xc1, 0x00, 0xfb, + 0x01, 0x34, 0x00, 0x5e, 0xb0, 0x03, 0x6c, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x91, + 0x10, 0xf8, 0x00, 0xff, 0x00, 0x3e, 0xc8, 0x0e, + 0xd0, 0x03, 0xfc, 0x02, 0xcf, 0x04, 0x2f, 0xc0, + 0x2c, 0xda, 0x03, 0xbc, 0x10, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x13, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xec, 0x40, 0xcf, + 0x00, 0x33, 0xe1, 0x45, 0x70, 0xed, 0x09, 0x00, + 0x2f, 0x02, 0x13, 0xbc, 0x10, 0xff, 0x00, 0x37, + 0xc0, 0x0f, 0xf0, 0x23, 0x7c, 0x00, 0xff, 0x00, + 0x37, 0xc0, 0x0f, 0xf0, 0x03, 0xc0, 0x44, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x04, 0x61, 0x00, + 0xb9, 0x00, 0x2e, 0xe0, 0x08, 0xa4, 0x82, 0xc7, + 0xc0, 0x8b, 0x00, 0x2e, 0xc0, 0x08, 0x90, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, + 0xb0, 0x02, 0xed, 0x00, 0x8b, 0x00, 0x22, 0xb2, + 0x08, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x03, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x40, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x20, 0x00, + 0xb9, 0x02, 0x2e, 0xc0, 0x08, 0x90, 0x02, 0xec, + 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x01, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xab, 0x00, 0x2e, 0xc0, 0x8b, + 0xb0, 0x06, 0xec, 0x00, 0xab, 0x02, 0x22, 0x88, + 0x0a, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x6e, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x26, 0xc0, 0x0b, 0xb0, 0x02, 0xe0, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, + 0xb1, 0x00, 0x2c, 0xc0, 0x28, 0x20, 0x02, 0xc8, + 0x1c, 0x83, 0x00, 0x2c, 0xc0, 0x08, 0x00, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x30, 0x02, 0xcc, 0x02, 0x83, 0x00, 0x20, 0x80, + 0x4a, 0x30, 0x0a, 0x0c, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x4b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc2, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x60, 0x00, + 0xf9, 0x00, 0x3e, 0x40, 0x0c, 0xa0, 0x13, 0xe0, + 0xed, 0x09, 0x00, 0x30, 0x02, 0x00, 0xcf, 0x00, + 0x3e, 0xc0, 0x0d, 0x80, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3e, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xfb, 0x02, 0x3e, 0xc0, 0x0f, 0xb0, 0x53, 0xec, + 0x08, 0x47, 0x00, 0xb2, 0x80, 0x2f, 0xf0, 0x03, + 0x2c, 0x00, 0xff, 0x00, 0x36, 0xc0, 0x0f, 0xb0, + 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x36, 0xc0, 0x0f, + 0xb0, 0x03, 0xc0, 0x03, 0x50, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1d, 0xf0, 0x04, 0xf5, 0x00, 0x2f, + 0x40, 0x07, 0xd0, 0x03, 0xf0, 0x00, 0xff, 0x04, + 0x3f, 0xc0, 0x0f, 0xc0, 0x02, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x8f, 0xf0, 0x23, 0xfc, 0x00, + 0xff, 0x00, 0x3f, 0xc1, 0x0b, 0xf0, 0x03, 0xf0, + 0x10, 0xff, 0x01, 0x3f, 0x40, 0x8d, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x04, 0x3f, 0xc0, 0x4f, 0xf0, + 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xe0, 0x03, 0xd4, 0x00, 0xf7, + 0x00, 0x3f, 0xc0, 0x0f, 0xe0, 0x03, 0xd4, 0x00, + 0xff, 0x00, 0x3f, 0xc0, 0x0c, 0xf0, 0x03, 0x3c, + 0x04, 0xfc, 0x02, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xfc, 0x00, 0x3f, 0x04, 0x8c, 0xc1, + 0x03, 0x31, 0x00, 0xcc, 0x00, 0x3f, 0xc8, 0x0c, + 0xf0, 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0xa0, 0x02, 0xe0, 0x00, 0xe8, + 0x00, 0x2e, 0x00, 0x0b, 0xa0, 0x02, 0xe0, 0x00, + 0xb8, 0x00, 0x2e, 0x00, 0x8d, 0x80, 0x0a, 0x20, + 0x00, 0xb8, 0x01, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, + 0xec, 0x00, 0x38, 0xed, 0x09, 0x00, 0x31, 0x02, + 0x00, 0x2c, 0x08, 0x08, 0x80, 0x02, 0x20, 0x00, + 0x89, 0x00, 0x2e, 0xc4, 0x8a, 0xb5, 0x02, 0xe0, + 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x88, 0x05, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, + 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x20, 0x02, 0xc4, 0x10, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x20, 0x02, 0xc4, 0x01, 0xb3, 0x00, 0x2c, + 0xc0, 0x08, 0x30, 0x02, 0x8c, 0x00, 0xb1, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x04, 0x30, + 0x28, 0x2c, 0x08, 0x09, 0x12, 0x02, 0x00, 0x84, + 0x90, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xe2, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, + 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x83, + 0xa0, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, + 0x0b, 0xa0, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, + 0x00, 0x09, 0x80, 0x02, 0xa0, 0x00, 0xb9, 0x10, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x04, 0xba, + 0x00, 0x2e, 0x04, 0x09, 0x10, 0x0a, 0x00, 0x00, + 0x99, 0x10, 0x2e, 0xc4, 0x0a, 0xb0, 0x02, 0xf0, + 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, + 0xa0, 0x03, 0xe4, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xa0, 0x03, 0xe4, 0x04, 0xfb, 0x00, 0x3e, + 0xc0, 0x0c, 0x30, 0x03, 0xac, 0x00, 0xf8, 0xc0, + 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf9, + 0xd0, 0x3e, 0x60, 0x2d, 0xa0, 0x0b, 0x29, 0x02, + 0xd8, 0x00, 0x3e, 0x80, 0x2c, 0xb0, 0x03, 0xd0, + 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, + 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, + 0x03, 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0xed, 0x09, + 0x00, 0x32, 0x02, 0xc0, 0x0f, 0xe0, 0x03, 0xf0, + 0x00, 0xec, 0x00, 0x3f, 0x02, 0x0f, 0xe0, 0x03, + 0xf0, 0x00, 0xfc, 0x00, 0x2f, 0x00, 0x0f, 0xc0, + 0x03, 0x70, 0x00, 0xfd, 0x80, 0x3f, 0xc0, 0x0f, + 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x60, + 0x0e, 0xe0, 0x03, 0xf8, 0x00, 0xed, 0x0a, 0x3f, + 0x80, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x10, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xa0, 0x13, 0xe4, + 0x02, 0xcb, 0x00, 0x32, 0xc0, 0xcf, 0xa1, 0x01, + 0xe4, 0x00, 0xdb, 0x10, 0x3a, 0xc8, 0x0c, 0xb0, + 0x03, 0x2c, 0x00, 0xf9, 0x40, 0x02, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xf9, 0x40, 0x3e, 0x60, + 0x2c, 0xb8, 0x03, 0x2b, 0x02, 0xc8, 0x00, 0x30, + 0xc0, 0x0f, 0xb0, 0x03, 0xd0, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0x05, 0x2c, 0x00, 0xbb, + 0x00, 0x2f, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, + 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xa0, 0x02, 0xe1, + 0x40, 0x88, 0xf0, 0x2a, 0x10, 0x0b, 0xa8, 0x02, + 0xe1, 0xc0, 0x88, 0x40, 0x2c, 0x20, 0x08, 0x88, + 0x10, 0x22, 0x20, 0xb9, 0xa0, 0x36, 0xc0, 0x0b, + 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0x60, + 0x88, 0xb8, 0x02, 0x2a, 0x00, 0x89, 0x88, 0x22, + 0xc0, 0x8b, 0xf0, 0x02, 0xf2, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x05, 0x4c, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, + 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x20, 0x02, 0xc5, + 0x00, 0x83, 0x00, 0x20, 0xc0, 0x0b, 0x28, 0x02, + 0xc7, 0x00, 0x93, 0xa0, 0x28, 0xe0, 0x98, 0x3a, + 0x02, 0x0f, 0x28, 0xb0, 0xc8, 0x20, 0xc1, 0x0b, + 0x30, 0x02, 0xcc, 0x00, 0xb0, 0x00, 0x2e, 0x80, + 0x08, 0xed, 0x09, 0x00, 0x33, 0x02, 0x00, 0x12, + 0x04, 0x00, 0x82, 0xc0, 0x20, 0x60, 0x0b, 0x30, + 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, + 0xe0, 0x0b, 0x68, 0x02, 0xf2, 0x00, 0x8c, 0x80, + 0x29, 0x20, 0x8b, 0x68, 0x02, 0xf2, 0x00, 0x94, + 0x80, 0x2f, 0x20, 0x28, 0xc8, 0x8e, 0x12, 0x01, + 0xb5, 0x80, 0x25, 0xe0, 0x0b, 0x78, 0x02, 0xde, + 0x00, 0xb6, 0x80, 0x2d, 0xa0, 0x08, 0x48, 0x02, + 0x16, 0x00, 0x8f, 0x80, 0x21, 0x60, 0x0b, 0x78, + 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, + 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, + 0xc4, 0x0f, 0x20, 0x03, 0xc4, 0x00, 0xc3, 0x00, + 0x30, 0xc2, 0x0f, 0x20, 0x02, 0xc4, 0x00, 0xd3, + 0x00, 0x38, 0xc2, 0x0c, 0x31, 0x03, 0x0c, 0x00, + 0xf3, 0x10, 0x30, 0xc0, 0x0f, 0x30, 0x03, 0xcc, + 0x00, 0xf0, 0x40, 0x3c, 0x80, 0x0c, 0x90, 0x03, + 0x25, 0x00, 0xc2, 0x00, 0x30, 0x42, 0x0f, 0x30, + 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x2f, 0xc4, + 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x01, 0x7f, + 0xc0, 0x0f, 0xe0, 0x03, 0xf0, 0x00, 0xfc, 0x00, + 0x3f, 0x20, 0x0f, 0xe0, 0x03, 0xf0, 0x04, 0xec, + 0x00, 0x3d, 0x00, 0x0f, 0x40, 0x43, 0xf2, 0x00, + 0xf7, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, + 0x40, 0xfe, 0x00, 0x3f, 0x84, 0x0f, 0xd0, 0x0b, + 0xf4, 0x40, 0xf7, 0x00, 0xbf, 0x40, 0x0f, 0xf0, + 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc4, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xa0, 0x03, 0xed, 0x09, 0x00, 0x34, + 0x02, 0xe4, 0x00, 0xf3, 0x00, 0x32, 0xc0, 0x0f, + 0xa0, 0x01, 0xe4, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x23, 0xec, 0x00, 0xb8, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf9, 0x00, + 0x3e, 0xc0, 0x0f, 0xa0, 0x03, 0xac, 0x08, 0xca, + 0x00, 0x32, 0x80, 0x0c, 0xf0, 0x03, 0xea, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x11, 0x9c, + 0x00, 0xb7, 0x00, 0x2d, 0xc8, 0x0b, 0x70, 0x02, + 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x60, + 0x02, 0xd0, 0x00, 0xb4, 0x00, 0x35, 0x00, 0x0b, + 0x60, 0x02, 0xd0, 0x00, 0xb4, 0x00, 0x2d, 0x00, + 0x0b, 0x40, 0x02, 0xd0, 0x00, 0xb5, 0x00, 0x2d, + 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0x36, 0x00, + 0x2d, 0xc0, 0x8b, 0xe0, 0x02, 0x3c, 0x00, 0xc7, + 0x00, 0x29, 0x80, 0x0a, 0x74, 0x02, 0xd2, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x9e, + 0x00, 0xb7, 0x80, 0x2d, 0xe8, 0x0b, 0x78, 0x02, + 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x8b, 0x68, + 0x02, 0xd6, 0x00, 0xbf, 0x80, 0x21, 0xe0, 0x0b, + 0x68, 0x02, 0x56, 0x00, 0xb7, 0x80, 0x2d, 0xe0, + 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x81, 0x2d, + 0xe1, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb5, 0xc0, + 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0x9e, 0x00, 0x96, + 0x80, 0x24, 0xe0, 0x08, 0x7a, 0x02, 0xf0, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x14, 0xcc, + 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, + 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x20, + 0x02, 0xc0, 0x00, 0xb0, 0x00, 0x24, 0x00, 0x0b, + 0x20, 0x02, 0xc0, 0x00, 0xb0, 0x00, 0x2c, 0x00, + 0x0b, 0x00, 0x02, 0xc0, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xbb, 0x40, + 0x2e, 0xc0, 0x0b, 0xb1, 0x02, 0x0c, 0x40, 0xed, + 0x09, 0x00, 0x35, 0x02, 0x83, 0x00, 0x2c, 0xe0, + 0x0a, 0x30, 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xe8, 0x15, 0xa8, 0x00, 0xfa, 0x00, + 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, + 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, + 0xf2, 0x00, 0x32, 0x80, 0x0f, 0x20, 0x03, 0x68, + 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x23, + 0xe8, 0x00, 0xfe, 0x44, 0x5e, 0x80, 0x0f, 0xa0, + 0x03, 0xe8, 0x00, 0xfe, 0x50, 0x3e, 0x90, 0x0f, + 0xa8, 0x03, 0xaa, 0x02, 0xda, 0x00, 0x37, 0xb4, + 0x0c, 0xa0, 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0xe0, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xf0, 0x00, + 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0x84, 0x03, 0xf1, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x87, 0xc4, 0x43, + 0xf0, 0x00, 0xf8, 0xc0, 0x3e, 0x00, 0x0f, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x02, 0x0f, + 0x80, 0x23, 0xe0, 0x02, 0xe8, 0x00, 0x3a, 0x04, + 0x0f, 0x80, 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x8f, 0x90, 0x03, 0xe4, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0x24, 0x00, + 0xc9, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, 0x65, + 0x00, 0xf9, 0x90, 0x3e, 0x40, 0x07, 0x90, 0x03, + 0xe6, 0x80, 0xf9, 0x40, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x08, 0xf9, 0x00, 0x32, 0x40, 0x8d, + 0x90, 0x03, 0x24, 0x00, 0xc9, 0xa0, 0x30, 0x40, + 0x08, 0x10, 0x03, 0x02, 0x04, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, 0x64, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, + 0x00, 0x2e, 0x40, 0x0b, 0x10, 0x02, 0x84, 0x02, + 0x89, 0x00, 0xed, 0x09, 0x00, 0x36, 0x02, 0x2a, + 0x40, 0x8b, 0x96, 0x02, 0x27, 0x00, 0xb9, 0xa0, + 0x2e, 0x64, 0x0b, 0x9c, 0x02, 0xe4, 0x00, 0xb9, + 0x40, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x2a, 0x50, 0x08, 0x94, 0x02, 0x25, + 0x00, 0x81, 0x02, 0x22, 0x40, 0x08, 0x90, 0x03, + 0x60, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, + 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, + 0x0b, 0x90, 0x02, 0x24, 0x00, 0x8d, 0x00, 0x23, + 0x40, 0x0b, 0x90, 0x02, 0x64, 0x00, 0xbd, 0x00, + 0x2f, 0x50, 0x0b, 0xdc, 0x42, 0xf4, 0x04, 0xbb, + 0x08, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x22, 0x40, 0x09, 0xd0, 0x02, 0x14, + 0x00, 0x8d, 0x00, 0x22, 0x40, 0x0a, 0x90, 0x02, + 0x06, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, + 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, + 0x0b, 0x10, 0x02, 0x94, 0x00, 0x85, 0x00, 0x29, + 0x40, 0x0b, 0x90, 0x02, 0x14, 0x00, 0xb5, 0x00, + 0x2d, 0x40, 0x0b, 0x50, 0x02, 0xd4, 0x00, 0xb1, + 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, + 0xb1, 0x40, 0x29, 0x70, 0x08, 0x5c, 0x0a, 0x17, + 0x03, 0x8d, 0x00, 0x60, 0x40, 0x0a, 0x10, 0x02, + 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, + 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, + 0x0f, 0x80, 0x03, 0x20, 0x00, 0xc8, 0x00, 0x33, + 0x00, 0x0f, 0x80, 0x03, 0x68, 0x00, 0xf8, 0x00, + 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xf0, 0x00, 0xf8, + 0x00, 0x1e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, + 0xf8, 0x00, 0x22, 0x00, 0x0d, 0x80, 0x03, 0x20, + 0x00, 0xcc, 0x02, 0x32, 0x00, 0xed, 0x09, 0x00, + 0x37, 0x02, 0x2e, 0x80, 0x03, 0x2e, 0x03, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x98, 0x1d, 0xe4, 0x00, + 0xf9, 0x01, 0x3e, 0x50, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, + 0x90, 0x03, 0xe4, 0x00, 0xfd, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x23, 0xe4, 0x00, 0xff, 0x00, 0x3e, + 0x40, 0x07, 0x90, 0x23, 0xe4, 0x02, 0xf1, 0x00, + 0xbf, 0x50, 0x0d, 0x94, 0x03, 0xe6, 0x06, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x05, 0xe4, 0x00, + 0xf9, 0x00, 0x3e, 0x4a, 0x0f, 0x90, 0x03, 0xe4, + 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x00, 0x3c, 0x40, 0x0e, 0x50, + 0x03, 0xd4, 0x00, 0xf5, 0x00, 0x31, 0x40, 0x0f, + 0xd0, 0x13, 0xf4, 0x08, 0xcd, 0x00, 0x3e, 0x40, + 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf1, 0x00, 0x33, + 0x50, 0x0c, 0xd0, 0x03, 0xf5, 0x00, 0xc5, 0x00, + 0x3f, 0x4a, 0x0c, 0x90, 0x03, 0x06, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0xe0, 0x00, + 0xb8, 0x00, 0x2e, 0x10, 0x8b, 0x80, 0x02, 0xe0, + 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, + 0xe0, 0x00, 0xe8, 0x00, 0x2f, 0x00, 0x08, 0x80, + 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x22, 0x00, 0x8b, + 0x80, 0x02, 0xe0, 0x00, 0x88, 0x00, 0x26, 0x00, + 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2a, + 0x08, 0x09, 0x02, 0x02, 0xe0, 0x00, 0x88, 0x00, + 0x2e, 0x10, 0x08, 0x84, 0x02, 0x8e, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0xc4, 0x00, + 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, + 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, + 0x54, 0x00, 0xb5, 0x00, 0x2d, 0x40, 0x0a, 0x10, + 0xed, 0x09, 0x00, 0x38, 0x02, 0x02, 0xc4, 0x00, + 0xb9, 0x02, 0xa0, 0x40, 0x0b, 0x10, 0x02, 0xe4, + 0x02, 0x91, 0x02, 0x2c, 0x40, 0x0b, 0x10, 0x02, + 0xc4, 0x08, 0xb9, 0x28, 0x20, 0x40, 0x29, 0x10, + 0x82, 0xc4, 0x80, 0x81, 0x03, 0x2c, 0x40, 0x88, + 0x14, 0x02, 0x02, 0x01, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, + 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, + 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xad, + 0x00, 0x2f, 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, + 0xb9, 0x00, 0x02, 0x40, 0x0b, 0x90, 0x02, 0xe4, + 0x00, 0x99, 0x50, 0x2e, 0x40, 0x0b, 0x90, 0x02, + 0xe4, 0x08, 0xb9, 0x00, 0x2a, 0x40, 0x09, 0x94, + 0x02, 0xe4, 0x02, 0x89, 0x00, 0x2e, 0x50, 0x08, + 0x90, 0x02, 0x86, 0x04, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x11, 0xe4, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x13, 0xe4, 0x00, 0xf9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0x64, 0x00, 0xf9, + 0x00, 0x3e, 0x40, 0x0e, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x00, 0x32, 0x40, 0x0f, 0x90, 0x03, 0xc4, + 0x00, 0xd9, 0x80, 0x3e, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0xd0, 0x32, 0x40, 0x0c, 0x90, + 0x03, 0xe4, 0x00, 0xc9, 0x00, 0x3e, 0x40, 0x2c, + 0x90, 0x03, 0x28, 0x04, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, + 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xb9, 0x00, + 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xe9, + 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, + 0xf9, 0x02, 0x3e, 0x40, 0x0f, 0x90, 0x83, 0xe4, + 0x00, 0xe9, 0x80, 0x36, 0x40, 0x0f, 0x90, 0x03, + 0xe4, 0x00, 0xf9, 0x80, 0x3e, 0x40, 0x0e, 0x90, + 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3c, 0x40, 0x0f, + 0x10, 0x03, 0xca, 0xed, 0x09, 0x00, 0x39, 0x02, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, + 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, 0x80, + 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, + 0x80, 0x03, 0xf0, 0x00, 0xcc, 0x00, 0x3f, 0x00, + 0x0c, 0x88, 0x03, 0x22, 0x00, 0xc8, 0x20, 0xb2, + 0x00, 0x8c, 0x81, 0x03, 0xe2, 0x04, 0xf8, 0x80, + 0x02, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, + 0x00, 0x32, 0x08, 0x0f, 0x80, 0x03, 0x20, 0x00, + 0xc8, 0x80, 0x32, 0x00, 0x2c, 0x80, 0x03, 0xca, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0a, 0xa0, + 0x03, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, + 0xa0, 0x02, 0xe8, 0x00, 0x8a, 0x00, 0x2c, 0x80, + 0x0a, 0xe4, 0x07, 0x7b, 0x00, 0xd6, 0x80, 0x23, + 0xa0, 0x08, 0xe8, 0x02, 0x7b, 0x00, 0xbe, 0x40, + 0x36, 0x80, 0x0b, 0xa0, 0x52, 0xe8, 0x00, 0xb2, + 0x00, 0x23, 0xb0, 0x0b, 0xe0, 0x02, 0x38, 0x00, + 0x8e, 0x40, 0x36, 0xa0, 0x08, 0xa0, 0x02, 0xca, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x4c, 0x01, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, + 0x20, 0x02, 0xc0, 0x00, 0x80, 0x00, 0x2c, 0x00, + 0x0a, 0x31, 0x12, 0x0e, 0x00, 0x83, 0xc0, 0x28, + 0x28, 0x08, 0x0c, 0x22, 0xce, 0x00, 0xb3, 0x00, + 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x22, 0xc0, 0x9b, 0x30, 0x02, 0x2c, 0x00, + 0x83, 0x82, 0x20, 0xc0, 0x08, 0x30, 0x02, 0xca, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, + 0x1c, 0x00, 0xb7, 0x00, 0x2c, 0xe0, 0x0a, 0x70, + 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, + 0x60, 0x02, 0xf6, 0x00, 0x87, 0x00, 0x2d, 0xc0, + 0x0a, 0x58, 0x02, 0x5a, 0x20, 0x96, 0xed, 0x09, + 0x00, 0x3a, 0x02, 0x08, 0x2b, 0xf0, 0x28, 0x70, + 0x02, 0xdd, 0x00, 0xbf, 0x80, 0x25, 0xc0, 0x0b, + 0x70, 0x02, 0xdc, 0x00, 0xbf, 0x00, 0x21, 0x50, + 0x0b, 0x58, 0x02, 0x14, 0x02, 0x85, 0x88, 0x24, + 0xc2, 0x08, 0x70, 0x02, 0xe8, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0x08, 0x1e, 0x00, 0xf7, + 0x80, 0x3d, 0xe0, 0x0c, 0x78, 0x03, 0xde, 0x00, + 0xf7, 0x80, 0x2d, 0xe0, 0x0b, 0x68, 0x13, 0xd2, + 0x02, 0xc4, 0x80, 0x3d, 0x20, 0x0e, 0x78, 0x02, + 0x1e, 0x00, 0xc7, 0x82, 0x19, 0xe0, 0x0c, 0x78, + 0x03, 0xde, 0x00, 0xf7, 0x82, 0x31, 0xe0, 0x0f, + 0x78, 0x02, 0xde, 0x00, 0xf7, 0xa0, 0x31, 0xa0, + 0x0f, 0x68, 0x03, 0x3a, 0x00, 0xc7, 0x80, 0x31, + 0xe0, 0x0c, 0x78, 0x03, 0xea, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x1d, 0xac, 0x00, 0xfb, + 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xac, 0x00, + 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xa0, 0x03, 0xc4, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x90, 0x03, + 0xe8, 0x00, 0xf8, 0x00, 0x36, 0x80, 0x0b, 0xb0, + 0x03, 0x6c, 0x00, 0xf3, 0x00, 0x3e, 0xc0, 0x0f, + 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x80, 0xbe, 0x00, + 0x0f, 0x80, 0x0b, 0xe0, 0x00, 0xbb, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xc2, 0x06, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0x00, 0xff, + 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, + 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0x68, 0x03, 0x32, + 0x00, 0xfc, 0x80, 0x3b, 0x20, 0x0c, 0xe8, 0x03, + 0xfa, 0x00, 0xf5, 0x80, 0x33, 0xe0, 0x0f, 0xf8, + 0x03, 0xde, 0x00, 0xcf, 0x80, 0x3f, 0xe0, 0x0f, + 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x88, 0x3f, 0xe0, + 0x0e, 0xf8, 0x03, 0x3e, 0x08, 0xc7, 0x80, 0x33, + 0xe0, 0x0c, 0xf8, 0x03, 0xc0, 0x00, 0x70, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x3b, 0x02, 0x00, 0x00, + 0xa8, 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x06, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0e, 0x60, 0x01, 0x54, 0x00, 0xb7, 0x00, + 0x21, 0xc0, 0x08, 0x62, 0x02, 0xd8, 0x00, 0xb4, + 0x00, 0x39, 0x40, 0x0e, 0x64, 0x02, 0xdc, 0x00, + 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, + 0x04, 0xb7, 0x08, 0x2d, 0xc0, 0x08, 0xd4, 0x02, + 0x35, 0x00, 0xa7, 0x00, 0x21, 0xc0, 0x0a, 0x70, + 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, + 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, + 0xc0, 0x0b, 0xe0, 0x02, 0x10, 0x00, 0xb4, 0x00, + 0x2b, 0x20, 0x08, 0x70, 0x22, 0xd8, 0x00, 0xb4, + 0x00, 0x25, 0xc0, 0x0b, 0x50, 0x02, 0xfc, 0x00, + 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, + 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0a, 0x60, 0x02, + 0x18, 0x00, 0x87, 0x00, 0x20, 0xc0, 0x08, 0x70, + 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, + 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, + 0xc0, 0x8b, 0x20, 0x02, 0x45, 0x20, 0xb3, 0x10, + 0x20, 0xc2, 0x08, 0x30, 0x02, 0xc1, 0x80, 0x30, + 0xf0, 0x28, 0xf0, 0x0a, 0x3e, 0x02, 0xce, 0x60, + 0x82, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, + 0x00, 0xb3, 0xe0, 0x2c, 0xc0, 0x08, 0x00, 0x02, + 0x00, 0x00, 0xa3, 0x00, 0x20, 0xc0, 0x0a, 0x30, + 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, + 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, + 0xc0, 0x0f, 0xa0, 0x03, 0x01, 0x08, 0xf8, 0x50, + 0x38, 0x20, 0x0c, 0xb0, 0x03, 0xcc, 0x00, 0x7b, + 0x00, 0x36, 0xc2, 0x0f, 0xed, 0x09, 0x00, 0x3c, + 0x02, 0x36, 0x03, 0xee, 0x00, 0x4b, 0x00, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xff, 0x01, + 0x3e, 0xc0, 0x8e, 0xb0, 0x03, 0x2c, 0x00, 0xcb, + 0x00, 0x30, 0x40, 0x0c, 0xb0, 0x03, 0xea, 0x04, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xec, + 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, + 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0e, 0xa0, + 0x03, 0xe4, 0x00, 0xfb, 0x00, 0x3e, 0xc4, 0x2f, + 0xb0, 0x07, 0xe9, 0x08, 0xf8, 0x40, 0x3e, 0xd2, + 0x0f, 0x90, 0x01, 0xed, 0x00, 0xfb, 0x40, 0x3e, + 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, + 0x3e, 0x41, 0x0f, 0xb0, 0x0b, 0xec, 0x00, 0xfb, + 0x20, 0xbe, 0xc0, 0x0f, 0xb0, 0x03, 0xe0, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xfc, + 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xfc, 0x00, 0xff, 0x00, 0x3b, 0xc0, 0x0f, 0xe0, + 0x03, 0xf0, 0x00, 0xcc, 0x00, 0x3f, 0x00, 0x0c, + 0xf1, 0x03, 0xf8, 0x0c, 0xcf, 0x44, 0x33, 0x48, + 0x0c, 0xe8, 0x03, 0x34, 0x00, 0xcf, 0x88, 0x33, + 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0x80, 0x0c, 0xf0, 0x03, 0x3c, 0x00, 0xcf, + 0x90, 0x2f, 0x40, 0x0c, 0x70, 0x03, 0x00, 0x44, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x6c, + 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x8b, 0xb0, 0x02, + 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xa0, + 0x02, 0xe4, 0x02, 0x8b, 0x00, 0x2e, 0xc0, 0x08, + 0xb4, 0x82, 0xe9, 0x80, 0xa0, 0xe0, 0x28, 0xd0, + 0x0d, 0xbd, 0x02, 0x0c, 0x80, 0xd1, 0x80, 0x36, + 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, + 0x2e, 0x00, 0x28, 0xbc, 0x02, 0x2f, 0x02, 0x8b, + 0x48, 0x2e, 0xe4, 0x8a, 0xb0, 0x02, 0x20, 0x40, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0xed, + 0x09, 0x00, 0x3d, 0x02, 0x2c, 0x00, 0xbb, 0x00, + 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, + 0x00, 0x2e, 0xc0, 0x0b, 0xa0, 0x02, 0xe0, 0x01, + 0x88, 0x00, 0x2e, 0x00, 0x08, 0xb0, 0x02, 0xe8, + 0x80, 0xa8, 0x00, 0x22, 0x90, 0x88, 0xb0, 0x2a, + 0x2e, 0x00, 0x8b, 0x50, 0x22, 0xc0, 0x0b, 0xb0, + 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2c, 0xc0, 0x08, + 0x31, 0x02, 0x0c, 0x40, 0x8b, 0x00, 0x2e, 0xc0, + 0x08, 0xb0, 0x02, 0x20, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x0c, 0x00, 0xb3, 0x00, + 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, + 0x00, 0x2c, 0xc0, 0x0b, 0x20, 0x42, 0xc4, 0x01, + 0x83, 0x00, 0x2e, 0xc0, 0x08, 0x10, 0x02, 0xe8, + 0x00, 0xa8, 0x00, 0x28, 0xc0, 0x09, 0x30, 0x00, + 0x08, 0x00, 0x93, 0x00, 0x24, 0xc0, 0x0b, 0x30, + 0x02, 0xcc, 0x00, 0xb3, 0x02, 0x2c, 0xc0, 0x08, + 0x30, 0x02, 0x0c, 0x00, 0x82, 0x00, 0x2c, 0xc0, + 0x08, 0x30, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x00, 0xfb, 0x00, + 0x3e, 0xc0, 0x0f, 0xb0, 0x43, 0xec, 0x00, 0xfb, + 0x00, 0x3a, 0xc0, 0x0f, 0xa0, 0x03, 0xe0, 0x00, + 0x88, 0x00, 0x3e, 0x00, 0x08, 0xa0, 0x02, 0xe0, + 0x00, 0xe8, 0x00, 0x32, 0xc0, 0x0c, 0xb0, 0x03, + 0x2c, 0x00, 0xca, 0x00, 0x32, 0xc0, 0x0f, 0xb0, + 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3c, 0xc0, 0x0c, + 0xb0, 0x03, 0x2c, 0x04, 0xcb, 0x00, 0x3e, 0xc0, + 0x0c, 0xb0, 0x0b, 0x00, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x1d, 0xfc, 0x00, 0xff, 0x00, + 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, + 0x00, 0x3f, 0xc0, 0x0f, 0xe0, 0x03, 0xf4, 0x00, + 0xf7, 0x00, 0x3d, 0xc0, 0x2f, 0xc0, 0x03, 0xf0, + 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, + 0xf8, 0x00, 0xed, 0x09, 0x00, 0x3e, 0x02, 0xfc, + 0x02, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, + 0xff, 0x00, 0x0f, 0xc0, 0x0f, 0xf0, 0x01, 0xfc, + 0x00, 0xfe, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, + 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc5, 0x41, 0x03, 0x70, 0x40, 0xdc, 0x10, 0x37, + 0x02, 0x05, 0xc1, 0x03, 0x71, 0x40, 0xdc, 0x10, + 0x37, 0x00, 0x05, 0xc5, 0x01, 0x70, 0x40, 0xdc, + 0x08, 0x37, 0x04, 0x05, 0xc0, 0x23, 0x70, 0x44, + 0x9c, 0x10, 0x07, 0x04, 0x05, 0xc1, 0x03, 0x70, + 0x40, 0xdc, 0x10, 0x13, 0x04, 0x11, 0xc1, 0x02, + 0x70, 0x40, 0xdc, 0x10, 0x37, 0x00, 0x9d, 0xc1, + 0x03, 0x70, 0x40, 0xdc, 0x10, 0x37, 0x04, 0x0d, + 0xc0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x44, 0x05, 0x71, 0x01, 0x5c, 0x40, 0x57, + 0x12, 0x05, 0xc4, 0x01, 0x72, 0x01, 0x0c, 0x40, + 0x57, 0x10, 0xc5, 0xc1, 0x44, 0x21, 0x01, 0x5c, + 0x40, 0x57, 0x10, 0x05, 0xc4, 0x05, 0x71, 0x01, + 0x5c, 0x40, 0x17, 0x10, 0x15, 0xc4, 0x04, 0x31, + 0x01, 0x5c, 0x40, 0x13, 0x10, 0x0d, 0xc4, 0x05, + 0x71, 0x01, 0x5c, 0x40, 0x57, 0x10, 0x15, 0xc4, + 0x05, 0x71, 0x01, 0x5c, 0x40, 0x55, 0x10, 0x15, + 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x03, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, + 0x0a, 0x04, 0x82, 0x01, 0x22, 0x80, 0x5c, 0x20, + 0x12, 0x08, 0x04, 0x82, 0x41, 0x30, 0x80, 0x48, + 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, + 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x70, + 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, + 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, + 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, + 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x01, 0x60, 0x00, 0xed, 0x09, 0x00, + 0x3f, 0x02, 0x58, 0x00, 0x16, 0x00, 0x05, 0x80, + 0x01, 0x60, 0x09, 0x58, 0x00, 0x16, 0x00, 0x05, + 0x80, 0xa5, 0x60, 0x00, 0x58, 0x00, 0x06, 0x00, + 0x05, 0x80, 0x00, 0x60, 0x00, 0x58, 0x00, 0x16, + 0x00, 0x95, 0x80, 0x61, 0x60, 0x00, 0x58, 0x01, + 0x16, 0x00, 0x05, 0x80, 0x01, 0x60, 0x00, 0x58, + 0x00, 0x16, 0x00, 0x05, 0x80, 0x01, 0x60, 0x00, + 0x58, 0x00, 0x16, 0x00, 0x05, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x48, 0x45, + 0x72, 0x01, 0x1c, 0x80, 0x57, 0x25, 0x15, 0xc8, + 0x04, 0x70, 0x21, 0x5c, 0x80, 0x57, 0x71, 0x94, + 0xc8, 0x05, 0x72, 0x01, 0x5c, 0x85, 0x57, 0x60, + 0x14, 0xd8, 0x65, 0x32, 0x01, 0x1c, 0x80, 0x47, + 0x20, 0x11, 0xc8, 0x05, 0x72, 0x01, 0x1c, 0x80, + 0x57, 0x20, 0x05, 0xc8, 0x05, 0x56, 0x09, 0x4c, + 0x80, 0x57, 0x21, 0x05, 0x48, 0x05, 0x72, 0x01, + 0x5c, 0x80, 0x57, 0x20, 0x15, 0xc0, 0x11, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x40, 0x00, + 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, + 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x01, 0x00, + 0x80, 0x00, 0x60, 0x10, 0x18, 0x00, 0x06, 0x01, + 0x00, 0x80, 0x40, 0x20, 0x00, 0x10, 0x00, 0x06, + 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, + 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x10, 0x08, + 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, + 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x48, 0x04, + 0x22, 0x01, 0x08, 0x80, 0x42, 0x20, 0x10, 0x88, + 0x04, 0x20, 0x81, 0x08, 0x80, 0x42, 0x20, 0x11, + 0x82, 0x04, 0x22, 0x01, 0x08, 0x80, 0x42, 0x20, + 0x11, 0x88, 0x04, 0x62, 0x01, 0x08, 0x80, 0x42, + 0x00, 0x10, 0x88, 0x04, 0x22, 0x01, 0x08, 0x80, + 0xed, 0x09, 0x00, 0x40, 0x02, 0x42, 0x20, 0x00, + 0x88, 0x04, 0x20, 0x01, 0x18, 0x80, 0x42, 0x20, + 0x00, 0x88, 0x04, 0x22, 0x01, 0x08, 0x80, 0x42, + 0x20, 0x10, 0x80, 0x31, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc1, 0x4a, 0x05, 0x42, 0x81, 0x50, + 0xa0, 0x54, 0x3c, 0x15, 0x0a, 0x05, 0x40, 0x80, + 0x58, 0xa0, 0x54, 0x2a, 0x15, 0x42, 0x01, 0x42, + 0x81, 0x50, 0xa1, 0x54, 0x28, 0x15, 0x4a, 0x04, + 0x52, 0x85, 0x50, 0xa0, 0x44, 0x08, 0x01, 0x0a, + 0x04, 0x42, 0x81, 0x50, 0xa0, 0x54, 0x28, 0x45, + 0x0a, 0x05, 0x42, 0x81, 0x54, 0xa0, 0x54, 0x28, + 0x15, 0x0a, 0x05, 0x42, 0x81, 0x50, 0xa0, 0x54, + 0x28, 0x15, 0x00, 0x31, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x84, 0x0d, 0x01, 0x53, 0x00, 0x54, + 0xc0, 0x15, 0x34, 0x04, 0x4c, 0x01, 0x53, 0x00, + 0x40, 0xc0, 0x15, 0x66, 0x04, 0x0c, 0x01, 0x57, + 0x00, 0x54, 0xd0, 0x15, 0x70, 0x05, 0x5d, 0x01, + 0x53, 0x00, 0x54, 0xc0, 0x15, 0x30, 0x05, 0x4c, + 0x01, 0x71, 0x00, 0x54, 0xc0, 0x15, 0x30, 0x05, + 0x4c, 0x01, 0x57, 0x00, 0x54, 0xc0, 0x15, 0x34, + 0x05, 0x4c, 0x01, 0x53, 0x00, 0x54, 0xc0, 0x15, + 0x30, 0x05, 0x40, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x10, + 0x00, 0x04, 0x10, 0x00, 0x40, 0x00, 0x42, 0x00, + 0x10, 0x00, 0x04, 0x90, 0x40, 0x00, 0x10, 0x40, + 0x00, 0x10, 0x00, 0x04, 0x81, 0x11, 0x20, 0x00, + 0x40, 0x00, 0x10, 0x00, 0x04, 0x20, 0x01, 0x00, + 0x00, 0x40, 0x04, 0x10, 0x00, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x48, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x01, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc5, 0x60, 0x02, 0x08, 0x00, 0x82, + 0x00, 0x20, 0x80, 0xed, 0x09, 0x00, 0x41, 0x02, + 0x18, 0x60, 0x00, 0x08, 0x08, 0x82, 0x00, 0x20, + 0x84, 0x18, 0x28, 0x22, 0x08, 0x00, 0x82, 0x00, + 0x20, 0x80, 0x58, 0x20, 0x02, 0x08, 0x00, 0x82, + 0x00, 0x00, 0x80, 0x88, 0x20, 0x22, 0x0a, 0x00, + 0x82, 0x00, 0x00, 0x80, 0x00, 0x20, 0x02, 0x0a, + 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, + 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, 0x01, + 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, + 0x40, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, 0x00, + 0x1d, 0x80, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, + 0x40, 0x1d, 0x80, 0x07, 0x64, 0x01, 0x58, 0x00, + 0x56, 0x40, 0x15, 0x90, 0x05, 0x60, 0x00, 0x58, + 0x00, 0x76, 0x00, 0x1d, 0x80, 0x05, 0x60, 0x02, + 0x58, 0x00, 0x76, 0x00, 0x3d, 0x80, 0x05, 0x64, + 0x01, 0x58, 0x00, 0x56, 0x00, 0x05, 0x80, 0x05, + 0x60, 0x01, 0x58, 0x00, 0x56, 0x00, 0x15, 0x80, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, + 0x40, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00, + 0x0d, 0x80, 0x03, 0x60, 0x01, 0xdc, 0x00, 0x36, + 0x00, 0x0d, 0x88, 0x03, 0x70, 0x00, 0x58, 0x00, + 0x16, 0x00, 0x0d, 0x80, 0x02, 0x60, 0x00, 0x98, + 0x00, 0x36, 0x20, 0x05, 0x80, 0x03, 0x70, 0x01, + 0xd8, 0x00, 0x36, 0x00, 0x0d, 0x80, 0x01, 0x60, + 0x00, 0xd8, 0x00, 0x36, 0x00, 0x1d, 0x80, 0x03, + 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00, 0x0d, 0x80, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, + 0x42, 0x24, 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08, + 0x90, 0xc2, 0x04, 0x30, 0x80, 0x18, 0x20, 0x43, + 0x08, 0x90, 0xc2, 0x04, 0x60, 0x80, 0x0c, 0x22, + 0x03, 0x08, 0x10, 0xc2, 0x34, 0x30, 0x81, 0x0c, + 0x21, 0x43, 0x0c, 0x10, 0xc2, 0x04, 0x60, 0x81, + 0x04, 0x20, 0x43, 0x08, 0x10, 0xc2, 0xed, 0x09, + 0x00, 0x42, 0x02, 0x00, 0x30, 0xc1, 0x04, 0x20, + 0x43, 0x08, 0x90, 0xc2, 0x04, 0x30, 0x81, 0x0c, + 0x20, 0x43, 0x08, 0x10, 0xc0, 0x31, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x30, + 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, + 0x30, 0x00, 0x08, 0x00, 0x03, 0x01, 0x00, 0xc0, + 0x00, 0x00, 0x11, 0x0c, 0x00, 0x03, 0x01, 0x00, + 0xc0, 0x40, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, + 0x00, 0xc0, 0x00, 0x20, 0x00, 0x0c, 0x00, 0x03, + 0x00, 0x00, 0xc0, 0x04, 0x30, 0x10, 0x0c, 0x00, + 0x01, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c, + 0x00, 0x03, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, 0x01, 0x30, + 0x80, 0x4c, 0x20, 0x13, 0x08, 0x04, 0xc2, 0x01, + 0x30, 0xc0, 0x4c, 0x20, 0x13, 0x08, 0x04, 0xc3, + 0x05, 0x30, 0x80, 0x4c, 0x20, 0x13, 0x08, 0x04, + 0xc2, 0x01, 0x30, 0x80, 0x4c, 0x20, 0x13, 0x08, + 0x14, 0xc2, 0x01, 0x30, 0x80, 0x4c, 0x20, 0x11, + 0x08, 0x04, 0xc2, 0x01, 0x12, 0xc0, 0x4c, 0x20, + 0x13, 0x08, 0x14, 0xc2, 0x01, 0x30, 0x80, 0x4c, + 0x20, 0x13, 0x08, 0x04, 0xc0, 0x21, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x02, 0x05, 0x60, + 0x81, 0x58, 0x20, 0x56, 0x00, 0x15, 0x82, 0x05, + 0x60, 0xc0, 0x58, 0x20, 0x56, 0x04, 0x15, 0x83, + 0x05, 0x60, 0x81, 0x58, 0x00, 0x56, 0x08, 0x15, + 0x81, 0x04, 0x60, 0x81, 0x18, 0x20, 0x56, 0x08, + 0x15, 0x82, 0x04, 0x60, 0x80, 0x18, 0x20, 0x44, + 0x08, 0x11, 0x82, 0x05, 0x60, 0xc1, 0x58, 0x20, + 0x56, 0x00, 0x05, 0x82, 0x05, 0x60, 0x81, 0x58, + 0x20, 0x56, 0x08, 0x15, 0x80, 0x31, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x02, 0x00, 0x20, + 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, + 0x20, 0xed, 0x09, 0x00, 0x43, 0x02, 0x80, 0x0c, + 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, 0x30, 0x80, + 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, + 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0xc2, 0x00, + 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, + 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x10, + 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, + 0x00, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x45, 0x52, 0x04, 0x60, 0x81, 0x18, 0x20, + 0x46, 0x48, 0x11, 0x82, 0x04, 0x60, 0x80, 0x0c, + 0x20, 0x46, 0x4c, 0x11, 0x82, 0x04, 0x30, 0x81, + 0x19, 0x20, 0x46, 0x08, 0x11, 0x93, 0x04, 0x60, + 0x81, 0x18, 0x20, 0x46, 0x0c, 0x10, 0xc2, 0x04, + 0x60, 0x80, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, + 0x04, 0x60, 0xc1, 0x18, 0x20, 0x46, 0x48, 0x11, + 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, + 0x11, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc5, 0x60, 0x05, 0x58, 0x01, 0x56, 0x00, + 0x55, 0x80, 0x15, 0x60, 0x05, 0x58, 0x00, 0x46, + 0x00, 0x55, 0x80, 0x15, 0x60, 0x01, 0x18, 0x01, + 0x56, 0x00, 0x55, 0x80, 0x55, 0x60, 0x04, 0x58, + 0x01, 0x56, 0x00, 0x55, 0x80, 0x04, 0x60, 0x14, + 0x58, 0x01, 0x56, 0x00, 0x55, 0x80, 0x15, 0x60, + 0x05, 0x58, 0x01, 0x56, 0x00, 0x55, 0x80, 0x05, + 0x60, 0x05, 0x58, 0x01, 0x56, 0x00, 0x55, 0x80, + 0x15, 0x40, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x26, 0x01, 0x41, 0x80, 0x50, 0x60, + 0x14, 0x98, 0x05, 0x06, 0x01, 0x41, 0x81, 0x50, + 0x60, 0x04, 0x98, 0x01, 0x46, 0x01, 0x41, 0x80, + 0x52, 0x60, 0x14, 0x18, 0x05, 0x66, 0x01, 0x51, + 0x80, 0x50, 0x60, 0x14, 0x18, 0x05, 0x06, 0x01, + 0x41, 0x80, 0x50, 0x60, 0x04, 0x18, 0x05, 0x06, + 0x01, 0x41, 0x80, 0x54, 0xed, 0x09, 0x00, 0x44, + 0x02, 0x60, 0x04, 0x98, 0x01, 0x06, 0x01, 0x41, + 0x80, 0x50, 0x60, 0x14, 0x18, 0x05, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, + 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x48, 0x04, + 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x48, + 0x00, 0x03, 0x01, 0x00, 0x80, 0x01, 0x20, 0x10, + 0x28, 0x44, 0x12, 0x00, 0x00, 0x80, 0x40, 0x20, + 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, + 0x00, 0x20, 0x10, 0x48, 0x04, 0x02, 0x01, 0x00, + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x46, + 0x03, 0x51, 0x80, 0xd4, 0x60, 0x35, 0x18, 0x0d, + 0x46, 0x03, 0x51, 0x91, 0xd4, 0x60, 0x35, 0x18, + 0x08, 0x46, 0x43, 0x51, 0x80, 0x44, 0x60, 0x75, + 0x18, 0x08, 0x46, 0x02, 0x11, 0x80, 0xd4, 0x60, + 0x35, 0x19, 0x0d, 0x46, 0x43, 0x51, 0x80, 0xc4, + 0x60, 0x35, 0x18, 0x0d, 0x46, 0x01, 0x51, 0x80, + 0x84, 0x60, 0x35, 0x18, 0x0d, 0x46, 0x03, 0x51, + 0x80, 0xd4, 0x60, 0x35, 0x18, 0x0d, 0x40, 0x31, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x42, + 0x25, 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x95, + 0xc6, 0x05, 0x73, 0x01, 0x5c, 0x60, 0x57, 0x38, + 0x95, 0xcc, 0x05, 0x71, 0x81, 0x5c, 0x62, 0x77, + 0x38, 0x04, 0xc6, 0x25, 0x71, 0x81, 0x5c, 0x60, + 0x57, 0x18, 0x1d, 0xc4, 0x05, 0x71, 0x80, 0x5c, + 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05, 0x71, 0x81, + 0x5c, 0x60, 0x57, 0x18, 0x95, 0xc6, 0x05, 0x71, + 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc0, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x46, + 0x03, 0x71, 0x80, 0xdc, 0x60, 0x34, 0x18, 0x05, + 0xc6, 0x03, 0x71, 0x80, 0x54, 0x60, 0x37, 0xed, + 0x09, 0x00, 0x45, 0x02, 0x38, 0x0d, 0xce, 0x01, + 0x71, 0x80, 0xdc, 0x60, 0x37, 0x18, 0x15, 0xc6, + 0x01, 0x71, 0x80, 0xdc, 0x60, 0x57, 0x18, 0x05, + 0xc6, 0x03, 0x71, 0x80, 0xd8, 0x61, 0x37, 0x18, + 0x09, 0xc6, 0x13, 0x71, 0x80, 0xd0, 0x60, 0x27, + 0x18, 0x15, 0xc6, 0x03, 0x71, 0x80, 0xdc, 0x60, + 0x17, 0x18, 0x0d, 0xc0, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x45, 0x56, 0x05, 0x71, 0x81, + 0x5c, 0x60, 0x53, 0x58, 0x15, 0xc6, 0x05, 0x71, + 0x81, 0x0c, 0x61, 0x57, 0x59, 0x15, 0xc6, 0x14, + 0x31, 0x91, 0x5d, 0x60, 0x57, 0x19, 0x44, 0xd6, + 0x41, 0x71, 0x81, 0x5c, 0x60, 0x37, 0x18, 0x10, + 0xc6, 0x01, 0x31, 0x81, 0x4c, 0x60, 0x55, 0x18, + 0x15, 0xc6, 0x05, 0x51, 0x91, 0x4c, 0x60, 0x57, + 0x58, 0x05, 0xc6, 0x05, 0x71, 0x81, 0x5c, 0x60, + 0x12, 0x18, 0x15, 0xc0, 0x11, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x20, 0x80, + 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, + 0x80, 0x5c, 0x20, 0x12, 0x08, 0x04, 0x83, 0x01, + 0x70, 0x80, 0x48, 0x20, 0x12, 0x08, 0x10, 0x82, + 0x01, 0x20, 0x80, 0x48, 0x20, 0x52, 0x08, 0x05, + 0xc2, 0x00, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, + 0x04, 0x82, 0x01, 0x00, 0x80, 0x48, 0x20, 0x12, + 0x08, 0x14, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, + 0x52, 0x08, 0x04, 0x80, 0x11, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x06, 0x01, 0x61, 0x80, + 0x58, 0x60, 0x16, 0x18, 0x05, 0x86, 0x01, 0x61, + 0x81, 0x58, 0x60, 0x16, 0x18, 0x05, 0x86, 0x05, + 0x61, 0x80, 0x58, 0x60, 0x16, 0x18, 0x05, 0x86, + 0x00, 0x61, 0x80, 0x58, 0x60, 0x16, 0x18, 0x15, + 0x86, 0x01, 0x61, 0x80, 0x58, 0x60, 0x16, 0x18, + 0x05, 0x86, 0x01, 0x61, 0x80, 0x58, 0x60, 0x16, + 0x18, 0x05, 0xed, 0x09, 0x00, 0x46, 0x02, 0x86, + 0x01, 0x61, 0x80, 0x58, 0x60, 0x16, 0x18, 0x05, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x40, 0x05, 0x70, 0x01, 0x5c, 0x00, 0x57, + 0x00, 0x15, 0xc0, 0x05, 0x70, 0x01, 0x5c, 0x00, + 0x57, 0x00, 0x14, 0xc0, 0x04, 0x70, 0x01, 0x4c, + 0x00, 0x57, 0x00, 0x84, 0xc0, 0x04, 0x70, 0x01, + 0x5c, 0x00, 0x17, 0x00, 0x11, 0xc0, 0x05, 0x70, + 0x01, 0x5c, 0x00, 0x47, 0x00, 0x15, 0xc0, 0x05, + 0x70, 0x21, 0x5c, 0x00, 0x57, 0x00, 0x05, 0xc0, + 0x05, 0x70, 0x01, 0x5c, 0x00, 0x57, 0x00, 0x15, + 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x43, 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, + 0x08, 0x01, 0x82, 0x00, 0x60, 0x80, 0x18, 0x20, + 0x06, 0x0a, 0x00, 0x82, 0x00, 0x60, 0xc0, 0x08, + 0x20, 0x06, 0x0a, 0x00, 0x82, 0x80, 0x60, 0x80, + 0x18, 0x20, 0x04, 0x08, 0x01, 0x82, 0x00, 0x60, + 0x80, 0x18, 0x20, 0x06, 0x08, 0x00, 0x82, 0x00, + 0x60, 0xa0, 0x18, 0x20, 0x06, 0x08, 0x01, 0x82, + 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, 0x08, 0x01, + 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x42, 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, + 0x08, 0x10, 0x82, 0x04, 0x20, 0x81, 0x08, 0x20, + 0x42, 0x28, 0x11, 0x82, 0x04, 0x20, 0x81, 0x18, + 0x20, 0x40, 0x0a, 0x01, 0x82, 0x84, 0x20, 0x81, + 0x08, 0x20, 0x02, 0x08, 0x10, 0x82, 0x04, 0x20, + 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, + 0x20, 0xa1, 0x08, 0x20, 0x42, 0x08, 0x00, 0x82, + 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, + 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x43, 0x05, 0x40, 0x81, 0x50, 0x20, 0x54, + 0x08, 0x15, 0x02, 0x05, 0x42, 0x80, 0x50, 0x20, + 0x54, 0x20, 0x95, 0x4a, 0x01, 0xed, 0x09, 0x00, + 0x47, 0x02, 0x40, 0x81, 0x54, 0x20, 0x54, 0x24, + 0x45, 0x40, 0x05, 0x40, 0x81, 0x50, 0x20, 0x14, + 0x08, 0x01, 0x02, 0x04, 0x40, 0x81, 0x50, 0x20, + 0x44, 0x08, 0x14, 0x02, 0x05, 0x40, 0x01, 0x50, + 0x20, 0x54, 0x08, 0x05, 0x82, 0x05, 0x40, 0x81, + 0x50, 0x20, 0x54, 0x08, 0x15, 0x00, 0x11, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x43, 0x01, + 0x10, 0xc0, 0x54, 0x30, 0x15, 0x08, 0x04, 0xc3, + 0x01, 0x50, 0xc0, 0x14, 0x30, 0x15, 0x28, 0x04, + 0xc3, 0x01, 0x50, 0xc0, 0x54, 0x30, 0x11, 0x0c, + 0x15, 0x43, 0x21, 0x00, 0xc0, 0x54, 0x30, 0x15, + 0x0c, 0x05, 0x43, 0x01, 0x50, 0xc0, 0x54, 0x30, + 0x15, 0x0c, 0x05, 0x43, 0x01, 0x50, 0xc0, 0x54, + 0x30, 0x15, 0x0c, 0x14, 0x43, 0x01, 0x50, 0xc0, + 0x54, 0x30, 0x15, 0x0c, 0x05, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x48, 0x00, + 0x12, 0x00, 0x10, 0x80, 0x04, 0x20, 0x00, 0x48, + 0x00, 0x42, 0x00, 0x10, 0x80, 0x04, 0x01, 0x00, + 0x08, 0x00, 0x40, 0x00, 0x10, 0x80, 0x01, 0x01, + 0x01, 0x08, 0x40, 0x02, 0x00, 0x10, 0x80, 0x04, + 0x20, 0x41, 0x08, 0x00, 0x42, 0x00, 0x10, 0x80, + 0x04, 0x20, 0x41, 0x08, 0x00, 0x42, 0x10, 0x10, + 0x80, 0x04, 0x20, 0x00, 0x08, 0x00, 0x42, 0x00, + 0x10, 0x80, 0x04, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x42, 0x22, + 0x10, 0x80, 0x80, 0x20, 0x20, 0x08, 0x88, 0x42, + 0x02, 0x04, 0x90, 0x80, 0x20, 0x20, 0x08, 0xc8, + 0x92, 0x02, 0x02, 0x80, 0x80, 0x22, 0x21, 0x28, + 0x00, 0x02, 0x36, 0x00, 0x80, 0x80, 0x20, 0x00, + 0x08, 0x08, 0x12, 0x86, 0x00, 0x80, 0x80, 0x20, + 0x20, 0x08, 0x08, 0x02, 0x02, 0x00, 0x80, 0x80, + 0x20, 0x20, 0x08, 0x80, 0x42, 0x02, 0x00, 0x80, + 0xed, 0x09, 0x00, 0x48, 0x02, 0x80, 0x20, 0x00, + 0x08, 0x08, 0x00, 0x11, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x40, 0x85, 0x60, 0x01, 0x58, + 0x00, 0x56, 0x02, 0x1d, 0x80, 0x05, 0x60, 0x10, + 0xd8, 0x00, 0x56, 0x00, 0x14, 0x80, 0x43, 0x60, + 0x01, 0x58, 0x00, 0x56, 0x00, 0x15, 0x80, 0x87, + 0x20, 0x01, 0x58, 0x00, 0x56, 0x00, 0x1d, 0x80, + 0x45, 0x60, 0x00, 0x58, 0x00, 0x56, 0x00, 0x15, + 0x80, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, 0x02, + 0x14, 0x80, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, + 0x00, 0x15, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc5, 0x40, 0x83, 0x60, 0x00, 0xd8, + 0x00, 0x16, 0x02, 0x0d, 0x80, 0x03, 0x60, 0x10, + 0x5c, 0x00, 0x16, 0x02, 0x81, 0x80, 0x41, 0x70, + 0x01, 0x58, 0x08, 0x36, 0x00, 0x19, 0x80, 0x81, + 0x60, 0x00, 0xd8, 0x00, 0x16, 0x00, 0x05, 0xc0, + 0x07, 0x60, 0x00, 0xd8, 0x00, 0x26, 0x00, 0x4d, + 0x00, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, 0x02, + 0x0d, 0x80, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, + 0x00, 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x01, 0x0c, + 0x00, 0x03, 0x02, 0x10, 0xc0, 0x04, 0x30, 0x09, + 0x18, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x24, 0x60, + 0x00, 0x0c, 0x09, 0x43, 0x00, 0x18, 0xc0, 0x00, + 0x30, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x11, 0x80, + 0x34, 0x30, 0x01, 0x0c, 0x00, 0x03, 0x00, 0x00, + 0xc0, 0x04, 0x30, 0x01, 0x0c, 0x00, 0x43, 0x01, + 0x10, 0xc0, 0x04, 0x30, 0x01, 0x0c, 0x00, 0x43, + 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x00, 0x0c, + 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x34, 0x00, + 0x08, 0x00, 0x03, 0x12, 0x00, 0xd0, 0x00, 0x20, + 0x01, 0x0c, 0x00, 0xed, 0x09, 0x00, 0x49, 0x02, + 0x03, 0x30, 0x00, 0xc0, 0x20, 0x30, 0x00, 0x0c, + 0x00, 0x43, 0x40, 0x00, 0x90, 0x00, 0x30, 0x00, + 0x0c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x00, 0x30, + 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, + 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x01, 0x31, 0x40, 0x4c, 0x50, 0x13, 0x10, + 0x04, 0xc5, 0x01, 0x3b, 0x41, 0x4c, 0x50, 0x13, + 0x1a, 0x04, 0xe5, 0x25, 0x31, 0x40, 0x4c, 0x51, + 0x13, 0x06, 0x00, 0xc5, 0x01, 0x31, 0x40, 0x4c, + 0x50, 0x13, 0x14, 0x14, 0xe5, 0x01, 0x31, 0x40, + 0x44, 0x50, 0x13, 0x14, 0x04, 0xc5, 0x01, 0x31, + 0x40, 0x4c, 0x50, 0x13, 0x14, 0x04, 0xc5, 0x01, + 0x31, 0x40, 0x4c, 0x50, 0x13, 0x14, 0x04, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x23, 0x05, 0x68, 0xc1, 0x5a, 0x30, 0x56, 0x8c, + 0x15, 0xa3, 0x05, 0x68, 0x81, 0x5a, 0x30, 0x56, + 0x8e, 0x15, 0xa2, 0x05, 0x68, 0xc0, 0x5a, 0x30, + 0x46, 0x8c, 0x01, 0xa3, 0x05, 0x68, 0xc1, 0x1a, + 0x30, 0x56, 0x8c, 0x11, 0xa2, 0x01, 0x68, 0xc1, + 0x5a, 0x30, 0x56, 0x8c, 0x15, 0xa3, 0x04, 0x68, + 0xc1, 0x5a, 0x30, 0x56, 0x8c, 0x15, 0xa3, 0x05, + 0x68, 0xc1, 0x5a, 0x30, 0x56, 0x8c, 0x15, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x24, 0x00, 0x0c, 0x00, 0x02, + 0x10, 0x00, 0x90, 0x00, 0x32, 0x00, 0x08, 0x00, + 0x02, 0x20, 0x10, 0x80, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x02, 0x40, 0x00, 0x10, 0x04, 0x30, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0xed, 0x09, + 0x00, 0x4a, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x44, 0x62, + 0x11, 0x18, 0x84, 0x46, 0x21, 0x11, 0x88, 0x44, + 0x62, 0x11, 0x0c, 0x84, 0x46, 0x01, 0x11, 0x88, + 0x44, 0x30, 0x10, 0x18, 0x84, 0x46, 0x01, 0x11, + 0x88, 0x44, 0x62, 0x11, 0x18, 0x84, 0x46, 0x21, + 0x11, 0x88, 0x44, 0x32, 0x11, 0x18, 0x84, 0x46, + 0x21, 0x11, 0x88, 0x44, 0x62, 0x11, 0x18, 0x84, + 0x46, 0x21, 0x11, 0x88, 0x44, 0x62, 0x11, 0x18, + 0x84, 0x46, 0x21, 0x11, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x50, + 0x11, 0x54, 0x04, 0x55, 0x01, 0x15, 0x40, 0x45, + 0x50, 0x30, 0x44, 0x04, 0x55, 0x01, 0x15, 0x40, + 0x41, 0x10, 0x10, 0x54, 0x04, 0x55, 0x11, 0x85, + 0x40, 0x55, 0x50, 0x11, 0x14, 0x04, 0x45, 0x01, + 0x05, 0x40, 0x45, 0x10, 0x11, 0x54, 0x05, 0x45, + 0x01, 0x15, 0x40, 0x45, 0x50, 0x11, 0x54, 0x04, + 0x55, 0x01, 0x15, 0x40, 0x45, 0x50, 0x11, 0x54, + 0x04, 0x55, 0x01, 0x15, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x42, + 0x08, 0x50, 0x82, 0x14, 0x20, 0x85, 0x08, 0x20, + 0x42, 0x08, 0x50, 0x82, 0x14, 0x20, 0x84, 0x08, + 0xa1, 0x42, 0x09, 0x54, 0x82, 0x14, 0x20, 0x84, + 0x08, 0x21, 0x42, 0x08, 0x50, 0x82, 0x14, 0x20, + 0x85, 0x08, 0x21, 0x42, 0x08, 0x50, 0x82, 0x14, + 0x20, 0x85, 0x08, 0x21, 0x42, 0x08, 0x50, 0x82, + 0x14, 0x20, 0x85, 0x08, 0x21, 0x42, 0x08, 0x50, + 0x82, 0x14, 0x20, 0x85, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x02, + 0x84, 0x40, 0xa0, 0x10, 0x2a, 0x04, 0x0a, 0x01, + 0x00, 0x90, 0x40, 0xa0, 0x10, 0x08, 0x14, 0x02, + 0x41, 0x02, 0x80, 0x00, 0xa0, 0x10, 0x0c, 0x00, + 0x0a, 0xed, 0x09, 0x00, 0x4b, 0x02, 0x05, 0x02, + 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01, + 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, + 0x01, 0x02, 0x80, 0x40, 0xa1, 0x10, 0x28, 0x04, + 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x03, 0x53, 0x00, 0xd4, 0xc0, + 0x10, 0x32, 0x0d, 0x4c, 0x03, 0x53, 0x00, 0xd4, + 0xc0, 0x15, 0x32, 0x18, 0x0c, 0x03, 0x53, 0x00, + 0x04, 0xc0, 0x35, 0x30, 0x08, 0x4c, 0x07, 0x53, + 0x00, 0x54, 0xc0, 0x15, 0x30, 0x0d, 0x4c, 0x03, + 0x53, 0x00, 0xd4, 0xc0, 0x15, 0x30, 0x05, 0x4c, + 0x03, 0x03, 0x00, 0xd4, 0xc0, 0x35, 0x30, 0x0d, + 0x4c, 0x03, 0x53, 0x00, 0xd4, 0xc0, 0x35, 0x30, + 0x0d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x05, 0x72, 0x01, 0x5c, 0x80, + 0x77, 0x21, 0x05, 0xc8, 0x05, 0x72, 0x00, 0xd4, + 0x80, 0x67, 0x26, 0x11, 0xc8, 0x07, 0x72, 0x01, + 0x5c, 0x80, 0x17, 0x20, 0x15, 0xc9, 0x05, 0x72, + 0x01, 0x5c, 0x80, 0x47, 0x20, 0x1d, 0xc8, 0x04, + 0x72, 0x01, 0x1c, 0x80, 0x47, 0x20, 0x15, 0xc8, + 0x05, 0x72, 0x41, 0x5c, 0x80, 0x57, 0x20, 0x15, + 0xc8, 0x05, 0x72, 0x01, 0x5c, 0x80, 0x57, 0x20, + 0x15, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x23, 0x08, 0x48, 0xc6, 0x12, 0x31, + 0x84, 0x8c, 0x21, 0x23, 0x18, 0x48, 0xc4, 0x12, + 0x31, 0x84, 0x0c, 0x21, 0x23, 0x10, 0x40, 0xc6, + 0x12, 0x30, 0x84, 0x0c, 0x61, 0x03, 0x08, 0x48, + 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x41, 0x23, 0x10, + 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x61, 0x23, + 0x18, 0x40, 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x21, + 0x23, 0x18, 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, + 0x61, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x4c, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, + 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, + 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, + 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, + 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, + 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, + 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, + 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0xdb, 0x0b, 0x36, 0xc2, 0xcd, 0xb0, 0xb7, 0xec, + 0x2c, 0xdb, 0x0b, 0x37, 0xd2, 0xcd, 0xb0, 0xff, + 0xec, 0x2c, 0xdf, 0x4b, 0x36, 0xc2, 0xcd, 0xb0, + 0xfb, 0x6c, 0x2c, 0xdb, 0x0b, 0x36, 0xc2, 0xcd, + 0xb0, 0xb3, 0x6c, 0x2c, 0xdb, 0x0b, 0x36, 0xc2, + 0xcd, 0xb0, 0xb3, 0x6c, 0x2c, 0xdb, 0x0b, 0x36, + 0xc2, 0xcd, 0xb0, 0xb3, 0x6c, 0x2c, 0xdb, 0x0b, + 0x36, 0xc2, 0xcd, 0xb0, 0xb3, 0x6c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, + 0x3c, 0x4c, 0xcf, 0x13, 0x33, 0xc4, 0xcf, 0xf1, + 0x33, 0x3c, 0x4c, 0xcf, 0xd3, 0x33, 0xc4, 0xff, + 0xf1, 0x33, 0x3f, 0x4c, 0xcf, 0x13, 0x33, 0xc4, + 0xfc, 0xf1, 0x33, 0x3c, 0x4c, 0xcf, 0x13, 0xed, + 0x09, 0x00, 0x4d, 0x02, 0x33, 0xc4, 0xcc, 0xf1, + 0x33, 0x3c, 0x4c, 0xcf, 0x13, 0x33, 0xc4, 0xcc, + 0xf1, 0x33, 0x3c, 0x4c, 0xcf, 0x13, 0x33, 0xc4, + 0xcc, 0xf1, 0x33, 0x3c, 0x4c, 0xcf, 0x13, 0x33, + 0xc4, 0xcc, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3b, 0x1e, 0x4e, 0xdf, + 0x93, 0xb7, 0xe4, 0xec, 0x79, 0x3b, 0x7e, 0x4e, + 0xde, 0x13, 0xb7, 0xe4, 0x8c, 0x79, 0x3b, 0x78, + 0x48, 0xdf, 0x93, 0xb1, 0xe4, 0x8d, 0xf9, 0x23, + 0x1e, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed, 0xe1, + 0x3b, 0x78, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed, + 0xf9, 0x3b, 0x7e, 0x48, 0xdf, 0x93, 0xb7, 0xe4, + 0xec, 0x79, 0x3b, 0x7e, 0x4e, 0xdf, 0x93, 0xb7, + 0xe4, 0xed, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x70, 0x40, + 0x9c, 0x10, 0x27, 0x04, 0x09, 0xc1, 0x02, 0x70, + 0x40, 0x9c, 0x50, 0x27, 0x00, 0x0d, 0xc1, 0x06, + 0x70, 0x40, 0x9c, 0x10, 0x27, 0x04, 0x09, 0xc1, + 0x00, 0x70, 0x40, 0x9c, 0x10, 0x27, 0x04, 0x09, + 0xc1, 0x02, 0x71, 0x40, 0x9c, 0x10, 0x27, 0x04, + 0x09, 0xc1, 0x02, 0x70, 0x40, 0x9c, 0x10, 0x27, + 0x04, 0x09, 0xc1, 0x02, 0x70, 0x40, 0x9c, 0x10, + 0x27, 0x04, 0x09, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x71, 0x01, + 0x5c, 0x40, 0x57, 0x10, 0x15, 0xc4, 0x05, 0x71, + 0x01, 0x5c, 0x40, 0x57, 0x10, 0x14, 0xc4, 0x04, + 0x31, 0x01, 0x5c, 0x40, 0x57, 0x10, 0x15, 0xc4, + 0x01, 0x71, 0x01, 0x5c, 0x40, 0x57, 0x10, 0x15, + 0xc4, 0x04, 0x31, 0x01, 0x5c, 0x40, 0x57, 0x10, + 0x15, 0xc4, 0x05, 0x71, 0x01, 0x5c, 0x40, 0x57, + 0x10, 0x15, 0xc4, 0x05, 0x71, 0x01, 0x5c, 0x40, + 0x57, 0x10, 0x15, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x4e, 0x02, 0x00, + 0x00, 0x02, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, + 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, + 0x12, 0x08, 0x05, 0x82, 0x01, 0x70, 0x80, 0x48, + 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, + 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x70, + 0x80, 0x48, 0x60, 0x12, 0x08, 0x04, 0x82, 0x01, + 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, + 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x01, 0x06, + 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18, 0x02, + 0x06, 0x00, 0x01, 0x80, 0x20, 0x60, 0x00, 0x18, + 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, + 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x60, 0x61, + 0x08, 0x18, 0x22, 0x06, 0x00, 0x01, 0x80, 0x00, + 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, + 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x04, 0x72, 0x01, 0x1c, 0x80, 0x47, + 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, 0x1c, 0x80, + 0x47, 0x21, 0x11, 0xc8, 0x00, 0x72, 0x01, 0x1c, + 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, + 0x1c, 0x80, 0x47, 0x25, 0x11, 0xc8, 0x04, 0x72, + 0x81, 0x1c, 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04, + 0x72, 0x01, 0x1c, 0x80, 0x47, 0x21, 0x11, 0xc8, + 0x04, 0x72, 0x01, 0x1c, 0x80, 0x47, 0x20, 0x11, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, + 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, + 0x06, 0x01, 0x01, 0x80, 0x04, 0x60, 0x00, 0x18, + 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, + 0x18, 0x00, 0x06, 0x00, 0x01, 0xed, 0x09, 0x00, + 0x4f, 0x02, 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, + 0x06, 0x00, 0x01, 0x80, 0x40, 0x60, 0x00, 0x18, + 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, + 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, + 0x22, 0x01, 0x08, 0x80, 0x42, 0x20, 0x10, 0x88, + 0x04, 0x22, 0x01, 0x09, 0x80, 0x42, 0x20, 0x10, + 0x98, 0x04, 0x22, 0x01, 0x08, 0x80, 0x42, 0x20, + 0x10, 0x88, 0x04, 0x22, 0x01, 0x08, 0x80, 0x42, + 0x30, 0x10, 0x98, 0x04, 0x26, 0x01, 0x09, 0x80, + 0x42, 0x20, 0x10, 0x88, 0x04, 0x22, 0x01, 0x08, + 0x80, 0x42, 0x20, 0x10, 0x88, 0x04, 0x22, 0x01, + 0x08, 0x80, 0x42, 0x20, 0x10, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x04, + 0x4a, 0x81, 0x12, 0xa0, 0x44, 0xa8, 0x11, 0x2a, + 0x04, 0x4a, 0x81, 0x12, 0xa0, 0x44, 0xa8, 0x11, + 0x2a, 0x04, 0x4a, 0x81, 0x12, 0xa0, 0x44, 0xa8, + 0x11, 0x2a, 0x04, 0x4a, 0x81, 0x12, 0xa0, 0x44, + 0xa8, 0x11, 0x2a, 0x04, 0x4a, 0x81, 0x12, 0xa1, + 0x44, 0xa8, 0x11, 0x2a, 0x04, 0x4a, 0x81, 0x12, + 0xa0, 0x44, 0xac, 0x11, 0x2a, 0x04, 0x4a, 0x81, + 0x12, 0xa0, 0x44, 0xa8, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x0c, 0x00, + 0x53, 0x00, 0x14, 0xc0, 0x05, 0x30, 0x01, 0x4c, + 0x00, 0x53, 0x00, 0x14, 0xc0, 0x05, 0x34, 0x01, + 0x6c, 0x00, 0x53, 0x00, 0x14, 0xc0, 0x05, 0x30, + 0x01, 0x4c, 0x00, 0x53, 0x00, 0x14, 0xc0, 0x05, + 0x30, 0x01, 0x6c, 0x00, 0x53, 0x00, 0x14, 0xc0, + 0x05, 0x30, 0x01, 0x4c, 0x00, 0x53, 0x00, 0x14, + 0xc0, 0x05, 0x30, 0x00, 0x4c, 0x00, 0x53, 0x00, + 0x14, 0xc0, 0x05, 0x30, 0x01, 0x40, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x50, 0x02, 0x40, 0x00, 0x10, + 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, + 0x11, 0x00, 0x04, 0x00, 0x01, 0x10, 0x00, 0x40, + 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x10, 0x00, 0x04, 0x10, 0x41, 0x10, + 0x00, 0x40, 0x00, 0x11, 0x00, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x00, 0x40, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0xc0, 0x40, 0x02, 0x00, 0x00, 0x80, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x80, 0x02, 0x20, 0x00, 0x08, 0x00, 0x22, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, + 0x22, 0x04, 0x08, 0x81, 0x02, 0x20, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, + 0x08, 0x40, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0xc0, 0x40, 0x04, 0x60, 0x01, 0x18, + 0x00, 0x06, 0x00, 0x11, 0x80, 0x04, 0x60, 0x01, + 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, 0x04, 0x60, + 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, 0x0e, + 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, + 0x04, 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, + 0x80, 0x04, 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, + 0x11, 0x80, 0x04, 0x60, 0x01, 0x18, 0x00, 0x46, + 0x00, 0x11, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x01, 0x40, 0x02, 0x60, 0x00, 0x98, + 0x00, 0x26, 0x00, 0x09, 0x80, 0x02, 0x60, 0x00, + 0x98, 0x00, 0x26, 0x00, 0x19, 0x80, 0x02, 0x70, + 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, 0x02, + 0x60, 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, + 0x02, 0x74, 0x00, 0xed, 0x09, 0x00, 0x51, 0x02, + 0x99, 0x00, 0x26, 0x00, 0x09, 0x80, 0x02, 0x60, + 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, 0x02, + 0x60, 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x82, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, + 0x42, 0x04, 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08, + 0x10, 0xc2, 0x04, 0x30, 0x81, 0x0c, 0x20, 0x43, + 0x08, 0x90, 0xd2, 0x04, 0x60, 0x81, 0x0c, 0x20, + 0x43, 0x08, 0x10, 0xc2, 0x04, 0x30, 0x81, 0x0c, + 0x20, 0x43, 0x08, 0x90, 0xd2, 0x04, 0x60, 0x81, + 0x0c, 0x20, 0x43, 0x08, 0x10, 0xc2, 0x04, 0x10, + 0x81, 0x0c, 0x20, 0x43, 0x08, 0x90, 0xc2, 0x04, + 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08, 0x10, 0xc0, + 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, + 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, + 0x01, 0x00, 0xc0, 0x00, 0x20, 0x00, 0x0c, 0x00, + 0x03, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c, + 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x20, 0x00, + 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x40, 0x10, + 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, + 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x02, 0x00, 0x30, 0x80, 0x0c, 0x20, 0x03, 0x08, + 0x00, 0xc2, 0x00, 0x30, 0x80, 0x0c, 0x20, 0x03, + 0x08, 0x10, 0xc2, 0x00, 0x30, 0x80, 0x0c, 0x20, + 0x03, 0x08, 0x00, 0xc2, 0x00, 0x30, 0x80, 0x0c, + 0x20, 0x03, 0x08, 0x00, 0xc2, 0x00, 0x30, 0x80, + 0x0c, 0x20, 0x03, 0x08, 0x00, 0xc2, 0x00, 0x30, + 0x80, 0x0c, 0x20, 0x03, 0x08, 0x00, 0xc2, 0x00, + 0x30, 0x80, 0x04, 0x20, 0x03, 0x08, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, + 0x42, 0x04, 0x60, 0x81, 0x18, 0x20, 0xed, 0x09, + 0x00, 0x52, 0x02, 0x46, 0x08, 0x11, 0x82, 0x04, + 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x01, 0x82, + 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, + 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, + 0x11, 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, + 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, + 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18, + 0x20, 0x46, 0x08, 0x11, 0x80, 0x11, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x01, 0x42, 0x00, 0x20, + 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, + 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, + 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, + 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, + 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, + 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, + 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, + 0x20, 0x02, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x01, 0x42, 0x04, 0x60, + 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, 0x04, + 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x01, 0x82, + 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, + 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, + 0x11, 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, + 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, + 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18, + 0x20, 0x46, 0x08, 0x11, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x45, 0x40, 0x04, 0x50, + 0x01, 0x14, 0x00, 0x45, 0x00, 0x11, 0x40, 0x04, + 0x50, 0x01, 0x14, 0x00, 0x45, 0x00, 0x01, 0x40, + 0x04, 0x50, 0x01, 0x14, 0x00, 0x45, 0x00, 0x11, + 0x40, 0x04, 0x50, 0x01, 0x14, 0x00, 0x45, 0x00, + 0x11, 0x40, 0x04, 0x50, 0x01, 0x14, 0x00, 0x45, + 0x00, 0xed, 0x09, 0x00, 0x53, 0x02, 0x11, 0x40, + 0x04, 0x50, 0x01, 0x14, 0x00, 0x45, 0x00, 0x11, + 0x40, 0x04, 0x50, 0x01, 0x14, 0x00, 0x45, 0x00, + 0x11, 0x42, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x06, 0x00, 0x41, 0x80, 0x10, 0x60, + 0x04, 0x18, 0x01, 0x06, 0x00, 0x41, 0x80, 0x10, + 0x60, 0x04, 0x18, 0x01, 0x06, 0x00, 0x41, 0x80, + 0x10, 0x60, 0x04, 0x18, 0x01, 0x06, 0x00, 0x41, + 0x80, 0x10, 0x60, 0x04, 0x18, 0x01, 0x06, 0x00, + 0x41, 0x80, 0x10, 0x60, 0x04, 0x18, 0x01, 0x06, + 0x00, 0x41, 0x80, 0x10, 0x60, 0x04, 0x18, 0x01, + 0x06, 0x00, 0x41, 0x80, 0x10, 0x60, 0x04, 0x18, + 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, + 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, + 0x20, 0x10, 0x00, 0x04, 0x02, 0x01, 0x00, 0x80, + 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, + 0x80, 0x40, 0x20, 0x10, 0x00, 0x04, 0x03, 0x01, + 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, + 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, + 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x45, 0x46, 0x03, 0x51, 0x80, 0xd4, 0x60, + 0x35, 0x18, 0x0d, 0x46, 0x03, 0x51, 0x80, 0xd4, + 0x64, 0x35, 0x58, 0x0d, 0x44, 0x43, 0x51, 0x80, + 0xd4, 0x60, 0x35, 0x18, 0x0d, 0x46, 0x03, 0x51, + 0x80, 0xd4, 0x60, 0x35, 0x18, 0x0d, 0x44, 0x43, + 0x51, 0x10, 0xd4, 0x44, 0x35, 0x18, 0x0d, 0x46, + 0x03, 0x51, 0x80, 0xd4, 0x60, 0x35, 0x18, 0x0d, + 0x46, 0x03, 0x51, 0x80, 0xd4, 0x60, 0x35, 0x18, + 0x0d, 0x40, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x46, 0x04, 0x71, 0x82, 0x1c, 0x60, + 0x47, 0x18, 0x11, 0xc6, 0xed, 0x09, 0x00, 0x54, + 0x02, 0x04, 0x71, 0x81, 0x1c, 0x60, 0x47, 0x18, + 0x91, 0xc6, 0x04, 0x71, 0x81, 0x1c, 0x60, 0x47, + 0x18, 0x11, 0xc6, 0x04, 0x71, 0x81, 0x1c, 0x60, + 0x47, 0x58, 0x91, 0xc6, 0x04, 0x71, 0x81, 0x1c, + 0x60, 0x47, 0x18, 0x11, 0xce, 0x04, 0x71, 0x81, + 0x1c, 0x60, 0x47, 0x18, 0x91, 0xc6, 0x04, 0x71, + 0x81, 0x1c, 0x60, 0x47, 0x18, 0x11, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x46, + 0x02, 0x71, 0x80, 0x9c, 0x60, 0x27, 0x18, 0x09, + 0xc6, 0x02, 0x71, 0x80, 0x9c, 0x60, 0x07, 0x18, + 0x01, 0xc6, 0x02, 0x71, 0x80, 0x9c, 0x60, 0x27, + 0x18, 0x09, 0xc6, 0x02, 0x71, 0x80, 0x9c, 0x60, + 0x27, 0x18, 0x09, 0xc6, 0x02, 0x71, 0x80, 0x9c, + 0x60, 0x27, 0x18, 0x09, 0xce, 0x02, 0x71, 0x80, + 0x9c, 0x60, 0x27, 0x18, 0x0d, 0xc6, 0x02, 0x71, + 0x80, 0x9c, 0x60, 0x27, 0x18, 0x09, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x45, 0x46, + 0x05, 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, + 0xc6, 0x05, 0x71, 0x81, 0x5c, 0x60, 0x17, 0x19, + 0x05, 0xc6, 0x05, 0x71, 0x81, 0x5c, 0x60, 0x57, + 0x18, 0x15, 0xc6, 0x05, 0x71, 0x80, 0x5c, 0x60, + 0x57, 0x58, 0x15, 0xc6, 0x05, 0x71, 0x81, 0x5c, + 0x60, 0x57, 0x18, 0x05, 0xc6, 0x45, 0x71, 0x81, + 0x5c, 0x60, 0x57, 0x18, 0x14, 0xc6, 0x05, 0x71, + 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc2, 0x11, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, + 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, + 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x40, + 0x04, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, + 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, + 0x12, 0x48, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48, + 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0xed, + 0x09, 0x00, 0x55, 0x02, 0x80, 0x48, 0x20, 0x12, + 0x48, 0x05, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, + 0x12, 0x08, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x06, 0x00, 0x61, 0x80, + 0x18, 0x60, 0x06, 0x18, 0x01, 0x86, 0x00, 0x61, + 0x80, 0x18, 0x60, 0x06, 0x98, 0x01, 0x86, 0x00, + 0x61, 0x80, 0x18, 0x60, 0x06, 0x18, 0x01, 0x86, + 0x00, 0x61, 0x80, 0x18, 0x60, 0x06, 0x18, 0x01, + 0x86, 0x00, 0x61, 0x80, 0x18, 0x60, 0x06, 0x18, + 0x01, 0x86, 0x00, 0x61, 0x80, 0x18, 0x60, 0x06, + 0x18, 0x01, 0x86, 0x00, 0x61, 0x80, 0x18, 0x60, + 0x06, 0x18, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x45, 0x60, 0x04, 0x78, 0x01, + 0x1e, 0x00, 0x47, 0x80, 0x11, 0xe0, 0x04, 0x78, + 0x01, 0x1e, 0x00, 0x47, 0x80, 0x91, 0xe0, 0x04, + 0x78, 0x01, 0x1e, 0x00, 0x47, 0x80, 0x11, 0xe0, + 0x04, 0x78, 0x01, 0x1e, 0x00, 0x47, 0x80, 0x11, + 0xe0, 0x04, 0x78, 0x01, 0x1e, 0x00, 0x47, 0x80, + 0x11, 0xe0, 0x04, 0x78, 0x01, 0x1e, 0x00, 0x47, + 0x80, 0x11, 0xe0, 0x04, 0x78, 0x01, 0x1e, 0x00, + 0x47, 0x80, 0x11, 0xc0, 0x11, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x01, 0x42, 0x00, 0x60, 0x80, + 0x18, 0x20, 0x06, 0x08, 0x01, 0x82, 0x00, 0x60, + 0x80, 0x18, 0x20, 0x06, 0x4a, 0x01, 0x82, 0x00, + 0x60, 0x80, 0x18, 0x20, 0x06, 0x08, 0x01, 0x82, + 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, 0x48, 0x01, + 0x82, 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, 0x08, + 0x01, 0x82, 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, + 0x48, 0x01, 0x82, 0x00, 0x60, 0x80, 0x18, 0x20, + 0x06, 0x08, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x01, 0x42, 0x04, 0x20, 0x81, + 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, + 0x81, 0x08, 0xed, 0x09, 0x00, 0x56, 0x02, 0x20, + 0x42, 0x0a, 0x10, 0x82, 0x04, 0x20, 0x81, 0x08, + 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, 0x81, + 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, + 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, + 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, + 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x45, 0x42, 0x04, 0x40, 0x81, 0x10, 0x20, 0x44, + 0x08, 0x11, 0x02, 0x04, 0x40, 0x81, 0x10, 0x20, + 0x44, 0x08, 0x11, 0x02, 0x04, 0x40, 0x81, 0x10, + 0x20, 0x44, 0x08, 0x11, 0x02, 0x04, 0x40, 0x81, + 0x10, 0x20, 0x44, 0x08, 0x11, 0x02, 0x04, 0x40, + 0x81, 0x10, 0x20, 0x44, 0x08, 0x51, 0x0a, 0x04, + 0x40, 0x81, 0x10, 0x20, 0x44, 0x08, 0x11, 0x02, + 0x04, 0x40, 0x81, 0x10, 0x20, 0x44, 0x08, 0x11, + 0x00, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x03, 0x00, 0x50, 0xc0, 0x14, 0x30, 0x05, + 0x0c, 0x01, 0x43, 0x00, 0x50, 0xc0, 0x14, 0x30, + 0x05, 0x0c, 0x00, 0x43, 0x00, 0x50, 0xc0, 0x14, + 0x30, 0x05, 0x0c, 0x01, 0x43, 0x00, 0x50, 0xc0, + 0x14, 0x30, 0x05, 0x0c, 0x01, 0x43, 0x00, 0x50, + 0xc0, 0x14, 0x30, 0x05, 0x0c, 0x01, 0x43, 0x00, + 0x50, 0xc0, 0x14, 0x30, 0x05, 0x0c, 0x01, 0x43, + 0x00, 0x50, 0xc0, 0x14, 0x30, 0x05, 0x0c, 0x01, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x08, 0x00, 0x42, 0x00, 0x10, 0x80, 0x04, + 0x20, 0x01, 0x08, 0x00, 0x42, 0x00, 0x10, 0x80, + 0x04, 0x21, 0x00, 0x48, 0x00, 0x42, 0x04, 0x10, + 0x80, 0x04, 0x20, 0x01, 0x08, 0x00, 0x42, 0x00, + 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x00, 0x42, + 0x00, 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x00, + 0x42, 0x00, 0x10, 0x81, 0x04, 0xed, 0x09, 0x00, + 0x57, 0x02, 0x20, 0x01, 0x88, 0x00, 0x42, 0x00, + 0x10, 0x80, 0x04, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x42, 0x02, + 0x00, 0x80, 0x80, 0x20, 0x20, 0x08, 0x08, 0x02, + 0x02, 0x00, 0x80, 0x80, 0x20, 0x00, 0x08, 0x80, + 0x42, 0x02, 0x00, 0x80, 0x80, 0x20, 0x20, 0x08, + 0x08, 0x02, 0x02, 0x00, 0x80, 0x00, 0x20, 0x20, + 0x08, 0x88, 0x02, 0x02, 0x00, 0xa0, 0x80, 0x28, + 0x20, 0x08, 0x00, 0x02, 0x02, 0x00, 0x80, 0x80, + 0x20, 0x20, 0x0c, 0x08, 0x02, 0x02, 0x00, 0x80, + 0x80, 0x20, 0x20, 0x08, 0x08, 0x00, 0x11, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x04, + 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, + 0x04, 0x60, 0x01, 0x18, 0x00, 0x66, 0x02, 0x19, + 0x80, 0x64, 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, + 0x11, 0x80, 0x04, 0x60, 0x01, 0x18, 0x00, 0x46, + 0x00, 0x11, 0x80, 0x44, 0x60, 0x11, 0x18, 0x04, + 0x46, 0x00, 0x11, 0x80, 0x04, 0x60, 0x01, 0x18, + 0x00, 0x46, 0x00, 0x11, 0x80, 0x04, 0x60, 0x01, + 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x02, + 0x60, 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, + 0x02, 0x60, 0x00, 0x98, 0x00, 0x26, 0x42, 0x09, + 0x80, 0x42, 0x60, 0x00, 0x98, 0x00, 0x26, 0x00, + 0x09, 0x80, 0x06, 0x60, 0x00, 0x98, 0x00, 0x26, + 0x02, 0x89, 0x80, 0x42, 0x60, 0x10, 0x98, 0x00, + 0x26, 0x00, 0x09, 0x90, 0x02, 0x60, 0x00, 0x98, + 0x00, 0x26, 0x00, 0x19, 0x80, 0x02, 0x60, 0x00, + 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x60, 0x04, + 0x38, 0x01, 0x0e, 0x00, 0x43, 0x80, 0x10, 0xe0, + 0x04, 0x38, 0x01, 0x0e, 0x00, 0x43, 0x81, 0x10, + 0xed, 0x09, 0x00, 0x58, 0x02, 0xe0, 0x24, 0x38, + 0x01, 0x0e, 0x00, 0x43, 0x80, 0x10, 0xe0, 0x04, + 0x38, 0x01, 0x0e, 0x00, 0x43, 0x80, 0x10, 0xe0, + 0x24, 0x38, 0x09, 0x0e, 0x02, 0x43, 0x80, 0x10, + 0xe0, 0x04, 0x38, 0x01, 0x0e, 0x00, 0x43, 0x84, + 0x10, 0xe0, 0x04, 0x38, 0x01, 0x0e, 0x00, 0x43, + 0x80, 0x10, 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x01, 0x01, 0x00, 0x30, 0x40, 0x0c, + 0x10, 0x03, 0x04, 0x00, 0xc1, 0x00, 0x30, 0x40, + 0x0c, 0x10, 0x03, 0x14, 0x00, 0xc1, 0x00, 0x30, + 0x40, 0x0c, 0x10, 0x03, 0x04, 0x00, 0xc1, 0x00, + 0x30, 0x40, 0x0c, 0x10, 0x03, 0x04, 0x00, 0xc1, + 0x00, 0x30, 0x40, 0x0c, 0x10, 0x03, 0x04, 0x00, + 0xc0, 0x00, 0x30, 0x40, 0x0c, 0x10, 0x03, 0x04, + 0x00, 0xc1, 0x00, 0x30, 0x40, 0x0c, 0x10, 0x03, + 0x04, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x05, 0x00, 0x31, 0x40, 0x0c, + 0x50, 0x03, 0x14, 0x00, 0xc5, 0x00, 0x31, 0x40, + 0x0c, 0x50, 0x03, 0x54, 0x00, 0xc5, 0x00, 0x31, + 0x40, 0x0c, 0x50, 0x03, 0x14, 0x00, 0xc5, 0x04, + 0x31, 0x40, 0x0c, 0x50, 0x03, 0x14, 0x00, 0xc5, + 0x20, 0x31, 0x40, 0x0c, 0x50, 0x03, 0x14, 0x00, + 0xd1, 0x00, 0x31, 0x40, 0x0c, 0x50, 0x03, 0x14, + 0x10, 0xc5, 0x00, 0x31, 0x40, 0x0c, 0x50, 0x03, + 0x14, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x45, 0x43, 0x04, 0x60, 0xc1, 0x18, + 0x30, 0x46, 0x0c, 0x11, 0x83, 0x04, 0x60, 0xc1, + 0x18, 0x30, 0x46, 0x4c, 0x11, 0x82, 0x04, 0x60, + 0xc1, 0x18, 0x30, 0x46, 0x0c, 0x11, 0x83, 0x00, + 0x60, 0xc1, 0x18, 0x30, 0x46, 0x0c, 0x11, 0x82, + 0x04, 0x60, 0xc1, 0x18, 0x30, 0x46, 0x0c, 0x11, + 0x83, 0x04, 0x60, 0xc1, 0x18, 0x30, 0x46, 0x0c, + 0x11, 0x83, 0x04, 0xed, 0x09, 0x00, 0x59, 0x02, + 0x60, 0xc1, 0x18, 0x30, 0x46, 0x0c, 0x11, 0x80, + 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0x40, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, + 0x10, 0x00, 0x80, 0x00, 0x30, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x30, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0x48, 0x44, 0x62, 0x11, 0x18, 0x84, 0x46, 0x21, + 0x11, 0x88, 0x44, 0x62, 0x11, 0x18, 0x84, 0x46, + 0x60, 0x11, 0x88, 0x44, 0x32, 0x11, 0x18, 0x84, + 0x46, 0x21, 0x11, 0x88, 0x40, 0x62, 0x11, 0x18, + 0x84, 0x46, 0x21, 0x11, 0x88, 0x44, 0x32, 0x11, + 0x18, 0x84, 0x46, 0x21, 0x11, 0x88, 0x04, 0x62, + 0x11, 0x18, 0x84, 0x46, 0x21, 0x11, 0x88, 0x44, + 0x62, 0x11, 0x18, 0x84, 0x46, 0x21, 0x11, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, + 0x40, 0x44, 0x50, 0x11, 0x14, 0x04, 0x45, 0x01, + 0x11, 0x40, 0x44, 0x50, 0x11, 0x14, 0x0c, 0x45, + 0x05, 0x11, 0x40, 0x44, 0x10, 0x11, 0x14, 0x04, + 0x45, 0x01, 0x11, 0x40, 0x40, 0x50, 0x11, 0x14, + 0x04, 0x45, 0x00, 0x11, 0x40, 0x44, 0x10, 0x11, + 0x14, 0x04, 0x45, 0x01, 0x11, 0x44, 0x44, 0x50, + 0x11, 0x14, 0x04, 0x45, 0x01, 0x01, 0x40, 0x44, + 0x50, 0x11, 0x14, 0x04, 0x45, 0x01, 0x11, 0x40, + 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, + 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x80, 0x04, + 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0xed, 0x09, + 0x00, 0x5a, 0x02, 0x10, 0x82, 0x04, 0x20, 0x81, + 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, + 0x81, 0x08, 0x20, 0x42, 0x00, 0x10, 0x80, 0x04, + 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, + 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, + 0x82, 0x04, 0x20, 0x81, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x02, + 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01, + 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, + 0x01, 0x02, 0x84, 0x40, 0xa0, 0x10, 0x28, 0x04, + 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, + 0x04, 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, 0x10, + 0x28, 0x04, 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, + 0x10, 0x28, 0x04, 0x0a, 0x01, 0x02, 0x80, 0x40, + 0xa0, 0x10, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x45, 0x4d, 0x03, 0x53, + 0x40, 0xd4, 0xd0, 0x35, 0x34, 0x0d, 0x4d, 0x03, + 0x53, 0x40, 0xd4, 0xd0, 0x35, 0x34, 0x0d, 0x4d, + 0x03, 0x53, 0x40, 0xd4, 0xd0, 0x35, 0x34, 0x0d, + 0x4d, 0x03, 0x53, 0x40, 0xd4, 0xd0, 0x35, 0x34, + 0x0d, 0x4d, 0x03, 0x53, 0x40, 0xd4, 0xd0, 0x35, + 0x34, 0x0d, 0x4d, 0x03, 0x53, 0x40, 0xd4, 0xd0, + 0x35, 0x34, 0x0d, 0x4d, 0x03, 0x53, 0x40, 0xd4, + 0xd0, 0x35, 0x34, 0x0d, 0x40, 0x11, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x01, 0x48, 0x04, 0x72, + 0x01, 0x1c, 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04, + 0x72, 0x01, 0x1c, 0x80, 0x07, 0x20, 0x11, 0xc8, + 0x04, 0x72, 0x01, 0x1c, 0x80, 0x47, 0x20, 0x11, + 0xc8, 0x04, 0x72, 0x01, 0x1c, 0x80, 0x47, 0x20, + 0x11, 0xc8, 0x04, 0x72, 0x00, 0x1c, 0x80, 0x47, + 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, 0x1c, 0x80, + 0x47, 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, 0x1c, + 0x80, 0xed, 0x09, 0x00, 0x5b, 0x02, 0x47, 0x20, + 0x11, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x23, 0x18, 0x48, 0xc6, 0x12, 0x31, + 0x84, 0x8c, 0x61, 0x23, 0x18, 0x48, 0xc6, 0x12, + 0x31, 0x04, 0x0c, 0x21, 0x23, 0x10, 0x48, 0xc6, + 0x12, 0x31, 0x84, 0x8c, 0x61, 0x23, 0x18, 0x48, + 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x21, 0x23, 0x10, + 0x48, 0xc4, 0x12, 0x31, 0x04, 0x8c, 0x61, 0x03, + 0x18, 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x21, + 0x23, 0x18, 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, + 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, + 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, + 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, + 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, + 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, + 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, + 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, + 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, + 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2c, 0xdb, 0x0b, 0x36, 0xc2, 0xcd, + 0xb0, 0xb3, 0x6c, 0x2c, 0xdb, 0x0b, 0x36, 0xc2, + 0xcd, 0xf4, 0xfb, 0x6c, 0x2c, 0xdb, 0x0b, 0x36, + 0xc2, 0xcd, 0xb0, 0xb3, 0xed, 0x09, 0x00, 0x5c, + 0x02, 0x6c, 0x2c, 0xdb, 0x0b, 0x36, 0xc2, 0xcd, + 0xb0, 0xb7, 0xec, 0x2c, 0xdb, 0x0b, 0x37, 0xd2, + 0xcd, 0xf4, 0xb3, 0x6c, 0x3e, 0xdb, 0x0b, 0x36, + 0xc2, 0xcd, 0xb0, 0xb3, 0x6c, 0x2c, 0xdb, 0x0b, + 0x36, 0xc2, 0xcd, 0xb0, 0xb3, 0x6c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, + 0x3c, 0x4c, 0xcf, 0x13, 0x33, 0xc4, 0xcc, 0xf1, + 0x33, 0x3c, 0x4c, 0xcf, 0x13, 0x33, 0xf4, 0xfc, + 0xf1, 0x33, 0x3c, 0x4c, 0xcf, 0x13, 0x33, 0xc4, + 0xcc, 0xf1, 0x33, 0x3c, 0x4c, 0xcf, 0x13, 0x33, + 0xc4, 0xcf, 0xf1, 0x33, 0x3c, 0x4c, 0xcf, 0xd3, + 0x33, 0xf4, 0xcc, 0xf1, 0x3f, 0x3c, 0x4c, 0xcf, + 0x13, 0x33, 0xc4, 0xcc, 0xf1, 0x33, 0x3c, 0x4c, + 0xcf, 0x13, 0x33, 0xc4, 0xcc, 0xf1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, + 0x7e, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed, 0xf9, + 0x3b, 0x7e, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xfc, + 0x79, 0x3b, 0x78, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, + 0xed, 0xf9, 0x3b, 0x7e, 0x4e, 0xdf, 0x93, 0xb7, + 0xe4, 0xef, 0xf9, 0x3b, 0x78, 0x4e, 0xdf, 0xd3, + 0xb7, 0xf4, 0xed, 0xf9, 0x3b, 0x7e, 0x4e, 0xdf, + 0x93, 0xb7, 0xe4, 0xec, 0x79, 0x3b, 0x7e, 0x4e, + 0xdf, 0x93, 0xb7, 0xe4, 0xed, 0xf9, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x84, 0x00, 0xa1, 0x00, 0x28, 0x40, 0x0a, 0x10, + 0x02, 0x84, 0x00, 0xa1, 0x00, 0x28, 0x40, 0x0a, + 0x10, 0x02, 0x84, 0x00, 0xa1, 0x8c, 0x28, 0x60, + 0x0a, 0x10, 0x02, 0x06, 0x24, 0x21, 0xc0, 0x08, + 0x60, 0x00, 0x14, 0x00, 0x47, 0x04, 0x20, 0x04, + 0x08, 0x40, 0x02, 0x54, 0x82, 0x84, 0x00, 0xa1, + 0x00, 0x28, 0x40, 0x0a, 0x10, 0x02, 0x84, 0x00, + 0xa1, 0x00, 0x28, 0x40, 0x0a, 0x10, 0x00, 0xed, + 0x09, 0x00, 0x5d, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x01, 0x00, 0x00, 0x51, 0x00, 0x18, 0x00, + 0x07, 0x04, 0x01, 0x40, 0x20, 0x50, 0x08, 0x10, + 0x00, 0x47, 0x14, 0x01, 0x44, 0x20, 0x70, 0x00, + 0x14, 0x40, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, + 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x84, 0x00, 0x21, + 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, + 0x21, 0x00, 0x88, 0x40, 0x22, 0x10, 0x08, 0x84, + 0x00, 0x21, 0x40, 0x08, 0x62, 0x22, 0x14, 0x00, + 0x85, 0x20, 0x11, 0x41, 0x20, 0x60, 0x01, 0x14, + 0x00, 0x85, 0x20, 0x91, 0x48, 0x28, 0x72, 0x0a, + 0x1c, 0x80, 0xc4, 0x00, 0x21, 0x00, 0x08, 0x40, + 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, + 0x40, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x01, 0x8c, 0x00, 0x60, 0x00, 0x14, 0x00, + 0x04, 0x20, 0x81, 0x41, 0x20, 0x60, 0x01, 0x14, + 0x02, 0x07, 0x20, 0x01, 0x83, 0x20, 0x62, 0x00, + 0x1c, 0x80, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, + 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x20, + 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, + 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x83, + 0x32, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, + 0x80, 0x06, 0xed, 0x09, 0x00, 0x5e, 0x02, 0xa0, + 0x8d, 0x88, 0x23, 0x21, 0x08, 0x88, 0x01, 0x06, + 0x20, 0xc2, 0x84, 0x10, 0x22, 0x44, 0xc8, 0x83, + 0x12, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, + 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x08, 0x00, 0x02, 0x02, 0x00, 0x00, + 0x40, 0x00, 0x10, 0x01, 0x04, 0x82, 0x41, 0x00, + 0x40, 0xc0, 0x00, 0x33, 0x08, 0x0c, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, + 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x88, + 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, + 0x88, 0x02, 0x22, 0x00, 0x08, 0x01, 0x06, 0x20, + 0xc0, 0xa8, 0x10, 0x20, 0x0c, 0xca, 0x83, 0x06, + 0xa0, 0xcb, 0xa0, 0x13, 0x22, 0x0c, 0x88, 0xc0, + 0x22, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, + 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x32, 0x80, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, + 0x00, 0xa0, 0x30, 0x28, 0x04, 0xc0, 0x01, 0x0a, + 0x80, 0x88, 0x84, 0x31, 0x20, 0x04, 0xc9, 0x03, + 0x10, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x5f, 0x02, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x84, + 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x2a, 0x10, 0x0a, + 0x84, 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x2a, 0x00, + 0x0a, 0x85, 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x22, + 0x14, 0xc8, 0x05, 0x22, 0x11, 0x01, 0x88, 0x51, + 0x22, 0x10, 0x08, 0x44, 0x02, 0x01, 0x84, 0x84, + 0x10, 0x21, 0x1c, 0x0a, 0x84, 0x02, 0xb1, 0x00, + 0xa8, 0x40, 0x2a, 0x10, 0x0a, 0x84, 0x02, 0xa1, + 0x00, 0xa8, 0x40, 0x2a, 0x10, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x04, + 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, + 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x18, + 0x48, 0x06, 0x02, 0x11, 0x00, 0x80, 0x50, 0x28, + 0x14, 0x08, 0x04, 0x1a, 0x81, 0x41, 0x80, 0x52, + 0x20, 0x18, 0x08, 0x47, 0x0a, 0x01, 0xcc, 0x84, + 0x71, 0x29, 0x14, 0x08, 0x05, 0x02, 0x01, 0x00, + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, + 0x00, 0x80, 0x40, 0x20, 0x10, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, + 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, + 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x18, + 0x40, 0x85, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, + 0x10, 0x02, 0x05, 0x20, 0x21, 0x82, 0x08, 0x73, + 0x02, 0x14, 0x02, 0x45, 0x00, 0x21, 0x4e, 0x28, + 0x71, 0x02, 0x1c, 0x00, 0x86, 0x00, 0x21, 0x00, + 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, + 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x07, + 0x30, 0x01, 0xcc, 0x00, 0x73, 0x00, 0x1c, 0xc0, + 0x07, 0x30, 0x01, 0x00, 0x00, 0x73, 0x00, 0x1c, + 0xc0, 0x07, 0x30, 0x01, 0xcc, 0x00, 0x60, 0x00, + 0x14, 0xd0, 0x07, 0x30, 0x01, 0x4e, 0x20, 0x63, + 0xed, 0x09, 0x00, 0x60, 0x02, 0x40, 0x18, 0xd0, + 0x46, 0x00, 0x81, 0x46, 0x20, 0x73, 0x40, 0x14, + 0xc0, 0x05, 0x30, 0x05, 0x00, 0x00, 0x73, 0x00, + 0x1c, 0xc0, 0x07, 0x30, 0x01, 0xcc, 0x00, 0x73, + 0x00, 0x1c, 0xc2, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x84, 0x00, 0x21, 0x00, + 0x08, 0x73, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, + 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, + 0x21, 0x00, 0x08, 0x52, 0x09, 0x1c, 0xf0, 0x84, + 0x00, 0x91, 0x48, 0x28, 0x40, 0x00, 0x18, 0x32, + 0x84, 0x38, 0xa1, 0x4c, 0x08, 0x40, 0x0a, 0x1c, + 0xc0, 0x44, 0x00, 0x31, 0xcc, 0x08, 0x73, 0x02, + 0x14, 0x80, 0x84, 0x00, 0x21, 0x00, 0x08, 0x73, + 0x02, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x40, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x21, 0x01, 0x14, 0x02, 0x01, + 0x00, 0x10, 0xc0, 0x00, 0x30, 0x09, 0x04, 0x00, + 0x07, 0x00, 0x41, 0xc0, 0x00, 0x10, 0x40, 0x18, + 0x02, 0x40, 0x00, 0x81, 0x00, 0x20, 0x40, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x40, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, + 0x08, 0x40, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x08, 0x12, 0x0a, 0x18, 0x02, 0x82, + 0x0c, 0x00, 0xc9, 0x20, 0x10, 0x8a, 0x08, 0x00, + 0x87, 0x2c, 0xa1, 0x41, 0x00, 0x22, 0x0a, 0x14, + 0x00, 0x80, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, + 0x04, 0x80, 0x80, 0x00, 0x20, 0x00, 0x08, 0x40, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0xed, 0x09, 0x00, 0x61, 0x02, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x0c, 0xc0, 0x02, 0x04, 0x00, 0x8a, + 0x00, 0x30, 0x40, 0x08, 0x00, 0x01, 0x30, 0x00, + 0x02, 0x24, 0x22, 0x48, 0x08, 0xc0, 0x00, 0x00, + 0x00, 0xcc, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x80, 0xb0, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x80, 0x80, 0x80, 0x00, + 0x00, 0x10, 0x10, 0x10, 0xd0, 0x80, 0x80, 0x80, + 0x00, 0x00, 0x10, 0x10, 0x10, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0x99, 0x91, 0xf8, 0xa1, 0xac, 0x80, + 0x28, 0xea, 0xf7, 0xad, 0xf7, 0x37, 0xed, 0x09, + 0x00, 0x62, 0x02, 0x13, 0x2a, 0xc0, 0x3c, 0x52, + 0xdc, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x03, 0x81, 0xd3, 0x40, 0x1e, 0xa6, 0xc7, + 0x32, 0xd1, 0x47, 0x18, 0xd5, 0x00, 0x04, 0xea, + 0xbc, 0xa4, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xe1, 0x52, 0x12, 0x08, 0xa2, 0x91, 0x32, + 0x14, 0x12, 0x11, 0x42, 0x91, 0x48, 0xb2, 0x01, + 0x81, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xbf, 0xbf, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xf7, 0xff, 0x7f, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xed, 0x09, 0x00, 0x63, 0x02, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x7d, + 0xfb, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x37, 0xfe, + 0xff, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xdf, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x32, 0xfe, 0xf5, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xbf, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0x6f, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf7, 0xfe, + 0xdf, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xbf, + 0xef, 0xff, 0xc0, 0x00, 0xed, 0x09, 0x00, 0x64, + 0x02, 0x00, 0x00, 0x00, 0x3f, 0xbf, 0xed, 0xfb, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xef, 0xff, 0xef, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x37, 0xfe, 0x7f, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x84, 0x00, 0xa1, 0x00, 0x28, 0x40, 0x0a, 0x10, + 0x02, 0x84, 0x00, 0xa1, 0x00, 0x28, 0x40, 0x0a, + 0x10, 0x02, 0x84, 0x00, 0xa1, 0x00, 0x28, 0x40, + 0x0a, 0x10, 0x02, 0x84, 0x00, 0xa1, 0x00, 0x28, + 0x40, 0x0a, 0x10, 0x02, 0x84, 0x00, 0xa1, 0x00, + 0x28, 0x40, 0x0a, 0x10, 0x02, 0x84, 0x00, 0xa1, + 0x00, 0x28, 0x40, 0x0a, 0x10, 0x02, 0x84, 0x00, + 0xa1, 0x00, 0x28, 0x40, 0x0a, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, + 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, + 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, + 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, + 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0xed, + 0x09, 0x00, 0x65, 0x02, 0x10, 0x00, 0x84, 0x00, + 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, + 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, + 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, + 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, + 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, + 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, + 0x40, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, + 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, + 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, + 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x20, + 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, + 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, + 0x02, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, + 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, + 0x08, 0x80, 0x02, 0x20, 0x00, 0x08, 0x00, 0x22, + 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, + 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x88, + 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x02, 0xed, 0x09, 0x00, 0x66, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, + 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x88, + 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, + 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, + 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, + 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, + 0x02, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, + 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x0a, 0x84, 0x02, 0xa1, 0x00, 0xa8, 0x40, + 0x2a, 0x10, 0x0a, 0x84, 0x02, 0xa1, 0x00, 0xa8, + 0x40, 0x2a, 0x1c, 0xca, 0x84, 0x02, 0xa1, 0x00, + 0xa8, 0x40, 0x2a, 0x1c, 0xca, 0x84, 0x02, 0xa1, + 0x00, 0xa8, 0x40, 0x2a, 0x10, 0x0a, 0x84, 0x02, + 0xa1, 0x00, 0xa8, 0x40, 0x2a, 0x10, 0x0a, 0x84, + 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x2a, 0x10, 0x0a, + 0x84, 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x2a, 0x10, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, + 0x20, 0x10, 0x08, 0x04, 0x02, 0xed, 0x09, 0x00, + 0x67, 0x02, 0x01, 0x00, 0x80, 0x40, 0x00, 0x10, + 0x00, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, + 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, + 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, + 0x00, 0x80, 0x40, 0x20, 0x10, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, + 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, + 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, + 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, + 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, + 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, + 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, + 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, + 0x00, 0x08, 0x40, 0x02, 0x10, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x07, + 0x30, 0x01, 0xcc, 0x00, 0x73, 0x00, 0x1c, 0xc0, + 0x07, 0x30, 0x01, 0xcc, 0x00, 0x73, 0x00, 0x1c, + 0xc0, 0x07, 0x30, 0x01, 0xcc, 0x00, 0x73, 0x00, + 0x1c, 0xc0, 0x07, 0x30, 0x01, 0xcc, 0x00, 0x73, + 0x00, 0x1c, 0xc0, 0x07, 0x30, 0x01, 0xcc, 0x00, + 0x73, 0x00, 0x1c, 0xc0, 0x07, 0x30, 0x01, 0x00, + 0x00, 0x73, 0x00, 0x1c, 0xc0, 0x07, 0x30, 0x01, + 0xcc, 0x00, 0x73, 0x00, 0x1c, 0xc2, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x84, + 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, + 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, + 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, + 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, + 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, + 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, + 0xed, 0x09, 0x00, 0x68, 0x02, 0x08, 0x40, 0x02, + 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, + 0x02, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x69, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x6a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xed, 0x09, 0x00, 0x6b, 0x02, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xed, 0x09, 0x00, 0x6c, + 0x02, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x20, + 0x01, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x44, + 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x6d, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x6e, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x6f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x70, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x71, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x72, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x73, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x74, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x75, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x76, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x77, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x78, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x79, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x7a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x7b, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x7c, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x7d, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x7e, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x20, 0x01, 0x02, + 0x02, 0x00, 0x00, 0x30, 0x00, 0x44, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x7f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x81, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x83, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x84, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x85, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x86, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x87, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x88, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x89, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x8a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x8b, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x8c, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x8d, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x8e, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x8f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0xed, 0x09, 0x00, 0x91, 0x02, + 0x00, 0x01, 0x00, 0x00, 0x93, 0x80, 0x30, 0x00, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x03, 0x30, 0x00, + 0x40, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x80, 0x01, 0x00, 0x00, + 0x00, 0x05, 0x30, 0x00, 0xa0, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, + 0xf8, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x00, 0x00, 0x70, 0x56, 0xaf, 0x12, 0xd7, + 0x35, 0x42, 0x01, 0x00, 0x00, 0x00, 0x20, 0xd0, + 0xb2, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0xea, 0xd0, + 0xb2, 0x03, 0x20, 0xf4, 0x17, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x20, 0x70, 0x65, 0x03, 0x20, 0x70, + 0x65, 0x03, 0x20, 0xf4, 0x17, 0x04, 0x20, 0x70, + 0x65, 0x03, 0x20, 0xf4, 0x17, 0x04, 0x20, 0x70, + 0x65, 0x03, 0x20, 0xbc, 0x65, 0x03, 0x20, 0xc0, + 0x65, 0x03, 0x20, 0xc4, 0x65, 0x03, 0x20, 0xec, + 0x66, 0x03, 0x20, 0x84, 0x65, 0x03, 0x20, 0x00, + 0x00, 0xa0, 0xe3, 0x10, 0x0f, 0x01, 0xee, 0x13, + 0xe0, 0xa0, 0xe3, 0xc0, 0xe0, 0x8e, 0xe2, 0x0e, + 0xf0, 0x21, 0xe1, 0x0e, 0xf0, 0x6f, 0xe1, 0x08, + 0x01, 0x9f, 0xe5, 0x00, 0xf0, 0xa0, 0xe1, 0x6a, + 0x00, 0x00, 0xeb, 0x5c, 0x00, 0x00, 0xeb, 0x4c, + 0x00, 0x1f, 0xe5, 0x04, 0x00, 0x80, 0xe2, 0x01, + 0x1a, 0xa0, 0xe3, 0x04, 0x10, 0x41, 0xe2, 0x01, + 0x20, 0x80, 0xe0, 0x03, 0x20, 0xc2, 0xe3, 0x00, + 0xa0, 0xa0, 0xe1, 0x50, 0x30, 0x1f, 0xe5, 0x00, + 0xa0, 0x83, 0xe5, 0x02, 0xd0, 0xa0, 0xe1, 0x60, + 0x30, 0x1f, 0xe5, 0x00, 0xd0, 0x83, 0xe5, 0x02, + 0x50, 0xa0, 0xe1, 0x01, 0x0a, 0xa0, 0xe3, 0x31, + 0x00, 0x00, 0xeb, 0x37, 0x00, 0x00, 0xeb, 0x3c, + 0x00, 0x00, 0xeb, 0x42, 0x00, 0x00, 0xeb, 0x05, + 0x20, 0xa0, 0xe1, 0x90, 0x30, 0x1f, 0xe5, 0x04, + 0x20, 0x82, 0xe2, 0x00, 0x20, 0x83, 0xe5, 0x02, + 0x1b, 0xa0, 0xe3, 0x03, 0x10, 0xc1, 0xe3, 0x01, + 0x20, 0x82, 0xe0, 0xa4, 0x30, 0x1f, 0xe5, 0x00, + 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0xac, + 0x30, 0x1f, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x0f, + 0x00, 0x2d, 0xe9, 0xb3, 0xd5, 0x00, 0xeb, 0x63, + 0x45, 0xed, 0x09, 0x00, 0x01, 0x00, 0x00, 0xeb, + 0xb4, 0xd5, 0x00, 0xeb, 0x0f, 0x00, 0xbd, 0xe8, + 0x02, 0x00, 0xa0, 0xe1, 0xb4, 0xd5, 0x00, 0xea, + 0x02, 0x00, 0x2d, 0xe9, 0x00, 0x10, 0x4f, 0xe1, + 0x80, 0x00, 0x11, 0xe3, 0x02, 0x00, 0xbd, 0xe8, + 0x04, 0xf0, 0x5e, 0x12, 0x0f, 0x00, 0x2d, 0xe9, + 0x04, 0x30, 0x4e, 0xe2, 0x59, 0x48, 0x00, 0xeb, + 0xae, 0xd5, 0x00, 0xeb, 0x9d, 0x48, 0x00, 0xea, + 0x02, 0x00, 0x2d, 0xe9, 0x00, 0x10, 0x4f, 0xe1, + 0x40, 0x00, 0x11, 0xe3, 0x02, 0x00, 0xbd, 0xe8, + 0x04, 0xf0, 0x5e, 0x12, 0x0f, 0x00, 0x2d, 0xe9, + 0x04, 0x30, 0x4e, 0xe2, 0x4f, 0x48, 0x00, 0xeb, + 0xa7, 0xd5, 0x00, 0xeb, 0x93, 0x48, 0x00, 0xea, + 0x00, 0x00, 0xa0, 0xe3, 0x10, 0x0f, 0x01, 0xee, + 0x00, 0x00, 0xa0, 0xe3, 0x0e, 0x12, 0xa0, 0xe3, + 0x00, 0x00, 0x81, 0xe5, 0x00, 0xf0, 0xa0, 0xe1, + 0xf8, 0xff, 0xff, 0xea, 0x5c, 0x00, 0x00, 0x20, + 0x02, 0x0b, 0x80, 0xe2, 0xd2, 0x10, 0xa0, 0xe3, + 0x01, 0xf0, 0x21, 0xe1, 0x00, 0xd0, 0xa0, 0xe1, + 0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, + 0x1e, 0xff, 0x2f, 0xe1, 0xd1, 0x10, 0xa0, 0xe3, + 0x01, 0xf0, 0x21, 0xe1, 0x00, 0xd0, 0xa0, 0xe1, + 0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, + 0x1e, 0xff, 0x2f, 0xe1, 0x02, 0x0b, 0x80, 0xe2, + 0xd7, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, + 0x00, 0xd0, 0xa0, 0xe1, 0xd3, 0x10, 0xa0, 0xe3, + 0x01, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, + 0x02, 0x0b, 0x80, 0xe2, 0xdb, 0x10, 0xa0, 0xe3, + 0x01, 0xf0, 0x21, 0xe1, 0x00, 0xd0, 0xa0, 0xe1, + 0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, + 0x1e, 0xff, 0x2f, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, + 0x24, 0x00, 0x9f, 0xe5, 0x24, 0x10, 0x9f, 0xe5, + 0x00, 0x00, 0x90, 0xe5, 0xed, 0x09, 0x00, 0x02, + 0x00, 0x00, 0x10, 0x91, 0xe5, 0x00, 0x20, 0xa0, + 0xe3, 0x01, 0x00, 0x50, 0xe1, 0x1e, 0xff, 0x2f, + 0x21, 0x04, 0x20, 0x80, 0xe4, 0x01, 0x00, 0x50, + 0xe1, 0xfc, 0xff, 0xff, 0x3a, 0x1e, 0xff, 0x2f, + 0xe1, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, + 0x20, 0x30, 0x00, 0x9f, 0xe5, 0x14, 0x20, 0x1f, + 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x28, 0x00, 0x9f, + 0xe5, 0x00, 0x00, 0x90, 0xe5, 0x00, 0x30, 0x92, + 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x1e, 0xff, 0x2f, + 0x21, 0x04, 0x30, 0x91, 0xe4, 0x04, 0x30, 0x80, + 0xe4, 0x00, 0x30, 0x92, 0xe5, 0x03, 0x00, 0x50, + 0xe1, 0xfa, 0xff, 0xff, 0x3a, 0x1e, 0xff, 0x2f, + 0xe1, 0x10, 0x00, 0x00, 0x20, 0x14, 0x00, 0x00, + 0x20, 0x78, 0x47, 0x00, 0x00, 0x00, 0x20, 0xa0, + 0xe3, 0xa1, 0xc1, 0x70, 0xe0, 0x20, 0x00, 0x00, + 0x3a, 0x21, 0xc4, 0x70, 0xe0, 0x0f, 0x00, 0x00, + 0x3a, 0x00, 0x04, 0xa0, 0xe1, 0xff, 0x24, 0x82, + 0xe3, 0x21, 0xc2, 0x70, 0xe0, 0x17, 0x00, 0x00, + 0x3a, 0x21, 0xc4, 0x70, 0xe0, 0x09, 0x00, 0x00, + 0x3a, 0x00, 0x04, 0xa0, 0xe1, 0xff, 0x28, 0x82, + 0xe3, 0x21, 0xc4, 0x70, 0xe0, 0x00, 0x04, 0xa0, + 0x21, 0xff, 0x2c, 0x82, 0x23, 0x21, 0xc2, 0x70, + 0xe0, 0x0e, 0x00, 0x00, 0x3a, 0x00, 0xc0, 0x70, + 0xe2, 0x32, 0x01, 0x00, 0x2a, 0x20, 0x04, 0xa0, + 0x21, 0xa1, 0xc3, 0x70, 0xe0, 0x80, 0x13, 0x41, + 0x20, 0x02, 0x20, 0xa2, 0xe0, 0x21, 0xc3, 0x70, + 0xe0, 0x00, 0x13, 0x41, 0x20, 0x02, 0x20, 0xa2, + 0xe0, 0xa1, 0xc2, 0x70, 0xe0, 0x80, 0x12, 0x41, + 0x20, 0x02, 0x20, 0xa2, 0xe0, 0x21, 0xc2, 0x70, + 0xe0, 0x00, 0x12, 0x41, 0x20, 0x02, 0x20, 0xa2, + 0xe0, 0xa1, 0xc1, 0x70, 0xe0, 0x80, 0x11, 0x41, + 0x20, 0x02, 0x20, 0xa2, 0xe0, 0x21, 0xc1, 0xed, + 0x09, 0x00, 0x03, 0x00, 0x70, 0xe0, 0x00, 0x11, + 0x41, 0x20, 0x02, 0x20, 0xa2, 0xe0, 0xa1, 0xc0, + 0x70, 0xe0, 0x80, 0x10, 0x41, 0x20, 0x02, 0x20, + 0xa2, 0xe0, 0x01, 0xc0, 0x70, 0xe0, 0x00, 0x10, + 0x41, 0x20, 0x02, 0x20, 0xb2, 0xe0, 0xe5, 0xff, + 0xff, 0x2a, 0x02, 0x00, 0xa0, 0xe1, 0x1e, 0xff, + 0x2f, 0xe1, 0x78, 0x47, 0x00, 0x00, 0x01, 0xe0, + 0x8e, 0xe3, 0x01, 0x40, 0x2d, 0xe9, 0x04, 0x20, + 0x52, 0xe2, 0x1c, 0x00, 0x00, 0x4a, 0x03, 0xc0, + 0x10, 0xe2, 0x23, 0x00, 0x00, 0x1a, 0xff, 0x10, + 0x01, 0xe2, 0x01, 0x14, 0x81, 0xe1, 0x01, 0x18, + 0x81, 0xe1, 0x01, 0x30, 0xa0, 0xe1, 0x01, 0xc0, + 0xa0, 0xe1, 0x01, 0xe0, 0xa0, 0xe1, 0x08, 0x20, + 0x52, 0xe2, 0x0c, 0x00, 0x00, 0xba, 0x14, 0x20, + 0x52, 0xe2, 0x06, 0x00, 0x00, 0xba, 0x0a, 0x50, + 0xa0, 0xe8, 0x0a, 0x50, 0xa0, 0xe8, 0x20, 0x20, + 0x52, 0xe2, 0xfb, 0xff, 0xff, 0xaa, 0x10, 0x00, + 0x72, 0xe3, 0x0a, 0x50, 0xa0, 0xa8, 0x10, 0x20, + 0x42, 0xa2, 0x14, 0x20, 0x92, 0xe2, 0x08, 0x50, + 0xa0, 0xa8, 0x0c, 0x20, 0x52, 0xa2, 0xfc, 0xff, + 0xff, 0xaa, 0x08, 0x20, 0x92, 0xe2, 0x03, 0x00, + 0x00, 0xba, 0x04, 0x20, 0x52, 0xe2, 0x04, 0x10, + 0x80, 0xb4, 0x0a, 0x00, 0xa0, 0xa8, 0x04, 0x20, + 0x42, 0xa2, 0x04, 0x20, 0x92, 0xe2, 0x01, 0x40, + 0xbd, 0x08, 0x1e, 0xff, 0x2f, 0x01, 0x02, 0x00, + 0x52, 0xe3, 0x01, 0x10, 0xc0, 0xe4, 0x01, 0x10, + 0xc0, 0xa4, 0x01, 0x10, 0xc0, 0xc4, 0x01, 0x40, + 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x04, 0xc0, + 0x6c, 0xe2, 0x02, 0x00, 0x5c, 0xe3, 0x01, 0x10, + 0xc0, 0xe4, 0x01, 0x10, 0xc0, 0xa4, 0x01, 0x10, + 0xc0, 0xc4, 0x0c, 0x20, 0x52, 0xe0, 0xef, 0xff, + 0xff, 0xba, 0xd3, 0xff, 0xff, 0xea, 0x00, 0x47, + 0x08, 0x47, 0xed, 0x09, 0x00, 0x04, 0x00, 0x10, + 0x47, 0x18, 0x47, 0x20, 0x47, 0x28, 0x47, 0x30, + 0x47, 0x38, 0x47, 0x78, 0x47, 0x00, 0x00, 0x03, + 0x00, 0x51, 0xe1, 0x01, 0x00, 0xa0, 0xb3, 0x00, + 0x00, 0xa0, 0xc3, 0x1e, 0xff, 0x2f, 0x11, 0x02, + 0x00, 0x50, 0xe1, 0x01, 0x00, 0xa0, 0x33, 0x00, + 0x00, 0xa0, 0x23, 0x1e, 0xff, 0x2f, 0xe1, 0x78, + 0x47, 0x00, 0x00, 0x02, 0x00, 0x70, 0xe0, 0x00, + 0x10, 0xe1, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x78, + 0x47, 0x00, 0x00, 0x01, 0xe0, 0x8e, 0xe3, 0x01, + 0x40, 0x2d, 0xe9, 0x04, 0x20, 0x52, 0xe2, 0x20, + 0x00, 0x00, 0xba, 0x03, 0xc0, 0x10, 0xe2, 0x2a, + 0x00, 0x00, 0x1a, 0x03, 0xc0, 0x11, 0xe2, 0x34, + 0x00, 0x00, 0x1a, 0x08, 0x20, 0x52, 0xe2, 0x12, + 0x00, 0x00, 0xba, 0x14, 0x20, 0x52, 0xe2, 0x0b, + 0x00, 0x00, 0xba, 0x10, 0x00, 0x2d, 0xe9, 0x18, + 0x50, 0xb1, 0xe8, 0x18, 0x50, 0xa0, 0xe8, 0x18, + 0x50, 0xb1, 0xe8, 0x18, 0x50, 0xa0, 0xe8, 0x20, + 0x20, 0x52, 0xe2, 0xf9, 0xff, 0xff, 0xaa, 0x10, + 0x00, 0x72, 0xe3, 0x18, 0x50, 0xb1, 0xa8, 0x18, + 0x50, 0xa0, 0xa8, 0x10, 0x20, 0x42, 0xa2, 0x10, + 0x00, 0xbd, 0xe8, 0x14, 0x20, 0x92, 0xe2, 0x08, + 0x50, 0xb1, 0xa8, 0x08, 0x50, 0xa0, 0xa8, 0x0c, + 0x20, 0x52, 0xa2, 0xfb, 0xff, 0xff, 0xaa, 0x08, + 0x20, 0x92, 0xe2, 0x05, 0x00, 0x00, 0xba, 0x04, + 0x20, 0x52, 0xe2, 0x04, 0x30, 0x91, 0xb4, 0x04, + 0x30, 0x80, 0xb4, 0x08, 0x10, 0xb1, 0xa8, 0x08, + 0x10, 0xa0, 0xa8, 0x04, 0x20, 0x42, 0xa2, 0x04, + 0x20, 0x92, 0xe2, 0x01, 0x40, 0xbd, 0x08, 0x1e, + 0xff, 0x2f, 0x01, 0x02, 0x00, 0x52, 0xe3, 0x01, + 0x30, 0xd1, 0xe4, 0x01, 0x30, 0xc0, 0xe4, 0x01, + 0x30, 0xd1, 0xa4, 0x01, 0x30, 0xc0, 0xa4, 0x01, + 0x30, 0xd1, 0xc4, 0x01, 0x30, 0xed, 0x09, 0x00, + 0x05, 0x00, 0xc0, 0xc4, 0x01, 0x40, 0xbd, 0xe8, + 0x1e, 0xff, 0x2f, 0xe1, 0x04, 0xc0, 0x6c, 0xe2, + 0x02, 0x00, 0x5c, 0xe3, 0x01, 0x30, 0xd1, 0xe4, + 0x01, 0x30, 0xc0, 0xe4, 0x01, 0x30, 0xd1, 0xa4, + 0x01, 0x30, 0xc0, 0xa4, 0x01, 0x30, 0xd1, 0xc4, + 0x01, 0x30, 0xc0, 0xc4, 0x0c, 0x20, 0x52, 0xe0, + 0xe9, 0xff, 0xff, 0xba, 0x03, 0xc0, 0x11, 0xe2, + 0xca, 0xff, 0xff, 0x0a, 0x03, 0x10, 0xc1, 0xe3, + 0x04, 0xe0, 0x91, 0xe4, 0x02, 0x00, 0x5c, 0xe3, + 0x36, 0x00, 0x00, 0xca, 0x1a, 0x00, 0x00, 0x0a, + 0x0c, 0x00, 0x52, 0xe3, 0x10, 0x00, 0x00, 0xba, + 0x0c, 0x20, 0x42, 0xe2, 0x30, 0x00, 0x2d, 0xe9, + 0x2e, 0x34, 0xa0, 0xe1, 0x30, 0x50, 0xb1, 0xe8, + 0x04, 0x3c, 0x83, 0xe1, 0x24, 0x44, 0xa0, 0xe1, + 0x05, 0x4c, 0x84, 0xe1, 0x25, 0x54, 0xa0, 0xe1, + 0x0c, 0x5c, 0x85, 0xe1, 0x2c, 0xc4, 0xa0, 0xe1, + 0x0e, 0xcc, 0x8c, 0xe1, 0x38, 0x10, 0xa0, 0xe8, + 0x10, 0x20, 0x52, 0xe2, 0xf3, 0xff, 0xff, 0xaa, + 0x30, 0x00, 0xbd, 0xe8, 0x0c, 0x20, 0x92, 0xe2, + 0x05, 0x00, 0x00, 0xba, 0x2e, 0xc4, 0xa0, 0xe1, + 0x04, 0xe0, 0x91, 0xe4, 0x0e, 0xcc, 0x8c, 0xe1, + 0x04, 0xc0, 0x80, 0xe4, 0x04, 0x20, 0x52, 0xe2, + 0xf9, 0xff, 0xff, 0xaa, 0x03, 0x10, 0x41, 0xe2, + 0xc7, 0xff, 0xff, 0xea, 0x0c, 0x00, 0x52, 0xe3, + 0x10, 0x00, 0x00, 0xba, 0x0c, 0x20, 0x42, 0xe2, + 0x30, 0x00, 0x2d, 0xe9, 0x2e, 0x38, 0xa0, 0xe1, + 0x30, 0x50, 0xb1, 0xe8, 0x04, 0x38, 0x83, 0xe1, + 0x24, 0x48, 0xa0, 0xe1, 0x05, 0x48, 0x84, 0xe1, + 0x25, 0x58, 0xa0, 0xe1, 0x0c, 0x58, 0x85, 0xe1, + 0x2c, 0xc8, 0xa0, 0xe1, 0x0e, 0xc8, 0x8c, 0xe1, + 0x38, 0x10, 0xa0, 0xe8, 0x10, 0x20, 0x52, 0xe2, + 0xf3, 0xff, 0xff, 0xaa, 0x30, 0x00, 0xbd, 0xe8, + 0xed, 0x09, 0x00, 0x06, 0x00, 0x0c, 0x20, 0x92, + 0xe2, 0x05, 0x00, 0x00, 0xba, 0x2e, 0xc8, 0xa0, + 0xe1, 0x04, 0xe0, 0x91, 0xe4, 0x0e, 0xc8, 0x8c, + 0xe1, 0x04, 0xc0, 0x80, 0xe4, 0x04, 0x20, 0x52, + 0xe2, 0xf9, 0xff, 0xff, 0xaa, 0x02, 0x10, 0x41, + 0xe2, 0xac, 0xff, 0xff, 0xea, 0x0c, 0x00, 0x52, + 0xe3, 0x10, 0x00, 0x00, 0xba, 0x0c, 0x20, 0x42, + 0xe2, 0x30, 0x00, 0x2d, 0xe9, 0x2e, 0x3c, 0xa0, + 0xe1, 0x30, 0x50, 0xb1, 0xe8, 0x04, 0x34, 0x83, + 0xe1, 0x24, 0x4c, 0xa0, 0xe1, 0x05, 0x44, 0x84, + 0xe1, 0x25, 0x5c, 0xa0, 0xe1, 0x0c, 0x54, 0x85, + 0xe1, 0x2c, 0xcc, 0xa0, 0xe1, 0x0e, 0xc4, 0x8c, + 0xe1, 0x38, 0x10, 0xa0, 0xe8, 0x10, 0x20, 0x52, + 0xe2, 0xf3, 0xff, 0xff, 0xaa, 0x30, 0x00, 0xbd, + 0xe8, 0x0c, 0x20, 0x92, 0xe2, 0x05, 0x00, 0x00, + 0xba, 0x2e, 0xcc, 0xa0, 0xe1, 0x04, 0xe0, 0x91, + 0xe4, 0x0e, 0xc4, 0x8c, 0xe1, 0x04, 0xc0, 0x80, + 0xe4, 0x04, 0x20, 0x52, 0xe2, 0xf9, 0xff, 0xff, + 0xaa, 0x01, 0x10, 0x41, 0xe2, 0x91, 0xff, 0xff, + 0xea, 0x78, 0x47, 0x00, 0x00, 0x03, 0x00, 0x51, + 0xe1, 0x02, 0x00, 0x50, 0x01, 0x01, 0x00, 0xa0, + 0x03, 0x00, 0x00, 0xa0, 0x13, 0x1e, 0xff, 0x2f, + 0xe1, 0x78, 0x47, 0x00, 0x00, 0x0a, 0x10, 0x40, + 0xe2, 0x20, 0x01, 0x40, 0xe0, 0x20, 0x02, 0x80, + 0xe0, 0x20, 0x04, 0x80, 0xe0, 0x20, 0x08, 0x80, + 0xe0, 0xa0, 0x01, 0xa0, 0xe1, 0x00, 0x21, 0x80, + 0xe0, 0x82, 0x10, 0x51, 0xe0, 0x01, 0x00, 0x80, + 0x52, 0x0a, 0x10, 0x81, 0x42, 0x1e, 0xff, 0x2f, + 0xe1, 0x78, 0x47, 0x00, 0x00, 0x00, 0x30, 0xa0, + 0xe3, 0x38, 0x00, 0x00, 0xea, 0x78, 0x47, 0x00, + 0x00, 0x03, 0x00, 0x10, 0xe3, 0x03, 0x00, 0x11, + 0x03, 0x17, 0x00, 0x00, 0x1a, 0x04, 0xe0, 0x2d, + 0xe5, 0x84, 0xe0, 0xed, 0x09, 0x00, 0x07, 0x00, + 0x9f, 0xe5, 0x04, 0x20, 0x90, 0xe4, 0x04, 0x30, + 0x91, 0xe4, 0x0e, 0xc0, 0x42, 0xe0, 0x02, 0xc0, + 0xcc, 0xe1, 0x8e, 0xc3, 0x1c, 0xe0, 0x03, 0x00, + 0x52, 0x01, 0xf8, 0xff, 0xff, 0x0a, 0x04, 0xe0, + 0x9d, 0xe4, 0x03, 0x0c, 0xa0, 0xe1, 0x02, 0x0c, + 0x50, 0xe0, 0xff, 0x0e, 0x1c, 0x03, 0x07, 0x00, + 0x00, 0x1a, 0x03, 0x08, 0xa0, 0xe1, 0x02, 0x08, + 0x50, 0xe0, 0xff, 0x0c, 0x1c, 0x03, 0x03, 0x00, + 0x00, 0x1a, 0x03, 0x04, 0xa0, 0xe1, 0x02, 0x04, + 0x50, 0xe0, 0xff, 0x08, 0x1c, 0x03, 0x02, 0x00, + 0x53, 0x00, 0x60, 0x00, 0xa0, 0x11, 0x1e, 0xff, + 0x2f, 0xe1, 0x01, 0x20, 0xd0, 0xe4, 0x01, 0x30, + 0xd1, 0xe4, 0x01, 0x00, 0x52, 0xe3, 0x03, 0x00, + 0x52, 0x21, 0x04, 0x00, 0x00, 0x1a, 0x01, 0x20, + 0xd0, 0xe4, 0x01, 0x30, 0xd1, 0xe4, 0x01, 0x00, + 0x52, 0xe3, 0x03, 0x00, 0x52, 0x21, 0xf5, 0xff, + 0xff, 0x0a, 0x03, 0x00, 0x42, 0xe0, 0x1e, 0xff, + 0x2f, 0xe1, 0x01, 0x01, 0x01, 0x01, 0x78, 0x47, + 0x00, 0x00, 0x2c, 0xc0, 0x9f, 0xe5, 0xff, 0x7f, + 0x8c, 0xe8, 0x3c, 0xc0, 0x8c, 0xe2, 0x0c, 0x00, + 0x8f, 0xe2, 0x3c, 0x10, 0x4c, 0xe2, 0x04, 0xe0, + 0x4e, 0xe2, 0x00, 0xe0, 0x8c, 0xe5, 0x74, 0xfe, + 0xff, 0xea, 0x20, 0x00, 0x00, 0x80, 0x44, 0x69, + 0x76, 0x69, 0x64, 0x65, 0x20, 0x62, 0x79, 0x20, + 0x7a, 0x65, 0x72, 0x6f, 0x00, 0x00, 0x60, 0x01, + 0x00, 0x20, 0x78, 0x47, 0x00, 0x00, 0x70, 0x40, + 0x2d, 0xe9, 0x00, 0xe0, 0xa0, 0xe1, 0x2e, 0x58, + 0xa0, 0xe1, 0x05, 0x48, 0xce, 0xe1, 0x22, 0xc8, + 0xa0, 0xe1, 0x0c, 0x68, 0xc2, 0xe1, 0x94, 0x06, + 0x00, 0xe0, 0x9c, 0x04, 0x04, 0xe0, 0x95, 0x0c, + 0x0c, 0xe0, 0x96, 0x05, 0x05, 0xe0, 0x04, 0x08, + 0x90, 0xe0, 0x24, 0xc8, 0xac, 0xe0, 0xed, 0x09, + 0x00, 0x08, 0x00, 0x05, 0x08, 0x90, 0xe0, 0x25, + 0xc8, 0xac, 0xe0, 0x92, 0xc1, 0x21, 0xe0, 0x93, + 0x1e, 0x21, 0xe0, 0x70, 0x40, 0xbd, 0xe8, 0x1e, + 0xff, 0x2f, 0xe1, 0xf0, 0xb5, 0x83, 0xb0, 0x8d, + 0x01, 0x04, 0x1c, 0x01, 0x20, 0x0f, 0x1c, 0x29, + 0x1c, 0x25, 0xf0, 0x7b, 0xf9, 0x31, 0x4e, 0x00, + 0x28, 0xf0, 0x60, 0x05, 0xd1, 0x1f, 0x20, 0xc0, + 0x43, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x0b, 0x22, 0x01, 0x92, 0x38, 0x21, 0x02, + 0x1c, 0x00, 0x91, 0x2b, 0xa1, 0x2a, 0x48, 0x2b, + 0x1c, 0x26, 0xf0, 0x45, 0xf8, 0x00, 0x28, 0xef, + 0xd1, 0x00, 0x2c, 0x47, 0xd1, 0x01, 0x37, 0xb8, + 0x00, 0x04, 0x1c, 0x25, 0xf0, 0x4c, 0xf9, 0x35, + 0x1c, 0x03, 0x1c, 0x30, 0x60, 0x02, 0xd1, 0x1f, + 0x20, 0xc0, 0x43, 0xe1, 0xe7, 0x06, 0x22, 0x01, + 0x21, 0x07, 0x20, 0x02, 0x92, 0x1a, 0x1c, 0x00, + 0x90, 0x01, 0x91, 0x20, 0xa1, 0x1f, 0x48, 0x3b, + 0x1c, 0x26, 0xf0, 0x8d, 0xf9, 0x00, 0x28, 0xd3, + 0xd1, 0x20, 0x1c, 0x25, 0xf0, 0x34, 0xf9, 0x68, + 0x60, 0x06, 0x1c, 0x02, 0xd1, 0x1f, 0x20, 0xc0, + 0x43, 0xca, 0xe7, 0x06, 0x22, 0x01, 0x21, 0x07, + 0x20, 0x02, 0x92, 0x32, 0x1c, 0x00, 0x90, 0x01, + 0x91, 0x19, 0xa1, 0x17, 0x48, 0x3b, 0x1c, 0x26, + 0xf0, 0x76, 0xf9, 0x00, 0x28, 0xbc, 0xd1, 0x20, + 0x1c, 0x25, 0xf0, 0x1d, 0xf9, 0xa8, 0x60, 0x04, + 0x1c, 0x02, 0xd1, 0x1f, 0x20, 0xc0, 0x43, 0xb3, + 0xe7, 0x06, 0x22, 0x01, 0x21, 0x07, 0x20, 0x02, + 0x92, 0x22, 0x1c, 0x00, 0x90, 0x01, 0x91, 0x11, + 0xa1, 0x10, 0x48, 0x3b, 0x1c, 0x26, 0xf0, 0x5f, + 0xf9, 0x00, 0x28, 0xa5, 0xd1, 0x00, 0x20, 0xa3, + 0xe7, 0x00, 0x00, 0xdc, 0x6c, 0x03, 0x20, 0xf0, + 0xe2, 0x03, 0x20, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0xed, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x18, 0xe2, 0x03, 0x20, 0x54, 0x6f, 0x4c, 0x43, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00, + 0x60, 0xe2, 0x03, 0x20, 0x54, 0x6f, 0x4c, 0x4d, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00, + 0xa8, 0xe2, 0x03, 0x20, 0x54, 0x6f, 0x48, 0x43, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00, + 0x80, 0xb5, 0x83, 0xb0, 0x16, 0x4f, 0x00, 0x22, + 0x00, 0x92, 0x01, 0x22, 0x38, 0x1c, 0x02, 0xa9, + 0x01, 0xab, 0x26, 0xf0, 0xcb, 0xfa, 0x00, 0x28, + 0xf5, 0xd0, 0x12, 0x4f, 0x00, 0x22, 0x00, 0x92, + 0x01, 0x22, 0x38, 0x1c, 0x02, 0xa9, 0x01, 0xab, + 0x26, 0xf0, 0xc0, 0xfa, 0x00, 0x28, 0xf5, 0xd0, + 0x0d, 0x4f, 0x00, 0x22, 0x00, 0x92, 0x01, 0x22, + 0x38, 0x1c, 0x02, 0xa9, 0x01, 0xab, 0x26, 0xf0, + 0xb5, 0xfa, 0x00, 0x28, 0xf5, 0xd0, 0x09, 0x48, + 0x26, 0xf0, 0x0c, 0xf8, 0x08, 0x4f, 0xf8, 0x68, + 0x25, 0xf0, 0xe8, 0xf8, 0x00, 0x20, 0xf8, 0x60, + 0x03, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xa8, 0xe2, 0x03, 0x20, 0x60, 0xe2, 0x03, 0x20, + 0x18, 0xe2, 0x03, 0x20, 0xf0, 0xe2, 0x03, 0x20, + 0xdc, 0x6c, 0x03, 0x20, 0x80, 0xb5, 0x82, 0xb0, + 0x68, 0x23, 0x58, 0x43, 0x07, 0x1c, 0x25, 0xf0, + 0xa5, 0xf8, 0x0b, 0x49, 0x00, 0x28, 0x08, 0x61, + 0x05, 0xd1, 0x1f, 0x20, 0xc0, 0x43, 0x02, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0b, 0x22, + 0x01, 0x92, 0x60, 0x21, 0x02, 0x1c, 0x00, 0x91, + 0x05, 0xa1, 0x04, 0x48, 0x3b, 0x1c, 0x25, 0xf0, + 0x81, 0xff, 0x00, 0x28, 0xef, 0xd1, 0xee, 0xe7, + 0xdc, 0x6c, 0x03, 0x20, 0x2c, 0xe3, 0x03, 0x20, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x00, + 0x80, 0xb5, 0x06, 0x48, 0x25, 0xf0, 0xce, 0xff, + 0x05, 0x4f, 0x38, 0x69, 0xed, 0x09, 0x00, 0x0a, + 0x00, 0x25, 0xf0, 0xaa, 0xf8, 0x00, 0x20, 0x38, + 0x61, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x2c, 0xe3, 0x03, 0x20, 0xdc, 0x6c, 0x03, + 0x20, 0x90, 0xb5, 0x82, 0xb0, 0x21, 0x48, 0x25, + 0xf0, 0x6f, 0xf8, 0x21, 0x4c, 0x1f, 0x27, 0xff, + 0x43, 0x00, 0x28, 0x60, 0x61, 0x04, 0xd1, 0x38, + 0x1c, 0x02, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x22, 0x21, 0x0b, 0x22, 0x01, 0x92, 0x02, + 0x1c, 0x00, 0x91, 0x1b, 0xa1, 0x19, 0x48, 0x17, + 0x4b, 0x25, 0xf0, 0x4a, 0xff, 0x00, 0x28, 0xef, + 0xd1, 0x19, 0x48, 0x25, 0xf0, 0x55, 0xf8, 0xa0, + 0x61, 0x00, 0x28, 0x01, 0xd1, 0x38, 0x1c, 0xe7, + 0xe7, 0xbd, 0x21, 0x0b, 0x22, 0x01, 0x92, 0x02, + 0x1c, 0x00, 0x91, 0x15, 0xa1, 0x13, 0x48, 0x12, + 0x4b, 0x25, 0xf0, 0x36, 0xff, 0x00, 0x28, 0xdb, + 0xd1, 0x79, 0x20, 0x80, 0x01, 0x25, 0xf0, 0x40, + 0xf8, 0xe0, 0x61, 0x00, 0x28, 0x01, 0xd1, 0x38, + 0x1c, 0xd2, 0xe7, 0xff, 0x21, 0x59, 0x31, 0x0b, + 0x22, 0x01, 0x92, 0x02, 0x1c, 0x79, 0x23, 0x00, + 0x91, 0x0c, 0xa1, 0x9b, 0x01, 0x0a, 0x48, 0x25, + 0xf0, 0x1f, 0xff, 0xc5, 0xe7, 0x60, 0x27, 0x00, + 0x00, 0xdc, 0x6c, 0x03, 0x20, 0x68, 0xe3, 0x03, + 0x20, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x00, 0x00, + 0x00, 0x52, 0x20, 0x00, 0x00, 0xa4, 0xe3, 0x03, + 0x20, 0x4d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x00, + 0x00, 0xe0, 0xe3, 0x03, 0x20, 0x4c, 0x61, 0x72, + 0x67, 0x65, 0x00, 0x00, 0x00, 0x90, 0xb5, 0x0d, + 0x48, 0x25, 0xf0, 0x5e, 0xff, 0x0c, 0x48, 0x25, + 0xf0, 0x5b, 0xff, 0x0c, 0x48, 0x25, 0xf0, 0x58, + 0xff, 0x0b, 0x4f, 0xf8, 0x69, 0x25, 0xf0, 0x34, + 0xf8, 0x00, 0x24, 0xfc, 0x61, 0xb8, 0x69, 0x25, + 0xf0, 0x2f, 0xf8, 0xbc, 0x61, 0x78, 0x69, 0xed, + 0x09, 0x00, 0x0b, 0x00, 0x25, 0xf0, 0x2b, 0xf8, + 0x7c, 0x61, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xe0, 0xe3, 0x03, 0x20, 0xa4, 0xe3, + 0x03, 0x20, 0x68, 0xe3, 0x03, 0x20, 0xdc, 0x6c, + 0x03, 0x20, 0x98, 0xb5, 0x07, 0x1c, 0x12, 0xf0, + 0x24, 0xf9, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x22, + 0x01, 0xe0, 0x00, 0x22, 0xd2, 0x43, 0x00, 0x24, + 0x22, 0x2f, 0x01, 0xd8, 0x0c, 0x48, 0x08, 0xe0, + 0xbd, 0x2f, 0x01, 0xd8, 0x0b, 0x48, 0x04, 0xe0, + 0xff, 0x23, 0x59, 0x33, 0x9f, 0x42, 0x09, 0xd8, + 0x09, 0x48, 0x69, 0x46, 0x25, 0xf0, 0x77, 0xff, + 0x00, 0x28, 0x05, 0xd0, 0x20, 0x1c, 0x98, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, + 0x00, 0x98, 0xf8, 0xe7, 0x00, 0x00, 0x68, 0xe3, + 0x03, 0x20, 0xa4, 0xe3, 0x03, 0x20, 0xe0, 0xe3, + 0x03, 0x20, 0x00, 0xb5, 0x25, 0xf0, 0xbf, 0xff, + 0x08, 0xbc, 0x18, 0x47, 0x08, 0xb5, 0x69, 0x46, + 0x00, 0x22, 0x0f, 0x48, 0x25, 0xf0, 0x5b, 0xff, + 0x22, 0x23, 0xd8, 0x42, 0x0b, 0xd1, 0x00, 0x20, + 0x14, 0xf0, 0x3f, 0xf9, 0x0c, 0xa0, 0x14, 0xf0, + 0x00, 0xfa, 0x08, 0x20, 0x34, 0xf0, 0x41, 0xfe, + 0x34, 0xf0, 0x3b, 0xfe, 0x01, 0xe0, 0x00, 0x28, + 0x03, 0xd0, 0x00, 0x20, 0x01, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x0e, 0x48, 0x01, 0x6a, 0x01, 0x31, + 0x01, 0x62, 0x00, 0x98, 0x41, 0x60, 0x00, 0x98, + 0xf4, 0xe7, 0xf0, 0xe2, 0x03, 0x20, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x3a, 0x20, 0x4e, 0x55, 0x5f, + 0x4e, 0x4f, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x28, 0x72, 0x65, + 0x62, 0x6f, 0x6f, 0x74, 0x20, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x29, 0x0a, 0x00, 0xdc, 0x6c, + 0x03, 0x20, 0x00, 0xb5, 0x25, 0xf0, 0x7f, 0xff, + 0x08, 0xbc, 0xed, 0x09, 0x00, 0x0c, 0x00, 0x18, + 0x47, 0x08, 0xb5, 0x12, 0xf0, 0xb4, 0xf8, 0x00, + 0x28, 0x01, 0xd0, 0x00, 0x22, 0x01, 0xe0, 0x00, + 0x22, 0xd2, 0x43, 0x69, 0x46, 0x0a, 0x48, 0x25, + 0xf0, 0x14, 0xff, 0x00, 0x21, 0x00, 0x28, 0x03, + 0xd0, 0x08, 0x1c, 0x01, 0xb0, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x98, 0x00, 0x22, 0x01, 0x63, 0x00, + 0x98, 0x00, 0x21, 0x00, 0x23, 0x18, 0x30, 0x0e, + 0xc0, 0x0e, 0xc0, 0x00, 0x98, 0xf1, 0xe7, 0x2c, + 0xe3, 0x03, 0x20, 0x00, 0xb5, 0x25, 0xf0, 0x59, + 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x1c, 0x00, + 0x20, 0x00, 0x22, 0x8b, 0x5c, 0x01, 0x32, 0x18, + 0x18, 0x34, 0x2a, 0xfa, 0xd3, 0x70, 0x47, 0x93, + 0xb5, 0x00, 0x27, 0x00, 0x24, 0x0f, 0x28, 0x1b, + 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, + 0x44, 0x00, 0x1c, 0x08, 0x08, 0x0a, 0x0c, 0x0e, + 0x08, 0x0a, 0x0c, 0x08, 0x0a, 0x0c, 0x0e, 0x17, + 0x17, 0x0c, 0x00, 0x12, 0x4f, 0x12, 0xe0, 0x12, + 0x4f, 0x10, 0xe0, 0x12, 0x4f, 0x0e, 0xe0, 0x00, + 0x20, 0x01, 0x99, 0x02, 0xf0, 0x0a, 0xff, 0x00, + 0x20, 0x02, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x33, 0xf0, 0xef, 0xfa, 0x01, 0x1c, 0x0c, + 0xa0, 0x14, 0xf0, 0x79, 0xf9, 0x12, 0xf0, 0x5f, + 0xf8, 0x00, 0x28, 0x00, 0xd1, 0xc4, 0x43, 0x01, + 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x01, 0xa9, 0x26, + 0xf0, 0x3c, 0xf8, 0x01, 0x21, 0x00, 0x28, 0x00, + 0xd1, 0x00, 0x21, 0x08, 0x1c, 0xe4, 0xe7, 0xa8, + 0xe2, 0x03, 0x20, 0x60, 0xe2, 0x03, 0x20, 0x18, + 0xe2, 0x03, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x3a, 0x20, 0x27, 0x25, 0x73, 0x27, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x75, 0x73, 0x65, 0x64, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0xb5, 0x83, 0xb0, 0x01, + 0x1c, 0x00, 0x20, 0xc2, 0x43, 0xed, 0x09, 0x00, + 0x0d, 0x00, 0x00, 0x29, 0x11, 0xd0, 0x01, 0x29, + 0x11, 0xd0, 0x02, 0x29, 0x00, 0xd1, 0x0a, 0x48, + 0x00, 0x92, 0x01, 0x22, 0x01, 0xa9, 0x02, 0xab, + 0x26, 0xf0, 0xe6, 0xf8, 0x2d, 0x23, 0xd8, 0x42, + 0x07, 0xd1, 0x00, 0x20, 0x03, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x04, 0x48, 0xf0, 0xe7, 0x04, 0x48, + 0xee, 0xe7, 0x01, 0x98, 0xf6, 0xe7, 0x00, 0x00, + 0x18, 0xe2, 0x03, 0x20, 0xa8, 0xe2, 0x03, 0x20, + 0x60, 0xe2, 0x03, 0x20, 0x04, 0x48, 0x00, 0x21, + 0x00, 0x22, 0x0a, 0x23, 0x06, 0xc0, 0x01, 0x3b, + 0xfc, 0xd1, 0x04, 0xc0, 0x70, 0x47, 0x00, 0x00, + 0xe4, 0xe4, 0x03, 0x20, 0xb0, 0xb5, 0x82, 0xb0, + 0x0c, 0x1c, 0x17, 0x1c, 0x00, 0x2b, 0x01, 0xd0, + 0x05, 0x25, 0x00, 0xe0, 0x01, 0x25, 0x15, 0x49, + 0x49, 0x69, 0x01, 0x29, 0x1e, 0xd0, 0x02, 0x29, + 0x06, 0xd1, 0x09, 0x21, 0x0f, 0xf0, 0xbc, 0xff, + 0x6a, 0x46, 0x03, 0xc2, 0x00, 0x98, 0x01, 0x99, + 0xc2, 0x1f, 0x0f, 0x49, 0x21, 0x3a, 0x8a, 0x60, + 0xff, 0x30, 0xff, 0x30, 0x42, 0x30, 0xc8, 0x60, + 0x01, 0x2f, 0x01, 0xd0, 0x03, 0x2f, 0x04, 0xd1, + 0x08, 0x23, 0x1d, 0x43, 0x09, 0x4a, 0x60, 0x08, + 0x10, 0x60, 0x0d, 0x60, 0x02, 0xb0, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x10, 0x21, 0x0f, 0xf0, + 0x9f, 0xff, 0x6a, 0x46, 0x03, 0xc2, 0x00, 0x98, + 0x01, 0x99, 0xe1, 0xe7, 0x48, 0xe6, 0x03, 0x20, + 0x00, 0x51, 0x00, 0xe0, 0x80, 0x55, 0x00, 0xe0, + 0x80, 0xb5, 0x0d, 0x4f, 0xb8, 0x68, 0x00, 0x28, + 0x12, 0xd0, 0x01, 0x23, 0x07, 0x22, 0x00, 0x21, + 0x01, 0xf0, 0x98, 0xfd, 0x00, 0x20, 0xb8, 0x60, + 0xf8, 0x63, 0x78, 0x68, 0xc0, 0x69, 0x00, 0x28, + 0x01, 0xd0, 0x24, 0xf0, 0xb5, 0xfe, 0x78, 0x68, + 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x24, 0xff, + 0xed, 0x09, 0x00, 0x0e, 0x00, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe4, 0xe4, 0x03, + 0x20, 0x90, 0xb4, 0x11, 0x4b, 0x11, 0x4f, 0x5c, + 0x69, 0x11, 0x4b, 0x01, 0x2c, 0x14, 0xd0, 0x02, + 0x2c, 0x10, 0xd1, 0x62, 0x24, 0x3c, 0x60, 0x00, + 0x2a, 0x13, 0xd1, 0x99, 0x61, 0x09, 0x09, 0x09, + 0x07, 0x09, 0x0f, 0x18, 0x68, 0x01, 0x31, 0x01, + 0x30, 0x48, 0x43, 0xc0, 0x08, 0x1a, 0x30, 0x58, + 0x61, 0x01, 0x20, 0xd8, 0x61, 0x90, 0xbc, 0x70, + 0x47, 0x14, 0x33, 0x07, 0xc3, 0x80, 0x20, 0x38, + 0x60, 0xf8, 0xe7, 0x14, 0x33, 0x07, 0xc3, 0xf5, + 0xe7, 0x48, 0xe6, 0x03, 0x20, 0x40, 0x53, 0x00, + 0xe0, 0xe4, 0xe4, 0x03, 0x20, 0x09, 0x49, 0xca, + 0x1d, 0xb9, 0x32, 0x52, 0x69, 0x01, 0x2a, 0x07, + 0xd0, 0x02, 0x2a, 0x04, 0xd1, 0x80, 0x22, 0x00, + 0x28, 0x00, 0xd1, 0x00, 0x22, 0x0a, 0x60, 0x70, + 0x47, 0x40, 0x22, 0x00, 0x28, 0x00, 0xd1, 0x00, + 0x22, 0x0a, 0x60, 0x70, 0x47, 0x88, 0xe5, 0x03, + 0x20, 0xb0, 0xb5, 0x1f, 0x4f, 0x01, 0x25, 0x49, + 0x07, 0xf8, 0x60, 0x49, 0x0f, 0x3a, 0x61, 0x39, + 0x60, 0xbb, 0x63, 0x04, 0xa9, 0x18, 0xc9, 0xf8, + 0x1d, 0x19, 0x30, 0x18, 0xc0, 0xb8, 0x68, 0x00, + 0x24, 0x00, 0x28, 0x06, 0xd1, 0x01, 0x20, 0x29, + 0x1c, 0x03, 0xf0, 0x28, 0xfa, 0xb8, 0x60, 0xc4, + 0x60, 0x04, 0xe0, 0x00, 0x23, 0x07, 0x22, 0x00, + 0x21, 0x01, 0xf0, 0x26, 0xfd, 0x78, 0x68, 0x00, + 0x28, 0x02, 0xd1, 0xff, 0xf7, 0x9a, 0xfe, 0x78, + 0x60, 0x0e, 0x49, 0x78, 0x68, 0x0c, 0xc9, 0x0c, + 0xc0, 0x78, 0x68, 0x04, 0x72, 0x79, 0x68, 0x01, + 0x20, 0x48, 0x72, 0x79, 0x68, 0x8c, 0x72, 0x79, + 0x68, 0xc8, 0x72, 0x78, 0x68, 0x84, 0x61, 0x78, + 0x68, 0xc4, 0x61, 0x78, 0x68, 0x04, 0x62, 0x78, + 0x68, 0x44, 0x62, 0xed, 0x09, 0x00, 0x0f, 0x00, + 0x78, 0x68, 0x84, 0x62, 0x78, 0x68, 0xc4, 0x62, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe4, 0xe4, + 0x03, 0x20, 0x88, 0xe6, 0x03, 0x20, 0x04, 0x49, + 0x05, 0x48, 0xc1, 0x60, 0x00, 0x21, 0x81, 0x60, + 0x05, 0xa1, 0x0c, 0xc9, 0x03, 0x48, 0x0c, 0xc0, + 0x70, 0x47, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x50, + 0x00, 0xe0, 0x88, 0xe6, 0x03, 0x20, 0x55, 0x55, + 0x33, 0x33, 0x00, 0x00, 0xff, 0x4f, 0xf0, 0xb5, + 0x0d, 0x1c, 0x14, 0x1c, 0x07, 0x1c, 0x47, 0xa1, + 0x34, 0xf0, 0x7d, 0xfc, 0x47, 0x4e, 0x00, 0x28, + 0x03, 0xd1, 0x71, 0x68, 0x10, 0x20, 0xc8, 0x60, + 0x6d, 0xe0, 0x38, 0x1c, 0x44, 0xa1, 0x34, 0xf0, + 0x72, 0xfc, 0x00, 0x28, 0x14, 0xd1, 0x71, 0x68, + 0x09, 0x20, 0xc8, 0x60, 0x71, 0x68, 0x1d, 0x20, + 0x88, 0x61, 0x20, 0x20, 0x24, 0xf0, 0xc9, 0xfd, + 0x71, 0x68, 0xc8, 0x61, 0x71, 0x68, 0x03, 0x20, + 0x48, 0x61, 0x71, 0x68, 0x01, 0x20, 0x08, 0x61, + 0x70, 0x68, 0x81, 0x69, 0x81, 0x63, 0x52, 0xe0, + 0x38, 0x1c, 0x38, 0xa1, 0x34, 0xf0, 0x57, 0xfc, + 0x00, 0x28, 0x14, 0xd1, 0x71, 0x68, 0x04, 0x20, + 0xc8, 0x60, 0x71, 0x68, 0x1b, 0x20, 0x88, 0x61, + 0x20, 0x20, 0x24, 0xf0, 0xae, 0xfd, 0x71, 0x68, + 0xc8, 0x61, 0x71, 0x68, 0x03, 0x20, 0x48, 0x61, + 0x71, 0x68, 0x01, 0x20, 0x08, 0x61, 0x70, 0x68, + 0x81, 0x69, 0x81, 0x63, 0x37, 0xe0, 0x38, 0x1c, + 0x2c, 0xa1, 0x34, 0xf0, 0x3c, 0xfc, 0x00, 0x28, + 0x15, 0xd1, 0x71, 0x68, 0x0b, 0x20, 0xc8, 0x60, + 0x71, 0x68, 0xb7, 0x20, 0x88, 0x61, 0xff, 0x20, + 0x01, 0x30, 0x24, 0xf0, 0x92, 0xfd, 0x71, 0x68, + 0xc8, 0x61, 0x71, 0x68, 0x03, 0x20, 0x48, 0x61, + 0x71, 0x68, 0x01, 0x20, 0x08, 0x61, 0x70, 0x68, + 0x81, 0x69, 0x81, 0x63, 0x1b, 0xe0, 0xed, 0x09, + 0x00, 0x10, 0x00, 0x38, 0x1c, 0x1f, 0xa1, 0x34, + 0xf0, 0x20, 0xfc, 0x00, 0x28, 0x28, 0xd1, 0x71, + 0x68, 0x0f, 0x20, 0xc8, 0x60, 0xff, 0x20, 0x71, + 0x68, 0x54, 0x30, 0x88, 0x61, 0x01, 0x20, 0x40, + 0x02, 0x24, 0xf0, 0x75, 0xfd, 0x71, 0x68, 0xc8, + 0x61, 0x71, 0x68, 0x03, 0x20, 0x48, 0x61, 0x71, + 0x68, 0x01, 0x20, 0x08, 0x61, 0x70, 0x68, 0x81, + 0x69, 0x81, 0x63, 0x72, 0x68, 0x00, 0x20, 0xd1, + 0x69, 0x92, 0x69, 0xd2, 0x08, 0x0a, 0x1c, 0x54, + 0x60, 0x15, 0x60, 0x72, 0x68, 0x92, 0x69, 0xd2, + 0x08, 0x01, 0x30, 0x08, 0x31, 0x82, 0x42, 0xf5, + 0xd2, 0x00, 0x20, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x34, 0xf0, 0xeb, 0xfb, 0x01, 0x20, 0xf8, + 0xe7, 0x00, 0x00, 0x49, 0x44, 0x00, 0x00, 0xe4, + 0xe4, 0x03, 0x20, 0x41, 0x55, 0x58, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x44, 0x48, 0x31, 0x00, 0x44, + 0x48, 0x33, 0x00, 0x44, 0x48, 0x35, 0x00, 0xff, + 0xb5, 0x82, 0xb0, 0x04, 0x1c, 0x1f, 0x1c, 0x0c, + 0x9d, 0x0b, 0x9e, 0x34, 0xf0, 0xd6, 0xfb, 0xff, + 0xf7, 0x40, 0xff, 0x1d, 0x4a, 0x00, 0x2f, 0x02, + 0xd1, 0x02, 0x20, 0xd0, 0x63, 0x01, 0xe0, 0x01, + 0x20, 0xd0, 0x63, 0x00, 0x20, 0x19, 0x4a, 0x14, + 0x21, 0x10, 0x64, 0x51, 0x64, 0x90, 0x64, 0xd0, + 0x64, 0x01, 0x2c, 0x24, 0xd1, 0x28, 0x1c, 0xff, + 0xf7, 0xd2, 0xfe, 0x0d, 0x99, 0x0e, 0x9a, 0x00, + 0x91, 0x01, 0x92, 0x3a, 0x1c, 0x00, 0x21, 0x33, + 0x1c, 0x04, 0x98, 0xff, 0xf7, 0xde, 0xfe, 0x0e, + 0x4f, 0xf8, 0x6b, 0x01, 0x28, 0x0c, 0xd1, 0x03, + 0x98, 0x0d, 0x99, 0x0e, 0x9a, 0xff, 0xf7, 0x2d, + 0xff, 0x00, 0x28, 0x05, 0xd0, 0x34, 0xf0, 0xa5, + 0xfb, 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x07, 0x23, 0x1c, 0x22, 0x00, 0x21, 0xb8, + 0x68, 0xed, 0x09, 0x00, 0x11, 0x00, 0x01, 0xf0, + 0xe3, 0xf9, 0x01, 0xe0, 0xff, 0xf7, 0x66, 0xfe, + 0x34, 0xf0, 0x96, 0xfb, 0xef, 0xe7, 0x00, 0x00, + 0xe4, 0xe4, 0x03, 0x20, 0xff, 0xb5, 0x82, 0xb0, + 0x0e, 0x9c, 0x0d, 0x9d, 0x0c, 0x9e, 0x0b, 0x9f, + 0x34, 0xf0, 0x8e, 0xfb, 0xff, 0xf7, 0xf8, 0xfe, + 0x00, 0x2f, 0x03, 0xd1, 0x1a, 0x49, 0x03, 0x20, + 0xc8, 0x63, 0x02, 0xe0, 0x18, 0x49, 0x00, 0x20, + 0xc8, 0x63, 0x02, 0x98, 0x01, 0x28, 0x26, 0xd1, + 0x30, 0x1c, 0x29, 0x1c, 0x22, 0x1c, 0xff, 0xf7, + 0x63, 0xfe, 0x10, 0x99, 0x11, 0x9a, 0x00, 0x91, + 0x01, 0x92, 0x3a, 0x1c, 0x04, 0x99, 0x05, 0x98, + 0x0f, 0x9b, 0xff, 0xf7, 0x99, 0xfe, 0x0e, 0x4f, + 0xf8, 0x6b, 0x00, 0x28, 0x0c, 0xd1, 0x03, 0x98, + 0x10, 0x99, 0x11, 0x9a, 0xff, 0xf7, 0xe8, 0xfe, + 0x00, 0x28, 0x05, 0xd0, 0x34, 0xf0, 0x60, 0xfb, + 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x07, 0x23, 0x1c, 0x22, 0x00, 0x21, 0xb8, 0x68, + 0x01, 0xf0, 0x9e, 0xf9, 0x01, 0xe0, 0xff, 0xf7, + 0x21, 0xfe, 0x34, 0xf0, 0x51, 0xfb, 0xef, 0xe7, + 0xe4, 0xe4, 0x03, 0x20, 0xf0, 0xb5, 0xc8, 0x1d, + 0xff, 0x30, 0x7a, 0x30, 0x0f, 0x1c, 0x01, 0x69, + 0x03, 0x23, 0x19, 0x43, 0x01, 0x61, 0x23, 0x4e, + 0x00, 0x20, 0x30, 0x63, 0x70, 0x63, 0xf1, 0x6b, + 0x14, 0x1c, 0x00, 0x29, 0x20, 0x4d, 0x0e, 0xd0, + 0x20, 0x4a, 0x01, 0x29, 0x25, 0xd0, 0x02, 0x29, + 0x29, 0xd0, 0x03, 0x29, 0x04, 0xd1, 0x28, 0x60, + 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 0x7c, 0xfc, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x34, 0xf0, + 0x2f, 0xfb, 0xf0, 0x69, 0xe8, 0x60, 0x71, 0x68, + 0x17, 0x48, 0x28, 0xc9, 0x28, 0xc0, 0x18, 0x48, + 0x16, 0x49, 0xc1, 0x60, 0x81, 0x68, 0x01, 0x23, + 0x9b, 0x02, 0x19, 0x43, 0xed, 0x09, 0x00, 0x12, + 0x00, 0x81, 0x60, 0x00, 0x69, 0xff, 0x30, 0x91, + 0x30, 0xb0, 0x62, 0x00, 0x20, 0x00, 0xf0, 0x1e, + 0xfd, 0x34, 0xf0, 0x14, 0xfb, 0xe2, 0xe7, 0x38, + 0x1c, 0x21, 0x1c, 0x12, 0x68, 0x00, 0xf0, 0xd2, + 0xf8, 0xdc, 0xe7, 0xd0, 0x1d, 0xb9, 0x30, 0x40, + 0x69, 0x02, 0x28, 0x03, 0xd1, 0x05, 0x21, 0x31, + 0x20, 0x00, 0xf0, 0x13, 0xfe, 0x00, 0x22, 0x38, + 0x1c, 0x21, 0x1c, 0x00, 0xf0, 0x37, 0xf8, 0xcd, + 0xe7, 0xe4, 0xe4, 0x03, 0x20, 0x00, 0x52, 0x00, + 0xe0, 0x88, 0xe5, 0x03, 0x20, 0x90, 0x57, 0x00, + 0xe0, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x50, 0x00, + 0xe0, 0x90, 0xb5, 0x11, 0x4c, 0x0f, 0x1c, 0xe0, + 0x6b, 0x02, 0x28, 0x19, 0xd0, 0x03, 0x28, 0x17, + 0xd0, 0x34, 0xf0, 0xec, 0xfa, 0x0d, 0x49, 0x0e, + 0x48, 0xc1, 0x60, 0xe1, 0x6b, 0x01, 0x29, 0x06, + 0xd0, 0x02, 0x29, 0x04, 0xd0, 0x81, 0x68, 0x01, + 0x23, 0x9b, 0x02, 0x99, 0x43, 0x81, 0x60, 0xf8, + 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x01, 0x69, 0x89, + 0x08, 0x89, 0x00, 0x01, 0x61, 0x34, 0xf0, 0xd2, + 0xfa, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0xe4, 0xe4, 0x03, 0x20, 0xfc, 0x07, 0x00, + 0x00, 0x00, 0x50, 0x00, 0xe0, 0xf0, 0xb5, 0x17, + 0x1c, 0x34, 0xf0, 0xc8, 0xfa, 0x39, 0x49, 0x3a, + 0x4a, 0xc8, 0x69, 0xd0, 0x60, 0x4c, 0x68, 0x39, + 0x48, 0x60, 0xcc, 0x60, 0xc0, 0x38, 0x4e, 0xb0, + 0x68, 0xb0, 0x60, 0x38, 0x48, 0xf0, 0x60, 0x30, + 0x69, 0xff, 0x30, 0x91, 0x30, 0xc8, 0x62, 0x36, + 0x4d, 0xcc, 0x68, 0x69, 0x69, 0x01, 0x29, 0x3a, + 0xd0, 0x02, 0x29, 0x20, 0xd1, 0x09, 0x21, 0x0f, + 0xf0, 0x0b, 0xfd, 0xc8, 0x22, 0x0f, 0xf0, 0x12, + 0xfd, 0x34, 0x22, 0x0f, 0xf0, 0x0f, 0xfd, 0x50, + 0x22, 0x0f, 0xf0, 0x0c, 0xfd, 0x0d, 0x22, 0xed, + 0x09, 0x00, 0x13, 0x00, 0x0f, 0xf0, 0x09, 0xfd, + 0x04, 0x22, 0x0f, 0xf0, 0x06, 0xfd, 0x28, 0x22, + 0x0f, 0xf0, 0x03, 0xfd, 0xa1, 0x1c, 0x09, 0x02, + 0x10, 0x22, 0x0a, 0x43, 0x27, 0x49, 0x0a, 0x62, + 0x42, 0x22, 0x3a, 0x43, 0x12, 0x02, 0x11, 0x23, + 0x1a, 0x43, 0x4a, 0x62, 0x24, 0x4a, 0x24, 0x49, + 0x0a, 0x62, 0x08, 0x60, 0x30, 0x69, 0x69, 0x69, + 0xff, 0x30, 0x91, 0x30, 0x01, 0x29, 0x2d, 0xd0, + 0x02, 0x29, 0x00, 0xd1, 0x09, 0x30, 0xc1, 0x1f, + 0x1f, 0x48, 0x21, 0x39, 0x81, 0x60, 0x00, 0x21, + 0x01, 0x60, 0x34, 0xf0, 0x76, 0xfa, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x10, 0x21, 0x0f, 0xf0, + 0xd2, 0xfc, 0xff, 0x22, 0x05, 0x32, 0x0f, 0xf0, + 0xd8, 0xfc, 0x46, 0x22, 0x0f, 0xf0, 0xd5, 0xfc, + 0x0d, 0x22, 0x0f, 0xf0, 0xd2, 0xfc, 0x04, 0x22, + 0x0f, 0xf0, 0xcf, 0xfc, 0x28, 0x22, 0x0f, 0xf0, + 0xcc, 0xfc, 0xa1, 0x1c, 0x09, 0x02, 0x20, 0x22, + 0x0a, 0x43, 0x0b, 0x49, 0x0a, 0x62, 0x82, 0x22, + 0x3a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, + 0x4a, 0x62, 0xc7, 0xe7, 0x10, 0x30, 0xd2, 0xe7, + 0x00, 0x00, 0xe4, 0xe4, 0x03, 0x20, 0x00, 0x52, + 0x00, 0xe0, 0x90, 0x57, 0x00, 0xe0, 0x00, 0x50, + 0x00, 0xe0, 0xfc, 0x07, 0x00, 0x00, 0x48, 0xe6, + 0x03, 0x20, 0xa0, 0x55, 0x00, 0xe0, 0x02, 0x05, + 0x00, 0x00, 0x08, 0x53, 0x00, 0xe0, 0x00, 0x51, + 0x00, 0xe0, 0xf0, 0xb5, 0x17, 0x1c, 0x34, 0xf0, + 0x3c, 0xfa, 0x68, 0x48, 0x69, 0x4a, 0xc1, 0x69, + 0xd1, 0x60, 0x44, 0x68, 0x68, 0x49, 0x60, 0xcc, + 0x60, 0xc1, 0x44, 0x68, 0x67, 0x49, 0x60, 0xcc, + 0x60, 0xc1, 0x66, 0x4e, 0x03, 0x22, 0xb2, 0x62, + 0x66, 0x4b, 0x66, 0x49, 0xcb, 0x60, 0x8c, 0x68, + 0x7d, 0x23, 0xdb, 0x00, 0x23, 0x43, 0x8b, 0x60, + 0x03, 0x69, 0xed, 0x09, 0x00, 0x14, 0x00, 0x09, + 0x69, 0x5b, 0x00, 0x59, 0x18, 0x62, 0x4c, 0xc1, + 0x62, 0x65, 0x69, 0x61, 0x4b, 0x01, 0x2d, 0x4f, + 0xd0, 0x02, 0x2d, 0x01, 0xd1, 0x60, 0x4d, 0x1d, + 0x62, 0xff, 0x23, 0x50, 0x31, 0x5f, 0x4a, 0x02, + 0x33, 0x13, 0x62, 0x11, 0x60, 0x53, 0x49, 0xc8, + 0x6a, 0xcd, 0x68, 0x61, 0x69, 0x01, 0x29, 0x42, + 0xd0, 0x02, 0x29, 0x20, 0xd1, 0x09, 0x21, 0x0f, + 0xf0, 0x64, 0xfc, 0xc8, 0x22, 0x0f, 0xf0, 0x6b, + 0xfc, 0x34, 0x22, 0x0f, 0xf0, 0x68, 0xfc, 0x50, + 0x22, 0x0f, 0xf0, 0x65, 0xfc, 0x0d, 0x22, 0x0f, + 0xf0, 0x62, 0xfc, 0x04, 0x22, 0x0f, 0xf0, 0x5f, + 0xfc, 0x28, 0x22, 0x0f, 0xf0, 0x5c, 0xfc, 0xa9, + 0x1c, 0x09, 0x02, 0x10, 0x22, 0x0a, 0x43, 0x4d, + 0x49, 0x0a, 0x62, 0x42, 0x22, 0x3a, 0x43, 0x12, + 0x02, 0x11, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x4a, + 0x4a, 0x4b, 0x49, 0x0a, 0x62, 0x08, 0x60, 0x3c, + 0x48, 0x41, 0x68, 0xc9, 0x68, 0x10, 0x29, 0x3a, + 0xd1, 0x03, 0x22, 0x32, 0x60, 0xc0, 0x6a, 0x61, + 0x69, 0x01, 0x29, 0x30, 0xd0, 0x02, 0x29, 0x02, + 0xd1, 0x09, 0x21, 0x0f, 0xf0, 0x32, 0xfc, 0xc1, + 0x1f, 0x21, 0x39, 0xb1, 0x60, 0xb0, 0x30, 0xf0, + 0x60, 0x32, 0x20, 0x10, 0xf0, 0xcc, 0xf9, 0x54, + 0xe0, 0x3e, 0x4d, 0x1d, 0x62, 0xb0, 0xe7, 0x10, + 0x21, 0x0f, 0xf0, 0x23, 0xfc, 0xff, 0x22, 0x05, + 0x32, 0x0f, 0xf0, 0x29, 0xfc, 0x46, 0x22, 0x0f, + 0xf0, 0x26, 0xfc, 0x0d, 0x22, 0x0f, 0xf0, 0x23, + 0xfc, 0x04, 0x22, 0x0f, 0xf0, 0x20, 0xfc, 0x28, + 0x22, 0x0f, 0xf0, 0x1d, 0xfc, 0xa9, 0x1c, 0x09, + 0x02, 0x20, 0x22, 0x0a, 0x43, 0x2e, 0x49, 0x0a, + 0x62, 0x82, 0x22, 0x3a, 0x43, 0x12, 0x02, 0x10, + 0x23, 0x1a, 0x43, 0x4a, 0x62, 0xbf, 0xe7, 0x10, + 0x21, 0x0f, 0xf0, 0x03, 0xfc, 0xed, 0x09, 0x00, + 0x15, 0x00, 0xcf, 0xe7, 0xc5, 0x6a, 0x66, 0x69, + 0x3e, 0x23, 0x3d, 0x22, 0x2d, 0x21, 0x01, 0x2e, + 0x28, 0x4f, 0x2a, 0xd0, 0x02, 0x2e, 0x02, 0xd1, + 0x39, 0x62, 0x2c, 0x26, 0x7e, 0x62, 0xef, 0x1d, + 0x25, 0x4d, 0x26, 0x4e, 0x21, 0x37, 0x35, 0x62, + 0x37, 0x60, 0xc7, 0x6a, 0x64, 0x69, 0x64, 0x37, + 0x01, 0x2c, 0x23, 0x4d, 0x1c, 0xd0, 0x02, 0x2c, + 0x02, 0xd1, 0x29, 0x62, 0x2c, 0x26, 0x6e, 0x62, + 0x1d, 0x4d, 0x20, 0x4a, 0xf9, 0x1d, 0x21, 0x31, + 0x15, 0x62, 0x11, 0x60, 0x81, 0x6b, 0x01, 0x23, + 0x00, 0x29, 0x00, 0xd1, 0x00, 0x23, 0x00, 0x22, + 0x00, 0x21, 0xc0, 0x6a, 0xff, 0xf7, 0x06, 0xfc, + 0x34, 0xf0, 0x70, 0xf9, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x3a, 0x62, 0x7b, 0x62, 0xd6, 0xe7, + 0x2a, 0x62, 0x6b, 0x62, 0xe4, 0xe7, 0x00, 0x00, + 0xe4, 0xe4, 0x03, 0x20, 0x00, 0x52, 0x00, 0xe0, + 0x20, 0x51, 0x00, 0xe0, 0x90, 0x57, 0x00, 0xe0, + 0x00, 0x51, 0x00, 0xe0, 0xfc, 0x07, 0x00, 0x00, + 0x00, 0x50, 0x00, 0xe0, 0x48, 0xe6, 0x03, 0x20, + 0xb0, 0x55, 0x00, 0xe0, 0x11, 0x40, 0x00, 0x00, + 0x0c, 0x53, 0x00, 0xe0, 0xa0, 0x55, 0x00, 0xe0, + 0x02, 0x05, 0x00, 0x00, 0x08, 0x53, 0x00, 0xe0, + 0x10, 0x80, 0x00, 0x00, 0xc0, 0x55, 0x00, 0xe0, + 0x02, 0x03, 0x00, 0x00, 0x10, 0x53, 0x00, 0xe0, + 0xd0, 0x55, 0x00, 0xe0, 0x14, 0x53, 0x00, 0xe0, + 0xf0, 0xb5, 0x82, 0xb0, 0xf0, 0x4e, 0x05, 0x1c, + 0xf7, 0x6a, 0x10, 0xf0, 0x2f, 0xf9, 0x30, 0x6b, + 0x01, 0x30, 0x30, 0x63, 0xff, 0x20, 0x0a, 0x30, + 0x28, 0x40, 0x18, 0xd0, 0x68, 0x08, 0x02, 0xd3, + 0xea, 0xa0, 0x13, 0xf0, 0xe3, 0xfc, 0x68, 0x0a, + 0x02, 0xd3, 0xe9, 0xa0, 0x13, 0xf0, 0xde, 0xfc, + 0x30, 0x6b, 0x0a, 0x28, 0x01, 0xd9, 0x00, 0x20, + 0xed, 0x09, 0x00, 0x16, 0x00, 0x30, 0x63, 0xe6, + 0x49, 0xb0, 0x68, 0x0a, 0x68, 0x00, 0x21, 0xff, + 0xf7, 0xdf, 0xfe, 0x02, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x30, 0x69, 0x40, 0x00, 0xc7, + 0x19, 0x68, 0x09, 0x0d, 0xd3, 0xdf, 0xa0, 0x13, + 0xf0, 0xc7, 0xfc, 0xdf, 0x48, 0xc1, 0x6a, 0x09, + 0x09, 0x0a, 0x07, 0xc0, 0x6a, 0x12, 0x0f, 0x01, + 0x07, 0x09, 0x0f, 0xdc, 0xa0, 0x13, 0xf0, 0xbc, + 0xfc, 0x04, 0x24, 0x2c, 0x40, 0x02, 0xd0, 0xe1, + 0xa0, 0x13, 0xf0, 0xb6, 0xfc, 0xd1, 0x4a, 0xd0, + 0x6b, 0x01, 0x28, 0x6f, 0xd1, 0x20, 0x1c, 0xde, + 0x4c, 0x12, 0xd0, 0xde, 0x48, 0x80, 0x6a, 0x41, + 0x07, 0x49, 0x0f, 0x00, 0xab, 0x19, 0x70, 0x41, + 0x06, 0x09, 0x0f, 0x01, 0x91, 0x01, 0x06, 0xc9, + 0x0f, 0x59, 0x70, 0xc1, 0x05, 0xc9, 0x0f, 0x80, + 0x05, 0xc0, 0x0f, 0x99, 0x70, 0xd8, 0x70, 0x61, + 0xe0, 0xe8, 0x09, 0x5f, 0xd2, 0x28, 0x0a, 0x5d, + 0xd2, 0x11, 0x20, 0x40, 0x01, 0x28, 0x40, 0x61, + 0xd0, 0x00, 0x21, 0x28, 0x1c, 0x02, 0xf0, 0x0c, + 0xff, 0x05, 0x1c, 0xc0, 0x69, 0x00, 0x28, 0x6c, + 0xd0, 0xbf, 0x48, 0xcd, 0x4a, 0x01, 0x68, 0x10, + 0x6a, 0x52, 0x6a, 0x00, 0x0a, 0xff, 0x23, 0x1b, + 0x02, 0x1a, 0x40, 0x10, 0x43, 0x62, 0x69, 0x01, + 0x2a, 0x3d, 0xd0, 0x02, 0x2a, 0x07, 0xd1, 0xd7, + 0x03, 0x03, 0x0c, 0x00, 0xd2, 0x00, 0x27, 0x38, + 0x43, 0x01, 0x23, 0xdb, 0x03, 0x98, 0x43, 0xc3, + 0x4b, 0x1f, 0x6a, 0x5e, 0x6a, 0x3f, 0x0a, 0xff, + 0x23, 0x1b, 0x02, 0x33, 0x40, 0x1f, 0x43, 0x3e, + 0x1c, 0x01, 0x2a, 0x30, 0xd0, 0x02, 0x2a, 0x09, + 0xd1, 0xd7, 0x03, 0x31, 0x0c, 0x00, 0xd2, 0x00, + 0x27, 0x37, 0x43, 0x01, 0x23, 0xdb, 0x03, 0x39, + 0x1c, 0x99, 0x43, 0x0e, 0x1c, 0x26, 0xf0, 0xf6, + 0xfd, 0x07, 0x1c, 0xed, 0x09, 0x00, 0x17, 0x00, + 0x30, 0x1c, 0x26, 0xf0, 0xf2, 0xfd, 0x06, 0x1c, + 0x28, 0x1c, 0x00, 0xf0, 0x82, 0xf9, 0xa0, 0x4a, + 0x11, 0x6c, 0x01, 0x31, 0x11, 0x64, 0x01, 0x29, + 0x1c, 0xd1, 0xf9, 0x00, 0xc9, 0x1b, 0xc9, 0x19, + 0xc9, 0x10, 0x91, 0x64, 0xf1, 0x00, 0x89, 0x1b, + 0x89, 0x19, 0xc9, 0x10, 0x10, 0x65, 0xd1, 0x64, + 0x32, 0xe0, 0x20, 0xe1, 0x01, 0x27, 0x3f, 0x04, + 0x00, 0x29, 0x00, 0xd1, 0x00, 0x27, 0x38, 0x43, + 0xc4, 0xe7, 0x5f, 0xe0, 0x01, 0x27, 0x3f, 0x04, + 0x00, 0x29, 0x00, 0xd1, 0x00, 0x27, 0x3e, 0x43, + 0xd3, 0xe7, 0x4f, 0xe0, 0x53, 0x6c, 0x99, 0x42, + 0x0f, 0xd1, 0x90, 0x6c, 0xc1, 0x00, 0x08, 0x1a, + 0xc0, 0x19, 0xc0, 0x10, 0x90, 0x64, 0xd1, 0x6c, + 0xc8, 0x00, 0x40, 0x1a, 0x80, 0x19, 0xc0, 0x10, + 0xd0, 0x64, 0x00, 0x20, 0x10, 0x64, 0x0f, 0xe0, + 0x18, 0xe0, 0x91, 0x6c, 0xcb, 0x00, 0x59, 0x1a, + 0xc9, 0x19, 0xc9, 0x10, 0x91, 0x64, 0xd1, 0x6c, + 0xcb, 0x00, 0x59, 0x1a, 0x89, 0x19, 0xc9, 0x10, + 0xd1, 0x64, 0x11, 0x6d, 0x08, 0x18, 0x10, 0x65, + 0x28, 0x6b, 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, + 0xf6, 0xf9, 0xe8, 0x69, 0xff, 0xf7, 0xf3, 0xf9, + 0x00, 0x20, 0x28, 0x63, 0x7e, 0x48, 0x07, 0x69, + 0x02, 0xf0, 0x0f, 0xfc, 0x00, 0x90, 0x01, 0x91, + 0x60, 0x69, 0x01, 0x28, 0x14, 0xd0, 0x02, 0x28, + 0x04, 0xd1, 0x8e, 0x21, 0x38, 0x1c, 0x0f, 0xf0, + 0xb2, 0xfa, 0x07, 0x1c, 0x00, 0x98, 0x87, 0x42, + 0x02, 0xd9, 0x01, 0x98, 0x01, 0x38, 0x01, 0x90, + 0x81, 0x4b, 0x00, 0x97, 0xff, 0x18, 0x28, 0x1c, + 0x01, 0x99, 0xff, 0xf7, 0x3a, 0xfa, 0x0d, 0xe0, + 0x95, 0x21, 0x38, 0x1c, 0x0f, 0xf0, 0x9f, 0xfa, + 0x07, 0x1c, 0xeb, 0xe7, 0x67, 0x4a, 0x11, 0x6b, + 0x48, 0x1c, 0x10, 0x63, 0x0a, 0x29, 0xed, 0x09, + 0x00, 0x18, 0x00, 0x01, 0xd9, 0x00, 0x20, 0x10, + 0x63, 0x63, 0x69, 0x03, 0x22, 0x01, 0x2b, 0x64, + 0x49, 0x75, 0x48, 0x52, 0xd0, 0x02, 0x2b, 0x01, + 0xd1, 0x74, 0x4b, 0x03, 0x62, 0xf8, 0x1d, 0x49, + 0x30, 0xff, 0x23, 0x72, 0x4a, 0x02, 0x33, 0x13, + 0x62, 0x10, 0x60, 0x5a, 0x4d, 0x0e, 0x68, 0xed, + 0x68, 0x61, 0x69, 0x38, 0x1c, 0x01, 0x29, 0x43, + 0xd0, 0x02, 0x29, 0x20, 0xd1, 0x09, 0x21, 0x0f, + 0xf0, 0x66, 0xfa, 0xc8, 0x22, 0x0f, 0xf0, 0x6d, + 0xfa, 0x34, 0x22, 0x0f, 0xf0, 0x6a, 0xfa, 0x50, + 0x22, 0x0f, 0xf0, 0x67, 0xfa, 0x0d, 0x22, 0x0f, + 0xf0, 0x64, 0xfa, 0x04, 0x22, 0x0f, 0xf0, 0x61, + 0xfa, 0x28, 0x22, 0x0f, 0xf0, 0x5e, 0xfa, 0xa9, + 0x1c, 0x09, 0x02, 0x10, 0x22, 0x0a, 0x43, 0x60, + 0x49, 0x0a, 0x62, 0x42, 0x22, 0x32, 0x43, 0x12, + 0x02, 0x11, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x5d, + 0x4a, 0x5e, 0x49, 0x0a, 0x62, 0x44, 0x4d, 0x08, + 0x60, 0x68, 0x68, 0xc0, 0x68, 0x10, 0x28, 0x3b, + 0xd1, 0x46, 0x4e, 0x03, 0x22, 0x32, 0x60, 0x61, + 0x69, 0x38, 0x1c, 0x01, 0x29, 0x30, 0xd0, 0x02, + 0x29, 0x02, 0xd1, 0x09, 0x21, 0x0f, 0xf0, 0x33, + 0xfa, 0xc1, 0x1f, 0x21, 0x39, 0xb1, 0x60, 0xb0, + 0x30, 0xf0, 0x60, 0x32, 0x20, 0x0f, 0xf0, 0xcd, + 0xff, 0x54, 0xe0, 0x50, 0x4b, 0x03, 0x62, 0xad, + 0xe7, 0x10, 0x21, 0x0f, 0xf0, 0x24, 0xfa, 0xff, + 0x22, 0x05, 0x32, 0x0f, 0xf0, 0x2a, 0xfa, 0x46, + 0x22, 0x0f, 0xf0, 0x27, 0xfa, 0x0d, 0x22, 0x0f, + 0xf0, 0x24, 0xfa, 0x04, 0x22, 0x0f, 0xf0, 0x21, + 0xfa, 0x28, 0x22, 0x0f, 0xf0, 0x1e, 0xfa, 0xa9, + 0x1c, 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x40, + 0x49, 0x0a, 0x62, 0x82, 0x22, 0x32, 0x43, 0x12, + 0x02, 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0xbe, + 0xe7, 0xed, 0x09, 0x00, 0x19, 0x00, 0x10, 0x21, + 0x0f, 0xf0, 0x04, 0xfa, 0xcf, 0xe7, 0x62, 0x69, + 0x3e, 0x21, 0x3d, 0x20, 0x01, 0x2a, 0x39, 0xd0, + 0x02, 0x2a, 0x04, 0xd1, 0x30, 0x4a, 0x2d, 0x23, + 0x13, 0x62, 0x2c, 0x23, 0x53, 0x62, 0x38, 0x4b, + 0x38, 0x4e, 0xfa, 0x1d, 0x21, 0x32, 0x33, 0x62, + 0x32, 0x60, 0x63, 0x69, 0xfa, 0x1d, 0x5d, 0x32, + 0x01, 0x2b, 0x2b, 0xd0, 0x02, 0x2b, 0x04, 0xd1, + 0x28, 0x48, 0x2d, 0x23, 0x03, 0x62, 0x2c, 0x23, + 0x43, 0x62, 0x2f, 0x4b, 0x30, 0x49, 0xd0, 0x1d, + 0x21, 0x30, 0x0b, 0x62, 0x08, 0x60, 0xa8, 0x6b, + 0x01, 0x23, 0x00, 0x28, 0x00, 0xd1, 0x00, 0x23, + 0x00, 0x22, 0x00, 0x21, 0x38, 0x1c, 0xff, 0xf7, + 0x07, 0xfa, 0x69, 0x68, 0x29, 0x48, 0x0c, 0xc9, + 0x0c, 0xc0, 0x69, 0x68, 0x28, 0x48, 0x28, 0xc9, + 0x28, 0xc0, 0x0d, 0x4e, 0x00, 0x20, 0xb0, 0x62, + 0x32, 0x20, 0x0f, 0xf0, 0x69, 0xff, 0x05, 0x4a, + 0xd7, 0x62, 0x46, 0xe6, 0x14, 0x4a, 0x10, 0x62, + 0x51, 0x62, 0xc8, 0xe7, 0x13, 0x4b, 0x18, 0x62, + 0x59, 0x62, 0xd6, 0xe7, 0xe4, 0xe4, 0x03, 0x20, + 0x77, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x88, 0xe5, 0x03, 0x20, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x51, 0x00, 0xe0, 0x43, 0x6f, 0x72, 0x72, + 0x42, 0x69, 0x74, 0x73, 0x3d, 0x30, 0x78, 0x25, + 0x78, 0x2c, 0x20, 0x50, 0x72, 0x65, 0x42, 0x69, + 0x74, 0x73, 0x3d, 0x30, 0x78, 0x25, 0x78, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x48, 0xe6, 0x03, 0x20, 0x40, 0x55, 0x00, 0xe0, + 0xc0, 0x55, 0x00, 0xe0, 0xd0, 0x55, 0x00, 0xe0, + 0xd8, 0x1f, 0x00, 0x00, 0xb0, 0x55, 0x00, 0xe0, + 0x11, 0x40, 0x00, 0x00, 0x0c, 0x53, 0x00, 0xe0, + 0xa0, 0x55, 0x00, 0xe0, 0x02, 0x05, 0x00, 0x00, + 0x08, 0x53, 0x00, 0xe0, 0xed, 0x09, 0x00, 0x1a, + 0x00, 0x10, 0x80, 0x00, 0x00, 0x02, 0x03, 0x00, + 0x00, 0x10, 0x53, 0x00, 0xe0, 0x14, 0x53, 0x00, + 0xe0, 0x20, 0x51, 0x00, 0xe0, 0x90, 0x57, 0x00, + 0xe0, 0xf1, 0xb5, 0x88, 0xb0, 0x08, 0x98, 0x00, + 0x25, 0xc1, 0x69, 0x00, 0x91, 0x00, 0x21, 0x01, + 0x91, 0x80, 0x69, 0xc0, 0x08, 0x3e, 0xd0, 0x27, + 0x48, 0x27, 0xa1, 0x43, 0x68, 0x07, 0x93, 0x02, + 0x68, 0x27, 0xa0, 0x06, 0x92, 0x4b, 0x68, 0x05, + 0x93, 0x0a, 0x68, 0x04, 0x92, 0x43, 0x68, 0x03, + 0x93, 0x02, 0x68, 0x02, 0x92, 0x00, 0x99, 0x08, + 0x68, 0x49, 0x68, 0x07, 0x9b, 0x06, 0x9a, 0x59, + 0x40, 0x50, 0x40, 0x04, 0x1c, 0x0f, 0x1c, 0x02, + 0x9a, 0x03, 0x9b, 0x0f, 0xf0, 0xb3, 0xf8, 0x00, + 0x28, 0x15, 0xd0, 0x00, 0x26, 0x01, 0x22, 0x20, + 0x1c, 0x39, 0x1c, 0x0f, 0xf0, 0xb5, 0xf8, 0x05, + 0x9b, 0x0f, 0x1c, 0x19, 0x40, 0x04, 0x9a, 0x04, + 0x1c, 0x10, 0x40, 0x02, 0x9a, 0x03, 0x9b, 0x0f, + 0xf0, 0xa1, 0xf8, 0x00, 0x28, 0x00, 0xd0, 0x01, + 0x35, 0x01, 0x36, 0x40, 0x2e, 0xea, 0xd3, 0x00, + 0x99, 0x08, 0x31, 0x00, 0x91, 0x01, 0x99, 0x08, + 0x98, 0x01, 0x31, 0x01, 0x91, 0x80, 0x69, 0xc0, + 0x08, 0x88, 0x42, 0xcf, 0xd8, 0x0c, 0x49, 0x01, + 0x98, 0x69, 0x43, 0x00, 0x28, 0x04, 0xd0, 0x01, + 0x98, 0x80, 0x01, 0xfe, 0xf7, 0xed, 0xfb, 0x00, + 0xe0, 0x07, 0x48, 0x09, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x04, 0xe5, 0x03, + 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x42, 0x0f, 0x00, 0xf8, 0xb5, 0x33, + 0xf0, 0xb5, 0xfe, 0x51, 0x49, 0x51, 0x4a, 0xc8, + 0x69, 0xd0, 0x60, 0x4f, 0x68, 0x50, 0x48, 0x60, + 0xcf, 0x60, 0xc0, 0x50, 0x48, 0x50, 0x4a, 0xed, + 0x09, 0x00, 0x1b, 0x00, 0xd0, 0x60, 0x90, 0x68, + 0x90, 0x60, 0x10, 0x69, 0xff, 0x30, 0x91, 0x30, + 0x88, 0x62, 0x00, 0x22, 0x0a, 0x63, 0x4a, 0x63, + 0x0c, 0x68, 0x4d, 0x69, 0x8e, 0x69, 0xcf, 0x68, + 0x4a, 0x49, 0x00, 0x91, 0x49, 0x69, 0x01, 0x29, + 0x55, 0xd0, 0x02, 0x29, 0x27, 0xd1, 0x47, 0x4a, + 0x03, 0x21, 0xd1, 0x62, 0x06, 0x21, 0x0f, 0xf0, + 0x00, 0xf9, 0xc8, 0x22, 0x0f, 0xf0, 0xf5, 0xf8, + 0x6a, 0x00, 0x0f, 0xf0, 0xf2, 0xf8, 0x28, 0x22, + 0x0f, 0xf0, 0xef, 0xf8, 0x03, 0x22, 0x0f, 0xf0, + 0xfc, 0xf8, 0xb9, 0x1c, 0x09, 0x02, 0x10, 0x23, + 0x3d, 0x4a, 0x19, 0x43, 0x11, 0x62, 0xe1, 0x00, + 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, + 0x19, 0x43, 0x51, 0x62, 0x31, 0x02, 0x16, 0x23, + 0x19, 0x43, 0x91, 0x62, 0x37, 0x49, 0x08, 0x60, + 0x05, 0x20, 0x00, 0x02, 0x08, 0x62, 0x2d, 0x48, + 0x81, 0x6a, 0x02, 0x68, 0x00, 0x98, 0x43, 0x69, + 0x33, 0x48, 0x01, 0x2b, 0x49, 0xd0, 0x02, 0x2b, + 0x06, 0xd1, 0xd2, 0x00, 0x40, 0x23, 0x1a, 0x43, + 0x12, 0x02, 0x11, 0x23, 0x1a, 0x43, 0x02, 0x62, + 0xc8, 0x1d, 0x5d, 0x30, 0x2d, 0x49, 0xff, 0x22, + 0x02, 0x32, 0x0a, 0x62, 0x26, 0x4a, 0x08, 0x60, + 0x10, 0x69, 0x00, 0x99, 0xff, 0x30, 0x49, 0x69, + 0x91, 0x30, 0x01, 0x29, 0x39, 0xd0, 0x02, 0x29, + 0x00, 0xd1, 0x06, 0x38, 0x1d, 0x49, 0x88, 0x60, + 0x00, 0x22, 0x0a, 0x60, 0x33, 0xf0, 0x41, 0xfe, + 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x21, + 0x0f, 0xf0, 0xaf, 0xf8, 0xff, 0x22, 0x05, 0x32, + 0x0f, 0xf0, 0xa3, 0xf8, 0x6a, 0x00, 0x0f, 0xf0, + 0xa0, 0xf8, 0x28, 0x22, 0x0f, 0xf0, 0x9d, 0xf8, + 0x03, 0x22, 0x0f, 0xf0, 0xaa, 0xf8, 0xb9, 0x1c, + 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x13, 0x49, + 0x0a, 0x62, 0xed, 0x09, 0x00, 0x1c, 0x00, 0xe2, + 0x00, 0x84, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, + 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x32, 0x02, 0x19, + 0x23, 0x1a, 0x43, 0x8a, 0x62, 0x0e, 0x49, 0x08, + 0x60, 0x10, 0x48, 0x08, 0x62, 0xad, 0xe7, 0xd2, + 0x00, 0x80, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, + 0x23, 0x1a, 0x43, 0x02, 0x62, 0xb6, 0xe7, 0x06, + 0x38, 0xc6, 0xe7, 0xe4, 0xe4, 0x03, 0x20, 0x00, + 0x52, 0x00, 0xe0, 0x90, 0x57, 0x00, 0xe0, 0xfc, + 0x07, 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, 0x48, + 0xe6, 0x03, 0x20, 0x80, 0x55, 0x00, 0xe0, 0x00, + 0x53, 0x00, 0xe0, 0x90, 0x55, 0x00, 0xe0, 0x04, + 0x53, 0x00, 0xe0, 0x03, 0x05, 0x00, 0x00, 0xf0, + 0xb5, 0x82, 0xb0, 0x6c, 0x4d, 0x04, 0x1c, 0xaf, + 0x6a, 0x0f, 0xf0, 0xe9, 0xfd, 0xff, 0x20, 0x0a, + 0x30, 0x20, 0x40, 0x08, 0xd0, 0x00, 0x22, 0x01, + 0x20, 0xa9, 0x68, 0xff, 0xf7, 0x9a, 0xfa, 0x02, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x63, + 0x48, 0xc0, 0x6b, 0x00, 0x28, 0x65, 0xd1, 0x61, + 0x48, 0x62, 0x4c, 0x01, 0x69, 0x03, 0x68, 0x49, + 0x00, 0xcf, 0x19, 0x66, 0x69, 0x39, 0x1c, 0x01, + 0x25, 0x01, 0x2e, 0x5e, 0x4a, 0x5a, 0xd0, 0x02, + 0x2e, 0x06, 0xd1, 0xde, 0x00, 0x40, 0x23, 0x33, + 0x43, 0x1e, 0x02, 0x11, 0x23, 0x33, 0x43, 0x13, + 0x62, 0xff, 0x22, 0x64, 0x31, 0x59, 0x4b, 0x02, + 0x32, 0x1a, 0x62, 0x54, 0x48, 0x19, 0x60, 0x42, + 0x69, 0xc5, 0x68, 0x06, 0x68, 0x00, 0x92, 0x82, + 0x69, 0x01, 0x92, 0x60, 0x69, 0x01, 0x28, 0x49, + 0xd0, 0x02, 0x28, 0x2b, 0xd1, 0x52, 0x49, 0x03, + 0x20, 0xc8, 0x62, 0x06, 0x21, 0x38, 0x1c, 0x0f, + 0xf0, 0x26, 0xf8, 0xc8, 0x22, 0x0f, 0xf0, 0x1b, + 0xf8, 0x00, 0x9a, 0x52, 0x00, 0x0f, 0xf0, 0x17, + 0xf8, 0x28, 0x22, 0x0f, 0xf0, 0xed, 0x09, 0x00, + 0x1d, 0x00, 0x14, 0xf8, 0x03, 0x22, 0x0f, 0xf0, + 0x21, 0xf8, 0xa9, 0x1c, 0x09, 0x02, 0x10, 0x23, + 0x46, 0x4a, 0x19, 0x43, 0x11, 0x62, 0xf1, 0x00, + 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, + 0x19, 0x43, 0x51, 0x62, 0x01, 0x9a, 0x11, 0x02, + 0x16, 0x23, 0x40, 0x4a, 0x19, 0x43, 0x91, 0x62, + 0x3f, 0x49, 0x08, 0x60, 0x05, 0x20, 0x00, 0x02, + 0x08, 0x62, 0x38, 0x4d, 0x68, 0x68, 0xc0, 0x68, + 0x10, 0x28, 0x43, 0xd1, 0x61, 0x69, 0x38, 0x1c, + 0x01, 0x29, 0x3b, 0xd0, 0x02, 0x29, 0x02, 0xd1, + 0x06, 0x21, 0x0e, 0xf0, 0xf3, 0xff, 0x37, 0x49, + 0x88, 0x60, 0x03, 0x20, 0x08, 0x60, 0x4b, 0xe0, + 0x4d, 0xe0, 0xde, 0x00, 0x80, 0x23, 0x33, 0x43, + 0x1e, 0x02, 0x10, 0x23, 0x33, 0x43, 0x13, 0x62, + 0xa5, 0xe7, 0x06, 0x21, 0x38, 0x1c, 0x0e, 0xf0, + 0xe1, 0xff, 0xff, 0x22, 0x05, 0x32, 0x0e, 0xf0, + 0xd5, 0xff, 0x00, 0x9a, 0x52, 0x00, 0x0e, 0xf0, + 0xd1, 0xff, 0x28, 0x22, 0x0e, 0xf0, 0xce, 0xff, + 0x03, 0x22, 0x0e, 0xf0, 0xdb, 0xff, 0xa9, 0x1c, + 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x23, 0x49, + 0x0a, 0x62, 0xf2, 0x00, 0x84, 0x23, 0x1a, 0x43, + 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, + 0x01, 0x9a, 0x12, 0x02, 0x19, 0x23, 0x1a, 0x43, + 0x8a, 0x62, 0x1d, 0x49, 0x08, 0x60, 0x1e, 0x48, + 0x08, 0x62, 0xba, 0xe7, 0x06, 0x21, 0x0e, 0xf0, + 0xb9, 0xff, 0xc4, 0xe7, 0xaa, 0x6b, 0x01, 0x21, + 0x38, 0x1c, 0x00, 0x2a, 0x00, 0xd1, 0x00, 0x21, + 0x00, 0x29, 0x01, 0xd0, 0x05, 0x26, 0x00, 0xe0, + 0x01, 0x26, 0x61, 0x69, 0x01, 0x29, 0x10, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, 0x0e, 0xf0, + 0xa5, 0xff, 0x10, 0x49, 0x88, 0x60, 0x0e, 0x60, + 0x68, 0x68, 0x02, 0xf0, 0x05, 0xfd, 0x32, 0x20, + 0xed, 0x09, 0x00, 0x1e, 0x00, 0x0f, 0xf0, 0x2c, + 0xfd, 0x05, 0x48, 0x87, 0x62, 0x3c, 0xe7, 0x06, + 0x21, 0x0e, 0xf0, 0x96, 0xff, 0x6a, 0x46, 0x03, + 0xc2, 0x00, 0x98, 0x01, 0x99, 0xeb, 0xe7, 0x00, + 0x00, 0xe4, 0xe4, 0x03, 0x20, 0x48, 0xe6, 0x03, + 0x20, 0x90, 0x55, 0x00, 0xe0, 0x04, 0x53, 0x00, + 0xe0, 0x80, 0x55, 0x00, 0xe0, 0x00, 0x53, 0x00, + 0xe0, 0x00, 0x52, 0x00, 0xe0, 0x03, 0x05, 0x00, + 0x00, 0x80, 0xb5, 0x1f, 0x1c, 0x00, 0x28, 0x05, + 0xd0, 0x08, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x13, + 0xf8, 0x38, 0x60, 0x03, 0xe0, 0x08, 0x1c, 0x00, + 0xf0, 0x2d, 0xf8, 0x38, 0x60, 0x80, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0xb5, 0x00, + 0x20, 0x33, 0xf0, 0x0e, 0xfd, 0x01, 0x20, 0x33, + 0xf0, 0x0b, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb4, 0x01, 0x27, 0x0b, 0x4a, 0x3f, 0x03, 0xd7, + 0x60, 0x09, 0x02, 0x08, 0x43, 0x09, 0x49, 0x08, + 0x62, 0x09, 0x48, 0x51, 0x68, 0x49, 0x0b, 0x07, + 0xd2, 0x01, 0x38, 0x02, 0xd1, 0x01, 0x20, 0x80, + 0xbc, 0x70, 0x47, 0x51, 0x68, 0x49, 0x0b, 0xf7, + 0xd3, 0xd7, 0x60, 0x00, 0x20, 0xf7, 0xe7, 0x00, + 0x00, 0x00, 0x50, 0x00, 0xe0, 0x40, 0x53, 0x00, + 0xe0, 0x10, 0x27, 0x00, 0x00, 0x90, 0xb4, 0x01, + 0x27, 0x0b, 0x49, 0xff, 0x02, 0xcf, 0x60, 0x0b, + 0x4a, 0x50, 0x62, 0x0b, 0x48, 0x4c, 0x68, 0x23, + 0x0b, 0x07, 0xd2, 0x01, 0x38, 0x02, 0xd1, 0x01, + 0x20, 0x90, 0xbc, 0x70, 0x47, 0x4c, 0x68, 0x23, + 0x0b, 0xf7, 0xd3, 0x50, 0x6a, 0x00, 0x0a, 0x00, + 0x06, 0x00, 0x0e, 0xcf, 0x60, 0xf4, 0xe7, 0x00, + 0x00, 0x00, 0x50, 0x00, 0xe0, 0x40, 0x53, 0x00, + 0xe0, 0x10, 0x27, 0x00, 0x00, 0x90, 0xb5, 0x01, + 0x21, 0x20, 0x20, 0x23, 0xf0, 0x8b, 0xf8, 0x00, + 0x20, 0x00, 0xf0, 0xed, 0x09, 0x00, 0x1f, 0x00, + 0x62, 0xf9, 0x00, 0x20, 0xff, 0x27, 0x01, 0x37, + 0x01, 0x06, 0x02, 0x04, 0x89, 0x18, 0x02, 0x02, + 0x89, 0x18, 0x0a, 0x18, 0x00, 0x21, 0x8c, 0x00, + 0x3b, 0x4b, 0x01, 0x31, 0xe3, 0x18, 0x1a, 0x60, + 0xb9, 0x42, 0xf8, 0xd3, 0x00, 0x21, 0x37, 0x4b, + 0x8c, 0x00, 0xe3, 0x18, 0x1b, 0x68, 0x93, 0x42, + 0x01, 0xd0, 0xff, 0xe7, 0xfe, 0xe7, 0x01, 0x31, + 0xb9, 0x42, 0xf4, 0xd3, 0x01, 0x30, 0xb8, 0x42, + 0xe2, 0xd3, 0x31, 0x49, 0x0a, 0x69, 0x00, 0x20, + 0x01, 0x30, 0x64, 0x28, 0xfc, 0xd3, 0x08, 0x69, + 0x82, 0x42, 0x01, 0xd3, 0xff, 0xe7, 0xfe, 0xe7, + 0xff, 0xf7, 0x83, 0xff, 0xff, 0xf7, 0x81, 0xff, + 0x3a, 0x20, 0xff, 0xf7, 0xa6, 0xff, 0x07, 0x1c, + 0x3b, 0x20, 0xff, 0xf7, 0xa2, 0xff, 0x00, 0x02, + 0x38, 0x43, 0x01, 0x1c, 0x26, 0x4a, 0x26, 0x48, + 0x0a, 0x40, 0x5f, 0x23, 0xdb, 0x01, 0x9a, 0x42, + 0x16, 0xd1, 0x02, 0x22, 0x24, 0x4b, 0x42, 0x61, + 0x19, 0x40, 0x08, 0xd0, 0x01, 0x29, 0x08, 0xd0, + 0x02, 0x29, 0x09, 0xd0, 0x03, 0x29, 0x0a, 0xd1, + 0x05, 0x21, 0x81, 0x61, 0x2a, 0xe0, 0x82, 0x61, + 0x28, 0xe0, 0x03, 0x21, 0x81, 0x61, 0x25, 0xe0, + 0x04, 0x21, 0x81, 0x61, 0x22, 0xe0, 0xfe, 0xe7, + 0x01, 0x21, 0x41, 0x61, 0xa5, 0x21, 0x31, 0x20, + 0xff, 0xf7, 0x5c, 0xff, 0x00, 0x28, 0x01, 0xd0, + 0xff, 0xe7, 0xfe, 0xe7, 0x5a, 0x21, 0x32, 0x20, + 0xff, 0xf7, 0x54, 0xff, 0x00, 0x28, 0x01, 0xd0, + 0xff, 0xe7, 0xfe, 0xe7, 0x31, 0x20, 0xff, 0xf7, + 0x6c, 0xff, 0xa5, 0x28, 0x01, 0xd0, 0xff, 0xe7, + 0xfe, 0xe7, 0x32, 0x20, 0xff, 0xf7, 0x65, 0xff, + 0x40, 0x06, 0x40, 0x0e, 0x5a, 0x28, 0x01, 0xd0, + 0xff, 0xe7, 0xfe, 0xe7, 0x00, 0x21, 0x20, 0x20, + 0x23, 0xf0, 0x0b, 0xf8, 0x90, 0xbc, 0xed, 0x09, + 0x00, 0x20, 0x00, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x00, 0x00, 0x00, 0x54, 0x00, 0xe0, 0x00, + 0x50, 0x00, 0xe0, 0xe0, 0xff, 0x00, 0x00, 0x48, + 0xe6, 0x03, 0x20, 0x1f, 0x00, 0xff, 0xff, 0xf0, + 0xb5, 0x07, 0x1c, 0x00, 0x28, 0x40, 0x4d, 0x13, + 0xd1, 0xff, 0x22, 0x00, 0x21, 0x28, 0x1c, 0x09, + 0x32, 0xfe, 0xf7, 0x9b, 0xf9, 0x3d, 0x48, 0x00, + 0x21, 0x00, 0x22, 0x00, 0x24, 0x00, 0x26, 0x06, + 0x23, 0x56, 0xc0, 0x01, 0x3b, 0xfc, 0xd1, 0x40, + 0xc0, 0xff, 0xf7, 0x55, 0xff, 0x00, 0x28, 0x67, + 0xd1, 0x02, 0xf0, 0xb5, 0xfc, 0xec, 0x1d, 0xb9, + 0x34, 0x60, 0x69, 0x01, 0x28, 0x19, 0xd0, 0x02, + 0x28, 0x01, 0xd1, 0x80, 0x20, 0x28, 0x60, 0x05, + 0x20, 0x68, 0x60, 0x00, 0x26, 0x6e, 0x61, 0xa8, + 0x68, 0x40, 0x19, 0xc0, 0x30, 0x01, 0x79, 0xe9, + 0x60, 0x00, 0x7b, 0x28, 0x61, 0x01, 0x20, 0xe0, + 0x62, 0x26, 0x63, 0x33, 0xf0, 0xfe, 0xfb, 0xff, + 0x23, 0x03, 0x33, 0x98, 0x42, 0x04, 0xd3, 0x07, + 0x20, 0x03, 0xe0, 0x40, 0x20, 0x28, 0x60, 0xe6, + 0xe7, 0x05, 0x20, 0xe0, 0x61, 0x33, 0xf0, 0xf1, + 0xfb, 0xff, 0x23, 0x03, 0x33, 0x98, 0x42, 0x01, + 0xd3, 0x07, 0x20, 0x00, 0xe0, 0x05, 0x20, 0xa8, + 0x60, 0x1f, 0x48, 0x60, 0x63, 0x01, 0x20, 0xa0, + 0x62, 0x01, 0x2f, 0x09, 0xd1, 0x02, 0xf0, 0x2d, + 0xfe, 0x02, 0xf0, 0x81, 0xff, 0x00, 0xf0, 0x0b, + 0xf9, 0xfe, 0xf7, 0xab, 0xfc, 0xfe, 0xf7, 0x19, + 0xfd, 0x02, 0xf0, 0xd1, 0xfe, 0x00, 0x2f, 0x01, + 0xd1, 0x33, 0xf0, 0xcf, 0xfb, 0x00, 0xf0, 0x00, + 0xf9, 0x00, 0x28, 0x1d, 0xd1, 0x00, 0x2f, 0x06, + 0xd1, 0xff, 0x21, 0x38, 0x1c, 0xa5, 0x31, 0xfe, + 0xf7, 0xac, 0xfb, 0x00, 0x28, 0x14, 0xd1, 0xff, + 0x20, 0x7d, 0x30, 0xfe, 0xf7, 0x6c, 0xfc, 0x00, + 0x28, 0xed, 0x09, 0x00, 0x21, 0x00, 0x0e, 0xd1, + 0xfe, 0xf7, 0xa0, 0xfc, 0x00, 0x28, 0x0a, 0xd1, + 0x38, 0x1c, 0x00, 0xf0, 0x5d, 0xf8, 0x02, 0xf0, + 0xed, 0xfd, 0x38, 0x1c, 0x00, 0xf0, 0x82, 0xf8, + 0x03, 0xf0, 0x86, 0xfa, 0x30, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x88, 0xe5, 0x03, 0x20, + 0x90, 0xe6, 0x03, 0x20, 0x14, 0x02, 0x42, 0x00, + 0x00, 0xb5, 0x83, 0xb0, 0x05, 0x21, 0xc9, 0x02, + 0x01, 0x22, 0x12, 0x03, 0x01, 0x92, 0x00, 0x91, + 0x19, 0xa1, 0x17, 0x4a, 0x00, 0x23, 0x17, 0x48, + 0x10, 0xf0, 0xec, 0xfa, 0x00, 0x28, 0x02, 0xd0, + 0x03, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x02, 0xaa, + 0x15, 0x49, 0x08, 0x20, 0x10, 0xf0, 0xf8, 0xfe, + 0x00, 0x28, 0x00, 0xd0, 0xf4, 0xe7, 0x07, 0x21, + 0xc9, 0x02, 0x01, 0x22, 0xd2, 0x02, 0x01, 0x92, + 0x00, 0x91, 0x12, 0xa1, 0x0f, 0x4a, 0x00, 0x23, + 0x0f, 0x48, 0x10, 0xf0, 0xd3, 0xfa, 0x00, 0x28, + 0x00, 0xd0, 0xe5, 0xe7, 0x02, 0xaa, 0x0f, 0x49, + 0x03, 0x20, 0x10, 0xf0, 0xe1, 0xfe, 0x00, 0x28, + 0x00, 0xd0, 0xdd, 0xe7, 0x08, 0x20, 0x33, 0xf0, + 0x6b, 0xfb, 0x00, 0x20, 0xd8, 0xe7, 0x00, 0x00, + 0x45, 0x59, 0x00, 0x20, 0x34, 0xf2, 0x03, 0x20, + 0x48, 0x5f, 0x4c, 0x63, 0x49, 0x72, 0x71, 0x00, + 0x09, 0x59, 0x00, 0x20, 0x39, 0x59, 0x00, 0x20, + 0x8c, 0xf2, 0x03, 0x20, 0x48, 0x5f, 0x4c, 0x63, + 0x54, 0x4d, 0x4f, 0x00, 0x21, 0x59, 0x00, 0x20, + 0x90, 0xb5, 0x01, 0x24, 0x00, 0x28, 0x13, 0xd1, + 0x0e, 0x4f, 0x01, 0x20, 0x3c, 0x60, 0x10, 0xf0, + 0x65, 0xfd, 0x03, 0x20, 0x38, 0x60, 0x01, 0x20, + 0x10, 0xf0, 0x60, 0xfd, 0x02, 0x20, 0x38, 0x60, + 0x01, 0x20, 0x10, 0xf0, 0x5b, 0xfd, 0xff, 0x20, + 0x07, 0x30, 0x38, 0x60, 0x06, 0x48, 0x44, 0x60, + 0x06, 0x48, 0x00, 0x21, 0xed, 0x09, 0x00, 0x22, + 0x00, 0x81, 0x60, 0x06, 0x4a, 0xc2, 0x60, 0x01, + 0x61, 0x84, 0x61, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x58, 0x00, 0xe0, 0x40, 0x53, 0x00, + 0xe0, 0x00, 0x50, 0x00, 0xe0, 0xff, 0xff, 0x07, + 0x00, 0x90, 0xb5, 0x2a, 0x4c, 0x61, 0x69, 0x01, + 0x29, 0x42, 0xd0, 0x02, 0x29, 0x3d, 0xd1, 0x00, + 0x28, 0x29, 0xd1, 0xa0, 0x69, 0x26, 0x4f, 0x03, + 0x28, 0x00, 0xdd, 0x08, 0x37, 0x38, 0x68, 0xff, + 0x28, 0x09, 0xd0, 0xff, 0xf7, 0x11, 0xfe, 0x03, + 0xcf, 0x08, 0x3f, 0xff, 0xf7, 0x16, 0xfe, 0x38, + 0x69, 0x10, 0x37, 0xff, 0x28, 0xf5, 0xd1, 0x01, + 0x20, 0x10, 0xf0, 0x26, 0xfd, 0xa0, 0x69, 0x1d, + 0x4f, 0x03, 0x28, 0x00, 0xdd, 0x08, 0x37, 0x38, + 0x68, 0xff, 0x28, 0x09, 0xd0, 0xff, 0xf7, 0xfc, + 0xfd, 0x03, 0xcf, 0x08, 0x3f, 0xff, 0xf7, 0x01, + 0xfe, 0x38, 0x69, 0x10, 0x37, 0xff, 0x28, 0xf5, + 0xd1, 0x01, 0x20, 0x10, 0xf0, 0x11, 0xfd, 0xa0, + 0x69, 0x13, 0x4f, 0x03, 0x28, 0x00, 0xdd, 0x08, + 0x37, 0x38, 0x68, 0xff, 0x28, 0x09, 0xd0, 0xff, + 0xf7, 0xe7, 0xfd, 0x03, 0xcf, 0x08, 0x3f, 0xff, + 0xf7, 0xec, 0xfd, 0x38, 0x69, 0x10, 0x37, 0xff, + 0x28, 0xf5, 0xd1, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x0a, 0x4f, 0x38, 0x68, 0xff, 0x28, 0xf8, + 0xd0, 0x03, 0xcf, 0x08, 0x3f, 0xff, 0xf7, 0xdd, + 0xfd, 0xb8, 0x68, 0x08, 0x37, 0xff, 0x28, 0xf7, + 0xd1, 0xef, 0xe7, 0x00, 0x00, 0x48, 0xe6, 0x03, + 0x20, 0xe0, 0x6f, 0x03, 0x20, 0x80, 0x70, 0x03, + 0x20, 0xb0, 0x70, 0x03, 0x20, 0x78, 0x6e, 0x03, + 0x20, 0x70, 0x47, 0x00, 0xb5, 0x23, 0x22, 0x12, + 0x01, 0x00, 0x21, 0x05, 0x48, 0xfe, 0xf7, 0x3e, + 0xf8, 0x04, 0x49, 0x00, 0x20, 0x88, 0x61, 0x04, + 0x49, 0x48, 0x60, 0x08, 0xbc, 0x18, 0x47, 0xed, + 0x09, 0x00, 0x23, 0x00, 0x00, 0x00, 0x44, 0xe7, + 0x03, 0x20, 0x88, 0xe5, 0x03, 0x20, 0x74, 0x73, + 0x03, 0x20, 0xf0, 0xb5, 0x8f, 0xb0, 0x01, 0xf0, + 0x80, 0xfe, 0x03, 0x1c, 0x0a, 0x1c, 0x19, 0x1c, + 0x2f, 0xa0, 0x12, 0xf0, 0x56, 0xfe, 0x35, 0x49, + 0x34, 0x4c, 0x00, 0x25, 0x0e, 0x91, 0x20, 0x68, + 0x00, 0x28, 0x4b, 0xd0, 0x32, 0xf0, 0x23, 0xfb, + 0x07, 0x1c, 0x60, 0x6a, 0x00, 0x28, 0x05, 0xd0, + 0x00, 0x7e, 0x10, 0x22, 0x04, 0xa9, 0x23, 0xf0, + 0x8c, 0xfb, 0x00, 0xe0, 0x2d, 0xa0, 0x06, 0x1c, + 0x20, 0x6a, 0x00, 0x28, 0x05, 0xd0, 0x00, 0x68, + 0x0a, 0x22, 0x09, 0xa9, 0x23, 0xf0, 0x81, 0xfb, + 0x00, 0xe0, 0x2a, 0xa0, 0x02, 0x1c, 0x29, 0x1c, + 0x33, 0x1c, 0x2c, 0xa0, 0x00, 0x97, 0x12, 0xf0, + 0x30, 0xfe, 0x0e, 0x99, 0x60, 0x6a, 0x32, 0x4f, + 0x00, 0x28, 0x01, 0xd0, 0xc1, 0x1d, 0x09, 0x31, + 0x31, 0xa0, 0x12, 0xf0, 0x26, 0xfe, 0x20, 0x6a, + 0x00, 0x69, 0x32, 0xf0, 0x86, 0xfb, 0x01, 0x1c, + 0x2f, 0xa0, 0x12, 0xf0, 0x1e, 0xfe, 0x63, 0x69, + 0x26, 0x69, 0xb8, 0x69, 0xa0, 0x42, 0x01, 0xd1, + 0x2d, 0xa2, 0x00, 0xe0, 0x2f, 0xa2, 0x60, 0x68, + 0x00, 0x28, 0x01, 0xd0, 0x2f, 0xa1, 0x00, 0xe0, + 0x31, 0xa1, 0xe0, 0x6a, 0x03, 0x92, 0xe2, 0x1d, + 0x01, 0x32, 0x00, 0x93, 0x01, 0x90, 0x02, 0x91, + 0x11, 0x68, 0x52, 0x68, 0x2f, 0xa0, 0x33, 0x1c, + 0x12, 0xf0, 0x03, 0xfe, 0x38, 0x34, 0x01, 0x35, + 0x0a, 0x2d, 0xac, 0xd3, 0x0f, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x5b, 0x53, + 0x63, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x5d, 0x20, + 0x6e, 0x6f, 0x77, 0x3d, 0x25, 0x4c, 0x78, 0x3a, + 0x0a, 0x00, 0x44, 0xe7, 0x03, 0x20, 0x80, 0xe6, + 0x03, 0x20, 0xed, 0x09, 0x00, 0x24, 0x00, 0x3c, + 0x6e, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x3e, + 0x00, 0x00, 0x00, 0x3c, 0x6e, 0x6f, 0x20, 0x70, + 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x74, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x5b, 0x25, 0x75, 0x5d, 0x20, + 0x50, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x74, 0x20, + 0x25, 0x73, 0x20, 0x4c, 0x69, 0x6e, 0x6b, 0x20, + 0x25, 0x73, 0x20, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x25, 0x73, 0x20, 0x00, 0x00, 0x88, + 0xe5, 0x03, 0x20, 0x28, 0x25, 0x3a, 0x2d, 0x36, + 0x42, 0x00, 0x00, 0x20, 0x25, 0x73, 0x29, 0x0a, + 0x00, 0x00, 0x00, 0x3c, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x3e, 0x00, 0x00, 0x00, 0x3c, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x3e, 0x00, 0x3c, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x3c, 0x77, 0x61, 0x69, 0x74, + 0x69, 0x6e, 0x67, 0x3e, 0x00, 0x00, 0x00, 0x09, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x25, 0x4c, + 0x78, 0x20, 0x45, 0x6e, 0x64, 0x20, 0x25, 0x4c, + 0x78, 0x20, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x20, + 0x25, 0x75, 0x20, 0x25, 0x73, 0x20, 0x25, 0x73, + 0x20, 0x0a, 0x00, 0xf1, 0xb5, 0x01, 0xf0, 0xa1, + 0xfd, 0x04, 0x1c, 0x0f, 0x1c, 0x23, 0x23, 0x0e, + 0x4d, 0x1b, 0x01, 0xee, 0x18, 0xb5, 0x42, 0x15, + 0xd2, 0x28, 0x68, 0x00, 0x28, 0x0f, 0xd0, 0x28, + 0x6a, 0x00, 0x99, 0x88, 0x42, 0x0b, 0xd0, 0xa8, + 0x68, 0x22, 0x1c, 0x3b, 0x1c, 0xe9, 0x68, 0x0e, + 0xf0, 0x4a, 0xfc, 0x00, 0x28, 0x03, 0xd0, 0x28, + 0x6a, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, + 0x35, 0xb5, 0x42, 0xe9, 0xd3, 0x00, 0x20, 0xf7, + 0xe7, 0x00, 0x00, 0x44, 0xe7, 0x03, 0x20, 0xff, + 0xb5, 0x1c, 0x1c, 0x0d, 0x1c, 0x07, 0x1c, 0x33, + 0xf0, 0xb6, 0xf9, 0x3b, 0x4e, 0xed, 0x09, 0x00, + 0x25, 0x00, 0x00, 0x20, 0x31, 0x68, 0x00, 0x29, + 0x69, 0xd1, 0x75, 0x62, 0xf5, 0x1d, 0x01, 0x35, + 0x37, 0x62, 0x01, 0xf0, 0x6d, 0xfd, 0x03, 0xc5, + 0x36, 0xa1, 0x28, 0xc9, 0xf0, 0x1d, 0x09, 0x30, + 0x28, 0xc0, 0x34, 0x60, 0x02, 0x9a, 0x00, 0x20, + 0xb2, 0x62, 0xf0, 0x62, 0xf8, 0x1d, 0x79, 0x30, + 0x08, 0x2c, 0x33, 0x4a, 0x31, 0x4d, 0x33, 0x49, + 0x08, 0xd2, 0x02, 0xa3, 0x1b, 0x5d, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0x04, 0x04, 0x04, 0x16, + 0x1e, 0x27, 0x2f, 0x37, 0x38, 0x6d, 0xb0, 0x61, + 0x78, 0x6d, 0xf0, 0x61, 0x30, 0x6a, 0x00, 0x69, + 0x01, 0x28, 0x04, 0xd1, 0x2a, 0x48, 0x30, 0x63, + 0x2a, 0x48, 0x70, 0x63, 0x2d, 0xe0, 0x2a, 0x48, + 0x30, 0x63, 0x2a, 0x48, 0x70, 0x63, 0x28, 0xe0, + 0xfa, 0x6f, 0xb2, 0x61, 0x00, 0x68, 0xf0, 0x61, + 0x27, 0x48, 0x30, 0x63, 0x71, 0x63, 0x20, 0xe0, + 0x78, 0x6e, 0xb0, 0x61, 0xb8, 0x6e, 0xf0, 0x61, + 0x23, 0x48, 0x30, 0x63, 0x71, 0x63, 0x7e, 0x67, + 0x17, 0xe0, 0xc1, 0x6a, 0xb1, 0x61, 0x01, 0x6b, + 0xf1, 0x61, 0x32, 0x63, 0x75, 0x63, 0xc6, 0x63, + 0x0f, 0xe0, 0xc1, 0x68, 0xb1, 0x61, 0x01, 0x69, + 0xf1, 0x61, 0x32, 0x63, 0x75, 0x63, 0x86, 0x62, + 0x07, 0xe0, 0x01, 0x20, 0x00, 0x03, 0xb0, 0x61, + 0xf0, 0x61, 0x18, 0x48, 0x30, 0x63, 0x18, 0x48, + 0x70, 0x63, 0x33, 0xf0, 0x4f, 0xf9, 0x01, 0x20, + 0x00, 0xf0, 0x4e, 0xfa, 0x15, 0x48, 0x01, 0x21, + 0x33, 0xf0, 0x68, 0xf9, 0x00, 0x20, 0x04, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xe7, + 0x01, 0x30, 0x38, 0x36, 0x0a, 0x28, 0x8d, 0xd3, + 0x33, 0xf0, 0x3c, 0xf9, 0x07, 0x20, 0xf2, 0xe7, + 0x44, 0xe7, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x39, 0x5c, 0x00, 0x20, + 0xed, 0x09, 0x00, 0x26, 0x00, 0x6d, 0x5a, 0x00, + 0x20, 0x89, 0x5f, 0x00, 0x20, 0x59, 0x72, 0x00, + 0x20, 0xad, 0x73, 0x00, 0x20, 0x21, 0x84, 0x00, + 0x20, 0x3d, 0x85, 0x00, 0x20, 0x11, 0x60, 0x00, + 0x20, 0x65, 0x11, 0x00, 0x20, 0x1d, 0x12, 0x00, + 0x20, 0x78, 0x73, 0x03, 0x20, 0x80, 0xb4, 0x1a, + 0x4a, 0x00, 0x23, 0x17, 0x68, 0x8f, 0x42, 0x29, + 0xd1, 0x17, 0x6a, 0x87, 0x42, 0x26, 0xd1, 0x0f, + 0x1c, 0xc1, 0x1d, 0x79, 0x31, 0x07, 0x2f, 0x0b, + 0xd2, 0x01, 0xa3, 0xdb, 0x5d, 0x5b, 0x00, 0x9f, + 0x44, 0x07, 0x07, 0x03, 0x09, 0x0e, 0x13, 0x18, + 0x00, 0x01, 0x6d, 0x91, 0x61, 0x40, 0x6d, 0xd0, + 0x61, 0x80, 0xbc, 0x70, 0x47, 0xc0, 0x6f, 0x90, + 0x61, 0x08, 0x68, 0xd0, 0x61, 0xf8, 0xe7, 0x41, + 0x6e, 0x91, 0x61, 0x80, 0x6e, 0xd0, 0x61, 0xf3, + 0xe7, 0xc8, 0x6a, 0x90, 0x61, 0x08, 0x6b, 0xd0, + 0x61, 0xee, 0xe7, 0xc8, 0x68, 0x90, 0x61, 0x08, + 0x69, 0xd0, 0x61, 0xe9, 0xe7, 0x38, 0x32, 0x01, + 0x33, 0x0a, 0x2b, 0xce, 0xd3, 0xe4, 0xe7, 0x00, + 0x00, 0x44, 0xe7, 0x03, 0x20, 0xb0, 0xb5, 0x0c, + 0x1c, 0x07, 0x1c, 0x00, 0x28, 0x13, 0xd0, 0x00, + 0x2c, 0x01, 0xd0, 0x33, 0xf0, 0xe1, 0xf8, 0x0a, + 0x48, 0x00, 0x25, 0x01, 0x6a, 0xb9, 0x42, 0x03, + 0xd0, 0x38, 0x30, 0x01, 0x35, 0x0a, 0x2d, 0xf8, + 0xd3, 0x00, 0x2c, 0x01, 0xd0, 0x33, 0xf0, 0xd0, + 0xf8, 0x0a, 0x2d, 0x00, 0xd1, 0x00, 0x27, 0x38, + 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x44, 0xe7, 0x03, 0x20, 0xf3, 0xb5, 0x81, + 0xb0, 0x45, 0x68, 0x1b, 0x4b, 0x00, 0x27, 0x01, + 0x1c, 0xec, 0x18, 0xb3, 0x23, 0x9b, 0x00, 0x17, + 0x4a, 0xeb, 0x18, 0x00, 0x95, 0x15, 0x6a, 0x00, + 0x9e, 0xb5, 0x42, 0x22, 0xd1, 0x15, 0x68, 0x02, + 0x9e, 0xb5, 0x42, 0xed, 0x09, 0x00, 0x27, 0x00, + 0x1e, 0xd1, 0xff, 0x31, 0x35, 0x31, 0x81, 0x42, + 0x1a, 0xd0, 0x8c, 0x42, 0x00, 0xd8, 0x19, 0x1c, + 0xcd, 0x68, 0x05, 0x2d, 0x01, 0xd0, 0x03, 0x2d, + 0x0e, 0xd1, 0x0d, 0x4b, 0x5f, 0x69, 0x87, 0x42, + 0x00, 0xd1, 0x59, 0x61, 0x51, 0x62, 0x49, 0x6f, + 0x00, 0x29, 0x01, 0xd0, 0x00, 0x20, 0x88, 0x65, + 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xff, 0x31, 0x35, 0x31, 0x81, 0x42, 0xe4, 0xd1, + 0x38, 0x32, 0x01, 0x37, 0x0a, 0x2f, 0xd4, 0xd3, + 0xf2, 0xe7, 0x44, 0xe7, 0x03, 0x20, 0x38, 0x0b, + 0x00, 0x00, 0x68, 0x14, 0x04, 0x20, 0xff, 0xb5, + 0x1c, 0x1c, 0x0f, 0x1c, 0x33, 0xf0, 0x87, 0xf8, + 0x6d, 0x4e, 0x00, 0x20, 0x00, 0x21, 0x35, 0x1c, + 0x2a, 0x6a, 0x00, 0x9b, 0x9a, 0x42, 0x16, 0xd1, + 0x2a, 0x68, 0xa2, 0x42, 0x13, 0xd1, 0x07, 0x2c, + 0x11, 0xd2, 0x01, 0xa3, 0x1b, 0x5d, 0x5b, 0x00, + 0x9f, 0x44, 0x0d, 0x0d, 0x13, 0x0d, 0x09, 0x0d, + 0x03, 0x00, 0x00, 0x9b, 0x00, 0x20, 0xd9, 0x1d, + 0x79, 0x31, 0x88, 0x62, 0x09, 0xe0, 0x00, 0x9b, + 0x00, 0x20, 0x58, 0x67, 0x05, 0xe0, 0x01, 0x29, + 0x03, 0xd0, 0x01, 0x30, 0x38, 0x35, 0x0a, 0x28, + 0xde, 0xd3, 0x00, 0x20, 0x00, 0x22, 0x31, 0x1c, + 0x0b, 0x6a, 0xbb, 0x42, 0x13, 0xd1, 0x0b, 0x68, + 0x09, 0x9e, 0xb3, 0x42, 0x03, 0xd0, 0x02, 0x2c, + 0x0d, 0xd1, 0x01, 0x2b, 0x0b, 0xd1, 0x09, 0x9e, + 0x07, 0x2e, 0x08, 0xd2, 0x02, 0xa3, 0x9b, 0x5d, + 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x04, 0x0b, + 0x0b, 0x04, 0x04, 0x04, 0x04, 0x00, 0x01, 0x2a, + 0x04, 0xd0, 0x01, 0x30, 0x38, 0x31, 0x0a, 0x28, + 0xe2, 0xd3, 0x17, 0xe0, 0x8d, 0x42, 0x15, 0xd0, + 0x02, 0x9a, 0x02, 0x20, 0x08, 0x60, 0x48, 0x48, + 0x4a, 0x62, 0x01, 0x60, 0x0b, 0x98, 0xed, 0x09, + 0x00, 0x28, 0x00, 0x00, 0x28, 0x07, 0xd0, 0x00, + 0x98, 0x0a, 0x99, 0x0c, 0x9b, 0x22, 0x1c, 0x00, + 0xf0, 0x9c, 0xf8, 0x07, 0x1c, 0x79, 0xe0, 0x02, + 0x20, 0x00, 0xf0, 0x29, 0xf9, 0x07, 0x1c, 0x74, + 0xe0, 0x0a, 0x99, 0xe8, 0x1d, 0xa9, 0x62, 0x09, + 0x9e, 0x3e, 0xa1, 0x2e, 0x60, 0x02, 0x9a, 0x09, + 0x30, 0x6a, 0x62, 0x48, 0xc9, 0x48, 0xc0, 0xee, + 0x1d, 0x01, 0x36, 0x01, 0xf0, 0xdc, 0xfb, 0x03, + 0xc6, 0x04, 0x2c, 0x0a, 0xd1, 0x09, 0x9e, 0x02, + 0x2e, 0x07, 0xd1, 0xf8, 0x1d, 0xff, 0x30, 0x7a, + 0x30, 0x41, 0x69, 0x00, 0x29, 0x01, 0xd0, 0x01, + 0x39, 0x41, 0x61, 0x09, 0x9e, 0xf8, 0x1d, 0x79, + 0x30, 0x07, 0x2e, 0x31, 0x4c, 0x32, 0x4a, 0x32, + 0x49, 0x39, 0xd2, 0x01, 0xa3, 0x9b, 0x5d, 0x5b, + 0x00, 0x9f, 0x44, 0x35, 0x03, 0x03, 0x15, 0x1d, + 0x26, 0x2e, 0x00, 0x38, 0x6d, 0xa8, 0x61, 0x78, + 0x6d, 0xe8, 0x61, 0x28, 0x6a, 0x00, 0x69, 0x01, + 0x28, 0x04, 0xd1, 0x2a, 0x48, 0x28, 0x63, 0x2a, + 0x48, 0x68, 0x63, 0x24, 0xe0, 0x2a, 0x48, 0x28, + 0x63, 0x2a, 0x48, 0x68, 0x63, 0x1f, 0xe0, 0xfa, + 0x6f, 0xaa, 0x61, 0x00, 0x68, 0xe8, 0x61, 0x27, + 0x48, 0x28, 0x63, 0x69, 0x63, 0x17, 0xe0, 0x78, + 0x6e, 0xa8, 0x61, 0xb8, 0x6e, 0xe8, 0x61, 0x23, + 0x48, 0x28, 0x63, 0x69, 0x63, 0x7d, 0x67, 0x0e, + 0xe0, 0xc1, 0x6a, 0xa9, 0x61, 0x01, 0x6b, 0xe9, + 0x61, 0x2a, 0x63, 0x6c, 0x63, 0xc5, 0x63, 0x06, + 0xe0, 0xc1, 0x68, 0xa9, 0x61, 0x01, 0x69, 0xe9, + 0x61, 0x2a, 0x63, 0x6c, 0x63, 0x85, 0x62, 0x02, + 0x9a, 0xd0, 0x1d, 0x79, 0x30, 0x40, 0x69, 0x00, + 0x28, 0x06, 0xd1, 0x02, 0x9a, 0x50, 0x68, 0xff, + 0x30, 0x81, 0x30, 0x00, 0x69, 0x80, 0x07, 0x04, + 0xd0, 0x04, 0x20, 0x00, 0xf0, 0xb8, 0xf8, 0x07, + 0x1c, 0xed, 0x09, 0x00, 0x29, 0x00, 0x03, 0xe0, + 0x02, 0x20, 0x00, 0xf0, 0xb3, 0xf8, 0x07, 0x1c, + 0x32, 0xf0, 0xae, 0xff, 0x38, 0x1c, 0x04, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x44, 0xe7, 0x03, 0x20, 0x74, 0x73, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x39, 0x5c, 0x00, 0x20, 0x6d, 0x5a, 0x00, 0x20, + 0x89, 0x5f, 0x00, 0x20, 0x59, 0x72, 0x00, 0x20, + 0xad, 0x73, 0x00, 0x20, 0x21, 0x84, 0x00, 0x20, + 0x3d, 0x85, 0x00, 0x20, 0x11, 0x60, 0x00, 0x20, + 0xf0, 0xb5, 0x14, 0x1c, 0x1d, 0x1c, 0x0e, 0x1c, + 0x07, 0x1c, 0x32, 0xf0, 0x8d, 0xff, 0x29, 0x48, + 0x00, 0x21, 0x02, 0x6a, 0xba, 0x42, 0x44, 0xd1, + 0x02, 0x68, 0xa2, 0x42, 0x41, 0xd1, 0x22, 0x1c, + 0xfc, 0x1d, 0xff, 0x34, 0xf9, 0x1d, 0x79, 0x31, + 0x7a, 0x34, 0x08, 0x2a, 0x15, 0xd2, 0x02, 0xa3, + 0x9b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, + 0x11, 0x11, 0x11, 0x09, 0x07, 0x04, 0x0f, 0x11, + 0x00, 0x22, 0xca, 0x63, 0x09, 0xe0, 0x00, 0x22, + 0x7a, 0x67, 0x61, 0x69, 0x00, 0x29, 0x04, 0xd0, + 0x01, 0x39, 0x61, 0x61, 0x01, 0xe0, 0x00, 0x22, + 0x8a, 0x62, 0x00, 0x22, 0x02, 0x60, 0x00, 0x6a, + 0xc6, 0x60, 0x02, 0x20, 0x00, 0xf0, 0x5e, 0xf8, + 0x06, 0x1c, 0x32, 0xf0, 0x59, 0xff, 0x12, 0x48, + 0x01, 0x21, 0x32, 0xf0, 0x71, 0xff, 0x01, 0x28, + 0x01, 0xd1, 0x0e, 0xf0, 0x49, 0xff, 0x00, 0x2d, + 0x0b, 0xd0, 0x60, 0x69, 0x00, 0x28, 0x08, 0xd1, + 0x01, 0x21, 0x38, 0x1c, 0x01, 0xf0, 0x64, 0xfc, + 0x00, 0x28, 0x02, 0xd1, 0x38, 0x1c, 0x01, 0xf0, + 0xc1, 0xfc, 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x38, 0x30, 0x01, 0x31, 0x0a, 0x29, + 0xb3, 0xd3, 0x32, 0xf0, 0x39, 0xff, 0x00, 0x20, + 0xf4, 0xe7, 0x00, 0x00, 0xed, 0x09, 0x00, 0x2a, + 0x00, 0x44, 0xe7, 0x03, 0x20, 0x78, 0x73, 0x03, + 0x20, 0xf0, 0xb5, 0x82, 0xb0, 0x0c, 0x1c, 0x05, + 0x1c, 0x17, 0x1c, 0x32, 0xf0, 0x2f, 0xff, 0x15, + 0x4e, 0x00, 0x20, 0x31, 0x6a, 0xa9, 0x42, 0x1d, + 0xd1, 0x31, 0x68, 0xa1, 0x42, 0x1a, 0xd1, 0x01, + 0xf0, 0xe7, 0xfa, 0x00, 0x90, 0x01, 0x91, 0x00, + 0x99, 0xf8, 0x1f, 0xc1, 0x38, 0x81, 0x42, 0x02, + 0xd9, 0x01, 0x98, 0x01, 0x30, 0x01, 0x90, 0x69, + 0x46, 0xf0, 0x1d, 0x48, 0xc9, 0x01, 0x30, 0x48, + 0xc0, 0x02, 0x20, 0x00, 0xf0, 0x11, 0xf8, 0x32, + 0xf0, 0x0d, 0xff, 0x00, 0x20, 0x02, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x30, 0x38, + 0x36, 0x0a, 0x28, 0xda, 0xd3, 0x32, 0xf0, 0x02, + 0xff, 0x01, 0x20, 0xf3, 0xe7, 0x44, 0xe7, 0x03, + 0x20, 0xf0, 0xb5, 0x86, 0xb0, 0x82, 0xa3, 0x5c, + 0x68, 0x1d, 0x68, 0x07, 0x1c, 0x32, 0xf0, 0xfa, + 0xfe, 0x01, 0xf0, 0xba, 0xfa, 0x01, 0x90, 0x80, + 0x48, 0x02, 0x91, 0x86, 0x69, 0x05, 0x2f, 0x75, + 0xd2, 0x01, 0xa3, 0xdb, 0x5d, 0x5b, 0x00, 0x9f, + 0x44, 0x0b, 0x02, 0x28, 0x19, 0xa2, 0x00, 0x00, + 0x2e, 0x23, 0xd0, 0x32, 0xf0, 0xe3, 0xfe, 0x00, + 0x20, 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x2e, 0x1a, 0xd0, 0x30, 0x69, 0x71, + 0x69, 0x01, 0x9a, 0x02, 0x9b, 0x0e, 0xf0, 0xfe, + 0xf8, 0x00, 0x28, 0x12, 0xd0, 0x32, 0xf0, 0xd2, + 0xfe, 0x00, 0x20, 0xed, 0xe7, 0x2d, 0x23, 0x9b, + 0x01, 0x30, 0x6a, 0x6e, 0x4a, 0xc0, 0x18, 0x40, + 0x68, 0xf7, 0x1d, 0x42, 0x43, 0x01, 0x98, 0x01, + 0x37, 0x02, 0x99, 0x00, 0x23, 0x80, 0x18, 0x59, + 0x41, 0x03, 0xc7, 0x69, 0x49, 0x01, 0x20, 0xc8, + 0x60, 0x88, 0x68, 0x40, 0x08, 0x40, 0x00, 0x88, + 0x60, 0x66, 0x4f, 0x00, 0x2e, 0x0d, 0xd0, 0xed, + 0x09, 0x00, 0x2b, 0x00, 0x72, 0x6b, 0x00, 0x2a, + 0x03, 0xd0, 0x01, 0x20, 0x31, 0x6a, 0xfd, 0xf7, + 0xa0, 0xfc, 0x00, 0x20, 0x70, 0x60, 0x31, 0x68, + 0x00, 0x29, 0x03, 0xd1, 0x30, 0x62, 0x01, 0xe0, + 0xfe, 0x1f, 0x31, 0x3e, 0x5e, 0x49, 0x08, 0x68, + 0x00, 0x28, 0x03, 0xd0, 0xc6, 0x1f, 0x31, 0x3e, + 0x00, 0x20, 0x08, 0x60, 0x00, 0x20, 0x00, 0x90, + 0x5a, 0x48, 0x05, 0x90, 0x05, 0x98, 0x38, 0x36, + 0x86, 0x42, 0x55, 0x4f, 0x00, 0xd1, 0x3e, 0x1c, + 0x30, 0x68, 0x00, 0x28, 0x44, 0xd0, 0x01, 0x28, + 0x42, 0xd0, 0xb0, 0x68, 0xf7, 0x1d, 0x04, 0x90, + 0xf1, 0x68, 0x01, 0x9a, 0x02, 0x9b, 0x01, 0x37, + 0x03, 0x91, 0x0e, 0xf0, 0x0a, 0xf9, 0x00, 0x28, + 0x2c, 0xd0, 0xb0, 0x69, 0x49, 0x4a, 0x00, 0x23, + 0x42, 0x43, 0xb0, 0x68, 0xf1, 0x68, 0x80, 0x18, + 0x59, 0x41, 0x03, 0xc7, 0x08, 0x3f, 0x01, 0x9a, + 0x00, 0xe0, 0x47, 0xe0, 0x02, 0x9b, 0x0e, 0xf0, + 0xf8, 0xf8, 0x00, 0x28, 0x03, 0xd0, 0x02, 0x99, + 0x79, 0x60, 0x01, 0x98, 0x38, 0x60, 0xf0, 0x69, + 0x3e, 0x4a, 0xf7, 0x1d, 0x42, 0x43, 0x01, 0x98, + 0x09, 0x37, 0x02, 0x99, 0x00, 0x23, 0x80, 0x18, + 0x59, 0x41, 0x03, 0xc7, 0x01, 0x20, 0x70, 0x60, + 0xf0, 0x6a, 0x01, 0x30, 0xf0, 0x62, 0xb0, 0x6a, + 0x31, 0x6a, 0xc8, 0x60, 0x00, 0x98, 0x0a, 0x28, + 0x2f, 0xd2, 0x16, 0xe0, 0x2a, 0x1c, 0x23, 0x1c, + 0x04, 0x98, 0x03, 0x99, 0x0e, 0xf0, 0xd5, 0xf8, + 0x00, 0x28, 0x01, 0xd0, 0x7c, 0x68, 0x3d, 0x68, + 0x00, 0x98, 0x01, 0x30, 0x00, 0x90, 0x0a, 0x28, + 0xac, 0xd3, 0x1e, 0xe0, 0x72, 0x6b, 0x00, 0x2a, + 0x03, 0xd0, 0x01, 0x20, 0x31, 0x6a, 0xfd, 0xf7, + 0x30, 0xfc, 0x00, 0x2e, 0x15, 0xd0, 0x30, 0x6a, + 0x25, 0x49, 0x48, 0x61, 0x8e, 0x61, 0x33, 0x6b, + 0x00, 0x2b, 0xed, 0x09, 0x00, 0x2c, 0x00, 0x04, + 0xd0, 0x31, 0x6a, 0x72, 0x6a, 0x01, 0x20, 0xfd, + 0xf7, 0x23, 0xfc, 0x32, 0xf0, 0x30, 0xfe, 0x35, + 0xe0, 0x1e, 0x49, 0x00, 0x20, 0x88, 0x61, 0x32, + 0xf0, 0x2a, 0xfe, 0x01, 0x20, 0x45, 0xe7, 0x1a, + 0x48, 0x00, 0x27, 0x47, 0x61, 0x87, 0x61, 0x16, + 0xa3, 0x1a, 0x68, 0x28, 0x1c, 0x21, 0x1c, 0x5b, + 0x68, 0x0d, 0xf0, 0xdd, 0xff, 0x00, 0x28, 0x1f, + 0xd0, 0x0e, 0xf0, 0x11, 0xfe, 0x28, 0x1c, 0x14, + 0x4e, 0x21, 0x1c, 0x31, 0x69, 0x40, 0x1a, 0x14, + 0x28, 0x01, 0xda, 0x01, 0x20, 0x00, 0xe0, 0x38, + 0x1c, 0x00, 0x28, 0x06, 0xd0, 0x01, 0xf0, 0xd1, + 0xf9, 0x64, 0x22, 0x0e, 0xf0, 0x84, 0xf8, 0x0c, + 0x1c, 0x05, 0x1c, 0x01, 0x20, 0xf0, 0x60, 0x75, + 0x61, 0xb0, 0x68, 0x01, 0x23, 0x18, 0x43, 0xb0, + 0x60, 0x21, 0x1c, 0x32, 0xf0, 0xfc, 0xfd, 0x01, + 0xe0, 0x32, 0xf0, 0xf9, 0xfd, 0x01, 0x20, 0x14, + 0xe7, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x88, 0xe5, 0x03, 0x20, 0x71, + 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, 0x44, + 0xe7, 0x03, 0x20, 0x74, 0x73, 0x03, 0x20, 0x74, + 0xe9, 0x03, 0x20, 0xf7, 0xb5, 0x00, 0x24, 0x0d, + 0x1c, 0x06, 0x1c, 0xfd, 0xf7, 0x89, 0xff, 0x07, + 0x1c, 0x02, 0xd1, 0xff, 0x24, 0x01, 0x34, 0x42, + 0xe0, 0x01, 0x20, 0x07, 0xf0, 0xb6, 0xf8, 0x00, + 0x28, 0x08, 0xd0, 0x74, 0x20, 0x38, 0x60, 0x0c, + 0x24, 0x09, 0x20, 0x39, 0x1c, 0xfc, 0x60, 0xfd, + 0xf7, 0xe6, 0xff, 0x34, 0xe0, 0x07, 0xf0, 0x6f, + 0xf8, 0x00, 0x28, 0x0e, 0xd1, 0x1b, 0xa1, 0x01, + 0x20, 0x06, 0xf0, 0xf5, 0xff, 0x00, 0x28, 0x08, + 0xd1, 0x74, 0x20, 0x38, 0x60, 0x07, 0x24, 0x09, + 0x20, 0x39, 0x1c, 0xfc, 0x60, 0xfd, 0xf7, 0xd3, + 0xff, 0x21, 0xe0, 0x37, 0x23, 0xed, 0x09, 0x00, + 0x2d, 0x00, 0x9b, 0x01, 0xc1, 0x18, 0x02, 0x9a, + 0x15, 0x4b, 0x0a, 0x62, 0xc1, 0x18, 0x4d, 0x60, + 0x0e, 0x60, 0xf8, 0x60, 0x01, 0x21, 0x39, 0x60, + 0x01, 0x69, 0x1a, 0x29, 0x02, 0xd1, 0xc1, 0x68, + 0x39, 0x61, 0x01, 0xe0, 0x00, 0x21, 0x39, 0x61, + 0x01, 0x21, 0x49, 0x03, 0xf9, 0x61, 0xbd, 0x61, + 0x7e, 0x61, 0x39, 0x62, 0x00, 0x22, 0x04, 0x21, + 0x06, 0xf0, 0x32, 0xff, 0x0b, 0x20, 0x39, 0x1c, + 0xfd, 0xf7, 0xb0, 0xff, 0x20, 0x1c, 0x03, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x69, 0x66, + 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x36, 0x30, 0x00, + 0xd8, 0x0d, 0x00, 0x00, 0xf0, 0xb5, 0x00, 0x24, + 0x06, 0x1c, 0xfd, 0xf7, 0x2c, 0xff, 0x07, 0x1c, + 0x02, 0xd1, 0xff, 0x24, 0x01, 0x34, 0x3c, 0xe0, + 0x0c, 0x20, 0x07, 0xf0, 0x11, 0xf8, 0x05, 0x1c, + 0x13, 0xd1, 0x14, 0x20, 0x07, 0xf0, 0x0c, 0xf8, + 0x05, 0x1c, 0x0e, 0xd1, 0x0c, 0x24, 0x00, 0x2e, + 0x07, 0xd0, 0x75, 0x20, 0x38, 0x60, 0x09, 0x20, + 0x39, 0x1c, 0xfc, 0x60, 0xfd, 0xf7, 0x82, 0xff, + 0x27, 0xe0, 0x38, 0x1c, 0xfd, 0xf7, 0x4a, 0xff, + 0x23, 0xe0, 0x00, 0x22, 0x05, 0x21, 0x28, 0x1c, + 0x06, 0xf0, 0xf6, 0xfe, 0x00, 0x28, 0x0e, 0xd0, + 0x0c, 0x24, 0x00, 0x2e, 0x07, 0xd0, 0x75, 0x20, + 0x38, 0x60, 0x09, 0x20, 0x39, 0x1c, 0xfc, 0x60, + 0xfd, 0xf7, 0x6c, 0xff, 0x11, 0xe0, 0x38, 0x1c, + 0xfd, 0xf7, 0x34, 0xff, 0x0d, 0xe0, 0x02, 0x20, + 0x6e, 0x61, 0x38, 0x60, 0xe8, 0x68, 0x01, 0x22, + 0xf8, 0x60, 0x00, 0x20, 0x29, 0x1c, 0x07, 0xf0, + 0x8d, 0xf8, 0x0b, 0x20, 0x39, 0x1c, 0xfd, 0xf7, + 0x59, 0xff, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xff, 0xb5, 0x84, 0xb0, 0x07, 0x1c, + 0xed, 0x09, 0x00, 0x2e, 0x00, 0x00, 0x20, 0x47, + 0x4e, 0x03, 0x90, 0x03, 0xce, 0x08, 0x3e, 0x81, + 0x42, 0x02, 0xd0, 0x0c, 0x20, 0x03, 0x90, 0x73, + 0xe0, 0xb8, 0x42, 0x3c, 0xd0, 0x01, 0x2f, 0x0c, + 0xd1, 0x00, 0x28, 0x02, 0xd1, 0x01, 0x25, 0x00, + 0x24, 0x49, 0xe0, 0x02, 0x28, 0x02, 0xd1, 0x01, + 0x25, 0x02, 0x24, 0x2c, 0xe0, 0x00, 0x25, 0x02, + 0x24, 0x29, 0xe0, 0x02, 0x2f, 0x0c, 0xd1, 0x00, + 0x28, 0x02, 0xd1, 0x00, 0x25, 0x01, 0x24, 0x3a, + 0xe0, 0x01, 0x28, 0x02, 0xd1, 0x02, 0x25, 0x01, + 0x24, 0x2e, 0xe0, 0x02, 0x25, 0x00, 0x24, 0x2b, + 0xe0, 0x03, 0x2f, 0x0c, 0xd1, 0x00, 0x28, 0x02, + 0xd1, 0x01, 0x25, 0x01, 0x24, 0x26, 0xe0, 0x01, + 0x28, 0x02, 0xd1, 0x00, 0x25, 0x01, 0x24, 0x0e, + 0xe0, 0x01, 0x25, 0x00, 0x24, 0x0b, 0xe0, 0x03, + 0x28, 0x02, 0xd1, 0x02, 0x25, 0x02, 0x24, 0x19, + 0xe0, 0x01, 0x28, 0x02, 0xd1, 0x02, 0x25, 0x00, + 0x24, 0x01, 0xe0, 0x00, 0x25, 0x02, 0x24, 0x00, + 0x2d, 0x0e, 0xd1, 0x00, 0x2c, 0x13, 0xd1, 0xfd, + 0xf7, 0x98, 0xfe, 0x00, 0x28, 0x3c, 0xd0, 0x6e, + 0x21, 0x01, 0x60, 0x00, 0x21, 0xc1, 0x60, 0x01, + 0x1c, 0x09, 0x20, 0xfd, 0xf7, 0xfd, 0xfe, 0x33, + 0xe0, 0x00, 0x2c, 0x04, 0xd0, 0x01, 0x20, 0xf0, + 0x60, 0x00, 0x20, 0x30, 0x61, 0x01, 0xe0, 0x00, + 0x20, 0xf0, 0x60, 0x06, 0x98, 0x07, 0x99, 0x0d, + 0x9a, 0x00, 0x90, 0x01, 0x91, 0x29, 0x1c, 0x00, + 0x20, 0x02, 0x92, 0x22, 0x1c, 0x05, 0x9b, 0x08, + 0xf0, 0x05, 0xfd, 0x03, 0x90, 0x00, 0x28, 0x0f, + 0xd1, 0xb4, 0x61, 0x75, 0x61, 0x77, 0x60, 0x07, + 0x99, 0x71, 0x62, 0x0d, 0x9a, 0xb2, 0x62, 0x05, + 0x99, 0xf1, 0x61, 0x06, 0x98, 0x30, 0x62, 0x07, + 0x98, 0x0d, 0x99, 0x08, 0xf0, 0xa3, 0xfe, 0x0b, + 0xe0, 0xfd, 0xf7, 0xed, 0x09, 0x00, 0x2f, 0x00, + 0x63, 0xfe, 0x00, 0x28, 0x07, 0xd0, 0x6e, 0x21, + 0x01, 0x60, 0x03, 0x99, 0xc1, 0x60, 0x01, 0x1c, + 0x09, 0x20, 0xfd, 0xf7, 0xc8, 0xfe, 0x03, 0x98, + 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, 0xf0, 0xb5, + 0x06, 0x1c, 0x03, 0x20, 0x00, 0x24, 0x0d, 0x1c, + 0x06, 0xf0, 0x37, 0xff, 0x07, 0x1c, 0x0b, 0xd1, + 0x04, 0x20, 0x06, 0xf0, 0x32, 0xff, 0x07, 0x1c, + 0x06, 0xd1, 0x05, 0x20, 0x06, 0xf0, 0x2d, 0xff, + 0x07, 0x1c, 0x01, 0xd1, 0x0c, 0x24, 0x14, 0xe0, + 0x0c, 0x48, 0x05, 0x62, 0xc6, 0x61, 0xfd, 0xf7, + 0x37, 0xfe, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x24, + 0x0b, 0xe0, 0x06, 0x21, 0x01, 0x60, 0xf9, 0x68, + 0xc1, 0x60, 0x71, 0x00, 0x01, 0x61, 0x69, 0x00, + 0x41, 0x61, 0x01, 0x1c, 0x0b, 0x20, 0xfd, 0xf7, + 0x96, 0xfe, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xd8, 0xeb, 0x03, 0x20, 0xf0, 0xb5, + 0x06, 0x1c, 0x07, 0x20, 0x00, 0x24, 0x0d, 0x1c, + 0x06, 0xf0, 0x07, 0xff, 0x07, 0x1c, 0x0b, 0xd1, + 0x08, 0x20, 0x06, 0xf0, 0x02, 0xff, 0x07, 0x1c, + 0x06, 0xd1, 0x09, 0x20, 0x06, 0xf0, 0xfd, 0xfe, + 0x07, 0x1c, 0x01, 0xd1, 0x0c, 0x24, 0x18, 0xe0, + 0x0e, 0x48, 0x85, 0x62, 0x46, 0x62, 0x30, 0x1c, + 0x29, 0x1c, 0x08, 0xf0, 0x42, 0xfe, 0xfd, 0xf7, + 0x03, 0xfe, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x24, + 0x0b, 0xe0, 0x0b, 0x21, 0x01, 0x60, 0xf9, 0x68, + 0xc1, 0x60, 0x71, 0x00, 0x01, 0x61, 0x69, 0x00, + 0x41, 0x61, 0x01, 0x1c, 0x0b, 0x20, 0xfd, 0xf7, + 0x62, 0xfe, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xd8, 0xeb, 0x03, 0x20, 0x0f, 0xb4, + 0xf0, 0xb5, 0x00, 0x25, 0x06, 0x1c, 0x01, 0x20, + 0x06, 0xf0, 0x1b, 0xff, 0x00, 0x28, 0xed, 0x09, + 0x00, 0x30, 0x00, 0x01, 0xd0, 0x0c, 0x25, 0x1f, + 0xe0, 0xfd, 0xf7, 0xe0, 0xfd, 0x07, 0x1c, 0x01, + 0xd1, 0x07, 0x25, 0x19, 0xe0, 0x06, 0xf0, 0xd5, + 0xfe, 0x04, 0x1c, 0x0a, 0xd1, 0x33, 0xa1, 0x01, + 0x20, 0x06, 0xf0, 0x5b, 0xfe, 0x04, 0x1c, 0x04, + 0xd1, 0x38, 0x1c, 0xfd, 0xf7, 0x0a, 0xfe, 0x07, + 0x25, 0x0a, 0xe0, 0x02, 0x21, 0x20, 0x1c, 0x0b, + 0x9a, 0x06, 0xf0, 0xef, 0xff, 0x00, 0x28, 0x16, + 0xd1, 0x38, 0x1c, 0xfd, 0xf7, 0xfe, 0xfd, 0x09, + 0x25, 0xfd, 0xf7, 0xc0, 0xfd, 0x00, 0x28, 0x09, + 0xd0, 0x6f, 0x21, 0x01, 0x60, 0x00, 0x21, 0x01, + 0x61, 0x45, 0x61, 0xc6, 0x60, 0x01, 0x1c, 0x09, + 0x20, 0xfd, 0xf7, 0x23, 0xfe, 0x28, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x04, 0xb0, 0x18, 0x47, 0xc6, + 0x60, 0x07, 0x9a, 0x08, 0xae, 0x82, 0x61, 0x06, + 0x9a, 0x42, 0x61, 0x0a, 0x99, 0x01, 0x87, 0x0c, + 0xce, 0xc1, 0x1d, 0x29, 0x31, 0x0c, 0xc1, 0x37, + 0x23, 0x9b, 0x01, 0xe1, 0x18, 0x48, 0x63, 0x1a, + 0x4e, 0xe1, 0x1d, 0x0c, 0xce, 0x29, 0x31, 0x0c, + 0xc1, 0xf8, 0x60, 0x07, 0x21, 0x39, 0x60, 0x41, + 0x68, 0x39, 0x61, 0x21, 0x69, 0x1a, 0x29, 0x03, + 0xd1, 0x41, 0x68, 0xc9, 0x68, 0x79, 0x61, 0x01, + 0xe0, 0x00, 0x21, 0x79, 0x61, 0x00, 0x7f, 0xb8, + 0x61, 0x07, 0x9a, 0xf8, 0x1d, 0x3a, 0x62, 0x06, + 0x99, 0x1d, 0x30, 0xf9, 0x61, 0x08, 0xa9, 0x0c, + 0xc9, 0x0c, 0xc0, 0x0f, 0x98, 0x00, 0x22, 0xf8, + 0x62, 0x10, 0x98, 0x08, 0x21, 0x38, 0x63, 0x0c, + 0x98, 0x78, 0x63, 0x20, 0x1c, 0x06, 0xf0, 0x63, + 0xfd, 0x0b, 0x20, 0x39, 0x1c, 0xfd, 0xf7, 0xe1, + 0xfd, 0xbc, 0xe7, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x63, 0x69, 0x66, 0x2e, 0x63, 0x3a, 0x20, 0x36, + 0x31, 0x33, 0x00, 0xc4, 0xeb, 0x03, 0x20, 0xf0, + 0xb5, 0xed, 0x09, 0x00, 0x31, 0x00, 0x00, 0x25, + 0x0c, 0x1c, 0x07, 0x1c, 0x06, 0xf0, 0xd5, 0xfe, + 0x00, 0x28, 0x01, 0xd1, 0x02, 0x25, 0x22, 0xe0, + 0x38, 0x69, 0x05, 0x28, 0x02, 0xd0, 0xff, 0x25, + 0x0a, 0x35, 0x1c, 0xe0, 0xfc, 0x60, 0x38, 0x1c, + 0x08, 0xf0, 0x05, 0xff, 0x04, 0x1c, 0x16, 0xd0, + 0x7a, 0x26, 0xfd, 0xf7, 0x4e, 0xfd, 0x00, 0x28, + 0x04, 0xd1, 0x20, 0x1c, 0x0a, 0xa1, 0x24, 0xf0, + 0xda, 0xff, 0x07, 0xe0, 0x06, 0x60, 0xf9, 0x68, + 0xc1, 0x60, 0x04, 0x61, 0x01, 0x1c, 0x09, 0x20, + 0xfd, 0xf7, 0xae, 0xfd, 0x38, 0x1c, 0x08, 0xf0, + 0xee, 0xfe, 0x04, 0x1c, 0xe9, 0xd1, 0x28, 0x1c, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x69, 0x66, + 0x2e, 0x63, 0x3a, 0x20, 0x37, 0x31, 0x34, 0x00, + 0x00, 0xb5, 0x00, 0x21, 0x08, 0xf0, 0xe6, 0xfc, + 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 0x82, 0xb0, + 0x00, 0x27, 0x04, 0x1c, 0x0d, 0x1c, 0x0b, 0x9e, + 0x06, 0xf0, 0x93, 0xfe, 0x00, 0x28, 0x07, 0xd1, + 0x02, 0x27, 0x39, 0x1c, 0x20, 0x1c, 0x32, 0x1c, + 0x2b, 0x1c, 0x09, 0xf0, 0x10, 0xf9, 0x26, 0xe0, + 0x20, 0x69, 0x05, 0x28, 0x07, 0xd0, 0x0c, 0x27, + 0x39, 0x1c, 0x20, 0x1c, 0x32, 0x1c, 0x2b, 0x1c, + 0x09, 0xf0, 0x05, 0xf9, 0x1b, 0xe0, 0x00, 0x2d, + 0x07, 0xd1, 0x11, 0x27, 0x39, 0x1c, 0x20, 0x1c, + 0x32, 0x1c, 0x2b, 0x1c, 0x09, 0xf0, 0xfb, 0xf8, + 0x11, 0xe0, 0x03, 0x2d, 0x02, 0xd1, 0xe0, 0x1d, + 0xb5, 0x30, 0x01, 0xe0, 0xe0, 0x1d, 0x55, 0x30, + 0x05, 0x9b, 0x11, 0x22, 0x03, 0x61, 0x01, 0x92, + 0x02, 0x1c, 0x20, 0x1c, 0x33, 0x1c, 0x00, 0x95, + 0x04, 0x99, 0x09, 0xf0, 0xd1, 0xf9, 0x38, 0x1c, + 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xb0, 0xb5, 0x00, 0x24, 0xed, 0x09, 0x00, 0x32, + 0x00, 0x0d, 0x1c, 0x07, 0x1c, 0x06, 0xf0, 0x57, + 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xff, 0x24, 0x0c, + 0x34, 0x10, 0xe0, 0x0a, 0x49, 0x69, 0x43, 0x38, + 0x1c, 0x07, 0xf0, 0xc4, 0xfe, 0xf8, 0x6c, 0x00, + 0x28, 0x08, 0xd1, 0x38, 0x1c, 0x07, 0xf0, 0xae, + 0xfe, 0x38, 0x1c, 0x07, 0xf0, 0xd9, 0xfd, 0x38, + 0x1c, 0x07, 0xf0, 0xee, 0xfd, 0x20, 0x1c, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe2, 0x04, 0x00, + 0x00, 0xf0, 0xb5, 0x00, 0x25, 0x0c, 0x1c, 0x07, + 0x1c, 0x00, 0x28, 0x0a, 0x4e, 0x0b, 0xd9, 0xa8, + 0x00, 0x20, 0x58, 0x01, 0x02, 0x09, 0x0a, 0xe8, + 0x00, 0x80, 0x19, 0xa0, 0x30, 0x25, 0xf0, 0xb4, + 0xfc, 0x01, 0x35, 0xbd, 0x42, 0xf3, 0xd3, 0xf0, + 0x1d, 0x79, 0x30, 0xc7, 0x61, 0xf0, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x18, 0xeb, 0x03, + 0x20, 0xf0, 0xb5, 0x00, 0x27, 0xfd, 0xf7, 0xa7, + 0xfc, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x1c, + 0xe0, 0x10, 0x4b, 0xc3, 0x21, 0xda, 0x1d, 0x79, + 0x32, 0x01, 0x60, 0xd5, 0x69, 0xc4, 0x1d, 0x09, + 0x34, 0x00, 0x21, 0x00, 0x2d, 0x0b, 0xd9, 0xcd, + 0x00, 0xed, 0x18, 0x80, 0x35, 0x6d, 0x6a, 0xad, + 0x01, 0x2e, 0x0a, 0x8d, 0x00, 0x66, 0x51, 0xd5, + 0x69, 0x01, 0x31, 0x8d, 0x42, 0xf3, 0xd8, 0xd1, + 0x69, 0xc1, 0x60, 0x01, 0x1c, 0x08, 0x20, 0xfd, + 0xf7, 0xf5, 0xfc, 0x38, 0x1c, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x18, 0xeb, 0x03, + 0x20, 0xf0, 0xb5, 0x00, 0x27, 0x04, 0x1c, 0x15, + 0x1c, 0x0e, 0x1c, 0x06, 0xf0, 0xec, 0xfd, 0x00, + 0x28, 0x02, 0xd1, 0xff, 0x27, 0x0c, 0x37, 0x12, + 0xe0, 0xfd, 0xf7, 0x71, 0xfc, 0x00, 0x28, 0x01, + 0xd1, 0x07, 0x27, 0x0c, 0xe0, 0x17, 0x21, 0x01, + 0x60, 0xa1, 0x68, 0xc1, 0x60, 0x5c, 0xce, 0xed, + 0x09, 0x00, 0x33, 0x00, 0xc1, 0x1d, 0x09, 0x31, + 0x5c, 0xc1, 0x05, 0x62, 0x01, 0x1c, 0x0b, 0x20, + 0xfd, 0xf7, 0xcf, 0xfc, 0x38, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x00, 0x24, + 0x07, 0x1c, 0x06, 0xf0, 0xcb, 0xfd, 0x00, 0x28, + 0x02, 0xd1, 0xff, 0x24, 0x0c, 0x34, 0x42, 0xe0, + 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x69, 0x3a, 0x31, + 0x05, 0x2a, 0x02, 0xd1, 0xfa, 0x6c, 0x00, 0x2a, + 0x09, 0xd0, 0x48, 0x6b, 0x0c, 0x24, 0x01, 0x30, + 0x48, 0x63, 0x38, 0x1c, 0x00, 0x22, 0x21, 0x1c, + 0x07, 0xf0, 0x7f, 0xff, 0x2f, 0xe0, 0xfa, 0x1d, + 0xff, 0x32, 0x7a, 0x32, 0x12, 0x6b, 0x00, 0x2a, + 0x09, 0xd0, 0x48, 0x6b, 0x0c, 0x24, 0x01, 0x30, + 0x48, 0x63, 0x38, 0x1c, 0x00, 0x22, 0x21, 0x1c, + 0x07, 0xf0, 0x6f, 0xff, 0x1f, 0xe0, 0x4a, 0x6b, + 0x01, 0x32, 0x4a, 0x63, 0x80, 0x69, 0x01, 0x28, + 0x06, 0xd1, 0x38, 0x1c, 0x08, 0xf0, 0x12, 0xf8, + 0x01, 0x21, 0x38, 0x1c, 0x08, 0xf0, 0x27, 0xf8, + 0xfd, 0xf7, 0x20, 0xfc, 0x00, 0x28, 0x07, 0xd0, + 0x15, 0x21, 0x01, 0x60, 0xb9, 0x68, 0xc1, 0x60, + 0x01, 0x1c, 0x0b, 0x20, 0xfd, 0xf7, 0x85, 0xfc, + 0x00, 0x21, 0x38, 0x1c, 0x07, 0xf0, 0x99, 0xff, + 0x38, 0x1c, 0x07, 0xf0, 0xb8, 0xff, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x00, 0x27, 0x04, 0x1c, 0x06, 0xf0, 0x7a, 0xfd, + 0x00, 0x28, 0x02, 0xd1, 0xff, 0x27, 0x0c, 0x37, + 0x0d, 0xe0, 0xfd, 0xf7, 0xff, 0xfb, 0x00, 0x28, + 0x01, 0xd1, 0x07, 0x27, 0x07, 0xe0, 0x24, 0x21, + 0x01, 0x60, 0xa1, 0x68, 0xc1, 0x60, 0x01, 0x1c, + 0x0b, 0x20, 0xfd, 0xf7, 0x62, 0xfc, 0x38, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, + 0x00, 0x25, 0x04, 0x1c, 0x06, 0xf0, 0x5e, 0xfd, + 0x00, 0x28, 0xed, 0x09, 0x00, 0x34, 0x00, 0x02, + 0xd1, 0xff, 0x25, 0x0c, 0x35, 0x2e, 0xe0, 0xfd, + 0xf7, 0xe3, 0xfb, 0x07, 0x1c, 0x2a, 0xd0, 0x7e, + 0x20, 0x38, 0x60, 0xe0, 0x68, 0x16, 0x49, 0xf8, + 0x60, 0x00, 0x20, 0x38, 0x61, 0xe0, 0x1d, 0xff, + 0x30, 0x3a, 0x30, 0x00, 0x6a, 0x13, 0x4b, 0x00, + 0x01, 0x40, 0x18, 0xc0, 0x68, 0xff, 0x34, 0x81, + 0x34, 0x78, 0x75, 0xa0, 0x68, 0x98, 0x42, 0x02, + 0xd1, 0x88, 0x20, 0x38, 0x75, 0x02, 0xe0, 0x24, + 0xf0, 0x70, 0xff, 0x38, 0x75, 0xe0, 0x68, 0xb8, + 0x61, 0x20, 0x69, 0xf8, 0x61, 0x60, 0x6a, 0x38, + 0x62, 0xa0, 0x6a, 0xf8, 0x62, 0xe0, 0x69, 0xb8, + 0x62, 0xe0, 0x6a, 0x78, 0x62, 0x09, 0x20, 0x39, + 0x1c, 0xfd, 0xf7, 0x25, 0xfc, 0x28, 0x1c, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x50, + 0x7b, 0x03, 0x20, 0xff, 0xff, 0x00, 0x00, 0xf8, + 0xb5, 0x00, 0x24, 0x00, 0x26, 0xfd, 0xf7, 0xa8, + 0xfb, 0x07, 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x2c, + 0xe0, 0x18, 0x49, 0x01, 0x20, 0xca, 0x1d, 0xf9, + 0x32, 0x10, 0x61, 0xc8, 0x1d, 0xa5, 0x30, 0x05, + 0x1c, 0x06, 0x22, 0x14, 0xa1, 0x22, 0xf0, 0xe3, + 0xfb, 0x15, 0x49, 0x00, 0x28, 0x00, 0x91, 0x0c, + 0xd0, 0xc8, 0x1f, 0x2d, 0x38, 0xc0, 0x6a, 0x01, + 0x02, 0x09, 0x0a, 0x00, 0x98, 0x25, 0xf0, 0x89, + 0xfb, 0x01, 0x26, 0x29, 0x1c, 0x0f, 0xa0, 0x11, + 0xf0, 0x96, 0xfd, 0x19, 0x20, 0x38, 0x60, 0xfe, + 0x60, 0x48, 0xcd, 0xf8, 0x1d, 0x09, 0x30, 0x48, + 0xc0, 0x00, 0x99, 0xf8, 0x1d, 0x60, 0xc9, 0x11, + 0x30, 0x60, 0xc0, 0x0b, 0x20, 0x39, 0x1c, 0xfd, + 0xf7, 0xe6, 0xfb, 0x20, 0x1c, 0xf8, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x18, 0xeb, 0x03, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, + 0xeb, 0x03, 0x20, 0x0a, 0x4d, 0xed, 0x09, 0x00, + 0x35, 0x00, 0x79, 0x20, 0x42, 0x54, 0x41, 0x64, + 0x64, 0x72, 0x3a, 0x20, 0x25, 0x3a, 0x2d, 0x36, + 0x42, 0x20, 0x28, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x29, 0x0a, 0x00, 0x00, 0xf0, 0xb5, 0x00, 0x27, + 0x0c, 0x1c, 0x05, 0x1c, 0x16, 0x1c, 0x06, 0xf0, + 0xca, 0xfc, 0x00, 0x28, 0x02, 0xd1, 0xff, 0x27, + 0x0c, 0x37, 0x04, 0xe0, 0xe8, 0x1d, 0xf9, 0x30, + 0xc4, 0x61, 0x34, 0x40, 0x04, 0x62, 0x38, 0x1c, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, + 0x00, 0x27, 0x14, 0x1c, 0x05, 0x1c, 0x0e, 0x1c, + 0x06, 0xf0, 0xb5, 0xfc, 0x00, 0x28, 0x02, 0xd1, + 0xff, 0x27, 0x0c, 0x37, 0x0d, 0xe0, 0xe8, 0x1d, + 0xf9, 0x30, 0x01, 0x2c, 0x01, 0xd0, 0x02, 0x2c, + 0x02, 0xd1, 0x01, 0x21, 0x41, 0x62, 0x01, 0xe0, + 0x00, 0x21, 0x41, 0x62, 0xc1, 0x69, 0x31, 0x40, + 0x01, 0x62, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf0, 0xb5, 0x00, 0x24, 0x15, 0x1c, + 0x0e, 0x1c, 0x07, 0x1c, 0x00, 0x28, 0x07, 0xd0, + 0x38, 0x1c, 0x06, 0xf0, 0x94, 0xfc, 0x00, 0x28, + 0x02, 0xd1, 0xff, 0x24, 0x0c, 0x34, 0x1c, 0xe0, + 0xfd, 0xf7, 0x19, 0xfb, 0x00, 0x28, 0x18, 0xd0, + 0x18, 0x21, 0x01, 0x60, 0x00, 0x2f, 0x07, 0xd0, + 0xf9, 0x1d, 0xff, 0x31, 0x7a, 0x31, 0x4d, 0x60, + 0x0e, 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x04, 0xe0, + 0x08, 0x49, 0xcd, 0x63, 0x8e, 0x63, 0x00, 0x21, + 0xc1, 0x60, 0x05, 0x21, 0x41, 0x61, 0x85, 0x61, + 0x06, 0x61, 0x01, 0x1c, 0x0b, 0x20, 0xfd, 0xf7, + 0x6d, 0xfb, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, + 0xf7, 0xb5, 0x8e, 0xb0, 0x00, 0x25, 0x07, 0x1c, + 0x06, 0xf0, 0x65, 0xfc, 0x06, 0x1c, 0x02, 0xd1, + 0xff, 0x25, 0x0c, 0x35, 0x6b, 0xe0, 0xf8, 0x6c, + 0xed, 0x09, 0x00, 0x36, 0x00, 0x00, 0x28, 0x03, + 0xd0, 0x78, 0x6d, 0x00, 0x28, 0x65, 0xd0, 0x05, + 0xe0, 0x0f, 0x99, 0x00, 0x29, 0x02, 0xd1, 0x10, + 0x9a, 0x00, 0x2a, 0x5e, 0xd0, 0xfd, 0xf7, 0xdd, + 0xfa, 0x04, 0x1c, 0x5a, 0xd0, 0xf8, 0x6c, 0x00, + 0x28, 0x3b, 0xd1, 0xb0, 0x69, 0x01, 0x28, 0x15, + 0xd1, 0x00, 0x20, 0xb8, 0x65, 0x39, 0x7f, 0x30, + 0x1c, 0x06, 0xf0, 0x2e, 0xfc, 0x00, 0x28, 0x0b, + 0xd0, 0x39, 0xa1, 0x02, 0x20, 0x06, 0xf0, 0x50, + 0xfb, 0x78, 0x65, 0x00, 0x28, 0x02, 0xd0, 0x1a, + 0x21, 0x01, 0x61, 0x16, 0xe0, 0x07, 0x25, 0x42, + 0xe0, 0x7e, 0x65, 0x12, 0xe0, 0x06, 0xf0, 0xb8, + 0xfb, 0x78, 0x65, 0x00, 0x28, 0x07, 0xd0, 0xf9, + 0x1d, 0xf9, 0x31, 0xca, 0x69, 0x01, 0x21, 0x06, + 0xf0, 0xdb, 0xfc, 0xb8, 0x65, 0x01, 0xe0, 0x7e, + 0x65, 0xbf, 0x65, 0xb8, 0x6d, 0x00, 0x28, 0x2d, + 0xd0, 0x07, 0x65, 0x38, 0x1c, 0x07, 0xf0, 0x2e, + 0xfc, 0x38, 0x1c, 0x07, 0xf0, 0xaf, 0xfb, 0x38, + 0x1c, 0x07, 0xf0, 0xa5, 0xfd, 0x38, 0x1c, 0x07, + 0xf0, 0x8c, 0xfe, 0x01, 0x21, 0x38, 0x1c, 0x07, + 0xf0, 0x23, 0xfe, 0x01, 0x20, 0xf8, 0x64, 0x1a, + 0x21, 0x21, 0x60, 0xb8, 0x68, 0xe0, 0x61, 0x0f, + 0x99, 0x21, 0x62, 0x10, 0x9a, 0x62, 0x62, 0xb8, + 0x6d, 0xe0, 0x60, 0x78, 0x6d, 0x20, 0x61, 0x78, + 0x6d, 0xc0, 0x68, 0x60, 0x61, 0xb9, 0x6d, 0x00, + 0x20, 0x00, 0x29, 0x00, 0xd0, 0x08, 0x7f, 0xa0, + 0x61, 0x0b, 0x20, 0x21, 0x1c, 0xfd, 0xf7, 0xf0, + 0xfa, 0x0b, 0xe0, 0x1f, 0xe0, 0x09, 0x25, 0x7d, + 0x20, 0x20, 0x60, 0xe7, 0x60, 0xf8, 0x68, 0x20, + 0x61, 0x09, 0x20, 0x21, 0x1c, 0x65, 0x61, 0xfd, + 0xf7, 0xe3, 0xfa, 0x0f, 0x99, 0x00, 0x29, 0x11, + 0xd1, 0x10, 0x9a, 0x00, 0x2a, 0x0e, 0xd1, 0x41, + 0x20, 0x00, 0x90, 0xed, 0x09, 0x00, 0x37, 0x00, + 0x38, 0x7f, 0x03, 0x90, 0x78, 0x68, 0x04, 0x90, + 0x00, 0x20, 0x06, 0x90, 0x05, 0x90, 0x1f, 0x20, + 0x07, 0x90, 0x68, 0x46, 0x01, 0x21, 0x06, 0xf0, + 0xee, 0xff, 0x28, 0x1c, 0x11, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x31, 0x32, 0x31, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xb4, 0xc1, 0x1d, 0x10, 0x4b, + 0xff, 0x31, 0xe6, 0x31, 0x00, 0x27, 0x28, 0x22, + 0xc3, 0x18, 0x8b, 0x42, 0x0e, 0xd3, 0x08, 0x69, + 0x05, 0x28, 0x07, 0xd1, 0xc8, 0x1d, 0xff, 0x30, + 0x3a, 0x30, 0xc0, 0x6a, 0x01, 0x37, 0x90, 0x42, + 0x00, 0xd2, 0x02, 0x1c, 0xff, 0x31, 0xb5, 0x31, + 0x8b, 0x42, 0xf0, 0xd2, 0x78, 0x00, 0x81, 0x1c, + 0x91, 0x42, 0x03, 0xd2, 0x10, 0x1a, 0x02, 0x38, + 0x80, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, + 0x00, 0x00, 0x24, 0x0c, 0x00, 0x00, 0xf7, 0xb5, + 0x00, 0x27, 0x04, 0x1c, 0x0e, 0x1c, 0x06, 0xf0, + 0x97, 0xfb, 0x05, 0x1c, 0x02, 0xd1, 0xff, 0x27, + 0x0c, 0x37, 0x29, 0xe0, 0x00, 0x2e, 0x09, 0xd0, + 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0xc6, 0x62, + 0x02, 0x9a, 0x60, 0x68, 0x07, 0x23, 0x5b, 0x02, + 0xc0, 0x18, 0x42, 0x60, 0x20, 0x69, 0x05, 0x28, + 0x02, 0xd0, 0xff, 0x27, 0x0a, 0x37, 0x17, 0xe0, + 0xfd, 0xf7, 0x0a, 0xfa, 0x06, 0x1c, 0x01, 0xd1, + 0x07, 0x27, 0x11, 0xe0, 0x28, 0x1c, 0xff, 0xf7, + 0xb4, 0xff, 0x25, 0x21, 0x40, 0x00, 0x31, 0x60, + 0xa1, 0x68, 0x30, 0x61, 0x07, 0x23, 0x5b, 0x02, + 0xe8, 0x18, 0xf1, 0x60, 0x40, 0x68, 0x70, 0x61, + 0x0b, 0x20, 0x31, 0x1c, 0xfd, 0xf7, 0x63, 0xfa, + 0x38, 0x1c, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xff, 0xb5, 0x00, 0x27, 0xed, 0x09, + 0x00, 0x38, 0x00, 0x0c, 0x1c, 0x05, 0x1c, 0x16, + 0x1c, 0x06, 0xf0, 0x5c, 0xfb, 0x00, 0x28, 0x02, + 0xd1, 0xff, 0x27, 0x0c, 0x37, 0x26, 0xe0, 0x28, + 0x69, 0x05, 0x28, 0x02, 0xd0, 0xff, 0x27, 0x0a, + 0x37, 0x20, 0xe0, 0xfd, 0xf7, 0xdb, 0xf9, 0x00, + 0x28, 0x01, 0xd1, 0x07, 0x27, 0x1a, 0xe0, 0x1b, + 0x21, 0x01, 0x60, 0x00, 0x2c, 0x07, 0xd0, 0xff, + 0x2c, 0x05, 0xd0, 0x00, 0x2e, 0x03, 0xd1, 0x03, + 0x9b, 0x43, 0x62, 0x09, 0x99, 0x81, 0x62, 0xa9, + 0x68, 0x0c, 0x30, 0x52, 0xc0, 0x0a, 0x99, 0x18, + 0x38, 0x89, 0x00, 0x01, 0x62, 0x0b, 0x99, 0x81, + 0x61, 0x0c, 0x99, 0xc1, 0x61, 0x01, 0x1c, 0x0b, + 0x20, 0xfd, 0xf7, 0x2b, 0xfa, 0x38, 0x1c, 0x04, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, + 0xb5, 0x00, 0x27, 0x04, 0x1c, 0x0d, 0x1c, 0x06, + 0xf0, 0x25, 0xfb, 0x00, 0x28, 0x02, 0xd1, 0xff, + 0x27, 0x0c, 0x37, 0x20, 0xe0, 0xfd, 0xf7, 0xaa, + 0xf9, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x1a, + 0xe0, 0x23, 0x21, 0x01, 0x60, 0xa1, 0x68, 0x00, + 0x22, 0xc1, 0x60, 0x01, 0x21, 0x00, 0x2d, 0x07, + 0xd0, 0x64, 0x68, 0x37, 0x23, 0x9b, 0x01, 0xe3, + 0x18, 0x99, 0x63, 0x02, 0x61, 0x41, 0x61, 0x06, + 0xe0, 0x64, 0x68, 0x37, 0x23, 0x9b, 0x01, 0xe3, + 0x18, 0x9a, 0x63, 0x01, 0x61, 0x42, 0x61, 0x01, + 0x1c, 0x0b, 0x20, 0xfd, 0xf7, 0xfa, 0xf9, 0x38, + 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, + 0xb5, 0x00, 0x24, 0x05, 0x1c, 0x0a, 0x9e, 0x06, + 0xf0, 0xf5, 0xfa, 0x00, 0x28, 0x02, 0xd1, 0xff, + 0x24, 0x0c, 0x34, 0x33, 0xe0, 0x28, 0x69, 0x05, + 0x28, 0x02, 0xd0, 0xff, 0x24, 0x0a, 0x34, 0x2d, + 0xe0, 0xfd, 0xf7, 0x74, 0xf9, 0x07, 0x1c, 0x01, + 0xd1, 0x07, 0x24, 0x27, 0xe0, 0x03, 0x9b, 0x07, + 0x2b, 0xed, 0x09, 0x00, 0x39, 0x00, 0x01, 0xd1, + 0x02, 0x21, 0x05, 0xe0, 0x03, 0x9b, 0x06, 0x2b, + 0x01, 0xd1, 0x03, 0x21, 0x00, 0xe0, 0x06, 0x21, + 0x28, 0x1c, 0x06, 0xf0, 0x79, 0xf8, 0x68, 0x68, + 0x80, 0x69, 0x02, 0x28, 0x02, 0xd1, 0xb0, 0x1c, + 0x06, 0x01, 0x36, 0x09, 0x26, 0x20, 0x38, 0x60, + 0xa8, 0x68, 0xf8, 0x60, 0x01, 0x99, 0x39, 0x61, + 0x02, 0x9a, 0x7a, 0x61, 0x03, 0x9b, 0xbb, 0x61, + 0x09, 0x98, 0xf8, 0x61, 0x3e, 0x62, 0x0b, 0x98, + 0x78, 0x62, 0x0b, 0x20, 0x39, 0x1c, 0xfd, 0xf7, + 0xb7, 0xf9, 0x20, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x00, 0x24, + 0x05, 0x1c, 0x0e, 0x1c, 0x06, 0xf0, 0xb1, 0xfa, + 0x00, 0x28, 0x02, 0xd1, 0xff, 0x24, 0x0c, 0x34, + 0x11, 0xe0, 0xfd, 0xf7, 0x36, 0xf9, 0x07, 0x1c, + 0x01, 0xd1, 0x07, 0x24, 0x0b, 0xe0, 0x28, 0x1c, + 0x06, 0xf0, 0x53, 0xf8, 0x27, 0x20, 0x38, 0x60, + 0xa8, 0x68, 0xf8, 0x60, 0x0b, 0x20, 0x39, 0x1c, + 0x3e, 0x61, 0xfd, 0xf7, 0x95, 0xf9, 0x20, 0x1c, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, + 0x00, 0x27, 0x04, 0x1c, 0x15, 0x1c, 0x0e, 0x1c, + 0x06, 0xf0, 0x8f, 0xfa, 0x00, 0x28, 0x02, 0xd1, + 0xff, 0x27, 0x0c, 0x37, 0x0f, 0xe0, 0xfd, 0xf7, + 0x14, 0xf9, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, + 0x09, 0xe0, 0x1f, 0x21, 0x01, 0x60, 0xa1, 0x68, + 0xc1, 0x60, 0x06, 0x61, 0x45, 0x61, 0x01, 0x1c, + 0x0b, 0x20, 0xfd, 0xf7, 0x75, 0xf9, 0x38, 0x1c, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x04, 0x1c, 0x0f, 0x1c, 0xfd, 0xf7, 0xfd, 0xf8, + 0x00, 0x28, 0x19, 0xd0, 0x10, 0x49, 0x00, 0x2c, + 0x0d, 0xd0, 0x21, 0x22, 0xcc, 0x1d, 0xa5, 0x34, + 0x02, 0x60, 0x0c, 0xcc, 0xc7, 0x1d, 0x05, 0x37, + 0x0c, 0xc7, 0xb4, 0x31, 0xed, 0x09, 0x00, 0x3a, + 0x00, 0x18, 0xc9, 0xc7, 0x1d, 0x0d, 0x37, 0x18, + 0xc7, 0x08, 0xe0, 0x22, 0x22, 0x02, 0x60, 0x00, + 0x2f, 0x04, 0xd0, 0xff, 0x31, 0x01, 0x31, 0x4a, + 0x69, 0x01, 0x32, 0x4a, 0x61, 0x01, 0x1c, 0x0b, + 0x20, 0xfd, 0xf7, 0x4c, 0xf9, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x18, 0xeb, 0x03, + 0x20, 0x00, 0xb5, 0xfd, 0xf7, 0xd4, 0xf8, 0x00, + 0x28, 0x04, 0xd1, 0x06, 0x49, 0x01, 0x20, 0x88, + 0x60, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x21, 0x01, + 0x60, 0x01, 0x1c, 0x0b, 0x20, 0xfd, 0xf7, 0x36, + 0xf9, 0xf6, 0xe7, 0x00, 0x00, 0x18, 0xec, 0x03, + 0x20, 0xf0, 0xb5, 0x92, 0xb0, 0x00, 0x24, 0x0f, + 0x1c, 0x08, 0xf0, 0x96, 0xfc, 0x06, 0x1c, 0x08, + 0xf0, 0xdb, 0xf8, 0x10, 0x90, 0x00, 0x28, 0x01, + 0xd1, 0x02, 0x24, 0x39, 0xe0, 0x00, 0x21, 0x00, + 0x22, 0x07, 0x23, 0x02, 0xa8, 0x06, 0xc0, 0x01, + 0x3b, 0xfc, 0xd1, 0x14, 0x20, 0x02, 0x90, 0x11, + 0x2e, 0x08, 0xd1, 0xff, 0x23, 0x54, 0x33, 0x9f, + 0x42, 0x01, 0xd9, 0xff, 0x27, 0x54, 0x37, 0x0a, + 0x97, 0x01, 0x27, 0x05, 0xe0, 0xf0, 0x00, 0x80, + 0x19, 0x14, 0x49, 0x80, 0x00, 0x08, 0x58, 0x0a, + 0x90, 0x13, 0x48, 0x0a, 0x99, 0x0b, 0x90, 0x00, + 0x20, 0x00, 0x29, 0x05, 0xd9, 0x0b, 0x9a, 0x10, + 0x54, 0x0a, 0x99, 0x01, 0x30, 0x81, 0x42, 0xf9, + 0xd8, 0x00, 0x25, 0x00, 0x2f, 0x10, 0xd9, 0x10, + 0x98, 0xc2, 0x1d, 0x55, 0x32, 0x11, 0x92, 0x02, + 0x21, 0x00, 0x91, 0x01, 0x96, 0x11, 0x9a, 0x10, + 0x98, 0x02, 0xa9, 0x00, 0x23, 0x08, 0xf0, 0x62, + 0xfd, 0x04, 0x1c, 0x01, 0x35, 0xbd, 0x42, 0xf2, + 0xd3, 0x20, 0x1c, 0x12, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x7b, 0x03, + 0x20, 0x74, 0xe9, 0x03, 0x20, 0x01, 0x49, 0xed, + 0x09, 0x00, 0x3b, 0x00, 0x08, 0x63, 0x70, 0x47, + 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, 0x80, 0xb5, + 0x0a, 0x68, 0x0f, 0x1c, 0x17, 0x2a, 0x45, 0xd0, + 0x11, 0xdc, 0x17, 0x2a, 0x43, 0xd2, 0x01, 0xa3, + 0x9b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x74, 0x64, + 0x68, 0x4b, 0x6d, 0x4b, 0x75, 0x79, 0x7d, 0x8b, + 0x81, 0x87, 0x90, 0x50, 0xa3, 0x74, 0x74, 0x74, + 0xb2, 0xb2, 0x55, 0x59, 0x9f, 0x00, 0x72, 0x49, + 0x21, 0x2a, 0x45, 0xd0, 0x0c, 0xdc, 0xd0, 0x1f, + 0x11, 0x38, 0x09, 0x28, 0x2b, 0xd2, 0x01, 0xa3, + 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x8f, 0x9e, + 0x83, 0x96, 0x7c, 0xa2, 0xa8, 0xaf, 0xb3, 0x00, + 0x26, 0x2a, 0x21, 0xd0, 0x10, 0xdc, 0x22, 0x2a, + 0x4a, 0xd0, 0x23, 0x2a, 0x4e, 0xd0, 0x24, 0x2a, + 0x4d, 0xd0, 0x25, 0x2a, 0x4c, 0xd1, 0x38, 0x1c, + 0x00, 0xf0, 0x3c, 0xfc, 0x38, 0x1c, 0xfd, 0xf7, + 0x6c, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x27, 0x2a, 0x0d, 0xd0, 0x28, 0x2a, 0x51, 0xd0, + 0x87, 0x2a, 0x0d, 0xd0, 0x9d, 0x2a, 0x3b, 0xd1, + 0xf8, 0x68, 0x48, 0x63, 0x38, 0x1c, 0xfd, 0xf7, + 0x5c, 0xf8, 0xee, 0xe7, 0x1d, 0xe0, 0xab, 0xe0, + 0x39, 0x1c, 0x01, 0xf0, 0x6c, 0xfe, 0xe8, 0xe7, + 0x38, 0x1c, 0x01, 0xf0, 0xdd, 0xfc, 0x38, 0x1c, + 0xfd, 0xf7, 0x4f, 0xf8, 0xe1, 0xe7, 0x00, 0x22, + 0x39, 0x1c, 0x08, 0xf0, 0x8e, 0xfd, 0xdc, 0xe7, + 0x38, 0x1c, 0x08, 0xf0, 0xe2, 0xff, 0xd8, 0xe7, + 0x81, 0xe0, 0x39, 0x1c, 0x09, 0xf0, 0x67, 0xf9, + 0xd3, 0xe7, 0x39, 0x1c, 0x09, 0xf0, 0x6d, 0xf9, + 0xcf, 0xe7, 0x39, 0x1c, 0x09, 0xf0, 0x75, 0xf9, + 0x38, 0x1c, 0xfd, 0xf7, 0x36, 0xf8, 0xc8, 0xe7, + 0x39, 0x1c, 0x09, 0xf0, 0xb2, 0xf9, 0xc4, 0xe7, + 0x39, 0x1c, 0x09, 0xf0, 0x09, 0xfa, 0xc0, 0xe7, + 0x61, 0xe0, 0xed, 0x09, 0x00, 0x3c, 0x00, 0x01, + 0x22, 0x39, 0x1c, 0x08, 0xf0, 0xf2, 0xfd, 0xba, + 0xe7, 0x6a, 0xe0, 0x70, 0xe0, 0x76, 0xe0, 0x39, + 0x1c, 0x08, 0xf0, 0x51, 0xfd, 0xb3, 0xe7, 0x39, + 0x1c, 0x09, 0xf0, 0x2b, 0xfa, 0xaf, 0xe7, 0x39, + 0x1c, 0x09, 0xf0, 0xed, 0xfa, 0xab, 0xe7, 0x01, + 0x22, 0x39, 0x1c, 0x09, 0xf0, 0x96, 0xfb, 0xa6, + 0xe7, 0x4b, 0xe0, 0x39, 0x1c, 0x09, 0xf0, 0x35, + 0xfb, 0xa1, 0xe7, 0x01, 0x22, 0x39, 0x1c, 0x09, + 0xf0, 0x44, 0xfb, 0x9c, 0xe7, 0x39, 0x1c, 0x09, + 0xf0, 0xc8, 0xfb, 0x98, 0xe7, 0x38, 0x1c, 0x09, + 0xf0, 0xac, 0xfb, 0x38, 0x1c, 0xfc, 0xf7, 0xff, + 0xff, 0x91, 0xe7, 0x38, 0x1c, 0x09, 0xf0, 0x00, + 0xfc, 0x8d, 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0xf8, + 0xff, 0x89, 0xe7, 0x38, 0x1c, 0xfc, 0xf7, 0xf3, + 0xff, 0x85, 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0x58, + 0xff, 0x38, 0x1c, 0xfc, 0xf7, 0xec, 0xff, 0x7e, + 0xe7, 0x38, 0x1c, 0x09, 0xf0, 0x3e, 0xfd, 0x7a, + 0xe7, 0x38, 0x1c, 0xfc, 0xf7, 0xe4, 0xff, 0x76, + 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0x7c, 0xff, 0x72, + 0xe7, 0xf8, 0x68, 0xc8, 0x62, 0x38, 0x1c, 0xfc, + 0xf7, 0xda, 0xff, 0x6c, 0xe7, 0x38, 0x1c, 0x09, + 0xf0, 0xd6, 0xfb, 0x38, 0x1c, 0xfc, 0xf7, 0xd3, + 0xff, 0x65, 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0xe1, + 0xf9, 0x61, 0xe7, 0x38, 0x1c, 0x09, 0xf0, 0xe7, + 0xfd, 0x5d, 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0x1b, + 0xff, 0x59, 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0xf7, + 0xfe, 0x55, 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0x01, + 0xff, 0x38, 0x1c, 0xfc, 0xf7, 0xbc, 0xff, 0x4e, + 0xe7, 0x38, 0x1c, 0x00, 0xf0, 0x57, 0xfb, 0x38, + 0x1c, 0xfc, 0xf7, 0xb5, 0xff, 0x47, 0xe7, 0x38, + 0x1c, 0x00, 0xf0, 0x8f, 0xff, 0x38, 0x1c, 0xfc, + 0xf7, 0xae, 0xff, 0x40, 0xe7, 0xed, 0x09, 0x00, + 0x3d, 0x00, 0x38, 0x1c, 0xfc, 0xf7, 0xaa, 0xff, + 0x3c, 0xe7, 0x00, 0x00, 0x48, 0xe6, 0x03, 0x20, + 0xb0, 0xb5, 0x8a, 0xb0, 0xbf, 0x4c, 0x02, 0x20, + 0xfd, 0xf7, 0x1e, 0xf8, 0xc5, 0x1d, 0x07, 0x1c, + 0x20, 0x69, 0x05, 0x35, 0x00, 0x28, 0x02, 0xd0, + 0x38, 0x68, 0x3f, 0x28, 0xf3, 0xd1, 0x38, 0x68, + 0x55, 0x28, 0x51, 0xd0, 0x27, 0xdc, 0x31, 0x38, + 0x22, 0x28, 0x01, 0xd2, 0x43, 0x00, 0x9f, 0x44, + 0x5d, 0xe0, 0xa3, 0xe0, 0x5c, 0xe0, 0x5a, 0xe0, + 0x84, 0xe0, 0x7e, 0xe0, 0x5c, 0xe0, 0x5f, 0xe0, + 0x67, 0xe0, 0x6a, 0xe0, 0x60, 0xe0, 0x6c, 0xe0, + 0x51, 0xe0, 0x47, 0xe0, 0x4b, 0xe0, 0x80, 0xe0, + 0x90, 0xe0, 0x82, 0xe0, 0x69, 0xe0, 0x85, 0xe0, + 0x88, 0xe0, 0x48, 0xe0, 0x47, 0xe0, 0x46, 0xe0, + 0x45, 0xe0, 0x44, 0xe0, 0x43, 0xe0, 0x42, 0xe0, + 0x41, 0xe0, 0x8b, 0xe0, 0x91, 0xe0, 0x96, 0xe0, + 0xb0, 0xe0, 0xb4, 0xe0, 0xa8, 0xe0, 0x62, 0x28, + 0x34, 0xd0, 0x0d, 0xdc, 0x56, 0x38, 0x0c, 0x28, + 0x35, 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0xcf, 0xce, 0xcd, 0xcc, + 0xcb, 0x91, 0x98, 0xca, 0xc9, 0x95, 0xc8, 0xc7, + 0x68, 0x28, 0x39, 0xd0, 0x09, 0xdc, 0x63, 0x38, + 0x05, 0x28, 0x24, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, + 0x5b, 0x00, 0x9f, 0x44, 0xc7, 0xc6, 0xc5, 0xc4, + 0xc3, 0x00, 0x8e, 0x28, 0x3f, 0xd0, 0x08, 0xdc, + 0x84, 0x28, 0x3d, 0xd0, 0x8d, 0x28, 0x40, 0xd1, + 0x03, 0xcd, 0xff, 0xf7, 0xb7, 0xf8, 0x15, 0xe1, + 0x8d, 0xe0, 0xa7, 0x28, 0x40, 0xd0, 0xa8, 0x28, + 0x37, 0xd1, 0x28, 0x68, 0x29, 0x1d, 0xff, 0xf7, + 0x37, 0xfa, 0x0b, 0xe1, 0x38, 0x1c, 0x06, 0xf0, + 0x32, 0xfc, 0x07, 0xe1, 0xd1, 0xe0, 0x38, 0x1c, + 0x06, 0xf0, 0x39, 0xfc, 0x02, 0xe1, 0x01, 0xe1, + 0xed, 0x09, 0x00, 0x3e, 0x00, 0x03, 0xcd, 0x23, + 0xf0, 0xd5, 0xfe, 0xfd, 0xe0, 0x38, 0x1c, 0x06, + 0xf0, 0x9b, 0xfa, 0xf9, 0xe0, 0x38, 0x1c, 0x06, + 0xf0, 0xfb, 0xfa, 0xf5, 0xe0, 0x38, 0x1c, 0x06, + 0xf0, 0xad, 0xf9, 0xf1, 0xe0, 0xd3, 0xe0, 0x38, + 0x1c, 0x06, 0xf0, 0x30, 0xfb, 0xec, 0xe0, 0x38, + 0x1c, 0x06, 0xf0, 0xb2, 0xfb, 0xe8, 0xe0, 0x38, + 0x1c, 0x06, 0xf0, 0xde, 0xfb, 0xe4, 0xe0, 0x05, + 0xcd, 0x08, 0x3d, 0xa9, 0x68, 0x07, 0xf0, 0x92, + 0xff, 0xde, 0xe0, 0xd2, 0xe0, 0xd8, 0xe0, 0x38, + 0x1c, 0x08, 0xf0, 0x40, 0xf9, 0xd8, 0xe0, 0xd7, + 0xe0, 0x38, 0x1c, 0x08, 0xf0, 0xdb, 0xfa, 0x0e, + 0xf0, 0x57, 0xff, 0xd1, 0xe0, 0xc9, 0xe0, 0x38, + 0x1c, 0x06, 0xf0, 0x12, 0xfc, 0xcc, 0xe0, 0x00, + 0x21, 0x38, 0x1c, 0x06, 0xf0, 0x49, 0xfc, 0xc7, + 0xe0, 0x38, 0x1c, 0x07, 0xf0, 0xa1, 0xff, 0xc3, + 0xe0, 0x38, 0x1c, 0x07, 0xf0, 0xc7, 0xff, 0xbf, + 0xe0, 0x38, 0x1c, 0x08, 0xf0, 0x19, 0xf8, 0xbb, + 0xe0, 0x38, 0x1c, 0x08, 0xf0, 0x4b, 0xf8, 0xb7, + 0xe0, 0x05, 0xcd, 0x08, 0x3d, 0xa9, 0x68, 0xeb, + 0x68, 0x07, 0xf0, 0xfa, 0xfe, 0xb0, 0xe0, 0x2a, + 0x69, 0x00, 0x92, 0x0f, 0xcd, 0x07, 0xf0, 0x2e, + 0xff, 0xaa, 0xe0, 0x00, 0x22, 0x00, 0x92, 0x00, + 0x23, 0x00, 0x21, 0x28, 0x68, 0x07, 0xf0, 0x26, + 0xff, 0xa2, 0xe0, 0x28, 0x68, 0xff, 0xf7, 0x35, + 0xfa, 0x9e, 0xe0, 0xff, 0xf7, 0xe1, 0xfa, 0x9b, + 0xe0, 0x28, 0x68, 0x6a, 0x69, 0x29, 0x1d, 0xff, + 0xf7, 0x09, 0xfa, 0x95, 0xe0, 0x2a, 0x69, 0x00, + 0x92, 0x0f, 0xcd, 0xfe, 0xf7, 0x9c, 0xff, 0x8f, + 0xe0, 0x2a, 0x7a, 0x03, 0xcd, 0xfe, 0xf7, 0xee, + 0xfe, 0x8a, 0xe0, 0x28, 0x68, 0xfe, 0xf7, 0x48, + 0xff, 0x86, 0xe0, 0xe9, 0x1d, 0x05, 0x31, 0x0c, + 0xc9, 0x08, 0xa8, 0xed, 0x09, 0x00, 0x3f, 0x00, + 0x0c, 0xc0, 0x68, 0x8c, 0x69, 0x6a, 0xaa, 0x6a, + 0x06, 0x91, 0x05, 0x90, 0x07, 0x92, 0xe8, 0x69, + 0x69, 0x69, 0xaa, 0x69, 0x03, 0x91, 0x02, 0x90, + 0x04, 0x92, 0x2a, 0x8c, 0x09, 0x99, 0x00, 0x91, + 0x01, 0x92, 0x07, 0xcd, 0x08, 0x9b, 0xff, 0xf7, + 0x72, 0xf8, 0x6c, 0xe0, 0x32, 0xe0, 0x2d, 0xe0, + 0x24, 0xe0, 0x1f, 0xe0, 0x1a, 0xe0, 0x0f, 0xe0, + 0x24, 0xe0, 0x09, 0xe0, 0xff, 0xe7, 0x03, 0xcd, + 0xff, 0xf7, 0xeb, 0xf8, 0x5f, 0xe0, 0x4f, 0xe0, + 0x44, 0xe0, 0x3b, 0xe0, 0x36, 0xe0, 0x29, 0xe0, + 0x28, 0x68, 0xff, 0xf7, 0x1c, 0xf9, 0x56, 0xe0, + 0x69, 0x69, 0x2a, 0x69, 0x00, 0x91, 0x01, 0x92, + 0x0d, 0xcd, 0x0c, 0x3d, 0xe9, 0x68, 0xff, 0xf7, + 0x18, 0xf9, 0x4c, 0xe0, 0x03, 0xcd, 0xff, 0xf7, + 0x52, 0xf9, 0x48, 0xe0, 0x07, 0xcd, 0xff, 0xf7, + 0xda, 0xfa, 0x44, 0xe0, 0x07, 0xcd, 0xff, 0xf7, + 0xeb, 0xfa, 0x40, 0xe0, 0x07, 0xcd, 0x06, 0xf0, + 0x00, 0xfd, 0x3c, 0xe0, 0x07, 0xcd, 0xff, 0xf7, + 0x01, 0xfb, 0x38, 0xe0, 0x07, 0xcd, 0xff, 0xf7, + 0x30, 0xfb, 0x34, 0xe0, 0x07, 0xcd, 0xff, 0xf7, + 0xfa, 0xfb, 0x30, 0xe0, 0x14, 0x35, 0x07, 0xcd, + 0x20, 0x3d, 0x02, 0x91, 0x01, 0x90, 0x03, 0x92, + 0x2a, 0x69, 0x00, 0x92, 0x0f, 0xcd, 0xff, 0xf7, + 0x28, 0xfc, 0x24, 0xe0, 0x28, 0x68, 0xff, 0xf7, + 0x24, 0xfa, 0x20, 0xe0, 0x03, 0xcd, 0xff, 0xf7, + 0x58, 0xfc, 0x1c, 0xe0, 0x07, 0xcd, 0xff, 0xf7, + 0xe9, 0xfc, 0x18, 0xe0, 0x10, 0x35, 0x07, 0xcd, + 0x1c, 0x3d, 0x01, 0x91, 0x00, 0x90, 0x02, 0x92, + 0x0f, 0xcd, 0xff, 0xf7, 0x7a, 0xfc, 0x0e, 0xe0, + 0x03, 0xcd, 0xff, 0xf7, 0xba, 0xfc, 0x0a, 0xe0, + 0x03, 0xcd, 0xfe, 0xf7, 0xd8, 0xff, 0x06, 0xe0, + 0xff, 0xf7, 0x4b, 0xf9, 0x03, 0xe0, 0xed, 0x09, + 0x00, 0x40, 0x00, 0x01, 0x21, 0x00, 0x20, 0xff, + 0xf7, 0xef, 0xfc, 0x00, 0x2f, 0x00, 0xd1, 0x85, + 0xe6, 0x38, 0x1c, 0xfc, 0xf7, 0x26, 0xfe, 0x81, + 0xe6, 0x00, 0x00, 0x18, 0xec, 0x03, 0x20, 0xa7, + 0x20, 0x70, 0x47, 0x02, 0x20, 0x70, 0x47, 0x82, + 0xb0, 0x08, 0x48, 0x00, 0x69, 0x00, 0x90, 0x07, + 0x48, 0x01, 0x68, 0x01, 0x91, 0x00, 0x99, 0x40, + 0x68, 0x81, 0x42, 0x02, 0xd2, 0x01, 0x98, 0x01, + 0x30, 0x01, 0x90, 0x00, 0x98, 0x01, 0x99, 0x02, + 0xb0, 0x70, 0x47, 0x00, 0x50, 0x00, 0xe0, 0x70, + 0x7b, 0x03, 0x20, 0x90, 0xb5, 0x31, 0xf0, 0x25, + 0xfc, 0xff, 0xf7, 0xe5, 0xff, 0x04, 0x1c, 0x0f, + 0x1c, 0x31, 0xf0, 0x1b, 0xfc, 0x20, 0x1c, 0x39, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x03, + 0x48, 0x01, 0x68, 0x01, 0x31, 0x01, 0x60, 0x02, + 0x49, 0x09, 0x69, 0x41, 0x60, 0x70, 0x47, 0x70, + 0x7b, 0x03, 0x20, 0x00, 0x50, 0x00, 0xe0, 0xf0, + 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xc6, 0x68, 0x00, + 0x69, 0x01, 0x90, 0x78, 0x69, 0x00, 0x90, 0xff, + 0xf7, 0xdc, 0xff, 0x72, 0x68, 0x13, 0x69, 0x02, + 0x2b, 0x04, 0xd1, 0x14, 0x6b, 0xd5, 0x6a, 0x40, + 0x19, 0x61, 0x41, 0x02, 0xe0, 0x10, 0xa2, 0x54, + 0x68, 0x15, 0x68, 0x10, 0xa3, 0x1a, 0x68, 0x5b, + 0x68, 0x0c, 0xf0, 0xcf, 0xfd, 0x43, 0x21, 0x39, + 0x60, 0xb1, 0x68, 0x38, 0x61, 0xf9, 0x60, 0xbc, + 0x61, 0x7d, 0x61, 0x70, 0x68, 0xff, 0x30, 0x81, + 0x30, 0x00, 0x68, 0xf8, 0x61, 0x01, 0x98, 0x38, + 0x62, 0x00, 0x98, 0x78, 0x62, 0x0a, 0x20, 0x39, + 0x1c, 0xfc, 0xf7, 0xf3, 0xfd, 0x02, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xb5, 0xed, 0x09, 0x00, 0x41, 0x00, 0x82, 0xb0, + 0x07, 0x1c, 0xff, 0xf7, 0x8f, 0xff, 0x00, 0x90, + 0x01, 0x91, 0x87, 0x42, 0x02, 0xd2, 0x01, 0x98, + 0x01, 0x30, 0x01, 0x90, 0x00, 0x97, 0x05, 0xa3, + 0x01, 0x99, 0x1a, 0x68, 0x5b, 0x68, 0x38, 0x1c, + 0x0c, 0xf0, 0x9a, 0xfd, 0x02, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x71, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xb5, 0x84, 0xb0, + 0x07, 0x1c, 0xff, 0xf7, 0x73, 0xff, 0x00, 0x90, + 0x01, 0x91, 0x0e, 0xa3, 0x1a, 0x68, 0x5b, 0x68, + 0x0c, 0xf0, 0x86, 0xfd, 0x02, 0x90, 0x00, 0x98, + 0x03, 0x91, 0x80, 0x1a, 0x01, 0x99, 0x00, 0x90, + 0x99, 0x41, 0x01, 0x91, 0x03, 0x99, 0x09, 0xa3, + 0x02, 0x98, 0x1a, 0x68, 0x5b, 0x68, 0x19, 0x40, + 0x10, 0x40, 0x02, 0x90, 0x03, 0x91, 0x38, 0x60, + 0x00, 0x98, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xb5, 0x82, 0xb0, + 0x1c, 0x1c, 0x05, 0x1c, 0xff, 0xf7, 0x46, 0xff, + 0xe6, 0x1d, 0x25, 0x36, 0x00, 0x2c, 0x00, 0x90, + 0x01, 0x91, 0x09, 0xd0, 0x00, 0x2d, 0x07, 0xd1, + 0x00, 0x98, 0x01, 0x99, 0x0c, 0xce, 0x08, 0x3e, + 0x80, 0x18, 0x59, 0x41, 0x01, 0x91, 0x00, 0x90, + 0x3f, 0xa3, 0x00, 0x98, 0x01, 0x99, 0x1a, 0x68, + 0x5b, 0x68, 0x0c, 0xf0, 0x49, 0xfd, 0x07, 0x1c, + 0x00, 0x98, 0x01, 0x99, 0x80, 0x1a, 0x99, 0x41, + 0x01, 0x91, 0x03, 0x99, 0x00, 0x90, 0xa9, 0x42, + 0x2c, 0xd1, 0xb8, 0x07, 0x80, 0x0f, 0x20, 0xd0, + 0x01, 0x28, 0x0c, 0xd0, 0x02, 0x28, 0x13, 0xd0, + 0x03, 0x28, 0x4f, 0xd1, 0x00, 0x98, 0x01, 0x99, + 0x33, 0x4a, 0x0c, 0xf0, 0xcd, 0xfd, 0x00, 0x90, + 0x01, 0x91, 0x01, 0x37, 0xed, 0x09, 0x00, 0x42, + 0x00, 0x46, 0xe0, 0x00, 0x98, 0x01, 0x99, 0x30, + 0x4a, 0x0c, 0xf0, 0xc4, 0xfd, 0x00, 0x90, 0x01, + 0x91, 0x03, 0x37, 0x3d, 0xe0, 0x00, 0x98, 0x01, + 0x99, 0x2c, 0x4a, 0x0c, 0xf0, 0xbb, 0xfd, 0x00, + 0x90, 0x01, 0x91, 0x02, 0x37, 0x34, 0xe0, 0x00, + 0x98, 0x01, 0x99, 0x29, 0x4a, 0x0c, 0xf0, 0xb2, + 0xfd, 0x00, 0x90, 0x01, 0x91, 0x04, 0x37, 0x2b, + 0xe0, 0xb8, 0x07, 0x80, 0x0f, 0x20, 0xd0, 0x01, + 0x28, 0x0c, 0xd0, 0x02, 0x28, 0x13, 0xd0, 0x03, + 0x28, 0x22, 0xd1, 0x00, 0x98, 0x01, 0x99, 0x1e, + 0x4a, 0x0c, 0xf0, 0xa0, 0xfd, 0x00, 0x90, 0x01, + 0x91, 0x03, 0x37, 0x19, 0xe0, 0x00, 0x98, 0x01, + 0x99, 0x18, 0x4a, 0x0c, 0xf0, 0x97, 0xfd, 0x00, + 0x90, 0x01, 0x91, 0x01, 0x37, 0x10, 0xe0, 0x00, + 0x98, 0x01, 0x99, 0x17, 0x4a, 0x0c, 0xf0, 0x8e, + 0xfd, 0x00, 0x90, 0x01, 0x91, 0x04, 0x37, 0x07, + 0xe0, 0x00, 0x98, 0x01, 0x99, 0x11, 0x4a, 0x0c, + 0xf0, 0x85, 0xfd, 0x00, 0x90, 0x01, 0x91, 0x02, + 0x37, 0x3f, 0x01, 0x3f, 0x09, 0x00, 0x2c, 0x08, + 0xd0, 0x00, 0x2d, 0x06, 0xd1, 0x00, 0x98, 0x01, + 0x99, 0x0c, 0xce, 0x80, 0x1a, 0x99, 0x41, 0x01, + 0x91, 0x00, 0x90, 0x69, 0x46, 0x0c, 0xc9, 0x04, + 0x98, 0x0c, 0xc0, 0x06, 0xb0, 0x38, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x71, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, + 0x00, 0x53, 0x07, 0x00, 0x00, 0xe2, 0x04, 0x00, + 0x00, 0xc4, 0x09, 0x00, 0x00, 0x80, 0xb4, 0xb3, + 0x23, 0x9b, 0x00, 0xc2, 0x18, 0x00, 0x20, 0x00, + 0x23, 0xd7, 0x68, 0x05, 0x2f, 0x03, 0xd0, 0x00, + 0x29, 0x02, 0xd0, 0x03, 0x2f, 0x00, 0xd1, 0x01, + 0x30, 0xff, 0x32, 0x35, 0x32, 0x01, 0x33, 0x07, + 0x2b, 0xf2, 0xd3, 0x80, 0xbc, 0x70, 0x47, 0xed, + 0x09, 0x00, 0x43, 0x00, 0xb3, 0x23, 0x9b, 0x00, + 0xc1, 0x18, 0x00, 0x20, 0x00, 0x22, 0xcb, 0x68, + 0x05, 0x2b, 0x03, 0xd0, 0x03, 0x2b, 0x01, 0xd0, + 0x01, 0x2b, 0x00, 0xd1, 0x01, 0x30, 0xff, 0x31, + 0x35, 0x31, 0x01, 0x32, 0x07, 0x2a, 0xf2, 0xd3, + 0x70, 0x47, 0xb0, 0xb5, 0x14, 0x1c, 0x0d, 0x1c, + 0x07, 0x1c, 0x00, 0x21, 0x0e, 0x4a, 0xfc, 0xf7, + 0x3c, 0xf8, 0x00, 0x20, 0xf8, 0x60, 0x0c, 0x49, + 0x3d, 0x61, 0x0b, 0x68, 0x5a, 0x1c, 0x0a, 0x60, + 0x18, 0xc7, 0x08, 0x3f, 0xf9, 0x1d, 0xff, 0x31, + 0x00, 0x22, 0x92, 0x31, 0x0a, 0x60, 0x0a, 0x76, + 0xc8, 0x60, 0x4f, 0x60, 0xff, 0x31, 0x35, 0x31, + 0x01, 0x32, 0x08, 0x2a, 0xf6, 0xd3, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x0b, + 0x00, 0x00, 0xdc, 0x7d, 0x03, 0x20, 0xb0, 0xb5, + 0x0c, 0x1c, 0x05, 0x1c, 0x07, 0x48, 0x21, 0xf0, + 0xfa, 0xfb, 0x07, 0x1c, 0x04, 0xd0, 0x38, 0x1c, + 0x29, 0x1c, 0x22, 0x1c, 0xff, 0xf7, 0xcd, 0xff, + 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x4c, 0x0b, 0x00, 0x00, 0x00, 0xb5, + 0x21, 0xf0, 0x15, 0xfc, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0xb4, 0xc2, 0x68, 0x43, 0x69, 0x51, 0x68, + 0xff, 0x31, 0x91, 0x31, 0x0f, 0x68, 0x3b, 0x43, + 0x0b, 0x60, 0x51, 0x68, 0x00, 0x69, 0xff, 0x31, + 0x91, 0x31, 0x0a, 0x68, 0xc0, 0x43, 0x10, 0x40, + 0x08, 0x60, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, + 0x05, 0x1c, 0xff, 0x20, 0x35, 0x30, 0x48, 0x43, + 0x40, 0x19, 0xc7, 0x1d, 0xff, 0x37, 0x92, 0x37, + 0x16, 0x1c, 0x0c, 0x1c, 0x00, 0x21, 0xff, 0x22, + 0x38, 0x1c, 0x35, 0x32, 0xfb, 0xf7, 0xe1, 0xff, + 0x3c, 0x60, 0x3c, 0x76, 0x00, 0x21, 0x7d, 0x60, + 0xf9, 0x60, 0xbe, 0x60, 0x38, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0xed, 0x09, 0x00, 0x44, 0x00, 0x18, + 0x47, 0x80, 0xb4, 0xc1, 0x68, 0x2d, 0x23, 0x4f, + 0x68, 0x9b, 0x01, 0x02, 0x69, 0xfb, 0x18, 0x5a, + 0x60, 0x0b, 0x23, 0x4a, 0x68, 0x1b, 0x02, 0xd2, + 0x18, 0x40, 0x69, 0x2d, 0x23, 0x90, 0x63, 0x48, + 0x68, 0x9b, 0x01, 0xc0, 0x18, 0x41, 0x68, 0x00, + 0x29, 0x01, 0xd0, 0x01, 0x21, 0x01, 0x60, 0x80, + 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x85, 0xb0, 0x6a, + 0x46, 0x07, 0x1c, 0x2f, 0x49, 0x04, 0x20, 0x08, + 0xc9, 0x08, 0xc2, 0x03, 0x1c, 0x01, 0x38, 0x00, + 0x2b, 0xf9, 0xd1, 0x2c, 0x49, 0x38, 0x1c, 0x49, + 0x69, 0x3c, 0x31, 0x0c, 0xc9, 0x0c, 0xc0, 0x00, + 0x98, 0x38, 0x61, 0x78, 0x69, 0x01, 0x99, 0x80, + 0x08, 0x80, 0x00, 0x89, 0x07, 0x89, 0x0f, 0x01, + 0x43, 0x79, 0x61, 0x38, 0x6b, 0x01, 0x9a, 0x00, + 0x0e, 0x00, 0x06, 0x92, 0x10, 0x12, 0x02, 0x12, + 0x0a, 0x10, 0x43, 0x38, 0x63, 0x01, 0x9a, 0x92, + 0x00, 0x92, 0x0f, 0xba, 0x61, 0x01, 0x9a, 0x92, + 0x0f, 0xfa, 0x61, 0x02, 0x9a, 0x00, 0x02, 0x00, + 0x0a, 0x12, 0x06, 0x10, 0x43, 0x38, 0x63, 0x02, + 0x9a, 0x12, 0x02, 0x12, 0x0c, 0xba, 0x86, 0x02, + 0x9a, 0x03, 0x9b, 0x12, 0x0e, 0x1b, 0x04, 0x1b, + 0x0c, 0x1b, 0x02, 0x1a, 0x43, 0x3a, 0x62, 0x03, + 0x9a, 0x52, 0x03, 0x52, 0x0f, 0x7a, 0x62, 0x03, + 0x9a, 0x04, 0x9b, 0xd2, 0x0c, 0xdb, 0x04, 0xdb, + 0x0c, 0x5b, 0x03, 0x1a, 0x43, 0xba, 0x62, 0x04, + 0x9a, 0x0e, 0x4b, 0x12, 0x04, 0x52, 0x0f, 0x00, + 0x02, 0x00, 0x0a, 0x19, 0x40, 0x80, 0x00, 0x08, + 0x43, 0xfa, 0x62, 0x78, 0x61, 0x80, 0x01, 0x00, + 0x0a, 0x23, 0xf0, 0x3d, 0xfe, 0x79, 0x69, 0x89, + 0x01, 0x89, 0x09, 0x80, 0x06, 0x08, 0x43, 0x78, + 0x61, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x00, 0x54, 0xed, 0x09, 0x00, + 0x45, 0x00, 0x00, 0xe0, 0x88, 0xe5, 0x03, 0x20, + 0x03, 0x00, 0x00, 0xfc, 0xf0, 0xb5, 0x82, 0xb0, + 0x0c, 0x1c, 0x05, 0x1c, 0xfc, 0xf7, 0xaf, 0xfb, + 0x07, 0x1c, 0x04, 0xd1, 0x00, 0x20, 0x02, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x21, + 0x29, 0x40, 0x10, 0x20, 0x00, 0x29, 0x0b, 0xd0, + 0x00, 0x21, 0xf9, 0x61, 0x39, 0x63, 0x74, 0x49, + 0xf8, 0x60, 0x49, 0x69, 0x38, 0x1c, 0x3c, 0x31, + 0x0c, 0xc9, 0x0c, 0xc0, 0x38, 0x1c, 0xea, 0xe7, + 0x70, 0x4b, 0x1a, 0x6b, 0xd6, 0x06, 0xf6, 0x0e, + 0xf9, 0x1d, 0x39, 0x31, 0x0e, 0x70, 0x16, 0x0a, + 0x4e, 0x70, 0x12, 0x0c, 0x8a, 0x70, 0xda, 0x6a, + 0xd3, 0x06, 0xdb, 0x0e, 0xcb, 0x70, 0x13, 0x0a, + 0xdb, 0x06, 0xdb, 0x0e, 0x12, 0x0b, 0xd2, 0x06, + 0xd2, 0x0e, 0x0b, 0x71, 0x4a, 0x71, 0x69, 0x0a, + 0x05, 0xd3, 0x00, 0x21, 0xf9, 0x61, 0x39, 0x63, + 0xf8, 0x60, 0x38, 0x1c, 0xcb, 0xe7, 0x62, 0x48, + 0xf9, 0x1d, 0x82, 0x6a, 0x01, 0x31, 0x53, 0x07, + 0x5b, 0x0f, 0x0b, 0x70, 0x53, 0x06, 0x1b, 0x0f, + 0x4b, 0x60, 0x13, 0x06, 0xdb, 0x0f, 0x4b, 0x70, + 0xd3, 0x05, 0xdb, 0x0f, 0x92, 0x05, 0xd2, 0x0f, + 0x8b, 0x70, 0xca, 0x70, 0xf9, 0x68, 0x00, 0x29, + 0x01, 0xd0, 0x01, 0x29, 0x01, 0xd1, 0x38, 0x1c, + 0xb1, 0xe7, 0x02, 0x39, 0x0e, 0x29, 0x0a, 0xd2, + 0x01, 0xa3, 0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, + 0x29, 0x0b, 0x0b, 0x2b, 0x2d, 0x2f, 0x0b, 0x0b, + 0x1a, 0x1a, 0x06, 0x06, 0x1a, 0x1a, 0x38, 0x1c, + 0xfc, 0xf7, 0x6e, 0xfb, 0x00, 0x20, 0x9e, 0xe7, + 0x00, 0x6a, 0x00, 0xab, 0x18, 0x70, 0x00, 0x98, + 0x80, 0x07, 0x80, 0x0f, 0x78, 0x61, 0x00, 0x98, + 0x40, 0x07, 0xc0, 0x0f, 0x38, 0x61, 0x00, 0x98, + 0x00, 0x06, 0xc5, 0x0e, 0x15, 0xe0, 0x00, 0x6a, + 0xed, 0x09, 0x00, 0x46, 0x00, 0x01, 0xab, 0x18, + 0x80, 0x01, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x78, + 0x61, 0x01, 0x98, 0x40, 0x07, 0xc0, 0x0f, 0x38, + 0x61, 0x01, 0x98, 0x00, 0x05, 0xc5, 0x0d, 0x06, + 0xe0, 0x12, 0x25, 0x04, 0xe0, 0x0a, 0x25, 0x02, + 0xe0, 0x14, 0x25, 0x00, 0xe0, 0x1e, 0x25, 0xf8, + 0x68, 0x02, 0x38, 0x0e, 0x28, 0x67, 0xd2, 0x02, + 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, + 0x1c, 0x07, 0x1e, 0x1e, 0x44, 0x44, 0x44, 0x0b, + 0x1e, 0x1e, 0x1e, 0x63, 0x63, 0x1e, 0x1e, 0x38, + 0x1c, 0xff, 0xf7, 0xf4, 0xfe, 0x57, 0xe0, 0x0c, + 0x20, 0xfc, 0xf7, 0x9e, 0xfa, 0x38, 0x63, 0x00, + 0x28, 0x04, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, 0x2a, + 0xfb, 0x00, 0x20, 0x5a, 0xe7, 0x2a, 0x4a, 0x02, + 0x21, 0x08, 0xca, 0x08, 0xc0, 0x0b, 0x1c, 0x01, + 0x39, 0x00, 0x2b, 0xf9, 0xd1, 0xe8, 0x1c, 0x06, + 0x1c, 0xfc, 0xf7, 0x8a, 0xfa, 0xf8, 0x61, 0x00, + 0x28, 0x0b, 0xd1, 0x38, 0x6b, 0x00, 0x28, 0x03, + 0xd0, 0xfc, 0xf7, 0xae, 0xfa, 0x00, 0x21, 0x39, + 0x63, 0x38, 0x1c, 0xfc, 0xf7, 0x0f, 0xfb, 0x00, + 0x20, 0x3f, 0xe7, 0x00, 0x2c, 0x02, 0xd0, 0x01, + 0x20, 0x00, 0xf0, 0xc6, 0xf8, 0xb3, 0x08, 0x5a, + 0x1e, 0x00, 0x2b, 0xf8, 0x69, 0x19, 0x49, 0x05, + 0xd0, 0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, + 0x3a, 0x00, 0x2b, 0xf9, 0xd1, 0xbd, 0x61, 0x1e, + 0xe0, 0xe8, 0x1c, 0x04, 0x1c, 0xfc, 0xf7, 0x64, + 0xfa, 0xf8, 0x61, 0x00, 0x28, 0x0b, 0xd1, 0x38, + 0x6b, 0x00, 0x28, 0x03, 0xd0, 0xfc, 0xf7, 0x88, + 0xfa, 0x00, 0x21, 0x39, 0x63, 0x38, 0x1c, 0xfc, + 0xf7, 0xe9, 0xfa, 0x00, 0x20, 0x19, 0xe7, 0xa3, + 0x08, 0x5a, 0x1e, 0x00, 0x2b, 0x09, 0x49, 0x05, + 0xd0, 0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, + 0x3a, 0x00, 0x2b, 0xed, 0x09, 0x00, 0x47, 0x00, + 0xf9, 0xd1, 0xbd, 0x61, 0x38, 0x1c, 0x0b, 0xe7, + 0x00, 0x00, 0x88, 0xe5, 0x03, 0x20, 0x00, 0x51, + 0x00, 0xe0, 0x40, 0x55, 0x00, 0xe0, 0x70, 0x55, + 0x00, 0xe0, 0x00, 0x54, 0x00, 0xe0, 0x90, 0xb4, + 0x00, 0x23, 0x00, 0x2a, 0x0e, 0xd9, 0x4f, 0x78, + 0x0c, 0x78, 0x3f, 0x02, 0x27, 0x43, 0x8c, 0x78, + 0x24, 0x04, 0x27, 0x43, 0xcc, 0x78, 0x24, 0x06, + 0x27, 0x43, 0x80, 0xc0, 0x04, 0x31, 0x04, 0x33, + 0x93, 0x42, 0xf0, 0xd3, 0x90, 0xbc, 0x70, 0x47, + 0x80, 0xb4, 0x02, 0x69, 0x36, 0x49, 0x0a, 0x60, + 0x42, 0x69, 0x4b, 0x68, 0x92, 0x07, 0x92, 0x0f, + 0x9b, 0x08, 0x9b, 0x00, 0x13, 0x43, 0x4b, 0x60, + 0x02, 0x6b, 0x12, 0x02, 0x12, 0x0a, 0x1f, 0x1c, + 0x30, 0x4b, 0x3b, 0x40, 0x92, 0x00, 0x1a, 0x43, + 0x03, 0x23, 0x9b, 0x06, 0x9a, 0x43, 0x17, 0x1c, + 0x4a, 0x60, 0x82, 0x69, 0x9b, 0x00, 0x9f, 0x43, + 0x92, 0x07, 0x92, 0x0f, 0x12, 0x07, 0x3b, 0x1c, + 0x13, 0x43, 0x4b, 0x60, 0x9b, 0x00, 0xc2, 0x69, + 0x9b, 0x08, 0x92, 0x07, 0x1a, 0x43, 0x4a, 0x60, + 0x02, 0x6b, 0x8b, 0x68, 0x12, 0x0e, 0x1b, 0x0a, + 0x1b, 0x02, 0x13, 0x43, 0x8b, 0x60, 0x1f, 0x1c, + 0x21, 0x4b, 0x82, 0x8e, 0x3b, 0x40, 0x12, 0x02, + 0x13, 0x43, 0x8b, 0x60, 0x1b, 0x02, 0x02, 0x6a, + 0x1b, 0x0a, 0x12, 0x06, 0x1a, 0x43, 0x8a, 0x60, + 0x02, 0x6a, 0xcb, 0x68, 0x12, 0x0a, 0x1b, 0x0c, + 0x1b, 0x04, 0x12, 0x04, 0x12, 0x0c, 0x13, 0x43, + 0xcb, 0x60, 0x1f, 0x1c, 0x07, 0x23, 0x1b, 0x04, + 0x42, 0x6a, 0x9f, 0x43, 0x52, 0x07, 0x52, 0x0f, + 0x12, 0x04, 0x3b, 0x1c, 0x13, 0x43, 0xcb, 0x60, + 0x5b, 0x03, 0x82, 0x6a, 0x5b, 0x0b, 0xd2, 0x04, + 0x1a, 0x43, 0xca, 0x60, 0x82, 0x6a, 0x0b, 0x69, + 0x52, 0x0b, 0x5b, 0x0b, 0x5b, 0x03, 0xed, 0x09, + 0x00, 0x48, 0x00, 0xd2, 0x04, 0xd2, 0x0c, 0x1a, + 0x43, 0x0a, 0x61, 0x07, 0x23, 0x5b, 0x03, 0xc0, + 0x6a, 0x9a, 0x43, 0x40, 0x07, 0x40, 0x0f, 0x40, + 0x03, 0x10, 0x43, 0x08, 0x61, 0x06, 0x48, 0x41, + 0x60, 0x14, 0x21, 0x01, 0x60, 0x80, 0xbc, 0x70, + 0x47, 0x00, 0x00, 0x30, 0xed, 0x03, 0x20, 0x03, + 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xff, 0xe4, + 0x7d, 0x03, 0x20, 0x06, 0x49, 0xff, 0x23, 0x0a, + 0x68, 0x01, 0x33, 0x9a, 0x43, 0xc0, 0x07, 0xc0, + 0x0f, 0x00, 0x02, 0x10, 0x43, 0x08, 0x60, 0x02, + 0x49, 0x88, 0x62, 0x70, 0x47, 0x00, 0x00, 0xe0, + 0x7d, 0x03, 0x20, 0x40, 0x57, 0x00, 0xe0, 0xf0, + 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xc0, 0x68, 0x10, + 0x28, 0x06, 0xd1, 0x57, 0x49, 0x03, 0x20, 0x08, + 0x60, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x55, 0x48, 0x39, 0x7a, 0x02, 0x68, 0xd2, + 0x08, 0xd2, 0x00, 0x49, 0x07, 0x49, 0x0f, 0x0a, + 0x43, 0x02, 0x60, 0xf9, 0x68, 0x78, 0x23, 0x9a, + 0x43, 0x09, 0x07, 0x09, 0x0f, 0xc9, 0x00, 0x0a, + 0x43, 0x02, 0x60, 0x79, 0x7a, 0x80, 0x23, 0x9a, + 0x43, 0xc9, 0x07, 0xc9, 0x0f, 0xc9, 0x01, 0x0a, + 0x43, 0x02, 0x60, 0xb9, 0x7a, 0x5b, 0x00, 0x9a, + 0x43, 0xc9, 0x07, 0xc9, 0x0f, 0x09, 0x02, 0x0a, + 0x43, 0x02, 0x60, 0xf9, 0x7a, 0x5b, 0x00, 0x9a, + 0x43, 0xc9, 0x07, 0xc9, 0x0f, 0x49, 0x02, 0x11, + 0x43, 0x42, 0x4a, 0x01, 0x60, 0x91, 0x62, 0xf9, + 0x68, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x29, 0x00, + 0xd1, 0xca, 0xe7, 0xf8, 0x1d, 0x11, 0x30, 0x00, + 0x24, 0x00, 0x25, 0x8e, 0x1e, 0x0e, 0x2e, 0x66, + 0xd2, 0x02, 0xa3, 0x9b, 0x5d, 0x5b, 0x00, 0x9f, + 0x44, 0x00, 0x1c, 0x49, 0x09, 0x09, 0x4e, 0x50, + 0x52, 0x07, 0x09, 0x28, 0x28, 0x63, 0x63, 0x28, + 0x28, 0xed, 0x09, 0x00, 0x49, 0x00, 0x3c, 0x6b, + 0x0a, 0x25, 0x79, 0x69, 0x00, 0x9b, 0x9b, 0x08, + 0x9b, 0x00, 0x89, 0x07, 0x89, 0x0f, 0x19, 0x43, + 0x00, 0x91, 0x39, 0x69, 0x00, 0x9e, 0x04, 0x23, + 0x9e, 0x43, 0xc9, 0x07, 0xc9, 0x0f, 0x89, 0x00, + 0x31, 0x43, 0x00, 0x91, 0xb9, 0x6b, 0x00, 0x9f, + 0xf8, 0x23, 0x9f, 0x43, 0xc9, 0x06, 0xc9, 0x0e, + 0xc9, 0x00, 0x39, 0x43, 0x00, 0x91, 0x00, 0x9b, + 0x09, 0x06, 0xc9, 0x0e, 0x13, 0x62, 0x1d, 0xe0, + 0x79, 0x69, 0x01, 0x9b, 0x9b, 0x08, 0x9b, 0x00, + 0x89, 0x07, 0x89, 0x0f, 0x19, 0x43, 0x01, 0x91, + 0x39, 0x69, 0x01, 0x9e, 0x04, 0x23, 0x9e, 0x43, + 0xc9, 0x07, 0xc9, 0x0f, 0x89, 0x00, 0x31, 0x43, + 0x01, 0x91, 0xb9, 0x6b, 0x01, 0x9f, 0x1b, 0x4b, + 0x3b, 0x40, 0xc9, 0x05, 0xc9, 0x0d, 0xc9, 0x00, + 0x19, 0x43, 0x01, 0x91, 0x01, 0x9b, 0x09, 0x05, + 0xc9, 0x0d, 0x13, 0x62, 0x00, 0x29, 0x11, 0xd0, + 0x09, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0xe1, 0xfe, + 0x14, 0x21, 0x04, 0xe0, 0x0a, 0x21, 0x02, 0xe0, + 0x14, 0x21, 0x00, 0xe0, 0x1e, 0x21, 0x00, 0x28, + 0x04, 0xd0, 0x0a, 0x1c, 0x01, 0x1c, 0x0e, 0x48, + 0x30, 0xf0, 0xa6, 0xff, 0x00, 0x2c, 0x04, 0xd0, + 0x21, 0x1c, 0x2a, 0x1c, 0x0b, 0x48, 0xff, 0xf7, + 0xb7, 0xfe, 0x5c, 0xe7, 0xff, 0xe7, 0x08, 0x1c, + 0x30, 0xf0, 0xc6, 0xf8, 0x02, 0x1c, 0x08, 0xa0, + 0xf9, 0x68, 0x10, 0xf0, 0x29, 0xfb, 0xed, 0xe7, + 0x00, 0x52, 0x00, 0xe0, 0xe0, 0x7d, 0x03, 0x20, + 0x40, 0x57, 0x00, 0xe0, 0x07, 0xf0, 0xff, 0xff, + 0x00, 0x56, 0x00, 0xe0, 0x70, 0x57, 0x00, 0xe0, + 0x4c, 0x63, 0x49, 0x72, 0x71, 0x5f, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x75, 0x6e, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x70, 0x61, + 0x63, 0x6b, 0x65, 0x74, 0xed, 0x09, 0x00, 0x4a, + 0x00, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x25, + 0x78, 0x20, 0x28, 0x25, 0x73, 0x29, 0x00, 0x00, + 0x00, 0x80, 0xb5, 0x88, 0xb0, 0x18, 0x49, 0x06, + 0xa8, 0x88, 0xc9, 0x88, 0xc0, 0x17, 0x49, 0x04, + 0xa8, 0x88, 0xc9, 0x88, 0xc0, 0x16, 0x49, 0x02, + 0xa8, 0x88, 0xc9, 0x88, 0xc0, 0x15, 0x49, 0x68, + 0x46, 0x88, 0xc9, 0x88, 0xc0, 0x14, 0x48, 0x41, + 0x69, 0xc0, 0x38, 0xc7, 0x1d, 0xbd, 0x37, 0xcc, + 0x30, 0x01, 0x29, 0x0e, 0xd0, 0x02, 0x29, 0x08, + 0xd1, 0x69, 0x46, 0x08, 0x22, 0xfb, 0xf7, 0x3e, + 0xfd, 0x08, 0x22, 0x38, 0x1c, 0x02, 0xa9, 0xfb, + 0xf7, 0x39, 0xfd, 0x08, 0xb0, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x08, 0x22, 0x04, 0xa9, 0xfb, + 0xf7, 0x31, 0xfd, 0x08, 0x22, 0x38, 0x1c, 0x06, + 0xa9, 0xfb, 0xf7, 0x2c, 0xfd, 0xf1, 0xe7, 0x00, + 0x00, 0x80, 0x0f, 0x01, 0x20, 0x88, 0x0f, 0x01, + 0x20, 0x90, 0x0f, 0x01, 0x20, 0x98, 0x0f, 0x01, + 0x20, 0x48, 0xe6, 0x03, 0x20, 0xf0, 0xb4, 0x11, + 0x4f, 0xc0, 0x30, 0x7c, 0x18, 0xc0, 0x34, 0x25, + 0x79, 0x24, 0x7b, 0xc1, 0x60, 0xc0, 0x37, 0xfe, + 0x69, 0xb1, 0x42, 0x00, 0xd9, 0xc6, 0x60, 0x00, + 0x2a, 0x0a, 0xd0, 0x79, 0x69, 0x01, 0x29, 0x04, + 0xd0, 0x02, 0x29, 0x07, 0xd1, 0x80, 0x21, 0x81, + 0x60, 0x04, 0xe0, 0x40, 0x21, 0x81, 0x60, 0x01, + 0xe0, 0x00, 0x21, 0x81, 0x60, 0x04, 0x49, 0x01, + 0x62, 0x83, 0x61, 0x44, 0x61, 0x05, 0x61, 0xf0, + 0xbc, 0x70, 0x47, 0x00, 0x00, 0x88, 0xe5, 0x03, + 0x20, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0x31, + 0x21, 0x01, 0x60, 0x04, 0x49, 0x49, 0x69, 0xc1, + 0x60, 0x01, 0x1c, 0x0a, 0x20, 0xfc, 0xf7, 0xf6, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x48, 0xe6, 0x03, + 0x20, 0x90, 0xb4, 0x07, 0x49, 0xc4, 0x1d, 0xed, + 0x09, 0x00, 0x4b, 0x00, 0x05, 0x34, 0xcf, 0x1d, + 0xf1, 0x37, 0x0c, 0xcc, 0x0c, 0xc7, 0x14, 0x30, + 0x90, 0xc8, 0xff, 0x31, 0x01, 0x31, 0x90, 0xc1, + 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x88, 0xe5, + 0x03, 0x20, 0x80, 0xb5, 0x82, 0xb0, 0x07, 0x1c, + 0x68, 0x46, 0x30, 0xf0, 0x20, 0xfb, 0x40, 0x20, + 0x38, 0x60, 0x69, 0x46, 0x0c, 0xc9, 0xf8, 0x1d, + 0x05, 0x30, 0x0c, 0xc0, 0x0a, 0x20, 0x39, 0x1c, + 0xfc, 0xf7, 0xcf, 0xf8, 0x02, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x02, 0x69, + 0x17, 0x49, 0x53, 0x18, 0xc0, 0x33, 0x1c, 0x79, + 0x1b, 0x7b, 0xc7, 0x68, 0x00, 0x2f, 0x1d, 0xd1, + 0xcf, 0x1d, 0xb9, 0x37, 0x8a, 0x60, 0xfd, 0x69, + 0xaa, 0x42, 0x00, 0xd9, 0x8d, 0x60, 0x82, 0x69, + 0x00, 0x2a, 0x0a, 0xd0, 0x7a, 0x69, 0x01, 0x2a, + 0x04, 0xd0, 0x02, 0x2a, 0x07, 0xd1, 0x80, 0x22, + 0x0a, 0x60, 0x04, 0xe0, 0x40, 0x22, 0x0a, 0x60, + 0x01, 0xe0, 0x00, 0x22, 0x0a, 0x60, 0x40, 0x69, + 0x48, 0x60, 0x0b, 0x61, 0xcc, 0x60, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x43, 0x69, 0x84, 0x69, + 0x38, 0x1c, 0x11, 0x1c, 0x22, 0x1c, 0xff, 0xf7, + 0x74, 0xff, 0xf4, 0xe7, 0x00, 0x00, 0x88, 0xe5, + 0x03, 0x20, 0xf0, 0xb5, 0x82, 0xb0, 0x69, 0x46, + 0xc7, 0x1d, 0x09, 0x37, 0x48, 0xcf, 0xc4, 0x69, + 0x85, 0x69, 0x48, 0xc1, 0xc7, 0x68, 0xfc, 0xf7, + 0x58, 0xf8, 0x30, 0xf0, 0x76, 0xfe, 0x01, 0x20, + 0xfd, 0xf7, 0x51, 0xfa, 0x00, 0x2f, 0x0a, 0xd0, + 0x6e, 0x46, 0x15, 0x48, 0x0c, 0xce, 0xc1, 0x1d, + 0xf1, 0x31, 0x0c, 0xc1, 0xff, 0x30, 0x01, 0x30, + 0x44, 0x60, 0x05, 0x60, 0x02, 0xe0, 0x68, 0x46, + 0x30, 0xf0, 0xbd, 0xfa, 0xfc, 0xf7, 0x06, 0xf8, + 0x3f, 0x21, 0x01, 0x60, 0x04, 0x1c, 0x01, 0x20, + 0x00, 0x2f, 0xed, 0x09, 0x00, 0x4c, 0x00, 0x00, + 0xd0, 0x00, 0x20, 0x20, 0x61, 0x69, 0x46, 0x0c, + 0xc9, 0xe0, 0x1d, 0x0d, 0x30, 0x0c, 0xc0, 0x00, + 0x20, 0xe0, 0x60, 0x30, 0xf0, 0x4c, 0xfe, 0x0a, + 0x20, 0x21, 0x1c, 0xfc, 0xf7, 0x60, 0xf8, 0x08, + 0x20, 0x30, 0xf0, 0x51, 0xfe, 0x02, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x88, + 0xe5, 0x03, 0x20, 0xc0, 0x68, 0x02, 0x49, 0xc0, + 0x30, 0x01, 0x62, 0x70, 0x47, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x08, 0x1a, 0x90, 0x42, 0x01, + 0xda, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, + 0x47, 0x90, 0xb5, 0x90, 0xc9, 0xfb, 0xf7, 0xd4, + 0xff, 0x00, 0x28, 0x03, 0xd1, 0x01, 0x20, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x32, 0x21, 0x01, + 0x60, 0xc4, 0x60, 0x07, 0x61, 0x01, 0x1c, 0x0e, + 0x20, 0xfc, 0xf7, 0x35, 0xf8, 0x00, 0x20, 0xf2, + 0xe7, 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0x68, + 0x46, 0xf9, 0x1d, 0x05, 0x31, 0x60, 0xc9, 0x60, + 0xc0, 0x00, 0x98, 0x01, 0x99, 0x26, 0xa6, 0x0c, + 0xce, 0x08, 0x3e, 0xfb, 0xf7, 0x44, 0xfd, 0x00, + 0x28, 0x09, 0xd0, 0x24, 0x48, 0x2f, 0xf0, 0x8b, + 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0xe8, 0xff, 0x02, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x69, + 0x46, 0x0c, 0xc9, 0x1f, 0x48, 0x0c, 0xc0, 0xff, + 0xf7, 0xd6, 0xf9, 0x0c, 0x1c, 0x05, 0x1c, 0x00, + 0x9a, 0x01, 0x9b, 0x0c, 0xf0, 0x78, 0xf8, 0x00, + 0x28, 0x0d, 0xd0, 0x00, 0x98, 0x01, 0x99, 0x40, + 0x1b, 0xa1, 0x41, 0x01, 0x91, 0x00, 0x90, 0x17, + 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0x0b, 0xf0, 0xc7, + 0xff, 0x00, 0x90, 0x01, 0x91, 0x03, 0xe0, 0x68, + 0x46, 0x31, 0x1c, 0x0c, 0xc9, 0x0c, 0xc0, 0x00, + 0x98, 0x01, 0x99, 0x0c, 0xce, 0xfb, 0xf7, 0x13, + 0xfd, 0x00, 0x28, 0x08, 0xd0, 0xed, 0x09, 0x00, + 0x4d, 0x00, 0x0c, 0x4c, 0x20, 0x1c, 0x2f, 0xf0, + 0x59, 0xfa, 0x0b, 0x49, 0x20, 0x1c, 0xff, 0xf7, + 0xa2, 0xff, 0x07, 0xe0, 0x00, 0x98, 0x01, 0x99, + 0x07, 0x4b, 0x01, 0x1c, 0x05, 0x48, 0x09, 0x4a, + 0x2f, 0xf0, 0x02, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, + 0xa9, 0xff, 0xbf, 0xe7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x94, 0xed, 0x03, 0x20, + 0xfc, 0x7d, 0x03, 0x20, 0xd0, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa3, 0x4b, 0x00, 0x20, + 0x80, 0xb5, 0x08, 0x48, 0x02, 0x21, 0xc1, 0x60, + 0x81, 0x68, 0x02, 0x23, 0x19, 0x43, 0x81, 0x60, + 0x05, 0x48, 0x00, 0x27, 0xc7, 0x60, 0x2f, 0xf0, + 0xbb, 0xf9, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, + 0x94, 0xed, 0x03, 0x20, 0x00, 0xb5, 0x2f, 0xf0, + 0xc5, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x01, 0x2a, 0x04, 0xd1, 0x00, 0x0b, 0x40, 0x18, + 0xc0, 0x06, 0xc0, 0x0e, 0x70, 0x47, 0x00, 0x20, + 0x70, 0x47, 0x01, 0x2a, 0x11, 0xd1, 0x0a, 0x0b, + 0xd2, 0x06, 0xd2, 0x0e, 0x88, 0x42, 0x03, 0xd3, + 0x40, 0x1a, 0x01, 0x30, 0x80, 0x08, 0x04, 0xe0, + 0x05, 0x4b, 0x19, 0x43, 0x40, 0x1a, 0x01, 0x30, + 0x80, 0x08, 0x10, 0x18, 0xc0, 0x06, 0xc0, 0x0e, + 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0xb0, 0xb4, 0x01, 0x29, + 0x41, 0xd1, 0x41, 0x08, 0x0e, 0x23, 0x19, 0x40, + 0xc3, 0x07, 0xdb, 0x0f, 0x19, 0x43, 0x0d, 0x1c, + 0x01, 0x0b, 0xcc, 0x06, 0xe4, 0x0e, 0x01, 0x0b, + 0xc9, 0x06, 0xc9, 0x0e, 0xcf, 0x1d, 0x01, 0x37, + 0x18, 0x31, 0x02, 0x2a, 0x0e, 0xd1, 0x0e, 0x22, + 0x22, 0x40, 0x00, 0x0b, 0x02, 0x23, 0x18, 0x40, + 0xaa, 0x42, 0x03, 0xd8, 0x00, 0x28, 0x19, 0xd0, + 0xed, 0x09, 0x00, 0x4e, 0x00, 0x39, 0x1c, 0x17, + 0xe0, 0x00, 0x28, 0x15, 0xd1, 0x39, 0x1c, 0x13, + 0xe0, 0x01, 0x2a, 0x0e, 0xd1, 0x22, 0x07, 0x12, + 0x0f, 0x00, 0x0b, 0xc0, 0x07, 0xc0, 0x0f, 0xaa, + 0x42, 0x03, 0xd8, 0x00, 0x28, 0x08, 0xd0, 0x39, + 0x1c, 0x06, 0xe0, 0x00, 0x28, 0x04, 0xd1, 0x39, + 0x1c, 0x02, 0xe0, 0x80, 0x09, 0x00, 0xd3, 0x39, + 0x1c, 0xa5, 0x42, 0x02, 0xd3, 0x28, 0x1b, 0x40, + 0x18, 0x03, 0xe0, 0x60, 0x1b, 0x00, 0x07, 0x00, + 0x0f, 0x08, 0x1a, 0xc0, 0x06, 0xc0, 0x0e, 0xb0, + 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0xb0, + 0xb4, 0x01, 0x2a, 0x34, 0xd1, 0x1b, 0x4a, 0x0a, + 0x40, 0x88, 0x42, 0x02, 0xd3, 0x80, 0x1a, 0x80, + 0x08, 0x03, 0xe0, 0x19, 0x4b, 0x1a, 0x43, 0x80, + 0x1a, 0x80, 0x08, 0x4a, 0x08, 0x0e, 0x23, 0x1a, + 0x40, 0xcb, 0x07, 0xdb, 0x0f, 0x13, 0x43, 0x0a, + 0x0b, 0xd2, 0x06, 0xd2, 0x0e, 0x17, 0x07, 0x3f, + 0x0f, 0x09, 0x0b, 0xc9, 0x06, 0xc9, 0x0e, 0xcd, + 0x07, 0xed, 0x0f, 0xcc, 0x1d, 0x11, 0x34, 0x08, + 0x31, 0x9f, 0x42, 0x03, 0xd8, 0x00, 0x2d, 0x04, + 0xd1, 0x21, 0x1c, 0x02, 0xe0, 0x00, 0x2d, 0x00, + 0xd0, 0x21, 0x1c, 0x93, 0x42, 0x02, 0xd3, 0x9a, + 0x1a, 0x51, 0x18, 0x03, 0xe0, 0xd2, 0x1a, 0x12, + 0x07, 0x12, 0x0f, 0x89, 0x1a, 0x08, 0x18, 0xc0, + 0x06, 0xc0, 0x0e, 0xb0, 0xbc, 0x70, 0x47, 0x00, + 0x20, 0xfb, 0xe7, 0x00, 0x00, 0xfc, 0xff, 0xff, + 0x0f, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb5, 0x8f, + 0xb0, 0x50, 0x4f, 0x38, 0x68, 0x00, 0x28, 0x0a, + 0xd1, 0x01, 0x20, 0x00, 0x03, 0x20, 0xf0, 0x52, + 0xfe, 0x38, 0x60, 0x00, 0x28, 0x03, 0xd1, 0x0f, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, + 0x68, 0x00, 0x28, 0x07, 0xd1, 0x01, 0x20, 0x00, + 0x03, 0x20, 0xf0, 0xed, 0x09, 0x00, 0x4f, 0x00, + 0x44, 0xfe, 0x78, 0x60, 0x00, 0x28, 0x00, 0xd1, + 0xf0, 0xe7, 0x68, 0x46, 0x44, 0x4c, 0x07, 0x23, + 0x06, 0xcc, 0x06, 0xc0, 0x01, 0x3b, 0xfb, 0xd1, + 0x00, 0x24, 0x00, 0x20, 0x63, 0x01, 0x0e, 0x93, + 0x06, 0x27, 0x01, 0x1c, 0x02, 0x1c, 0x01, 0x25, + 0xbd, 0x40, 0x2b, 0x1c, 0x23, 0x40, 0x1d, 0x1c, + 0x08, 0xd0, 0xbb, 0x00, 0x6b, 0x44, 0xdb, 0x69, + 0x1e, 0x1c, 0x16, 0x40, 0x02, 0xd0, 0x9e, 0x42, + 0x00, 0xd0, 0x5a, 0x40, 0x00, 0x2d, 0x08, 0xd0, + 0xbb, 0x00, 0x6d, 0x46, 0xeb, 0x58, 0x1d, 0x1c, + 0x0d, 0x40, 0x02, 0xd0, 0x9d, 0x42, 0x00, 0xd0, + 0x59, 0x40, 0x01, 0x3f, 0xe3, 0xd5, 0x0e, 0x9b, + 0x2e, 0x4d, 0x1b, 0x18, 0x2f, 0x68, 0x01, 0x30, + 0xfa, 0x54, 0x6a, 0x68, 0x20, 0x28, 0xd1, 0x54, + 0xd6, 0xd3, 0x01, 0x34, 0x80, 0x2c, 0xd0, 0xd3, + 0x28, 0x4f, 0xb8, 0x68, 0x00, 0x28, 0x07, 0xd1, + 0x01, 0x20, 0x40, 0x03, 0x20, 0xf0, 0x01, 0xfe, + 0xb8, 0x60, 0x00, 0x28, 0x00, 0xd1, 0xad, 0xe7, + 0x00, 0x20, 0x01, 0x21, 0x49, 0x03, 0xc2, 0x07, + 0xd2, 0x0f, 0x44, 0x10, 0x02, 0x23, 0x23, 0x40, + 0x1a, 0x43, 0x84, 0x10, 0x04, 0x23, 0x23, 0x40, + 0x1a, 0x43, 0xc4, 0x10, 0x08, 0x23, 0x23, 0x40, + 0x1a, 0x43, 0x04, 0x11, 0x10, 0x23, 0x23, 0x40, + 0x1a, 0x43, 0x44, 0x11, 0x20, 0x23, 0x23, 0x40, + 0x1a, 0x43, 0x84, 0x11, 0x40, 0x23, 0x23, 0x40, + 0x13, 0x43, 0xba, 0x68, 0x13, 0x54, 0x01, 0x30, + 0x88, 0x42, 0xe0, 0xdb, 0xf8, 0x68, 0x3c, 0x1c, + 0x00, 0x28, 0x07, 0xd1, 0x01, 0x20, 0x40, 0x02, + 0x20, 0xf0, 0xd3, 0xfd, 0xe0, 0x60, 0x00, 0x28, + 0x00, 0xd1, 0x7f, 0xe7, 0x00, 0x27, 0x01, 0x25, + 0x6d, 0x02, 0x4f, 0x20, 0x39, 0x1c, 0x0b, 0xf0, + 0xee, 0xfe, 0x28, 0x29, 0x03, 0xda, 0xed, 0x09, + 0x00, 0x50, 0x00, 0x48, 0x00, 0xe1, 0x68, 0xc8, + 0x55, 0x05, 0xe0, 0xc8, 0x1f, 0x21, 0x38, 0x40, + 0x00, 0x41, 0x1c, 0xe0, 0x68, 0xc1, 0x55, 0x01, + 0x37, 0xaf, 0x42, 0xec, 0xdb, 0x68, 0xe7, 0x04, + 0x7e, 0x03, 0x20, 0xa0, 0x0f, 0x01, 0x20, 0x90, + 0xb5, 0x0e, 0x4c, 0x00, 0x27, 0x20, 0x68, 0x00, + 0x28, 0x02, 0xd0, 0x20, 0xf0, 0xd8, 0xfd, 0x27, + 0x60, 0x60, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x20, + 0xf0, 0xd2, 0xfd, 0x67, 0x60, 0xa0, 0x68, 0x00, + 0x28, 0x02, 0xd0, 0x20, 0xf0, 0xcc, 0xfd, 0xa7, + 0x60, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x20, + 0xf0, 0xc6, 0xfd, 0xe7, 0x60, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x04, 0x7e, 0x03, 0x20, 0xff, + 0xb5, 0x95, 0xb0, 0x00, 0x27, 0x45, 0x08, 0x20, + 0x9c, 0x14, 0x95, 0x1f, 0x9a, 0x1e, 0x9b, 0x01, + 0x2c, 0x5f, 0xd1, 0x18, 0x9f, 0xfe, 0x1e, 0x07, + 0x0b, 0x12, 0x06, 0x1a, 0x43, 0x12, 0x01, 0x12, + 0x09, 0xd5, 0x05, 0xed, 0x0d, 0x93, 0x0a, 0x11, + 0x93, 0xdb, 0x05, 0xdb, 0x0d, 0x12, 0x93, 0xd3, + 0x0c, 0x1c, 0x07, 0xe9, 0x4b, 0x13, 0x97, 0x5b, + 0x68, 0x24, 0x0f, 0x10, 0x93, 0xe7, 0x4b, 0xd7, + 0x0d, 0x1b, 0x68, 0x0f, 0x93, 0xe5, 0x4b, 0xdb, + 0x68, 0x0e, 0x93, 0x02, 0x23, 0x03, 0x40, 0x0a, + 0x93, 0x1b, 0x01, 0x52, 0x08, 0xd2, 0x04, 0xd2, + 0x0c, 0x0c, 0x92, 0x0a, 0x0b, 0xd2, 0x06, 0xd2, + 0x0e, 0x0b, 0x92, 0xdd, 0x4a, 0x0d, 0x93, 0x92, + 0x68, 0x18, 0x2e, 0x5e, 0xd2, 0x02, 0xa3, 0x9b, + 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0xe4, + 0xe3, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xe3, 0xe3, + 0x0c, 0xe3, 0xe3, 0x0c, 0x84, 0xe0, 0xe3, 0xe3, + 0x0c, 0xe3, 0xe3, 0x0c, 0x84, 0xe0, 0xe0, 0x14, + 0x99, 0x0e, 0x23, 0x19, 0x40, 0xc3, 0x07, 0xdb, + 0x0f, 0xed, 0x09, 0x00, 0x51, 0x00, 0x19, 0x43, + 0x13, 0x9b, 0xde, 0x06, 0xf6, 0x0e, 0x00, 0x96, + 0x06, 0x0b, 0xf6, 0x06, 0xf6, 0x0e, 0x04, 0x96, + 0x18, 0x36, 0x21, 0x9b, 0x09, 0x96, 0x04, 0x9e, + 0x08, 0x36, 0x08, 0x96, 0x02, 0x2b, 0x14, 0xd1, + 0x00, 0x9e, 0x0e, 0x23, 0x1e, 0x40, 0x00, 0x0b, + 0x02, 0x23, 0x18, 0x40, 0x8e, 0x42, 0x06, 0xd8, + 0x00, 0x28, 0x02, 0xd0, 0x08, 0x9e, 0x24, 0xe0, + 0x69, 0xe1, 0x09, 0x9e, 0x21, 0xe0, 0x00, 0x28, + 0x01, 0xd0, 0x09, 0x9e, 0x1d, 0xe0, 0x08, 0x9e, + 0x1b, 0xe0, 0x21, 0x9b, 0x01, 0x2b, 0x13, 0xd1, + 0x00, 0x9e, 0x33, 0x07, 0x1b, 0x0f, 0x00, 0x0b, + 0xc0, 0x07, 0xc0, 0x0f, 0x8b, 0x42, 0x05, 0xd8, + 0x00, 0x28, 0x01, 0xd0, 0x08, 0x9e, 0x0c, 0xe0, + 0x09, 0x9e, 0x0a, 0xe0, 0x00, 0x28, 0x01, 0xd0, + 0x09, 0x9e, 0x06, 0xe0, 0x08, 0x9e, 0x04, 0xe0, + 0x80, 0x09, 0x01, 0xd3, 0x08, 0x9e, 0x00, 0xe0, + 0x09, 0x9e, 0x00, 0x98, 0x81, 0x42, 0x04, 0xd3, + 0x00, 0x98, 0x08, 0x1a, 0x80, 0x19, 0x05, 0xe0, + 0x3b, 0xe1, 0x00, 0x98, 0x40, 0x1a, 0x00, 0x07, + 0x00, 0x0f, 0x30, 0x1a, 0x38, 0x18, 0xc0, 0x06, + 0xc0, 0x0e, 0x60, 0x40, 0x53, 0x5d, 0x0a, 0x9c, + 0x12, 0x99, 0x00, 0x2c, 0x02, 0xd0, 0x1f, 0x1c, + 0x1f, 0x23, 0x7b, 0x40, 0x5b, 0x02, 0x19, 0x43, + 0xcb, 0x09, 0x5b, 0x01, 0x18, 0x43, 0x0f, 0x9b, + 0x49, 0x06, 0x18, 0x5c, 0x49, 0x0e, 0x49, 0x01, + 0x10, 0x9b, 0x08, 0x43, 0x18, 0x5c, 0x0c, 0x9f, + 0xd1, 0x5d, 0x0d, 0x9b, 0x08, 0x18, 0x18, 0x18, + 0x0e, 0x9b, 0x18, 0x5c, 0x19, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x97, 0x4b, 0x0b, 0x40, + 0x88, 0x42, 0x03, 0xd3, 0xc0, 0x1a, 0x80, 0x08, + 0x00, 0x90, 0x05, 0xe0, 0x1e, 0x1c, 0x94, 0x4b, + 0x33, 0x43, 0xc0, 0x1a, 0xed, 0x09, 0x00, 0x52, + 0x00, 0x80, 0x08, 0x00, 0x90, 0x48, 0x08, 0x0e, + 0x23, 0x18, 0x40, 0xcb, 0x07, 0xdb, 0x0f, 0x18, + 0x43, 0x0b, 0x9b, 0x1e, 0x07, 0x36, 0x0f, 0x09, + 0x0b, 0xc9, 0x06, 0xc9, 0x0e, 0x03, 0x91, 0x18, + 0x31, 0x07, 0x91, 0x03, 0x99, 0x08, 0x31, 0x06, + 0x91, 0x03, 0x99, 0xc9, 0x07, 0xc9, 0x0f, 0x86, + 0x42, 0x05, 0xd8, 0x00, 0x29, 0x01, 0xd0, 0x06, + 0x99, 0x06, 0xe0, 0x07, 0x99, 0x04, 0xe0, 0x00, + 0x29, 0x01, 0xd0, 0x07, 0x99, 0x00, 0xe0, 0x06, + 0x99, 0x98, 0x42, 0x02, 0xd3, 0xc0, 0x1a, 0x40, + 0x18, 0x03, 0xe0, 0x18, 0x1a, 0x00, 0x07, 0x00, + 0x0f, 0x08, 0x1a, 0x00, 0x99, 0x53, 0x5d, 0x79, + 0x18, 0x08, 0x18, 0xc0, 0x06, 0xc0, 0x0e, 0x60, + 0x40, 0x0a, 0x9c, 0x12, 0x99, 0x00, 0x2c, 0x02, + 0xd0, 0x1f, 0x1c, 0x1f, 0x23, 0x7b, 0x40, 0x5b, + 0x02, 0x19, 0x43, 0xcb, 0x09, 0x5b, 0x01, 0x18, + 0x43, 0x0f, 0x9b, 0x49, 0x06, 0x18, 0x5c, 0x49, + 0x0e, 0x49, 0x01, 0x10, 0x9b, 0x08, 0x43, 0x18, + 0x5c, 0x0c, 0x9f, 0xd1, 0x5d, 0x0d, 0x9b, 0x08, + 0x18, 0x18, 0x18, 0x0e, 0x9b, 0x18, 0x5c, 0x9f, + 0xe7, 0x82, 0xe0, 0x02, 0xe0, 0x66, 0xe0, 0xb2, + 0xe0, 0x3e, 0xe0, 0x0b, 0x9b, 0x46, 0x1a, 0x02, + 0x93, 0x66, 0x4b, 0x0b, 0x43, 0xc3, 0x1a, 0x05, + 0x93, 0x88, 0x42, 0x02, 0xd3, 0x73, 0x1c, 0x9b, + 0x08, 0x02, 0xe0, 0x05, 0x9b, 0x01, 0x33, 0x9b, + 0x08, 0xfb, 0x18, 0x02, 0x9f, 0xdb, 0x19, 0xdb, + 0x06, 0xdb, 0x0e, 0x5c, 0x40, 0x12, 0x9b, 0x27, + 0x1c, 0x01, 0x93, 0x54, 0x5d, 0x88, 0x42, 0x01, + 0xd3, 0x33, 0x1c, 0x00, 0xe0, 0x05, 0x9b, 0x5d, + 0x1c, 0xab, 0x08, 0x01, 0xd3, 0x1f, 0x23, 0x5c, + 0x40, 0x63, 0x02, 0x01, 0x9c, 0x23, 0x43, 0xdc, + 0x09, 0x64, 0x01, 0x27, 0x43, 0x0f, 0x9c, 0xed, + 0x09, 0x00, 0x53, 0x00, 0x5b, 0x06, 0xe7, 0x5d, + 0x5b, 0x0e, 0x5b, 0x01, 0x3b, 0x43, 0x10, 0x9f, + 0xfb, 0x5c, 0x0c, 0x9f, 0xd2, 0x5d, 0xd2, 0x18, + 0x88, 0x42, 0x00, 0xd2, 0x05, 0x9e, 0x02, 0x23, + 0x70, 0x1c, 0x18, 0x40, 0x00, 0x01, 0x0e, 0x9b, + 0x80, 0x18, 0x18, 0x5c, 0x5b, 0xe7, 0x17, 0x98, + 0x13, 0x9b, 0x18, 0x18, 0xc0, 0x19, 0xc0, 0x06, + 0x53, 0x5d, 0x18, 0x9f, 0xc0, 0x0e, 0x60, 0x40, + 0x05, 0x2f, 0x12, 0x99, 0x02, 0xd1, 0x1f, 0x1c, + 0x1f, 0x23, 0x7b, 0x40, 0x5b, 0x02, 0x19, 0x43, + 0xcb, 0x09, 0x5b, 0x01, 0x18, 0x43, 0x0f, 0x9b, + 0x49, 0x06, 0x18, 0x5c, 0x49, 0x0e, 0x49, 0x01, + 0x10, 0x9b, 0x08, 0x43, 0x18, 0x5c, 0x0c, 0x9f, + 0xd1, 0x5d, 0x18, 0x9b, 0x08, 0x18, 0x05, 0x2b, + 0x00, 0xd1, 0x20, 0x30, 0x0e, 0x9b, 0x18, 0x5c, + 0x35, 0xe7, 0x13, 0x9b, 0xd8, 0x19, 0xc0, 0x06, + 0x53, 0x5d, 0xc0, 0x0e, 0x60, 0x40, 0x12, 0x99, + 0x5b, 0x02, 0x19, 0x43, 0xcb, 0x09, 0x5b, 0x01, + 0x18, 0x43, 0x0f, 0x9b, 0x49, 0x06, 0x18, 0x5c, + 0x49, 0x0e, 0x49, 0x01, 0x10, 0x9b, 0x08, 0x43, + 0x18, 0x5c, 0x0c, 0x9f, 0xd1, 0x5d, 0x0e, 0x9b, + 0x08, 0x18, 0x18, 0x5c, 0x1b, 0xe7, 0x41, 0x0d, + 0x79, 0x40, 0x83, 0x08, 0xc9, 0x18, 0xc9, 0x06, + 0xc9, 0x0e, 0x61, 0x40, 0x11, 0x9b, 0xc7, 0x09, + 0x7b, 0x40, 0xdf, 0x05, 0xff, 0x0d, 0x04, 0x0c, + 0x53, 0x5d, 0xe4, 0x06, 0xe4, 0x0e, 0x63, 0x40, + 0x0a, 0x9c, 0x00, 0x2c, 0x02, 0xd0, 0x1c, 0x1c, + 0x1f, 0x23, 0x63, 0x40, 0x5b, 0x02, 0x3b, 0x43, + 0xdf, 0x09, 0x7f, 0x01, 0x39, 0x43, 0x0f, 0x9c, + 0x5b, 0x06, 0x61, 0x5c, 0x5b, 0x0e, 0x5b, 0x01, + 0x19, 0x43, 0x10, 0x9b, 0x59, 0x5c, 0x0c, 0x9f, + 0xd2, 0x5d, 0x57, 0x18, 0x16, 0x49, 0xc0, 0x08, + 0x01, 0x40, 0xed, 0x09, 0x00, 0x54, 0x00, 0x4f, + 0x20, 0xfa, 0xf7, 0x83, 0xff, 0x0d, 0x9b, 0xc8, + 0x19, 0x18, 0x18, 0x0e, 0x9b, 0x18, 0x5c, 0xe8, + 0xe6, 0x00, 0x20, 0xe6, 0xe6, 0x00, 0x2c, 0x09, + 0xd1, 0x81, 0x07, 0x89, 0x0f, 0x0e, 0x48, 0x01, + 0xd1, 0x47, 0x6a, 0x0c, 0xe0, 0x02, 0x29, 0x0a, + 0xd1, 0x07, 0x6a, 0x08, 0xe0, 0x05, 0x2c, 0x06, + 0xd1, 0x05, 0x20, 0x14, 0x99, 0xfa, 0xf7, 0x69, + 0xff, 0x08, 0x48, 0x40, 0x5c, 0xd1, 0xe6, 0x38, + 0x06, 0x00, 0x0e, 0xce, 0xe6, 0x00, 0x00, 0x04, + 0x7e, 0x03, 0x20, 0xfc, 0xff, 0xff, 0x0f, 0x00, + 0x00, 0x00, 0xf0, 0xf0, 0xff, 0xff, 0x01, 0x48, + 0xe6, 0x03, 0x20, 0x14, 0x7e, 0x03, 0x20, 0xf0, + 0xb5, 0x83, 0xb0, 0x00, 0x27, 0x99, 0x26, 0xb6, + 0x00, 0x05, 0x1c, 0x30, 0x1c, 0x20, 0xf0, 0x91, + 0xfb, 0x04, 0x1c, 0x01, 0xd1, 0x07, 0x27, 0x17, + 0xe0, 0x0e, 0x48, 0x29, 0x1a, 0xf4, 0x20, 0x0b, + 0xf0, 0xae, 0xfc, 0x0c, 0x4b, 0x30, 0x30, 0x98, + 0x71, 0x0d, 0x20, 0x00, 0x90, 0x06, 0x22, 0x1e, + 0x21, 0x01, 0x91, 0x02, 0x92, 0xe8, 0x1d, 0xa5, + 0x30, 0x22, 0x1c, 0x19, 0x1c, 0x33, 0x1c, 0x20, + 0xf0, 0x68, 0xfc, 0x00, 0x28, 0x00, 0xd0, 0x07, + 0x27, 0x38, 0x1c, 0x03, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xfc, 0xef, 0x03, 0x20, 0x1c, + 0x7e, 0x03, 0x20, 0xf0, 0xb5, 0x9e, 0xb0, 0x15, + 0x1c, 0x04, 0x1c, 0x68, 0x46, 0x0a, 0x1c, 0x0f, + 0x1c, 0xaa, 0x21, 0xfa, 0xf7, 0x80, 0xff, 0x6e, + 0x1e, 0x00, 0x2d, 0x09, 0xd0, 0x69, 0x46, 0x00, + 0x23, 0x20, 0x1c, 0x3a, 0x1c, 0x20, 0xf0, 0x13, + 0xfd, 0x30, 0x1c, 0x01, 0x3e, 0x00, 0x28, 0xf5, + 0xd1, 0x1e, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x08, 0x48, 0xc1, 0x1d, 0xff, 0x31, 0xe2, + 0x31, 0x81, 0x42, 0x07, 0xd9, 0xed, 0x09, 0x00, + 0x55, 0x00, 0x02, 0x68, 0x00, 0x2a, 0x01, 0xd0, + 0x01, 0x20, 0x70, 0x47, 0xf4, 0x30, 0x81, 0x42, + 0xf7, 0xd8, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, + 0xfc, 0xef, 0x03, 0x20, 0x06, 0x48, 0xc1, 0x1d, + 0xff, 0x31, 0xe2, 0x31, 0x81, 0x42, 0x05, 0xd9, + 0x02, 0x68, 0x00, 0x2a, 0x03, 0xd0, 0xf4, 0x30, + 0x81, 0x42, 0xf9, 0xd8, 0x00, 0x20, 0x70, 0x47, + 0xfc, 0xef, 0x03, 0x20, 0x01, 0x1c, 0x08, 0x48, + 0xc2, 0x1d, 0xff, 0x32, 0xe2, 0x32, 0x82, 0x42, + 0x08, 0xd9, 0x03, 0x68, 0x00, 0x2b, 0x02, 0xd0, + 0x83, 0x68, 0x8b, 0x42, 0x03, 0xd0, 0xf4, 0x30, + 0x82, 0x42, 0xf6, 0xd8, 0x00, 0x20, 0x70, 0x47, + 0xfc, 0xef, 0x03, 0x20, 0x01, 0x1c, 0x08, 0x48, + 0xc2, 0x1d, 0xff, 0x32, 0xe2, 0x32, 0x82, 0x42, + 0x08, 0xd9, 0x03, 0x68, 0x00, 0x2b, 0x02, 0xd0, + 0x43, 0x68, 0x8b, 0x42, 0x03, 0xd0, 0xf4, 0x30, + 0x82, 0x42, 0xf6, 0xd8, 0x00, 0x20, 0x70, 0x47, + 0xfc, 0xef, 0x03, 0x20, 0xc1, 0x68, 0x00, 0x29, + 0x05, 0xd0, 0x01, 0x39, 0xc1, 0x60, 0x02, 0xd1, + 0x01, 0x21, 0x09, 0x03, 0x81, 0x60, 0x70, 0x47, + 0x70, 0x47, 0xf0, 0xb5, 0x82, 0xb0, 0x46, 0x69, + 0xc1, 0x68, 0x70, 0x6a, 0x00, 0x25, 0x00, 0x90, + 0xc8, 0x1d, 0xf9, 0x30, 0x34, 0x6a, 0x47, 0x69, + 0x00, 0x2f, 0x06, 0xd1, 0x30, 0x1c, 0x22, 0xf0, + 0xeb, 0xff, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf8, 0x6a, 0x00, 0x28, 0x1c, 0xd0, + 0xb9, 0x6a, 0x22, 0x1c, 0x09, 0x1a, 0xa1, 0x42, + 0x00, 0xd2, 0x0a, 0x1c, 0xc0, 0x19, 0x30, 0x30, + 0x15, 0x1c, 0x00, 0x99, 0xfa, 0xf7, 0x7e, 0xff, + 0xf8, 0x6a, 0xba, 0x6a, 0x40, 0x19, 0x90, 0x42, + 0x09, 0xd3, 0xf8, 0x1d, 0xa5, 0x30, 0x00, 0x23, + 0xf9, 0x1d, 0x29, 0x31, 0x20, 0xf0, 0x86, 0xfc, + 0xed, 0x09, 0x00, 0x56, 0x00, 0x00, 0x20, 0xf8, + 0x62, 0x00, 0xe0, 0xf8, 0x62, 0x64, 0x1b, 0xb8, + 0x6a, 0xa0, 0x42, 0x0e, 0xd8, 0xf8, 0x1d, 0xa5, + 0x30, 0x01, 0x90, 0xba, 0x6a, 0x00, 0x99, 0x01, + 0x98, 0x49, 0x19, 0x00, 0x23, 0x20, 0xf0, 0x74, + 0xfc, 0xb8, 0x6a, 0x45, 0x19, 0x24, 0x1a, 0xa0, + 0x42, 0xf3, 0xd9, 0x00, 0x2c, 0x07, 0xd0, 0xfc, + 0x62, 0x00, 0x99, 0xf8, 0x1d, 0x29, 0x30, 0x49, + 0x19, 0x22, 0x1c, 0xfa, 0xf7, 0x51, 0xff, 0x30, + 0x1c, 0x22, 0xf0, 0xa8, 0xff, 0xbb, 0xe7, 0x80, + 0xb5, 0x83, 0xb0, 0x10, 0x4f, 0xff, 0xf7, 0x51, + 0xff, 0x00, 0x28, 0x03, 0xd1, 0x01, 0x20, 0x0d, + 0xf0, 0x59, 0xfb, 0xf7, 0xe7, 0x00, 0x22, 0xd2, + 0x43, 0x00, 0x92, 0x01, 0x22, 0x38, 0x1c, 0x01, + 0xa9, 0x02, 0xab, 0x21, 0xf0, 0x83, 0xfc, 0x00, + 0x28, 0xec, 0xd1, 0x01, 0x9a, 0xd0, 0x6d, 0xd1, + 0x69, 0x93, 0x69, 0x42, 0x6f, 0x02, 0x2a, 0xe5, + 0xd1, 0x90, 0x30, 0x0a, 0x1c, 0x30, 0xf0, 0x44, + 0xf9, 0xe0, 0xe7, 0x00, 0x00, 0xbc, 0xed, 0x03, + 0x20, 0xb0, 0xb5, 0x12, 0x4c, 0xff, 0x22, 0x00, + 0x21, 0x20, 0x1c, 0xe9, 0x32, 0xfa, 0xf7, 0x98, + 0xfe, 0x00, 0x27, 0x01, 0x25, 0x2d, 0x03, 0xf4, + 0x20, 0x78, 0x43, 0x00, 0x19, 0x85, 0x60, 0xff, + 0xf7, 0xd7, 0xfe, 0x01, 0x37, 0x02, 0x2f, 0xf6, + 0xd3, 0x09, 0x4f, 0x1e, 0x22, 0xaa, 0x21, 0xf8, + 0x1d, 0xa9, 0x30, 0xfa, 0xf7, 0x85, 0xfe, 0x00, + 0x20, 0xb8, 0x66, 0xf8, 0x66, 0x38, 0x67, 0x78, + 0x67, 0xb8, 0x67, 0xf8, 0x67, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xfc, 0xef, 0x03, + 0x20, 0xb4, 0xed, 0x03, 0x20, 0xf0, 0xb5, 0x04, + 0x1c, 0xff, 0x30, 0x01, 0x30, 0x45, 0x69, 0x00, + 0x2d, 0x16, 0xd0, 0xae, 0x6a, 0xfb, 0xf7, 0xcd, + 0xfa, 0x07, 0x1c, 0xed, 0x09, 0x00, 0x57, 0x00, + 0x11, 0xd0, 0x28, 0x6d, 0xf8, 0x60, 0x20, 0x7e, + 0x38, 0x72, 0x68, 0x6d, 0x00, 0x28, 0x01, 0xd0, + 0xf8, 0x61, 0x0f, 0xe0, 0x30, 0x1c, 0xfb, 0xf7, + 0x4e, 0xfa, 0xf8, 0x61, 0x00, 0x28, 0x05, 0xd1, + 0x38, 0x1c, 0xfb, 0xf7, 0xda, 0xfa, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xaa, 0x21, 0x32, 0x1c, + 0xfa, 0xf7, 0x51, 0xfe, 0x01, 0x22, 0x20, 0x1c, + 0x39, 0x1c, 0xbe, 0x61, 0x00, 0xf0, 0x01, 0xf8, + 0xf1, 0xe7, 0xf7, 0xb5, 0xcd, 0x69, 0x8e, 0x69, + 0x00, 0x98, 0x0f, 0x1c, 0xff, 0x30, 0x01, 0x30, + 0x44, 0x69, 0x00, 0x2c, 0x63, 0xd0, 0xa0, 0x6d, + 0x00, 0x28, 0x05, 0xd1, 0x78, 0x20, 0xfb, 0xf7, + 0x2a, 0xfa, 0xa0, 0x65, 0x00, 0x28, 0x4c, 0xd0, + 0xa0, 0x6d, 0xe1, 0x6d, 0x40, 0x18, 0x29, 0x1c, + 0x32, 0x1c, 0xfa, 0xf7, 0xb8, 0xfe, 0x01, 0x20, + 0x38, 0x61, 0xe0, 0x6d, 0x80, 0x19, 0xe0, 0x65, + 0x02, 0x9a, 0x00, 0x2a, 0x07, 0xd1, 0x20, 0x6e, + 0x80, 0x19, 0x20, 0x66, 0x60, 0x6e, 0x01, 0x30, + 0x60, 0x66, 0xb8, 0x6c, 0xa0, 0x66, 0x60, 0x6d, + 0x00, 0x28, 0x03, 0xd0, 0xa8, 0x42, 0x01, 0xd0, + 0xfb, 0xf7, 0x35, 0xfa, 0x65, 0x65, 0xe0, 0x6d, + 0x5a, 0x28, 0x27, 0xd9, 0xa0, 0x6d, 0x00, 0x25, + 0xf8, 0x61, 0xe0, 0x6d, 0xb8, 0x61, 0x20, 0x6e, + 0x38, 0x62, 0x60, 0x6e, 0xb8, 0x62, 0xa0, 0x6e, + 0x58, 0x34, 0xb8, 0x64, 0x00, 0x20, 0x21, 0xc4, + 0x21, 0xc4, 0x68, 0x3c, 0x77, 0x20, 0xc0, 0x43, + 0xa0, 0x66, 0xfb, 0xf7, 0x21, 0xfa, 0x06, 0x1c, + 0x21, 0xd0, 0x35, 0x20, 0x30, 0x60, 0x00, 0x98, + 0x40, 0x68, 0x40, 0x68, 0xf0, 0x60, 0x0e, 0x20, + 0x31, 0x1c, 0x37, 0x61, 0xfb, 0xf7, 0x83, 0xfa, + 0x00, 0x28, 0x27, 0xd0, 0x30, 0x1c, 0xfb, 0xf7, + 0x4a, 0xfa, 0x14, 0xe0, 0x00, 0x20, 0xed, 0x09, + 0x00, 0x58, 0x00, 0xf8, 0x61, 0x11, 0xe0, 0x60, + 0x6d, 0x00, 0x28, 0x03, 0xd0, 0xa8, 0x42, 0x01, + 0xd0, 0xfb, 0xf7, 0xff, 0xf9, 0xfb, 0xf7, 0x02, + 0xfa, 0x06, 0x1c, 0x03, 0xd0, 0x00, 0x20, 0x60, + 0x65, 0xdd, 0xe7, 0x02, 0xe0, 0x00, 0x20, 0x65, + 0x65, 0xf8, 0x61, 0x00, 0x2f, 0x0c, 0xd0, 0x38, + 0x6b, 0x00, 0x28, 0x01, 0xd0, 0xfb, 0xf7, 0xed, + 0xf9, 0xf8, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xfb, + 0xf7, 0xe8, 0xf9, 0x38, 0x1c, 0xfb, 0xf7, 0x4b, + 0xfa, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xff, + 0x30, 0x01, 0x30, 0x15, 0x4c, 0x45, 0x69, 0xbc, + 0x67, 0x7a, 0x68, 0x20, 0x1c, 0xd6, 0x1d, 0x51, + 0x36, 0x0c, 0xce, 0x0c, 0xc0, 0x38, 0x7e, 0x00, + 0x26, 0x20, 0x72, 0x01, 0x20, 0x60, 0x72, 0xe1, + 0x60, 0x20, 0x1c, 0x39, 0x1c, 0xe6, 0x63, 0x07, + 0xf0, 0xed, 0xfa, 0xa8, 0x6a, 0x0c, 0x49, 0xa0, + 0x61, 0xa8, 0x6a, 0x00, 0x22, 0xa0, 0x63, 0xe1, + 0x61, 0x00, 0x92, 0xe8, 0x1d, 0xa5, 0x30, 0xaa, + 0x6a, 0x01, 0xab, 0x20, 0xf0, 0x24, 0xfc, 0x00, + 0x28, 0x01, 0xd0, 0x05, 0x48, 0xe0, 0x61, 0xb9, + 0x6f, 0x8e, 0x65, 0x02, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x04, 0xee, 0x03, 0x20, 0x82, + 0xee, 0x03, 0x20, 0x64, 0xee, 0x03, 0x20, 0xf0, + 0xb5, 0x08, 0x68, 0x0f, 0x1c, 0x26, 0x28, 0x3d, + 0xd0, 0x27, 0x28, 0x35, 0xd1, 0xfd, 0x68, 0x30, + 0xf0, 0x00, 0xf8, 0xe8, 0x1d, 0xf9, 0x30, 0x44, + 0x69, 0x00, 0x2c, 0x25, 0xd0, 0x69, 0x68, 0xff, + 0x31, 0x91, 0x31, 0x0a, 0x68, 0x02, 0x23, 0x9a, + 0x43, 0x0a, 0x60, 0x00, 0x25, 0x25, 0x60, 0xe5, + 0x61, 0x25, 0x62, 0x65, 0x62, 0x45, 0x61, 0x20, + 0x1c, 0xff, 0xf7, 0x4b, 0xfe, 0x07, 0x20, 0x20, + 0x65, 0xed, 0x09, 0x00, 0x59, 0x00, 0x1e, 0x22, + 0xa2, 0x62, 0xa0, 0x6d, 0x00, 0x28, 0x08, 0xd0, + 0xfb, 0xf7, 0x82, 0xf9, 0xa5, 0x65, 0xe5, 0x65, + 0x77, 0x21, 0xc9, 0x43, 0x25, 0x66, 0xa1, 0x66, + 0x65, 0x66, 0x60, 0x6d, 0x00, 0x28, 0x02, 0xd0, + 0xfb, 0xf7, 0x76, 0xf9, 0x65, 0x65, 0x2f, 0xf0, + 0xcf, 0xff, 0xff, 0xf7, 0x3b, 0xfe, 0xe0, 0x1d, + 0xa5, 0x30, 0x2f, 0xf0, 0x57, 0xfd, 0x38, 0x1c, + 0xfb, 0xf7, 0xaa, 0xf9, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xfc, 0x68, 0x7d, 0x6a, 0xe6, 0x1d, + 0xf9, 0x36, 0x70, 0x69, 0x00, 0x28, 0xf2, 0xd1, + 0x2f, 0xf0, 0xbe, 0xff, 0x28, 0x1c, 0xff, 0xf7, + 0xf3, 0xfd, 0x00, 0x28, 0x06, 0xd1, 0xff, 0xf7, + 0xdf, 0xfd, 0x00, 0x28, 0x02, 0xd1, 0x2f, 0xf0, + 0xaf, 0xff, 0xe4, 0xe7, 0x00, 0x21, 0xc1, 0x61, + 0x3a, 0x6a, 0x02, 0x62, 0xfa, 0x69, 0x42, 0x62, + 0xba, 0x69, 0x02, 0x65, 0x7b, 0x69, 0x05, 0x2a, + 0x43, 0x67, 0x1e, 0xd0, 0x06, 0x2a, 0x1f, 0xd0, + 0x07, 0x2a, 0x01, 0xd1, 0x1e, 0x22, 0x82, 0x62, + 0x41, 0x65, 0xc1, 0x62, 0x81, 0x65, 0xc1, 0x65, + 0x01, 0x66, 0x41, 0x66, 0x77, 0x21, 0xc9, 0x43, + 0x81, 0x66, 0x61, 0x68, 0xff, 0x31, 0x91, 0x31, + 0x0a, 0x68, 0x02, 0x23, 0x1a, 0x43, 0x0a, 0x60, + 0x85, 0x60, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, + 0x04, 0x60, 0x70, 0x61, 0x2f, 0xf0, 0x84, 0xff, + 0xb9, 0xe7, 0x0a, 0x22, 0x82, 0x62, 0xe3, 0xe7, + 0x14, 0x22, 0x82, 0x62, 0xe0, 0xe7, 0x00, 0x00, + 0x00, 0xb5, 0x08, 0x20, 0x2f, 0xf0, 0xa8, 0xff, + 0x02, 0x48, 0x2f, 0xf0, 0xa1, 0xff, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x34, 0xf2, 0x03, 0x20, + 0x00, 0xb5, 0xff, 0x20, 0x01, 0x30, 0x2f, 0xf0, + 0x9b, 0xff, 0x02, 0x48, 0x2f, 0xf0, 0x94, 0xff, + 0x08, 0xbc, 0x18, 0x47, 0xed, 0x09, 0x00, 0x5a, + 0x00, 0x8c, 0xf2, 0x03, 0x20, 0x00, 0xb5, 0x01, + 0x20, 0x08, 0xf0, 0x62, 0xf9, 0x08, 0xbc, 0x18, + 0x47, 0xb0, 0xb5, 0x48, 0x4f, 0x38, 0x68, 0x38, + 0x68, 0x40, 0x08, 0x08, 0xd3, 0x01, 0x20, 0xf8, + 0x60, 0xb8, 0x68, 0x40, 0x08, 0x40, 0x00, 0xb8, + 0x60, 0x00, 0x20, 0xfd, 0xf7, 0x51, 0xf8, 0x38, + 0x68, 0x80, 0x08, 0x03, 0xd3, 0x02, 0x20, 0xf8, + 0x60, 0xfe, 0xf7, 0x32, 0xfb, 0x2f, 0xf0, 0x4a, + 0xff, 0xff, 0x25, 0x3c, 0x68, 0x09, 0x35, 0x25, + 0x40, 0x07, 0xd0, 0x0b, 0xf0, 0x37, 0xff, 0xff, + 0x20, 0x09, 0x30, 0xf8, 0x60, 0x28, 0x1c, 0x08, + 0xf0, 0x3b, 0xf9, 0x60, 0x09, 0x03, 0xd3, 0x10, + 0x20, 0xf8, 0x60, 0x08, 0xf0, 0xcb, 0xf9, 0xe0, + 0x08, 0x03, 0xd3, 0x04, 0x20, 0xf8, 0x60, 0x08, + 0xf0, 0x49, 0xfa, 0x0b, 0x20, 0x3c, 0x68, 0x80, + 0x01, 0x20, 0x40, 0x04, 0xd0, 0x0b, 0x21, 0x89, + 0x01, 0xf9, 0x60, 0x08, 0xf0, 0x3f, 0xfb, 0xa0, + 0x09, 0x03, 0xd3, 0x20, 0x20, 0xf8, 0x60, 0x08, + 0xf0, 0xb1, 0xfa, 0x2f, 0xf0, 0x1b, 0xff, 0x38, + 0x68, 0xc0, 0x0a, 0x04, 0xd3, 0x01, 0x20, 0x80, + 0x02, 0xf8, 0x60, 0x08, 0xf0, 0xb3, 0xfb, 0x38, + 0x68, 0x00, 0x0b, 0x04, 0xd3, 0x01, 0x20, 0xc0, + 0x02, 0xf8, 0x60, 0x08, 0xf0, 0x2f, 0xfc, 0x38, + 0x68, 0x40, 0x0b, 0x04, 0xd3, 0x01, 0x20, 0x00, + 0x03, 0xf8, 0x60, 0x08, 0xf0, 0x27, 0xfc, 0x38, + 0x68, 0x80, 0x0b, 0x04, 0xd3, 0x01, 0x20, 0x40, + 0x03, 0xf8, 0x60, 0x08, 0xf0, 0x1f, 0xfc, 0x38, + 0x68, 0xc0, 0x0b, 0x04, 0xd3, 0x01, 0x20, 0x80, + 0x03, 0xf8, 0x60, 0x08, 0xf0, 0x17, 0xfc, 0x38, + 0x68, 0x00, 0x0c, 0x04, 0xd3, 0x01, 0x20, 0xc0, + 0x03, 0xf8, 0x60, 0x08, 0xf0, 0x0f, 0xfc, 0x38, + 0x68, 0x40, 0x0c, 0x04, 0xd3, 0x01, 0x20, 0xed, + 0x09, 0x00, 0x5b, 0x00, 0x00, 0x04, 0xf8, 0x60, + 0x08, 0xf0, 0x07, 0xfc, 0x38, 0x68, 0x80, 0x0c, + 0x04, 0xd3, 0x01, 0x20, 0x40, 0x04, 0xf8, 0x60, + 0x08, 0xf0, 0xff, 0xfb, 0x38, 0x68, 0xc0, 0x0c, + 0x04, 0xd3, 0x01, 0x20, 0x80, 0x04, 0xf8, 0x60, + 0x08, 0xf0, 0xf7, 0xfb, 0x08, 0x20, 0x2f, 0xf0, + 0xdc, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, 0xf0, 0xb5, + 0x85, 0xb0, 0x0f, 0x1c, 0x61, 0x49, 0x5f, 0x48, + 0xc8, 0x60, 0x60, 0x4c, 0xf9, 0x1d, 0x22, 0x63, + 0xe7, 0x62, 0xf8, 0x68, 0x35, 0x31, 0x04, 0x91, + 0x5e, 0x49, 0xfc, 0x1d, 0x03, 0x91, 0x5d, 0x49, + 0xfd, 0x1d, 0xfe, 0x1d, 0x8d, 0x36, 0xad, 0x35, + 0x79, 0x34, 0x03, 0x28, 0x02, 0x91, 0x75, 0xd0, + 0x05, 0x28, 0x74, 0xd0, 0x07, 0x28, 0x2c, 0xd1, + 0x03, 0x98, 0x54, 0x4a, 0x80, 0x6b, 0x01, 0x02, + 0x09, 0x0a, 0x00, 0x0e, 0x90, 0x63, 0x51, 0x63, + 0x02, 0x99, 0x01, 0x20, 0x48, 0x60, 0xe0, 0x69, + 0x02, 0x99, 0x88, 0x60, 0x00, 0x20, 0x78, 0x61, + 0x38, 0x62, 0x4f, 0xa1, 0x0c, 0xc9, 0xf8, 0x1d, + 0x1d, 0x30, 0x0c, 0xc0, 0x4d, 0xa1, 0x0c, 0xc9, + 0xf8, 0x1d, 0x11, 0x30, 0x0c, 0xc0, 0x4a, 0xa1, + 0x0c, 0xc9, 0xf8, 0x1d, 0x25, 0x30, 0x0c, 0xc0, + 0x00, 0x20, 0x78, 0x63, 0x49, 0x49, 0x04, 0x98, + 0x01, 0x91, 0x0c, 0xc9, 0x0c, 0xc0, 0x01, 0x99, + 0x30, 0x1c, 0x0c, 0xc9, 0x0c, 0xc0, 0x00, 0x20, + 0x78, 0x64, 0x2f, 0xf0, 0x82, 0xfe, 0x43, 0x48, + 0x03, 0x21, 0x01, 0x60, 0x43, 0x49, 0x4a, 0x68, + 0x82, 0x62, 0x03, 0x98, 0x43, 0x4b, 0x42, 0x69, + 0x41, 0x48, 0x01, 0x2a, 0x56, 0xd0, 0x02, 0x2a, + 0x03, 0xd1, 0x62, 0x21, 0x19, 0x60, 0x01, 0x21, + 0xc1, 0x60, 0xfa, 0x68, 0x3e, 0x48, 0x3e, 0x49, + 0x03, 0x2a, 0xed, 0x09, 0x00, 0x5c, 0x00, 0x50, + 0xd0, 0x05, 0x2a, 0x4e, 0xd0, 0x07, 0x2a, 0x0d, + 0xd1, 0x35, 0x1c, 0x0c, 0xcd, 0x0c, 0xc1, 0x31, + 0x1c, 0x28, 0xc9, 0x28, 0xc0, 0x28, 0xce, 0x04, + 0x98, 0x2c, 0x4a, 0x28, 0xc0, 0x20, 0x69, 0x90, + 0x61, 0xe0, 0x68, 0xd0, 0x61, 0x29, 0x4c, 0x27, + 0x48, 0xe7, 0x62, 0x81, 0x68, 0x1f, 0x23, 0x5b, + 0x01, 0x99, 0x43, 0x81, 0x60, 0x31, 0x49, 0xc1, + 0x60, 0x81, 0x68, 0x2f, 0x4b, 0x19, 0x43, 0x81, + 0x60, 0x68, 0x46, 0xfe, 0xf7, 0x92, 0xfa, 0x00, + 0x21, 0x2d, 0x4a, 0x0b, 0xf0, 0xbc, 0xf8, 0x00, + 0x9a, 0x02, 0x32, 0x17, 0x01, 0x3f, 0x09, 0x01, + 0xe0, 0x12, 0xe0, 0x0b, 0xe0, 0x00, 0x97, 0x60, + 0x60, 0x00, 0x20, 0x27, 0x60, 0x00, 0xf0, 0x91, + 0xf8, 0x2f, 0xf0, 0x31, 0xfe, 0x05, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0c, 0xcd, 0x08, + 0x3d, 0x00, 0x21, 0x38, 0x1c, 0x06, 0xf0, 0xfc, + 0xfd, 0x20, 0x48, 0x11, 0x4a, 0x50, 0x63, 0x00, + 0x20, 0x90, 0x63, 0x02, 0x99, 0x01, 0x20, 0x48, + 0x60, 0xe0, 0x69, 0x02, 0x99, 0x88, 0x60, 0x9a, + 0xe7, 0x80, 0x22, 0x1a, 0x60, 0xc9, 0x68, 0xc1, + 0x60, 0xa9, 0xe7, 0x2e, 0x1c, 0x0c, 0xce, 0x0c, + 0xc1, 0x29, 0x1c, 0x48, 0xc9, 0x48, 0xc0, 0x48, + 0xcd, 0x04, 0x98, 0x05, 0x4a, 0x48, 0xc0, 0x20, + 0x6b, 0x90, 0x61, 0xe0, 0x6a, 0xd0, 0x61, 0xb1, + 0xe7, 0x00, 0x00, 0xfc, 0x07, 0x02, 0x00, 0x00, + 0x50, 0x00, 0xe0, 0x34, 0xf3, 0x03, 0x20, 0x48, + 0xe6, 0x03, 0x20, 0x74, 0x03, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, + 0xe6, 0x03, 0x20, 0x00, 0x51, 0x00, 0xe0, 0x88, + 0xe5, 0x03, 0x20, 0x00, 0x52, 0x00, 0xe0, 0x40, + 0x53, 0x00, 0xe0, 0x90, 0x57, 0x00, 0xe0, 0x20, + 0x51, 0x00, 0xe0, 0x18, 0x00, 0xed, 0x09, 0x00, + 0x5d, 0x00, 0x02, 0x00, 0xe2, 0x04, 0x00, 0x00, + 0x33, 0x8b, 0x9e, 0x00, 0x00, 0xb5, 0x2f, 0xf0, + 0xe5, 0xfd, 0x18, 0x49, 0x00, 0x20, 0x08, 0x60, + 0x17, 0x49, 0x08, 0x60, 0x17, 0x49, 0x8a, 0x68, + 0x17, 0x4b, 0x1a, 0x40, 0x8a, 0x60, 0xda, 0x43, + 0xca, 0x60, 0x16, 0x49, 0x08, 0x62, 0x48, 0x62, + 0x88, 0x62, 0xc8, 0x62, 0x08, 0x63, 0x48, 0x63, + 0x13, 0x49, 0xc8, 0x1d, 0xb9, 0x30, 0x42, 0x69, + 0x12, 0x48, 0x01, 0x2a, 0x0e, 0xd0, 0x02, 0x2a, + 0x06, 0xd1, 0x09, 0x68, 0x40, 0x23, 0x19, 0x43, + 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x01, 0x62, + 0x01, 0x21, 0x41, 0x60, 0x2f, 0xf0, 0xba, 0xfd, + 0x08, 0xbc, 0x18, 0x47, 0x09, 0x68, 0x80, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, + 0x01, 0x62, 0xf1, 0xe7, 0x00, 0x51, 0x00, 0xe0, + 0x00, 0x52, 0x00, 0xe0, 0x00, 0x50, 0x00, 0xe0, + 0x03, 0xf8, 0xfd, 0xff, 0x00, 0x53, 0x00, 0xe0, + 0x88, 0xe5, 0x03, 0x20, 0x40, 0x53, 0x00, 0xe0, + 0xf0, 0xb5, 0x85, 0xb0, 0x73, 0x4e, 0x71, 0x68, + 0x73, 0x4b, 0xcc, 0x18, 0x31, 0x68, 0xf7, 0x6a, + 0x8d, 0x1c, 0x40, 0x08, 0x08, 0xd3, 0x00, 0x20, + 0x39, 0x1c, 0x32, 0x6b, 0xff, 0xf7, 0xc8, 0xfe, + 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x20, 0xfc, 0xf7, 0x8d, 0xfe, 0x00, 0x28, + 0x00, 0xd0, 0xf5, 0xe7, 0x69, 0x48, 0x00, 0x69, + 0xff, 0x21, 0xf5, 0x31, 0x20, 0x1a, 0x88, 0x42, + 0x01, 0xda, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, + 0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0x39, 0x1c, + 0x32, 0x6b, 0xff, 0xf7, 0xad, 0xfe, 0xe3, 0xe7, + 0x5e, 0x4e, 0x41, 0x23, 0x9b, 0x01, 0xf0, 0x18, + 0x02, 0x1d, 0x06, 0xca, 0xb0, 0x6b, 0x03, 0x92, + 0x00, 0x06, 0x00, 0x0e, 0x01, 0x90, 0x02, 0x91, + 0xed, 0x09, 0x00, 0x5e, 0x00, 0x72, 0x6b, 0x03, + 0x23, 0x00, 0x92, 0xf8, 0x68, 0x05, 0x28, 0x00, + 0xd0, 0x03, 0x1c, 0xf8, 0x1d, 0xff, 0x30, 0x7a, + 0x30, 0x42, 0x68, 0x00, 0x21, 0x28, 0x1c, 0xff, + 0xf7, 0x31, 0xf9, 0x54, 0x49, 0x07, 0x1c, 0x0e, + 0x68, 0xc0, 0x31, 0x04, 0x91, 0x49, 0x69, 0x20, + 0x1c, 0x01, 0x29, 0x6b, 0xd0, 0x02, 0x29, 0x20, + 0xd1, 0x09, 0x21, 0x0a, 0xf0, 0xaf, 0xff, 0xc8, + 0x22, 0x0a, 0xf0, 0xb6, 0xff, 0x34, 0x22, 0x0a, + 0xf0, 0xb3, 0xff, 0x50, 0x22, 0x0a, 0xf0, 0xb0, + 0xff, 0x0d, 0x22, 0x0a, 0xf0, 0xad, 0xff, 0x04, + 0x22, 0x0a, 0xf0, 0xaa, 0xff, 0x28, 0x22, 0x0a, + 0xf0, 0xa7, 0xff, 0xb9, 0x1c, 0x09, 0x02, 0x10, + 0x22, 0x0a, 0x43, 0x43, 0x49, 0x0a, 0x62, 0x42, + 0x22, 0x32, 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, + 0x43, 0x4a, 0x62, 0x40, 0x4a, 0x40, 0x49, 0x0a, + 0x62, 0x08, 0x60, 0x3c, 0x49, 0x09, 0x68, 0x04, + 0x98, 0x42, 0x69, 0x3e, 0x48, 0x01, 0x2a, 0x5e, + 0xd0, 0x02, 0x2a, 0x05, 0xd1, 0x40, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x01, + 0x62, 0xe1, 0x1d, 0x49, 0x31, 0xff, 0x22, 0x38, + 0x48, 0x02, 0x32, 0x02, 0x62, 0x01, 0x60, 0x04, + 0x99, 0x36, 0x4b, 0x4a, 0x69, 0xe0, 0x18, 0x01, + 0x2a, 0x35, 0x49, 0x4f, 0xd0, 0x02, 0x2a, 0x03, + 0xd1, 0x2d, 0x22, 0x0a, 0x62, 0x2c, 0x22, 0x4a, + 0x62, 0x32, 0x4a, 0x33, 0x49, 0x28, 0x30, 0x0a, + 0x62, 0x08, 0x60, 0xe1, 0x1f, 0x31, 0x48, 0x0d, + 0x39, 0x81, 0x60, 0x23, 0x4e, 0x2b, 0x4b, 0xb1, + 0x69, 0x59, 0x43, 0x09, 0x19, 0x9c, 0x31, 0xc1, + 0x60, 0x01, 0x23, 0x1b, 0x03, 0xc8, 0x1f, 0xc1, + 0x38, 0xf1, 0x18, 0xc8, 0x63, 0xb0, 0x69, 0x25, + 0x49, 0x41, 0x43, 0x09, 0x19, 0x71, 0x60, 0x40, + 0x19, 0x30, 0x60, 0xed, 0x09, 0x00, 0x5f, 0x00, + 0x7d, 0x20, 0x00, 0x01, 0x0b, 0xf0, 0xeb, 0xfc, + 0x53, 0xe7, 0xff, 0xe7, 0x10, 0x21, 0x0a, 0xf0, + 0x44, 0xff, 0xff, 0x22, 0x05, 0x32, 0x0a, 0xf0, + 0x4a, 0xff, 0x46, 0x22, 0x0a, 0xf0, 0x47, 0xff, + 0x0d, 0x22, 0x0a, 0xf0, 0x44, 0xff, 0x04, 0x22, + 0x0a, 0xf0, 0x41, 0xff, 0x28, 0x22, 0x0a, 0xf0, + 0x3e, 0xff, 0xb9, 0x1c, 0x09, 0x02, 0x20, 0x22, + 0x0a, 0x43, 0x0e, 0x49, 0x0a, 0x62, 0x82, 0x22, + 0x32, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, + 0x4a, 0x62, 0x95, 0xe7, 0x80, 0x23, 0x19, 0x43, + 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, 0x62, + 0xa1, 0xe7, 0x3d, 0x22, 0x0a, 0x62, 0x3e, 0x22, + 0x4a, 0x62, 0xb0, 0xe7, 0x00, 0x00, 0x34, 0xf3, + 0x03, 0x20, 0xe2, 0x04, 0x00, 0x00, 0x00, 0x50, + 0x00, 0xe0, 0x88, 0xe5, 0x03, 0x20, 0xa0, 0x55, + 0x00, 0xe0, 0x02, 0x05, 0x00, 0x00, 0x08, 0x53, + 0x00, 0xe0, 0xb0, 0x55, 0x00, 0xe0, 0x0c, 0x53, + 0x00, 0xe0, 0x71, 0x02, 0x00, 0x00, 0xc0, 0x55, + 0x00, 0xe0, 0x02, 0x03, 0x00, 0x00, 0x10, 0x53, + 0x00, 0xe0, 0x00, 0x51, 0x00, 0xe0, 0xb0, 0xb5, + 0x22, 0x48, 0x04, 0x69, 0x22, 0x48, 0x22, 0x4a, + 0xc5, 0x68, 0x11, 0x6a, 0x57, 0x6a, 0x09, 0x0a, + 0xff, 0x23, 0x1b, 0x02, 0x3b, 0x40, 0x19, 0x43, + 0x1f, 0x4b, 0x5f, 0x69, 0x01, 0x23, 0x1b, 0x04, + 0x01, 0x2f, 0x28, 0xd0, 0x02, 0x2f, 0x07, 0xd1, + 0x1d, 0x1c, 0x0b, 0x0c, 0x00, 0xd2, 0x00, 0x25, + 0x29, 0x43, 0x01, 0x23, 0xdb, 0x03, 0x99, 0x43, + 0x41, 0x23, 0x9b, 0x01, 0xc3, 0x18, 0x19, 0x60, + 0x01, 0x2f, 0x1d, 0xd0, 0x02, 0x2f, 0x03, 0xd1, + 0x2d, 0x21, 0x11, 0x62, 0x2c, 0x21, 0x51, 0x62, + 0x12, 0x4b, 0xe7, 0x18, 0x01, 0x23, 0x1b, 0x03, + 0xc0, 0x18, 0xc1, 0x6b, 0xc8, 0x22, 0xed, 0x09, + 0x00, 0x60, 0x00, 0x38, 0x1c, 0xfe, 0xf7, 0x33, + 0xfe, 0x00, 0x28, 0x03, 0xd1, 0x0d, 0x49, 0x0d, + 0x48, 0x01, 0x63, 0x07, 0x61, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x2d, 0x00, 0xd1, 0x00, + 0x23, 0x19, 0x43, 0xdb, 0xe7, 0x3d, 0x21, 0x11, + 0x62, 0x3e, 0x21, 0x51, 0x62, 0xe2, 0xe7, 0x00, + 0x50, 0x00, 0xe0, 0x34, 0xf3, 0x03, 0x20, 0xc0, + 0x55, 0x00, 0xe0, 0x48, 0xe6, 0x03, 0x20, 0xe2, + 0x04, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, + 0x53, 0x00, 0xe0, 0x00, 0xb5, 0x04, 0x48, 0xc1, + 0x6a, 0x02, 0x6b, 0x01, 0x20, 0xff, 0xf7, 0x77, + 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x34, + 0xf3, 0x03, 0x20, 0x00, 0xb5, 0x2f, 0xf0, 0x3d, + 0xfc, 0x18, 0x49, 0x00, 0x20, 0x08, 0x60, 0x17, + 0x49, 0x08, 0x60, 0x17, 0x49, 0x8a, 0x68, 0x17, + 0x4b, 0x1a, 0x40, 0x8a, 0x60, 0xda, 0x43, 0xca, + 0x60, 0x16, 0x49, 0x08, 0x62, 0x48, 0x62, 0x88, + 0x62, 0xc8, 0x62, 0x08, 0x63, 0x48, 0x63, 0x13, + 0x48, 0x14, 0x49, 0x42, 0x69, 0x14, 0x48, 0x01, + 0x2a, 0x0e, 0xd0, 0x02, 0x2a, 0x06, 0xd1, 0x09, + 0x69, 0x40, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, + 0x23, 0x19, 0x43, 0x01, 0x62, 0x01, 0x21, 0x41, + 0x60, 0x2f, 0xf0, 0x13, 0xfc, 0x08, 0xbc, 0x18, + 0x47, 0x09, 0x69, 0x80, 0x23, 0x19, 0x43, 0x09, + 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, 0x62, 0xf1, + 0xe7, 0x00, 0x00, 0x00, 0x51, 0x00, 0xe0, 0x00, + 0x52, 0x00, 0xe0, 0x00, 0x50, 0x00, 0xe0, 0x03, + 0xf8, 0xff, 0xff, 0x00, 0x53, 0x00, 0xe0, 0x48, + 0xe6, 0x03, 0x20, 0xd4, 0x03, 0x04, 0x20, 0x40, + 0x53, 0x00, 0xe0, 0xf0, 0xb5, 0x85, 0xb0, 0xc8, + 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x14, 0x1c, 0x0f, + 0x1c, 0x87, 0x49, 0x40, 0x68, 0xc8, 0x61, 0x0f, + 0x62, 0xed, 0x09, 0x00, 0x61, 0x00, 0x4a, 0x62, + 0x2f, 0xf0, 0xee, 0xfb, 0x84, 0x49, 0x88, 0x68, + 0x84, 0x4b, 0x18, 0x40, 0x88, 0x60, 0xd8, 0x43, + 0xc8, 0x60, 0x83, 0x4a, 0x00, 0x21, 0x11, 0x60, + 0x82, 0x4a, 0x83, 0x48, 0x11, 0x60, 0x01, 0x62, + 0x41, 0x62, 0x81, 0x62, 0xc1, 0x62, 0x01, 0x63, + 0x41, 0x63, 0x80, 0x49, 0x01, 0x20, 0x48, 0x60, + 0xf8, 0x68, 0x7f, 0x49, 0xfd, 0x1d, 0x04, 0x91, + 0xf9, 0x1d, 0x79, 0x31, 0xfe, 0x1d, 0xad, 0x36, + 0x65, 0x35, 0x0c, 0x38, 0x0e, 0x28, 0x03, 0x91, + 0x4d, 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0x07, 0x49, 0x49, 0x23, + 0x23, 0x23, 0x49, 0x49, 0x07, 0x49, 0x49, 0x23, + 0x23, 0x23, 0x74, 0x48, 0x6b, 0x4c, 0x00, 0x21, + 0xa0, 0x62, 0x00, 0x20, 0xe0, 0x62, 0x0c, 0xce, + 0x08, 0x3e, 0x38, 0x1c, 0x06, 0xf0, 0x85, 0xfb, + 0x6f, 0x49, 0x08, 0x68, 0x20, 0x61, 0x88, 0x68, + 0xe0, 0x60, 0xc8, 0x68, 0x60, 0x61, 0x08, 0x69, + 0xa0, 0x61, 0x01, 0x20, 0x60, 0x63, 0x04, 0x99, + 0x00, 0x20, 0x08, 0x60, 0x02, 0x20, 0xa0, 0x63, + 0x25, 0xe0, 0x20, 0x69, 0x5d, 0x4a, 0x00, 0x02, + 0x00, 0x0a, 0x90, 0x62, 0x20, 0x69, 0x00, 0x0e, + 0xd0, 0x62, 0x21, 0x7e, 0x0c, 0xcd, 0x08, 0x3d, + 0x38, 0x1c, 0x06, 0xf0, 0x66, 0xfb, 0x01, 0x22, + 0x38, 0x1c, 0x21, 0x7e, 0x06, 0xf0, 0x8a, 0xfb, + 0xe0, 0x1d, 0xb9, 0x30, 0x81, 0x68, 0x53, 0x4a, + 0x11, 0x61, 0xc1, 0x68, 0xd1, 0x60, 0x01, 0x69, + 0x51, 0x61, 0x40, 0x69, 0x90, 0x61, 0x01, 0x20, + 0x50, 0x63, 0x04, 0x99, 0x00, 0x20, 0x08, 0x60, + 0x03, 0x99, 0xc8, 0x69, 0x90, 0x63, 0x68, 0x46, + 0xfd, 0xf7, 0xc4, 0xff, 0x53, 0x4b, 0x00, 0x99, + 0xc0, 0x18, 0x02, 0x31, 0x09, 0x01, 0x09, 0x09, + 0x00, 0x91, 0xf9, 0x1d, 0xed, 0x09, 0x00, 0x62, + 0x00, 0xfa, 0x68, 0x35, 0x31, 0x50, 0x4b, 0x02, + 0x91, 0x4e, 0x49, 0x0c, 0x2a, 0x01, 0x93, 0x1b, + 0xd0, 0x0f, 0x2a, 0x03, 0xd0, 0x14, 0x2a, 0x17, + 0xd0, 0x17, 0x2a, 0x33, 0xd1, 0x2c, 0x1c, 0x0c, + 0xcc, 0x0c, 0xc1, 0x18, 0xcd, 0x49, 0x49, 0x3f, + 0x4a, 0x18, 0xc1, 0x30, 0xce, 0x02, 0x99, 0x30, + 0xc1, 0x47, 0x49, 0x11, 0x60, 0x3c, 0x4a, 0x03, + 0x21, 0x11, 0x60, 0x38, 0x49, 0x8a, 0x68, 0x10, + 0x23, 0x1a, 0x43, 0x8a, 0x60, 0xb9, 0x6e, 0x1e, + 0xe0, 0x84, 0x37, 0x3c, 0x1c, 0x0c, 0xcf, 0x0c, + 0xc1, 0x88, 0xcc, 0x3e, 0x49, 0x88, 0xc1, 0x90, + 0xce, 0x02, 0x99, 0x90, 0xc1, 0x01, 0x9b, 0x3d, + 0x49, 0x9a, 0x6a, 0x00, 0x2a, 0x00, 0xd1, 0x04, + 0x39, 0x2e, 0x4a, 0x11, 0x60, 0x2e, 0x4a, 0x03, + 0x21, 0x11, 0x60, 0x2a, 0x49, 0x8a, 0x68, 0x17, + 0x23, 0x5b, 0x01, 0x1a, 0x43, 0x8a, 0x60, 0x03, + 0x99, 0x09, 0x68, 0x00, 0xe0, 0x00, 0x21, 0x2d, + 0x4a, 0x26, 0x4b, 0x52, 0x68, 0x9a, 0x62, 0x01, + 0x9b, 0x5a, 0x69, 0x01, 0x2a, 0x21, 0xd0, 0x02, + 0x2a, 0x05, 0xd1, 0x25, 0x4b, 0x62, 0x22, 0x1a, + 0x60, 0x21, 0x4b, 0x01, 0x22, 0xda, 0x60, 0x00, + 0x9a, 0x93, 0x07, 0x9b, 0x0f, 0x0a, 0xd0, 0x01, + 0x2b, 0x1b, 0xd0, 0x02, 0x2b, 0x1e, 0xd0, 0x03, + 0x2b, 0x25, 0xd1, 0x01, 0x32, 0xff, 0x30, 0xff, + 0x30, 0x73, 0x30, 0x00, 0x92, 0x14, 0x4c, 0xa0, + 0x60, 0x00, 0x98, 0x60, 0x60, 0x40, 0x18, 0x20, + 0x60, 0x01, 0x20, 0x80, 0x02, 0x00, 0xf0, 0x40, + 0xf8, 0x15, 0xe0, 0x15, 0x4b, 0x80, 0x22, 0x1a, + 0x60, 0x0d, 0x4c, 0x11, 0x4b, 0x62, 0x69, 0xda, + 0x60, 0xdd, 0xe7, 0x01, 0x32, 0xff, 0x30, 0xff, + 0x30, 0x73, 0x30, 0x00, 0x92, 0x08, 0x4c, 0xa0, + 0x60, 0x00, 0x98, 0x60, 0x60, 0x40, 0x18, 0xed, + 0x09, 0x00, 0x63, 0x00, 0x20, 0x60, 0x08, 0x20, + 0x00, 0xf0, 0xff, 0xf9, 0x04, 0x49, 0x63, 0x20, + 0x08, 0x63, 0x2f, 0xf0, 0xe6, 0xfa, 0x05, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd4, 0x03, + 0x04, 0x20, 0x00, 0x50, 0x00, 0xe0, 0x03, 0xf8, + 0xff, 0xff, 0x00, 0x51, 0x00, 0xe0, 0x00, 0x52, + 0x00, 0xe0, 0x00, 0x53, 0x00, 0xe0, 0x40, 0x53, + 0x00, 0xe0, 0x14, 0x14, 0x04, 0x20, 0x33, 0x8b, + 0x9e, 0x00, 0x88, 0xe5, 0x03, 0x20, 0xe2, 0x04, + 0x00, 0x00, 0x20, 0x51, 0x00, 0xe0, 0x48, 0xe6, + 0x03, 0x20, 0x90, 0x57, 0x00, 0xe0, 0x23, 0x3f, + 0x00, 0x00, 0x25, 0x3f, 0x00, 0x00, 0xf0, 0xb5, + 0x86, 0xb0, 0xd4, 0x48, 0x06, 0x1d, 0x60, 0xce, + 0x00, 0x68, 0x85, 0x42, 0x06, 0xd9, 0x00, 0x20, + 0xfc, 0xf7, 0xb9, 0xfb, 0x06, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xd0, 0x48, 0xce, 0x4b, + 0x01, 0x69, 0xf7, 0x18, 0x7b, 0x1a, 0x01, 0x21, + 0x00, 0x22, 0xc8, 0x2b, 0x00, 0xda, 0x0a, 0x1c, + 0x00, 0x2a, 0x06, 0xd0, 0xc8, 0x48, 0x01, 0x6a, + 0x42, 0x6a, 0x01, 0x20, 0xff, 0xf7, 0xa9, 0xfe, + 0xe8, 0xe7, 0xc6, 0x48, 0x81, 0x68, 0x01, 0x23, + 0x9b, 0x02, 0x99, 0x43, 0x81, 0x60, 0xc4, 0x4c, + 0x38, 0x1c, 0x61, 0x69, 0x01, 0x29, 0x73, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, 0x0a, 0xf0, + 0x04, 0xfd, 0x01, 0x1c, 0xc0, 0x48, 0x81, 0x60, + 0x03, 0x21, 0x01, 0x60, 0xba, 0x48, 0xbe, 0x49, + 0xc2, 0x68, 0x63, 0x69, 0x01, 0x2b, 0x64, 0xd0, + 0x02, 0x2b, 0x06, 0xd1, 0xd2, 0x00, 0x40, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, 0x43, + 0x0a, 0x62, 0xfa, 0x1d, 0x5d, 0x32, 0xff, 0x23, + 0xb7, 0x49, 0x02, 0x33, 0x0b, 0x62, 0xaf, 0x48, + 0x0a, 0x60, 0x82, 0x6b, 0x41, 0x6b, 0xc0, 0x6a, + 0x03, 0x92, 0xed, 0x09, 0x00, 0x64, 0x00, 0x00, + 0x06, 0x00, 0x0e, 0x01, 0x90, 0xab, 0x48, 0x02, + 0x91, 0x82, 0x6a, 0x00, 0x92, 0x00, 0x6a, 0xc3, + 0x68, 0xa8, 0x48, 0xc2, 0x69, 0xa8, 0x1c, 0x05, + 0x90, 0x00, 0x21, 0xfe, 0xf7, 0x36, 0xfe, 0xa4, + 0x49, 0x04, 0x90, 0x0a, 0x69, 0xaa, 0x4b, 0x03, + 0x92, 0x61, 0x69, 0xf0, 0x18, 0x07, 0x1c, 0x01, + 0x29, 0x75, 0xd0, 0x02, 0x29, 0x22, 0xd1, 0x09, + 0x21, 0x0a, 0xf0, 0xb3, 0xfc, 0xc8, 0x22, 0x0a, + 0xf0, 0xba, 0xfc, 0x34, 0x22, 0x0a, 0xf0, 0xb7, + 0xfc, 0x50, 0x22, 0x0a, 0xf0, 0xb4, 0xfc, 0x0d, + 0x22, 0x0a, 0xf0, 0xb1, 0xfc, 0x04, 0x22, 0x0a, + 0xf0, 0xae, 0xfc, 0x28, 0x22, 0x0a, 0xf0, 0xab, + 0xfc, 0x04, 0x99, 0x02, 0x31, 0x09, 0x02, 0x10, + 0x22, 0x0a, 0x43, 0x99, 0x49, 0x0a, 0x62, 0x03, + 0x9a, 0x42, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x11, + 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x96, 0x4a, 0x96, + 0x49, 0x0a, 0x62, 0x08, 0x60, 0x8b, 0x48, 0x41, + 0x6b, 0x82, 0x6b, 0x05, 0x98, 0xfe, 0xf7, 0xaf, + 0xfc, 0x20, 0x23, 0x18, 0x43, 0x92, 0x4a, 0x00, + 0x02, 0x50, 0x60, 0x01, 0xe0, 0xaa, 0xe0, 0xad, + 0xe0, 0x61, 0x69, 0x38, 0x1c, 0x01, 0x29, 0x73, + 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x09, 0x21, 0x0a, + 0xf0, 0x78, 0xfc, 0xc1, 0x1f, 0x8a, 0x4a, 0x21, + 0x39, 0x91, 0x60, 0xb0, 0x30, 0xd0, 0x60, 0x32, + 0x20, 0x0b, 0xf0, 0x11, 0xfa, 0x7b, 0x48, 0x86, + 0x49, 0x02, 0x69, 0x63, 0x69, 0x01, 0x2b, 0x60, + 0xd0, 0x02, 0x2b, 0x05, 0xd1, 0x40, 0x23, 0x1a, + 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, 0x43, 0x0a, + 0x62, 0xf9, 0x1d, 0x49, 0x31, 0xff, 0x23, 0x7f, + 0x4a, 0x02, 0x33, 0x13, 0x62, 0x11, 0x60, 0x63, + 0x69, 0x02, 0x22, 0x01, 0x2b, 0x7d, 0x49, 0x74, + 0xd0, 0x02, 0x2b, 0x03, 0xd1, 0xed, 0x09, 0x00, + 0x65, 0x00, 0x2d, 0x23, 0x0b, 0x62, 0x2c, 0x23, + 0x4b, 0x62, 0x7a, 0x4b, 0x7a, 0x4a, 0xf9, 0x1d, + 0x21, 0x31, 0x13, 0x62, 0x11, 0x60, 0x02, 0x22, + 0x78, 0x48, 0xff, 0x21, 0xc2, 0x63, 0x68, 0x48, + 0x09, 0x31, 0x00, 0xe0, 0x75, 0xe0, 0xc1, 0x60, + 0x81, 0x68, 0xff, 0x23, 0x09, 0x33, 0x19, 0x43, + 0x81, 0x60, 0x69, 0x49, 0x08, 0x6a, 0x49, 0x6a, + 0x00, 0x0a, 0xff, 0x23, 0x1b, 0x02, 0x19, 0x40, + 0x08, 0x43, 0x00, 0x09, 0x80, 0x05, 0x80, 0x0d, + 0x5b, 0x49, 0x80, 0x00, 0x40, 0x18, 0xc1, 0x6b, + 0x01, 0x31, 0xc1, 0x63, 0x58, 0x48, 0x82, 0x6b, + 0x41, 0x6b, 0xc0, 0x6a, 0x03, 0x92, 0x00, 0x06, + 0x00, 0x0e, 0x01, 0x90, 0x54, 0x48, 0x02, 0x91, + 0x82, 0x6a, 0x00, 0x21, 0x00, 0x92, 0x00, 0x6a, + 0xc3, 0x68, 0x51, 0x48, 0xc2, 0x69, 0xe8, 0x1c, + 0xfe, 0xf7, 0x8a, 0xfd, 0x60, 0x4b, 0x05, 0x1c, + 0x4d, 0x49, 0xf0, 0x18, 0x0e, 0x69, 0x61, 0x69, + 0x5e, 0x4c, 0x01, 0x29, 0x63, 0xd0, 0x02, 0x29, + 0x22, 0xd1, 0x09, 0x21, 0x01, 0xe0, 0x5f, 0xe0, + 0x62, 0xe0, 0x0a, 0xf0, 0x05, 0xfc, 0xc8, 0x22, + 0x0a, 0xf0, 0x0c, 0xfc, 0x34, 0x22, 0x0a, 0xf0, + 0x09, 0xfc, 0x50, 0x22, 0x0a, 0xf0, 0x06, 0xfc, + 0x0d, 0x22, 0x0a, 0xf0, 0x03, 0xfc, 0x04, 0x22, + 0x0a, 0xf0, 0x00, 0xfc, 0x28, 0x22, 0x0a, 0xf0, + 0xfd, 0xfb, 0xa9, 0x1c, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0x21, 0x62, 0x42, 0x21, 0x31, 0x43, + 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x61, 0x62, + 0x40, 0x4a, 0x4b, 0x49, 0x0a, 0x62, 0x08, 0x60, + 0x35, 0x48, 0x87, 0x60, 0x41, 0x68, 0x00, 0xe0, + 0x41, 0xe0, 0x02, 0x31, 0x41, 0x60, 0x63, 0x21, + 0x01, 0x63, 0x32, 0x20, 0x0b, 0xf0, 0x7a, 0xf9, + 0xbd, 0xe6, 0x06, 0x21, 0x0a, 0xf0, 0xe6, 0xfb, + 0xed, 0x09, 0x00, 0x66, 0x00, 0xe0, 0xe6, 0xd2, + 0x00, 0x80, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, + 0x23, 0x1a, 0x43, 0x0a, 0x62, 0xec, 0xe6, 0x10, + 0x21, 0x0a, 0xf0, 0xc8, 0xfb, 0xff, 0x22, 0x05, + 0x32, 0x0a, 0xf0, 0xce, 0xfb, 0x46, 0x22, 0x0a, + 0xf0, 0xcb, 0xfb, 0x0d, 0x22, 0x0a, 0xf0, 0xc8, + 0xfb, 0x04, 0x22, 0x0a, 0xf0, 0xc5, 0xfb, 0x28, + 0x22, 0x0a, 0xf0, 0xc2, 0xfb, 0x04, 0x99, 0x02, + 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x25, + 0x49, 0x0a, 0x62, 0x03, 0x9a, 0x82, 0x23, 0x1a, + 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x4a, + 0x62, 0x15, 0xe7, 0x0f, 0xe0, 0x10, 0x21, 0x0a, + 0xf0, 0xa5, 0xfb, 0x2b, 0xe7, 0x80, 0x23, 0x1a, + 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x0a, + 0x62, 0x3b, 0xe7, 0x3d, 0x23, 0x0b, 0x62, 0x3e, + 0x23, 0x4b, 0x62, 0x48, 0xe7, 0x10, 0x21, 0x0a, + 0xf0, 0x95, 0xfb, 0xff, 0x22, 0x05, 0x32, 0x0a, + 0xf0, 0x9b, 0xfb, 0x46, 0x22, 0x0a, 0xf0, 0x98, + 0xfb, 0x0d, 0x22, 0x0a, 0xf0, 0x95, 0xfb, 0x04, + 0x22, 0x0a, 0xf0, 0x92, 0xfb, 0x28, 0x22, 0x0a, + 0xf0, 0x8f, 0xfb, 0xa9, 0x1c, 0x09, 0x02, 0x20, + 0x23, 0x19, 0x43, 0x21, 0x62, 0x82, 0x21, 0x31, + 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x61, + 0x62, 0x90, 0xe7, 0x00, 0x00, 0xd4, 0x03, 0x04, + 0x20, 0x71, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, + 0xe0, 0x48, 0xe6, 0x03, 0x20, 0x00, 0x52, 0x00, + 0xe0, 0xc0, 0x55, 0x00, 0xe0, 0x10, 0x53, 0x00, + 0xe0, 0xe2, 0x04, 0x00, 0x00, 0x80, 0x55, 0x00, + 0xe0, 0x02, 0x05, 0x00, 0x00, 0x00, 0x53, 0x00, + 0xe0, 0x00, 0x51, 0x00, 0xe0, 0xd0, 0x55, 0x00, + 0xe0, 0x14, 0x53, 0x00, 0xe0, 0xa0, 0x55, 0x00, + 0xe0, 0x02, 0x03, 0x00, 0x00, 0x08, 0x53, 0x00, + 0xe0, 0xd4, 0x13, 0xed, 0x09, 0x00, 0x67, 0x00, + 0x04, 0x20, 0x53, 0x07, 0x00, 0x00, 0x90, 0x55, + 0x00, 0xe0, 0x04, 0x53, 0x00, 0xe0, 0xf0, 0xb5, + 0x87, 0xb0, 0xf0, 0x49, 0x0e, 0x1d, 0x60, 0xce, + 0x40, 0x08, 0x08, 0xd3, 0x4a, 0x6a, 0x09, 0x6a, + 0x01, 0x20, 0xff, 0xf7, 0xe8, 0xfc, 0x07, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe9, 0x49, + 0x08, 0x68, 0x85, 0x42, 0x03, 0xd9, 0x00, 0x20, + 0xfc, 0xf7, 0xd7, 0xf9, 0xf3, 0xe7, 0xe7, 0x48, + 0xe6, 0x4b, 0x01, 0x69, 0xf4, 0x18, 0x61, 0x1a, + 0xc8, 0x29, 0x01, 0xda, 0x01, 0x21, 0x00, 0xe0, + 0x00, 0x21, 0x00, 0x29, 0x06, 0xd0, 0xdf, 0x49, + 0x01, 0x20, 0x4a, 0x6a, 0x09, 0x6a, 0xff, 0xf7, + 0xca, 0xfc, 0xe0, 0xe7, 0xde, 0x48, 0x81, 0x68, + 0xff, 0x23, 0x09, 0x33, 0x99, 0x43, 0x81, 0x60, + 0xdc, 0x4f, 0x20, 0x1c, 0x79, 0x69, 0x01, 0x29, + 0x73, 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x09, 0x21, + 0x0a, 0xf0, 0x13, 0xfb, 0xc1, 0x1f, 0xd7, 0x4a, + 0x21, 0x39, 0x91, 0x60, 0xb0, 0x30, 0xd0, 0x60, + 0x32, 0x20, 0x0b, 0xf0, 0xac, 0xf8, 0xcf, 0x48, + 0x82, 0x6b, 0x41, 0x6b, 0x68, 0x1c, 0x06, 0x90, + 0xfe, 0xf7, 0x29, 0xfb, 0x20, 0x23, 0x18, 0x43, + 0xcf, 0x49, 0x00, 0x02, 0x48, 0x60, 0xc9, 0x48, + 0x01, 0x69, 0x7a, 0x69, 0xcd, 0x48, 0x01, 0x2a, + 0x73, 0xd0, 0x02, 0x2a, 0x05, 0xd1, 0x40, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, + 0x01, 0x62, 0xe1, 0x1d, 0x49, 0x31, 0xff, 0x23, + 0xc7, 0x4a, 0x02, 0x33, 0x13, 0x62, 0x11, 0x60, + 0x7a, 0x69, 0xc5, 0x49, 0x01, 0x2a, 0x61, 0xd0, + 0x02, 0x2a, 0x03, 0xd1, 0x2d, 0x22, 0x0a, 0x62, + 0x2c, 0x22, 0x4a, 0x62, 0xe1, 0x1d, 0xc1, 0x4a, + 0xc2, 0x4b, 0x21, 0x31, 0x00, 0x24, 0x1a, 0x62, + 0x19, 0x60, 0xc0, 0x49, 0xcc, 0x63, 0xed, 0x09, + 0x00, 0x68, 0x00, 0x01, 0x68, 0x40, 0x68, 0x09, + 0x0a, 0xff, 0x23, 0x1b, 0x02, 0x18, 0x40, 0x08, + 0x43, 0x00, 0x09, 0x80, 0x05, 0x80, 0x0d, 0xb0, + 0x49, 0x80, 0x00, 0x40, 0x18, 0xc1, 0x6b, 0x01, + 0x31, 0xc1, 0x63, 0xad, 0x48, 0x82, 0x6b, 0x41, + 0x6b, 0xc0, 0x6a, 0x03, 0x92, 0x00, 0x06, 0x00, + 0x0e, 0x01, 0x90, 0xa9, 0x48, 0x02, 0x91, 0x82, + 0x6a, 0x00, 0x92, 0x00, 0x6a, 0xc3, 0x68, 0xa6, + 0x48, 0xc2, 0x69, 0xa8, 0x1c, 0x05, 0x90, 0x00, + 0x21, 0xfe, 0xf7, 0x25, 0xfc, 0x04, 0x90, 0xa2, + 0x48, 0xad, 0x4b, 0xc1, 0x68, 0xf4, 0x18, 0x01, + 0x91, 0x42, 0x69, 0x02, 0x92, 0x81, 0x69, 0x03, + 0x91, 0x78, 0x69, 0x01, 0x28, 0x00, 0xe0, 0xc8, + 0xe0, 0x73, 0xd0, 0x02, 0x28, 0x2f, 0xd1, 0xa6, + 0x49, 0x03, 0x20, 0xc8, 0x62, 0x06, 0x21, 0x20, + 0x1c, 0x0a, 0xf0, 0xab, 0xfa, 0xc8, 0x22, 0x0a, + 0xf0, 0xa0, 0xfa, 0x02, 0x9a, 0x52, 0x00, 0x0a, + 0xf0, 0x9c, 0xfa, 0x28, 0x22, 0x0a, 0xf0, 0x99, + 0xfa, 0x03, 0x22, 0x0a, 0xf0, 0xa6, 0xfa, 0x04, + 0x99, 0x9c, 0x4a, 0x02, 0x31, 0x09, 0x02, 0x10, + 0x23, 0x19, 0x43, 0x11, 0x62, 0x01, 0xe0, 0xac, + 0xe0, 0xb2, 0xe0, 0x01, 0x99, 0xc9, 0x00, 0x44, + 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, + 0x43, 0x51, 0x62, 0x03, 0x99, 0x09, 0x02, 0x16, + 0x23, 0x19, 0x43, 0x91, 0x62, 0x92, 0x49, 0x08, + 0x60, 0x05, 0x20, 0x00, 0x02, 0x08, 0x62, 0x82, + 0x48, 0xc1, 0x68, 0x7a, 0x69, 0x8f, 0x48, 0x01, + 0x2a, 0x73, 0xd0, 0x02, 0x2a, 0x06, 0xd1, 0xc9, + 0x00, 0x40, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, + 0x23, 0x19, 0x43, 0x01, 0x62, 0xe0, 0x1d, 0x5d, + 0x30, 0xff, 0x22, 0x88, 0x49, 0x02, 0x32, 0x0a, + 0x62, 0x08, 0x60, 0x79, 0x69, 0x20, 0x1c, 0x01, + 0x29, 0xed, 0x09, 0x00, 0x69, 0x00, 0x60, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, 0x0a, 0xf0, + 0x63, 0xfa, 0x01, 0x1c, 0x82, 0x48, 0x81, 0x60, + 0x03, 0x21, 0x01, 0x60, 0x01, 0x21, 0x72, 0x48, + 0x89, 0x02, 0xc1, 0x60, 0x81, 0x68, 0x01, 0x23, + 0x9b, 0x02, 0x19, 0x43, 0x81, 0x60, 0x6c, 0x48, + 0x82, 0x6b, 0x41, 0x6b, 0xc0, 0x6a, 0x03, 0x92, + 0x00, 0x06, 0x00, 0x0e, 0x01, 0x90, 0x68, 0x48, + 0x02, 0x91, 0x82, 0x6a, 0x00, 0x21, 0x00, 0x92, + 0x00, 0x6a, 0xc3, 0x68, 0x64, 0x48, 0xc2, 0x69, + 0xe8, 0x1c, 0xfe, 0xf7, 0xa3, 0xfb, 0x00, 0xe0, + 0x62, 0xe0, 0x04, 0x90, 0x71, 0x4b, 0x60, 0x49, + 0xf0, 0x18, 0x4e, 0x69, 0xcd, 0x68, 0x89, 0x69, + 0x03, 0x91, 0x79, 0x69, 0x6e, 0x4f, 0x01, 0x29, + 0x74, 0xd0, 0x02, 0x29, 0x2a, 0xd1, 0x03, 0x21, + 0xf9, 0x62, 0x06, 0x21, 0x0a, 0xf0, 0x2c, 0xfa, + 0xc8, 0x22, 0x0a, 0xf0, 0x21, 0xfa, 0x72, 0x00, + 0x0a, 0xf0, 0x1e, 0xfa, 0x28, 0x22, 0x0a, 0xf0, + 0x1b, 0xfa, 0x03, 0x22, 0x0a, 0xf0, 0x28, 0xfa, + 0x04, 0x99, 0x02, 0x31, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0x39, 0x62, 0xe9, 0x00, 0x44, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, + 0x79, 0x62, 0x03, 0x99, 0x09, 0x02, 0x16, 0x23, + 0x19, 0x43, 0xb9, 0x62, 0x5b, 0x49, 0x08, 0x60, + 0x05, 0x20, 0x00, 0x02, 0x08, 0x62, 0x01, 0xe0, + 0x57, 0xe0, 0x5e, 0xe0, 0x44, 0x4f, 0xf8, 0x6a, + 0x79, 0x6b, 0xba, 0x6b, 0x00, 0x06, 0x00, 0x0e, + 0x01, 0x90, 0x02, 0x91, 0x03, 0x92, 0xba, 0x6a, + 0x10, 0x23, 0x00, 0x92, 0xfa, 0x69, 0x05, 0x98, + 0x06, 0x99, 0xfe, 0xf7, 0x57, 0xfb, 0x38, 0x63, + 0xbc, 0x60, 0x78, 0x68, 0x02, 0x30, 0x78, 0x60, + 0x32, 0x20, 0x0a, 0xf0, 0x7d, 0xff, 0x97, 0xe6, + 0x10, 0x21, 0x0a, 0xf0, 0xed, 0x09, 0x00, 0x6a, + 0x00, 0xd7, 0xf9, 0xc2, 0xe6, 0x80, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, + 0x62, 0xde, 0xe6, 0x3d, 0x22, 0x0a, 0x62, 0x3e, + 0x22, 0x4a, 0x62, 0xea, 0xe6, 0x06, 0x21, 0x20, + 0x1c, 0x0a, 0xf0, 0xd8, 0xf9, 0xff, 0x22, 0x05, + 0x32, 0x0a, 0xf0, 0xcc, 0xf9, 0x02, 0x9a, 0x52, + 0x00, 0x0a, 0xf0, 0xc8, 0xf9, 0x28, 0x22, 0x0a, + 0xf0, 0xc5, 0xf9, 0x03, 0x22, 0x0a, 0xf0, 0xd2, + 0xf9, 0x04, 0x99, 0x02, 0x31, 0x09, 0x02, 0x20, + 0x22, 0x0a, 0x43, 0x30, 0x49, 0x0a, 0x62, 0x01, + 0x9a, 0xd2, 0x00, 0x84, 0x23, 0x1a, 0x43, 0x00, + 0xe0, 0x19, 0xe0, 0x12, 0x02, 0x10, 0x23, 0x1a, + 0x43, 0x4a, 0x62, 0x03, 0x9a, 0x12, 0x02, 0x19, + 0x23, 0x1a, 0x43, 0x8a, 0x62, 0x28, 0x49, 0x08, + 0x60, 0x2e, 0x48, 0x08, 0x62, 0x2c, 0xe7, 0xc9, + 0x00, 0x80, 0x23, 0x19, 0x43, 0x09, 0x02, 0x10, + 0x23, 0x19, 0x43, 0x01, 0x62, 0x33, 0xe7, 0x06, + 0x21, 0x0a, 0xf0, 0xa4, 0xf9, 0x3f, 0xe7, 0x06, + 0x21, 0x0a, 0xf0, 0xa0, 0xf9, 0xff, 0x22, 0x05, + 0x32, 0x0a, 0xf0, 0x94, 0xf9, 0x72, 0x00, 0x0a, + 0xf0, 0x91, 0xf9, 0x28, 0x22, 0x0a, 0xf0, 0x8e, + 0xf9, 0x03, 0x22, 0x0a, 0xf0, 0x9b, 0xf9, 0x04, + 0x99, 0x02, 0x31, 0x09, 0x02, 0x20, 0x23, 0x19, + 0x43, 0x39, 0x62, 0xe9, 0x00, 0x84, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x79, + 0x62, 0x03, 0x99, 0x09, 0x02, 0x19, 0x23, 0x19, + 0x43, 0xb9, 0x62, 0x15, 0x49, 0x08, 0x60, 0x15, + 0x48, 0x08, 0x62, 0x75, 0xe7, 0xd4, 0x03, 0x04, + 0x20, 0x71, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, + 0xe0, 0x48, 0xe6, 0x03, 0x20, 0x00, 0x51, 0x00, + 0xe0, 0xc0, 0x55, 0x00, 0xe0, 0x10, 0x53, 0x00, + 0xe0, 0x80, 0x55, 0x00, 0xe0, 0x02, 0x03, 0xed, + 0x09, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x53, + 0x00, 0xe0, 0xd4, 0x13, 0x04, 0x20, 0xe2, 0x04, + 0x00, 0x00, 0xa0, 0x55, 0x00, 0xe0, 0x08, 0x53, + 0x00, 0xe0, 0xd0, 0x55, 0x00, 0xe0, 0x14, 0x53, + 0x00, 0xe0, 0x00, 0x52, 0x00, 0xe0, 0x53, 0x07, + 0x00, 0x00, 0xb0, 0x55, 0x00, 0xe0, 0x0c, 0x53, + 0x00, 0xe0, 0x03, 0x05, 0x00, 0x00, 0xf0, 0xb5, + 0x07, 0x1c, 0xfa, 0xf7, 0x83, 0xf8, 0x04, 0x1c, + 0x00, 0x28, 0x22, 0x4d, 0x19, 0xd0, 0x00, 0x21, + 0x38, 0x1c, 0xfd, 0xf7, 0x06, 0xfd, 0x07, 0x1c, + 0x10, 0xd0, 0xf8, 0x68, 0x02, 0x28, 0x18, 0xd0, + 0xf8, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xfa, 0xf7, + 0x6c, 0xf8, 0x00, 0x26, 0xbe, 0x61, 0xfe, 0x61, + 0x38, 0x6b, 0x00, 0x28, 0x01, 0xd0, 0xfa, 0xf7, + 0x64, 0xf8, 0x3e, 0x63, 0x20, 0x1c, 0xfa, 0xf7, + 0xa0, 0xf8, 0x29, 0x6a, 0x6a, 0x6a, 0x01, 0x20, + 0xff, 0xf7, 0xbf, 0xfa, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0x23, 0x1b, 0x03, 0xe8, 0x18, + 0xc0, 0x6b, 0x0f, 0x4b, 0x00, 0x01, 0xc1, 0x18, + 0x08, 0x6a, 0x49, 0x6a, 0x00, 0x0a, 0xff, 0x23, + 0x1b, 0x02, 0x19, 0x40, 0x01, 0x43, 0x01, 0x20, + 0x2a, 0x69, 0x00, 0x04, 0x00, 0x2a, 0x00, 0xd1, + 0x00, 0x20, 0x08, 0x43, 0xb8, 0x64, 0x35, 0x20, + 0x20, 0x60, 0x28, 0x6a, 0x40, 0x68, 0xe0, 0x60, + 0x0e, 0x20, 0x21, 0x1c, 0x27, 0x61, 0xfa, 0xf7, + 0xac, 0xf8, 0xd6, 0xe7, 0x00, 0x00, 0xd4, 0x03, + 0x04, 0x20, 0x80, 0x55, 0x00, 0xe0, 0x00, 0xb5, + 0x04, 0x48, 0x01, 0x6a, 0x42, 0x6a, 0x01, 0x20, + 0xff, 0xf7, 0x8f, 0xfa, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xd4, 0x03, 0x04, 0x20, 0xf1, 0xb5, + 0x8c, 0xb0, 0xfa, 0x48, 0x00, 0x21, 0x04, 0x6a, + 0x06, 0x91, 0x0c, 0x99, 0xcb, 0x07, 0xdb, 0x0f, + 0x0f, 0x22, 0xed, 0x09, 0x00, 0x6c, 0x00, 0x17, + 0x21, 0x00, 0x2b, 0x1a, 0xd0, 0xe3, 0x68, 0x9f, + 0x1a, 0x0b, 0x2f, 0x0d, 0xd2, 0x02, 0xa3, 0xdb, + 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x08, + 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, + 0x06, 0x06, 0x00, 0xe1, 0x60, 0x00, 0xe0, 0xe2, + 0x60, 0x42, 0x6a, 0x01, 0x20, 0x21, 0x1c, 0xff, + 0xf7, 0x66, 0xfa, 0x0d, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xff, 0x23, 0x0c, 0x9f, 0x09, + 0x33, 0x3b, 0x40, 0xe6, 0x4f, 0x10, 0x26, 0xfd, + 0x1d, 0xb9, 0x35, 0x00, 0x2b, 0x39, 0xd0, 0x00, + 0x23, 0x05, 0x93, 0xe3, 0x68, 0x10, 0x2b, 0x06, + 0xd0, 0x11, 0x2b, 0x1b, 0xd0, 0x18, 0x2b, 0x02, + 0xd0, 0x19, 0x2b, 0x17, 0xd0, 0xe5, 0xe7, 0xa3, + 0x6c, 0x01, 0x33, 0xa3, 0x64, 0xa3, 0x6c, 0x04, + 0x2b, 0x71, 0xd9, 0xe3, 0x68, 0x10, 0x2b, 0x03, + 0xd1, 0x61, 0x6f, 0x8a, 0x62, 0xe2, 0x60, 0x02, + 0xe0, 0x62, 0x6f, 0x91, 0x62, 0xe1, 0x60, 0x40, + 0x6a, 0x06, 0xf0, 0x29, 0xfb, 0x02, 0x20, 0xfb, + 0xf7, 0x30, 0xff, 0xce, 0xe7, 0xe3, 0x6c, 0x01, + 0x33, 0xe3, 0x64, 0xe3, 0x6c, 0x10, 0x2b, 0x5a, + 0xd9, 0xe3, 0x68, 0x11, 0x2b, 0x03, 0xd1, 0x61, + 0x6f, 0x8a, 0x62, 0xe2, 0x60, 0x02, 0xe0, 0x62, + 0x6f, 0x91, 0x62, 0xe1, 0x60, 0x40, 0x6a, 0x06, + 0xf0, 0x12, 0xfb, 0x02, 0x20, 0xfb, 0xf7, 0x19, + 0xff, 0xb7, 0xe7, 0x0c, 0x99, 0x49, 0x09, 0x52, + 0xd3, 0x01, 0x23, 0x05, 0x93, 0xe2, 0x68, 0x05, + 0x21, 0x0f, 0x2a, 0x06, 0xd0, 0x10, 0x2a, 0x22, + 0xd0, 0x17, 0x2a, 0x02, 0xd0, 0x18, 0x2a, 0x1e, + 0xd0, 0xa7, 0xe7, 0x00, 0x22, 0xa2, 0x64, 0xe2, + 0x64, 0xe2, 0x68, 0x17, 0x2a, 0x04, 0xd1, 0x63, + 0x6f, 0x18, 0x22, 0x9a, 0x62, 0xe2, 0x60, 0x02, + 0xe0, 0x62, 0x6f, 0x96, 0x62, 0xed, 0x09, 0x00, + 0x6d, 0x00, 0xe6, 0x60, 0xaa, 0x6a, 0x00, 0x2a, + 0x00, 0xd1, 0x01, 0x21, 0xb6, 0x4a, 0x11, 0x60, + 0x01, 0x6b, 0x63, 0x29, 0x03, 0xd0, 0x41, 0x68, + 0x01, 0x39, 0x61, 0x64, 0x2c, 0xe0, 0x41, 0x68, + 0x61, 0x64, 0x29, 0xe0, 0x63, 0x6f, 0x11, 0x22, + 0x9a, 0x62, 0xe2, 0x60, 0xaa, 0x6a, 0x00, 0x2a, + 0x00, 0xd1, 0x01, 0x21, 0xad, 0x4a, 0x11, 0x60, + 0x2f, 0x22, 0xad, 0x49, 0x12, 0x01, 0xca, 0x60, + 0x8a, 0x68, 0x17, 0x23, 0x5b, 0x01, 0x1a, 0x43, + 0x8a, 0x60, 0x8a, 0x68, 0x10, 0x23, 0x9a, 0x43, + 0x8a, 0x60, 0xff, 0x37, 0x01, 0x37, 0x39, 0x1c, + 0xa6, 0x4e, 0x00, 0xe0, 0x0c, 0xe0, 0x0c, 0xcf, + 0x0c, 0xc6, 0x0e, 0x1c, 0x0c, 0xce, 0xa4, 0x4f, + 0x0c, 0xc7, 0x48, 0xc9, 0xe7, 0x1d, 0x35, 0x37, + 0x48, 0xc7, 0x01, 0xe0, 0x00, 0x23, 0x05, 0x93, + 0x01, 0x23, 0x1b, 0x03, 0xc1, 0x18, 0x0b, 0x91, + 0xc9, 0x6b, 0x9e, 0x4b, 0x09, 0x01, 0xcb, 0x18, + 0x02, 0x69, 0x19, 0x6a, 0x5f, 0x6a, 0x09, 0x0a, + 0xff, 0x23, 0x1b, 0x02, 0x3b, 0x40, 0x19, 0x43, + 0x01, 0x27, 0x6b, 0x69, 0x3f, 0x04, 0x01, 0x2b, + 0x20, 0xd0, 0x02, 0x2b, 0x06, 0xd1, 0x0a, 0x0c, + 0x00, 0xd2, 0x00, 0x27, 0x39, 0x43, 0x01, 0x23, + 0xdb, 0x03, 0x99, 0x43, 0x41, 0x23, 0x9b, 0x01, + 0xc2, 0x18, 0x0a, 0x92, 0x04, 0x91, 0x11, 0x68, + 0x4a, 0x04, 0x04, 0x99, 0x52, 0x0c, 0x49, 0x04, + 0x49, 0x0c, 0x8a, 0x42, 0x02, 0xd2, 0x04, 0x99, + 0x0a, 0x9a, 0x11, 0x60, 0x82, 0x48, 0x07, 0x6b, + 0x63, 0x2f, 0x08, 0xd0, 0x81, 0x68, 0x09, 0x91, + 0x46, 0x68, 0x36, 0xe0, 0x00, 0x2a, 0x00, 0xd1, + 0x00, 0x27, 0x39, 0x43, 0xe2, 0xe7, 0x7c, 0x4f, + 0x83, 0x4b, 0xb8, 0x68, 0xc0, 0x18, 0x09, 0x90, + 0x78, 0x68, 0xe3, 0x68, 0x86, 0x1c, 0x10, 0x2b, + 0xed, 0x09, 0x00, 0x6e, 0x00, 0x06, 0xd0, 0x11, + 0x2b, 0x15, 0xd0, 0x18, 0x2b, 0x02, 0xd0, 0x19, + 0x2b, 0x11, 0xd0, 0x13, 0xe7, 0xf8, 0x6a, 0x79, + 0x6b, 0xba, 0x6b, 0x00, 0x06, 0x00, 0x0e, 0x01, + 0x90, 0x02, 0x91, 0x03, 0x92, 0xba, 0x6a, 0x30, + 0x1c, 0x00, 0x92, 0xfa, 0x69, 0x61, 0x6c, 0xfe, + 0xf7, 0x39, 0xf9, 0x07, 0x1c, 0x0f, 0xe0, 0x79, + 0x6b, 0xba, 0x6b, 0xaf, 0x6b, 0x03, 0x92, 0x38, + 0x0e, 0x3a, 0x02, 0x12, 0x0a, 0x00, 0x92, 0x02, + 0x91, 0x00, 0x21, 0x00, 0x22, 0x01, 0x90, 0x30, + 0x1c, 0xfe, 0xf7, 0x28, 0xf9, 0x07, 0x1c, 0x09, + 0x98, 0x6a, 0x4b, 0x09, 0x99, 0xc0, 0x18, 0x08, + 0x90, 0xb0, 0x1c, 0x07, 0x90, 0x5f, 0x48, 0xc2, + 0x68, 0x01, 0x92, 0x42, 0x69, 0x02, 0x92, 0x82, + 0x69, 0x03, 0x20, 0x03, 0x92, 0x6a, 0x69, 0x01, + 0x2a, 0x34, 0xd0, 0x02, 0x2a, 0x2b, 0xd1, 0x60, + 0x4a, 0xd0, 0x62, 0x08, 0x1c, 0x06, 0x21, 0x09, + 0xf0, 0xab, 0xff, 0xc8, 0x22, 0x09, 0xf0, 0xa0, + 0xff, 0x02, 0x9a, 0x52, 0x00, 0x09, 0xf0, 0x9c, + 0xff, 0x28, 0x22, 0x09, 0xf0, 0x99, 0xff, 0x03, + 0x22, 0x09, 0xf0, 0xa6, 0xff, 0xb9, 0x1c, 0x09, + 0x02, 0x10, 0x23, 0x55, 0x4a, 0x19, 0x43, 0x11, + 0x62, 0x01, 0x99, 0xc9, 0x00, 0x44, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x51, + 0x62, 0x03, 0x9a, 0x11, 0x02, 0x16, 0x23, 0x4e, + 0x4a, 0x19, 0x43, 0x91, 0x62, 0x4e, 0x49, 0x08, + 0x60, 0x05, 0x20, 0x00, 0x02, 0x08, 0x62, 0x09, + 0x98, 0xa9, 0x6a, 0x00, 0x29, 0x2c, 0xd0, 0x05, + 0x21, 0x03, 0x91, 0x2b, 0xe0, 0x08, 0x1c, 0x06, + 0x21, 0x09, 0xf0, 0x7a, 0xff, 0xff, 0x22, 0x05, + 0x32, 0x09, 0xf0, 0x6e, 0xff, 0x02, 0x9a, 0x52, + 0x00, 0x09, 0xf0, 0x6a, 0xff, 0x28, 0x22, 0x09, + 0xf0, 0x67, 0xff, 0xed, 0x09, 0x00, 0x6f, 0x00, + 0x03, 0x22, 0x09, 0xf0, 0x74, 0xff, 0xb9, 0x1c, + 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x3b, 0x49, + 0x0a, 0x62, 0x01, 0x9a, 0xd2, 0x00, 0x84, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, + 0x4a, 0x62, 0x03, 0x9a, 0x12, 0x02, 0x19, 0x23, + 0x1a, 0x43, 0x8a, 0x62, 0x36, 0x49, 0x08, 0x60, + 0x36, 0x48, 0x08, 0x62, 0xce, 0xe7, 0x01, 0x21, + 0x03, 0x91, 0x69, 0x69, 0x01, 0x29, 0x14, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, 0x09, 0xf0, + 0x4a, 0xff, 0x01, 0x1c, 0x27, 0x48, 0x81, 0x60, + 0x00, 0x21, 0x03, 0x99, 0x01, 0x60, 0xe0, 0x68, + 0x10, 0x28, 0x0e, 0xd0, 0x11, 0x28, 0x25, 0xd0, + 0x18, 0x28, 0x0a, 0xd0, 0x19, 0x28, 0x21, 0xd0, + 0x67, 0xe6, 0x06, 0x21, 0x09, 0xf0, 0x37, 0xff, + 0x01, 0xaa, 0x03, 0xc2, 0x01, 0x98, 0x02, 0x99, + 0xe7, 0xe7, 0x19, 0x49, 0x30, 0x1c, 0x4a, 0x6b, + 0x61, 0x6c, 0xfd, 0xf7, 0x87, 0xff, 0x16, 0x49, + 0x20, 0x23, 0x18, 0x43, 0xc9, 0x6a, 0x00, 0x02, + 0x08, 0x43, 0x15, 0x49, 0x48, 0x60, 0xb1, 0x08, + 0xe0, 0x1d, 0xb9, 0x30, 0x81, 0x62, 0x00, 0x21, + 0xe2, 0x1d, 0xf9, 0x32, 0x91, 0x61, 0xfd, 0xf7, + 0x80, 0xfc, 0x30, 0xe0, 0xa8, 0x6b, 0x00, 0x0e, + 0x71, 0x08, 0x09, 0x02, 0x08, 0x43, 0x0c, 0x49, + 0x48, 0x60, 0xa8, 0x6b, 0x07, 0x99, 0x00, 0x0e, + 0x49, 0x08, 0x09, 0x02, 0x08, 0x43, 0x09, 0x49, + 0x48, 0x60, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, + 0x00, 0x21, 0x81, 0x63, 0xe0, 0x1d, 0xff, 0x30, + 0x1a, 0x30, 0xfd, 0xf7, 0x66, 0xfc, 0x16, 0xe0, + 0x00, 0x00, 0xd4, 0x03, 0x04, 0x20, 0x88, 0xe5, + 0x03, 0x20, 0x00, 0x52, 0x00, 0xe0, 0x00, 0x51, + 0x00, 0xe0, 0x00, 0x50, 0x00, 0xe0, 0x90, 0x57, + 0x00, 0xe0, 0x20, 0x51, 0x00, 0xe0, 0xed, 0x09, + 0x00, 0x70, 0x00, 0x80, 0x55, 0x00, 0xe0, 0xe2, + 0x04, 0x00, 0x00, 0x00, 0x53, 0x00, 0xe0, 0x03, + 0x05, 0x00, 0x00, 0x94, 0x4e, 0x09, 0x98, 0xf2, + 0x68, 0x6b, 0x69, 0x93, 0x49, 0x01, 0x2b, 0x73, + 0xd0, 0x02, 0x2b, 0x06, 0xd1, 0xd2, 0x00, 0x40, + 0x23, 0x1a, 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, + 0x43, 0x0a, 0x62, 0xff, 0x22, 0x64, 0x30, 0x8d, + 0x49, 0x02, 0x32, 0x0a, 0x62, 0x08, 0x60, 0x05, + 0x98, 0x01, 0x28, 0x0e, 0xd1, 0x00, 0x21, 0x0c, + 0x98, 0xfd, 0xf7, 0x8b, 0xfa, 0xe1, 0x1d, 0x65, + 0x31, 0x06, 0x90, 0x0c, 0xc9, 0x0c, 0xc0, 0x06, + 0x98, 0x04, 0x99, 0x81, 0x64, 0x0a, 0x9a, 0x00, + 0x21, 0x11, 0x60, 0xe0, 0x68, 0x10, 0x28, 0x73, + 0xd0, 0x11, 0x28, 0x03, 0xd0, 0x18, 0x28, 0x6f, + 0xd0, 0x19, 0x28, 0x11, 0xd1, 0x71, 0x6b, 0xb2, + 0x6b, 0xab, 0x6b, 0x03, 0x92, 0x18, 0x0e, 0x1a, + 0x02, 0x12, 0x0a, 0x00, 0x92, 0x01, 0x90, 0x02, + 0x91, 0x30, 0x6a, 0xf2, 0x69, 0xc3, 0x68, 0x61, + 0x6c, 0x07, 0x98, 0xfe, 0xf7, 0x08, 0xf8, 0x07, + 0x1c, 0x08, 0x98, 0x34, 0x69, 0x69, 0x69, 0x01, + 0x29, 0x73, 0xd0, 0x02, 0x29, 0x20, 0xd1, 0x09, + 0x21, 0x09, 0xf0, 0x89, 0xfe, 0xc8, 0x22, 0x09, + 0xf0, 0x90, 0xfe, 0x34, 0x22, 0x09, 0xf0, 0x8d, + 0xfe, 0x50, 0x22, 0x09, 0xf0, 0x8a, 0xfe, 0x0d, + 0x22, 0x09, 0xf0, 0x87, 0xfe, 0x04, 0x22, 0x09, + 0xf0, 0x84, 0xfe, 0x28, 0x22, 0x09, 0xf0, 0x81, + 0xfe, 0xb9, 0x1c, 0x09, 0x02, 0x10, 0x22, 0x0a, + 0x43, 0x66, 0x49, 0x0a, 0x62, 0x42, 0x22, 0x22, + 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, 0x43, 0x4a, + 0x62, 0x63, 0x4a, 0x63, 0x49, 0x0a, 0x62, 0x08, + 0x60, 0x08, 0x98, 0x32, 0x69, 0x6b, 0x69, 0x61, + 0x49, 0x01, 0x2b, 0x60, 0xd0, 0x02, 0x2b, 0x07, + 0xd1, 0xed, 0x09, 0x00, 0x71, 0x00, 0x40, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x00, 0xe0, 0x5a, 0xe0, + 0x11, 0x23, 0x1a, 0x43, 0x0a, 0x62, 0xff, 0x22, + 0x50, 0x30, 0x5b, 0x49, 0x02, 0x32, 0x0a, 0x62, + 0x08, 0x60, 0x08, 0x9a, 0x69, 0x69, 0x59, 0x48, + 0x01, 0x29, 0x67, 0xd0, 0x02, 0x29, 0x03, 0xd1, + 0x2d, 0x21, 0x01, 0x62, 0x2c, 0x21, 0x41, 0x62, + 0xd0, 0x1d, 0x56, 0x4a, 0x54, 0x49, 0x21, 0x30, + 0x04, 0x23, 0x11, 0x62, 0x10, 0x60, 0x0b, 0x99, + 0xcb, 0x63, 0x08, 0x98, 0x69, 0x69, 0x01, 0x29, + 0x74, 0xd0, 0x02, 0x29, 0x00, 0xe0, 0x3e, 0xe0, + 0x02, 0xd1, 0x09, 0x21, 0x09, 0xf0, 0x32, 0xfe, + 0xc1, 0x1f, 0x4d, 0x4a, 0x21, 0x39, 0x91, 0x60, + 0xb0, 0x30, 0xd0, 0x60, 0x32, 0x20, 0x0a, 0xf0, + 0xcb, 0xfb, 0xa1, 0x20, 0x49, 0x49, 0xc0, 0x00, + 0xc8, 0x60, 0x88, 0x68, 0x01, 0x23, 0x9b, 0x02, + 0x98, 0x43, 0x88, 0x60, 0x88, 0x68, 0xff, 0x23, + 0x09, 0x33, 0x18, 0x43, 0x88, 0x60, 0x00, 0xe0, + 0x35, 0xe0, 0x63, 0x20, 0x30, 0x63, 0x08, 0x98, + 0xb0, 0x60, 0x07, 0x98, 0x70, 0x60, 0x06, 0x98, + 0x00, 0x28, 0x61, 0xd0, 0xf9, 0xf7, 0x55, 0xfd, + 0x00, 0x28, 0x5a, 0xd0, 0x35, 0x21, 0x01, 0x60, + 0x31, 0x6a, 0x49, 0x68, 0xc1, 0x60, 0x06, 0x99, + 0x01, 0x61, 0x01, 0x1c, 0x0e, 0x20, 0xf9, 0xf7, + 0xb7, 0xfd, 0x51, 0xe0, 0x3d, 0xe0, 0xd2, 0x00, + 0x80, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, + 0x1a, 0x43, 0x0a, 0x62, 0x30, 0xe7, 0xf0, 0x6a, + 0x71, 0x6b, 0xb2, 0x6b, 0x00, 0x06, 0x00, 0x0e, + 0x01, 0x90, 0x02, 0x91, 0x03, 0x92, 0xb2, 0x6a, + 0x00, 0x92, 0x30, 0x6a, 0xf2, 0x69, 0xc3, 0x68, + 0x61, 0x6c, 0x07, 0x98, 0xfd, 0xf7, 0x5a, 0xff, + 0x07, 0x1c, 0x50, 0xe7, 0x28, 0xe0, 0x10, 0x21, + 0x09, 0xf0, 0xe0, 0xfd, 0xed, 0x09, 0x00, 0x72, + 0x00, 0xff, 0x22, 0x05, 0x32, 0x09, 0xf0, 0xe6, + 0xfd, 0x46, 0x22, 0x09, 0xf0, 0xe3, 0xfd, 0x0d, + 0x22, 0x09, 0xf0, 0xe0, 0xfd, 0x04, 0x22, 0x09, + 0xf0, 0xdd, 0xfd, 0x28, 0x22, 0x09, 0xf0, 0xda, + 0xfd, 0xb9, 0x1c, 0x09, 0x02, 0x20, 0x22, 0x0a, + 0x43, 0x12, 0x49, 0x0a, 0x62, 0x82, 0x22, 0x22, + 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x00, + 0xe0, 0x0d, 0xe0, 0x4a, 0x62, 0x55, 0xe7, 0x80, + 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, + 0x43, 0x0a, 0x62, 0x62, 0xe7, 0x3d, 0x21, 0x01, + 0x62, 0x3e, 0x21, 0x41, 0x62, 0x6e, 0xe7, 0x10, + 0x21, 0x09, 0xf0, 0xb2, 0xfd, 0x7e, 0xe7, 0x06, + 0x98, 0xf9, 0xf7, 0x56, 0xfd, 0xec, 0xe4, 0x00, + 0x00, 0xd4, 0x03, 0x04, 0x20, 0x90, 0x55, 0x00, + 0xe0, 0x04, 0x53, 0x00, 0xe0, 0xa0, 0x55, 0x00, + 0xe0, 0x02, 0x05, 0x00, 0x00, 0x08, 0x53, 0x00, + 0xe0, 0xb0, 0x55, 0x00, 0xe0, 0x0c, 0x53, 0x00, + 0xe0, 0xc0, 0x55, 0x00, 0xe0, 0x02, 0x03, 0x00, + 0x00, 0x10, 0x53, 0x00, 0xe0, 0x00, 0x51, 0x00, + 0xe0, 0x00, 0x50, 0x00, 0xe0, 0xf0, 0xb5, 0x84, + 0xb0, 0x2a, 0x4e, 0x04, 0x1c, 0x75, 0x6a, 0xf9, + 0xf7, 0xd2, 0xfc, 0x07, 0x1c, 0x06, 0xd1, 0x08, + 0x20, 0xff, 0xf7, 0xa2, 0xfc, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0x20, + 0x1c, 0xfd, 0xf7, 0x50, 0xf9, 0x04, 0x1c, 0x06, + 0xd1, 0x38, 0x1c, 0xf9, 0xf7, 0xfb, 0xfc, 0x08, + 0x20, 0xff, 0xf7, 0x92, 0xfc, 0xee, 0xe7, 0xe9, + 0x1d, 0x30, 0x69, 0xb9, 0x31, 0x88, 0x60, 0xf0, + 0x68, 0x05, 0x22, 0xc8, 0x60, 0x70, 0x69, 0x08, + 0x61, 0x19, 0x48, 0x40, 0x68, 0x88, 0x61, 0x00, + 0x20, 0x48, 0x62, 0xea, 0x60, 0xe8, 0x64, 0x28, + 0x65, 0x68, 0x65, 0xa8, 0x65, 0xe8, 0x65, 0xed, + 0x09, 0x00, 0x73, 0x00, 0x28, 0x66, 0xa8, 0x66, + 0x68, 0x67, 0xea, 0x1d, 0x79, 0x32, 0xa8, 0x67, + 0x50, 0x60, 0xd0, 0x60, 0x28, 0x64, 0x68, 0x64, + 0x88, 0x63, 0x28, 0x1c, 0x05, 0xf0, 0x10, 0xfd, + 0x35, 0x20, 0x38, 0x60, 0x30, 0x6a, 0x40, 0x68, + 0xf8, 0x60, 0x0e, 0x20, 0x39, 0x1c, 0x3c, 0x61, + 0xf9, 0xf7, 0xff, 0xfc, 0x00, 0x22, 0x03, 0x92, + 0x02, 0x22, 0x01, 0x21, 0x1a, 0x20, 0x01, 0x90, + 0x02, 0x91, 0x00, 0x92, 0x30, 0x6a, 0x04, 0x23, + 0x01, 0x1c, 0x2a, 0x1c, 0xfb, 0xf7, 0x51, 0xfa, + 0xb3, 0xe7, 0xd4, 0x03, 0x04, 0x20, 0x88, 0xe5, + 0x03, 0x20, 0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, + 0x0f, 0x1c, 0x2e, 0xf0, 0xd2, 0xfa, 0x39, 0x4e, + 0x3a, 0x4d, 0x37, 0x61, 0xe0, 0x68, 0x05, 0x28, + 0x08, 0xd0, 0x03, 0x28, 0x06, 0xd0, 0x20, 0x1c, + 0x00, 0xf0, 0xd7, 0xf8, 0x70, 0x61, 0xa9, 0x69, + 0x48, 0x62, 0x00, 0xe0, 0x74, 0x61, 0xe0, 0x1d, + 0xf9, 0x30, 0x00, 0x21, 0x30, 0x4e, 0x01, 0x63, + 0x70, 0x69, 0xb0, 0x61, 0x38, 0x1c, 0xfc, 0xf7, + 0xd0, 0xff, 0x2d, 0x23, 0x9b, 0x01, 0xf9, 0x18, + 0x88, 0x60, 0x00, 0x2c, 0x04, 0xd0, 0x60, 0x6f, + 0x00, 0x28, 0x01, 0xd0, 0x00, 0x21, 0x81, 0x65, + 0xe8, 0x1d, 0xb9, 0x30, 0x42, 0x69, 0xe0, 0x1d, + 0xb9, 0x30, 0x01, 0x2a, 0x26, 0x49, 0x43, 0xd0, + 0x02, 0x2a, 0x01, 0xd1, 0x01, 0x22, 0xca, 0x60, + 0xfd, 0x1d, 0x51, 0x35, 0x29, 0x1c, 0x0c, 0xcd, + 0x22, 0x4e, 0x22, 0x4d, 0x0c, 0xc6, 0x48, 0xc9, + 0x48, 0xc5, 0x80, 0x6b, 0x00, 0x28, 0x0a, 0xd0, + 0xe1, 0x1d, 0xe1, 0x31, 0x6c, 0xc9, 0x1e, 0x48, + 0x6c, 0xc0, 0x61, 0x68, 0x1e, 0x48, 0xff, 0x31, + 0x89, 0x31, 0x60, 0xc9, 0x60, 0xc0, 0x6a, 0x46, + 0x00, 0x21, 0x01, 0x20, 0x3b, 0x1c, 0xfc, 0xf7, + 0xfa, 0xfe, 0xed, 0x09, 0x00, 0x74, 0x00, 0x05, + 0x1c, 0x01, 0x99, 0x00, 0x9c, 0x78, 0x6d, 0x17, + 0x4a, 0x10, 0x4f, 0x42, 0x43, 0xfe, 0x1d, 0x01, + 0x36, 0x00, 0x23, 0xa0, 0x18, 0x59, 0x41, 0x03, + 0xc6, 0x7c, 0x60, 0x13, 0x48, 0x3d, 0x60, 0x01, + 0x22, 0x02, 0x60, 0x13, 0x48, 0x12, 0x49, 0xc1, + 0x60, 0x81, 0x68, 0xfb, 0x23, 0x9b, 0x00, 0x19, + 0x43, 0x81, 0x60, 0x80, 0x04, 0x00, 0xf0, 0xb7, + 0xf8, 0x2e, 0xf0, 0x61, 0xfa, 0x02, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x02, 0x69, 0xca, + 0x60, 0xbc, 0xe7, 0x68, 0x14, 0x04, 0x20, 0x88, + 0xe5, 0x03, 0x20, 0x00, 0x52, 0x00, 0xe0, 0x20, + 0x51, 0x00, 0xe0, 0x90, 0x57, 0x00, 0xe0, 0xa0, + 0x57, 0x00, 0xe0, 0xb0, 0x57, 0x00, 0xe0, 0x71, + 0x02, 0x00, 0x00, 0x24, 0x7e, 0x03, 0x20, 0xfc, + 0x07, 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, 0x80, + 0xb4, 0x09, 0x49, 0x49, 0x69, 0x81, 0x42, 0x0c, + 0xd1, 0xc7, 0x1d, 0xe1, 0x37, 0x0c, 0xcf, 0x06, + 0x49, 0x0c, 0xc1, 0x0c, 0xcf, 0x0c, 0xc1, 0x40, + 0x68, 0x05, 0x49, 0xff, 0x30, 0x89, 0x30, 0x88, + 0xc8, 0x88, 0xc1, 0x80, 0xbc, 0x70, 0x47, 0x68, + 0x14, 0x04, 0x20, 0xa0, 0x57, 0x00, 0xe0, 0xb0, + 0x57, 0x00, 0xe0, 0x00, 0xb5, 0x2e, 0xf0, 0x2b, + 0xfa, 0x13, 0x49, 0x00, 0x20, 0x08, 0x60, 0x12, + 0x49, 0x8a, 0x68, 0x12, 0x4b, 0x1a, 0x40, 0x8a, + 0x60, 0xda, 0x43, 0xca, 0x60, 0x11, 0x49, 0x08, + 0x60, 0x11, 0x49, 0x08, 0x60, 0x11, 0x49, 0x08, + 0x62, 0x48, 0x62, 0x88, 0x62, 0xc8, 0x62, 0x08, + 0x63, 0x48, 0x63, 0x0e, 0x48, 0x41, 0x69, 0x0e, + 0x48, 0x01, 0x29, 0x09, 0xd0, 0x02, 0x29, 0x01, + 0xd1, 0x0d, 0x49, 0x01, 0x62, 0x01, 0x21, 0x41, + 0x60, 0x2e, 0xf0, 0x05, 0xfa, 0x08, 0xbc, 0x18, + 0x47, 0x0a, 0x49, 0x01, 0x62, 0xed, 0x09, 0x00, + 0x75, 0x00, 0xf6, 0xe7, 0x24, 0x7e, 0x03, 0x20, + 0x00, 0x50, 0x00, 0xe0, 0x03, 0xf8, 0xff, 0xff, + 0x00, 0x51, 0x00, 0xe0, 0x00, 0x52, 0x00, 0xe0, + 0x00, 0x53, 0x00, 0xe0, 0x48, 0xe6, 0x03, 0x20, + 0x40, 0x53, 0x00, 0xe0, 0x11, 0x40, 0x00, 0x00, + 0x10, 0x80, 0x00, 0x00, 0xf8, 0xb5, 0x07, 0x1c, + 0x40, 0x68, 0x1d, 0x4b, 0x00, 0x25, 0xc6, 0x18, + 0xff, 0x30, 0xff, 0x30, 0xce, 0x30, 0x00, 0x90, + 0xff, 0x37, 0x35, 0x37, 0xb7, 0x42, 0x00, 0xd3, + 0x00, 0x9f, 0xf8, 0x68, 0x05, 0x28, 0x08, 0xd1, + 0x78, 0x6f, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x21, + 0x81, 0x65, 0x38, 0x1c, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x03, 0x28, 0x1a, 0xd1, 0xf9, 0xf7, + 0x76, 0xfb, 0x04, 0x1c, 0x16, 0xd0, 0x01, 0x20, + 0x39, 0x1c, 0x05, 0xf0, 0x33, 0xfc, 0x38, 0x1c, + 0x05, 0xf0, 0xd8, 0xfb, 0x04, 0x20, 0xf8, 0x60, + 0x02, 0x21, 0x38, 0x1c, 0xfb, 0xf7, 0xf8, 0xf8, + 0x3b, 0x20, 0x20, 0x60, 0xb8, 0x68, 0xe0, 0x60, + 0x00, 0x20, 0x20, 0x61, 0x0e, 0x20, 0x21, 0x1c, + 0xf9, 0xf7, 0xcc, 0xfb, 0x01, 0x35, 0x08, 0x2d, + 0xce, 0xd3, 0x00, 0x20, 0xda, 0xe7, 0x00, 0x00, + 0x38, 0x0b, 0x00, 0x00, 0xf1, 0xb5, 0x92, 0xb0, + 0xf9, 0x4a, 0xfa, 0x4b, 0x10, 0x68, 0x01, 0x1d, + 0x50, 0x68, 0xc4, 0x18, 0x5b, 0x08, 0xe3, 0x1a, + 0x08, 0x93, 0x00, 0x23, 0x57, 0x69, 0x06, 0x93, + 0x05, 0x93, 0x01, 0x23, 0x0e, 0x01, 0x36, 0x09, + 0x88, 0x1e, 0x00, 0x01, 0x04, 0x93, 0xd7, 0x61, + 0x00, 0x09, 0x09, 0x90, 0xf8, 0x68, 0x03, 0x28, + 0x31, 0xd1, 0x3d, 0x1c, 0xf9, 0xf7, 0x37, 0xfb, + 0x03, 0x90, 0x00, 0x28, 0x28, 0xd0, 0x01, 0x20, + 0x29, 0x1c, 0x05, 0xf0, 0xf3, 0xfb, 0x28, 0x1c, + 0x05, 0xf0, 0x98, 0xfb, 0x04, 0x20, 0xe8, 0x60, + 0xed, 0x09, 0x00, 0x76, 0x00, 0x03, 0x99, 0x3b, + 0x20, 0x08, 0x60, 0xa8, 0x68, 0x03, 0x99, 0xc8, + 0x60, 0x03, 0x99, 0x00, 0x20, 0x08, 0x61, 0x03, + 0x99, 0x0e, 0x20, 0xf9, 0xf7, 0x8d, 0xfb, 0x28, + 0x1c, 0xff, 0xf7, 0x86, 0xff, 0x07, 0x1c, 0x09, + 0xd1, 0x01, 0x23, 0x02, 0x22, 0x00, 0x21, 0x68, + 0x68, 0xfb, 0xf7, 0xda, 0xf9, 0x13, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x02, 0x21, 0x28, + 0x1c, 0xfb, 0xf7, 0x9c, 0xf8, 0xd5, 0x4a, 0x00, + 0x20, 0xd0, 0x61, 0xfd, 0x1d, 0x79, 0x35, 0x69, + 0x69, 0x01, 0x29, 0x4d, 0xd1, 0x28, 0x6b, 0xb0, + 0x42, 0x4a, 0xd2, 0x74, 0x30, 0xb0, 0x42, 0x22, + 0xd9, 0x78, 0x6f, 0x00, 0x28, 0x06, 0xd0, 0xc0, + 0x68, 0x02, 0x28, 0x03, 0xd0, 0x01, 0x28, 0x01, + 0xd0, 0x00, 0x28, 0x0e, 0xd1, 0xf8, 0x1d, 0x45, + 0x30, 0x05, 0xf0, 0x83, 0xf9, 0x00, 0x28, 0x08, + 0xd1, 0xf8, 0x1d, 0x4d, 0x30, 0x05, 0xf0, 0x7d, + 0xf9, 0x00, 0x28, 0x02, 0xd1, 0x07, 0xf0, 0x4c, + 0xf8, 0xd0, 0xe7, 0xf8, 0x1d, 0x45, 0x30, 0x05, + 0xf0, 0x74, 0xf9, 0x00, 0x28, 0x03, 0xd1, 0xf8, + 0x1d, 0x4d, 0x30, 0x05, 0xf0, 0x6e, 0xf9, 0xf9, + 0xf7, 0xd8, 0xfa, 0x00, 0x28, 0x0f, 0xd0, 0x41, + 0x21, 0x01, 0x60, 0x79, 0x68, 0x81, 0x61, 0x47, + 0x61, 0x79, 0x68, 0x49, 0x68, 0x01, 0x61, 0x39, + 0x7e, 0xc1, 0x60, 0x08, 0x21, 0xc1, 0x61, 0x01, + 0x1c, 0x0e, 0x20, 0xf9, 0xf7, 0x35, 0xfb, 0x00, + 0x20, 0x68, 0x61, 0xa8, 0x69, 0x00, 0x28, 0x08, + 0xd0, 0x79, 0x68, 0x40, 0x68, 0x81, 0x42, 0x04, + 0xd0, 0x01, 0x23, 0x01, 0x22, 0x00, 0x21, 0xfb, + 0xf7, 0x7f, 0xf9, 0x00, 0x20, 0xa8, 0x61, 0x0f, + 0xe0, 0x04, 0x29, 0x0d, 0xd1, 0x28, 0x6b, 0x01, + 0x38, 0x28, 0x63, 0x09, 0xd1, 0x38, 0x1c, 0x06, + 0xf0, 0x6b, 0xfe, 0xed, 0x09, 0x00, 0x77, 0x00, + 0x00, 0x28, 0x00, 0xd0, 0x95, 0xe7, 0xa4, 0x4a, + 0x00, 0x20, 0x57, 0x69, 0xd0, 0x61, 0xa4, 0x4d, + 0xe8, 0x1d, 0xff, 0x30, 0xe2, 0x30, 0x11, 0x90, + 0xa8, 0x42, 0x20, 0xd9, 0x09, 0x98, 0x04, 0x38, + 0x10, 0x90, 0x28, 0x68, 0x0f, 0x90, 0x00, 0x28, + 0x15, 0xd0, 0x10, 0x98, 0x29, 0x6a, 0x41, 0x1a, + 0x68, 0x6a, 0x0e, 0x90, 0xf8, 0xf7, 0x0d, 0xfe, + 0x04, 0x91, 0x00, 0x29, 0x04, 0xd1, 0x0f, 0x98, + 0x96, 0x49, 0x05, 0x90, 0xc8, 0x61, 0x06, 0xe0, + 0x0e, 0x98, 0x04, 0x99, 0x04, 0x38, 0x88, 0x42, + 0x01, 0xd1, 0x0f, 0x98, 0x06, 0x90, 0x11, 0x98, + 0xf4, 0x35, 0xa8, 0x42, 0xe1, 0xd8, 0x12, 0x98, + 0x00, 0x28, 0x71, 0xd0, 0x12, 0x98, 0x80, 0x0f, + 0x0a, 0xd2, 0x78, 0x6e, 0x40, 0x08, 0x03, 0xd3, + 0x01, 0x21, 0x38, 0x1c, 0x05, 0xf0, 0x1f, 0xfb, + 0x05, 0x98, 0x00, 0x28, 0x00, 0xd1, 0x38, 0x66, + 0x12, 0x98, 0x40, 0x0a, 0x08, 0xd3, 0xf8, 0x1d, + 0xf9, 0x30, 0x41, 0x68, 0x01, 0x31, 0x41, 0x60, + 0x01, 0x69, 0x01, 0x31, 0x01, 0x61, 0x08, 0xe0, + 0x12, 0x98, 0x40, 0x08, 0x05, 0xd3, 0x01, 0x20, + 0x3a, 0x1c, 0x79, 0x68, 0xff, 0xf7, 0xdb, 0xfd, + 0x43, 0xe7, 0xf8, 0x1d, 0x79, 0x30, 0x40, 0x69, + 0x04, 0x28, 0x2e, 0xd0, 0x12, 0x98, 0xc0, 0x0f, + 0x2b, 0xd2, 0x05, 0x98, 0x00, 0x28, 0x28, 0xd1, + 0xf8, 0x1d, 0x45, 0x30, 0x05, 0xf0, 0xdc, 0xf8, + 0x00, 0x28, 0x09, 0xd1, 0xf8, 0x1d, 0x4d, 0x30, + 0x05, 0xf0, 0xd6, 0xf8, 0x00, 0x28, 0x03, 0xd1, + 0x78, 0x6f, 0xf9, 0x6f, 0x88, 0x42, 0x06, 0xd0, + 0xf8, 0x1d, 0xf9, 0x30, 0x02, 0x6b, 0x51, 0x1c, + 0x01, 0x63, 0x10, 0x2a, 0x11, 0xd3, 0xf9, 0x1d, + 0xf9, 0x31, 0x00, 0x20, 0x08, 0x63, 0x38, 0x1c, + 0xff, 0xf7, 0x99, 0xfe, 0x07, 0x1c, 0xed, 0x09, + 0x00, 0x78, 0x00, 0x06, 0xd1, 0x69, 0xa0, 0x0d, + 0xf0, 0x1c, 0xfc, 0x02, 0x20, 0xfb, 0xf7, 0x7f, + 0xf9, 0x11, 0xe7, 0x62, 0x4a, 0x57, 0x61, 0x78, + 0x68, 0xc1, 0x1d, 0xff, 0x31, 0x7a, 0x31, 0x09, + 0x69, 0x89, 0x07, 0x38, 0xd1, 0xf9, 0x1d, 0x79, + 0x31, 0x49, 0x69, 0x00, 0x29, 0x33, 0xd1, 0x2d, + 0x23, 0x9b, 0x01, 0xc1, 0x18, 0x0a, 0x68, 0x00, + 0x2a, 0x0f, 0xd0, 0x89, 0x68, 0x00, 0x29, 0x06, + 0xd0, 0x62, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, + 0x39, 0x01, 0x60, 0x24, 0xe0, 0x2a, 0xe0, 0x03, + 0x20, 0xfb, 0xf7, 0x5d, 0xf9, 0x00, 0x28, 0x1e, + 0xd0, 0xed, 0xe6, 0xfc, 0xf7, 0x1c, 0xfc, 0x5b, + 0x4d, 0x0c, 0xcd, 0x08, 0x3d, 0x09, 0xf0, 0x91, + 0xfa, 0x00, 0x28, 0x14, 0xd0, 0x78, 0x68, 0xfa, + 0xf7, 0x6e, 0xfe, 0x00, 0x28, 0x05, 0xd0, 0x00, + 0x20, 0xfb, 0xf7, 0x49, 0xf9, 0x00, 0x28, 0x0a, + 0xd0, 0xd9, 0xe6, 0x78, 0x68, 0x53, 0x4a, 0x40, + 0x6d, 0x00, 0x23, 0x42, 0x43, 0x03, 0xcd, 0x08, + 0x3d, 0x80, 0x18, 0x59, 0x41, 0x03, 0xc5, 0x05, + 0x98, 0x00, 0x28, 0x23, 0xd0, 0x05, 0x98, 0xfd, + 0xf7, 0x46, 0xff, 0x1f, 0xe0, 0x05, 0x98, 0x00, + 0x28, 0x1c, 0xd1, 0xf8, 0x1d, 0xf9, 0x30, 0x01, + 0x6b, 0x10, 0x29, 0x02, 0xd2, 0x01, 0x31, 0x01, + 0x63, 0x14, 0xe0, 0xf9, 0x1d, 0x79, 0x31, 0x49, + 0x69, 0x04, 0x29, 0x0f, 0xd0, 0x00, 0x21, 0x01, + 0x63, 0x38, 0x1c, 0xff, 0xf7, 0x32, 0xfe, 0x07, + 0x1c, 0x06, 0xd1, 0x35, 0xa0, 0x0d, 0xf0, 0xb5, + 0xfb, 0x02, 0x20, 0xfb, 0xf7, 0x18, 0xf9, 0xaa, + 0xe6, 0x2f, 0x4a, 0x57, 0x61, 0x3c, 0x49, 0x08, + 0x98, 0x09, 0x69, 0xff, 0x22, 0x91, 0x32, 0xfd, + 0xf7, 0xd6, 0xf9, 0x00, 0x28, 0x05, 0xd1, 0x01, + 0x20, 0x3a, 0x1c, 0x79, 0x68, 0xff, 0xf7, 0x31, + 0xfd, 0xed, 0x09, 0x00, 0x79, 0x00, 0x99, 0xe6, + 0x06, 0x98, 0x00, 0x28, 0x00, 0xd0, 0x06, 0x9f, + 0x24, 0x48, 0x87, 0x61, 0x78, 0x68, 0xc1, 0x1d, + 0x79, 0x31, 0xca, 0x69, 0xff, 0x30, 0x81, 0x30, + 0xb9, 0x6a, 0x83, 0x68, 0x03, 0x92, 0x18, 0x0e, + 0x1a, 0x02, 0x12, 0x0a, 0x00, 0x92, 0x00, 0x22, + 0x1a, 0x23, 0x01, 0x90, 0x02, 0x91, 0x00, 0x21, + 0x09, 0x98, 0xfd, 0xf7, 0xbf, 0xfb, 0xf9, 0x1d, + 0xb9, 0x31, 0x07, 0x90, 0x08, 0x98, 0x0d, 0x91, + 0xca, 0x68, 0x25, 0x4d, 0x01, 0x92, 0x0a, 0x69, + 0x02, 0x92, 0x4a, 0x69, 0x03, 0x21, 0x03, 0x92, + 0x6a, 0x69, 0x01, 0x2a, 0x6c, 0xd0, 0x02, 0x2a, + 0x4f, 0xd1, 0x20, 0x4a, 0xd1, 0x62, 0x06, 0x21, + 0x09, 0xf0, 0x46, 0xfa, 0xc8, 0x22, 0x09, 0xf0, + 0x3b, 0xfa, 0x02, 0x9a, 0x52, 0x00, 0x09, 0xf0, + 0x37, 0xfa, 0x28, 0x22, 0x09, 0xf0, 0x34, 0xfa, + 0x03, 0x22, 0x09, 0xf0, 0x41, 0xfa, 0x07, 0x99, + 0x16, 0x4a, 0x02, 0x31, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0x11, 0x62, 0x01, 0x9a, 0xd1, 0x00, + 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, + 0x19, 0x43, 0x21, 0xe0, 0x68, 0x14, 0x04, 0x20, + 0xc4, 0x09, 0x00, 0x00, 0xfc, 0xef, 0x03, 0x20, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x3a, 0x20, 0x6e, + 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x0a, 0x00, + 0x48, 0x0b, 0x00, 0x00, 0x70, 0x14, 0x04, 0x20, + 0x71, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, + 0x48, 0xe6, 0x03, 0x20, 0x80, 0x55, 0x00, 0xe0, + 0xf8, 0x4a, 0x51, 0x62, 0x03, 0x9a, 0x11, 0x02, + 0x16, 0x23, 0xf6, 0x4a, 0x19, 0x43, 0x91, 0x62, + 0xf5, 0x49, 0x08, 0x60, 0x05, 0x20, 0x00, 0x02, + 0x08, 0x62, 0x0d, 0x98, 0xed, 0x09, 0x00, 0x7a, + 0x00, 0x08, 0x99, 0xc2, 0x68, 0x6b, 0x69, 0xf2, + 0x48, 0x01, 0x2b, 0x5c, 0xd0, 0x02, 0x2b, 0x06, + 0xd1, 0xd2, 0x00, 0x40, 0x23, 0x1a, 0x43, 0x12, + 0x02, 0x11, 0x23, 0x1a, 0x43, 0x02, 0x62, 0xc8, + 0x1d, 0x5d, 0x30, 0xec, 0x49, 0xff, 0x22, 0x02, + 0x32, 0x0a, 0x62, 0x08, 0x60, 0xf9, 0x1d, 0xe1, + 0x31, 0xe9, 0x48, 0x00, 0xe0, 0x1d, 0xe0, 0x0c, + 0xc9, 0x0c, 0xc0, 0x0c, 0xc9, 0x0c, 0xc0, 0x06, + 0x98, 0x00, 0x28, 0x73, 0xd0, 0xf8, 0x1d, 0xf9, + 0x30, 0x40, 0x69, 0x01, 0x6d, 0x38, 0x1c, 0xfd, + 0xf7, 0x20, 0xff, 0x00, 0x20, 0x2d, 0x23, 0x79, + 0x68, 0x9b, 0x01, 0xc9, 0x18, 0x08, 0x60, 0x0d, + 0x99, 0x08, 0x98, 0x89, 0x6b, 0x03, 0x91, 0xf9, + 0x6a, 0x00, 0x29, 0x34, 0xd0, 0x05, 0x21, 0x02, + 0x91, 0x33, 0xe0, 0x06, 0x21, 0x09, 0xf0, 0xbe, + 0xf9, 0xff, 0x22, 0x05, 0x32, 0x09, 0xf0, 0xb2, + 0xf9, 0x02, 0x9a, 0x52, 0x00, 0x09, 0xf0, 0xae, + 0xf9, 0x28, 0x22, 0x09, 0xf0, 0xab, 0xf9, 0x03, + 0x22, 0x09, 0xf0, 0xb8, 0xf9, 0x07, 0x99, 0x02, + 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0xca, + 0x49, 0x0a, 0x62, 0x01, 0x9a, 0xd2, 0x00, 0x84, + 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, + 0x43, 0x4a, 0x62, 0x03, 0x9a, 0x12, 0x02, 0x19, + 0x23, 0x1a, 0x43, 0x8a, 0x62, 0xc3, 0x49, 0x08, + 0x60, 0xc6, 0x48, 0x08, 0x62, 0x9b, 0xe7, 0xd2, + 0x00, 0x80, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, + 0x23, 0x1a, 0x43, 0x02, 0x62, 0xa3, 0xe7, 0x01, + 0x21, 0x02, 0x91, 0x69, 0x69, 0x01, 0x29, 0x27, + 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, 0x09, + 0xf0, 0x85, 0xf9, 0x01, 0x1c, 0xbc, 0x48, 0x81, + 0x60, 0x03, 0x99, 0x02, 0x29, 0x02, 0xd0, 0x03, + 0x99, 0x03, 0x29, 0x07, 0xd1, 0x02, 0x99, 0xed, + 0x09, 0x00, 0x7b, 0x00, 0x08, 0x23, 0x19, 0x43, + 0x02, 0x91, 0x09, 0x99, 0xb7, 0x4a, 0x49, 0x08, + 0x11, 0x60, 0x02, 0x99, 0x01, 0x60, 0x79, 0x68, + 0xff, 0x31, 0x81, 0x31, 0x89, 0x68, 0x09, 0x9a, + 0x09, 0x0e, 0x52, 0x08, 0x12, 0x02, 0x11, 0x43, + 0x41, 0x60, 0xb8, 0x6f, 0xfc, 0xf7, 0xcb, 0xfe, + 0x00, 0xe0, 0x08, 0xe0, 0x9e, 0xe0, 0x06, 0x21, + 0x09, 0xf0, 0x5f, 0xf9, 0x6a, 0x46, 0x03, 0xc2, + 0x00, 0x98, 0x01, 0x99, 0xd4, 0xe7, 0xf8, 0x1d, + 0x79, 0x30, 0x40, 0x69, 0x01, 0x21, 0x04, 0x28, + 0x00, 0xd0, 0x00, 0x21, 0x38, 0x1c, 0x04, 0xf0, + 0x1f, 0xff, 0x78, 0x6f, 0x00, 0x28, 0x5c, 0xd0, + 0xc0, 0x68, 0x0a, 0x28, 0x01, 0xd0, 0x0b, 0x28, + 0x0b, 0xd1, 0x05, 0x98, 0x00, 0x28, 0x08, 0xd1, + 0x04, 0x99, 0x01, 0x29, 0x05, 0xd0, 0x96, 0x49, + 0x08, 0x62, 0x48, 0x62, 0x9a, 0x49, 0x08, 0x60, + 0x78, 0xe0, 0x0d, 0x99, 0x08, 0x98, 0x89, 0x6b, + 0x03, 0x91, 0xf9, 0x6a, 0x00, 0x29, 0x02, 0xd0, + 0x05, 0x21, 0x02, 0x91, 0x01, 0xe0, 0x01, 0x21, + 0x02, 0x91, 0x69, 0x69, 0x01, 0x29, 0x34, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, 0x09, 0xf0, + 0x28, 0xf9, 0x01, 0x1c, 0x8e, 0x48, 0x81, 0x60, + 0x03, 0x99, 0x02, 0x29, 0x02, 0xd0, 0x03, 0x99, + 0x03, 0x29, 0x07, 0xd1, 0x02, 0x99, 0x08, 0x23, + 0x19, 0x43, 0x02, 0x91, 0x09, 0x99, 0x88, 0x4a, + 0x49, 0x08, 0x11, 0x60, 0x02, 0x99, 0x01, 0x60, + 0x79, 0x68, 0xff, 0x31, 0x81, 0x31, 0x89, 0x68, + 0x09, 0x9a, 0x09, 0x0e, 0x52, 0x08, 0x12, 0x02, + 0x11, 0x43, 0x41, 0x60, 0x78, 0x6f, 0xfc, 0xf7, + 0x6e, 0xfe, 0x78, 0x6f, 0xc0, 0x68, 0x10, 0x28, + 0x40, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, + 0x9f, 0x44, 0x3c, 0x30, 0x3c, 0x10, 0x10, 0x3c, + 0x3c, 0x3c, 0xed, 0x09, 0x00, 0x7c, 0x00, 0x3c, + 0x3c, 0x17, 0x17, 0x1d, 0x1d, 0x23, 0x23, 0x06, + 0x21, 0x09, 0xf0, 0xf5, 0xf8, 0x6a, 0x46, 0x03, + 0xc2, 0x00, 0x98, 0x01, 0x99, 0xc7, 0xe7, 0x25, + 0xe0, 0x00, 0x20, 0x2d, 0x23, 0x79, 0x68, 0x9b, + 0x01, 0xc9, 0x18, 0x08, 0x60, 0x24, 0xe0, 0x00, + 0x20, 0x2d, 0x23, 0x79, 0x68, 0x9b, 0x01, 0xc9, + 0x18, 0x08, 0x60, 0x30, 0x1d, 0x06, 0x01, 0x6c, + 0x4b, 0x36, 0x09, 0xe4, 0x18, 0x18, 0xe0, 0x00, + 0x20, 0x2d, 0x23, 0x79, 0x68, 0x9b, 0x01, 0xc9, + 0x18, 0x08, 0x60, 0xf0, 0x1d, 0x01, 0x30, 0x06, + 0x01, 0x67, 0x4b, 0x36, 0x09, 0xe4, 0x18, 0x0b, + 0xe0, 0x0d, 0x98, 0x40, 0x6a, 0x0d, 0x99, 0x01, + 0x30, 0x48, 0x62, 0x05, 0xe0, 0x5a, 0x49, 0x00, + 0x20, 0x08, 0x62, 0x48, 0x62, 0x5d, 0x49, 0x08, + 0x60, 0x60, 0x49, 0xff, 0x22, 0x20, 0x1c, 0x09, + 0x69, 0x91, 0x32, 0xfd, 0xf7, 0x12, 0xf8, 0x00, + 0x28, 0x05, 0xd1, 0x01, 0x20, 0x3a, 0x1c, 0x79, + 0x68, 0xff, 0xf7, 0x6d, 0xfb, 0xd5, 0xe4, 0x78, + 0x68, 0xc1, 0x1d, 0x79, 0x31, 0xca, 0x69, 0xff, + 0x30, 0x81, 0x30, 0xb9, 0x6a, 0x83, 0x68, 0x03, + 0x92, 0x18, 0x0e, 0x1a, 0x02, 0x12, 0x0a, 0x00, + 0x92, 0x02, 0x91, 0x00, 0x21, 0x00, 0x22, 0x1a, + 0x23, 0x01, 0x90, 0x30, 0x1c, 0xfd, 0xf7, 0x01, + 0xfa, 0x07, 0x90, 0x78, 0x68, 0xff, 0x30, 0x81, + 0x30, 0x80, 0x68, 0x00, 0x0e, 0x71, 0x08, 0x0c, + 0x91, 0x09, 0x02, 0x08, 0x43, 0x4a, 0x49, 0x48, + 0x60, 0x0d, 0x99, 0x20, 0x1c, 0x8a, 0x68, 0x03, + 0x92, 0x69, 0x69, 0x01, 0x29, 0x71, 0xd0, 0x02, + 0x29, 0x22, 0xd1, 0x09, 0x21, 0x09, 0xf0, 0x75, + 0xf8, 0xc8, 0x22, 0x09, 0xf0, 0x7c, 0xf8, 0x34, + 0x22, 0x09, 0xf0, 0x79, 0xf8, 0x50, 0x22, 0x09, + 0xf0, 0x76, 0xf8, 0x0d, 0x22, 0xed, 0x09, 0x00, + 0x7d, 0x00, 0x09, 0xf0, 0x73, 0xf8, 0x04, 0x22, + 0x09, 0xf0, 0x70, 0xf8, 0x28, 0x22, 0x09, 0xf0, + 0x6d, 0xf8, 0x07, 0x99, 0x02, 0x31, 0x09, 0x02, + 0x10, 0x22, 0x0a, 0x43, 0x38, 0x49, 0x0a, 0x62, + 0x03, 0x9a, 0x42, 0x23, 0x1a, 0x43, 0x12, 0x02, + 0x11, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x35, 0x4a, + 0x35, 0x49, 0x0a, 0x62, 0x08, 0x60, 0x0d, 0x98, + 0x81, 0x68, 0x6a, 0x69, 0x33, 0x48, 0x01, 0x2a, + 0x44, 0xd0, 0x02, 0x2a, 0x05, 0xd1, 0x40, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, + 0x01, 0x62, 0xe0, 0x1d, 0x49, 0x30, 0xff, 0x22, + 0x2d, 0x49, 0x02, 0x32, 0x0a, 0x62, 0x08, 0x60, + 0x2c, 0x48, 0xc0, 0x69, 0x00, 0x28, 0x73, 0xd0, + 0xc2, 0x1d, 0xb9, 0x32, 0x0b, 0x92, 0x93, 0x68, + 0x29, 0x4a, 0x02, 0x93, 0x11, 0x6a, 0x52, 0x6a, + 0x09, 0x0a, 0xff, 0x23, 0x1b, 0x02, 0x1a, 0x40, + 0x11, 0x43, 0x6a, 0x69, 0x01, 0x2a, 0x64, 0xd0, + 0x02, 0x2a, 0x07, 0xd1, 0xd2, 0x03, 0x0b, 0x0c, + 0x00, 0xd2, 0x00, 0x22, 0x11, 0x43, 0x01, 0x23, + 0xdb, 0x03, 0x99, 0x43, 0x03, 0x91, 0x0b, 0x9a, + 0x03, 0x23, 0x11, 0x6a, 0x03, 0x9a, 0x1b, 0x04, + 0x1a, 0x40, 0x0b, 0x40, 0x01, 0x93, 0x03, 0x23, + 0x1b, 0x04, 0x02, 0x92, 0x0a, 0x1c, 0x9a, 0x43, + 0xd2, 0x00, 0x00, 0x92, 0x02, 0x9a, 0x01, 0x9b, + 0x9a, 0x42, 0x5f, 0xd0, 0x03, 0x99, 0x62, 0xe0, + 0x28, 0xe0, 0x27, 0xe0, 0x4b, 0xe0, 0x00, 0x00, + 0x80, 0x55, 0x00, 0xe0, 0x00, 0x53, 0x00, 0xe0, + 0x90, 0x55, 0x00, 0xe0, 0x04, 0x53, 0x00, 0xe0, + 0xa0, 0x57, 0x00, 0xe0, 0x03, 0x05, 0x00, 0x00, + 0x00, 0x52, 0x00, 0xe0, 0x80, 0x57, 0x00, 0xe0, + 0xc4, 0x09, 0x00, 0x00, 0x88, 0x13, 0x00, 0x00, + 0x00, 0x50, 0x00, 0xe0, 0x00, 0x51, 0x00, 0xe0, + 0xed, 0x09, 0x00, 0x7e, 0x00, 0xa0, 0x55, 0x00, + 0xe0, 0x02, 0x05, 0x00, 0x00, 0x08, 0x53, 0x00, + 0xe0, 0xb0, 0x55, 0x00, 0xe0, 0x0c, 0x53, 0x00, + 0xe0, 0x68, 0x14, 0x04, 0x20, 0xd0, 0x55, 0x00, + 0xe0, 0x10, 0x21, 0x08, 0xf0, 0xdb, 0xff, 0xff, + 0x22, 0x05, 0x32, 0x08, 0xf0, 0xe1, 0xff, 0x46, + 0x22, 0x08, 0xf0, 0xde, 0xff, 0x0d, 0x22, 0x08, + 0xf0, 0xdb, 0xff, 0x04, 0x22, 0x08, 0xf0, 0xd8, + 0xff, 0x28, 0x22, 0x08, 0xf0, 0xd5, 0xff, 0x07, + 0x99, 0x02, 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, + 0x43, 0x65, 0x49, 0x01, 0xe0, 0x26, 0xe0, 0x0f, + 0xe0, 0x0a, 0x62, 0x03, 0x9a, 0x82, 0x23, 0x1a, + 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x4a, + 0x62, 0x63, 0xe7, 0x80, 0x23, 0x19, 0x43, 0x09, + 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, 0x62, 0x6e, + 0xe7, 0x01, 0x22, 0x02, 0x9b, 0x12, 0x04, 0x00, + 0x2b, 0x00, 0xd1, 0x00, 0x22, 0x11, 0x43, 0x8b, + 0xe7, 0x00, 0x9a, 0x51, 0x1a, 0x03, 0x9a, 0x89, + 0x18, 0xc9, 0x08, 0x01, 0x22, 0x02, 0x9b, 0x12, + 0x04, 0x00, 0x2b, 0x00, 0xd1, 0x00, 0x22, 0x11, + 0x43, 0x0b, 0x9a, 0x11, 0x62, 0x6a, 0x69, 0x21, + 0x1c, 0x01, 0x2a, 0x5e, 0xd0, 0x02, 0x2a, 0x05, + 0xd1, 0x4e, 0x4a, 0x2d, 0x23, 0x13, 0x62, 0x2c, + 0x23, 0x53, 0x62, 0x3c, 0x39, 0x4c, 0x4b, 0x4d, + 0x4a, 0x13, 0x62, 0x11, 0x60, 0x12, 0x99, 0x4c, + 0x4b, 0x19, 0x40, 0x35, 0xd1, 0x00, 0x28, 0x33, + 0xd0, 0xc0, 0x30, 0x0a, 0x90, 0x49, 0x4a, 0x81, + 0x68, 0x10, 0x6a, 0x52, 0x6a, 0x00, 0x0a, 0xff, + 0x23, 0x1b, 0x02, 0x1a, 0x40, 0x10, 0x43, 0x6a, + 0x69, 0x01, 0x2a, 0x45, 0xd0, 0x02, 0x2a, 0x07, + 0xd1, 0xd2, 0x03, 0x01, 0x0c, 0x00, 0xd2, 0x00, + 0x22, 0x10, 0x43, 0x01, 0x23, 0xdb, 0x03, 0x98, + 0x43, 0x03, 0x22, 0xed, 0x09, 0x00, 0x7f, 0x00, + 0x12, 0x04, 0x0a, 0x99, 0x02, 0x40, 0x03, 0x23, + 0xc9, 0x69, 0x1b, 0x04, 0x0b, 0x40, 0x02, 0x93, + 0x3b, 0x4b, 0x0b, 0x40, 0xdb, 0x00, 0x01, 0x93, + 0x02, 0x9b, 0x9a, 0x42, 0x03, 0xd1, 0x01, 0x9b, + 0x59, 0x1a, 0x08, 0x18, 0xc0, 0x08, 0x01, 0x21, + 0x09, 0x04, 0x00, 0x2a, 0x00, 0xd1, 0x00, 0x21, + 0x08, 0x43, 0x0a, 0x99, 0xc8, 0x61, 0x68, 0x69, + 0x01, 0x28, 0x23, 0xd0, 0x02, 0x28, 0x04, 0xd1, + 0x2e, 0x4a, 0x2d, 0x23, 0x13, 0x62, 0x2c, 0x23, + 0x53, 0x62, 0x28, 0x4b, 0x2d, 0x49, 0xe0, 0x1d, + 0x21, 0x30, 0x0b, 0x62, 0x08, 0x60, 0x0d, 0x99, + 0x20, 0x1c, 0x89, 0x6b, 0x03, 0x91, 0xf9, 0x6a, + 0x00, 0x29, 0x15, 0xd0, 0x05, 0x27, 0x14, 0xe0, + 0x20, 0x4a, 0x3d, 0x23, 0x13, 0x62, 0x3e, 0x23, + 0x53, 0x62, 0x46, 0x39, 0xa1, 0xe7, 0x01, 0x22, + 0x12, 0x04, 0x00, 0x29, 0x00, 0xd1, 0x00, 0x22, + 0x10, 0x43, 0xbc, 0xe7, 0x1d, 0x4a, 0x3d, 0x23, + 0x13, 0x62, 0x3e, 0x23, 0x53, 0x62, 0xdc, 0xe7, + 0x01, 0x27, 0x69, 0x69, 0x01, 0x29, 0x1d, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x09, 0x21, 0x08, 0xf0, + 0x1c, 0xff, 0xc2, 0x1f, 0x18, 0x49, 0x21, 0x3a, + 0x8a, 0x60, 0xb0, 0x30, 0xc8, 0x60, 0x03, 0x98, + 0x01, 0x28, 0x02, 0xd0, 0x03, 0x98, 0x03, 0x28, + 0x04, 0xd1, 0x0c, 0x98, 0x13, 0x4a, 0x08, 0x23, + 0x1f, 0x43, 0x10, 0x60, 0x32, 0x20, 0x0f, 0x60, + 0x09, 0xf0, 0xa9, 0xfc, 0x10, 0x48, 0x44, 0x60, + 0x06, 0x60, 0x23, 0xe4, 0x10, 0x21, 0x08, 0xf0, + 0x00, 0xff, 0x01, 0xaa, 0x03, 0xc2, 0x01, 0x98, + 0x02, 0x99, 0xde, 0xe7, 0x00, 0x00, 0xa0, 0x55, + 0x00, 0xe0, 0xd0, 0x55, 0x00, 0xe0, 0x02, 0x03, + 0x00, 0x00, 0x14, 0x53, 0x00, 0xe0, 0x09, 0x00, + 0x00, 0x40, 0xc0, 0x55, 0x00, 0xe0, 0xed, 0x09, + 0x00, 0x80, 0x00, 0xff, 0xff, 0xfc, 0xff, 0x10, + 0x53, 0x00, 0xe0, 0x00, 0x51, 0x00, 0xe0, 0x80, + 0x55, 0x00, 0xe0, 0x68, 0x14, 0x04, 0x20, 0xf1, + 0xb5, 0x88, 0xb0, 0xad, 0x48, 0x00, 0x21, 0x60, + 0xc8, 0x08, 0x38, 0x40, 0x69, 0x02, 0x91, 0x08, + 0x91, 0xab, 0x49, 0x00, 0x24, 0x89, 0x6a, 0x07, + 0x1c, 0x4a, 0x07, 0x52, 0x0f, 0x07, 0x92, 0x04, + 0xab, 0x1a, 0x70, 0x4a, 0x06, 0x12, 0x0f, 0x05, + 0x92, 0x0a, 0x06, 0xd2, 0x0f, 0x5a, 0x70, 0xca, + 0x05, 0xd2, 0x0f, 0x89, 0x05, 0xc9, 0x0f, 0x9a, + 0x70, 0xd9, 0x70, 0x39, 0x7e, 0x07, 0x9a, 0x38, + 0x1c, 0x91, 0x42, 0x09, 0xd0, 0x04, 0xaa, 0x12, + 0x78, 0xff, 0x23, 0x35, 0x33, 0x5a, 0x43, 0x79, + 0x68, 0x89, 0x18, 0xcf, 0x1d, 0xff, 0x37, 0x92, + 0x37, 0x04, 0xa9, 0x89, 0x78, 0x01, 0x29, 0x47, + 0xd1, 0xc0, 0x68, 0x03, 0x28, 0x07, 0xd1, 0x2d, + 0xf0, 0x50, 0xfc, 0x00, 0x22, 0x01, 0x21, 0x38, + 0x1c, 0x04, 0xf0, 0xfc, 0xfd, 0x3c, 0xe0, 0x78, + 0x6f, 0x01, 0x90, 0x00, 0x28, 0x38, 0xd0, 0x78, + 0x6a, 0xfd, 0x28, 0x35, 0xd0, 0xf8, 0x1d, 0x79, + 0x30, 0x06, 0x90, 0xc0, 0x68, 0x00, 0x28, 0x01, + 0xd1, 0x78, 0x67, 0x2d, 0xe0, 0x38, 0x1c, 0x04, + 0xf0, 0x02, 0xff, 0x00, 0x28, 0x1b, 0xd1, 0x01, + 0x98, 0x88, 0x49, 0xc0, 0x68, 0xc3, 0x00, 0x18, + 0x18, 0x80, 0x00, 0x40, 0x18, 0xc0, 0x69, 0x00, + 0x28, 0x0c, 0xd0, 0x01, 0x21, 0xfa, 0x6d, 0x08, + 0x1c, 0x00, 0x2a, 0x00, 0xd0, 0x00, 0x20, 0xf8, + 0x65, 0xf8, 0x1d, 0xb9, 0x30, 0xf9, 0x66, 0xc1, + 0x6b, 0x01, 0x31, 0xc1, 0x63, 0x01, 0x98, 0x39, + 0x1c, 0x04, 0xf0, 0xe0, 0xfe, 0x0c, 0xe0, 0x06, + 0x98, 0x40, 0x68, 0x06, 0x99, 0x02, 0x90, 0x00, + 0x20, 0x48, 0x60, 0x01, 0x99, 0xcc, 0x6b, 0xc8, + 0x63, 0xed, 0x09, 0x00, 0x81, 0x00, 0x06, 0x99, + 0xc9, 0x68, 0x03, 0x91, 0x78, 0x67, 0x78, 0x6e, + 0x40, 0x08, 0x07, 0xd3, 0x04, 0xa8, 0x40, 0x78, + 0x00, 0x28, 0x03, 0xd0, 0x01, 0x21, 0x38, 0x1c, + 0x04, 0xf0, 0x56, 0xfe, 0x78, 0x6e, 0x40, 0x08, + 0x07, 0xd2, 0x04, 0xa8, 0x40, 0x78, 0x00, 0x28, + 0x03, 0xd1, 0x01, 0x21, 0x38, 0x1c, 0x04, 0xf0, + 0x31, 0xfe, 0xf8, 0x1d, 0xf9, 0x30, 0x41, 0x68, + 0x01, 0x31, 0x41, 0x60, 0x05, 0x98, 0x10, 0x28, + 0x67, 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0x08, 0x6c, 0x6c, 0x11, + 0x11, 0x46, 0x46, 0x46, 0x11, 0x6c, 0x4d, 0x4d, + 0x5d, 0x5d, 0x64, 0x64, 0xf8, 0x1d, 0xb9, 0x30, + 0x40, 0x6a, 0x00, 0x28, 0x5e, 0xd1, 0x01, 0x21, + 0x49, 0x07, 0x08, 0x91, 0x69, 0xe0, 0x04, 0xa9, + 0xc9, 0x78, 0x38, 0x6c, 0x88, 0x42, 0x02, 0xd1, + 0x01, 0x21, 0x39, 0x66, 0x01, 0xe0, 0x00, 0x20, + 0x38, 0x66, 0x00, 0x20, 0x2d, 0x23, 0x79, 0x68, + 0x9b, 0x01, 0xc9, 0x18, 0x08, 0x60, 0x53, 0x48, + 0x00, 0x68, 0x80, 0x09, 0x55, 0xd3, 0x4f, 0x48, + 0x00, 0x6a, 0x00, 0xab, 0x18, 0x70, 0x00, 0x98, + 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x14, 0xd0, + 0x78, 0x6e, 0x02, 0x23, 0x18, 0x40, 0x07, 0xd0, + 0x00, 0x99, 0xc9, 0x08, 0x04, 0xd3, 0x02, 0x21, + 0x38, 0x1c, 0x04, 0xf0, 0x05, 0xfe, 0x08, 0xe0, + 0x00, 0x28, 0x06, 0xd1, 0x00, 0x98, 0xc0, 0x08, + 0x03, 0xd2, 0x02, 0x21, 0x38, 0x1c, 0x04, 0xf0, + 0xe1, 0xfd, 0x01, 0x21, 0x39, 0x66, 0x34, 0xe0, + 0x00, 0x20, 0x2d, 0x23, 0x79, 0x68, 0x9b, 0x01, + 0xc9, 0x18, 0x08, 0x60, 0x2d, 0xe0, 0x04, 0xa9, + 0xc9, 0x78, 0x38, 0x6c, 0x88, 0x42, 0x02, 0xd1, + 0x01, 0x21, 0x39, 0x66, 0x01, 0xe0, 0x00, 0x20, + 0x38, 0x66, 0x00, 0x20, 0xed, 0x09, 0x00, 0x82, + 0x00, 0x2d, 0x23, 0x79, 0x68, 0x9b, 0x01, 0xc9, + 0x18, 0x08, 0x60, 0x28, 0x1d, 0x05, 0x01, 0x35, + 0x4b, 0x2d, 0x09, 0xf6, 0x18, 0x17, 0xe0, 0x16, + 0xe0, 0x04, 0xa9, 0xc9, 0x78, 0x38, 0x6c, 0x88, + 0x42, 0x03, 0xd1, 0x01, 0x21, 0x39, 0x66, 0x02, + 0xe0, 0x0d, 0xe0, 0x00, 0x20, 0x38, 0x66, 0xe8, + 0x1d, 0x01, 0x30, 0x05, 0x01, 0x2d, 0x09, 0x2c, + 0x4b, 0x00, 0x20, 0xf6, 0x18, 0x2d, 0x23, 0x79, + 0x68, 0x9b, 0x01, 0xc9, 0x18, 0x08, 0x60, 0x23, + 0x48, 0x60, 0xc0, 0x08, 0x98, 0xff, 0xf7, 0xba, + 0xf9, 0x02, 0x98, 0x00, 0x28, 0x10, 0xd0, 0x00, + 0x2c, 0x13, 0xd0, 0x34, 0x20, 0x20, 0x60, 0xb8, + 0x68, 0xe0, 0x60, 0x00, 0x20, 0x20, 0x61, 0x02, + 0x98, 0x60, 0x61, 0x03, 0x99, 0x0e, 0x20, 0xa1, + 0x61, 0x21, 0x1c, 0xf8, 0xf7, 0x6b, 0xfd, 0x04, + 0xe0, 0x00, 0x2c, 0x02, 0xd0, 0x20, 0x1c, 0xf8, + 0xf7, 0x31, 0xfd, 0xfc, 0x1d, 0x79, 0x34, 0x60, + 0x69, 0x04, 0x28, 0x1f, 0xd1, 0xf8, 0xf7, 0xef, + 0xfc, 0x00, 0x28, 0x1b, 0xd0, 0x41, 0x21, 0x01, + 0x60, 0x79, 0x68, 0x00, 0x25, 0x81, 0x61, 0x47, + 0x61, 0x79, 0x68, 0x49, 0x68, 0x01, 0x61, 0x39, + 0x7e, 0xc1, 0x60, 0xc5, 0x61, 0x01, 0x1c, 0x0e, + 0x20, 0xf8, 0xf7, 0x4c, 0xfd, 0xf9, 0x1d, 0xb9, + 0x31, 0x49, 0x68, 0x78, 0x68, 0x4a, 0x68, 0x90, + 0x42, 0x03, 0xd0, 0x4d, 0x60, 0x10, 0x1c, 0xfc, + 0xf7, 0xa7, 0xf8, 0x65, 0x61, 0x09, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x14, 0x04, + 0x20, 0x40, 0x55, 0x00, 0xe0, 0x78, 0x7b, 0x03, + 0x20, 0x00, 0x50, 0x00, 0xe0, 0xc4, 0x09, 0x00, + 0x00, 0x88, 0x13, 0x00, 0x00, 0xf0, 0xb5, 0x25, + 0x48, 0xc5, 0x69, 0x00, 0x2d, 0x2b, 0xd0, 0xe8, + 0x1d, 0xf9, 0x30, 0xc1, 0x68, 0xee, 0x1d, 0xed, + 0x09, 0x00, 0x83, 0x00, 0x01, 0x31, 0xc1, 0x60, + 0xb9, 0x36, 0x70, 0x6a, 0x00, 0x28, 0x21, 0xd0, + 0xf8, 0xf7, 0xf0, 0xfc, 0x07, 0x1c, 0x1d, 0xd0, + 0x1d, 0x49, 0xf8, 0x1d, 0x89, 0x6a, 0x01, 0x30, + 0x4a, 0x07, 0x52, 0x0f, 0x02, 0x70, 0x4a, 0x06, + 0x12, 0x0f, 0x42, 0x60, 0x0a, 0x06, 0xd2, 0x0f, + 0x42, 0x70, 0xca, 0x05, 0xd2, 0x0f, 0x89, 0x05, + 0xc9, 0x0f, 0x82, 0x70, 0xc1, 0x70, 0x00, 0x20, + 0xf8, 0x60, 0xf0, 0x69, 0xb8, 0x64, 0xf8, 0xf7, + 0x95, 0xfc, 0x04, 0x1c, 0x05, 0xd1, 0x38, 0x1c, + 0xf8, 0xf7, 0xf1, 0xfc, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x35, 0x20, 0x20, 0x60, 0x68, 0x68, + 0x40, 0x68, 0xe0, 0x60, 0x0e, 0x20, 0x21, 0x1c, + 0x27, 0x61, 0xf8, 0xf7, 0xf2, 0xfc, 0x00, 0x28, + 0x06, 0xd0, 0x38, 0x1c, 0xf8, 0xf7, 0xdf, 0xfc, + 0x20, 0x1c, 0xf8, 0xf7, 0xb6, 0xfc, 0xe9, 0xe7, + 0x70, 0x6a, 0x01, 0x38, 0x70, 0x62, 0xe5, 0xe7, + 0x00, 0x00, 0x68, 0x14, 0x04, 0x20, 0x40, 0x55, + 0x00, 0xe0, 0xf0, 0xb5, 0x69, 0x4d, 0x07, 0x1c, + 0xec, 0x69, 0x68, 0x68, 0x2e, 0x69, 0x00, 0x2c, + 0x09, 0xd0, 0x66, 0x49, 0x00, 0x22, 0x09, 0x69, + 0xfc, 0xf7, 0x85, 0xfc, 0x00, 0x28, 0x05, 0xd1, + 0x38, 0x1c, 0xff, 0xf7, 0x9e, 0xff, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xa8, 0x69, 0x01, 0x21, + 0xa0, 0x42, 0x00, 0xd0, 0x00, 0x21, 0x38, 0x1c, + 0xfc, 0xf7, 0xdf, 0xf8, 0x00, 0x21, 0x07, 0x1c, + 0x00, 0x28, 0x08, 0xd1, 0x20, 0x66, 0xfc, 0xf7, + 0x6c, 0xfa, 0xe0, 0x1d, 0xf9, 0x30, 0xc1, 0x68, + 0x01, 0x31, 0xc1, 0x60, 0xe7, 0xe7, 0x20, 0x7e, + 0x3a, 0x7a, 0x90, 0x42, 0x16, 0xd0, 0x00, 0x20, + 0x21, 0x66, 0xfc, 0xf7, 0x5e, 0xfa, 0xe0, 0x1d, + 0xf9, 0x30, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, + 0x38, 0x6b, 0xed, 0x09, 0x00, 0x84, 0x00, 0x00, + 0x28, 0x01, 0xd0, 0xf8, 0xf7, 0x30, 0xfc, 0xf8, + 0x69, 0x00, 0x28, 0x01, 0xd0, 0xf8, 0xf7, 0x2b, + 0xfc, 0x38, 0x1c, 0xf8, 0xf7, 0x8e, 0xfc, 0xcc, + 0xe7, 0xe5, 0x1d, 0xb9, 0x35, 0xe8, 0x69, 0xb8, + 0x64, 0xf8, 0x68, 0x03, 0x38, 0x0d, 0x28, 0x40, + 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, + 0x44, 0x00, 0x1c, 0x07, 0x07, 0x36, 0x36, 0x36, + 0x07, 0x3c, 0x07, 0x07, 0x3c, 0x3c, 0x07, 0x07, + 0x00, 0x78, 0x69, 0x02, 0x28, 0x01, 0xd0, 0x01, + 0x28, 0x14, 0xd1, 0x60, 0x6e, 0x02, 0x23, 0x18, + 0x40, 0x07, 0xd0, 0x39, 0x69, 0x00, 0x29, 0x04, + 0xd0, 0x02, 0x21, 0x20, 0x1c, 0x04, 0xf0, 0xb7, + 0xfc, 0x08, 0xe0, 0x00, 0x28, 0x06, 0xd1, 0x38, + 0x69, 0x00, 0x28, 0x03, 0xd1, 0x02, 0x21, 0x20, + 0x1c, 0x04, 0xf0, 0x93, 0xfc, 0xf8, 0x1d, 0x01, + 0x30, 0x21, 0x1c, 0x04, 0xf0, 0x09, 0xfd, 0x00, + 0x28, 0x13, 0xd0, 0x38, 0x6b, 0x00, 0x28, 0x01, + 0xd0, 0xf8, 0xf7, 0xed, 0xfb, 0xf8, 0x69, 0x00, + 0x28, 0x01, 0xd0, 0xf8, 0xf7, 0xe8, 0xfb, 0x38, + 0x1c, 0xf8, 0xf7, 0x4b, 0xfc, 0x89, 0xe7, 0x00, + 0x22, 0x20, 0x1c, 0x39, 0x1c, 0xfd, 0xf7, 0x79, + 0xf9, 0x83, 0xe7, 0x68, 0x6a, 0x00, 0x28, 0x02, + 0xd0, 0x01, 0x38, 0x68, 0x62, 0x10, 0xe0, 0xf8, + 0x68, 0x00, 0x28, 0x0d, 0xd1, 0x38, 0x6b, 0x00, + 0x28, 0x01, 0xd0, 0xf8, 0xf7, 0xd0, 0xfb, 0xf8, + 0x69, 0x00, 0x28, 0x01, 0xd0, 0xf8, 0xf7, 0xcb, + 0xfb, 0x38, 0x1c, 0xf8, 0xf7, 0x2e, 0xfc, 0x6c, + 0xe7, 0xf8, 0xf7, 0xca, 0xfb, 0x04, 0x1c, 0x0d, + 0xd1, 0x38, 0x6b, 0x00, 0x28, 0x01, 0xd0, 0xf8, + 0xf7, 0xbe, 0xfb, 0xf8, 0x69, 0x00, 0x28, 0x01, + 0xd0, 0xf8, 0xf7, 0xb9, 0xfb, 0x38, 0x1c, 0xf8, + 0xf7, 0x1c, 0xfc, 0x5a, 0xe7, 0xed, 0x09, 0x00, + 0x85, 0x00, 0x35, 0x20, 0x20, 0x60, 0x70, 0x68, + 0xe0, 0x60, 0x0e, 0x20, 0x21, 0x1c, 0x27, 0x61, + 0xf8, 0xf7, 0x20, 0xfc, 0x00, 0x28, 0xc4, 0xd0, + 0x38, 0x6b, 0x00, 0x28, 0x01, 0xd0, 0xf8, 0xf7, + 0xa5, 0xfb, 0xf8, 0x69, 0x00, 0x28, 0x01, 0xd0, + 0xf8, 0xf7, 0xa0, 0xfb, 0x38, 0x1c, 0xf8, 0xf7, + 0x03, 0xfc, 0x20, 0x1c, 0xf8, 0xf7, 0xda, 0xfb, + 0x3e, 0xe7, 0x00, 0x00, 0x68, 0x14, 0x04, 0x20, + 0x00, 0x50, 0x00, 0xe0, 0xf0, 0xb5, 0x84, 0xb0, + 0x0c, 0x1c, 0x17, 0x1c, 0x2d, 0xf0, 0xee, 0xf9, + 0x2c, 0x4d, 0x2c, 0x61, 0x6f, 0x61, 0xfb, 0xf7, + 0xab, 0xfd, 0x02, 0x90, 0x03, 0x91, 0x60, 0x6d, + 0x29, 0x4b, 0x58, 0x43, 0x00, 0x21, 0x6a, 0x46, + 0x51, 0x60, 0x10, 0x60, 0x02, 0x98, 0x00, 0x9a, + 0xee, 0x1d, 0x01, 0x36, 0x03, 0x99, 0x01, 0x9b, + 0x80, 0x18, 0x59, 0x41, 0x03, 0xc6, 0x00, 0x21, + 0x00, 0x20, 0x23, 0x1c, 0x02, 0xaa, 0xfb, 0xf7, + 0x47, 0xfe, 0x28, 0x60, 0x03, 0x99, 0x02, 0x98, + 0x1e, 0x49, 0x68, 0x60, 0x02, 0x20, 0x08, 0x60, + 0x1d, 0x48, 0x1e, 0x49, 0x42, 0x69, 0xf8, 0x1d, + 0xb9, 0x30, 0x01, 0x2a, 0x2a, 0xd0, 0x02, 0x2a, + 0x01, 0xd1, 0x01, 0x22, 0xca, 0x60, 0xe5, 0x1d, + 0x51, 0x35, 0x2c, 0x1c, 0x0c, 0xcd, 0x18, 0x49, + 0x0c, 0xc1, 0x28, 0xcc, 0x17, 0x49, 0x28, 0xc1, + 0x80, 0x6b, 0x00, 0x28, 0x09, 0xd0, 0xf9, 0x1d, + 0xe1, 0x31, 0x3c, 0xc9, 0x14, 0x48, 0xf9, 0x1d, + 0x3c, 0xc0, 0x09, 0x31, 0xa0, 0xc9, 0x13, 0x48, + 0xa0, 0xc0, 0x13, 0x49, 0x13, 0x48, 0xc1, 0x60, + 0x81, 0x68, 0xfb, 0x23, 0x9b, 0x00, 0x19, 0x43, + 0x81, 0x60, 0x80, 0x04, 0x00, 0xf0, 0x76, 0xf8, + 0x2d, 0xf0, 0x98, 0xf9, 0x04, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x02, 0x69, 0xca, 0x60, + 0xed, 0x09, 0x00, 0x86, 0x00, 0xd5, 0xe7, 0x00, + 0x00, 0x68, 0x14, 0x04, 0x20, 0x71, 0x02, 0x00, + 0x00, 0x24, 0x7e, 0x03, 0x20, 0x48, 0xe6, 0x03, + 0x20, 0x00, 0x52, 0x00, 0xe0, 0x20, 0x51, 0x00, + 0xe0, 0x90, 0x57, 0x00, 0xe0, 0xa0, 0x57, 0x00, + 0xe0, 0xb0, 0x57, 0x00, 0xe0, 0xfc, 0x07, 0x00, + 0x00, 0x00, 0x50, 0x00, 0xe0, 0x80, 0xb4, 0x08, + 0x49, 0x49, 0x69, 0x81, 0x42, 0x0a, 0xd1, 0xc7, + 0x1d, 0xe1, 0x37, 0x0c, 0xcf, 0x05, 0x49, 0x10, + 0x30, 0x0c, 0xc1, 0x0c, 0xcf, 0x0c, 0xc1, 0x88, + 0xc8, 0x03, 0x49, 0x88, 0xc1, 0x80, 0xbc, 0x70, + 0x47, 0x68, 0x14, 0x04, 0x20, 0xa0, 0x57, 0x00, + 0xe0, 0xb0, 0x57, 0x00, 0xe0, 0x00, 0xb5, 0x2d, + 0xf0, 0x63, 0xf9, 0x13, 0x49, 0x00, 0x20, 0x08, + 0x60, 0x12, 0x49, 0x8a, 0x68, 0x12, 0x4b, 0x1a, + 0x40, 0x8a, 0x60, 0xda, 0x43, 0xca, 0x60, 0x11, + 0x49, 0x08, 0x60, 0x11, 0x49, 0x08, 0x60, 0x11, + 0x49, 0x08, 0x62, 0x48, 0x62, 0x88, 0x62, 0xc8, + 0x62, 0x08, 0x63, 0x48, 0x63, 0x0e, 0x48, 0x41, + 0x69, 0x0e, 0x48, 0x01, 0x29, 0x09, 0xd0, 0x02, + 0x29, 0x01, 0xd1, 0x0d, 0x49, 0x01, 0x62, 0x01, + 0x21, 0x41, 0x60, 0x2d, 0xf0, 0x3d, 0xf9, 0x08, + 0xbc, 0x18, 0x47, 0x0a, 0x49, 0x01, 0x62, 0xf6, + 0xe7, 0x24, 0x7e, 0x03, 0x20, 0x00, 0x50, 0x00, + 0xe0, 0x03, 0xf8, 0xff, 0xff, 0x00, 0x51, 0x00, + 0xe0, 0x00, 0x52, 0x00, 0xe0, 0x00, 0x53, 0x00, + 0xe0, 0x48, 0xe6, 0x03, 0x20, 0x40, 0x53, 0x00, + 0xe0, 0x11, 0x40, 0x00, 0x00, 0x10, 0x80, 0x00, + 0x00, 0xf1, 0xb5, 0x8b, 0xb0, 0xf8, 0x4a, 0xf9, + 0x4b, 0x10, 0x68, 0x51, 0x68, 0x54, 0x69, 0x04, + 0x30, 0xcf, 0x18, 0x61, 0x68, 0x05, 0x01, 0x05, + 0x91, 0xe0, 0x68, 0x2d, 0x09, 0x03, 0x28, 0x23, + 0xd1, 0xf8, 0xf7, 0xed, 0x09, 0x00, 0x87, 0x00, + 0xbb, 0xfa, 0x06, 0x1c, 0x1f, 0xd0, 0x20, 0x1c, + 0x05, 0xf0, 0x1b, 0xf8, 0x01, 0x20, 0x21, 0x1c, + 0x04, 0xf0, 0x75, 0xfb, 0x20, 0x1c, 0x04, 0xf0, + 0x1a, 0xfb, 0x3b, 0x20, 0x30, 0x60, 0xa0, 0x68, + 0xf0, 0x60, 0x00, 0x20, 0x30, 0x61, 0x0e, 0x20, + 0x31, 0x1c, 0xf8, 0xf7, 0x14, 0xfb, 0x04, 0x20, + 0xe0, 0x60, 0x01, 0x23, 0x02, 0x22, 0x00, 0x21, + 0x60, 0x68, 0xfa, 0xf7, 0x64, 0xf9, 0x0c, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe0, 0x1d, + 0x79, 0x30, 0x0a, 0x90, 0x40, 0x69, 0x08, 0x26, + 0x01, 0x28, 0x4e, 0xd1, 0x0a, 0x99, 0x09, 0x6b, + 0xa9, 0x42, 0x4a, 0xd2, 0xc8, 0x1d, 0x6d, 0x30, + 0xa8, 0x42, 0x20, 0xd9, 0x60, 0x6f, 0x00, 0x28, + 0x04, 0xd0, 0xc0, 0x68, 0x00, 0x28, 0x01, 0xd0, + 0x02, 0x28, 0x0e, 0xd1, 0xe0, 0x1d, 0x45, 0x30, + 0x04, 0xf0, 0x12, 0xf9, 0x00, 0x28, 0x08, 0xd1, + 0xe0, 0x1d, 0x4d, 0x30, 0x04, 0xf0, 0x0c, 0xf9, + 0x00, 0x28, 0x02, 0xd1, 0x06, 0xf0, 0x9d, 0xfc, + 0xd5, 0xe7, 0xe0, 0x1d, 0x45, 0x30, 0x04, 0xf0, + 0x03, 0xf9, 0x00, 0x28, 0x03, 0xd1, 0xe0, 0x1d, + 0x4d, 0x30, 0x04, 0xf0, 0xfd, 0xf8, 0xf8, 0xf7, + 0x67, 0xfa, 0x00, 0x28, 0x0e, 0xd0, 0x41, 0x21, + 0x01, 0x60, 0x61, 0x68, 0x81, 0x61, 0x44, 0x61, + 0x61, 0x68, 0x49, 0x68, 0x01, 0x61, 0x21, 0x7e, + 0xc1, 0x60, 0xc6, 0x61, 0x01, 0x1c, 0x0e, 0x20, + 0xf8, 0xf7, 0xc5, 0xfa, 0x0a, 0x98, 0x00, 0x26, + 0x46, 0x61, 0x0a, 0x98, 0x80, 0x69, 0x00, 0x28, + 0x08, 0xd0, 0x61, 0x68, 0x40, 0x68, 0x81, 0x42, + 0x04, 0xd0, 0x01, 0x23, 0x01, 0x22, 0x00, 0x21, + 0xfa, 0xf7, 0x0d, 0xf9, 0x0a, 0x98, 0x86, 0x61, + 0x0d, 0xe0, 0x04, 0x28, 0x0b, 0xd1, 0x0a, 0x98, + 0x00, 0x6b, 0x0a, 0x99, 0x01, 0x38, 0xed, 0x09, + 0x00, 0x88, 0x00, 0x08, 0x63, 0x05, 0xd1, 0x20, + 0x1c, 0x06, 0xf0, 0x31, 0xfb, 0x00, 0x28, 0x00, + 0xd0, 0x97, 0xe7, 0x0b, 0x98, 0x00, 0x28, 0x6b, + 0xd0, 0x29, 0x1c, 0x3a, 0x1c, 0x05, 0x98, 0x01, + 0xf0, 0xf4, 0xf8, 0x07, 0x1c, 0x60, 0x6e, 0x40, + 0x08, 0x03, 0xd3, 0x01, 0x21, 0x20, 0x1c, 0x04, + 0xf0, 0xd4, 0xfa, 0x00, 0x26, 0x26, 0x66, 0x0b, + 0x98, 0x40, 0x08, 0x05, 0xd3, 0x01, 0x20, 0x22, + 0x1c, 0x61, 0x68, 0xff, 0xf7, 0x82, 0xfe, 0x7c, + 0xe7, 0xe6, 0x1d, 0xf9, 0x36, 0x70, 0x69, 0x09, + 0x90, 0x00, 0x28, 0x1a, 0xd0, 0x09, 0x98, 0xc0, + 0x69, 0x00, 0x28, 0x16, 0xd0, 0xa9, 0x1e, 0x09, + 0x98, 0x08, 0x91, 0x00, 0x6a, 0x09, 0x1a, 0x09, + 0x98, 0x40, 0x6a, 0xf7, 0xf7, 0x84, 0xfd, 0x00, + 0x29, 0x0b, 0xd1, 0x09, 0x98, 0x97, 0x4b, 0x00, + 0x6d, 0xfa, 0x18, 0x03, 0x1c, 0x20, 0x1c, 0x08, + 0x99, 0x00, 0xf0, 0xfd, 0xfa, 0x20, 0x1c, 0xfc, + 0xf7, 0x62, 0xff, 0x60, 0x6a, 0xfd, 0x28, 0x37, + 0xd1, 0x70, 0x68, 0x01, 0x30, 0x70, 0x60, 0x30, + 0x69, 0x01, 0x30, 0x30, 0x61, 0x0b, 0x98, 0x00, + 0x09, 0x54, 0xd3, 0x60, 0x6f, 0x00, 0x28, 0x23, + 0xd0, 0xa0, 0x6b, 0x0a, 0x28, 0x4e, 0xd3, 0xe0, + 0x6b, 0xae, 0x1e, 0x31, 0x1a, 0x60, 0x6b, 0xf7, + 0xf7, 0x5e, 0xfd, 0x00, 0x29, 0x46, 0xd1, 0x84, + 0x4b, 0x20, 0x1c, 0xfa, 0x18, 0x31, 0x1c, 0x00, + 0xf0, 0xee, 0xf9, 0x60, 0x6f, 0xc0, 0x68, 0x0a, + 0x38, 0x06, 0x28, 0x3b, 0xd2, 0x02, 0xa3, 0x1b, + 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x03, + 0x03, 0x03, 0x03, 0x0a, 0x0a, 0x28, 0x1d, 0x05, + 0x01, 0x79, 0x4b, 0x2d, 0x09, 0xff, 0x18, 0x2d, + 0xe0, 0x2c, 0xe0, 0xe8, 0x1d, 0x01, 0x30, 0x05, + 0x01, 0x77, 0x4b, 0x2d, 0x09, 0xff, 0x18, 0x25, + 0xe0, 0xed, 0x09, 0x00, 0x89, 0x00, 0x00, 0x28, + 0x01, 0xd0, 0xff, 0x28, 0x21, 0xd1, 0x0b, 0x98, + 0x40, 0x0a, 0x05, 0xd3, 0x70, 0x68, 0x01, 0x30, + 0x70, 0x60, 0x30, 0x69, 0x01, 0x30, 0x30, 0x61, + 0x60, 0x68, 0xff, 0x30, 0x81, 0x30, 0x00, 0x69, + 0x80, 0x07, 0x12, 0xd1, 0x0a, 0x98, 0x40, 0x69, + 0x00, 0x28, 0x0e, 0xd1, 0xfb, 0xf7, 0xd8, 0xfb, + 0x69, 0x4b, 0x1a, 0x68, 0x5b, 0x68, 0x08, 0xf0, + 0x37, 0xfa, 0x00, 0x28, 0x05, 0xd0, 0x00, 0x20, + 0xfa, 0xf7, 0xf4, 0xf8, 0x00, 0x28, 0x00, 0xd0, + 0xfa, 0xe6, 0x64, 0x49, 0xff, 0x22, 0x38, 0x1c, + 0x09, 0x69, 0xb9, 0x32, 0xfc, 0xf7, 0xb2, 0xf9, + 0x00, 0x28, 0x05, 0xd1, 0x01, 0x20, 0x22, 0x1c, + 0x61, 0x68, 0xff, 0xf7, 0xf1, 0xfd, 0xeb, 0xe6, + 0x60, 0x68, 0xa1, 0x6a, 0x80, 0x30, 0xc2, 0x69, + 0x23, 0x69, 0x03, 0x92, 0x18, 0x0e, 0x1a, 0x02, + 0x12, 0x0a, 0x00, 0x92, 0x02, 0x91, 0x00, 0x21, + 0x00, 0x22, 0x1a, 0x23, 0x01, 0x90, 0x28, 0x1c, + 0xfc, 0xf7, 0xa4, 0xfb, 0x04, 0x90, 0x20, 0x69, + 0x00, 0x0e, 0x69, 0x08, 0x07, 0x91, 0x09, 0x02, + 0x08, 0x43, 0x51, 0x49, 0x48, 0x60, 0xe6, 0x1d, + 0xb9, 0x36, 0xb2, 0x68, 0x38, 0x1c, 0x03, 0x92, + 0x4e, 0x4a, 0x06, 0x92, 0x51, 0x69, 0x01, 0x29, + 0x75, 0xd0, 0x02, 0x29, 0x22, 0xd1, 0x09, 0x21, + 0x08, 0xf0, 0x18, 0xfa, 0xc8, 0x22, 0x08, 0xf0, + 0x1f, 0xfa, 0x34, 0x22, 0x08, 0xf0, 0x1c, 0xfa, + 0x50, 0x22, 0x08, 0xf0, 0x19, 0xfa, 0x0d, 0x22, + 0x08, 0xf0, 0x16, 0xfa, 0x04, 0x22, 0x08, 0xf0, + 0x13, 0xfa, 0x28, 0x22, 0x08, 0xf0, 0x10, 0xfa, + 0x04, 0x99, 0x02, 0x31, 0x09, 0x02, 0x10, 0x22, + 0x0a, 0x43, 0x3f, 0x49, 0x0a, 0x62, 0x03, 0x9a, + 0x42, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x11, 0x23, + 0x1a, 0x43, 0x4a, 0x62, 0xed, 0x09, 0x00, 0x8a, + 0x00, 0x3b, 0x4a, 0x3c, 0x49, 0x0a, 0x62, 0x08, + 0x60, 0xb1, 0x68, 0x06, 0x9a, 0x3a, 0x48, 0x52, + 0x69, 0x01, 0x2a, 0x59, 0xd0, 0x02, 0x2a, 0x05, + 0xd1, 0x40, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, + 0x23, 0x19, 0x43, 0x01, 0x62, 0xf8, 0x1d, 0x49, + 0x30, 0xff, 0x22, 0x34, 0x49, 0x02, 0x32, 0x0a, + 0x62, 0x08, 0x60, 0x33, 0x4a, 0xb0, 0x68, 0x11, + 0x6a, 0x52, 0x6a, 0x09, 0x0a, 0xff, 0x23, 0x1b, + 0x02, 0x1a, 0x40, 0x11, 0x43, 0x06, 0x9a, 0x52, + 0x69, 0x01, 0x2a, 0x3e, 0xd0, 0x02, 0x2a, 0x09, + 0xd1, 0xd2, 0x03, 0x08, 0x0c, 0x00, 0xd2, 0x00, + 0x22, 0x0a, 0x43, 0x01, 0x23, 0xdb, 0x03, 0x10, + 0x1c, 0x98, 0x43, 0x01, 0x1c, 0x03, 0x20, 0x00, + 0x04, 0x08, 0x40, 0x03, 0x23, 0x32, 0x6a, 0x1b, + 0x04, 0x13, 0x40, 0x03, 0x93, 0x23, 0x4b, 0x13, + 0x40, 0xdb, 0x00, 0x02, 0x93, 0x03, 0x9b, 0x98, + 0x42, 0x03, 0xd1, 0x02, 0x9b, 0x9a, 0x1a, 0x51, + 0x18, 0xc9, 0x08, 0x01, 0x22, 0x12, 0x04, 0x00, + 0x28, 0x00, 0xd1, 0x00, 0x22, 0x0a, 0x43, 0x32, + 0x62, 0x06, 0x9a, 0x38, 0x1c, 0x51, 0x69, 0x01, + 0x29, 0x00, 0xe0, 0x82, 0xe0, 0x73, 0xd0, 0x02, + 0x29, 0x05, 0xd1, 0x15, 0x49, 0x2d, 0x22, 0x0a, + 0x62, 0x2c, 0x22, 0x4a, 0x62, 0x3c, 0x38, 0x14, + 0x4a, 0x14, 0x49, 0x0a, 0x62, 0x08, 0x60, 0x0b, + 0x98, 0x13, 0x4b, 0x18, 0x40, 0x57, 0xd1, 0x25, + 0xe0, 0x92, 0xe0, 0x98, 0xe0, 0x68, 0x14, 0x04, + 0x20, 0xc4, 0x09, 0x00, 0x00, 0x1e, 0xfb, 0xff, + 0xff, 0x88, 0x13, 0x00, 0x00, 0x70, 0x14, 0x04, + 0x20, 0x00, 0x50, 0x00, 0xe0, 0x00, 0x51, 0x00, + 0xe0, 0x48, 0xe6, 0x03, 0x20, 0xa0, 0x55, 0x00, + 0xe0, 0x02, 0x05, 0x00, 0x00, 0x08, 0x53, 0x00, + 0xe0, 0xb0, 0x55, 0x00, 0xe0, 0x0c, 0x53, 0xed, + 0x09, 0x00, 0x8b, 0x00, 0x00, 0xe0, 0xd0, 0x55, + 0x00, 0xe0, 0xff, 0xff, 0xfc, 0xff, 0x02, 0x03, + 0x00, 0x00, 0x14, 0x53, 0x00, 0xe0, 0x09, 0x00, + 0x00, 0x40, 0x5b, 0x4a, 0xb1, 0x68, 0x10, 0x6a, + 0x52, 0x6a, 0x00, 0x0a, 0xff, 0x23, 0x1b, 0x02, + 0x1a, 0x40, 0x10, 0x43, 0x06, 0x9a, 0x52, 0x69, + 0x01, 0x2a, 0x5f, 0xd0, 0x02, 0x2a, 0x07, 0xd1, + 0xd2, 0x03, 0x01, 0x0c, 0x00, 0xd2, 0x00, 0x22, + 0x10, 0x43, 0x01, 0x23, 0xdb, 0x03, 0x98, 0x43, + 0x03, 0x22, 0x12, 0x04, 0x02, 0x40, 0x03, 0x23, + 0xf1, 0x69, 0x1b, 0x04, 0x0b, 0x40, 0x03, 0x93, + 0x4d, 0x4b, 0x0b, 0x40, 0xdb, 0x00, 0x02, 0x93, + 0x03, 0x9b, 0x9a, 0x42, 0x03, 0xd1, 0x02, 0x9b, + 0x59, 0x1a, 0x08, 0x18, 0xc0, 0x08, 0x01, 0x21, + 0x09, 0x04, 0x00, 0x2a, 0x00, 0xd1, 0x00, 0x21, + 0x08, 0x43, 0xf0, 0x61, 0x06, 0x9a, 0x50, 0x69, + 0x01, 0x28, 0x54, 0xd0, 0x02, 0x28, 0x06, 0xd1, + 0x40, 0x48, 0x2d, 0x22, 0x02, 0x62, 0x2c, 0x22, + 0x42, 0x62, 0x00, 0xe0, 0x3d, 0xe0, 0x3e, 0x4a, + 0x3f, 0x49, 0xf8, 0x1d, 0x21, 0x30, 0x0a, 0x62, + 0x08, 0x60, 0xb6, 0x6b, 0xe1, 0x6a, 0x38, 0x1c, + 0x00, 0x29, 0x46, 0xd0, 0x05, 0x24, 0x45, 0xe0, + 0x10, 0x21, 0x08, 0xf0, 0x20, 0xf9, 0xff, 0x22, + 0x05, 0x32, 0x08, 0xf0, 0x26, 0xf9, 0x46, 0x22, + 0x08, 0xf0, 0x23, 0xf9, 0x0d, 0x22, 0x08, 0xf0, + 0x20, 0xf9, 0x04, 0x22, 0x08, 0xf0, 0x1d, 0xf9, + 0x28, 0x22, 0x08, 0xf0, 0x1a, 0xf9, 0x04, 0x99, + 0x02, 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, + 0x2e, 0x49, 0x0a, 0x62, 0x03, 0x9a, 0x82, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, + 0x4a, 0x62, 0x08, 0xe7, 0x14, 0xe0, 0x80, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, + 0x01, 0x62, 0xed, 0x09, 0x00, 0x8c, 0x00, 0x12, + 0xe7, 0x01, 0x22, 0x12, 0x04, 0x00, 0x28, 0x00, + 0xd1, 0x00, 0x22, 0x11, 0x43, 0x2b, 0xe7, 0x22, + 0x49, 0x3d, 0x22, 0x0a, 0x62, 0x3e, 0x22, 0x4a, + 0x62, 0x46, 0x38, 0x4d, 0xe7, 0x01, 0x22, 0x12, + 0x04, 0x00, 0x29, 0x00, 0xd1, 0x00, 0x22, 0x10, + 0x43, 0x8c, 0xe7, 0x16, 0x48, 0x3d, 0x22, 0x02, + 0x62, 0x3e, 0x22, 0x42, 0x62, 0xad, 0xe7, 0x01, + 0x24, 0x06, 0x9a, 0x51, 0x69, 0x01, 0x29, 0x1a, + 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x09, 0x21, 0x08, + 0xf0, 0xd4, 0xf8, 0xc2, 0x1f, 0x14, 0x49, 0x21, + 0x3a, 0x8a, 0x60, 0xb0, 0x30, 0xc8, 0x60, 0x01, + 0x2e, 0x01, 0xd0, 0x03, 0x2e, 0x04, 0xd1, 0x07, + 0x98, 0x10, 0x4a, 0x08, 0x23, 0x1c, 0x43, 0x10, + 0x60, 0x32, 0x20, 0x0c, 0x60, 0x08, 0xf0, 0x63, + 0xfe, 0x0d, 0x4a, 0xa0, 0xc2, 0x67, 0xe5, 0x10, + 0x21, 0x08, 0xf0, 0xbb, 0xf8, 0x02, 0xaa, 0x03, + 0xc2, 0x02, 0x98, 0x03, 0x99, 0xe1, 0xe7, 0xc0, + 0x55, 0x00, 0xe0, 0xff, 0xff, 0xfc, 0xff, 0x02, + 0x03, 0x00, 0x00, 0x10, 0x53, 0x00, 0xe0, 0xa0, + 0x55, 0x00, 0xe0, 0xd0, 0x55, 0x00, 0xe0, 0x00, + 0x51, 0x00, 0xe0, 0x80, 0x55, 0x00, 0xe0, 0x68, + 0x14, 0x04, 0x20, 0xf0, 0xb5, 0x87, 0xb0, 0x07, + 0x1c, 0x00, 0x20, 0x78, 0x64, 0x0d, 0x1c, 0x00, + 0x21, 0x38, 0x1c, 0x14, 0x1c, 0x03, 0xf0, 0x7a, + 0xfe, 0x78, 0x6f, 0x00, 0x28, 0x73, 0xd0, 0x2d, + 0x01, 0x78, 0x68, 0x2d, 0x09, 0x80, 0x30, 0xc2, + 0x69, 0xb9, 0x6a, 0x3b, 0x69, 0x03, 0x92, 0x18, + 0x0e, 0x1a, 0x02, 0x12, 0x0a, 0x00, 0x92, 0x02, + 0x91, 0x00, 0x21, 0x00, 0x22, 0x1a, 0x23, 0x01, + 0x90, 0x28, 0x1c, 0xfc, 0xf7, 0xf6, 0xf9, 0x04, + 0x90, 0x38, 0x69, 0x00, 0x0e, 0x69, 0x08, 0x06, + 0x91, 0x09, 0x02, 0x08, 0x43, 0xed, 0x09, 0x00, + 0x8d, 0x00, 0x59, 0x49, 0x48, 0x60, 0xfd, 0x1d, + 0xb9, 0x35, 0x2a, 0x69, 0xee, 0x68, 0x02, 0x92, + 0x6a, 0x69, 0x56, 0x48, 0x03, 0x92, 0x05, 0x90, + 0x40, 0x69, 0x01, 0x28, 0x4d, 0xd0, 0x02, 0x28, + 0x2c, 0xd1, 0x53, 0x49, 0x03, 0x20, 0xc8, 0x62, + 0x06, 0x21, 0x20, 0x1c, 0x08, 0xf0, 0x76, 0xf8, + 0xc8, 0x22, 0x08, 0xf0, 0x6b, 0xf8, 0x02, 0x9a, + 0x52, 0x00, 0x08, 0xf0, 0x67, 0xf8, 0x28, 0x22, + 0x08, 0xf0, 0x64, 0xf8, 0x03, 0x22, 0x08, 0xf0, + 0x71, 0xf8, 0x04, 0x99, 0x48, 0x4a, 0x02, 0x31, + 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x11, 0x62, + 0xf1, 0x00, 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, + 0x11, 0x23, 0x19, 0x43, 0x51, 0x62, 0x03, 0x9a, + 0x11, 0x02, 0x16, 0x23, 0x40, 0x4a, 0x19, 0x43, + 0x91, 0x62, 0x40, 0x49, 0x08, 0x60, 0x05, 0x20, + 0x00, 0x02, 0x08, 0x62, 0xe9, 0x68, 0x05, 0x98, + 0x42, 0x69, 0x3d, 0x48, 0x01, 0x2a, 0x42, 0xd0, + 0x02, 0x2a, 0x06, 0xd1, 0xc9, 0x00, 0x40, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, + 0x01, 0x62, 0xe0, 0x1d, 0x5d, 0x30, 0xff, 0x22, + 0x36, 0x49, 0x02, 0x32, 0x0a, 0x62, 0x08, 0x60, + 0xae, 0x6b, 0xf9, 0x6a, 0x20, 0x1c, 0x00, 0x29, + 0x35, 0xd0, 0x00, 0xe0, 0x4c, 0xe0, 0x05, 0x25, + 0x32, 0xe0, 0x06, 0x21, 0x20, 0x1c, 0x08, 0xf0, + 0x2d, 0xf8, 0xff, 0x22, 0x05, 0x32, 0x08, 0xf0, + 0x21, 0xf8, 0x02, 0x9a, 0x52, 0x00, 0x08, 0xf0, + 0x1d, 0xf8, 0x28, 0x22, 0x08, 0xf0, 0x1a, 0xf8, + 0x03, 0x22, 0x08, 0xf0, 0x27, 0xf8, 0x04, 0x99, + 0x02, 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, + 0x21, 0x49, 0x0a, 0x62, 0xf2, 0x00, 0x84, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, + 0x4a, 0x62, 0x03, 0x9a, 0x12, 0x02, 0x19, 0x23, + 0xed, 0x09, 0x00, 0x8e, 0x00, 0x1a, 0x43, 0x8a, + 0x62, 0x1b, 0x49, 0x08, 0x60, 0x1d, 0x48, 0x08, + 0x62, 0xb6, 0xe7, 0xc9, 0x00, 0x80, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, + 0x62, 0xbd, 0xe7, 0x01, 0x25, 0x05, 0x99, 0x49, + 0x69, 0x01, 0x29, 0x17, 0xd0, 0x02, 0x29, 0x02, + 0xd1, 0x06, 0x21, 0x07, 0xf0, 0xf5, 0xff, 0x0d, + 0x49, 0x88, 0x60, 0x02, 0x2e, 0x01, 0xd0, 0x03, + 0x2e, 0x04, 0xd1, 0x06, 0x98, 0x10, 0x4a, 0x08, + 0x23, 0x1d, 0x43, 0x10, 0x60, 0x0d, 0x60, 0x78, + 0x6f, 0xfb, 0xf7, 0x4c, 0xfd, 0x07, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x21, 0x07, + 0xf0, 0xdf, 0xff, 0x02, 0xaa, 0x03, 0xc2, 0x02, + 0x98, 0x03, 0x99, 0xe4, 0xe7, 0x00, 0x52, 0x00, + 0xe0, 0x48, 0xe6, 0x03, 0x20, 0x80, 0x55, 0x00, + 0xe0, 0x00, 0x53, 0x00, 0xe0, 0x90, 0x55, 0x00, + 0xe0, 0x04, 0x53, 0x00, 0xe0, 0x03, 0x05, 0x00, + 0x00, 0x80, 0x57, 0x00, 0xe0, 0xf0, 0xb5, 0x87, + 0xb0, 0x0d, 0x1c, 0x19, 0x1c, 0x14, 0x1c, 0x07, + 0x1c, 0xfc, 0xf7, 0x11, 0xfd, 0xb8, 0x6f, 0x00, + 0x28, 0x73, 0xd0, 0x2d, 0x01, 0x78, 0x68, 0x2d, + 0x09, 0x80, 0x30, 0xc2, 0x69, 0xb9, 0x6a, 0x3b, + 0x69, 0x03, 0x92, 0x18, 0x0e, 0x1a, 0x02, 0x12, + 0x0a, 0x00, 0x92, 0x02, 0x91, 0x00, 0x21, 0x00, + 0x22, 0x1a, 0x23, 0x01, 0x90, 0x28, 0x1c, 0xfc, + 0xf7, 0x0d, 0xf9, 0x04, 0x90, 0x38, 0x69, 0x00, + 0x0e, 0x69, 0x08, 0x06, 0x91, 0x09, 0x02, 0x08, + 0x43, 0x59, 0x49, 0x48, 0x60, 0xfd, 0x1d, 0xb9, + 0x35, 0x2a, 0x69, 0xee, 0x68, 0x02, 0x92, 0x6a, + 0x69, 0x56, 0x48, 0x03, 0x92, 0x05, 0x90, 0x40, + 0x69, 0x01, 0x28, 0x4d, 0xd0, 0x02, 0x28, 0x2c, + 0xd1, 0x53, 0x49, 0x03, 0x20, 0xc8, 0x62, 0x06, + 0x21, 0x20, 0x1c, 0xed, 0x09, 0x00, 0x8f, 0x00, + 0x07, 0xf0, 0x8d, 0xff, 0xc8, 0x22, 0x07, 0xf0, + 0x82, 0xff, 0x02, 0x9a, 0x52, 0x00, 0x07, 0xf0, + 0x7e, 0xff, 0x28, 0x22, 0x07, 0xf0, 0x7b, 0xff, + 0x03, 0x22, 0x07, 0xf0, 0x88, 0xff, 0x04, 0x99, + 0x49, 0x4a, 0x02, 0x31, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0x11, 0x62, 0xf1, 0x00, 0x44, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, + 0x51, 0x62, 0x03, 0x9a, 0x11, 0x02, 0x16, 0x23, + 0x41, 0x4a, 0x19, 0x43, 0x91, 0x62, 0x40, 0x49, + 0x08, 0x60, 0x05, 0x20, 0x00, 0x02, 0x08, 0x62, + 0xe9, 0x68, 0x05, 0x98, 0x42, 0x69, 0x3d, 0x48, + 0x01, 0x2a, 0x42, 0xd0, 0x02, 0x2a, 0x06, 0xd1, + 0xc9, 0x00, 0x40, 0x23, 0x19, 0x43, 0x09, 0x02, + 0x11, 0x23, 0x19, 0x43, 0x01, 0x62, 0xe0, 0x1d, + 0x5d, 0x30, 0xff, 0x22, 0x37, 0x49, 0x02, 0x32, + 0x0a, 0x62, 0x08, 0x60, 0xae, 0x6b, 0xf9, 0x6a, + 0x20, 0x1c, 0x00, 0x29, 0x35, 0xd0, 0x00, 0xe0, + 0x4c, 0xe0, 0x05, 0x25, 0x32, 0xe0, 0x06, 0x21, + 0x20, 0x1c, 0x07, 0xf0, 0x44, 0xff, 0xff, 0x22, + 0x05, 0x32, 0x07, 0xf0, 0x38, 0xff, 0x02, 0x9a, + 0x52, 0x00, 0x07, 0xf0, 0x34, 0xff, 0x28, 0x22, + 0x07, 0xf0, 0x31, 0xff, 0x03, 0x22, 0x07, 0xf0, + 0x3e, 0xff, 0x04, 0x99, 0x02, 0x31, 0x09, 0x02, + 0x20, 0x22, 0x0a, 0x43, 0x22, 0x49, 0x0a, 0x62, + 0xf2, 0x00, 0x84, 0x23, 0x1a, 0x43, 0x12, 0x02, + 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x03, 0x9a, + 0x12, 0x02, 0x19, 0x23, 0x1a, 0x43, 0x8a, 0x62, + 0x1c, 0x49, 0x08, 0x60, 0x1e, 0x48, 0x08, 0x62, + 0xb6, 0xe7, 0xc9, 0x00, 0x80, 0x23, 0x19, 0x43, + 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, 0x62, + 0xbd, 0xe7, 0x01, 0x25, 0x05, 0x99, 0x49, 0x69, + 0x01, 0x29, 0x17, 0xd0, 0x02, 0x29, 0xed, 0x09, + 0x00, 0x90, 0x00, 0x02, 0xd1, 0x06, 0x21, 0x07, + 0xf0, 0x0c, 0xff, 0x0d, 0x49, 0x88, 0x60, 0x02, + 0x2e, 0x01, 0xd0, 0x03, 0x2e, 0x04, 0xd1, 0x06, + 0x98, 0x11, 0x4a, 0x08, 0x23, 0x1d, 0x43, 0x10, + 0x60, 0x0d, 0x60, 0xb8, 0x6f, 0xfb, 0xf7, 0x63, + 0xfc, 0x07, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x06, 0x21, 0x07, 0xf0, 0xf6, 0xfe, 0x02, + 0xaa, 0x03, 0xc2, 0x02, 0x98, 0x03, 0x99, 0xe4, + 0xe7, 0x00, 0x00, 0x00, 0x52, 0x00, 0xe0, 0x48, + 0xe6, 0x03, 0x20, 0x80, 0x55, 0x00, 0xe0, 0x00, + 0x53, 0x00, 0xe0, 0x90, 0x55, 0x00, 0xe0, 0x04, + 0x53, 0x00, 0xe0, 0x03, 0x05, 0x00, 0x00, 0x80, + 0x57, 0x00, 0xe0, 0xf0, 0xb5, 0x00, 0x24, 0xc6, + 0x1d, 0xb9, 0x36, 0xcc, 0x60, 0x05, 0x1c, 0xf0, + 0x69, 0x0f, 0x1c, 0x88, 0x64, 0x08, 0x6b, 0x00, + 0x28, 0x02, 0xd0, 0xf7, 0xf7, 0x02, 0xfe, 0x3c, + 0x63, 0xf8, 0x69, 0x00, 0x28, 0x02, 0xd0, 0xf7, + 0xf7, 0xfc, 0xfd, 0xfc, 0x61, 0xf7, 0xf7, 0xfe, + 0xfd, 0x04, 0x1c, 0x05, 0xd1, 0x38, 0x1c, 0xf7, + 0xf7, 0x5a, 0xfe, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x35, 0x20, 0x20, 0x60, 0x68, 0x68, 0x40, + 0x68, 0xe0, 0x60, 0x0e, 0x20, 0x21, 0x1c, 0x27, + 0x61, 0xf7, 0xf7, 0x5b, 0xfe, 0x00, 0x28, 0x06, + 0xd0, 0x38, 0x1c, 0xf7, 0xf7, 0x48, 0xfe, 0x20, + 0x1c, 0xf7, 0xf7, 0x1f, 0xfe, 0xe9, 0xe7, 0x70, + 0x6a, 0x01, 0x38, 0x70, 0x62, 0xe5, 0xe7, 0xf0, + 0xb5, 0x99, 0xb0, 0xfb, 0x48, 0x47, 0x69, 0x44, + 0x68, 0x05, 0x68, 0x78, 0x68, 0x0f, 0x90, 0x00, + 0x20, 0x08, 0x90, 0xf8, 0x48, 0x00, 0x26, 0x00, + 0x69, 0x04, 0x90, 0xfa, 0xf7, 0xec, 0xff, 0x05, + 0x90, 0xf6, 0x48, 0x06, 0x91, 0x18, 0x90, 0x40, + 0x69, 0x01, 0x28, 0x2a, 0xd0, 0x02, 0x28, 0x04, + 0xd1, 0xed, 0x09, 0x00, 0x91, 0x00, 0x8e, 0x21, + 0x04, 0x98, 0x07, 0xf0, 0x8d, 0xfe, 0x04, 0x90, + 0x04, 0x98, 0x05, 0x99, 0x88, 0x42, 0x02, 0xd9, + 0x06, 0x98, 0x01, 0x38, 0x06, 0x90, 0x04, 0x98, + 0x06, 0x99, 0x05, 0x90, 0x10, 0x90, 0xeb, 0x48, + 0x11, 0x91, 0x80, 0x6a, 0x41, 0x07, 0x49, 0x0f, + 0x42, 0x06, 0x0d, 0xab, 0x19, 0x70, 0x12, 0x0f, + 0x0e, 0x92, 0x02, 0x06, 0xd2, 0x0f, 0x5a, 0x70, + 0xc2, 0x05, 0xd2, 0x0f, 0x80, 0x05, 0xc0, 0x0f, + 0x9a, 0x70, 0xd8, 0x70, 0x38, 0x7e, 0x88, 0x42, + 0x08, 0xd0, 0x01, 0x21, 0x0b, 0x91, 0x71, 0xe0, + 0x95, 0x21, 0x04, 0x98, 0x07, 0xf0, 0x64, 0xfe, + 0x04, 0x90, 0xd5, 0xe7, 0x00, 0x21, 0x0b, 0x91, + 0x0d, 0xa8, 0x80, 0x78, 0x01, 0x28, 0x47, 0xd1, + 0xf8, 0x68, 0x03, 0x28, 0x07, 0xd1, 0x2c, 0xf0, + 0xe7, 0xfb, 0x00, 0x22, 0x01, 0x21, 0x38, 0x1c, + 0x03, 0xf0, 0x93, 0xfd, 0x3c, 0xe0, 0x78, 0x6f, + 0x07, 0x90, 0x00, 0x28, 0x38, 0xd0, 0x78, 0x6a, + 0xfd, 0x28, 0x35, 0xd0, 0xf8, 0x1d, 0x79, 0x30, + 0x17, 0x90, 0xc0, 0x68, 0x00, 0x28, 0x01, 0xd1, + 0x78, 0x67, 0x2d, 0xe0, 0x38, 0x1c, 0x03, 0xf0, + 0x99, 0xfe, 0x00, 0x28, 0x1b, 0xd1, 0x07, 0x98, + 0xc9, 0x49, 0xc0, 0x68, 0xc3, 0x00, 0x18, 0x18, + 0x80, 0x00, 0x40, 0x18, 0xc0, 0x69, 0x00, 0x28, + 0x0c, 0xd0, 0x01, 0x21, 0xfa, 0x6d, 0x08, 0x1c, + 0x00, 0x2a, 0x00, 0xd0, 0x00, 0x20, 0xf8, 0x65, + 0xf8, 0x1d, 0xb9, 0x30, 0xf9, 0x66, 0xc1, 0x6b, + 0x01, 0x31, 0xc1, 0x63, 0x07, 0x98, 0x39, 0x1c, + 0x03, 0xf0, 0x77, 0xfe, 0x0c, 0xe0, 0x17, 0x98, + 0x40, 0x68, 0x17, 0x99, 0x08, 0x90, 0x00, 0x20, + 0x48, 0x60, 0x07, 0x99, 0xce, 0x6b, 0xc8, 0x63, + 0x17, 0x99, 0xc9, 0x68, 0x09, 0x91, 0x78, 0x67, + 0x78, 0x6e, 0x40, 0x08, 0xed, 0x09, 0x00, 0x92, + 0x00, 0x07, 0xd3, 0x0d, 0xa8, 0x40, 0x78, 0x00, + 0x28, 0x03, 0xd0, 0x01, 0x21, 0x38, 0x1c, 0x03, + 0xf0, 0xed, 0xfd, 0x78, 0x6e, 0x40, 0x08, 0x07, + 0xd2, 0x0d, 0xa8, 0x40, 0x78, 0x00, 0x28, 0x03, + 0xd1, 0x01, 0x21, 0x38, 0x1c, 0x03, 0xf0, 0xc8, + 0xfd, 0xf8, 0x1d, 0xf9, 0x30, 0x41, 0x68, 0x01, + 0x31, 0x41, 0x60, 0x0d, 0xa8, 0x80, 0x78, 0x78, + 0x64, 0x38, 0x7e, 0x0d, 0xa9, 0x09, 0x78, 0x88, + 0x42, 0x09, 0xd1, 0x10, 0x98, 0x11, 0x99, 0x22, + 0x1a, 0x0f, 0x98, 0x29, 0x1c, 0x00, 0xf0, 0x96, + 0xfb, 0x24, 0x1a, 0x00, 0x20, 0xb8, 0x64, 0x00, + 0x20, 0x0a, 0x90, 0x0e, 0x98, 0x10, 0x28, 0x44, + 0xd2, 0x01, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, + 0x44, 0x40, 0x3d, 0x40, 0x33, 0x33, 0x07, 0x07, + 0x07, 0x31, 0x40, 0x0c, 0x0c, 0x16, 0x16, 0x1e, + 0x1e, 0x01, 0x20, 0x0a, 0x90, 0x0e, 0x98, 0x0c, + 0x90, 0x35, 0xe0, 0x0d, 0xa9, 0xc9, 0x78, 0x38, + 0x6c, 0x88, 0x42, 0x02, 0xd1, 0x01, 0x21, 0x39, + 0x66, 0x01, 0xe0, 0x00, 0x20, 0x38, 0x66, 0x00, + 0x20, 0x0c, 0x90, 0x28, 0x1d, 0x05, 0x01, 0x8e, + 0x4b, 0x2d, 0x09, 0xe4, 0x18, 0x23, 0xe0, 0x0d, + 0xa9, 0xc9, 0x78, 0x38, 0x6c, 0x88, 0x42, 0x02, + 0xd1, 0x01, 0x21, 0x39, 0x66, 0x01, 0xe0, 0x00, + 0x20, 0x38, 0x66, 0x00, 0x20, 0x0c, 0x90, 0xe8, + 0x1d, 0x01, 0x30, 0x05, 0x01, 0x85, 0x4b, 0x2d, + 0x09, 0xe4, 0x18, 0x10, 0xe0, 0x01, 0x20, 0x0a, + 0x90, 0x0d, 0xa9, 0xc9, 0x78, 0x38, 0x6c, 0x88, + 0x42, 0x02, 0xd1, 0x01, 0x21, 0x39, 0x66, 0x01, + 0xe0, 0x00, 0x20, 0x38, 0x66, 0x00, 0x20, 0x0c, + 0x90, 0x01, 0xe0, 0x11, 0x20, 0x0c, 0x90, 0x0b, + 0x99, 0x7b, 0x48, 0x01, 0x29, 0x0f, 0xd1, 0x73, + 0x49, 0x4c, 0x60, 0x0d, 0x60, 0x72, 0x49, 0xed, + 0x09, 0x00, 0x93, 0x00, 0x00, 0x25, 0x0d, 0x60, + 0x17, 0x21, 0x49, 0x01, 0xc1, 0x60, 0x00, 0x20, + 0xff, 0xf7, 0xf3, 0xf9, 0x19, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x0e, 0x99, 0x01, 0x29, + 0x09, 0xd1, 0x79, 0x6a, 0xfd, 0x29, 0x06, 0xd1, + 0xb9, 0x6b, 0x0a, 0x29, 0x01, 0xd2, 0x01, 0x31, + 0xb9, 0x63, 0xa9, 0x1c, 0xf9, 0x63, 0x0e, 0x99, + 0x03, 0x29, 0x03, 0xd0, 0x04, 0x29, 0x01, 0xd0, + 0x08, 0x29, 0x22, 0xd1, 0x00, 0x68, 0x80, 0x09, + 0x1f, 0xd3, 0x62, 0x48, 0x00, 0x6a, 0x06, 0xab, + 0x18, 0x70, 0x06, 0x98, 0x80, 0x07, 0x80, 0x0f, + 0x03, 0x28, 0x14, 0xd0, 0x78, 0x6e, 0x02, 0x23, + 0x18, 0x40, 0x07, 0xd0, 0x06, 0x99, 0xc9, 0x08, + 0x04, 0xd3, 0x02, 0x21, 0x38, 0x1c, 0x03, 0xf0, + 0x40, 0xfd, 0x08, 0xe0, 0x00, 0x28, 0x06, 0xd1, + 0x06, 0x98, 0xc0, 0x08, 0x03, 0xd2, 0x02, 0x21, + 0x38, 0x1c, 0x03, 0xf0, 0x1c, 0xfd, 0x01, 0x21, + 0x39, 0x66, 0x0a, 0x98, 0x01, 0x28, 0x1a, 0xd1, + 0xf8, 0x1d, 0xf9, 0x30, 0x16, 0x90, 0x40, 0x69, + 0x15, 0x90, 0x00, 0x28, 0x13, 0xd0, 0xa9, 0x1c, + 0x15, 0x98, 0x14, 0x91, 0x40, 0x6a, 0xf6, 0xf7, + 0xf2, 0xff, 0x15, 0x98, 0x4f, 0x4b, 0x01, 0x62, + 0x16, 0x98, 0x01, 0x21, 0x40, 0x69, 0xe2, 0x18, + 0xc1, 0x61, 0x14, 0x99, 0x0c, 0x9b, 0x38, 0x1c, + 0xff, 0xf7, 0x69, 0xfd, 0x7d, 0xe0, 0x0c, 0x99, + 0x38, 0x1c, 0x03, 0xf0, 0xfd, 0xfa, 0x78, 0x6f, + 0x00, 0x28, 0x76, 0xd0, 0x45, 0x4b, 0xa8, 0x1c, + 0xe1, 0x18, 0x00, 0x01, 0x00, 0x09, 0x05, 0x90, + 0x04, 0x91, 0x78, 0x68, 0xb9, 0x6a, 0x80, 0x30, + 0xc2, 0x69, 0x3b, 0x69, 0x03, 0x92, 0x18, 0x0e, + 0x1a, 0x02, 0x12, 0x0a, 0x00, 0x92, 0x00, 0x22, + 0x1a, 0x23, 0x01, 0x90, 0x02, 0x91, 0x00, 0x21, + 0x05, 0x98, 0xed, 0x09, 0x00, 0x94, 0x00, 0xfb, + 0xf7, 0x74, 0xfe, 0x06, 0x90, 0x38, 0x69, 0x05, + 0x99, 0x00, 0x0e, 0x49, 0x08, 0x13, 0x91, 0x09, + 0x02, 0x08, 0x43, 0x35, 0x49, 0x48, 0x60, 0xf8, + 0x1d, 0xb9, 0x30, 0x12, 0x90, 0x04, 0x99, 0xc2, + 0x68, 0x01, 0x92, 0x02, 0x69, 0x02, 0x92, 0x40, + 0x69, 0x03, 0x90, 0x18, 0x98, 0x40, 0x69, 0x01, + 0x28, 0x48, 0xd0, 0x02, 0x28, 0x2d, 0xd1, 0x2d, + 0x4a, 0x03, 0x20, 0xd0, 0x62, 0x08, 0x1c, 0x06, + 0x21, 0x07, 0xf0, 0xf1, 0xfc, 0xc8, 0x22, 0x07, + 0xf0, 0xe6, 0xfc, 0x02, 0x9a, 0x52, 0x00, 0x07, + 0xf0, 0xe2, 0xfc, 0x28, 0x22, 0x07, 0xf0, 0xdf, + 0xfc, 0x03, 0x22, 0x07, 0xf0, 0xec, 0xfc, 0x06, + 0x99, 0x23, 0x4a, 0x02, 0x31, 0x09, 0x02, 0x10, + 0x23, 0x19, 0x43, 0x11, 0x62, 0x01, 0x9a, 0xd1, + 0x00, 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, + 0x23, 0x1d, 0x4a, 0x19, 0x43, 0x51, 0x62, 0x03, + 0x99, 0x09, 0x02, 0x16, 0x23, 0x19, 0x43, 0x91, + 0x62, 0x1a, 0x49, 0x08, 0x60, 0x05, 0x20, 0x00, + 0x02, 0x08, 0x62, 0x12, 0x98, 0x04, 0x99, 0xc2, + 0x68, 0x18, 0x98, 0x43, 0x69, 0x16, 0x48, 0x01, + 0x2b, 0x64, 0xd0, 0x02, 0x2b, 0x06, 0xd1, 0xd2, + 0x00, 0x40, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x11, + 0x23, 0x1a, 0x43, 0x02, 0x62, 0xc8, 0x1d, 0x5d, + 0x30, 0xff, 0x22, 0x02, 0x32, 0x00, 0xe0, 0x9d, + 0xe0, 0x0e, 0x49, 0x1c, 0xe0, 0x27, 0xe0, 0x68, + 0x14, 0x04, 0x20, 0x00, 0x51, 0x00, 0xe0, 0x48, + 0xe6, 0x03, 0x20, 0x40, 0x55, 0x00, 0xe0, 0x78, + 0x7b, 0x03, 0x20, 0xc4, 0x09, 0x00, 0x00, 0x88, + 0x13, 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, 0xe2, + 0x04, 0x00, 0x00, 0x00, 0x52, 0x00, 0xe0, 0x80, + 0x55, 0x00, 0xe0, 0x00, 0x53, 0x00, 0xe0, 0x90, + 0x55, 0x00, 0xe0, 0x04, 0x53, 0xed, 0x09, 0x00, + 0x95, 0x00, 0x00, 0xe0, 0x0a, 0x62, 0x08, 0x60, + 0x12, 0x99, 0x04, 0x98, 0x89, 0x6b, 0x03, 0x91, + 0xf9, 0x6a, 0x00, 0x29, 0x36, 0xd0, 0x05, 0x21, + 0x02, 0x91, 0x35, 0xe0, 0x08, 0x1c, 0x06, 0x21, + 0x07, 0xf0, 0x84, 0xfc, 0xff, 0x22, 0x05, 0x32, + 0x07, 0xf0, 0x78, 0xfc, 0x02, 0x9a, 0x52, 0x00, + 0x07, 0xf0, 0x74, 0xfc, 0x28, 0x22, 0x07, 0xf0, + 0x71, 0xfc, 0x03, 0x22, 0x07, 0xf0, 0x7e, 0xfc, + 0x06, 0x99, 0x02, 0x31, 0x09, 0x02, 0x20, 0x22, + 0x0a, 0x43, 0x59, 0x49, 0x0a, 0x62, 0x01, 0x9a, + 0xd2, 0x00, 0x84, 0x23, 0x1a, 0x43, 0x12, 0x02, + 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x03, 0x9a, + 0x12, 0x02, 0x19, 0x23, 0x1a, 0x43, 0x8a, 0x62, + 0x52, 0x49, 0x08, 0x60, 0x52, 0x48, 0x08, 0x62, + 0x92, 0xe7, 0xff, 0xe7, 0xd2, 0x00, 0x80, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, + 0x02, 0x62, 0x9a, 0xe7, 0x01, 0x21, 0x02, 0x91, + 0x18, 0x99, 0x49, 0x69, 0x01, 0x29, 0x24, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, 0x07, 0xf0, + 0x49, 0xfc, 0x48, 0x49, 0x88, 0x60, 0x03, 0x98, + 0x02, 0x28, 0x02, 0xd0, 0x03, 0x98, 0x03, 0x28, + 0x06, 0xd1, 0x02, 0x98, 0x08, 0x23, 0x18, 0x43, + 0x02, 0x90, 0x13, 0x98, 0x42, 0x4a, 0x10, 0x60, + 0x02, 0x98, 0x08, 0x60, 0x78, 0x6f, 0xfb, 0xf7, + 0x9b, 0xf9, 0x78, 0x6f, 0xc0, 0x68, 0x0a, 0x38, + 0x06, 0x28, 0x1a, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, + 0x5b, 0x00, 0x9f, 0x44, 0x0a, 0x0a, 0x0a, 0x0a, + 0x10, 0x10, 0x06, 0x21, 0x07, 0xf0, 0x26, 0xfc, + 0x6a, 0x46, 0x03, 0xc2, 0x00, 0x98, 0x01, 0x99, + 0xd7, 0xe7, 0x28, 0x1d, 0x05, 0x01, 0x35, 0x4b, + 0x2d, 0x09, 0xe4, 0x18, 0x05, 0xe0, 0xe8, 0x1d, + 0x01, 0x30, 0x05, 0x01, 0x32, 0x4b, 0x2d, 0x09, + 0xed, 0x09, 0x00, 0x96, 0x00, 0xe4, 0x18, 0x32, + 0x48, 0x44, 0x60, 0x05, 0x60, 0x00, 0x20, 0xff, + 0xf7, 0x77, 0xf8, 0x08, 0x98, 0x00, 0x28, 0x10, + 0xd0, 0x00, 0x2e, 0x13, 0xd0, 0x34, 0x20, 0x30, + 0x60, 0xb8, 0x68, 0xf0, 0x60, 0x00, 0x20, 0x30, + 0x61, 0x08, 0x98, 0x70, 0x61, 0x09, 0x99, 0x0e, + 0x20, 0xb1, 0x61, 0x31, 0x1c, 0xf7, 0xf7, 0xa0, + 0xfb, 0x04, 0xe0, 0x00, 0x2e, 0x02, 0xd0, 0x30, + 0x1c, 0xf7, 0xf7, 0x66, 0xfb, 0xfc, 0x1d, 0x79, + 0x34, 0x60, 0x69, 0x04, 0x28, 0x30, 0xd1, 0xf7, + 0xf7, 0x24, 0xfb, 0x00, 0x28, 0x2c, 0xd0, 0x41, + 0x21, 0x01, 0x60, 0x79, 0x68, 0x00, 0x25, 0x81, + 0x61, 0x47, 0x61, 0x79, 0x68, 0x49, 0x68, 0x01, + 0x61, 0x39, 0x7e, 0xc1, 0x60, 0xc5, 0x61, 0x01, + 0x1c, 0x0e, 0x20, 0xf7, 0xf7, 0x81, 0xfb, 0x65, + 0x61, 0x79, 0x68, 0xc0, 0x37, 0x78, 0x68, 0x44, + 0x68, 0xa1, 0x42, 0x13, 0xd0, 0xc5, 0x60, 0x20, + 0x1c, 0xfa, 0xf7, 0x8f, 0xfe, 0x00, 0x28, 0x05, + 0xd1, 0x78, 0x68, 0x45, 0x60, 0x20, 0x1c, 0xfa, + 0xf7, 0xd5, 0xfe, 0x09, 0xe0, 0x78, 0x68, 0x80, + 0x30, 0x85, 0x61, 0x78, 0x68, 0x02, 0x21, 0xf9, + 0xf7, 0x89, 0xf8, 0x01, 0xe0, 0x80, 0x30, 0x85, + 0x61, 0x33, 0xe6, 0x00, 0x00, 0x80, 0x55, 0x00, + 0xe0, 0x00, 0x53, 0x00, 0xe0, 0x03, 0x05, 0x00, + 0x00, 0x00, 0x52, 0x00, 0xe0, 0x80, 0x57, 0x00, + 0xe0, 0xc4, 0x09, 0x00, 0x00, 0x88, 0x13, 0x00, + 0x00, 0x68, 0x14, 0x04, 0x20, 0x80, 0xb5, 0x1b, + 0x49, 0x4f, 0x69, 0xf9, 0x1d, 0xf9, 0x31, 0xca, + 0x68, 0x01, 0x32, 0xca, 0x60, 0x79, 0x6a, 0xfe, + 0x29, 0x0a, 0xd1, 0xff, 0x23, 0xcd, 0x33, 0x18, + 0x40, 0x06, 0xd1, 0x11, 0x20, 0x40, 0x01, 0x00, + 0xf0, 0x29, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf8, 0x1d, 0xed, 0x09, 0x00, 0x97, 0x00, + 0xb9, 0x30, 0x40, 0x6a, 0x00, 0x28, 0xf7, 0xd0, + 0xf7, 0xf7, 0x06, 0xfb, 0x00, 0x28, 0xf3, 0xd0, + 0x0d, 0x4a, 0xc1, 0x1d, 0x92, 0x6a, 0x01, 0x31, + 0x53, 0x07, 0x5b, 0x0f, 0x0b, 0x70, 0x53, 0x06, + 0x1b, 0x0f, 0x4b, 0x60, 0x13, 0x06, 0xdb, 0x0f, + 0x4b, 0x70, 0xd3, 0x05, 0xdb, 0x0f, 0x92, 0x05, + 0xd2, 0x0f, 0x8b, 0x70, 0xca, 0x70, 0x01, 0x1c, + 0x38, 0x1c, 0xff, 0xf7, 0x98, 0xfc, 0xdb, 0xe7, + 0x00, 0x00, 0x68, 0x14, 0x04, 0x20, 0x40, 0x55, + 0x00, 0xe0, 0xf8, 0xb5, 0x07, 0x1c, 0x8b, 0x48, + 0x00, 0x22, 0x01, 0x69, 0x44, 0x69, 0x00, 0x91, + 0x8a, 0x49, 0x40, 0x68, 0x09, 0x69, 0xfb, 0xf7, + 0xbc, 0xfa, 0x01, 0x26, 0x76, 0x02, 0x3e, 0x40, + 0x00, 0x28, 0x0d, 0xd1, 0x00, 0x2e, 0x04, 0xd0, + 0xe0, 0x1d, 0xf9, 0x30, 0xc1, 0x68, 0x01, 0x39, + 0xc1, 0x60, 0x08, 0x20, 0x38, 0x43, 0xff, 0xf7, + 0xa8, 0xff, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x01, 0x21, 0x00, 0x2e, 0x00, 0xd0, 0x00, 0x21, + 0x38, 0x1c, 0xfa, 0xf7, 0x0c, 0xff, 0x07, 0x1c, + 0x09, 0xd1, 0x00, 0x20, 0x20, 0x66, 0xfb, 0xf7, + 0x9a, 0xf8, 0xe0, 0x1d, 0xf9, 0x30, 0xc1, 0x68, + 0x01, 0x31, 0xc1, 0x60, 0xe9, 0xe7, 0xe5, 0x1d, + 0xb9, 0x35, 0xe8, 0x69, 0xb8, 0x64, 0x60, 0x6a, + 0xfd, 0x28, 0x4a, 0xd0, 0xfe, 0x28, 0x48, 0xd1, + 0x20, 0x6b, 0x00, 0x28, 0x13, 0xd0, 0x00, 0x6b, + 0x00, 0x28, 0x01, 0xd0, 0xf7, 0xf7, 0x5f, 0xfa, + 0x20, 0x6b, 0x00, 0x21, 0x01, 0x63, 0x20, 0x6b, + 0xc0, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xf7, 0xf7, + 0x56, 0xfa, 0x20, 0x6b, 0x00, 0x21, 0xc1, 0x61, + 0x20, 0x6b, 0xf7, 0xf7, 0xb6, 0xfa, 0x78, 0x69, + 0x03, 0x28, 0x05, 0xd1, 0xf8, 0x68, 0x03, 0x28, + 0x02, 0xd1, 0x00, 0x20, 0x20, 0x63, 0xed, 0x09, + 0x00, 0x98, 0x00, 0x28, 0xe0, 0xf8, 0x68, 0x10, + 0x28, 0x15, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x11, 0x0f, 0x11, 0x07, 0x07, + 0x11, 0x11, 0x11, 0x07, 0x11, 0x07, 0x07, 0x11, + 0x11, 0x07, 0x07, 0x00, 0x2e, 0x07, 0xd1, 0xf8, + 0x1d, 0x01, 0x30, 0x21, 0x1c, 0x03, 0xf0, 0x46, + 0xfb, 0x01, 0xe0, 0x00, 0x20, 0xf8, 0x60, 0x27, + 0x63, 0x68, 0x6a, 0x00, 0x28, 0x1a, 0xd0, 0xf7, + 0xf7, 0x6d, 0xfa, 0x08, 0x37, 0x0c, 0xcf, 0xc1, + 0x1d, 0x01, 0x31, 0x0c, 0xc1, 0x00, 0x21, 0xc1, + 0x60, 0xe9, 0x69, 0x07, 0x1c, 0x81, 0x64, 0xf8, + 0x68, 0x03, 0x38, 0x0d, 0x28, 0x4a, 0xd2, 0x01, + 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x07, + 0x07, 0x40, 0x40, 0x40, 0x07, 0x46, 0x07, 0x07, + 0x46, 0x46, 0x07, 0x07, 0x00, 0x87, 0xe7, 0x78, + 0x69, 0x02, 0x28, 0x01, 0xd0, 0x01, 0x28, 0x14, + 0xd1, 0x60, 0x6e, 0x02, 0x23, 0x18, 0x40, 0x07, + 0xd0, 0x39, 0x69, 0x00, 0x29, 0x04, 0xd0, 0x02, + 0x21, 0x20, 0x1c, 0x03, 0xf0, 0xb2, 0xfa, 0x08, + 0xe0, 0x00, 0x28, 0x06, 0xd1, 0x38, 0x69, 0x00, + 0x28, 0x03, 0xd1, 0x02, 0x21, 0x20, 0x1c, 0x03, + 0xf0, 0x8e, 0xfa, 0x00, 0x2e, 0x06, 0xd1, 0xf8, + 0x1d, 0x01, 0x30, 0x21, 0x1c, 0x03, 0xf0, 0x02, + 0xfb, 0x00, 0x28, 0x1b, 0xd0, 0x68, 0x6a, 0x00, + 0x28, 0x04, 0xd0, 0x20, 0x1c, 0x39, 0x1c, 0xff, + 0xf7, 0xd4, 0xfb, 0x0c, 0xe0, 0x38, 0x6b, 0x00, + 0x28, 0x01, 0xd0, 0xf7, 0xf7, 0xde, 0xf9, 0xf8, + 0x69, 0x00, 0x28, 0x01, 0xd0, 0xf7, 0xf7, 0xd9, + 0xf9, 0x38, 0x1c, 0xf7, 0xf7, 0x3c, 0xfa, 0x4e, + 0xe7, 0x00, 0x22, 0x20, 0x1c, 0x39, 0x1c, 0xfb, + 0xf7, 0x6a, 0xff, 0x48, 0xe7, 0x68, 0x6a, 0x00, + 0x28, 0x02, 0xd0, 0x01, 0x38, 0x68, 0x62, 0x10, + 0xe0, 0xed, 0x09, 0x00, 0x99, 0x00, 0xf8, 0x68, + 0x00, 0x28, 0x0d, 0xd1, 0x38, 0x6b, 0x00, 0x28, + 0x01, 0xd0, 0xf7, 0xf7, 0xc1, 0xf9, 0xf8, 0x69, + 0x00, 0x28, 0x01, 0xd0, 0xf7, 0xf7, 0xbc, 0xf9, + 0x38, 0x1c, 0xf7, 0xf7, 0x1f, 0xfa, 0x31, 0xe7, + 0xf7, 0xf7, 0xbb, 0xf9, 0x04, 0x1c, 0x0d, 0xd1, + 0x38, 0x6b, 0x00, 0x28, 0x01, 0xd0, 0xf7, 0xf7, + 0xaf, 0xf9, 0xf8, 0x69, 0x00, 0x28, 0x01, 0xd0, + 0xf7, 0xf7, 0xaa, 0xf9, 0x38, 0x1c, 0xf7, 0xf7, + 0x0d, 0xfa, 0x1f, 0xe7, 0x35, 0x20, 0x20, 0x60, + 0x00, 0x99, 0x48, 0x68, 0xe0, 0x60, 0x0e, 0x20, + 0x21, 0x1c, 0x27, 0x61, 0xf7, 0xf7, 0x10, 0xfa, + 0x00, 0x28, 0x0f, 0xd0, 0x38, 0x6b, 0x00, 0x28, + 0x01, 0xd0, 0xf7, 0xf7, 0x95, 0xf9, 0xf8, 0x69, + 0x00, 0x28, 0x01, 0xd0, 0xf7, 0xf7, 0x90, 0xf9, + 0x38, 0x1c, 0xf7, 0xf7, 0xf3, 0xf9, 0x20, 0x1c, + 0xf7, 0xf7, 0xca, 0xf9, 0x02, 0xe7, 0x00, 0x00, + 0x68, 0x14, 0x04, 0x20, 0x00, 0x50, 0x00, 0xe0, + 0xf0, 0xb5, 0x04, 0x1c, 0x01, 0x62, 0x00, 0x20, + 0x60, 0x63, 0xe5, 0x1d, 0x25, 0x35, 0xe0, 0x6a, + 0x21, 0x6b, 0x17, 0x1c, 0x07, 0xf0, 0xd0, 0xfa, + 0x03, 0xc5, 0x08, 0x3d, 0xe0, 0x1d, 0x1d, 0x30, + 0x0c, 0xcd, 0x06, 0x1c, 0x0c, 0xc0, 0x60, 0x69, + 0x21, 0x6a, 0x09, 0x1a, 0x09, 0x01, 0x09, 0x09, + 0x01, 0x23, 0x1b, 0x05, 0xe5, 0x1d, 0x11, 0x35, + 0x99, 0x42, 0x13, 0xd9, 0x49, 0x08, 0x08, 0x18, + 0x00, 0x01, 0x00, 0x09, 0x60, 0x61, 0x03, 0xce, + 0x0c, 0xcd, 0x08, 0x3d, 0x08, 0x3e, 0x80, 0x1a, + 0x99, 0x41, 0x01, 0x22, 0x07, 0xf0, 0xb8, 0xfa, + 0x0c, 0xcd, 0x08, 0x3d, 0x80, 0x18, 0x59, 0x41, + 0x03, 0xc5, 0x08, 0x3d, 0x03, 0xcd, 0x0c, 0xa3, + 0x1a, 0x68, 0x5b, 0x68, 0x08, 0x3d, 0xf6, 0xf7, + 0xdf, 0xfe, 0x00, 0x28, 0xed, 0x09, 0x00, 0x9a, + 0x00, 0x0c, 0xd0, 0x20, 0x6a, 0x61, 0x69, 0x40, + 0x1a, 0x00, 0x01, 0x00, 0x09, 0x01, 0x23, 0x5b, + 0x02, 0x98, 0x42, 0x03, 0xd9, 0x0c, 0xce, 0x0c, + 0xc5, 0x20, 0x6a, 0x60, 0x61, 0x38, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xb5, 0xc1, + 0x1d, 0x11, 0x31, 0x04, 0x1c, 0x08, 0x68, 0x49, + 0x68, 0x17, 0x1c, 0x22, 0xa3, 0x1a, 0x68, 0x0d, + 0x1c, 0x06, 0x1c, 0x5b, 0x68, 0xf6, 0xf7, 0xba, + 0xfe, 0x00, 0x28, 0x04, 0xd0, 0x38, 0x1c, 0x03, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, + 0x6a, 0x61, 0x69, 0x40, 0x1a, 0x00, 0x01, 0x00, + 0x09, 0x01, 0x23, 0x9b, 0x02, 0x98, 0x42, 0x01, + 0xd2, 0x38, 0x1c, 0xf0, 0xe7, 0x60, 0x6a, 0xa1, + 0x6a, 0x80, 0x1b, 0xa9, 0x41, 0x18, 0x22, 0x07, + 0xf0, 0xb5, 0xf9, 0x02, 0x1c, 0x20, 0x6a, 0x0b, + 0x1c, 0x61, 0x69, 0x40, 0x1a, 0x00, 0x01, 0x00, + 0x09, 0x00, 0x21, 0x07, 0xf0, 0x79, 0xfa, 0xa0, + 0x63, 0x20, 0x6a, 0x01, 0x99, 0xa2, 0x6b, 0x08, + 0x1a, 0x00, 0x01, 0x00, 0x09, 0x00, 0x21, 0x07, + 0xf0, 0x7d, 0xfa, 0x18, 0x22, 0x07, 0xf0, 0x56, + 0xfa, 0x01, 0x1c, 0x60, 0x6b, 0x0d, 0x1a, 0x40, + 0x19, 0x60, 0x63, 0xe0, 0x6a, 0x21, 0x6b, 0x2a, + 0x1c, 0x2c, 0x34, 0x07, 0xf0, 0x43, 0xfa, 0x03, + 0xc4, 0x78, 0x1b, 0xc4, 0xe7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x68, 0x52, + 0x6a, 0x52, 0x18, 0x06, 0x2a, 0x06, 0xd8, 0xc2, + 0x1d, 0xf9, 0x32, 0x91, 0x62, 0x40, 0x68, 0x42, + 0x6a, 0x51, 0x18, 0x41, 0x62, 0x70, 0x47, 0xc2, + 0x1d, 0xf9, 0x32, 0x91, 0x6a, 0x00, 0x29, 0x09, + 0xd0, 0x40, 0x68, 0x43, 0x6a, 0x00, 0x2b, 0x03, + 0xd0, 0x43, 0x6a, 0x59, 0x1a, 0x41, 0x62, 0xed, + 0x09, 0x00, 0x9b, 0x00, 0x24, 0x30, 0x00, 0x20, + 0x90, 0x62, 0x70, 0x47, 0x97, 0xb5, 0x83, 0xb0, + 0xc4, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x21, 0x6b, + 0x00, 0x27, 0x00, 0x29, 0x02, 0xd0, 0xff, 0x27, + 0x02, 0x37, 0x11, 0xe0, 0x02, 0x68, 0x40, 0x68, + 0x00, 0x23, 0x81, 0x68, 0x09, 0x48, 0x02, 0x92, + 0x01, 0x91, 0x00, 0x90, 0x04, 0x98, 0x05, 0x99, + 0x01, 0x22, 0x1e, 0xf0, 0x9c, 0xf9, 0x20, 0x63, + 0x00, 0x28, 0x01, 0xd1, 0xff, 0x27, 0x02, 0x37, + 0x38, 0x1c, 0x06, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf7, 0xaa, 0x00, 0x20, 0x90, 0xb5, + 0xc4, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x20, 0x6b, + 0x00, 0x27, 0x00, 0x28, 0x05, 0xd0, 0x05, 0xa1, + 0x1e, 0xf0, 0x51, 0xfa, 0x00, 0x20, 0x20, 0x63, + 0x01, 0xe0, 0xff, 0x27, 0x02, 0x37, 0x38, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x30, 0x36, + 0x00, 0x00, 0xb0, 0xb5, 0x07, 0x1c, 0xff, 0x30, + 0x81, 0x30, 0x04, 0x68, 0x2b, 0xf0, 0xed, 0xfe, + 0xff, 0x25, 0x03, 0x35, 0xa8, 0x42, 0x01, 0xd3, + 0x07, 0x20, 0x00, 0xe0, 0x05, 0x20, 0x40, 0x10, + 0xa0, 0x42, 0x09, 0xd2, 0x2b, 0xf0, 0xe1, 0xfe, + 0xa8, 0x42, 0x01, 0xd3, 0x07, 0x21, 0x00, 0xe0, + 0x05, 0x21, 0x49, 0x10, 0x00, 0x22, 0x07, 0xe0, + 0x2b, 0xf0, 0xd7, 0xfe, 0xa8, 0x42, 0x01, 0xd3, + 0x07, 0x21, 0x00, 0xe0, 0x05, 0x21, 0x01, 0x22, + 0x38, 0x1c, 0xf9, 0xf7, 0x39, 0xfd, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x03, 0x21, + 0x09, 0x04, 0x01, 0x40, 0x0d, 0x0c, 0x17, 0x1c, + 0x1e, 0xf0, 0x01, 0xfc, 0x04, 0x1c, 0x00, 0x2f, + 0x02, 0xd0, 0x38, 0x1c, 0xff, 0xf7, 0xab, 0xff, + 0xff, 0x26, 0xed, 0x09, 0x00, 0x9c, 0x00, 0x03, + 0x36, 0x28, 0x23, 0xdc, 0x42, 0x22, 0xdb, 0x00, + 0x2d, 0x18, 0xd9, 0x2b, 0xf0, 0xb4, 0xfe, 0xb0, + 0x42, 0x01, 0xd3, 0x07, 0x21, 0x00, 0xe0, 0x05, + 0x21, 0x49, 0x10, 0x00, 0x22, 0x38, 0x1c, 0xf9, + 0xf7, 0x15, 0xfd, 0x00, 0x2f, 0x0d, 0xd0, 0x38, + 0x8f, 0x13, 0x4b, 0x58, 0x43, 0x00, 0xd5, 0x01, + 0x30, 0x40, 0x10, 0xc2, 0x17, 0x01, 0x1c, 0x38, + 0x1c, 0xff, 0xf7, 0x66, 0xff, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x01, 0xf0, 0xa2, 0xfa, 0x01, + 0xf0, 0x7e, 0xfa, 0xf7, 0xe7, 0x32, 0x23, 0xdc, + 0x42, 0xf4, 0xdc, 0x01, 0x2d, 0xf2, 0xd2, 0x2b, + 0xf0, 0x8e, 0xfe, 0xb0, 0x42, 0x01, 0xd3, 0x07, + 0x21, 0x00, 0xe0, 0x05, 0x21, 0x01, 0x22, 0x38, + 0x1c, 0xf9, 0xf7, 0xf0, 0xfc, 0x00, 0x2f, 0xe5, + 0xd1, 0x01, 0xf0, 0x8b, 0xfa, 0xe2, 0xe7, 0xe2, + 0x04, 0x00, 0x00, 0xb0, 0xb5, 0x07, 0x1c, 0x3d, + 0x69, 0x00, 0x20, 0x13, 0x4c, 0xab, 0x00, 0xe4, + 0x58, 0x63, 0x00, 0x1b, 0x19, 0x12, 0x4c, 0x9b, + 0x00, 0x1c, 0x19, 0x23, 0x68, 0x24, 0x2b, 0x11, + 0xd0, 0x23, 0x68, 0x8b, 0x42, 0x13, 0xd1, 0x61, + 0x68, 0x39, 0x61, 0xa3, 0x68, 0x00, 0x2b, 0x06, + 0xd0, 0x38, 0x1c, 0x11, 0x1c, 0xf6, 0xf7, 0x40, + 0xfc, 0x00, 0x28, 0x00, 0xd0, 0x3d, 0x61, 0x21, + 0x68, 0x24, 0x29, 0x01, 0xd1, 0xff, 0x20, 0x0a, + 0x30, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe3, + 0x68, 0x0c, 0x34, 0x24, 0x2b, 0xe4, 0xd1, 0xf5, + 0xe7, 0x00, 0x00, 0x18, 0xeb, 0x03, 0x20, 0x7c, + 0x73, 0x03, 0x20, 0x43, 0x68, 0x00, 0x22, 0x00, + 0x2b, 0x03, 0xd0, 0x19, 0x60, 0x43, 0x68, 0x4b, + 0x60, 0x01, 0xe0, 0x01, 0x60, 0x4a, 0x60, 0x0a, + 0x60, 0x41, 0x60, 0x81, 0x68, 0x01, 0x31, 0x81, + 0x60, 0x70, 0x47, 0x0a, 0x68, 0xed, 0x09, 0x00, + 0x9d, 0x00, 0x00, 0x2a, 0x02, 0xd0, 0x4b, 0x68, + 0x53, 0x60, 0x01, 0xe0, 0x4a, 0x68, 0x42, 0x60, + 0x4a, 0x68, 0x00, 0x2a, 0x02, 0xd0, 0x09, 0x68, + 0x11, 0x60, 0x01, 0xe0, 0x09, 0x68, 0x01, 0x60, + 0x81, 0x68, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x39, + 0x81, 0x60, 0x70, 0x47, 0xb0, 0xb5, 0x07, 0x23, + 0x5b, 0x02, 0x04, 0x1c, 0xc0, 0x18, 0x80, 0x68, + 0x1b, 0x4b, 0x0f, 0x1c, 0x98, 0x42, 0x30, 0xd1, + 0x08, 0x2f, 0x2e, 0xd2, 0xff, 0x20, 0xb5, 0x30, + 0x78, 0x43, 0x00, 0x19, 0xc5, 0x1d, 0x31, 0x35, + 0x28, 0x1c, 0xff, 0xf7, 0xcc, 0xfe, 0xff, 0x22, + 0x00, 0x21, 0x28, 0x1c, 0xb5, 0x32, 0xf6, 0xf7, + 0x81, 0xfb, 0x00, 0x20, 0x28, 0x61, 0x6c, 0x60, + 0x2f, 0x60, 0xe9, 0x1d, 0x59, 0x31, 0x2f, 0x77, + 0x0f, 0x71, 0x29, 0x7f, 0xea, 0x1d, 0xb9, 0x32, + 0x11, 0x71, 0xe9, 0x1d, 0x0b, 0x4a, 0xf9, 0x31, + 0xca, 0x61, 0x0b, 0x4b, 0xea, 0x1d, 0xff, 0x32, + 0x9f, 0x6b, 0x7a, 0x32, 0x17, 0x60, 0xdb, 0x6b, + 0x53, 0x60, 0x18, 0x22, 0x0a, 0x62, 0x48, 0x62, + 0xe8, 0x1d, 0xff, 0x30, 0x28, 0x21, 0x3a, 0x30, + 0xc1, 0x62, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x11, 0x19, 0x03, 0x64, 0x18, 0xcc, 0x00, 0x00, + 0xd8, 0xeb, 0x03, 0x20, 0xf0, 0xb5, 0x04, 0x1c, + 0x13, 0x48, 0x1e, 0xf0, 0xfb, 0xf9, 0x07, 0x1c, + 0x1d, 0xd0, 0x00, 0x20, 0x07, 0x23, 0x5b, 0x02, + 0x38, 0x61, 0x10, 0x48, 0xfe, 0x18, 0xb0, 0x60, + 0x00, 0x25, 0x38, 0x1c, 0x29, 0x1c, 0xff, 0xf7, + 0xa9, 0xff, 0x01, 0x35, 0x08, 0x2d, 0xf8, 0xd3, + 0x0b, 0x49, 0xbc, 0x61, 0xc8, 0x1d, 0x79, 0x30, + 0x83, 0x6a, 0x5a, 0x1c, 0x82, 0x62, 0xbb, 0x60, + 0x01, 0x20, 0x70, 0x60, 0xc8, 0x1d, 0x89, 0x30, + 0x39, 0x1c, 0xff, 0xf7, 0x71, 0xff, 0x38, 0x1c, + 0xed, 0x09, 0x00, 0x9e, 0x00, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x0c, 0x0e, 0x00, + 0x00, 0x11, 0x19, 0x03, 0x64, 0x18, 0xeb, 0x03, + 0x20, 0xb0, 0xb5, 0x07, 0x1c, 0x0c, 0x1c, 0x39, + 0x1c, 0x0a, 0x48, 0xff, 0xf7, 0x6f, 0xff, 0x00, + 0x25, 0xff, 0x20, 0xb5, 0x30, 0x68, 0x43, 0xc0, + 0x19, 0x38, 0x30, 0x00, 0xf0, 0xff, 0xf8, 0x01, + 0x35, 0x08, 0x2d, 0xf5, 0xd3, 0x38, 0x1c, 0x21, + 0x1c, 0x1e, 0xf0, 0xc0, 0xf9, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa8, 0xeb, 0x03, + 0x20, 0x80, 0xb5, 0x06, 0x48, 0x00, 0x69, 0x00, + 0x28, 0x05, 0xd0, 0x07, 0x68, 0x04, 0xa1, 0xff, + 0xf7, 0xdb, 0xff, 0x38, 0x1c, 0xf9, 0xd1, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x98, 0xeb, 0x03, + 0x20, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x35, 0x34, 0x36, 0x00, 0x00, 0x01, 0x1c, 0x05, + 0x48, 0x00, 0x69, 0x00, 0x28, 0x05, 0xd0, 0x02, + 0x69, 0x8a, 0x42, 0x02, 0xd0, 0x00, 0x68, 0x00, + 0x28, 0xf9, 0xd1, 0x70, 0x47, 0x98, 0xeb, 0x03, + 0x20, 0x05, 0x48, 0x00, 0x69, 0x00, 0x28, 0x05, + 0xd0, 0x81, 0x69, 0x01, 0x29, 0x02, 0xd0, 0x00, + 0x68, 0x00, 0x28, 0xf9, 0xd1, 0x70, 0x47, 0x00, + 0x00, 0x98, 0xeb, 0x03, 0x20, 0x01, 0x1c, 0x07, + 0x48, 0x00, 0x69, 0x00, 0x28, 0x08, 0xd0, 0x02, + 0x69, 0x1a, 0x2a, 0x02, 0xd1, 0x82, 0x69, 0x8a, + 0x42, 0x02, 0xd0, 0x00, 0x68, 0x00, 0x28, 0xf6, + 0xd1, 0x70, 0x47, 0x00, 0x00, 0x98, 0xeb, 0x03, + 0x20, 0x80, 0xb4, 0x01, 0x1c, 0x09, 0x48, 0x00, + 0x69, 0x00, 0x28, 0x0c, 0xd0, 0x08, 0x4a, 0x83, + 0x68, 0x8b, 0x42, 0x05, 0xd1, 0x07, 0x23, 0x5b, + 0x02, 0xc3, 0x18, 0x9f, 0x68, 0x97, 0x42, 0x02, + 0xd0, 0x00, 0x68, 0xed, 0x09, 0x00, 0x9f, 0x00, + 0x00, 0x28, 0xf3, 0xd1, 0x80, 0xbc, 0x70, 0x47, + 0x00, 0x00, 0x98, 0xeb, 0x03, 0x20, 0x11, 0x19, + 0x03, 0x64, 0x01, 0x1c, 0x08, 0x48, 0x00, 0x69, + 0x00, 0x28, 0x0a, 0xd0, 0x02, 0x69, 0x00, 0x2a, + 0x04, 0xd0, 0x1a, 0x2a, 0x02, 0xd0, 0x82, 0x69, + 0x8a, 0x42, 0x02, 0xd0, 0x00, 0x68, 0x00, 0x28, + 0xf4, 0xd1, 0x70, 0x47, 0x00, 0x00, 0x98, 0xeb, + 0x03, 0x20, 0x01, 0x21, 0xff, 0x22, 0xb5, 0x32, + 0x4a, 0x43, 0x12, 0x18, 0x92, 0x6c, 0x05, 0x2a, + 0x08, 0xd0, 0x02, 0x2a, 0x06, 0xd0, 0x03, 0x2a, + 0x04, 0xd0, 0x04, 0x2a, 0x02, 0xd0, 0x01, 0x31, + 0x08, 0x29, 0xef, 0xd3, 0x01, 0x20, 0x08, 0x29, + 0x00, 0xd1, 0x00, 0x20, 0x70, 0x47, 0x01, 0x22, + 0x8a, 0x42, 0x0c, 0xd0, 0xff, 0x23, 0xb5, 0x33, + 0x53, 0x43, 0x1b, 0x18, 0x9b, 0x6c, 0x00, 0x2b, + 0x05, 0xd0, 0xff, 0x21, 0xb5, 0x31, 0x51, 0x43, + 0x08, 0x18, 0x38, 0x30, 0x70, 0x47, 0x01, 0x32, + 0x08, 0x2a, 0xed, 0xd3, 0x00, 0x20, 0x70, 0x47, + 0x00, 0x28, 0x09, 0xd0, 0x40, 0x68, 0x00, 0x28, + 0x06, 0xd0, 0x07, 0x23, 0x5b, 0x02, 0xc1, 0x18, + 0x89, 0x68, 0x02, 0x4b, 0x99, 0x42, 0x00, 0xd0, + 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x11, 0x19, + 0x03, 0x64, 0x80, 0xb4, 0x0b, 0x4a, 0x00, 0x23, + 0x12, 0x69, 0x00, 0x2a, 0x0e, 0xd0, 0x97, 0x68, + 0x87, 0x42, 0x08, 0xd1, 0x08, 0x29, 0x06, 0xd2, + 0xff, 0x20, 0xb5, 0x30, 0x48, 0x43, 0x80, 0x18, + 0xc3, 0x1d, 0x31, 0x33, 0x02, 0xe0, 0x12, 0x68, + 0x00, 0x2a, 0xf0, 0xd1, 0x80, 0xbc, 0x18, 0x1c, + 0x70, 0x47, 0x98, 0xeb, 0x03, 0x20, 0x90, 0xb4, + 0x00, 0x24, 0x00, 0x29, 0x1c, 0xd0, 0x0b, 0x69, + 0x0a, 0x2b, 0x19, 0xd0, 0x0c, 0x2b, 0x17, 0xd0, + 0x12, 0x2b, 0x15, 0xd0, 0x14, 0x2b, 0xed, 0x09, + 0x00, 0xa0, 0x00, 0x13, 0xd0, 0x01, 0x27, 0xff, + 0x23, 0xb5, 0x33, 0x7b, 0x43, 0x5b, 0x18, 0x9b, + 0x6c, 0x05, 0x2b, 0x08, 0xd0, 0x00, 0x2a, 0x01, + 0xd0, 0x02, 0x2b, 0x04, 0xd0, 0x01, 0x2b, 0x02, + 0xd0, 0x01, 0x37, 0x08, 0x2f, 0xef, 0xd3, 0x08, + 0x2f, 0x00, 0xd1, 0xcc, 0x60, 0x00, 0x28, 0x00, + 0xd0, 0x84, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x90, + 0xb5, 0xc4, 0x1d, 0xf9, 0x34, 0x07, 0x1c, 0x20, + 0x6b, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, + 0xf0, 0xb6, 0xff, 0xe0, 0x6a, 0x00, 0x28, 0x02, + 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x34, 0xff, 0x60, + 0x6b, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x01, + 0xf0, 0x27, 0xf9, 0xfc, 0x1d, 0xff, 0x34, 0x3a, + 0x34, 0xe0, 0x6b, 0x00, 0x28, 0x02, 0xd0, 0x38, + 0x1c, 0x01, 0xf0, 0x08, 0xfa, 0xa0, 0x6b, 0x00, + 0x28, 0x03, 0xd0, 0x01, 0x21, 0x38, 0x1c, 0x01, + 0xf0, 0x9c, 0xf9, 0xf8, 0x6a, 0x00, 0x28, 0x02, + 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0xc6, 0xfe, 0xf8, + 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x00, 0x6b, 0x00, + 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x63, + 0xfe, 0x38, 0x1c, 0x01, 0xf0, 0xb5, 0xff, 0x00, + 0x28, 0x07, 0xd0, 0x0e, 0xa1, 0x1e, 0xf0, 0x90, + 0xf8, 0x38, 0x1c, 0x01, 0xf0, 0xad, 0xff, 0x00, + 0x28, 0xf7, 0xd1, 0x38, 0x1c, 0xff, 0xf7, 0x1a, + 0xfd, 0x00, 0x20, 0x38, 0x61, 0xf8, 0x64, 0x60, + 0x60, 0xf8, 0x60, 0xf8, 0x1d, 0xff, 0x30, 0x86, + 0x30, 0x00, 0x24, 0x00, 0x21, 0x00, 0x22, 0x00, + 0x23, 0x00, 0x27, 0x9e, 0xc0, 0x9c, 0xc0, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, + 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x37, 0x37, + 0x30, 0x00, 0x00, 0xf0, 0xb5, 0xc5, 0x1d, 0xff, + 0x35, 0xed, 0x09, 0x00, 0xa1, 0x00, 0xe6, 0x35, + 0x01, 0x26, 0x0c, 0x1c, 0x17, 0x1c, 0x29, 0x69, + 0x00, 0x29, 0x0d, 0xd1, 0x31, 0x1c, 0xff, 0xf7, + 0x0f, 0xfe, 0x2c, 0x61, 0x28, 0x1c, 0x0a, 0x49, + 0x00, 0xf0, 0xb2, 0xff, 0xe8, 0x1d, 0xf9, 0x30, + 0x18, 0x21, 0x01, 0x62, 0xc7, 0x61, 0x04, 0xe0, + 0xff, 0x35, 0xb5, 0x35, 0x01, 0x36, 0x08, 0x2e, + 0xe9, 0xd3, 0x00, 0x20, 0x08, 0x2e, 0x00, 0xd0, + 0x28, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x5a, 0x62, 0x02, 0x90, 0xb5, 0x83, 0xb0, + 0x12, 0x4f, 0x38, 0x68, 0x00, 0x28, 0x1c, 0xd0, + 0x79, 0x68, 0x00, 0x24, 0x88, 0x42, 0x0b, 0xd1, + 0x02, 0x28, 0x01, 0xd0, 0x03, 0x28, 0x07, 0xd1, + 0x01, 0x24, 0x07, 0x23, 0xb8, 0x6a, 0x1b, 0x02, + 0x98, 0x42, 0x01, 0xd1, 0x22, 0x20, 0xb8, 0x62, + 0x20, 0x37, 0x07, 0xcf, 0x01, 0x91, 0x00, 0x90, + 0x2c, 0x3f, 0x02, 0x92, 0x01, 0x20, 0x00, 0x21, + 0x22, 0x1c, 0xfb, 0x69, 0x01, 0xf0, 0x1e, 0xfc, + 0xb8, 0x60, 0x03, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, + 0x07, 0x48, 0x01, 0x68, 0x00, 0x29, 0x08, 0xd0, + 0x00, 0x20, 0x01, 0x29, 0x04, 0xd0, 0x02, 0x29, + 0x02, 0xd0, 0x03, 0x29, 0x00, 0xd1, 0x02, 0x20, + 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x00, 0x00, + 0xd8, 0xeb, 0x03, 0x20, 0x05, 0x48, 0x01, 0x68, + 0x00, 0x20, 0x00, 0x29, 0x04, 0xd0, 0x01, 0x29, + 0x02, 0xd0, 0x02, 0x29, 0x00, 0xd1, 0x01, 0x20, + 0x70, 0x47, 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, + 0x06, 0x48, 0x01, 0x68, 0x01, 0x20, 0x00, 0x29, + 0x07, 0xd0, 0x01, 0x29, 0x05, 0xd0, 0x00, 0x20, + 0x02, 0x29, 0x02, 0xd0, 0x03, 0x29, 0x00, 0xd1, + 0x02, 0x20, 0x70, 0x47, 0xd8, 0xeb, 0x03, 0x20, + 0x08, 0x48, 0x02, 0x68, 0xed, 0x09, 0x00, 0xa2, + 0x00, 0x00, 0x2a, 0x09, 0xd0, 0x01, 0x21, 0x01, + 0x2a, 0x08, 0xd0, 0x00, 0x20, 0x02, 0x2a, 0x02, + 0xd0, 0x03, 0x2a, 0x00, 0xd1, 0x08, 0x1c, 0x70, + 0x47, 0x02, 0x20, 0x70, 0x47, 0x08, 0x1c, 0x70, + 0x47, 0xd8, 0xeb, 0x03, 0x20, 0x05, 0x48, 0x01, + 0x68, 0x00, 0x20, 0x00, 0x29, 0x04, 0xd0, 0x01, + 0x29, 0x02, 0xd0, 0x02, 0x29, 0x00, 0xd1, 0x01, + 0x20, 0x70, 0x47, 0x00, 0x00, 0xd8, 0xeb, 0x03, + 0x20, 0xf0, 0xb5, 0x83, 0xb0, 0xc5, 0x68, 0x6a, + 0x4c, 0x00, 0x2d, 0x06, 0xd0, 0x07, 0x23, 0x5b, + 0x02, 0xe9, 0x18, 0x89, 0x68, 0x67, 0x4b, 0x99, + 0x42, 0x05, 0xd0, 0x20, 0x68, 0x60, 0x60, 0x03, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x47, + 0x69, 0x00, 0x69, 0x2e, 0x69, 0xe8, 0x60, 0x00, + 0x2f, 0x01, 0xd1, 0x19, 0x21, 0x00, 0xe0, 0x1a, + 0x21, 0x00, 0x22, 0x28, 0x1c, 0xff, 0xf7, 0x04, + 0xfd, 0x00, 0x28, 0x02, 0xd0, 0x20, 0x68, 0x60, + 0x60, 0xe9, 0xe7, 0x37, 0x23, 0x9b, 0x01, 0xe8, + 0x18, 0x01, 0x6b, 0x00, 0x29, 0x05, 0xd0, 0x06, + 0x2e, 0x00, 0xd1, 0xa7, 0x60, 0x00, 0x21, 0x01, + 0x63, 0x9c, 0xe0, 0x60, 0x69, 0x00, 0x28, 0x5d, + 0xd0, 0xa0, 0x69, 0x00, 0x28, 0x5a, 0xd0, 0xe0, + 0x68, 0x00, 0x28, 0x34, 0xd0, 0x00, 0x2f, 0x03, + 0xd0, 0xff, 0x23, 0x11, 0x33, 0x9f, 0x42, 0x2e, + 0xd1, 0xff, 0xf7, 0x8c, 0xff, 0x07, 0x1c, 0xff, + 0xf7, 0x7b, 0xff, 0x06, 0x1c, 0x20, 0x34, 0x07, + 0xcc, 0x01, 0x91, 0x00, 0x90, 0x2c, 0x3c, 0x02, + 0x92, 0x00, 0x20, 0x31, 0x1c, 0x3a, 0x1c, 0xe3, + 0x69, 0x01, 0xf0, 0x72, 0xfb, 0x07, 0x1c, 0x3d, + 0xd0, 0xff, 0xf7, 0x9c, 0xff, 0x06, 0x1c, 0xff, + 0xf7, 0x85, 0xff, 0x03, 0x1c, 0x20, 0x34, 0x07, + 0xcc, 0x2c, 0x3c, 0x01, 0x91, 0x00, 0x90, 0xed, + 0x09, 0x00, 0xa3, 0x00, 0x02, 0x92, 0xe0, 0x69, + 0x19, 0x1c, 0x03, 0x1c, 0x00, 0x20, 0x32, 0x1c, + 0x01, 0xf0, 0x5d, 0xfb, 0x00, 0x28, 0x28, 0xd0, + 0x00, 0x20, 0xe0, 0x60, 0xff, 0xf7, 0x41, 0xff, + 0x20, 0x60, 0x22, 0xe0, 0x00, 0x28, 0x20, 0xd1, + 0x00, 0x2f, 0x1e, 0xd0, 0xff, 0x23, 0x11, 0x33, + 0x9f, 0x42, 0x1a, 0xd0, 0xff, 0xf7, 0x79, 0xff, + 0x06, 0x1c, 0xff, 0xf7, 0x62, 0xff, 0x03, 0x1c, + 0x20, 0x34, 0x07, 0xcc, 0x2c, 0x3c, 0x01, 0x91, + 0x00, 0x90, 0x02, 0x92, 0xe0, 0x69, 0x19, 0x1c, + 0x03, 0x1c, 0x00, 0x20, 0x32, 0x1c, 0x01, 0xf0, + 0x3a, 0xfb, 0x00, 0x28, 0x03, 0xd0, 0xff, 0xf7, + 0x20, 0xff, 0x20, 0x60, 0x01, 0xe0, 0x01, 0x20, + 0xe0, 0x60, 0xe0, 0x68, 0x00, 0x28, 0x03, 0xd0, + 0x00, 0x20, 0xe0, 0x60, 0x27, 0x61, 0x34, 0xe0, + 0x20, 0x69, 0x00, 0x28, 0x01, 0xd0, 0x07, 0x1c, + 0x04, 0xe0, 0x00, 0x2f, 0x02, 0xd1, 0x60, 0x68, + 0x20, 0x60, 0x09, 0xe0, 0xff, 0x23, 0x11, 0x33, + 0x9f, 0x42, 0x03, 0xd1, 0x60, 0x68, 0x00, 0x27, + 0x20, 0x60, 0x01, 0xe0, 0x20, 0x68, 0x60, 0x60, + 0x20, 0x68, 0x02, 0x28, 0x01, 0xd0, 0x03, 0x28, + 0x10, 0xd1, 0x07, 0x20, 0xff, 0xf7, 0x6f, 0xfd, + 0x00, 0x28, 0x0b, 0xd1, 0x08, 0x20, 0xff, 0xf7, + 0x6a, 0xfd, 0x00, 0x28, 0x06, 0xd1, 0x09, 0x20, + 0xff, 0xf7, 0x65, 0xfd, 0x00, 0x28, 0x01, 0xd1, + 0xff, 0xf7, 0xc1, 0xfe, 0xf6, 0xf7, 0x72, 0xfc, + 0x00, 0x28, 0x06, 0xd0, 0x6e, 0x21, 0x01, 0x60, + 0xc7, 0x60, 0x01, 0x1c, 0x09, 0x20, 0xf6, 0xf7, + 0xd8, 0xfc, 0x28, 0x69, 0x00, 0x28, 0x00, 0xd0, + 0x3c, 0xe7, 0x28, 0x1c, 0x04, 0xa1, 0xff, 0xf7, + 0x18, 0xfd, 0x37, 0xe7, 0x00, 0x00, 0xd8, 0xeb, + 0x03, 0x20, 0x11, 0x19, 0x03, 0x64, 0x73, 0x72, + 0x63, 0x5c, 0xed, 0x09, 0x00, 0xa4, 0x00, 0x6c, + 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, + 0x3a, 0x20, 0x31, 0x30, 0x35, 0x38, 0x00, 0xf0, + 0xb5, 0x84, 0xb0, 0xc4, 0x68, 0x00, 0x2c, 0x49, + 0xd0, 0x07, 0x23, 0x5b, 0x02, 0xe1, 0x18, 0x89, + 0x68, 0x25, 0x4b, 0x99, 0x42, 0x42, 0xd1, 0x45, + 0x69, 0x00, 0x69, 0x00, 0x2d, 0xe0, 0x60, 0x01, + 0xd1, 0x1b, 0x26, 0x00, 0xe0, 0x1c, 0x26, 0xf6, + 0xf7, 0x3b, 0xfc, 0x07, 0x1c, 0x36, 0xd0, 0x00, + 0x22, 0x20, 0x1c, 0x31, 0x1c, 0xff, 0xf7, 0x21, + 0xfc, 0x00, 0x28, 0x2f, 0xd1, 0x00, 0x2d, 0x19, + 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xe6, 0x18, 0x30, + 0x6a, 0x00, 0x21, 0x17, 0x4a, 0xf6, 0xf7, 0xdb, + 0xf9, 0x03, 0x90, 0xf0, 0x69, 0x80, 0x01, 0x02, + 0x0a, 0x0b, 0x1c, 0xa1, 0x68, 0x14, 0x48, 0x01, + 0x91, 0x19, 0x1c, 0x00, 0x23, 0x02, 0x92, 0x00, + 0x90, 0x03, 0x98, 0x01, 0x22, 0x1d, 0xf0, 0x01, + 0xfd, 0x70, 0x62, 0x0c, 0xe0, 0x20, 0x69, 0x00, + 0x28, 0x04, 0xd1, 0x20, 0x1c, 0x0d, 0xa1, 0xff, + 0xf7, 0xc6, 0xfc, 0x04, 0xe0, 0x00, 0x22, 0x00, + 0x20, 0x21, 0x1c, 0xff, 0xf7, 0xa8, 0xfd, 0x74, + 0x20, 0x38, 0x60, 0x09, 0x20, 0x39, 0x1c, 0xfd, + 0x60, 0xf6, 0xf7, 0x71, 0xfc, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x11, + 0x19, 0x03, 0x64, 0x00, 0x10, 0x27, 0x00, 0xb9, + 0xaa, 0x00, 0x20, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, + 0x3a, 0x20, 0x31, 0x31, 0x31, 0x31, 0x00, 0x90, + 0xb5, 0x07, 0x1c, 0xc4, 0x68, 0x00, 0x69, 0x00, + 0x28, 0x01, 0xd1, 0x1d, 0x21, 0x00, 0xe0, 0x1e, + 0x21, 0x00, 0x2c, 0x22, 0xd0, 0x07, 0x23, 0x5b, + 0x02, 0xe0, 0x18, 0x80, 0x68, 0x11, 0x4b, 0x98, + 0x42, 0x1b, 0xd1, 0x00, 0x22, 0xed, 0x09, 0x00, + 0xa5, 0x00, 0x20, 0x1c, 0xff, 0xf7, 0xc4, 0xfb, + 0x00, 0x28, 0x15, 0xd1, 0x60, 0x69, 0x00, 0x28, + 0x0b, 0xd0, 0xf6, 0xf7, 0xd0, 0xfb, 0x00, 0x28, + 0x07, 0xd0, 0x75, 0x21, 0x01, 0x60, 0x39, 0x69, + 0xc1, 0x60, 0x01, 0x1c, 0x09, 0x20, 0xf6, 0xf7, + 0x35, 0xfc, 0x20, 0x69, 0x00, 0x28, 0x03, 0xd1, + 0x20, 0x1c, 0x04, 0xa1, 0xff, 0xf7, 0x76, 0xfc, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x11, 0x19, 0x03, 0x64, 0x73, 0x72, 0x63, 0x5c, + 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, + 0x63, 0x3a, 0x20, 0x31, 0x31, 0x36, 0x39, 0x00, + 0xf0, 0xb5, 0x84, 0xb0, 0xc5, 0x68, 0x07, 0x1c, + 0x28, 0x1c, 0xff, 0xf7, 0x1c, 0xfd, 0x04, 0x1c, + 0x64, 0xd0, 0x38, 0x69, 0xbe, 0x69, 0xe0, 0x60, + 0x78, 0x69, 0x00, 0x2e, 0xa8, 0x60, 0x02, 0xd1, + 0x1f, 0x21, 0x03, 0x91, 0x01, 0xe0, 0x20, 0x21, + 0x03, 0x91, 0xf6, 0xf7, 0x98, 0xfb, 0x07, 0x1c, + 0x54, 0xd0, 0x00, 0x22, 0x20, 0x1c, 0x03, 0x99, + 0xff, 0xf7, 0x7e, 0xfb, 0x00, 0x28, 0x03, 0xd0, + 0x38, 0x1c, 0xf6, 0xf7, 0xc7, 0xfb, 0x49, 0xe0, + 0x6f, 0x20, 0x38, 0x60, 0x3d, 0x61, 0xe8, 0x68, + 0xf8, 0x60, 0x09, 0x20, 0x39, 0x1c, 0x7e, 0x61, + 0xf6, 0xf7, 0xf0, 0xfb, 0x00, 0x2e, 0x28, 0xd1, + 0x28, 0x8f, 0x20, 0x4a, 0xc1, 0x17, 0xf6, 0xf7, + 0x2d, 0xf9, 0x0b, 0x1c, 0x2a, 0x68, 0xa1, 0x68, + 0x07, 0x1c, 0x1d, 0x48, 0x01, 0x91, 0x19, 0x1c, + 0x02, 0x92, 0x01, 0x22, 0x00, 0x23, 0x00, 0x90, + 0x38, 0x1c, 0x1d, 0xf0, 0x55, 0xfc, 0xe8, 0x63, + 0x28, 0x8f, 0x16, 0x49, 0x17, 0x4b, 0x41, 0x43, + 0x99, 0x42, 0x23, 0xdb, 0xc1, 0x17, 0x5a, 0x0b, + 0xf6, 0xf7, 0x14, 0xf9, 0x14, 0xa3, 0x1a, 0x68, + 0x5b, 0x68, 0x06, 0xf0, 0x93, 0xfb, 0x0a, 0x1c, + 0xed, 0x09, 0x00, 0xa6, 0x00, 0x01, 0x1c, 0x28, + 0x1c, 0xff, 0xf7, 0x8b, 0xfa, 0x14, 0xe0, 0x20, + 0x69, 0x00, 0x28, 0x04, 0xd1, 0x20, 0x1c, 0x0f, + 0xa1, 0xff, 0xf7, 0x06, 0xfc, 0x0c, 0xe0, 0x00, + 0x22, 0x00, 0x20, 0x69, 0x68, 0xff, 0xf7, 0xe8, + 0xfc, 0x28, 0x1c, 0xff, 0xf7, 0x0b, 0xfd, 0x00, + 0x20, 0x37, 0x23, 0x9b, 0x01, 0xe1, 0x18, 0x48, + 0x63, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xe2, 0x04, 0x00, 0x00, 0x47, 0xab, 0x00, + 0x20, 0x00, 0x40, 0x9c, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x37, + 0x00, 0xb0, 0xb5, 0xc4, 0x68, 0x07, 0x1c, 0x20, + 0x1c, 0xff, 0xf7, 0x97, 0xfc, 0x00, 0x28, 0x1c, + 0xd0, 0x3f, 0x69, 0xff, 0x25, 0x11, 0x35, 0x00, + 0x2f, 0x02, 0xd1, 0x04, 0x27, 0x21, 0x21, 0x06, + 0xe0, 0xaf, 0x42, 0x03, 0xd1, 0x21, 0x6c, 0x00, + 0x29, 0x00, 0xd1, 0x00, 0x27, 0x22, 0x21, 0x3a, + 0x1c, 0xff, 0xf7, 0xfc, 0xfa, 0x20, 0x6c, 0x00, + 0x28, 0x0a, 0xd0, 0xaf, 0x42, 0x08, 0xd1, 0x00, + 0x20, 0x20, 0x64, 0x00, 0x21, 0x20, 0x1c, 0x01, + 0xf0, 0xc1, 0xfa, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x2f, 0xfa, 0xd0, 0x00, 0x22, 0x20, + 0x1c, 0x61, 0x68, 0xff, 0xf7, 0x99, 0xfc, 0xf4, + 0xe7, 0x90, 0xb5, 0xc4, 0x68, 0x07, 0x1c, 0x20, + 0x1c, 0xff, 0xf7, 0x67, 0xfc, 0x00, 0x28, 0x17, + 0xd0, 0x04, 0x20, 0x20, 0x61, 0xe0, 0x1d, 0xf9, + 0x30, 0x3f, 0x69, 0x01, 0x6b, 0x00, 0x29, 0x12, + 0xd0, 0x00, 0x21, 0x01, 0x63, 0xf6, 0xf7, 0xe5, + 0xfa, 0x00, 0x28, 0x09, 0xd0, 0x78, 0x21, 0x01, + 0x60, 0xe1, 0x68, 0xc1, 0x60, 0x08, 0x21, 0x01, + 0x61, 0x01, 0x1c, 0xed, 0x09, 0x00, 0xa7, 0x00, + 0x09, 0x20, 0xf6, 0xf7, 0x48, 0xfb, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf6, 0xf7, 0xd4, 0xfa, + 0x00, 0x28, 0xf8, 0xd0, 0x72, 0x21, 0x01, 0x60, + 0xe1, 0x68, 0xc1, 0x60, 0x07, 0x61, 0x01, 0x1c, + 0x09, 0x20, 0xf6, 0xf7, 0x38, 0xfb, 0xee, 0xe7, + 0x00, 0xb5, 0xc0, 0x68, 0xff, 0xf7, 0x38, 0xfc, + 0x00, 0x28, 0x03, 0xd0, 0x00, 0x22, 0x16, 0x21, + 0xff, 0xf7, 0xab, 0xfa, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0xb5, 0x07, 0x1c, 0xc0, 0x68, 0x3a, 0x69, + 0x17, 0x21, 0xff, 0xf7, 0xa2, 0xfa, 0x00, 0x28, + 0x02, 0xd1, 0x38, 0x69, 0x1d, 0xf0, 0x59, 0xfe, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x07, 0x1c, 0x00, 0x69, 0x00, 0x28, 0x12, 0xd0, + 0x13, 0x4c, 0x13, 0xa0, 0xe1, 0x1d, 0xa5, 0x31, + 0x0a, 0xf0, 0xb1, 0xfc, 0xe0, 0x1d, 0x79, 0x30, + 0xc0, 0x6a, 0x01, 0x02, 0x09, 0x0a, 0xe0, 0x1d, + 0xad, 0x30, 0x1e, 0xf0, 0x96, 0xfa, 0x00, 0x21, + 0x01, 0x20, 0xf9, 0xf7, 0x93, 0xf9, 0x1e, 0xf0, + 0xb8, 0xf8, 0xf9, 0xf7, 0xba, 0xf9, 0xf6, 0xf7, + 0x8f, 0xfa, 0x00, 0x28, 0x07, 0xd0, 0x7c, 0x21, + 0x01, 0x60, 0xf9, 0x68, 0xc1, 0x60, 0x01, 0x1c, + 0x09, 0x20, 0xf6, 0xf7, 0xf4, 0xfa, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x18, 0xeb, + 0x03, 0x20, 0x0a, 0x4d, 0x79, 0x20, 0x42, 0x54, + 0x41, 0x64, 0x64, 0x72, 0x3a, 0x20, 0x25, 0x3a, + 0x2d, 0x36, 0x42, 0x20, 0x28, 0x66, 0x69, 0x6e, + 0x61, 0x6c, 0x29, 0x0a, 0x00, 0x00, 0xf3, 0xb5, + 0x84, 0xb0, 0x04, 0x98, 0x06, 0x69, 0xc0, 0x68, + 0x00, 0x2e, 0x73, 0xd0, 0x07, 0x23, 0x5b, 0x02, + 0xf1, 0x18, 0x89, 0x68, 0x8f, 0x4b, 0x99, 0x42, + 0x6d, 0xd1, 0x00, 0x28, 0x6a, 0xd0, 0x07, 0x28, + 0x6a, 0xd8, 0xff, 0x23, 0xb5, 0x33, 0xed, 0x09, + 0x00, 0xa8, 0x00, 0x58, 0x43, 0x80, 0x19, 0xc4, + 0x1d, 0x31, 0x34, 0xe0, 0x6c, 0x00, 0x28, 0x05, + 0xd1, 0x20, 0x6d, 0x00, 0x28, 0x5c, 0xd0, 0xc0, + 0x6c, 0x00, 0x28, 0x59, 0xd0, 0xf6, 0xf7, 0x4e, + 0xfa, 0x07, 0x1c, 0x55, 0xd0, 0x04, 0x98, 0xc0, + 0x69, 0x01, 0x90, 0x00, 0x20, 0xe0, 0x64, 0x01, + 0x98, 0x00, 0x28, 0x1e, 0xd0, 0xe0, 0x68, 0x38, + 0x61, 0x65, 0x6d, 0x00, 0x2d, 0x73, 0xd0, 0xb5, + 0x42, 0x71, 0xd0, 0xa0, 0x6d, 0x00, 0x28, 0x03, + 0xd0, 0xa0, 0x42, 0x01, 0xd0, 0xff, 0xf7, 0xfb, + 0xfb, 0x00, 0x21, 0x28, 0x1c, 0xff, 0xf7, 0x91, + 0xfb, 0x00, 0x28, 0x05, 0xd0, 0x01, 0x22, 0x00, + 0x20, 0x29, 0x1c, 0xff, 0xf7, 0xca, 0xfb, 0xc4, + 0xe0, 0x28, 0x1c, 0x71, 0xa1, 0xff, 0xf7, 0xdd, + 0xfa, 0xbf, 0xe0, 0x25, 0x6d, 0x00, 0x2d, 0x05, + 0xd1, 0xe0, 0x68, 0x38, 0x61, 0xff, 0x20, 0x0c, + 0x30, 0x01, 0x90, 0xb6, 0xe0, 0xe8, 0x68, 0x38, + 0x61, 0x62, 0x68, 0x69, 0x68, 0x6e, 0x48, 0x8a, + 0x42, 0x0f, 0xd1, 0xb1, 0x69, 0x01, 0x29, 0x02, + 0xd1, 0x02, 0x21, 0xb1, 0x61, 0x09, 0xe0, 0x02, + 0x29, 0x07, 0xd1, 0x01, 0x21, 0xb1, 0x61, 0xf1, + 0x1d, 0x29, 0x31, 0xc6, 0x1d, 0xa5, 0x36, 0x0c, + 0xce, 0x0c, 0xc1, 0x61, 0x68, 0x89, 0x69, 0x01, + 0x29, 0x10, 0xd1, 0xe8, 0x1d, 0xf9, 0x30, 0x81, + 0x6b, 0x20, 0x1c, 0x00, 0xf0, 0xe6, 0xfb, 0xe0, + 0x1d, 0x0d, 0x30, 0xe9, 0x1d, 0x0d, 0x31, 0x02, + 0xe0, 0xa8, 0xe0, 0xa7, 0xe0, 0xa6, 0xe0, 0x0c, + 0xc9, 0x0c, 0xc0, 0x14, 0xe0, 0xff, 0x30, 0x01, + 0x30, 0x01, 0x68, 0x40, 0x68, 0x41, 0x43, 0xe8, + 0x1d, 0xf9, 0x30, 0x80, 0x6b, 0x09, 0x18, 0x20, + 0x1c, 0x00, 0xf0, 0xcf, 0xfb, 0xe9, 0x1d, 0xff, + 0x31, 0x7a, 0x31, 0x00, 0x20, 0x08, 0x61, 0xe9, + 0x1d, 0xed, 0x09, 0x00, 0xa9, 0x00, 0xff, 0x31, + 0x3a, 0x31, 0x08, 0x61, 0xac, 0x42, 0x0d, 0xd0, + 0x68, 0x68, 0x00, 0x90, 0x04, 0x98, 0x40, 0x69, + 0xa0, 0x60, 0x60, 0x68, 0xc1, 0x68, 0x04, 0x9a, + 0x92, 0x69, 0x91, 0x42, 0x00, 0xd0, 0xc2, 0x60, + 0x05, 0x20, 0x00, 0xe0, 0x64, 0xe0, 0x20, 0x61, + 0xe8, 0x1d, 0xf9, 0x30, 0xc2, 0x69, 0xe1, 0x1d, + 0xf9, 0x31, 0xca, 0x61, 0x00, 0x6a, 0xee, 0x1d, + 0x08, 0x62, 0xe8, 0x1d, 0xff, 0x30, 0x3a, 0x30, + 0xe1, 0x1d, 0xff, 0x31, 0x03, 0x90, 0x40, 0x69, + 0x3a, 0x31, 0x02, 0x91, 0x48, 0x61, 0x03, 0x98, + 0xff, 0x36, 0x80, 0x69, 0x02, 0x99, 0x86, 0x36, + 0x88, 0x61, 0x03, 0x98, 0xc0, 0x69, 0x02, 0x99, + 0xc8, 0x61, 0x03, 0x98, 0x00, 0x6a, 0x02, 0x99, + 0x08, 0x62, 0x0e, 0xce, 0xe0, 0x1d, 0xff, 0x30, + 0x86, 0x30, 0x0e, 0xc0, 0x0e, 0xce, 0x0e, 0xc0, + 0x0e, 0xce, 0x0e, 0xc0, 0x03, 0x98, 0x80, 0x68, + 0x02, 0x99, 0x88, 0x60, 0x03, 0x98, 0xc0, 0x68, + 0x02, 0x99, 0xc8, 0x60, 0x03, 0x98, 0x00, 0x69, + 0x02, 0x99, 0x08, 0x61, 0xe8, 0x1d, 0xff, 0x30, + 0x7a, 0x30, 0xe1, 0x1d, 0xff, 0x31, 0x02, 0x68, + 0x7a, 0x31, 0x0a, 0x60, 0x40, 0x68, 0x48, 0x60, + 0x03, 0x98, 0x40, 0x6b, 0x02, 0x99, 0x48, 0x63, + 0x20, 0x1c, 0x29, 0x1c, 0x01, 0xf0, 0x3d, 0xfb, + 0xe8, 0x68, 0xe0, 0x60, 0x28, 0x1c, 0xff, 0xf7, + 0x41, 0xfb, 0x00, 0x21, 0x00, 0x98, 0xff, 0xf7, + 0xd7, 0xfa, 0x00, 0x28, 0x03, 0xd1, 0x00, 0x98, + 0x1d, 0xa1, 0xff, 0xf7, 0x29, 0xfa, 0xf6, 0xf7, + 0x70, 0xf9, 0x00, 0x28, 0x08, 0xd0, 0x1e, 0x21, + 0x01, 0x60, 0xc4, 0x60, 0xa1, 0x68, 0x01, 0x61, + 0x01, 0x1c, 0x0b, 0x20, 0xf6, 0xf7, 0xd4, 0xf9, + 0x00, 0x20, 0x20, 0x65, 0x60, 0x65, 0xa0, 0x65, + 0x05, 0x99, 0x00, 0x29, 0xed, 0x09, 0x00, 0xaa, + 0x00, 0x08, 0xd1, 0x7d, 0x20, 0x38, 0x60, 0xfc, + 0x60, 0x01, 0x98, 0x78, 0x61, 0x09, 0x20, 0x39, + 0x1c, 0xf6, 0xf7, 0xc4, 0xf9, 0x20, 0x1c, 0x00, + 0xf0, 0x2d, 0xfb, 0x20, 0x1c, 0x00, 0xf0, 0x70, + 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0x67, 0xfc, 0x06, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x11, 0x19, 0x03, 0x64, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x34, 0x36, 0x34, + 0x00, 0x18, 0xeb, 0x03, 0x20, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x35, 0x37, 0x33, + 0x00, 0xf7, 0xb5, 0x83, 0xb0, 0x04, 0x1c, 0xf9, + 0xf7, 0x5d, 0xfb, 0x00, 0x90, 0x01, 0x91, 0x04, + 0x9a, 0x05, 0x9b, 0x06, 0xf0, 0xa9, 0xfa, 0x06, + 0x1c, 0x20, 0x1c, 0x0d, 0x1c, 0xff, 0xf7, 0x93, + 0xfa, 0x07, 0x1c, 0x32, 0xd0, 0x20, 0x69, 0x02, + 0x90, 0x04, 0x28, 0x02, 0xd0, 0x02, 0x98, 0x02, + 0x28, 0x2b, 0xd1, 0x18, 0xa3, 0x1a, 0x68, 0x30, + 0x1c, 0x29, 0x1c, 0x5b, 0x68, 0x06, 0xf0, 0x9c, + 0xfa, 0x00, 0x28, 0x05, 0xd0, 0x20, 0x1c, 0x31, + 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0x9c, 0xf9, 0x1c, + 0xe0, 0x02, 0x9d, 0x20, 0x1c, 0xff, 0xf7, 0xc8, + 0xfa, 0x04, 0x2d, 0x09, 0xd1, 0x38, 0x1c, 0xff, + 0xf7, 0x47, 0xfa, 0x00, 0x28, 0x04, 0xd1, 0x00, + 0x22, 0x0a, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xe4, + 0xf8, 0x38, 0x69, 0x00, 0x28, 0x09, 0xd1, 0x38, + 0x1c, 0x08, 0xa1, 0xff, 0xf7, 0xa7, 0xf9, 0x0c, + 0x48, 0x80, 0x68, 0x00, 0x28, 0x01, 0xd0, 0xff, + 0xf7, 0x37, 0xfb, 0x06, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0xed, + 0x09, 0x00, 0xab, 0x00, 0x63, 0x5c, 0x6c, 0x63, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x31, 0x36, 0x33, 0x37, 0x00, 0xd8, 0xeb, + 0x03, 0x20, 0xb0, 0xb5, 0x83, 0xb0, 0xff, 0xf7, + 0xec, 0xf9, 0x04, 0x1c, 0x3a, 0xd0, 0x37, 0x23, + 0x9b, 0x01, 0xe5, 0x18, 0xa8, 0x6a, 0x00, 0x28, + 0x34, 0xd0, 0x00, 0x20, 0xa8, 0x62, 0x00, 0x22, + 0x15, 0x21, 0x20, 0x1c, 0xff, 0xf7, 0xaf, 0xf8, + 0x00, 0x28, 0x1d, 0xd1, 0xf6, 0xf7, 0xbe, 0xf8, + 0x07, 0x1c, 0x19, 0xd0, 0x05, 0x20, 0x38, 0x60, + 0xe0, 0x68, 0xf8, 0x60, 0x14, 0x48, 0xc1, 0x69, + 0x49, 0x00, 0x39, 0x61, 0x01, 0x6a, 0x49, 0x00, + 0x79, 0x61, 0x41, 0x6a, 0x49, 0x00, 0xb9, 0x61, + 0x80, 0x6a, 0x40, 0x00, 0xf8, 0x61, 0xf8, 0x1d, + 0x19, 0x30, 0x21, 0x1c, 0x00, 0xf0, 0x2c, 0xff, + 0x0b, 0x20, 0x39, 0x1c, 0xf6, 0xf7, 0x11, 0xf9, + 0xa1, 0x68, 0x00, 0x22, 0x09, 0x48, 0x02, 0x92, + 0x01, 0x91, 0x08, 0xa1, 0x00, 0x90, 0x08, 0x68, + 0x00, 0x23, 0x01, 0x22, 0x49, 0x68, 0x1d, 0xf0, + 0x7e, 0xf9, 0xe8, 0x62, 0x03, 0xb0, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xd8, 0xeb, + 0x03, 0x20, 0x45, 0xaa, 0x00, 0x20, 0x00, 0x10, + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xb5, + 0xff, 0xf7, 0x9f, 0xf9, 0x04, 0x1c, 0x2e, 0xd0, + 0x37, 0x23, 0x9b, 0x01, 0xe0, 0x18, 0xc1, 0x6a, + 0x00, 0x29, 0x28, 0xd0, 0x01, 0x21, 0x01, 0x63, + 0x00, 0x21, 0xc1, 0x62, 0x02, 0x21, 0x00, 0x22, + 0x20, 0x1c, 0xff, 0xf7, 0x60, 0xf8, 0x00, 0x28, + 0x1d, 0xd1, 0xf6, 0xf7, 0x6f, 0xf8, 0x07, 0x1c, + 0x19, 0xd0, 0x0c, 0x20, 0x38, 0x60, 0xe0, 0x68, + 0xf8, 0x60, 0x0c, 0x48, 0xc1, 0x69, 0x49, 0x00, + 0x39, 0x61, 0x01, 0x6a, 0x49, 0x00, 0x79, 0x61, + 0x41, 0x6a, 0xed, 0x09, 0x00, 0xac, 0x00, 0x49, + 0x00, 0xb9, 0x61, 0x80, 0x6a, 0x40, 0x00, 0xf8, + 0x61, 0xf8, 0x1d, 0x19, 0x30, 0x21, 0x1c, 0x00, + 0xf0, 0xdd, 0xfe, 0x0b, 0x20, 0x39, 0x1c, 0xf6, + 0xf7, 0xc2, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, 0x80, + 0xb5, 0x0f, 0x1c, 0xff, 0xf7, 0x64, 0xf9, 0x00, + 0x28, 0x15, 0xd0, 0x37, 0x23, 0x9b, 0x01, 0xc0, + 0x18, 0x41, 0x6a, 0x00, 0x29, 0x0f, 0xd0, 0x00, + 0x21, 0x41, 0x62, 0xf6, 0xf7, 0x3d, 0xf8, 0x00, + 0x28, 0x06, 0xd0, 0x76, 0x21, 0x01, 0x60, 0xc7, + 0x60, 0x01, 0x1c, 0x09, 0x20, 0xf6, 0xf7, 0xa3, + 0xf8, 0x00, 0x20, 0xf8, 0xf7, 0x00, 0xf9, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xff, + 0xf7, 0xb0, 0xf9, 0x07, 0x1c, 0x0f, 0xd0, 0x38, + 0x1c, 0xff, 0xf7, 0x9a, 0xf9, 0x00, 0x28, 0x0a, + 0xd0, 0xf8, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x01, + 0x6b, 0x00, 0x29, 0x04, 0xd0, 0x00, 0x21, 0x01, + 0x63, 0x38, 0x1c, 0xfe, 0xf7, 0x90, 0xff, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x2a, + 0xf0, 0x7e, 0xfe, 0xff, 0x23, 0x03, 0x33, 0x98, + 0x42, 0x01, 0xd3, 0x07, 0x21, 0x00, 0xe0, 0x05, + 0x21, 0x01, 0x22, 0x00, 0x20, 0xf8, 0xf7, 0xde, + 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xff, + 0xf7, 0x88, 0xf9, 0x07, 0x1c, 0x0b, 0xd0, 0x38, + 0x1c, 0xff, 0xf7, 0x72, 0xf9, 0x00, 0x28, 0x06, + 0xd0, 0xf8, 0x6b, 0x00, 0x28, 0x03, 0xd0, 0x01, + 0x21, 0x38, 0x1c, 0x00, 0xf0, 0x66, 0xff, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xff, + 0xf7, 0x74, 0xf9, 0x07, 0x1c, 0x21, 0xd0, 0x38, + 0x1c, 0xff, 0xf7, 0x5e, 0xf9, 0x00, 0x28, 0x1c, + 0xd0, 0xf8, 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x01, + 0x6b, 0x00, 0x29, 0x16, 0xd0, 0xed, 0x09, 0x00, + 0xad, 0x00, 0x00, 0x21, 0x01, 0x63, 0x38, 0x1c, + 0x00, 0xf0, 0xb8, 0xf9, 0x38, 0x1c, 0x00, 0xf0, + 0xfb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0xf2, 0xfa, + 0xf5, 0xf7, 0xd5, 0xff, 0x00, 0x28, 0x07, 0xd0, + 0x6d, 0x21, 0x01, 0x60, 0xf9, 0x68, 0xc1, 0x60, + 0x01, 0x1c, 0x09, 0x20, 0xf6, 0xf7, 0x3a, 0xf8, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x97, 0xb5, + 0x83, 0xb0, 0xc4, 0x1d, 0xff, 0x34, 0x7a, 0x34, + 0x21, 0x6b, 0x00, 0x27, 0x00, 0x29, 0x02, 0xd0, + 0xff, 0x27, 0x02, 0x37, 0x11, 0xe0, 0x02, 0x68, + 0x40, 0x68, 0x00, 0x23, 0x81, 0x68, 0x09, 0x48, + 0x02, 0x92, 0x01, 0x91, 0x00, 0x90, 0x04, 0x98, + 0x05, 0x99, 0x01, 0x22, 0x1d, 0xf0, 0x98, 0xf8, + 0x20, 0x63, 0x00, 0x28, 0x01, 0xd1, 0xff, 0x27, + 0x02, 0x37, 0x38, 0x1c, 0x06, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x6f, 0xab, 0x00, 0x20, + 0x90, 0xb5, 0xc4, 0x1d, 0xff, 0x34, 0x7a, 0x34, + 0x20, 0x6b, 0x00, 0x27, 0x00, 0x28, 0x05, 0xd0, + 0x05, 0xa1, 0x1d, 0xf0, 0x4d, 0xf9, 0x00, 0x20, + 0x20, 0x63, 0x01, 0xe0, 0xff, 0x27, 0x02, 0x37, + 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x31, + 0x38, 0x38, 0x38, 0x00, 0x80, 0xb5, 0xff, 0xf7, + 0x07, 0xf9, 0x07, 0x1c, 0x10, 0xd0, 0x38, 0x1c, + 0xff, 0xf7, 0xf1, 0xf8, 0x00, 0x28, 0x0b, 0xd0, + 0xf8, 0x6a, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x20, + 0xf8, 0x62, 0xf9, 0xf7, 0xa7, 0xf9, 0x0a, 0x1c, + 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x40, 0xfe, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x97, 0xb5, + 0x83, 0xb0, 0x04, 0x1c, 0xc0, 0x6a, 0x00, 0x27, + 0x00, 0x28, 0x02, 0xd0, 0xff, 0x27, 0x02, 0x37, + 0xed, 0x09, 0x00, 0xae, 0x00, 0x11, 0xe0, 0x60, + 0x68, 0x22, 0x68, 0x81, 0x68, 0x09, 0x48, 0x02, + 0x92, 0x00, 0x23, 0x01, 0x91, 0x00, 0x90, 0x04, + 0x98, 0x05, 0x99, 0x01, 0x22, 0x1d, 0xf0, 0x3e, + 0xf8, 0xe0, 0x62, 0x00, 0x28, 0x01, 0xd1, 0xff, + 0x27, 0x02, 0x37, 0x38, 0x1c, 0x06, 0xb0, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x49, 0xac, 0x00, + 0x20, 0x90, 0xb5, 0x04, 0x1c, 0xc0, 0x6a, 0x00, + 0x27, 0x00, 0x28, 0x05, 0xd0, 0x05, 0xa1, 0x1d, + 0xf0, 0xf5, 0xf8, 0x00, 0x20, 0xe0, 0x62, 0x01, + 0xe0, 0xff, 0x27, 0x02, 0x37, 0x38, 0x1c, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x39, 0x34, 0x37, + 0x00, 0x80, 0xb4, 0x02, 0x1c, 0xd1, 0x1d, 0xff, + 0x31, 0x7a, 0x31, 0x4b, 0x69, 0x0f, 0x6a, 0xc9, + 0x69, 0xff, 0x32, 0xdb, 0x1b, 0x59, 0x1a, 0x41, + 0x32, 0x93, 0x68, 0x00, 0x20, 0x8b, 0x42, 0x01, + 0xd0, 0x01, 0x20, 0x91, 0x60, 0x80, 0xbc, 0x70, + 0x47, 0x80, 0xb5, 0xff, 0xf7, 0x9b, 0xf8, 0x07, + 0x1c, 0x19, 0xd0, 0x38, 0x1c, 0xff, 0xf7, 0x85, + 0xf8, 0x00, 0x28, 0x14, 0xd0, 0xf8, 0x1d, 0xf9, + 0x30, 0xc1, 0x6a, 0x00, 0x29, 0x0f, 0xd0, 0x00, + 0x21, 0xc1, 0x62, 0x80, 0x6b, 0x00, 0x28, 0x07, + 0xd0, 0x38, 0x1c, 0xff, 0xf7, 0xd5, 0xff, 0x00, + 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0xd8, + 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x1b, 0xf8, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xc7, + 0x1d, 0xf9, 0x37, 0xf8, 0x6a, 0x00, 0x28, 0x04, + 0xd0, 0x03, 0xa1, 0x1d, 0xf0, 0xa3, 0xf8, 0x00, + 0x20, 0xf8, 0x62, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0xed, 0x09, 0x00, 0xaf, 0x00, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x30, 0x31, + 0x36, 0x00, 0x90, 0xb5, 0x85, 0xb0, 0x07, 0x1c, + 0x00, 0x69, 0x05, 0x28, 0x1a, 0xd1, 0xfc, 0x1d, + 0xf9, 0x34, 0xe1, 0x6b, 0x00, 0x29, 0x15, 0xd0, + 0x38, 0x1c, 0x00, 0xf0, 0x76, 0xfe, 0x00, 0x21, + 0x03, 0xaa, 0xe0, 0x6b, 0x51, 0x60, 0x10, 0x60, + 0x78, 0x68, 0x3a, 0x68, 0x81, 0x68, 0x07, 0x48, + 0x02, 0x92, 0x00, 0x23, 0x01, 0x91, 0x00, 0x90, + 0x03, 0x98, 0x04, 0x99, 0x01, 0x22, 0x1c, 0xf0, + 0xa8, 0xff, 0xe0, 0x62, 0x05, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x21, 0xad, + 0x00, 0x20, 0x80, 0xb5, 0xff, 0xf7, 0x39, 0xf8, + 0x07, 0x1c, 0x11, 0xd0, 0x38, 0x1c, 0xff, 0xf7, + 0x23, 0xf8, 0x00, 0x28, 0x0c, 0xd0, 0xf8, 0x1d, + 0xf9, 0x30, 0x00, 0x6b, 0x00, 0x28, 0x07, 0xd0, + 0x38, 0x1c, 0xff, 0xf7, 0x78, 0xff, 0x00, 0x28, + 0x05, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x3d, 0xf8, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x68, + 0x80, 0x69, 0x01, 0x28, 0x10, 0xd1, 0xf8, 0x1d, + 0xff, 0x30, 0x3a, 0x30, 0x0c, 0x4a, 0x41, 0x68, + 0x12, 0x68, 0x91, 0x42, 0x08, 0xd2, 0x01, 0x31, + 0x41, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0x29, 0xf8, + 0x38, 0x1c, 0x01, 0xf0, 0x93, 0xfb, 0xe7, 0xe7, + 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x00, 0x20, + 0x48, 0x60, 0x01, 0x21, 0x38, 0x1c, 0x00, 0xf0, + 0x3c, 0xfe, 0xdd, 0xe7, 0x00, 0x00, 0x18, 0xec, + 0x03, 0x20, 0x80, 0xb5, 0xc7, 0x1d, 0xf9, 0x37, + 0x38, 0x6b, 0x00, 0x28, 0x04, 0xd0, 0x03, 0xa1, + 0x1d, 0xf0, 0x27, 0xf8, 0x00, 0x20, 0x38, 0x63, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0xed, 0x09, + 0x00, 0xb0, 0x00, 0x30, 0x38, 0x32, 0x00, 0xb0, + 0xb5, 0x89, 0xb0, 0x07, 0x1c, 0x00, 0x69, 0x05, + 0x28, 0x30, 0xd1, 0xfc, 0x1d, 0xf9, 0x34, 0xa1, + 0x6b, 0x00, 0x29, 0x2b, 0xd0, 0xe0, 0x6b, 0x00, + 0x28, 0x02, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0xf7, + 0xfd, 0x78, 0x68, 0x03, 0xad, 0x80, 0x69, 0x01, + 0x28, 0x0b, 0xd1, 0xf8, 0x1d, 0xff, 0x30, 0x3a, + 0x30, 0x41, 0x68, 0x00, 0x29, 0x05, 0xd0, 0x00, + 0x68, 0x00, 0x21, 0x05, 0x90, 0x05, 0xa8, 0x06, + 0x91, 0x04, 0xe0, 0xa0, 0x6b, 0x00, 0x21, 0x07, + 0x90, 0x07, 0xa8, 0x08, 0x91, 0x0c, 0xc8, 0x0c, + 0xc5, 0x78, 0x68, 0x3a, 0x68, 0x81, 0x68, 0x07, + 0x48, 0x02, 0x92, 0x00, 0x23, 0x01, 0x91, 0x00, + 0x90, 0x03, 0x98, 0x04, 0x99, 0x01, 0x22, 0x1c, + 0xf0, 0x16, 0xff, 0x20, 0x63, 0x09, 0xb0, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe5, + 0xad, 0x00, 0x20, 0x80, 0xb5, 0x07, 0x1c, 0xf9, + 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x00, 0x20, 0x48, + 0x60, 0x38, 0x1c, 0xff, 0xf7, 0xa0, 0xff, 0x38, + 0x1c, 0xff, 0xf7, 0xb5, 0xff, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0xc5, 0x1d, 0xff, + 0x35, 0xc4, 0x1d, 0xf9, 0x34, 0x3a, 0x35, 0x0f, + 0x1c, 0x00, 0x29, 0x1d, 0x4e, 0x25, 0xd0, 0x40, + 0x68, 0x80, 0x69, 0x01, 0x28, 0x21, 0xd1, 0x1b, + 0x48, 0x02, 0x68, 0x00, 0x2a, 0x03, 0xd1, 0x00, + 0x20, 0xa7, 0x63, 0x28, 0x60, 0x1e, 0xe0, 0x41, + 0x68, 0x13, 0x1c, 0x4b, 0x43, 0xbb, 0x42, 0x0d, + 0xd3, 0x10, 0x1c, 0x79, 0x1e, 0xf5, 0xf7, 0x73, + 0xf9, 0x28, 0x60, 0x00, 0x28, 0x02, 0xd0, 0x38, + 0x1a, 0xa0, 0x63, 0x0f, 0xe0, 0x01, 0x20, 0xa0, + 0x63, 0x28, 0x60, 0x0b, 0xe0, 0x29, 0x60, 0x01, + 0x68, 0x40, 0x68, 0x41, 0x43, 0x78, 0x1a, 0xa0, + 0x63, 0xed, 0x09, 0x00, 0xb1, 0x00, 0x04, 0xe0, + 0x00, 0x20, 0xa7, 0x63, 0x28, 0x60, 0x00, 0x2f, + 0x02, 0xd0, 0x09, 0x4b, 0x9f, 0x42, 0x03, 0xd9, + 0xe6, 0x63, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xb7, 0x42, 0x02, 0xd9, 0x05, 0x48, 0xe0, 0x63, + 0xf7, 0xe7, 0x00, 0x20, 0xe0, 0x63, 0xf4, 0xe7, + 0x40, 0x0d, 0x03, 0x00, 0x18, 0xec, 0x03, 0x20, + 0x80, 0x1a, 0x06, 0x00, 0xa0, 0x86, 0x01, 0x00, + 0x90, 0xb5, 0x04, 0x1c, 0xc0, 0x6b, 0x00, 0x27, + 0x00, 0x28, 0x05, 0xd0, 0x05, 0xa1, 0x1c, 0xf0, + 0x75, 0xff, 0x00, 0x20, 0xe0, 0x63, 0x01, 0xe0, + 0xff, 0x27, 0x02, 0x37, 0x38, 0x1c, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, 0x63, 0x5c, + 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, + 0x63, 0x3a, 0x20, 0x32, 0x31, 0x37, 0x32, 0x00, + 0x80, 0xb5, 0x83, 0xb0, 0x00, 0x21, 0x00, 0x22, + 0x0a, 0x48, 0x02, 0x92, 0x01, 0x91, 0x0a, 0xa1, + 0x00, 0x90, 0x08, 0x68, 0x00, 0x27, 0x00, 0x23, + 0x01, 0x22, 0x49, 0x68, 0x1c, 0xf0, 0x86, 0xfe, + 0x07, 0x49, 0x00, 0x28, 0x88, 0x61, 0x00, 0xd1, + 0x07, 0x27, 0x38, 0x1c, 0x03, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x27, 0xab, 0x00, 0x20, + 0x00, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0xec, 0x03, 0x20, 0x90, 0xb5, 0x08, 0x4c, + 0x00, 0x27, 0xa0, 0x69, 0x00, 0x28, 0x05, 0xd0, + 0x06, 0xa1, 0x1c, 0xf0, 0x37, 0xff, 0x00, 0x20, + 0xa0, 0x61, 0x01, 0xe0, 0xff, 0x27, 0x02, 0x37, + 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x18, 0xec, 0x03, 0x20, 0x73, 0x72, 0x63, 0x5c, + 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, + 0x63, 0x3a, 0x20, 0x32, 0x32, 0x30, 0x30, 0x00, + 0xb0, 0xb5, 0xc7, 0x1d, 0xff, 0x37, 0x3a, 0x37, + 0x38, 0x6a, 0x1e, 0x4c, 0xed, 0x09, 0x00, 0xb2, + 0x00, 0x03, 0x01, 0x1b, 0x19, 0xbc, 0x69, 0x01, + 0x34, 0xbc, 0x61, 0x5c, 0x68, 0x4c, 0x43, 0x99, + 0x68, 0x25, 0x1c, 0x51, 0x43, 0x00, 0x24, 0x8d, + 0x42, 0x13, 0xd3, 0x79, 0x69, 0xfa, 0x69, 0x8a, + 0x42, 0x0c, 0xd3, 0x00, 0x28, 0x05, 0xd0, 0x01, + 0x38, 0x38, 0x62, 0xbc, 0x61, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x29, 0xfa, 0xd0, 0x48, + 0x1e, 0x78, 0x61, 0xf7, 0xe7, 0x50, 0x1c, 0xf8, + 0x61, 0xf4, 0xe7, 0xf8, 0xf7, 0x5f, 0xff, 0x41, + 0x1e, 0x38, 0x6a, 0x81, 0x42, 0x06, 0xd9, 0xb9, + 0x69, 0x01, 0x29, 0x03, 0xd9, 0x01, 0x30, 0x38, + 0x62, 0xfc, 0x61, 0xbc, 0x61, 0x78, 0x69, 0x40, + 0x00, 0x78, 0x61, 0x10, 0x28, 0x02, 0xd9, 0x10, + 0x20, 0x78, 0x61, 0xdf, 0xe7, 0x00, 0x28, 0xdd, + 0xd1, 0x01, 0x20, 0x78, 0x61, 0xda, 0xe7, 0x00, + 0x00, 0x50, 0x7b, 0x03, 0x20, 0xf0, 0xb5, 0xfe, + 0xf7, 0xab, 0xfe, 0x07, 0x1c, 0x22, 0xd0, 0x38, + 0x1c, 0xfe, 0xf7, 0x95, 0xfe, 0x00, 0x28, 0x1d, + 0xd0, 0xf8, 0x1d, 0xf9, 0x30, 0x41, 0x6b, 0x00, + 0x29, 0x18, 0xd0, 0x39, 0x69, 0x05, 0x29, 0x15, + 0xd1, 0xf9, 0x1d, 0xff, 0x31, 0x7a, 0x31, 0xcd, + 0x68, 0x0e, 0x69, 0xfc, 0x1d, 0xff, 0x34, 0x00, + 0x21, 0x41, 0x63, 0x3a, 0x34, 0x20, 0x69, 0x32, + 0x1a, 0xe0, 0x68, 0x29, 0x1a, 0x38, 0x1c, 0xff, + 0xf7, 0x99, 0xff, 0xe5, 0x60, 0x26, 0x61, 0x38, + 0x1c, 0x00, 0xf0, 0x1c, 0xf8, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xc7, 0x1d, 0xf9, + 0x37, 0x78, 0x6b, 0x00, 0x28, 0x04, 0xd0, 0x04, + 0xa1, 0x1c, 0xf0, 0xaa, 0xfe, 0x00, 0x20, 0x78, + 0x63, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0xed, + 0x09, 0x00, 0xb3, 0x00, 0x20, 0x32, 0x33, 0x30, + 0x38, 0x00, 0x80, 0xb5, 0x83, 0xb0, 0x01, 0x69, + 0x05, 0x29, 0x13, 0xd1, 0xc7, 0x1d, 0xf9, 0x37, + 0x79, 0x6b, 0x00, 0x29, 0x0e, 0xd1, 0x02, 0x68, + 0x40, 0x68, 0x00, 0x23, 0x81, 0x68, 0x07, 0x48, + 0x02, 0x92, 0x01, 0x91, 0x07, 0xa1, 0x00, 0x90, + 0x08, 0x68, 0x49, 0x68, 0x01, 0x22, 0x1c, 0xf0, + 0xb6, 0xfd, 0x78, 0x63, 0x03, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x01, 0xb1, + 0x00, 0x20, 0x80, 0x84, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x1c, 0x15, 0x1c, + 0x0e, 0x1c, 0xf5, 0xf7, 0xbb, 0xfc, 0x07, 0x1c, + 0x1f, 0xd0, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, + 0x41, 0x6b, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x39, + 0x41, 0x63, 0x60, 0x68, 0x80, 0x69, 0x01, 0x28, + 0x02, 0xd1, 0x20, 0x1c, 0x00, 0xf0, 0x96, 0xf8, + 0x00, 0x21, 0x20, 0x1c, 0x00, 0xf0, 0x2d, 0xf8, + 0x79, 0x20, 0x38, 0x60, 0x3e, 0x61, 0xe0, 0x68, + 0xf8, 0x60, 0x28, 0x1c, 0x1d, 0xf0, 0x47, 0xf8, + 0x78, 0x61, 0x09, 0x20, 0x39, 0x1c, 0xf5, 0xf7, + 0x08, 0xfd, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0xb5, 0xfe, 0xf7, 0x18, 0xfe, 0x07, 0x1c, + 0x14, 0xd0, 0x38, 0x1c, 0xfe, 0xf7, 0x02, 0xfe, + 0x00, 0x28, 0x0f, 0xd0, 0xf8, 0x1d, 0xff, 0x30, + 0x3a, 0x30, 0x81, 0x6b, 0x00, 0x29, 0x09, 0xd0, + 0x39, 0x69, 0x05, 0x29, 0x06, 0xd1, 0x00, 0x21, + 0x81, 0x63, 0x0c, 0x21, 0x00, 0x22, 0x38, 0x1c, + 0xff, 0xf7, 0xbb, 0xff, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xb0, 0xb5, 0xc5, 0x1d, 0xff, 0x35, + 0x3a, 0x35, 0x07, 0x1c, 0xa8, 0x6b, 0x0c, 0x1c, + 0x00, 0x28, 0x0b, 0xd0, 0x07, 0xa1, 0x1c, 0xf0, + 0x22, 0xfe, 0x00, 0x20, 0xa8, 0x63, 0x00, 0x2c, + 0x04, 0xd0, 0xed, 0x09, 0x00, 0xb4, 0x00, 0x00, + 0x22, 0x0c, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xa3, + 0xff, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, + 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x33, + 0x39, 0x39, 0x00, 0x80, 0xb5, 0x83, 0xb0, 0x01, + 0x69, 0x05, 0x29, 0x14, 0xd1, 0xc7, 0x1d, 0xff, + 0x37, 0x3a, 0x37, 0xb9, 0x6b, 0x00, 0x29, 0x0e, + 0xd1, 0x02, 0x68, 0x40, 0x68, 0x00, 0x23, 0x81, + 0x68, 0x07, 0x48, 0x02, 0x92, 0x01, 0x91, 0x06, + 0xa1, 0x00, 0x90, 0x08, 0x68, 0x49, 0x68, 0x01, + 0x22, 0x1c, 0xf0, 0x27, 0xfd, 0xb8, 0x63, 0x03, + 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x27, + 0xb2, 0x00, 0x20, 0x40, 0x77, 0x1b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xb5, 0xfe, 0xf7, 0xb5, + 0xfd, 0x07, 0x1c, 0x16, 0xd0, 0x38, 0x1c, 0xfe, + 0xf7, 0x9f, 0xfd, 0x00, 0x28, 0x11, 0xd0, 0xf8, + 0x1d, 0xff, 0x30, 0x3a, 0x30, 0xc1, 0x6b, 0x00, + 0x29, 0x0b, 0xd0, 0x39, 0x69, 0x05, 0x29, 0x08, + 0xd1, 0x00, 0x21, 0xc1, 0x63, 0x38, 0x1c, 0x01, + 0xf0, 0x25, 0xf9, 0x00, 0x21, 0x38, 0x1c, 0x00, + 0xf0, 0x1c, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x80, 0xb5, 0xc7, 0x1d, 0xff, 0x37, 0x3a, + 0x37, 0xf8, 0x6b, 0x00, 0x28, 0x04, 0xd0, 0x03, + 0xa1, 0x1c, 0xf0, 0xbf, 0xfd, 0x00, 0x20, 0xf8, + 0x63, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, + 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x34, + 0x35, 0x38, 0x00, 0x80, 0xb5, 0x83, 0xb0, 0x0b, + 0x1c, 0x01, 0x69, 0x05, 0x29, 0x18, 0xd1, 0xc7, + 0x1d, 0xff, 0x37, 0x3a, 0x37, 0xf9, 0x6b, 0x00, + 0x29, 0x12, 0xd1, 0x02, 0x68, 0x40, 0x68, 0x00, + 0x2b, 0x81, 0x68, 0x09, 0x48, 0xed, 0x09, 0x00, + 0xb5, 0x00, 0x02, 0x92, 0x01, 0x91, 0x00, 0x90, + 0x01, 0xd0, 0x08, 0xa1, 0x00, 0xe0, 0x09, 0xa1, + 0x08, 0x68, 0x00, 0x23, 0x01, 0x22, 0x49, 0x68, + 0x1c, 0xf0, 0xc6, 0xfc, 0xf8, 0x63, 0x03, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0xed, 0xb2, 0x00, 0x20, 0x40, 0x0d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0xa1, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf3, 0xb5, 0x81, 0xb0, + 0x00, 0x24, 0x37, 0x23, 0x9b, 0x01, 0xc1, 0x18, + 0x00, 0x91, 0x4e, 0x6b, 0x05, 0x1c, 0x00, 0x2e, + 0x02, 0xd1, 0xff, 0x24, 0x0c, 0x34, 0x2f, 0xe0, + 0x30, 0x69, 0x02, 0x28, 0x02, 0xd0, 0xff, 0x24, + 0x0a, 0x34, 0x29, 0xe0, 0xf5, 0xf7, 0xb7, 0xfb, + 0x07, 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x23, 0xe0, + 0x00, 0x99, 0x00, 0x20, 0x48, 0x63, 0x02, 0x99, + 0x00, 0x29, 0x0c, 0xd1, 0x05, 0x20, 0x30, 0x61, + 0x1a, 0x20, 0x28, 0x61, 0x30, 0x1c, 0xff, 0xf7, + 0x81, 0xfd, 0x30, 0x1c, 0xff, 0xf7, 0xc4, 0xfc, + 0x30, 0x1c, 0xff, 0xf7, 0xbb, 0xfe, 0x70, 0x20, + 0x38, 0x60, 0xf0, 0x68, 0xf8, 0x60, 0x02, 0x99, + 0xf0, 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x39, 0x61, + 0x01, 0x68, 0x79, 0x61, 0x40, 0x68, 0xb8, 0x61, + 0x09, 0x20, 0x39, 0x1c, 0xf5, 0xf7, 0xfe, 0xfb, + 0x20, 0x1c, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x21, 0x01, 0x61, 0x08, 0x1c, + 0x70, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xb6, 0xff, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x90, 0xb5, + 0xff, 0x23, 0x11, 0x33, 0x00, 0x24, 0x07, 0x1c, + 0x99, 0x42, 0x06, 0xd1, 0x1a, 0x20, 0x37, 0x23, + 0x9b, 0x01, 0x38, 0x61, 0xf8, 0x18, 0x44, 0x63, + 0x0b, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0xa2, 0xff, + 0x00, 0x28, 0x06, 0xd0, 0x38, 0x69, 0x00, 0x28, + 0xed, 0x09, 0x00, 0xb6, 0x00, 0x03, 0xd1, 0x38, + 0x1c, 0x03, 0xa1, 0xfe, 0xf7, 0x1d, 0xfc, 0x20, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x32, 0x35, 0x37, 0x39, 0x00, 0x90, 0xb5, 0x83, + 0xb0, 0x07, 0x1c, 0x0f, 0x48, 0x1c, 0xf0, 0x4c, + 0xfe, 0x00, 0x21, 0x0e, 0x4a, 0xf5, 0xf7, 0x00, + 0xf9, 0x0b, 0x1c, 0xb9, 0x68, 0x04, 0x1c, 0x0c, + 0x48, 0x00, 0x22, 0x01, 0x91, 0x19, 0x1c, 0x02, + 0x92, 0x01, 0x22, 0x00, 0x23, 0x00, 0x90, 0x20, + 0x1c, 0x1c, 0xf0, 0x28, 0xfc, 0x37, 0x23, 0x9b, + 0x01, 0xf9, 0x18, 0x88, 0x62, 0x03, 0xb0, 0x90, + 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0x00, 0xdf, 0x03, 0x00, 0x00, 0xe2, 0x04, 0x00, + 0x00, 0xa9, 0xa9, 0x00, 0x20, 0x90, 0xb5, 0x37, + 0x23, 0x9b, 0x01, 0xc4, 0x18, 0xa0, 0x6a, 0x00, + 0x27, 0x00, 0x28, 0x03, 0xd0, 0x03, 0xa1, 0x1c, + 0xf0, 0xd9, 0xfc, 0xa7, 0x62, 0x38, 0x1c, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x36, 0x30, 0x36, + 0x00, 0x90, 0xb5, 0x37, 0x23, 0x9b, 0x01, 0xc4, + 0x18, 0xe0, 0x6a, 0x00, 0x27, 0x00, 0x28, 0x03, + 0xd0, 0x03, 0xa1, 0x1c, 0xf0, 0xbf, 0xfc, 0xe7, + 0x62, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x32, 0x36, 0x32, 0x30, 0x00, 0x90, 0xb5, 0x37, + 0x23, 0x9b, 0x01, 0xc4, 0x18, 0xe0, 0x6a, 0x00, + 0x27, 0x00, 0x28, 0x03, 0xd0, 0x03, 0xa1, 0x1c, + 0xf0, 0xa5, 0xfc, 0xe7, 0x62, 0x38, 0x1c, 0x90, + 0xbc, 0x08, 0xbc, 0xed, 0x09, 0x00, 0xb7, 0x00, + 0x18, 0x47, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x32, 0x36, 0x33, 0x37, 0x00, 0xf8, 0xb5, + 0x04, 0x1c, 0x08, 0x7a, 0xff, 0x23, 0xb5, 0x33, + 0x58, 0x43, 0x00, 0x19, 0xc5, 0x1d, 0x80, 0x6c, + 0x31, 0x35, 0x0e, 0x1c, 0x00, 0x28, 0x42, 0xd1, + 0xf5, 0xf7, 0xd2, 0xfa, 0x07, 0x1c, 0x3e, 0xd0, + 0x03, 0x23, 0xb0, 0x6c, 0x1b, 0x04, 0x18, 0x40, + 0x06, 0x0c, 0x05, 0x20, 0x28, 0x61, 0xe8, 0x1d, + 0xff, 0x30, 0x7a, 0x30, 0x00, 0x90, 0x46, 0x60, + 0x28, 0x1c, 0x1a, 0x49, 0xff, 0xf7, 0xab, 0xfc, + 0x1a, 0x20, 0x20, 0x61, 0x28, 0x1c, 0xff, 0xf7, + 0x96, 0xfc, 0x28, 0x1c, 0xff, 0xf7, 0xd9, 0xfb, + 0x28, 0x1c, 0xff, 0xf7, 0xd0, 0xfd, 0xff, 0xf7, + 0x28, 0xfd, 0x2a, 0xf0, 0x1c, 0xf9, 0xff, 0x23, + 0x03, 0x33, 0x98, 0x42, 0x01, 0xd3, 0x07, 0x21, + 0x00, 0xe0, 0x05, 0x21, 0x01, 0x22, 0x00, 0x20, + 0xf7, 0xf7, 0x7c, 0xff, 0x71, 0x20, 0x38, 0x60, + 0xfd, 0x60, 0x28, 0x6a, 0xe9, 0x1d, 0x38, 0x61, + 0x0d, 0x31, 0x28, 0xc9, 0xf8, 0x1d, 0x0d, 0x30, + 0x28, 0xc0, 0x00, 0x98, 0x00, 0x68, 0xf8, 0x61, + 0x09, 0x20, 0x39, 0x1c, 0x3e, 0x62, 0xf5, 0xf7, + 0x02, 0xfb, 0xfe, 0xf7, 0xde, 0xfc, 0xf8, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x5a, + 0x62, 0x02, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, + 0x70, 0x47, 0x00, 0xb5, 0x02, 0x1c, 0x08, 0x1c, + 0x11, 0x1c, 0x00, 0x22, 0xfe, 0xf7, 0x20, 0xfa, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0xf0, 0xb5, + 0x04, 0x1c, 0x48, 0x6a, 0xff, 0x23, 0xb5, 0x33, + 0x58, 0x43, 0x00, 0x19, 0xc6, 0x1d, 0x80, 0x6c, + 0x31, 0x36, 0x00, 0x27, 0x0d, 0x1c, 0x00, 0x28, + 0x02, 0xd0, 0xff, 0x27, 0x0a, 0x37, 0xed, 0x09, + 0x00, 0xb8, 0x00, 0x13, 0xe0, 0x30, 0x1c, 0x29, + 0x1c, 0x00, 0xf0, 0x38, 0xfc, 0xa8, 0x6c, 0x1c, + 0xf0, 0x0e, 0xfe, 0x00, 0x22, 0x21, 0x1c, 0xa8, + 0x6c, 0xfe, 0xf7, 0x00, 0xfa, 0x06, 0x48, 0xf2, + 0x1d, 0xff, 0x32, 0xc1, 0x6b, 0x7a, 0x32, 0x51, + 0x60, 0x80, 0x6b, 0x10, 0x60, 0x38, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xd8, + 0xeb, 0x03, 0x20, 0x00, 0x20, 0x70, 0x47, 0x90, + 0xb5, 0x37, 0x23, 0x9b, 0x01, 0xc4, 0x18, 0x60, + 0x6a, 0x00, 0x27, 0x00, 0x28, 0x03, 0xd0, 0x03, + 0xa1, 0x1c, 0xf0, 0xf9, 0xfb, 0x67, 0x62, 0x38, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, + 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x37, + 0x36, 0x36, 0x00, 0xb0, 0xb5, 0x00, 0x27, 0x0c, + 0x1c, 0xf5, 0xf7, 0x30, 0xfa, 0x00, 0x28, 0x01, + 0xd1, 0x07, 0x27, 0x31, 0xe0, 0x77, 0x21, 0x01, + 0x60, 0x61, 0x68, 0x89, 0x01, 0x09, 0x0a, 0xc1, + 0x60, 0xe5, 0x1d, 0x29, 0x35, 0x0c, 0xcd, 0xc1, + 0x1d, 0x09, 0x31, 0x0c, 0xc1, 0x21, 0x6b, 0xc2, + 0x69, 0x14, 0x4b, 0x09, 0x02, 0x09, 0x0a, 0x1a, + 0x40, 0x89, 0x00, 0x11, 0x43, 0xc1, 0x61, 0x22, + 0x6b, 0x12, 0x0e, 0x06, 0xd3, 0x89, 0x01, 0x89, + 0x09, 0x13, 0x23, 0x9b, 0x06, 0x19, 0x43, 0xc1, + 0x61, 0x04, 0xe0, 0x89, 0x01, 0x0c, 0x4b, 0x89, + 0x09, 0x19, 0x43, 0xc1, 0x61, 0xa1, 0x69, 0x01, + 0x62, 0xe1, 0x69, 0x41, 0x62, 0xe1, 0x6a, 0x81, + 0x62, 0x21, 0x6a, 0x01, 0x63, 0xa1, 0x6a, 0xc1, + 0x62, 0x01, 0x1c, 0x09, 0x20, 0xf5, 0xf7, 0x69, + 0xfa, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x03, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0x00, 0xb0, 0x00, 0xb5, 0x37, 0x23, 0x9b, + 0x01, 0xed, 0x09, 0x00, 0xb9, 0x00, 0xc2, 0x18, + 0x52, 0x6b, 0x8b, 0x6c, 0x01, 0x1c, 0x18, 0x1c, + 0xfe, 0xf7, 0x87, 0xf9, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x29, + 0x06, 0xd0, 0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, + 0x40, 0x6b, 0x88, 0x42, 0x00, 0xd1, 0x08, 0x69, + 0x00, 0x20, 0x70, 0x47, 0xb0, 0xb5, 0x04, 0x1c, + 0x08, 0x7a, 0xff, 0x23, 0xb5, 0x33, 0x58, 0x43, + 0x00, 0x19, 0x00, 0x27, 0x37, 0x23, 0x9b, 0x01, + 0xc5, 0x1d, 0xe0, 0x18, 0x40, 0x6b, 0x31, 0x35, + 0x00, 0x28, 0x01, 0xd0, 0xa8, 0x42, 0x02, 0xd0, + 0xff, 0x27, 0x12, 0x37, 0x0f, 0xe0, 0x28, 0x69, + 0x02, 0x28, 0x02, 0xd0, 0xff, 0x27, 0x0a, 0x37, + 0x09, 0xe0, 0x28, 0x1c, 0xfe, 0xf7, 0x12, 0xf9, + 0x28, 0x1c, 0xff, 0xf7, 0xed, 0xfb, 0x00, 0x21, + 0x20, 0x1c, 0xff, 0xf7, 0xe5, 0xfd, 0x38, 0x1c, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x29, + 0x06, 0xd0, 0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, + 0x40, 0x6b, 0x88, 0x42, 0x00, 0xd1, 0x08, 0x69, + 0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x0b, 0x7a, + 0x4a, 0x6a, 0x01, 0x2b, 0x1f, 0xd3, 0x08, 0x2b, + 0x1d, 0xd2, 0x01, 0x2a, 0x1b, 0xd3, 0x08, 0x2a, + 0x19, 0xd2, 0x1f, 0x1c, 0xff, 0x23, 0xb5, 0x33, + 0x7b, 0x43, 0x18, 0x18, 0xc7, 0x1d, 0x80, 0x6c, + 0x31, 0x37, 0x01, 0x28, 0x01, 0xd0, 0x05, 0x28, + 0x0d, 0xd1, 0xf8, 0x6c, 0x00, 0x28, 0x0a, 0xd0, + 0xff, 0x23, 0xb5, 0x33, 0x5a, 0x43, 0x78, 0x6d, + 0x10, 0x18, 0xc4, 0x1d, 0x31, 0x34, 0x20, 0x1c, + 0x00, 0xf0, 0x4f, 0xfb, 0x27, 0x65, 0x90, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x02, 0x49, + 0x0c, 0xc9, 0x0c, 0xc0, 0x70, 0x47, 0x00, 0x00, + 0xb8, 0xeb, 0x03, 0x20, 0xff, 0xb5, 0x81, 0xb0, + 0x00, 0x27, 0x01, 0x20, 0xed, 0x09, 0x00, 0xba, + 0x00, 0x14, 0x1c, 0x0d, 0x1c, 0x0c, 0x9e, 0xfe, + 0xf7, 0x9f, 0xfa, 0x00, 0x28, 0x02, 0xd1, 0x01, + 0x20, 0xfe, 0xf7, 0x6e, 0xfa, 0x02, 0x2d, 0x24, + 0xd1, 0x03, 0x20, 0xfe, 0xf7, 0x4d, 0xfa, 0x04, + 0x1c, 0x0b, 0xd1, 0x04, 0x20, 0xfe, 0xf7, 0x48, + 0xfa, 0x04, 0x1c, 0x06, 0xd1, 0x05, 0x20, 0xfe, + 0xf7, 0x43, 0xfa, 0x04, 0x1c, 0x01, 0xd1, 0x0c, + 0x27, 0x95, 0xe0, 0xf5, 0xf7, 0x50, 0xf9, 0x05, + 0x1c, 0x01, 0xd1, 0x07, 0x27, 0x8f, 0xe0, 0x00, + 0x22, 0x03, 0x21, 0x20, 0x1c, 0xfe, 0xf7, 0x34, + 0xf9, 0x04, 0x20, 0x28, 0x60, 0xe0, 0x68, 0xe8, + 0x60, 0x0b, 0x20, 0x29, 0x1c, 0xf5, 0xf7, 0xae, + 0xf9, 0x81, 0xe0, 0x02, 0x2c, 0x24, 0xd1, 0x07, + 0x20, 0xfe, 0xf7, 0x26, 0xfa, 0x04, 0x1c, 0x0b, + 0xd1, 0x08, 0x20, 0xfe, 0xf7, 0x21, 0xfa, 0x04, + 0x1c, 0x06, 0xd1, 0x09, 0x20, 0xfe, 0xf7, 0x1c, + 0xfa, 0x04, 0x1c, 0x01, 0xd1, 0x0c, 0x27, 0x6e, + 0xe0, 0xf5, 0xf7, 0x29, 0xf9, 0x05, 0x1c, 0x01, + 0xd1, 0x07, 0x27, 0x68, 0xe0, 0x00, 0x22, 0x03, + 0x21, 0x20, 0x1c, 0xfe, 0xf7, 0x0d, 0xf9, 0x0a, + 0x20, 0x28, 0x60, 0xe0, 0x68, 0xe8, 0x60, 0x0b, + 0x20, 0x29, 0x1c, 0xf5, 0xf7, 0x87, 0xf9, 0x5a, + 0xe0, 0x0b, 0x98, 0x76, 0x00, 0x40, 0x00, 0x00, + 0x90, 0x01, 0x2d, 0x2c, 0xd1, 0x2c, 0xa1, 0x02, + 0x20, 0xfe, 0xf7, 0x94, 0xf9, 0x05, 0x1c, 0x01, + 0xd1, 0x07, 0x27, 0x4c, 0xe0, 0xf5, 0xf7, 0x07, + 0xf9, 0x04, 0x1c, 0x05, 0xd1, 0x28, 0x1c, 0x2b, + 0xa1, 0xfe, 0xf7, 0xb8, 0xf9, 0x07, 0x27, 0x42, + 0xe0, 0x00, 0x22, 0x01, 0x21, 0x28, 0x1c, 0xfe, + 0xf7, 0xe7, 0xf8, 0x03, 0x20, 0x20, 0x60, 0xe5, + 0x60, 0x04, 0x9b, 0x58, 0x00, 0x20, 0x61, 0x0a, + 0x98, 0x40, 0x00, 0x60, 0x61, 0x00, 0x98, 0xed, + 0x09, 0x00, 0xbb, 0x00, 0xa0, 0x61, 0xe0, 0x1d, + 0x19, 0x30, 0x29, 0x1c, 0xe6, 0x61, 0xff, 0xf7, + 0x6f, 0xff, 0x0b, 0x20, 0x21, 0x1c, 0xf5, 0xf7, + 0x54, 0xf9, 0x27, 0xe0, 0x01, 0x2c, 0x25, 0xd1, + 0x1f, 0xa1, 0x02, 0x20, 0xfe, 0xf7, 0x65, 0xf9, + 0x05, 0x1c, 0x01, 0xd1, 0x07, 0x27, 0x1d, 0xe0, + 0xf5, 0xf7, 0xd8, 0xf8, 0x04, 0x1c, 0x05, 0xd1, + 0x28, 0x1c, 0x1d, 0xa1, 0xfe, 0xf7, 0x89, 0xf9, + 0x07, 0x27, 0x13, 0xe0, 0x37, 0x23, 0x9b, 0x01, + 0x01, 0x98, 0xe9, 0x18, 0x08, 0x63, 0x06, 0x21, + 0x00, 0x22, 0x28, 0x1c, 0xfe, 0xf7, 0xb3, 0xf8, + 0x09, 0x20, 0x20, 0x60, 0xe5, 0x60, 0x00, 0x98, + 0x20, 0x61, 0x0b, 0x20, 0x21, 0x1c, 0x66, 0x61, + 0xf5, 0xf7, 0x2b, 0xf9, 0x38, 0x1c, 0x05, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x30, 0x34, + 0x32, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x33, 0x30, 0x34, 0x38, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x30, 0x36, + 0x39, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x33, 0x30, 0x37, 0x35, 0x00, 0xf3, 0xb5, + 0x00, 0x24, 0x07, 0x1c, 0xfe, 0xf7, 0xfe, 0xf9, + 0x06, 0x1c, 0x02, 0xd1, 0xff, 0x24, 0x0c, 0x34, + 0x24, 0xe0, 0x38, 0x69, 0x02, 0x28, 0x04, 0xd0, + 0x05, 0x28, 0x02, 0xd0, 0xff, 0x24, 0x0a, 0x34, + 0x1c, 0xe0, 0xf5, 0xf7, 0x7b, 0xf8, 0x05, 0x1c, + 0x02, 0xd1, 0xff, 0x24, 0x01, 0x34, 0x15, 0xe0, + 0x38, 0x1c, 0xfd, 0xf7, 0xcc, 0xff, 0x01, 0x99, + 0x00, 0x29, 0xed, 0x09, 0x00, 0xbc, 0x00, 0x02, + 0xd1, 0x38, 0x1c, 0xff, 0xf7, 0xa4, 0xfa, 0x09, + 0x21, 0x30, 0x1c, 0x3a, 0x1c, 0xfe, 0xf7, 0x55, + 0xf8, 0x08, 0x20, 0x28, 0x60, 0xb8, 0x68, 0xe8, + 0x60, 0x0b, 0x20, 0x29, 0x1c, 0xf5, 0xf7, 0xcf, + 0xf8, 0x20, 0x1c, 0x02, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xfe, + 0xf7, 0xcb, 0xf9, 0x00, 0x28, 0x0e, 0xd0, 0x38, + 0x69, 0x05, 0x28, 0x0b, 0xd1, 0xf5, 0xf7, 0x50, + 0xf8, 0x00, 0x28, 0x07, 0xd0, 0x20, 0x21, 0x01, + 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x01, 0x1c, 0x0b, + 0x20, 0xf5, 0xf7, 0xb5, 0xf8, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x00, 0x24, 0x0d, + 0x1c, 0x07, 0x1c, 0xfe, 0xf7, 0xb1, 0xf9, 0x00, + 0x28, 0x02, 0xd1, 0xff, 0x24, 0x0c, 0x34, 0x54, + 0xe0, 0x38, 0x69, 0x05, 0x28, 0x04, 0xd0, 0x02, + 0x28, 0x02, 0xd0, 0xff, 0x24, 0x0a, 0x34, 0x4c, + 0xe0, 0xfe, 0x1d, 0xf9, 0x36, 0x00, 0x2d, 0x05, + 0xd1, 0x30, 0x6b, 0x00, 0x28, 0x02, 0xd0, 0x38, + 0x1c, 0xff, 0xf7, 0xab, 0xf9, 0x38, 0x69, 0x02, + 0x28, 0x08, 0xd1, 0x00, 0x2d, 0x01, 0xd1, 0x01, + 0x20, 0x38, 0x64, 0x00, 0x21, 0x38, 0x1c, 0xff, + 0xf7, 0x8c, 0xff, 0x36, 0xe0, 0xf5, 0xf7, 0x18, + 0xf8, 0x05, 0x1c, 0x02, 0xd1, 0xff, 0x24, 0x01, + 0x34, 0x2f, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0x19, + 0xf9, 0x38, 0x1c, 0xff, 0xf7, 0x0f, 0xfb, 0x38, + 0x1c, 0xff, 0xf7, 0xf6, 0xfb, 0x01, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0x8d, 0xfb, 0x38, 0x1c, 0xff, + 0xf7, 0x60, 0xf8, 0x38, 0x1c, 0xfd, 0xf7, 0x59, + 0xff, 0x38, 0x1c, 0xff, 0xf7, 0x34, 0xfa, 0xb0, + 0x6a, 0x00, 0x28, 0x03, 0xd0, 0x00, 0x21, 0x38, + 0x1c, 0xf7, 0xf7, 0xb3, 0xfe, 0x00, 0x21, 0x38, + 0x1c, 0xf7, 0xf7, 0x3b, 0xfe, 0xed, 0x09, 0x00, + 0xbd, 0x00, 0x03, 0x20, 0x38, 0x61, 0x14, 0x20, + 0x28, 0x60, 0xb8, 0x68, 0x01, 0x22, 0xe8, 0x60, + 0x79, 0x68, 0x38, 0x1c, 0xfe, 0xf7, 0x86, 0xf9, + 0x0b, 0x20, 0x29, 0x1c, 0xf5, 0xf7, 0x52, 0xf8, + 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x0c, 0x48, 0x00, 0x69, 0x00, 0x28, 0x13, 0xd0, + 0x01, 0x21, 0xff, 0x22, 0xb5, 0x32, 0x4a, 0x43, + 0x12, 0x18, 0x92, 0x6c, 0x05, 0x2a, 0x05, 0xd1, + 0xff, 0x23, 0xb5, 0x33, 0x59, 0x43, 0x08, 0x18, + 0x38, 0x30, 0x70, 0x47, 0x01, 0x31, 0x08, 0x29, + 0xef, 0xd3, 0x00, 0x68, 0x00, 0x28, 0xeb, 0xd1, + 0x00, 0x20, 0x70, 0x47, 0x98, 0xeb, 0x03, 0x20, + 0x80, 0xb5, 0x88, 0x42, 0x01, 0xd1, 0x00, 0x27, + 0x06, 0xe0, 0x01, 0x23, 0xdb, 0x02, 0x98, 0x42, + 0x01, 0xd8, 0x01, 0x27, 0x00, 0xe0, 0x02, 0x27, + 0xf4, 0xf7, 0xb5, 0xff, 0x00, 0x28, 0x06, 0xd0, + 0x1d, 0x21, 0x01, 0x60, 0xc7, 0x60, 0x01, 0x1c, + 0x0b, 0x20, 0xf5, 0xf7, 0x1b, 0xf8, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x1c, 0x1c, + 0x15, 0x1c, 0x0e, 0x1c, 0x07, 0x1c, 0xfe, 0xf7, + 0x16, 0xf9, 0x00, 0x28, 0x2b, 0xd0, 0x38, 0x69, + 0x05, 0x28, 0x28, 0xd1, 0xf4, 0xf7, 0x9b, 0xff, + 0x00, 0x28, 0x24, 0xd0, 0x10, 0x21, 0x01, 0x60, + 0xb9, 0x68, 0xc1, 0x60, 0x71, 0x00, 0x01, 0x61, + 0x69, 0x00, 0x41, 0x61, 0x00, 0x21, 0x81, 0x61, + 0xc1, 0x61, 0x01, 0x1c, 0x0b, 0x20, 0xf4, 0xf7, + 0xf9, 0xff, 0x38, 0x1c, 0xff, 0xf7, 0x0c, 0xf9, + 0x38, 0x1c, 0xff, 0xf7, 0x8d, 0xf8, 0x38, 0x1c, + 0xff, 0xf7, 0x83, 0xfa, 0x38, 0x1c, 0xff, 0xf7, + 0x6a, 0xfb, 0x01, 0x21, 0x38, 0x1c, 0xff, 0xf7, + 0x01, 0xfb, 0x04, 0x49, 0x00, 0x22, 0x61, 0x43, + 0x38, 0x1c, 0xfe, 0xf7, 0xac, 0xff, 0xf0, 0xbc, + 0xed, 0x09, 0x00, 0xbe, 0x00, 0x08, 0xbc, 0x18, + 0x47, 0xe2, 0x04, 0x00, 0x00, 0xff, 0xb5, 0x14, + 0x1c, 0x0d, 0x1c, 0x07, 0x1c, 0x09, 0x9e, 0xfe, + 0xf7, 0xdc, 0xf8, 0x00, 0x28, 0x10, 0xd0, 0x38, + 0x69, 0x05, 0x28, 0x0d, 0xd1, 0xf4, 0xf7, 0x61, + 0xff, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x2c, 0x0b, + 0xd1, 0x11, 0x21, 0x01, 0x60, 0xb9, 0x68, 0xc1, + 0x60, 0x01, 0x1c, 0x0b, 0x20, 0xf4, 0xf7, 0xc4, + 0xff, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x10, 0x21, 0x01, 0x60, 0xb9, 0x68, 0xc1, + 0x60, 0x69, 0x00, 0x01, 0x61, 0x61, 0x00, 0x41, + 0x61, 0x03, 0x9b, 0x99, 0x00, 0x81, 0x61, 0xb1, + 0x00, 0xc1, 0x61, 0x01, 0x1c, 0x0b, 0x20, 0xf4, + 0xf7, 0xaf, 0xff, 0xe9, 0xe7, 0x90, 0xb5, 0x17, + 0x1c, 0x00, 0x29, 0x20, 0xd0, 0x07, 0x29, 0x1e, + 0xd8, 0x00, 0x28, 0x1c, 0xd0, 0x07, 0x23, 0x5b, + 0x02, 0xc2, 0x18, 0x92, 0x68, 0x0d, 0x4b, 0x9a, + 0x42, 0x15, 0xd1, 0xff, 0x23, 0xb5, 0x33, 0x59, + 0x43, 0x08, 0x18, 0xc4, 0x1d, 0x80, 0x6c, 0x31, + 0x34, 0x00, 0x28, 0x0c, 0xd1, 0xf4, 0xf7, 0x25, + 0xff, 0x00, 0x28, 0x08, 0xd0, 0x1c, 0x21, 0xa7, + 0x60, 0x01, 0x60, 0x04, 0x61, 0xc7, 0x60, 0x01, + 0x1c, 0x0b, 0x20, 0xf4, 0xf7, 0x89, 0xff, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x11, 0x19, 0x03, + 0x64, 0x90, 0xb5, 0xc4, 0x68, 0x07, 0x1c, 0x20, + 0x1c, 0xfe, 0xf7, 0x83, 0xf8, 0x00, 0x28, 0x1e, + 0xd0, 0x20, 0x69, 0x05, 0x28, 0x1b, 0xd1, 0xf4, + 0xf7, 0x08, 0xff, 0x00, 0x28, 0x17, 0xd0, 0x7f, + 0x21, 0x01, 0x60, 0xe1, 0x68, 0xfc, 0x1d, 0xc1, + 0x60, 0x00, 0x21, 0x01, 0x61, 0x39, 0x69, 0x0d, + 0x34, 0x41, 0x61, 0x0c, 0xcc, 0xc1, 0x1d, 0x11, + 0x31, 0x0c, 0xc1, 0xf9, 0x69, 0x01, 0x62, 0x39, + 0x6a, 0x41, 0x62, 0xed, 0x09, 0x00, 0xbf, 0x00, + 0x79, 0x6a, 0x81, 0x62, 0x01, 0x1c, 0x09, 0x20, + 0xf4, 0xf7, 0x5d, 0xff, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf8, 0xb5, 0xc5, 0x68, 0x04, 0x1c, + 0x28, 0x1c, 0xfe, 0xf7, 0x59, 0xf8, 0x07, 0x1c, + 0x44, 0xd0, 0x28, 0x69, 0x05, 0x28, 0x41, 0xd1, + 0xf8, 0xf7, 0x11, 0xf9, 0x21, 0xa3, 0x1a, 0x68, + 0x5b, 0x68, 0x04, 0xf0, 0x10, 0xff, 0x00, 0x90, + 0xe6, 0x1d, 0x09, 0x36, 0x0e, 0xce, 0xe8, 0x1d, + 0xff, 0x30, 0x86, 0x30, 0x0e, 0xc0, 0x0e, 0xce, + 0x0e, 0xc0, 0xea, 0x1d, 0xff, 0x32, 0xa0, 0x6a, + 0x7a, 0x32, 0x90, 0x60, 0xe8, 0x1d, 0xff, 0x30, + 0x3a, 0x30, 0x83, 0x6a, 0xd1, 0x68, 0x44, 0x6a, + 0xc9, 0x1a, 0xd3, 0x6a, 0x43, 0x62, 0xc9, 0x18, + 0x09, 0x1b, 0xd2, 0x68, 0x07, 0x23, 0x5b, 0x02, + 0x82, 0x62, 0xf8, 0x18, 0x02, 0x68, 0x8a, 0x42, + 0x06, 0xd0, 0x01, 0x60, 0x37, 0x23, 0x9b, 0x01, + 0x00, 0x98, 0xf9, 0x18, 0xc8, 0x63, 0x11, 0xe0, + 0x37, 0x23, 0x9b, 0x01, 0xff, 0x18, 0xf9, 0x6b, + 0x00, 0x29, 0x0b, 0xd0, 0x00, 0x9a, 0x08, 0x4b, + 0x51, 0x1a, 0x99, 0x42, 0x06, 0xd9, 0x42, 0x68, + 0x00, 0x21, 0x28, 0x1c, 0xf7, 0xf7, 0x77, 0xfc, + 0x00, 0x20, 0xf8, 0x63, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x88, 0x13, 0x00, 0x00, 0x90, 0xb5, + 0x18, 0x4c, 0x0c, 0x30, 0x0c, 0xc8, 0xe1, 0x1d, + 0xa5, 0x31, 0x0f, 0x1c, 0x0c, 0xc1, 0xe0, 0x1d, + 0xf9, 0x30, 0x41, 0x69, 0x00, 0x29, 0x12, 0xd0, + 0x01, 0x39, 0x41, 0x61, 0xf4, 0xf7, 0x84, 0xfe, + 0x00, 0x28, 0x09, 0xd0, 0xe3, 0x21, 0x01, 0x60, + 0x0c, 0xcf, 0xc1, 0x1d, 0x05, 0x31, 0x0c, 0xc1, + 0x01, 0x1c, 0x08, 0x20, 0xf4, 0xf7, 0xe7, 0xfe, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xed, 0x09, + 0x00, 0xc0, 0x00, 0x39, 0x1c, 0x09, 0x48, 0x09, + 0xf0, 0x80, 0xf8, 0xe0, 0x1d, 0x79, 0x30, 0xc0, + 0x6a, 0x01, 0x02, 0x09, 0x0a, 0xe0, 0x1d, 0xad, + 0x30, 0x1c, 0xf0, 0x65, 0xfe, 0x00, 0x21, 0x01, + 0x20, 0xf7, 0xf7, 0x62, 0xfd, 0xea, 0xe7, 0x18, + 0xeb, 0x03, 0x20, 0x54, 0xa6, 0x00, 0x20, 0xc0, + 0x68, 0x01, 0x49, 0x88, 0x60, 0x70, 0x47, 0x18, + 0xec, 0x03, 0x20, 0x00, 0x22, 0x4a, 0x65, 0x82, + 0x6c, 0x00, 0x2a, 0x02, 0xd0, 0x51, 0x65, 0x81, + 0x64, 0x70, 0x47, 0x41, 0x64, 0x81, 0x64, 0x70, + 0x47, 0x01, 0x1c, 0x40, 0x6c, 0x00, 0x28, 0x04, + 0xd0, 0x42, 0x6d, 0x4a, 0x64, 0x00, 0x2a, 0x00, + 0xd1, 0x8a, 0x64, 0x70, 0x47, 0x90, 0xb5, 0x04, + 0x1c, 0x08, 0x1c, 0x0f, 0x1c, 0xff, 0xf7, 0xf0, + 0xff, 0x00, 0x28, 0x08, 0xd0, 0x01, 0x1c, 0x20, + 0x1c, 0xff, 0xf7, 0xdf, 0xff, 0x38, 0x1c, 0xff, + 0xf7, 0xe7, 0xff, 0x00, 0x28, 0xf6, 0xd1, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb4, 0xcc, + 0x1d, 0x29, 0x34, 0x0c, 0xcc, 0xc7, 0x1d, 0x0d, + 0x37, 0x0c, 0xc7, 0x09, 0x6a, 0x01, 0x62, 0x90, + 0xbc, 0x70, 0x47, 0xf7, 0xb5, 0x81, 0x69, 0x01, + 0x29, 0x0e, 0xd1, 0x16, 0x4b, 0xc1, 0x18, 0x01, + 0xa8, 0x08, 0x22, 0x19, 0xf0, 0x66, 0xfe, 0x00, + 0x28, 0x04, 0xd1, 0x01, 0x20, 0x03, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0xf9, + 0xe7, 0x00, 0x26, 0x02, 0x29, 0x18, 0xd1, 0x0e, + 0x4c, 0x00, 0x27, 0xe5, 0x1d, 0x79, 0x35, 0xe8, + 0x69, 0x00, 0x28, 0x0f, 0xd9, 0xf8, 0x00, 0x00, + 0x19, 0xc1, 0x1d, 0x99, 0x31, 0x08, 0x22, 0x01, + 0xa8, 0x19, 0xf0, 0x4b, 0xfe, 0x00, 0x28, 0x01, + 0xd1, 0x01, 0x20, 0xe3, 0xe7, 0xe8, 0x69, 0x01, + 0x37, 0xb8, 0x42, 0xef, 0xd8, 0x30, 0x1c, 0xdd, + 0xe7, 0xed, 0x09, 0x00, 0xc1, 0x00, 0x30, 0x1c, + 0xdb, 0xe7, 0x00, 0x00, 0xd8, 0x0d, 0x00, 0x00, + 0x18, 0xeb, 0x03, 0x20, 0x07, 0xb5, 0x82, 0x69, + 0x00, 0x21, 0x01, 0x2a, 0x15, 0xd1, 0x37, 0x23, + 0x9b, 0x01, 0xc0, 0x18, 0x40, 0x6b, 0x00, 0x28, + 0x0d, 0xd0, 0xc1, 0x1d, 0x29, 0x31, 0x08, 0x22, + 0x01, 0xa8, 0x19, 0xf0, 0x29, 0xfe, 0x00, 0x28, + 0x03, 0xd1, 0x01, 0x20, 0x03, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x20, 0xfa, 0xe7, 0x08, 0x1c, + 0xf8, 0xe7, 0x02, 0x2a, 0x0a, 0xd1, 0x06, 0x49, + 0x08, 0x22, 0x01, 0xa8, 0x19, 0xf0, 0x18, 0xfe, + 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20, 0xed, 0xe7, + 0x00, 0x20, 0xeb, 0xe7, 0x08, 0x1c, 0xe9, 0xe7, + 0xcc, 0xeb, 0x03, 0x20, 0xb0, 0xb5, 0x04, 0x1c, + 0xc8, 0x68, 0x23, 0x25, 0x0f, 0x1c, 0x11, 0x28, + 0x2e, 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0x1e, 0x20, 0x22, 0x24, + 0x24, 0x28, 0x28, 0x28, 0x26, 0x26, 0x24, 0x24, + 0x2a, 0x2a, 0x24, 0x24, 0x09, 0x00, 0x06, 0xcf, + 0x08, 0x3f, 0x20, 0x1c, 0xff, 0xf7, 0x84, 0xff, + 0x00, 0x28, 0x03, 0xd0, 0x0b, 0x20, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x06, 0xcf, 0x20, 0x1c, + 0xff, 0xf7, 0xb0, 0xff, 0x00, 0x28, 0x01, 0xd0, + 0x0c, 0x20, 0xf4, 0xe7, 0x28, 0x1c, 0xf2, 0xe7, + 0x0d, 0x20, 0xf0, 0xe7, 0x0e, 0x20, 0xee, 0xe7, + 0x0f, 0x20, 0xec, 0xe7, 0x10, 0x20, 0xea, 0xe7, + 0x11, 0x20, 0xe8, 0xe7, 0x14, 0x20, 0xe6, 0xe7, + 0x28, 0x1c, 0xe4, 0xe7, 0xb0, 0xb5, 0xc4, 0x68, + 0x07, 0x69, 0x00, 0x2f, 0x1b, 0xd0, 0x00, 0x2c, + 0x06, 0xd0, 0x07, 0x23, 0x5b, 0x02, 0xe0, 0x18, + 0x80, 0x68, 0x7d, 0x4b, 0x98, 0x42, 0x19, 0xd0, + 0xf8, 0x68, 0x03, 0x38, 0x0d, 0x28, 0x11, 0xd2, + 0x01, 0xa3, 0x1b, 0x5c, 0xed, 0x09, 0x00, 0xc2, + 0x00, 0x5b, 0x00, 0x9f, 0x44, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0d, 0x0d, + 0x06, 0x06, 0x00, 0x38, 0x1c, 0x74, 0xa1, 0x1b, + 0xf0, 0xfc, 0xff, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x38, 0x1c, 0xf4, 0xf7, 0xc5, 0xfd, 0xf8, + 0xe7, 0x20, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0x9c, + 0xff, 0x01, 0x1c, 0x05, 0x1c, 0x20, 0x1c, 0x3a, + 0x1c, 0xfd, 0xf7, 0x46, 0xfd, 0x10, 0x2d, 0x05, + 0xd0, 0x0d, 0x2d, 0x03, 0xd0, 0x0e, 0x2d, 0x01, + 0xd0, 0x11, 0x2d, 0x73, 0xd1, 0x38, 0x7a, 0xff, + 0x23, 0xb5, 0x33, 0x58, 0x43, 0x00, 0x19, 0x38, + 0x30, 0xc1, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, + 0x6b, 0x00, 0x29, 0x06, 0xd0, 0xba, 0x6c, 0x78, + 0x23, 0xda, 0x42, 0x02, 0xd0, 0x00, 0x21, 0xff, + 0xf7, 0x7d, 0xf8, 0x10, 0x2d, 0x5e, 0xd1, 0x38, + 0x7a, 0xff, 0x23, 0xb5, 0x33, 0x58, 0x43, 0x00, + 0x19, 0xc5, 0x1d, 0x31, 0x35, 0xe8, 0x1d, 0xff, + 0x30, 0x7a, 0x30, 0x81, 0x6a, 0xba, 0x69, 0x89, + 0x18, 0x81, 0x62, 0xc1, 0x6a, 0x01, 0x31, 0xc1, + 0x62, 0x28, 0x69, 0x05, 0x28, 0x04, 0xd0, 0x38, + 0x1c, 0x56, 0xa1, 0x1b, 0xf0, 0xb6, 0xff, 0xb8, + 0xe7, 0x01, 0x22, 0xe9, 0x68, 0x13, 0x1c, 0x00, + 0x29, 0x00, 0xd0, 0x00, 0x23, 0x78, 0x69, 0x03, + 0x28, 0x00, 0xd0, 0x00, 0x22, 0x1a, 0x40, 0x04, + 0xd0, 0x28, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xba, + 0xfe, 0xa7, 0xe7, 0x51, 0x4a, 0x12, 0x6b, 0x00, + 0x2a, 0x06, 0xd0, 0x03, 0x28, 0x04, 0xd0, 0x28, + 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x21, 0xfa, 0x9c, + 0xe7, 0x03, 0x28, 0x12, 0xd1, 0xf4, 0xf7, 0x03, + 0xfd, 0x00, 0x28, 0x09, 0xd0, 0x7a, 0x21, 0x01, + 0x60, 0xe9, 0x68, 0xc1, 0x60, 0x07, 0x61, 0x01, + 0x1c, 0x09, 0x20, 0xf4, 0xf7, 0x67, 0xfd, 0xed, + 0x09, 0x00, 0xc3, 0x00, 0x8c, 0xe7, 0x38, 0x1c, + 0x44, 0xa1, 0x1b, 0xf0, 0x85, 0xff, 0x87, 0xe7, + 0x00, 0x29, 0x1b, 0xd0, 0x37, 0x23, 0x9b, 0x01, + 0xe0, 0x18, 0x80, 0x6b, 0x00, 0x28, 0x15, 0xd1, + 0xf4, 0xf7, 0xe8, 0xfc, 0x00, 0x28, 0x0c, 0xd0, + 0xd7, 0x21, 0x01, 0x60, 0xe9, 0x68, 0xc9, 0x6a, + 0xc1, 0x60, 0x07, 0x61, 0x01, 0x1c, 0x08, 0x20, + 0x00, 0xe0, 0x0c, 0xe0, 0xf4, 0xf7, 0x49, 0xfd, + 0x6e, 0xe7, 0x38, 0x1c, 0x3a, 0xa1, 0x1b, 0xf0, + 0x67, 0xff, 0x69, 0xe7, 0x38, 0x1c, 0x3c, 0xa1, + 0x1b, 0xf0, 0x62, 0xff, 0x64, 0xe7, 0x14, 0x2d, + 0x3b, 0xd1, 0x38, 0x7a, 0xff, 0x23, 0xb5, 0x33, + 0x58, 0x43, 0x00, 0x19, 0xc5, 0x1d, 0x31, 0x35, + 0xe8, 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x81, 0x6a, + 0x3a, 0x6a, 0x89, 0x18, 0x81, 0x62, 0xc1, 0x6a, + 0xba, 0x6a, 0x89, 0x18, 0xc1, 0x62, 0x28, 0x69, + 0x05, 0x28, 0x04, 0xd0, 0x38, 0x1c, 0x33, 0xa1, + 0x1b, 0xf0, 0x46, 0xff, 0x48, 0xe7, 0xe8, 0x68, + 0x00, 0x28, 0x19, 0xd0, 0x37, 0x23, 0x9b, 0x01, + 0xe0, 0x18, 0x80, 0x6b, 0x00, 0x28, 0x13, 0xd1, + 0xf4, 0xf7, 0xa8, 0xfc, 0x00, 0x28, 0x04, 0xd1, + 0x38, 0x1c, 0x2f, 0xa1, 0x1b, 0xf0, 0x34, 0xff, + 0x36, 0xe7, 0xe1, 0x21, 0x01, 0x60, 0xe9, 0x68, + 0xc9, 0x6a, 0xc1, 0x60, 0x07, 0x61, 0x01, 0x1c, + 0x08, 0x20, 0xf4, 0xf7, 0x06, 0xfd, 0x2b, 0xe7, + 0x38, 0x1c, 0x2c, 0xa1, 0x1b, 0xf0, 0x24, 0xff, + 0x26, 0xe7, 0x11, 0x2d, 0x04, 0xd1, 0x38, 0x1c, + 0x2e, 0xa1, 0x1b, 0xf0, 0x1d, 0xff, 0x1f, 0xe7, + 0x38, 0x1c, 0xf4, 0xf7, 0xe8, 0xfc, 0x1b, 0xe7, + 0x00, 0x00, 0x11, 0x19, 0x03, 0x64, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x72, 0x63, 0x76, 0x2e, + 0x63, 0x3a, 0x20, 0x32, 0x36, 0x35, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0xc4, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x72, 0x63, 0x76, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x30, 0x32, 0x00, + 0x00, 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x72, 0x63, 0x76, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x33, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x63, 0x72, 0x63, 0x76, 0x2e, 0x63, 0x3a, 0x20, + 0x33, 0x34, 0x36, 0x00, 0x00, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x72, 0x63, 0x76, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x35, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x63, 0x72, 0x63, 0x76, 0x2e, 0x63, 0x3a, 0x20, + 0x33, 0x36, 0x39, 0x00, 0x00, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x72, 0x63, 0x76, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x37, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x63, 0x72, 0x63, 0x76, 0x2e, 0x63, 0x3a, 0x20, + 0x33, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x72, 0x63, 0x76, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x39, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x23, 0xdb, 0x02, 0x98, + 0x42, 0x16, 0xd0, 0x08, 0xdc, 0x08, 0x28, 0x0f, + 0xd0, 0x10, 0x28, 0x0f, 0xd0, 0x5b, 0x08, 0x98, + 0x42, 0x12, 0xd1, 0x0a, 0x20, 0x70, 0x47, 0x01, + 0x23, 0x9b, 0x03, 0x98, 0x42, 0x0a, 0xd0, 0x5b, + 0x00, 0x98, 0x42, 0x09, 0xd1, 0x0f, 0x20, 0x70, + 0x47, 0x03, 0x20, 0x70, 0x47, 0x04, 0x20, 0x70, + 0x47, 0x0b, 0x20, 0x70, 0x47, 0x0e, 0x20, 0x70, + 0x47, 0x11, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x1c, + 0x1c, 0x15, 0x1c, 0x0e, 0x1c, 0x07, 0x1c, 0xfd, + 0xf7, 0x73, 0xfd, 0x00, 0x28, 0x0e, 0xd0, 0xf4, + 0xf7, 0xfb, 0xfb, 0x00, 0x28, 0xed, 0x09, 0x00, + 0xc5, 0x00, 0x0a, 0xd0, 0x73, 0x21, 0x01, 0x60, + 0xf9, 0x68, 0xc1, 0x60, 0x06, 0x61, 0x84, 0x61, + 0x45, 0x61, 0x01, 0x1c, 0x09, 0x20, 0xf4, 0xf7, + 0x5d, 0xfc, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x90, 0xb5, 0xc4, 0x68, 0x07, 0x1c, 0x20, 0x1c, + 0xfd, 0xf7, 0x59, 0xfd, 0x00, 0x28, 0x28, 0xd0, + 0x20, 0x69, 0x05, 0x28, 0x03, 0xd0, 0x03, 0x28, + 0x01, 0xd0, 0x04, 0x28, 0x21, 0xd1, 0xf4, 0xf7, + 0xda, 0xfb, 0x00, 0x28, 0x1d, 0xd0, 0x79, 0x69, + 0x00, 0x29, 0x0c, 0xd0, 0x0b, 0x68, 0x14, 0x22, + 0xd2, 0x1a, 0x8b, 0x69, 0x09, 0x6a, 0xd2, 0x18, + 0x52, 0x18, 0xe1, 0x1d, 0xff, 0x31, 0x7a, 0x31, + 0x4b, 0x6a, 0xd2, 0x18, 0x4a, 0x62, 0x73, 0x21, + 0x01, 0x60, 0xe1, 0x68, 0xc1, 0x60, 0x39, 0x69, + 0x01, 0x61, 0x79, 0x69, 0x41, 0x61, 0xb9, 0x69, + 0x81, 0x61, 0x01, 0x1c, 0x09, 0x20, 0xf4, 0xf7, + 0x29, 0xfc, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xf3, 0xb5, 0x8d, 0xb0, 0x21, 0x4d, 0x06, 0xac, + 0x4e, 0xcd, 0x4e, 0xc4, 0x48, 0xcd, 0x48, 0xc4, + 0x1f, 0x4d, 0x07, 0x1c, 0x4e, 0xcd, 0x11, 0x20, + 0x6c, 0x46, 0x4e, 0xc4, 0x48, 0xcd, 0x48, 0xc4, + 0x79, 0x68, 0x4a, 0x6a, 0x00, 0x21, 0x03, 0x2a, + 0x01, 0xd3, 0x08, 0x91, 0x09, 0x91, 0x7a, 0x68, + 0x52, 0x6a, 0x02, 0x2a, 0x01, 0xd3, 0x0a, 0x91, + 0x0b, 0x91, 0x3b, 0x1c, 0xfa, 0x1d, 0xf9, 0x32, + 0xdd, 0x1d, 0xff, 0x35, 0x00, 0x21, 0x3a, 0x35, + 0x17, 0x6a, 0x12, 0x4e, 0x0c, 0x95, 0x8c, 0x00, + 0x06, 0xab, 0x1b, 0x59, 0x3b, 0x40, 0x12, 0xd0, + 0x55, 0x6a, 0x00, 0x2d, 0x05, 0xd1, 0x0c, 0x9d, + 0x2d, 0x6a, 0x2d, 0x01, 0x75, 0x59, 0x2b, 0x40, + 0x09, 0xd0, 0x68, 0x46, 0x00, 0x59, 0x0a, 0x4c, + 0xc3, 0x00, 0x1b, 0x18, 0x9b, 0x00, 0xe3, 0x58, + 0xed, 0x09, 0x00, 0xc6, 0x00, 0x0e, 0x9c, 0xa3, + 0x42, 0x02, 0xd2, 0x01, 0x31, 0x06, 0x29, 0xe4, + 0xd3, 0x0f, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xd8, 0x0f, 0x01, 0x20, 0xf0, 0x0f, 0x01, + 0x20, 0x50, 0x7b, 0x03, 0x20, 0x78, 0x7b, 0x03, + 0x20, 0xf0, 0xb5, 0x07, 0x1c, 0x05, 0x98, 0x0c, + 0x1c, 0x14, 0x21, 0x11, 0x28, 0x21, 0x4e, 0x26, + 0xd1, 0x00, 0x2a, 0x21, 0xd0, 0x10, 0x68, 0x08, + 0x1a, 0x91, 0x69, 0x40, 0x18, 0x11, 0x6a, 0x45, + 0x18, 0x03, 0x2b, 0x01, 0xd1, 0x03, 0x20, 0x03, + 0xe0, 0x20, 0x1c, 0x29, 0x1c, 0xff, 0xf7, 0x9a, + 0xff, 0x78, 0x62, 0x11, 0x28, 0x10, 0xd0, 0xc3, + 0x00, 0x18, 0x18, 0x80, 0x00, 0x32, 0x58, 0x29, + 0x1c, 0xaa, 0x42, 0x00, 0xd2, 0x11, 0x1c, 0xf9, + 0x61, 0x30, 0x58, 0x29, 0x1c, 0xf3, 0xf7, 0xbe, + 0xfe, 0x20, 0x1c, 0xff, 0xf7, 0x87, 0xff, 0xb8, + 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, + 0x62, 0x00, 0x2a, 0xf9, 0xd0, 0x13, 0x68, 0xc9, + 0x1a, 0x93, 0x69, 0x12, 0x6a, 0xc9, 0x18, 0x8a, + 0x18, 0xc3, 0x00, 0x18, 0x18, 0x80, 0x00, 0x33, + 0x58, 0x11, 0x1c, 0x93, 0x42, 0x00, 0xd2, 0x19, + 0x1c, 0xf9, 0x61, 0x30, 0x58, 0x11, 0x1c, 0xf3, + 0xf7, 0xa1, 0xfe, 0x20, 0x1c, 0xff, 0xf7, 0x6a, + 0xff, 0xb8, 0x62, 0xe1, 0xe7, 0x78, 0x7b, 0x03, + 0x20, 0xff, 0xb5, 0x81, 0xb0, 0x00, 0x24, 0x05, + 0x1c, 0x0a, 0x9e, 0xf4, 0xf7, 0x16, 0xfb, 0x07, + 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x16, 0xe0, 0x0b, + 0x9a, 0x38, 0x1c, 0x29, 0x1c, 0x00, 0x92, 0x02, + 0x9a, 0x33, 0x1c, 0xff, 0xf7, 0xa1, 0xff, 0x0d, + 0x20, 0x38, 0x60, 0xa8, 0x68, 0xf8, 0x60, 0x02, + 0x99, 0x0b, 0x20, 0xb9, 0x61, 0x03, 0x9a, 0x39, + 0x1c, 0x3a, 0x61, 0x04, 0x9b, 0x7b, 0x61, 0x3e, + 0x62, 0xf4, 0xf7, 0xed, 0x09, 0x00, 0xc7, 0x00, + 0x6a, 0xfb, 0x20, 0x1c, 0x05, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x82, 0xb0, + 0x01, 0x22, 0x03, 0x21, 0x00, 0x91, 0x01, 0x92, + 0xc2, 0x1d, 0x00, 0x21, 0x00, 0x23, 0xb5, 0x32, + 0xff, 0xf7, 0xcd, 0xff, 0x02, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0x90, 0xb0, 0x0f, 0x1c, + 0x00, 0x21, 0x00, 0x22, 0x07, 0x23, 0x02, 0xac, + 0x06, 0xc4, 0x01, 0x3b, 0xfc, 0xd1, 0x14, 0x21, + 0x02, 0x91, 0xf9, 0x69, 0x0b, 0x91, 0xb9, 0x69, + 0x0a, 0x91, 0xfa, 0x68, 0x02, 0x21, 0x01, 0x92, + 0xc2, 0x1d, 0x00, 0x91, 0x02, 0xa9, 0x55, 0x32, + 0xff, 0xf7, 0xb1, 0xff, 0x04, 0x1c, 0x38, 0x1c, + 0x04, 0xa1, 0x1b, 0xf0, 0x5b, 0xfd, 0x20, 0x1c, + 0x10, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, + 0x73, 0x65, 0x6e, 0x64, 0x2e, 0x63, 0x3a, 0x20, + 0x35, 0x31, 0x37, 0x00, 0x00, 0x00, 0x80, 0xb5, + 0x01, 0x21, 0x0d, 0x48, 0x19, 0xf0, 0x87, 0xfa, + 0x07, 0x1c, 0xf4, 0xf7, 0xb1, 0xfa, 0x03, 0x21, + 0x01, 0x60, 0xc7, 0x60, 0xff, 0x21, 0x01, 0x31, + 0x01, 0x61, 0x41, 0x61, 0x81, 0x61, 0xc1, 0x61, + 0x07, 0xa7, 0x0c, 0xcf, 0xc1, 0x1d, 0x19, 0x31, + 0x0c, 0xc1, 0x00, 0x22, 0x01, 0x1c, 0x00, 0x20, + 0x00, 0xf0, 0x1d, 0xf8, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x0c, 0x0e, 0x00, 0x00, 0xe2, 0x3a, + 0x1a, 0x33, 0xce, 0x2c, 0x7a, 0x4e, 0x90, 0xb5, + 0xc8, 0x68, 0x0f, 0x1c, 0x0a, 0x69, 0xc1, 0x1d, + 0x79, 0x31, 0xca, 0x62, 0x7a, 0x69, 0x00, 0x24, + 0x0a, 0x63, 0x05, 0x21, 0xf5, 0xf7, 0xc1, 0xff, + 0x38, 0x1c, 0xf4, 0xf7, 0xc0, 0xfa, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, + 0x81, 0xb0, 0x0c, 0x1c, 0x08, 0x68, 0xed, 0x09, + 0x00, 0xc8, 0x00, 0x20, 0x31, 0x17, 0x1c, 0x03, + 0x28, 0x00, 0x91, 0x52, 0xd1, 0x00, 0x25, 0x00, + 0x2f, 0xe6, 0x68, 0x07, 0xd1, 0x02, 0x20, 0x31, + 0x1c, 0xf7, 0xf7, 0x31, 0xfe, 0x07, 0x1c, 0x01, + 0xd1, 0x07, 0x25, 0x28, 0xe0, 0xf8, 0x1d, 0x21, + 0x69, 0x79, 0x30, 0xc1, 0x62, 0x61, 0x69, 0x01, + 0x63, 0xa1, 0x69, 0xc1, 0x60, 0xe1, 0x69, 0x01, + 0x61, 0x00, 0x99, 0xf8, 0x1d, 0x0c, 0xc9, 0xad, + 0x30, 0x0c, 0xc0, 0x00, 0x20, 0x78, 0x61, 0x38, + 0x62, 0x78, 0x64, 0x2c, 0xa1, 0x0c, 0xc9, 0xf8, + 0x1d, 0x1d, 0x30, 0x0c, 0xc0, 0x2a, 0xa1, 0x0c, + 0xc9, 0xf8, 0x1d, 0x11, 0x30, 0x0c, 0xc0, 0x27, + 0xa1, 0x0c, 0xc9, 0xf8, 0x1d, 0x25, 0x30, 0x0c, + 0xc0, 0x00, 0x20, 0x78, 0x63, 0xf8, 0x68, 0x00, + 0x28, 0x01, 0xd1, 0x03, 0x20, 0xf8, 0x60, 0x3a, + 0x20, 0x20, 0x60, 0x65, 0x61, 0xe6, 0x60, 0x27, + 0x61, 0x01, 0x98, 0x00, 0x28, 0x04, 0xd0, 0x0e, + 0x20, 0x21, 0x1c, 0xf4, 0xf7, 0xa6, 0xfa, 0x03, + 0xe0, 0x0a, 0x20, 0x21, 0x1c, 0xf4, 0xf7, 0xa1, + 0xfa, 0x00, 0x2f, 0x05, 0xd0, 0x05, 0x23, 0x03, + 0x22, 0x00, 0x21, 0x38, 0x1c, 0xf5, 0xf7, 0xc9, + 0xfe, 0x00, 0x20, 0x04, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x05, 0x28, 0x1f, 0xd1, 0xe7, + 0x68, 0x21, 0x69, 0xf8, 0x1d, 0x79, 0x30, 0xc1, + 0x62, 0x61, 0x69, 0x01, 0x63, 0xa1, 0x69, 0xc1, + 0x60, 0xe1, 0x69, 0x01, 0x61, 0x00, 0x99, 0xf8, + 0x1d, 0x0c, 0xc9, 0xad, 0x30, 0x0c, 0xc0, 0xf8, + 0x68, 0x04, 0x28, 0x01, 0xd1, 0x05, 0x20, 0xf8, + 0x60, 0x20, 0x1c, 0xf4, 0xf7, 0x46, 0xfa, 0x05, + 0x23, 0x05, 0x22, 0x00, 0x21, 0x38, 0x1c, 0xf5, + 0xf7, 0xa4, 0xfe, 0x00, 0x20, 0xd9, 0xe7, 0xff, + 0x20, 0x0d, 0x30, 0xd6, 0xe7, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0xc9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf7, 0xb5, 0xcd, 0x68, + 0x13, 0x1c, 0x14, 0x1c, 0x0f, 0x1c, 0x00, 0x21, + 0x05, 0x22, 0x00, 0x26, 0x28, 0x1c, 0xf6, 0xf7, + 0xb7, 0xf8, 0x00, 0x2c, 0x03, 0xd1, 0x38, 0x1c, + 0xf4, 0xf7, 0x26, 0xfa, 0x10, 0xe0, 0x3a, 0x20, + 0x38, 0x60, 0x68, 0x68, 0xf8, 0x60, 0x7e, 0x61, + 0x00, 0x98, 0x00, 0x28, 0x04, 0xd0, 0x0e, 0x20, + 0x39, 0x1c, 0xf4, 0xf7, 0x4d, 0xfa, 0x03, 0xe0, + 0x0a, 0x20, 0x39, 0x1c, 0xf4, 0xf7, 0x48, 0xfa, + 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0xf0, 0xb4, 0xc7, 0x1d, 0xb9, 0x37, + 0x0c, 0xc7, 0x08, 0x3f, 0x00, 0x24, 0x3c, 0x72, + 0x02, 0x22, 0xfa, 0x60, 0x01, 0x22, 0x7a, 0x72, + 0xbc, 0x72, 0x0b, 0x4e, 0xfc, 0x72, 0x0c, 0xce, + 0xc5, 0x1d, 0xc9, 0x35, 0x0c, 0xc5, 0x09, 0x4a, + 0xf0, 0x30, 0xd3, 0x6a, 0xbb, 0x61, 0x13, 0x6b, + 0xfb, 0x61, 0x52, 0x6b, 0x79, 0x62, 0x3a, 0x62, + 0xbc, 0x62, 0x05, 0x49, 0xfc, 0x62, 0xc0, 0xc9, + 0xc0, 0xc0, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, + 0x88, 0xe6, 0x03, 0x20, 0x48, 0xe6, 0x03, 0x20, + 0x80, 0xe6, 0x03, 0x20, 0xf0, 0xb4, 0xc5, 0x1d, + 0xc6, 0x1d, 0x51, 0x36, 0xff, 0x35, 0x17, 0x1c, + 0x1a, 0x35, 0x2c, 0x1c, 0x0c, 0xce, 0x0c, 0xc5, + 0xff, 0x30, 0x01, 0x30, 0x21, 0x72, 0xc7, 0x62, + 0x01, 0x20, 0x60, 0x72, 0x00, 0x20, 0xa0, 0x72, + 0xe0, 0x72, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, + 0x90, 0xb5, 0x07, 0x1c, 0x00, 0x20, 0xb8, 0x60, + 0x0c, 0x1c, 0x28, 0xf0, 0xe9, 0xff, 0x60, 0x68, + 0x00, 0x28, 0x01, 0xd1, 0x27, 0x60, 0x00, 0xe0, + 0x87, 0x60, 0x67, 0x60, 0x28, 0xf0, 0xdc, 0xff, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, + 0x07, 0x1c, 0x00, 0x68, 0xed, 0x09, 0x00, 0xca, + 0x00, 0x00, 0x25, 0x00, 0x28, 0x03, 0xd1, 0x28, + 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, + 0xf0, 0xd1, 0xff, 0x3c, 0x68, 0xa0, 0x68, 0x38, + 0x60, 0x00, 0x28, 0x00, 0xd1, 0x7d, 0x60, 0x28, + 0xf0, 0xc5, 0xff, 0x20, 0x1c, 0xf0, 0xe7, 0x00, + 0x68, 0x00, 0x28, 0x00, 0xd1, 0x70, 0x47, 0x01, + 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x04, 0x1c, 0xe6, + 0x1d, 0x40, 0x6f, 0x79, 0x36, 0x0d, 0x1c, 0x00, + 0x28, 0x5b, 0xd0, 0x61, 0x6a, 0xfe, 0x29, 0x0d, + 0xd1, 0x21, 0x6b, 0x00, 0x29, 0x18, 0xd0, 0x00, + 0x27, 0x61, 0x67, 0x77, 0x60, 0xf7, 0x60, 0x20, + 0x6b, 0x61, 0x6f, 0x80, 0x69, 0x88, 0x63, 0x60, + 0x6f, 0xc7, 0x63, 0x72, 0xe0, 0xfd, 0x29, 0x0b, + 0xd1, 0x61, 0x6c, 0x01, 0x29, 0x04, 0xd1, 0xe2, + 0x6d, 0x00, 0x2a, 0x00, 0xd0, 0x00, 0x21, 0xe1, + 0x65, 0x21, 0x1c, 0x00, 0xf0, 0x60, 0xfa, 0x2e, + 0xe0, 0x01, 0x7a, 0xe7, 0x1d, 0xf9, 0x37, 0x00, + 0x29, 0x11, 0xd1, 0x60, 0x68, 0x85, 0x4b, 0xc0, + 0x18, 0x01, 0x68, 0x01, 0x31, 0x01, 0x60, 0x60, + 0x68, 0x0b, 0x23, 0x1b, 0x02, 0xc0, 0x18, 0xc1, + 0x6b, 0x80, 0x6b, 0x81, 0x42, 0x1f, 0xd8, 0x38, + 0x68, 0x01, 0x30, 0x38, 0x60, 0x17, 0xe0, 0xc1, + 0x68, 0x03, 0x39, 0x0d, 0x29, 0x17, 0xd2, 0x02, + 0xa3, 0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, + 0x1c, 0x07, 0x07, 0x13, 0x13, 0x13, 0x07, 0x13, + 0x07, 0x07, 0x13, 0x13, 0x07, 0x07, 0x00, 0x21, + 0x1c, 0x00, 0xf0, 0x35, 0xfa, 0xe0, 0x6e, 0x00, + 0x28, 0xe5, 0xd0, 0x00, 0x27, 0xe7, 0x66, 0x00, + 0x20, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0x6f, 0xc0, 0x6b, 0x00, 0x28, 0x01, 0xd0, 0xf4, + 0xf7, 0x41, 0xf9, 0x60, 0x6f, 0x00, 0x27, 0xc7, + 0x63, 0x67, 0x67, 0x60, 0x6e, 0x40, 0x08, 0xed, + 0x09, 0x00, 0xcb, 0x00, 0x0e, 0xd2, 0xe0, 0x1d, + 0x45, 0x30, 0xff, 0xf7, 0x79, 0xff, 0x00, 0x28, + 0x6e, 0xd1, 0x60, 0x6e, 0x00, 0x28, 0x05, 0xd1, + 0xe0, 0x1d, 0x4d, 0x30, 0xff, 0xf7, 0x70, 0xff, + 0x00, 0x28, 0x65, 0xd1, 0x60, 0x6a, 0xfe, 0x28, + 0x19, 0xd1, 0x20, 0x6b, 0x00, 0x28, 0x16, 0xd0, + 0x00, 0x27, 0x60, 0x67, 0x77, 0x60, 0xf7, 0x60, + 0x60, 0x6f, 0xc7, 0x63, 0x20, 0x6b, 0x61, 0x6f, + 0x80, 0x69, 0x88, 0x63, 0xe0, 0x6d, 0x01, 0x21, + 0x00, 0x28, 0x00, 0xd0, 0x00, 0x21, 0xe1, 0x65, + 0x60, 0x6f, 0x21, 0x1c, 0x87, 0x65, 0x60, 0x6f, + 0x00, 0xf0, 0xf4, 0xf9, 0x46, 0xe0, 0x00, 0x27, + 0x77, 0x60, 0x11, 0x2d, 0x42, 0xd0, 0xa0, 0x6e, + 0x00, 0x28, 0x02, 0xd9, 0x01, 0x25, 0x01, 0x38, + 0xa0, 0x66, 0xe0, 0x6f, 0x60, 0x67, 0x00, 0x28, + 0x38, 0xd0, 0x61, 0x68, 0x58, 0x31, 0x0c, 0xc9, + 0x0c, 0xc0, 0x20, 0x7e, 0x61, 0x6f, 0x08, 0x72, + 0x60, 0x6f, 0x01, 0x21, 0x41, 0x72, 0x60, 0x6f, + 0x21, 0x1c, 0xc5, 0x60, 0x77, 0x60, 0xf7, 0x60, + 0x60, 0x6f, 0x87, 0x63, 0x60, 0x6f, 0xc7, 0x63, + 0x60, 0x6f, 0x00, 0xf0, 0xcf, 0xf9, 0x02, 0x2d, + 0x1e, 0xd1, 0x60, 0x6f, 0xc1, 0x1d, 0x3f, 0x48, + 0x09, 0x31, 0xc5, 0x1d, 0xf9, 0x35, 0x48, 0xcd, + 0x48, 0xc1, 0xc1, 0x1d, 0xb9, 0x31, 0xca, 0x6a, + 0x63, 0x6f, 0xf8, 0x30, 0x9a, 0x61, 0x0a, 0x6b, + 0x63, 0x6f, 0xda, 0x61, 0x49, 0x6b, 0x62, 0x6f, + 0x11, 0x62, 0xe1, 0x1d, 0x99, 0x31, 0x09, 0x7b, + 0x62, 0x6f, 0x51, 0x62, 0x61, 0x6f, 0xcf, 0x62, + 0x61, 0x6f, 0x60, 0xc8, 0x30, 0x31, 0x60, 0xc1, + 0x60, 0x6f, 0x87, 0x65, 0x38, 0x1c, 0x7a, 0xe7, + 0xff, 0xe7, 0x01, 0x69, 0x00, 0x27, 0x61, 0x67, + 0x41, 0x69, 0x71, 0x60, 0x01, 0x6a, 0xf1, 0x60, + 0x62, 0x6f, 0xed, 0x09, 0x00, 0xcc, 0x00, 0x01, + 0x21, 0x51, 0x72, 0xe7, 0x66, 0x62, 0x6f, 0xd0, + 0x63, 0x02, 0x6a, 0x63, 0x6f, 0x5a, 0x61, 0x42, + 0x6a, 0x63, 0x6f, 0xda, 0x60, 0x82, 0x69, 0x00, + 0x2a, 0x1e, 0xd0, 0x12, 0x68, 0x14, 0x23, 0x9a, + 0x1a, 0x63, 0x6f, 0x9a, 0x61, 0x82, 0x69, 0x13, + 0x68, 0xd2, 0x18, 0x63, 0x6f, 0x04, 0x32, 0xda, + 0x61, 0x82, 0x69, 0x63, 0x6f, 0x92, 0x69, 0x1a, + 0x62, 0x82, 0x69, 0x63, 0x6f, 0xd2, 0x69, 0x5a, + 0x62, 0x82, 0x69, 0x63, 0x6f, 0x12, 0x6a, 0x9a, + 0x62, 0x82, 0x69, 0x63, 0x6f, 0x52, 0x6a, 0xda, + 0x62, 0xc2, 0x69, 0x63, 0x6f, 0x9a, 0x63, 0x07, + 0xe0, 0x62, 0x6f, 0x97, 0x61, 0x62, 0x6f, 0x17, + 0x62, 0x62, 0x6f, 0x97, 0x62, 0x62, 0x6f, 0x97, + 0x63, 0x00, 0x69, 0xc0, 0x68, 0x03, 0x38, 0x0d, + 0x28, 0x14, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x06, 0x06, 0x10, 0x10, 0x10, + 0x06, 0x10, 0x06, 0x06, 0x10, 0x10, 0x06, 0x06, + 0x00, 0xe0, 0x1d, 0xb9, 0x30, 0xc2, 0x6b, 0x01, + 0x32, 0xc2, 0x63, 0xe0, 0x6d, 0x00, 0x28, 0x00, + 0xd0, 0x00, 0x21, 0xe1, 0x65, 0x60, 0x6f, 0x21, + 0x1c, 0x00, 0xf0, 0x4e, 0xf9, 0x9e, 0xe7, 0x3c, + 0x0b, 0x00, 0x00, 0x88, 0xe5, 0x03, 0x20, 0xb0, + 0xb5, 0xc4, 0x68, 0x07, 0x1c, 0xe0, 0x68, 0x00, + 0x25, 0x05, 0x28, 0x18, 0xd0, 0x78, 0x69, 0x00, + 0x28, 0x11, 0xd0, 0xf4, 0xf7, 0x1d, 0xf8, 0x00, + 0x28, 0x0d, 0xd0, 0x34, 0x21, 0x01, 0x60, 0xa1, + 0x68, 0xc1, 0x60, 0x02, 0x21, 0x01, 0x61, 0x79, + 0x69, 0x41, 0x61, 0x39, 0x6a, 0x81, 0x61, 0x01, + 0x1c, 0x0a, 0x20, 0xf4, 0xf7, 0x7c, 0xf8, 0x38, + 0x1c, 0xf4, 0xf7, 0x45, 0xf8, 0x10, 0xe0, 0x38, + 0x6a, 0x00, 0x28, 0x0d, 0xd0, 0x01, 0x28, 0x06, + 0xd0, 0x02, 0x28, 0x04, 0xd0, 0xed, 0x09, 0x00, + 0xcd, 0x00, 0x03, 0x28, 0x07, 0xd1, 0xe1, 0x1d, + 0x45, 0x31, 0x01, 0xe0, 0xe1, 0x1d, 0x4d, 0x31, + 0x38, 0x1c, 0xff, 0xf7, 0x63, 0xfe, 0x28, 0x1c, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, + 0x44, 0x6f, 0x07, 0x1c, 0x00, 0x2c, 0x2b, 0xd0, + 0x78, 0x6a, 0xfd, 0x28, 0x28, 0xd0, 0xfd, 0x1d, + 0x79, 0x35, 0xe8, 0x68, 0x00, 0x28, 0x01, 0xd1, + 0x78, 0x67, 0x21, 0xe0, 0x02, 0x9a, 0x00, 0x2a, + 0x24, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0x04, 0xf9, + 0x00, 0x28, 0x1f, 0xd1, 0xe0, 0x68, 0x22, 0x49, + 0xc3, 0x00, 0x18, 0x18, 0x80, 0x00, 0x40, 0x18, + 0xc0, 0x69, 0x00, 0x28, 0x0c, 0xd0, 0x01, 0x20, + 0xfa, 0x6d, 0x01, 0x1c, 0x00, 0x2a, 0x00, 0xd0, + 0x00, 0x21, 0xf8, 0x66, 0xf8, 0x1d, 0xb9, 0x30, + 0xf9, 0x65, 0xc1, 0x6b, 0x01, 0x31, 0xc1, 0x63, + 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0xe3, 0xf8, + 0x28, 0xf0, 0x18, 0xfe, 0x03, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x6e, 0x68, + 0x68, 0x60, 0xed, 0x68, 0x78, 0x67, 0x28, 0xf0, + 0x0d, 0xfe, 0x00, 0x2e, 0x13, 0xd0, 0xe1, 0x6b, + 0x00, 0x29, 0xef, 0xd0, 0x34, 0x20, 0x08, 0x60, + 0xb8, 0x68, 0xc8, 0x60, 0x02, 0x9a, 0x0a, 0x61, + 0x4e, 0x61, 0x8d, 0x61, 0x01, 0x98, 0x00, 0x28, + 0x01, 0xd0, 0x0e, 0x20, 0x00, 0xe0, 0x0a, 0x20, + 0xf4, 0xf7, 0x10, 0xf8, 0xde, 0xe7, 0xe0, 0x6b, + 0x00, 0x28, 0xdb, 0xd0, 0xf3, 0xf7, 0xd6, 0xff, + 0x00, 0x20, 0xe0, 0x63, 0xd6, 0xe7, 0x00, 0x00, + 0x78, 0x7b, 0x03, 0x20, 0x00, 0xb5, 0x00, 0x22, + 0xc1, 0x6f, 0xc2, 0x67, 0x00, 0x29, 0x02, 0xd0, + 0x08, 0x1c, 0xf3, 0xf7, 0xed, 0xff, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0x00, 0x24, 0x04, 0x64, + 0x07, 0x1c, 0x44, 0x64, 0x44, 0x66, 0x80, 0x30, + 0xed, 0x09, 0x00, 0xce, 0x00, 0x04, 0x60, 0x84, + 0x60, 0x04, 0x61, 0x09, 0x48, 0xf9, 0x1d, 0xb9, + 0x31, 0xbc, 0x64, 0x08, 0x62, 0x38, 0x1c, 0x00, + 0xf0, 0x91, 0xfc, 0xf8, 0x6f, 0x00, 0x28, 0x03, + 0xd1, 0xf3, 0xf7, 0xb3, 0xff, 0xf8, 0x67, 0xc4, + 0x63, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x4a, 0x08, 0x10, + 0xd3, 0x42, 0x6e, 0x01, 0x23, 0x1a, 0x43, 0x42, + 0x66, 0xc2, 0x6f, 0x43, 0x6f, 0x93, 0x42, 0x08, + 0xd0, 0xc2, 0x1d, 0x79, 0x32, 0x13, 0x60, 0x53, + 0x68, 0x93, 0x60, 0xd3, 0x68, 0x13, 0x61, 0x00, + 0x22, 0x42, 0x67, 0x89, 0x08, 0x03, 0xd3, 0x41, + 0x6e, 0x02, 0x23, 0x19, 0x43, 0x41, 0x66, 0x70, + 0x47, 0x42, 0x6e, 0x8a, 0x43, 0x42, 0x66, 0x49, + 0x08, 0x0d, 0xd3, 0x51, 0x08, 0x0b, 0xd2, 0xc1, + 0x1d, 0x79, 0x31, 0x0a, 0x68, 0x00, 0x2a, 0x06, + 0xd0, 0x42, 0x67, 0x88, 0x68, 0x48, 0x60, 0x08, + 0x69, 0xc8, 0x60, 0x00, 0x20, 0x08, 0x60, 0x70, + 0x47, 0xf0, 0xb5, 0x82, 0xb0, 0x05, 0x1c, 0x0f, + 0x1c, 0x28, 0xf0, 0x92, 0xfd, 0x03, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0xe2, 0xff, 0x02, 0x22, 0x38, + 0x1c, 0x29, 0x1c, 0xff, 0xf7, 0x3a, 0xff, 0xf8, + 0x1d, 0x45, 0x30, 0xfe, 0x1d, 0x79, 0x36, 0x01, + 0x90, 0x01, 0x98, 0xff, 0xf7, 0xa4, 0xfd, 0x04, + 0x1c, 0x03, 0xd1, 0xf8, 0x1d, 0x4d, 0x30, 0x00, + 0x90, 0x12, 0xe0, 0x28, 0xf0, 0x79, 0xfd, 0x20, + 0x69, 0x78, 0x67, 0xc4, 0x63, 0x60, 0x69, 0x70, + 0x60, 0x20, 0x6a, 0xf0, 0x60, 0x28, 0xf0, 0x70, + 0xfd, 0x02, 0x22, 0x38, 0x1c, 0x29, 0x1c, 0xff, + 0xf7, 0x1c, 0xff, 0x28, 0xf0, 0x65, 0xfd, 0xe3, + 0xe7, 0x00, 0x98, 0xff, 0xf7, 0x88, 0xfd, 0x04, + 0x1c, 0x12, 0xd0, 0x28, 0xf0, 0x61, 0xfd, 0x20, + 0x69, 0x78, 0x67, 0xed, 0x09, 0x00, 0xcf, 0x00, + 0xc4, 0x63, 0x60, 0x69, 0x70, 0x60, 0x20, 0x6a, + 0xf0, 0x60, 0x28, 0xf0, 0x58, 0xfd, 0x02, 0x22, + 0x38, 0x1c, 0x29, 0x1c, 0xff, 0xf7, 0x04, 0xff, + 0x28, 0xf0, 0x4d, 0xfd, 0xe7, 0xe7, 0x02, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0xc3, 0x78, 0x0a, 0x6c, 0x01, 0x20, 0x9a, 0x42, + 0x06, 0xd1, 0x08, 0x66, 0xff, 0x31, 0x01, 0x31, + 0x8a, 0x68, 0x01, 0x32, 0x8a, 0x60, 0x70, 0x47, + 0x08, 0x66, 0x0b, 0x64, 0x00, 0x20, 0x70, 0x47, + 0x0a, 0x6e, 0x82, 0x72, 0xc9, 0x6d, 0xc1, 0x72, + 0x70, 0x47, 0x90, 0xb4, 0x41, 0x6f, 0x01, 0x27, + 0x8b, 0x6b, 0xca, 0x1d, 0x11, 0x32, 0x00, 0x2b, + 0x28, 0xd0, 0x40, 0x6a, 0xff, 0x28, 0x01, 0xd0, + 0x00, 0x28, 0x23, 0xd1, 0x00, 0x20, 0x88, 0x65, + 0x4c, 0x69, 0x03, 0x2c, 0x1e, 0xd0, 0x4f, 0x61, + 0x14, 0x68, 0x9c, 0x42, 0x0f, 0xd9, 0x14, 0x68, + 0xe4, 0x1a, 0x14, 0x60, 0x54, 0x68, 0xe3, 0x18, + 0x53, 0x60, 0x8a, 0x69, 0x0b, 0x6a, 0xd2, 0x18, + 0x8b, 0x6a, 0xd2, 0x18, 0x0e, 0xd0, 0x8b, 0x6b, + 0x93, 0x42, 0x0c, 0xd9, 0x10, 0xe0, 0x10, 0x60, + 0x08, 0x32, 0x1b, 0x1b, 0x00, 0x2b, 0xe7, 0xd1, + 0x8a, 0x69, 0x0b, 0x6a, 0xd2, 0x18, 0x8b, 0x6a, + 0xd2, 0x18, 0x02, 0xd1, 0x38, 0x1c, 0x90, 0xbc, + 0x70, 0x47, 0x8b, 0x6b, 0x93, 0x42, 0xfa, 0xd9, + 0x8a, 0x63, 0xca, 0x6b, 0x92, 0x6a, 0xca, 0x60, + 0xf5, 0xe7, 0x00, 0xb5, 0xca, 0x68, 0x03, 0x20, + 0xd0, 0x60, 0x08, 0x1c, 0xf3, 0xf7, 0xd3, 0xfe, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0xb5, + 0xc8, 0x68, 0xc0, 0x30, 0x42, 0x6a, 0x01, 0x32, + 0x42, 0x62, 0x08, 0x1c, 0xf3, 0xf7, 0xc7, 0xfe, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x90, 0xb5, + 0xcc, 0x68, 0x0f, 0x1c, 0x28, 0xf0, 0xed, 0x09, + 0x00, 0xd0, 0x00, 0xdf, 0xfc, 0xf9, 0x1d, 0x09, + 0x31, 0x0c, 0xc9, 0xe0, 0x1d, 0xe1, 0x30, 0x0c, + 0xc0, 0x0c, 0xc9, 0x0c, 0xc0, 0x38, 0x6a, 0xe1, + 0x1d, 0xb9, 0x31, 0x88, 0x63, 0x60, 0x68, 0x00, + 0x69, 0x01, 0x28, 0x03, 0xd1, 0x20, 0x1c, 0xfa, + 0xf7, 0x84, 0xfa, 0x02, 0xe0, 0x20, 0x1c, 0xfb, + 0xf7, 0x4a, 0xfb, 0x28, 0xf0, 0xc2, 0xfc, 0x90, + 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x90, + 0xb5, 0x01, 0x21, 0x0c, 0x48, 0x18, 0xf0, 0x35, + 0xfe, 0x07, 0x1c, 0xf3, 0xf7, 0x5f, 0xfe, 0x01, + 0x21, 0x01, 0x60, 0x09, 0xa4, 0x0c, 0xcc, 0xc1, + 0x1d, 0x0d, 0x31, 0x0c, 0xc1, 0x01, 0x21, 0x49, + 0x03, 0xc1, 0x61, 0xc7, 0x60, 0x01, 0x62, 0x01, + 0x1c, 0x00, 0x20, 0x00, 0xf0, 0x0a, 0xf8, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x0c, + 0x0e, 0x00, 0x00, 0xe2, 0x3a, 0x1a, 0x33, 0xce, + 0x2c, 0x7a, 0x4e, 0xf3, 0xb5, 0x81, 0xb0, 0x00, + 0x20, 0x00, 0x90, 0xce, 0x68, 0x0c, 0x1c, 0x28, + 0xf0, 0x98, 0xfc, 0x27, 0x69, 0x00, 0x2f, 0x14, + 0xd0, 0x00, 0x21, 0x38, 0x1c, 0xf5, 0xf7, 0xa7, + 0xfb, 0x00, 0x28, 0x0e, 0xd0, 0xf8, 0x68, 0x1a, + 0x28, 0x01, 0xd1, 0x14, 0x25, 0x00, 0xe0, 0x0c, + 0x25, 0xf8, 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x41, + 0x69, 0x01, 0x31, 0x41, 0x61, 0x28, 0xf0, 0x7d, + 0xfc, 0x0e, 0xe0, 0x28, 0xf0, 0x7a, 0xfc, 0x01, + 0x20, 0x31, 0x1c, 0xf7, 0xf7, 0xe0, 0xf9, 0x07, + 0x1c, 0x26, 0xd0, 0xf8, 0x1d, 0xff, 0x30, 0x7a, + 0x30, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x0c, + 0x25, 0xe1, 0x1d, 0x0d, 0x31, 0x0c, 0xc9, 0xf8, + 0x1d, 0x7d, 0x30, 0x0c, 0xc0, 0xe0, 0x69, 0xf9, + 0x1d, 0xf8, 0x67, 0x20, 0x6a, 0x79, 0x31, 0x08, + 0x60, 0x00, 0x21, 0x38, 0x1c, 0x03, 0x23, 0x2a, + 0x1c, 0xed, 0x09, 0x00, 0xd1, 0x00, 0xf5, 0xf7, + 0xa3, 0xfa, 0x36, 0x20, 0x20, 0x60, 0xe6, 0x60, + 0x27, 0x61, 0x00, 0x98, 0x60, 0x61, 0x01, 0x98, + 0x00, 0x28, 0x07, 0xd0, 0x0e, 0x20, 0x21, 0x1c, + 0xf3, 0xf7, 0x66, 0xfe, 0x06, 0xe0, 0x07, 0x20, + 0x00, 0x90, 0xee, 0xe7, 0x0a, 0x20, 0x21, 0x1c, + 0xf3, 0xf7, 0x5e, 0xfe, 0x03, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0xb0, 0xb5, + 0xcd, 0x68, 0x04, 0x1c, 0xe8, 0x68, 0x0f, 0x1c, + 0x00, 0x28, 0x0d, 0xd0, 0x0c, 0x28, 0x0b, 0xd0, + 0x14, 0x28, 0x01, 0xd0, 0x1a, 0x28, 0x0f, 0xd1, + 0x01, 0x23, 0x03, 0x22, 0x1a, 0x21, 0x28, 0x1c, + 0xf5, 0xf7, 0x9e, 0xfc, 0x00, 0x20, 0x08, 0xe0, + 0x01, 0x23, 0x03, 0x22, 0x00, 0x21, 0x28, 0x1c, + 0xf5, 0xf7, 0x96, 0xfc, 0x00, 0x20, 0x00, 0xe0, + 0x0c, 0x20, 0x37, 0x21, 0x39, 0x60, 0x69, 0x68, + 0x38, 0x61, 0xf9, 0x60, 0x00, 0x2c, 0x04, 0xd0, + 0x0e, 0x20, 0x39, 0x1c, 0xf3, 0xf7, 0x30, 0xfe, + 0x03, 0xe0, 0x0a, 0x20, 0x39, 0x1c, 0xf3, 0xf7, + 0x2b, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0x00, 0xf3, 0xb5, 0x84, 0xb0, + 0x00, 0x25, 0x0c, 0x1c, 0x09, 0x69, 0x02, 0x91, + 0xe2, 0x68, 0x01, 0x92, 0xa1, 0x69, 0x00, 0x91, + 0x28, 0xf0, 0x06, 0xfc, 0x67, 0x69, 0x00, 0x2f, + 0x2e, 0xd0, 0x00, 0x21, 0x38, 0x1c, 0xf5, 0xf7, + 0x15, 0xfb, 0x00, 0x28, 0x28, 0xd0, 0xf8, 0x68, + 0x17, 0x28, 0x16, 0xd0, 0x0f, 0xdc, 0x00, 0x28, + 0x05, 0xd0, 0x0f, 0x28, 0x03, 0xd0, 0x10, 0x28, + 0x01, 0xd0, 0x11, 0x28, 0x15, 0xd1, 0xf8, 0x1d, + 0xff, 0x30, 0x7a, 0x30, 0x41, 0x69, 0x0f, 0x26, + 0x01, 0x31, 0x41, 0x61, 0x0e, 0xe0, 0x18, 0x28, + 0x03, 0xd0, 0x19, 0x28, 0x01, 0xd0, 0x1a, 0x28, + 0x07, 0xd1, 0xf8, 0x1d, 0xed, 0x09, 0x00, 0xd2, + 0x00, 0xff, 0x30, 0x7a, 0x30, 0x41, 0x69, 0x17, + 0x26, 0x01, 0x31, 0x41, 0x61, 0x00, 0xe0, 0x00, + 0x27, 0x28, 0xf0, 0xd4, 0xfb, 0x00, 0x2f, 0x10, + 0xd1, 0x07, 0x26, 0x69, 0xe0, 0x28, 0xf0, 0xce, + 0xfb, 0x01, 0x20, 0x02, 0x99, 0xf7, 0xf7, 0x34, + 0xf9, 0x07, 0x1c, 0xf5, 0xd0, 0xf8, 0x1d, 0xff, + 0x30, 0x7a, 0x30, 0x41, 0x69, 0x01, 0x31, 0x41, + 0x61, 0x0f, 0x26, 0x00, 0x99, 0x01, 0x9a, 0x38, + 0x1c, 0xf7, 0xf7, 0x52, 0xf9, 0xe1, 0x1d, 0x15, + 0x31, 0x0c, 0xc9, 0x05, 0x1c, 0x10, 0x30, 0x0c, + 0xc0, 0xe8, 0x1d, 0x15, 0x30, 0xe1, 0x1d, 0x1d, + 0x31, 0x03, 0x90, 0x0c, 0xc9, 0x0c, 0xc0, 0xe1, + 0x6a, 0x05, 0x23, 0x28, 0x1c, 0x22, 0x6b, 0xf7, + 0xf7, 0x99, 0xfc, 0x02, 0x20, 0xe8, 0x60, 0xf8, + 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x00, 0x21, 0x41, + 0x60, 0x29, 0x49, 0xf8, 0x1d, 0x0c, 0xc9, 0xff, + 0x30, 0x82, 0x30, 0x0c, 0xc0, 0x00, 0x21, 0xe9, + 0x64, 0x29, 0x65, 0x69, 0x65, 0xa9, 0x65, 0xe9, + 0x65, 0x29, 0x66, 0xa9, 0x66, 0x69, 0x67, 0xa9, + 0x67, 0xe8, 0x1d, 0x79, 0x30, 0xe9, 0x67, 0x41, + 0x60, 0xc1, 0x60, 0xe8, 0x1d, 0x29, 0x64, 0x69, + 0x64, 0xb9, 0x30, 0x81, 0x63, 0xf8, 0x1d, 0x61, + 0x6b, 0x79, 0x30, 0xc1, 0x61, 0x1b, 0x49, 0x09, + 0x6b, 0x01, 0x62, 0x00, 0x21, 0x41, 0x62, 0x01, + 0x20, 0x00, 0x03, 0x78, 0x66, 0xb8, 0x66, 0x03, + 0x99, 0xf8, 0x1d, 0x0c, 0xc9, 0x65, 0x30, 0x0c, + 0xc0, 0x15, 0x49, 0xf8, 0x1d, 0x0c, 0xc9, 0x51, + 0x30, 0x0c, 0xc0, 0xff, 0x20, 0x01, 0x30, 0x38, + 0x65, 0x78, 0x65, 0x38, 0x1c, 0x04, 0x23, 0x29, + 0x1c, 0x32, 0x1c, 0xf5, 0xf7, 0xaf, 0xf9, 0x00, + 0x26, 0x38, 0x20, 0x20, 0x60, 0x01, 0x9a, 0xe2, + 0x60, 0x27, 0x61, 0x65, 0x61, 0xa6, 0x61, 0xed, + 0x09, 0x00, 0xd3, 0x00, 0x04, 0x98, 0x00, 0x28, + 0x04, 0xd0, 0x0e, 0x20, 0x21, 0x1c, 0xf3, 0xf7, + 0x70, 0xfd, 0x03, 0xe0, 0x0a, 0x20, 0x21, 0x1c, + 0xf3, 0xf7, 0x6b, 0xfd, 0x30, 0x1c, 0x06, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xe6, + 0x03, 0x20, 0x48, 0xe6, 0x03, 0x20, 0x88, 0xe6, + 0x03, 0x20, 0xf0, 0xb5, 0x0f, 0x1c, 0xc9, 0x68, + 0x04, 0x1c, 0x0e, 0x1d, 0x41, 0xce, 0xc2, 0x68, + 0x00, 0x25, 0x17, 0x2a, 0x17, 0xd0, 0x08, 0xdc, + 0x00, 0x2a, 0x1a, 0xd0, 0x0f, 0x2a, 0x18, 0xd0, + 0x10, 0x2a, 0x16, 0xd0, 0x11, 0x2a, 0x14, 0xd0, + 0x05, 0xe0, 0x18, 0x2a, 0x0b, 0xd0, 0x19, 0x2a, + 0x09, 0xd0, 0x1a, 0x2a, 0x01, 0xd0, 0x0c, 0x25, + 0x10, 0xe0, 0xc9, 0x68, 0x05, 0x29, 0x02, 0xd1, + 0xff, 0x25, 0x11, 0x35, 0x0a, 0xe0, 0x01, 0x23, + 0x04, 0x22, 0x1a, 0x21, 0xf5, 0xf7, 0x91, 0xfb, + 0x04, 0xe0, 0x01, 0x23, 0x04, 0x22, 0x00, 0x21, + 0xf5, 0xf7, 0x8b, 0xfb, 0x39, 0x20, 0x38, 0x60, + 0x3d, 0x61, 0xfe, 0x60, 0x00, 0x2c, 0x04, 0xd0, + 0x0e, 0x20, 0x39, 0x1c, 0xf3, 0xf7, 0x29, 0xfd, + 0x03, 0xe0, 0x0a, 0x20, 0x39, 0x1c, 0xf3, 0xf7, + 0x24, 0xfd, 0xf0, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xf3, 0xf7, + 0xad, 0xfc, 0x00, 0x28, 0x07, 0xd0, 0x3d, 0x21, + 0x01, 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x01, 0x1c, + 0x0e, 0x20, 0xf3, 0xf7, 0x12, 0xfd, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x90, 0xb5, + 0xc8, 0x68, 0x0f, 0x1c, 0x0a, 0x69, 0xc1, 0x1d, + 0x79, 0x31, 0xca, 0x60, 0x7a, 0x69, 0x00, 0x24, + 0x0a, 0x61, 0x06, 0x21, 0xf5, 0xf7, 0xcb, 0xf9, + 0x38, 0x1c, 0xf3, 0xf7, 0xca, 0xfc, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, + 0xce, 0x68, 0xed, 0x09, 0x00, 0xd4, 0x00, 0x00, + 0x25, 0x0f, 0x1c, 0x02, 0x20, 0x31, 0x1c, 0xf7, + 0xf7, 0x44, 0xf8, 0x04, 0x1c, 0x01, 0xd1, 0x07, + 0x25, 0x13, 0xe0, 0xe0, 0x1d, 0x39, 0x69, 0x79, + 0x30, 0xc1, 0x60, 0x79, 0x69, 0x01, 0x61, 0x19, + 0x49, 0xe0, 0x1d, 0x0c, 0xc9, 0x8d, 0x30, 0x0c, + 0xc0, 0xff, 0x20, 0x01, 0x30, 0x20, 0x65, 0x60, + 0x65, 0xe0, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x07, + 0x20, 0xe0, 0x60, 0x02, 0x9a, 0x00, 0x2a, 0x03, + 0xd1, 0x38, 0x1c, 0xf3, 0xf7, 0xa0, 0xfc, 0x10, + 0xe0, 0x3a, 0x20, 0x38, 0x60, 0x3c, 0x61, 0x7d, + 0x61, 0xfe, 0x60, 0x00, 0x98, 0x00, 0x28, 0x04, + 0xd0, 0x0e, 0x20, 0x39, 0x1c, 0xf3, 0xf7, 0xc7, + 0xfc, 0x03, 0xe0, 0x0a, 0x20, 0x39, 0x1c, 0xf3, + 0xf7, 0xc2, 0xfc, 0x00, 0x2d, 0x05, 0xd1, 0x06, + 0x23, 0x07, 0x22, 0x00, 0x21, 0x20, 0x1c, 0xf5, + 0xf7, 0xea, 0xf8, 0x03, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, 0x88, + 0xe6, 0x03, 0x20, 0xf7, 0xb5, 0xcd, 0x68, 0x13, + 0x1c, 0x14, 0x1c, 0x0f, 0x1c, 0x00, 0x21, 0x06, + 0x22, 0x00, 0x26, 0x28, 0x1c, 0xf5, 0xf7, 0xff, + 0xfa, 0x00, 0x2c, 0x03, 0xd1, 0x38, 0x1c, 0xf3, + 0xf7, 0x6e, 0xfc, 0x11, 0xe0, 0x3a, 0x20, 0x38, + 0x60, 0x68, 0x68, 0x0c, 0x37, 0x61, 0xc7, 0x00, + 0x98, 0x18, 0x3f, 0x00, 0x28, 0x04, 0xd0, 0x0e, + 0x20, 0x39, 0x1c, 0xf3, 0xf7, 0x94, 0xfc, 0x03, + 0xe0, 0x0a, 0x20, 0x39, 0x1c, 0xf3, 0xf7, 0x8f, + 0xfc, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0xc1, 0x68, 0x00, 0x69, 0x88, + 0x60, 0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x04, + 0x1c, 0x0f, 0x1c, 0xf3, 0xf7, 0x11, 0xfc, 0x00, + 0x28, 0x08, 0xd0, 0x3e, 0x21, 0x01, 0x60, 0x61, + 0x68, 0xc1, 0x60, 0x07, 0x61, 0xed, 0x09, 0x00, + 0xd5, 0x00, 0x01, 0x1c, 0x0e, 0x20, 0xf3, 0xf7, + 0x75, 0xfc, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xf0, 0xb5, 0x87, 0xb0, 0xcd, 0x68, 0x04, 0x1c, + 0x6e, 0x68, 0x08, 0x69, 0x05, 0x90, 0x48, 0x69, + 0x04, 0x90, 0x88, 0x69, 0x01, 0x90, 0xc8, 0x69, + 0x00, 0x90, 0xc8, 0x1d, 0x19, 0x30, 0x06, 0x90, + 0x0f, 0x1c, 0x01, 0x68, 0x02, 0x91, 0x40, 0x68, + 0x03, 0x90, 0xf3, 0xf7, 0xec, 0xfb, 0x01, 0x1c, + 0x04, 0x20, 0x08, 0x60, 0x00, 0x22, 0x20, 0x1c, + 0xcd, 0x60, 0xff, 0xf7, 0xe9, 0xf9, 0x03, 0x20, + 0x38, 0x60, 0x05, 0x98, 0x38, 0x61, 0x04, 0x98, + 0x78, 0x61, 0x01, 0x98, 0xb8, 0x61, 0x00, 0x98, + 0xf8, 0x61, 0x06, 0x98, 0x03, 0x99, 0x41, 0x60, + 0x02, 0x99, 0x01, 0x60, 0xfe, 0x60, 0x28, 0x1c, + 0x32, 0x1c, 0x29, 0x69, 0xf6, 0xf7, 0x6a, 0xff, + 0x20, 0x1c, 0x39, 0x1c, 0x2a, 0x1c, 0xff, 0xf7, + 0x49, 0xf9, 0x07, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x01, 0x69, 0xc0, 0x68, + 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0xf0, 0xb5, + 0x85, 0xb0, 0xc2, 0x68, 0xc5, 0x69, 0x00, 0x92, + 0x01, 0x69, 0x47, 0x69, 0x04, 0x1c, 0x67, 0x48, + 0x01, 0x91, 0xc1, 0x1d, 0xf9, 0x31, 0x04, 0x91, + 0xc1, 0x1d, 0xf1, 0x31, 0x03, 0x91, 0x00, 0x2a, + 0x57, 0xd0, 0xa6, 0x69, 0x00, 0x2f, 0x1a, 0xd0, + 0x68, 0x68, 0xb8, 0x42, 0x09, 0xd1, 0xff, 0x20, + 0x35, 0x30, 0x70, 0x43, 0xc0, 0x19, 0xff, 0x30, + 0x99, 0x30, 0xe9, 0x1d, 0x79, 0x31, 0x88, 0x61, + 0x09, 0xe0, 0x38, 0x1c, 0x31, 0x1c, 0x00, 0x9a, + 0xf6, 0xf7, 0x86, 0xff, 0xe9, 0x1d, 0x79, 0x31, + 0x88, 0x61, 0x01, 0x21, 0xc1, 0x60, 0xe8, 0x1d, + 0x99, 0x30, 0x06, 0x73, 0x6f, 0xe0, 0xe8, 0x1d, + 0x79, 0x30, 0x02, 0x90, 0x80, 0x69, 0x00, 0x28, + 0xed, 0x09, 0x00, 0xd6, 0x00, 0x05, 0xd0, 0x40, + 0x68, 0x01, 0x21, 0xf5, 0xf7, 0xf7, 0xf8, 0x07, + 0x1c, 0x63, 0xd1, 0x01, 0x20, 0x01, 0x99, 0xf6, + 0xf7, 0x41, 0xff, 0x07, 0x1c, 0x5d, 0xd0, 0x38, + 0x1c, 0x31, 0x1c, 0x00, 0x9a, 0xf6, 0xf7, 0x66, + 0xff, 0x02, 0x99, 0x1a, 0x22, 0x88, 0x61, 0x01, + 0x21, 0xc1, 0x60, 0xe8, 0x1d, 0x99, 0x30, 0xf9, + 0x1d, 0xff, 0x31, 0x06, 0x73, 0x00, 0x20, 0x7a, + 0x31, 0x48, 0x60, 0x03, 0x99, 0xf8, 0x1d, 0xff, + 0x30, 0x48, 0xc9, 0x82, 0x30, 0x48, 0xc0, 0x04, + 0x99, 0xf8, 0x1d, 0x48, 0xc9, 0x51, 0x30, 0x48, + 0xc0, 0xff, 0x20, 0x01, 0x30, 0x38, 0x65, 0x78, + 0x65, 0x02, 0x98, 0x01, 0x23, 0x81, 0x69, 0x38, + 0x1c, 0xf4, 0xf7, 0xf6, 0xff, 0x35, 0xe0, 0x00, + 0x2f, 0x2c, 0xd1, 0xe8, 0x1d, 0x79, 0x30, 0x80, + 0x69, 0x00, 0x28, 0x05, 0xd0, 0x40, 0x68, 0x01, + 0x21, 0xf5, 0xf7, 0xbc, 0xf8, 0x07, 0x1c, 0x21, + 0xd1, 0x02, 0x20, 0x01, 0x99, 0xf6, 0xf7, 0x06, + 0xff, 0x07, 0x1c, 0x1b, 0xd0, 0xf9, 0x1d, 0xff, + 0x31, 0x7a, 0x31, 0x00, 0x20, 0x48, 0x60, 0x03, + 0x99, 0xf8, 0x1d, 0xff, 0x30, 0x0c, 0xc9, 0x82, + 0x30, 0x0c, 0xc0, 0x04, 0x99, 0xf8, 0x1d, 0x0c, + 0xc9, 0x51, 0x30, 0x0c, 0xc0, 0xff, 0x20, 0x01, + 0x30, 0x38, 0x65, 0x78, 0x65, 0xf9, 0x1d, 0xff, + 0x31, 0x38, 0x1c, 0x01, 0x23, 0x1a, 0x22, 0x92, + 0x31, 0xf4, 0xf7, 0xc6, 0xff, 0xe9, 0x1d, 0x79, + 0x31, 0x00, 0x20, 0x88, 0x61, 0xe9, 0x1d, 0x99, + 0x31, 0x08, 0x73, 0x00, 0x2f, 0x14, 0xd1, 0x41, + 0x20, 0x20, 0x60, 0x68, 0x68, 0xa0, 0x61, 0x65, + 0x61, 0x68, 0x68, 0x40, 0x68, 0x20, 0x61, 0x28, + 0x7e, 0xe0, 0x60, 0x07, 0x20, 0xe0, 0x61, 0x0e, + 0x20, 0x21, 0x1c, 0xf3, 0xf7, 0x7d, 0xfb, 0x00, + 0x20, 0x05, 0xb0, 0xed, 0x09, 0x00, 0xd7, 0x00, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, 0x6a, + 0x40, 0x00, 0x80, 0x35, 0xe8, 0x61, 0x21, 0x6a, + 0x00, 0x28, 0x29, 0x63, 0x08, 0xd1, 0x00, 0x29, + 0x06, 0xd1, 0x00, 0x27, 0x20, 0x1c, 0x69, 0x61, + 0xf3, 0xf7, 0x35, 0xfb, 0x38, 0x1c, 0xea, 0xe7, + 0x20, 0x1c, 0xf3, 0xf7, 0x30, 0xfb, 0xa8, 0x69, + 0x00, 0x28, 0x03, 0xd1, 0xf8, 0x1d, 0xff, 0x30, + 0x92, 0x30, 0xa8, 0x61, 0x01, 0x21, 0x69, 0x61, + 0x00, 0x20, 0xdc, 0xe7, 0x00, 0x00, 0x88, 0xe5, + 0x03, 0x20, 0xff, 0x21, 0x41, 0x62, 0x01, 0x21, + 0x81, 0x62, 0x06, 0x49, 0x89, 0x6a, 0xc1, 0x62, + 0x00, 0x21, 0x01, 0x63, 0x40, 0x68, 0xff, 0x30, + 0x91, 0x30, 0x01, 0x68, 0x02, 0x23, 0x99, 0x43, + 0x01, 0x60, 0x70, 0x47, 0x00, 0x00, 0x48, 0xe6, + 0x03, 0x20, 0xb0, 0xb5, 0x05, 0x1c, 0x0f, 0x1c, + 0x03, 0xd1, 0x00, 0x20, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x38, 0x1c, 0xf3, 0xf7, 0x97, 0xfa, + 0x04, 0x1c, 0x0a, 0x2d, 0x25, 0xd2, 0x01, 0xa3, + 0x5b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x21, 0x04, + 0x0a, 0x10, 0x1c, 0x21, 0x21, 0x21, 0x21, 0x16, + 0x00, 0x21, 0x20, 0x1c, 0x3a, 0x1c, 0xf2, 0xf7, + 0x96, 0xfe, 0x16, 0xe0, 0xff, 0x21, 0x20, 0x1c, + 0x3a, 0x1c, 0xf2, 0xf7, 0x90, 0xfe, 0x10, 0xe0, + 0xaa, 0x21, 0x20, 0x1c, 0x3a, 0x1c, 0xf2, 0xf7, + 0x8a, 0xfe, 0x0a, 0xe0, 0xf0, 0x21, 0x20, 0x1c, + 0x3a, 0x1c, 0xf2, 0xf7, 0x84, 0xfe, 0x04, 0xe0, + 0x3a, 0x1c, 0x20, 0x1c, 0x02, 0x49, 0xf2, 0xf7, + 0x06, 0xff, 0x20, 0x1c, 0xce, 0xe7, 0x60, 0x63, + 0x03, 0x20, 0xb0, 0xb5, 0x00, 0x25, 0x13, 0x4c, + 0x85, 0x63, 0x07, 0x1c, 0x20, 0x6e, 0x00, 0x28, + 0x06, 0xd0, 0x40, 0x6a, 0xf3, 0xf7, 0x8b, 0xfa, + 0x20, 0x6e, 0x1a, 0xf0, 0x4e, 0xff, 0xed, 0x09, + 0x00, 0xd8, 0x00, 0x25, 0x66, 0x38, 0x6b, 0x00, + 0x28, 0x0e, 0xd0, 0x00, 0x6b, 0x00, 0x28, 0x01, + 0xd0, 0xf3, 0xf7, 0x7f, 0xfa, 0x38, 0x6b, 0xc0, + 0x69, 0x00, 0x28, 0x01, 0xd0, 0xf3, 0xf7, 0x79, + 0xfa, 0x38, 0x6b, 0xf3, 0xf7, 0xdc, 0xfa, 0x3d, + 0x63, 0x78, 0x6a, 0xfd, 0x28, 0x01, 0xd1, 0xff, + 0x20, 0x78, 0x62, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x90, 0xe6, 0x03, 0x20, 0xf0, + 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0xc4, 0x68, 0x00, + 0x69, 0xfe, 0x26, 0x05, 0x28, 0x5d, 0x4d, 0x73, + 0xd0, 0x08, 0xdc, 0x05, 0x28, 0x71, 0xd2, 0x01, + 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x1b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x00, 0x08, 0x28, 0x04, + 0xd0, 0x11, 0xdc, 0x06, 0x28, 0x64, 0xd0, 0x07, + 0x28, 0x64, 0xd1, 0x28, 0xf0, 0xae, 0xf8, 0x66, + 0x62, 0x78, 0x69, 0xa0, 0x62, 0x78, 0x6a, 0x28, + 0x62, 0xb8, 0x6a, 0x68, 0x62, 0x00, 0x20, 0xe0, + 0x62, 0x28, 0xf0, 0x9f, 0xf8, 0x93, 0xe0, 0x09, + 0x28, 0x21, 0xd0, 0xff, 0x28, 0x52, 0xd1, 0x28, + 0xf0, 0x9c, 0xf8, 0x00, 0x20, 0xa0, 0x63, 0x39, + 0x69, 0x61, 0x62, 0xff, 0x29, 0x03, 0xd1, 0x79, + 0x69, 0xa1, 0x62, 0x01, 0x21, 0xe1, 0x62, 0x25, + 0x6b, 0x00, 0x2d, 0x6f, 0xd0, 0x20, 0x63, 0x28, + 0xf0, 0x88, 0xf8, 0x28, 0x6b, 0x00, 0x28, 0x01, + 0xd0, 0xf3, 0xf7, 0x27, 0xfa, 0xe8, 0x69, 0x00, + 0x28, 0x01, 0xd0, 0xf3, 0xf7, 0x22, 0xfa, 0x28, + 0x1c, 0xf3, 0xf7, 0x85, 0xfa, 0x6f, 0xe0, 0x39, + 0x6a, 0xfe, 0x69, 0x04, 0x91, 0xb9, 0x69, 0x02, + 0x90, 0x03, 0x91, 0x78, 0x69, 0x38, 0x49, 0x01, + 0x90, 0x08, 0x6e, 0x00, 0x90, 0x1a, 0xf0, 0xb5, + 0xfe, 0x35, 0x49, 0x08, 0x66, 0x02, 0x98, 0x31, + 0x1c, 0xff, 0xf7, 0x3d, 0xff, 0x32, 0x49, 0x09, + 0x6e, 0xed, 0x09, 0x00, 0xd9, 0x00, 0x48, 0x62, + 0x30, 0x49, 0x08, 0x6e, 0x06, 0x62, 0x28, 0xf0, + 0x63, 0xf8, 0xfd, 0x20, 0x60, 0x62, 0x01, 0x98, + 0x2c, 0x4a, 0xa0, 0x62, 0x00, 0x20, 0xe0, 0x62, + 0x04, 0x99, 0x61, 0x63, 0xa0, 0x63, 0x79, 0x6a, + 0x29, 0x62, 0xb9, 0x6a, 0x69, 0x62, 0x0d, 0x21, + 0x39, 0x60, 0x26, 0x49, 0xfc, 0x60, 0x39, 0x61, + 0x21, 0x7e, 0x11, 0x72, 0x02, 0xe0, 0x2d, 0xe0, + 0x3c, 0xe0, 0x3b, 0xe0, 0x21, 0x49, 0x09, 0x6e, + 0xb9, 0x61, 0x78, 0x61, 0x02, 0x20, 0x38, 0x62, + 0xfe, 0x61, 0x03, 0x99, 0x38, 0x1c, 0x79, 0x62, + 0x03, 0x99, 0xb9, 0x62, 0xff, 0xf7, 0xb8, 0xf9, + 0x60, 0x6f, 0x00, 0x28, 0x09, 0xd0, 0xc0, 0x6b, + 0x00, 0x28, 0x04, 0xd0, 0xf3, 0xf7, 0x14, 0xfa, + 0x61, 0x6f, 0x00, 0x20, 0xc8, 0x63, 0x00, 0x20, + 0x60, 0x67, 0x28, 0xf0, 0x29, 0xf8, 0x00, 0x98, + 0x00, 0x28, 0x06, 0xd0, 0x00, 0x98, 0x40, 0x6a, + 0xf3, 0xf7, 0xc6, 0xf9, 0x00, 0x98, 0x1a, 0xf0, + 0x89, 0xfe, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x0d, 0xe0, 0x28, 0xf0, 0x1c, 0xf8, + 0x66, 0x62, 0x78, 0x69, 0x01, 0x21, 0xa0, 0x62, + 0x78, 0x6a, 0x28, 0x62, 0xb8, 0x6a, 0x68, 0x62, + 0xe1, 0x62, 0x28, 0xf0, 0x0d, 0xf8, 0x01, 0xe0, + 0x28, 0xf0, 0x0a, 0xf8, 0x00, 0x2f, 0xe8, 0xd0, + 0x38, 0x1c, 0xf3, 0xf7, 0xe9, 0xf9, 0xe4, 0xe7, + 0x48, 0xe6, 0x03, 0x20, 0x90, 0xe6, 0x03, 0x20, + 0xb0, 0xb5, 0xc7, 0x68, 0x44, 0x21, 0x01, 0x60, + 0xb9, 0x68, 0xfd, 0x1d, 0xf5, 0x35, 0xc1, 0x60, + 0x0e, 0xcd, 0xc4, 0x1d, 0x09, 0x34, 0x0e, 0xc4, + 0x0e, 0xcd, 0x0e, 0xc4, 0xf9, 0x1d, 0xb9, 0x31, + 0x09, 0x6a, 0x81, 0x62, 0x01, 0x1c, 0x0a, 0x20, + 0xf3, 0xf7, 0x02, 0xfa, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xed, 0x09, 0x00, 0xda, + 0x00, 0xf0, 0x47, 0x2d, 0xe9, 0x00, 0x30, 0xa0, + 0xe3, 0x00, 0xc0, 0xa0, 0xe3, 0x18, 0x70, 0x81, + 0xe2, 0x04, 0x80, 0xa0, 0xe3, 0x65, 0x00, 0x00, + 0xea, 0x00, 0xe0, 0x91, 0xe5, 0x0e, 0x00, 0x52, + 0xe1, 0x02, 0xe0, 0xa0, 0x31, 0x00, 0x00, 0x5e, + 0xe3, 0x5f, 0x00, 0x00, 0x0a, 0x04, 0x40, 0x91, + 0xe5, 0x04, 0x50, 0x48, 0xe0, 0x03, 0x50, 0x05, + 0xe2, 0x0e, 0x00, 0x55, 0xe1, 0x0e, 0x50, 0xa0, + 0x21, 0x05, 0x60, 0x83, 0xe0, 0x03, 0x60, 0x06, + 0xe2, 0x06, 0x00, 0x53, 0xe1, 0x0e, 0x00, 0x00, + 0x0a, 0x03, 0x00, 0x53, 0xe3, 0x06, 0x00, 0x00, + 0x1a, 0x01, 0x30, 0xd4, 0xe4, 0x03, 0x3c, 0x8c, + 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x04, 0x00, 0x80, + 0xe2, 0x00, 0xc0, 0xa0, 0xe3, 0x00, 0x30, 0xa0, + 0xe3, 0x03, 0x00, 0x00, 0xea, 0x01, 0x90, 0xd4, + 0xe4, 0x83, 0xa1, 0xa0, 0xe1, 0x01, 0x30, 0x83, + 0xe2, 0x19, 0xca, 0x8c, 0xe1, 0x06, 0x00, 0x53, + 0xe1, 0xf0, 0xff, 0xff, 0x1a, 0x05, 0x60, 0x4e, + 0xe0, 0x26, 0x91, 0xa0, 0xe1, 0x00, 0x00, 0x53, + 0xe3, 0x1d, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x53, + 0xe3, 0x24, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x53, + 0xe3, 0x2d, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x53, + 0xe3, 0x09, 0x00, 0x00, 0x1a, 0x01, 0x60, 0x49, + 0xe2, 0x00, 0x00, 0x59, 0xe3, 0x06, 0x00, 0x00, + 0x0a, 0x04, 0x90, 0x94, 0xe4, 0x09, 0xcc, 0x8c, + 0xe1, 0x00, 0xc0, 0x80, 0xe5, 0x29, 0xc4, 0xa0, + 0xe1, 0x01, 0x60, 0x56, 0xe2, 0x04, 0x00, 0x80, + 0xe2, 0xf8, 0xff, 0xff, 0x2a, 0x0e, 0x60, 0x83, + 0xe0, 0x05, 0x50, 0x46, 0xe0, 0x03, 0x50, 0x05, + 0xe2, 0x05, 0x00, 0x53, 0xe1, 0x2d, 0x00, 0x00, + 0x0a, 0x03, 0x00, 0x53, 0xe3, 0x25, 0x00, 0x00, + 0x1a, 0x01, 0x30, 0xd4, 0xe4, 0x03, 0x3c, 0xed, + 0x09, 0x00, 0xdb, 0x00, 0x8c, 0xe1, 0x00, 0x30, + 0x80, 0xe5, 0x04, 0x00, 0x80, 0xe2, 0x00, 0xc0, + 0xa0, 0xe3, 0x00, 0x30, 0xa0, 0xe3, 0x22, 0x00, + 0x00, 0xea, 0x01, 0x60, 0x49, 0xe2, 0x00, 0x00, + 0x59, 0xe3, 0xee, 0xff, 0xff, 0x0a, 0x04, 0x90, + 0x94, 0xe4, 0x00, 0x90, 0x80, 0xe5, 0x04, 0x00, + 0x80, 0xe2, 0x01, 0x60, 0x56, 0xe2, 0xfa, 0xff, + 0xff, 0x2a, 0xe8, 0xff, 0xff, 0xea, 0x01, 0x60, + 0x49, 0xe2, 0x00, 0x00, 0x59, 0xe3, 0xe5, 0xff, + 0xff, 0x0a, 0x04, 0x90, 0x94, 0xe4, 0x09, 0xc4, + 0x8c, 0xe1, 0x00, 0xc0, 0x80, 0xe5, 0x29, 0xcc, + 0xa0, 0xe1, 0x01, 0x60, 0x56, 0xe2, 0x04, 0x00, + 0x80, 0xe2, 0xf8, 0xff, 0xff, 0x2a, 0xdd, 0xff, + 0xff, 0xea, 0x01, 0x60, 0x49, 0xe2, 0x00, 0x00, + 0x59, 0xe3, 0xda, 0xff, 0xff, 0x0a, 0x04, 0x90, + 0x94, 0xe4, 0x09, 0xc8, 0x8c, 0xe1, 0x00, 0xc0, + 0x80, 0xe5, 0x29, 0xc8, 0xa0, 0xe1, 0x01, 0x60, + 0x56, 0xe2, 0x04, 0x00, 0x80, 0xe2, 0xf8, 0xff, + 0xff, 0x2a, 0xd2, 0xff, 0xff, 0xea, 0x01, 0x90, + 0xd4, 0xe4, 0x83, 0x61, 0xa0, 0xe1, 0x01, 0x30, + 0x83, 0xe2, 0x19, 0xc6, 0x8c, 0xe1, 0x05, 0x00, + 0x53, 0xe1, 0xd1, 0xff, 0xff, 0x1a, 0x0e, 0x20, + 0x42, 0xe0, 0x08, 0x10, 0x81, 0xe2, 0x00, 0x00, + 0x52, 0xe3, 0x01, 0x00, 0x00, 0xda, 0x07, 0x00, + 0x51, 0xe1, 0x95, 0xff, 0xff, 0x3a, 0x00, 0xc0, + 0x80, 0xe5, 0xf0, 0x47, 0xbd, 0xe8, 0x1e, 0xff, + 0x2f, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x0a, 0x2b, + 0xa0, 0xe3, 0x06, 0x00, 0x80, 0xe8, 0x0c, 0x10, + 0x80, 0xe5, 0x0a, 0x20, 0xa0, 0xe3, 0x08, 0x20, + 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf0, 0x4f, + 0x2d, 0xe9, 0x00, 0x09, 0x90, 0xe9, 0x00, 0x40, + 0xa0, 0xe1, 0x01, 0x70, 0xa0, 0xe1, 0x02, 0x60, + 0xa0, 0xe1, 0xed, 0x09, 0x00, 0xdc, 0x00, 0x03, + 0x50, 0xa0, 0xe1, 0x00, 0x00, 0x53, 0xe3, 0x00, + 0xa0, 0x90, 0xe5, 0x00, 0x90, 0xa0, 0xe3, 0x2a, + 0x00, 0x00, 0xda, 0x09, 0x10, 0xd6, 0xe7, 0x02, + 0x34, 0xa0, 0xe3, 0x01, 0x3b, 0x43, 0xe2, 0x81, + 0x11, 0x8b, 0xe1, 0x02, 0x1b, 0x81, 0xe3, 0x00, + 0x00, 0xa0, 0xe3, 0x0f, 0x20, 0x01, 0xe2, 0x0f, + 0x00, 0x52, 0xe3, 0x00, 0x00, 0x52, 0x13, 0x03, + 0x00, 0x00, 0x1a, 0x0a, 0x8b, 0x88, 0xe2, 0x05, + 0x07, 0x58, 0xe3, 0x05, 0x87, 0xa0, 0xc3, 0x03, + 0x00, 0x00, 0xea, 0x08, 0x25, 0x68, 0xe0, 0x42, + 0x85, 0xa0, 0xe1, 0x0a, 0x0b, 0x58, 0xe3, 0x0a, + 0x8b, 0xa0, 0xb3, 0x08, 0x00, 0x11, 0xe3, 0x08, + 0x20, 0x8a, 0x00, 0x08, 0x20, 0x4a, 0x10, 0x03, + 0x00, 0x52, 0xe1, 0x03, 0x20, 0xa0, 0xc1, 0x01, + 0x00, 0x00, 0xca, 0xfe, 0x04, 0x52, 0xe3, 0xfe, + 0x24, 0xa0, 0xb3, 0x82, 0x22, 0x62, 0xe0, 0xc2, + 0xa2, 0xa0, 0xe1, 0xc1, 0x10, 0xa0, 0xe1, 0x10, + 0x00, 0x51, 0xe3, 0x0a, 0x00, 0x80, 0xe0, 0xe5, + 0xff, 0xff, 0xaa, 0xc0, 0x06, 0xa0, 0xe1, 0x00, + 0x08, 0xa0, 0xe1, 0x40, 0x08, 0xa0, 0xe1, 0x07, + 0xb0, 0x01, 0xe2, 0x63, 0x9f, 0x00, 0xeb, 0x20, + 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xd1, 0xe7, 0x09, + 0x00, 0xc7, 0xe7, 0x01, 0x90, 0x89, 0xe2, 0x05, + 0x00, 0x59, 0xe1, 0xd4, 0xff, 0xff, 0xba, 0x00, + 0x09, 0x84, 0xe9, 0x00, 0xa0, 0x84, 0xe5, 0xf0, + 0x4f, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x08, + 0x10, 0x01, 0x20, 0xff, 0x4f, 0x2d, 0xe9, 0x0c, + 0x40, 0x90, 0xe5, 0x04, 0x40, 0x90, 0xe9, 0x84, + 0x61, 0xa0, 0xe1, 0x00, 0x00, 0x53, 0xe3, 0x02, + 0xa4, 0xa0, 0xc3, 0x01, 0xab, 0x4a, 0xc2, 0x00, + 0xc0, 0x90, 0xe5, 0x00, 0x50, 0xa0, 0xe3, 0x00, + 0x00, 0x00, 0xca, 0x2d, 0x00, 0xed, 0x09, 0x00, + 0xdd, 0x00, 0x00, 0xea, 0x08, 0x90, 0x9d, 0xe5, + 0x3c, 0xb0, 0x1f, 0xe5, 0x05, 0x90, 0xd9, 0xe7, + 0x00, 0x80, 0xa0, 0xe3, 0x01, 0x70, 0xa0, 0xe3, + 0x09, 0x90, 0xdb, 0xe7, 0xb0, 0xb0, 0x9f, 0xe5, + 0x89, 0x90, 0xa0, 0xe1, 0xf9, 0x90, 0x9b, 0xe1, + 0x09, 0x95, 0xa0, 0xe1, 0x04, 0xb0, 0x49, 0xe0, + 0x0f, 0x40, 0xa0, 0xe3, 0x8e, 0xe0, 0x04, 0xe0, + 0x0b, 0x60, 0x86, 0xe0, 0x06, 0x00, 0x5c, 0xe1, + 0x01, 0xe0, 0x8e, 0xc3, 0x07, 0x80, 0x88, 0xc1, + 0x0f, 0x00, 0x5e, 0xe3, 0x00, 0x00, 0x5e, 0x13, + 0x03, 0x00, 0x00, 0x1a, 0x0a, 0x2b, 0x82, 0xe2, + 0x05, 0x07, 0x52, 0xe3, 0x05, 0x27, 0xa0, 0xc3, + 0x03, 0x00, 0x00, 0xea, 0x02, 0x25, 0x62, 0xe0, + 0x42, 0x25, 0xa0, 0xe1, 0x0a, 0x0b, 0x52, 0xe3, + 0x0a, 0x2b, 0xa0, 0xb3, 0x06, 0x00, 0x5c, 0xe1, + 0x02, 0x40, 0x8c, 0xd0, 0x02, 0x40, 0x4c, 0xc0, + 0x0a, 0x00, 0x54, 0xe1, 0x0a, 0x40, 0xa0, 0xc1, + 0x01, 0x00, 0x00, 0xca, 0xfe, 0x04, 0x54, 0xe3, + 0xfe, 0x44, 0xa0, 0xb3, 0x84, 0xc2, 0x64, 0xe0, + 0xcc, 0xc2, 0xa0, 0xe1, 0x87, 0x70, 0xa0, 0xe1, + 0x80, 0x00, 0x57, 0xe3, 0xe1, 0xff, 0xff, 0xda, + 0x05, 0x80, 0xc1, 0xe7, 0x01, 0x50, 0x85, 0xe2, + 0x09, 0x40, 0xa0, 0xe1, 0x03, 0x00, 0x55, 0xe1, + 0xd1, 0xff, 0xff, 0xba, 0x04, 0x40, 0x80, 0xe9, + 0x0c, 0x40, 0x80, 0xe5, 0x00, 0xc0, 0x80, 0xe5, + 0x10, 0xd0, 0x8d, 0xe2, 0xf0, 0x4f, 0xbd, 0xe8, + 0x1e, 0xff, 0x2f, 0xe1, 0x08, 0x11, 0x01, 0x20, + 0x90, 0xb5, 0x2d, 0x49, 0x49, 0x69, 0x00, 0x29, + 0x17, 0xd0, 0xcf, 0x68, 0xf9, 0x1e, 0x1a, 0x29, + 0x49, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0x0d, 0x45, 0x0d, 0x45, + 0x0d, 0x12, 0x15, 0x45, 0x45, 0x1b, 0x45, 0x45, + 0xed, 0x09, 0x00, 0xde, 0x00, 0x1b, 0x18, 0x18, + 0x45, 0x45, 0x1b, 0x45, 0x45, 0x1b, 0x18, 0x18, + 0x1e, 0x45, 0x42, 0xf8, 0xf7, 0x3f, 0xf8, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x02, 0xf0, 0x1a, + 0xf9, 0xf9, 0xe7, 0x02, 0xf0, 0xb3, 0xfa, 0xf6, + 0xe7, 0xf8, 0xf7, 0x54, 0xff, 0xf3, 0xe7, 0xf8, + 0xf7, 0xe7, 0xfc, 0xf0, 0xe7, 0x18, 0x49, 0x09, + 0x68, 0x05, 0x29, 0x12, 0xd2, 0x01, 0xa3, 0x5b, + 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x0e, 0x02, 0x05, + 0x08, 0x0b, 0x00, 0xf9, 0xf7, 0x19, 0xfc, 0xe2, + 0xe7, 0xfa, 0xf7, 0x9e, 0xfc, 0xdf, 0xe7, 0x00, + 0xf0, 0x39, 0xfd, 0xdc, 0xe7, 0x01, 0xf0, 0x0c, + 0xfa, 0xd9, 0xe7, 0x08, 0x1c, 0x27, 0xf0, 0x02, + 0xf8, 0x04, 0x1c, 0x38, 0x1c, 0x26, 0xf0, 0xd2, + 0xfb, 0x01, 0x1c, 0x0a, 0xa0, 0x22, 0x1c, 0x07, + 0xf0, 0x67, 0xf9, 0xcc, 0xe7, 0xf3, 0xf7, 0x6e, + 0xfc, 0xc9, 0xe7, 0x38, 0x1c, 0x26, 0xf0, 0xc6, + 0xfb, 0x01, 0x1c, 0x13, 0xa0, 0x07, 0xf0, 0x5c, + 0xf9, 0xc1, 0xe7, 0x00, 0x00, 0x88, 0xe5, 0x03, + 0x20, 0x24, 0x7e, 0x03, 0x20, 0x4c, 0x63, 0x49, + 0x72, 0x71, 0x5f, 0x48, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x52, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x49, 0x72, 0x71, 0x3a, 0x20, 0x69, + 0x6e, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x25, 0x73, 0x20, 0x69, 0x6c, 0x6c, 0x65, 0x67, + 0x61, 0x6c, 0x20, 0x53, 0x75, 0x62, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, 0x0a, 0x00, + 0x00, 0x4c, 0x63, 0x49, 0x72, 0x71, 0x5f, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x78, 0x54, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x49, 0x72, + 0x71, 0x3a, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, 0x20, 0x69, + 0x6c, 0x6c, 0x65, 0xed, 0x09, 0x00, 0xdf, 0x00, + 0x67, 0x61, 0x6c, 0x0a, 0x00, 0x00, 0x90, 0xb5, + 0x26, 0x49, 0x49, 0x69, 0xcf, 0x68, 0x10, 0x2f, + 0x1f, 0xd0, 0x08, 0xdc, 0x03, 0x2f, 0x16, 0xd0, + 0x05, 0x2f, 0x11, 0xd0, 0x07, 0x2f, 0x15, 0xd0, + 0x0f, 0x2f, 0x35, 0xd1, 0x15, 0xe0, 0x17, 0x2f, + 0x13, 0xd0, 0x18, 0x2f, 0x11, 0xd0, 0x1a, 0x2f, + 0x12, 0xd0, 0x1c, 0x2f, 0x2c, 0xd1, 0xf3, 0xf7, + 0x10, 0xfc, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x02, 0xf0, 0x95, 0xfd, 0xf9, 0xe7, 0x02, 0xf0, + 0x1a, 0xfd, 0xf6, 0xe7, 0x01, 0xf0, 0xa3, 0xfc, + 0xf3, 0xe7, 0xf8, 0xf7, 0xbe, 0xfe, 0xf0, 0xe7, + 0x13, 0x49, 0x09, 0x68, 0x05, 0x29, 0x0a, 0xd2, + 0x02, 0xa3, 0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, + 0x00, 0x1c, 0x06, 0x06, 0x06, 0x06, 0x03, 0x00, + 0x01, 0xf0, 0x15, 0xfc, 0xe1, 0xe7, 0x08, 0x1c, + 0x26, 0xf0, 0x77, 0xff, 0x04, 0x1c, 0x38, 0x1c, + 0x26, 0xf0, 0x47, 0xfb, 0x01, 0x1c, 0x08, 0xa0, + 0x22, 0x1c, 0x07, 0xf0, 0xdc, 0xf8, 0xd4, 0xe7, + 0x38, 0x1c, 0x26, 0xf0, 0x3e, 0xfb, 0x01, 0x1c, + 0x12, 0xa0, 0x07, 0xf0, 0xd4, 0xf8, 0xcc, 0xe7, + 0x00, 0x00, 0x88, 0xe5, 0x03, 0x20, 0x24, 0x7e, + 0x03, 0x20, 0x4c, 0x63, 0x49, 0x72, 0x71, 0x5f, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x78, + 0x53, 0x79, 0x6e, 0x63, 0x49, 0x72, 0x71, 0x3a, + 0x20, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x20, 0x69, 0x6c, 0x6c, + 0x65, 0x67, 0x61, 0x6c, 0x20, 0x53, 0x75, 0x62, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, + 0x0a, 0x00, 0x4c, 0x63, 0x49, 0x72, 0x71, 0x5f, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x78, + 0x53, 0x79, 0x6e, 0x63, 0x49, 0x72, 0x71, 0x3a, + 0x20, 0x69, 0x6e, 0x20, 0x53, 0x74, 0xed, 0x09, + 0x00, 0xe0, 0x00, 0x61, 0x74, 0x65, 0x20, 0x25, + 0x73, 0x20, 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, + 0x6c, 0x0a, 0x00, 0x90, 0xb5, 0x20, 0x49, 0x49, + 0x69, 0xcf, 0x68, 0x08, 0x2f, 0x0a, 0xd0, 0x09, + 0x2f, 0x0b, 0xd0, 0x1a, 0x2f, 0x0c, 0xd0, 0x1c, + 0x2f, 0x2c, 0xd1, 0xf3, 0xf7, 0x98, 0xfb, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0xf0, 0x97, + 0xfd, 0xf9, 0xe7, 0x02, 0xf0, 0xf7, 0xfa, 0xf6, + 0xe7, 0x16, 0x49, 0x09, 0x68, 0x05, 0x29, 0x10, + 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, 0x00, 0x9f, + 0x44, 0x00, 0x1c, 0x0c, 0x03, 0x06, 0x09, 0x0c, + 0x00, 0xfa, 0xf7, 0x3d, 0xf8, 0xe7, 0xe7, 0xfb, + 0xf7, 0x86, 0xf8, 0xe4, 0xe7, 0x00, 0xf0, 0xd1, + 0xfd, 0xe1, 0xe7, 0x08, 0x1c, 0x26, 0xf0, 0xff, + 0xfe, 0x04, 0x1c, 0x38, 0x1c, 0x26, 0xf0, 0xcf, + 0xfa, 0x01, 0x1c, 0x08, 0xa0, 0x22, 0x1c, 0x07, + 0xf0, 0x64, 0xf8, 0xd4, 0xe7, 0x38, 0x1c, 0x26, + 0xf0, 0xc6, 0xfa, 0x01, 0x1c, 0x12, 0xa0, 0x07, + 0xf0, 0x5c, 0xf8, 0xcc, 0xe7, 0x00, 0x00, 0x88, + 0xe5, 0x03, 0x20, 0x24, 0x7e, 0x03, 0x20, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x78, 0x50, + 0x61, 0x63, 0x6b, 0x65, 0x74, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x3a, 0x20, 0x69, 0x6e, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, + 0x20, 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, + 0x20, 0x53, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x0a, 0x00, 0x00, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x78, 0x50, + 0x61, 0x63, 0x6b, 0x65, 0x74, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x3a, 0x20, 0x69, 0x6e, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, + 0x20, 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, + 0x0a, 0xed, 0x09, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0x90, 0xb5, 0x28, 0x49, 0x49, 0x69, 0xcf, 0x68, + 0x14, 0x2f, 0x1d, 0xd0, 0x08, 0xdc, 0x08, 0x2f, + 0x11, 0xd0, 0x09, 0x2f, 0x12, 0xd0, 0x0c, 0x2f, + 0x16, 0xd0, 0x11, 0x2f, 0x39, 0xd1, 0x10, 0xe0, + 0x19, 0x2f, 0x0e, 0xd0, 0x1a, 0x2f, 0x12, 0xd0, + 0x1c, 0x2f, 0x32, 0xd1, 0xf3, 0xf7, 0x16, 0xfb, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0xf0, + 0x31, 0xfe, 0xf9, 0xe7, 0x02, 0xf0, 0x6e, 0xfa, + 0xf6, 0xe7, 0xf9, 0xf7, 0x19, 0xf9, 0xf3, 0xe7, + 0xf8, 0xf7, 0x68, 0xfd, 0xf0, 0xe7, 0x16, 0x49, + 0x09, 0x68, 0x05, 0x29, 0x10, 0xd2, 0x02, 0xa3, + 0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, + 0x0c, 0x03, 0x06, 0x09, 0x0c, 0x00, 0xfa, 0xf7, + 0x6f, 0xf9, 0xe1, 0xe7, 0xfb, 0xf7, 0x36, 0xfb, + 0xde, 0xe7, 0x00, 0xf0, 0x67, 0xfe, 0xdb, 0xe7, + 0x08, 0x1c, 0x26, 0xf0, 0x77, 0xfe, 0x04, 0x1c, + 0x38, 0x1c, 0x26, 0xf0, 0x47, 0xfa, 0x01, 0x1c, + 0x08, 0xa0, 0x22, 0x1c, 0x06, 0xf0, 0xdc, 0xff, + 0xce, 0xe7, 0x38, 0x1c, 0x26, 0xf0, 0x3e, 0xfa, + 0x01, 0x1c, 0x12, 0xa0, 0x06, 0xf0, 0xd4, 0xff, + 0xc6, 0xe7, 0x00, 0x00, 0x88, 0xe5, 0x03, 0x20, + 0x24, 0x7e, 0x03, 0x20, 0x4c, 0x63, 0x49, 0x72, + 0x71, 0x5f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x52, 0x78, 0x45, 0x6e, 0x64, 0x49, 0x72, 0x71, + 0x3a, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x20, 0x25, 0x73, 0x20, 0x69, 0x6c, + 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, 0x53, 0x75, + 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, + 0x73, 0x0a, 0x00, 0x00, 0x4c, 0x63, 0x49, 0x72, + 0x71, 0x5f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x52, 0x78, 0x45, 0x6e, 0x64, 0x49, 0x72, 0x71, + 0x3a, 0x20, 0x69, 0x6e, 0xed, 0x09, 0x00, 0xe2, + 0x00, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x25, 0x73, 0x20, 0x69, 0x6c, 0x6c, 0x65, 0x67, + 0x61, 0x6c, 0x0a, 0x00, 0x00, 0x90, 0xb5, 0x24, + 0x49, 0x49, 0x69, 0xcf, 0x68, 0x14, 0x2f, 0x06, + 0xd0, 0x0a, 0xdc, 0x08, 0x2f, 0x0f, 0xd0, 0x09, + 0x2f, 0x10, 0xd0, 0x0c, 0x2f, 0x33, 0xd1, 0xf8, + 0xf7, 0x47, 0xfd, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x1a, 0x2f, 0x0a, 0xd0, 0x1c, 0x2f, 0x2a, + 0xd1, 0xf3, 0xf7, 0x8e, 0xfa, 0xf5, 0xe7, 0x01, + 0xf0, 0x9b, 0xfd, 0xf2, 0xe7, 0x02, 0xf0, 0xe9, + 0xf9, 0xef, 0xe7, 0x16, 0x49, 0x09, 0x68, 0x05, + 0x29, 0x10, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x0c, 0x03, 0x06, + 0x09, 0x0c, 0x00, 0xfa, 0xf7, 0x9f, 0xf8, 0xe0, + 0xe7, 0xfb, 0xf7, 0x7a, 0xfa, 0xdd, 0xe7, 0x00, + 0xf0, 0xbd, 0xfd, 0xda, 0xe7, 0x08, 0x1c, 0x26, + 0xf0, 0xf7, 0xfd, 0x04, 0x1c, 0x38, 0x1c, 0x26, + 0xf0, 0xc7, 0xf9, 0x01, 0x1c, 0x08, 0xa0, 0x22, + 0x1c, 0x06, 0xf0, 0x5c, 0xff, 0xcd, 0xe7, 0x38, + 0x1c, 0x26, 0xf0, 0xbe, 0xf9, 0x01, 0x1c, 0x13, + 0xa0, 0x06, 0xf0, 0x54, 0xff, 0xc5, 0xe7, 0x00, + 0x00, 0x88, 0xe5, 0x03, 0x20, 0x24, 0x7e, 0x03, + 0x20, 0x4c, 0x63, 0x49, 0x72, 0x71, 0x5f, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x78, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x49, 0x72, 0x71, 0x3a, + 0x20, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x20, 0x69, 0x6c, 0x6c, + 0x65, 0x67, 0x61, 0x6c, 0x20, 0x53, 0x75, 0x62, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x63, 0x49, + 0x72, 0x71, 0x5f, 0x48, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x52, 0x78, 0x45, 0x72, 0x72, 0x6f, 0xed, + 0x09, 0x00, 0xe3, 0x00, 0x72, 0x49, 0x72, 0x71, + 0x3a, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x20, 0x25, 0x73, 0x20, 0x69, 0x6c, + 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x90, 0xb5, 0x26, 0x49, 0x49, 0x69, + 0xcf, 0x68, 0x14, 0x2f, 0x1f, 0xd0, 0x10, 0xdc, + 0x09, 0x2f, 0x19, 0xd0, 0x08, 0xdc, 0x03, 0x2f, + 0x01, 0xd0, 0x05, 0x2f, 0x36, 0xd1, 0xf7, 0xf7, + 0x08, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x0c, 0x2f, 0x10, 0xd0, 0x0f, 0x2f, 0x2d, 0xd1, + 0x0d, 0xe0, 0x17, 0x2f, 0x0b, 0xd0, 0x1a, 0x2f, + 0x0c, 0xd0, 0x1b, 0x2f, 0x0a, 0xd0, 0x1c, 0x2f, + 0x24, 0xd1, 0xf3, 0xf7, 0x46, 0xfd, 0xec, 0xe7, + 0x02, 0xf0, 0xe1, 0xfa, 0xe9, 0xe7, 0xf8, 0xf7, + 0x76, 0xf8, 0xe6, 0xe7, 0x13, 0x49, 0x09, 0x68, + 0x05, 0x29, 0x0a, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, + 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x06, 0x06, + 0x06, 0x03, 0x06, 0x00, 0x00, 0xf0, 0x27, 0xfc, + 0xd7, 0xe7, 0x08, 0x1c, 0x26, 0xf0, 0x6f, 0xfd, + 0x04, 0x1c, 0x38, 0x1c, 0x26, 0xf0, 0x3f, 0xf9, + 0x01, 0x1c, 0x08, 0xa0, 0x22, 0x1c, 0x06, 0xf0, + 0xd4, 0xfe, 0xca, 0xe7, 0x38, 0x1c, 0x26, 0xf0, + 0x36, 0xf9, 0x01, 0x1c, 0x12, 0xa0, 0x06, 0xf0, + 0xcc, 0xfe, 0xc2, 0xe7, 0x00, 0x00, 0x88, 0xe5, + 0x03, 0x20, 0x24, 0x7e, 0x03, 0x20, 0x4c, 0x63, + 0x49, 0x72, 0x71, 0x5f, 0x48, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x54, 0x78, 0x45, 0x6e, 0x64, 0x49, + 0x72, 0x71, 0x3a, 0x20, 0x69, 0x6e, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, 0x20, + 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, + 0x53, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x20, 0x25, 0x73, 0x0a, 0x00, 0x00, 0x4c, 0x63, + 0x49, 0x72, 0xed, 0x09, 0x00, 0xe4, 0x00, 0x71, + 0x5f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x54, + 0x78, 0x45, 0x6e, 0x64, 0x49, 0x72, 0x71, 0x3a, + 0x20, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x20, 0x69, 0x6c, 0x6c, + 0x65, 0x67, 0x61, 0x6c, 0x0a, 0x00, 0x00, 0x80, + 0xb5, 0x13, 0x49, 0x4f, 0x69, 0xf9, 0x68, 0x1e, + 0x29, 0x17, 0xd2, 0x01, 0xa3, 0x5b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x13, 0x13, 0x13, 0x0e, 0x13, + 0x0e, 0x13, 0x0e, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0xf7, 0xf7, 0x25, 0xfe, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x08, 0x1c, 0x26, 0xf0, 0xd9, + 0xf8, 0x01, 0x1c, 0x03, 0xa0, 0x3a, 0x68, 0x06, + 0xf0, 0x6e, 0xfe, 0xf3, 0xe7, 0x00, 0x00, 0x88, + 0xe5, 0x03, 0x20, 0x48, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x52, + 0x65, 0x61, 0x64, 0x49, 0x72, 0x71, 0x3a, 0x20, + 0x75, 0x6e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x25, 0x73, 0x20, 0x50, 0x69, 0x63, 0x6f, 0x6e, + 0x65, 0x74, 0x20, 0x25, 0x75, 0x0a, 0x00, 0xf0, + 0xb5, 0x87, 0xb0, 0x07, 0x1c, 0x54, 0x48, 0x54, + 0x4b, 0x01, 0x68, 0x02, 0x31, 0x01, 0x60, 0x41, + 0x68, 0xc9, 0x18, 0x41, 0x60, 0x78, 0x68, 0x01, + 0x21, 0xf5, 0xf7, 0xa5, 0xff, 0xfe, 0x1d, 0xb9, + 0x36, 0x04, 0x90, 0x11, 0xce, 0xf9, 0x1d, 0x79, + 0x31, 0xe0, 0x65, 0x06, 0x91, 0xc8, 0x6b, 0x08, + 0x3e, 0x20, 0x64, 0xf8, 0x6c, 0xe0, 0x64, 0x38, + 0x6d, 0x20, 0x65, 0x00, 0x20, 0x60, 0x65, 0xa0, + 0x65, 0x20, 0x66, 0xa0, 0x66, 0x60, 0x67, 0xa0, + 0x67, 0xf9, 0x6f, 0xbc, 0x42, 0xed, 0x09, 0x00, + 0xe5, 0x00, 0xe1, 0x67, 0x00, 0xd0, 0xf8, 0x67, + 0xe1, 0x1d, 0x79, 0x31, 0x05, 0x91, 0x00, 0x20, + 0x48, 0x60, 0xc8, 0x60, 0x60, 0x64, 0xb0, 0x6b, + 0xe5, 0x1d, 0xb9, 0x35, 0xa8, 0x63, 0xf9, 0x1d, + 0xe1, 0x31, 0x0c, 0xc9, 0xe0, 0x1d, 0xe1, 0x30, + 0x0c, 0xc0, 0x0c, 0xc9, 0x0c, 0xc0, 0xa8, 0x6b, + 0x00, 0x28, 0x02, 0xd0, 0x20, 0x1c, 0xfa, 0xf7, + 0xdb, 0xf8, 0xb0, 0x68, 0xa8, 0x60, 0xf0, 0x68, + 0xe8, 0x60, 0x30, 0x69, 0x28, 0x61, 0x70, 0x69, + 0x68, 0x61, 0xb0, 0x69, 0xa8, 0x61, 0x30, 0x6a, + 0x28, 0x62, 0x01, 0x20, 0xa0, 0x64, 0x06, 0x99, + 0x00, 0x20, 0x48, 0x61, 0xf8, 0x60, 0x2d, 0x49, + 0x65, 0x68, 0x08, 0x1c, 0x0c, 0xc9, 0xee, 0x1d, + 0x51, 0x36, 0x0c, 0xc6, 0x48, 0xc8, 0xe9, 0x1d, + 0x35, 0x31, 0x48, 0xc1, 0x02, 0x20, 0x28, 0x61, + 0x1a, 0x20, 0xe8, 0x60, 0x05, 0x20, 0xe0, 0x60, + 0x05, 0x99, 0x00, 0x20, 0x48, 0x61, 0x05, 0x99, + 0x88, 0x61, 0x20, 0x1c, 0xfe, 0xf7, 0x49, 0xfc, + 0xf2, 0xf7, 0xd1, 0xfb, 0x00, 0x28, 0x0f, 0xd0, + 0x41, 0x21, 0x01, 0x60, 0x61, 0x68, 0x49, 0x68, + 0x01, 0x61, 0x21, 0x7e, 0xc1, 0x60, 0x61, 0x68, + 0x81, 0x61, 0x44, 0x61, 0x08, 0x21, 0xc1, 0x61, + 0x01, 0x1c, 0x0e, 0x20, 0xf2, 0xf7, 0x2e, 0xfc, + 0x04, 0x98, 0x01, 0x28, 0x0d, 0xd9, 0x02, 0x21, + 0x38, 0x1c, 0xf4, 0xf7, 0x49, 0xf9, 0x02, 0x23, + 0x1a, 0x22, 0x28, 0x1c, 0x21, 0x1c, 0xf4, 0xf7, + 0x51, 0xf8, 0x07, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x78, 0x68, 0xa8, 0x42, 0x05, 0xd0, + 0x02, 0x23, 0x1a, 0x22, 0x28, 0x1c, 0x21, 0x1c, + 0xf4, 0xf7, 0x44, 0xf8, 0x01, 0x22, 0x03, 0x92, + 0x01, 0x21, 0x02, 0x91, 0x02, 0x22, 0x1a, 0x20, + 0x00, 0x92, 0x01, 0x90, 0x29, 0x1c, 0x02, 0x23, + 0xed, 0x09, 0x00, 0xe6, 0x00, 0x22, 0x1c, 0x78, + 0x68, 0xf4, 0xf7, 0x66, 0xf9, 0xe3, 0xe7, 0x00, + 0x00, 0x68, 0x14, 0x04, 0x20, 0xe2, 0x04, 0x00, + 0x00, 0x88, 0xe6, 0x03, 0x20, 0xf0, 0xb5, 0x88, + 0xb0, 0x07, 0x1c, 0x72, 0x48, 0xf9, 0x1d, 0x06, + 0x68, 0xf8, 0x1d, 0x79, 0x30, 0x07, 0x90, 0x80, + 0x69, 0x99, 0x31, 0x40, 0x68, 0x09, 0x7b, 0xff, + 0x23, 0x35, 0x33, 0x59, 0x43, 0x40, 0x18, 0xc4, + 0x1d, 0xff, 0x34, 0x92, 0x34, 0xe1, 0x1d, 0xb9, + 0x31, 0x06, 0x91, 0x4f, 0x60, 0xf8, 0x6d, 0x08, + 0x60, 0xe1, 0x1d, 0x79, 0x31, 0x38, 0x6c, 0x05, + 0x91, 0xc8, 0x63, 0x01, 0x20, 0xf8, 0x60, 0x65, + 0x68, 0x07, 0x98, 0x00, 0x21, 0x41, 0x61, 0xf9, + 0x1d, 0x9d, 0x31, 0x0c, 0xc9, 0xe0, 0x1d, 0x09, + 0x30, 0x0c, 0xc0, 0xf8, 0x6c, 0x00, 0x21, 0xe0, + 0x64, 0x38, 0x6d, 0x20, 0x65, 0x54, 0x34, 0x00, + 0x20, 0x03, 0xc4, 0x03, 0xc4, 0x64, 0x3c, 0xa0, + 0x66, 0x60, 0x67, 0xa0, 0x67, 0xf8, 0x6f, 0xbc, + 0x42, 0xe0, 0x67, 0x01, 0xd0, 0x00, 0x20, 0xf8, + 0x67, 0x05, 0x99, 0x00, 0x20, 0x48, 0x60, 0x05, + 0x99, 0xc8, 0x60, 0x20, 0x64, 0x60, 0x64, 0xf8, + 0x1d, 0xb9, 0x30, 0x04, 0x90, 0x80, 0x6b, 0x06, + 0x99, 0x88, 0x63, 0xf9, 0x1d, 0xe1, 0x31, 0x0c, + 0xc9, 0xe0, 0x1d, 0xe1, 0x30, 0x0c, 0xc0, 0x0c, + 0xc9, 0x0c, 0xc0, 0x06, 0x99, 0x88, 0x6b, 0x00, + 0x28, 0x02, 0xd0, 0x20, 0x1c, 0xfa, 0xf7, 0x12, + 0xf8, 0x07, 0x98, 0x01, 0x6a, 0x30, 0x1c, 0x02, + 0xf0, 0xcf, 0xfc, 0xee, 0x1d, 0x25, 0x36, 0x44, + 0x4a, 0xf2, 0xf7, 0xde, 0xf8, 0x03, 0xc6, 0x07, + 0x98, 0x42, 0x49, 0xc0, 0x69, 0x08, 0x3e, 0x0a, + 0x1a, 0x07, 0x98, 0xc2, 0x61, 0x03, 0xce, 0x08, + 0x3e, 0x02, 0xf0, 0xf2, 0xfb, 0x03, 0xc6, 0x08, + 0x3e, 0x02, 0xf0, 0xed, 0x09, 0x00, 0xe7, 0x00, + 0xc2, 0xfc, 0x3c, 0xa3, 0x1a, 0x68, 0x5b, 0x68, + 0x02, 0xf0, 0xc5, 0xfc, 0xe9, 0x1d, 0xff, 0x31, + 0x7a, 0x31, 0x08, 0x60, 0x07, 0x98, 0x39, 0xa1, + 0x00, 0x6a, 0x28, 0x62, 0x07, 0x98, 0x00, 0x6a, + 0x68, 0x61, 0x0c, 0xc9, 0xe8, 0x1d, 0x11, 0x30, + 0x0c, 0xc0, 0x0c, 0xce, 0xe8, 0x1d, 0x1d, 0x30, + 0x0c, 0xc0, 0x00, 0x20, 0xf9, 0x1d, 0xad, 0x31, + 0x68, 0x63, 0x08, 0x1c, 0x0c, 0xc9, 0xee, 0x1d, + 0x51, 0x36, 0x0c, 0xc6, 0xe9, 0x1d, 0x60, 0xc8, + 0x35, 0x31, 0x60, 0xc1, 0x05, 0x20, 0xe0, 0x60, + 0x61, 0x68, 0x02, 0x20, 0x08, 0x61, 0x61, 0x68, + 0x1a, 0x20, 0xc8, 0x60, 0x05, 0x99, 0x04, 0x20, + 0x48, 0x61, 0x07, 0x98, 0xfd, 0x1d, 0x00, 0x6b, + 0x05, 0x99, 0xf5, 0x35, 0x08, 0x63, 0x04, 0x98, + 0x80, 0x68, 0x06, 0x99, 0x88, 0x60, 0x04, 0x98, + 0xc0, 0x68, 0x06, 0x99, 0xc8, 0x60, 0x04, 0x98, + 0x00, 0x69, 0x06, 0x99, 0x08, 0x61, 0x04, 0x98, + 0x40, 0x69, 0x06, 0x99, 0x48, 0x61, 0x04, 0x98, + 0x80, 0x69, 0x06, 0x99, 0x88, 0x61, 0x04, 0x98, + 0x00, 0x6a, 0x06, 0x99, 0x08, 0x62, 0x4e, 0xcd, + 0xe0, 0x1d, 0xf5, 0x30, 0x4e, 0xc0, 0x48, 0xcd, + 0x48, 0xc0, 0xe1, 0x1d, 0xf9, 0x31, 0x00, 0x20, + 0x08, 0x60, 0x20, 0x1c, 0xfe, 0xf7, 0x36, 0xfb, + 0x78, 0x68, 0xf5, 0xf7, 0x45, 0xfe, 0x01, 0x28, + 0x01, 0xd1, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, + 0x00, 0x22, 0x03, 0x92, 0x02, 0x22, 0x1a, 0x20, + 0x00, 0x92, 0x01, 0x90, 0x02, 0x91, 0x61, 0x68, + 0x02, 0x23, 0x22, 0x1c, 0x78, 0x68, 0xf4, 0xf7, + 0x7a, 0xf8, 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x68, 0x14, 0x04, 0x20, 0x71, 0x02, + 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x71, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb5, 0x0b, 0x48, 0x0b, + 0x4b, 0x02, 0x68, 0x41, 0x69, 0x02, 0x32, 0x02, + 0x60, 0x42, 0x68, 0xd2, 0x18, 0x42, 0x60, 0x20, + 0x20, 0x80, 0x31, 0x08, 0x63, 0x07, 0x4a, 0x03, + 0x20, 0x10, 0x60, 0x02, 0x20, 0x48, 0x61, 0x58, + 0x07, 0x00, 0xf0, 0x55, 0xf8, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x68, 0x14, 0x04, 0x20, 0xe2, + 0x04, 0x00, 0x00, 0x24, 0x7e, 0x03, 0x20, 0xb0, + 0xb5, 0x21, 0x4f, 0x21, 0x4b, 0x38, 0x68, 0x7c, + 0x69, 0x06, 0x30, 0x38, 0x60, 0x78, 0x68, 0xc0, + 0x18, 0x78, 0x60, 0x1e, 0x48, 0x81, 0x68, 0x01, + 0x23, 0x9b, 0x02, 0x99, 0x43, 0x81, 0x60, 0xf2, + 0xf7, 0x69, 0xfa, 0x00, 0x28, 0x13, 0xd0, 0x41, + 0x21, 0x01, 0x60, 0x79, 0x69, 0x49, 0x68, 0x81, + 0x61, 0x79, 0x69, 0x41, 0x61, 0x79, 0x69, 0x49, + 0x68, 0x49, 0x68, 0x01, 0x61, 0x79, 0x69, 0x09, + 0x7e, 0xc1, 0x60, 0x08, 0x21, 0xc1, 0x61, 0x01, + 0x1c, 0x0e, 0x20, 0xf2, 0xf7, 0xc2, 0xfa, 0xe7, + 0x1d, 0x79, 0x37, 0x00, 0x25, 0x7d, 0x61, 0xb8, + 0x69, 0x00, 0x28, 0x08, 0xd0, 0x61, 0x68, 0x40, + 0x68, 0x81, 0x42, 0x04, 0xd0, 0x01, 0x23, 0x01, + 0x22, 0x00, 0x21, 0xf4, 0xf7, 0x0a, 0xf9, 0x08, + 0x49, 0x01, 0x20, 0xbd, 0x61, 0x08, 0x60, 0x01, + 0x20, 0x80, 0x07, 0xf8, 0xf7, 0xe6, 0xfe, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, + 0x14, 0x04, 0x20, 0xa6, 0x0e, 0x00, 0x00, 0x00, + 0x50, 0x00, 0xe0, 0x24, 0x7e, 0x03, 0x20, 0xf0, + 0xb5, 0x87, 0xb0, 0x05, 0x1c, 0xaf, 0x48, 0xaf, + 0x4b, 0x01, 0x68, 0x04, 0x31, 0x05, 0x91, 0x41, + 0x68, 0x44, 0x69, 0xcf, 0x18, 0x00, 0x2d, 0x0e, + 0xd0, 0x60, 0x6e, 0x00, 0x28, 0x03, 0xd0, 0x01, + 0x21, 0xed, 0x09, 0x00, 0xe9, 0x00, 0x20, 0x1c, + 0xfe, 0xf7, 0xca, 0xfa, 0x68, 0x08, 0x05, 0xd3, + 0xff, 0xf7, 0x9c, 0xff, 0x07, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xe0, 0x1d, 0x79, 0x30, + 0x01, 0x6b, 0x01, 0x39, 0x01, 0x63, 0x02, 0xd1, + 0xff, 0xf7, 0x90, 0xff, 0xf2, 0xe7, 0xa0, 0x49, + 0xff, 0x22, 0x38, 0x1c, 0x09, 0x69, 0xb9, 0x32, + 0xf6, 0xf7, 0x24, 0xfa, 0x00, 0x28, 0x04, 0xd1, + 0x9c, 0x4b, 0x05, 0x98, 0xff, 0x18, 0x04, 0x30, + 0x05, 0x90, 0x60, 0x68, 0xc1, 0x1d, 0x79, 0x31, + 0xca, 0x69, 0xff, 0x30, 0x81, 0x30, 0xa1, 0x6a, + 0x83, 0x68, 0x03, 0x92, 0x18, 0x0e, 0x1a, 0x02, + 0x12, 0x0a, 0x00, 0x92, 0x00, 0x22, 0x1a, 0x23, + 0x01, 0x90, 0x02, 0x91, 0x00, 0x21, 0x05, 0x98, + 0xf6, 0xf7, 0x14, 0xfc, 0x04, 0x90, 0x60, 0x68, + 0xff, 0x30, 0x81, 0x30, 0x80, 0x68, 0x05, 0x99, + 0x00, 0x0e, 0x49, 0x08, 0x06, 0x91, 0x09, 0x02, + 0x08, 0x43, 0x8b, 0x49, 0x48, 0x60, 0xe6, 0x1d, + 0xb9, 0x36, 0xb2, 0x68, 0x89, 0x4d, 0x03, 0x92, + 0x69, 0x69, 0x38, 0x1c, 0x01, 0x29, 0x73, 0xd0, + 0x02, 0x29, 0x22, 0xd1, 0x09, 0x21, 0x02, 0xf0, + 0x85, 0xfa, 0xc8, 0x22, 0x02, 0xf0, 0x8c, 0xfa, + 0x34, 0x22, 0x02, 0xf0, 0x89, 0xfa, 0x50, 0x22, + 0x02, 0xf0, 0x86, 0xfa, 0x0d, 0x22, 0x02, 0xf0, + 0x83, 0xfa, 0x04, 0x22, 0x02, 0xf0, 0x80, 0xfa, + 0x28, 0x22, 0x02, 0xf0, 0x7d, 0xfa, 0x04, 0x99, + 0x02, 0x31, 0x09, 0x02, 0x10, 0x22, 0x0a, 0x43, + 0x79, 0x49, 0x0a, 0x62, 0x03, 0x9a, 0x42, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, 0x43, + 0x4a, 0x62, 0x76, 0x4a, 0x76, 0x49, 0x0a, 0x62, + 0x08, 0x60, 0xb1, 0x68, 0x6a, 0x69, 0x75, 0x48, + 0x01, 0x2a, 0x65, 0xd0, 0x02, 0x2a, 0x05, 0xd1, + 0x40, 0x23, 0x19, 0x43, 0xed, 0x09, 0x00, 0xea, + 0x00, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x01, + 0x62, 0xf9, 0x1d, 0x49, 0x31, 0xff, 0x22, 0x6f, + 0x48, 0x02, 0x32, 0x02, 0x62, 0x01, 0x60, 0x6e, + 0x4a, 0xb1, 0x68, 0x10, 0x6a, 0x52, 0x6a, 0x00, + 0x0a, 0xff, 0x23, 0x1b, 0x02, 0x1a, 0x40, 0x10, + 0x43, 0x6a, 0x69, 0x01, 0x2a, 0x6d, 0xd0, 0x02, + 0x2a, 0x07, 0xd1, 0xd2, 0x03, 0x01, 0x0c, 0x00, + 0xd2, 0x00, 0x22, 0x10, 0x43, 0x01, 0x23, 0xdb, + 0x03, 0x98, 0x43, 0x30, 0x62, 0x69, 0x69, 0x38, + 0x1c, 0x01, 0x29, 0x5f, 0xd0, 0x02, 0x29, 0x05, + 0xd1, 0x5f, 0x49, 0x2d, 0x22, 0x0a, 0x62, 0x2c, + 0x22, 0x4a, 0x62, 0x3c, 0x38, 0x5d, 0x4a, 0x5e, + 0x49, 0x0a, 0x62, 0x08, 0x60, 0x5d, 0x4a, 0xb1, + 0x68, 0x10, 0x6a, 0x52, 0x6a, 0x00, 0x0a, 0xff, + 0x23, 0x1b, 0x02, 0x1a, 0x40, 0x10, 0x43, 0x6a, + 0x69, 0x01, 0x2a, 0x5d, 0xd0, 0x02, 0x2a, 0x09, + 0xd1, 0xd2, 0x03, 0x00, 0xe0, 0x1f, 0xe0, 0x01, + 0x0c, 0x00, 0xd2, 0x00, 0x22, 0x10, 0x43, 0x01, + 0x23, 0xdb, 0x03, 0x98, 0x43, 0xf0, 0x61, 0x68, + 0x69, 0x01, 0x28, 0x54, 0xd0, 0x02, 0x28, 0x04, + 0xd1, 0x4e, 0x48, 0x2d, 0x22, 0x02, 0x62, 0x2c, + 0x22, 0x42, 0x62, 0x4a, 0x4a, 0x4c, 0x49, 0xf8, + 0x1d, 0x21, 0x30, 0x0a, 0x62, 0x08, 0x60, 0xb6, + 0x6b, 0xe1, 0x6a, 0x38, 0x1c, 0x00, 0x29, 0x48, + 0xd0, 0x05, 0x24, 0x47, 0xe0, 0x23, 0xe0, 0x10, + 0x21, 0x02, 0xf0, 0xf2, 0xf9, 0xff, 0x22, 0x05, + 0x32, 0x02, 0xf0, 0xf8, 0xf9, 0x46, 0x22, 0x02, + 0xf0, 0xf5, 0xf9, 0x0d, 0x22, 0x02, 0xf0, 0xf2, + 0xf9, 0x04, 0x22, 0x02, 0xf0, 0xef, 0xf9, 0x28, + 0x22, 0x02, 0xf0, 0xec, 0xf9, 0x04, 0x99, 0x02, + 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x31, + 0x49, 0x0a, 0x62, 0x03, 0x9a, 0x82, 0x23, 0xed, + 0x09, 0x00, 0xeb, 0x00, 0x1a, 0x43, 0x12, 0x02, + 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x6d, 0xe7, + 0x07, 0xe0, 0x0d, 0xe0, 0x80, 0x23, 0x19, 0x43, + 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, 0x62, + 0x75, 0xe7, 0x01, 0x22, 0x12, 0x04, 0x00, 0x29, + 0x00, 0xd1, 0x00, 0x22, 0x10, 0x43, 0x8b, 0xe7, + 0x29, 0x49, 0x3d, 0x22, 0x0a, 0x62, 0x3e, 0x22, + 0x4a, 0x62, 0x46, 0x38, 0x91, 0xe7, 0x01, 0x22, + 0x12, 0x04, 0x00, 0x29, 0x00, 0xd1, 0x00, 0x22, + 0x10, 0x43, 0xa6, 0xe7, 0x25, 0x48, 0x3d, 0x22, + 0x02, 0x62, 0x3e, 0x22, 0x42, 0x62, 0xab, 0xe7, + 0x01, 0x24, 0x69, 0x69, 0x01, 0x29, 0x1b, 0xd0, + 0x02, 0x29, 0x02, 0xd1, 0x09, 0x21, 0x02, 0xf0, + 0xa6, 0xf9, 0xc2, 0x1f, 0x13, 0x49, 0x21, 0x3a, + 0x8a, 0x60, 0xb0, 0x30, 0xc8, 0x60, 0x01, 0x2e, + 0x01, 0xd0, 0x03, 0x2e, 0x04, 0xd1, 0x06, 0x98, + 0x1a, 0x4a, 0x08, 0x23, 0x1c, 0x43, 0x10, 0x60, + 0x32, 0x20, 0x0c, 0x60, 0x02, 0xf0, 0x35, 0xff, + 0x05, 0x98, 0x05, 0x49, 0x81, 0xc1, 0xbe, 0xe6, + 0x10, 0x21, 0x02, 0xf0, 0x8c, 0xf9, 0x02, 0xaa, + 0x03, 0xc2, 0x02, 0x98, 0x03, 0x99, 0xe0, 0xe7, + 0x00, 0x00, 0x68, 0x14, 0x04, 0x20, 0xc4, 0x09, + 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, 0x88, 0x13, + 0x00, 0x00, 0x00, 0x51, 0x00, 0xe0, 0x48, 0xe6, + 0x03, 0x20, 0xa0, 0x55, 0x00, 0xe0, 0x02, 0x05, + 0x00, 0x00, 0x08, 0x53, 0x00, 0xe0, 0xb0, 0x55, + 0x00, 0xe0, 0x0c, 0x53, 0x00, 0xe0, 0xd0, 0x55, + 0x00, 0xe0, 0x02, 0x03, 0x00, 0x00, 0x14, 0x53, + 0x00, 0xe0, 0xc0, 0x55, 0x00, 0xe0, 0x10, 0x53, + 0x00, 0xe0, 0x80, 0x55, 0x00, 0xe0, 0x00, 0xb5, + 0x0a, 0x48, 0x01, 0x22, 0x41, 0x69, 0x09, 0x48, + 0x92, 0x02, 0xc2, 0x60, 0x82, 0x68, 0x01, 0x23, + 0x9b, 0x02, 0xed, 0x09, 0x00, 0xec, 0x00, 0x9a, + 0x43, 0x82, 0x60, 0xca, 0x1d, 0x79, 0x32, 0x04, + 0x20, 0x50, 0x61, 0x08, 0x1c, 0xff, 0xf7, 0x09, + 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, + 0x14, 0x04, 0x20, 0x00, 0x50, 0x00, 0xe0, 0xf0, + 0xb5, 0x89, 0xb0, 0x6d, 0x48, 0x6e, 0x4b, 0x01, + 0x68, 0x44, 0x69, 0x0a, 0x1d, 0x41, 0x68, 0x6c, + 0x48, 0xc9, 0x18, 0x5b, 0x08, 0xcf, 0x1a, 0x80, + 0x6a, 0x95, 0x1e, 0x41, 0x07, 0x49, 0x0f, 0x04, + 0xab, 0x19, 0x70, 0x41, 0x06, 0x09, 0x0f, 0x05, + 0x91, 0x01, 0x06, 0xc9, 0x0f, 0x59, 0x70, 0xc1, + 0x05, 0xc9, 0x0f, 0x80, 0x05, 0xc0, 0x0f, 0x99, + 0x70, 0xd8, 0x70, 0x05, 0x98, 0x02, 0x28, 0x06, + 0xd0, 0x00, 0x20, 0xff, 0xf7, 0x3e, 0xfe, 0x09, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0x68, 0xc1, 0x1d, 0x79, 0x31, 0xca, 0x69, 0xff, + 0x30, 0x81, 0x30, 0xa1, 0x6a, 0x83, 0x68, 0x03, + 0x92, 0x18, 0x0e, 0x1a, 0x02, 0x12, 0x0a, 0x00, + 0x92, 0x02, 0x91, 0x00, 0x21, 0x00, 0x22, 0x1a, + 0x23, 0x01, 0x90, 0x28, 0x1c, 0xf6, 0xf7, 0x81, + 0xfa, 0x06, 0x90, 0xe0, 0x1d, 0xb9, 0x30, 0x08, + 0x90, 0x41, 0x69, 0x05, 0x69, 0xc6, 0x68, 0x4f, + 0x48, 0x03, 0x91, 0x07, 0x90, 0x40, 0x69, 0x01, + 0x28, 0x5e, 0xd0, 0x02, 0x28, 0x2a, 0xd1, 0x4c, + 0x49, 0x03, 0x20, 0xc8, 0x62, 0x06, 0x21, 0x38, + 0x1c, 0x02, 0xf0, 0x09, 0xf9, 0xc8, 0x22, 0x02, + 0xf0, 0xfe, 0xf8, 0x6a, 0x00, 0x02, 0xf0, 0xfb, + 0xf8, 0x28, 0x22, 0x02, 0xf0, 0xf8, 0xf8, 0x03, + 0x22, 0x02, 0xf0, 0x05, 0xf9, 0x06, 0x99, 0x42, + 0x4a, 0x02, 0x31, 0x09, 0x02, 0x10, 0x23, 0x19, + 0x43, 0x11, 0x62, 0xf1, 0x00, 0x44, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x51, + 0x62, 0x03, 0x99, 0x09, 0x02, 0xed, 0x09, 0x00, + 0xed, 0x00, 0x16, 0x23, 0x19, 0x43, 0x91, 0x62, + 0x3a, 0x49, 0x08, 0x60, 0x05, 0x20, 0x00, 0x02, + 0x08, 0x62, 0x08, 0x98, 0xc1, 0x68, 0x07, 0x98, + 0x42, 0x69, 0x37, 0x48, 0x01, 0x2a, 0x53, 0xd0, + 0x02, 0x2a, 0x06, 0xd1, 0xc9, 0x00, 0x40, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, + 0x01, 0x62, 0xf8, 0x1d, 0x5d, 0x30, 0xff, 0x22, + 0x30, 0x49, 0x02, 0x32, 0x0a, 0x62, 0x08, 0x60, + 0xe0, 0x1d, 0x79, 0x30, 0x03, 0x25, 0x45, 0x61, + 0x07, 0x99, 0x38, 0x1c, 0x49, 0x69, 0x01, 0x29, + 0x42, 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x06, 0x21, + 0x02, 0xf0, 0xc0, 0xf8, 0x28, 0x49, 0x88, 0x60, + 0x0d, 0x60, 0x01, 0x21, 0x27, 0x48, 0x89, 0x02, + 0xc1, 0x60, 0x81, 0x68, 0x01, 0x23, 0x9b, 0x02, + 0x19, 0x43, 0x81, 0x60, 0x7a, 0xe7, 0x06, 0x21, + 0x38, 0x1c, 0x02, 0xf0, 0xaf, 0xf8, 0xff, 0x22, + 0x05, 0x32, 0x02, 0xf0, 0xa3, 0xf8, 0x6a, 0x00, + 0x02, 0xf0, 0xa0, 0xf8, 0x28, 0x22, 0x02, 0xf0, + 0x9d, 0xf8, 0x03, 0x22, 0x02, 0xf0, 0xaa, 0xf8, + 0x06, 0x99, 0x02, 0x31, 0x09, 0x02, 0x20, 0x22, + 0x0a, 0x43, 0x13, 0x49, 0x0a, 0x62, 0xf2, 0x00, + 0x84, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, 0x23, + 0x1a, 0x43, 0x4a, 0x62, 0x03, 0x9a, 0x12, 0x02, + 0x19, 0x23, 0x1a, 0x43, 0x8a, 0x62, 0x0d, 0x49, + 0x08, 0x60, 0x11, 0x48, 0x08, 0x62, 0xa4, 0xe7, + 0xc9, 0x00, 0x80, 0x23, 0x19, 0x43, 0x09, 0x02, + 0x10, 0x23, 0x19, 0x43, 0x01, 0x62, 0xac, 0xe7, + 0x06, 0x21, 0x02, 0xf0, 0x7f, 0xf8, 0xbd, 0xe7, + 0x68, 0x14, 0x04, 0x20, 0xc4, 0x09, 0x00, 0x00, + 0x40, 0x55, 0x00, 0xe0, 0x48, 0xe6, 0x03, 0x20, + 0x80, 0x55, 0x00, 0xe0, 0x00, 0x53, 0x00, 0xe0, + 0x90, 0x55, 0x00, 0xe0, 0x04, 0x53, 0x00, 0xe0, + 0xed, 0x09, 0x00, 0xee, 0x00, 0x00, 0x52, 0x00, + 0xe0, 0x00, 0x50, 0x00, 0xe0, 0x03, 0x05, 0x00, + 0x00, 0x00, 0xb5, 0x82, 0xb0, 0x10, 0x48, 0x80, + 0x6a, 0x41, 0x07, 0x49, 0x0f, 0x00, 0xab, 0x19, + 0x70, 0x41, 0x06, 0x09, 0x0f, 0x01, 0x91, 0x01, + 0x06, 0xc9, 0x0f, 0x59, 0x70, 0xc1, 0x05, 0xc9, + 0x0f, 0x80, 0x05, 0xc0, 0x0f, 0x99, 0x70, 0xd8, + 0x70, 0x01, 0x98, 0x02, 0x28, 0x02, 0xd0, 0x02, + 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x05, 0x49, 0x00, + 0x20, 0x08, 0x62, 0x48, 0x62, 0x04, 0x49, 0x08, + 0x60, 0xff, 0xf7, 0x4c, 0xfd, 0xf3, 0xe7, 0x00, + 0x00, 0x40, 0x55, 0x00, 0xe0, 0x00, 0x53, 0x00, + 0xe0, 0x00, 0x52, 0x00, 0xe0, 0xf0, 0xb5, 0x82, + 0xb0, 0x30, 0x49, 0x4d, 0x69, 0x0e, 0x69, 0x30, + 0x49, 0x89, 0x6a, 0x4a, 0x07, 0x52, 0x0f, 0x00, + 0xab, 0x1a, 0x70, 0x4a, 0x06, 0x12, 0x0f, 0x01, + 0x92, 0x0a, 0x06, 0xd2, 0x0f, 0x5a, 0x70, 0xca, + 0x05, 0xd2, 0x0f, 0x89, 0x05, 0xc9, 0x0f, 0x9a, + 0x70, 0xd9, 0x70, 0x01, 0x99, 0x02, 0x29, 0x03, + 0xd0, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x21, 0xf5, 0xf7, 0xdd, 0xfb, 0x07, + 0x1c, 0x0c, 0xd1, 0x22, 0x49, 0x00, 0x20, 0x08, + 0x62, 0x48, 0x62, 0x21, 0x49, 0x08, 0x60, 0x28, + 0x66, 0xf5, 0xf7, 0x66, 0xfd, 0x00, 0x20, 0xff, + 0xf7, 0x15, 0xfd, 0xe9, 0xe7, 0xf1, 0xf7, 0x41, + 0xff, 0x04, 0x1c, 0x06, 0xd1, 0x19, 0x49, 0x00, + 0x20, 0x08, 0x62, 0x48, 0x62, 0x18, 0x49, 0x08, + 0x60, 0xde, 0xe7, 0x03, 0x21, 0xe8, 0x1d, 0x79, + 0x30, 0x41, 0x61, 0xb9, 0x6a, 0x89, 0x00, 0x01, + 0x62, 0xf9, 0x1d, 0x29, 0x31, 0x0c, 0xc9, 0xe8, + 0x1d, 0x9d, 0x30, 0x0c, 0xc0, 0x78, 0x6a, 0xe9, + 0x1d, 0x99, 0x31, 0x08, 0x73, 0xf9, 0x1d, 0xe8, + 0x1d, 0x09, 0x31, 0xed, 0x09, 0x00, 0xef, 0x00, + 0x28, 0xc9, 0xad, 0x30, 0x28, 0xc0, 0x35, 0x20, + 0x20, 0x60, 0x70, 0x68, 0xe0, 0x60, 0x0e, 0x20, + 0x21, 0x1c, 0x27, 0x61, 0xf1, 0xf7, 0x87, 0xff, + 0x00, 0x28, 0x05, 0xd0, 0x38, 0x1c, 0xf1, 0xf7, + 0x74, 0xff, 0x20, 0x1c, 0xf1, 0xf7, 0x4b, 0xff, + 0xb5, 0xe7, 0x68, 0x14, 0x04, 0x20, 0x40, 0x55, + 0x00, 0xe0, 0x00, 0x53, 0x00, 0xe0, 0x00, 0x52, + 0x00, 0xe0, 0xf0, 0xb5, 0x87, 0xb0, 0xc6, 0x1d, + 0x07, 0x1c, 0x4b, 0x48, 0xb9, 0x36, 0x01, 0x68, + 0x74, 0x68, 0x02, 0x31, 0x01, 0x60, 0x41, 0x68, + 0x49, 0x4b, 0xc9, 0x18, 0x41, 0x60, 0x00, 0x20, + 0xf8, 0x60, 0xf9, 0x6c, 0xbc, 0x42, 0xe1, 0x64, + 0x39, 0x6d, 0x21, 0x65, 0x60, 0x65, 0xa0, 0x65, + 0x31, 0x68, 0xe1, 0x65, 0x20, 0x66, 0xa0, 0x66, + 0x60, 0x67, 0xf9, 0x6f, 0xe1, 0x67, 0x00, 0xd0, + 0xf8, 0x67, 0xe1, 0x1d, 0x79, 0x31, 0x06, 0x91, + 0x00, 0x20, 0x48, 0x60, 0xc8, 0x60, 0xf9, 0x1d, + 0x79, 0x31, 0x60, 0x64, 0x05, 0x91, 0xc8, 0x6b, + 0xe5, 0x1d, 0x20, 0x64, 0xb0, 0x6b, 0xb9, 0x35, + 0xa8, 0x63, 0xf9, 0x1d, 0xe1, 0x31, 0x0c, 0xc9, + 0xe0, 0x1d, 0xe1, 0x30, 0x0c, 0xc0, 0x0c, 0xc9, + 0x0c, 0xc0, 0xa8, 0x6b, 0x00, 0x28, 0x02, 0xd0, + 0x20, 0x1c, 0xf8, 0xf7, 0xdc, 0xfa, 0x05, 0x20, + 0xe0, 0x60, 0x61, 0x68, 0x01, 0x20, 0x08, 0x61, + 0x61, 0x68, 0x1a, 0x20, 0xc8, 0x60, 0x60, 0x68, + 0xc1, 0x1d, 0x2b, 0x48, 0x51, 0x31, 0x04, 0x90, + 0x0c, 0xc8, 0x0c, 0xc1, 0x60, 0x68, 0x04, 0x99, + 0x3c, 0x30, 0x0c, 0xc9, 0x0c, 0xc0, 0x06, 0x99, + 0x00, 0x20, 0x48, 0x61, 0x05, 0x99, 0x09, 0x6b, + 0x06, 0x9a, 0x11, 0x63, 0x06, 0x99, 0x88, 0x61, + 0xb0, 0x68, 0xa8, 0x60, 0xf0, 0x68, 0xe8, 0x60, + 0x30, 0x69, 0x28, 0x61, 0x70, 0x69, 0xed, 0x09, + 0x00, 0xf0, 0x00, 0x68, 0x61, 0xb0, 0x69, 0xa8, + 0x61, 0x30, 0x6a, 0x28, 0x62, 0xf1, 0xf7, 0x9e, + 0xfe, 0x00, 0x28, 0x0f, 0xd0, 0x41, 0x21, 0x01, + 0x60, 0x61, 0x68, 0x49, 0x68, 0x01, 0x61, 0x21, + 0x7e, 0xc1, 0x60, 0x61, 0x68, 0x81, 0x61, 0x44, + 0x61, 0x08, 0x21, 0xc1, 0x61, 0x01, 0x1c, 0x0e, + 0x20, 0xf1, 0xf7, 0xfb, 0xfe, 0x79, 0x68, 0x60, + 0x68, 0x81, 0x42, 0x09, 0xd0, 0xf5, 0xf7, 0x0e, + 0xfa, 0x01, 0x28, 0x05, 0xd1, 0x02, 0x23, 0x1a, + 0x22, 0x21, 0x1c, 0x60, 0x68, 0xf3, 0xf7, 0x1d, + 0xfb, 0x01, 0x22, 0x03, 0x92, 0x02, 0x22, 0x01, + 0x21, 0x1a, 0x20, 0x00, 0x92, 0x01, 0x90, 0x02, + 0x91, 0x61, 0x68, 0x02, 0x23, 0x22, 0x1c, 0x78, + 0x68, 0xf3, 0xf7, 0x3f, 0xfc, 0x07, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, + 0x14, 0x04, 0x20, 0xe2, 0x04, 0x00, 0x00, 0x88, + 0xe6, 0x03, 0x20, 0xf0, 0xb5, 0x86, 0xb0, 0xc2, + 0x1d, 0x79, 0x32, 0x05, 0x92, 0x94, 0x69, 0x07, + 0x1c, 0x20, 0x20, 0x10, 0x63, 0xe0, 0x1d, 0x00, + 0x21, 0xf9, 0x60, 0xb9, 0x30, 0x47, 0x60, 0xfa, + 0x6d, 0xe3, 0x1d, 0x02, 0x60, 0x3a, 0x6c, 0x79, + 0x33, 0x04, 0x93, 0xda, 0x63, 0xfa, 0x6c, 0xe2, + 0x64, 0x3a, 0x6d, 0x22, 0x65, 0x54, 0x34, 0x00, + 0x22, 0x06, 0xc4, 0x06, 0xc4, 0x64, 0x3c, 0xa1, + 0x66, 0x61, 0x67, 0xfa, 0x6f, 0xbc, 0x42, 0xe2, + 0x67, 0x00, 0xd0, 0xf9, 0x67, 0x04, 0x9b, 0xfe, + 0x1d, 0x59, 0x60, 0x04, 0x9b, 0xe1, 0x36, 0xd9, + 0x60, 0x61, 0x64, 0x21, 0x64, 0xf9, 0x1d, 0xb9, + 0x31, 0x8a, 0x6b, 0xe5, 0x1d, 0x82, 0x63, 0x0c, + 0xce, 0xe1, 0x35, 0x0c, 0xc5, 0x0c, 0xce, 0x0c, + 0xc5, 0x05, 0x22, 0xe2, 0x60, 0x63, 0x68, 0x01, + 0x22, 0x1a, 0x61, 0x63, 0x68, 0x1a, 0x22, 0xda, + 0x60, 0xed, 0x09, 0x00, 0xf1, 0x00, 0x04, 0x9b, + 0x04, 0x22, 0x5a, 0x61, 0x05, 0x9a, 0xfe, 0x1d, + 0x12, 0x6b, 0x04, 0x9b, 0xf5, 0x36, 0x1a, 0x63, + 0x8a, 0x68, 0xe5, 0x1d, 0x82, 0x60, 0xca, 0x68, + 0xf5, 0x35, 0xc2, 0x60, 0x0a, 0x69, 0x02, 0x61, + 0x4a, 0x69, 0x42, 0x61, 0x8a, 0x69, 0x82, 0x61, + 0x09, 0x6a, 0x01, 0x62, 0x0e, 0xce, 0x0e, 0xc5, + 0x0e, 0xce, 0x0e, 0xc5, 0x7a, 0x68, 0xf9, 0x1d, + 0xd5, 0x1d, 0x51, 0x35, 0x48, 0xcd, 0xad, 0x31, + 0x48, 0xc1, 0x61, 0x68, 0xcd, 0x1d, 0x14, 0x49, + 0x51, 0x35, 0xce, 0x1d, 0xf9, 0x36, 0x0c, 0xce, + 0x0c, 0xc5, 0x62, 0x68, 0xf8, 0x31, 0xd5, 0x1d, + 0xff, 0x35, 0x48, 0xc9, 0x82, 0x35, 0x48, 0xc5, + 0x80, 0x6b, 0x00, 0x28, 0x02, 0xd0, 0x20, 0x1c, + 0xf8, 0xf7, 0x02, 0xfa, 0x20, 0x1c, 0xfd, 0xf7, + 0x62, 0xfe, 0x00, 0x22, 0x03, 0x92, 0x02, 0x22, + 0x01, 0x21, 0x1a, 0x20, 0x00, 0x92, 0x01, 0x90, + 0x02, 0x91, 0x61, 0x68, 0x02, 0x23, 0x22, 0x1c, + 0x78, 0x68, 0xf3, 0xf7, 0xad, 0xfb, 0x06, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x88, 0xe5, 0x03, 0x20, 0x00, 0xb5, 0x0f, 0x48, + 0x0f, 0x4b, 0x02, 0x68, 0x41, 0x69, 0x02, 0x32, + 0x02, 0x60, 0x42, 0x68, 0xd2, 0x18, 0x42, 0x60, + 0x0c, 0x48, 0x82, 0x68, 0x0c, 0x4b, 0x1a, 0x40, + 0x82, 0x60, 0x0c, 0x4a, 0xc2, 0x60, 0x82, 0x68, + 0x10, 0x23, 0x1a, 0x43, 0x82, 0x60, 0x0a, 0x4a, + 0x04, 0x20, 0x10, 0x60, 0x20, 0x20, 0x80, 0x31, + 0x08, 0x63, 0x00, 0x20, 0x00, 0xf0, 0x60, 0xf8, + 0x08, 0xbc, 0x18, 0x47, 0x68, 0x14, 0x04, 0x20, + 0xe2, 0x04, 0x00, 0x00, 0x00, 0x50, 0x00, 0xe0, + 0x1b, 0xf8, 0xff, 0xff, 0xfc, 0x07, 0x00, 0x00, + 0x24, 0x7e, 0x03, 0x20, 0xb0, 0xb5, 0x24, 0x4f, + 0x24, 0x4b, 0x38, 0x68, 0xed, 0x09, 0x00, 0xf2, + 0x00, 0x7c, 0x69, 0x06, 0x30, 0x38, 0x60, 0x78, + 0x68, 0xc0, 0x18, 0x78, 0x60, 0x21, 0x48, 0x81, + 0x68, 0x10, 0x23, 0x99, 0x43, 0x81, 0x60, 0x81, + 0x68, 0xfb, 0x23, 0x9b, 0x00, 0x19, 0x43, 0x81, + 0x60, 0xf1, 0xf7, 0x95, 0xfd, 0x00, 0x28, 0x13, + 0xd0, 0x41, 0x21, 0x01, 0x60, 0x79, 0x69, 0x41, + 0x61, 0x79, 0x69, 0x49, 0x68, 0x81, 0x61, 0x79, + 0x69, 0x49, 0x68, 0x49, 0x68, 0x01, 0x61, 0x79, + 0x69, 0x09, 0x7e, 0xc1, 0x60, 0x08, 0x21, 0xc1, + 0x61, 0x01, 0x1c, 0x0e, 0x20, 0xf1, 0xf7, 0xee, + 0xfd, 0xe7, 0x1d, 0x79, 0x37, 0x00, 0x25, 0x7d, + 0x61, 0xb8, 0x69, 0x00, 0x28, 0x08, 0xd0, 0x61, + 0x68, 0x40, 0x68, 0x81, 0x42, 0x04, 0xd0, 0x01, + 0x23, 0x01, 0x22, 0x00, 0x21, 0xf3, 0xf7, 0x36, + 0xfc, 0x01, 0x20, 0xbd, 0x61, 0xa0, 0x64, 0x08, + 0x49, 0x02, 0x20, 0x08, 0x60, 0x01, 0x20, 0x80, + 0x07, 0xf9, 0xf7, 0x98, 0xfa, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x14, 0x04, + 0x20, 0xa6, 0x0e, 0x00, 0x00, 0x00, 0x50, 0x00, + 0xe0, 0x24, 0x7e, 0x03, 0x20, 0xf0, 0xb5, 0x8c, + 0xb0, 0xf9, 0x49, 0x05, 0x1c, 0x08, 0x68, 0xf9, + 0x4b, 0x06, 0x1d, 0x48, 0x68, 0xc7, 0x18, 0x08, + 0x69, 0x4c, 0x69, 0x08, 0x90, 0xe1, 0x1d, 0x79, + 0x31, 0x0b, 0x91, 0x08, 0x6b, 0x01, 0x38, 0x08, + 0x63, 0x08, 0x6b, 0x00, 0x28, 0x05, 0xd1, 0xff, + 0xf7, 0x97, 0xff, 0x0c, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x2d, 0x11, 0xd0, 0x60, + 0x6e, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x21, 0x20, + 0x1c, 0xfd, 0xf7, 0xe4, 0xfd, 0x68, 0x08, 0x02, + 0xd3, 0xff, 0xf7, 0x86, 0xff, 0xed, 0xe7, 0x31, + 0x1c, 0x3a, 0x1c, 0x08, 0x98, 0xfa, 0xf7, 0xf2, + 0xfb, 0x07, 0x1c, 0xe6, 0x49, 0xe4, 0x4a, 0xed, + 0x09, 0x00, 0xf3, 0x00, 0x09, 0x69, 0x38, 0x1c, + 0xf5, 0xf7, 0x45, 0xfd, 0x00, 0x28, 0x02, 0xd1, + 0xe3, 0x4b, 0xff, 0x18, 0x04, 0x36, 0x02, 0x21, + 0x20, 0x1c, 0xfd, 0xf7, 0xb5, 0xfb, 0x60, 0x6f, + 0x02, 0x21, 0x00, 0x28, 0xdf, 0x4d, 0x73, 0xd0, + 0xb2, 0x1e, 0xde, 0x4b, 0x05, 0x92, 0xfa, 0x18, + 0x04, 0x92, 0xc0, 0x68, 0x02, 0x28, 0x07, 0xd0, + 0x26, 0xf0, 0x67, 0xfb, 0x0c, 0x22, 0x01, 0x21, + 0x20, 0x1c, 0xfd, 0xf7, 0x13, 0xfd, 0xd6, 0xe0, + 0x0b, 0x98, 0x41, 0x61, 0x60, 0x68, 0xa1, 0x6a, + 0x80, 0x30, 0xc2, 0x69, 0x23, 0x69, 0x03, 0x92, + 0x18, 0x0e, 0x1a, 0x02, 0x12, 0x0a, 0x00, 0x92, + 0x00, 0x22, 0x1a, 0x23, 0x01, 0x90, 0x02, 0x91, + 0x00, 0x21, 0x05, 0x98, 0xf5, 0xf7, 0x1f, 0xff, + 0x06, 0x90, 0x20, 0x69, 0x05, 0x99, 0x00, 0x0e, + 0x49, 0x08, 0x0a, 0x91, 0x09, 0x02, 0x08, 0x43, + 0xca, 0x49, 0x48, 0x60, 0xe1, 0x1d, 0xb9, 0x31, + 0x09, 0x91, 0x04, 0x98, 0xca, 0x68, 0x01, 0x92, + 0x0a, 0x69, 0x02, 0x92, 0x49, 0x69, 0x03, 0x91, + 0x69, 0x69, 0x01, 0x29, 0x50, 0xd0, 0x02, 0x29, + 0x2b, 0xd1, 0xc2, 0x4a, 0x03, 0x21, 0xd1, 0x62, + 0x06, 0x21, 0x01, 0xf0, 0x9e, 0xfd, 0xc8, 0x22, + 0x01, 0xf0, 0x93, 0xfd, 0x02, 0x9a, 0x52, 0x00, + 0x01, 0xf0, 0x8f, 0xfd, 0x28, 0x22, 0x01, 0xf0, + 0x8c, 0xfd, 0x03, 0x22, 0x01, 0xf0, 0x99, 0xfd, + 0x06, 0x99, 0xb8, 0x4a, 0x02, 0x31, 0x09, 0x02, + 0x10, 0x23, 0x19, 0x43, 0x11, 0x62, 0x01, 0x99, + 0xc9, 0x00, 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, + 0x11, 0x23, 0x19, 0x43, 0x51, 0x62, 0x03, 0x99, + 0x09, 0x02, 0x16, 0x23, 0x19, 0x43, 0x91, 0x62, + 0xb0, 0x49, 0x08, 0x60, 0x05, 0x20, 0x00, 0x02, + 0x08, 0x62, 0x09, 0x98, 0x04, 0x99, 0xc2, 0x68, + 0x6b, 0x69, 0xed, 0x09, 0x00, 0xf4, 0x00, 0xac, + 0x48, 0x01, 0x2b, 0x45, 0xd0, 0x02, 0x2b, 0x08, + 0xd1, 0xd2, 0x00, 0x00, 0xe0, 0x71, 0xe0, 0x40, + 0x23, 0x1a, 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, + 0x43, 0x02, 0x62, 0xc8, 0x1d, 0x5d, 0x30, 0xa5, + 0x49, 0xff, 0x22, 0x02, 0x32, 0x0a, 0x62, 0x08, + 0x60, 0x09, 0x99, 0x04, 0x98, 0x89, 0x6b, 0x03, + 0x91, 0xe1, 0x6a, 0x00, 0x29, 0x34, 0xd0, 0x05, + 0x21, 0x02, 0x91, 0x33, 0xe0, 0x06, 0x21, 0x01, + 0xf0, 0x52, 0xfd, 0xff, 0x22, 0x05, 0x32, 0x01, + 0xf0, 0x46, 0xfd, 0x02, 0x9a, 0x52, 0x00, 0x01, + 0xf0, 0x42, 0xfd, 0x28, 0x22, 0x01, 0xf0, 0x3f, + 0xfd, 0x03, 0x22, 0x01, 0xf0, 0x4c, 0xfd, 0x06, + 0x99, 0x02, 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, + 0x43, 0x90, 0x49, 0x0a, 0x62, 0x01, 0x9a, 0xd2, + 0x00, 0x84, 0x23, 0x1a, 0x43, 0x12, 0x02, 0x10, + 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x03, 0x9a, 0x12, + 0x02, 0x19, 0x23, 0x1a, 0x43, 0x8a, 0x62, 0x89, + 0x49, 0x08, 0x60, 0x8b, 0x48, 0x08, 0x62, 0xb2, + 0xe7, 0xd2, 0x00, 0x80, 0x23, 0x1a, 0x43, 0x12, + 0x02, 0x10, 0x23, 0x1a, 0x43, 0x02, 0x62, 0xbc, + 0xe7, 0x01, 0x21, 0x02, 0x91, 0x69, 0x69, 0x01, + 0x29, 0x73, 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x06, + 0x21, 0x01, 0xf0, 0x19, 0xfd, 0x7c, 0x49, 0x88, + 0x60, 0x03, 0x98, 0x02, 0x28, 0x02, 0xd0, 0x03, + 0x98, 0x03, 0x28, 0x06, 0xd1, 0x02, 0x98, 0x08, + 0x23, 0x18, 0x43, 0x02, 0x90, 0x0a, 0x98, 0x7b, + 0x4a, 0x10, 0x60, 0x02, 0x98, 0x08, 0x60, 0x04, + 0x98, 0xf4, 0xf7, 0xc3, 0xfe, 0x6b, 0x49, 0x08, + 0x62, 0x61, 0x6f, 0x80, 0x08, 0x88, 0x62, 0x61, + 0x6f, 0x00, 0x20, 0x88, 0x65, 0x60, 0x6f, 0xf5, + 0xf7, 0x60, 0xfa, 0x68, 0x49, 0xff, 0x22, 0x38, + 0x1c, 0x09, 0x69, 0xb9, 0x32, 0xed, 0x09, 0x00, + 0xf5, 0x00, 0xf5, 0xf7, 0x49, 0xfc, 0x00, 0x28, + 0x07, 0xd1, 0x6a, 0x49, 0x08, 0x62, 0x48, 0x62, + 0x63, 0x4b, 0x66, 0x49, 0xff, 0x18, 0x04, 0x36, + 0x08, 0x60, 0x60, 0x68, 0xa1, 0x6a, 0x80, 0x30, + 0xc2, 0x69, 0x23, 0x69, 0x03, 0x92, 0x18, 0x0e, + 0x1a, 0x02, 0x12, 0x0a, 0x00, 0x92, 0x02, 0x91, + 0x00, 0x21, 0x00, 0x22, 0x1a, 0x23, 0x01, 0x90, + 0x30, 0x1c, 0xf5, 0xf7, 0x39, 0xfe, 0x07, 0x90, + 0x20, 0x69, 0x00, 0x0e, 0x71, 0x08, 0x09, 0x02, + 0x08, 0x43, 0x5f, 0x49, 0x48, 0x60, 0xc0, 0x34, + 0xa2, 0x68, 0x38, 0x1c, 0x06, 0x92, 0x69, 0x69, + 0x01, 0x29, 0x73, 0xd0, 0x02, 0x29, 0x24, 0xd1, + 0x09, 0x21, 0x01, 0xf0, 0xb1, 0xfc, 0xc8, 0x22, + 0x01, 0xf0, 0xb8, 0xfc, 0x34, 0x22, 0x01, 0xf0, + 0xb5, 0xfc, 0x50, 0x22, 0x01, 0xf0, 0xb2, 0xfc, + 0x0d, 0x22, 0x01, 0xf0, 0xaf, 0xfc, 0x04, 0x22, + 0x01, 0xf0, 0xac, 0xfc, 0x28, 0x22, 0x01, 0xf0, + 0xa9, 0xfc, 0x07, 0x99, 0x02, 0x31, 0x09, 0x02, + 0x10, 0x22, 0x0a, 0x43, 0x4d, 0x49, 0x00, 0xe0, + 0xbe, 0xe0, 0x0a, 0x62, 0x06, 0x9a, 0x42, 0x23, + 0x1a, 0x43, 0x12, 0x02, 0x11, 0x23, 0x1a, 0x43, + 0x4a, 0x62, 0x49, 0x4a, 0x49, 0x49, 0x0a, 0x62, + 0x08, 0x60, 0xa1, 0x68, 0x6a, 0x69, 0x48, 0x48, + 0x01, 0x2a, 0x65, 0xd0, 0x02, 0x2a, 0x05, 0xd1, + 0x40, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, + 0x19, 0x43, 0x01, 0x62, 0xf8, 0x1d, 0x49, 0x30, + 0xff, 0x22, 0x42, 0x49, 0x02, 0x32, 0x0a, 0x62, + 0x08, 0x60, 0x41, 0x4a, 0xa1, 0x68, 0x10, 0x6a, + 0x52, 0x6a, 0x00, 0x0a, 0xff, 0x23, 0x1b, 0x02, + 0x1a, 0x40, 0x10, 0x43, 0x6a, 0x69, 0x01, 0x2a, + 0x4b, 0xd0, 0x02, 0x2a, 0x07, 0xd1, 0xd1, 0x03, + 0x02, 0x0c, 0x00, 0xd2, 0x00, 0x21, 0x08, 0x43, + 0xed, 0x09, 0x00, 0xf6, 0x00, 0x01, 0x23, 0xdb, + 0x03, 0x98, 0x43, 0x20, 0x62, 0x69, 0x69, 0x38, + 0x1c, 0x01, 0x29, 0x3d, 0xd0, 0x02, 0x29, 0x05, + 0xd1, 0x32, 0x49, 0x2d, 0x22, 0x0a, 0x62, 0x2c, + 0x22, 0x4a, 0x62, 0x3c, 0x38, 0x30, 0x4a, 0x31, + 0x49, 0x0a, 0x62, 0x08, 0x60, 0x30, 0x4a, 0xa1, + 0x68, 0x10, 0x6a, 0x52, 0x6a, 0x00, 0x0a, 0xff, + 0x23, 0x1b, 0x02, 0x1a, 0x40, 0x10, 0x43, 0x6a, + 0x69, 0x01, 0x2a, 0x6a, 0xd0, 0x02, 0x2a, 0x00, + 0xe0, 0x71, 0xe0, 0x07, 0xd1, 0xd1, 0x03, 0x02, + 0x0c, 0x00, 0xd2, 0x00, 0x21, 0x08, 0x43, 0x01, + 0x23, 0xdb, 0x03, 0x98, 0x43, 0xe0, 0x61, 0x68, + 0x69, 0x01, 0x28, 0x63, 0xd0, 0x02, 0x28, 0x04, + 0xd1, 0x21, 0x48, 0x2d, 0x22, 0x02, 0x62, 0x2c, + 0x22, 0x42, 0x62, 0x1d, 0x4a, 0x1f, 0x49, 0xf8, + 0x1d, 0x21, 0x30, 0x0a, 0x62, 0x08, 0x60, 0x13, + 0x4c, 0x03, 0x20, 0x20, 0x60, 0x69, 0x69, 0x38, + 0x1c, 0x01, 0x29, 0x35, 0xe0, 0x71, 0xe0, 0x77, + 0xe0, 0x7d, 0xe0, 0x00, 0x00, 0x68, 0x14, 0x04, + 0x20, 0xc4, 0x09, 0x00, 0x00, 0x7c, 0x0b, 0x00, + 0x00, 0x00, 0x50, 0x00, 0xe0, 0x88, 0x13, 0x00, + 0x00, 0x48, 0xe6, 0x03, 0x20, 0x1e, 0xfb, 0xff, + 0xff, 0x00, 0x52, 0x00, 0xe0, 0x80, 0x55, 0x00, + 0xe0, 0x00, 0x53, 0x00, 0xe0, 0x90, 0x55, 0x00, + 0xe0, 0x04, 0x53, 0x00, 0xe0, 0x03, 0x05, 0x00, + 0x00, 0x80, 0x57, 0x00, 0xe0, 0x00, 0x51, 0x00, + 0xe0, 0xa0, 0x55, 0x00, 0xe0, 0x02, 0x05, 0x00, + 0x00, 0x08, 0x53, 0x00, 0xe0, 0xb0, 0x55, 0x00, + 0xe0, 0x0c, 0x53, 0x00, 0xe0, 0xd0, 0x55, 0x00, + 0xe0, 0x02, 0x03, 0x00, 0x00, 0x14, 0x53, 0x00, + 0xe0, 0xc0, 0x55, 0x00, 0xe0, 0x10, 0x53, 0x00, + 0xe0, 0x5d, 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x09, + 0x21, 0x01, 0xf0, 0xed, 0x09, 0x00, 0xf7, 0x00, + 0xe4, 0xfb, 0xc1, 0x1f, 0x21, 0x39, 0xa1, 0x60, + 0xb0, 0x30, 0xe0, 0x60, 0x32, 0x20, 0x02, 0xf0, + 0x7e, 0xf9, 0x2a, 0x49, 0xc0, 0xc1, 0xdd, 0xe5, + 0x3f, 0xe0, 0x06, 0x21, 0x01, 0xf0, 0xe7, 0xfb, + 0x6a, 0x46, 0x03, 0xc2, 0x00, 0x98, 0x01, 0x99, + 0xc8, 0xe6, 0x3d, 0xe0, 0x10, 0x21, 0x01, 0xf0, + 0xcc, 0xfb, 0xff, 0x22, 0x05, 0x32, 0x01, 0xf0, + 0xd2, 0xfb, 0x46, 0x22, 0x01, 0xf0, 0xcf, 0xfb, + 0x0d, 0x22, 0x01, 0xf0, 0xcc, 0xfb, 0x04, 0x22, + 0x01, 0xf0, 0xc9, 0xfb, 0x28, 0x22, 0x01, 0xf0, + 0xc6, 0xfb, 0x07, 0x99, 0x02, 0x31, 0x09, 0x02, + 0x20, 0x22, 0x0a, 0x43, 0x19, 0x49, 0x0a, 0x62, + 0x06, 0x9a, 0x82, 0x23, 0x1a, 0x43, 0x12, 0x02, + 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x1d, 0xe7, + 0x80, 0x23, 0x19, 0x43, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0x01, 0x62, 0x27, 0xe7, 0x01, 0x22, + 0x12, 0x04, 0x00, 0x29, 0x00, 0xd1, 0x00, 0x22, + 0x10, 0x43, 0x3d, 0xe7, 0x0e, 0x49, 0x3d, 0x22, + 0x0a, 0x62, 0x3e, 0x22, 0x4a, 0x62, 0x46, 0x38, + 0x43, 0xe7, 0x01, 0x22, 0x12, 0x04, 0x00, 0x29, + 0x00, 0xd1, 0x00, 0x22, 0x10, 0x43, 0x58, 0xe7, + 0x08, 0x48, 0x3d, 0x22, 0x02, 0x62, 0x3e, 0x22, + 0x42, 0x62, 0x5d, 0xe7, 0x10, 0x21, 0x01, 0xf0, + 0x88, 0xfb, 0xa2, 0xe7, 0x00, 0x00, 0x68, 0x14, + 0x04, 0x20, 0xa0, 0x55, 0x00, 0xe0, 0xd0, 0x55, + 0x00, 0xe0, 0xc0, 0x55, 0x00, 0xe0, 0x00, 0xb5, + 0x03, 0x48, 0x40, 0x69, 0xff, 0xf7, 0x5b, 0xfc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x14, + 0x04, 0x20, 0x80, 0x21, 0xc0, 0x10, 0x02, 0x04, + 0x12, 0x14, 0x03, 0xd5, 0x00, 0x21, 0xd0, 0x43, + 0x02, 0x04, 0x12, 0x14, 0x09, 0x4b, 0x50, 0x11, + 0x18, 0x5c, 0x00, 0x28, 0x01, 0xd0, 0xed, 0x09, + 0x00, 0xf8, 0x00, 0x02, 0x41, 0x00, 0xe0, 0x52, + 0x10, 0x12, 0x07, 0x12, 0x0f, 0x00, 0x01, 0x08, + 0x43, 0x10, 0x43, 0x55, 0x23, 0x58, 0x40, 0x00, + 0x06, 0x00, 0x0e, 0x70, 0x47, 0x00, 0x00, 0x08, + 0x15, 0x01, 0x20, 0x80, 0x10, 0x00, 0x04, 0x00, + 0x14, 0x04, 0xd5, 0x80, 0x22, 0xc0, 0x43, 0x00, + 0x04, 0x00, 0x14, 0x00, 0xe0, 0x00, 0x22, 0x21, + 0x30, 0x00, 0x04, 0x22, 0x4b, 0x00, 0x14, 0x98, + 0x42, 0x00, 0xdd, 0x18, 0x1c, 0x01, 0x23, 0x1b, + 0x03, 0x98, 0x42, 0x03, 0xdb, 0x07, 0x21, 0xc0, + 0x1a, 0x00, 0x12, 0x2f, 0xe0, 0x01, 0x23, 0xdb, + 0x02, 0x98, 0x42, 0x03, 0xdb, 0x06, 0x21, 0xc0, + 0x1a, 0xc0, 0x11, 0x27, 0xe0, 0x01, 0x23, 0x9b, + 0x02, 0x98, 0x42, 0x03, 0xdb, 0x05, 0x21, 0xc0, + 0x1a, 0x80, 0x11, 0x1f, 0xe0, 0x01, 0x23, 0x5b, + 0x02, 0x98, 0x42, 0x03, 0xdb, 0x04, 0x21, 0xc0, + 0x1a, 0x40, 0x11, 0x17, 0xe0, 0xff, 0x23, 0x01, + 0x33, 0x98, 0x42, 0x04, 0xdb, 0x03, 0x21, 0xff, + 0x38, 0x01, 0x38, 0x00, 0x11, 0x0e, 0xe0, 0x80, + 0x28, 0x03, 0xdb, 0x02, 0x21, 0x80, 0x38, 0xc0, + 0x10, 0x08, 0xe0, 0x40, 0x28, 0x03, 0xdb, 0x01, + 0x21, 0x40, 0x38, 0x80, 0x10, 0x02, 0xe0, 0x00, + 0x21, 0x20, 0x38, 0x40, 0x10, 0x00, 0x06, 0x00, + 0x0e, 0x09, 0x01, 0x11, 0x43, 0x08, 0x43, 0xff, + 0x23, 0x58, 0x40, 0x18, 0x40, 0x70, 0x47, 0xff, + 0x1f, 0x00, 0x00, 0xf0, 0xb5, 0x89, 0xb0, 0x9e, + 0x49, 0x9f, 0x4a, 0xcd, 0x6a, 0x00, 0x21, 0x11, + 0x63, 0x9e, 0x4a, 0x9e, 0x49, 0xca, 0x60, 0x8a, + 0x68, 0x9e, 0x4b, 0x1a, 0x40, 0x8a, 0x60, 0x00, + 0x21, 0xf4, 0xf7, 0xc3, 0xfe, 0x07, 0x1c, 0x09, + 0xd1, 0x96, 0x48, 0x02, 0x6b, 0x01, 0x20, 0x29, + 0x1c, 0xf6, 0xf7, 0xbd, 0xf9, 0x09, 0xb0, 0xf0, + 0xbc, 0xed, 0x09, 0x00, 0xf9, 0x00, 0x08, 0xbc, + 0x18, 0x47, 0xfe, 0x1d, 0x45, 0x36, 0x95, 0x48, + 0x08, 0x96, 0x04, 0x69, 0xf4, 0xf7, 0x42, 0xfc, + 0x02, 0x90, 0x93, 0x48, 0x03, 0x91, 0x07, 0x90, + 0x40, 0x69, 0x01, 0x28, 0x73, 0xd0, 0x02, 0x28, + 0x04, 0xd1, 0x8e, 0x21, 0x20, 0x1c, 0x01, 0xf0, + 0xe3, 0xfa, 0x04, 0x1c, 0x02, 0x98, 0x84, 0x42, + 0x02, 0xd9, 0x03, 0x98, 0x01, 0x38, 0x03, 0x90, + 0x03, 0x99, 0x02, 0x94, 0x71, 0x60, 0xe9, 0x1d, + 0x79, 0x31, 0x34, 0x60, 0x89, 0x6a, 0x08, 0x20, + 0x88, 0x62, 0xe8, 0x60, 0x85, 0x48, 0x00, 0x26, + 0x06, 0x90, 0x06, 0x60, 0x08, 0x9e, 0x84, 0xa3, + 0x30, 0x68, 0x05, 0x90, 0x71, 0x68, 0x1a, 0x68, + 0x5b, 0x68, 0x04, 0x1c, 0x01, 0xf0, 0x30, 0xfa, + 0x01, 0x01, 0x09, 0x09, 0x80, 0x4b, 0x0e, 0x1c, + 0xe4, 0x18, 0x88, 0x1c, 0x00, 0x01, 0x00, 0x09, + 0x69, 0x64, 0x04, 0x90, 0x06, 0x98, 0x02, 0x1d, + 0x06, 0xca, 0x07, 0x98, 0x83, 0x6b, 0x03, 0x92, + 0x18, 0x0e, 0x1a, 0x02, 0x12, 0x0a, 0x01, 0x90, + 0xe8, 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x02, 0x91, + 0x00, 0x92, 0x42, 0x68, 0x08, 0x23, 0x31, 0x1c, + 0x04, 0x98, 0xf5, 0xf7, 0x07, 0xfc, 0x06, 0x1c, + 0x72, 0x48, 0x82, 0x68, 0x01, 0x92, 0xc2, 0x68, + 0x02, 0x92, 0x00, 0x69, 0x03, 0x90, 0x07, 0x98, + 0x40, 0x69, 0x01, 0x28, 0x73, 0xd0, 0x02, 0x28, + 0x2f, 0xd1, 0x6d, 0x49, 0x03, 0x20, 0xc8, 0x62, + 0x06, 0x21, 0x20, 0x1c, 0x01, 0xf0, 0x90, 0xfa, + 0xc8, 0x22, 0x01, 0xf0, 0x85, 0xfa, 0x02, 0x9a, + 0x52, 0x00, 0x01, 0xf0, 0x81, 0xfa, 0x28, 0x22, + 0x01, 0xf0, 0x7e, 0xfa, 0x03, 0x22, 0x01, 0xf0, + 0x8b, 0xfa, 0xb1, 0x1c, 0x09, 0x02, 0x10, 0x23, + 0x61, 0x4a, 0x19, 0x43, 0x11, 0x62, 0x01, 0x9a, + 0xd1, 0x00, 0x44, 0x23, 0xed, 0x09, 0x00, 0xfa, + 0x00, 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, + 0x43, 0x00, 0xe0, 0x5c, 0xe0, 0x5b, 0x4a, 0x51, + 0x62, 0x03, 0x9a, 0x11, 0x02, 0x16, 0x23, 0x59, + 0x4a, 0x19, 0x43, 0x91, 0x62, 0x4c, 0x49, 0x08, + 0x60, 0x05, 0x20, 0x00, 0x02, 0x08, 0x62, 0x54, + 0x48, 0x81, 0x68, 0x07, 0x98, 0x42, 0x69, 0x54, + 0x48, 0x01, 0x2a, 0x74, 0xd0, 0x02, 0x2a, 0x06, + 0xd1, 0xc9, 0x00, 0x40, 0x23, 0x19, 0x43, 0x09, + 0x02, 0x11, 0x23, 0x19, 0x43, 0x01, 0x62, 0xe0, + 0x1d, 0x5d, 0x30, 0xff, 0x22, 0x4d, 0x49, 0x02, + 0x32, 0x0a, 0x62, 0x08, 0x60, 0x07, 0x99, 0x20, + 0x1c, 0x49, 0x69, 0x01, 0x29, 0x68, 0xd0, 0x02, + 0x29, 0x02, 0xd1, 0x06, 0x21, 0x01, 0xf0, 0x46, + 0xfa, 0x47, 0x49, 0x88, 0x60, 0x03, 0x20, 0x08, + 0x60, 0x00, 0x26, 0xae, 0x64, 0xee, 0x64, 0x38, + 0x4d, 0xa8, 0x68, 0x44, 0x4b, 0x18, 0x40, 0xa8, + 0x60, 0xd8, 0x43, 0xe8, 0x60, 0x42, 0x4b, 0xe0, + 0x18, 0x30, 0x4c, 0x60, 0x60, 0x04, 0x98, 0x03, + 0x38, 0x20, 0x60, 0x00, 0x20, 0x00, 0xf0, 0xf8, + 0xfa, 0xa8, 0x68, 0xfb, 0x23, 0x9b, 0x00, 0x18, + 0x43, 0xa8, 0x60, 0xf1, 0xf7, 0x5c, 0xf9, 0x00, + 0x28, 0x00, 0xe0, 0x15, 0xe0, 0x0a, 0xd0, 0x35, + 0x21, 0xbe, 0x64, 0x01, 0x60, 0xe1, 0x6a, 0x49, + 0x68, 0xc1, 0x60, 0x07, 0x61, 0x01, 0x1c, 0x0e, + 0x20, 0xf1, 0xf7, 0xbc, 0xf9, 0x1b, 0xe7, 0x95, + 0x21, 0x20, 0x1c, 0x01, 0xf0, 0x13, 0xfa, 0x6a, + 0x46, 0x03, 0xc2, 0x01, 0x99, 0x00, 0x9c, 0x2b, + 0xe7, 0x06, 0x21, 0x20, 0x1c, 0x01, 0xf0, 0x0a, + 0xfa, 0xff, 0x22, 0x05, 0x32, 0x01, 0xf0, 0xfe, + 0xf9, 0x02, 0x9a, 0x52, 0x00, 0x01, 0xf0, 0xfa, + 0xf9, 0x28, 0x22, 0x01, 0xf0, 0xf7, 0xf9, 0x03, + 0x22, 0x01, 0xf0, 0x04, 0xfa, 0xb1, 0x1c, 0xed, + 0x09, 0x00, 0xfb, 0x00, 0x09, 0x02, 0x20, 0x22, + 0x0a, 0x43, 0x1d, 0x49, 0x0a, 0x62, 0x01, 0x9a, + 0xd2, 0x00, 0x84, 0x23, 0x1a, 0x43, 0x12, 0x02, + 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x03, 0x9a, + 0x12, 0x02, 0x00, 0xe0, 0x08, 0xe0, 0x19, 0x23, + 0x1a, 0x43, 0x8a, 0x62, 0x0a, 0x49, 0x08, 0x60, + 0x1a, 0x48, 0x08, 0x62, 0x7a, 0xe7, 0x07, 0xe0, + 0xc9, 0x00, 0x80, 0x23, 0x19, 0x43, 0x09, 0x02, + 0x10, 0x23, 0x19, 0x43, 0x01, 0x62, 0x81, 0xe7, + 0x06, 0x21, 0x01, 0xf0, 0xd6, 0xf9, 0x8e, 0xe7, + 0x00, 0x00, 0x34, 0xf3, 0x03, 0x20, 0x00, 0x53, + 0x00, 0xe0, 0x08, 0x01, 0x02, 0x00, 0x00, 0x50, + 0x00, 0xe0, 0xe7, 0xfe, 0xfd, 0xff, 0x00, 0x51, + 0x00, 0xe0, 0x48, 0xe6, 0x03, 0x20, 0x74, 0x03, + 0x04, 0x20, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe2, 0x04, 0x00, 0x00, 0x88, 0xe5, + 0x03, 0x20, 0x80, 0x55, 0x00, 0xe0, 0x90, 0x55, + 0x00, 0xe0, 0x04, 0x53, 0x00, 0xe0, 0x00, 0x52, + 0x00, 0xe0, 0x03, 0xf8, 0xfd, 0xff, 0xad, 0xf8, + 0xff, 0xff, 0x03, 0x05, 0x00, 0x00, 0xf0, 0xb5, + 0x88, 0xb0, 0x75, 0x48, 0xc6, 0x6a, 0x75, 0x48, + 0x80, 0x6a, 0x41, 0x07, 0x49, 0x0f, 0x06, 0xab, + 0x19, 0x70, 0x41, 0x06, 0x09, 0x0f, 0x07, 0x91, + 0x01, 0x06, 0xc9, 0x0f, 0x59, 0x70, 0xc1, 0x05, + 0xc9, 0x0f, 0x80, 0x05, 0xc0, 0x0f, 0x99, 0x70, + 0xd8, 0x70, 0x07, 0x9a, 0x00, 0x21, 0x02, 0x2a, + 0x6c, 0x48, 0x0b, 0xd0, 0x01, 0x60, 0x17, 0x20, + 0x6b, 0x49, 0x40, 0x01, 0xc8, 0x60, 0x00, 0x20, + 0x00, 0xf0, 0x55, 0xfa, 0x08, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x07, 0x69, 0xf4, 0xf7, + 0xd6, 0xfa, 0x65, 0x4d, 0x02, 0x90, 0x03, 0x91, + 0x68, 0x69, 0x01, 0x28, 0x73, 0xd0, 0x02, 0x28, + 0x04, 0xd1, 0xed, 0x09, 0x00, 0xfc, 0x00, 0x8e, + 0x21, 0x38, 0x1c, 0x01, 0xf0, 0x78, 0xf9, 0x07, + 0x1c, 0x02, 0x98, 0x87, 0x42, 0x02, 0xd9, 0x03, + 0x98, 0x01, 0x38, 0x03, 0x90, 0x02, 0x97, 0x03, + 0x99, 0x38, 0x1c, 0x5b, 0x4a, 0x01, 0xf0, 0x73, + 0xf9, 0x5b, 0xa3, 0x1a, 0x68, 0x04, 0x1c, 0x0f, + 0x1c, 0x5b, 0x68, 0x01, 0xf0, 0xd0, 0xf8, 0x04, + 0x90, 0x59, 0x48, 0x02, 0x1d, 0x06, 0xca, 0xab, + 0x6b, 0x03, 0x92, 0x18, 0x0e, 0x1a, 0x02, 0x12, + 0x0a, 0x01, 0x90, 0xf0, 0x1d, 0xff, 0x30, 0x7a, + 0x30, 0x00, 0x92, 0x02, 0x91, 0x42, 0x68, 0x71, + 0x6c, 0x04, 0x98, 0x08, 0x23, 0xf5, 0xf7, 0xb1, + 0xfa, 0x39, 0x1c, 0x4f, 0x49, 0x05, 0x90, 0x8e, + 0x68, 0xca, 0x68, 0x20, 0x1c, 0x02, 0x92, 0x09, + 0x69, 0x03, 0x91, 0x69, 0x69, 0x01, 0x29, 0x51, + 0xd0, 0x02, 0x29, 0x2a, 0xd1, 0x4a, 0x4a, 0x03, + 0x21, 0xd1, 0x62, 0x06, 0x21, 0x01, 0xf0, 0x3b, + 0xf9, 0xc8, 0x22, 0x01, 0xf0, 0x30, 0xf9, 0x02, + 0x9a, 0x52, 0x00, 0x01, 0xf0, 0x2c, 0xf9, 0x28, + 0x22, 0x01, 0xf0, 0x29, 0xf9, 0x03, 0x22, 0x01, + 0xf0, 0x36, 0xf9, 0x05, 0x99, 0x40, 0x4a, 0x02, + 0x31, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x11, + 0x62, 0xf1, 0x00, 0x44, 0x23, 0x19, 0x43, 0x09, + 0x02, 0x11, 0x23, 0x19, 0x43, 0x51, 0x62, 0x03, + 0x99, 0x09, 0x02, 0x16, 0x23, 0x19, 0x43, 0x91, + 0x62, 0x38, 0x49, 0x08, 0x60, 0x05, 0x20, 0x00, + 0x02, 0x08, 0x62, 0x39, 0x1c, 0x33, 0x49, 0x20, + 0x1c, 0x89, 0x68, 0x6b, 0x69, 0x34, 0x4a, 0x01, + 0x2b, 0x45, 0xd0, 0x02, 0x2b, 0x08, 0xd1, 0xc9, + 0x00, 0x00, 0xe0, 0x11, 0xe0, 0x40, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x11, + 0x62, 0xff, 0x22, 0x64, 0x30, 0x2d, 0x49, 0x02, + 0x32, 0x0a, 0x62, 0x08, 0x60, 0xed, 0x09, 0x00, + 0xfd, 0x00, 0x39, 0x1c, 0x1d, 0x49, 0x4c, 0x60, + 0x04, 0x98, 0x08, 0x60, 0x6b, 0xe7, 0x95, 0x21, + 0x38, 0x1c, 0x01, 0xf0, 0xf3, 0xf8, 0x07, 0x1c, + 0x79, 0xe7, 0x06, 0x21, 0x01, 0xf0, 0xee, 0xf8, + 0xff, 0x22, 0x05, 0x32, 0x01, 0xf0, 0xe2, 0xf8, + 0x02, 0x9a, 0x52, 0x00, 0x01, 0xf0, 0xde, 0xf8, + 0x28, 0x22, 0x01, 0xf0, 0xdb, 0xf8, 0x03, 0x22, + 0x01, 0xf0, 0xe8, 0xf8, 0x05, 0x99, 0x02, 0x31, + 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x17, 0x49, + 0x0a, 0x62, 0xf2, 0x00, 0x84, 0x23, 0x1a, 0x43, + 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, + 0x03, 0x9a, 0x12, 0x02, 0x19, 0x23, 0x1a, 0x43, + 0x8a, 0x62, 0x11, 0x49, 0x08, 0x60, 0x13, 0x48, + 0x08, 0x62, 0xb1, 0xe7, 0xc9, 0x00, 0x80, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, + 0x11, 0x62, 0xbc, 0xe7, 0x34, 0xf3, 0x03, 0x20, + 0x40, 0x55, 0x00, 0xe0, 0x00, 0x51, 0x00, 0xe0, + 0x00, 0x50, 0x00, 0xe0, 0x48, 0xe6, 0x03, 0x20, + 0xe2, 0x04, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x03, 0x04, 0x20, + 0x88, 0xe5, 0x03, 0x20, 0x80, 0x55, 0x00, 0xe0, + 0x00, 0x53, 0x00, 0xe0, 0x90, 0x55, 0x00, 0xe0, + 0x04, 0x53, 0x00, 0xe0, 0x03, 0x05, 0x00, 0x00, + 0x00, 0xb5, 0x05, 0x49, 0x00, 0x20, 0x08, 0x62, + 0x48, 0x62, 0x04, 0x49, 0x08, 0x60, 0x00, 0xf0, + 0x63, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x00, 0x53, 0x00, 0xe0, 0x00, 0x51, 0x00, 0xe0, + 0xf0, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 0x9c, 0x48, + 0xc5, 0x6a, 0x01, 0x68, 0x04, 0x91, 0x40, 0x68, + 0x9a, 0x4a, 0x9b, 0x49, 0xca, 0x60, 0x8a, 0x68, + 0x9a, 0x4b, 0x1a, 0x40, 0x8a, 0x60, 0x9a, 0x49, + 0x0b, 0x91, 0x49, 0x69, 0x01, 0x29, 0x73, 0xd0, + 0xed, 0x09, 0x00, 0xfe, 0x00, 0x02, 0x29, 0x02, + 0xd1, 0x06, 0x21, 0x01, 0xf0, 0x79, 0xf8, 0x01, + 0x1c, 0x95, 0x48, 0x81, 0x60, 0x03, 0x21, 0x01, + 0x60, 0x00, 0x21, 0x38, 0x1c, 0xf4, 0xf7, 0x30, + 0xfc, 0xc6, 0x1d, 0x45, 0x36, 0x07, 0x1c, 0x91, + 0x48, 0x0a, 0x96, 0x04, 0x69, 0xf4, 0xf7, 0xba, + 0xf9, 0x03, 0x91, 0x0b, 0x99, 0x02, 0x90, 0x48, + 0x69, 0x01, 0x28, 0x6d, 0xd0, 0x02, 0x28, 0x04, + 0xd1, 0x8e, 0x21, 0x20, 0x1c, 0x01, 0xf0, 0x5c, + 0xf8, 0x04, 0x1c, 0x02, 0x98, 0x84, 0x42, 0x02, + 0xd9, 0x03, 0x98, 0x01, 0x38, 0x03, 0x90, 0x03, + 0x99, 0x02, 0x94, 0x71, 0x60, 0x84, 0x48, 0x34, + 0x60, 0x84, 0x4a, 0x00, 0x68, 0x11, 0x6a, 0x52, + 0x6a, 0x09, 0x0a, 0xff, 0x23, 0x1b, 0x02, 0x1a, + 0x40, 0x11, 0x43, 0x0e, 0x1c, 0x0b, 0x99, 0x4a, + 0x69, 0x01, 0x2a, 0x74, 0xd0, 0x02, 0x2a, 0x08, + 0xd1, 0xd1, 0x03, 0x33, 0x0c, 0x00, 0xd2, 0x00, + 0x21, 0x31, 0x43, 0x01, 0x23, 0xdb, 0x03, 0x99, + 0x43, 0x0e, 0x1c, 0x79, 0x4b, 0x31, 0x1c, 0x1c, + 0x6a, 0x5e, 0x6a, 0x24, 0x0a, 0xff, 0x23, 0x1b, + 0x02, 0x33, 0x40, 0x1c, 0x43, 0x26, 0x1c, 0x01, + 0x2a, 0x6f, 0xd0, 0x02, 0x2a, 0x09, 0xd1, 0xd2, + 0x03, 0x30, 0x0c, 0x00, 0xd2, 0x00, 0x22, 0x32, + 0x43, 0x01, 0x23, 0xdb, 0x03, 0x10, 0x1c, 0x98, + 0x43, 0x06, 0x1c, 0x48, 0x04, 0x40, 0x0c, 0x72, + 0x04, 0x52, 0x0c, 0x90, 0x42, 0x00, 0xd9, 0x0e, + 0x1c, 0xe9, 0x1d, 0x79, 0x31, 0x89, 0x6a, 0x09, + 0x20, 0x88, 0x62, 0xe8, 0x60, 0x00, 0x22, 0x28, + 0x1c, 0x79, 0x6a, 0xf4, 0xf7, 0x2f, 0xfb, 0x04, + 0x1c, 0x5a, 0x48, 0x00, 0xe0, 0x92, 0xe0, 0x04, + 0x63, 0xe8, 0x1d, 0x35, 0x30, 0xf9, 0x1d, 0x09, + 0x31, 0x09, 0x90, 0x0c, 0xc9, 0x0c, 0xc0, 0xe8, + 0x1d, 0x51, 0x30, 0xed, 0x09, 0x00, 0xff, 0x00, + 0x09, 0x99, 0x08, 0x90, 0x0c, 0xc9, 0x0c, 0xc0, + 0xe0, 0x1d, 0x09, 0x30, 0xf9, 0x1d, 0x29, 0x31, + 0x06, 0x91, 0x07, 0x90, 0x00, 0xe0, 0x84, 0xe0, + 0x0c, 0xc9, 0x0c, 0xc0, 0x00, 0x21, 0xe1, 0x64, + 0x21, 0x65, 0x61, 0x65, 0xa1, 0x65, 0xe1, 0x65, + 0x21, 0x66, 0xa1, 0x66, 0x61, 0x67, 0xa1, 0x67, + 0xe0, 0x1d, 0x79, 0x30, 0xe1, 0x67, 0x41, 0x60, + 0xc1, 0x60, 0xe0, 0x1d, 0x21, 0x64, 0x61, 0x64, + 0xb9, 0x30, 0x81, 0x63, 0xb8, 0x6a, 0x4c, 0x4a, + 0x80, 0x00, 0xf0, 0xf7, 0xc0, 0xfc, 0x0a, 0x9b, + 0x1a, 0x68, 0x5b, 0x68, 0x80, 0x1a, 0x99, 0x41, + 0xea, 0x1d, 0x25, 0x32, 0x05, 0x92, 0x03, 0xc2, + 0xb8, 0x6a, 0x00, 0xe0, 0x66, 0xe0, 0x04, 0x99, + 0x80, 0x00, 0x08, 0x1a, 0xe9, 0x1d, 0xff, 0x31, + 0x7a, 0x31, 0x08, 0x60, 0xb8, 0x6a, 0x41, 0xa1, + 0x80, 0x00, 0x28, 0x62, 0xb8, 0x6a, 0x80, 0x00, + 0x68, 0x61, 0xe8, 0x1d, 0x11, 0x30, 0x00, 0xe0, + 0x5b, 0xe0, 0x0c, 0xc9, 0x0c, 0xc0, 0x05, 0x99, + 0xe8, 0x1d, 0x0c, 0xc9, 0x1d, 0x30, 0x0c, 0xc0, + 0x00, 0x21, 0x69, 0x63, 0x06, 0x99, 0x07, 0x98, + 0x0c, 0xc9, 0x0c, 0xc0, 0x08, 0x99, 0x37, 0x48, + 0x0c, 0xc9, 0x0c, 0xc0, 0x0a, 0x9b, 0x03, 0xcb, + 0x28, 0x49, 0x48, 0x60, 0xb8, 0x6a, 0x80, 0x00, + 0x08, 0x60, 0x27, 0x49, 0x88, 0x68, 0x32, 0x4b, + 0x18, 0x40, 0x88, 0x60, 0xd8, 0x43, 0xc8, 0x60, + 0x00, 0x20, 0x00, 0xf0, 0xfe, 0xf9, 0x22, 0x49, + 0x88, 0x68, 0xfb, 0x23, 0x9b, 0x00, 0x18, 0x43, + 0x88, 0x60, 0x00, 0x22, 0x28, 0x1c, 0x21, 0x7e, + 0xfc, 0xf7, 0x17, 0xfd, 0xf0, 0xf7, 0xc0, 0xfe, + 0x00, 0x28, 0x0b, 0xd0, 0x35, 0x21, 0xbe, 0x64, + 0x01, 0x60, 0x17, 0x49, 0xc9, 0x6a, 0x49, 0x68, + 0xc1, 0x60, 0x07, 0x61, 0x01, 0x1c, 0xed, 0x09, + 0x00, 0x00, 0x01, 0x0e, 0x20, 0xf0, 0xf7, 0x21, + 0xff, 0x22, 0x49, 0x00, 0x20, 0x08, 0x60, 0x0c, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, + 0x21, 0x00, 0xf0, 0x73, 0xff, 0x02, 0xaa, 0x03, + 0xc2, 0x02, 0x98, 0x03, 0x99, 0xf4, 0xe6, 0x95, + 0x21, 0x20, 0x1c, 0x00, 0xf0, 0x6a, 0xff, 0x6a, + 0x46, 0x03, 0xc2, 0x01, 0x99, 0x00, 0x9c, 0x09, + 0xe7, 0x01, 0x21, 0x09, 0x04, 0x00, 0x28, 0x00, + 0xd1, 0x00, 0x21, 0x0e, 0x43, 0x26, 0xe7, 0x01, + 0x22, 0x12, 0x04, 0x00, 0x28, 0x00, 0xd1, 0x00, + 0x22, 0x16, 0x43, 0x37, 0xe7, 0x00, 0x00, 0x34, + 0xf3, 0x03, 0x20, 0x08, 0x01, 0x02, 0x00, 0x00, + 0x50, 0x00, 0xe0, 0xe7, 0xfe, 0xfd, 0xff, 0x48, + 0xe6, 0x03, 0x20, 0x00, 0x52, 0x00, 0xe0, 0x00, + 0x51, 0x00, 0xe0, 0x88, 0xe5, 0x03, 0x20, 0xd0, + 0x55, 0x00, 0xe0, 0xc0, 0x55, 0x00, 0xe0, 0x71, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x51, 0x00, 0xe0, 0x03, + 0xf8, 0xfd, 0xff, 0x74, 0x03, 0x04, 0x20, 0xf0, + 0xb5, 0x88, 0xb0, 0xbc, 0x49, 0x4a, 0x68, 0xbc, + 0x4b, 0xbd, 0x4e, 0xd5, 0x18, 0x0a, 0x68, 0xbc, + 0x4f, 0x04, 0x32, 0x05, 0x92, 0xcc, 0x6a, 0x00, + 0x28, 0x41, 0xd0, 0xf1, 0x1f, 0xb9, 0x39, 0x09, + 0x68, 0xb9, 0x4a, 0x07, 0x91, 0x03, 0x91, 0x11, + 0x6a, 0x52, 0x6a, 0x09, 0x0a, 0xff, 0x23, 0x1b, + 0x02, 0x1a, 0x40, 0x11, 0x43, 0x72, 0x69, 0x06, + 0x92, 0x01, 0x2a, 0x47, 0xd0, 0x02, 0x2a, 0x07, + 0xd1, 0xd2, 0x03, 0x0b, 0x0c, 0x00, 0xd2, 0x00, + 0x22, 0x11, 0x43, 0x01, 0x23, 0xdb, 0x03, 0x99, + 0x43, 0x4a, 0x04, 0x3b, 0x68, 0x52, 0x0c, 0x5b, + 0x04, 0x5b, 0x0c, 0x9a, 0x42, 0x00, 0xd9, 0x39, + 0x60, 0x07, 0x99, 0xa9, 0x4a, 0x03, 0x91, 0x11, + 0x6a, 0xed, 0x09, 0x00, 0x01, 0x01, 0x52, 0x6a, + 0x09, 0x0a, 0xff, 0x23, 0x1b, 0x02, 0x1a, 0x40, + 0x11, 0x43, 0x06, 0x9a, 0x01, 0x2a, 0x30, 0xd0, + 0x02, 0x2a, 0x07, 0xd1, 0xd2, 0x03, 0x0b, 0x0c, + 0x00, 0xd2, 0x00, 0x22, 0x11, 0x43, 0x01, 0x23, + 0xdb, 0x03, 0x99, 0x43, 0x4a, 0x04, 0x3b, 0x68, + 0x52, 0x0c, 0x5b, 0x04, 0x5b, 0x0c, 0x9a, 0x42, + 0x00, 0xd9, 0x39, 0x60, 0xc1, 0x07, 0xc9, 0x0f, + 0x07, 0x20, 0x00, 0x29, 0x21, 0xd0, 0xe1, 0x1d, + 0x79, 0x31, 0x89, 0x6a, 0x88, 0x62, 0xe0, 0x60, + 0x39, 0x68, 0x20, 0x1c, 0xfd, 0xf7, 0xf7, 0xf9, + 0x00, 0x20, 0xf8, 0x60, 0x02, 0x20, 0xf2, 0xf7, + 0x61, 0xfd, 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0x22, 0x03, 0x9b, 0x12, 0x04, + 0x00, 0x2b, 0x00, 0xd1, 0x00, 0x22, 0x11, 0x43, + 0xb9, 0xe7, 0x01, 0x22, 0x03, 0x9b, 0x12, 0x04, + 0x00, 0x2b, 0x00, 0xd1, 0x00, 0x22, 0x11, 0x43, + 0xd0, 0xe7, 0xa1, 0x6c, 0x4a, 0x1c, 0xa2, 0x64, + 0x04, 0x29, 0x1a, 0xd9, 0xe1, 0x1d, 0x79, 0x31, + 0x89, 0x6a, 0x7e, 0x4d, 0x88, 0x62, 0xe0, 0x60, + 0x39, 0x68, 0x20, 0x1c, 0xfd, 0xf7, 0xcf, 0xf9, + 0xf8, 0x68, 0x04, 0x28, 0x07, 0xd2, 0x01, 0x30, + 0xf8, 0x60, 0x01, 0x20, 0x21, 0x1c, 0x2a, 0x6b, + 0xf5, 0xf7, 0x68, 0xfd, 0xd1, 0xe7, 0x00, 0x20, + 0xf8, 0x60, 0x02, 0x20, 0xf2, 0xf7, 0x2e, 0xfd, + 0xcb, 0xe7, 0x3a, 0x1d, 0x06, 0xca, 0xb3, 0x6b, + 0x03, 0x92, 0x18, 0x0e, 0x1a, 0x02, 0x12, 0x0a, + 0x01, 0x90, 0xe0, 0x1d, 0xff, 0x30, 0x7a, 0x30, + 0x00, 0x92, 0x02, 0x91, 0x42, 0x68, 0x61, 0x6c, + 0x05, 0x98, 0x08, 0x23, 0xf4, 0xf7, 0xee, 0xff, + 0x04, 0x90, 0x7a, 0x68, 0x61, 0x6c, 0x05, 0x98, + 0xf4, 0xf7, 0x81, 0xfe, 0x20, 0x23, 0xb1, 0x6b, + 0x18, 0x43, 0x09, 0x0e, 0xed, 0x09, 0x00, 0x02, + 0x01, 0x00, 0x02, 0x69, 0x4f, 0x08, 0x43, 0x78, + 0x60, 0x68, 0x49, 0x28, 0x1c, 0x0c, 0x68, 0x71, + 0x69, 0x01, 0x29, 0x73, 0xd0, 0x02, 0x29, 0x21, + 0xd1, 0x09, 0x21, 0x00, 0xf0, 0x61, 0xfe, 0xc8, + 0x22, 0x00, 0xf0, 0x68, 0xfe, 0x34, 0x22, 0x00, + 0xf0, 0x65, 0xfe, 0x50, 0x22, 0x00, 0xf0, 0x62, + 0xfe, 0x0d, 0x22, 0x00, 0xf0, 0x5f, 0xfe, 0x04, + 0x22, 0x00, 0xf0, 0x5c, 0xfe, 0x28, 0x22, 0x00, + 0xf0, 0x59, 0xfe, 0x04, 0x99, 0x02, 0x31, 0x09, + 0x02, 0x10, 0x22, 0x0a, 0x43, 0x58, 0x49, 0x0a, + 0x62, 0x42, 0x22, 0x22, 0x43, 0x12, 0x02, 0x11, + 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x55, 0x4a, 0x56, + 0x49, 0x0a, 0x62, 0x08, 0x60, 0x51, 0x48, 0x01, + 0x68, 0x72, 0x69, 0x54, 0x48, 0x01, 0x2a, 0x74, + 0xd0, 0x02, 0x2a, 0x05, 0xd1, 0x40, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x01, + 0x62, 0xe8, 0x1d, 0x49, 0x30, 0xff, 0x22, 0x4e, + 0x49, 0x02, 0x32, 0x0a, 0x62, 0x08, 0x60, 0x72, + 0x69, 0x3e, 0x21, 0x3d, 0x20, 0x01, 0x2a, 0x61, + 0xd0, 0x02, 0x2a, 0x04, 0xd1, 0x40, 0x4a, 0x2d, + 0x23, 0x13, 0x62, 0x2c, 0x23, 0x53, 0x62, 0x47, + 0x4b, 0x47, 0x4c, 0xea, 0x1d, 0x21, 0x32, 0x23, + 0x62, 0x27, 0x23, 0x1b, 0x01, 0x22, 0x60, 0xea, + 0x18, 0x73, 0x69, 0x01, 0x2b, 0x5c, 0xd0, 0x02, + 0x2b, 0x04, 0xd1, 0x38, 0x48, 0x2d, 0x23, 0x03, + 0x62, 0x2c, 0x23, 0x43, 0x62, 0xd0, 0x1d, 0x3d, + 0x4b, 0x3e, 0x49, 0x21, 0x30, 0x05, 0x24, 0x0b, + 0x62, 0x08, 0x60, 0xb1, 0x6a, 0x28, 0x1c, 0x00, + 0x29, 0x00, 0xd1, 0x01, 0x24, 0x71, 0x69, 0x01, + 0x29, 0x4a, 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x09, + 0x21, 0x00, 0xf0, 0xf6, 0xfd, 0xc1, 0x1f, 0x21, + 0x39, 0xb9, 0x60, 0x00, 0xe0, 0x0d, 0xe0, 0xed, + 0x09, 0x00, 0x03, 0x01, 0xff, 0x30, 0xff, 0x30, + 0xff, 0x30, 0x23, 0x30, 0xf8, 0x60, 0x32, 0x20, + 0x3c, 0x60, 0x01, 0xf0, 0x8a, 0xfb, 0x1f, 0x48, + 0x45, 0x60, 0x05, 0x9a, 0x02, 0x60, 0x21, 0xe7, + 0x10, 0x21, 0x00, 0xf0, 0xe0, 0xfd, 0xff, 0x22, + 0x05, 0x32, 0x00, 0xf0, 0xe6, 0xfd, 0x46, 0x22, + 0x00, 0xf0, 0xe3, 0xfd, 0x0d, 0x22, 0x00, 0xf0, + 0xe0, 0xfd, 0x04, 0x22, 0x00, 0xf0, 0xdd, 0xfd, + 0x28, 0x22, 0x00, 0xf0, 0xda, 0xfd, 0x04, 0x99, + 0x02, 0x31, 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, + 0x19, 0x49, 0x0a, 0x62, 0x82, 0x22, 0x22, 0x43, + 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x01, 0xe0, + 0x02, 0xe0, 0x08, 0xe0, 0x4a, 0x62, 0x7c, 0xe7, + 0x80, 0x23, 0x19, 0x43, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0x01, 0x62, 0x87, 0xe7, 0x0b, 0x4a, + 0x10, 0x62, 0x51, 0x62, 0x96, 0xe7, 0x0a, 0x4b, + 0x18, 0x62, 0x59, 0x62, 0xa5, 0xe7, 0x10, 0x21, + 0x00, 0xf0, 0xad, 0xfd, 0x02, 0xaa, 0x03, 0xc2, + 0x02, 0x98, 0x03, 0x99, 0xb1, 0xe7, 0x34, 0xf3, + 0x03, 0x20, 0xc4, 0x09, 0x00, 0x00, 0x48, 0xe6, + 0x03, 0x20, 0x74, 0x03, 0x04, 0x20, 0xc0, 0x55, + 0x00, 0xe0, 0xd0, 0x55, 0x00, 0xe0, 0x00, 0x51, + 0x00, 0xe0, 0x88, 0xe5, 0x03, 0x20, 0xa0, 0x55, + 0x00, 0xe0, 0x02, 0x05, 0x00, 0x00, 0x08, 0x53, + 0x00, 0xe0, 0xb0, 0x55, 0x00, 0xe0, 0x0c, 0x53, + 0x00, 0xe0, 0x02, 0x03, 0x00, 0x00, 0x10, 0x53, + 0x00, 0xe0, 0x14, 0x53, 0x00, 0xe0, 0xf0, 0xb5, + 0x86, 0xb0, 0x94, 0x4d, 0x69, 0x68, 0x94, 0x4b, + 0xcf, 0x18, 0x29, 0x68, 0x94, 0x4b, 0x04, 0x31, + 0x05, 0x91, 0x29, 0x6b, 0xee, 0x6a, 0x04, 0x91, + 0x1a, 0x68, 0x91, 0x4b, 0x19, 0x6a, 0x5c, 0x6a, + 0x09, 0x0a, 0xff, 0x23, 0x1b, 0x02, 0x23, 0x40, + 0x8f, 0x4c, 0xed, 0x09, 0x00, 0x04, 0x01, 0x19, + 0x43, 0x63, 0x69, 0x01, 0x2b, 0x29, 0xd0, 0x02, + 0x2b, 0x07, 0xd1, 0xda, 0x03, 0x0b, 0x0c, 0x00, + 0xd2, 0x00, 0x22, 0x11, 0x43, 0x01, 0x23, 0xdb, + 0x03, 0x99, 0x43, 0x88, 0x4d, 0x4a, 0x04, 0x2b, + 0x68, 0x52, 0x0c, 0x5b, 0x04, 0x5b, 0x0c, 0x9a, + 0x42, 0x00, 0xd9, 0x29, 0x60, 0xc1, 0x07, 0xc9, + 0x0f, 0x07, 0x20, 0x00, 0x29, 0x18, 0xd0, 0xf1, + 0x1d, 0x79, 0x31, 0x89, 0x6a, 0x88, 0x62, 0xf0, + 0x60, 0x29, 0x68, 0x30, 0x1c, 0xfd, 0xf7, 0x7e, + 0xf8, 0x00, 0x20, 0xe8, 0x60, 0x02, 0x20, 0xf2, + 0xf7, 0xe8, 0xfb, 0x06, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x01, 0x23, 0x1b, 0x04, 0x00, + 0x2a, 0x00, 0xd1, 0x00, 0x23, 0x19, 0x43, 0xd8, + 0xe7, 0xf1, 0x6c, 0x4a, 0x1c, 0xf2, 0x64, 0x04, + 0x29, 0x1a, 0xd9, 0xf1, 0x1d, 0x79, 0x31, 0x89, + 0x6a, 0x6c, 0x4f, 0x88, 0x62, 0xf0, 0x60, 0x29, + 0x68, 0x30, 0x1c, 0xfd, 0xf7, 0x5f, 0xf8, 0xe8, + 0x68, 0x04, 0x28, 0x07, 0xd2, 0x01, 0x30, 0xe8, + 0x60, 0x01, 0x20, 0x31, 0x1c, 0x3a, 0x6b, 0xf5, + 0xf7, 0xf8, 0xfb, 0xda, 0xe7, 0x00, 0x20, 0xe8, + 0x60, 0x02, 0x20, 0xf2, 0xf7, 0xbe, 0xfb, 0xd4, + 0xe7, 0x2a, 0x1d, 0x06, 0xca, 0x04, 0x98, 0x03, + 0x69, 0x03, 0x92, 0x18, 0x0e, 0x1a, 0x02, 0x12, + 0x0a, 0x00, 0x92, 0x00, 0x22, 0x09, 0x23, 0x01, + 0x90, 0x02, 0x91, 0x00, 0x21, 0x05, 0x98, 0xf4, + 0xf7, 0x80, 0xfe, 0x06, 0x1c, 0x04, 0x98, 0x00, + 0x69, 0x05, 0x99, 0x00, 0x0e, 0x49, 0x08, 0x09, + 0x02, 0x08, 0x43, 0x59, 0x49, 0x48, 0x60, 0x54, + 0x49, 0x38, 0x1c, 0x0d, 0x68, 0x61, 0x69, 0x01, + 0x29, 0x68, 0xd0, 0x02, 0x29, 0x20, 0xd1, 0x09, + 0x21, 0x00, 0xf0, 0xf7, 0xfc, 0xc8, 0x22, 0x00, + 0xf0, 0xfe, 0xfc, 0x34, 0x22, 0xed, 0x09, 0x00, + 0x05, 0x01, 0x00, 0xf0, 0xfb, 0xfc, 0x50, 0x22, + 0x00, 0xf0, 0xf8, 0xfc, 0x0d, 0x22, 0x00, 0xf0, + 0xf5, 0xfc, 0x04, 0x22, 0x00, 0xf0, 0xf2, 0xfc, + 0x28, 0x22, 0x00, 0xf0, 0xef, 0xfc, 0xb1, 0x1c, + 0x09, 0x02, 0x10, 0x22, 0x0a, 0x43, 0x49, 0x49, + 0x0a, 0x62, 0x42, 0x22, 0x2a, 0x43, 0x12, 0x02, + 0x11, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x46, 0x4a, + 0x46, 0x49, 0x0a, 0x62, 0x08, 0x60, 0x3e, 0x48, + 0x01, 0x68, 0x62, 0x69, 0x44, 0x48, 0x01, 0x2a, + 0x5c, 0xd0, 0x02, 0x2a, 0x05, 0xd1, 0x40, 0x23, + 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, + 0x01, 0x62, 0xf8, 0x1d, 0x49, 0x30, 0xff, 0x22, + 0x3e, 0x49, 0x02, 0x32, 0x0a, 0x62, 0x08, 0x60, + 0x60, 0x69, 0x01, 0x28, 0x51, 0xd0, 0x02, 0x28, + 0x04, 0xd1, 0x32, 0x4b, 0x2d, 0x20, 0x18, 0x62, + 0x2c, 0x20, 0x58, 0x62, 0x38, 0x4a, 0x39, 0x48, + 0xf9, 0x1d, 0x21, 0x31, 0x02, 0x62, 0x01, 0x60, + 0xa1, 0x6a, 0x38, 0x1c, 0x05, 0x25, 0x00, 0x29, + 0x00, 0xd1, 0x01, 0x25, 0x61, 0x69, 0x01, 0x29, + 0x41, 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x09, 0x21, + 0x00, 0xf0, 0xa2, 0xfc, 0xc1, 0x1f, 0x28, 0x4a, + 0x21, 0x39, 0x91, 0x60, 0xb0, 0x30, 0xd0, 0x60, + 0x32, 0x20, 0x15, 0x60, 0x01, 0xf0, 0x3a, 0xfa, + 0x1d, 0x48, 0x47, 0x60, 0x05, 0x99, 0x01, 0x60, + 0x4a, 0xe7, 0xff, 0xe7, 0x10, 0x21, 0x00, 0xf0, + 0x8f, 0xfc, 0xff, 0x22, 0x05, 0x32, 0x00, 0xf0, + 0x95, 0xfc, 0x46, 0x22, 0x00, 0xf0, 0x92, 0xfc, + 0x0d, 0x22, 0x00, 0xf0, 0x8f, 0xfc, 0x04, 0x22, + 0x00, 0xf0, 0x8c, 0xfc, 0x28, 0x22, 0x00, 0xf0, + 0x89, 0xfc, 0xb1, 0x1c, 0x09, 0x02, 0x20, 0x22, + 0x0a, 0x43, 0x16, 0x49, 0x0a, 0x62, 0x82, 0x22, + 0x2a, 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, + 0xed, 0x09, 0x00, 0x06, 0x01, 0x4a, 0x62, 0x98, + 0xe7, 0x80, 0x23, 0x19, 0x43, 0x09, 0x02, 0x10, + 0x23, 0x19, 0x43, 0x01, 0x62, 0xa3, 0xe7, 0x0a, + 0x4b, 0x3d, 0x20, 0x18, 0x62, 0x3e, 0x20, 0x58, + 0x62, 0xae, 0xe7, 0x10, 0x21, 0x00, 0xf0, 0x62, + 0xfc, 0x02, 0xaa, 0x03, 0xc2, 0x02, 0x98, 0x03, + 0x99, 0xba, 0xe7, 0x00, 0x00, 0x34, 0xf3, 0x03, + 0x20, 0xc4, 0x09, 0x00, 0x00, 0x88, 0xe5, 0x03, + 0x20, 0xc0, 0x55, 0x00, 0xe0, 0x48, 0xe6, 0x03, + 0x20, 0x74, 0x03, 0x04, 0x20, 0x00, 0x51, 0x00, + 0xe0, 0xa0, 0x55, 0x00, 0xe0, 0x02, 0x05, 0x00, + 0x00, 0x08, 0x53, 0x00, 0xe0, 0xb0, 0x55, 0x00, + 0xe0, 0x0c, 0x53, 0x00, 0xe0, 0x02, 0x03, 0x00, + 0x00, 0x10, 0x53, 0x00, 0xe0, 0x70, 0x47, 0x00, + 0xb5, 0x00, 0x20, 0xff, 0xf7, 0xb3, 0xfe, 0x08, + 0xbc, 0x18, 0x47, 0xf1, 0xb5, 0x88, 0xb0, 0xad, + 0x49, 0x48, 0x68, 0x0c, 0x6b, 0xce, 0x6a, 0xac, + 0x4b, 0xc7, 0x18, 0x08, 0x68, 0x85, 0x1c, 0xab, + 0x48, 0x80, 0x6a, 0x42, 0x07, 0x52, 0x0f, 0x05, + 0xab, 0x1a, 0x70, 0x42, 0x06, 0x12, 0x0f, 0x06, + 0x92, 0x02, 0x06, 0xd2, 0x0f, 0x5a, 0x70, 0xc2, + 0x05, 0xd2, 0x0f, 0x9a, 0x70, 0x80, 0x05, 0xc0, + 0x0f, 0xd8, 0x70, 0x17, 0x20, 0xa2, 0x4a, 0x40, + 0x01, 0xd0, 0x60, 0xa2, 0x4a, 0x00, 0x20, 0x10, + 0x60, 0x06, 0x9a, 0x01, 0x2a, 0x08, 0xd0, 0x06, + 0x9a, 0x03, 0x2a, 0x05, 0xd0, 0xff, 0xf7, 0x86, + 0xfe, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x9b, 0x49, 0x00, 0x20, 0x07, 0x91, 0xc8, + 0x60, 0xf1, 0x1d, 0x51, 0x31, 0x0c, 0xc9, 0x99, + 0x48, 0x0c, 0xc0, 0x07, 0x99, 0x8a, 0x68, 0x49, + 0x68, 0x23, 0x69, 0x03, 0x92, 0x18, 0x0e, 0x1a, + 0x02, 0x12, 0x0a, 0x00, 0x92, 0x02, 0x91, 0x00, + 0x21, 0x00, 0x22, 0xed, 0x09, 0x00, 0x07, 0x01, + 0x09, 0x23, 0x01, 0x90, 0x28, 0x1c, 0xf4, 0xf7, + 0x64, 0xfd, 0x04, 0x90, 0x20, 0x69, 0x00, 0x0e, + 0x69, 0x08, 0x09, 0x02, 0x08, 0x43, 0x8d, 0x49, + 0x48, 0x60, 0x8d, 0x49, 0x8a, 0x68, 0xcd, 0x1d, + 0x01, 0x92, 0xca, 0x68, 0xb9, 0x35, 0x02, 0x92, + 0x08, 0x69, 0x03, 0x90, 0x68, 0x69, 0x01, 0x28, + 0x4a, 0xd0, 0x02, 0x28, 0x2c, 0xd1, 0x87, 0x49, + 0x03, 0x20, 0xc8, 0x62, 0x06, 0x21, 0x38, 0x1c, + 0x00, 0xf0, 0xe5, 0xfb, 0xc8, 0x22, 0x00, 0xf0, + 0xda, 0xfb, 0x02, 0x9a, 0x52, 0x00, 0x00, 0xf0, + 0xd6, 0xfb, 0x28, 0x22, 0x00, 0xf0, 0xd3, 0xfb, + 0x03, 0x22, 0x00, 0xf0, 0xe0, 0xfb, 0x04, 0x99, + 0x7d, 0x4a, 0x02, 0x31, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0x11, 0x62, 0x01, 0x99, 0xc9, 0x00, + 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, 0x23, + 0x19, 0x43, 0x51, 0x62, 0x03, 0x99, 0x09, 0x02, + 0x16, 0x23, 0x19, 0x43, 0x91, 0x62, 0x74, 0x49, + 0x08, 0x60, 0x05, 0x20, 0x00, 0x02, 0x08, 0x62, + 0x70, 0x49, 0x72, 0x48, 0x8a, 0x68, 0x6b, 0x69, + 0x01, 0x2b, 0x40, 0xd0, 0x02, 0x2b, 0x06, 0xd1, + 0xd2, 0x00, 0x40, 0x23, 0x1a, 0x43, 0x12, 0x02, + 0x11, 0x23, 0x1a, 0x43, 0x02, 0x62, 0xf8, 0x1d, + 0x5d, 0x30, 0xff, 0x22, 0x6b, 0x4b, 0x02, 0x32, + 0x1a, 0x62, 0x18, 0x60, 0xaa, 0x6a, 0x38, 0x1c, + 0x00, 0x2a, 0x34, 0xd0, 0x05, 0x27, 0x33, 0xe0, + 0x06, 0x21, 0x38, 0x1c, 0x00, 0xf0, 0x9f, 0xfb, + 0xff, 0x22, 0x05, 0x32, 0x00, 0xf0, 0x93, 0xfb, + 0x02, 0x9a, 0x52, 0x00, 0x00, 0xf0, 0x8f, 0xfb, + 0x28, 0x22, 0x00, 0xf0, 0x8c, 0xfb, 0x03, 0x22, + 0x00, 0xf0, 0x99, 0xfb, 0x04, 0x99, 0x02, 0x31, + 0x09, 0x02, 0x20, 0x22, 0x0a, 0x43, 0x57, 0x49, + 0x0a, 0x62, 0x01, 0x9a, 0xd2, 0x00, 0xed, 0x09, + 0x00, 0x08, 0x01, 0x84, 0x23, 0x1a, 0x43, 0x12, + 0x02, 0x10, 0x23, 0x1a, 0x43, 0x4a, 0x62, 0x03, + 0x9a, 0x12, 0x02, 0x19, 0x23, 0x1a, 0x43, 0x8a, + 0x62, 0x51, 0x49, 0x08, 0x60, 0x53, 0x48, 0x08, + 0x62, 0xb8, 0xe7, 0xd2, 0x00, 0x80, 0x23, 0x1a, + 0x43, 0x12, 0x02, 0x10, 0x23, 0x1a, 0x43, 0x02, + 0x62, 0xbf, 0xe7, 0x01, 0x27, 0x69, 0x69, 0x01, + 0x29, 0x27, 0xd0, 0x02, 0x29, 0x02, 0xd1, 0x06, + 0x21, 0x00, 0xf0, 0x67, 0xfb, 0x43, 0x49, 0x88, + 0x60, 0x00, 0x20, 0x0f, 0x60, 0x07, 0x1c, 0xf0, + 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x87, 0x63, 0xf0, + 0x1d, 0xff, 0x30, 0x1a, 0x30, 0xf4, 0xf7, 0xbf, + 0xf8, 0x05, 0x20, 0xe0, 0x60, 0x37, 0x48, 0x81, + 0x68, 0x41, 0x4b, 0x19, 0x40, 0x81, 0x60, 0xd9, + 0x43, 0xc1, 0x60, 0x81, 0x68, 0x01, 0x23, 0x9b, + 0x02, 0x19, 0x43, 0x81, 0x60, 0x00, 0x21, 0x08, + 0x98, 0xf3, 0xf7, 0x07, 0xff, 0x06, 0x1c, 0x08, + 0xd1, 0x23, 0xe7, 0x06, 0x21, 0x00, 0xf0, 0x41, + 0xfb, 0x02, 0xaa, 0x03, 0xc2, 0x02, 0x98, 0x03, + 0x99, 0xd4, 0xe7, 0x2e, 0x49, 0x35, 0x4a, 0x09, + 0x68, 0x10, 0x6a, 0x52, 0x6a, 0x00, 0x0a, 0xff, + 0x23, 0x1b, 0x02, 0x1a, 0x40, 0x10, 0x43, 0x01, + 0x23, 0x6a, 0x69, 0x1b, 0x04, 0x01, 0x2a, 0x38, + 0xd0, 0x02, 0x2a, 0x07, 0xd1, 0x19, 0x1c, 0x02, + 0x0c, 0x00, 0xd2, 0x00, 0x21, 0x08, 0x43, 0x01, + 0x23, 0xdb, 0x03, 0x98, 0x43, 0x07, 0x99, 0x19, + 0x4d, 0x08, 0x60, 0xb0, 0x64, 0xf0, 0x68, 0x03, + 0x28, 0x08, 0xd1, 0x01, 0x20, 0xf0, 0x60, 0xf0, + 0x69, 0x00, 0x28, 0x01, 0xd0, 0xf0, 0xf7, 0x45, + 0xfa, 0xf7, 0x61, 0xb7, 0x61, 0xf0, 0xf7, 0x46, + 0xfa, 0x00, 0x28, 0x0b, 0xd0, 0x42, 0x21, 0x01, + 0x60, 0xe9, 0x6a, 0x49, 0x68, 0xc1, 0x60, 0x04, + 0x61, 0xed, 0x09, 0x00, 0x09, 0x01, 0x21, 0x7e, + 0x41, 0x61, 0x01, 0x1c, 0x0e, 0x20, 0xf0, 0xf7, + 0xa7, 0xfa, 0xf0, 0xf7, 0x36, 0xfa, 0x00, 0x28, + 0x09, 0xd0, 0x35, 0x21, 0x01, 0x60, 0xe9, 0x6a, + 0x49, 0x68, 0xc1, 0x60, 0x06, 0x61, 0x01, 0x1c, + 0x0e, 0x20, 0xf0, 0xf7, 0x99, 0xfa, 0xd3, 0xe6, + 0x00, 0x29, 0x00, 0xd1, 0x00, 0x23, 0x18, 0x43, + 0xcb, 0xe7, 0x00, 0x00, 0x34, 0xf3, 0x03, 0x20, + 0xe2, 0x04, 0x00, 0x00, 0x40, 0x55, 0x00, 0xe0, + 0x00, 0x50, 0x00, 0xe0, 0x00, 0x51, 0x00, 0xe0, + 0x74, 0x03, 0x04, 0x20, 0x90, 0x57, 0x00, 0xe0, + 0x00, 0x52, 0x00, 0xe0, 0x88, 0xe5, 0x03, 0x20, + 0x80, 0x55, 0x00, 0xe0, 0x00, 0x53, 0x00, 0xe0, + 0x90, 0x55, 0x00, 0xe0, 0x04, 0x53, 0x00, 0xe0, + 0x03, 0x05, 0x00, 0x00, 0x03, 0xf8, 0xfd, 0xff, + 0xc0, 0x55, 0x00, 0xe0, 0x90, 0xb5, 0x84, 0xb0, + 0x13, 0x49, 0xcc, 0x6a, 0x0f, 0x6b, 0x13, 0x49, + 0xf8, 0x1d, 0x0a, 0x68, 0xb9, 0x30, 0x82, 0x60, + 0x8a, 0x68, 0xc2, 0x60, 0xca, 0x68, 0x02, 0x61, + 0x0a, 0x69, 0x42, 0x61, 0x49, 0x68, 0x81, 0x61, + 0x00, 0x21, 0x41, 0x62, 0x38, 0x1c, 0xfc, 0xf7, + 0x62, 0xfa, 0x00, 0x22, 0x03, 0x92, 0x01, 0x21, + 0x1a, 0x20, 0x01, 0x90, 0x02, 0x91, 0x02, 0x22, + 0x00, 0x92, 0x21, 0x1c, 0x20, 0x1c, 0x06, 0x23, + 0x3a, 0x1c, 0xf1, 0xf7, 0xad, 0xff, 0x04, 0xb0, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x34, 0xf3, 0x03, 0x20, 0x88, 0xe5, 0x03, 0x20, + 0xf0, 0xb5, 0x85, 0xb0, 0x04, 0x1c, 0x33, 0x48, + 0x33, 0x49, 0xc0, 0x6a, 0x04, 0x90, 0x00, 0x20, + 0x08, 0x63, 0x32, 0x49, 0x32, 0x48, 0xc1, 0x60, + 0x81, 0x68, 0x32, 0x4b, 0x19, 0x40, 0x81, 0x60, + 0xf0, 0xf7, 0xc3, 0xf9, 0x07, 0x1c, 0x08, 0xd1, + 0x00, 0x22, 0x01, 0x20, 0xed, 0x09, 0x00, 0x0a, + 0x01, 0x04, 0x99, 0xf5, 0xf7, 0x49, 0xf9, 0x05, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x21, 0x20, 0x1c, 0xf3, 0xf7, 0x3f, 0xfe, 0x05, + 0x1c, 0x08, 0xd1, 0x38, 0x1c, 0xf0, 0xf7, 0xea, + 0xf9, 0x00, 0x22, 0x01, 0x20, 0x04, 0x99, 0xf5, + 0xf7, 0x37, 0xf9, 0xec, 0xe7, 0x23, 0x48, 0xee, + 0x1d, 0x04, 0x69, 0x45, 0x36, 0xf3, 0xf7, 0xc0, + 0xfb, 0x02, 0x90, 0x21, 0x48, 0x03, 0x91, 0x40, + 0x69, 0x01, 0x28, 0x27, 0xd0, 0x02, 0x28, 0x04, + 0xd1, 0x8e, 0x21, 0x20, 0x1c, 0x00, 0xf0, 0x62, + 0xfa, 0x04, 0x1c, 0x02, 0x98, 0x84, 0x42, 0x02, + 0xd9, 0x03, 0x98, 0x01, 0x38, 0x03, 0x90, 0x03, + 0x99, 0x02, 0x94, 0x71, 0x60, 0x10, 0x48, 0x41, + 0x23, 0x9b, 0x01, 0xc1, 0x18, 0x34, 0x60, 0x09, + 0x68, 0xa9, 0x64, 0x35, 0x21, 0x39, 0x60, 0xc0, + 0x6a, 0x40, 0x68, 0xf8, 0x60, 0x0e, 0x20, 0x39, + 0x1c, 0x3d, 0x61, 0xf0, 0xf7, 0xeb, 0xf9, 0x00, + 0x23, 0x05, 0x22, 0x04, 0x21, 0x04, 0x98, 0xf2, + 0xf7, 0x3d, 0xf8, 0xb8, 0xe7, 0x95, 0x21, 0x20, + 0x1c, 0x00, 0xf0, 0x3c, 0xfa, 0x6a, 0x46, 0x03, + 0xc2, 0x01, 0x99, 0x00, 0x9c, 0xd5, 0xe7, 0x00, + 0x00, 0x34, 0xf3, 0x03, 0x20, 0x00, 0x53, 0x00, + 0xe0, 0x08, 0x01, 0x02, 0x00, 0x00, 0x50, 0x00, + 0xe0, 0xe7, 0xfe, 0xfd, 0xff, 0x00, 0x51, 0x00, + 0xe0, 0x48, 0xe6, 0x03, 0x20, 0xf0, 0xb5, 0x8a, + 0xb0, 0xa7, 0x49, 0xa8, 0x4a, 0xcc, 0x6a, 0x00, + 0x21, 0x11, 0x63, 0xa7, 0x4a, 0xa7, 0x49, 0xca, + 0x60, 0x8a, 0x68, 0xa7, 0x4b, 0x1a, 0x40, 0x8a, + 0x60, 0x00, 0x21, 0xf3, 0xf7, 0xd7, 0xfd, 0x07, + 0x1c, 0x08, 0xd1, 0x00, 0x22, 0x01, 0x20, 0x21, + 0x1c, 0xf5, 0xf7, 0xd2, 0xf8, 0x0a, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x9f, 0x48, 0xed, + 0x09, 0x00, 0x0b, 0x01, 0xfe, 0x1d, 0x05, 0x69, + 0x45, 0x36, 0xf3, 0xf7, 0x58, 0xfb, 0x02, 0x90, + 0x9d, 0x48, 0x03, 0x91, 0x09, 0x90, 0x40, 0x69, + 0x01, 0x28, 0x73, 0xd0, 0x02, 0x28, 0x04, 0xd1, + 0x8e, 0x21, 0x28, 0x1c, 0x00, 0xf0, 0xf9, 0xf9, + 0x05, 0x1c, 0x02, 0x98, 0x85, 0x42, 0x02, 0xd9, + 0x03, 0x98, 0x01, 0x38, 0x03, 0x90, 0x03, 0x99, + 0x02, 0x95, 0x71, 0x60, 0x35, 0x60, 0x03, 0xce, + 0x08, 0x3e, 0x91, 0x4a, 0x00, 0xf0, 0xf1, 0xf9, + 0x05, 0x1c, 0x03, 0xce, 0x8f, 0x4a, 0x00, 0xf0, + 0xec, 0xf9, 0x8e, 0xa3, 0x1a, 0x68, 0x5b, 0x68, + 0x00, 0xf0, 0x4b, 0xf9, 0x06, 0x01, 0x36, 0x09, + 0xb0, 0x08, 0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x91, + 0x88, 0x62, 0x8a, 0x48, 0x07, 0x90, 0x02, 0x1d, + 0x06, 0xca, 0x7e, 0x48, 0x80, 0x6b, 0x02, 0x91, + 0x00, 0x06, 0x00, 0x0e, 0x01, 0x90, 0x7b, 0x48, + 0x03, 0x92, 0x42, 0x6b, 0xe0, 0x1d, 0xff, 0x30, + 0x7a, 0x30, 0x06, 0x90, 0x05, 0x90, 0x00, 0x92, + 0x42, 0x68, 0x05, 0x23, 0x00, 0x21, 0x30, 0x1c, + 0xf4, 0xf7, 0x21, 0xfb, 0x04, 0x90, 0x07, 0x98, + 0x42, 0x68, 0x05, 0x98, 0x41, 0x68, 0x30, 0x1c, + 0xf4, 0xf7, 0xa9, 0xf9, 0x20, 0x23, 0x18, 0x43, + 0x7a, 0x49, 0x00, 0x02, 0x48, 0x60, 0x79, 0x48, + 0x7a, 0x4e, 0x82, 0x68, 0x01, 0x92, 0xc2, 0x68, + 0x02, 0x92, 0x00, 0x69, 0x03, 0x90, 0x09, 0x98, + 0x40, 0x69, 0x01, 0x28, 0x55, 0xd0, 0x02, 0x28, + 0x2c, 0xd1, 0x03, 0x20, 0xf0, 0x62, 0x06, 0x21, + 0x28, 0x1c, 0x00, 0xf0, 0x9e, 0xf9, 0xc8, 0x22, + 0x00, 0xf0, 0x93, 0xf9, 0x02, 0x9a, 0x52, 0x00, + 0x00, 0xf0, 0x8f, 0xf9, 0x28, 0x22, 0x00, 0xf0, + 0x8c, 0xf9, 0x03, 0x22, 0x00, 0xf0, 0x99, 0xf9, + 0x04, 0x99, 0x02, 0x31, 0x09, 0x02, 0x10, 0x23, + 0x19, 0x43, 0xed, 0x09, 0x00, 0x0c, 0x01, 0x00, + 0xe0, 0x30, 0xe0, 0x31, 0x62, 0x01, 0x9a, 0xd1, + 0x00, 0x44, 0x23, 0x19, 0x43, 0x09, 0x02, 0x11, + 0x23, 0x19, 0x43, 0x71, 0x62, 0x03, 0x9a, 0x11, + 0x02, 0x16, 0x23, 0x19, 0x43, 0xb1, 0x62, 0x53, + 0x49, 0x08, 0x60, 0x05, 0x20, 0x00, 0x02, 0x08, + 0x62, 0x5c, 0x48, 0x81, 0x68, 0x09, 0x98, 0x42, + 0x69, 0x5c, 0x48, 0x01, 0x2a, 0x49, 0xd0, 0x02, + 0x2a, 0x06, 0xd1, 0xc9, 0x00, 0x40, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x11, 0x23, 0x19, 0x43, 0x01, + 0x62, 0xe8, 0x1d, 0x5d, 0x30, 0xff, 0x22, 0x55, + 0x49, 0x02, 0x32, 0x0a, 0x62, 0x08, 0x60, 0x09, + 0x99, 0x28, 0x1c, 0x89, 0x6a, 0x00, 0x29, 0x3c, + 0xd0, 0x05, 0x26, 0x3b, 0xe0, 0x95, 0x21, 0x28, + 0x1c, 0x00, 0xf0, 0x55, 0xf9, 0x6a, 0x46, 0x03, + 0xc2, 0x01, 0x99, 0x00, 0x9d, 0x57, 0xe7, 0x06, + 0x21, 0x28, 0x1c, 0x00, 0xf0, 0x4c, 0xf9, 0xff, + 0x22, 0x05, 0x32, 0x00, 0xf0, 0x40, 0xf9, 0x02, + 0x9a, 0x52, 0x00, 0x00, 0xf0, 0x3c, 0xf9, 0x28, + 0x22, 0x00, 0xf0, 0x39, 0xf9, 0x03, 0x22, 0x00, + 0xf0, 0x46, 0xf9, 0x04, 0x99, 0x02, 0x31, 0x09, + 0x02, 0x20, 0x22, 0x0a, 0x43, 0x32, 0x62, 0x01, + 0x9a, 0xd2, 0x00, 0x84, 0x23, 0x1a, 0x43, 0x12, + 0x02, 0x10, 0x23, 0x1a, 0x43, 0x72, 0x62, 0x03, + 0x9a, 0x12, 0x02, 0x19, 0x23, 0x1a, 0x43, 0xb2, + 0x62, 0x2b, 0x49, 0x08, 0x60, 0x39, 0x48, 0x08, + 0x62, 0xae, 0xe7, 0xc9, 0x00, 0x80, 0x23, 0x19, + 0x43, 0x09, 0x02, 0x10, 0x23, 0x19, 0x43, 0x01, + 0x62, 0xb6, 0xe7, 0x01, 0x26, 0x09, 0x99, 0x49, + 0x69, 0x01, 0x29, 0x26, 0xd0, 0x02, 0x29, 0x02, + 0xd1, 0x06, 0x21, 0x00, 0xf0, 0x14, 0xf9, 0x29, + 0x49, 0x88, 0x60, 0x0e, 0x60, 0xe1, 0x1d, 0x00, + 0x20, 0xf9, 0x31, 0x88, 0x61, 0xed, 0x09, 0x00, + 0x0d, 0x01, 0x08, 0x98, 0xf3, 0xf7, 0x70, 0xfe, + 0x06, 0x98, 0x40, 0x68, 0x06, 0x99, 0x01, 0x30, + 0x48, 0x60, 0xe1, 0x1d, 0x03, 0x20, 0x79, 0x31, + 0xc9, 0x6b, 0x88, 0x62, 0xe0, 0x60, 0xf0, 0xf7, + 0x32, 0xf8, 0x00, 0x28, 0x10, 0xd1, 0x38, 0x1c, + 0xf0, 0xf7, 0x8e, 0xf8, 0x00, 0x22, 0x01, 0x20, + 0x21, 0x1c, 0xf4, 0xf7, 0xb5, 0xff, 0xe1, 0xe6, + 0x06, 0x21, 0x00, 0xf0, 0xef, 0xf8, 0x02, 0xaa, + 0x03, 0xc2, 0x02, 0x98, 0x03, 0x99, 0xd5, 0xe7, + 0x07, 0x9a, 0x09, 0x49, 0x12, 0x68, 0xba, 0x64, + 0x35, 0x22, 0x02, 0x60, 0xc9, 0x6a, 0x49, 0x68, + 0xc1, 0x60, 0x07, 0x61, 0x01, 0x1c, 0x0e, 0x20, + 0xf0, 0xf7, 0x80, 0xf8, 0x00, 0x22, 0x01, 0x20, + 0x21, 0x1c, 0xf4, 0xf7, 0x99, 0xff, 0xc5, 0xe6, + 0x34, 0xf3, 0x03, 0x20, 0x00, 0x53, 0x00, 0xe0, + 0x08, 0x01, 0x02, 0x00, 0x00, 0x50, 0x00, 0xe0, + 0xe7, 0xfe, 0xfd, 0xff, 0x00, 0x51, 0x00, 0xe0, + 0x48, 0xe6, 0x03, 0x20, 0xe2, 0x04, 0x00, 0x00, + 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x03, 0x04, 0x20, 0x00, 0x52, 0x00, 0xe0, + 0x88, 0xe5, 0x03, 0x20, 0x80, 0x55, 0x00, 0xe0, + 0x90, 0x55, 0x00, 0xe0, 0x04, 0x53, 0x00, 0xe0, + 0x03, 0x05, 0x00, 0x00, 0x78, 0x47, 0x00, 0x00, + 0x02, 0x00, 0x50, 0xe0, 0x03, 0x00, 0x51, 0x01, + 0x01, 0x00, 0xa0, 0x13, 0x1e, 0xff, 0x2f, 0xe1, + 0x78, 0x47, 0x00, 0x00, 0x20, 0x30, 0x52, 0xe2, + 0x04, 0x00, 0x00, 0x5a, 0x20, 0x30, 0x62, 0xe2, + 0x30, 0x02, 0xa0, 0xe1, 0x11, 0x03, 0x80, 0xe1, + 0x31, 0x12, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, + 0x31, 0x03, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, + 0x1e, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0x00, 0x00, + 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, + 0xed, 0x09, 0x00, 0x0e, 0x01, 0x01, 0x50, 0xa0, + 0xe1, 0x02, 0x60, 0xa0, 0xe1, 0x03, 0xe0, 0xa0, + 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, + 0xe3, 0x05, 0x30, 0xa0, 0xe1, 0x04, 0x20, 0xa0, + 0xe1, 0x00, 0x00, 0x3e, 0xe3, 0x00, 0x00, 0x36, + 0x03, 0x14, 0x00, 0x00, 0x0a, 0x00, 0xc0, 0xb0, + 0xe3, 0x06, 0x60, 0x96, 0xe0, 0x0e, 0xe0, 0xbe, + 0xe0, 0x04, 0x00, 0x00, 0x2a, 0x03, 0x00, 0x5e, + 0xe1, 0x02, 0x00, 0x56, 0x01, 0x01, 0xc0, 0x8c, + 0x92, 0xf8, 0xff, 0xff, 0x9a, 0x00, 0xc0, 0x9c, + 0xe2, 0x6e, 0xe0, 0xb0, 0xe1, 0x66, 0x60, 0xa0, + 0xe1, 0x06, 0x40, 0x52, 0xe0, 0x0e, 0x50, 0xd3, + 0xe0, 0x05, 0x30, 0xa0, 0x21, 0x04, 0x20, 0xa0, + 0x21, 0x00, 0x00, 0xb0, 0xe0, 0x01, 0x10, 0xa1, + 0xe0, 0xae, 0xe0, 0xb0, 0xe1, 0x66, 0x60, 0xa0, + 0xe1, 0x01, 0xc0, 0x5c, 0xe2, 0xf5, 0xff, 0xff, + 0xaa, 0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, + 0xe1, 0x78, 0x47, 0x00, 0x00, 0x03, 0x00, 0x51, + 0xe1, 0x02, 0x00, 0x50, 0x01, 0x01, 0x00, 0xa0, + 0x83, 0x00, 0x00, 0xa0, 0x93, 0x1e, 0xff, 0x2f, + 0xe1, 0x78, 0x47, 0x00, 0x00, 0x03, 0x00, 0x51, + 0xe1, 0x02, 0x00, 0x50, 0x01, 0x01, 0x00, 0xa0, + 0x93, 0x00, 0x00, 0xa0, 0x83, 0x1e, 0xff, 0x2f, + 0xe1, 0x78, 0x47, 0x00, 0x00, 0x03, 0x00, 0x51, + 0xe1, 0x02, 0x00, 0x50, 0x01, 0x01, 0x00, 0xa0, + 0x23, 0x00, 0x00, 0xa0, 0x33, 0x1e, 0xff, 0x2f, + 0xe1, 0x78, 0x47, 0x00, 0x00, 0x20, 0x30, 0x52, + 0xe2, 0x04, 0x00, 0x00, 0x5a, 0x20, 0x30, 0x62, + 0xe2, 0x11, 0x12, 0xa0, 0xe1, 0x30, 0x13, 0x81, + 0xe1, 0x10, 0x02, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, + 0xe1, 0x10, 0x13, 0xa0, 0xe1, 0x00, 0x00, 0xa0, + 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0x00, + 0x00, 0x00, 0x20, 0xed, 0x09, 0x00, 0x0f, 0x01, + 0xa0, 0xe3, 0x01, 0x00, 0x90, 0xe0, 0x00, 0x10, + 0xa2, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x78, 0x47, + 0x00, 0x00, 0x02, 0x00, 0x50, 0xe0, 0x00, 0x10, + 0xc1, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x78, 0x47, + 0x00, 0x00, 0x01, 0x00, 0x50, 0xe0, 0x01, 0x10, + 0xc1, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x78, 0x47, + 0x00, 0x00, 0x02, 0x00, 0x90, 0xe0, 0x00, 0x10, + 0xa1, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x78, 0x47, + 0x00, 0x00, 0x03, 0x00, 0x51, 0xe1, 0x02, 0x00, + 0x50, 0x01, 0x01, 0x00, 0xa0, 0x33, 0x00, 0x00, + 0xa0, 0x23, 0x1e, 0xff, 0x2f, 0xe1, 0x78, 0x47, + 0x00, 0x00, 0x02, 0x21, 0x10, 0xe2, 0x00, 0x00, + 0x60, 0x42, 0x41, 0x30, 0x32, 0xe0, 0x00, 0x10, + 0x61, 0x22, 0xa1, 0xc1, 0x70, 0xe0, 0x20, 0x00, + 0x00, 0x3a, 0x21, 0xc4, 0x70, 0xe0, 0x0f, 0x00, + 0x00, 0x3a, 0x00, 0x04, 0xa0, 0xe1, 0xff, 0x24, + 0x82, 0xe3, 0x21, 0xc2, 0x70, 0xe0, 0x17, 0x00, + 0x00, 0x3a, 0x21, 0xc4, 0x70, 0xe0, 0x09, 0x00, + 0x00, 0x3a, 0x00, 0x04, 0xa0, 0xe1, 0xff, 0x28, + 0x82, 0xe3, 0x21, 0xc4, 0x70, 0xe0, 0x00, 0x04, + 0xa0, 0x21, 0xff, 0x2c, 0x82, 0x23, 0x21, 0xc2, + 0x70, 0xe0, 0x0e, 0x00, 0x00, 0x3a, 0x00, 0xc0, + 0x70, 0xe2, 0x7a, 0xbe, 0xff, 0x2a, 0x20, 0x04, + 0xa0, 0x21, 0xa1, 0xc3, 0x70, 0xe0, 0x80, 0x13, + 0x41, 0x20, 0x02, 0x20, 0xa2, 0xe0, 0x21, 0xc3, + 0x70, 0xe0, 0x00, 0x13, 0x41, 0x20, 0x02, 0x20, + 0xa2, 0xe0, 0xa1, 0xc2, 0x70, 0xe0, 0x80, 0x12, + 0x41, 0x20, 0x02, 0x20, 0xa2, 0xe0, 0x21, 0xc2, + 0x70, 0xe0, 0x00, 0x12, 0x41, 0x20, 0x02, 0x20, + 0xa2, 0xe0, 0xa1, 0xc1, 0x70, 0xe0, 0x80, 0x11, + 0x41, 0x20, 0x02, 0x20, 0xa2, 0xe0, 0x21, 0xc1, + 0x70, 0xe0, 0x00, 0x11, 0x41, 0x20, 0xed, 0x09, + 0x00, 0x10, 0x01, 0x02, 0x20, 0xa2, 0xe0, 0xa1, + 0xc0, 0x70, 0xe0, 0x80, 0x10, 0x41, 0x20, 0x02, + 0x20, 0xa2, 0xe0, 0x01, 0xc0, 0x70, 0xe0, 0x00, + 0x10, 0x41, 0x20, 0x02, 0x20, 0xb2, 0xe0, 0xe5, + 0xff, 0xff, 0x2a, 0xc3, 0x0f, 0x32, 0xe0, 0xa3, + 0x0f, 0x80, 0xe0, 0x00, 0x10, 0x61, 0x22, 0x1e, + 0xff, 0x2f, 0xe1, 0x78, 0x47, 0x00, 0x00, 0x02, + 0x00, 0x90, 0xe0, 0xc2, 0x1f, 0xa1, 0xe0, 0x1e, + 0xff, 0x2f, 0xe1, 0x78, 0x47, 0x00, 0x00, 0x20, + 0x30, 0x52, 0xe2, 0x04, 0x00, 0x00, 0x5a, 0x20, + 0x30, 0x62, 0xe2, 0x30, 0x02, 0xa0, 0xe1, 0x11, + 0x03, 0x80, 0xe1, 0x51, 0x12, 0xa0, 0xe1, 0x1e, + 0xff, 0x2f, 0xe1, 0x51, 0x03, 0xa0, 0xe1, 0xc1, + 0x1f, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x78, + 0x47, 0x00, 0x00, 0xf0, 0x40, 0x2d, 0xe9, 0x02, + 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1, 0x00, + 0x60, 0xa0, 0xe1, 0x01, 0x70, 0xa0, 0xe1, 0x1d, + 0x00, 0x00, 0xea, 0x78, 0x47, 0x00, 0x00, 0xc2, + 0x3f, 0xa0, 0xe1, 0x52, 0xbe, 0xff, 0xea, 0x78, + 0x47, 0x00, 0x00, 0x02, 0x00, 0x70, 0xe0, 0x03, + 0x10, 0xe1, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x78, + 0x47, 0x00, 0x00, 0x03, 0x00, 0x51, 0xe1, 0x01, + 0x00, 0xa0, 0xc3, 0x00, 0x00, 0xa0, 0xb3, 0x1e, + 0xff, 0x2f, 0x11, 0x02, 0x00, 0x50, 0xe1, 0x01, + 0x00, 0xa0, 0x83, 0x00, 0x00, 0xa0, 0x93, 0x1e, + 0xff, 0x2f, 0xe1, 0x78, 0x47, 0x00, 0x00, 0x01, + 0x00, 0x70, 0xe0, 0x01, 0x10, 0xe1, 0xe0, 0x1e, + 0xff, 0x2f, 0xe1, 0x78, 0x47, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xe2, 0x00, 0x10, 0xe1, 0xe2, 0x1e, + 0xff, 0x2f, 0xe1, 0x78, 0x47, 0x00, 0x00, 0xf0, + 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, + 0x50, 0xa0, 0xe1, 0x02, 0x60, 0xa0, 0xe1, 0x03, + 0x70, 0xed, 0x09, 0x00, 0x11, 0x01, 0xa0, 0xe1, + 0x02, 0xc1, 0x17, 0xe2, 0x01, 0x00, 0x00, 0x5a, + 0x00, 0x60, 0x76, 0xe2, 0x00, 0x70, 0xe7, 0xe2, + 0x45, 0xc0, 0x3c, 0xe0, 0x01, 0x00, 0x00, 0x3a, + 0x00, 0x40, 0x74, 0xe2, 0x00, 0x50, 0xe5, 0xe2, + 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, + 0x05, 0x30, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, + 0x00, 0x00, 0x37, 0xe3, 0x00, 0x00, 0x36, 0x03, + 0x14, 0x00, 0x00, 0x0a, 0x00, 0xe0, 0xb0, 0xe3, + 0x06, 0x60, 0x96, 0xe0, 0x07, 0x70, 0xb7, 0xe0, + 0x04, 0x00, 0x00, 0x2a, 0x03, 0x00, 0x57, 0xe1, + 0x02, 0x00, 0x56, 0x01, 0x01, 0xe0, 0x8e, 0x92, + 0xf8, 0xff, 0xff, 0x9a, 0x00, 0xe0, 0x9e, 0xe2, + 0x67, 0x70, 0xb0, 0xe1, 0x66, 0x60, 0xa0, 0xe1, + 0x06, 0x40, 0x52, 0xe0, 0x07, 0x50, 0xd3, 0xe0, + 0x05, 0x30, 0xa0, 0x21, 0x04, 0x20, 0xa0, 0x21, + 0x00, 0x00, 0xb0, 0xe0, 0x01, 0x10, 0xa1, 0xe0, + 0xa7, 0x70, 0xb0, 0xe1, 0x66, 0x60, 0xa0, 0xe1, + 0x01, 0xe0, 0x5e, 0xe2, 0xf5, 0xff, 0xff, 0xaa, + 0x8c, 0xc0, 0xb0, 0xe1, 0x01, 0x00, 0x00, 0x3a, + 0x00, 0x00, 0x70, 0xe2, 0x00, 0x10, 0xe1, 0xe2, + 0x8c, 0xc0, 0xb0, 0xe1, 0x01, 0x00, 0x00, 0x3a, + 0x00, 0x20, 0x72, 0xe2, 0x00, 0x30, 0xe3, 0xe2, + 0xf0, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x12, + 0x01, 0x09, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, + 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, + 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, + 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, + 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, + 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, + 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, + 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, + 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, + 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, + 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, + 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, + 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, + 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, + 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, + 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, + 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, + 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, + 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, + 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, + 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, + 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, + 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, + 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0xed, + 0x09, 0x00, 0x13, 0x01, 0x5d, 0xdd, 0x3d, 0xbd, + 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, + 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, + 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, + 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, + 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, + 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, + 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, + 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, + 0x7f, 0xff, 0x50, 0xfd, 0x70, 0xfd, 0x10, 0xfd, + 0x30, 0xfd, 0xd0, 0xfd, 0xf0, 0xfd, 0x90, 0xfd, + 0xb0, 0xfd, 0x50, 0xfc, 0x70, 0xfc, 0x10, 0xfc, + 0x30, 0xfc, 0xd0, 0xfc, 0xf0, 0xfc, 0x90, 0xfc, + 0xb0, 0xfc, 0xa8, 0xfe, 0xb8, 0xfe, 0x88, 0xfe, + 0x98, 0xfe, 0xe8, 0xfe, 0xf8, 0xfe, 0xc8, 0xfe, + 0xd8, 0xfe, 0x28, 0xfe, 0x38, 0xfe, 0x08, 0xfe, + 0x18, 0xfe, 0x68, 0xfe, 0x78, 0xfe, 0x48, 0xfe, + 0x58, 0xfe, 0x40, 0xf5, 0xc0, 0xf5, 0x40, 0xf4, + 0xc0, 0xf4, 0x40, 0xf7, 0xc0, 0xf7, 0x40, 0xf6, + 0xc0, 0xf6, 0x40, 0xf1, 0xc0, 0xf1, 0x40, 0xf0, + 0xc0, 0xf0, 0x40, 0xf3, 0xc0, 0xf3, 0x40, 0xf2, + 0xc0, 0xf2, 0xa0, 0xfa, 0xe0, 0xfa, 0x20, 0xfa, + 0x60, 0xfa, 0xa0, 0xfb, 0xe0, 0xfb, 0x20, 0xfb, + 0x60, 0xfb, 0xa0, 0xf8, 0xe0, 0xf8, 0x20, 0xf8, + 0x60, 0xf8, 0xa0, 0xf9, 0xe0, 0xf9, 0x20, 0xf9, + 0x60, 0xf9, 0xd5, 0xff, 0xd7, 0xff, 0xd1, 0xff, + 0xd3, 0xff, 0xdd, 0xff, 0xdf, 0xff, 0xd9, 0xff, + 0xdb, 0xff, 0xc5, 0xff, 0xc7, 0xff, 0xc1, 0xff, + 0xc3, 0xff, 0xcd, 0xff, 0xcf, 0xff, 0xc9, 0xff, + 0xcb, 0xff, 0xf5, 0xff, 0xf7, 0xff, 0xf1, 0xff, + 0xf3, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xf9, 0xff, + 0xfb, 0xff, 0xe5, 0xff, 0xe7, 0xff, 0xe1, 0xff, + 0xe3, 0xff, 0xed, 0x09, 0x00, 0x14, 0x01, 0xed, + 0xff, 0xef, 0xff, 0xe9, 0xff, 0xeb, 0xff, 0x54, + 0xff, 0x5c, 0xff, 0x44, 0xff, 0x4c, 0xff, 0x74, + 0xff, 0x7c, 0xff, 0x64, 0xff, 0x6c, 0xff, 0x14, + 0xff, 0x1c, 0xff, 0x04, 0xff, 0x0c, 0xff, 0x34, + 0xff, 0x3c, 0xff, 0x24, 0xff, 0x2c, 0xff, 0xaa, + 0xff, 0xae, 0xff, 0xa2, 0xff, 0xa6, 0xff, 0xba, + 0xff, 0xbe, 0xff, 0xb2, 0xff, 0xb6, 0xff, 0x8a, + 0xff, 0x8e, 0xff, 0x82, 0xff, 0x86, 0xff, 0x9a, + 0xff, 0x9e, 0xff, 0x92, 0xff, 0x96, 0xff, 0xb0, + 0x02, 0x90, 0x02, 0xf0, 0x02, 0xd0, 0x02, 0x30, + 0x02, 0x10, 0x02, 0x70, 0x02, 0x50, 0x02, 0xb0, + 0x03, 0x90, 0x03, 0xf0, 0x03, 0xd0, 0x03, 0x30, + 0x03, 0x10, 0x03, 0x70, 0x03, 0x50, 0x03, 0x58, + 0x01, 0x48, 0x01, 0x78, 0x01, 0x68, 0x01, 0x18, + 0x01, 0x08, 0x01, 0x38, 0x01, 0x28, 0x01, 0xd8, + 0x01, 0xc8, 0x01, 0xf8, 0x01, 0xe8, 0x01, 0x98, + 0x01, 0x88, 0x01, 0xb8, 0x01, 0xa8, 0x01, 0xc0, + 0x0a, 0x40, 0x0a, 0xc0, 0x0b, 0x40, 0x0b, 0xc0, + 0x08, 0x40, 0x08, 0xc0, 0x09, 0x40, 0x09, 0xc0, + 0x0e, 0x40, 0x0e, 0xc0, 0x0f, 0x40, 0x0f, 0xc0, + 0x0c, 0x40, 0x0c, 0xc0, 0x0d, 0x40, 0x0d, 0x60, + 0x05, 0x20, 0x05, 0xe0, 0x05, 0xa0, 0x05, 0x60, + 0x04, 0x20, 0x04, 0xe0, 0x04, 0xa0, 0x04, 0x60, + 0x07, 0x20, 0x07, 0xe0, 0x07, 0xa0, 0x07, 0x60, + 0x06, 0x20, 0x06, 0xe0, 0x06, 0xa0, 0x06, 0x2b, + 0x00, 0x29, 0x00, 0x2f, 0x00, 0x2d, 0x00, 0x23, + 0x00, 0x21, 0x00, 0x27, 0x00, 0x25, 0x00, 0x3b, + 0x00, 0x39, 0x00, 0x3f, 0x00, 0x3d, 0x00, 0x33, + 0x00, 0x31, 0x00, 0x37, 0x00, 0x35, 0x00, 0x0b, + 0x00, 0x09, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0x03, + 0x00, 0x01, 0x00, 0x07, 0x00, 0x05, 0x00, 0x1b, + 0x00, 0x19, 0x00, 0x1f, 0x00, 0xed, 0x09, 0x00, + 0x15, 0x01, 0x1d, 0x00, 0x13, 0x00, 0x11, 0x00, + 0x17, 0x00, 0x15, 0x00, 0xac, 0x00, 0xa4, 0x00, + 0xbc, 0x00, 0xb4, 0x00, 0x8c, 0x00, 0x84, 0x00, + 0x9c, 0x00, 0x94, 0x00, 0xec, 0x00, 0xe4, 0x00, + 0xfc, 0x00, 0xf4, 0x00, 0xcc, 0x00, 0xc4, 0x00, + 0xdc, 0x00, 0xd4, 0x00, 0x56, 0x00, 0x52, 0x00, + 0x5e, 0x00, 0x5a, 0x00, 0x46, 0x00, 0x42, 0x00, + 0x4e, 0x00, 0x4a, 0x00, 0x76, 0x00, 0x72, 0x00, + 0x7e, 0x00, 0x7a, 0x00, 0x66, 0x00, 0x62, 0x00, + 0x6e, 0x00, 0x6a, 0x00, 0xa1, 0xe0, 0xa1, 0xe1, + 0xa1, 0xe2, 0xa1, 0xe3, 0xa1, 0xe4, 0xa1, 0xe5, + 0xa1, 0xe6, 0xa1, 0xe7, 0xa1, 0xe8, 0xa1, 0xe9, + 0xa1, 0xea, 0xa1, 0xeb, 0xa1, 0xec, 0xa1, 0xed, + 0xa1, 0xee, 0xa1, 0xef, 0x61, 0xf0, 0xe1, 0xf0, + 0x61, 0xf1, 0xe1, 0xf1, 0x61, 0xf2, 0xe1, 0xf2, + 0x61, 0xf3, 0xe1, 0xf3, 0x61, 0xf4, 0xe1, 0xf4, + 0x61, 0xf5, 0xe1, 0xf5, 0x61, 0xf6, 0xe1, 0xf6, + 0x61, 0xf7, 0xe1, 0xf7, 0x41, 0xf8, 0x81, 0xf8, + 0xc1, 0xf8, 0x01, 0xf9, 0x41, 0xf9, 0x81, 0xf9, + 0xc1, 0xf9, 0x01, 0xfa, 0x41, 0xfa, 0x81, 0xfa, + 0xc1, 0xfa, 0x01, 0xfb, 0x41, 0xfb, 0x81, 0xfb, + 0xc1, 0xfb, 0x01, 0xfc, 0x31, 0xfc, 0x51, 0xfc, + 0x71, 0xfc, 0x91, 0xfc, 0xb1, 0xfc, 0xd1, 0xfc, + 0xf1, 0xfc, 0x11, 0xfd, 0x31, 0xfd, 0x51, 0xfd, + 0x71, 0xfd, 0x91, 0xfd, 0xb1, 0xfd, 0xd1, 0xfd, + 0xf1, 0xfd, 0x11, 0xfe, 0x29, 0xfe, 0x39, 0xfe, + 0x49, 0xfe, 0x59, 0xfe, 0x69, 0xfe, 0x79, 0xfe, + 0x89, 0xfe, 0x99, 0xfe, 0xa9, 0xfe, 0xb9, 0xfe, + 0xc9, 0xfe, 0xd9, 0xfe, 0xe9, 0xfe, 0xf9, 0xfe, + 0x09, 0xff, 0x19, 0xff, 0x25, 0xff, 0x2d, 0xff, + 0x35, 0xff, 0x3d, 0xff, 0x45, 0xff, 0x4d, 0xff, + 0x55, 0xff, 0x5d, 0xff, 0x65, 0xff, 0x6d, 0xff, + 0xed, 0x09, 0x00, 0x16, 0x01, 0x75, 0xff, 0x7d, + 0xff, 0x85, 0xff, 0x8d, 0xff, 0x95, 0xff, 0x9d, + 0xff, 0xa3, 0xff, 0xa7, 0xff, 0xab, 0xff, 0xaf, + 0xff, 0xb3, 0xff, 0xb7, 0xff, 0xbb, 0xff, 0xbf, + 0xff, 0xc3, 0xff, 0xc7, 0xff, 0xcb, 0xff, 0xcf, + 0xff, 0xd3, 0xff, 0xd7, 0xff, 0xdb, 0xff, 0xdf, + 0xff, 0xe2, 0xff, 0xe4, 0xff, 0xe6, 0xff, 0xe8, + 0xff, 0xea, 0xff, 0xec, 0xff, 0xee, 0xff, 0xf0, + 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf6, 0xff, 0xf8, + 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0x00, + 0x00, 0x5f, 0x1f, 0x5f, 0x1e, 0x5f, 0x1d, 0x5f, + 0x1c, 0x5f, 0x1b, 0x5f, 0x1a, 0x5f, 0x19, 0x5f, + 0x18, 0x5f, 0x17, 0x5f, 0x16, 0x5f, 0x15, 0x5f, + 0x14, 0x5f, 0x13, 0x5f, 0x12, 0x5f, 0x11, 0x5f, + 0x10, 0x9f, 0x0f, 0x1f, 0x0f, 0x9f, 0x0e, 0x1f, + 0x0e, 0x9f, 0x0d, 0x1f, 0x0d, 0x9f, 0x0c, 0x1f, + 0x0c, 0x9f, 0x0b, 0x1f, 0x0b, 0x9f, 0x0a, 0x1f, + 0x0a, 0x9f, 0x09, 0x1f, 0x09, 0x9f, 0x08, 0x1f, + 0x08, 0xbf, 0x07, 0x7f, 0x07, 0x3f, 0x07, 0xff, + 0x06, 0xbf, 0x06, 0x7f, 0x06, 0x3f, 0x06, 0xff, + 0x05, 0xbf, 0x05, 0x7f, 0x05, 0x3f, 0x05, 0xff, + 0x04, 0xbf, 0x04, 0x7f, 0x04, 0x3f, 0x04, 0xff, + 0x03, 0xcf, 0x03, 0xaf, 0x03, 0x8f, 0x03, 0x6f, + 0x03, 0x4f, 0x03, 0x2f, 0x03, 0x0f, 0x03, 0xef, + 0x02, 0xcf, 0x02, 0xaf, 0x02, 0x8f, 0x02, 0x6f, + 0x02, 0x4f, 0x02, 0x2f, 0x02, 0x0f, 0x02, 0xef, + 0x01, 0xd7, 0x01, 0xc7, 0x01, 0xb7, 0x01, 0xa7, + 0x01, 0x97, 0x01, 0x87, 0x01, 0x77, 0x01, 0x67, + 0x01, 0x57, 0x01, 0x47, 0x01, 0x37, 0x01, 0x27, + 0x01, 0x17, 0x01, 0x07, 0x01, 0xf7, 0x00, 0xe7, + 0x00, 0xdb, 0x00, 0xd3, 0x00, 0xcb, 0x00, 0xc3, + 0x00, 0xbb, 0x00, 0xb3, 0x00, 0xab, 0x00, 0xa3, + 0x00, 0x9b, 0x00, 0xed, 0x09, 0x00, 0x17, 0x01, + 0x93, 0x00, 0x8b, 0x00, 0x83, 0x00, 0x7b, 0x00, + 0x73, 0x00, 0x6b, 0x00, 0x63, 0x00, 0x5d, 0x00, + 0x59, 0x00, 0x55, 0x00, 0x51, 0x00, 0x4d, 0x00, + 0x49, 0x00, 0x45, 0x00, 0x41, 0x00, 0x3d, 0x00, + 0x39, 0x00, 0x35, 0x00, 0x31, 0x00, 0x2d, 0x00, + 0x29, 0x00, 0x25, 0x00, 0x21, 0x00, 0x1e, 0x00, + 0x1c, 0x00, 0x1a, 0x00, 0x18, 0x00, 0x16, 0x00, + 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x0e, 0x00, + 0x0c, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, + 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x01, 0x20, + 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, + 0x70, 0x47, 0xb0, 0xb5, 0x1a, 0x4c, 0x01, 0x25, + 0x1a, 0x48, 0x25, 0x60, 0x07, 0x69, 0x38, 0x09, + 0x02, 0xd3, 0x08, 0x20, 0x01, 0xf0, 0x8f, 0xfc, + 0xf8, 0x0a, 0x02, 0xd3, 0x02, 0x20, 0x01, 0xf0, + 0x8a, 0xfc, 0x78, 0x0a, 0x02, 0xd3, 0xed, 0x09, + 0x00, 0x18, 0x01, 0x03, 0x20, 0x01, 0xf0, 0x85, + 0xfc, 0x38, 0x09, 0x00, 0x07, 0x02, 0xd0, 0x04, + 0x20, 0x01, 0xf0, 0x7f, 0xfc, 0xf8, 0x08, 0x02, + 0xd3, 0x06, 0x20, 0x01, 0xf0, 0x7a, 0xfc, 0xb8, + 0x08, 0x02, 0xd3, 0x01, 0x20, 0x01, 0xf0, 0x75, + 0xfc, 0x78, 0x08, 0x02, 0xd3, 0x07, 0x20, 0x01, + 0xf0, 0x70, 0xfc, 0xb8, 0x0a, 0x03, 0xd3, 0x06, + 0x48, 0x05, 0x62, 0x24, 0xf0, 0x40, 0xf9, 0x00, + 0x20, 0x20, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x70, 0x65, 0x03, 0x20, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xd0, 0x80, + 0xb5, 0x18, 0x48, 0x07, 0x69, 0xf8, 0x0e, 0x02, + 0xd3, 0x02, 0x20, 0x01, 0xf0, 0x56, 0xfc, 0x78, + 0x0e, 0x02, 0xd3, 0x03, 0x20, 0x01, 0xf0, 0x51, + 0xfc, 0x38, 0x0d, 0x00, 0x07, 0x02, 0xd0, 0x04, + 0x20, 0x01, 0xf0, 0x4b, 0xfc, 0x38, 0x0d, 0x02, + 0xd3, 0x05, 0x20, 0x01, 0xf0, 0x46, 0xfc, 0xf8, + 0x0c, 0x02, 0xd3, 0x06, 0x20, 0x01, 0xf0, 0x41, + 0xfc, 0xb8, 0x0c, 0x02, 0xd3, 0x01, 0x20, 0x01, + 0xf0, 0x3c, 0xfc, 0x78, 0x0c, 0x02, 0xd3, 0x07, + 0x20, 0x01, 0xf0, 0x37, 0xfc, 0xb8, 0x0e, 0x04, + 0xd3, 0x05, 0x49, 0x01, 0x20, 0x08, 0x62, 0x24, + 0xf0, 0x06, 0xf9, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, + 0x00, 0x00, 0xd0, 0x00, 0x00, 0xa0, 0xe3, 0x10, + 0x0f, 0x01, 0xee, 0x19, 0x00, 0xa0, 0xe3, 0x17, + 0x0f, 0x06, 0xee, 0x1f, 0x00, 0xa0, 0xe3, 0x16, + 0x0f, 0x06, 0xee, 0xa2, 0x02, 0x80, 0xe2, 0x15, + 0x0f, 0x06, 0xee, 0x01, 0x00, 0x40, 0xe2, 0x14, + 0x0f, 0x06, 0xee, 0x13, 0x0f, 0x06, 0xee, 0x9d, + 0x02, 0xa0, 0xe3, 0x10, 0x00, 0x80, 0xe2, 0x12, + 0x0f, 0x06, 0xee, 0x81, 0x02, 0x80, 0xe2, 0x11, + 0x0f, 0xed, 0x09, 0x00, 0x19, 0x01, 0x06, 0xee, + 0x0e, 0x02, 0xa0, 0xe3, 0x20, 0x00, 0x80, 0xe2, + 0x10, 0x0f, 0x06, 0xee, 0xc0, 0x07, 0xe0, 0xe1, + 0x10, 0x0f, 0x05, 0xee, 0x3f, 0x0d, 0xa0, 0xe3, + 0x10, 0x0f, 0x02, 0xee, 0xff, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x04, 0xee, 0x00, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x03, 0xee, 0x03, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x07, 0xee, 0x0f, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x01, 0xee, 0x1e, 0xff, 0x2f, 0xe1, + 0x00, 0x00, 0xa0, 0xe3, 0x10, 0x0f, 0x01, 0xee, + 0x10, 0x0f, 0x03, 0xee, 0x03, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x07, 0xee, 0x1e, 0xff, 0x2f, 0xe1, + 0x00, 0x00, 0xa0, 0xe3, 0x10, 0x0f, 0x01, 0xee, + 0x10, 0x0f, 0x03, 0xee, 0x03, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x07, 0xee, 0x01, 0x09, 0xa0, 0xe3, + 0x01, 0x00, 0x40, 0xe2, 0x10, 0x0f, 0x05, 0xee, + 0x3f, 0x0d, 0xa0, 0xe3, 0x10, 0x0f, 0x02, 0xee, + 0x0f, 0x00, 0xa0, 0xe3, 0x10, 0x0f, 0x01, 0xee, + 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x01, 0xee, 0x10, 0x0f, 0x03, 0xee, + 0x03, 0x00, 0xa0, 0xe3, 0x10, 0x0f, 0x07, 0xee, + 0x01, 0x09, 0xa0, 0xe3, 0x01, 0x00, 0x40, 0xe2, + 0x10, 0x0f, 0x05, 0xee, 0x3f, 0x0d, 0xa0, 0xe3, + 0x10, 0x0f, 0x02, 0xee, 0x0f, 0x00, 0xa0, 0xe3, + 0x10, 0x0f, 0x01, 0xee, 0x1e, 0xff, 0x2f, 0xe1, + 0x10, 0x0f, 0x18, 0xee, 0x1e, 0xff, 0x2f, 0xe1, + 0x07, 0x48, 0x02, 0x21, 0x41, 0x62, 0x00, 0x21, + 0x01, 0x63, 0x06, 0x4a, 0xc2, 0x62, 0x81, 0x62, + 0x09, 0x21, 0x81, 0x63, 0x03, 0x21, 0x41, 0x63, + 0x01, 0x21, 0x41, 0x62, 0x01, 0x62, 0x70, 0x47, + 0x00, 0x00, 0x00, 0xd0, 0x7f, 0xbb, 0x00, 0x00, + 0x07, 0x48, 0x02, 0x21, 0x41, 0x60, 0x00, 0x21, + 0x01, 0x61, 0x06, 0x4a, 0xed, 0x09, 0x00, 0x1a, + 0x01, 0xc2, 0x60, 0x81, 0x60, 0x41, 0x61, 0x81, + 0x61, 0x01, 0x22, 0x42, 0x60, 0x02, 0x60, 0x08, + 0x1c, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0x7f, 0xbb, 0x00, 0x00, 0x00, 0xb5, 0x03, + 0x48, 0x01, 0x69, 0x30, 0x20, 0xee, 0xf7, 0x38, + 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, + 0xd0, 0x01, 0x48, 0x80, 0x68, 0x70, 0x47, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0xb5, 0x04, + 0x49, 0x00, 0x20, 0x48, 0x61, 0xff, 0x20, 0x01, + 0x30, 0x24, 0xf0, 0x30, 0xf8, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x00, 0xd0, 0x00, 0xb5, 0x06, + 0x49, 0x01, 0x22, 0x0a, 0x60, 0x8b, 0x68, 0xc0, + 0x18, 0x88, 0x61, 0x4a, 0x61, 0x10, 0x02, 0x23, + 0xf0, 0xfd, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0xb5, 0x03, + 0xa0, 0x03, 0xf0, 0xa0, 0xfb, 0x00, 0x20, 0x00, + 0xdf, 0x08, 0xbc, 0x18, 0x47, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x20, 0x4a, 0x55, 0x4d, 0x50, 0x20, 0x54, 0x4f, + 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x44, 0x45, + 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x20, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x0a, 0x00, 0xf0, 0xb4, 0x82, + 0xb0, 0x20, 0x49, 0x00, 0x20, 0x0a, 0x68, 0x4b, + 0x0d, 0x1a, 0x43, 0x0a, 0x60, 0x1e, 0x4a, 0x00, + 0x21, 0x8b, 0x00, 0x01, 0x31, 0x08, 0x29, 0xc2, + 0x50, 0xfa, 0xd3, 0xc6, 0x1d, 0x11, 0x36, 0x01, + 0x96, 0xc6, 0x1d, 0x15, 0x36, 0xc2, 0x1d, 0xc4, + 0x1d, 0x01, 0x34, 0x09, 0x32, 0x00, 0x21, 0x05, + 0x1d, 0xc7, 0x1d, 0x05, 0x37, 0x00, 0x96, 0x08, + 0x29, 0x1e, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x04, 0x07, 0xed, + 0x09, 0x00, 0x1b, 0x01, 0x0a, 0x0d, 0x10, 0x1a, + 0x13, 0x17, 0x0f, 0x4b, 0x03, 0x62, 0x12, 0xe0, + 0x0f, 0x4b, 0x2b, 0x62, 0x0f, 0xe0, 0x0e, 0x4b, + 0x23, 0x62, 0x0c, 0xe0, 0x0e, 0x4b, 0x3b, 0x62, + 0x09, 0xe0, 0x0d, 0x4b, 0x13, 0x62, 0x06, 0xe0, + 0x0d, 0x4b, 0x01, 0x9e, 0x33, 0x62, 0x02, 0xe0, + 0x0c, 0x4b, 0x00, 0x9e, 0x33, 0x62, 0x01, 0x31, + 0x08, 0x29, 0xdb, 0xd3, 0x02, 0xb0, 0xf0, 0xbc, + 0x70, 0x47, 0x00, 0x00, 0x00, 0xe0, 0x18, 0xf0, + 0x9f, 0xe5, 0x29, 0x18, 0x01, 0x20, 0xe8, 0x59, + 0x03, 0x20, 0x88, 0x5a, 0x03, 0x20, 0xcc, 0x5a, + 0x03, 0x20, 0x48, 0x5b, 0x03, 0x20, 0xf8, 0x00, + 0x00, 0x20, 0x20, 0x01, 0x00, 0x20, 0x08, 0x10, + 0x9f, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x00, + 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x74, 0x65, + 0x03, 0x20, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, + 0xa0, 0xe1, 0x01, 0x40, 0xa0, 0xe1, 0xe2, 0x8f, + 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x30, 0x40, + 0xbd, 0x18, 0x1e, 0xff, 0x2f, 0x11, 0x28, 0x00, + 0x1f, 0xe5, 0x00, 0x00, 0x90, 0xe5, 0x00, 0x00, + 0x50, 0xe3, 0x30, 0x40, 0xbd, 0x08, 0x1e, 0xff, + 0x2f, 0x01, 0x00, 0x00, 0xa0, 0xe3, 0xd5, 0x8f, + 0x00, 0xeb, 0xd1, 0x8f, 0x00, 0xeb, 0x04, 0x20, + 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x04, 0x0f, + 0x8f, 0xe2, 0xca, 0x8f, 0x00, 0xeb, 0x00, 0x00, + 0xa0, 0xe3, 0x00, 0x00, 0x00, 0xef, 0x30, 0x40, + 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x41, 0x53, + 0x53, 0x45, 0x52, 0x54, 0x20, 0x4e, 0x4f, 0x54, + 0x20, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, + 0x4c, 0x20, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x75, + 0x0a, 0x00, 0x10, 0x40, 0x2d, 0xe9, 0xba, 0x8f, + 0x00, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0xb2, 0x8f, + 0x00, 0xeb, 0xed, 0x09, 0x00, 0x1c, 0x01, 0x00, + 0x40, 0xa0, 0xe1, 0x2c, 0x00, 0x9f, 0xe5, 0x01, + 0x10, 0xa0, 0xe3, 0x3b, 0x00, 0x00, 0xeb, 0x00, + 0x00, 0x50, 0xe3, 0x10, 0x40, 0xbd, 0x18, 0x1e, + 0xff, 0x2f, 0x11, 0x08, 0x00, 0xa0, 0xe3, 0xac, + 0x8f, 0x00, 0xeb, 0x10, 0x10, 0x9f, 0xe5, 0x01, + 0x00, 0xc1, 0xe5, 0x00, 0x40, 0xc1, 0xe5, 0x10, + 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x74, + 0x65, 0x03, 0x20, 0x7c, 0x65, 0x03, 0x20, 0x30, + 0x40, 0x2d, 0xe9, 0x14, 0x00, 0x1f, 0xe5, 0x01, + 0x10, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb, 0x00, + 0x00, 0x50, 0xe3, 0x30, 0x40, 0xbd, 0x08, 0x1e, + 0xff, 0x2f, 0x01, 0x01, 0x00, 0x50, 0xe3, 0x30, + 0x40, 0xbd, 0x18, 0x1e, 0xff, 0x2f, 0x11, 0x9d, + 0x8f, 0x00, 0xeb, 0x38, 0x50, 0x1f, 0xe5, 0x00, + 0x40, 0xa0, 0xe1, 0x01, 0x00, 0xd5, 0xe5, 0x0a, + 0x00, 0x50, 0xe3, 0x95, 0x8f, 0x00, 0x0b, 0x00, + 0x10, 0xd5, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0x30, + 0x40, 0xbd, 0xe8, 0x8e, 0x8f, 0x00, 0xea, 0x8e, + 0x12, 0xa0, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x92, + 0x10, 0x01, 0xe1, 0x00, 0x00, 0x81, 0xe1, 0x0e, + 0x12, 0xa0, 0xe3, 0x08, 0x00, 0x81, 0xe5, 0x1e, + 0xff, 0x2f, 0xe1, 0x00, 0x10, 0xa0, 0xe1, 0x8e, + 0x02, 0xa0, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x92, + 0x00, 0x00, 0xe1, 0x0e, 0x22, 0xa0, 0xe3, 0x01, + 0x10, 0xc0, 0xe1, 0x08, 0x10, 0x82, 0xe5, 0x1e, + 0xff, 0x2f, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x91, + 0x00, 0x00, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, + 0x20, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x8e, + 0x32, 0xa0, 0xe3, 0x90, 0x30, 0x03, 0xe1, 0x00, + 0x00, 0x92, 0xe5, 0x01, 0x10, 0x40, 0xe0, 0x00, + 0x10, 0x82, 0xe5, 0x0e, 0x12, 0xa0, 0xe3, 0x08, + 0x30, 0x81, 0xe5, 0x1e, 0xff, 0xed, 0x09, 0x00, + 0x1d, 0x01, 0x2f, 0xe1, 0x00, 0x20, 0xa0, 0xe1, + 0x00, 0x00, 0xa0, 0xe3, 0x8e, 0x32, 0xa0, 0xe3, + 0x90, 0x30, 0x03, 0xe1, 0x00, 0x00, 0x92, 0xe5, + 0x01, 0x10, 0x80, 0xe0, 0x00, 0x10, 0x82, 0xe5, + 0x0e, 0x12, 0xa0, 0xe3, 0x08, 0x30, 0x81, 0xe5, + 0x1e, 0xff, 0x2f, 0xe1, 0x91, 0x00, 0x00, 0xe1, + 0x1e, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x9f, 0xe5, + 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, + 0x04, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, + 0x08, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, + 0xd0, 0xb2, 0x03, 0x20, 0x8e, 0x12, 0xa0, 0xe3, + 0x00, 0x00, 0xa0, 0xe3, 0x90, 0x10, 0x01, 0xe1, + 0x18, 0x00, 0x1f, 0xe5, 0x00, 0x30, 0x90, 0xe5, + 0x01, 0x20, 0x83, 0xe2, 0x00, 0x20, 0x80, 0xe5, + 0x00, 0x00, 0x53, 0xe3, 0x04, 0x10, 0x80, 0x05, + 0x1e, 0xff, 0x2f, 0xe1, 0x8e, 0x12, 0xa0, 0xe3, + 0x00, 0x00, 0xa0, 0xe3, 0x90, 0x10, 0x01, 0xe1, + 0x01, 0x00, 0xa0, 0xe1, 0x44, 0x10, 0x1f, 0xe5, + 0x00, 0x20, 0x91, 0xe5, 0x01, 0x20, 0x52, 0xe2, + 0x00, 0x20, 0x81, 0xe5, 0x04, 0x10, 0x91, 0x05, + 0x00, 0x00, 0x81, 0x01, 0x0e, 0x12, 0xa0, 0xe3, + 0x08, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, + 0x90, 0xb5, 0x07, 0x1c, 0x14, 0x4c, 0x01, 0x20, + 0x20, 0x60, 0x01, 0xf0, 0x97, 0xfc, 0x01, 0xf0, + 0x99, 0xfc, 0x01, 0xf0, 0x9b, 0xfc, 0x01, 0xf0, + 0x9f, 0xfc, 0x01, 0xf0, 0xb3, 0xfc, 0x01, 0xf0, + 0x27, 0xfd, 0x01, 0xf0, 0x33, 0xfd, 0x01, 0xf0, + 0x3f, 0xfd, 0x01, 0xf0, 0x4b, 0xfd, 0x01, 0xf0, + 0x57, 0xfd, 0x01, 0xf0, 0x63, 0xfd, 0x01, 0xf0, + 0x6f, 0xfd, 0x01, 0xf0, 0x7b, 0xfd, 0x01, 0xf0, + 0xd3, 0xfd, 0x38, 0x1c, 0x03, 0xf0, 0xf4, 0xf9, + 0x02, 0x20, 0x20, 0x60, 0x23, 0xf0, 0x92, 0xfe, + 0xed, 0x09, 0x00, 0x1e, 0x01, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x80, 0x65, 0x03, + 0x20, 0x84, 0x65, 0x03, 0x20, 0x18, 0x67, 0x03, + 0x20, 0x5d, 0x2d, 0x01, 0x20, 0xa8, 0x24, 0x01, + 0x20, 0x95, 0x2d, 0x01, 0x20, 0xe8, 0x66, 0x03, + 0x20, 0xe4, 0x66, 0x03, 0x20, 0xd8, 0x66, 0x03, + 0x20, 0xb0, 0x65, 0x03, 0x20, 0xb8, 0x65, 0x03, + 0x20, 0xec, 0x66, 0x03, 0x20, 0xf0, 0x66, 0x03, + 0x20, 0x60, 0xb7, 0x03, 0x20, 0x54, 0xb7, 0x03, + 0x20, 0x00, 0x20, 0x0f, 0xe1, 0xc0, 0x20, 0x82, + 0xe3, 0x02, 0xf0, 0x2f, 0xe1, 0x48, 0x10, 0x1f, + 0xe5, 0x00, 0x30, 0x91, 0xe5, 0xc0, 0x20, 0xc2, + 0xe3, 0x00, 0x20, 0x82, 0xe1, 0x00, 0x00, 0x81, + 0xe5, 0x02, 0xf0, 0x2f, 0xe1, 0xc0, 0x00, 0x03, + 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x20, 0x0f, + 0xe1, 0x02, 0x30, 0xa0, 0xe1, 0xc0, 0x20, 0xc2, + 0xe3, 0x00, 0x20, 0x82, 0xe1, 0x02, 0xf0, 0x2f, + 0xe1, 0xc0, 0x00, 0x03, 0xe2, 0x1e, 0xff, 0x2f, + 0xe1, 0x00, 0x10, 0x0f, 0xe1, 0x01, 0x20, 0xa0, + 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x2f, + 0xe1, 0xc0, 0x20, 0xc2, 0xe3, 0x98, 0x10, 0x1f, + 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x00, 0x20, 0x82, + 0xe1, 0x02, 0xf0, 0x2f, 0xe1, 0x1e, 0xff, 0x2f, + 0xe1, 0x24, 0x20, 0x90, 0xe5, 0x30, 0x10, 0x90, + 0xe5, 0x02, 0x30, 0x81, 0xe0, 0x03, 0x30, 0xc3, + 0xe3, 0x04, 0x30, 0x43, 0xe2, 0x28, 0x30, 0x80, + 0xe5, 0xc0, 0x20, 0x1f, 0xe5, 0x01, 0x20, 0xc2, + 0xe3, 0x04, 0x20, 0x03, 0xe4, 0x00, 0x20, 0xa0, + 0xe3, 0x04, 0x20, 0x03, 0xe4, 0x08, 0x20, 0x83, + 0xe2, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, 0x03, + 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x24, 0x20, 0x90, + 0xe5, 0x04, 0x20, 0x03, 0xe4, 0x00, 0x20, 0xa0, + 0xe3, 0x04, 0x20, 0xed, 0x09, 0x00, 0x1f, 0x01, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x02, 0xf0, + 0x28, 0xe1, 0x00, 0x20, 0x0f, 0xe1, 0xc0, 0x20, + 0xc2, 0xe3, 0x20, 0x20, 0x82, 0xe3, 0x04, 0x20, + 0x03, 0xe4, 0x01, 0x20, 0xa0, 0xe3, 0x00, 0x20, + 0x83, 0xe5, 0x48, 0x20, 0xa0, 0xe3, 0x02, 0x10, + 0x41, 0xe0, 0x34, 0x10, 0x80, 0xe5, 0x2c, 0x30, + 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x24, 0x20, + 0x90, 0xe5, 0x30, 0x10, 0x90, 0xe5, 0x02, 0x30, + 0x81, 0xe0, 0x03, 0x30, 0xc3, 0xe3, 0x04, 0x30, + 0x43, 0xe2, 0x28, 0x30, 0x80, 0xe5, 0x5c, 0x21, + 0x1f, 0xe5, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x83, 0xe2, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x24, 0x20, 0x90, 0xe5, 0x04, 0x20, + 0x03, 0xe4, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x00, 0x20, 0x83, 0xe5, 0x30, 0x20, + 0xa0, 0xe3, 0x02, 0x10, 0x41, 0xe0, 0x34, 0x10, + 0x80, 0xe5, 0x2c, 0x30, 0x80, 0xe5, 0x1e, 0xff, + 0x2f, 0xe1, 0x2c, 0x30, 0x90, 0xe5, 0xb0, 0x21, + 0x1f, 0xe5, 0x01, 0x20, 0xc2, 0xe3, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x83, 0xe2, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x24, 0x20, + 0x90, 0xe5, 0x04, 0x20, 0x03, 0xe4, 0x00, 0x20, + 0xa0, 0xe3, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0x04, 0x20, + 0x03, 0xe4, 0x04, 0x20, 0x03, 0xe4, 0xed, 0x09, + 0x00, 0x20, 0x01, 0x04, 0x20, 0x03, 0xe4, 0x20, + 0x10, 0xa0, 0xe3, 0x04, 0x10, 0x03, 0xe4, 0x00, + 0x20, 0x83, 0xe5, 0x2c, 0x30, 0x80, 0xe5, 0x1e, + 0xff, 0x2f, 0xe1, 0xfc, 0x01, 0x1f, 0xe5, 0x00, + 0x00, 0x90, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x00, + 0x30, 0xa0, 0xe3, 0x13, 0x00, 0x00, 0x0a, 0x24, + 0x20, 0x90, 0xe5, 0x02, 0x00, 0x5d, 0xe1, 0x02, + 0x00, 0x00, 0xba, 0x28, 0x10, 0x90, 0xe5, 0x01, + 0x00, 0x5d, 0xe1, 0x03, 0x00, 0x00, 0xda, 0x04, + 0xe0, 0xad, 0xe5, 0x03, 0x00, 0xa0, 0xe3, 0x94, + 0x37, 0x9f, 0xe5, 0x13, 0xff, 0x2f, 0xe1, 0x02, + 0x30, 0x4d, 0xe0, 0x50, 0x00, 0x53, 0xe3, 0x03, + 0x00, 0x00, 0x2a, 0x04, 0xe0, 0xad, 0xe5, 0x03, + 0x00, 0xa0, 0xe3, 0x78, 0x37, 0x9f, 0xe5, 0x13, + 0xff, 0x2f, 0xe1, 0x34, 0x20, 0x90, 0xe5, 0x02, + 0x00, 0x53, 0xe1, 0x34, 0x30, 0x80, 0x35, 0x03, + 0x00, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x78, + 0x12, 0x1f, 0xe5, 0x00, 0x00, 0x0f, 0xe1, 0x00, + 0x20, 0x91, 0xe5, 0xc0, 0x00, 0xc0, 0xe3, 0x02, + 0x00, 0x80, 0xe1, 0x00, 0xf0, 0x2f, 0xe1, 0x7c, + 0x22, 0x1f, 0xe5, 0x7c, 0x32, 0x1f, 0xe5, 0x00, + 0x00, 0x92, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x02, + 0x00, 0x00, 0x1a, 0x00, 0x00, 0x93, 0xe5, 0x00, + 0x00, 0x50, 0xe3, 0xf9, 0xff, 0xff, 0x0a, 0x00, + 0x10, 0x0f, 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, + 0xf0, 0x2f, 0xe1, 0xac, 0x12, 0x1f, 0xe5, 0x1c, + 0x20, 0x90, 0xe5, 0x00, 0x00, 0x81, 0xe5, 0x20, + 0x30, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, 0x1c, + 0x20, 0x80, 0xe5, 0x00, 0x00, 0x53, 0xe3, 0x04, + 0x00, 0x00, 0x0a, 0xc0, 0x22, 0x1f, 0xe5, 0xc0, + 0x12, 0x1f, 0xe5, 0x00, 0x30, 0x82, 0xe5, 0x00, + 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x81, 0xe5, 0x2c, + 0xd0, 0xed, 0x09, 0x00, 0x21, 0x01, 0x90, 0xe5, + 0x04, 0x10, 0x9d, 0xe4, 0x01, 0x00, 0x51, 0xe3, + 0x08, 0x00, 0x00, 0x0a, 0x00, 0x13, 0x1f, 0xe5, + 0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, + 0x00, 0x20, 0x91, 0xe5, 0x02, 0x00, 0x80, 0xe1, + 0x04, 0x20, 0x9d, 0xe4, 0x02, 0x00, 0x80, 0xe1, + 0x00, 0xf0, 0x6f, 0xe1, 0xf0, 0x9f, 0xfd, 0xe8, + 0x04, 0x00, 0x9d, 0xe4, 0x28, 0x13, 0x1f, 0xe5, + 0xc0, 0x00, 0xc0, 0xe3, 0x00, 0x20, 0x91, 0xe5, + 0x02, 0x00, 0x80, 0xe1, 0x00, 0xf0, 0x6f, 0xe1, + 0xff, 0xff, 0xdd, 0xe8, 0x00, 0x00, 0x0f, 0xe1, + 0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x2f, 0xe1, + 0xf0, 0x5f, 0x2d, 0xe9, 0x0e, 0x20, 0xa0, 0xe1, + 0x82, 0x2f, 0xa0, 0xe1, 0x22, 0x2d, 0xa0, 0xe1, + 0x04, 0x20, 0x2d, 0xe5, 0x00, 0x20, 0xa0, 0xe3, + 0x04, 0x20, 0x2d, 0xe5, 0x58, 0x13, 0x1f, 0xe5, + 0x00, 0x00, 0x91, 0xe5, 0x50, 0x33, 0x1f, 0xe5, + 0x00, 0x20, 0x81, 0xe5, 0x00, 0x10, 0x93, 0xe5, + 0x00, 0x00, 0x51, 0xe3, 0x03, 0x00, 0x00, 0x1a, + 0x40, 0x10, 0x90, 0xe5, 0x01, 0x20, 0xa0, 0xe3, + 0x00, 0x20, 0x83, 0xe5, 0x20, 0x10, 0x80, 0xe5, + 0x2c, 0xd0, 0x80, 0xe5, 0x38, 0x10, 0x90, 0xe5, + 0x00, 0x20, 0xa0, 0xe3, 0x38, 0x20, 0x80, 0xe5, + 0x00, 0x20, 0x81, 0xe5, 0x84, 0x13, 0x1f, 0xe5, + 0xb0, 0x23, 0x1f, 0xe5, 0x00, 0xd0, 0x91, 0xe5, + 0x00, 0xa0, 0x92, 0xe5, 0xae, 0xff, 0xff, 0xea, + 0x00, 0x30, 0x0f, 0xe1, 0xc0, 0x30, 0x83, 0xe3, + 0x03, 0xf0, 0x2f, 0xe1, 0xb8, 0x13, 0x1f, 0xe5, + 0x00, 0x20, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, + 0xb4, 0x33, 0x1f, 0xe5, 0x00, 0x20, 0x81, 0xe5, + 0x00, 0x10, 0x93, 0xe5, 0x00, 0x00, 0x51, 0xe3, + 0x03, 0x00, 0x00, 0x1a, 0x40, 0x10, 0x90, 0xe5, + 0x01, 0x20, 0xa0, 0xe3, 0xed, 0x09, 0x00, 0x22, + 0x01, 0x00, 0x20, 0x83, 0xe5, 0x20, 0x10, 0x80, + 0xe5, 0x3c, 0x10, 0x90, 0xe5, 0x2c, 0x10, 0x80, + 0xe5, 0x38, 0x10, 0x90, 0xe5, 0x00, 0x20, 0xa0, + 0xe3, 0x38, 0x20, 0x80, 0xe5, 0x00, 0x20, 0x81, + 0xe5, 0xec, 0x13, 0x1f, 0xe5, 0x18, 0x24, 0x1f, + 0xe5, 0x00, 0xd0, 0x91, 0xe5, 0x00, 0xa0, 0x92, + 0xe5, 0x94, 0xff, 0xff, 0xea, 0x14, 0x04, 0x1f, + 0xe5, 0x00, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, + 0xe1, 0x18, 0x14, 0x1f, 0xe5, 0x00, 0x00, 0x81, + 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x2c, 0x14, 0x1f, + 0xe5, 0x00, 0x30, 0x91, 0xe5, 0x00, 0x00, 0x53, + 0xe3, 0x1d, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x0f, + 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x2f, + 0xe1, 0x00, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, + 0xe3, 0x0d, 0x00, 0x00, 0x0a, 0x01, 0x20, 0xa0, + 0xe3, 0x04, 0x20, 0x80, 0xe5, 0x04, 0x00, 0x2d, + 0xe5, 0x04, 0xe0, 0x2d, 0xe5, 0x03, 0x00, 0xa0, + 0xe1, 0x72, 0x00, 0x00, 0xeb, 0x04, 0xe0, 0x9d, + 0xe4, 0x04, 0x00, 0x9d, 0xe4, 0x74, 0x14, 0x1f, + 0xe5, 0x00, 0x30, 0x91, 0xe5, 0x00, 0x10, 0x0f, + 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x2f, + 0xe1, 0xee, 0xff, 0xff, 0xea, 0x00, 0x30, 0x80, + 0xe5, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x20, 0x80, + 0xe5, 0x38, 0x00, 0x83, 0xe5, 0xac, 0x24, 0x1f, + 0xe5, 0x00, 0x10, 0x0f, 0xe1, 0x00, 0x30, 0x92, + 0xe5, 0xc0, 0x10, 0xc1, 0xe3, 0x03, 0x10, 0x81, + 0xe1, 0x01, 0xf0, 0x2f, 0xe1, 0x1e, 0xff, 0x2f, + 0xe1, 0xb8, 0x14, 0x1f, 0xe5, 0x00, 0x30, 0x91, + 0xe5, 0x00, 0x00, 0x53, 0xe3, 0x12, 0x00, 0x00, + 0x0a, 0x38, 0x00, 0x93, 0xe5, 0x00, 0x00, 0x50, + 0xe3, 0x0f, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x0f, + 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0xed, + 0x09, 0x00, 0x23, 0x01, 0x2f, 0xe1, 0x04, 0x20, + 0x90, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x00, 0x00, + 0x00, 0x0a, 0x8f, 0xff, 0xff, 0xea, 0x00, 0x20, + 0xa0, 0xe3, 0x00, 0x20, 0x80, 0xe5, 0x38, 0x20, + 0x83, 0xe5, 0x0c, 0x25, 0x1f, 0xe5, 0x00, 0x10, + 0x0f, 0xe1, 0x00, 0x30, 0x92, 0xe5, 0xc0, 0x10, + 0xc1, 0xe3, 0x03, 0x10, 0x81, 0xe1, 0x01, 0xf0, + 0x2f, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x18, 0x15, + 0x1f, 0xe5, 0x00, 0x30, 0x91, 0xe5, 0x00, 0x00, + 0x53, 0xe3, 0x25, 0x00, 0x00, 0x0a, 0x00, 0x10, + 0x0f, 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, + 0x2f, 0xe1, 0x00, 0x20, 0xa0, 0xe3, 0x00, 0x20, + 0x80, 0xe5, 0x04, 0x10, 0x90, 0xe5, 0x00, 0x00, + 0x51, 0xe3, 0x17, 0x00, 0x00, 0x0a, 0xf0, 0x5f, + 0x2d, 0xe9, 0x0e, 0x20, 0xa0, 0xe1, 0x82, 0x2f, + 0xa0, 0xe1, 0x22, 0x2d, 0xa0, 0xe1, 0x04, 0x20, + 0x2d, 0xe5, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x20, + 0x2d, 0xe5, 0x64, 0x15, 0x1f, 0xe5, 0x00, 0x00, + 0x91, 0xe5, 0x5c, 0x35, 0x1f, 0xe5, 0x00, 0x20, + 0x81, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x00, 0x00, + 0x51, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x40, 0x10, + 0x90, 0xe5, 0x01, 0x20, 0xa0, 0xe3, 0x00, 0x20, + 0x83, 0xe5, 0x20, 0x10, 0x80, 0xe5, 0x2c, 0xd0, + 0x80, 0xe5, 0x80, 0x15, 0x1f, 0xe5, 0xac, 0x25, + 0x1f, 0xe5, 0x00, 0xd0, 0x91, 0xe5, 0x00, 0xa0, + 0x92, 0xe5, 0x2f, 0xff, 0xff, 0xea, 0xb8, 0x25, + 0x1f, 0xe5, 0x00, 0x10, 0x0f, 0xe1, 0x00, 0x30, + 0x92, 0xe5, 0xc0, 0x10, 0xc1, 0xe3, 0x03, 0x10, + 0x81, 0xe1, 0x01, 0xf0, 0x2f, 0xe1, 0x1e, 0xff, + 0x2f, 0xe1, 0xc4, 0x15, 0x1f, 0xe5, 0x00, 0x30, + 0x91, 0xe5, 0x00, 0x00, 0x53, 0xe3, 0x38, 0x00, + 0x83, 0x15, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x10, + 0x0f, 0xe1, 0xed, 0x09, 0x00, 0x24, 0x01, 0xc0, + 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x2f, 0xe1, 0x38, + 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x0a, + 0x00, 0x00, 0x0a, 0x01, 0x20, 0xa0, 0xe3, 0x04, + 0x20, 0x81, 0xe5, 0xf8, 0x25, 0x1f, 0xe5, 0x04, + 0x00, 0x2d, 0xe5, 0x04, 0xe0, 0x2d, 0xe5, 0x00, + 0x10, 0xa0, 0xe1, 0x00, 0x00, 0x92, 0xe5, 0x09, + 0x00, 0x00, 0xeb, 0x04, 0xe0, 0x9d, 0xe4, 0x04, + 0x00, 0x9d, 0xe4, 0xee, 0xff, 0xff, 0xea, 0x2c, + 0x26, 0x1f, 0xe5, 0x00, 0x10, 0x0f, 0xe1, 0x00, + 0x30, 0x92, 0xe5, 0xc0, 0x10, 0xc1, 0xe3, 0x03, + 0x10, 0x81, 0xe1, 0x01, 0xf0, 0x2f, 0xe1, 0x1e, + 0xff, 0x2f, 0xe1, 0xf0, 0x5f, 0x2d, 0xe9, 0x0e, + 0x20, 0xa0, 0xe1, 0x82, 0x2f, 0xa0, 0xe1, 0x22, + 0x2d, 0xa0, 0xe1, 0x04, 0x20, 0x2d, 0xe5, 0x00, + 0x20, 0xa0, 0xe3, 0x04, 0x20, 0x2d, 0xe5, 0x01, + 0x40, 0xa0, 0xe1, 0x58, 0x16, 0x1f, 0xe5, 0x4c, + 0x36, 0x1f, 0xe5, 0x00, 0x20, 0x81, 0xe5, 0x00, + 0x10, 0x93, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x03, + 0x00, 0x00, 0x1a, 0x40, 0x10, 0x90, 0xe5, 0x01, + 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x20, + 0x10, 0x80, 0xe5, 0x2c, 0xd0, 0x80, 0xe5, 0x70, + 0x16, 0x1f, 0xe5, 0x9c, 0x26, 0x1f, 0xe5, 0x00, + 0xd0, 0x91, 0xe5, 0x00, 0xa0, 0x92, 0xe5, 0xa4, + 0x26, 0x1f, 0xe5, 0x00, 0x10, 0x0f, 0xe1, 0x00, + 0x30, 0x92, 0xe5, 0xc0, 0x10, 0xc1, 0xe3, 0x03, + 0x10, 0x81, 0xe1, 0x04, 0x00, 0xa0, 0xe1, 0x01, + 0xf0, 0x2f, 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, + 0xf0, 0x2f, 0xe1, 0xfb, 0xfe, 0xff, 0xea, 0x00, + 0x20, 0x4f, 0xe1, 0x80, 0x20, 0x02, 0xe2, 0x00, + 0x00, 0x52, 0xe3, 0x19, 0x00, 0x00, 0x0a, 0xb4, + 0x06, 0x1f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, + 0x10, 0x81, 0xe2, 0x00, 0x10, 0xed, 0x09, 0x00, + 0x25, 0x01, 0x80, 0xe5, 0x70, 0x00, 0x2d, 0xe9, + 0x00, 0x40, 0x4f, 0xe1, 0x0e, 0x50, 0xa0, 0xe1, + 0x0d, 0x60, 0xa0, 0xe1, 0x1c, 0xd0, 0x8d, 0xe2, + 0x00, 0x00, 0x0f, 0xe1, 0x1f, 0x00, 0xc0, 0xe3, + 0x13, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x2f, 0xe1, + 0x0d, 0x10, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe1, + 0x04, 0x30, 0x21, 0xe5, 0x09, 0x30, 0xa0, 0xe1, + 0x80, 0x7f, 0x21, 0xe9, 0x01, 0xd0, 0xa0, 0xe1, + 0x80, 0x03, 0xb6, 0xe8, 0x80, 0x03, 0x2d, 0xe9, + 0x03, 0x90, 0xa0, 0xe1, 0x0f, 0x00, 0x96, 0xe8, + 0x0f, 0x00, 0x2d, 0xe9, 0x04, 0x40, 0x2d, 0xe5, + 0x15, 0xff, 0x2f, 0xe1, 0x34, 0x17, 0x1f, 0xe5, + 0x00, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x51, 0xe3, + 0x1c, 0x00, 0x00, 0x0a, 0x70, 0x00, 0x2d, 0xe9, + 0x0e, 0x50, 0xa0, 0xe1, 0x00, 0x40, 0x4f, 0xe1, + 0x0d, 0x60, 0xa0, 0xe1, 0x1c, 0xd0, 0x8d, 0xe2, + 0x00, 0x00, 0x0f, 0xe1, 0x1f, 0x00, 0xc0, 0xe3, + 0x13, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x2f, 0xe1, + 0x0d, 0x10, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe1, + 0x04, 0x30, 0x21, 0xe5, 0x80, 0x7f, 0x21, 0xe9, + 0x01, 0xd0, 0xa0, 0xe1, 0x80, 0x03, 0xb6, 0xe8, + 0x80, 0x03, 0x2d, 0xe9, 0x0f, 0x00, 0x96, 0xe8, + 0x0f, 0x00, 0x2d, 0xe9, 0x04, 0x40, 0x2d, 0xe5, + 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x10, 0x2d, 0xe5, + 0x98, 0x17, 0x1f, 0xe5, 0x00, 0x00, 0x91, 0xe5, + 0x2c, 0xd0, 0x80, 0xe5, 0x90, 0x17, 0x1f, 0xe5, + 0xbc, 0x27, 0x1f, 0xe5, 0x00, 0xd0, 0x91, 0xe5, + 0x00, 0xa0, 0x92, 0xe5, 0x15, 0xff, 0x2f, 0xe1, + 0x0e, 0x50, 0xa0, 0xe1, 0x10, 0xd0, 0x8d, 0xe2, + 0x00, 0x00, 0x0f, 0xe1, 0x1f, 0x00, 0xc0, 0xe3, + 0x13, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x2f, 0xe1, + 0x15, 0xff, 0x2f, 0xe1, 0x00, 0x10, 0x0f, 0xe1, + 0xed, 0x09, 0x00, 0x26, 0x01, 0xc0, 0x10, 0x81, + 0xe3, 0x01, 0xf0, 0x2f, 0xe1, 0xc8, 0x07, 0x1f, + 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, + 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x01, 0x10, 0x41, + 0xe2, 0x00, 0x10, 0x80, 0xe5, 0x04, 0x00, 0x9d, + 0xe4, 0x00, 0xf0, 0x6f, 0xe1, 0xff, 0xff, 0xdd, + 0xe8, 0x04, 0x18, 0x1f, 0xe5, 0x00, 0x00, 0x91, + 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, + 0x0a, 0x04, 0x38, 0x1f, 0xe5, 0x00, 0x20, 0xa0, + 0xe3, 0x00, 0x20, 0x81, 0xe5, 0x00, 0x10, 0x93, + 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x04, 0x00, 0x00, + 0x1a, 0x20, 0x28, 0x1f, 0xe5, 0x01, 0x10, 0xa0, + 0xe3, 0x00, 0x20, 0x92, 0xe5, 0x00, 0x10, 0x83, + 0xe5, 0x20, 0x20, 0x80, 0xe5, 0x2c, 0x18, 0x1f, + 0xe5, 0x58, 0x28, 0x1f, 0xe5, 0x00, 0xd0, 0x91, + 0xe5, 0x00, 0xa0, 0x92, 0xe5, 0x84, 0xfe, 0xff, + 0xea, 0x04, 0x40, 0x2d, 0xe5, 0x00, 0x40, 0x0f, + 0xe1, 0xc0, 0x10, 0x84, 0xe3, 0x01, 0xf0, 0x2f, + 0xe1, 0x40, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, + 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x01, 0x10, 0x91, + 0xe2, 0x40, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xe0, + 0x03, 0x40, 0x10, 0x80, 0x05, 0x13, 0x00, 0x00, + 0xea, 0x01, 0x10, 0xa0, 0xe3, 0x40, 0x10, 0x80, + 0xe5, 0x1a, 0x10, 0xd0, 0xe5, 0x74, 0x28, 0x1f, + 0xe5, 0x01, 0x31, 0x92, 0xe7, 0x00, 0x00, 0x53, + 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x3c, 0x00, 0x83, + 0xe5, 0x01, 0x01, 0x82, 0xe7, 0x09, 0x00, 0x00, + 0xea, 0x8c, 0x38, 0x1f, 0xe5, 0x01, 0x01, 0x82, + 0xe7, 0x01, 0x01, 0x83, 0xe7, 0x00, 0x10, 0x93, + 0xe5, 0xb8, 0x08, 0x1f, 0xe5, 0x00, 0x00, 0x51, + 0xe3, 0x04, 0x10, 0x93, 0x05, 0x00, 0x00, 0x51, + 0x03, 0x08, 0x10, 0x93, 0x05, 0x00, 0x10, 0x80, + 0xe5, 0x04, 0xf0, 0xed, 0x09, 0x00, 0x27, 0x01, + 0x2f, 0xe1, 0x04, 0x40, 0x9d, 0xe4, 0x00, 0x00, + 0xa0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 0xe4, 0x08, + 0x1f, 0xe5, 0x00, 0x50, 0x90, 0xe5, 0x44, 0x40, + 0x95, 0xe5, 0x01, 0x00, 0x14, 0xe3, 0x02, 0x00, + 0x00, 0x1a, 0x0f, 0xe0, 0xa0, 0xe1, 0x14, 0xff, + 0x2f, 0xe1, 0x02, 0x00, 0x00, 0xea, 0xc4, 0xe0, + 0x9f, 0xe5, 0x14, 0xff, 0x2f, 0xe1, 0x31, 0x49, + 0x08, 0x47, 0x00, 0x10, 0x0f, 0xe1, 0xc0, 0x10, + 0x81, 0xe3, 0x01, 0xf0, 0x2f, 0xe1, 0x40, 0x00, + 0x95, 0xe5, 0x01, 0x00, 0x50, 0xe2, 0x40, 0x00, + 0x85, 0xe5, 0x06, 0x00, 0x00, 0x0a, 0x3c, 0x29, + 0x1f, 0xe5, 0x00, 0x10, 0x0f, 0xe1, 0x00, 0x30, + 0x92, 0xe5, 0xc0, 0x10, 0xc1, 0xe3, 0x03, 0x10, + 0x81, 0xe1, 0x01, 0xf0, 0x2f, 0xe1, 0xe8, 0xff, + 0xff, 0xea, 0x2c, 0xe9, 0x1f, 0xe5, 0x1a, 0x30, + 0xd5, 0xe5, 0x03, 0x61, 0x9e, 0xe7, 0x50, 0x29, + 0x1f, 0xe5, 0x00, 0xc0, 0xa0, 0xe3, 0x3c, 0x19, + 0x1f, 0xe5, 0x05, 0x00, 0x56, 0xe1, 0x08, 0x00, + 0x00, 0x1a, 0x03, 0xc1, 0x81, 0xe7, 0x03, 0xc1, + 0x8e, 0xe7, 0x00, 0x30, 0x91, 0xe5, 0x00, 0x00, + 0x53, 0xe3, 0x04, 0x30, 0x91, 0x05, 0x00, 0x00, + 0x53, 0x03, 0x08, 0x30, 0x91, 0x05, 0x00, 0x30, + 0x82, 0xe5, 0x02, 0x00, 0x00, 0xea, 0x3c, 0xe0, + 0x95, 0xe5, 0x03, 0xe1, 0x81, 0xe7, 0x00, 0xe0, + 0x82, 0xe5, 0xa0, 0xe9, 0x1f, 0xe5, 0xf0, 0x5f, + 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x20, + 0x2d, 0xe5, 0x04, 0x20, 0x2d, 0xe5, 0xac, 0x19, + 0x1f, 0xe5, 0x00, 0x20, 0x81, 0xe5, 0x2c, 0xd0, + 0x85, 0xe5, 0xa4, 0x19, 0x1f, 0xe5, 0xd0, 0x29, + 0x1f, 0xe5, 0x00, 0xd0, 0x91, 0xe5, 0x00, 0xa0, + 0x92, 0xe5, 0x26, 0xfe, 0xff, 0xea, 0x61, 0x37, + 0x01, 0x20, 0xd1, 0x24, 0x01, 0x20, 0xed, 0x09, + 0x00, 0x28, 0x01, 0xd4, 0x24, 0x01, 0x20, 0xff, + 0xb5, 0x07, 0x1c, 0x0d, 0x98, 0x00, 0x21, 0x0c, + 0x9c, 0x0b, 0x9d, 0x0a, 0x9e, 0xf9, 0x60, 0x01, + 0x9a, 0x7b, 0x18, 0x52, 0x5c, 0x01, 0x31, 0x08, + 0x29, 0x1a, 0x74, 0xf8, 0xdb, 0x02, 0x9a, 0xfa, + 0x65, 0x03, 0x9b, 0x3b, 0x66, 0x09, 0x99, 0x79, + 0x66, 0x01, 0x21, 0x39, 0x76, 0x00, 0x21, 0x79, + 0x76, 0xf9, 0x61, 0x38, 0x64, 0x38, 0x62, 0xb9, + 0x63, 0xb9, 0x66, 0xf9, 0x66, 0x39, 0x67, 0x0e, + 0x98, 0x0a, 0x28, 0x02, 0xd1, 0x01, 0x21, 0xf9, + 0x76, 0x01, 0xe0, 0x00, 0x21, 0xf9, 0x76, 0x55, + 0x21, 0x30, 0x1c, 0x2a, 0x1c, 0xed, 0xf7, 0x8d, + 0xfe, 0x7e, 0x62, 0x00, 0x26, 0x2d, 0x49, 0xa0, + 0x00, 0x40, 0x18, 0xbe, 0x62, 0x3d, 0x63, 0x7d, + 0x63, 0x62, 0x07, 0x52, 0x0f, 0xbc, 0x76, 0x38, + 0x65, 0x01, 0x21, 0x08, 0x1c, 0x90, 0x40, 0xfd, + 0x1d, 0x49, 0x35, 0x28, 0x72, 0xe0, 0x10, 0x00, + 0x06, 0x00, 0x0e, 0x81, 0x40, 0xf9, 0x64, 0x23, + 0x49, 0x08, 0x18, 0x78, 0x65, 0x3e, 0x60, 0x7e, + 0x60, 0x7e, 0x64, 0xbe, 0x64, 0x38, 0x1c, 0x23, + 0xf0, 0x6c, 0xf9, 0xf8, 0x1d, 0x79, 0x30, 0xc6, + 0x60, 0x06, 0x61, 0x46, 0x61, 0xf8, 0x1d, 0x71, + 0x30, 0xae, 0x72, 0x7e, 0x67, 0x39, 0x1c, 0x01, + 0xf0, 0x8e, 0xf8, 0x19, 0x48, 0x23, 0xf0, 0x45, + 0xf9, 0x19, 0x48, 0xf8, 0x60, 0x19, 0x48, 0x01, + 0x68, 0x00, 0x29, 0x06, 0xd0, 0x09, 0x68, 0x39, + 0x60, 0x4f, 0x60, 0x00, 0x68, 0x78, 0x60, 0x07, + 0x60, 0x03, 0xe0, 0x07, 0x60, 0x3f, 0x60, 0x7f, + 0x60, 0x38, 0x1c, 0x12, 0x48, 0x01, 0x68, 0x01, + 0x31, 0x01, 0x60, 0x23, 0xf0, 0x2a, 0xf9, 0x0f, + 0x98, 0x0c, 0x28, 0x0d, 0xd1, 0x0f, 0x48, 0x23, + 0xf0, 0x28, 0xf9, 0x01, 0x21, 0x38, 0x1c, 0x00, + 0xf0, 0xed, 0x09, 0x00, 0x29, 0x01, 0x3e, 0xf9, + 0x00, 0x28, 0x02, 0xd0, 0x23, 0xf0, 0x28, 0xf9, + 0x01, 0xe0, 0x23, 0xf0, 0x19, 0xf9, 0x30, 0x1c, + 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x34, 0xb3, 0x03, 0x20, 0x34, 0xb7, 0x03, 0x20, + 0xf8, 0x66, 0x03, 0x20, 0x4b, 0x53, 0x41, 0x54, + 0xc8, 0x65, 0x03, 0x20, 0xcc, 0x65, 0x03, 0x20, + 0x00, 0x67, 0x03, 0x20, 0xff, 0xb5, 0x00, 0x23, + 0x0a, 0x9c, 0x09, 0x9d, 0xc3, 0x60, 0x07, 0x1c, + 0x00, 0x20, 0x0b, 0x5c, 0x3e, 0x18, 0x01, 0x30, + 0x08, 0x28, 0x33, 0x74, 0xf9, 0xdb, 0x00, 0x26, + 0x7a, 0x64, 0xfe, 0x61, 0x3e, 0x62, 0x55, 0x21, + 0x28, 0x1c, 0x22, 0x1c, 0x3e, 0x64, 0xed, 0xf7, + 0x0b, 0xfe, 0x3c, 0x63, 0x7d, 0x62, 0xbe, 0x62, + 0x7c, 0x63, 0x03, 0x9b, 0x98, 0x07, 0x80, 0x0f, + 0xb8, 0x76, 0x3e, 0x60, 0x7e, 0x60, 0xfe, 0x63, + 0xbe, 0x63, 0x38, 0x1c, 0x23, 0xf0, 0x00, 0xf9, + 0x0e, 0x48, 0x23, 0xf0, 0xe1, 0xf8, 0x0e, 0x48, + 0xf8, 0x60, 0x0e, 0x48, 0x01, 0x68, 0x00, 0x29, + 0x06, 0xd0, 0x09, 0x68, 0x39, 0x60, 0x4f, 0x60, + 0x00, 0x68, 0x78, 0x60, 0x07, 0x60, 0x02, 0xe0, + 0x07, 0x60, 0x3f, 0x60, 0x7f, 0x60, 0x08, 0x48, + 0x01, 0x68, 0x01, 0x31, 0x01, 0x60, 0x23, 0xf0, + 0xc7, 0xf8, 0x30, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x10, 0x67, 0x03, 0x20, + 0x52, 0x53, 0x49, 0x48, 0xdc, 0x66, 0x03, 0x20, + 0xe0, 0x66, 0x03, 0x20, 0x90, 0xb5, 0x07, 0x1c, + 0x0f, 0x48, 0x23, 0xf0, 0xb9, 0xf8, 0x39, 0x68, + 0x00, 0x24, 0xb9, 0x42, 0x0d, 0x48, 0x01, 0xd1, + 0x04, 0x60, 0x09, 0xe0, 0x7a, 0x68, 0x4a, 0x60, + 0x06, 0xcf, 0x08, 0x3f, 0x11, 0x60, 0x01, 0x68, + 0x8f, 0x42, 0x01, 0xd1, 0x79, 0x68, 0x01, 0x60, + 0x07, 0x48, 0x01, 0x68, 0xed, 0x09, 0x00, 0x2a, + 0x01, 0x01, 0x39, 0x01, 0x60, 0xfc, 0x60, 0x23, + 0xf0, 0x9d, 0xf8, 0x20, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf8, 0x66, 0x03, + 0x20, 0xc8, 0x65, 0x03, 0x20, 0xcc, 0x65, 0x03, + 0x20, 0x90, 0xb5, 0x07, 0x1c, 0x0f, 0x48, 0x23, + 0xf0, 0x91, 0xf8, 0x39, 0x68, 0x00, 0x24, 0xb9, + 0x42, 0x0d, 0x48, 0x01, 0xd1, 0x04, 0x60, 0x09, + 0xe0, 0x7a, 0x68, 0x4a, 0x60, 0x06, 0xcf, 0x08, + 0x3f, 0x11, 0x60, 0x01, 0x68, 0x8f, 0x42, 0x01, + 0xd1, 0x79, 0x68, 0x01, 0x60, 0x07, 0x48, 0x01, + 0x68, 0x01, 0x39, 0x01, 0x60, 0xfc, 0x60, 0x23, + 0xf0, 0x75, 0xf8, 0x20, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x67, 0x03, + 0x20, 0xdc, 0x66, 0x03, 0x20, 0xe0, 0x66, 0x03, + 0x20, 0xf0, 0xb5, 0x14, 0x1c, 0x0d, 0x1c, 0x06, + 0x1c, 0x0e, 0x48, 0x23, 0xf0, 0x67, 0xf8, 0x30, + 0x7e, 0x0b, 0x28, 0x01, 0xd0, 0x0c, 0x28, 0x0d, + 0xd1, 0x74, 0x66, 0x35, 0x66, 0x01, 0x20, 0x30, + 0x76, 0x00, 0x20, 0x70, 0x76, 0xf0, 0x61, 0x30, + 0x6b, 0x00, 0x27, 0x70, 0x63, 0x30, 0x1c, 0x23, + 0xf0, 0x6d, 0xf8, 0x01, 0xe0, 0x25, 0x27, 0xff, + 0x43, 0x23, 0xf0, 0x4c, 0xf8, 0x38, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x67, 0x03, + 0x20, 0xf8, 0xb5, 0x07, 0x1c, 0x2e, 0x48, 0x2f, + 0x4c, 0x00, 0x68, 0x87, 0x42, 0x0c, 0xd1, 0x20, + 0x1c, 0x23, 0xf0, 0x40, 0xf8, 0x00, 0x22, 0xd2, + 0x43, 0x00, 0x92, 0x00, 0x22, 0x00, 0x23, 0x0c, + 0x21, 0x38, 0x1c, 0x00, 0xf0, 0xf1, 0xf8, 0x46, + 0xe0, 0x20, 0x1c, 0x23, 0xf0, 0x33, 0xf8, 0xfe, + 0x1d, 0x71, 0x36, 0x39, 0xe0, 0x00, 0x2d, 0x0a, + 0xd1, 0xea, 0x43, 0x00, 0x92, 0x00, 0x22, 0x00, + 0x23, 0x0c, 0x21, 0x38, 0x1c, 0x00, 0xf0, 0xed, + 0x09, 0x00, 0x2b, 0x01, 0xe0, 0xf8, 0x23, 0xf0, + 0x20, 0xf8, 0x29, 0xe0, 0x3c, 0x6f, 0x23, 0xf0, + 0x1c, 0xf8, 0x00, 0x2c, 0x02, 0xd0, 0x20, 0x1c, + 0x23, 0xf0, 0x1b, 0xf8, 0x19, 0x48, 0x23, 0xf0, + 0x18, 0xf8, 0x38, 0x7e, 0xa8, 0x42, 0x12, 0xd1, + 0x38, 0x6f, 0xa0, 0x42, 0x0f, 0xd1, 0xb9, 0x6e, + 0x00, 0x29, 0x02, 0xd0, 0xf8, 0x6e, 0xed, 0xf7, + 0x8b, 0xfd, 0x0c, 0x20, 0x38, 0x76, 0x78, 0x6f, + 0x00, 0x28, 0x04, 0xd0, 0x30, 0x1c, 0x00, 0xf0, + 0x55, 0xff, 0x00, 0x21, 0x79, 0x67, 0x00, 0x2c, + 0x04, 0xd0, 0x20, 0x1c, 0x23, 0xf0, 0x09, 0xf8, + 0x00, 0x21, 0x39, 0x67, 0x22, 0xf0, 0xf5, 0xff, + 0x08, 0x48, 0x22, 0xf0, 0xf6, 0xff, 0x3d, 0x7e, + 0x0b, 0x2d, 0x01, 0xd0, 0x0c, 0x2d, 0xc0, 0xd1, + 0x22, 0xf0, 0xeb, 0xff, 0xf8, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x66, + 0x03, 0x20, 0x00, 0x67, 0x03, 0x20, 0xf0, 0xb5, + 0x04, 0x1c, 0x02, 0x7e, 0xe6, 0x1d, 0x49, 0x36, + 0x78, 0x30, 0x00, 0x27, 0x00, 0x25, 0x8a, 0x42, + 0x4c, 0xd1, 0xb1, 0x7a, 0x00, 0x29, 0x02, 0xd1, + 0x68, 0x34, 0xa2, 0xc4, 0x74, 0x3c, 0x61, 0x6f, + 0x00, 0x29, 0x05, 0xd0, 0xb1, 0x7a, 0x00, 0x29, + 0x02, 0xd1, 0x00, 0xf0, 0x1f, 0xff, 0x65, 0x67, + 0x60, 0x7e, 0x00, 0x28, 0x03, 0xd0, 0x65, 0x76, + 0x01, 0x20, 0x20, 0x76, 0x46, 0xe0, 0x25, 0x76, + 0x20, 0x6d, 0x00, 0x68, 0x00, 0x28, 0x05, 0xd0, + 0x41, 0x6c, 0x61, 0x64, 0x8c, 0x64, 0xa0, 0x64, + 0x44, 0x64, 0x3b, 0xe0, 0x64, 0x64, 0xa4, 0x64, + 0x20, 0x6d, 0x04, 0x60, 0x1e, 0x48, 0xe1, 0x6c, + 0x02, 0x68, 0x11, 0x43, 0x01, 0x60, 0x60, 0x6d, + 0x32, 0x7a, 0x01, 0x78, 0x11, 0x43, 0x01, 0x70, + 0x1a, 0x48, 0xa1, 0x7e, 0x02, 0x68, 0x91, 0x42, + 0x28, 0xda, 0xed, 0x09, 0x00, 0x2c, 0x01, 0x01, + 0x60, 0x18, 0x48, 0x01, 0x68, 0x00, 0x29, 0x01, + 0xd1, 0x04, 0x60, 0x21, 0xe0, 0xc9, 0x7e, 0x00, + 0x29, 0x03, 0xd1, 0x14, 0x49, 0x09, 0x68, 0x01, + 0x29, 0x1a, 0xd1, 0x04, 0x60, 0x13, 0x48, 0x00, + 0x68, 0x00, 0x28, 0x15, 0xd0, 0xc0, 0x68, 0x11, + 0x4b, 0x98, 0x42, 0x11, 0xd1, 0x01, 0x27, 0x0f, + 0xe0, 0x01, 0x29, 0x00, 0xd1, 0x65, 0x76, 0x72, + 0x7a, 0x8a, 0x42, 0x09, 0xd1, 0xb1, 0x7a, 0x00, + 0x29, 0x06, 0xd0, 0x75, 0x72, 0x61, 0x6f, 0x00, + 0x29, 0x02, 0xd0, 0x00, 0xf0, 0xd1, 0xfe, 0x65, + 0x67, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0xd0, 0x65, 0x03, 0x20, 0xd4, + 0x66, 0x03, 0x20, 0xd8, 0x66, 0x03, 0x20, 0x80, + 0x65, 0x03, 0x20, 0xe8, 0x66, 0x03, 0x20, 0x4b, + 0x53, 0x41, 0x54, 0xb0, 0xb5, 0x07, 0x1c, 0x10, + 0x48, 0x00, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x84, + 0x6b, 0x00, 0xe0, 0x00, 0x24, 0x0e, 0x4d, 0x28, + 0x1c, 0x22, 0xf0, 0x61, 0xff, 0x01, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0x77, 0xff, 0x00, 0x28, 0x01, + 0xd0, 0x22, 0xf0, 0x61, 0xff, 0x00, 0x2c, 0x06, + 0xd0, 0x20, 0x1c, 0x22, 0xf0, 0x64, 0xff, 0x28, + 0x1c, 0x22, 0xf0, 0x5d, 0xff, 0x01, 0xe0, 0x22, + 0xf0, 0x4a, 0xff, 0xb0, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0xe8, 0x66, 0x03, 0x20, 0x00, + 0x67, 0x03, 0x20, 0xf0, 0xb5, 0x0f, 0x1c, 0x05, + 0x99, 0x1c, 0x1c, 0x01, 0x23, 0x15, 0x1c, 0x06, + 0x1c, 0xd9, 0x42, 0x05, 0xd0, 0x01, 0x20, 0x70, + 0x67, 0xf0, 0x1d, 0x71, 0x30, 0x00, 0xf0, 0x83, + 0xfe, 0x42, 0x48, 0x00, 0x68, 0x86, 0x42, 0x0d, + 0xd0, 0xb0, 0x6b, 0x00, 0x28, 0x0a, 0xd0, 0x22, + 0xf0, 0x2a, 0xff, 0x30, 0x1c, 0x22, 0xf0, 0x3f, + 0xff, 0x3d, 0x48, 0x22, 0xf0, 0xed, 0x09, 0x00, + 0x2d, 0x01, 0x28, 0xff, 0xb0, 0x6b, 0x00, 0x28, + 0xf1, 0xd1, 0x30, 0x7e, 0x00, 0x28, 0x68, 0xd1, + 0x37, 0x76, 0xf4, 0x66, 0xb5, 0x66, 0xb0, 0x6c, + 0xff, 0x24, 0x01, 0x34, 0x00, 0x27, 0xb0, 0x42, + 0x35, 0x4a, 0x3b, 0xd1, 0x77, 0x64, 0xb7, 0x64, + 0x30, 0x6d, 0xf3, 0x1d, 0x07, 0x60, 0x70, 0x6d, + 0x49, 0x33, 0x1b, 0x7a, 0x01, 0x78, 0x99, 0x43, + 0x01, 0x70, 0x70, 0x6d, 0x01, 0x78, 0x2f, 0x48, + 0x00, 0x29, 0x04, 0xd1, 0xf1, 0x6c, 0x03, 0x68, + 0xc9, 0x43, 0x19, 0x40, 0x01, 0x60, 0xb1, 0x7e, + 0x13, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x99, 0x42, + 0x2d, 0xd1, 0x01, 0x68, 0x00, 0x29, 0x01, 0xd1, + 0x14, 0x60, 0x28, 0xe0, 0x08, 0x06, 0x01, 0xd0, + 0x00, 0x20, 0x0a, 0xe0, 0x08, 0x0a, 0x00, 0x06, + 0x01, 0xd0, 0x08, 0x20, 0x05, 0xe0, 0x08, 0x0c, + 0x00, 0x06, 0x01, 0xd0, 0x10, 0x20, 0x00, 0xe0, + 0x18, 0x20, 0xc1, 0x40, 0x0b, 0x06, 0x1e, 0x49, + 0x1b, 0x0e, 0xcb, 0x5c, 0x18, 0x18, 0x1d, 0x4b, + 0x1b, 0x5c, 0xc0, 0x00, 0xc9, 0x5c, 0x40, 0x18, + 0x10, 0x60, 0x0c, 0xe0, 0x71, 0x6c, 0x88, 0x64, + 0x70, 0x6c, 0xb1, 0x6c, 0x48, 0x64, 0x30, 0x6d, + 0x01, 0x68, 0xb1, 0x42, 0x01, 0xd1, 0xb1, 0x6c, + 0x01, 0x60, 0xb7, 0x64, 0x77, 0x64, 0x14, 0x48, + 0x01, 0x68, 0x8e, 0x42, 0x08, 0xd1, 0x11, 0x68, + 0xa1, 0x42, 0x04, 0xda, 0x11, 0x4a, 0x89, 0x00, + 0x51, 0x58, 0x01, 0x60, 0x00, 0xe0, 0x07, 0x60, + 0x07, 0x48, 0x00, 0x68, 0x86, 0x42, 0x01, 0xd1, + 0x22, 0xf0, 0xc4, 0xfe, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xff, 0xe7, 0x01, 0x2f, 0xf9, 0xd1, + 0x01, 0x20, 0x70, 0x76, 0xf6, 0xe7, 0x00, 0x00, + 0xe8, 0x66, 0x03, 0x20, 0x00, 0x67, 0x03, 0x20, + 0xd4, 0x66, 0x03, 0x20, 0xd0, 0x65, 0x03, 0x20, + 0xed, 0x09, 0x00, 0x2e, 0x01, 0xd4, 0x65, 0x03, + 0x20, 0x34, 0xb7, 0x03, 0x20, 0xd8, 0x66, 0x03, + 0x20, 0x34, 0xb3, 0x03, 0x20, 0x88, 0xb5, 0x07, + 0x1c, 0x08, 0x48, 0x22, 0xf0, 0x9d, 0xfe, 0x00, + 0x22, 0xd2, 0x43, 0x00, 0x92, 0x00, 0x22, 0x00, + 0x23, 0x01, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0x4e, + 0xff, 0x22, 0xf0, 0x8e, 0xfe, 0x88, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x67, 0x03, + 0x20, 0xf0, 0xb5, 0x07, 0x1c, 0x1e, 0x48, 0x22, + 0xf0, 0x87, 0xfe, 0xfe, 0x1d, 0x49, 0x36, 0xb0, + 0x7a, 0x3d, 0x6f, 0x00, 0x28, 0x01, 0xd0, 0x74, + 0x7a, 0x00, 0xe0, 0x3c, 0x7e, 0x22, 0xf0, 0x78, + 0xfe, 0x00, 0x2d, 0x02, 0xd0, 0x28, 0x1c, 0x22, + 0xf0, 0x77, 0xfe, 0x15, 0x48, 0x22, 0xf0, 0x74, + 0xfe, 0x38, 0x7e, 0xa0, 0x42, 0x05, 0xd0, 0xb0, + 0x7a, 0x00, 0x28, 0x13, 0xd0, 0x70, 0x7a, 0xa0, + 0x42, 0x10, 0xd1, 0x78, 0x6f, 0x00, 0x28, 0x0d, + 0xd0, 0xf8, 0x6f, 0x00, 0x28, 0x0a, 0xd1, 0x78, + 0x67, 0xb9, 0x6e, 0x00, 0x29, 0x02, 0xd0, 0xf8, + 0x6e, 0xed, 0xf7, 0xdd, 0xfb, 0x38, 0x1c, 0x21, + 0x1c, 0xff, 0xf7, 0x74, 0xfe, 0x00, 0x2d, 0x05, + 0xd0, 0x28, 0x1c, 0x22, 0xf0, 0x65, 0xfe, 0x04, + 0x48, 0x22, 0xf0, 0x5e, 0xfe, 0x22, 0xf0, 0x4c, + 0xfe, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x00, 0x67, 0x03, 0x20, 0x88, 0xb5, 0x07, + 0x1c, 0x07, 0x48, 0x22, 0xf0, 0x45, 0xfe, 0x07, + 0x48, 0x00, 0x97, 0x00, 0x23, 0x00, 0x22, 0x02, + 0x21, 0x00, 0x68, 0xff, 0xf7, 0xf7, 0xfe, 0x22, + 0xf0, 0x37, 0xfe, 0x88, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x67, 0x03, 0x20, 0xe8, 0x66, 0x03, + 0x20, 0x80, 0xb5, 0x0f, 0x48, 0x22, 0xf0, 0x30, + 0xfe, 0x0e, 0x48, 0x0f, 0x49, 0x00, 0x68, 0x82, + 0x6c, 0x82, 0x42, 0xed, 0x09, 0x00, 0x2f, 0x01, + 0x05, 0xd1, 0x83, 0x7e, 0x0f, 0x68, 0x3f, 0x06, + 0x3f, 0x0e, 0xbb, 0x42, 0x09, 0xd0, 0x00, 0x6d, + 0x02, 0x60, 0x08, 0x68, 0x09, 0x49, 0x80, 0x00, + 0x08, 0x58, 0x08, 0x49, 0x08, 0x60, 0x22, 0xf0, + 0x22, 0xfe, 0x22, 0xf0, 0x14, 0xfe, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x67, + 0x03, 0x20, 0xe8, 0x66, 0x03, 0x20, 0xd4, 0x66, + 0x03, 0x20, 0x34, 0xb3, 0x03, 0x20, 0xd8, 0x66, + 0x03, 0x20, 0x80, 0xb5, 0x07, 0x1c, 0x10, 0x48, + 0x22, 0xf0, 0x05, 0xfe, 0x38, 0x7e, 0x00, 0x28, + 0x16, 0xd1, 0xf8, 0x7e, 0x00, 0x28, 0x13, 0xd0, + 0xb9, 0x6c, 0x0c, 0x48, 0xb9, 0x42, 0x05, 0xd1, + 0xba, 0x7e, 0x03, 0x68, 0x1b, 0x06, 0x1b, 0x0e, + 0x9a, 0x42, 0x09, 0xd0, 0x3a, 0x6d, 0x11, 0x60, + 0x00, 0x68, 0x07, 0x49, 0x80, 0x00, 0x08, 0x58, + 0x07, 0x49, 0x08, 0x60, 0x38, 0x6c, 0x38, 0x62, + 0x22, 0xf0, 0xe5, 0xfd, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, 0xd4, 0x66, + 0x03, 0x20, 0x34, 0xb3, 0x03, 0x20, 0xd8, 0x66, + 0x03, 0x20, 0x04, 0x48, 0x00, 0x68, 0x00, 0x28, + 0x03, 0xd0, 0xc1, 0x68, 0x03, 0x4b, 0x99, 0x42, + 0x00, 0xd0, 0x00, 0x20, 0x70, 0x47, 0xe8, 0x66, + 0x03, 0x20, 0x4b, 0x53, 0x41, 0x54, 0x04, 0x48, + 0x00, 0x68, 0x00, 0x28, 0x03, 0xd0, 0xc1, 0x68, + 0x03, 0x4b, 0x99, 0x42, 0x00, 0xd0, 0x00, 0x20, + 0x70, 0x47, 0xe8, 0x66, 0x03, 0x20, 0x52, 0x53, + 0x49, 0x48, 0x88, 0xb5, 0x0b, 0x4f, 0x3a, 0x68, + 0x10, 0x6e, 0x51, 0x6e, 0xd2, 0x6d, 0xed, 0xf7, + 0x3a, 0xfb, 0x08, 0x48, 0x22, 0xf0, 0xb7, 0xfd, + 0x00, 0x22, 0xd2, 0x43, 0x00, 0x92, 0x00, 0x22, + 0x00, 0x23, 0x0b, 0x21, 0x38, 0x68, 0xff, 0xf7, + 0x68, 0xfe, 0x88, 0xbc, 0x08, 0xbc, 0xed, 0x09, + 0x00, 0x30, 0x01, 0x18, 0x47, 0x00, 0x00, 0xd8, + 0x66, 0x03, 0x20, 0x00, 0x67, 0x03, 0x20, 0xf0, + 0xb5, 0x44, 0x48, 0x44, 0x4d, 0x07, 0x68, 0x28, + 0x1c, 0x22, 0xf0, 0x9f, 0xfd, 0xfc, 0x1d, 0x79, + 0x34, 0xe0, 0x68, 0x21, 0x69, 0x08, 0x40, 0x00, + 0x26, 0x00, 0x28, 0x10, 0xd0, 0xe5, 0x68, 0xe6, + 0x60, 0x22, 0xf0, 0x8f, 0xfd, 0x61, 0x69, 0x00, + 0x29, 0x02, 0xd0, 0x28, 0x1c, 0xed, 0xf7, 0x0c, + 0xfb, 0x39, 0x48, 0x22, 0xf0, 0x8a, 0xfd, 0xe0, + 0x68, 0x21, 0x69, 0x08, 0x40, 0xee, 0xd1, 0xfb, + 0x1d, 0x49, 0x33, 0x9e, 0x72, 0xf8, 0x6b, 0x00, + 0x28, 0x5e, 0xd0, 0x58, 0x7a, 0x00, 0x28, 0x59, + 0xd0, 0x38, 0x76, 0xbc, 0x6c, 0xff, 0x22, 0x01, + 0x32, 0xbc, 0x42, 0x30, 0x48, 0x2f, 0x49, 0x3b, + 0xd1, 0xbe, 0x64, 0x7e, 0x64, 0x3c, 0x6d, 0x26, + 0x60, 0x7c, 0x6d, 0x1b, 0x7a, 0x25, 0x78, 0xdb, + 0x43, 0x2b, 0x40, 0x23, 0x70, 0x7b, 0x6d, 0x1c, + 0x78, 0x2a, 0x4b, 0x00, 0x2c, 0x04, 0xd1, 0xfc, + 0x6c, 0x1d, 0x68, 0xe4, 0x43, 0x2c, 0x40, 0x1c, + 0x60, 0xbf, 0x7e, 0x04, 0x68, 0x24, 0x06, 0x24, + 0x0e, 0xa7, 0x42, 0x2e, 0xd1, 0x1c, 0x68, 0x00, + 0x2c, 0x01, 0xd1, 0x02, 0x60, 0x31, 0xe0, 0x23, + 0x06, 0x01, 0xd0, 0x00, 0x27, 0x0a, 0xe0, 0x23, + 0x0a, 0x1b, 0x06, 0x01, 0xd0, 0x08, 0x27, 0x05, + 0xe0, 0x23, 0x0c, 0x1b, 0x06, 0x01, 0xd0, 0x10, + 0x27, 0x00, 0xe0, 0x18, 0x27, 0xfc, 0x40, 0x23, + 0x1c, 0x24, 0x06, 0x18, 0x4b, 0x24, 0x0e, 0x1c, + 0x5d, 0xe7, 0x19, 0x17, 0x4c, 0xe4, 0x5d, 0xff, + 0x00, 0x1b, 0x5d, 0xfb, 0x18, 0x03, 0x60, 0x0c, + 0xe0, 0x7b, 0x6c, 0x9c, 0x64, 0x7b, 0x6c, 0xbc, + 0x6c, 0x63, 0x64, 0x3b, 0x6d, 0x1c, 0x68, 0xbc, + 0x42, 0x01, 0xd1, 0xbc, 0x6c, 0x1c, 0x60, 0xbe, + 0x64, 0xed, 0x09, 0x00, 0x31, 0x01, 0x7e, 0x64, + 0x00, 0x68, 0x90, 0x42, 0x04, 0xda, 0x0d, 0x4a, + 0x80, 0x00, 0x10, 0x58, 0x08, 0x60, 0x00, 0xe0, + 0x0e, 0x60, 0x22, 0xf0, 0x25, 0xfd, 0x22, 0xf0, + 0x1b, 0xfd, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xe8, 0x66, 0x03, 0x20, 0x00, 0x67, 0x03, 0x20, + 0xd8, 0x66, 0x03, 0x20, 0xd4, 0x66, 0x03, 0x20, + 0xd0, 0x65, 0x03, 0x20, 0xd4, 0x65, 0x03, 0x20, + 0x34, 0xb7, 0x03, 0x20, 0x34, 0xb3, 0x03, 0x20, + 0x00, 0xb5, 0x08, 0x49, 0x09, 0x5c, 0x00, 0x29, + 0x06, 0xd0, 0x07, 0x4a, 0x89, 0x00, 0x51, 0x58, + 0xed, 0xf7, 0x81, 0xfa, 0x08, 0xbc, 0x18, 0x47, + 0x04, 0x49, 0x08, 0x60, 0x04, 0x20, 0x00, 0xf0, + 0x3b, 0xfc, 0xf7, 0xe7, 0x6c, 0xb7, 0x03, 0x20, + 0x78, 0xb7, 0x03, 0x20, 0x1c, 0x67, 0x03, 0x20, + 0xf0, 0xb5, 0x15, 0x1c, 0x0e, 0x1c, 0x07, 0x1c, + 0x0a, 0x28, 0x04, 0xdd, 0x1a, 0x20, 0xc0, 0x43, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x24, + 0x20, 0x48, 0x22, 0xf0, 0xe5, 0xfc, 0x00, 0x22, + 0x00, 0x2e, 0x1f, 0x4b, 0x1f, 0x49, 0x2a, 0xd0, + 0xc8, 0x5d, 0x00, 0x28, 0x07, 0xd0, 0xca, 0x55, + 0x82, 0x00, 0x9b, 0x58, 0x2b, 0x60, 0x1a, 0x4b, + 0x9e, 0x50, 0xc8, 0x55, 0x2a, 0xe0, 0x01, 0x20, + 0x00, 0xe0, 0x01, 0x30, 0x81, 0x00, 0x59, 0x58, + 0x00, 0x29, 0x02, 0xd0, 0x0a, 0x28, 0xf8, 0xdd, + 0x12, 0xe0, 0x0a, 0x28, 0x10, 0xdc, 0x81, 0x00, + 0x5e, 0x50, 0x12, 0x49, 0xc8, 0x55, 0x2a, 0x60, + 0xfe, 0xf7, 0x16, 0xfb, 0x00, 0x28, 0x15, 0xd1, + 0x38, 0x1c, 0xfe, 0xf7, 0x13, 0xfb, 0x01, 0x1c, + 0x38, 0x1c, 0xfe, 0xf7, 0x11, 0xfb, 0x0d, 0xe0, + 0x20, 0x24, 0xe4, 0x43, 0x0a, 0xe0, 0xc8, 0x5d, + 0x00, 0x28, 0x05, 0xd0, 0xca, 0x55, 0x80, 0x00, + 0x19, 0x58, 0x29, 0x60, 0xed, 0x09, 0x00, 0x32, + 0x01, 0x1a, 0x50, 0x01, 0xe0, 0x24, 0x24, 0xe4, + 0x43, 0x22, 0xf0, 0xa4, 0xfc, 0x20, 0x1c, 0xb9, + 0xe7, 0x08, 0x67, 0x03, 0x20, 0x78, 0xb7, 0x03, + 0x20, 0x6c, 0xb7, 0x03, 0x20, 0xa0, 0x65, 0x03, + 0x20, 0xa8, 0x65, 0x03, 0x20, 0xac, 0x65, 0x03, + 0x20, 0xb8, 0x65, 0x03, 0x20, 0xb0, 0x65, 0x03, + 0x20, 0xe8, 0x66, 0x03, 0x20, 0xb4, 0x65, 0x03, + 0x20, 0xdc, 0xb2, 0x03, 0x20, 0x18, 0x67, 0x03, + 0x20, 0x2c, 0x10, 0x1f, 0xe5, 0x00, 0x00, 0x81, + 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x38, 0x00, 0x1f, + 0xe5, 0x00, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, + 0xe1, 0x40, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x90, + 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x4c, 0x10, 0x1f, + 0xe5, 0x00, 0x00, 0x81, 0xe5, 0x00, 0x00, 0xa0, + 0xe3, 0x54, 0x10, 0x1f, 0xe5, 0x00, 0x00, 0x81, + 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x20, 0x0f, + 0xe1, 0xc0, 0x20, 0x82, 0xe3, 0x02, 0xf0, 0x2f, + 0xe1, 0x70, 0x10, 0x1f, 0xe5, 0x00, 0x20, 0x91, + 0xe5, 0x00, 0x00, 0x52, 0xe1, 0x00, 0x00, 0x00, + 0xba, 0x00, 0x00, 0x81, 0xe5, 0x68, 0x10, 0x1f, + 0xe5, 0x00, 0x10, 0x91, 0xe5, 0x00, 0x20, 0x0f, + 0xe1, 0xc0, 0x20, 0xc2, 0xe3, 0x01, 0x20, 0x82, + 0xe1, 0x02, 0xf0, 0x2f, 0xe1, 0x1e, 0xff, 0x2f, + 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0xa0, 0x00, 0x1f, + 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, + 0xe1, 0x9c, 0x10, 0x1f, 0xe5, 0x00, 0x00, 0x91, + 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xc0, 0x00, 0x1f, + 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x10, 0x81, + 0xe2, 0x00, 0x10, 0x80, 0xe5, 0xc8, 0x10, 0x1f, + 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x02, 0x30, 0xa0, + 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x07, 0x00, 0x00, + 0x1a, 0xe0, 0x00, 0x1f, 0xe5, 0x00, 0x20, 0xed, + 0x09, 0x00, 0x33, 0x01, 0x90, 0xe5, 0x00, 0x00, + 0x52, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x20, + 0x52, 0xe2, 0x00, 0x20, 0x80, 0xe5, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x30, 0x81, 0x05, 0xf8, 0x00, + 0x1f, 0xe5, 0x00, 0x20, 0x90, 0xe5, 0x00, 0x00, + 0x52, 0xe3, 0x0c, 0x00, 0x00, 0x1a, 0x04, 0x21, + 0x1f, 0xe5, 0x00, 0x30, 0x92, 0xe5, 0x01, 0x30, + 0x53, 0xe2, 0x00, 0x30, 0x82, 0xe5, 0x07, 0x00, + 0x00, 0x1a, 0x02, 0x30, 0xa0, 0xe3, 0x00, 0x30, + 0x80, 0xe5, 0x1c, 0x21, 0x1f, 0xe5, 0x00, 0x20, + 0x92, 0xe5, 0x20, 0x31, 0x1f, 0xe5, 0x00, 0x20, + 0x83, 0xe5, 0x01, 0x30, 0xa0, 0xe3, 0x20, 0x30, + 0xa2, 0xe5, 0x00, 0x10, 0x91, 0xe5, 0x02, 0x00, + 0x51, 0xe3, 0x00, 0x00, 0x90, 0x15, 0x02, 0x00, + 0x50, 0x13, 0x1e, 0xff, 0x2f, 0x11, 0x04, 0xe0, + 0x2d, 0xe5, 0x44, 0x01, 0x1f, 0xe5, 0xc5, 0xfc, + 0xff, 0xeb, 0x04, 0xe0, 0x9d, 0xe4, 0x1e, 0xff, + 0x2f, 0xe1, 0xf0, 0xb5, 0x83, 0xb0, 0x04, 0x1c, + 0x54, 0x48, 0x0f, 0x1c, 0x22, 0xf0, 0xe5, 0xfb, + 0xa0, 0x7e, 0x00, 0x90, 0xb8, 0x42, 0x63, 0xd0, + 0xfe, 0x10, 0x50, 0x48, 0x01, 0x22, 0x31, 0x18, + 0x10, 0x1c, 0xb0, 0x40, 0x7e, 0x07, 0x76, 0x0f, + 0xb2, 0x40, 0x12, 0x06, 0x12, 0x0e, 0x4c, 0x4e, + 0xbb, 0x00, 0x9b, 0x19, 0x25, 0x7e, 0x02, 0x93, + 0xe3, 0x1d, 0x49, 0x33, 0x00, 0x2d, 0x74, 0xd1, + 0xa5, 0x6c, 0xa5, 0x42, 0x17, 0xd1, 0x00, 0x25, + 0x65, 0x64, 0xa5, 0x64, 0x26, 0x6d, 0x35, 0x60, + 0x65, 0x6d, 0x01, 0x95, 0x2d, 0x78, 0x1e, 0x7a, + 0xb5, 0x43, 0x01, 0x9e, 0x35, 0x70, 0x65, 0x6d, + 0x2d, 0x78, 0x00, 0x2d, 0x16, 0xd1, 0x3f, 0x4e, + 0xe5, 0x6c, 0x36, 0x68, 0xed, 0x43, 0x35, 0x40, + 0x3d, 0x4e, 0x35, 0x60, 0x0e, 0xe0, 0x66, 0x6c, + 0xb5, 0x64, 0xed, 0x09, 0x00, 0x34, 0x01, 0x65, + 0x6c, 0xa6, 0x6c, 0x75, 0x64, 0x25, 0x6d, 0x2e, + 0x1c, 0x2d, 0x68, 0xa5, 0x42, 0x01, 0xd1, 0xa5, + 0x6c, 0x35, 0x60, 0x00, 0x25, 0x65, 0x64, 0xa5, + 0x64, 0xa7, 0x76, 0x02, 0x9d, 0x32, 0x4f, 0x25, + 0x65, 0x1a, 0x72, 0xe0, 0x64, 0x61, 0x65, 0x21, + 0x6d, 0x2e, 0x48, 0x09, 0x68, 0x00, 0x29, 0x05, + 0xd0, 0x4a, 0x6c, 0x62, 0x64, 0x94, 0x64, 0xa1, + 0x64, 0x4c, 0x64, 0x0d, 0xe0, 0x64, 0x64, 0xa4, + 0x64, 0x21, 0x6d, 0x29, 0x4a, 0x0c, 0x60, 0xe1, + 0x6c, 0x15, 0x68, 0x29, 0x43, 0x11, 0x60, 0x61, + 0x6d, 0x1b, 0x7a, 0x0a, 0x78, 0x1a, 0x43, 0x0a, + 0x70, 0x24, 0x4a, 0x12, 0x68, 0x11, 0x06, 0x02, + 0xd0, 0x00, 0x21, 0x0b, 0xe0, 0x34, 0xe0, 0x11, + 0x0a, 0x09, 0x06, 0x01, 0xd0, 0x08, 0x21, 0x05, + 0xe0, 0x11, 0x0c, 0x09, 0x06, 0x01, 0xd0, 0x10, + 0x21, 0x00, 0xe0, 0x18, 0x21, 0xca, 0x40, 0x13, + 0x06, 0x1b, 0x4a, 0x1b, 0x0e, 0xd3, 0x5c, 0x59, + 0x18, 0x40, 0x5c, 0xc9, 0x00, 0x10, 0x5c, 0x19, + 0x4a, 0x08, 0x18, 0x17, 0x49, 0x08, 0x60, 0x11, + 0x68, 0x8b, 0x7e, 0x83, 0x42, 0x18, 0xdb, 0xc9, + 0x7e, 0x00, 0x29, 0x15, 0xd0, 0x80, 0x00, 0x38, + 0x58, 0x10, 0x60, 0x13, 0x48, 0x00, 0xe0, 0x09, + 0xe0, 0x00, 0x68, 0x00, 0x28, 0x0c, 0xd0, 0xc0, + 0x68, 0x11, 0x4b, 0x98, 0x42, 0x08, 0xd1, 0x22, + 0xf0, 0x56, 0xfb, 0x05, 0xe0, 0xa7, 0x76, 0x02, + 0x9d, 0x25, 0x65, 0x1a, 0x72, 0xe0, 0x64, 0x61, + 0x65, 0x22, 0xf0, 0x41, 0xfb, 0x00, 0x98, 0x03, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x67, 0x03, 0x20, 0x34, 0xb7, 0x03, 0x20, 0x34, + 0xb3, 0x03, 0x20, 0xd0, 0x65, 0x03, 0x20, 0xd4, + 0x65, 0x03, 0x20, 0xd4, 0x66, 0x03, 0x20, 0xd8, + 0x66, 0x03, 0x20, 0xe8, 0x66, 0xed, 0x09, 0x00, + 0x35, 0x01, 0x03, 0x20, 0x4b, 0x53, 0x41, 0x54, + 0x90, 0xb5, 0x04, 0x1c, 0x13, 0x48, 0x22, 0xf0, + 0x29, 0xfb, 0x13, 0x48, 0x00, 0x68, 0xc1, 0x7e, + 0x00, 0x29, 0x01, 0xd0, 0x0a, 0x27, 0x00, 0xe0, + 0x08, 0x27, 0x10, 0x49, 0x08, 0x2c, 0x03, 0xd1, + 0x09, 0x68, 0x00, 0x20, 0xc8, 0x76, 0x0f, 0xe0, + 0x01, 0x22, 0xc2, 0x76, 0x0a, 0x68, 0x90, 0x42, + 0x0a, 0xd1, 0x0b, 0x48, 0x92, 0x7e, 0x00, 0x68, + 0x82, 0x42, 0x05, 0xdd, 0x09, 0x4a, 0x80, 0x00, + 0x10, 0x58, 0x08, 0x60, 0x22, 0xf0, 0x12, 0xfb, + 0x22, 0xf0, 0x04, 0xfb, 0x38, 0x1c, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, + 0xe8, 0x66, 0x03, 0x20, 0xd8, 0x66, 0x03, 0x20, + 0xd4, 0x66, 0x03, 0x20, 0x34, 0xb3, 0x03, 0x20, + 0xb0, 0xb5, 0x0c, 0x1c, 0x05, 0x1c, 0x07, 0x48, + 0x22, 0xf0, 0xf4, 0xfa, 0x2f, 0x6c, 0x2c, 0x64, + 0x05, 0x49, 0x2c, 0x62, 0x00, 0x20, 0x08, 0x60, + 0x22, 0xf0, 0xe8, 0xfa, 0x38, 0x1c, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, + 0xb8, 0x65, 0x03, 0x20, 0xb0, 0xb5, 0x04, 0x1c, + 0x11, 0x48, 0x05, 0x68, 0x11, 0x48, 0x22, 0xf0, + 0xdd, 0xfa, 0xe8, 0x1d, 0x79, 0x30, 0x07, 0x69, + 0x04, 0x61, 0xc1, 0x68, 0x21, 0x40, 0x10, 0xd0, + 0xe9, 0x1d, 0x49, 0x31, 0x8a, 0x7a, 0x00, 0x2a, + 0x0b, 0xd1, 0x40, 0x69, 0x00, 0x28, 0x08, 0xd0, + 0x01, 0x20, 0x88, 0x72, 0x00, 0x20, 0xe8, 0x63, + 0x22, 0xf0, 0xc4, 0xfa, 0xff, 0xf7, 0x20, 0xfd, + 0x01, 0xe0, 0x22, 0xf0, 0xbf, 0xfa, 0x38, 0x1c, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0xe8, 0x66, 0x03, 0x20, 0x00, 0x67, 0x03, 0x20, + 0x80, 0xb5, 0x08, 0x48, 0x07, 0x68, 0x08, 0x48, + 0x22, 0xf0, 0xb4, 0xfa, 0xf9, 0x1d, 0x79, 0x31, + 0xed, 0x09, 0x00, 0x36, 0x01, 0xcf, 0x68, 0x00, + 0x20, 0xc8, 0x60, 0x22, 0xf0, 0xa9, 0xfa, 0x38, + 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0xe8, 0x66, 0x03, 0x20, 0x00, 0x67, 0x03, + 0x20, 0xb0, 0xb5, 0x07, 0x1c, 0x11, 0x48, 0x04, + 0x68, 0x11, 0x48, 0x22, 0xf0, 0x9d, 0xfa, 0xe0, + 0x1d, 0x79, 0x30, 0x47, 0x61, 0x01, 0x69, 0xc0, + 0x68, 0x08, 0x40, 0x00, 0x25, 0x00, 0x28, 0x0e, + 0xd0, 0xe0, 0x1d, 0x49, 0x30, 0x81, 0x7a, 0x00, + 0x29, 0x09, 0xd1, 0x00, 0x2f, 0x07, 0xd0, 0x01, + 0x21, 0x81, 0x72, 0xe5, 0x63, 0x22, 0xf0, 0x84, + 0xfa, 0xff, 0xf7, 0xe0, 0xfc, 0x01, 0xe0, 0x22, + 0xf0, 0x7f, 0xfa, 0x28, 0x1c, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x66, 0x03, + 0x20, 0x00, 0x67, 0x03, 0x20, 0xf0, 0xb5, 0x28, + 0x4e, 0x0c, 0x1c, 0x07, 0x1c, 0x30, 0x1c, 0x22, + 0xf0, 0x73, 0xfa, 0xf8, 0x1d, 0x79, 0x30, 0xc1, + 0x68, 0x21, 0x43, 0xc1, 0x60, 0x02, 0x69, 0x11, + 0x40, 0x00, 0x25, 0x00, 0x29, 0x39, 0xd0, 0xfc, + 0x1d, 0x49, 0x34, 0xa1, 0x7a, 0x00, 0x29, 0x34, + 0xd1, 0x39, 0x7e, 0x0c, 0x29, 0x31, 0xd0, 0x0b, + 0x29, 0x2f, 0xd0, 0x40, 0x69, 0x00, 0x28, 0x2c, + 0xd0, 0x01, 0x20, 0x1a, 0x49, 0xa0, 0x72, 0x09, + 0x68, 0x8f, 0x42, 0x05, 0xd1, 0xfd, 0x63, 0x22, + 0xf0, 0x4f, 0xfa, 0xff, 0xf7, 0xab, 0xfc, 0x20, + 0xe0, 0xb8, 0x6b, 0x00, 0x28, 0x0a, 0xd0, 0x22, + 0xf0, 0x47, 0xfa, 0x38, 0x1c, 0x22, 0xf0, 0x5c, + 0xfa, 0x30, 0x1c, 0x22, 0xf0, 0x45, 0xfa, 0xb8, + 0x6b, 0x00, 0x28, 0xf1, 0xd1, 0x38, 0x7e, 0x60, + 0x72, 0xf8, 0x6a, 0xf8, 0x63, 0x38, 0x1c, 0x22, + 0xf0, 0x5b, 0xfa, 0x39, 0x7e, 0x00, 0x29, 0x08, + 0xd0, 0x01, 0x29, 0x06, 0xd0, 0x38, 0x1c, 0xff, + 0xf7, 0x4d, 0xfa, 0xed, 0x09, 0x00, 0x37, 0x01, + 0x00, 0x28, 0x01, 0xd0, 0x22, 0xf0, 0x37, 0xfa, + 0x22, 0xf0, 0x29, 0xfa, 0x28, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x67, + 0x03, 0x20, 0xe8, 0x66, 0x03, 0x20, 0x00, 0x48, + 0x70, 0x47, 0xdc, 0x5b, 0x03, 0x20, 0x00, 0x48, + 0x70, 0x47, 0x70, 0x5c, 0x03, 0x20, 0x01, 0x49, + 0x00, 0x20, 0x08, 0x60, 0x70, 0x47, 0x20, 0x67, + 0x03, 0x20, 0x05, 0x49, 0x00, 0x20, 0x08, 0x60, + 0x05, 0x49, 0x08, 0x60, 0x05, 0x49, 0x08, 0x60, + 0x05, 0x49, 0x08, 0x60, 0x05, 0x49, 0x08, 0x60, + 0x70, 0x47, 0x24, 0x67, 0x03, 0x20, 0x28, 0x67, + 0x03, 0x20, 0x2c, 0x67, 0x03, 0x20, 0x30, 0x67, + 0x03, 0x20, 0x34, 0x67, 0x03, 0x20, 0x80, 0xb4, + 0x24, 0x48, 0x00, 0x21, 0x01, 0x60, 0x23, 0x48, + 0xff, 0x22, 0x01, 0x60, 0x00, 0x20, 0x22, 0x4f, + 0x01, 0x32, 0x83, 0x00, 0x01, 0x30, 0x90, 0x42, + 0xf9, 0x50, 0xfa, 0xdb, 0x20, 0x48, 0x20, 0x4b, + 0x01, 0x60, 0x00, 0x20, 0x19, 0x54, 0x01, 0x30, + 0x20, 0x28, 0xfb, 0xdb, 0x1e, 0x48, 0x23, 0x4f, + 0x02, 0x60, 0x1d, 0x48, 0x23, 0x4b, 0x01, 0x60, + 0x1d, 0x48, 0x01, 0x60, 0x1d, 0x48, 0x01, 0x60, + 0x1d, 0x48, 0x01, 0x60, 0x1d, 0x48, 0x01, 0x60, + 0x00, 0x20, 0x82, 0x00, 0x99, 0x50, 0x01, 0x30, + 0x03, 0x28, 0xb9, 0x50, 0xf9, 0xdb, 0x1b, 0x4a, + 0x00, 0x20, 0x11, 0x54, 0x01, 0x30, 0x0a, 0x28, + 0xfb, 0xdb, 0x19, 0x4a, 0x00, 0x20, 0x83, 0x00, + 0x01, 0x30, 0x0a, 0x28, 0xd1, 0x50, 0xfa, 0xdd, + 0x17, 0x48, 0x01, 0x60, 0x17, 0x48, 0x01, 0x60, + 0x17, 0x48, 0x01, 0x60, 0x17, 0x48, 0x01, 0x60, + 0x17, 0x48, 0x01, 0x60, 0x17, 0x48, 0x01, 0x60, + 0x17, 0x48, 0x01, 0x60, 0x80, 0xbc, 0x70, 0x47, + 0x00, 0x00, 0xc8, 0x65, 0x03, 0x20, 0xed, 0x09, + 0x00, 0x38, 0x01, 0xcc, 0x65, 0x03, 0x20, 0x34, + 0xb3, 0x03, 0x20, 0xd0, 0x65, 0x03, 0x20, 0x34, + 0xb7, 0x03, 0x20, 0xd4, 0x66, 0x03, 0x20, 0xd8, + 0x66, 0x03, 0x20, 0xe4, 0x66, 0x03, 0x20, 0xe8, + 0x66, 0x03, 0x20, 0xdc, 0x66, 0x03, 0x20, 0xe0, + 0x66, 0x03, 0x20, 0x60, 0xb7, 0x03, 0x20, 0x54, + 0xb7, 0x03, 0x20, 0x6c, 0xb7, 0x03, 0x20, 0x78, + 0xb7, 0x03, 0x20, 0xf0, 0x66, 0x03, 0x20, 0xf4, + 0x66, 0x03, 0x20, 0xf8, 0x66, 0x03, 0x20, 0x00, + 0x67, 0x03, 0x20, 0x08, 0x67, 0x03, 0x20, 0x10, + 0x67, 0x03, 0x20, 0x18, 0x67, 0x03, 0x20, 0x03, + 0x49, 0x00, 0x20, 0x08, 0x60, 0x03, 0x49, 0x08, + 0x60, 0x03, 0x49, 0x08, 0x60, 0x70, 0x47, 0x3c, + 0x67, 0x03, 0x20, 0x40, 0x67, 0x03, 0x20, 0x44, + 0x67, 0x03, 0x20, 0x03, 0x49, 0x00, 0x20, 0x08, + 0x60, 0x03, 0x49, 0x08, 0x60, 0x03, 0x49, 0x08, + 0x60, 0x70, 0x47, 0x4c, 0x67, 0x03, 0x20, 0x50, + 0x67, 0x03, 0x20, 0x54, 0x67, 0x03, 0x20, 0x03, + 0x49, 0x00, 0x20, 0x08, 0x60, 0x03, 0x49, 0x08, + 0x60, 0x03, 0x49, 0x08, 0x60, 0x70, 0x47, 0x5c, + 0x67, 0x03, 0x20, 0x60, 0x67, 0x03, 0x20, 0x64, + 0x67, 0x03, 0x20, 0x03, 0x49, 0x00, 0x20, 0x08, + 0x60, 0x03, 0x49, 0x08, 0x60, 0x03, 0x49, 0x08, + 0x60, 0x70, 0x47, 0x6c, 0x67, 0x03, 0x20, 0x70, + 0x67, 0x03, 0x20, 0x74, 0x67, 0x03, 0x20, 0x03, + 0x49, 0x00, 0x20, 0x08, 0x60, 0x03, 0x49, 0x08, + 0x60, 0x03, 0x49, 0x08, 0x60, 0x70, 0x47, 0x7c, + 0x67, 0x03, 0x20, 0x80, 0x67, 0x03, 0x20, 0x84, + 0x67, 0x03, 0x20, 0x03, 0x49, 0x00, 0x20, 0x08, + 0x60, 0x03, 0x49, 0x08, 0x60, 0x03, 0x49, 0x08, + 0x60, 0x70, 0x47, 0x8c, 0x67, 0x03, 0x20, 0x90, + 0x67, 0x03, 0x20, 0x94, 0x67, 0x03, 0x20, 0x03, + 0x49, 0xed, 0x09, 0x00, 0x39, 0x01, 0x00, 0x20, + 0x08, 0x60, 0x03, 0x49, 0x08, 0x60, 0x03, 0x49, + 0x08, 0x60, 0x70, 0x47, 0x9c, 0x67, 0x03, 0x20, + 0xa0, 0x67, 0x03, 0x20, 0xa4, 0x67, 0x03, 0x20, + 0x00, 0xb5, 0x82, 0xb0, 0x18, 0x49, 0x00, 0x20, + 0x08, 0x60, 0x18, 0x49, 0x1c, 0x4a, 0x08, 0x60, + 0x17, 0x49, 0x08, 0x60, 0x17, 0x49, 0x08, 0x60, + 0x17, 0x49, 0x08, 0x60, 0x17, 0x49, 0x08, 0x60, + 0x01, 0x21, 0x11, 0x60, 0x17, 0x4a, 0x10, 0x60, + 0x17, 0x4a, 0x10, 0x60, 0x17, 0x4a, 0x11, 0x60, + 0x17, 0x49, 0x08, 0x60, 0x01, 0x1c, 0x17, 0x48, + 0xc1, 0x60, 0x17, 0x49, 0x0a, 0x68, 0x17, 0x49, + 0x09, 0x68, 0x01, 0x92, 0x00, 0x91, 0x16, 0x49, + 0x16, 0x4a, 0x09, 0x68, 0x0b, 0x06, 0x1b, 0x0e, + 0x15, 0xa1, 0xfe, 0xf7, 0xf3, 0xff, 0x00, 0x28, + 0x02, 0xd0, 0x01, 0x20, 0x00, 0xf0, 0x38, 0xf8, + 0x02, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x88, 0x65, 0x03, 0x20, 0x8c, 0x65, 0x03, 0x20, + 0x90, 0x65, 0x03, 0x20, 0x94, 0x65, 0x03, 0x20, + 0xa0, 0x65, 0x03, 0x20, 0xa8, 0x65, 0x03, 0x20, + 0xac, 0x65, 0x03, 0x20, 0xb0, 0x65, 0x03, 0x20, + 0xb4, 0x65, 0x03, 0x20, 0xb8, 0x65, 0x03, 0x20, + 0x98, 0x65, 0x03, 0x20, 0xdc, 0xb2, 0x03, 0x20, + 0xc0, 0x65, 0x03, 0x20, 0xbc, 0x65, 0x03, 0x20, + 0xc4, 0x65, 0x03, 0x20, 0xa1, 0x38, 0x01, 0x20, + 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x20, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x49, 0x00, 0x20, + 0x08, 0x60, 0x03, 0x49, 0x08, 0x60, 0x03, 0x49, + 0x08, 0x60, 0x70, 0x47, 0xac, 0x67, 0x03, 0x20, + 0xb0, 0x67, 0x03, 0x20, 0xb4, 0x67, 0x03, 0x20, + 0x01, 0x49, 0x08, 0x60, 0xff, 0xe7, 0xfe, 0xe7, + 0x20, 0x67, 0x03, 0x20, 0x00, 0x22, 0x02, 0x60, + 0x81, 0x60, 0xc2, 0x60, 0xed, 0x09, 0x00, 0x3a, + 0x01, 0x02, 0x61, 0x70, 0x47, 0x00, 0xb5, 0x00, + 0xf0, 0x0a, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xc1, 0x68, 0x00, 0x29, 0x01, 0xd0, 0x00, + 0xf0, 0x65, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xf0, + 0xb5, 0x0c, 0x1c, 0x2c, 0x49, 0x07, 0x1c, 0x0d, + 0x68, 0x2b, 0x4e, 0x00, 0x2d, 0x10, 0xd1, 0xff, + 0x60, 0x3f, 0x61, 0x2a, 0x4a, 0x0f, 0x60, 0x14, + 0x60, 0x7c, 0x60, 0x00, 0x2c, 0x05, 0xd0, 0x10, + 0x68, 0x22, 0xf0, 0xb8, 0xf8, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x02, 0x20, 0x30, 0x60, 0xf9, + 0xe7, 0x23, 0x48, 0x00, 0x68, 0x00, 0x28, 0x0e, + 0xd1, 0x22, 0xf0, 0xbc, 0xf8, 0x1f, 0x4a, 0x11, + 0x68, 0x08, 0x1a, 0x09, 0x1a, 0x11, 0x60, 0x69, + 0x68, 0x81, 0x42, 0x02, 0xd9, 0x08, 0x1a, 0x68, + 0x60, 0x01, 0xe0, 0x00, 0x20, 0x68, 0x60, 0x17, + 0x49, 0x00, 0x20, 0x0a, 0x68, 0x6b, 0x68, 0xa3, + 0x42, 0x07, 0xd9, 0x68, 0x68, 0x00, 0x1b, 0x68, + 0x60, 0x08, 0x68, 0x85, 0x42, 0x07, 0xd1, 0x0f, + 0x60, 0x05, 0xe0, 0xed, 0x68, 0xe4, 0x1a, 0x95, + 0x42, 0x01, 0xd0, 0x00, 0x28, 0xee, 0xd0, 0xfd, + 0x60, 0x28, 0x69, 0x38, 0x61, 0x28, 0x69, 0xc7, + 0x60, 0x2f, 0x61, 0x0d, 0x48, 0x7c, 0x60, 0x00, + 0x68, 0x00, 0x28, 0xc7, 0xd1, 0x08, 0x68, 0x09, + 0x4a, 0x40, 0x68, 0x11, 0x68, 0x88, 0x42, 0xc1, + 0xd8, 0x10, 0x60, 0x00, 0x28, 0x02, 0xd0, 0x22, + 0xf0, 0x81, 0xf8, 0xbb, 0xe7, 0x02, 0x20, 0x30, + 0x60, 0xb8, 0xe7, 0x00, 0x00, 0x90, 0x65, 0x03, + 0x20, 0xac, 0x65, 0x03, 0x20, 0xa4, 0x65, 0x03, + 0x20, 0x94, 0x65, 0x03, 0x20, 0x90, 0xb5, 0xc1, + 0x68, 0x07, 0x1c, 0x0f, 0x48, 0x02, 0x68, 0x91, + 0x42, 0x03, 0xd0, 0x4a, 0x68, 0x7b, 0x68, 0xd2, + 0x18, 0x4a, 0x60, 0xf9, 0x68, 0x00, 0x24, 0xed, + 0x09, 0x00, 0x3b, 0x01, 0xb9, 0x42, 0x03, 0xd1, + 0x04, 0x60, 0x22, 0xf0, 0x5a, 0xf8, 0x09, 0xe0, + 0x3a, 0x69, 0xd1, 0x60, 0x39, 0x69, 0xfa, 0x68, + 0x11, 0x61, 0x01, 0x68, 0xb9, 0x42, 0x01, 0xd1, + 0xf9, 0x68, 0x01, 0x60, 0xfc, 0x60, 0x3c, 0x61, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0x65, + 0x03, 0x20, 0x00, 0xb5, 0x0a, 0x48, 0x00, 0x68, + 0x02, 0x28, 0x01, 0xd1, 0x00, 0xf0, 0x15, 0xf8, + 0x22, 0xf0, 0x43, 0xf8, 0x00, 0x28, 0x07, 0xd0, + 0x06, 0x4a, 0x01, 0x21, 0x11, 0x60, 0xff, 0xf7, + 0x06, 0xfa, 0x04, 0x49, 0x00, 0x20, 0x08, 0x60, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xac, 0x65, + 0x03, 0x20, 0xb8, 0x65, 0x03, 0x20, 0xb4, 0x65, + 0x03, 0x20, 0xf0, 0xb5, 0x83, 0xb0, 0x00, 0x20, + 0x00, 0x21, 0x36, 0x4c, 0x02, 0x90, 0x01, 0x90, + 0x00, 0x25, 0x20, 0x1c, 0x00, 0x91, 0x21, 0xf0, + 0xf8, 0xff, 0x22, 0xf0, 0x1e, 0xf8, 0x32, 0x48, + 0x01, 0x27, 0x07, 0x60, 0x32, 0x48, 0x00, 0x68, + 0x00, 0x28, 0x09, 0xd0, 0x31, 0x49, 0x42, 0x68, + 0x09, 0x68, 0x8a, 0x42, 0x02, 0xd9, 0x51, 0x1a, + 0x41, 0x60, 0x01, 0xe0, 0x00, 0x21, 0x41, 0x60, + 0x21, 0xf0, 0xdf, 0xff, 0x00, 0x26, 0x27, 0x48, + 0x21, 0xf0, 0xdf, 0xff, 0x28, 0x48, 0x07, 0x68, + 0x00, 0x2f, 0x23, 0xd0, 0x78, 0x68, 0x00, 0x28, + 0x20, 0xd1, 0x38, 0x68, 0x01, 0x28, 0x16, 0xd1, + 0xbc, 0x68, 0x01, 0x25, 0x60, 0x6a, 0x40, 0x19, + 0x60, 0x62, 0xe0, 0x69, 0x01, 0x90, 0xa1, 0x69, + 0x00, 0x20, 0x00, 0x91, 0x20, 0x62, 0x38, 0x1c, + 0xff, 0xf7, 0x83, 0xff, 0xe1, 0x6a, 0x00, 0x29, + 0x0d, 0xd0, 0x01, 0x20, 0x20, 0x62, 0x38, 0x1c, + 0xff, 0xf7, 0x18, 0xff, 0x07, 0xe0, 0x00, 0x25, + 0x38, 0x1c, 0xff, 0xf7, 0x76, 0xff, 0xb8, 0x68, + 0x02, 0x90, 0xed, 0x09, 0x00, 0x3c, 0x01, 0x00, + 0xe0, 0x01, 0x26, 0x21, 0xf0, 0xb0, 0xff, 0x00, + 0x2e, 0x0a, 0xd1, 0x01, 0x2d, 0x04, 0xd1, 0x01, + 0x98, 0x00, 0x99, 0xec, 0xf7, 0x2b, 0xfd, 0xc8, + 0xe7, 0x02, 0x98, 0xff, 0xf7, 0x1c, 0xf9, 0xc4, + 0xe7, 0x0a, 0x48, 0x21, 0xf0, 0xa4, 0xff, 0x09, + 0x49, 0x00, 0x20, 0x08, 0x60, 0x09, 0x48, 0x00, + 0x68, 0x00, 0x28, 0x04, 0xd0, 0x40, 0x68, 0x07, + 0x49, 0x08, 0x60, 0x21, 0xf0, 0xbc, 0xff, 0x21, + 0xf0, 0x92, 0xff, 0x03, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, 0x94, + 0x65, 0x03, 0x20, 0x90, 0x65, 0x03, 0x20, 0xa4, + 0x65, 0x03, 0x20, 0x90, 0xb5, 0x04, 0x1c, 0xc0, + 0x07, 0xc0, 0x0f, 0xa2, 0x07, 0x92, 0x0f, 0x01, + 0x27, 0x07, 0x29, 0x58, 0xd2, 0x02, 0xa3, 0x5b, + 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x04, + 0x12, 0x36, 0x1e, 0x2a, 0x36, 0x54, 0x00, 0x00, + 0x2a, 0x2f, 0xd0, 0x08, 0x1c, 0x0f, 0xf0, 0xb9, + 0xf9, 0x21, 0x1c, 0x02, 0x1c, 0x26, 0xa0, 0x01, + 0xf0, 0xb6, 0xfa, 0x38, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x28, 0x21, 0xd0, 0x08, + 0x1c, 0x0f, 0xf0, 0xab, 0xf9, 0x21, 0x1c, 0x02, + 0x1c, 0x1f, 0xa0, 0x01, 0xf0, 0xa8, 0xfa, 0x38, + 0x1c, 0xf0, 0xe7, 0x00, 0x2a, 0x15, 0xd0, 0x08, + 0x1c, 0x0f, 0xf0, 0x9f, 0xf9, 0x21, 0x1c, 0x02, + 0x1c, 0x19, 0xa0, 0x01, 0xf0, 0x9c, 0xfa, 0x38, + 0x1c, 0xe4, 0xe7, 0x00, 0x28, 0x09, 0xd0, 0x08, + 0x1c, 0x0f, 0xf0, 0x93, 0xf9, 0x21, 0x1c, 0x02, + 0x1c, 0x13, 0xa0, 0x01, 0xf0, 0x90, 0xfa, 0x38, + 0x1c, 0xd8, 0xe7, 0x01, 0x23, 0x5b, 0x07, 0x9c, + 0x42, 0x0b, 0xd2, 0x08, 0x1c, 0x0f, 0xf0, 0x85, + 0xf9, 0x21, 0x1c, 0x02, 0x1c, 0x01, 0x23, 0x5b, + 0x07, 0x14, 0xa0, 0x01, 0xf0, 0xed, 0x09, 0x00, + 0x3d, 0x01, 0x80, 0xfa, 0x02, 0x20, 0xc8, 0xe7, + 0x1c, 0x4b, 0x9c, 0x42, 0x0c, 0xd3, 0x08, 0x1c, + 0x0f, 0xf0, 0x76, 0xf9, 0x21, 0x1c, 0x02, 0x1c, + 0x19, 0xa0, 0x18, 0x4b, 0x01, 0xf0, 0x72, 0xfa, + 0x03, 0x20, 0xba, 0xe7, 0x04, 0x20, 0xb8, 0xe7, + 0x00, 0x20, 0xb6, 0xe7, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x28, 0x25, 0x23, 0x70, 0x2c, 0x20, 0x25, 0x73, + 0x29, 0x3a, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x0a, 0x00, 0x00, 0x00, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x28, 0x25, 0x23, 0x70, + 0x2c, 0x20, 0x25, 0x73, 0x29, 0x3a, 0x20, 0x74, + 0x6f, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x28, + 0x6d, 0x69, 0x6e, 0x3d, 0x25, 0x23, 0x78, 0x29, + 0x20, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x28, 0x25, 0x23, 0x70, + 0x2c, 0x20, 0x25, 0x73, 0x29, 0x3a, 0x20, 0x74, + 0x6f, 0x6f, 0x20, 0x68, 0x69, 0x67, 0x68, 0x20, + 0x28, 0x6d, 0x61, 0x78, 0x3d, 0x25, 0x23, 0x78, + 0x29, 0x0a, 0x00, 0x00, 0x01, 0x49, 0x00, 0x20, + 0x08, 0x60, 0x70, 0x47, 0xd0, 0x67, 0x03, 0x20, + 0xf7, 0xb5, 0xbc, 0xb0, 0x3e, 0x9a, 0x0c, 0x1c, + 0x07, 0x1c, 0x04, 0x2a, 0x03, 0xd1, 0x3f, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, + 0x13, 0x90, 0x00, 0x23, 0xf8, 0x56, 0x00, 0x25, + 0x00, 0x28, 0x6e, 0xd0, 0x0a, 0xaa, 0x01, 0x32, + 0x3b, 0x92, 0x09, 0xe0, 0x3d, 0x2d, 0x07, 0xd3, + 0x00, 0x21, 0x1b, 0xa8, 0x41, 0x55, 0x3e, 0x9a, + 0x29, 0x1c, 0x01, 0xf0, 0xb5, 0xf9, 0x00, 0x25, + 0x00, 0x23, 0xf8, 0x56, 0x08, 0x28, 0x0b, 0xd0, + 0xed, 0x09, 0x00, 0x3e, 0x01, 0x09, 0x28, 0x0d, + 0xd0, 0x25, 0x28, 0x61, 0xd1, 0x00, 0x20, 0x00, + 0x26, 0x01, 0x37, 0x17, 0x90, 0x15, 0x90, 0x14, + 0x90, 0x16, 0x90, 0x39, 0xe0, 0x00, 0x2d, 0x6d, + 0xd0, 0x01, 0x3d, 0x7e, 0xe3, 0xa8, 0x07, 0x69, + 0xd0, 0x20, 0x22, 0x28, 0x1c, 0x1b, 0xa9, 0x0a, + 0x54, 0x01, 0x35, 0xa8, 0x07, 0xf9, 0xd1, 0x74, + 0xe3, 0x2d, 0x28, 0x02, 0xd1, 0x01, 0x20, 0x15, + 0x90, 0x3f, 0x18, 0x00, 0x23, 0xf8, 0x56, 0x20, + 0x28, 0x05, 0xd1, 0x14, 0x98, 0x00, 0x28, 0x01, + 0xd1, 0x20, 0x20, 0x14, 0x90, 0x01, 0x37, 0x00, + 0x23, 0xf8, 0x56, 0x2b, 0x28, 0x01, 0xd1, 0x14, + 0x90, 0x01, 0x37, 0x00, 0x23, 0xf8, 0x56, 0x30, + 0x28, 0x05, 0xd1, 0x15, 0x98, 0x01, 0x37, 0x00, + 0x28, 0x01, 0xd1, 0x01, 0x20, 0x16, 0x90, 0x00, + 0x23, 0xf8, 0x56, 0x23, 0x28, 0x02, 0xd1, 0x30, + 0x20, 0x14, 0x90, 0x01, 0x37, 0x00, 0x23, 0xf8, + 0x56, 0x3a, 0x28, 0x01, 0xd1, 0x14, 0x90, 0x01, + 0x37, 0x00, 0x23, 0xf8, 0x56, 0x2d, 0x28, 0xcf, + 0xd0, 0x2b, 0x28, 0xcd, 0xd0, 0x20, 0x28, 0xcb, + 0xd0, 0x30, 0x28, 0xc9, 0xd0, 0x23, 0x28, 0xc7, + 0xd0, 0x3a, 0x28, 0xc5, 0xd0, 0xf9, 0x56, 0x2a, + 0x29, 0x06, 0xd1, 0x04, 0x34, 0xe0, 0x1f, 0x39, + 0x38, 0xc6, 0x6b, 0x01, 0x37, 0x0f, 0xe0, 0x6e, + 0xe3, 0x30, 0x38, 0x09, 0x28, 0x0b, 0xd8, 0x38, + 0x1c, 0x11, 0xf0, 0xde, 0xfd, 0x06, 0x1c, 0x01, + 0xe0, 0x7e, 0xe3, 0x01, 0x37, 0x00, 0x23, 0xf8, + 0x56, 0x30, 0x38, 0x09, 0x28, 0xf9, 0xd9, 0x00, + 0x23, 0xf8, 0x56, 0x2e, 0x28, 0x16, 0xd1, 0x01, + 0x37, 0xf8, 0x56, 0x2a, 0x28, 0x07, 0xd1, 0x04, + 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, 0x6b, 0x01, + 0x37, 0x17, 0x90, 0x0b, 0xe0, 0x69, 0xe3, 0x38, + 0x1c, 0x11, 0xf0, 0xed, 0x09, 0x00, 0x3f, 0x01, + 0xc2, 0xfd, 0x17, 0x90, 0x00, 0xe0, 0x01, 0x37, + 0x00, 0x23, 0xf8, 0x56, 0x30, 0x38, 0x09, 0x28, + 0xf9, 0xd9, 0x17, 0x98, 0xb0, 0x42, 0x00, 0xd9, + 0x17, 0x9e, 0x00, 0x23, 0xf8, 0x56, 0x4e, 0x28, + 0x1a, 0xd0, 0x15, 0xdc, 0x46, 0x28, 0x17, 0xd0, + 0x4c, 0x28, 0x02, 0xd1, 0x01, 0x20, 0x13, 0x90, + 0x3f, 0x18, 0x00, 0x23, 0xf8, 0x56, 0x69, 0x28, + 0x18, 0xd0, 0x34, 0xdc, 0x58, 0x28, 0x54, 0xd0, + 0x0e, 0xdc, 0x25, 0x28, 0x3d, 0xd0, 0x42, 0x28, + 0x64, 0xd0, 0x50, 0x28, 0x63, 0xd1, 0x05, 0xe1, + 0x68, 0x28, 0x01, 0xd0, 0x6c, 0x28, 0xec, 0xd1, + 0x00, 0x20, 0x13, 0x90, 0x01, 0x37, 0xe8, 0xe7, + 0x62, 0x28, 0x59, 0xd0, 0x63, 0x28, 0x38, 0xd0, + 0x64, 0x28, 0x54, 0xd1, 0x13, 0x98, 0x01, 0x28, + 0x53, 0xd1, 0x08, 0x34, 0xe1, 0x1f, 0x01, 0x39, + 0x08, 0x68, 0xf4, 0xa3, 0x11, 0x90, 0x49, 0x68, + 0x12, 0x91, 0x1a, 0x68, 0x5b, 0x68, 0xec, 0xf7, + 0x7c, 0xfb, 0x00, 0x28, 0x6b, 0xd0, 0x2d, 0x21, + 0x1b, 0xa8, 0x41, 0x55, 0x11, 0x98, 0x12, 0x99, + 0x00, 0x22, 0xec, 0xf7, 0x84, 0xfb, 0x11, 0x90, + 0x12, 0x91, 0x01, 0x35, 0x7b, 0xe0, 0xc1, 0x1f, + 0x67, 0x39, 0x0b, 0x29, 0x5c, 0xd2, 0x01, 0xa3, + 0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x0a, 0xd3, + 0xd2, 0xd1, 0xd1, 0xd0, 0xcf, 0x1a, 0xd1, 0xd1, + 0xce, 0x00, 0x25, 0x21, 0x1b, 0xa8, 0x41, 0x55, + 0x01, 0x35, 0x74, 0xe2, 0x04, 0x34, 0xe0, 0x1f, + 0x39, 0x38, 0xc0, 0x6b, 0x01, 0x37, 0x05, 0x60, + 0x6d, 0xe2, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, + 0xc0, 0x6b, 0x1b, 0xa9, 0x48, 0x55, 0x01, 0x35, + 0x65, 0xe2, 0x9a, 0xe2, 0x14, 0x98, 0x00, 0x28, + 0x03, 0xd0, 0x14, 0x98, 0x1b, 0xa9, 0x48, 0x55, + 0x01, 0x35, 0x13, 0x98, 0x01, 0x28, 0xed, 0x09, + 0x00, 0x40, 0x01, 0x0d, 0xd1, 0x08, 0x34, 0xe1, + 0x1f, 0x01, 0x39, 0x08, 0x68, 0x49, 0x68, 0x0a, + 0x23, 0x0b, 0xaa, 0x11, 0xf0, 0x74, 0xfd, 0x0b, + 0xe0, 0x29, 0xe1, 0x15, 0xe3, 0x8f, 0xe0, 0x47, + 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, + 0x6b, 0x0a, 0x22, 0x0b, 0xa9, 0x11, 0xf0, 0x35, + 0xfe, 0x0b, 0xa8, 0x11, 0xf0, 0x8e, 0xfe, 0x19, + 0x90, 0x15, 0x98, 0x01, 0x28, 0x07, 0xd1, 0x1b, + 0xa8, 0x40, 0x19, 0x19, 0x9a, 0x0b, 0xa9, 0xec, + 0xf7, 0x38, 0xfb, 0x19, 0x98, 0x2d, 0x18, 0x19, + 0x98, 0x86, 0x42, 0x13, 0xd9, 0x20, 0x22, 0x30, + 0x21, 0x16, 0x98, 0x00, 0x28, 0x07, 0xd0, 0x15, + 0x98, 0x00, 0x28, 0x04, 0xd1, 0x1b, 0xa8, 0x41, + 0x55, 0x03, 0xe0, 0x13, 0xe0, 0xec, 0xe2, 0x1b, + 0xa8, 0x42, 0x55, 0x19, 0x98, 0x01, 0x35, 0x01, + 0x3e, 0x86, 0x42, 0xed, 0xd8, 0x15, 0x98, 0x00, + 0x28, 0x07, 0xd1, 0x1b, 0xa8, 0x40, 0x19, 0x19, + 0x9a, 0x0b, 0xa9, 0xec, 0xf7, 0x16, 0xfb, 0x19, + 0x98, 0x2d, 0x18, 0x12, 0xe2, 0x14, 0x98, 0x00, + 0x28, 0x03, 0xd0, 0x14, 0x98, 0x1b, 0xa9, 0x48, + 0x55, 0x01, 0x35, 0x0a, 0x23, 0x11, 0x98, 0x12, + 0x99, 0x0b, 0xaa, 0x11, 0xf0, 0x28, 0xfd, 0x16, + 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, + 0x6b, 0x00, 0x28, 0x05, 0xda, 0x2d, 0x22, 0x1b, + 0xa9, 0x4a, 0x55, 0x40, 0x42, 0x01, 0x35, 0x06, + 0xe0, 0x14, 0x99, 0x00, 0x29, 0x03, 0xd0, 0x14, + 0x99, 0x1b, 0xaa, 0x51, 0x55, 0x01, 0x35, 0x0a, + 0x22, 0x0b, 0xa9, 0x11, 0xf0, 0xde, 0xfd, 0x0b, + 0xa8, 0x11, 0xf0, 0x37, 0xfe, 0x19, 0x90, 0x15, + 0x98, 0x01, 0x28, 0x07, 0xd1, 0x1b, 0xa8, 0x40, + 0x19, 0x19, 0x9a, 0x0b, 0xa9, 0xec, 0xf7, 0xe1, + 0xfa, 0x19, 0x98, 0x2d, 0x18, 0x19, 0x98, 0x86, + 0x42, 0xed, 0x09, 0x00, 0x41, 0x01, 0x11, 0xd9, + 0x20, 0x22, 0x30, 0x21, 0x16, 0x98, 0x00, 0x28, + 0x05, 0xd0, 0x15, 0x98, 0x00, 0x28, 0x02, 0xd1, + 0x1b, 0xa8, 0x41, 0x55, 0x01, 0xe0, 0x1b, 0xa8, + 0x42, 0x55, 0x19, 0x98, 0x01, 0x35, 0x01, 0x3e, + 0x86, 0x42, 0xef, 0xd8, 0x15, 0x98, 0x00, 0x28, + 0x07, 0xd1, 0x1b, 0xa8, 0x40, 0x19, 0x19, 0x9a, + 0x0b, 0xa9, 0xec, 0xf7, 0xc1, 0xfa, 0x19, 0x98, + 0x2d, 0x18, 0xbd, 0xe1, 0x13, 0x98, 0x01, 0x28, + 0x0f, 0xd1, 0x08, 0x34, 0x6a, 0x46, 0xe1, 0x1f, + 0x01, 0x39, 0x08, 0x68, 0x49, 0x68, 0x02, 0x23, + 0x11, 0xf0, 0xd4, 0xfc, 0x0d, 0xe0, 0xe5, 0xe1, + 0x59, 0xe2, 0x0b, 0xe1, 0x73, 0xe2, 0x54, 0xe1, + 0x37, 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, + 0x69, 0x46, 0x02, 0x22, 0xc0, 0x6b, 0x11, 0xf0, + 0x93, 0xfd, 0x68, 0x46, 0x11, 0xf0, 0xec, 0xfd, + 0x19, 0x90, 0x15, 0x98, 0x01, 0x28, 0x07, 0xd1, + 0x1b, 0xa8, 0x40, 0x19, 0x69, 0x46, 0x19, 0x9a, + 0xec, 0xf7, 0x96, 0xfa, 0x19, 0x98, 0x2d, 0x18, + 0x19, 0x98, 0x86, 0x42, 0x11, 0xd9, 0x20, 0x22, + 0x30, 0x21, 0x16, 0x98, 0x00, 0x28, 0x05, 0xd0, + 0x15, 0x98, 0x00, 0x28, 0x02, 0xd1, 0x1b, 0xa8, + 0x41, 0x55, 0x01, 0xe0, 0x1b, 0xa8, 0x42, 0x55, + 0x19, 0x98, 0x01, 0x35, 0x01, 0x3e, 0x86, 0x42, + 0xef, 0xd8, 0x15, 0x98, 0x00, 0x28, 0x07, 0xd1, + 0x1b, 0xa8, 0x40, 0x19, 0x69, 0x46, 0x19, 0x9a, + 0xec, 0xf7, 0x76, 0xfa, 0x19, 0x98, 0x2d, 0x18, + 0x72, 0xe1, 0x14, 0x98, 0x30, 0x28, 0x04, 0xd1, + 0x14, 0x98, 0x0a, 0xab, 0x18, 0x70, 0x3b, 0x9a, + 0x00, 0xe0, 0x0a, 0xaa, 0x13, 0x98, 0x01, 0x28, + 0x08, 0xd1, 0x08, 0x34, 0xe1, 0x1f, 0x01, 0x39, + 0x08, 0x68, 0x49, 0x68, 0x08, 0x23, 0x11, 0xf0, + 0x81, 0xfc, 0x07, 0xe0, 0xed, 0x09, 0x00, 0x42, + 0x01, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0x11, + 0x1c, 0x08, 0x22, 0xc0, 0x6b, 0x11, 0xf0, 0x46, + 0xfd, 0x0a, 0xa8, 0x11, 0xf0, 0x9f, 0xfd, 0x19, + 0x90, 0x15, 0x98, 0x01, 0x28, 0x07, 0xd1, 0x1b, + 0xa8, 0x40, 0x19, 0x19, 0x9a, 0x0a, 0xa9, 0xec, + 0xf7, 0x49, 0xfa, 0x19, 0x98, 0x2d, 0x18, 0x19, + 0x98, 0x86, 0x42, 0x11, 0xd9, 0x20, 0x22, 0x30, + 0x21, 0x16, 0x98, 0x00, 0x28, 0x05, 0xd0, 0x15, + 0x98, 0x00, 0x28, 0x02, 0xd1, 0x1b, 0xa8, 0x41, + 0x55, 0x01, 0xe0, 0x1b, 0xa8, 0x42, 0x55, 0x19, + 0x98, 0x01, 0x35, 0x01, 0x3e, 0x86, 0x42, 0xef, + 0xd8, 0x15, 0x98, 0x00, 0x28, 0x07, 0xd1, 0x1b, + 0xa8, 0x40, 0x19, 0x19, 0x9a, 0x0a, 0xa9, 0xec, + 0xf7, 0x29, 0xfa, 0x19, 0x98, 0x2d, 0x18, 0x25, + 0xe1, 0x3a, 0x48, 0x0b, 0xa9, 0x0c, 0xc8, 0x0c, + 0xc1, 0x0d, 0xc8, 0x0d, 0xc1, 0x04, 0x34, 0xe0, + 0x1f, 0x39, 0x38, 0xc1, 0x6b, 0x00, 0x2e, 0x10, + 0x91, 0x00, 0xd1, 0x01, 0x26, 0x15, 0x98, 0x01, + 0x28, 0x03, 0xd1, 0x10, 0x99, 0x88, 0x19, 0x41, + 0x1e, 0x10, 0x91, 0x70, 0x1e, 0x18, 0x90, 0x00, + 0x2e, 0x57, 0xd0, 0x3a, 0x26, 0x75, 0x2d, 0x07, + 0xd3, 0x00, 0x21, 0x1b, 0xa8, 0x41, 0x55, 0x3e, + 0x9a, 0x29, 0x1c, 0x00, 0xf0, 0x59, 0xff, 0x00, + 0x25, 0x14, 0x98, 0x30, 0x28, 0x06, 0xd1, 0x30, + 0x22, 0x1b, 0xa9, 0x4a, 0x55, 0x78, 0x22, 0x68, + 0x1c, 0x0a, 0x54, 0x45, 0x1c, 0x10, 0x99, 0x00, + 0x29, 0x19, 0xd1, 0x28, 0x20, 0x1b, 0xaa, 0x50, + 0x55, 0x69, 0x1c, 0x6e, 0x23, 0x53, 0x54, 0x75, + 0x23, 0x48, 0x1c, 0x13, 0x54, 0x6c, 0x23, 0x41, + 0x1c, 0x6a, 0x46, 0xd2, 0x18, 0x53, 0x54, 0x48, + 0x1c, 0x01, 0x1c, 0x6a, 0x46, 0xd2, 0x18, 0x53, + 0x54, 0x29, 0x22, 0x01, 0x30, 0x69, 0x46, 0xed, + 0x09, 0x00, 0x43, 0x01, 0xc9, 0x18, 0x0a, 0x54, + 0x45, 0x1c, 0x37, 0xe0, 0x10, 0x99, 0x1b, 0xaa, + 0x08, 0x78, 0x0b, 0xa9, 0x00, 0x09, 0x09, 0x5c, + 0x51, 0x55, 0x10, 0x99, 0x09, 0x78, 0x09, 0x07, + 0x09, 0x0f, 0x40, 0x3a, 0x51, 0x5c, 0x68, 0x1c, + 0x1b, 0xaa, 0x11, 0x54, 0x45, 0x1c, 0x15, 0x98, + 0x01, 0x28, 0x03, 0xd1, 0x10, 0x99, 0x01, 0x39, + 0x10, 0x91, 0x02, 0xe0, 0x10, 0x99, 0x01, 0x31, + 0x10, 0x91, 0x18, 0x98, 0x00, 0x28, 0x14, 0xd0, + 0x14, 0x98, 0x3a, 0x28, 0x0c, 0xd1, 0x28, 0x1c, + 0x1b, 0xa9, 0x0e, 0x54, 0x01, 0x35, 0x06, 0xe0, + 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb4, 0x5c, 0x03, 0x20, 0x04, 0xe0, + 0x20, 0x22, 0x28, 0x1c, 0x1b, 0xa9, 0x0a, 0x54, + 0x01, 0x35, 0x18, 0x98, 0x41, 0x1e, 0x18, 0x91, + 0x00, 0x28, 0x96, 0xd1, 0xa1, 0xe0, 0x04, 0x34, + 0xe0, 0x1f, 0x39, 0x38, 0xc1, 0x6b, 0x1a, 0x91, + 0x00, 0x29, 0x01, 0xd1, 0xbf, 0xa1, 0x1a, 0x91, + 0x17, 0x98, 0x00, 0x28, 0x03, 0xd1, 0x7f, 0x20, + 0x40, 0x1b, 0x02, 0x38, 0x17, 0x90, 0x00, 0x20, + 0x19, 0x90, 0x02, 0xe0, 0x19, 0x98, 0x01, 0x30, + 0x19, 0x90, 0x19, 0x98, 0x1a, 0x99, 0x08, 0x56, + 0x00, 0x28, 0x03, 0xd0, 0x19, 0x98, 0x17, 0x99, + 0x88, 0x42, 0xf3, 0xd3, 0x15, 0x98, 0x01, 0x28, + 0x07, 0xd1, 0x1b, 0xa8, 0x40, 0x19, 0x1a, 0x99, + 0x19, 0x9a, 0xec, 0xf7, 0x7a, 0xf9, 0x19, 0x98, + 0x2d, 0x18, 0x19, 0x98, 0x86, 0x42, 0x11, 0xd9, + 0x20, 0x22, 0x30, 0x21, 0x16, 0x98, 0x00, 0x28, + 0x05, 0xd0, 0x15, 0x98, 0x00, 0x28, 0x02, 0xd1, + 0x1b, 0xa8, 0x41, 0x55, 0x01, 0xe0, 0x1b, 0xa8, + 0x42, 0x55, 0x19, 0x98, 0x01, 0x35, 0x01, 0x3e, + 0x86, 0x42, 0xef, 0xd8, 0x15, 0x98, 0x00, 0x28, + 0x5f, 0xd1, 0xed, 0x09, 0x00, 0x44, 0x01, 0x1b, + 0xa8, 0x40, 0x19, 0x1a, 0x99, 0x19, 0x9a, 0xec, + 0xf7, 0x5a, 0xf9, 0x19, 0x98, 0x2d, 0x18, 0x20, + 0xe1, 0x13, 0x98, 0x01, 0x28, 0x1a, 0xd1, 0x08, + 0x34, 0xe1, 0x1f, 0x01, 0x39, 0x08, 0x68, 0x9b, + 0xa3, 0x0a, 0x90, 0x49, 0x68, 0x0b, 0x91, 0x1a, + 0x68, 0x5b, 0x68, 0xec, 0xf7, 0x70, 0xfa, 0x00, + 0x28, 0x05, 0xd0, 0x0c, 0xa8, 0x94, 0xa1, 0x07, + 0x22, 0xec, 0xf7, 0x41, 0xf9, 0x05, 0xe0, 0x10, + 0x23, 0x0a, 0x98, 0x0b, 0x99, 0x0c, 0xaa, 0x11, + 0xf0, 0x5c, 0xfb, 0x0f, 0xe0, 0x04, 0x34, 0xe0, + 0x1f, 0x39, 0x38, 0xc0, 0x6b, 0x00, 0x28, 0x05, + 0xd1, 0x0c, 0xa8, 0x8a, 0xa1, 0x07, 0x22, 0xec, + 0xf7, 0x2e, 0xf9, 0x03, 0xe0, 0x10, 0x22, 0x0c, + 0xa9, 0x11, 0xf0, 0x19, 0xfc, 0x0c, 0xa8, 0x11, + 0xf0, 0x72, 0xfc, 0x19, 0x90, 0x15, 0x98, 0x01, + 0x28, 0x02, 0xd0, 0x19, 0x98, 0x86, 0x42, 0x1f, + 0xd8, 0x14, 0x98, 0x30, 0x28, 0x07, 0xd1, 0x30, + 0x21, 0x1b, 0xaa, 0x51, 0x55, 0x78, 0x22, 0x68, + 0x1c, 0x1b, 0xa9, 0x0a, 0x54, 0x45, 0x1c, 0x1b, + 0xa8, 0x40, 0x19, 0x19, 0x9a, 0x0c, 0xa9, 0xec, + 0xf7, 0x0e, 0xf9, 0x19, 0x98, 0x2d, 0x18, 0x86, + 0x42, 0x3d, 0xd9, 0x20, 0x22, 0x28, 0x1c, 0x1b, + 0xa9, 0x0a, 0x54, 0x19, 0x98, 0x01, 0x35, 0x01, + 0x3e, 0x86, 0x42, 0xf7, 0xd8, 0x33, 0xe0, 0xc8, + 0xe0, 0x16, 0x98, 0x00, 0x28, 0x13, 0xd0, 0x14, + 0x98, 0x30, 0x28, 0x06, 0xd1, 0x30, 0x21, 0x1b, + 0xaa, 0x51, 0x55, 0x78, 0x21, 0x68, 0x1c, 0x11, + 0x54, 0x45, 0x1c, 0x30, 0x22, 0x28, 0x1c, 0x1b, + 0xa9, 0x0a, 0x54, 0x19, 0x98, 0x01, 0x35, 0x01, + 0x3e, 0x86, 0x42, 0xf7, 0xd8, 0x13, 0xe0, 0x20, + 0x22, 0x28, 0x1c, 0x1b, 0xa9, 0x0a, 0x54, 0x19, + 0x98, 0x01, 0x35, 0x01, 0x3e, 0xed, 0x09, 0x00, + 0x45, 0x01, 0x86, 0x42, 0xf7, 0xd8, 0x14, 0x98, + 0x30, 0x28, 0x07, 0xd1, 0x30, 0x21, 0x1b, 0xaa, + 0x51, 0x55, 0x78, 0x22, 0x68, 0x1c, 0x1b, 0xa9, + 0x0a, 0x54, 0x45, 0x1c, 0x1b, 0xa8, 0x40, 0x19, + 0x19, 0x9a, 0x0c, 0xa9, 0xec, 0xf7, 0xce, 0xf8, + 0x19, 0x98, 0x2d, 0x18, 0x94, 0xe0, 0x99, 0xe0, + 0x13, 0x98, 0x01, 0x28, 0x09, 0xd1, 0x08, 0x34, + 0xe1, 0x1f, 0x01, 0x39, 0x08, 0x68, 0x49, 0x68, + 0x10, 0x23, 0x0c, 0xaa, 0x11, 0xf0, 0xe0, 0xfa, + 0x07, 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, + 0xc0, 0x6b, 0x10, 0x22, 0x0c, 0xa9, 0x11, 0xf0, + 0xa5, 0xfb, 0x0c, 0xa8, 0x11, 0xf0, 0xfe, 0xfb, + 0x19, 0x90, 0x15, 0x98, 0x01, 0x28, 0x02, 0xd0, + 0x19, 0x98, 0x86, 0x42, 0x1e, 0xd8, 0x14, 0x98, + 0x30, 0x28, 0x06, 0xd1, 0x30, 0x21, 0x1b, 0xaa, + 0x51, 0x55, 0x78, 0x21, 0x68, 0x1c, 0x11, 0x54, + 0x45, 0x1c, 0x1b, 0xa8, 0x40, 0x19, 0x19, 0x9a, + 0x0c, 0xa9, 0xec, 0xf7, 0x9b, 0xf8, 0x19, 0x98, + 0x2d, 0x18, 0x86, 0x42, 0x40, 0xd9, 0x20, 0x22, + 0x28, 0x1c, 0x1b, 0xa9, 0x0a, 0x54, 0x19, 0x98, + 0x01, 0x35, 0x01, 0x3e, 0x86, 0x42, 0xf7, 0xd8, + 0x36, 0xe0, 0x64, 0xe0, 0x16, 0x98, 0x00, 0x28, + 0x16, 0xd0, 0x14, 0x98, 0x30, 0x28, 0x07, 0xd1, + 0x30, 0x21, 0x1b, 0xaa, 0x51, 0x55, 0x78, 0x22, + 0x68, 0x1c, 0x1b, 0xa9, 0x0a, 0x54, 0x45, 0x1c, + 0x30, 0x22, 0x28, 0x1c, 0x1b, 0xa9, 0x0a, 0x54, + 0x19, 0x98, 0x01, 0x35, 0x01, 0x3e, 0x86, 0x42, + 0xf7, 0xd8, 0x15, 0xe0, 0x3f, 0xe0, 0x41, 0xe0, + 0x20, 0x22, 0x28, 0x1c, 0x1b, 0xa9, 0x0a, 0x54, + 0x19, 0x98, 0x01, 0x35, 0x01, 0x3e, 0x86, 0x42, + 0xf7, 0xd8, 0x14, 0x98, 0x30, 0x28, 0x07, 0xd1, + 0x30, 0x21, 0x1b, 0xaa, 0x51, 0x55, 0x78, 0x22, + 0xed, 0x09, 0x00, 0x46, 0x01, 0x68, 0x1c, 0x1b, + 0xa9, 0x0a, 0x54, 0x45, 0x1c, 0x1b, 0xa8, 0x40, + 0x19, 0x19, 0x9a, 0x0c, 0xa9, 0xec, 0xf7, 0x58, + 0xf8, 0x19, 0x98, 0x2d, 0x18, 0x1e, 0xe0, 0x04, + 0x34, 0xe0, 0x1f, 0x39, 0x38, 0x54, 0x22, 0xd2, + 0x43, 0xc0, 0x6b, 0x1b, 0xab, 0x5a, 0x55, 0x69, + 0x1c, 0x58, 0x54, 0x03, 0x0a, 0x4a, 0x1c, 0x1b, + 0xad, 0xab, 0x54, 0x03, 0x0c, 0x51, 0x1c, 0x6b, + 0x54, 0x00, 0x0e, 0x4a, 0x1c, 0x1b, 0xab, 0x98, + 0x54, 0x45, 0x20, 0xc0, 0x43, 0x51, 0x1c, 0x1b, + 0xaa, 0x50, 0x54, 0x4d, 0x1c, 0x02, 0xe0, 0x1b, + 0xa9, 0x48, 0x55, 0x01, 0x35, 0x00, 0x20, 0x13, + 0x90, 0x02, 0xe0, 0x1b, 0xa9, 0x48, 0x55, 0x01, + 0x35, 0x00, 0x23, 0x01, 0x37, 0xf8, 0x56, 0x00, + 0x28, 0x01, 0xd0, 0xff, 0xf7, 0xc1, 0xfb, 0x00, + 0x2d, 0x01, 0xd1, 0xff, 0xf7, 0xae, 0xfb, 0x00, + 0x20, 0x1b, 0xa9, 0x48, 0x55, 0x3e, 0x9a, 0x29, + 0x1c, 0x1b, 0xa8, 0x00, 0xf0, 0x73, 0xfd, 0xf4, + 0xe7, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xb5, 0x9d, 0xb0, 0x07, 0x1c, 0x00, + 0x20, 0x13, 0x90, 0x00, 0x23, 0xd0, 0x56, 0x00, + 0x26, 0x15, 0x1c, 0x00, 0x28, 0x74, 0xd0, 0x1e, + 0x99, 0x0a, 0xaa, 0x01, 0x32, 0xc8, 0x1f, 0x3b, + 0x38, 0x1b, 0x92, 0xca, 0x1f, 0x03, 0x3a, 0x1a, + 0x92, 0x1c, 0x90, 0x1c, 0x98, 0xb0, 0x42, 0x05, + 0xd8, 0x00, 0x20, 0xb8, 0x55, 0x21, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23, 0xe8, + 0x56, 0x08, 0x28, 0x0c, 0xd0, 0x09, 0x28, 0x0e, + 0xd0, 0x25, 0x28, 0x5e, 0xd1, 0x00, 0x22, 0x00, + 0x20, 0x00, 0x24, 0x01, 0x35, 0x17, 0x90, 0x15, + 0x92, 0x14, 0x92, 0x16, 0x92, 0x3a, 0xe0, 0x00, + 0x2e, 0x73, 0xd0, 0xed, 0x09, 0x00, 0x47, 0x01, + 0x01, 0x3e, 0x72, 0xe3, 0xb0, 0x07, 0x6f, 0xd0, + 0x20, 0x21, 0x30, 0x1c, 0x39, 0x54, 0x01, 0x36, + 0xb0, 0x07, 0xfa, 0xd1, 0x69, 0xe3, 0x2d, 0x28, + 0x02, 0xd1, 0x01, 0x22, 0x15, 0x92, 0xad, 0x18, + 0x00, 0x23, 0xe8, 0x56, 0x20, 0x28, 0x05, 0xd1, + 0x14, 0x9a, 0x00, 0x2a, 0x01, 0xd1, 0x20, 0x22, + 0x14, 0x92, 0x01, 0x35, 0x00, 0x23, 0xe8, 0x56, + 0x2b, 0x28, 0x02, 0xd1, 0x2b, 0x22, 0x14, 0x92, + 0x01, 0x35, 0x00, 0x23, 0xe8, 0x56, 0x30, 0x28, + 0x05, 0xd1, 0x15, 0x9a, 0x01, 0x35, 0x00, 0x2a, + 0x01, 0xd1, 0x01, 0x22, 0x16, 0x92, 0x00, 0x23, + 0xe8, 0x56, 0x23, 0x28, 0x02, 0xd1, 0x30, 0x22, + 0x14, 0x92, 0x01, 0x35, 0x00, 0x23, 0xe8, 0x56, + 0x3a, 0x28, 0x02, 0xd1, 0x3a, 0x22, 0x14, 0x92, + 0x01, 0x35, 0x00, 0x23, 0xe8, 0x56, 0x2d, 0x28, + 0xcd, 0xd0, 0x2b, 0x28, 0xcb, 0xd0, 0x20, 0x28, + 0xc9, 0xd0, 0x30, 0x28, 0xc7, 0xd0, 0x23, 0x28, + 0xc5, 0xd0, 0x3a, 0x28, 0xc3, 0xd0, 0xe9, 0x56, + 0x2a, 0x29, 0x0a, 0xd1, 0x20, 0x9b, 0x04, 0x33, + 0x20, 0x93, 0x01, 0x35, 0x00, 0xe0, 0x69, 0xe3, + 0xd8, 0x1f, 0x39, 0x38, 0xc4, 0x6b, 0x0e, 0xe0, + 0x7e, 0xe3, 0x30, 0x38, 0x09, 0x28, 0x0a, 0xd8, + 0x28, 0x1c, 0x11, 0xf0, 0x70, 0xf9, 0x04, 0x1c, + 0x00, 0xe0, 0x01, 0x35, 0x00, 0x23, 0xe8, 0x56, + 0x30, 0x38, 0x09, 0x28, 0xf9, 0xd9, 0x00, 0x23, + 0xe8, 0x56, 0x2e, 0x28, 0x18, 0xd1, 0x01, 0x35, + 0xe8, 0x56, 0x2a, 0x28, 0x09, 0xd1, 0x20, 0x9b, + 0x04, 0x33, 0xd8, 0x1f, 0x39, 0x38, 0x20, 0x93, + 0xc0, 0x6b, 0x01, 0x35, 0x17, 0x90, 0x0b, 0xe0, + 0x79, 0xe3, 0x28, 0x1c, 0x11, 0xf0, 0x53, 0xf9, + 0x17, 0x90, 0x00, 0xe0, 0x01, 0x35, 0x00, 0x23, + 0xe8, 0x56, 0x30, 0x38, 0x09, 0x28, 0xed, 0x09, + 0x00, 0x48, 0x01, 0xf9, 0xd9, 0x17, 0x98, 0xa0, + 0x42, 0x00, 0xd9, 0x17, 0x9c, 0x00, 0x23, 0xe8, + 0x56, 0x4e, 0x28, 0x1a, 0xd0, 0x15, 0xdc, 0x46, + 0x28, 0x17, 0xd0, 0x4c, 0x28, 0x02, 0xd1, 0x01, + 0x20, 0x13, 0x90, 0x2d, 0x18, 0x00, 0x23, 0xe8, + 0x56, 0x69, 0x28, 0x18, 0xd0, 0x35, 0xdc, 0x58, + 0x28, 0x57, 0xd0, 0x0e, 0xdc, 0x25, 0x28, 0x3e, + 0xd0, 0x42, 0x28, 0x53, 0xd0, 0x50, 0x28, 0x52, + 0xd1, 0x04, 0xe1, 0x68, 0x28, 0x01, 0xd0, 0x6c, + 0x28, 0xec, 0xd1, 0x00, 0x20, 0x13, 0x90, 0x01, + 0x35, 0xe8, 0xe7, 0x62, 0x28, 0x5d, 0xd0, 0x63, + 0x28, 0x3a, 0xd0, 0x64, 0x28, 0x43, 0xd1, 0x13, + 0x98, 0x01, 0x28, 0x57, 0xd1, 0x20, 0x9b, 0x08, + 0x33, 0xd9, 0x1f, 0x01, 0x39, 0x20, 0x93, 0x08, + 0x68, 0xf6, 0xa3, 0x11, 0x90, 0x49, 0x68, 0x12, + 0x91, 0x1a, 0x68, 0x5b, 0x68, 0xeb, 0xf7, 0x0b, + 0xff, 0x00, 0x28, 0x6d, 0xd0, 0x2d, 0x20, 0xb8, + 0x55, 0x11, 0x98, 0x12, 0x99, 0x00, 0x22, 0xeb, + 0xf7, 0x14, 0xff, 0x11, 0x90, 0x12, 0x91, 0x01, + 0x36, 0x7b, 0xe0, 0xc1, 0x1f, 0x67, 0x39, 0x0b, + 0x29, 0x5f, 0xd2, 0x01, 0xa3, 0x5b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x09, 0xd1, 0xd0, 0xcf, 0xcf, + 0xce, 0xcd, 0x1e, 0xcf, 0xcf, 0xcc, 0x00, 0x25, + 0x20, 0xb8, 0x55, 0x01, 0x36, 0x59, 0xe2, 0x20, + 0x9b, 0x04, 0x33, 0xd8, 0x1f, 0x39, 0x38, 0x20, + 0x93, 0xc0, 0x6b, 0x01, 0x35, 0x06, 0x60, 0x50, + 0xe2, 0x20, 0x9b, 0x04, 0x33, 0xd8, 0x1f, 0x39, + 0x38, 0x20, 0x93, 0xc0, 0x6b, 0xb8, 0x55, 0x01, + 0x36, 0x47, 0xe2, 0x75, 0xe2, 0x37, 0xe1, 0xfd, + 0xe2, 0x14, 0x9a, 0x00, 0x2a, 0x02, 0xd0, 0x14, + 0x9a, 0xba, 0x55, 0x01, 0x36, 0x13, 0x98, 0x01, + 0x28, 0x0d, 0xd1, 0x20, 0x9b, 0x0b, 0xaa, 0x08, + 0x33, 0xed, 0x09, 0x00, 0x49, 0x01, 0xd9, 0x1f, + 0x01, 0x39, 0x20, 0x93, 0x08, 0x68, 0x49, 0x68, + 0x0a, 0x23, 0x11, 0xf0, 0xff, 0xf8, 0x0b, 0xe0, + 0x88, 0xe0, 0x44, 0xe0, 0x20, 0x9b, 0x0b, 0xa9, + 0x04, 0x33, 0xd8, 0x1f, 0x39, 0x38, 0x20, 0x93, + 0xc0, 0x6b, 0x0a, 0x22, 0x11, 0xf0, 0xc0, 0xf9, + 0x0b, 0xa8, 0x11, 0xf0, 0x19, 0xfa, 0x15, 0x9a, + 0x18, 0x90, 0x01, 0x2a, 0x06, 0xd1, 0xb8, 0x19, + 0x18, 0x9a, 0x0b, 0xa9, 0xeb, 0xf7, 0xc4, 0xfe, + 0x18, 0x98, 0x36, 0x18, 0x18, 0x98, 0x84, 0x42, + 0x11, 0xd9, 0x20, 0x21, 0x30, 0x20, 0x16, 0x9a, + 0x00, 0x2a, 0x06, 0xd0, 0x15, 0x9a, 0x00, 0x2a, + 0x03, 0xd1, 0xb8, 0x55, 0x02, 0xe0, 0x11, 0xe0, + 0xbf, 0xe2, 0xb9, 0x55, 0x18, 0x9a, 0x01, 0x3c, + 0x01, 0x36, 0x94, 0x42, 0xef, 0xd8, 0x15, 0x9a, + 0x00, 0x2a, 0x06, 0xd1, 0xb8, 0x19, 0x18, 0x9a, + 0x0b, 0xa9, 0xeb, 0xf7, 0xa5, 0xfe, 0x18, 0x98, + 0x36, 0x18, 0xf5, 0xe1, 0x14, 0x9a, 0x00, 0x2a, + 0x02, 0xd0, 0x14, 0x9a, 0xba, 0x55, 0x01, 0x36, + 0x0a, 0x23, 0x11, 0x98, 0x12, 0x99, 0x0b, 0xaa, + 0x11, 0xf0, 0xb8, 0xf8, 0x16, 0xe0, 0x20, 0x9b, + 0x04, 0x33, 0xd8, 0x1f, 0x39, 0x38, 0x20, 0x93, + 0xc0, 0x6b, 0x00, 0x28, 0x04, 0xda, 0x2d, 0x21, + 0xb9, 0x55, 0x40, 0x42, 0x01, 0x36, 0x05, 0xe0, + 0x14, 0x9a, 0x00, 0x2a, 0x02, 0xd0, 0x14, 0x9a, + 0xba, 0x55, 0x01, 0x36, 0x0a, 0x22, 0x0b, 0xa9, + 0x11, 0xf0, 0x6e, 0xf9, 0x0b, 0xa8, 0x11, 0xf0, + 0xc7, 0xf9, 0x15, 0x9a, 0x18, 0x90, 0x01, 0x2a, + 0x06, 0xd1, 0xb8, 0x19, 0x18, 0x9a, 0x0b, 0xa9, + 0xeb, 0xf7, 0x72, 0xfe, 0x18, 0x98, 0x36, 0x18, + 0x18, 0x98, 0x84, 0x42, 0x0f, 0xd9, 0x20, 0x21, + 0x30, 0x20, 0x16, 0x9a, 0x00, 0x2a, 0x04, 0xd0, + 0x15, 0x9a, 0x00, 0x2a, 0xed, 0x09, 0x00, 0x4a, + 0x01, 0x01, 0xd1, 0xb8, 0x55, 0x00, 0xe0, 0xb9, + 0x55, 0x18, 0x9a, 0x01, 0x3c, 0x01, 0x36, 0x94, + 0x42, 0xf1, 0xd8, 0x15, 0x9a, 0x00, 0x2a, 0x06, + 0xd1, 0xb8, 0x19, 0x18, 0x9a, 0x0b, 0xa9, 0xeb, + 0xf7, 0x55, 0xfe, 0x18, 0x98, 0x36, 0x18, 0xa5, + 0xe1, 0x13, 0x98, 0x01, 0x28, 0x11, 0xd1, 0x20, + 0x9b, 0x08, 0x33, 0x6a, 0x46, 0xd9, 0x1f, 0x01, + 0x39, 0x20, 0x93, 0x08, 0x68, 0x49, 0x68, 0x02, + 0x23, 0x11, 0xf0, 0x66, 0xf8, 0x0f, 0xe0, 0xc4, + 0xe1, 0x32, 0xe2, 0xe5, 0xe0, 0x4b, 0xe2, 0x38, + 0xe1, 0x35, 0xe0, 0x20, 0x9b, 0x04, 0x33, 0xd8, + 0x1f, 0x39, 0x38, 0x69, 0x46, 0x20, 0x93, 0xc0, + 0x6b, 0x02, 0x22, 0x11, 0xf0, 0x23, 0xf9, 0x68, + 0x46, 0x11, 0xf0, 0x7c, 0xf9, 0x15, 0x9a, 0x18, + 0x90, 0x01, 0x2a, 0x06, 0xd1, 0xb8, 0x19, 0x69, + 0x46, 0x18, 0x9a, 0xeb, 0xf7, 0x27, 0xfe, 0x18, + 0x98, 0x36, 0x18, 0x18, 0x98, 0x84, 0x42, 0x0f, + 0xd9, 0x20, 0x21, 0x30, 0x20, 0x16, 0x9a, 0x00, + 0x2a, 0x04, 0xd0, 0x15, 0x9a, 0x00, 0x2a, 0x01, + 0xd1, 0xb8, 0x55, 0x00, 0xe0, 0xb9, 0x55, 0x18, + 0x9a, 0x01, 0x3c, 0x01, 0x36, 0x94, 0x42, 0xf1, + 0xd8, 0x15, 0x9a, 0x00, 0x2a, 0x06, 0xd1, 0xb8, + 0x19, 0x69, 0x46, 0x18, 0x9a, 0xeb, 0xf7, 0x0a, + 0xfe, 0x18, 0x98, 0x36, 0x18, 0x5a, 0xe1, 0x14, + 0x9a, 0x30, 0x2a, 0x04, 0xd1, 0x14, 0x9a, 0x0a, + 0xab, 0x1a, 0x70, 0x1b, 0x9a, 0x00, 0xe0, 0x0a, + 0xaa, 0x13, 0x98, 0x01, 0x28, 0x0a, 0xd1, 0x20, + 0x9b, 0x08, 0x33, 0xd9, 0x1f, 0x01, 0x39, 0x20, + 0x93, 0x08, 0x68, 0x49, 0x68, 0x08, 0x23, 0x11, + 0xf0, 0x13, 0xf8, 0x09, 0xe0, 0x20, 0x9b, 0x04, + 0x33, 0xd8, 0x1f, 0x39, 0x38, 0x11, 0x1c, 0x20, + 0x93, 0xc0, 0x6b, 0x08, 0x22, 0x11, 0xf0, 0xed, + 0x09, 0x00, 0x4b, 0x01, 0xd6, 0xf8, 0x0a, 0xa8, + 0x11, 0xf0, 0x2f, 0xf9, 0x15, 0x9a, 0x18, 0x90, + 0x01, 0x2a, 0x06, 0xd1, 0xb8, 0x19, 0x18, 0x9a, + 0x0a, 0xa9, 0xeb, 0xf7, 0xda, 0xfd, 0x18, 0x98, + 0x36, 0x18, 0x18, 0x98, 0x84, 0x42, 0x0f, 0xd9, + 0x20, 0x21, 0x30, 0x20, 0x16, 0x9a, 0x00, 0x2a, + 0x04, 0xd0, 0x15, 0x9a, 0x00, 0x2a, 0x01, 0xd1, + 0xb8, 0x55, 0x00, 0xe0, 0xb9, 0x55, 0x18, 0x9a, + 0x01, 0x3c, 0x01, 0x36, 0x94, 0x42, 0xf1, 0xd8, + 0x15, 0x9a, 0x00, 0x2a, 0x06, 0xd1, 0xb8, 0x19, + 0x18, 0x9a, 0x0a, 0xa9, 0xeb, 0xf7, 0xbd, 0xfd, + 0x18, 0x98, 0x36, 0x18, 0x0d, 0xe1, 0x3e, 0x49, + 0x0c, 0xa8, 0x0c, 0xc9, 0x0c, 0xc0, 0x0e, 0xc9, + 0x0e, 0xc0, 0x20, 0x9b, 0x04, 0x33, 0xd8, 0x1f, + 0x39, 0x38, 0x20, 0x93, 0xc0, 0x6b, 0x00, 0x2c, + 0x00, 0xd1, 0x01, 0x24, 0x15, 0x9a, 0x01, 0x2a, + 0x01, 0xd1, 0x00, 0x19, 0x01, 0x38, 0x61, 0x1e, + 0x00, 0x2c, 0x47, 0xd0, 0x3a, 0x24, 0x1a, 0x9a, + 0xb2, 0x42, 0x02, 0xd8, 0x00, 0x20, 0xb8, 0x55, + 0xa1, 0xe5, 0x14, 0x9a, 0x30, 0x2a, 0x05, 0xd1, + 0x30, 0x23, 0xbb, 0x55, 0x78, 0x23, 0x72, 0x1c, + 0xbb, 0x54, 0x56, 0x1c, 0x00, 0x28, 0x11, 0xd1, + 0x28, 0x20, 0xb8, 0x55, 0x71, 0x1c, 0x6e, 0x22, + 0x7a, 0x54, 0x48, 0x1c, 0x75, 0x22, 0x3a, 0x54, + 0x41, 0x1c, 0x6c, 0x22, 0x7a, 0x54, 0x48, 0x1c, + 0x3a, 0x54, 0x41, 0x1c, 0x29, 0x20, 0x78, 0x54, + 0x4e, 0x1c, 0x23, 0xe0, 0x02, 0x78, 0x0c, 0xab, + 0x12, 0x09, 0x9b, 0x5c, 0xbb, 0x55, 0x03, 0x78, + 0x1b, 0x07, 0x1b, 0x0f, 0x72, 0x1c, 0x0c, 0xae, + 0xf3, 0x5c, 0x56, 0x1c, 0xbb, 0x54, 0x15, 0x9a, + 0x01, 0x2a, 0x01, 0xd1, 0x01, 0x38, 0x00, 0xe0, + 0x01, 0x30, 0x00, 0x29, 0x0a, 0xd0, 0x14, 0x9a, + 0x3a, 0x2a, 0xed, 0x09, 0x00, 0x4c, 0x01, 0x03, + 0xd1, 0x32, 0x1c, 0xbc, 0x54, 0x01, 0x36, 0x03, + 0xe0, 0x20, 0x23, 0x32, 0x1c, 0xbb, 0x54, 0x01, + 0x36, 0x0a, 0x1c, 0x01, 0x39, 0x00, 0x2a, 0xb8, + 0xd1, 0xad, 0xe0, 0x20, 0x9b, 0x04, 0x33, 0xd8, + 0x1f, 0x39, 0x38, 0x20, 0x93, 0xc1, 0x6b, 0x19, + 0x91, 0x00, 0x29, 0x01, 0xd1, 0x0b, 0xa1, 0x19, + 0x91, 0x17, 0x98, 0x00, 0x28, 0x03, 0xd1, 0x1e, + 0x99, 0x88, 0x1b, 0x02, 0x38, 0x17, 0x90, 0x00, + 0x22, 0x18, 0x92, 0x0e, 0xe0, 0x18, 0x9a, 0x01, + 0x32, 0x18, 0x92, 0x0a, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, + 0x5c, 0x03, 0x20, 0x28, 0x6e, 0x75, 0x6c, 0x6c, + 0x29, 0x00, 0x00, 0x19, 0x99, 0x18, 0x9a, 0x88, + 0x56, 0x00, 0x28, 0x03, 0xd0, 0x17, 0x98, 0x18, + 0x9a, 0x82, 0x42, 0xe7, 0xd3, 0x15, 0x9a, 0x01, + 0x2a, 0x06, 0xd1, 0xb8, 0x19, 0x19, 0x99, 0x18, + 0x9a, 0xeb, 0xf7, 0x25, 0xfd, 0x18, 0x9a, 0xb6, + 0x18, 0x18, 0x9a, 0x94, 0x42, 0x0f, 0xd9, 0x20, + 0x21, 0x30, 0x20, 0x16, 0x9a, 0x00, 0x2a, 0x04, + 0xd0, 0x15, 0x9a, 0x00, 0x2a, 0x01, 0xd1, 0xb8, + 0x55, 0x00, 0xe0, 0xb9, 0x55, 0x18, 0x9a, 0x01, + 0x3c, 0x01, 0x36, 0x94, 0x42, 0xf1, 0xd8, 0x15, + 0x9a, 0x00, 0x2a, 0x60, 0xd1, 0xb8, 0x19, 0x19, + 0x99, 0x18, 0x9a, 0xeb, 0xf7, 0x08, 0xfd, 0x18, + 0x9a, 0xb6, 0x18, 0x13, 0xe1, 0x13, 0x98, 0x01, + 0x28, 0x1d, 0xd1, 0x20, 0x9b, 0x08, 0x33, 0xd9, + 0x1f, 0x01, 0x39, 0x20, 0x93, 0x08, 0x68, 0x8e, + 0xa3, 0x0a, 0x90, 0x49, 0x68, 0x0b, 0x91, 0x1a, + 0x68, 0x5b, 0x68, 0xeb, 0xf7, 0x1c, 0xfe, 0x00, + 0x28, 0x06, 0xd0, 0x00, 0xa1, 0x07, 0x22, 0x94, + 0x39, 0x0c, 0xa8, 0xeb, 0xf7, 0xec, 0xfc, 0x05, + 0xe0, 0x10, 0x23, 0x0a, 0x98, 0xed, 0x09, 0x00, + 0x4d, 0x01, 0x0b, 0x99, 0x0c, 0xaa, 0x10, 0xf0, + 0x07, 0xff, 0x12, 0xe0, 0x20, 0x9b, 0x04, 0x33, + 0xd8, 0x1f, 0x39, 0x38, 0x20, 0x93, 0xc0, 0x6b, + 0x00, 0x28, 0x06, 0xd1, 0x00, 0xa1, 0x07, 0x22, + 0xc0, 0x39, 0x0c, 0xa8, 0xeb, 0xf7, 0xd6, 0xfc, + 0x03, 0xe0, 0x10, 0x22, 0x0c, 0xa9, 0x10, 0xf0, + 0xc1, 0xff, 0x0c, 0xa8, 0x11, 0xf0, 0x1a, 0xf8, + 0x15, 0x9a, 0x18, 0x90, 0x01, 0x2a, 0x02, 0xd0, + 0x18, 0x98, 0x84, 0x42, 0x1b, 0xd8, 0x14, 0x9a, + 0x30, 0x2a, 0x05, 0xd1, 0x30, 0x21, 0xb9, 0x55, + 0x78, 0x21, 0x70, 0x1c, 0x39, 0x54, 0x46, 0x1c, + 0xb8, 0x19, 0x18, 0x9a, 0x0c, 0xa9, 0xeb, 0xf7, + 0xb9, 0xfc, 0x18, 0x98, 0x36, 0x18, 0x84, 0x42, + 0x36, 0xd9, 0x20, 0x21, 0x30, 0x1c, 0x39, 0x54, + 0x18, 0x98, 0x01, 0x36, 0x01, 0x3c, 0x84, 0x42, + 0xf8, 0xd8, 0x2d, 0xe0, 0xb9, 0xe0, 0x16, 0x9a, + 0x00, 0x2a, 0x11, 0xd0, 0x14, 0x9a, 0x30, 0x2a, + 0x05, 0xd1, 0x30, 0x21, 0xb9, 0x55, 0x78, 0x21, + 0x70, 0x1c, 0x39, 0x54, 0x46, 0x1c, 0x30, 0x21, + 0x30, 0x1c, 0x39, 0x54, 0x18, 0x98, 0x01, 0x36, + 0x01, 0x3c, 0x84, 0x42, 0xf8, 0xd8, 0x10, 0xe0, + 0x20, 0x21, 0x30, 0x1c, 0x39, 0x54, 0x18, 0x98, + 0x01, 0x36, 0x01, 0x3c, 0x84, 0x42, 0xf8, 0xd8, + 0x14, 0x9a, 0x30, 0x2a, 0x05, 0xd1, 0x30, 0x21, + 0xb9, 0x55, 0x78, 0x21, 0x70, 0x1c, 0x39, 0x54, + 0x46, 0x1c, 0xb8, 0x19, 0x18, 0x9a, 0x0c, 0xa9, + 0xeb, 0xf7, 0x80, 0xfc, 0x18, 0x98, 0x36, 0x18, + 0x8b, 0xe0, 0x13, 0x98, 0x01, 0x28, 0x0c, 0xd1, + 0x20, 0x9b, 0x0c, 0xaa, 0x08, 0x33, 0xd9, 0x1f, + 0x01, 0x39, 0x20, 0x93, 0x08, 0x68, 0x49, 0x68, + 0x10, 0x23, 0x10, 0xf0, 0x91, 0xfe, 0x0a, 0xe0, + 0x80, 0xe0, 0x20, 0x9b, 0x0c, 0xa9, 0x04, 0x33, + 0xed, 0x09, 0x00, 0x4e, 0x01, 0xd8, 0x1f, 0x39, + 0x38, 0x20, 0x93, 0xc0, 0x6b, 0x10, 0x22, 0x10, + 0xf0, 0x53, 0xff, 0x0c, 0xa8, 0x10, 0xf0, 0xac, + 0xff, 0x15, 0x9a, 0x18, 0x90, 0x01, 0x2a, 0x02, + 0xd0, 0x18, 0x98, 0x84, 0x42, 0x1a, 0xd8, 0x14, + 0x9a, 0x30, 0x2a, 0x05, 0xd1, 0x30, 0x21, 0xb9, + 0x55, 0x78, 0x21, 0x70, 0x1c, 0x39, 0x54, 0x46, + 0x1c, 0xb8, 0x19, 0x18, 0x9a, 0x0c, 0xa9, 0xeb, + 0xf7, 0x4b, 0xfc, 0x18, 0x98, 0x36, 0x18, 0x84, + 0x42, 0x36, 0xd9, 0x20, 0x21, 0x30, 0x1c, 0x39, + 0x54, 0x18, 0x98, 0x01, 0x36, 0x01, 0x3c, 0x84, + 0x42, 0xf8, 0xd8, 0x2d, 0xe0, 0x16, 0x9a, 0x00, + 0x2a, 0x12, 0xd0, 0x14, 0x9a, 0x30, 0x2a, 0x05, + 0xd1, 0x30, 0x21, 0xb9, 0x55, 0x78, 0x21, 0x70, + 0x1c, 0x39, 0x54, 0x46, 0x1c, 0x30, 0x21, 0x30, + 0x1c, 0x39, 0x54, 0x18, 0x98, 0x01, 0x36, 0x01, + 0x3c, 0x84, 0x42, 0xf8, 0xd8, 0x11, 0xe0, 0x44, + 0xe0, 0x20, 0x21, 0x30, 0x1c, 0x39, 0x54, 0x18, + 0x98, 0x01, 0x36, 0x01, 0x3c, 0x84, 0x42, 0xf8, + 0xd8, 0x14, 0x9a, 0x30, 0x2a, 0x05, 0xd1, 0x30, + 0x21, 0xb9, 0x55, 0x78, 0x21, 0x70, 0x1c, 0x39, + 0x54, 0x46, 0x1c, 0xb8, 0x19, 0x18, 0x9a, 0x0c, + 0xa9, 0xeb, 0xf7, 0x12, 0xfc, 0x18, 0x98, 0x36, + 0x18, 0x1d, 0xe0, 0x1f, 0xe0, 0x20, 0x9b, 0x04, + 0x33, 0xd8, 0x1f, 0x39, 0x38, 0x54, 0x21, 0xc9, + 0x43, 0x20, 0x93, 0xc0, 0x6b, 0x72, 0x1c, 0xb9, + 0x55, 0x03, 0x0a, 0x51, 0x1c, 0xb8, 0x54, 0x7b, + 0x54, 0x03, 0x0c, 0x4a, 0x1c, 0x00, 0x0e, 0x51, + 0x1c, 0xbb, 0x54, 0x78, 0x54, 0x45, 0x20, 0xc0, + 0x43, 0x4a, 0x1c, 0xb8, 0x54, 0x56, 0x1c, 0x02, + 0xe0, 0x06, 0xe0, 0xb8, 0x55, 0x01, 0x36, 0x00, + 0x20, 0x13, 0x90, 0x01, 0xe0, 0xb8, 0x55, 0x01, + 0x36, 0x00, 0x23, 0xed, 0x09, 0x00, 0x4f, 0x01, + 0x01, 0x35, 0xe8, 0x56, 0x00, 0x28, 0x01, 0xd0, + 0xff, 0xf7, 0xe6, 0xfb, 0x00, 0x2e, 0x00, 0xd1, + 0x44, 0xe6, 0x00, 0x20, 0xb8, 0x55, 0x41, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0xb4, 0x00, 0xb5, 0x00, 0x21, + 0xc9, 0x43, 0x02, 0x9a, 0x03, 0xab, 0xff, 0xf7, + 0xbe, 0xfb, 0x08, 0xbc, 0x04, 0xb0, 0x18, 0x47, + 0x0f, 0xb4, 0x00, 0xb5, 0x03, 0x9a, 0x04, 0xab, + 0xff, 0xf7, 0xb5, 0xfb, 0x08, 0xbc, 0x04, 0xb0, + 0x18, 0x47, 0xf0, 0xb5, 0xa2, 0xb0, 0x00, 0x22, + 0x00, 0x92, 0x31, 0x4f, 0x7f, 0x22, 0x38, 0x1c, + 0x02, 0xa9, 0x01, 0xab, 0x11, 0xf0, 0xb9, 0xf9, + 0x28, 0x23, 0xd8, 0x42, 0x07, 0xd1, 0x82, 0x11, + 0x00, 0x92, 0x7f, 0x22, 0x38, 0x1c, 0x02, 0xa9, + 0x01, 0xab, 0x11, 0xf0, 0xae, 0xf9, 0x01, 0x98, + 0x00, 0x22, 0x02, 0xa9, 0x0a, 0x54, 0x06, 0x28, + 0x02, 0xac, 0x02, 0xad, 0x40, 0xd3, 0x20, 0x78, + 0xab, 0x28, 0x36, 0xd1, 0x60, 0x79, 0xba, 0x28, + 0x33, 0xd1, 0xac, 0x42, 0x05, 0xd0, 0x00, 0x22, + 0x22, 0x70, 0x28, 0x1c, 0x10, 0xf0, 0x07, 0xf9, + 0x25, 0x1c, 0x61, 0x78, 0x00, 0xab, 0x19, 0x70, + 0xa1, 0x78, 0x59, 0x70, 0xe1, 0x78, 0x99, 0x70, + 0x20, 0x79, 0xd8, 0x70, 0x00, 0x99, 0x00, 0x29, + 0x16, 0xd0, 0x7d, 0x20, 0xc0, 0x00, 0xeb, 0xf7, + 0xa0, 0xfa, 0x0e, 0x1c, 0x01, 0x1c, 0x3c, 0x20, + 0xeb, 0xf7, 0x9b, 0xfa, 0x0f, 0x1c, 0x01, 0x1c, + 0x3c, 0x20, 0xeb, 0xf7, 0x96, 0xfa, 0x0a, 0x1c, + 0x3b, 0x1c, 0x10, 0xa7, 0x01, 0x1c, 0x38, 0x1c, + 0x00, 0x96, 0x00, 0xf0, 0x16, 0xf9, 0x02, 0xe0, + 0x13, 0xa0, 0x00, 0xf0, 0x12, 0xf9, 0x01, 0x98, + 0x06, 0x34, 0x06, 0x38, 0x01, 0x90, 0x06, 0x35, + 0x03, 0xe0, 0x01, 0x98, 0x01, 0x38, 0xed, 0x09, + 0x00, 0x50, 0x01, 0x01, 0x90, 0x01, 0x34, 0x01, + 0x98, 0x06, 0x28, 0xbe, 0xd2, 0x00, 0x23, 0xe8, + 0x56, 0x00, 0x28, 0x9e, 0xd0, 0x28, 0x1c, 0x10, + 0xf0, 0xcc, 0xf8, 0x9a, 0xe7, 0x00, 0x00, 0x4c, + 0xb8, 0x03, 0x20, 0x5b, 0x25, 0x30, 0x32, 0x75, + 0x3a, 0x25, 0x30, 0x32, 0x75, 0x3a, 0x25, 0x30, + 0x32, 0x75, 0x20, 0x25, 0x30, 0x33, 0x75, 0x5d, + 0x00, 0x00, 0x00, 0x5b, 0x69, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x20, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x5d, + 0x00, 0x00, 0x00, 0x90, 0xb5, 0xa2, 0xb0, 0x0c, + 0xa0, 0x10, 0xf0, 0xd9, 0xf8, 0x10, 0x4c, 0x00, + 0x27, 0x00, 0x22, 0x00, 0x92, 0x7f, 0x22, 0x20, + 0x1c, 0x02, 0xa9, 0x01, 0xab, 0x11, 0xf0, 0x33, + 0xf9, 0x00, 0x28, 0x05, 0xd1, 0x01, 0x99, 0x02, + 0xa8, 0x47, 0x54, 0x10, 0xf0, 0xc8, 0xf8, 0xef, + 0xe7, 0x22, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x44, 0x65, 0x62, 0x75, 0x67, + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x5f, 0x46, + 0x6c, 0x75, 0x73, 0x68, 0x3a, 0x0a, 0x00, 0x4c, + 0xb8, 0x03, 0x20, 0x80, 0xb5, 0x07, 0x1c, 0xfd, + 0xf7, 0xa8, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x20, + 0xf0, 0xb0, 0xfd, 0x0e, 0x48, 0x05, 0x2f, 0x0f, + 0xd2, 0x02, 0xa3, 0xdb, 0x5d, 0x5b, 0x00, 0x9f, + 0x44, 0x00, 0x1c, 0x03, 0x09, 0x06, 0x06, 0x06, + 0x00, 0xfd, 0xf7, 0xf9, 0xfd, 0x04, 0xe0, 0xfd, + 0xf7, 0xc2, 0xfe, 0x01, 0xe0, 0xfd, 0xf7, 0xf3, + 0xfd, 0x06, 0x48, 0x07, 0x60, 0xfd, 0xf7, 0x8d, + 0xff, 0x00, 0x28, 0x01, 0xd1, 0x20, 0xf0, 0x91, + 0xfd, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xa4, + 0xb7, 0x03, 0x20, 0xd0, 0x67, 0x03, 0x20, 0x80, + 0xb5, 0x87, 0xb0, 0x01, 0x20, 0x40, 0x03, 0x10, + 0xf0, 0xed, 0x09, 0x00, 0x51, 0x01, 0x46, 0xfe, + 0x1f, 0x27, 0xff, 0x43, 0x19, 0x49, 0x03, 0x1c, + 0x00, 0x28, 0x48, 0x60, 0x04, 0xd1, 0x38, 0x1c, + 0x07, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x06, 0x22, 0x7f, 0x21, 0x0d, 0x20, 0x02, 0x92, + 0x1a, 0x1c, 0x01, 0x23, 0x00, 0x90, 0x01, 0x91, + 0x12, 0xa1, 0x11, 0x48, 0x5b, 0x03, 0x10, 0xf0, + 0x1d, 0xff, 0x11, 0x48, 0x10, 0xf0, 0x2a, 0xfe, + 0x03, 0x1c, 0x01, 0xd1, 0x38, 0x1c, 0xe7, 0xe7, + 0x09, 0x22, 0x06, 0x92, 0x64, 0x22, 0x0a, 0x21, + 0x05, 0x91, 0x03, 0x92, 0x00, 0x22, 0x0a, 0x49, + 0x14, 0x20, 0x04, 0x90, 0x00, 0x92, 0x01, 0x93, + 0x02, 0x91, 0x06, 0xa1, 0x00, 0x23, 0x07, 0x4a, + 0x07, 0x48, 0xfd, 0xf7, 0x77, 0xfb, 0x00, 0x20, + 0xd2, 0xe7, 0x00, 0x00, 0xd0, 0x67, 0x03, 0x20, + 0x4c, 0xb8, 0x03, 0x20, 0x44, 0x62, 0x67, 0x00, + 0xfe, 0x04, 0x00, 0x00, 0x95, 0x4c, 0x01, 0x20, + 0xa4, 0xb7, 0x03, 0x20, 0x90, 0xb5, 0x17, 0x1c, + 0x1c, 0xd0, 0x01, 0x2f, 0x03, 0xd0, 0x02, 0x2f, + 0x01, 0xd0, 0x03, 0x2f, 0x13, 0xd1, 0x0a, 0x1c, + 0x11, 0x4c, 0x01, 0x1c, 0x00, 0x23, 0x20, 0x1c, + 0x10, 0xf0, 0xae, 0xff, 0x29, 0x23, 0xd8, 0x42, + 0x05, 0xd1, 0x20, 0x1c, 0x00, 0x23, 0x06, 0x22, + 0x0c, 0xa1, 0x10, 0xf0, 0xa5, 0xff, 0x02, 0x2f, + 0x01, 0xd1, 0x0e, 0xf0, 0xb3, 0xfa, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x10, 0xf0, 0x22, 0xf8, + 0x08, 0x48, 0x41, 0x79, 0x60, 0x23, 0x19, 0x40, + 0x60, 0x29, 0xf4, 0xd0, 0x41, 0x79, 0x60, 0x23, + 0x19, 0x40, 0x60, 0x29, 0xfa, 0xd1, 0xee, 0xe7, + 0x4c, 0xb8, 0x03, 0x20, 0x3c, 0x46, 0x55, 0x4c, + 0x4c, 0x3e, 0x00, 0x00, 0x60, 0x00, 0x00, 0xd0, + 0x0f, 0xb4, 0x00, 0xb5, 0x06, 0x48, 0x01, 0x22, + 0x03, 0x68, 0x02, 0xa9, 0xed, 0x09, 0x00, 0x52, + 0x01, 0x00, 0x2b, 0x00, 0xd0, 0x02, 0x68, 0x01, + 0x98, 0xfe, 0xf7, 0xea, 0xfd, 0x08, 0xbc, 0x04, + 0xb0, 0x18, 0x47, 0x00, 0x00, 0xd0, 0x67, 0x03, + 0x20, 0x0f, 0xb4, 0x00, 0xb5, 0x00, 0x22, 0x01, + 0x98, 0x02, 0xa9, 0xfe, 0xf7, 0xdd, 0xfd, 0x08, + 0xbc, 0x04, 0xb0, 0x18, 0x47, 0x0f, 0xb4, 0x00, + 0xb5, 0x04, 0x48, 0x02, 0xa9, 0x02, 0x68, 0x01, + 0x98, 0xfe, 0xf7, 0xd2, 0xfd, 0x08, 0xbc, 0x04, + 0xb0, 0x18, 0x47, 0x00, 0x00, 0xd0, 0x67, 0x03, + 0x20, 0x90, 0xb5, 0x87, 0xb0, 0x07, 0x1c, 0x23, + 0x48, 0xc4, 0x1b, 0x9c, 0x20, 0x0f, 0xf0, 0x5a, + 0xff, 0x0f, 0xf0, 0x6c, 0xff, 0xfe, 0xf7, 0xba, + 0xfd, 0x20, 0xf0, 0xe0, 0xfc, 0xfc, 0xf7, 0xfe, + 0xfb, 0x0f, 0xf0, 0xec, 0xff, 0x10, 0xf0, 0x3e, + 0xf8, 0x1b, 0xa3, 0x22, 0xa2, 0x24, 0xa1, 0x27, + 0xa0, 0xff, 0xf7, 0xd8, 0xff, 0xff, 0x21, 0x01, + 0x31, 0x06, 0x22, 0x01, 0x92, 0x3a, 0x1c, 0x00, + 0x91, 0x2d, 0xa1, 0x23, 0x1c, 0x2b, 0x48, 0x11, + 0xf0, 0xa3, 0xf9, 0x10, 0xf0, 0x6d, 0xf8, 0x06, + 0xf0, 0x03, 0xfc, 0x00, 0xf0, 0x27, 0xf9, 0x01, + 0x27, 0x3f, 0x03, 0x38, 0x1c, 0x10, 0xf0, 0x74, + 0xfd, 0x27, 0x49, 0x0c, 0x22, 0x48, 0x60, 0x06, + 0x92, 0x01, 0x22, 0x03, 0x1c, 0x03, 0x92, 0x00, + 0x22, 0x00, 0x20, 0x08, 0x21, 0x05, 0x91, 0x04, + 0x90, 0x00, 0x92, 0x01, 0x93, 0x00, 0x23, 0x21, + 0x4a, 0x21, 0x48, 0x22, 0xa1, 0x02, 0x97, 0xfd, + 0xf7, 0xc3, 0xfa, 0x07, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x20, 0x24, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x36, 0x39, 0x20, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x31, 0x36, 0xed, + 0x09, 0x00, 0x53, 0x01, 0x3a, 0x30, 0x34, 0x3a, + 0x32, 0x31, 0x00, 0x00, 0x00, 0x00, 0x41, 0x70, + 0x72, 0x20, 0x32, 0x33, 0x20, 0x32, 0x30, 0x30, + 0x33, 0x00, 0x0d, 0x0a, 0x42, 0x6c, 0x75, 0x65, + 0x74, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x20, 0x28, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x20, 0x25, 0x73, 0x20, 0x25, + 0x73, 0x20, 0x25, 0x73, 0x29, 0x0d, 0x0a, 0x00, + 0x00, 0x00, 0x94, 0xb8, 0x03, 0x20, 0x53, 0x59, + 0x53, 0x4d, 0x45, 0x4d, 0x00, 0x00, 0xd8, 0x67, + 0x03, 0x20, 0x11, 0x51, 0x01, 0x20, 0x1c, 0xb9, + 0x03, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xb5, 0x09, 0x4f, 0x38, 0x1c, + 0xfd, 0xf7, 0xd1, 0xfb, 0x38, 0x1c, 0xfd, 0xf7, + 0x5a, 0xfb, 0x06, 0x4f, 0x78, 0x68, 0x10, 0xf0, + 0x6c, 0xfd, 0x00, 0x20, 0x78, 0x60, 0x02, 0x20, + 0x38, 0x60, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x1c, 0xb9, 0x03, 0x20, 0xd8, 0x67, + 0x03, 0x20, 0x80, 0xb4, 0x0e, 0x49, 0x00, 0x23, + 0x0a, 0x68, 0x17, 0x78, 0x11, 0x1c, 0xff, 0x2f, + 0x12, 0xd0, 0x17, 0x78, 0x00, 0x2f, 0x0b, 0xd1, + 0x00, 0x28, 0x07, 0xd1, 0x18, 0x1c, 0x00, 0x23, + 0xca, 0x56, 0x00, 0x2a, 0x00, 0xd0, 0x08, 0x1c, + 0x80, 0xbc, 0x70, 0x47, 0x01, 0x38, 0x51, 0x1c, + 0x57, 0x78, 0x01, 0x32, 0xff, 0x2f, 0xec, 0xd1, + 0x18, 0x1c, 0xf5, 0xe7, 0x00, 0x00, 0xc8, 0x67, + 0x03, 0x20, 0x00, 0xb5, 0x68, 0x22, 0xff, 0x21, + 0x1f, 0x20, 0x80, 0x02, 0xeb, 0xf7, 0xf9, 0xf8, + 0x68, 0x22, 0x1f, 0x20, 0x80, 0x02, 0x0c, 0x49, + 0x10, 0xf0, 0x0f, 0xf8, 0x01, 0x20, 0x40, 0x02, + 0x20, 0xf0, 0x73, 0xfb, 0x00, 0x20, 0x20, 0xf0, + 0x14, 0xfc, 0xff, 0xf7, 0x80, 0xfe, 0x00, 0xf0, + 0x7c, 0xf9, 0xed, 0x09, 0x00, 0x54, 0x01, 0x9c, + 0x20, 0x0f, 0xf0, 0x85, 0xfe, 0x00, 0xf0, 0xf9, + 0xf9, 0x0d, 0xf0, 0xf9, 0xfe, 0x03, 0x49, 0x01, + 0x20, 0x08, 0x60, 0x08, 0xbc, 0x18, 0x47, 0x98, + 0x1f, 0x00, 0x00, 0xd8, 0x67, 0x03, 0x20, 0x70, + 0x47, 0x00, 0x00, 0x00, 0x20, 0x70, 0x47, 0xb0, + 0xb5, 0x04, 0x1c, 0x0d, 0x1c, 0x17, 0x1c, 0x20, + 0xf0, 0xfe, 0xfb, 0x05, 0x49, 0x00, 0x20, 0x08, + 0x60, 0x21, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x03, + 0xa0, 0xff, 0xf7, 0xf5, 0xfe, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xd0, 0x67, 0x03, 0x20, 0x0a, + 0x0d, 0x50, 0x72, 0x65, 0x66, 0x65, 0x74, 0x63, + 0x68, 0x5f, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x5f, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3a, + 0x20, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x2e, 0x3a, + 0x25, 0x78, 0x20, 0x61, 0x74, 0x20, 0x25, 0x78, + 0x20, 0x28, 0x4d, 0x50, 0x55, 0x5f, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x3a, 0x20, 0x25, 0x78, + 0x29, 0x0a, 0x00, 0xf0, 0xb5, 0x0c, 0x1c, 0x05, + 0x1c, 0x17, 0x1c, 0x20, 0xf0, 0xcc, 0xfb, 0x00, + 0x26, 0x06, 0x48, 0x29, 0x1c, 0x22, 0x1c, 0x06, + 0x60, 0x05, 0xa0, 0x3b, 0x1c, 0xff, 0xf7, 0xc3, + 0xfe, 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0xd0, 0x67, 0x03, 0x20, 0x0a, + 0x0d, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x41, 0x62, + 0x6f, 0x72, 0x74, 0x5f, 0x48, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x72, 0x3a, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x72, 0x2e, 0x3a, 0x25, 0x78, 0x20, 0x61, + 0x74, 0x20, 0x25, 0x78, 0x20, 0x28, 0x4d, 0x50, + 0x55, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x3a, 0x20, 0x25, 0x78, 0x29, 0x0a, 0x00, 0x80, + 0xb5, 0x87, 0xb0, 0x01, 0x20, 0x14, 0x49, 0x01, + 0x27, 0xff, 0x02, 0x08, 0x60, 0xed, 0x09, 0x00, + 0x55, 0x01, 0x38, 0x1c, 0x10, 0xf0, 0x48, 0xfc, + 0x03, 0x1c, 0x05, 0xd1, 0x1f, 0x20, 0xc0, 0x43, + 0x07, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x0c, 0x22, 0x06, 0x92, 0x64, 0x22, 0x03, 0x92, + 0x00, 0x22, 0x0a, 0x21, 0x00, 0x20, 0x04, 0x90, + 0x05, 0x91, 0x00, 0x92, 0x01, 0x93, 0x00, 0x23, + 0x07, 0x4a, 0x09, 0xa1, 0x07, 0x48, 0x02, 0x97, + 0xfd, 0xf7, 0x92, 0xf9, 0x07, 0x1c, 0x03, 0xd0, + 0x38, 0x1c, 0x00, 0xdf, 0x38, 0x1c, 0xe3, 0xe7, + 0x00, 0x20, 0xe1, 0xe7, 0xe0, 0x67, 0x03, 0x20, + 0x79, 0x53, 0x01, 0x20, 0xc4, 0xb9, 0x03, 0x20, + 0x69, 0x64, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xb5, 0x18, 0x4f, 0x00, 0x26, 0x78, 0x68, + 0x00, 0x28, 0x06, 0xd1, 0xfc, 0xf7, 0x9c, 0xfa, + 0x78, 0x60, 0xbe, 0x60, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xb8, 0x68, 0x01, 0x30, 0xb8, 0x60, + 0xfc, 0xf7, 0x92, 0xfa, 0x79, 0x68, 0x10, 0x4b, + 0xcd, 0x18, 0x85, 0x42, 0xf2, 0xd2, 0x3c, 0x1c, + 0xbf, 0x68, 0xa0, 0x69, 0x87, 0x42, 0x00, 0xd9, + 0xa7, 0x61, 0x60, 0x69, 0x87, 0x42, 0x00, 0xd9, + 0x67, 0x61, 0xe0, 0x69, 0x87, 0x42, 0x00, 0xd2, + 0xe7, 0x61, 0x64, 0x21, 0x79, 0x43, 0xa0, 0x69, + 0xea, 0xf7, 0xae, 0xff, 0xe1, 0x68, 0x40, 0x18, + 0x40, 0x08, 0xe0, 0x60, 0x27, 0x61, 0x65, 0x60, + 0xa6, 0x60, 0xd7, 0xe7, 0xe0, 0x67, 0x03, 0x20, + 0x88, 0x13, 0x00, 0x00, 0xf0, 0xb5, 0x11, 0x4e, + 0x01, 0x23, 0xf5, 0x69, 0xdd, 0x42, 0x19, 0xd0, + 0x70, 0x69, 0x64, 0x21, 0x41, 0x43, 0xb0, 0x69, + 0x07, 0x1c, 0xea, 0xf7, 0x95, 0xff, 0x64, 0x21, + 0x69, 0x43, 0x04, 0x1c, 0x38, 0x1c, 0xea, 0xf7, + 0x8f, 0xff, 0x01, 0x1c, 0x08, 0xa0, 0x22, 0x1c, + 0xf3, 0x68, 0x06, 0xf0, 0x18, 0xff, 0x00, 0x20, + 0xed, 0x09, 0x00, 0x56, 0x01, 0xc0, 0x43, 0xf0, + 0x61, 0x00, 0x20, 0x70, 0x61, 0x64, 0x20, 0xf0, + 0x60, 0x30, 0x69, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xe0, 0x67, 0x03, 0x20, 0x49, 0x64, 0x6c, + 0x65, 0x5b, 0x30, 0x5d, 0x3a, 0x20, 0x6d, 0x69, + 0x6e, 0x20, 0x25, 0x64, 0x25, 0x25, 0x20, 0x6d, + 0x61, 0x78, 0x20, 0x25, 0x64, 0x25, 0x25, 0x20, + 0x61, 0x76, 0x72, 0x20, 0x25, 0x64, 0x25, 0x25, + 0x00, 0xb0, 0xb5, 0x0b, 0x4c, 0x0b, 0x4d, 0x00, + 0x27, 0xff, 0xf7, 0x8c, 0xff, 0x08, 0xf0, 0x2f, + 0xfa, 0x20, 0x68, 0x01, 0x28, 0x01, 0xd1, 0xff, + 0xf7, 0x87, 0xfe, 0x38, 0x1c, 0x01, 0x37, 0xa8, + 0x42, 0x02, 0xd9, 0x00, 0x27, 0x00, 0xf0, 0x19, + 0xf8, 0xfd, 0xf7, 0x6a, 0xfc, 0xec, 0xe7, 0x00, + 0x00, 0xd8, 0x67, 0x03, 0x20, 0x40, 0x42, 0x0f, + 0x00, 0x80, 0xb5, 0x07, 0x1c, 0xfc, 0xf7, 0x16, + 0xfa, 0xc7, 0x19, 0xfc, 0xf7, 0x13, 0xfa, 0xb8, + 0x42, 0xfb, 0xd3, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0x0b, 0xfa, 0x08, + 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xfc, 0xf7, 0x06, + 0xfa, 0x0b, 0x4d, 0x07, 0x1c, 0x29, 0x68, 0x2c, + 0x1d, 0x88, 0x42, 0x08, 0xd2, 0x09, 0xa3, 0x03, + 0xcc, 0x1a, 0x68, 0x5b, 0x68, 0x08, 0x3c, 0x80, + 0x18, 0x59, 0x41, 0x03, 0xc4, 0x08, 0x3c, 0x2f, + 0x60, 0x03, 0xcc, 0x00, 0x23, 0xc0, 0x19, 0xb0, + 0xbc, 0x59, 0x41, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x00, 0x68, 0x03, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xb5, 0x07, + 0x4f, 0x04, 0x21, 0x38, 0x1c, 0x11, 0xf0, 0x20, + 0xfa, 0x79, 0x6c, 0x00, 0x29, 0x02, 0xd0, 0xb8, + 0x6c, 0xea, 0xf7, 0xd9, 0xff, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x6c, 0xba, 0x03, + 0x20, 0x00, 0xb5, 0xed, 0x09, 0x00, 0x57, 0x01, + 0x83, 0xb0, 0x04, 0x22, 0x00, 0x21, 0x0a, 0x20, + 0x00, 0x90, 0x01, 0x91, 0x02, 0x92, 0x04, 0x4a, + 0x06, 0xa1, 0x04, 0x48, 0x00, 0x23, 0x11, 0xf0, + 0x5c, 0xf9, 0x03, 0xb0, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x15, 0x54, 0x01, 0x20, 0x6c, 0xba, + 0x03, 0x20, 0x43, 0x41, 0x5f, 0x54, 0x49, 0x4d, + 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb5, + 0x0f, 0x1c, 0x0d, 0x4e, 0x04, 0x21, 0x14, 0x1c, + 0x05, 0x1c, 0x30, 0x1c, 0x11, 0xf0, 0xef, 0xf9, + 0x00, 0x2f, 0x0f, 0xd0, 0x28, 0x1c, 0xeb, 0xf7, + 0xfe, 0xf8, 0x00, 0x28, 0x00, 0xd1, 0x01, 0x20, + 0xb4, 0x64, 0x77, 0x64, 0x05, 0x22, 0x00, 0x92, + 0x02, 0x1c, 0x00, 0x23, 0x30, 0x1c, 0x03, 0x49, + 0x11, 0xf0, 0xb7, 0xf9, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x6c, 0xba, 0x03, 0x20, 0x15, 0x54, + 0x01, 0x20, 0x1f, 0x48, 0x00, 0x21, 0x01, 0x60, + 0x01, 0x22, 0x42, 0x60, 0xfd, 0x22, 0x52, 0x01, + 0x08, 0x30, 0x00, 0x23, 0x0a, 0xc0, 0x0a, 0xc0, + 0x18, 0x38, 0x82, 0x61, 0x01, 0x22, 0xd2, 0x03, + 0x01, 0x23, 0xdb, 0x02, 0xc2, 0x61, 0x03, 0x62, + 0x22, 0x22, 0x42, 0x62, 0x83, 0x62, 0xc2, 0x62, + 0xca, 0x43, 0x30, 0x30, 0x00, 0x23, 0x0a, 0xc0, + 0x0a, 0xc0, 0x0a, 0xc0, 0x48, 0x38, 0xc1, 0x64, + 0x01, 0x65, 0xff, 0x23, 0x55, 0x33, 0x42, 0x65, + 0x83, 0x66, 0x41, 0x66, 0x01, 0x22, 0x12, 0x03, + 0xc1, 0x66, 0x02, 0x67, 0x02, 0x22, 0x42, 0x67, + 0x81, 0x65, 0xc1, 0x65, 0xc2, 0x1d, 0x79, 0x32, + 0x01, 0x66, 0x93, 0x60, 0x51, 0x60, 0xd1, 0x60, + 0x11, 0x61, 0x51, 0x61, 0x81, 0x67, 0xc1, 0x67, + 0x11, 0x60, 0x60, 0x20, 0xd0, 0x61, 0x11, 0x62, + 0x51, 0x62, 0x02, 0x48, 0x91, 0x62, 0xd0, 0x62, + 0x70, 0x47, 0x60, 0xbb, 0x03, 0x20, 0xed, 0x09, + 0x00, 0x58, 0x01, 0xff, 0xff, 0x00, 0x00, 0xb0, + 0xb5, 0x87, 0xb0, 0x1c, 0x4c, 0x20, 0x68, 0x00, + 0x28, 0x02, 0xd0, 0xff, 0x27, 0x10, 0x37, 0x30, + 0xe0, 0x13, 0xf0, 0x23, 0xfa, 0x07, 0x1c, 0x04, + 0xd0, 0x38, 0x1c, 0x07, 0xb0, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x20, 0xe1, 0x1d, 0x79, + 0x31, 0x88, 0x61, 0xff, 0xf7, 0xa4, 0xff, 0x00, + 0xf0, 0x91, 0xf9, 0x0b, 0x23, 0xdb, 0x02, 0x09, + 0x22, 0x06, 0x92, 0x46, 0x22, 0x0a, 0x21, 0x00, + 0x20, 0x05, 0x91, 0x03, 0x21, 0x89, 0x02, 0x03, + 0x92, 0x00, 0x22, 0x0c, 0x4d, 0x04, 0x90, 0x28, + 0x1c, 0x00, 0x92, 0x02, 0x91, 0x01, 0x93, 0x00, + 0x23, 0x0a, 0xa1, 0x07, 0x4a, 0xfc, 0xf7, 0xff, + 0xff, 0x00, 0x28, 0xda, 0xd1, 0x28, 0x1c, 0xfd, + 0xf7, 0x2e, 0xfa, 0x00, 0x28, 0xd5, 0xd1, 0x01, + 0x20, 0x20, 0x60, 0x38, 0x1c, 0xd1, 0xe7, 0x60, + 0xbb, 0x03, 0x20, 0x8f, 0x56, 0x01, 0x20, 0xb8, + 0xba, 0x03, 0x20, 0x54, 0x5f, 0x48, 0x43, 0x00, + 0x00, 0x00, 0x00, 0xb0, 0xb5, 0x0c, 0x4c, 0x00, + 0x27, 0x20, 0x68, 0x00, 0x28, 0x0e, 0xd0, 0x13, + 0xf0, 0x36, 0xfa, 0x09, 0x4d, 0x28, 0x1c, 0xfd, + 0xf7, 0x36, 0xf9, 0x28, 0x1c, 0xfd, 0xf7, 0xbf, + 0xf8, 0x00, 0xf0, 0xcb, 0xf9, 0x02, 0xf0, 0x93, + 0xfa, 0x00, 0x20, 0x20, 0x60, 0x38, 0x1c, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0xb8, 0xba, 0x03, 0x20, 0x00, + 0xb5, 0x02, 0xf0, 0x85, 0xfa, 0xff, 0xf7, 0x53, + 0xff, 0x02, 0x49, 0x01, 0x20, 0x08, 0x60, 0x08, + 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0xb0, + 0xb5, 0x0c, 0x1c, 0x05, 0x1c, 0x17, 0x1c, 0xeb, + 0xf7, 0x95, 0xfa, 0x00, 0x28, 0x08, 0xd0, 0xde, + 0x21, 0x01, 0x60, 0x0c, 0x30, 0xb0, 0xc0, 0x18, + 0x38, 0xed, 0x09, 0x00, 0x59, 0x01, 0x01, 0x1c, + 0x01, 0x20, 0xeb, 0xf7, 0xf9, 0xfa, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x02, 0x1c, + 0x41, 0x69, 0xc0, 0x68, 0x12, 0x69, 0xea, 0xf7, + 0xc7, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, + 0x83, 0xb0, 0x15, 0x1c, 0x08, 0x9a, 0x0f, 0x1c, + 0x04, 0x1c, 0x07, 0x48, 0x07, 0x99, 0x00, 0x90, + 0x01, 0x91, 0x39, 0x1c, 0x20, 0x1c, 0x02, 0x92, + 0x2a, 0x1c, 0x12, 0xf0, 0x57, 0xfb, 0x03, 0xb0, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x1d, 0x56, 0x01, 0x20, 0x00, 0xb5, 0x12, 0xf0, + 0x19, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x78, 0x4c, 0xfd, 0xf7, 0xf1, 0xfa, 0x00, 0x20, + 0xeb, 0xf7, 0x14, 0xfb, 0x07, 0x1c, 0x20, 0x6a, + 0x00, 0x28, 0x04, 0xd0, 0x38, 0x68, 0xbe, 0x28, + 0x01, 0xd0, 0xb7, 0x28, 0xf1, 0xd1, 0x38, 0x68, + 0xb7, 0x38, 0x2b, 0x28, 0x01, 0xd2, 0x43, 0x00, + 0x9f, 0x44, 0xd4, 0xe0, 0xd1, 0xe0, 0x54, 0xe0, + 0x4f, 0xe0, 0x4a, 0xe0, 0xc1, 0xe0, 0x54, 0xe0, + 0xbb, 0xe0, 0xb6, 0xe0, 0xad, 0xe0, 0xa8, 0xe0, + 0xa3, 0xe0, 0x9e, 0xe0, 0x29, 0xe0, 0x98, 0xe0, + 0x93, 0xe0, 0x8e, 0xe0, 0xa9, 0xe0, 0x34, 0xe0, + 0x27, 0xe0, 0x2a, 0xe0, 0x2d, 0xe0, 0x34, 0xe0, + 0x47, 0xe0, 0x4a, 0xe0, 0x4d, 0xe0, 0x50, 0xe0, + 0x53, 0xe0, 0x66, 0xe0, 0x6d, 0xe0, 0x70, 0xe0, + 0x67, 0xe0, 0x0a, 0xe0, 0x0d, 0xe0, 0x70, 0xe0, + 0x73, 0xe0, 0x4e, 0xe0, 0x51, 0xe0, 0x54, 0xe0, + 0x57, 0xe0, 0x72, 0xe0, 0xa1, 0xe0, 0xa4, 0xe0, + 0x07, 0xe0, 0x38, 0x1c, 0x02, 0xf0, 0xbc, 0xff, + 0xa5, 0xe0, 0x38, 0x1c, 0x02, 0xf0, 0xfa, 0xff, + 0xa1, 0xe0, 0x38, 0x1c, 0x03, 0xf0, 0x16, 0xf8, + 0x9d, 0xe0, 0x38, 0x1c, 0x02, 0xf0, 0x96, 0xfe, + 0x99, 0xe0, 0x38, 0x1c, 0xed, 0x09, 0x00, 0x5a, + 0x01, 0x02, 0xf0, 0x88, 0xfa, 0x95, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x98, 0xfa, 0x91, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xa6, 0xfa, 0x8d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xb4, 0xfa, 0x89, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xf0, 0xfa, 0x85, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x14, 0xfb, 0x81, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x20, 0xfb, 0x7d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x2a, 0xfb, 0x79, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x6c, 0xff, 0x75, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xec, 0xfa, 0x71, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xf4, 0xfa, 0x6d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x28, 0xfb, 0x69, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x82, 0xfb, 0x65, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xb8, 0xfb, 0x61, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xcc, 0xfb, 0x5d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xf8, 0xfb, 0x59, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x04, 0xfc, 0x55, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x10, 0xfc, 0x51, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x18, 0xfc, 0x4d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x54, 0xfc, 0x49, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xae, 0xfc, 0x45, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x50, 0xfd, 0x41, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x06, 0xfd, 0x3d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xd8, 0xfd, 0x39, 0xe0, 0x38, + 0x1c, 0xff, 0xf7, 0x26, 0xff, 0x35, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x0a, 0xfe, 0x31, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x1a, 0xfe, 0x2d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x3c, 0xfe, 0x29, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x58, 0xfe, 0x25, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x70, 0xfe, 0x21, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0x7c, 0xfe, 0x1d, 0xe0, 0x38, + 0x1c, 0x02, 0xf0, 0xc2, 0xfe, 0x19, 0xe0, 0xed, + 0x09, 0x00, 0x5b, 0x01, 0x38, 0x1c, 0x02, 0xf0, + 0xd8, 0xfd, 0x15, 0xe0, 0x38, 0x1c, 0x02, 0xf0, + 0xca, 0xfe, 0x11, 0xe0, 0x38, 0x1c, 0x02, 0xf0, + 0xf6, 0xfe, 0x0d, 0xe0, 0x38, 0x1c, 0x02, 0xf0, + 0xe2, 0xfe, 0x09, 0xe0, 0x38, 0x1c, 0x02, 0xf0, + 0x8c, 0xfe, 0x05, 0xe0, 0x38, 0x1c, 0x02, 0xf0, + 0x08, 0xff, 0x01, 0xe0, 0x01, 0xf0, 0x73, 0xff, + 0x00, 0x2f, 0x00, 0xd1, 0x12, 0xe7, 0x38, 0x1c, + 0xeb, 0xf7, 0xab, 0xf9, 0x0e, 0xe7, 0xe0, 0xbb, + 0x03, 0x20, 0x00, 0xb5, 0xeb, 0xf7, 0x6a, 0xf9, + 0x00, 0x28, 0x05, 0xd0, 0xb7, 0x21, 0x01, 0x60, + 0x01, 0x1c, 0x01, 0x20, 0xeb, 0xf7, 0xd1, 0xf9, + 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x87, 0xb0, + 0x1f, 0x4f, 0x01, 0x20, 0x39, 0x1c, 0x10, 0xf0, + 0x2c, 0xf9, 0x1d, 0x4c, 0x0b, 0x22, 0xe0, 0x60, + 0x01, 0x92, 0x1c, 0x49, 0x02, 0x1c, 0x00, 0x91, + 0x1d, 0xa1, 0x1b, 0x48, 0x3b, 0x1c, 0x10, 0xf0, + 0xfe, 0xff, 0x03, 0x21, 0x04, 0x20, 0x10, 0xf0, + 0x1c, 0xf9, 0x20, 0x61, 0x03, 0x1c, 0x07, 0x20, + 0x06, 0x22, 0x01, 0x21, 0x02, 0x92, 0x1a, 0x1c, + 0x01, 0x91, 0x00, 0x90, 0x17, 0x48, 0x17, 0xa1, + 0x03, 0x23, 0x11, 0xf0, 0x50, 0xf9, 0x07, 0x23, + 0x1b, 0x03, 0x0c, 0x22, 0x06, 0x92, 0x0a, 0x20, + 0x46, 0x22, 0x08, 0x21, 0x05, 0x91, 0x03, 0x21, + 0x89, 0x02, 0x03, 0x92, 0x00, 0x22, 0x00, 0x92, + 0x02, 0x91, 0x04, 0x90, 0x01, 0x93, 0x00, 0x23, + 0x10, 0x48, 0x10, 0xa1, 0x0e, 0x4a, 0xfc, 0xf7, + 0x4a, 0xfe, 0x07, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, 0x3f, 0x30, + 0x00, 0x00, 0x10, 0x68, 0x03, 0x20, 0x05, 0x10, + 0x00, 0x00, 0x18, 0xbc, 0x03, 0x20, 0x48, 0x43, + 0x49, 0x50, 0x55, 0x53, 0x42, 0x52, 0x78, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x5c, 0x01, 0x54, + 0xbc, 0x03, 0x20, 0x51, 0x5f, 0x48, 0x43, 0x49, + 0x50, 0x00, 0x00, 0x4d, 0x59, 0x01, 0x20, 0x9c, + 0xbc, 0x03, 0x20, 0x54, 0x5f, 0x48, 0x43, 0x49, + 0x50, 0x00, 0x00, 0x80, 0xb5, 0x83, 0xb0, 0x0a, + 0x4f, 0x00, 0x22, 0xd2, 0x43, 0x00, 0x92, 0x01, + 0x22, 0x38, 0x1c, 0x01, 0xa9, 0x02, 0xab, 0x11, + 0xf0, 0xa8, 0xfa, 0x00, 0x28, 0xf4, 0xd1, 0x01, + 0x98, 0x02, 0xf0, 0x15, 0xff, 0x00, 0x28, 0xef, + 0xd0, 0x01, 0x98, 0x11, 0xf0, 0xaa, 0xf8, 0xeb, + 0xe7, 0x00, 0x00, 0x54, 0xbc, 0x03, 0x20, 0xb0, + 0xb5, 0x0d, 0x48, 0xfc, 0xf7, 0xee, 0xfe, 0x0c, + 0x48, 0x11, 0xf0, 0x51, 0xf9, 0x0c, 0x4f, 0x38, + 0x69, 0x10, 0xf0, 0xcb, 0xf8, 0x00, 0x24, 0x3c, + 0x61, 0x0a, 0x48, 0x10, 0xf0, 0xe6, 0xff, 0x05, + 0x1c, 0xf8, 0x68, 0x10, 0xf0, 0xc2, 0xf8, 0x20, + 0x1c, 0x00, 0x2d, 0xfc, 0x60, 0x00, 0xd0, 0x07, + 0x20, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x9c, + 0xbc, 0x03, 0x20, 0x54, 0xbc, 0x03, 0x20, 0x10, + 0x68, 0x03, 0x20, 0x18, 0xbc, 0x03, 0x20, 0x00, + 0xb5, 0x0c, 0x22, 0x0d, 0xf0, 0x76, 0xfb, 0x08, + 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x0c, 0x1c, 0x05, + 0x1c, 0x17, 0x1c, 0xeb, 0xf7, 0xb9, 0xf8, 0x00, + 0x28, 0x0c, 0xd0, 0x07, 0x49, 0x4a, 0x68, 0x01, + 0x3a, 0x4a, 0x60, 0x8f, 0x21, 0x01, 0x60, 0xc5, + 0x60, 0x04, 0x74, 0x47, 0x61, 0x01, 0x1c, 0x02, + 0x20, 0xeb, 0xf7, 0x19, 0xf9, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0x00, + 0xb5, 0xeb, 0xf7, 0xa2, 0xf8, 0x00, 0x28, 0x09, + 0xd0, 0x06, 0x49, 0x4a, 0x68, 0x01, 0x3a, 0x4a, + 0x60, 0x90, 0x21, 0x01, 0x60, 0x01, 0x1c, 0x02, + 0x20, 0xeb, 0xf7, 0x05, 0xf9, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x60, 0xbb, 0xed, 0x09, 0x00, + 0x5d, 0x01, 0x03, 0x20, 0x00, 0xb5, 0x04, 0x48, + 0x01, 0x22, 0x04, 0x49, 0x40, 0x68, 0x03, 0xf0, + 0x18, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x03, 0x04, 0x00, 0x00, + 0x00, 0xb5, 0x04, 0x48, 0x01, 0x22, 0x04, 0x49, + 0x40, 0x68, 0x03, 0xf0, 0x0a, 0xfb, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, + 0x04, 0x04, 0x00, 0x00, 0xff, 0xb5, 0x04, 0x1c, + 0x0d, 0x1c, 0x08, 0x09, 0x09, 0x9e, 0x09, 0xd2, + 0x27, 0x48, 0x28, 0x4a, 0x41, 0x68, 0x11, 0x20, + 0x03, 0xf0, 0xbe, 0xf8, 0x04, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0x01, 0xf0, + 0xed, 0xfe, 0x00, 0x28, 0x06, 0xd0, 0x20, 0x48, + 0x20, 0x4a, 0x41, 0x68, 0x0b, 0x20, 0x03, 0xf0, + 0xaf, 0xf8, 0xef, 0xe7, 0xeb, 0xf7, 0x57, 0xf8, + 0x07, 0x1c, 0x06, 0xd1, 0x1a, 0x48, 0x1b, 0x4a, + 0x41, 0x68, 0x07, 0x20, 0x03, 0xf0, 0xa4, 0xf8, + 0xe4, 0xe7, 0x20, 0x1c, 0x18, 0xa1, 0x01, 0xf0, + 0xe5, 0xff, 0x00, 0x28, 0x09, 0xd1, 0x14, 0x48, + 0x14, 0x4a, 0x41, 0x68, 0x07, 0x20, 0x03, 0xf0, + 0x97, 0xf8, 0x38, 0x1c, 0xeb, 0xf7, 0x7a, 0xf8, + 0xd4, 0xe7, 0x01, 0x21, 0x0e, 0x4a, 0x41, 0x63, + 0x51, 0x68, 0x01, 0x39, 0x51, 0x60, 0xf8, 0x60, + 0xf8, 0x1d, 0x91, 0x21, 0x39, 0x60, 0x09, 0x30, + 0x06, 0x22, 0x21, 0x1c, 0xea, 0xf7, 0x96, 0xfc, + 0xbd, 0x61, 0x02, 0x9a, 0xfa, 0x61, 0x03, 0x9b, + 0x05, 0x4a, 0x3b, 0x62, 0x7e, 0x62, 0xd0, 0x69, + 0xb8, 0x62, 0x0a, 0x98, 0xf8, 0x62, 0x02, 0x20, + 0x39, 0x1c, 0xeb, 0xf7, 0x8f, 0xf8, 0xb5, 0xe7, + 0x60, 0xbb, 0x03, 0x20, 0x05, 0x04, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x69, 0x66, + 0x2e, 0x63, 0x3a, 0x20, 0x34, 0x39, 0x35, 0x00, + 0xed, 0x09, 0x00, 0x5e, 0x01, 0xf8, 0xb5, 0x0d, + 0x1c, 0x69, 0x46, 0x01, 0xf0, 0x09, 0xff, 0x07, + 0x1c, 0x00, 0x28, 0x21, 0x4e, 0x05, 0xd1, 0x71, + 0x68, 0x20, 0x4a, 0x02, 0x20, 0x03, 0xf0, 0x5a, + 0xf8, 0x37, 0xe0, 0x78, 0x6b, 0x04, 0x28, 0x05, + 0xd1, 0x71, 0x68, 0x1c, 0x4a, 0x00, 0x20, 0x03, + 0xf0, 0x51, 0xf8, 0x2e, 0xe0, 0xb8, 0x68, 0x00, + 0x28, 0x05, 0xd1, 0x71, 0x68, 0x17, 0x4a, 0x02, + 0x20, 0x03, 0xf0, 0x48, 0xf8, 0x25, 0xe0, 0xea, + 0xf7, 0xf0, 0xff, 0x04, 0x1c, 0x05, 0xd1, 0x71, + 0x68, 0x12, 0x4a, 0x07, 0x20, 0x03, 0xf0, 0x3e, + 0xf8, 0x1b, 0xe0, 0x00, 0x99, 0x03, 0x20, 0x00, + 0x29, 0x03, 0xd0, 0xc9, 0x00, 0xc9, 0x19, 0x48, + 0x61, 0x00, 0xe0, 0x78, 0x63, 0x38, 0x1c, 0x02, + 0xf0, 0x11, 0xf8, 0x70, 0x68, 0x01, 0x38, 0x70, + 0x60, 0x94, 0x20, 0x20, 0x60, 0xb8, 0x68, 0xe0, + 0x60, 0x65, 0x61, 0x00, 0x98, 0x20, 0x61, 0x00, + 0x20, 0xa0, 0x61, 0x02, 0x20, 0x21, 0x1c, 0xeb, + 0xf7, 0x3b, 0xf8, 0xf8, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x60, 0xbb, 0x03, 0x20, 0x06, 0x04, 0x00, + 0x00, 0xb0, 0xb5, 0x04, 0x1c, 0x01, 0xf0, 0x4c, + 0xfe, 0x07, 0x1c, 0x00, 0x28, 0x1b, 0x4d, 0x09, + 0xd1, 0x02, 0x22, 0x85, 0x21, 0xc9, 0x00, 0x23, + 0x1c, 0x68, 0x68, 0x03, 0xf0, 0x44, 0xfa, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x6b, 0x01, + 0x28, 0x07, 0xd0, 0x0b, 0x22, 0x85, 0x21, 0xc9, + 0x00, 0x23, 0x1c, 0x68, 0x68, 0x03, 0xf0, 0x37, + 0xfa, 0xf1, 0xe7, 0xea, 0xf7, 0xa6, 0xff, 0x00, + 0x28, 0x07, 0xd1, 0x07, 0x22, 0x85, 0x21, 0xc9, + 0x00, 0x23, 0x1c, 0x68, 0x68, 0x03, 0xf0, 0x2b, + 0xfa, 0xe5, 0xe7, 0x03, 0x21, 0x79, 0x63, 0x69, + 0x68, 0x01, 0x39, 0x69, 0x60, 0x94, 0x21, 0x01, + 0x60, 0xb9, 0x68, 0xed, 0x09, 0x00, 0x5f, 0x01, + 0xc1, 0x60, 0x02, 0x21, 0x41, 0x61, 0x00, 0x21, + 0x01, 0x61, 0x01, 0x21, 0x81, 0x61, 0x01, 0x1c, + 0x02, 0x20, 0xea, 0xf7, 0xf8, 0xff, 0xd1, 0xe7, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0xf0, 0xb5, + 0xc0, 0x23, 0x0c, 0x1c, 0x19, 0x40, 0x20, 0x4d, + 0x07, 0xd1, 0x69, 0x68, 0x20, 0x4a, 0x11, 0x20, + 0x02, 0xf0, 0xcf, 0xff, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0xf0, 0x1e, 0xfe, 0x07, 0x1c, + 0x05, 0xd1, 0x69, 0x68, 0x1a, 0x4a, 0x02, 0x20, + 0x02, 0xf0, 0xc3, 0xff, 0xf2, 0xe7, 0x01, 0x26, + 0x38, 0x6b, 0x36, 0x03, 0xb0, 0x42, 0x05, 0xd0, + 0x69, 0x68, 0x14, 0x4a, 0x0c, 0x20, 0x02, 0xf0, + 0xb8, 0xff, 0xe7, 0xe7, 0x01, 0xf0, 0xb7, 0xfe, + 0x38, 0x63, 0xb0, 0x42, 0x05, 0xd1, 0x69, 0x68, + 0x0f, 0x4a, 0x0d, 0x20, 0x02, 0xf0, 0xad, 0xff, + 0xdc, 0xe7, 0xea, 0xf7, 0x55, 0xff, 0x00, 0x28, + 0x05, 0xd1, 0x69, 0x68, 0x0a, 0x4a, 0x02, 0x20, + 0x02, 0xf0, 0xa3, 0xff, 0xd2, 0xe7, 0x69, 0x68, + 0x01, 0x39, 0x69, 0x60, 0x95, 0x21, 0x01, 0x60, + 0xb9, 0x68, 0xc1, 0x60, 0x04, 0x61, 0x01, 0x1c, + 0x02, 0x20, 0xea, 0xf7, 0xb0, 0xff, 0xc5, 0xe7, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x07, 0x04, + 0x00, 0x00, 0xf8, 0xb5, 0x05, 0x1c, 0x0e, 0x1c, + 0x01, 0xf0, 0xc1, 0xfd, 0x04, 0x1c, 0x19, 0xd1, + 0x33, 0x48, 0x40, 0x68, 0x01, 0x28, 0x03, 0xd0, + 0x32, 0x48, 0x00, 0x68, 0x00, 0x28, 0x08, 0xd0, + 0x31, 0x48, 0x31, 0x4a, 0x41, 0x68, 0x02, 0x20, + 0x02, 0xf0, 0x7b, 0xff, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x22, 0x00, 0x92, 0x2a, 0x1c, + 0x01, 0x23, 0x02, 0x20, 0x2c, 0x49, 0x02, 0xf0, + 0xec, 0xfd, 0xf3, 0xe7, 0x20, 0x6c, 0x00, 0x28, + 0x0e, 0xd0, 0x24, 0x48, 0x40, 0x68, 0xed, 0x09, + 0x00, 0x60, 0x01, 0x01, 0x28, 0x03, 0xd0, 0x23, + 0x48, 0x00, 0x68, 0x00, 0x28, 0xe8, 0xd0, 0x22, + 0x48, 0x23, 0x4a, 0x41, 0x68, 0x00, 0x20, 0x02, + 0xf0, 0x5e, 0xff, 0xe1, 0xe7, 0xea, 0xf7, 0x06, + 0xff, 0x07, 0x1c, 0x17, 0xd1, 0x1b, 0x48, 0x40, + 0x68, 0x01, 0x28, 0x03, 0xd0, 0x1a, 0x48, 0x00, + 0x68, 0x00, 0x28, 0x06, 0xd0, 0x19, 0x48, 0x19, + 0x4a, 0x41, 0x68, 0x07, 0x20, 0x02, 0xf0, 0x4b, + 0xff, 0xce, 0xe7, 0x00, 0x22, 0x00, 0x92, 0x2a, + 0x1c, 0x01, 0x23, 0x07, 0x20, 0x15, 0x49, 0x02, + 0xf0, 0xbe, 0xfd, 0xc5, 0xe7, 0x20, 0x1c, 0x01, + 0xf0, 0x1e, 0xff, 0x0d, 0x48, 0x40, 0x68, 0x01, + 0x28, 0x03, 0xd0, 0x0c, 0x48, 0x00, 0x68, 0x00, + 0x28, 0x03, 0xd0, 0x0b, 0x48, 0x41, 0x68, 0x01, + 0x39, 0x41, 0x60, 0x01, 0x20, 0xe0, 0x63, 0x92, + 0x20, 0x38, 0x60, 0xfc, 0x60, 0xa0, 0x68, 0x38, + 0x61, 0x00, 0x20, 0x78, 0x61, 0x02, 0x20, 0x39, + 0x1c, 0xbe, 0x61, 0xea, 0xf7, 0x3e, 0xff, 0xa7, + 0xe7, 0x00, 0x00, 0x10, 0x68, 0x03, 0x20, 0xc0, + 0x69, 0x03, 0x20, 0x60, 0xbb, 0x03, 0x20, 0x09, + 0x04, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xf8, + 0xb5, 0x05, 0x1c, 0x0e, 0x1c, 0x01, 0xf0, 0x49, + 0xfd, 0x04, 0x1c, 0x19, 0xd1, 0x40, 0x48, 0x40, + 0x68, 0x01, 0x28, 0x03, 0xd0, 0x3f, 0x48, 0x00, + 0x68, 0x00, 0x28, 0x08, 0xd0, 0x3e, 0x48, 0x3e, + 0x4a, 0x41, 0x68, 0x02, 0x20, 0x02, 0xf0, 0x03, + 0xff, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x22, 0x00, 0x92, 0x2a, 0x1c, 0x01, 0x23, 0x02, + 0x20, 0x39, 0x49, 0x02, 0xf0, 0x74, 0xfd, 0xf3, + 0xe7, 0x00, 0x2e, 0x17, 0xd1, 0x32, 0x48, 0x40, + 0x68, 0x01, 0x28, 0x03, 0xd0, 0x31, 0x48, 0x00, + 0x68, 0x00, 0x28, 0x06, 0xd0, 0x30, 0x48, 0x30, + 0x4a, 0xed, 0x09, 0x00, 0x61, 0x01, 0x41, 0x68, + 0x11, 0x20, 0x02, 0xf0, 0xe7, 0xfe, 0xe2, 0xe7, + 0x00, 0x22, 0x00, 0x92, 0x2a, 0x1c, 0x01, 0x23, + 0x11, 0x20, 0x2c, 0x49, 0x02, 0xf0, 0x5a, 0xfd, + 0xd9, 0xe7, 0x20, 0x6c, 0x00, 0x28, 0x0e, 0xd0, + 0x24, 0x48, 0x40, 0x68, 0x01, 0x28, 0x03, 0xd0, + 0x23, 0x48, 0x00, 0x68, 0x00, 0x28, 0xce, 0xd0, + 0x22, 0x48, 0x23, 0x4a, 0x41, 0x68, 0x00, 0x20, + 0x02, 0xf0, 0xcc, 0xfe, 0xc7, 0xe7, 0xea, 0xf7, + 0x74, 0xfe, 0x07, 0x1c, 0x17, 0xd1, 0x1b, 0x48, + 0x40, 0x68, 0x01, 0x28, 0x03, 0xd0, 0x1a, 0x48, + 0x00, 0x68, 0x00, 0x28, 0x06, 0xd0, 0x19, 0x48, + 0x19, 0x4a, 0x41, 0x68, 0x07, 0x20, 0x02, 0xf0, + 0xb9, 0xfe, 0xb4, 0xe7, 0x00, 0x22, 0x00, 0x92, + 0x2a, 0x1c, 0x01, 0x23, 0x07, 0x20, 0x15, 0x49, + 0x02, 0xf0, 0x2c, 0xfd, 0xab, 0xe7, 0x20, 0x1c, + 0x01, 0xf0, 0x8c, 0xfe, 0x0d, 0x48, 0x40, 0x68, + 0x01, 0x28, 0x03, 0xd0, 0x0c, 0x48, 0x00, 0x68, + 0x00, 0x28, 0x03, 0xd0, 0x0b, 0x48, 0x41, 0x68, + 0x01, 0x39, 0x41, 0x60, 0x00, 0x20, 0xe0, 0x63, + 0x92, 0x20, 0x38, 0x60, 0xfc, 0x60, 0xa0, 0x68, + 0x38, 0x61, 0x7e, 0x61, 0x01, 0x20, 0xb8, 0x61, + 0x02, 0x20, 0x39, 0x1c, 0xea, 0xf7, 0xac, 0xfe, + 0x8d, 0xe7, 0x00, 0x00, 0x10, 0x68, 0x03, 0x20, + 0xc0, 0x69, 0x03, 0x20, 0x60, 0xbb, 0x03, 0x20, + 0x0a, 0x04, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, + 0xf0, 0xb5, 0x04, 0x1c, 0x0e, 0x1c, 0x01, 0xf0, + 0xb7, 0xfc, 0x05, 0x1c, 0x09, 0xd1, 0x19, 0x48, + 0x02, 0x22, 0x23, 0x1c, 0x18, 0x49, 0x40, 0x68, + 0x03, 0xf0, 0xb1, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xea, 0xf7, 0x1e, 0xfe, 0x07, 0x1c, + 0x07, 0xd1, 0x12, 0x48, 0x07, 0x22, 0x23, 0x1c, + 0x11, 0x49, 0x40, 0x68, 0xed, 0x09, 0x00, 0x62, + 0x01, 0x03, 0xf0, 0xa3, 0xf8, 0xf0, 0xe7, 0x10, + 0x48, 0x40, 0x68, 0x01, 0x28, 0x03, 0xd0, 0x0f, + 0x48, 0x00, 0x68, 0x00, 0x28, 0x03, 0xd0, 0x0a, + 0x48, 0x41, 0x68, 0x01, 0x39, 0x41, 0x60, 0x9e, + 0x20, 0x38, 0x60, 0xa8, 0x68, 0x10, 0x22, 0xf8, + 0x60, 0x00, 0x20, 0x38, 0x61, 0xf8, 0x1d, 0x0d, + 0x30, 0x31, 0x1c, 0xea, 0xf7, 0x63, 0xfa, 0x02, + 0x20, 0x39, 0x1c, 0xea, 0xf7, 0x67, 0xfe, 0xd3, + 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x0b, 0x04, 0x00, + 0x00, 0x10, 0x68, 0x03, 0x20, 0xc0, 0x69, 0x03, + 0x20, 0xb0, 0xb5, 0x07, 0x1c, 0x01, 0xf0, 0x76, + 0xfc, 0x04, 0x1c, 0x00, 0x28, 0x15, 0x4d, 0x08, + 0xd1, 0x02, 0x22, 0x3b, 0x1c, 0x68, 0x68, 0x14, + 0x49, 0x03, 0xf0, 0x6f, 0xf8, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xea, 0xf7, 0xdc, 0xfd, 0x00, + 0x28, 0x06, 0xd1, 0x07, 0x22, 0x3b, 0x1c, 0x68, + 0x68, 0x0d, 0x49, 0x03, 0xf0, 0x62, 0xf8, 0xf1, + 0xe7, 0x0c, 0x49, 0x49, 0x68, 0x01, 0x29, 0x03, + 0xd0, 0x0b, 0x49, 0x09, 0x68, 0x00, 0x29, 0x02, + 0xd0, 0x69, 0x68, 0x01, 0x39, 0x69, 0x60, 0x9e, + 0x21, 0x01, 0x60, 0xa1, 0x68, 0xc1, 0x60, 0x1f, + 0x21, 0x01, 0x61, 0x01, 0x1c, 0x02, 0x20, 0xea, + 0xf7, 0x2d, 0xfe, 0xdb, 0xe7, 0x60, 0xbb, 0x03, + 0x20, 0x0c, 0x04, 0x00, 0x00, 0x10, 0x68, 0x03, + 0x20, 0xc0, 0x69, 0x03, 0x20, 0xf7, 0xb5, 0x04, + 0x1c, 0x0e, 0x1c, 0x01, 0xf0, 0x3b, 0xfc, 0x05, + 0x1c, 0x0a, 0xd1, 0x1a, 0x48, 0x02, 0x22, 0x23, + 0x1c, 0x19, 0x49, 0x40, 0x68, 0x03, 0xf0, 0x35, + 0xf8, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xea, 0xf7, 0xa1, 0xfd, 0x07, 0x1c, 0x07, + 0xd1, 0x12, 0x48, 0x07, 0x22, 0x23, 0x1c, 0x12, + 0x49, 0x40, 0x68, 0x03, 0xf0, 0x26, 0xf8, 0xed, + 0x09, 0x00, 0x63, 0x01, 0xef, 0xe7, 0x10, 0x48, + 0x40, 0x68, 0x01, 0x28, 0x03, 0xd0, 0x0f, 0x48, + 0x00, 0x68, 0x00, 0x28, 0x03, 0xd0, 0x0a, 0x48, + 0x41, 0x68, 0x01, 0x39, 0x41, 0x60, 0x9f, 0x20, + 0x38, 0x60, 0xa8, 0x68, 0xf8, 0x60, 0x00, 0x20, + 0x38, 0x61, 0xf8, 0x1d, 0x11, 0x30, 0x7e, 0x61, + 0x02, 0x99, 0x32, 0x1c, 0xea, 0xf7, 0xe5, 0xf9, + 0x02, 0x20, 0x39, 0x1c, 0xea, 0xf7, 0xe9, 0xfd, + 0xd1, 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x0d, 0x04, + 0x00, 0x00, 0x10, 0x68, 0x03, 0x20, 0xc0, 0x69, + 0x03, 0x20, 0xb0, 0xb5, 0x07, 0x1c, 0x01, 0xf0, + 0xf8, 0xfb, 0x04, 0x1c, 0x00, 0x28, 0x15, 0x4d, + 0x08, 0xd1, 0x02, 0x22, 0x3b, 0x1c, 0x68, 0x68, + 0x14, 0x49, 0x02, 0xf0, 0xf1, 0xff, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xea, 0xf7, 0x5e, 0xfd, + 0x00, 0x28, 0x06, 0xd1, 0x07, 0x22, 0x3b, 0x1c, + 0x68, 0x68, 0x0d, 0x49, 0x02, 0xf0, 0xe4, 0xff, + 0xf1, 0xe7, 0x0c, 0x49, 0x49, 0x68, 0x01, 0x29, + 0x03, 0xd0, 0x0b, 0x49, 0x09, 0x68, 0x00, 0x29, + 0x02, 0xd0, 0x69, 0x68, 0x01, 0x39, 0x69, 0x60, + 0x9f, 0x21, 0x01, 0x60, 0xa1, 0x68, 0xc1, 0x60, + 0x18, 0x21, 0x01, 0x61, 0x01, 0x1c, 0x02, 0x20, + 0xea, 0xf7, 0xaf, 0xfd, 0xdb, 0xe7, 0x60, 0xbb, + 0x03, 0x20, 0x0e, 0x04, 0x00, 0x00, 0x10, 0x68, + 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, 0xf0, 0xb5, + 0x2b, 0x4d, 0x07, 0x1c, 0x0d, 0x40, 0x2a, 0x4e, + 0x15, 0xd1, 0x2a, 0x48, 0x40, 0x68, 0x01, 0x28, + 0x03, 0xd0, 0x29, 0x48, 0x00, 0x68, 0x00, 0x28, + 0x07, 0xd0, 0x71, 0x68, 0x28, 0x4a, 0x11, 0x20, + 0x02, 0xf0, 0x79, 0xfd, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x11, 0x20, 0x39, 0x1c, 0x2a, 0x1c, + 0x02, 0xf0, 0x09, 0xff, 0xf6, 0xe7, 0x38, 0x1c, + 0x01, 0xf0, 0xed, 0x09, 0x00, 0x64, 0x01, 0xc1, + 0xfb, 0x04, 0x1c, 0x13, 0xd1, 0x1d, 0x48, 0x40, + 0x68, 0x01, 0x28, 0x03, 0xd0, 0x1c, 0x48, 0x00, + 0x68, 0x00, 0x28, 0x05, 0xd0, 0x71, 0x68, 0x1a, + 0x4a, 0x02, 0x20, 0x02, 0xf0, 0x5e, 0xfd, 0xe3, + 0xe7, 0x02, 0x20, 0x39, 0x1c, 0x2a, 0x1c, 0x02, + 0xf0, 0xf0, 0xfe, 0xdd, 0xe7, 0xea, 0xf7, 0x00, + 0xfd, 0x00, 0x28, 0x13, 0xd1, 0x11, 0x48, 0x40, + 0x68, 0x01, 0x28, 0x03, 0xd0, 0x10, 0x48, 0x00, + 0x68, 0x00, 0x28, 0x05, 0xd0, 0x71, 0x68, 0x0e, + 0x4a, 0x07, 0x20, 0x02, 0xf0, 0x46, 0xfd, 0xcb, + 0xe7, 0x07, 0x20, 0x39, 0x1c, 0x2a, 0x1c, 0x02, + 0xf0, 0xd8, 0xfe, 0xc5, 0xe7, 0xac, 0x21, 0x01, + 0x60, 0xa1, 0x68, 0xc1, 0x60, 0x05, 0x61, 0x01, + 0x1c, 0x02, 0x20, 0xea, 0xf7, 0x50, 0xfd, 0xbb, + 0xe7, 0x00, 0x00, 0x18, 0xcc, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x10, 0x68, 0x03, 0x20, 0xc0, + 0x69, 0x03, 0x20, 0x0f, 0x04, 0x00, 0x00, 0xf0, + 0xb5, 0x07, 0x1c, 0x01, 0xf0, 0x7a, 0xfb, 0x04, + 0x1c, 0x00, 0x28, 0x1f, 0x4e, 0x20, 0x4d, 0x13, + 0xd1, 0x20, 0x49, 0x48, 0x68, 0x01, 0x28, 0x02, + 0xd0, 0x28, 0x68, 0x00, 0x28, 0x07, 0xd0, 0x71, + 0x68, 0x1d, 0x4a, 0x02, 0x20, 0x02, 0xf0, 0x15, + 0xfd, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x02, + 0x20, 0x39, 0x1c, 0x02, 0xf0, 0xf2, 0xfb, 0xf7, + 0xe7, 0xea, 0xf7, 0xb6, 0xfc, 0x00, 0x28, 0x11, + 0xd1, 0x14, 0x49, 0x48, 0x68, 0x01, 0x28, 0x02, + 0xd0, 0x28, 0x68, 0x00, 0x28, 0x05, 0xd0, 0x71, + 0x68, 0x11, 0x4a, 0x07, 0x20, 0x02, 0xf0, 0xfd, + 0xfc, 0xe6, 0xe7, 0x07, 0x20, 0x39, 0x1c, 0x02, + 0xf0, 0xdc, 0xfb, 0xe1, 0xe7, 0x0b, 0x49, 0x49, + 0x68, 0x01, 0x29, 0x02, 0xd0, 0x29, 0x68, 0x00, + 0x29, 0x02, 0xd0, 0x71, 0x68, 0xed, 0x09, 0x00, + 0x65, 0x01, 0x01, 0x39, 0x71, 0x60, 0xb2, 0x21, + 0x01, 0x60, 0xa1, 0x68, 0xc1, 0x60, 0x01, 0x1c, + 0x02, 0x20, 0xea, 0xf7, 0xff, 0xfc, 0xce, 0xe7, + 0x60, 0xbb, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, + 0x10, 0x68, 0x03, 0x20, 0x11, 0x04, 0x00, 0x00, + 0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x01, 0xf0, + 0x2b, 0xfb, 0x05, 0x1c, 0x00, 0x2f, 0x01, 0xd0, + 0x00, 0x26, 0x00, 0xe0, 0x01, 0x26, 0x00, 0x28, + 0x16, 0xd1, 0x23, 0x49, 0x48, 0x68, 0x01, 0x28, + 0x03, 0xd0, 0x22, 0x49, 0x08, 0x68, 0x00, 0x28, + 0x08, 0xd0, 0x21, 0x49, 0x21, 0x4a, 0x02, 0x20, + 0x49, 0x68, 0x02, 0xf0, 0xc1, 0xfc, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x02, 0x20, 0x21, 0x1c, + 0x32, 0x1c, 0x02, 0xf0, 0xde, 0xfb, 0xf6, 0xe7, + 0xea, 0xf7, 0x61, 0xfc, 0x00, 0x28, 0x14, 0xd1, + 0x15, 0x49, 0x48, 0x68, 0x01, 0x28, 0x03, 0xd0, + 0x14, 0x49, 0x08, 0x68, 0x00, 0x28, 0x06, 0xd0, + 0x13, 0x49, 0x14, 0x4a, 0x07, 0x20, 0x49, 0x68, + 0x02, 0xf0, 0xa6, 0xfc, 0xe3, 0xe7, 0x07, 0x20, + 0x21, 0x1c, 0x32, 0x1c, 0x02, 0xf0, 0xc5, 0xfb, + 0xdd, 0xe7, 0x0b, 0x49, 0x49, 0x68, 0x01, 0x29, + 0x03, 0xd0, 0x0a, 0x49, 0x09, 0x68, 0x00, 0x29, + 0x03, 0xd0, 0x09, 0x49, 0x4a, 0x68, 0x01, 0x3a, + 0x4a, 0x60, 0xaf, 0x21, 0x01, 0x60, 0xa9, 0x68, + 0xc1, 0x60, 0x07, 0x61, 0x01, 0x1c, 0x02, 0x20, + 0xea, 0xf7, 0xa4, 0xfc, 0xc7, 0xe7, 0x00, 0x00, + 0x10, 0x68, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, + 0x60, 0xbb, 0x03, 0x20, 0x13, 0x04, 0x00, 0x00, + 0x90, 0xb5, 0x01, 0xf0, 0xd1, 0xfa, 0x07, 0x1c, + 0x00, 0x28, 0x10, 0x4c, 0x07, 0xd1, 0x61, 0x68, + 0x0f, 0x4a, 0x02, 0x20, 0x02, 0xf0, 0x74, 0xfc, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xea, 0xf7, + 0xed, 0x09, 0x00, 0x66, 0x01, 0x1a, 0xfc, 0x00, + 0x28, 0x05, 0xd1, 0x61, 0x68, 0x09, 0x4a, 0x07, + 0x20, 0x02, 0xf0, 0x68, 0xfc, 0xf2, 0xe7, 0x61, + 0x68, 0x01, 0x39, 0x61, 0x60, 0xb1, 0x21, 0x01, + 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x01, 0x1c, 0x02, + 0x20, 0xea, 0xf7, 0x76, 0xfc, 0xe6, 0xe7, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0x15, 0x04, 0x00, + 0x00, 0x00, 0xb5, 0x04, 0x48, 0x04, 0x4a, 0x41, + 0x68, 0x01, 0x20, 0x02, 0xf0, 0x4f, 0xfc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x17, 0x04, 0x00, 0x00, 0xff, 0xb5, 0x14, + 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0xea, 0xf7, 0xed, + 0xfb, 0x07, 0x1c, 0x00, 0x28, 0x11, 0x49, 0x08, + 0xd1, 0x49, 0x68, 0x11, 0x4a, 0x07, 0x20, 0x02, + 0xf0, 0x39, 0xfc, 0x04, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x0c, 0x49, 0x06, 0x22, 0x48, + 0x68, 0x01, 0x38, 0x48, 0x60, 0xa6, 0x20, 0x38, + 0x60, 0xf8, 0x1d, 0x05, 0x30, 0x31, 0x1c, 0xea, + 0xf7, 0x3b, 0xf8, 0xbc, 0x61, 0x7d, 0x61, 0x03, + 0x9b, 0x04, 0x49, 0xfb, 0x61, 0xc8, 0x69, 0x38, + 0x62, 0x02, 0x20, 0x39, 0x1c, 0xea, 0xf7, 0x38, + 0xfc, 0xe3, 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x19, 0x04, 0x00, 0x00, 0x90, 0xb5, 0x01, + 0xf0, 0x69, 0xfa, 0x07, 0x1c, 0x00, 0x28, 0x10, + 0x4c, 0x07, 0xd1, 0x61, 0x68, 0x0f, 0x4a, 0x02, + 0x20, 0x02, 0xf0, 0x0c, 0xfc, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xea, 0xf7, 0xb2, 0xfb, 0x00, + 0x28, 0x05, 0xd1, 0x61, 0x68, 0x09, 0x4a, 0x07, + 0x20, 0x02, 0xf0, 0x00, 0xfc, 0xf2, 0xe7, 0x61, + 0x68, 0x01, 0x39, 0x61, 0x60, 0xa5, 0x21, 0x01, + 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x01, 0x1c, 0x02, + 0x20, 0xea, 0xf7, 0x0e, 0xfc, 0xe6, 0xe7, 0x00, + 0x00, 0x60, 0xbb, 0xed, 0x09, 0x00, 0x67, 0x01, + 0x03, 0x20, 0x1b, 0x04, 0x00, 0x00, 0x90, 0xb5, + 0x01, 0xf0, 0x3f, 0xfa, 0x07, 0x1c, 0x00, 0x28, + 0x10, 0x4c, 0x07, 0xd1, 0x61, 0x68, 0x0f, 0x4a, + 0x02, 0x20, 0x02, 0xf0, 0xe2, 0xfb, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xea, 0xf7, 0x88, 0xfb, + 0x00, 0x28, 0x05, 0xd1, 0x61, 0x68, 0x09, 0x4a, + 0x07, 0x20, 0x02, 0xf0, 0xd6, 0xfb, 0xf2, 0xe7, + 0x61, 0x68, 0x01, 0x39, 0x61, 0x60, 0xa4, 0x21, + 0x01, 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x01, 0x1c, + 0x02, 0x20, 0xea, 0xf7, 0xe4, 0xfb, 0xe6, 0xe7, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x1d, 0x04, + 0x00, 0x00, 0x90, 0xb5, 0x01, 0xf0, 0x15, 0xfa, + 0x07, 0x1c, 0x00, 0x28, 0x10, 0x4c, 0x07, 0xd1, + 0x61, 0x68, 0x0f, 0x4a, 0x02, 0x20, 0x02, 0xf0, + 0xb8, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xea, 0xf7, 0x5e, 0xfb, 0x00, 0x28, 0x05, 0xd1, + 0x61, 0x68, 0x09, 0x4a, 0x07, 0x20, 0x02, 0xf0, + 0xac, 0xfb, 0xf2, 0xe7, 0x61, 0x68, 0x01, 0x39, + 0x61, 0x60, 0xaa, 0x21, 0x01, 0x60, 0xb9, 0x68, + 0xc1, 0x60, 0x01, 0x1c, 0x02, 0x20, 0xea, 0xf7, + 0xba, 0xfb, 0xe6, 0xe7, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x1f, 0x04, 0x00, 0x00, 0x00, 0xb5, + 0x04, 0x48, 0x04, 0x4a, 0x41, 0x68, 0x01, 0x20, + 0x02, 0xf0, 0x93, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x01, 0x08, + 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x04, 0x4a, + 0x41, 0x68, 0x01, 0x20, 0x02, 0xf0, 0x85, 0xfb, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x03, 0x08, 0x00, 0x00, 0x00, 0xb5, + 0x04, 0x48, 0x04, 0x4a, 0x41, 0x68, 0x01, 0x20, + 0x02, 0xf0, 0x77, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0xed, 0x09, + 0x00, 0x68, 0x01, 0x04, 0x08, 0x00, 0x00, 0x00, + 0xb5, 0x04, 0x48, 0x04, 0x4a, 0x41, 0x68, 0x01, + 0x20, 0x02, 0xf0, 0x69, 0xfb, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x05, + 0x08, 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x04, + 0x4a, 0x41, 0x68, 0x01, 0x20, 0x02, 0xf0, 0x5b, + 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x06, 0x08, 0x00, 0x00, 0xff, + 0xb5, 0x0b, 0x9c, 0x0a, 0x9d, 0x09, 0x9e, 0x01, + 0xf0, 0xa2, 0xf9, 0x07, 0x1c, 0x09, 0xd1, 0x14, + 0x49, 0x15, 0x4a, 0x02, 0x20, 0x49, 0x68, 0x02, + 0xf0, 0x46, 0xfb, 0x04, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xea, 0xf7, 0xeb, 0xfa, 0x00, + 0x28, 0x06, 0xd1, 0x0d, 0x49, 0x0e, 0x4a, 0x07, + 0x20, 0x49, 0x68, 0x02, 0xf0, 0x38, 0xfb, 0xf0, + 0xe7, 0x0a, 0x49, 0x4a, 0x68, 0x01, 0x3a, 0x4a, + 0x60, 0xa9, 0x21, 0x01, 0x60, 0xb9, 0x68, 0xc1, + 0x60, 0x02, 0x9a, 0x01, 0x1c, 0x02, 0x61, 0x03, + 0x9b, 0x43, 0x61, 0x86, 0x61, 0x04, 0x62, 0xc5, + 0x61, 0x02, 0x20, 0xea, 0xf7, 0x3e, 0xfb, 0xdc, + 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x07, + 0x08, 0x00, 0x00, 0xb8, 0xb5, 0x04, 0x1c, 0x01, + 0xf0, 0x6e, 0xf9, 0x07, 0x1c, 0x00, 0x28, 0x0f, + 0x4d, 0x04, 0xd0, 0xb8, 0x68, 0x12, 0xf0, 0x7b, + 0xfb, 0x00, 0x28, 0x0a, 0xd1, 0x00, 0x22, 0x00, + 0x92, 0x02, 0x22, 0x23, 0x1c, 0x68, 0x68, 0x0a, + 0x49, 0x02, 0xf0, 0x42, 0xfd, 0xb8, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb8, 0x68, 0x01, 0x22, 0x00, + 0x69, 0x01, 0x28, 0x00, 0xd1, 0x00, 0x22, 0x00, + 0x92, 0x00, 0x22, 0x23, 0x1c, 0x68, 0x68, 0x02, + 0x49, 0x02, 0xf0, 0x32, 0xfd, 0xee, 0xe7, 0x60, + 0xbb, 0x03, 0x20, 0x09, 0x08, 0x00, 0x00, 0xb0, + 0xb5, 0xed, 0x09, 0x00, 0x69, 0x01, 0x0f, 0x1c, + 0x00, 0x29, 0x16, 0x4d, 0x09, 0xd0, 0x01, 0x2f, + 0x07, 0xd0, 0x69, 0x68, 0x14, 0x4a, 0x11, 0x20, + 0x02, 0xf0, 0xe8, 0xfa, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0xf0, 0x19, 0xf9, 0x04, 0x1c, + 0x05, 0xd1, 0x69, 0x68, 0x0e, 0x4a, 0x02, 0x20, + 0x02, 0xf0, 0xdc, 0xfa, 0xf2, 0xe7, 0xea, 0xf7, + 0x84, 0xfa, 0x00, 0x28, 0x05, 0xd1, 0x69, 0x68, + 0x09, 0x4a, 0x07, 0x20, 0x02, 0xf0, 0xd2, 0xfa, + 0xe8, 0xe7, 0x69, 0x68, 0x01, 0x39, 0x69, 0x60, + 0xb4, 0x21, 0x01, 0x60, 0xa1, 0x68, 0xc1, 0x60, + 0x07, 0x61, 0x01, 0x1c, 0x02, 0x20, 0xea, 0xf7, + 0xdf, 0xfa, 0xdb, 0xe7, 0x60, 0xbb, 0x03, 0x20, + 0x0b, 0x08, 0x00, 0x00, 0x88, 0xb5, 0x07, 0x1c, + 0x01, 0xf0, 0x10, 0xf9, 0x0b, 0x49, 0x00, 0x28, + 0x0a, 0xd1, 0x00, 0x22, 0x00, 0x92, 0x48, 0x68, + 0x02, 0x22, 0x3b, 0x1c, 0x08, 0x49, 0x02, 0xf0, + 0xea, 0xfc, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x42, 0x6c, 0x00, 0x92, 0x48, 0x68, 0x00, 0x22, + 0x3b, 0x1c, 0x03, 0x49, 0x02, 0xf0, 0xdf, 0xfc, + 0xf3, 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, + 0x0c, 0x08, 0x00, 0x00, 0xf0, 0xb5, 0x07, 0x1c, + 0x48, 0x08, 0x40, 0x00, 0x0d, 0x1c, 0x00, 0x28, + 0x19, 0x4e, 0x08, 0xd0, 0x11, 0x22, 0x3b, 0x1c, + 0x70, 0x68, 0x18, 0x49, 0x02, 0xf0, 0xcb, 0xfc, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, + 0x01, 0xf0, 0xe0, 0xf8, 0x04, 0x1c, 0x06, 0xd1, + 0x02, 0x22, 0x3b, 0x1c, 0x70, 0x68, 0x11, 0x49, + 0x02, 0xf0, 0xbd, 0xfc, 0xf0, 0xe7, 0xea, 0xf7, + 0x2c, 0xfa, 0x00, 0x28, 0x06, 0xd1, 0x07, 0x22, + 0x3b, 0x1c, 0x70, 0x68, 0x0b, 0x49, 0x02, 0xf0, + 0xb2, 0xfc, 0xe5, 0xe7, 0xb3, 0x21, 0x65, 0x64, + 0x01, 0x60, 0xa1, 0x68, 0xed, 0x09, 0x00, 0x6a, + 0x01, 0xc1, 0x60, 0x05, 0x61, 0x01, 0x1c, 0x02, + 0x20, 0xea, 0xf7, 0x88, 0xfa, 0x00, 0x22, 0x3b, + 0x1c, 0x70, 0x68, 0x03, 0x49, 0x02, 0xf0, 0xa1, + 0xfc, 0xd4, 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x0d, 0x08, 0x00, 0x00, 0x00, 0xb5, 0x82, + 0xb0, 0x01, 0x1c, 0x68, 0x46, 0x08, 0x22, 0xe9, + 0xf7, 0x6d, 0xfe, 0x01, 0x99, 0x00, 0x98, 0x05, + 0x49, 0x00, 0x23, 0x48, 0x65, 0x48, 0x68, 0x04, + 0x49, 0x00, 0x22, 0x02, 0xf0, 0x8a, 0xfc, 0x02, + 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0x01, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0xea, + 0xf7, 0xf2, 0xf9, 0x0b, 0x49, 0x00, 0x28, 0x06, + 0xd1, 0x48, 0x68, 0x0a, 0x49, 0x07, 0x22, 0x02, + 0xf0, 0x78, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x4a, + 0x68, 0x01, 0x3a, 0x4a, 0x60, 0x80, 0x31, 0x01, + 0x22, 0x0a, 0x62, 0xad, 0x21, 0x01, 0x60, 0x01, + 0x1c, 0x02, 0x20, 0xea, 0xf7, 0x4b, 0xfa, 0xf0, + 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x03, 0x0c, 0x00, + 0x00, 0xf0, 0xb5, 0x00, 0x27, 0x00, 0x24, 0x06, + 0x1c, 0x1a, 0x48, 0x07, 0x9b, 0x06, 0x9d, 0x0b, + 0xd0, 0x01, 0x2e, 0x0d, 0xd0, 0x02, 0x2e, 0x23, + 0xd1, 0x00, 0x2a, 0x14, 0xd0, 0x01, 0x2a, 0x01, + 0xd0, 0x02, 0x2a, 0x1b, 0xd1, 0x11, 0x27, 0x1c, + 0xe0, 0x13, 0x49, 0x44, 0x62, 0xc1, 0x62, 0x18, + 0xe0, 0x02, 0x29, 0x06, 0xd1, 0xc1, 0x62, 0x06, + 0x22, 0x29, 0x1c, 0x10, 0x48, 0xe9, 0xf7, 0x1e, + 0xfe, 0x0f, 0xe0, 0x11, 0x27, 0x0d, 0xe0, 0x01, + 0x2b, 0x01, 0xd1, 0x44, 0x62, 0x09, 0xe0, 0x02, + 0x2b, 0x02, 0xd1, 0x01, 0x21, 0x41, 0x62, 0x04, + 0xe0, 0x11, 0x27, 0x02, 0xe0, 0x11, 0x27, 0x00, + 0xe0, 0x11, 0x27, 0x07, 0x48, 0x3a, 0x1c, 0x07, + 0x49, 0x40, 0x68, 0x02, 0xf0, 0x2e, 0xfc, 0xed, + 0x09, 0x00, 0x6b, 0x01, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xe0, 0xbb, 0x03, 0x20, 0xff, 0xff, + 0x00, 0x00, 0x10, 0xbc, 0x03, 0x20, 0x60, 0xbb, + 0x03, 0x20, 0x05, 0x0c, 0x00, 0x00, 0x00, 0xb5, + 0x03, 0x1c, 0x03, 0x48, 0x01, 0x22, 0x03, 0x49, + 0x40, 0x68, 0x02, 0xf0, 0x19, 0xfc, 0x08, 0xbc, + 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0x08, 0x0c, + 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x00, 0x22, + 0xc3, 0x6c, 0x40, 0x68, 0x03, 0x49, 0x02, 0xf0, + 0x0b, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x09, 0x0c, 0x00, 0x00, 0xb0, 0xb5, + 0x04, 0x1c, 0xea, 0xf7, 0x73, 0xf9, 0x07, 0x1c, + 0x00, 0x28, 0x0c, 0x4d, 0x07, 0xd1, 0x07, 0x22, + 0x68, 0x68, 0x0b, 0x49, 0x02, 0xf0, 0xf8, 0xfb, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22, + 0x68, 0x68, 0x07, 0x49, 0x02, 0xf0, 0xf0, 0xfb, + 0xa0, 0x20, 0xec, 0x64, 0x38, 0x60, 0xe8, 0x6c, + 0xf8, 0x60, 0x02, 0x20, 0x39, 0x1c, 0xea, 0xf7, + 0xc8, 0xf9, 0xed, 0xe7, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x0a, 0x0c, 0x00, 0x00, 0x00, 0xb5, + 0x04, 0x48, 0x01, 0x22, 0x04, 0x49, 0x40, 0x68, + 0x02, 0xf0, 0xda, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x0b, 0x0c, + 0x00, 0x00, 0xb0, 0xb5, 0x0c, 0x1c, 0x05, 0x1c, + 0xea, 0xf7, 0x40, 0xf9, 0x07, 0x1c, 0x00, 0x28, + 0x0e, 0x49, 0x08, 0xd1, 0x00, 0x23, 0x48, 0x68, + 0x0d, 0x49, 0x07, 0x22, 0x02, 0xf0, 0xc4, 0xfb, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c, + 0x49, 0x68, 0x06, 0x22, 0x01, 0x39, 0x41, 0x60, + 0xa1, 0x20, 0x38, 0x60, 0xf8, 0x1d, 0x05, 0x30, + 0x29, 0x1c, 0xe9, 0xf7, 0x8e, 0xfd, 0x02, 0x20, + 0x39, 0x1c, 0x7c, 0x61, 0xea, 0xf7, 0x91, 0xf9, + 0xea, 0xe7, 0xed, 0x09, 0x00, 0x6c, 0x01, 0x60, + 0xbb, 0x03, 0x20, 0x0d, 0x0c, 0x00, 0x00, 0xf7, + 0xb5, 0x81, 0xb0, 0x07, 0x1c, 0x0b, 0x28, 0x00, + 0xd9, 0x0b, 0x27, 0x00, 0x2f, 0x07, 0xd1, 0x2d, + 0x48, 0x00, 0x23, 0x11, 0x22, 0x2d, 0x49, 0x40, + 0x68, 0x02, 0xf0, 0x9c, 0xfb, 0x4e, 0xe0, 0xf8, + 0x00, 0x2b, 0xa1, 0x11, 0xf0, 0x90, 0xfb, 0x04, + 0x1c, 0x07, 0xd1, 0x26, 0x48, 0x00, 0x23, 0x07, + 0x22, 0x26, 0x49, 0x40, 0x68, 0x02, 0xf0, 0x8e, + 0xfb, 0x40, 0xe0, 0x38, 0x01, 0x00, 0x90, 0x28, + 0xa1, 0x11, 0xf0, 0x81, 0xfb, 0x06, 0x1c, 0x04, + 0xd1, 0x20, 0x1c, 0x2a, 0xa1, 0x11, 0xf0, 0x81, + 0xfb, 0x34, 0xe0, 0xea, 0xf7, 0xf1, 0xf8, 0x05, + 0x1c, 0x0f, 0xd1, 0x1a, 0x48, 0x00, 0x23, 0x07, + 0x22, 0x1a, 0x49, 0x40, 0x68, 0x02, 0xf0, 0x76, + 0xfb, 0x30, 0x1c, 0x27, 0xa1, 0x11, 0xf0, 0x71, + 0xfb, 0x20, 0x1c, 0x2a, 0xa1, 0x11, 0xf0, 0x6d, + 0xfb, 0x20, 0xe0, 0x12, 0x48, 0x41, 0x68, 0x01, + 0x39, 0x41, 0x60, 0xa2, 0x20, 0x28, 0x60, 0x2c, + 0x61, 0x6e, 0x61, 0x00, 0x26, 0x00, 0x2f, 0xef, + 0x60, 0x0b, 0xd9, 0x06, 0x22, 0x20, 0x1c, 0x02, + 0x99, 0xe9, 0xf7, 0x35, 0xfd, 0x02, 0x99, 0x08, + 0x34, 0x06, 0x31, 0x01, 0x36, 0xbe, 0x42, 0x02, + 0x91, 0xf3, 0xd3, 0x00, 0x9a, 0x68, 0x69, 0x03, + 0x99, 0xe9, 0xf7, 0x29, 0xfd, 0x02, 0x20, 0x29, + 0x1c, 0xea, 0xf7, 0x2d, 0xf9, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x11, 0x0c, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x68, 0x63, 0x69, 0x66, 0x2e, + 0x63, 0x3a, 0x20, 0x31, 0x37, 0x34, 0x37, 0x00, + 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x68, + 0x63, 0x69, 0x66, 0x2e, 0x63, 0x3a, 0x20, 0x31, + 0x37, 0x35, 0x32, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x6d, 0x01, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, + 0x68, 0x63, 0x69, 0x66, 0x2e, 0x63, 0x3a, 0x20, + 0x31, 0x37, 0x35, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x69, 0x66, + 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x37, 0x35, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, + 0x68, 0x63, 0x69, 0x66, 0x2e, 0x63, 0x3a, 0x20, + 0x31, 0x37, 0x36, 0x30, 0x00, 0x00, 0x00, 0x00, + 0xb0, 0xb5, 0x0c, 0x1c, 0x05, 0x1c, 0xea, 0xf7, + 0x7e, 0xf8, 0x07, 0x1c, 0x00, 0x28, 0x0e, 0x49, + 0x08, 0xd1, 0x00, 0x23, 0x48, 0x68, 0x0d, 0x49, + 0x07, 0x22, 0x02, 0xf0, 0x02, 0xfb, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c, 0x49, 0x68, + 0x06, 0x22, 0x01, 0x39, 0x41, 0x60, 0xa3, 0x20, + 0x38, 0x60, 0xf8, 0x1d, 0x05, 0x30, 0x29, 0x1c, + 0xe9, 0xf7, 0xcc, 0xfc, 0x02, 0x20, 0x39, 0x1c, + 0x7c, 0x61, 0xea, 0xf7, 0xcf, 0xf8, 0xea, 0xe7, + 0x60, 0xbb, 0x03, 0x20, 0x12, 0x0c, 0x00, 0x00, + 0x00, 0xb5, 0x12, 0xf0, 0x0b, 0xf9, 0x04, 0x48, + 0x00, 0x22, 0x04, 0x49, 0x40, 0x68, 0x02, 0xf0, + 0xe0, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x13, 0x0c, 0x00, 0x00, + 0x00, 0xb5, 0xbf, 0xb0, 0x68, 0x46, 0x12, 0xf0, + 0xf1, 0xf8, 0x05, 0x48, 0x6b, 0x46, 0x00, 0x22, + 0x04, 0x49, 0x40, 0x68, 0x02, 0xf0, 0xcd, 0xfa, + 0x3f, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x14, 0x0c, 0x00, 0x00, + 0x00, 0xb5, 0x04, 0x48, 0x00, 0x22, 0x83, 0x69, + 0x40, 0x68, 0x03, 0x49, 0x02, 0xf0, 0xbd, 0xfa, + 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, + 0x15, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x0a, 0x4b, + 0x08, 0x49, 0x98, 0x42, 0x06, 0xd9, 0x48, 0x68, + 0xed, 0x09, 0x00, 0x6e, 0x01, 0x08, 0x49, 0x11, + 0x22, 0x02, 0xf0, 0xad, 0xfa, 0x08, 0xbc, 0x18, + 0x47, 0x88, 0x61, 0x48, 0x68, 0x04, 0x49, 0x00, + 0x22, 0x02, 0xf0, 0xa5, 0xfa, 0xf6, 0xe7, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0xff, 0xff, 0x00, + 0x00, 0x16, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x04, + 0x48, 0x00, 0x22, 0xc3, 0x69, 0x40, 0x68, 0x03, + 0x49, 0x02, 0xf0, 0x95, 0xfa, 0x08, 0xbc, 0x18, + 0x47, 0x60, 0xbb, 0x03, 0x20, 0x17, 0x0c, 0x00, + 0x00, 0x00, 0xb5, 0x08, 0x49, 0x00, 0x28, 0x07, + 0xd0, 0xc8, 0x61, 0x48, 0x68, 0x06, 0x49, 0x00, + 0x22, 0x02, 0xf0, 0x85, 0xfa, 0x08, 0xbc, 0x18, + 0x47, 0x48, 0x68, 0x03, 0x49, 0x11, 0x22, 0x02, + 0xf0, 0x7e, 0xfa, 0xf7, 0xe7, 0x60, 0xbb, 0x03, + 0x20, 0x18, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x04, + 0x48, 0x00, 0x22, 0x83, 0x68, 0x40, 0x68, 0x03, + 0x49, 0x02, 0xf0, 0x71, 0xfa, 0x08, 0xbc, 0x18, + 0x47, 0x60, 0xbb, 0x03, 0x20, 0x19, 0x0c, 0x00, + 0x00, 0x90, 0xb5, 0x07, 0x1c, 0x00, 0x28, 0x17, + 0x4c, 0x0d, 0xd0, 0x01, 0x2f, 0x0b, 0xd0, 0x02, + 0x2f, 0x09, 0xd0, 0x03, 0x2f, 0x07, 0xd0, 0x11, + 0x22, 0x60, 0x68, 0x13, 0x49, 0x02, 0xf0, 0x5b, + 0xfa, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe9, + 0xf7, 0xc8, 0xff, 0x00, 0x28, 0x05, 0xd1, 0x11, + 0x22, 0x60, 0x68, 0x0d, 0x49, 0x02, 0xf0, 0x4f, + 0xfa, 0xf2, 0xe7, 0x61, 0x68, 0x01, 0x39, 0x61, + 0x60, 0x8c, 0x21, 0x01, 0x60, 0xe7, 0x60, 0xc7, + 0x60, 0x21, 0x6a, 0x81, 0x61, 0x61, 0x6a, 0xc1, + 0x61, 0xa1, 0x6a, 0x01, 0x61, 0xe1, 0x6a, 0x41, + 0x61, 0x01, 0x1c, 0x02, 0x20, 0xea, 0xf7, 0x1c, + 0xf8, 0xde, 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x1a, 0x0c, 0x00, 0x00, 0x08, 0xb5, 0x06, + 0x48, 0x06, 0x49, 0xed, 0x09, 0x00, 0x6f, 0x01, + 0xc2, 0x6a, 0x00, 0x92, 0x83, 0x6a, 0x40, 0x68, + 0x00, 0x22, 0x02, 0xf0, 0x2b, 0xfa, 0x01, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x1b, 0x0c, 0x00, 0x00, 0xb0, 0xb5, + 0x04, 0x1c, 0x0f, 0x1c, 0x88, 0x42, 0x11, 0x4d, + 0x07, 0xd2, 0x11, 0x22, 0x68, 0x68, 0x10, 0x49, + 0x02, 0xf0, 0x18, 0xfa, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xe9, 0xf7, 0x85, 0xff, 0x00, 0x28, + 0x05, 0xd1, 0x07, 0x22, 0x68, 0x68, 0x0a, 0x49, + 0x02, 0xf0, 0x0c, 0xfa, 0xf2, 0xe7, 0xac, 0x62, + 0xef, 0x62, 0x8e, 0x21, 0x01, 0x60, 0xc4, 0x60, + 0x07, 0x61, 0x01, 0x1c, 0x03, 0x20, 0xe9, 0xf7, + 0xe2, 0xff, 0x00, 0x22, 0x68, 0x68, 0x02, 0x49, + 0x02, 0xf0, 0xfc, 0xf9, 0xe2, 0xe7, 0x60, 0xbb, + 0x03, 0x20, 0x1c, 0x0c, 0x00, 0x00, 0x08, 0xb5, + 0x06, 0x48, 0x06, 0x49, 0x42, 0x6a, 0x00, 0x92, + 0x03, 0x6a, 0x40, 0x68, 0x00, 0x22, 0x02, 0xf0, + 0xed, 0xf9, 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x1d, 0x0c, + 0x00, 0x00, 0xb0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, + 0x88, 0x42, 0x11, 0x4d, 0x07, 0xd2, 0x11, 0x22, + 0x68, 0x68, 0x10, 0x49, 0x02, 0xf0, 0xda, 0xf9, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe9, 0xf7, + 0x47, 0xff, 0x00, 0x28, 0x05, 0xd1, 0x07, 0x22, + 0x68, 0x68, 0x0a, 0x49, 0x02, 0xf0, 0xce, 0xf9, + 0xf2, 0xe7, 0x2c, 0x62, 0x6f, 0x62, 0x8d, 0x21, + 0x01, 0x60, 0xc4, 0x60, 0x07, 0x61, 0x01, 0x1c, + 0x03, 0x20, 0xe9, 0xf7, 0xa4, 0xff, 0x00, 0x22, + 0x68, 0x68, 0x02, 0x49, 0x02, 0xf0, 0xbe, 0xf9, + 0xe2, 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x1e, 0x0c, + 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x00, 0x22, + 0x03, 0x6b, 0x40, 0x68, 0x03, 0x49, 0xed, 0x09, + 0x00, 0x70, 0x01, 0x02, 0xf0, 0xb1, 0xf9, 0x08, + 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0x1f, + 0x0c, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, 0x00, + 0x28, 0x13, 0x4c, 0x0a, 0xd0, 0x01, 0x2f, 0x08, + 0xd0, 0x11, 0x22, 0x61, 0x21, 0x49, 0x01, 0x60, + 0x68, 0x02, 0xf0, 0x9e, 0xf9, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xe9, 0xf7, 0x0b, 0xff, 0x00, + 0x28, 0x06, 0xd1, 0x07, 0x22, 0x61, 0x21, 0x49, + 0x01, 0x60, 0x68, 0x02, 0xf0, 0x91, 0xf9, 0xf1, + 0xe7, 0x97, 0x21, 0x27, 0x63, 0x01, 0x60, 0xc7, + 0x60, 0x01, 0x1c, 0x02, 0x20, 0xe9, 0xf7, 0x69, + 0xff, 0x00, 0x22, 0x61, 0x21, 0x49, 0x01, 0x60, + 0x68, 0x02, 0xf0, 0x82, 0xf9, 0xe2, 0xe7, 0x60, + 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x04, 0x48, 0x00, + 0x22, 0x43, 0x6b, 0x40, 0x68, 0x03, 0x49, 0x02, + 0xf0, 0x77, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x21, 0x0c, 0x00, 0x00, 0x90, + 0xb5, 0x07, 0x1c, 0x00, 0x28, 0x13, 0x4c, 0x0b, + 0xd0, 0x01, 0x2f, 0x09, 0xd0, 0x02, 0x2f, 0x07, + 0xd0, 0x11, 0x22, 0x60, 0x68, 0x10, 0x49, 0x02, + 0xf0, 0x63, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xe9, 0xf7, 0xd0, 0xfe, 0x00, 0x28, 0x05, + 0xd1, 0x07, 0x22, 0x60, 0x68, 0x0a, 0x49, 0x02, + 0xf0, 0x57, 0xf9, 0xf2, 0xe7, 0x98, 0x21, 0x67, + 0x63, 0x01, 0x60, 0xc7, 0x60, 0x01, 0x1c, 0x02, + 0x20, 0xe9, 0xf7, 0x2f, 0xff, 0x00, 0x22, 0x60, + 0x68, 0x03, 0x49, 0x02, 0xf0, 0x49, 0xf9, 0xe4, + 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x22, + 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x00, + 0x22, 0x83, 0x6b, 0x40, 0x68, 0x03, 0x49, 0x02, + 0xf0, 0x3b, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x23, 0x0c, 0x00, 0x00, 0x90, + 0xb5, 0xed, 0x09, 0x00, 0x71, 0x01, 0x0e, 0x4c, + 0x07, 0x1c, 0xa0, 0x63, 0xe9, 0xf7, 0xa1, 0xfe, + 0x00, 0x28, 0x07, 0xd1, 0x07, 0x22, 0x60, 0x68, + 0x0a, 0x49, 0x02, 0xf0, 0x28, 0xf9, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x9d, 0x21, 0x01, 0x60, + 0xc7, 0x60, 0x01, 0x1c, 0x04, 0x20, 0xe9, 0xf7, + 0xff, 0xfe, 0x00, 0x22, 0x60, 0x68, 0x03, 0x49, + 0x02, 0xf0, 0x19, 0xf9, 0xef, 0xe7, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x24, 0x0c, 0x00, 0x00, + 0x00, 0xb5, 0x05, 0x48, 0xc1, 0x1d, 0x79, 0x31, + 0xcb, 0x69, 0x40, 0x68, 0x03, 0x49, 0x00, 0x22, + 0x02, 0xf0, 0x09, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x60, 0xbb, 0x03, 0x20, 0x25, 0x0c, 0x00, 0x00, + 0xb0, 0xb5, 0x85, 0x07, 0xad, 0x0f, 0x07, 0x1c, + 0x03, 0x2d, 0x18, 0x4c, 0x07, 0xd1, 0x11, 0x22, + 0x60, 0x68, 0x17, 0x49, 0x02, 0xf0, 0xf7, 0xf8, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe9, 0xf7, + 0x64, 0xfe, 0x00, 0x28, 0x05, 0xd1, 0x07, 0x22, + 0x60, 0x68, 0x11, 0x49, 0x02, 0xf0, 0xeb, 0xf8, + 0xf2, 0xe7, 0xe1, 0x1d, 0x79, 0x31, 0xcf, 0x61, + 0x8b, 0x21, 0x01, 0x60, 0x00, 0x2d, 0x0f, 0xd0, + 0x01, 0x2d, 0x10, 0xd0, 0x02, 0x2d, 0x01, 0xd1, + 0x01, 0x21, 0xc1, 0x60, 0x01, 0x1c, 0x02, 0x20, + 0xe9, 0xf7, 0xba, 0xfe, 0x00, 0x22, 0x60, 0x68, + 0x05, 0x49, 0x02, 0xf0, 0xd4, 0xf8, 0xdb, 0xe7, + 0x02, 0x21, 0xc1, 0x60, 0xf2, 0xe7, 0x00, 0x21, + 0xc1, 0x60, 0xef, 0xe7, 0x60, 0xbb, 0x03, 0x20, + 0x26, 0x0c, 0x00, 0x00, 0x08, 0xb5, 0x00, 0x22, + 0x03, 0x1c, 0x05, 0x48, 0x00, 0x92, 0x40, 0x68, + 0x01, 0x22, 0x04, 0x49, 0x02, 0xf0, 0xbf, 0xf8, + 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x27, 0x0c, 0x00, 0x00, + 0x00, 0xb5, 0x03, 0x1c, 0xed, 0x09, 0x00, 0x72, + 0x01, 0x03, 0x48, 0x01, 0x22, 0x03, 0x49, 0x40, + 0x68, 0x02, 0xf0, 0xaf, 0xf8, 0x08, 0xbc, 0x18, + 0x47, 0x60, 0xbb, 0x03, 0x20, 0x28, 0x0c, 0x00, + 0x00, 0x00, 0xb5, 0x04, 0x48, 0x00, 0x23, 0x01, + 0x22, 0x03, 0x49, 0x40, 0x68, 0x02, 0xf0, 0xa1, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0x29, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x04, + 0x48, 0x01, 0x22, 0x04, 0x49, 0x40, 0x68, 0x02, + 0xf0, 0x94, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0x2a, 0x0c, 0x00, + 0x00, 0x00, 0xb5, 0x04, 0x48, 0x00, 0x23, 0x01, + 0x22, 0x03, 0x49, 0x40, 0x68, 0x02, 0xf0, 0x85, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0x2b, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x04, + 0x48, 0x01, 0x22, 0x04, 0x49, 0x40, 0x68, 0x02, + 0xf0, 0x78, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0x2c, 0x0c, 0x00, + 0x00, 0x08, 0xb5, 0x00, 0x22, 0x03, 0x1c, 0x05, + 0x48, 0x00, 0x92, 0x40, 0x68, 0x01, 0x22, 0x04, + 0x49, 0x02, 0xf0, 0x67, 0xf8, 0x01, 0xb0, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x2d, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x04, + 0x48, 0x00, 0x23, 0x01, 0x22, 0x03, 0x49, 0x40, + 0x68, 0x02, 0xf0, 0x57, 0xf8, 0x08, 0xbc, 0x18, + 0x47, 0x60, 0xbb, 0x03, 0x20, 0x2e, 0x0c, 0x00, + 0x00, 0x00, 0xb5, 0x04, 0x48, 0x01, 0x22, 0x04, + 0x49, 0x40, 0x68, 0x02, 0xf0, 0x4a, 0xf8, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x2f, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x08, + 0x49, 0x00, 0x28, 0x06, 0xd1, 0x48, 0x68, 0x07, + 0x49, 0x00, 0x22, 0x02, 0xf0, 0x3a, 0xf8, 0x08, + 0xbc, 0x18, 0x47, 0x48, 0x68, 0x03, 0x49, 0xed, + 0x09, 0x00, 0x73, 0x01, 0x11, 0x22, 0x02, 0xf0, + 0x33, 0xf8, 0xf7, 0xe7, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x31, 0x0c, 0x00, 0x00, 0xf0, 0xb5, + 0x1c, 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0x17, 0x1c, + 0x0d, 0x4a, 0x10, 0x6d, 0x00, 0xf0, 0xb4, 0xfb, + 0x00, 0x28, 0x05, 0xd0, 0x0a, 0x4a, 0xd0, 0x6e, + 0x51, 0x6e, 0x38, 0x1a, 0x08, 0x18, 0x50, 0x66, + 0x07, 0x4a, 0x07, 0x49, 0xd0, 0x1d, 0x79, 0x30, + 0x96, 0x66, 0x85, 0x60, 0xd7, 0x66, 0xc4, 0x60, + 0x50, 0x68, 0x00, 0x22, 0x02, 0xf0, 0x10, 0xf8, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x33, 0x0c, 0x00, 0x00, 0xf0, 0xb5, + 0x05, 0x1c, 0x0d, 0x48, 0x0c, 0x1c, 0x17, 0x1c, + 0x00, 0x6d, 0x00, 0xf0, 0x91, 0xfb, 0x00, 0x28, + 0x0f, 0xd0, 0x00, 0x26, 0x00, 0x2d, 0x0c, 0xd9, + 0x20, 0x68, 0x00, 0xf0, 0xf4, 0xfb, 0x00, 0x28, + 0x02, 0xd0, 0x38, 0x68, 0x00, 0xf0, 0x8c, 0xfb, + 0x04, 0x34, 0x01, 0x36, 0x04, 0x37, 0xae, 0x42, + 0xf2, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0xb8, 0xb5, + 0x04, 0x1c, 0x00, 0xf0, 0x00, 0xfc, 0x07, 0x1c, + 0x00, 0x28, 0x11, 0x4d, 0x0a, 0xd1, 0x00, 0x22, + 0x00, 0x92, 0x02, 0x22, 0x23, 0x1c, 0x68, 0x68, + 0x0f, 0x49, 0x01, 0xf0, 0xd9, 0xff, 0xb8, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xe9, 0xf7, 0x46, 0xfd, + 0x00, 0x28, 0x05, 0xd1, 0x07, 0x22, 0x68, 0x68, + 0x09, 0x49, 0x01, 0xf0, 0xcd, 0xff, 0xf2, 0xe7, + 0x69, 0x68, 0x01, 0x39, 0x69, 0x60, 0x99, 0x21, + 0x01, 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x01, 0x1c, + 0x02, 0x20, 0xe9, 0xf7, 0xa2, 0xfd, 0xe6, 0xe7, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x36, 0x0c, + 0x00, 0x00, 0xf0, 0xb5, 0x0d, 0x1c, 0x07, 0x1c, + 0x00, 0xf0, 0xed, 0x09, 0x00, 0x74, 0x01, 0xd1, + 0xfb, 0x04, 0x1c, 0x00, 0x28, 0x13, 0x4e, 0x08, + 0xd1, 0x02, 0x22, 0x3b, 0x1c, 0x70, 0x68, 0x11, + 0x49, 0x01, 0xf0, 0xac, 0xff, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xe9, 0xf7, 0x19, 0xfd, 0x00, + 0x28, 0x06, 0xd1, 0x07, 0x22, 0x3b, 0x1c, 0x70, + 0x68, 0x0b, 0x49, 0x01, 0xf0, 0x9f, 0xff, 0xf1, + 0xe7, 0x9a, 0x21, 0x01, 0x60, 0xa1, 0x68, 0xc1, + 0x60, 0x05, 0x61, 0x01, 0x1c, 0x02, 0x20, 0xe9, + 0xf7, 0x76, 0xfd, 0x00, 0x22, 0x3b, 0x1c, 0x70, + 0x68, 0x03, 0x49, 0x01, 0xf0, 0x8f, 0xff, 0xe1, + 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x37, + 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x01, + 0x23, 0x00, 0x22, 0x03, 0x49, 0x40, 0x68, 0x01, + 0xf0, 0x81, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x38, 0x0c, 0x00, 0x00, 0x08, + 0xb5, 0xe9, 0xf7, 0xea, 0xfc, 0x0c, 0x49, 0x00, + 0x28, 0x0a, 0xd1, 0x00, 0x22, 0x00, 0x92, 0x48, + 0x68, 0x00, 0x23, 0x07, 0x22, 0x09, 0x49, 0x01, + 0xf0, 0x6d, 0xff, 0x01, 0xb0, 0x08, 0xbc, 0x18, + 0x47, 0x4a, 0x68, 0x01, 0x3a, 0x4a, 0x60, 0xa7, + 0x21, 0x01, 0x60, 0x01, 0x1c, 0x03, 0x20, 0xe9, + 0xf7, 0x42, 0xfd, 0xf2, 0xe7, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x39, 0x0c, 0x00, 0x00, 0xf0, + 0xb5, 0x04, 0x1c, 0x0d, 0x1c, 0x00, 0x28, 0x14, + 0x4e, 0x07, 0xd1, 0x11, 0x22, 0x70, 0x68, 0x13, + 0x49, 0x01, 0xf0, 0x50, 0xff, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xe9, 0xf7, 0xbd, 0xfc, 0x07, + 0x1c, 0x05, 0xd1, 0x07, 0x22, 0x70, 0x68, 0x0d, + 0x49, 0x01, 0xf0, 0x44, 0xff, 0xf2, 0xe7, 0x01, + 0x2c, 0x00, 0xd9, 0x01, 0x24, 0xa8, 0x20, 0x38, + 0x60, 0xa2, 0x00, 0xf8, 0x1d, 0x09, 0x30, 0x29, + 0x1c, 0xfc, 0x60, 0xe9, 0xf7, 0xed, 0x09, 0x00, + 0x75, 0x01, 0x10, 0xf9, 0x03, 0x20, 0x39, 0x1c, + 0xe9, 0xf7, 0x14, 0xfd, 0x00, 0x22, 0x70, 0x68, + 0x02, 0x49, 0x01, 0xf0, 0x2e, 0xff, 0xdc, 0xe7, + 0x60, 0xbb, 0x03, 0x20, 0x3a, 0x0c, 0x00, 0x00, + 0x00, 0xb5, 0x04, 0x48, 0x00, 0x22, 0x03, 0x69, + 0x40, 0x68, 0x03, 0x49, 0x01, 0xf0, 0x21, 0xff, + 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, + 0x3b, 0x0c, 0x00, 0x00, 0x90, 0xb5, 0x0e, 0x4c, + 0x07, 0x1c, 0x20, 0x61, 0xe9, 0xf7, 0x87, 0xfc, + 0x00, 0x28, 0x07, 0xd1, 0x07, 0x22, 0x60, 0x68, + 0x0a, 0x49, 0x01, 0xf0, 0x0e, 0xff, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x9b, 0x21, 0x01, 0x60, + 0xc7, 0x60, 0x01, 0x1c, 0x03, 0x20, 0xe9, 0xf7, + 0xe5, 0xfc, 0x00, 0x22, 0x60, 0x68, 0x03, 0x49, + 0x01, 0xf0, 0xff, 0xfe, 0xef, 0xe7, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x3c, 0x0c, 0x00, 0x00, + 0x00, 0xb5, 0x04, 0x48, 0x00, 0x22, 0x43, 0x69, + 0x40, 0x68, 0x03, 0x49, 0x01, 0xf0, 0xf1, 0xfe, + 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, + 0x3d, 0x0c, 0x00, 0x00, 0x90, 0xb5, 0x0e, 0x4c, + 0x07, 0x1c, 0x60, 0x61, 0xe9, 0xf7, 0x57, 0xfc, + 0x00, 0x28, 0x07, 0xd1, 0x07, 0x22, 0x60, 0x68, + 0x0a, 0x49, 0x01, 0xf0, 0xde, 0xfe, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x9c, 0x21, 0x01, 0x60, + 0xc7, 0x60, 0x01, 0x1c, 0x03, 0x20, 0xe9, 0xf7, + 0xb5, 0xfc, 0x00, 0x22, 0x60, 0x68, 0x03, 0x49, + 0x01, 0xf0, 0xcf, 0xfe, 0xef, 0xe7, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x3e, 0x0c, 0x00, 0x00, + 0x80, 0xb5, 0x87, 0xb0, 0x1a, 0x48, 0x1b, 0xa1, + 0x0e, 0xf0, 0x5a, 0xfc, 0x00, 0x23, 0x0d, 0x30, + 0xc1, 0x56, 0x8b, 0x00, 0x59, 0x18, 0x49, 0x00, + 0x01, 0x23, 0xc2, 0x56, 0x89, 0x18, 0xff, 0x39, + 0xed, 0x09, 0x00, 0x76, 0x01, 0xff, 0x39, 0x12, + 0x39, 0x0a, 0x02, 0x03, 0x23, 0xc1, 0x56, 0x8b, + 0x00, 0x59, 0x18, 0x49, 0x00, 0x04, 0x23, 0xc0, + 0x56, 0x08, 0x18, 0xff, 0x38, 0xff, 0x38, 0x12, + 0x38, 0x02, 0x43, 0x17, 0x1c, 0x05, 0xaa, 0x06, + 0xa8, 0x04, 0xa9, 0x11, 0xf0, 0xa6, 0xfc, 0x06, + 0x98, 0x04, 0x99, 0x05, 0x9a, 0x01, 0x90, 0x0b, + 0x48, 0x02, 0x91, 0x03, 0x92, 0x00, 0x97, 0x01, + 0x23, 0x00, 0x22, 0x40, 0x68, 0x08, 0x49, 0x01, + 0xf0, 0x96, 0xfe, 0x07, 0xb0, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xc4, 0x5d, 0x03, + 0x20, 0x24, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x01, 0x10, 0x00, 0x00, 0x00, 0xb5, 0x82, + 0xb0, 0x68, 0x46, 0x11, 0xf0, 0x97, 0xfc, 0x05, + 0x48, 0x6b, 0x46, 0x00, 0x22, 0x04, 0x49, 0x40, + 0x68, 0x01, 0xf0, 0x79, 0xfe, 0x02, 0xb0, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x03, 0x10, 0x00, 0x00, 0x80, 0xb5, 0x83, + 0xb0, 0x09, 0x4f, 0xf8, 0x1d, 0x79, 0x30, 0x42, + 0x69, 0x79, 0x6f, 0x00, 0x69, 0x02, 0x92, 0x01, + 0x91, 0x00, 0x90, 0x78, 0x68, 0x3b, 0x6f, 0x05, + 0x49, 0x00, 0x22, 0x01, 0xf0, 0x60, 0xfe, 0x03, + 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0x05, 0x10, 0x00, + 0x00, 0x00, 0xb5, 0x10, 0xf0, 0xe9, 0xfe, 0x03, + 0x1c, 0x03, 0x48, 0x00, 0x22, 0x03, 0x49, 0x40, + 0x68, 0x01, 0xf0, 0x4d, 0xfe, 0x08, 0xbc, 0x18, + 0x47, 0x60, 0xbb, 0x03, 0x20, 0x07, 0x10, 0x00, + 0x00, 0x00, 0xb5, 0x82, 0xb0, 0x68, 0x46, 0x10, + 0xf0, 0xd1, 0xfe, 0x05, 0x48, 0x6b, 0x46, 0x00, + 0x22, 0x04, 0x49, 0x40, 0x68, 0x01, 0xf0, 0x3b, + 0xfe, 0x02, 0xb0, 0xed, 0x09, 0x00, 0x77, 0x01, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x09, 0x10, 0x00, 0x00, 0x08, 0xb5, + 0x00, 0x22, 0x03, 0x1c, 0x05, 0x48, 0x00, 0x92, + 0x40, 0x68, 0x01, 0x22, 0x04, 0x49, 0x01, 0xf0, + 0x29, 0xfe, 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x01, 0x14, + 0x00, 0x00, 0x00, 0xb5, 0x03, 0x1c, 0x03, 0x48, + 0x01, 0x22, 0x03, 0x49, 0x40, 0x68, 0x01, 0xf0, + 0x19, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x02, 0x14, 0x00, 0x00, 0x08, 0xb5, + 0x00, 0x22, 0x03, 0x1c, 0x05, 0x48, 0x00, 0x92, + 0x40, 0x68, 0x01, 0x22, 0x04, 0x49, 0x01, 0xf0, + 0x09, 0xfe, 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x03, 0x14, + 0x00, 0x00, 0xb8, 0xb5, 0x07, 0x1c, 0x00, 0xf0, + 0x18, 0xfa, 0x04, 0x1c, 0x00, 0x28, 0x12, 0x4d, + 0x0a, 0xd1, 0x00, 0x22, 0x00, 0x92, 0x02, 0x22, + 0x3b, 0x1c, 0x68, 0x68, 0x10, 0x49, 0x01, 0xf0, + 0xf1, 0xfd, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xe9, 0xf7, 0x5e, 0xfb, 0x00, 0x28, 0x08, 0xd1, + 0x00, 0x22, 0x00, 0x92, 0x07, 0x22, 0x3b, 0x1c, + 0x68, 0x68, 0x08, 0x49, 0x01, 0xf0, 0xe2, 0xfd, + 0xef, 0xe7, 0x69, 0x68, 0x01, 0x39, 0x69, 0x60, + 0xab, 0x21, 0x01, 0x60, 0xa1, 0x68, 0xc1, 0x60, + 0x01, 0x1c, 0x02, 0x20, 0xe9, 0xf7, 0xb7, 0xfb, + 0xe3, 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x05, 0x14, + 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x00, 0x23, + 0x01, 0x22, 0x03, 0x49, 0x40, 0x68, 0x01, 0xf0, + 0xc9, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x01, 0x18, 0x00, 0x00, 0x00, 0xb5, + 0x04, 0x48, 0x01, 0x22, 0x04, 0x49, 0x40, 0x68, + 0x01, 0xf0, 0xbc, 0xfd, 0x08, 0xbc, 0xed, 0x09, + 0x00, 0x78, 0x01, 0x18, 0x47, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x02, 0x18, 0x00, 0x00, 0x80, + 0xb5, 0xe9, 0xf7, 0x24, 0xfb, 0x0b, 0x4f, 0x00, + 0x28, 0x07, 0xd1, 0x07, 0x22, 0x78, 0x68, 0x09, + 0x49, 0x01, 0xf0, 0xaa, 0xfd, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb5, 0x21, 0x01, 0x60, 0x01, + 0x1c, 0x02, 0x20, 0xe9, 0xf7, 0x82, 0xfb, 0x00, + 0x22, 0x78, 0x68, 0x02, 0x49, 0x01, 0xf0, 0x9c, + 0xfd, 0xf0, 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x03, + 0x18, 0x00, 0x00, 0x90, 0xb5, 0x89, 0xb0, 0x01, + 0x90, 0x00, 0xf0, 0xad, 0xf9, 0x07, 0x1c, 0x00, + 0x28, 0x14, 0x4c, 0x08, 0xd1, 0x01, 0xaa, 0x00, + 0x92, 0x20, 0x23, 0x02, 0x22, 0x60, 0x68, 0x11, + 0x49, 0x01, 0xf0, 0x86, 0xfd, 0x19, 0xe0, 0xe9, + 0xf7, 0xf5, 0xfa, 0x00, 0x28, 0x08, 0xd1, 0x01, + 0xaa, 0x00, 0x92, 0x20, 0x23, 0x07, 0x22, 0x60, + 0x68, 0x0b, 0x49, 0x01, 0xf0, 0x79, 0xfd, 0x0c, + 0xe0, 0x61, 0x68, 0x01, 0x39, 0x61, 0x60, 0xb6, + 0x21, 0x01, 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x00, + 0x21, 0x01, 0x61, 0x01, 0x1c, 0x02, 0x20, 0xe9, + 0xf7, 0x4c, 0xfb, 0x09, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0x01, + 0xfc, 0x00, 0x00, 0x90, 0xb5, 0x89, 0xb0, 0x01, + 0x90, 0x00, 0xf0, 0x79, 0xf9, 0x07, 0x1c, 0x00, + 0x28, 0x14, 0x4c, 0x08, 0xd1, 0x01, 0xaa, 0x00, + 0x92, 0x20, 0x23, 0x02, 0x22, 0x60, 0x68, 0x11, + 0x49, 0x01, 0xf0, 0x52, 0xfd, 0x19, 0xe0, 0xe9, + 0xf7, 0xc1, 0xfa, 0x00, 0x28, 0x08, 0xd1, 0x01, + 0xaa, 0x00, 0x92, 0x20, 0x23, 0x07, 0x22, 0x60, + 0x68, 0x0b, 0x49, 0x01, 0xf0, 0x45, 0xfd, 0x0c, + 0xe0, 0x61, 0x68, 0x01, 0x39, 0x61, 0x60, 0xb6, + 0x21, 0x01, 0x60, 0xb9, 0x68, 0xc1, 0x60, 0x01, + 0x21, 0xed, 0x09, 0x00, 0x79, 0x01, 0x01, 0x61, + 0x01, 0x1c, 0x02, 0x20, 0xe9, 0xf7, 0x18, 0xfb, + 0x09, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x60, 0xbb, 0x03, 0x20, 0x12, 0xfc, 0x00, 0x00, + 0xff, 0xb5, 0x81, 0xb0, 0x01, 0x20, 0x00, 0x90, + 0x18, 0x68, 0x0d, 0x1c, 0x14, 0x21, 0x08, 0x1a, + 0x99, 0x69, 0x40, 0x18, 0x19, 0x6a, 0x46, 0x18, + 0x01, 0x98, 0x1f, 0x1c, 0x00, 0xf0, 0x3a, 0xf9, + 0x04, 0x1c, 0x08, 0xd1, 0x6a, 0x46, 0x01, 0x20, + 0x01, 0xa9, 0x01, 0xf0, 0x47, 0xfb, 0x38, 0x1c, + 0x10, 0xf0, 0x48, 0xff, 0x54, 0xe0, 0x60, 0x6b, + 0x02, 0x28, 0x08, 0xd0, 0x6a, 0x46, 0x01, 0x20, + 0x01, 0xa9, 0x01, 0xf0, 0x3b, 0xfb, 0x38, 0x1c, + 0x10, 0xf0, 0x3c, 0xff, 0x48, 0xe0, 0x02, 0x2d, + 0x0a, 0xd0, 0x01, 0x2d, 0x08, 0xd0, 0x6a, 0x46, + 0x01, 0x20, 0x01, 0xa9, 0x01, 0xf0, 0x2e, 0xfb, + 0x38, 0x1c, 0x10, 0xf0, 0x2f, 0xff, 0x3b, 0xe0, + 0x1f, 0x48, 0x00, 0x6f, 0xb0, 0x42, 0x0b, 0xd2, + 0x01, 0x20, 0x01, 0xf0, 0x06, 0xfc, 0x6a, 0x46, + 0x01, 0x20, 0x01, 0xa9, 0x01, 0xf0, 0x1e, 0xfb, + 0x38, 0x1c, 0x10, 0xf0, 0x1f, 0xff, 0x2b, 0xe0, + 0x20, 0x1c, 0x02, 0xf0, 0x95, 0xf9, 0x00, 0x28, + 0x0b, 0xd0, 0x01, 0x20, 0x01, 0xf0, 0xf5, 0xfb, + 0x6a, 0x46, 0x01, 0x20, 0x01, 0xa9, 0x01, 0xf0, + 0x0d, 0xfb, 0x38, 0x1c, 0x10, 0xf0, 0x0e, 0xff, + 0x1a, 0xe0, 0xe9, 0xf7, 0x4a, 0xfa, 0x00, 0x28, + 0x09, 0xd1, 0x20, 0x1c, 0x39, 0x1c, 0x02, 0xf0, + 0x92, 0xf9, 0x6a, 0x46, 0x01, 0x20, 0x01, 0xa9, + 0x01, 0xf0, 0xfc, 0xfa, 0x0c, 0xe0, 0x93, 0x21, + 0x01, 0x60, 0xa1, 0x68, 0xc1, 0x60, 0x07, 0x61, + 0x45, 0x61, 0x03, 0x9a, 0x01, 0x1c, 0x82, 0x61, + 0xc7, 0x61, 0x02, 0x20, 0xe9, 0xf7, 0xa0, 0xfa, + 0x05, 0xb0, 0xf0, 0xbc, 0xed, 0x09, 0x00, 0x7a, + 0x01, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0x98, 0xb5, 0x0f, 0x1c, 0x69, 0x46, 0x00, + 0xf0, 0xf1, 0xf8, 0x04, 0x1c, 0x03, 0xd1, 0x38, + 0x1c, 0x10, 0xf0, 0xe2, 0xfe, 0x19, 0xe0, 0x60, + 0x6b, 0x02, 0x28, 0x03, 0xd0, 0x38, 0x1c, 0x10, + 0xf0, 0xdb, 0xfe, 0x12, 0xe0, 0xe9, 0xf7, 0x17, + 0xfa, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x1c, 0x10, + 0xf0, 0xd3, 0xfe, 0x0a, 0xe0, 0x87, 0x21, 0x01, + 0x60, 0xa1, 0x68, 0x09, 0x6b, 0x89, 0x68, 0xc1, + 0x60, 0x47, 0x61, 0x01, 0x1c, 0x04, 0x20, 0xe9, + 0xf7, 0x75, 0xfa, 0x98, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x04, 0x48, 0x81, 0x69, 0x01, + 0x31, 0x81, 0x61, 0xff, 0xf7, 0x07, 0xf8, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe0, 0xbb, 0x03, + 0x20, 0x00, 0x22, 0x4a, 0x65, 0x42, 0x68, 0x00, + 0x2a, 0x02, 0xd0, 0x51, 0x65, 0x41, 0x60, 0x70, + 0x47, 0x41, 0x60, 0x01, 0x60, 0x70, 0x47, 0x01, + 0x1c, 0x00, 0x68, 0x00, 0x28, 0x04, 0xd0, 0x42, + 0x6d, 0x0a, 0x60, 0x00, 0x2a, 0x00, 0xd1, 0x4a, + 0x60, 0x70, 0x47, 0x01, 0x21, 0x01, 0x28, 0x02, + 0xd0, 0x03, 0x28, 0x00, 0xd0, 0x00, 0x21, 0x08, + 0x1c, 0x70, 0x47, 0x02, 0x49, 0x4a, 0x6e, 0x10, + 0x18, 0x48, 0x66, 0x70, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0xf0, 0xb5, 0x84, 0xb0, 0x25, 0x48, 0x00, + 0x22, 0x01, 0x92, 0x03, 0x90, 0x35, 0xe0, 0xbe, + 0x6d, 0xf0, 0x6d, 0x02, 0x90, 0xb0, 0x69, 0x39, + 0x6e, 0x45, 0x1a, 0x1c, 0xe0, 0x20, 0x48, 0x87, + 0x6e, 0xaf, 0x42, 0x00, 0xd3, 0x2f, 0x1c, 0x00, + 0x97, 0x1d, 0x48, 0xf1, 0x69, 0x00, 0x6e, 0xed, + 0x1b, 0x0b, 0x18, 0x01, 0x21, 0x00, 0x28, 0x00, + 0xd1, 0x71, 0x69, 0x02, 0x98, 0x40, 0x69, 0x01, + 0x9a, 0x02, 0xf0, 0xdc, 0xf9, 0x16, 0x49, 0xed, + 0x09, 0x00, 0x7b, 0x01, 0x08, 0x6e, 0xc0, 0x19, + 0x08, 0x66, 0x00, 0x2c, 0x02, 0xd0, 0x48, 0x6e, + 0x01, 0x38, 0x48, 0x66, 0x00, 0x2d, 0x06, 0xd0, + 0x00, 0x2c, 0xde, 0xd0, 0x10, 0x48, 0x40, 0x6e, + 0x00, 0x28, 0xda, 0xdc, 0x08, 0xe0, 0x0d, 0x4f, + 0x00, 0x20, 0x38, 0x66, 0x03, 0x98, 0xff, 0xf7, + 0xad, 0xff, 0x0b, 0xa1, 0x10, 0xf0, 0x28, 0xfc, + 0x09, 0x4f, 0xb8, 0x6d, 0x00, 0x28, 0x07, 0xd0, + 0x38, 0x6d, 0xff, 0xf7, 0xad, 0xff, 0x04, 0x1c, + 0xc0, 0xd0, 0x78, 0x6e, 0x00, 0x28, 0xbd, 0xdc, + 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xb8, 0xbb, 0x03, 0x20, 0x60, 0xbb, + 0x03, 0x20, 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x35, 0x30, 0x33, 0x00, 0x00, 0x01, 0x20, + 0x70, 0x47, 0x90, 0xb4, 0x01, 0x1c, 0x0c, 0x48, + 0xc0, 0x6b, 0x00, 0x28, 0x12, 0xd0, 0x0b, 0x68, + 0x1f, 0x02, 0x3f, 0x0a, 0xc2, 0x68, 0x14, 0x02, + 0x24, 0x0a, 0xbc, 0x42, 0x07, 0xd1, 0x12, 0x0e, + 0x1c, 0x0e, 0xa2, 0x42, 0x03, 0xd1, 0x02, 0x8a, + 0x8c, 0x88, 0xa2, 0x42, 0x02, 0xd0, 0x00, 0x68, + 0x00, 0x28, 0xef, 0xd1, 0x90, 0xbc, 0x70, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x01, 0x1c, + 0x07, 0x48, 0x00, 0x6c, 0x00, 0x28, 0x08, 0xd0, + 0x06, 0x4a, 0x43, 0x69, 0x8b, 0x42, 0x04, 0xd0, + 0x91, 0x42, 0x02, 0xd0, 0x40, 0x68, 0x00, 0x28, + 0xf7, 0xd1, 0x70, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0xff, 0x0f, 0x00, 0x00, 0x01, 0x1c, + 0x05, 0x48, 0xc0, 0x6b, 0x00, 0x28, 0x05, 0xd0, + 0x42, 0x69, 0x8a, 0x42, 0x02, 0xd0, 0x00, 0x68, + 0x00, 0x28, 0xf9, 0xd1, 0x70, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x16, 0x4a, 0xd2, 0x6b, 0x00, 0x2a, + 0x26, 0xd0, 0xed, 0x09, 0x00, 0x7c, 0x01, 0x53, + 0x69, 0x83, 0x42, 0x02, 0xd0, 0x13, 0x6b, 0x83, + 0x42, 0x02, 0xd1, 0x00, 0x20, 0x08, 0x60, 0x1d, + 0xe0, 0xd3, 0x69, 0x00, 0x2b, 0x05, 0xd0, 0x93, + 0x69, 0x83, 0x42, 0x02, 0xd1, 0x01, 0x20, 0x08, + 0x60, 0x14, 0xe0, 0x53, 0x6a, 0x00, 0x2b, 0x05, + 0xd0, 0x13, 0x6a, 0x83, 0x42, 0x02, 0xd1, 0x02, + 0x20, 0x08, 0x60, 0x0b, 0xe0, 0xd3, 0x6a, 0x00, + 0x2b, 0x05, 0xd0, 0x93, 0x6a, 0x83, 0x42, 0x02, + 0xd1, 0x03, 0x20, 0x08, 0x60, 0x02, 0xe0, 0x12, + 0x68, 0x00, 0x2a, 0xd8, 0xd1, 0x10, 0x1c, 0x70, + 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x80, + 0xb4, 0x1a, 0x4a, 0x12, 0x6c, 0x00, 0x2a, 0x2c, + 0xd0, 0x19, 0x4f, 0xd3, 0x69, 0x00, 0x2b, 0x07, + 0xd0, 0x93, 0x69, 0x83, 0x42, 0x01, 0xd0, 0xb8, + 0x42, 0x02, 0xd1, 0x01, 0x20, 0x08, 0x60, 0x20, + 0xe0, 0x53, 0x6a, 0x00, 0x2b, 0x07, 0xd0, 0x13, + 0x6a, 0x83, 0x42, 0x01, 0xd0, 0xb8, 0x42, 0x02, + 0xd1, 0x02, 0x20, 0x08, 0x60, 0x15, 0xe0, 0xd3, + 0x6a, 0x00, 0x2b, 0x07, 0xd0, 0x93, 0x6a, 0x83, + 0x42, 0x01, 0xd0, 0xb8, 0x42, 0x02, 0xd1, 0x03, + 0x20, 0x08, 0x60, 0x0a, 0xe0, 0x53, 0x69, 0x83, + 0x42, 0x01, 0xd0, 0xb8, 0x42, 0x02, 0xd1, 0x00, + 0x20, 0x08, 0x60, 0x02, 0xe0, 0x52, 0x68, 0x00, + 0x2a, 0xd3, 0xd1, 0x80, 0xbc, 0x10, 0x1c, 0x70, + 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0xff, + 0x0f, 0x00, 0x00, 0xc3, 0x69, 0x01, 0x22, 0x02, + 0x2b, 0x03, 0xd1, 0x80, 0x69, 0x08, 0x60, 0x10, + 0x1c, 0x70, 0x47, 0x43, 0x6a, 0x02, 0x2b, 0x03, + 0xd1, 0x00, 0x6a, 0x08, 0x60, 0x10, 0x1c, 0x70, + 0x47, 0xc3, 0x6a, 0x02, 0x2b, 0x03, 0xd1, 0x80, + 0x6a, 0x08, 0x60, 0x10, 0x1c, 0x70, 0x47, 0x00, + 0x20, 0x70, 0x47, 0x00, 0x28, 0xed, 0x09, 0x00, + 0x7d, 0x01, 0x03, 0xd0, 0xc1, 0x6c, 0x02, 0x4b, + 0x99, 0x42, 0x00, 0xd0, 0x00, 0x20, 0x70, 0x47, + 0x19, 0x64, 0x11, 0x03, 0xf8, 0xb5, 0x0c, 0x4d, + 0x0c, 0x4e, 0x00, 0x24, 0xa8, 0x6c, 0x0b, 0x4f, + 0x41, 0x1c, 0xa9, 0x64, 0x07, 0x40, 0x69, 0x46, + 0x38, 0x1c, 0xff, 0xf7, 0x67, 0xff, 0x00, 0x28, + 0x03, 0xd1, 0x38, 0x1c, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0x34, 0xb4, 0x42, 0xed, 0xd3, + 0x01, 0x20, 0x00, 0x03, 0xf6, 0xe7, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0xff, 0x0e, 0x00, 0x00, + 0x43, 0x68, 0x00, 0x22, 0x00, 0x2b, 0x03, 0xd0, + 0x19, 0x60, 0x43, 0x68, 0x4b, 0x60, 0x01, 0xe0, + 0x01, 0x60, 0x4a, 0x60, 0x0a, 0x60, 0x41, 0x60, + 0x81, 0x68, 0x01, 0x31, 0x81, 0x60, 0x70, 0x47, + 0x0a, 0x68, 0x00, 0x2a, 0x02, 0xd0, 0x4b, 0x68, + 0x53, 0x60, 0x01, 0xe0, 0x4a, 0x68, 0x42, 0x60, + 0x4a, 0x68, 0x00, 0x2a, 0x02, 0xd0, 0x09, 0x68, + 0x11, 0x60, 0x01, 0xe0, 0x09, 0x68, 0x01, 0x60, + 0x81, 0x68, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x39, + 0x81, 0x60, 0x70, 0x47, 0x90, 0xb5, 0x04, 0x1c, + 0x50, 0x20, 0x10, 0xf0, 0xe7, 0xfa, 0x07, 0x1c, + 0x12, 0xd0, 0x0b, 0x48, 0xf8, 0x64, 0xff, 0xf7, + 0xb1, 0xff, 0x78, 0x61, 0x0c, 0xcc, 0xf8, 0x1d, + 0x05, 0x30, 0x0c, 0xc0, 0x00, 0x20, 0xb8, 0x60, + 0x78, 0x63, 0x01, 0x20, 0x00, 0x03, 0x38, 0x63, + 0x04, 0x48, 0x39, 0x1c, 0xff, 0xf7, 0xc0, 0xff, + 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x19, 0x64, 0x11, 0x03, 0x9c, 0xbb, 0x03, 0x20, + 0x90, 0xb5, 0x14, 0x1c, 0x07, 0x1c, 0x00, 0x29, + 0x0b, 0xd0, 0xe9, 0xf7, 0x3c, 0xf8, 0x00, 0x28, + 0x07, 0xd0, 0xae, 0x21, 0x01, 0x60, 0xb9, 0x68, + 0xc1, 0x60, 0x01, 0x1c, 0x02, 0x20, 0xe9, 0xf7, + 0xed, 0x09, 0x00, 0x7e, 0x01, 0xa1, 0xf8, 0x38, + 0x1c, 0x00, 0xf0, 0x64, 0xf8, 0x06, 0x48, 0x39, + 0x1c, 0xff, 0xf7, 0xb0, 0xff, 0x00, 0x20, 0xf8, + 0x64, 0x38, 0x1c, 0x21, 0x1c, 0x10, 0xf0, 0xb2, + 0xfa, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x9c, 0xbb, 0x03, 0x20, 0x80, 0xb5, 0x07, + 0x48, 0xc0, 0x6b, 0x00, 0x28, 0x06, 0xd0, 0x07, + 0x68, 0x05, 0xa2, 0x00, 0x21, 0xff, 0xf7, 0xd2, + 0xff, 0x38, 0x1c, 0xf8, 0xd1, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x37, 0x37, 0x35, 0x00, 0x00, 0xb0, 0xb5, 0x0c, + 0x1c, 0x15, 0x1c, 0x07, 0x1c, 0xff, 0xf7, 0x54, + 0xff, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x42, 0x0b, + 0xd0, 0x61, 0x1e, 0xc9, 0x00, 0xc9, 0x19, 0xca, + 0x69, 0x00, 0x2a, 0x05, 0xd1, 0x88, 0x61, 0xcd, + 0x61, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x20, 0xfa, 0xe7, 0x90, 0xb5, 0xff, + 0xf7, 0xa5, 0xfe, 0x07, 0x1c, 0x17, 0xd0, 0xb8, + 0x6c, 0x00, 0x28, 0x14, 0xd0, 0x00, 0x24, 0xbc, + 0x64, 0xe8, 0xf7, 0xdf, 0xff, 0x00, 0x28, 0x0e, + 0xd0, 0x01, 0x21, 0x39, 0x64, 0xfc, 0x63, 0x92, + 0x22, 0x02, 0x60, 0xc7, 0x60, 0xba, 0x68, 0x02, + 0x61, 0x81, 0x61, 0x10, 0x22, 0x42, 0x61, 0x01, + 0x1c, 0x02, 0x20, 0xe9, 0xf7, 0x3d, 0xf8, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, + 0x1c, 0x80, 0x6c, 0x00, 0x28, 0x04, 0xd0, 0x04, + 0xa1, 0xfd, 0xf7, 0x5c, 0xfd, 0x00, 0x20, 0xb8, + 0x64, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x38, 0x34, 0x32, 0xed, 0x09, 0x00, 0x7f, 0x01, + 0x00, 0x00, 0x80, 0xb5, 0x82, 0xb0, 0x07, 0x1c, + 0x80, 0x6c, 0x00, 0x28, 0x02, 0xd0, 0x0b, 0xa1, + 0xfd, 0xf7, 0x43, 0xfd, 0x0f, 0x48, 0x00, 0x21, + 0x0f, 0x4a, 0x80, 0x69, 0xe8, 0xf7, 0x57, 0xfd, + 0x7a, 0x69, 0x0b, 0x1c, 0x0d, 0x49, 0x01, 0x92, + 0x00, 0x91, 0x19, 0x1c, 0x00, 0x23, 0x01, 0x22, + 0xfd, 0xf7, 0x1c, 0xfd, 0xb8, 0x64, 0x02, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, + 0x63, 0x5c, 0x68, 0x63, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x38, 0x35, 0x34, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0xe2, 0x04, + 0x00, 0x00, 0x7d, 0x7b, 0x01, 0x20, 0x08, 0xb5, + 0x07, 0x4a, 0x01, 0x1c, 0x50, 0x68, 0x01, 0x30, + 0x50, 0x60, 0x4a, 0x69, 0x00, 0x92, 0xca, 0x68, + 0x0b, 0x69, 0x03, 0x49, 0x01, 0xf0, 0x06, 0xfa, + 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x0d, 0x0c, 0x00, 0x00, 0x00, 0xb5, + 0x06, 0x4a, 0x01, 0x1c, 0x50, 0x68, 0x01, 0x30, + 0x50, 0x60, 0xca, 0x68, 0x0b, 0x69, 0x03, 0x49, + 0x01, 0xf0, 0xf4, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x11, 0x0c, + 0x00, 0x00, 0x00, 0xb5, 0x06, 0x4a, 0x01, 0x1c, + 0x50, 0x68, 0x01, 0x30, 0x50, 0x60, 0xca, 0x68, + 0x0b, 0x69, 0x03, 0x49, 0x01, 0xf0, 0xe2, 0xf9, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x12, 0x0c, 0x00, 0x00, 0x90, 0xb5, + 0x91, 0xb0, 0x07, 0x1c, 0x13, 0x48, 0x40, 0x6d, + 0x40, 0x0d, 0x1e, 0xd3, 0xf8, 0x68, 0x00, 0x24, + 0x00, 0x28, 0x0d, 0xd9, 0x38, 0x69, 0xe1, 0x00, + 0x41, 0x18, 0x60, 0x00, 0x00, 0x19, 0x40, 0x00, + 0x68, 0x44, 0x06, 0x22, 0xe8, 0xf7, 0x9f, 0xfb, + 0xf8, 0x68, 0x01, 0x34, 0xa0, 0x42, 0xed, 0x09, + 0x00, 0x80, 0x01, 0xf1, 0xd8, 0xf8, 0x68, 0x7a, + 0x69, 0x69, 0x46, 0x01, 0xf0, 0x3d, 0xf8, 0x38, + 0x69, 0x06, 0xa1, 0x10, 0xf0, 0xb8, 0xf9, 0x78, + 0x69, 0x09, 0xa1, 0x10, 0xf0, 0xb4, 0xf9, 0x11, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x73, 0x72, 0x63, 0x5c, 0x68, + 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, + 0x3a, 0x20, 0x39, 0x32, 0x32, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, 0x6e, 0x74, + 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x39, 0x32, + 0x33, 0x00, 0x00, 0x00, 0xb5, 0x06, 0x49, 0x49, + 0x6d, 0x09, 0x0e, 0x06, 0xd3, 0xc1, 0x1d, 0x02, + 0x6a, 0xc0, 0x68, 0x09, 0x31, 0x0c, 0x30, 0x01, + 0xf0, 0x7a, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x04, 0x49, 0x49, + 0x6d, 0xc9, 0x0d, 0x02, 0xd3, 0x0c, 0x30, 0x01, + 0xf0, 0x52, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x04, 0x49, 0x49, + 0x6d, 0x89, 0x0d, 0x02, 0xd3, 0x0c, 0x30, 0x01, + 0xf0, 0x2a, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x06, 0x49, 0x49, + 0x6d, 0x89, 0x0a, 0x05, 0xd3, 0x01, 0x69, 0x42, + 0x69, 0x49, 0x69, 0xc0, 0x68, 0x00, 0xf0, 0x8a, + 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x05, 0x49, 0x49, + 0x6d, 0x49, 0x0a, 0x04, 0xd3, 0x01, 0x69, 0x49, + 0x69, 0xc0, 0x68, 0x00, 0xf0, 0x61, 0xfe, 0x08, + 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0x00, + 0xb5, 0x05, 0x49, 0x49, 0x6d, 0x89, 0x09, 0x04, + 0xd3, 0x01, 0x69, 0x49, 0x69, 0xc0, 0x68, 0x00, + 0xf0, 0xf6, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x90, 0xb5, 0xc4, 0x68, 0x2a, + 0x4b, 0xed, 0x09, 0x00, 0x81, 0x01, 0x27, 0x4f, + 0x27, 0x4a, 0x28, 0x49, 0x9c, 0x42, 0x2d, 0xd0, + 0x02, 0x33, 0x9c, 0x42, 0x03, 0xd0, 0x27, 0x4b, + 0x9c, 0x42, 0x3a, 0xd1, 0x13, 0xe0, 0x53, 0x68, + 0x01, 0x2b, 0x10, 0xd0, 0x0b, 0x68, 0x00, 0x2b, + 0x0d, 0xd1, 0x02, 0x69, 0x00, 0x2a, 0x07, 0xd0, + 0x40, 0x69, 0x39, 0x1c, 0x00, 0x28, 0x00, 0xd0, + 0x41, 0x69, 0x10, 0x1c, 0x00, 0xf0, 0xd2, 0xfd, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x52, 0x68, + 0x01, 0x2a, 0x22, 0xd0, 0x09, 0x68, 0x00, 0x29, + 0x1f, 0xd1, 0x02, 0x69, 0x00, 0x2a, 0xf3, 0xd0, + 0x40, 0x69, 0x39, 0x1c, 0x00, 0x28, 0x00, 0xd0, + 0x41, 0x69, 0x10, 0x1c, 0x00, 0x22, 0x00, 0xf0, + 0xfe, 0xfd, 0xe9, 0xe7, 0x52, 0x68, 0x01, 0x2a, + 0x0f, 0xd0, 0x09, 0x68, 0x00, 0x29, 0x0c, 0xd1, + 0x02, 0x69, 0x00, 0x2a, 0xe0, 0xd0, 0x40, 0x69, + 0x39, 0x1c, 0x00, 0x28, 0x00, 0xd0, 0x41, 0x69, + 0x10, 0x1c, 0x00, 0x22, 0x01, 0xf0, 0x5e, 0xf8, + 0xd6, 0xe7, 0x09, 0x4a, 0x51, 0x68, 0x01, 0x31, + 0x51, 0x60, 0xc2, 0x68, 0x00, 0x69, 0x00, 0xf0, + 0xbd, 0xfe, 0xcd, 0xe7, 0xff, 0x0f, 0x00, 0x00, + 0x24, 0x68, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, + 0x0f, 0x04, 0x00, 0x00, 0x13, 0x04, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x80, 0xb5, 0x01, 0x1c, + 0x16, 0x48, 0xca, 0x1d, 0x43, 0x68, 0x0d, 0x32, + 0x01, 0x2b, 0x15, 0x48, 0x03, 0xd0, 0x15, 0x4b, + 0x1b, 0x68, 0x00, 0x2b, 0x0b, 0xd0, 0x43, 0x68, + 0x01, 0x33, 0x43, 0x60, 0x18, 0x1c, 0x13, 0x1c, + 0x0a, 0x69, 0xc9, 0x68, 0x01, 0xf0, 0xd3, 0xf8, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xcf, 0x68, + 0x0d, 0x4b, 0x9f, 0x42, 0xf8, 0xd0, 0x01, 0x33, + 0x9f, 0x42, 0xf5, 0xd0, 0x0b, 0x4b, 0x9f, 0x42, + 0xf2, 0xd0, 0x01, 0x33, 0xed, 0x09, 0x00, 0x82, + 0x01, 0x9f, 0x42, 0xef, 0xd0, 0x43, 0x68, 0x01, + 0x33, 0x43, 0x60, 0x18, 0x1c, 0x13, 0x1c, 0x0a, + 0x69, 0xc9, 0x68, 0x01, 0xf0, 0xba, 0xf8, 0xe5, + 0xe7, 0x24, 0x68, 0x03, 0x20, 0x60, 0xbb, 0x03, + 0x20, 0xc0, 0x69, 0x03, 0x20, 0x0b, 0x04, 0x00, + 0x00, 0x0d, 0x04, 0x00, 0x00, 0x00, 0xb5, 0x09, + 0x49, 0x4a, 0x68, 0x53, 0x1c, 0x4b, 0x60, 0xc2, + 0x68, 0x00, 0x2a, 0x02, 0xd0, 0xca, 0x68, 0x00, + 0x2a, 0x01, 0xd1, 0xca, 0x68, 0x8a, 0x60, 0xc2, + 0x68, 0x18, 0x1c, 0x03, 0x49, 0x01, 0xf0, 0x9d, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0x1a, 0x0c, 0x00, 0x00, 0x90, 0xb5, 0x86, + 0xb0, 0x07, 0x1c, 0x15, 0x48, 0x41, 0x6d, 0x89, + 0x08, 0x21, 0xd3, 0xc1, 0x1d, 0x79, 0x31, 0xc9, + 0x6a, 0xfc, 0x1d, 0x05, 0x34, 0x02, 0x29, 0x06, + 0xd1, 0x06, 0x22, 0xb0, 0x30, 0x21, 0x1c, 0x0d, + 0xf0, 0x41, 0xfe, 0x00, 0x28, 0x13, 0xd1, 0xf8, + 0x69, 0xfa, 0x1d, 0x05, 0x90, 0x78, 0x69, 0x19, + 0x32, 0x04, 0x90, 0xb8, 0x69, 0xf9, 0x1d, 0x03, + 0x90, 0x05, 0xa8, 0x00, 0x90, 0x1d, 0x31, 0x01, + 0x91, 0x01, 0x20, 0x02, 0x92, 0x04, 0xaa, 0x21, + 0x1c, 0x03, 0xab, 0x00, 0xf0, 0x4c, 0xfc, 0x06, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x05, + 0x4a, 0x51, 0x68, 0x01, 0x31, 0x51, 0x60, 0xc0, + 0x68, 0x03, 0x4a, 0x00, 0xf0, 0x25, 0xfe, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, + 0x20, 0x01, 0x04, 0x00, 0x00, 0x00, 0xb5, 0x05, + 0x4a, 0x01, 0x1c, 0x50, 0x68, 0x01, 0x30, 0x50, + 0x60, 0xca, 0x68, 0x03, 0x49, 0x01, 0xf0, 0x4d, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0xb5, 0xed, + 0x09, 0x00, 0x83, 0x01, 0x04, 0x49, 0x49, 0x6d, + 0x49, 0x08, 0x02, 0xd3, 0xc0, 0x68, 0x00, 0xf0, + 0x08, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0xb0, 0xb5, 0x17, 0x4d, 0x07, 0x1c, + 0x68, 0x68, 0x01, 0x30, 0x68, 0x60, 0xf8, 0x68, + 0xff, 0xf7, 0xf1, 0xfc, 0x00, 0x28, 0x1b, 0xd0, + 0xbc, 0x69, 0x00, 0x2c, 0x05, 0xd1, 0x79, 0x69, + 0x00, 0x29, 0x10, 0xd1, 0x39, 0x69, 0x81, 0x60, + 0x0a, 0xe0, 0x79, 0x69, 0x00, 0x29, 0x03, 0xd0, + 0x01, 0x21, 0x09, 0x03, 0x01, 0x63, 0x03, 0xe0, + 0x0b, 0xa2, 0x00, 0x21, 0xff, 0xf7, 0x4b, 0xfd, + 0x78, 0x69, 0x00, 0x28, 0x07, 0xd0, 0x69, 0x68, + 0x20, 0x1c, 0x0b, 0x4a, 0x00, 0xf0, 0xdb, 0xfd, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x69, 0x68, + 0x20, 0x1c, 0x08, 0x4a, 0x00, 0xf0, 0xd3, 0xfd, + 0xf6, 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x73, 0x72, + 0x63, 0x5c, 0x68, 0x63, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x31, 0x39, + 0x32, 0x00, 0x07, 0x04, 0x00, 0x00, 0x05, 0x04, + 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x1c, 0xc5, 0x69, + 0x10, 0x30, 0x00, 0x2d, 0x2f, 0xd0, 0xff, 0xf7, + 0xf0, 0xfb, 0x00, 0x28, 0x28, 0xd0, 0x01, 0x22, + 0x29, 0x1c, 0xff, 0xf7, 0x5c, 0xfd, 0x07, 0x1c, + 0x22, 0xd0, 0x1e, 0x4e, 0xf0, 0x1d, 0x79, 0x30, + 0x40, 0x6a, 0x00, 0x28, 0x27, 0xd0, 0xe8, 0xf7, + 0x55, 0xfd, 0x00, 0x28, 0x18, 0xd0, 0x1a, 0x49, + 0x49, 0x68, 0x01, 0x29, 0x03, 0xd0, 0x19, 0x49, + 0x09, 0x68, 0x00, 0x29, 0x02, 0xd0, 0x71, 0x68, + 0x01, 0x39, 0x71, 0x60, 0x01, 0x22, 0xfa, 0x63, + 0x92, 0x21, 0x01, 0x60, 0xc7, 0x60, 0xb9, 0x68, + 0x01, 0x61, 0x00, 0x21, 0x41, 0x61, 0x82, 0x61, + 0x01, 0x1c, 0x02, 0x20, 0xe8, 0xf7, 0xa9, 0xfd, + 0xf0, 0xbc, 0xed, 0x09, 0x00, 0x84, 0x01, 0x08, + 0xbc, 0x18, 0x47, 0x0e, 0xa1, 0xff, 0xf7, 0xcf, + 0xfc, 0x07, 0x1c, 0xf7, 0xd0, 0xe0, 0x68, 0xb8, + 0x60, 0xd1, 0xe7, 0x38, 0x1c, 0xff, 0xf7, 0x79, + 0xfd, 0x70, 0x6d, 0x00, 0x09, 0xee, 0xd3, 0x01, + 0x22, 0x00, 0x2d, 0x00, 0xd0, 0x00, 0x22, 0xf8, + 0x1d, 0x05, 0x30, 0xa1, 0x69, 0x00, 0xf0, 0x19, + 0xfc, 0xe4, 0xe7, 0x60, 0xbb, 0x03, 0x20, 0x24, + 0x68, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, 0x73, + 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, 0x6e, 0x74, + 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x32, + 0x32, 0x30, 0x00, 0x98, 0xb5, 0x07, 0x1c, 0xc0, + 0x68, 0xff, 0xf7, 0x57, 0xfc, 0x00, 0x28, 0x10, + 0xd0, 0x04, 0x6c, 0x25, 0x4b, 0x26, 0x4a, 0x26, + 0x49, 0x00, 0x2c, 0x0d, 0xd0, 0x00, 0x27, 0x07, + 0x64, 0x48, 0x68, 0x01, 0x28, 0x02, 0xd0, 0x10, + 0x68, 0x00, 0x28, 0x02, 0xd0, 0x58, 0x68, 0x01, + 0x30, 0x58, 0x60, 0x98, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xc4, 0x6b, 0x00, 0x2c, 0x1a, 0xd0, 0x49, + 0x68, 0x01, 0x29, 0x02, 0xd0, 0x11, 0x68, 0x00, + 0x29, 0x07, 0xd0, 0x58, 0x68, 0x1a, 0x4a, 0x41, + 0x1c, 0x59, 0x60, 0x38, 0x69, 0x00, 0xf0, 0x39, + 0xfd, 0xeb, 0xe7, 0x39, 0x69, 0x00, 0x29, 0xe8, + 0xd0, 0x00, 0x22, 0x00, 0x92, 0xc2, 0x1d, 0x05, + 0x32, 0x01, 0x23, 0x08, 0x1c, 0x13, 0x49, 0x00, + 0xf0, 0xa8, 0xfb, 0xde, 0xe7, 0x49, 0x68, 0x01, + 0x29, 0x02, 0xd0, 0x11, 0x68, 0x00, 0x29, 0x07, + 0xd0, 0x58, 0x68, 0x0e, 0x4a, 0x41, 0x1c, 0x59, + 0x60, 0x38, 0x69, 0x00, 0xf0, 0x1e, 0xfd, 0xd0, + 0xe7, 0x39, 0x69, 0x00, 0x29, 0xcd, 0xd0, 0x00, + 0x22, 0x00, 0x92, 0xc2, 0x1d, 0x05, 0x32, 0x01, + 0x23, 0x08, 0x1c, 0x05, 0x49, 0x00, 0xf0, 0x8d, + 0xfb, 0xc3, 0xe7, 0x60, 0xbb, 0xed, 0x09, 0x00, + 0x85, 0x01, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, + 0x24, 0x68, 0x03, 0x20, 0x09, 0x04, 0x00, 0x00, + 0xff, 0x0f, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, + 0xf0, 0xb5, 0x04, 0x1c, 0xc0, 0x68, 0xff, 0xf7, + 0xf7, 0xfb, 0x07, 0x1c, 0x07, 0xd0, 0x25, 0x69, + 0x00, 0x2d, 0x07, 0xd1, 0xb8, 0x6b, 0x00, 0x28, + 0x04, 0xd0, 0x04, 0x20, 0x78, 0x63, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x2d, 0x03, 0xd0, + 0xe8, 0x00, 0xc0, 0x19, 0x01, 0x69, 0x00, 0xe0, + 0x79, 0x69, 0x10, 0x4e, 0x70, 0x6d, 0x40, 0x09, + 0x0e, 0xd3, 0x60, 0x69, 0xa2, 0x69, 0x00, 0xf0, + 0xab, 0xfb, 0xf0, 0x1d, 0x79, 0x30, 0x81, 0x6a, + 0x00, 0x29, 0x05, 0xd0, 0x01, 0x39, 0x81, 0x62, + 0x02, 0xd1, 0x20, 0x20, 0x01, 0xf0, 0xb6, 0xfb, + 0x00, 0x2d, 0x04, 0xd0, 0x00, 0x20, 0xe9, 0x00, + 0xc9, 0x19, 0x48, 0x61, 0xdb, 0xe7, 0x38, 0x1c, + 0x01, 0x21, 0x03, 0xa2, 0xff, 0xf7, 0x34, 0xfc, + 0xd5, 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, + 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x31, + 0x33, 0x37, 0x38, 0x00, 0xf8, 0xb5, 0xc7, 0x68, + 0x04, 0x1c, 0x00, 0x2f, 0x04, 0xd0, 0x38, 0x1c, + 0xff, 0xf7, 0xae, 0xfb, 0x07, 0x1c, 0x5e, 0xd0, + 0x25, 0x6a, 0x00, 0x2f, 0x1f, 0xd0, 0x01, 0x20, + 0xa1, 0x69, 0x00, 0x03, 0x00, 0x29, 0x0f, 0xd1, + 0x02, 0x21, 0x00, 0x2d, 0x0a, 0xd0, 0x3a, 0x6b, + 0x82, 0x42, 0x03, 0xd0, 0xeb, 0x00, 0xdb, 0x19, + 0x1a, 0x61, 0x38, 0x63, 0xe8, 0x00, 0xc0, 0x19, + 0x41, 0x61, 0x0c, 0xe0, 0x79, 0x63, 0x0a, 0xe0, + 0x00, 0x21, 0x00, 0x2d, 0x06, 0xd0, 0x38, 0x63, + 0x03, 0x2d, 0x04, 0xd8, 0xe8, 0x00, 0xc0, 0x19, + 0x41, 0x61, 0x00, 0xe0, 0x79, 0x63, 0x24, 0x48, + 0xed, 0x09, 0x00, 0x86, 0x01, 0x04, 0x23, 0x40, + 0x6d, 0x18, 0x40, 0xe6, 0x1d, 0x09, 0x36, 0x00, + 0x28, 0x27, 0xd0, 0x00, 0x2f, 0x0d, 0xd0, 0x00, + 0x2d, 0x08, 0xd0, 0x03, 0x2d, 0x03, 0xd8, 0xe8, + 0x00, 0xc0, 0x19, 0x01, 0x69, 0x00, 0xe0, 0x1c, + 0x49, 0x00, 0x23, 0x04, 0xe0, 0x01, 0x23, 0x79, + 0x69, 0x01, 0xe0, 0x19, 0x49, 0x01, 0x23, 0x62, + 0x6a, 0x00, 0x92, 0xfa, 0x1d, 0x05, 0x32, 0x00, + 0x2f, 0x00, 0xd1, 0x32, 0x1c, 0xa0, 0x69, 0x00, + 0xf0, 0xe9, 0xfa, 0xa0, 0x69, 0x00, 0x28, 0x08, + 0xd1, 0x12, 0x48, 0x81, 0x6a, 0x01, 0x31, 0x81, + 0x62, 0x01, 0x29, 0x02, 0xd1, 0x20, 0x20, 0x01, + 0xf0, 0x3f, 0xfb, 0x00, 0x2d, 0x09, 0xd1, 0xa0, + 0x69, 0x00, 0x28, 0x06, 0xd0, 0x00, 0x2f, 0x07, + 0xd0, 0x38, 0x1c, 0x01, 0x21, 0x0a, 0xa2, 0xff, + 0xf7, 0xbd, 0xfb, 0xf8, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x30, 0x1c, 0xff, 0xf7, 0x85, 0xfa, 0x00, + 0x28, 0xf7, 0xd0, 0x0a, 0xa2, 0x00, 0x21, 0xff, + 0xf7, 0xb1, 0xfb, 0xf2, 0xe7, 0x60, 0xbb, 0x03, + 0x20, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xbb, 0x03, + 0x20, 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x31, 0x34, 0x37, 0x31, 0x00, 0x73, 0x72, 0x63, + 0x5c, 0x68, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x34, 0x37, 0x36, + 0x00, 0x90, 0xb5, 0x0f, 0x4c, 0x07, 0x1c, 0x60, + 0x68, 0x41, 0x1c, 0x61, 0x60, 0x78, 0x69, 0x00, + 0x28, 0x11, 0xd0, 0xf8, 0x68, 0x00, 0x28, 0x0b, + 0xd0, 0xff, 0xf7, 0x18, 0xfb, 0x00, 0x28, 0x07, + 0xd0, 0xc3, 0x1d, 0x05, 0x33, 0x85, 0x21, 0x3a, + 0x69, 0x60, 0x68, 0xc9, 0x00, 0x00, 0xf0, 0x4f, + 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, + 0x69, 0x02, 0x4a, 0xed, 0x09, 0x00, 0x87, 0x01, + 0x00, 0xf0, 0x0f, 0xfc, 0xf7, 0xe7, 0x60, 0xbb, + 0x03, 0x20, 0x06, 0x04, 0x00, 0x00, 0x08, 0xb5, + 0x08, 0x4a, 0x01, 0x1c, 0x50, 0x68, 0x01, 0x30, + 0x50, 0x60, 0x0a, 0x69, 0x00, 0x92, 0xc9, 0x68, + 0x00, 0x22, 0x4b, 0x69, 0x04, 0x49, 0x00, 0xf0, + 0x35, 0xfe, 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x36, 0x0c, + 0x00, 0x00, 0x08, 0xb5, 0x08, 0x49, 0x49, 0x6d, + 0x09, 0x0b, 0x08, 0xd3, 0xc2, 0x69, 0x10, 0x30, + 0x00, 0x92, 0x0e, 0xc8, 0x1c, 0x38, 0x49, 0x69, + 0xc0, 0x68, 0x00, 0xf0, 0x80, 0xfb, 0x01, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x00, 0xb5, 0x06, 0x49, 0x49, 0x6d, + 0xc9, 0x0a, 0x06, 0xd3, 0x01, 0x69, 0xc2, 0x1d, + 0x49, 0x69, 0xc0, 0x68, 0x0d, 0x32, 0x00, 0xf0, + 0x4b, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x08, 0xb5, 0x08, 0x4a, 0x01, 0x1c, + 0x50, 0x68, 0x01, 0x30, 0x50, 0x60, 0xca, 0x1d, + 0x09, 0x32, 0x00, 0x92, 0xcb, 0x68, 0x04, 0x49, + 0x00, 0x22, 0x00, 0xf0, 0xfb, 0xfd, 0x01, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x39, 0x0c, 0x00, 0x00, 0x80, 0xb5, + 0x07, 0x1c, 0x08, 0x48, 0x40, 0x6d, 0xc0, 0x09, + 0x09, 0xd3, 0xf8, 0x68, 0xf9, 0x1d, 0x09, 0x31, + 0xba, 0x69, 0x00, 0xf0, 0xac, 0xfa, 0xb8, 0x69, + 0x04, 0xa1, 0x0f, 0xf0, 0xe2, 0xfd, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x31, 0x35, 0x37, 0x30, 0x00, 0x80, 0xb5, + 0x84, 0xb0, 0x07, 0x1c, 0x0b, 0x48, 0x40, 0x6d, + 0x40, 0x0b, 0x0e, 0xd3, 0x1c, 0x37, 0xed, 0x09, + 0x00, 0x88, 0x01, 0x07, 0xcf, 0x28, 0x3f, 0x02, + 0x91, 0x01, 0x90, 0x03, 0x92, 0xba, 0x69, 0x00, + 0x92, 0x38, 0x69, 0x7b, 0x69, 0x41, 0x69, 0xf8, + 0x68, 0x00, 0x22, 0x00, 0xf0, 0x42, 0xfb, 0x04, + 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, + 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x06, 0x49, 0x49, + 0x6d, 0x09, 0x0f, 0x05, 0xd3, 0x01, 0x69, 0x42, + 0x69, 0x49, 0x69, 0xc0, 0x68, 0x00, 0xf0, 0xed, + 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x08, 0xb5, 0x08, 0x4a, 0x01, + 0x1c, 0x50, 0x68, 0x01, 0x30, 0x50, 0x60, 0x4a, + 0x69, 0x00, 0x92, 0xca, 0x68, 0x53, 0x69, 0x0a, + 0x69, 0x04, 0x49, 0x00, 0xf0, 0x99, 0xfd, 0x01, + 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, + 0xbb, 0x03, 0x20, 0x05, 0x14, 0x00, 0x00, 0x00, + 0xb5, 0x01, 0x1c, 0x05, 0x4a, 0xcb, 0x1d, 0x50, + 0x68, 0x05, 0x49, 0x01, 0x30, 0x50, 0x60, 0x00, + 0x22, 0x05, 0x33, 0x00, 0xf0, 0x85, 0xfd, 0x08, + 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0x09, + 0x10, 0x00, 0x00, 0x08, 0xb5, 0x01, 0x1c, 0xca, + 0x68, 0x40, 0x69, 0x52, 0x69, 0x4a, 0x61, 0xca, + 0x1d, 0x0d, 0x32, 0x00, 0x28, 0x08, 0xd0, 0x13, + 0x1c, 0x08, 0x22, 0x08, 0x69, 0x12, 0x21, 0x00, + 0xf0, 0x41, 0xfd, 0x01, 0xb0, 0x08, 0xbc, 0x18, + 0x47, 0x05, 0x4b, 0x58, 0x68, 0x01, 0x30, 0x58, + 0x60, 0x00, 0x92, 0x0a, 0x69, 0x03, 0x49, 0x20, + 0x23, 0x00, 0xf0, 0x62, 0xfd, 0xf1, 0xe7, 0x60, + 0xbb, 0x03, 0x20, 0x01, 0xfc, 0x00, 0x00, 0x00, + 0xb5, 0x06, 0x49, 0x49, 0x6d, 0x49, 0x0f, 0x05, + 0xd3, 0xc1, 0x68, 0x02, 0x69, 0x49, 0x69, 0x40, + 0x69, 0x00, 0xf0, 0xb1, 0xfc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x80, + 0xb5, 0xed, 0x09, 0x00, 0x89, 0x01, 0x07, 0x1c, + 0xfd, 0xf7, 0x14, 0xf8, 0x00, 0x21, 0x20, 0x20, + 0x01, 0xf0, 0xea, 0xf9, 0x09, 0x48, 0xc1, 0x1d, + 0x79, 0x31, 0x8a, 0x69, 0x00, 0x2a, 0x06, 0xd0, + 0x00, 0x20, 0x88, 0x61, 0x0a, 0xf0, 0x2a, 0xfd, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xfa, 0x68, + 0x40, 0x68, 0x03, 0x49, 0x00, 0xf0, 0x33, 0xfd, + 0xf6, 0xe7, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, + 0x03, 0x0c, 0x00, 0x00, 0x00, 0xb5, 0x06, 0x49, + 0x49, 0x6d, 0x89, 0x0c, 0x05, 0xd3, 0xc1, 0x1d, + 0x82, 0x69, 0x40, 0x69, 0x05, 0x31, 0x00, 0xf0, + 0x30, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x00, 0xb5, 0x05, 0x49, + 0x49, 0x6d, 0xc9, 0x0e, 0x04, 0xd3, 0x01, 0x69, + 0xc0, 0x68, 0x40, 0x69, 0x00, 0xf0, 0x3a, 0xfc, + 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, + 0x00, 0xb5, 0x06, 0x49, 0x49, 0x6d, 0x09, 0x0a, + 0x05, 0xd3, 0xc1, 0x68, 0x42, 0x69, 0x49, 0x69, + 0x00, 0x69, 0x00, 0xf0, 0xf0, 0xf9, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, + 0x00, 0xb5, 0x06, 0x49, 0x49, 0x6d, 0x09, 0x0d, + 0x06, 0xd3, 0xc1, 0x68, 0x42, 0x69, 0x83, 0x69, + 0x49, 0x69, 0x00, 0x69, 0x00, 0xf0, 0x53, 0xfb, + 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, + 0xb8, 0xb5, 0x04, 0x1c, 0x01, 0x20, 0x00, 0x90, + 0xe0, 0x68, 0xff, 0xf7, 0xa7, 0xf9, 0x07, 0x1c, + 0x28, 0xd0, 0x61, 0x69, 0x38, 0x1c, 0x01, 0xf0, + 0xa2, 0xf9, 0x6a, 0x46, 0x01, 0x20, 0xf9, 0x1d, + 0x0d, 0x31, 0x00, 0xf0, 0x0b, 0xfb, 0x78, 0x6b, + 0x04, 0x28, 0x1b, 0xd1, 0xb8, 0x6b, 0x00, 0x28, + 0x18, 0xd1, 0x0e, 0x4d, 0x68, 0x6d, 0x40, 0x09, + 0x0f, 0xd3, 0xa2, 0x69, 0x79, 0x69, 0x60, 0x69, + 0x00, 0xf0, 0x5c, 0xf9, 0xed, 0x09, 0x00, 0x8a, + 0x01, 0xe8, 0x1d, 0x79, 0x30, 0x81, 0x6a, 0x00, + 0x29, 0x05, 0xd0, 0x01, 0x39, 0x81, 0x62, 0x02, + 0xd1, 0x20, 0x20, 0x01, 0xf0, 0x67, 0xf9, 0x38, + 0x1c, 0x01, 0x21, 0x04, 0xa2, 0xff, 0xf7, 0xec, + 0xf9, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0x73, 0x72, 0x63, + 0x5c, 0x68, 0x63, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x38, 0x30, 0x30, + 0x00, 0x00, 0xb5, 0x01, 0x69, 0x00, 0x29, 0x06, + 0xd0, 0xc0, 0x68, 0x00, 0x28, 0x05, 0xd1, 0x08, + 0x1c, 0x05, 0xa1, 0x0f, 0xf0, 0xa6, 0xfc, 0x08, + 0xbc, 0x18, 0x47, 0xc8, 0x65, 0x07, 0x48, 0xff, + 0xf7, 0x17, 0xf8, 0xff, 0xf7, 0x39, 0xf8, 0xf6, + 0xe7, 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x31, 0x38, 0x31, 0x39, 0x00, 0xb8, 0xbb, 0x03, + 0x20, 0x88, 0xb5, 0x07, 0x69, 0x00, 0x2f, 0x10, + 0xd0, 0xc0, 0x68, 0x00, 0x28, 0x09, 0xd0, 0x69, + 0x46, 0xff, 0xf7, 0x2a, 0xf9, 0x00, 0x28, 0x04, + 0xd0, 0xf9, 0x69, 0xba, 0x69, 0x00, 0x98, 0x01, + 0xf0, 0x48, 0xfa, 0x38, 0x1c, 0x02, 0xa1, 0x0f, + 0xf0, 0x7c, 0xfc, 0x88, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x73, 0x72, 0x63, 0x5c, 0x68, 0x63, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x31, 0x38, 0x37, 0x39, 0x00, 0x90, 0xb5, 0x01, + 0x78, 0x01, 0x27, 0xc4, 0x19, 0x07, 0x29, 0x10, + 0xd2, 0x01, 0xa3, 0x5b, 0x5c, 0x5b, 0x00, 0x9f, + 0x44, 0x0c, 0x03, 0x07, 0x07, 0x0c, 0x0c, 0x0c, + 0x00, 0x20, 0x1c, 0x01, 0xf0, 0x4b, 0xfa, 0x04, + 0xe0, 0x02, 0x1c, 0x20, 0x1c, 0x01, 0xf0, 0xac, + 0xf9, 0x07, 0x1c, 0x38, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb5, 0xed, + 0x09, 0x00, 0x8b, 0x01, 0xc1, 0xb0, 0x69, 0x46, + 0x04, 0x22, 0x00, 0xab, 0x1a, 0x70, 0x0e, 0x22, + 0x5a, 0x70, 0xc8, 0x70, 0x00, 0x20, 0x08, 0x71, + 0x48, 0x71, 0x05, 0x31, 0x48, 0x1c, 0x69, 0x46, + 0x41, 0x1a, 0xc8, 0x1e, 0x98, 0x70, 0x68, 0x46, + 0xfd, 0xf7, 0xe7, 0xf8, 0x41, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xc1, 0xb0, 0x69, 0x46, + 0x04, 0x22, 0x00, 0xab, 0x1a, 0x70, 0x01, 0x22, + 0x5a, 0x70, 0xc8, 0x70, 0x03, 0x31, 0x88, 0x18, + 0x69, 0x46, 0x41, 0x1a, 0xc8, 0x1e, 0x98, 0x70, + 0x68, 0x46, 0xfd, 0xf7, 0xd2, 0xf8, 0x41, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 0xc1, 0xb0, + 0x04, 0x25, 0x00, 0xab, 0x4b, 0x9a, 0x4c, 0x9f, + 0x1d, 0x70, 0x02, 0x25, 0x5d, 0x70, 0x6b, 0x46, + 0x5b, 0x19, 0x58, 0x70, 0x02, 0x33, 0x00, 0x24, + 0x00, 0x28, 0x0a, 0xd9, 0x00, 0x25, 0x0e, 0x78, + 0x01, 0x31, 0x01, 0x35, 0x1e, 0x70, 0x01, 0x33, + 0x06, 0x2d, 0xf8, 0xd3, 0x01, 0x34, 0x84, 0x42, + 0xf4, 0xd3, 0x00, 0x21, 0x00, 0x28, 0x07, 0xd9, + 0x43, 0x9d, 0x8c, 0x00, 0x2c, 0x59, 0x01, 0x31, + 0x1c, 0x70, 0x01, 0x33, 0x81, 0x42, 0xf7, 0xd3, + 0x00, 0x21, 0x00, 0x28, 0x07, 0xd9, 0x44, 0x9d, + 0x8c, 0x00, 0x2c, 0x59, 0x01, 0x31, 0x1c, 0x70, + 0x01, 0x33, 0x81, 0x42, 0xf7, 0xd3, 0x00, 0x21, + 0x00, 0x28, 0x07, 0xd9, 0x4a, 0x9d, 0x8c, 0x00, + 0x2c, 0x59, 0x01, 0x31, 0x1c, 0x70, 0x01, 0x33, + 0x81, 0x42, 0xf7, 0xd3, 0x00, 0x21, 0x00, 0x28, + 0x0c, 0xd9, 0x8c, 0x00, 0x15, 0x59, 0x1d, 0x70, + 0x15, 0x59, 0x2d, 0x0a, 0x5d, 0x70, 0x14, 0x59, + 0x24, 0x0c, 0x9c, 0x70, 0x03, 0x33, 0x01, 0x31, + 0x81, 0x42, 0xf2, 0xd3, 0x00, 0x21, 0x00, 0x28, + 0x09, 0xd9, 0x8a, 0x00, 0xbc, 0x58, 0x1c, 0x70, + 0xba, 0x58, 0xed, 0x09, 0x00, 0x8c, 0x01, 0x12, + 0x0a, 0x5a, 0x70, 0x02, 0x33, 0x01, 0x31, 0x81, + 0x42, 0xf5, 0xd3, 0x68, 0x46, 0x19, 0x1a, 0xc8, + 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfd, + 0xf7, 0x6e, 0xf8, 0x45, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0xc1, 0xb0, 0x1f, + 0x1c, 0x00, 0xab, 0x04, 0x26, 0x46, 0x9d, 0x1e, + 0x70, 0x03, 0x26, 0x5e, 0x70, 0x6b, 0x46, 0x9b, + 0x19, 0x18, 0x70, 0x58, 0x1c, 0x01, 0x70, 0x09, + 0x0a, 0x41, 0x70, 0x00, 0x21, 0x02, 0x30, 0x13, + 0x78, 0x01, 0x32, 0x01, 0x31, 0x03, 0x70, 0x01, + 0x30, 0x06, 0x29, 0xf8, 0xd3, 0x07, 0x70, 0x45, + 0x70, 0x69, 0x46, 0x02, 0x30, 0x41, 0x1a, 0xc8, + 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfd, + 0xf7, 0x46, 0xf8, 0x41, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xb5, 0xc1, 0xb0, 0x6f, + 0x46, 0x04, 0x24, 0x00, 0xab, 0x1c, 0x70, 0x5c, + 0x70, 0xfb, 0x1c, 0x00, 0x27, 0x04, 0x78, 0x01, + 0x30, 0x01, 0x37, 0x1c, 0x70, 0x01, 0x33, 0x06, + 0x2f, 0xf8, 0xd3, 0x19, 0x70, 0x58, 0x1c, 0x0b, + 0x0a, 0x03, 0x70, 0x09, 0x0c, 0x41, 0x70, 0x82, + 0x70, 0x69, 0x46, 0x03, 0x30, 0x41, 0x1a, 0xc8, + 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfd, + 0xf7, 0x22, 0xf8, 0x41, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xb5, 0xc1, 0xb0, 0x6f, + 0x46, 0x04, 0x24, 0x00, 0xab, 0x1c, 0x70, 0x05, + 0x24, 0x5c, 0x70, 0xf8, 0x70, 0xfb, 0x1c, 0x58, + 0x1c, 0x01, 0x70, 0x09, 0x0a, 0x41, 0x70, 0x82, + 0x70, 0x69, 0x46, 0x03, 0x30, 0x41, 0x1a, 0xc8, + 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfd, + 0xf7, 0x06, 0xf8, 0x41, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xc1, 0xb0, 0x6a, + 0x46, 0x04, 0x27, 0x00, 0xab, 0xed, 0x09, 0x00, + 0x8d, 0x01, 0x1f, 0x70, 0x06, 0x27, 0x5f, 0x70, + 0xd0, 0x70, 0x03, 0x32, 0x50, 0x1c, 0x01, 0x70, + 0x09, 0x0a, 0x41, 0x70, 0x69, 0x46, 0x02, 0x30, + 0x41, 0x1a, 0xc8, 0x1e, 0x98, 0x70, 0x68, 0x46, + 0xfc, 0xf7, 0xec, 0xff, 0x41, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0xc1, 0xb0, + 0x6f, 0x46, 0x04, 0x24, 0x00, 0xab, 0x1c, 0x70, + 0x07, 0x24, 0x5c, 0x70, 0xf8, 0x70, 0xfb, 0x1c, + 0x58, 0x1c, 0x00, 0x23, 0x0f, 0x78, 0x01, 0x31, + 0x01, 0x33, 0x07, 0x70, 0x01, 0x30, 0x06, 0x2b, + 0xf8, 0xd3, 0x00, 0x21, 0x13, 0x78, 0x01, 0x32, + 0x01, 0x31, 0x03, 0x70, 0x01, 0x30, 0xf8, 0x29, + 0xf8, 0xd3, 0x69, 0x46, 0x41, 0x1a, 0xc8, 0x1e, + 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, + 0xc5, 0xff, 0x41, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0xc1, 0xb0, 0x6f, 0x46, + 0x04, 0x24, 0x00, 0xab, 0x1c, 0x70, 0x08, 0x24, + 0x5c, 0x70, 0xf8, 0x70, 0xfb, 0x1c, 0x58, 0x1c, + 0x01, 0x70, 0x09, 0x0a, 0x41, 0x70, 0x82, 0x70, + 0x69, 0x46, 0x03, 0x30, 0x41, 0x1a, 0xc8, 0x1e, + 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, + 0xa9, 0xff, 0x41, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x80, 0xb5, 0xc1, 0xb0, 0x6a, 0x46, + 0x04, 0x27, 0x00, 0xab, 0x1f, 0x70, 0x09, 0x27, + 0x5f, 0x70, 0xd0, 0x70, 0x03, 0x32, 0x50, 0x1c, + 0x01, 0x70, 0x09, 0x0a, 0x41, 0x70, 0x69, 0x46, + 0x02, 0x30, 0x41, 0x1a, 0xc8, 0x1e, 0x98, 0x70, + 0x68, 0x46, 0xfc, 0xf7, 0x8f, 0xff, 0x41, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0xc1, 0xb0, 0x6f, 0x46, 0x04, 0x24, 0x00, 0xab, + 0x1c, 0x70, 0x0a, 0x24, 0x5c, 0x70, 0xf8, 0x70, + 0xfb, 0x1c, 0x58, 0x1c, 0x01, 0x70, 0x09, 0x0a, + 0xed, 0x09, 0x00, 0x8e, 0x01, 0x41, 0x70, 0x82, + 0x70, 0x69, 0x46, 0x03, 0x30, 0x41, 0x1a, 0xc8, + 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, + 0xf7, 0x73, 0xff, 0x41, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xb5, 0xc1, 0xb0, 0x6f, + 0x46, 0x04, 0x24, 0x00, 0xab, 0x1c, 0x70, 0x0b, + 0x24, 0x5c, 0x70, 0xf8, 0x70, 0xfb, 0x1c, 0x58, + 0x1c, 0x01, 0x70, 0x09, 0x0a, 0x41, 0x70, 0x00, + 0x21, 0x02, 0x30, 0x13, 0x78, 0x01, 0x32, 0x01, + 0x31, 0x03, 0x70, 0x01, 0x30, 0x08, 0x29, 0xf8, + 0xd3, 0x69, 0x46, 0x41, 0x1a, 0xc8, 0x1e, 0x00, + 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, 0x50, + 0xff, 0x41, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0xc1, 0xb0, 0x6c, 0x46, 0x1f, + 0x1c, 0x00, 0xab, 0x04, 0x26, 0x46, 0x9d, 0x1e, + 0x70, 0x0c, 0x26, 0x5e, 0x70, 0xe0, 0x70, 0xe3, + 0x1c, 0x58, 0x1c, 0x01, 0x70, 0x09, 0x0a, 0x41, + 0x70, 0x82, 0x70, 0xc7, 0x70, 0x39, 0x0a, 0x01, + 0x71, 0x45, 0x71, 0x29, 0x0a, 0x81, 0x71, 0x69, + 0x46, 0x07, 0x30, 0x41, 0x1a, 0xc8, 0x1e, 0x00, + 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, 0x2c, + 0xff, 0x41, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xff, 0xb5, 0xc1, 0xb0, 0x6d, 0x46, 0x04, + 0x26, 0x00, 0xab, 0x4d, 0x98, 0x4c, 0x9a, 0x4a, + 0x9c, 0x4b, 0x9f, 0x1e, 0x70, 0x0d, 0x26, 0x5e, + 0x70, 0xeb, 0x1c, 0x41, 0x9d, 0x1d, 0x70, 0x59, + 0x70, 0x09, 0x0a, 0x99, 0x70, 0x02, 0x33, 0x59, + 0x1c, 0x43, 0x9b, 0x0b, 0x70, 0x44, 0x9b, 0x4b, + 0x70, 0x8c, 0x70, 0x23, 0x0a, 0xcb, 0x70, 0x23, + 0x0c, 0x0b, 0x71, 0x23, 0x0e, 0x4b, 0x71, 0x8f, + 0x71, 0x3b, 0x0a, 0xcb, 0x71, 0x3b, 0x0c, 0x0b, + 0x72, 0x3b, 0x0e, 0x4b, 0x72, 0x8a, 0x72, 0x13, + 0x0a, 0xcb, 0x72, 0xed, 0x09, 0x00, 0x8f, 0x01, + 0x13, 0x0c, 0x0b, 0x73, 0x12, 0x0e, 0x4a, 0x73, + 0x88, 0x73, 0x02, 0x0a, 0xca, 0x73, 0x02, 0x0c, + 0x0a, 0x74, 0x00, 0x0e, 0x48, 0x74, 0x11, 0x31, + 0x48, 0x1c, 0x69, 0x46, 0x41, 0x1a, 0xc8, 0x1e, + 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, + 0xea, 0xfe, 0x45, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0xc1, 0xb0, 0x6f, 0x46, + 0x04, 0x24, 0x00, 0xab, 0x1c, 0x70, 0x0f, 0x24, + 0x5c, 0x70, 0xf8, 0x70, 0xfb, 0x1c, 0x59, 0x70, + 0x9a, 0x70, 0x11, 0x0a, 0xd9, 0x70, 0x69, 0x46, + 0x18, 0x1d, 0x41, 0x1a, 0xc8, 0x1e, 0x00, 0xab, + 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, 0xcf, 0xfe, + 0x41, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0xc1, 0xb0, 0x69, 0x46, 0x04, 0x22, + 0x00, 0xab, 0x1a, 0x70, 0x10, 0x22, 0x5a, 0x70, + 0xc8, 0x70, 0x03, 0x31, 0x48, 0x1c, 0x69, 0x46, + 0x41, 0x1a, 0xc8, 0x1e, 0x98, 0x70, 0x68, 0x46, + 0xfc, 0xf7, 0xb9, 0xfe, 0x41, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xc1, 0xb0, 0x69, 0x46, + 0x04, 0x22, 0x00, 0xab, 0x1a, 0x70, 0x11, 0x22, + 0x5a, 0x70, 0xc8, 0x70, 0x00, 0x0a, 0x08, 0x71, + 0x04, 0x31, 0x48, 0x1c, 0x69, 0x46, 0x41, 0x1a, + 0xc8, 0x1e, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, + 0xa2, 0xfe, 0x41, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x90, 0xb5, 0xc1, 0xb0, 0x6f, 0x46, 0x04, 0x24, + 0x00, 0xab, 0x1c, 0x70, 0x12, 0x24, 0x5c, 0x70, + 0xf8, 0x70, 0xfb, 0x1c, 0x58, 0x1c, 0x00, 0x23, + 0x0f, 0x78, 0x01, 0x31, 0x01, 0x33, 0x07, 0x70, + 0x01, 0x30, 0x06, 0x2b, 0xf8, 0xd3, 0x02, 0x70, + 0x69, 0x46, 0x01, 0x30, 0x41, 0x1a, 0xc8, 0x1e, + 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, + 0x82, 0xfe, 0x41, 0xb0, 0x90, 0xbc, 0xed, 0x09, + 0x00, 0x90, 0x01, 0x08, 0xbc, 0x18, 0x47, 0xb0, + 0xb5, 0xc1, 0xb0, 0x6f, 0x46, 0x04, 0x24, 0x00, + 0xab, 0x1c, 0x70, 0x13, 0x24, 0x5c, 0x70, 0xfb, + 0x1c, 0x18, 0x70, 0x01, 0x33, 0x00, 0x27, 0x00, + 0x28, 0x09, 0xd9, 0xbc, 0x00, 0x0d, 0x59, 0x1d, + 0x70, 0x0c, 0x59, 0x24, 0x0a, 0x5c, 0x70, 0x02, + 0x33, 0x01, 0x37, 0x87, 0x42, 0xf5, 0xd3, 0x00, + 0x21, 0x00, 0x28, 0x09, 0xd9, 0x8f, 0x00, 0xd4, + 0x59, 0x1c, 0x70, 0xd7, 0x59, 0x3f, 0x0a, 0x5f, + 0x70, 0x02, 0x33, 0x01, 0x31, 0x81, 0x42, 0xf5, + 0xd3, 0x68, 0x46, 0x19, 0x1a, 0xc8, 0x1e, 0x00, + 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, 0x51, + 0xfe, 0x41, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xb0, 0xb5, 0xc1, 0xb0, 0x6c, 0x46, 0x1f, + 0x1c, 0x00, 0xab, 0x04, 0x25, 0x1d, 0x70, 0x14, + 0x25, 0x5d, 0x70, 0xe0, 0x70, 0xe3, 0x1c, 0x58, + 0x1c, 0x01, 0x70, 0x09, 0x0a, 0x41, 0x70, 0x82, + 0x70, 0xc7, 0x70, 0x39, 0x0a, 0x01, 0x71, 0x69, + 0x46, 0x05, 0x30, 0x41, 0x1a, 0xc8, 0x1e, 0x00, + 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, 0x31, + 0xfe, 0x41, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xb0, 0xb5, 0xc1, 0xb0, 0x6f, 0x46, 0x04, + 0x24, 0x00, 0xab, 0x1c, 0x70, 0x15, 0x24, 0x5c, + 0x70, 0xfb, 0x1c, 0x18, 0x70, 0x01, 0x33, 0x00, + 0x24, 0x00, 0x28, 0x0a, 0xd9, 0x00, 0x27, 0x0d, + 0x78, 0x01, 0x31, 0x01, 0x37, 0x1d, 0x70, 0x01, + 0x33, 0x06, 0x2f, 0xf8, 0xd3, 0x01, 0x34, 0x84, + 0x42, 0xf4, 0xd3, 0x00, 0x27, 0x00, 0x28, 0x0a, + 0xd9, 0x00, 0x21, 0x14, 0x78, 0x01, 0x32, 0x01, + 0x31, 0x1c, 0x70, 0x01, 0x33, 0x10, 0x29, 0xf8, + 0xd3, 0x01, 0x37, 0x87, 0x42, 0xf4, 0xd3, 0x68, + 0x46, 0x19, 0x1a, 0xc8, 0x1e, 0x00, 0xab, 0x98, + 0x70, 0xed, 0x09, 0x00, 0x91, 0x01, 0x68, 0x46, + 0xfc, 0xf7, 0xfe, 0xfd, 0x41, 0xb0, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xc1, 0xb0, + 0x69, 0x46, 0x04, 0x22, 0x00, 0xab, 0x1a, 0x70, + 0x16, 0x22, 0x5a, 0x70, 0x00, 0x22, 0x03, 0x31, + 0x03, 0x78, 0x01, 0x30, 0x01, 0x32, 0x0b, 0x70, + 0x01, 0x31, 0x06, 0x2a, 0xf8, 0xd3, 0x68, 0x46, + 0x09, 0x1a, 0xc8, 0x1e, 0x00, 0xab, 0x98, 0x70, + 0x68, 0x46, 0xfc, 0xf7, 0xe1, 0xfd, 0x41, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xc1, 0xb0, + 0x69, 0x46, 0x04, 0x22, 0x00, 0xab, 0x1a, 0x70, + 0x17, 0x22, 0x5a, 0x70, 0x00, 0x22, 0x03, 0x31, + 0x03, 0x78, 0x01, 0x30, 0x01, 0x32, 0x0b, 0x70, + 0x01, 0x31, 0x06, 0x2a, 0xf8, 0xd3, 0x68, 0x46, + 0x09, 0x1a, 0xc8, 0x1e, 0x00, 0xab, 0x98, 0x70, + 0x68, 0x46, 0xfc, 0xf7, 0xc5, 0xfd, 0x41, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0xc1, 0xb0, + 0x6f, 0x46, 0x04, 0x24, 0x00, 0xab, 0x1c, 0x70, + 0x18, 0x24, 0x5c, 0x70, 0xfb, 0x1c, 0x00, 0x27, + 0x04, 0x78, 0x01, 0x30, 0x01, 0x37, 0x1c, 0x70, + 0x01, 0x33, 0x06, 0x2f, 0xf8, 0xd3, 0x00, 0x20, + 0x0f, 0x78, 0x01, 0x31, 0x01, 0x30, 0x1f, 0x70, + 0x01, 0x33, 0x10, 0x28, 0xf8, 0xd3, 0x69, 0x46, + 0x58, 0x1c, 0x41, 0x1a, 0x1a, 0x70, 0x00, 0xab, + 0xc8, 0x1e, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, + 0x9f, 0xfd, 0x41, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xc1, 0xb0, 0x69, 0x46, + 0x04, 0x22, 0x00, 0xab, 0x1a, 0x70, 0x1a, 0x22, + 0x5a, 0x70, 0xc8, 0x70, 0x03, 0x31, 0x48, 0x1c, + 0x69, 0x46, 0x41, 0x1a, 0xc8, 0x1e, 0x98, 0x70, + 0x68, 0x46, 0xfc, 0xf7, 0x89, 0xfd, 0x41, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xc1, 0xb0, + 0x6a, 0x46, 0x04, 0x27, 0xed, 0x09, 0x00, 0x92, + 0x01, 0x00, 0xab, 0x1f, 0x70, 0x1b, 0x27, 0x5f, + 0x70, 0xd0, 0x70, 0x00, 0x0a, 0x10, 0x71, 0x04, + 0x32, 0x51, 0x70, 0x69, 0x46, 0x90, 0x1c, 0x41, + 0x1a, 0xc8, 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, + 0x46, 0xfc, 0xf7, 0x70, 0xfd, 0x41, 0xb0, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0xc1, + 0xb0, 0x6f, 0x46, 0x04, 0x24, 0x00, 0xab, 0x1c, + 0x70, 0x1c, 0x24, 0x5c, 0x70, 0xf8, 0x70, 0xfb, + 0x1c, 0x58, 0x1c, 0x01, 0x70, 0x09, 0x0a, 0x41, + 0x70, 0x82, 0x70, 0x11, 0x0a, 0xc1, 0x70, 0x69, + 0x46, 0x04, 0x30, 0x41, 0x1a, 0xc8, 0x1e, 0x00, + 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, 0x52, + 0xfd, 0x41, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x90, 0xb5, 0xc1, 0xb0, 0x6f, 0x46, 0x04, + 0x24, 0x00, 0xab, 0x1c, 0x70, 0x1d, 0x24, 0x5c, + 0x70, 0xf8, 0x70, 0xfb, 0x1c, 0x58, 0x1c, 0x01, + 0x70, 0x09, 0x0a, 0x41, 0x70, 0x82, 0x70, 0x11, + 0x0a, 0xc1, 0x70, 0x69, 0x46, 0x04, 0x30, 0x41, + 0x1a, 0xc8, 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, + 0x46, 0xfc, 0xf7, 0x34, 0xfd, 0x41, 0xb0, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xc1, + 0xb0, 0x69, 0x46, 0x04, 0x22, 0x00, 0xab, 0x1a, + 0x70, 0x1e, 0x22, 0x5a, 0x70, 0xc8, 0x70, 0x00, + 0x0a, 0x08, 0x71, 0x04, 0x31, 0x48, 0x1c, 0x69, + 0x46, 0x41, 0x1a, 0xc8, 0x1e, 0x98, 0x70, 0x68, + 0x46, 0xfc, 0xf7, 0x1c, 0xfd, 0x41, 0xb0, 0x08, + 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xc1, 0xb0, 0x6a, + 0x46, 0x04, 0x27, 0x00, 0xab, 0x1f, 0x70, 0x1f, + 0x27, 0x5f, 0x70, 0x00, 0x23, 0x03, 0x32, 0x07, + 0x78, 0x01, 0x30, 0x01, 0x33, 0x17, 0x70, 0x01, + 0x32, 0x06, 0x2b, 0xf8, 0xd3, 0x11, 0x70, 0x69, + 0x46, 0x50, 0x1c, 0x41, 0x1a, 0xc8, 0x1e, 0xed, + 0x09, 0x00, 0x93, 0x01, 0x00, 0xab, 0x98, 0x70, + 0x68, 0x46, 0xfc, 0xf7, 0xfe, 0xfc, 0x41, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, + 0xc1, 0xb0, 0x6a, 0x46, 0x04, 0x27, 0x00, 0xab, + 0x1f, 0x70, 0x20, 0x27, 0x5f, 0x70, 0x00, 0x23, + 0x03, 0x32, 0x07, 0x78, 0x01, 0x30, 0x01, 0x33, + 0x17, 0x70, 0x01, 0x32, 0x06, 0x2b, 0xf8, 0xd3, + 0x11, 0x70, 0x69, 0x46, 0x50, 0x1c, 0x41, 0x1a, + 0xc8, 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, + 0xfc, 0xf7, 0xdf, 0xfc, 0x41, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc1, 0xb0, + 0x6c, 0x46, 0x1f, 0x1c, 0x00, 0xab, 0x04, 0x25, + 0x1d, 0x70, 0xff, 0x25, 0x5d, 0x70, 0xe0, 0x70, + 0xe3, 0x1c, 0x59, 0x70, 0x9a, 0x70, 0x98, 0x1c, + 0x43, 0x1c, 0x00, 0x20, 0x00, 0x2a, 0x0f, 0xd9, + 0x81, 0x00, 0x7c, 0x58, 0x1c, 0x70, 0x7c, 0x58, + 0x24, 0x0a, 0x5c, 0x70, 0x7c, 0x58, 0x24, 0x0c, + 0x9c, 0x70, 0x79, 0x58, 0x09, 0x0e, 0xd9, 0x70, + 0x04, 0x33, 0x01, 0x30, 0x90, 0x42, 0xef, 0xd3, + 0x68, 0x46, 0x19, 0x1a, 0xc8, 0x1e, 0x00, 0xab, + 0x98, 0x70, 0x68, 0x46, 0xfc, 0xf7, 0xb1, 0xfc, + 0x41, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x0f, 0xb4, 0xf0, 0xb5, 0xcf, 0xb0, 0x69, 0x46, + 0x04, 0x22, 0x00, 0xab, 0x1a, 0x70, 0x0e, 0x22, + 0x5a, 0x70, 0xc8, 0x70, 0x03, 0x31, 0x48, 0x1c, + 0x55, 0x99, 0x01, 0x70, 0x55, 0x99, 0x09, 0x0a, + 0x41, 0x70, 0x57, 0xa9, 0x0b, 0x1d, 0x01, 0x30, + 0x42, 0x1c, 0x68, 0x46, 0x07, 0x30, 0xcf, 0x1f, + 0x41, 0x1c, 0x4c, 0x1c, 0xdd, 0x1f, 0x4e, 0x93, + 0x63, 0x1c, 0x4c, 0x93, 0x01, 0x33, 0x55, 0x9e, + 0x4d, 0x93, 0x4e, 0x9b, 0x39, 0x3d, 0x3c, 0x3b, + 0x4b, 0x93, 0xd2, 0x4b, 0x39, 0x3f, 0x9e, 0x42, + 0x51, 0xd0, 0xed, 0x09, 0x00, 0x94, 0x01, 0x51, + 0xdc, 0xd1, 0x4b, 0x9e, 0x42, 0x4f, 0xd0, 0x4f, + 0xdc, 0xd0, 0x4b, 0x9e, 0x42, 0x4d, 0xd0, 0x45, + 0xdc, 0xcf, 0x4b, 0x9e, 0x42, 0x4a, 0xd0, 0x1d, + 0xdc, 0xce, 0x4b, 0x9e, 0x42, 0x47, 0xd0, 0x08, + 0xdc, 0x02, 0x3b, 0x9e, 0x42, 0x44, 0xd0, 0xcb, + 0x4b, 0x9e, 0x42, 0x42, 0xd1, 0xf9, 0x6b, 0x11, + 0x70, 0xff, 0xe1, 0xc9, 0x4b, 0x9e, 0x42, 0x3d, + 0xd0, 0x01, 0x33, 0x9e, 0x42, 0x39, 0xd1, 0xf9, + 0x6b, 0x11, 0x70, 0xea, 0x6b, 0x00, 0x21, 0x53, + 0x5c, 0x01, 0x31, 0x03, 0x70, 0x01, 0x30, 0x06, + 0x29, 0xf9, 0xd3, 0xee, 0xe1, 0xc2, 0x4b, 0x9e, + 0x42, 0x72, 0xd0, 0x11, 0xdc, 0xc1, 0x4b, 0x9e, + 0x42, 0x6f, 0xd0, 0x85, 0x23, 0xdb, 0x00, 0x9e, + 0x42, 0x23, 0xd1, 0xf9, 0x6b, 0x11, 0x70, 0xea, + 0x6b, 0x00, 0x21, 0x53, 0x5c, 0x01, 0x31, 0x03, + 0x70, 0x01, 0x30, 0x06, 0x29, 0xf9, 0xd3, 0xd8, + 0xe1, 0xb9, 0x4b, 0x9e, 0x42, 0x5e, 0xd0, 0x01, + 0x33, 0x9e, 0x42, 0x12, 0xd1, 0xfb, 0x6b, 0x13, + 0x70, 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, + 0x70, 0x20, 0x1c, 0xca, 0xe1, 0xb3, 0x4b, 0xf6, + 0x18, 0x09, 0xe0, 0x85, 0xe2, 0x2a, 0xe0, 0xf3, + 0xe1, 0x14, 0xe0, 0x9c, 0xe1, 0x2e, 0xe1, 0x1f, + 0xe1, 0x18, 0xe1, 0x48, 0xe0, 0x1f, 0xe1, 0x12, + 0x2e, 0x45, 0xd2, 0x01, 0xa3, 0x9b, 0x5d, 0x5b, + 0x00, 0x9f, 0x44, 0xac, 0x84, 0xab, 0x84, 0x84, + 0xaa, 0xa9, 0xa8, 0xa7, 0x84, 0xa6, 0x84, 0x84, + 0x84, 0xa5, 0xa4, 0xa3, 0xa2, 0xa6, 0x4b, 0xf6, + 0x18, 0x16, 0x2e, 0x34, 0xd2, 0x02, 0xa3, 0x9b, + 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0xc8, + 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, + 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8, + 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xed, 0x09, 0x00, + 0x95, 0x01, 0x6b, 0x46, 0x0c, 0x33, 0x45, 0x93, + 0x01, 0x33, 0x46, 0x93, 0x01, 0x33, 0x49, 0x93, + 0x01, 0x33, 0x4a, 0x93, 0x5a, 0xab, 0x41, 0x93, + 0x04, 0x33, 0x43, 0x93, 0x04, 0x33, 0x47, 0x93, + 0x40, 0x3b, 0x48, 0x93, 0x43, 0x9b, 0x40, 0x3b, + 0x44, 0x93, 0x41, 0x9b, 0x40, 0x3b, 0x42, 0x93, + 0x91, 0x4b, 0x9e, 0x42, 0x2b, 0xd0, 0x2b, 0xdc, + 0x90, 0x4b, 0x9e, 0x42, 0x29, 0xd0, 0x15, 0xdc, + 0x8f, 0x4b, 0xf6, 0x18, 0x03, 0xe0, 0xfa, 0xe0, + 0xee, 0xe0, 0x3b, 0xe1, 0x46, 0xe0, 0x0f, 0x2e, + 0x3f, 0xd2, 0x02, 0xa3, 0x9b, 0x5d, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0xac, 0xab, 0xaa, 0x40, + 0xa9, 0x40, 0xa8, 0x40, 0x40, 0xa7, 0xa6, 0xa5, + 0xa4, 0xa3, 0xa2, 0x00, 0x85, 0x4b, 0x9e, 0x42, + 0x30, 0xd0, 0x30, 0xdc, 0x06, 0x3b, 0x9e, 0x42, + 0x2e, 0xd0, 0x0b, 0xdc, 0x82, 0x4b, 0x9e, 0x42, + 0x2b, 0xd0, 0x01, 0x33, 0x9e, 0x42, 0x29, 0xd1, + 0xf9, 0x6b, 0x11, 0x70, 0x54, 0xe1, 0xc2, 0xe2, + 0x48, 0xe0, 0x67, 0xe2, 0x7d, 0x4b, 0x9e, 0x42, + 0x38, 0xd0, 0x02, 0x33, 0x9e, 0x42, 0x1d, 0xd1, + 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, + 0x10, 0x0a, 0x08, 0x70, 0x4b, 0x98, 0xc0, 0x6b, + 0x20, 0x70, 0x42, 0x9b, 0x4c, 0x98, 0xd9, 0x6b, + 0x01, 0x70, 0x4d, 0x98, 0x09, 0x0a, 0x01, 0x70, + 0x44, 0x98, 0x45, 0x9b, 0xc0, 0x6b, 0x18, 0x70, + 0x46, 0x9b, 0x00, 0x0a, 0x18, 0x70, 0x49, 0x98, + 0x32, 0xe1, 0x55, 0xe0, 0x77, 0xe2, 0x02, 0xe0, + 0x4d, 0xe2, 0x46, 0xe2, 0x89, 0xe0, 0x6c, 0x4b, + 0x9e, 0x42, 0x34, 0xd0, 0x6b, 0x4b, 0x9e, 0x42, + 0x32, 0xd0, 0x01, 0x33, 0x9e, 0x42, 0x46, 0xd0, + 0x69, 0x4b, 0x9e, 0x42, 0x44, 0xd1, 0xfb, 0x6b, + 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, + 0xed, 0x09, 0x00, 0x96, 0x01, 0x08, 0x70, 0x4b, + 0x98, 0xc0, 0x6b, 0x20, 0x70, 0x4c, 0x98, 0x15, + 0xe1, 0x50, 0xe2, 0x33, 0xe1, 0x2f, 0xe1, 0x26, + 0xe1, 0x1f, 0xe1, 0x10, 0xe1, 0x0c, 0xe1, 0x08, + 0xe1, 0x01, 0xe1, 0xf8, 0xe0, 0xf4, 0xe0, 0xf0, + 0xe0, 0x5d, 0x4b, 0x9e, 0x42, 0x34, 0xd0, 0x34, + 0xdc, 0x07, 0x3b, 0x9e, 0x42, 0x32, 0xd0, 0x32, + 0xdc, 0x5a, 0x4b, 0x9e, 0x42, 0x30, 0xd0, 0x22, + 0xdc, 0x02, 0x3b, 0x9e, 0x42, 0x2d, 0xd0, 0x58, + 0x4b, 0x9e, 0x42, 0x1b, 0xd1, 0xf9, 0x6b, 0x11, + 0x70, 0xf4, 0xe0, 0x41, 0xe2, 0x4b, 0xe2, 0xaa, + 0xe1, 0xa6, 0xe1, 0x9f, 0xe1, 0x96, 0xe1, 0x87, + 0xe1, 0x83, 0xe1, 0x7a, 0xe1, 0x76, 0xe1, 0x6b, + 0xe1, 0x67, 0xe1, 0x60, 0xe1, 0x5c, 0xe1, 0x55, + 0xe1, 0x51, 0xe1, 0x42, 0xe1, 0x3e, 0xe1, 0x2f, + 0xe1, 0x2b, 0xe1, 0x24, 0xe1, 0x20, 0xe1, 0x17, + 0xe1, 0x13, 0xe1, 0x42, 0xe2, 0x38, 0xe0, 0x49, + 0x4b, 0x9e, 0x42, 0x33, 0xd0, 0x01, 0x33, 0x9e, + 0x42, 0x31, 0xd1, 0xf9, 0x6b, 0x11, 0x70, 0xd1, + 0xe0, 0x9c, 0xe2, 0x1a, 0xe0, 0x5e, 0xe2, 0x0c, + 0xe0, 0x4c, 0xe2, 0x45, 0xe2, 0xda, 0xe1, 0xd6, + 0xe1, 0xc0, 0xe1, 0xb9, 0xe1, 0xb0, 0xe1, 0xa1, + 0xe1, 0x9d, 0xe1, 0x99, 0xe1, 0x95, 0xe1, 0x8e, + 0xe1, 0x82, 0xe1, 0x3d, 0x4b, 0xf1, 0x18, 0x06, + 0x29, 0x1a, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x91, 0x90, 0x8f, + 0x8e, 0x8d, 0x8c, 0x38, 0x4b, 0xf6, 0x18, 0x0a, + 0x2e, 0x0e, 0xd2, 0x02, 0xa3, 0x9b, 0x5d, 0x5b, + 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x92, 0x91, 0x90, + 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0xf9, + 0x6b, 0x11, 0x70, 0xa3, 0xe0, 0x25, 0xe2, 0x02, + 0xe3, 0x01, 0xe3, 0xf9, 0x6b, 0x11, 0x70, 0x9d, + 0xe0, 0xf9, 0x6b, 0xed, 0x09, 0x00, 0x97, 0x01, + 0x11, 0x70, 0xea, 0x6b, 0x00, 0x21, 0x53, 0x5c, + 0x01, 0x31, 0x03, 0x70, 0x01, 0x30, 0x06, 0x29, + 0xf9, 0xd3, 0x92, 0xe0, 0xf9, 0x6b, 0x11, 0x70, + 0xea, 0x6b, 0x00, 0x21, 0x53, 0x5c, 0x01, 0x31, + 0x03, 0x70, 0x01, 0x30, 0x06, 0x29, 0xf9, 0xd3, + 0x87, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0xea, 0x6b, + 0x00, 0x21, 0x53, 0x5c, 0x01, 0x31, 0x03, 0x70, + 0x01, 0x30, 0x06, 0x29, 0xf9, 0xd3, 0x7c, 0xe0, + 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x13, 0x1c, + 0x35, 0xe0, 0x2c, 0x0c, 0x00, 0x00, 0x15, 0x0c, + 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x0d, 0x04, + 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x03, 0x04, + 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x09, 0x08, + 0x00, 0x00, 0x0e, 0x04, 0x00, 0x00, 0x0c, 0x08, + 0x00, 0x00, 0xfd, 0xf3, 0xff, 0xff, 0xea, 0xf3, + 0xff, 0xff, 0x05, 0x14, 0x00, 0x00, 0x3c, 0x0c, + 0x00, 0x00, 0xd3, 0xf3, 0xff, 0xff, 0x07, 0x10, + 0x00, 0x00, 0x3d, 0x0c, 0x00, 0x00, 0x03, 0x10, + 0x00, 0x00, 0x09, 0x10, 0x00, 0x00, 0x01, 0x14, + 0x00, 0x00, 0x03, 0x14, 0x00, 0x00, 0x0a, 0xfc, + 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x02, 0x18, + 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0xfc, 0x03, + 0xff, 0xff, 0xf5, 0x03, 0xff, 0xff, 0x03, 0x70, + 0x10, 0x0a, 0x08, 0x70, 0x4b, 0x98, 0xc0, 0x6b, + 0x20, 0x70, 0x4c, 0x98, 0x39, 0xe0, 0xfb, 0x6b, + 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, + 0x08, 0x70, 0x4b, 0x98, 0xc0, 0x6b, 0x20, 0x70, + 0x4c, 0x9b, 0x00, 0x0a, 0x18, 0x70, 0x4d, 0x98, + 0x2b, 0xe0, 0xeb, 0xe1, 0xe7, 0xe1, 0x89, 0xe2, + 0xe2, 0xe1, 0xd2, 0xe1, 0xce, 0xe1, 0xf9, 0x6b, + 0x11, 0x70, 0x22, 0xe0, 0x73, 0xe2, 0x6c, 0xe2, + 0x68, 0xe2, 0x64, 0xe2, 0x60, 0xe2, 0xed, 0x09, + 0x00, 0x98, 0x01, 0x59, 0xe2, 0x55, 0xe2, 0xf7, + 0xe1, 0xf3, 0xe1, 0xe7, 0xe1, 0xf9, 0x6b, 0x11, + 0x70, 0x15, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0x12, + 0xe0, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, + 0x70, 0x10, 0x0a, 0x08, 0x70, 0x20, 0x1c, 0x0a, + 0xe0, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, + 0x70, 0x08, 0x1c, 0x04, 0xe0, 0xf9, 0x6b, 0x11, + 0x70, 0x01, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0x4b, + 0xe1, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, + 0x70, 0x10, 0x0a, 0x08, 0x70, 0x4b, 0x98, 0xc0, + 0x6b, 0x20, 0x70, 0x4c, 0x9b, 0x00, 0x0a, 0x18, + 0x70, 0x4d, 0x98, 0x3d, 0xe1, 0xfb, 0x6b, 0x13, + 0x70, 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, 0x37, + 0xe1, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, + 0x70, 0x10, 0x0a, 0x08, 0x70, 0x20, 0x1c, 0x2f, + 0xe1, 0xf9, 0x6b, 0x11, 0x70, 0x2c, 0xe1, 0xf9, + 0x6b, 0x11, 0x70, 0xec, 0x6b, 0x21, 0x1c, 0x07, + 0x1c, 0x0c, 0xf0, 0x6b, 0xfb, 0x20, 0x1c, 0x0c, + 0xf0, 0xb8, 0xfa, 0xc0, 0x19, 0x00, 0x21, 0x01, + 0x70, 0x01, 0x30, 0x1d, 0xe1, 0xfb, 0x6b, 0x13, + 0x70, 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, + 0x70, 0x20, 0x1c, 0x15, 0xe1, 0xf9, 0x6b, 0x11, + 0x70, 0x12, 0xe1, 0xfb, 0x6b, 0x13, 0x70, 0xea, + 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, 0x20, + 0x1c, 0x0a, 0xe1, 0xf9, 0x6b, 0x11, 0x70, 0x07, + 0xe1, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, + 0x70, 0x08, 0x1c, 0x01, 0xe1, 0xf9, 0x6b, 0x11, + 0x70, 0xfe, 0xe0, 0xfb, 0x6b, 0x13, 0x70, 0xea, + 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, 0x4b, + 0x98, 0xc0, 0x6b, 0x20, 0x70, 0x4c, 0x9b, 0x00, + 0x0a, 0x18, 0x70, 0x4d, 0x98, 0xf0, 0xe0, 0xf9, + 0x6b, 0x11, 0x70, 0xed, 0xe0, 0xfb, 0x6b, 0x13, + 0x70, 0xed, 0x09, 0x00, 0x99, 0x01, 0xea, 0x6b, + 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, 0x4b, 0x98, + 0xc0, 0x6b, 0x20, 0x70, 0x4c, 0x9b, 0x00, 0x0a, + 0x18, 0x70, 0x4d, 0x98, 0xdf, 0xe0, 0xf9, 0x6b, + 0x11, 0x70, 0xdc, 0xe0, 0xfb, 0x6b, 0x13, 0x70, + 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, 0xd6, 0xe0, + 0xf9, 0x6b, 0x11, 0x70, 0xd3, 0xe0, 0xfb, 0x6b, + 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, + 0xcd, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0xca, 0xe0, + 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, + 0x10, 0x0a, 0x08, 0x70, 0x10, 0x0c, 0x20, 0x70, + 0x4c, 0x98, 0xc0, 0xe0, 0xf9, 0x6b, 0x11, 0x70, + 0xbd, 0xe0, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, + 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, 0x20, 0x1c, + 0xb5, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0xb2, 0xe0, + 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, + 0x10, 0x0a, 0x08, 0x70, 0x4b, 0x98, 0xc0, 0x6b, + 0x20, 0x70, 0x4c, 0x9b, 0x00, 0x0a, 0x18, 0x70, + 0x4d, 0x98, 0xa4, 0xe0, 0xfb, 0x6b, 0x13, 0x70, + 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, + 0x20, 0x1c, 0x9c, 0xe0, 0xfb, 0x6b, 0x13, 0x70, + 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, 0x96, 0xe0, + 0xf9, 0x6b, 0x11, 0x70, 0x93, 0xe0, 0xfb, 0x6b, + 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, + 0x8d, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0x8a, 0xe0, + 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, + 0x10, 0x0a, 0x08, 0x70, 0x4b, 0x98, 0xc0, 0x6b, + 0x20, 0x70, 0x4c, 0x98, 0x7f, 0xe0, 0xfb, 0x6b, + 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, + 0x79, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0x76, 0xe0, + 0xf9, 0x6b, 0x11, 0x70, 0x73, 0xe0, 0xf9, 0x6b, + 0x11, 0x70, 0x70, 0xe0, 0xfb, 0x6b, 0x13, 0x70, + 0xea, 0x6b, 0x02, 0x70, 0xed, 0x09, 0x00, 0x9a, + 0x01, 0x10, 0x0a, 0x08, 0x70, 0x4b, 0x98, 0xc0, + 0x6b, 0x20, 0x70, 0x4c, 0x9b, 0x00, 0x0a, 0x18, + 0x70, 0x4d, 0x98, 0x62, 0xe0, 0xfb, 0x6b, 0x13, + 0x70, 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, + 0x70, 0x20, 0x1c, 0x5a, 0xe0, 0xfb, 0x6b, 0x13, + 0x70, 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, 0x54, + 0xe0, 0xfb, 0x6b, 0x00, 0x27, 0x13, 0x70, 0xea, + 0x6b, 0x02, 0x70, 0x4b, 0x9b, 0x08, 0x1c, 0xd9, + 0x6b, 0x00, 0x2a, 0x4a, 0xd9, 0x08, 0xc9, 0x03, + 0x70, 0x1c, 0x0a, 0x1b, 0x0c, 0x44, 0x70, 0x83, + 0x70, 0x03, 0x30, 0x01, 0x37, 0x97, 0x42, 0xf5, + 0xd3, 0x46, 0xe1, 0xf9, 0x6b, 0x11, 0x70, 0x43, + 0xe1, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, + 0x70, 0x08, 0x1c, 0x3d, 0xe1, 0xf9, 0x6b, 0x11, + 0x70, 0x3a, 0xe1, 0xfb, 0x6b, 0x13, 0x70, 0xea, + 0x6b, 0x02, 0x70, 0x08, 0x1c, 0x34, 0xe1, 0xfb, + 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x4b, + 0x98, 0xc0, 0x6b, 0x08, 0x70, 0x00, 0x0a, 0x20, + 0x70, 0x42, 0x9b, 0x4c, 0x98, 0xd9, 0x6b, 0x01, + 0x70, 0x44, 0x9b, 0x4d, 0x98, 0xd9, 0x6b, 0x01, + 0x70, 0x45, 0x9b, 0x08, 0x0a, 0x18, 0x70, 0x48, + 0x98, 0x46, 0x9b, 0xc0, 0x6b, 0x18, 0x70, 0x49, + 0x9b, 0x00, 0x0a, 0x18, 0x70, 0x4a, 0x98, 0x17, + 0xe1, 0xf9, 0x6b, 0x11, 0x70, 0xea, 0x6b, 0x00, + 0x21, 0x53, 0x5c, 0x01, 0x31, 0x03, 0x70, 0x01, + 0x30, 0x08, 0x29, 0xf9, 0xd3, 0x0c, 0xe1, 0xfb, + 0x6b, 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x08, + 0x1c, 0x06, 0xe1, 0x05, 0xe1, 0xf9, 0x6b, 0x11, + 0x70, 0xea, 0x6b, 0x00, 0x21, 0x53, 0x5c, 0x01, + 0x31, 0x03, 0x70, 0x01, 0x30, 0x06, 0x29, 0xf9, + 0xd3, 0xfa, 0xe0, 0xfb, 0x6b, 0x13, 0x70, 0xea, + 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, 0xed, + 0x09, 0x00, 0x9b, 0x01, 0x4b, 0x98, 0xc0, 0x6b, + 0x20, 0x70, 0x4c, 0x9b, 0x00, 0x0a, 0x18, 0x70, + 0x4d, 0x98, 0xec, 0xe0, 0xfb, 0x6b, 0x13, 0x70, + 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, + 0x20, 0x1c, 0xe4, 0xe0, 0xfb, 0x6b, 0x13, 0x70, + 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, 0x70, + 0x4b, 0x98, 0xc0, 0x6b, 0x20, 0x70, 0x4c, 0x98, + 0xd9, 0xe0, 0xfb, 0x6b, 0x13, 0x70, 0xea, 0x6b, + 0x02, 0x70, 0x08, 0x1c, 0xd3, 0xe0, 0xf9, 0x6b, + 0x11, 0x70, 0xd0, 0xe0, 0xfb, 0x6b, 0x0c, 0x1c, + 0x13, 0x70, 0xef, 0x6b, 0x07, 0x70, 0x4b, 0x98, + 0xc1, 0x6b, 0x20, 0x1c, 0x3a, 0x1c, 0xe6, 0xf7, + 0x08, 0xfe, 0xe0, 0x19, 0xc3, 0xe0, 0xfb, 0x6b, + 0x13, 0x70, 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, + 0x08, 0x70, 0x4b, 0x98, 0xc0, 0x6b, 0x20, 0x70, + 0x4c, 0x9b, 0x00, 0x0a, 0x18, 0x70, 0x42, 0x9b, + 0x4d, 0x98, 0xdf, 0x6b, 0x07, 0x70, 0x44, 0x98, + 0x45, 0x9c, 0xc1, 0x6b, 0x20, 0x1c, 0x3a, 0x1c, + 0xe6, 0xf7, 0xef, 0xfd, 0xe0, 0x19, 0xaa, 0xe0, + 0xf9, 0x6b, 0x11, 0x70, 0xa7, 0xe0, 0xf9, 0x6b, + 0x11, 0x70, 0xec, 0x6b, 0x21, 0x1c, 0x07, 0x1c, + 0x0c, 0xf0, 0xdf, 0xf9, 0x20, 0x1c, 0x0c, 0xf0, + 0x2c, 0xf9, 0xc0, 0x19, 0x00, 0x21, 0x01, 0x70, + 0x01, 0x30, 0x98, 0xe0, 0xf9, 0x6b, 0x11, 0x70, + 0x95, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0x92, 0xe0, + 0xf9, 0x6b, 0x11, 0x70, 0xea, 0x6b, 0x00, 0x21, + 0x53, 0x5c, 0x01, 0x31, 0x03, 0x70, 0x01, 0x30, + 0x10, 0x29, 0xf9, 0xd3, 0x87, 0xe0, 0xf9, 0x6b, + 0x11, 0x70, 0x84, 0xe0, 0xf9, 0x6b, 0x11, 0x70, + 0xea, 0x6b, 0x00, 0x21, 0x53, 0x5c, 0x01, 0x31, + 0x03, 0x70, 0x01, 0x30, 0x10, 0x29, 0xf9, 0xd3, + 0x79, 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0x76, 0xe0, + 0xfb, 0x6b, 0xed, 0x09, 0x00, 0x9c, 0x01, 0x13, + 0x70, 0xea, 0x6b, 0x02, 0x70, 0x10, 0x0a, 0x08, + 0x70, 0x10, 0x0c, 0x20, 0x70, 0x4c, 0x98, 0x11, + 0x0e, 0x01, 0x70, 0x4b, 0x9b, 0x4d, 0x98, 0xd9, + 0x6b, 0x01, 0x70, 0x45, 0x9b, 0x08, 0x0a, 0x18, + 0x70, 0x46, 0x9b, 0x08, 0x0c, 0x18, 0x70, 0x49, + 0x9b, 0x08, 0x0e, 0x18, 0x70, 0x42, 0x98, 0x4a, + 0x9b, 0xc0, 0x6b, 0x18, 0x70, 0x02, 0x0a, 0x5a, + 0x70, 0x02, 0x0c, 0x00, 0x0e, 0x9a, 0x70, 0xd8, + 0x70, 0xd9, 0x1c, 0x44, 0x9b, 0x48, 0x1c, 0xd9, + 0x6b, 0x01, 0x70, 0x0a, 0x0a, 0x42, 0x70, 0x0a, + 0x0c, 0x82, 0x70, 0x09, 0x0e, 0xc1, 0x70, 0x48, + 0x99, 0x47, 0x9b, 0xc9, 0x6b, 0x01, 0x71, 0x0a, + 0x0a, 0x42, 0x71, 0x0a, 0x0c, 0x82, 0x71, 0x09, + 0x0e, 0xc1, 0x71, 0x07, 0x30, 0x41, 0x1c, 0x18, + 0x1d, 0xc2, 0x1f, 0x39, 0x3a, 0xd2, 0x6b, 0x0a, + 0x70, 0x13, 0x0a, 0x4b, 0x70, 0x13, 0x0c, 0x8b, + 0x70, 0x12, 0x0e, 0xca, 0x70, 0x03, 0x31, 0x4a, + 0x1c, 0x01, 0x1d, 0xc8, 0x1f, 0x39, 0x38, 0xc0, + 0x6b, 0x10, 0x70, 0x03, 0x0a, 0x53, 0x70, 0x03, + 0x0c, 0x93, 0x70, 0x00, 0x0e, 0xd0, 0x70, 0x09, + 0x68, 0x03, 0x32, 0x50, 0x1c, 0x01, 0x70, 0x0a, + 0x0a, 0x42, 0x70, 0x0a, 0x0c, 0x82, 0x70, 0x09, + 0x0e, 0xc1, 0x70, 0x04, 0x30, 0x19, 0xe0, 0xf9, + 0x6b, 0x11, 0x70, 0x16, 0xe0, 0xfb, 0x6b, 0x13, + 0x70, 0xea, 0x6b, 0x02, 0x70, 0x08, 0x1c, 0x10, + 0xe0, 0xf9, 0x6b, 0x11, 0x70, 0x0d, 0xe0, 0xf9, + 0x6b, 0x11, 0x70, 0x0a, 0xe0, 0xf9, 0x6b, 0x11, + 0x70, 0x07, 0xe0, 0xfb, 0x6b, 0x13, 0x70, 0xea, + 0x6b, 0x02, 0x70, 0x08, 0x1c, 0x01, 0xe0, 0xf9, + 0x6b, 0x11, 0x70, 0x69, 0x46, 0x41, 0x1a, 0xc8, + 0x1e, 0x00, 0xab, 0x98, 0x70, 0x68, 0x46, 0xfc, + 0xf7, 0x0e, 0xf8, 0x4f, 0xb0, 0xed, 0x09, 0x00, + 0x9d, 0x01, 0xf0, 0xbc, 0x08, 0xbc, 0x04, 0xb0, + 0x18, 0x47, 0xf9, 0xe7, 0x80, 0xb5, 0x00, 0x27, + 0x0b, 0xf0, 0xfe, 0xfa, 0x38, 0x1c, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x00, 0x27, + 0x38, 0x30, 0x01, 0x21, 0x04, 0x1c, 0x1b, 0xf0, + 0x35, 0xff, 0x02, 0x28, 0x05, 0xd3, 0x01, 0x21, + 0x20, 0x1c, 0x1b, 0xf0, 0x2b, 0xff, 0xff, 0x27, + 0x0f, 0x37, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0x0f, 0x1c, 0x01, 0x21, + 0x38, 0x30, 0x04, 0x1c, 0x1b, 0xf0, 0x1e, 0xff, + 0x00, 0x28, 0x03, 0xd1, 0x01, 0x21, 0x20, 0x1c, + 0x1b, 0xf0, 0x1c, 0xff, 0x38, 0x1c, 0x0e, 0xf0, + 0x63, 0xfd, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xb0, 0xb4, 0x00, 0x23, 0x00, 0x29, 0x0e, 0xd9, + 0x08, 0x4c, 0x07, 0x78, 0x15, 0x12, 0x7a, 0x40, + 0x12, 0x06, 0x12, 0x0e, 0x52, 0x00, 0xa2, 0x5a, + 0x6a, 0x40, 0x12, 0x04, 0x12, 0x0c, 0x01, 0x30, + 0x01, 0x33, 0x8b, 0x42, 0xf1, 0xd3, 0xb0, 0xbc, + 0x10, 0x1c, 0x70, 0x47, 0x18, 0xe0, 0x03, 0x20, + 0x80, 0xb5, 0x82, 0xb0, 0x13, 0x48, 0xc7, 0x6b, + 0x00, 0x2f, 0x1e, 0xd0, 0xb8, 0x68, 0x00, 0x28, + 0x0e, 0xd0, 0x78, 0x6b, 0x09, 0xf0, 0x10, 0xfa, + 0x02, 0x1c, 0xb8, 0x68, 0x81, 0x68, 0x01, 0x92, + 0x00, 0x91, 0x79, 0x69, 0xbb, 0x6b, 0x3a, 0x1c, + 0x0b, 0xa0, 0xfb, 0xf7, 0x7f, 0xfa, 0x09, 0xe0, + 0x78, 0x6b, 0x09, 0xf0, 0x01, 0xfa, 0x00, 0x90, + 0x79, 0x69, 0xbb, 0x6b, 0x18, 0xa0, 0x3a, 0x1c, + 0xfb, 0xf7, 0x74, 0xfa, 0x3f, 0x68, 0x00, 0x2f, + 0xe0, 0xd1, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, + 0x3c, 0x25, 0x75, 0x3e, 0x2c, 0x20, 0x25, 0x23, + 0x70, 0x2c, 0x20, 0x48, 0x63, 0x4d, 0x69, 0x73, + 0xed, 0x09, 0x00, 0x9e, 0x01, 0x63, 0x53, 0x68, + 0x6f, 0x77, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x2c, + 0x20, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x25, 0x75, + 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x7b, 0x25, 0x75, 0x7d, + 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, 0x0a, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x25, 0x75, + 0x3e, 0x2c, 0x20, 0x25, 0x23, 0x70, 0x2c, 0x20, + 0x48, 0x63, 0x4d, 0x69, 0x73, 0x63, 0x53, 0x68, + 0x6f, 0x77, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x2c, + 0x20, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x25, 0x75, + 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, 0x0a, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb5, 0x82, + 0xb0, 0x14, 0x1c, 0x07, 0x1c, 0x02, 0x78, 0x40, + 0x78, 0x03, 0x07, 0x1b, 0x0f, 0x1b, 0x02, 0x13, + 0x43, 0x1d, 0x1c, 0x02, 0x29, 0x20, 0xd1, 0x01, + 0x09, 0x8e, 0x07, 0xb6, 0x0f, 0x80, 0x09, 0x82, + 0x07, 0x92, 0x0f, 0x01, 0x92, 0xb8, 0x78, 0xf9, + 0x78, 0x09, 0x02, 0x01, 0x43, 0x0b, 0x1c, 0x00, + 0x91, 0x0e, 0xf0, 0x9e, 0xfc, 0x00, 0x9b, 0x39, + 0x1d, 0xc1, 0x61, 0x83, 0x61, 0x00, 0x22, 0x02, + 0x62, 0x10, 0x49, 0x42, 0x62, 0x01, 0x63, 0xc4, + 0x62, 0x03, 0x1c, 0x28, 0x1c, 0x31, 0x1c, 0x01, + 0x9a, 0xfd, 0xf7, 0x4e, 0xfd, 0x00, 0x20, 0x10, + 0xe0, 0xbe, 0x78, 0x0e, 0xf0, 0x89, 0xfc, 0x00, + 0x22, 0x82, 0x61, 0xc2, 0x61, 0xf9, 0x1c, 0x41, + 0x62, 0x06, 0x49, 0x06, 0x62, 0x01, 0x63, 0xc4, + 0x62, 0x01, 0x1c, 0x28, 0x1c, 0xfd, 0xf7, 0xb2, + 0xfd, 0x00, 0x20, 0x02, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xcd, 0x6a, 0x02, + 0x20, 0xf0, 0xb5, 0xed, 0x09, 0x00, 0x9f, 0x01, + 0x82, 0xb0, 0x6d, 0x46, 0x02, 0x26, 0x1f, 0x1c, + 0x00, 0xab, 0x07, 0x9c, 0x1e, 0x70, 0x58, 0x70, + 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0f, 0x89, 0x07, + 0x89, 0x0f, 0x09, 0x01, 0x08, 0x43, 0xa8, 0x70, + 0xa9, 0x78, 0x90, 0x01, 0x08, 0x43, 0xab, 0x1c, + 0x21, 0x0a, 0xa8, 0x70, 0x5c, 0x70, 0x99, 0x70, + 0x00, 0x2c, 0x05, 0xd1, 0x68, 0x46, 0x0c, 0x22, + 0x05, 0x21, 0x09, 0xf0, 0x6a, 0xfa, 0x09, 0xe0, + 0x68, 0x46, 0x04, 0x22, 0x05, 0x21, 0x09, 0xf0, + 0x64, 0xfa, 0x08, 0x22, 0x38, 0x1c, 0x21, 0x1c, + 0x09, 0xf0, 0x5f, 0xfa, 0x02, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x98, 0xb5, 0x0c, 0x1c, + 0x69, 0x46, 0x17, 0x1c, 0x03, 0x22, 0x00, 0xab, + 0x1a, 0x70, 0x58, 0x70, 0x00, 0x0a, 0x00, 0x07, + 0x00, 0x0f, 0x88, 0x70, 0x02, 0x31, 0x48, 0x1c, + 0x07, 0x70, 0x00, 0x2f, 0x05, 0xd1, 0x68, 0x46, + 0x0c, 0x22, 0x04, 0x21, 0x09, 0xf0, 0x45, 0xfa, + 0x09, 0xe0, 0x68, 0x46, 0x04, 0x22, 0x04, 0x21, + 0x09, 0xf0, 0x3f, 0xfa, 0x08, 0x22, 0x20, 0x1c, + 0x39, 0x1c, 0x09, 0xf0, 0x3a, 0xfa, 0x98, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb5, + 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x93, 0x07, + 0x9b, 0x0f, 0x1b, 0x02, 0x18, 0x43, 0x93, 0x08, + 0x8a, 0x78, 0x03, 0x31, 0x04, 0x2b, 0x1b, 0xd0, + 0x0b, 0xdc, 0x00, 0x2b, 0x07, 0xd0, 0x01, 0x2b, + 0x10, 0xd0, 0x02, 0x2b, 0x11, 0xd0, 0x03, 0x2b, + 0x01, 0xd1, 0x00, 0xf0, 0x03, 0xf9, 0x08, 0xbc, + 0x18, 0x47, 0x05, 0x2b, 0x0f, 0xd0, 0x06, 0x2b, + 0x10, 0xd0, 0x3f, 0x2b, 0xf7, 0xd1, 0x00, 0xf0, + 0xa1, 0xfa, 0xf4, 0xe7, 0x00, 0xf0, 0x0d, 0xf8, + 0xf1, 0xe7, 0x00, 0xf0, 0xaf, 0xf8, 0xee, 0xe7, + 0x00, 0xf0, 0x39, 0xfa, 0xeb, 0xe7, 0xed, 0x09, + 0x00, 0xa0, 0x01, 0x00, 0xf0, 0x5e, 0xfa, 0xe8, + 0xe7, 0x00, 0xf0, 0x7a, 0xfa, 0xe5, 0xe7, 0x80, + 0xb5, 0x0f, 0x1c, 0x29, 0x28, 0x01, 0xd2, 0x43, + 0x00, 0x9f, 0x44, 0x2c, 0xe0, 0x2b, 0xe0, 0x26, + 0xe0, 0x2c, 0xe0, 0x30, 0xe0, 0x34, 0xe0, 0x38, + 0xe0, 0x3c, 0xe0, 0x40, 0xe0, 0x23, 0xe0, 0x43, + 0xe0, 0x47, 0xe0, 0x4b, 0xe0, 0x4f, 0xe0, 0x53, + 0xe0, 0x57, 0xe0, 0x5b, 0xe0, 0x1b, 0xe0, 0x5e, + 0xe0, 0x19, 0xe0, 0x61, 0xe0, 0x17, 0xe0, 0x64, + 0xe0, 0x15, 0xe0, 0x67, 0xe0, 0x13, 0xe0, 0x6a, + 0xe0, 0x11, 0xe0, 0x6d, 0xe0, 0x0f, 0xe0, 0x70, + 0xe0, 0x0d, 0xe0, 0x73, 0xe0, 0x0b, 0xe0, 0x0a, + 0xe0, 0x09, 0xe0, 0x08, 0xe0, 0x07, 0xe0, 0x06, + 0xe0, 0x05, 0xe0, 0x04, 0xe0, 0x6f, 0xe0, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xd2, 0xfa, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0xdc, 0xfa, 0xf7, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xdc, 0xfa, 0xf2, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xf6, + 0xfa, 0xed, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0xf6, 0xfa, 0xe8, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x1d, 0xfb, 0xe3, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x23, 0xfb, 0xde, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x2c, + 0xfb, 0xd9, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x40, 0xfb, 0xd4, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x53, 0xfb, 0xcf, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x76, 0xfb, 0xca, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x89, + 0xfb, 0xc5, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0xac, 0xfb, 0xc0, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0xbf, 0xfb, 0xbb, 0xe7, 0x38, + 0x1c, 0xed, 0x09, 0x00, 0xa1, 0x01, 0x11, 0x1c, + 0x00, 0xf0, 0xc8, 0xfb, 0xb6, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0xcc, 0xfb, 0xb1, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xd2, 0xfb, + 0xac, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0xd6, 0xfb, 0xa7, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0xd7, 0xfb, 0xa2, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0xef, 0xfb, 0x9d, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xf3, 0xfb, + 0x98, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0xf7, 0xfb, 0x93, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0xfb, 0xfb, 0x8e, 0xe7, 0x80, 0xb5, + 0x0f, 0x1c, 0x0e, 0x28, 0x0f, 0xd2, 0x02, 0xa3, + 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, + 0x0b, 0x07, 0x0b, 0x0e, 0x13, 0x18, 0x1d, 0x22, + 0x0b, 0x27, 0x0b, 0x2c, 0x31, 0x36, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0xfd, 0xfb, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x0b, 0xfc, 0xf7, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x28, 0xfc, 0xf2, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x2c, 0xfc, + 0xed, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x3c, 0xfc, 0xe8, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x40, 0xfc, 0xe3, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x7d, 0xfc, 0xde, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x81, 0xfc, + 0xd9, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x95, 0xfc, 0xd4, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x99, 0xfc, 0xcf, 0xe7, 0x80, 0xb5, + 0x0f, 0x1c, 0x3f, 0x28, 0x03, 0xd2, 0x02, 0xa3, + 0x1b, 0x18, 0x1b, 0x5a, 0x9f, 0x44, 0x42, 0xe0, + 0x86, 0x00, 0x7e, 0x00, 0x86, 0x00, 0x8c, 0x00, + 0x86, 0x00, 0x96, 0x00, 0xed, 0x09, 0x00, 0xa2, + 0x01, 0x86, 0x00, 0x86, 0x00, 0xa0, 0x00, 0xaa, + 0x00, 0xb4, 0x00, 0xbe, 0x00, 0x86, 0x00, 0xc8, + 0x00, 0x86, 0x00, 0x86, 0x00, 0x86, 0x00, 0xd2, + 0x00, 0xdc, 0x00, 0xe6, 0x00, 0xf0, 0x00, 0xfa, + 0x00, 0x04, 0x01, 0x0e, 0x01, 0x18, 0x01, 0x22, + 0x01, 0x2c, 0x01, 0x36, 0x01, 0x40, 0x01, 0x4a, + 0x01, 0x54, 0x01, 0x5e, 0x01, 0x68, 0x01, 0x72, + 0x01, 0x7c, 0x01, 0x86, 0x01, 0x90, 0x01, 0x9a, + 0x01, 0xa4, 0x01, 0xae, 0x01, 0xb8, 0x01, 0xc2, + 0x01, 0xcc, 0x01, 0xd6, 0x01, 0xe0, 0x01, 0xea, + 0x01, 0xf4, 0x01, 0xfe, 0x01, 0x86, 0x00, 0x08, + 0x02, 0x86, 0x00, 0x12, 0x02, 0x86, 0x00, 0x1c, + 0x02, 0x26, 0x02, 0x30, 0x02, 0x3a, 0x02, 0x44, + 0x02, 0x4e, 0x02, 0x58, 0x02, 0x62, 0x02, 0x6c, + 0x02, 0x76, 0x02, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x5a, 0xfc, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x6a, + 0xfc, 0xf7, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x6a, 0xfc, 0xf2, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0xfc, 0xfc, 0xed, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x00, 0xfd, 0xe8, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x00, + 0xfd, 0xe3, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x01, 0xfd, 0xde, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x01, 0xfd, 0xd9, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x15, 0xfd, 0xd4, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x55, + 0xfd, 0xcf, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x69, 0xfd, 0xca, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x86, 0xfd, 0xc5, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x86, 0xfd, 0xc0, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xed, + 0x09, 0x00, 0xa3, 0x01, 0x86, 0xfd, 0xbb, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x8a, 0xfd, + 0xb6, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x8a, 0xfd, 0xb1, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x8e, 0xfd, 0xac, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x8e, 0xfd, 0xa7, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x8f, 0xfd, + 0xa2, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x8f, 0xfd, 0x9d, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x98, 0xfd, 0x98, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x98, 0xfd, 0x93, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xa1, 0xfd, + 0x8e, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0xa1, 0xfd, 0x89, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0xa2, 0xfd, 0x84, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0xa2, 0xfd, 0x7f, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xa3, 0xfd, + 0x7a, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0xa3, 0xfd, 0x75, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0xab, 0xfd, 0x70, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0xab, 0xfd, 0x6b, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xaf, 0xfd, + 0x66, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0xb3, 0xfd, 0x61, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0xbc, 0xfd, 0x5c, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0xbc, 0xfd, 0x57, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xbd, 0xfd, + 0x52, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0xbd, 0xfd, 0x4d, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0xbe, 0xfd, 0x48, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0xc4, 0xfd, 0x43, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xc4, 0xfd, + 0x3e, 0xe7, 0xed, 0x09, 0x00, 0xa4, 0x01, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xc5, 0xfd, 0x39, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xc6, + 0xfd, 0x34, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0xd8, 0xfd, 0x2f, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x0e, 0xfe, 0x2a, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x12, 0xfe, 0x25, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x1b, + 0xfe, 0x20, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x1b, 0xfe, 0x1b, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x1b, 0xfe, 0x16, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x3e, 0xfe, 0x11, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x3e, + 0xfe, 0x0c, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x3f, 0xfe, 0x07, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x3f, 0xfe, 0x02, 0xe7, 0x80, + 0xb5, 0x0f, 0x1c, 0x0a, 0x28, 0x0c, 0xd2, 0x01, + 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x08, + 0x04, 0x08, 0x0b, 0x08, 0x10, 0x08, 0x15, 0x08, + 0x1a, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x33, + 0xfe, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x31, 0xfe, 0xf7, + 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x31, + 0xfe, 0xf2, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x31, 0xfe, 0xed, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0x31, 0xfe, 0xe8, 0xe7, 0x00, + 0xb5, 0x0b, 0x1c, 0x01, 0x28, 0x0b, 0xd0, 0x02, + 0x28, 0x0e, 0xd0, 0x03, 0x28, 0x11, 0xd0, 0x05, + 0x28, 0x03, 0xd1, 0x18, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0x42, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x18, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x21, 0xfe, 0xf8, + 0xe7, 0x18, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x25, + 0xfe, 0xf3, 0xe7, 0x18, 0x1c, 0xed, 0x09, 0x00, + 0xa5, 0x01, 0x11, 0x1c, 0x00, 0xf0, 0x29, 0xfe, + 0xee, 0xe7, 0x00, 0xb5, 0x0b, 0x1c, 0x01, 0x28, + 0x09, 0xd0, 0x02, 0x28, 0x0c, 0xd0, 0x03, 0x28, + 0x03, 0xd1, 0x18, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x39, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x18, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x28, 0xfe, 0xf8, 0xe7, + 0x18, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x28, 0xfe, + 0xf3, 0xe7, 0x80, 0xb5, 0x0f, 0x1c, 0x15, 0x28, + 0x13, 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, + 0x9f, 0x44, 0x00, 0x1c, 0x0f, 0x0b, 0x12, 0x17, + 0x1c, 0x21, 0x26, 0x0f, 0x2b, 0x30, 0x35, 0x3a, + 0x3f, 0x44, 0x49, 0x4e, 0x53, 0x58, 0x5d, 0x62, + 0x67, 0x00, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x1a, 0xfe, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x1c, 0xfe, + 0xf7, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x40, 0xfe, 0xf2, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x40, 0xfe, 0xed, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x5d, 0xfe, 0xe8, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x5d, 0xfe, + 0xe3, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x6f, 0xfe, 0xde, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x84, 0xfe, 0xd9, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x84, 0xfe, 0xd4, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x9c, 0xfe, + 0xcf, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x9d, 0xfe, 0xca, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0x00, 0xf0, 0x09, 0xff, 0xc5, 0xe7, 0x38, 0x1c, + 0x11, 0x1c, 0x00, 0xf0, 0x09, 0xff, 0xc0, 0xe7, + 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x0c, 0xff, + 0xbb, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, 0xf0, + 0x0d, 0xff, 0xb6, 0xe7, 0x38, 0x1c, 0x11, 0x1c, + 0xed, 0x09, 0x00, 0xa6, 0x01, 0x00, 0xf0, 0xb2, + 0xff, 0xb1, 0xe7, 0x38, 0x1c, 0x11, 0x1c, 0x00, + 0xf0, 0xc4, 0xff, 0xac, 0xe7, 0x38, 0x1c, 0x11, + 0x1c, 0x00, 0xf0, 0xc8, 0xff, 0xa7, 0xe7, 0x38, + 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0xec, 0xff, 0xa2, + 0xe7, 0x00, 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, + 0x78, 0x12, 0x02, 0x10, 0x43, 0x8a, 0x78, 0x12, + 0x04, 0x10, 0x43, 0x03, 0x31, 0x0a, 0x1c, 0x09, + 0x78, 0x52, 0x78, 0xfb, 0xf7, 0x7b, 0xfb, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfb, 0xf7, 0x90, + 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x88, 0xb5, 0x01, + 0x1c, 0x4a, 0x1c, 0x49, 0x78, 0x00, 0x78, 0x09, + 0x02, 0x08, 0x43, 0x51, 0x78, 0x01, 0x32, 0x53, + 0x1c, 0x52, 0x78, 0x9f, 0x78, 0x12, 0x02, 0x11, + 0x43, 0x5a, 0x78, 0x3f, 0x02, 0x3a, 0x43, 0xdf, + 0x78, 0x3f, 0x04, 0x17, 0x43, 0x04, 0x33, 0x1a, + 0x1c, 0x1b, 0x78, 0x52, 0x78, 0x00, 0x92, 0x3a, + 0x1c, 0xfb, 0xf7, 0x86, 0xfb, 0x88, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfb, 0xf7, 0x8e, + 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, + 0xb0, 0x13, 0x4f, 0x02, 0xa9, 0x18, 0xcf, 0x18, + 0xc1, 0x00, 0x21, 0x03, 0x78, 0x02, 0xaa, 0x01, + 0x30, 0x53, 0x54, 0x01, 0x31, 0x06, 0x29, 0xf8, + 0xd3, 0x01, 0x1c, 0x4a, 0x1c, 0x49, 0x78, 0x00, + 0x78, 0x09, 0x02, 0x08, 0x43, 0x01, 0x32, 0x17, + 0x78, 0x53, 0x78, 0x51, 0x1c, 0x4a, 0x1c, 0x54, + 0x78, 0x49, 0x78, 0x92, 0x78, 0x24, 0x02, 0x21, + 0x43, 0x00, 0x91, 0x01, 0x1c, 0x01, 0x92, 0x3a, + 0x1c, 0x02, 0xa8, 0xfb, 0xf7, 0x75, 0xfb, 0x04, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0xdc, 0x5c, 0x03, 0x20, 0x00, 0xb5, 0x01, + 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x89, 0x78, 0x12, + 0x02, 0x10, 0x43, 0xed, 0x09, 0x00, 0xa7, 0x01, + 0xfb, 0xf7, 0xc7, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, + 0x12, 0x02, 0x10, 0x43, 0x8a, 0x78, 0xc9, 0x78, + 0x09, 0x02, 0x11, 0x43, 0xfb, 0xf7, 0x47, 0xfc, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x82, 0xb0, + 0x0a, 0x4f, 0x69, 0x46, 0x0c, 0xcf, 0x0c, 0xc1, + 0x00, 0x21, 0x03, 0x78, 0x6a, 0x46, 0x01, 0x30, + 0x53, 0x54, 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3, + 0x01, 0x78, 0x68, 0x46, 0xfb, 0xf7, 0x7d, 0xfc, + 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xe4, 0x5c, 0x03, 0x20, 0x80, 0xb5, + 0x82, 0xb0, 0x09, 0x4f, 0x69, 0x46, 0x0c, 0xcf, + 0x0c, 0xc1, 0x00, 0x21, 0x03, 0x78, 0x6a, 0x46, + 0x01, 0x30, 0x53, 0x54, 0x01, 0x31, 0x06, 0x29, + 0xf8, 0xd3, 0x01, 0x78, 0x68, 0x46, 0xfb, 0xf7, + 0xdc, 0xfc, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xec, 0x5c, 0x03, 0x20, 0x80, 0xb5, + 0x86, 0xb0, 0x10, 0x4f, 0x04, 0xa9, 0x0c, 0xcf, + 0x0c, 0xc1, 0x0f, 0x4f, 0x69, 0x46, 0x0c, 0xcf, + 0x0c, 0xc1, 0x0c, 0xcf, 0x0c, 0xc1, 0x00, 0x21, + 0x02, 0x78, 0x04, 0xab, 0x01, 0x30, 0x5a, 0x54, + 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3, 0x00, 0x21, + 0x02, 0x78, 0x6b, 0x46, 0x01, 0x30, 0x5a, 0x54, + 0x01, 0x31, 0x10, 0x29, 0xf8, 0xd3, 0x69, 0x46, + 0x04, 0xa8, 0xfb, 0xf7, 0x48, 0xfd, 0x06, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf4, 0x5c, + 0x03, 0x20, 0xfc, 0x5c, 0x03, 0x20, 0x80, 0xb5, + 0x82, 0xb0, 0x09, 0x4f, 0x69, 0x46, 0x0c, 0xcf, + 0x0c, 0xc1, 0x00, 0x21, 0x02, 0x78, 0x6b, 0x46, + 0x01, 0x30, 0x5a, 0x54, 0x01, 0x31, 0x06, 0x29, + 0xf8, 0xd3, 0x68, 0x46, 0xfb, 0xf7, 0x71, 0xfd, + 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0xed, 0x09, + 0x00, 0xa8, 0x01, 0x18, 0x47, 0x00, 0x00, 0x0c, + 0x5d, 0x03, 0x20, 0x80, 0xb5, 0x86, 0xb0, 0x10, + 0x4f, 0x04, 0xa9, 0x0c, 0xcf, 0x0c, 0xc1, 0x0f, + 0x4f, 0x69, 0x46, 0x0c, 0xcf, 0x0c, 0xc1, 0x0c, + 0xcf, 0x0c, 0xc1, 0x00, 0x21, 0x03, 0x78, 0x04, + 0xaa, 0x01, 0x30, 0x53, 0x54, 0x01, 0x31, 0x06, + 0x29, 0xf8, 0xd3, 0x07, 0x78, 0x41, 0x1c, 0x68, + 0x46, 0x3a, 0x1c, 0xe5, 0xf7, 0xa6, 0xff, 0x6a, + 0x46, 0x39, 0x1c, 0x04, 0xa8, 0xfb, 0xf7, 0x85, + 0xfd, 0x06, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x14, 0x5d, 0x03, 0x20, 0x1c, + 0x5d, 0x03, 0x20, 0x80, 0xb5, 0x82, 0xb0, 0x09, + 0x4f, 0x69, 0x46, 0x0c, 0xcf, 0x0c, 0xc1, 0x00, + 0x21, 0x02, 0x78, 0x6b, 0x46, 0x01, 0x30, 0x5a, + 0x54, 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3, 0x68, + 0x46, 0xfb, 0xf7, 0xaf, 0xfd, 0x02, 0xb0, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x2c, + 0x5d, 0x03, 0x20, 0x00, 0xb5, 0x01, 0x1c, 0x4a, + 0x78, 0x00, 0x78, 0x12, 0x02, 0x10, 0x43, 0x8a, + 0x78, 0xc9, 0x78, 0x09, 0x02, 0x11, 0x43, 0xfb, + 0xf7, 0xd6, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, + 0x43, 0xfb, 0xf7, 0x2f, 0xfe, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, + 0x78, 0x89, 0x78, 0x12, 0x02, 0x10, 0x43, 0xfb, + 0xf7, 0x72, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, + 0x43, 0xfb, 0xf7, 0xc5, 0xfe, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0x78, 0xfb, 0xf7, 0xe9, + 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x82, + 0xb0, 0x0c, 0x4f, 0x69, 0x46, 0x0c, 0xcf, 0x0c, + 0xc1, 0x00, 0x21, 0x03, 0x78, 0x6a, 0x46, 0x01, + 0x30, 0xed, 0x09, 0x00, 0xa9, 0x01, 0x53, 0x54, + 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3, 0x01, 0x78, + 0x42, 0x78, 0x83, 0x78, 0xc0, 0x78, 0x00, 0x02, + 0x03, 0x43, 0x68, 0x46, 0xfb, 0xf7, 0xde, 0xfe, + 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x34, 0x5d, 0x03, 0x20, 0x00, 0xb5, 0x01, 0x78, + 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, 0xfb, 0xf7, + 0x01, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, + 0xfb, 0xf7, 0x22, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, + 0x08, 0x43, 0xfb, 0xf7, 0x43, 0xff, 0x08, 0xbc, + 0x18, 0x47, 0x80, 0xb5, 0x82, 0xb0, 0x09, 0x4f, + 0x69, 0x46, 0x0c, 0xcf, 0x0c, 0xc1, 0x00, 0x21, + 0x02, 0x78, 0x6b, 0x46, 0x01, 0x30, 0x5a, 0x54, + 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3, 0x68, 0x46, + 0xfb, 0xf7, 0xda, 0xfa, 0x02, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x3c, 0x5d, 0x03, 0x20, + 0x00, 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, + 0x12, 0x02, 0x10, 0x43, 0x02, 0x31, 0x0a, 0x1c, + 0x53, 0x1c, 0x52, 0x78, 0x09, 0x78, 0x12, 0x02, + 0x11, 0x43, 0x5a, 0x78, 0x9b, 0x78, 0x1b, 0x02, + 0x1a, 0x43, 0xfb, 0xf7, 0x41, 0xff, 0x08, 0xbc, + 0x18, 0x47, 0x98, 0xb5, 0x01, 0x1c, 0x4a, 0x1c, + 0x49, 0x78, 0x00, 0x78, 0x09, 0x02, 0x08, 0x43, + 0x51, 0x78, 0x01, 0x32, 0x53, 0x1c, 0x52, 0x78, + 0x9f, 0x78, 0x12, 0x02, 0x11, 0x43, 0x5a, 0x78, + 0x3f, 0x02, 0x17, 0x43, 0xda, 0x78, 0x03, 0x33, + 0x5c, 0x1c, 0x5b, 0x78, 0x1b, 0x02, 0x13, 0x43, + 0x62, 0x78, 0xa4, 0x78, 0x24, 0x02, 0x22, 0x43, + 0x00, 0x92, 0x3a, 0x1c, 0xfb, 0xf7, 0x2e, 0xff, + 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0x01, 0x78, 0x40, 0x78, 0xed, 0x09, 0x00, 0xaa, + 0x01, 0x00, 0x02, 0x08, 0x43, 0xfb, 0xf7, 0x32, + 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, + 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x12, 0x02, 0x10, + 0x43, 0x02, 0x31, 0x0a, 0x1c, 0x53, 0x1c, 0x52, + 0x78, 0x09, 0x78, 0x12, 0x02, 0x11, 0x43, 0x5a, + 0x78, 0x9b, 0x78, 0x1b, 0x02, 0x1a, 0x43, 0xfb, + 0xf7, 0x2b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, + 0x43, 0xfb, 0xf7, 0x30, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x84, 0xb0, 0x42, 0x78, 0x01, + 0x78, 0x85, 0x78, 0x12, 0x02, 0x0a, 0x43, 0xc4, + 0x78, 0x03, 0x30, 0x41, 0x1c, 0x17, 0x1c, 0x4a, + 0x78, 0x40, 0x78, 0x4e, 0x7a, 0x12, 0x02, 0x10, + 0x43, 0x8a, 0x78, 0x12, 0x04, 0x10, 0x43, 0xca, + 0x78, 0x12, 0x06, 0x02, 0x43, 0x13, 0x1c, 0x4a, + 0x79, 0x08, 0x79, 0x12, 0x02, 0x10, 0x43, 0x8a, + 0x79, 0x12, 0x04, 0x10, 0x43, 0xca, 0x79, 0x12, + 0x06, 0x10, 0x43, 0x0a, 0x7a, 0x36, 0x02, 0x32, + 0x43, 0x8e, 0x7a, 0x36, 0x04, 0x32, 0x43, 0xce, + 0x7a, 0x36, 0x06, 0x32, 0x43, 0x03, 0x92, 0x4a, + 0x7b, 0x0e, 0x7b, 0x12, 0x02, 0x16, 0x43, 0x8a, + 0x7b, 0xc9, 0x7b, 0x00, 0x90, 0x12, 0x04, 0x32, + 0x43, 0x09, 0x06, 0x0a, 0x43, 0x03, 0x99, 0x02, + 0x92, 0x01, 0x91, 0x29, 0x1c, 0x38, 0x1c, 0x22, + 0x1c, 0xfb, 0xf7, 0xfe, 0xfe, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, + 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, 0xfb, + 0xf7, 0x29, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0x82, 0xb0, 0x0a, 0x4f, 0x69, 0x46, 0x0c, + 0xcf, 0x0c, 0xc1, 0x00, 0x21, 0x03, 0x78, 0x6a, + 0x46, 0x01, 0x30, 0x53, 0x54, 0x01, 0x31, 0x06, + 0x29, 0xf8, 0xd3, 0x01, 0x78, 0x68, 0x46, 0xed, + 0x09, 0x00, 0xab, 0x01, 0xfb, 0xf7, 0x3f, 0xff, + 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x44, 0x5d, 0x03, 0x20, 0x00, 0xb5, + 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, + 0xfb, 0xf7, 0x65, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, + 0x12, 0x02, 0x10, 0x43, 0x8a, 0x78, 0xc9, 0x78, + 0x09, 0x02, 0x11, 0x43, 0xfb, 0xf7, 0x77, 0xff, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x82, 0xb0, + 0x09, 0x4f, 0x69, 0x46, 0x0c, 0xcf, 0x0c, 0xc1, + 0x00, 0x21, 0x02, 0x78, 0x6b, 0x46, 0x01, 0x30, + 0x5a, 0x54, 0x01, 0x31, 0x08, 0x29, 0xf8, 0xd3, + 0x68, 0x46, 0xfb, 0xf7, 0xa2, 0xff, 0x02, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x5d, + 0x03, 0x20, 0x00, 0xb5, 0xfb, 0xf7, 0xb1, 0xff, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x89, 0xb0, + 0x00, 0x23, 0x48, 0x4e, 0x07, 0x93, 0x06, 0x93, + 0x0c, 0xce, 0x04, 0xad, 0x0c, 0xc5, 0x00, 0x23, + 0x03, 0x93, 0x03, 0x78, 0x02, 0x1c, 0x01, 0x30, + 0x00, 0x24, 0x00, 0x27, 0x01, 0x2b, 0x08, 0x93, + 0x04, 0xd1, 0x83, 0x1a, 0x8b, 0x42, 0x01, 0xd2, + 0x04, 0x78, 0x01, 0x30, 0x08, 0x9b, 0x02, 0x2b, + 0x04, 0xd1, 0x83, 0x1a, 0x8b, 0x42, 0x01, 0xd2, + 0x07, 0x78, 0x01, 0x30, 0x01, 0x2c, 0x0b, 0xd1, + 0x83, 0x1a, 0x8b, 0x42, 0x08, 0xd2, 0x45, 0x78, + 0x03, 0x78, 0x2d, 0x02, 0x2b, 0x43, 0x85, 0x78, + 0x2d, 0x04, 0x2b, 0x43, 0x07, 0x93, 0x03, 0x30, + 0x01, 0x2c, 0x0b, 0xd1, 0x83, 0x1a, 0x8b, 0x42, + 0x08, 0xd2, 0x45, 0x78, 0x03, 0x78, 0x2d, 0x02, + 0x2b, 0x43, 0x85, 0x78, 0x2d, 0x04, 0x2b, 0x43, + 0x06, 0x93, 0x03, 0x30, 0x02, 0x2c, 0x0a, 0xd1, + 0x83, 0x1a, 0x8b, 0x42, 0x07, 0xd2, 0x00, 0x23, + 0x06, 0x78, 0xed, 0x09, 0x00, 0xac, 0x01, 0x04, + 0xad, 0x01, 0x30, 0xee, 0x54, 0x01, 0x33, 0x06, + 0x2b, 0xf8, 0xd3, 0x00, 0x2f, 0x05, 0xd1, 0x83, + 0x1a, 0x8b, 0x42, 0x02, 0xd2, 0x03, 0x78, 0x01, + 0x30, 0x03, 0x93, 0x01, 0x2f, 0x1d, 0xd1, 0x83, + 0x1a, 0x8b, 0x42, 0x08, 0xd2, 0x45, 0x78, 0x03, + 0x78, 0x2d, 0x02, 0x2b, 0x43, 0x85, 0x78, 0x2d, + 0x04, 0x2b, 0x43, 0x07, 0x93, 0x03, 0x30, 0x83, + 0x1a, 0x8b, 0x42, 0x08, 0xd2, 0x45, 0x78, 0x03, + 0x78, 0x2d, 0x02, 0x2b, 0x43, 0x85, 0x78, 0x2d, + 0x04, 0x2b, 0x43, 0x06, 0x93, 0x03, 0x30, 0x83, + 0x1a, 0x8b, 0x42, 0x02, 0xd2, 0x03, 0x78, 0x01, + 0x30, 0x03, 0x93, 0x02, 0x2f, 0x11, 0xd1, 0x83, + 0x1a, 0x8b, 0x42, 0x09, 0xd2, 0x00, 0x23, 0x06, + 0x78, 0x04, 0xad, 0x01, 0x30, 0xee, 0x54, 0x01, + 0x33, 0x06, 0x2b, 0xf8, 0xd3, 0x02, 0x2f, 0x04, + 0xd1, 0x82, 0x1a, 0x8a, 0x42, 0x01, 0xd2, 0x02, + 0x78, 0x03, 0x92, 0x06, 0x98, 0x03, 0x9a, 0x04, + 0xa9, 0x01, 0x91, 0x21, 0x1c, 0x00, 0x90, 0x02, + 0x92, 0x3a, 0x1c, 0x08, 0x98, 0x07, 0x9b, 0xfb, + 0xf7, 0x3c, 0xff, 0x09, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x54, 0x5d, 0x03, 0x20, 0x00, + 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, + 0x43, 0xfb, 0xf7, 0x73, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0xfb, 0xf7, 0x7c, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0x78, 0xfb, + 0xf7, 0x84, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xfb, 0xf7, 0xa3, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0x80, 0xb5, 0x82, 0xb0, 0x0a, 0x4f, 0x69, + 0x46, 0x0c, 0xcf, 0x0c, 0xc1, 0x00, 0x21, 0x03, + 0x78, 0x6a, 0x46, 0x01, 0x30, 0x53, 0x54, 0x01, + 0x31, 0x06, 0x29, 0xf8, 0xd3, 0x01, 0x78, 0x68, + 0x46, 0xfb, 0xf7, 0x9d, 0xff, 0xed, 0x09, 0x00, + 0xad, 0x01, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x5c, 0x5d, 0x03, 0x20, + 0xb0, 0xb5, 0xff, 0xb0, 0xff, 0xb0, 0xe2, 0xb0, + 0x07, 0x1c, 0x01, 0x20, 0x80, 0x02, 0xff, 0x22, + 0x00, 0x21, 0x81, 0x32, 0x68, 0x44, 0xe5, 0xf7, + 0xad, 0xfc, 0x68, 0x46, 0x01, 0x22, 0x92, 0x02, + 0x00, 0x21, 0xe5, 0xf7, 0xa7, 0xfc, 0x38, 0x78, + 0x01, 0x37, 0x00, 0x22, 0x00, 0x28, 0x10, 0xd9, + 0x00, 0x21, 0x53, 0x00, 0x9b, 0x18, 0x5b, 0x00, + 0x01, 0x24, 0xa4, 0x02, 0x6c, 0x44, 0x1c, 0x19, + 0x3d, 0x78, 0x01, 0x37, 0x65, 0x54, 0x01, 0x31, + 0x06, 0x29, 0xf9, 0xd3, 0x01, 0x32, 0x82, 0x42, + 0xee, 0xd3, 0x00, 0x22, 0x00, 0x28, 0x0c, 0xd9, + 0x00, 0x21, 0x13, 0x01, 0x1c, 0x1c, 0x6c, 0x44, + 0x3d, 0x78, 0x01, 0x37, 0x65, 0x54, 0x01, 0x31, + 0x10, 0x29, 0xf9, 0xd3, 0x01, 0x32, 0x82, 0x42, + 0xf2, 0xd3, 0x6a, 0x46, 0x01, 0x21, 0x89, 0x02, + 0x69, 0x44, 0xfb, 0xf7, 0x7f, 0xff, 0x7f, 0xb0, + 0x7f, 0xb0, 0x62, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x80, 0xb5, 0x82, 0xb0, 0x0a, 0x4f, + 0x69, 0x46, 0x0c, 0xcf, 0x0c, 0xc1, 0x00, 0x21, + 0x03, 0x78, 0x6a, 0x46, 0x01, 0x30, 0x53, 0x54, + 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3, 0x01, 0x78, + 0x68, 0x46, 0xfc, 0xf7, 0x01, 0xf8, 0x02, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x64, 0x5d, 0x03, 0x20, 0xb0, 0xb5, 0xbf, 0xb0, + 0x04, 0x1c, 0x68, 0x46, 0xfc, 0x22, 0x0f, 0x1c, + 0x00, 0x21, 0xe5, 0xf7, 0x53, 0xfc, 0x00, 0x25, + 0xf8, 0x2f, 0x07, 0xd1, 0x68, 0x46, 0x21, 0x1c, + 0x3a, 0x1c, 0xe5, 0xf7, 0xd3, 0xfc, 0x68, 0x46, + 0xc5, 0x55, 0x06, 0xe0, 0x68, 0x46, 0x21, 0x1c, + 0x0b, 0xf0, 0xc8, 0xf8, 0x68, 0x46, 0x0b, 0xf0, + 0xed, 0x09, 0x00, 0xae, 0x01, 0x15, 0xf8, 0x68, + 0x46, 0xfc, 0xf7, 0x04, 0xf8, 0x3f, 0xb0, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, + 0xf7, 0x0d, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xfc, 0xf7, 0x1c, 0xf8, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, + 0x02, 0x08, 0x43, 0xfc, 0xf7, 0x21, 0xf8, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0x36, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, + 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, 0xfc, + 0xf7, 0x3b, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xfc, 0xf7, 0x4c, 0xf8, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0x78, 0xfc, 0xf7, 0x54, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, + 0xf7, 0x85, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x12, + 0x02, 0x10, 0x43, 0x8a, 0x78, 0xc9, 0x78, 0x09, + 0x02, 0x11, 0x43, 0xfc, 0xf7, 0x89, 0xf8, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0xb0, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, + 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x12, 0x02, 0x10, + 0x43, 0x8a, 0x78, 0xc9, 0x78, 0x09, 0x02, 0x11, + 0x43, 0xfc, 0xf7, 0xb4, 0xf8, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0xdb, 0xf8, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0x78, 0xfc, + 0xf7, 0xe3, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xfc, 0xf7, 0x0a, 0xf9, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0x78, 0xfc, 0xf7, 0x12, + 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, + 0xf7, 0x3b, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x89, + 0x78, 0x12, 0x02, 0x10, 0x43, 0x09, 0x04, 0x08, + 0x43, 0xfc, 0xf7, 0xed, 0x09, 0x00, 0xaf, 0x01, + 0x3c, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0xfc, 0xf7, 0x59, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, + 0x08, 0x43, 0xfc, 0xf7, 0x60, 0xf9, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0x01, 0x78, 0x40, 0x78, + 0x00, 0x02, 0x08, 0x43, 0xfc, 0xf7, 0x91, 0xf9, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, + 0x4a, 0x78, 0x00, 0x78, 0x12, 0x02, 0x10, 0x43, + 0x8a, 0x78, 0xc9, 0x78, 0x09, 0x02, 0x11, 0x43, + 0xfc, 0xf7, 0x95, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0xfc, 0xf7, 0x9e, 0xf9, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0x00, 0x78, 0xfc, 0xf7, + 0xa6, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0xfc, 0xf7, 0xaf, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x00, 0x78, 0xfc, 0xf7, 0xb7, 0xf9, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, + 0x4a, 0x78, 0x00, 0x78, 0x89, 0x78, 0x12, 0x02, + 0x10, 0x43, 0xfc, 0xf7, 0xba, 0xf9, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0xc7, 0xf9, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0x78, + 0xfc, 0xf7, 0xcf, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x00, 0x78, 0xfc, 0xf7, 0xd7, 0xf9, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x01, 0x1c, + 0x4a, 0x78, 0x00, 0x78, 0x12, 0x02, 0x10, 0x43, + 0x02, 0x31, 0x0a, 0x1c, 0x53, 0x1c, 0x5f, 0x78, + 0x52, 0x78, 0x09, 0x78, 0x3f, 0x02, 0x3a, 0x43, + 0x9f, 0x78, 0xdb, 0x78, 0x1b, 0x02, 0x3b, 0x43, + 0xfc, 0xf7, 0xd7, 0xf9, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0xff, 0xb0, 0x81, 0xb0, + 0x07, 0x1c, 0xff, 0x22, 0x00, 0x21, 0x01, 0x32, + 0x40, 0xa8, 0xe5, 0xf7, 0x48, 0xfb, 0x68, 0x46, + 0xff, 0x22, 0x00, 0x21, 0x01, 0x32, 0xed, 0x09, + 0x00, 0xb0, 0x01, 0xe5, 0xf7, 0x42, 0xfb, 0x38, + 0x78, 0x00, 0x21, 0x7a, 0x1c, 0x00, 0x28, 0x0c, + 0xd9, 0x17, 0x78, 0x8b, 0x00, 0x40, 0xac, 0xe7, + 0x50, 0x54, 0x78, 0x24, 0x02, 0x27, 0x43, 0x01, + 0x31, 0x02, 0x32, 0x40, 0xac, 0xe7, 0x50, 0x81, + 0x42, 0xf2, 0xd3, 0x00, 0x21, 0x00, 0x28, 0x0c, + 0xd9, 0x17, 0x78, 0x8b, 0x00, 0x6c, 0x46, 0xe7, + 0x50, 0x54, 0x78, 0x24, 0x02, 0x27, 0x43, 0x6c, + 0x46, 0x01, 0x31, 0x02, 0x32, 0x81, 0x42, 0xe7, + 0x50, 0xf2, 0xd3, 0x6a, 0x46, 0x40, 0xa9, 0xfc, + 0xf7, 0xc2, 0xf9, 0x7f, 0xb0, 0x01, 0xb0, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, + 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, 0xfc, + 0xf7, 0xd6, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x12, + 0x02, 0x10, 0x43, 0x8a, 0x78, 0xc9, 0x78, 0x09, + 0x02, 0x11, 0x43, 0xfc, 0xf7, 0xf6, 0xf9, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0x23, + 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, + 0xf7, 0x2c, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x90, + 0xb5, 0xc0, 0xb0, 0x07, 0x1c, 0x68, 0x46, 0xff, + 0x22, 0x00, 0x21, 0x01, 0x32, 0xe5, 0xf7, 0xed, + 0xfa, 0x3a, 0x78, 0x00, 0x20, 0x7b, 0x1c, 0x00, + 0x2a, 0x11, 0xd9, 0x1f, 0x78, 0x81, 0x00, 0x6c, + 0x46, 0x67, 0x50, 0x5c, 0x78, 0x24, 0x02, 0x27, + 0x43, 0x6c, 0x46, 0x67, 0x50, 0x9c, 0x78, 0x24, + 0x04, 0x27, 0x43, 0x6c, 0x46, 0x01, 0x30, 0x03, + 0x33, 0x90, 0x42, 0x67, 0x50, 0xed, 0xd3, 0x69, + 0x46, 0x10, 0x1c, 0xfc, 0xf7, 0x26, 0xfa, 0x40, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xfc, 0xf7, 0x51, 0xfa, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0x78, 0xfc, 0xf7, 0x59, + 0xfa, 0xed, 0x09, 0x00, 0xb1, 0x01, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0x76, 0xfa, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0x78, + 0xfc, 0xf7, 0x7e, 0xfa, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0xfc, 0xf7, 0x9b, 0xfa, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0xda, 0xfa, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, + 0xe9, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0xfc, 0xf7, 0xfe, 0xfa, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0xfc, 0xf7, 0x09, 0xfb, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0x01, 0x78, 0x40, 0x78, + 0x00, 0x02, 0x08, 0x43, 0xfc, 0xf7, 0x14, 0xfb, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x78, + 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, 0xfc, 0xf7, + 0x1d, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, + 0xfc, 0xf7, 0x22, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, + 0x08, 0x43, 0xfc, 0xf7, 0x2b, 0xfb, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0x56, 0xfb, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0x78, + 0xfc, 0xf7, 0x5e, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0xfc, 0xf7, 0x67, 0xfb, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0x01, 0x78, 0x40, 0x78, + 0x00, 0x02, 0x08, 0x43, 0xfc, 0xf7, 0x7c, 0xfb, + 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xa0, 0xb0, + 0x6f, 0x46, 0x00, 0x21, 0x00, 0x22, 0x00, 0x24, + 0x00, 0x25, 0x08, 0x23, 0x36, 0xc7, 0x01, 0x3b, + 0xfc, 0xd1, 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, + 0x12, 0x02, 0x02, 0x43, 0x02, 0x31, 0x08, 0x1c, + 0x14, 0x1c, 0x42, 0x78, 0x09, 0x78, 0x87, 0x78, + 0x12, 0x02, 0x0a, 0x43, 0x15, 0x1c, 0x02, 0x30, + 0x41, 0x1c, 0x68, 0x46, 0xed, 0x09, 0x00, 0xb2, + 0x01, 0x3a, 0x1c, 0xe5, 0xf7, 0xcb, 0xfa, 0x6b, + 0x46, 0x20, 0x1c, 0x29, 0x1c, 0x3a, 0x1c, 0x00, + 0xf0, 0x7b, 0xfa, 0x20, 0xb0, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x8e, + 0xfa, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xbf, + 0xb0, 0x04, 0x1c, 0x68, 0x46, 0xfc, 0x22, 0x0f, + 0x1c, 0x00, 0x21, 0xe5, 0xf7, 0x2b, 0xfa, 0x00, + 0x25, 0xf8, 0x2f, 0x07, 0xd1, 0x68, 0x46, 0x21, + 0x1c, 0x3a, 0x1c, 0xe5, 0xf7, 0xab, 0xfa, 0x68, + 0x46, 0xc5, 0x55, 0x06, 0xe0, 0x68, 0x46, 0x21, + 0x1c, 0x0a, 0xf0, 0xa0, 0xfe, 0x68, 0x46, 0x0a, + 0xf0, 0xed, 0xfd, 0x68, 0x46, 0x00, 0xf0, 0x9a, + 0xfa, 0x3f, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0xf0, 0xa1, 0xfa, 0x08, + 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x82, 0xb0, 0x09, + 0x4f, 0x69, 0x46, 0x0c, 0xcf, 0x0c, 0xc1, 0x00, + 0x21, 0x02, 0x78, 0x6b, 0x46, 0x01, 0x30, 0x5a, + 0x54, 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3, 0x68, + 0x46, 0x00, 0xf0, 0xb2, 0xfa, 0x02, 0xb0, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x6c, 0x5d, 0x03, + 0x20, 0x80, 0xb5, 0x84, 0xb0, 0x0a, 0x4f, 0x69, + 0x46, 0x0c, 0xcf, 0x0c, 0xc1, 0x0c, 0xcf, 0x0c, + 0xc1, 0x00, 0x21, 0x02, 0x78, 0x6b, 0x46, 0x01, + 0x30, 0x5a, 0x54, 0x01, 0x31, 0x10, 0x29, 0xf8, + 0xd3, 0x68, 0x46, 0x00, 0xf0, 0xab, 0xfa, 0x04, + 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x74, 0x5d, 0x03, 0x20, 0x00, 0xb5, 0x00, + 0xf0, 0xb5, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0x84, 0xb0, 0x0c, 0x4f, 0x69, 0x46, 0x0c, + 0xcf, 0x0c, 0xc1, 0x0c, 0xcf, 0x0c, 0xc1, 0x02, + 0x78, 0x41, 0x1c, 0x00, 0x20, 0x0b, 0x78, 0x6f, + 0x46, 0x01, 0x31, 0x3b, 0x54, 0x01, 0x30, 0xed, + 0x09, 0x00, 0xb3, 0x01, 0x10, 0x28, 0xf8, 0xd3, + 0x69, 0x46, 0x10, 0x1c, 0x00, 0xf0, 0xbf, 0xfa, + 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x84, 0x5d, 0x03, 0x20, 0x00, 0xb5, + 0x00, 0x78, 0x00, 0xf0, 0xc2, 0xfa, 0x08, 0xbc, + 0x18, 0x47, 0xf0, 0xb5, 0x86, 0xb0, 0x01, 0x1c, + 0x4a, 0x78, 0x00, 0x78, 0x12, 0x02, 0x10, 0x43, + 0x8a, 0x78, 0x12, 0x04, 0x10, 0x43, 0xca, 0x78, + 0x12, 0x06, 0x02, 0x43, 0x04, 0x31, 0x08, 0x1c, + 0x15, 0x1c, 0x42, 0x78, 0x09, 0x78, 0x12, 0x02, + 0x11, 0x43, 0x82, 0x78, 0x12, 0x04, 0x11, 0x43, + 0xc2, 0x78, 0x12, 0x06, 0x0a, 0x43, 0x17, 0x1c, + 0x42, 0x79, 0x01, 0x79, 0x12, 0x02, 0x11, 0x43, + 0x82, 0x79, 0x12, 0x04, 0x11, 0x43, 0xc2, 0x79, + 0x12, 0x06, 0x0a, 0x43, 0x16, 0x1c, 0x42, 0x7a, + 0x01, 0x7a, 0x12, 0x02, 0x11, 0x43, 0x82, 0x7a, + 0x12, 0x04, 0x11, 0x43, 0xc2, 0x7a, 0x12, 0x06, + 0x0a, 0x43, 0x0c, 0x30, 0x01, 0x1c, 0x14, 0x1c, + 0x4a, 0x78, 0x00, 0x78, 0x12, 0x02, 0x10, 0x43, + 0x8a, 0x78, 0x12, 0x04, 0x10, 0x43, 0xca, 0x78, + 0x12, 0x06, 0x02, 0x43, 0x13, 0x1c, 0x4a, 0x79, + 0x08, 0x79, 0x12, 0x02, 0x10, 0x43, 0x8a, 0x79, + 0x12, 0x04, 0x02, 0x43, 0x07, 0x31, 0x08, 0x1c, + 0x09, 0x78, 0x09, 0x06, 0x11, 0x43, 0x05, 0x91, + 0x82, 0x78, 0x41, 0x78, 0x12, 0x02, 0x11, 0x43, + 0xc2, 0x78, 0x12, 0x04, 0x11, 0x43, 0x02, 0x79, + 0x12, 0x06, 0x11, 0x43, 0x04, 0x91, 0x81, 0x79, + 0x42, 0x79, 0x09, 0x02, 0x0a, 0x43, 0xc1, 0x79, + 0x00, 0x7a, 0x00, 0x93, 0x09, 0x04, 0x11, 0x43, + 0x00, 0x06, 0x08, 0x43, 0x02, 0x1c, 0x05, 0x98, + 0x04, 0x99, 0x03, 0x92, 0x01, 0x90, 0x02, 0x91, + 0x39, 0x1c, 0x28, 0x1c, 0x32, 0x1c, 0x23, 0x1c, + 0x00, 0xf0, 0xed, 0x09, 0x00, 0xb4, 0x01, 0x6b, + 0xfa, 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x86, 0xfa, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x00, + 0x78, 0x49, 0x78, 0x00, 0xf0, 0xbc, 0xfa, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0x78, 0x00, + 0xf0, 0xa8, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0xf0, + 0xb5, 0x95, 0xb0, 0x52, 0x4f, 0x0d, 0x1c, 0x50, + 0xcf, 0x06, 0xa9, 0x50, 0xc1, 0x00, 0x21, 0x00, + 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x26, 0x0c, + 0xaf, 0x5e, 0xc7, 0x5c, 0xc7, 0x43, 0x78, 0x01, + 0x78, 0x1b, 0x02, 0x19, 0x43, 0x83, 0x78, 0x1b, + 0x04, 0x19, 0x43, 0xc3, 0x78, 0xc2, 0x1c, 0x54, + 0x1c, 0x1a, 0x06, 0x0a, 0x43, 0x20, 0x1a, 0x2d, + 0x1a, 0x17, 0x1c, 0x20, 0x2d, 0x09, 0xd1, 0x21, + 0x1c, 0x2a, 0x1c, 0x0c, 0xa8, 0xe5, 0xf7, 0x93, + 0xf9, 0x00, 0x21, 0x0c, 0xa8, 0x41, 0x55, 0x60, + 0x19, 0x08, 0xe0, 0x0c, 0xa8, 0x21, 0x1c, 0x0a, + 0xf0, 0x86, 0xfd, 0x0c, 0xa8, 0x0a, 0xf0, 0xd3, + 0xfc, 0x00, 0x19, 0x01, 0x30, 0x42, 0x78, 0x01, + 0x78, 0x12, 0x02, 0x11, 0x43, 0x82, 0x78, 0x12, + 0x04, 0x11, 0x43, 0xc2, 0x78, 0x12, 0x06, 0x0a, + 0x43, 0x15, 0x1c, 0x42, 0x79, 0x01, 0x79, 0x12, + 0x02, 0x11, 0x43, 0x82, 0x79, 0x12, 0x04, 0x11, + 0x43, 0xc2, 0x79, 0x12, 0x06, 0x0a, 0x43, 0x14, + 0x1c, 0x42, 0x7a, 0x01, 0x7a, 0x12, 0x02, 0x11, + 0x43, 0x82, 0x7a, 0x12, 0x04, 0x11, 0x43, 0xc2, + 0x7a, 0x12, 0x06, 0x0a, 0x43, 0x0c, 0x30, 0x01, + 0x1c, 0x13, 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x8e, + 0x78, 0x12, 0x02, 0x10, 0x43, 0x02, 0x31, 0x4a, + 0x1c, 0x31, 0x04, 0x16, 0x78, 0x01, 0x43, 0x50, + 0x1c, 0x32, 0x06, 0x11, 0x43, 0x0b, 0x91, 0x01, + 0x1c, 0x4a, 0x78, 0x00, 0x78, 0xed, 0x09, 0x00, + 0xb5, 0x01, 0x12, 0x02, 0x10, 0x43, 0x8a, 0x78, + 0x12, 0x04, 0x10, 0x43, 0xca, 0x78, 0x12, 0x06, + 0x10, 0x43, 0x0a, 0x90, 0x4a, 0x79, 0x08, 0x79, + 0x8e, 0x79, 0x12, 0x02, 0x02, 0x43, 0x06, 0x31, + 0x48, 0x1c, 0x31, 0x04, 0x11, 0x43, 0x02, 0x78, + 0x12, 0x06, 0x11, 0x43, 0x09, 0x91, 0x01, 0x30, + 0x01, 0x1c, 0x4a, 0x78, 0x00, 0x78, 0x12, 0x02, + 0x10, 0x43, 0x8a, 0x78, 0x12, 0x04, 0x10, 0x43, + 0xca, 0x78, 0x12, 0x06, 0x10, 0x43, 0x08, 0x90, + 0x00, 0x20, 0x04, 0x31, 0x0a, 0x78, 0x06, 0xae, + 0x01, 0x31, 0x32, 0x54, 0x01, 0x30, 0x08, 0x28, + 0xf8, 0xd3, 0x09, 0x98, 0x06, 0xaa, 0x08, 0x99, + 0x05, 0x92, 0x03, 0x90, 0x0a, 0x9a, 0x04, 0x91, + 0x0b, 0x99, 0x02, 0x92, 0x2a, 0x1c, 0x38, 0x1c, + 0x00, 0x93, 0x01, 0x91, 0x0c, 0xa9, 0x23, 0x1c, + 0x00, 0xf0, 0x5a, 0xfa, 0x15, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x94, 0x5d, 0x03, 0x20, + 0x80, 0xb5, 0x89, 0xb0, 0x6f, 0x46, 0x00, 0x21, + 0x00, 0x22, 0x00, 0x23, 0x0e, 0xc7, 0x0e, 0xc7, + 0x0e, 0xc7, 0x07, 0x78, 0x41, 0x1c, 0x68, 0x46, + 0x3a, 0x1c, 0xe5, 0xf7, 0xff, 0xf8, 0x69, 0x46, + 0x38, 0x1c, 0x00, 0xf0, 0x1b, 0xf9, 0x09, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0x01, 0x78, 0x40, 0x78, 0x00, 0x02, 0x08, 0x43, + 0xfc, 0xf7, 0xb4, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0xb0, 0xb5, 0x89, 0xb0, 0x07, 0x1c, 0x68, 0x46, + 0x0c, 0x1c, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, + 0x00, 0x25, 0x2e, 0xc0, 0x2e, 0xc0, 0x20, 0xc0, + 0x20, 0x2c, 0x08, 0xd1, 0x68, 0x46, 0x39, 0x1c, + 0x22, 0x1c, 0xe5, 0xf7, 0xdb, 0xf8, 0x68, 0x46, + 0x05, 0x55, 0x38, 0x19, 0x08, 0xe0, 0x68, 0x46, + 0x39, 0x1c, 0x0a, 0xf0, 0xcf, 0xfc, 0x68, 0x46, + 0xed, 0x09, 0x00, 0xb6, 0x01, 0x0a, 0xf0, 0x1c, + 0xfc, 0xc0, 0x19, 0x01, 0x30, 0x01, 0x78, 0x42, + 0x78, 0x68, 0x46, 0x00, 0xf0, 0x3d, 0xfa, 0x09, + 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, + 0xb5, 0x8f, 0xb0, 0x3b, 0x4f, 0x0d, 0x1c, 0x50, + 0xcf, 0x03, 0xa9, 0x50, 0xc1, 0x00, 0x21, 0x00, + 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x26, 0x06, + 0xaf, 0x5e, 0xc7, 0x5c, 0xc7, 0x43, 0x78, 0x02, + 0x78, 0x1b, 0x02, 0x1a, 0x43, 0x83, 0x78, 0x1b, + 0x04, 0x1a, 0x43, 0xc3, 0x78, 0xc1, 0x1c, 0x4c, + 0x1c, 0x19, 0x06, 0x11, 0x43, 0x20, 0x1a, 0x2d, + 0x1a, 0x0f, 0x1c, 0x20, 0x2d, 0x09, 0xd1, 0x21, + 0x1c, 0x2a, 0x1c, 0x06, 0xa8, 0xe5, 0xf7, 0xa0, + 0xf8, 0x00, 0x21, 0x06, 0xa8, 0x41, 0x55, 0x60, + 0x19, 0x08, 0xe0, 0x06, 0xa8, 0x21, 0x1c, 0x0a, + 0xf0, 0x93, 0xfc, 0x06, 0xa8, 0x0a, 0xf0, 0xe0, + 0xfb, 0x00, 0x19, 0x01, 0x30, 0x42, 0x78, 0x01, + 0x78, 0x12, 0x02, 0x11, 0x43, 0x82, 0x78, 0x12, + 0x04, 0x11, 0x43, 0xc2, 0x78, 0x12, 0x06, 0x0a, + 0x43, 0x14, 0x1c, 0x42, 0x79, 0x01, 0x79, 0x12, + 0x02, 0x11, 0x43, 0x82, 0x79, 0x12, 0x04, 0x11, + 0x43, 0xc2, 0x79, 0x12, 0x06, 0x0a, 0x43, 0x08, + 0x30, 0x01, 0x1c, 0x13, 0x1c, 0x4a, 0x1c, 0x49, + 0x78, 0x00, 0x78, 0x15, 0x79, 0x09, 0x02, 0x08, + 0x43, 0x51, 0x78, 0x09, 0x04, 0x08, 0x43, 0x91, + 0x78, 0x09, 0x06, 0x08, 0x43, 0xd1, 0x78, 0x2d, + 0x02, 0x29, 0x43, 0x55, 0x79, 0x2d, 0x04, 0x29, + 0x43, 0x95, 0x79, 0x2d, 0x06, 0x29, 0x43, 0x05, + 0x91, 0x00, 0x21, 0x07, 0x32, 0x16, 0x78, 0x03, + 0xad, 0x01, 0x32, 0x6e, 0x54, 0x01, 0x31, 0x08, + 0x29, 0xf8, 0xd3, 0x05, 0x99, 0x03, 0xaa, 0x00, + 0x90, 0x38, 0x1c, 0x02, 0x92, 0x01, 0x91, 0x06, + 0xa9, 0x22, 0x1c, 0xed, 0x09, 0x00, 0xb7, 0x01, + 0x00, 0xf0, 0x6d, 0xf9, 0x0f, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x9c, 0x5d, + 0x03, 0x20, 0x80, 0xb5, 0x17, 0x1c, 0x1a, 0x1c, + 0x3b, 0x1c, 0x0f, 0x1c, 0x01, 0x1c, 0x38, 0x1c, + 0x0a, 0xf0, 0xc9, 0xf8, 0x00, 0x22, 0x00, 0x28, + 0x00, 0xd0, 0x03, 0x22, 0x04, 0x48, 0x04, 0x49, + 0x40, 0x68, 0xfd, 0xf7, 0x5f, 0xfe, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x60, 0xbb, + 0x03, 0x20, 0x02, 0xfc, 0x00, 0x00, 0x00, 0xb5, + 0xa6, 0xb0, 0x00, 0x21, 0x00, 0x22, 0x10, 0x23, + 0x06, 0xa8, 0x06, 0xc0, 0x01, 0x3b, 0xfc, 0xd1, + 0x00, 0x20, 0x05, 0x90, 0x04, 0x90, 0x80, 0x20, + 0x03, 0x90, 0x05, 0xa8, 0x04, 0xa9, 0x06, 0xaa, + 0x03, 0xab, 0x0a, 0xf0, 0x84, 0xf8, 0x03, 0x1c, + 0x06, 0xaa, 0x02, 0x92, 0x05, 0x98, 0x03, 0x99, + 0x00, 0x22, 0x00, 0x2b, 0x00, 0x90, 0x01, 0x91, + 0x00, 0xd0, 0x03, 0x22, 0x04, 0x48, 0x04, 0x49, + 0x40, 0x68, 0x04, 0x9b, 0xfd, 0xf7, 0x32, 0xfe, + 0x26, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x03, 0xfc, 0x00, 0x00, 0x00, 0xb5, + 0x04, 0x48, 0x03, 0x22, 0x04, 0x49, 0x40, 0x68, + 0xfd, 0xf7, 0x24, 0xfe, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x04, 0xfc, + 0x00, 0x00, 0x00, 0xb5, 0x82, 0xb0, 0x00, 0x20, + 0x01, 0x90, 0x00, 0xab, 0x18, 0x70, 0x68, 0x46, + 0x01, 0x90, 0x04, 0x48, 0x03, 0x22, 0x40, 0x68, + 0x01, 0x9b, 0x03, 0x49, 0xfd, 0xf7, 0x0e, 0xfe, + 0x02, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, + 0x03, 0x20, 0x05, 0xfc, 0x00, 0x00, 0x00, 0xb5, + 0x04, 0x48, 0x03, 0x22, 0x04, 0x49, 0x40, 0x68, + 0xfd, 0xf7, 0x00, 0xfe, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0xed, 0x09, + 0x00, 0xb8, 0x01, 0x11, 0xfc, 0x00, 0x00, 0x00, + 0xb5, 0x09, 0xf0, 0x91, 0xff, 0x00, 0x22, 0x00, + 0x28, 0x00, 0xd0, 0x03, 0x22, 0x03, 0x48, 0x03, + 0x49, 0x40, 0x68, 0xfd, 0xf7, 0xed, 0xfd, 0x08, + 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, 0x06, + 0xfc, 0x00, 0x00, 0x00, 0xb5, 0x10, 0x21, 0x09, + 0xf0, 0xe0, 0xff, 0x00, 0x22, 0x00, 0x28, 0x00, + 0xd0, 0x03, 0x22, 0x03, 0x48, 0x04, 0x49, 0x40, + 0x68, 0xfd, 0xf7, 0xda, 0xfd, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x08, + 0xfc, 0x00, 0x00, 0x00, 0xb5, 0x85, 0xb0, 0x0c, + 0x49, 0x01, 0xa8, 0x0c, 0xc9, 0x0c, 0xc0, 0x0c, + 0xc9, 0x0c, 0xc0, 0x10, 0x20, 0x00, 0x90, 0x01, + 0xa8, 0x69, 0x46, 0x09, 0xf0, 0xa8, 0xff, 0x00, + 0x22, 0x00, 0x28, 0x00, 0xd0, 0x03, 0x22, 0x05, + 0x48, 0x01, 0xab, 0x05, 0x49, 0x40, 0x68, 0xfd, + 0xf7, 0xbb, 0xfd, 0x05, 0xb0, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0xa4, 0x5d, 0x03, 0x20, 0x60, + 0xbb, 0x03, 0x20, 0x09, 0xfc, 0x00, 0x00, 0x00, + 0xb5, 0x04, 0x48, 0x03, 0x22, 0x04, 0x49, 0x40, + 0x68, 0xfd, 0xf7, 0xaa, 0xfd, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x60, 0xbb, 0x03, 0x20, 0x0a, + 0xfc, 0x00, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x07, + 0x49, 0x68, 0x46, 0x0c, 0xc9, 0x0c, 0xc0, 0x0c, + 0xc9, 0x0c, 0xc0, 0x05, 0x48, 0x03, 0x22, 0x6b, + 0x46, 0x05, 0x49, 0x40, 0x68, 0xfd, 0xf7, 0x94, + 0xfd, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0xb4, + 0x5d, 0x03, 0x20, 0x60, 0xbb, 0x03, 0x20, 0x0b, + 0xfc, 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, 0x17, + 0x1c, 0x0a, 0xaa, 0x05, 0x1c, 0x0c, 0x1c, 0x07, + 0xca, 0x09, 0x9e, 0x01, 0x90, 0x02, 0x91, 0x21, + 0x1c, 0x28, 0x1c, 0x03, 0x92, 0x3a, 0x1c, 0x00, + 0x96, 0xed, 0x09, 0x00, 0xb9, 0x01, 0x0a, 0xf0, + 0x2d, 0xf8, 0x00, 0x22, 0x00, 0x28, 0x00, 0xd0, + 0x03, 0x22, 0x04, 0x48, 0x04, 0x49, 0x40, 0x68, + 0xfd, 0xf7, 0x71, 0xfd, 0x04, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, + 0x0c, 0xfc, 0x00, 0x00, 0x00, 0xb5, 0x8f, 0xb0, + 0x07, 0xaa, 0x03, 0x92, 0x0c, 0x32, 0x09, 0xa8, + 0x01, 0x90, 0x08, 0xa9, 0x02, 0x91, 0x14, 0x30, + 0x00, 0x92, 0x0c, 0xaa, 0x14, 0x31, 0x0b, 0xab, + 0x0a, 0xf0, 0x0e, 0xf8, 0x07, 0x9a, 0x08, 0x99, + 0x06, 0x92, 0x0a, 0x9a, 0x03, 0x1c, 0x05, 0x91, + 0x0b, 0x99, 0x03, 0x92, 0x09, 0x98, 0x0d, 0x9a, + 0x04, 0x90, 0x0c, 0x98, 0x00, 0x92, 0x00, 0x22, + 0x00, 0x2b, 0x02, 0x91, 0x01, 0x90, 0x00, 0xd0, + 0x03, 0x22, 0x04, 0x48, 0x04, 0x49, 0x40, 0x68, + 0x0e, 0x9b, 0xfd, 0xf7, 0x40, 0xfd, 0x0f, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, 0x20, + 0x0d, 0xfc, 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, + 0x00, 0x23, 0x03, 0x22, 0x03, 0x49, 0x40, 0x68, + 0xfd, 0xf7, 0x31, 0xfd, 0x08, 0xbc, 0x18, 0x47, + 0x60, 0xbb, 0x03, 0x20, 0x0f, 0xfc, 0x00, 0x00, + 0x80, 0xb5, 0x00, 0x27, 0x00, 0x28, 0x05, 0xd0, + 0x01, 0x28, 0x07, 0xd1, 0x20, 0x20, 0x09, 0xf0, + 0xc9, 0xfc, 0x04, 0xe0, 0x10, 0x20, 0x09, 0xf0, + 0xc5, 0xfc, 0x00, 0xe0, 0x01, 0x27, 0x00, 0x22, + 0x00, 0x2f, 0x00, 0xd0, 0x03, 0x22, 0x04, 0x48, + 0x04, 0x49, 0x40, 0x68, 0xfd, 0xf7, 0x13, 0xfd, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x60, 0xbb, 0x03, 0x20, 0x0e, 0xfc, 0x00, 0x00, + 0xff, 0xb5, 0x8e, 0xb0, 0x0f, 0x1c, 0x04, 0x1c, + 0x0c, 0xa8, 0x08, 0x22, 0x19, 0x99, 0x18, 0x9d, + 0x17, 0x9e, 0xe4, 0xf7, 0xd9, 0xfe, 0x20, 0x22, + 0x39, 0x1c, 0x04, 0xa8, 0xed, 0x09, 0x00, 0xba, + 0x01, 0xe4, 0xf7, 0xd4, 0xfe, 0x0c, 0x99, 0x0d, + 0x9a, 0x01, 0x95, 0x00, 0x96, 0x02, 0x91, 0x03, + 0x92, 0x10, 0x9a, 0x04, 0xa9, 0x11, 0x9b, 0x20, + 0x1c, 0xe5, 0xf7, 0xde, 0xfc, 0x04, 0x48, 0x00, + 0x22, 0x04, 0x49, 0x40, 0x68, 0xfd, 0xf7, 0xe9, + 0xfc, 0x12, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x60, 0xbb, 0x03, 0x20, 0x14, 0xfc, 0x00, + 0x00, 0xff, 0xb5, 0x91, 0xb0, 0x08, 0x22, 0x1f, + 0x99, 0x1c, 0x9c, 0x1d, 0x9f, 0x1b, 0x9d, 0x1a, + 0x9e, 0x0f, 0xa8, 0xe4, 0xf7, 0xaf, 0xfe, 0x20, + 0x22, 0x12, 0x99, 0x07, 0xa8, 0xe4, 0xf7, 0xaa, + 0xfe, 0x1e, 0x98, 0x0f, 0x99, 0x10, 0x9a, 0x04, + 0x90, 0x03, 0x97, 0x01, 0x95, 0x05, 0x91, 0x06, + 0x92, 0x13, 0x9a, 0x07, 0xa9, 0x11, 0x98, 0x14, + 0x9b, 0x00, 0x96, 0x02, 0x94, 0xe5, 0xf7, 0xf8, + 0xfc, 0x04, 0x48, 0x00, 0x22, 0x04, 0x49, 0x40, + 0x68, 0xfd, 0xf7, 0xbb, 0xfc, 0x15, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, 0xbb, 0x03, + 0x20, 0x10, 0xfc, 0x00, 0x00, 0xf8, 0xb5, 0x06, + 0x1c, 0x00, 0x20, 0x00, 0x90, 0x30, 0x1c, 0x00, + 0x27, 0x14, 0x1c, 0x0d, 0x1c, 0x12, 0xa1, 0x1a, + 0xf0, 0x79, 0xf8, 0x00, 0x28, 0x06, 0xd1, 0x6b, + 0x46, 0x29, 0x1c, 0x22, 0x1c, 0xe6, 0xf7, 0x5e, + 0xfb, 0x07, 0x1c, 0x0c, 0xe0, 0x30, 0x1c, 0x0d, + 0xa1, 0x1a, 0xf0, 0x6c, 0xf8, 0x00, 0x28, 0x06, + 0xd1, 0x6b, 0x46, 0x01, 0x20, 0x29, 0x1c, 0x22, + 0x1c, 0xe6, 0xf7, 0x50, 0xfb, 0x07, 0x1c, 0x00, + 0x22, 0x00, 0x2f, 0x00, 0xd0, 0x03, 0x22, 0x06, + 0x48, 0x06, 0x49, 0x40, 0x68, 0x00, 0x9b, 0xfd, + 0xf7, 0x88, 0xfc, 0xf8, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x72, 0x64, 0x00, 0x00, 0x77, 0x72, 0x00, + 0x00, 0x60, 0xbb, 0x03, 0x20, 0x13, 0xfc, 0xed, + 0x09, 0x00, 0xbb, 0x01, 0x00, 0x00, 0x90, 0xb5, + 0x4c, 0x1e, 0x07, 0x1c, 0x00, 0x29, 0x07, 0xd0, + 0x38, 0x78, 0x01, 0x37, 0x02, 0xf0, 0x39, 0xf8, + 0x20, 0x1c, 0x01, 0x3c, 0x00, 0x28, 0xf7, 0xd1, + 0x03, 0x48, 0x1a, 0xf0, 0x62, 0xf8, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x30, 0xbe, + 0x03, 0x20, 0x00, 0xb5, 0x01, 0xf0, 0xb7, 0xfe, + 0x00, 0x28, 0x07, 0xd0, 0x01, 0xf0, 0xc7, 0xfe, + 0x02, 0xf0, 0x23, 0xf8, 0x01, 0xf0, 0xaf, 0xfe, + 0x00, 0x28, 0xf7, 0xd1, 0x01, 0xf0, 0xc2, 0xfd, + 0x04, 0x48, 0xc0, 0x6a, 0x00, 0x28, 0x02, 0xd1, + 0x03, 0x48, 0x1a, 0xf0, 0x46, 0xf8, 0x08, 0xbc, + 0x18, 0x47, 0x28, 0x69, 0x03, 0x20, 0x30, 0xbe, + 0x03, 0x20, 0x01, 0x49, 0x08, 0x62, 0x70, 0x47, + 0x00, 0x00, 0x28, 0x69, 0x03, 0x20, 0x80, 0xb5, + 0x84, 0xb0, 0x00, 0x20, 0x03, 0x90, 0x01, 0x20, + 0xff, 0xf7, 0xf3, 0xff, 0x01, 0xf0, 0x89, 0xfe, + 0x00, 0x20, 0x26, 0x49, 0x00, 0x27, 0x42, 0x00, + 0x12, 0x18, 0x92, 0x00, 0x01, 0x30, 0x14, 0x28, + 0x8f, 0x50, 0xf8, 0xd3, 0x23, 0x48, 0x01, 0xf0, + 0xad, 0xfd, 0x22, 0x49, 0x4f, 0x67, 0xc8, 0x1d, + 0x75, 0x30, 0x8f, 0x67, 0xc7, 0x60, 0x07, 0x61, + 0x87, 0x61, 0xc7, 0x61, 0x47, 0x62, 0xc7, 0x62, + 0xcf, 0x67, 0x01, 0x21, 0x09, 0x06, 0x81, 0x60, + 0x47, 0x60, 0x07, 0x63, 0x47, 0x63, 0x87, 0x63, + 0xc7, 0x63, 0x07, 0x64, 0x01, 0xf0, 0xd5, 0xff, + 0x02, 0xf0, 0x07, 0xf8, 0x01, 0x27, 0xff, 0x02, + 0x3a, 0x1c, 0x00, 0x23, 0x03, 0xa9, 0x14, 0x48, + 0x0a, 0xf0, 0x17, 0xfe, 0x00, 0x28, 0x04, 0xd0, + 0x00, 0xdf, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x03, 0x99, 0x01, 0x97, 0x00, 0x91, + 0x11, 0xa1, 0x0e, 0x4a, 0x0f, 0x48, 0x02, 0x23, + 0xf6, 0xf7, 0xed, 0x09, 0x00, 0xbc, 0x01, 0x2d, + 0xff, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xdf, 0xee, + 0xe7, 0x02, 0xaa, 0x0d, 0x49, 0x02, 0x20, 0xf7, + 0xf7, 0x3a, 0xfb, 0x00, 0x28, 0x01, 0xd0, 0x00, + 0xdf, 0xe5, 0xe7, 0x01, 0xf0, 0x52, 0xfd, 0xe2, + 0xe7, 0x00, 0x00, 0x30, 0x68, 0x03, 0x20, 0xa0, + 0xbd, 0x03, 0x20, 0xac, 0x68, 0x03, 0x20, 0x94, + 0xb8, 0x03, 0x20, 0x39, 0xb9, 0x01, 0x20, 0x30, + 0xbe, 0x03, 0x20, 0x48, 0x5f, 0x4d, 0x4f, 0x4e, + 0x00, 0x00, 0x00, 0xa1, 0xb7, 0x01, 0x20, 0x00, + 0xb5, 0x04, 0x49, 0x01, 0x20, 0xc8, 0x62, 0x01, + 0xf0, 0x42, 0xfe, 0x01, 0xf0, 0x4e, 0xfd, 0x08, + 0xbc, 0x18, 0x47, 0x28, 0x69, 0x03, 0x20, 0x00, + 0xb5, 0x01, 0xf0, 0x4f, 0xfe, 0x04, 0x48, 0x41, + 0x6b, 0x00, 0x29, 0x02, 0xd1, 0xc1, 0x62, 0x01, + 0xf0, 0x41, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x28, + 0x69, 0x03, 0x20, 0x80, 0xb5, 0x07, 0x1c, 0x0a, + 0x28, 0x02, 0xd1, 0x0d, 0x20, 0xff, 0xf7, 0xf9, + 0xff, 0x01, 0xf0, 0x10, 0xfe, 0x00, 0x28, 0xfb, + 0xd1, 0x38, 0x1c, 0x01, 0xf0, 0x15, 0xfe, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x01, + 0xf0, 0x00, 0xfe, 0x00, 0x28, 0xfb, 0xd0, 0x01, + 0xf0, 0x10, 0xfe, 0x07, 0x1c, 0x05, 0x48, 0x40, + 0x6c, 0x00, 0x28, 0x02, 0xd1, 0x38, 0x1c, 0xff, + 0xf7, 0xe0, 0xff, 0x38, 0x1c, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x28, 0x69, 0x03, 0x20, 0xf0, + 0xb5, 0x26, 0x4d, 0x24, 0x4f, 0x28, 0x7d, 0x3c, + 0x18, 0x01, 0xf0, 0x7b, 0xff, 0x00, 0x28, 0x39, + 0xd1, 0x23, 0x4e, 0x01, 0xf0, 0x66, 0xff, 0x07, + 0x1c, 0x28, 0x6a, 0x00, 0x28, 0x02, 0xd0, 0x38, + 0x1c, 0xff, 0xf7, 0xc7, 0xff, 0x03, 0x2f, 0x02, + 0xd1, 0x00, 0x20, 0x68, 0x64, 0x1d, 0xe0, 0x0a, + 0x2f, 0x01, 0xd0, 0x0d, 0x2f, 0xed, 0x09, 0x00, + 0xbd, 0x01, 0x0e, 0xd1, 0x00, 0x27, 0x27, 0x70, + 0x67, 0x70, 0xa7, 0x70, 0xe7, 0x70, 0x68, 0x46, + 0xb0, 0x67, 0x44, 0x30, 0x70, 0x67, 0x00, 0x20, + 0x01, 0xf0, 0x56, 0xf8, 0x2f, 0x75, 0x11, 0x4c, + 0x1a, 0xe0, 0x08, 0x2f, 0x08, 0xd1, 0x28, 0x7d, + 0x00, 0x28, 0x15, 0xd0, 0x01, 0x38, 0x28, 0x75, + 0x00, 0x20, 0x01, 0x3c, 0x20, 0x70, 0x0f, 0xe0, + 0x27, 0x70, 0x28, 0x7d, 0x01, 0x34, 0x01, 0x30, + 0x28, 0x75, 0x28, 0x7d, 0x4b, 0x28, 0x07, 0xd3, + 0x00, 0x20, 0x28, 0x75, 0x08, 0xa0, 0x00, 0xf0, + 0xd6, 0xfb, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x01, 0xf0, 0x3a, 0xff, 0x00, 0x28, 0xbf, 0xd0, + 0xf7, 0xe7, 0x00, 0x00, 0xe0, 0xbd, 0x03, 0x20, + 0x28, 0x69, 0x03, 0x20, 0xac, 0x68, 0x03, 0x20, + 0x6c, 0x6f, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x6c, 0x69, 0x64, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x64, 0x0a, 0x00, 0x90, 0xb5, 0x14, 0x1c, + 0x0f, 0x1c, 0xff, 0xf7, 0x57, 0xff, 0x04, 0x21, + 0x20, 0x1c, 0x01, 0xf0, 0x1d, 0xfd, 0x1e, 0x4c, + 0x04, 0x21, 0xa0, 0x67, 0x80, 0x6b, 0x01, 0xf0, + 0x17, 0xfd, 0x60, 0x67, 0x1b, 0x48, 0x00, 0x24, + 0x44, 0x64, 0x00, 0x20, 0x02, 0xf0, 0x82, 0xf9, + 0x00, 0x2f, 0x05, 0xd1, 0xf8, 0x43, 0x00, 0xf0, + 0xff, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x01, 0x3f, 0x14, 0x2f, 0x09, 0xd3, 0x79, 0x1c, + 0x13, 0xa0, 0x00, 0xf0, 0x90, 0xfb, 0x00, 0x20, + 0xc0, 0x43, 0x00, 0xf0, 0xf1, 0xff, 0x20, 0x1c, + 0xef, 0xe7, 0x78, 0x00, 0xc0, 0x19, 0x14, 0x49, + 0x80, 0x00, 0x08, 0x58, 0x00, 0x28, 0x09, 0xd1, + 0x79, 0x1c, 0x12, 0xa0, 0x00, 0xf0, 0x7f, 0xfb, + 0xed, 0x09, 0x00, 0xbe, 0x01, 0x00, 0x20, 0xc0, + 0x43, 0x00, 0xf0, 0xe0, 0xff, 0x20, 0x1c, 0xde, + 0xe7, 0x00, 0x22, 0x00, 0x21, 0x38, 0x1c, 0x03, + 0xf0, 0x9f, 0xf8, 0x78, 0x1c, 0x00, 0xf0, 0xd6, + 0xff, 0xd5, 0xe7, 0x00, 0x00, 0xac, 0x68, 0x03, + 0x20, 0x28, 0x69, 0x03, 0x20, 0x0a, 0x23, 0x20, + 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, + 0x53, 0x57, 0x49, 0x20, 0x4e, 0x72, 0x20, 0x25, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x30, 0x68, 0x03, + 0x20, 0x0a, 0x23, 0x20, 0x53, 0x57, 0x49, 0x5f, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x25, + 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x00, 0x80, 0xb5, 0x07, + 0x1c, 0x00, 0x78, 0x00, 0x28, 0x06, 0xd0, 0x38, + 0x78, 0x01, 0x37, 0xff, 0xf7, 0x07, 0xff, 0x38, + 0x78, 0x00, 0x28, 0xf8, 0xd1, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x05, 0x1c, 0x07, + 0x1c, 0x40, 0x18, 0x46, 0x1f, 0x16, 0xa0, 0xff, + 0xf7, 0xe9, 0xff, 0x01, 0xf0, 0x9f, 0xfe, 0x00, + 0x28, 0x03, 0xd0, 0x01, 0xf0, 0x9b, 0xfe, 0x00, + 0x28, 0xfb, 0xd1, 0x01, 0xf0, 0x87, 0xfe, 0x04, + 0x1c, 0x10, 0x48, 0x00, 0x6a, 0x00, 0x28, 0x02, + 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0xe7, 0xfe, 0x0a, + 0x2c, 0x03, 0xd0, 0x0d, 0x2c, 0x01, 0xd0, 0xb7, + 0x42, 0x07, 0xd3, 0x00, 0x20, 0x38, 0x70, 0x78, + 0x70, 0xb8, 0x70, 0xf8, 0x70, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x08, 0x2c, 0x05, 0xd1, 0xaf, + 0x42, 0xdb, 0xd9, 0x00, 0x20, 0x01, 0x3f, 0x38, + 0x70, 0xd7, 0xe7, 0x3c, 0x70, 0x01, 0x37, 0xd4, + 0xe7, 0x0a, 0x23, 0x20, 0x00, 0x28, 0x69, 0x03, + 0x20, 0xb0, 0xb4, 0x1e, 0x49, 0x00, 0x27, 0x00, + 0x23, 0xca, 0x1d, 0x48, 0x32, 0x01, 0xe0, 0x6c, + 0x1c, 0x04, 0x60, 0xed, 0x09, 0x00, 0xbf, 0x01, + 0x05, 0x68, 0x2c, 0x78, 0x00, 0x2c, 0x05, 0xd0, + 0x20, 0x2c, 0xf7, 0xd0, 0x09, 0x2c, 0xf5, 0xd0, + 0x0c, 0x1c, 0x20, 0xe0, 0x18, 0x1c, 0xb0, 0xbc, + 0x70, 0x47, 0x05, 0x68, 0x2d, 0x78, 0x20, 0x2d, + 0x0f, 0xd0, 0x06, 0xdc, 0x09, 0x2d, 0x0c, 0xd0, + 0x0a, 0x2d, 0x16, 0xd0, 0x0d, 0x2d, 0x14, 0xd0, + 0x09, 0xe0, 0x28, 0x2d, 0x03, 0xd0, 0x29, 0x2d, + 0x05, 0xd1, 0x01, 0x3f, 0x03, 0xe0, 0x01, 0x37, + 0x01, 0xe0, 0x00, 0x2f, 0x09, 0xd0, 0x0d, 0x70, + 0x05, 0x68, 0x01, 0x31, 0x01, 0x35, 0x05, 0x60, + 0x2d, 0x78, 0x00, 0x2d, 0x01, 0xd0, 0x8a, 0x42, + 0xdf, 0xd2, 0x8a, 0x42, 0x01, 0xd2, 0x18, 0x1c, + 0xd9, 0xe7, 0x0b, 0x70, 0x20, 0x1c, 0xd6, 0xe7, + 0x00, 0x00, 0x44, 0xbd, 0x03, 0x20, 0xb0, 0xb5, + 0x07, 0x1c, 0x00, 0x68, 0x01, 0x78, 0x28, 0x29, + 0x06, 0xd1, 0x01, 0x30, 0x38, 0x60, 0x38, 0x1c, + 0xff, 0xf7, 0xf5, 0xff, 0x04, 0x1c, 0x03, 0xe0, + 0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xf8, 0x04, 0x1c, + 0x38, 0x68, 0x00, 0x78, 0x00, 0x28, 0x5d, 0xd0, + 0x01, 0x25, 0x05, 0xe0, 0x48, 0x1c, 0x38, 0x60, + 0x38, 0x68, 0x00, 0x78, 0x00, 0x28, 0x15, 0xd0, + 0x39, 0x68, 0x08, 0x78, 0x2b, 0x28, 0x11, 0xd0, + 0x2d, 0x28, 0x0f, 0xd0, 0x26, 0x28, 0x0d, 0xd0, + 0x7c, 0x28, 0x0b, 0xd0, 0x2a, 0x28, 0x09, 0xd0, + 0x2f, 0x28, 0x07, 0xd0, 0x3c, 0x28, 0x05, 0xd0, + 0x3e, 0x28, 0x03, 0xd0, 0x28, 0x28, 0x01, 0xd0, + 0x29, 0x28, 0xe3, 0xd1, 0x38, 0x68, 0x01, 0x78, + 0x2d, 0x29, 0x4c, 0xd0, 0x0a, 0xdc, 0x26, 0x39, + 0x06, 0x29, 0x5d, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, + 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x4b, 0x63, + 0x6c, 0x74, 0x52, 0x3d, 0x2f, 0x29, 0x54, 0xd0, + 0x3c, 0x29, 0x0a, 0xd0, 0x3e, 0x29, 0xed, 0x09, + 0x00, 0xc0, 0x01, 0x1d, 0xd0, 0x7c, 0x29, 0x57, + 0xd1, 0x01, 0x30, 0x38, 0x60, 0x38, 0x1c, 0x00, + 0xf0, 0x76, 0xf8, 0x04, 0x43, 0x50, 0xe0, 0x01, + 0x30, 0x38, 0x60, 0x01, 0x78, 0x3c, 0x29, 0x06, + 0xd1, 0x01, 0x30, 0x38, 0x60, 0x38, 0x1c, 0x00, + 0xf0, 0x6a, 0xf8, 0x84, 0x40, 0x44, 0xe0, 0x38, + 0x1c, 0x00, 0xf0, 0x65, 0xf8, 0x29, 0x1c, 0x84, + 0x42, 0x00, 0xd3, 0x00, 0x21, 0x0c, 0x1c, 0x3b, + 0xe0, 0x01, 0x30, 0x38, 0x60, 0x01, 0x78, 0x3e, + 0x29, 0x07, 0xd1, 0x01, 0x30, 0x38, 0x60, 0x38, + 0x1c, 0x00, 0xf0, 0x55, 0xf8, 0xc4, 0x40, 0x2f, + 0xe0, 0x33, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x4f, + 0xf8, 0x29, 0x1c, 0x84, 0x42, 0x00, 0xd8, 0x00, + 0x21, 0x0c, 0x1c, 0x25, 0xe0, 0x01, 0x30, 0x38, + 0x60, 0x38, 0x1c, 0x00, 0xf0, 0x44, 0xf8, 0x24, + 0x18, 0x1e, 0xe0, 0x01, 0x30, 0x38, 0x60, 0x38, + 0x1c, 0x00, 0xf0, 0x3d, 0xf8, 0x24, 0x1a, 0x17, + 0xe0, 0x01, 0x30, 0x38, 0x60, 0x38, 0x1c, 0x00, + 0xf0, 0x36, 0xf8, 0x04, 0x40, 0x10, 0xe0, 0x01, + 0x30, 0x38, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0x2f, + 0xf8, 0x44, 0x43, 0x09, 0xe0, 0x08, 0xe0, 0x01, + 0x30, 0x38, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0x27, + 0xf8, 0x21, 0x1c, 0xe4, 0xf7, 0x98, 0xfa, 0x04, + 0x1c, 0x38, 0x68, 0x00, 0x78, 0x00, 0x28, 0x00, + 0xd0, 0x70, 0xe7, 0x20, 0x1c, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x38, 0x68, 0x01, 0x30, 0x38, + 0x60, 0x05, 0xa0, 0x00, 0xf0, 0x17, 0xfa, 0x20, + 0x1c, 0xf4, 0xe7, 0x38, 0x68, 0x01, 0x30, 0x38, + 0x60, 0x20, 0x1c, 0xef, 0xe7, 0x00, 0x00, 0x0a, + 0x27, 0x28, 0x27, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x20, 0x21, 0x00, 0xb0, + 0xb5, 0xed, 0x09, 0x00, 0xc1, 0x01, 0x07, 0x1c, + 0x00, 0x20, 0x04, 0x21, 0x01, 0xe0, 0x5a, 0x1c, + 0x3a, 0x60, 0x3b, 0x68, 0x1a, 0x78, 0x00, 0x2a, + 0x0d, 0xd0, 0x20, 0x2a, 0xf7, 0xd0, 0x09, 0x2a, + 0xf5, 0xd0, 0x3c, 0x68, 0x24, 0x78, 0x7e, 0x2c, + 0x08, 0xd1, 0x58, 0x1c, 0x38, 0x60, 0x38, 0x1c, + 0xff, 0xf7, 0xe8, 0xff, 0xc0, 0x43, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x28, 0x2a, 0x05, 0xd1, + 0x58, 0x1c, 0x38, 0x60, 0x38, 0x1c, 0xff, 0xf7, + 0x17, 0xff, 0xf4, 0xe7, 0x2a, 0x2a, 0x06, 0xd1, + 0x58, 0x1c, 0x38, 0x60, 0x38, 0x1c, 0xff, 0xf7, + 0xd5, 0xff, 0x00, 0x68, 0xeb, 0xe7, 0x3a, 0x2a, + 0x64, 0xd1, 0x58, 0x1c, 0x38, 0x60, 0x02, 0x22, + 0xb7, 0xa1, 0x09, 0xf0, 0x2f, 0xff, 0xb7, 0x4c, + 0x00, 0x28, 0x01, 0xd1, 0x20, 0x68, 0xde, 0xe7, + 0x38, 0x68, 0xb5, 0xa1, 0x02, 0x22, 0x09, 0xf0, + 0x25, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x60, 0x68, + 0xd5, 0xe7, 0x38, 0x68, 0xb1, 0xa1, 0x02, 0x22, + 0x09, 0xf0, 0x1c, 0xff, 0x00, 0x28, 0x01, 0xd1, + 0xa0, 0x68, 0xcc, 0xe7, 0x38, 0x68, 0xae, 0xa1, + 0x02, 0x22, 0x09, 0xf0, 0x13, 0xff, 0x00, 0x28, + 0x01, 0xd1, 0xe0, 0x68, 0xc3, 0xe7, 0x38, 0x68, + 0xaa, 0xa1, 0x02, 0x22, 0x09, 0xf0, 0x0a, 0xff, + 0x00, 0x28, 0x01, 0xd1, 0x20, 0x69, 0xba, 0xe7, + 0x38, 0x68, 0xa7, 0xa1, 0x02, 0x22, 0x09, 0xf0, + 0x01, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x60, 0x69, + 0xb1, 0xe7, 0x38, 0x68, 0xa3, 0xa1, 0x02, 0x22, + 0x09, 0xf0, 0xf8, 0xfe, 0x00, 0x28, 0x01, 0xd1, + 0x60, 0x69, 0xa8, 0xe7, 0x38, 0x68, 0xa0, 0xa1, + 0x02, 0x22, 0x09, 0xf0, 0xef, 0xfe, 0x00, 0x28, + 0x01, 0xd1, 0xe0, 0x69, 0x9f, 0xe7, 0x38, 0x68, + 0x9c, 0xa1, 0x02, 0x22, 0x09, 0xf0, 0xe6, 0xfe, + 0x00, 0x28, 0x01, 0xd1, 0xed, 0x09, 0x00, 0xc2, + 0x01, 0x20, 0x6a, 0x96, 0xe7, 0x38, 0x68, 0x99, + 0xa1, 0x02, 0x22, 0x09, 0xf0, 0xdd, 0xfe, 0x00, + 0x28, 0x01, 0xd1, 0x60, 0x6a, 0x8d, 0xe7, 0x38, + 0x68, 0x95, 0xa1, 0x02, 0x22, 0x09, 0xf0, 0xd4, + 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6a, 0x84, + 0xe7, 0xcf, 0xe0, 0x38, 0x68, 0x91, 0xa1, 0x02, + 0x22, 0x09, 0xf0, 0xca, 0xfe, 0x00, 0x28, 0x01, + 0xd1, 0xe0, 0x6a, 0x7a, 0xe7, 0x38, 0x68, 0x8e, + 0xa1, 0x02, 0x22, 0x09, 0xf0, 0xc1, 0xfe, 0x00, + 0x28, 0x01, 0xd1, 0x20, 0x6b, 0x71, 0xe7, 0x38, + 0x68, 0x8a, 0xa1, 0x02, 0x22, 0x09, 0xf0, 0xb8, + 0xfe, 0x00, 0x28, 0x01, 0xd1, 0x60, 0x6b, 0x68, + 0xe7, 0x38, 0x68, 0x87, 0xa1, 0x02, 0x22, 0x09, + 0xf0, 0xaf, 0xfe, 0x00, 0x28, 0x01, 0xd1, 0xa0, + 0x6b, 0x5f, 0xe7, 0x38, 0x68, 0x83, 0xa1, 0x02, + 0x22, 0x09, 0xf0, 0xa6, 0xfe, 0x00, 0x28, 0x01, + 0xd1, 0xe0, 0x6b, 0x56, 0xe7, 0x38, 0x68, 0x80, + 0xa1, 0x02, 0x22, 0x09, 0xf0, 0x9d, 0xfe, 0x7f, + 0x4c, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, 0x40, + 0x68, 0x4b, 0xe7, 0x38, 0x68, 0x7c, 0xa1, 0x02, + 0x22, 0x09, 0xf0, 0x92, 0xfe, 0x00, 0x28, 0x02, + 0xd1, 0xa0, 0x6f, 0x80, 0x68, 0x41, 0xe7, 0x38, + 0x68, 0x78, 0xa1, 0x02, 0x22, 0x09, 0xf0, 0x88, + 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, 0xc0, + 0x68, 0x37, 0xe7, 0x38, 0x68, 0x74, 0xa1, 0x02, + 0x22, 0x09, 0xf0, 0x7e, 0xfe, 0x00, 0x28, 0x02, + 0xd1, 0xa0, 0x6f, 0x00, 0x69, 0x2d, 0xe7, 0x38, + 0x68, 0x70, 0xa1, 0x02, 0x22, 0x09, 0xf0, 0x74, + 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, 0x40, + 0x69, 0x23, 0xe7, 0x38, 0x68, 0x6c, 0xa1, 0x02, + 0x22, 0x09, 0xf0, 0x6a, 0xfe, 0x00, 0x28, 0x02, + 0xd1, 0xa0, 0x6f, 0x80, 0x69, 0x19, 0xe7, 0xed, + 0x09, 0x00, 0xc3, 0x01, 0x38, 0x68, 0x68, 0xa1, + 0x02, 0x22, 0x09, 0xf0, 0x60, 0xfe, 0x00, 0x28, + 0x02, 0xd1, 0xa0, 0x6f, 0xc0, 0x69, 0x0f, 0xe7, + 0x38, 0x68, 0x64, 0xa1, 0x02, 0x22, 0x09, 0xf0, + 0x56, 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, + 0x00, 0x6a, 0x05, 0xe7, 0x38, 0x68, 0x60, 0xa1, + 0x02, 0x22, 0x09, 0xf0, 0x4c, 0xfe, 0x00, 0x28, + 0x02, 0xd1, 0xa0, 0x6f, 0x40, 0x6a, 0xfb, 0xe6, + 0x38, 0x68, 0x5c, 0xa1, 0x02, 0x22, 0x09, 0xf0, + 0x42, 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, + 0x80, 0x6a, 0xf1, 0xe6, 0x38, 0x68, 0x58, 0xa1, + 0x02, 0x22, 0x09, 0xf0, 0x38, 0xfe, 0x00, 0x28, + 0x02, 0xd1, 0xa0, 0x6f, 0xc0, 0x6a, 0xe7, 0xe6, + 0x38, 0x68, 0x54, 0xa1, 0x02, 0x22, 0x09, 0xf0, + 0x2e, 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, + 0x00, 0x6b, 0xdd, 0xe6, 0x38, 0x68, 0x50, 0xa1, + 0x02, 0x22, 0x09, 0xf0, 0x24, 0xfe, 0x00, 0x28, + 0x02, 0xd1, 0xa0, 0x6f, 0x40, 0x6b, 0xd3, 0xe6, + 0x38, 0x68, 0x4c, 0xa1, 0x02, 0x22, 0x09, 0xf0, + 0x1a, 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, + 0xc0, 0x6b, 0xc9, 0xe6, 0x38, 0x68, 0x48, 0xa1, + 0x02, 0x22, 0x09, 0xf0, 0x10, 0xfe, 0x00, 0x28, + 0x02, 0xd1, 0xa0, 0x6f, 0x80, 0x6b, 0xbf, 0xe6, + 0x38, 0x68, 0x44, 0xa1, 0x02, 0x22, 0x09, 0xf0, + 0x06, 0xfe, 0x00, 0x28, 0x02, 0xd1, 0xa0, 0x6f, + 0x00, 0x6c, 0xb5, 0xe6, 0x00, 0x20, 0xb3, 0xe6, + 0x23, 0x2a, 0x04, 0xd1, 0x58, 0x1c, 0x38, 0x60, + 0x09, 0xf0, 0xdb, 0xfb, 0xac, 0xe6, 0x78, 0x2a, + 0x02, 0xd1, 0x59, 0x1c, 0x39, 0x60, 0x04, 0x21, + 0x3a, 0x68, 0x13, 0x78, 0x6f, 0x2b, 0x02, 0xd1, + 0x51, 0x1c, 0x39, 0x60, 0x03, 0x21, 0x3a, 0x68, + 0x13, 0x78, 0x42, 0x2b, 0x02, 0xd1, 0x51, 0x1c, + 0x39, 0x60, 0xed, 0x09, 0x00, 0xc4, 0x01, 0x01, + 0x21, 0x3a, 0x68, 0x12, 0x78, 0x00, 0x2a, 0x84, + 0xd0, 0x3d, 0x68, 0x2a, 0x78, 0xd4, 0x1f, 0x29, + 0x3c, 0x09, 0x2c, 0x02, 0xd8, 0x88, 0x40, 0x20, + 0x18, 0x0e, 0xe0, 0xd3, 0x1f, 0x3a, 0x3b, 0x05, + 0x2b, 0x03, 0xd8, 0x88, 0x40, 0x37, 0x3a, 0x10, + 0x18, 0x06, 0xe0, 0xd3, 0x1f, 0x5a, 0x3b, 0x05, + 0x2b, 0x8d, 0xd8, 0x88, 0x40, 0x57, 0x3a, 0x10, + 0x18, 0x6a, 0x1c, 0x3a, 0x60, 0x12, 0x78, 0x00, + 0x2a, 0xe2, 0xd1, 0x77, 0xe6, 0x00, 0x00, 0x74, + 0x31, 0x00, 0x00, 0xa0, 0xbd, 0x03, 0x20, 0x74, + 0x32, 0x00, 0x00, 0x74, 0x33, 0x00, 0x00, 0x74, + 0x34, 0x00, 0x00, 0x74, 0x35, 0x00, 0x00, 0x74, + 0x36, 0x00, 0x00, 0x74, 0x37, 0x00, 0x00, 0x74, + 0x38, 0x00, 0x00, 0x74, 0x39, 0x00, 0x00, 0x74, + 0x31, 0x30, 0x00, 0x74, 0x31, 0x31, 0x00, 0x74, + 0x31, 0x32, 0x00, 0x74, 0x31, 0x33, 0x00, 0x74, + 0x31, 0x34, 0x00, 0x74, 0x31, 0x35, 0x00, 0x74, + 0x31, 0x36, 0x00, 0x61, 0x31, 0x00, 0x00, 0xac, + 0x68, 0x03, 0x20, 0x61, 0x32, 0x00, 0x00, 0x61, + 0x33, 0x00, 0x00, 0x61, 0x34, 0x00, 0x00, 0x76, + 0x31, 0x00, 0x00, 0x76, 0x32, 0x00, 0x00, 0x76, + 0x33, 0x00, 0x00, 0x76, 0x34, 0x00, 0x00, 0x76, + 0x35, 0x00, 0x00, 0x76, 0x36, 0x00, 0x00, 0x76, + 0x37, 0x00, 0x00, 0x76, 0x38, 0x00, 0x00, 0x69, + 0x70, 0x00, 0x00, 0x6c, 0x72, 0x00, 0x00, 0x73, + 0x70, 0x00, 0x00, 0x70, 0x63, 0x00, 0x00, 0x80, + 0xb4, 0x00, 0x27, 0x03, 0xe0, 0x03, 0x70, 0x01, + 0x30, 0x01, 0x31, 0x01, 0x3a, 0x00, 0x23, 0xcb, + 0x56, 0x00, 0x2b, 0x08, 0xd0, 0x20, 0x2b, 0x06, + 0xd0, 0x0a, 0x2b, 0x04, 0xd0, 0x09, 0x2b, 0x02, + 0xd0, 0x00, 0x2a, 0xef, 0xd1, 0x05, 0xe0, 0x00, + 0x2a, 0x03, 0xd0, 0x07, 0x70, 0xed, 0x09, 0x00, + 0xc5, 0x01, 0x01, 0x30, 0x01, 0x3a, 0xfb, 0xd1, + 0x07, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x0f, 0xb4, + 0xf0, 0xb5, 0xbb, 0xb0, 0x00, 0x21, 0x40, 0x98, + 0x13, 0x91, 0x00, 0x23, 0xc0, 0x56, 0x00, 0x27, + 0x41, 0xac, 0x00, 0x28, 0x73, 0xd0, 0x0a, 0xaa, + 0x01, 0x32, 0x3a, 0x92, 0x0c, 0xe0, 0x3d, 0x2f, + 0x0a, 0xd3, 0x00, 0x21, 0x1a, 0xa8, 0xc1, 0x55, + 0xff, 0xf7, 0x9a, 0xfc, 0x02, 0x22, 0x39, 0x1c, + 0x1a, 0xa8, 0xf8, 0xf7, 0x95, 0xfe, 0x00, 0x27, + 0x40, 0x98, 0x00, 0x23, 0xc1, 0x56, 0x08, 0x29, + 0x0c, 0xd0, 0x09, 0x29, 0x0e, 0xd0, 0x25, 0x29, + 0x67, 0xd1, 0x01, 0x30, 0x40, 0x90, 0x00, 0x20, + 0x00, 0x26, 0x00, 0x25, 0x16, 0x90, 0x14, 0x90, + 0x15, 0x90, 0x42, 0xe0, 0x00, 0x2f, 0x65, 0xd0, + 0x01, 0x3f, 0x76, 0xe3, 0xb8, 0x07, 0x61, 0xd0, + 0x20, 0x22, 0x38, 0x1c, 0x1a, 0xa9, 0x0a, 0x54, + 0x01, 0x37, 0xb8, 0x07, 0xf9, 0xd1, 0x6c, 0xe3, + 0x2d, 0x28, 0x03, 0xd1, 0x01, 0x20, 0x14, 0x90, + 0x08, 0x18, 0x40, 0x90, 0x40, 0x98, 0x00, 0x23, + 0xc1, 0x56, 0x20, 0x29, 0x04, 0xd1, 0x00, 0x2d, + 0x00, 0xd1, 0x20, 0x25, 0x01, 0x30, 0x40, 0x90, + 0x40, 0x98, 0x00, 0x23, 0xc1, 0x56, 0x2b, 0x29, + 0x02, 0xd1, 0x2b, 0x25, 0x01, 0x30, 0x40, 0x90, + 0x40, 0x98, 0x00, 0x23, 0xc1, 0x56, 0x30, 0x29, + 0x06, 0xd1, 0x01, 0x30, 0x40, 0x90, 0x14, 0x98, + 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20, 0x15, 0x90, + 0x40, 0x98, 0x00, 0x23, 0xc1, 0x56, 0x23, 0x29, + 0x02, 0xd1, 0x30, 0x25, 0x01, 0x30, 0x40, 0x90, + 0x40, 0x98, 0x00, 0x23, 0xc0, 0x56, 0x3a, 0x28, + 0x03, 0xd1, 0x40, 0x98, 0x3a, 0x25, 0x01, 0x30, + 0x40, 0x90, 0x40, 0x99, 0x00, 0x23, 0xc8, 0x56, + 0x2d, 0x28, 0xc5, 0xd0, 0x2b, 0x28, 0xc3, 0xd0, + 0xed, 0x09, 0x00, 0xc6, 0x01, 0x20, 0x28, 0xc1, + 0xd0, 0x30, 0x28, 0xbf, 0xd0, 0x23, 0x28, 0xbd, + 0xd0, 0x00, 0xe0, 0x7d, 0xe3, 0x3a, 0x28, 0xb9, + 0xd0, 0x40, 0x9a, 0xd2, 0x56, 0x2a, 0x2a, 0x07, + 0xd1, 0x48, 0x1c, 0x40, 0x90, 0x04, 0x34, 0xe0, + 0x1f, 0x39, 0x38, 0xc6, 0x6b, 0x11, 0xe0, 0x70, + 0xe3, 0x30, 0x38, 0x09, 0x28, 0x0d, 0xd8, 0x08, + 0x1c, 0x09, 0xf0, 0xae, 0xfa, 0x06, 0x1c, 0x02, + 0xe0, 0x68, 0xe3, 0x01, 0x30, 0x40, 0x90, 0x40, + 0x98, 0x00, 0x23, 0xc1, 0x56, 0x30, 0x39, 0x09, + 0x29, 0xf7, 0xd9, 0x40, 0x98, 0x00, 0x23, 0xc1, + 0x56, 0x2e, 0x29, 0x18, 0xd1, 0x01, 0x30, 0x40, + 0x90, 0xc1, 0x56, 0x2a, 0x29, 0x07, 0xd1, 0x01, + 0x30, 0x40, 0x90, 0x04, 0x34, 0xe0, 0x1f, 0x39, + 0x38, 0xc0, 0x6b, 0x16, 0x90, 0x0b, 0xe0, 0x09, + 0xf0, 0x8f, 0xfa, 0x16, 0x90, 0x01, 0xe0, 0x01, + 0x30, 0x40, 0x90, 0x40, 0x98, 0x00, 0x23, 0xc1, + 0x56, 0x30, 0x39, 0x09, 0x29, 0xf7, 0xd9, 0x16, + 0x98, 0xb0, 0x42, 0x00, 0xd9, 0x16, 0x9e, 0x40, + 0x98, 0x00, 0x23, 0xc1, 0x56, 0x4e, 0x29, 0x1c, + 0xd0, 0x17, 0xdc, 0x46, 0x29, 0x19, 0xd0, 0x4c, + 0x29, 0x03, 0xd1, 0x01, 0x21, 0x40, 0x18, 0x40, + 0x90, 0x13, 0x91, 0x40, 0x98, 0x00, 0x23, 0xc0, + 0x56, 0x69, 0x28, 0x19, 0xd0, 0x35, 0xdc, 0x58, + 0x28, 0x50, 0xd0, 0x0f, 0xdc, 0x25, 0x28, 0x3f, + 0xd0, 0x42, 0x28, 0x54, 0xd0, 0x50, 0x28, 0x53, + 0xd1, 0xfb, 0xe0, 0x68, 0x29, 0x01, 0xd0, 0x6c, + 0x29, 0xeb, 0xd1, 0x00, 0x21, 0x01, 0x30, 0x40, + 0x90, 0x13, 0x91, 0xe6, 0xe7, 0x62, 0x28, 0x5a, + 0xd0, 0x63, 0x28, 0x3c, 0xd0, 0x64, 0x28, 0x43, + 0xd1, 0x13, 0x99, 0x01, 0x29, 0x54, 0xd1, 0x08, + 0x34, 0xe1, 0x1f, 0x01, 0x39, 0x08, 0x68, 0xf5, + 0xa3, 0x11, 0x90, 0xed, 0x09, 0x00, 0xc7, 0x01, + 0x49, 0x68, 0x12, 0x91, 0x1a, 0x68, 0x5b, 0x68, + 0xe4, 0xf7, 0x43, 0xf8, 0x00, 0x28, 0x6a, 0xd0, + 0x2d, 0x21, 0x1a, 0xa8, 0xc1, 0x55, 0x11, 0x98, + 0x12, 0x99, 0x00, 0x22, 0xe4, 0xf7, 0x4b, 0xf8, + 0x11, 0x90, 0x12, 0x91, 0x01, 0x37, 0x76, 0xe0, + 0xc1, 0x1f, 0x67, 0x39, 0x0b, 0x29, 0x5b, 0xd2, + 0x02, 0xa3, 0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, + 0x00, 0x1c, 0x0b, 0xc8, 0xc7, 0xc6, 0xc6, 0xc5, + 0xc4, 0x1f, 0xc6, 0xc6, 0xc3, 0x00, 0x25, 0x21, + 0x1a, 0xa8, 0xc1, 0x55, 0x01, 0x37, 0x56, 0xe2, + 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, 0x6b, + 0x07, 0x60, 0x40, 0x98, 0x01, 0x30, 0x40, 0x90, + 0x4d, 0xe2, 0x80, 0xe2, 0x04, 0x34, 0xe0, 0x1f, + 0x39, 0x38, 0xc0, 0x6b, 0x1a, 0xa9, 0xc8, 0x55, + 0x01, 0x37, 0x44, 0xe2, 0x25, 0xe1, 0x05, 0xe3, + 0x00, 0x2d, 0x02, 0xd0, 0x1a, 0xa8, 0xc5, 0x55, + 0x01, 0x37, 0x13, 0x99, 0x01, 0x29, 0x0b, 0xd1, + 0x08, 0x34, 0xe1, 0x1f, 0x01, 0x39, 0x08, 0x68, + 0x49, 0x68, 0x0a, 0x23, 0x0b, 0xaa, 0x09, 0xf0, + 0x38, 0xfa, 0x09, 0xe0, 0x83, 0xe0, 0x41, 0xe0, + 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, 0x6b, + 0x0a, 0x22, 0x0b, 0xa9, 0x09, 0xf0, 0xfb, 0xfa, + 0x0b, 0xa8, 0x09, 0xf0, 0x54, 0xfb, 0x05, 0x1c, + 0x14, 0x98, 0x01, 0x28, 0x06, 0xd1, 0x1a, 0xa8, + 0xc0, 0x19, 0x2a, 0x1c, 0x0b, 0xa9, 0xe3, 0xf7, + 0xfe, 0xff, 0x7f, 0x19, 0xae, 0x42, 0x12, 0xd9, + 0x20, 0x22, 0x30, 0x21, 0x15, 0x98, 0x00, 0x28, + 0x07, 0xd0, 0x14, 0x98, 0x00, 0x28, 0x04, 0xd1, + 0x1a, 0xa8, 0xc1, 0x55, 0x03, 0xe0, 0x11, 0xe0, + 0xcc, 0xe2, 0x1a, 0xa8, 0xc2, 0x55, 0x01, 0x3e, + 0x01, 0x37, 0xae, 0x42, 0xee, 0xd8, 0x14, 0x98, + 0x00, 0x28, 0x06, 0xd1, 0x1a, 0xa8, 0xed, 0x09, + 0x00, 0xc8, 0x01, 0xc0, 0x19, 0x2a, 0x1c, 0x0b, + 0xa9, 0xe3, 0xf7, 0xdf, 0xff, 0x7f, 0x19, 0xf8, + 0xe1, 0x00, 0x2d, 0x02, 0xd0, 0x1a, 0xa8, 0xc5, + 0x55, 0x01, 0x37, 0x0a, 0x23, 0x11, 0x98, 0x12, + 0x99, 0x0b, 0xaa, 0x09, 0xf0, 0xf4, 0xf9, 0x14, + 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, + 0x6b, 0x00, 0x28, 0x05, 0xda, 0x2d, 0x22, 0x1a, + 0xa9, 0xca, 0x55, 0x40, 0x42, 0x01, 0x37, 0x04, + 0xe0, 0x00, 0x2d, 0x02, 0xd0, 0x1a, 0xa9, 0xcd, + 0x55, 0x01, 0x37, 0x0a, 0x22, 0x0b, 0xa9, 0x09, + 0xf0, 0xac, 0xfa, 0x0b, 0xa8, 0x09, 0xf0, 0x05, + 0xfb, 0x05, 0x1c, 0x14, 0x98, 0x01, 0x28, 0x06, + 0xd1, 0x1a, 0xa8, 0xc0, 0x19, 0x2a, 0x1c, 0x0b, + 0xa9, 0xe3, 0xf7, 0xaf, 0xff, 0x7f, 0x19, 0xae, + 0x42, 0x10, 0xd9, 0x20, 0x22, 0x30, 0x21, 0x15, + 0x98, 0x00, 0x28, 0x05, 0xd0, 0x14, 0x98, 0x00, + 0x28, 0x02, 0xd1, 0x1a, 0xa8, 0xc1, 0x55, 0x01, + 0xe0, 0x1a, 0xa8, 0xc2, 0x55, 0x01, 0x3e, 0x01, + 0x37, 0xae, 0x42, 0xf0, 0xd8, 0x14, 0x98, 0x00, + 0x28, 0x06, 0xd1, 0x1a, 0xa8, 0xc0, 0x19, 0x2a, + 0x1c, 0x0b, 0xa9, 0xe3, 0xf7, 0x92, 0xff, 0x7f, + 0x19, 0xab, 0xe1, 0x13, 0x99, 0x01, 0x29, 0x0f, + 0xd1, 0x08, 0x34, 0x6a, 0x46, 0xe1, 0x1f, 0x01, + 0x39, 0x08, 0x68, 0x49, 0x68, 0x02, 0x23, 0x09, + 0xf0, 0xa6, 0xf9, 0x0d, 0xe0, 0xd1, 0xe1, 0x43, + 0xe2, 0xf6, 0xe0, 0x5d, 0xe2, 0x41, 0xe1, 0x33, + 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0x69, + 0x46, 0x02, 0x22, 0xc0, 0x6b, 0x09, 0xf0, 0x65, + 0xfa, 0x68, 0x46, 0x09, 0xf0, 0xbe, 0xfa, 0x05, + 0x1c, 0x14, 0x98, 0x01, 0x28, 0x06, 0xd1, 0x1a, + 0xa8, 0xc0, 0x19, 0x69, 0x46, 0x2a, 0x1c, 0xe3, + 0xf7, 0x68, 0xff, 0x7f, 0x19, 0xae, 0x42, 0x10, + 0xd9, 0xed, 0x09, 0x00, 0xc9, 0x01, 0x20, 0x22, + 0x30, 0x21, 0x15, 0x98, 0x00, 0x28, 0x05, 0xd0, + 0x14, 0x98, 0x00, 0x28, 0x02, 0xd1, 0x1a, 0xa8, + 0xc1, 0x55, 0x01, 0xe0, 0x1a, 0xa8, 0xc2, 0x55, + 0x01, 0x3e, 0x01, 0x37, 0xae, 0x42, 0xf0, 0xd8, + 0x14, 0x98, 0x00, 0x28, 0x06, 0xd1, 0x1a, 0xa8, + 0xc0, 0x19, 0x69, 0x46, 0x2a, 0x1c, 0xe3, 0xf7, + 0x4b, 0xff, 0x7f, 0x19, 0x64, 0xe1, 0x30, 0x2d, + 0x03, 0xd1, 0x0a, 0xab, 0x1d, 0x70, 0x3a, 0x9a, + 0x00, 0xe0, 0x0a, 0xaa, 0x13, 0x99, 0x01, 0x29, + 0x08, 0xd1, 0x08, 0x34, 0xe1, 0x1f, 0x01, 0x39, + 0x08, 0x68, 0x49, 0x68, 0x08, 0x23, 0x09, 0xf0, + 0x59, 0xf9, 0x07, 0xe0, 0x04, 0x34, 0xe0, 0x1f, + 0x39, 0x38, 0x11, 0x1c, 0x08, 0x22, 0xc0, 0x6b, + 0x09, 0xf0, 0x1e, 0xfa, 0x0a, 0xa8, 0x09, 0xf0, + 0x77, 0xfa, 0x05, 0x1c, 0x14, 0x98, 0x01, 0x28, + 0x06, 0xd1, 0x1a, 0xa8, 0xc0, 0x19, 0x2a, 0x1c, + 0x0a, 0xa9, 0xe3, 0xf7, 0x21, 0xff, 0x7f, 0x19, + 0xae, 0x42, 0x10, 0xd9, 0x20, 0x22, 0x30, 0x21, + 0x15, 0x98, 0x00, 0x28, 0x05, 0xd0, 0x14, 0x98, + 0x00, 0x28, 0x02, 0xd1, 0x1a, 0xa8, 0xc1, 0x55, + 0x01, 0xe0, 0x1a, 0xa8, 0xc2, 0x55, 0x01, 0x3e, + 0x01, 0x37, 0xae, 0x42, 0xf0, 0xd8, 0x14, 0x98, + 0x00, 0x28, 0x06, 0xd1, 0x1a, 0xa8, 0xc0, 0x19, + 0x2a, 0x1c, 0x0a, 0xa9, 0xe3, 0xf7, 0x04, 0xff, + 0x7f, 0x19, 0x1d, 0xe1, 0x45, 0x49, 0x0b, 0xa8, + 0x0c, 0xc9, 0x0c, 0xc0, 0x0e, 0xc9, 0x0e, 0xc0, + 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, 0x6b, + 0x00, 0x2e, 0x10, 0x90, 0x00, 0xd1, 0x01, 0x26, + 0x14, 0x98, 0x01, 0x28, 0x03, 0xd1, 0x10, 0x98, + 0x80, 0x19, 0x01, 0x38, 0x10, 0x90, 0x70, 0x1e, + 0x17, 0x90, 0x00, 0x2e, 0x53, 0xd0, 0x3a, 0x26, + 0x75, 0x2f, 0x0a, 0xd3, 0xed, 0x09, 0x00, 0xca, + 0x01, 0x00, 0x21, 0x1a, 0xa8, 0xc1, 0x55, 0xff, + 0xf7, 0x37, 0xfa, 0x02, 0x22, 0x39, 0x1c, 0x1a, + 0xa8, 0xf8, 0xf7, 0x32, 0xfc, 0x00, 0x27, 0x30, + 0x2d, 0x06, 0xd1, 0x30, 0x22, 0x1a, 0xa9, 0xca, + 0x55, 0x78, 0x22, 0x78, 0x1c, 0x0a, 0x54, 0x47, + 0x1c, 0x10, 0x98, 0x00, 0x28, 0x14, 0xd1, 0x28, + 0x20, 0x1a, 0xaa, 0xd0, 0x55, 0x79, 0x1c, 0x6e, + 0x23, 0x53, 0x54, 0x48, 0x1c, 0x75, 0x23, 0x13, + 0x54, 0x41, 0x1c, 0x6c, 0x23, 0x53, 0x54, 0x48, + 0x1c, 0x01, 0x1c, 0x53, 0x54, 0x29, 0x22, 0x01, + 0x30, 0x1a, 0xa9, 0x0a, 0x54, 0x47, 0x1c, 0x2f, + 0xe0, 0x10, 0x98, 0x0b, 0xa9, 0x00, 0x78, 0x1a, + 0xaa, 0x00, 0x09, 0x09, 0x5c, 0xd1, 0x55, 0x10, + 0x99, 0x09, 0x78, 0x09, 0x07, 0x09, 0x0f, 0x3c, + 0x3a, 0x51, 0x5c, 0x78, 0x1c, 0x1a, 0xaa, 0x11, + 0x54, 0x47, 0x1c, 0x14, 0x98, 0x01, 0x28, 0x03, + 0xd1, 0x10, 0x98, 0x01, 0x38, 0x10, 0x90, 0x02, + 0xe0, 0x10, 0x98, 0x01, 0x30, 0x10, 0x90, 0x17, + 0x98, 0x00, 0x28, 0x0c, 0xd0, 0x3a, 0x2d, 0x05, + 0xd1, 0x38, 0x1c, 0x1a, 0xa9, 0x0e, 0x54, 0x01, + 0x37, 0x05, 0xe0, 0x09, 0xe0, 0x20, 0x22, 0x38, + 0x1c, 0x1a, 0xa9, 0x0a, 0x54, 0x01, 0x37, 0x17, + 0x98, 0x41, 0x1e, 0x17, 0x91, 0x00, 0x28, 0xa1, + 0xd1, 0xa4, 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, + 0x38, 0xc1, 0x6b, 0x19, 0x91, 0x00, 0x29, 0x01, + 0xd1, 0x06, 0xa1, 0x19, 0x91, 0x16, 0x98, 0x00, + 0x28, 0x0e, 0xd1, 0x7f, 0x20, 0xc0, 0x1b, 0x09, + 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x5e, 0x03, 0x20, 0x28, 0x6e, 0x75, + 0x6c, 0x6c, 0x29, 0x00, 0x00, 0x02, 0x38, 0x16, + 0x90, 0x00, 0x25, 0x00, 0xe0, 0x01, 0x35, 0x19, + 0x99, 0x48, 0x57, 0x00, 0x28, 0x02, 0xd0, 0xed, + 0x09, 0x00, 0xcb, 0x01, 0x16, 0x98, 0x85, 0x42, + 0xf7, 0xd3, 0x14, 0x98, 0x01, 0x28, 0x06, 0xd1, + 0x1a, 0xa8, 0xc0, 0x19, 0x2a, 0x1c, 0x19, 0x99, + 0xe3, 0xf7, 0x5b, 0xfe, 0x7f, 0x19, 0xae, 0x42, + 0x10, 0xd9, 0x20, 0x22, 0x30, 0x21, 0x15, 0x98, + 0x00, 0x28, 0x05, 0xd0, 0x14, 0x98, 0x00, 0x28, + 0x02, 0xd1, 0x1a, 0xa8, 0xc1, 0x55, 0x01, 0xe0, + 0x1a, 0xa8, 0xc2, 0x55, 0x01, 0x3e, 0x01, 0x37, + 0xae, 0x42, 0xf0, 0xd8, 0x14, 0x98, 0x00, 0x28, + 0x5f, 0xd1, 0x1a, 0xa8, 0xc0, 0x19, 0x2a, 0x1c, + 0x19, 0x99, 0xe3, 0xf7, 0x3e, 0xfe, 0x7f, 0x19, + 0x1d, 0xe1, 0x13, 0x99, 0x01, 0x29, 0x1b, 0xd1, + 0x08, 0x34, 0xe1, 0x1f, 0x01, 0x39, 0x08, 0x68, + 0x9d, 0xa3, 0x0a, 0x90, 0x49, 0x68, 0x0b, 0x91, + 0x1a, 0x68, 0x5b, 0x68, 0xe3, 0xf7, 0x55, 0xff, + 0x00, 0x28, 0x06, 0xd0, 0x01, 0xa1, 0x07, 0x22, + 0x98, 0x39, 0x0c, 0xa8, 0xe3, 0xf7, 0x25, 0xfe, + 0x05, 0xe0, 0x10, 0x23, 0x0a, 0x98, 0x0b, 0x99, + 0x0c, 0xaa, 0x09, 0xf0, 0x40, 0xf8, 0x10, 0xe0, + 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, 0x6b, + 0x00, 0x28, 0x06, 0xd1, 0x01, 0xa1, 0x07, 0x22, + 0xc0, 0x39, 0x0c, 0xa8, 0xe3, 0xf7, 0x11, 0xfe, + 0x03, 0xe0, 0x10, 0x22, 0x0c, 0xa9, 0x09, 0xf0, + 0xfc, 0xf8, 0x0c, 0xa8, 0x09, 0xf0, 0x55, 0xf9, + 0x18, 0x90, 0x14, 0x98, 0x01, 0x28, 0x02, 0xd0, + 0x18, 0x98, 0x86, 0x42, 0x1e, 0xd8, 0x30, 0x2d, + 0x07, 0xd1, 0x30, 0x21, 0x1a, 0xaa, 0xd1, 0x55, + 0x78, 0x22, 0x78, 0x1c, 0x1a, 0xa9, 0x0a, 0x54, + 0x47, 0x1c, 0x1a, 0xa8, 0xc0, 0x19, 0x18, 0x9a, + 0x0c, 0xa9, 0xe3, 0xf7, 0xf2, 0xfd, 0x18, 0x98, + 0x3f, 0x18, 0x86, 0x42, 0x3b, 0xd9, 0x20, 0x22, + 0x38, 0x1c, 0x1a, 0xa9, 0x0a, 0x54, 0x18, 0x98, + 0x01, 0x37, 0xed, 0x09, 0x00, 0xcc, 0x01, 0x01, + 0x3e, 0x86, 0x42, 0xf7, 0xd8, 0x31, 0xe0, 0xc4, + 0xe0, 0x15, 0x98, 0x00, 0x28, 0x12, 0xd0, 0x30, + 0x2d, 0x06, 0xd1, 0x30, 0x21, 0x1a, 0xaa, 0xd1, + 0x55, 0x78, 0x21, 0x78, 0x1c, 0x11, 0x54, 0x47, + 0x1c, 0x30, 0x22, 0x38, 0x1c, 0x1a, 0xa9, 0x0a, + 0x54, 0x18, 0x98, 0x01, 0x37, 0x01, 0x3e, 0x86, + 0x42, 0xf7, 0xd8, 0x12, 0xe0, 0x20, 0x22, 0x38, + 0x1c, 0x1a, 0xa9, 0x0a, 0x54, 0x18, 0x98, 0x01, + 0x37, 0x01, 0x3e, 0x86, 0x42, 0xf7, 0xd8, 0x30, + 0x2d, 0x07, 0xd1, 0x30, 0x21, 0x1a, 0xaa, 0xd1, + 0x55, 0x78, 0x22, 0x78, 0x1c, 0x1a, 0xa9, 0x0a, + 0x54, 0x47, 0x1c, 0x1a, 0xa8, 0xc0, 0x19, 0x18, + 0x9a, 0x0c, 0xa9, 0xe3, 0xf7, 0xb4, 0xfd, 0x18, + 0x98, 0x3f, 0x18, 0x92, 0xe0, 0x97, 0xe0, 0x13, + 0x99, 0x01, 0x29, 0x09, 0xd1, 0x08, 0x34, 0xe1, + 0x1f, 0x01, 0x39, 0x08, 0x68, 0x49, 0x68, 0x10, + 0x23, 0x0c, 0xaa, 0x08, 0xf0, 0xc6, 0xff, 0x07, + 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, 0xc0, + 0x6b, 0x10, 0x22, 0x0c, 0xa9, 0x09, 0xf0, 0x8b, + 0xf8, 0x0c, 0xa8, 0x09, 0xf0, 0xe4, 0xf8, 0x18, + 0x90, 0x14, 0x98, 0x01, 0x28, 0x02, 0xd0, 0x18, + 0x98, 0x86, 0x42, 0x1d, 0xd8, 0x30, 0x2d, 0x07, + 0xd1, 0x30, 0x21, 0x1a, 0xaa, 0xd1, 0x55, 0x78, + 0x22, 0x78, 0x1c, 0x1a, 0xa9, 0x0a, 0x54, 0x47, + 0x1c, 0x1a, 0xa8, 0xc0, 0x19, 0x18, 0x9a, 0x0c, + 0xa9, 0xe3, 0xf7, 0x81, 0xfd, 0x18, 0x98, 0x3f, + 0x18, 0x86, 0x42, 0x3e, 0xd9, 0x20, 0x22, 0x38, + 0x1c, 0x1a, 0xa9, 0x0a, 0x54, 0x18, 0x98, 0x01, + 0x37, 0x01, 0x3e, 0x86, 0x42, 0xf7, 0xd8, 0x34, + 0xe0, 0x15, 0x98, 0x00, 0x28, 0x16, 0xd0, 0x30, + 0x2d, 0x07, 0xd1, 0x30, 0x21, 0x1a, 0xaa, 0xd1, + 0x55, 0x78, 0x22, 0x78, 0x1c, 0xed, 0x09, 0x00, + 0xcd, 0x01, 0x1a, 0xa9, 0x0a, 0x54, 0x47, 0x1c, + 0x30, 0x22, 0x38, 0x1c, 0x1a, 0xa9, 0x0a, 0x54, + 0x18, 0x98, 0x01, 0x37, 0x01, 0x3e, 0x86, 0x42, + 0xf7, 0xd8, 0x15, 0xe0, 0x4d, 0xe0, 0x3e, 0xe0, + 0x40, 0xe0, 0x20, 0x22, 0x38, 0x1c, 0x1a, 0xa9, + 0x0a, 0x54, 0x18, 0x98, 0x01, 0x37, 0x01, 0x3e, + 0x86, 0x42, 0xf7, 0xd8, 0x30, 0x2d, 0x07, 0xd1, + 0x30, 0x21, 0x1a, 0xaa, 0xd1, 0x55, 0x78, 0x22, + 0x78, 0x1c, 0x1a, 0xa9, 0x0a, 0x54, 0x47, 0x1c, + 0x1a, 0xa8, 0xc0, 0x19, 0x18, 0x9a, 0x0c, 0xa9, + 0xe3, 0xf7, 0x40, 0xfd, 0x18, 0x98, 0x3f, 0x18, + 0x1e, 0xe0, 0x04, 0x34, 0xe0, 0x1f, 0x39, 0x38, + 0x54, 0x21, 0xc9, 0x43, 0xc0, 0x6b, 0x1a, 0xab, + 0xd9, 0x55, 0x7a, 0x1c, 0x98, 0x54, 0x03, 0x0a, + 0x51, 0x1c, 0x1a, 0xaf, 0x7b, 0x54, 0x03, 0x0c, + 0x4a, 0x1c, 0xbb, 0x54, 0x00, 0x0e, 0x51, 0x1c, + 0x1a, 0xab, 0x58, 0x54, 0x45, 0x20, 0xc0, 0x43, + 0x4a, 0x1c, 0x1a, 0xa9, 0x88, 0x54, 0x57, 0x1c, + 0x02, 0xe0, 0x1a, 0xa9, 0xc8, 0x55, 0x01, 0x37, + 0x00, 0x21, 0x13, 0x91, 0x02, 0xe0, 0x1a, 0xa8, + 0xc1, 0x55, 0x01, 0x37, 0x40, 0x98, 0x00, 0x23, + 0x01, 0x30, 0x40, 0x90, 0xc0, 0x56, 0x00, 0x28, + 0x01, 0xd0, 0xff, 0xf7, 0xc4, 0xfb, 0x00, 0x2f, + 0x04, 0xd1, 0x3b, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x04, 0xb0, 0x18, 0x47, 0x00, 0x20, 0x1a, 0xa9, + 0xc8, 0x55, 0x1a, 0xa8, 0xff, 0xf7, 0x58, 0xf8, + 0x02, 0x22, 0x39, 0x1c, 0x1a, 0xa8, 0xf8, 0xf7, + 0x53, 0xfa, 0x00, 0xf0, 0x9f, 0xfc, 0xec, 0xe7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xb5, 0x85, 0xb0, 0x00, 0x21, 0x01, 0x91, + 0x00, 0x28, 0x05, 0xd1, 0xe9, 0x4e, 0x74, 0x1c, + 0x60, 0x1e, 0x04, 0x90, 0x65, 0x1c, 0x1e, 0xe0, + 0xed, 0x09, 0x00, 0xce, 0x01, 0x47, 0x1e, 0x14, + 0x2f, 0x10, 0xd2, 0x01, 0x20, 0x01, 0x90, 0x13, + 0x2f, 0x14, 0xd0, 0x00, 0xf0, 0xad, 0xfd, 0x01, + 0x1c, 0xe8, 0xa0, 0x00, 0x97, 0xe1, 0xa3, 0xe4, + 0xa2, 0xff, 0xf7, 0x7f, 0xfb, 0xee, 0xa0, 0xff, + 0xf7, 0x7c, 0xfb, 0x07, 0xe0, 0x00, 0xf0, 0xa0, + 0xfd, 0x01, 0x1c, 0xec, 0xa0, 0xdb, 0xa3, 0xde, + 0xa2, 0xff, 0xf7, 0x73, 0xfb, 0x02, 0xf0, 0x62, + 0xfd, 0xda, 0xe7, 0xf3, 0x48, 0xc0, 0x6a, 0x00, + 0x28, 0x03, 0xd0, 0xf2, 0x48, 0x50, 0x21, 0xff, + 0xf7, 0x28, 0xf8, 0xf0, 0x48, 0x01, 0x78, 0x03, + 0x96, 0x6d, 0x29, 0x57, 0xd0, 0x41, 0xdc, 0x66, + 0x29, 0x55, 0xd0, 0x33, 0xdc, 0x62, 0x29, 0x53, + 0xd0, 0x0c, 0xdc, 0x2e, 0x29, 0x49, 0xd0, 0x3a, + 0x29, 0x4f, 0xd0, 0x3f, 0x29, 0x4e, 0xd1, 0x03, + 0x98, 0x00, 0x78, 0x3f, 0x28, 0x4f, 0xd1, 0x00, + 0xf0, 0x8d, 0xfe, 0x7a, 0xe0, 0x63, 0x29, 0x4e, + 0xd0, 0x64, 0x29, 0x4d, 0xd0, 0x65, 0x29, 0x41, + 0xd1, 0x03, 0x98, 0x00, 0x78, 0x76, 0x28, 0x3d, + 0xd1, 0x03, 0x94, 0x20, 0x78, 0x68, 0x28, 0x68, + 0xd0, 0x68, 0xdc, 0x23, 0x28, 0x03, 0xd0, 0x62, + 0x28, 0x65, 0xd0, 0x64, 0x28, 0x64, 0xd1, 0x03, + 0x95, 0x03, 0xa8, 0xff, 0xf7, 0x2d, 0xf8, 0x02, + 0x90, 0x00, 0x28, 0x5e, 0xd0, 0x02, 0xa8, 0xff, + 0xf7, 0x2d, 0xf9, 0x01, 0x1c, 0xd4, 0xa0, 0xff, + 0xf7, 0x2c, 0xfb, 0x57, 0xe0, 0xc8, 0x1f, 0x60, + 0x38, 0x06, 0x28, 0x53, 0xd2, 0x01, 0xa3, 0x1b, + 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0xbd, 0xbc, 0xbb, + 0x75, 0x75, 0xba, 0xc8, 0x1f, 0x67, 0x38, 0x0d, + 0x28, 0x48, 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x6a, 0x6a, 0xdf, + 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0x6a, 0x6a, + 0x6a, 0x6a, 0x00, 0xed, 0x09, 0x00, 0xcf, 0x01, + 0xca, 0x49, 0x0a, 0x22, 0xe3, 0xf7, 0x67, 0xfc, + 0xa2, 0xe7, 0x21, 0xe2, 0x42, 0xe1, 0x0b, 0xe0, + 0x00, 0xe0, 0x2c, 0xe1, 0x03, 0x98, 0x02, 0xf0, + 0xce, 0xf8, 0x54, 0xe0, 0xff, 0xe7, 0x02, 0xf0, + 0x4e, 0xfe, 0x50, 0xe0, 0x2e, 0xe0, 0xc4, 0xe0, + 0x03, 0x98, 0x00, 0x78, 0x72, 0x28, 0x4a, 0xd1, + 0x03, 0x94, 0x03, 0xa8, 0xfe, 0xf7, 0xeb, 0xff, + 0x02, 0x90, 0x00, 0x28, 0x1e, 0xd0, 0x02, 0xa8, + 0xff, 0xf7, 0xeb, 0xf8, 0x07, 0x1c, 0x03, 0xa8, + 0xfe, 0xf7, 0xe1, 0xff, 0x00, 0x21, 0x00, 0x28, + 0x02, 0x90, 0x03, 0xd0, 0x02, 0xa8, 0xff, 0xf7, + 0xe0, 0xf8, 0x01, 0x1c, 0xac, 0x48, 0x01, 0x22, + 0xc0, 0x6a, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x22, + 0x38, 0x1c, 0x02, 0xf0, 0x04, 0xf8, 0xfe, 0xe0, + 0xdf, 0xe0, 0xda, 0xe0, 0xec, 0xe0, 0x0a, 0xe1, + 0x0f, 0xe1, 0xf5, 0xe1, 0xac, 0xa0, 0xff, 0xf7, + 0xcf, 0xfa, 0xf4, 0xe0, 0x03, 0x98, 0x00, 0x78, + 0x6c, 0x28, 0x4c, 0xd0, 0x10, 0xdc, 0x63, 0x28, + 0x0b, 0xd0, 0x06, 0xdc, 0x34, 0x28, 0x4a, 0xd0, + 0x62, 0x28, 0x14, 0xd1, 0x03, 0x94, 0x01, 0x27, + 0x62, 0xe0, 0x64, 0x28, 0x4f, 0xd0, 0x65, 0x28, + 0x0d, 0xd1, 0x00, 0xf0, 0x32, 0xfe, 0xde, 0xe0, + 0x73, 0x28, 0x1c, 0xd0, 0x74, 0x28, 0x3b, 0xd0, + 0x75, 0x28, 0x05, 0xd0, 0x77, 0x28, 0x02, 0xd1, + 0x03, 0x94, 0x02, 0x27, 0x50, 0xe0, 0x51, 0xe2, + 0x91, 0x49, 0x08, 0x6c, 0x00, 0x28, 0x03, 0xd0, + 0x01, 0x21, 0x01, 0xf0, 0x6e, 0xfa, 0xca, 0xe0, + 0xc8, 0x6b, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x21, + 0x01, 0xf0, 0xeb, 0xfa, 0xc3, 0xe0, 0x9b, 0xa0, + 0xff, 0xf7, 0x9a, 0xfa, 0xbf, 0xe0, 0x03, 0x94, + 0x03, 0xa8, 0xfe, 0xf7, 0x8c, 0xff, 0x02, 0x90, + 0x00, 0x28, 0x15, 0xd0, 0x02, 0xa8, 0xed, 0x09, + 0x00, 0xd0, 0x01, 0xff, 0xf7, 0x8c, 0xf8, 0x07, + 0x1c, 0x03, 0xa8, 0xfe, 0xf7, 0x82, 0xff, 0x02, + 0x90, 0x00, 0x28, 0x03, 0xd0, 0x02, 0xa8, 0xff, + 0xf7, 0x82, 0xf8, 0x01, 0xe0, 0xff, 0x20, 0x01, + 0x30, 0x01, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 0x31, + 0xfe, 0xa3, 0xe0, 0x17, 0xe0, 0x00, 0xf0, 0x0d, + 0xfe, 0x9f, 0xe0, 0x19, 0xe0, 0x03, 0x94, 0x03, + 0xa8, 0xfe, 0xf7, 0x6b, 0xff, 0x02, 0x90, 0x00, + 0x28, 0x04, 0xd0, 0x02, 0xa8, 0xff, 0xf7, 0x6b, + 0xf8, 0x01, 0xe0, 0x0a, 0xe0, 0x0a, 0x20, 0x00, + 0xf0, 0x48, 0xfe, 0x8e, 0xe0, 0x77, 0xe1, 0x6f, + 0xe1, 0x52, 0xe1, 0x36, 0xe1, 0x01, 0xf0, 0x29, + 0xff, 0x87, 0xe0, 0x03, 0x94, 0x04, 0x27, 0x01, + 0xe0, 0x03, 0x94, 0x10, 0x27, 0x03, 0xa8, 0xfe, + 0xf7, 0x50, 0xff, 0x02, 0x90, 0x00, 0x28, 0x0f, + 0xd0, 0x02, 0xa8, 0xff, 0xf7, 0x50, 0xf8, 0x64, + 0x49, 0x88, 0x61, 0x03, 0xa8, 0xfe, 0xf7, 0x45, + 0xff, 0x02, 0x90, 0x00, 0x28, 0x04, 0xd0, 0x02, + 0xa8, 0xff, 0xf7, 0x45, 0xf8, 0x5f, 0x49, 0xc8, + 0x61, 0x38, 0x1c, 0x03, 0xf0, 0xbe, 0xfc, 0x5c, + 0x49, 0x88, 0x69, 0xc0, 0x19, 0x88, 0x61, 0x64, + 0xe0, 0xaf, 0xe2, 0x3a, 0xe2, 0xc9, 0xe1, 0xb7, + 0xe1, 0xa3, 0xe1, 0x64, 0xe1, 0x7c, 0xe1, 0x03, + 0x98, 0x00, 0x78, 0x34, 0x28, 0x0e, 0xd0, 0x62, + 0x28, 0x06, 0xd0, 0x64, 0x28, 0x07, 0xd0, 0x77, + 0x28, 0x53, 0xd1, 0x03, 0x94, 0x02, 0x27, 0x07, + 0xe0, 0x03, 0x94, 0x01, 0x27, 0x04, 0xe0, 0x03, + 0x94, 0x04, 0x27, 0x01, 0xe0, 0x03, 0x94, 0x10, + 0x27, 0x03, 0xa8, 0xfe, 0xf7, 0x16, 0xff, 0x02, + 0x90, 0x00, 0x28, 0x17, 0xd0, 0x02, 0xa8, 0xff, + 0xf7, 0x16, 0xf8, 0x47, 0x49, 0xc8, 0x60, 0x03, + 0xa8, 0xfe, 0xf7, 0x0b, 0xff, 0x02, 0x90, 0x00, + 0x28, 0xed, 0x09, 0x00, 0xd1, 0x01, 0x07, 0xd0, + 0x02, 0xa8, 0xff, 0xf7, 0x0b, 0xf8, 0x42, 0x49, + 0xca, 0x68, 0x80, 0x18, 0x08, 0x61, 0x09, 0xe0, + 0x3f, 0x49, 0xc8, 0x68, 0x20, 0x30, 0x08, 0x61, + 0x04, 0xe0, 0x3d, 0x49, 0x08, 0x69, 0xc8, 0x60, + 0x20, 0x30, 0x08, 0x61, 0x38, 0x1c, 0x03, 0xf0, + 0x1c, 0xfb, 0x37, 0xe0, 0x6f, 0x28, 0x20, 0xd0, + 0x78, 0x28, 0x2d, 0xd1, 0x03, 0x95, 0x03, 0xa8, + 0xfe, 0xf7, 0xea, 0xfe, 0x02, 0x90, 0x00, 0x28, + 0x2c, 0xd0, 0x02, 0xa8, 0xfe, 0xf7, 0xea, 0xff, + 0x01, 0x1c, 0x49, 0xa0, 0xff, 0xf7, 0xe9, 0xf9, + 0x0b, 0xe1, 0x03, 0x95, 0x03, 0xa8, 0xfe, 0xf7, + 0xdb, 0xfe, 0x02, 0x90, 0x00, 0x28, 0x1d, 0xd0, + 0x02, 0xa8, 0xfe, 0xf7, 0xdb, 0xff, 0x01, 0x1c, + 0x45, 0xa0, 0xff, 0xf7, 0xda, 0xf9, 0xfc, 0xe0, + 0xee, 0xe1, 0x03, 0x95, 0x03, 0xa8, 0xfe, 0xf7, + 0xcb, 0xfe, 0x02, 0x90, 0x00, 0x28, 0x0d, 0xd0, + 0x02, 0xa8, 0xfe, 0xf7, 0xcb, 0xff, 0x01, 0x1c, + 0x41, 0xa0, 0xff, 0xf7, 0xca, 0xf9, 0xec, 0xe0, + 0x01, 0xf0, 0xe4, 0xfd, 0xe9, 0xe0, 0x03, 0x98, + 0x00, 0x78, 0x83, 0xe0, 0xd9, 0xe1, 0x00, 0x00, + 0xe1, 0xbd, 0x03, 0x20, 0x41, 0x70, 0x72, 0x20, + 0x32, 0x33, 0x20, 0x32, 0x30, 0x30, 0x33, 0x00, + 0x31, 0x36, 0x3a, 0x30, 0x35, 0x3a, 0x31, 0x37, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x20, 0x2d, 0x2d, + 0x2d, 0x20, 0x25, 0x73, 0x20, 0x28, 0x25, 0x73, + 0x20, 0x25, 0x73, 0x29, 0x20, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, + 0x25, 0x64, 0x20, 0x68, 0x69, 0x74, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x20, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x20, 0x25, 0x73, 0x20, 0x28, 0x25, + 0x73, 0x20, 0x25, 0x73, 0xed, 0x09, 0x00, 0xd2, + 0x01, 0x29, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x69, 0x03, + 0x20, 0xe0, 0xbd, 0x03, 0x20, 0x0a, 0x65, 0x76, + 0x61, 0x6c, 0x20, 0x28, 0x64, 0x65, 0x63, 0x69, + 0x6d, 0x61, 0x6c, 0x29, 0x3a, 0x20, 0x25, 0x75, + 0x00, 0x94, 0xbd, 0x03, 0x20, 0x75, 0x73, 0x65, + 0x3a, 0x20, 0x62, 0x72, 0x20, 0x3c, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x3e, 0x20, 0x3c, 0x30, + 0x7c, 0x41, 0x64, 0x64, 0x72, 0x3e, 0x20, 0x28, + 0x30, 0x3d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x29, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, + 0x48, 0x49, 0x53, 0x52, 0x2f, 0x54, 0x61, 0x73, + 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x65, 0x76, + 0x61, 0x6c, 0x20, 0x28, 0x68, 0x65, 0x78, 0x29, + 0x3a, 0x20, 0x25, 0x58, 0x00, 0x0a, 0x65, 0x76, + 0x61, 0x6c, 0x20, 0x28, 0x62, 0x69, 0x6e, 0x29, + 0x3a, 0x20, 0x25, 0x62, 0x00, 0x0a, 0x65, 0x76, + 0x61, 0x6c, 0x20, 0x28, 0x6f, 0x6b, 0x74, 0x61, + 0x6c, 0x29, 0x3a, 0x20, 0x25, 0x6f, 0x00, 0x00, + 0x00, 0x62, 0x28, 0x06, 0xd0, 0x64, 0x28, 0x07, + 0xd0, 0x77, 0x28, 0x5c, 0xd1, 0x03, 0x94, 0x02, + 0x21, 0x04, 0xe0, 0x03, 0x94, 0x01, 0x21, 0x01, + 0xe0, 0x03, 0x94, 0x04, 0x21, 0x03, 0x98, 0x03, + 0xf0, 0x45, 0xf9, 0xd2, 0xe0, 0x03, 0x98, 0x00, + 0x78, 0x6f, 0x28, 0x4c, 0xd1, 0xe1, 0xa0, 0xff, + 0xf7, 0x26, 0xf9, 0xfe, 0xf7, 0xd7, 0xfc, 0x03, + 0x98, 0x40, 0x78, 0x2b, 0x28, 0x04, 0xd1, 0x00, + 0xf0, 0x1b, 0xfa, 0xe1, 0xa0, 0xff, 0xf7, 0x1b, + 0xf9, 0x01, 0x99, 0x01, 0x20, 0x01, 0x29, 0x00, + 0xd0, 0x00, 0x20, 0x05, 0xb0, 0xf0, 0xbc, 0xed, + 0x09, 0x00, 0xd3, 0x01, 0x08, 0xbc, 0x18, 0x47, + 0x03, 0x98, 0x00, 0x78, 0x49, 0x28, 0x12, 0xd0, + 0x61, 0x28, 0x06, 0xd0, 0x69, 0x28, 0x2d, 0xd1, + 0x00, 0x21, 0x00, 0x20, 0x01, 0xf0, 0x53, 0xf9, + 0xaa, 0xe0, 0xda, 0x48, 0xc0, 0x6a, 0x00, 0x28, + 0x01, 0xd1, 0xfe, 0xf7, 0xa6, 0xfc, 0xd8, 0xa0, + 0xff, 0xf7, 0xfc, 0xf8, 0xa0, 0xe0, 0x01, 0x21, + 0x00, 0x20, 0x01, 0xf0, 0x44, 0xf9, 0x9b, 0xe0, + 0x03, 0x98, 0x00, 0x78, 0x64, 0x28, 0x15, 0xd1, + 0x03, 0xf0, 0xed, 0xfb, 0x94, 0xe0, 0x03, 0x98, + 0x00, 0x78, 0x69, 0x28, 0x0e, 0xd1, 0x01, 0xf0, + 0xd6, 0xfd, 0x8d, 0xe0, 0x03, 0x98, 0x00, 0x78, + 0x45, 0x28, 0x0c, 0xd0, 0x65, 0x28, 0x06, 0xd0, + 0x6c, 0x28, 0x03, 0xd1, 0xcd, 0x48, 0x03, 0xf0, + 0xca, 0xfc, 0x81, 0xe0, 0x61, 0xe1, 0x00, 0x20, + 0x01, 0xf0, 0x57, 0xfb, 0x7c, 0xe0, 0x01, 0x20, + 0x01, 0xf0, 0x53, 0xfb, 0x78, 0xe0, 0x03, 0x98, + 0x00, 0x27, 0x00, 0x78, 0x55, 0x28, 0x02, 0xd0, + 0x75, 0x28, 0x71, 0xd1, 0x00, 0xe0, 0x01, 0x27, + 0x03, 0x94, 0x03, 0xa8, 0xfe, 0xf7, 0xbd, 0xfd, + 0x02, 0x90, 0x00, 0x28, 0x03, 0xd0, 0x39, 0x1c, + 0x01, 0xf0, 0x75, 0xf9, 0xd5, 0xe0, 0x00, 0x20, + 0x39, 0x1c, 0x01, 0xf0, 0x70, 0xf9, 0xd0, 0xe0, + 0x03, 0x98, 0x00, 0x27, 0x00, 0x78, 0x41, 0x28, + 0x0a, 0xd0, 0x49, 0x28, 0x0c, 0xd0, 0x61, 0x28, + 0x02, 0xd0, 0x69, 0x28, 0x54, 0xd1, 0x08, 0xe0, + 0x00, 0x20, 0x01, 0xf0, 0x46, 0xfc, 0xc0, 0xe0, + 0x01, 0x20, 0x01, 0xf0, 0x42, 0xfc, 0xbc, 0xe0, + 0x01, 0x27, 0x03, 0x94, 0x03, 0xa8, 0xfe, 0xf7, + 0x98, 0xfd, 0x02, 0x90, 0x00, 0x28, 0x03, 0xd0, + 0x39, 0x1c, 0x01, 0xf0, 0x46, 0xfa, 0xb0, 0xe0, + 0x00, 0x20, 0x39, 0x1c, 0x01, 0xf0, 0x41, 0xfa, + 0xab, 0xe0, 0xed, 0x09, 0x00, 0xd4, 0x01, 0x03, + 0x98, 0x00, 0x78, 0x65, 0x28, 0x36, 0xd1, 0x03, + 0x94, 0x20, 0x78, 0x67, 0x28, 0x04, 0xd0, 0x73, + 0x28, 0x05, 0xd1, 0x00, 0xf0, 0x9c, 0xfa, 0x9e, + 0xe0, 0x02, 0xf0, 0x77, 0xfa, 0x9b, 0xe0, 0x04, + 0x98, 0x03, 0x90, 0x98, 0xe0, 0x03, 0x98, 0x00, + 0x78, 0x65, 0x28, 0x09, 0xd0, 0x74, 0x28, 0x21, + 0xd1, 0x03, 0x94, 0x03, 0xa8, 0xfe, 0xf7, 0x6f, + 0xfd, 0x02, 0x90, 0x02, 0xf0, 0x7c, 0xfb, 0x8a, + 0xe0, 0x01, 0xf0, 0xb1, 0xfb, 0x87, 0xe0, 0x03, + 0x98, 0x00, 0x78, 0x68, 0x28, 0x22, 0xd0, 0x12, + 0xdc, 0x41, 0x28, 0x3a, 0xd0, 0x61, 0x28, 0x0d, + 0xd1, 0x03, 0x94, 0x20, 0x78, 0x72, 0x28, 0x39, + 0xd1, 0x03, 0x95, 0x03, 0xa8, 0xfe, 0xf7, 0x57, + 0xfd, 0x02, 0x90, 0x00, 0x28, 0x73, 0xd0, 0x00, + 0xf0, 0x62, 0xff, 0x71, 0xe0, 0xdf, 0xe0, 0x69, + 0x28, 0x52, 0xd0, 0x72, 0x28, 0x6c, 0xd1, 0x03, + 0x94, 0x03, 0xa8, 0xfe, 0xf7, 0x48, 0xfd, 0x02, + 0x90, 0x00, 0x28, 0x14, 0xd0, 0x02, 0xa8, 0xfe, + 0xf7, 0x48, 0xfe, 0x12, 0xe0, 0x03, 0x94, 0x03, + 0xa8, 0xfe, 0xf7, 0x3d, 0xfd, 0x02, 0x90, 0x00, + 0x28, 0x59, 0xd0, 0x02, 0xa8, 0xfe, 0xf7, 0x3d, + 0xfe, 0x01, 0x22, 0x00, 0x28, 0x00, 0xd1, 0x00, + 0x22, 0x76, 0x48, 0x82, 0x63, 0xbf, 0xe0, 0x00, + 0x20, 0xc0, 0x43, 0x01, 0x1c, 0x01, 0x98, 0x03, + 0xf0, 0x40, 0xfb, 0xfe, 0xf7, 0xe4, 0xfb, 0x00, + 0x20, 0x18, 0xe7, 0x01, 0x21, 0x00, 0x20, 0x00, + 0xf0, 0xf4, 0xff, 0xb0, 0xe0, 0x52, 0x28, 0x09, + 0xd1, 0x03, 0x95, 0x03, 0xa8, 0xfe, 0xf7, 0x1b, + 0xfd, 0x02, 0x90, 0x00, 0x28, 0x37, 0xd0, 0x00, + 0xf0, 0x72, 0xff, 0xa4, 0xe0, 0x73, 0x28, 0x09, + 0xd1, 0x03, 0x95, 0x03, 0xa8, 0xfe, 0xf7, 0x0f, + 0xfd, 0x02, 0x90, 0x00, 0x28, 0xed, 0x09, 0x00, + 0xd5, 0x01, 0x2b, 0xd0, 0x00, 0xf0, 0xcc, 0xfe, + 0x98, 0xe0, 0x03, 0xa8, 0xfe, 0xf7, 0x06, 0xfd, + 0x02, 0x90, 0x00, 0x28, 0x02, 0xd0, 0x00, 0xf0, + 0x8f, 0xfd, 0x8f, 0xe0, 0x00, 0x21, 0x00, 0x20, + 0x00, 0xf0, 0xce, 0xff, 0x8a, 0xe0, 0x01, 0xf0, + 0x71, 0xfc, 0x87, 0xe0, 0x03, 0x98, 0x00, 0x78, + 0x6e, 0x28, 0x14, 0xd1, 0x56, 0x48, 0x03, 0x94, + 0x80, 0x6a, 0x01, 0x28, 0x01, 0xd3, 0x20, 0x28, + 0x02, 0xd9, 0x53, 0x48, 0x01, 0x22, 0x82, 0x62, + 0x03, 0xa8, 0xfe, 0xf7, 0xe7, 0xfc, 0x02, 0x90, + 0x00, 0x28, 0x36, 0xd0, 0x01, 0x78, 0x2b, 0x29, + 0x10, 0xd1, 0x01, 0xe0, 0x6e, 0xe0, 0x6d, 0xe0, + 0x01, 0x30, 0x02, 0x90, 0x02, 0xa8, 0xfe, 0xf7, + 0xdf, 0xfd, 0x49, 0x4f, 0x80, 0x00, 0x79, 0x6a, + 0x40, 0x18, 0x04, 0x21, 0x00, 0xf0, 0xee, 0xf8, + 0x78, 0x62, 0x17, 0xe0, 0x2d, 0x29, 0x0d, 0xd1, + 0x01, 0x30, 0x02, 0x90, 0x02, 0xa8, 0xfe, 0xf7, + 0xcf, 0xfd, 0x41, 0x4f, 0x80, 0x00, 0x79, 0x6a, + 0x08, 0x1a, 0x04, 0x21, 0x00, 0xf0, 0xde, 0xf8, + 0x78, 0x62, 0x07, 0xe0, 0x02, 0xa8, 0xfe, 0xf7, + 0xc3, 0xfd, 0x04, 0x21, 0x00, 0xf0, 0xd6, 0xf8, + 0x39, 0x4f, 0x78, 0x62, 0x03, 0xa8, 0xfe, 0xf7, + 0xb5, 0xfc, 0x02, 0x90, 0x00, 0x28, 0x04, 0xd0, + 0x02, 0xa8, 0xfe, 0xf7, 0xb5, 0xfd, 0x34, 0x4f, + 0xb8, 0x62, 0x33, 0x48, 0x00, 0x27, 0x81, 0x6a, + 0x00, 0x29, 0x37, 0xd9, 0x30, 0x49, 0x48, 0x6a, + 0x35, 0x49, 0x09, 0x68, 0x88, 0x42, 0x0b, 0xd2, + 0x2d, 0x49, 0x89, 0x6b, 0x01, 0x29, 0x03, 0xd1, + 0x01, 0x88, 0x03, 0xf0, 0x11, 0xfc, 0x05, 0xe0, + 0x01, 0x68, 0x04, 0xf0, 0x97, 0xf8, 0x01, 0xe0, + 0x04, 0xf0, 0x74, 0xf8, 0x26, 0x49, 0x88, 0x6b, + 0x01, 0x28, 0x03, 0xd1, 0x48, 0x6a, 0x02, 0x30, + 0xed, 0x09, 0x00, 0xd6, 0x01, 0x48, 0x62, 0x02, + 0xe0, 0x48, 0x6a, 0x04, 0x30, 0x48, 0x62, 0x88, + 0x6a, 0x01, 0x37, 0x87, 0x42, 0xdc, 0xd3, 0x13, + 0xe0, 0x03, 0x98, 0x01, 0x78, 0x65, 0x29, 0x0f, + 0xd1, 0x40, 0x78, 0x72, 0x28, 0x0c, 0xd1, 0x68, + 0x46, 0x00, 0xf0, 0x4a, 0xf8, 0x01, 0x1c, 0x20, + 0xa0, 0xfe, 0xf7, 0x7f, 0xff, 0x00, 0x99, 0x00, + 0x29, 0x02, 0xd0, 0x1d, 0xa0, 0xfe, 0xf7, 0x79, + 0xff, 0x1c, 0x4f, 0x38, 0x1c, 0x00, 0xf0, 0xac, + 0xf9, 0x39, 0x1c, 0x09, 0x22, 0x1a, 0x48, 0xfe, + 0xf7, 0x53, 0xff, 0x10, 0x48, 0xc0, 0x6a, 0x00, + 0x28, 0x01, 0xd0, 0xff, 0xf7, 0xfa, 0xfb, 0x17, + 0xa0, 0xfe, 0xf7, 0x18, 0xfc, 0x00, 0x20, 0x4e, + 0xe6, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, + 0x28, 0x72, 0x65, 0x29, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x65, 0x64, 0x0a, 0x00, 0x20, 0x57, 0x61, + 0x74, 0x63, 0x68, 0x64, 0x6f, 0x67, 0x20, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, + 0x21, 0x21, 0x20, 0x00, 0x00, 0x28, 0x69, 0x03, + 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, + 0x73, 0x74, 0x6f, 0x70, 0x65, 0x64, 0x0a, 0x00, + 0x00, 0x94, 0xb8, 0x03, 0x20, 0x24, 0x00, 0x00, + 0x20, 0x0a, 0x25, 0x73, 0x00, 0xe0, 0xbd, 0x03, + 0x20, 0x94, 0xbd, 0x03, 0x20, 0x0a, 0x40, 0x20, + 0x00, 0x80, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0x68, + 0x46, 0x0a, 0xf0, 0x44, 0xff, 0x05, 0x48, 0x6b, + 0x46, 0x28, 0x21, 0x05, 0xa2, 0x38, 0x60, 0xf7, + 0xf7, 0xb8, 0xfc, 0x02, 0xb0, 0x80, 0xbc, 0x08, + 0xbc, 0x05, 0x48, 0x18, 0x47, 0x88, 0xbe, 0x03, + 0x20, 0x42, 0x44, 0x5f, 0x41, 0x44, 0x44, 0x52, + 0x3a, 0x20, 0x25, 0x3a, 0x2d, 0x36, 0x42, 0x00, + 0x00, 0xc4, 0x5d, 0x03, 0x20, 0x00, 0xb5, 0x01, + 0x20, 0x80, 0x02, 0xed, 0x09, 0x00, 0xd7, 0x01, + 0x18, 0xf0, 0x6d, 0xfa, 0x08, 0xbc, 0x18, 0x47, + 0x01, 0x48, 0x80, 0x78, 0x70, 0x47, 0x60, 0x00, + 0x00, 0xd0, 0x00, 0xb5, 0x01, 0x20, 0x80, 0x02, + 0x18, 0xf0, 0x85, 0xfa, 0x08, 0xbc, 0x18, 0x47, + 0x01, 0x48, 0x00, 0x68, 0x70, 0x47, 0x70, 0x65, + 0x03, 0x20, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, + 0x08, 0x49, 0xca, 0x1d, 0xcc, 0x31, 0x41, 0x60, + 0xbd, 0x32, 0x02, 0x60, 0x08, 0x30, 0x00, 0x22, + 0x00, 0x21, 0x00, 0x23, 0x0e, 0xc0, 0x0e, 0xc0, + 0x0e, 0xc0, 0x0e, 0xc0, 0x0c, 0xc0, 0x70, 0x47, + 0x00, 0x00, 0x88, 0xe5, 0x03, 0x20, 0x90, 0xb5, + 0x0c, 0x1c, 0x01, 0x1c, 0x07, 0x1c, 0x20, 0x1c, + 0xe2, 0xf7, 0x57, 0xff, 0x00, 0x29, 0x0b, 0xd0, + 0x60, 0x1e, 0x3c, 0x1c, 0x84, 0x43, 0x39, 0x1c, + 0x22, 0x1c, 0x16, 0xa0, 0xfe, 0xf7, 0xdc, 0xfe, + 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x01, 0x23, 0xdb, 0x03, 0x9f, 0x42, 0x01, 0xd2, + 0x38, 0x1c, 0xf6, 0xe7, 0x01, 0x23, 0x5b, 0x07, + 0xf8, 0x1a, 0x9b, 0x0a, 0x98, 0x42, 0x01, 0xd2, + 0x38, 0x1c, 0xee, 0xe7, 0x03, 0x23, 0x1b, 0x07, + 0xf8, 0x18, 0x01, 0x23, 0x9b, 0x03, 0x98, 0x42, + 0x01, 0xd2, 0x38, 0x1c, 0xe5, 0xe7, 0x01, 0x23, + 0x5b, 0x07, 0xf8, 0x18, 0x59, 0x23, 0x1b, 0x02, + 0x98, 0x42, 0x01, 0xd2, 0x38, 0x1c, 0xdc, 0xe7, + 0x39, 0x1c, 0x0b, 0xa0, 0xfe, 0xf7, 0xb4, 0xfe, + 0x00, 0x20, 0xd6, 0xe7, 0x00, 0x00, 0x0a, 0x75, + 0x6e, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x41, 0x64, + 0x64, 0x72, 0x20, 0x25, 0x58, 0x20, 0x73, 0x65, + 0x74, 0x20, 0x74, 0x6f, 0x20, 0x25, 0x58, 0x00, + 0x00, 0x00, 0x0a, 0x75, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x20, 0x72, 0x65, 0x61, 0xed, 0x09, + 0x00, 0xd8, 0x01, 0x64, 0x20, 0x41, 0x64, 0x64, + 0x72, 0x20, 0x25, 0x58, 0x20, 0x73, 0x65, 0x74, + 0x20, 0x74, 0x6f, 0x20, 0x30, 0x00, 0x00, 0x90, + 0xb5, 0x0c, 0x1c, 0x01, 0x1c, 0x07, 0x1c, 0x20, + 0x1c, 0xe2, 0xf7, 0xf9, 0xfe, 0x00, 0x29, 0x0b, + 0xd0, 0x60, 0x1e, 0x3c, 0x1c, 0x84, 0x43, 0x39, + 0x1c, 0x22, 0x1c, 0x16, 0xa0, 0xfe, 0xf7, 0x7e, + 0xfe, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x01, 0x23, 0xdb, 0x03, 0x9f, 0x42, 0x01, + 0xd2, 0x38, 0x1c, 0xf6, 0xe7, 0x01, 0x23, 0x5b, + 0x07, 0xf8, 0x1a, 0x9b, 0x0a, 0x98, 0x42, 0x01, + 0xd2, 0x38, 0x1c, 0xee, 0xe7, 0x03, 0x23, 0x1b, + 0x07, 0xf8, 0x18, 0x01, 0x23, 0x9b, 0x03, 0x98, + 0x42, 0x01, 0xd2, 0x38, 0x1c, 0xe5, 0xe7, 0x01, + 0x23, 0x5b, 0x07, 0xf8, 0x18, 0x59, 0x23, 0x1b, + 0x02, 0x98, 0x42, 0x01, 0xd2, 0x38, 0x1c, 0xdc, + 0xe7, 0x39, 0x1c, 0x0b, 0xa0, 0xfe, 0xf7, 0x56, + 0xfe, 0x00, 0x20, 0xd6, 0xe7, 0x00, 0x00, 0x0a, + 0x75, 0x6e, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, + 0x41, 0x64, 0x64, 0x72, 0x20, 0x25, 0x58, 0x20, + 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x25, + 0x58, 0x00, 0x00, 0x0a, 0x75, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x20, 0x41, 0x64, 0x64, 0x72, 0x20, 0x25, + 0x58, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, + 0x20, 0x30, 0x00, 0x01, 0x49, 0x01, 0x20, 0x48, + 0x70, 0x70, 0x47, 0x60, 0x00, 0x00, 0xd0, 0x00, + 0xb5, 0x07, 0xf0, 0xc7, 0xfc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x07, 0xf0, 0xcc, 0xfc, 0x00, + 0x28, 0x02, 0xd1, 0x01, 0x20, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x01, 0x49, 0x08, + 0x70, 0xed, 0x09, 0x00, 0xd9, 0x01, 0x70, 0x47, + 0x60, 0x00, 0x00, 0xd0, 0x01, 0x48, 0x00, 0x78, + 0x70, 0x47, 0x00, 0x00, 0x60, 0x00, 0x00, 0xd0, + 0x80, 0xb5, 0x08, 0x48, 0x18, 0xf0, 0x88, 0xf9, + 0x07, 0x4f, 0x78, 0x60, 0x01, 0x20, 0x80, 0x02, + 0x18, 0xf0, 0x5e, 0xf9, 0x00, 0x20, 0x18, 0xf0, + 0xff, 0xf9, 0x38, 0x60, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, + 0x70, 0x69, 0x03, 0x20, 0x80, 0xb5, 0x05, 0x4f, + 0x38, 0x68, 0x18, 0xf0, 0xf1, 0xf9, 0x78, 0x68, + 0x18, 0xf0, 0x4a, 0xf9, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x70, 0x69, 0x03, 0x20, + 0x00, 0xb5, 0x03, 0xa0, 0xfe, 0xf7, 0xe9, 0xfd, + 0x18, 0xf0, 0x2a, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x0a, 0x2d, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x73, + 0x65, 0x74, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x20, 0x2d, 0x2d, 0x2d, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x70, 0x47, 0x42, 0x6c, 0x75, 0x65, + 0x74, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x20, 0x4d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xb5, 0x81, 0xb0, 0x01, 0x98, 0x01, 0x78, + 0x75, 0x29, 0x02, 0xd0, 0x02, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0x30, 0x01, 0x90, 0x01, 0x78, + 0x65, 0x29, 0x4d, 0xd0, 0x13, 0xdc, 0x3f, 0x29, + 0x1e, 0xd0, 0x64, 0x29, 0x59, 0xd1, 0x01, 0x30, + 0x01, 0x90, 0x01, 0x78, 0x72, 0x29, 0x54, 0xd1, + 0x01, 0x30, 0x01, 0x90, 0x00, 0x78, 0x6f, 0x28, + 0x3a, 0xd0, 0x21, 0xdc, 0x61, 0x28, 0x27, 0xd0, + 0x63, 0x28, 0x31, 0xd0, 0x20, 0xe0, 0x66, 0x29, + 0x17, 0xd0, 0x73, 0x29, 0x45, 0xd1, 0xe4, 0xf7, + 0x43, 0xfe, 0xfc, 0xf7, 0x0b, 0xfa, 0x0b, 0xf0, + 0x91, 0xfb, 0x0a, 0xf0, 0xed, 0x09, 0x00, 0xda, + 0x01, 0x73, 0xfe, 0x3c, 0xe0, 0x1e, 0xa0, 0xfe, + 0xf7, 0x96, 0xfd, 0x31, 0xa0, 0xfe, 0xf7, 0x93, + 0xfd, 0x3a, 0xa0, 0xfe, 0xf7, 0x90, 0xfd, 0x47, + 0xa0, 0xfe, 0xf7, 0x8d, 0xfd, 0x2f, 0xe0, 0xf7, + 0xf7, 0xa1, 0xfb, 0x2c, 0xe0, 0x73, 0x28, 0x09, + 0xd0, 0x75, 0x28, 0x0b, 0xd0, 0x4d, 0xa0, 0xfe, + 0xf7, 0x82, 0xfd, 0x24, 0xe0, 0x01, 0x20, 0xf7, + 0xf7, 0xbd, 0xfb, 0x20, 0xe0, 0x00, 0x20, 0xf7, + 0xf7, 0xb9, 0xfb, 0x1c, 0xe0, 0x02, 0x20, 0xf7, + 0xf7, 0xb5, 0xfb, 0x18, 0xe0, 0x03, 0x20, 0xf7, + 0xf7, 0xb1, 0xfb, 0x14, 0xe0, 0x04, 0x20, 0xf7, + 0xf7, 0xad, 0xfb, 0x10, 0xe0, 0x01, 0x30, 0x01, + 0x90, 0x01, 0xa8, 0xfe, 0xf7, 0x5f, 0xfa, 0x00, + 0x90, 0x00, 0x28, 0x05, 0xd0, 0x68, 0x46, 0xfe, + 0xf7, 0x5f, 0xfb, 0xe6, 0xf7, 0xe3, 0xf9, 0x02, + 0xe0, 0x01, 0x20, 0xe6, 0xf7, 0xdf, 0xf9, 0x97, + 0xe7, 0x0a, 0x64, 0x72, 0x3c, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x3e, 0x20, 0x20, 0x3c, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x3e, 0x3d, 0x20, 0x5b, 0x61, + 0x5d, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, + 0x6e, 0x65, 0x20, 0x5b, 0x73, 0x5d, 0x79, 0x6e, + 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x65, 0x20, 0x5b, + 0x75, 0x5d, 0x73, 0x62, 0x20, 0x5b, 0x63, 0x5d, + 0x61, 0x70, 0x69, 0x20, 0x5b, 0x6f, 0x5d, 0x66, + 0x66, 0x20, 0x44, 0x65, 0x62, 0x75, 0x67, 0x72, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x0a, 0x00, + 0x00, 0x66, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x6c, 0x75, 0x73, 0x68, 0x20, 0x64, 0x65, 0x62, + 0x75, 0x67, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x0a, 0x00, 0x65, 0x20, 0xed, + 0x09, 0x00, 0xdb, 0x01, 0x65, 0x63, 0x68, 0x6f, + 0x66, 0x6c, 0x61, 0x67, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x63, 0x68, 0x6f, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x64, 0x20, 0x64, 0x6d, 0x2f, 0x68, 0x20, + 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x0a, + 0x00, 0x00, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x73, 0x68, 0x6f, 0x77, 0x20, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x0a, 0x00, + 0x00, 0x00, 0x0a, 0x75, 0x73, 0x65, 0x3a, 0x20, + 0x5b, 0x75, 0x5d, 0x64, 0x72, 0x3c, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x3e, 0x20, 0x20, 0x3c, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x3e, 0x3d, 0x20, 0x5b, + 0x61, 0x5d, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, + 0x6f, 0x6e, 0x65, 0x20, 0x5b, 0x73, 0x5d, 0x79, + 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x65, 0x20, + 0x5b, 0x75, 0x5d, 0x73, 0x62, 0x20, 0x5b, 0x63, + 0x5d, 0x61, 0x70, 0x69, 0x20, 0x5b, 0x6f, 0x5d, + 0x66, 0x66, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x47, + 0x70, 0x47, 0x02, 0x48, 0x00, 0x21, 0x01, 0x60, + 0x41, 0x60, 0x70, 0x47, 0x00, 0x00, 0xb0, 0xbe, + 0x03, 0x20, 0x01, 0x1c, 0x07, 0x48, 0x43, 0x68, + 0x5a, 0x1c, 0x42, 0x60, 0x1a, 0x18, 0x11, 0x72, + 0x41, 0x68, 0x01, 0x23, 0x9b, 0x02, 0x99, 0x42, + 0x01, 0xd3, 0x00, 0x21, 0x41, 0x60, 0x70, 0x47, + 0x00, 0x00, 0xb0, 0xbe, 0x03, 0x20, 0x06, 0x49, + 0x08, 0x68, 0x42, 0x1c, 0x40, 0x18, 0x01, 0x23, + 0x9b, 0x02, 0x0a, 0x60, 0x00, 0x7a, 0x9a, 0x42, + 0x01, 0xd3, 0xed, 0x09, 0x00, 0xdc, 0x01, 0x00, + 0x22, 0x0a, 0x60, 0x70, 0x47, 0x00, 0x00, 0xb0, + 0xbe, 0x03, 0x20, 0x03, 0x49, 0x01, 0x20, 0x4a, + 0x68, 0x09, 0x68, 0x8a, 0x42, 0x00, 0xd0, 0x00, + 0x20, 0x70, 0x47, 0xb0, 0xbe, 0x03, 0x20, 0x01, + 0x49, 0x00, 0x20, 0x08, 0x60, 0x70, 0x47, 0x7c, + 0x69, 0x03, 0x20, 0x80, 0xb5, 0x07, 0x4f, 0x38, + 0x68, 0x00, 0x28, 0x01, 0xd0, 0x08, 0xf0, 0x93, + 0xf9, 0x00, 0x20, 0x38, 0x60, 0x04, 0xa0, 0xfe, + 0xf7, 0x7b, 0xfc, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x7c, 0x69, 0x03, 0x20, 0x0a, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x3a, 0x20, 0x63, + 0x6c, 0x65, 0x61, 0x72, 0x65, 0x64, 0x00, 0x00, + 0xb5, 0x07, 0x49, 0x08, 0x68, 0x00, 0x28, 0x04, + 0xd1, 0x06, 0xa0, 0xfe, 0xf7, 0x65, 0xfc, 0x08, + 0xbc, 0x18, 0x47, 0x8a, 0x68, 0x49, 0x68, 0x92, + 0x00, 0xe2, 0xf7, 0xb9, 0xfd, 0xf7, 0xe7, 0x7c, + 0x69, 0x03, 0x20, 0x0a, 0x6e, 0x6f, 0x20, 0x72, + 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x2c, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0xb5, 0x0d, 0x4e, 0x07, 0x1c, 0x30, 0x68, 0x0c, + 0x1c, 0x00, 0x28, 0x01, 0xd0, 0x08, 0xf0, 0x57, + 0xf9, 0xa0, 0x00, 0x05, 0x1c, 0x08, 0xf0, 0x28, + 0xf9, 0x81, 0xc6, 0x08, 0x3e, 0x39, 0x1c, 0x2a, + 0x1c, 0xb4, 0x60, 0xe2, 0xf7, 0x94, 0xfd, 0xea, + 0x19, 0x39, 0x1c, 0x03, 0xa0, 0xfe, 0xf7, 0x34, + 0xfc, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x7c, + 0x69, 0x03, 0x20, 0x0a, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x3a, 0x20, 0x73, 0x65, 0x74, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x25, 0x58, 0x20, 0x74, + 0x6f, 0x20, 0x25, 0x58, 0x00, 0x00, 0x00, 0xf0, + 0xb5, 0x13, 0x4e, 0x07, 0x1c, 0xed, 0x09, 0x00, + 0xdd, 0x01, 0x30, 0x68, 0x00, 0x28, 0x05, 0xd1, + 0x11, 0xa0, 0xfe, 0xf7, 0x18, 0xfc, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x25, 0x00, 0x24, + 0x0c, 0xe0, 0x32, 0x68, 0xa8, 0x00, 0x71, 0x68, + 0x13, 0x58, 0x0a, 0x58, 0x93, 0x42, 0x04, 0xd0, + 0x41, 0x18, 0x0f, 0xa0, 0x01, 0x34, 0xfe, 0xf7, + 0x06, 0xfc, 0x01, 0x35, 0xb0, 0x68, 0x85, 0x42, + 0x01, 0xd2, 0xbc, 0x42, 0xed, 0xd3, 0x00, 0x2c, + 0xe5, 0xd1, 0x10, 0xa0, 0xfe, 0xf7, 0xfb, 0xfb, + 0xe1, 0xe7, 0x00, 0x00, 0x7c, 0x69, 0x03, 0x20, + 0x0a, 0x0d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x3a, + 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, + 0x0a, 0x25, 0x30, 0x38, 0x78, 0x3a, 0x20, 0x25, + 0x30, 0x38, 0x58, 0x20, 0x21, 0x3d, 0x20, 0x25, + 0x30, 0x38, 0x58, 0x20, 0x28, 0x6f, 0x6c, 0x64, + 0x29, 0x20, 0x00, 0x00, 0x0a, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x3a, 0x20, 0x6e, 0x6f, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0x00, 0x00, 0x00, + 0x0d, 0x28, 0x24, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, + 0x5b, 0x00, 0x9f, 0x44, 0x18, 0x14, 0x1c, 0x0c, + 0x16, 0x12, 0x1a, 0x08, 0x10, 0x0e, 0x06, 0x0a, + 0x1e, 0x00, 0x0e, 0xa0, 0x70, 0x47, 0x13, 0xa0, + 0x70, 0x47, 0x18, 0xa0, 0x70, 0x47, 0x1d, 0xa0, + 0x70, 0x47, 0x22, 0xa0, 0x70, 0x47, 0x27, 0xa0, + 0x70, 0x47, 0x2c, 0xa0, 0x70, 0x47, 0x31, 0xa0, + 0x70, 0x47, 0x36, 0xa0, 0x70, 0x47, 0x3b, 0xa0, + 0x70, 0x47, 0x40, 0xa0, 0x70, 0x47, 0x45, 0xa0, + 0x70, 0x47, 0x4a, 0xa0, 0x70, 0x47, 0x4f, 0xa0, + 0x70, 0x47, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x44, + 0x52, 0x49, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x55, + 0x53, 0x50, 0x45, 0x4e, 0x44, 0x20, 0x20, 0x20, + 0xed, 0x09, 0x00, 0xde, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x45, 0x56, 0x45, 0x4e, + 0x54, 0x5f, 0x53, 0x55, 0x53, 0x50, 0x45, 0x4e, + 0x44, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x46, 0x49, 0x4e, 0x49, + 0x53, 0x48, 0x45, 0x44, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x4d, 0x41, 0x49, 0x4c, + 0x42, 0x4f, 0x58, 0x5f, 0x53, 0x55, 0x53, 0x50, + 0x45, 0x4e, 0x44, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, + 0x52, 0x59, 0x5f, 0x53, 0x55, 0x53, 0x50, 0x45, + 0x4e, 0x44, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x50, 0x41, 0x52, 0x54, + 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x55, + 0x53, 0x50, 0x45, 0x4e, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x50, 0x49, 0x50, 0x45, + 0x5f, 0x53, 0x55, 0x53, 0x50, 0x45, 0x4e, 0x44, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x50, 0x55, 0x52, 0x45, + 0x5f, 0x53, 0x55, 0x53, 0x50, 0x45, 0x4e, 0x44, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x51, 0x55, 0x45, 0x55, + 0x45, 0x5f, 0x53, 0x55, 0x53, 0x50, 0x45, 0x4e, + 0x44, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x52, 0x45, 0x41, 0x44, + 0x59, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x53, 0x45, 0x4d, 0x41, + 0x50, 0x48, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x55, + 0x53, 0x50, 0x45, 0x4e, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x53, 0x4c, 0x45, 0x45, + 0x50, 0x5f, 0x53, 0xed, 0x09, 0x00, 0xdf, 0x01, + 0x55, 0x53, 0x50, 0x45, 0x4e, 0x44, 0x20, 0x20, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, + 0x54, 0x45, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x75, + 0x6e, 0x6b, 0x6f, 0x6e, 0x6f, 0x77, 0x6e, 0x20, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb5, + 0x04, 0x68, 0x07, 0x1c, 0xff, 0xf7, 0xf4, 0xfb, + 0x00, 0x28, 0x02, 0xd0, 0x23, 0xa0, 0xfe, 0xf7, + 0xf7, 0xfa, 0x10, 0x20, 0x20, 0x40, 0x10, 0x28, + 0x06, 0xd1, 0x25, 0xa0, 0xfe, 0xf7, 0xf0, 0xfa, + 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x27, 0x4d, 0x01, 0x2c, 0x25, 0xd0, 0x26, 0xa0, + 0xfe, 0xf7, 0xe6, 0xfa, 0x2e, 0x48, 0x00, 0x24, + 0x28, 0x60, 0x04, 0x35, 0x00, 0x20, 0x11, 0xc5, + 0x11, 0xc5, 0x78, 0x68, 0x14, 0x3d, 0x68, 0x61, + 0xb8, 0x68, 0xa8, 0x61, 0xf8, 0x68, 0xe8, 0x61, + 0x38, 0x69, 0x28, 0x62, 0x78, 0x69, 0x68, 0x62, + 0xb8, 0x69, 0xa8, 0x62, 0xf8, 0x69, 0xe8, 0x62, + 0x38, 0x6a, 0x28, 0x63, 0x78, 0x6a, 0x68, 0x63, + 0xf8, 0x1d, 0x21, 0x30, 0xa8, 0x63, 0xb8, 0x6a, + 0xe8, 0x63, 0xb8, 0x6a, 0x28, 0x64, 0x28, 0x1c, + 0xd3, 0xe7, 0x1d, 0xa0, 0xfe, 0xf7, 0xc0, 0xfa, + 0x08, 0x23, 0x28, 0x1c, 0x3c, 0x1d, 0x06, 0xcc, + 0x06, 0xc0, 0x01, 0x3b, 0xfb, 0xd1, 0x04, 0xcc, + 0x04, 0xc0, 0xaf, 0x63, 0x28, 0x1c, 0xc4, 0xe7, + 0x00, 0x00, 0x20, 0x28, 0x68, 0x61, 0x72, 0x64, + 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x29, 0x20, + 0x00, 0x00, 0x20, 0x28, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0xed, 0x09, + 0x00, 0xe0, 0x01, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x29, 0x20, 0x00, 0xb8, 0xc2, 0x03, 0x20, 0x20, + 0x28, 0x74, 0x61, 0x73, 0x6b, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2c, 0x20, 0x6e, + 0x6f, 0x3a, 0x20, 0x61, 0x31, 0x2d, 0x61, 0x34, + 0x2c, 0x20, 0x63, 0x70, 0x73, 0x72, 0x29, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x20, + 0x28, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, + 0x70, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0x00, 0xf0, 0x5b, 0xf8, 0x00, 0x28, 0x0a, + 0xd0, 0x04, 0x21, 0xff, 0xf7, 0xe4, 0xfb, 0x04, + 0x49, 0x08, 0x60, 0x80, 0x6b, 0x04, 0x21, 0xff, + 0xf7, 0xde, 0xfb, 0x02, 0x49, 0x08, 0x60, 0x08, + 0xbc, 0x18, 0x47, 0x24, 0x69, 0x03, 0x20, 0x20, + 0x69, 0x03, 0x20, 0x00, 0xb5, 0x02, 0x1c, 0x40, + 0x6a, 0x92, 0x6a, 0x01, 0x1c, 0x03, 0x78, 0x01, + 0x30, 0x55, 0x2b, 0x01, 0xd1, 0x82, 0x42, 0xf9, + 0xd8, 0x13, 0x1a, 0x02, 0xa0, 0xfe, 0xf7, 0x56, + 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x0a, + 0x53, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x25, 0x78, + 0x2d, 0x25, 0x78, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x3a, 0x20, 0x25, 0x78, 0x20, 0x00, 0x00, 0x80, + 0xb5, 0x07, 0x1c, 0x0b, 0x48, 0x00, 0x68, 0x00, + 0x28, 0x05, 0xd0, 0x41, 0x6a, 0x39, 0x60, 0x80, + 0x6a, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x07, + 0x48, 0x00, 0x68, 0x00, 0x28, 0x03, 0xd0, 0x41, + 0x6a, 0x39, 0x60, 0x80, 0x6a, 0xf4, 0xe7, 0x04, + 0xa0, 0xfe, 0xf7, 0x30, 0xfa, 0x00, 0x20, 0x38, + 0x60, 0xee, 0xe7, 0x68, 0x69, 0x03, 0x20, 0x64, + 0x69, 0x03, 0x20, 0x0a, 0x6e, 0x6f, 0x20, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x48, + 0x49, 0xed, 0x09, 0x00, 0xe1, 0x01, 0x53, 0x52, + 0x2f, 0x54, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, + 0xf0, 0xb5, 0x38, 0x4e, 0x07, 0x1c, 0x00, 0x28, + 0x37, 0x4d, 0x34, 0x68, 0x17, 0xd1, 0x37, 0x49, + 0x28, 0x60, 0x08, 0x60, 0xf4, 0xf7, 0xee, 0xff, + 0x28, 0x60, 0x00, 0x28, 0x05, 0xd0, 0xc0, 0x6a, + 0xff, 0xf7, 0x0a, 0xff, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf4, 0xf7, 0xf1, 0xff, 0x2f, 0x49, + 0x00, 0x28, 0x08, 0x60, 0x03, 0xd0, 0xc0, 0x6a, + 0xff, 0xf7, 0xfe, 0xfe, 0xf2, 0xe7, 0x00, 0x2c, + 0x22, 0xd0, 0x08, 0x22, 0x38, 0x1c, 0xe1, 0x1d, + 0x09, 0x31, 0x07, 0xf0, 0x57, 0xff, 0x00, 0x28, + 0x14, 0xd1, 0x39, 0x1c, 0x26, 0xa0, 0xfe, 0xf7, + 0xf0, 0xf9, 0x24, 0x48, 0x00, 0x27, 0x2c, 0x60, + 0x07, 0x60, 0xf4, 0xf7, 0xc7, 0xff, 0xa0, 0x42, + 0x04, 0xd1, 0x29, 0xa0, 0xfe, 0xf7, 0xe5, 0xf9, + 0x38, 0x1c, 0xd7, 0xe7, 0xe0, 0x6a, 0xff, 0xf7, + 0xdf, 0xfe, 0xd3, 0xe7, 0x64, 0x68, 0x30, 0x68, + 0x84, 0x42, 0x01, 0xd0, 0x00, 0x2c, 0xdc, 0xd1, + 0x2d, 0x4e, 0x34, 0x68, 0x00, 0x2c, 0x22, 0xd0, + 0x08, 0x22, 0x38, 0x1c, 0xe1, 0x1d, 0x09, 0x31, + 0x07, 0xf0, 0x30, 0xff, 0x00, 0x28, 0x14, 0xd1, + 0x39, 0x1c, 0x28, 0xa0, 0xfe, 0xf7, 0xc9, 0xf9, + 0x00, 0x27, 0x10, 0x48, 0x2f, 0x60, 0x04, 0x60, + 0xf4, 0xf7, 0xae, 0xff, 0xa0, 0x42, 0x04, 0xd1, + 0x2a, 0xa0, 0xfe, 0xf7, 0xbe, 0xf9, 0x38, 0x1c, + 0xb0, 0xe7, 0xe0, 0x6a, 0xff, 0xf7, 0xb8, 0xfe, + 0xac, 0xe7, 0x64, 0x68, 0x30, 0x68, 0x84, 0x42, + 0x01, 0xd0, 0x00, 0x2c, 0xdc, 0xd1, 0x39, 0x1c, + 0x2e, 0xa0, 0xfe, 0xf7, 0xae, 0xf9, 0x00, 0x20, + 0xa0, 0xe7, 0x00, 0x00, 0xc8, 0x65, 0x03, 0x20, + 0x68, 0x69, 0x03, 0x20, 0x64, 0x69, 0x03, 0x20, + 0x0a, 0x43, 0x75, 0x72, 0xed, 0x09, 0x00, 0xe2, + 0x01, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x20, + 0x27, 0x25, 0x73, 0x27, 0x00, 0x20, 0x74, 0x61, + 0x73, 0x6b, 0x20, 0x69, 0x73, 0x20, 0x72, 0x75, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, + 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x62, 0x6c, + 0x65, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x03, + 0x20, 0x0a, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x20, + 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x68, + 0x69, 0x73, 0x72, 0x20, 0x27, 0x25, 0x73, 0x27, + 0x00, 0x20, 0x68, 0x69, 0x73, 0x72, 0x20, 0x69, + 0x73, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x20, 0x61, 0x76, 0x61, + 0x69, 0x6c, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x2f, 0x68, + 0x69, 0x73, 0x72, 0x20, 0x25, 0x73, 0x20, 0x75, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, + 0x00, 0xf0, 0xb5, 0x07, 0x1c, 0x07, 0xf0, 0xea, + 0xfd, 0x08, 0x28, 0x03, 0xd2, 0x38, 0x1c, 0x07, + 0xf0, 0xe5, 0xfd, 0x00, 0xe0, 0x08, 0x20, 0x12, + 0x4d, 0x06, 0x1c, 0x2c, 0x68, 0x00, 0x2c, 0x1a, + 0xd0, 0xe1, 0x1d, 0x09, 0x31, 0x38, 0x1c, 0x32, + 0x1c, 0x07, 0xf0, 0x92, 0xfe, 0x00, 0x28, 0x0c, + 0xd1, 0x20, 0x1c, 0xf4, 0xf7, 0x45, 0xfe, 0x09, + 0xf0, 0x21, 0xf9, 0x39, 0x1c, 0x02, 0x1c, 0x09, + 0xa0, 0xfe, 0xf7, 0x25, 0xf9, 0xf0, 0xbc, 0xed, + 0x09, 0x00, 0xe3, 0x01, 0x08, 0xbc, 0x18, 0x47, + 0x64, 0x68, 0x28, 0x68, 0x84, 0x42, 0x01, 0xd0, + 0x00, 0x2c, 0xe4, 0xd1, 0x39, 0x1c, 0x08, 0xa0, + 0xfe, 0xf7, 0x18, 0xf9, 0xf1, 0xe7, 0xc8, 0x65, + 0x03, 0x20, 0x0a, 0x53, 0x75, 0x73, 0x70, 0x65, + 0x6e, 0x64, 0x5f, 0x54, 0x61, 0x73, 0x6b, 0x28, + 0x25, 0x73, 0x29, 0x3a, 0x20, 0x25, 0x73, 0x20, + 0x00, 0x00, 0x0a, 0x53, 0x75, 0x73, 0x70, 0x65, + 0x6e, 0x64, 0x5f, 0x54, 0x61, 0x73, 0x6b, 0x28, + 0x25, 0x73, 0x29, 0x3a, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xb5, 0x07, 0x1c, 0x07, 0xf0, + 0x9c, 0xfd, 0x08, 0x28, 0x03, 0xd2, 0x38, 0x1c, + 0x07, 0xf0, 0x97, 0xfd, 0x00, 0xe0, 0x08, 0x20, + 0x12, 0x4d, 0x06, 0x1c, 0x2c, 0x68, 0x00, 0x2c, + 0x1a, 0xd0, 0xe1, 0x1d, 0x09, 0x31, 0x38, 0x1c, + 0x32, 0x1c, 0x07, 0xf0, 0x44, 0xfe, 0x00, 0x28, + 0x0c, 0xd1, 0x20, 0x1c, 0xf4, 0xf7, 0x2b, 0xfd, + 0x09, 0xf0, 0xd3, 0xf8, 0x39, 0x1c, 0x02, 0x1c, + 0x09, 0xa0, 0xfe, 0xf7, 0xd7, 0xf8, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x64, 0x68, 0x28, 0x68, + 0x84, 0x42, 0x01, 0xd0, 0x00, 0x2c, 0xe4, 0xd1, + 0x39, 0x1c, 0x08, 0xa0, 0xfe, 0xf7, 0xca, 0xf8, + 0xf1, 0xe7, 0xc8, 0x65, 0x03, 0x20, 0x0a, 0x52, + 0x65, 0x73, 0x75, 0x6d, 0x65, 0x5f, 0x54, 0x61, + 0x73, 0x6b, 0x28, 0x25, 0x73, 0x29, 0x3a, 0x20, + 0x25, 0x73, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x52, + 0x65, 0x73, 0x75, 0x6d, 0x65, 0x5f, 0x54, 0x61, + 0x73, 0x6b, 0x28, 0x25, 0x73, 0x29, 0x3a, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, + 0x64, 0x00, 0xf0, 0xb5, 0x07, 0x1c, 0x07, 0xf0, + 0x50, 0xfd, 0x08, 0x28, 0x03, 0xd2, 0x38, 0x1c, + 0x07, 0xf0, 0xed, 0x09, 0x00, 0xe4, 0x01, 0x4b, + 0xfd, 0x00, 0xe0, 0x08, 0x20, 0x1d, 0x4d, 0x06, + 0x1c, 0x2c, 0x68, 0x00, 0x2c, 0x30, 0xd0, 0xe1, + 0x1d, 0x09, 0x31, 0x38, 0x1c, 0x32, 0x1c, 0x07, + 0xf0, 0xf8, 0xfd, 0x00, 0x28, 0x22, 0xd1, 0x20, + 0x1c, 0xf4, 0xf7, 0xab, 0xfd, 0x09, 0xf0, 0x87, + 0xf8, 0x39, 0x1c, 0x02, 0x1c, 0x14, 0x48, 0xfe, + 0xf7, 0x8b, 0xf8, 0x20, 0x1c, 0xf4, 0xf7, 0xf9, + 0xfb, 0x09, 0xf0, 0x7d, 0xf8, 0x39, 0x1c, 0x02, + 0x1c, 0x10, 0xa0, 0xfe, 0xf7, 0x81, 0xf8, 0x00, + 0x22, 0x00, 0x21, 0x20, 0x1c, 0xf4, 0xf7, 0xc9, + 0xfb, 0x09, 0xf0, 0x71, 0xf8, 0x39, 0x1c, 0x02, + 0x1c, 0x11, 0xa0, 0xfe, 0xf7, 0x75, 0xf8, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x64, 0x68, 0x28, + 0x68, 0x84, 0x42, 0x01, 0xd0, 0x00, 0x2c, 0xce, + 0xd1, 0x39, 0x1c, 0x12, 0xa0, 0xfe, 0xf7, 0x68, + 0xf8, 0xf1, 0xe7, 0xc8, 0x65, 0x03, 0x20, 0x40, + 0xdf, 0x01, 0x20, 0x0a, 0x54, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x54, 0x61, + 0x73, 0x6b, 0x28, 0x25, 0x73, 0x29, 0x3a, 0x20, + 0x25, 0x73, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x52, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x54, 0x61, + 0x73, 0x6b, 0x28, 0x25, 0x73, 0x2c, 0x20, 0x30, + 0x2c, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3a, + 0x20, 0x25, 0x73, 0x20, 0x00, 0x00, 0x00, 0x0a, + 0x52, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x54, 0x61, + 0x73, 0x6b, 0x28, 0x25, 0x73, 0x29, 0x3a, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, + 0x64, 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, 0x0c, + 0x1c, 0x23, 0x4e, 0x07, 0x1c, 0x23, 0xa0, 0x35, + 0x68, 0xfe, 0xf7, 0x2e, 0xf8, 0x00, 0x2d, 0x39, + 0xd0, 0x00, 0x2f, 0x01, 0xd0, 0xaf, 0x42, 0x2e, + 0xd1, 0x08, 0x22, 0xe9, 0x1d, 0xed, 0x09, 0x00, + 0xe5, 0x01, 0x09, 0x31, 0x01, 0xa8, 0x07, 0xf0, + 0x9b, 0xfd, 0x00, 0x20, 0x03, 0xab, 0x18, 0x70, + 0x28, 0x7e, 0xff, 0xf7, 0x49, 0xfc, 0xaa, 0x7e, + 0x03, 0x1c, 0x1a, 0xa0, 0x00, 0x92, 0xea, 0x6d, + 0x01, 0xa9, 0xfe, 0xf7, 0x14, 0xf8, 0x00, 0x2c, + 0x11, 0xd0, 0x69, 0x6a, 0xa8, 0x6a, 0x0a, 0x1c, + 0x00, 0xe0, 0x04, 0x32, 0x16, 0x68, 0x1c, 0x4b, + 0x9e, 0x42, 0x01, 0xd1, 0x90, 0x42, 0xf8, 0xd8, + 0x82, 0x1a, 0x00, 0x92, 0x02, 0x1c, 0x19, 0xa0, + 0x2b, 0x6b, 0xfe, 0xf7, 0x00, 0xf8, 0xf4, 0xf7, + 0xdb, 0xfd, 0xa8, 0x42, 0x02, 0xd1, 0x21, 0xa0, + 0xfd, 0xf7, 0xf9, 0xff, 0x05, 0x4e, 0x6d, 0x68, + 0x30, 0x68, 0x85, 0x42, 0x01, 0xd0, 0x00, 0x2d, + 0xc5, 0xd1, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xc8, 0x65, 0x03, 0x20, + 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x6c, 0x69, 0x73, + 0x74, 0x3a, 0x00, 0x00, 0x0a, 0x5b, 0x25, 0x38, + 0x73, 0x5d, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x20, 0x25, 0x30, 0x38, 0x78, 0x20, 0x25, 0x73, + 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x25, 0x33, 0x64, 0x00, 0x00, 0x00, + 0x55, 0x55, 0x55, 0x55, 0x20, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x20, 0x25, 0x23, 0x30, 0x38, 0x70, + 0x20, 0x2d, 0x20, 0x25, 0x23, 0x30, 0x38, 0x70, + 0x20, 0x28, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x25, + 0x75, 0x29, 0x20, 0x25, 0x75, 0x20, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x3c, 0x72, 0x75, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x3e, 0x00, 0x00, + 0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, 0x22, 0x4e, + 0x07, 0x1c, 0x22, 0xa0, 0x35, 0x68, 0xfd, 0xf7, + 0xaa, 0xff, 0x00, 0x2d, 0x38, 0xd0, 0x00, 0x2f, + 0xed, 0x09, 0x00, 0xe6, 0x01, 0x01, 0xd0, 0xaf, + 0x42, 0x2d, 0xd1, 0x08, 0x22, 0xe9, 0x1d, 0x09, + 0x31, 0x01, 0xa8, 0x07, 0xf0, 0x17, 0xfd, 0x00, + 0x20, 0x03, 0xab, 0x18, 0x70, 0xaa, 0x7e, 0x1b, + 0xa0, 0x01, 0xa9, 0x00, 0x92, 0x6a, 0x6c, 0x2b, + 0x6c, 0xfd, 0xf7, 0x93, 0xff, 0x00, 0x2c, 0x12, + 0xd0, 0x69, 0x6a, 0xa8, 0x6a, 0x0a, 0x1c, 0x00, + 0xe0, 0x04, 0x32, 0x16, 0x68, 0x1e, 0x4b, 0x9e, + 0x42, 0x01, 0xd1, 0x90, 0x42, 0xf8, 0xd8, 0x82, + 0x1a, 0x00, 0x92, 0x02, 0x1c, 0x00, 0xa0, 0xa0, + 0x38, 0x2b, 0x6b, 0xfd, 0xf7, 0x7e, 0xff, 0xf4, + 0xf7, 0x67, 0xfd, 0xa8, 0x42, 0x03, 0xd1, 0x00, + 0xa0, 0x80, 0x38, 0xfd, 0xf7, 0x76, 0xff, 0x05, + 0x4e, 0x6d, 0x68, 0x30, 0x68, 0x85, 0x42, 0x01, + 0xd0, 0x00, 0x2d, 0xc6, 0xd1, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xdc, 0x66, 0x03, + 0x20, 0x0a, 0x48, 0x49, 0x53, 0x52, 0x6c, 0x69, + 0x73, 0x74, 0x3a, 0x00, 0x00, 0x0a, 0x5b, 0x25, + 0x38, 0x73, 0x5d, 0x20, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x20, 0x25, 0x30, 0x38, 0x78, 0x20, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x43, 0x6e, 0x74, 0x20, + 0x25, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x25, 0x64, 0x00, 0x00, + 0x00, 0x55, 0x55, 0x55, 0x55, 0xf3, 0xb5, 0x89, + 0xb0, 0x32, 0x4d, 0x07, 0x1c, 0x00, 0x28, 0x2c, + 0x68, 0x02, 0xd1, 0x31, 0xa0, 0xfd, 0xf7, 0x41, + 0xff, 0x00, 0x2c, 0x56, 0xd0, 0x08, 0x22, 0xe1, + 0x1d, 0x09, 0x31, 0x06, 0xa8, 0x07, 0xf0, 0xb2, + 0xfc, 0x00, 0x20, 0x08, 0xab, 0x18, 0x70, 0x00, + 0x2f, 0x05, 0xd0, 0x06, 0xa8, 0x39, 0x1c, 0x17, + 0xf0, 0x83, 0xfa, 0x00, 0x28, 0x3e, 0xd1, 0xa0, + 0x6a, 0xa1, 0x6b, 0x62, 0x6b, 0x03, 0x91, 0x02, + 0x90, 0x04, 0x92, 0xed, 0x09, 0x00, 0xe7, 0x01, + 0xe1, 0x69, 0x22, 0x6a, 0x00, 0x91, 0x01, 0x92, + 0x60, 0x7e, 0x00, 0x28, 0x01, 0xd0, 0x22, 0xa3, + 0x00, 0xe0, 0x23, 0xa3, 0x20, 0x7e, 0x00, 0x28, + 0x01, 0xd0, 0x24, 0xa2, 0x00, 0xe0, 0x27, 0xa2, + 0x06, 0xa9, 0x2b, 0xa0, 0xfd, 0xf7, 0x14, 0xff, + 0x0a, 0x99, 0x00, 0x29, 0x11, 0xd0, 0x3c, 0x34, + 0x07, 0xcc, 0x48, 0x3c, 0x04, 0x91, 0x03, 0x90, + 0x05, 0x92, 0x60, 0x6a, 0xe1, 0x6a, 0x22, 0x6b, + 0x01, 0x91, 0x00, 0x90, 0x02, 0x92, 0x21, 0x1c, + 0x22, 0x1c, 0xe3, 0x68, 0x32, 0xa0, 0xfd, 0xf7, + 0xff, 0xfe, 0x65, 0x6c, 0xe6, 0x6b, 0x06, 0xe0, + 0x28, 0x69, 0xc1, 0x1d, 0x09, 0x31, 0x4f, 0xa0, + 0xfd, 0xf7, 0xf6, 0xfe, 0x6d, 0x68, 0x00, 0x2d, + 0x03, 0xd0, 0x30, 0x1c, 0x01, 0x3e, 0x00, 0x28, + 0xf2, 0xd1, 0x05, 0x4d, 0x64, 0x68, 0x28, 0x68, + 0x84, 0x42, 0x01, 0xd0, 0x00, 0x2c, 0xa8, 0xd1, + 0x0b, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x4c, 0x67, 0x03, 0x20, 0x0a, 0x51, + 0x75, 0x65, 0x75, 0x65, 0x6c, 0x69, 0x73, 0x74, + 0x3a, 0x00, 0x4e, 0x55, 0x5f, 0x46, 0x49, 0x46, + 0x4f, 0x00, 0x4e, 0x55, 0x5f, 0x50, 0x52, 0x49, + 0x4f, 0x52, 0x49, 0x54, 0x59, 0x00, 0x4e, 0x55, + 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x53, + 0x49, 0x5a, 0x45, 0x00, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, + 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x5b, 0x25, 0x38, 0x73, 0x5d, + 0x20, 0x25, 0x31, 0x36, 0x73, 0x20, 0x25, 0x31, + 0x31, 0x73, 0x20, 0x53, 0x69, 0x7a, 0x65, 0x3d, + 0x25, 0x34, 0x64, 0x20, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x3d, 0x25, 0x34, 0x75, + 0x20, 0x46, 0x72, 0x65, 0x65, 0x3d, 0xed, 0x09, + 0x00, 0xe8, 0x01, 0x25, 0x34, 0x75, 0x20, 0x28, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x25, 0x78, + 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x25, 0x78, + 0x29, 0x00, 0x00, 0x0a, 0x71, 0x75, 0x65, 0x75, + 0x65, 0x3d, 0x25, 0x78, 0x20, 0x71, 0x75, 0x5f, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x3d, + 0x25, 0x78, 0x20, 0x71, 0x75, 0x5f, 0x69, 0x64, + 0x3d, 0x25, 0x78, 0x20, 0x71, 0x75, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x3d, 0x25, 0x75, 0x20, 0x71, + 0x75, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3d, + 0x25, 0x78, 0x20, 0x71, 0x75, 0x5f, 0x65, 0x6e, + 0x64, 0x3d, 0x25, 0x78, 0x20, 0x71, 0x75, 0x5f, + 0x74, 0x61, 0x73, 0x6b, 0x73, 0x5f, 0x77, 0x61, + 0x69, 0x74, 0x69, 0x6e, 0x67, 0x3d, 0x25, 0x78, + 0x20, 0x71, 0x75, 0x5f, 0x75, 0x72, 0x67, 0x65, + 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x3d, + 0x25, 0x78, 0x20, 0x71, 0x75, 0x5f, 0x73, 0x75, + 0x73, 0x70, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x3d, 0x25, 0x78, + 0x00, 0x00, 0x00, 0x20, 0x28, 0x25, 0x38, 0x73, + 0x29, 0x00, 0x00, 0xf3, 0xb5, 0x89, 0xb0, 0x30, + 0x4d, 0x07, 0x1c, 0x00, 0x28, 0x2c, 0x68, 0x02, + 0xd1, 0x2f, 0xa0, 0xfd, 0xf7, 0x4b, 0xfe, 0x00, + 0x2c, 0x53, 0xd0, 0x08, 0x22, 0xe1, 0x1d, 0x09, + 0x31, 0x06, 0xa8, 0x07, 0xf0, 0xbc, 0xfb, 0x00, + 0x20, 0x08, 0xab, 0x18, 0x70, 0x00, 0x2f, 0x05, + 0xd0, 0x06, 0xa8, 0x39, 0x1c, 0x17, 0xf0, 0x8d, + 0xf9, 0x00, 0x28, 0x3b, 0xd1, 0xe0, 0x69, 0x21, + 0x6a, 0xa2, 0x6a, 0x01, 0x91, 0x00, 0x90, 0x02, + 0x92, 0x60, 0x7e, 0x00, 0x28, 0x01, 0xd0, 0x22, + 0xa3, 0x00, 0xe0, 0x23, 0x4b, 0x20, 0x7e, 0x00, + 0x28, 0xed, 0x09, 0x00, 0xe9, 0x01, 0x01, 0xd0, + 0x22, 0x4a, 0x00, 0xe0, 0x22, 0x4a, 0x06, 0xa9, + 0x22, 0xa0, 0xfd, 0xf7, 0x22, 0xfe, 0x0a, 0x99, + 0x00, 0x29, 0x11, 0xd0, 0x3c, 0x34, 0x07, 0xcc, + 0x48, 0x3c, 0x04, 0x91, 0x03, 0x90, 0x05, 0x92, + 0x60, 0x6a, 0xe1, 0x6a, 0x22, 0x6b, 0x01, 0x91, + 0x00, 0x90, 0x02, 0x92, 0x21, 0x1c, 0x22, 0x1c, + 0xe3, 0x68, 0x25, 0xa0, 0xfd, 0xf7, 0x0d, 0xfe, + 0x65, 0x6c, 0xe6, 0x6b, 0x07, 0xe0, 0x28, 0x69, + 0xc1, 0x1d, 0x09, 0x31, 0x00, 0xa0, 0xa8, 0x38, + 0xfd, 0xf7, 0x03, 0xfe, 0x6d, 0x68, 0x00, 0x2d, + 0x03, 0xd0, 0x30, 0x1c, 0x01, 0x3e, 0x00, 0x28, + 0xf1, 0xd1, 0x05, 0x4d, 0x64, 0x68, 0x28, 0x68, + 0x84, 0x42, 0x01, 0xd0, 0x00, 0x2c, 0xab, 0xd1, + 0x0b, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x5c, 0x67, 0x03, 0x20, 0x0a, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x73, 0x74, 0x3a, 0x00, 0x00, + 0x4e, 0x55, 0x5f, 0x46, 0x49, 0x46, 0x4f, 0x00, + 0xbc, 0xe3, 0x01, 0x20, 0xc8, 0xe3, 0x01, 0x20, + 0xd8, 0xe3, 0x01, 0x20, 0x0a, 0x5b, 0x25, 0x38, + 0x73, 0x5d, 0x20, 0x25, 0x2d, 0x31, 0x36, 0x73, + 0x20, 0x25, 0x31, 0x31, 0x73, 0x20, 0x53, 0x69, + 0x7a, 0x65, 0x3d, 0x25, 0x34, 0x64, 0x20, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x3d, + 0x25, 0x34, 0x75, 0x20, 0x46, 0x72, 0x65, 0x65, + 0x3d, 0x25, 0x34, 0x75, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x70, 0x69, 0x70, 0x65, 0x3d, 0x25, 0x78, + 0x20, 0x70, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x3d, 0x25, 0x78, 0x20, 0x70, + 0x69, 0x5f, 0x69, 0x64, 0x3d, 0x25, 0x78, 0x20, + 0x70, 0x69, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3d, + 0x25, 0x75, 0x20, 0x70, 0xed, 0x09, 0x00, 0xea, + 0x01, 0x69, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x3d, 0x25, 0x78, 0x20, 0x70, 0x69, 0x5f, 0x65, + 0x6e, 0x64, 0x3d, 0x25, 0x78, 0x20, 0x70, 0x69, + 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x5f, 0x77, + 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x3d, 0x25, + 0x78, 0x20, 0x70, 0x69, 0x5f, 0x75, 0x72, 0x67, + 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, + 0x3d, 0x25, 0x78, 0x20, 0x70, 0x69, 0x5f, 0x73, + 0x75, 0x73, 0x70, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x3d, 0x25, + 0x78, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb5, 0x86, + 0xb0, 0x2d, 0x4d, 0x07, 0x1c, 0x2d, 0xa0, 0x2c, + 0x68, 0xfd, 0xf7, 0x79, 0xfd, 0x00, 0x2c, 0x4e, + 0xd0, 0x1f, 0x26, 0xf6, 0x43, 0x08, 0x22, 0xe1, + 0x1d, 0x11, 0x31, 0x03, 0xa8, 0x07, 0xf0, 0xe8, + 0xfa, 0x00, 0x20, 0x05, 0xab, 0x18, 0x70, 0xe0, + 0x1d, 0x29, 0x30, 0x00, 0x7a, 0xe2, 0x6a, 0x00, + 0x28, 0x01, 0xd0, 0x27, 0xa1, 0x00, 0xe0, 0x28, + 0x49, 0xa0, 0x6a, 0x01, 0x91, 0x00, 0x90, 0x02, + 0x92, 0x22, 0x6a, 0x63, 0x6a, 0x25, 0xa0, 0x03, + 0xa9, 0xfd, 0xf7, 0x59, 0xfd, 0x00, 0x2f, 0x27, + 0xd0, 0x2f, 0xa0, 0xfd, 0xf7, 0x54, 0xfd, 0x65, + 0x6b, 0x00, 0x2d, 0x21, 0xd0, 0x28, 0x68, 0x40, + 0x1b, 0x10, 0x38, 0x03, 0x1c, 0x00, 0x28, 0x00, + 0xda, 0x33, 0x1a, 0x29, 0x7a, 0x00, 0x29, 0x01, + 0xd0, 0x2b, 0xa2, 0x04, 0xe0, 0x00, 0x28, 0x01, + 0xda, 0x2b, 0xa2, 0x00, 0xe0, 0x2c, 0xa2, 0x29, + 0x1c, 0x2d, 0xa0, 0xfd, 0xf7, 0x3c, 0xfd, 0xe9, + 0x68, 0xa1, 0x42, 0x03, 0xd0, 0x22, 0x1c, 0x30, + 0xa0, 0xfd, 0xf7, 0x35, 0xfd, 0x2d, 0x68, 0x60, + 0x6b, 0xa8, 0x42, 0x01, 0xd0, 0x00, 0x2d, 0xdd, + 0xd1, 0x05, 0x4d, 0x64, 0x68, 0x28, 0x68, 0xed, + 0x09, 0x00, 0xeb, 0x01, 0x84, 0x42, 0x01, 0xd0, + 0x00, 0x2c, 0xb2, 0xd1, 0x06, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x9c, 0x67, + 0x03, 0x20, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x20, 0x50, 0x6f, 0x6f, 0x6c, 0x6c, 0x69, + 0x73, 0x74, 0x3a, 0x00, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x46, 0x49, 0x46, 0x4f, 0x00, 0xbc, 0xe3, + 0x01, 0x20, 0x0a, 0x5b, 0x25, 0x73, 0x5d, 0x20, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x25, 0x30, + 0x38, 0x78, 0x20, 0x53, 0x69, 0x7a, 0x65, 0x3d, + 0x25, 0x30, 0x38, 0x78, 0x20, 0x4d, 0x69, 0x6e, + 0x3d, 0x25, 0x34, 0x75, 0x20, 0x25, 0x31, 0x31, + 0x73, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x3d, + 0x25, 0x34, 0x75, 0x00, 0x00, 0x00, 0x0a, 0x09, + 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x6c, + 0x69, 0x73, 0x74, 0x3a, 0x00, 0x00, 0x66, 0x72, + 0x65, 0x65, 0x00, 0x00, 0x00, 0x00, 0x73, 0x69, + 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x75, 0x73, + 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x09, + 0x5b, 0x25, 0x23, 0x30, 0x38, 0x58, 0x5d, 0x20, + 0x25, 0x73, 0x20, 0x25, 0x64, 0x20, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x00, 0x00, 0x00, 0x0a, 0x09, + 0x49, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, + 0x50, 0x6f, 0x6f, 0x6c, 0x20, 0x5b, 0x25, 0x23, + 0x30, 0x38, 0x58, 0x5d, 0x20, 0x73, 0x68, 0x6f, + 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x5b, + 0x25, 0x23, 0x30, 0x38, 0x58, 0x5d, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, 0x1c, 0x4c, + 0x1d, 0xa0, 0x27, 0x68, 0xfd, 0xf7, 0xba, 0xfc, + 0x00, 0x2f, 0x2d, 0xd0, 0x00, 0x26, 0x08, 0x22, + 0xf9, 0x1d, 0x09, 0x31, 0x01, 0xa8, 0x07, 0xf0, + 0x2a, 0xfa, 0x03, 0xab, 0x1e, 0x70, 0x3a, 0x6a, + 0x00, 0x92, 0xed, 0x09, 0x00, 0xec, 0x01, 0x38, + 0x7f, 0x00, 0x28, 0x02, 0xd0, 0x00, 0xa3, 0xdc, + 0x3b, 0x00, 0xe0, 0x15, 0x4b, 0xba, 0x69, 0x01, + 0xa9, 0x15, 0xa0, 0xfd, 0xf7, 0xa1, 0xfc, 0x7c, + 0x6a, 0x3d, 0x6a, 0x06, 0xe0, 0x20, 0x69, 0xc1, + 0x1d, 0x09, 0x31, 0x18, 0xa0, 0xfd, 0xf7, 0x98, + 0xfc, 0x64, 0x68, 0x00, 0x2c, 0x03, 0xd0, 0x28, + 0x1c, 0x01, 0x3d, 0x00, 0x28, 0xf2, 0xd1, 0x05, + 0x4c, 0x7f, 0x68, 0x20, 0x68, 0x87, 0x42, 0x01, + 0xd0, 0x00, 0x2f, 0xd2, 0xd1, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x6c, + 0x67, 0x03, 0x20, 0x0a, 0x53, 0x65, 0x6d, 0x61, + 0x70, 0x68, 0x6f, 0x72, 0x65, 0x6c, 0x69, 0x73, + 0x74, 0x3a, 0x00, 0xbc, 0xe3, 0x01, 0x20, 0x0a, + 0x5b, 0x25, 0x38, 0x73, 0x5d, 0x20, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x3d, 0x25, 0x33, 0x75, 0x20, + 0x25, 0x31, 0x31, 0x73, 0x20, 0x54, 0x61, 0x73, + 0x6b, 0x73, 0x3d, 0x25, 0x33, 0x75, 0x00, 0x20, + 0x28, 0x25, 0x38, 0x73, 0x29, 0x00, 0x00, 0xf0, + 0xb5, 0x88, 0xb0, 0x1f, 0x4d, 0x07, 0x1c, 0x1f, + 0xa0, 0x2c, 0x68, 0xfd, 0xf7, 0x5d, 0xfc, 0x00, + 0x2c, 0x32, 0xd0, 0x00, 0x26, 0x08, 0x22, 0xe1, + 0x1d, 0x09, 0x31, 0x05, 0xa8, 0x07, 0xf0, 0xcd, + 0xf9, 0x07, 0xab, 0x1e, 0x70, 0x60, 0x6b, 0x61, + 0x6a, 0xa2, 0x6a, 0x02, 0x90, 0xe0, 0x1d, 0x29, + 0x30, 0x03, 0x91, 0x04, 0x92, 0x00, 0x78, 0x00, + 0x28, 0x01, 0xd0, 0x18, 0xa2, 0x00, 0xe0, 0x19, + 0x4a, 0x21, 0x6a, 0x01, 0x92, 0x00, 0x91, 0xa2, + 0x69, 0xe3, 0x69, 0x05, 0xa9, 0x17, 0xa0, 0xfd, + 0xf7, 0x3b, 0xfc, 0x00, 0x2f, 0x0a, 0xd0, 0xe0, + 0x6a, 0x00, 0x21, 0x00, 0x28, 0x03, 0xd0, 0x00, + 0x68, 0x01, 0x31, 0x00, 0x28, 0xfb, 0xd1, 0x23, + 0xa0, 0xfd, 0xf7, 0x2e, 0xfc, 0xed, 0x09, 0x00, + 0xed, 0x01, 0x64, 0x68, 0x28, 0x68, 0x84, 0x42, + 0x01, 0xd0, 0x00, 0x2c, 0xcd, 0xd1, 0x08, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x8c, 0x67, 0x03, 0x20, 0x0a, 0x50, 0x61, 0x72, + 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, + 0x6f, 0x6f, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x3a, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x46, + 0x49, 0x46, 0x4f, 0x00, 0xbc, 0xe3, 0x01, 0x20, + 0x0a, 0x5b, 0x25, 0x38, 0x73, 0x5d, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x3d, 0x25, 0x30, 0x38, + 0x78, 0x20, 0x53, 0x69, 0x7a, 0x65, 0x3d, 0x25, + 0x34, 0x64, 0x20, 0x50, 0x61, 0x72, 0x74, 0x2d, + 0x53, 0x69, 0x7a, 0x65, 0x3d, 0x25, 0x34, 0x64, + 0x20, 0x25, 0x31, 0x31, 0x73, 0x20, 0x54, 0x61, + 0x73, 0x6b, 0x73, 0x3d, 0x25, 0x32, 0x75, 0x20, + 0x46, 0x72, 0x65, 0x65, 0x3d, 0x25, 0x33, 0x75, + 0x20, 0x55, 0x73, 0x65, 0x64, 0x3d, 0x25, 0x33, + 0x75, 0x00, 0x00, 0x00, 0x20, 0x52, 0x65, 0x61, + 0x6c, 0x3d, 0x25, 0x33, 0x75, 0x00, 0x00, 0x00, + 0xf0, 0xb5, 0x83, 0xb0, 0x18, 0x4c, 0x19, 0xa0, + 0x27, 0x68, 0xfd, 0xf7, 0xdc, 0xfb, 0x00, 0x2f, + 0x25, 0xd0, 0x00, 0x26, 0x68, 0x46, 0x08, 0x22, + 0xf9, 0x1d, 0x09, 0x31, 0x07, 0xf0, 0x4c, 0xf9, + 0x02, 0xab, 0x1e, 0x70, 0xba, 0x69, 0xfb, 0x69, + 0x69, 0x46, 0x14, 0xa0, 0xfd, 0xf7, 0xcb, 0xfb, + 0x3c, 0x6a, 0xfd, 0x69, 0x06, 0xe0, 0xa0, 0x69, + 0xc1, 0x1d, 0x09, 0x31, 0x17, 0xa0, 0xfd, 0xf7, + 0xc2, 0xfb, 0x64, 0x68, 0x00, 0x2c, 0x03, 0xd0, + 0x28, 0x1c, 0x01, 0x3d, 0x00, 0x28, 0xf2, 0xd1, + 0x05, 0x4c, 0x7f, 0x68, 0x20, 0x68, 0x87, 0x42, + 0x01, 0xd0, 0x00, 0x2f, 0xda, 0xd1, 0x03, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0xed, 0x09, 0x00, 0xee, 0x01, 0x7c, 0x67, 0x03, + 0x20, 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x5b, 0x25, 0x38, 0x73, 0x5d, 0x20, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x25, + 0x30, 0x33, 0x32, 0x62, 0x20, 0x54, 0x61, 0x73, + 0x6b, 0x73, 0x3a, 0x25, 0x75, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x28, 0x25, 0x38, 0x73, 0x29, 0x00, + 0x00, 0xb0, 0xb5, 0x85, 0xb0, 0x14, 0x4c, 0x15, + 0xa0, 0x27, 0x68, 0xfd, 0xf7, 0x8a, 0xfb, 0x00, + 0x2f, 0x1d, 0xd0, 0x00, 0x25, 0x08, 0x22, 0xf9, + 0x1d, 0x09, 0x31, 0x02, 0xa8, 0x07, 0xf0, 0xfa, + 0xf8, 0x04, 0xab, 0x1d, 0x70, 0x38, 0x6a, 0x00, + 0x28, 0x01, 0xd0, 0x10, 0xa2, 0x00, 0xe0, 0x12, + 0xa2, 0xf9, 0x6a, 0x01, 0x92, 0x00, 0x91, 0xba, + 0x69, 0xbb, 0x6a, 0x02, 0xa9, 0x11, 0xa0, 0xfd, + 0xf7, 0x70, 0xfb, 0x7f, 0x68, 0x20, 0x68, 0x87, + 0x42, 0x01, 0xd0, 0x00, 0x2f, 0xe2, 0xd1, 0x05, + 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x88, 0x65, 0x03, 0x20, 0x0a, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x3a, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, + 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x44, 0x49, 0x53, 0x41, + 0x42, 0x4c, 0x45, 0x00, 0x00, 0x0a, 0x5b, 0x25, + 0x38, 0x73, 0x5d, 0x20, 0x46, 0x75, 0x6e, 0x63, + 0x3d, 0x25, 0x30, 0x38, 0x78, 0x20, 0x49, 0x6e, + 0x69, 0x74, 0x3d, 0x25, 0x35, 0x75, 0x20, 0x52, + 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x3d, 0x25, + 0x35, 0x75, 0x20, 0x25, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xb5, 0x0b, 0xa0, 0xfd, 0xf7, 0x35, + 0xfb, 0x0f, 0x4c, 0x00, 0x27, 0x78, 0x00, 0xc0, + 0x19, 0x80, 0x00, 0xed, 0x09, 0x00, 0xef, 0x01, + 0x20, 0x58, 0x01, 0x28, 0x04, 0xd1, 0x00, 0x22, + 0x00, 0x21, 0x38, 0x1c, 0x00, 0xf0, 0x53, 0xf8, + 0x01, 0x37, 0x14, 0x2f, 0xf1, 0xd3, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x0a, 0x63, + 0x6c, 0x65, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x00, 0x00, 0x30, 0x68, + 0x03, 0x20, 0xb0, 0xb5, 0x0d, 0xa0, 0xfd, 0xf7, + 0x0f, 0xfb, 0x11, 0x4d, 0x00, 0x27, 0x78, 0x00, + 0xc0, 0x19, 0x80, 0x00, 0x29, 0x58, 0x01, 0x29, + 0x09, 0xd1, 0x44, 0x19, 0xa2, 0x68, 0x0d, 0xa0, + 0x39, 0x1c, 0xfd, 0xf7, 0x01, 0xfb, 0xa0, 0x68, + 0x61, 0x68, 0x02, 0xf0, 0xf4, 0xfb, 0x01, 0x37, + 0x14, 0x2f, 0xec, 0xd3, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x00, + 0x00, 0x00, 0x30, 0x68, 0x03, 0x20, 0x0a, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x20, 0x25, 0x64, 0x3a, 0x20, 0x20, 0x41, + 0x64, 0x64, 0x72, 0x3d, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x00, 0xf0, 0xb5, + 0x0c, 0x1c, 0x07, 0x1c, 0x14, 0x28, 0x07, 0xd3, + 0x39, 0x1c, 0x14, 0x22, 0x23, 0xa0, 0xfd, 0xf7, + 0xcb, 0xfa, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x7e, 0x00, 0xf6, 0x19, 0x2b, 0x48, 0xb6, 0x00, + 0x85, 0x19, 0x00, 0x2c, 0x1e, 0xd0, 0x80, 0x59, + 0x01, 0x28, 0x04, 0xd1, 0x39, 0x1c, 0x27, 0xa0, + 0xfd, 0xf7, 0xba, 0xfa, 0xed, 0xe7, 0x39, 0x1c, + 0x22, 0x1c, 0x2a, 0xa0, 0xfd, 0xf7, 0xb4, 0xfa, + 0x22, 0x49, 0x01, 0x20, 0x88, 0x51, 0xed, 0x09, + 0x00, 0xf0, 0x01, 0xac, 0x60, 0x20, 0x68, 0x68, + 0x60, 0x16, 0xf0, 0xb7, 0xfe, 0x78, 0x1c, 0x2c, + 0x4b, 0x00, 0x02, 0x18, 0x43, 0x20, 0x60, 0x16, + 0xf0, 0xac, 0xfe, 0xa8, 0x68, 0x00, 0x68, 0xd6, + 0xe7, 0x04, 0x1c, 0x80, 0x59, 0x00, 0x28, 0x04, + 0xd1, 0x39, 0x1c, 0x26, 0xa0, 0xfd, 0xf7, 0x9a, + 0xfa, 0xcd, 0xe7, 0x13, 0x2f, 0x03, 0xd0, 0x39, + 0x1c, 0x2a, 0xa0, 0xfd, 0xf7, 0x93, 0xfa, 0x16, + 0xf0, 0x9c, 0xfe, 0x29, 0x1d, 0x03, 0xc9, 0x08, + 0x60, 0x16, 0xf0, 0x93, 0xfe, 0xa8, 0x68, 0x00, + 0x68, 0x00, 0x20, 0xa0, 0x51, 0xbb, 0xe7, 0x0a, + 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x25, 0x64, 0x20, 0x28, 0x73, 0x68, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, + 0x3c, 0x20, 0x25, 0x64, 0x29, 0x00, 0x00, 0x30, + 0x68, 0x03, 0x20, 0x0a, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x25, + 0x64, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x73, 0x65, + 0x00, 0x00, 0x00, 0x0a, 0x73, 0x65, 0x74, 0x20, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x20, 0x25, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x64, 0x64, 0x72, 0x20, 0x25, 0x30, + 0x38, 0x58, 0x00, 0x10, 0x00, 0x00, 0xe6, 0x0a, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x20, 0x25, 0x64, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x73, 0x65, + 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x25, 0x64, 0x00, + 0x00, 0x00, 0x00, 0x91, 0xb5, 0x81, 0xb0, 0x01, + 0x99, 0xed, 0x09, 0x00, 0xf1, 0x01, 0xfa, 0xa0, + 0x03, 0x22, 0x06, 0xf0, 0x8f, 0xff, 0xf9, 0x4f, + 0x00, 0x28, 0x17, 0xd1, 0x01, 0x98, 0x03, 0x30, + 0x01, 0x90, 0x38, 0x68, 0x44, 0x68, 0x01, 0xa8, + 0xfc, 0xf7, 0x1a, 0xff, 0x00, 0x90, 0x68, 0x46, + 0xfd, 0xf7, 0x1c, 0xf8, 0x39, 0x68, 0x22, 0x1c, + 0x48, 0x60, 0x03, 0x1c, 0xf1, 0xa0, 0xf0, 0xa1, + 0xfd, 0xf7, 0x17, 0xfa, 0x02, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x01, 0x99, 0xf2, 0xa0, + 0x03, 0x22, 0x06, 0xf0, 0x6f, 0xff, 0x00, 0x28, + 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, 0x90, + 0x38, 0x68, 0x84, 0x68, 0x01, 0xa8, 0xfc, 0xf7, + 0xfb, 0xfe, 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, + 0xfd, 0xff, 0x39, 0x68, 0x22, 0x1c, 0x88, 0x60, + 0x03, 0x1c, 0xe2, 0xa0, 0xe7, 0xa1, 0xfd, 0xf7, + 0xf8, 0xf9, 0xdf, 0xe7, 0x01, 0x99, 0xe6, 0xa0, + 0x03, 0x22, 0x06, 0xf0, 0x53, 0xff, 0x00, 0x28, + 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, 0x90, + 0x38, 0x68, 0xc4, 0x68, 0x01, 0xa8, 0xfc, 0xf7, + 0xdf, 0xfe, 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, + 0xe1, 0xff, 0x39, 0x68, 0x22, 0x1c, 0xc8, 0x60, + 0x03, 0x1c, 0xd4, 0xa0, 0xdb, 0xa1, 0xfd, 0xf7, + 0xdc, 0xf9, 0xc3, 0xe7, 0x01, 0x99, 0xda, 0xa0, + 0x03, 0x22, 0x06, 0xf0, 0x37, 0xff, 0x00, 0x28, + 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, 0x90, + 0x38, 0x68, 0x04, 0x69, 0x01, 0xa8, 0xfc, 0xf7, + 0xc3, 0xfe, 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, + 0xc5, 0xff, 0x39, 0x68, 0x22, 0x1c, 0x08, 0x61, + 0x03, 0x1c, 0xc6, 0xa0, 0xcf, 0xa1, 0xfd, 0xf7, + 0xc0, 0xf9, 0xa7, 0xe7, 0x01, 0x99, 0xce, 0xa0, + 0x03, 0x22, 0x06, 0xf0, 0x1b, 0xff, 0x00, 0x28, + 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, 0x90, + 0x38, 0x68, 0x44, 0x69, 0xed, 0x09, 0x00, 0xf2, + 0x01, 0x01, 0xa8, 0xfc, 0xf7, 0xa7, 0xfe, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0xa9, 0xff, 0x39, + 0x68, 0x22, 0x1c, 0x48, 0x61, 0x03, 0x1c, 0xb8, + 0xa0, 0xc3, 0xa1, 0xfd, 0xf7, 0xa4, 0xf9, 0x8b, + 0xe7, 0x01, 0x99, 0xc2, 0xa0, 0x03, 0x22, 0x06, + 0xf0, 0xff, 0xfe, 0x00, 0x28, 0x14, 0xd1, 0x01, + 0x98, 0x03, 0x30, 0x01, 0x90, 0x38, 0x68, 0x84, + 0x69, 0x01, 0xa8, 0xfc, 0xf7, 0x8b, 0xfe, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x8d, 0xff, 0x39, + 0x68, 0x22, 0x1c, 0x88, 0x61, 0x03, 0x1c, 0xaa, + 0xa0, 0xb7, 0xa1, 0xfd, 0xf7, 0x88, 0xf9, 0x6f, + 0xe7, 0x01, 0x99, 0xb6, 0xa0, 0x03, 0x22, 0x06, + 0xf0, 0xe3, 0xfe, 0x00, 0x28, 0x14, 0xd1, 0x01, + 0x98, 0x03, 0x30, 0x01, 0x90, 0x38, 0x68, 0xc4, + 0x69, 0x01, 0xa8, 0xfc, 0xf7, 0x6f, 0xfe, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x71, 0xff, 0x39, + 0x68, 0x22, 0x1c, 0xc8, 0x61, 0x03, 0x1c, 0x9c, + 0xa0, 0xab, 0xa1, 0xfd, 0xf7, 0x6c, 0xf9, 0x53, + 0xe7, 0x01, 0x99, 0xaa, 0xa0, 0x03, 0x22, 0x06, + 0xf0, 0xc7, 0xfe, 0x00, 0x28, 0x14, 0xd1, 0x01, + 0x98, 0x03, 0x30, 0x01, 0x90, 0x38, 0x68, 0x04, + 0x6a, 0x01, 0xa8, 0xfc, 0xf7, 0x53, 0xfe, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x55, 0xff, 0x39, + 0x68, 0x22, 0x1c, 0x08, 0x62, 0x03, 0x1c, 0x8e, + 0xa0, 0x9f, 0xa1, 0xfd, 0xf7, 0x50, 0xf9, 0x37, + 0xe7, 0x01, 0x99, 0x9e, 0xa0, 0x03, 0x22, 0x06, + 0xf0, 0xab, 0xfe, 0x00, 0x28, 0x14, 0xd1, 0x01, + 0x98, 0x03, 0x30, 0x01, 0x90, 0x38, 0x68, 0x44, + 0x6a, 0x01, 0xa8, 0xfc, 0xf7, 0x37, 0xfe, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x39, 0xff, 0x39, + 0x68, 0x22, 0x1c, 0x48, 0x62, 0x03, 0x1c, 0x80, + 0xa0, 0x93, 0xa1, 0xfd, 0xf7, 0x34, 0xf9, 0xed, + 0x09, 0x00, 0xf3, 0x01, 0x1b, 0xe7, 0x01, 0x99, + 0x92, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x8f, 0xfe, + 0x00, 0x28, 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, + 0x01, 0x90, 0x38, 0x68, 0x84, 0x6a, 0x01, 0xa8, + 0xfc, 0xf7, 0x1b, 0xfe, 0x00, 0x90, 0x68, 0x46, + 0xfc, 0xf7, 0x1d, 0xff, 0x39, 0x68, 0x22, 0x1c, + 0x88, 0x62, 0x03, 0x1c, 0x72, 0xa0, 0x87, 0xa1, + 0xfd, 0xf7, 0x18, 0xf9, 0xff, 0xe6, 0x01, 0x99, + 0x86, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x73, 0xfe, + 0x00, 0x28, 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, + 0x01, 0x90, 0x38, 0x68, 0xc4, 0x6a, 0x01, 0xa8, + 0xfc, 0xf7, 0xff, 0xfd, 0x00, 0x90, 0x68, 0x46, + 0xfc, 0xf7, 0x01, 0xff, 0x39, 0x68, 0x22, 0x1c, + 0xc8, 0x62, 0x03, 0x1c, 0x64, 0xa0, 0x7b, 0xa1, + 0xfd, 0xf7, 0xfc, 0xf8, 0xe3, 0xe6, 0x01, 0x99, + 0x7a, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x57, 0xfe, + 0x00, 0x28, 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, + 0x01, 0x90, 0x38, 0x68, 0x04, 0x6b, 0x01, 0xa8, + 0xfc, 0xf7, 0xe3, 0xfd, 0x00, 0x90, 0x68, 0x46, + 0xfc, 0xf7, 0xe5, 0xfe, 0x39, 0x68, 0x22, 0x1c, + 0x08, 0x63, 0x03, 0x1c, 0x56, 0xa0, 0x6f, 0xa1, + 0xfd, 0xf7, 0xe0, 0xf8, 0xc7, 0xe6, 0x01, 0x99, + 0x6e, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x3b, 0xfe, + 0x00, 0x28, 0x14, 0xd1, 0x01, 0x98, 0x03, 0x30, + 0x01, 0x90, 0x38, 0x68, 0x44, 0x6b, 0x01, 0xa8, + 0xfc, 0xf7, 0xc7, 0xfd, 0x00, 0x90, 0x68, 0x46, + 0xfc, 0xf7, 0xc9, 0xfe, 0x39, 0x68, 0x22, 0x1c, + 0x48, 0x63, 0x03, 0x1c, 0x48, 0xa0, 0x63, 0xa1, + 0xfd, 0xf7, 0xc4, 0xf8, 0xab, 0xe6, 0x01, 0x99, + 0x62, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x1f, 0xfe, + 0x00, 0x28, 0x15, 0xd1, 0x01, 0x98, 0x03, 0x30, + 0x01, 0x90, 0x38, 0x68, 0x84, 0x6b, 0x01, 0xa8, + 0xfc, 0xf7, 0xed, 0x09, 0x00, 0xf4, 0x01, 0xab, + 0xfd, 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, 0xad, + 0xfe, 0x83, 0x08, 0x9b, 0x00, 0x38, 0x68, 0x22, + 0x1c, 0x83, 0x63, 0x39, 0xa0, 0x57, 0xa1, 0xfd, + 0xf7, 0xa7, 0xf8, 0x8e, 0xe6, 0x01, 0x99, 0x55, + 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x02, 0xfe, 0x00, + 0x28, 0x15, 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, + 0x90, 0x38, 0x68, 0xc4, 0x6b, 0x01, 0xa8, 0xfc, + 0xf7, 0x8e, 0xfd, 0x00, 0x90, 0x68, 0x46, 0xfc, + 0xf7, 0x90, 0xfe, 0x83, 0x08, 0x9b, 0x00, 0x38, + 0x68, 0x22, 0x1c, 0xc3, 0x63, 0x2b, 0xa0, 0x4a, + 0xa1, 0xfd, 0xf7, 0x8a, 0xf8, 0x71, 0xe6, 0x01, + 0x99, 0x49, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0xe5, + 0xfd, 0x00, 0x28, 0x15, 0xd1, 0x01, 0x98, 0x03, + 0x30, 0x01, 0x90, 0x38, 0x68, 0x04, 0x6c, 0x01, + 0xa8, 0xfc, 0xf7, 0x71, 0xfd, 0x00, 0x90, 0x68, + 0x46, 0xfc, 0xf7, 0x73, 0xfe, 0x83, 0x08, 0x9b, + 0x00, 0x38, 0x68, 0x22, 0x1c, 0x03, 0x64, 0x1c, + 0xa0, 0x3e, 0xa1, 0xfd, 0xf7, 0x6d, 0xf8, 0x54, + 0xe6, 0x01, 0x99, 0x3c, 0xa0, 0x03, 0x22, 0x06, + 0xf0, 0xc8, 0xfd, 0x3b, 0x4f, 0x00, 0x28, 0x12, + 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, 0x90, 0x3c, + 0x68, 0x01, 0xa8, 0xfc, 0xf7, 0x54, 0xfd, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x56, 0xfe, 0x22, + 0x1c, 0x03, 0x1c, 0x38, 0x60, 0x0f, 0xa0, 0x33, + 0xa1, 0xfd, 0xf7, 0x52, 0xf8, 0x39, 0xe6, 0x01, + 0x99, 0x32, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0xad, + 0xfd, 0x00, 0x28, 0x69, 0xd1, 0x01, 0x98, 0x03, + 0x30, 0x01, 0x90, 0x7c, 0x68, 0x01, 0xa8, 0xfc, + 0xf7, 0x3a, 0xfd, 0x00, 0x90, 0x68, 0x46, 0xfc, + 0xf7, 0x3c, 0xfe, 0x54, 0xe0, 0x00, 0x00, 0x61, + 0x31, 0x3d, 0x00, 0x24, 0x69, 0x03, 0x20, 0x41, + 0x31, 0x00, 0x00, 0x0a, 0x25, 0xed, 0x09, 0x00, + 0xf5, 0x01, 0x73, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x2d, 0x3e, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x00, 0x00, 0x00, 0x00, 0x61, 0x32, 0x3d, 0x00, + 0x41, 0x32, 0x00, 0x00, 0x61, 0x33, 0x3d, 0x00, + 0x41, 0x33, 0x00, 0x00, 0x61, 0x34, 0x3d, 0x00, + 0x41, 0x34, 0x00, 0x00, 0x76, 0x31, 0x3d, 0x00, + 0x56, 0x31, 0x00, 0x00, 0x76, 0x32, 0x3d, 0x00, + 0x56, 0x32, 0x00, 0x00, 0x76, 0x33, 0x3d, 0x00, + 0x56, 0x33, 0x00, 0x00, 0x76, 0x34, 0x3d, 0x00, + 0x56, 0x34, 0x00, 0x00, 0x76, 0x35, 0x3d, 0x00, + 0x56, 0x35, 0x00, 0x00, 0x76, 0x36, 0x3d, 0x00, + 0x56, 0x36, 0x00, 0x00, 0x76, 0x37, 0x3d, 0x00, + 0x56, 0x37, 0x00, 0x00, 0x76, 0x38, 0x3d, 0x00, + 0x56, 0x38, 0x00, 0x00, 0x69, 0x70, 0x3d, 0x00, + 0x49, 0x50, 0x00, 0x00, 0x73, 0x70, 0x3d, 0x00, + 0x53, 0x50, 0x00, 0x00, 0x6c, 0x72, 0x3d, 0x00, + 0x4c, 0x52, 0x00, 0x00, 0x70, 0x63, 0x3d, 0x00, + 0x50, 0x43, 0x00, 0x00, 0x74, 0x31, 0x3d, 0x00, + 0xa0, 0xbd, 0x03, 0x20, 0x54, 0x31, 0x00, 0x00, + 0x74, 0x32, 0x3d, 0x00, 0x78, 0x60, 0x03, 0x1c, + 0x01, 0xa0, 0x22, 0x1c, 0xa8, 0x38, 0xbb, 0xa1, + 0xfc, 0xf7, 0xe1, 0xff, 0xc8, 0xe5, 0xff, 0xe7, + 0x01, 0x99, 0xb9, 0xa0, 0x03, 0x22, 0x06, 0xf0, + 0x3b, 0xfd, 0x00, 0x28, 0x13, 0xd1, 0x01, 0x98, + 0x03, 0x30, 0x01, 0x90, 0xbc, 0x68, 0x01, 0xa8, + 0xfc, 0xf7, 0xc8, 0xfc, 0x00, 0x90, 0x68, 0x46, + 0xfc, 0xf7, 0xca, 0xfd, 0xb8, 0x60, 0x03, 0x1c, + 0x01, 0xa0, 0x22, 0x1c, 0xe0, 0x38, 0xaf, 0xa1, + 0xfc, 0xf7, 0xc5, 0xff, 0xac, 0xe5, 0x01, 0x99, + 0xad, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x20, 0xfd, + 0x00, 0x28, 0x12, 0xd1, 0x01, 0x98, 0x03, 0x30, + 0x01, 0x90, 0xfc, 0x68, 0x01, 0xa8, 0xfc, 0xf7, + 0xed, 0x09, 0x00, 0xf6, 0x01, 0xad, 0xfc, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0xaf, 0xfd, 0x22, + 0x1c, 0x03, 0x1c, 0xf8, 0x60, 0xa5, 0x48, 0xa4, + 0xa1, 0xfc, 0xf7, 0xab, 0xff, 0x92, 0xe5, 0x01, + 0x99, 0xa3, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x06, + 0xfd, 0x00, 0x28, 0x12, 0xd1, 0x01, 0x98, 0x03, + 0x30, 0x01, 0x90, 0x3c, 0x69, 0x01, 0xa8, 0xfc, + 0xf7, 0x93, 0xfc, 0x00, 0x90, 0x68, 0x46, 0xfc, + 0xf7, 0x95, 0xfd, 0x22, 0x1c, 0x03, 0x1c, 0x38, + 0x61, 0x98, 0x48, 0x9a, 0xa1, 0xfc, 0xf7, 0x91, + 0xff, 0x78, 0xe5, 0x01, 0x99, 0x98, 0xa0, 0x03, + 0x22, 0x06, 0xf0, 0xec, 0xfc, 0x00, 0x28, 0x12, + 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, 0x90, 0x7c, + 0x69, 0x01, 0xa8, 0xfc, 0xf7, 0x79, 0xfc, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x7b, 0xfd, 0x22, + 0x1c, 0x03, 0x1c, 0x78, 0x61, 0x8b, 0x48, 0x8f, + 0xa1, 0xfc, 0xf7, 0x77, 0xff, 0x5e, 0xe5, 0x01, + 0x99, 0x8d, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0xd2, + 0xfc, 0x00, 0x28, 0x12, 0xd1, 0x01, 0x98, 0x03, + 0x30, 0x01, 0x90, 0xbc, 0x69, 0x01, 0xa8, 0xfc, + 0xf7, 0x5f, 0xfc, 0x00, 0x90, 0x68, 0x46, 0xfc, + 0xf7, 0x61, 0xfd, 0x22, 0x1c, 0x03, 0x1c, 0xb8, + 0x61, 0x7e, 0x48, 0x84, 0xa1, 0xfc, 0xf7, 0x5d, + 0xff, 0x44, 0xe5, 0x01, 0x99, 0x82, 0xa0, 0x03, + 0x22, 0x06, 0xf0, 0xb8, 0xfc, 0x00, 0x28, 0x12, + 0xd1, 0x01, 0x98, 0x03, 0x30, 0x01, 0x90, 0xfc, + 0x69, 0x01, 0xa8, 0xfc, 0xf7, 0x45, 0xfc, 0x00, + 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x47, 0xfd, 0x22, + 0x1c, 0x03, 0x1c, 0xf8, 0x61, 0x71, 0x48, 0x79, + 0xa1, 0xfc, 0xf7, 0x43, 0xff, 0x2a, 0xe5, 0x01, + 0x99, 0x77, 0xa0, 0x03, 0x22, 0x06, 0xf0, 0x9e, + 0xfc, 0x00, 0x28, 0x12, 0xd1, 0x01, 0x98, 0x03, + 0x30, 0x01, 0x90, 0xed, 0x09, 0x00, 0xf7, 0x01, + 0x3c, 0x6a, 0x01, 0xa8, 0xfc, 0xf7, 0x2b, 0xfc, + 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x2d, 0xfd, + 0x22, 0x1c, 0x03, 0x1c, 0x38, 0x62, 0x64, 0x48, + 0x6e, 0xa1, 0xfc, 0xf7, 0x29, 0xff, 0x10, 0xe5, + 0x01, 0x99, 0x6c, 0xa0, 0x04, 0x22, 0x06, 0xf0, + 0x84, 0xfc, 0x00, 0x28, 0x12, 0xd1, 0x01, 0x98, + 0x04, 0x30, 0x01, 0x90, 0x7c, 0x6a, 0x01, 0xa8, + 0xfc, 0xf7, 0x11, 0xfc, 0x00, 0x90, 0x68, 0x46, + 0xfc, 0xf7, 0x13, 0xfd, 0x22, 0x1c, 0x03, 0x1c, + 0x78, 0x62, 0x57, 0x48, 0x64, 0xa1, 0xfc, 0xf7, + 0x0f, 0xff, 0xf6, 0xe4, 0x01, 0x99, 0x62, 0xa0, + 0x04, 0x22, 0x06, 0xf0, 0x6a, 0xfc, 0x00, 0x28, + 0x12, 0xd1, 0x01, 0x98, 0x04, 0x30, 0x01, 0x90, + 0xbc, 0x6a, 0x01, 0xa8, 0xfc, 0xf7, 0xf7, 0xfb, + 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, 0xf9, 0xfc, + 0x22, 0x1c, 0x03, 0x1c, 0xb8, 0x62, 0x4a, 0x48, + 0x5a, 0xa1, 0xfc, 0xf7, 0xf5, 0xfe, 0xdc, 0xe4, + 0x01, 0x99, 0x58, 0xa0, 0x04, 0x22, 0x06, 0xf0, + 0x50, 0xfc, 0x00, 0x28, 0x12, 0xd1, 0x01, 0x98, + 0x04, 0x30, 0x01, 0x90, 0xfc, 0x6a, 0x01, 0xa8, + 0xfc, 0xf7, 0xdd, 0xfb, 0x00, 0x90, 0x68, 0x46, + 0xfc, 0xf7, 0xdf, 0xfc, 0x22, 0x1c, 0x03, 0x1c, + 0xf8, 0x62, 0x3d, 0x48, 0x50, 0xa1, 0xfc, 0xf7, + 0xdb, 0xfe, 0xc2, 0xe4, 0x01, 0x99, 0x4e, 0xa0, + 0x04, 0x22, 0x06, 0xf0, 0x36, 0xfc, 0x00, 0x28, + 0x12, 0xd1, 0x01, 0x98, 0x04, 0x30, 0x01, 0x90, + 0x3c, 0x6b, 0x01, 0xa8, 0xfc, 0xf7, 0xc3, 0xfb, + 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, 0xc5, 0xfc, + 0x22, 0x1c, 0x03, 0x1c, 0x38, 0x63, 0x30, 0x48, + 0x46, 0xa1, 0xfc, 0xf7, 0xc1, 0xfe, 0xa8, 0xe4, + 0x01, 0x99, 0x44, 0xa0, 0x04, 0x22, 0x06, 0xf0, + 0x1c, 0xfc, 0x00, 0x28, 0x12, 0xd1, 0xed, 0x09, + 0x00, 0xf8, 0x01, 0x01, 0x98, 0x04, 0x30, 0x01, + 0x90, 0x7c, 0x6b, 0x01, 0xa8, 0xfc, 0xf7, 0xa9, + 0xfb, 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, 0xab, + 0xfc, 0x22, 0x1c, 0x03, 0x1c, 0x78, 0x63, 0x23, + 0x48, 0x3c, 0xa1, 0xfc, 0xf7, 0xa7, 0xfe, 0x8e, + 0xe4, 0x01, 0x99, 0x3a, 0xa0, 0x04, 0x22, 0x06, + 0xf0, 0x02, 0xfc, 0x00, 0x28, 0x12, 0xd1, 0x01, + 0x98, 0x04, 0x30, 0x01, 0x90, 0xbc, 0x6b, 0x01, + 0xa8, 0xfc, 0xf7, 0x8f, 0xfb, 0x00, 0x90, 0x68, + 0x46, 0xfc, 0xf7, 0x91, 0xfc, 0x22, 0x1c, 0x03, + 0x1c, 0xb8, 0x63, 0x16, 0x48, 0x32, 0xa1, 0xfc, + 0xf7, 0x8d, 0xfe, 0x74, 0xe4, 0x01, 0x99, 0x30, + 0xa0, 0x04, 0x22, 0x06, 0xf0, 0xe8, 0xfb, 0x00, + 0x28, 0x12, 0xd1, 0x01, 0x98, 0x04, 0x30, 0x01, + 0x90, 0xfc, 0x6b, 0x01, 0xa8, 0xfc, 0xf7, 0x75, + 0xfb, 0x00, 0x90, 0x68, 0x46, 0xfc, 0xf7, 0x77, + 0xfc, 0x22, 0x1c, 0x03, 0x1c, 0xf8, 0x63, 0x09, + 0x48, 0x28, 0xa1, 0xfc, 0xf7, 0x73, 0xfe, 0x5a, + 0xe4, 0x01, 0x99, 0x26, 0xa0, 0xfc, 0xf7, 0x6e, + 0xfe, 0x55, 0xe4, 0x54, 0x32, 0x00, 0x00, 0x74, + 0x33, 0x3d, 0x00, 0x54, 0x33, 0x00, 0x00, 0x74, + 0x34, 0x3d, 0x00, 0x54, 0x34, 0x00, 0x00, 0xfc, + 0xf0, 0x01, 0x20, 0x74, 0x35, 0x3d, 0x00, 0x54, + 0x35, 0x00, 0x00, 0x74, 0x36, 0x3d, 0x00, 0x54, + 0x36, 0x00, 0x00, 0x74, 0x37, 0x3d, 0x00, 0x54, + 0x37, 0x00, 0x00, 0x74, 0x38, 0x3d, 0x00, 0x54, + 0x38, 0x00, 0x00, 0x74, 0x39, 0x3d, 0x00, 0x54, + 0x39, 0x00, 0x00, 0x74, 0x31, 0x30, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x31, 0x30, 0x00, 0x74, + 0x31, 0x31, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x31, 0x31, 0x00, 0x74, 0x31, 0x32, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x31, 0x32, 0x00, 0x74, + 0x31, 0xed, 0x09, 0x00, 0xf9, 0x01, 0x33, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x31, 0x33, 0x00, + 0x74, 0x31, 0x34, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x31, 0x34, 0x00, 0x74, 0x31, 0x35, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x31, 0x35, 0x00, + 0x74, 0x31, 0x36, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x31, 0x36, 0x00, 0x0a, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x25, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x90, 0xb5, 0x86, 0xb0, + 0x36, 0xa0, 0xfc, 0xf7, 0x0a, 0xfe, 0x3b, 0x4f, + 0x38, 0x68, 0x00, 0x28, 0x06, 0xd1, 0x3a, 0xa0, + 0xfc, 0xf7, 0x03, 0xfe, 0x06, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x01, 0x68, 0x3d, 0x4c, + 0xa1, 0x42, 0x03, 0xd1, 0x3c, 0xa0, 0xfc, 0xf7, + 0xf8, 0xfd, 0x06, 0xe0, 0x02, 0x69, 0x03, 0x1d, + 0x00, 0x92, 0x0e, 0xcb, 0x3e, 0xa0, 0xfc, 0xf7, + 0xf0, 0xfd, 0x38, 0x68, 0x02, 0x6a, 0x14, 0x30, + 0x00, 0x92, 0x0e, 0xc8, 0x44, 0xa0, 0xfc, 0xf7, + 0xe8, 0xfd, 0x38, 0x68, 0x02, 0x6b, 0x24, 0x30, + 0x00, 0x92, 0x0e, 0xc8, 0x4a, 0xa0, 0xfc, 0xf7, + 0xe0, 0xfd, 0x38, 0x68, 0x02, 0x6c, 0x00, 0x92, + 0x41, 0x6b, 0x83, 0x6b, 0xc2, 0x6b, 0x50, 0xa0, + 0xfc, 0xf7, 0xd7, 0xfd, 0x38, 0x68, 0x07, 0x68, + 0xa7, 0x42, 0x03, 0xd1, 0x56, 0xa0, 0xfc, 0xf7, + 0xd0, 0xfd, 0xcb, 0xe7, 0xfa, 0x06, 0xd2, 0x0e, + 0xb8, 0x09, 0x01, 0xd3, 0x58, 0xa1, 0x00, 0xe0, + 0x21, 0xa1, 0xf8, 0x09, 0x01, 0xd3, 0x57, 0xa0, + 0x00, 0xe0, 0x1f, 0xa0, 0x03, 0x90, 0x38, 0x0a, + 0x05, 0x92, 0x04, 0x91, 0x01, 0xd3, 0x54, 0xa2, + 0x00, 0xe0, 0x1b, 0xa2, 0xed, 0x09, 0x00, 0xfa, + 0x01, 0x78, 0x0f, 0x01, 0xd3, 0x52, 0xa1, 0x00, + 0xe0, 0x18, 0xa1, 0xb8, 0x0f, 0x01, 0xd3, 0x51, + 0xa0, 0x00, 0xe0, 0x16, 0xa0, 0x00, 0x90, 0xf8, + 0x0f, 0x02, 0x92, 0x01, 0x91, 0x01, 0xd3, 0x4e, + 0xa3, 0x00, 0xe0, 0x12, 0xa3, 0x38, 0x08, 0x01, + 0xd3, 0x4c, 0xa2, 0x00, 0xe0, 0x0f, 0xa2, 0x39, + 0x1c, 0x4b, 0xa0, 0xfc, 0xf7, 0xa0, 0xfd, 0x9b, + 0xe7, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, + 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x00, 0x00, + 0x00, 0x24, 0x69, 0x03, 0x20, 0x0a, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x41, 0x31, + 0x2d, 0x41, 0x34, 0x3a, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x41, 0x31, + 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x20, + 0x41, 0x32, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x41, 0x33, 0x3a, 0x20, 0x25, 0x30, 0x38, + 0x58, 0x20, 0x41, 0x34, 0x3a, 0x20, 0x25, 0x30, + 0x38, 0x58, 0x00, 0x00, 0x00, 0x0a, 0x56, 0x31, + 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x20, + 0x56, 0x32, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x56, 0x33, 0x3a, 0x20, 0x25, 0x30, 0x38, + 0x58, 0x20, 0x56, 0x34, 0x3a, 0x20, 0x25, 0x30, + 0x38, 0x58, 0x00, 0x00, 0x00, 0x0a, 0x56, 0x35, + 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x56, + 0x36, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, + 0x56, 0x37, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x56, 0x38, 0x3a, 0x20, 0x25, 0x30, 0xed, + 0x09, 0x00, 0xfb, 0x01, 0x38, 0x58, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x49, 0x50, 0x3a, 0x20, 0x25, + 0x30, 0x38, 0x58, 0x20, 0x20, 0x4c, 0x52, 0x3a, + 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x53, 0x50, + 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x50, + 0x43, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, + 0x00, 0x00, 0x20, 0x43, 0x50, 0x53, 0x52, 0x3a, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x76, 0x61, + 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x46, 0x00, + 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x56, 0x00, + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x5a, 0x00, + 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x20, 0x43, + 0x50, 0x53, 0x52, 0x3a, 0x20, 0x25, 0x30, 0x38, + 0x58, 0x20, 0x28, 0x25, 0x73, 0x25, 0x73, 0x25, + 0x73, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x25, + 0x73, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x78, 0x29, + 0x00, 0x00, 0xb8, 0xb5, 0x00, 0x28, 0x01, 0xd0, + 0xfe, 0xf7, 0x79, 0xfa, 0x68, 0x46, 0xfe, 0xf7, + 0xaa, 0xfa, 0x0e, 0x4d, 0x04, 0x1c, 0x28, 0x68, + 0x00, 0x99, 0x04, 0x38, 0x43, 0x1a, 0x0c, 0xa0, + 0x22, 0x1c, 0xfc, 0xf7, 0xe7, 0xfc, 0x00, 0x27, + 0x28, 0x68, 0xba, 0x00, 0x11, 0x18, 0xa1, 0x42, + 0x09, 0xd8, 0x82, 0x58, 0x12, 0xa0, 0xfc, 0xf7, + 0xdd, 0xfc, 0x14, 0xa0, 0xfc, 0xf7, 0xda, 0xfc, + 0x01, 0x37, 0x10, 0x2f, 0xf0, 0xd3, 0xb8, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x20, 0x69, + 0x03, 0x20, 0x0a, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x3a, 0x20, 0x28, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x45, + 0x6e, 0x64, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x2c, 0x20, 0x46, 0x72, 0x65, 0x65, 0x3a, 0x20, + 0x25, 0x64, 0xed, 0x09, 0x00, 0xfc, 0x01, 0x29, + 0x0a, 0x00, 0x00, 0x25, 0x30, 0x38, 0x58, 0x3a, + 0x20, 0x20, 0x20, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0xfd, 0xf7, 0xd5, 0xfe, 0x01, 0x1c, 0x25, + 0xa0, 0x1f, 0xa3, 0x21, 0xa2, 0xfc, 0xf7, 0xa8, + 0xfc, 0x2e, 0xa0, 0xfc, 0xf7, 0xa5, 0xfc, 0x32, + 0xa0, 0xfc, 0xf7, 0xa2, 0xfc, 0x3d, 0xa0, 0xfc, + 0xf7, 0x9f, 0xfc, 0x4c, 0xa0, 0xfc, 0xf7, 0x9c, + 0xfc, 0x58, 0xa0, 0xfc, 0xf7, 0x99, 0xfc, 0x62, + 0xa0, 0xfc, 0xf7, 0x96, 0xfc, 0x72, 0xa0, 0xfc, + 0xf7, 0x93, 0xfc, 0x7c, 0xa0, 0xfc, 0xf7, 0x90, + 0xfc, 0x88, 0xa0, 0xfc, 0xf7, 0x8d, 0xfc, 0x94, + 0xa0, 0xfc, 0xf7, 0x8a, 0xfc, 0xa1, 0xa0, 0xfc, + 0xf7, 0x87, 0xfc, 0xae, 0xa0, 0xfc, 0xf7, 0x84, + 0xfc, 0xba, 0xa0, 0xfc, 0xf7, 0x81, 0xfc, 0xc6, + 0xa0, 0xfc, 0xf7, 0x7e, 0xfc, 0xcb, 0xa0, 0xfc, + 0xf7, 0x7b, 0xfc, 0xd6, 0xa0, 0xfc, 0xf7, 0x78, + 0xfc, 0xe2, 0xa0, 0xfc, 0xf7, 0x75, 0xfc, 0xeb, + 0xa0, 0xfc, 0xf7, 0x72, 0xfc, 0xf3, 0xa0, 0xfc, + 0xf7, 0x6f, 0xfc, 0xf6, 0xe1, 0x00, 0x00, 0x41, + 0x70, 0x72, 0x20, 0x32, 0x33, 0x20, 0x32, 0x30, + 0x30, 0x33, 0x00, 0x31, 0x36, 0x3a, 0x30, 0x35, + 0x3a, 0x31, 0x34, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x25, 0x73, + 0x20, 0x28, 0x25, 0x73, 0x20, 0x25, 0x73, 0x29, + 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x73, 0x20, 0x28, 0x6e, 0x75, 0x63, + 0x6c, 0x65, 0x75, 0x73, 0x29, 0x3a, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x20, 0xed, 0x09, 0x00, + 0xfd, 0x01, 0x20, 0x74, 0x61, 0x5b, 0x61, 0x73, + 0x6b, 0x73, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x0a, 0x00, + 0x20, 0x20, 0x20, 0x74, 0x41, 0x5b, 0x61, 0x73, + 0x6b, 0x73, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x20, 0x28, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x29, + 0x0a, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x74, + 0x61, 0x5b, 0x61, 0x73, 0x6b, 0x73, 0x5d, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, + 0x74, 0x61, 0x73, 0x6b, 0x0a, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0x68, 0x69, 0x5b, 0x69, 0x73, + 0x72, 0x73, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x48, 0x49, 0x53, 0x52, 0x73, 0x0a, 0x00, + 0x20, 0x20, 0x20, 0x68, 0x49, 0x5b, 0x69, 0x73, + 0x72, 0x73, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, + 0xed, 0x09, 0x00, 0xfe, 0x01, 0x20, 0x48, 0x49, + 0x53, 0x52, 0x73, 0x20, 0x28, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x20, + 0x69, 0x6e, 0x66, 0x6f, 0x29, 0x0a, 0x00, 0x00, + 0x00, 0x20, 0x20, 0x20, 0x70, 0x69, 0x5b, 0x70, + 0x65, 0x73, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x70, 0x69, 0x70, 0x65, 0x73, 0x0a, + 0x00, 0x20, 0x20, 0x20, 0x71, 0x75, 0x5b, 0x65, + 0x75, 0x65, 0x73, 0x5d, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x71, 0x75, 0x65, 0x75, 0x65, 0x73, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x5b, 0x6d, 0x61, 0x70, 0x68, 0x6f, + 0x72, 0x65, 0x73, 0x5d, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x73, 0x65, + 0x6d, 0x61, 0x70, 0x68, 0x6f, 0x72, 0x65, 0x73, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0x6d, 0x65, 0x5b, 0x6d, 0x6f, 0x72, 0x79, 0x20, + 0x70, 0x6f, 0x6f, 0x6c, 0x5d, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x70, 0x6f, 0x6f, + 0x6c, 0x73, 0x0a, 0x00, 0x00, 0x20, 0x20, 0x20, + 0x70, 0x61, 0x5b, 0x72, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x5d, 0xed, 0x09, 0x00, 0xff, 0x01, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x00, 0x20, 0x20, + 0x20, 0x74, 0x69, 0x5b, 0x6d, 0x65, 0x72, 0x73, + 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, + 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x72, 0x73, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x20, 0x20, 0x63, 0x75, 0x5b, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5d, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x74, + 0x61, 0x73, 0x6b, 0x2f, 0x48, 0x49, 0x53, 0x52, + 0x0a, 0x00, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x20, 0x28, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x29, 0x3a, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x20, 0x20, 0x72, 0x65, 0x67, + 0x5b, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x73, 0x0a, 0x00, 0x20, 0x20, + 0x20, 0x73, 0x74, 0x5b, 0x61, 0x63, 0x6b, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xed, 0x09, + 0x00, 0x00, 0x02, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x0a, 0x00, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x73, 0x5b, 0x65, 0x74, + 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, + 0x65, 0x73, 0x65, 0x74, 0x20, 0x63, 0x61, 0x72, + 0x64, 0x0a, 0x00, 0x20, 0x20, 0x20, 0x67, 0x6f, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x67, 0x6f, 0x0a, 0x00, 0x20, + 0x20, 0x20, 0x68, 0x61, 0x5b, 0x6c, 0x74, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, + 0x61, 0x6c, 0x74, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x15, 0xe0, 0x20, 0x20, 0x20, 0x64, 0x62, + 0x20, 0x5b, 0x61, 0x64, 0x64, 0x72, 0x5d, 0x20, + 0x5b, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x64, 0x75, 0x6d, 0x70, 0x20, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x0a, 0x00, 0xfc, + 0xf7, 0x5d, 0xfa, 0x1b, 0xa0, 0xfc, 0xf7, 0x5a, + 0xfa, 0x26, 0xa0, 0xfc, 0xf7, 0x57, 0xfa, 0x2f, + 0xa0, 0xfc, 0xf7, 0x54, 0xfa, 0x3a, 0xa0, 0xfc, + 0xf7, 0x51, 0xfa, 0x44, 0xa0, 0xfc, 0xf7, 0x4e, + 0xfa, 0x4f, 0xa0, 0xfc, 0xf7, 0x4b, 0xfa, 0x5a, + 0xa0, 0xfc, 0xf7, 0x48, 0xfa, 0x67, 0xa0, 0xfc, + 0xf7, 0x45, 0xfa, 0x72, 0xa0, 0xfc, 0xf7, 0x42, + 0xfa, 0xed, 0x09, 0x00, 0x01, 0x02, 0x80, 0xa0, + 0xfc, 0xf7, 0x3f, 0xfa, 0x8c, 0xa0, 0xfc, 0xf7, + 0x3c, 0xfa, 0x99, 0xa0, 0xfc, 0xf7, 0x39, 0xfa, + 0xa7, 0xa0, 0xfc, 0xf7, 0x36, 0xfa, 0xb4, 0xa0, + 0xfc, 0xf7, 0x33, 0xfa, 0xc1, 0xa0, 0xfc, 0xf7, + 0x30, 0xfa, 0xcf, 0xa0, 0xfc, 0xf7, 0x2d, 0xfa, + 0xdf, 0xa0, 0xfc, 0xf7, 0x2a, 0xfa, 0xf5, 0xa0, + 0xfc, 0xf7, 0x27, 0xfa, 0x02, 0xe2, 0x00, 0x00, + 0x20, 0x20, 0x20, 0x64, 0x77, 0x20, 0x5b, 0x61, + 0x64, 0x64, 0x72, 0x5d, 0x20, 0x5b, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x5d, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x75, 0x6d, 0x70, 0x20, 0x73, 0x68, 0x6f, + 0x72, 0x74, 0x73, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0x64, 0x64, 0x20, 0x5b, 0x61, + 0x64, 0x64, 0x72, 0x5d, 0x20, 0x5b, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x5d, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x75, 0x6d, 0x70, 0x20, 0x77, 0x6f, 0x72, + 0x64, 0x73, 0x0a, 0x00, 0x20, 0x20, 0x20, 0x63, + 0x62, 0x20, 0x5b, 0x61, 0x64, 0x64, 0x72, 0x5d, + 0x20, 0x5b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x0a, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x63, + 0x77, 0x20, 0x5b, 0x61, 0x64, 0x64, 0x72, 0x5d, + 0x20, 0x5b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x72, 0x74, + 0x73, 0x0a, 0x00, 0x00, 0x20, 0x20, 0x20, 0x63, + 0x64, 0x20, 0x5b, 0x61, 0xed, 0x09, 0x00, 0x02, + 0x02, 0x64, 0x64, 0x72, 0x5d, 0x20, 0x5b, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5d, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, + 0x77, 0x6f, 0x72, 0x64, 0x73, 0x0a, 0x00, 0x00, + 0x00, 0x20, 0x20, 0x20, 0x66, 0x62, 0x20, 0x5b, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5d, 0x20, 0x5b, + 0x2d, 0x7c, 0x66, 0x72, 0x6f, 0x6d, 0x5d, 0x20, + 0x5b, 0x74, 0x6f, 0x5d, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x62, 0x79, + 0x74, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, + 0x74, 0x6f, 0x20, 0x0a, 0x00, 0x20, 0x20, 0x20, + 0x66, 0x77, 0x20, 0x5b, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5d, 0x20, 0x5b, 0x2d, 0x7c, 0x66, 0x72, + 0x6f, 0x6d, 0x5d, 0x20, 0x5b, 0x74, 0x6f, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6e, + 0x64, 0x20, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x6f, 0x20, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0x66, 0x64, 0x20, 0x5b, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5d, 0x20, 0x5b, 0x2d, 0x7c, 0x66, 0x72, + 0x6f, 0x6d, 0x5d, 0x20, 0x5b, 0x74, 0x6f, 0x5d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6e, + 0x64, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x6f, 0x20, 0x0a, + 0x00, 0x20, 0x20, 0x20, 0x62, 0x72, 0x20, 0x3c, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3e, 0x20, + 0x3c, 0x30, 0x7c, 0x41, 0x64, 0x64, 0x72, 0x3e, + 0x20, 0x28, 0x30, 0x3d, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x29, 0x20, 0x73, 0x65, 0x74, 0x2f, 0x72, + 0x65, 0x73, 0x65, 0x74, 0x20, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0xed, + 0x09, 0x00, 0x03, 0x02, 0x73, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x5b, + 0x69, 0x73, 0x74, 0x5d, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x0a, 0x00, + 0x00, 0x00, 0x20, 0x20, 0x20, 0x63, 0x6c, 0x5b, + 0x65, 0x61, 0x72, 0x5d, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x0a, + 0x00, 0x00, 0x20, 0x20, 0x20, 0x74, 0x72, 0x5b, + 0x61, 0x63, 0x65, 0x5d, 0x20, 0x5b, 0x61, 0x64, + 0x64, 0x72, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x20, + 0x6f, 0x6e, 0x65, 0x2f, 0x74, 0x6f, 0x20, 0x61, + 0x64, 0x64, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, + 0x00, 0x00, 0x20, 0x20, 0x20, 0x75, 0x6e, 0x5b, + 0x61, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x65, + 0x5d, 0x20, 0x3c, 0x61, 0x64, 0x64, 0x72, 0x3e, + 0x20, 0x3c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3e, + 0x20, 0x20, 0x75, 0x6e, 0x61, 0x73, 0x73, 0x65, + 0x6d, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x0a, 0x00, 0x20, 0x20, 0x20, 0x61, 0x64, 0x5b, + 0x64, 0x5d, 0x20, 0x61, 0x64, 0x64, 0x72, 0x20, + 0x6c, 0x65, 0xed, 0x09, 0x00, 0x04, 0x02, 0x6e, + 0x67, 0x74, 0x68, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x64, 0x64, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x28, + 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x29, + 0x20, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x0a, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x64, 0x65, + 0x5b, 0x6c, 0x65, 0x74, 0x65, 0x5d, 0x20, 0x61, + 0x64, 0x64, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x20, 0x28, 0x64, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x29, 0x20, 0x73, 0x79, 0x6d, 0x62, + 0x6f, 0x6c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x20, 0x20, 0x73, 0x79, 0x5b, 0x6d, 0x62, 0x6f, + 0x6c, 0x5d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x69, 0x73, 0x74, 0x20, 0x73, 0x79, 0x6d, 0x62, + 0x6f, 0x6c, 0x73, 0x20, 0x28, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x6e, 0x29, 0x20, 0x28, 0x6c, 0x61, 0x74, 0x65, + 0x72, 0x29, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x20, 0x20, 0x65, 0x76, 0x5b, 0x61, 0x6c, 0x5d, + 0x3c, 0x68, 0x7c, 0x64, 0x7c, 0x62, 0x7c, 0x6f, + 0x3e, 0x20, 0x3c, 0x65, 0x78, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x20, 0x65, + 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, + 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x2c, 0x20, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x3a, 0x20, + 0x6f, 0x63, 0x74, 0x61, 0x6c, 0x2c, 0x20, 0x68, + 0x65, 0x78, 0x2c, 0x20, 0x64, 0xed, 0x09, 0x00, + 0x05, 0x02, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, + 0x2c, 0x20, 0x62, 0x69, 0x6e, 0x0a, 0x00, 0x00, + 0x20, 0x20, 0x20, 0x2e, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x20, 0x6c, + 0x61, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1b, 0xe0, 0x20, 0x20, 0x20, 0x5b, + 0x61, 0x64, 0x64, 0x72, 0x5d, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x62, 0x65, 0x3a, 0x20, 0x20, 0x3c, + 0x68, 0x65, 0x78, 0x2d, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x3e, 0x20, 0x3c, 0x3a, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x3e, 0x20, + 0x3c, 0x3d, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x3e, 0x0a, 0x00, 0x00, 0xfc, 0xf7, 0x03, 0xf8, + 0x02, 0xa0, 0xfc, 0xf7, 0x00, 0xf8, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x20, 0x20, 0x20, 0x61, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, + 0x63, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, + 0x28, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x29, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0xf3, 0xb5, 0x82, 0xb0, + 0x02, 0xa8, 0x0f, 0x1c, 0xfb, 0xf7, 0xda, 0xfc, + 0x01, 0x90, 0x4a, 0x4c, 0x4a, 0x4d, 0x4b, 0x4e, + 0x00, 0x28, 0x31, 0xd0, 0x01, 0xa8, 0xfb, 0xf7, + 0xd7, 0xfd, 0x20, 0x60, 0x01, 0xe0, 0x01, 0x30, + 0x02, 0x90, 0x02, 0x98, 0x01, 0x78, 0x00, 0x29, + 0x05, 0xd0, 0x20, 0x29, 0xf7, 0xd0, 0x02, 0x99, + 0x09, 0x78, 0x2d, 0x29, 0x14, 0xd0, 0x02, 0xa8, + 0xfb, 0xf7, 0xc0, 0xfc, 0x01, 0x90, 0x00, 0x28, + 0xed, 0x09, 0x00, 0x06, 0x02, 0x1a, 0xd0, 0x01, + 0xa8, 0xfb, 0xf7, 0xc0, 0xfd, 0x30, 0x60, 0x02, + 0xa8, 0xfb, 0xf7, 0xb6, 0xfc, 0x01, 0x90, 0x00, + 0x28, 0x10, 0xd0, 0x01, 0xa8, 0xfb, 0xf7, 0xb6, + 0xfd, 0x28, 0x60, 0x0b, 0xe0, 0x01, 0x30, 0x02, + 0x90, 0x02, 0xa8, 0xfb, 0xf7, 0xa9, 0xfc, 0x01, + 0x90, 0x00, 0x28, 0x03, 0xd0, 0x01, 0xa8, 0xfb, + 0xf7, 0xa9, 0xfd, 0x28, 0x60, 0x30, 0x68, 0x39, + 0x1c, 0xfd, 0xf7, 0xba, 0xf8, 0x30, 0x60, 0x28, + 0x68, 0x39, 0x1c, 0xfd, 0xf7, 0xb5, 0xf8, 0x28, + 0x60, 0x00, 0x90, 0x04, 0x2f, 0x01, 0xd1, 0x2b, + 0xa1, 0x08, 0xe0, 0x02, 0x2f, 0x01, 0xd1, 0x2d, + 0xa1, 0x04, 0xe0, 0x01, 0x2f, 0x01, 0xd1, 0x2f, + 0xa1, 0x00, 0xe0, 0x32, 0xa1, 0x33, 0x68, 0x22, + 0x68, 0x32, 0xa0, 0xfb, 0xf7, 0x8e, 0xff, 0x31, + 0x68, 0x28, 0x68, 0x81, 0x42, 0x36, 0xd2, 0x22, + 0x68, 0x01, 0x2f, 0x20, 0xd0, 0x02, 0x2f, 0x10, + 0xd0, 0x04, 0x2f, 0x2a, 0xd1, 0x31, 0x68, 0x09, + 0x68, 0x91, 0x42, 0x26, 0xd1, 0x31, 0x68, 0x30, + 0xa0, 0xfb, 0xf7, 0x7b, 0xff, 0x30, 0x68, 0x04, + 0x30, 0x30, 0x60, 0x04, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x31, 0x68, 0x09, 0x88, 0x91, + 0x42, 0x17, 0xd1, 0x12, 0x04, 0x12, 0x0c, 0x31, + 0x68, 0x2c, 0xa0, 0xfb, 0xf7, 0x6a, 0xff, 0x30, + 0x68, 0x02, 0x30, 0x30, 0x60, 0xed, 0xe7, 0x31, + 0x68, 0x09, 0x78, 0x91, 0x42, 0x09, 0xd1, 0x12, + 0x06, 0x12, 0x0e, 0x31, 0x68, 0x2a, 0xa0, 0xfb, + 0xf7, 0x5c, 0xff, 0x30, 0x68, 0x01, 0x30, 0x30, + 0x60, 0xdf, 0xe7, 0x31, 0x68, 0xc9, 0x19, 0x31, + 0x60, 0x81, 0x42, 0xc9, 0xd3, 0x21, 0x68, 0x29, + 0xa0, 0xfb, 0xf7, 0x4f, 0xff, 0xd5, 0xe7, 0x00, + 0x00, 0x28, 0x69, 0x03, 0x20, 0x30, 0x69, 0x03, + 0x20, 0x2c, 0x69, 0xed, 0x09, 0x00, 0x07, 0x02, + 0x03, 0x20, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x20, 0x73, 0x68, 0x6f, 0x72, 0x74, + 0x00, 0x00, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x20, 0x63, 0x68, 0x61, 0x72, 0x00, + 0x00, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x00, 0x0a, 0x66, 0x69, 0x6e, 0x64, 0x20, + 0x27, 0x25, 0x73, 0x27, 0x20, 0x25, 0x78, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x25, 0x78, 0x20, + 0x74, 0x6f, 0x20, 0x25, 0x78, 0x00, 0x0a, 0x66, + 0x69, 0x6e, 0x64, 0x3a, 0x20, 0x20, 0x25, 0x30, + 0x38, 0x58, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x00, 0x00, 0x0a, 0x66, 0x69, 0x6e, 0x64, 0x3a, + 0x20, 0x20, 0x25, 0x30, 0x38, 0x58, 0x3a, 0x20, + 0x25, 0x30, 0x34, 0x58, 0x00, 0x00, 0x0a, 0x66, + 0x69, 0x6e, 0x64, 0x3a, 0x20, 0x20, 0x25, 0x30, + 0x38, 0x58, 0x3a, 0x20, 0x25, 0x30, 0x32, 0x58, + 0x00, 0x00, 0x0a, 0x66, 0x69, 0x6e, 0x64, 0x3a, + 0x20, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x00, 0x00, 0x42, 0x78, 0x01, 0x78, 0x12, 0x02, + 0x11, 0x43, 0x82, 0x78, 0xc0, 0x78, 0x12, 0x04, + 0x11, 0x43, 0x00, 0x06, 0x08, 0x43, 0x70, 0x47, + 0x01, 0x70, 0x0a, 0x0a, 0x42, 0x70, 0x0a, 0x0c, + 0x82, 0x70, 0x09, 0x0e, 0xc1, 0x70, 0x70, 0x47, + 0xf0, 0xb5, 0x8e, 0xb0, 0x07, 0x1c, 0x6f, 0x48, + 0x39, 0x1c, 0x00, 0x68, 0xfc, 0xf7, 0xeb, 0xff, + 0x39, 0x1c, 0x6d, 0x4d, 0x04, 0x1c, 0x28, 0x68, + 0xfc, 0xf7, 0xe5, 0xff, 0x28, 0x60, 0x84, 0x42, + 0x73, 0xd2, 0x01, 0x2f, 0x3d, 0xd0, 0x02, 0x2f, + 0x28, 0xd0, 0x04, 0x2f, 0x1b, 0xd0, 0xed, 0x09, + 0x00, 0x08, 0x02, 0x10, 0x2f, 0x6c, 0xd1, 0xe0, + 0x1d, 0x05, 0x30, 0xff, 0xf7, 0xd0, 0xff, 0x06, + 0x1c, 0xe0, 0x1d, 0x01, 0x30, 0xff, 0xf7, 0xcb, + 0xff, 0x05, 0x1c, 0x20, 0x1d, 0xff, 0xf7, 0xc7, + 0xff, 0x0d, 0x90, 0x20, 0x1c, 0xff, 0xf7, 0xc3, + 0xff, 0x21, 0x1c, 0x02, 0x1c, 0x5d, 0xa0, 0x01, + 0x96, 0x00, 0x95, 0x0d, 0x9b, 0xfb, 0xf7, 0xae, + 0xfe, 0xa2, 0xe0, 0xa1, 0x68, 0xe2, 0x68, 0x00, + 0x91, 0x01, 0x92, 0x0c, 0xcc, 0x08, 0x3c, 0x21, + 0x1c, 0x5d, 0xa0, 0xfb, 0xf7, 0xa3, 0xfe, 0x97, + 0xe0, 0xe2, 0x89, 0xa1, 0x89, 0x60, 0x89, 0x05, + 0x92, 0x04, 0x91, 0x03, 0x90, 0x22, 0x89, 0xe1, + 0x88, 0xa0, 0x88, 0x02, 0x92, 0x01, 0x91, 0x00, + 0x90, 0x63, 0x88, 0x22, 0x88, 0x5b, 0xa0, 0x21, + 0x1c, 0xfb, 0xf7, 0x90, 0xfe, 0x84, 0xe0, 0xe2, + 0x7b, 0xa1, 0x7b, 0x60, 0x7b, 0x0d, 0x92, 0x0c, + 0x91, 0x0b, 0x90, 0x22, 0x7b, 0xe1, 0x7a, 0xa0, + 0x7a, 0x0a, 0x92, 0x09, 0x91, 0x08, 0x90, 0x62, + 0x7a, 0x21, 0x7a, 0xe0, 0x79, 0x07, 0x92, 0x06, + 0x91, 0x05, 0x90, 0xa2, 0x79, 0x61, 0x79, 0x20, + 0x79, 0x04, 0x92, 0x03, 0x91, 0x02, 0x90, 0xe2, + 0x78, 0xa1, 0x78, 0x57, 0xa0, 0x01, 0x92, 0x00, + 0x91, 0x63, 0x78, 0x22, 0x78, 0x21, 0x1c, 0xfb, + 0xf7, 0x6d, 0xfe, 0xe0, 0x7b, 0x2e, 0x22, 0x20, + 0x28, 0x00, 0xdb, 0x02, 0x1c, 0xa0, 0x7b, 0x2e, + 0x21, 0x20, 0x28, 0x00, 0xdb, 0x01, 0x1c, 0x63, + 0x7b, 0x2e, 0x20, 0x20, 0x2b, 0x00, 0xdb, 0x18, + 0x1c, 0x0c, 0x92, 0x0b, 0x91, 0x01, 0xe0, 0x55, + 0xe0, 0x4e, 0xe0, 0x0a, 0x90, 0x20, 0x7b, 0x2e, + 0x22, 0x20, 0x28, 0x00, 0xdb, 0x02, 0x1c, 0xe0, + 0x7a, 0x2e, 0x21, 0x20, 0x28, 0x00, 0xdb, 0x01, + 0x1c, 0xa3, 0x7a, 0x2e, 0x20, 0x20, 0x2b, 0x00, + 0xdb, 0xed, 0x09, 0x00, 0x09, 0x02, 0x18, 0x1c, + 0x09, 0x92, 0x08, 0x91, 0x07, 0x90, 0x60, 0x7a, + 0x2e, 0x22, 0x20, 0x28, 0x00, 0xdb, 0x02, 0x1c, + 0x20, 0x7a, 0x2e, 0x21, 0x20, 0x28, 0x00, 0xdb, + 0x01, 0x1c, 0xe3, 0x79, 0x2e, 0x20, 0x20, 0x2b, + 0x00, 0xdb, 0x18, 0x1c, 0x06, 0x92, 0x05, 0x91, + 0x04, 0x90, 0xa0, 0x79, 0x2e, 0x22, 0x20, 0x28, + 0x00, 0xdb, 0x02, 0x1c, 0x60, 0x79, 0x2e, 0x21, + 0x20, 0x28, 0x00, 0xdb, 0x01, 0x1c, 0x23, 0x79, + 0x2e, 0x20, 0x20, 0x2b, 0x00, 0xdb, 0x18, 0x1c, + 0x03, 0x92, 0x02, 0x91, 0x01, 0x90, 0xe0, 0x78, + 0x2e, 0x22, 0x20, 0x28, 0x00, 0xdb, 0x02, 0x1c, + 0x00, 0x92, 0xa0, 0x78, 0x2e, 0x21, 0x0b, 0x1c, + 0x20, 0x28, 0x00, 0xdb, 0x03, 0x1c, 0x60, 0x78, + 0x0a, 0x1c, 0x20, 0x28, 0x00, 0xdb, 0x02, 0x1c, + 0x20, 0x78, 0x20, 0x28, 0x00, 0xdb, 0x01, 0x1c, + 0x3a, 0xa0, 0xfb, 0xf7, 0x0a, 0xfe, 0x07, 0x4d, + 0x10, 0x34, 0x28, 0x68, 0x84, 0x42, 0x00, 0xd2, + 0x34, 0xe7, 0x03, 0x48, 0x04, 0x60, 0x0e, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x34, 0x69, 0x03, 0x20, 0x38, 0x69, 0x03, 0x20, + 0x0a, 0x25, 0x30, 0x38, 0x58, 0x3a, 0x20, 0x25, + 0x30, 0x38, 0x58, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, 0x25, 0x30, + 0x38, 0x58, 0x20, 0x00, 0x0a, 0x25, 0x30, 0x38, + 0x58, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, + 0x25, 0x30, 0x38, 0x58, 0x20, 0x25, 0x30, 0x38, + 0x58, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, + 0x0a, 0x25, 0x30, 0x38, 0x58, 0x3a, 0x20, 0x25, + 0x30, 0x34, 0x58, 0x20, 0x25, 0x30, 0x34, 0x58, + 0x20, 0x25, 0x30, 0x34, 0x58, 0x20, 0x25, 0x30, + 0x34, 0x58, 0x20, 0x25, 0x30, 0x34, 0x58, 0x20, + 0x25, 0x30, 0x34, 0x58, 0xed, 0x09, 0x00, 0x0a, + 0x02, 0x20, 0x25, 0x30, 0x34, 0x58, 0x20, 0x25, + 0x30, 0x34, 0x58, 0x00, 0x00, 0x0a, 0x25, 0x30, + 0x38, 0x58, 0x3a, 0x20, 0x25, 0x30, 0x32, 0x58, + 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, 0x30, + 0x32, 0x58, 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, + 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, 0x30, 0x32, + 0x58, 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, + 0x30, 0x32, 0x58, 0x20, 0x25, 0x30, 0x32, 0x58, + 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, 0x30, + 0x32, 0x58, 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, + 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, 0x30, 0x32, + 0x58, 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, + 0x30, 0x32, 0x58, 0x20, 0x20, 0x20, 0x00, 0x00, + 0x00, 0x3a, 0x20, 0x25, 0x63, 0x25, 0x63, 0x25, + 0x63, 0x25, 0x63, 0x25, 0x63, 0x25, 0x63, 0x25, + 0x63, 0x25, 0x63, 0x25, 0x63, 0x25, 0x63, 0x25, + 0x63, 0x25, 0x63, 0x25, 0x63, 0x25, 0x63, 0x25, + 0x63, 0x25, 0x63, 0x00, 0x00, 0xb0, 0xb5, 0x01, + 0x1c, 0x1c, 0x4c, 0x07, 0x1c, 0x20, 0x68, 0xfc, + 0xf7, 0xef, 0xfe, 0x39, 0x1c, 0x01, 0x29, 0x1a, + 0x4f, 0x20, 0x60, 0x24, 0xd0, 0x02, 0x29, 0x18, + 0xd0, 0x04, 0x29, 0x0e, 0xd0, 0x10, 0x29, 0x09, + 0xd1, 0x05, 0x68, 0x39, 0x68, 0xff, 0xf7, 0x87, + 0xfe, 0x3b, 0x68, 0x21, 0x68, 0x2a, 0x1c, 0x13, + 0xa0, 0xfb, 0xf7, 0x69, 0xfd, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x39, 0x68, 0x01, 0x60, 0x3a, + 0x68, 0x21, 0x68, 0x18, 0xa0, 0xfb, 0xf7, 0x5f, + 0xfd, 0xf4, 0xe7, 0x39, 0x68, 0x01, 0x80, 0x38, + 0x68, 0x21, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x1a, + 0xa0, 0xfb, 0xf7, 0x55, 0xfd, 0xea, 0xe7, 0x39, + 0x68, 0x01, 0x70, 0x38, 0x68, 0x21, 0x68, 0x02, + 0x06, 0x12, 0x0e, 0x1d, 0xa0, 0xfb, 0xf7, 0xed, + 0x09, 0x00, 0x0b, 0x02, 0x4b, 0xfd, 0xe0, 0xe7, + 0x00, 0x00, 0x40, 0x69, 0x03, 0x20, 0x44, 0x69, + 0x03, 0x20, 0x0a, 0x25, 0x30, 0x38, 0x58, 0x20, + 0x28, 0x34, 0x20, 0x2a, 0x20, 0x75, 0x6e, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x29, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x2d, 0x3e, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x00, 0x00, 0x0a, 0x25, 0x30, 0x38, 0x58, 0x20, + 0x28, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x74, 0x29, 0x20, 0x3d, + 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x0a, 0x25, + 0x30, 0x38, 0x58, 0x20, 0x28, 0x75, 0x6e, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x73, 0x68, + 0x6f, 0x72, 0x74, 0x29, 0x20, 0x3d, 0x20, 0x25, + 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x0a, 0x25, + 0x30, 0x38, 0x58, 0x20, 0x28, 0x75, 0x6e, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x29, 0x20, 0x3d, 0x20, 0x25, 0x30, + 0x38, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, + 0xf4, 0xf7, 0xcf, 0xfd, 0x01, 0x1c, 0x02, 0xa0, + 0xfb, 0xf7, 0xfc, 0xfc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x0a, 0x49, 0x64, 0x6c, 0x65, 0x3a, + 0x20, 0x25, 0x75, 0x00, 0x00, 0x00, 0xf0, 0xb5, + 0x07, 0x1c, 0x26, 0x48, 0x0c, 0x1c, 0x00, 0x68, + 0x00, 0x25, 0x00, 0x6c, 0x06, 0x1f, 0x01, 0xe0, + 0x00, 0x2d, 0x05, 0xd1, 0x01, 0x2f, 0x03, 0xd1, + 0x22, 0xa0, 0xfb, 0xf7, 0xe3, 0xfc, 0x06, 0xe0, + 0x04, 0x2d, 0x04, 0xd1, 0x00, 0x2f, 0x02, 0xd1, + 0x1e, 0xa0, 0xfb, 0xf7, 0xdb, 0xfc, 0x31, 0x68, + 0x30, 0x1c, 0x00, 0xf0, 0xce, 0xfd, 0x00, 0x2d, + 0x05, 0xd1, 0x01, 0x2f, 0x03, 0xd1, 0x1a, 0xa0, + 0xfb, 0xf7, 0xd0, 0xfc, 0x06, 0xe0, 0x04, 0x2d, + 0x04, 0xd1, 0xed, 0x09, 0x00, 0x0c, 0x02, 0x00, + 0x2f, 0x02, 0xd1, 0x16, 0xa0, 0xfb, 0xf7, 0xc8, + 0xfc, 0x04, 0x35, 0x04, 0x36, 0x10, 0x2d, 0xd9, + 0xd3, 0x01, 0x2f, 0x0a, 0xd1, 0x0f, 0x4f, 0x38, + 0x68, 0x00, 0x6c, 0x04, 0x38, 0x00, 0xf0, 0x21, + 0xf8, 0x39, 0x68, 0x0a, 0x6c, 0x04, 0x3a, 0x0a, + 0x64, 0x04, 0xe0, 0x09, 0x48, 0x00, 0x68, 0x00, + 0x6c, 0x00, 0xf0, 0x17, 0xf8, 0x01, 0x23, 0xdc, + 0x42, 0x00, 0xd0, 0x20, 0x1c, 0x04, 0x21, 0xfc, + 0xf7, 0xbe, 0xfd, 0x00, 0x22, 0x01, 0x1c, 0x13, + 0x20, 0xfe, 0xf7, 0xd1, 0xf9, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x24, 0x69, 0x03, 0x20, 0x1b, + 0x5b, 0x37, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x1b, + 0x5b, 0x6d, 0x00, 0xf8, 0xb4, 0x41, 0x4b, 0x05, + 0x68, 0x1b, 0x68, 0x01, 0x21, 0x1e, 0x68, 0x0a, + 0x1c, 0x33, 0x08, 0x00, 0xd2, 0x00, 0x22, 0x0f, + 0x1c, 0xf3, 0x0f, 0x00, 0xd2, 0x00, 0x27, 0x0c, + 0x1c, 0xb3, 0x0f, 0x00, 0xd2, 0x00, 0x24, 0x73, + 0x0f, 0x00, 0xd2, 0x00, 0x21, 0x00, 0x23, 0x07, + 0x26, 0x76, 0x06, 0x2e, 0x40, 0x00, 0x93, 0x05, + 0x23, 0x5b, 0x06, 0x9e, 0x42, 0x62, 0xd1, 0x2e, + 0x02, 0x36, 0x0a, 0x33, 0x0e, 0x01, 0xd3, 0x31, + 0x4b, 0x1e, 0x43, 0xb3, 0x00, 0x1b, 0x18, 0x2d, + 0x0f, 0xde, 0x1d, 0x01, 0x36, 0x10, 0x2d, 0x4f, + 0xd2, 0x02, 0xa3, 0x5b, 0x5d, 0x5b, 0x00, 0x9f, + 0x44, 0x00, 0x1c, 0x08, 0x0b, 0x0e, 0x11, 0x14, + 0x17, 0x1a, 0x1d, 0x20, 0x25, 0x2a, 0x32, 0x3a, + 0x41, 0x4e, 0x4b, 0x00, 0x2f, 0x47, 0xd0, 0x42, + 0xe0, 0x00, 0x2f, 0x43, 0xd1, 0x3f, 0xe0, 0x00, + 0x2c, 0x41, 0xd0, 0x3c, 0xe0, 0x00, 0x2c, 0x3d, + 0xd1, 0x39, 0xe0, 0x00, 0x2a, 0x3b, 0xd0, 0x36, + 0xe0, 0x00, 0x2a, 0x37, 0xd1, 0x33, 0xe0, 0x00, + 0x29, 0x35, 0xd0, 0x30, 0xe0, 0xed, 0x09, 0x00, + 0x0d, 0x02, 0x00, 0x29, 0x31, 0xd1, 0x2d, 0xe0, + 0x00, 0x2c, 0x2f, 0xd0, 0x00, 0x2f, 0x2c, 0xd1, + 0x28, 0xe0, 0x00, 0x2c, 0x26, 0xd0, 0x00, 0x2f, + 0x28, 0xd0, 0x23, 0xe0, 0x00, 0x2a, 0x02, 0xd0, + 0x00, 0x29, 0x23, 0xd0, 0x1e, 0xe0, 0x00, 0x29, + 0x1f, 0xd1, 0x1b, 0xe0, 0x00, 0x2a, 0x02, 0xd0, + 0x00, 0x29, 0x1a, 0xd1, 0x16, 0xe0, 0x00, 0x29, + 0x18, 0xd0, 0x13, 0xe0, 0x00, 0x2f, 0x11, 0xd0, + 0x00, 0x2a, 0x12, 0xd1, 0x00, 0x29, 0x10, 0xd1, + 0x0c, 0xe0, 0x00, 0x2f, 0x0a, 0xd1, 0x00, 0x2a, + 0x02, 0xd0, 0x00, 0x29, 0x09, 0xd1, 0x05, 0xe0, + 0x00, 0x29, 0x07, 0xd0, 0x02, 0xe0, 0x00, 0x9b, + 0x00, 0x2b, 0x03, 0xd0, 0x30, 0x1c, 0xf8, 0xbc, + 0x70, 0x47, 0xff, 0xe7, 0x04, 0x30, 0xfa, 0xe7, + 0x24, 0x69, 0x03, 0x20, 0x00, 0x00, 0x00, 0xff, + 0xb8, 0xb5, 0xc1, 0x1d, 0x11, 0x31, 0x07, 0x1c, + 0x1b, 0xa0, 0xfb, 0xf7, 0x0c, 0xfc, 0x39, 0x6a, + 0x7b, 0x6a, 0x1a, 0xa0, 0xca, 0x18, 0xfb, 0xf7, + 0x06, 0xfc, 0xb9, 0x6a, 0x1d, 0xa0, 0xfb, 0xf7, + 0x02, 0xfc, 0xf9, 0x6a, 0x1f, 0xa0, 0xfb, 0xf7, + 0xfe, 0xfb, 0x3c, 0x6b, 0x00, 0x25, 0x00, 0x2c, + 0x0d, 0xd0, 0x23, 0x7a, 0x00, 0x2b, 0x07, 0xd0, + 0x1a, 0x1b, 0x00, 0x92, 0x22, 0x1c, 0x29, 0x1c, + 0x01, 0x35, 0x1d, 0xa0, 0xfb, 0xf7, 0xef, 0xfb, + 0x24, 0x7a, 0x00, 0x2c, 0xf1, 0xd1, 0x7f, 0x6b, + 0x00, 0x24, 0x00, 0x2f, 0x0d, 0xd0, 0x3b, 0x7a, + 0x00, 0x2b, 0x07, 0xd0, 0xda, 0x1b, 0x00, 0x92, + 0x3a, 0x1c, 0x21, 0x1c, 0x01, 0x34, 0x1d, 0xa0, + 0xfb, 0xf7, 0xdd, 0xfb, 0x3f, 0x7a, 0x00, 0x2f, + 0xf1, 0xd1, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x25, 0x73, 0x20, 0x00, 0x25, 0x30, 0x38, 0x58, + 0x20, 0x2d, 0x20, 0x25, 0x30, 0x38, 0x58, 0x20, + 0xed, 0x09, 0x00, 0x0e, 0x02, 0x28, 0x53, 0x69, + 0x7a, 0x65, 0x3a, 0x20, 0x25, 0x64, 0x29, 0x00, + 0x00, 0x28, 0x6d, 0x69, 0x6e, 0x20, 0x25, 0x64, + 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x29, 0x0a, + 0x00, 0x25, 0x64, 0x20, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x0a, 0x00, 0x5b, 0x25, 0x34, + 0x64, 0x5d, 0x20, 0x75, 0x73, 0x65, 0x64, 0x3a, + 0x20, 0x25, 0x30, 0x36, 0x58, 0x20, 0x2d, 0x20, + 0x25, 0x30, 0x36, 0x58, 0x20, 0x28, 0x25, 0x64, + 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x29, 0x0a, + 0x00, 0x5b, 0x25, 0x34, 0x64, 0x5d, 0x20, 0x66, + 0x72, 0x65, 0x65, 0x3a, 0x20, 0x25, 0x30, 0x36, + 0x58, 0x20, 0x2d, 0x20, 0x25, 0x30, 0x36, 0x58, + 0x20, 0x28, 0x25, 0x64, 0x20, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x29, 0x0a, 0x00, 0xb0, 0xb5, 0x0c, + 0x1c, 0x10, 0x4d, 0x07, 0x1c, 0xa8, 0x88, 0xe9, + 0x88, 0x20, 0x40, 0x88, 0x42, 0x18, 0xd1, 0x0e, + 0xa0, 0xfb, 0xf7, 0x87, 0xfb, 0x3a, 0x88, 0x39, + 0x1c, 0x0c, 0xa0, 0xfb, 0xf7, 0x82, 0xfb, 0xab, + 0x68, 0x00, 0x2b, 0x07, 0xd0, 0x38, 0x1c, 0x21, + 0x1c, 0x2a, 0x1c, 0xdf, 0xf7, 0xb6, 0xfc, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0x21, + 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0x0f, 0xf8, 0xf6, + 0xe7, 0x0c, 0x35, 0xdf, 0xe7, 0x24, 0x5e, 0x03, + 0x20, 0x0a, 0x00, 0x00, 0x00, 0x25, 0x30, 0x38, + 0x58, 0x3a, 0x20, 0x25, 0x30, 0x34, 0x58, 0x3a, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x09, + 0x04, 0x09, 0x0c, 0x13, 0x68, 0x02, 0x1c, 0x02, + 0xa0, 0xfb, 0xf7, 0x5b, 0xfb, 0x08, 0xbc, 0x18, + 0x47, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x69, 0x6f, 0xed, 0x09, 0x00, 0x0f, 0x02, + 0x6e, 0x20, 0x25, 0x30, 0x34, 0x78, 0x20, 0x61, + 0x74, 0x20, 0x25, 0x30, 0x38, 0x78, 0x20, 0x28, + 0x4e, 0x72, 0x3d, 0x25, 0x75, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb5, 0x09, 0x06, 0x09, 0x0e, + 0x02, 0xa0, 0xfb, 0xf7, 0x3d, 0xfb, 0x08, 0xbc, + 0x18, 0x47, 0x53, 0x57, 0x49, 0x20, 0x20, 0x23, + 0x25, 0x75, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xb5, + 0xc8, 0x10, 0x40, 0x07, 0x40, 0x0f, 0x0f, 0x1c, + 0x00, 0xf0, 0x47, 0xfd, 0x05, 0x1c, 0xb8, 0x11, + 0x40, 0x07, 0x40, 0x0f, 0x00, 0xf0, 0x41, 0xfd, + 0x04, 0x1c, 0x78, 0x07, 0x40, 0x0f, 0x00, 0xf0, + 0x3c, 0xfd, 0xb9, 0x0a, 0x01, 0xd3, 0x06, 0xa1, + 0x00, 0xe0, 0x07, 0xa1, 0x2b, 0x1c, 0x08, 0xa7, + 0x02, 0x1c, 0x38, 0x1c, 0x00, 0x94, 0xfb, 0xf7, + 0x17, 0xfb, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x41, 0x44, 0x44, 0x53, 0x00, 0x00, + 0x00, 0x00, 0x53, 0x55, 0x42, 0x53, 0x00, 0x00, + 0x00, 0x00, 0x25, 0x73, 0x20, 0x20, 0x25, 0x73, + 0x2c, 0x20, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, + 0x00, 0x00, 0x98, 0xb5, 0xc8, 0x10, 0x40, 0x07, + 0x40, 0x0f, 0x0f, 0x1c, 0x00, 0xf0, 0x15, 0xfd, + 0x04, 0x1c, 0x78, 0x07, 0x40, 0x0f, 0x00, 0xf0, + 0x10, 0xfd, 0xb9, 0x0a, 0x02, 0xd3, 0x00, 0xa1, + 0x40, 0x39, 0x01, 0xe0, 0x00, 0xa1, 0x3c, 0x39, + 0xba, 0x11, 0x52, 0x07, 0x52, 0x0f, 0x00, 0x92, + 0x02, 0x1c, 0x23, 0x1c, 0x03, 0xa7, 0x38, 0x1c, + 0xfb, 0xf7, 0xe6, 0xfa, 0x98, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x25, 0x73, 0x20, 0x20, 0x25, 0x73, + 0x2c, 0x20, 0x25, 0x73, 0x2c, 0x20, 0x23, 0x25, + 0x75, 0x00, 0x88, 0xb5, 0x08, 0x12, 0x40, 0x07, + 0x40, 0x0f, 0x0f, 0x1c, 0x00, 0xf0, 0xed, 0xfc, + 0x3a, 0x06, 0x12, 0x0e, 0xfb, 0x12, 0xed, 0x09, + 0x00, 0x10, 0x02, 0x9b, 0x07, 0x9b, 0x0f, 0x0d, + 0xa1, 0x11, 0xd0, 0x01, 0x2b, 0x11, 0xd0, 0x02, + 0x2b, 0x11, 0xd0, 0x03, 0x2b, 0x01, 0xd1, 0x00, + 0xa1, 0x94, 0x39, 0x00, 0x92, 0x02, 0x1c, 0x00, + 0xa0, 0x44, 0x38, 0x13, 0x1c, 0xfb, 0xf7, 0xbe, + 0xfa, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x05, + 0xa1, 0xf3, 0xe7, 0x05, 0xa1, 0xf1, 0xe7, 0x00, + 0xa1, 0xbc, 0x39, 0xee, 0xe7, 0x00, 0x00, 0x75, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x43, + 0x4d, 0x50, 0x00, 0x4d, 0x4f, 0x56, 0x53, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0x68, 0x02, 0x68, 0x03, + 0x60, 0x0a, 0x60, 0x70, 0x47, 0x90, 0xb5, 0x84, + 0xb0, 0xc8, 0x10, 0x40, 0x07, 0x40, 0x0f, 0x0f, + 0x1c, 0x00, 0xf0, 0xb5, 0xfc, 0x03, 0x90, 0x78, + 0x07, 0x40, 0x0f, 0x00, 0xf0, 0xb0, 0xfc, 0x02, + 0x90, 0x00, 0xa4, 0x00, 0x20, 0xb9, 0x11, 0x09, + 0x07, 0x09, 0x0f, 0x3c, 0x3c, 0x10, 0x29, 0x3f, + 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, 0x00, 0x9f, + 0x44, 0x00, 0x1c, 0x08, 0x0b, 0x0e, 0x11, 0x14, + 0x17, 0x1a, 0x1d, 0x20, 0x23, 0x26, 0x2e, 0x31, + 0x34, 0x36, 0x39, 0x2f, 0xa4, 0x02, 0x20, 0x2f, + 0xe0, 0x30, 0xa4, 0x02, 0x20, 0x2c, 0xe0, 0x30, + 0xa4, 0x01, 0x20, 0x29, 0xe0, 0x30, 0xa4, 0x01, + 0x20, 0x26, 0xe0, 0x2f, 0xa4, 0x01, 0x20, 0x23, + 0xe0, 0x2f, 0xa4, 0x02, 0x20, 0x20, 0xe0, 0x2f, + 0xa4, 0x02, 0x20, 0x1d, 0xe0, 0x30, 0xa4, 0x01, + 0x20, 0x1a, 0xe0, 0x2f, 0xa4, 0x03, 0x20, 0x17, + 0xe0, 0x2f, 0xa4, 0x04, 0x20, 0x14, 0xe0, 0x00, + 0xa4, 0x9c, 0x3c, 0x02, 0xa8, 0x03, 0xa9, 0xff, + 0xf7, 0xb4, 0xff, 0x03, 0x20, 0x0c, 0xe0, 0x2b, + 0xa4, 0x03, 0x20, 0x09, 0xe0, 0x2b, 0xa4, 0x02, + 0x20, 0x06, 0xe0, 0x2b, 0xa4, 0x04, 0xe0, 0x2c, + 0xa4, 0xed, 0x09, 0x00, 0x11, 0x02, 0x02, 0x20, + 0x01, 0xe0, 0x2d, 0xa4, 0x03, 0x20, 0x01, 0x28, + 0x0f, 0xd0, 0x02, 0x28, 0x18, 0xd0, 0x03, 0x28, + 0x1f, 0xd0, 0x04, 0x28, 0x05, 0xd1, 0x02, 0x9a, + 0x03, 0x9b, 0x21, 0x1c, 0x28, 0xa0, 0xfb, 0xf7, + 0x40, 0xfa, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x03, 0x9a, 0x01, 0xa1, 0x01, 0x92, + 0x02, 0x9a, 0xec, 0x39, 0x13, 0x1c, 0x00, 0x94, + 0x25, 0xa0, 0xfb, 0xf7, 0x32, 0xfa, 0xf0, 0xe7, + 0x03, 0x9a, 0x21, 0x1c, 0x00, 0x92, 0x02, 0x9a, + 0x26, 0x48, 0x13, 0x1c, 0xfb, 0xf7, 0x29, 0xfa, + 0xe7, 0xe7, 0x02, 0x9a, 0x03, 0x9b, 0x21, 0x1c, + 0x23, 0xa0, 0xfb, 0xf7, 0x22, 0xfa, 0xe0, 0xe7, + 0x41, 0x4e, 0x44, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x4f, 0x52, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x4c, 0x53, 0x4c, 0x00, 0x4c, 0x53, 0x52, 0x00, + 0x41, 0x53, 0x52, 0x00, 0x41, 0x44, 0x43, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x42, 0x43, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x52, 0x4f, 0x52, 0x00, + 0x54, 0x53, 0x54, 0x00, 0x52, 0x53, 0x42, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x4d, 0x4e, 0x00, + 0x4f, 0x52, 0x52, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x4d, 0x55, 0x4c, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x49, 0x43, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x4d, 0x56, 0x4e, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x25, 0x73, 0x20, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x2c, 0x20, 0x23, 0x30, 0x00, 0x00, + 0x25, 0x73, 0x20, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x20, 0x25, + 0x73, 0x00, 0x00, 0x00, 0x54, 0x0b, 0x02, 0x20, + 0x25, 0x73, 0x20, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x00, 0x00, 0x00, 0xb5, 0x49, 0x05, + 0x49, 0x0d, 0xca, 0x0a, 0xed, 0x09, 0x00, 0x12, + 0x02, 0x01, 0xd3, 0x05, 0x4b, 0x19, 0x43, 0x49, + 0x00, 0x08, 0x18, 0x01, 0x1f, 0x03, 0xa0, 0xfb, + 0xf7, 0xca, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x00, 0xf8, 0xff, 0xff, 0x42, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x25, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb5, 0x49, 0x05, 0x49, 0x0d, 0x02, + 0xa0, 0xfb, 0xf7, 0xb9, 0xf9, 0x08, 0xbc, 0x18, + 0x47, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x23, + 0x25, 0x78, 0x00, 0x00, 0x00, 0x80, 0xb5, 0x01, + 0x22, 0xd2, 0x02, 0x0a, 0x40, 0x49, 0x05, 0x49, + 0x0d, 0x00, 0x2a, 0x0c, 0x4f, 0x0c, 0xd0, 0xca, + 0x0a, 0x01, 0xd3, 0x0b, 0x4b, 0x19, 0x43, 0x09, + 0x03, 0x08, 0x18, 0x38, 0x60, 0x09, 0xa0, 0xfb, + 0xf7, 0x9e, 0xf9, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x38, 0x68, 0x40, 0x18, 0x01, 0x1f, 0x39, + 0x60, 0x08, 0xa0, 0xfb, 0xf7, 0x94, 0xf9, 0x00, + 0x20, 0x38, 0x60, 0xf2, 0xe7, 0x88, 0x69, 0x03, + 0x20, 0x00, 0xf8, 0xff, 0xff, 0x42, 0x4c, 0x20, + 0x28, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, + 0x61, 0x72, 0x74, 0x29, 0x00, 0x42, 0x4c, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x25, 0x78, 0x00, 0x00, + 0x00, 0x90, 0xb5, 0x04, 0x1c, 0x08, 0x12, 0x40, + 0x07, 0x40, 0x0f, 0x0f, 0x1c, 0x00, 0xf0, 0x90, + 0xfb, 0x3a, 0x06, 0x12, 0x0e, 0x01, 0x1c, 0x90, + 0x00, 0x63, 0x00, 0xc3, 0x18, 0x02, 0xa0, 0xfb, + 0xf7, 0x6e, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x4c, 0x44, 0x52, 0x20, 0x20, 0x20, 0x25, + 0x73, 0x2c, 0x20, 0x5b, 0x50, 0x43, 0x2c, 0x20, + 0x23, 0x25, 0x78, 0x5d, 0x20, 0x20, 0x20, 0x20, + 0x3b, 0x20, 0x23, 0x25, 0x78, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xb5, 0x48, 0x12, 0x46, 0x07, 0x76, + 0x0f, 0x88, 0x11, 0x40, 0x07, 0x40, 0x0f, 0xed, + 0x09, 0x00, 0x13, 0x02, 0x0f, 0x1c, 0x00, 0xf0, + 0x6a, 0xfb, 0x05, 0x1c, 0xf8, 0x10, 0x40, 0x07, + 0x40, 0x0f, 0x00, 0xf0, 0x64, 0xfb, 0x04, 0x1c, + 0x78, 0x07, 0x40, 0x0f, 0x00, 0xf0, 0x5f, 0xfb, + 0x10, 0xa1, 0x08, 0x2e, 0x12, 0xd2, 0x01, 0xa3, + 0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x0e, 0x03, + 0x05, 0x07, 0x0e, 0x09, 0x0b, 0x0d, 0x0c, 0xa1, + 0x08, 0xe0, 0x0d, 0xa1, 0x06, 0xe0, 0x0e, 0xa1, + 0x04, 0xe0, 0x0f, 0xa1, 0x02, 0xe0, 0x10, 0xa1, + 0x00, 0xe0, 0x11, 0xa1, 0x23, 0x1c, 0x12, 0xa7, + 0x02, 0x1c, 0x38, 0x1c, 0x00, 0x95, 0xfb, 0xf7, + 0x29, 0xf9, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x00, 0x53, 0x54, 0x52, 0x48, 0x20, 0x00, + 0x00, 0x00, 0x53, 0x54, 0x52, 0x42, 0x20, 0x00, + 0x00, 0x00, 0x4c, 0x44, 0x52, 0x53, 0x42, 0x00, + 0x00, 0x00, 0x4c, 0x44, 0x52, 0x48, 0x20, 0x00, + 0x00, 0x00, 0x4c, 0x44, 0x52, 0x42, 0x20, 0x00, + 0x00, 0x00, 0x4c, 0x44, 0x52, 0x53, 0x48, 0x00, + 0x00, 0x00, 0x25, 0x73, 0x20, 0x20, 0x20, 0x25, + 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x5d, 0x00, 0x00, 0x00, 0x80, 0xb5, + 0x08, 0x12, 0x40, 0x07, 0x40, 0x0f, 0x0f, 0x1c, + 0x00, 0xf0, 0x11, 0xfb, 0x3a, 0x06, 0x12, 0x0e, + 0x39, 0x0b, 0x07, 0xd3, 0x07, 0xa3, 0x01, 0x1c, + 0x18, 0x1c, 0xfb, 0xf7, 0xef, 0xf8, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x08, 0xa3, 0x01, 0x1c, + 0x18, 0x1c, 0xfb, 0xf7, 0xe7, 0xf8, 0xf6, 0xe7, + 0x00, 0x00, 0x41, 0x44, 0x44, 0x20, 0x20, 0x20, + 0x25, 0x73, 0x2c, 0x20, 0x53, 0x50, 0x2c, 0x20, + 0x23, 0x25, 0x78, 0x00, 0x00, 0x00, 0x41, 0x44, + 0x44, 0x20, 0x20, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x50, 0x43, 0xed, 0x09, 0x00, 0x14, 0x02, 0x2c, + 0x20, 0x23, 0x25, 0x78, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0x49, 0x06, 0x49, 0x0e, 0x02, 0xa0, 0xfb, + 0xf7, 0xcb, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x53, + 0x55, 0x42, 0x20, 0x20, 0x53, 0x50, 0x2c, 0x20, + 0x53, 0x50, 0x2c, 0x20, 0x23, 0x25, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xb5, 0x08, 0x06, 0x00, + 0x0e, 0x0f, 0x1c, 0x49, 0x0a, 0x02, 0xd3, 0x01, + 0x23, 0xdb, 0x03, 0x18, 0x43, 0x01, 0xf0, 0x79, + 0xfc, 0x39, 0x0b, 0x07, 0xd3, 0x07, 0xa2, 0x01, + 0x1c, 0x10, 0x1c, 0xfb, 0xf7, 0xad, 0xf8, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x07, 0xa2, 0x01, + 0x1c, 0x10, 0x1c, 0xfb, 0xf7, 0xa5, 0xf8, 0xf6, + 0xe7, 0x00, 0x00, 0x4c, 0x44, 0x4d, 0x49, 0x41, + 0x20, 0x53, 0x50, 0x21, 0x2c, 0x20, 0x7b, 0x25, + 0x73, 0x7d, 0x00, 0x53, 0x54, 0x4d, 0x44, 0x42, + 0x20, 0x53, 0x50, 0x21, 0x2c, 0x20, 0x7b, 0x25, + 0x73, 0x7d, 0x00, 0xb0, 0xb5, 0x0d, 0x06, 0x2d, + 0x0e, 0x08, 0x12, 0x40, 0x07, 0x40, 0x0f, 0x0f, + 0x1c, 0x00, 0xf0, 0xa3, 0xfa, 0x04, 0x1c, 0x28, + 0x1c, 0x01, 0xf0, 0x4b, 0xfc, 0x39, 0x0b, 0x08, + 0xd3, 0x21, 0x1c, 0x07, 0xa3, 0x02, 0x1c, 0x18, + 0x1c, 0xfb, 0xf7, 0x7e, 0xf8, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x21, 0x1c, 0x07, 0xa3, 0x02, + 0x1c, 0x18, 0x1c, 0xfb, 0xf7, 0x75, 0xf8, 0xf5, + 0xe7, 0x00, 0x00, 0x4c, 0x44, 0x4d, 0x49, 0x41, + 0x20, 0x25, 0x73, 0x21, 0x2c, 0x20, 0x7b, 0x25, + 0x73, 0x7d, 0x00, 0x53, 0x54, 0x4d, 0x44, 0x42, + 0x20, 0x25, 0x73, 0x21, 0x2c, 0x20, 0x7b, 0x25, + 0x73, 0x7d, 0x00, 0x90, 0xb5, 0x04, 0x1c, 0x08, + 0x12, 0x00, 0x07, 0x00, 0x0f, 0x0f, 0x1c, 0x00, + 0xf0, 0x7e, 0xf9, 0x39, 0x06, 0x09, 0x0e, 0x0a, + 0x0a, 0x02, 0xd3, 0xff, 0x23, 0xed, 0x09, 0x00, + 0x15, 0x02, 0xdb, 0x43, 0x19, 0x43, 0x49, 0x00, + 0x62, 0x18, 0x01, 0x1c, 0x03, 0xa3, 0x18, 0x1c, + 0xfb, 0xf7, 0x4d, 0xf8, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x42, 0x25, 0x73, 0x20, + 0x20, 0x25, 0x78, 0x00, 0x80, 0xb5, 0x08, 0x12, + 0x40, 0x07, 0x40, 0x0f, 0x0f, 0x1c, 0x00, 0xf0, + 0x57, 0xfa, 0x3a, 0x06, 0x12, 0x0e, 0x39, 0x0b, + 0x01, 0xd3, 0x05, 0xa1, 0x00, 0xe0, 0x05, 0xa1, + 0x13, 0x1c, 0x02, 0x1c, 0x04, 0xa0, 0xfb, 0xf7, + 0x32, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x44, 0x52, 0x00, 0x53, 0x54, 0x52, 0x00, + 0x25, 0x73, 0x20, 0x20, 0x20, 0x20, 0x25, 0x73, + 0x2c, 0x20, 0x5b, 0x53, 0x50, 0x2c, 0x20, 0x23, + 0x25, 0x78, 0x5d, 0x00, 0x80, 0xb5, 0x08, 0x12, + 0x40, 0x07, 0x40, 0x0f, 0x0f, 0x1c, 0x00, 0xf0, + 0x33, 0xfa, 0x3a, 0x06, 0x12, 0x0e, 0x39, 0x0b, + 0x02, 0xd3, 0x00, 0xa1, 0x34, 0x39, 0x01, 0xe0, + 0x00, 0xa1, 0x38, 0x39, 0x13, 0x1c, 0x02, 0x1c, + 0x02, 0xa0, 0xfb, 0xf7, 0x0c, 0xf8, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x25, 0x73, 0x20, 0x20, + 0x20, 0x20, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x50, + 0x43, 0x2c, 0x20, 0x23, 0x25, 0x78, 0x5d, 0x00, + 0x98, 0xb5, 0x48, 0x07, 0x40, 0x0f, 0x0f, 0x1c, + 0x00, 0xf0, 0x12, 0xfa, 0x04, 0x1c, 0xf8, 0x10, + 0x40, 0x07, 0x40, 0x0f, 0x00, 0xf0, 0x0c, 0xfa, + 0xb9, 0x11, 0xca, 0x06, 0xd2, 0x0e, 0x39, 0x0b, + 0x02, 0xd3, 0x00, 0xa1, 0x84, 0x39, 0x01, 0xe0, + 0x00, 0xa1, 0x88, 0x39, 0x00, 0x92, 0x22, 0x1c, + 0x03, 0x1c, 0x03, 0xa0, 0xfa, 0xf7, 0xe3, 0xff, + 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x25, 0x73, 0x20, 0x20, 0x20, 0x20, 0x25, 0x73, + 0x2c, 0x20, 0x5b, 0x25, 0x73, 0x2c, 0x20, 0x23, + 0xed, 0x09, 0x00, 0x16, 0x02, 0x25, 0x78, 0x5d, + 0x00, 0x98, 0xb5, 0x48, 0x07, 0x40, 0x0f, 0x0f, + 0x1c, 0x00, 0xf0, 0xe8, 0xf9, 0x04, 0x1c, 0xf8, + 0x10, 0x40, 0x07, 0x40, 0x0f, 0x00, 0xf0, 0xe2, + 0xf9, 0xb9, 0x11, 0xca, 0x06, 0xd2, 0x0e, 0xf9, + 0x12, 0x89, 0x07, 0x89, 0x0f, 0x05, 0xd0, 0x01, + 0x29, 0x05, 0xd0, 0x02, 0x29, 0x05, 0xd1, 0x08, + 0xa3, 0x04, 0xe0, 0x08, 0xa3, 0x02, 0xe0, 0x08, + 0xa3, 0x00, 0xe0, 0x08, 0xa3, 0x00, 0x92, 0x21, + 0x1c, 0x02, 0x1c, 0x08, 0xa0, 0xfa, 0xf7, 0xb1, + 0xff, 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x41, 0x53, 0x52, 0x00, 0x4c, 0x53, 0x4c, + 0x00, 0x4c, 0x53, 0x52, 0x00, 0x75, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x4d, 0x4f, 0x56, + 0x53, 0x20, 0x20, 0x20, 0x20, 0x25, 0x73, 0x2c, + 0x20, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x20, + 0x23, 0x25, 0x78, 0x00, 0x00, 0xf8, 0xb5, 0x40, + 0x20, 0x08, 0x40, 0x80, 0x25, 0x0d, 0x40, 0x4a, + 0x07, 0x52, 0x0f, 0x08, 0x26, 0x0f, 0x1c, 0x31, + 0x1c, 0x00, 0x28, 0x00, 0xd1, 0x00, 0x21, 0x0a, + 0x43, 0x10, 0x1c, 0x00, 0xf0, 0x9f, 0xf9, 0x04, + 0x1c, 0xf8, 0x10, 0x40, 0x07, 0x40, 0x0f, 0x00, + 0x2d, 0x00, 0xd1, 0x00, 0x26, 0x30, 0x43, 0x00, + 0xf0, 0x95, 0xf9, 0x39, 0x12, 0x89, 0x07, 0x89, + 0x0f, 0x0b, 0xd0, 0x01, 0x29, 0x0b, 0xd0, 0x03, + 0x29, 0x10, 0xd1, 0x02, 0x1c, 0x0d, 0xa0, 0x0c, + 0xa1, 0xfa, 0xf7, 0x6f, 0xff, 0xf8, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x0c, 0xa1, 0x08, 0xe0, 0x22, + 0x1c, 0x03, 0x1c, 0x0c, 0xa0, 0x0a, 0xa1, 0xfa, + 0xf7, 0x64, 0xff, 0xf3, 0xe7, 0x00, 0xa1, 0x8c, + 0x39, 0x00, 0x90, 0x22, 0x1c, 0x23, 0x1c, 0x0a, + 0xa0, 0xfa, 0xf7, 0x5b, 0xff, 0xea, 0xe7, 0x00, + 0x00, 0x42, 0x58, 0xed, 0x09, 0x00, 0x17, 0x02, + 0x00, 0x00, 0x25, 0x73, 0x20, 0x20, 0x20, 0x25, + 0x73, 0x00, 0x41, 0x44, 0x44, 0x00, 0x43, 0x4d, + 0x50, 0x00, 0x25, 0x73, 0x20, 0x20, 0x20, 0x25, + 0x73, 0x2c, 0x20, 0x25, 0x73, 0x00, 0x25, 0x73, + 0x20, 0x20, 0x20, 0x25, 0x73, 0x2c, 0x20, 0x25, + 0x73, 0x2c, 0x20, 0x25, 0x73, 0x00, 0x4d, 0x55, + 0x4c, 0x00, 0x4d, 0x52, 0x53, 0x00, 0x4d, 0x53, + 0x52, 0x00, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x00, + 0x00, 0x00, 0x4c, 0x44, 0x52, 0x00, 0x4c, 0x44, + 0x52, 0x00, 0x4d, 0x53, 0x52, 0x00, 0x4c, 0x44, + 0x52, 0x00, 0x42, 0x00, 0x00, 0x00, 0x53, 0x57, + 0x49, 0x00, 0x65, 0x72, 0x72, 0x00, 0x80, 0xb5, + 0x01, 0x1c, 0x07, 0x1c, 0x06, 0xa0, 0xfa, 0xf7, + 0x23, 0xff, 0x06, 0xa0, 0xfa, 0xf7, 0x20, 0xff, + 0x39, 0x68, 0x07, 0xa0, 0xfa, 0xf7, 0x1c, 0xff, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0a, 0x25, + 0x30, 0x38, 0x58, 0x09, 0x00, 0x00, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x20, 0x20, 0x44, 0x43, 0x44, 0x20, + 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0xf0, 0xb5, + 0x0e, 0x0f, 0x0d, 0x01, 0x2d, 0x09, 0x0d, 0x4c, + 0x07, 0x1c, 0xa0, 0x68, 0xe1, 0x68, 0x28, 0x40, + 0x88, 0x42, 0x11, 0xd1, 0x0b, 0xa0, 0xfa, 0xf7, + 0xfb, 0xfe, 0x3a, 0x68, 0x39, 0x1c, 0x09, 0xa0, + 0xfa, 0xf7, 0xf6, 0xfe, 0x38, 0x1c, 0x29, 0x1c, + 0x22, 0x1c, 0x33, 0x1c, 0x27, 0x69, 0xdf, 0xf7, + 0x2f, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x14, 0x34, 0xe6, 0xe7, 0x00, 0x00, 0x38, 0x5f, + 0x03, 0x20, 0x0a, 0x00, 0x00, 0x00, 0x25, 0x30, + 0x38, 0x58, 0x3a, 0x20, 0x25, 0x30, 0x38, 0x58, + 0x3a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x90, 0xb5, + 0x07, 0x1c, 0x10, 0x28, 0x2e, 0xd2, 0xed, 0x09, + 0x00, 0x18, 0x02, 0x01, 0xa3, 0x1b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x07, 0x0b, 0x0d, 0x0f, 0x11, + 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f, 0x21, + 0x23, 0x25, 0x28, 0x1a, 0xa0, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x19, 0xa0, 0xfa, 0xe7, 0x19, + 0xa0, 0xf8, 0xe7, 0x19, 0xa0, 0xf6, 0xe7, 0x19, + 0xa0, 0xf4, 0xe7, 0x19, 0xa0, 0xf2, 0xe7, 0x19, + 0xa0, 0xf0, 0xe7, 0x19, 0xa0, 0xee, 0xe7, 0x19, + 0xa0, 0xec, 0xe7, 0x19, 0xa0, 0xea, 0xe7, 0x19, + 0xa0, 0xe8, 0xe7, 0x19, 0xa0, 0xe6, 0xe7, 0x19, + 0xa0, 0xe4, 0xe7, 0x19, 0xa0, 0xe2, 0xe7, 0x00, + 0xa0, 0x64, 0x38, 0xdf, 0xe7, 0x18, 0xa0, 0xdd, + 0xe7, 0x19, 0xa1, 0x0e, 0xc9, 0x17, 0x4c, 0x20, + 0x1c, 0x0e, 0xc0, 0x20, 0x1c, 0x04, 0xf0, 0x49, + 0xfb, 0x01, 0x19, 0x10, 0x22, 0x38, 0x1c, 0x04, + 0xf0, 0xe8, 0xfa, 0x20, 0x1c, 0x15, 0xa1, 0x04, + 0xf0, 0x2e, 0xfc, 0x20, 0x1c, 0xca, 0xe7, 0x45, + 0x51, 0x00, 0x00, 0x4e, 0x45, 0x00, 0x00, 0x48, + 0x53, 0x00, 0x00, 0x4c, 0x4f, 0x00, 0x00, 0x4d, + 0x49, 0x00, 0x00, 0x50, 0x4c, 0x00, 0x00, 0x56, + 0x53, 0x00, 0x00, 0x56, 0x43, 0x00, 0x00, 0x48, + 0x49, 0x00, 0x00, 0x4c, 0x53, 0x00, 0x00, 0x47, + 0x45, 0x00, 0x00, 0x4c, 0x54, 0x00, 0x00, 0x47, + 0x54, 0x00, 0x00, 0x4c, 0x45, 0x00, 0x00, 0x4e, + 0x56, 0x00, 0x00, 0xfc, 0xc2, 0x03, 0x20, 0x27, + 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x00, 0x20, 0x75, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x27, 0x00, 0x00, 0x00, 0x90, + 0xb5, 0x07, 0x1c, 0x03, 0x20, 0x01, 0x24, 0x02, + 0x22, 0x10, 0x2f, 0x3e, 0xd2, 0x02, 0xa3, 0xdb, + 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x08, + 0x0d, 0x10, 0x13, 0x16, 0x19, 0x1c, 0x1f, 0x22, + 0x25, 0xed, 0x09, 0x00, 0x19, 0x02, 0x28, 0x2b, + 0x2e, 0x31, 0x34, 0x37, 0x08, 0x60, 0x23, 0xa0, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x60, + 0x21, 0xa0, 0xf9, 0xe7, 0x08, 0x60, 0x21, 0xa0, + 0xf6, 0xe7, 0x08, 0x60, 0x20, 0xa0, 0xf3, 0xe7, + 0x08, 0x60, 0x20, 0xa0, 0xf0, 0xe7, 0x08, 0x60, + 0x1f, 0xa0, 0xed, 0xe7, 0x08, 0x60, 0x1f, 0xa0, + 0xea, 0xe7, 0x08, 0x60, 0x1e, 0xa0, 0xe7, 0xe7, + 0x0a, 0x60, 0x1e, 0xa0, 0xe4, 0xe7, 0x0a, 0x60, + 0x1d, 0xa0, 0xe1, 0xe7, 0x0a, 0x60, 0x1d, 0xa0, + 0xde, 0xe7, 0x0a, 0x60, 0x1c, 0xa0, 0xdb, 0xe7, + 0x08, 0x60, 0x1c, 0xa0, 0xd8, 0xe7, 0x0c, 0x60, + 0x1b, 0xa0, 0xd5, 0xe7, 0x08, 0x60, 0x1b, 0xa0, + 0xd2, 0xe7, 0x0c, 0x60, 0x1a, 0xa0, 0xcf, 0xe7, + 0x1a, 0x4c, 0x1b, 0xa1, 0x20, 0x1c, 0x09, 0x22, + 0xde, 0xf7, 0x7a, 0xff, 0x20, 0x1c, 0x04, 0xf0, + 0xc3, 0xfa, 0x01, 0x19, 0x10, 0x22, 0x38, 0x1c, + 0x04, 0xf0, 0x62, 0xfa, 0x20, 0x1c, 0x00, 0xa1, + 0xb8, 0x39, 0x04, 0xf0, 0xa7, 0xfb, 0x20, 0x1c, + 0xba, 0xe7, 0x00, 0x00, 0x41, 0x4e, 0x44, 0x00, + 0x45, 0x4f, 0x52, 0x00, 0x53, 0x55, 0x42, 0x00, + 0x52, 0x53, 0x42, 0x00, 0x41, 0x44, 0x44, 0x00, + 0x41, 0x44, 0x43, 0x00, 0x53, 0x42, 0x43, 0x00, + 0x52, 0x53, 0x43, 0x00, 0x54, 0x53, 0x54, 0x00, + 0x54, 0x45, 0x51, 0x00, 0x43, 0x4d, 0x50, 0x00, + 0x43, 0x4d, 0x4e, 0x00, 0x4f, 0x52, 0x52, 0x00, + 0x4d, 0x4f, 0x56, 0x00, 0x42, 0x49, 0x43, 0x00, + 0x4d, 0x56, 0x4e, 0x00, 0x24, 0xc3, 0x03, 0x20, + 0x27, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, + 0x10, 0x28, 0x2d, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, + 0x5b, 0x00, 0x9f, 0x44, 0x07, 0x0b, 0x0d, 0x0f, + 0x11, 0x13, 0x15, 0x17, 0xed, 0x09, 0x00, 0x1a, + 0x02, 0x19, 0x1b, 0x1d, 0x1f, 0x21, 0x23, 0x25, + 0x27, 0x1a, 0xa0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x19, 0xa0, 0xfa, 0xe7, 0x19, 0xa0, 0xf8, + 0xe7, 0x19, 0xa0, 0xf6, 0xe7, 0x19, 0xa0, 0xf4, + 0xe7, 0x19, 0xa0, 0xf2, 0xe7, 0x19, 0xa0, 0xf0, + 0xe7, 0x19, 0xa0, 0xee, 0xe7, 0x19, 0xa0, 0xec, + 0xe7, 0x19, 0xa0, 0xea, 0xe7, 0x19, 0xa0, 0xe8, + 0xe7, 0x19, 0xa0, 0xe6, 0xe7, 0x19, 0xa0, 0xe4, + 0xe7, 0x19, 0xa0, 0xe2, 0xe7, 0x19, 0xa0, 0xe0, + 0xe7, 0x19, 0xa0, 0xde, 0xe7, 0x19, 0x4c, 0x1a, + 0xa1, 0x20, 0x1c, 0x0b, 0x22, 0xde, 0xf7, 0x0a, + 0xff, 0x20, 0x1c, 0x04, 0xf0, 0x53, 0xfa, 0x01, + 0x19, 0x10, 0x22, 0x38, 0x1c, 0x04, 0xf0, 0xf2, + 0xf9, 0x20, 0x1c, 0x16, 0x49, 0x04, 0xf0, 0x38, + 0xfb, 0x20, 0x1c, 0xca, 0xe7, 0x61, 0x31, 0x00, + 0x00, 0x61, 0x32, 0x00, 0x00, 0x61, 0x33, 0x00, + 0x00, 0x61, 0x34, 0x00, 0x00, 0x76, 0x31, 0x00, + 0x00, 0x76, 0x32, 0x00, 0x00, 0x76, 0x33, 0x00, + 0x00, 0x76, 0x34, 0x00, 0x00, 0x76, 0x35, 0x00, + 0x00, 0x76, 0x36, 0x00, 0x00, 0x76, 0x37, 0x00, + 0x00, 0x76, 0x38, 0x00, 0x00, 0x69, 0x70, 0x00, + 0x00, 0x73, 0x70, 0x00, 0x00, 0x6c, 0x72, 0x00, + 0x00, 0x70, 0x63, 0x00, 0x00, 0x4c, 0xc3, 0x03, + 0x20, 0x27, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x00, 0x00, 0x88, 0x14, 0x02, + 0x20, 0x90, 0xb5, 0x07, 0x1c, 0x10, 0x28, 0x2d, + 0xd2, 0x01, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, + 0x44, 0x07, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, + 0x17, 0x19, 0x1b, 0x1d, 0x1f, 0x21, 0x23, 0x25, + 0x27, 0x1a, 0xa0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x1a, 0xa0, 0xfa, 0xe7, 0x1a, 0xa0, 0xf8, + 0xe7, 0x1a, 0xa0, 0xf6, 0xe7, 0x1a, 0xa0, 0xed, + 0x09, 0x00, 0x1b, 0x02, 0xf4, 0xe7, 0x1a, 0xa0, + 0xf2, 0xe7, 0x1a, 0xa0, 0xf0, 0xe7, 0x1a, 0xa0, + 0xee, 0xe7, 0x1b, 0xa0, 0xec, 0xe7, 0x1b, 0xa0, + 0xea, 0xe7, 0x1b, 0xa0, 0xe8, 0xe7, 0x1b, 0xa0, + 0xe6, 0xe7, 0x1c, 0xa0, 0xe4, 0xe7, 0x1c, 0xa0, + 0xe2, 0xe7, 0x1d, 0xa0, 0xe0, 0xe7, 0x1e, 0xa0, + 0xde, 0xe7, 0x1f, 0x4c, 0x20, 0xa1, 0x20, 0x1c, + 0x07, 0x22, 0xde, 0xf7, 0x9a, 0xfe, 0x20, 0x1c, + 0x04, 0xf0, 0xe3, 0xf9, 0x01, 0x19, 0x10, 0x22, + 0x38, 0x1c, 0x04, 0xf0, 0x82, 0xf9, 0x20, 0x1c, + 0x1b, 0x49, 0x04, 0xf0, 0xc8, 0xfa, 0x20, 0x1c, + 0xca, 0xe7, 0x5f, 0x6e, 0x6f, 0x6e, 0x00, 0x00, + 0x00, 0x00, 0x5f, 0x63, 0x00, 0x00, 0x5f, 0x78, + 0x00, 0x00, 0x5f, 0x78, 0x63, 0x00, 0x5f, 0x73, + 0x00, 0x00, 0x5f, 0x73, 0x63, 0x00, 0x5f, 0x73, + 0x78, 0x00, 0x5f, 0x73, 0x78, 0x63, 0x00, 0x00, + 0x00, 0x00, 0x5f, 0x66, 0x00, 0x00, 0x5f, 0x66, + 0x63, 0x00, 0x5f, 0x66, 0x78, 0x00, 0x5f, 0x66, + 0x78, 0x63, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x66, + 0x73, 0x00, 0x5f, 0x66, 0x73, 0x63, 0x00, 0x00, + 0x00, 0x00, 0x5f, 0x66, 0x73, 0x78, 0x00, 0x00, + 0x00, 0x00, 0x5f, 0x66, 0x73, 0x78, 0x63, 0x00, + 0x00, 0x00, 0x74, 0xc3, 0x03, 0x20, 0x27, 0x4d, + 0x61, 0x73, 0x6b, 0x20, 0x00, 0x00, 0x88, 0x14, + 0x02, 0x20, 0xb8, 0xb5, 0x04, 0x1c, 0x18, 0x1c, + 0x15, 0x1c, 0x0f, 0x1c, 0xff, 0xf7, 0x19, 0xfe, + 0x00, 0x90, 0x21, 0x1c, 0x3a, 0x1c, 0x2b, 0x68, + 0x03, 0xa0, 0xfa, 0xf7, 0xef, 0xfc, 0xb8, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x25, 0x30, + 0x38, 0x58, 0x20, 0x25, 0x30, 0x38, 0x58, 0x3a, + 0x20, 0x4e, 0x72, 0x3a, 0x25, 0x64, 0x20, 0x43, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x25, 0xed, 0x09, 0x00, 0x1c, 0x02, 0x73, + 0x00, 0x00, 0x00, 0xb8, 0xb5, 0x0c, 0x1c, 0x15, + 0x1c, 0x22, 0x02, 0x12, 0x0a, 0x92, 0x00, 0x19, + 0x1c, 0x93, 0x0e, 0x01, 0xd3, 0x0b, 0x4b, 0x1a, + 0x43, 0x80, 0x18, 0xc7, 0x1d, 0x01, 0x37, 0x08, + 0x1c, 0xff, 0xf7, 0xed, 0xfd, 0x00, 0x97, 0x61, + 0x0e, 0x01, 0xd3, 0x06, 0xa2, 0x01, 0xe0, 0x00, + 0xa2, 0xd8, 0x3a, 0x03, 0x1c, 0x05, 0xa0, 0x69, + 0x68, 0xfa, 0xf7, 0xbe, 0xfc, 0xb8, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xfc, 0x4c, + 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, + 0x25, 0x73, 0x09, 0x30, 0x78, 0x25, 0x30, 0x38, + 0x58, 0x00, 0x00, 0xf0, 0xb5, 0x8b, 0xb0, 0x1d, + 0x1c, 0x0f, 0x1c, 0x48, 0x0d, 0x00, 0x07, 0x00, + 0x0f, 0x0a, 0xa9, 0x48, 0xa4, 0xff, 0xf7, 0x39, + 0xfe, 0x06, 0x1c, 0x28, 0x1c, 0xff, 0xf7, 0xc3, + 0xfd, 0x09, 0x90, 0x78, 0x0d, 0x01, 0xd3, 0x45, + 0xa0, 0x01, 0xe0, 0x00, 0xa0, 0xf8, 0x38, 0x08, + 0x90, 0x38, 0x0b, 0x00, 0x07, 0x00, 0x0f, 0xff, + 0xf7, 0xac, 0xfe, 0x07, 0x90, 0x38, 0x0c, 0x00, + 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xa6, 0xfe, 0x06, + 0x90, 0x38, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xa1, + 0xfe, 0x05, 0x90, 0xf8, 0x09, 0xc5, 0x06, 0xed, + 0x0e, 0x78, 0x09, 0x80, 0x07, 0x80, 0x0f, 0x09, + 0xd0, 0x01, 0x28, 0x09, 0xd0, 0x02, 0x28, 0x09, + 0xd0, 0x03, 0x28, 0x0a, 0xd1, 0x00, 0x2d, 0x07, + 0xd1, 0x34, 0xa4, 0x06, 0xe0, 0x34, 0xa4, 0x04, + 0xe0, 0x34, 0xa4, 0x02, 0xe0, 0x34, 0xa4, 0x00, + 0xe0, 0x34, 0xa4, 0x0a, 0x98, 0x03, 0x28, 0x11, + 0xd1, 0x07, 0x99, 0x05, 0x98, 0x06, 0x9a, 0x00, + 0x91, 0x02, 0x90, 0x01, 0x92, 0x09, 0x9a, 0x2f, + 0xa0, 0x08, 0x9b, 0x31, 0x1c, 0x04, 0x95, 0x03, + 0x94, 0xfa, 0xf7, 0x5e, 0xfc, 0xed, 0x09, 0x00, + 0x1d, 0x02, 0x0b, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x02, 0x28, 0x0c, 0xd1, 0x05, 0x98, + 0x06, 0x9a, 0x01, 0x90, 0x00, 0x92, 0x08, 0x9b, + 0x09, 0x9a, 0x2d, 0xa0, 0x03, 0x95, 0x02, 0x94, + 0x31, 0x1c, 0xfa, 0xf7, 0x4c, 0xfc, 0xec, 0xe7, + 0x01, 0x28, 0x32, 0xd1, 0x08, 0x98, 0x00, 0x23, + 0xc0, 0x56, 0x00, 0x28, 0x13, 0xd1, 0x07, 0x98, + 0x05, 0x99, 0x13, 0xf0, 0x93, 0xff, 0x00, 0x28, + 0x0d, 0xd1, 0x30, 0x1c, 0x28, 0xa1, 0x13, 0xf0, + 0x8d, 0xff, 0x00, 0x28, 0x07, 0xd1, 0x00, 0x2d, + 0x12, 0xd1, 0x09, 0x9a, 0x25, 0xa1, 0x26, 0xa0, + 0xfa, 0xf7, 0x31, 0xfc, 0x18, 0xe0, 0x00, 0x2d, + 0x0a, 0xd1, 0x07, 0x99, 0x05, 0x9a, 0x00, 0x91, + 0x01, 0x92, 0x09, 0x9a, 0x08, 0x9b, 0x31, 0x1c, + 0x21, 0xa0, 0xfa, 0xf7, 0x24, 0xfc, 0x0b, 0xe0, + 0x05, 0x98, 0x07, 0x9a, 0x01, 0x90, 0x00, 0x92, + 0x08, 0x9b, 0x09, 0x9a, 0x12, 0xa0, 0x03, 0x95, + 0x02, 0x94, 0x31, 0x1c, 0xfa, 0xf7, 0x17, 0xfc, + 0xb7, 0xe7, 0xb6, 0xe7, 0x75, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x00, 0x53, 0x00, 0x00, 0x00, + 0x52, 0x52, 0x58, 0x00, 0x4c, 0x53, 0x4c, 0x00, + 0x4c, 0x53, 0x52, 0x00, 0x41, 0x53, 0x52, 0x00, + 0x52, 0x4f, 0x52, 0x00, 0x20, 0x25, 0x73, 0x25, + 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x20, 0x25, + 0x73, 0x20, 0x23, 0x30, 0x78, 0x25, 0x58, 0x00, + 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x09, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x20, 0x25, + 0x73, 0x20, 0x23, 0x30, 0x78, 0x25, 0x58, 0x00, + 0x4d, 0x4f, 0x56, 0x00, 0x4e, 0x4f, 0x50, 0x00, + 0x20, 0x25, 0x73, 0x25, 0x73, 0x00, 0x00, 0x00, + 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x09, + 0xed, 0x09, 0x00, 0x1e, 0x02, 0x25, 0x73, 0x2c, + 0x20, 0x25, 0x73, 0x00, 0x00, 0xf0, 0xb5, 0x89, + 0xb0, 0x48, 0x0d, 0x00, 0x07, 0x00, 0x0f, 0x0f, + 0x1c, 0x08, 0xa9, 0x1c, 0x1c, 0xff, 0xf7, 0x66, + 0xfd, 0x06, 0x1c, 0x20, 0x1c, 0xff, 0xf7, 0xf0, + 0xfc, 0x04, 0x1c, 0x78, 0x0d, 0x02, 0xd3, 0x00, + 0xa5, 0x90, 0x3d, 0x00, 0xe0, 0x2f, 0xa5, 0x38, + 0x0b, 0x00, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xda, + 0xfd, 0x07, 0x90, 0x38, 0x0c, 0x00, 0x07, 0x00, + 0x0f, 0xff, 0xf7, 0xd4, 0xfd, 0x06, 0x90, 0x38, + 0x0a, 0x00, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xce, + 0xfd, 0x05, 0x90, 0x38, 0x07, 0x00, 0x0f, 0xff, + 0xf7, 0xc9, 0xfd, 0x00, 0xa1, 0x7a, 0x09, 0xcc, + 0x39, 0x92, 0x07, 0x92, 0x0f, 0x1c, 0xd0, 0x01, + 0x2a, 0x1c, 0xd0, 0x02, 0x2a, 0x1c, 0xd0, 0x03, + 0x2a, 0x01, 0xd1, 0x00, 0xa1, 0xc8, 0x39, 0x08, + 0x9a, 0x03, 0x2a, 0x17, 0xd1, 0x05, 0x9a, 0x03, + 0x91, 0x04, 0x92, 0x06, 0x9a, 0x07, 0x99, 0x01, + 0x92, 0x00, 0x91, 0x31, 0x1c, 0x22, 0x1c, 0x02, + 0x90, 0x17, 0xa0, 0x2b, 0x1c, 0xfa, 0xf7, 0x91, + 0xfb, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x1a, 0xa1, 0xe8, 0xe7, 0x1a, 0xa1, 0xe6, + 0xe7, 0x1a, 0xa1, 0xe4, 0xe7, 0x02, 0x2a, 0x0c, + 0xd1, 0x05, 0x9a, 0x02, 0x91, 0x03, 0x92, 0x06, + 0x9a, 0x31, 0x1c, 0x00, 0x92, 0x22, 0x1c, 0x01, + 0x90, 0x15, 0xa0, 0x2b, 0x1c, 0xfa, 0xf7, 0x79, + 0xfb, 0xe6, 0xe7, 0x01, 0x2a, 0x0c, 0xd1, 0x05, + 0x9a, 0x02, 0x91, 0x03, 0x92, 0x07, 0x9a, 0x31, + 0x1c, 0x00, 0x92, 0x22, 0x1c, 0x01, 0x90, 0x0e, + 0xa0, 0x2b, 0x1c, 0xfa, 0xf7, 0x6a, 0xfb, 0xd7, + 0xe7, 0xd6, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0xed, 0x09, 0x00, 0x1f, 0x02, + 0x2c, 0x20, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, + 0x20, 0x25, 0x73, 0x20, 0x25, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x4c, 0x53, 0x4c, 0x00, 0x4c, 0x53, + 0x52, 0x00, 0x41, 0x53, 0x52, 0x00, 0x20, 0x25, + 0x73, 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, + 0x2c, 0x20, 0x25, 0x73, 0x20, 0x25, 0x73, 0x20, + 0x25, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, + 0x08, 0xd0, 0x42, 0x08, 0x03, 0xd3, 0x03, 0x4b, + 0x40, 0x08, 0x18, 0x43, 0x00, 0xe0, 0x40, 0x08, + 0x01, 0x39, 0xf6, 0xd1, 0x70, 0x47, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xb5, 0x87, 0xb0, 0x48, 0x0d, + 0x00, 0x07, 0x00, 0x0f, 0x0f, 0x1c, 0x06, 0xa9, + 0x1c, 0x1c, 0xff, 0xf7, 0xc2, 0xfc, 0x06, 0x1c, + 0x20, 0x1c, 0xff, 0xf7, 0x4c, 0xfc, 0x04, 0x1c, + 0x78, 0x0d, 0x01, 0xd3, 0x2f, 0xa3, 0x01, 0xe0, + 0x00, 0xa3, 0x88, 0x3b, 0x38, 0x0b, 0x00, 0x07, + 0x00, 0x0f, 0x05, 0x93, 0xff, 0xf7, 0x35, 0xfd, + 0x04, 0x90, 0x38, 0x0c, 0x00, 0x07, 0x00, 0x0f, + 0xff, 0xf7, 0x2f, 0xfd, 0x3d, 0x06, 0x2d, 0x0e, + 0x39, 0x0a, 0x09, 0x07, 0x03, 0x90, 0x06, 0x98, + 0x09, 0x0f, 0x4f, 0x00, 0x03, 0x28, 0x1f, 0xd1, + 0x28, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xc3, 0xff, + 0x02, 0x1c, 0x03, 0x99, 0x04, 0x98, 0x01, 0x91, + 0x31, 0x1c, 0x02, 0x92, 0x00, 0x90, 0x1d, 0xa0, + 0x22, 0x1c, 0x05, 0x9b, 0xfa, 0xf7, 0xfc, 0xfa, + 0x03, 0x98, 0x00, 0x23, 0xc0, 0x56, 0x70, 0x28, + 0x0a, 0xd1, 0x28, 0x1c, 0x39, 0x1c, 0xff, 0xf7, + 0xae, 0xff, 0x07, 0x99, 0x40, 0x18, 0xc1, 0x1d, + 0x01, 0x31, 0x1a, 0xa0, 0xfa, 0xf7, 0xec, 0xfa, + 0x06, 0x98, 0x02, 0x28, 0x0c, 0xd1, 0x28, 0x1c, + 0x39, 0x1c, 0xff, 0xf7, 0xa0, 0xff, 0x03, 0x99, + 0x01, 0x90, 0x00, 0x91, 0x31, 0x1c, 0xed, 0x09, + 0x00, 0x20, 0x02, 0x22, 0x1c, 0x16, 0xa0, 0x05, + 0x9b, 0xfa, 0xf7, 0xdc, 0xfa, 0x06, 0x98, 0x01, + 0x28, 0x0c, 0xd1, 0x28, 0x1c, 0x39, 0x1c, 0xff, + 0xf7, 0x90, 0xff, 0x04, 0x99, 0x01, 0x90, 0x00, + 0x91, 0x31, 0x1c, 0x22, 0x1c, 0x0e, 0xa0, 0x05, + 0x9b, 0xfa, 0xf7, 0xcc, 0xfa, 0x0b, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x53, + 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, + 0x25, 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, 0x25, + 0x73, 0x2c, 0x20, 0x23, 0x30, 0x78, 0x25, 0x58, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x3b, 0x20, 0x23, + 0x30, 0x78, 0x25, 0x58, 0x00, 0x00, 0x00, 0x20, + 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, + 0x73, 0x2c, 0x20, 0x23, 0x30, 0x78, 0x25, 0x58, + 0x00, 0x00, 0x00, 0xff, 0xb5, 0x82, 0xb0, 0x18, + 0x1c, 0x0f, 0x1c, 0xff, 0xf7, 0xc6, 0xfb, 0x04, + 0x1c, 0xf8, 0x0d, 0x02, 0xd3, 0x00, 0xa3, 0x50, + 0x3b, 0x00, 0xe0, 0x0c, 0xa3, 0x38, 0x07, 0x00, + 0x0f, 0x1e, 0x1c, 0xff, 0xf7, 0xb0, 0xfc, 0x05, + 0x1c, 0x38, 0x0c, 0x00, 0x07, 0x00, 0x0f, 0xff, + 0xf7, 0x1a, 0xfd, 0x00, 0x90, 0x04, 0x9a, 0x01, + 0x95, 0x51, 0x68, 0x22, 0x1c, 0x33, 0x1c, 0x04, + 0xa0, 0xfa, 0xf7, 0x88, 0xfa, 0x06, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x43, + 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x50, 0x53, 0x52, 0x25, 0x73, + 0x2c, 0x20, 0x25, 0x73, 0x00, 0x00, 0x00, 0xff, + 0xb5, 0x82, 0xb0, 0x18, 0x1c, 0x0f, 0x1c, 0xff, + 0xf7, 0x94, 0xfb, 0x04, 0x1c, 0xf8, 0x0d, 0x02, + 0xd3, 0x00, 0xa3, 0xb4, 0x3b, 0x01, 0xe0, 0x00, + 0xa3, 0x34, 0x3b, 0x38, 0x0c, 0x00, 0x07, 0x00, + 0x0f, 0x1e, 0x1c, 0xff, 0xf7, 0xec, 0xfc, 0x05, + 0x1c, 0xed, 0x09, 0x00, 0x21, 0x02, 0x38, 0x0a, + 0x00, 0x07, 0x00, 0x0f, 0x3a, 0x06, 0x12, 0x0e, + 0x41, 0x00, 0x10, 0x1c, 0xff, 0xf7, 0x14, 0xff, + 0x01, 0x90, 0x04, 0x9a, 0x00, 0x95, 0x51, 0x68, + 0x22, 0x1c, 0x33, 0x1c, 0x03, 0xa0, 0xfa, 0xf7, + 0x50, 0xfa, 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, + 0x73, 0x09, 0x25, 0x73, 0x50, 0x53, 0x52, 0x25, + 0x73, 0x2c, 0x20, 0x23, 0x30, 0x78, 0x25, 0x58, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb5, 0x18, 0x1c, + 0x0c, 0x1c, 0x15, 0x1c, 0xff, 0xf7, 0x5c, 0xfb, + 0x07, 0x1c, 0xe0, 0x0d, 0x01, 0xd3, 0x0a, 0xa2, + 0x01, 0xe0, 0x00, 0xa2, 0xa0, 0x3a, 0x20, 0x0b, + 0x00, 0x07, 0x00, 0x0f, 0x16, 0x1c, 0xff, 0xf7, + 0x45, 0xfc, 0x3a, 0x1c, 0x03, 0x1c, 0x00, 0x96, + 0x69, 0x68, 0x04, 0xa0, 0xfa, 0xf7, 0x25, 0xfa, + 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x53, 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, + 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, + 0x50, 0x53, 0x52, 0x00, 0xff, 0xb5, 0x8a, 0xb0, + 0x18, 0x1c, 0x0c, 0x1c, 0xff, 0xf7, 0x34, 0xfb, + 0x09, 0x90, 0x01, 0x20, 0x01, 0x1c, 0x62, 0x0e, + 0x00, 0xd2, 0x00, 0x21, 0x08, 0x91, 0x06, 0x1c, + 0x21, 0x0e, 0x00, 0xd2, 0x00, 0x26, 0x01, 0x1c, + 0xe2, 0x0d, 0x00, 0xd2, 0x00, 0x21, 0x07, 0x91, + 0x01, 0x1c, 0xa2, 0x0d, 0x00, 0xd2, 0x00, 0x21, + 0x06, 0x91, 0x61, 0x0d, 0x00, 0xd2, 0x00, 0x20, + 0x05, 0x90, 0x20, 0x0b, 0x00, 0x07, 0x00, 0x0f, + 0xff, 0xf7, 0x0c, 0xfc, 0x04, 0x90, 0x20, 0x0c, + 0x00, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0x06, 0xfc, + 0x27, 0x05, 0x3f, 0x0d, 0x05, 0x1c, 0x08, 0x98, + 0x01, 0x28, 0x5a, 0xd1, 0x21, 0x05, 0x09, 0x0d, + 0x06, 0x98, 0x4c, 0x42, 0xed, 0x09, 0x00, 0x22, + 0x02, 0x00, 0x28, 0x29, 0xd1, 0x3a, 0x1c, 0x00, + 0x2e, 0x02, 0xd0, 0x00, 0xa1, 0xc8, 0x39, 0x00, + 0xe0, 0x49, 0xa1, 0x03, 0x92, 0x02, 0x91, 0x07, + 0x99, 0x04, 0x9a, 0x01, 0x95, 0x00, 0x29, 0x00, + 0x92, 0x01, 0xd0, 0x46, 0xa2, 0x01, 0xe0, 0x00, + 0xa2, 0xe4, 0x3a, 0x05, 0x98, 0x00, 0x28, 0x01, + 0xd0, 0x43, 0xa1, 0x00, 0xe0, 0x43, 0xa1, 0x09, + 0x9b, 0x43, 0xa0, 0xfa, 0xf7, 0xc4, 0xf9, 0x00, + 0x23, 0xe8, 0x56, 0x70, 0x28, 0x68, 0xd1, 0x00, + 0x2e, 0x00, 0xd1, 0x27, 0x1c, 0x0a, 0x98, 0x39, + 0x18, 0x44, 0x48, 0xfa, 0xf7, 0xb8, 0xf9, 0x6b, + 0xe0, 0x06, 0x98, 0x01, 0x28, 0x27, 0xd1, 0x3a, + 0x1c, 0x00, 0x2e, 0x01, 0xd0, 0x40, 0xa1, 0x00, + 0xe0, 0x33, 0xa1, 0x03, 0x92, 0x02, 0x91, 0x07, + 0x99, 0x04, 0x9a, 0x01, 0x95, 0x00, 0x29, 0x00, + 0x92, 0x01, 0xd0, 0x30, 0xa2, 0x00, 0xe0, 0x3a, + 0xa2, 0x05, 0x98, 0x00, 0x28, 0x01, 0xd0, 0x2e, + 0xa1, 0x00, 0xe0, 0x2e, 0xa1, 0x09, 0x9b, 0x37, + 0xa0, 0xfa, 0xf7, 0x99, 0xf9, 0x00, 0x23, 0xe8, + 0x56, 0x70, 0x28, 0x3d, 0xd1, 0x00, 0x2e, 0x00, + 0xd1, 0x27, 0x1c, 0x0a, 0x98, 0x39, 0x18, 0x2f, + 0x48, 0xfa, 0xf7, 0x8d, 0xf9, 0x40, 0xe0, 0x08, + 0x98, 0x00, 0x28, 0x3d, 0xd1, 0x06, 0x98, 0x01, + 0x28, 0x1b, 0xd1, 0x3a, 0x1c, 0x00, 0x2e, 0x01, + 0xd0, 0x29, 0xa1, 0x00, 0xe0, 0x1c, 0xa1, 0x03, + 0x92, 0x02, 0x91, 0x07, 0x99, 0x04, 0x9a, 0x01, + 0x95, 0x00, 0x29, 0x00, 0x92, 0x01, 0xd0, 0x19, + 0xa2, 0x00, 0xe0, 0x23, 0xa2, 0x05, 0x98, 0x00, + 0x28, 0x01, 0xd0, 0x17, 0xa1, 0x00, 0xe0, 0x17, + 0xa1, 0x09, 0x9b, 0x27, 0xa0, 0xfa, 0xf7, 0x6b, + 0xf9, 0x1e, 0xe0, 0x06, 0x98, 0x00, 0x28, 0x1b, + 0xd1, 0x3a, 0x1c, 0x00, 0x2e, 0x01, 0xd0, 0xed, + 0x09, 0x00, 0x23, 0x02, 0x1a, 0xa1, 0x00, 0xe0, + 0x0d, 0xa1, 0x03, 0x92, 0x02, 0x91, 0x07, 0x99, + 0x04, 0x9a, 0x01, 0x95, 0x00, 0x29, 0x00, 0x92, + 0x02, 0xd0, 0x09, 0xa2, 0x01, 0xe0, 0x0a, 0xe0, + 0x13, 0xa2, 0x05, 0x98, 0x00, 0x28, 0x01, 0xd0, + 0x07, 0xa1, 0x00, 0xe0, 0x07, 0xa1, 0x09, 0x9b, + 0x1e, 0xa0, 0xfa, 0xf7, 0x4b, 0xf9, 0x0e, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x2d, 0x00, + 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x4c, 0x44, + 0x52, 0x00, 0x53, 0x54, 0x52, 0x00, 0x20, 0x25, + 0x73, 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, + 0x2c, 0x20, 0x5b, 0x25, 0x73, 0x2c, 0x20, 0x23, + 0x25, 0x73, 0x30, 0x78, 0x25, 0x58, 0x5d, 0x00, + 0x00, 0x00, 0xf8, 0x1b, 0x02, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, + 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, + 0x73, 0x2c, 0x20, 0x23, 0x25, 0x73, 0x30, 0x78, + 0x25, 0x58, 0x5d, 0x21, 0x00, 0x00, 0x20, 0x25, + 0x73, 0x25, 0x73, 0x25, 0x73, 0x54, 0x09, 0x25, + 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, 0x5d, 0x2c, + 0x20, 0x23, 0x25, 0x73, 0x30, 0x78, 0x25, 0x58, + 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, + 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, + 0x73, 0x5d, 0x2c, 0x20, 0x23, 0x25, 0x73, 0x30, + 0x78, 0x25, 0x58, 0x00, 0x00, 0x00, 0xf0, 0xb5, + 0x8b, 0xb0, 0x18, 0x1c, 0x0f, 0x1c, 0xff, 0xf7, + 0x20, 0xfa, 0x04, 0x1c, 0x01, 0x20, 0x01, 0x1c, + 0x7a, 0x0e, 0x00, 0xd2, 0x00, 0x21, 0x0a, 0x91, + 0x06, 0x1c, 0x39, 0x0e, 0x00, 0xd2, 0x00, 0x26, + 0x05, 0x1c, 0xf9, 0x0d, 0x00, 0xd2, 0x00, 0x25, + 0x01, 0x1c, 0xba, 0x0d, 0x00, 0xd2, 0x00, 0x21, + 0x09, 0x91, 0x79, 0x0d, 0x00, 0xd2, 0x00, 0x20, + 0x08, 0x90, 0xed, 0x09, 0x00, 0x24, 0x02, 0x38, + 0x0b, 0x00, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xf9, + 0xfa, 0x07, 0x90, 0x38, 0x0c, 0x00, 0x07, 0x00, + 0x0f, 0xff, 0xf7, 0xf3, 0xfa, 0x06, 0x90, 0x38, + 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xee, 0xfa, 0xfa, + 0x09, 0xd2, 0x06, 0xd2, 0x0e, 0x7b, 0x09, 0x9b, + 0x07, 0x9b, 0x0f, 0x8a, 0xa1, 0x09, 0xd0, 0x01, + 0x2b, 0x09, 0xd0, 0x02, 0x2b, 0x09, 0xd0, 0x03, + 0x2b, 0x0a, 0xd1, 0x00, 0x2a, 0x07, 0xd1, 0x87, + 0xa1, 0x06, 0xe0, 0x87, 0xa1, 0x04, 0xe0, 0x87, + 0xa1, 0x02, 0xe0, 0x87, 0xa1, 0x00, 0xe0, 0x87, + 0xa1, 0x0a, 0x9b, 0x01, 0x2b, 0x65, 0xd1, 0x09, + 0x9b, 0x00, 0x2b, 0x3a, 0xd1, 0x00, 0x2a, 0x1b, + 0xd1, 0x02, 0x1c, 0x00, 0x2e, 0x01, 0xd0, 0x82, + 0xa1, 0x00, 0xe0, 0x82, 0xa1, 0x03, 0x92, 0x07, + 0x9a, 0x06, 0x98, 0x02, 0x91, 0x00, 0x2d, 0x00, + 0x92, 0x01, 0x90, 0x01, 0xd0, 0x7f, 0xa2, 0x00, + 0xe0, 0x7c, 0xa2, 0x08, 0x98, 0x00, 0x28, 0x01, + 0xd0, 0x7d, 0xa1, 0x00, 0xe0, 0x7d, 0xa1, 0x23, + 0x1c, 0x7d, 0xa0, 0xfa, 0xf7, 0x99, 0xf8, 0xc4, + 0xe0, 0x05, 0x92, 0x04, 0x91, 0x03, 0x90, 0x00, + 0x2e, 0x01, 0xd0, 0x73, 0xa2, 0x00, 0xe0, 0x73, + 0xa2, 0x07, 0x98, 0x06, 0x99, 0x02, 0x92, 0x00, + 0x2d, 0x00, 0x90, 0x01, 0x91, 0x01, 0xd0, 0x70, + 0xa2, 0x00, 0xe0, 0x6d, 0xa2, 0x08, 0x98, 0x00, + 0x28, 0x01, 0xd0, 0x6e, 0xa1, 0x00, 0xe0, 0x6e, + 0xa1, 0x23, 0x1c, 0x74, 0xa0, 0xfa, 0xf7, 0x7c, + 0xf8, 0xa7, 0xe0, 0x09, 0x9b, 0x01, 0x2b, 0x24, + 0xd1, 0x00, 0x2a, 0x1b, 0xd1, 0x02, 0x1c, 0x00, + 0x2e, 0x01, 0xd0, 0x63, 0xa1, 0x00, 0xe0, 0x63, + 0xa1, 0x03, 0x92, 0x07, 0x9a, 0x06, 0x98, 0x02, + 0x91, 0x00, 0x2d, 0x00, 0x92, 0x01, 0x90, 0x01, + 0xd0, 0x60, 0xa2, 0x00, 0xe0, 0xed, 0x09, 0x00, + 0x25, 0x02, 0x5d, 0xa2, 0x08, 0x98, 0x00, 0x28, + 0x01, 0xd0, 0x5e, 0xa1, 0x00, 0xe0, 0x5e, 0xa1, + 0x23, 0x1c, 0x6d, 0xa0, 0xfa, 0xf7, 0x5b, 0xf8, + 0x86, 0xe0, 0x05, 0x92, 0x04, 0x91, 0x03, 0x90, + 0x00, 0x2e, 0x02, 0xd0, 0x54, 0xa2, 0x01, 0xe0, + 0x15, 0xe0, 0x54, 0xa2, 0x07, 0x98, 0x06, 0x99, + 0x02, 0x92, 0x00, 0x2d, 0x00, 0x90, 0x01, 0x91, + 0x01, 0xd0, 0x51, 0xa2, 0x00, 0xe0, 0x4e, 0xa2, + 0x08, 0x98, 0x00, 0x28, 0x01, 0xd0, 0x4f, 0xa1, + 0x00, 0xe0, 0x4f, 0xa1, 0x23, 0x1c, 0x65, 0xa0, + 0xfa, 0xf7, 0x3d, 0xf8, 0x68, 0xe0, 0x0a, 0x9b, + 0x00, 0x2b, 0x65, 0xd1, 0x09, 0x9b, 0x01, 0x2b, + 0x3a, 0xd1, 0x00, 0x2a, 0x1b, 0xd1, 0x02, 0x1c, + 0x00, 0x2e, 0x01, 0xd0, 0x42, 0xa1, 0x00, 0xe0, + 0x42, 0xa1, 0x03, 0x92, 0x07, 0x9a, 0x06, 0x98, + 0x02, 0x91, 0x00, 0x2d, 0x00, 0x92, 0x01, 0x90, + 0x01, 0xd0, 0x3f, 0xa2, 0x00, 0xe0, 0x3c, 0xa2, + 0x08, 0x98, 0x00, 0x28, 0x01, 0xd0, 0x3d, 0xa1, + 0x00, 0xe0, 0x3d, 0xa1, 0x23, 0x1c, 0x5c, 0xa0, + 0xfa, 0xf7, 0x19, 0xf8, 0x5a, 0xe0, 0x05, 0x92, + 0x04, 0x91, 0x03, 0x90, 0x00, 0x2e, 0x01, 0xd0, + 0x33, 0xa2, 0x00, 0xe0, 0x33, 0xa2, 0x07, 0x98, + 0x06, 0x99, 0x02, 0x92, 0x00, 0x2d, 0x00, 0x90, + 0x01, 0x91, 0x01, 0xd0, 0x30, 0xa2, 0x00, 0xe0, + 0x2d, 0xa2, 0x08, 0x98, 0x00, 0x28, 0x01, 0xd0, + 0x2e, 0xa1, 0x00, 0xe0, 0x2e, 0xa1, 0x23, 0x1c, + 0x54, 0xa0, 0xf9, 0xf7, 0xfc, 0xff, 0x3d, 0xe0, + 0x09, 0x9b, 0x00, 0x2b, 0x24, 0xd1, 0x00, 0x2a, + 0x1b, 0xd1, 0x02, 0x1c, 0x00, 0x2e, 0x01, 0xd0, + 0x23, 0xa1, 0x00, 0xe0, 0x23, 0xa1, 0x03, 0x92, + 0x07, 0x9a, 0x06, 0x98, 0x02, 0x91, 0x00, 0x2d, + 0x00, 0x92, 0x01, 0x90, 0x01, 0xd0, 0x20, 0xa2, + 0xed, 0x09, 0x00, 0x26, 0x02, 0x00, 0xe0, 0x1d, + 0xa2, 0x08, 0x98, 0x00, 0x28, 0x01, 0xd0, 0x1e, + 0xa1, 0x00, 0xe0, 0x1e, 0xa1, 0x23, 0x1c, 0x4d, + 0xa0, 0xf9, 0xf7, 0xdb, 0xff, 0x1c, 0xe0, 0x05, + 0x92, 0x04, 0x91, 0x03, 0x90, 0x00, 0x2e, 0x02, + 0xd0, 0x14, 0xa2, 0x01, 0xe0, 0x14, 0xe0, 0x14, + 0xa2, 0x07, 0x98, 0x06, 0x99, 0x02, 0x92, 0x00, + 0x2d, 0x00, 0x90, 0x01, 0x91, 0x01, 0xd0, 0x11, + 0xa2, 0x00, 0xe0, 0x0e, 0xa2, 0x08, 0x98, 0x00, + 0x28, 0x01, 0xd0, 0x0f, 0xa1, 0x00, 0xe0, 0x0f, + 0xa1, 0x23, 0x1c, 0x44, 0xa0, 0xf9, 0xf7, 0xbd, + 0xff, 0x0b, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x00, 0x52, 0x52, 0x58, 0x00, 0x4c, 0x53, 0x4c, + 0x00, 0x4c, 0x53, 0x52, 0x00, 0x41, 0x53, 0x52, + 0x00, 0x52, 0x4f, 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, + 0x00, 0x4c, 0x44, 0x52, 0x00, 0x53, 0x54, 0x52, + 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, + 0x2c, 0x20, 0x23, 0x25, 0x73, 0x25, 0x73, 0x5d, + 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, + 0x2c, 0x20, 0x23, 0x25, 0x73, 0x25, 0x73, 0x2c, + 0x20, 0x25, 0x73, 0x20, 0x30, 0x78, 0x25, 0x58, + 0x5d, 0x00, 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, + 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, 0x2c, + 0x20, 0x5b, 0x25, 0x73, 0x2c, 0x20, 0x23, 0x25, + 0x73, 0x25, 0x73, 0x5d, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, + 0x2c, 0x20, 0x23, 0x25, 0x73, 0x25, 0x73, 0x2c, + 0x20, 0x25, 0x73, 0xed, 0x09, 0x00, 0x27, 0x02, + 0x20, 0x30, 0x78, 0x25, 0x58, 0x5d, 0x21, 0x00, + 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, + 0x73, 0x54, 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, + 0x25, 0x73, 0x5d, 0x2c, 0x20, 0x23, 0x25, 0x73, + 0x25, 0x73, 0x00, 0x00, 0x00, 0x00, 0x20, 0x25, + 0x73, 0x25, 0x73, 0x25, 0x73, 0x54, 0x09, 0x25, + 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, 0x5d, 0x2c, + 0x20, 0x23, 0x25, 0x73, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x20, 0x30, 0x78, 0x25, 0x58, 0x00, + 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, + 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, + 0x73, 0x5d, 0x2c, 0x20, 0x23, 0x25, 0x73, 0x25, + 0x73, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, 0x25, + 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, + 0x73, 0x5d, 0x2c, 0x20, 0x23, 0x25, 0x73, 0x25, + 0x73, 0x2c, 0x20, 0x25, 0x73, 0x20, 0x30, 0x78, + 0x25, 0x58, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb5, + 0x86, 0xb0, 0x18, 0x1c, 0x0f, 0x1c, 0xff, 0xf7, + 0x42, 0xf8, 0x01, 0x26, 0x31, 0x1c, 0x04, 0x1c, + 0xb8, 0x0d, 0x00, 0xd2, 0x00, 0x21, 0x05, 0x91, + 0x78, 0x0d, 0x00, 0xd2, 0x00, 0x26, 0x38, 0x0c, + 0x00, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0x29, 0xf9, + 0x05, 0x1c, 0x38, 0x0b, 0x00, 0x07, 0x00, 0x0f, + 0xff, 0xf7, 0x23, 0xf9, 0x04, 0x90, 0x38, 0x0a, + 0x00, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0x1d, 0xf9, + 0x03, 0x90, 0x38, 0x07, 0x00, 0x0f, 0xff, 0xf7, + 0x18, 0xf9, 0x05, 0x99, 0x00, 0x29, 0x10, 0xd0, + 0x03, 0x99, 0x04, 0x9a, 0x00, 0x90, 0x00, 0x2e, + 0x01, 0x91, 0x02, 0x92, 0x01, 0xd0, 0x0d, 0xa2, + 0x01, 0xe0, 0x00, 0xa2, 0xcc, 0x3a, 0x21, 0x1c, + 0x2b, 0x1c, 0x0b, 0xa0, 0xf9, 0xf7, 0xec, 0xfe, + 0x0d, 0xe0, 0x03, 0x9a, 0x00, 0x90, 0xed, 0x09, + 0x00, 0x28, 0x02, 0x00, 0x2e, 0x01, 0x92, 0x01, + 0xd0, 0x06, 0xa2, 0x01, 0xe0, 0x00, 0xa2, 0xe8, + 0x3a, 0x21, 0x1c, 0x2b, 0x1c, 0x0a, 0xa0, 0xf9, + 0xf7, 0xdd, 0xfe, 0x06, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x53, 0x00, 0x00, 0x00, 0x20, + 0x4d, 0x4c, 0x41, 0x25, 0x73, 0x25, 0x73, 0x09, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x00, 0x20, + 0x4d, 0x55, 0x4c, 0x25, 0x73, 0x25, 0x73, 0x09, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x00, 0xf0, 0xb5, 0x88, 0xb0, 0x18, + 0x1c, 0x0f, 0x1c, 0xfe, 0xf7, 0xde, 0xff, 0x01, + 0x25, 0x29, 0x1c, 0x04, 0x1c, 0xb8, 0x0d, 0x00, + 0xd2, 0x00, 0x21, 0x2e, 0x1c, 0x78, 0x0d, 0x07, + 0x91, 0x00, 0xd2, 0x00, 0x26, 0xf8, 0x0d, 0x00, + 0xd2, 0x00, 0x25, 0x38, 0x0b, 0x00, 0x07, 0x00, + 0x0f, 0xff, 0xf7, 0xc1, 0xf8, 0x06, 0x90, 0x38, + 0x0c, 0x00, 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xbb, + 0xf8, 0x05, 0x90, 0x38, 0x07, 0x00, 0x0f, 0xff, + 0xf7, 0xb6, 0xf8, 0x04, 0x90, 0x38, 0x0a, 0x00, + 0x07, 0x00, 0x0f, 0xff, 0xf7, 0xb0, 0xf8, 0x07, + 0x99, 0x00, 0x29, 0x18, 0xd0, 0x02, 0x1c, 0x03, + 0x92, 0x06, 0x9a, 0x05, 0x98, 0x04, 0x99, 0x00, + 0x2e, 0x00, 0x92, 0x01, 0x90, 0x02, 0x91, 0x02, + 0xd0, 0x00, 0xa3, 0xa0, 0x3b, 0x00, 0xe0, 0x13, + 0xa3, 0x00, 0x2d, 0x01, 0xd0, 0x13, 0xa1, 0x01, + 0xe0, 0x00, 0xa1, 0xb0, 0x39, 0x22, 0x1c, 0x11, + 0xa0, 0xf9, 0xf7, 0x7c, 0xfe, 0x17, 0xe0, 0x02, + 0x1c, 0x03, 0x92, 0x06, 0x9a, 0x05, 0x98, 0x04, + 0x99, 0x00, 0x2e, 0x00, 0x92, 0x01, 0x90, 0x02, + 0x91, 0x02, 0xd0, 0x00, 0xa3, 0xd4, 0x3b, 0x00, + 0xe0, 0x07, 0xa3, 0x00, 0x2d, 0x01, 0xd0, 0x06, + 0xa1, 0xed, 0x09, 0x00, 0x29, 0x02, 0x01, 0xe0, + 0x00, 0xa1, 0xe4, 0x39, 0x22, 0x1c, 0x0c, 0xa0, + 0xf9, 0xf7, 0x63, 0xfe, 0x08, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, 0x4d, + 0x4c, 0x41, 0x4c, 0x25, 0x73, 0x25, 0x73, 0x09, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x00, 0x00, + 0x20, 0x25, 0x73, 0x4d, 0x55, 0x4c, 0x4c, 0x25, + 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x2c, 0x20, + 0x25, 0x73, 0x00, 0x00, 0xff, 0xb5, 0x90, 0xb0, + 0x13, 0x98, 0x0f, 0x1c, 0xfe, 0xf7, 0x5c, 0xff, + 0x04, 0x1c, 0x01, 0x20, 0x01, 0x1c, 0x7a, 0x0e, + 0x00, 0xd2, 0x00, 0x21, 0x0c, 0x91, 0x06, 0x1c, + 0x39, 0x0e, 0x00, 0xd2, 0x00, 0x26, 0x01, 0x1c, + 0xfa, 0x0d, 0x00, 0xd2, 0x00, 0x21, 0x0b, 0x91, + 0x05, 0x1c, 0xb9, 0x0d, 0x00, 0xd2, 0x00, 0x25, + 0x01, 0x1c, 0x7a, 0x0d, 0x00, 0xd2, 0x00, 0x21, + 0x0a, 0x91, 0x01, 0x1c, 0xfa, 0x09, 0x00, 0xd2, + 0x00, 0x21, 0x09, 0x91, 0xb9, 0x09, 0x00, 0xd2, + 0x00, 0x20, 0x08, 0x90, 0x38, 0x07, 0x00, 0x0f, + 0x0f, 0x90, 0xff, 0xf7, 0x2b, 0xf8, 0x06, 0x90, + 0x0f, 0x20, 0x00, 0x02, 0x38, 0x40, 0x0f, 0x99, + 0x00, 0x09, 0x08, 0x43, 0x02, 0x1c, 0x39, 0x0b, + 0x09, 0x07, 0x09, 0x0f, 0x0e, 0x91, 0x39, 0x0c, + 0x09, 0x07, 0x05, 0x90, 0x0b, 0x98, 0x09, 0x0f, + 0x0d, 0x91, 0x01, 0x28, 0x68, 0xd1, 0x0d, 0x98, + 0xff, 0xf7, 0x14, 0xf8, 0x07, 0x90, 0x0e, 0x98, + 0xff, 0xf7, 0x10, 0xf8, 0x0c, 0x99, 0x01, 0x29, + 0x4a, 0xd1, 0x00, 0x2d, 0x23, 0xd1, 0x05, 0x9a, + 0x00, 0x2e, 0x02, 0xd0, 0x00, 0xa1, 0xe4, 0x39, + 0x00, 0xe0, 0x7c, 0xa1, 0xed, 0x09, 0x00, 0x2a, + 0x02, 0x02, 0x90, 0x08, 0x98, 0x04, 0x92, 0x07, + 0x9a, 0x03, 0x91, 0x00, 0x28, 0x01, 0xd0, 0x79, + 0xa1, 0x00, 0xe0, 0x79, 0xa1, 0x01, 0x92, 0x00, + 0x91, 0x09, 0x99, 0x00, 0x29, 0x01, 0xd0, 0x77, + 0xa3, 0x00, 0xe0, 0x77, 0xa3, 0x0a, 0x99, 0x00, + 0x29, 0x01, 0xd0, 0x76, 0xa1, 0x00, 0xe0, 0x76, + 0xa1, 0x22, 0x1c, 0x76, 0xa0, 0xf9, 0xf7, 0xcf, + 0xfd, 0xd6, 0xe0, 0x01, 0x2d, 0x22, 0xd1, 0x05, + 0x9a, 0x00, 0x2e, 0x01, 0xd0, 0x6e, 0xa1, 0x00, + 0xe0, 0x69, 0xa1, 0x02, 0x90, 0x08, 0x98, 0x04, + 0x92, 0x07, 0x9a, 0x03, 0x91, 0x00, 0x28, 0x01, + 0xd0, 0x66, 0xa1, 0x00, 0xe0, 0x66, 0xa1, 0x01, + 0x92, 0x00, 0x91, 0x09, 0x99, 0x00, 0x29, 0x01, + 0xd0, 0x64, 0xa3, 0x00, 0xe0, 0x64, 0xa3, 0x0a, + 0x99, 0x00, 0x29, 0x01, 0xd0, 0x63, 0xa1, 0x00, + 0xe0, 0x63, 0xa1, 0x22, 0x1c, 0x6a, 0xa0, 0xf9, + 0xf7, 0xaa, 0xfd, 0xb1, 0xe0, 0x0c, 0x99, 0x00, + 0x29, 0x25, 0xd1, 0x00, 0x2d, 0x23, 0xd1, 0x05, + 0x9a, 0x00, 0x2e, 0x01, 0xd0, 0x5a, 0xa1, 0x00, + 0xe0, 0x55, 0xa1, 0x02, 0x90, 0x08, 0x98, 0x04, + 0x92, 0x07, 0x9a, 0x03, 0x91, 0x00, 0x28, 0x02, + 0xd0, 0x52, 0xa1, 0x01, 0xe0, 0x1a, 0xe0, 0x52, + 0xa1, 0x01, 0x92, 0x00, 0x91, 0x09, 0x99, 0x00, + 0x29, 0x01, 0xd0, 0x50, 0xa3, 0x00, 0xe0, 0x50, + 0xa3, 0x0a, 0x99, 0x00, 0x29, 0x01, 0xd0, 0x4f, + 0xa1, 0x00, 0xe0, 0x4f, 0xa1, 0x22, 0x1c, 0x5e, + 0xa0, 0xf9, 0xf7, 0x81, 0xfd, 0x88, 0xe0, 0x10, + 0x98, 0x12, 0x9a, 0x13, 0x9b, 0x39, 0x1c, 0xff, + 0xf7, 0x7d, 0xf8, 0x81, 0xe0, 0x0e, 0x98, 0xfe, + 0xf7, 0x8f, 0xff, 0x07, 0x90, 0x0d, 0x98, 0xfe, + 0xf7, 0x8b, 0xff, 0x0c, 0x99, 0x01, 0x29, 0x49, + 0xd1, 0x00, 0x2d, 0x22, 0xd1, 0x06, 0x9a, 0xed, + 0x09, 0x00, 0x2b, 0x02, 0x00, 0x2e, 0x01, 0xd0, + 0x3f, 0xa1, 0x00, 0xe0, 0x3a, 0xa1, 0x02, 0x90, + 0x08, 0x98, 0x04, 0x92, 0x07, 0x9a, 0x03, 0x91, + 0x00, 0x28, 0x01, 0xd0, 0x37, 0xa1, 0x00, 0xe0, + 0x37, 0xa1, 0x01, 0x92, 0x00, 0x91, 0x09, 0x99, + 0x00, 0x29, 0x01, 0xd0, 0x35, 0xa3, 0x00, 0xe0, + 0x35, 0xa3, 0x0a, 0x99, 0x00, 0x29, 0x01, 0xd0, + 0x34, 0xa1, 0x00, 0xe0, 0x34, 0xa1, 0x22, 0x1c, + 0x4a, 0xa0, 0xf9, 0xf7, 0x4b, 0xfd, 0x52, 0xe0, + 0x01, 0x2d, 0x22, 0xd1, 0x06, 0x9a, 0x00, 0x2e, + 0x01, 0xd0, 0x2c, 0xa1, 0x00, 0xe0, 0x27, 0xa1, + 0x02, 0x90, 0x08, 0x98, 0x04, 0x92, 0x07, 0x9a, + 0x03, 0x91, 0x00, 0x28, 0x01, 0xd0, 0x24, 0xa1, + 0x00, 0xe0, 0x24, 0xa1, 0x01, 0x92, 0x00, 0x91, + 0x09, 0x99, 0x00, 0x29, 0x01, 0xd0, 0x22, 0xa3, + 0x00, 0xe0, 0x22, 0xa3, 0x0a, 0x99, 0x00, 0x29, + 0x01, 0xd0, 0x21, 0xa1, 0x00, 0xe0, 0x21, 0xa1, + 0x22, 0x1c, 0x3e, 0xa0, 0xf9, 0xf7, 0x26, 0xfd, + 0x2d, 0xe0, 0x0c, 0x99, 0x00, 0x29, 0x24, 0xd1, + 0x00, 0x2d, 0x22, 0xd1, 0x06, 0x9a, 0x00, 0x2e, + 0x01, 0xd0, 0x18, 0xa1, 0x00, 0xe0, 0x13, 0xa1, + 0x02, 0x90, 0x08, 0x98, 0x04, 0x92, 0x07, 0x9a, + 0x03, 0x91, 0x00, 0x28, 0x01, 0xd0, 0x10, 0xa1, + 0x00, 0xe0, 0x10, 0xa1, 0x01, 0x92, 0x00, 0x91, + 0x09, 0x99, 0x00, 0x29, 0x01, 0xd0, 0x0e, 0xa3, + 0x00, 0xe0, 0x0e, 0xa3, 0x0a, 0x99, 0x00, 0x29, + 0x01, 0xd0, 0x0d, 0xa1, 0x00, 0xe0, 0x0d, 0xa1, + 0x22, 0x1c, 0x31, 0xa0, 0xf9, 0xf7, 0xfe, 0xfc, + 0x05, 0xe0, 0x10, 0x98, 0x12, 0x9a, 0x13, 0x9b, + 0x39, 0x1c, 0xfe, 0xf7, 0xfa, 0xff, 0x14, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x2d, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x2c, 0x02, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, + 0x44, 0x52, 0x00, 0x53, 0x54, 0x52, 0x00, 0x20, + 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, + 0x2c, 0x20, 0x23, 0x25, 0x73, 0x30, 0x78, 0x25, + 0x58, 0x5d, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, + 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, 0x2c, + 0x20, 0x5b, 0x25, 0x73, 0x2c, 0x20, 0x23, 0x25, + 0x73, 0x30, 0x78, 0x25, 0x58, 0x5d, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, + 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, 0x2c, + 0x20, 0x5b, 0x25, 0x73, 0x5d, 0x2c, 0x20, 0x23, + 0x25, 0x73, 0x30, 0x78, 0x25, 0x58, 0x00, 0x20, + 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, + 0x2c, 0x20, 0x25, 0x73, 0x25, 0x73, 0x5d, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x25, 0x73, 0x25, 0x73, + 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, 0x73, 0x2c, + 0x20, 0x5b, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, + 0x25, 0x73, 0x5d, 0x21, 0x00, 0x00, 0x00, 0x20, + 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x2c, 0x20, 0x5b, 0x25, 0x73, + 0x5d, 0x2c, 0x20, 0x25, 0x73, 0x25, 0x73, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0xb5, 0x83, 0xb0, 0x18, + 0x1c, 0x0f, 0x1c, 0xfe, 0xf7, 0xac, 0xfd, 0x01, + 0x26, 0x04, 0x1c, 0xf8, 0x0d, 0x00, 0xd2, 0x00, + 0x26, 0x38, 0x0b, 0x00, 0x07, 0x00, 0x0f, 0xfe, + 0xf7, 0x98, 0xfe, 0x05, 0x1c, 0x38, 0x07, 0x00, + 0x0f, 0xfe, 0xf7, 0x93, 0xfe, 0x02, 0x90, 0x38, + 0x0c, 0x00, 0x07, 0x00, 0x0f, 0xfe, 0xf7, 0x8d, + 0xfe, 0x02, 0x99, 0x01, 0x90, 0x00, 0x2e, 0x00, + 0x91, 0x01, 0xd0, 0x06, 0xa2, 0xed, 0x09, 0x00, + 0x2d, 0x02, 0x01, 0xe0, 0x00, 0xa2, 0xbc, 0x3a, + 0x21, 0x1c, 0x2b, 0x1c, 0x04, 0xa0, 0xf9, 0xf7, + 0x66, 0xfc, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x20, 0x53, 0x57, 0x50, 0x25, 0x73, 0x25, 0x73, + 0x09, 0x25, 0x73, 0x2c, 0x20, 0x25, 0x73, 0x2c, + 0x20, 0x5b, 0x25, 0x73, 0x5d, 0x00, 0x00, 0x00, + 0x90, 0xb5, 0x18, 0x1c, 0x0f, 0x1c, 0xfe, 0xf7, + 0x71, 0xfd, 0x04, 0x1c, 0x38, 0x07, 0x00, 0x0f, + 0xfe, 0xf7, 0x62, 0xfe, 0x21, 0x1c, 0x02, 0x1c, + 0x02, 0xa0, 0xf9, 0xf7, 0x44, 0xfc, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x20, 0x42, 0x58, 0x25, + 0x73, 0x09, 0x25, 0x73, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xb5, 0x07, 0x1c, 0x00, 0x20, 0x7a, 0x4a, + 0x00, 0x21, 0x00, 0x25, 0x10, 0x70, 0xc0, 0x43, + 0x01, 0x26, 0x04, 0x1c, 0x02, 0xe0, 0x01, 0x23, + 0xd8, 0x42, 0x16, 0xd1, 0x32, 0x1c, 0xaa, 0x40, + 0x3a, 0x40, 0x0f, 0xd0, 0x00, 0x29, 0x03, 0xd0, + 0x71, 0x48, 0x72, 0xa1, 0x03, 0xf0, 0xb8, 0xf9, + 0x28, 0x1c, 0xfe, 0xf7, 0x39, 0xfe, 0x01, 0x1c, + 0x6d, 0x48, 0x03, 0xf0, 0xb1, 0xf9, 0x01, 0x21, + 0x28, 0x1c, 0x2c, 0x1c, 0x01, 0x23, 0xd8, 0x42, + 0x27, 0xd0, 0x32, 0x1c, 0xaa, 0x40, 0x3a, 0x40, + 0x00, 0xd0, 0x2c, 0x1c, 0x00, 0x2a, 0x20, 0xd1, + 0x01, 0x30, 0xa0, 0x42, 0x0c, 0xd1, 0x64, 0x48, + 0x64, 0xa1, 0x03, 0xf0, 0x9d, 0xf9, 0x20, 0x1c, + 0xfe, 0xf7, 0x1e, 0xfe, 0x01, 0x1c, 0x60, 0x48, + 0x03, 0xf0, 0x96, 0xf9, 0x01, 0x21, 0x0d, 0xe0, + 0xa0, 0x42, 0x0b, 0xd2, 0x5c, 0x48, 0x5e, 0xa1, + 0x03, 0xf0, 0x8e, 0xf9, 0x20, 0x1c, 0xfe, 0xf7, + 0x0f, 0xfe, 0x01, 0x1c, 0x58, 0x48, 0x03, 0xf0, + 0x87, 0xf9, 0x01, 0x21, 0x00, 0x20, 0xc0, 0x43, + 0xed, 0x09, 0x00, 0x2e, 0x02, 0x04, 0x1c, 0x01, + 0x35, 0x04, 0x2d, 0xba, 0xd3, 0x01, 0x23, 0xd8, + 0x42, 0x20, 0xd0, 0x01, 0x30, 0xa0, 0x42, 0x0c, + 0xd1, 0x50, 0x48, 0x51, 0xa1, 0x03, 0xf0, 0x76, + 0xf9, 0x20, 0x1c, 0xfe, 0xf7, 0xf7, 0xfd, 0x01, + 0x1c, 0x4c, 0x48, 0x03, 0xf0, 0x6f, 0xf9, 0x01, + 0x21, 0x0d, 0xe0, 0xa0, 0x42, 0x0b, 0xd2, 0x49, + 0x48, 0x4a, 0xa1, 0x03, 0xf0, 0x67, 0xf9, 0x20, + 0x1c, 0xfe, 0xf7, 0xe8, 0xfd, 0x01, 0x1c, 0x45, + 0x48, 0x03, 0xf0, 0x60, 0xf9, 0x01, 0x21, 0x00, + 0x20, 0xc0, 0x43, 0x04, 0x1c, 0x0c, 0x2d, 0x43, + 0xd2, 0x01, 0x23, 0xd8, 0x42, 0x15, 0xd1, 0x32, + 0x1c, 0xaa, 0x40, 0x3a, 0x40, 0x39, 0xd0, 0x00, + 0x29, 0x03, 0xd0, 0x3c, 0x48, 0x3c, 0xa1, 0x03, + 0xf0, 0x4d, 0xf9, 0x28, 0x1c, 0xfe, 0xf7, 0xce, + 0xfd, 0x01, 0x1c, 0x38, 0x48, 0x03, 0xf0, 0x46, + 0xf9, 0x01, 0x21, 0x28, 0x1c, 0x2c, 0x1c, 0xcd, + 0x42, 0x27, 0xd0, 0x32, 0x1c, 0xaa, 0x40, 0x3a, + 0x40, 0x00, 0xd0, 0x2c, 0x1c, 0x00, 0x2a, 0x20, + 0xd1, 0x01, 0x30, 0xa0, 0x42, 0x0c, 0xd1, 0x2f, + 0x48, 0x2f, 0xa1, 0x03, 0xf0, 0x33, 0xf9, 0x20, + 0x1c, 0xfe, 0xf7, 0xb4, 0xfd, 0x01, 0x1c, 0x2b, + 0x48, 0x03, 0xf0, 0x2c, 0xf9, 0x01, 0x21, 0x0d, + 0xe0, 0xa0, 0x42, 0x0b, 0xd2, 0x27, 0x48, 0x29, + 0xa1, 0x03, 0xf0, 0x24, 0xf9, 0x20, 0x1c, 0xfe, + 0xf7, 0xa5, 0xfd, 0x01, 0x1c, 0x23, 0x48, 0x03, + 0xf0, 0x1d, 0xf9, 0x01, 0x21, 0x00, 0x20, 0xc0, + 0x43, 0x04, 0x1c, 0x01, 0x35, 0x0c, 0x2d, 0xbb, + 0xd3, 0x01, 0x23, 0xd8, 0x42, 0x1d, 0xd0, 0x01, + 0x30, 0xa0, 0x42, 0x0c, 0xd1, 0x1b, 0x48, 0x1c, + 0xa1, 0x03, 0xf0, 0x0c, 0xf9, 0x20, 0x1c, 0xfe, + 0xf7, 0x8d, 0xfd, 0x01, 0x1c, 0x17, 0x48, 0x03, + 0xf0, 0x05, 0xf9, 0xed, 0x09, 0x00, 0x2f, 0x02, + 0x01, 0x21, 0x0d, 0xe0, 0xa0, 0x42, 0x0b, 0xd2, + 0x14, 0x48, 0x15, 0xa1, 0x03, 0xf0, 0xfd, 0xf8, + 0x20, 0x1c, 0xfe, 0xf7, 0x7e, 0xfd, 0x01, 0x1c, + 0x10, 0x48, 0x03, 0xf0, 0xf6, 0xf8, 0x01, 0x21, + 0x10, 0x2d, 0x15, 0xd2, 0x0d, 0x4c, 0x30, 0x1c, + 0xa8, 0x40, 0x38, 0x40, 0x0d, 0xd0, 0x00, 0x29, + 0x03, 0xd0, 0x20, 0x1c, 0x0a, 0xa1, 0x03, 0xf0, + 0xe8, 0xf8, 0x28, 0x1c, 0xfe, 0xf7, 0x69, 0xfd, + 0x01, 0x1c, 0x20, 0x1c, 0x03, 0xf0, 0xe1, 0xf8, + 0x01, 0x21, 0x01, 0x35, 0x10, 0x2d, 0xea, 0xd3, + 0xf0, 0xbc, 0x08, 0xbc, 0x01, 0x48, 0x18, 0x47, + 0x00, 0x00, 0x9c, 0xc3, 0x03, 0x20, 0x2c, 0x00, + 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0xf0, 0xb5, + 0x89, 0xb0, 0x18, 0x1c, 0x0c, 0x1c, 0xfe, 0xf7, + 0x5a, 0xfc, 0x01, 0x25, 0x07, 0x1c, 0x28, 0x1c, + 0x61, 0x0d, 0x00, 0xd2, 0x00, 0x20, 0x08, 0x90, + 0x28, 0x1c, 0xa1, 0x0d, 0x00, 0xd2, 0x00, 0x20, + 0x07, 0x90, 0x28, 0x1c, 0xe1, 0x0d, 0x00, 0xd2, + 0x00, 0x20, 0x06, 0x90, 0x2e, 0x1c, 0x20, 0x0e, + 0x00, 0xd2, 0x00, 0x26, 0x60, 0x0e, 0x00, 0xd2, + 0x00, 0x25, 0x20, 0x04, 0x00, 0x0c, 0x05, 0x90, + 0x20, 0x0c, 0x00, 0x07, 0x00, 0x0f, 0xfe, 0xf7, + 0x30, 0xfd, 0x04, 0x90, 0x1c, 0xa4, 0x00, 0x2e, + 0x07, 0xd1, 0x00, 0x2d, 0x01, 0xd1, 0x1b, 0xa4, + 0x0c, 0xe0, 0x01, 0x2d, 0x01, 0xd1, 0x1a, 0xa4, + 0x08, 0xe0, 0x01, 0x2e, 0x06, 0xd1, 0x00, 0x2d, + 0x01, 0xd1, 0x18, 0xa4, 0x02, 0xe0, 0x01, 0x2d, + 0x00, 0xd1, 0x17, 0xa4, 0x05, 0x98, 0xff, 0xf7, + 0xc4, 0xfe, 0x06, 0x99, 0x00, 0x29, 0x01, 0xd0, + 0x15, 0xa2, 0x00, 0xe0, 0x15, 0xa2, 0x01, 0x1c, + 0x07, 0x98, 0x00, 0x28, 0x01, 0xd0, 0x13, 0xa0, + 0x00, 0xe0, 0x11, 0xa0, 0x03, 0x92, 0xed, 0x09, + 0x00, 0x30, 0x02, 0x04, 0x9a, 0x01, 0x90, 0x00, + 0x92, 0x08, 0x98, 0x02, 0x91, 0x00, 0x28, 0x01, + 0xd0, 0x0f, 0xa1, 0x00, 0xe0, 0x0f, 0xa1, 0x3a, + 0x1c, 0x23, 0x1c, 0x0e, 0xa0, 0xf9, 0xf7, 0xe2, + 0xfa, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x00, 0x44, 0x41, 0x00, 0x00, 0x44, + 0x42, 0x00, 0x00, 0x49, 0x41, 0x00, 0x00, 0x49, + 0x42, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x4c, + 0x44, 0x4d, 0x00, 0x53, 0x54, 0x4d, 0x00, 0x20, + 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x09, 0x25, + 0x73, 0x25, 0x73, 0x2c, 0x20, 0x7b, 0x25, 0x73, + 0x7d, 0x25, 0x73, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xb5, 0x18, 0x1c, 0x0f, 0x1c, 0xfe, 0xf7, 0xd9, + 0xfb, 0x3a, 0x02, 0x12, 0x0a, 0x01, 0x1c, 0x02, + 0xa0, 0xf9, 0xf7, 0xb0, 0xfa, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x20, 0x53, 0x57, 0x49, 0x25, + 0x73, 0x09, 0x23, 0x30, 0x78, 0x25, 0x58, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xb5, 0x18, 0x1c, 0x0f, + 0x1c, 0xfe, 0xf7, 0xc3, 0xfb, 0x3a, 0x02, 0x12, + 0x0a, 0x01, 0x1c, 0x02, 0xa0, 0xf9, 0xf7, 0x9a, + 0xfa, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, + 0x55, 0x6e, 0x64, 0x65, 0x66, 0x25, 0x73, 0x09, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x23, 0x30, 0x78, 0x25, 0x58, 0x29, + 0x00, 0x00, 0x00, 0xb0, 0xb5, 0x84, 0xb0, 0x18, + 0x1c, 0x0f, 0x1c, 0xfe, 0xf7, 0xa6, 0xfb, 0x05, + 0x1c, 0x38, 0x0b, 0x04, 0x07, 0x24, 0x0f, 0x38, + 0x0c, 0x00, 0x07, 0x00, 0x0f, 0x39, 0x07, 0x09, + 0x0f, 0x3a, 0x0d, 0x13, 0x07, 0x1b, 0x0f, 0x7a, + 0x09, 0x52, 0x07, 0x52, 0x0f, 0x3f, 0x0a, 0x3f, + 0x07, 0xed, 0x09, 0x00, 0x31, 0x02, 0x3f, 0x0f, + 0x02, 0x91, 0x29, 0x1c, 0x03, 0x92, 0x01, 0x90, + 0x04, 0xa0, 0x3a, 0x1c, 0x00, 0x94, 0xf9, 0xf7, + 0x68, 0xfa, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x20, 0x43, 0x44, 0x50, + 0x25, 0x73, 0x09, 0x50, 0x25, 0x64, 0x2c, 0x20, + 0x23, 0x30, 0x78, 0x25, 0x58, 0x2c, 0x20, 0x43, + 0x52, 0x25, 0x64, 0x2c, 0x20, 0x43, 0x52, 0x25, + 0x64, 0x2c, 0x20, 0x43, 0x52, 0x25, 0x64, 0x2c, + 0x20, 0x23, 0x30, 0x78, 0x25, 0x58, 0x00, 0x00, + 0xf0, 0xb5, 0x87, 0xb0, 0x18, 0x1c, 0x0f, 0x1c, + 0xfe, 0xf7, 0x6a, 0xfb, 0x04, 0x1c, 0x38, 0x0b, + 0x00, 0x07, 0x00, 0x0f, 0xfe, 0xf7, 0x5a, 0xfc, + 0x05, 0x1c, 0x38, 0x0c, 0x00, 0x07, 0x00, 0x0f, + 0x39, 0x07, 0x09, 0x0f, 0x7a, 0x0d, 0x56, 0x07, + 0x76, 0x0f, 0x7a, 0x09, 0x52, 0x07, 0x52, 0x0f, + 0x06, 0x92, 0x3a, 0x0a, 0x12, 0x07, 0x12, 0x0f, + 0x05, 0x92, 0x01, 0x22, 0x7b, 0x0d, 0x00, 0xd2, + 0x00, 0x22, 0x13, 0x1c, 0x06, 0x9a, 0x03, 0x91, + 0x02, 0x90, 0x01, 0x95, 0x00, 0x96, 0x04, 0x92, + 0x01, 0xd0, 0x06, 0xa1, 0x00, 0xe0, 0x06, 0xa1, + 0x05, 0x9b, 0x22, 0x1c, 0x05, 0xa0, 0xf9, 0xf7, + 0x1c, 0xfa, 0x07, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x4d, 0x52, 0x43, 0x00, + 0x4d, 0x43, 0x52, 0x00, 0x20, 0x25, 0x73, 0x25, + 0x73, 0x09, 0x50, 0x25, 0x64, 0x2c, 0x20, 0x23, + 0x30, 0x78, 0x25, 0x58, 0x2c, 0x20, 0x25, 0x73, + 0x2c, 0x20, 0x43, 0x52, 0x25, 0x64, 0x2c, 0x20, + 0x43, 0x52, 0x25, 0x64, 0x2c, 0x20, 0x23, 0x30, + 0x78, 0x25, 0x58, 0x00, 0x00, 0x28, 0x01, 0xd1, + 0x0d, 0xa0, 0x70, 0x47, 0x01, 0x28, 0x01, 0xd1, + 0x12, 0xa0, 0x70, 0x47, 0x02, 0x28, 0x01, 0xd1, + 0x17, 0xa0, 0x70, 0x47, 0xed, 0x09, 0x00, 0x32, + 0x02, 0x03, 0x28, 0x01, 0xd1, 0x1c, 0xa0, 0x70, + 0x47, 0x04, 0x28, 0x01, 0xd1, 0x21, 0xa0, 0x70, + 0x47, 0x05, 0x28, 0x01, 0xd1, 0x26, 0xa0, 0x70, + 0x47, 0x06, 0x28, 0x01, 0xd1, 0x2b, 0xa0, 0x70, + 0x47, 0x2f, 0xa0, 0x70, 0x47, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x57, 0x6f, 0x72, 0x64, 0x5f, 0x52, 0x65, + 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x00, 0x00, + 0x00, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x68, 0x6f, + 0x72, 0x74, 0x5f, 0x52, 0x65, 0x61, 0x64, 0x4f, + 0x6e, 0x6c, 0x79, 0x00, 0x00, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x42, 0x79, 0x74, 0x65, 0x5f, 0x52, 0x65, + 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x00, 0x00, + 0x00, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x57, 0x6f, 0x72, + 0x64, 0x5f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x00, 0x00, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x52, + 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x00, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x79, 0x74, + 0x65, 0x5f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x00, 0x00, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4e, 0x6f, 0x74, 0x4e, 0x75, 0x6c, 0x6c, + 0x00, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x75, 0x6e, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x01, 0xd1, 0x09, 0xa0, 0xed, + 0x09, 0x00, 0x33, 0x02, 0x70, 0x47, 0x01, 0x28, + 0x01, 0xd1, 0x0c, 0xa0, 0x70, 0x47, 0x02, 0x28, + 0x01, 0xd1, 0x11, 0xa0, 0x70, 0x47, 0x03, 0x28, + 0x01, 0xd1, 0x15, 0xa0, 0x70, 0x47, 0x04, 0x28, + 0x01, 0xd1, 0x1a, 0xa0, 0x70, 0x47, 0x20, 0xa0, + 0x70, 0x47, 0x42, 0x54, 0x5f, 0x48, 0x43, 0x5f, + 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, + 0x49, 0x44, 0x4c, 0x45, 0x00, 0x00, 0x42, 0x54, + 0x5f, 0x48, 0x43, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, + 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, + 0x45, 0x43, 0x54, 0x49, 0x4e, 0x47, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x54, 0x5f, 0x48, 0x43, 0x5f, + 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, + 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, + 0x44, 0x00, 0x42, 0x54, 0x5f, 0x48, 0x43, 0x5f, + 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, + 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, + 0x43, 0x54, 0x49, 0x4e, 0x47, 0x00, 0x42, 0x54, + 0x5f, 0x48, 0x43, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, + 0x5f, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x00, 0x00, 0x5f, 0x42, 0x54, 0x5f, 0x48, 0x63, + 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x00, 0xf0, 0xb5, 0x88, 0xb0, 0x2c, 0x4e, + 0x2e, 0x4d, 0x30, 0x68, 0x00, 0x24, 0x2b, 0x48, + 0x2d, 0x4f, 0x28, 0x60, 0x04, 0x35, 0x00, 0x20, + 0x11, 0xc5, 0x11, 0xc5, 0x14, 0x3d, 0xa8, 0x61, + 0x38, 0x7a, 0x7b, 0x7a, 0x1b, 0x02, 0x18, 0x43, + 0x28, 0x4b, 0x98, 0x42, 0x01, 0xd0, 0x00, 0x28, + 0x04, 0xd1, 0x11, 0x20, 0x40, 0x02, 0x38, 0x72, + 0x03, 0x0a, 0x7b, 0x72, 0x12, 0xf0, 0x55, 0xfc, + 0xb8, 0x71, 0xed, 0x09, 0x00, 0x34, 0x02, 0x03, + 0x0a, 0xfb, 0x71, 0x22, 0x48, 0x21, 0x49, 0x00, + 0xf0, 0xa8, 0xfb, 0x00, 0xf0, 0x94, 0xfa, 0x00, + 0x20, 0x6c, 0x61, 0x00, 0xf0, 0x37, 0xfc, 0x1e, + 0x48, 0x1f, 0xa1, 0x04, 0xf0, 0x66, 0xfb, 0x19, + 0x21, 0x89, 0x02, 0x01, 0x22, 0x92, 0x02, 0x01, + 0x92, 0x00, 0x91, 0x1f, 0xa1, 0x1d, 0x4a, 0x01, + 0x23, 0x1d, 0x48, 0xef, 0xf7, 0x8a, 0xfb, 0x07, + 0xaa, 0x1f, 0x49, 0x07, 0x20, 0xef, 0xf7, 0x9b, + 0xff, 0x0d, 0x23, 0xdb, 0x02, 0x0c, 0x22, 0x06, + 0x92, 0x00, 0x20, 0x46, 0x22, 0x0a, 0x21, 0x05, + 0x91, 0x01, 0x21, 0xc9, 0x02, 0x03, 0x92, 0x00, + 0x22, 0x00, 0x92, 0x02, 0x91, 0x04, 0x90, 0x01, + 0x93, 0x00, 0x23, 0x16, 0x48, 0x17, 0xa1, 0x14, + 0x4a, 0xef, 0xf7, 0xd7, 0xfa, 0x30, 0x68, 0x08, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, + 0x67, 0x03, 0x20, 0xf8, 0xd4, 0x03, 0x20, 0x8c, + 0x69, 0x03, 0x20, 0x30, 0x7c, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x28, 0x7c, 0x00, 0x00, 0x3a, + 0x7c, 0x00, 0x00, 0xc4, 0xc4, 0x03, 0x20, 0x55, + 0x53, 0x42, 0x2d, 0x45, 0x76, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x7d, 0x32, 0x02, 0x20, 0x6c, + 0xc4, 0x03, 0x20, 0x55, 0x53, 0x42, 0x2d, 0x48, + 0x49, 0x53, 0x52, 0x00, 0x00, 0x00, 0x00, 0x65, + 0x32, 0x02, 0x20, 0x87, 0x32, 0x02, 0x20, 0xc4, + 0xc3, 0x03, 0x20, 0x54, 0x5f, 0x55, 0x53, 0x42, + 0x00, 0x00, 0x00, 0x00, 0xb5, 0x04, 0x48, 0x00, + 0x68, 0x04, 0x49, 0x00, 0x20, 0x88, 0x61, 0x00, + 0xf0, 0x08, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0xd0, + 0x67, 0x03, 0x20, 0x8c, 0x69, 0x03, 0x20, 0x00, + 0xb5, 0x10, 0x49, 0x09, 0x68, 0x10, 0x4a, 0x10, + 0x49, 0x00, 0x23, 0x0a, 0x60, 0x04, 0x31, 0x00, + 0x22, 0x0c, 0xc1, 0x0c, 0xc1, 0xed, 0x09, 0x00, + 0x35, 0x02, 0x14, 0x39, 0x00, 0x28, 0x0a, 0xd0, + 0x01, 0x20, 0xc8, 0x61, 0x0b, 0x48, 0x12, 0xf0, + 0x7d, 0xfc, 0x00, 0x28, 0x01, 0xd1, 0xf2, 0xf7, + 0xf1, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, + 0x20, 0x20, 0x01, 0xf0, 0x8d, 0xff, 0xff, 0x20, + 0x09, 0x30, 0x12, 0xf0, 0xdb, 0xfb, 0xf4, 0xe7, + 0xd0, 0x67, 0x03, 0x20, 0xf8, 0xd4, 0x03, 0x20, + 0x8c, 0x69, 0x03, 0x20, 0xa4, 0x69, 0x03, 0x20, + 0xf7, 0xb5, 0x84, 0xb0, 0x37, 0x48, 0x0f, 0x1c, + 0x01, 0x68, 0x16, 0x1c, 0x36, 0x49, 0x01, 0x22, + 0x0b, 0x68, 0x92, 0x02, 0x00, 0x2b, 0x35, 0x49, + 0x20, 0xd0, 0x48, 0x68, 0xc4, 0x19, 0x94, 0x42, + 0x03, 0xd3, 0x07, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x0c, 0x1c, 0x09, 0x68, 0x08, 0x18, + 0x04, 0x99, 0x3a, 0x1c, 0xdd, 0xf7, 0x96, 0xf9, + 0x60, 0x68, 0xc0, 0x19, 0x60, 0x60, 0x08, 0x2e, + 0x00, 0xd0, 0xee, 0xe7, 0x00, 0xf0, 0xb4, 0xf9, + 0x00, 0x22, 0xd2, 0x43, 0x00, 0x92, 0x01, 0x22, + 0x01, 0x21, 0x01, 0xab, 0x26, 0x48, 0x04, 0xf0, + 0x95, 0xfb, 0xe2, 0xe7, 0x04, 0x25, 0x33, 0x1c, + 0x2b, 0x40, 0x00, 0xd1, 0x00, 0x25, 0x00, 0x24, + 0x00, 0x2f, 0x37, 0xd9, 0x08, 0x23, 0x1e, 0x40, + 0x00, 0xd1, 0x00, 0x23, 0x03, 0x93, 0xff, 0x22, + 0x01, 0x32, 0x38, 0x1b, 0x90, 0x42, 0x00, 0xd8, + 0x02, 0x1c, 0xa0, 0x18, 0x02, 0x90, 0xb8, 0x42, + 0x01, 0xd1, 0x03, 0x98, 0x05, 0x43, 0x17, 0x48, + 0x40, 0x68, 0x81, 0x18, 0x01, 0x23, 0x9b, 0x02, + 0x03, 0x31, 0x99, 0x42, 0x0d, 0xd2, 0x04, 0x99, + 0x09, 0x19, 0x12, 0x4c, 0x23, 0x68, 0x18, 0x18, + 0x2b, 0x1c, 0x00, 0xf0, 0x23, 0xf8, 0x61, 0x68, + 0x40, 0x18, 0x60, 0x60, 0x02, 0x9c, 0x00, 0x25, + 0x0e, 0xe0, 0x0a, 0x48, 0x00, 0x68, 0x00, 0xf0, + 0xed, 0x09, 0x00, 0x36, 0x02, 0x77, 0xf9, 0x00, + 0x22, 0xd2, 0x43, 0x00, 0x92, 0x01, 0x22, 0x01, + 0x21, 0x01, 0xab, 0x08, 0x48, 0x04, 0xf0, 0x58, + 0xfb, 0x03, 0x48, 0x00, 0x68, 0xbc, 0x42, 0xcc, + 0xd3, 0x00, 0xf0, 0x68, 0xf9, 0x9f, 0xe7, 0x00, + 0x00, 0xd0, 0x67, 0x03, 0x20, 0xc0, 0x69, 0x03, + 0x20, 0x8c, 0x69, 0x03, 0x20, 0xc4, 0xc4, 0x03, + 0x20, 0x80, 0xb5, 0x17, 0x1c, 0x0b, 0x4a, 0x12, + 0x68, 0x1a, 0x1c, 0xc1, 0x23, 0x1a, 0x43, 0x02, + 0x70, 0x12, 0x0a, 0x42, 0x70, 0xff, 0x23, 0x01, + 0x33, 0x00, 0x22, 0x9f, 0x42, 0x00, 0xd0, 0x3a, + 0x1c, 0x82, 0x70, 0x03, 0x30, 0x3a, 0x1c, 0xdd, + 0xf7, 0x23, 0xf9, 0xf8, 0x1c, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xd0, 0x67, 0x03, + 0x20, 0xf0, 0xb5, 0x05, 0x1c, 0x04, 0x20, 0x10, + 0x40, 0x14, 0x1c, 0x0f, 0x1c, 0x00, 0x28, 0x16, + 0x4e, 0x05, 0xd0, 0x31, 0x1c, 0x00, 0x22, 0xd2, + 0x43, 0x14, 0x48, 0x03, 0xf0, 0x07, 0xfc, 0x00, + 0x2f, 0x0b, 0xd0, 0x13, 0x49, 0x08, 0x6a, 0x49, + 0x6a, 0x40, 0x18, 0x29, 0x1c, 0x3a, 0x1c, 0xdd, + 0xf7, 0x03, 0xf9, 0x0f, 0x49, 0x48, 0x6a, 0xc0, + 0x19, 0x48, 0x62, 0x20, 0x09, 0x11, 0xd3, 0x0c, + 0x4f, 0x78, 0x6a, 0x03, 0x28, 0x06, 0xd9, 0x31, + 0x1c, 0x00, 0x23, 0x01, 0x22, 0x09, 0x48, 0x03, + 0xf0, 0x69, 0xfd, 0x04, 0xe0, 0x38, 0x6a, 0x03, + 0xf0, 0x45, 0xfc, 0x07, 0x48, 0x00, 0x68, 0x00, + 0x20, 0x78, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xac, 0x69, 0x03, 0x20, 0x18, 0xbc, 0x03, + 0x20, 0x8c, 0x69, 0x03, 0x20, 0x54, 0xbc, 0x03, + 0x20, 0xd0, 0x67, 0x03, 0x20, 0x00, 0xb5, 0x01, + 0x20, 0x12, 0xf0, 0xfa, 0xfa, 0x02, 0x48, 0x12, + 0xf0, 0xf3, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x6c, 0xc4, 0xed, 0x09, 0x00, 0x37, 0x02, + 0x03, 0x20, 0x00, 0xb5, 0x00, 0xf0, 0xf5, 0xf8, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x83, 0xb0, + 0x71, 0x4c, 0x20, 0x68, 0x00, 0xf0, 0xed, 0xf8, + 0x70, 0x48, 0x70, 0x4e, 0x02, 0x90, 0x6d, 0x4c, + 0x20, 0x68, 0x01, 0x20, 0x12, 0xf0, 0xbb, 0xfa, + 0x00, 0x22, 0xd2, 0x43, 0x00, 0x92, 0x01, 0x22, + 0x02, 0x21, 0x01, 0xab, 0x6b, 0x48, 0x04, 0xf0, + 0xc6, 0xfa, 0x66, 0x4c, 0x20, 0x68, 0x00, 0xf0, + 0x4d, 0xf9, 0x00, 0x28, 0x0e, 0xd1, 0x71, 0x69, + 0x30, 0x1c, 0x00, 0x29, 0xe7, 0xd0, 0x00, 0x22, + 0x42, 0x61, 0x00, 0x20, 0x00, 0xf0, 0xdd, 0xf8, + 0x00, 0x20, 0x00, 0xf0, 0x97, 0xfa, 0x5d, 0x4c, + 0x20, 0x68, 0xdc, 0xe7, 0x71, 0x69, 0x81, 0x42, + 0x15, 0xd0, 0x70, 0x61, 0x01, 0x20, 0x37, 0x1c, + 0x00, 0xf0, 0xcf, 0xf8, 0x01, 0x20, 0x00, 0xf0, + 0x89, 0xfa, 0x56, 0x4c, 0x20, 0x68, 0x59, 0x48, + 0x00, 0x68, 0x00, 0x28, 0x07, 0xd1, 0x03, 0xcf, + 0x08, 0x3f, 0x40, 0x18, 0x00, 0xf0, 0xb1, 0xfa, + 0x79, 0x68, 0x40, 0x18, 0x78, 0x60, 0x54, 0x4d, + 0x28, 0x1c, 0x00, 0xf0, 0x80, 0xf9, 0x07, 0x1c, + 0x51, 0xd0, 0x4c, 0x4c, 0x20, 0x68, 0x70, 0x69, + 0x00, 0xf0, 0xb3, 0xf8, 0x29, 0x78, 0x89, 0x07, + 0x89, 0x0f, 0x28, 0x1c, 0x01, 0x29, 0x09, 0xd0, + 0x20, 0x68, 0x03, 0xce, 0x08, 0x3e, 0x40, 0x18, + 0x00, 0xf0, 0x97, 0xfa, 0x71, 0x68, 0x40, 0x18, + 0x70, 0x60, 0x3c, 0xe0, 0x00, 0x25, 0x00, 0x2f, + 0x39, 0xd9, 0x45, 0x48, 0x41, 0x5d, 0x40, 0x19, + 0x42, 0x78, 0x12, 0x02, 0x11, 0x43, 0x0a, 0x04, + 0x12, 0x0c, 0xd3, 0x0b, 0x81, 0x78, 0x01, 0xd3, + 0x02, 0x24, 0x05, 0xe0, 0x00, 0x29, 0x02, 0xd1, + 0xff, 0x24, 0x04, 0x34, 0x00, 0xe0, 0xcc, 0x1c, + 0x91, 0x09, 0x12, 0xd3, 0x36, 0x49, 0xed, 0x09, + 0x00, 0x38, 0x02, 0x09, 0x68, 0x72, 0x68, 0x01, + 0x23, 0x9b, 0x02, 0xd1, 0x1d, 0x21, 0x31, 0x99, + 0x42, 0x18, 0xd2, 0x31, 0x68, 0x8a, 0x18, 0x01, + 0x1c, 0x10, 0x1c, 0x00, 0xf0, 0xa2, 0xfa, 0x71, + 0x68, 0x40, 0x18, 0x70, 0x60, 0x0e, 0xe0, 0x91, + 0x09, 0x89, 0x07, 0x09, 0xd0, 0x2b, 0x49, 0x09, + 0x68, 0x00, 0x21, 0x02, 0x2c, 0x00, 0xd9, 0xe1, + 0x1e, 0x03, 0x30, 0xff, 0xf7, 0x1a, 0xff, 0x01, + 0xe0, 0x26, 0x49, 0x08, 0x68, 0x2d, 0x19, 0xbd, + 0x42, 0xc5, 0xd3, 0x00, 0xf0, 0xd4, 0xfa, 0x00, + 0x28, 0x89, 0xd1, 0xb0, 0x68, 0x00, 0x28, 0x07, + 0xd0, 0xf0, 0x68, 0x31, 0x69, 0x00, 0xf0, 0x57, + 0xf9, 0xb0, 0x60, 0x00, 0x28, 0x00, 0xd0, 0x5c, + 0xe7, 0x20, 0x48, 0x00, 0x68, 0x00, 0x28, 0x17, + 0xd1, 0x1a, 0x4c, 0x20, 0x68, 0x02, 0x28, 0x13, + 0xd1, 0x01, 0x27, 0xbf, 0x02, 0x70, 0x68, 0x34, + 0x1c, 0x82, 0x30, 0xb8, 0x42, 0x0c, 0xd2, 0x03, + 0xcc, 0x08, 0x3c, 0x40, 0x18, 0x00, 0xf0, 0x92, + 0xfa, 0x00, 0x28, 0x05, 0xd0, 0x61, 0x68, 0x08, + 0x18, 0x60, 0x60, 0x82, 0x30, 0xb8, 0x42, 0xf2, + 0xd3, 0x71, 0x68, 0x37, 0x1c, 0x00, 0x29, 0xde, + 0xd0, 0x0c, 0x4c, 0x00, 0x22, 0x20, 0x68, 0x38, + 0x68, 0xf8, 0x60, 0x39, 0x61, 0x7a, 0x60, 0x00, + 0xf0, 0x2a, 0xf9, 0xb8, 0x60, 0x38, 0x68, 0x0c, + 0x49, 0x88, 0x42, 0x02, 0xd1, 0x02, 0x98, 0x38, + 0x60, 0x00, 0xe0, 0x39, 0x60, 0x00, 0x22, 0x01, + 0x21, 0x05, 0x48, 0x04, 0xf0, 0x98, 0xf9, 0x24, + 0xe7, 0x00, 0x00, 0xd0, 0x67, 0x03, 0x20, 0xf8, + 0xd8, 0x03, 0x20, 0x8c, 0x69, 0x03, 0x20, 0xc4, + 0xc4, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, 0xe8, + 0xc4, 0x03, 0x20, 0xf8, 0xd4, 0x03, 0x20, 0x00, + 0xb5, 0x05, 0x48, 0x80, 0x69, 0x00, 0x28, 0x04, + 0xd1, 0xed, 0x09, 0x00, 0x39, 0x02, 0x00, 0x22, + 0x02, 0x21, 0x03, 0x48, 0x04, 0xf0, 0x7e, 0xf9, + 0x08, 0xbc, 0x18, 0x47, 0x8c, 0x69, 0x03, 0x20, + 0xc4, 0xc4, 0x03, 0x20, 0x90, 0xb5, 0x09, 0x4c, + 0x07, 0x1c, 0xa0, 0x6a, 0xb8, 0x42, 0x09, 0xd0, + 0x02, 0x2f, 0x03, 0xd1, 0x02, 0x20, 0xf1, 0xf7, + 0xa3, 0xfc, 0x02, 0xe0, 0x01, 0x20, 0xf1, 0xf7, + 0x9f, 0xfc, 0xa7, 0x62, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x8c, 0x69, 0x03, 0x20, + 0x90, 0xb5, 0x13, 0x4c, 0x00, 0x20, 0x20, 0x60, + 0x60, 0x60, 0xa0, 0x60, 0x00, 0xf0, 0x80, 0xf9, + 0x07, 0x1c, 0xc4, 0x22, 0x00, 0x21, 0x0f, 0x48, + 0xdc, 0xf7, 0x1e, 0xff, 0x38, 0x06, 0x00, 0x0e, + 0x00, 0xf0, 0xf0, 0xfb, 0x00, 0x2f, 0x0c, 0xd1, + 0x00, 0x21, 0x06, 0x20, 0x00, 0xf0, 0x0e, 0xfc, + 0x40, 0x21, 0x41, 0x20, 0x00, 0xf0, 0x10, 0xf8, + 0x00, 0xf0, 0xa8, 0xf9, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0x20, 0x60, 0x60, 0xc0, 0x21, + 0xc1, 0x20, 0x00, 0xf0, 0x05, 0xf8, 0xf5, 0xe7, + 0xb8, 0x69, 0x03, 0x20, 0xcc, 0xdd, 0x03, 0x20, + 0x80, 0xb5, 0x07, 0x1c, 0x0d, 0x20, 0x00, 0xf0, + 0xf5, 0xfb, 0x06, 0x20, 0x00, 0xf0, 0xfa, 0xfb, + 0x38, 0x43, 0x01, 0x06, 0x09, 0x0e, 0x06, 0x20, + 0x00, 0xf0, 0xec, 0xfb, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0x06, 0x20, + 0x00, 0xf0, 0xec, 0xfb, 0xb8, 0x43, 0x01, 0x06, + 0x09, 0x0e, 0x06, 0x20, 0x00, 0xf0, 0xde, 0xfb, + 0x0d, 0x20, 0x39, 0x1c, 0x00, 0xf0, 0xda, 0xfb, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, + 0x0d, 0x20, 0x00, 0xf0, 0xdb, 0xfb, 0x40, 0x23, + 0x07, 0x1c, 0x18, 0x40, 0x01, 0x26, 0x00, 0x25, + 0x00, 0x28, 0x28, 0x4c, 0x21, 0xd0, 0x20, 0x68, + 0x00, 0x28, 0x1e, 0xd1, 0xed, 0x09, 0x00, 0x3a, + 0x02, 0x40, 0x21, 0x0d, 0x20, 0x00, 0xf0, 0xc4, + 0xfb, 0x0d, 0x20, 0x00, 0xf0, 0xc9, 0xfb, 0xc0, + 0x09, 0x13, 0xd3, 0x65, 0x60, 0x26, 0x60, 0x00, + 0x20, 0x00, 0xf0, 0x96, 0xfb, 0x20, 0x21, 0x20, + 0x20, 0xff, 0xf7, 0xbc, 0xff, 0x40, 0x20, 0xff, + 0xf7, 0xca, 0xff, 0x40, 0x21, 0x0d, 0x20, 0x00, + 0xf0, 0xaf, 0xfb, 0x28, 0x1c, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x18, 0x48, 0x00, 0x68, 0xb8, + 0x09, 0x0b, 0xd3, 0x20, 0x68, 0x01, 0x28, 0x08, + 0xd1, 0x60, 0xc4, 0xc0, 0x21, 0xc0, 0x20, 0x08, + 0x3c, 0xff, 0xf7, 0xa4, 0xff, 0x20, 0x20, 0xff, + 0xf7, 0xb2, 0xff, 0x78, 0x08, 0x05, 0xd3, 0x01, + 0x21, 0x0d, 0x20, 0x00, 0xf0, 0x95, 0xfb, 0x00, + 0xf0, 0x4d, 0xfe, 0x60, 0x68, 0x01, 0x28, 0x0b, + 0xd1, 0x38, 0x0a, 0x03, 0xd2, 0x00, 0xf0, 0xc0, + 0xf9, 0x00, 0x28, 0x05, 0xd0, 0x80, 0x21, 0x0d, + 0x20, 0x00, 0xf0, 0x86, 0xfb, 0x00, 0xf0, 0xd5, + 0xf9, 0x05, 0x48, 0x01, 0x68, 0x04, 0x29, 0x01, + 0xd1, 0x40, 0x7a, 0xcf, 0xe7, 0x28, 0x1c, 0xcd, + 0xe7, 0xb8, 0x69, 0x03, 0x20, 0xd0, 0x67, 0x03, + 0x20, 0xcc, 0xdd, 0x03, 0x20, 0x98, 0xb5, 0x07, + 0x1c, 0x17, 0x48, 0x18, 0x4c, 0x80, 0x68, 0x00, + 0x28, 0x24, 0xd0, 0x68, 0x46, 0x00, 0xf0, 0xb4, + 0xfb, 0x00, 0x28, 0x0e, 0xd0, 0x08, 0x28, 0x08, + 0xd9, 0xc1, 0x1f, 0x00, 0x9a, 0x01, 0x20, 0xd0, + 0x71, 0x00, 0x98, 0x0c, 0x22, 0x07, 0x30, 0xff, + 0xf7, 0xd1, 0xfd, 0x00, 0x21, 0x00, 0x20, 0x00, + 0xf0, 0xc1, 0xfd, 0x20, 0x1c, 0x79, 0x1c, 0x00, + 0xf0, 0xdf, 0xfe, 0x00, 0x28, 0x06, 0xd0, 0x41, + 0x1c, 0x02, 0x20, 0x38, 0x70, 0x0c, 0x22, 0x38, + 0x1c, 0xff, 0xf7, 0xc0, 0xfd, 0x00, 0x20, 0x98, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xed, + 0x09, 0x00, 0x3b, 0x02, 0x39, 0x1c, 0x00, 0xf0, + 0xce, 0xfe, 0xf7, 0xe7, 0x00, 0x00, 0xb8, 0x69, + 0x03, 0x20, 0xe8, 0xdd, 0x03, 0x20, 0x80, 0xb5, + 0x13, 0x4a, 0x13, 0x4f, 0x92, 0x68, 0xfb, 0x1d, + 0x31, 0x33, 0x00, 0x2a, 0x18, 0xd0, 0x02, 0x78, + 0x01, 0x30, 0x01, 0x39, 0x04, 0x2a, 0x09, 0xd1, + 0x0a, 0x1c, 0xfb, 0x1d, 0x69, 0x33, 0x01, 0x1c, + 0x18, 0x1c, 0x00, 0xf0, 0x1d, 0xff, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x02, 0x2a, 0x05, 0xd1, + 0x0a, 0x1c, 0x01, 0x1c, 0x18, 0x1c, 0x00, 0xf0, + 0x13, 0xff, 0xf4, 0xe7, 0x00, 0x20, 0xf2, 0xe7, + 0x0a, 0x1c, 0x01, 0x1c, 0x18, 0x1c, 0x00, 0xf0, + 0x0b, 0xff, 0xec, 0xe7, 0x00, 0x00, 0xb8, 0x69, + 0x03, 0x20, 0xcc, 0xdd, 0x03, 0x20, 0xb0, 0xb4, + 0x07, 0x78, 0x01, 0x24, 0x00, 0x23, 0x00, 0x2f, + 0x12, 0x4a, 0x01, 0xd0, 0xff, 0x2f, 0x01, 0xd1, + 0x11, 0x48, 0x05, 0xe0, 0x05, 0x78, 0x67, 0x1c, + 0x01, 0x30, 0x15, 0x55, 0xd3, 0x55, 0x7c, 0x1c, + 0x07, 0x78, 0x00, 0x2f, 0x01, 0xd0, 0x5d, 0x2c, + 0xf4, 0xd3, 0x14, 0x70, 0x0b, 0x4a, 0x01, 0x20, + 0x0f, 0x78, 0x00, 0x2f, 0x0b, 0xd0, 0xff, 0x2f, + 0x09, 0xd0, 0x17, 0x54, 0x44, 0x1c, 0x60, 0x1c, + 0x01, 0x31, 0x11, 0x28, 0x13, 0x55, 0xf3, 0xd3, + 0x10, 0x70, 0xb0, 0xbc, 0x70, 0x47, 0x13, 0x70, + 0xfa, 0xe7, 0xf8, 0xdc, 0x03, 0x20, 0x0c, 0x61, + 0x03, 0x20, 0x58, 0xdd, 0x03, 0x20, 0x90, 0xb4, + 0x06, 0x29, 0x32, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, + 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x03, 0x06, + 0x09, 0x0f, 0x15, 0x18, 0x03, 0x27, 0x15, 0x48, + 0x13, 0xe0, 0x15, 0x27, 0x15, 0x48, 0x10, 0xe0, + 0x15, 0x48, 0x01, 0x78, 0x0f, 0x06, 0x3f, 0x0e, + 0x01, 0x30, 0x0a, 0xe0, 0x13, 0x48, 0x01, 0x78, + 0x0f, 0x06, 0xed, 0x09, 0x00, 0x3c, 0x02, 0x3f, + 0x0e, 0x01, 0x30, 0x04, 0xe0, 0x25, 0x27, 0x10, + 0x48, 0x01, 0xe0, 0x10, 0x48, 0x1d, 0x27, 0x10, + 0x4b, 0x79, 0x1c, 0x19, 0x70, 0x03, 0x21, 0x59, + 0x70, 0x02, 0x21, 0x7f, 0x18, 0x02, 0x2f, 0x05, + 0xd9, 0x04, 0x78, 0x01, 0x30, 0x5c, 0x54, 0x01, + 0x31, 0x8f, 0x42, 0xf9, 0xd8, 0x18, 0x78, 0x10, + 0x70, 0x18, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x00, + 0x20, 0xfb, 0xe7, 0xf0, 0x60, 0x03, 0x20, 0xf4, + 0x60, 0x03, 0x20, 0xf8, 0xdc, 0x03, 0x20, 0x58, + 0xdd, 0x03, 0x20, 0x20, 0x61, 0x03, 0x20, 0x48, + 0x61, 0x03, 0x20, 0x6c, 0xdd, 0x03, 0x20, 0x80, + 0xb5, 0x12, 0xf0, 0xe5, 0xf8, 0x00, 0x28, 0x03, + 0xd0, 0x01, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x07, 0x4f, 0x01, 0x23, 0x38, 0x68, 0x18, + 0x43, 0x38, 0x60, 0x01, 0x20, 0xef, 0xf7, 0x31, + 0xfa, 0x38, 0x68, 0x40, 0x08, 0x40, 0x00, 0x38, + 0x60, 0x00, 0x20, 0xee, 0xe7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0xb5, 0xdc, 0xf7, 0xed, + 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47, 0x0d, + 0x48, 0x81, 0x68, 0x00, 0x22, 0x82, 0x60, 0x01, + 0x22, 0x42, 0x60, 0x02, 0x68, 0x40, 0x23, 0x1a, + 0x43, 0x02, 0x60, 0x02, 0x68, 0x9a, 0x43, 0x02, + 0x60, 0x02, 0x68, 0x80, 0x23, 0x1a, 0x43, 0xc0, + 0x46, 0xc0, 0x46, 0xc0, 0x46, 0xc0, 0x46, 0x02, + 0x60, 0x02, 0x68, 0xc0, 0x46, 0xc0, 0x46, 0x9a, + 0x43, 0x81, 0x60, 0x02, 0x60, 0x70, 0x47, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0xb5, 0x08, 0x20, 0x12, + 0xf0, 0xa2, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x24, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x31, 0x2e, 0x36, 0x39, 0x20, 0x24, 0x00, + 0x00, 0x00, 0x00, 0xb0, 0xb5, 0xed, 0x09, 0x00, + 0x3d, 0x02, 0x07, 0x1c, 0xed, 0x20, 0x38, 0x70, + 0x04, 0x20, 0x13, 0x4c, 0x78, 0x70, 0x20, 0x68, + 0x0a, 0x30, 0x01, 0xf0, 0xb7, 0xff, 0xf8, 0x70, + 0x20, 0x68, 0x0d, 0x30, 0x01, 0xf0, 0xb2, 0xff, + 0x0e, 0x4c, 0x38, 0x71, 0x20, 0x68, 0x12, 0x30, + 0x01, 0xf0, 0xac, 0xff, 0x7d, 0x25, 0xed, 0x00, + 0x45, 0x43, 0x20, 0x68, 0x14, 0x30, 0x01, 0xf0, + 0xa5, 0xff, 0x40, 0x19, 0x78, 0x71, 0x00, 0x0a, + 0xb8, 0x71, 0xf8, 0x1d, 0x09, 0x22, 0x06, 0xa1, + 0xdc, 0xf7, 0xb4, 0xfd, 0x10, 0x20, 0x0d, 0x21, + 0xb9, 0x70, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xbc, 0x67, 0x03, 0x20, 0xc4, 0x69, 0x03, 0x20, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x00, 0x00, 0x00, 0x00, 0x90, 0xb5, 0x0a, 0x78, + 0x4b, 0x78, 0x00, 0x27, 0x1b, 0x02, 0x1a, 0x43, + 0x14, 0x04, 0x24, 0x0c, 0x8a, 0x1c, 0xe1, 0x0b, + 0x01, 0xd3, 0x00, 0x21, 0x05, 0xe0, 0x11, 0x78, + 0x01, 0x32, 0x00, 0x29, 0x01, 0xd1, 0xff, 0x21, + 0x01, 0x31, 0x63, 0x09, 0x03, 0xd3, 0x00, 0x20, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x23, 0x12, + 0x1b, 0x07, 0x1b, 0x0f, 0x04, 0x2b, 0x06, 0xd0, + 0x08, 0x2b, 0x02, 0xd1, 0x10, 0x1c, 0xf7, 0xf7, + 0x2b, 0xff, 0x38, 0x1c, 0xf0, 0xe7, 0xff, 0xf7, + 0xa3, 0xff, 0x07, 0x1c, 0xf9, 0xe7, 0x80, 0xb5, + 0x82, 0xb0, 0xc1, 0x1c, 0x07, 0x1c, 0x00, 0x22, + 0x00, 0x92, 0x7f, 0x22, 0x0b, 0x48, 0x01, 0xab, + 0x02, 0xf0, 0x6e, 0xfb, 0x00, 0x28, 0x02, 0xd1, + 0x01, 0x98, 0x00, 0x28, 0x04, 0xd1, 0x00, 0x20, + 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xed, 0x20, 0x38, 0x70, 0x08, 0x20, 0x78, 0x70, + 0x01, 0x98, 0xb8, 0x70, 0x01, 0x98, 0x03, 0x30, + 0xf2, 0xe7, 0x00, 0x00, 0x4c, 0xb8, 0x03, 0x20, + 0xed, 0x09, 0x00, 0x3e, 0x02, 0x00, 0xb5, 0x05, + 0x20, 0x00, 0xf0, 0xd0, 0xf9, 0x80, 0x08, 0x02, + 0xd3, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x20, 0xfb, 0xe7, 0x00, 0xb5, 0x11, 0x21, 0x05, + 0x20, 0x00, 0xf0, 0xbc, 0xf9, 0x05, 0x20, 0xef, + 0xf7, 0x5d, 0xf9, 0x01, 0x21, 0x05, 0x20, 0x00, + 0xf0, 0xb5, 0xf9, 0x01, 0x21, 0x10, 0x20, 0x01, + 0xf0, 0x0d, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0x14, 0x4f, 0xf8, 0x1d, 0x31, 0x30, 0x00, + 0xf0, 0x5d, 0xfe, 0xf8, 0x1d, 0x69, 0x30, 0x00, + 0xf0, 0x59, 0xfe, 0x00, 0x20, 0xff, 0xf7, 0x54, + 0xfb, 0x00, 0x21, 0x10, 0x20, 0x01, 0xf0, 0xfa, + 0xfa, 0x38, 0x7e, 0x01, 0x28, 0x02, 0xd1, 0xff, + 0xf7, 0x1b, 0xff, 0x02, 0xe0, 0x00, 0x20, 0xff, + 0xf7, 0x17, 0xff, 0x38, 0x68, 0x04, 0x28, 0x05, + 0xd1, 0xff, 0xf7, 0xc4, 0xff, 0x00, 0x28, 0x04, + 0xd0, 0xff, 0xf7, 0xcb, 0xff, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x01, 0x21, 0x10, 0x20, 0x01, + 0xf0, 0xe1, 0xfa, 0xf7, 0xe7, 0xcc, 0xdd, 0x03, + 0x20, 0x08, 0x4a, 0x01, 0x1c, 0x13, 0x68, 0x00, + 0x20, 0x04, 0x2b, 0x06, 0xd1, 0x00, 0x29, 0x05, + 0xd0, 0xd1, 0x7a, 0x89, 0x09, 0x01, 0xd3, 0x01, + 0x20, 0x10, 0x76, 0x70, 0x47, 0x00, 0x20, 0x10, + 0x76, 0x01, 0x20, 0x70, 0x47, 0xcc, 0xdd, 0x03, + 0x20, 0x03, 0x4a, 0x53, 0x7e, 0x03, 0x70, 0x10, + 0x7e, 0x08, 0x70, 0x01, 0x20, 0x70, 0x47, 0x00, + 0x00, 0xcc, 0xdd, 0x03, 0x20, 0xb0, 0xb5, 0x16, + 0x4d, 0x0c, 0x1c, 0x29, 0x68, 0x07, 0x1c, 0x00, + 0x20, 0x04, 0x29, 0x21, 0xd1, 0x79, 0x06, 0x1f, + 0xd0, 0xe9, 0x1d, 0x19, 0x31, 0x09, 0x78, 0xb9, + 0x42, 0x05, 0xd1, 0xe8, 0x1d, 0x15, 0x30, 0x21, + 0x1c, 0x00, 0xf0, 0x2e, 0xfd, 0x01, 0x20, 0xe9, + 0x1d, 0x29, 0x31, 0xed, 0x09, 0x00, 0x3f, 0x02, + 0x09, 0x7b, 0xb9, 0x42, 0x05, 0xd1, 0xe8, 0x1d, + 0x31, 0x30, 0x21, 0x1c, 0x00, 0xf0, 0x23, 0xfd, + 0x01, 0x20, 0xe9, 0x1d, 0x69, 0x31, 0x0a, 0x79, + 0xba, 0x42, 0x04, 0xd1, 0x08, 0x1c, 0x21, 0x1c, + 0x00, 0xf0, 0x19, 0xfd, 0x01, 0x20, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xcc, 0xdd, + 0x03, 0x20, 0x05, 0x49, 0x0a, 0x68, 0x04, 0x2a, + 0x02, 0xd1, 0x49, 0x7a, 0x01, 0x70, 0x01, 0xe0, + 0x00, 0x21, 0x01, 0x70, 0x01, 0x20, 0x70, 0x47, + 0x00, 0x00, 0xcc, 0xdd, 0x03, 0x20, 0xf0, 0xb5, + 0x85, 0xb0, 0x04, 0x1c, 0x00, 0x20, 0x01, 0x90, + 0x69, 0x46, 0x20, 0x1c, 0x00, 0xf0, 0x45, 0xfe, + 0x07, 0x1c, 0x3e, 0x48, 0x04, 0x90, 0x10, 0x38, + 0x03, 0x90, 0x20, 0x38, 0xc6, 0x1f, 0xc5, 0x1f, + 0x4d, 0x3d, 0x31, 0x3e, 0x00, 0x2c, 0x02, 0x90, + 0x05, 0xd0, 0x00, 0x2f, 0x69, 0xd0, 0x70, 0x38, + 0x00, 0x68, 0x04, 0x28, 0x16, 0xd1, 0x00, 0x20, + 0xff, 0xf7, 0xb9, 0xfa, 0x28, 0x1c, 0x00, 0xf0, + 0xcb, 0xfd, 0x30, 0x1c, 0x00, 0xf0, 0xc8, 0xfd, + 0x02, 0x98, 0x00, 0xf0, 0xc5, 0xfd, 0x03, 0x98, + 0x00, 0x22, 0x02, 0x70, 0x04, 0x98, 0x2e, 0x49, + 0x02, 0x73, 0x03, 0x20, 0x08, 0x60, 0x0a, 0x71, + 0x00, 0x2f, 0x41, 0xd0, 0x20, 0x1c, 0xff, 0xf7, + 0xa2, 0xfa, 0x29, 0x4c, 0x09, 0x22, 0x20, 0x1d, + 0x39, 0x1c, 0xdc, 0xf7, 0x78, 0xfc, 0x21, 0x7a, + 0x00, 0x20, 0x00, 0x29, 0x07, 0xd9, 0x00, 0x22, + 0x81, 0x00, 0x09, 0x19, 0x0a, 0x61, 0x21, 0x7a, + 0x01, 0x30, 0x81, 0x42, 0xf8, 0xd8, 0x21, 0x48, + 0x04, 0x27, 0x00, 0x68, 0x00, 0x28, 0x17, 0xd0, + 0x40, 0x23, 0x01, 0x22, 0x03, 0x21, 0x28, 0x1c, + 0x00, 0xf0, 0x22, 0xfd, 0x40, 0x23, 0x01, 0x22, + 0x82, 0x21, 0x30, 0x1c, 0x00, 0xf0, 0xed, 0x09, + 0x00, 0x40, 0x02, 0x1c, 0xfd, 0x10, 0x23, 0x03, + 0x22, 0x81, 0x21, 0x02, 0x98, 0x00, 0xf0, 0x16, + 0xfd, 0x03, 0x98, 0x07, 0x70, 0x04, 0x99, 0x84, + 0x20, 0x08, 0x73, 0x0b, 0xe0, 0x40, 0x23, 0x01, + 0x22, 0x01, 0x21, 0x28, 0x1c, 0x00, 0xf0, 0x0a, + 0xfd, 0x40, 0x23, 0x01, 0x22, 0x82, 0x21, 0x30, + 0x1c, 0x00, 0xf0, 0x04, 0xfd, 0x0e, 0x49, 0x01, + 0x20, 0x27, 0x60, 0x08, 0x70, 0x0a, 0x48, 0x00, + 0x22, 0x02, 0x76, 0x00, 0x68, 0x01, 0x21, 0x04, + 0x28, 0x00, 0xd0, 0x00, 0x21, 0x10, 0x20, 0x01, + 0xf0, 0x02, 0xfa, 0x01, 0x20, 0x01, 0x90, 0x01, + 0x98, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x6c, 0xde, 0x03, 0x20, 0xcc, + 0xdd, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, 0xc8, + 0x69, 0x03, 0x20, 0xb0, 0xb5, 0x1d, 0x4d, 0x0c, + 0x1c, 0x29, 0x68, 0x07, 0x1c, 0x00, 0x20, 0x04, + 0x29, 0x30, 0xd1, 0x79, 0x06, 0x2e, 0xd0, 0xe9, + 0x1d, 0x19, 0x31, 0x09, 0x78, 0xb9, 0x42, 0x05, + 0xd1, 0xe8, 0x1d, 0x15, 0x30, 0x00, 0xf0, 0x69, + 0xfc, 0x20, 0x70, 0x01, 0x20, 0xe9, 0x1d, 0x29, + 0x31, 0x09, 0x7b, 0xb9, 0x42, 0x05, 0xd1, 0xe8, + 0x1d, 0x31, 0x30, 0x00, 0xf0, 0x5e, 0xfc, 0x20, + 0x70, 0x01, 0x20, 0xe9, 0x1d, 0x69, 0x31, 0x0a, + 0x79, 0xba, 0x42, 0x04, 0xd1, 0x08, 0x1c, 0x00, + 0xf0, 0x54, 0xfc, 0x20, 0x70, 0x01, 0x20, 0xe9, + 0x1d, 0x89, 0x31, 0x0a, 0x78, 0x00, 0x21, 0xba, + 0x42, 0x01, 0xd1, 0x21, 0x70, 0x01, 0x20, 0xea, + 0x1d, 0x99, 0x32, 0x12, 0x7b, 0xba, 0x42, 0x01, + 0xd1, 0x21, 0x70, 0x01, 0x20, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xcc, 0xdd, 0x03, 0x20, 0x80, + 0xb5, 0x03, 0x1c, 0x0a, 0x48, 0x00, 0x27, 0x02, + 0x68, 0x04, 0x2a, 0x0b, 0xd1, 0x9a, 0x00, 0x12, + 0x18, 0xed, 0x09, 0x00, 0x41, 0x02, 0x12, 0x69, + 0x0a, 0x70, 0x40, 0x7a, 0x0a, 0x78, 0x19, 0x1c, + 0x00, 0xf0, 0x08, 0xfe, 0x00, 0x28, 0x00, 0xd0, + 0x01, 0x27, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xcc, 0xdd, 0x03, 0x20, + 0xf0, 0xb5, 0x0b, 0x4e, 0x05, 0x1c, 0x30, 0x68, + 0x00, 0x27, 0x0c, 0x1c, 0x04, 0x28, 0x0a, 0xd1, + 0x29, 0x1c, 0x22, 0x1c, 0x70, 0x7a, 0x00, 0xf0, + 0xf1, 0xfd, 0x00, 0x28, 0x03, 0xd0, 0xa8, 0x00, + 0x80, 0x19, 0x04, 0x61, 0x01, 0x27, 0x38, 0x1c, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0xcc, 0xdd, 0x03, 0x20, 0x88, 0xb5, 0x07, 0x1c, + 0x00, 0xf0, 0xfc, 0xfc, 0x69, 0x46, 0x01, 0x20, + 0x00, 0xf0, 0x44, 0xfd, 0xc0, 0x79, 0xc0, 0x09, + 0x01, 0xd3, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, + 0x08, 0x49, 0x48, 0x76, 0x00, 0x20, 0xff, 0xf7, + 0xeb, 0xfe, 0x38, 0x1c, 0x01, 0xf0, 0xa2, 0xf8, + 0x05, 0x48, 0x00, 0x78, 0x00, 0x28, 0x01, 0xd0, + 0x11, 0xf0, 0x7e, 0xfd, 0x88, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xcc, 0xdd, 0x03, 0x20, + 0xc8, 0x69, 0x03, 0x20, 0x02, 0x1c, 0x02, 0x48, + 0x02, 0x70, 0x01, 0x71, 0x70, 0x47, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0xe0, 0x01, 0x1c, 0x02, 0x48, + 0x01, 0x70, 0x00, 0x79, 0x70, 0x47, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0xe0, 0x00, 0x2a, 0x0b, 0xd9, + 0x06, 0x4b, 0x18, 0x70, 0x50, 0x1e, 0x00, 0x2a, + 0x06, 0xd9, 0x0a, 0x78, 0x1a, 0x71, 0x02, 0x1c, + 0x01, 0x38, 0x01, 0x31, 0x00, 0x2a, 0xf8, 0xd8, + 0x70, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xe0, + 0x00, 0x2a, 0x0b, 0xd9, 0x06, 0x4b, 0x18, 0x70, + 0x50, 0x1e, 0x00, 0x2a, 0x06, 0xd9, 0x1a, 0x79, + 0x0a, 0x70, 0x02, 0x1c, 0x01, 0x38, 0x01, 0x31, + 0x00, 0x2a, 0xf8, 0xd8, 0xed, 0x09, 0x00, 0x42, + 0x02, 0x70, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x00, + 0xe0, 0x80, 0xb4, 0x08, 0x4b, 0x18, 0x70, 0x1f, + 0x79, 0x18, 0x70, 0x38, 0x1c, 0x88, 0x43, 0x00, + 0x06, 0x00, 0x0e, 0x00, 0x2a, 0x02, 0xd0, 0x0f, + 0x43, 0x38, 0x06, 0x00, 0x0e, 0x18, 0x71, 0x80, + 0xbc, 0x70, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x00, + 0xe0, 0xb0, 0xb4, 0x0d, 0x49, 0x00, 0x22, 0xcc, + 0x1d, 0xf9, 0x34, 0x67, 0x69, 0x00, 0x2f, 0x11, + 0xd0, 0x0d, 0x7a, 0x4b, 0x7a, 0x1b, 0x02, 0x1d, + 0x43, 0xfb, 0x1f, 0x01, 0x3b, 0x02, 0x31, 0x9d, + 0x42, 0x08, 0xd1, 0x01, 0x60, 0x62, 0x61, 0x88, + 0x79, 0xcb, 0x79, 0x1b, 0x02, 0x18, 0x43, 0x08, + 0x30, 0xb0, 0xbc, 0x70, 0x47, 0x10, 0x1c, 0xfb, + 0xe7, 0x90, 0xde, 0x03, 0x20, 0xf0, 0xb5, 0x72, + 0x4c, 0xe7, 0x1d, 0x09, 0x37, 0x71, 0x4d, 0x28, + 0x68, 0x03, 0x30, 0x00, 0x06, 0x00, 0x0e, 0xff, + 0xf7, 0x97, 0xff, 0x41, 0x09, 0x63, 0xd3, 0x41, + 0x08, 0x61, 0xd3, 0xff, 0x20, 0xf8, 0x70, 0xf8, + 0x73, 0x6a, 0x48, 0x6b, 0x4d, 0x00, 0x68, 0x02, + 0x30, 0x00, 0x06, 0x00, 0x0e, 0xff, 0xf7, 0x88, + 0xff, 0x06, 0x1c, 0x66, 0x48, 0x00, 0x68, 0x04, + 0x30, 0x00, 0x06, 0x00, 0x0e, 0xff, 0xf7, 0x80, + 0xff, 0x32, 0x1a, 0x40, 0x20, 0xa9, 0x1c, 0x0d, + 0x1c, 0x62, 0x61, 0xff, 0xf7, 0x93, 0xff, 0x5f, + 0x48, 0x08, 0x23, 0x00, 0x68, 0x5d, 0x49, 0x58, + 0x40, 0x08, 0x60, 0x02, 0x21, 0x00, 0x28, 0x00, + 0xd0, 0x0a, 0x21, 0xfb, 0x78, 0x40, 0x26, 0x32, + 0x1c, 0x00, 0x2b, 0x00, 0xd1, 0x00, 0x22, 0x11, + 0x43, 0x09, 0x06, 0x09, 0x0e, 0x00, 0x06, 0x00, + 0x0e, 0xff, 0xf7, 0x5a, 0xff, 0x0e, 0x20, 0xff, + 0xf7, 0x5f, 0xff, 0x40, 0x08, 0x01, 0xd3, 0x08, + 0x20, 0x00, 0xe0, 0x00, 0x20, 0x4f, 0x49, 0xed, + 0x09, 0x00, 0x43, 0x02, 0x08, 0x60, 0x01, 0x21, + 0x0d, 0x20, 0xff, 0xf7, 0x4c, 0xff, 0x60, 0x69, + 0x01, 0x06, 0x09, 0x0e, 0x28, 0x1c, 0x00, 0xf0, + 0x94, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x48, 0x4c, + 0xb9, 0x78, 0x20, 0x68, 0x02, 0x30, 0x00, 0x06, + 0x00, 0x0e, 0xff, 0xf7, 0x3c, 0xff, 0x22, 0x68, + 0x03, 0x20, 0x00, 0x2a, 0x00, 0xd0, 0x0b, 0x20, + 0xf9, 0x78, 0x00, 0x29, 0x00, 0xd1, 0x00, 0x26, + 0x30, 0x43, 0x01, 0x06, 0x09, 0x0e, 0x10, 0x06, + 0x00, 0x0e, 0xff, 0xf7, 0x2c, 0xff, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x02, 0xe0, 0x00, 0x20, + 0x60, 0x61, 0xf8, 0xe7, 0xc6, 0x07, 0xf6, 0x0f, + 0x2f, 0xd0, 0x01, 0x22, 0x11, 0x1c, 0x00, 0x09, + 0x00, 0xd3, 0x00, 0x21, 0xf8, 0x78, 0x00, 0x28, + 0x00, 0xd0, 0x00, 0x22, 0x91, 0x42, 0x24, 0xd1, + 0x32, 0x48, 0x00, 0x68, 0x02, 0x30, 0x00, 0x06, + 0x00, 0x0e, 0xff, 0xf7, 0x18, 0xff, 0x05, 0x1c, + 0x2e, 0x48, 0x00, 0x68, 0x04, 0x30, 0x00, 0x06, + 0x00, 0x0e, 0xff, 0xf7, 0x10, 0xff, 0x28, 0x1a, + 0x05, 0x06, 0x2d, 0x0e, 0x60, 0x69, 0xff, 0x23, + 0x11, 0x33, 0x42, 0x19, 0x9a, 0x42, 0x27, 0x49, + 0x08, 0xd8, 0x40, 0x18, 0x81, 0x1c, 0x40, 0x20, + 0x2a, 0x1c, 0xff, 0xf7, 0x1a, 0xff, 0x60, 0x69, + 0x40, 0x19, 0x60, 0x61, 0xf8, 0x78, 0xc0, 0x43, + 0xf8, 0x70, 0x00, 0x2e, 0x21, 0xd0, 0x1e, 0x4d, + 0x28, 0x68, 0x00, 0x06, 0x00, 0x0e, 0xff, 0xf7, + 0xf2, 0xfe, 0x00, 0x09, 0x01, 0xd2, 0x01, 0x20, + 0x00, 0xe0, 0x00, 0x20, 0x29, 0x68, 0x01, 0x22, + 0x00, 0x29, 0x00, 0xd0, 0x00, 0x22, 0x90, 0x42, + 0x0f, 0xd0, 0x08, 0x20, 0x48, 0x40, 0x28, 0x60, + 0x00, 0x06, 0x00, 0x0e, 0xff, 0xf7, 0xdf, 0xfe, + 0x40, 0x08, 0xa8, 0xd2, 0x0d, 0x20, 0xff, 0xf7, + 0xda, 0xfe, 0xed, 0x09, 0x00, 0x44, 0x02, 0x40, + 0x08, 0x00, 0xd2, 0x38, 0xe7, 0xa1, 0xe7, 0x0d, + 0x4c, 0xb9, 0x78, 0x20, 0x68, 0x02, 0x30, 0x00, + 0x06, 0x00, 0x0e, 0xff, 0xf7, 0xc6, 0xfe, 0x22, + 0x68, 0x03, 0x20, 0x00, 0x2a, 0x00, 0xd0, 0x0b, + 0x20, 0xf9, 0x78, 0x40, 0x26, 0x00, 0x29, 0x00, + 0xd1, 0x00, 0x26, 0x30, 0x43, 0x01, 0x06, 0x09, + 0x0e, 0x10, 0x06, 0x00, 0x0e, 0xff, 0xf7, 0xb5, + 0xfe, 0x87, 0xe7, 0x90, 0xdf, 0x03, 0x20, 0xcc, + 0x69, 0x03, 0x20, 0x90, 0xde, 0x03, 0x20, 0xf0, + 0xb5, 0x1e, 0x48, 0xc7, 0x1d, 0xff, 0x37, 0x0a, + 0x37, 0x39, 0x7b, 0xba, 0x78, 0x91, 0x42, 0x00, + 0xdb, 0x11, 0x1c, 0x0c, 0x06, 0x24, 0x0e, 0xc6, + 0x1d, 0xf9, 0x36, 0x40, 0x20, 0x22, 0x1c, 0xb1, + 0x69, 0xff, 0xf7, 0xab, 0xfe, 0x16, 0x4d, 0x28, + 0x68, 0x02, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x21, + 0x1c, 0xff, 0xf7, 0x93, 0xfe, 0x2a, 0x68, 0x07, + 0x20, 0x00, 0x2a, 0x00, 0xd0, 0x0f, 0x20, 0xfb, + 0x7b, 0x40, 0x21, 0x00, 0x2b, 0x00, 0xd1, 0x00, + 0x21, 0x08, 0x43, 0x01, 0x06, 0x09, 0x0e, 0x10, + 0x06, 0x00, 0x0e, 0xff, 0xf7, 0x82, 0xfe, 0xb0, + 0x69, 0x00, 0x19, 0xb0, 0x61, 0x38, 0x7b, 0x00, + 0x1b, 0x38, 0x73, 0x39, 0x7b, 0x01, 0x20, 0x00, + 0x29, 0x02, 0xd1, 0xb9, 0x78, 0xa1, 0x42, 0x00, + 0xd0, 0x00, 0x20, 0x78, 0x73, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xde, 0x03, 0x20, 0xcc, + 0x69, 0x03, 0x20, 0xf0, 0xb5, 0x62, 0x4c, 0x20, + 0x68, 0x03, 0x30, 0x00, 0x06, 0x00, 0x0e, 0xff, + 0xf7, 0x6c, 0xfe, 0xc0, 0x07, 0xc0, 0x0f, 0x03, + 0x26, 0x40, 0x25, 0x00, 0x28, 0x5d, 0x4f, 0x03, + 0xd0, 0xf8, 0x7b, 0xc0, 0x43, 0xf8, 0x73, 0x53, + 0xe0, 0x20, 0x68, 0x00, 0x06, 0x00, 0x0e, 0xff, + 0xf7, 0x5c, 0xfe, 0x80, 0x09, 0xed, 0x09, 0x00, + 0x45, 0x02, 0x4c, 0xd2, 0x0e, 0x20, 0xff, 0xf7, + 0x57, 0xfe, 0xc1, 0x07, 0xc9, 0x0f, 0x20, 0x68, + 0x01, 0x22, 0x00, 0x28, 0x00, 0xd1, 0x00, 0x22, + 0x91, 0x42, 0x32, 0xd0, 0x02, 0x30, 0x00, 0x06, + 0x00, 0x0e, 0xb9, 0x78, 0xff, 0xf7, 0x40, 0xfe, + 0x20, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x0b, 0x26, + 0xfa, 0x78, 0x29, 0x1c, 0x00, 0x2a, 0x00, 0xd1, + 0x00, 0x21, 0x31, 0x43, 0x09, 0x06, 0x09, 0x0e, + 0x00, 0x06, 0x00, 0x0e, 0xff, 0xf7, 0x30, 0xfe, + 0x20, 0x68, 0x08, 0x23, 0x58, 0x40, 0x20, 0x60, + 0x02, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x21, + 0xff, 0xf7, 0x26, 0xfe, 0x22, 0x68, 0x07, 0x20, + 0x00, 0x2a, 0x00, 0xd0, 0x0f, 0x20, 0xf9, 0x7b, + 0x00, 0x29, 0x00, 0xd1, 0x00, 0x25, 0x28, 0x43, + 0x01, 0x06, 0x09, 0x0e, 0x10, 0x06, 0x00, 0x0e, + 0xff, 0xf7, 0x16, 0xfe, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x06, 0x00, 0x0e, 0xff, 0xf7, + 0x17, 0xfe, 0x01, 0x23, 0x18, 0x43, 0x01, 0x06, + 0x20, 0x68, 0x09, 0x0e, 0x00, 0x06, 0x00, 0x0e, + 0xff, 0xf7, 0x06, 0xfe, 0xee, 0xe7, 0x79, 0x7b, + 0x30, 0x48, 0x00, 0x29, 0x02, 0xd1, 0x39, 0x7b, + 0x00, 0x29, 0x02, 0xd0, 0xff, 0xf7, 0x4e, 0xff, + 0xe4, 0xe7, 0x41, 0x78, 0x00, 0x29, 0x05, 0xd0, + 0x07, 0x20, 0xff, 0xf7, 0xf5, 0xfd, 0x29, 0x49, + 0x00, 0x20, 0x48, 0x70, 0xb8, 0x7b, 0x00, 0x28, + 0x13, 0xd0, 0x00, 0x20, 0xb8, 0x73, 0x20, 0x68, + 0x08, 0x23, 0x58, 0x40, 0x20, 0x60, 0x00, 0x06, + 0x00, 0x0e, 0xff, 0xf7, 0xed, 0xfd, 0x40, 0x08, + 0xcc, 0xd2, 0x0d, 0x20, 0xff, 0xf7, 0xe8, 0xfd, + 0x40, 0x08, 0xc7, 0xd2, 0xff, 0xf7, 0x42, 0xfe, + 0xc4, 0xe7, 0x20, 0x68, 0x08, 0x23, 0x58, 0x40, + 0x20, 0x60, 0x02, 0x30, 0x00, 0x06, 0x00, 0x0e, + 0xed, 0x09, 0x00, 0x46, 0x02, 0xb9, 0x78, 0xff, + 0xf7, 0xd1, 0xfd, 0x20, 0x68, 0x00, 0x28, 0x00, + 0xd0, 0x0b, 0x26, 0xfa, 0x78, 0x29, 0x1c, 0x00, + 0x2a, 0x00, 0xd1, 0x00, 0x21, 0x31, 0x43, 0x09, + 0x06, 0x09, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0xff, + 0xf7, 0xc1, 0xfd, 0x20, 0x68, 0x08, 0x23, 0x58, + 0x40, 0x20, 0x60, 0x02, 0x30, 0x00, 0x06, 0x00, + 0x0e, 0xb9, 0x78, 0xff, 0xf7, 0xb7, 0xfd, 0x22, + 0x68, 0x0b, 0x20, 0x00, 0x2a, 0x00, 0xd0, 0x03, + 0x20, 0xf9, 0x78, 0x00, 0x29, 0x00, 0xd1, 0x00, + 0x25, 0x28, 0x43, 0x01, 0x06, 0x09, 0x0e, 0x10, + 0x06, 0x00, 0x0e, 0xff, 0xf7, 0xa7, 0xfd, 0x8f, + 0xe7, 0xcc, 0x69, 0x03, 0x20, 0xa0, 0xdf, 0x03, + 0x20, 0x90, 0xde, 0x03, 0x20, 0x01, 0x49, 0x48, + 0x70, 0x70, 0x47, 0x00, 0x00, 0x90, 0xde, 0x03, + 0x20, 0xb0, 0xb5, 0x27, 0x4a, 0x00, 0x23, 0xd7, + 0x1d, 0xff, 0x37, 0x0a, 0x37, 0x7b, 0x73, 0x01, + 0x23, 0x00, 0x29, 0x39, 0x73, 0x00, 0xd0, 0x00, + 0x23, 0x19, 0x06, 0x09, 0x0e, 0xb9, 0x73, 0x39, + 0xd0, 0x20, 0x4c, 0x08, 0x23, 0x20, 0x68, 0x58, + 0x40, 0x20, 0x60, 0x02, 0x30, 0x00, 0x06, 0x00, + 0x0e, 0xb9, 0x78, 0xff, 0xf7, 0x7f, 0xfd, 0x20, + 0x68, 0x03, 0x21, 0x00, 0x28, 0x00, 0xd0, 0x0b, + 0x21, 0xfb, 0x78, 0x40, 0x25, 0x2a, 0x1c, 0x00, + 0x2b, 0x00, 0xd1, 0x00, 0x22, 0x11, 0x43, 0x09, + 0x06, 0x09, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0xff, + 0xf7, 0x6d, 0xfd, 0x20, 0x68, 0x08, 0x23, 0x58, + 0x40, 0x20, 0x60, 0x02, 0x30, 0x00, 0x06, 0x00, + 0x0e, 0x00, 0x21, 0xff, 0xf7, 0x63, 0xfd, 0x22, + 0x68, 0x0f, 0x20, 0x00, 0x2a, 0x00, 0xd0, 0x07, + 0x20, 0xf9, 0x7b, 0x00, 0x29, 0x00, 0xd1, 0x00, + 0x25, 0x28, 0x43, 0x01, 0x06, 0x09, 0x0e, 0x10, + 0x06, 0x00, 0x0e, 0xed, 0x09, 0x00, 0x47, 0x02, + 0xff, 0xf7, 0x53, 0xfd, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xd1, 0x1d, 0xf9, 0x31, 0x88, 0x61, + 0xff, 0xf7, 0x9d, 0xfe, 0xf6, 0xe7, 0x90, 0xde, + 0x03, 0x20, 0xcc, 0x69, 0x03, 0x20, 0x00, 0xb5, + 0x07, 0x48, 0x00, 0x68, 0x00, 0x06, 0x00, 0x0e, + 0xff, 0xf7, 0x47, 0xfd, 0xc0, 0x08, 0x03, 0xd3, + 0xff, 0xf7, 0xcf, 0xfe, 0x08, 0xbc, 0x18, 0x47, + 0xff, 0xf7, 0x9d, 0xfd, 0xfa, 0xe7, 0xcc, 0x69, + 0x03, 0x20, 0x00, 0xb5, 0x07, 0x48, 0x27, 0x21, + 0x00, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x2f, 0x21, + 0x09, 0x06, 0x09, 0x0e, 0x00, 0x06, 0x00, 0x0e, + 0xff, 0xf7, 0x27, 0xfd, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xcc, 0x69, 0x03, 0x20, 0xf8, 0xb5, + 0x52, 0x4d, 0x07, 0x1c, 0x28, 0x1c, 0xff, 0x22, + 0x00, 0x21, 0x21, 0x32, 0xdc, 0xf7, 0x1f, 0xf8, + 0x68, 0x46, 0x00, 0xf0, 0x2c, 0xfa, 0xec, 0x1d, + 0xff, 0x34, 0xc0, 0x79, 0x0a, 0x34, 0x00, 0x2f, + 0x4b, 0x4e, 0xa0, 0x70, 0x48, 0xd1, 0x00, 0x21, + 0x07, 0x20, 0xff, 0xf7, 0x0a, 0xfd, 0x00, 0x21, + 0x00, 0x20, 0xff, 0xf7, 0x06, 0xfd, 0x00, 0x21, + 0x08, 0x20, 0xff, 0xf7, 0x02, 0xfd, 0x01, 0x21, + 0x0d, 0x20, 0xff, 0xf7, 0xfe, 0xfc, 0x0e, 0x20, + 0xff, 0xf7, 0x03, 0xfd, 0x40, 0x08, 0x01, 0xd3, + 0x08, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x08, 0x23, + 0x58, 0x40, 0x30, 0x60, 0x01, 0x30, 0x00, 0x06, + 0x00, 0x0e, 0x40, 0x21, 0x37, 0x1c, 0xff, 0xf7, + 0xec, 0xfc, 0x38, 0x68, 0x08, 0x23, 0x58, 0x40, + 0x38, 0x60, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, + 0x40, 0x21, 0xff, 0xf7, 0xe2, 0xfc, 0xa1, 0x78, + 0x38, 0x68, 0x02, 0x30, 0x00, 0x06, 0x00, 0x0e, + 0xff, 0xf7, 0xdb, 0xfc, 0x3a, 0x68, 0x03, 0x20, + 0x00, 0x2a, 0x00, 0xd0, 0x0b, 0x20, 0xed, 0x09, + 0x00, 0x48, 0x02, 0xe3, 0x78, 0x40, 0x21, 0x00, + 0x2b, 0x00, 0xd1, 0x00, 0x21, 0x08, 0x43, 0x01, + 0x06, 0x09, 0x0e, 0x10, 0x06, 0x00, 0x0e, 0xff, + 0xf7, 0xca, 0xfc, 0x01, 0x21, 0x05, 0x20, 0xff, + 0xf7, 0xc6, 0xfc, 0x3f, 0xe0, 0x0e, 0x20, 0xff, + 0xf7, 0xca, 0xfc, 0x40, 0x08, 0x01, 0xd3, 0x08, + 0x20, 0x00, 0xe0, 0x00, 0x20, 0x30, 0x60, 0x00, + 0x20, 0xff, 0xf7, 0xc1, 0xfc, 0x00, 0x09, 0x23, + 0xd3, 0x08, 0x20, 0xff, 0xf7, 0xbc, 0xfc, 0x00, + 0x09, 0x1e, 0xd2, 0x00, 0x20, 0xff, 0xf7, 0xb7, + 0xfc, 0x40, 0x08, 0x11, 0xd2, 0x08, 0x20, 0xff, + 0xf7, 0xb2, 0xfc, 0x40, 0x08, 0x09, 0xd2, 0x0e, + 0x20, 0xff, 0xf7, 0xad, 0xfc, 0x40, 0x08, 0x01, + 0xd3, 0x08, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x30, + 0x60, 0x18, 0xe0, 0x00, 0x20, 0x30, 0x60, 0x15, + 0xe0, 0x08, 0x20, 0xff, 0xf7, 0xa0, 0xfc, 0x40, + 0x08, 0x10, 0xd2, 0x08, 0x20, 0x30, 0x60, 0x0d, + 0xe0, 0x30, 0x68, 0x08, 0x23, 0x58, 0x40, 0x30, + 0x60, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x40, + 0x21, 0xff, 0xf7, 0x89, 0xfc, 0x30, 0x68, 0x08, + 0x23, 0x58, 0x40, 0x30, 0x60, 0x01, 0x20, 0x28, + 0x70, 0x07, 0x20, 0xff, 0xf7, 0x88, 0xfc, 0xf8, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x90, + 0xde, 0x03, 0x20, 0xcc, 0x69, 0x03, 0x20, 0xf0, + 0xb5, 0x07, 0x1c, 0x0d, 0x20, 0x00, 0x24, 0x0d, + 0x1c, 0xff, 0xf7, 0x79, 0xfc, 0x39, 0x7d, 0x08, + 0x40, 0x45, 0xd0, 0x0d, 0x20, 0xff, 0xf7, 0x6b, + 0xfc, 0x78, 0x7c, 0x03, 0x30, 0x00, 0x06, 0x00, + 0x0e, 0xff, 0xf7, 0x6d, 0xfc, 0x41, 0x08, 0x29, + 0xd3, 0x01, 0x21, 0x0a, 0x1c, 0x00, 0x09, 0x00, + 0xd3, 0x00, 0x22, 0xf8, 0x7c, 0x00, 0x28, 0x00, + 0xd0, 0x00, 0x21, 0x8a, 0x42, 0x1e, 0xd1, 0xc0, + 0x43, 0xed, 0x09, 0x00, 0x49, 0x02, 0xf8, 0x74, + 0x78, 0x7c, 0x04, 0x30, 0x00, 0x06, 0x00, 0x0e, + 0xff, 0xf7, 0x58, 0xfc, 0x39, 0x7c, 0x15, 0x4b, + 0x08, 0x1a, 0x06, 0x06, 0xb8, 0x69, 0x36, 0x0e, + 0x81, 0x19, 0x99, 0x42, 0x07, 0xd8, 0x41, 0x19, + 0xb8, 0x7c, 0x32, 0x1c, 0xff, 0xf7, 0x64, 0xfc, + 0xb8, 0x69, 0x80, 0x19, 0xb8, 0x61, 0x38, 0x7c, + 0xb0, 0x42, 0x02, 0xd9, 0x00, 0x20, 0xbc, 0x69, + 0xb8, 0x61, 0x39, 0x7c, 0x78, 0x7c, 0x02, 0x30, + 0x00, 0x06, 0x00, 0x0e, 0xff, 0xf7, 0x32, 0xfc, + 0xf9, 0x7c, 0x43, 0x20, 0x00, 0x29, 0x00, 0xdc, + 0x03, 0x20, 0x01, 0x06, 0x09, 0x0e, 0x78, 0x7c, + 0xff, 0xf7, 0x28, 0xfc, 0x20, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x10, 0x10, 0x00, 0x00, + 0x00, 0xb5, 0x0a, 0x1c, 0x20, 0x21, 0x40, 0x7c, + 0xff, 0xf7, 0x50, 0xfc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x40, 0x7c, 0xff, 0xf7, 0x1e, 0xfc, + 0x80, 0x09, 0x02, 0xd3, 0x01, 0x20, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0xf0, 0xb5, + 0x07, 0x1c, 0x0d, 0x20, 0x14, 0x1c, 0x0d, 0x1c, + 0xff, 0xf7, 0x10, 0xfc, 0x39, 0x7d, 0x08, 0x40, + 0x01, 0x26, 0x00, 0x28, 0x08, 0xd1, 0x78, 0x7c, + 0xff, 0xf7, 0x08, 0xfc, 0x40, 0x08, 0x03, 0xd3, + 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x0d, 0x20, 0xff, 0xf7, 0xff, 0xfb, 0x39, 0x7d, + 0x08, 0x40, 0x16, 0xd0, 0x0d, 0x20, 0xff, 0xf7, + 0xf1, 0xfb, 0x78, 0x7c, 0x03, 0x30, 0x00, 0x06, + 0x00, 0x0e, 0xff, 0xf7, 0xf3, 0xfb, 0x40, 0x08, + 0x2b, 0xd3, 0xf8, 0x7c, 0xc0, 0x43, 0xf8, 0x74, + 0x39, 0x7c, 0xb8, 0x69, 0x40, 0x18, 0xa0, 0x42, + 0x02, 0xd9, 0x00, 0x20, 0xb8, 0x61, 0xe0, 0xe7, + 0xb8, 0x61, 0xb8, 0x69, 0x39, 0x7c, 0x24, 0x1a, + 0x8c, 0x42, 0x00, 0xd2, 0xed, 0x09, 0x00, 0x4a, + 0x02, 0x21, 0x1c, 0x0c, 0x1c, 0x41, 0x19, 0xb8, + 0x7c, 0x22, 0x1c, 0xff, 0xf7, 0xe1, 0xfb, 0x78, + 0x7c, 0x02, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x21, + 0x06, 0x09, 0x0e, 0xff, 0xf7, 0xc9, 0xfb, 0xf9, + 0x7c, 0x47, 0x20, 0x00, 0x29, 0x00, 0xdc, 0x07, + 0x20, 0x01, 0x06, 0x09, 0x0e, 0x78, 0x7c, 0xff, + 0xf7, 0xbf, 0xfb, 0x30, 0x1c, 0xbf, 0xe7, 0xf9, + 0x7c, 0x47, 0x20, 0x00, 0x29, 0x00, 0xdc, 0x07, + 0x20, 0x01, 0x06, 0x09, 0x0e, 0x78, 0x7c, 0xff, + 0xf7, 0xb3, 0xfb, 0x30, 0x1c, 0xb3, 0xe7, 0xf0, + 0xb5, 0x07, 0x1c, 0x08, 0x1c, 0x14, 0x1c, 0x1d, + 0x1c, 0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0x3e, + 0x1c, 0x0e, 0xc6, 0x0e, 0xc6, 0x08, 0xc6, 0x01, + 0x22, 0x3a, 0x60, 0x11, 0x1c, 0x03, 0x0a, 0x38, + 0x71, 0x00, 0xd3, 0x00, 0x21, 0xb9, 0x60, 0xfc, + 0x60, 0x3d, 0x74, 0x45, 0x06, 0x6d, 0x0e, 0xaa, + 0x40, 0x00, 0x01, 0x40, 0x06, 0x40, 0x0e, 0x3a, + 0x75, 0x78, 0x74, 0x03, 0x2c, 0x05, 0xd1, 0x60, + 0x20, 0x00, 0x29, 0x00, 0xd0, 0x70, 0x20, 0xb8, + 0x74, 0x04, 0xe0, 0x80, 0x20, 0x00, 0x29, 0x00, + 0xd0, 0xc0, 0x20, 0xb8, 0x74, 0x00, 0x24, 0xfc, + 0x74, 0x78, 0x7c, 0x04, 0x30, 0x00, 0x06, 0x00, + 0x0e, 0x00, 0x21, 0xff, 0xf7, 0x7d, 0xfb, 0xb9, + 0x7c, 0x78, 0x7c, 0x01, 0x30, 0x00, 0x06, 0x00, + 0x0e, 0xff, 0xf7, 0x76, 0xfb, 0xb8, 0x68, 0x00, + 0x28, 0x00, 0xd0, 0x3c, 0x7c, 0x78, 0x7c, 0x21, + 0x06, 0x09, 0x0e, 0x02, 0x30, 0x00, 0x06, 0x00, + 0x0e, 0xff, 0xf7, 0x6a, 0xfb, 0x78, 0x7c, 0x00, + 0x21, 0xff, 0xf7, 0x66, 0xfb, 0x39, 0x7d, 0x08, + 0x1c, 0xfe, 0xf7, 0x68, 0xff, 0xb8, 0x68, 0x00, + 0x28, 0x05, 0xd1, 0xf9, 0x7c, 0x46, 0x20, 0x00, + 0x29, 0x06, 0xdc, 0x06, 0x20, 0x04, 0xe0, 0xed, + 0x09, 0x00, 0x4b, 0x02, 0xf9, 0x7c, 0x43, 0x20, + 0x00, 0x29, 0x00, 0xdc, 0x03, 0x20, 0x01, 0x06, + 0x09, 0x0e, 0x78, 0x7c, 0xff, 0xf7, 0x4f, 0xfb, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0x01, 0x68, 0x00, 0x29, 0x0c, 0xd0, 0x81, 0x68, + 0x00, 0x29, 0x09, 0xd1, 0xc2, 0x7c, 0x46, 0x21, + 0x00, 0x2a, 0x00, 0xdc, 0x06, 0x21, 0x09, 0x06, + 0x09, 0x0e, 0x40, 0x7c, 0xff, 0xf7, 0x3b, 0xfb, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, + 0x00, 0x68, 0x00, 0x28, 0x0c, 0xd0, 0x38, 0x7d, + 0xfe, 0xf7, 0x48, 0xff, 0x78, 0x7c, 0x00, 0x21, + 0xff, 0xf7, 0x2d, 0xfb, 0x00, 0x21, 0x00, 0x22, + 0x00, 0x23, 0x0e, 0xc7, 0x0e, 0xc7, 0x08, 0xc7, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x88, 0xb5, + 0x19, 0x48, 0x19, 0x4f, 0x43, 0x7a, 0x01, 0x7a, + 0x1b, 0x02, 0x19, 0x43, 0x79, 0x81, 0xc3, 0x79, + 0x80, 0x79, 0x1b, 0x02, 0x18, 0x43, 0xb8, 0x81, + 0x15, 0x48, 0x00, 0x68, 0x00, 0x28, 0x0c, 0xd0, + 0x78, 0x89, 0x01, 0x23, 0x18, 0x43, 0x78, 0x81, + 0x01, 0x20, 0x78, 0x74, 0x20, 0x21, 0xf9, 0x71, + 0xe0, 0x21, 0x39, 0x71, 0x78, 0x71, 0xb8, 0x71, + 0x07, 0xe0, 0x02, 0x20, 0x78, 0x74, 0x40, 0x20, + 0xf8, 0x71, 0xff, 0x20, 0x38, 0x71, 0x78, 0x71, + 0xb8, 0x71, 0x6a, 0x46, 0x03, 0x21, 0x00, 0x20, + 0xff, 0xf7, 0x15, 0xf8, 0x00, 0xa8, 0x00, 0x78, + 0x02, 0x28, 0x01, 0xdc, 0x00, 0x20, 0x38, 0x74, + 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x30, 0x7c, + 0x00, 0x00, 0xd0, 0x69, 0x03, 0x20, 0xc0, 0x69, + 0x03, 0x20, 0x90, 0xb5, 0x07, 0x4c, 0x07, 0x1c, + 0x12, 0x22, 0x20, 0x1c, 0x04, 0x49, 0xdb, 0xf7, + 0x70, 0xfe, 0x20, 0x78, 0x38, 0x70, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, 0x69, + 0x03, 0x20, 0xed, 0x09, 0x00, 0x4c, 0x02, 0xb0, + 0xdf, 0x03, 0x20, 0xf3, 0xb5, 0x82, 0xb0, 0x01, + 0x38, 0x05, 0x06, 0x45, 0x48, 0x2d, 0x0e, 0x40, + 0x7c, 0x00, 0x27, 0xa8, 0x42, 0x65, 0xdd, 0x43, + 0x48, 0x44, 0x4e, 0x00, 0x68, 0x44, 0x4c, 0x00, + 0x28, 0x08, 0xd0, 0xf1, 0x1d, 0xff, 0x31, 0x09, + 0x22, 0x20, 0x1c, 0x6b, 0x31, 0xdb, 0xf7, 0x4f, + 0xfe, 0x01, 0x25, 0x12, 0xe0, 0x01, 0x2d, 0x08, + 0xdb, 0x09, 0x22, 0x20, 0x1c, 0x31, 0x1c, 0xdb, + 0xf7, 0x46, 0xfe, 0x68, 0x1c, 0x60, 0x71, 0x00, + 0x25, 0x07, 0xe0, 0xff, 0x20, 0x72, 0x30, 0x68, + 0x43, 0x81, 0x19, 0x09, 0x22, 0x20, 0x1c, 0xdb, + 0xf7, 0x3a, 0xfe, 0x34, 0x48, 0x80, 0x21, 0xc1, + 0x71, 0x64, 0x21, 0x01, 0x72, 0x47, 0x80, 0x00, + 0x79, 0x00, 0x27, 0x00, 0x24, 0x00, 0x28, 0x4b, + 0xd9, 0xff, 0x20, 0x72, 0x30, 0x68, 0x43, 0x80, + 0x19, 0x01, 0x90, 0xb4, 0x21, 0x61, 0x43, 0x01, + 0x98, 0x2b, 0x4d, 0x40, 0x18, 0x39, 0x01, 0xc9, + 0x1b, 0x49, 0x00, 0x46, 0x18, 0x00, 0x90, 0x68, + 0x88, 0xf1, 0x1d, 0x02, 0x31, 0x09, 0x22, 0x40, + 0x19, 0x09, 0x30, 0xdb, 0xf7, 0x18, 0xfe, 0x68, + 0x88, 0x09, 0x30, 0x68, 0x80, 0x70, 0x7b, 0x00, + 0x25, 0x00, 0x28, 0x15, 0xd9, 0xe8, 0x00, 0x40, + 0x1b, 0x30, 0x18, 0x1e, 0x4a, 0xc1, 0x1d, 0x50, + 0x88, 0x0b, 0x31, 0x80, 0x18, 0x07, 0x22, 0x09, + 0x30, 0xdb, 0xf7, 0x05, 0xfe, 0x1a, 0x4a, 0x50, + 0x88, 0x07, 0x30, 0x50, 0x80, 0x02, 0x2d, 0x03, + 0xd0, 0x70, 0x7b, 0x01, 0x35, 0xa8, 0x42, 0xe9, + 0xd8, 0x05, 0x2f, 0x03, 0xd1, 0x00, 0x27, 0x01, + 0x34, 0x0e, 0xe0, 0x1c, 0xe0, 0x01, 0x37, 0x39, + 0x01, 0xc9, 0x1b, 0x00, 0x98, 0x49, 0x00, 0x40, + 0x18, 0xc1, 0x7a, 0xa1, 0x42, 0x02, 0xd1, 0x40, + 0x7a, 0x00, 0x28, 0x01, 0xd1, 0xed, 0x09, 0x00, + 0x4d, 0x02, 0x00, 0x27, 0x01, 0x34, 0x0b, 0x4d, + 0x28, 0x79, 0xa0, 0x42, 0xb8, 0xd8, 0x09, 0x48, + 0x41, 0x88, 0x09, 0x31, 0x41, 0x80, 0x41, 0x88, + 0x03, 0x9a, 0x11, 0x70, 0x04, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xf9, 0xe7, + 0xd0, 0x69, 0x03, 0x20, 0xc0, 0x69, 0x03, 0x20, + 0xe4, 0x69, 0x03, 0x20, 0xc4, 0xdf, 0x03, 0x20, + 0xb0, 0xb5, 0x01, 0x38, 0x00, 0x06, 0x00, 0x0e, + 0x0c, 0x1c, 0x18, 0x49, 0x17, 0x1c, 0x49, 0x7c, + 0x81, 0x42, 0x28, 0xdd, 0x16, 0x49, 0x09, 0x68, + 0x00, 0x29, 0x01, 0xd0, 0x01, 0x20, 0x02, 0xe0, + 0x01, 0x28, 0x00, 0xdb, 0x00, 0x20, 0xff, 0x23, + 0x72, 0x33, 0x58, 0x43, 0x11, 0x49, 0x12, 0x4d, + 0x40, 0x18, 0xb4, 0x21, 0x61, 0x43, 0x40, 0x18, + 0x39, 0x01, 0xc9, 0x1b, 0x49, 0x00, 0x40, 0x18, + 0xc1, 0x1d, 0x02, 0x31, 0x09, 0x22, 0x28, 0x1c, + 0xdb, 0xf7, 0xa8, 0xfd, 0x28, 0x78, 0x00, 0x28, + 0x09, 0xd0, 0xa8, 0x78, 0xa0, 0x42, 0x06, 0xd1, + 0xe8, 0x78, 0xb8, 0x42, 0x03, 0xd1, 0x28, 0x1c, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, + 0xfa, 0xe7, 0x00, 0x00, 0xd0, 0x69, 0x03, 0x20, + 0xc0, 0x69, 0x03, 0x20, 0xe4, 0x69, 0x03, 0x20, + 0x0c, 0xe0, 0x03, 0x20, 0x90, 0xb4, 0x01, 0x38, + 0x00, 0x06, 0x00, 0x0e, 0x1f, 0x1c, 0x1b, 0x4b, + 0x5b, 0x7c, 0x83, 0x42, 0x30, 0xdd, 0x1a, 0x4b, + 0x1b, 0x68, 0x00, 0x2b, 0x01, 0xd0, 0x01, 0x20, + 0x02, 0xe0, 0x01, 0x28, 0x00, 0xdb, 0x00, 0x20, + 0xff, 0x23, 0x72, 0x33, 0x58, 0x43, 0x15, 0x4b, + 0xc0, 0x18, 0xb4, 0x23, 0x4b, 0x43, 0xc0, 0x18, + 0x13, 0x01, 0x9b, 0x1a, 0x5b, 0x00, 0xc0, 0x18, + 0xc3, 0x7a, 0x8b, 0x42, 0x18, 0xd1, 0x01, 0x7b, + 0x91, 0x42, 0x15, 0xd1, 0x42, 0x7b, 0x00, 0x21, + 0xed, 0x09, 0x00, 0x4e, 0x02, 0x00, 0x2a, 0x11, + 0xd9, 0xcb, 0x00, 0x5b, 0x1a, 0xc3, 0x18, 0x9c, + 0x7c, 0x00, 0x2c, 0x08, 0xd0, 0x1b, 0x7d, 0xbb, + 0x42, 0x05, 0xd1, 0xcb, 0x00, 0x59, 0x1a, 0x40, + 0x18, 0x12, 0x30, 0x90, 0xbc, 0x70, 0x47, 0x01, + 0x31, 0x8a, 0x42, 0xed, 0xd8, 0x00, 0x20, 0xf8, + 0xe7, 0xd0, 0x69, 0x03, 0x20, 0xc0, 0x69, 0x03, + 0x20, 0xe4, 0x69, 0x03, 0x20, 0xb0, 0xb5, 0x83, + 0xb0, 0x07, 0x1c, 0x40, 0x78, 0x00, 0x24, 0x0d, + 0x28, 0x68, 0xd2, 0x02, 0xa3, 0x1b, 0x5c, 0x5b, + 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x07, 0x75, 0x74, + 0xae, 0x74, 0xd8, 0xd7, 0x74, 0xd6, 0xd5, 0xd4, + 0xd3, 0x74, 0x00, 0x38, 0x78, 0x80, 0x28, 0x03, + 0xd0, 0x81, 0x28, 0x01, 0xd0, 0x82, 0x28, 0x65, + 0xd1, 0xb9, 0x78, 0xfb, 0x78, 0x1b, 0x02, 0x19, + 0x43, 0x60, 0xd1, 0xb9, 0x79, 0xfb, 0x79, 0x1b, + 0x02, 0x19, 0x43, 0x02, 0x29, 0x5a, 0xd1, 0x00, + 0x07, 0x00, 0x0f, 0x00, 0x25, 0x00, 0x28, 0x21, + 0xd0, 0x01, 0x28, 0x44, 0xd0, 0x02, 0x28, 0x1c, + 0xd1, 0x7b, 0x79, 0x38, 0x79, 0x01, 0xa9, 0x1b, + 0x02, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x00, + 0xa8, 0x00, 0x78, 0xff, 0xf7, 0xf1, 0xf8, 0x00, + 0x28, 0x0f, 0xd0, 0x02, 0xab, 0x1d, 0x80, 0x02, + 0x98, 0x01, 0xa9, 0x09, 0x78, 0x40, 0x08, 0x40, + 0x00, 0xc9, 0x07, 0xc9, 0x0f, 0x08, 0x43, 0x02, + 0x90, 0x02, 0xa8, 0x02, 0x21, 0xff, 0xf7, 0xdc, + 0xfb, 0x01, 0x24, 0xad, 0xe0, 0x38, 0x79, 0x7b, + 0x79, 0x1b, 0x02, 0x18, 0x43, 0xf9, 0xd1, 0x69, + 0x46, 0x01, 0xa8, 0xfe, 0xf7, 0xfd, 0xff, 0x00, + 0x28, 0x17, 0xd0, 0x02, 0xab, 0x1d, 0x80, 0x02, + 0x98, 0x01, 0xa9, 0x09, 0x78, 0x40, 0x08, 0x40, + 0x00, 0xc9, 0x07, 0xc9, 0x0f, 0x08, 0x43, 0x00, + 0xa9, 0x09, 0x78, 0xed, 0x09, 0x00, 0x4f, 0x02, + 0x02, 0x23, 0x98, 0x43, 0xc9, 0x07, 0xc9, 0x0f, + 0x49, 0x00, 0x08, 0x43, 0x02, 0x90, 0x02, 0xa8, + 0x02, 0x21, 0xff, 0xf7, 0xb8, 0xfb, 0x01, 0x24, + 0xda, 0xe7, 0xa1, 0xe0, 0x38, 0x79, 0x7b, 0x79, + 0x1b, 0x02, 0x18, 0x43, 0xd4, 0xd1, 0x02, 0x98, + 0x00, 0x0c, 0x00, 0x04, 0x02, 0x90, 0x02, 0xa8, + 0x02, 0x21, 0xff, 0xf7, 0xa8, 0xfb, 0x01, 0x24, + 0xca, 0xe7, 0xee, 0xe0, 0x38, 0x78, 0x00, 0x28, + 0x03, 0xd0, 0x01, 0x28, 0x01, 0xd0, 0x02, 0x28, + 0x71, 0xd1, 0xb9, 0x79, 0xfb, 0x79, 0x1b, 0x02, + 0x19, 0x43, 0x6c, 0xd1, 0xb9, 0x78, 0xfb, 0x78, + 0x1b, 0x02, 0x19, 0x43, 0x12, 0xd0, 0x01, 0x29, + 0x65, 0xd1, 0x00, 0x07, 0x63, 0xd1, 0x38, 0x79, + 0x7b, 0x79, 0x1b, 0x02, 0x18, 0x43, 0x5e, 0xd1, + 0xfe, 0xf7, 0xa1, 0xff, 0x00, 0x28, 0x73, 0xd0, + 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x83, 0xfb, + 0x01, 0x24, 0xca, 0xe0, 0x00, 0x07, 0x00, 0x0f, + 0x02, 0x28, 0x50, 0xd1, 0x38, 0x79, 0x7b, 0x79, + 0x1b, 0x02, 0x18, 0x43, 0x00, 0x06, 0x00, 0x0e, + 0x00, 0x21, 0xfe, 0xf7, 0xaa, 0xff, 0x00, 0x28, + 0x5e, 0xd0, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, + 0x6e, 0xfb, 0x01, 0x24, 0xb5, 0xe0, 0x38, 0x78, + 0x00, 0x28, 0x03, 0xd0, 0x01, 0x28, 0x01, 0xd0, + 0x02, 0x28, 0x38, 0xd1, 0xb9, 0x79, 0xfb, 0x79, + 0x1b, 0x02, 0x19, 0x43, 0x33, 0xd1, 0xb9, 0x78, + 0xfb, 0x78, 0x1b, 0x02, 0x19, 0x43, 0x19, 0xd0, + 0x01, 0x29, 0x2c, 0xd1, 0x00, 0x07, 0x2a, 0xd1, + 0x38, 0x79, 0x7b, 0x79, 0x1b, 0x02, 0x18, 0x43, + 0x25, 0xd1, 0x01, 0x20, 0xfe, 0xf7, 0x67, 0xff, + 0x00, 0x28, 0x39, 0xd0, 0x00, 0x21, 0x00, 0x20, + 0xff, 0xf7, 0x49, 0xfb, 0x01, 0x24, 0x90, 0xe0, + 0x07, 0xe1, 0xe7, 0xe0, 0xc9, 0xe0, 0xed, 0x09, + 0x00, 0x50, 0x02, 0xaa, 0xe0, 0x36, 0xe0, 0x15, + 0xe0, 0x00, 0x07, 0x00, 0x0f, 0x02, 0x28, 0x10, + 0xd1, 0x38, 0x79, 0x7b, 0x79, 0x1b, 0x02, 0x18, + 0x43, 0x00, 0x06, 0x00, 0x0e, 0x01, 0x21, 0xfe, + 0xf7, 0x6a, 0xff, 0x00, 0x28, 0x1e, 0xd0, 0x00, + 0x21, 0x00, 0x20, 0xff, 0xf7, 0x2e, 0xfb, 0x01, + 0x24, 0x75, 0xe0, 0x91, 0xe0, 0x38, 0x78, 0x00, + 0x28, 0x71, 0xd1, 0x38, 0x79, 0x7b, 0x79, 0x1b, + 0x02, 0x18, 0x43, 0x6c, 0xd1, 0xb8, 0x79, 0xfb, + 0x79, 0x1b, 0x02, 0x18, 0x43, 0x67, 0xd1, 0xb8, + 0x78, 0xfb, 0x78, 0x1b, 0x02, 0x18, 0x43, 0x00, + 0x06, 0x00, 0x0e, 0xff, 0xf7, 0x10, 0xfb, 0x03, + 0x20, 0x7d, 0x49, 0x00, 0xe0, 0xf0, 0xe0, 0x08, + 0x60, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x0d, + 0xfb, 0x01, 0x24, 0x71, 0xe0, 0x38, 0x78, 0x80, + 0x28, 0x51, 0xd1, 0xb8, 0x78, 0xfb, 0x78, 0x1b, + 0x02, 0x18, 0x43, 0x01, 0x0a, 0x09, 0x06, 0x09, + 0x0e, 0x06, 0x29, 0x65, 0xd2, 0x02, 0xa3, 0x5b, + 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0xd9, + 0x03, 0x26, 0x45, 0xd9, 0xd9, 0x00, 0x06, 0x3e, + 0xd1, 0x38, 0x79, 0x7b, 0x79, 0x1b, 0x02, 0x18, + 0x43, 0x39, 0xd1, 0xfb, 0x79, 0xb8, 0x79, 0x1b, + 0x02, 0x18, 0x43, 0x02, 0xab, 0x18, 0x70, 0x02, + 0xa8, 0xff, 0xf7, 0x97, 0xfd, 0x00, 0x28, 0x0f, + 0xd0, 0xfb, 0x79, 0xba, 0x79, 0x02, 0xa9, 0x1b, + 0x02, 0x1a, 0x43, 0x02, 0xab, 0x09, 0x78, 0x1b, + 0x78, 0x9a, 0x42, 0x00, 0xdc, 0x11, 0x1c, 0x09, + 0x06, 0x09, 0x0e, 0xff, 0xf7, 0xd6, 0xfa, 0x01, + 0x24, 0xb2, 0xe0, 0x39, 0x79, 0x7b, 0x79, 0x1b, + 0x02, 0x19, 0x43, 0x18, 0xd1, 0x01, 0x30, 0x00, + 0x06, 0x00, 0x0e, 0x02, 0xa9, 0xff, 0xf7, 0x8b, + 0xfd, 0x00, 0x28, 0x0f, 0xd0, 0xfb, 0x79, 0xba, + 0x79, 0xed, 0x09, 0x00, 0x51, 0x02, 0x02, 0xa9, + 0x1b, 0x02, 0x1a, 0x43, 0x02, 0xab, 0x09, 0x78, + 0x1b, 0x78, 0x9a, 0x42, 0x00, 0xdc, 0x11, 0x1c, + 0x09, 0x06, 0x09, 0x0e, 0xff, 0xf7, 0xb8, 0xfa, + 0x01, 0x24, 0x94, 0xe0, 0x95, 0xe0, 0x01, 0x06, + 0x38, 0x79, 0x7b, 0x79, 0x09, 0x0e, 0x02, 0xaa, + 0x1b, 0x02, 0x18, 0x43, 0xfe, 0xf7, 0x62, 0xfd, + 0x00, 0x28, 0x0f, 0xd0, 0xfb, 0x79, 0xba, 0x79, + 0x02, 0xa9, 0x1b, 0x02, 0x1a, 0x43, 0x02, 0xab, + 0x09, 0x78, 0x1b, 0x78, 0x9a, 0x42, 0x00, 0xdc, + 0x11, 0x1c, 0x09, 0x06, 0x09, 0x0e, 0xff, 0xf7, + 0x9b, 0xfa, 0x01, 0x24, 0x77, 0xe0, 0x78, 0xe0, + 0x38, 0x78, 0x80, 0x28, 0x73, 0xd1, 0xb8, 0x78, + 0xfb, 0x78, 0x1b, 0x02, 0x18, 0x43, 0x6e, 0xd1, + 0x38, 0x79, 0x7b, 0x79, 0x1b, 0x02, 0x18, 0x43, + 0x69, 0xd1, 0xb8, 0x79, 0xfb, 0x79, 0x1b, 0x02, + 0x18, 0x43, 0x01, 0x28, 0x63, 0xd1, 0x02, 0xa8, + 0xfe, 0xf7, 0xe8, 0xfe, 0x00, 0x28, 0x04, 0xd0, + 0x01, 0x21, 0x02, 0xa8, 0xff, 0xf7, 0x7c, 0xfa, + 0x01, 0x24, 0x5a, 0xe0, 0x38, 0x78, 0x00, 0x28, + 0x55, 0xd1, 0x38, 0x79, 0x7b, 0x79, 0x1b, 0x02, + 0x18, 0x43, 0x50, 0xd1, 0xb8, 0x79, 0xfb, 0x79, + 0x1b, 0x02, 0x18, 0x43, 0x4b, 0xd1, 0xb8, 0x78, + 0xfb, 0x78, 0x1b, 0x02, 0x18, 0x43, 0x00, 0x06, + 0x00, 0x0e, 0xfe, 0xf7, 0xd9, 0xfe, 0x00, 0x28, + 0x43, 0xd0, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, + 0x5f, 0xfa, 0x01, 0x24, 0x3d, 0xe0, 0x38, 0x78, + 0x81, 0x28, 0x38, 0xd1, 0xb8, 0x78, 0xfb, 0x78, + 0x1b, 0x02, 0x18, 0x43, 0x33, 0xd1, 0xb8, 0x79, + 0xfb, 0x79, 0x1b, 0x02, 0x18, 0x43, 0x01, 0x28, + 0x2d, 0xd1, 0x38, 0x79, 0x7b, 0x79, 0x02, 0xa9, + 0x1b, 0x02, 0x18, 0x43, 0x00, 0x06, 0x00, 0x0e, + 0xfe, 0xf7, 0x88, 0xff, 0xed, 0x09, 0x00, 0x52, + 0x02, 0x00, 0x28, 0x04, 0xd0, 0x01, 0x21, 0x02, + 0xa8, 0xff, 0xf7, 0x40, 0xfa, 0x01, 0x24, 0x1e, + 0xe0, 0x38, 0x78, 0x01, 0x28, 0x19, 0xd1, 0xb8, + 0x79, 0xfb, 0x79, 0x1b, 0x02, 0x18, 0x43, 0x14, + 0xd1, 0xfb, 0x78, 0xb8, 0x78, 0x1b, 0x02, 0x18, + 0x43, 0x01, 0x06, 0x38, 0x79, 0x7b, 0x79, 0x09, + 0x0e, 0x1b, 0x02, 0x18, 0x43, 0x00, 0x06, 0x00, + 0x0e, 0xfe, 0xf7, 0x84, 0xff, 0x00, 0x28, 0x06, + 0xd0, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x22, + 0xfa, 0x00, 0xe0, 0x00, 0xe0, 0x01, 0x24, 0x20, + 0x1c, 0x03, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xcc, 0xdd, 0x03, 0x20, 0x90, 0xb5, 0x02, + 0x1c, 0x00, 0x20, 0x08, 0x29, 0x36, 0xd1, 0x14, + 0x78, 0x11, 0x1c, 0x60, 0x22, 0x22, 0x40, 0x53, + 0x09, 0x17, 0xd0, 0x01, 0x27, 0x01, 0x2b, 0x19, + 0x4a, 0x17, 0xd0, 0x02, 0x2b, 0x28, 0xd1, 0x8c, + 0x78, 0xcb, 0x78, 0x1b, 0x02, 0x1c, 0x43, 0x16, + 0x4b, 0x9c, 0x42, 0x21, 0xd1, 0x49, 0x78, 0x30, + 0x29, 0x14, 0xd0, 0x40, 0x29, 0x1c, 0xd1, 0x00, + 0x21, 0x17, 0x60, 0xff, 0xf7, 0xf7, 0xf9, 0x01, + 0x20, 0x16, 0xe0, 0x08, 0x1c, 0xff, 0xf7, 0xcc, + 0xfd, 0x12, 0xe0, 0x11, 0x68, 0x00, 0x29, 0x0f, + 0xd0, 0x21, 0x0a, 0x0d, 0xd2, 0x38, 0x1c, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x09, 0x4f, 0x38, + 0x68, 0x00, 0xf0, 0x58, 0xfe, 0x01, 0x06, 0x09, + 0x0e, 0x38, 0x68, 0xff, 0xf7, 0xdf, 0xf9, 0x01, + 0x20, 0x00, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x40, + 0xfa, 0x00, 0x20, 0xec, 0xe7, 0xc0, 0x69, 0x03, + 0x20, 0x7c, 0x05, 0x00, 0x00, 0xbc, 0x67, 0x03, + 0x20, 0x80, 0xb5, 0x07, 0x4f, 0x01, 0x21, 0x39, + 0x60, 0xff, 0xf7, 0x44, 0xfa, 0x00, 0x28, 0x04, + 0xd1, 0x02, 0x20, 0x38, 0x60, 0x80, 0xbc, 0xed, + 0x09, 0x00, 0x53, 0x02, 0x08, 0xbc, 0x18, 0x47, + 0x03, 0x20, 0x38, 0x60, 0xf9, 0xe7, 0xcc, 0xdd, + 0x03, 0x20, 0x07, 0x49, 0x07, 0x22, 0x8a, 0x70, + 0x01, 0x22, 0x8a, 0x70, 0x83, 0x22, 0xca, 0x70, + 0x08, 0x70, 0x00, 0x0a, 0x48, 0x70, 0x03, 0x20, + 0xc8, 0x70, 0x02, 0x49, 0x00, 0x20, 0x08, 0x60, + 0x70, 0x47, 0x60, 0x00, 0x00, 0xd0, 0xc8, 0x6c, + 0x03, 0x20, 0x04, 0x48, 0x41, 0x79, 0x49, 0x08, + 0x03, 0xd3, 0x01, 0x78, 0x41, 0x79, 0x49, 0x08, + 0xfb, 0xd2, 0x00, 0x78, 0x70, 0x47, 0x60, 0x00, + 0x00, 0xd0, 0x04, 0x48, 0x41, 0x79, 0x4a, 0x08, + 0x00, 0xd3, 0x00, 0x78, 0x01, 0x20, 0x49, 0x09, + 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, 0x60, 0x00, + 0x00, 0xd0, 0x03, 0x49, 0x01, 0x20, 0x49, 0x79, + 0x49, 0x08, 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, + 0x00, 0x00, 0x60, 0x00, 0x00, 0xd0, 0x03, 0x49, + 0x01, 0x20, 0x49, 0x79, 0x89, 0x09, 0x00, 0xd2, + 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x60, 0x00, + 0x00, 0xd0, 0x00, 0xb5, 0xff, 0xf7, 0xf3, 0xff, + 0x00, 0x28, 0xfb, 0xd0, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0xeb, 0xff, + 0x00, 0x28, 0xfb, 0xd0, 0x02, 0x48, 0x07, 0x70, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, 0x00, + 0x00, 0xd0, 0xf0, 0xb5, 0x00, 0x23, 0x07, 0x1c, + 0xc0, 0x56, 0x00, 0x28, 0x1c, 0xd0, 0x12, 0x4d, + 0x0d, 0x26, 0x68, 0x79, 0x10, 0x24, 0x80, 0x09, + 0x0e, 0xd2, 0xed, 0xf7, 0xb2, 0xfe, 0x68, 0x79, + 0x80, 0x09, 0xfa, 0xd3, 0x08, 0xe0, 0x0a, 0x28, + 0x03, 0xd1, 0x00, 0x2c, 0xf1, 0xd0, 0x2e, 0x70, + 0x01, 0x3c, 0x38, 0x78, 0x28, 0x70, 0x01, 0x37, + 0x20, 0x1c, 0x01, 0x3c, 0x00, 0x28, 0x06, 0xd0, + 0x00, 0x23, 0xf8, 0x56, 0x00, 0x28, 0xee, 0xd1, + 0xf0, 0xbc, 0xed, 0x09, 0x00, 0x54, 0x02, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x23, 0xf8, 0x56, 0x00, + 0x28, 0xdd, 0xd1, 0xf7, 0xe7, 0x00, 0x00, 0x60, + 0x00, 0x00, 0xd0, 0x80, 0xb5, 0x00, 0x23, 0x07, + 0x1c, 0xc0, 0x56, 0x00, 0x28, 0x0f, 0xd0, 0x00, + 0x23, 0xf8, 0x56, 0x0a, 0x28, 0x02, 0xd1, 0x0d, + 0x20, 0xff, 0xf7, 0xb8, 0xff, 0x00, 0x23, 0xf8, + 0x56, 0x01, 0x37, 0xff, 0xf7, 0xb3, 0xff, 0x00, + 0x23, 0xf8, 0x56, 0x00, 0x28, 0xef, 0xd1, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, + 0xb5, 0x0a, 0x48, 0x00, 0x21, 0x01, 0x60, 0x41, + 0x60, 0x10, 0xf0, 0x0d, 0xfd, 0x08, 0x48, 0x01, + 0x79, 0x49, 0x08, 0x49, 0x00, 0x01, 0x71, 0x30, + 0x20, 0x10, 0xf0, 0x01, 0xfd, 0x00, 0x21, 0x30, + 0x20, 0x10, 0xf0, 0xf9, 0xfc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0xcc, 0x6c, 0x03, 0x20, 0x40, + 0x00, 0x00, 0xd0, 0x00, 0xb5, 0x01, 0x23, 0x1b, + 0x07, 0x03, 0x40, 0x18, 0x4a, 0x0a, 0xd1, 0x00, + 0x29, 0x03, 0xd0, 0x11, 0x68, 0x08, 0x43, 0x10, + 0x60, 0x10, 0xe0, 0x11, 0x68, 0xc0, 0x43, 0x08, + 0x40, 0x10, 0x60, 0x0b, 0xe0, 0x00, 0x01, 0x00, + 0x09, 0x00, 0x29, 0x03, 0xd0, 0x51, 0x68, 0x08, + 0x43, 0x50, 0x60, 0x03, 0xe0, 0x51, 0x68, 0xc0, + 0x43, 0x08, 0x40, 0x50, 0x60, 0x50, 0x68, 0x11, + 0x68, 0x08, 0x43, 0xff, 0x22, 0x01, 0x32, 0x02, + 0x40, 0x0a, 0x49, 0x04, 0xd0, 0x0a, 0x79, 0x01, + 0x23, 0x1a, 0x43, 0x0a, 0x71, 0x03, 0xe0, 0x0a, + 0x79, 0x52, 0x08, 0x52, 0x00, 0x0a, 0x71, 0xc0, + 0x43, 0x30, 0x23, 0x18, 0x40, 0x30, 0x21, 0x10, + 0xf0, 0xbe, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0xcc, + 0x6c, 0x03, 0x20, 0x40, 0x00, 0x00, 0xd0, 0x00, + 0xb5, 0x00, 0x20, 0x00, 0xf0, 0x1a, 0xf8, 0xec, + 0xf7, 0xb6, 0xfb, 0x06, 0x49, 0xed, 0x09, 0x00, + 0x55, 0x02, 0x48, 0x07, 0x01, 0x62, 0x06, 0x49, + 0x06, 0x4a, 0x11, 0x60, 0x06, 0x49, 0x07, 0x4a, + 0x11, 0x60, 0x00, 0x21, 0x41, 0x60, 0x81, 0x60, + 0x08, 0xbc, 0x18, 0x47, 0xbf, 0x03, 0x00, 0x80, + 0x29, 0x20, 0x28, 0xe8, 0xc0, 0x00, 0x00, 0xd0, + 0x31, 0x00, 0x30, 0x08, 0x00, 0x01, 0x00, 0xd0, + 0x90, 0xb5, 0x06, 0x24, 0x00, 0x22, 0x02, 0x27, + 0x01, 0x23, 0x01, 0x28, 0x0d, 0x49, 0x06, 0xd1, + 0x0b, 0x62, 0x4f, 0x62, 0x8a, 0x62, 0xca, 0x62, + 0x0a, 0x63, 0x4c, 0x63, 0x8a, 0x63, 0x88, 0xc1, + 0x08, 0x39, 0x8a, 0x60, 0xca, 0x60, 0x0a, 0x61, + 0x4c, 0x61, 0x8a, 0x61, 0x47, 0x21, 0x09, 0x02, + 0x4a, 0x05, 0x11, 0x60, 0x01, 0x28, 0x01, 0xd1, + 0x10, 0xf0, 0xa4, 0xfb, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, + 0x90, 0xb4, 0x00, 0x20, 0xff, 0x27, 0x0a, 0x4a, + 0x01, 0x37, 0x00, 0x21, 0x03, 0x1c, 0x5c, 0x08, + 0x5b, 0x08, 0x01, 0xd3, 0x07, 0x4b, 0x5c, 0x40, + 0x01, 0x31, 0x23, 0x1c, 0x08, 0x29, 0xf6, 0xdb, + 0x41, 0x00, 0x01, 0x30, 0xb8, 0x42, 0x53, 0x52, + 0xef, 0xd3, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, + 0x18, 0xe0, 0x03, 0x20, 0x08, 0x84, 0x00, 0x00, + 0x00, 0xb5, 0x00, 0x23, 0x00, 0xf0, 0x02, 0xf8, + 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 0x04, 0x1c, + 0x1f, 0x30, 0x40, 0x09, 0x40, 0x01, 0x06, 0x1b, + 0x0d, 0x1c, 0x17, 0x1c, 0x00, 0xf0, 0x9a, 0xf8, + 0x00, 0x2e, 0x00, 0xd1, 0x20, 0x26, 0xbe, 0x42, + 0x00, 0xd9, 0x3e, 0x1c, 0x00, 0x2f, 0x11, 0xd0, + 0xa0, 0x20, 0x21, 0x1c, 0x32, 0x1c, 0x2b, 0x1c, + 0x00, 0xf0, 0x04, 0xf9, 0x03, 0x9b, 0x00, 0x2b, + 0x00, 0xd1, 0xad, 0x19, 0xa4, 0x19, 0xbf, 0x1b, + 0x20, 0x26, 0x20, 0x2f, 0x00, 0xd8, 0x3e, 0x1c, + 0xed, 0x09, 0x00, 0x56, 0x02, 0x00, 0x2f, 0xed, + 0xd1, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0xa0, 0x26, 0x04, 0x1c, 0x0d, + 0x1c, 0x17, 0x1c, 0x00, 0xf0, 0x75, 0xf8, 0x00, + 0xf0, 0x85, 0xf8, 0x30, 0x1c, 0x00, 0xf0, 0xa8, + 0xf8, 0x00, 0xf0, 0xc1, 0xf8, 0x00, 0x28, 0xf6, + 0xd0, 0x28, 0x0a, 0x00, 0x06, 0x00, 0x0e, 0x00, + 0xf0, 0x9f, 0xf8, 0x00, 0xf0, 0xb8, 0xf8, 0x28, + 0x06, 0x00, 0x0e, 0x00, 0xf0, 0x99, 0xf8, 0x00, + 0xf0, 0xb2, 0xf8, 0x00, 0xf0, 0x6f, 0xf8, 0x01, + 0x20, 0x30, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x00, + 0xf0, 0x8f, 0xf8, 0x00, 0xf0, 0xa8, 0xf8, 0x00, + 0x25, 0x00, 0x2f, 0x0a, 0xd9, 0x7e, 0x1e, 0x10, + 0xf0, 0xd3, 0xfa, 0x60, 0x55, 0xae, 0x42, 0x01, + 0xd9, 0x10, 0xf0, 0xf0, 0xfa, 0x01, 0x35, 0xbd, + 0x42, 0xf5, 0xd3, 0x00, 0xf0, 0x6e, 0xf8, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x48, 0x41, + 0x69, 0x06, 0x23, 0x99, 0x43, 0x04, 0x23, 0x19, + 0x43, 0x41, 0x61, 0x80, 0x69, 0x80, 0x08, 0x01, + 0xd3, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, + 0x47, 0x00, 0x00, 0x00, 0xe0, 0x80, 0xb4, 0x16, + 0x4a, 0x57, 0x69, 0x06, 0x23, 0x3b, 0x43, 0x53, + 0x61, 0x14, 0x4f, 0x01, 0x28, 0x07, 0xd0, 0x02, + 0x28, 0x13, 0xd1, 0x00, 0x29, 0x0d, 0xd0, 0x38, + 0x68, 0x04, 0x23, 0x18, 0x43, 0x0c, 0xe0, 0x00, + 0x29, 0x03, 0xd0, 0x38, 0x68, 0x02, 0x23, 0x18, + 0x43, 0x06, 0xe0, 0x38, 0x68, 0x02, 0x23, 0x98, + 0x43, 0x02, 0xe0, 0x38, 0x68, 0x04, 0x23, 0x98, + 0x43, 0x38, 0x60, 0x38, 0x68, 0x91, 0x69, 0x06, + 0x23, 0x99, 0x43, 0x18, 0x40, 0x08, 0x43, 0xd0, + 0x61, 0x14, 0x21, 0x08, 0x1c, 0x01, 0x39, 0x00, + 0x28, 0xfb, 0xd1, 0x80, 0xbc, 0x70, 0x47, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x57, 0x02, + 0x00, 0xe0, 0xd4, 0x6c, 0x03, 0x20, 0x80, 0xb5, + 0x01, 0x21, 0x01, 0x20, 0xff, 0xf7, 0xc9, 0xff, + 0x00, 0x21, 0x02, 0x20, 0xff, 0xf7, 0xc5, 0xff, + 0x00, 0x27, 0x00, 0xf0, 0x1d, 0xf8, 0x01, 0x37, + 0x04, 0x2f, 0xfa, 0xd3, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0x01, 0x21, 0x02, 0x20, + 0xff, 0xf7, 0xb7, 0xff, 0x01, 0x21, 0x01, 0x20, + 0xff, 0xf7, 0xb3, 0xff, 0x00, 0x21, 0x01, 0x20, + 0xff, 0xf7, 0xaf, 0xff, 0x00, 0x21, 0x02, 0x20, + 0xff, 0xf7, 0xab, 0xff, 0x01, 0x21, 0x01, 0x20, + 0xff, 0xf7, 0xa7, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x00, 0x21, 0x01, 0x20, 0xff, 0xf7, + 0xa0, 0xff, 0x01, 0x21, 0x02, 0x20, 0xff, 0xf7, + 0x9c, 0xff, 0x01, 0x21, 0x01, 0x20, 0xff, 0xf7, + 0x98, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x07, 0x24, 0x07, 0x1c, 0x38, 0x1c, 0x20, 0x41, + 0xc1, 0x07, 0xc9, 0x0f, 0x01, 0x20, 0xff, 0xf7, + 0x8c, 0xff, 0x01, 0x21, 0x02, 0x20, 0xff, 0xf7, + 0x88, 0xff, 0x00, 0x21, 0x02, 0x20, 0xff, 0xf7, + 0x84, 0xff, 0x01, 0x3c, 0xee, 0xd5, 0x01, 0x21, + 0x01, 0x20, 0xff, 0xf7, 0x7e, 0xff, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x7d, 0x27, + 0xff, 0x00, 0x01, 0x21, 0x01, 0x20, 0xff, 0xf7, + 0x74, 0xff, 0x01, 0x21, 0x02, 0x20, 0xff, 0xf7, + 0x70, 0xff, 0xff, 0xf7, 0x5e, 0xff, 0x00, 0x28, + 0x0f, 0xd0, 0x09, 0xe0, 0x00, 0x2f, 0x07, 0xd1, + 0x00, 0x21, 0x02, 0x20, 0xff, 0xf7, 0x65, 0xff, + 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x01, 0x3f, 0xff, 0xf7, 0x4e, 0xff, 0x00, 0x28, + 0xf0, 0xd1, 0x00, 0x21, 0x02, 0x20, 0xff, 0xf7, + 0x58, 0xff, 0x01, 0x20, 0xf1, 0xe7, 0xf0, 0xb5, + 0x40, 0x08, 0x40, 0x00, 0x06, 0x06, 0xed, 0x09, + 0x00, 0x58, 0x02, 0x36, 0x0e, 0x0c, 0x1c, 0x1d, + 0x1c, 0x17, 0x1c, 0xff, 0xf7, 0x90, 0xff, 0x30, + 0x1c, 0xff, 0xf7, 0xb3, 0xff, 0xff, 0xf7, 0xcc, + 0xff, 0x00, 0x28, 0xf6, 0xd0, 0x20, 0x0a, 0x00, + 0x06, 0x00, 0x0e, 0xff, 0xf7, 0xaa, 0xff, 0xff, + 0xf7, 0xc3, 0xff, 0x20, 0x06, 0x00, 0x0e, 0xff, + 0xf7, 0xa4, 0xff, 0xff, 0xf7, 0xbd, 0xff, 0x00, + 0x24, 0x00, 0x2f, 0x07, 0xd9, 0x28, 0x5d, 0xff, + 0xf7, 0x9c, 0xff, 0xff, 0xf7, 0xb5, 0xff, 0x01, + 0x34, 0xbc, 0x42, 0xf7, 0xd3, 0xff, 0xf7, 0x86, + 0xff, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x04, 0x49, 0x06, 0x22, 0x09, 0x68, 0xdb, + 0xf7, 0x44, 0xf8, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x00, 0x00, 0xcc, 0x67, 0x03, 0x20, 0xf0, + 0xb5, 0x82, 0xb0, 0x1d, 0x49, 0x07, 0x1c, 0x60, + 0xc9, 0x68, 0x46, 0x60, 0xc0, 0x1c, 0x4c, 0x06, + 0x22, 0x1c, 0xa1, 0x20, 0x68, 0x00, 0xf0, 0x15, + 0xfc, 0x01, 0x25, 0x00, 0x28, 0x0c, 0xd0, 0x06, + 0x22, 0x39, 0x1c, 0x20, 0x68, 0x00, 0xf0, 0x0d, + 0xfc, 0x00, 0x28, 0x03, 0xd1, 0x02, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x1c, 0xf9, + 0xe7, 0xc0, 0x20, 0x10, 0xf0, 0xbe, 0xfa, 0x06, + 0x1c, 0x06, 0x22, 0x39, 0x1c, 0x11, 0x48, 0xff, + 0xf7, 0x7e, 0xfe, 0x68, 0x46, 0x06, 0x22, 0x0e, + 0x49, 0xff, 0xf7, 0xa7, 0xfe, 0x30, 0x1c, 0x10, + 0xf0, 0xb0, 0xfa, 0x69, 0x46, 0x06, 0x22, 0x38, + 0x1c, 0x00, 0xf0, 0xef, 0xfb, 0x00, 0x28, 0x01, + 0xd0, 0x28, 0x1c, 0xdf, 0xe7, 0x69, 0x46, 0x06, + 0x22, 0x20, 0x68, 0xdb, 0xf7, 0x02, 0xf8, 0x00, + 0x20, 0xd8, 0xe7, 0x68, 0x61, 0x03, 0x20, 0xcc, + 0x67, 0x03, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0xc8, 0x1f, 0x00, 0x00, 0x80, + 0xb5, 0xed, 0x09, 0x00, 0x59, 0x02, 0x07, 0x1c, + 0x0a, 0x68, 0x10, 0x20, 0x10, 0x2a, 0x00, 0xd2, + 0x10, 0x1c, 0x08, 0x60, 0x00, 0x21, 0x10, 0x22, + 0x38, 0x1c, 0xda, 0xf7, 0x61, 0xff, 0x05, 0x48, + 0x08, 0x22, 0x01, 0x68, 0x38, 0x1c, 0xda, 0xf7, + 0xe3, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0x00, 0xc0, 0x67, 0x03, 0x20, + 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0x1c, 0x4c, + 0x08, 0x22, 0x1c, 0xa1, 0x20, 0x68, 0x00, 0xf0, + 0xb7, 0xfb, 0x01, 0x25, 0x00, 0x28, 0x0c, 0xd0, + 0x08, 0x22, 0x39, 0x1c, 0x20, 0x68, 0x00, 0xf0, + 0xaf, 0xfb, 0x00, 0x28, 0x03, 0xd1, 0x02, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x1c, + 0xf9, 0xe7, 0xc0, 0x20, 0x10, 0xf0, 0x60, 0xfa, + 0x06, 0x1c, 0x7f, 0x20, 0x80, 0x01, 0x08, 0x22, + 0x39, 0x1c, 0xff, 0xf7, 0x1f, 0xfe, 0x7f, 0x21, + 0x89, 0x01, 0x68, 0x46, 0x08, 0x22, 0xff, 0xf7, + 0x47, 0xfe, 0x30, 0x1c, 0x10, 0xf0, 0x50, 0xfa, + 0x69, 0x46, 0x08, 0x22, 0x38, 0x1c, 0x00, 0xf0, + 0x8f, 0xfb, 0x00, 0x28, 0x01, 0xd0, 0x28, 0x1c, + 0xdd, 0xe7, 0x08, 0x22, 0x39, 0x1c, 0x20, 0x68, + 0xda, 0xf7, 0xa2, 0xff, 0x00, 0x20, 0xd6, 0xe7, + 0xc0, 0x67, 0x03, 0x20, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xb0, 0xb5, 0x0d, 0x4c, 0x1f, 0x1c, 0xe3, 0x79, + 0xa5, 0x79, 0x1b, 0x02, 0x1d, 0x43, 0x05, 0x60, + 0x63, 0x7a, 0x20, 0x7a, 0x1b, 0x02, 0x18, 0x43, + 0x08, 0x60, 0x38, 0x68, 0x2e, 0x23, 0x2e, 0x28, + 0x00, 0xd2, 0x03, 0x1c, 0x10, 0x1c, 0x1a, 0x1c, + 0x3b, 0x60, 0x04, 0x49, 0xda, 0xf7, 0x80, 0xff, + 0xb0, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0x30, 0x7c, 0x00, 0x00, 0x3a, 0x7c, 0x00, 0x00, + 0xff, 0xb5, 0xa6, 0xb0, 0xed, 0x09, 0x00, 0x5a, + 0x02, 0x68, 0x46, 0x14, 0x1c, 0x1f, 0x1c, 0x00, + 0x23, 0x00, 0x22, 0x00, 0x21, 0x00, 0x25, 0x00, + 0x26, 0x6e, 0xc0, 0x6e, 0xc0, 0x60, 0xc0, 0xc0, + 0x20, 0x10, 0xf0, 0x08, 0xfa, 0x06, 0x1c, 0x1c, + 0x48, 0x02, 0x22, 0x26, 0xa9, 0xff, 0xf7, 0xc8, + 0xfd, 0x1a, 0x48, 0x02, 0x22, 0x27, 0xa9, 0xff, + 0xf7, 0xc3, 0xfd, 0x2e, 0x22, 0x2e, 0x2f, 0x00, + 0xd8, 0x3a, 0x1c, 0x68, 0x46, 0x21, 0x1c, 0x15, + 0x1c, 0xda, 0xf7, 0x54, 0xff, 0x69, 0x46, 0x2e, + 0x22, 0x13, 0x48, 0xff, 0xf7, 0xb5, 0xfd, 0x68, + 0x22, 0x0c, 0xa8, 0x12, 0x49, 0xff, 0xf7, 0xde, + 0xfd, 0x30, 0x1c, 0x10, 0xf0, 0xe7, 0xf9, 0x1a, + 0xa9, 0x02, 0x31, 0x20, 0x1c, 0x2a, 0x1c, 0x00, + 0xf0, 0x25, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x19, + 0xa8, 0x40, 0x88, 0x26, 0x99, 0x88, 0x42, 0x04, + 0xd1, 0x1a, 0xa8, 0x00, 0x88, 0x27, 0x99, 0x88, + 0x42, 0x04, 0xd0, 0x01, 0x20, 0x2a, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0xf9, + 0xe7, 0xce, 0x1f, 0x00, 0x00, 0xd0, 0x1f, 0x00, + 0x00, 0xd2, 0x1f, 0x00, 0x00, 0x98, 0x1f, 0x00, + 0x00, 0x01, 0x20, 0x70, 0x47, 0xff, 0xb5, 0x00, + 0x26, 0x0c, 0x9b, 0x0a, 0x9c, 0x0b, 0x9f, 0x09, + 0x9d, 0x06, 0x60, 0x0e, 0x60, 0x16, 0x60, 0x03, + 0x98, 0x06, 0x60, 0x2e, 0x60, 0x26, 0x60, 0x3e, + 0x60, 0x1e, 0x60, 0x04, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x01, 0x20, 0x18, 0x47, 0x0e, 0x12, 0xa0, + 0xe3, 0x14, 0x00, 0x91, 0xe5, 0x01, 0x2c, 0x00, + 0xe2, 0x00, 0x00, 0x52, 0xe3, 0x18, 0x20, 0x91, + 0x15, 0x34, 0x00, 0x9f, 0xe5, 0x01, 0x0c, 0x12, + 0x13, 0x07, 0x20, 0xa0, 0x13, 0x03, 0x2c, 0x82, + 0x12, 0x00, 0x20, 0x80, 0x15, 0x02, 0x00, 0x00, + 0x1a, 0x07, 0x20, 0xa0, 0xe3, 0x02, 0x2c, 0xed, + 0x09, 0x00, 0x5b, 0x02, 0x82, 0xe2, 0x00, 0x20, + 0x80, 0xe5, 0x00, 0x00, 0x90, 0xe5, 0x1c, 0x00, + 0x81, 0xe5, 0x07, 0x00, 0xa0, 0xe3, 0x23, 0x0c, + 0x80, 0xe2, 0x14, 0x00, 0x81, 0xe5, 0x1e, 0xff, + 0x2f, 0xe1, 0xd8, 0x6c, 0x03, 0x20, 0x1e, 0xff, + 0x2f, 0xe1, 0x8e, 0x12, 0xa0, 0xe3, 0x00, 0x30, + 0xa0, 0xe3, 0x93, 0x20, 0x01, 0xe1, 0x00, 0x30, + 0xb0, 0xe1, 0x20, 0x00, 0x1f, 0xe5, 0x00, 0x30, + 0x90, 0xe5, 0x02, 0x3a, 0x83, 0x03, 0x02, 0x3a, + 0xc3, 0x13, 0x00, 0x30, 0x80, 0xe5, 0x00, 0x30, + 0x90, 0xe5, 0x0e, 0x02, 0xa0, 0xe3, 0x1c, 0x30, + 0x80, 0xe5, 0x00, 0x20, 0x81, 0xe5, 0x1e, 0xff, + 0x2f, 0xe1, 0x8e, 0x12, 0xa0, 0xe3, 0x00, 0x30, + 0xa0, 0xe3, 0x93, 0x20, 0x01, 0xe1, 0x00, 0x30, + 0xa0, 0xe1, 0x0e, 0x02, 0xa0, 0xe3, 0x14, 0xc0, + 0x90, 0xe5, 0x0c, 0x30, 0x83, 0xe1, 0x14, 0x30, + 0x80, 0xe5, 0x00, 0x20, 0x81, 0xe5, 0x1e, 0xff, + 0x2f, 0xe1, 0x8e, 0x12, 0xa0, 0xe3, 0x00, 0x30, + 0xa0, 0xe3, 0x93, 0x20, 0x01, 0xe1, 0x00, 0x30, + 0xe0, 0xe1, 0x0e, 0x02, 0xa0, 0xe3, 0x14, 0xc0, + 0x90, 0xe5, 0x0c, 0x30, 0x03, 0xe0, 0x14, 0x30, + 0x80, 0xe5, 0x00, 0x20, 0x81, 0xe5, 0x1e, 0xff, + 0x2f, 0xe1, 0x0e, 0x02, 0xa0, 0xe3, 0x18, 0x00, + 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x04, 0xe0, + 0x2d, 0xe5, 0x8e, 0x22, 0xa0, 0xe3, 0x00, 0xc0, + 0xa0, 0xe3, 0x9c, 0x30, 0x02, 0xe1, 0xb4, 0xc0, + 0x1f, 0xe5, 0x00, 0xe0, 0x9c, 0xe5, 0x01, 0x10, + 0xce, 0xe1, 0x00, 0x00, 0x81, 0xe1, 0x00, 0x00, + 0x8c, 0xe5, 0x0e, 0x12, 0xa0, 0xe3, 0x1c, 0x00, + 0x81, 0xe5, 0x00, 0x30, 0x82, 0xe5, 0x04, 0xe0, + 0x9d, 0xe4, 0x1e, 0xff, 0x2f, 0xe1, 0x8e, 0x12, + 0xa0, 0xe3, 0x00, 0x30, 0xa0, 0xe3, 0x93, 0x20, + 0x01, 0xe1, 0xed, 0x09, 0x00, 0x5c, 0x02, 0x01, + 0x30, 0xa0, 0xe3, 0x13, 0x30, 0xa0, 0xe1, 0xf0, + 0x00, 0x1f, 0xe5, 0x00, 0xc0, 0x90, 0xe5, 0x0c, + 0x30, 0x83, 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x0e, + 0x02, 0xa0, 0xe3, 0x1c, 0x30, 0x80, 0xe5, 0x00, + 0x20, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x8e, + 0x12, 0xa0, 0xe3, 0x00, 0x30, 0xa0, 0xe3, 0x93, + 0x20, 0x01, 0xe1, 0x01, 0x30, 0xa0, 0xe3, 0x13, + 0x30, 0xe0, 0xe1, 0x24, 0x01, 0x1f, 0xe5, 0x00, + 0xc0, 0x90, 0xe5, 0x0c, 0x30, 0x03, 0xe0, 0x00, + 0x30, 0x80, 0xe5, 0x0e, 0x02, 0xa0, 0xe3, 0x1c, + 0x30, 0x80, 0xe5, 0x00, 0x20, 0x81, 0xe5, 0x1e, + 0xff, 0x2f, 0xe1, 0x44, 0x01, 0x1f, 0xe5, 0x00, + 0x00, 0x90, 0xe5, 0x01, 0x0c, 0x10, 0xe2, 0x01, + 0x00, 0xa0, 0x13, 0x1e, 0xff, 0x2f, 0xe1, 0x07, + 0x0a, 0xa0, 0xe3, 0x37, 0xcc, 0xd0, 0xe5, 0x36, + 0x0c, 0xd0, 0xe5, 0x0c, 0x04, 0x80, 0xe1, 0xff, + 0xcc, 0x40, 0xe2, 0xff, 0x00, 0x5c, 0xe3, 0x1e, + 0xff, 0x2f, 0x11, 0x04, 0xe0, 0x2d, 0xe5, 0x0f, + 0x00, 0xa0, 0xe3, 0xbb, 0xff, 0xff, 0xeb, 0xc4, + 0xff, 0xff, 0xeb, 0x00, 0x10, 0xe0, 0xe3, 0x20, + 0x05, 0x81, 0xe0, 0x07, 0x10, 0x00, 0xe2, 0xc0, + 0xff, 0xff, 0xeb, 0x03, 0x20, 0xa0, 0xe3, 0x20, + 0x07, 0x02, 0xe0, 0x00, 0x04, 0x81, 0xe1, 0x04, + 0xe0, 0x9d, 0xe4, 0x1e, 0xff, 0x2f, 0xe1, 0xb0, + 0xb4, 0x02, 0x1c, 0x11, 0x78, 0x19, 0x4c, 0x00, + 0x20, 0x00, 0x27, 0x63, 0x18, 0x5d, 0x78, 0x2b, + 0x09, 0x05, 0xd3, 0x51, 0x78, 0x63, 0x18, 0x5d, + 0x78, 0x01, 0x32, 0x2b, 0x09, 0xf9, 0xd2, 0x2d, + 0x29, 0x03, 0xd1, 0x01, 0x27, 0xd2, 0x19, 0x11, + 0x78, 0x03, 0xe0, 0x2b, 0x29, 0x01, 0xd1, 0x51, + 0x78, 0x01, 0x32, 0x63, 0x18, 0x5d, 0x78, 0xeb, + 0x08, 0x0a, 0xd3, 0x83, 0x00, 0xed, 0x09, 0x00, + 0x5d, 0x02, 0x18, 0x18, 0x40, 0x00, 0x30, 0x39, + 0x40, 0x18, 0x51, 0x78, 0x63, 0x18, 0x5d, 0x78, + 0x01, 0x32, 0xeb, 0x08, 0xf4, 0xd2, 0x00, 0x2f, + 0x07, 0xd0, 0x06, 0x4b, 0x41, 0x42, 0x98, 0x42, + 0x02, 0xd9, 0xc0, 0x1a, 0x59, 0x42, 0x09, 0x1a, + 0x08, 0x1c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, + 0x98, 0x61, 0x03, 0x20, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xb5, 0x98, 0xb0, 0x15, 0x1c, 0x17, 0x1c, + 0x61, 0xa6, 0x18, 0x98, 0x19, 0x99, 0x0c, 0xce, + 0x00, 0x24, 0x08, 0x3e, 0xda, 0xf7, 0xfa, 0xfe, + 0x00, 0x21, 0x00, 0x28, 0x07, 0xd0, 0x30, 0x20, + 0x38, 0x70, 0x79, 0x70, 0x38, 0x1c, 0x1c, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, + 0x39, 0x70, 0x1b, 0x98, 0x02, 0x28, 0x47, 0xd0, + 0x08, 0x28, 0x23, 0xd0, 0x10, 0x28, 0x65, 0xd1, + 0x18, 0x98, 0x19, 0x99, 0x32, 0x68, 0x33, 0x1c, + 0x5b, 0x68, 0x16, 0x1c, 0x17, 0x93, 0xeb, 0xf7, + 0x65, 0xf9, 0x00, 0x28, 0x78, 0xd0, 0x18, 0x98, + 0x19, 0x99, 0x00, 0x07, 0x4e, 0x49, 0x00, 0x0f, + 0x09, 0x5c, 0x68, 0x46, 0x04, 0x22, 0x01, 0x55, + 0x18, 0x98, 0x19, 0x99, 0xeb, 0xf7, 0x60, 0xf9, + 0x32, 0x1c, 0x01, 0x34, 0x18, 0x90, 0x19, 0x91, + 0x17, 0x9b, 0xeb, 0xf7, 0x4f, 0xf9, 0x00, 0x28, + 0xe9, 0xd1, 0x78, 0xe0, 0x18, 0x98, 0x19, 0x99, + 0x32, 0x68, 0x33, 0x1c, 0x5b, 0x68, 0x16, 0x1c, + 0x16, 0x93, 0xeb, 0xf7, 0x43, 0xf9, 0x00, 0x28, + 0x56, 0xd0, 0x18, 0x98, 0x19, 0x99, 0x40, 0x07, + 0x3d, 0x49, 0x40, 0x0f, 0x09, 0x5c, 0x68, 0x46, + 0x03, 0x22, 0x01, 0x55, 0x18, 0x98, 0x19, 0x99, + 0xeb, 0xf7, 0x3e, 0xf9, 0x32, 0x1c, 0x01, 0x34, + 0x18, 0x90, 0x19, 0x91, 0x16, 0x9b, 0xeb, 0xf7, + 0x2d, 0xf9, 0x00, 0x28, 0xe9, 0xd1, 0x56, 0xe0, + 0xed, 0x09, 0x00, 0x5e, 0x02, 0x18, 0x98, 0x19, + 0x99, 0x32, 0x68, 0x33, 0x1c, 0x5b, 0x68, 0x16, + 0x1c, 0x15, 0x93, 0xeb, 0xf7, 0x21, 0xf9, 0x00, + 0x28, 0x34, 0xd0, 0x18, 0x98, 0x19, 0x99, 0xc0, + 0x07, 0x2c, 0x49, 0xc0, 0x0f, 0x09, 0x5c, 0x68, + 0x46, 0x01, 0x22, 0x01, 0x55, 0x18, 0x98, 0x19, + 0x99, 0xeb, 0xf7, 0x1c, 0xf9, 0x32, 0x1c, 0x01, + 0x34, 0x18, 0x90, 0x19, 0x91, 0x15, 0x9b, 0xeb, + 0xf7, 0x0b, 0xf9, 0x00, 0x28, 0xe9, 0xd1, 0x34, + 0xe0, 0xff, 0xe7, 0x18, 0x98, 0x19, 0x99, 0x32, + 0x68, 0x14, 0x92, 0x73, 0x68, 0x13, 0x93, 0xeb, + 0xf7, 0xff, 0xf8, 0x00, 0x28, 0x12, 0xd0, 0x1b, + 0x98, 0x00, 0x21, 0x11, 0x91, 0x12, 0x90, 0x18, + 0x98, 0x19, 0x99, 0x01, 0x1c, 0x1b, 0x98, 0xda, + 0xf7, 0x59, 0xfc, 0x0e, 0x06, 0x36, 0x16, 0x19, + 0x99, 0x18, 0x98, 0x12, 0x9a, 0x11, 0x9b, 0xeb, + 0xf7, 0x0b, 0xf9, 0x00, 0xe0, 0x1e, 0xe0, 0x18, + 0x90, 0x19, 0x91, 0x09, 0x2e, 0x04, 0xdc, 0x68, + 0x46, 0xf1, 0x1d, 0x29, 0x31, 0x01, 0x55, 0x03, + 0xe0, 0x69, 0x46, 0xf0, 0x1d, 0x30, 0x30, 0x08, + 0x55, 0x18, 0x98, 0x19, 0x99, 0x14, 0x9a, 0x13, + 0x9b, 0x01, 0x34, 0xeb, 0xf7, 0xd5, 0xf8, 0x00, + 0x28, 0xd9, 0xd1, 0x00, 0x2c, 0x06, 0xd0, 0x68, + 0x46, 0x01, 0x3c, 0x00, 0x5d, 0x28, 0x70, 0x01, + 0x35, 0x00, 0x2c, 0xf8, 0xd1, 0x00, 0x21, 0x29, + 0x70, 0x38, 0x1c, 0x4a, 0xe7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, 0x03, + 0x20, 0xf0, 0xb5, 0x89, 0xb0, 0x0e, 0x1c, 0x0f, + 0x1c, 0x00, 0x21, 0x00, 0x25, 0x14, 0x1c, 0x00, + 0x28, 0x07, 0xd1, 0x30, 0x20, 0x38, 0x70, 0x79, + 0x70, 0x38, 0x1c, 0x09, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x21, 0x39, 0x70, 0x23, + 0x49, 0x02, 0x2c, 0xed, 0x09, 0x00, 0x5f, 0x02, + 0x17, 0xd0, 0x08, 0x2c, 0x0b, 0xd0, 0x10, 0x2c, + 0x1d, 0xd1, 0x02, 0x07, 0x12, 0x0f, 0x8b, 0x5c, + 0x6a, 0x46, 0x00, 0x09, 0x53, 0x55, 0x01, 0x35, + 0x00, 0x28, 0xf6, 0xd1, 0x27, 0xe0, 0x42, 0x07, + 0x52, 0x0f, 0x8b, 0x5c, 0x6a, 0x46, 0xc0, 0x08, + 0x53, 0x55, 0x01, 0x35, 0x00, 0x28, 0xf6, 0xd1, + 0x1d, 0xe0, 0xc2, 0x07, 0xd2, 0x0f, 0x8b, 0x5c, + 0x6a, 0x46, 0x40, 0x08, 0x53, 0x55, 0x01, 0x35, + 0x00, 0x28, 0xf6, 0xd1, 0x13, 0xe0, 0x01, 0x1c, + 0x20, 0x1c, 0xda, 0xf7, 0xea, 0xfb, 0x09, 0x06, + 0x09, 0x16, 0x09, 0x29, 0x04, 0xdc, 0xca, 0x1d, + 0x29, 0x32, 0x69, 0x46, 0x4a, 0x55, 0x03, 0xe0, + 0xca, 0x1d, 0x30, 0x32, 0x69, 0x46, 0x4a, 0x55, + 0x01, 0x35, 0x00, 0x28, 0xeb, 0xd1, 0x00, 0x2d, + 0x06, 0xd0, 0x68, 0x46, 0x01, 0x3d, 0x40, 0x5d, + 0x30, 0x70, 0x01, 0x36, 0x00, 0x2d, 0xf8, 0xd1, + 0x00, 0x21, 0x31, 0x70, 0x38, 0x1c, 0xb3, 0xe7, + 0x00, 0x00, 0x84, 0x61, 0x03, 0x20, 0x01, 0x1c, + 0x00, 0x23, 0xca, 0x56, 0x01, 0x31, 0x00, 0x20, + 0x00, 0x2a, 0x05, 0xd0, 0x00, 0x23, 0xca, 0x56, + 0x01, 0x31, 0x01, 0x30, 0x00, 0x2a, 0xf9, 0xd1, + 0x70, 0x47, 0x08, 0xb5, 0x69, 0x46, 0x02, 0x1c, + 0x06, 0x48, 0x00, 0x23, 0x00, 0xf0, 0xcf, 0xfc, + 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0x00, 0x90, + 0x00, 0x98, 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x94, 0xb8, 0x03, 0x20, 0x88, 0xb5, + 0x48, 0x43, 0x69, 0x46, 0x02, 0x1c, 0x07, 0x1c, + 0x09, 0x48, 0x00, 0x23, 0x00, 0xf0, 0xbb, 0xfc, + 0x00, 0x28, 0x02, 0xd0, 0x00, 0x20, 0x00, 0x90, + 0x04, 0xe0, 0x00, 0x21, 0x3a, 0x1c, 0x00, 0x98, + 0xda, 0xf7, 0xf9, 0xfb, 0x00, 0x98, 0x88, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x60, 0x02, 0x94, 0xb8, 0x03, 0x20, 0x00, + 0xb5, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x39, + 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x08, 0xb5, 0x00, + 0x21, 0x00, 0x91, 0x69, 0x46, 0x02, 0x1c, 0x05, + 0x48, 0x00, 0x23, 0x00, 0xf0, 0x9a, 0xfc, 0x00, + 0x28, 0x03, 0xd1, 0x00, 0x98, 0x01, 0xb0, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x20, 0xfa, 0xe7, 0x94, + 0xb8, 0x03, 0x20, 0x88, 0xb5, 0x48, 0x43, 0x69, + 0x46, 0x02, 0x1c, 0x07, 0x1c, 0x08, 0x48, 0x00, + 0x23, 0x00, 0xf0, 0x87, 0xfc, 0x00, 0x28, 0x08, + 0xd1, 0x00, 0x21, 0x3a, 0x1c, 0x00, 0x98, 0xda, + 0xf7, 0xc8, 0xfb, 0x00, 0x98, 0x88, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x20, 0xfa, 0xe7, 0x94, + 0xb8, 0x03, 0x20, 0x00, 0xb5, 0x00, 0xf0, 0x09, + 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xb0, + 0xb5, 0x07, 0x1c, 0x08, 0x1c, 0x0c, 0x1c, 0xff, + 0xf7, 0x88, 0xff, 0x05, 0x1c, 0x03, 0xd1, 0x38, + 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x23, 0xf8, 0x56, 0x00, 0x28, 0x12, 0xd0, 0x00, + 0x23, 0xf8, 0x56, 0xe1, 0x56, 0x88, 0x42, 0x08, + 0xd1, 0x38, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x00, + 0xf0, 0x2e, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x38, + 0x1c, 0xea, 0xe7, 0x00, 0x23, 0x01, 0x37, 0xf8, + 0x56, 0x00, 0x28, 0xec, 0xd1, 0x00, 0x20, 0xe3, + 0xe7, 0x00, 0x00, 0x80, 0xb4, 0x82, 0x18, 0x90, + 0x42, 0x11, 0xd2, 0x03, 0x78, 0x0f, 0x78, 0xbb, + 0x42, 0x09, 0xd0, 0x00, 0x78, 0x09, 0x78, 0x88, + 0x42, 0x03, 0xda, 0x00, 0x20, 0xc0, 0x43, 0x80, + 0xbc, 0x70, 0x47, 0x01, 0x20, 0xfb, 0xe7, 0x01, + 0x30, 0x01, 0x31, 0x90, 0x42, 0xed, 0xd3, 0x00, + 0x20, 0xf5, 0xe7, 0x02, 0x1c, 0x00, 0x23, 0xcb, + 0x56, 0x01, 0x31, 0x03, 0x70, 0x01, 0x30, 0x00, + 0x2b, 0xed, 0x09, 0x00, 0x61, 0x02, 0xf8, 0xd1, + 0x10, 0x1c, 0x70, 0x47, 0x80, 0xb4, 0x02, 0xe0, + 0x01, 0x30, 0x01, 0x31, 0x01, 0x3a, 0x00, 0x2a, + 0x07, 0xd9, 0x00, 0x23, 0xc7, 0x56, 0xcb, 0x56, + 0x9f, 0x42, 0x07, 0xd1, 0x00, 0x2f, 0xf3, 0xd1, + 0x04, 0xe0, 0x00, 0x2a, 0x02, 0xd1, 0x00, 0x20, + 0x80, 0xbc, 0x70, 0x47, 0x00, 0x78, 0x09, 0x78, + 0x40, 0x1a, 0xf9, 0xe7, 0x80, 0xb4, 0x07, 0x1c, + 0x00, 0x2a, 0x09, 0xd9, 0x00, 0x23, 0xcb, 0x56, + 0x01, 0x31, 0x01, 0x3a, 0x03, 0x70, 0x01, 0x30, + 0x00, 0x2b, 0x01, 0xd0, 0x00, 0x2a, 0xf5, 0xd8, + 0x51, 0x1e, 0x00, 0x2a, 0x06, 0xd9, 0x00, 0x22, + 0x02, 0x70, 0x0b, 0x1c, 0x01, 0x39, 0x01, 0x30, + 0x00, 0x2b, 0xf9, 0xd8, 0x38, 0x1c, 0x80, 0xbc, + 0x70, 0x47, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x23, + 0xd3, 0x56, 0x01, 0x32, 0x00, 0x2b, 0xfa, 0xd1, + 0x01, 0x3a, 0x00, 0x23, 0xcb, 0x56, 0x01, 0x31, + 0x13, 0x70, 0x01, 0x32, 0x00, 0x2b, 0xf8, 0xd1, + 0x70, 0x47, 0x00, 0x00, 0xf0, 0xb5, 0x00, 0x26, + 0x06, 0x9d, 0xc6, 0x60, 0x04, 0x1c, 0x00, 0x20, + 0x17, 0x1c, 0x0a, 0x5c, 0x26, 0x18, 0x01, 0x30, + 0x08, 0x28, 0x32, 0x74, 0xf9, 0xdb, 0x07, 0x99, + 0x01, 0x20, 0x06, 0x29, 0x01, 0xd1, 0x60, 0x76, + 0x01, 0xe0, 0x00, 0x26, 0x66, 0x76, 0x05, 0x99, + 0x07, 0x29, 0x01, 0xd1, 0x20, 0x76, 0x01, 0xe0, + 0x00, 0x26, 0x26, 0x76, 0x00, 0x26, 0x65, 0x62, + 0x26, 0x62, 0xe3, 0x61, 0x20, 0x7e, 0x00, 0x28, + 0x05, 0xd0, 0x28, 0x1c, 0x19, 0x1c, 0xda, 0xf7, + 0xa5, 0xfa, 0x68, 0x43, 0x01, 0xe0, 0x98, 0x08, + 0x80, 0x00, 0xa0, 0x62, 0xe7, 0x62, 0x38, 0x18, + 0x20, 0x63, 0x67, 0x63, 0x66, 0x64, 0xa7, 0x63, + 0xe6, 0x63, 0x26, 0x64, 0x26, 0x60, 0x66, 0x60, + 0x0e, 0x48, 0x0f, 0xf0, 0xed, 0x09, 0x00, 0x62, + 0x02, 0xdd, 0xfd, 0x0e, 0x48, 0xe0, 0x60, 0x0e, + 0x48, 0x01, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x09, + 0x68, 0x21, 0x60, 0x4c, 0x60, 0x00, 0x68, 0x60, + 0x60, 0x04, 0x60, 0x02, 0xe0, 0x04, 0x60, 0x24, + 0x60, 0x64, 0x60, 0x08, 0x48, 0x01, 0x68, 0x01, + 0x31, 0x01, 0x60, 0x0f, 0xf0, 0xc3, 0xfd, 0x30, + 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x64, 0x67, 0x03, 0x20, 0x45, 0x50, 0x49, + 0x50, 0x5c, 0x67, 0x03, 0x20, 0x60, 0x67, 0x03, + 0x20, 0xf0, 0xb5, 0x07, 0x1c, 0x31, 0x48, 0x0f, + 0xf0, 0xb5, 0xfd, 0x00, 0x21, 0xf9, 0x60, 0x0f, + 0xf0, 0xad, 0xfd, 0x2f, 0x48, 0x0f, 0xf0, 0xae, + 0xfd, 0x39, 0x68, 0x2e, 0x48, 0xb9, 0x42, 0x02, + 0xd1, 0x00, 0x21, 0x01, 0x60, 0x09, 0xe0, 0x7a, + 0x68, 0x4a, 0x60, 0x06, 0xcf, 0x08, 0x3f, 0x11, + 0x60, 0x01, 0x68, 0x8f, 0x42, 0x01, 0xd1, 0x79, + 0x68, 0x01, 0x60, 0x27, 0x48, 0x00, 0x25, 0x01, + 0x68, 0x01, 0x39, 0x01, 0x60, 0x7c, 0x6c, 0x00, + 0x2c, 0x19, 0xd0, 0x20, 0x48, 0x0f, 0xf0, 0x92, + 0xfd, 0x26, 0x20, 0xc0, 0x43, 0x20, 0x62, 0x20, + 0x69, 0x66, 0x68, 0x05, 0x21, 0xec, 0xf7, 0xa4, + 0xfd, 0x05, 0x43, 0x78, 0x6c, 0xb0, 0x42, 0x01, + 0xd1, 0x00, 0x24, 0x00, 0xe0, 0x34, 0x1c, 0x18, + 0x48, 0x0f, 0xf0, 0x90, 0xfd, 0x15, 0x48, 0x0f, + 0xf0, 0x89, 0xfd, 0x00, 0x2c, 0xe5, 0xd1, 0x3c, + 0x6c, 0x00, 0x2c, 0x19, 0xd0, 0x11, 0x48, 0x0f, + 0xf0, 0x75, 0xfd, 0x26, 0x20, 0xc0, 0x43, 0x20, + 0x62, 0x20, 0x69, 0x66, 0x68, 0x05, 0x21, 0xec, + 0xf7, 0x87, 0xfd, 0x05, 0x43, 0x38, 0x6c, 0xb0, + 0x42, 0x01, 0xd1, 0x00, 0x24, 0x00, 0xe0, 0x34, + 0x1c, 0x09, 0x48, 0x0f, 0xf0, 0x73, 0xfd, 0x07, + 0x48, 0x0f, 0xf0, 0x6c, 0xfd, 0x00, 0x2c, 0xed, + 0x09, 0x00, 0x63, 0x02, 0xe5, 0xd1, 0x00, 0x2d, + 0x01, 0xd0, 0x0f, 0xf0, 0x62, 0xfd, 0x0f, 0xf0, + 0x54, 0xfd, 0xf0, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, 0x64, 0x67, + 0x03, 0x20, 0x5c, 0x67, 0x03, 0x20, 0x60, 0x67, + 0x03, 0x20, 0xff, 0xb5, 0x8c, 0xb0, 0x05, 0x1c, + 0x00, 0x26, 0x00, 0x24, 0x17, 0x1c, 0x6e, 0x48, + 0x0f, 0xf0, 0x43, 0xfd, 0x29, 0x7e, 0x00, 0x29, + 0x01, 0xd0, 0x00, 0x20, 0x19, 0xe0, 0xf8, 0x1c, + 0x80, 0x08, 0x80, 0x00, 0x6b, 0x6c, 0xc6, 0x1b, + 0x30, 0x1d, 0x00, 0x2b, 0x0b, 0x93, 0x10, 0xd0, + 0x2a, 0x6a, 0x00, 0x2a, 0x0d, 0xd0, 0x65, 0x4a, + 0x12, 0x68, 0x6b, 0x7e, 0x00, 0x2b, 0x07, 0xd1, + 0x0f, 0x9b, 0x00, 0x2b, 0x04, 0xd0, 0x0b, 0x9b, + 0x1b, 0x7a, 0x92, 0x7e, 0x93, 0x42, 0x00, 0xdc, + 0xa8, 0x6a, 0x3b, 0x18, 0xaa, 0x6a, 0x00, 0x20, + 0x9a, 0x42, 0x35, 0xd2, 0x0f, 0x9b, 0x00, 0x2b, + 0x2f, 0xd0, 0xe9, 0x6b, 0x5a, 0x4a, 0x01, 0x31, + 0xe9, 0x63, 0x05, 0x95, 0x0d, 0x99, 0x03, 0x90, + 0x02, 0x90, 0x08, 0x97, 0x07, 0x91, 0x17, 0x68, + 0x02, 0xac, 0x06, 0x97, 0x68, 0x7e, 0x00, 0x28, + 0x0d, 0xd0, 0x68, 0x6c, 0x00, 0x28, 0x06, 0xd0, + 0x00, 0x68, 0x02, 0x90, 0x44, 0x60, 0x68, 0x6c, + 0x03, 0x90, 0x04, 0x60, 0x0b, 0xe0, 0x6c, 0x64, + 0x02, 0x94, 0x03, 0x94, 0x07, 0xe0, 0xb8, 0x7e, + 0x04, 0xab, 0x18, 0x70, 0xe8, 0x1d, 0x3d, 0x30, + 0x21, 0x1c, 0x01, 0xf0, 0x1a, 0xfd, 0x0f, 0x9a, + 0x23, 0x1c, 0x05, 0x21, 0x00, 0x92, 0x46, 0x4a, + 0x38, 0x1c, 0xec, 0xf7, 0xa8, 0xfd, 0x0a, 0x9c, + 0x7b, 0xe0, 0x28, 0x24, 0xe4, 0x43, 0x78, 0xe0, + 0x6a, 0x6c, 0x00, 0x2a, 0x2a, 0xd0, 0x2a, 0x6a, + 0x00, 0x2a, 0x27, 0xd1, 0xe9, 0x6b, 0x01, 0x39, + 0xe9, 0x63, 0xed, 0x09, 0x00, 0x64, 0x02, 0x69, + 0x6c, 0x0a, 0x68, 0x8a, 0x42, 0x01, 0xd1, 0x68, + 0x64, 0x09, 0xe0, 0x4b, 0x68, 0x53, 0x60, 0x0c, + 0xc9, 0x08, 0x39, 0x1a, 0x60, 0x6a, 0x6c, 0x8a, + 0x42, 0x01, 0xd1, 0x4a, 0x68, 0x6a, 0x64, 0x0d, + 0x9a, 0x4b, 0x69, 0x08, 0x62, 0x38, 0x1c, 0x15, + 0x78, 0x1d, 0x70, 0x01, 0x33, 0x01, 0x38, 0x01, + 0xd0, 0x01, 0x32, 0xf8, 0xe7, 0xcf, 0x61, 0x08, + 0x69, 0x05, 0x21, 0xec, 0xf7, 0xda, 0xfc, 0x00, + 0x28, 0x4d, 0xd0, 0x0f, 0xf0, 0xc4, 0xfc, 0x4a, + 0xe0, 0x0d, 0x9a, 0xa8, 0x6b, 0x00, 0x29, 0x07, + 0xd0, 0x39, 0x1c, 0x13, 0x78, 0x03, 0x70, 0x01, + 0x30, 0x01, 0x39, 0x28, 0xd0, 0x01, 0x32, 0xf8, + 0xe7, 0x80, 0xc0, 0x29, 0x6b, 0x81, 0x42, 0x00, + 0xd8, 0xe8, 0x6a, 0xa9, 0x6a, 0x04, 0x39, 0xa9, + 0x62, 0x29, 0x6b, 0x09, 0x1a, 0x01, 0x91, 0xb9, + 0x42, 0x07, 0xd3, 0x39, 0x1c, 0x13, 0x78, 0x03, + 0x70, 0x01, 0x30, 0x01, 0x39, 0x13, 0xd0, 0x01, + 0x32, 0xf8, 0xe7, 0x01, 0x99, 0x13, 0x78, 0x01, + 0x32, 0x01, 0x39, 0x03, 0x70, 0x01, 0xd0, 0x01, + 0x30, 0xf8, 0xe7, 0xe8, 0x6a, 0x01, 0x99, 0x79, + 0x1a, 0x13, 0x78, 0x03, 0x70, 0x01, 0x30, 0x01, + 0x39, 0x01, 0xd0, 0x01, 0x32, 0xf8, 0xe7, 0x29, + 0x6b, 0x81, 0x42, 0x00, 0xd8, 0xe8, 0x6a, 0x00, + 0x2e, 0x0a, 0xd0, 0x09, 0x1a, 0xb1, 0x42, 0x03, + 0xd8, 0xe8, 0x6a, 0x71, 0x1a, 0x40, 0x18, 0x00, + 0xe0, 0x80, 0x19, 0xa9, 0x6a, 0x89, 0x1b, 0xa9, + 0x62, 0xa8, 0x63, 0xa8, 0x6a, 0xc0, 0x1b, 0xa8, + 0x62, 0x28, 0x6a, 0x01, 0x30, 0x28, 0x62, 0x0f, + 0xf0, 0x6a, 0xfc, 0x20, 0x1c, 0x10, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, + 0x67, 0x03, 0x20, 0xe8, 0x66, 0x03, 0x20, 0xe9, + 0x62, 0x02, 0x20, 0xff, 0xb5, 0xed, 0x09, 0x00, + 0x65, 0x02, 0x8d, 0xb0, 0x04, 0x1c, 0x00, 0x20, + 0x01, 0x90, 0x00, 0x25, 0x0e, 0x1c, 0x17, 0x1c, + 0xab, 0x48, 0x0f, 0xf0, 0x57, 0xfc, 0x20, 0x6c, + 0x00, 0x28, 0x2a, 0xd0, 0xe0, 0x6b, 0x01, 0x38, + 0xe0, 0x63, 0x20, 0x6c, 0x01, 0x68, 0x81, 0x42, + 0x02, 0xd1, 0x00, 0x21, 0x21, 0x64, 0x09, 0xe0, + 0x42, 0x68, 0x4a, 0x60, 0x06, 0xc8, 0x08, 0x38, + 0x11, 0x60, 0x21, 0x6c, 0x81, 0x42, 0x01, 0xd1, + 0x41, 0x68, 0x21, 0x64, 0x00, 0x23, 0x42, 0x69, + 0x03, 0x62, 0x31, 0x1c, 0x13, 0x78, 0x0b, 0x70, + 0x01, 0x31, 0x01, 0x3f, 0x01, 0xd0, 0x01, 0x32, + 0xf8, 0xe7, 0x81, 0x69, 0x10, 0x9b, 0x19, 0x60, + 0x00, 0x69, 0x05, 0x21, 0xec, 0xf7, 0x48, 0xfc, + 0x00, 0x28, 0x65, 0xd0, 0x0f, 0xf0, 0x32, 0xfc, + 0xb8, 0xe0, 0x20, 0x6a, 0x00, 0x28, 0x60, 0xd0, + 0x22, 0x7e, 0x31, 0x1c, 0x60, 0x6b, 0x00, 0x2a, + 0x07, 0xd0, 0x3e, 0x1c, 0x02, 0x78, 0x01, 0x30, + 0x01, 0x3e, 0x0a, 0x70, 0x2a, 0xd0, 0x01, 0x31, + 0xf8, 0xe7, 0x80, 0xc8, 0x22, 0x6b, 0x82, 0x42, + 0x00, 0xd8, 0xe0, 0x6a, 0xa2, 0x6a, 0x04, 0x32, + 0xa2, 0x62, 0xfa, 0x1c, 0x92, 0x08, 0x92, 0x00, + 0xd5, 0x1b, 0x22, 0x6b, 0x12, 0x1a, 0xba, 0x42, + 0x07, 0xd3, 0x3e, 0x1c, 0x02, 0x78, 0x01, 0x30, + 0x01, 0x3e, 0x0a, 0x70, 0x12, 0xd0, 0x01, 0x31, + 0xf8, 0xe7, 0x13, 0x1c, 0x06, 0x78, 0x0e, 0x70, + 0x01, 0x31, 0x01, 0x3b, 0x01, 0xd0, 0x01, 0x30, + 0xf8, 0xe7, 0xe0, 0x6a, 0xbe, 0x1a, 0x02, 0x78, + 0x01, 0x30, 0x01, 0x3e, 0x0a, 0x70, 0x01, 0xd0, + 0x01, 0x31, 0xf8, 0xe7, 0x21, 0x6b, 0x81, 0x42, + 0x00, 0xd8, 0xe0, 0x6a, 0x00, 0x2d, 0x0a, 0xd0, + 0x09, 0x1a, 0xa9, 0x42, 0x03, 0xd8, 0xe0, 0x6a, + 0x69, 0x1a, 0x40, 0x18, 0x00, 0xe0, 0x40, 0x19, + 0xed, 0x09, 0x00, 0x66, 0x02, 0xa1, 0x6a, 0x49, + 0x19, 0xa1, 0x62, 0x60, 0x63, 0xa0, 0x6a, 0xc0, + 0x19, 0xa0, 0x62, 0x20, 0x6a, 0x01, 0x38, 0x20, + 0x62, 0x10, 0x9b, 0x1f, 0x60, 0x60, 0x6c, 0x00, + 0x28, 0x62, 0xd0, 0x00, 0x21, 0x02, 0x91, 0x21, + 0x7e, 0x00, 0x25, 0x87, 0x69, 0x00, 0x29, 0x73, + 0xd1, 0xf9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0xcd, + 0x1b, 0x2e, 0x1d, 0x77, 0xe0, 0xba, 0xe0, 0x7f, + 0xe0, 0x23, 0x7e, 0x42, 0x69, 0xa1, 0x6b, 0x00, + 0x2b, 0x07, 0xd0, 0x3e, 0x1c, 0x13, 0x78, 0x0b, + 0x70, 0x01, 0x31, 0x01, 0x3e, 0x27, 0xd0, 0x01, + 0x32, 0xf8, 0xe7, 0x80, 0xc1, 0x23, 0x6b, 0x8b, + 0x42, 0x00, 0xd8, 0xe1, 0x6a, 0xa6, 0x6a, 0x5b, + 0x1a, 0x04, 0x3e, 0xa6, 0x62, 0x03, 0x93, 0xbb, + 0x42, 0x07, 0xd3, 0x3e, 0x1c, 0x13, 0x78, 0x0b, + 0x70, 0x01, 0x31, 0x01, 0x3e, 0x13, 0xd0, 0x01, + 0x32, 0xf8, 0xe7, 0x03, 0x9b, 0x16, 0x78, 0x01, + 0x32, 0x01, 0x3b, 0x0e, 0x70, 0x01, 0xd0, 0x01, + 0x31, 0xf8, 0xe7, 0xe1, 0x6a, 0x03, 0x9b, 0xfe, + 0x1a, 0x13, 0x78, 0x0b, 0x70, 0x01, 0x31, 0x01, + 0x3e, 0x01, 0xd0, 0x01, 0x32, 0xf8, 0xe7, 0x22, + 0x6b, 0x8a, 0x42, 0x00, 0xd8, 0xe1, 0x6a, 0x00, + 0x2d, 0x0a, 0xd0, 0x52, 0x1a, 0xaa, 0x42, 0x03, + 0xd8, 0xe1, 0x6a, 0xaa, 0x1a, 0x89, 0x18, 0x00, + 0xe0, 0x49, 0x19, 0xa2, 0x6a, 0x52, 0x1b, 0xa2, + 0x62, 0xa1, 0x63, 0xa1, 0x6a, 0xc9, 0x1b, 0xa1, + 0x62, 0x21, 0x6a, 0x01, 0x31, 0x21, 0x62, 0xe1, + 0x6b, 0x01, 0x39, 0xe1, 0x63, 0x01, 0x68, 0x81, + 0x42, 0x03, 0xd1, 0x00, 0x21, 0x61, 0x64, 0x0a, + 0xe0, 0x64, 0xe0, 0x42, 0x68, 0x4a, 0x60, 0x06, + 0xc8, 0x08, 0x38, 0x11, 0x60, 0x61, 0x6c, 0x81, + 0x42, 0x01, 0xd1, 0x41, 0x68, 0x61, 0x64, 0x00, + 0x21, 0x01, 0x62, 0xed, 0x09, 0x00, 0x67, 0x02, + 0x00, 0x69, 0x05, 0x21, 0xec, 0xf7, 0x79, 0xfb, + 0x02, 0x99, 0x01, 0x43, 0x02, 0x91, 0x60, 0x6c, + 0x00, 0x28, 0x0e, 0xd0, 0x00, 0xe0, 0x08, 0xe0, + 0x21, 0x7e, 0x00, 0x29, 0x05, 0xd1, 0x87, 0x69, + 0xf9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0xcd, 0x1b, + 0x2e, 0x1d, 0xa2, 0x6a, 0xb9, 0x19, 0x91, 0x42, + 0x85, 0xd9, 0x02, 0x99, 0x00, 0x29, 0x3c, 0xd0, + 0x0f, 0xf0, 0x4d, 0xfb, 0x39, 0xe0, 0x16, 0x98, + 0x00, 0x28, 0x33, 0xd0, 0xe0, 0x6b, 0x04, 0xad, + 0x01, 0x30, 0xe0, 0x63, 0x00, 0x20, 0x05, 0x90, + 0x04, 0x90, 0x1c, 0x48, 0x07, 0x94, 0x09, 0x96, + 0x0a, 0x97, 0x07, 0x68, 0x08, 0x97, 0x60, 0x7e, + 0x00, 0x28, 0x0d, 0xd0, 0x60, 0x6c, 0x00, 0x28, + 0x06, 0xd0, 0x00, 0x68, 0x04, 0x90, 0x45, 0x60, + 0x60, 0x6c, 0x05, 0x90, 0x05, 0x60, 0x0b, 0xe0, + 0x65, 0x64, 0x04, 0x95, 0x05, 0x95, 0x07, 0xe0, + 0xb8, 0x7e, 0x06, 0xab, 0x18, 0x70, 0xe0, 0x1d, + 0x3d, 0x30, 0x29, 0x1c, 0x01, 0xf0, 0x3f, 0xfb, + 0x16, 0x9a, 0x2b, 0x1c, 0x05, 0x21, 0x00, 0x92, + 0x0c, 0x4a, 0x38, 0x1c, 0xec, 0xf7, 0xcd, 0xfb, + 0x0c, 0x98, 0x10, 0x9b, 0x01, 0x90, 0x0b, 0x98, + 0x18, 0x60, 0x02, 0xe0, 0x27, 0x20, 0xc0, 0x43, + 0x01, 0x90, 0x0f, 0xf0, 0x04, 0xfb, 0x01, 0x98, + 0x11, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, 0xe8, 0x66, + 0x03, 0x20, 0xe9, 0x62, 0x02, 0x20, 0x31, 0x21, + 0xc9, 0x43, 0x01, 0x62, 0xc1, 0x68, 0xca, 0x6b, + 0x01, 0x3a, 0xca, 0x63, 0x01, 0x68, 0x81, 0x42, + 0x03, 0xd1, 0xc0, 0x68, 0x00, 0x21, 0x41, 0x64, + 0x70, 0x47, 0x42, 0x68, 0x4a, 0x60, 0x06, 0xc8, + 0x08, 0x38, 0x11, 0x60, 0xc1, 0x68, 0x4a, 0x6c, + 0x82, 0x42, 0xf5, 0xd1, 0x40, 0x68, 0xed, 0x09, + 0x00, 0x68, 0x02, 0x48, 0x64, 0x70, 0x47, 0xff, + 0xb5, 0x00, 0x25, 0x0a, 0x9b, 0x09, 0x9c, 0x45, + 0x61, 0x07, 0x1c, 0x00, 0x20, 0x0d, 0x5c, 0x3e, + 0x18, 0x01, 0x30, 0x08, 0x28, 0x35, 0x76, 0xf9, + 0xdb, 0x03, 0x98, 0x80, 0x08, 0x80, 0x00, 0xe1, + 0x1c, 0x89, 0x08, 0x89, 0x00, 0x78, 0x62, 0xb9, + 0x62, 0x01, 0x21, 0x06, 0x2b, 0x3a, 0x62, 0x03, + 0xd1, 0xfb, 0x1d, 0x29, 0x33, 0x19, 0x72, 0x03, + 0xe0, 0x00, 0x24, 0xfb, 0x1d, 0x29, 0x33, 0x1c, + 0x72, 0x00, 0x24, 0x3c, 0x60, 0x7c, 0x60, 0xfc, + 0x63, 0x3c, 0x64, 0x20, 0x38, 0xf8, 0x62, 0x3a, + 0x63, 0x7a, 0x63, 0xd7, 0x60, 0x11, 0x72, 0xf8, + 0x6a, 0x80, 0x18, 0x10, 0x30, 0x10, 0x60, 0x50, + 0x60, 0x10, 0x68, 0x02, 0x60, 0x42, 0x60, 0xc7, + 0x60, 0x04, 0x72, 0xfc, 0x60, 0x0f, 0x48, 0x0f, + 0xf0, 0xa8, 0xfa, 0x0e, 0x48, 0x78, 0x61, 0x0e, + 0x48, 0x01, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x09, + 0x68, 0x39, 0x60, 0x4f, 0x60, 0x00, 0x68, 0x78, + 0x60, 0x07, 0x60, 0x02, 0xe0, 0x07, 0x60, 0x3f, + 0x60, 0x7f, 0x60, 0x08, 0x48, 0x01, 0x68, 0x01, + 0x31, 0x01, 0x60, 0x0f, 0xf0, 0x8e, 0xfa, 0x20, + 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0xa4, 0x67, 0x03, 0x20, 0x41, + 0x4e, 0x59, 0x44, 0x9c, 0x67, 0x03, 0x20, 0xa0, + 0x67, 0x03, 0x20, 0xf0, 0xb5, 0x07, 0x1c, 0x0c, + 0x30, 0x0f, 0xf0, 0x7f, 0xfa, 0x00, 0x21, 0x79, + 0x61, 0x0f, 0xf0, 0x77, 0xfa, 0x21, 0x4e, 0x30, + 0x1c, 0x0f, 0xf0, 0x77, 0xfa, 0x39, 0x68, 0x1f, + 0x48, 0xb9, 0x42, 0x02, 0xd1, 0x00, 0x21, 0x01, + 0x60, 0x09, 0xe0, 0x7a, 0x68, 0x4a, 0x60, 0x06, + 0xcf, 0x08, 0x3f, 0x11, 0x60, 0x01, 0x68, 0x8f, + 0x42, 0x01, 0xd1, 0x79, 0x68, 0x01, 0x60, 0x18, + 0x48, 0xed, 0x09, 0x00, 0x69, 0x02, 0x00, 0x25, + 0x01, 0x68, 0x01, 0x39, 0x01, 0x60, 0x3c, 0x6c, + 0x00, 0x2c, 0x1f, 0xd0, 0x15, 0x48, 0x0f, 0xf0, + 0x5b, 0xfa, 0x00, 0x20, 0xa0, 0x61, 0x2a, 0x20, + 0xc0, 0x43, 0xe0, 0x61, 0x60, 0x69, 0x66, 0x68, + 0x09, 0x21, 0xec, 0xf7, 0x6b, 0xfa, 0x05, 0x43, + 0x38, 0x6c, 0xb0, 0x42, 0x01, 0xd1, 0x00, 0x24, + 0x00, 0xe0, 0x34, 0x1c, 0x08, 0x48, 0x0f, 0xf0, + 0x57, 0xfa, 0x0a, 0x48, 0x0f, 0xf0, 0x50, 0xfa, + 0x00, 0x2c, 0xe3, 0xd1, 0x00, 0x2d, 0x01, 0xd0, + 0x0f, 0xf0, 0x46, 0xfa, 0x0f, 0xf0, 0x38, 0xfa, + 0xf0, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0xa4, 0x67, 0x03, 0x20, 0x9c, 0x67, 0x03, 0x20, + 0xa0, 0x67, 0x03, 0x20, 0x00, 0x67, 0x03, 0x20, + 0xff, 0xb5, 0x8a, 0xb0, 0x86, 0x6a, 0x00, 0x25, + 0x04, 0x1c, 0x0f, 0x1c, 0x96, 0x42, 0x02, 0xd8, + 0xd0, 0x1c, 0x80, 0x08, 0x86, 0x00, 0xe0, 0x1d, + 0x05, 0x30, 0x09, 0x90, 0x0f, 0xf0, 0x20, 0xfa, + 0x60, 0x6b, 0x01, 0x1c, 0x0a, 0x7a, 0x00, 0x2a, + 0x03, 0xd0, 0x0a, 0x68, 0x52, 0x1a, 0x10, 0x3a, + 0x00, 0xe0, 0x00, 0x22, 0xb2, 0x42, 0x00, 0xd2, + 0x09, 0x68, 0xb2, 0x42, 0x01, 0xd2, 0x88, 0x42, + 0xf0, 0xd1, 0x00, 0x20, 0xb2, 0x42, 0x20, 0xd3, + 0xa3, 0x6a, 0x9b, 0x19, 0x10, 0x33, 0x93, 0x42, + 0x0e, 0xd8, 0x8a, 0x19, 0x01, 0x23, 0x13, 0x76, + 0x51, 0x61, 0xd4, 0x61, 0x0b, 0x68, 0x10, 0x32, + 0x13, 0x60, 0x5a, 0x60, 0x0a, 0x60, 0xe2, 0x6a, + 0x92, 0x1b, 0x10, 0x3a, 0xe2, 0x62, 0x02, 0xe0, + 0xe3, 0x6a, 0x9a, 0x1a, 0xe2, 0x62, 0x08, 0x72, + 0x60, 0x6b, 0x88, 0x42, 0x01, 0xd1, 0x08, 0x68, + 0x60, 0x63, 0xc8, 0x1d, 0x09, 0x30, 0x38, 0x60, + 0x41, 0xe0, 0x0d, 0x9b, 0x00, 0x2b, 0x3b, 0xd0, + 0xe1, 0x6b, 0x01, 0xad, 0xed, 0x09, 0x00, 0x6a, + 0x02, 0x01, 0x31, 0xe1, 0x63, 0x02, 0x90, 0x01, + 0x90, 0x1f, 0x49, 0x04, 0x94, 0x05, 0x96, 0x0e, + 0x68, 0xe0, 0x1d, 0x29, 0x30, 0x06, 0x96, 0x00, + 0x7a, 0x00, 0x28, 0x0d, 0xd0, 0x20, 0x6c, 0x00, + 0x28, 0x06, 0xd0, 0x00, 0x68, 0x01, 0x90, 0x45, + 0x60, 0x20, 0x6c, 0x02, 0x90, 0x05, 0x60, 0x0b, + 0xe0, 0x25, 0x64, 0x01, 0x95, 0x02, 0x95, 0x07, + 0xe0, 0xb0, 0x7e, 0x03, 0xab, 0x18, 0x70, 0xe0, + 0x1d, 0x39, 0x30, 0x29, 0x1c, 0x01, 0xf0, 0xe6, + 0xf9, 0x10, 0x48, 0x0f, 0xf0, 0xbf, 0xf9, 0x0e, + 0x49, 0x09, 0x98, 0x09, 0x68, 0x08, 0x67, 0x09, + 0x98, 0x0f, 0xf0, 0xc4, 0xf9, 0x0d, 0x9a, 0x2b, + 0x1c, 0x09, 0x21, 0x00, 0x92, 0x0a, 0x4a, 0x30, + 0x1c, 0xec, 0xf7, 0x6a, 0xfa, 0x07, 0x98, 0x08, + 0x9d, 0x38, 0x60, 0x02, 0xe0, 0x1f, 0x25, 0xed, + 0x43, 0x38, 0x60, 0x0f, 0xf0, 0xa3, 0xf9, 0x28, + 0x1c, 0x0e, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xe8, 0x66, 0x03, 0x20, 0x00, 0x67, 0x03, + 0x20, 0xd5, 0x66, 0x02, 0x20, 0xf8, 0xb5, 0x00, + 0x21, 0xc4, 0x1f, 0x09, 0x3c, 0x00, 0x91, 0xe7, + 0x68, 0xf8, 0x1d, 0x05, 0x30, 0x06, 0x1c, 0x0f, + 0xf0, 0x91, 0xf9, 0x01, 0x23, 0x23, 0x72, 0x20, + 0x68, 0xf9, 0x6a, 0x00, 0x1b, 0x08, 0x18, 0x10, + 0x38, 0xf8, 0x62, 0x61, 0x68, 0x09, 0x7a, 0x00, + 0x29, 0x09, 0xd0, 0x10, 0x30, 0xf8, 0x62, 0x03, + 0xcc, 0x08, 0x3c, 0x08, 0x60, 0x60, 0x68, 0x21, + 0x68, 0x48, 0x60, 0x64, 0x68, 0x7c, 0x63, 0x20, + 0x68, 0x00, 0x7a, 0x00, 0x28, 0x08, 0xd0, 0xf8, + 0x6a, 0x10, 0x30, 0xf8, 0x62, 0x20, 0x68, 0x01, + 0x68, 0x4c, 0x60, 0x00, 0x68, 0x20, 0x60, 0x7c, + 0x63, 0x3c, 0x6c, 0x00, 0x25, 0x00, 0x2c, 0x5b, + 0xd0, 0x22, 0x69, 0x78, 0x6b, 0x03, 0x1c, 0xed, + 0x09, 0x00, 0x6b, 0x02, 0x01, 0x7a, 0x00, 0x29, + 0x03, 0xd0, 0x01, 0x68, 0x09, 0x1a, 0x10, 0x39, + 0x00, 0xe0, 0x00, 0x21, 0x91, 0x42, 0x00, 0xd2, + 0x00, 0x68, 0x91, 0x42, 0x01, 0xd2, 0x83, 0x42, + 0xf0, 0xd1, 0x91, 0x42, 0x43, 0xd3, 0xbb, 0x6a, + 0x9b, 0x18, 0x10, 0x33, 0x8b, 0x42, 0x0e, 0xd8, + 0x81, 0x18, 0x01, 0x23, 0x0b, 0x76, 0x48, 0x61, + 0xcf, 0x61, 0x03, 0x68, 0x10, 0x31, 0x0b, 0x60, + 0x59, 0x60, 0x01, 0x60, 0xf9, 0x6a, 0x89, 0x1a, + 0x10, 0x39, 0xf9, 0x62, 0x02, 0xe0, 0xfa, 0x6a, + 0x51, 0x1a, 0xf9, 0x62, 0x00, 0x23, 0x03, 0x72, + 0x79, 0x6b, 0x81, 0x42, 0x01, 0xd1, 0x01, 0x68, + 0x79, 0x63, 0xf9, 0x6b, 0x01, 0x39, 0xf9, 0x63, + 0x21, 0x68, 0xa1, 0x42, 0x01, 0xd1, 0x3b, 0x64, + 0x09, 0xe0, 0x62, 0x68, 0x4a, 0x60, 0x06, 0xcc, + 0x08, 0x3c, 0x11, 0x60, 0x39, 0x6c, 0xa1, 0x42, + 0x01, 0xd1, 0x61, 0x68, 0x39, 0x64, 0x10, 0x30, + 0xa0, 0x61, 0xe3, 0x61, 0x0d, 0x48, 0x0f, 0xf0, + 0x20, 0xf9, 0x09, 0x21, 0x60, 0x69, 0xec, 0xf7, + 0x36, 0xf9, 0x05, 0x43, 0x30, 0x1c, 0x0f, 0xf0, + 0x28, 0xf9, 0x07, 0x48, 0x0f, 0xf0, 0x21, 0xf9, + 0x3c, 0x6c, 0x00, 0x2c, 0xa7, 0xd1, 0x00, 0x2d, + 0x01, 0xd0, 0x0f, 0xf0, 0x16, 0xf9, 0x0f, 0xf0, + 0x08, 0xf9, 0x00, 0x98, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, 0x31, 0x21, + 0xc9, 0x43, 0xc1, 0x61, 0x00, 0x22, 0x82, 0x61, + 0xc1, 0x68, 0xcb, 0x6b, 0x01, 0x3b, 0xcb, 0x63, + 0x01, 0x68, 0x81, 0x42, 0x02, 0xd1, 0xc0, 0x68, + 0x02, 0x64, 0x70, 0x47, 0x42, 0x68, 0x4a, 0x60, + 0x06, 0xc8, 0x08, 0x38, 0x11, 0x60, 0xc1, 0x68, + 0x0a, 0x6c, 0x82, 0x42, 0xf5, 0xd1, 0x40, 0x68, + 0x08, 0x64, 0x70, 0x47, 0x00, 0x00, 0xff, 0xb5, + 0x07, 0x1c, 0xed, 0x09, 0x00, 0x6c, 0x02, 0x00, + 0x24, 0x00, 0x23, 0x0a, 0x98, 0x0b, 0x9d, 0x09, + 0x9a, 0xfb, 0x60, 0xcc, 0x5c, 0xfe, 0x18, 0x01, + 0x33, 0x08, 0x2b, 0x34, 0x74, 0xf9, 0xdb, 0x02, + 0x99, 0x00, 0x24, 0xb9, 0x61, 0x03, 0x9b, 0xfb, + 0x61, 0x7c, 0x62, 0xf8, 0x62, 0xba, 0x62, 0x01, + 0x20, 0x38, 0x63, 0x3c, 0x60, 0x7c, 0x60, 0x3c, + 0x62, 0xfc, 0x63, 0x3c, 0x64, 0x38, 0x1c, 0x12, + 0x48, 0xbf, 0x63, 0x0f, 0xf0, 0xc8, 0xf8, 0x11, + 0x48, 0xf8, 0x60, 0x11, 0x48, 0x01, 0x68, 0x00, + 0x29, 0x06, 0xd0, 0x09, 0x68, 0x39, 0x60, 0x4f, + 0x60, 0x00, 0x68, 0x78, 0x60, 0x07, 0x60, 0x03, + 0xe0, 0x07, 0x60, 0x3f, 0x60, 0x7f, 0x60, 0x38, + 0x1c, 0x0b, 0x48, 0x01, 0x68, 0x01, 0x31, 0x01, + 0x60, 0x0f, 0xf0, 0xad, 0xf8, 0x05, 0x2d, 0x03, + 0xd1, 0x05, 0x21, 0x38, 0x1c, 0x00, 0xf0, 0x6b, + 0xf8, 0x20, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x98, 0x65, 0x03, 0x20, 0x45, + 0x4d, 0x49, 0x54, 0x88, 0x65, 0x03, 0x20, 0x8c, + 0x65, 0x03, 0x20, 0xb0, 0xb5, 0x00, 0x27, 0x04, + 0x1c, 0x16, 0x48, 0x0f, 0xf0, 0x98, 0xf8, 0x20, + 0x6a, 0x00, 0x25, 0x00, 0x28, 0x02, 0xd0, 0x22, + 0x27, 0xff, 0x43, 0x00, 0xe0, 0xe5, 0x60, 0x0f, + 0xf0, 0x8a, 0xf8, 0x00, 0x2f, 0x18, 0xd1, 0x0f, + 0x48, 0x0f, 0xf0, 0x89, 0xf8, 0x21, 0x68, 0x0e, + 0x48, 0xa1, 0x42, 0x01, 0xd1, 0x05, 0x60, 0x09, + 0xe0, 0x62, 0x68, 0x4a, 0x60, 0x06, 0xcc, 0x08, + 0x3c, 0x11, 0x60, 0x01, 0x68, 0x8c, 0x42, 0x01, + 0xd1, 0x61, 0x68, 0x01, 0x60, 0x08, 0x48, 0x01, + 0x68, 0x01, 0x39, 0x01, 0x60, 0x0f, 0xf0, 0x6f, + 0xf8, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, 0x98, + 0x65, 0x03, 0x20, 0x88, 0x65, 0xed, 0x09, 0x00, + 0x6d, 0x02, 0x03, 0x20, 0x8c, 0x65, 0x03, 0x20, + 0xff, 0xb5, 0x14, 0x1c, 0x0d, 0x1c, 0x07, 0x1c, + 0x0f, 0x48, 0x09, 0x9e, 0x0f, 0xf0, 0x5e, 0xf8, + 0x38, 0x6a, 0x00, 0x28, 0x02, 0xd0, 0x22, 0x24, + 0xe4, 0x43, 0x06, 0xe0, 0x00, 0x20, 0xbd, 0x61, + 0x78, 0x62, 0xbc, 0x62, 0x03, 0x9b, 0x00, 0x24, + 0xfb, 0x62, 0x0f, 0xf0, 0x4b, 0xf8, 0x00, 0x2c, + 0x05, 0xd1, 0x05, 0x2e, 0x03, 0xd1, 0x05, 0x21, + 0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x20, 0x1c, + 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x67, 0x03, 0x20, 0xb0, 0xb5, 0x04, 0x1c, + 0x12, 0x48, 0x0f, 0x1c, 0x0f, 0xf0, 0x3a, 0xf8, + 0xe0, 0x1d, 0x29, 0x30, 0x00, 0x25, 0x05, 0x2f, + 0x0d, 0xd1, 0x21, 0x6a, 0x00, 0x29, 0x12, 0xd1, + 0x61, 0x6a, 0x00, 0x29, 0x01, 0xd0, 0xe1, 0x6a, + 0x00, 0xe0, 0xa1, 0x6a, 0x01, 0x22, 0x22, 0x62, + 0xec, 0xf7, 0x81, 0xff, 0x07, 0xe0, 0x04, 0x2f, + 0x05, 0xd1, 0x21, 0x6a, 0x00, 0x29, 0x02, 0xd0, + 0xec, 0xf7, 0xdc, 0xff, 0x25, 0x62, 0x0f, 0xf0, + 0x19, 0xf8, 0x28, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, + 0xf0, 0xb5, 0x00, 0x24, 0x05, 0x9d, 0xc4, 0x60, + 0x07, 0x1c, 0x00, 0x20, 0x0c, 0x5c, 0x3e, 0x18, + 0x01, 0x30, 0x08, 0x28, 0x34, 0x74, 0xf9, 0xdb, + 0x18, 0x37, 0x2c, 0xc7, 0x06, 0x98, 0x24, 0x3f, + 0x06, 0x28, 0x04, 0xd1, 0x01, 0x20, 0xf9, 0x1d, + 0x29, 0x31, 0x08, 0x70, 0x03, 0xe0, 0x00, 0x24, + 0xf8, 0x1d, 0x29, 0x30, 0x04, 0x70, 0x00, 0x24, + 0x3c, 0x60, 0x7c, 0x60, 0xe8, 0x1c, 0x80, 0x08, + 0x7c, 0x62, 0xbc, 0x62, 0x80, 0x00, 0xc1, 0x1d, + 0xfc, 0x62, 0x7c, 0x63, 0x01, 0x31, 0x99, 0x42, + 0xbc, 0x63, 0x0b, 0xd8, 0x57, 0x60, 0xfd, 0x6a, + 0xed, 0x09, 0x00, 0x6e, 0x02, 0x5b, 0x1a, 0x15, + 0x60, 0xfa, 0x62, 0x7d, 0x6a, 0x12, 0x18, 0x01, + 0x35, 0x08, 0x32, 0x99, 0x42, 0x7d, 0x62, 0xf3, + 0xd9, 0x0e, 0x48, 0x0e, 0xf0, 0xdd, 0xff, 0x0e, + 0x48, 0xf8, 0x60, 0x0e, 0x48, 0x01, 0x68, 0x00, + 0x29, 0x06, 0xd0, 0x09, 0x68, 0x39, 0x60, 0x4f, + 0x60, 0x00, 0x68, 0x78, 0x60, 0x07, 0x60, 0x02, + 0xe0, 0x07, 0x60, 0x3f, 0x60, 0x7f, 0x60, 0x08, + 0x48, 0x01, 0x68, 0x01, 0x31, 0x01, 0x60, 0x0e, + 0xf0, 0xc3, 0xff, 0x20, 0x1c, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x94, 0x67, 0x03, + 0x20, 0x54, 0x52, 0x41, 0x50, 0x8c, 0x67, 0x03, + 0x20, 0x90, 0x67, 0x03, 0x20, 0xf0, 0xb5, 0x25, + 0x4e, 0x07, 0x1c, 0x30, 0x1c, 0x0e, 0xf0, 0xb4, + 0xff, 0x00, 0x21, 0xf9, 0x60, 0x0e, 0xf0, 0xac, + 0xff, 0x21, 0x48, 0x0e, 0xf0, 0xad, 0xff, 0x39, + 0x68, 0x20, 0x48, 0xb9, 0x42, 0x02, 0xd1, 0x00, + 0x21, 0x01, 0x60, 0x09, 0xe0, 0x7a, 0x68, 0x4a, + 0x60, 0x06, 0xcf, 0x08, 0x3f, 0x11, 0x60, 0x01, + 0x68, 0x8f, 0x42, 0x01, 0xd1, 0x79, 0x68, 0x01, + 0x60, 0x19, 0x48, 0x00, 0x25, 0x01, 0x68, 0x01, + 0x39, 0x01, 0x60, 0xbc, 0x6b, 0x00, 0x2c, 0x1f, + 0xd0, 0x12, 0x48, 0x0e, 0xf0, 0x91, 0xff, 0x00, + 0x20, 0x60, 0x61, 0x2a, 0x20, 0xc0, 0x43, 0xa0, + 0x61, 0x20, 0x69, 0x66, 0x68, 0x08, 0x21, 0xeb, + 0xf7, 0xa1, 0xff, 0x05, 0x43, 0xb8, 0x6b, 0xb0, + 0x42, 0x01, 0xd1, 0x00, 0x24, 0x00, 0xe0, 0x34, + 0x1c, 0x09, 0x48, 0x0e, 0xf0, 0x8d, 0xff, 0x07, + 0x48, 0x0e, 0xf0, 0x86, 0xff, 0x00, 0x2c, 0xe3, + 0xd1, 0x00, 0x2d, 0x01, 0xd0, 0x0e, 0xf0, 0x7c, + 0xff, 0x0e, 0xf0, 0x6e, 0xff, 0xf0, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x67, 0x03, + 0x20, 0x94, 0x67, 0xed, 0x09, 0x00, 0x6f, 0x02, + 0x03, 0x20, 0x8c, 0x67, 0x03, 0x20, 0x90, 0x67, + 0x03, 0x20, 0xf7, 0xb5, 0x88, 0xb0, 0x04, 0x1c, + 0x00, 0x25, 0x0f, 0x1c, 0x28, 0x48, 0x0e, 0xf0, + 0x5e, 0xff, 0x61, 0x6a, 0x00, 0x20, 0x00, 0x29, + 0x0c, 0xd0, 0x01, 0x39, 0x61, 0x62, 0xa1, 0x6a, + 0x01, 0x31, 0xa1, 0x62, 0xe1, 0x6a, 0x0a, 0x68, + 0xe2, 0x62, 0x08, 0x60, 0xc8, 0x1d, 0x01, 0x30, + 0x38, 0x60, 0x35, 0xe0, 0x0a, 0x9a, 0x00, 0x2a, + 0x30, 0xd0, 0x61, 0x6b, 0x01, 0xad, 0x01, 0x31, + 0x61, 0x63, 0x02, 0x90, 0x01, 0x90, 0x1a, 0x48, + 0x04, 0x94, 0x06, 0x68, 0xe0, 0x1d, 0x29, 0x30, + 0x05, 0x96, 0x00, 0x78, 0x00, 0x28, 0x0d, 0xd0, + 0xa0, 0x6b, 0x00, 0x28, 0x06, 0xd0, 0x00, 0x68, + 0x01, 0x90, 0x45, 0x60, 0xa0, 0x6b, 0x02, 0x90, + 0x05, 0x60, 0x0b, 0xe0, 0xa5, 0x63, 0x01, 0x95, + 0x02, 0x95, 0x07, 0xe0, 0xb0, 0x7e, 0x03, 0xab, + 0x18, 0x70, 0xe0, 0x1d, 0x31, 0x30, 0x29, 0x1c, + 0x00, 0xf0, 0x49, 0xff, 0x0a, 0x9a, 0x2b, 0x1c, + 0x08, 0x21, 0x00, 0x92, 0x0a, 0x4a, 0x30, 0x1c, + 0xeb, 0xf7, 0xd7, 0xff, 0x06, 0x98, 0x07, 0x9d, + 0x38, 0x60, 0x01, 0xe0, 0x21, 0x25, 0xed, 0x43, + 0x0e, 0xf0, 0x11, 0xff, 0x28, 0x1c, 0x0b, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x67, + 0x03, 0x20, 0xe8, 0x66, 0x03, 0x20, 0x45, 0x6b, + 0x02, 0x20, 0xf0, 0xb5, 0xc6, 0x1f, 0x01, 0x3e, + 0x00, 0x27, 0x04, 0x1c, 0x1a, 0x48, 0x75, 0x68, + 0x0e, 0xf0, 0x01, 0xff, 0x68, 0x6b, 0x00, 0x28, + 0x1d, 0xd0, 0x01, 0x38, 0x68, 0x63, 0xa8, 0x6b, + 0x00, 0x21, 0x02, 0x68, 0x82, 0x42, 0x01, 0xd1, + 0xa9, 0x63, 0x09, 0xe0, 0x43, 0x68, 0x53, 0x60, + 0x0c, 0xc8, 0x08, 0x38, 0x1a, 0x60, 0xaa, 0x6b, + 0x82, 0x42, 0x01, 0xd1, 0x42, 0x68, 0xed, 0x09, + 0x00, 0x70, 0x02, 0xaa, 0x63, 0x81, 0x61, 0x44, + 0x61, 0x00, 0x69, 0x08, 0x21, 0xeb, 0xf7, 0xff, + 0xfe, 0x00, 0x28, 0x0b, 0xd0, 0x0e, 0xf0, 0xe9, + 0xfe, 0x08, 0xe0, 0x68, 0x6a, 0x01, 0x30, 0x68, + 0x62, 0xa8, 0x6a, 0x01, 0x38, 0xa8, 0x62, 0xe8, + 0x6a, 0x30, 0x60, 0xee, 0x62, 0x0e, 0xf0, 0xd1, + 0xfe, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, 0x31, + 0x21, 0xc9, 0x43, 0x81, 0x61, 0x00, 0x22, 0x42, + 0x61, 0xc1, 0x68, 0x4b, 0x6b, 0x01, 0x3b, 0x4b, + 0x63, 0x01, 0x68, 0x81, 0x42, 0x02, 0xd1, 0xc0, + 0x68, 0x82, 0x63, 0x70, 0x47, 0x42, 0x68, 0x4a, + 0x60, 0x06, 0xc8, 0x08, 0x38, 0x11, 0x60, 0xc1, + 0x68, 0x8a, 0x6b, 0x82, 0x42, 0xf5, 0xd1, 0x40, + 0x68, 0x88, 0x63, 0x70, 0x47, 0x00, 0x00, 0xf0, + 0xb5, 0x00, 0x26, 0x06, 0x9d, 0xc6, 0x60, 0x04, + 0x1c, 0x00, 0x20, 0x17, 0x1c, 0x0a, 0x5c, 0x26, + 0x18, 0x01, 0x30, 0x08, 0x28, 0x32, 0x74, 0xf9, + 0xdb, 0x07, 0x99, 0x01, 0x20, 0x06, 0x29, 0x01, + 0xd1, 0x60, 0x76, 0x01, 0xe0, 0x00, 0x26, 0x66, + 0x76, 0x05, 0x99, 0x07, 0x29, 0x01, 0xd1, 0x20, + 0x76, 0x01, 0xe0, 0x00, 0x26, 0x26, 0x76, 0x00, + 0x26, 0x65, 0x62, 0x26, 0x62, 0xe3, 0x61, 0x20, + 0x7e, 0x00, 0x28, 0x05, 0xd0, 0x28, 0x1c, 0x19, + 0x1c, 0xd9, 0xf7, 0x41, 0xfb, 0x68, 0x43, 0x03, + 0x1c, 0x98, 0x00, 0x38, 0x18, 0x20, 0x63, 0xa3, + 0x62, 0xe7, 0x62, 0x67, 0x63, 0x66, 0x64, 0xa7, + 0x63, 0xe6, 0x63, 0x26, 0x64, 0x26, 0x60, 0x66, + 0x60, 0x0e, 0x48, 0x0e, 0xf0, 0x7a, 0xfe, 0x0d, + 0x48, 0xe0, 0x60, 0x0d, 0x48, 0x01, 0x68, 0x00, + 0x29, 0x06, 0xd0, 0x09, 0x68, 0x21, 0x60, 0x4c, + 0x60, 0x00, 0x68, 0x60, 0x60, 0x04, 0x60, 0x02, + 0xe0, 0xed, 0x09, 0x00, 0x71, 0x02, 0x04, 0x60, + 0x24, 0x60, 0x64, 0x60, 0x07, 0x48, 0x01, 0x68, + 0x01, 0x31, 0x01, 0x60, 0x0e, 0xf0, 0x60, 0xfe, + 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x54, 0x67, 0x03, 0x20, 0x55, 0x45, 0x55, 0x51, + 0x4c, 0x67, 0x03, 0x20, 0x50, 0x67, 0x03, 0x20, + 0xf0, 0xb5, 0x07, 0x1c, 0x31, 0x48, 0x0e, 0xf0, + 0x53, 0xfe, 0x00, 0x21, 0xf9, 0x60, 0x0e, 0xf0, + 0x4b, 0xfe, 0x2f, 0x48, 0x0e, 0xf0, 0x4c, 0xfe, + 0x39, 0x68, 0x2e, 0x48, 0xb9, 0x42, 0x02, 0xd1, + 0x00, 0x21, 0x01, 0x60, 0x09, 0xe0, 0x7a, 0x68, + 0x4a, 0x60, 0x06, 0xcf, 0x08, 0x3f, 0x11, 0x60, + 0x01, 0x68, 0x8f, 0x42, 0x01, 0xd1, 0x79, 0x68, + 0x01, 0x60, 0x27, 0x48, 0x00, 0x25, 0x01, 0x68, + 0x01, 0x39, 0x01, 0x60, 0x7c, 0x6c, 0x00, 0x2c, + 0x19, 0xd0, 0x20, 0x48, 0x0e, 0xf0, 0x30, 0xfe, + 0x2b, 0x20, 0xc0, 0x43, 0x20, 0x62, 0x20, 0x69, + 0x66, 0x68, 0x04, 0x21, 0xeb, 0xf7, 0x42, 0xfe, + 0x05, 0x43, 0x78, 0x6c, 0xb0, 0x42, 0x01, 0xd1, + 0x00, 0x24, 0x00, 0xe0, 0x34, 0x1c, 0x18, 0x48, + 0x0e, 0xf0, 0x2e, 0xfe, 0x15, 0x48, 0x0e, 0xf0, + 0x27, 0xfe, 0x00, 0x2c, 0xe5, 0xd1, 0x3c, 0x6c, + 0x00, 0x2c, 0x19, 0xd0, 0x11, 0x48, 0x0e, 0xf0, + 0x13, 0xfe, 0x2b, 0x20, 0xc0, 0x43, 0x20, 0x62, + 0x20, 0x69, 0x66, 0x68, 0x04, 0x21, 0xeb, 0xf7, + 0x25, 0xfe, 0x05, 0x43, 0x38, 0x6c, 0xb0, 0x42, + 0x01, 0xd1, 0x00, 0x24, 0x00, 0xe0, 0x34, 0x1c, + 0x09, 0x48, 0x0e, 0xf0, 0x11, 0xfe, 0x07, 0x48, + 0x0e, 0xf0, 0x0a, 0xfe, 0x00, 0x2c, 0xe5, 0xd1, + 0x00, 0x2d, 0x01, 0xd0, 0x0e, 0xf0, 0x00, 0xfe, + 0x0e, 0xf0, 0xf2, 0xfd, 0xf0, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, + 0x54, 0x67, 0x03, 0x20, 0xed, 0x09, 0x00, 0x72, + 0x02, 0x4c, 0x67, 0x03, 0x20, 0x50, 0x67, 0x03, + 0x20, 0xff, 0xb5, 0x8b, 0xb0, 0x06, 0x1c, 0x00, + 0x25, 0x0c, 0x1c, 0x17, 0x1c, 0x63, 0x48, 0x0e, + 0xf0, 0xe1, 0xfd, 0x32, 0x7e, 0x00, 0x2a, 0x01, + 0xd0, 0x00, 0x20, 0x15, 0xe0, 0x73, 0x6c, 0x01, + 0x20, 0x00, 0x2b, 0x0a, 0x93, 0x10, 0xd0, 0x31, + 0x6a, 0x00, 0x29, 0x0d, 0xd0, 0x5c, 0x49, 0x09, + 0x68, 0x73, 0x7e, 0x00, 0x2b, 0x07, 0xd1, 0x0e, + 0x9b, 0x00, 0x2b, 0x04, 0xd0, 0x0a, 0x9b, 0x1b, + 0x7a, 0x89, 0x7e, 0x8b, 0x42, 0x00, 0xdc, 0xb0, + 0x6a, 0x3b, 0x18, 0xb1, 0x6a, 0x00, 0x20, 0x99, + 0x42, 0x34, 0xd2, 0x0e, 0x9b, 0x00, 0x2b, 0x2e, + 0xd0, 0xf1, 0x6b, 0x01, 0xad, 0x01, 0x31, 0xf1, + 0x63, 0x4f, 0x49, 0x04, 0x96, 0x02, 0x90, 0x01, + 0x90, 0x06, 0x94, 0x07, 0x97, 0x0f, 0x68, 0x05, + 0x97, 0x70, 0x7e, 0x00, 0x28, 0x0d, 0xd0, 0x70, + 0x6c, 0x00, 0x28, 0x06, 0xd0, 0x00, 0x68, 0x01, + 0x90, 0x45, 0x60, 0x70, 0x6c, 0x02, 0x90, 0x05, + 0x60, 0x0b, 0xe0, 0x75, 0x64, 0x01, 0x95, 0x02, + 0x95, 0x07, 0xe0, 0xb8, 0x7e, 0x03, 0xab, 0x18, + 0x70, 0xf0, 0x1d, 0x3d, 0x30, 0x29, 0x1c, 0x00, + 0xf0, 0xbd, 0xfd, 0x0e, 0x9a, 0x2b, 0x1c, 0x04, + 0x21, 0x00, 0x92, 0x3e, 0x4a, 0x38, 0x1c, 0xeb, + 0xf7, 0x4b, 0xfe, 0x09, 0x9d, 0x6a, 0xe0, 0x2d, + 0x25, 0xed, 0x43, 0x67, 0xe0, 0x71, 0x6c, 0x00, + 0x29, 0x28, 0xd0, 0x31, 0x6a, 0x00, 0x29, 0x25, + 0xd1, 0xf1, 0x6b, 0x01, 0x39, 0xf1, 0x63, 0x71, + 0x6c, 0x0a, 0x68, 0x8a, 0x42, 0x01, 0xd1, 0x70, + 0x64, 0x09, 0xe0, 0x4b, 0x68, 0x53, 0x60, 0x0c, + 0xc9, 0x08, 0x39, 0x1a, 0x60, 0x72, 0x6c, 0x8a, + 0x42, 0x01, 0xd1, 0x4a, 0x68, 0x72, 0x64, 0x4a, + 0x69, 0x08, 0x62, 0x38, 0x1c, 0x23, 0x68, 0xed, + 0x09, 0x00, 0x73, 0x02, 0x01, 0x38, 0x08, 0xc2, + 0x01, 0xd0, 0x04, 0x34, 0xf9, 0xe7, 0xcf, 0x61, + 0x08, 0x69, 0x04, 0x21, 0xeb, 0xf7, 0x7f, 0xfd, + 0x00, 0x28, 0x3e, 0xd0, 0x0e, 0xf0, 0x69, 0xfd, + 0x3b, 0xe0, 0xb0, 0x6b, 0x00, 0x2a, 0x06, 0xd0, + 0x39, 0x1c, 0x22, 0x68, 0x01, 0x39, 0x04, 0xc0, + 0x26, 0xd0, 0x04, 0x34, 0xf9, 0xe7, 0x80, 0xc0, + 0x31, 0x6b, 0x81, 0x42, 0x00, 0xd8, 0xf0, 0x6a, + 0xb1, 0x6a, 0x01, 0x39, 0xb1, 0x62, 0x31, 0x6b, + 0x09, 0x1a, 0x00, 0xd5, 0x03, 0x31, 0x89, 0x10, + 0xb9, 0x42, 0x06, 0xd3, 0x39, 0x1c, 0x22, 0x68, + 0x01, 0x39, 0x04, 0xc0, 0x10, 0xd0, 0x04, 0x34, + 0xf9, 0xe7, 0x0a, 0x1c, 0x08, 0xcc, 0x01, 0x3a, + 0x03, 0x60, 0x01, 0xd0, 0x04, 0x30, 0xf9, 0xe7, + 0xf0, 0x6a, 0x79, 0x1a, 0x22, 0x68, 0x01, 0x39, + 0x04, 0xc0, 0x01, 0xd0, 0x04, 0x34, 0xf9, 0xe7, + 0x31, 0x6b, 0x81, 0x42, 0x02, 0xd8, 0xf0, 0x6a, + 0xb0, 0x63, 0x00, 0xe0, 0xb0, 0x63, 0xb0, 0x6a, + 0xc0, 0x1b, 0xb0, 0x62, 0x30, 0x6a, 0x01, 0x30, + 0x30, 0x62, 0x0e, 0xf0, 0x1e, 0xfd, 0x28, 0x1c, + 0x0f, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, 0xe8, 0x66, + 0x03, 0x20, 0x25, 0x71, 0x02, 0x20, 0xff, 0xb5, + 0x8c, 0xb0, 0x05, 0x1c, 0x00, 0x20, 0x01, 0x90, + 0x0c, 0x1c, 0x17, 0x1c, 0x95, 0x48, 0x0e, 0xf0, + 0x0c, 0xfd, 0x29, 0x6c, 0x00, 0x20, 0x00, 0x29, + 0x27, 0xd0, 0xe9, 0x6b, 0x01, 0x39, 0xe9, 0x63, + 0x29, 0x6c, 0x0a, 0x68, 0x8a, 0x42, 0x01, 0xd1, + 0x28, 0x64, 0x09, 0xe0, 0x4b, 0x68, 0x53, 0x60, + 0x0c, 0xc9, 0x08, 0x39, 0x1a, 0x60, 0x2a, 0x6c, + 0x8a, 0x42, 0x01, 0xd1, 0x4a, 0x68, 0x2a, 0x64, + 0x4a, 0x69, 0x08, 0x62, 0x88, 0x69, 0x13, 0x68, + 0x01, 0x38, 0xed, 0x09, 0x00, 0x74, 0x02, 0x08, + 0xc4, 0x01, 0xd0, 0x04, 0x32, 0xf9, 0xe7, 0x88, + 0x69, 0x0f, 0x9b, 0x18, 0x60, 0x08, 0x69, 0x04, + 0x21, 0xeb, 0xf7, 0xff, 0xfc, 0x00, 0x28, 0x6f, + 0xd0, 0x0e, 0xf0, 0xe9, 0xfc, 0xb8, 0xe0, 0x29, + 0x6a, 0x00, 0x29, 0x6a, 0xd0, 0x2a, 0x7e, 0x69, + 0x6b, 0x00, 0x2a, 0x06, 0xd0, 0x3e, 0x1c, 0x04, + 0xc9, 0x01, 0x3e, 0x22, 0x60, 0x26, 0xd0, 0x04, + 0x34, 0xf9, 0xe7, 0x80, 0xc9, 0x2a, 0x6b, 0x8a, + 0x42, 0x00, 0xd8, 0xe9, 0x6a, 0xaa, 0x6a, 0x01, + 0x32, 0xaa, 0x62, 0x2a, 0x6b, 0x52, 0x1a, 0x00, + 0xd5, 0x03, 0x32, 0x92, 0x10, 0xba, 0x42, 0x06, + 0xd3, 0x3e, 0x1c, 0x04, 0xc9, 0x01, 0x3e, 0x22, + 0x60, 0x10, 0xd0, 0x04, 0x34, 0xf9, 0xe7, 0x13, + 0x1c, 0x0e, 0x68, 0x01, 0x3b, 0x40, 0xc4, 0x01, + 0xd0, 0x04, 0x31, 0xf9, 0xe7, 0xe9, 0x6a, 0xbe, + 0x1a, 0x04, 0xc9, 0x01, 0x3e, 0x22, 0x60, 0x01, + 0xd0, 0x04, 0x34, 0xf9, 0xe7, 0x2a, 0x6b, 0x8a, + 0x42, 0x02, 0xd8, 0xe9, 0x6a, 0x69, 0x63, 0x00, + 0xe0, 0x69, 0x63, 0xa9, 0x6a, 0xc9, 0x19, 0xa9, + 0x62, 0x29, 0x6a, 0x01, 0x39, 0x29, 0x62, 0x0f, + 0x9b, 0x1f, 0x60, 0x69, 0x6c, 0x00, 0x29, 0x73, + 0xd0, 0x2a, 0x7e, 0x00, 0x2a, 0x00, 0xd1, 0x01, + 0x26, 0x00, 0x22, 0x02, 0x92, 0x61, 0xe0, 0x2f, + 0x7e, 0x4a, 0x69, 0xa8, 0x6b, 0x00, 0x2f, 0x06, + 0xd0, 0x1e, 0x1c, 0x17, 0x68, 0x01, 0x3e, 0x80, + 0xc0, 0x27, 0xd0, 0x04, 0x32, 0xf9, 0xe7, 0x08, + 0xc0, 0x2f, 0x6b, 0x87, 0x42, 0x00, 0xd8, 0xe8, + 0x6a, 0xac, 0x6a, 0x01, 0x3c, 0xac, 0x62, 0x3f, + 0x1a, 0x00, 0xd5, 0x03, 0x37, 0xbf, 0x10, 0x9f, + 0x42, 0x08, 0xd3, 0x1e, 0x1c, 0x17, 0x68, 0x01, + 0x3e, 0x80, 0xc0, 0x12, 0xd0, 0x04, 0x32, 0xf9, + 0xe7, 0x85, 0xe0, 0x4b, 0xe0, 0xed, 0x09, 0x00, + 0x75, 0x02, 0x3c, 0x1c, 0x40, 0xca, 0x01, 0x3c, + 0x06, 0x60, 0x01, 0xd0, 0x04, 0x30, 0xf9, 0xe7, + 0xe8, 0x6a, 0xde, 0x1b, 0x17, 0x68, 0x01, 0x3e, + 0x80, 0xc0, 0x01, 0xd0, 0x04, 0x32, 0xf9, 0xe7, + 0x2a, 0x6b, 0x82, 0x42, 0x02, 0xd8, 0xe8, 0x6a, + 0xa8, 0x63, 0x00, 0xe0, 0xa8, 0x63, 0xa8, 0x6a, + 0xc0, 0x1a, 0xa8, 0x62, 0x28, 0x6a, 0x01, 0x30, + 0x28, 0x62, 0xe8, 0x6b, 0x01, 0x38, 0xe8, 0x63, + 0x08, 0x68, 0x88, 0x42, 0x02, 0xd1, 0x00, 0x20, + 0x68, 0x64, 0x09, 0xe0, 0x4a, 0x68, 0x42, 0x60, + 0x05, 0xc9, 0x08, 0x39, 0x10, 0x60, 0x68, 0x6c, + 0x88, 0x42, 0x01, 0xd1, 0x48, 0x68, 0x68, 0x64, + 0x00, 0x20, 0x08, 0x62, 0x08, 0x69, 0x04, 0x21, + 0xeb, 0xf7, 0x56, 0xfc, 0x02, 0x9a, 0x02, 0x43, + 0x02, 0x92, 0x28, 0x7e, 0x69, 0x6c, 0x00, 0x28, + 0x00, 0xd1, 0x01, 0x26, 0x00, 0x29, 0x04, 0xd0, + 0x8b, 0x69, 0xaa, 0x6a, 0x98, 0x19, 0x90, 0x42, + 0x98, 0xd9, 0x02, 0x9a, 0x00, 0x2a, 0x3d, 0xd0, + 0x0e, 0xf0, 0x30, 0xfc, 0x00, 0xe0, 0x39, 0xe0, + 0x38, 0xe0, 0x15, 0x99, 0x00, 0x29, 0x32, 0xd0, + 0xe9, 0x6b, 0x03, 0xae, 0x01, 0x31, 0xe9, 0x63, + 0x04, 0x90, 0x03, 0x90, 0x1c, 0x48, 0x06, 0x95, + 0x08, 0x94, 0x09, 0x97, 0x07, 0x68, 0x07, 0x97, + 0x68, 0x7e, 0x00, 0x28, 0x0d, 0xd0, 0x68, 0x6c, + 0x00, 0x28, 0x06, 0xd0, 0x00, 0x68, 0x03, 0x90, + 0x46, 0x60, 0x68, 0x6c, 0x04, 0x90, 0x06, 0x60, + 0x0b, 0xe0, 0x6e, 0x64, 0x03, 0x96, 0x04, 0x96, + 0x07, 0xe0, 0xb8, 0x7e, 0x05, 0xab, 0x18, 0x70, + 0xe8, 0x1d, 0x3d, 0x30, 0x31, 0x1c, 0x00, 0xf0, + 0x21, 0xfc, 0x15, 0x9a, 0x33, 0x1c, 0x04, 0x21, + 0x00, 0x92, 0x0c, 0x4a, 0x38, 0x1c, 0xeb, 0xf7, + 0xaf, 0xfc, 0x0b, 0x98, 0x0f, 0x9b, 0x01, 0x90, + 0xed, 0x09, 0x00, 0x76, 0x02, 0x0a, 0x98, 0x18, + 0x60, 0x02, 0xe0, 0x2c, 0x20, 0xc0, 0x43, 0x01, + 0x90, 0x0e, 0xf0, 0xe6, 0xfb, 0x01, 0x98, 0x10, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x00, 0x67, 0x03, 0x20, 0xe8, 0x66, 0x03, + 0x20, 0x25, 0x71, 0x02, 0x20, 0x31, 0x21, 0xc9, + 0x43, 0x01, 0x62, 0xc1, 0x68, 0xca, 0x6b, 0x01, + 0x3a, 0xca, 0x63, 0x01, 0x68, 0x81, 0x42, 0x03, + 0xd1, 0xc0, 0x68, 0x00, 0x21, 0x41, 0x64, 0x70, + 0x47, 0x42, 0x68, 0x4a, 0x60, 0x06, 0xc8, 0x08, + 0x38, 0x11, 0x60, 0xc1, 0x68, 0x4a, 0x6c, 0x82, + 0x42, 0xf5, 0xd1, 0x40, 0x68, 0x48, 0x64, 0x70, + 0x47, 0x33, 0x30, 0x34, 0x28, 0x01, 0xd2, 0x43, + 0x00, 0x9f, 0x44, 0x9b, 0xe0, 0x98, 0xe0, 0x95, + 0xe0, 0x92, 0xe0, 0x8f, 0xe0, 0x8c, 0xe0, 0x89, + 0xe0, 0x86, 0xe0, 0x83, 0xe0, 0x80, 0xe0, 0x7d, + 0xe0, 0x7a, 0xe0, 0x77, 0xe0, 0x74, 0xe0, 0x71, + 0xe0, 0x6e, 0xe0, 0x6b, 0xe0, 0x68, 0xe0, 0x65, + 0xe0, 0x62, 0xe0, 0x5f, 0xe0, 0x5c, 0xe0, 0x59, + 0xe0, 0x56, 0xe0, 0x53, 0xe0, 0x50, 0xe0, 0x4d, + 0xe0, 0x4a, 0xe0, 0x47, 0xe0, 0x44, 0xe0, 0x41, + 0xe0, 0x3e, 0xe0, 0x3b, 0xe0, 0x38, 0xe0, 0x35, + 0xe0, 0x32, 0xe0, 0x2f, 0xe0, 0x2c, 0xe0, 0x29, + 0xe0, 0x26, 0xe0, 0x23, 0xe0, 0x20, 0xe0, 0x1d, + 0xe0, 0x1a, 0xe0, 0x17, 0xe0, 0x14, 0xe0, 0x11, + 0xe0, 0x0e, 0xe0, 0x0b, 0xe0, 0x08, 0xe0, 0x05, + 0xe0, 0x02, 0xe0, 0xff, 0xe7, 0x34, 0xa0, 0x70, + 0x47, 0x36, 0xa0, 0x70, 0x47, 0x39, 0xa0, 0x70, + 0x47, 0x3d, 0xa0, 0x70, 0x47, 0x41, 0xa0, 0x70, + 0x47, 0x45, 0xa0, 0x70, 0x47, 0x49, 0xa0, 0x70, + 0x47, 0x4d, 0xa0, 0x70, 0x47, 0x51, 0xa0, 0x70, + 0x47, 0x55, 0xa0, 0x70, 0x47, 0x58, 0xa0, 0x70, + 0x47, 0x5c, 0xa0, 0xed, 0x09, 0x00, 0x77, 0x02, + 0x70, 0x47, 0x60, 0xa0, 0x70, 0x47, 0x64, 0xa0, + 0x70, 0x47, 0x69, 0xa0, 0x70, 0x47, 0x6c, 0xa0, + 0x70, 0x47, 0x70, 0xa0, 0x70, 0x47, 0x73, 0xa0, + 0x70, 0x47, 0x77, 0xa0, 0x70, 0x47, 0x7b, 0xa0, + 0x70, 0x47, 0x7f, 0xa0, 0x70, 0x47, 0x83, 0xa0, + 0x70, 0x47, 0x88, 0xa0, 0x70, 0x47, 0x8b, 0xa0, + 0x70, 0x47, 0x8f, 0xa0, 0x70, 0x47, 0x93, 0xa0, + 0x70, 0x47, 0x96, 0xa0, 0x70, 0x47, 0x9a, 0xa0, + 0x70, 0x47, 0x9e, 0xa0, 0x70, 0x47, 0xa2, 0xa0, + 0x70, 0x47, 0xa6, 0xa0, 0x70, 0x47, 0xa9, 0xa0, + 0x70, 0x47, 0xad, 0xa0, 0x70, 0x47, 0xb0, 0xa0, + 0x70, 0x47, 0xb4, 0xa0, 0x70, 0x47, 0xb7, 0xa0, + 0x70, 0x47, 0xba, 0xa0, 0x70, 0x47, 0xbd, 0xa0, + 0x70, 0x47, 0xc1, 0xa0, 0x70, 0x47, 0xc5, 0xa0, + 0x70, 0x47, 0xc8, 0xa0, 0x70, 0x47, 0xcb, 0xa0, + 0x70, 0x47, 0xce, 0xa0, 0x70, 0x47, 0xd1, 0xa0, + 0x70, 0x47, 0xd4, 0xa0, 0x70, 0x47, 0xd8, 0xa0, + 0x70, 0x47, 0xdb, 0xa0, 0x70, 0x47, 0xde, 0xa0, + 0x70, 0x47, 0xe1, 0xa0, 0x70, 0x47, 0xe6, 0xa0, + 0x70, 0x47, 0xea, 0xa0, 0x70, 0x47, 0xec, 0xa0, + 0x70, 0x47, 0xef, 0xa0, 0x70, 0x47, 0x4e, 0x55, + 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, + 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x45, 0x4e, 0x44, + 0x5f, 0x4f, 0x46, 0x5f, 0x4c, 0x4f, 0x47, 0x00, + 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x47, 0x52, 0x4f, + 0x55, 0x50, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x45, 0x44, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x00, + 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x52, 0x49, + 0x56, 0x45, 0x52, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x78, 0x02, 0x4e, 0x55, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x4e, + 0x41, 0x42, 0x4c, 0x45, 0x00, 0x00, 0x00, 0x4e, + 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x59, 0x00, + 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x55, + 0x4e, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x4e, + 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x48, 0x49, + 0x53, 0x52, 0x00, 0x4e, 0x55, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4d, 0x41, + 0x49, 0x4c, 0x42, 0x4f, 0x58, 0x00, 0x00, 0x4e, + 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, + 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4d, 0x45, + 0x53, 0x53, 0x41, 0x47, 0x45, 0x00, 0x00, 0x4e, + 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x4e, + 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x50, 0x49, 0x50, 0x45, 0x00, 0x4e, + 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x45, + 0x52, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x4f, + 0x4f, 0x4c, 0x00, 0x4e, 0x55, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x52, + 0x45, 0x45, 0x4d, 0x50, 0x54, 0x00, 0x00, 0x4e, + 0x55, 0xed, 0x09, 0x00, 0x79, 0x02, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, + 0x52, 0x49, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x00, + 0x4e, 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x51, 0x55, 0x45, 0x55, 0x45, + 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, + 0x45, 0x53, 0x55, 0x4d, 0x45, 0x00, 0x00, 0x00, + 0x4e, 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x53, 0x45, 0x4d, 0x41, 0x50, + 0x48, 0x4f, 0x52, 0x45, 0x00, 0x00, 0x00, 0x00, + 0x4e, 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x00, + 0x4e, 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, + 0x55, 0x53, 0x50, 0x45, 0x4e, 0x44, 0x00, 0x00, + 0x4e, 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x54, 0x41, 0x53, 0x4b, 0x00, + 0x4e, 0x55, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x52, + 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x56, + 0x45, 0x43, 0x54, 0x4f, 0x52, 0x00, 0x00, 0x00, + 0x4e, 0x55, 0x5f, 0x4d, 0x41, 0x49, 0x4c, 0x42, + 0x4f, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x45, 0x44, 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x4d, + 0x41, 0x49, 0x4c, 0x42, 0x4f, 0x58, 0x5f, 0x45, + 0x4d, 0x50, 0x54, 0x59, 0x00, 0x00, 0x00, 0x00, + 0x4e, 0x55, 0x5f, 0x4d, 0x41, 0x49, 0x4c, 0x42, + 0x4f, 0x58, 0x5f, 0x46, 0x55, 0x4c, 0x4c, 0x00, + 0x4e, 0x55, 0x5f, 0x4d, 0xed, 0x09, 0x00, 0x7a, + 0x02, 0x41, 0x49, 0x4c, 0x42, 0x4f, 0x58, 0x5f, + 0x52, 0x45, 0x53, 0x45, 0x54, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, + 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, + 0x4f, 0x52, 0x45, 0x5f, 0x4c, 0x49, 0x53, 0x52, + 0x53, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, + 0x4e, 0x4f, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x4e, 0x55, 0x5f, + 0x4e, 0x4f, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x41, + 0x42, 0x4c, 0x45, 0x44, 0x00, 0x4e, 0x55, 0x5f, + 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, + 0x45, 0x4e, 0x54, 0x00, 0x00, 0x4e, 0x55, 0x5f, + 0x4e, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x47, 0x49, + 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, + 0x45, 0x44, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, + 0x50, 0x49, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x4c, + 0x45, 0x54, 0x45, 0x44, 0x00, 0x4e, 0x55, 0x5f, + 0x50, 0x49, 0x50, 0x45, 0x5f, 0x45, 0x4d, 0x50, + 0x54, 0x59, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, + 0x50, 0x49, 0x50, 0x45, 0x5f, 0x46, 0x55, 0x4c, + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, + 0x50, 0x49, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x53, + 0x45, 0x54, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x5f, + 0x50, 0x4f, 0x4f, 0x4c, 0x5f, 0x44, 0x45, 0x4c, + 0x45, 0x54, 0x45, 0x44, 0x00, 0x4e, 0x55, 0x5f, + 0x51, 0x55, 0x45, 0x55, 0x45, 0x5f, 0x44, 0x45, + 0x4c, 0x45, 0x54, 0x45, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x55, 0x5f, 0x51, 0x55, 0x45, 0x55, + 0x45, 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, 0xed, + 0x09, 0x00, 0x7b, 0x02, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x51, 0x55, 0x45, 0x55, 0x45, 0x5f, 0x46, + 0x55, 0x4c, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x51, 0x55, 0x45, 0x55, 0x45, 0x5f, 0x52, + 0x45, 0x53, 0x45, 0x54, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x53, 0x45, 0x4d, 0x41, 0x50, 0x48, 0x4f, + 0x52, 0x45, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x45, 0x44, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x53, 0x45, 0x4d, 0x41, 0x50, 0x48, 0x4f, + 0x52, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, + 0x00, 0x00, 0x4e, 0x55, 0x5f, 0x54, 0x49, 0x4d, + 0x45, 0x4f, 0x55, 0x54, 0x00, 0x00, 0x4e, 0x55, + 0x5f, 0x55, 0x4e, 0x41, 0x56, 0x41, 0x49, 0x4c, + 0x41, 0x42, 0x4c, 0x45, 0x00, 0x00, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x00, 0x00, 0x90, 0xb5, + 0x00, 0x24, 0xc4, 0x60, 0x07, 0x1c, 0x00, 0x20, + 0x0a, 0x5c, 0x3b, 0x18, 0x01, 0x30, 0x08, 0x28, + 0x1a, 0x74, 0xf9, 0xdb, 0xbc, 0x61, 0x3c, 0x62, + 0xfc, 0x61, 0x3c, 0x60, 0x7c, 0x60, 0x0e, 0x48, + 0x0e, 0xf0, 0x27, 0xf9, 0x0e, 0x48, 0xf8, 0x60, + 0x0e, 0x48, 0x01, 0x68, 0x00, 0x29, 0x06, 0xd0, + 0x09, 0x68, 0x39, 0x60, 0x4f, 0x60, 0x00, 0x68, + 0x78, 0x60, 0x07, 0x60, 0x02, 0xe0, 0x07, 0x60, + 0x3f, 0x60, 0x7f, 0x60, 0x08, 0x48, 0x01, 0x68, + 0x01, 0x31, 0x01, 0x60, 0x0e, 0xf0, 0x0d, 0xf9, + 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x84, 0x67, 0x03, 0x20, 0x54, 0x4e, + 0x56, 0x45, 0x7c, 0x67, 0x03, 0x20, 0x80, 0x67, + 0x03, 0x20, 0xf0, 0xb5, 0x24, 0x4e, 0x07, 0x1c, + 0x30, 0x1c, 0x0e, 0xf0, 0xfe, 0xf8, 0x00, 0x21, + 0xf9, 0x60, 0x0e, 0xf0, 0xf6, 0xf8, 0x20, 0x48, + 0x0e, 0xf0, 0xed, 0x09, 0x00, 0x7c, 0x02, 0xf7, + 0xf8, 0x39, 0x68, 0x1f, 0x48, 0xb9, 0x42, 0x02, + 0xd1, 0x00, 0x21, 0x01, 0x60, 0x09, 0xe0, 0x7a, + 0x68, 0x4a, 0x60, 0x06, 0xcf, 0x08, 0x3f, 0x11, + 0x60, 0x01, 0x68, 0x8f, 0x42, 0x01, 0xd1, 0x79, + 0x68, 0x01, 0x60, 0x18, 0x48, 0x00, 0x25, 0x01, + 0x68, 0x01, 0x39, 0x01, 0x60, 0x3c, 0x6a, 0x00, + 0x2c, 0x1d, 0xd0, 0x11, 0x48, 0x0e, 0xf0, 0xdb, + 0xf8, 0x01, 0x20, 0xc0, 0x43, 0xe0, 0x61, 0xa0, + 0x69, 0x66, 0x68, 0x07, 0x21, 0xeb, 0xf7, 0xed, + 0xf8, 0x05, 0x43, 0x38, 0x6a, 0xb0, 0x42, 0x01, + 0xd1, 0x00, 0x24, 0x00, 0xe0, 0x34, 0x1c, 0x09, + 0x48, 0x0e, 0xf0, 0xd9, 0xf8, 0x07, 0x48, 0x0e, + 0xf0, 0xd2, 0xf8, 0x00, 0x2c, 0xe5, 0xd1, 0x00, + 0x2d, 0x01, 0xd0, 0x0e, 0xf0, 0xc8, 0xf8, 0x0e, + 0xf0, 0xba, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x00, 0x67, 0x03, 0x20, 0x84, + 0x67, 0x03, 0x20, 0x7c, 0x67, 0x03, 0x20, 0x80, + 0x67, 0x03, 0x20, 0xf0, 0xb5, 0x82, 0xb0, 0x04, + 0x1c, 0x15, 0x1c, 0x0f, 0x1c, 0x2d, 0x48, 0x0e, + 0xf0, 0xaa, 0xf8, 0xa8, 0x08, 0x03, 0xd3, 0xa0, + 0x69, 0x38, 0x40, 0xa0, 0x61, 0x02, 0xe0, 0xa0, + 0x69, 0x38, 0x43, 0xa0, 0x61, 0x27, 0x6a, 0x00, + 0x2f, 0x43, 0xd0, 0x00, 0x21, 0x01, 0x91, 0x3e, + 0x68, 0x00, 0x91, 0xa0, 0x69, 0x39, 0x69, 0x3a, + 0x7d, 0x08, 0x40, 0x92, 0x08, 0x04, 0xd3, 0x01, + 0x22, 0x81, 0x42, 0x00, 0xd0, 0x00, 0x22, 0x10, + 0x1c, 0x7d, 0x68, 0x00, 0x28, 0x24, 0xd0, 0xe0, + 0x69, 0x01, 0x38, 0xe0, 0x61, 0x38, 0x7d, 0x40, + 0x08, 0x03, 0xd3, 0x38, 0x69, 0x01, 0x99, 0x01, + 0x43, 0x01, 0x91, 0x38, 0x68, 0xb8, 0x42, 0x02, + 0xd1, 0x00, 0x20, 0x20, 0x62, 0x09, 0xe0, 0x79, + 0x68, 0x41, 0x60, 0x03, 0xcf, 0xed, 0x09, 0x00, + 0x7d, 0x02, 0x08, 0x3f, 0x08, 0x60, 0x20, 0x6a, + 0xb8, 0x42, 0x01, 0xd1, 0x78, 0x68, 0x20, 0x62, + 0x00, 0x20, 0xf8, 0x61, 0xa0, 0x69, 0x07, 0x21, + 0x38, 0x62, 0xb8, 0x69, 0xeb, 0xf7, 0x84, 0xf8, + 0x00, 0x99, 0x01, 0x43, 0x00, 0x91, 0xb7, 0x42, + 0x01, 0xd0, 0x2f, 0x1c, 0xc8, 0xd1, 0xa0, 0x69, + 0x01, 0x99, 0x88, 0x43, 0xa0, 0x61, 0x00, 0x99, + 0x00, 0x29, 0x01, 0xd0, 0x0e, 0xf0, 0x62, 0xf8, + 0x0e, 0xf0, 0x54, 0xf8, 0x02, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, + 0x00, 0x67, 0x03, 0x20, 0xff, 0xb5, 0x8a, 0xb0, + 0x00, 0x27, 0x0c, 0x1c, 0x15, 0x1c, 0x06, 0x1c, + 0x26, 0x48, 0x0e, 0xf0, 0x47, 0xf8, 0xb1, 0x69, + 0x08, 0x1c, 0x20, 0x40, 0xaa, 0x08, 0x04, 0xd3, + 0x01, 0x22, 0xa0, 0x42, 0x00, 0xd0, 0x00, 0x22, + 0x10, 0x1c, 0x00, 0x28, 0x07, 0xd0, 0x0d, 0x9b, + 0x68, 0x08, 0x19, 0x60, 0x32, 0xd3, 0xb0, 0x69, + 0xa0, 0x43, 0xb0, 0x61, 0x2e, 0xe0, 0x13, 0x98, + 0x00, 0x21, 0x00, 0x28, 0x26, 0xd0, 0xf0, 0x69, + 0x06, 0xab, 0x01, 0x30, 0xf0, 0x61, 0x02, 0x91, + 0x01, 0x91, 0x17, 0x49, 0x04, 0x96, 0x09, 0x68, + 0x05, 0x94, 0x07, 0x91, 0x1d, 0x70, 0x32, 0x6a, + 0x01, 0xa8, 0x00, 0x2a, 0x06, 0xd0, 0x12, 0x68, + 0x01, 0x92, 0x50, 0x60, 0x32, 0x6a, 0x02, 0x92, + 0x10, 0x60, 0x02, 0xe0, 0x30, 0x62, 0x01, 0x90, + 0x02, 0x90, 0x13, 0x9a, 0x03, 0x1c, 0x08, 0x1c, + 0x00, 0x92, 0x0c, 0x4a, 0x07, 0x21, 0xeb, 0xf7, + 0xc7, 0xf8, 0x09, 0x98, 0x0d, 0x9b, 0x08, 0x9f, + 0x18, 0x60, 0x03, 0xe0, 0x0d, 0x9b, 0x23, 0x27, + 0xff, 0x43, 0x19, 0x60, 0x0d, 0xf0, 0xfe, 0xff, + 0x38, 0x1c, 0x0e, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, + 0xed, 0x09, 0x00, 0x7e, 0x02, 0xe8, 0x66, 0x03, + 0x20, 0xf5, 0x78, 0x02, 0x20, 0x31, 0x21, 0xc9, + 0x43, 0xc1, 0x61, 0xc1, 0x68, 0xca, 0x69, 0x01, + 0x3a, 0xca, 0x61, 0x01, 0x68, 0x81, 0x42, 0x03, + 0xd1, 0xc0, 0x68, 0x00, 0x21, 0x01, 0x62, 0x70, + 0x47, 0x42, 0x68, 0x4a, 0x60, 0x06, 0xc8, 0x08, + 0x38, 0x11, 0x60, 0xc1, 0x68, 0x0a, 0x6a, 0x82, + 0x42, 0xf5, 0xd1, 0x40, 0x68, 0x08, 0x62, 0x70, + 0x47, 0x90, 0xb4, 0x03, 0x68, 0x00, 0x2b, 0x15, + 0xd0, 0x1c, 0x7a, 0x0f, 0x7a, 0x1a, 0x1c, 0xbc, + 0x42, 0x01, 0xdd, 0x01, 0x60, 0x07, 0xe0, 0x52, + 0x68, 0x00, 0xe0, 0x52, 0x68, 0x10, 0x7a, 0xb8, + 0x42, 0x01, 0xdc, 0x9a, 0x42, 0xf9, 0xd1, 0x10, + 0x68, 0x08, 0x60, 0x41, 0x60, 0x4a, 0x60, 0x11, + 0x60, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x60, 0x09, + 0x60, 0x49, 0x60, 0xf9, 0xe7, 0xf0, 0xb5, 0x06, + 0x1c, 0x13, 0x48, 0x00, 0x24, 0x00, 0x69, 0x0d, + 0x1c, 0x00, 0x28, 0x1c, 0xd1, 0xd9, 0xf7, 0xed, + 0xf8, 0x07, 0x1c, 0x02, 0xd1, 0xff, 0x24, 0x01, + 0x34, 0x15, 0xe0, 0x16, 0x20, 0x38, 0x60, 0x3d, + 0x61, 0xf8, 0x1d, 0x05, 0x30, 0xfe, 0x60, 0x0b, + 0xa3, 0x1a, 0x68, 0x30, 0x1c, 0x29, 0x1c, 0x5b, + 0x68, 0xe9, 0xf7, 0xf2, 0xf8, 0x09, 0x49, 0x00, + 0x28, 0x01, 0xd0, 0x01, 0x20, 0x08, 0x60, 0x0b, + 0x20, 0x39, 0x1c, 0xd9, 0xf7, 0x41, 0xf9, 0x20, + 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x18, 0xec, 0x03, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x03, + 0x20, 0x00, 0xb5, 0x02, 0x1c, 0x03, 0xa1, 0x08, + 0x68, 0x49, 0x68, 0xff, 0xf7, 0xc7, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x05, + 0x48, 0x40, 0x6f, 0xed, 0x09, 0x00, 0x7f, 0x02, + 0x00, 0xe0, 0x00, 0x68, 0x00, 0x28, 0x02, 0xd0, + 0x82, 0x6a, 0x8a, 0x42, 0xf9, 0xd1, 0x70, 0x47, + 0x00, 0x00, 0x18, 0xeb, 0x03, 0x20, 0x0a, 0x68, + 0x00, 0x2a, 0x02, 0xd0, 0x4b, 0x68, 0x53, 0x60, + 0x01, 0xe0, 0x4a, 0x68, 0x42, 0x60, 0x4a, 0x68, + 0x00, 0x2a, 0x02, 0xd0, 0x08, 0x68, 0x10, 0x60, + 0x70, 0x47, 0x09, 0x68, 0x01, 0x60, 0x70, 0x47, + 0xff, 0xb5, 0x83, 0xb0, 0x04, 0x1c, 0x00, 0x26, + 0x0f, 0x1c, 0xf1, 0x43, 0x2a, 0x48, 0x0d, 0xf0, + 0xdc, 0xfb, 0x29, 0x4a, 0x2a, 0xa1, 0x02, 0x92, + 0xd0, 0x68, 0xd1, 0x61, 0x02, 0x9a, 0x01, 0x30, + 0xd0, 0x60, 0x25, 0x68, 0x00, 0x2d, 0x41, 0xd0, + 0x28, 0x69, 0x69, 0x69, 0x3a, 0x69, 0x01, 0x92, + 0x7b, 0x69, 0x00, 0x93, 0xe9, 0xf7, 0xfb, 0xf8, + 0x00, 0x28, 0x06, 0xd0, 0x6f, 0x60, 0x00, 0x20, + 0x3d, 0x60, 0x78, 0x60, 0x27, 0x60, 0x02, 0x26, + 0x1d, 0xe0, 0x28, 0x69, 0x69, 0x69, 0x01, 0x9a, + 0x00, 0x9b, 0xe9, 0xf7, 0xf8, 0xf8, 0x00, 0x28, + 0x0b, 0xd0, 0x28, 0x68, 0x00, 0x28, 0x02, 0xd0, + 0x05, 0x1c, 0xf2, 0xd1, 0x0b, 0xe0, 0x2f, 0x60, + 0x7d, 0x60, 0x00, 0x20, 0x38, 0x60, 0x67, 0x60, + 0x05, 0xe0, 0x68, 0x68, 0x07, 0x60, 0x68, 0x68, + 0x78, 0x60, 0x6f, 0x60, 0x3d, 0x60, 0x00, 0x2e, + 0x09, 0xd0, 0x02, 0x2e, 0x02, 0xd1, 0x12, 0xa0, + 0xff, 0xf7, 0x8d, 0xff, 0x16, 0xa2, 0x05, 0x98, + 0x06, 0x99, 0xff, 0xf7, 0x56, 0xff, 0x02, 0x9a, + 0xd0, 0x68, 0x01, 0x38, 0xd0, 0x60, 0x05, 0x48, + 0x0d, 0xf0, 0xdf, 0xfb, 0x07, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x27, 0x60, 0x67, 0x60, + 0x01, 0x26, 0xeb, 0xe7, 0x00, 0x00, 0x1c, 0xe4, + 0x03, 0x20, 0x18, 0xec, 0x03, 0x20, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, 0xed, 0x09, + 0x00, 0x80, 0x02, 0x6d, 0x65, 0x72, 0x2e, 0x63, + 0x3a, 0x20, 0x32, 0x31, 0x30, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, 0x6d, + 0x65, 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x34, + 0x36, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x63, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x63, + 0x3a, 0x20, 0x32, 0x34, 0x38, 0x00, 0x00, 0xf3, + 0xb5, 0x0f, 0x1c, 0x00, 0x21, 0xc9, 0x43, 0x40, + 0x48, 0x0d, 0xf0, 0x61, 0xfb, 0x40, 0x48, 0x40, + 0xa2, 0xc5, 0x1d, 0xf9, 0x35, 0xe9, 0x68, 0xea, + 0x61, 0x4e, 0x1c, 0xee, 0x60, 0x44, 0x6f, 0x00, + 0x2c, 0x66, 0xd0, 0x20, 0x69, 0x61, 0x69, 0x00, + 0x9a, 0x3b, 0x1c, 0xe9, 0xf7, 0x8e, 0xf8, 0x00, + 0x28, 0x5f, 0xd0, 0x3c, 0x48, 0x00, 0x27, 0x01, + 0x68, 0x00, 0x29, 0x00, 0xd0, 0x07, 0x60, 0x3a, + 0x48, 0x21, 0x1c, 0x06, 0x1c, 0xff, 0xf7, 0x4d, + 0xff, 0x31, 0x48, 0x40, 0x6f, 0x00, 0x28, 0x06, + 0xd0, 0xc1, 0x1d, 0x09, 0x31, 0x08, 0x68, 0x49, + 0x68, 0x35, 0xa2, 0xff, 0xf7, 0xf4, 0xfe, 0xe8, + 0x68, 0x01, 0x38, 0xe8, 0x60, 0x29, 0x48, 0x0d, + 0xf0, 0x7e, 0xfb, 0x20, 0x6a, 0x00, 0x28, 0x04, + 0xd0, 0x01, 0x23, 0xd8, 0x42, 0x01, 0xd0, 0x01, + 0x38, 0x20, 0x62, 0x63, 0x6a, 0x00, 0x2b, 0x04, + 0xd0, 0xa0, 0x68, 0xe1, 0x68, 0x22, 0x6a, 0xd8, + 0xf7, 0x1d, 0xfc, 0x20, 0x6a, 0x00, 0x28, 0x0e, + 0xd0, 0xdc, 0xf7, 0x03, 0xfa, 0xa2, 0x69, 0xe3, + 0x69, 0x82, 0x18, 0x59, 0x41, 0x0b, 0x1c, 0x30, + 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0x2f, 0xff, 0x02, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x16, + 0x4e, 0x00, 0x21, 0xc9, 0x43, 0x30, 0x1c, 0x0d, + 0xf0, 0x0a, 0xfb, 0xe9, 0x68, 0x14, 0x48, 0x01, + 0x31, 0xe9, 0x60, 0xc1, 0x1d, 0x1f, 0xa2, 0xea, + 0x61, 0xed, 0x09, 0x00, 0x81, 0x02, 0x79, 0x31, + 0x4b, 0x68, 0xca, 0x68, 0x9b, 0x00, 0xd4, 0x50, + 0x84, 0x30, 0x02, 0x68, 0x01, 0x32, 0x02, 0x60, + 0x08, 0x68, 0x82, 0x42, 0x00, 0xd1, 0x4f, 0x60, + 0xe8, 0x68, 0x01, 0x38, 0xe8, 0x60, 0x30, 0x1c, + 0x0d, 0xf0, 0x3c, 0xfb, 0xda, 0xe7, 0x05, 0xe0, + 0x70, 0x1e, 0xe8, 0x60, 0x04, 0x48, 0x0d, 0xf0, + 0x35, 0xfb, 0xd3, 0xe7, 0x70, 0x1e, 0xe8, 0x60, + 0x01, 0x48, 0x0d, 0xf0, 0x2f, 0xfb, 0xcd, 0xe7, + 0x1c, 0xe4, 0x03, 0x20, 0x18, 0xeb, 0x03, 0x20, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, + 0x6d, 0x65, 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x32, + 0x36, 0x33, 0x00, 0x00, 0x00, 0x6d, 0x03, 0x20, + 0x8c, 0xeb, 0x03, 0x20, 0x73, 0x72, 0x63, 0x5c, + 0x6c, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, + 0x63, 0x3a, 0x20, 0x32, 0x38, 0x32, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, + 0x6d, 0x65, 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x33, + 0x30, 0x31, 0x00, 0x00, 0xff, 0xb5, 0x00, 0x27, + 0xf9, 0x43, 0x0b, 0x9c, 0x0a, 0x9d, 0x09, 0x9e, + 0x21, 0x48, 0x0d, 0xf0, 0xb3, 0xfa, 0x21, 0x4b, + 0x21, 0xa2, 0xd9, 0x1d, 0xf9, 0x31, 0xc8, 0x68, + 0x01, 0x30, 0xc8, 0x60, 0xd8, 0x1d, 0x79, 0x30, + 0xca, 0x61, 0x82, 0x68, 0x43, 0x68, 0x93, 0x42, + 0x27, 0xd0, 0xc7, 0x68, 0x92, 0x00, 0xbf, 0x58, + 0xc2, 0x1d, 0x01, 0x32, 0x13, 0x68, 0x01, 0x33, + 0x13, 0x60, 0x02, 0x68, 0x93, 0x42, 0x01, 0xd1, + 0x00, 0x22, 0x82, 0x60, 0x01, 0x9a, 0x7a, 0x61, + 0x00, 0x9a, 0x3a, 0x61, 0x03, 0x9b, 0xfb, 0x61, + 0x02, 0x9a, 0xba, 0x61, 0xbc, 0x60, 0x0c, 0x98, + 0x00, 0x22, 0xf8, 0x60, 0x3e, 0x62, 0x3a, 0x60, + 0x7a, 0x60, 0x0c, 0x48, 0x7d, 0x62, 0xc3, 0x6f, + 0x5a, 0x1c, 0xc2, 0x67, 0xed, 0x09, 0x00, 0x82, + 0x02, 0xbb, 0x62, 0x00, 0x2b, 0x03, 0xd1, 0xc3, + 0x6f, 0x5a, 0x1c, 0xc2, 0x67, 0xbb, 0x62, 0xc8, + 0x68, 0x01, 0x38, 0xc8, 0x60, 0x03, 0x48, 0x0d, + 0xf0, 0xc3, 0xfa, 0x38, 0x1c, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1c, 0xe4, 0x03, + 0x20, 0x18, 0xeb, 0x03, 0x20, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x72, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x32, 0x35, 0x00, + 0x00, 0xff, 0xb5, 0x86, 0xb0, 0x1f, 0x1c, 0x00, + 0x2a, 0x11, 0x9c, 0x10, 0x9d, 0x0f, 0x9e, 0x0e, + 0xd0, 0x06, 0xa9, 0x0c, 0xc9, 0x04, 0xa8, 0x0c, + 0xc0, 0xdc, 0xf7, 0x3c, 0xf9, 0x06, 0x9a, 0x02, + 0x90, 0x80, 0x18, 0x07, 0x9b, 0x03, 0x91, 0x59, + 0x41, 0x07, 0x91, 0x06, 0x90, 0x16, 0xe0, 0xdc, + 0xf7, 0x31, 0xf9, 0x04, 0x90, 0x05, 0x91, 0x06, + 0x9a, 0x07, 0x9b, 0xe8, 0xf7, 0x8f, 0xff, 0x00, + 0x28, 0x04, 0xd0, 0x13, 0xa1, 0x0c, 0xc9, 0x04, + 0xa8, 0x0c, 0xc0, 0x07, 0xe0, 0x06, 0x98, 0x04, + 0x9a, 0x07, 0x99, 0x05, 0x9b, 0x80, 0x1a, 0x99, + 0x41, 0x05, 0x91, 0x04, 0x90, 0x03, 0x94, 0x02, + 0x95, 0x01, 0x96, 0x00, 0x97, 0x06, 0x98, 0x07, + 0x99, 0x04, 0x9a, 0x05, 0x9b, 0xff, 0xf7, 0x70, + 0xff, 0x07, 0x1c, 0x05, 0xd0, 0x08, 0x48, 0x06, + 0x9a, 0x07, 0x9b, 0x39, 0x1c, 0xff, 0xf7, 0x3f, + 0xfe, 0x00, 0x20, 0x00, 0x2f, 0x00, 0xd0, 0xb8, + 0x6a, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8c, 0xeb, 0x03, 0x20, 0xf0, 0xb5, 0x82, + 0xb0, 0x00, 0x24, 0x07, 0x1c, 0x28, 0x4e, 0xe1, + 0x43, 0x30, 0x1c, 0x0d, 0xf0, 0x0d, 0xfa, 0x27, + 0x4a, 0x27, 0xa1, 0xd5, 0x1d, 0xf9, 0x35, 0xe8, + 0x68, 0x01, 0x30, 0xe8, 0x60, 0xe9, 0x61, 0xed, + 0x09, 0x00, 0x83, 0x02, 0x38, 0x1c, 0xff, 0xf7, + 0xfe, 0xfd, 0x07, 0x1c, 0x31, 0xd0, 0x39, 0x68, + 0x68, 0x46, 0x00, 0x29, 0x01, 0xd0, 0x10, 0x31, + 0x00, 0xe0, 0x23, 0xa1, 0x0c, 0xc9, 0x0c, 0xc0, + 0x24, 0x48, 0x39, 0x1c, 0xff, 0xf7, 0xfd, 0xfd, + 0x78, 0x68, 0x00, 0x28, 0x0a, 0xd1, 0x21, 0xa0, + 0xff, 0xf7, 0xdb, 0xfd, 0x38, 0x68, 0x00, 0x28, + 0x04, 0xd0, 0x23, 0xa2, 0x00, 0x98, 0x01, 0x99, + 0xff, 0xf7, 0xa1, 0xfd, 0x13, 0x49, 0xc8, 0x1d, + 0x79, 0x30, 0x43, 0x68, 0xc2, 0x68, 0x9b, 0x00, + 0xd7, 0x50, 0x84, 0x31, 0x0a, 0x68, 0x01, 0x32, + 0x0a, 0x60, 0x01, 0x68, 0x8a, 0x42, 0x01, 0xd1, + 0x00, 0x21, 0x41, 0x60, 0xe8, 0x68, 0x01, 0x38, + 0xe8, 0x60, 0x30, 0x1c, 0x0d, 0xf0, 0x1b, 0xfa, + 0x07, 0xe0, 0xe8, 0x68, 0x01, 0x38, 0xe8, 0x60, + 0x30, 0x1c, 0x0d, 0xf0, 0x14, 0xfa, 0xff, 0x24, + 0x05, 0x34, 0x20, 0x1c, 0x02, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0xe4, + 0x03, 0x20, 0x18, 0xeb, 0x03, 0x20, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, 0x6d, 0x65, + 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x38, 0x37, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8c, 0xeb, 0x03, 0x20, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, 0x6d, 0x65, + 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x39, 0x32, + 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, + 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x63, 0x3a, + 0x20, 0x33, 0x39, 0x35, 0x00, 0x00, 0x00, 0xb5, + 0xff, 0xf7, 0x7f, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0xf0, 0xb5, 0x00, 0x27, 0x06, 0x23, 0x01, 0x22, + 0x1c, 0x48, 0x1c, 0xa1, 0x0d, 0xf0, 0xfd, 0xf8, + 0xff, 0x20, 0x95, 0x30, 0x1c, 0xa1, 0x00, 0xf0, + 0xc0, 0xf8, 0xed, 0x09, 0x00, 0x84, 0x02, 0x1f, + 0x49, 0xcc, 0x1d, 0x79, 0x34, 0xe0, 0x60, 0x00, + 0x28, 0x01, 0xd1, 0x07, 0x27, 0x23, 0xe0, 0x00, + 0x26, 0x66, 0x60, 0x64, 0x25, 0x65, 0x20, 0xa6, + 0x60, 0x20, 0x60, 0x19, 0x48, 0x1a, 0xa1, 0x00, + 0xf0, 0xae, 0xf8, 0x1d, 0x49, 0x00, 0x28, 0x48, + 0x60, 0x01, 0xd1, 0x07, 0x27, 0x13, 0xe0, 0x1b, + 0x49, 0x0b, 0xe0, 0x63, 0x68, 0xe2, 0x68, 0x9b, + 0x00, 0xd0, 0x50, 0x0a, 0x68, 0x01, 0x32, 0x0a, + 0x60, 0x23, 0x68, 0x9a, 0x42, 0x00, 0xd1, 0x66, + 0x60, 0x2c, 0x30, 0x2a, 0x1c, 0x01, 0x3d, 0x00, + 0x2a, 0x01, 0xd0, 0x00, 0x2f, 0xed, 0xd0, 0x38, + 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1c, + 0xe4, 0x03, 0x20, 0x53, 0x5f, 0x54, 0x49, 0x4d, + 0x45, 0x52, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x63, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x63, + 0x3a, 0x20, 0x34, 0x33, 0x32, 0x00, 0x00, 0x18, + 0xeb, 0x03, 0x20, 0x30, 0x11, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, 0x6d, + 0x65, 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x34, 0x34, + 0x34, 0x00, 0x00, 0x00, 0x6d, 0x03, 0x20, 0x9c, + 0xeb, 0x03, 0x20, 0xf0, 0xb5, 0x24, 0x4e, 0x00, + 0x21, 0xc9, 0x43, 0x30, 0x1c, 0x0d, 0xf0, 0x2d, + 0xf9, 0x22, 0x4c, 0x22, 0xa1, 0xe7, 0x1d, 0xf9, + 0x37, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0xf9, + 0x61, 0x61, 0x6f, 0x00, 0x29, 0x07, 0xd0, 0xe5, + 0x1d, 0x6d, 0x35, 0x28, 0x1c, 0xff, 0xf7, 0x27, + 0xfd, 0x61, 0x6f, 0x00, 0x29, 0xf9, 0xd1, 0xf8, + 0x68, 0x01, 0x38, 0xf8, 0x60, 0x30, 0x1c, 0x0d, + 0xf0, 0x60, 0xf9, 0x30, 0x1c, 0x0d, 0xf0, 0xbf, + 0xf8, 0xe7, 0x1d, 0x79, 0x37, 0x39, 0x1d, 0x03, + 0xc9, 0x00, 0x25, 0x88, 0x42, 0x0c, 0xd0, 0xe0, + 0x1d, 0x81, 0x30, 0x01, 0x68, 0xed, 0x09, 0x00, + 0x85, 0x02, 0x01, 0x31, 0x01, 0x60, 0x3a, 0x68, + 0x91, 0x42, 0x00, 0xd1, 0xbd, 0x60, 0x3a, 0x1d, + 0x06, 0xca, 0x91, 0x42, 0xf4, 0xd1, 0x10, 0x4c, + 0x60, 0x68, 0x00, 0x28, 0x03, 0xd0, 0x0f, 0xa1, + 0x00, 0xf0, 0x36, 0xf8, 0x65, 0x60, 0xf8, 0x68, + 0x00, 0x28, 0x03, 0xd0, 0x10, 0xa1, 0x00, 0xf0, + 0x2f, 0xf8, 0xfd, 0x60, 0x28, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x1c, 0xe4, 0x03, 0x20, + 0x18, 0xeb, 0x03, 0x20, 0x73, 0x72, 0x63, 0x5c, + 0x6c, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, + 0x63, 0x3a, 0x20, 0x34, 0x36, 0x33, 0x00, 0x00, + 0x00, 0x6d, 0x03, 0x20, 0x73, 0x72, 0x63, 0x5c, + 0x6c, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, + 0x63, 0x3a, 0x20, 0x34, 0x37, 0x37, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x63, 0x74, 0x69, + 0x6d, 0x65, 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x34, + 0x38, 0x31, 0x00, 0x00, 0x00, 0xb5, 0x01, 0x21, + 0xfd, 0xf7, 0x48, 0xfd, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0xfd, 0xf7, 0x5d, 0xfd, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0x07, 0x1c, 0xc0, 0x69, + 0x00, 0x24, 0x00, 0x28, 0x03, 0xd0, 0xd8, 0xf7, + 0x61, 0xfd, 0xfc, 0x61, 0xbc, 0x61, 0x78, 0x6a, + 0x00, 0x28, 0x03, 0xd0, 0xd8, 0xf7, 0x5a, 0xfd, + 0x7c, 0x62, 0x3c, 0x62, 0xf8, 0x6a, 0x00, 0x28, + 0x03, 0xd0, 0xd8, 0xf7, 0x53, 0xfd, 0xfc, 0x62, + 0xbc, 0x62, 0x38, 0x6b, 0x00, 0x28, 0x02, 0xd0, + 0xd8, 0xf7, 0x4c, 0xfd, 0x3c, 0x63, 0x38, 0x1c, + 0xd8, 0xf7, 0xae, 0xfd, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xd3, + 0x13, 0x20, 0x70, 0x47, 0x2c, 0x20, 0x70, 0x47, + 0xb0, 0xb5, 0x00, 0x24, 0x00, 0x27, 0xd8, 0xf7, + 0x7e, 0xfd, 0x00, 0x28, 0x06, 0xd0, 0x44, 0x65, + 0xed, 0x09, 0x00, 0x86, 0x02, 0x04, 0x1c, 0x01, + 0x37, 0xd8, 0xf7, 0x77, 0xfd, 0x00, 0x28, 0xf8, + 0xd1, 0x00, 0x2c, 0x05, 0xd0, 0x65, 0x6d, 0x20, + 0x1c, 0xd8, 0xf7, 0x90, 0xfd, 0x2c, 0x1c, 0xf9, + 0xd1, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xb0, 0xb5, 0x0f, 0x1c, 0x01, 0x1c, 0x0e, + 0x48, 0xd8, 0xf7, 0xa0, 0xf8, 0x0c, 0x1c, 0x39, + 0x1c, 0x05, 0x1c, 0x0b, 0x48, 0xd8, 0xf7, 0x9a, + 0xf8, 0x0f, 0x1c, 0x21, 0x1c, 0x41, 0x43, 0x7d, + 0x43, 0x49, 0x19, 0x07, 0x48, 0xd8, 0xf7, 0x92, + 0xf8, 0x05, 0x48, 0x7c, 0x43, 0x48, 0x43, 0x01, + 0x19, 0x04, 0x48, 0xd8, 0xf7, 0x8b, 0xf8, 0xb0, + 0xbc, 0x08, 0xbc, 0x08, 0x1c, 0x18, 0x47, 0x00, + 0x00, 0x10, 0x27, 0x00, 0x00, 0x00, 0xe1, 0xf5, + 0x05, 0x90, 0xb5, 0x07, 0x1c, 0x00, 0xd1, 0x0b, + 0x4f, 0x0b, 0x4c, 0x0c, 0x49, 0xe0, 0x6a, 0xff, + 0xf7, 0xd3, 0xff, 0x41, 0x1c, 0x07, 0x48, 0xd8, + 0xf7, 0x75, 0xf8, 0xe1, 0x62, 0x08, 0x48, 0xd8, + 0xf7, 0x71, 0xf8, 0x78, 0x43, 0x01, 0x1c, 0x06, + 0x48, 0xd8, 0xf7, 0x6c, 0xf8, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xe1, 0xf5, + 0x05, 0xd8, 0xeb, 0x03, 0x20, 0x0d, 0x5e, 0xdf, + 0x01, 0x10, 0x27, 0x00, 0x00, 0x01, 0x49, 0x0c, + 0xc9, 0x0c, 0xc0, 0x70, 0x47, 0xc4, 0xeb, 0x03, + 0x20, 0x00, 0x20, 0x70, 0x47, 0x00, 0xb5, 0x08, + 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0x19, 0x40, 0x10, + 0x40, 0x07, 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0xe8, + 0xf7, 0xe7, 0xfc, 0x00, 0x28, 0x02, 0xd0, 0x05, + 0x20, 0x08, 0xbc, 0x18, 0x47, 0x0a, 0x20, 0xfb, + 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb5, 0x08, 0xa3, 0x1a, 0x68, 0x5b, + 0x68, 0x19, 0x40, 0xed, 0x09, 0x00, 0x87, 0x02, + 0x10, 0x40, 0x07, 0xa3, 0x1a, 0x68, 0x5b, 0x68, + 0xe8, 0xf7, 0xcd, 0xfc, 0x00, 0x28, 0x02, 0xd0, + 0x0a, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x05, 0x20, + 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf3, 0xb5, 0x84, 0xb0, 0x1a, 0xa0, + 0x84, 0xc8, 0x0d, 0x1c, 0x00, 0x26, 0x08, 0x38, + 0x04, 0x68, 0x03, 0x92, 0x43, 0x68, 0x18, 0xa0, + 0x02, 0x93, 0x43, 0x68, 0x01, 0x93, 0x02, 0x68, + 0x00, 0x92, 0x01, 0x22, 0x20, 0x1c, 0x39, 0x1c, + 0xe8, 0xf7, 0x35, 0xfd, 0x04, 0x1c, 0x0f, 0x1c, + 0x01, 0x9b, 0x29, 0x1c, 0x19, 0x40, 0x04, 0x98, + 0x00, 0x9a, 0x02, 0x9b, 0x10, 0x40, 0x03, 0x9a, + 0xe8, 0xf7, 0x9d, 0xfc, 0x00, 0x28, 0x03, 0xd0, + 0x01, 0x9b, 0x00, 0x9a, 0x1f, 0x43, 0x14, 0x43, + 0x01, 0x22, 0x29, 0x1c, 0x04, 0x98, 0xe8, 0xf7, + 0x9c, 0xfc, 0x0d, 0x1c, 0x01, 0x36, 0x40, 0x2e, + 0x04, 0x90, 0xde, 0xd3, 0x20, 0x1c, 0x39, 0x1c, + 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x1c, 0x1d, 0x1c, + 0x16, 0x1c, 0x0f, 0x1c, 0xff, 0xf7, 0x85, 0xff, + 0x30, 0x60, 0x20, 0x1c, 0x39, 0x1c, 0xff, 0xf7, + 0x9a, 0xff, 0x28, 0x60, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf8, 0xb4, 0x00, 0x27, 0x61, 0x25, + 0x30, 0x21, 0x0a, 0x03, 0x02, 0x40, 0x12, 0x0c, + 0x00, 0x92, 0x17, 0x4a, 0x92, 0x68, 0x01, 0x2a, + 0x04, 0xd0, 0x02, 0x2a, 0x05, 0xd1, 0x66, 0x22, + 0x19, 0x24, 0x04, 0xe0, 0x14, 0x24, 0x66, 0x22, + 0x01, 0xe0, 0x66, 0x22, 0x14, 0x24, 0x07, 0x23, + 0xdb, 0x03, 0x98, 0x43, 0x03, 0x1c, 0xed, 0x09, + 0x00, 0x88, 0x02, 0x0f, 0x4e, 0x01, 0xe0, 0x00, + 0x29, 0x07, 0xd0, 0x48, 0x00, 0x80, 0x19, 0x20, + 0x38, 0xc0, 0x8b, 0x98, 0x42, 0x01, 0xd9, 0x0d, + 0x1c, 0x04, 0xe0, 0x48, 0x00, 0x30, 0x5a, 0x98, + 0x42, 0x05, 0xd8, 0x0f, 0x1c, 0xe8, 0x1b, 0x40, + 0x08, 0x39, 0x18, 0x00, 0x28, 0xeb, 0xd1, 0x00, + 0x98, 0x00, 0x28, 0x00, 0xd0, 0x12, 0x19, 0xf8, + 0xbc, 0x88, 0x1a, 0x70, 0x47, 0x00, 0x00, 0x18, + 0xec, 0x03, 0x20, 0x9c, 0x62, 0x03, 0x20, 0xb0, + 0xb5, 0x82, 0xb0, 0x1d, 0x48, 0x07, 0x69, 0x00, + 0x2f, 0x32, 0xd0, 0x38, 0x69, 0x0c, 0xf0, 0x87, + 0xf8, 0x3a, 0x1c, 0x03, 0x1c, 0x1a, 0xa0, 0xb9, + 0x68, 0xec, 0xf7, 0x1b, 0xfe, 0x00, 0x24, 0xff, + 0x20, 0xb5, 0x30, 0x60, 0x43, 0xc5, 0x19, 0xa8, + 0x6c, 0x00, 0x28, 0x1b, 0xd0, 0x69, 0x6c, 0x00, + 0x29, 0x0e, 0xd0, 0x0c, 0xf0, 0x7e, 0xfa, 0x02, + 0x1c, 0x68, 0x6c, 0xeb, 0x1d, 0x81, 0x68, 0x01, + 0x92, 0x22, 0x1c, 0x00, 0x91, 0xb9, 0x68, 0x31, + 0x33, 0x18, 0xa0, 0xec, 0xf7, 0x02, 0xfe, 0x09, + 0xe0, 0x0c, 0xf0, 0x6f, 0xfa, 0x00, 0x90, 0x22, + 0x1c, 0xeb, 0x1d, 0x31, 0x33, 0xb9, 0x68, 0x22, + 0xa0, 0xec, 0xf7, 0xf7, 0xfd, 0x01, 0x34, 0x08, + 0x2c, 0xd9, 0xd3, 0x3f, 0x68, 0x00, 0x2f, 0xcc, + 0xd1, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x98, 0xeb, 0x03, 0x20, 0x5b, + 0x25, 0x75, 0x5d, 0x2c, 0x20, 0x25, 0x23, 0x70, + 0x2c, 0x20, 0x4c, 0x63, 0x4d, 0x69, 0x73, 0x63, + 0x53, 0x68, 0x6f, 0x77, 0x55, 0x73, 0x65, 0x64, + 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x2c, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, 0x0a, + 0x0d, 0x00, 0x00, 0x5b, 0x25, 0x75, 0x5d, 0x28, + 0x25, 0x75, 0x29, 0x2c, 0x20, 0x25, 0x23, 0x70, + 0x2c, 0xed, 0x09, 0x00, 0x89, 0x02, 0x20, 0x4c, + 0x63, 0x4d, 0x69, 0x73, 0x63, 0x53, 0x68, 0x6f, + 0x77, 0x55, 0x73, 0x65, 0x64, 0x4c, 0x69, 0x6e, + 0x6b, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x7b, 0x25, + 0x75, 0x7d, 0x2c, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x0a, 0x0d, 0x00, 0x00, + 0x5b, 0x25, 0x75, 0x5d, 0x28, 0x25, 0x75, 0x29, + 0x2c, 0x20, 0x25, 0x23, 0x70, 0x2c, 0x20, 0x4c, + 0x63, 0x4d, 0x69, 0x73, 0x63, 0x53, 0x68, 0x6f, + 0x77, 0x55, 0x73, 0x65, 0x64, 0x4c, 0x69, 0x6e, + 0x6b, 0x73, 0x2c, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x0a, 0x0d, 0x00, 0x00, + 0x80, 0xb5, 0x82, 0xb0, 0x87, 0x01, 0x38, 0x1c, + 0xfd, 0xf7, 0x48, 0xfb, 0x07, 0x49, 0x0b, 0x22, + 0x08, 0x60, 0x01, 0x92, 0x38, 0x21, 0x02, 0x1c, + 0x00, 0x91, 0x06, 0xa1, 0x04, 0x48, 0x3b, 0x1c, + 0xfe, 0xf7, 0x2c, 0xfa, 0x02, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x08, 0x6d, 0x03, 0x20, + 0x44, 0xe4, 0x03, 0x20, 0x42, 0x54, 0x5f, 0x44, + 0x41, 0x54, 0x41, 0x00, 0x00, 0xb5, 0x04, 0x48, + 0xfe, 0xf7, 0x78, 0xfa, 0x03, 0x48, 0x00, 0x68, + 0xfd, 0xf7, 0x54, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x44, 0xe4, 0x03, 0x20, 0x08, 0x6d, 0x03, 0x20, + 0x08, 0xb5, 0xea, 0xf7, 0x55, 0xfc, 0x00, 0x28, + 0x01, 0xd0, 0x00, 0x22, 0x01, 0xe0, 0x00, 0x22, + 0xd2, 0x43, 0x69, 0x46, 0x0a, 0x48, 0xfe, 0xf7, + 0xb5, 0xfa, 0x00, 0x28, 0x03, 0xd0, 0x00, 0x20, + 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, + 0x00, 0x22, 0x00, 0x98, 0x07, 0x23, 0x06, 0xc0, + 0x01, 0x3b, 0xfc, 0xd1, 0x00, 0x99, 0x14, 0x20, + 0x08, 0x60, 0x00, 0x98, 0xf0, 0xe7, 0x00, 0x00, + 0x44, 0xe4, 0x03, 0x20, 0xed, 0x09, 0x00, 0x8a, + 0x02, 0x80, 0xb5, 0x07, 0x1c, 0xc0, 0x6a, 0x00, + 0x28, 0x06, 0xd0, 0x39, 0x6b, 0x00, 0x29, 0x03, + 0xd0, 0xd7, 0xf7, 0x7b, 0xff, 0x00, 0x20, 0xf8, + 0x62, 0x00, 0x21, 0x38, 0x68, 0xc9, 0x43, 0x88, + 0x42, 0x03, 0xd0, 0x39, 0x60, 0x38, 0x1c, 0xfe, + 0xf7, 0xe7, 0xfa, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x23, 0x4d, 0x00, 0x27, 0x6f, + 0x67, 0xec, 0x1d, 0x79, 0x34, 0xaf, 0x67, 0xef, + 0x67, 0x27, 0x61, 0x67, 0x61, 0x01, 0x26, 0xa7, + 0x61, 0xe8, 0x1d, 0x99, 0x30, 0xe6, 0x61, 0x1d, + 0x49, 0x00, 0xf0, 0x12, 0xfb, 0xe6, 0x63, 0xa7, + 0x62, 0xec, 0x1d, 0xb9, 0x34, 0xa7, 0x60, 0x27, + 0x60, 0x67, 0x60, 0xe7, 0x60, 0x01, 0x20, 0xc0, + 0x02, 0x27, 0x61, 0x67, 0x61, 0xe0, 0x61, 0x22, + 0x21, 0x21, 0x62, 0xa7, 0x61, 0x60, 0x62, 0xa1, + 0x62, 0xe6, 0x63, 0xe9, 0x1d, 0x13, 0x20, 0xf9, + 0x31, 0x27, 0x63, 0x08, 0x60, 0x10, 0x48, 0x48, + 0x60, 0xcf, 0x60, 0x0f, 0x61, 0x4f, 0x61, 0x0f, + 0xa0, 0xc8, 0x61, 0x8e, 0x60, 0x0d, 0xf0, 0x5e, + 0xf9, 0xff, 0x27, 0x03, 0x37, 0xb8, 0x42, 0x01, + 0xd3, 0x07, 0x20, 0x00, 0xe0, 0x05, 0x20, 0x60, + 0x63, 0x0d, 0xf0, 0x54, 0xf9, 0xb8, 0x42, 0x01, + 0xd3, 0x07, 0x20, 0x00, 0xe0, 0x05, 0x20, 0xa0, + 0x63, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x18, 0xeb, 0x03, 0x20, 0x33, 0x8b, 0x9e, + 0x00, 0x80, 0x84, 0x1e, 0x00, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x69, 0x74, + 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x31, 0x37, 0x00, + 0x00, 0xf0, 0xb5, 0x82, 0xb0, 0x01, 0x26, 0x22, + 0x4c, 0xdb, 0xf7, 0xe2, 0xfc, 0x43, 0x00, 0x18, + 0x18, 0x80, 0x00, 0x00, 0x19, 0x1f, 0x4d, 0x01, + 0x90, 0xe8, 0x1d, 0x27, 0x1c, 0x6d, 0x30, 0xed, + 0x09, 0x00, 0x8b, 0x02, 0x00, 0x90, 0x0c, 0xe0, + 0x00, 0x2e, 0x05, 0xd0, 0x00, 0x26, 0x39, 0x1b, + 0x0c, 0x20, 0xe8, 0xf7, 0x9e, 0xfb, 0x01, 0xc5, + 0x38, 0x68, 0x24, 0x28, 0x00, 0xd1, 0x01, 0x26, + 0x0c, 0x37, 0x01, 0x98, 0x87, 0x42, 0x04, 0xd2, + 0x00, 0x98, 0x85, 0x42, 0xec, 0xd3, 0x00, 0x2e, + 0xea, 0xd0, 0x00, 0x98, 0x85, 0x42, 0x0b, 0xd2, + 0x01, 0x98, 0x01, 0x1b, 0x0c, 0x20, 0xe8, 0xf7, + 0x88, 0xfb, 0x0e, 0xa3, 0x1d, 0x22, 0x01, 0x1c, + 0x18, 0x1c, 0xec, 0xf7, 0xaa, 0xfc, 0x0d, 0xe0, + 0x01, 0x98, 0x87, 0x42, 0x0a, 0xd2, 0x01, 0x98, + 0x01, 0x1b, 0x0c, 0x20, 0xe8, 0xf7, 0x79, 0xfb, + 0x12, 0xa3, 0x1d, 0x22, 0x01, 0x1c, 0x18, 0x1c, + 0xec, 0xf7, 0x9b, 0xfc, 0x02, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x7c, 0x73, + 0x03, 0x20, 0x18, 0xeb, 0x03, 0x20, 0x4c, 0x63, + 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x73, 0x2c, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x44, 0x65, 0x73, 0x63, 0x20, 0x74, 0x6f, + 0x6f, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x20, + 0x28, 0x25, 0x75, 0x20, 0x25, 0x75, 0x29, 0x00, + 0x00, 0x00, 0x4c, 0x63, 0x49, 0x6e, 0x69, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x20, 0x74, 0x6f, 0x6f, 0x20, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x28, 0x25, 0x75, + 0x20, 0x25, 0x75, 0x29, 0x00, 0x00, 0xb0, 0xb5, + 0x87, 0xb0, 0x00, 0x27, 0xff, 0xf7, 0x2b, 0xff, + 0xff, 0xf7, 0x81, 0xff, 0x64, 0x20, 0xff, 0xf7, + 0xc0, 0xfe, 0x00, 0x20, 0xd9, 0xf7, 0x83, 0xfc, + 0x00, 0x28, 0x4a, 0xd1, 0x01, 0x23, 0x9b, 0x03, + 0x26, 0x4d, 0x09, 0x22, 0xe8, 0x1d, 0xf9, 0x30, + 0x03, 0x62, 0xed, 0x09, 0x00, 0x8c, 0x02, 0x06, + 0x92, 0x00, 0x20, 0x32, 0x22, 0x0a, 0x21, 0x05, + 0x91, 0x03, 0x21, 0x89, 0x02, 0x03, 0x92, 0x04, + 0x90, 0x20, 0x48, 0x00, 0x22, 0x00, 0x92, 0x02, + 0x91, 0x01, 0x93, 0x04, 0x1c, 0x00, 0x23, 0x1e, + 0xa1, 0x1d, 0x4a, 0xe9, 0xf7, 0x52, 0xff, 0x00, + 0x28, 0x2d, 0xd1, 0xff, 0xf7, 0xe3, 0xfb, 0x20, + 0x1c, 0xea, 0xf7, 0x7f, 0xf9, 0x00, 0x28, 0x26, + 0xd1, 0xe8, 0x1d, 0xa5, 0x30, 0x04, 0x1c, 0x06, + 0x22, 0x18, 0xa1, 0xfd, 0xf7, 0x68, 0xfa, 0x00, + 0x28, 0x0d, 0xd0, 0xe8, 0x1d, 0x79, 0x30, 0xc0, + 0x6a, 0x01, 0x02, 0x09, 0x0a, 0xe8, 0x1d, 0xad, + 0x30, 0x00, 0xf0, 0x0f, 0xfa, 0x01, 0x27, 0x21, + 0x1c, 0x12, 0xa0, 0xec, 0xf7, 0x1c, 0xfc, 0xdb, + 0xf7, 0x3e, 0xfc, 0xe9, 0x1d, 0xb9, 0x31, 0xc8, + 0x62, 0xd9, 0xf7, 0xc9, 0xfc, 0x00, 0x28, 0x06, + 0xd1, 0x00, 0x21, 0x38, 0x1c, 0xdb, 0xf7, 0xfe, + 0xf8, 0xdb, 0xf7, 0x27, 0xf9, 0x00, 0x20, 0x07, + 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x18, + 0xeb, 0x03, 0x20, 0xa4, 0xe5, 0x03, 0x20, 0x7d, + 0x3c, 0x00, 0x20, 0x54, 0x5f, 0x4c, 0x43, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0x4d, 0x79, 0x20, 0x42, + 0x54, 0x41, 0x64, 0x64, 0x72, 0x3a, 0x20, 0x25, + 0x3a, 0x2d, 0x36, 0x42, 0x20, 0x28, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x29, 0x0a, 0x00, 0x00, 0x00, + 0x20, 0x70, 0x47, 0x00, 0xb5, 0xe2, 0xf7, 0x4d, + 0xfc, 0xff, 0xf7, 0xef, 0xfb, 0xe1, 0xf7, 0xa7, + 0xfa, 0xdc, 0xf7, 0xdf, 0xfb, 0xdc, 0xf7, 0x35, + 0xfb, 0xff, 0xf7, 0xa7, 0xfe, 0xff, 0xf7, 0x86, + 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf0, + 0xb5, 0x8a, 0xb0, 0x33, 0x49, 0x06, 0xa8, 0xf0, + 0xc9, 0xf0, 0xc0, 0x00, 0x27, 0xed, 0x09, 0x00, + 0x8d, 0x02, 0x05, 0x23, 0x31, 0x4c, 0x1b, 0x02, + 0xe0, 0x18, 0x15, 0x23, 0x07, 0x63, 0x47, 0x63, + 0x9b, 0x01, 0xe5, 0x18, 0x87, 0x63, 0x2f, 0x60, + 0x6f, 0x60, 0xaf, 0x60, 0x2f, 0x61, 0x6f, 0x62, + 0xaf, 0x62, 0x10, 0x20, 0x02, 0xa9, 0x00, 0xf0, + 0x13, 0xfa, 0x68, 0x46, 0xff, 0xf7, 0xc8, 0xfc, + 0x27, 0x4b, 0x00, 0x9a, 0xe0, 0x18, 0x01, 0x9b, + 0x02, 0xa9, 0x01, 0xf0, 0x05, 0xf8, 0x2f, 0x63, + 0x0b, 0x23, 0xdb, 0x01, 0x6f, 0x63, 0x23, 0x48, + 0xaf, 0x63, 0xe6, 0x18, 0x70, 0x61, 0x22, 0x48, + 0x22, 0x4b, 0xb0, 0x61, 0xe0, 0x18, 0x22, 0xa1, + 0x0c, 0xc9, 0x0c, 0xc0, 0xef, 0x63, 0x10, 0x25, + 0x21, 0x4b, 0x2a, 0x1c, 0xe0, 0x18, 0x35, 0x60, + 0x06, 0xa9, 0xd7, 0xf7, 0xf3, 0xfd, 0x75, 0x62, + 0x01, 0x25, 0x14, 0x20, 0xf0, 0x62, 0x37, 0x63, + 0xb5, 0x62, 0xdb, 0xf7, 0xb7, 0xfb, 0x70, 0x63, + 0x02, 0x20, 0x5b, 0x23, 0x1b, 0x01, 0xb0, 0x63, + 0xe0, 0x18, 0x05, 0x73, 0x1f, 0x20, 0x2d, 0x23, + 0x5b, 0x01, 0xe1, 0x18, 0x17, 0x23, 0x9b, 0x01, + 0xc8, 0x83, 0xe0, 0x18, 0x04, 0x33, 0xe1, 0x18, + 0x05, 0x80, 0x00, 0x25, 0x00, 0x26, 0x60, 0xc1, + 0x41, 0x68, 0x10, 0x4b, 0x19, 0x43, 0x41, 0x60, + 0x5d, 0x23, 0x1b, 0x01, 0xc7, 0x60, 0xe0, 0x18, + 0x11, 0x22, 0x0d, 0xa1, 0xd7, 0xf7, 0xca, 0xfd, + 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x60, 0x65, 0x03, 0x20, 0xb8, 0xa8, 0x03, 0x20, + 0x54, 0x05, 0x00, 0x00, 0x80, 0x84, 0x1e, 0x00, + 0x00, 0x0e, 0x27, 0x07, 0x9c, 0x05, 0x00, 0x00, + 0x00, 0xc0, 0xae, 0x3b, 0x28, 0x00, 0x00, 0x00, + 0x84, 0x05, 0x00, 0x00, 0x2f, 0xbe, 0x05, 0x00, + 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, + 0x68, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0xed, 0x09, 0x00, 0x8e, 0x02, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xb5, 0x82, 0xb0, 0x01, 0x26, 0x16, + 0x4c, 0x00, 0xf0, 0xb6, 0xfc, 0x43, 0x00, 0x18, + 0x18, 0x80, 0x00, 0x00, 0x19, 0x0c, 0x38, 0x01, + 0x90, 0x12, 0x48, 0x27, 0x1c, 0xc5, 0x1d, 0xff, + 0x35, 0x3a, 0x35, 0xff, 0x30, 0x8d, 0x30, 0x00, + 0x90, 0x0c, 0xe0, 0x00, 0x2e, 0x05, 0xd0, 0x00, + 0x26, 0x39, 0x1b, 0x0c, 0x20, 0xe8, 0xf7, 0x0c, + 0xfa, 0x01, 0xc5, 0x38, 0x68, 0xa5, 0x28, 0x00, + 0xd1, 0x01, 0x26, 0x0c, 0x37, 0x01, 0x98, 0x87, + 0x42, 0x04, 0xd8, 0x00, 0x98, 0x85, 0x42, 0xec, + 0xd9, 0x00, 0x2e, 0xea, 0xd0, 0x00, 0x98, 0x02, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x28, 0x7e, 0x03, 0x20, 0xb8, 0xa8, 0x03, + 0x20, 0xf0, 0xb5, 0x82, 0xb0, 0x01, 0x26, 0x14, + 0x4d, 0x00, 0xf0, 0x85, 0xfc, 0x43, 0x00, 0x18, + 0x18, 0x80, 0x00, 0x40, 0x19, 0x11, 0x4c, 0x01, + 0x90, 0xe0, 0x1d, 0xff, 0x30, 0x2f, 0x1c, 0x36, + 0x30, 0x00, 0x90, 0x0c, 0xe0, 0x00, 0x2e, 0x05, + 0xd0, 0x00, 0x26, 0x79, 0x1b, 0x0c, 0x20, 0xe8, + 0xf7, 0xdb, 0xf9, 0x01, 0xc4, 0x38, 0x68, 0xa5, + 0x28, 0x00, 0xd1, 0x01, 0x26, 0x0c, 0x37, 0x01, + 0x98, 0x87, 0x42, 0x04, 0xd2, 0x00, 0x98, 0x84, + 0x42, 0xec, 0xd9, 0x00, 0x2e, 0xea, 0xd0, 0x00, + 0x98, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x84, 0x94, 0x03, 0x20, 0xb8, 0xa8, 0x03, + 0x20, 0xb0, 0xb5, 0x87, 0xb0, 0xff, 0xf7, 0x82, + 0xfe, 0x07, 0x1c, 0x04, 0xd0, 0x38, 0x1c, 0x07, + 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, + 0xf7, 0x07, 0xff, 0xff, 0xf7, 0x8d, 0xff, 0xff, + 0xf7, 0xbf, 0xff, 0x13, 0x20, 0x80, 0x02, 0x1b, + 0x23, 0x9b, 0x01, 0x18, 0x4c, 0x09, 0x22, 0xe1, + 0x18, 0xc8, 0x60, 0xed, 0x09, 0x00, 0x8f, 0x02, + 0x03, 0x1c, 0x06, 0x92, 0x3c, 0x22, 0x00, 0x20, + 0x0a, 0x21, 0x05, 0x91, 0x03, 0x21, 0x89, 0x02, + 0x03, 0x92, 0x00, 0x22, 0x13, 0x4d, 0x04, 0x90, + 0x28, 0x1c, 0x00, 0x92, 0x02, 0x91, 0x01, 0x93, + 0x00, 0x23, 0x10, 0xa1, 0x0e, 0x4a, 0xe9, 0xf7, + 0xd4, 0xfd, 0x00, 0x28, 0xd6, 0xd1, 0x28, 0x1c, + 0xea, 0xf7, 0x03, 0xf8, 0x00, 0x28, 0xd1, 0xd1, + 0x0d, 0x49, 0x00, 0x22, 0x01, 0x92, 0x00, 0x91, + 0x0c, 0xa1, 0x08, 0x68, 0x00, 0x23, 0x01, 0x22, + 0x49, 0x68, 0x00, 0xf0, 0x9d, 0xfa, 0x15, 0x23, + 0x9b, 0x01, 0xe1, 0x18, 0xc8, 0x60, 0x38, 0x1c, + 0xc0, 0xe7, 0xb8, 0xa8, 0x03, 0x20, 0x8b, 0x8f, + 0x02, 0x20, 0x0c, 0x17, 0x04, 0x20, 0x54, 0x5f, + 0x4c, 0x4d, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xb3, + 0x02, 0x20, 0x80, 0x84, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0xb5, 0x00, 0x27, 0xff, 0xf7, + 0xa6, 0xfe, 0x0b, 0x4c, 0x20, 0x1c, 0xe9, 0xf7, + 0xfc, 0xfe, 0x20, 0x1c, 0xe9, 0xf7, 0x85, 0xfe, + 0x02, 0xf0, 0x7d, 0xfa, 0x02, 0xf0, 0xa1, 0xfe, + 0x07, 0x4c, 0xe0, 0x68, 0x00, 0x28, 0x03, 0xd0, + 0xfd, 0xf7, 0x91, 0xf8, 0x00, 0x20, 0xe0, 0x60, + 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x0c, 0x17, 0x04, 0x20, 0x78, 0xaf, + 0x03, 0x20, 0x80, 0xb5, 0x82, 0xb0, 0x0c, 0x4f, + 0x00, 0x20, 0xf8, 0x60, 0x02, 0xf0, 0x63, 0xfa, + 0x02, 0xf0, 0x87, 0xfe, 0xff, 0xf7, 0x93, 0xfe, + 0x09, 0x49, 0x00, 0x22, 0x01, 0x92, 0x00, 0x91, + 0x08, 0xa1, 0x08, 0x68, 0x00, 0x23, 0x01, 0x22, + 0x49, 0x68, 0x00, 0xf0, 0x51, 0xfa, 0xf8, 0x60, + 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, 0xfd, 0xb3, + 0x02, 0x20, 0x80, 0x84, 0x1e, 0x00, 0xed, 0x09, + 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0xb5, 0x85, 0xb0, 0x18, 0xa2, 0x13, 0x68, 0x00, + 0x93, 0x56, 0x68, 0x04, 0x22, 0xe8, 0xf7, 0xdd, + 0xf8, 0x00, 0x25, 0x04, 0x1c, 0x0f, 0x1c, 0x15, + 0xa1, 0x4b, 0x68, 0x16, 0xa0, 0x04, 0x93, 0x0a, + 0x68, 0x03, 0x92, 0x43, 0x68, 0x02, 0x93, 0x02, + 0x68, 0x01, 0x92, 0x01, 0x22, 0x20, 0x1c, 0x39, + 0x1c, 0xe8, 0xf7, 0xcb, 0xf8, 0x02, 0x9b, 0x0f, + 0x1c, 0x19, 0x40, 0x01, 0x9a, 0x04, 0x1c, 0x10, + 0x40, 0x03, 0x9a, 0x04, 0x9b, 0xe8, 0xf7, 0x35, + 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x00, 0x9a, 0x77, + 0x40, 0x54, 0x40, 0x01, 0x35, 0x1e, 0x2d, 0xe8, + 0xd3, 0x20, 0x1c, 0x39, 0x1c, 0x05, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa9, + 0x3d, 0x71, 0x85, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, + 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x08, 0x0e, 0x05, + 0xd3, 0x08, 0x02, 0x00, 0x0a, 0x13, 0x23, 0x1b, + 0x06, 0x18, 0x43, 0x04, 0xe0, 0x08, 0x02, 0x00, + 0x0a, 0x0b, 0x23, 0x9b, 0x06, 0x18, 0x43, 0x00, + 0x21, 0x03, 0x91, 0x02, 0x90, 0x14, 0xa3, 0x1a, + 0x68, 0x5b, 0x68, 0x59, 0x40, 0x50, 0x40, 0x02, + 0x90, 0x03, 0x91, 0xff, 0xf7, 0xa4, 0xff, 0x04, + 0x90, 0x05, 0x91, 0x03, 0x99, 0x02, 0x98, 0x22, + 0x22, 0xe8, 0xf7, 0x83, 0xf8, 0x6a, 0x46, 0x03, + 0xc2, 0x05, 0x99, 0x01, 0x9b, 0x04, 0x98, 0x19, + 0x43, 0x00, 0x9a, 0x05, 0x91, 0x10, 0x43, 0x04, + 0x90, 0x09, 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0x59, + 0x40, 0x50, 0x40, 0x04, 0x90, 0x04, 0xa8, 0x05, + 0x91, 0x0c, 0xc8, 0x0c, 0xc7, 0x06, 0xb0, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x65, + 0x23, 0xed, 0x09, 0x00, 0x91, 0x02, 0xe1, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x54, 0xcc, 0xbb, + 0x96, 0x8d, 0x84, 0x83, 0xb0, 0xb5, 0x0f, 0x1c, + 0x01, 0x1c, 0x0e, 0x48, 0xd7, 0xf7, 0x36, 0xfb, + 0x0c, 0x1c, 0x39, 0x1c, 0x05, 0x1c, 0x0b, 0x48, + 0xd7, 0xf7, 0x30, 0xfb, 0x0f, 0x1c, 0x21, 0x1c, + 0x41, 0x43, 0x7d, 0x43, 0x49, 0x19, 0x07, 0x48, + 0xd7, 0xf7, 0x28, 0xfb, 0x05, 0x48, 0x7c, 0x43, + 0x48, 0x43, 0x01, 0x19, 0x04, 0x48, 0xd7, 0xf7, + 0x21, 0xfb, 0xb0, 0xbc, 0x08, 0xbc, 0x08, 0x1c, + 0x18, 0x47, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, + 0x00, 0xe1, 0xf5, 0x05, 0xf0, 0xb5, 0x00, 0x25, + 0x0c, 0x1c, 0x07, 0x1c, 0x00, 0x28, 0x15, 0xd9, + 0x0c, 0x4e, 0x70, 0x6b, 0x0c, 0x49, 0xff, 0xf7, + 0xd1, 0xff, 0x41, 0x1c, 0x0b, 0x48, 0xd7, 0xf7, + 0x09, 0xfb, 0x71, 0x63, 0x0a, 0x48, 0xd7, 0xf7, + 0x05, 0xfb, 0x01, 0x02, 0x09, 0x1a, 0x08, 0x48, + 0xd7, 0xf7, 0x00, 0xfb, 0x60, 0x55, 0x01, 0x35, + 0xbd, 0x42, 0xea, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x38, 0xae, 0x03, 0x20, + 0x0d, 0x5e, 0xdf, 0x01, 0x00, 0xe1, 0xf5, 0x05, + 0x10, 0x27, 0x00, 0x00, 0x80, 0x02, 0x08, 0x43, + 0x70, 0x47, 0x80, 0xb4, 0x08, 0x4f, 0x5b, 0x23, + 0x1b, 0x01, 0xfb, 0x18, 0x1b, 0x7b, 0x03, 0x60, + 0x2d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0xc0, 0x8b, + 0x17, 0x23, 0x9b, 0x01, 0x08, 0x60, 0xf8, 0x18, + 0x00, 0x88, 0x10, 0x60, 0x80, 0xbc, 0x70, 0x47, + 0xb8, 0xa8, 0x03, 0x20, 0x01, 0x49, 0x0c, 0xc9, + 0x0c, 0xc0, 0x70, 0x47, 0x7c, 0xae, 0x03, 0x20, + 0x00, 0xb5, 0x02, 0x49, 0xfc, 0xf7, 0xb4, 0xff, + 0x08, 0xbc, 0x18, 0x47, 0x88, 0xae, 0x03, 0x20, + 0x00, 0xb5, 0x03, 0x4a, 0x01, 0x1c, 0x10, 0x1c, + 0xfc, 0xf7, 0xaa, 0xff, 0xed, 0x09, 0x00, 0x92, + 0x02, 0x08, 0xbc, 0x18, 0x47, 0x88, 0xae, 0x03, + 0x20, 0x00, 0x28, 0x06, 0xd0, 0x09, 0x23, 0xdb, + 0x01, 0xc1, 0x18, 0x89, 0x6b, 0x02, 0x4b, 0x99, + 0x42, 0x00, 0xd0, 0x00, 0x20, 0x70, 0x47, 0x00, + 0x00, 0x19, 0x64, 0x03, 0x11, 0xb0, 0xb5, 0x0c, + 0x1c, 0x05, 0x1c, 0x17, 0x1c, 0xd7, 0xf7, 0x2f, + 0xff, 0x00, 0x28, 0x09, 0xd0, 0x68, 0x21, 0x01, + 0x60, 0x29, 0x6b, 0x0c, 0x30, 0x92, 0xc0, 0x18, + 0x38, 0x01, 0x1c, 0x07, 0x20, 0xd7, 0xf7, 0x92, + 0xff, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x02, + 0x4b, 0x40, 0x18, 0x18, 0x40, 0x70, 0x47, 0x00, + 0x00, 0xfc, 0xff, 0xff, 0x0f, 0x80, 0x08, 0x40, + 0x04, 0x40, 0x0c, 0x70, 0x47, 0x90, 0xb5, 0x03, + 0x9c, 0x17, 0x1c, 0x22, 0x1c, 0x18, 0x1c, 0x00, + 0x29, 0x02, 0xd0, 0x01, 0x23, 0xdb, 0x06, 0x9a, + 0x43, 0x51, 0x08, 0xd7, 0xf7, 0x85, 0xfa, 0x78, + 0x1a, 0x40, 0x00, 0x00, 0x19, 0x90, 0xbc, 0x00, + 0x01, 0x00, 0x09, 0x08, 0xbc, 0x40, 0x08, 0x18, + 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x2e, 0x48, 0x07, + 0x6b, 0x00, 0x2f, 0x54, 0xd0, 0x38, 0x6b, 0x00, + 0x28, 0x2c, 0xd0, 0xf8, 0x6a, 0x00, 0x28, 0x17, + 0xd0, 0x78, 0x69, 0x0c, 0xf0, 0x01, 0xf8, 0x02, + 0x1c, 0xf8, 0x6a, 0x3b, 0x6b, 0x41, 0x69, 0x18, + 0x68, 0x03, 0x92, 0x02, 0x91, 0x01, 0x90, 0x58, + 0x68, 0x82, 0x68, 0xf8, 0x1d, 0xff, 0x30, 0x3a, + 0x30, 0x00, 0x92, 0x43, 0x68, 0xb9, 0x68, 0x21, + 0xa0, 0x3a, 0x1c, 0xec, 0xf7, 0xeb, 0xf8, 0x33, + 0xe0, 0x78, 0x69, 0x0b, 0xf0, 0xe9, 0xff, 0x02, + 0x1c, 0x38, 0x6b, 0x01, 0x68, 0xf8, 0x1d, 0xff, + 0x30, 0x3a, 0x30, 0x01, 0x92, 0x00, 0x91, 0x43, + 0x68, 0xb9, 0x68, 0x2c, 0xa0, 0x3a, 0x1c, 0xec, + 0xf7, 0xd9, 0xf8, 0x21, 0xe0, 0xf8, 0x6a, 0xed, + 0x09, 0x00, 0x93, 0x02, 0x00, 0x28, 0x11, 0xd0, + 0x78, 0x69, 0x0b, 0xf0, 0xd4, 0xff, 0x02, 0x1c, + 0xf8, 0x6a, 0x41, 0x69, 0xf8, 0x1d, 0xff, 0x30, + 0x3a, 0x30, 0x01, 0x92, 0x00, 0x91, 0x43, 0x68, + 0xb9, 0x68, 0x31, 0xa0, 0x3a, 0x1c, 0xec, 0xf7, + 0xc4, 0xf8, 0x0c, 0xe0, 0x78, 0x69, 0x0b, 0xf0, + 0xc2, 0xff, 0x00, 0x90, 0xf8, 0x1d, 0xff, 0x30, + 0x3a, 0x30, 0x43, 0x68, 0xb9, 0x68, 0x3a, 0xa0, + 0x3a, 0x1c, 0xec, 0xf7, 0xb6, 0xf8, 0x3f, 0x68, + 0x00, 0x2f, 0xaa, 0xd1, 0x04, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xb8, 0xad, + 0x03, 0x20, 0x7b, 0x25, 0x75, 0x7d, 0x2c, 0x20, + 0x25, 0x23, 0x70, 0x2c, 0x20, 0x4c, 0x6d, 0x4d, + 0x69, 0x73, 0x63, 0x53, 0x68, 0x6f, 0x77, 0x4c, + 0x69, 0x6e, 0x6b, 0x73, 0x2c, 0x20, 0x70, 0x65, + 0x6e, 0x64, 0x20, 0x25, 0x75, 0x2c, 0x20, 0x63, + 0x6f, 0x6e, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x5b, 0x25, 0x75, 0x5d, 0x28, 0x25, 0x75, + 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x3c, 0x25, + 0x75, 0x3e, 0x2c, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x0a, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x7b, 0x25, 0x75, 0x7d, 0x2c, 0x20, + 0x25, 0x23, 0x70, 0x2c, 0x20, 0x4c, 0x6d, 0x4d, + 0x69, 0x73, 0x63, 0x53, 0x68, 0x6f, 0x77, 0x4c, + 0x69, 0x6e, 0x6b, 0x73, 0x2c, 0x20, 0x70, 0x65, + 0x6e, 0x64, 0x20, 0x25, 0x75, 0x2c, 0x20, 0x63, + 0x6f, 0x6e, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x28, 0x25, 0x75, 0x29, 0x2c, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x20, 0x25, 0x73, 0x0a, + 0x0d, 0x00, 0x7b, 0x25, 0x75, 0x7d, 0x2c, 0x20, + 0x25, 0x23, 0x70, 0x2c, 0x20, 0x4c, 0x6d, 0x4d, + 0x69, 0x73, 0x63, 0x53, 0x68, 0x6f, 0x77, 0x4c, + 0x69, 0x6e, 0xed, 0x09, 0x00, 0x94, 0x02, 0x6b, + 0x73, 0x2c, 0x20, 0x70, 0x65, 0x6e, 0x64, 0x20, + 0x25, 0x75, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x3c, 0x25, + 0x75, 0x3e, 0x2c, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x0a, 0x0d, 0x00, 0x7b, + 0x25, 0x75, 0x7d, 0x2c, 0x20, 0x25, 0x23, 0x70, + 0x2c, 0x20, 0x4c, 0x6d, 0x4d, 0x69, 0x73, 0x63, + 0x53, 0x68, 0x6f, 0x77, 0x4c, 0x69, 0x6e, 0x6b, + 0x73, 0x2c, 0x20, 0x70, 0x65, 0x6e, 0x64, 0x20, + 0x25, 0x75, 0x2c, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x25, 0x73, 0x0a, 0x0d, 0x00, 0xb0, + 0xb5, 0x0c, 0x1c, 0x05, 0x1c, 0x17, 0x1c, 0xd7, + 0xf7, 0x17, 0xfe, 0x00, 0x28, 0x08, 0xd0, 0x7b, + 0x21, 0x01, 0x60, 0x0c, 0x30, 0xb0, 0xc0, 0x18, + 0x38, 0x01, 0x1c, 0x06, 0x20, 0xd7, 0xf7, 0x7b, + 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x02, 0x1c, 0x41, 0x69, 0xc0, 0x68, 0x12, + 0x69, 0xd7, 0xf7, 0x49, 0xfa, 0x08, 0xbc, 0x18, + 0x47, 0xb0, 0xb5, 0x83, 0xb0, 0x15, 0x1c, 0x08, + 0x9a, 0x0f, 0x1c, 0x04, 0x1c, 0x07, 0x48, 0x07, + 0x99, 0x00, 0x90, 0x01, 0x91, 0x39, 0x1c, 0x20, + 0x1c, 0x02, 0x92, 0x2a, 0x1c, 0xfe, 0xf7, 0xd9, + 0xfe, 0x03, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x19, 0x8f, 0x02, 0x20, 0x00, + 0xb5, 0xfe, 0xf7, 0x9b, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x85, 0xb0, 0xad, 0x48, 0x17, + 0x23, 0x9b, 0x01, 0xc5, 0x18, 0x0b, 0x23, 0xdb, + 0x01, 0xc4, 0x18, 0x01, 0x20, 0xd7, 0xf7, 0x91, + 0xfe, 0xc6, 0x1d, 0x07, 0x1c, 0xe8, 0x68, 0x05, + 0x36, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x68, 0x7c, + 0x28, 0xf3, 0xd1, 0x38, 0x68, 0x6e, 0x38, 0x49, + 0x28, 0x03, 0xd2, 0x02, 0xa3, 0xed, 0x09, 0x00, + 0x95, 0x02, 0x1b, 0x18, 0x1b, 0x5a, 0x9f, 0x44, + 0x37, 0xe1, 0x00, 0x1c, 0xe2, 0x01, 0xea, 0x01, + 0xf2, 0x01, 0xfa, 0x01, 0x02, 0x02, 0x0a, 0x02, + 0x12, 0x02, 0x1a, 0x02, 0x22, 0x02, 0x2a, 0x02, + 0x4a, 0x02, 0x32, 0x02, 0x52, 0x02, 0x5a, 0x02, + 0x3a, 0x02, 0x42, 0x02, 0x62, 0x02, 0x6a, 0x02, + 0x70, 0x02, 0x70, 0x02, 0x70, 0x02, 0x70, 0x02, + 0x70, 0x02, 0x70, 0x02, 0x70, 0x02, 0x70, 0x02, + 0x70, 0x02, 0x70, 0x02, 0x70, 0x02, 0xdc, 0x01, + 0xa6, 0x00, 0x70, 0x02, 0x70, 0x02, 0x94, 0x00, + 0xa0, 0x00, 0xb8, 0x00, 0xd4, 0x00, 0xe0, 0x00, + 0xec, 0x00, 0xf4, 0x00, 0x70, 0x02, 0xfc, 0x00, + 0x04, 0x01, 0x14, 0x01, 0x0c, 0x01, 0x70, 0x02, + 0x70, 0x02, 0x70, 0x02, 0x1c, 0x01, 0x26, 0x01, + 0x30, 0x01, 0x38, 0x01, 0x40, 0x01, 0x48, 0x01, + 0x60, 0x01, 0x58, 0x01, 0x68, 0x01, 0x70, 0x02, + 0x70, 0x02, 0x78, 0x01, 0x88, 0x01, 0x90, 0x01, + 0x9e, 0x01, 0x98, 0x01, 0xae, 0x01, 0xa6, 0x01, + 0x70, 0x02, 0x50, 0x01, 0xb6, 0x01, 0xbe, 0x01, + 0xc6, 0x01, 0xce, 0x01, 0xd4, 0x01, 0x31, 0x79, + 0x30, 0x68, 0xb2, 0x68, 0x09, 0xf0, 0x52, 0xfa, + 0xe7, 0xe0, 0x09, 0xf0, 0x7d, 0xfa, 0xe4, 0xe0, + 0xb2, 0x68, 0x00, 0x92, 0x09, 0xce, 0x08, 0x3e, + 0xf1, 0x68, 0x32, 0x69, 0x09, 0xf0, 0x88, 0xfa, + 0xdb, 0xe0, 0x18, 0x36, 0x07, 0xce, 0x24, 0x3e, + 0x03, 0x91, 0x02, 0x90, 0x04, 0x92, 0x31, 0x69, + 0x72, 0x69, 0x00, 0x91, 0x01, 0x92, 0x0f, 0xce, + 0x09, 0xf0, 0xf2, 0xfa, 0xcd, 0xe0, 0x33, 0x1d, + 0x0d, 0xcb, 0x31, 0x68, 0x09, 0xf0, 0x29, 0xfb, + 0xc7, 0xe0, 0x32, 0x69, 0x00, 0x92, 0x0f, 0xce, + 0x09, 0xf0, 0xc4, 0xfb, 0xc1, 0xe0, 0x0f, 0xce, + 0x09, 0xf0, 0x18, 0xfc, 0xbd, 0xe0, 0x03, 0xce, + 0xed, 0x09, 0x00, 0x96, 0x02, 0x08, 0xf0, 0xfe, + 0xfe, 0xb9, 0xe0, 0x30, 0x68, 0x0a, 0xf0, 0x17, + 0xfb, 0xb5, 0xe0, 0x30, 0x68, 0x0a, 0xf0, 0x1a, + 0xfb, 0xb1, 0xe0, 0x03, 0xce, 0x09, 0xf0, 0x60, + 0xfc, 0xad, 0xe0, 0x30, 0x68, 0x09, 0xf0, 0x3e, + 0xfc, 0xa9, 0xe0, 0x03, 0xce, 0x32, 0x1c, 0x09, + 0xf0, 0x76, 0xfc, 0xa4, 0xe0, 0x07, 0xce, 0x33, + 0x1c, 0x09, 0xf0, 0xc5, 0xfc, 0x9f, 0xe0, 0x30, + 0x68, 0x09, 0xf0, 0x19, 0xfd, 0x9b, 0xe0, 0x07, + 0xce, 0x09, 0xf0, 0x1c, 0xfd, 0x97, 0xe0, 0x07, + 0xce, 0x09, 0xf0, 0x32, 0xfe, 0x93, 0xe0, 0x07, + 0xce, 0x09, 0xf0, 0xaa, 0xfe, 0x8f, 0xe0, 0x30, + 0x68, 0x09, 0xf0, 0xd8, 0xfe, 0x8b, 0xe0, 0x30, + 0x68, 0x09, 0xf0, 0x88, 0xff, 0x87, 0xe0, 0x30, + 0x68, 0x09, 0xf0, 0x2e, 0xff, 0x83, 0xe0, 0x31, + 0x69, 0x72, 0x69, 0x00, 0x91, 0x01, 0x92, 0x0f, + 0xce, 0x09, 0xf0, 0xd2, 0xff, 0x7b, 0xe0, 0x31, + 0x69, 0x72, 0x69, 0x00, 0x91, 0x01, 0x92, 0x0f, + 0xce, 0x0a, 0xf0, 0x46, 0xf8, 0x73, 0xe0, 0x30, + 0x68, 0x0a, 0xf0, 0x4a, 0xf9, 0x6f, 0xe0, 0x30, + 0x68, 0x0a, 0xf0, 0x96, 0xf9, 0x6b, 0xe0, 0x0a, + 0xf0, 0xec, 0xf9, 0x68, 0xe0, 0x03, 0xce, 0x0a, + 0xf0, 0x07, 0xfa, 0x64, 0xe0, 0x03, 0xce, 0x0a, + 0xf0, 0x35, 0xfb, 0x60, 0xe0, 0x30, 0x68, 0x0a, + 0xf0, 0xaf, 0xfb, 0x5c, 0xe0, 0x30, 0x68, 0x0a, + 0xf0, 0xc9, 0xfa, 0x58, 0xe0, 0x03, 0xce, 0x0a, + 0xf0, 0xad, 0xf8, 0x54, 0xe0, 0x03, 0xce, 0x0a, + 0xf0, 0xb8, 0xf8, 0x50, 0xe0, 0x0a, 0xf0, 0xe8, + 0xf9, 0x4d, 0xe0, 0x03, 0xce, 0x0a, 0xf0, 0xac, + 0xf9, 0x49, 0xe0, 0x30, 0x68, 0xa0, 0x63, 0x46, + 0xe0, 0x38, 0x1c, 0x03, 0xf0, 0x76, 0xfd, 0x42, + 0xe0, 0x38, 0x1c, 0x03, 0xf0, 0x83, 0xfd, 0x3e, + 0xe0, 0x38, 0x1c, 0xed, 0x09, 0x00, 0x97, 0x02, + 0x03, 0xf0, 0xd1, 0xfd, 0x3a, 0xe0, 0x38, 0x1c, + 0x03, 0xf0, 0x61, 0xfe, 0x36, 0xe0, 0x38, 0x1c, + 0x03, 0xf0, 0xfd, 0xfe, 0x32, 0xe0, 0x38, 0x1c, + 0x08, 0xf0, 0xa3, 0xfa, 0x2e, 0xe0, 0x38, 0x1c, + 0x03, 0xf0, 0xa1, 0xff, 0x2a, 0xe0, 0x38, 0x1c, + 0x03, 0xf0, 0xbb, 0xff, 0x26, 0xe0, 0x38, 0x1c, + 0x03, 0xf0, 0xcf, 0xff, 0x22, 0xe0, 0x38, 0x1c, + 0x03, 0xf0, 0xdf, 0xff, 0x1e, 0xe0, 0x38, 0x1c, + 0x0a, 0xf0, 0x42, 0xfc, 0x1a, 0xe0, 0x38, 0x1c, + 0x04, 0xf0, 0x37, 0xf9, 0x16, 0xe0, 0x38, 0x1c, + 0x04, 0xf0, 0xea, 0xfd, 0x12, 0xe0, 0x38, 0x1c, + 0x04, 0xf0, 0x1d, 0xf9, 0x0e, 0xe0, 0x38, 0x1c, + 0x08, 0xf0, 0xe1, 0xf8, 0x0a, 0xe0, 0x38, 0x1c, + 0xff, 0xf7, 0x8d, 0xfe, 0x06, 0xe0, 0x38, 0x1c, + 0x04, 0xf0, 0x11, 0xf8, 0x02, 0xe0, 0x38, 0x1c, + 0x04, 0xf0, 0x32, 0xf9, 0x00, 0x2f, 0x00, 0xd1, + 0xaf, 0xe6, 0x38, 0x1c, 0xd7, 0xf7, 0xc3, 0xfc, + 0xab, 0xe6, 0xb8, 0xa8, 0x03, 0x20, 0xff, 0x20, + 0xde, 0x30, 0x70, 0x47, 0xff, 0x20, 0xb0, 0x30, + 0x70, 0x47, 0x80, 0xb4, 0x0f, 0x1c, 0x0c, 0xcf, + 0x01, 0x1c, 0x0c, 0xc1, 0x0c, 0xcf, 0x0c, 0xc1, + 0x01, 0x78, 0xe9, 0x31, 0x01, 0x70, 0x41, 0x78, + 0xe5, 0x23, 0x59, 0x40, 0x41, 0x70, 0x81, 0x78, + 0xdf, 0x31, 0x81, 0x70, 0xc1, 0x78, 0xc1, 0x23, + 0x59, 0x40, 0xc1, 0x70, 0x01, 0x79, 0xb3, 0x31, + 0x01, 0x71, 0x41, 0x79, 0xa7, 0x23, 0x59, 0x40, + 0x41, 0x71, 0x81, 0x79, 0x95, 0x31, 0x81, 0x71, + 0xc1, 0x79, 0x83, 0x23, 0x59, 0x40, 0xc1, 0x71, + 0x01, 0x7a, 0xe9, 0x23, 0x59, 0x40, 0x01, 0x72, + 0x41, 0x7a, 0xe5, 0x31, 0x41, 0x72, 0x81, 0x7a, + 0xdf, 0x23, 0x59, 0x40, 0x81, 0x72, 0xc1, 0x7a, + 0xc1, 0x31, 0xc1, 0x72, 0x01, 0x7b, 0xed, 0x09, + 0x00, 0x98, 0x02, 0xb3, 0x23, 0x59, 0x40, 0x01, + 0x73, 0x41, 0x7b, 0xa7, 0x31, 0x41, 0x73, 0x81, + 0x7b, 0x95, 0x23, 0x59, 0x40, 0x81, 0x73, 0xc1, + 0x7b, 0x83, 0x31, 0xc1, 0x73, 0x80, 0xbc, 0x70, + 0x47, 0xf3, 0xb5, 0x86, 0xb0, 0xf0, 0xc9, 0x68, + 0x46, 0xf0, 0xc0, 0x00, 0x21, 0x00, 0x20, 0x6a, + 0x46, 0x12, 0x5c, 0x06, 0x9c, 0x51, 0x40, 0x09, + 0x06, 0x09, 0x0e, 0x22, 0x54, 0x01, 0x30, 0x10, + 0x28, 0xf5, 0xd3, 0x04, 0xab, 0x00, 0x22, 0x18, + 0x4e, 0x01, 0x20, 0x19, 0x70, 0x00, 0x21, 0x6b, + 0x46, 0x5b, 0x5c, 0xdf, 0x00, 0x5b, 0x09, 0x1f, + 0x43, 0x6b, 0x46, 0x5f, 0x54, 0x01, 0x31, 0x10, + 0x29, 0xf5, 0xd9, 0x11, 0x01, 0x89, 0x18, 0xcf, + 0x1d, 0x01, 0x32, 0x1c, 0x37, 0x00, 0x21, 0x06, + 0x9c, 0x03, 0x01, 0x1b, 0x19, 0x05, 0x92, 0x6c, + 0x46, 0xa5, 0x5c, 0x7c, 0x18, 0x24, 0x06, 0x24, + 0x0e, 0x34, 0x5d, 0x34, 0x5d, 0x2c, 0x19, 0x5c, + 0x54, 0x00, 0x24, 0x10, 0x2a, 0x00, 0xd0, 0x54, + 0x1c, 0x01, 0x31, 0x22, 0x1c, 0x10, 0x29, 0xee, + 0xd3, 0x05, 0x9a, 0x01, 0x30, 0x10, 0x2a, 0xd5, + 0xd3, 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x88, 0xaf, 0x03, 0x20, 0xf0, + 0xb4, 0x8a, 0xb0, 0x13, 0x78, 0x07, 0x78, 0x0c, + 0x78, 0x7b, 0x40, 0xb7, 0x4f, 0xfb, 0x5c, 0x1b, + 0x19, 0x13, 0x70, 0x53, 0x78, 0x44, 0x78, 0x4d, + 0x78, 0x1c, 0x19, 0xb4, 0x4b, 0x1c, 0x5d, 0x6c, + 0x40, 0x54, 0x70, 0x94, 0x78, 0x85, 0x78, 0x64, + 0x19, 0x1c, 0x5d, 0x8d, 0x78, 0x6c, 0x40, 0x94, + 0x70, 0xd4, 0x78, 0xc5, 0x78, 0x6c, 0x40, 0x3c, + 0x5d, 0xcd, 0x78, 0x64, 0x19, 0xd4, 0x70, 0x14, + 0x79, 0x05, 0x79, 0x6c, 0x40, 0x3c, 0x5d, 0x0d, + 0x79, 0x64, 0x19, 0x14, 0x71, 0x54, 0x79, 0x45, + 0x79, 0xed, 0x09, 0x00, 0x99, 0x02, 0x64, 0x19, + 0x1c, 0x5d, 0x4d, 0x79, 0x6c, 0x40, 0x54, 0x71, + 0x94, 0x79, 0x85, 0x79, 0x64, 0x19, 0x1c, 0x5d, + 0x8d, 0x79, 0x6c, 0x40, 0x94, 0x71, 0xd4, 0x79, + 0xc5, 0x79, 0x6c, 0x40, 0x3c, 0x5d, 0xcd, 0x79, + 0x64, 0x19, 0xd4, 0x71, 0x14, 0x7a, 0x05, 0x7a, + 0x6c, 0x40, 0x3c, 0x5d, 0x0d, 0x7a, 0x64, 0x19, + 0x14, 0x72, 0x54, 0x7a, 0x45, 0x7a, 0x64, 0x19, + 0x1c, 0x5d, 0x4d, 0x7a, 0x6c, 0x40, 0x54, 0x72, + 0x94, 0x7a, 0x85, 0x7a, 0x64, 0x19, 0x1c, 0x5d, + 0x8d, 0x7a, 0x6c, 0x40, 0x94, 0x72, 0xd4, 0x7a, + 0xc5, 0x7a, 0x6c, 0x40, 0x3c, 0x5d, 0xcd, 0x7a, + 0x64, 0x19, 0xd4, 0x72, 0x14, 0x7b, 0x05, 0x7b, + 0x6c, 0x40, 0x3c, 0x5d, 0x0d, 0x7b, 0x64, 0x19, + 0x14, 0x73, 0x54, 0x7b, 0x45, 0x7b, 0x64, 0x19, + 0x1c, 0x5d, 0x4d, 0x7b, 0x6c, 0x40, 0x54, 0x73, + 0x94, 0x7b, 0x85, 0x7b, 0x64, 0x19, 0x1b, 0x5d, + 0x8c, 0x7b, 0x63, 0x40, 0x93, 0x73, 0xd3, 0x7b, + 0xc0, 0x7b, 0xc9, 0x7b, 0x58, 0x40, 0x38, 0x5c, + 0x40, 0x18, 0xd0, 0x73, 0x51, 0x78, 0x10, 0x78, + 0x09, 0x18, 0x51, 0x70, 0x57, 0x78, 0x38, 0x18, + 0x10, 0x70, 0xd1, 0x78, 0x90, 0x78, 0x09, 0x18, + 0xd1, 0x70, 0xd3, 0x78, 0xc0, 0x18, 0x90, 0x70, + 0x50, 0x79, 0x11, 0x79, 0x40, 0x18, 0x50, 0x71, + 0x50, 0x79, 0x09, 0x18, 0x11, 0x71, 0xd4, 0x79, + 0x91, 0x79, 0x64, 0x18, 0xd4, 0x71, 0xd4, 0x79, + 0x09, 0x19, 0x91, 0x71, 0x51, 0x7a, 0x15, 0x7a, + 0x49, 0x19, 0x51, 0x72, 0x51, 0x7a, 0x6d, 0x18, + 0x15, 0x72, 0xd6, 0x7a, 0x95, 0x7a, 0x76, 0x19, + 0xd6, 0x72, 0xd6, 0x7a, 0x09, 0x96, 0xad, 0x19, + 0x95, 0x72, 0x56, 0x7b, 0x15, 0x7b, 0x76, 0x19, + 0x56, 0x73, 0x56, 0x7b, 0x08, 0x96, 0xad, 0x19, + 0x15, 0x73, 0xd5, 0x7b, 0xed, 0x09, 0x00, 0x9a, + 0x02, 0x96, 0x7b, 0xad, 0x19, 0xd5, 0x73, 0xd5, + 0x7b, 0x07, 0x95, 0x75, 0x19, 0x95, 0x73, 0x15, + 0x78, 0x64, 0x19, 0xd4, 0x71, 0xd4, 0x79, 0x06, + 0x94, 0x64, 0x19, 0x14, 0x70, 0x3c, 0x1c, 0x97, + 0x78, 0xe4, 0x19, 0x54, 0x70, 0x54, 0x78, 0x3f, + 0x19, 0x97, 0x70, 0x1f, 0x1c, 0x13, 0x79, 0xff, + 0x18, 0xd7, 0x70, 0xd7, 0x78, 0xdb, 0x19, 0x13, + 0x71, 0x03, 0x1c, 0x90, 0x79, 0x1b, 0x18, 0x53, + 0x71, 0x53, 0x79, 0x3e, 0x1c, 0x25, 0x1c, 0xc0, + 0x18, 0x90, 0x71, 0x10, 0x7a, 0x1f, 0x1c, 0x09, + 0x9b, 0x1b, 0x18, 0xd3, 0x72, 0xd3, 0x7a, 0x05, + 0x93, 0xc0, 0x18, 0x10, 0x72, 0x90, 0x7a, 0x09, + 0x18, 0x51, 0x72, 0x51, 0x7a, 0x04, 0x91, 0x40, + 0x18, 0x90, 0x72, 0x10, 0x7b, 0x07, 0x99, 0x09, + 0x18, 0xd1, 0x73, 0xd1, 0x7b, 0x40, 0x18, 0x10, + 0x73, 0x90, 0x7b, 0x0c, 0x1c, 0x08, 0x99, 0x09, + 0x18, 0x51, 0x73, 0x51, 0x7b, 0x40, 0x18, 0x90, + 0x73, 0x10, 0x78, 0x0b, 0x1c, 0x31, 0x18, 0xd1, + 0x70, 0xd1, 0x78, 0x03, 0x91, 0x08, 0x18, 0x10, + 0x70, 0x90, 0x78, 0x21, 0x18, 0xd1, 0x73, 0xd1, + 0x7b, 0x40, 0x18, 0x90, 0x70, 0x10, 0x79, 0x06, + 0x9c, 0x0e, 0x1c, 0x21, 0x18, 0xd1, 0x71, 0xd1, + 0x79, 0x02, 0x91, 0x40, 0x18, 0x10, 0x71, 0x90, + 0x79, 0x29, 0x18, 0x51, 0x70, 0x51, 0x78, 0x40, + 0x18, 0x90, 0x71, 0x10, 0x7a, 0x0d, 0x1c, 0x39, + 0x18, 0x51, 0x71, 0x57, 0x79, 0xc0, 0x19, 0x10, + 0x72, 0x90, 0x7a, 0x19, 0x18, 0x51, 0x73, 0x53, + 0x7b, 0xc0, 0x18, 0x90, 0x72, 0x11, 0x7b, 0x05, + 0x98, 0x40, 0x18, 0xd0, 0x72, 0x08, 0x1c, 0xd1, + 0x7a, 0x40, 0x18, 0x10, 0x73, 0x0c, 0x1c, 0x91, + 0x7b, 0x04, 0x98, 0x40, 0x18, 0x50, 0x72, 0x50, + 0x7a, 0x09, 0x18, 0x91, 0x73, 0x11, 0x78, 0xed, + 0x09, 0x00, 0x9b, 0x02, 0x5b, 0x18, 0x53, 0x73, + 0x53, 0x7b, 0x59, 0x18, 0x11, 0x70, 0x91, 0x78, + 0x7f, 0x18, 0x57, 0x71, 0x57, 0x79, 0xc9, 0x19, + 0x91, 0x70, 0x11, 0x79, 0x40, 0x18, 0x50, 0x72, + 0x50, 0x7a, 0x08, 0x18, 0x10, 0x71, 0x91, 0x79, + 0x60, 0x18, 0xd0, 0x72, 0xd0, 0x7a, 0x09, 0x18, + 0x91, 0x71, 0x14, 0x7a, 0x31, 0x19, 0xd1, 0x73, + 0xd1, 0x7b, 0x64, 0x18, 0x14, 0x72, 0x2c, 0x1c, + 0x95, 0x7a, 0x64, 0x19, 0x54, 0x70, 0x54, 0x78, + 0x2d, 0x19, 0x95, 0x72, 0x15, 0x7b, 0x03, 0x9e, + 0x76, 0x19, 0xd6, 0x70, 0xd6, 0x78, 0x01, 0x96, + 0xad, 0x19, 0x15, 0x73, 0x95, 0x7b, 0x02, 0x9e, + 0x76, 0x19, 0xd6, 0x71, 0xd6, 0x79, 0x00, 0x96, + 0xad, 0x19, 0x95, 0x73, 0x96, 0x7b, 0x15, 0x78, + 0x16, 0x70, 0x16, 0x7b, 0x96, 0x73, 0x96, 0x7a, + 0x16, 0x73, 0x96, 0x78, 0x96, 0x72, 0x16, 0x7a, + 0x96, 0x70, 0x16, 0x79, 0x16, 0x72, 0x15, 0x71, + 0x00, 0x9e, 0x56, 0x70, 0xd0, 0x71, 0xd7, 0x72, + 0x53, 0x71, 0x54, 0x73, 0x01, 0x9e, 0xd6, 0x73, + 0xd1, 0x70, 0x0a, 0xb0, 0xf0, 0xbc, 0x70, 0x47, + 0x00, 0x00, 0x88, 0xaf, 0x03, 0x20, 0x88, 0xb0, + 0x03, 0x20, 0x90, 0xb5, 0xc8, 0xb0, 0x14, 0x1c, + 0x0f, 0x1c, 0x01, 0x1c, 0x04, 0xaa, 0x10, 0x1c, + 0xff, 0xf7, 0x36, 0xfe, 0x00, 0x2c, 0x04, 0xd0, + 0x68, 0x46, 0x10, 0x22, 0x39, 0x1c, 0xd6, 0xf7, + 0xd4, 0xfe, 0x04, 0xa8, 0x08, 0xa9, 0x3a, 0x1c, + 0xff, 0xf7, 0x71, 0xfe, 0x0c, 0xa8, 0x10, 0xa9, + 0x3a, 0x1c, 0xff, 0xf7, 0x6c, 0xfe, 0x00, 0x2c, + 0x4f, 0xd0, 0x00, 0xa9, 0x09, 0x78, 0x38, 0x78, + 0x48, 0x40, 0x38, 0x70, 0x00, 0xa9, 0x49, 0x78, + 0x78, 0x78, 0x40, 0x18, 0x78, 0x70, 0x00, 0xa9, + 0x89, 0x78, 0xb8, 0x78, 0x40, 0x18, 0xb8, 0x70, + 0x00, 0xa9, 0xed, 0x09, 0x00, 0x9c, 0x02, 0xc9, + 0x78, 0xf8, 0x78, 0x48, 0x40, 0xf8, 0x70, 0x01, + 0xa9, 0x09, 0x78, 0x38, 0x79, 0x48, 0x40, 0x38, + 0x71, 0x01, 0xa9, 0x49, 0x78, 0x78, 0x79, 0x40, + 0x18, 0x78, 0x71, 0x01, 0xa9, 0x89, 0x78, 0xb8, + 0x79, 0x40, 0x18, 0xb8, 0x71, 0x01, 0xa9, 0xc9, + 0x78, 0xf8, 0x79, 0x48, 0x40, 0xf8, 0x71, 0x02, + 0xa9, 0x09, 0x78, 0x38, 0x7a, 0x48, 0x40, 0x38, + 0x72, 0x02, 0xa9, 0x49, 0x78, 0x78, 0x7a, 0x40, + 0x18, 0x78, 0x72, 0x02, 0xa9, 0x89, 0x78, 0xb8, + 0x7a, 0x40, 0x18, 0xb8, 0x72, 0x02, 0xa9, 0xc9, + 0x78, 0xf8, 0x7a, 0x48, 0x40, 0xf8, 0x72, 0x03, + 0xa9, 0x09, 0x78, 0x38, 0x7b, 0x48, 0x40, 0x38, + 0x73, 0x03, 0xa9, 0x49, 0x78, 0x78, 0x7b, 0x40, + 0x18, 0x78, 0x73, 0x03, 0xa9, 0x89, 0x78, 0xb8, + 0x7b, 0x40, 0x18, 0xb8, 0x73, 0x03, 0xa9, 0xc9, + 0x78, 0xf8, 0x7b, 0x48, 0x40, 0xf8, 0x73, 0x14, + 0xa8, 0x18, 0xa9, 0x3a, 0x1c, 0xff, 0xf7, 0x15, + 0xfe, 0x1c, 0xa8, 0x20, 0xa9, 0x3a, 0x1c, 0xff, + 0xf7, 0x10, 0xfe, 0x24, 0xa8, 0x28, 0xa9, 0x3a, + 0x1c, 0xff, 0xf7, 0x0b, 0xfe, 0x2c, 0xa8, 0x30, + 0xa9, 0x3a, 0x1c, 0xff, 0xf7, 0x06, 0xfe, 0x34, + 0xa8, 0x38, 0xa9, 0x3a, 0x1c, 0xff, 0xf7, 0x01, + 0xfe, 0x3c, 0xa8, 0x40, 0xa9, 0x3a, 0x1c, 0xff, + 0xf7, 0xfc, 0xfd, 0x44, 0xa9, 0x09, 0x78, 0x38, + 0x78, 0x48, 0x40, 0x38, 0x70, 0x44, 0xa9, 0x49, + 0x78, 0x78, 0x78, 0x40, 0x18, 0x78, 0x70, 0x44, + 0xa9, 0x89, 0x78, 0xb8, 0x78, 0x40, 0x18, 0xb8, + 0x70, 0x44, 0xa9, 0xc9, 0x78, 0xf8, 0x78, 0x48, + 0x40, 0xf8, 0x70, 0x45, 0xa9, 0x09, 0x78, 0x38, + 0x79, 0x48, 0x40, 0x38, 0x71, 0x45, 0xa9, 0x49, + 0x78, 0x78, 0x79, 0x40, 0x18, 0x78, 0x71, 0x45, + 0xa9, 0x89, 0x78, 0xb8, 0x79, 0xed, 0x09, 0x00, + 0x9d, 0x02, 0x40, 0x18, 0xb8, 0x71, 0x45, 0xa9, + 0xc9, 0x78, 0xf8, 0x79, 0x48, 0x40, 0xf8, 0x71, + 0x46, 0xa9, 0x09, 0x78, 0x38, 0x7a, 0x48, 0x40, + 0x38, 0x72, 0x46, 0xa9, 0x49, 0x78, 0x78, 0x7a, + 0x40, 0x18, 0x78, 0x72, 0x46, 0xa9, 0x89, 0x78, + 0xb8, 0x7a, 0x40, 0x18, 0xb8, 0x72, 0x46, 0xa9, + 0xc9, 0x78, 0xf8, 0x7a, 0x48, 0x40, 0xf8, 0x72, + 0x47, 0xa9, 0x09, 0x78, 0x38, 0x7b, 0x48, 0x40, + 0x38, 0x73, 0x47, 0xa9, 0x49, 0x78, 0x78, 0x7b, + 0x40, 0x18, 0x78, 0x73, 0x47, 0xa9, 0x89, 0x78, + 0xb8, 0x7b, 0x40, 0x18, 0xb8, 0x73, 0x47, 0xa9, + 0xc9, 0x78, 0xf8, 0x7b, 0x48, 0x40, 0xf8, 0x73, + 0x48, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x9f, 0xb5, 0x88, 0xb0, 0x04, 0x1c, 0x68, 0x46, + 0x0f, 0x22, 0x0f, 0x1c, 0xd6, 0xf7, 0xfe, 0xfd, + 0xf8, 0x7b, 0x06, 0x23, 0x0a, 0xa9, 0x58, 0x40, + 0x03, 0xab, 0xd8, 0x70, 0x04, 0xa8, 0x06, 0x22, + 0xd6, 0xf7, 0xf4, 0xfd, 0x06, 0x22, 0x05, 0xa8, + 0x02, 0x30, 0x0a, 0xa9, 0xd6, 0xf7, 0xee, 0xfd, + 0x04, 0x22, 0x07, 0xa8, 0x0a, 0xa9, 0xd6, 0xf7, + 0xe9, 0xfd, 0x68, 0x46, 0x01, 0x22, 0x04, 0xa9, + 0xff, 0xf7, 0x00, 0xff, 0x04, 0xa8, 0x8d, 0xc8, + 0x8d, 0xc4, 0x0c, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xff, 0xb5, 0x8c, 0xb0, 0x0f, 0x1c, + 0x16, 0x9d, 0x04, 0x1c, 0x10, 0x2d, 0x15, 0x99, + 0x00, 0xd9, 0x10, 0x25, 0x08, 0xa8, 0x2a, 0x1c, + 0xd6, 0xf7, 0xd0, 0xfd, 0x10, 0x20, 0x40, 0x1b, + 0x06, 0x26, 0x06, 0x28, 0x00, 0xd8, 0x06, 0x1c, + 0x00, 0x2e, 0x06, 0xd0, 0x08, 0xa8, 0x40, 0x19, + 0x32, 0x1c, 0x0e, 0xa9, 0xd6, 0xf7, 0xc2, 0xfd, + 0xad, 0x19, 0x00, 0x26, 0x28, 0x1c, 0x31, 0x1c, + 0xd6, 0xf7, 0xd2, 0xfc, 0x08, 0xa8, 0x41, 0x5c, + 0xed, 0x09, 0x00, 0x9e, 0x02, 0x68, 0x46, 0x81, + 0x55, 0x01, 0x36, 0x10, 0x2e, 0xf4, 0xd3, 0x0f, + 0x22, 0x39, 0x1c, 0x04, 0xa8, 0xd6, 0xf7, 0xb0, + 0xfd, 0xf8, 0x7b, 0x07, 0xab, 0x04, 0xa9, 0x68, + 0x40, 0xd8, 0x70, 0x68, 0x46, 0x01, 0x22, 0xff, + 0xf7, 0xc3, 0xfe, 0x04, 0xa8, 0xac, 0xc8, 0xac, + 0xc4, 0x10, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x0f, 0xb4, 0xf0, 0xb5, 0x84, 0xb0, 0x14, + 0x1c, 0x10, 0x22, 0x0d, 0x1c, 0x07, 0x1c, 0xd6, + 0xf7, 0x97, 0xfd, 0x00, 0x22, 0x20, 0x1c, 0x39, + 0x1c, 0xff, 0xf7, 0xae, 0xfe, 0x00, 0x20, 0x39, + 0x5c, 0x2a, 0x5c, 0x51, 0x40, 0x39, 0x54, 0x01, + 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x00, 0x25, 0x06, + 0x20, 0x29, 0x1c, 0x7e, 0x5d, 0xd6, 0xf7, 0x9a, + 0xfc, 0x0c, 0xa8, 0x40, 0x5c, 0x30, 0x18, 0x78, + 0x55, 0x01, 0x35, 0x10, 0x2d, 0xf3, 0xd3, 0x68, + 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x93, 0xfc, 0x68, + 0x46, 0x01, 0x22, 0x39, 0x1c, 0xff, 0xf7, 0x90, + 0xfe, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x04, + 0xb0, 0x18, 0x47, 0xff, 0xb5, 0x84, 0xb0, 0x14, + 0x1c, 0x10, 0x22, 0x0d, 0x1c, 0x07, 0x1c, 0xd6, + 0xf7, 0x67, 0xfd, 0x00, 0x22, 0x20, 0x1c, 0x39, + 0x1c, 0xff, 0xf7, 0x7e, 0xfe, 0x00, 0x20, 0x39, + 0x5c, 0x2a, 0x5c, 0x51, 0x40, 0x39, 0x54, 0x01, + 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x00, 0x25, 0x0c, + 0x20, 0x29, 0x1c, 0x7e, 0x5d, 0xd6, 0xf7, 0x6a, + 0xfc, 0x07, 0x9b, 0x58, 0x5c, 0x30, 0x18, 0x78, + 0x55, 0x01, 0x35, 0x10, 0x2d, 0xf3, 0xd3, 0x68, + 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x63, 0xfc, 0x68, + 0x46, 0x01, 0x22, 0x39, 0x1c, 0xff, 0xf7, 0x60, + 0xfe, 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0xda, + 0xf7, 0x07, 0xfb, 0xed, 0x09, 0x00, 0x9f, 0x02, + 0x05, 0x1c, 0x35, 0xa0, 0x0c, 0x1c, 0x01, 0x68, + 0x00, 0x91, 0x41, 0x68, 0x01, 0x91, 0xf9, 0x1d, + 0x9d, 0x31, 0x08, 0x68, 0x49, 0x68, 0x01, 0xf0, + 0x4c, 0xfe, 0x07, 0x1c, 0x4b, 0xd0, 0x7c, 0x61, + 0x3d, 0x61, 0xf8, 0x6c, 0x00, 0x28, 0x52, 0xd0, + 0xfe, 0x1d, 0x3d, 0x36, 0x03, 0x96, 0x32, 0x68, + 0x28, 0x1c, 0x02, 0x92, 0x73, 0x68, 0x21, 0x1c, + 0x1e, 0x1c, 0xe7, 0xf7, 0x40, 0xf9, 0x00, 0x28, + 0x06, 0xd0, 0x02, 0x98, 0x31, 0x1c, 0x40, 0x1b, + 0xa1, 0x41, 0x01, 0x91, 0x00, 0x90, 0x3e, 0xe0, + 0x02, 0x9a, 0x21, 0x1c, 0xad, 0x1a, 0xb1, 0x41, + 0x0c, 0x1c, 0x1f, 0xe0, 0x02, 0x1c, 0x28, 0x1c, + 0x00, 0x23, 0x21, 0x1c, 0xe7, 0xf7, 0x37, 0xf9, + 0x00, 0x28, 0x15, 0xd0, 0xfa, 0x6c, 0x00, 0x23, + 0x21, 0x1c, 0xad, 0x1a, 0xfa, 0x6c, 0x03, 0x9e, + 0x99, 0x41, 0x0c, 0x1c, 0x03, 0xce, 0x08, 0x3e, + 0x80, 0x18, 0x59, 0x41, 0x03, 0xc6, 0xf8, 0x6c, + 0x16, 0x4b, 0x40, 0x08, 0xf8, 0x64, 0x98, 0x42, + 0x04, 0xd2, 0x00, 0x20, 0xf8, 0x64, 0x01, 0xe0, + 0x74, 0x68, 0x35, 0x68, 0x0f, 0xa6, 0x0c, 0xce, + 0x08, 0x3e, 0x28, 0x1c, 0x21, 0x1c, 0xe7, 0xf7, + 0x96, 0xf8, 0x00, 0x28, 0x0f, 0xd0, 0xf8, 0x6c, + 0x00, 0x28, 0xd3, 0xd1, 0x0b, 0xe0, 0x01, 0xf0, + 0xba, 0xfe, 0x0a, 0x49, 0xca, 0x6a, 0x90, 0x42, + 0x05, 0xd9, 0x88, 0x69, 0x07, 0x4b, 0x58, 0x43, + 0x00, 0x21, 0x01, 0x91, 0x00, 0x90, 0x00, 0x98, + 0x01, 0x99, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x84, 0x1e, 0x00, 0x38, 0xae, + 0x03, 0x20, 0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, + 0x07, 0x1c, 0xc5, 0x68, 0xda, 0xf7, 0x8b, 0xfa, + 0x00, 0x90, 0xf8, 0x1d, 0xff, 0x30, 0xed, 0x09, + 0x00, 0xa0, 0x02, 0x01, 0x91, 0x01, 0x21, 0x3a, + 0x30, 0x00, 0x22, 0x00, 0x2c, 0x04, 0xd1, 0xea, + 0x64, 0x02, 0x22, 0x2a, 0x65, 0x01, 0x63, 0x5f, + 0xe0, 0x00, 0x22, 0x02, 0x63, 0x29, 0x65, 0xe8, + 0x6c, 0x30, 0x49, 0x00, 0x28, 0x03, 0x91, 0x45, + 0xd0, 0xee, 0x1d, 0x3d, 0x36, 0x02, 0x96, 0x00, + 0x98, 0x01, 0x99, 0x32, 0x68, 0x73, 0x68, 0x1c, + 0x1c, 0x17, 0x1c, 0xe7, 0xf7, 0xb6, 0xf8, 0x00, + 0x28, 0x34, 0xd0, 0x00, 0x98, 0x01, 0x99, 0xc0, + 0x1b, 0xa1, 0x41, 0x04, 0x1c, 0x0f, 0x1c, 0x1e, + 0xe0, 0x02, 0x1c, 0x20, 0x1c, 0x00, 0x23, 0x39, + 0x1c, 0xe7, 0xf7, 0xbf, 0xf8, 0x00, 0x28, 0x15, + 0xd0, 0xea, 0x6c, 0x00, 0x23, 0x39, 0x1c, 0xa4, + 0x1a, 0xea, 0x6c, 0x02, 0x9e, 0x99, 0x41, 0x0f, + 0x1c, 0x03, 0xce, 0x08, 0x3e, 0x80, 0x18, 0x59, + 0x41, 0x03, 0xc6, 0xe8, 0x6c, 0x1a, 0x4b, 0x40, + 0x08, 0xe8, 0x64, 0x98, 0x42, 0x03, 0xd2, 0x00, + 0x20, 0xe8, 0x64, 0x00, 0xe0, 0x90, 0xce, 0x16, + 0xa6, 0x0c, 0xce, 0x08, 0x3e, 0x20, 0x1c, 0x39, + 0x1c, 0xe7, 0xf7, 0x1f, 0xf8, 0x00, 0x28, 0x02, + 0xd0, 0xe8, 0x6c, 0x00, 0x28, 0xd4, 0xd1, 0xe8, + 0x6c, 0x00, 0x28, 0x03, 0xd0, 0xe8, 0x6c, 0x40, + 0x00, 0xe8, 0x64, 0x02, 0xe0, 0x03, 0x99, 0x48, + 0x69, 0xe8, 0x64, 0xe8, 0x6c, 0x03, 0x99, 0x89, + 0x69, 0x88, 0x42, 0x00, 0xd9, 0xe9, 0x64, 0xea, + 0x6c, 0x00, 0x98, 0xef, 0x1d, 0x3d, 0x37, 0x01, + 0x99, 0x00, 0x23, 0x80, 0x18, 0x59, 0x41, 0x03, + 0xc7, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x38, 0xae, 0x03, 0x20, 0x80, + 0x84, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xb5, 0x07, 0x1c, 0xf9, + 0x6a, 0x00, 0x20, 0x00, 0x29, 0x15, 0xd0, 0x39, + 0x6c, 0xed, 0x09, 0x00, 0xa1, 0x02, 0x00, 0x29, + 0x12, 0xd1, 0xb8, 0x68, 0xf9, 0x68, 0x01, 0xf0, + 0x7b, 0xfa, 0x00, 0x28, 0x05, 0xd0, 0x40, 0x69, + 0x00, 0x28, 0x02, 0xd0, 0x01, 0x20, 0x38, 0x64, + 0x05, 0xe0, 0x00, 0x20, 0xf8, 0x62, 0x38, 0x1c, + 0x03, 0xa1, 0x01, 0xf0, 0xa7, 0xfd, 0x01, 0x20, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x61, 0x75, + 0x74, 0x68, 0x2e, 0x63, 0x3a, 0x20, 0x36, 0x35, + 0x34, 0x00, 0x00, 0x00, 0xf0, 0xb5, 0x87, 0xb0, + 0x0f, 0x1c, 0x6d, 0x46, 0x04, 0x1c, 0x47, 0xa0, + 0x11, 0x1c, 0x06, 0x1c, 0x0c, 0xce, 0x0c, 0xc5, + 0x6a, 0x46, 0xd5, 0x1d, 0x01, 0x35, 0x06, 0x95, + 0x06, 0x1c, 0x0c, 0xce, 0x0c, 0xc5, 0xe5, 0x1d, + 0x00, 0x22, 0x01, 0x31, 0x01, 0x35, 0x00, 0x29, + 0x05, 0x91, 0x04, 0x92, 0x6f, 0xd9, 0xfe, 0x1d, + 0x01, 0x36, 0x3e, 0xa3, 0x1a, 0x68, 0x03, 0xcf, + 0x5b, 0x68, 0x08, 0x3f, 0x19, 0x40, 0x10, 0x40, + 0x38, 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0xe6, 0xf7, + 0xa3, 0xff, 0x00, 0x28, 0x0f, 0xd0, 0x02, 0x98, + 0x03, 0x99, 0x0c, 0xcd, 0x08, 0x3d, 0x59, 0x40, + 0x50, 0x40, 0x02, 0x90, 0x03, 0x91, 0x01, 0x99, + 0x00, 0x98, 0x0c, 0xcc, 0x08, 0x3c, 0x59, 0x40, + 0x50, 0x40, 0x00, 0x90, 0x01, 0x91, 0x03, 0xcd, + 0x01, 0x22, 0x08, 0x3d, 0xe7, 0xf7, 0x18, 0xf8, + 0x03, 0xc5, 0x2e, 0xa3, 0x1a, 0x68, 0x03, 0xcc, + 0x5b, 0x68, 0x08, 0x3d, 0x08, 0x3c, 0x19, 0x40, + 0x10, 0x40, 0x26, 0xa3, 0x1a, 0x68, 0x5b, 0x68, + 0xe6, 0xf7, 0x7e, 0xff, 0x00, 0x28, 0x08, 0xd0, + 0x24, 0xa3, 0x1a, 0x68, 0x03, 0xcd, 0x5b, 0x68, + 0x08, 0x3d, 0x19, 0x43, 0x10, 0x43, 0x03, 0xc5, + 0x08, 0x3d, 0x03, 0xcc, 0x01, 0x22, 0x08, 0x3c, + 0xe6, 0xf7, 0xfa, 0xff, 0xed, 0x09, 0x00, 0xa2, + 0x02, 0x03, 0xc4, 0x03, 0xcf, 0x08, 0x3c, 0x01, + 0x22, 0x08, 0x3f, 0xe6, 0xf7, 0x71, 0xff, 0x03, + 0xc7, 0x19, 0xa3, 0x1a, 0x68, 0x03, 0xce, 0x5b, + 0x68, 0x08, 0x3f, 0x08, 0x3e, 0x19, 0x40, 0x10, + 0x40, 0x13, 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0xe6, + 0xf7, 0x59, 0xff, 0x00, 0x28, 0x08, 0xd0, 0x14, + 0xa3, 0x1a, 0x68, 0x03, 0xcf, 0x5b, 0x68, 0x08, + 0x3f, 0x19, 0x43, 0x10, 0x43, 0x03, 0xc7, 0x08, + 0x3f, 0x03, 0xce, 0x01, 0x22, 0x08, 0x3e, 0xe6, + 0xf7, 0x53, 0xff, 0x03, 0xc6, 0x04, 0x99, 0x05, + 0x98, 0x01, 0x31, 0x08, 0x3e, 0x88, 0x42, 0x04, + 0x91, 0x91, 0xd8, 0x06, 0x98, 0x0c, 0xc8, 0x0c, + 0xc5, 0x68, 0x46, 0x28, 0xc8, 0x28, 0xc4, 0x07, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xf7, 0xb5, 0x81, 0xb0, 0x07, 0x1c, 0xfc, + 0x1d, 0x80, 0x20, 0x86, 0x1a, 0x01, 0x34, 0x00, + 0x25, 0x00, 0x2e, 0x4e, 0xd9, 0x02, 0x99, 0xcb, + 0x1d, 0x01, 0x33, 0x00, 0x93, 0x26, 0xe0, 0x00, + 0x2d, 0x24, 0xd0, 0x03, 0xcc, 0x01, 0x22, 0x08, + 0x3c, 0xe6, 0xf7, 0xa0, 0xff, 0x03, 0xc4, 0x38, + 0xa3, 0x1a, 0x68, 0x03, 0xcf, 0x5b, 0x68, 0x08, + 0x3c, 0x08, 0x3f, 0x19, 0x40, 0x10, 0x40, 0x36, + 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0xe6, 0xf7, 0x06, + 0xff, 0x00, 0x28, 0x08, 0xd0, 0x34, 0xa3, 0x1a, + 0x68, 0x03, 0xcc, 0x5b, 0x68, 0x08, 0x3c, 0x19, + 0x43, 0x10, 0x43, 0x03, 0xc4, 0x08, 0x3c, 0x03, + 0xcf, 0x01, 0x22, 0x08, 0x3f, 0xe6, 0xf7, 0x82, + 0xff, 0x03, 0xc7, 0x08, 0x3f, 0x28, 0xa3, 0x1a, + 0x68, 0x03, 0xcc, 0x5b, 0x68, 0x08, 0x3c, 0xed, + 0x09, 0x00, 0xa3, 0x02, 0x19, 0x40, 0x10, 0x40, + 0x27, 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0xe6, 0xf7, + 0xe8, 0xfe, 0x00, 0x28, 0x11, 0xd0, 0x00, 0x9b, + 0x03, 0xcc, 0x1a, 0x68, 0x5b, 0x68, 0x08, 0x3c, + 0x59, 0x40, 0x50, 0x40, 0x03, 0xc4, 0x02, 0x9b, + 0x03, 0xcf, 0x1a, 0x68, 0x5b, 0x68, 0x08, 0x3c, + 0x08, 0x3f, 0x59, 0x40, 0x50, 0x40, 0x03, 0xc7, + 0x08, 0x3f, 0x01, 0x35, 0xae, 0x42, 0xb5, 0xd8, + 0x00, 0x25, 0x01, 0x3e, 0x27, 0xd0, 0x03, 0xcf, + 0x01, 0x22, 0x08, 0x3f, 0xe6, 0xf7, 0xd3, 0xfe, + 0x03, 0xc7, 0x16, 0xa3, 0x1a, 0x68, 0x03, 0xcc, + 0x5b, 0x68, 0x08, 0x3f, 0x08, 0x3c, 0x19, 0x40, + 0x10, 0x40, 0x10, 0xa3, 0x1a, 0x68, 0x5b, 0x68, + 0xe6, 0xf7, 0xbb, 0xfe, 0x00, 0x28, 0x08, 0xd0, + 0x0b, 0xa3, 0x1a, 0x68, 0x03, 0xcf, 0x5b, 0x68, + 0x08, 0x3f, 0x19, 0x43, 0x10, 0x43, 0x03, 0xc7, + 0x08, 0x3f, 0x03, 0xcc, 0x01, 0x22, 0x08, 0x3c, + 0xe6, 0xf7, 0xb5, 0xfe, 0x03, 0xc4, 0x08, 0x3c, + 0x01, 0x35, 0xae, 0x42, 0xd7, 0xd8, 0x04, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb5, + 0xff, 0xb0, 0x88, 0xb0, 0x04, 0x1c, 0x77, 0x20, + 0x78, 0x90, 0x70, 0x20, 0x79, 0x90, 0x68, 0x20, + 0x7a, 0x90, 0x60, 0x20, 0x7b, 0x90, 0x58, 0x20, + 0x7c, 0x90, 0x4d, 0x20, 0x7d, 0x90, 0x47, 0x20, + 0x7e, 0x90, 0x3f, 0x20, 0x7f, 0x90, 0x31, 0x20, + 0x80, 0x90, 0x2a, 0x20, 0x81, 0x90, 0x23, 0x20, + 0x82, 0x90, 0x1c, 0x20, 0x83, 0x90, 0x15, 0x20, + 0x84, 0x90, 0x0e, 0x20, 0x85, 0x90, 0x07, 0x20, + 0x86, 0x90, 0x0f, 0x1c, 0x9d, 0xa1, 0x60, 0xc9, + 0x3e, 0xa8, 0xed, 0x09, 0x00, 0xa4, 0x02, 0x60, + 0xc0, 0x9d, 0xa0, 0x05, 0x1c, 0x48, 0xcd, 0x3c, + 0xa9, 0x48, 0xc1, 0x9c, 0xa5, 0x48, 0xcd, 0x69, + 0x46, 0x08, 0x31, 0x48, 0xc1, 0x9c, 0xa5, 0x48, + 0xcd, 0x69, 0x46, 0x48, 0xc1, 0x9c, 0xa5, 0x48, + 0xcd, 0x42, 0xa9, 0x48, 0xc1, 0x05, 0x1c, 0x48, + 0xcd, 0x40, 0xa9, 0x48, 0xc1, 0x9a, 0xa5, 0x48, + 0xcd, 0x69, 0x46, 0x18, 0x31, 0x48, 0xc1, 0x99, + 0xa5, 0x48, 0xcd, 0x69, 0x46, 0x10, 0x31, 0x48, + 0xc1, 0x99, 0xa5, 0x48, 0xcd, 0x46, 0xa9, 0x48, + 0xc1, 0x05, 0x1c, 0x48, 0xcd, 0x44, 0xa9, 0x48, + 0xc1, 0x97, 0xa5, 0x48, 0xcd, 0x69, 0x46, 0x28, + 0x31, 0x48, 0xc1, 0x96, 0xa5, 0x48, 0xcd, 0x69, + 0x46, 0x20, 0x31, 0x48, 0xc1, 0x96, 0xa5, 0x48, + 0xcd, 0x4a, 0xa9, 0x48, 0xc1, 0x05, 0x1c, 0x48, + 0xcd, 0x48, 0xa9, 0x48, 0xc1, 0x94, 0xa5, 0x48, + 0xcd, 0x69, 0x46, 0x38, 0x31, 0x48, 0xc1, 0x93, + 0xa5, 0x48, 0xcd, 0x69, 0x46, 0x30, 0x31, 0x48, + 0xc1, 0x93, 0xa5, 0x48, 0xcd, 0x4e, 0xa9, 0x48, + 0xc1, 0x05, 0x1c, 0x48, 0xcd, 0x4c, 0xa9, 0x48, + 0xc1, 0x91, 0xa5, 0x48, 0xcd, 0x69, 0x46, 0x48, + 0x31, 0x48, 0xc1, 0x90, 0xa5, 0x48, 0xcd, 0x69, + 0x46, 0x40, 0x31, 0x48, 0xc1, 0x90, 0xa5, 0x48, + 0xcd, 0x52, 0xa9, 0x48, 0xc1, 0x05, 0x1c, 0x48, + 0xcd, 0x50, 0xa9, 0x48, 0xc1, 0x8e, 0xa5, 0x48, + 0xcd, 0x69, 0x46, 0x58, 0x31, 0x48, 0xc1, 0x8d, + 0xa5, 0x48, 0xcd, 0x69, 0x46, 0x50, 0x31, 0x48, + 0xc1, 0x8d, 0xa5, 0x48, 0xcd, 0x56, 0xa9, 0x48, + 0xc1, 0x05, 0x1c, 0x48, 0xcd, 0x54, 0xa9, 0x48, + 0xc1, 0x8b, 0xa5, 0x48, 0xcd, 0x69, 0x46, 0x68, + 0x31, 0x48, 0xc1, 0x8a, 0xa5, 0x48, 0xcd, 0x69, + 0x46, 0x60, 0x31, 0x48, 0xc1, 0x8a, 0xa5, 0x48, + 0xcd, 0x5a, 0xa9, 0x48, 0xc1, 0xed, 0x09, 0x00, + 0xa5, 0x02, 0x8a, 0xa1, 0x0e, 0x1c, 0x0c, 0xce, + 0x58, 0xad, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, 0x1d, + 0x06, 0x1c, 0x0c, 0xce, 0x71, 0x35, 0x0c, 0xc5, + 0x6a, 0x46, 0xd5, 0x1d, 0x85, 0xa6, 0x0c, 0xce, + 0x69, 0x35, 0x0c, 0xc5, 0x85, 0xa6, 0x0c, 0xce, + 0x5e, 0xad, 0x0c, 0xc5, 0x85, 0xa6, 0x0c, 0xce, + 0x5c, 0xad, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, 0x1d, + 0x06, 0x1c, 0x0c, 0xce, 0x81, 0x35, 0x0c, 0xc5, + 0x6a, 0x46, 0xd5, 0x1d, 0x81, 0xa6, 0x0c, 0xce, + 0x79, 0x35, 0x0c, 0xc5, 0x0e, 0x1c, 0x0c, 0xce, + 0x62, 0xad, 0x0c, 0xc5, 0x7f, 0xa6, 0x0c, 0xce, + 0x60, 0xad, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, 0x1d, + 0x06, 0x1c, 0x0c, 0xce, 0x91, 0x35, 0x0c, 0xc5, + 0x6a, 0x46, 0xd5, 0x1d, 0x7b, 0xa6, 0x0c, 0xce, + 0x89, 0x35, 0x0c, 0xc5, 0x0e, 0x1c, 0x0c, 0xce, + 0x66, 0xad, 0x0c, 0xc5, 0x79, 0xa6, 0x0c, 0xce, + 0x64, 0xad, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, 0x1d, + 0x06, 0x1c, 0x0c, 0xce, 0xa1, 0x35, 0x0c, 0xc5, + 0x6a, 0x46, 0xd5, 0x1d, 0x75, 0xa6, 0x0c, 0xce, + 0x99, 0x35, 0x0c, 0xc5, 0x0e, 0x1c, 0x0c, 0xce, + 0x6a, 0xad, 0x0c, 0xc5, 0x73, 0xa6, 0x0c, 0xce, + 0x68, 0xad, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, 0x1d, + 0x06, 0x1c, 0x0c, 0xce, 0xb1, 0x35, 0x0c, 0xc5, + 0x6a, 0x46, 0xd5, 0x1d, 0x6f, 0xa6, 0x0c, 0xce, + 0xa9, 0x35, 0x0c, 0xc5, 0x0e, 0x1c, 0x0c, 0xce, + 0x6e, 0xad, 0x0c, 0xc5, 0x6d, 0xa6, 0x0c, 0xce, + 0x6c, 0xad, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, 0x1d, + 0x06, 0x1c, 0x0c, 0xce, 0xc1, 0x35, 0x0c, 0xc5, + 0x6a, 0x46, 0xd5, 0x1d, 0x69, 0xa6, 0x0c, 0xce, + 0xb9, 0x35, 0x0c, 0xc5, 0x0e, 0x1c, 0x0c, 0xce, + 0x72, 0xad, 0x0c, 0xc5, 0x67, 0xa6, 0x0c, 0xce, + 0x70, 0xad, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, 0x1d, + 0xed, 0x09, 0x00, 0xa6, 0x02, 0x06, 0x1c, 0x0c, + 0xce, 0xd1, 0x35, 0x0c, 0xc5, 0x6a, 0x46, 0xd5, + 0x1d, 0x63, 0xa6, 0x0c, 0xce, 0xc9, 0x35, 0x0c, + 0xc5, 0x48, 0xc9, 0x76, 0xad, 0x48, 0xc5, 0x62, + 0xa5, 0x48, 0xcd, 0x74, 0xa9, 0x48, 0xc1, 0x60, + 0xc8, 0x69, 0x46, 0xe8, 0x31, 0x60, 0xc1, 0x60, + 0xa1, 0x68, 0x46, 0xe0, 0x30, 0x60, 0xc9, 0x60, + 0xc0, 0x00, 0x2f, 0x18, 0xd0, 0x10, 0x2f, 0x16, + 0xd8, 0x10, 0x2f, 0x14, 0xd2, 0xfa, 0x00, 0x3d, + 0x01, 0x3c, 0xa8, 0x28, 0x18, 0xc1, 0x1f, 0x09, + 0x39, 0x20, 0x1c, 0xff, 0xf7, 0x1f, 0xfe, 0xb8, + 0x00, 0x78, 0xa9, 0x40, 0x18, 0x40, 0x38, 0xc2, + 0x6b, 0x28, 0x1c, 0x68, 0x44, 0xc1, 0x1f, 0x09, + 0x39, 0x20, 0x1c, 0xff, 0xf7, 0x73, 0xfd, 0x7f, + 0xb0, 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd4, 0x18, 0xd2, 0xab, 0xa0, 0x75, 0xe2, + 0x00, 0x8f, 0xb0, 0x6c, 0xbf, 0x9b, 0x8b, 0x92, + 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, + 0x80, 0xb3, 0x59, 0x76, 0x3d, 0xf6, 0xe3, 0x01, + 0x00, 0xef, 0xef, 0xf6, 0xcf, 0x58, 0xc2, 0x18, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6d, 0x00, + 0x80, 0x3a, 0x6c, 0x6c, 0xf6, 0xbe, 0x01, 0x00, + 0x00, 0x8b, 0x80, 0x19, 0x19, 0x5a, 0x0a, 0x03, + 0xb1, 0x00, 0x00, 0x00, 0x80, 0x57, 0x00, 0x00, + 0x80, 0x69, 0x99, 0xb8, 0x6a, 0x01, 0x00, 0x00, + 0x00, 0xd9, 0x6a, 0x73, 0xd3, 0x7f, 0x46, 0x17, + 0xde, 0x00, 0x00, 0x80, 0x1c, 0x00, 0x00, 0x00, + 0x80, 0x32, 0x06, 0x63, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x47, 0x52, 0x71, 0x55, 0xec, 0x50, 0xda, + 0x91, 0x00, 0x80, 0x48, 0x01, 0x00, 0x00, 0x00, + 0x80, 0x93, 0x2c, 0xed, 0x09, 0x00, 0xa7, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x83, + 0x46, 0x54, 0xc0, 0x6c, 0xaa, 0x52, 0x80, 0x4a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xa0, + 0xf3, 0x79, 0xe2, 0xfc, 0xff, 0xf7, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x80, + 0xec, 0xc7, 0x5b, 0x81, 0xab, 0xa1, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x4d, 0xb0, + 0xd8, 0x11, 0x80, 0xc9, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x0a, 0x01, 0xbb, 0xa4, + 0xf9, 0x24, 0x8e, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x9d, 0x00, 0x00, 0xd7, 0x24, + 0x60, 0xa7, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x6e, 0x00, 0x00, 0x00, 0xb9, 0x26, + 0x9c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x4e, 0x02, 0x00, 0x00, 0x00, 0xe3, 0xd9, + 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x43, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb5, + 0x82, 0xb0, 0x0c, 0x1c, 0xc1, 0x1d, 0xff, 0x31, + 0x7a, 0x31, 0x43, 0x23, 0x1b, 0x01, 0x49, 0x6b, + 0xc7, 0x18, 0x00, 0x29, 0x22, 0xd0, 0x06, 0x33, + 0x01, 0x69, 0xc4, 0x18, 0x01, 0x29, 0x10, 0xd1, + 0x68, 0x46, 0xfd, 0xf7, 0x8a, 0xff, 0x69, 0x46, + 0x06, 0x22, 0x38, 0x1c, 0xd6, 0xf7, 0xcf, 0xf8, + 0x69, 0x46, 0x06, 0x22, 0x20, 0x1c, 0xd6, 0xf7, + 0xca, 0xf8, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xc1, 0x1d, 0x9d, 0x31, 0xed, 0x09, + 0x00, 0xa8, 0x02, 0x38, 0x1c, 0x06, 0x22, 0x0d, + 0x1c, 0xd6, 0xf7, 0xbf, 0xf8, 0x06, 0x22, 0x20, + 0x1c, 0x29, 0x1c, 0xd6, 0xf7, 0xba, 0xf8, 0xee, + 0xe7, 0x06, 0x4b, 0x0c, 0x22, 0xc0, 0x18, 0x21, + 0x1c, 0xd6, 0xf7, 0xb3, 0xf8, 0x0c, 0x22, 0x38, + 0x1c, 0x21, 0x1c, 0xd6, 0xf7, 0xae, 0xf8, 0xe2, + 0xe7, 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0xc2, + 0x1d, 0xff, 0x32, 0x3a, 0x32, 0x00, 0x21, 0xd1, + 0x62, 0x00, 0x22, 0xff, 0x30, 0x00, 0x23, 0x75, + 0x30, 0x0e, 0xc0, 0x08, 0xc0, 0x70, 0x47, 0xb0, + 0xb5, 0x04, 0x1c, 0xff, 0x30, 0xc1, 0x30, 0x0d, + 0x1c, 0xc1, 0x68, 0x00, 0x27, 0x00, 0x29, 0x10, + 0xd0, 0x00, 0x21, 0xc1, 0x60, 0xd6, 0xf7, 0x2a, + 0xfc, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x08, + 0xe0, 0xb8, 0x21, 0x01, 0x60, 0xe1, 0x6a, 0x01, + 0x61, 0xc5, 0x60, 0x01, 0x1c, 0x05, 0x20, 0xd6, + 0xf7, 0x8c, 0xfc, 0x38, 0x1c, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x89, 0xb0, 0x07, + 0x1c, 0xff, 0x30, 0x81, 0x30, 0xf9, 0x1d, 0x9d, + 0x31, 0x00, 0x6a, 0x00, 0x24, 0x00, 0x25, 0x00, + 0x28, 0x08, 0x91, 0x03, 0xd0, 0xfd, 0x1d, 0xff, + 0x35, 0x9e, 0x35, 0x20, 0xe0, 0xf8, 0x1d, 0xff, + 0x30, 0x3a, 0x30, 0x07, 0x90, 0xfe, 0x1d, 0xff, + 0x36, 0xc0, 0x6a, 0x6e, 0x36, 0x00, 0x28, 0x01, + 0xd0, 0x35, 0x1c, 0x14, 0xe0, 0x08, 0x99, 0x08, + 0x68, 0x49, 0x68, 0x01, 0xf0, 0x7c, 0xf9, 0x00, + 0x28, 0x0d, 0xd0, 0xc1, 0x6a, 0x00, 0x29, 0x0a, + 0xd0, 0xc1, 0x1d, 0x29, 0x31, 0x0c, 0xc9, 0x30, + 0x1c, 0x0c, 0xc0, 0x0c, 0xc9, 0x0c, 0xc0, 0x07, + 0x99, 0x01, 0x20, 0xc8, 0x62, 0x35, 0x1c, 0x00, + 0x2d, 0x25, 0xd0, 0x01, 0xa8, 0xfd, 0xf7, 0xff, + 0xfe, 0x02, 0x9a, 0x0a, 0x99, 0x00, 0x92, 0x2a, + 0x1c, 0xed, 0x09, 0x00, 0xa9, 0x02, 0x01, 0x9b, + 0x03, 0xa8, 0xff, 0xf7, 0xa1, 0xfa, 0x04, 0x21, + 0x09, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x00, 0x91, + 0x03, 0xaa, 0x01, 0x92, 0x42, 0x6b, 0x0c, 0x21, + 0x01, 0x23, 0x38, 0x1c, 0x07, 0xf0, 0x89, 0xfa, + 0x04, 0x1c, 0x27, 0xd1, 0x00, 0x22, 0x2a, 0x21, + 0x38, 0x1c, 0x02, 0xf0, 0x15, 0xfc, 0x00, 0x28, + 0x20, 0xd1, 0x38, 0x1c, 0x04, 0xa9, 0xff, 0xf7, + 0x3f, 0xff, 0x1b, 0xe0, 0x10, 0x4b, 0x0a, 0x99, + 0xf8, 0x18, 0x10, 0x22, 0xd6, 0xf7, 0x20, 0xf8, + 0xd6, 0xf7, 0xb7, 0xfb, 0x05, 0x1c, 0x11, 0xd0, + 0x00, 0x22, 0x18, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0xff, 0xfb, 0x00, 0x28, 0x0a, 0xd1, 0xcd, 0x20, + 0x28, 0x60, 0x08, 0x99, 0xe8, 0x1d, 0x88, 0xc9, + 0x05, 0x30, 0x88, 0xc0, 0x05, 0x20, 0x29, 0x1c, + 0xd6, 0xf7, 0x12, 0xfc, 0x20, 0x1c, 0x0b, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x04, 0x04, 0x00, 0x00, 0xb0, 0xb5, 0x82, 0xb0, + 0x07, 0x1c, 0x80, 0x6a, 0x1c, 0x1c, 0x00, 0x28, + 0x04, 0xd0, 0x01, 0x20, 0xf9, 0x1d, 0xb9, 0x31, + 0x48, 0x62, 0x12, 0xe0, 0x0b, 0x4b, 0x10, 0x20, + 0xf9, 0x18, 0x0d, 0x1c, 0xba, 0x61, 0xfe, 0xf7, + 0xed, 0xfb, 0x10, 0x21, 0x00, 0x91, 0x0b, 0x21, + 0x01, 0x23, 0x38, 0x1c, 0x22, 0x1c, 0x01, 0x95, + 0x07, 0xf0, 0x3b, 0xfa, 0x38, 0x1c, 0x01, 0xf0, + 0x17, 0xf8, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x04, 0x04, 0x00, 0x00, + 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0x07, 0xf0, + 0x14, 0xf8, 0x09, 0x23, 0x9b, 0x01, 0xf9, 0x18, + 0x48, 0x63, 0x03, 0x1c, 0x38, 0x1c, 0x21, 0x22, + 0x21, 0x1c, 0xff, 0xf7, 0xcb, 0xff, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x09, 0x23, + 0x9b, 0x01, 0xc2, 0x18, 0xed, 0x09, 0x00, 0xaa, + 0x02, 0x53, 0x6b, 0x1e, 0x22, 0xff, 0xf7, 0xc0, + 0xff, 0x08, 0xbc, 0x18, 0x47, 0x88, 0xb5, 0x07, + 0x1c, 0xff, 0x30, 0x41, 0x30, 0xc0, 0x6a, 0x00, + 0x28, 0x0f, 0xd0, 0x00, 0x23, 0x21, 0x22, 0x38, + 0x1c, 0xff, 0xf7, 0xb2, 0xff, 0xb8, 0x6a, 0x00, + 0x28, 0x07, 0xd1, 0x06, 0xa2, 0x00, 0x92, 0x0b, + 0x22, 0x23, 0x23, 0x01, 0x21, 0x38, 0x1c, 0x07, + 0xf0, 0x82, 0xfa, 0x88, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x41, + 0x75, 0x74, 0x68, 0x53, 0x75, 0x62, 0x53, 0x74, + 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x4c, 0x69, 0x6e, + 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x4f, 0x6b, 0x00, 0x00, 0x00, 0xb5, 0xfd, + 0x23, 0x9b, 0x00, 0xc1, 0x18, 0x02, 0xa2, 0x03, + 0xf0, 0x25, 0xfe, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x4c, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x53, + 0x75, 0x62, 0x53, 0x74, 0x49, 0x6e, 0x69, 0x74, + 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, + 0x69, 0x6e, 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x00, 0x00, 0x00, 0x08, 0xb5, 0x09, + 0x23, 0x9b, 0x01, 0xc1, 0x18, 0x05, 0xa2, 0x00, + 0x92, 0x05, 0x23, 0x09, 0x22, 0x09, 0x6b, 0x07, + 0xf0, 0x3a, 0xfa, 0x01, 0xb0, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x41, + 0x75, 0x74, 0x68, 0x53, 0x75, 0x62, 0x53, 0x74, + 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6c, 0x6c, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x4b, + 0x65, 0x79, 0x49, 0x6e, 0x64, 0x53, 0x52, 0xed, + 0x09, 0x00, 0xab, 0x02, 0x65, 0x73, 0x46, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x00, 0x90, 0xb5, + 0x04, 0x1c, 0xd6, 0xf7, 0xd7, 0xfa, 0x07, 0x1c, + 0x12, 0xd0, 0x20, 0x1c, 0x06, 0xf0, 0x76, 0xff, + 0x09, 0x23, 0x9b, 0x01, 0xe1, 0x18, 0x48, 0x63, + 0xcd, 0x20, 0x38, 0x60, 0xe1, 0x1d, 0x9d, 0x31, + 0x18, 0xc9, 0xf8, 0x1d, 0x05, 0x30, 0x18, 0xc0, + 0x05, 0x20, 0x39, 0x1c, 0xd6, 0xf7, 0x31, 0xfb, + 0x90, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0xc9, 0x69, 0x09, 0x78, 0xc9, 0x07, 0xc9, 0x0f, + 0xff, 0x30, 0xff, 0x30, 0x42, 0x30, 0x41, 0x63, + 0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x07, 0x1c, + 0xc8, 0x69, 0x01, 0x78, 0xcc, 0x07, 0xe4, 0x0f, + 0xfd, 0x23, 0x9b, 0x00, 0x41, 0x1c, 0xf8, 0x18, + 0x10, 0x22, 0xd5, 0xf7, 0x0e, 0xff, 0x09, 0x23, + 0x9b, 0x01, 0xf8, 0x18, 0x04, 0x63, 0x00, 0x22, + 0x1f, 0x21, 0x38, 0x1c, 0x02, 0xf0, 0xed, 0xfa, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0xc4, 0x1d, 0xff, 0x34, 0x0c, 0xc9, 0x6e, 0x34, + 0x0c, 0xc4, 0x0c, 0xc9, 0x0c, 0xc4, 0xc2, 0x1d, + 0xff, 0x32, 0x3a, 0x32, 0x01, 0x21, 0xd1, 0x62, + 0x00, 0x22, 0x00, 0x27, 0x27, 0x21, 0x02, 0xf0, + 0xd8, 0xfa, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x80, 0xb5, 0x00, 0x27, 0x04, 0xf0, + 0xaa, 0xfd, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf0, 0xb5, 0x87, 0xb0, 0x0d, 0x1c, + 0xc1, 0x1d, 0x07, 0x1c, 0x28, 0x1c, 0x4d, 0xc8, + 0xff, 0x31, 0x6e, 0x31, 0x4d, 0xc1, 0xf8, 0x1d, + 0xff, 0x30, 0x3a, 0x30, 0x01, 0x26, 0xc6, 0x62, + 0x38, 0x69, 0x00, 0x24, 0x01, 0x28, 0x05, 0xd1, + 0x00, 0x22, 0x27, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0xb4, 0xfa, 0x24, 0xe0, 0x01, 0xa8, 0xfd, 0xf7, + 0x7e, 0xfd, 0xed, 0x09, 0x00, 0xac, 0x02, 0x13, + 0x4b, 0x02, 0x9a, 0xf9, 0x18, 0x00, 0x92, 0x2a, + 0x1c, 0x01, 0x9b, 0x03, 0xa8, 0xff, 0xf7, 0x1f, + 0xf9, 0x04, 0x21, 0x03, 0xaa, 0x01, 0x92, 0x00, + 0x91, 0x0c, 0x21, 0x00, 0x22, 0x01, 0x23, 0x38, + 0x1c, 0x07, 0xf0, 0x0a, 0xf9, 0x04, 0x1c, 0x03, + 0xd1, 0x38, 0x1c, 0x04, 0xa9, 0xff, 0xf7, 0xc7, + 0xfd, 0x09, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x46, + 0x63, 0x00, 0x22, 0x2a, 0x21, 0x38, 0x1c, 0x02, + 0xf0, 0x8e, 0xfa, 0x20, 0x1c, 0x07, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x98, 0xb5, 0x07, 0x1c, 0x06, + 0xf0, 0xdf, 0xfe, 0x07, 0xa2, 0x00, 0x92, 0x0b, + 0x22, 0x01, 0x1c, 0x06, 0x23, 0x38, 0x1c, 0x07, + 0xf0, 0x6b, 0xf9, 0x04, 0x1c, 0x38, 0x1c, 0x04, + 0xf0, 0x50, 0xfd, 0x20, 0x1c, 0x98, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x41, 0x75, 0x74, + 0x68, 0x53, 0x75, 0x62, 0x53, 0x74, 0x43, 0x6f, + 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x41, + 0x6e, 0x73, 0x77, 0x65, 0x72, 0x4b, 0x65, 0x79, + 0x52, 0x65, 0x71, 0x4c, 0x69, 0x6e, 0x6b, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x45, + 0x72, 0x72, 0x00, 0x90, 0xb5, 0x87, 0xb0, 0x07, + 0x1c, 0x0c, 0x1c, 0x0c, 0xc9, 0xff, 0x30, 0x75, + 0x30, 0x0c, 0xc0, 0x0c, 0xc9, 0x0c, 0xc0, 0xf9, + 0x1d, 0xff, 0x31, 0x01, 0x20, 0x3a, 0x31, 0xc8, + 0x62, 0x01, 0xa8, 0xfd, 0xf7, 0x16, 0xfd, 0x10, + 0x4b, 0x02, 0x9a, 0xf9, 0x18, 0x00, 0x92, 0x22, + 0x1c, 0x01, 0x9b, 0x03, 0xa8, 0xff, 0xf7, 0xb7, + 0xf8, 0x04, 0x21, 0x09, 0x23, 0x9b, 0x01, 0xf8, + 0x18, 0x00, 0x91, 0x03, 0xaa, 0x01, 0x92, 0x42, + 0x6b, 0x0c, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x07, + 0xf0, 0x9f, 0xf8, 0x04, 0x1c, 0xed, 0x09, 0x00, + 0xad, 0x02, 0x03, 0xd1, 0x38, 0x1c, 0x04, 0xa9, + 0xff, 0xf7, 0x5c, 0xfd, 0x20, 0x1c, 0x07, 0xb0, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x04, 0x04, 0x00, 0x00, 0x08, 0xb5, 0x09, 0x23, + 0x9b, 0x01, 0xc1, 0x18, 0x04, 0xa2, 0x00, 0x92, + 0x06, 0x23, 0x0b, 0x22, 0x49, 0x6b, 0x07, 0xf0, + 0x0a, 0xf9, 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x53, 0x75, + 0x62, 0x53, 0x74, 0x52, 0x65, 0x73, 0x70, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x4c, 0x69, 0x6e, + 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x45, 0x72, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb5, 0xc9, 0x69, 0x01, 0x31, 0xff, 0xf7, + 0x95, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x0c, 0x1c, 0x0a, 0xa1, 0x07, 0x1c, 0xff, 0xf7, + 0x63, 0xfd, 0x38, 0x1c, 0x21, 0x1c, 0xff, 0xf7, + 0x43, 0xf9, 0x23, 0x2c, 0x06, 0xd1, 0x78, 0x69, + 0x0e, 0x28, 0x03, 0xd1, 0x38, 0x1c, 0x21, 0x1c, + 0xff, 0xf7, 0x62, 0xfd, 0x90, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x4c, 0x6d, 0x41, 0x75, + 0x74, 0x68, 0x53, 0x75, 0x62, 0x53, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x52, 0x65, 0x71, 0x49, 0x6e, + 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x41, + 0x75, 0x52, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xb5, 0xc9, 0x69, + 0x05, 0x4b, 0x01, 0x31, 0xc0, 0x18, 0x00, 0x27, + 0x10, 0x22, 0xd5, 0xf7, 0xdf, 0xfd, 0x38, 0x1c, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x04, 0x04, 0x00, 0x00, 0x98, 0xb5, 0x00, 0x24, + 0x07, 0x1c, 0xc8, 0x69, 0x01, 0x78, 0x3a, 0x69, + 0xc9, 0x07, 0xc9, 0x0f, 0x01, 0x2a, 0x08, 0xd1, + 0x0b, 0xa2, 0x00, 0x92, 0x0b, 0x22, 0x23, 0x23, + 0xed, 0x09, 0x00, 0xae, 0x02, 0x38, 0x1c, 0x07, + 0xf0, 0xa0, 0xf8, 0x04, 0x1c, 0x0a, 0xe0, 0x0e, + 0x4b, 0x41, 0x1c, 0xf8, 0x18, 0x10, 0x22, 0xd5, + 0xf7, 0xbf, 0xfd, 0x00, 0x22, 0x2f, 0x21, 0x38, + 0x1c, 0x02, 0xf0, 0xa2, 0xf9, 0x20, 0x1c, 0x98, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x41, + 0x75, 0x74, 0x68, 0x53, 0x75, 0x62, 0x53, 0x74, + 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x52, + 0x65, 0x71, 0x53, 0x52, 0x65, 0x73, 0x00, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0xb5, 0x00, + 0x22, 0x67, 0x21, 0x02, 0xf0, 0xc5, 0xf9, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x02, 0xa1, 0xff, + 0xf7, 0xf1, 0xfc, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x4c, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x53, + 0x75, 0x62, 0x53, 0x74, 0x49, 0x6e, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x49, 0x6e, 0x64, 0x41, 0x6e, + 0x73, 0x77, 0x65, 0x72, 0x41, 0x75, 0x52, 0x61, + 0x6e, 0x64, 0x45, 0x72, 0x72, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xb5, 0x07, 0x1c, 0xc8, 0x69, 0x00, + 0x78, 0xc5, 0x07, 0xed, 0x0f, 0x0c, 0x1c, 0x38, + 0x1c, 0x29, 0x1c, 0x03, 0xf0, 0x75, 0xfb, 0x00, + 0x28, 0x0b, 0xd1, 0x09, 0x23, 0x9b, 0x01, 0xf8, + 0x18, 0x05, 0x63, 0xe0, 0x69, 0xfd, 0x23, 0x9b, + 0x00, 0x41, 0x1c, 0xf8, 0x18, 0x10, 0x22, 0xd5, + 0xf7, 0x6b, 0xfd, 0xb0, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0x40, + 0x69, 0x0e, 0x28, 0x03, 0xd1, 0x22, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0xc0, 0xfc, 0x38, 0x1c, 0x03, + 0xa1, 0xff, 0xf7, 0xb0, 0xfc, 0x80, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x4c, 0x6d, 0x41, + 0x75, 0x74, 0x68, 0x53, 0x75, 0x62, 0x53, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x54, 0x69, 0x6d, 0xed, 0x09, 0x00, 0xaf, 0x02, + 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x90, 0xb5, + 0x07, 0x1c, 0xc8, 0x69, 0x01, 0x78, 0xcc, 0x07, + 0xe4, 0x0f, 0xfd, 0x23, 0x9b, 0x00, 0x41, 0x1c, + 0xf8, 0x18, 0x10, 0x22, 0xd5, 0xf7, 0x3b, 0xfd, + 0x09, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x04, 0x63, + 0x00, 0x22, 0x1f, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0x1a, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xff, 0x30, 0xff, 0x30, 0x42, 0x30, 0x81, 0x63, + 0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x87, 0xb0, + 0x07, 0x1c, 0x01, 0xa8, 0xfd, 0xf7, 0xd9, 0xfb, + 0x02, 0x9a, 0x11, 0x4b, 0x00, 0x92, 0xfa, 0x1d, + 0xff, 0x32, 0x6e, 0x32, 0xf9, 0x18, 0x01, 0x9b, + 0x03, 0xa8, 0xfe, 0xf7, 0x78, 0xff, 0x04, 0x21, + 0x03, 0xaa, 0x01, 0x92, 0x00, 0x91, 0x0c, 0x21, + 0x00, 0x22, 0x01, 0x23, 0x38, 0x1c, 0x06, 0xf0, + 0x63, 0xff, 0x04, 0x1c, 0x03, 0xd1, 0x38, 0x1c, + 0x04, 0xa9, 0xff, 0xf7, 0x20, 0xfc, 0x00, 0x22, + 0x27, 0x21, 0x38, 0x1c, 0x02, 0xf0, 0xeb, 0xf8, + 0x20, 0x1c, 0x07, 0xb0, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x04, 0x04, 0x00, 0x00, 0x90, 0xb5, + 0x87, 0xb0, 0x07, 0x1c, 0x01, 0xa8, 0x0c, 0x1c, + 0xfd, 0xf7, 0xab, 0xfb, 0x02, 0x9a, 0x00, 0x92, + 0xe0, 0x69, 0xfa, 0x1d, 0x41, 0x1c, 0xff, 0x32, + 0x6e, 0x32, 0x03, 0xa8, 0x01, 0x9b, 0xfe, 0xf7, + 0x4a, 0xff, 0x04, 0x21, 0x03, 0xaa, 0x01, 0x92, + 0x00, 0x91, 0xe0, 0x69, 0x00, 0x78, 0xc2, 0x07, + 0xd2, 0x0f, 0x01, 0x23, 0x0c, 0x21, 0x38, 0x1c, + 0x06, 0xf0, 0x32, 0xff, 0x04, 0x1c, 0x03, 0xd1, + 0x38, 0x1c, 0x04, 0xa9, 0xff, 0xf7, 0xef, 0xfb, + 0x00, 0x22, 0x27, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0xba, 0xf8, 0x20, 0x1c, 0x07, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xed, 0x09, + 0x00, 0xb0, 0x02, 0x42, 0x69, 0x0e, 0x2a, 0x01, + 0xd1, 0xff, 0xf7, 0x29, 0xfc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x90, 0xb5, 0x0c, 0x1c, 0x1f, + 0x21, 0x07, 0x1c, 0xfe, 0xf7, 0xf8, 0xff, 0x38, + 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0xed, 0xff, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, + 0xf7, 0xe7, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, + 0xb5, 0x0c, 0x1c, 0x1f, 0x21, 0x07, 0x1c, 0xfe, + 0xf7, 0xe6, 0xff, 0x38, 0x1c, 0x21, 0x1c, 0xff, + 0xf7, 0xf1, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0x21, 0xff, 0xf7, 0x03, + 0xfc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0xb5, 0x00, 0x21, 0xff, 0xf7, 0xfc, 0xfb, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x90, 0xb5, 0x0c, + 0x1c, 0x68, 0x21, 0x00, 0x22, 0x07, 0x1c, 0x02, + 0xf0, 0x78, 0xf8, 0x38, 0x1c, 0x21, 0x1c, 0xff, + 0xf7, 0xee, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xe7, + 0xfb, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0xb5, 0xff, 0xf7, 0xe1, 0xfb, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xdb, + 0xfb, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0xb5, 0x00, 0xf0, 0x8f, 0xfc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0xb0, 0xb5, 0x07, 0x1c, 0x00, + 0x24, 0x0d, 0x1c, 0xfd, 0x23, 0xc8, 0x69, 0x9b, + 0x00, 0x41, 0x1c, 0xf8, 0x18, 0x10, 0x22, 0xd5, + 0xf7, 0x64, 0xfc, 0xe8, 0x69, 0x00, 0x78, 0xc0, + 0x07, 0xc0, 0x0f, 0x09, 0x23, 0x9b, 0x01, 0xf9, + 0x18, 0x08, 0x63, 0xf9, 0x1d, 0xff, 0x31, 0xba, + 0x31, 0x02, 0x20, 0x48, 0x63, 0x20, 0x1c, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x07, + 0x1c, 0x15, 0x48, 0x00, 0x24, 0x81, 0x6a, 0xf8, + 0x1d, 0xed, 0x09, 0x00, 0xb1, 0x02, 0xb9, 0x30, + 0x00, 0x29, 0x05, 0xd0, 0x82, 0x6b, 0x00, 0x2a, + 0x02, 0xd0, 0xc2, 0x6b, 0xd2, 0x08, 0x16, 0xd2, + 0x00, 0x29, 0x00, 0xd0, 0x80, 0x6b, 0x38, 0x1c, + 0x06, 0xf0, 0x7b, 0xfc, 0x02, 0x1c, 0x00, 0x23, + 0x31, 0x21, 0x38, 0x1c, 0x06, 0xf0, 0x8d, 0xfe, + 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0x57, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x38, 0x1c, + 0x00, 0xf0, 0x62, 0xfc, 0x02, 0xe0, 0x38, 0x1c, + 0x04, 0xf0, 0xcc, 0xfe, 0x20, 0x1c, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf8, 0xad, 0x03, 0x20, + 0x00, 0xb5, 0x01, 0x1c, 0x8a, 0x69, 0x00, 0x20, + 0x00, 0x2a, 0x03, 0xd1, 0x08, 0x1c, 0x2c, 0x21, + 0x02, 0xf0, 0x3e, 0xf8, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x02, 0xa1, 0x01, 0xf0, 0x91, 0xfa, + 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x41, 0x75, + 0x74, 0x68, 0x53, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x00, 0x90, 0xb5, 0x0c, 0x1c, + 0x07, 0x1c, 0x00, 0xf0, 0x57, 0xff, 0x38, 0x1c, + 0x00, 0xf0, 0x1a, 0xfc, 0xf8, 0x1d, 0x79, 0x30, + 0x04, 0x63, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0x1d, + 0xa9, 0x33, 0x03, 0xa2, 0x01, 0xf0, 0x84, 0xfb, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x4c, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x53, 0x74, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x00, 0x00, 0x90, 0xb5, 0x0c, 0x1c, + 0x07, 0x1c, 0x00, 0xf0, 0x7d, 0xff, 0xf8, 0x1d, + 0x79, 0x30, 0x04, 0x63, 0x38, 0x1c, 0x00, 0xf0, + 0xf7, 0xfb, 0x55, 0x21, 0x38, 0x1c, 0x22, 0x1c, + 0x01, 0xf0, 0xbe, 0xff, 0x90, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x90, 0xb5, 0x0c, 0x1c, + 0x07, 0x1c, 0x00, 0xf0, 0xed, 0x09, 0x00, 0xb2, + 0x02, 0x69, 0xff, 0x9a, 0x21, 0x38, 0x1c, 0x22, + 0x1c, 0x01, 0xf0, 0xb0, 0xff, 0x38, 0x1c, 0x21, + 0x1c, 0x02, 0xa2, 0x01, 0xf0, 0x1f, 0xfd, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x41, + 0x75, 0x74, 0x68, 0x53, 0x74, 0x42, 0x42, 0x44, + 0x65, 0x74, 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xb5, 0x07, 0x1c, 0xc8, 0x69, 0x0c, + 0x1c, 0x08, 0x4b, 0x41, 0x1c, 0xf8, 0x18, 0x10, + 0x22, 0xd5, 0xf7, 0xac, 0xfb, 0xe0, 0x69, 0x00, + 0x78, 0xc0, 0x07, 0xc0, 0x0f, 0x09, 0x23, 0x9b, + 0x01, 0xf9, 0x18, 0x48, 0x63, 0x90, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x04, 0x04, 0x00, + 0x00, 0x80, 0xb5, 0x07, 0x1c, 0x00, 0x29, 0x0e, + 0xd0, 0x00, 0x22, 0x28, 0x21, 0x38, 0x1c, 0x01, + 0xf0, 0xb9, 0xff, 0x00, 0x28, 0x04, 0xd1, 0x00, + 0x22, 0x28, 0x21, 0x38, 0x1c, 0x01, 0xf0, 0x76, + 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x22, 0x18, 0x21, 0x38, 0x1c, 0x01, 0xf0, 0xaa, + 0xff, 0x00, 0x28, 0xf5, 0xd1, 0x00, 0x22, 0x18, + 0x21, 0x38, 0x1c, 0x01, 0xf0, 0x67, 0xff, 0xef, + 0xe7, 0x90, 0xb5, 0x82, 0xb0, 0x0c, 0x4b, 0x07, + 0x1c, 0xc1, 0x18, 0x10, 0x20, 0x0c, 0x1c, 0xfd, + 0xf7, 0x73, 0xff, 0x10, 0x21, 0x09, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0x00, 0x91, 0x01, 0x94, 0x42, + 0x6b, 0x0b, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x06, + 0xf0, 0xbe, 0xfd, 0x38, 0x1c, 0x00, 0xf0, 0x9a, + 0xfb, 0x02, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x04, 0x04, 0x00, 0x00, 0x80, 0xb5, 0x00, + 0x27, 0x00, 0x29, 0x0a, 0xd1, 0xc1, 0x1d, 0xb9, + 0x31, 0x4a, 0x6a, 0x00, 0x2a, 0x10, 0xd0, 0x00, + 0x22, 0x4a, 0x62, 0x27, 0x21, 0x01, 0xf0, 0x3a, + 0xff, 0x0a, 0xe0, 0xc2, 0x1d, 0xff, 0x32, 0xed, + 0x09, 0x00, 0xb3, 0x02, 0xba, 0x32, 0xd3, 0x68, + 0x00, 0x2b, 0x02, 0xd1, 0x92, 0x68, 0x00, 0x2a, + 0x01, 0xd0, 0x03, 0xf0, 0x83, 0xf8, 0x38, 0x1c, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x43, 0x68, + 0x00, 0x22, 0x00, 0x2b, 0x03, 0xd0, 0x19, 0x60, + 0x43, 0x68, 0x4b, 0x60, 0x01, 0xe0, 0x01, 0x60, + 0x4a, 0x60, 0x0a, 0x60, 0x41, 0x60, 0x81, 0x68, + 0x01, 0x31, 0x81, 0x60, 0x70, 0x47, 0x0a, 0x68, + 0x00, 0x2a, 0x02, 0xd0, 0x4b, 0x68, 0x53, 0x60, + 0x01, 0xe0, 0x4a, 0x68, 0x42, 0x60, 0x4a, 0x68, + 0x00, 0x2a, 0x02, 0xd0, 0x09, 0x68, 0x11, 0x60, + 0x01, 0xe0, 0x09, 0x68, 0x01, 0x60, 0x81, 0x68, + 0x00, 0x29, 0x01, 0xd0, 0x01, 0x39, 0x81, 0x60, + 0x70, 0x47, 0x0f, 0xb4, 0xf0, 0xb5, 0x84, 0xb0, + 0x00, 0x27, 0x16, 0x1c, 0x09, 0x98, 0x0a, 0x99, + 0x10, 0x9d, 0x00, 0xf0, 0x30, 0xfc, 0x04, 0x1c, + 0x12, 0xd1, 0x01, 0x21, 0x2a, 0x1c, 0x02, 0x2e, + 0x00, 0xd0, 0x00, 0x21, 0x03, 0x92, 0x0e, 0x9a, + 0x0f, 0x98, 0x02, 0x91, 0x00, 0x92, 0x01, 0x90, + 0x09, 0x98, 0x0c, 0x9a, 0x0a, 0x99, 0x0d, 0x9b, + 0x00, 0xf0, 0x3d, 0xfc, 0x04, 0x1c, 0x58, 0xd0, + 0x29, 0x1c, 0x2e, 0x48, 0xfd, 0xf7, 0x19, 0xf9, + 0x07, 0x1c, 0x52, 0xd0, 0x09, 0xa9, 0x28, 0xc9, + 0xf8, 0x1d, 0x9d, 0x30, 0x28, 0xc0, 0x09, 0x23, + 0xdb, 0x01, 0xf9, 0x18, 0x29, 0x48, 0x05, 0x23, + 0x3e, 0x61, 0x28, 0x4a, 0x88, 0x63, 0x1b, 0x02, + 0xd0, 0x18, 0xc1, 0x6b, 0x4b, 0x1c, 0xc3, 0x63, + 0xb9, 0x60, 0xf8, 0x1d, 0xb9, 0x30, 0x00, 0x21, + 0x7d, 0x23, 0x1b, 0x02, 0x41, 0x60, 0x81, 0x60, + 0x03, 0x60, 0x01, 0x26, 0x0b, 0x23, 0x9b, 0x01, + 0xfd, 0x18, 0xae, 0x60, 0x01, 0x26, 0x6e, 0x60, + 0x05, 0x23, 0xdb, 0x01, 0x1d, 0x4e, 0xfb, 0x18, + 0x29, 0x60, 0xed, 0x09, 0x00, 0xb4, 0x02, 0xde, + 0x63, 0x9e, 0x63, 0xfb, 0x1d, 0xff, 0x33, 0x3a, + 0x33, 0x99, 0x60, 0x19, 0x49, 0x19, 0x61, 0x31, + 0x07, 0xd9, 0x60, 0x28, 0x21, 0xe9, 0x61, 0x77, + 0x21, 0xc9, 0x43, 0x19, 0x62, 0x59, 0x62, 0xf9, + 0x1d, 0xff, 0x31, 0xfa, 0x31, 0x14, 0x4b, 0x01, + 0x26, 0x0e, 0x61, 0xcb, 0x60, 0x86, 0x61, 0xa0, + 0x69, 0x00, 0x28, 0x01, 0xd1, 0xa7, 0x61, 0xfc, + 0x60, 0x00, 0x20, 0xc1, 0x00, 0x09, 0x18, 0x89, + 0x00, 0xc9, 0x19, 0x48, 0x63, 0x01, 0x30, 0x03, + 0x28, 0xf7, 0xd3, 0x53, 0x23, 0x1b, 0x01, 0xd0, + 0x18, 0x39, 0x1c, 0xff, 0xf7, 0x62, 0xff, 0x38, + 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x04, + 0xb0, 0x18, 0x47, 0xbc, 0x04, 0x00, 0x00, 0x19, + 0x64, 0x03, 0x11, 0xb8, 0xa8, 0x03, 0x20, 0x18, + 0xcc, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0x00, 0x00, 0xf0, 0xb5, 0x07, 0x1c, 0x0c, + 0x1c, 0x39, 0x1c, 0x13, 0x48, 0xff, 0xf7, 0x59, + 0xff, 0x38, 0x1c, 0x06, 0xf0, 0x98, 0xfa, 0x00, + 0x28, 0x06, 0xd0, 0xfd, 0xf7, 0xde, 0xfa, 0x38, + 0x1c, 0x06, 0xf0, 0x91, 0xfa, 0x00, 0x28, 0xf8, + 0xd1, 0xf8, 0x68, 0x00, 0x25, 0x00, 0x28, 0x09, + 0xd0, 0xc6, 0x1d, 0x09, 0x36, 0xd9, 0xf7, 0x43, + 0xf8, 0x03, 0xc6, 0xf8, 0x68, 0x81, 0x69, 0x00, + 0x29, 0x00, 0xd0, 0x85, 0x61, 0x09, 0x23, 0xdb, + 0x01, 0xf8, 0x18, 0x85, 0x63, 0x38, 0x1c, 0x21, + 0x1c, 0xfd, 0xf7, 0x8f, 0xf8, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xe8, 0xad, 0x03, 0x20, 0x80, + 0xb5, 0x06, 0x48, 0x00, 0x6b, 0x00, 0x28, 0x05, + 0xd0, 0x07, 0x68, 0x04, 0xa1, 0xff, 0xf7, 0xc9, + 0xff, 0x38, 0x1c, 0xf9, 0xd1, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb8, 0xad, 0x03, 0x20, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0xed, 0x09, 0x00, + 0xb5, 0x02, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, + 0x63, 0x3a, 0x20, 0x34, 0x30, 0x36, 0x00, 0x00, + 0xf7, 0xb5, 0x07, 0x1c, 0xff, 0x30, 0x01, 0x30, + 0x40, 0x68, 0x0d, 0x1c, 0x00, 0x28, 0x02, 0xd0, + 0x27, 0xa1, 0xfd, 0xf7, 0xef, 0xff, 0x38, 0x1c, + 0x00, 0xf0, 0x92, 0xfd, 0x38, 0x1c, 0x00, 0xf0, + 0x55, 0xfa, 0x38, 0x1c, 0x00, 0xf0, 0xd6, 0xfa, + 0x38, 0x1c, 0x08, 0xf0, 0x0b, 0xfd, 0x38, 0x1c, + 0x06, 0xf0, 0x4c, 0xfa, 0x00, 0x2d, 0x37, 0xd0, + 0xf9, 0x1d, 0x9d, 0x31, 0x08, 0x68, 0x49, 0x68, + 0x00, 0xf0, 0x46, 0xfb, 0x04, 0x1c, 0x02, 0x2d, + 0x1e, 0xd1, 0xd5, 0xf7, 0xbc, 0xfd, 0x05, 0x1c, + 0x1a, 0xd0, 0x58, 0x20, 0x28, 0x60, 0x38, 0x6b, + 0xfe, 0x1d, 0xe8, 0x60, 0xb1, 0x36, 0x03, 0xce, + 0x18, 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0x08, 0x3e, + 0xd5, 0xf7, 0x3c, 0xfb, 0x00, 0x28, 0x03, 0xd0, + 0xd8, 0xf7, 0xdc, 0xff, 0x03, 0xc6, 0x08, 0x3e, + 0x0c, 0xce, 0xe8, 0x1d, 0x09, 0x30, 0x0c, 0xc0, + 0x07, 0x20, 0x29, 0x1c, 0xd5, 0xf7, 0x0e, 0xfe, + 0x02, 0x99, 0x38, 0x1c, 0xff, 0xf7, 0x70, 0xff, + 0x00, 0x2c, 0x09, 0xd0, 0x20, 0x6c, 0x00, 0x28, + 0x02, 0xd0, 0x00, 0x20, 0xe0, 0x62, 0x20, 0x64, + 0x02, 0x99, 0x20, 0x1c, 0x00, 0xf0, 0x74, 0xfb, + 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x34, + 0x31, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0xb5, 0x12, 0x48, + 0x00, 0x6b, 0x00, 0x28, 0x1c, 0xd0, 0x00, 0x99, + 0x0a, 0x02, 0x12, 0x0a, 0x09, 0x0e, 0xc3, 0x1d, + 0x79, 0x33, 0x5b, 0x6a, 0x1f, 0x02, 0x3f, 0x0a, + 0x97, 0x42, 0x0e, 0xd1, 0x1b, 0x0e, 0x8b, 0x42, + 0xed, 0x09, 0x00, 0xb6, 0x02, 0x0b, 0xd1, 0xc3, + 0x1d, 0x99, 0x33, 0x1b, 0x89, 0x01, 0xaf, 0x3f, + 0x88, 0xbb, 0x42, 0x04, 0xd1, 0x43, 0x69, 0x00, + 0x2b, 0x01, 0xd0, 0x02, 0x2b, 0x02, 0xd1, 0x00, + 0x68, 0x00, 0x28, 0xe6, 0xd1, 0x02, 0xb0, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb8, 0xad, 0x03, + 0x20, 0x83, 0xb5, 0x10, 0x48, 0x00, 0x6b, 0x00, + 0x28, 0x17, 0xd0, 0x00, 0x99, 0x0b, 0x02, 0x1b, + 0x0a, 0x0a, 0x0e, 0xc1, 0x1d, 0x79, 0x31, 0x49, + 0x6a, 0x0f, 0x02, 0x3f, 0x0a, 0x9f, 0x42, 0x09, + 0xd1, 0x09, 0x0e, 0x91, 0x42, 0x06, 0xd1, 0xc1, + 0x1d, 0x99, 0x31, 0x09, 0x89, 0x01, 0xaf, 0x3f, + 0x88, 0xb9, 0x42, 0x02, 0xd0, 0x00, 0x68, 0x00, + 0x28, 0xeb, 0xd1, 0x02, 0xb0, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xb8, 0xad, 0x03, + 0x20, 0x05, 0x49, 0x09, 0x6b, 0x00, 0x29, 0x05, + 0xd0, 0x0a, 0x69, 0x82, 0x42, 0x02, 0xd0, 0x09, + 0x68, 0x00, 0x29, 0xf9, 0xd1, 0x08, 0x1c, 0x70, + 0x47, 0xb8, 0xad, 0x03, 0x20, 0x05, 0x49, 0x09, + 0x6b, 0x00, 0x29, 0x05, 0xd0, 0x8a, 0x68, 0x82, + 0x42, 0x02, 0xd0, 0x09, 0x68, 0x00, 0x29, 0xf9, + 0xd1, 0x08, 0x1c, 0x70, 0x47, 0xb8, 0xad, 0x03, + 0x20, 0x83, 0xb5, 0x11, 0x48, 0x00, 0x6b, 0x00, + 0x28, 0x1a, 0xd0, 0x00, 0x99, 0x0b, 0x02, 0x1b, + 0x0a, 0x0a, 0x0e, 0xc1, 0x1d, 0x79, 0x31, 0x49, + 0x6a, 0x0f, 0x02, 0x3f, 0x0a, 0x9f, 0x42, 0x0c, + 0xd1, 0x09, 0x0e, 0x91, 0x42, 0x09, 0xd1, 0xc1, + 0x1d, 0x99, 0x31, 0x09, 0x89, 0x01, 0xaf, 0x3f, + 0x88, 0xb9, 0x42, 0x02, 0xd1, 0xc1, 0x68, 0x00, + 0x29, 0x02, 0xd1, 0x00, 0x68, 0x00, 0x28, 0xe8, + 0xd1, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xb8, 0xad, 0x03, 0x20, 0x07, 0x49, 0x09, + 0x6b, 0x00, 0x29, 0xed, 0x09, 0x00, 0xb7, 0x02, + 0x09, 0xd0, 0x0a, 0x69, 0x01, 0x2a, 0x03, 0xd1, + 0x81, 0x42, 0x01, 0xd0, 0x08, 0x1c, 0x70, 0x47, + 0x09, 0x68, 0x00, 0x29, 0xf5, 0xd1, 0x00, 0x20, + 0x70, 0x47, 0xb8, 0xad, 0x03, 0x20, 0x06, 0x49, + 0x09, 0x6b, 0x00, 0x29, 0x07, 0xd0, 0x4a, 0x69, + 0x82, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x70, 0x47, + 0x09, 0x68, 0x00, 0x29, 0xf7, 0xd1, 0x00, 0x20, + 0x70, 0x47, 0xb8, 0xad, 0x03, 0x20, 0xb0, 0xb5, + 0xc5, 0x1d, 0xff, 0x35, 0x7a, 0x35, 0x04, 0x1c, + 0x68, 0x6b, 0x00, 0x27, 0x00, 0x28, 0x03, 0xd0, + 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xd5, 0xf7, 0xbe, 0xfc, 0x00, 0x28, 0x01, 0xd1, + 0x07, 0x27, 0x11, 0xe0, 0xcc, 0x21, 0x01, 0x60, + 0xe1, 0x6a, 0xff, 0x34, 0xc1, 0x60, 0x75, 0x34, + 0x0c, 0xcc, 0xc1, 0x1d, 0x09, 0x31, 0x0c, 0xc1, + 0x0c, 0xcc, 0x0c, 0xc1, 0xe9, 0x69, 0x01, 0x62, + 0x01, 0x1c, 0x05, 0x20, 0xd5, 0xf7, 0x17, 0xfd, + 0x38, 0x1c, 0xe2, 0xe7, 0x00, 0xb5, 0xff, 0xf7, + 0x80, 0xff, 0x00, 0x28, 0x0c, 0xd0, 0xc1, 0x1d, + 0xf9, 0x31, 0x4a, 0x68, 0x00, 0x2a, 0x07, 0xd0, + 0x00, 0x22, 0x4a, 0x60, 0xc1, 0x1d, 0x79, 0x31, + 0x0a, 0x6b, 0x02, 0x21, 0x01, 0xf0, 0x1f, 0xfd, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, + 0x6c, 0xff, 0x00, 0x28, 0x09, 0xd0, 0xc1, 0x1d, + 0xf9, 0x31, 0x8a, 0x68, 0x00, 0x2a, 0x04, 0xd0, + 0x00, 0x22, 0x8a, 0x60, 0xa1, 0x21, 0x01, 0xf0, + 0x0e, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0xff, 0xf7, 0x5b, 0xff, 0x00, 0x28, 0x09, 0xd0, + 0xc1, 0x1d, 0xf9, 0x31, 0xca, 0x68, 0x00, 0x2a, + 0x04, 0xd0, 0x00, 0x22, 0xca, 0x60, 0x22, 0x21, + 0x00, 0xf0, 0x63, 0xfb, 0x08, 0xbc, 0x18, 0x47, + 0x08, 0xb5, 0xff, 0xf7, 0x4a, 0xff, 0xed, 0x09, + 0x00, 0xb8, 0x02, 0x00, 0x28, 0x0b, 0xd0, 0xc1, + 0x1d, 0xf9, 0x31, 0x0a, 0x69, 0x00, 0x2a, 0x06, + 0xd0, 0x00, 0x22, 0x0a, 0x61, 0x00, 0x23, 0x22, + 0x21, 0x00, 0x92, 0x00, 0xf0, 0x00, 0xfb, 0x01, + 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, + 0xf7, 0x36, 0xff, 0x00, 0x28, 0x0f, 0xd0, 0xc1, + 0x1d, 0xf9, 0x31, 0x4a, 0x69, 0x00, 0x2a, 0x0a, + 0xd0, 0x00, 0x22, 0x4a, 0x61, 0xc1, 0x1d, 0xb9, + 0x31, 0xc9, 0x69, 0x00, 0x29, 0x05, 0xd0, 0x22, + 0x22, 0x02, 0x21, 0x01, 0xf0, 0xd2, 0xfc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x22, 0x22, 0x21, 0x00, + 0xf0, 0x6c, 0xfb, 0xf8, 0xe7, 0x00, 0xb5, 0xff, + 0xf7, 0x1a, 0xff, 0x00, 0x28, 0x0d, 0xd0, 0xc1, + 0x1d, 0xf9, 0x31, 0x8a, 0x69, 0x00, 0x2a, 0x08, + 0xd0, 0x00, 0x22, 0x05, 0x23, 0xdb, 0x01, 0x8a, + 0x61, 0xc1, 0x18, 0x4a, 0x6b, 0x22, 0x21, 0x00, + 0xf0, 0xca, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0x83, 0xb0, 0xff, 0xf7, 0x04, 0xff, 0x07, + 0x1c, 0x19, 0xd0, 0xf8, 0x1d, 0xf9, 0x30, 0xc1, + 0x69, 0x00, 0x29, 0x14, 0xd0, 0x00, 0x21, 0x0b, + 0x23, 0x9b, 0x01, 0xfb, 0x18, 0x10, 0x33, 0xc1, + 0x61, 0x07, 0xcb, 0x1c, 0x3b, 0x01, 0x91, 0x00, + 0x90, 0x02, 0x92, 0xd9, 0x68, 0x05, 0x23, 0xdb, + 0x01, 0xf8, 0x18, 0x0b, 0x1c, 0x22, 0x21, 0xc2, + 0x68, 0x38, 0x1c, 0x00, 0xf0, 0x7e, 0xfb, 0x03, + 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xff, 0xf7, 0xe1, 0xfe, 0x00, 0x28, 0x0c, + 0xd0, 0xc1, 0x1d, 0xf9, 0x31, 0x0a, 0x6a, 0x00, + 0x2a, 0x07, 0xd0, 0x00, 0x22, 0x0a, 0x62, 0xc1, + 0x1d, 0xb9, 0x31, 0x4a, 0x63, 0x22, 0x21, 0x00, + 0xf0, 0xbb, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0xff, 0xf7, 0xcd, 0xfe, 0x07, 0x1c, 0x12, + 0xd0, 0xed, 0x09, 0x00, 0xb9, 0x02, 0xf8, 0x1d, + 0xf9, 0x30, 0x41, 0x6a, 0x00, 0x29, 0x0d, 0xd0, + 0x00, 0x21, 0x41, 0x62, 0xf9, 0x1d, 0x38, 0x1c, + 0x00, 0x23, 0xa0, 0x22, 0x1d, 0x31, 0x01, 0xf0, + 0xf5, 0xfb, 0x00, 0x22, 0xa0, 0x21, 0x38, 0x1c, + 0x01, 0xf0, 0x66, 0xfc, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x80, 0xb5, 0xff, 0xf7, 0xb2, 0xfe, + 0x07, 0x1c, 0x13, 0xd0, 0xf8, 0x1d, 0xff, 0x30, + 0x3a, 0x30, 0x01, 0x68, 0x00, 0x29, 0x0d, 0xd0, + 0x00, 0x21, 0x01, 0x60, 0xf9, 0x1d, 0x38, 0x1c, + 0x22, 0x23, 0xa4, 0x22, 0x21, 0x31, 0x01, 0xf0, + 0xd9, 0xfb, 0x00, 0x22, 0xa4, 0x21, 0x38, 0x1c, + 0x01, 0xf0, 0x4a, 0xfc, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x96, 0xfe, + 0x00, 0x28, 0x09, 0xd0, 0xc1, 0x1d, 0xf9, 0x31, + 0x4a, 0x6b, 0x00, 0x2a, 0x04, 0xd0, 0x00, 0x22, + 0x4a, 0x63, 0xa2, 0x21, 0x01, 0xf0, 0x38, 0xfc, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x82, 0xb0, + 0x0c, 0x48, 0x00, 0x68, 0x00, 0x28, 0x05, 0xd0, + 0x07, 0x68, 0x0b, 0xa1, 0x00, 0xf0, 0x86, 0xf9, + 0x38, 0x1c, 0xf9, 0xd1, 0x0d, 0x49, 0x00, 0x22, + 0x01, 0x92, 0x00, 0x91, 0x0c, 0xa1, 0x08, 0x68, + 0x00, 0x23, 0x01, 0x22, 0x49, 0x68, 0xfd, 0xf7, + 0x94, 0xfd, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x38, + 0x39, 0x36, 0x00, 0x00, 0xfd, 0xb3, 0x02, 0x20, + 0x80, 0x84, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xb5, 0xc7, 0x1d, 0xf9, 0x37, 0xb8, 0x68, + 0x00, 0x28, 0x04, 0xd0, 0x03, 0xa1, 0xfd, 0xf7, + 0x8b, 0xfd, 0x00, 0x20, 0xb8, 0x60, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xed, 0x09, 0x00, 0xba, + 0x02, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x39, 0x30, 0x38, 0x00, 0x00, 0x90, 0xb5, 0x82, + 0xb0, 0xc4, 0x1d, 0xf9, 0x34, 0x07, 0x1c, 0xa0, + 0x68, 0x00, 0x28, 0x02, 0xd0, 0x09, 0xa1, 0xfd, + 0xf7, 0x71, 0xfd, 0xba, 0x68, 0x0c, 0x49, 0x01, + 0x92, 0x00, 0x91, 0x0c, 0xa1, 0x08, 0x68, 0x00, + 0x23, 0x01, 0x22, 0x49, 0x68, 0xfd, 0xf7, 0x4f, + 0xfd, 0xa0, 0x60, 0x02, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x6d, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x39, 0x32, 0x30, 0x00, + 0x00, 0x2f, 0xb2, 0x02, 0x20, 0x00, 0x87, 0x93, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb5, 0x08, + 0x68, 0x0f, 0x1c, 0x00, 0x28, 0x04, 0xd0, 0x04, + 0xa1, 0xfd, 0xf7, 0x48, 0xfd, 0x00, 0x20, 0x38, + 0x60, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x39, 0x33, 0x34, 0x00, 0x00, 0xb0, 0xb5, 0x82, + 0xb0, 0x05, 0x1c, 0x08, 0x68, 0x14, 0x1c, 0x0f, + 0x1c, 0x00, 0x28, 0x02, 0xd0, 0x08, 0xa1, 0xfd, + 0xf7, 0x2d, 0xfd, 0xaa, 0x68, 0x00, 0x94, 0x01, + 0x92, 0x0a, 0xa1, 0x08, 0x68, 0x00, 0x23, 0x01, + 0x22, 0x49, 0x68, 0xfd, 0xf7, 0x0c, 0xfd, 0x38, + 0x60, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x39, 0x34, 0x36, 0x00, 0x00, 0x00, 0x87, 0x93, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb5, 0xc7, + 0x1d, 0xf9, 0x37, 0x78, 0x6b, 0x00, 0x28, 0x04, + 0xd0, 0x03, 0xa1, 0xfd, 0xf7, 0x07, 0xfd, 0xed, + 0x09, 0x00, 0xbb, 0x02, 0x00, 0x20, 0x78, 0x63, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x39, 0x36, 0x30, + 0x00, 0x00, 0xff, 0xb5, 0x82, 0xb0, 0xc6, 0x1d, + 0xf9, 0x36, 0x07, 0x1c, 0x70, 0x6b, 0x0c, 0x1c, + 0x00, 0x28, 0x02, 0xd0, 0x14, 0xa1, 0xfd, 0xf7, + 0xec, 0xfc, 0x00, 0x2c, 0x14, 0xd0, 0xf8, 0x1d, + 0xb9, 0x30, 0x00, 0x68, 0x01, 0x23, 0x1b, 0x03, + 0x98, 0x42, 0x0d, 0xd9, 0x13, 0x4b, 0x58, 0x43, + 0x40, 0x00, 0x5b, 0x03, 0xc4, 0x1a, 0x00, 0x25, + 0xd8, 0xf7, 0xf7, 0xfc, 0x22, 0x1c, 0xfc, 0x1d, + 0xb1, 0x34, 0x80, 0x18, 0x69, 0x41, 0x03, 0xc4, + 0xba, 0x68, 0x0c, 0x49, 0x00, 0x23, 0x01, 0x92, + 0x00, 0x91, 0x05, 0x99, 0x01, 0x22, 0x04, 0x98, + 0xfd, 0xf7, 0xb4, 0xfc, 0x70, 0x63, 0x06, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x39, 0x37, 0x33, + 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0xdb, 0xb3, + 0x02, 0x20, 0x43, 0x68, 0x00, 0x22, 0x00, 0x2b, + 0x03, 0xd0, 0x19, 0x60, 0x43, 0x68, 0x4b, 0x60, + 0x01, 0xe0, 0x01, 0x60, 0x4a, 0x60, 0x0a, 0x60, + 0x41, 0x60, 0x81, 0x68, 0x01, 0x31, 0x81, 0x60, + 0x70, 0x47, 0x0a, 0x68, 0x00, 0x2a, 0x02, 0xd0, + 0x4b, 0x68, 0x53, 0x60, 0x01, 0xe0, 0x4a, 0x68, + 0x42, 0x60, 0x4a, 0x68, 0x00, 0x2a, 0x02, 0xd0, + 0x09, 0x68, 0x11, 0x60, 0x01, 0xe0, 0x09, 0x68, + 0x01, 0x60, 0x81, 0x68, 0x00, 0x29, 0x01, 0xd0, + 0x01, 0x39, 0x81, 0x60, 0x70, 0x47, 0x83, 0xb5, + 0x0e, 0x48, 0x00, 0x68, 0x00, 0x28, 0x13, 0xd0, + 0x00, 0x99, 0x0b, 0x02, 0x1b, 0x0a, 0x0a, 0x0e, + 0x81, 0x68, 0xed, 0x09, 0x00, 0xbc, 0x02, 0x0f, + 0x02, 0x3f, 0x0a, 0x9f, 0x42, 0x07, 0xd1, 0x09, + 0x0e, 0x91, 0x42, 0x04, 0xd1, 0x81, 0x89, 0x01, + 0xaf, 0x3f, 0x88, 0xb9, 0x42, 0x02, 0xd0, 0x00, + 0x68, 0x00, 0x28, 0xef, 0xd1, 0x02, 0xb0, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf8, + 0xad, 0x03, 0x20, 0xff, 0xb5, 0x0b, 0x98, 0x00, + 0x27, 0x00, 0x28, 0x0c, 0x9e, 0x0a, 0x9c, 0x09, + 0x9d, 0x05, 0xd0, 0x00, 0xf0, 0x94, 0xf8, 0x10, + 0x49, 0xc9, 0x6a, 0x88, 0x42, 0x18, 0xd2, 0x54, + 0x20, 0x31, 0x1c, 0xfc, 0xf7, 0xd0, 0xfc, 0x07, + 0x1c, 0x12, 0xd0, 0xfe, 0x1d, 0x09, 0x36, 0xd8, + 0xf7, 0x76, 0xfc, 0x03, 0xc6, 0x01, 0x99, 0x09, + 0x48, 0xf9, 0x60, 0x00, 0x99, 0xb9, 0x60, 0x03, + 0x9b, 0x39, 0x1c, 0x3b, 0x62, 0x02, 0x9a, 0xfa, + 0x61, 0xbc, 0x62, 0x7d, 0x62, 0xff, 0xf7, 0x93, + 0xff, 0x38, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x38, 0xae, 0x03, 0x20, 0xf8, + 0xad, 0x03, 0x20, 0x90, 0xb5, 0x07, 0x1c, 0x0c, + 0x1c, 0x39, 0x1c, 0x04, 0x48, 0xff, 0xf7, 0x93, + 0xff, 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7, 0xad, + 0xfc, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, + 0xad, 0x03, 0x20, 0xf3, 0xb5, 0x82, 0xb0, 0x07, + 0x1c, 0xd8, 0xf7, 0x49, 0xfc, 0x05, 0x1c, 0xb8, + 0x69, 0x0c, 0x1c, 0x00, 0x28, 0x31, 0xd1, 0xf8, + 0x6a, 0x00, 0x28, 0x2e, 0xd1, 0x38, 0x6c, 0x00, + 0x28, 0x2b, 0xd1, 0x38, 0x6d, 0x00, 0x28, 0x24, + 0xd0, 0xfe, 0x1d, 0x09, 0x36, 0x01, 0x28, 0x12, + 0xd1, 0x14, 0x48, 0x00, 0x21, 0x01, 0x22, 0x80, + 0x69, 0xe5, 0xf7, 0xa1, 0xfa, 0x01, 0x91, 0x00, + 0x90, 0x0c, 0xce, 0x08, 0x3e, 0x21, 0x1c, 0xa8, + 0x1a, 0x99, 0x41, 0x01, 0x9b, 0x00, 0x9a, 0xe5, + 0xf7, 0x72, 0xfa, 0x00, 0x28, 0xed, 0x09, 0x00, + 0xbd, 0x02, 0x0d, 0xd1, 0x38, 0x6d, 0x02, 0x28, + 0x0e, 0xd1, 0x0c, 0xce, 0x21, 0x1c, 0xa8, 0x1a, + 0x99, 0x41, 0x08, 0x4b, 0x1a, 0x68, 0x5b, 0x68, + 0xe5, 0xf7, 0x64, 0xfa, 0x00, 0x28, 0x03, 0xd0, + 0x03, 0x99, 0x38, 0x1c, 0xff, 0xf7, 0xb4, 0xff, + 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x38, 0xae, 0x03, 0x20, 0x54, 0xae, 0x03, 0x20, + 0x80, 0xb5, 0x06, 0x48, 0x00, 0x68, 0x00, 0x28, + 0x05, 0xd0, 0x07, 0x68, 0x04, 0xa1, 0xff, 0xf7, + 0xa3, 0xff, 0x38, 0x1c, 0xf9, 0xd1, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf8, 0xad, 0x03, 0x20, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x31, + 0x31, 0x31, 0x32, 0x00, 0x06, 0x49, 0x00, 0x20, + 0x09, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x0a, 0x6d, + 0x02, 0x2a, 0x00, 0xd0, 0x01, 0x30, 0x09, 0x68, + 0x00, 0x29, 0xf8, 0xd1, 0x70, 0x47, 0x00, 0x00, + 0xf8, 0xad, 0x03, 0x20, 0xf7, 0xb5, 0x00, 0x24, + 0x0d, 0x1c, 0x07, 0x1c, 0xd5, 0xf7, 0xa7, 0xf9, + 0x00, 0x28, 0x01, 0xd1, 0x07, 0x24, 0x1a, 0xe0, + 0xd4, 0x21, 0x01, 0x60, 0xf9, 0x6a, 0xc1, 0x60, + 0x00, 0x29, 0x05, 0xd1, 0xfe, 0x1d, 0x9d, 0x36, + 0x0c, 0xce, 0xc1, 0x1d, 0x09, 0x31, 0x0c, 0xc1, + 0xf9, 0x1d, 0x79, 0x31, 0x85, 0x61, 0xc9, 0x6a, + 0xc1, 0x61, 0x02, 0x9a, 0xf9, 0x1d, 0xb9, 0x31, + 0x02, 0x62, 0x49, 0x68, 0x41, 0x62, 0x01, 0x1c, + 0x05, 0x20, 0xd5, 0xf7, 0xf7, 0xf9, 0x20, 0x1c, + 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xff, 0xb5, 0x03, 0x9b, 0x00, 0x27, 0x14, 0x1c, + 0x0d, 0x1c, 0x06, 0x1c, 0x00, 0x2b, 0x04, 0xd1, + 0x30, 0x1c, 0x29, 0x1c, 0x22, 0x1c, 0x06, 0xf0, + 0xad, 0xfa, 0xd5, 0xf7, 0x74, 0xf9, 0x00, 0x28, + 0xed, 0x09, 0x00, 0xbe, 0x02, 0x01, 0xd1, 0x07, + 0x27, 0x0b, 0xe0, 0xd8, 0x21, 0x01, 0x60, 0xf1, + 0x6a, 0xc1, 0x60, 0x84, 0x61, 0x45, 0x61, 0x03, + 0x9b, 0x01, 0x1c, 0x03, 0x61, 0x05, 0x20, 0xd5, + 0xf7, 0xd3, 0xf9, 0x38, 0x1c, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 0x04, + 0x1c, 0xff, 0x30, 0xc1, 0x30, 0x0d, 0x1c, 0x09, + 0x9e, 0xc1, 0x69, 0x00, 0x27, 0x00, 0x29, 0x15, + 0xd0, 0x00, 0x21, 0xc1, 0x61, 0xd5, 0xf7, 0x51, + 0xf9, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x0d, + 0xe0, 0xc6, 0x21, 0x01, 0x60, 0xc5, 0x60, 0xe1, + 0x6a, 0x01, 0x61, 0x02, 0x9a, 0x01, 0x1c, 0x42, + 0x61, 0x03, 0x9b, 0x83, 0x61, 0xc6, 0x61, 0x05, + 0x20, 0xd5, 0xf7, 0xae, 0xf9, 0x38, 0x1c, 0x04, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, + 0xb5, 0x05, 0x1c, 0xff, 0x30, 0xc1, 0x30, 0x0e, + 0x1c, 0xc1, 0x6a, 0x00, 0x27, 0x14, 0x1c, 0x00, + 0x29, 0x1c, 0xd0, 0x00, 0x21, 0xc1, 0x62, 0xd5, + 0xf7, 0x2c, 0xf9, 0x00, 0x28, 0x01, 0xd1, 0x07, + 0x27, 0x14, 0xe0, 0xc5, 0x21, 0x01, 0x60, 0xc6, + 0x60, 0xe9, 0x6a, 0x00, 0x2c, 0x01, 0x61, 0x04, + 0xd0, 0x60, 0xcc, 0xc1, 0x1d, 0x0d, 0x31, 0x60, + 0xc1, 0x04, 0xe0, 0x00, 0x22, 0x00, 0x23, 0xc1, + 0x1d, 0x0d, 0x31, 0x0c, 0xc1, 0x01, 0x1c, 0x05, + 0x20, 0xd5, 0xf7, 0x82, 0xf9, 0x38, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, + 0x1c, 0xff, 0x30, 0xc1, 0x30, 0x0e, 0x1c, 0x81, + 0x69, 0x00, 0x27, 0x15, 0x1c, 0x00, 0x29, 0x11, + 0xd0, 0x00, 0x21, 0x81, 0x61, 0xd5, 0xf7, 0x01, + 0xf9, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x09, + 0xe0, 0xc1, 0x21, 0x01, 0x60, 0xc6, 0x60, 0xe1, + 0x6a, 0x01, 0x61, 0x45, 0x61, 0x01, 0x1c, 0x05, + 0x20, 0xd5, 0xf7, 0xed, 0x09, 0x00, 0xbf, 0x02, + 0x62, 0xf9, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0x00, 0x27, 0x04, 0x1c, + 0xd5, 0xf7, 0xea, 0xf8, 0x00, 0x28, 0x01, 0xd1, + 0x07, 0x27, 0x0c, 0xe0, 0xbd, 0x21, 0x01, 0x60, + 0xe1, 0x6a, 0x0b, 0x23, 0x9b, 0x01, 0xc1, 0x60, + 0xe1, 0x18, 0x89, 0x68, 0x01, 0x61, 0x01, 0x1c, + 0x05, 0x20, 0xd5, 0xf7, 0x48, 0xf9, 0x38, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, + 0x06, 0x1c, 0xff, 0x30, 0xc1, 0x30, 0x01, 0x6a, + 0x00, 0x24, 0x15, 0x1c, 0x00, 0x29, 0x2e, 0xd0, + 0x00, 0x21, 0x01, 0x62, 0xd5, 0xf7, 0xc8, 0xf8, + 0x07, 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x26, 0xe0, + 0x16, 0xa1, 0xf9, 0x20, 0xfc, 0xf7, 0x47, 0xfb, + 0xb8, 0x61, 0x00, 0x28, 0x04, 0xd1, 0x38, 0x1c, + 0xd5, 0xf7, 0xf5, 0xf8, 0x07, 0x24, 0x1a, 0xe0, + 0xc4, 0x20, 0x38, 0x60, 0x01, 0x99, 0xf8, 0x1d, + 0xf9, 0x60, 0xf1, 0x1d, 0x9d, 0x31, 0x48, 0xc9, + 0x09, 0x30, 0x48, 0xc0, 0x00, 0x2d, 0x05, 0xd0, + 0xf9, 0x22, 0x29, 0x1c, 0xb8, 0x69, 0xd4, 0xf7, + 0x0e, 0xfd, 0x04, 0xe0, 0xf9, 0x22, 0x00, 0x21, + 0xb8, 0x69, 0xd4, 0xf7, 0x80, 0xfc, 0x05, 0x20, + 0x39, 0x1c, 0xd5, 0xf7, 0x0c, 0xf9, 0x20, 0x1c, + 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x31, 0x33, 0x32, 0x36, 0x00, 0xff, 0xb5, + 0x81, 0xb0, 0x07, 0x1c, 0x00, 0x20, 0x00, 0x90, + 0xf8, 0x1d, 0xff, 0x30, 0xba, 0x30, 0x0c, 0x9c, + 0x0b, 0x9d, 0x0a, 0x9e, 0x81, 0x6a, 0x00, 0x29, + 0x16, 0xd0, 0x00, 0x21, 0x81, 0x62, 0xd5, 0xf7, + 0x7b, 0xf8, 0x00, 0x28, 0x10, 0xd0, 0xc2, 0x21, + 0x01, 0x60, 0x02, 0x99, 0xc1, 0x60, 0xed, 0x09, + 0x00, 0xc0, 0x02, 0xf9, 0x6a, 0x01, 0x61, 0x03, + 0x9a, 0x01, 0x1c, 0x42, 0x61, 0x04, 0x9b, 0x83, + 0x61, 0xc6, 0x61, 0x44, 0x62, 0x05, 0x62, 0x05, + 0x20, 0xd5, 0xf7, 0xd7, 0xf8, 0x00, 0x98, 0x05, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, + 0xb5, 0x04, 0x1c, 0xff, 0x30, 0xc1, 0x30, 0x0e, + 0x1c, 0x41, 0x6a, 0x00, 0x27, 0x15, 0x1c, 0x00, + 0x29, 0x11, 0xd0, 0x00, 0x21, 0x41, 0x62, 0xd5, + 0xf7, 0x55, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x07, + 0x27, 0x09, 0xe0, 0xbf, 0x21, 0x01, 0x60, 0x46, + 0x61, 0xe1, 0x6a, 0xc1, 0x60, 0x05, 0x61, 0x01, + 0x1c, 0x05, 0x20, 0xd5, 0xf7, 0xb6, 0xf8, 0x38, + 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0xc1, 0x1d, 0xff, 0x31, 0x06, 0x31, 0x07, + 0x1c, 0xff, 0xf7, 0x03, 0xfd, 0xf9, 0x1d, 0xff, + 0x31, 0x38, 0x1c, 0x0a, 0x31, 0xff, 0xf7, 0xfd, + 0xfc, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x0e, + 0x31, 0xff, 0xf7, 0xf7, 0xfc, 0xf9, 0x1d, 0xff, + 0x31, 0x38, 0x1c, 0x12, 0x31, 0xff, 0xf7, 0xf1, + 0xfc, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x16, + 0x31, 0xff, 0xf7, 0xeb, 0xfc, 0xf9, 0x1d, 0xff, + 0x31, 0x38, 0x1c, 0x1a, 0x31, 0xff, 0xf7, 0xe5, + 0xfc, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x2a, + 0x31, 0xff, 0xf7, 0xdf, 0xfc, 0xf9, 0x1d, 0xff, + 0x31, 0x38, 0x1c, 0x1e, 0x31, 0xff, 0xf7, 0xd9, + 0xfc, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x3a, + 0x31, 0xff, 0xf7, 0xd3, 0xfc, 0xf9, 0x1d, 0xff, + 0x31, 0x38, 0x1c, 0x22, 0x31, 0xff, 0xf7, 0xcd, + 0xfc, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x26, + 0x31, 0xff, 0xf7, 0xc7, 0xfc, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x83, 0xb0, 0x0c, + 0x1c, 0x07, 0x1c, 0xff, 0xf7, 0xb4, 0xff, 0x00, + 0x22, 0xed, 0x09, 0x00, 0xc1, 0x02, 0x38, 0x1c, + 0x21, 0x1c, 0xff, 0xf7, 0xe3, 0xfe, 0x00, 0x22, + 0x00, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0x92, + 0xff, 0xf7, 0x8c, 0xfe, 0x00, 0x22, 0x38, 0x1c, + 0x21, 0x1c, 0xff, 0xf7, 0x11, 0xff, 0x05, 0x23, + 0xdb, 0x01, 0xfd, 0x18, 0x38, 0x1c, 0x21, 0x1c, + 0x6a, 0x6b, 0xff, 0xf7, 0x7b, 0xff, 0x0b, 0x23, + 0x9b, 0x01, 0xfb, 0x18, 0x10, 0x33, 0x07, 0xcb, + 0x00, 0x90, 0x1c, 0x3b, 0x01, 0x91, 0x02, 0x92, + 0xdb, 0x68, 0x38, 0x1c, 0x21, 0x1c, 0xea, 0x68, + 0xff, 0xf7, 0x42, 0xff, 0x00, 0x22, 0x38, 0x1c, + 0x21, 0x1c, 0xff, 0xf7, 0x90, 0xfe, 0x00, 0x22, + 0x38, 0x1c, 0x21, 0x1c, 0x08, 0xf0, 0x20, 0xf8, + 0x03, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0x05, 0xf0, + 0x60, 0xfc, 0x09, 0x4a, 0x08, 0x21, 0x00, 0x91, + 0x01, 0x92, 0x02, 0x1c, 0x27, 0x21, 0x01, 0x23, + 0x38, 0x1c, 0x05, 0xf0, 0x6e, 0xfe, 0x38, 0x1c, + 0xff, 0xf7, 0x4a, 0xfc, 0x02, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, + 0x7c, 0xae, 0x03, 0x20, 0x00, 0xb5, 0x00, 0x21, + 0xff, 0xf7, 0x6c, 0xf8, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0xb5, 0x01, 0x21, 0xff, 0xf7, + 0x65, 0xf8, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0x80, 0xb5, 0x07, 0x1c, 0x05, 0xf0, 0x39, 0xfc, + 0x02, 0x1c, 0x00, 0x23, 0x31, 0x21, 0x38, 0x1c, + 0x05, 0xf0, 0x4b, 0xfe, 0x38, 0x1c, 0xff, 0xf7, + 0x27, 0xfc, 0x80, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0xb0, 0xb5, 0x00, 0x25, 0x07, 0x1c, + 0xff, 0xf7, 0x06, 0xfc, 0x38, 0x1c, 0x00, 0xf0, + 0x39, 0xff, 0x04, 0x1c, 0x18, 0x28, 0x20, 0xd0, + 0x28, 0x28, 0x19, 0xd0, 0x37, 0x28, 0x13, 0xd1, + 0x38, 0x1c, 0x05, 0xf0, 0xed, 0x09, 0x00, 0xc2, + 0x02, 0x1a, 0xfc, 0x02, 0x1c, 0x00, 0x23, 0x31, + 0x21, 0x38, 0x1c, 0x05, 0xf0, 0x2c, 0xfe, 0x05, + 0x1c, 0x38, 0x1c, 0x00, 0x22, 0x21, 0x1c, 0x00, + 0xf0, 0xf5, 0xff, 0x00, 0x28, 0x02, 0xd1, 0x38, + 0x1c, 0xff, 0xf7, 0x00, 0xfc, 0x28, 0x1c, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0x26, 0xf8, 0xf6, 0xe7, 0x00, + 0x21, 0x38, 0x1c, 0xff, 0xf7, 0x21, 0xf8, 0xf1, + 0xe7, 0xf0, 0xb5, 0x84, 0xb0, 0x00, 0x24, 0x07, + 0x1c, 0xff, 0xf7, 0xd4, 0xfb, 0x2e, 0x4e, 0xfd, + 0x23, 0x9b, 0x00, 0x70, 0x6a, 0xfd, 0x18, 0x00, + 0x28, 0x32, 0xd0, 0x68, 0x46, 0x10, 0x22, 0x29, + 0x1c, 0xd4, 0xf7, 0xac, 0xfb, 0x38, 0x1c, 0x03, + 0xf0, 0x6b, 0xfa, 0x00, 0x28, 0x27, 0xd1, 0x38, + 0x69, 0x01, 0x28, 0x05, 0xd1, 0x00, 0x22, 0x1f, + 0x21, 0x38, 0x1c, 0x00, 0xf0, 0x87, 0xff, 0x1e, + 0xe0, 0x69, 0x46, 0x10, 0x22, 0x28, 0x1c, 0xd4, + 0xf7, 0x99, 0xfb, 0x38, 0x1c, 0x05, 0xf0, 0xdb, + 0xfb, 0x09, 0x23, 0x9b, 0x01, 0xf9, 0x18, 0x08, + 0x63, 0xf9, 0x1d, 0xff, 0x31, 0xba, 0x31, 0x02, + 0x20, 0x48, 0x63, 0xf0, 0x6b, 0x01, 0x28, 0x05, + 0xd1, 0x00, 0x22, 0x30, 0x21, 0x38, 0x1c, 0x00, + 0xf0, 0x6d, 0xff, 0x04, 0xe0, 0x00, 0x22, 0x31, + 0x21, 0x38, 0x1c, 0x00, 0xf0, 0x67, 0xff, 0x1d, + 0xe0, 0x0d, 0x20, 0xb8, 0x61, 0x38, 0x1c, 0x05, + 0xf0, 0xbe, 0xfb, 0x01, 0x1c, 0x38, 0x1c, 0x2a, + 0x1c, 0x02, 0xf0, 0xd3, 0xf8, 0x38, 0x1c, 0x05, + 0xf0, 0xae, 0xfb, 0x02, 0x1c, 0x00, 0x23, 0x31, + 0x21, 0x38, 0x1c, 0x05, 0xf0, 0xc0, 0xfd, 0x04, + 0x1c, 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, 0x00, + 0xf0, 0x89, 0xff, 0x00, 0x28, 0x02, 0xd1, 0x38, + 0x1c, 0xff, 0xf7, 0x94, 0xfb, 0x20, 0x1c, 0xed, + 0x09, 0x00, 0xc3, 0x02, 0x04, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf8, 0xad, + 0x03, 0x20, 0xb0, 0xb5, 0x87, 0xb0, 0x07, 0x1c, + 0xff, 0xf7, 0x6f, 0xfb, 0x38, 0x1c, 0x00, 0xf0, + 0xa2, 0xfe, 0xfd, 0x1d, 0x39, 0x4b, 0xff, 0x35, + 0x3a, 0x35, 0xfc, 0x18, 0x28, 0x28, 0x37, 0xd1, + 0x38, 0x69, 0x02, 0x28, 0x24, 0xd1, 0x01, 0xa8, + 0xfc, 0xf7, 0xf9, 0xf9, 0x02, 0x9a, 0x21, 0x1c, + 0x00, 0x92, 0xfa, 0x1d, 0xff, 0x32, 0x6e, 0x32, + 0x01, 0x9b, 0x03, 0xa8, 0xfd, 0xf7, 0x99, 0xfd, + 0x04, 0x21, 0x09, 0x23, 0x9b, 0x01, 0xf8, 0x18, + 0x00, 0x91, 0x03, 0xaa, 0x01, 0x92, 0x42, 0x6b, + 0x0c, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x05, 0xf0, + 0x81, 0xfd, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x1c, + 0x04, 0xa9, 0xfe, 0xf7, 0x3e, 0xfa, 0xe9, 0x6a, + 0x38, 0x1c, 0xfe, 0xf7, 0x84, 0xff, 0x0e, 0xe0, + 0xe9, 0x6a, 0x38, 0x1c, 0xfe, 0xf7, 0x7f, 0xff, + 0x38, 0x1c, 0x05, 0xf0, 0x5f, 0xfb, 0x1f, 0xa2, + 0x00, 0x92, 0x0b, 0x22, 0x01, 0x1c, 0x23, 0x23, + 0x38, 0x1c, 0x05, 0xf0, 0xeb, 0xfd, 0x2e, 0xe0, + 0x18, 0x28, 0x13, 0xd1, 0x10, 0x22, 0x21, 0x1c, + 0x03, 0xa8, 0xd4, 0xf7, 0x0a, 0xfb, 0xe9, 0x6a, + 0x38, 0x1c, 0xfe, 0xf7, 0x68, 0xff, 0x38, 0x69, + 0x02, 0x28, 0x04, 0xd1, 0x10, 0x22, 0x20, 0x1c, + 0x03, 0xa9, 0xd4, 0xf7, 0xfe, 0xfa, 0x1f, 0x20, + 0xb8, 0x61, 0x18, 0xe0, 0x1d, 0x20, 0xb8, 0x61, + 0x38, 0x1c, 0x21, 0x1c, 0xfe, 0xf7, 0x75, 0xfa, + 0x38, 0x1c, 0x05, 0xf0, 0x2f, 0xfb, 0x02, 0x1c, + 0x00, 0x23, 0x31, 0x21, 0x38, 0x1c, 0x05, 0xf0, + 0x41, 0xfd, 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, + 0x00, 0xf0, 0x0b, 0xff, 0x00, 0x28, 0x02, 0xd1, + 0x38, 0x1c, 0xff, 0xf7, 0x16, 0xfb, 0x07, 0xb0, + 0xb0, 0xbc, 0xed, 0x09, 0x00, 0xc4, 0x02, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x6d, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, + 0x3a, 0x20, 0x31, 0x36, 0x32, 0x34, 0x00, 0x01, + 0x1c, 0x00, 0x20, 0xc0, 0x31, 0x8a, 0x68, 0x4a, + 0x60, 0x70, 0x47, 0x90, 0xb5, 0x82, 0xb0, 0x00, + 0x24, 0x07, 0x1c, 0xff, 0xf7, 0xe0, 0xfa, 0x38, + 0x69, 0x02, 0x28, 0x13, 0xd1, 0xf8, 0x1d, 0xb9, + 0x30, 0x81, 0x6b, 0x00, 0x29, 0x0e, 0xd1, 0x01, + 0x21, 0x41, 0x63, 0x38, 0x1c, 0x05, 0xf0, 0xf4, + 0xfa, 0x0b, 0x4a, 0x08, 0x21, 0x00, 0x91, 0x01, + 0x92, 0x02, 0x1c, 0x27, 0x21, 0x01, 0x23, 0x38, + 0x1c, 0x05, 0xf0, 0x02, 0xfd, 0x38, 0x1c, 0x01, + 0xf0, 0x58, 0xfb, 0x00, 0x22, 0x00, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0x91, 0xfc, 0x20, 0x1c, 0x02, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x7c, + 0xae, 0x03, 0x20, 0x00, 0xb5, 0xff, 0xf7, 0xb7, + 0xfa, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0xb5, 0x00, 0x22, 0xa1, 0x21, 0x00, 0xf0, 0x7b, + 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, + 0xf0, 0xcb, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x01, 0xf0, 0xc6, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x01, 0xf0, 0xc1, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0xf0, 0xbc, + 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, + 0xf0, 0xb7, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0xc2, 0x1d, 0xff, 0x32, 0x7a, 0x32, 0x53, + 0x6b, 0x00, 0x2b, 0x02, 0xd0, 0x00, 0x23, 0x53, + 0x63, 0x01, 0xe0, 0x01, 0x23, 0x53, 0x63, 0x52, + 0x6b, 0x01, 0xf0, 0x8d, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xb9, + 0x31, 0x49, 0x68, 0x00, 0x20, 0xed, 0x09, 0x00, + 0xc5, 0x02, 0x00, 0x29, 0x08, 0xd1, 0xf8, 0x1d, + 0xff, 0x30, 0x7a, 0x30, 0x42, 0x6b, 0x38, 0x1c, + 0x01, 0xf0, 0x7c, 0xff, 0x0e, 0x21, 0x79, 0x61, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0xc2, 0x1d, 0xff, 0x32, 0x7a, 0x32, 0x53, 0x6b, + 0x00, 0x2b, 0x02, 0xd0, 0x00, 0x23, 0x53, 0x63, + 0x01, 0xe0, 0x01, 0x23, 0x53, 0x63, 0x52, 0x6b, + 0x01, 0xf0, 0x68, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x90, 0xb5, 0x0c, 0x1c, 0x68, 0x21, 0x00, 0x22, + 0x07, 0x1c, 0x00, 0xf0, 0x23, 0xfe, 0x38, 0x1c, + 0x21, 0x1c, 0x01, 0xf0, 0x74, 0xff, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x0c, 0x1c, + 0x68, 0x21, 0x00, 0x22, 0x07, 0x1c, 0x00, 0xf0, + 0x15, 0xfe, 0xf8, 0x1d, 0xff, 0x30, 0x7a, 0x30, + 0x41, 0x6b, 0x00, 0x29, 0x02, 0xd0, 0x00, 0x21, + 0x41, 0x63, 0x01, 0xe0, 0x01, 0x21, 0x41, 0x63, + 0x42, 0x6b, 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, + 0x41, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0xb5, 0xc1, 0x1d, 0xb9, 0x31, 0x49, 0x68, + 0x00, 0x27, 0x00, 0x29, 0x05, 0xd0, 0xc1, 0x1d, + 0xff, 0x31, 0x7a, 0x31, 0x49, 0x6b, 0x00, 0x29, + 0x06, 0xd1, 0x0e, 0x21, 0x41, 0x61, 0x00, 0x21, + 0x01, 0xf0, 0x45, 0xff, 0x07, 0x1c, 0x05, 0xe0, + 0x01, 0x69, 0x01, 0x29, 0x02, 0xd1, 0x00, 0x21, + 0x03, 0xf0, 0xa2, 0xfc, 0x38, 0x1c, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xc2, 0x1d, + 0xb9, 0x32, 0x52, 0x68, 0x00, 0x21, 0x00, 0x2a, + 0x09, 0xd1, 0x0e, 0x21, 0x41, 0x61, 0xc1, 0x1d, + 0xff, 0x31, 0x7a, 0x31, 0x4a, 0x6b, 0x00, 0x21, + 0x01, 0xf0, 0x10, 0xff, 0x01, 0x1c, 0x08, 0xbc, + 0x08, 0x1c, 0x18, 0x47, 0x00, 0xb5, 0x00, 0x21, + 0x01, 0xf0, 0x21, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0xed, 0x09, 0x00, 0xc6, 0x02, 0x00, 0xb5, 0xc1, + 0x1d, 0xff, 0x31, 0x7a, 0x31, 0x4a, 0x6b, 0x00, + 0x21, 0x01, 0xf0, 0xfe, 0xfe, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0x21, 0x01, 0xf0, 0x11, + 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xc1, + 0x1d, 0xff, 0x31, 0x7a, 0x31, 0x4a, 0x6b, 0x00, + 0x21, 0x01, 0xf0, 0xee, 0xfe, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x00, 0x21, 0x01, 0xf0, 0x01, + 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xc1, + 0x1d, 0xff, 0x31, 0x7a, 0x31, 0x4a, 0x6b, 0x00, + 0x21, 0x01, 0xf0, 0xde, 0xfe, 0x08, 0xbc, 0x18, + 0x47, 0x80, 0xb5, 0x01, 0x69, 0x00, 0x27, 0x01, + 0x29, 0x01, 0xd1, 0x03, 0xf0, 0x53, 0xfc, 0x38, + 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x20, 0x70, 0x47, 0x80, 0xb5, 0x00, 0x22, 0xa1, + 0x21, 0x07, 0x1c, 0x00, 0xf0, 0x8d, 0xfd, 0x0e, + 0x20, 0x78, 0x61, 0x22, 0x21, 0x38, 0x1c, 0x01, + 0xf0, 0xdc, 0xfe, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x80, 0xb5, 0x00, 0x22, 0xa1, 0x21, 0x07, + 0x1c, 0x00, 0xf0, 0x7e, 0xfd, 0xf8, 0x1d, 0xff, + 0x30, 0x7a, 0x30, 0x41, 0x6b, 0x00, 0x29, 0x02, + 0xd0, 0x00, 0x21, 0x41, 0x63, 0x01, 0xe0, 0x01, + 0x21, 0x41, 0x63, 0x42, 0x6b, 0x22, 0x21, 0x38, + 0x1c, 0x01, 0xf0, 0xaa, 0xfe, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x82, 0xb0, 0x07, + 0x1c, 0x07, 0xf0, 0x56, 0xfc, 0xf9, 0x1d, 0x79, + 0x31, 0x22, 0x20, 0x08, 0x63, 0x38, 0x1c, 0x05, + 0xf0, 0xb4, 0xf9, 0xfa, 0x1d, 0xa9, 0x32, 0x01, + 0x21, 0x00, 0x91, 0x01, 0x92, 0x02, 0x1c, 0x07, + 0x21, 0x01, 0x23, 0x38, 0x1c, 0x05, 0xf0, 0xc1, + 0xfb, 0x04, 0x1c, 0x14, 0xd1, 0x0b, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0xc0, 0x69, 0x43, 0x00, 0x18, + 0x18, 0x09, 0x4b, 0xed, 0x09, 0x00, 0xc7, 0x02, + 0x40, 0x00, 0x58, 0x43, 0x40, 0x00, 0x5b, 0x03, + 0xc2, 0x18, 0x38, 0x69, 0x00, 0x23, 0x01, 0x21, + 0x01, 0x28, 0x00, 0xd0, 0x00, 0x21, 0x38, 0x1c, + 0xff, 0xf7, 0x0d, 0xfa, 0x20, 0x1c, 0x02, 0xb0, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x71, 0x02, + 0x00, 0x00, 0x90, 0xb5, 0x83, 0xb0, 0x07, 0x1c, + 0x22, 0x20, 0x02, 0x90, 0x38, 0x1c, 0x07, 0xf0, + 0x1e, 0xfc, 0x38, 0x1c, 0x05, 0xf0, 0x80, 0xf9, + 0x01, 0x21, 0x02, 0xaa, 0x01, 0x92, 0x00, 0x91, + 0x07, 0x21, 0x02, 0x1c, 0x01, 0x23, 0x38, 0x1c, + 0x05, 0xf0, 0x8e, 0xfb, 0x04, 0x1c, 0x14, 0xd1, + 0x0b, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x69, + 0x43, 0x00, 0x18, 0x18, 0x0a, 0x4b, 0x40, 0x00, + 0x58, 0x43, 0x40, 0x00, 0x5b, 0x03, 0xc2, 0x18, + 0x38, 0x69, 0x00, 0x23, 0x01, 0x21, 0x01, 0x28, + 0x00, 0xd0, 0x00, 0x21, 0x38, 0x1c, 0xff, 0xf7, + 0xda, 0xf9, 0x20, 0x1c, 0x03, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x71, 0x02, + 0x00, 0x00, 0x00, 0xb5, 0x02, 0xa1, 0xff, 0xf7, + 0x93, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, + 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x50, + 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, + 0x00, 0x00, 0x00, 0xb5, 0x02, 0xa1, 0xff, 0xf7, + 0x77, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, + 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0xb5, + 0x02, 0xa1, 0xff, 0xf7, 0x61, 0xff, 0xed, 0x09, + 0x00, 0xc8, 0x02, 0x08, 0xbc, 0x18, 0x47, 0x4c, + 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, + 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, + 0xb5, 0x02, 0xa1, 0xff, 0xf7, 0x47, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x43, 0x6e, 0x74, + 0x72, 0x6c, 0x53, 0x74, 0x53, 0x65, 0x74, 0x75, + 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x00, 0x00, 0x00, 0x90, 0xb5, 0x00, 0x27, 0x04, + 0x1c, 0xd4, 0xf7, 0x48, 0xfc, 0x00, 0x28, 0x01, + 0xd1, 0x07, 0x27, 0x07, 0xe0, 0x57, 0x21, 0x01, + 0x60, 0x21, 0x6b, 0xc1, 0x60, 0x01, 0x1c, 0x07, + 0x20, 0xd4, 0xf7, 0xab, 0xfc, 0x38, 0x1c, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x00, + 0x27, 0x04, 0x1c, 0xd4, 0xf7, 0x33, 0xfc, 0x00, + 0x28, 0x01, 0xd1, 0x07, 0x27, 0x07, 0xe0, 0x57, + 0x21, 0x01, 0x60, 0x21, 0x6b, 0xc1, 0x60, 0x01, + 0x1c, 0x07, 0x20, 0xd4, 0xf7, 0x96, 0xfc, 0x38, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, + 0xb5, 0x00, 0x24, 0x05, 0x1c, 0x80, 0x30, 0x01, + 0x63, 0xd4, 0xf7, 0x1c, 0xfc, 0x07, 0x1c, 0x01, + 0xd1, 0x07, 0x24, 0x0a, 0xe0, 0x28, 0x1c, 0x07, + 0xf0, 0x54, 0xfb, 0x57, 0x20, 0x38, 0x60, 0x28, + 0x6b, 0xf8, 0x60, 0x07, 0x20, 0x39, 0x1c, 0xd4, + 0xf7, 0x7c, 0xfc, 0x20, 0x1c, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x83, 0xb0, 0x1c, + 0x1c, 0x0d, 0x1c, 0x07, 0x1c, 0x07, 0xf0, 0x41, + 0xfb, 0x02, 0x95, 0x00, 0x2d, 0x01, 0xd1, 0x13, + 0x20, 0xed, 0x09, 0x00, 0xc9, 0x02, 0x02, 0x90, + 0x38, 0x1c, 0x05, 0xf0, 0x9e, 0xf8, 0x01, 0x21, + 0x02, 0xaa, 0x01, 0x92, 0x00, 0x91, 0x07, 0x21, + 0x02, 0x1c, 0x01, 0x23, 0x38, 0x1c, 0x05, 0xf0, + 0xac, 0xfa, 0x05, 0x1c, 0x14, 0xd1, 0x0b, 0x23, + 0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x69, 0x43, 0x00, + 0x18, 0x18, 0x0f, 0x4b, 0x40, 0x00, 0x58, 0x43, + 0x40, 0x00, 0x5b, 0x03, 0xc2, 0x18, 0x38, 0x69, + 0x00, 0x23, 0x01, 0x21, 0x01, 0x28, 0x00, 0xd0, + 0x00, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xf8, 0xf8, + 0x00, 0x2c, 0x08, 0xd0, 0x20, 0x68, 0x13, 0x28, + 0x03, 0xd0, 0x14, 0x28, 0x01, 0xd0, 0x15, 0x28, + 0x01, 0xd1, 0x16, 0x20, 0x20, 0x60, 0x28, 0x1c, + 0x03, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x71, 0x02, 0x00, 0x00, 0x90, 0xb5, 0x0c, 0x1c, + 0x07, 0x1c, 0xff, 0xf7, 0x45, 0xf8, 0xf8, 0x1d, + 0x79, 0x30, 0x04, 0x63, 0x38, 0x1c, 0x21, 0x1c, + 0xfb, 0x1d, 0xa9, 0x33, 0x02, 0xa2, 0xff, 0xf7, + 0xaf, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, + 0x74, 0x50, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0xff, 0xf7, + 0x1f, 0xf8, 0xf8, 0x1d, 0x79, 0x30, 0x04, 0x63, + 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0x1d, 0xa9, 0x33, + 0x02, 0xa2, 0xff, 0xf7, 0x89, 0xff, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x43, 0x6e, + 0x74, 0x72, 0x6c, 0x53, 0x74, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x00, + 0x00, 0xb5, 0xc2, 0x1d, 0xed, 0x09, 0x00, 0xca, + 0x02, 0x79, 0x32, 0x11, 0x63, 0xc3, 0x1d, 0xa9, + 0x33, 0x02, 0xa2, 0xff, 0xf7, 0x6f, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x43, + 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x64, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xc2, + 0x1d, 0x79, 0x32, 0x11, 0x63, 0xc3, 0x1d, 0xa9, + 0x33, 0x02, 0xa2, 0xff, 0xf7, 0x53, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x43, + 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x41, 0x6e, 0x73, + 0x77, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xb5, 0xc5, 0x1d, 0xf9, 0x35, 0x07, + 0x1c, 0x68, 0x68, 0x0c, 0x1c, 0x00, 0x28, 0x04, + 0xd0, 0x09, 0xa1, 0xfc, 0xf7, 0x53, 0xfd, 0x00, + 0x20, 0x68, 0x60, 0xf8, 0x1d, 0x79, 0x30, 0x04, + 0x63, 0xfb, 0x1d, 0xa9, 0x33, 0x38, 0x1c, 0x21, + 0x1c, 0x00, 0xa2, 0x50, 0x3a, 0xff, 0xf7, 0x26, + 0xff, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x32, 0x32, 0x33, 0x33, 0x00, 0x90, 0xb5, 0x0c, + 0x1c, 0x07, 0x1c, 0xfe, 0xf7, 0x9f, 0xff, 0xf8, + 0x1d, 0x79, 0x30, 0x04, 0x63, 0x38, 0x1c, 0x21, + 0x1c, 0xfb, 0x1d, 0xa9, 0x33, 0x02, 0xa2, 0xff, + 0xf7, 0x09, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, + 0x53, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0xed, + 0x09, 0x00, 0xcb, 0x02, 0x65, 0x63, 0x74, 0x00, + 0x00, 0x00, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, + 0xfe, 0xf7, 0x7b, 0xff, 0xf8, 0x1d, 0x79, 0x30, + 0x04, 0x63, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0x1d, + 0xa9, 0x33, 0x02, 0xa2, 0xff, 0xf7, 0xe5, 0xfe, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, + 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x53, + 0x65, 0x74, 0x75, 0x70, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb5, 0xc2, 0x1d, 0x79, 0x32, + 0x51, 0x63, 0xc3, 0x1d, 0xad, 0x33, 0x02, 0xa2, + 0xff, 0xf7, 0xc7, 0xfe, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, + 0x6c, 0x53, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb5, 0xfe, 0xf7, 0x3d, 0xff, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0xb5, + 0xff, 0xf7, 0xb7, 0xfa, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x80, 0x30, 0x01, 0x63, 0x00, 0x20, + 0x70, 0x47, 0x80, 0x30, 0x01, 0x63, 0x00, 0x20, + 0x70, 0x47, 0x90, 0xb5, 0xc4, 0x1d, 0xf9, 0x34, + 0x60, 0x68, 0x00, 0x27, 0x00, 0x28, 0x03, 0xd0, + 0x04, 0xa1, 0xfc, 0xf7, 0xb6, 0xfc, 0x67, 0x60, + 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, + 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, + 0x20, 0x32, 0x33, 0x30, 0x37, 0x00, 0x00, 0xb5, + 0xc2, 0x1d, 0x79, 0x32, 0x11, 0x63, 0xfe, 0xf7, + 0x0c, 0xff, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0x00, 0xb5, 0xc2, 0x1d, 0x79, 0x32, 0x11, 0x63, + 0xfe, 0xf7, 0xed, 0x09, 0x00, 0xcc, 0x02, 0x03, + 0xff, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0xb5, 0xc2, 0x1d, 0x79, 0x32, 0x11, 0x63, 0xfe, + 0xf7, 0xfa, 0xfe, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0xff, + 0xf7, 0x72, 0xfa, 0xf9, 0x1d, 0x15, 0x31, 0x55, + 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0x7d, + 0xfa, 0xf9, 0x1d, 0x19, 0x31, 0x55, 0x22, 0x38, + 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0x76, 0xfa, 0xf9, + 0x1d, 0x1d, 0x31, 0x55, 0x22, 0x38, 0x1c, 0x23, + 0x1c, 0x00, 0xf0, 0x6f, 0xfa, 0xf9, 0x1d, 0x21, + 0x31, 0x55, 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x00, + 0xf0, 0x68, 0xfa, 0x55, 0x21, 0x38, 0x1c, 0x22, + 0x1c, 0x00, 0xf0, 0x9d, 0xfa, 0xf8, 0x1d, 0x79, + 0x30, 0x44, 0x63, 0x90, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x02, 0xa1, 0x0c, 0xc9, 0xb8, + 0x30, 0x0c, 0xc0, 0x00, 0x20, 0x70, 0x47, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, + 0xb5, 0x09, 0x06, 0x09, 0x0e, 0x00, 0x22, 0x07, + 0x1c, 0xff, 0xf7, 0x89, 0xf8, 0x04, 0x1c, 0xf8, + 0x6a, 0x00, 0x21, 0x00, 0x28, 0x00, 0xd1, 0x02, + 0x21, 0x38, 0x1c, 0x03, 0xa2, 0xfe, 0xf7, 0x49, + 0xfc, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x6d, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, + 0x3a, 0x20, 0x32, 0x33, 0x37, 0x39, 0x00, 0x90, + 0xb5, 0x0a, 0x06, 0x12, 0x0e, 0x00, 0x23, 0x00, + 0x21, 0x04, 0x1c, 0xff, 0xf7, 0x92, 0xf8, 0x07, + 0x1c, 0x20, 0x1c, 0x00, 0x21, 0x03, 0xa2, 0xfe, + 0xf7, 0x2c, 0xfc, 0x38, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x6d, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, + 0x3a, 0x20, 0x32, 0x33, 0x39, 0xed, 0x09, 0x00, + 0xcd, 0x02, 0x32, 0x00, 0x00, 0xb5, 0x02, 0xa2, + 0xff, 0xf7, 0xc0, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, + 0x74, 0x42, 0x42, 0x50, 0x61, 0x67, 0x65, 0x42, + 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, 0x68, 0x00, + 0x00, 0xb5, 0x03, 0xa2, 0x02, 0x21, 0xfe, 0xf7, + 0x07, 0xfc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, + 0x34, 0x30, 0x38, 0x00, 0x80, 0xb5, 0x07, 0x1c, + 0xff, 0xf7, 0xdc, 0xf9, 0x38, 0x1c, 0x02, 0x21, + 0x03, 0xa2, 0xfe, 0xf7, 0xf1, 0xfb, 0x80, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, + 0x34, 0x31, 0x37, 0x00, 0x00, 0xb5, 0x02, 0xa2, + 0xff, 0xf7, 0x84, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x42, 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x02, 0xa2, + 0xff, 0xf7, 0x70, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x49, 0x6e, 0x64, 0x42, 0x42, 0x44, 0x65, 0x74, + 0x61, 0x63, 0x68, 0x00, 0x00, 0xb5, 0x02, 0xa2, + 0xff, 0xf7, 0x5c, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x4f, 0x6b, + 0x42, 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xc1, 0x1d, + 0xed, 0x09, 0x00, 0xce, 0x02, 0x79, 0x31, 0x09, + 0x6b, 0x02, 0xa2, 0xff, 0xf7, 0x41, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x43, + 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x41, 0x6e, 0x73, + 0x77, 0x65, 0x72, 0x52, 0x65, 0x6a, 0x65, 0x63, + 0x74, 0x42, 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x02, + 0xa2, 0xff, 0xf7, 0x26, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, 0x6c, + 0x53, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, 0x68, + 0x00, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0xfe, + 0xf7, 0xcf, 0xfd, 0x38, 0x1c, 0x21, 0x1c, 0x03, + 0xa2, 0xff, 0xf7, 0x0a, 0xff, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x43, + 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x53, 0x65, + 0x74, 0x75, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x42, 0x42, 0x44, 0x65, 0x74, + 0x61, 0x63, 0x68, 0x00, 0x00, 0x90, 0xb5, 0x0c, + 0x1c, 0x07, 0x1c, 0xff, 0xf7, 0x31, 0xf9, 0xf9, + 0x1d, 0x15, 0x31, 0x9a, 0x22, 0x38, 0x1c, 0x23, + 0x1c, 0x00, 0xf0, 0x3c, 0xf9, 0xf9, 0x1d, 0x19, + 0x31, 0x9a, 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x00, + 0xf0, 0x35, 0xf9, 0xf9, 0x1d, 0x1d, 0x31, 0x9a, + 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0x2e, + 0xf9, 0xf9, 0x1d, 0x21, 0x31, 0x9a, 0x22, 0x38, + 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0x27, 0xf9, 0x9a, + 0x21, 0x38, 0x1c, 0x22, 0x1c, 0x00, 0xf0, 0x5c, + 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0x02, 0xa2, 0xff, + 0xf7, 0xeb, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x4c, 0x6d, 0xed, 0x09, 0x00, 0xcf, 0x02, + 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x42, 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, 0x68, + 0x00, 0x00, 0x00, 0xb5, 0xc2, 0x1d, 0x79, 0x32, + 0x52, 0x6b, 0x00, 0x2a, 0x04, 0xd0, 0x04, 0xa2, + 0xff, 0xf7, 0xd1, 0xfe, 0x08, 0xbc, 0x18, 0x47, + 0x02, 0xa2, 0xff, 0xf7, 0xac, 0xfe, 0xf9, 0xe7, + 0x00, 0x00, 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, + 0x6c, 0x53, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, + 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, 0x68, 0x00, + 0x00, 0x00, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, + 0xff, 0xf7, 0xd5, 0xf8, 0xf9, 0x1d, 0x15, 0x31, + 0x9a, 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x00, 0xf0, + 0xe0, 0xf8, 0xf9, 0x1d, 0x19, 0x31, 0x9a, 0x22, + 0x38, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0xd9, 0xf8, + 0xf9, 0x1d, 0x1d, 0x31, 0x9a, 0x22, 0x38, 0x1c, + 0x23, 0x1c, 0x00, 0xf0, 0xd2, 0xf8, 0xf9, 0x1d, + 0x21, 0x31, 0x9a, 0x22, 0x38, 0x1c, 0x23, 0x1c, + 0x00, 0xf0, 0xcb, 0xf8, 0x9a, 0x21, 0x38, 0x1c, + 0x22, 0x1c, 0x00, 0xf0, 0x00, 0xf9, 0xf8, 0x1d, + 0x79, 0x30, 0x40, 0x6b, 0x00, 0x28, 0x07, 0xd0, + 0x38, 0x1c, 0x21, 0x1c, 0x06, 0xa2, 0xff, 0xf7, + 0x8a, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x38, 0x1c, 0x21, 0x1c, 0x02, 0xa2, 0xff, 0xf7, + 0x62, 0xfe, 0xf6, 0xe7, 0x00, 0x00, 0x4c, 0x6d, + 0x43, 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x42, 0x42, 0x44, 0x65, 0x74, 0x61, 0x63, + 0x68, 0x00, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, + 0xff, 0xf7, 0x8d, 0xf8, 0xf9, 0x1d, 0x15, 0x31, + 0x9a, 0x22, 0x38, 0x1c, 0x23, 0x1c, 0xed, 0x09, + 0x00, 0xd0, 0x02, 0x00, 0xf0, 0x98, 0xf8, 0xf9, + 0x1d, 0x19, 0x31, 0x9a, 0x22, 0x38, 0x1c, 0x23, + 0x1c, 0x00, 0xf0, 0x91, 0xf8, 0xf9, 0x1d, 0x1d, + 0x31, 0x9a, 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x00, + 0xf0, 0x8a, 0xf8, 0xf9, 0x1d, 0x21, 0x31, 0x9a, + 0x22, 0x38, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0x83, + 0xf8, 0x9a, 0x21, 0x38, 0x1c, 0x22, 0x1c, 0x00, + 0xf0, 0xb8, 0xf8, 0xf8, 0x1d, 0x79, 0x30, 0x40, + 0x6b, 0x00, 0x28, 0x07, 0xd0, 0x38, 0x1c, 0x21, + 0x1c, 0x06, 0xa2, 0xff, 0xf7, 0x42, 0xfe, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0x21, + 0x1c, 0x02, 0xa2, 0xff, 0xf7, 0x1a, 0xfe, 0xf6, + 0xe7, 0x00, 0x00, 0x4c, 0x6d, 0x43, 0x6e, 0x74, + 0x72, 0x6c, 0x53, 0x74, 0x42, 0x42, 0x44, 0x65, + 0x74, 0x61, 0x63, 0x68, 0x42, 0x42, 0x44, 0x65, + 0x74, 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, 0x90, + 0xb5, 0x07, 0x1c, 0x79, 0x69, 0xa5, 0x20, 0x04, + 0x29, 0x05, 0xd0, 0x05, 0x29, 0x03, 0xd0, 0x07, + 0x29, 0x01, 0xd0, 0x09, 0x29, 0x24, 0xd1, 0xf8, + 0x1d, 0xb9, 0x30, 0x80, 0x6b, 0x00, 0x28, 0x02, + 0xd1, 0x38, 0x69, 0x02, 0x28, 0x23, 0xd1, 0x12, + 0x48, 0x40, 0x6a, 0x00, 0x28, 0x1d, 0xd0, 0xf9, + 0x1d, 0x9d, 0x31, 0xfc, 0x1d, 0xff, 0x34, 0x08, + 0x68, 0x49, 0x68, 0x3a, 0x34, 0xfe, 0xf7, 0xab, + 0xfd, 0x00, 0x28, 0x10, 0xd0, 0xc1, 0x6a, 0x00, + 0x29, 0x0d, 0xd0, 0xfa, 0x1d, 0xff, 0x32, 0xc1, + 0x1d, 0x29, 0x31, 0x6e, 0x32, 0x10, 0x1c, 0x8e, + 0xc9, 0x8e, 0xc0, 0x01, 0x20, 0xe0, 0x62, 0x28, + 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x18, + 0x20, 0xfa, 0xe7, 0x37, 0x20, 0xf8, 0xe7, 0x0b, + 0x20, 0xf6, 0xe7, 0xf8, 0xad, 0x03, 0x20, 0x08, + 0x68, 0x0d, 0x49, 0x80, 0x00, 0x08, 0x58, 0x0c, + 0x49, 0xed, 0x09, 0x00, 0xd1, 0x02, 0x43, 0x00, + 0x18, 0x18, 0x80, 0x00, 0x41, 0x18, 0x08, 0x68, + 0x00, 0x23, 0xa5, 0x28, 0x08, 0xd0, 0x08, 0x68, + 0x90, 0x42, 0x01, 0xd1, 0x01, 0x23, 0x03, 0xe0, + 0xc8, 0x68, 0x0c, 0x31, 0xa5, 0x28, 0xf6, 0xd1, + 0x00, 0x20, 0x00, 0x2b, 0x00, 0xd0, 0x08, 0x1c, + 0x70, 0x47, 0x00, 0x00, 0xb8, 0xa8, 0x03, 0x20, + 0x84, 0x94, 0x03, 0x20, 0xf0, 0xb5, 0x00, 0x27, + 0x0c, 0x1c, 0x05, 0x1c, 0x1e, 0x1c, 0xff, 0xf7, + 0xd9, 0xff, 0x00, 0x28, 0x0a, 0xd0, 0x41, 0x68, + 0x21, 0x60, 0x82, 0x68, 0x00, 0x2a, 0x07, 0xd0, + 0x28, 0x1c, 0x31, 0x1c, 0xd3, 0xf7, 0x20, 0xfc, + 0x07, 0x1c, 0x01, 0xe0, 0xff, 0x27, 0x0a, 0x37, + 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0x69, 0x0d, 0x4a, 0x80, 0x00, 0x10, 0x58, + 0x0c, 0x4a, 0x43, 0x00, 0x18, 0x18, 0x80, 0x00, + 0x82, 0x18, 0x10, 0x68, 0x00, 0x23, 0xa5, 0x28, + 0x08, 0xd0, 0x10, 0x68, 0x88, 0x42, 0x01, 0xd1, + 0x01, 0x23, 0x03, 0xe0, 0xd0, 0x68, 0x0c, 0x32, + 0xa5, 0x28, 0xf6, 0xd1, 0x00, 0x20, 0x00, 0x2b, + 0x00, 0xd0, 0x10, 0x1c, 0x70, 0x47, 0x00, 0x00, + 0xb8, 0xa8, 0x03, 0x20, 0x84, 0x94, 0x03, 0x20, + 0xb0, 0xb5, 0x00, 0x27, 0x04, 0x1c, 0x15, 0x1c, + 0xff, 0xf7, 0xda, 0xff, 0x00, 0x28, 0x0a, 0xd0, + 0x41, 0x68, 0xa1, 0x61, 0x82, 0x68, 0x00, 0x2a, + 0x07, 0xd0, 0x20, 0x1c, 0x29, 0x1c, 0xd3, 0xf7, + 0xe7, 0xfb, 0x07, 0x1c, 0x01, 0xe0, 0xff, 0x27, + 0x0a, 0x37, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x40, 0x69, 0x0e, 0x4a, 0x80, 0x00, + 0x80, 0x18, 0xff, 0x30, 0x41, 0x30, 0x00, 0x68, + 0x0c, 0x4a, 0x43, 0x00, 0x18, 0x18, 0x80, 0x00, + 0x82, 0x18, 0x10, 0x68, 0x00, 0x23, 0xa5, 0x28, + 0x08, 0xd0, 0x10, 0x68, 0xed, 0x09, 0x00, 0xd2, + 0x02, 0x88, 0x42, 0x01, 0xd1, 0x01, 0x23, 0x03, + 0xe0, 0xd0, 0x68, 0x0c, 0x32, 0xa5, 0x28, 0xf6, + 0xd1, 0x00, 0x20, 0x00, 0x2b, 0x00, 0xd0, 0x10, + 0x1c, 0x70, 0x47, 0x00, 0x00, 0xb8, 0xa8, 0x03, + 0x20, 0x28, 0x7e, 0x03, 0x20, 0xb0, 0xb5, 0x00, + 0x27, 0x04, 0x1c, 0x15, 0x1c, 0xff, 0xf7, 0xd7, + 0xff, 0x00, 0x28, 0x0a, 0xd0, 0x41, 0x68, 0x61, + 0x61, 0x82, 0x68, 0x00, 0x2a, 0x07, 0xd0, 0x20, + 0x1c, 0x29, 0x1c, 0xd3, 0xf7, 0xab, 0xfb, 0x07, + 0x1c, 0x01, 0xe0, 0xff, 0x27, 0x0a, 0x37, 0x38, + 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0x07, 0x1c, 0xd3, 0xf7, 0x58, 0xff, 0x00, + 0x28, 0x07, 0xd0, 0xd1, 0x21, 0x01, 0x60, 0xf9, + 0x68, 0xc1, 0x60, 0x01, 0x1c, 0x05, 0x20, 0xd3, + 0xf7, 0xbd, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf8, 0xb5, 0x05, 0x1c, 0xc0, 0x68, 0xfc, + 0xf7, 0x03, 0xf8, 0x04, 0x1c, 0x3d, 0xd0, 0x6e, + 0x69, 0x00, 0x2e, 0x02, 0xd1, 0x94, 0x21, 0x00, + 0x91, 0x01, 0xe0, 0x95, 0x21, 0x00, 0x91, 0xd3, + 0xf7, 0x3a, 0xff, 0x07, 0x1c, 0x2c, 0xd0, 0x00, + 0x22, 0x20, 0x1c, 0x00, 0x99, 0xff, 0xf7, 0xbe, + 0xff, 0x00, 0x28, 0x03, 0xd0, 0x38, 0x1c, 0xd3, + 0xf7, 0x69, 0xff, 0x21, 0xe0, 0x28, 0x69, 0x20, + 0x63, 0xe0, 0x1d, 0xb9, 0x30, 0xc0, 0x69, 0x00, + 0x28, 0x0c, 0xd0, 0xcf, 0x20, 0x38, 0x60, 0x19, + 0x21, 0x01, 0x20, 0xfb, 0xf7, 0xad, 0xff, 0xf8, + 0x60, 0x05, 0x20, 0x39, 0x1c, 0x3e, 0x61, 0xd3, + 0xf7, 0x89, 0xff, 0x0b, 0xe0, 0xd2, 0x20, 0x38, + 0x60, 0xbe, 0x61, 0xe0, 0x6a, 0xf8, 0x60, 0x3c, + 0x61, 0x00, 0x20, 0x78, 0x61, 0x05, 0x20, 0x39, + 0x1c, 0xd3, 0xf7, 0x7c, 0xff, 0x00, 0x2e, 0x04, + 0xd0, 0x20, 0x1c, 0x01, 0x21, 0x02, 0xa2, 0xed, + 0x09, 0x00, 0xd3, 0x02, 0xfe, 0xf7, 0x23, 0xf9, + 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, 0x74, 0x72, + 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x38, 0x30, + 0x37, 0x00, 0xf0, 0xb5, 0x82, 0xb0, 0x05, 0x69, + 0x04, 0x1c, 0x00, 0x2d, 0x01, 0xd1, 0x96, 0x26, + 0x00, 0xe0, 0x97, 0x26, 0xe0, 0x68, 0xfb, 0xf7, + 0xaa, 0xff, 0x07, 0x1c, 0x2f, 0xd0, 0x38, 0x1c, + 0x31, 0x1c, 0xff, 0xf7, 0x4f, 0xff, 0x00, 0x28, + 0x29, 0xd0, 0x97, 0x2e, 0x2b, 0xd1, 0xf8, 0x1d, + 0x79, 0x30, 0x00, 0x6b, 0x00, 0x24, 0x02, 0x28, + 0x00, 0xd1, 0x05, 0x1c, 0x00, 0x22, 0x38, 0x1c, + 0x31, 0x1c, 0xff, 0xf7, 0x62, 0xff, 0xf8, 0x1d, + 0xb9, 0x30, 0xc1, 0x69, 0x00, 0x29, 0x08, 0xd0, + 0x00, 0x21, 0xc1, 0x61, 0x38, 0x1c, 0x00, 0x22, + 0x29, 0x1c, 0xfe, 0xf7, 0xf6, 0xfd, 0x02, 0x24, + 0x08, 0xe0, 0x00, 0x22, 0x38, 0x1c, 0x29, 0x1c, + 0xfe, 0xf7, 0x17, 0xfd, 0xf8, 0x6a, 0x00, 0x28, + 0x00, 0xd1, 0x02, 0x24, 0x38, 0x1c, 0x21, 0x1c, + 0x26, 0xa2, 0xfe, 0xf7, 0xd8, 0xf8, 0x02, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x60, 0x69, + 0xf9, 0x68, 0x00, 0x22, 0x48, 0x62, 0xa0, 0x69, + 0xf9, 0x68, 0x88, 0x62, 0x38, 0x1c, 0x31, 0x1c, + 0xff, 0xf7, 0x37, 0xff, 0xf8, 0x1d, 0xb9, 0x30, + 0xc0, 0x69, 0x00, 0x28, 0x25, 0xd0, 0x00, 0x21, + 0x0b, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x5d, 0x23, + 0xdb, 0x00, 0x41, 0x62, 0xf8, 0x18, 0xf9, 0x22, + 0xd3, 0xf7, 0x7b, 0xfa, 0x38, 0x1c, 0x04, 0xf0, + 0x3d, 0xfb, 0xb9, 0x23, 0x9b, 0x00, 0xfa, 0x18, + 0x01, 0x92, 0x01, 0x21, 0x02, 0x1c, 0x01, 0x23, + 0x38, 0x1c, 0x00, 0x91, 0x04, 0xf0, 0x4a, 0xfd, + 0x00, 0x22, 0x0c, 0x21, 0x38, 0x1c, 0xff, 0xf7, + 0x14, 0xff, 0xed, 0x09, 0x00, 0xd4, 0x02, 0xf9, + 0x1d, 0xff, 0x31, 0x0e, 0x31, 0x38, 0x1c, 0x0e, + 0x4a, 0xfe, 0xf7, 0x61, 0xfb, 0x08, 0xe0, 0x00, + 0x23, 0x00, 0x22, 0x33, 0x21, 0x38, 0x1c, 0x04, + 0xf0, 0x37, 0xfd, 0x38, 0x1c, 0xfe, 0xf7, 0x13, + 0xfb, 0x38, 0x1c, 0x06, 0xf0, 0x8e, 0xfd, 0x38, + 0x1c, 0x06, 0xf0, 0xc9, 0xfd, 0xb5, 0xe7, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, 0x74, + 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, 0x38, + 0x35, 0x36, 0x00, 0x9b, 0xb2, 0x02, 0x20, 0xf0, + 0xb5, 0x88, 0xb0, 0x05, 0x1c, 0xe9, 0x1d, 0x0d, + 0x31, 0xc0, 0xc9, 0x06, 0xa8, 0xc0, 0xc0, 0x06, + 0x98, 0x07, 0x99, 0xfe, 0xf7, 0x44, 0xf9, 0x06, + 0x1c, 0xe8, 0x68, 0x00, 0x28, 0x75, 0xd0, 0xd3, + 0xf7, 0x53, 0xfe, 0x04, 0x1c, 0x71, 0xd0, 0x06, + 0x98, 0x01, 0x02, 0x09, 0x0a, 0x04, 0xa8, 0xfb, + 0xf7, 0x48, 0xfe, 0xe8, 0x69, 0x29, 0x6a, 0x37, + 0xa2, 0x03, 0x92, 0x05, 0x9a, 0x01, 0x90, 0x02, + 0x91, 0x00, 0x92, 0x02, 0x22, 0x07, 0x99, 0x06, + 0x98, 0x04, 0x9b, 0xfd, 0xf7, 0x88, 0xff, 0x07, + 0x1c, 0x08, 0xd1, 0x57, 0x20, 0x20, 0x60, 0xe8, + 0x68, 0xe0, 0x60, 0x07, 0x20, 0x21, 0x1c, 0xd3, + 0xf7, 0xa2, 0xfe, 0x53, 0xe0, 0xf9, 0x1d, 0x28, + 0x69, 0x79, 0x31, 0xc8, 0x62, 0xe8, 0x68, 0x98, + 0x21, 0x00, 0x22, 0x38, 0x63, 0x38, 0x1c, 0xff, + 0xf7, 0xb2, 0xfe, 0x00, 0x28, 0x07, 0xd0, 0x20, + 0x1c, 0xd3, 0xf7, 0x5d, 0xfe, 0x38, 0x1c, 0x28, + 0xa1, 0xfd, 0xf7, 0xf3, 0xff, 0x3e, 0xe0, 0x00, + 0x2e, 0x1f, 0xd0, 0x70, 0x69, 0x00, 0x28, 0x15, + 0xd0, 0x00, 0x22, 0x90, 0x21, 0x38, 0x1c, 0xff, + 0xf7, 0x9e, 0xfe, 0x00, 0x28, 0x03, 0xd0, 0x20, + 0x1c, 0xd3, 0xf7, 0x49, 0xfe, 0x2e, 0xe0, 0x38, + 0x6b, 0xc7, 0x60, 0x57, 0x20, 0xed, 0x09, 0x00, + 0xd5, 0x02, 0x20, 0x60, 0x38, 0x6b, 0xe0, 0x60, + 0x07, 0x20, 0x21, 0x1c, 0xd3, 0xf7, 0x72, 0xfe, + 0x23, 0xe0, 0xf0, 0x68, 0xf8, 0x60, 0x00, 0x28, + 0x02, 0xd0, 0x87, 0x61, 0x00, 0x20, 0xf0, 0x60, + 0x56, 0x20, 0x20, 0x60, 0x27, 0x61, 0x38, 0x6b, + 0xe0, 0x60, 0x07, 0x20, 0x21, 0x1c, 0xd3, 0xf7, + 0x61, 0xfe, 0xe8, 0x69, 0xf9, 0x68, 0x48, 0x62, + 0x28, 0x6a, 0xf9, 0x68, 0x88, 0x62, 0x38, 0x1c, + 0x06, 0xf0, 0x6a, 0xfd, 0x38, 0x1c, 0x06, 0xf0, + 0xff, 0xfc, 0x38, 0x1c, 0x06, 0xf0, 0x3a, 0xfd, + 0x38, 0x1c, 0xfe, 0xf7, 0x7b, 0xfa, 0x00, 0xe0, + 0xff, 0xe7, 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, + 0x6c, 0x6d, 0x63, 0x6e, 0x74, 0x72, 0x6c, 0x2e, + 0x63, 0x3a, 0x20, 0x32, 0x39, 0x31, 0x34, 0x00, + 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, 0x6e, + 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, 0x32, + 0x39, 0x33, 0x30, 0x00, 0xb0, 0xb5, 0xc0, 0x68, + 0xfb, 0xf7, 0x7e, 0xfe, 0x07, 0x1c, 0x1b, 0xd0, + 0x99, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0x23, 0xfe, + 0x00, 0x28, 0x15, 0xd0, 0xfc, 0x1d, 0x79, 0x34, + 0x21, 0x6b, 0x00, 0x25, 0x00, 0x29, 0x25, 0xd0, + 0xf8, 0x1d, 0xb9, 0x30, 0xc2, 0x69, 0x00, 0x2a, + 0x0d, 0xd0, 0xc5, 0x61, 0x00, 0x22, 0x38, 0x1c, + 0x21, 0x6b, 0xfe, 0xf7, 0xd3, 0xfc, 0x38, 0x1c, + 0x02, 0x21, 0x32, 0xa2, 0xfd, 0xf7, 0xc0, 0xff, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22, + 0x38, 0x1c, 0xfe, 0xf7, 0xef, 0xfb, 0x00, 0x22, + 0x99, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0x22, 0xfe, + 0xf8, 0x6a, 0x29, 0x1c, 0x00, 0x28, 0x00, 0xd1, + 0x02, 0x21, 0x38, 0x1c, 0x2c, 0xa2, 0xfd, 0xf7, + 0xab, 0xff, 0xe9, 0xe7, 0x60, 0x6b, 0x00, 0x28, + 0xed, 0x09, 0x00, 0xd6, 0x02, 0x35, 0xd0, 0x01, + 0x1c, 0x38, 0x1c, 0xfe, 0xf7, 0x89, 0xfd, 0x9a, + 0x22, 0x38, 0x1c, 0xf9, 0x1d, 0x15, 0x31, 0x63, + 0x6b, 0xff, 0xf7, 0x94, 0xfd, 0x9a, 0x22, 0x38, + 0x1c, 0xf9, 0x1d, 0x19, 0x31, 0x63, 0x6b, 0xff, + 0xf7, 0x8d, 0xfd, 0x9a, 0x22, 0x38, 0x1c, 0xf9, + 0x1d, 0x1d, 0x31, 0x63, 0x6b, 0xff, 0xf7, 0x86, + 0xfd, 0x9a, 0x22, 0x38, 0x1c, 0xf9, 0x1d, 0x21, + 0x31, 0x63, 0x6b, 0xff, 0xf7, 0x7f, 0xfd, 0x9a, + 0x21, 0x38, 0x1c, 0x62, 0x6b, 0xff, 0xf7, 0xb4, + 0xfd, 0x00, 0x23, 0x00, 0x21, 0x38, 0x1c, 0x62, + 0x6b, 0xfe, 0xf7, 0xdc, 0xfb, 0x00, 0x22, 0x99, + 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xe5, 0xfd, 0x38, + 0x1c, 0x00, 0x21, 0x15, 0xa2, 0xfd, 0xf7, 0x72, + 0xff, 0xb0, 0xe7, 0xf8, 0x1d, 0xb9, 0x30, 0xc1, + 0x69, 0x00, 0x29, 0x07, 0xd0, 0x5d, 0x23, 0xdb, + 0x00, 0xfa, 0x18, 0x00, 0x21, 0xc5, 0x61, 0x38, + 0x1c, 0xfe, 0xf7, 0x72, 0xfc, 0x38, 0x1c, 0x02, + 0x21, 0x10, 0xa2, 0xfd, 0xf7, 0x5f, 0xff, 0x9d, + 0xe7, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x32, 0x39, 0x39, 0x39, 0x00, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x6d, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x30, 0x30, 0x33, + 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x63, + 0x6e, 0x74, 0x72, 0x6c, 0x2e, 0x63, 0x3a, 0x20, + 0x33, 0x30, 0x32, 0x33, 0x00, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x6d, 0x63, 0x6e, 0x74, 0x72, 0x6c, + 0x2e, 0x63, 0x3a, 0x20, 0x33, 0x30, 0x33, 0x33, + 0x00, 0x80, 0xb5, 0x07, 0x1c, 0xd3, 0xf7, 0x15, + 0xfd, 0x00, 0x28, 0x0e, 0xd0, 0xff, 0x68, 0xdb, + 0x21, 0x01, 0x60, 0xc7, 0x60, 0x01, 0x1c, 0x05, + 0x20, 0xd3, 0xf7, 0xed, 0x09, 0x00, 0xd7, 0x02, + 0x7a, 0xfd, 0x00, 0x20, 0x00, 0x2f, 0x05, 0x49, + 0x05, 0xd1, 0x4a, 0x6b, 0x0a, 0x63, 0x88, 0x63, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x63, + 0x48, 0x63, 0xf9, 0xe7, 0x00, 0x00, 0xf8, 0xad, + 0x03, 0x20, 0x80, 0xb5, 0x07, 0x1c, 0xd3, 0xf7, + 0xf7, 0xfc, 0x00, 0x28, 0x0b, 0xd0, 0xdc, 0x21, + 0x01, 0x60, 0xf9, 0x68, 0xc1, 0x60, 0x01, 0x1c, + 0x05, 0x20, 0xd3, 0xf7, 0x5c, 0xfd, 0x03, 0x49, + 0x00, 0x20, 0x08, 0x63, 0x48, 0x63, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf8, 0xad, + 0x03, 0x20, 0x00, 0xb5, 0xd3, 0xf7, 0xe0, 0xfc, + 0x00, 0x28, 0x0a, 0xd0, 0xdd, 0x21, 0x01, 0x60, + 0x05, 0x49, 0x89, 0x6b, 0x01, 0x61, 0x00, 0x21, + 0xc1, 0x60, 0x01, 0x1c, 0x05, 0x20, 0xd3, 0xf7, + 0x42, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0xad, + 0x03, 0x20, 0xb0, 0xb5, 0x07, 0x1c, 0xd3, 0xf7, + 0xcb, 0xfc, 0x23, 0x4d, 0x00, 0x28, 0x20, 0xd0, + 0x29, 0x6b, 0x00, 0x29, 0x02, 0xd0, 0xaa, 0x6b, + 0x8a, 0x42, 0x18, 0xd2, 0xa9, 0x6b, 0x01, 0x31, + 0xa9, 0x63, 0xda, 0x21, 0x01, 0x60, 0x39, 0x6a, + 0x41, 0x61, 0x79, 0x6a, 0x81, 0x61, 0xb9, 0x6a, + 0xc1, 0x61, 0xf9, 0x6a, 0x01, 0x62, 0x39, 0x6b, + 0x10, 0x37, 0x41, 0x62, 0x0c, 0xcf, 0xc1, 0x1d, + 0x05, 0x31, 0x0c, 0xc1, 0x01, 0x1c, 0x05, 0x20, + 0xd3, 0xf7, 0x19, 0xfd, 0x01, 0xe0, 0x50, 0x1c, + 0xa8, 0x63, 0xa8, 0x6b, 0x29, 0x6b, 0x88, 0x42, + 0x0a, 0xd1, 0xd3, 0xf7, 0xa1, 0xfc, 0x07, 0x1c, + 0x06, 0xd0, 0xd3, 0xf7, 0x9d, 0xfc, 0x04, 0x1c, + 0x05, 0xd1, 0x38, 0x1c, 0xd3, 0xf7, 0xd3, 0xfc, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xdd, 0x20, + 0x38, 0x60, 0xa8, 0x6b, 0x00, 0x25, 0x38, 0x61, + 0x05, 0x20, 0x39, 0x1c, 0xfd, 0x60, 0xed, 0x09, + 0x00, 0xd8, 0x02, 0xd3, 0xf7, 0xfa, 0xfc, 0x51, + 0x20, 0x20, 0x60, 0x07, 0x20, 0x21, 0x1c, 0xe5, + 0x60, 0xd3, 0xf7, 0xf3, 0xfc, 0xea, 0xe7, 0xf8, + 0xad, 0x03, 0x20, 0xf0, 0xb5, 0x84, 0xb0, 0x07, + 0x1c, 0xc0, 0x68, 0xfb, 0xf7, 0x38, 0xfd, 0x04, + 0x1c, 0x6d, 0xd0, 0xd3, 0xf7, 0x77, 0xfc, 0x05, + 0x1c, 0x69, 0xd0, 0x14, 0x23, 0xf8, 0x56, 0x78, + 0x23, 0xd8, 0x42, 0x03, 0xd0, 0xe1, 0x1d, 0xff, + 0x31, 0x3a, 0x31, 0x48, 0x62, 0x11, 0x23, 0x9b, + 0x01, 0xe6, 0x18, 0x70, 0x6a, 0x41, 0x1c, 0x05, + 0x20, 0xd2, 0xf7, 0xe1, 0xff, 0x88, 0x00, 0x02, + 0x19, 0x71, 0x62, 0xbe, 0x69, 0x11, 0x23, 0x9b, + 0x01, 0xd0, 0x18, 0x03, 0x96, 0x81, 0x6a, 0x71, + 0x1a, 0x02, 0x91, 0xf9, 0x69, 0xc3, 0x6b, 0xc9, + 0x1a, 0x09, 0x23, 0xdb, 0x01, 0x01, 0x91, 0xd2, + 0x18, 0x13, 0x69, 0x79, 0x6a, 0xc9, 0x1a, 0xbb, + 0x6a, 0x56, 0x6a, 0x9b, 0x1b, 0x00, 0x93, 0x03, + 0x9b, 0x5f, 0x4e, 0x83, 0x62, 0xfb, 0x69, 0xc3, + 0x63, 0x78, 0x6a, 0x10, 0x61, 0xb8, 0x6a, 0x50, + 0x62, 0x02, 0x98, 0x01, 0x9a, 0x82, 0x18, 0x14, + 0x2a, 0x03, 0xd8, 0x00, 0x98, 0x08, 0x18, 0x14, + 0x28, 0x30, 0xd9, 0x00, 0x98, 0x08, 0x18, 0x90, + 0x42, 0x09, 0xd3, 0x64, 0x23, 0x59, 0x43, 0x01, + 0x22, 0x01, 0x28, 0x00, 0xd3, 0x02, 0x1c, 0x10, + 0x1c, 0xd2, 0xf7, 0xa9, 0xff, 0x08, 0xe0, 0x02, + 0x98, 0x64, 0x21, 0x41, 0x43, 0x01, 0x20, 0x01, + 0x2a, 0x00, 0xd3, 0x10, 0x1c, 0xd2, 0xf7, 0x9f, + 0xff, 0xe1, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x09, + 0x6a, 0x78, 0x23, 0xd9, 0x42, 0x01, 0xd1, 0x01, + 0x20, 0x3d, 0xe0, 0x3d, 0x22, 0xb3, 0x68, 0xd2, + 0x43, 0x01, 0x2b, 0x01, 0xd0, 0x4a, 0x22, 0xd2, + 0x43, 0x91, 0x42, 0x34, 0xda, 0x51, 0x1a, 0x81, + 0x42, 0xed, 0x09, 0x00, 0xd9, 0x02, 0x02, 0xd2, + 0x40, 0x1a, 0x2f, 0xe0, 0x7a, 0xe0, 0x01, 0x20, + 0x2c, 0xe0, 0xe1, 0x1d, 0xff, 0x31, 0x3a, 0x31, + 0x09, 0x6a, 0x64, 0x20, 0x78, 0x23, 0xd9, 0x42, + 0x01, 0xd1, 0x01, 0x20, 0x22, 0xe0, 0x3d, 0x22, + 0xb3, 0x68, 0xd2, 0x43, 0x01, 0x2b, 0x01, 0xd0, + 0x4a, 0x22, 0xd2, 0x43, 0x91, 0x42, 0x19, 0xda, + 0x51, 0x1a, 0x01, 0x2b, 0x0a, 0xd0, 0x02, 0x2b, + 0x14, 0xd1, 0x1a, 0x29, 0x00, 0xd3, 0x19, 0x21, + 0x31, 0x4a, 0x51, 0x56, 0x64, 0x29, 0x0c, 0xd2, + 0x40, 0x1a, 0x0b, 0xe0, 0x1a, 0x29, 0x00, 0xd3, + 0x19, 0x21, 0x2e, 0x4a, 0x51, 0x56, 0x64, 0x29, + 0x01, 0xd2, 0x40, 0x1a, 0x02, 0xe0, 0x01, 0x20, + 0x00, 0xe0, 0x01, 0x20, 0xe2, 0x1d, 0xff, 0x32, + 0x3a, 0x32, 0x13, 0x6a, 0x28, 0x4e, 0x6b, 0x76, + 0xe3, 0x68, 0xe9, 0x1d, 0x5b, 0x6a, 0x76, 0x6b, + 0x0d, 0x31, 0xb3, 0x42, 0x00, 0xd3, 0x33, 0x1c, + 0x24, 0x4e, 0xf3, 0x5c, 0x0b, 0x71, 0x16, 0x6a, + 0x78, 0x23, 0xde, 0x42, 0x02, 0xd0, 0x52, 0x6a, + 0xda, 0x42, 0x02, 0xd1, 0x00, 0x22, 0x8a, 0x71, + 0x07, 0xe0, 0xb2, 0x1a, 0x8a, 0x71, 0x06, 0x23, + 0xca, 0x56, 0x00, 0x2a, 0x01, 0xda, 0x00, 0x22, + 0x8a, 0x71, 0xc8, 0x71, 0xb8, 0x69, 0x09, 0x23, + 0x88, 0x61, 0x38, 0x6a, 0x9b, 0x01, 0xc8, 0x61, + 0xf8, 0x69, 0x48, 0x61, 0x78, 0x6a, 0xc8, 0x60, + 0xf8, 0x6a, 0x08, 0x61, 0xb8, 0x6a, 0x88, 0x60, + 0xe0, 0x18, 0xc2, 0x69, 0x00, 0x2a, 0x08, 0xd0, + 0x01, 0x3a, 0xc2, 0x61, 0x20, 0x1c, 0x06, 0xf0, + 0xb7, 0xfd, 0x28, 0x1c, 0xd3, 0xf7, 0xd8, 0xfb, + 0x0c, 0xe0, 0xdf, 0x20, 0x28, 0x60, 0xf8, 0x68, + 0x00, 0x22, 0xc0, 0x6a, 0xe8, 0x60, 0x38, 0x69, + 0x28, 0x61, 0x0a, 0x60, 0x05, 0x20, 0x29, 0x1c, + 0xd3, 0xf7, 0xfe, 0xfb, 0xed, 0x09, 0x00, 0xda, + 0x02, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x18, 0xec, 0x03, 0x20, 0xac, 0xb2, 0x03, + 0x20, 0x90, 0xb2, 0x03, 0x20, 0xd8, 0xeb, 0x03, + 0x20, 0x88, 0xb2, 0x03, 0x20, 0x90, 0xb5, 0x04, + 0x1c, 0xc0, 0x68, 0xfb, 0xf7, 0x39, 0xfc, 0x07, + 0x1c, 0x07, 0xd0, 0x38, 0x1c, 0x06, 0xf0, 0xb6, + 0xfa, 0x9a, 0x21, 0x38, 0x1c, 0x22, 0x69, 0xff, + 0xf7, 0xfd, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xfb, 0xf7, 0x04, + 0xfb, 0xd3, 0xf7, 0x69, 0xfb, 0x00, 0x28, 0x07, + 0xd0, 0xbe, 0x21, 0x01, 0x60, 0xf9, 0x68, 0xc1, + 0x60, 0x01, 0x1c, 0x05, 0x20, 0xd3, 0xf7, 0xce, + 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, + 0xb5, 0x83, 0xb0, 0xc4, 0x68, 0x86, 0x6a, 0x07, + 0x1c, 0x20, 0x1c, 0x9d, 0x25, 0x29, 0x1c, 0xff, + 0xf7, 0xba, 0xfb, 0x00, 0x28, 0x1e, 0xd0, 0x00, + 0x21, 0x78, 0x69, 0xfb, 0xf7, 0x2c, 0xfc, 0x78, + 0x61, 0x47, 0x2e, 0x44, 0xd0, 0x1a, 0xdc, 0x15, + 0x2e, 0x23, 0xd0, 0x18, 0x2e, 0x21, 0xd0, 0x45, + 0x2e, 0x2f, 0xd0, 0x46, 0x2e, 0x0e, 0xd1, 0x38, + 0x6a, 0x7d, 0x6a, 0xfb, 0xf7, 0x23, 0xfc, 0x02, + 0x21, 0x00, 0x91, 0x02, 0x90, 0x02, 0xaa, 0x01, + 0x92, 0x20, 0x1c, 0x06, 0x21, 0x01, 0x23, 0x2a, + 0x1c, 0x04, 0xf0, 0xed, 0xf9, 0x03, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x48, 0x2e, 0x2b, + 0xd0, 0x4b, 0x2e, 0x1f, 0xd0, 0x4c, 0x2e, 0xf5, + 0xd1, 0x20, 0x1c, 0x39, 0x1c, 0x04, 0xf0, 0x77, + 0xff, 0xf0, 0xe7, 0xe1, 0x1d, 0x1d, 0x31, 0x20, + 0x1c, 0x2a, 0x1c, 0x0e, 0x1c, 0xff, 0xf7, 0x10, + 0xfb, 0x00, 0x28, 0xe7, 0xd0, 0x20, 0x1c, 0x31, + 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0xff, 0xf7, 0x28, + 0xfb, 0xe0, 0xe7, 0x38, 0x6a, 0xfb, 0xf7, 0xed, + 0x09, 0x00, 0xdb, 0x02, 0xf6, 0xfb, 0x02, 0x1c, + 0x20, 0x1c, 0x39, 0x69, 0xfe, 0xf7, 0xfb, 0xf9, + 0xd7, 0xe7, 0x20, 0x1c, 0x39, 0x1c, 0x04, 0xf0, + 0x24, 0xff, 0xd2, 0xe7, 0x20, 0x1c, 0x39, 0x1c, + 0x04, 0xf0, 0x7d, 0xff, 0xcd, 0xe7, 0x20, 0x1c, + 0x39, 0x1c, 0x04, 0xf0, 0xad, 0xff, 0xc8, 0xe7, + 0x01, 0x1c, 0x18, 0x20, 0xc0, 0x31, 0xc9, 0x6b, + 0x4a, 0x08, 0x00, 0xd3, 0x03, 0x48, 0x89, 0x08, + 0x02, 0xd3, 0x03, 0x23, 0x9b, 0x03, 0x18, 0x43, + 0x70, 0x47, 0x18, 0x0c, 0x00, 0x00, 0xc0, 0x30, + 0x81, 0x6b, 0x00, 0x29, 0x0b, 0xd0, 0xc1, 0x6b, + 0xc9, 0x0a, 0x08, 0xd3, 0x05, 0x49, 0x49, 0x68, + 0xc9, 0x0a, 0x04, 0xd3, 0x01, 0x6a, 0x00, 0x29, + 0x01, 0xd1, 0x01, 0x21, 0x01, 0x62, 0x70, 0x47, + 0x00, 0x00, 0x78, 0xae, 0x03, 0x20, 0x80, 0xb5, + 0x83, 0xb0, 0x07, 0x1c, 0xc0, 0x30, 0x82, 0x6b, + 0x00, 0x2a, 0x30, 0xd0, 0xc0, 0x6b, 0xc0, 0x0a, + 0x2d, 0xd3, 0x88, 0x0b, 0x80, 0x07, 0x03, 0xd0, + 0x06, 0x20, 0x02, 0xab, 0x18, 0x70, 0x10, 0xe0, + 0x88, 0x0a, 0x80, 0x07, 0x03, 0xd0, 0x04, 0x20, + 0x02, 0xab, 0x18, 0x70, 0x09, 0xe0, 0xc8, 0x08, + 0x80, 0x07, 0x03, 0xd0, 0x02, 0x20, 0x02, 0xab, + 0x18, 0x70, 0x02, 0xe0, 0x00, 0x20, 0x02, 0xab, + 0x18, 0x70, 0x0c, 0x48, 0x08, 0x40, 0x05, 0xd0, + 0x02, 0xa8, 0x00, 0x78, 0x01, 0x23, 0x18, 0x43, + 0x02, 0xab, 0x18, 0x70, 0x38, 0x1c, 0x03, 0xf0, + 0x4d, 0xff, 0x01, 0x21, 0x02, 0xaa, 0x01, 0x92, + 0x00, 0x91, 0x24, 0x21, 0x02, 0x1c, 0x01, 0x23, + 0x38, 0x1c, 0x04, 0xf0, 0x5b, 0xf9, 0x03, 0xb0, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x88, + 0x00, 0x00, 0xb0, 0xb5, 0x00, 0x27, 0x01, 0x23, + 0x9b, 0x02, 0x04, 0x1c, 0xc0, 0x18, 0xc0, 0x6b, + 0x0d, 0x1c, 0xed, 0x09, 0x00, 0xdc, 0x02, 0x00, + 0x28, 0x0e, 0xd0, 0xd3, 0xf7, 0x8d, 0xfa, 0x00, + 0x28, 0x01, 0xd1, 0x07, 0x27, 0x08, 0xe0, 0x65, + 0x21, 0x01, 0x60, 0x21, 0x6b, 0xc1, 0x60, 0x05, + 0x61, 0x01, 0x1c, 0x07, 0x20, 0xd3, 0xf7, 0xef, + 0xfa, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x00, 0x27, 0x0c, 0x1c, 0x15, + 0x1c, 0x06, 0x1c, 0xd3, 0xf7, 0x75, 0xfa, 0x00, + 0x28, 0x01, 0xd1, 0x07, 0x27, 0x0c, 0xe0, 0x04, + 0x2c, 0x00, 0xd2, 0x02, 0x24, 0x62, 0x21, 0x01, + 0x60, 0x31, 0x6b, 0x0c, 0x30, 0x32, 0xc0, 0x18, + 0x38, 0x01, 0x1c, 0x07, 0x20, 0xd3, 0xf7, 0xd3, + 0xfa, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x00, 0x27, 0x14, 0x1c, 0x0d, + 0x1c, 0x06, 0x1c, 0xd3, 0xf7, 0x59, 0xfa, 0x00, + 0x28, 0x01, 0xd1, 0x07, 0x27, 0x09, 0xe0, 0x5d, + 0x21, 0x01, 0x60, 0x31, 0x6b, 0xc1, 0x60, 0x05, + 0x61, 0x44, 0x61, 0x01, 0x1c, 0x07, 0x20, 0xd3, + 0xf7, 0xba, 0xfa, 0x38, 0x1c, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x00, 0x27, 0x11, + 0x23, 0x9b, 0x01, 0xc6, 0x18, 0x04, 0x1c, 0x0d, + 0x1c, 0x00, 0x2a, 0x05, 0xd0, 0x30, 0x6a, 0x01, + 0x30, 0x30, 0x62, 0x01, 0x28, 0x23, 0xd1, 0x07, + 0xe0, 0x30, 0x6a, 0x00, 0x28, 0x01, 0xd0, 0x01, + 0x38, 0x30, 0x62, 0x30, 0x6a, 0x00, 0x28, 0x1a, + 0xd1, 0xd3, 0xf7, 0x2e, 0xfa, 0x00, 0x28, 0x01, + 0xd1, 0x07, 0x27, 0x14, 0xe0, 0x63, 0x21, 0x01, + 0x60, 0x21, 0x6b, 0xc1, 0x60, 0x05, 0x61, 0xf1, + 0x69, 0x41, 0x61, 0x71, 0x68, 0x81, 0x61, 0xb1, + 0x68, 0xc1, 0x61, 0xf1, 0x68, 0x01, 0x62, 0x71, + 0x69, 0x41, 0x62, 0x31, 0x69, 0x81, 0x62, 0x01, + 0x1c, 0x07, 0x20, 0xd3, 0xf7, 0x84, 0xfa, 0x38, + 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0xed, 0x09, 0x00, + 0xdd, 0x02, 0x18, 0x47, 0x07, 0x48, 0x00, 0x6b, + 0x00, 0x28, 0x09, 0xd0, 0x04, 0xe0, 0x00, 0x29, + 0x02, 0xd0, 0x02, 0x69, 0x8a, 0x42, 0x03, 0xd1, + 0x01, 0x69, 0x00, 0x68, 0x00, 0x28, 0xf6, 0xd1, + 0x70, 0x47, 0x00, 0x00, 0xb8, 0xad, 0x03, 0x20, + 0xb0, 0xb5, 0x00, 0x27, 0x04, 0x1c, 0x0d, 0x1c, + 0xd3, 0xf7, 0xf9, 0xf9, 0x00, 0x28, 0x01, 0xd1, + 0x07, 0x27, 0x18, 0xe0, 0x61, 0x21, 0x01, 0x60, + 0x21, 0x6b, 0x00, 0x2d, 0xc1, 0x60, 0x03, 0xd0, + 0x00, 0x21, 0x01, 0x61, 0x41, 0x61, 0x0a, 0xe0, + 0xe1, 0x1d, 0xb9, 0x31, 0xca, 0x68, 0x00, 0x2a, + 0x01, 0xd0, 0x02, 0x61, 0x01, 0xe0, 0x04, 0x22, + 0x02, 0x61, 0x09, 0x69, 0x41, 0x61, 0x01, 0x1c, + 0x07, 0x20, 0xd3, 0xf7, 0x4b, 0xfa, 0x38, 0x1c, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, + 0x07, 0x1c, 0x0d, 0x1c, 0xf9, 0x1d, 0xff, 0x31, + 0x00, 0x20, 0x00, 0x24, 0xba, 0x31, 0x08, 0x61, + 0xd3, 0xf7, 0xcd, 0xf9, 0x00, 0x28, 0x14, 0xd0, + 0xbb, 0x21, 0x01, 0x60, 0xfe, 0x1d, 0x9d, 0x36, + 0x0c, 0xce, 0xc1, 0x1d, 0x05, 0x31, 0x0c, 0xc1, + 0x45, 0x61, 0x39, 0x69, 0x01, 0x29, 0x02, 0xd1, + 0x00, 0x21, 0x81, 0x61, 0x01, 0xe0, 0x01, 0x21, + 0x81, 0x61, 0x01, 0x1c, 0x05, 0x20, 0xd3, 0xf7, + 0x25, 0xfa, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xff, 0xb5, 0x87, 0xb0, 0x07, 0x1c, + 0xff, 0x20, 0x1c, 0x1c, 0x0b, 0x23, 0x9b, 0x01, + 0x0d, 0x1c, 0xf9, 0x18, 0xc9, 0x69, 0x49, 0x00, + 0x21, 0x30, 0x20, 0x29, 0x01, 0xd3, 0xc8, 0x1d, + 0xf9, 0x30, 0x46, 0x00, 0x04, 0xa8, 0xfa, 0xf7, + 0xbb, 0xfc, 0x28, 0x1c, 0x31, 0x1c, 0xfb, 0xf7, + 0x7a, 0xfa, 0xfd, 0x1d, 0xb9, 0x35, 0xe8, 0x60, + 0x00, 0x28, 0x01, 0xd1, 0x04, 0x20, 0xe8, 0x60, + 0xed, 0x09, 0x00, 0xde, 0x02, 0x01, 0x22, 0x21, + 0x1c, 0x09, 0x98, 0xe3, 0xf7, 0xe9, 0xfa, 0x21, + 0xa3, 0x1a, 0x68, 0x5b, 0x68, 0xe3, 0xf7, 0x38, + 0xfb, 0x10, 0x1c, 0x19, 0x1c, 0x00, 0x2a, 0x06, + 0x92, 0x03, 0xda, 0x1e, 0x49, 0x40, 0x42, 0x08, + 0x1a, 0x06, 0x90, 0x09, 0x23, 0x9b, 0x01, 0x38, + 0x69, 0xfe, 0x18, 0x02, 0x28, 0x0f, 0xd1, 0x04, + 0xaa, 0x03, 0x92, 0x06, 0x21, 0x02, 0x91, 0x02, + 0x22, 0x06, 0xa8, 0x01, 0x90, 0x00, 0x92, 0x34, + 0x21, 0x02, 0x23, 0x38, 0x1c, 0xf2, 0x6b, 0x04, + 0xf0, 0x28, 0xf8, 0x04, 0x1c, 0x11, 0xd1, 0xe8, + 0x68, 0x40, 0x08, 0x03, 0x90, 0x00, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0x64, 0xff, 0x04, 0x21, 0x00, + 0x91, 0x03, 0xaa, 0x01, 0x92, 0x13, 0x21, 0x01, + 0x23, 0x38, 0x1c, 0xf2, 0x6b, 0x04, 0xf0, 0x15, + 0xf8, 0x04, 0x1c, 0xf9, 0x1d, 0xff, 0x31, 0x1e, + 0x31, 0x38, 0x1c, 0x07, 0x4a, 0xfd, 0xf7, 0x30, + 0xfe, 0x20, 0x1c, 0x0b, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe2, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00, + 0x00, 0x6d, 0xb3, 0x02, 0x20, 0x90, 0xb5, 0x83, + 0xb0, 0x07, 0x1c, 0x00, 0x69, 0x0c, 0x1c, 0x01, + 0x28, 0x1b, 0xd1, 0x00, 0x20, 0x02, 0x90, 0x01, + 0x90, 0xe0, 0x69, 0x41, 0x1c, 0x68, 0x46, 0x04, + 0x22, 0xd2, 0xf7, 0x9a, 0xfd, 0x00, 0xa8, 0x00, + 0x88, 0xf9, 0x1d, 0xb9, 0x31, 0x08, 0x61, 0xe0, + 0x69, 0x01, 0xab, 0x41, 0x79, 0x99, 0x70, 0x01, + 0x79, 0x59, 0x70, 0xc1, 0x78, 0x19, 0x70, 0xe0, + 0x69, 0x01, 0x7a, 0x59, 0x71, 0xc1, 0x79, 0x02, + 0xab, 0x19, 0x70, 0x03, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x80, 0xb5, 0x07, + 0x1c, 0xc8, 0x69, 0x00, 0x78, 0xc0, 0x07, 0xc0, + 0x0f, 0x09, 0x23, 0xed, 0x09, 0x00, 0xdf, 0x02, + 0x9b, 0x01, 0xfa, 0x18, 0xd0, 0x63, 0xc8, 0x69, + 0x04, 0x22, 0x41, 0x1c, 0xf8, 0x1d, 0xc5, 0x30, + 0xd2, 0xf7, 0x71, 0xfd, 0xf8, 0x1d, 0xb9, 0x30, + 0xc1, 0x68, 0x49, 0x00, 0xc1, 0x60, 0x00, 0x21, + 0x38, 0x1c, 0x7a, 0x6a, 0xfb, 0xf7, 0xcb, 0xf9, + 0x80, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0xb0, 0xb5, 0x87, 0xb0, 0x07, 0x1c, 0x48, 0x69, + 0x0c, 0x1c, 0xf9, 0x1d, 0xb9, 0x31, 0xc9, 0x68, + 0x08, 0x1a, 0x09, 0x23, 0x9b, 0x01, 0xfd, 0x18, + 0x20, 0x28, 0x44, 0xdd, 0x38, 0x69, 0x02, 0x28, + 0x27, 0xd1, 0x04, 0xa8, 0xfa, 0xf7, 0x05, 0xfc, + 0xa0, 0x69, 0xe1, 0x69, 0x01, 0x22, 0xe3, 0xf7, + 0x3e, 0xfa, 0x00, 0x90, 0x01, 0x91, 0x28, 0xa3, + 0x1a, 0x68, 0x5b, 0x68, 0xe3, 0xf7, 0x8b, 0xfa, + 0x10, 0x1c, 0x19, 0x1c, 0x00, 0x2a, 0x02, 0x92, + 0x03, 0x93, 0x06, 0x92, 0x03, 0xda, 0x24, 0x49, + 0x40, 0x42, 0x08, 0x1a, 0x06, 0x90, 0x04, 0xaa, + 0x03, 0x92, 0x06, 0x21, 0x02, 0x91, 0x02, 0x22, + 0x06, 0xa8, 0x01, 0x90, 0x00, 0x92, 0x34, 0x21, + 0x02, 0x23, 0x38, 0x1c, 0xea, 0x6b, 0x03, 0xf0, + 0x7f, 0xff, 0xf8, 0x1d, 0xff, 0x30, 0x3a, 0x30, + 0x40, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x14, 0x24, + 0x0a, 0xe0, 0x00, 0x21, 0x38, 0x1c, 0xff, 0xf7, + 0xb8, 0xfe, 0x38, 0x1c, 0x13, 0x22, 0xe9, 0x6b, + 0x15, 0xa3, 0x03, 0xf0, 0xe2, 0xff, 0x91, 0x24, + 0x05, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x81, 0x6a, + 0x01, 0x31, 0x81, 0x62, 0x08, 0xe0, 0x0f, 0xa2, + 0x00, 0x92, 0x13, 0x22, 0x28, 0x23, 0x38, 0x1c, + 0xe9, 0x6b, 0x03, 0xf0, 0xe1, 0xff, 0x1d, 0x24, + 0xf9, 0x1d, 0x1d, 0x31, 0x00, 0x23, 0x38, 0x1c, + 0x22, 0x1c, 0xff, 0xf7, 0xae, 0xf8, 0x00, 0x22, + 0x38, 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0xed, 0x09, + 0x00, 0xe0, 0x02, 0x1f, 0xf9, 0x07, 0xb0, 0xb0, + 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0xe2, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, + 0x04, 0x00, 0x00, 0x4c, 0x6d, 0x52, 0x6f, 0x6c, + 0x65, 0x53, 0x75, 0x62, 0x53, 0x74, 0x49, 0x64, + 0x6c, 0x65, 0x49, 0x6e, 0x64, 0x53, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x00, 0x90, + 0xb5, 0x00, 0x24, 0x07, 0x1c, 0x03, 0xf0, 0x1a, + 0xfd, 0x09, 0x23, 0x9b, 0x01, 0xf9, 0x18, 0x05, + 0x23, 0xdb, 0x01, 0xc8, 0x63, 0xf8, 0x18, 0x81, + 0x6a, 0x01, 0x31, 0x81, 0x62, 0xf8, 0x1d, 0xff, + 0x30, 0x3a, 0x30, 0x40, 0x68, 0x00, 0x28, 0x02, + 0xd0, 0x14, 0x20, 0x78, 0x62, 0x05, 0xe0, 0x15, + 0x22, 0x00, 0x21, 0x38, 0x1c, 0x7a, 0x62, 0xfb, + 0xf7, 0x28, 0xf9, 0x20, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xcb, 0x1d, 0x11, + 0x33, 0x1a, 0x68, 0x49, 0x69, 0x5b, 0x68, 0xff, + 0xf7, 0x9f, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x00, 0x21, 0x42, 0x6a, 0xfb, 0xf7, 0x15, + 0xf9, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x80, + 0xb5, 0x00, 0x21, 0x07, 0x1c, 0xff, 0xf7, 0x43, + 0xfe, 0x00, 0x23, 0x91, 0x22, 0x38, 0x1c, 0xf9, + 0x1d, 0x1d, 0x31, 0xff, 0xf7, 0x50, 0xf8, 0x80, + 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0xb5, 0xc1, 0x1d, 0xff, 0x31, 0x1e, 0x31, 0xfd, + 0xf7, 0xf8, 0xfc, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x80, 0xb5, 0x00, 0x21, 0x07, 0x1c, 0xff, + 0xf7, 0x2a, 0xfe, 0x09, 0x23, 0x9b, 0x01, 0xf8, + 0x18, 0xc1, 0x6b, 0x38, 0x1c, 0x13, 0x22, 0x03, + 0xa3, 0x03, 0xf0, 0x51, 0xff, 0x80, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, 0x4c, + 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x75, 0x62, + 0x53, 0xed, 0x09, 0x00, 0xe1, 0x02, 0x74, 0x52, + 0x6f, 0x6c, 0x65, 0x53, 0x77, 0x69, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x4c, 0x32, 0x43, + 0x41, 0x50, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, + 0x71, 0x4c, 0x32, 0x43, 0x41, 0x50, 0x47, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0x01, 0x29, + 0x02, 0xd1, 0x02, 0x21, 0x01, 0x61, 0x03, 0xe0, + 0x02, 0x29, 0x01, 0xd1, 0x01, 0x21, 0x01, 0x61, + 0x00, 0x20, 0x70, 0x47, 0x00, 0xb5, 0xc2, 0x1d, + 0xff, 0x32, 0xba, 0x32, 0x12, 0x69, 0x00, 0x2a, + 0x03, 0xd0, 0xff, 0xf7, 0x16, 0xfe, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0xf0, 0x19, 0xff, 0x00, 0x20, + 0xf9, 0xe7, 0x00, 0xb5, 0xff, 0xf7, 0xee, 0xff, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x82, 0xb0, + 0x04, 0x1c, 0xc0, 0x30, 0x01, 0x90, 0x40, 0x69, + 0x00, 0x27, 0x0d, 0x1c, 0x00, 0x28, 0x03, 0xd0, + 0x03, 0xf0, 0x2e, 0xff, 0x00, 0x28, 0x10, 0xd0, + 0x0a, 0xa2, 0x00, 0x92, 0x13, 0x22, 0x1d, 0x26, + 0x21, 0x27, 0x20, 0x1c, 0x29, 0x1c, 0x3b, 0x1c, + 0x03, 0xf0, 0x0b, 0xff, 0x01, 0x98, 0x00, 0x22, + 0x40, 0x69, 0x20, 0x1c, 0x31, 0x1c, 0xff, 0xf7, + 0x4f, 0xf8, 0x38, 0x1c, 0x02, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x52, 0x6f, + 0x6c, 0x65, 0x53, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x49, 0x6e, 0x64, 0x53, 0x77, + 0x69, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x00, + 0x90, 0xb5, 0x01, 0x21, 0x07, 0x1c, 0xff, 0xf7, + 0xad, 0xfd, 0x00, 0x23, 0xa1, 0x22, 0x38, 0x1c, + 0xf9, 0x1d, 0x1d, 0x31, 0xfe, 0xf7, 0xba, 0xff, + 0x04, 0x1c, 0x0e, 0xd1, 0x38, 0x1c, 0x33, 0x22, + 0x00, 0x21, 0x08, 0xa3, 0x03, 0xf0, 0xce, 0xfe, + 0x04, 0x1c, 0x38, 0x1c, 0xfe, 0xf7, 0x52, 0xff, + 0x01, 0x1c, 0x00, 0x22, 0xed, 0x09, 0x00, 0xe2, + 0x02, 0x38, 0x1c, 0xff, 0xf7, 0x1f, 0xf8, 0x20, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x4c, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x53, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x49, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x00, 0x00, 0x00, 0x90, 0xb5, 0x01, + 0x21, 0x07, 0x1c, 0xff, 0xf7, 0x79, 0xfd, 0x38, + 0x1c, 0x33, 0x22, 0x00, 0x21, 0x07, 0xa3, 0x03, + 0xf0, 0xa3, 0xfe, 0x04, 0x1c, 0x38, 0x1c, 0xfe, + 0xf7, 0x27, 0xff, 0x01, 0x1c, 0x00, 0x22, 0x38, + 0x1c, 0xfe, 0xf7, 0xf4, 0xff, 0x20, 0x1c, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x52, + 0x6f, 0x6c, 0x65, 0x53, 0x74, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x64, 0x49, + 0x6e, 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, + 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x00, 0x90, 0xb5, 0x07, 0x1c, 0x33, 0x22, 0x00, + 0x21, 0x07, 0xa3, 0x03, 0xf0, 0x79, 0xfe, 0x04, + 0x1c, 0x38, 0x1c, 0xfe, 0xf7, 0xfd, 0xfe, 0x01, + 0x1c, 0x00, 0x22, 0x38, 0x1c, 0xfe, 0xf7, 0xca, + 0xff, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x4c, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x53, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x49, 0x6e, 0x64, 0x49, 0x6e, 0x64, 0x42, 0x42, + 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x4f, 0x6b, + 0x00, 0xf0, 0xb5, 0x82, 0xb0, 0x04, 0x1c, 0xc0, + 0x30, 0x01, 0x90, 0x80, 0x69, 0x00, 0x27, 0x0d, + 0x1c, 0x40, 0x08, 0x03, 0xd3, 0x03, 0xf0, 0x72, + 0xfe, 0x00, 0x28, 0x12, 0xd0, 0x0b, 0xa2, 0xed, + 0x09, 0x00, 0xe3, 0x02, 0x00, 0x92, 0x13, 0x22, + 0x1d, 0x26, 0x21, 0x27, 0x20, 0x1c, 0x29, 0x1c, + 0x3b, 0x1c, 0x03, 0xf0, 0x4f, 0xfe, 0x01, 0x98, + 0x80, 0x69, 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0x22, + 0x20, 0x1c, 0x31, 0x1c, 0xfe, 0xf7, 0x91, 0xff, + 0x38, 0x1c, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x4c, 0x6d, 0x52, 0x6f, 0x6c, 0x65, + 0x53, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x53, 0x77, + 0x69, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x00, + 0x00, 0x00, 0xb0, 0xb5, 0x0d, 0x1c, 0x01, 0x21, + 0x00, 0x24, 0x07, 0x1c, 0xff, 0xf7, 0xeb, 0xfc, + 0xf8, 0x1d, 0xff, 0x30, 0xba, 0x30, 0x00, 0x69, + 0x00, 0x28, 0x04, 0xd0, 0x38, 0x1c, 0x29, 0x1c, + 0xff, 0xf7, 0x08, 0xfd, 0x04, 0x1c, 0x38, 0x1c, + 0x03, 0xf0, 0x5f, 0xfb, 0x00, 0x21, 0x38, 0x1c, + 0x01, 0xf0, 0x07, 0xfe, 0x20, 0x1c, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x00, 0x24, + 0x01, 0x21, 0x07, 0x1c, 0xff, 0xf7, 0xcf, 0xfc, + 0xf8, 0x1d, 0xff, 0x30, 0xba, 0x30, 0x00, 0x69, + 0x00, 0x28, 0x04, 0xd0, 0x22, 0x21, 0x38, 0x1c, + 0xff, 0xf7, 0xec, 0xfc, 0x04, 0x1c, 0x38, 0x1c, + 0x03, 0xf0, 0x43, 0xfb, 0x00, 0x21, 0x38, 0x1c, + 0x01, 0xf0, 0xeb, 0xfd, 0x20, 0x1c, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, 0x1c, + 0x00, 0x69, 0xfa, 0xf7, 0x70, 0xff, 0x07, 0x1c, + 0x2b, 0xd0, 0x65, 0x69, 0x00, 0x2d, 0x01, 0xd1, + 0x9b, 0x26, 0x00, 0xe0, 0x9c, 0x26, 0x00, 0x22, + 0x38, 0x1c, 0x31, 0x1c, 0xfe, 0xf7, 0x31, 0xff, + 0x00, 0x28, 0x1e, 0xd1, 0xf9, 0x1d, 0x1d, 0x31, + 0x00, 0x23, 0x38, 0x1c, 0x32, 0x1c, 0xfe, 0xf7, + 0xb2, 0xfe, 0x00, 0x28, 0x15, 0xd1, 0x00, 0x2d, + 0x02, 0xd1, 0xed, 0x09, 0x00, 0xe4, 0x02, 0xe0, + 0x68, 0x38, 0x63, 0x05, 0xe0, 0xf8, 0x1d, 0xff, + 0x30, 0xba, 0x30, 0x00, 0x69, 0x00, 0x28, 0x03, + 0xd0, 0x38, 0x1c, 0x29, 0x1c, 0xff, 0xf7, 0xb4, + 0xfc, 0x38, 0x1c, 0x03, 0xf0, 0x0c, 0xfb, 0x00, + 0x21, 0x38, 0x1c, 0x01, 0xf0, 0xb4, 0xfd, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x05, 0x48, 0x00, + 0x6b, 0x00, 0x28, 0x05, 0xd0, 0x41, 0x6a, 0x00, + 0x29, 0x02, 0xd1, 0x00, 0x68, 0x00, 0x28, 0xf9, + 0xd1, 0x70, 0x47, 0xb8, 0xad, 0x03, 0x20, 0xf0, + 0xb5, 0x00, 0x27, 0x14, 0x1c, 0x0d, 0x1c, 0x06, + 0x1c, 0xd2, 0xf7, 0x6e, 0xfe, 0x00, 0x28, 0x01, + 0xd1, 0x07, 0x27, 0x09, 0xe0, 0xba, 0x21, 0x01, + 0x60, 0xf1, 0x6a, 0x01, 0x61, 0x44, 0x61, 0xc5, + 0x60, 0x01, 0x1c, 0x05, 0x20, 0xd2, 0xf7, 0xcf, + 0xfe, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xb0, 0xb5, 0x04, 0x1c, 0xff, 0x30, 0xc1, + 0x30, 0x0d, 0x1c, 0x81, 0x68, 0x00, 0x27, 0x00, + 0x29, 0x10, 0xd0, 0x00, 0x21, 0x81, 0x60, 0xd2, + 0xf7, 0x4f, 0xfe, 0x00, 0x28, 0x01, 0xd1, 0x07, + 0x27, 0x08, 0xe0, 0xb9, 0x21, 0x01, 0x60, 0xc5, + 0x60, 0xe1, 0x6a, 0x01, 0x61, 0x01, 0x1c, 0x05, + 0x20, 0xd2, 0xf7, 0xb1, 0xfe, 0x20, 0x1c, 0x29, + 0x1c, 0xfc, 0xf7, 0x07, 0xfa, 0x38, 0x1c, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, 0x85, + 0xb0, 0x07, 0x1c, 0xf9, 0x1d, 0xff, 0x31, 0xba, + 0x31, 0x02, 0x20, 0x00, 0x24, 0x09, 0x23, 0x48, + 0x63, 0x06, 0x99, 0x9b, 0x01, 0xf8, 0x18, 0x01, + 0x63, 0xf9, 0x1d, 0x9d, 0x31, 0xfd, 0x23, 0x9b, + 0x00, 0x40, 0x48, 0xfe, 0x1d, 0xff, 0x36, 0xc0, + 0x6b, 0x7a, 0x36, 0xfd, 0x18, 0x01, 0x28, 0x04, + 0x91, 0x31, 0xd1, 0x10, 0x20, 0x29, 0x1c, 0xfa, + 0xf7, 0x80, 0xfe, 0x70, 0x68, 0xed, 0x09, 0x00, + 0xe5, 0x02, 0x00, 0x28, 0x15, 0xd0, 0x10, 0x21, + 0x00, 0x91, 0x08, 0x21, 0x01, 0x23, 0x38, 0x1c, + 0x01, 0x95, 0x06, 0x9a, 0x03, 0xf0, 0xcb, 0xfc, + 0x00, 0x22, 0x1e, 0x21, 0x38, 0x1c, 0xfe, 0xf7, + 0x59, 0xfe, 0x04, 0x1c, 0x01, 0xd0, 0x0c, 0x24, + 0x58, 0xe0, 0x38, 0x1c, 0xfd, 0xf7, 0x9e, 0xfa, + 0x54, 0xe0, 0xd2, 0xf7, 0x00, 0xfe, 0x05, 0x1c, + 0x50, 0xd0, 0x00, 0x22, 0x1b, 0x21, 0x38, 0x1c, + 0xfe, 0xf7, 0x48, 0xfe, 0xce, 0x20, 0x28, 0x60, + 0x04, 0x99, 0xe8, 0x1d, 0x88, 0xc9, 0x05, 0x30, + 0x88, 0xc0, 0x05, 0x20, 0x29, 0x1c, 0xd2, 0xf7, + 0x5d, 0xfe, 0x3f, 0xe0, 0x11, 0x1c, 0x10, 0x22, + 0x28, 0x1c, 0xd2, 0xf7, 0x4f, 0xfa, 0x70, 0x68, + 0x00, 0x28, 0x23, 0xd0, 0x38, 0x1c, 0x08, 0x22, + 0x06, 0x99, 0x1e, 0xa3, 0x03, 0xf0, 0x10, 0xfd, + 0x00, 0x28, 0x04, 0xd1, 0x00, 0x22, 0x23, 0x21, + 0x38, 0x1c, 0xfe, 0xf7, 0x27, 0xfe, 0x02, 0xa8, + 0xfa, 0xf7, 0xf2, 0xf8, 0xb2, 0x69, 0xf9, 0x1d, + 0xff, 0x31, 0xf8, 0x1d, 0xff, 0x30, 0x82, 0x31, + 0x00, 0x91, 0x6e, 0x30, 0x01, 0x92, 0x02, 0x9a, + 0x29, 0x1c, 0x03, 0x9b, 0xfb, 0xf7, 0x51, 0xfc, + 0xf9, 0x1d, 0xff, 0x31, 0x01, 0x20, 0x3a, 0x31, + 0xc8, 0x62, 0x13, 0xe0, 0xd2, 0xf7, 0xbf, 0xfd, + 0x05, 0x1c, 0x0f, 0xd0, 0x00, 0x22, 0x1a, 0x21, + 0x38, 0x1c, 0xfe, 0xf7, 0x07, 0xfe, 0xce, 0x20, + 0x28, 0x60, 0x04, 0x99, 0xe8, 0x1d, 0x88, 0xc9, + 0x05, 0x30, 0x88, 0xc0, 0x05, 0x20, 0x29, 0x1c, + 0xd2, 0xf7, 0x1c, 0xfe, 0x20, 0x1c, 0x08, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0xf8, 0xad, 0x03, 0x20, 0x4c, 0x6d, 0x50, 0x61, + 0x69, 0x72, 0x49, 0x6e, 0x64, 0x49, 0x6e, 0x52, + 0x61, 0x6e, 0x64, 0x00, 0x88, 0xb5, 0x07, 0x1c, + 0xed, 0x09, 0x00, 0xe6, 0x02, 0xfa, 0x1d, 0xff, + 0x32, 0x3a, 0x32, 0xd2, 0x6a, 0x00, 0x20, 0x00, + 0x2a, 0x05, 0xd0, 0xfa, 0x1d, 0xff, 0x32, 0x7a, + 0x32, 0x53, 0x6b, 0x00, 0x2b, 0x0f, 0xd0, 0x10, + 0xa2, 0x00, 0x92, 0x09, 0x22, 0x24, 0x23, 0x38, + 0x1c, 0x03, 0xf0, 0xc7, 0xfc, 0x00, 0x22, 0x25, + 0x21, 0x38, 0x1c, 0xfe, 0xf7, 0xd1, 0xfd, 0x24, + 0x20, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd2, + 0x69, 0x00, 0x2a, 0xf9, 0xd0, 0x06, 0xa2, 0x00, + 0x92, 0x09, 0x22, 0x26, 0x23, 0x38, 0x1c, 0x03, + 0xf0, 0xb4, 0xfc, 0x00, 0x22, 0x25, 0x21, 0x38, + 0x1c, 0xfe, 0xf7, 0xbe, 0xfd, 0x26, 0x20, 0xeb, + 0xe7, 0x4c, 0x6d, 0x50, 0x61, 0x69, 0x72, 0x49, + 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, + 0x65, 0x4b, 0x65, 0x79, 0x00, 0xf0, 0xb5, 0x88, + 0xb0, 0x07, 0x1c, 0x02, 0xa8, 0xfa, 0xf7, 0x7a, + 0xf8, 0xf8, 0x1d, 0xff, 0x30, 0x7a, 0x30, 0xf9, + 0x1d, 0xff, 0x31, 0x82, 0x69, 0x82, 0x31, 0xfd, + 0x23, 0x9b, 0x00, 0x00, 0x91, 0xf9, 0x18, 0xf8, + 0x1d, 0xff, 0x30, 0x01, 0x92, 0x02, 0x9a, 0x6e, + 0x30, 0x03, 0x9b, 0xfb, 0xf7, 0xd4, 0xfb, 0xf9, + 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x01, 0x20, 0x15, + 0x23, 0x9b, 0x01, 0xc8, 0x62, 0x22, 0x48, 0xfc, + 0x1d, 0xc5, 0x18, 0x29, 0x69, 0xff, 0x34, 0x9e, + 0x34, 0x00, 0x29, 0x0a, 0xd0, 0x1f, 0x4b, 0x04, + 0xae, 0xc1, 0x18, 0x08, 0x1c, 0x0c, 0xc9, 0x0c, + 0xc6, 0x0c, 0xc9, 0x0c, 0xc6, 0x4e, 0xc8, 0x4e, + 0xc4, 0x0c, 0xe0, 0x10, 0x20, 0x04, 0xa9, 0xfa, + 0xf7, 0x91, 0xfd, 0x02, 0xa8, 0xfa, 0xf7, 0x46, + 0xf8, 0x02, 0x9a, 0x03, 0x9b, 0x20, 0x1c, 0x04, + 0xa9, 0xfb, 0xf7, 0x84, 0xfb, 0x00, 0x20, 0x3a, + 0x18, 0xff, 0x32, 0x71, 0x32, 0x04, 0xa9, 0x09, + 0x5c, 0x12, 0x79, 0xed, 0x09, 0x00, 0xe7, 0x02, + 0x51, 0x40, 0x04, 0xaa, 0x11, 0x54, 0x01, 0x30, + 0x10, 0x28, 0xf3, 0xd3, 0x10, 0x21, 0x09, 0x23, + 0x9b, 0x01, 0xf8, 0x18, 0x00, 0x91, 0x01, 0x92, + 0x02, 0x6b, 0x28, 0x69, 0x0a, 0x21, 0x00, 0x28, + 0x00, 0xd1, 0x09, 0x21, 0x01, 0x23, 0x38, 0x1c, + 0x03, 0xf0, 0xc2, 0xfb, 0x04, 0x1c, 0x38, 0x1c, + 0xfd, 0xf7, 0x9d, 0xf9, 0x20, 0x1c, 0x08, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb8, 0xa8, + 0x03, 0x20, 0x54, 0x05, 0x00, 0x00, 0xf7, 0xb5, + 0x8e, 0xb0, 0x07, 0x1c, 0xfd, 0xf7, 0x77, 0xf9, + 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x4c, 0xba, 0x31, + 0x02, 0x20, 0x48, 0x63, 0xfd, 0x1d, 0xff, 0x35, + 0x20, 0x69, 0xe6, 0x1d, 0x0d, 0x36, 0x9e, 0x35, + 0x00, 0x28, 0x06, 0xd0, 0x30, 0x1c, 0x0c, 0xc8, + 0x02, 0xa9, 0x0c, 0xc1, 0x0c, 0xc8, 0x0c, 0xc1, + 0x0c, 0xe0, 0x10, 0x20, 0x02, 0xa9, 0xfa, 0xf7, + 0x40, 0xfd, 0x68, 0x46, 0xf9, 0xf7, 0xf5, 0xff, + 0x00, 0x9a, 0x01, 0x9b, 0x28, 0x1c, 0x02, 0xa9, + 0xfb, 0xf7, 0x33, 0xfb, 0x00, 0x20, 0x3a, 0x18, + 0xff, 0x32, 0x71, 0x32, 0x02, 0xa9, 0x09, 0x5c, + 0x12, 0x79, 0x51, 0x40, 0x02, 0xaa, 0x11, 0x54, + 0x01, 0x30, 0x10, 0x28, 0xf3, 0xd3, 0x10, 0x21, + 0x09, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x00, 0x91, + 0x01, 0x92, 0x02, 0x6b, 0x20, 0x69, 0x0a, 0x21, + 0x00, 0x28, 0x00, 0xd1, 0x09, 0x21, 0x01, 0x23, + 0x38, 0x1c, 0x03, 0xf0, 0x71, 0xfb, 0x38, 0x1c, + 0xfd, 0xf7, 0x4d, 0xf9, 0x20, 0x69, 0xfc, 0x1d, + 0xff, 0x34, 0x7a, 0x34, 0x00, 0x28, 0x04, 0xd0, + 0x4d, 0xce, 0x4d, 0xc5, 0x01, 0x20, 0xe0, 0x61, + 0x22, 0xe0, 0x00, 0x20, 0x3a, 0x18, 0xff, 0x32, + 0x0f, 0x99, 0x71, 0x32, 0x12, 0x79, 0x09, 0x5c, + 0x51, 0x40, 0x06, 0xaa, 0x11, 0x54, 0xed, 0x09, + 0x00, 0xe8, 0x02, 0x01, 0x30, 0x10, 0x28, 0xf3, + 0xd3, 0xfb, 0x1d, 0x9d, 0x33, 0x1a, 0x68, 0x5b, + 0x68, 0x0a, 0xa8, 0x06, 0xa9, 0xfb, 0xf7, 0xf3, + 0xfa, 0x00, 0x20, 0x39, 0x18, 0xff, 0x31, 0xa1, + 0x31, 0x0a, 0xaa, 0x12, 0x5c, 0x0b, 0x79, 0x5a, + 0x40, 0x01, 0x30, 0x10, 0x28, 0x0a, 0x71, 0xf4, + 0xd3, 0x00, 0x20, 0xe0, 0x61, 0x01, 0x20, 0x20, + 0x62, 0x11, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0xf8, 0xad, 0x03, 0x20, 0x80, + 0xb5, 0x0a, 0x1c, 0xc9, 0x69, 0x09, 0x78, 0xc9, + 0x07, 0xc9, 0x0f, 0xc7, 0x1d, 0xff, 0x37, 0x7a, + 0x37, 0x00, 0x23, 0x7b, 0x60, 0xd2, 0x69, 0x01, + 0x32, 0xff, 0xf7, 0x32, 0xfe, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x86, 0xb0, 0x07, + 0x1c, 0xf9, 0x1d, 0xff, 0x31, 0xba, 0x31, 0x01, + 0x20, 0x48, 0x63, 0x38, 0x1c, 0x03, 0xf0, 0x02, + 0xf9, 0x09, 0x23, 0x9b, 0x01, 0xfc, 0x18, 0x20, + 0x63, 0x10, 0x20, 0x02, 0xa9, 0xfa, 0xf7, 0xbb, + 0xfc, 0x68, 0x46, 0xf9, 0xf7, 0x70, 0xff, 0xf8, + 0x1d, 0xff, 0x30, 0x9e, 0x30, 0x00, 0x9a, 0x01, + 0x9b, 0x02, 0xa9, 0xfb, 0xf7, 0xac, 0xfa, 0x00, + 0x20, 0x3a, 0x18, 0xff, 0x32, 0x71, 0x32, 0x02, + 0xa9, 0x09, 0x5c, 0x12, 0x79, 0x51, 0x40, 0x02, + 0xaa, 0x11, 0x54, 0x01, 0x30, 0x10, 0x28, 0xf3, + 0xd3, 0x10, 0x21, 0x00, 0x91, 0x09, 0x21, 0x01, + 0x92, 0x01, 0x23, 0x38, 0x1c, 0x22, 0x6b, 0x03, + 0xf0, 0xf1, 0xfa, 0x38, 0x1c, 0xfd, 0xf7, 0xcd, + 0xf8, 0x06, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0xf0, 0xb5, 0x00, 0x24, 0x07, + 0x1c, 0xc8, 0x69, 0x00, 0x78, 0xc6, 0x07, 0xf6, + 0x0f, 0x0d, 0x1c, 0x38, 0x1c, 0x31, 0x1c, 0xff, + 0xf7, 0x84, 0xfe, 0x00, 0x28, 0x09, 0xd1, 0x09, + 0x23, 0xed, 0x09, 0x00, 0xe9, 0x02, 0x9b, 0x01, + 0xf8, 0x18, 0x06, 0x63, 0xe8, 0x69, 0x04, 0xa2, + 0x41, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x1c, 0xff, + 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x4c, 0x6d, 0x50, 0x61, 0x69, 0x72, 0x53, 0x75, + 0x62, 0x53, 0x74, 0x49, 0x64, 0x6c, 0x65, 0x49, + 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, + 0x65, 0x4b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xb5, 0x82, 0xb0, 0xfd, 0x23, 0x9b, 0x00, + 0xc2, 0x18, 0x07, 0x1c, 0xff, 0x30, 0x10, 0x21, + 0x00, 0x91, 0xff, 0x30, 0x42, 0x30, 0x01, 0x92, + 0x02, 0x6b, 0x08, 0x21, 0x01, 0x23, 0x38, 0x1c, + 0x03, 0xf0, 0xab, 0xfa, 0x38, 0x1c, 0xfd, 0xf7, + 0x87, 0xf8, 0x06, 0xa2, 0x00, 0x92, 0x08, 0x22, + 0x23, 0x23, 0x01, 0x21, 0x38, 0x1c, 0x03, 0xf0, + 0x24, 0xfb, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x50, 0x61, + 0x69, 0x72, 0x53, 0x75, 0x62, 0x53, 0x74, 0x49, + 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x52, 0x61, + 0x6e, 0x64, 0x50, 0x69, 0x6e, 0x52, 0x65, 0x71, + 0x50, 0x69, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x00, 0x00, 0x00, 0x00, + 0x90, 0xb5, 0x82, 0xb0, 0xfd, 0x23, 0x9b, 0x00, + 0xc2, 0x18, 0x07, 0x1c, 0xff, 0x30, 0x10, 0x21, + 0x00, 0x91, 0xff, 0x30, 0x42, 0x30, 0x01, 0x92, + 0x02, 0x6b, 0x08, 0x21, 0x01, 0x23, 0x38, 0x1c, + 0x03, 0xf0, 0x6f, 0xfa, 0x04, 0x1c, 0x38, 0x1c, + 0xfd, 0xf7, 0x4a, 0xf8, 0x20, 0x1c, 0x02, 0xb0, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x00, 0x24, 0x07, 0x1c, 0xc8, 0x69, 0x00, 0x78, + 0x3a, 0x69, 0xc0, 0x07, 0xc0, 0x0f, 0x02, 0x2a, + 0x20, 0xd1, 0x09, 0x23, 0xed, 0x09, 0x00, 0xea, + 0x02, 0x9b, 0x01, 0xfa, 0x18, 0x10, 0x63, 0xfa, + 0x1d, 0xff, 0x32, 0xba, 0x32, 0x02, 0x20, 0x50, + 0x63, 0x10, 0x48, 0xc0, 0x6b, 0x01, 0x28, 0x05, + 0xd1, 0x00, 0x22, 0x30, 0x21, 0x38, 0x1c, 0xfe, + 0xf7, 0xdd, 0xfb, 0x12, 0xe0, 0xc8, 0x69, 0xfd, + 0x23, 0x9b, 0x00, 0x41, 0x1c, 0xf8, 0x18, 0x10, + 0x22, 0xd1, 0xf7, 0xec, 0xff, 0x00, 0x22, 0x31, + 0x21, 0x38, 0x1c, 0xfe, 0xf7, 0xcf, 0xfb, 0x04, + 0xe0, 0x00, 0x22, 0x1f, 0x21, 0x38, 0x1c, 0xfe, + 0xf7, 0xc9, 0xfb, 0x20, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf8, 0xad, 0x03, + 0x20, 0x08, 0xb5, 0xc9, 0x69, 0x05, 0xa2, 0x09, + 0x78, 0x00, 0x92, 0xc9, 0x07, 0xc9, 0x0f, 0x06, + 0x23, 0x0b, 0x22, 0x03, 0xf0, 0xa8, 0xfa, 0x01, + 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x43, + 0x6e, 0x74, 0x72, 0x6c, 0x53, 0x75, 0x62, 0x53, + 0x74, 0x49, 0x6e, 0x69, 0x74, 0x50, 0x69, 0x6e, + 0x52, 0x65, 0x71, 0x49, 0x6e, 0x64, 0x41, 0x75, + 0x52, 0x61, 0x6e, 0x64, 0x00, 0xf8, 0xb5, 0x00, + 0x24, 0x07, 0x1c, 0xc8, 0x69, 0x00, 0x78, 0xc5, + 0x07, 0xed, 0x0f, 0x38, 0x69, 0x0e, 0x1c, 0x01, + 0x28, 0x0b, 0xd1, 0x01, 0x2d, 0x09, 0xd1, 0x29, + 0xa2, 0x00, 0x92, 0x08, 0x22, 0x23, 0x23, 0x38, + 0x1c, 0x29, 0x1c, 0x03, 0xf0, 0x80, 0xfa, 0x04, + 0x1c, 0x44, 0xe0, 0x02, 0x28, 0x0b, 0xd1, 0x00, + 0x2d, 0x09, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, 0xba, + 0xff, 0xf0, 0x69, 0x42, 0x1c, 0x38, 0x1c, 0x29, + 0x1c, 0xff, 0xf7, 0xf7, 0xfc, 0x36, 0xe0, 0x25, + 0x48, 0xc0, 0x6b, 0x01, 0x28, 0x17, 0xd1, 0x18, + 0x24, 0x38, 0x1c, 0xfc, 0xf7, 0xab, 0xff, 0x19, + 0xa2, 0x00, 0x92, 0x08, 0x22, 0x38, 0x1c, 0x29, + 0x1c, 0x23, 0x1c, 0x03, 0xf0, 0x60, 0xfa, 0xed, + 0x09, 0x00, 0xeb, 0x02, 0x00, 0x22, 0x22, 0x21, + 0x38, 0x1c, 0xfe, 0xf7, 0x6a, 0xfb, 0x22, 0x21, + 0x38, 0x1c, 0x22, 0x1c, 0xfe, 0xf7, 0xa1, 0xfb, + 0x04, 0x1c, 0x1a, 0xe0, 0x38, 0x1c, 0xfc, 0xf7, + 0x94, 0xff, 0xf0, 0x69, 0xfd, 0x23, 0x9b, 0x00, + 0x41, 0x1c, 0xf8, 0x18, 0x10, 0x22, 0xd1, 0xf7, + 0x70, 0xff, 0x38, 0x1c, 0x29, 0x1c, 0x08, 0x22, + 0x08, 0xa3, 0x03, 0xf0, 0x34, 0xfa, 0x04, 0x1c, + 0x04, 0xd1, 0x00, 0x22, 0x21, 0x21, 0x38, 0x1c, + 0xfe, 0xf7, 0x4b, 0xfb, 0x38, 0x1c, 0xff, 0xf7, + 0x96, 0xfd, 0x20, 0x1c, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, + 0x6c, 0x53, 0x75, 0x62, 0x53, 0x74, 0x49, 0x6e, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x49, 0x6e, 0x64, + 0x49, 0x6e, 0x52, 0x61, 0x6e, 0x64, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, 0x08, 0xb5, + 0xc9, 0x69, 0x05, 0xa2, 0x09, 0x78, 0x00, 0x92, + 0xc9, 0x07, 0xc9, 0x0f, 0x06, 0x23, 0x0b, 0x22, + 0x03, 0xf0, 0x18, 0xfa, 0x01, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x4c, 0x6d, 0x43, 0x6e, 0x74, 0x72, + 0x6c, 0x53, 0x75, 0x62, 0x53, 0x74, 0x49, 0x6e, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x49, 0x6e, 0x64, + 0x41, 0x75, 0x52, 0x61, 0x6e, 0x64, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xb5, 0x87, 0xb0, 0x07, 0x1c, + 0xff, 0x30, 0xc1, 0x30, 0x40, 0x6b, 0x00, 0x24, + 0x01, 0x28, 0x5b, 0xd1, 0xf8, 0x1d, 0xff, 0x30, + 0x7a, 0x30, 0xf9, 0x1d, 0xff, 0x31, 0x82, 0x31, + 0xfd, 0x23, 0x82, 0x69, 0x9b, 0x00, 0xfd, 0x1d, + 0x00, 0x91, 0xf9, 0x18, 0x9d, 0x35, 0xf8, 0x1d, + 0x01, 0x92, 0x0c, 0xcd, 0xff, 0x30, 0x6e, 0x30, + 0xfb, 0xf7, 0x32, 0xf9, 0xf9, 0x1d, 0xff, 0x31, + 0x3a, 0x31, 0x01, 0x20, 0x15, 0x23, 0x9b, 0x01, + 0xc8, 0x62, 0xed, 0x09, 0x00, 0xec, 0x02, 0x22, + 0x48, 0xfd, 0x1d, 0xc6, 0x18, 0x31, 0x69, 0xff, + 0x35, 0x9e, 0x35, 0x00, 0x29, 0x0b, 0xd0, 0x1f, + 0x4b, 0x02, 0xa9, 0xc0, 0x18, 0x06, 0x90, 0x0c, + 0xc8, 0x0c, 0xc1, 0x0c, 0xc8, 0x0c, 0xc1, 0x06, + 0x98, 0x0f, 0xc8, 0x0f, 0xc5, 0x0c, 0xe0, 0x10, + 0x20, 0x02, 0xa9, 0xfa, 0xf7, 0xee, 0xfa, 0x68, + 0x46, 0xf9, 0xf7, 0xa3, 0xfd, 0x00, 0x9a, 0x01, + 0x9b, 0x28, 0x1c, 0x02, 0xa9, 0xfb, 0xf7, 0xe1, + 0xf8, 0x00, 0x20, 0x3a, 0x18, 0xff, 0x32, 0x71, + 0x32, 0x02, 0xa9, 0x09, 0x5c, 0x12, 0x79, 0x51, + 0x40, 0x02, 0xaa, 0x11, 0x54, 0x01, 0x30, 0x10, + 0x28, 0xf3, 0xd3, 0x10, 0x21, 0x09, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0x00, 0x91, 0x01, 0x92, 0x02, + 0x6b, 0x30, 0x69, 0x0a, 0x21, 0x00, 0x28, 0x00, + 0xd1, 0x09, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x03, + 0xf0, 0x1f, 0xf9, 0x38, 0x1c, 0xfc, 0xf7, 0xfb, + 0xfe, 0x20, 0x1c, 0x07, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb8, 0xa8, 0x03, 0x20, 0x54, + 0x05, 0x00, 0x00, 0x80, 0xb5, 0x07, 0x1c, 0x40, + 0x69, 0x0e, 0x28, 0x03, 0xd1, 0x22, 0x21, 0x38, + 0x1c, 0xfb, 0xf7, 0x17, 0xfe, 0x38, 0x1c, 0x03, + 0xa1, 0xfb, 0xf7, 0x07, 0xfe, 0x80, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, 0x00, 0x4c, + 0x6d, 0x50, 0x61, 0x69, 0x72, 0x53, 0x75, 0x62, + 0x53, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x00, 0x00, 0x00, 0xb5, 0x09, 0x23, 0x9b, + 0x01, 0xc2, 0x18, 0x13, 0x6b, 0x06, 0x22, 0xfb, + 0xf7, 0x94, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x09, 0x23, 0x9b, 0x01, 0xc2, 0x18, 0x13, + 0x6b, 0x12, 0x22, 0xfb, 0xf7, 0x8a, 0xfe, 0x08, + 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xed, 0x09, 0x00, + 0xed, 0x02, 0x87, 0xb0, 0x07, 0x1c, 0xc8, 0x69, + 0x00, 0x78, 0xc4, 0x07, 0xe4, 0x0f, 0x09, 0x23, + 0x9b, 0x01, 0xf8, 0x18, 0x00, 0x6b, 0x0d, 0x1c, + 0xa0, 0x42, 0x08, 0xd1, 0x1d, 0xa2, 0x00, 0x92, + 0x0b, 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, + 0x03, 0xf0, 0x4d, 0xf9, 0x2c, 0xe0, 0xf8, 0x1d, + 0xff, 0x30, 0x3a, 0x30, 0xc0, 0x6a, 0x00, 0x28, + 0x08, 0xd1, 0x16, 0xa2, 0x00, 0x92, 0x0b, 0x22, + 0x06, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x03, 0xf0, + 0x3e, 0xf9, 0x1d, 0xe0, 0x01, 0xa8, 0xf9, 0xf7, + 0x17, 0xfd, 0x02, 0x9a, 0x00, 0x92, 0xe8, 0x69, + 0xfa, 0x1d, 0x41, 0x1c, 0xff, 0x32, 0x6e, 0x32, + 0x03, 0xa8, 0x01, 0x9b, 0xfb, 0xf7, 0xb6, 0xf8, + 0x04, 0x21, 0x00, 0x91, 0x03, 0xaa, 0x01, 0x92, + 0x0c, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x22, 0x1c, + 0x03, 0xf0, 0xa1, 0xf8, 0x00, 0x28, 0x03, 0xd1, + 0x38, 0x1c, 0x04, 0xa9, 0xfb, 0xf7, 0x5e, 0xfd, + 0x07, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x50, 0x61, + 0x69, 0x72, 0x53, 0x75, 0x62, 0x53, 0x74, 0x49, + 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x62, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x53, 0x52, 0x65, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0xb5, 0x89, 0xb0, + 0x07, 0x1c, 0xc8, 0x69, 0x00, 0x78, 0xc0, 0x07, + 0xc0, 0x0f, 0x09, 0x23, 0x9b, 0x01, 0xfa, 0x18, + 0x12, 0x6b, 0x00, 0x26, 0x0d, 0x1c, 0x82, 0x42, + 0x13, 0xd0, 0x3a, 0x69, 0x01, 0x2a, 0x08, 0xd1, + 0x25, 0xa2, 0x00, 0x92, 0x09, 0x22, 0x23, 0x23, + 0x01, 0x1c, 0x38, 0x1c, 0x03, 0xf0, 0xef, 0xf8, + 0x3d, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0x7e, 0xfd, + 0x00, 0x28, 0x38, 0xd1, 0x13, 0x20, 0xb8, 0x61, + 0x35, 0xe0, 0x38, 0x1c, 0xfc, 0xf7, 0x26, 0xfe, + 0xed, 0x09, 0x00, 0xee, 0x02, 0x24, 0x48, 0xfc, + 0x1d, 0xff, 0x34, 0x00, 0x69, 0x7a, 0x34, 0x00, + 0x28, 0x02, 0xd0, 0x01, 0x20, 0xe0, 0x61, 0x21, + 0xe0, 0x00, 0x20, 0xe9, 0x69, 0x3a, 0x18, 0x09, + 0x18, 0xff, 0x32, 0x71, 0x32, 0x12, 0x79, 0x49, + 0x78, 0x4a, 0x40, 0x01, 0xa9, 0x0a, 0x54, 0x01, + 0x30, 0x10, 0x28, 0xf2, 0xd3, 0xfb, 0x1d, 0x9d, + 0x33, 0x1a, 0x68, 0x5b, 0x68, 0x05, 0xa8, 0xfa, + 0xf7, 0xe5, 0xff, 0x00, 0x20, 0x39, 0x18, 0xff, + 0x31, 0xa1, 0x31, 0x05, 0xaa, 0x12, 0x5c, 0x0b, + 0x79, 0x5a, 0x40, 0x01, 0x30, 0x10, 0x28, 0x0a, + 0x71, 0xf4, 0xd3, 0xe6, 0x61, 0x01, 0x20, 0x20, + 0x62, 0x00, 0x22, 0x27, 0x21, 0x38, 0x1c, 0xfe, + 0xf7, 0xbf, 0xf9, 0x30, 0x1c, 0x09, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x50, + 0x61, 0x69, 0x72, 0x53, 0x75, 0x62, 0x53, 0x74, + 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x62, + 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x64, 0x43, 0x6f, + 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, + 0x00, 0xf8, 0xad, 0x03, 0x20, 0xf0, 0xb5, 0x0c, + 0x1c, 0x07, 0x1c, 0xfc, 0xf7, 0xd5, 0xfd, 0x14, + 0x48, 0xf9, 0x1d, 0xff, 0x31, 0x00, 0x69, 0x7a, + 0x31, 0x01, 0x23, 0x00, 0x28, 0x02, 0xd0, 0x38, + 0x69, 0x02, 0x28, 0x12, 0xd1, 0x02, 0x20, 0xc8, + 0x61, 0x00, 0x20, 0xe2, 0x69, 0x12, 0x18, 0x55, + 0x78, 0x3a, 0x18, 0xd6, 0x1d, 0xff, 0x36, 0x6a, + 0x36, 0x36, 0x79, 0x75, 0x40, 0xff, 0x32, 0xa1, + 0x32, 0x01, 0x30, 0x10, 0x28, 0x15, 0x71, 0xf0, + 0xd3, 0x00, 0xe0, 0xcb, 0x61, 0x0b, 0x62, 0x27, + 0x21, 0x00, 0x22, 0x38, 0x1c, 0xfe, 0xf7, 0x7c, + 0xf9, 0xf0, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0xf8, 0xad, 0x03, 0x20, 0xb0, 0xb5, 0x82, + 0xb0, 0x07, 0x1c, 0xed, 0x09, 0x00, 0xef, 0x02, + 0xff, 0x30, 0x81, 0x30, 0xf9, 0x1d, 0xff, 0x31, + 0x82, 0x31, 0x00, 0x24, 0xfd, 0x23, 0x82, 0x69, + 0x9b, 0x00, 0xfd, 0x1d, 0x00, 0x91, 0xf9, 0x18, + 0x9d, 0x35, 0xf8, 0x1d, 0x01, 0x92, 0x0c, 0xcd, + 0xff, 0x30, 0x6e, 0x30, 0xfa, 0xf7, 0x9a, 0xff, + 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x01, 0x20, + 0xc8, 0x62, 0x38, 0x1c, 0xfc, 0xf7, 0xa3, 0xfd, + 0x20, 0x1c, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0xb5, 0xc9, 0x69, 0x02, 0xa2, + 0x01, 0x31, 0xff, 0xf7, 0x04, 0xfc, 0x08, 0xbc, + 0x18, 0x47, 0x4c, 0x6d, 0x50, 0x61, 0x69, 0x72, + 0x53, 0x75, 0x62, 0x53, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, + 0x57, 0x61, 0x69, 0x74, 0x49, 0x6e, 0x64, 0x43, + 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, + 0x79, 0x00, 0xf0, 0xb5, 0x87, 0xb0, 0x0d, 0x1c, + 0x07, 0x1c, 0xfc, 0xf7, 0x64, 0xfd, 0xf8, 0x1d, + 0xff, 0x30, 0xba, 0x30, 0x02, 0x21, 0x15, 0x23, + 0x9b, 0x01, 0x41, 0x63, 0x2e, 0x48, 0xfc, 0x1d, + 0xc6, 0x18, 0x32, 0x69, 0xff, 0x34, 0x7a, 0x34, + 0x00, 0x2a, 0x22, 0xd0, 0x3a, 0x69, 0x01, 0x2a, + 0x1f, 0xd1, 0x29, 0x4b, 0x02, 0xa9, 0xc0, 0x18, + 0x06, 0x90, 0x0c, 0xc8, 0x0c, 0xc1, 0x0c, 0xc8, + 0x0c, 0xc1, 0x06, 0x98, 0xf9, 0x1d, 0xff, 0x31, + 0x0c, 0xc8, 0x9e, 0x31, 0x0c, 0xc1, 0x0c, 0xc8, + 0x0c, 0xc1, 0x00, 0x20, 0x3a, 0x18, 0xff, 0x32, + 0x71, 0x32, 0x02, 0xa9, 0x09, 0x5c, 0x12, 0x79, + 0x51, 0x40, 0x02, 0xaa, 0x11, 0x54, 0x01, 0x30, + 0x10, 0x28, 0xf3, 0xd3, 0x01, 0x20, 0xe0, 0x61, + 0x00, 0xe0, 0xe1, 0x61, 0x10, 0x21, 0x09, 0x23, + 0x9b, 0x01, 0x02, 0xaa, 0x01, 0x92, 0xf8, 0x18, + 0x00, 0x91, 0x02, 0x6b, 0x30, 0x69, 0xed, 0x09, + 0x00, 0xf0, 0x02, 0x0a, 0x21, 0x00, 0x28, 0x00, + 0xd1, 0x09, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x02, + 0xf0, 0x59, 0xff, 0x38, 0x1c, 0xfc, 0xf7, 0x35, + 0xfd, 0x30, 0x69, 0x00, 0x28, 0x02, 0xd0, 0x38, + 0x69, 0x02, 0x28, 0x0f, 0xd1, 0x00, 0x20, 0xe9, + 0x69, 0x09, 0x18, 0x4a, 0x78, 0x39, 0x18, 0xcb, + 0x1d, 0xff, 0x33, 0x6a, 0x33, 0x1b, 0x79, 0x5a, + 0x40, 0xff, 0x31, 0xa1, 0x31, 0x01, 0x30, 0x10, + 0x28, 0x0a, 0x71, 0xf0, 0xd3, 0x01, 0x20, 0x20, + 0x62, 0x07, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0xb8, 0xa8, 0x03, 0x20, 0x54, + 0x05, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, 0x00, + 0x69, 0x00, 0x24, 0x01, 0x28, 0x03, 0xd1, 0x38, + 0x1c, 0x00, 0xf0, 0x99, 0xfb, 0x14, 0xe0, 0x00, + 0x22, 0x20, 0x21, 0x38, 0x1c, 0xfe, 0xf7, 0xb9, + 0xf8, 0xf9, 0x1d, 0xff, 0x31, 0x7a, 0x31, 0x00, + 0x20, 0xfd, 0x23, 0x9b, 0x00, 0xfa, 0x18, 0x09, + 0x23, 0x9b, 0x01, 0x48, 0x60, 0xf8, 0x18, 0x01, + 0x6b, 0x38, 0x1c, 0xff, 0xf7, 0x21, 0xfa, 0x04, + 0x1c, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x90, 0xb5, 0x07, 0x1c, 0x00, 0x69, 0x00, + 0x24, 0x01, 0x28, 0x03, 0xd1, 0x38, 0x1c, 0x00, + 0xf0, 0x76, 0xfb, 0x14, 0xe0, 0x00, 0x22, 0x20, + 0x21, 0x38, 0x1c, 0xfe, 0xf7, 0x96, 0xf8, 0xf9, + 0x1d, 0xff, 0x31, 0x7a, 0x31, 0x00, 0x20, 0xfd, + 0x23, 0x9b, 0x00, 0xfa, 0x18, 0x09, 0x23, 0x9b, + 0x01, 0x48, 0x60, 0xf8, 0x18, 0x01, 0x6b, 0x38, + 0x1c, 0xff, 0xf7, 0xfe, 0xf9, 0x04, 0x1c, 0x20, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, + 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0x08, 0x1c, 0xf9, + 0x1d, 0xff, 0x31, 0xba, 0x31, 0x49, 0x6b, 0x02, + 0x29, 0x2a, 0xd1, 0x09, 0x23, 0x9b, 0x01, 0xfd, + 0x18, 0xed, 0x09, 0x00, 0xf1, 0x02, 0x00, 0x28, + 0x1b, 0xd1, 0xfd, 0x23, 0x9b, 0x00, 0xf8, 0x18, + 0x04, 0x1c, 0x10, 0x22, 0x13, 0xa1, 0xf7, 0xf7, + 0x67, 0xf8, 0x00, 0x28, 0x03, 0xd1, 0x10, 0x20, + 0x21, 0x1c, 0xfa, 0xf7, 0x7b, 0xf8, 0x10, 0x21, + 0x00, 0x91, 0x08, 0x21, 0x01, 0x94, 0x01, 0x23, + 0x38, 0x1c, 0x2a, 0x6b, 0x02, 0xf0, 0xc9, 0xfe, + 0x04, 0x1c, 0x38, 0x1c, 0xfc, 0xf7, 0xa4, 0xfc, + 0x0a, 0xe0, 0x0d, 0xa2, 0x00, 0x92, 0x08, 0x22, + 0x03, 0x1c, 0x38, 0x1c, 0x29, 0x6b, 0x02, 0xf0, + 0x40, 0xff, 0x04, 0x1c, 0x00, 0xe0, 0x0c, 0x24, + 0x20, 0x1c, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4c, 0x6d, 0x50, 0x61, 0x69, 0x72, 0x53, 0x75, + 0x62, 0x53, 0x74, 0x52, 0x65, 0x73, 0x70, 0x46, + 0x69, 0x78, 0x50, 0x69, 0x6e, 0x52, 0x65, 0x71, + 0x50, 0x69, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x00, 0x00, 0x00, 0x00, + 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x08, 0x1c, + 0xf9, 0x1d, 0xff, 0x31, 0xba, 0x31, 0x49, 0x6b, + 0x02, 0x29, 0x34, 0xd1, 0x09, 0x23, 0x9b, 0x01, + 0xf9, 0x18, 0x00, 0x28, 0x25, 0xd1, 0x38, 0x1c, + 0x08, 0x22, 0x09, 0x6b, 0x19, 0xa3, 0x02, 0xf0, + 0xf5, 0xfe, 0x04, 0x1c, 0x02, 0xa8, 0xf9, 0xf7, + 0xdd, 0xfa, 0xf8, 0x1d, 0xff, 0x30, 0x7a, 0x30, + 0xf9, 0x1d, 0xff, 0x31, 0x82, 0x69, 0x82, 0x31, + 0xfd, 0x23, 0x9b, 0x00, 0x00, 0x91, 0xf9, 0x18, + 0xf8, 0x1d, 0xff, 0x30, 0x01, 0x92, 0x02, 0x9a, + 0x6e, 0x30, 0x03, 0x9b, 0xfa, 0xf7, 0x37, 0xfe, + 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x01, 0x20, + 0xc8, 0x62, 0x38, 0x1c, 0xed, 0x09, 0x00, 0xf2, + 0x02, 0xfc, 0xf7, 0x40, 0xfc, 0x0a, 0xe0, 0x08, + 0xa2, 0x00, 0x92, 0x08, 0x22, 0x03, 0x1c, 0x38, + 0x1c, 0x09, 0x6b, 0x02, 0xf0, 0xdc, 0xfe, 0x04, + 0x1c, 0x00, 0xe0, 0x0c, 0x24, 0x20, 0x1c, 0x04, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x4c, 0x6d, 0x50, 0x61, 0x69, 0x72, 0x53, + 0x75, 0x62, 0x53, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x56, 0x61, 0x72, 0x50, 0x69, 0x6e, 0x52, 0x65, + 0x71, 0x50, 0x69, 0x6e, 0x43, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xb4, 0xc5, 0x1d, 0xff, 0x35, 0x6e, + 0x35, 0x6c, 0xcd, 0xc4, 0x1d, 0xff, 0x34, 0xb2, + 0x34, 0x6c, 0xc4, 0xc5, 0x1d, 0xff, 0x35, 0x7a, + 0x35, 0x01, 0x22, 0x6a, 0x63, 0x00, 0x27, 0x00, + 0x22, 0xcb, 0x69, 0x84, 0x18, 0x9b, 0x18, 0x5e, + 0x78, 0x1f, 0x23, 0x5b, 0x01, 0xe3, 0x18, 0x1b, + 0x79, 0x73, 0x40, 0xff, 0x34, 0xa1, 0x34, 0x01, + 0x32, 0x10, 0x2a, 0x23, 0x71, 0xf0, 0xd3, 0x01, + 0x22, 0x2a, 0x62, 0x38, 0x1c, 0xf0, 0xbc, 0x70, + 0x47, 0x00, 0xb5, 0xfc, 0xf7, 0xdb, 0xfb, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0xb0, 0xb5, 0x87, + 0xb0, 0x07, 0x1c, 0xff, 0x30, 0x81, 0x30, 0x00, + 0x6a, 0x00, 0x24, 0x0d, 0x1c, 0x00, 0x28, 0x2b, + 0xd0, 0x01, 0xa8, 0xf9, 0xf7, 0x65, 0xfa, 0x02, + 0x9a, 0x00, 0x92, 0xe8, 0x69, 0xfa, 0x1d, 0x41, + 0x1c, 0xff, 0x32, 0x9e, 0x32, 0x03, 0xa8, 0x01, + 0x9b, 0xfa, 0xf7, 0x04, 0xfe, 0x04, 0x21, 0x09, + 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x00, 0x91, 0x03, + 0xaa, 0x01, 0x92, 0x02, 0x6b, 0x0c, 0x21, 0x01, + 0x23, 0x38, 0x1c, 0x02, 0xf0, 0xec, 0xfd, 0x04, + 0x1c, 0x03, 0xd1, 0x38, 0x1c, 0x04, 0xa9, 0xfb, + 0xf7, 0xa9, 0xfa, 0xf8, 0x1d, 0xff, 0x30, 0xed, + 0x09, 0x00, 0xf3, 0x02, 0xba, 0x30, 0x40, 0x6b, + 0x02, 0x28, 0x04, 0xd1, 0x00, 0x22, 0x27, 0x21, + 0x38, 0x1c, 0xfd, 0xf7, 0x6e, 0xff, 0x20, 0x1c, + 0x07, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x90, 0xb5, 0x07, 0x1c, 0xff, 0x30, 0xc1, 0x30, + 0x40, 0x6b, 0x00, 0x24, 0x02, 0x28, 0x07, 0xd1, + 0x38, 0x1c, 0xfc, 0xf7, 0x42, 0xfa, 0x00, 0x22, + 0x48, 0x21, 0x38, 0x1c, 0xfd, 0xf7, 0x95, 0xff, + 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x90, 0xb5, 0x0c, 0x1c, 0x0a, 0xa1, 0x07, 0x1c, + 0xfb, 0xf7, 0xbd, 0xfa, 0x38, 0x1c, 0x21, 0x1c, + 0xfa, 0xf7, 0x9d, 0xfe, 0x23, 0x2c, 0x06, 0xd1, + 0x78, 0x69, 0x0e, 0x28, 0x03, 0xd1, 0x38, 0x1c, + 0x21, 0x1c, 0xfb, 0xf7, 0xbc, 0xfa, 0x90, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x4c, 0x6d, + 0x50, 0x61, 0x69, 0x72, 0x53, 0x75, 0x62, 0x53, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x41, 0x75, 0x74, + 0x68, 0x52, 0x65, 0x71, 0x49, 0x6e, 0x64, 0x41, + 0x6e, 0x73, 0x77, 0x65, 0x72, 0x41, 0x75, 0x52, + 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x90, 0xb5, 0x0c, 0x1c, 0x05, 0xa1, + 0x07, 0x1c, 0xfb, 0xf7, 0x90, 0xfa, 0x38, 0x1c, + 0x21, 0x1c, 0xfa, 0xf7, 0x70, 0xfe, 0x90, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x4c, 0x6d, + 0x50, 0x61, 0x69, 0x72, 0x53, 0x75, 0x62, 0x53, + 0x74, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6c, + 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x41, + 0x75, 0x52, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, + 0x00, 0x00, 0x90, 0xb5, 0x87, 0xb0, 0x07, 0x1c, + 0x01, 0xa8, 0x0c, 0x1c, 0xf9, 0xf7, 0xcb, 0xf9, + 0x02, 0x9a, 0x00, 0x92, 0xe0, 0x69, 0xfa, 0x1d, + 0x41, 0x1c, 0xed, 0x09, 0x00, 0xf4, 0x02, 0xff, + 0x32, 0x6e, 0x32, 0x03, 0xa8, 0x01, 0x9b, 0xfa, + 0xf7, 0x6a, 0xfd, 0x04, 0x21, 0x09, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0x00, 0x91, 0x03, 0xaa, 0x01, + 0x92, 0x02, 0x6b, 0x0c, 0x21, 0x01, 0x23, 0x38, + 0x1c, 0x02, 0xf0, 0x52, 0xfd, 0x00, 0x28, 0x03, + 0xd1, 0x38, 0x1c, 0x04, 0xa9, 0xfb, 0xf7, 0x0f, + 0xfa, 0x00, 0x22, 0x27, 0x21, 0x38, 0x1c, 0xfd, + 0xf7, 0xda, 0xfe, 0x07, 0xb0, 0x90, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0xf0, 0xb5, 0x88, + 0xb0, 0x07, 0x1c, 0x00, 0x24, 0x09, 0x23, 0x9b, + 0x01, 0x00, 0x69, 0xfd, 0x18, 0x01, 0x28, 0x09, + 0xd1, 0x22, 0xa2, 0x00, 0x92, 0x0b, 0x22, 0x23, + 0x23, 0x38, 0x1c, 0x29, 0x6b, 0x02, 0xf0, 0xb4, + 0xfd, 0x04, 0x1c, 0x34, 0xe0, 0x07, 0x91, 0xf9, + 0x1d, 0xff, 0x31, 0xba, 0x31, 0x02, 0x20, 0x48, + 0x63, 0xf8, 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x00, + 0x6a, 0x00, 0x28, 0x03, 0xd0, 0xfe, 0x1d, 0xff, + 0x36, 0x9e, 0x36, 0x02, 0xe0, 0xfe, 0x1d, 0xff, + 0x36, 0x6e, 0x36, 0x01, 0xa8, 0xf9, 0xf7, 0x79, + 0xf9, 0x02, 0x9a, 0x07, 0x99, 0x00, 0x92, 0xc8, + 0x69, 0x01, 0x9b, 0x41, 0x1c, 0x03, 0xa8, 0x32, + 0x1c, 0xfa, 0xf7, 0x19, 0xfd, 0x04, 0x21, 0x00, + 0x91, 0x03, 0xaa, 0x01, 0x92, 0x0c, 0x21, 0x01, + 0x23, 0x38, 0x1c, 0x2a, 0x6b, 0x02, 0xf0, 0x04, + 0xfd, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x1c, 0x04, + 0xa9, 0xfb, 0xf7, 0xc1, 0xf9, 0x00, 0x22, 0x2f, + 0x21, 0x38, 0x1c, 0xfd, 0xf7, 0x8c, 0xfe, 0x20, + 0x1c, 0x08, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x50, 0x61, 0x69, + 0x72, 0x53, 0x75, 0x62, 0x53, 0x74, 0x49, 0x6e, + 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, + 0x71, 0x52, 0x65, 0x71, 0x53, 0xed, 0x09, 0x00, + 0xf5, 0x02, 0x52, 0x65, 0x73, 0x00, 0x00, 0x00, + 0xff, 0x30, 0xc1, 0x30, 0x02, 0x21, 0x41, 0x63, + 0x00, 0x20, 0x70, 0x47, 0x00, 0xb5, 0x03, 0xa1, + 0xfb, 0xf7, 0xda, 0xf9, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0x00, 0x4c, 0x6d, 0x50, 0x61, + 0x69, 0x72, 0x53, 0x75, 0x62, 0x53, 0x74, 0x49, + 0x6e, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x52, + 0x65, 0x71, 0x49, 0x6e, 0x64, 0x41, 0x6e, 0x73, + 0x77, 0x65, 0x72, 0x41, 0x75, 0x52, 0x61, 0x6e, + 0x64, 0x45, 0x72, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb5, 0xfc, 0xf7, 0x9b, 0xfa, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x90, 0xb5, 0x87, 0xb0, + 0x07, 0x1c, 0x01, 0xa8, 0x0c, 0x1c, 0xf9, 0xf7, + 0x13, 0xf9, 0x02, 0x9a, 0x00, 0x92, 0xe0, 0x69, + 0xfa, 0x1d, 0x41, 0x1c, 0xff, 0x32, 0x6e, 0x32, + 0x03, 0xa8, 0x01, 0x9b, 0xfa, 0xf7, 0xb2, 0xfc, + 0x04, 0x21, 0x09, 0x23, 0x9b, 0x01, 0xf8, 0x18, + 0x00, 0x91, 0x03, 0xaa, 0x01, 0x92, 0x02, 0x6b, + 0x0c, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x02, 0xf0, + 0x9a, 0xfc, 0x04, 0x1c, 0x03, 0xd1, 0x38, 0x1c, + 0x04, 0xa9, 0xfb, 0xf7, 0x57, 0xf9, 0xf8, 0x1d, + 0xff, 0x30, 0xba, 0x30, 0x40, 0x6b, 0x01, 0x28, + 0x07, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, 0x02, 0xf9, + 0x00, 0x22, 0x49, 0x21, 0x38, 0x1c, 0xfd, 0xf7, + 0x55, 0xfe, 0x20, 0x1c, 0x07, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfc, 0xf7, + 0x45, 0xfa, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, + 0x00, 0xb5, 0x42, 0x69, 0x0e, 0x2a, 0x01, 0xd1, + 0xfe, 0xf7, 0x5d, 0xff, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x90, 0xb5, 0x0c, 0x1c, 0x1f, 0x21, + 0x07, 0x1c, 0xfa, 0xf7, 0x51, 0xfd, 0x38, 0x1c, + 0x21, 0x1c, 0xff, 0xf7, 0xed, 0xff, 0x90, 0xbc, + 0xed, 0x09, 0x00, 0xf6, 0x02, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xe7, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x0c, 0x1c, 0x1f, + 0x21, 0x07, 0x1c, 0xfa, 0xf7, 0x3f, 0xfd, 0x38, + 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0xf1, 0xff, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x07, + 0x1c, 0x15, 0x48, 0x81, 0x6a, 0xf8, 0x1d, 0xb9, + 0x30, 0x00, 0x29, 0x05, 0xd0, 0x82, 0x6b, 0x00, + 0x2a, 0x02, 0xd0, 0xc2, 0x6b, 0xd2, 0x08, 0x16, + 0xd2, 0x00, 0x29, 0x00, 0xd0, 0x80, 0x6b, 0x38, + 0x1c, 0x02, 0xf0, 0x27, 0xfa, 0x02, 0x1c, 0x00, + 0x23, 0x31, 0x21, 0x38, 0x1c, 0x02, 0xf0, 0x39, + 0xfc, 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, 0xfd, + 0xf7, 0x03, 0xfe, 0x04, 0x1c, 0x07, 0xd1, 0x38, + 0x1c, 0xfc, 0xf7, 0x0e, 0xfa, 0x03, 0xe0, 0x38, + 0x1c, 0x00, 0xf0, 0x78, 0xfc, 0x04, 0x1c, 0x20, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0xf8, 0xad, 0x03, 0x20, 0x00, 0xb5, 0xff, + 0xf7, 0xcd, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x80, + 0xb5, 0x82, 0x69, 0x00, 0x27, 0x00, 0x2a, 0x03, + 0xd1, 0x0a, 0x1c, 0x02, 0x21, 0xfd, 0xf7, 0xe4, + 0xfd, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x02, 0xa1, 0xfd, 0xf7, 0x35, + 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x50, + 0x61, 0x69, 0x72, 0x53, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x00, 0x90, 0xb5, 0x0c, + 0x1c, 0x07, 0x1c, 0xfc, 0xf7, 0xfb, 0xfc, 0x38, + 0x1c, 0xfc, 0xf7, 0xbe, 0xf9, 0xf8, 0x1d, 0x79, + 0x30, 0x04, 0x63, 0x38, 0x1c, 0x21, 0x1c, 0xfb, + 0x1d, 0xa9, 0x33, 0x03, 0xa2, 0xfd, 0xf7, 0x28, + 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x4c, 0x6d, 0xed, 0x09, 0x00, 0xf7, 0x02, + 0x50, 0x61, 0x69, 0x72, 0x53, 0x74, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x00, 0x00, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, + 0xfc, 0xf7, 0x21, 0xfd, 0xf8, 0x1d, 0x79, 0x30, + 0x04, 0x63, 0x38, 0x1c, 0xfc, 0xf7, 0x9b, 0xf9, + 0x55, 0x21, 0x38, 0x1c, 0x22, 0x1c, 0xfd, 0xf7, + 0x62, 0xfd, 0x90, 0xbc, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x00, 0xb5, 0xfd, 0x23, 0x9b, 0x00, + 0xc9, 0x69, 0xc0, 0x18, 0x10, 0x22, 0x01, 0x31, + 0xd1, 0xf7, 0x6d, 0xf9, 0x08, 0xbc, 0x00, 0x20, + 0x18, 0x47, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, + 0xfc, 0xf7, 0x01, 0xfd, 0x9a, 0x21, 0x38, 0x1c, + 0x22, 0x1c, 0xfd, 0xf7, 0x48, 0xfd, 0x38, 0x1c, + 0x21, 0x1c, 0x02, 0xa2, 0xfd, 0xf7, 0xb7, 0xfa, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, + 0x50, 0x61, 0x69, 0x72, 0x53, 0x74, 0x42, 0x42, + 0x44, 0x65, 0x74, 0x61, 0x63, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x90, 0xb5, 0x04, 0x1c, 0xff, 0x30, + 0x89, 0x30, 0x17, 0x1c, 0xd1, 0xf7, 0x47, 0xf9, + 0xe1, 0x1d, 0xff, 0x31, 0x01, 0x20, 0x7a, 0x31, + 0x48, 0x60, 0x8f, 0x61, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xb0, 0xb5, 0x00, 0x25, 0x07, 0x1c, + 0xd1, 0xf7, 0xd2, 0xfc, 0x04, 0x1c, 0x2b, 0xd0, + 0x00, 0x22, 0x19, 0x21, 0x38, 0x1c, 0xfd, 0xf7, + 0x56, 0xfd, 0x05, 0x1c, 0x24, 0xd1, 0x00, 0x22, + 0x19, 0x21, 0x38, 0x1c, 0xfd, 0xf7, 0x13, 0xfd, + 0x05, 0x1c, 0x1d, 0xd1, 0xf9, 0x1d, 0xff, 0x31, + 0xba, 0x31, 0x01, 0x20, 0x48, 0x63, 0x38, 0x1c, + 0x02, 0xf0, 0x5e, 0xf9, 0x09, 0x23, 0x9b, 0x01, + 0xf9, 0x18, 0xfd, 0x23, 0x9b, 0x00, 0x08, 0x63, + 0xf9, 0x18, 0x10, 0x20, 0xf9, 0xf7, 0x15, 0xfd, + 0xce, 0x20, 0x20, 0x60, 0xf9, 0x1d, 0xed, 0x09, + 0x00, 0xf8, 0x02, 0x9d, 0x31, 0x88, 0xc9, 0xe0, + 0x1d, 0x05, 0x30, 0x88, 0xc0, 0x05, 0x20, 0x21, + 0x1c, 0xd1, 0xf7, 0x13, 0xfd, 0x28, 0x1c, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x00, + 0x22, 0x11, 0x21, 0x07, 0x1c, 0xfd, 0xf7, 0x25, + 0xfd, 0x00, 0x28, 0x04, 0xd1, 0x00, 0x22, 0x11, + 0x21, 0x38, 0x1c, 0xfd, 0xf7, 0xe2, 0xfc, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xb0, + 0xb5, 0x04, 0x1c, 0x0d, 0x1c, 0xe1, 0x1d, 0xff, + 0x31, 0x00, 0x20, 0x00, 0x27, 0xba, 0x31, 0x48, + 0x61, 0xd1, 0xf7, 0x84, 0xfc, 0x00, 0x28, 0x01, + 0xd1, 0x07, 0x27, 0x10, 0xe0, 0xbc, 0x21, 0x01, + 0x60, 0xe1, 0x6a, 0xe2, 0x1d, 0xc1, 0x60, 0x05, + 0x61, 0xb9, 0x32, 0x52, 0x68, 0x01, 0x21, 0x00, + 0x2a, 0x00, 0xd1, 0x00, 0x21, 0x41, 0x61, 0x01, + 0x1c, 0x05, 0x20, 0xd1, 0xf7, 0xde, 0xfc, 0x38, + 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0xb5, 0x42, 0x69, 0x0e, 0x2a, 0x03, 0xd0, 0x0f, + 0x2a, 0x01, 0xd0, 0x10, 0x2a, 0x09, 0xd1, 0x00, + 0x29, 0x05, 0xd0, 0xc2, 0x1d, 0xff, 0x32, 0xba, + 0x32, 0x52, 0x69, 0x00, 0x2a, 0x01, 0xd0, 0xff, + 0xf7, 0xca, 0xff, 0x08, 0xbc, 0x18, 0x47, 0xb0, + 0xb5, 0x0c, 0x1c, 0xc1, 0x1d, 0xb9, 0x31, 0x07, + 0x1c, 0x88, 0x68, 0x00, 0x25, 0x00, 0x2a, 0x48, + 0x60, 0x06, 0xd0, 0x29, 0x1c, 0x00, 0x28, 0x00, + 0xd0, 0x03, 0x21, 0x38, 0x1c, 0x00, 0xf0, 0xfd, + 0xfa, 0x38, 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0xd7, + 0xff, 0x38, 0x1c, 0x02, 0xf0, 0xc2, 0xf8, 0x28, + 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, + 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xc0, 0x30, 0x09, + 0x23, 0x9b, 0x01, 0x40, 0x68, 0xfd, 0x18, 0x00, + 0x28, 0x0b, 0xd1, 0x36, 0x24, 0x02, 0x21, 0x38, + 0x1c, 0xed, 0x09, 0x00, 0xf9, 0x02, 0x00, 0xf0, + 0xe3, 0xfa, 0x00, 0x23, 0x12, 0x21, 0x38, 0x1c, + 0xaa, 0x6b, 0x02, 0xf0, 0xe2, 0xfa, 0x12, 0xe0, + 0x2d, 0x24, 0x05, 0x23, 0xdb, 0x01, 0xf9, 0x18, + 0x10, 0x48, 0x15, 0x23, 0x5b, 0x01, 0x40, 0x6a, + 0xfa, 0x18, 0x08, 0x62, 0x01, 0x21, 0x00, 0x91, + 0x10, 0x21, 0x01, 0x92, 0x01, 0x23, 0x38, 0x1c, + 0xaa, 0x6b, 0x02, 0xf0, 0xce, 0xfa, 0xf9, 0x1d, + 0xff, 0x31, 0x3a, 0x31, 0x38, 0x1c, 0x08, 0x4a, + 0xfc, 0xf7, 0xea, 0xf8, 0xf9, 0x1d, 0x21, 0x31, + 0x00, 0x23, 0x38, 0x1c, 0x22, 0x1c, 0xfd, 0xf7, + 0x19, 0xfc, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x00, 0x20, 0x18, 0x47, 0x38, 0xae, 0x03, 0x20, + 0xa3, 0xb3, 0x02, 0x20, 0x90, 0xb5, 0x07, 0x1c, + 0xff, 0x30, 0xff, 0x30, 0x42, 0x30, 0x81, 0x6b, + 0x38, 0x1c, 0x0f, 0x22, 0x11, 0xa3, 0x02, 0xf0, + 0x21, 0xfb, 0x04, 0x1c, 0x38, 0x69, 0x02, 0x28, + 0x11, 0xd1, 0xf8, 0x1d, 0xb9, 0x30, 0x40, 0x68, + 0x00, 0x28, 0x02, 0xd1, 0x2d, 0x20, 0xb8, 0x62, + 0x01, 0xe0, 0x29, 0x20, 0xb8, 0x62, 0xf9, 0x1d, + 0xff, 0x31, 0x3a, 0x31, 0x38, 0x1c, 0x0e, 0x4a, + 0xfc, 0xf7, 0xba, 0xf8, 0x06, 0xe0, 0x01, 0x28, + 0x04, 0xd1, 0x27, 0x20, 0xb8, 0x62, 0x38, 0x1c, + 0xff, 0xf7, 0x98, 0xff, 0x20, 0x1c, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x43, 0x72, + 0x79, 0x70, 0x74, 0x41, 0x6e, 0x73, 0x77, 0x65, + 0x72, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x00, + 0xa3, 0xb3, 0x02, 0x20, 0x90, 0xb5, 0x00, 0x22, + 0x07, 0x1c, 0xff, 0xf7, 0x63, 0xff, 0x04, 0x1c, + 0x00, 0x21, 0x38, 0x1c, 0xfb, 0xf7, 0xbc, 0xfc, + 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x80, 0xb5, 0x82, 0xb0, 0xed, 0x09, 0x00, 0xfa, + 0x02, 0x07, 0x1c, 0x02, 0xf0, 0x50, 0xf8, 0x09, + 0x23, 0x9b, 0x01, 0xf9, 0x18, 0x88, 0x63, 0xfa, + 0x1d, 0xbd, 0x32, 0x01, 0x21, 0x00, 0x91, 0x01, + 0x92, 0x02, 0x1c, 0x0f, 0x21, 0x01, 0x23, 0x38, + 0x1c, 0x02, 0xf0, 0x59, 0xfa, 0xf9, 0x1d, 0xff, + 0x31, 0x3a, 0x31, 0x38, 0x1c, 0x03, 0x4a, 0xfc, + 0xf7, 0x75, 0xf8, 0x02, 0xb0, 0x80, 0xbc, 0x08, + 0xbc, 0x00, 0x20, 0x18, 0x47, 0xa3, 0xb3, 0x02, + 0x20, 0x00, 0xb5, 0x42, 0x6a, 0x00, 0x2a, 0x03, + 0xd0, 0x01, 0x21, 0xc0, 0x30, 0x81, 0x62, 0x01, + 0xe0, 0xff, 0xf7, 0xd4, 0xff, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x80, 0xb5, 0xc2, 0x1d, 0xb9, + 0x32, 0x53, 0x68, 0x51, 0x60, 0x93, 0x60, 0x00, + 0x27, 0x05, 0x23, 0xdb, 0x01, 0xc2, 0x18, 0x93, + 0x6a, 0x01, 0x33, 0x93, 0x62, 0xc2, 0x1d, 0xff, + 0x32, 0x3a, 0x32, 0x52, 0x68, 0x00, 0x2a, 0x02, + 0xd0, 0x25, 0x21, 0x81, 0x62, 0x01, 0xe0, 0xff, + 0xf7, 0xdb, 0xff, 0x38, 0x1c, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x07, 0x1c, 0xff, + 0x30, 0xff, 0x30, 0x42, 0x30, 0x81, 0x63, 0xf8, + 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x40, 0x68, 0x00, + 0x24, 0x00, 0x28, 0x02, 0xd0, 0x26, 0x20, 0xb8, + 0x62, 0x02, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0x58, + 0xff, 0x05, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x81, + 0x6a, 0x01, 0x31, 0x81, 0x62, 0x20, 0x1c, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0x30, 0xff, + 0x30, 0x42, 0x30, 0x81, 0x63, 0x00, 0x20, 0x70, + 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x45, 0xff, 0x08, + 0xbc, 0x18, 0x47, 0x88, 0xb5, 0x07, 0x1c, 0x00, + 0x69, 0x02, 0x28, 0x15, 0xd1, 0x09, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0x81, 0x63, 0x38, 0x1c, 0x0f, + 0x22, 0x0b, 0xa3, 0x02, 0xf0, 0x61, 0xfa, 0xed, + 0x09, 0x00, 0xfb, 0x02, 0xf9, 0x1d, 0xb9, 0x31, + 0x49, 0x68, 0x00, 0x29, 0x04, 0xd1, 0x2d, 0x21, + 0xb9, 0x62, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x29, 0x21, 0xb9, 0x62, 0xf9, 0xe7, 0x03, 0xa2, + 0x00, 0x92, 0x0f, 0x22, 0x23, 0x23, 0x38, 0x1c, + 0x02, 0xf0, 0x5c, 0xfa, 0xf1, 0xe7, 0x4c, 0x6d, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x53, 0x75, 0x62, + 0x53, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, + 0x71, 0x49, 0x6e, 0x64, 0x45, 0x6e, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, + 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb5, + 0x00, 0x27, 0x09, 0x23, 0x9b, 0x01, 0xc1, 0x18, + 0x89, 0x6b, 0x00, 0xf0, 0xd6, 0xf9, 0x38, 0x1c, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0xc1, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x00, 0x24, + 0x07, 0x1c, 0xfb, 0xf7, 0xba, 0xff, 0x09, 0x23, + 0x9b, 0x01, 0xf8, 0x18, 0x81, 0x6b, 0x38, 0x1c, + 0x00, 0xf0, 0xc3, 0xf9, 0x20, 0x1c, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xc1, 0x1d, + 0xff, 0x31, 0x00, 0x27, 0x3a, 0x31, 0x03, 0x4a, + 0xfb, 0xf7, 0xbf, 0xff, 0x38, 0x1c, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa3, 0xb3, + 0x02, 0x20, 0x80, 0xb5, 0xc1, 0x1d, 0xff, 0x31, + 0x00, 0x27, 0x3a, 0x31, 0x03, 0x4a, 0xfb, 0xf7, + 0xb0, 0xff, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xa3, 0xb3, 0x02, 0x20, 0x80, 0xb5, + 0x07, 0x1c, 0x00, 0x29, 0x0f, 0xd1, 0xf8, 0x1d, + 0xb9, 0x30, 0x41, 0x68, 0x81, 0x60, 0x03, 0x21, + 0x38, 0x1c, 0x00, 0xf0, 0x76, 0xf9, 0x00, 0x21, + 0x38, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0x38, 0x1c, + 0x01, 0xf0, 0x3b, 0xff, 0x03, 0xe0, 0x01, 0x22, + 0x38, 0x1c, 0xff, 0xf7, 0x5c, 0xfe, 0x00, 0x21, + 0x38, 0x1c, 0xed, 0x09, 0x00, 0xfc, 0x02, 0xfb, + 0xf7, 0xb6, 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x80, 0xb5, 0x00, 0x21, 0x07, + 0x1c, 0xff, 0xf7, 0x3b, 0xfe, 0x38, 0x1c, 0x01, + 0xf0, 0x26, 0xff, 0x00, 0x21, 0x38, 0x1c, 0xfb, + 0xf7, 0xa6, 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x90, 0xb5, 0x01, 0x22, 0x22, + 0x21, 0x04, 0x1c, 0xff, 0xf7, 0x3e, 0xfe, 0x07, + 0x1c, 0x00, 0x21, 0x20, 0x1c, 0xfb, 0xf7, 0x97, + 0xfb, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x90, 0xb5, 0x01, 0x22, 0x22, 0x21, 0x04, + 0x1c, 0xff, 0xf7, 0x2f, 0xfe, 0x07, 0x1c, 0x00, + 0x21, 0x20, 0x1c, 0xfb, 0xf7, 0x88, 0xfb, 0x38, + 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, + 0xb5, 0x07, 0x1c, 0xc0, 0x30, 0x0c, 0x1c, 0x41, + 0x68, 0x81, 0x60, 0x00, 0x21, 0x38, 0x1c, 0x00, + 0xf0, 0x2a, 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0xff, + 0xf7, 0x04, 0xfe, 0x38, 0x1c, 0x01, 0xf0, 0xef, + 0xfe, 0x00, 0x21, 0x38, 0x1c, 0xfb, 0xf7, 0x6f, + 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x80, 0xb5, 0x00, 0x21, 0x07, 0x1c, 0xff, + 0xf7, 0xf4, 0xfd, 0x38, 0x1c, 0x01, 0xf0, 0xdf, + 0xfe, 0x00, 0x21, 0x38, 0x1c, 0xfb, 0xf7, 0x5f, + 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, + 0x47, 0x00, 0xb5, 0xc2, 0x1d, 0xff, 0x32, 0xba, + 0x32, 0x52, 0x69, 0x00, 0x2a, 0x03, 0xd0, 0xff, + 0xf7, 0xbc, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0xfb, + 0xf7, 0x4e, 0xfb, 0x00, 0x20, 0xf9, 0xe7, 0x00, + 0xb5, 0xff, 0xf7, 0xee, 0xff, 0x08, 0xbc, 0x18, + 0x47, 0x90, 0xb5, 0x07, 0x1c, 0xc0, 0x30, 0x81, + 0x68, 0x41, 0x60, 0x38, 0x1c, 0x01, 0xf0, 0xdc, + 0xfe, 0x02, 0x1c, 0x00, 0x23, 0x31, 0x21, 0x38, + 0x1c, 0x02, 0xf0, 0xee, 0xf8, 0xed, 0x09, 0x00, + 0xfd, 0x02, 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, + 0xfd, 0xf7, 0xb8, 0xfa, 0x04, 0x1c, 0x02, 0xd1, + 0x38, 0x1c, 0xfb, 0xf7, 0xc3, 0xfe, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x07, 0x1c, 0xc0, 0x30, 0x81, 0x68, 0x41, 0x60, + 0x38, 0x1c, 0x01, 0xf0, 0xc0, 0xfe, 0x02, 0x1c, + 0x00, 0x23, 0x31, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0xd2, 0xf8, 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, + 0xfd, 0xf7, 0x9c, 0xfa, 0x04, 0x1c, 0x02, 0xd1, + 0x38, 0x1c, 0xfb, 0xf7, 0xa7, 0xfe, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x07, 0x1c, 0xc0, 0x30, 0x81, 0x68, 0x41, 0x60, + 0x38, 0x1c, 0x01, 0xf0, 0xa4, 0xfe, 0x02, 0x1c, + 0x00, 0x23, 0x31, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0xb6, 0xf8, 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, + 0xfd, 0xf7, 0x80, 0xfa, 0x04, 0x1c, 0x02, 0xd1, + 0x38, 0x1c, 0xfb, 0xf7, 0x8b, 0xfe, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x07, 0x1c, 0x01, 0xf0, 0x8c, 0xfe, 0x02, 0x1c, + 0x00, 0x23, 0x31, 0x21, 0x38, 0x1c, 0x02, 0xf0, + 0x9e, 0xf8, 0x00, 0x22, 0x37, 0x21, 0x38, 0x1c, + 0xfd, 0xf7, 0x68, 0xfa, 0x04, 0x1c, 0x02, 0xd1, + 0x38, 0x1c, 0xfb, 0xf7, 0x73, 0xfe, 0x20, 0x1c, + 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, + 0xff, 0xf7, 0xe5, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0xff, 0xf7, 0xe0, 0xff, 0x08, 0xbc, + 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0x01, 0xf0, + 0x6a, 0xfe, 0x02, 0x1c, 0x00, 0x23, 0x31, 0x21, + 0x38, 0x1c, 0x02, 0xf0, 0x7c, 0xf8, 0x00, 0x22, + 0x37, 0x21, 0x38, 0x1c, 0xfd, 0xf7, 0x46, 0xfa, + 0x38, 0x1c, 0xfb, 0xf7, 0x53, 0xfe, 0x80, 0xbc, + 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x90, 0xb5, + 0xed, 0x09, 0x00, 0xfe, 0x02, 0x0c, 0x1c, 0x07, + 0x1c, 0xfc, 0xf7, 0x6c, 0xf9, 0x38, 0x1c, 0xfb, + 0xf7, 0x2f, 0xfe, 0xf8, 0x1d, 0x79, 0x30, 0x04, + 0x63, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0x1d, 0xa9, + 0x33, 0x02, 0xa2, 0xfc, 0xf7, 0x99, 0xfd, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x43, + 0x72, 0x79, 0x70, 0x74, 0x53, 0x74, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x00, 0x00, 0xb5, 0xc2, 0x1d, 0x79, 0x32, 0x11, + 0x63, 0xfb, 0xf7, 0x12, 0xfe, 0x08, 0xbc, 0x00, + 0x20, 0x18, 0x47, 0x00, 0xb5, 0x02, 0xa2, 0xfc, + 0xf7, 0x4b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x4c, 0x6d, 0x43, 0x72, 0x79, 0x70, 0x74, + 0x53, 0x74, 0x42, 0x42, 0x44, 0x65, 0x74, 0x61, + 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x02, + 0xa1, 0xfc, 0xf7, 0x5b, 0xfc, 0x08, 0xbc, 0x18, + 0x47, 0x4c, 0x6d, 0x43, 0x72, 0x79, 0x70, 0x74, + 0x53, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb5, 0x43, + 0x23, 0x1b, 0x01, 0xc5, 0x18, 0x0b, 0x4b, 0xc2, + 0x1d, 0xc1, 0x18, 0x07, 0x1c, 0xff, 0x30, 0xff, + 0x30, 0xff, 0x32, 0x6e, 0x32, 0x92, 0x30, 0x2b, + 0x1c, 0x04, 0x1c, 0xfa, 0xf7, 0x4e, 0xf8, 0x05, + 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x01, 0x6a, 0x20, + 0x1c, 0xfa, 0xf7, 0xd0, 0xfa, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x14, 0x04, 0x00, + 0x00, 0xb0, 0xb5, 0x00, 0x27, 0x04, 0x1c, 0x0d, + 0x1c, 0xd1, 0xf7, 0x43, 0xf9, 0x00, 0x28, 0x01, + 0xd1, 0x07, 0x27, 0x11, 0xe0, 0x5c, 0x21, 0x01, + 0x60, 0x21, 0x6b, 0xff, 0x34, 0xc1, 0x60, 0xff, + 0x34, 0x92, 0x34, 0x0c, 0xcc, 0xc1, 0x1d, 0x09, + 0x31, 0x0c, 0xc1, 0xed, 0x09, 0x00, 0xff, 0x02, + 0x0c, 0xcc, 0x0c, 0xc1, 0x05, 0x62, 0x01, 0x1c, + 0x07, 0x20, 0xd1, 0xf7, 0x9c, 0xf9, 0x38, 0x1c, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, + 0x82, 0xb0, 0x15, 0x4b, 0x0c, 0x1c, 0xc1, 0x18, + 0x07, 0x1c, 0x10, 0x20, 0x0d, 0x1c, 0xf9, 0xf7, + 0x84, 0xf9, 0x38, 0x1c, 0xff, 0xf7, 0xb5, 0xff, + 0x01, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xcf, 0xff, + 0x10, 0x21, 0x00, 0x91, 0x11, 0x21, 0x01, 0x23, + 0x38, 0x1c, 0x22, 0x1c, 0x01, 0x95, 0x01, 0xf0, + 0xcb, 0xff, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, + 0x04, 0x1c, 0x38, 0x1c, 0x08, 0x4a, 0xfb, 0xf7, + 0xe6, 0xfd, 0x00, 0x23, 0x35, 0x22, 0x38, 0x1c, + 0xf9, 0x1d, 0x21, 0x31, 0xfd, 0xf7, 0x15, 0xf9, + 0x20, 0x1c, 0x02, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x14, 0x04, 0x00, 0x00, 0xa3, 0xb3, + 0x02, 0x20, 0xf3, 0xb5, 0x2c, 0x25, 0x29, 0x1c, + 0x00, 0x24, 0x07, 0x1c, 0xfd, 0xf7, 0x58, 0xf9, + 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x24, 0x15, 0xe0, + 0xf9, 0x1d, 0x21, 0x31, 0x38, 0x1c, 0x2a, 0x1c, + 0x0e, 0x1c, 0xfd, 0xf7, 0xda, 0xf8, 0x00, 0x28, + 0x01, 0xd1, 0x0c, 0x24, 0x0a, 0xe0, 0x00, 0x22, + 0x38, 0x1c, 0x29, 0x1c, 0xfd, 0xf7, 0x67, 0xf9, + 0x38, 0x1c, 0x31, 0x1c, 0x2a, 0x1c, 0x01, 0x9b, + 0xfd, 0xf7, 0xeb, 0xf8, 0x20, 0x1c, 0x02, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, + 0x00, 0x27, 0x00, 0x29, 0x0c, 0xd1, 0xc1, 0x1d, + 0xb9, 0x31, 0x8a, 0x6a, 0x00, 0x2a, 0x0f, 0xd0, + 0x8f, 0x62, 0xc1, 0x1d, 0x00, 0x23, 0x2b, 0x22, + 0x21, 0x31, 0xfd, 0xf7, 0xd6, 0xf8, 0x07, 0xe0, + 0xc2, 0x1d, 0xff, 0x32, 0xba, 0x32, 0x52, 0x69, + 0x00, 0x2a, 0x01, 0xd0, 0xff, 0xf7, 0x29, 0xfc, + 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0xed, 0x09, + 0x00, 0x00, 0x03, 0x18, 0x47, 0x80, 0xb4, 0x02, + 0x1c, 0xc0, 0x32, 0x53, 0x68, 0x00, 0x20, 0x00, + 0x29, 0x93, 0x60, 0x0e, 0xd0, 0x15, 0x4b, 0x01, + 0x29, 0x0e, 0xd0, 0x02, 0x29, 0x22, 0xd1, 0x9b, + 0x6a, 0x00, 0x2b, 0x19, 0xd0, 0x01, 0x2b, 0x19, + 0xd0, 0x02, 0x2b, 0x19, 0xd1, 0x51, 0x60, 0x80, + 0xbc, 0x70, 0x47, 0x00, 0x21, 0x51, 0x60, 0xfa, + 0xe7, 0x9b, 0x6a, 0x01, 0x21, 0x00, 0x2b, 0x05, + 0xd0, 0x01, 0x2b, 0x05, 0xd0, 0x02, 0x2b, 0x05, + 0xd1, 0x51, 0x60, 0xf0, 0xe7, 0x51, 0x60, 0xee, + 0xe7, 0x51, 0x60, 0xec, 0xe7, 0x1f, 0x20, 0xea, + 0xe7, 0x51, 0x60, 0xe8, 0xe7, 0x51, 0x60, 0xe6, + 0xe7, 0x1f, 0x20, 0xe4, 0xe7, 0x1e, 0x20, 0xe2, + 0xe7, 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, 0x90, + 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0x00, 0x29, 0x50, + 0xd1, 0x4f, 0x21, 0x38, 0x1c, 0xfd, 0xf7, 0xde, + 0xf8, 0x00, 0x28, 0x24, 0xd0, 0x38, 0x1c, 0xfd, + 0xf7, 0x2a, 0xf8, 0x04, 0x1c, 0x00, 0x20, 0xb8, + 0x61, 0x38, 0x1c, 0xfb, 0xf7, 0xee, 0xfc, 0x20, + 0x1c, 0x0b, 0x2c, 0x26, 0xd0, 0x18, 0x28, 0x1f, + 0xd0, 0x28, 0x28, 0x18, 0xd0, 0x37, 0x28, 0x12, + 0xd1, 0x38, 0x1c, 0x01, 0xf0, 0x03, 0xfd, 0x02, + 0x1c, 0x00, 0x23, 0x31, 0x21, 0x38, 0x1c, 0x01, + 0xf0, 0x15, 0xff, 0x00, 0x22, 0x38, 0x1c, 0x21, + 0x1c, 0xfd, 0xf7, 0xdf, 0xf8, 0x00, 0x28, 0x02, + 0xd1, 0x38, 0x1c, 0xfb, 0xf7, 0xea, 0xfc, 0x02, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, + 0x21, 0x38, 0x1c, 0xfb, 0xf7, 0x10, 0xf9, 0xf6, + 0xe7, 0x00, 0x21, 0x38, 0x1c, 0xfb, 0xf7, 0x0b, + 0xf9, 0xf1, 0xe7, 0x38, 0x1c, 0x01, 0xf0, 0xe2, + 0xfc, 0x0d, 0x4a, 0x08, 0x21, 0x00, 0x91, 0x01, + 0x92, 0x02, 0x1c, 0x27, 0x21, 0x01, 0x23, 0x38, + 0x1c, 0xed, 0x09, 0x00, 0x01, 0x03, 0x01, 0xf0, + 0xf0, 0xfe, 0x00, 0x22, 0x38, 0x1c, 0x21, 0x1c, + 0xfd, 0xf7, 0xba, 0xf8, 0x00, 0x28, 0xdd, 0xd1, + 0x38, 0x1c, 0xfb, 0xf7, 0xc5, 0xfc, 0xd9, 0xe7, + 0x0a, 0x1c, 0x02, 0x21, 0x38, 0x1c, 0xfd, 0xf7, + 0xaf, 0xf8, 0xd3, 0xe7, 0x7c, 0xae, 0x03, 0x20, + 0xb0, 0xb5, 0x07, 0x1c, 0x0c, 0x1c, 0x01, 0xd1, + 0x57, 0x25, 0x0f, 0xe0, 0x09, 0x23, 0x9b, 0x01, + 0xf8, 0x18, 0x00, 0x6b, 0x90, 0x42, 0x08, 0xd1, + 0x23, 0x2c, 0x04, 0xd1, 0x38, 0x69, 0x02, 0x28, + 0x01, 0xd1, 0x59, 0x25, 0x02, 0xe0, 0x58, 0x25, + 0x00, 0xe0, 0x59, 0x25, 0x38, 0x1c, 0x29, 0x1c, + 0xfd, 0xf7, 0x6f, 0xf8, 0x00, 0x28, 0x14, 0xd0, + 0x38, 0x1c, 0x29, 0x1c, 0xfd, 0xf7, 0x30, 0xf8, + 0x00, 0x28, 0x0e, 0xd0, 0x59, 0x2d, 0x02, 0xd0, + 0x38, 0x1c, 0xfb, 0xf7, 0x7d, 0xfc, 0x38, 0x1c, + 0x29, 0x1c, 0x22, 0x1c, 0xfd, 0xf7, 0x80, 0xf8, + 0x38, 0x1c, 0x29, 0x1c, 0x22, 0x1c, 0xfd, 0xf7, + 0x3f, 0xf8, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xb0, 0xb5, 0x64, 0x25, 0x0c, 0x1c, 0x29, 0x1c, + 0x07, 0x1c, 0xfd, 0xf7, 0x4e, 0xf8, 0x00, 0x28, + 0x16, 0xd0, 0x38, 0x1c, 0x29, 0x1c, 0xfd, 0xf7, + 0x0f, 0xf8, 0x00, 0x28, 0x10, 0xd0, 0x00, 0x2c, + 0x0e, 0xd0, 0x06, 0x2c, 0x1a, 0xd0, 0x23, 0x2c, + 0x32, 0xd1, 0x38, 0x1c, 0xfb, 0xf7, 0x58, 0xfc, + 0x38, 0x69, 0x02, 0x28, 0x07, 0xd1, 0x66, 0x21, + 0x38, 0x1c, 0x22, 0x1c, 0xfd, 0xf7, 0x1c, 0xf8, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x24, 0x22, + 0x65, 0x21, 0x38, 0x1c, 0xfd, 0xf7, 0x14, 0xf8, + 0x24, 0x22, 0x65, 0x21, 0x38, 0x1c, 0xfd, 0xf7, + 0x4b, 0xf8, 0xf1, 0xe7, 0x38, 0x1c, 0xfb, 0xf7, + 0x3f, 0xfc, 0x65, 0x21, 0x38, 0x1c, 0x22, 0x1c, + 0xfd, 0xf7, 0x06, 0xf8, 0xed, 0x09, 0x00, 0x02, + 0x03, 0x78, 0x69, 0x0b, 0x28, 0x08, 0xd1, 0xb8, + 0x69, 0x00, 0x28, 0x05, 0xd1, 0x0a, 0x20, 0x78, + 0x61, 0x38, 0x1c, 0xff, 0xf7, 0xd5, 0xfa, 0xdd, + 0xe7, 0x65, 0x21, 0x38, 0x1c, 0x22, 0x1c, 0xfd, + 0xf7, 0x31, 0xf8, 0xd7, 0xe7, 0x38, 0x1c, 0xfb, + 0xf7, 0x25, 0xfc, 0x65, 0x21, 0x38, 0x1c, 0x22, + 0x1c, 0xfc, 0xf7, 0xec, 0xff, 0x65, 0x21, 0x38, + 0x1c, 0x22, 0x1c, 0xfd, 0xf7, 0x23, 0xf8, 0xc9, + 0xe7, 0xf0, 0xb5, 0x6d, 0x26, 0x0c, 0x1c, 0x31, + 0x1c, 0x07, 0x1c, 0xfc, 0xf7, 0xf8, 0xff, 0x00, + 0x28, 0x23, 0xd0, 0xf9, 0x1d, 0x21, 0x31, 0x38, + 0x1c, 0x32, 0x1c, 0x0d, 0x1c, 0xfc, 0xf7, 0x7c, + 0xff, 0x00, 0x28, 0x1a, 0xd0, 0xf9, 0x1d, 0xff, + 0x31, 0x3a, 0x31, 0x38, 0x1c, 0x0e, 0x1c, 0xfb, + 0xf7, 0x45, 0xfc, 0x05, 0x23, 0xdb, 0x01, 0xf9, + 0x18, 0xf8, 0x1d, 0xb9, 0x30, 0x10, 0x23, 0x00, + 0x2c, 0x31, 0x4a, 0x0d, 0xd0, 0x23, 0x2c, 0x2c, + 0xd0, 0x2a, 0x2c, 0x01, 0xd0, 0x32, 0x2c, 0x4f, + 0xd1, 0x79, 0x6a, 0x00, 0x29, 0x40, 0xd0, 0x01, + 0x21, 0x81, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x3c, 0x69, 0x01, 0x2c, 0x03, 0xd1, 0x38, + 0x1c, 0xff, 0xf7, 0x26, 0xfb, 0xf5, 0xe7, 0x40, + 0x68, 0x00, 0x28, 0x0a, 0xd1, 0x38, 0x1c, 0x31, + 0x1c, 0xfb, 0xf7, 0x38, 0xfc, 0x00, 0x23, 0x6f, + 0x22, 0x38, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0x68, + 0xff, 0xe7, 0xe7, 0x0b, 0x62, 0x38, 0x1c, 0x31, + 0x1c, 0xfb, 0xf7, 0x2c, 0xfc, 0x00, 0x23, 0x6e, + 0x22, 0x38, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0x5c, + 0xff, 0xdb, 0xe7, 0x38, 0x69, 0x02, 0x28, 0x0b, + 0xd1, 0x0b, 0x62, 0x38, 0x1c, 0x31, 0x1c, 0xfb, + 0xf7, 0x1d, 0xfc, 0x00, 0x23, 0x71, 0x22, 0x38, + 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0x4d, 0xff, 0xed, + 0x09, 0x00, 0x03, 0x03, 0xcc, 0xe7, 0x70, 0x21, + 0x38, 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0xbd, 0xff, + 0x70, 0x22, 0x38, 0x1c, 0x29, 0x1c, 0x23, 0x1c, + 0xfc, 0xf7, 0x41, 0xff, 0xc0, 0xe7, 0x70, 0x21, + 0x38, 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0xb1, 0xff, + 0x70, 0x22, 0x38, 0x1c, 0x29, 0x1c, 0x23, 0x1c, + 0xfc, 0xf7, 0x35, 0xff, 0xb4, 0xe7, 0x70, 0x22, + 0x38, 0x1c, 0x29, 0x1c, 0x23, 0x1c, 0xfc, 0xf7, + 0x2e, 0xff, 0x70, 0x21, 0x38, 0x1c, 0x22, 0x1c, + 0xfc, 0xf7, 0x9f, 0xff, 0xa8, 0xe7, 0xa3, 0xb3, + 0x02, 0x20, 0xf0, 0xb5, 0x07, 0x1c, 0x0c, 0x1c, + 0x01, 0xd1, 0x72, 0x25, 0x00, 0xe0, 0x73, 0x25, + 0x38, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0x6e, 0xff, + 0x00, 0x28, 0x19, 0xd0, 0xf9, 0x1d, 0x21, 0x31, + 0x38, 0x1c, 0x2a, 0x1c, 0x0e, 0x1c, 0xfc, 0xf7, + 0xf2, 0xfe, 0x00, 0x28, 0x10, 0xd0, 0xf9, 0x1d, + 0xff, 0x31, 0x38, 0x1c, 0x3a, 0x31, 0xfb, 0xf7, + 0xbc, 0xfb, 0x38, 0x1c, 0x31, 0x1c, 0x2a, 0x1c, + 0x23, 0x1c, 0xfc, 0xf7, 0x04, 0xff, 0x38, 0x1c, + 0x29, 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0x75, 0xff, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, + 0x07, 0x1c, 0x0c, 0x1c, 0x01, 0xd1, 0x75, 0x25, + 0x00, 0xe0, 0x76, 0x25, 0x38, 0x1c, 0x29, 0x1c, + 0xfc, 0xf7, 0x44, 0xff, 0x00, 0x28, 0x19, 0xd0, + 0xf9, 0x1d, 0x21, 0x31, 0x38, 0x1c, 0x2a, 0x1c, + 0x0e, 0x1c, 0xfc, 0xf7, 0xc8, 0xfe, 0x00, 0x28, + 0x10, 0xd0, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, + 0x3a, 0x31, 0xfb, 0xf7, 0x92, 0xfb, 0x38, 0x1c, + 0x31, 0x1c, 0x2a, 0x1c, 0x23, 0x1c, 0xfc, 0xf7, + 0xda, 0xfe, 0x38, 0x1c, 0x29, 0x1c, 0x22, 0x1c, + 0xfc, 0xf7, 0x4b, 0xff, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf0, 0xb5, 0x07, 0x1c, 0x0c, 0x1c, + 0x01, 0xd1, 0xed, 0x09, 0x00, 0x04, 0x03, 0x78, + 0x25, 0x00, 0xe0, 0x79, 0x25, 0x38, 0x1c, 0x29, + 0x1c, 0xfc, 0xf7, 0x1a, 0xff, 0x00, 0x28, 0x19, + 0xd0, 0xf9, 0x1d, 0x21, 0x31, 0x38, 0x1c, 0x2a, + 0x1c, 0x0e, 0x1c, 0xfc, 0xf7, 0x9e, 0xfe, 0x00, + 0x28, 0x10, 0xd0, 0xf9, 0x1d, 0xff, 0x31, 0x38, + 0x1c, 0x3a, 0x31, 0xfb, 0xf7, 0x68, 0xfb, 0x38, + 0x1c, 0x31, 0x1c, 0x2a, 0x1c, 0x23, 0x1c, 0xfc, + 0xf7, 0xb0, 0xfe, 0x38, 0x1c, 0x29, 0x1c, 0x22, + 0x1c, 0xfc, 0xf7, 0x21, 0xff, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x83, 0xb0, 0x0c, + 0x1c, 0x7f, 0x21, 0x07, 0x1c, 0xfc, 0xf7, 0xf4, + 0xfe, 0x00, 0x28, 0x26, 0xd0, 0xf8, 0x1d, 0xff, + 0x30, 0xba, 0x30, 0x80, 0x6a, 0x00, 0x28, 0x20, + 0xd0, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x16, + 0x31, 0xfb, 0xf7, 0x45, 0xfb, 0x0b, 0x23, 0x9b, + 0x01, 0xfd, 0x18, 0x00, 0x2c, 0x05, 0xd1, 0x29, + 0x6a, 0x01, 0x22, 0x38, 0x1c, 0xe9, 0x61, 0xfd, + 0xf7, 0xf7, 0xfb, 0x10, 0x35, 0x07, 0xcd, 0x1c, + 0x3d, 0x05, 0x23, 0xdb, 0x01, 0x01, 0x91, 0x00, + 0x90, 0x02, 0x92, 0xed, 0x68, 0xf8, 0x18, 0xc2, + 0x68, 0x38, 0x1c, 0x21, 0x1c, 0x2b, 0x1c, 0xfb, + 0xf7, 0xd6, 0xfd, 0x03, 0xb0, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x83, 0xb0, 0x0c, + 0x1c, 0x80, 0x21, 0x07, 0x1c, 0xfc, 0xf7, 0xc0, + 0xfe, 0x00, 0x28, 0x53, 0xd0, 0xf8, 0x1d, 0xff, + 0x30, 0xba, 0x30, 0x40, 0x6a, 0x00, 0x28, 0x4d, + 0xd0, 0x05, 0x23, 0xdb, 0x01, 0xfe, 0x18, 0x70, + 0x6b, 0x01, 0xf0, 0x9b, 0xfc, 0x02, 0x90, 0xf9, + 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x12, 0x31, 0xfb, + 0xf7, 0x0a, 0xfb, 0x0b, 0x23, 0x9b, 0x01, 0xfd, + 0x18, 0x00, 0x2c, 0x2a, 0xd1, 0x68, 0x68, 0x02, + 0x99, 0x88, 0x42, 0x0e, 0xd2, 0xed, 0x09, 0x00, + 0x05, 0x03, 0x38, 0x1c, 0x01, 0xf0, 0xdb, 0xfa, + 0x01, 0x21, 0x02, 0xaa, 0x01, 0x92, 0x00, 0x91, + 0x2d, 0x21, 0x02, 0x1c, 0x01, 0x23, 0x38, 0x1c, + 0x01, 0xf0, 0xe9, 0xfc, 0x02, 0x98, 0x68, 0x60, + 0x70, 0x6b, 0xb0, 0x63, 0xa9, 0x68, 0x02, 0x98, + 0x81, 0x42, 0x03, 0xd0, 0xa8, 0x60, 0x38, 0x1c, + 0xfb, 0xf7, 0x32, 0xfd, 0x38, 0x1c, 0xfd, 0xf7, + 0x24, 0xfb, 0x02, 0x1c, 0x38, 0x1c, 0xb1, 0x6b, + 0xfd, 0xf7, 0xb9, 0xfb, 0x00, 0x21, 0x38, 0x1c, + 0x01, 0xf0, 0x72, 0xfc, 0xb2, 0x6b, 0x0c, 0xe0, + 0xb2, 0x6b, 0xa8, 0x68, 0x00, 0x24, 0x05, 0x28, + 0x02, 0xd2, 0x03, 0x23, 0x9b, 0x03, 0x9a, 0x43, + 0x03, 0x28, 0x02, 0xd2, 0x03, 0x23, 0x9b, 0x02, + 0x9a, 0x43, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0xf7, + 0x9f, 0xfd, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf0, 0xb5, 0x07, 0x1c, 0x0c, 0x1c, + 0x01, 0xd1, 0x50, 0x25, 0x00, 0xe0, 0x51, 0x25, + 0x38, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0x5b, 0xfe, + 0x00, 0x28, 0x19, 0xd0, 0xf9, 0x1d, 0x1d, 0x31, + 0x38, 0x1c, 0x2a, 0x1c, 0x0e, 0x1c, 0xfc, 0xf7, + 0xdf, 0xfd, 0x00, 0x28, 0x10, 0xd0, 0xf9, 0x1d, + 0xff, 0x31, 0x38, 0x1c, 0x1e, 0x31, 0xfb, 0xf7, + 0xa9, 0xfa, 0x00, 0x23, 0x38, 0x1c, 0x31, 0x1c, + 0x2a, 0x1c, 0xfc, 0xf7, 0xf1, 0xfd, 0x38, 0x1c, + 0x29, 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0x62, 0xfe, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, + 0x07, 0x1c, 0x00, 0x29, 0x01, 0xd1, 0x61, 0x24, + 0x00, 0xe0, 0x62, 0x24, 0x38, 0x1c, 0x21, 0x1c, + 0xfc, 0xf7, 0x31, 0xfe, 0x00, 0x28, 0x12, 0xd0, + 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7, 0xf2, 0xfd, + 0x00, 0x28, 0x0c, 0xd0, 0x38, 0x1c, 0xfb, 0xf7, + 0x41, 0xfa, 0x00, 0x22, 0x38, 0x1c, 0x21, 0x1c, + 0xed, 0x09, 0x00, 0x06, 0x03, 0xfc, 0xf7, 0x08, + 0xfe, 0x00, 0x22, 0x38, 0x1c, 0x21, 0x1c, 0xfc, + 0xf7, 0x3f, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xb0, 0xb5, 0x07, 0x1c, 0x0c, 0x1c, 0x1f, + 0xd0, 0x23, 0x2c, 0x01, 0xd1, 0x5d, 0x25, 0x00, + 0xe0, 0x5c, 0x25, 0x38, 0x1c, 0x29, 0x1c, 0xfc, + 0xf7, 0x0c, 0xfe, 0x00, 0x28, 0x14, 0xd0, 0x38, + 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0xcd, 0xfd, 0x00, + 0x28, 0x0e, 0xd0, 0x5d, 0x2d, 0x02, 0xd0, 0x38, + 0x1c, 0xfb, 0xf7, 0x1a, 0xfa, 0x38, 0x1c, 0x29, + 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0xe1, 0xfd, 0x38, + 0x1c, 0x29, 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0x18, + 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1a, + 0x29, 0x01, 0xd0, 0x00, 0x29, 0x03, 0xd0, 0x01, + 0x21, 0xff, 0x30, 0x41, 0x30, 0x81, 0x62, 0x70, + 0x47, 0x80, 0xb5, 0xcb, 0x69, 0x19, 0x78, 0x49, + 0x08, 0x04, 0x29, 0x01, 0xd1, 0x99, 0x78, 0x00, + 0xe0, 0x00, 0x21, 0x5b, 0x78, 0x1f, 0x2b, 0x4f, + 0xd0, 0x0e, 0xdc, 0xdf, 0x1f, 0x01, 0x3f, 0x0c, + 0x2f, 0x17, 0xd2, 0x02, 0xa3, 0xdb, 0x5d, 0x5b, + 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x22, 0x40, 0x13, + 0x25, 0x13, 0x13, 0x13, 0x28, 0x2b, 0x2e, 0x31, + 0x3a, 0x2e, 0x2b, 0x2e, 0xd0, 0x0c, 0xdc, 0x20, + 0x2b, 0x3a, 0xd0, 0x2a, 0x2b, 0x26, 0xd0, 0x2b, + 0x2b, 0x33, 0xd0, 0x2c, 0x2b, 0x01, 0xd1, 0x02, + 0xf0, 0x21, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x32, 0x2b, 0x24, 0xd0, 0x33, 0x2b, 0x04, + 0xd0, 0x79, 0x2b, 0xf6, 0xd1, 0x03, 0xf0, 0x0a, + 0xff, 0xf3, 0xe7, 0xff, 0xf7, 0xcb, 0xfc, 0xf0, + 0xe7, 0xff, 0xf7, 0x26, 0xfd, 0xed, 0xe7, 0xff, + 0xf7, 0x57, 0xfd, 0xea, 0xe7, 0xff, 0xf7, 0xaa, + 0xfd, 0xe7, 0xe7, 0xff, 0xf7, 0x2d, 0xfe, 0xe4, + 0xe7, 0xff, 0xf7, 0xed, 0x09, 0x00, 0x07, 0x03, + 0x54, 0xfe, 0xe1, 0xe7, 0xff, 0xf7, 0x7b, 0xfe, + 0xde, 0xe7, 0xff, 0xf7, 0xa2, 0xfe, 0xdb, 0xe7, + 0xff, 0xf7, 0xd3, 0xfe, 0xd8, 0xe7, 0xff, 0xf7, + 0x31, 0xff, 0xd5, 0xe7, 0xff, 0xf7, 0x58, 0xff, + 0xd2, 0xe7, 0xff, 0xf7, 0x78, 0xff, 0xcf, 0xe7, + 0x01, 0xf0, 0xbb, 0xff, 0xcc, 0xe7, 0xff, 0xf7, + 0x99, 0xff, 0xc9, 0xe7, 0xf8, 0xb5, 0x15, 0x1c, + 0x07, 0x1c, 0xd0, 0xf7, 0x1d, 0xfd, 0x04, 0x1c, + 0x11, 0xd0, 0x00, 0x22, 0x4e, 0x21, 0x38, 0x1c, + 0xfc, 0xf7, 0xa1, 0xfd, 0x00, 0x28, 0x0d, 0xd0, + 0x1f, 0xa2, 0x00, 0x92, 0x33, 0x22, 0x24, 0x23, + 0x38, 0x1c, 0x29, 0x1c, 0x01, 0xf0, 0x4c, 0xfc, + 0x20, 0x1c, 0xd0, 0xf7, 0x44, 0xfd, 0xf8, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xfb, 0xf7, + 0x86, 0xf9, 0x38, 0x1c, 0xf9, 0xf7, 0x27, 0xfc, + 0xfe, 0x1d, 0x79, 0x36, 0x00, 0x28, 0x14, 0xd0, + 0x19, 0x48, 0x40, 0x6a, 0x00, 0x28, 0x10, 0xd0, + 0x11, 0xa2, 0x00, 0x92, 0x33, 0x22, 0x17, 0x24, + 0x38, 0x1c, 0x29, 0x1c, 0x23, 0x1c, 0x01, 0xf0, + 0x2f, 0xfc, 0x02, 0x21, 0x38, 0x1c, 0x22, 0x1c, + 0xfc, 0xf7, 0x75, 0xfd, 0x00, 0x20, 0x30, 0x63, + 0xdd, 0xe7, 0xd5, 0x20, 0x20, 0x60, 0xf9, 0x1d, + 0x9d, 0x31, 0xe7, 0x60, 0x88, 0xc9, 0xe0, 0x1d, + 0x09, 0x30, 0x88, 0xc0, 0xf0, 0x6a, 0xa0, 0x61, + 0x00, 0x20, 0xe0, 0x61, 0x05, 0x20, 0x21, 0x1c, + 0xd0, 0xf7, 0x45, 0xfd, 0xcb, 0xe7, 0x4c, 0x6d, + 0x52, 0x63, 0x76, 0x48, 0x6f, 0x73, 0x74, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x00, 0x00, 0xf8, 0xad, + 0x03, 0x20, 0x80, 0xb5, 0x7a, 0x21, 0x07, 0x1c, + 0xfc, 0xf7, 0x2a, 0xfd, 0x00, 0x28, 0x09, 0xd0, + 0xf8, 0x1d, 0xb9, 0x30, 0xc1, 0x6a, 0xed, 0x09, + 0x00, 0x08, 0x03, 0x00, 0x29, 0x07, 0xd0, 0x00, + 0x22, 0x1c, 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0x41, + 0xfd, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, + 0x21, 0x01, 0x63, 0xf9, 0xe7, 0xb8, 0xb5, 0x0d, + 0x1c, 0x54, 0x21, 0x14, 0x1c, 0x07, 0x1c, 0xfc, + 0xf7, 0x11, 0xfd, 0x00, 0x28, 0x0a, 0xd1, 0x12, + 0xa2, 0x00, 0x92, 0x08, 0x22, 0x24, 0x23, 0x38, + 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0xdf, 0xfb, 0xb8, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x54, 0x21, 0x38, + 0x1c, 0xfc, 0xf7, 0xc7, 0xfc, 0x00, 0x28, 0x08, + 0xd1, 0x0a, 0xa2, 0x00, 0x92, 0x08, 0x22, 0x24, + 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0xce, + 0xfb, 0xed, 0xe7, 0x54, 0x21, 0x38, 0x1c, 0x2a, + 0x1c, 0xfc, 0xf7, 0x13, 0xfd, 0x54, 0x21, 0x38, + 0x1c, 0x2a, 0x1c, 0xfc, 0xf7, 0xd2, 0xfc, 0xe2, + 0xe7, 0x00, 0x00, 0x4c, 0x6d, 0x52, 0x63, 0x76, + 0x49, 0x6e, 0x52, 0x61, 0x6e, 0x64, 0x00, 0xb8, + 0xb5, 0x0d, 0x1c, 0x5b, 0x21, 0x14, 0x1c, 0x07, + 0x1c, 0xfc, 0xf7, 0xdc, 0xfc, 0x00, 0x28, 0x0a, + 0xd1, 0x12, 0xa2, 0x00, 0x92, 0x0a, 0x22, 0x24, + 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0xaa, + 0xfb, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x5b, + 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0x92, 0xfc, 0x00, + 0x28, 0x08, 0xd1, 0x09, 0xa2, 0x00, 0x92, 0x0a, + 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, + 0xf0, 0x99, 0xfb, 0xed, 0xe7, 0x5b, 0x21, 0x38, + 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0xde, 0xfc, 0x5b, + 0x21, 0x38, 0x1c, 0x2a, 0x1c, 0xfc, 0xf7, 0x9d, + 0xfc, 0xe2, 0xe7, 0x4c, 0x6d, 0x52, 0x63, 0x76, + 0x55, 0x6e, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0xb5, 0x0d, 0x1c, 0x5a, + 0x21, 0x14, 0x1c, 0x07, 0x1c, 0xfc, 0xf7, 0xa6, + 0xfc, 0xed, 0x09, 0x00, 0x09, 0x03, 0x00, 0x28, + 0x0a, 0xd1, 0x12, 0xa2, 0x00, 0x92, 0x09, 0x22, + 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, + 0x74, 0xfb, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x5a, 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0x5c, 0xfc, + 0x00, 0x28, 0x08, 0xd1, 0x09, 0xa2, 0x00, 0x92, + 0x09, 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, + 0x01, 0xf0, 0x63, 0xfb, 0xed, 0xe7, 0x5a, 0x21, + 0x38, 0x1c, 0x22, 0x1c, 0xfc, 0xf7, 0xa8, 0xfc, + 0x5a, 0x21, 0x38, 0x1c, 0x2a, 0x1c, 0xfc, 0xf7, + 0x67, 0xfc, 0xe2, 0xe7, 0x4c, 0x6d, 0x52, 0x63, + 0x76, 0x43, 0x6f, 0x6d, 0x62, 0x4b, 0x65, 0x79, + 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb5, 0x5f, 0x25, + 0x0c, 0x1c, 0x29, 0x1c, 0x07, 0x1c, 0xfc, 0xf7, + 0x70, 0xfc, 0x00, 0x28, 0x0f, 0xd0, 0x38, 0x1c, + 0x29, 0x1c, 0xfc, 0xf7, 0x31, 0xfc, 0x00, 0x28, + 0x09, 0xd0, 0x00, 0x22, 0x38, 0x1c, 0x29, 0x1c, + 0xfc, 0xf7, 0x86, 0xfc, 0x38, 0x1c, 0x29, 0x1c, + 0x22, 0x1c, 0xfc, 0xf7, 0x45, 0xfc, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x82, 0xb0, + 0x5e, 0x26, 0x0d, 0x1c, 0x31, 0x1c, 0x14, 0x1c, + 0x07, 0x1c, 0xfc, 0xf7, 0x52, 0xfc, 0x00, 0x28, + 0x28, 0xd0, 0x38, 0x1c, 0x31, 0x1c, 0xfc, 0xf7, + 0x13, 0xfc, 0x00, 0x28, 0x22, 0xd0, 0xfa, 0x1d, + 0xff, 0x32, 0xba, 0x32, 0x02, 0x21, 0x09, 0x23, + 0x9b, 0x01, 0x51, 0x63, 0xf9, 0x18, 0x0c, 0x63, + 0xf9, 0x1d, 0xff, 0x31, 0x6e, 0x31, 0x10, 0x22, + 0xf9, 0x23, 0x9b, 0x00, 0x01, 0x92, 0xfc, 0x18, + 0x00, 0x91, 0xe9, 0x69, 0x03, 0x1c, 0x02, 0x1c, + 0x20, 0x1c, 0x01, 0x31, 0xf9, 0xf7, 0x53, 0xfa, + 0x00, 0x22, 0x38, 0x1c, 0x31, 0x1c, 0xfc, 0xf7, + 0x4f, 0xfc, 0x00, 0x22, 0x38, 0x1c, 0x31, 0x1c, + 0xfc, 0xf7, 0x0e, 0xfc, 0xed, 0x09, 0x00, 0x0a, + 0x03, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xb8, 0xb5, 0x60, 0x25, 0x29, 0x1c, 0x14, + 0x1c, 0x07, 0x1c, 0xfc, 0xf7, 0x1c, 0xfc, 0x00, + 0x28, 0x0a, 0xd1, 0x25, 0xa2, 0x00, 0x92, 0x32, + 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, + 0xf0, 0xea, 0xfa, 0xb8, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x38, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0xd2, + 0xfb, 0x00, 0x28, 0x08, 0xd1, 0x1c, 0xa2, 0x00, + 0x92, 0x32, 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, + 0x1c, 0x01, 0xf0, 0xd9, 0xfa, 0xed, 0xe7, 0xf8, + 0x1d, 0xff, 0x30, 0x7a, 0x30, 0x41, 0x6b, 0x00, + 0x29, 0x17, 0xd0, 0x00, 0x21, 0x41, 0x63, 0xf9, + 0x1d, 0xff, 0x31, 0xb2, 0x31, 0xf8, 0x1d, 0xff, + 0x30, 0x0c, 0xc9, 0x6e, 0x30, 0x0c, 0xc0, 0x0c, + 0xc9, 0x0c, 0xc0, 0x16, 0x4b, 0xf9, 0x18, 0x38, + 0x1c, 0xf9, 0xf7, 0x00, 0xff, 0x38, 0x1c, 0x21, + 0x1c, 0x32, 0x22, 0x0b, 0xa3, 0x01, 0xf0, 0xac, + 0xfa, 0x07, 0xe0, 0x09, 0xa2, 0x00, 0x92, 0x32, + 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, + 0xf0, 0xb2, 0xfa, 0x00, 0x22, 0x38, 0x1c, 0x29, + 0x1c, 0xfc, 0xf7, 0xf8, 0xfb, 0x00, 0x22, 0x38, + 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0xb7, 0xfb, 0xbc, + 0xe7, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x55, 0x73, + 0x65, 0x53, 0x65, 0x6d, 0x69, 0x50, 0x65, 0x72, + 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x4b, 0x65, + 0x79, 0x00, 0x00, 0x00, 0x00, 0x24, 0x04, 0x00, + 0x00, 0xb8, 0xb5, 0x0d, 0x1c, 0x63, 0x21, 0x14, + 0x1c, 0x07, 0x1c, 0xfc, 0xf7, 0xb8, 0xfb, 0x00, + 0x28, 0x0a, 0xd1, 0x2d, 0xa2, 0x00, 0x92, 0x0b, + 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, + 0xf0, 0x86, 0xfa, 0xb8, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x63, 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0xed, + 0x09, 0x00, 0x0b, 0x03, 0x6e, 0xfb, 0x00, 0x28, + 0x08, 0xd1, 0x24, 0xa2, 0x00, 0x92, 0x0b, 0x22, + 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, + 0x75, 0xfa, 0xed, 0xe7, 0x63, 0x22, 0x38, 0x1c, + 0xf9, 0x1d, 0x21, 0x31, 0xfc, 0xf7, 0x23, 0xfb, + 0x00, 0x28, 0x0d, 0xd1, 0xf8, 0x1d, 0xb9, 0x30, + 0x40, 0x68, 0x00, 0x28, 0x08, 0xd0, 0x19, 0xa2, + 0x00, 0x92, 0x0b, 0x22, 0x24, 0x23, 0x38, 0x1c, + 0x21, 0x1c, 0x01, 0xf0, 0x5f, 0xfa, 0xd7, 0xe7, + 0x63, 0x21, 0x38, 0x1c, 0x2a, 0x1c, 0xfc, 0xf7, + 0xa4, 0xfb, 0x63, 0x21, 0x38, 0x1c, 0x2a, 0x1c, + 0xfc, 0xf7, 0x63, 0xfb, 0x38, 0x1c, 0xf9, 0xf7, + 0x38, 0xfa, 0x00, 0x28, 0x15, 0xd0, 0x0d, 0xa2, + 0x00, 0x92, 0x0b, 0x22, 0x17, 0x25, 0x38, 0x1c, + 0x21, 0x1c, 0x2b, 0x1c, 0x01, 0xf0, 0x46, 0xfa, + 0x00, 0x28, 0xbd, 0xd1, 0x00, 0x22, 0x2e, 0x21, + 0x38, 0x1c, 0xfc, 0xf7, 0x4e, 0xfb, 0x2e, 0x21, + 0x38, 0x1c, 0x2a, 0x1c, 0xfc, 0xf7, 0x85, 0xfb, + 0xb2, 0xe7, 0x29, 0x21, 0x38, 0x1c, 0x2a, 0x1c, + 0xfc, 0xf7, 0x43, 0xfb, 0xac, 0xe7, 0x4c, 0x6d, + 0x52, 0x63, 0x76, 0x41, 0x75, 0x52, 0x61, 0x6e, + 0x64, 0x00, 0xf7, 0xb5, 0x86, 0xb0, 0x67, 0x21, + 0x07, 0x1c, 0xfc, 0xf7, 0x4f, 0xfb, 0x00, 0x28, + 0x4f, 0xd0, 0x67, 0x21, 0x38, 0x1c, 0xfc, 0xf7, + 0x10, 0xfb, 0x00, 0x28, 0x49, 0xd0, 0x38, 0x1c, + 0xfa, 0xf7, 0x5f, 0xff, 0xfe, 0x1d, 0xff, 0x36, + 0x7a, 0x36, 0xfc, 0x1d, 0xfd, 0x1d, 0xff, 0x35, + 0xff, 0x34, 0x30, 0x6a, 0x6e, 0x34, 0x9e, 0x35, + 0x00, 0x28, 0x01, 0xd0, 0x28, 0x1c, 0x00, 0xe0, + 0x20, 0x1c, 0xf9, 0x1d, 0x9d, 0x31, 0x0b, 0x68, + 0x01, 0x93, 0x4a, 0x68, 0x1b, 0x4b, 0x00, 0x92, + 0xf9, 0x18, 0x02, 0x1c, 0x02, 0xa8, 0x01, 0x9b, + 0xf9, 0xf7, 0xed, 0x09, 0x00, 0x0c, 0x03, 0x87, + 0xf9, 0x07, 0x99, 0xc8, 0x69, 0x41, 0x1c, 0x02, + 0xa8, 0x04, 0x22, 0xf5, 0xf7, 0x04, 0xfb, 0x00, + 0x28, 0x14, 0xd1, 0x00, 0x21, 0x38, 0x1c, 0xf9, + 0xf7, 0x54, 0xfa, 0x30, 0x6a, 0x00, 0x28, 0x03, + 0xd0, 0x00, 0x20, 0x30, 0x62, 0x4d, 0xcd, 0x4d, + 0xc4, 0x38, 0x1c, 0x03, 0xa9, 0xf9, 0xf7, 0x27, + 0xfe, 0x00, 0x22, 0x67, 0x21, 0x38, 0x1c, 0xfc, + 0xf7, 0xf2, 0xfa, 0x0c, 0xe0, 0x05, 0x21, 0x38, + 0x1c, 0xf9, 0xf7, 0x3f, 0xfa, 0x38, 0x1c, 0x06, + 0xa1, 0xf9, 0xf7, 0x57, 0xfe, 0x05, 0x22, 0x68, + 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0x20, 0xfb, 0x09, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x04, + 0x04, 0x00, 0x00, 0x4c, 0x6d, 0x52, 0x63, 0x76, + 0x53, 0x52, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf0, + 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x0e, 0x1c, 0x07, + 0x1c, 0x46, 0x48, 0x40, 0x68, 0xc0, 0x08, 0x08, + 0xd2, 0x45, 0xa2, 0x00, 0x92, 0x0f, 0x22, 0x1a, + 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0xb8, + 0xf9, 0x7a, 0xe0, 0x69, 0x21, 0x38, 0x1c, 0xfc, + 0xf7, 0xdb, 0xfa, 0x00, 0x28, 0x08, 0xd1, 0x3d, + 0xa2, 0x00, 0x92, 0x0f, 0x22, 0x24, 0x23, 0x38, + 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0xa9, 0xf9, 0x6b, + 0xe0, 0xf9, 0x1d, 0x21, 0x31, 0x69, 0x22, 0x38, + 0x1c, 0x01, 0x91, 0xfc, 0xf7, 0x56, 0xfa, 0x00, + 0x28, 0x08, 0xd1, 0x34, 0xa2, 0x00, 0x92, 0x0f, + 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, + 0xf0, 0x97, 0xf9, 0x59, 0xe0, 0xb8, 0x6a, 0x00, + 0x28, 0x0e, 0xd1, 0xf8, 0x1d, 0xff, 0x30, 0x3a, + 0x30, 0xc0, 0x6a, 0x00, 0x28, 0x08, 0xd1, 0x2b, + 0xa2, 0x00, 0x92, 0x0f, 0x22, 0x06, 0x23, 0x38, + 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0x85, 0xf9, 0x47, + 0xe0, 0x78, 0x6a, 0x00, 0x28, 0xed, 0x09, 0x00, + 0x0d, 0x03, 0x08, 0xd0, 0x25, 0xa2, 0x00, 0x92, + 0x0f, 0x22, 0x32, 0x23, 0x38, 0x1c, 0x21, 0x1c, + 0x01, 0xf0, 0x79, 0xf9, 0x3b, 0xe0, 0xf0, 0x69, + 0x25, 0x25, 0x41, 0x78, 0xf8, 0x1d, 0xb9, 0x30, + 0x00, 0x29, 0x04, 0xd1, 0x80, 0x68, 0x00, 0x28, + 0x0a, 0xd0, 0x69, 0x26, 0x03, 0xe0, 0x80, 0x68, + 0x00, 0x28, 0x05, 0xd1, 0x69, 0x26, 0x38, 0x1c, + 0xff, 0xf7, 0x71, 0xf9, 0x05, 0x1c, 0x16, 0xd0, + 0x16, 0xa2, 0x00, 0x92, 0x0f, 0x22, 0x32, 0x26, + 0x38, 0x1c, 0x21, 0x1c, 0x2b, 0x1c, 0x01, 0xf0, + 0x5a, 0xf9, 0x00, 0x28, 0x1b, 0xd1, 0x00, 0x23, + 0x38, 0x1c, 0x32, 0x1c, 0x01, 0x99, 0xfc, 0xf7, + 0x27, 0xfa, 0x38, 0x1c, 0x31, 0x1c, 0x2a, 0x1c, + 0xfc, 0xf7, 0x98, 0xfa, 0x0f, 0xe0, 0x10, 0x20, + 0x05, 0x23, 0xdb, 0x01, 0xf9, 0x18, 0x08, 0x62, + 0x38, 0x1c, 0x00, 0x22, 0x31, 0x1c, 0xfc, 0xf7, + 0x8d, 0xfa, 0x38, 0x1c, 0x32, 0x1c, 0x23, 0x1c, + 0x01, 0x99, 0xfc, 0xf7, 0x11, 0xfa, 0x02, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x78, 0xae, 0x03, 0x20, 0x4c, 0x6d, 0x52, 0x63, + 0x76, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x71, 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, + 0x0d, 0x1c, 0x6a, 0x21, 0x14, 0x1c, 0x07, 0x1c, + 0xfc, 0xf7, 0x49, 0xfa, 0x00, 0x28, 0x08, 0xd1, + 0x38, 0xa2, 0x00, 0x92, 0x10, 0x22, 0x24, 0x23, + 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0x17, 0xf9, + 0x63, 0xe0, 0xf9, 0x1d, 0x21, 0x31, 0x6a, 0x22, + 0x38, 0x1c, 0x0e, 0x1c, 0xfc, 0xf7, 0xc4, 0xf9, + 0x00, 0x28, 0x08, 0xd1, 0x2f, 0xa2, 0x00, 0x92, + 0x10, 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, + 0x01, 0xf0, 0x05, 0xf9, 0x51, 0xe0, 0xe8, 0x69, + 0xed, 0x09, 0x00, 0x0e, 0x03, 0xf9, 0x1d, 0x45, + 0x78, 0x38, 0x1c, 0xff, 0x31, 0x3a, 0x31, 0xfa, + 0xf7, 0x83, 0xfe, 0x2e, 0x48, 0x0b, 0x23, 0xdb, + 0x01, 0xc1, 0x18, 0x03, 0x91, 0x89, 0x6a, 0xa9, + 0x42, 0x06, 0xd8, 0x05, 0x23, 0xdb, 0x01, 0xf9, + 0x18, 0x02, 0x91, 0x09, 0x6a, 0xa9, 0x42, 0x16, + 0xd2, 0x1f, 0xa2, 0x00, 0x92, 0x10, 0x22, 0x20, + 0x25, 0x38, 0x1c, 0x21, 0x1c, 0x2b, 0x1c, 0x01, + 0xf0, 0xe4, 0xf8, 0x00, 0x28, 0x2f, 0xd1, 0x34, + 0x22, 0x38, 0x1c, 0x31, 0x1c, 0x2b, 0x1c, 0xfc, + 0xf7, 0xb1, 0xf9, 0x34, 0x21, 0x38, 0x1c, 0x2a, + 0x1c, 0xfc, 0xf7, 0x22, 0xfa, 0x23, 0xe0, 0x03, + 0x99, 0x49, 0x6a, 0xa9, 0x42, 0x0f, 0xd2, 0x1a, + 0x4b, 0x01, 0x21, 0xc2, 0x18, 0x00, 0x91, 0x10, + 0x21, 0x01, 0x92, 0x01, 0x23, 0x38, 0x1c, 0x22, + 0x1c, 0x01, 0xf0, 0x43, 0xf8, 0x03, 0x99, 0x48, + 0x6a, 0x02, 0x99, 0x08, 0x62, 0x0f, 0xe0, 0x38, + 0x1c, 0x21, 0x1c, 0x10, 0x22, 0x08, 0xa3, 0x01, + 0xf0, 0xad, 0xf8, 0x00, 0x28, 0x07, 0xd1, 0x02, + 0x99, 0x00, 0x23, 0x33, 0x22, 0x38, 0x1c, 0x0d, + 0x62, 0x31, 0x1c, 0xfc, 0xf7, 0x87, 0xf9, 0x04, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x45, 0x6e, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x4b, 0x65, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x52, + 0x65, 0x71, 0x00, 0x00, 0x00, 0xb8, 0xa8, 0x03, + 0x20, 0xa4, 0x05, 0x00, 0x00, 0xb8, 0xb5, 0x0d, + 0x1c, 0x6b, 0x21, 0x14, 0x1c, 0x07, 0x1c, 0xfc, + 0xf7, 0xbc, 0xf9, 0x00, 0x28, 0x0a, 0xd1, 0x1d, + 0xa2, 0x00, 0x92, 0x11, 0x22, 0x24, 0x23, 0x38, + 0x1c, 0x21, 0x1c, 0x01, 0xf0, 0x8a, 0xf8, 0xb8, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x6b, 0x22, 0x38, + 0x1c, 0xf9, 0x1d, 0xed, 0x09, 0x00, 0x0f, 0x03, + 0x21, 0x31, 0xfc, 0xf7, 0x36, 0xf9, 0x00, 0x28, + 0x08, 0xd1, 0x13, 0xa2, 0x00, 0x92, 0x11, 0x22, + 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x01, 0xf0, + 0x77, 0xf8, 0xeb, 0xe7, 0xf9, 0x1d, 0xff, 0x31, + 0x38, 0x1c, 0x3a, 0x31, 0xfa, 0xf7, 0xf7, 0xfd, + 0xe8, 0x69, 0x11, 0x4b, 0x41, 0x1c, 0xf8, 0x18, + 0x10, 0x22, 0xcf, 0xf7, 0x90, 0xfd, 0x38, 0x1c, + 0xfe, 0xf7, 0xbf, 0xff, 0xf8, 0x1d, 0xb9, 0x30, + 0x41, 0x68, 0x81, 0x60, 0x03, 0x21, 0x38, 0x1c, + 0xfe, 0xf7, 0xd5, 0xff, 0x38, 0x1c, 0x21, 0x1c, + 0x11, 0x22, 0x01, 0xa3, 0x01, 0xf0, 0x49, 0xf8, + 0xcc, 0xe7, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x45, 0x6e, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x00, 0x14, 0x04, 0x00, 0x00, 0x98, 0xb5, + 0x6c, 0x21, 0x14, 0x1c, 0x07, 0x1c, 0xfc, 0xf7, + 0x6b, 0xf9, 0x00, 0x28, 0x0a, 0xd1, 0x18, 0xa2, + 0x00, 0x92, 0x12, 0x22, 0x24, 0x23, 0x38, 0x1c, + 0x21, 0x1c, 0x01, 0xf0, 0x39, 0xf8, 0x98, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x6c, 0x22, 0x38, 0x1c, + 0xf9, 0x1d, 0x21, 0x31, 0xfc, 0xf7, 0xe5, 0xf8, + 0x00, 0x28, 0x08, 0xd1, 0x0f, 0xa2, 0x00, 0x92, + 0x12, 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, + 0x01, 0xf0, 0x26, 0xf8, 0xeb, 0xe7, 0xf9, 0x1d, + 0xff, 0x31, 0x38, 0x1c, 0x3a, 0x31, 0xfa, 0xf7, + 0xa6, 0xfd, 0x00, 0x21, 0x38, 0x1c, 0xfe, 0xf7, + 0x92, 0xff, 0xf9, 0x1d, 0xb9, 0x31, 0x00, 0x20, + 0x48, 0x60, 0x88, 0x60, 0x38, 0x1c, 0x21, 0x1c, + 0x12, 0x22, 0x01, 0xa3, 0x01, 0xf0, 0x01, 0xf8, + 0xd5, 0xe7, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x53, + 0x74, 0x6f, 0x70, 0x45, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0xed, 0x09, + 0x00, 0x10, 0x03, 0x65, 0x71, 0x00, 0x00, 0x90, + 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0xc8, 0x69, 0x41, + 0x1c, 0x14, 0x1c, 0x08, 0x22, 0x02, 0xa8, 0xcf, + 0xf7, 0x20, 0xfd, 0x38, 0x69, 0x02, 0x28, 0x0c, + 0xd1, 0xf9, 0x1d, 0xb9, 0x31, 0x01, 0x20, 0x88, + 0x63, 0x02, 0xa9, 0x0c, 0xc9, 0xf8, 0x1d, 0xf5, + 0x30, 0x0c, 0xc0, 0x00, 0x21, 0x38, 0x1c, 0x00, + 0xf0, 0x06, 0xff, 0x06, 0x4a, 0x08, 0x21, 0x00, + 0x91, 0x28, 0x21, 0x01, 0x23, 0x38, 0x1c, 0x01, + 0x92, 0x22, 0x1c, 0x00, 0xf0, 0x5b, 0xff, 0x04, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x7c, + 0xae, 0x03, 0x20, 0xf0, 0xb5, 0x56, 0x25, 0x0c, + 0x1c, 0x29, 0x1c, 0x07, 0x1c, 0xfc, 0xf7, 0xfa, + 0xf8, 0x00, 0x28, 0x2d, 0xd0, 0xf9, 0x1d, 0xff, + 0x31, 0x38, 0x1c, 0x1a, 0x31, 0xfa, 0xf7, 0x51, + 0xfd, 0xe0, 0x69, 0x08, 0x22, 0x41, 0x1c, 0xf8, + 0x1d, 0xf5, 0x30, 0x06, 0x1c, 0xcf, 0xf7, 0xe9, + 0xfc, 0xfc, 0x1d, 0xb9, 0x34, 0x01, 0x20, 0xa0, + 0x63, 0x00, 0x20, 0x60, 0x63, 0x00, 0x21, 0x38, + 0x1c, 0x00, 0xf0, 0xd5, 0xfe, 0xe0, 0x6b, 0x80, + 0x0a, 0x08, 0xd2, 0xf8, 0x68, 0x41, 0x6a, 0x02, + 0x29, 0x04, 0xd9, 0x02, 0x21, 0x41, 0x62, 0x38, + 0x1c, 0x02, 0xf0, 0xed, 0xff, 0x00, 0x21, 0x38, + 0x1c, 0x32, 0x1c, 0xfa, 0xf7, 0x2d, 0xff, 0x00, + 0x22, 0x38, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0xed, + 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, + 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x00, 0x20, 0x13, + 0x23, 0x5b, 0x01, 0x14, 0x1c, 0xfa, 0x18, 0x10, + 0x80, 0xc8, 0x69, 0x17, 0x23, 0xc1, 0x78, 0x9b, + 0x01, 0x0e, 0x4d, 0x51, 0x70, 0x81, 0x78, 0x11, + 0x70, 0xea, 0x18, 0x02, 0x3b, 0xe8, 0x18, 0x0b, + 0x4b, 0x02, 0x21, 0x04, 0x91, 0xe9, 0x18, 0x03, + 0x90, 0xed, 0x09, 0x00, 0x11, 0x03, 0x01, 0x20, + 0x05, 0x92, 0x02, 0x22, 0x00, 0x90, 0x01, 0x91, + 0x26, 0x21, 0x38, 0x1c, 0x02, 0x92, 0x03, 0x23, + 0x22, 0x1c, 0x00, 0xf0, 0xf6, 0xfe, 0x06, 0xb0, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0xb8, 0xa8, 0x03, 0x20, 0xbc, 0x05, 0x00, 0x00, + 0x90, 0xb5, 0x82, 0xb0, 0x0a, 0x1c, 0x0c, 0x1c, + 0x7b, 0x21, 0x07, 0x1c, 0xfc, 0xf7, 0xb4, 0xf8, + 0x00, 0x28, 0x27, 0xd1, 0xf8, 0x1d, 0xff, 0x30, + 0xba, 0x30, 0xc0, 0x69, 0x00, 0x28, 0x21, 0xd0, + 0x00, 0x20, 0x01, 0x90, 0xf9, 0x1d, 0xff, 0x31, + 0x38, 0x1c, 0x0a, 0x31, 0xfa, 0xf7, 0xe0, 0xfc, + 0xe0, 0x69, 0x00, 0x22, 0x13, 0x23, 0x5b, 0x01, + 0x41, 0x78, 0xf8, 0x18, 0x02, 0x80, 0xe2, 0x69, + 0xd3, 0x78, 0x43, 0x70, 0x93, 0x78, 0x03, 0x70, + 0xe2, 0x69, 0x01, 0xab, 0x54, 0x79, 0x5c, 0x70, + 0x14, 0x79, 0x1c, 0x70, 0x01, 0x9a, 0x00, 0x92, + 0x0a, 0x1c, 0x00, 0x21, 0x03, 0x88, 0x38, 0x1c, + 0xfa, 0xf7, 0xa0, 0xfe, 0x02, 0xb0, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x8c, 0xb0, + 0x05, 0x1c, 0x0c, 0x1c, 0x17, 0x1c, 0x1c, 0x48, + 0xf4, 0xf7, 0xa6, 0xff, 0x0b, 0x90, 0xe0, 0x69, + 0x40, 0x78, 0x0b, 0x9c, 0x21, 0x1a, 0x0e, 0x29, + 0x0a, 0x90, 0x05, 0xd3, 0x17, 0x4a, 0x10, 0x18, + 0x5d, 0x23, 0x1b, 0x01, 0xc2, 0x18, 0x11, 0xe0, + 0x00, 0x22, 0x00, 0x23, 0x06, 0xae, 0x0c, 0xc6, + 0x0c, 0xc6, 0x84, 0x42, 0x09, 0xd9, 0x11, 0x4a, + 0x10, 0x18, 0x5d, 0x23, 0x1b, 0x01, 0xc3, 0x18, + 0x0a, 0x1c, 0x19, 0x1c, 0x06, 0xa8, 0xcf, 0xf7, + 0x3b, 0xfc, 0x06, 0xaa, 0x0e, 0x21, 0x0b, 0xa8, + 0x03, 0x90, 0x04, 0x91, 0x0a, 0xa9, 0x01, 0x20, + 0x05, 0x92, 0x01, 0x22, 0x00, 0x90, 0x01, 0x91, + 0x02, 0x21, 0x28, 0x1c, 0xed, 0x09, 0x00, 0x12, + 0x03, 0x02, 0x92, 0x03, 0x23, 0x3a, 0x1c, 0x00, + 0xf0, 0x7e, 0xfe, 0x0c, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x88, 0xae, 0x03, + 0x20, 0xb8, 0xa8, 0x03, 0x20, 0xf7, 0xb5, 0x84, + 0xb0, 0x7c, 0x21, 0x07, 0x1c, 0xfc, 0xf7, 0x1b, + 0xf8, 0x00, 0x28, 0x60, 0xd0, 0xf8, 0x1d, 0xff, + 0x30, 0xba, 0x30, 0x00, 0x6a, 0x00, 0x28, 0x5a, + 0xd0, 0x05, 0x99, 0x00, 0x24, 0xc8, 0x69, 0xf9, + 0x1d, 0xff, 0x31, 0x46, 0x78, 0x85, 0x78, 0x0e, + 0x31, 0x03, 0x91, 0x38, 0x1c, 0xfa, 0xf7, 0x66, + 0xfc, 0x0b, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x02, + 0x90, 0x40, 0x6a, 0xb0, 0x42, 0x01, 0xd0, 0x1f, + 0x24, 0x1f, 0xe0, 0xf8, 0x2d, 0x19, 0xd8, 0xb5, + 0x42, 0x01, 0xd2, 0x1f, 0x24, 0x19, 0xe0, 0xaa, + 0x1b, 0x01, 0x92, 0x0e, 0x2a, 0x01, 0xd9, 0x0e, + 0x22, 0x01, 0x92, 0x05, 0x99, 0xc8, 0x69, 0x01, + 0x9a, 0xc1, 0x1c, 0xb8, 0x19, 0xff, 0x30, 0xff, + 0x30, 0xea, 0x30, 0xcf, 0xf7, 0xe7, 0xfb, 0x02, + 0x98, 0x40, 0x6a, 0x01, 0x9a, 0x02, 0x99, 0x80, + 0x18, 0x48, 0x62, 0x02, 0x98, 0x40, 0x6a, 0xa8, + 0x42, 0x12, 0xd1, 0xf8, 0x1d, 0xb9, 0x30, 0xc0, + 0x69, 0x00, 0x28, 0x05, 0xd0, 0x02, 0x21, 0x38, + 0x1c, 0x22, 0x1c, 0xfb, 0xf7, 0xf7, 0xff, 0x1a, + 0xe0, 0x5d, 0x23, 0xdb, 0x00, 0xfa, 0x18, 0x38, + 0x1c, 0x21, 0x1c, 0xfa, 0xf7, 0x8f, 0xfe, 0x12, + 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x04, 0xfc, 0xb9, + 0x23, 0x9b, 0x00, 0xfa, 0x18, 0x01, 0x92, 0x01, + 0x21, 0x02, 0x1c, 0x01, 0x23, 0x38, 0x1c, 0x00, + 0x91, 0x00, 0xf0, 0x11, 0xfe, 0x03, 0x99, 0x04, + 0x4a, 0x38, 0x1c, 0xfa, 0xf7, 0x2f, 0xfc, 0x07, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x9b, 0xb2, 0x02, 0x20, 0x70, 0x47, 0xed, + 0x09, 0x00, 0x13, 0x03, 0xb0, 0xb5, 0xc9, 0x69, + 0x4c, 0x78, 0xe2, 0x07, 0xd2, 0x0f, 0x0b, 0x23, + 0x9b, 0x01, 0xc7, 0x18, 0x00, 0x2a, 0x02, 0xd0, + 0x02, 0x21, 0x39, 0x60, 0x01, 0xe0, 0x01, 0x21, + 0x39, 0x60, 0x00, 0x25, 0x05, 0x23, 0xdb, 0x01, + 0xc1, 0x18, 0x06, 0x23, 0x23, 0x40, 0x02, 0x2b, + 0xcd, 0x63, 0x19, 0xd0, 0x04, 0x2b, 0x0a, 0xd0, + 0x06, 0x2b, 0x21, 0xd1, 0x00, 0x2a, 0x03, 0xd0, + 0x01, 0x23, 0xdb, 0x03, 0xcb, 0x63, 0x02, 0xe0, + 0x01, 0x23, 0x9b, 0x03, 0xcb, 0x63, 0x00, 0x2a, + 0x05, 0xd0, 0x01, 0x23, 0xcc, 0x6b, 0xdb, 0x02, + 0x23, 0x43, 0xcb, 0x63, 0x04, 0xe0, 0x01, 0x23, + 0xcc, 0x6b, 0x9b, 0x02, 0x23, 0x43, 0xcb, 0x63, + 0x00, 0x2a, 0x04, 0xd0, 0xca, 0x6b, 0x10, 0x23, + 0x1a, 0x43, 0xca, 0x63, 0x0b, 0xe0, 0xca, 0x6b, + 0x08, 0x23, 0x1a, 0x43, 0xca, 0x63, 0x06, 0xe0, + 0x00, 0x2a, 0x02, 0xd0, 0x05, 0x4a, 0xca, 0x63, + 0x01, 0xe0, 0x04, 0x4a, 0xca, 0x63, 0x39, 0x68, + 0x00, 0xf0, 0x5d, 0xfd, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x10, 0x88, 0x00, 0x00, 0x08, 0x44, + 0x00, 0x00, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, + 0x08, 0x1c, 0x11, 0x1c, 0x00, 0x22, 0x03, 0x92, + 0xc2, 0x69, 0x03, 0xab, 0x94, 0x78, 0x5c, 0x70, + 0x54, 0x78, 0x1c, 0x70, 0xc0, 0x69, 0xc4, 0x78, + 0x03, 0x98, 0x04, 0x28, 0x07, 0xd2, 0x16, 0xa2, + 0x00, 0x92, 0x2a, 0x22, 0x20, 0x23, 0x38, 0x1c, + 0x00, 0xf0, 0x20, 0xfe, 0x20, 0xe0, 0x38, 0x1c, + 0x2a, 0x22, 0x11, 0xa3, 0x00, 0xf0, 0x0b, 0xfe, + 0x0b, 0x23, 0x9b, 0x01, 0x03, 0x98, 0xf9, 0x18, + 0xc8, 0x61, 0x38, 0x1c, 0x22, 0x1c, 0x03, 0x99, + 0xfc, 0xf7, 0x54, 0xfc, 0x00, 0x22, 0xd2, 0x43, + 0x03, 0x9c, 0x0e, 0x49, 0x02, 0x92, 0x61, 0x43, + 0x00, 0x20, 0xed, 0x09, 0x00, 0x14, 0x03, 0xc3, + 0x43, 0x04, 0x2c, 0x00, 0x90, 0x01, 0x91, 0x00, + 0xd9, 0x00, 0x23, 0x01, 0x22, 0x00, 0x21, 0x38, + 0x1c, 0xfa, 0xf7, 0x31, 0xfe, 0x04, 0xb0, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, + 0x6d, 0x52, 0x63, 0x76, 0x51, 0x6f, 0x73, 0x53, + 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x00, + 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x90, + 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x00, 0x20, 0x03, + 0x90, 0xc8, 0x69, 0x03, 0xab, 0x82, 0x78, 0x5a, + 0x70, 0x42, 0x78, 0x1a, 0x70, 0xc8, 0x69, 0x0b, + 0x23, 0xc2, 0x78, 0x03, 0x98, 0x9b, 0x01, 0xf9, + 0x18, 0xc8, 0x61, 0x03, 0x99, 0x38, 0x1c, 0xfc, + 0xf7, 0x1b, 0xfc, 0x00, 0x22, 0xd2, 0x43, 0x03, + 0x9c, 0x09, 0x49, 0x02, 0x92, 0x61, 0x43, 0x00, + 0x20, 0xc3, 0x43, 0x04, 0x2c, 0x00, 0x90, 0x01, + 0x91, 0x00, 0xd9, 0x00, 0x23, 0x01, 0x22, 0x00, + 0x21, 0x38, 0x1c, 0xfa, 0xf7, 0xf8, 0xfd, 0x04, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x71, + 0x02, 0x00, 0x00, 0x98, 0xb5, 0x07, 0x1c, 0x08, + 0x1c, 0xc0, 0x69, 0x11, 0x1c, 0x44, 0x78, 0x01, + 0x2c, 0x01, 0xd3, 0x05, 0x2c, 0x09, 0xd9, 0x14, + 0xa2, 0x00, 0x92, 0x2e, 0x22, 0x20, 0x23, 0x38, + 0x1c, 0x00, 0xf0, 0xae, 0xfd, 0x98, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x13, 0x48, 0x03, 0x2c, 0x03, + 0xd9, 0x42, 0x68, 0x92, 0x08, 0x07, 0xd3, 0x01, + 0xe0, 0x01, 0x2c, 0x0c, 0xd9, 0x40, 0x68, 0x42, + 0x08, 0x09, 0xd2, 0x80, 0x08, 0x07, 0xd2, 0x08, + 0xa2, 0x00, 0x92, 0x2e, 0x22, 0x20, 0x23, 0x38, + 0x1c, 0x00, 0xf0, 0x96, 0xfd, 0xe6, 0xe7, 0x38, + 0x1c, 0x2e, 0x22, 0x03, 0xa3, 0x00, 0xf0, 0x81, + 0xfd, 0x0b, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x44, + 0x60, 0xdc, 0xe7, 0x4c, 0x6d, 0xed, 0x09, 0x00, + 0x15, 0x03, 0x52, 0x63, 0x76, 0x4d, 0x61, 0x78, + 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x00, + 0x78, 0xae, 0x03, 0x20, 0x80, 0xb5, 0x07, 0x1c, + 0xc8, 0x69, 0x40, 0x78, 0x01, 0x28, 0x12, 0xd3, + 0x05, 0x28, 0x10, 0xd8, 0x0b, 0x23, 0x9b, 0x01, + 0xf9, 0x18, 0x8a, 0x68, 0x82, 0x42, 0x0a, 0xd0, + 0x88, 0x60, 0x00, 0x21, 0x38, 0x1c, 0x00, 0xf0, + 0x8b, 0xfc, 0x78, 0x69, 0x0e, 0x28, 0x02, 0xd1, + 0x38, 0x1c, 0xfa, 0xf7, 0x39, 0xfd, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x83, 0xb0, + 0x01, 0x69, 0x13, 0x1c, 0x01, 0x29, 0x0d, 0xd1, + 0x00, 0x21, 0x02, 0xaa, 0x01, 0x92, 0x02, 0x91, + 0x02, 0x21, 0x1a, 0x1c, 0x01, 0x23, 0x00, 0x91, + 0x06, 0x21, 0x00, 0xf0, 0xd0, 0xfc, 0x03, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x46, 0x22, 0x19, 0x1c, + 0xf7, 0xf7, 0xd8, 0xfe, 0xf7, 0xe7, 0x98, 0xb5, + 0x0c, 0x1c, 0x81, 0x21, 0x07, 0x1c, 0xfb, 0xf7, + 0x6e, 0xfe, 0x00, 0x28, 0x18, 0xd0, 0xf8, 0x1d, + 0xff, 0x30, 0xba, 0x30, 0x80, 0x69, 0x00, 0x28, + 0x12, 0xd0, 0x00, 0x20, 0x00, 0x90, 0xf9, 0x1d, + 0xff, 0x31, 0x38, 0x1c, 0x06, 0x31, 0xfa, 0xf7, + 0xbd, 0xfa, 0xe0, 0x69, 0x00, 0xab, 0x81, 0x78, + 0x59, 0x70, 0x41, 0x78, 0x19, 0x70, 0x00, 0x21, + 0x38, 0x1c, 0x00, 0x9a, 0xfa, 0xf7, 0xdc, 0xfc, + 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, + 0x52, 0x25, 0x0c, 0x1c, 0x29, 0x1c, 0x07, 0x1c, + 0xfb, 0xf7, 0x49, 0xfe, 0x00, 0x28, 0x13, 0xd0, + 0xf9, 0x1d, 0x1d, 0x31, 0x38, 0x1c, 0x2a, 0x1c, + 0x0e, 0x1c, 0xfb, 0xf7, 0xcd, 0xfd, 0x00, 0x28, + 0x0a, 0xd0, 0x38, 0x1c, 0x29, 0x1c, 0x02, 0x9a, + 0xfb, 0xf7, 0x5c, 0xfe, 0x38, 0x1c, 0x31, 0x1c, + 0x2a, 0x1c, 0x23, 0x1c, 0xfb, 0xf7, 0xe0, 0xfd, + 0xed, 0x09, 0x00, 0x16, 0x03, 0x03, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, 0x81, + 0xb0, 0x53, 0x25, 0x29, 0x1c, 0x14, 0x1c, 0x07, + 0x1c, 0xfb, 0xf7, 0x27, 0xfe, 0x00, 0x28, 0x0b, + 0xd1, 0x15, 0xa2, 0x00, 0x92, 0x13, 0x22, 0x24, + 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 0xf5, + 0xfc, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf9, 0x1d, 0x1d, 0x31, 0x38, 0x1c, 0x2a, + 0x1c, 0x0e, 0x1c, 0xfb, 0xf7, 0x9f, 0xfd, 0x00, + 0x28, 0x08, 0xd1, 0x0b, 0xa2, 0x00, 0x92, 0x13, + 0x22, 0x24, 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x00, + 0xf0, 0xe0, 0xfc, 0xe9, 0xe7, 0x38, 0x1c, 0x29, + 0x1c, 0x22, 0x1c, 0xfb, 0xf7, 0x25, 0xfe, 0x00, + 0x28, 0xe2, 0xd1, 0x38, 0x1c, 0x31, 0x1c, 0x2a, + 0x1c, 0x02, 0x9b, 0xfb, 0xf7, 0xa7, 0xfd, 0xdb, + 0xe7, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x53, 0x77, + 0x69, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x00, + 0x00, 0x90, 0xb5, 0x14, 0x1c, 0x07, 0x1c, 0x04, + 0xf0, 0xef, 0xfb, 0xff, 0x23, 0x03, 0x33, 0x98, + 0x42, 0x01, 0xd3, 0x07, 0x21, 0x00, 0xe0, 0x05, + 0x21, 0xf8, 0x68, 0x42, 0x6a, 0x91, 0x42, 0x13, + 0xd8, 0x01, 0x23, 0x9b, 0x02, 0xf8, 0x18, 0xc0, + 0x6b, 0x00, 0x28, 0x04, 0xd0, 0x01, 0x22, 0x00, + 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0x27, 0xfb, 0x00, + 0x23, 0x21, 0x21, 0x38, 0x1c, 0x22, 0x1c, 0x00, + 0xf0, 0x24, 0xfc, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x38, + 0x1c, 0x02, 0xf0, 0xe0, 0xfc, 0xf5, 0xe7, 0x90, + 0xb5, 0x07, 0x1c, 0xc0, 0x68, 0x14, 0x1c, 0x41, + 0x6a, 0x00, 0x29, 0x12, 0xd1, 0x01, 0x23, 0x9b, + 0x02, 0xf8, 0x18, 0xc0, 0x6b, 0x00, 0x28, 0x03, + 0xd0, 0x01, 0x22, 0x38, 0x1c, 0xfc, 0xf7, 0x06, + 0xfb, 0x00, 0x23, 0xed, 0x09, 0x00, 0x17, 0x03, + 0x22, 0x21, 0x38, 0x1c, 0x22, 0x1c, 0x00, 0xf0, + 0x03, 0xfc, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x41, 0x6a, 0x01, 0x39, 0x41, 0x62, 0x38, 0x1c, + 0x02, 0xf0, 0xbf, 0xfc, 0xf5, 0xe7, 0xff, 0x30, + 0x41, 0x30, 0x81, 0x68, 0x01, 0x61, 0x70, 0x47, + 0xff, 0x30, 0x41, 0x30, 0x81, 0x68, 0xc1, 0x60, + 0x70, 0x47, 0x08, 0xb5, 0x00, 0x22, 0x00, 0x92, + 0xc9, 0x69, 0x00, 0xab, 0x8a, 0x78, 0x5a, 0x70, + 0x4a, 0x78, 0x1a, 0x70, 0x00, 0x99, 0x01, 0xf0, + 0x4a, 0xfc, 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, + 0x08, 0xb5, 0x11, 0x1c, 0x06, 0x4a, 0x52, 0x68, + 0xd2, 0x09, 0x05, 0xd2, 0x05, 0xa2, 0x00, 0x92, + 0x1a, 0x23, 0x15, 0x22, 0x00, 0xf0, 0x58, 0xfc, + 0x01, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x78, 0xae, + 0x03, 0x20, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x48, + 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x71, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x47, 0x08, 0xb5, 0x11, 0x1c, + 0x06, 0x4a, 0x52, 0x68, 0x12, 0x0a, 0x05, 0xd2, + 0x05, 0xa2, 0x00, 0x92, 0x1a, 0x23, 0x17, 0x22, + 0x00, 0xf0, 0x3e, 0xfc, 0x01, 0xb0, 0x08, 0xbc, + 0x18, 0x47, 0x78, 0xae, 0x03, 0x20, 0x4c, 0x6d, + 0x52, 0x63, 0x76, 0x53, 0x6e, 0x69, 0x66, 0x66, + 0x52, 0x65, 0x71, 0x00, 0x00, 0x00, 0x08, 0xb5, + 0x11, 0x1c, 0x06, 0x4a, 0x52, 0x68, 0x12, 0x0a, + 0x05, 0xd2, 0x05, 0xa2, 0x00, 0x92, 0x1a, 0x23, + 0x18, 0x22, 0x00, 0xf0, 0x25, 0xfc, 0x01, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0xae, + 0x03, 0x20, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x55, + 0x6e, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x52, 0x65, + 0x71, 0x00, 0x98, 0xb5, 0x07, 0x1c, 0x11, 0x48, + 0x14, 0x1c, 0x00, 0x6b, 0x00, 0x28, 0x15, 0xd0, + 0x01, 0x20, 0x83, 0x02, 0xf9, 0x18, 0xed, 0x09, + 0x00, 0x18, 0x03, 0xc8, 0x63, 0x00, 0x20, 0x11, + 0x23, 0x9b, 0x01, 0xf9, 0x18, 0x08, 0x60, 0x01, + 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0x2a, 0xfa, 0x38, + 0x1c, 0x21, 0x1c, 0x38, 0x22, 0x08, 0xa3, 0x00, + 0xf0, 0xee, 0xfb, 0x98, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x05, 0xa2, 0x00, 0x92, 0x38, 0x22, 0x24, + 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 0xf2, + 0xfb, 0xf3, 0xe7, 0x38, 0xae, 0x03, 0x20, 0x4c, + 0x6d, 0x52, 0x63, 0x76, 0x54, 0x65, 0x73, 0x74, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x00, 0x00, 0x00, 0xb8, 0xb5, 0x01, 0x23, 0x9b, + 0x02, 0x07, 0x1c, 0xc0, 0x18, 0xc0, 0x6b, 0x14, + 0x1c, 0x00, 0x28, 0x3d, 0xd0, 0xc8, 0x69, 0x55, + 0x22, 0x40, 0x78, 0x42, 0x40, 0x11, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0x82, 0x61, 0xca, 0x69, 0x55, + 0x23, 0x92, 0x78, 0x5a, 0x40, 0xc2, 0x61, 0xca, + 0x69, 0xd2, 0x78, 0x5a, 0x40, 0x42, 0x60, 0xca, + 0x69, 0x12, 0x79, 0x5a, 0x40, 0x82, 0x60, 0xca, + 0x69, 0x92, 0x79, 0x5a, 0x40, 0xc2, 0x60, 0xca, + 0x69, 0xd2, 0x79, 0x5a, 0x40, 0x42, 0x61, 0x00, + 0x22, 0x02, 0x61, 0xca, 0x69, 0x45, 0x23, 0x55, + 0x7a, 0x1b, 0x01, 0xfb, 0x18, 0x5d, 0x70, 0x15, + 0x7a, 0x1d, 0x70, 0x02, 0x69, 0x0f, 0x4b, 0x5a, + 0x40, 0x02, 0x61, 0xc9, 0x69, 0x55, 0x23, 0x49, + 0x79, 0x59, 0x40, 0x01, 0x60, 0x00, 0x21, 0x01, + 0x22, 0x38, 0x1c, 0xfc, 0xf7, 0x20, 0xfa, 0x38, + 0x1c, 0x21, 0x1c, 0x39, 0x22, 0x08, 0xa3, 0x00, + 0xf0, 0x92, 0xfb, 0xb8, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x05, 0xa2, 0x00, 0x92, 0x39, 0x22, 0x24, + 0x23, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 0x96, + 0xfb, 0xf3, 0xe7, 0x55, 0x55, 0x00, 0x00, 0x4c, + 0x6d, 0x52, 0x63, 0x76, 0x54, 0x65, 0x73, 0x74, + 0x43, 0xed, 0x09, 0x00, 0x19, 0x03, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xb5, 0x07, 0x1c, 0xc8, 0x69, 0x42, 0x78, + 0x00, 0x2a, 0x00, 0xd1, 0x13, 0x22, 0x55, 0x21, + 0x38, 0x1c, 0xfb, 0xf7, 0xc9, 0xfc, 0x00, 0x28, + 0x19, 0xd1, 0x38, 0x1c, 0x02, 0xf0, 0x78, 0xfb, + 0x38, 0x1c, 0xfa, 0xf7, 0x3d, 0xf9, 0x0b, 0x23, + 0x9b, 0x01, 0x38, 0x69, 0xf9, 0x18, 0x01, 0x28, + 0x04, 0xd1, 0xc8, 0x69, 0x07, 0x4a, 0x42, 0x43, + 0x00, 0x21, 0x03, 0xe0, 0xc8, 0x69, 0x06, 0x4a, + 0x42, 0x43, 0x00, 0x21, 0x0b, 0x1c, 0x00, 0x21, + 0x38, 0x1c, 0xfa, 0xf7, 0x41, 0xf9, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x1d, 0x00, 0x00, + 0xa6, 0x0e, 0x00, 0x00, 0xf0, 0xb5, 0x82, 0xb0, + 0x8e, 0x69, 0x00, 0x2e, 0x4d, 0xd0, 0xca, 0x69, + 0x12, 0x78, 0xd4, 0x07, 0xe4, 0x0f, 0x57, 0x08, + 0x79, 0x2f, 0x03, 0xd1, 0x22, 0x1c, 0x02, 0xf0, + 0x83, 0xfd, 0x42, 0xe0, 0x00, 0x2f, 0x01, 0xd0, + 0x39, 0x2f, 0x07, 0xdd, 0x21, 0xa2, 0x00, 0x92, + 0x19, 0x23, 0x21, 0x1c, 0x3a, 0x1c, 0x00, 0xf0, + 0x40, 0xfb, 0x36, 0xe0, 0x21, 0x4b, 0x3a, 0x01, + 0xd2, 0x18, 0xff, 0x32, 0x81, 0x32, 0x93, 0x69, + 0x01, 0x93, 0x00, 0x2b, 0x07, 0xd1, 0x19, 0xa2, + 0x00, 0x92, 0x1a, 0x23, 0x21, 0x1c, 0x3a, 0x1c, + 0x00, 0xf0, 0x2f, 0xfb, 0x25, 0xe0, 0x15, 0x69, + 0x01, 0x23, 0xdd, 0x42, 0x09, 0xd0, 0xae, 0x42, + 0x07, 0xd2, 0x12, 0xa2, 0x00, 0x92, 0x1e, 0x23, + 0x21, 0x1c, 0x3a, 0x1c, 0x00, 0xf0, 0x21, 0xfb, + 0x17, 0xe0, 0x03, 0x69, 0x01, 0x2b, 0x03, 0xd1, + 0x52, 0x69, 0x01, 0x2a, 0x0d, 0xd1, 0x04, 0xe0, + 0x02, 0x2b, 0x0a, 0xd1, 0x52, 0x69, 0x02, 0x2a, + 0x07, 0xd1, 0x08, 0xa2, 0x00, 0x92, 0x24, 0x23, + 0x21, 0x1c, 0x3a, 0x1c, 0xed, 0x09, 0x00, 0x1a, + 0x03, 0x00, 0xf0, 0x0d, 0xfb, 0x03, 0xe0, 0x01, + 0x9b, 0x22, 0x1c, 0xcf, 0xf7, 0x10, 0xf8, 0x02, + 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x4c, 0x6d, 0x52, 0x63, 0x76, 0x4c, 0x4d, + 0x50, 0x46, 0x72, 0x6f, 0x6d, 0x4c, 0x43, 0x00, + 0x00, 0xb8, 0xa8, 0x03, 0x20, 0x80, 0xb5, 0x07, + 0x1c, 0xc0, 0x68, 0xf7, 0xf7, 0x71, 0xfc, 0x00, + 0x28, 0x0c, 0xd0, 0x3f, 0x69, 0x00, 0x2f, 0x09, + 0xd0, 0x79, 0x69, 0x03, 0x29, 0x06, 0xd1, 0x39, + 0x1c, 0xff, 0xf7, 0x8e, 0xff, 0x38, 0x1c, 0x03, + 0xa1, 0xf6, 0xf7, 0x37, 0xfe, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x73, 0x72, 0x63, + 0x5c, 0x6c, 0x6d, 0x72, 0x63, 0x76, 0x2e, 0x63, + 0x3a, 0x20, 0x32, 0x33, 0x36, 0x34, 0x00, 0x00, + 0x00, 0xff, 0x30, 0xff, 0x30, 0x00, 0x22, 0x4a, + 0x63, 0x82, 0x30, 0x02, 0x6b, 0x00, 0x2a, 0x02, + 0xd0, 0x51, 0x63, 0x01, 0x63, 0x70, 0x47, 0xc1, + 0x62, 0x01, 0x63, 0x70, 0x47, 0x05, 0x23, 0xdb, + 0x01, 0xc1, 0x18, 0xc8, 0x6a, 0x00, 0x28, 0x04, + 0xd0, 0x42, 0x6b, 0xca, 0x62, 0x00, 0x2a, 0x00, + 0xd1, 0x0a, 0x63, 0x70, 0x47, 0x88, 0xb5, 0x07, + 0x1c, 0xff, 0x30, 0xff, 0x30, 0x82, 0x30, 0x81, + 0x6a, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x39, 0x81, + 0x62, 0x80, 0x6a, 0x00, 0x28, 0x10, 0xd1, 0x38, + 0x1c, 0xff, 0xf7, 0xe4, 0xff, 0x00, 0x28, 0x0b, + 0xd0, 0x00, 0x90, 0x82, 0x6a, 0x01, 0x1c, 0x00, + 0x23, 0x38, 0x1c, 0x01, 0xf0, 0xd7, 0xf9, 0x38, + 0x1c, 0xff, 0xf7, 0xd8, 0xff, 0x00, 0x28, 0xf3, + 0xd1, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, + 0x69, 0x00, 0x20, 0x01, 0x29, 0x02, 0xd0, 0x02, + 0x29, 0x00, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x01, + 0x69, 0x01, 0x20, 0x01, 0x29, 0x02, 0xd0, 0xed, + 0x09, 0x00, 0x1b, 0x03, 0x02, 0x29, 0x00, 0xd1, + 0x00, 0x20, 0x70, 0x47, 0xb0, 0xb5, 0x07, 0x1c, + 0x00, 0x29, 0x1c, 0xd1, 0x00, 0x2a, 0x1a, 0xd0, + 0x4a, 0x24, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0xf7, + 0xa9, 0xfb, 0x00, 0x28, 0x13, 0xd0, 0xf9, 0x1d, + 0x21, 0x31, 0x38, 0x1c, 0x22, 0x1c, 0x0d, 0x1c, + 0xfb, 0xf7, 0x2d, 0xfb, 0x00, 0x28, 0x0a, 0xd0, + 0x00, 0x23, 0x38, 0x1c, 0x29, 0x1c, 0x22, 0x1c, + 0xfb, 0xf7, 0x45, 0xfb, 0x00, 0x22, 0x38, 0x1c, + 0x21, 0x1c, 0xfb, 0xf7, 0xb6, 0xfb, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x07, 0x1c, + 0x00, 0x2a, 0x1a, 0xd0, 0x4b, 0x24, 0x38, 0x1c, + 0x21, 0x1c, 0xfb, 0xf7, 0x87, 0xfb, 0x00, 0x28, + 0x13, 0xd0, 0xf9, 0x1d, 0x21, 0x31, 0x38, 0x1c, + 0x22, 0x1c, 0x0d, 0x1c, 0xfb, 0xf7, 0x0b, 0xfb, + 0x00, 0x28, 0x0a, 0xd0, 0x00, 0x23, 0x38, 0x1c, + 0x29, 0x1c, 0x22, 0x1c, 0xfb, 0xf7, 0x23, 0xfb, + 0x00, 0x22, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0xf7, + 0x94, 0xfb, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x90, 0xb5, 0x07, 0x1c, 0x00, 0x2a, 0x01, 0xd0, + 0x46, 0x24, 0x00, 0xe0, 0x47, 0x24, 0x38, 0x1c, + 0x21, 0x1c, 0xfb, 0xf7, 0x63, 0xfb, 0x00, 0x28, + 0x0f, 0xd0, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0xf7, + 0x24, 0xfb, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x22, + 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0xf7, 0x3d, 0xfb, + 0x00, 0x22, 0x38, 0x1c, 0x21, 0x1c, 0xfb, 0xf7, + 0x74, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xb0, 0xb5, 0x07, 0x1c, 0x00, 0x2a, 0x16, 0xd0, + 0x01, 0x23, 0x9b, 0x02, 0xfd, 0x18, 0xe8, 0x6b, + 0x00, 0x28, 0x10, 0xd0, 0x11, 0x23, 0x9b, 0x01, + 0xfc, 0x18, 0x00, 0x22, 0x38, 0x1c, 0xa1, 0x69, + 0xfc, 0xf7, 0x8d, 0xf8, 0xa0, 0x69, 0xff, 0x28, + 0x05, 0xd1, 0xed, 0x09, 0x00, 0x1c, 0x03, 0x00, + 0x21, 0x38, 0x1c, 0xfc, 0xf7, 0x34, 0xf8, 0x00, + 0x20, 0xe8, 0x63, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0xb5, 0x0b, 0x1c, 0x11, 0x1c, 0x1a, + 0x0a, 0x52, 0x06, 0x52, 0x0e, 0x11, 0x2a, 0x0a, + 0xd0, 0x12, 0x2a, 0x0c, 0xd0, 0x32, 0x2a, 0x0e, + 0xd0, 0x39, 0x2a, 0x02, 0xd1, 0x01, 0x22, 0xff, + 0xf7, 0xd1, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, + 0x22, 0xff, 0xf7, 0x66, 0xff, 0xf9, 0xe7, 0x01, + 0x22, 0xff, 0xf7, 0x86, 0xff, 0xf5, 0xe7, 0x01, + 0x22, 0xff, 0xf7, 0xa4, 0xff, 0xf1, 0xe7, 0x00, + 0xb5, 0x0b, 0x1c, 0x11, 0x1c, 0x1a, 0x0a, 0x52, + 0x06, 0x52, 0x0e, 0x11, 0x2a, 0x0a, 0xd0, 0x12, + 0x2a, 0x0c, 0xd0, 0x32, 0x2a, 0x0e, 0xd0, 0x39, + 0x2a, 0x02, 0xd1, 0x00, 0x22, 0xff, 0xf7, 0xb2, + 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22, 0xff, + 0xf7, 0x47, 0xff, 0xf9, 0xe7, 0x00, 0x22, 0xff, + 0xf7, 0x67, 0xff, 0xf5, 0xe7, 0x00, 0x22, 0xff, + 0xf7, 0x85, 0xff, 0xf1, 0xe7, 0x80, 0xb5, 0x4c, + 0x21, 0x07, 0x1c, 0xfb, 0xf7, 0xed, 0xfa, 0x00, + 0x28, 0x09, 0xd0, 0xf8, 0x1d, 0xb9, 0x30, 0x01, + 0x6b, 0x00, 0x29, 0x07, 0xd0, 0x00, 0x22, 0x1c, + 0x21, 0x38, 0x1c, 0xfb, 0xf7, 0x04, 0xfb, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x21, 0xc1, + 0x62, 0xf9, 0xe7, 0x90, 0xb5, 0x04, 0x1c, 0xf9, + 0xf7, 0x76, 0xff, 0xcf, 0xf7, 0x6d, 0xfa, 0x07, + 0x1c, 0x09, 0xd0, 0x00, 0x22, 0x4d, 0x21, 0x20, + 0x1c, 0xfb, 0xf7, 0xf1, 0xfa, 0x00, 0x28, 0x05, + 0xd0, 0x38, 0x1c, 0xcf, 0xf7, 0x9c, 0xfa, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x07, 0xa1, 0x0c, + 0xc9, 0xe0, 0x1d, 0xb1, 0x30, 0x0c, 0xc0, 0x57, + 0x20, 0x38, 0x60, 0x20, 0x6b, 0xf8, 0x60, 0x07, + 0x20, 0x39, 0x1c, 0xcf, 0xf7, 0xed, 0x09, 0x00, + 0x1d, 0x03, 0xc0, 0xfa, 0xee, 0xe7, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xb5, 0x00, 0x22, 0x45, 0x21, 0x07, 0x1c, + 0xfb, 0xf7, 0xd0, 0xfa, 0x00, 0x28, 0x04, 0xd1, + 0x00, 0x22, 0x45, 0x21, 0x38, 0x1c, 0xfb, 0xf7, + 0x8d, 0xfa, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x01, 0x23, 0x9b, 0x02, 0xc1, 0x18, + 0xc9, 0x6b, 0x00, 0x29, 0x06, 0xd0, 0x11, 0x23, + 0x9b, 0x01, 0xc1, 0x18, 0x89, 0x69, 0x00, 0x22, + 0xfb, 0xf7, 0xe6, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0xb5, 0x01, 0x23, 0x9b, 0x02, 0xc1, 0x18, + 0xc9, 0x6b, 0x00, 0x29, 0x06, 0xd0, 0x11, 0x23, + 0x9b, 0x01, 0xc1, 0x18, 0x89, 0x69, 0x00, 0x22, + 0xfb, 0xf7, 0xd6, 0xff, 0x08, 0xbc, 0x18, 0x47, + 0xf0, 0xb5, 0x04, 0x1c, 0x65, 0x69, 0xc0, 0x68, + 0x26, 0x69, 0xf7, 0xf7, 0xd1, 0xfa, 0x07, 0x1c, + 0x1c, 0xd0, 0xa0, 0x69, 0x03, 0x28, 0x1c, 0xd1, + 0x00, 0x2d, 0x17, 0xd0, 0xa9, 0x6a, 0x48, 0x06, + 0x40, 0x0e, 0x79, 0x28, 0x0f, 0xd0, 0x00, 0x28, + 0x0d, 0xd0, 0x39, 0x28, 0x0b, 0xdc, 0x29, 0x4a, + 0x00, 0x01, 0x80, 0x18, 0xff, 0x30, 0x81, 0x30, + 0xc3, 0x69, 0x00, 0x2b, 0x03, 0xd0, 0x38, 0x1c, + 0x32, 0x1c, 0xce, 0xf7, 0x40, 0xfe, 0x28, 0x1c, + 0xf6, 0xf7, 0xb6, 0xfe, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xcf, 0xf7, 0xf0, 0xf9, 0x00, 0x28, + 0x09, 0xd0, 0xd6, 0x21, 0x01, 0x60, 0xf9, 0x6a, + 0xc1, 0x60, 0x06, 0x61, 0x45, 0x61, 0x01, 0x1c, + 0x05, 0x20, 0xcf, 0xf7, 0x53, 0xfa, 0xf8, 0x1d, + 0xff, 0x30, 0x3a, 0x30, 0x41, 0x68, 0x00, 0x29, + 0xe8, 0xd0, 0x01, 0x39, 0x41, 0x60, 0xe5, 0xd1, + 0x78, 0x6a, 0x14, 0x28, 0x01, 0xd0, 0x19, 0x28, + 0x06, 0xd1, 0x00, 0x23, 0x15, 0x22, 0x38, 0x1c, + 0xed, 0x09, 0x00, 0x1e, 0x03, 0xf9, 0x1d, 0x1d, + 0x31, 0xfb, 0xf7, 0xe4, 0xf9, 0xb8, 0x6a, 0x25, + 0x28, 0x01, 0xd0, 0x26, 0x28, 0x06, 0xd1, 0x00, + 0x23, 0x15, 0x22, 0x38, 0x1c, 0xf9, 0x1d, 0x21, + 0x31, 0xfb, 0xf7, 0xd8, 0xf9, 0xf8, 0x69, 0x38, + 0x28, 0x05, 0xd0, 0x3e, 0x28, 0x03, 0xd0, 0x3b, + 0x28, 0x01, 0xd0, 0x41, 0x28, 0xc4, 0xd1, 0x00, + 0x23, 0x15, 0x22, 0x38, 0x1c, 0xf9, 0x1d, 0x15, + 0x31, 0xfb, 0xf7, 0xc8, 0xf9, 0xbc, 0xe7, 0x00, + 0x00, 0xb8, 0xa8, 0x03, 0x20, 0x81, 0x0b, 0x89, + 0x07, 0x01, 0xd0, 0x05, 0x20, 0x70, 0x47, 0x80, + 0x0a, 0x80, 0x07, 0x01, 0xd0, 0x03, 0x20, 0x70, + 0x47, 0x01, 0x20, 0x70, 0x47, 0xf3, 0xb5, 0x82, + 0xb0, 0x07, 0x1c, 0x00, 0x20, 0x00, 0x90, 0xcf, + 0xf7, 0x9c, 0xf9, 0x00, 0x28, 0x50, 0xd0, 0x0b, + 0x23, 0x9b, 0x01, 0xfd, 0x18, 0x2a, 0x68, 0x02, + 0x2a, 0x01, 0xd1, 0x10, 0x21, 0x04, 0xe0, 0x01, + 0x2a, 0x01, 0xd1, 0x08, 0x21, 0x00, 0xe0, 0x18, + 0x21, 0xfb, 0x1d, 0xb9, 0x33, 0x9c, 0x6b, 0x00, + 0x2c, 0x33, 0xd0, 0xde, 0x6b, 0x01, 0x96, 0xf6, + 0x07, 0xf6, 0x0f, 0x05, 0x23, 0xdb, 0x01, 0xfc, + 0x18, 0x00, 0x2e, 0x13, 0xd0, 0xab, 0x68, 0x03, + 0x2b, 0x10, 0xd3, 0xe6, 0x6b, 0xb3, 0x0a, 0x9b, + 0x07, 0x0c, 0xd0, 0x02, 0x2a, 0x02, 0xd1, 0x93, + 0x02, 0x19, 0x43, 0x07, 0xe0, 0x01, 0x2a, 0x02, + 0xd1, 0x93, 0x02, 0x19, 0x43, 0x02, 0xe0, 0x03, + 0x23, 0x9b, 0x02, 0x19, 0x43, 0x01, 0x9e, 0xb3, + 0x08, 0x13, 0xd3, 0xab, 0x68, 0x05, 0x2b, 0x10, + 0xd3, 0xe4, 0x6b, 0xa3, 0x0b, 0x9b, 0x07, 0x0c, + 0xd0, 0x02, 0x2a, 0x02, 0xd1, 0x93, 0x03, 0x19, + 0x43, 0x07, 0xe0, 0x01, 0x2a, 0x02, 0xd1, 0x93, + 0x03, 0x19, 0x43, 0x02, 0xe0, 0x03, 0x23, 0x9b, + 0x03, 0x19, 0x43, 0xed, 0x09, 0x00, 0x1f, 0x03, + 0x5e, 0x22, 0x02, 0x60, 0x3a, 0x6b, 0x01, 0x61, + 0xc2, 0x60, 0x03, 0x99, 0x41, 0x61, 0x01, 0x1c, + 0x07, 0x20, 0xcf, 0xf7, 0xb8, 0xf9, 0x00, 0x98, + 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x0f, 0xb4, 0xf0, 0xb5, 0x85, 0xb0, 0x00, 0x20, + 0x03, 0x90, 0x15, 0x1c, 0xf6, 0xf7, 0xdb, 0xfd, + 0x07, 0x1c, 0x02, 0xd1, 0x07, 0x20, 0x03, 0x90, + 0x5f, 0xe0, 0xcf, 0xf7, 0x35, 0xf9, 0x04, 0x1c, + 0x02, 0xd1, 0x07, 0x20, 0x03, 0x90, 0x58, 0xe0, + 0x01, 0x20, 0x02, 0x90, 0x0b, 0x98, 0x39, 0x1d, + 0x40, 0x00, 0x28, 0x43, 0x04, 0x91, 0x08, 0x70, + 0x48, 0x1c, 0x01, 0x90, 0x0e, 0xa8, 0x00, 0x90, + 0x0d, 0x98, 0x00, 0x25, 0x00, 0x28, 0x16, 0xd9, + 0x00, 0x98, 0x04, 0x30, 0xc1, 0x1f, 0x39, 0x39, + 0xce, 0x6b, 0x04, 0x30, 0x00, 0x90, 0x40, 0x38, + 0xc1, 0x6b, 0x01, 0x98, 0x32, 0x1c, 0xce, 0xf7, + 0x7a, 0xfd, 0x01, 0x98, 0x01, 0x35, 0x80, 0x19, + 0x01, 0x90, 0x02, 0x98, 0x80, 0x19, 0x02, 0x90, + 0x0d, 0x98, 0x85, 0x42, 0xe8, 0xd3, 0x04, 0x99, + 0xf9, 0x61, 0x02, 0x98, 0xb8, 0x61, 0x0b, 0x98, + 0x79, 0x28, 0x06, 0xd0, 0x0b, 0x98, 0x17, 0x49, + 0x00, 0x01, 0x40, 0x18, 0xff, 0x30, 0x81, 0x30, + 0x00, 0x69, 0x59, 0x20, 0x20, 0x60, 0x0a, 0x98, + 0x00, 0x6b, 0xe0, 0x60, 0x01, 0x20, 0x60, 0x61, + 0x27, 0x61, 0x03, 0x20, 0xa0, 0x61, 0x27, 0x62, + 0x00, 0x20, 0xe0, 0x61, 0x0b, 0x98, 0x03, 0x28, + 0x04, 0xd1, 0xf9, 0x69, 0x49, 0x78, 0x09, 0x02, + 0x08, 0x43, 0x09, 0xe0, 0x0b, 0x99, 0x04, 0x29, + 0x06, 0xd1, 0xf9, 0x69, 0x4a, 0x78, 0x89, 0x78, + 0x12, 0x02, 0x10, 0x43, 0x09, 0x04, 0x08, 0x43, + 0xb8, 0x62, 0x07, 0x20, 0x21, 0x1c, 0xcf, 0xf7, + 0x46, 0xf9, 0x03, 0x98, 0x05, 0xb0, 0xed, 0x09, + 0x00, 0x20, 0x03, 0xf0, 0xbc, 0x08, 0xbc, 0x04, + 0xb0, 0x18, 0x47, 0xb8, 0xa8, 0x03, 0x20, 0x0f, + 0xb5, 0x82, 0xb0, 0x0b, 0x1c, 0x04, 0xaa, 0x01, + 0x92, 0x1a, 0x1c, 0x01, 0x21, 0x00, 0x91, 0x01, + 0x23, 0x03, 0x21, 0xff, 0xf7, 0x7f, 0xff, 0x06, + 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x8f, 0xb5, 0x84, + 0xb0, 0x03, 0x1c, 0x06, 0xa8, 0x0f, 0x1c, 0x07, + 0xaa, 0x03, 0x92, 0x01, 0x21, 0x01, 0x90, 0x18, + 0x1c, 0x02, 0x91, 0x01, 0x22, 0x00, 0x92, 0x04, + 0x21, 0x02, 0x23, 0x3a, 0x1c, 0xff, 0xf7, 0x6a, + 0xff, 0x08, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x09, 0x48, 0x00, 0x6b, 0x00, + 0x28, 0x0c, 0xd0, 0x00, 0x21, 0xc2, 0x1d, 0x2d, + 0x32, 0x93, 0x68, 0x00, 0x2b, 0x07, 0xd1, 0x01, + 0x31, 0x24, 0x32, 0x03, 0x29, 0xf8, 0xd3, 0x00, + 0x68, 0x00, 0x28, 0xf2, 0xd1, 0x00, 0x20, 0x70, + 0x47, 0x00, 0x00, 0xb8, 0xad, 0x03, 0x20, 0x80, + 0x30, 0x01, 0x6a, 0x03, 0x29, 0x01, 0xd2, 0x01, + 0x31, 0x01, 0x62, 0x70, 0x47, 0x80, 0x30, 0x01, + 0x6a, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x39, 0x01, + 0x62, 0x70, 0x47, 0x80, 0xb5, 0x83, 0xb0, 0x13, + 0x48, 0x07, 0x6b, 0x00, 0x2f, 0x1e, 0xd0, 0x78, + 0x69, 0x0e, 0x28, 0x03, 0xd0, 0x0f, 0x28, 0x01, + 0xd0, 0x10, 0x28, 0x14, 0xd1, 0x0b, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0x40, 0x68, 0x01, 0x28, 0x0e, + 0xd9, 0x01, 0x20, 0x02, 0x90, 0x38, 0x1c, 0xff, + 0xf7, 0x11, 0xfd, 0x01, 0x21, 0x02, 0xaa, 0x01, + 0x92, 0x00, 0x91, 0x2d, 0x21, 0x02, 0x1c, 0x01, + 0x23, 0x38, 0x1c, 0xff, 0xf7, 0x1f, 0xff, 0x3f, + 0x68, 0x00, 0x2f, 0xe0, 0xd1, 0x03, 0xb0, 0x80, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xb8, + 0xad, 0x03, 0x20, 0x80, 0xb5, 0x83, 0xb0, 0x13, + 0x48, 0xed, 0x09, 0x00, 0x21, 0x03, 0x07, 0x6b, + 0x00, 0x2f, 0x1f, 0xd0, 0x78, 0x69, 0x0e, 0x28, + 0x03, 0xd0, 0x0f, 0x28, 0x01, 0xd0, 0x10, 0x28, + 0x15, 0xd1, 0x01, 0x20, 0x0b, 0x23, 0x9b, 0x01, + 0x02, 0x90, 0xf8, 0x18, 0x40, 0x68, 0x02, 0x90, + 0x01, 0x28, 0x0c, 0xd9, 0x38, 0x1c, 0xff, 0xf7, + 0xe4, 0xfc, 0x01, 0x21, 0x02, 0xaa, 0x01, 0x92, + 0x00, 0x91, 0x2d, 0x21, 0x02, 0x1c, 0x01, 0x23, + 0x38, 0x1c, 0xff, 0xf7, 0xf2, 0xfe, 0x3f, 0x68, + 0x00, 0x2f, 0xdf, 0xd1, 0x03, 0xb0, 0x80, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xb8, 0xad, 0x03, 0x20, + 0x00, 0x29, 0x09, 0xd0, 0x01, 0x29, 0x0b, 0xd0, + 0x02, 0x29, 0x0d, 0xd0, 0x03, 0x29, 0x0f, 0xd1, + 0x10, 0x68, 0x00, 0x03, 0xc0, 0x0f, 0x70, 0x47, + 0x10, 0x68, 0x40, 0x04, 0xc0, 0x0f, 0x70, 0x47, + 0x10, 0x68, 0x00, 0x04, 0xc0, 0x0f, 0x70, 0x47, + 0x10, 0x68, 0xc0, 0x03, 0xc0, 0x0f, 0x70, 0x47, + 0x00, 0x20, 0x70, 0x47, 0xf7, 0xb5, 0x23, 0x48, + 0x00, 0x25, 0x00, 0x6b, 0x01, 0x27, 0x0c, 0x1c, + 0x00, 0x28, 0x17, 0xd0, 0x01, 0x69, 0x01, 0x29, + 0x11, 0xd1, 0x00, 0x22, 0xc1, 0x1d, 0x2d, 0x31, + 0xa1, 0x42, 0x08, 0xd0, 0x8b, 0x68, 0x00, 0x2b, + 0x05, 0xd0, 0x8e, 0x69, 0x01, 0x23, 0x00, 0x2e, + 0x00, 0xd0, 0x33, 0x1c, 0x5d, 0x19, 0x24, 0x31, + 0x01, 0x32, 0x03, 0x2a, 0xf0, 0xd3, 0x00, 0x68, + 0x00, 0x28, 0xe7, 0xd1, 0x02, 0x9a, 0x10, 0x0f, + 0x01, 0xd3, 0x02, 0x23, 0x1f, 0x43, 0x01, 0x23, + 0x02, 0x9a, 0xdb, 0x06, 0x9a, 0x43, 0x51, 0x08, + 0x60, 0x69, 0xce, 0xf7, 0x63, 0xfb, 0x00, 0x20, + 0x01, 0x22, 0x2b, 0x1c, 0x13, 0x40, 0x04, 0xd0, + 0x01, 0x30, 0x13, 0x1c, 0x83, 0x40, 0x2b, 0x40, + 0xfa, 0xd1, 0x82, 0x40, 0x50, 0x08, 0x40, 0x00, + 0xa0, 0x61, 0x40, 0x1a, 0xed, 0x09, 0x00, 0x22, + 0x03, 0x02, 0x9a, 0x40, 0x00, 0x80, 0x18, 0x00, + 0x01, 0x00, 0x09, 0xe0, 0x61, 0x03, 0xb0, 0x38, + 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0xb8, 0xad, 0x03, 0x20, 0xf0, 0xb4, 0x17, + 0x4b, 0x00, 0x27, 0x1c, 0x6b, 0x00, 0x22, 0x00, + 0x2c, 0x26, 0xd0, 0x00, 0x26, 0xe3, 0x1d, 0x2d, + 0x33, 0x98, 0x42, 0x1a, 0xd0, 0x9d, 0x68, 0x00, + 0x2d, 0x17, 0xd0, 0x1d, 0x69, 0x8d, 0x42, 0x02, + 0xd0, 0x1c, 0x20, 0xf0, 0xbc, 0x70, 0x47, 0x00, + 0x2d, 0x01, 0xd1, 0x0a, 0x20, 0xf9, 0xe7, 0x01, + 0x2d, 0x04, 0xd1, 0x01, 0x37, 0x01, 0x2f, 0x08, + 0xd3, 0x0a, 0x20, 0xf2, 0xe7, 0x02, 0x2d, 0x04, + 0xd1, 0x01, 0x32, 0x02, 0x2a, 0x01, 0xd3, 0x0a, + 0x20, 0xeb, 0xe7, 0x24, 0x33, 0x01, 0x36, 0x03, + 0x2e, 0xde, 0xd3, 0x24, 0x68, 0x00, 0x2c, 0xd8, + 0xd1, 0x00, 0x20, 0xe2, 0xe7, 0xb8, 0xad, 0x03, + 0x20, 0xf0, 0xb5, 0x0f, 0x1c, 0x00, 0x21, 0x80, + 0x23, 0x14, 0x1c, 0x1a, 0x40, 0xc5, 0x1d, 0xb9, + 0x35, 0x02, 0x26, 0x00, 0x2a, 0x0c, 0xd0, 0xe8, + 0x6b, 0x80, 0x0b, 0x09, 0xd3, 0x02, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0xbc, 0xff, 0x01, 0x1c, 0x03, + 0xd1, 0x06, 0x20, 0x78, 0x61, 0x3e, 0x61, 0x1e, + 0xe0, 0xe0, 0x09, 0x0d, 0xd3, 0xe8, 0x6b, 0x40, + 0x0b, 0x0a, 0xd3, 0x01, 0x21, 0x38, 0x1c, 0xff, + 0xf7, 0xad, 0xff, 0x01, 0x1c, 0x04, 0xd1, 0x01, + 0x20, 0x38, 0x61, 0x04, 0x20, 0x78, 0x61, 0x0e, + 0xe0, 0xa0, 0x09, 0x09, 0xd3, 0x00, 0x21, 0x38, + 0x1c, 0xff, 0xf7, 0xa0, 0xff, 0x01, 0x1c, 0x06, + 0xd1, 0x00, 0x20, 0x38, 0x61, 0x7e, 0x61, 0x02, + 0xe0, 0x00, 0x29, 0x00, 0xd1, 0x1a, 0x21, 0xf0, + 0xbc, 0x08, 0xbc, 0x08, 0x1c, 0x18, 0x47, 0xf0, + 0xb5, 0x00, 0x27, 0x04, 0x1c, 0x0d, 0x1c, 0xed, + 0x09, 0x00, 0x23, 0x03, 0xce, 0xf7, 0x56, 0xff, + 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x11, 0xe0, + 0xd5, 0x21, 0x01, 0x60, 0xe6, 0x1d, 0x9d, 0x36, + 0xc4, 0x60, 0x0c, 0xce, 0xc1, 0x1d, 0x09, 0x31, + 0x0c, 0xc1, 0xe1, 0x1d, 0x79, 0x31, 0xc9, 0x6a, + 0x81, 0x61, 0xc5, 0x61, 0x01, 0x1c, 0x05, 0x20, + 0xce, 0xf7, 0xaf, 0xff, 0x38, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x00, 0x24, + 0x05, 0x1c, 0x0f, 0x1c, 0xce, 0xf7, 0x36, 0xff, + 0x00, 0x28, 0x01, 0xd1, 0x07, 0x24, 0x1c, 0xe0, + 0x66, 0x21, 0x01, 0x60, 0x29, 0x6b, 0xc1, 0x60, + 0xf9, 0x68, 0x41, 0x61, 0x39, 0x69, 0x00, 0x29, + 0x17, 0xd0, 0x01, 0x29, 0x18, 0xd0, 0x02, 0x29, + 0x01, 0xd1, 0x07, 0x21, 0x81, 0x61, 0x79, 0x69, + 0x49, 0x00, 0xc1, 0x61, 0x39, 0x68, 0x01, 0x61, + 0xf9, 0x69, 0x01, 0x62, 0xe9, 0x6a, 0x49, 0x69, + 0x41, 0x62, 0x01, 0x1c, 0x07, 0x20, 0xce, 0xf7, + 0x84, 0xff, 0x20, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x05, 0x21, 0x81, 0x61, 0xea, 0xe7, + 0x06, 0x21, 0x81, 0x61, 0xe7, 0xe7, 0xb0, 0xb5, + 0x00, 0x27, 0x0c, 0x1c, 0x05, 0x1c, 0xce, 0xf7, + 0x05, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, + 0x09, 0xe0, 0x67, 0x21, 0x01, 0x60, 0x29, 0x6b, + 0xc1, 0x60, 0x21, 0x68, 0x01, 0x61, 0x01, 0x1c, + 0x07, 0x20, 0xce, 0xf7, 0x66, 0xff, 0x38, 0x1c, + 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb4, + 0x00, 0x27, 0xc2, 0x1d, 0x2d, 0x32, 0xfb, 0x00, + 0xdb, 0x19, 0x9b, 0x00, 0x1b, 0x18, 0xdb, 0x6b, + 0x8b, 0x42, 0x02, 0xd1, 0x10, 0x1c, 0x80, 0xbc, + 0x70, 0x47, 0x24, 0x32, 0x01, 0x37, 0x03, 0x2f, + 0xf1, 0xd3, 0x00, 0x20, 0xf7, 0xe7, 0x80, 0xb4, + 0x00, 0x29, 0x10, 0xd0, 0x00, 0x27, 0xc2, 0x1d, + 0x2d, 0x32, 0xed, 0x09, 0x00, 0x24, 0x03, 0xfb, + 0x00, 0xdb, 0x19, 0x9b, 0x00, 0x1b, 0x18, 0x9b, + 0x6b, 0x8b, 0x42, 0x02, 0xd1, 0x10, 0x1c, 0x80, + 0xbc, 0x70, 0x47, 0x24, 0x32, 0x01, 0x37, 0x03, + 0x2f, 0xf1, 0xd3, 0x00, 0x20, 0xf7, 0xe7, 0xf7, + 0xb5, 0xc5, 0x1d, 0xc6, 0x1d, 0x99, 0x36, 0x2d, + 0x35, 0x14, 0x1c, 0x07, 0x1c, 0xae, 0x42, 0x28, + 0xd9, 0xa8, 0x68, 0x4b, 0x28, 0x29, 0xd0, 0x0c, + 0xdc, 0x48, 0x28, 0x26, 0xd0, 0x04, 0xdc, 0x00, + 0x28, 0x19, 0xd0, 0x47, 0x28, 0x17, 0xd1, 0x20, + 0xe0, 0x49, 0x28, 0x1e, 0xd0, 0x4a, 0x28, 0x12, + 0xd1, 0x1b, 0xe0, 0x4c, 0x28, 0x19, 0xd0, 0x4d, + 0x28, 0x17, 0xd0, 0x4e, 0x28, 0x01, 0xd0, 0x4f, + 0x28, 0x09, 0xd1, 0x38, 0x1c, 0xff, 0xf7, 0x18, + 0xfe, 0x28, 0x68, 0x01, 0x99, 0x43, 0x1c, 0x38, + 0x1c, 0x22, 0x1c, 0xf9, 0xf7, 0x1a, 0xfd, 0x00, + 0x20, 0x68, 0x60, 0xa8, 0x60, 0x24, 0x35, 0xae, + 0x42, 0xd6, 0xd8, 0x03, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x04, + 0xfe, 0x28, 0x68, 0x42, 0x1c, 0x38, 0x1c, 0x21, + 0x1c, 0xf9, 0xf7, 0xdd, 0xfc, 0xeb, 0xe7, 0xf8, + 0xb5, 0x00, 0x26, 0x04, 0x1c, 0x15, 0x1c, 0x0f, + 0x1c, 0x00, 0x2a, 0x0d, 0xd1, 0x20, 0x69, 0x01, + 0x28, 0x02, 0xd1, 0x4b, 0x20, 0xb8, 0x60, 0x01, + 0xe0, 0x4c, 0x20, 0xb8, 0x60, 0x20, 0x1c, 0x39, + 0x1c, 0xba, 0x68, 0xf6, 0xf7, 0x40, 0xff, 0x17, + 0xe0, 0x20, 0x1c, 0xff, 0xf7, 0x1d, 0xfb, 0x0c, + 0xa2, 0x00, 0x92, 0x01, 0x1c, 0x20, 0x1c, 0x2b, + 0x22, 0x2b, 0x1c, 0xff, 0xf7, 0xa9, 0xfd, 0x06, + 0x1c, 0x00, 0x20, 0x78, 0x60, 0xb8, 0x60, 0x20, + 0x1c, 0xff, 0xf7, 0xd6, 0xfd, 0x38, 0x68, 0x42, + 0x1c, 0x20, 0x1c, 0x29, 0x1c, 0xf9, 0xf7, 0xaf, + 0xfc, 0x30, 0x1c, 0xf8, 0xbc, 0xed, 0x09, 0x00, + 0x25, 0x03, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x4c, 0x6d, 0x53, 0x63, 0x6f, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x00, 0x00, + 0xf0, 0xb5, 0x8d, 0xb0, 0x0d, 0x1c, 0xf6, 0xf7, + 0x03, 0xff, 0x07, 0x1c, 0x01, 0xd1, 0x02, 0x25, + 0x9c, 0xe0, 0x16, 0x21, 0x38, 0x1c, 0xfa, 0xf7, + 0xa6, 0xfe, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x25, + 0x83, 0xe0, 0x49, 0x21, 0x38, 0x1c, 0xff, 0xf7, + 0x43, 0xff, 0x00, 0x28, 0x05, 0xd1, 0x47, 0x21, + 0x38, 0x1c, 0xff, 0xf7, 0x3d, 0xff, 0x00, 0x28, + 0x01, 0xd0, 0x0c, 0x25, 0x75, 0xe0, 0xfb, 0xf7, + 0xa8, 0xff, 0x00, 0x28, 0x01, 0xd0, 0x0c, 0x25, + 0x6f, 0xe0, 0xfb, 0xf7, 0x13, 0xfc, 0x00, 0x28, + 0x01, 0xd0, 0x0c, 0x25, 0x69, 0xe0, 0xf8, 0x1d, + 0xb9, 0x30, 0x81, 0x6b, 0x00, 0x29, 0x02, 0xd0, + 0xc0, 0x6b, 0x00, 0x0b, 0x01, 0xd2, 0x1a, 0x25, + 0x5f, 0xe0, 0xfa, 0x1d, 0x3a, 0x4e, 0xf5, 0x32, + 0x38, 0x1c, 0xb1, 0x6b, 0xff, 0xf7, 0xe2, 0xfd, + 0x00, 0x28, 0x01, 0xd1, 0x1a, 0x25, 0x54, 0xe0, + 0xf8, 0x1d, 0x79, 0x30, 0x00, 0x6a, 0x01, 0x28, + 0x01, 0xd3, 0x0a, 0x25, 0x4d, 0xe0, 0x00, 0x21, + 0x38, 0x1c, 0xff, 0xf7, 0x0d, 0xff, 0x04, 0x1c, + 0x01, 0xd1, 0x0a, 0x25, 0x45, 0xe0, 0x38, 0x1c, + 0x21, 0x1c, 0x2a, 0x1c, 0xff, 0xf7, 0x60, 0xfe, + 0x05, 0x1c, 0x3e, 0xd1, 0xb0, 0x6b, 0xe0, 0x60, + 0x38, 0x69, 0x01, 0x28, 0x09, 0xd1, 0x20, 0x68, + 0x47, 0x22, 0x01, 0x30, 0x60, 0x60, 0x38, 0x1c, + 0x21, 0x1c, 0xa2, 0x60, 0xf6, 0xf7, 0xb2, 0xfe, + 0x2c, 0xe0, 0x00, 0x20, 0x0c, 0x90, 0x60, 0x60, + 0xa0, 0x61, 0x49, 0x20, 0xa0, 0x60, 0x38, 0x1c, + 0xff, 0xf7, 0x81, 0xfa, 0xe2, 0x1d, 0x05, 0x32, + 0xed, 0x09, 0x00, 0x26, 0x03, 0x03, 0x1c, 0x0b, + 0x92, 0x01, 0x21, 0x0a, 0x91, 0xe0, 0x1d, 0x09, + 0x30, 0x01, 0x22, 0x08, 0x92, 0x09, 0x90, 0xe1, + 0x1d, 0x0d, 0x31, 0xe2, 0x1d, 0x11, 0x32, 0x07, + 0x91, 0x01, 0x20, 0x06, 0x90, 0x01, 0x21, 0x05, + 0x92, 0x01, 0x22, 0x04, 0x91, 0x0c, 0xa8, 0x03, + 0x90, 0x21, 0x1d, 0x02, 0x92, 0x1a, 0x1c, 0x01, + 0x91, 0x01, 0x20, 0x00, 0x90, 0x2b, 0x21, 0x06, + 0x23, 0x38, 0x1c, 0xff, 0xf7, 0x76, 0xfc, 0x05, + 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x23, 0xfd, 0xce, + 0xf7, 0xb4, 0xfd, 0x00, 0x28, 0x0c, 0xd0, 0xd2, + 0x21, 0x01, 0x60, 0x85, 0x61, 0xf9, 0x6a, 0xc1, + 0x60, 0x00, 0x21, 0x01, 0x61, 0x01, 0x21, 0x41, + 0x61, 0x01, 0x1c, 0x05, 0x20, 0xce, 0xf7, 0x14, + 0xfe, 0x28, 0x1c, 0x0d, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x38, 0xae, 0x03, + 0x20, 0xb7, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x03, + 0x29, 0x01, 0xd9, 0x1f, 0x27, 0x25, 0xe0, 0xc8, + 0x00, 0x40, 0x18, 0x80, 0x00, 0x05, 0x19, 0xa8, + 0x69, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x27, 0x1c, + 0xe0, 0x20, 0x1c, 0xff, 0xf7, 0x2e, 0xfa, 0x03, + 0x1c, 0x06, 0xaa, 0x03, 0x92, 0x01, 0x22, 0x00, + 0x92, 0xe8, 0x1d, 0x01, 0x21, 0x02, 0x91, 0x0d, + 0x30, 0x1a, 0x1c, 0x02, 0x23, 0x01, 0x90, 0x2c, + 0x21, 0x20, 0x1c, 0xff, 0xf7, 0x36, 0xfc, 0x07, + 0x1c, 0x4f, 0x20, 0xa8, 0x61, 0x20, 0x1c, 0xe9, + 0x1d, 0x09, 0x31, 0xff, 0xf7, 0x67, 0xfe, 0xff, + 0xf7, 0x17, 0xfd, 0x38, 0x1c, 0x07, 0xb0, 0xb0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x04, + 0x1c, 0x0d, 0x1c, 0x17, 0x1c, 0xff, 0xf7, 0x09, + 0xfa, 0xb8, 0x42, 0x0a, 0xd1, 0x20, 0x69, 0x02, + 0x28, 0x01, 0xd1, 0x00, 0x2d, 0x23, 0xd0, 0x49, + 0x21, 0x20, 0x1c, 0xed, 0x09, 0x00, 0x27, 0x03, + 0xff, 0xf7, 0x67, 0xfe, 0x07, 0x1c, 0x04, 0xe0, + 0x4d, 0x21, 0x20, 0x1c, 0xff, 0xf7, 0x61, 0xfe, + 0x07, 0x1c, 0x00, 0x2f, 0x16, 0xd0, 0x00, 0x2d, + 0x08, 0xd1, 0x4e, 0x20, 0xb8, 0x60, 0xff, 0xf7, + 0xc6, 0xfc, 0x20, 0x1c, 0x39, 0x1c, 0xff, 0xf7, + 0x0b, 0xfe, 0x05, 0xe0, 0x00, 0x20, 0x78, 0x60, + 0xb8, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0xb4, 0xfc, + 0x38, 0x68, 0x42, 0x1c, 0x20, 0x1c, 0x29, 0x1c, + 0xf9, 0xf7, 0x8d, 0xfb, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xb0, 0xb5, 0x0d, 0x1c, 0x4f, 0x21, + 0x04, 0x1c, 0xff, 0xf7, 0x3e, 0xfe, 0x07, 0x1c, + 0x0c, 0xd0, 0x00, 0x20, 0x78, 0x60, 0xb8, 0x60, + 0x20, 0x1c, 0xff, 0xf7, 0x9d, 0xfc, 0x38, 0x68, + 0x00, 0x21, 0x43, 0x1c, 0x20, 0x1c, 0x2a, 0x1c, + 0xf9, 0xf7, 0x9f, 0xfb, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf7, 0xb5, 0x82, 0xb0, 0x04, 0x1c, + 0xc8, 0x69, 0x0e, 0x1c, 0x41, 0x78, 0x6c, 0x48, + 0x00, 0x25, 0x01, 0x91, 0x40, 0x68, 0x00, 0x27, + 0x00, 0x0b, 0x08, 0xd2, 0x6a, 0xa2, 0x00, 0x92, + 0x2b, 0x22, 0x1a, 0x23, 0x20, 0x1c, 0x04, 0x99, + 0xff, 0xf7, 0x4a, 0xfc, 0xc5, 0xe0, 0x82, 0x21, + 0x20, 0x1c, 0xfa, 0xf7, 0x6d, 0xfd, 0x00, 0x28, + 0x01, 0xd1, 0x0c, 0x25, 0xa4, 0xe0, 0x01, 0x99, + 0x20, 0x1c, 0xff, 0xf7, 0x1e, 0xfe, 0x07, 0x1c, + 0x05, 0xd0, 0xb8, 0x68, 0x00, 0x28, 0x02, 0xd0, + 0x1e, 0x25, 0x00, 0x27, 0x98, 0xe0, 0x20, 0x1c, + 0xff, 0xf7, 0x96, 0xf9, 0x04, 0x99, 0x88, 0x42, + 0x07, 0xd1, 0x49, 0x21, 0x20, 0x1c, 0xff, 0xf7, + 0xf8, 0xfd, 0x07, 0x1c, 0x01, 0xd1, 0x0a, 0x25, + 0x8a, 0xe0, 0x20, 0x1c, 0xff, 0xf7, 0x90, 0xf9, + 0x04, 0x99, 0x88, 0x42, 0x21, 0xd1, 0xfb, 0xf7, + 0x5d, 0xfe, 0x00, 0x28, 0x09, 0xd0, 0xed, 0x09, + 0x00, 0x28, 0x03, 0x4f, 0xa2, 0x00, 0x92, 0x2b, + 0x22, 0x32, 0x25, 0x20, 0x1c, 0x2b, 0x1c, 0x04, + 0x99, 0xff, 0xf7, 0x14, 0xfc, 0x13, 0xe0, 0xfb, + 0xf7, 0xc0, 0xfa, 0x00, 0x28, 0x09, 0xd0, 0x48, + 0xa2, 0x00, 0x92, 0x2b, 0x22, 0x0d, 0x25, 0x20, + 0x1c, 0x2b, 0x1c, 0x04, 0x99, 0xff, 0xf7, 0x06, + 0xfc, 0x05, 0xe0, 0xe0, 0x1d, 0x79, 0x30, 0x00, + 0x6a, 0x01, 0x28, 0x1b, 0xd3, 0x0a, 0x25, 0x00, + 0x2f, 0x5e, 0xd0, 0xf0, 0x69, 0x00, 0x79, 0x78, + 0x61, 0xf1, 0x69, 0x49, 0x79, 0x39, 0x61, 0xf2, + 0x69, 0x92, 0x79, 0xfa, 0x60, 0x22, 0x69, 0x02, + 0x2a, 0x05, 0xd1, 0xf2, 0x69, 0x92, 0x78, 0x3a, + 0x62, 0xf2, 0x69, 0xd2, 0x78, 0xba, 0x61, 0x01, + 0x9a, 0x02, 0x29, 0x7a, 0x60, 0x13, 0xd1, 0x06, + 0x28, 0x1c, 0xd0, 0x19, 0xe0, 0x00, 0x21, 0x20, + 0x1c, 0xff, 0xf7, 0xad, 0xfd, 0x07, 0x1c, 0x01, + 0xd1, 0x0a, 0x25, 0x3f, 0xe0, 0x20, 0x69, 0x01, + 0x28, 0xdb, 0xd1, 0x38, 0x68, 0x41, 0x1c, 0x01, + 0x91, 0x00, 0x20, 0xb8, 0x61, 0xd5, 0xe7, 0x01, + 0x29, 0x02, 0xd1, 0x04, 0x28, 0x06, 0xd0, 0x03, + 0xe0, 0x00, 0x29, 0x03, 0xd1, 0x02, 0x28, 0x01, + 0xd0, 0x1c, 0x25, 0x2b, 0xe0, 0xba, 0x69, 0x82, + 0x42, 0x01, 0xd2, 0x50, 0x08, 0x01, 0xd3, 0x1b, + 0x25, 0x24, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0xb5, + 0xfc, 0x05, 0x1c, 0x1f, 0xd1, 0x24, 0x4a, 0xf9, + 0x68, 0x20, 0x1c, 0xff, 0xf7, 0x4a, 0xfc, 0x00, + 0x28, 0x01, 0xd1, 0x1d, 0x25, 0x16, 0xe0, 0xb8, + 0x68, 0x49, 0x28, 0x06, 0xd1, 0x48, 0x22, 0x20, + 0x1c, 0x39, 0x1c, 0xba, 0x60, 0xf6, 0xf7, 0x35, + 0xfd, 0x25, 0xe0, 0x4a, 0x20, 0xb8, 0x60, 0x20, + 0x1c, 0xff, 0xf7, 0xd1, 0xfb, 0x38, 0x68, 0x41, + 0x1c, 0x20, 0x1c, 0xff, 0xf7, 0x03, 0xfd, 0x1a, + 0xe0, 0xed, 0x09, 0x00, 0x29, 0x03, 0x00, 0x2d, + 0x18, 0xd0, 0x0f, 0xa2, 0x00, 0x92, 0x2b, 0x22, + 0x20, 0x1c, 0x2b, 0x1c, 0x04, 0x99, 0xff, 0xf7, + 0x94, 0xfb, 0x00, 0x2f, 0x0e, 0xd0, 0xb8, 0x68, + 0x49, 0x28, 0x0b, 0xd1, 0x00, 0x20, 0x78, 0x60, + 0xb8, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0xbd, 0xfb, + 0x38, 0x68, 0x42, 0x1c, 0x20, 0x1c, 0x29, 0x1c, + 0xf9, 0xf7, 0x96, 0xfa, 0x05, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x78, 0xae, 0x03, 0x20, + 0x4c, 0x6d, 0x53, 0x63, 0x6f, 0x52, 0x63, 0x76, + 0x53, 0x43, 0x4f, 0x4c, 0x69, 0x6e, 0x6b, 0x52, + 0x65, 0x71, 0x00, 0x00, 0x7c, 0xae, 0x03, 0x20, + 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xc8, 0x69, + 0x15, 0x1c, 0x46, 0x78, 0x82, 0x78, 0x1c, 0x48, + 0x01, 0x92, 0x40, 0x68, 0x00, 0x0b, 0x08, 0xd2, + 0x1a, 0xa2, 0x00, 0x92, 0x2b, 0x22, 0x1a, 0x23, + 0x38, 0x1c, 0x29, 0x1c, 0xff, 0xf7, 0x5d, 0xfb, + 0x26, 0xe0, 0x83, 0x21, 0x38, 0x1c, 0xfa, 0xf7, + 0x80, 0xfc, 0x00, 0x28, 0x1a, 0xd0, 0x38, 0x1c, + 0x31, 0x1c, 0xff, 0xf7, 0x33, 0xfd, 0x04, 0x1c, + 0x14, 0xd0, 0xa0, 0x68, 0x00, 0x28, 0x11, 0xd0, + 0x38, 0x1c, 0xff, 0xf7, 0x7e, 0xfb, 0x38, 0x1c, + 0x21, 0x1c, 0xff, 0xf7, 0xfb, 0xfc, 0xff, 0xf7, + 0xab, 0xfb, 0x00, 0x20, 0x60, 0x60, 0xa0, 0x60, + 0x38, 0x1c, 0x00, 0x21, 0x33, 0x1c, 0x01, 0x9a, + 0xf9, 0xf7, 0x78, 0xfa, 0x38, 0x1c, 0x29, 0x1c, + 0x2c, 0x22, 0x04, 0xa3, 0xff, 0xf7, 0x26, 0xfb, + 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x78, 0xae, 0x03, 0x20, 0x4c, 0x6d, 0x53, 0x63, + 0x6f, 0x52, 0x63, 0x76, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x53, 0x43, 0x4f, 0x4c, 0x69, 0x6e, + 0x6b, 0x52, 0x65, 0x71, 0x00, 0x00, 0x00, 0x00, + 0x90, 0xb5, 0x8d, 0xb0, 0xed, 0x09, 0x00, 0x2a, + 0x03, 0x4a, 0x69, 0x4c, 0x6a, 0x21, 0x1c, 0x07, + 0x1c, 0xff, 0xf7, 0xc6, 0xfb, 0x0c, 0x90, 0x4d, + 0x20, 0xa0, 0x60, 0x38, 0x1c, 0xff, 0xf7, 0x7f, + 0xf8, 0xe2, 0x1d, 0x05, 0x32, 0x03, 0x1c, 0x0b, + 0x92, 0x01, 0x21, 0x0a, 0x91, 0xe0, 0x1d, 0x09, + 0x30, 0x01, 0x22, 0x08, 0x92, 0x09, 0x90, 0xe1, + 0x1d, 0x0d, 0x31, 0xe2, 0x1d, 0x11, 0x32, 0x07, + 0x91, 0x01, 0x20, 0x06, 0x90, 0x01, 0x21, 0x05, + 0x92, 0x01, 0x22, 0x04, 0x91, 0x0c, 0xa8, 0x03, + 0x90, 0x21, 0x1d, 0x02, 0x92, 0x1a, 0x1c, 0x01, + 0x91, 0x01, 0x20, 0x00, 0x90, 0x2b, 0x21, 0x06, + 0x23, 0x38, 0x1c, 0xff, 0xf7, 0x6c, 0xfa, 0x0d, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x98, + 0xb5, 0x4a, 0x69, 0x4c, 0x6a, 0x00, 0x92, 0x21, + 0x6a, 0xa2, 0x69, 0x63, 0x69, 0x07, 0x1c, 0xf6, + 0xf7, 0x8d, 0xfc, 0x40, 0x00, 0xe0, 0x61, 0xff, + 0xf7, 0x19, 0xfb, 0x38, 0x1c, 0xff, 0xf7, 0x47, + 0xf8, 0x01, 0x1c, 0x38, 0x1c, 0x2b, 0x22, 0x09, + 0x4b, 0xff, 0xf7, 0xc6, 0xfa, 0x4e, 0x20, 0xa0, + 0x60, 0x38, 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0x53, + 0xfc, 0x20, 0x68, 0x00, 0x21, 0x42, 0x1c, 0x38, + 0x1c, 0xf9, 0xf7, 0xdc, 0xf9, 0x98, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa4, 0x1e, 0x03, + 0x20, 0x90, 0xb5, 0x8d, 0xb0, 0x4a, 0x69, 0x4c, + 0x6a, 0x21, 0x1c, 0x07, 0x1c, 0xff, 0xf7, 0x68, + 0xfb, 0x0c, 0x90, 0x49, 0x20, 0xa0, 0x60, 0x38, + 0x1c, 0xff, 0xf7, 0x19, 0xf8, 0xe2, 0x1d, 0x05, + 0x32, 0x03, 0x1c, 0x0b, 0x92, 0x01, 0x21, 0x0a, + 0x91, 0xe0, 0x1d, 0x09, 0x30, 0x01, 0x22, 0x08, + 0x92, 0x09, 0x90, 0xe1, 0x1d, 0x0d, 0x31, 0xe2, + 0x1d, 0x11, 0x32, 0x07, 0x91, 0x01, 0x20, 0x06, + 0x90, 0x01, 0x21, 0x05, 0x92, 0x01, 0x22, 0xed, + 0x09, 0x00, 0x2b, 0x03, 0x04, 0x91, 0x0c, 0xa8, + 0x03, 0x90, 0x21, 0x1d, 0x02, 0x92, 0x1a, 0x1c, + 0x01, 0x91, 0x01, 0x20, 0x00, 0x90, 0x2b, 0x21, + 0x06, 0x23, 0x38, 0x1c, 0xff, 0xf7, 0x0e, 0xfa, + 0x0d, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x98, 0xb5, 0x4a, 0x69, 0x4c, 0x6a, 0x00, 0x92, + 0x21, 0x6a, 0xa2, 0x69, 0x63, 0x69, 0x07, 0x1c, + 0xf6, 0xf7, 0x2f, 0xfc, 0x40, 0x00, 0xe0, 0x61, + 0x4e, 0x20, 0xa0, 0x60, 0xff, 0xf7, 0xb9, 0xfa, + 0x38, 0x1c, 0xfe, 0xf7, 0xdf, 0xff, 0x01, 0x1c, + 0x38, 0x1c, 0x2b, 0x22, 0x08, 0x4b, 0xff, 0xf7, + 0x66, 0xfa, 0x38, 0x1c, 0x21, 0x1c, 0xff, 0xf7, + 0xf5, 0xfb, 0x20, 0x68, 0x00, 0x21, 0x42, 0x1c, + 0x38, 0x1c, 0xf9, 0xf7, 0x7e, 0xf9, 0x98, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xd8, 0x22, + 0x03, 0x20, 0xf7, 0xb5, 0x00, 0x24, 0x0d, 0x1c, + 0x06, 0x1c, 0xce, 0xf7, 0x1f, 0xfb, 0x07, 0x1c, + 0x01, 0xd1, 0x07, 0x24, 0x0b, 0xe0, 0xff, 0xf7, + 0x70, 0xfa, 0x00, 0x28, 0x0c, 0xd0, 0xdb, 0x20, + 0x38, 0x60, 0x0c, 0x24, 0x05, 0x20, 0x39, 0x1c, + 0xfc, 0x60, 0xce, 0xf7, 0x7e, 0xfb, 0x20, 0x1c, + 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x08, 0x48, 0x02, 0x9a, 0x42, 0x63, 0x50, 0x20, + 0x38, 0x60, 0xf8, 0x1d, 0x05, 0x30, 0x31, 0x1c, + 0xf6, 0xf7, 0xfd, 0xfa, 0x07, 0x20, 0x39, 0x1c, + 0x3d, 0x75, 0xce, 0xf7, 0x6a, 0xfb, 0xea, 0xe7, + 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, 0x80, 0xb5, + 0x00, 0x27, 0xce, 0xf7, 0xf3, 0xfa, 0x00, 0x28, + 0x01, 0xd1, 0x07, 0x27, 0x07, 0xe0, 0x51, 0x21, + 0x01, 0x60, 0x01, 0x21, 0xc1, 0x60, 0x01, 0x1c, + 0x07, 0x20, 0xce, 0xf7, 0x56, 0xfb, 0x38, 0x1c, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, + 0x00, 0x27, 0xed, 0x09, 0x00, 0x2c, 0x03, 0x0c, + 0x1c, 0x05, 0x1c, 0x09, 0x9e, 0xce, 0xf7, 0xdc, + 0xfa, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x0c, + 0xe0, 0x52, 0x21, 0x01, 0x60, 0x04, 0x61, 0xc5, + 0x60, 0x02, 0x9a, 0x01, 0x1c, 0x42, 0x61, 0x03, + 0x9b, 0x83, 0x61, 0xc6, 0x61, 0x07, 0x20, 0xce, + 0xf7, 0x3a, 0xfb, 0x38, 0x1c, 0x04, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 0x86, + 0xb0, 0x07, 0x1c, 0x08, 0x98, 0x0f, 0x9d, 0x01, + 0x02, 0x09, 0x0a, 0x04, 0xa8, 0x10, 0x9e, 0xf6, + 0xf7, 0xb8, 0xfa, 0x26, 0x48, 0x22, 0xa2, 0xc1, + 0x6b, 0x80, 0x6b, 0x03, 0x92, 0x05, 0x9a, 0x01, + 0x90, 0x00, 0x92, 0x02, 0x91, 0x09, 0x99, 0x08, + 0x98, 0x01, 0x22, 0x04, 0x9b, 0xf8, 0xf7, 0xf7, + 0xfb, 0x04, 0x1c, 0x2e, 0xd0, 0x07, 0x99, 0x00, + 0x22, 0xe1, 0x62, 0xe1, 0x1d, 0x14, 0x98, 0xb9, + 0x31, 0x48, 0x61, 0x01, 0x21, 0x20, 0x1c, 0xfa, + 0xf7, 0x2a, 0xfb, 0x05, 0x23, 0xdb, 0x01, 0xe0, + 0x18, 0x85, 0x63, 0x55, 0x20, 0x38, 0x60, 0xfc, + 0x60, 0x08, 0xa9, 0x0c, 0xc9, 0xf8, 0x1d, 0x09, + 0x30, 0x0c, 0xc0, 0x3e, 0x62, 0x11, 0x98, 0x78, + 0x62, 0xbd, 0x62, 0x12, 0x98, 0xf8, 0x85, 0x13, + 0x98, 0xb8, 0x85, 0xe1, 0x68, 0xf8, 0x1d, 0x1c, + 0x31, 0x60, 0xc9, 0x11, 0x30, 0x60, 0xc0, 0xe0, + 0x68, 0x40, 0x6a, 0x38, 0x63, 0xe0, 0x68, 0x80, + 0x6a, 0x78, 0x63, 0x07, 0x20, 0x39, 0x1c, 0xce, + 0xf7, 0xea, 0xfa, 0x20, 0x1c, 0x0a, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, + 0x63, 0x3a, 0x20, 0x33, 0x30, 0x35, 0x00, 0xd8, + 0xeb, 0x03, 0x20, 0xff, 0xb5, 0x86, 0xb0, 0x00, + 0x24, 0x15, 0x1c, 0x06, 0x1c, 0xce, 0xf7, 0x64, + 0xfa, 0x07, 0x1c, 0x01, 0xd1, 0xed, 0x09, 0x00, + 0x2d, 0x03, 0x07, 0x24, 0x2c, 0xe0, 0xff, 0xf7, + 0xb5, 0xf9, 0x00, 0x28, 0x01, 0xd0, 0x0c, 0x24, + 0x1b, 0xe0, 0x07, 0x98, 0x29, 0x1c, 0xf8, 0xf7, + 0xd9, 0xfc, 0x00, 0x28, 0x01, 0xd0, 0x0b, 0x24, + 0x13, 0xe0, 0x11, 0xaa, 0x07, 0xca, 0x03, 0x90, + 0x05, 0x92, 0x10, 0x9a, 0x09, 0x98, 0x04, 0x91, + 0x0f, 0x99, 0x00, 0x90, 0x01, 0x91, 0x31, 0x1c, + 0x38, 0x1c, 0x02, 0x92, 0x07, 0x9a, 0x2b, 0x1c, + 0xff, 0xf7, 0x7b, 0xff, 0x00, 0x28, 0x0b, 0xd1, + 0x07, 0x24, 0xd2, 0x20, 0x38, 0x60, 0xbc, 0x61, + 0xfe, 0x60, 0x00, 0x20, 0x38, 0x61, 0x78, 0x61, + 0x05, 0x20, 0x39, 0x1c, 0xce, 0xf7, 0xa2, 0xfa, + 0x20, 0x1c, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xff, 0xb5, 0x83, 0xb0, 0x00, 0x24, + 0x00, 0x26, 0x15, 0x1c, 0x00, 0x2a, 0x02, 0xd1, + 0x03, 0x21, 0x02, 0x91, 0x01, 0xe0, 0x04, 0x21, + 0x02, 0x91, 0xf6, 0xf7, 0xdd, 0xfa, 0x07, 0x1c, + 0x01, 0xd1, 0x02, 0x24, 0x10, 0xe0, 0x4a, 0x21, + 0x38, 0x1c, 0xff, 0xf7, 0x25, 0xfb, 0x06, 0x1c, + 0x0a, 0xd1, 0x02, 0x99, 0x38, 0x1c, 0xfa, 0xf7, + 0x7a, 0xfa, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x24, + 0x02, 0xe0, 0xf8, 0x1d, 0x79, 0x30, 0x05, 0x63, + 0xce, 0xf7, 0x09, 0xfa, 0x00, 0x28, 0x01, 0xd1, + 0x07, 0x24, 0x60, 0xe0, 0xd3, 0x21, 0x01, 0x60, + 0x04, 0x99, 0xc1, 0x60, 0x04, 0x61, 0x01, 0x1c, + 0x05, 0x20, 0xce, 0xf7, 0x6b, 0xfa, 0x00, 0x2c, + 0x55, 0xd1, 0x00, 0x2e, 0x05, 0xd0, 0x38, 0x1c, + 0x31, 0x1c, 0x2a, 0x1c, 0xff, 0xf7, 0x6a, 0xfb, + 0x4d, 0xe0, 0x04, 0x99, 0x00, 0x2d, 0xf9, 0x62, + 0x1c, 0xd0, 0x27, 0xa2, 0x00, 0x92, 0x33, 0x22, + 0x00, 0x21, 0x38, 0x1c, 0x2b, 0x1c, 0xff, 0xf7, + 0x26, 0xf9, 0xba, 0x68, 0x28, 0x49, 0x04, 0x1c, + 0xed, 0x09, 0x00, 0x2e, 0x03, 0x01, 0x92, 0x00, + 0x91, 0x27, 0xa1, 0x08, 0x68, 0x00, 0x23, 0x01, + 0x22, 0x49, 0x68, 0xf6, 0xf7, 0xda, 0xfb, 0xf9, + 0x1d, 0xf9, 0x31, 0x48, 0x60, 0x00, 0x22, 0x38, + 0x1c, 0x02, 0x99, 0xfa, 0xf7, 0x5d, 0xfa, 0x2c, + 0xe0, 0x06, 0x9b, 0x00, 0x2b, 0x17, 0xd1, 0x10, + 0x25, 0xf9, 0x1d, 0x1d, 0x31, 0x2a, 0x1c, 0x38, + 0x1c, 0x0e, 0x1c, 0xfa, 0xf7, 0xbb, 0xf9, 0x00, + 0x28, 0x01, 0xd1, 0x0c, 0x24, 0x1d, 0xe0, 0x00, + 0x22, 0x38, 0x1c, 0x29, 0x1c, 0xfa, 0xf7, 0x48, + 0xfa, 0x00, 0x23, 0x38, 0x1c, 0x31, 0x1c, 0x2a, + 0x1c, 0xfa, 0xf7, 0xcc, 0xf9, 0x11, 0xe0, 0x38, + 0x1c, 0x33, 0x22, 0x00, 0x21, 0x09, 0xa3, 0xff, + 0xf7, 0xe1, 0xf8, 0x04, 0x1c, 0x09, 0xd1, 0x00, + 0x20, 0xb8, 0x61, 0x38, 0x1c, 0xfa, 0xf7, 0x62, + 0xf9, 0x01, 0x1c, 0x00, 0x22, 0x38, 0x1c, 0xfa, + 0xf7, 0x2f, 0xfa, 0x20, 0x1c, 0x07, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x4c, 0x6d, 0x49, + 0x66, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x07, 0xb2, 0x02, + 0x20, 0x00, 0x24, 0xf4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xb5, 0x00, 0x24, 0x0d, 0x1c, 0x09, + 0x9e, 0xf6, 0xf7, 0x44, 0xfa, 0x07, 0x1c, 0x01, + 0xd1, 0x02, 0x24, 0x21, 0xe0, 0x05, 0x21, 0x38, + 0x1c, 0xfa, 0xf7, 0xe7, 0xf9, 0x00, 0x28, 0x01, + 0xd1, 0x0c, 0x24, 0x19, 0xe0, 0x01, 0x23, 0x9b, + 0x02, 0xf8, 0x18, 0xc0, 0x6b, 0x00, 0x28, 0x01, + 0xd0, 0x0c, 0x24, 0x11, 0xe0, 0x05, 0x23, 0xdb, + 0x01, 0xf8, 0x18, 0x80, 0x6a, 0x00, 0x28, 0x06, + 0xd0, 0x02, 0x9a, 0x38, 0x1c, 0x29, 0x1c, 0xaa, + 0x62, 0xfe, 0xf7, 0xd0, 0xfd, 0x2b, 0xe0, 0xce, + 0xf7, 0x64, 0xf9, 0xed, 0x09, 0x00, 0x2f, 0x03, + 0x00, 0x28, 0x06, 0xd1, 0x07, 0x24, 0xce, 0xf7, + 0x5f, 0xf9, 0x00, 0x28, 0x18, 0xd1, 0x07, 0x24, + 0x20, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, + 0x4a, 0x68, 0x01, 0x32, 0x4a, 0x60, 0x59, 0x21, + 0x01, 0x60, 0x39, 0x6b, 0xc1, 0x60, 0x05, 0x61, + 0x01, 0x21, 0x41, 0x61, 0x02, 0x9a, 0x01, 0x1c, + 0x82, 0x61, 0x03, 0x9b, 0xc3, 0x61, 0x06, 0x62, + 0x07, 0x20, 0xce, 0xf7, 0xb4, 0xf9, 0x09, 0xe0, + 0xd6, 0x21, 0x01, 0x60, 0xf9, 0x6a, 0x0c, 0x30, + 0x52, 0xc0, 0x18, 0x38, 0x01, 0x1c, 0x05, 0x20, + 0xce, 0xf7, 0xa9, 0xf9, 0x20, 0x1c, 0x04, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, + 0x1c, 0x1c, 0x0d, 0x1c, 0x16, 0x1c, 0xf6, 0xf7, + 0xec, 0xf9, 0x07, 0x1c, 0x01, 0xd1, 0x02, 0x25, + 0x1b, 0xe0, 0x00, 0x2d, 0x06, 0xd0, 0x38, 0x1c, + 0x29, 0x1c, 0x32, 0x1c, 0xff, 0xf7, 0x87, 0xfb, + 0x05, 0x1c, 0x12, 0xe0, 0x00, 0x2c, 0x08, 0xd0, + 0x78, 0x69, 0x0e, 0x28, 0x03, 0xd0, 0x0f, 0x28, + 0x01, 0xd0, 0x10, 0x28, 0x01, 0xd1, 0x0b, 0x25, + 0x07, 0xe0, 0x02, 0x21, 0x38, 0x1c, 0x32, 0x1c, + 0xfa, 0xf7, 0x9d, 0xf9, 0x05, 0x1c, 0x00, 0xd0, + 0x0c, 0x25, 0xce, 0xf7, 0x0d, 0xf9, 0x00, 0x28, + 0x01, 0xd1, 0x07, 0x25, 0x09, 0xe0, 0xd9, 0x21, + 0x01, 0x60, 0xf9, 0x6a, 0xc1, 0x60, 0x05, 0x61, + 0x44, 0x61, 0x01, 0x1c, 0x05, 0x20, 0xce, 0xf7, + 0x6e, 0xf9, 0x28, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x90, 0xb5, 0x00, 0x27, 0xf6, 0xf7, + 0xb4, 0xf9, 0x04, 0x1c, 0x01, 0xd1, 0x02, 0x27, + 0x11, 0xe0, 0xce, 0xf7, 0xf1, 0xf8, 0x00, 0x28, + 0x01, 0xd1, 0x07, 0x27, 0x0b, 0xe0, 0xc7, 0x21, + 0x01, 0x60, 0xe1, 0x6a, 0xc1, 0x60, 0xe1, 0x1d, + 0xb9, 0x31, 0x09, 0x68, 0x01, 0x61, 0xed, 0x09, + 0x00, 0x30, 0x03, 0x01, 0x1c, 0x05, 0x20, 0xce, + 0xf7, 0x50, 0xf9, 0x38, 0x1c, 0x90, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x00, 0x27, 0x0d, + 0x1c, 0xf6, 0xf7, 0x95, 0xf9, 0x04, 0x1c, 0x01, + 0xd1, 0x02, 0x27, 0x11, 0xe0, 0xce, 0xf7, 0xd2, + 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x27, 0x0b, + 0xe0, 0xe1, 0x1d, 0xb9, 0x31, 0x0d, 0x60, 0x5a, + 0x21, 0x01, 0x60, 0x21, 0x6b, 0xc1, 0x60, 0x05, + 0x61, 0x01, 0x1c, 0x07, 0x20, 0xce, 0xf7, 0x31, + 0xf9, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf7, 0xb5, 0x01, 0x99, 0x00, 0x27, 0x05, + 0x1c, 0x00, 0x29, 0x01, 0xd1, 0x06, 0x26, 0x00, + 0xe0, 0x07, 0x26, 0xce, 0xf7, 0xb3, 0xf8, 0x04, + 0x1c, 0x01, 0xd1, 0x07, 0x27, 0x3f, 0xe0, 0x28, + 0x1c, 0xf6, 0xf7, 0x69, 0xf9, 0x05, 0x1c, 0x01, + 0xd1, 0x02, 0x27, 0x0e, 0xe0, 0x28, 0x1c, 0x31, + 0x1c, 0xfa, 0xf7, 0x0c, 0xf9, 0x00, 0x28, 0x01, + 0xd1, 0x0c, 0x27, 0x06, 0xe0, 0x28, 0x1c, 0x31, + 0x1c, 0xfa, 0xf7, 0xcb, 0xf8, 0x00, 0x28, 0x00, + 0xd1, 0x0c, 0x27, 0xd0, 0x20, 0x20, 0x60, 0x01, + 0x99, 0x00, 0x29, 0x05, 0xd1, 0x0b, 0x21, 0x01, + 0x20, 0xf6, 0xf7, 0x1d, 0xf9, 0xe0, 0x60, 0x04, + 0xe0, 0x0c, 0x21, 0x01, 0x20, 0xf6, 0xf7, 0x17, + 0xf9, 0xe0, 0x60, 0xe9, 0x1d, 0x9d, 0x31, 0x27, + 0x61, 0x0c, 0xc9, 0xe0, 0x1d, 0x0d, 0x30, 0x0c, + 0xc0, 0x05, 0x20, 0x21, 0x1c, 0xce, 0xf7, 0xed, + 0xf8, 0x00, 0x2f, 0x0c, 0xd1, 0x00, 0x22, 0x28, + 0x1c, 0x31, 0x1c, 0xfa, 0xf7, 0x02, 0xf9, 0x07, + 0x1c, 0x05, 0xd1, 0x28, 0x1c, 0x31, 0x1c, 0x02, + 0x9a, 0xfa, 0xf7, 0xbf, 0xf8, 0x07, 0x1c, 0x38, + 0x1c, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xff, 0xb5, 0x00, 0x25, 0x07, 0x1c, 0xce, + 0xf7, 0xed, 0x09, 0x00, 0x31, 0x03, 0x65, 0xf8, + 0x04, 0x1c, 0x01, 0xd1, 0x07, 0x25, 0x49, 0xe0, + 0x38, 0x1c, 0xf6, 0xf7, 0x1b, 0xf9, 0x07, 0x1c, + 0x01, 0xd1, 0x02, 0x25, 0x27, 0xe0, 0x01, 0x99, + 0x00, 0x29, 0x01, 0xd1, 0x08, 0x26, 0x00, 0xe0, + 0x09, 0x26, 0x38, 0x1c, 0x31, 0x1c, 0xfa, 0xf7, + 0xb8, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x25, + 0x19, 0xe0, 0x38, 0x1c, 0x31, 0x1c, 0xfa, 0xf7, + 0x77, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x25, + 0x11, 0xe0, 0x01, 0x99, 0x00, 0x29, 0x04, 0xd1, + 0x03, 0x99, 0x02, 0x9a, 0x38, 0x1c, 0xfc, 0xf7, + 0x55, 0xfb, 0x38, 0x1c, 0x31, 0x1c, 0x01, 0x9a, + 0xfa, 0xf7, 0x86, 0xf8, 0x38, 0x1c, 0x31, 0x1c, + 0x01, 0x9a, 0xfa, 0xf7, 0xbd, 0xf8, 0xd0, 0x20, + 0x20, 0x60, 0x01, 0x99, 0x00, 0x29, 0x05, 0xd1, + 0x0d, 0x21, 0x01, 0x20, 0xf6, 0xf7, 0xb6, 0xf8, + 0xe0, 0x60, 0x04, 0xe0, 0x0e, 0x21, 0x01, 0x20, + 0xf6, 0xf7, 0xb0, 0xf8, 0xe0, 0x60, 0xf9, 0x1d, + 0x9d, 0x31, 0x25, 0x61, 0x88, 0xc9, 0xe0, 0x1d, + 0x0d, 0x30, 0x88, 0xc0, 0x05, 0x20, 0x21, 0x1c, + 0xce, 0xf7, 0x86, 0xf8, 0x28, 0x1c, 0x04, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x02, 0x49, + 0xc8, 0x63, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, + 0xf8, 0xad, 0x03, 0x20, 0xf0, 0xb5, 0x85, 0xb0, + 0x00, 0x24, 0x0d, 0x1c, 0x16, 0x1c, 0x07, 0x1c, + 0xce, 0xf7, 0x03, 0xf8, 0x03, 0x90, 0x00, 0x28, + 0x01, 0xd1, 0x07, 0x24, 0xc2, 0xe0, 0x00, 0x20, + 0x63, 0x4b, 0x02, 0x90, 0x00, 0x2e, 0x04, 0x93, + 0x62, 0xd0, 0x04, 0x9b, 0x00, 0x26, 0x1d, 0x68, + 0x5b, 0xe0, 0xcd, 0xf7, 0xf2, 0xff, 0x07, 0x1c, + 0x55, 0xd0, 0x5e, 0xa1, 0x08, 0x20, 0xf5, 0xf7, + 0x73, 0xfa, 0x01, 0x90, 0x00, 0x28, 0x04, 0xd1, + 0x38, 0x1c, 0xce, 0xf7, 0xed, 0x09, 0x00, 0x32, + 0x03, 0x21, 0xf8, 0x07, 0x24, 0x4d, 0xe0, 0x5c, + 0xa1, 0x10, 0x20, 0xf5, 0xf7, 0x67, 0xfa, 0x00, + 0x90, 0x00, 0x28, 0x08, 0xd1, 0x38, 0x1c, 0xce, + 0xf7, 0x15, 0xf8, 0x01, 0x98, 0x5a, 0xa1, 0xf5, + 0xf7, 0x63, 0xfa, 0x07, 0x24, 0x3d, 0xe0, 0xc8, + 0x20, 0x38, 0x60, 0x01, 0x98, 0x38, 0x61, 0x00, + 0x98, 0x78, 0x61, 0x1a, 0xe0, 0xe8, 0x6a, 0x00, + 0x28, 0x16, 0xd0, 0x28, 0x6c, 0x00, 0x28, 0x13, + 0xd1, 0x38, 0x69, 0xf1, 0x00, 0x40, 0x18, 0xe9, + 0x1d, 0x01, 0x31, 0x0c, 0xc9, 0x0c, 0xc0, 0x78, + 0x69, 0x31, 0x01, 0x40, 0x18, 0xe9, 0x1d, 0x29, + 0x31, 0x0c, 0xc9, 0x0c, 0xc0, 0x0c, 0xc9, 0x0c, + 0xc0, 0x02, 0x98, 0x01, 0x30, 0x02, 0x90, 0x01, + 0x36, 0x2d, 0x68, 0x00, 0x2d, 0x01, 0xd0, 0x0b, + 0x2e, 0xe0, 0xd3, 0x00, 0x2e, 0x06, 0xd0, 0x05, + 0x20, 0x39, 0x1c, 0xfe, 0x60, 0xce, 0xf7, 0x16, + 0xf8, 0x00, 0x26, 0x0a, 0xe0, 0x38, 0x1c, 0xcd, + 0xf7, 0xdd, 0xff, 0x01, 0x98, 0x42, 0xa1, 0xf5, + 0xf7, 0x2b, 0xfa, 0x00, 0x98, 0x44, 0xa1, 0xf5, + 0xf7, 0x27, 0xfa, 0x00, 0x2c, 0x01, 0xd1, 0x00, + 0x2d, 0xa1, 0xd1, 0x3d, 0xe0, 0xff, 0xe7, 0x38, + 0x1c, 0x29, 0x1c, 0xf8, 0xf7, 0x15, 0xfd, 0x06, + 0x1c, 0x35, 0xd0, 0xcd, 0xf7, 0x8c, 0xff, 0x07, + 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x30, 0xe0, 0x3e, + 0xa1, 0x08, 0x20, 0xf5, 0xf7, 0x0b, 0xfa, 0x05, + 0x1c, 0x04, 0xd1, 0x38, 0x1c, 0xcd, 0xf7, 0xba, + 0xff, 0x07, 0x24, 0x25, 0xe0, 0x3c, 0xa1, 0x10, + 0x20, 0xf5, 0xf7, 0x00, 0xfa, 0x00, 0x28, 0x08, + 0xd1, 0x38, 0x1c, 0xcd, 0xf7, 0xaf, 0xff, 0x28, + 0x1c, 0x3b, 0xa1, 0xf5, 0xf7, 0xfd, 0xf9, 0x07, + 0x24, 0x16, 0xe0, 0x78, 0x61, 0xc8, 0x21, 0x39, + 0x60, 0xf0, 0x1d, 0x01, 0x30, 0x3d, 0x61, 0xed, + 0x09, 0x00, 0x33, 0x03, 0x0c, 0xc8, 0x0c, 0xc5, + 0xf1, 0x1d, 0x29, 0x31, 0x6c, 0xc9, 0x78, 0x69, + 0x6c, 0xc0, 0x01, 0x20, 0xf8, 0x60, 0x05, 0x20, + 0x39, 0x1c, 0xcd, 0xf7, 0xca, 0xff, 0x01, 0x20, + 0x02, 0x90, 0x00, 0xe0, 0x1f, 0x24, 0x03, 0x99, + 0xc9, 0x20, 0x08, 0x60, 0x04, 0x9b, 0x14, 0x22, + 0x9f, 0x68, 0x11, 0x1c, 0x14, 0x2f, 0x2d, 0x48, + 0x00, 0xd9, 0x39, 0x1c, 0x81, 0x42, 0x03, 0xd8, + 0x10, 0x1c, 0x14, 0x2f, 0x00, 0xd9, 0x38, 0x1c, + 0x03, 0x99, 0x08, 0x61, 0x02, 0x98, 0x03, 0x99, + 0x48, 0x61, 0x03, 0x98, 0xc4, 0x60, 0x03, 0x99, + 0x05, 0x20, 0xcd, 0xf7, 0xaa, 0xff, 0x20, 0x1c, + 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x37, 0x39, 0x34, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x37, 0x39, 0x39, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x38, 0x30, 0x33, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x38, 0x32, 0x38, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x38, 0x32, 0x39, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x38, 0x34, 0x32, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x38, 0x34, 0x37, 0x00, 0x73, 0x72, + 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, 0x63, + 0x3a, 0x20, 0x38, 0x35, 0x31, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xf7, 0xb5, 0x8b, 0xb0, 0x00, 0x20, + 0x14, 0x1c, 0x0f, 0x1c, 0x09, 0x90, 0x07, 0x91, + 0x06, 0x92, 0xed, 0x09, 0x00, 0x34, 0x03, 0xcd, + 0xf7, 0xe7, 0xfe, 0x08, 0x90, 0x00, 0x28, 0x02, + 0xd1, 0x07, 0x20, 0x09, 0x90, 0x4b, 0xe0, 0x0b, + 0x98, 0x00, 0x25, 0x00, 0x28, 0x33, 0xd9, 0x26, + 0x48, 0x0a, 0x90, 0x03, 0xcf, 0x08, 0x3f, 0xf8, + 0xf7, 0x5c, 0xfc, 0x00, 0x28, 0x1a, 0xd1, 0x38, + 0x68, 0x01, 0x02, 0x09, 0x0a, 0x04, 0xa8, 0xf5, + 0xf7, 0xcc, 0xfe, 0x0a, 0x98, 0x00, 0x21, 0xc0, + 0x6b, 0x02, 0x91, 0x01, 0x90, 0x0a, 0x98, 0x1d, + 0xa2, 0x03, 0x92, 0x82, 0x6b, 0x00, 0x92, 0x03, + 0xcf, 0x08, 0x3f, 0x04, 0x9a, 0x05, 0x9b, 0xf8, + 0xf7, 0x64, 0xfc, 0x00, 0x28, 0x02, 0xd1, 0x07, + 0x20, 0x09, 0x90, 0x10, 0xe0, 0x21, 0x1c, 0x0c, + 0xc9, 0xc6, 0x1d, 0x29, 0x36, 0x0c, 0xc6, 0x0c, + 0xc9, 0x0c, 0xc6, 0x01, 0x21, 0xc1, 0x62, 0x00, + 0x21, 0x01, 0x64, 0x0b, 0x98, 0x10, 0x34, 0x01, + 0x35, 0x08, 0x37, 0x85, 0x42, 0xcd, 0xd3, 0x07, + 0x98, 0x11, 0xa1, 0xf5, 0xf7, 0x32, 0xf9, 0x06, + 0x98, 0x13, 0xa1, 0xf5, 0xf7, 0x2e, 0xf9, 0x08, + 0x99, 0xca, 0x20, 0x08, 0x60, 0x08, 0x98, 0x05, + 0x61, 0x09, 0x98, 0x08, 0x99, 0xc8, 0x60, 0x08, + 0x99, 0x05, 0x20, 0xcd, 0xf7, 0x04, 0xff, 0x09, + 0x98, 0x0e, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0xd8, 0xeb, 0x03, 0x20, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, + 0x63, 0x3a, 0x20, 0x39, 0x30, 0x31, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, + 0x63, 0x3a, 0x20, 0x39, 0x31, 0x31, 0x00, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x69, 0x66, 0x2e, + 0x63, 0x3a, 0x20, 0x39, 0x31, 0x32, 0x00, 0xf7, + 0xb5, 0x00, 0x25, 0x00, 0x27, 0x0e, 0x1c, 0xcd, + 0xf7, 0x6f, 0xfe, 0x04, 0x1c, 0x01, 0xd1, 0x07, + 0x25, 0x20, 0xe0, 0x02, 0x9a, 0xed, 0x09, 0x00, + 0x35, 0x03, 0x00, 0x2a, 0x0a, 0xd0, 0x11, 0x48, + 0x00, 0x68, 0x00, 0x28, 0x11, 0xd0, 0x06, 0x68, + 0xf6, 0xf7, 0x84, 0xfe, 0xc7, 0x19, 0x30, 0x1c, + 0xf9, 0xd1, 0x0a, 0xe0, 0x00, 0x98, 0x31, 0x1c, + 0xf8, 0xf7, 0xde, 0xfb, 0x00, 0x28, 0x03, 0xd0, + 0xf6, 0xf7, 0x78, 0xfe, 0x07, 0x1c, 0x00, 0xe0, + 0x1f, 0x25, 0xcb, 0x20, 0x20, 0x60, 0xe5, 0x60, + 0x05, 0x20, 0x21, 0x1c, 0x27, 0x61, 0xcd, 0xf7, + 0xb9, 0xfe, 0x28, 0x1c, 0x03, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0xf8, 0xad, 0x03, 0x20, + 0xf0, 0xb5, 0x00, 0x27, 0x04, 0x1c, 0xcd, 0xf7, + 0x3e, 0xfe, 0x05, 0x1c, 0x01, 0xd1, 0x07, 0x27, + 0x50, 0xe0, 0x20, 0x1c, 0xf5, 0xf7, 0xf4, 0xfe, + 0x04, 0x1c, 0x01, 0xd1, 0x02, 0x27, 0x22, 0xe0, + 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0xc0, 0x6a, + 0x00, 0x28, 0x05, 0xd0, 0xe0, 0x1d, 0xff, 0x30, + 0x7a, 0x30, 0x41, 0x6b, 0x00, 0x29, 0x01, 0xd0, + 0x18, 0x27, 0x14, 0xe0, 0xc0, 0x69, 0x00, 0x28, + 0x01, 0xd1, 0x11, 0x26, 0x00, 0xe0, 0x19, 0x26, + 0x20, 0x1c, 0x31, 0x1c, 0xf9, 0xf7, 0x83, 0xfe, + 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x27, 0x06, 0xe0, + 0x20, 0x1c, 0x31, 0x1c, 0xf9, 0xf7, 0x42, 0xfe, + 0x00, 0x28, 0x00, 0xd1, 0x0c, 0x27, 0xcf, 0x20, + 0x28, 0x60, 0x15, 0x21, 0x01, 0x20, 0xf5, 0xf7, + 0x97, 0xfe, 0xe8, 0x60, 0x05, 0x20, 0x29, 0x1c, + 0x2f, 0x61, 0xcd, 0xf7, 0x73, 0xfe, 0x00, 0x2f, + 0x18, 0xd1, 0xe1, 0x1d, 0xff, 0x31, 0xba, 0x31, + 0x01, 0x20, 0x88, 0x60, 0xe0, 0x1d, 0xff, 0x30, + 0x7a, 0x30, 0xc0, 0x69, 0x00, 0x28, 0x04, 0xd1, + 0x20, 0x1c, 0xfc, 0xf7, 0x54, 0xf9, 0x07, 0x1c, + 0x08, 0xe0, 0x00, 0x22, 0x11, 0x21, 0x20, 0x1c, + 0xf9, 0xf7, 0x78, 0xfe, 0x20, 0x1c, 0xfc, 0xf7, + 0xed, 0x09, 0x00, 0x36, 0x03, 0x13, 0xf9, 0x07, + 0x1c, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf0, 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0xcd, + 0xf7, 0xe0, 0xfd, 0x05, 0x1c, 0x01, 0xd1, 0x07, + 0x27, 0x42, 0xe0, 0x38, 0x1c, 0xf5, 0xf7, 0x96, + 0xfe, 0x04, 0x1c, 0x01, 0xd1, 0x02, 0x27, 0x2f, + 0xe0, 0x0a, 0x21, 0x20, 0x1c, 0xf9, 0xf7, 0x39, + 0xfe, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x27, 0x27, + 0xe0, 0xe6, 0x1d, 0xff, 0x36, 0xba, 0x36, 0xf0, + 0x69, 0x00, 0x28, 0x01, 0xd0, 0x0c, 0x27, 0x1f, + 0xe0, 0x20, 0x1c, 0xfe, 0xf7, 0x66, 0xfa, 0x17, + 0x4a, 0x07, 0x1c, 0x90, 0x1e, 0x02, 0x21, 0x04, + 0x91, 0x81, 0x1e, 0x03, 0x90, 0x01, 0x20, 0x05, + 0x92, 0x02, 0x22, 0x00, 0x90, 0x01, 0x91, 0x25, + 0x21, 0x20, 0x1c, 0x02, 0x92, 0x03, 0x23, 0x3a, + 0x1c, 0xfe, 0xf7, 0x6b, 0xfc, 0x07, 0x1c, 0xe1, + 0x1d, 0xff, 0x31, 0x01, 0x20, 0xf0, 0x61, 0x0a, + 0x31, 0x20, 0x1c, 0x0b, 0x4a, 0xf8, 0xf7, 0x84, + 0xfa, 0xcf, 0x20, 0x28, 0x60, 0x1d, 0x21, 0x01, + 0x20, 0xf5, 0xf7, 0x2c, 0xfe, 0xe8, 0x60, 0x05, + 0x20, 0x29, 0x1c, 0x2f, 0x61, 0xcd, 0xf7, 0x08, + 0xfe, 0x38, 0x1c, 0x06, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0xae, 0x03, + 0x20, 0x73, 0xb2, 0x02, 0x20, 0xf0, 0xb5, 0x82, + 0xb0, 0x00, 0x24, 0x07, 0x1c, 0xcd, 0xf7, 0x89, + 0xfd, 0x05, 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x41, + 0xe0, 0x38, 0x1c, 0xf5, 0xf7, 0x3f, 0xfe, 0x07, + 0x1c, 0x01, 0xd1, 0x02, 0x24, 0x2e, 0xe0, 0x0b, + 0x21, 0x38, 0x1c, 0xf9, 0xf7, 0xe2, 0xfd, 0x00, + 0x28, 0x01, 0xd1, 0x0c, 0x24, 0x26, 0xe0, 0xfe, + 0x1d, 0xff, 0x36, 0xba, 0x36, 0xf0, 0x6a, 0x00, + 0x28, 0x01, 0xd0, 0x0c, 0x24, 0x1e, 0xe0, 0xf8, + 0x1d, 0xb9, 0x30, 0xed, 0x09, 0x00, 0x37, 0x03, + 0x41, 0x6b, 0x00, 0x29, 0x02, 0xd0, 0x00, 0x21, + 0x41, 0x63, 0x0d, 0xe0, 0x38, 0x1c, 0xfe, 0xf7, + 0x07, 0xfa, 0x12, 0x4a, 0x08, 0x21, 0x00, 0x91, + 0x01, 0x92, 0x02, 0x1c, 0x27, 0x21, 0x01, 0x23, + 0x38, 0x1c, 0xfe, 0xf7, 0x15, 0xfc, 0x04, 0x1c, + 0xf9, 0x1d, 0xff, 0x31, 0x01, 0x20, 0xf0, 0x62, + 0x1a, 0x31, 0x38, 0x1c, 0x0b, 0x4a, 0xf8, 0xf7, + 0x2e, 0xfa, 0xcf, 0x20, 0x28, 0x60, 0x1b, 0x21, + 0x01, 0x20, 0xf5, 0xf7, 0xd6, 0xfd, 0xe8, 0x60, + 0x05, 0x20, 0x29, 0x1c, 0x2c, 0x61, 0xcd, 0xf7, + 0xb2, 0xfd, 0x20, 0x1c, 0x02, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x7c, 0xae, + 0x03, 0x20, 0x45, 0xb3, 0x02, 0x20, 0xff, 0xb5, + 0x86, 0xb0, 0x00, 0x24, 0x0e, 0x1c, 0xcd, 0xf7, + 0x33, 0xfd, 0x05, 0x1c, 0x01, 0xd1, 0x07, 0x24, + 0x69, 0xe0, 0x06, 0x98, 0x31, 0x1c, 0xf7, 0xf7, + 0xd6, 0xff, 0x07, 0x1c, 0x23, 0xd1, 0xfe, 0xf7, + 0x7e, 0xfc, 0x00, 0x28, 0x01, 0xd0, 0x0c, 0x24, + 0x51, 0xe0, 0x00, 0x22, 0x10, 0x99, 0x05, 0x92, + 0x04, 0x91, 0x09, 0x9a, 0x0f, 0x98, 0x08, 0x99, + 0x03, 0x90, 0x08, 0x20, 0x00, 0x90, 0x01, 0x91, + 0x00, 0x21, 0x28, 0x1c, 0x02, 0x92, 0x06, 0x9a, + 0x33, 0x1c, 0xff, 0xf7, 0x4b, 0xfa, 0x00, 0x28, + 0x01, 0xd1, 0x07, 0x24, 0x3b, 0xe0, 0xc2, 0x1d, + 0xff, 0x32, 0xba, 0x32, 0x01, 0x21, 0x11, 0x62, + 0xc0, 0x30, 0xc1, 0x61, 0x3f, 0xe0, 0x0c, 0x21, + 0x38, 0x1c, 0xf9, 0xf7, 0x69, 0xfd, 0x00, 0x28, + 0x01, 0xd1, 0x0c, 0x24, 0x2b, 0xe0, 0xfe, 0x1d, + 0xff, 0x36, 0xba, 0x36, 0x30, 0x6a, 0x00, 0x28, + 0x01, 0xd0, 0x0c, 0x24, 0x23, 0xe0, 0x00, 0x20, + 0x0b, 0x23, 0x9b, 0x01, 0xf9, 0x18, 0x5d, 0x23, + 0xdb, 0x00, 0x48, 0x62, 0xf8, 0x18, 0xed, 0x09, + 0x00, 0x38, 0x03, 0xf9, 0x22, 0x00, 0x21, 0xcd, + 0xf7, 0xc8, 0xf8, 0x38, 0x1c, 0xfe, 0xf7, 0x8a, + 0xf9, 0xb9, 0x23, 0x9b, 0x00, 0xfa, 0x18, 0x01, + 0x92, 0x01, 0x21, 0x02, 0x1c, 0x01, 0x23, 0x38, + 0x1c, 0x00, 0x91, 0xfe, 0xf7, 0x97, 0xfb, 0x04, + 0x1c, 0xf9, 0x1d, 0xff, 0x31, 0x01, 0x20, 0x30, + 0x62, 0x0e, 0x31, 0x38, 0x1c, 0x0a, 0x4a, 0xf8, + 0xf7, 0xb0, 0xf9, 0xcf, 0x20, 0x28, 0x60, 0x19, + 0x21, 0x01, 0x20, 0xf5, 0xf7, 0x58, 0xfd, 0xe8, + 0x60, 0x05, 0x20, 0x29, 0x1c, 0x2c, 0x61, 0xcd, + 0xf7, 0x34, 0xfd, 0x20, 0x1c, 0x0a, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x9b, + 0xb2, 0x02, 0x20, 0xff, 0xb5, 0x86, 0xb0, 0x0f, + 0x9e, 0x07, 0x1c, 0xcd, 0xf7, 0xb7, 0xfc, 0x05, + 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x71, 0xe0, 0x38, + 0x1c, 0xf5, 0xf7, 0x6d, 0xfd, 0x07, 0x1c, 0x01, + 0xd1, 0x02, 0x24, 0x5e, 0xe0, 0x0d, 0x21, 0x38, + 0x1c, 0xf9, 0xf7, 0x10, 0xfd, 0x00, 0x28, 0x01, + 0xd1, 0x0c, 0x24, 0x56, 0xe0, 0xf8, 0x1d, 0xff, + 0x30, 0xba, 0x30, 0x05, 0x90, 0x80, 0x6a, 0x00, + 0x28, 0x01, 0xd0, 0x0c, 0x24, 0x4d, 0xe0, 0x01, + 0x20, 0x04, 0x90, 0x08, 0x9a, 0x40, 0x42, 0x04, + 0x24, 0x82, 0x42, 0x04, 0xd1, 0x0b, 0x23, 0x9b, + 0x01, 0xf8, 0x18, 0x04, 0x62, 0x13, 0xe0, 0x86, + 0x42, 0x0c, 0xd0, 0x31, 0x1c, 0x28, 0x48, 0xcd, + 0xf7, 0x06, 0xf8, 0x0b, 0x23, 0x9b, 0x01, 0xf9, + 0x18, 0x40, 0x00, 0x08, 0x62, 0x04, 0x28, 0x06, + 0xd2, 0x0c, 0x62, 0x04, 0xe0, 0x28, 0x20, 0x0b, + 0x23, 0x9b, 0x01, 0xf9, 0x18, 0x08, 0x62, 0x38, + 0x1c, 0xfe, 0xf7, 0x1c, 0xf9, 0x01, 0x21, 0x17, + 0x23, 0x5b, 0x01, 0x04, 0x1c, 0xf8, 0x18, 0x04, + 0xaa, 0x03, 0x92, 0x02, 0x22, 0x01, 0x90, 0x02, + 0x91, 0xed, 0x09, 0x00, 0x39, 0x03, 0x2a, 0x21, + 0x38, 0x1c, 0x00, 0x92, 0x02, 0x23, 0x22, 0x1c, + 0xfe, 0xf7, 0x23, 0xfb, 0x05, 0x23, 0xdb, 0x01, + 0x04, 0x1c, 0xf8, 0x18, 0x07, 0x99, 0x0b, 0x23, + 0xc1, 0x60, 0x08, 0x9a, 0x9b, 0x01, 0xf8, 0x18, + 0xc2, 0x60, 0x09, 0x9b, 0x10, 0x4a, 0x03, 0x61, + 0x46, 0x61, 0x10, 0x99, 0x81, 0x61, 0x05, 0x99, + 0x01, 0x20, 0x88, 0x62, 0xf9, 0x1d, 0xff, 0x31, + 0x16, 0x31, 0x38, 0x1c, 0xf8, 0xf7, 0x2c, 0xf9, + 0xcf, 0x20, 0x28, 0x60, 0x07, 0x21, 0x02, 0x20, + 0xf5, 0xf7, 0xd4, 0xfc, 0xe8, 0x60, 0x05, 0x20, + 0x29, 0x1c, 0x2c, 0x61, 0xcd, 0xf7, 0xb0, 0xfc, + 0x20, 0x1c, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0xe2, 0x04, 0x00, 0x00, + 0xfd, 0xb2, 0x02, 0x20, 0x90, 0xb5, 0x00, 0x27, + 0x0c, 0x1c, 0xf5, 0xf7, 0xef, 0xfc, 0x00, 0x28, + 0x01, 0xd1, 0x02, 0x27, 0x01, 0xe0, 0xc0, 0x30, + 0x84, 0x61, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, 0x00, 0x24, + 0x00, 0x26, 0x07, 0x1c, 0xcd, 0xf7, 0x21, 0xfc, + 0x05, 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x62, 0xe0, + 0x38, 0x1c, 0xf5, 0xf7, 0xd7, 0xfc, 0x07, 0x1c, + 0x01, 0xd1, 0x02, 0x24, 0x49, 0xe0, 0x10, 0x21, + 0x38, 0x1c, 0xf9, 0xf7, 0x7a, 0xfc, 0x00, 0x28, + 0x01, 0xd1, 0x0c, 0x24, 0x41, 0xe0, 0xf9, 0x1d, + 0x1d, 0x31, 0x10, 0x22, 0x38, 0x1c, 0x00, 0x91, + 0xf9, 0xf7, 0xfc, 0xfb, 0x00, 0x28, 0x01, 0xd1, + 0x0c, 0x24, 0x36, 0xe0, 0x38, 0x69, 0x01, 0x28, + 0x03, 0xd1, 0x02, 0x99, 0x00, 0x29, 0x07, 0xd1, + 0x04, 0xe0, 0x02, 0x28, 0x04, 0xd1, 0x02, 0x99, + 0x01, 0x29, 0x01, 0xd1, 0x01, 0x26, 0x28, 0xe0, + 0xf8, 0x1d, 0xb9, 0x30, 0x81, 0x6b, 0x00, 0x29, + 0x04, 0xd0, 0xc1, 0x6b, 0xed, 0x09, 0x00, 0x3a, + 0x03, 0x89, 0x09, 0x01, 0xd2, 0x1a, 0x24, 0x1e, + 0xe0, 0x40, 0x68, 0x00, 0x28, 0x03, 0xd1, 0xb8, + 0x6a, 0x25, 0x38, 0x08, 0x28, 0x01, 0xd8, 0x0c, + 0x24, 0x15, 0xe0, 0xfe, 0xf7, 0x37, 0xfb, 0x00, + 0x28, 0x01, 0xd0, 0x0c, 0x24, 0x0f, 0xe0, 0xf9, + 0x1d, 0xff, 0x31, 0xba, 0x31, 0x01, 0x20, 0x08, + 0x61, 0x10, 0x21, 0x00, 0x22, 0x38, 0x1c, 0xf9, + 0xf7, 0x5d, 0xfc, 0x00, 0x23, 0x10, 0x22, 0x38, + 0x1c, 0x00, 0x99, 0xf9, 0xf7, 0xe1, 0xfb, 0xcf, + 0x20, 0x28, 0x60, 0x0b, 0x21, 0x02, 0x20, 0xf5, + 0xf7, 0x53, 0xfc, 0xe8, 0x60, 0x05, 0x20, 0x29, + 0x1c, 0x2c, 0x61, 0xcd, 0xf7, 0x2f, 0xfc, 0x00, + 0x2e, 0x03, 0xd0, 0x00, 0x21, 0x38, 0x1c, 0xfa, + 0xf7, 0xe2, 0xf9, 0x20, 0x1c, 0x03, 0xb0, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x00, + 0x24, 0x07, 0x1c, 0xcd, 0xf7, 0xb0, 0xfb, 0x05, + 0x1c, 0x01, 0xd1, 0x07, 0x24, 0x40, 0xe0, 0x38, + 0x1c, 0xf5, 0xf7, 0x66, 0xfc, 0x07, 0x1c, 0x01, + 0xd1, 0x02, 0x24, 0x2d, 0xe0, 0x0e, 0x21, 0x38, + 0x1c, 0xf9, 0xf7, 0x09, 0xfc, 0x00, 0x28, 0x01, + 0xd1, 0x0c, 0x24, 0x25, 0xe0, 0xfe, 0x1d, 0xff, + 0x36, 0xba, 0x36, 0xb0, 0x69, 0x00, 0x28, 0x01, + 0xd0, 0x0c, 0x24, 0x1d, 0xe0, 0x38, 0x69, 0x02, + 0x28, 0x07, 0xd1, 0x01, 0x20, 0xb0, 0x61, 0x45, + 0x22, 0x00, 0x21, 0x38, 0x1c, 0xf5, 0xf7, 0x56, + 0xfc, 0x12, 0xe0, 0x38, 0x1c, 0xfe, 0xf7, 0x2b, + 0xf8, 0x02, 0x1c, 0x00, 0x23, 0x05, 0x21, 0x38, + 0x1c, 0xfe, 0xf7, 0x3d, 0xfa, 0x04, 0x1c, 0xf9, + 0x1d, 0xff, 0x31, 0x01, 0x20, 0xb0, 0x61, 0x06, + 0x31, 0x38, 0x1c, 0x09, 0x4a, 0xf8, 0xf7, 0x56, + 0xf8, 0xcf, 0x20, 0x28, 0x60, 0x1f, 0x21, 0x01, + 0x20, 0xf5, 0xf7, 0xfe, 0xfb, 0xe8, 0x60, 0xed, + 0x09, 0x00, 0x3b, 0x03, 0x05, 0x20, 0x29, 0x1c, + 0x2c, 0x61, 0xcd, 0xf7, 0xda, 0xfb, 0x20, 0x1c, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x51, 0xb2, + 0x02, 0x20, 0x90, 0xb5, 0x00, 0x24, 0xf5, 0xf7, + 0x1e, 0xfc, 0x07, 0x1c, 0x01, 0xd1, 0x02, 0x24, + 0x28, 0xe0, 0xcd, 0xf7, 0x5b, 0xfb, 0x00, 0x28, + 0x24, 0xd0, 0xc0, 0x22, 0x02, 0x60, 0xfa, 0x6a, + 0x00, 0x21, 0xc2, 0x60, 0x00, 0x22, 0xfa, 0x1d, + 0xff, 0x32, 0x3a, 0x32, 0x01, 0x61, 0x13, 0x6a, + 0x0f, 0x4a, 0x30, 0x27, 0x92, 0x68, 0xff, 0x43, + 0x01, 0x2a, 0x01, 0xd0, 0x3b, 0x27, 0xff, 0x43, + 0xbb, 0x42, 0x01, 0xdd, 0xd9, 0x1b, 0x08, 0xe0, + 0x3d, 0x27, 0xff, 0x43, 0x01, 0x2a, 0x01, 0xd0, + 0x4a, 0x27, 0xff, 0x43, 0xbb, 0x42, 0x00, 0xda, + 0xd9, 0x1b, 0x41, 0x61, 0x01, 0x1c, 0x05, 0x20, + 0xcd, 0xf7, 0xa3, 0xfb, 0x20, 0x1c, 0x90, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x18, 0xec, + 0x03, 0x20, 0xb0, 0xb5, 0x00, 0x27, 0x0d, 0x1c, + 0xf5, 0xf7, 0xe5, 0xfb, 0x04, 0x1c, 0x01, 0xd1, + 0x02, 0x27, 0x13, 0xe0, 0x00, 0x2d, 0x03, 0xd0, + 0x20, 0x1c, 0x00, 0xf0, 0xf4, 0xfc, 0x0d, 0xe0, + 0xcd, 0xf7, 0x1c, 0xfb, 0x00, 0x28, 0x01, 0xd1, + 0x07, 0x27, 0x07, 0xe0, 0x64, 0x21, 0x01, 0x60, + 0x21, 0x6b, 0xc1, 0x60, 0x01, 0x1c, 0x07, 0x20, + 0xcd, 0xf7, 0x7f, 0xfb, 0x38, 0x1c, 0xb0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x00, 0x27, + 0xcd, 0xf7, 0x08, 0xfb, 0x00, 0x28, 0x01, 0xd1, + 0x07, 0x27, 0x08, 0xe0, 0x06, 0x4a, 0x01, 0x21, + 0xd1, 0x60, 0x5f, 0x21, 0x01, 0x60, 0x01, 0x1c, + 0x07, 0x20, 0xcd, 0xf7, 0x6a, 0xfb, 0x38, 0x1c, + 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0xae, + 0x03, 0x20, 0x02, 0x49, 0x01, 0x20, 0x08, 0x63, + 0x00, 0x20, 0xed, 0x09, 0x00, 0x3c, 0x03, 0x70, + 0x47, 0x00, 0x00, 0x38, 0xae, 0x03, 0x20, 0xf0, + 0xb5, 0x83, 0xb0, 0x00, 0x24, 0x0d, 0x1c, 0x07, + 0x1c, 0xcd, 0xf7, 0xe6, 0xfa, 0x06, 0x1c, 0x00, + 0xd1, 0x07, 0x24, 0x38, 0x1c, 0xf5, 0xf7, 0x9d, + 0xfb, 0x07, 0x1c, 0x01, 0xd1, 0x02, 0x24, 0x0e, + 0xe0, 0x0f, 0x21, 0x38, 0x1c, 0xf9, 0xf7, 0x40, + 0xfb, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x24, 0x06, + 0xe0, 0xf8, 0x1d, 0xff, 0x30, 0xba, 0x30, 0x40, + 0x6a, 0x00, 0x28, 0x00, 0xd0, 0x0c, 0x24, 0x00, + 0x2e, 0x12, 0xd0, 0xcf, 0x20, 0x30, 0x60, 0x0f, + 0x21, 0x01, 0x20, 0xf5, 0xf7, 0x52, 0xfb, 0xf0, + 0x60, 0x34, 0x61, 0x00, 0x2f, 0x02, 0xd0, 0xf8, + 0x6a, 0x70, 0x61, 0x01, 0xe0, 0x00, 0x20, 0x70, + 0x61, 0x05, 0x20, 0x31, 0x1c, 0xcd, 0xf7, 0x27, + 0xfb, 0x00, 0x2c, 0x67, 0xd1, 0xf9, 0x1d, 0xff, + 0x31, 0xba, 0x31, 0x01, 0x20, 0x48, 0x62, 0xf8, + 0x1d, 0xb9, 0x30, 0x81, 0x6b, 0x00, 0x29, 0x03, + 0xd1, 0x33, 0x23, 0x9b, 0x02, 0x9d, 0x43, 0x0a, + 0xe0, 0xc0, 0x6b, 0x41, 0x08, 0x02, 0xd2, 0x03, + 0x23, 0x9b, 0x02, 0x9d, 0x43, 0x80, 0x08, 0x02, + 0xd2, 0x03, 0x23, 0x9b, 0x03, 0x9d, 0x43, 0x00, + 0x2d, 0x01, 0xd1, 0x1a, 0x24, 0x50, 0xe0, 0x28, + 0x1c, 0xfe, 0xf7, 0xe7, 0xf8, 0x0b, 0x23, 0x9b, + 0x01, 0xfc, 0x18, 0x02, 0x90, 0xa1, 0x68, 0x88, + 0x42, 0x25, 0xd8, 0x81, 0x42, 0x10, 0xd9, 0x38, + 0x1c, 0xfd, 0xf7, 0x2e, 0xff, 0x01, 0x21, 0x02, + 0xaa, 0x01, 0x92, 0x00, 0x91, 0x2d, 0x21, 0x02, + 0x1c, 0x01, 0x23, 0x38, 0x1c, 0xfe, 0xf7, 0x3c, + 0xf9, 0x02, 0x98, 0x60, 0x60, 0x02, 0x98, 0xa0, + 0x60, 0x05, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x85, + 0x63, 0x38, 0x1c, 0xf9, 0xf7, 0x7b, 0xff, 0x02, + 0x1c, 0x38, 0x1c, 0x29, 0x1c, 0xed, 0x09, 0x00, + 0x3d, 0x03, 0xfa, 0xf7, 0x10, 0xf8, 0x01, 0x1c, + 0x04, 0x1c, 0x38, 0x1c, 0x2a, 0x1c, 0xf8, 0xf7, + 0x07, 0xfa, 0x20, 0xe0, 0x38, 0x1c, 0xfd, 0xf7, + 0x0a, 0xff, 0x01, 0x21, 0x02, 0xaa, 0x01, 0x92, + 0x00, 0x91, 0x2e, 0x21, 0x02, 0x1c, 0x01, 0x23, + 0x38, 0x1c, 0xfe, 0xf7, 0x18, 0xf9, 0x04, 0x1c, + 0x0c, 0xd1, 0x05, 0x23, 0xdb, 0x01, 0xf9, 0x1d, + 0xff, 0x31, 0xf8, 0x18, 0x45, 0x63, 0x12, 0x31, + 0x38, 0x1c, 0x07, 0x4a, 0xf7, 0xf7, 0x2e, 0xff, + 0x05, 0xe0, 0x04, 0xe0, 0x38, 0x1c, 0x21, 0x1c, + 0x2a, 0x1c, 0xf8, 0xf7, 0xe5, 0xf9, 0x20, 0x1c, + 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xd3, 0xb2, 0x02, 0x20, 0x90, 0xb5, 0x00, 0x27, + 0x0c, 0x1c, 0x00, 0x28, 0x06, 0xd1, 0x0e, 0x20, + 0xf7, 0xf7, 0x5c, 0xfd, 0x00, 0x28, 0x01, 0xd1, + 0x02, 0x27, 0x02, 0xe0, 0x21, 0x1c, 0xf9, 0xf7, + 0x5b, 0xff, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x01, 0x1c, 0x01, 0x4a, 0x00, 0x20, + 0x51, 0x62, 0x70, 0x47, 0xf8, 0xad, 0x03, 0x20, + 0x01, 0x1c, 0x02, 0x4a, 0x00, 0x20, 0x91, 0x62, + 0x70, 0x47, 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, + 0xf0, 0xb5, 0x00, 0x24, 0xf5, 0xf7, 0xd8, 0xfa, + 0x01, 0x26, 0x07, 0x1c, 0x00, 0x28, 0x01, 0xd1, + 0x02, 0x24, 0x2f, 0xe0, 0xfd, 0x1d, 0xff, 0x35, + 0x3a, 0x35, 0xe8, 0x6a, 0x00, 0x21, 0x00, 0x28, + 0x0a, 0xd1, 0xf9, 0x1d, 0x9d, 0x31, 0x08, 0x68, + 0x49, 0x68, 0xf7, 0xf7, 0x8d, 0xff, 0x01, 0x1c, + 0x10, 0xd0, 0xc8, 0x6a, 0x00, 0x28, 0x0d, 0xd0, + 0xe8, 0x6a, 0x00, 0x28, 0x08, 0xd1, 0x30, 0x31, + 0xf8, 0x1d, 0xff, 0x30, 0x0c, 0xc9, 0x6e, 0x30, + 0x0c, 0xc0, 0x0c, 0xc9, 0x0c, 0xc0, 0xee, 0x62, + 0x28, 0x25, 0x00, 0xe0, 0x18, 0x25, 0x38, 0x1c, + 0xed, 0x09, 0x00, 0x3e, 0x03, 0x29, 0x1c, 0xf9, + 0xf7, 0x58, 0xfa, 0x00, 0x28, 0x01, 0xd1, 0x0c, + 0x24, 0x06, 0xe0, 0x38, 0x1c, 0x29, 0x1c, 0xf9, + 0xf7, 0x17, 0xfa, 0x00, 0x28, 0x00, 0xd1, 0x0c, + 0x24, 0xcd, 0xf7, 0xe3, 0xf9, 0x05, 0x1c, 0x01, + 0xd1, 0x07, 0x24, 0x1f, 0xe0, 0xcf, 0x20, 0x28, + 0x60, 0x11, 0x21, 0x01, 0x20, 0xf5, 0xf7, 0x66, + 0xfa, 0xe8, 0x60, 0x2c, 0x61, 0x00, 0x2f, 0x02, + 0xd0, 0xf8, 0x6a, 0x68, 0x61, 0x01, 0xe0, 0x00, + 0x20, 0x68, 0x61, 0x05, 0x20, 0x29, 0x1c, 0xcd, + 0xf7, 0x3b, 0xfa, 0x00, 0x2c, 0x0a, 0xd1, 0xf8, + 0x1d, 0xff, 0x30, 0xba, 0x30, 0xc6, 0x60, 0xf8, + 0x1d, 0xff, 0x30, 0x3a, 0x30, 0xc1, 0x6a, 0x38, + 0x1c, 0xf7, 0xf7, 0x88, 0xfa, 0x20, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x00, + 0x24, 0x00, 0x26, 0x0d, 0x1c, 0xf5, 0xf7, 0x72, + 0xfa, 0x07, 0x1c, 0x01, 0xd1, 0x02, 0x24, 0x4c, + 0xe0, 0x2c, 0x21, 0x38, 0x1c, 0xf9, 0xf7, 0x15, + 0xfa, 0x00, 0x28, 0x01, 0xd1, 0x0c, 0x24, 0x44, + 0xe0, 0x2c, 0x22, 0x38, 0x1c, 0xf9, 0x1d, 0x21, + 0x31, 0xf9, 0xf7, 0x98, 0xf9, 0x00, 0x28, 0x01, + 0xd1, 0x0c, 0x24, 0x3a, 0xe0, 0x2f, 0x48, 0x81, + 0x6a, 0x00, 0x29, 0x09, 0xd0, 0xf9, 0x1d, 0xb9, + 0x31, 0x8a, 0x6b, 0x00, 0x2a, 0x02, 0xd0, 0xc9, + 0x6b, 0xc9, 0x08, 0x01, 0xd2, 0x1a, 0x24, 0x2c, + 0xe0, 0x01, 0x21, 0x00, 0x2d, 0x1a, 0xd0, 0xfa, + 0x1d, 0xb9, 0x32, 0x52, 0x68, 0x00, 0x2a, 0x13, + 0xd1, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0x12, + 0x6b, 0x00, 0x2a, 0x01, 0xd1, 0x06, 0x24, 0x1c, + 0xe0, 0xfa, 0x1d, 0xff, 0x32, 0xba, 0x32, 0x51, + 0x61, 0x80, 0x6a, 0x00, 0x28, 0x00, 0xd0, 0x01, + 0x1c, 0x38, 0x1c, 0xfc, 0xf7, 0x7f, 0xf8, 0x10, + 0xe0, 0x01, 0x26, 0xed, 0x09, 0x00, 0x3f, 0x03, + 0x0e, 0xe0, 0xf8, 0x1d, 0xb9, 0x30, 0x40, 0x68, + 0x00, 0x28, 0x08, 0xd0, 0xf8, 0x1d, 0xff, 0x30, + 0xba, 0x30, 0x41, 0x61, 0x00, 0x21, 0x38, 0x1c, + 0xfc, 0xf7, 0x6f, 0xf8, 0x00, 0xe0, 0x01, 0x26, + 0xcd, 0xf7, 0x62, 0xf9, 0x05, 0x1c, 0x01, 0xd1, + 0x07, 0x24, 0x19, 0xe0, 0xcf, 0x20, 0x28, 0x60, + 0x13, 0x21, 0x01, 0x20, 0xf5, 0xf7, 0xe5, 0xf9, + 0xe8, 0x60, 0x2c, 0x61, 0x00, 0x2f, 0x02, 0xd0, + 0xf8, 0x6a, 0x68, 0x61, 0x01, 0xe0, 0x00, 0x20, + 0x68, 0x61, 0x05, 0x20, 0x29, 0x1c, 0xcd, 0xf7, + 0xba, 0xf9, 0x00, 0x2e, 0x04, 0xd0, 0x38, 0x1c, + 0x21, 0x1c, 0xfb, 0xf7, 0xb6, 0xfc, 0x04, 0x1c, + 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0xf8, 0xad, 0x03, 0x20, 0xb0, 0xb5, + 0xf5, 0xf7, 0xf7, 0xf9, 0x07, 0x1c, 0x35, 0xd0, + 0xcd, 0xf7, 0x36, 0xf9, 0x04, 0x1c, 0x1a, 0xd0, + 0x58, 0x20, 0x20, 0x60, 0x38, 0x6b, 0xfd, 0x1d, + 0xe0, 0x60, 0xb1, 0x35, 0x03, 0xcd, 0x16, 0xa3, + 0x1a, 0x68, 0x5b, 0x68, 0x08, 0x3d, 0xcc, 0xf7, + 0xb6, 0xfe, 0x00, 0x28, 0x03, 0xd0, 0xd0, 0xf7, + 0x56, 0xfb, 0x03, 0xc5, 0x08, 0x3d, 0x0c, 0xcd, + 0xe0, 0x1d, 0x09, 0x30, 0x0c, 0xc0, 0x07, 0x20, + 0x21, 0x1c, 0xcd, 0xf7, 0x88, 0xf9, 0xf9, 0x1d, + 0x9d, 0x31, 0x08, 0x68, 0x49, 0x68, 0xf7, 0xf7, + 0x98, 0xfe, 0x04, 0x1c, 0x38, 0x1c, 0x0a, 0xa1, + 0xf7, 0xf7, 0xe3, 0xfa, 0x00, 0x2c, 0x09, 0xd0, + 0x20, 0x6c, 0x00, 0x28, 0x02, 0xd0, 0x00, 0x20, + 0xe0, 0x62, 0x20, 0x64, 0x20, 0x1c, 0x09, 0xa1, + 0xf7, 0xf7, 0xe7, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, 0x6d, + 0x69, 0x66, 0x2e, 0x63, 0x3a, 0x20, 0xed, 0x09, + 0x00, 0x40, 0x03, 0x31, 0x39, 0x30, 0x39, 0x00, + 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5c, 0x6c, + 0x6d, 0x69, 0x66, 0x2e, 0x63, 0x3a, 0x20, 0x31, + 0x39, 0x31, 0x35, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xb5, 0x07, 0x1c, 0xcd, 0xf7, 0xe3, 0xf8, 0x00, + 0x28, 0x07, 0xd0, 0x5b, 0x21, 0x01, 0x60, 0x39, + 0x6b, 0xc1, 0x60, 0x01, 0x1c, 0x07, 0x20, 0xcd, + 0xf7, 0x48, 0xf9, 0x80, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x80, 0xb5, 0xf5, 0xf7, 0x90, 0xf9, 0x07, + 0x1c, 0x0c, 0xd0, 0xf8, 0x1d, 0xf9, 0x30, 0xc1, + 0x6b, 0x00, 0x29, 0x07, 0xd0, 0x00, 0x21, 0xc1, + 0x63, 0x38, 0x1c, 0xff, 0xf7, 0xe0, 0xff, 0x38, + 0x1c, 0x00, 0xf0, 0x1b, 0xf8, 0x80, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xc7, 0x1d, 0xf9, + 0x37, 0xf8, 0x6b, 0x00, 0x28, 0x04, 0xd0, 0x03, + 0xa1, 0xf5, 0xf7, 0xcf, 0xfa, 0x00, 0x20, 0xf8, + 0x63, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x70, 0x6f, 0x77, + 0x65, 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x36, + 0x35, 0x00, 0x00, 0x90, 0xb5, 0x82, 0xb0, 0xc4, + 0x1d, 0xf9, 0x34, 0x07, 0x1c, 0xe0, 0x6b, 0x00, + 0x28, 0x02, 0xd0, 0x08, 0xa1, 0xf5, 0xf7, 0xb5, + 0xfa, 0x0c, 0x49, 0x01, 0x97, 0x00, 0x91, 0x0b, + 0xa1, 0x08, 0x68, 0x00, 0x23, 0x01, 0x22, 0x49, + 0x68, 0xf5, 0xf7, 0x94, 0xfa, 0xe0, 0x63, 0x02, + 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x73, + 0x72, 0x63, 0x5c, 0x6c, 0x6d, 0x70, 0x6f, 0x77, + 0x65, 0x72, 0x2e, 0x63, 0x3a, 0x20, 0x31, 0x37, + 0x37, 0x00, 0x00, 0xa7, 0x39, 0x03, 0x20, 0x80, + 0x84, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xb5, 0x07, 0x1c, 0xcd, 0xf7, 0x7b, 0xf8, 0x00, + 0x28, 0x0d, 0xd0, 0x60, 0x21, 0x01, 0x60, 0x39, + 0x6b, 0xed, 0x09, 0x00, 0x41, 0x03, 0xc1, 0x60, + 0xf9, 0x68, 0x89, 0x6a, 0x41, 0x61, 0xf9, 0x68, + 0x49, 0x6a, 0x01, 0x61, 0x01, 0x1c, 0x07, 0x20, + 0xcd, 0xf7, 0xda, 0xf8, 0x80, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf0, 0xb5, 0x83, 0xb0, 0x04, 0x1c, + 0xc0, 0x68, 0xf5, 0xf7, 0x1f, 0xf9, 0x07, 0x1c, + 0x0d, 0xd0, 0x20, 0x69, 0x00, 0x28, 0x0e, 0xd0, + 0xf8, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x41, 0x69, + 0x01, 0x31, 0x41, 0x61, 0x02, 0x29, 0x02, 0xd9, + 0x77, 0x21, 0xc9, 0x43, 0x01, 0x62, 0x03, 0xb0, + 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xfd, 0x1d, + 0xff, 0x35, 0x3a, 0x35, 0x00, 0x26, 0x6e, 0x61, + 0xe8, 0x69, 0x61, 0x69, 0x41, 0x18, 0xe9, 0x61, + 0xa8, 0x69, 0x01, 0x30, 0xa8, 0x61, 0x04, 0x28, + 0x03, 0xda, 0x38, 0x1c, 0xff, 0xf7, 0x56, 0xff, + 0xe9, 0xe7, 0xdd, 0xf7, 0x21, 0xf9, 0x28, 0x62, + 0xee, 0x61, 0x32, 0x23, 0xd8, 0x42, 0xae, 0x61, + 0x0a, 0xdc, 0xf8, 0x68, 0x81, 0x6a, 0x01, 0x29, + 0x13, 0xd2, 0x81, 0x6a, 0x01, 0x31, 0x81, 0x62, + 0x38, 0x1c, 0xff, 0xf7, 0xab, 0xff, 0x0c, 0xe0, + 0x28, 0x23, 0xd8, 0x42, 0x09, 0xdb, 0xf8, 0x68, + 0x81, 0x6a, 0x00, 0x29, 0x05, 0xd9, 0x81, 0x6a, + 0x01, 0x39, 0x81, 0x62, 0x38, 0x1c, 0xff, 0xf7, + 0x9d, 0xff, 0x01, 0x23, 0x9b, 0x02, 0xf8, 0x18, + 0xc0, 0x6b, 0x00, 0x28, 0x05, 0xd0, 0x11, 0x23, + 0x9b, 0x01, 0xf8, 0x18, 0x00, 0x68, 0x00, 0x28, + 0xbd, 0xd0, 0x78, 0x69, 0x12, 0x28, 0xba, 0xd0, + 0x11, 0x28, 0xb8, 0xd0, 0x13, 0x28, 0xb6, 0xd0, + 0xf8, 0x1d, 0xb9, 0x30, 0x81, 0x6b, 0x00, 0x29, + 0x02, 0xd1, 0xaa, 0x6a, 0x00, 0x2a, 0x04, 0xd0, + 0x00, 0x29, 0xac, 0xd0, 0xc0, 0x6b, 0xc0, 0x0c, + 0xa9, 0xd3, 0x02, 0xab, 0x1e, 0x70, 0x1d, 0x48, + 0x29, 0x6a, 0x80, 0x68, 0xed, 0x09, 0x00, 0x42, + 0x03, 0x30, 0x22, 0xd2, 0x43, 0x01, 0x28, 0x01, + 0xd0, 0x3b, 0x22, 0xd2, 0x43, 0x91, 0x42, 0x13, + 0xdd, 0xa8, 0x68, 0xe9, 0x68, 0x88, 0x42, 0x2a, + 0xdd, 0x01, 0x38, 0xa8, 0x60, 0x38, 0x1c, 0xfd, + 0xf7, 0x8a, 0xfc, 0x01, 0x21, 0x02, 0xaa, 0x01, + 0x92, 0x00, 0x91, 0x20, 0x21, 0x02, 0x1c, 0x01, + 0x23, 0x38, 0x1c, 0xfd, 0xf7, 0x98, 0xfe, 0x1a, + 0xe0, 0x3d, 0x22, 0xd2, 0x43, 0x01, 0x28, 0x01, + 0xd0, 0x4a, 0x22, 0xd2, 0x43, 0x91, 0x42, 0x12, + 0xda, 0xa8, 0x68, 0x29, 0x69, 0x88, 0x42, 0x0e, + 0xda, 0x01, 0x30, 0xa8, 0x60, 0x38, 0x1c, 0xfd, + 0xf7, 0x6e, 0xfc, 0x01, 0x21, 0x02, 0xaa, 0x01, + 0x92, 0x00, 0x91, 0x1f, 0x21, 0x02, 0x1c, 0x01, + 0x23, 0x38, 0x1c, 0xfd, 0xf7, 0x7c, 0xfe, 0x6c, + 0xe7, 0x18, 0xec, 0x03, 0x20, 0xf0, 0xb5, 0x14, + 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0x1f, 0x1c, 0xcc, + 0xf7, 0xb6, 0xff, 0x00, 0x28, 0x0a, 0xd0, 0xe0, + 0x21, 0x01, 0x60, 0xf1, 0x6a, 0xc1, 0x60, 0x05, + 0x61, 0x44, 0x61, 0x87, 0x61, 0x01, 0x1c, 0x05, + 0x20, 0xcd, 0xf7, 0x18, 0xf8, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf0, 0xb5, 0x04, + 0x1c, 0xff, 0x30, 0xc1, 0x30, 0x0d, 0x1c, 0x01, + 0x6b, 0x17, 0x1c, 0x00, 0x29, 0x24, 0xd0, 0x01, + 0x39, 0x01, 0x63, 0xcc, 0xf7, 0x98, 0xff, 0x00, + 0x28, 0x1e, 0xd0, 0xdf, 0x21, 0x01, 0x60, 0x00, + 0x2f, 0x08, 0xd0, 0x0e, 0xcf, 0xc6, 0x1d, 0x0d, + 0x36, 0x0e, 0xc6, 0x0e, 0xcf, 0x0e, 0xc6, 0x0c, + 0xcf, 0x0c, 0xc6, 0x08, 0xe0, 0x00, 0x21, 0x00, + 0x22, 0x00, 0x23, 0xc7, 0x1d, 0x05, 0x37, 0x0e, + 0xc7, 0x0e, 0xc7, 0x0e, 0xc7, 0x08, 0xc7, 0x01, + 0x21, 0x41, 0x61, 0xe1, 0x6a, 0xc1, 0x60, 0x05, + 0x61, 0x01, 0x1c, 0x05, 0x20, 0xcc, 0xf7, 0xed, + 0x09, 0x00, 0x43, 0x03, 0xe6, 0xff, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xf7, 0xf7, + 0x4e, 0xfa, 0x00, 0x28, 0x09, 0xd0, 0xc1, 0x1d, + 0xf9, 0x31, 0x0a, 0x6b, 0x00, 0x2a, 0x04, 0xd0, + 0x00, 0x22, 0x0a, 0x63, 0x22, 0x21, 0xff, 0xf7, + 0xc0, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x08, 0xb5, + 0x0b, 0x1c, 0x11, 0x1c, 0x9a, 0x69, 0x02, 0x2a, + 0x08, 0xd2, 0x0b, 0xa2, 0x00, 0x92, 0x19, 0x23, + 0x79, 0x22, 0xfd, 0xf7, 0x97, 0xfe, 0x01, 0xb0, + 0x08, 0xbc, 0x18, 0x47, 0x05, 0x23, 0xdb, 0x01, + 0xc2, 0x18, 0x09, 0x23, 0x9b, 0x01, 0x91, 0x60, + 0xc1, 0x18, 0xca, 0x69, 0x01, 0x32, 0xca, 0x61, + 0x00, 0x21, 0xff, 0xf7, 0x1a, 0xfc, 0xee, 0xe7, + 0x00, 0x00, 0x4c, 0x6d, 0x4d, 0x61, 0x6e, 0x75, + 0x52, 0x63, 0x76, 0x52, 0x65, 0x71, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x00, + 0x00, 0x00, 0x88, 0xb5, 0x13, 0x1c, 0x8a, 0x69, + 0x10, 0x2a, 0x09, 0xd2, 0x1c, 0xa2, 0x19, 0x1c, + 0x19, 0x23, 0x00, 0x92, 0x79, 0x22, 0xfd, 0xf7, + 0x6d, 0xfe, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xca, 0x69, 0x13, 0x23, 0x92, 0x78, 0x5b, 0x01, + 0xc3, 0x18, 0x9a, 0x70, 0xca, 0x69, 0xff, 0x30, + 0xd2, 0x78, 0xff, 0x30, 0x42, 0x30, 0xda, 0x70, + 0xca, 0x69, 0x00, 0xab, 0x17, 0x79, 0x1f, 0x70, + 0x57, 0x79, 0x5f, 0x70, 0x97, 0x79, 0x9f, 0x70, + 0xd2, 0x79, 0xda, 0x70, 0x00, 0x9a, 0x42, 0x62, + 0xca, 0x69, 0x17, 0x7a, 0x1f, 0x70, 0x57, 0x7a, + 0x5f, 0x70, 0x97, 0x7a, 0x9f, 0x70, 0xd2, 0x7a, + 0xda, 0x70, 0x00, 0x9a, 0x82, 0x62, 0xc9, 0x69, + 0x0a, 0x7b, 0x1a, 0x70, 0x4a, 0x7b, 0x5a, 0x70, + 0x8a, 0x7b, 0x9a, 0x70, 0xc9, 0x7b, 0xd9, 0x70, + 0x00, 0x99, 0xc1, 0x62, 0xcd, 0xe7, 0x4c, 0x6d, + 0x4d, 0x61, 0xed, 0x09, 0x00, 0x44, 0x03, 0x6e, + 0x75, 0x52, 0x63, 0x76, 0x52, 0x63, 0x76, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, + 0x00, 0x00, 0x00, 0x90, 0xb5, 0x89, 0xb0, 0x0c, + 0x1c, 0x07, 0x1c, 0xa0, 0x69, 0x11, 0x1c, 0x10, + 0x28, 0x0a, 0xd2, 0x28, 0xa2, 0x00, 0x92, 0x79, + 0x22, 0x19, 0x23, 0x38, 0x1c, 0xfd, 0xf7, 0x20, + 0xfe, 0x09, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x2a, + 0x31, 0xf7, 0xf7, 0x9d, 0xfb, 0x13, 0x23, 0x5b, + 0x01, 0xf8, 0x18, 0x81, 0x78, 0x02, 0xab, 0x01, + 0xaa, 0x59, 0x70, 0xc0, 0x78, 0x98, 0x70, 0x09, + 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x41, 0x6a, 0x02, + 0xab, 0x03, 0x91, 0x81, 0x6a, 0x04, 0x91, 0xc0, + 0x6a, 0x05, 0x90, 0xe0, 0x69, 0x80, 0x78, 0x18, + 0x70, 0xe0, 0x69, 0xc0, 0x78, 0xd8, 0x70, 0xe0, + 0x69, 0x08, 0x3b, 0x01, 0x79, 0x19, 0x70, 0x41, + 0x79, 0x00, 0xab, 0x59, 0x70, 0x81, 0x79, 0x99, + 0x70, 0xc0, 0x79, 0xd8, 0x70, 0x00, 0x98, 0x06, + 0x90, 0xe0, 0x69, 0x01, 0x7a, 0x19, 0x70, 0x41, + 0x7a, 0x59, 0x70, 0x81, 0x7a, 0x99, 0x70, 0xc0, + 0x7a, 0xd8, 0x70, 0x00, 0x98, 0x07, 0x90, 0xe0, + 0x69, 0x01, 0x7b, 0x19, 0x70, 0x41, 0x7b, 0x59, + 0x70, 0x81, 0x7b, 0x99, 0x70, 0xc0, 0x7b, 0x00, + 0x21, 0xd8, 0x70, 0x00, 0x98, 0x08, 0x90, 0x38, + 0x1c, 0xff, 0xf7, 0xf1, 0xfe, 0xb4, 0xe7, 0x4c, + 0x6d, 0x4d, 0x61, 0x6e, 0x75, 0x52, 0x63, 0x76, + 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x73, 0x74, 0x69, 0x63, 0x00, 0x00, 0x88, + 0xb5, 0x13, 0x23, 0x5b, 0x01, 0x17, 0x1c, 0xc2, + 0x18, 0x12, 0x88, 0x1f, 0x2a, 0x09, 0xd0, 0x18, + 0xa2, 0x00, 0x92, 0x79, 0x22, 0x19, 0x23, 0x39, + 0x1c, 0xfd, 0xf7, 0xba, 0xfd, 0xed, 0x09, 0x00, + 0x45, 0x03, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x8a, 0x69, 0x01, 0x2a, 0x07, 0xd8, 0x12, 0xa2, + 0x00, 0x92, 0x79, 0x22, 0x19, 0x23, 0x39, 0x1c, + 0xfd, 0xf7, 0xad, 0xfd, 0xf1, 0xe7, 0xca, 0x69, + 0x52, 0x78, 0x41, 0x2a, 0x07, 0xd0, 0xc1, 0x2a, + 0x09, 0xd0, 0xc2, 0x2a, 0x0b, 0xd1, 0x3a, 0x1c, + 0xff, 0xf7, 0x72, 0xff, 0xe5, 0xe7, 0x3a, 0x1c, + 0xff, 0xf7, 0xfa, 0xfe, 0xe1, 0xe7, 0x3a, 0x1c, + 0xff, 0xf7, 0x20, 0xff, 0xdd, 0xe7, 0x04, 0xa2, + 0x00, 0x92, 0x79, 0x22, 0x19, 0x23, 0x39, 0x1c, + 0xfd, 0xf7, 0x91, 0xfd, 0xd5, 0xe7, 0x00, 0x00, + 0x4c, 0x6d, 0x4d, 0x61, 0x6e, 0x75, 0x52, 0x63, + 0x76, 0x4d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, + 0x74, 0x75, 0x72, 0x65, 0x72, 0x00, 0x00, 0x00, + 0x90, 0xb5, 0x07, 0x1c, 0xff, 0x30, 0xc1, 0x30, + 0x00, 0x6b, 0x0c, 0x1c, 0x00, 0x28, 0x0c, 0xd0, + 0xf9, 0x1d, 0xff, 0x31, 0x38, 0x1c, 0x2a, 0x31, + 0xf7, 0xf7, 0xfc, 0xfa, 0x00, 0x2c, 0x04, 0xd0, + 0x00, 0x22, 0x38, 0x1c, 0x21, 0x1c, 0xff, 0xf7, + 0x89, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0xb0, 0xb5, 0x83, 0xb0, 0x07, 0x1c, 0x41, 0x20, + 0x02, 0x90, 0xcc, 0xf7, 0x24, 0xfe, 0x05, 0x1c, + 0x01, 0xd1, 0x07, 0x24, 0x2e, 0xe0, 0x13, 0x23, + 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x88, 0x1f, 0x28, + 0x01, 0xd0, 0x1a, 0x24, 0x1a, 0xe0, 0x38, 0x1c, + 0xfd, 0xf7, 0xb9, 0xfa, 0x01, 0x21, 0x02, 0xaa, + 0x01, 0x92, 0x00, 0x91, 0x79, 0x21, 0x02, 0x1c, + 0x01, 0x23, 0x38, 0x1c, 0xfd, 0xf7, 0xc7, 0xfc, + 0x04, 0x1c, 0x0b, 0xd1, 0xf9, 0x1d, 0xff, 0x31, + 0xba, 0x31, 0x01, 0x20, 0x08, 0x63, 0xf9, 0x1d, + 0xff, 0x31, 0x2a, 0x31, 0x38, 0x1c, 0x0a, 0x4a, + 0xf7, 0xf7, 0xdc, 0xfa, 0xcf, 0x20, 0x28, 0x60, + 0xed, 0x09, 0x00, 0x46, 0x03, 0x12, 0x21, 0x3f, + 0x20, 0xf4, 0xf7, 0x84, 0xfe, 0xe8, 0x60, 0x05, + 0x20, 0x29, 0x1c, 0x2c, 0x61, 0xcc, 0xf7, 0x60, + 0xfe, 0x20, 0x1c, 0x03, 0xb0, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x6b, 0x3c, 0x03, + 0x20, 0xb0, 0xb5, 0x8d, 0xb0, 0x0f, 0x1c, 0xca, + 0x1d, 0x04, 0x1c, 0xc1, 0x20, 0x0c, 0x90, 0x09, + 0x32, 0x0b, 0x92, 0xf8, 0x1d, 0x04, 0x21, 0x0a, + 0x91, 0x05, 0x30, 0x09, 0x90, 0xf9, 0x1d, 0x04, + 0x22, 0x08, 0x92, 0x01, 0x31, 0x04, 0x20, 0x06, + 0x90, 0x07, 0x91, 0x01, 0x21, 0x78, 0x1d, 0xba, + 0x1d, 0x05, 0x92, 0x03, 0x90, 0x01, 0x20, 0x01, + 0x22, 0x05, 0x23, 0xdb, 0x01, 0x04, 0x91, 0x0c, + 0xa9, 0x01, 0x91, 0xe5, 0x18, 0x00, 0x90, 0x06, + 0x23, 0x79, 0x21, 0x02, 0x92, 0xaa, 0x68, 0x20, + 0x1c, 0xfd, 0xf7, 0x7b, 0xfc, 0xc2, 0x20, 0x0c, + 0x90, 0xfa, 0x1d, 0x15, 0x32, 0xf8, 0x1d, 0x04, + 0x21, 0x0a, 0x91, 0x11, 0x30, 0x0b, 0x92, 0x09, + 0x90, 0xf9, 0x1d, 0x0d, 0x31, 0x04, 0x22, 0x08, + 0x92, 0x07, 0x91, 0x04, 0x20, 0x06, 0x90, 0x01, + 0x21, 0x04, 0x91, 0x38, 0x18, 0xfa, 0x1d, 0x05, + 0x92, 0x03, 0x90, 0x0c, 0xa9, 0x01, 0x91, 0x01, + 0x20, 0x01, 0x22, 0x00, 0x90, 0x02, 0x92, 0x79, + 0x21, 0x06, 0x23, 0x20, 0x1c, 0xaa, 0x68, 0xfd, + 0xf7, 0x58, 0xfc, 0x0d, 0xb0, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x07, 0x49, 0x08, + 0x48, 0x08, 0x4a, 0x01, 0x60, 0x42, 0x60, 0xc9, + 0x61, 0x41, 0x68, 0x02, 0x68, 0x91, 0x61, 0x06, + 0xc8, 0x08, 0x38, 0xd1, 0x61, 0x40, 0x68, 0x80, + 0x61, 0x70, 0x47, 0x00, 0x00, 0xb4, 0x17, 0x04, + 0x20, 0xc8, 0xb2, 0x03, 0x20, 0xd4, 0x17, 0x04, + 0x20, 0x00, 0xb5, 0x07, 0x48, 0x41, 0x68, 0x02, + 0x68, 0x91, 0x61, 0xed, 0x09, 0x00, 0x47, 0x03, + 0x01, 0x68, 0x40, 0x68, 0x00, 0x22, 0xc1, 0x61, + 0x00, 0x21, 0x00, 0x20, 0xe1, 0xf7, 0x03, 0xfa, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xc8, 0xb2, + 0x03, 0x20, 0xff, 0xb5, 0x82, 0xb0, 0x0c, 0x1c, + 0x07, 0x1c, 0x01, 0xf0, 0xc4, 0xfb, 0xf8, 0x68, + 0x01, 0x28, 0x02, 0xd1, 0x38, 0x1c, 0x00, 0xf0, + 0x3e, 0xf8, 0x01, 0x20, 0xf8, 0x60, 0xe1, 0xf7, + 0x9f, 0xf9, 0x00, 0x23, 0x00, 0x19, 0x59, 0x41, + 0x03, 0xc7, 0x08, 0x3f, 0x01, 0x91, 0xbc, 0x60, + 0x05, 0x9b, 0x05, 0x1c, 0x7b, 0x61, 0x04, 0x9a, + 0x15, 0x48, 0x3a, 0x61, 0x01, 0x68, 0x8e, 0x69, + 0x40, 0x68, 0x00, 0x90, 0x86, 0x42, 0x0b, 0xd0, + 0x03, 0xce, 0x08, 0x3e, 0x2a, 0x1c, 0x01, 0x9b, + 0xdc, 0xf7, 0xc5, 0xfd, 0x00, 0x28, 0x03, 0xd1, + 0xb6, 0x69, 0x00, 0x98, 0x86, 0x42, 0xf3, 0xd1, + 0xbe, 0x61, 0xf0, 0x69, 0x0a, 0x49, 0xf8, 0x61, + 0xf0, 0x69, 0x87, 0x61, 0xf7, 0x61, 0xf8, 0x69, + 0x09, 0x68, 0x88, 0x42, 0x04, 0xd1, 0x00, 0x22, + 0x20, 0x1c, 0x05, 0x49, 0xe1, 0xf7, 0xbf, 0xf9, + 0x01, 0xf0, 0x85, 0xfb, 0x06, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xc8, 0xb2, + 0x03, 0x20, 0xbb, 0x41, 0x03, 0x20, 0xf8, 0xb5, + 0x07, 0x1c, 0x02, 0xd1, 0xf8, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0xf8, 0x68, 0x00, 0x28, 0x00, 0xd1, + 0xf8, 0xe7, 0x01, 0xf0, 0x74, 0xfb, 0x1b, 0x48, + 0x01, 0x68, 0x89, 0x69, 0xb9, 0x42, 0x26, 0xd1, + 0xb9, 0x69, 0x40, 0x68, 0x81, 0x42, 0x05, 0xd1, + 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0xe1, 0xf7, + 0x9a, 0xf9, 0x1c, 0xe0, 0xe1, 0xf7, 0x48, 0xf9, + 0x0c, 0x1c, 0xb9, 0x69, 0x05, 0x1c, 0x08, 0x68, + 0x2a, 0x1c, 0x00, 0x90, 0x4e, 0x68, 0x31, 0x1c, + 0x23, 0x1c, 0xdc, 0xf7, 0xd8, 0xfd, 0xed, 0x09, + 0x00, 0x48, 0x03, 0x00, 0x28, 0x05, 0xd0, 0x00, + 0x22, 0x00, 0x20, 0x0c, 0x49, 0xe1, 0xf7, 0x85, + 0xf9, 0x07, 0xe0, 0x00, 0x98, 0x31, 0x1c, 0x40, + 0x1b, 0xa1, 0x41, 0x08, 0x49, 0x00, 0x22, 0xe1, + 0xf7, 0x7c, 0xf9, 0xf8, 0x69, 0xb9, 0x69, 0xc8, + 0x61, 0xb8, 0x69, 0xf9, 0x69, 0x88, 0x61, 0x00, + 0x20, 0xf8, 0x60, 0x01, 0xf0, 0x3a, 0xfb, 0xbf, + 0xe7, 0x00, 0x00, 0xc8, 0xb2, 0x03, 0x20, 0xbb, + 0x41, 0x03, 0x20, 0x90, 0xb5, 0x0c, 0x1c, 0x07, + 0x1c, 0x00, 0x28, 0x08, 0xd0, 0x38, 0x1c, 0xff, + 0xf7, 0xb0, 0xff, 0x3a, 0x69, 0x38, 0x1c, 0x21, + 0x1c, 0x7b, 0x69, 0xff, 0xf7, 0x60, 0xff, 0x90, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x01, + 0xf0, 0x24, 0xfb, 0xe1, 0xf7, 0x07, 0xf9, 0x04, + 0x1c, 0x21, 0x48, 0x0f, 0x1c, 0x01, 0x68, 0x00, + 0x26, 0x8d, 0x69, 0x41, 0x68, 0x8d, 0x42, 0x05, + 0xd1, 0x01, 0xf0, 0x13, 0xfb, 0x30, 0x1c, 0xf0, + 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x1c, 0x03, + 0xcd, 0x08, 0x3d, 0x22, 0x1c, 0x3b, 0x1c, 0xdc, + 0xf7, 0x30, 0xfd, 0x00, 0x28, 0x19, 0xd1, 0xa8, + 0x69, 0x31, 0x68, 0x88, 0x61, 0x30, 0x68, 0xa9, + 0x69, 0xc8, 0x61, 0x00, 0x20, 0xe8, 0x60, 0x69, + 0x69, 0x2a, 0x69, 0x28, 0x1c, 0xcc, 0xf7, 0xe9, + 0xf8, 0x00, 0x28, 0x05, 0xd0, 0xa9, 0x68, 0x2a, + 0x69, 0x6b, 0x69, 0x28, 0x1c, 0xff, 0xf7, 0x2b, + 0xff, 0x30, 0x68, 0x85, 0x69, 0x70, 0x68, 0x85, + 0x42, 0xdd, 0xd1, 0x70, 0x68, 0x85, 0x42, 0x03, + 0xd1, 0x01, 0xf0, 0xe7, 0xfa, 0x00, 0x20, 0xd2, + 0xe7, 0x03, 0xcd, 0x00, 0x1b, 0xb9, 0x41, 0x04, + 0x49, 0x00, 0x22, 0xe1, 0xf7, 0x16, 0xf9, 0x01, + 0xf0, 0xdc, 0xfa, 0x00, 0x20, 0xc7, 0xe7, 0xc8, + 0xb2, 0x03, 0x20, 0xbb, 0x41, 0x03, 0x20, 0x00, + 0x28, 0xed, 0x09, 0x00, 0x49, 0x03, 0x01, 0xd1, + 0x1f, 0xa0, 0x70, 0x47, 0x01, 0x28, 0x01, 0xd1, + 0x22, 0xa0, 0x70, 0x47, 0x02, 0x28, 0x01, 0xd1, + 0x25, 0xa0, 0x70, 0x47, 0x03, 0x28, 0x01, 0xd1, + 0x28, 0xa0, 0x70, 0x47, 0x04, 0x28, 0x01, 0xd1, + 0x2b, 0xa0, 0x70, 0x47, 0x05, 0x28, 0x01, 0xd1, + 0x2e, 0xa0, 0x70, 0x47, 0x06, 0x28, 0x01, 0xd1, + 0x31, 0xa0, 0x70, 0x47, 0x07, 0x28, 0x01, 0xd1, + 0x34, 0xa0, 0x70, 0x47, 0x08, 0x28, 0x01, 0xd1, + 0x37, 0xa0, 0x70, 0x47, 0x09, 0x28, 0x01, 0xd1, + 0x3a, 0xa0, 0x70, 0x47, 0x0a, 0x28, 0x01, 0xd1, + 0x3d, 0xa0, 0x70, 0x47, 0x0b, 0x28, 0x01, 0xd1, + 0x40, 0xa0, 0x70, 0x47, 0x0c, 0x28, 0x01, 0xd1, + 0x43, 0xa0, 0x70, 0x47, 0x0d, 0x28, 0x01, 0xd1, + 0x46, 0xa0, 0x70, 0x47, 0x0e, 0x28, 0x01, 0xd1, + 0x4a, 0xa0, 0x70, 0x47, 0x0f, 0x28, 0x01, 0xd1, + 0x4d, 0xa0, 0x70, 0x47, 0x52, 0xa0, 0x70, 0x47, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x6f, + 0x6d, 0x5f, 0x55, 0x50, 0x5f, 0x54, 0x6f, 0x5f, + 0x48, 0x43, 0x00, 0x00, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x48, 0x43, + 0x5f, 0x54, 0x6f, 0x5f, 0x48, 0x43, 0x00, 0x00, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x6f, + 0x6d, 0x5f, 0x48, 0x43, 0x5f, 0x54, 0x6f, 0x5f, + 0x4c, 0x4d, 0x00, 0x00, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x48, 0x43, + 0x5f, 0x54, 0x6f, 0x5f, 0x4c, 0x43, 0x00, 0x00, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x6f, + 0x6d, 0x5f, 0x48, 0x43, 0x5f, 0x54, 0x6f, 0x5f, + 0x49, 0x72, 0x71, 0x00, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x4c, 0x4d, + 0x5f, 0x54, 0x6f, 0x5f, 0x48, 0x43, 0x00, 0x00, + 0x45, 0x76, 0x65, 0x6e, 0xed, 0x09, 0x00, 0x4a, + 0x03, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x4c, + 0x4d, 0x5f, 0x54, 0x6f, 0x5f, 0x4c, 0x4d, 0x00, + 0x00, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, + 0x6f, 0x6d, 0x5f, 0x4c, 0x4d, 0x5f, 0x54, 0x6f, + 0x5f, 0x4c, 0x43, 0x00, 0x00, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x4c, + 0x43, 0x5f, 0x54, 0x6f, 0x5f, 0x48, 0x43, 0x00, + 0x00, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, + 0x6f, 0x6d, 0x5f, 0x4c, 0x43, 0x5f, 0x54, 0x6f, + 0x5f, 0x4c, 0x4d, 0x00, 0x00, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x4c, + 0x43, 0x5f, 0x54, 0x6f, 0x5f, 0x4c, 0x43, 0x00, + 0x00, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, + 0x6f, 0x6d, 0x5f, 0x4c, 0x43, 0x5f, 0x54, 0x6f, + 0x5f, 0x49, 0x72, 0x71, 0x00, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x44, + 0x50, 0x43, 0x5f, 0x54, 0x6f, 0x5f, 0x4c, 0x43, + 0x00, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, + 0x6f, 0x6d, 0x5f, 0x49, 0x72, 0x71, 0x5f, 0x54, + 0x6f, 0x5f, 0x44, 0x50, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x72, + 0x6f, 0x6d, 0x5f, 0x49, 0x72, 0x71, 0x5f, 0x54, + 0x6f, 0x5f, 0x4c, 0x43, 0x00, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x5f, 0x49, + 0x72, 0x71, 0x5f, 0x54, 0x6f, 0x5f, 0x49, 0x72, + 0x71, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x42, 0x54, + 0x5f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x01, 0xd1, 0x39, 0xa0, 0x70, + 0x47, 0x01, 0x28, 0x01, 0xd1, 0x3c, 0xa0, 0x70, + 0x47, 0x02, 0x28, 0x01, 0xd1, 0x40, 0xa0, 0xed, + 0x09, 0x00, 0x4b, 0x03, 0x70, 0x47, 0x03, 0x28, + 0x01, 0xd1, 0x45, 0xa0, 0x70, 0x47, 0x04, 0x28, + 0x01, 0xd1, 0x49, 0xa0, 0x70, 0x47, 0x05, 0x28, + 0x01, 0xd1, 0x4e, 0xa0, 0x70, 0x47, 0x06, 0x28, + 0x01, 0xd1, 0x53, 0xa0, 0x70, 0x47, 0x07, 0x28, + 0x01, 0xd1, 0x57, 0xa0, 0x70, 0x47, 0x08, 0x28, + 0x01, 0xd1, 0x5a, 0xa0, 0x70, 0x47, 0x09, 0x28, + 0x01, 0xd1, 0x5e, 0xa0, 0x70, 0x47, 0x0a, 0x28, + 0x01, 0xd1, 0x62, 0xa0, 0x70, 0x47, 0x0b, 0x28, + 0x01, 0xd1, 0x68, 0xa0, 0x70, 0x47, 0x0c, 0x28, + 0x01, 0xd1, 0x6f, 0xa0, 0x70, 0x47, 0x0d, 0x28, + 0x01, 0xd1, 0x74, 0xa0, 0x70, 0x47, 0x0e, 0x28, + 0x01, 0xd1, 0x79, 0xa0, 0x70, 0x47, 0x0f, 0x28, + 0x01, 0xd1, 0x7f, 0xa0, 0x70, 0x47, 0x10, 0x28, + 0x01, 0xd1, 0x83, 0xa0, 0x70, 0x47, 0x11, 0x28, + 0x01, 0xd1, 0x88, 0xa0, 0x70, 0x47, 0x12, 0x28, + 0x01, 0xd1, 0x8d, 0xa0, 0x70, 0x47, 0x13, 0x28, + 0x01, 0xd1, 0x93, 0xa0, 0x70, 0x47, 0x14, 0x28, + 0x01, 0xd1, 0x9a, 0xa0, 0x70, 0x47, 0x15, 0x28, + 0x01, 0xd1, 0x9f, 0xa0, 0x70, 0x47, 0x16, 0x28, + 0x01, 0xd1, 0xa4, 0xa0, 0x70, 0x47, 0x17, 0x28, + 0x01, 0xd1, 0xab, 0xa0, 0x70, 0x47, 0x18, 0x28, + 0x01, 0xd1, 0xaf, 0xa0, 0x70, 0x47, 0x19, 0x28, + 0x01, 0xd1, 0xb4, 0xa0, 0x70, 0x47, 0x1a, 0x28, + 0x01, 0xd1, 0xba, 0xa0, 0x70, 0x47, 0x1b, 0x28, + 0x01, 0xd1, 0xbd, 0xa0, 0x70, 0x47, 0x1c, 0x28, + 0x01, 0xd1, 0xc1, 0xa0, 0x70, 0x47, 0xc5, 0xa0, + 0x70, 0x47, 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, + 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4e, 0x44, + 0x42, 0x59, 0x00, 0x00, 0x00, 0x00, 0x42, 0x54, + 0x5f, 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x53, + 0x43, 0x41, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x50, + 0x5f, 0x52, 0xed, 0x09, 0x00, 0x4c, 0x03, 0x45, + 0x51, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, + 0x5f, 0x53, 0x54, 0x5f, 0x49, 0x4e, 0x51, 0x55, + 0x49, 0x52, 0x59, 0x5f, 0x53, 0x43, 0x41, 0x4e, + 0x5f, 0x52, 0x45, 0x51, 0x00, 0x00, 0x00, 0x42, + 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, + 0x49, 0x4e, 0x51, 0x55, 0x49, 0x52, 0x59, 0x5f, + 0x53, 0x43, 0x41, 0x4e, 0x00, 0x00, 0x00, 0x42, + 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, + 0x49, 0x4e, 0x51, 0x55, 0x49, 0x52, 0x59, 0x5f, + 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57, 0x41, 0x49, + 0x54, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, + 0x5f, 0x53, 0x54, 0x5f, 0x49, 0x4e, 0x51, 0x55, + 0x49, 0x52, 0x59, 0x5f, 0x53, 0x43, 0x41, 0x4e, + 0x5f, 0x52, 0x53, 0x50, 0x00, 0x00, 0x00, 0x42, + 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, + 0x50, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x43, 0x41, + 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x00, 0x00, 0x42, + 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, + 0x50, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x43, 0x41, + 0x4e, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, + 0x5f, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, + 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x52, 0x53, + 0x50, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, + 0x5f, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, + 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x50, 0x4f, + 0x4c, 0x4c, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, + 0x5f, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4e, + 0x44, 0x42, 0x59, 0x5f, 0x49, 0x4e, 0x51, 0x55, + 0x49, 0x52, 0x59, 0x5f, 0x52, 0x45, 0x51, 0x00, + 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, + 0x5f, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4e, + 0x44, 0x42, 0x59, 0x5f, 0x49, 0xed, 0x09, 0x00, + 0x4d, 0x03, 0x4e, 0x51, 0x55, 0x49, 0x52, 0x59, + 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x52, 0x45, + 0x51, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x49, 0x4e, 0x51, + 0x55, 0x49, 0x52, 0x59, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, 0x54, + 0x5f, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, + 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, + 0x51, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x50, 0x41, 0x47, + 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x52, + 0x45, 0x51, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x50, 0x41, 0x47, + 0x45, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x50, 0x41, 0x47, + 0x45, 0x5f, 0x52, 0x53, 0x50, 0x00, 0x00, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, 0x54, + 0x5f, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, + 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x50, 0x4f, + 0x4c, 0x4c, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, 0x4e, + 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, 0x49, + 0x4e, 0x51, 0x55, 0x49, 0x52, 0x59, 0x5f, 0x52, + 0x45, 0x51, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, 0x4e, + 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, 0x49, + 0x4e, 0x51, 0x55, 0x49, 0x52, 0x59, 0x5f, 0x53, + 0x54, 0x4f, 0x50, 0x5f, 0x52, 0x45, 0x51, 0x00, + 0xed, 0x09, 0x00, 0x4e, 0x03, 0x42, 0x54, 0x5f, + 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, + 0x49, 0x4e, 0x51, 0x55, 0x49, 0x52, 0x59, 0x00, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, + 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, + 0x54, 0x45, 0x44, 0x5f, 0x50, 0x41, 0x47, 0x45, + 0x5f, 0x52, 0x45, 0x51, 0x00, 0x42, 0x54, 0x5f, + 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, + 0x50, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x4f, + 0x50, 0x5f, 0x52, 0x45, 0x51, 0x00, 0x00, 0x00, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, + 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, + 0x54, 0x45, 0x44, 0x5f, 0x50, 0x41, 0x47, 0x45, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, + 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, + 0x54, 0x45, 0x44, 0x5f, 0x50, 0x41, 0x47, 0x45, + 0x5f, 0x52, 0x53, 0x50, 0x00, 0x42, 0x54, 0x5f, + 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, + 0x50, 0x41, 0x47, 0x45, 0x5f, 0x50, 0x4f, 0x4c, + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, + 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x00, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, + 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, + 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x4f, 0x50, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x53, + 0x54, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x48, 0x41, + 0x4e, 0x47, 0x45, 0x00, 0x00, 0x5f, 0x42, 0x54, + 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x75, + 0x6e, 0x6b, 0x6e, 0xed, 0x09, 0x00, 0x4f, 0x03, + 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x01, 0xd1, 0x0b, 0xa0, 0x70, 0x47, 0x01, 0x28, + 0x01, 0xd1, 0x0d, 0xa0, 0x70, 0x47, 0x02, 0x28, + 0x01, 0xd1, 0x11, 0xa0, 0x70, 0x47, 0x03, 0x28, + 0x01, 0xd1, 0x14, 0xa0, 0x70, 0x47, 0x04, 0x28, + 0x01, 0xd1, 0x18, 0xa0, 0x70, 0x47, 0x05, 0x28, + 0x01, 0xd1, 0x1b, 0xa0, 0x70, 0x47, 0x20, 0xa0, + 0x70, 0x47, 0x42, 0x54, 0x5f, 0x4c, 0x49, 0x4e, + 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x49, 0x44, 0x4c, + 0x45, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x49, 0x4e, + 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x52, 0x4f, 0x4c, + 0x45, 0x5f, 0x53, 0x57, 0x49, 0x54, 0x43, 0x48, + 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x49, 0x4e, + 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x47, + 0x49, 0x4e, 0x47, 0x00, 0x00, 0x00, 0x42, 0x54, + 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, + 0x5f, 0x44, 0x45, 0x54, 0x41, 0x43, 0x48, 0x49, + 0x4e, 0x47, 0x00, 0x00, 0x00, 0x00, 0x42, 0x54, + 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, + 0x5f, 0x44, 0x45, 0x54, 0x41, 0x43, 0x48, 0x45, + 0x44, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x49, 0x4e, + 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, 0x4e, + 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x5f, 0x42, 0x54, 0x5f, 0x4c, 0x63, + 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x00, 0x00, 0x28, 0x01, 0xd1, 0x0f, 0xa0, + 0x70, 0x47, 0x01, 0x28, 0x01, 0xd1, 0x12, 0xa0, + 0x70, 0x47, 0x02, 0x28, 0x01, 0xd1, 0x15, 0xa0, + 0x70, 0x47, 0x03, 0x28, 0x01, 0xd1, 0x1a, 0xa0, + 0x70, 0x47, 0x04, 0x28, 0x01, 0xd1, 0x1e, 0xa0, + 0x70, 0x47, 0x05, 0x28, 0x01, 0xd1, 0xed, 0x09, + 0x00, 0x50, 0x03, 0x21, 0xa0, 0x70, 0x47, 0x06, + 0x28, 0x01, 0xd1, 0x26, 0xa0, 0x70, 0x47, 0x07, + 0x28, 0x01, 0xd1, 0x2a, 0xa0, 0x70, 0x47, 0x2f, + 0xa0, 0x70, 0x47, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x46, 0x72, 0x65, 0x65, 0x00, 0x00, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x6c, + 0x65, 0x00, 0x00, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x71, + 0x75, 0x69, 0x72, 0x79, 0x00, 0x00, 0x00, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x67, + 0x65, 0x00, 0x00, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x71, 0x75, 0x69, 0x72, 0x79, + 0x53, 0x63, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x67, + 0x65, 0x53, 0x63, 0x61, 0x6e, 0x00, 0x00, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x78, 0x54, + 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x5f, + 0x42, 0x54, 0x5f, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x00, 0x00, 0x00, 0x28, 0x01, 0xd1, 0x05, + 0xa0, 0x70, 0x47, 0x01, 0x28, 0x01, 0xd1, 0x07, + 0xa0, 0xed, 0x09, 0x00, 0x51, 0x03, 0x70, 0x47, + 0x02, 0x28, 0x01, 0xd1, 0x0a, 0xa0, 0x70, 0x47, + 0x0e, 0xa0, 0x70, 0x47, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4e, + 0x4f, 0x4e, 0x45, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x43, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4d, + 0x41, 0x53, 0x54, 0x45, 0x52, 0x00, 0x00, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x43, 0x5f, 0x4d, 0x4f, + 0x44, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x56, 0x45, + 0x00, 0x00, 0x00, 0x00, 0x5f, 0x42, 0x54, 0x5f, + 0x4d, 0x6f, 0x64, 0x65, 0x5f, 0x75, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x01, 0xd1, 0x23, 0xa0, 0x70, 0x47, + 0x01, 0x28, 0x01, 0xd1, 0x26, 0xa0, 0x70, 0x47, + 0x02, 0x28, 0x01, 0xd1, 0x29, 0xa0, 0x70, 0x47, + 0x03, 0x28, 0x01, 0xd1, 0x2b, 0xa0, 0x70, 0x47, + 0x04, 0x28, 0x01, 0xd1, 0x2d, 0xa0, 0x70, 0x47, + 0x05, 0x28, 0x01, 0xd1, 0x2f, 0xa0, 0x70, 0x47, + 0x06, 0x28, 0x01, 0xd1, 0x31, 0xa0, 0x70, 0x47, + 0x07, 0x28, 0x01, 0xd1, 0x33, 0xa0, 0x70, 0x47, + 0x08, 0x28, 0x01, 0xd1, 0x35, 0xa0, 0x70, 0x47, + 0x09, 0x28, 0x01, 0xd1, 0x37, 0xa0, 0x70, 0x47, + 0x0a, 0x28, 0x01, 0xd1, 0x3a, 0xa0, 0x70, 0x47, + 0x0b, 0x28, 0x01, 0xd1, 0x3c, 0xa0, 0x70, 0x47, + 0x0c, 0x28, 0x01, 0xd1, 0x3e, 0xa0, 0x70, 0x47, + 0x0d, 0x28, 0x01, 0xd1, 0x42, 0xa0, 0x70, 0x47, + 0x0e, 0x28, 0x01, 0xd1, 0x46, 0xa0, 0x70, 0x47, + 0x0f, 0x28, 0x01, 0xd1, 0x48, 0xa0, 0x70, 0x47, + 0x10, 0x28, 0x01, 0xd1, 0x4a, 0xa0, 0x70, 0x47, + 0x11, 0x28, 0x01, 0xd1, 0x4c, 0xa0, 0x70, 0x47, + 0x52, 0xa0, 0x70, 0x47, 0x42, 0x54, 0x5f, 0x50, + 0x4b, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x4e, 0x55, 0x4c, 0x4c, 0xed, 0x09, 0x00, 0x52, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, + 0x50, 0x4b, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x50, 0x4f, 0x4c, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x48, 0x53, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4d, 0x31, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x48, 0x31, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x56, 0x31, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x56, 0x32, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x56, 0x33, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x56, 0x00, + 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x55, 0x58, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, + 0x50, 0x4b, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x44, 0x4d, 0x33, 0x00, 0x42, 0x54, 0x5f, + 0x50, 0x4b, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x44, 0x48, 0x33, 0x00, 0x42, 0x54, 0x5f, + 0x50, 0x4b, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x43, 0x00, 0x00, 0x42, 0x54, 0x5f, + 0x50, 0x4b, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x44, 0x00, 0x00, 0x42, 0x54, 0x5f, + 0x50, 0x4b, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x44, 0x4d, 0x35, 0x00, 0x42, 0x54, 0xed, + 0x09, 0x00, 0x53, 0x03, 0x5f, 0x50, 0x4b, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x48, + 0x35, 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x44, + 0x00, 0x00, 0x42, 0x54, 0x5f, 0x50, 0x4b, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, + 0x44, 0x5f, 0x4f, 0x46, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x42, + 0x54, 0x5f, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x5f, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x75, 0x6e, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x28, + 0x01, 0xd1, 0x09, 0xa0, 0x70, 0x47, 0x01, 0x28, + 0x01, 0xd1, 0x0d, 0xa0, 0x70, 0x47, 0x02, 0x28, + 0x01, 0xd1, 0x12, 0xa0, 0x70, 0x47, 0x03, 0x28, + 0x01, 0xd1, 0x17, 0xa0, 0x70, 0x47, 0x04, 0x28, + 0x01, 0xd1, 0x1e, 0xa0, 0x70, 0x47, 0x26, 0xa0, + 0x70, 0x47, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x49, 0x64, 0x6c, + 0x65, 0x00, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x4d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x5f, 0x53, 0x6c, 0x61, 0x76, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x4d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x54, 0x6f, 0x53, 0x6c, 0x61, + 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x75, 0xed, 0x09, 0x00, 0x54, 0x03, 0x62, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x53, 0x6c, + 0x61, 0x76, 0x65, 0x54, 0x6f, 0x4d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x5f, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x00, 0x00, 0x28, 0x01, 0xd1, 0x29, + 0xa0, 0x70, 0x47, 0x01, 0x28, 0x01, 0xd1, 0x2c, + 0xa0, 0x70, 0x47, 0x02, 0x28, 0x01, 0xd1, 0x30, + 0xa0, 0x70, 0x47, 0x03, 0x28, 0x01, 0xd1, 0x35, + 0xa0, 0x70, 0x47, 0x04, 0x28, 0x01, 0xd1, 0x3c, + 0xa0, 0x70, 0x47, 0x05, 0x28, 0x01, 0xd1, 0x40, + 0xa0, 0x70, 0x47, 0x06, 0x28, 0x01, 0xd1, 0x45, + 0xa0, 0x70, 0x47, 0x07, 0x28, 0x01, 0xd1, 0x4c, + 0xa0, 0x70, 0x47, 0x08, 0x28, 0x01, 0xd1, 0x52, + 0xa0, 0x70, 0x47, 0x09, 0x28, 0x01, 0xd1, 0x5c, + 0xa0, 0x70, 0x47, 0x0a, 0x28, 0x01, 0xd1, 0x66, + 0xa0, 0x70, 0x47, 0x0b, 0x28, 0x01, 0xd1, 0x6a, + 0xa0, 0x70, 0x47, 0x0c, 0x28, 0x01, 0xd1, 0x70, + 0xa0, 0x70, 0x47, 0x0d, 0x28, 0x01, 0xd1, 0x75, + 0xa0, 0x70, 0x47, 0x0e, 0x28, 0x01, 0xd1, 0x7b, + 0xa0, 0x70, 0x47, 0x0f, 0x28, 0x01, 0xd1, 0x7f, + 0xa0, 0x70, 0x47, 0x10, 0x28, 0x01, 0xd1, 0x87, + 0xa0, 0x70, 0x47, 0x11, 0x28, 0x01, 0xd1, 0x8f, + 0xa0, 0x70, 0x47, 0x12, 0x28, 0x01, 0xd1, 0x94, + 0xa0, 0x70, 0x47, 0x13, 0x28, 0x01, 0xd1, 0x99, + 0xa0, 0x70, 0x47, 0x14, 0x28, 0x01, 0xd1, 0x9d, + 0xa0, 0x70, 0x47, 0xa1, 0xa0, 0x70, 0x47, 0x42, + 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, 0x4e, + 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x49, 0x44, 0x4c, + 0x45, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x4d, + 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0xed, 0x09, 0x00, + 0x55, 0x03, 0x5f, 0x53, 0x54, 0x5f, 0x42, 0x42, + 0x5f, 0x50, 0x41, 0x47, 0x45, 0x00, 0x00, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, + 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x42, 0x42, + 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, + 0x45, 0x44, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, + 0x54, 0x5f, 0x50, 0x52, 0x45, 0x5f, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x00, 0x00, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, + 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x00, 0x00, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, + 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x49, 0x4e, + 0x44, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, + 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, + 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, + 0x54, 0x5f, 0x41, 0x4e, 0x53, 0x57, 0x45, 0x52, + 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, + 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x49, 0x4e, + 0x49, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, + 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, + 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x49, 0x4e, + 0x49, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, + 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, + 0x5f, 0x52, 0x41, 0x4e, 0x44, 0x5f, 0x43, 0x4f, + 0x4c, 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x00, + 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, + 0xed, 0x09, 0x00, 0x56, 0x03, 0x4e, 0x4b, 0x5f, + 0x53, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x5f, + 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x41, 0x55, 0x5f, 0x52, 0x41, + 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x49, + 0x53, 0x49, 0x4f, 0x4e, 0x00, 0x42, 0x54, 0x5f, + 0x4c, 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, + 0x53, 0x54, 0x5f, 0x50, 0x41, 0x49, 0x52, 0x49, + 0x4e, 0x47, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, + 0x4c, 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, + 0x53, 0x54, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x45, + 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x00, 0x00, 0x00, 0x00, 0x42, 0x54, 0x5f, + 0x4c, 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, + 0x53, 0x54, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, + 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, + 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x53, + 0x45, 0x54, 0x55, 0x50, 0x5f, 0x43, 0x4f, 0x4d, + 0x50, 0x4c, 0x45, 0x54, 0x45, 0x00, 0x00, 0x00, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, + 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x43, + 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, + 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x43, + 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, + 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x4b, 0x45, 0x59, + 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, + 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, 0x43, + 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x5f, 0x4d, 0x41, 0x53, 0x54, 0x45, 0x52, 0x5f, + 0x4c, 0x49, 0x4e, 0xed, 0x09, 0x00, 0x57, 0x03, + 0x4b, 0x5f, 0x4b, 0x45, 0x59, 0x00, 0x42, 0x54, + 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, + 0x5f, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x00, 0x00, 0x42, 0x54, 0x5f, 0x4c, 0x4d, 0x5f, + 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x53, 0x54, 0x5f, + 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, + 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x42, 0x54, + 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, + 0x5f, 0x53, 0x54, 0x5f, 0x42, 0x42, 0x5f, 0x44, + 0x45, 0x54, 0x41, 0x43, 0x48, 0x00, 0x42, 0x54, + 0x5f, 0x4c, 0x4d, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, + 0x5f, 0x53, 0x54, 0x5f, 0x45, 0x4e, 0x44, 0x00, + 0x00, 0x00, 0x5f, 0x42, 0x54, 0x5f, 0x4c, 0x6d, + 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x00, 0x00, 0xb5, 0x03, 0x49, 0x06, 0x22, + 0xcb, 0xf7, 0xad, 0xf9, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x00, 0x30, 0x7c, 0x00, 0x00, 0xf0, 0xb5, + 0x00, 0x24, 0xc4, 0x60, 0x07, 0x1c, 0x00, 0x20, + 0x0d, 0x5c, 0x3e, 0x18, 0x01, 0x30, 0x08, 0x28, + 0x35, 0x74, 0xf9, 0xdb, 0xba, 0x61, 0x06, 0x2b, + 0x02, 0xd1, 0x01, 0x20, 0x38, 0x77, 0x00, 0xe0, + 0x3c, 0x77, 0x7c, 0x62, 0x3c, 0x62, 0x3c, 0x60, + 0x7c, 0x60, 0x0e, 0x48, 0x00, 0xf0, 0xef, 0xfb, + 0x0e, 0x48, 0xf8, 0x60, 0x0e, 0x48, 0x01, 0x68, + 0x00, 0x29, 0x06, 0xd0, 0x09, 0x68, 0x39, 0x60, + 0x4f, 0x60, 0x00, 0x68, 0x78, 0x60, 0x07, 0x60, + 0x02, 0xe0, 0x07, 0x60, 0x3f, 0x60, 0x7f, 0x60, + 0x08, 0x48, 0x01, 0x68, 0x01, 0x31, 0x01, 0x60, + 0x00, 0xf0, 0xd5, 0xfb, 0x20, 0x1c, 0xf0, 0xbc, + 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x58, 0x03, 0x74, 0x67, 0x03, 0x20, 0x41, + 0x4d, 0x45, 0x53, 0x6c, 0x67, 0x03, 0x20, 0x70, + 0x67, 0x03, 0x20, 0xf0, 0xb5, 0x24, 0x4e, 0x07, + 0x1c, 0x30, 0x1c, 0x00, 0xf0, 0xc6, 0xfb, 0x00, + 0x21, 0xf9, 0x60, 0x00, 0xf0, 0xbe, 0xfb, 0x20, + 0x48, 0x00, 0xf0, 0xbf, 0xfb, 0x39, 0x68, 0x1f, + 0x48, 0xb9, 0x42, 0x02, 0xd1, 0x00, 0x21, 0x01, + 0x60, 0x09, 0xe0, 0x7a, 0x68, 0x4a, 0x60, 0x06, + 0xcf, 0x08, 0x3f, 0x11, 0x60, 0x01, 0x68, 0x8f, + 0x42, 0x01, 0xd1, 0x79, 0x68, 0x01, 0x60, 0x18, + 0x48, 0x00, 0x25, 0x01, 0x68, 0x01, 0x39, 0x01, + 0x60, 0x7c, 0x6a, 0x00, 0x2c, 0x1d, 0xd0, 0x11, + 0x48, 0x00, 0xf0, 0xa3, 0xfb, 0x2f, 0x20, 0xc0, + 0x43, 0x60, 0x61, 0x20, 0x69, 0x66, 0x68, 0x06, + 0x21, 0xdd, 0xf7, 0xb5, 0xfb, 0x05, 0x43, 0x78, + 0x6a, 0xb0, 0x42, 0x01, 0xd1, 0x00, 0x24, 0x00, + 0xe0, 0x34, 0x1c, 0x09, 0x48, 0x00, 0xf0, 0xa1, + 0xfb, 0x07, 0x48, 0x00, 0xf0, 0x9a, 0xfb, 0x00, + 0x2c, 0xe5, 0xd1, 0x00, 0x2d, 0x01, 0xd0, 0x00, + 0xf0, 0x90, 0xfb, 0x00, 0xf0, 0x82, 0xfb, 0xf0, + 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x18, 0x47, 0x00, + 0x67, 0x03, 0x20, 0x74, 0x67, 0x03, 0x20, 0x6c, + 0x67, 0x03, 0x20, 0x70, 0x67, 0x03, 0x20, 0xf0, + 0xb5, 0x87, 0xb0, 0x04, 0x1c, 0x00, 0x25, 0x0f, + 0x1c, 0x20, 0x48, 0x00, 0xf0, 0x72, 0xfb, 0xa0, + 0x69, 0x00, 0x28, 0x02, 0xd0, 0x01, 0x38, 0xa0, + 0x61, 0x30, 0xe0, 0x00, 0x2f, 0x2c, 0xd0, 0x20, + 0x6a, 0x01, 0xad, 0x01, 0x30, 0x20, 0x62, 0x00, + 0x20, 0x02, 0x90, 0x01, 0x90, 0x18, 0x48, 0x04, + 0x94, 0x06, 0x68, 0x05, 0x96, 0x20, 0x7f, 0x00, + 0x28, 0x0d, 0xd0, 0x60, 0x6a, 0x00, 0x28, 0x06, + 0xd0, 0x00, 0x68, 0x01, 0x90, 0x45, 0x60, 0x60, + 0x6a, 0xed, 0x09, 0x00, 0x59, 0x03, 0x02, 0x90, + 0x05, 0x60, 0x0b, 0xe0, 0x65, 0x62, 0x01, 0x95, + 0x02, 0x95, 0x07, 0xe0, 0xb0, 0x7e, 0x03, 0xab, + 0x18, 0x70, 0xe0, 0x1d, 0x1d, 0x30, 0x29, 0x1c, + 0xf2, 0xf7, 0x6a, 0xfb, 0x2b, 0x1c, 0x06, 0x21, + 0x30, 0x1c, 0x00, 0x97, 0x08, 0x4a, 0xdd, 0xf7, + 0xf9, 0xfb, 0x06, 0x9d, 0x01, 0xe0, 0x32, 0x25, + 0xed, 0x43, 0x00, 0xf0, 0x35, 0xfb, 0x28, 0x1c, + 0x07, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, + 0x00, 0x67, 0x03, 0x20, 0xe8, 0x66, 0x03, 0x20, + 0xe9, 0x52, 0x03, 0x20, 0x90, 0xb5, 0x00, 0x27, + 0x04, 0x1c, 0x16, 0x48, 0x00, 0xf0, 0x28, 0xfb, + 0x20, 0x6a, 0x00, 0x28, 0x1c, 0xd0, 0x01, 0x38, + 0x20, 0x62, 0x60, 0x6a, 0x00, 0x21, 0x02, 0x68, + 0x82, 0x42, 0x01, 0xd1, 0x61, 0x62, 0x09, 0xe0, + 0x43, 0x68, 0x53, 0x60, 0x0c, 0xc8, 0x08, 0x38, + 0x1a, 0x60, 0x62, 0x6a, 0x82, 0x42, 0x01, 0xd1, + 0x42, 0x68, 0x62, 0x62, 0x41, 0x61, 0x00, 0x69, + 0x06, 0x21, 0xdd, 0xf7, 0x27, 0xfb, 0x00, 0x28, + 0x05, 0xd0, 0x00, 0xf0, 0x11, 0xfb, 0x02, 0xe0, + 0xa0, 0x69, 0x01, 0x30, 0xa0, 0x61, 0x00, 0xf0, + 0xff, 0xfa, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, + 0x18, 0x47, 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, + 0x31, 0x21, 0xc9, 0x43, 0x41, 0x61, 0xc1, 0x68, + 0x0a, 0x6a, 0x01, 0x3a, 0x0a, 0x62, 0x01, 0x68, + 0x81, 0x42, 0x03, 0xd1, 0xc0, 0x68, 0x00, 0x21, + 0x41, 0x62, 0x70, 0x47, 0x42, 0x68, 0x4a, 0x60, + 0x06, 0xc8, 0x08, 0x38, 0x11, 0x60, 0xc1, 0x68, + 0x4a, 0x6a, 0x82, 0x42, 0xf5, 0xd1, 0x40, 0x68, + 0x48, 0x62, 0x70, 0x47, 0xf0, 0xb5, 0x07, 0x1c, + 0x1c, 0x48, 0x00, 0xf0, 0xdd, 0xfa, 0x00, 0x24, + 0x29, 0x26, 0x78, 0x6c, 0xf6, 0x43, 0x00, 0x28, + 0x0b, 0xd0, 0x06, 0x62, 0xed, 0x09, 0x00, 0x5a, + 0x03, 0x45, 0x68, 0x00, 0x69, 0x05, 0x21, 0xdd, + 0xf7, 0xeb, 0xfa, 0x04, 0x43, 0x78, 0x6c, 0xa8, + 0x42, 0x01, 0xd0, 0x28, 0x1c, 0xf3, 0xd1, 0x38, + 0x6c, 0x00, 0x28, 0x0b, 0xd0, 0x06, 0x62, 0x45, + 0x68, 0x00, 0x69, 0x05, 0x21, 0xdd, 0xf7, 0xdc, + 0xfa, 0x04, 0x43, 0x38, 0x6c, 0xa8, 0x42, 0x01, + 0xd0, 0x28, 0x1c, 0xf3, 0xd1, 0xf8, 0x6a, 0x39, + 0x6b, 0x00, 0x25, 0x09, 0x1a, 0xb9, 0x62, 0x3d, + 0x62, 0x78, 0x63, 0xb8, 0x63, 0xfd, 0x63, 0x3d, + 0x64, 0x7d, 0x64, 0x00, 0x2c, 0x01, 0xd0, 0x00, + 0xf0, 0xb5, 0xfa, 0x00, 0xf0, 0xa7, 0xfa, 0x28, + 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, + 0x00, 0x00, 0x67, 0x03, 0x20, 0xff, 0xb5, 0x8c, + 0xb0, 0x04, 0x1c, 0x00, 0x20, 0x01, 0x90, 0x00, + 0x25, 0x0e, 0x1c, 0x17, 0x1c, 0x6c, 0x48, 0x00, + 0xf0, 0x99, 0xfa, 0x21, 0x7e, 0x00, 0x29, 0x01, + 0xd0, 0x00, 0x20, 0x19, 0xe0, 0xf8, 0x1c, 0x80, + 0x08, 0x80, 0x00, 0x62, 0x6c, 0xc5, 0x1b, 0x28, + 0x1d, 0x00, 0x2a, 0x0b, 0x92, 0x10, 0xd0, 0x22, + 0x6a, 0x00, 0x2a, 0x0d, 0xd0, 0x63, 0x4a, 0x12, + 0x68, 0x63, 0x7e, 0x00, 0x2b, 0x07, 0xd1, 0x0f, + 0x9b, 0x00, 0x2b, 0x04, 0xd0, 0x0b, 0x9b, 0x1b, + 0x7a, 0x92, 0x7e, 0x93, 0x42, 0x00, 0xdc, 0xa0, + 0x6a, 0xa2, 0x6a, 0x38, 0x18, 0x82, 0x42, 0x2c, + 0xd2, 0x0f, 0x9b, 0x00, 0x2b, 0x25, 0xd0, 0xe0, + 0x6b, 0x58, 0x4a, 0x01, 0x30, 0xe0, 0x63, 0x00, + 0x20, 0x03, 0x90, 0x02, 0x90, 0x05, 0x94, 0x07, + 0x96, 0x08, 0x97, 0x10, 0x68, 0x02, 0xab, 0x06, + 0x90, 0x21, 0x6c, 0x00, 0x29, 0x06, 0xd0, 0x09, + 0x68, 0x02, 0x91, 0x4b, 0x60, 0x21, 0x6c, 0x03, + 0x91, 0x0b, 0x60, 0x02, 0xe0, 0x23, 0x64, 0x02, + 0x93, 0x03, 0x93, 0x21, 0x6c, 0x09, 0x68, 0xed, + 0x09, 0x00, 0x5b, 0x03, 0x21, 0x64, 0x0f, 0x9a, + 0x05, 0x21, 0x00, 0x92, 0x4a, 0x4a, 0xdd, 0xf7, + 0x0a, 0xfb, 0x0a, 0x98, 0x01, 0x90, 0x82, 0xe0, + 0x28, 0x20, 0xc0, 0x43, 0x01, 0x90, 0x7e, 0xe0, + 0x62, 0x6c, 0x00, 0x2a, 0x2c, 0xd0, 0x22, 0x6a, + 0x00, 0x2a, 0x29, 0xd1, 0xe0, 0x6b, 0x01, 0x38, + 0xe0, 0x63, 0x60, 0x6c, 0x01, 0x68, 0x81, 0x42, + 0x02, 0xd1, 0x00, 0x21, 0x61, 0x64, 0x09, 0xe0, + 0x42, 0x68, 0x4a, 0x60, 0x06, 0xc8, 0x08, 0x38, + 0x11, 0x60, 0x61, 0x6c, 0x81, 0x42, 0x01, 0xd1, + 0x41, 0x68, 0x61, 0x64, 0x00, 0x23, 0x42, 0x69, + 0x03, 0x62, 0x31, 0x1c, 0x3b, 0x1c, 0x0c, 0x78, + 0x14, 0x70, 0x01, 0x32, 0x01, 0x3b, 0x01, 0xd0, + 0x01, 0x31, 0xf8, 0xe7, 0xc7, 0x61, 0x00, 0x69, + 0x05, 0x21, 0xdd, 0xf7, 0x38, 0xfa, 0x00, 0x28, + 0x51, 0xd0, 0x00, 0xf0, 0x22, 0xfa, 0x4e, 0xe0, + 0x32, 0x1c, 0x00, 0x29, 0x63, 0x6b, 0x0f, 0xd0, + 0xe0, 0x6a, 0x98, 0x42, 0x02, 0xd1, 0x20, 0x6b, + 0xc0, 0x1b, 0x00, 0xe0, 0xd8, 0x1b, 0x60, 0x63, + 0x39, 0x1c, 0x13, 0x78, 0x03, 0x70, 0x01, 0x30, + 0x01, 0x39, 0x36, 0xd0, 0x01, 0x32, 0xf8, 0xe7, + 0xe1, 0x6a, 0x59, 0x1a, 0x88, 0x42, 0x03, 0xd9, + 0x23, 0x6b, 0x40, 0x1a, 0x18, 0x1a, 0x00, 0xe0, + 0x18, 0x1a, 0x60, 0x63, 0x80, 0xc0, 0x21, 0x6b, + 0x81, 0x42, 0x00, 0xd8, 0xe0, 0x6a, 0xa1, 0x6a, + 0x7b, 0x19, 0x04, 0x39, 0xa1, 0x62, 0x21, 0x6b, + 0x09, 0x1a, 0x8b, 0x42, 0x07, 0xd8, 0x39, 0x1c, + 0x13, 0x78, 0x03, 0x70, 0x01, 0x30, 0x01, 0x39, + 0x14, 0xd0, 0x01, 0x32, 0xf8, 0xe7, 0x0b, 0x1c, + 0x16, 0x78, 0x01, 0x32, 0x01, 0x3b, 0x06, 0x70, + 0x01, 0xd0, 0x01, 0x30, 0xf8, 0xe7, 0xe0, 0x6a, + 0x8f, 0x42, 0x07, 0xd9, 0x79, 0x1a, 0x13, 0x78, + 0x03, 0x70, 0xed, 0x09, 0x00, 0x5c, 0x03, 0x01, + 0x30, 0x01, 0x39, 0x01, 0xd0, 0x01, 0x32, 0xf8, + 0xe7, 0xa0, 0x6a, 0x40, 0x1b, 0xa0, 0x62, 0xa0, + 0x6a, 0xc0, 0x1b, 0xa0, 0x62, 0x20, 0x6a, 0x01, + 0x30, 0x20, 0x62, 0x00, 0xf0, 0xc4, 0xf9, 0x01, + 0x98, 0x10, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, + 0x47, 0x00, 0x00, 0x00, 0x67, 0x03, 0x20, 0xe8, + 0x66, 0x03, 0x20, 0xe9, 0x62, 0x02, 0x20, 0xff, + 0xb5, 0x8b, 0xb0, 0x04, 0x1c, 0x00, 0x20, 0x01, + 0x90, 0x00, 0x25, 0x17, 0x1c, 0x71, 0x48, 0x00, + 0xf0, 0xb2, 0xf9, 0x21, 0x7e, 0x00, 0x29, 0x01, + 0xd0, 0x00, 0x20, 0x17, 0xe0, 0xf8, 0x1c, 0x80, + 0x08, 0x80, 0x00, 0xc5, 0x1b, 0x63, 0x6c, 0x28, + 0x1d, 0x00, 0x2b, 0x0f, 0xd0, 0x22, 0x6a, 0x00, + 0x2a, 0x0c, 0xd0, 0x68, 0x4a, 0x12, 0x68, 0x66, + 0x7e, 0x00, 0x2e, 0x06, 0xd1, 0x0e, 0x9e, 0x00, + 0x2e, 0x03, 0xd0, 0x1b, 0x7a, 0x92, 0x7e, 0x93, + 0x42, 0x00, 0xdc, 0xa0, 0x6a, 0x3b, 0x18, 0xa2, + 0x6a, 0x00, 0x20, 0x9a, 0x42, 0x37, 0xd2, 0x0e, + 0x9b, 0x00, 0x2b, 0x30, 0xd0, 0xe1, 0x6b, 0x5d, + 0x4a, 0x01, 0x31, 0xe1, 0x63, 0x0c, 0x99, 0x05, + 0x94, 0x03, 0x90, 0x02, 0x90, 0x08, 0x97, 0x07, + 0x91, 0x17, 0x68, 0x02, 0xad, 0x06, 0x97, 0x60, + 0x7e, 0x00, 0x28, 0x0d, 0xd0, 0x60, 0x6c, 0x00, + 0x28, 0x06, 0xd0, 0x00, 0x68, 0x02, 0x90, 0x45, + 0x60, 0x60, 0x6c, 0x03, 0x90, 0x05, 0x60, 0x0b, + 0xe0, 0x65, 0x64, 0x02, 0x95, 0x03, 0x95, 0x07, + 0xe0, 0xb8, 0x7e, 0x04, 0xab, 0x18, 0x70, 0xe0, + 0x1d, 0x3d, 0x30, 0x29, 0x1c, 0xf2, 0xf7, 0x8b, + 0xf9, 0x0e, 0x9a, 0x2b, 0x1c, 0x05, 0x21, 0x00, + 0x92, 0x4a, 0x4a, 0x38, 0x1c, 0xdd, 0xf7, 0x19, + 0xfa, 0x0a, 0x98, 0x01, 0x90, 0x81, 0xe0, 0x28, + 0x20, 0xc0, 0x43, 0x01, 0x90, 0xed, 0x09, 0x00, + 0x5d, 0x03, 0x7d, 0xe0, 0x62, 0x6c, 0x00, 0x2a, + 0x31, 0xd0, 0x22, 0x6a, 0x00, 0x2a, 0x2e, 0xd1, + 0x00, 0x25, 0xe0, 0x6b, 0x01, 0x38, 0xe0, 0x63, + 0x60, 0x6c, 0x01, 0x68, 0x81, 0x42, 0x02, 0xd1, + 0x00, 0x22, 0x62, 0x64, 0x09, 0xe0, 0x42, 0x68, + 0x4a, 0x60, 0x06, 0xc8, 0x08, 0x38, 0x11, 0x60, + 0x61, 0x6c, 0x81, 0x42, 0x01, 0xd1, 0x41, 0x68, + 0x61, 0x64, 0x0c, 0x99, 0x43, 0x69, 0x00, 0x22, + 0x02, 0x62, 0x3a, 0x1c, 0x0e, 0x78, 0x1e, 0x70, + 0x01, 0x33, 0x01, 0x3a, 0x01, 0xd0, 0x01, 0x31, + 0xf8, 0xe7, 0xc7, 0x61, 0x00, 0x69, 0x05, 0x21, + 0xdd, 0xf7, 0x46, 0xf9, 0x05, 0x43, 0x60, 0x6c, + 0x00, 0x28, 0xd6, 0xd1, 0x00, 0x2d, 0x4b, 0xd0, + 0x00, 0xf0, 0x2c, 0xf9, 0x48, 0xe0, 0x0c, 0x9a, + 0xa0, 0x6b, 0x00, 0x29, 0x07, 0xd0, 0x39, 0x1c, + 0x13, 0x78, 0x03, 0x70, 0x01, 0x30, 0x01, 0x39, + 0x26, 0xd0, 0x01, 0x32, 0xf8, 0xe7, 0x80, 0xc0, + 0x21, 0x6b, 0x81, 0x42, 0x00, 0xd8, 0xe0, 0x6a, + 0xa1, 0x6a, 0x04, 0x39, 0xa1, 0x62, 0x21, 0x6b, + 0x09, 0x1a, 0xb9, 0x42, 0x07, 0xd3, 0x39, 0x1c, + 0x13, 0x78, 0x03, 0x70, 0x01, 0x30, 0x01, 0x39, + 0x12, 0xd0, 0x01, 0x32, 0xf8, 0xe7, 0x0b, 0x1c, + 0x16, 0x78, 0x01, 0x32, 0x01, 0x3b, 0x06, 0x70, + 0x01, 0xd0, 0x01, 0x30, 0xf8, 0xe7, 0xe0, 0x6a, + 0x79, 0x1a, 0x13, 0x78, 0x03, 0x70, 0x01, 0x30, + 0x01, 0x39, 0x01, 0xd0, 0x01, 0x32, 0xf8, 0xe7, + 0x21, 0x6b, 0x81, 0x42, 0x00, 0xd8, 0xe0, 0x6a, + 0x00, 0x2d, 0x0a, 0xd0, 0x09, 0x1a, 0xa9, 0x42, + 0x03, 0xd8, 0xe0, 0x6a, 0x69, 0x1a, 0x40, 0x18, + 0x00, 0xe0, 0x40, 0x19, 0xa1, 0x6a, 0x49, 0x1b, + 0xa1, 0x62, 0xa0, 0x63, 0xa0, 0x6a, 0xc0, 0x1b, + 0xa0, 0x62, 0x20, 0x6a, 0x01, 0x30, 0x20, 0x62, + 0xed, 0x09, 0x00, 0x5e, 0x03, 0x00, 0xf0, 0xd4, + 0xf8, 0x01, 0x98, 0x0f, 0xb0, 0xf0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x67, 0x03, + 0x20, 0xe8, 0x66, 0x03, 0x20, 0xe9, 0x62, 0x02, + 0x20, 0xb0, 0xb5, 0x00, 0x27, 0x07, 0x24, 0x01, + 0x25, 0x01, 0x21, 0x02, 0x20, 0xef, 0xf7, 0x42, + 0xfd, 0xef, 0xf7, 0x30, 0xfd, 0x00, 0x28, 0x02, + 0xd0, 0x28, 0x1c, 0xa0, 0x40, 0x00, 0xe0, 0x00, + 0x20, 0x38, 0x43, 0x07, 0x06, 0x3f, 0x0e, 0x00, + 0x21, 0x02, 0x20, 0xef, 0xf7, 0x33, 0xfd, 0x01, + 0x3c, 0xea, 0xd5, 0x01, 0x21, 0x01, 0x20, 0xef, + 0xf7, 0x2d, 0xfd, 0x38, 0x1c, 0xb0, 0xbc, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb5, 0x00, + 0x21, 0x01, 0x20, 0xef, 0xf7, 0x23, 0xfd, 0x01, + 0x21, 0x02, 0x20, 0xef, 0xf7, 0x1f, 0xfd, 0x00, + 0x21, 0x02, 0x20, 0xef, 0xf7, 0x1b, 0xfd, 0x01, + 0x21, 0x01, 0x20, 0xef, 0xf7, 0x17, 0xfd, 0x08, + 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xc0, 0x9f, + 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x69, 0x18, 0x01, + 0x20, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, + 0xe1, 0x81, 0x17, 0x01, 0x20, 0x00, 0xc0, 0x9f, + 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x5d, 0x1b, 0x01, + 0x20, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, + 0xe1, 0x95, 0x15, 0x01, 0x20, 0x00, 0xc0, 0x9f, + 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x0d, 0x16, 0x01, + 0x20, 0x78, 0x47, 0x00, 0x00, 0x53, 0x2a, 0xff, + 0xea, 0x78, 0x47, 0x00, 0x00, 0xd5, 0xbf, 0xff, + 0xea, 0x78, 0x47, 0x00, 0x00, 0xc7, 0x70, 0xff, + 0xea, 0x78, 0x47, 0x00, 0x00, 0xbb, 0x70, 0xff, + 0xea, 0x78, 0x47, 0x00, 0x00, 0xab, 0x2b, 0xff, + 0xea, 0x78, 0x47, 0x00, 0x00, 0x87, 0x70, 0xff, + 0xea, 0x78, 0x47, 0x00, 0x00, 0xad, 0x70, 0xff, + 0xea, 0x78, 0x47, 0xed, 0x09, 0x00, 0x5f, 0x03, + 0x00, 0x00, 0xdb, 0xbf, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x87, 0xbf, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x91, 0x70, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x99, 0x70, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0xf8, 0x5f, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x70, 0x60, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0xed, 0x72, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x7c, 0x70, 0xff, 0xea, 0x00, 0xc0, + 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0xdd, 0xf5, + 0x00, 0x20, 0x78, 0x47, 0x00, 0x00, 0xf6, 0x75, + 0xff, 0xea, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, + 0x2f, 0xe1, 0x09, 0x31, 0x01, 0x20, 0x00, 0xc0, + 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x85, 0x32, + 0x01, 0x20, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, + 0x2f, 0xe1, 0x25, 0x2d, 0x01, 0x20, 0x00, 0xc0, + 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x71, 0x4f, + 0x01, 0x20, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, + 0x2f, 0xe1, 0x99, 0x4d, 0x01, 0x20, 0x00, 0xc0, + 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0xe9, 0x4d, + 0x01, 0x20, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, + 0x2f, 0xe1, 0x41, 0x2d, 0x01, 0x20, 0x78, 0x47, + 0x00, 0x00, 0x54, 0x71, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0xe6, 0x71, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0xc1, 0x71, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x9f, 0x71, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x7e, 0x71, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0xf6, 0x71, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x1f, 0x72, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x22, 0x72, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0xd1, 0x70, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0xf7, 0x70, 0xff, 0xea, 0x78, 0x47, + 0x00, 0x00, 0x10, 0x71, 0xff, 0xea, 0xed, 0x09, + 0x00, 0x60, 0x03, 0x78, 0x47, 0x00, 0x00, 0xad, + 0x75, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0xc0, + 0x75, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0xc2, + 0x75, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0xad, + 0x75, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0xa2, + 0x75, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x25, + 0x70, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x0f, + 0x70, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0xa1, + 0x70, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0xe8, + 0x6f, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x5f, + 0x6f, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x63, + 0x6f, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x6e, + 0x6f, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x3a, + 0x70, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x62, + 0xbf, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x7a, + 0xbf, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x50, + 0xbf, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x37, + 0xbf, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x11, + 0xbf, 0xff, 0xea, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, + 0xff, 0x2f, 0xe1, 0x65, 0x51, 0x01, 0x20, 0x00, + 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x69, + 0x51, 0x01, 0x20, 0x00, 0xc0, 0x9f, 0xe5, 0x1c, + 0xff, 0x2f, 0xe1, 0xcd, 0x51, 0x01, 0x20, 0x00, + 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0xdf, + 0x4e, 0x02, 0x20, 0x0c, 0xd0, 0x4d, 0xe2, 0xff, + 0x1f, 0x2d, 0xe9, 0x00, 0x10, 0x4f, 0xe1, 0x02, + 0x00, 0x2d, 0xe9, 0x20, 0x10, 0xc1, 0xe3, 0x01, + 0xf0, 0x21, 0xe1, 0x0d, 0x20, 0xa0, 0xe1, 0x0e, + 0x30, 0xa0, 0xe1, 0x1f, 0x10, 0xc1, 0xe3, 0x1b, + 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0x40, + 0xe0, 0x8d, 0xe5, 0x3c, 0x30, 0x8d, 0xe5, 0x38, + 0x20, 0x8d, 0xe5, 0x00, 0x00, 0x9d, 0xe5, 0x20, + 0x00, 0xed, 0x09, 0x00, 0x61, 0x03, 0x10, 0xe3, + 0x02, 0x00, 0x00, 0x0a, 0xb2, 0x10, 0x5e, 0xe1, + 0x3e, 0x1b, 0xc1, 0xe3, 0x02, 0x00, 0x00, 0xea, + 0x04, 0x10, 0x1e, 0xe5, 0xff, 0x14, 0xc1, 0xe3, + 0x21, 0x14, 0xa0, 0xe1, 0x0d, 0x20, 0xa0, 0xe1, + 0xda, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x50, 0xe3, + 0x02, 0x00, 0xbd, 0xe8, 0x01, 0xf0, 0x6f, 0xe1, + 0x03, 0x00, 0x00, 0x0a, 0xff, 0x1f, 0xbd, 0xe8, + 0x08, 0xd0, 0x8d, 0xe2, 0x00, 0x40, 0xbd, 0xe8, + 0x0e, 0xf0, 0xb0, 0xe1, 0x20, 0x00, 0x11, 0xe3, + 0xff, 0x1f, 0xbd, 0xe8, 0x08, 0xd0, 0x8d, 0xe2, + 0x00, 0x40, 0xbd, 0xe8, 0x02, 0xe0, 0x4e, 0x02, + 0x04, 0xe0, 0x4e, 0x12, 0x0e, 0xf0, 0xb0, 0xe1, + 0x00, 0x40, 0x2d, 0xe9, 0xff, 0x7f, 0x0d, 0xe9, + 0x3c, 0xd0, 0x4d, 0xe2, 0x00, 0x10, 0x4f, 0xe1, + 0x02, 0x00, 0x2d, 0xe9, 0xb2, 0x10, 0x5e, 0xe1, + 0x0f, 0x10, 0x01, 0xe2, 0x0d, 0x20, 0xa0, 0xe1, + 0xc2, 0xff, 0xff, 0xeb, 0x00, 0x00, 0x10, 0xe3, + 0x02, 0x00, 0xbd, 0xe8, 0x01, 0xf0, 0x6f, 0xe1, + 0xff, 0x1f, 0xbd, 0xe8, 0x08, 0xd0, 0x8d, 0xe2, + 0x00, 0x40, 0xbd, 0xe8, 0x04, 0xe0, 0x4e, 0x12, + 0x0e, 0xf0, 0xb0, 0xe1, 0x0c, 0xd0, 0x4d, 0xe2, + 0xff, 0x1f, 0x2d, 0xe9, 0x00, 0x10, 0x4f, 0xe1, + 0x02, 0x00, 0x2d, 0xe9, 0x20, 0x10, 0xc1, 0xe3, + 0x01, 0xf0, 0x21, 0xe1, 0x0d, 0x20, 0xa0, 0xe1, + 0x0e, 0x30, 0xa0, 0xe1, 0x1f, 0x10, 0xc1, 0xe3, + 0x17, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, + 0x40, 0xe0, 0x8d, 0xe5, 0x3c, 0x30, 0x8d, 0xe5, + 0x38, 0x20, 0x8d, 0xe5, 0x00, 0x00, 0x9d, 0xe5, + 0x20, 0x00, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, + 0xb8, 0x00, 0x5e, 0xe1, 0x04, 0x10, 0x4e, 0xe2, + 0x01, 0x00, 0x00, 0xea, 0x04, 0x00, 0x1e, 0xe5, + 0x04, 0x10, 0x4e, 0xe2, 0xed, 0x09, 0x00, 0x62, + 0x03, 0x10, 0x2f, 0x18, 0xee, 0x0d, 0x30, 0xa0, + 0xe1, 0xa4, 0xff, 0xff, 0xeb, 0x02, 0x00, 0xbd, + 0xe8, 0x01, 0xf0, 0x6f, 0xe1, 0xff, 0x1f, 0xbd, + 0xe8, 0x08, 0xd0, 0x8d, 0xe2, 0x00, 0x40, 0xbd, + 0xe8, 0x04, 0xf0, 0x5e, 0xe2, 0x0c, 0xd0, 0x4d, + 0xe2, 0xff, 0x1f, 0x2d, 0xe9, 0x00, 0x10, 0x4f, + 0xe1, 0x02, 0x00, 0x2d, 0xe9, 0x20, 0x10, 0xc1, + 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0x0d, 0x20, 0xa0, + 0xe1, 0x0e, 0x30, 0xa0, 0xe1, 0x1f, 0x10, 0xc1, + 0xe3, 0x17, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, + 0xe1, 0x40, 0xe0, 0x8d, 0xe5, 0x3c, 0x30, 0x8d, + 0xe5, 0x38, 0x20, 0x8d, 0xe5, 0x00, 0x00, 0x9d, + 0xe5, 0x20, 0x00, 0x10, 0xe3, 0x02, 0x00, 0x00, + 0x0a, 0xb8, 0x00, 0x5e, 0xe1, 0x04, 0x10, 0x4e, + 0xe2, 0x01, 0x00, 0x00, 0xea, 0x08, 0x00, 0x1e, + 0xe5, 0x04, 0x10, 0x4e, 0xe2, 0x10, 0x2f, 0x18, + 0xee, 0x0d, 0x30, 0xa0, 0xe1, 0x88, 0xff, 0xff, + 0xeb, 0x00, 0x00, 0x10, 0xe3, 0x02, 0x00, 0xbd, + 0xe8, 0x01, 0xf0, 0x6f, 0xe1, 0xff, 0x1f, 0xbd, + 0xe8, 0x08, 0xd0, 0x8d, 0xe2, 0x00, 0x40, 0xbd, + 0xe8, 0x04, 0xf0, 0x5e, 0x12, 0x08, 0xf0, 0x5e, + 0x02, 0x64, 0x00, 0xa0, 0xe3, 0x81, 0xff, 0xff, + 0xeb, 0xfc, 0xff, 0xff, 0xea, 0x01, 0x00, 0x00, + 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, + 0x39, 0x39, 0x33, 0x2d, 0x32, 0x30, 0x30, 0x31, + 0x20, 0x41, 0x54, 0x49, 0x20, 0x2d, 0x20, 0x4e, + 0x75, 0x63, 0x6c, 0x65, 0x75, 0x73, 0x20, 0x50, + 0x4c, 0x55, 0x53, 0x20, 0x2d, 0x20, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x52, + 0x4d, 0x20, 0x36, 0x2f, 0x37, 0x2f, 0x39, 0x20, + 0x31, 0x2e, 0x31, 0x33, 0x2e, 0x32, 0x31, 0xed, + 0x09, 0x00, 0x63, 0x03, 0x00, 0x00, 0x47, 0x2c, + 0x4d, 0x2c, 0x44, 0x2c, 0x47, 0x42, 0x2c, 0x47, + 0x4c, 0x2c, 0x41, 0x47, 0x2c, 0x4b, 0x4c, 0x2c, + 0x43, 0x52, 0x2c, 0x48, 0x52, 0x2c, 0x4e, 0x48, + 0x2c, 0x44, 0x4c, 0x2c, 0x42, 0x48, 0x2c, 0x4c, + 0x50, 0x2c, 0x41, 0x50, 0x2c, 0x48, 0x41, 0x2c, + 0x4d, 0x45, 0x2c, 0x4b, 0x43, 0x2c, 0x4b, 0x48, + 0x2c, 0x47, 0x46, 0x2c, 0x52, 0x47, 0x2c, 0x48, + 0x53, 0x2c, 0x44, 0x53, 0x2c, 0x4b, 0x59, 0x2c, + 0x42, 0x43, 0x2c, 0x4c, 0x43, 0x2c, 0x54, 0x44, + 0x00, 0x00, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x20, 0x55, 0x73, 0x65, 0x20, 0x4f, 0x6e, + 0x6c, 0x79, 0x20, 0x2d, 0x20, 0x53, 0x65, 0x72, + 0x69, 0x61, 0x6c, 0x20, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x35, 0x35, + 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x64, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x24, 0x54, 0x79, + 0x70, 0x65, 0x3a, 0x20, 0x42, 0x54, 0x5f, 0x43, + 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x20, 0x24, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x30, 0x33, 0x2e, 0x31, 0x37, 0x2e, 0x34, 0x36, + 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, + 0x41, 0x70, 0x72, 0x20, 0x32, 0x33, 0x20, 0x32, + 0x30, 0x30, 0x33, 0x20, 0x24, 0x54, 0x69, 0x6d, + 0x65, 0x3a, 0x20, 0x31, 0x36, 0x3a, 0x30, 0x35, + 0x3a, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x41, 0x42, 0x43, 0x44, 0xed, 0x09, 0x00, + 0x65, 0x03, 0x45, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xdf, + 0xe5, 0x0a, 0x02, 0x20, 0x05, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x40, 0x23, 0x0c, 0x02, 0x20, + 0x06, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44, + 0x3d, 0x12, 0x02, 0x20, 0x02, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x18, 0x01, 0x0b, 0x02, 0x20, + 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x1c, + 0x65, 0x0b, 0x02, 0x20, 0x12, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0xe0, 0xbd, 0x0d, 0x02, 0x20, + 0x13, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xe8, + 0xed, 0x0d, 0x02, 0x20, 0x14, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0xf0, 0x09, 0x0e, 0x02, 0x20, + 0x15, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, + 0x09, 0x0e, 0x02, 0x20, 0x07, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x48, 0x6d, 0x0e, 0x02, 0x20, + 0x08, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x50, + 0xb5, 0x0e, 0x02, 0x20, 0x09, 0x00, 0x00, 0x00, + 0x00, 0xf2, 0x00, 0x52, 0xb5, 0x0e, 0x02, 0x20, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, 0xb0, + 0xc9, 0x0f, 0x02, 0x20, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0xf4, 0x00, 0xb4, 0xed, 0x0f, 0x02, 0x20, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x40, + 0x29, 0x11, 0x02, 0x20, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x00, 0x90, 0xe1, 0x10, 0x02, 0x20, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xa0, + 0x6d, 0x0f, 0x02, 0x20, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x00, 0xc0, 0x45, 0x10, 0x02, 0x20, + 0x10, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xd0, + 0xa5, 0x10, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x00, 0x00, 0xc1, 0x11, 0x02, 0x20, + 0x04, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x20, + 0xed, 0x09, 0x00, 0x66, 0x03, 0xb5, 0x0b, 0x02, + 0x20, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, + 0x60, 0x6d, 0x11, 0x02, 0x20, 0x17, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x10, 0x00, 0x20, + 0x01, 0xc5, 0x28, 0x02, 0x20, 0x04, 0x00, 0x00, + 0x00, 0xe8, 0x12, 0x02, 0x20, 0xf0, 0x00, 0xc0, + 0x0f, 0x90, 0x00, 0x00, 0x00, 0x21, 0x23, 0x02, + 0x20, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x00, 0x80, 0x0f, 0x90, 0x00, 0x00, + 0x00, 0xe9, 0x23, 0x02, 0x20, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, + 0x0f, 0x90, 0x00, 0x00, 0x01, 0x4d, 0x28, 0x02, + 0x20, 0x06, 0x00, 0x00, 0x00, 0xec, 0x12, 0x02, + 0x20, 0x00, 0x00, 0xb0, 0x0f, 0x00, 0x00, 0x00, + 0x01, 0xed, 0x1c, 0x02, 0x20, 0x08, 0x00, 0x00, + 0x00, 0xf0, 0x12, 0x02, 0x20, 0x10, 0x00, 0xb0, + 0x0f, 0x00, 0x00, 0x20, 0x01, 0x19, 0x1c, 0x02, + 0x20, 0x15, 0x00, 0x00, 0x00, 0xf4, 0x12, 0x02, + 0x20, 0x10, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x00, + 0x06, 0x21, 0x2c, 0x02, 0x20, 0x0c, 0x00, 0x00, + 0x00, 0xfc, 0x12, 0x02, 0x20, 0x90, 0x00, 0x40, + 0x0e, 0x90, 0x00, 0x40, 0x00, 0xed, 0x24, 0x02, + 0x20, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, + 0x20, 0x90, 0x00, 0x40, 0x0e, 0x90, 0x00, 0x00, + 0x00, 0xed, 0x24, 0x02, 0x20, 0x07, 0x00, 0x00, + 0x00, 0x04, 0x13, 0x02, 0x20, 0x00, 0x00, 0xb0, + 0x0f, 0x00, 0x00, 0x20, 0x03, 0x7d, 0x1c, 0x02, + 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x02, 0xfd, 0x1a, 0x02, 0x20, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x67, 0x03, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x18, 0x02, 0x20, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, + 0x00, 0x0e, 0x10, 0x00, 0x00, 0x00, 0xb5, 0x19, + 0x02, 0x20, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x04, 0x3d, 0x1d, 0x02, 0x20, 0x0b, 0x00, + 0x00, 0x00, 0x08, 0x13, 0x02, 0x20, 0x10, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x65, 0x1f, + 0x02, 0x20, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x08, 0xf1, 0x2a, 0x02, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x59, 0x2c, + 0x02, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f, 0x10, 0x00, + 0x00, 0x0e, 0xd1, 0x2c, 0x02, 0x20, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x71, 0x17, + 0x02, 0x20, 0x13, 0x00, 0x00, 0x00, 0x0c, 0x13, + 0x02, 0x20, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x0a, 0xb5, 0x17, 0x02, 0x20, 0x14, 0x00, + 0x00, 0x00, 0x10, 0x13, 0x02, 0x20, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xf5, 0x2b, + 0x02, 0x20, 0x16, 0x00, 0x00, 0x00, 0x14, 0x13, + 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x17, 0x02, 0x20, 0x09, 0x04, + 0x00, 0x00, 0x41, 0x00, 0x56, 0x00, 0x4d, 0x00, + 0x20, 0x00, 0x42, 0x00, 0x65, 0x00, 0x72, 0x00, + 0x6c, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, + 0x6f, 0x74, 0x68, 0x20, 0x44, 0x65, 0xed, 0x09, + 0x00, 0x68, 0x03, 0x76, 0x69, 0x63, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x00, 0x41, 0x00, 0x50, + 0x00, 0x49, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, + 0x00, 0x6e, 0x00, 0x66, 0x00, 0x69, 0x00, 0x67, + 0x00, 0x75, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, + 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x00, 0x41, 0x00, 0x50, + 0x00, 0x49, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, + 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, + 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x48, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x84, 0x84, 0x84, 0x84, + 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, + 0x10, 0xed, 0x09, 0x00, 0x69, 0x03, 0x10, 0x10, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x09, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0d, 0x00, + 0x0f, 0x00, 0x10, 0x00, 0x12, 0x00, 0x14, 0x00, + 0x17, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x20, 0x00, + 0x24, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x33, 0x00, + 0x39, 0x00, 0x40, 0x00, 0x47, 0x00, 0x50, 0x00, + 0x5a, 0x00, 0x64, 0x00, 0x71, 0x00, 0x7e, 0x00, + 0x8e, 0x00, 0x9f, 0x00, 0xb2, 0x00, 0xc8, 0x00, + 0xe0, 0x00, 0xfc, 0x00, 0x1a, 0x01, 0x3d, 0x01, + 0x63, 0x01, 0x8f, 0x01, 0xbf, 0x01, 0xf6, 0x01, + 0x33, 0x02, 0x77, 0x02, 0xc4, 0x02, 0x1b, 0x03, + 0x7c, 0x03, 0xe8, 0x03, 0xed, 0x09, 0x00, 0x6a, + 0x03, 0x63, 0x04, 0xeb, 0x04, 0x85, 0x05, 0x31, + 0x06, 0xf3, 0x06, 0xcc, 0x07, 0xbf, 0x08, 0xd0, + 0x09, 0x03, 0x0b, 0x5b, 0x0c, 0xdd, 0x0d, 0x8e, + 0x0f, 0x73, 0x11, 0x94, 0x13, 0xf8, 0x15, 0xa6, + 0x18, 0xa8, 0x1b, 0x08, 0x1f, 0xd1, 0x22, 0x10, + 0x27, 0xd5, 0x2b, 0x2e, 0x31, 0x2e, 0x37, 0xe9, + 0x3d, 0x77, 0x45, 0xf1, 0x4d, 0x74, 0x57, 0x1f, + 0x62, 0x18, 0x6e, 0x87, 0x7b, 0x9a, 0x8a, 0x83, + 0x9b, 0x7d, 0xae, 0xc7, 0xc3, 0xab, 0xdb, 0x78, + 0xf6, 0xff, 0xff, 0x00, 0x00, 0xff, 0x83, 0xdf, + 0x17, 0x32, 0x09, 0x4e, 0xd1, 0xe7, 0xcd, 0x8a, + 0x91, 0xc6, 0xd5, 0xc4, 0xc4, 0x40, 0x21, 0x18, + 0x4e, 0x55, 0x86, 0xf4, 0xdc, 0x8a, 0x15, 0xa7, + 0xec, 0x92, 0xdf, 0x93, 0x53, 0x30, 0x18, 0xca, + 0x34, 0xbf, 0xa2, 0xc7, 0x59, 0x67, 0x8f, 0xba, + 0x0d, 0x6d, 0xd8, 0x2d, 0x7d, 0x54, 0x0a, 0x57, + 0x97, 0x70, 0x39, 0xd2, 0x7a, 0xea, 0x24, 0x33, + 0x85, 0xed, 0x9a, 0x1d, 0xe1, 0xff, 0x07, 0xbe, + 0x2e, 0x64, 0x12, 0x9d, 0xa3, 0xcf, 0x9b, 0x15, + 0x23, 0x8d, 0xab, 0x89, 0x88, 0x80, 0x42, 0x30, + 0x9c, 0xab, 0x0d, 0xe9, 0xb9, 0x14, 0x2b, 0x4f, + 0xd9, 0x25, 0xbf, 0x26, 0xa6, 0x60, 0x31, 0x94, + 0x69, 0x7f, 0x45, 0x8e, 0xb2, 0xcf, 0x1f, 0x74, + 0x1a, 0xdb, 0xb0, 0x5a, 0xfa, 0xa8, 0x14, 0xaf, + 0x2e, 0xe0, 0x73, 0xa4, 0xf5, 0xd4, 0x48, 0x67, + 0x0b, 0xdb, 0x34, 0x3b, 0xc3, 0xfe, 0x0f, 0x7c, + 0x5c, 0xc8, 0x25, 0x3b, 0x47, 0x9f, 0x36, 0x2a, + 0x47, 0x1b, 0x57, 0x13, 0x11, 0x00, 0x84, 0x61, + 0x39, 0x56, 0x1b, 0xd3, 0x72, 0x28, 0x56, 0x9f, + 0xb2, 0x4b, 0x7e, 0x4d, 0x4c, 0xc0, 0x63, 0x28, + 0xd2, 0xfe, 0x8b, 0x1d, 0x65, 0x9e, 0x3e, 0xe8, + 0x35, 0xb7, 0x60, 0xb5, 0xf5, 0x50, 0x29, 0xed, + 0x09, 0x00, 0x6b, 0x03, 0x5e, 0x5d, 0xc0, 0xe7, + 0x49, 0xeb, 0xa8, 0x90, 0xce, 0x17, 0xb6, 0x68, + 0x77, 0x87, 0xfc, 0x1e, 0xf8, 0xb9, 0x90, 0x4a, + 0x76, 0x8f, 0x3e, 0x6c, 0x54, 0x8e, 0x36, 0xae, + 0x26, 0x22, 0x01, 0x08, 0xc2, 0x72, 0xac, 0x37, + 0xa6, 0xe4, 0x50, 0xad, 0x3f, 0x64, 0x96, 0xfc, + 0x9a, 0x99, 0x80, 0xc6, 0x51, 0xa5, 0xfd, 0x16, + 0x3a, 0xcb, 0x3c, 0x7d, 0xd0, 0x6b, 0x6e, 0xc1, + 0x6b, 0xea, 0xa0, 0x52, 0xbc, 0xbb, 0x81, 0xce, + 0x93, 0xd7, 0x51, 0x21, 0x9c, 0x2f, 0x6c, 0xd0, + 0xef, 0x0f, 0xf8, 0x3d, 0xf1, 0x73, 0x20, 0x94, + 0xed, 0x1e, 0x7c, 0xd8, 0xa9, 0x1c, 0x6d, 0x5c, + 0x4c, 0x44, 0x02, 0x11, 0x84, 0xe5, 0x58, 0x6f, + 0x4d, 0xc8, 0xa1, 0x5a, 0x7e, 0xc9, 0x2d, 0xf9, + 0x35, 0x33, 0x01, 0x8c, 0xa3, 0x4b, 0xfa, 0x2c, + 0x75, 0x96, 0x78, 0xfb, 0xa0, 0xd6, 0xdd, 0x82, + 0xd7, 0xd5, 0x40, 0xa5, 0x79, 0x77, 0x03, 0x9d, + 0x27, 0xae, 0xa2, 0x43, 0x38, 0x5e, 0xd9, 0xa1, + 0xde, 0x1f, 0xf0, 0x7b, 0xe2, 0xe6, 0x41, 0x29, + 0xda, 0x3c, 0xf9, 0xb1, 0x52, 0x38, 0xda, 0xb8, + 0x98, 0x88, 0x04, 0x23, 0x09, 0xca, 0xb0, 0xde, + 0x9b, 0x91, 0x42, 0xb4, 0xfd, 0x92, 0x5b, 0xf2, + 0x6a, 0x66, 0x03, 0x19, 0x46, 0x97, 0xf4, 0x58, + 0xeb, 0x2c, 0xf1, 0xf7, 0x41, 0xad, 0xbb, 0x05, + 0xaf, 0xaa, 0x81, 0x4a, 0xf2, 0xee, 0x07, 0x3a, + 0x4f, 0x5d, 0x44, 0x86, 0x70, 0xbd, 0xb3, 0x43, + 0xbc, 0x3f, 0xe0, 0xf7, 0xc5, 0xcc, 0x82, 0x53, + 0xb4, 0x79, 0xf3, 0x62, 0xa4, 0x71, 0xb5, 0x71, + 0x31, 0x10, 0x08, 0x46, 0x13, 0x95, 0x61, 0xbd, + 0x37, 0x22, 0x85, 0x69, 0xfb, 0x24, 0xb7, 0xe4, + 0xd4, 0xcc, 0x06, 0x32, 0x8d, 0x2f, 0xe8, 0xb1, + 0xd6, 0x59, 0xe3, 0xee, 0x83, 0x5b, 0x76, 0x0b, + 0x5f, 0x55, 0xed, 0x09, 0x00, 0x6c, 0x03, 0x02, + 0x95, 0xe5, 0xdc, 0x0e, 0x74, 0x9e, 0xba, 0x89, + 0x0c, 0xe1, 0x7b, 0x66, 0x87, 0x78, 0x7f, 0xc1, + 0xef, 0x8b, 0x99, 0x04, 0xa7, 0x68, 0xf3, 0xe6, + 0xc5, 0x48, 0xe3, 0x6a, 0xe2, 0x62, 0x20, 0x10, + 0x8c, 0x27, 0x2a, 0xc3, 0x7a, 0x6e, 0x45, 0x0a, + 0xd3, 0xf6, 0x49, 0x6f, 0xc9, 0xa9, 0x98, 0x0c, + 0x65, 0x1a, 0x5f, 0xd1, 0x63, 0xac, 0xb3, 0xc7, + 0xdd, 0x06, 0xb6, 0xec, 0x16, 0xbe, 0xaa, 0x05, + 0x2b, 0xcb, 0xb8, 0x1c, 0xe9, 0x3d, 0x75, 0x12, + 0x19, 0xc2, 0xf6, 0xcd, 0x0e, 0xf0, 0xff, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x03, 0x00, 0xed, 0x09, 0x00, + 0x6d, 0x03, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x6e, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x7c, 0x00, + 0x00, 0x28, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x68, 0x7c, 0x00, 0x00, 0x30, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x6f, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x70, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, + 0x38, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, + 0xff, 0xff, 0x40, 0x7c, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x09, + 0x02, 0x00, 0x00, 0x01, 0x01, 0x04, 0x00, 0x00, + 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, + 0x05, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, + 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x71, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x72, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x02, 0x00, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x03, + 0xe0, 0x01, 0x01, 0x00, 0x07, 0x05, 0x81, 0x03, + 0x10, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02, 0x40, + 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x73, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x01, 0x00, + 0x02, 0xe0, 0x01, 0x01, 0x00, 0x07, 0x05, 0x84, + 0x01, 0x00, 0x00, 0x01, 0x07, 0x05, 0x04, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x04, 0x01, 0x01, 0x02, 0xe0, + 0x01, 0x01, 0x00, 0x07, 0x05, 0x84, 0x01, 0x09, + 0x00, 0x01, 0x07, 0x05, 0x04, 0x01, 0x09, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x04, 0x01, 0x02, 0x02, 0xe0, 0x01, 0x01, + 0x00, 0x07, 0x05, 0x84, 0x01, 0x11, 0x00, 0x01, + 0x07, 0x05, 0x04, 0x01, 0x11, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, + 0x01, 0x03, 0x02, 0xe0, 0x01, 0x01, 0x00, 0x07, + 0x05, 0x84, 0x01, 0x19, 0x00, 0x01, 0x07, 0x05, + 0x04, 0x01, 0x19, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x01, 0x04, + 0x02, 0xe0, 0x01, 0x01, 0x00, 0x07, 0x05, 0x84, + 0x01, 0x21, 0x00, 0x01, 0x07, 0x05, 0x04, 0x01, + 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x04, 0x01, 0x05, 0x02, 0xe0, + 0x01, 0x01, 0x00, 0x07, 0x05, 0x84, 0x01, 0x31, + 0x00, 0x01, 0x07, 0x05, 0x04, 0x01, 0x31, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x74, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x44, 0x48, 0x31, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x23, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x00, 0x27, 0x00, 0xed, 0x09, 0x00, + 0x75, 0x03, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x76, 0x03, 0x0b, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, + 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x27, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x31, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x33, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x36, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x39, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x3b, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0xed, 0x09, 0x00, 0x77, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x78, 0x03, 0x05, 0x00, 0x00, 0x00, 0x43, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xf8, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xf8, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x7c, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x76, + 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x76, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x41, + 0x00, 0xed, 0x09, 0x00, 0x79, 0x03, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x7a, + 0x03, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, + 0x00, 0x6d, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x00, 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, + 0x00, 0x61, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x3b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x7b, 0x03, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xb4, 0x00, 0x20, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xa5, 0xb4, 0x00, 0x20, 0x03, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf5, 0xb4, + 0x00, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x29, 0xb5, + 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x5d, 0xb5, 0x00, 0x20, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x7c, 0x03, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x3d, 0xb6, 0x00, 0x20, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x41, 0xb6, 0x00, 0x20, 0x07, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x45, 0xb6, 0x00, 0x20, 0x0f, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x59, + 0xb6, 0x00, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0xb1, 0xb6, 0x00, 0x20, 0x07, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x91, + 0xb5, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x91, 0xb5, 0x00, 0x20, 0x11, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x91, + 0xb5, 0x00, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0xed, 0x09, 0x00, + 0x7d, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0xb5, 0xb6, 0x00, 0x20, + 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xe9, 0xb6, 0x00, 0x20, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0xb4, 0x00, 0x20, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0xb4, 0x00, 0x20, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x71, 0xb7, 0x00, 0x20, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x8f, 0xb7, 0x00, 0x20, + 0x16, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x8b, 0xb7, 0x00, 0x20, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x7e, 0x03, 0x0e, 0x00, 0x00, + 0x00, 0xf7, 0xb7, 0x00, 0x20, 0x16, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xa5, 0xb7, 0x00, 0x20, 0x10, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xa5, 0xb7, 0x00, + 0x20, 0x11, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xa5, 0xb7, 0x00, 0x20, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x13, 0x00, 0xed, 0x09, 0x00, 0x7f, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xb5, 0xb6, + 0x00, 0x20, 0x0f, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0xe9, 0xb6, 0x00, 0x20, 0x0a, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0d, 0xb8, + 0x00, 0x20, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x47, + 0xb4, 0x00, 0x20, 0x22, 0x00, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x53, 0xb4, 0x00, 0x20, 0x10, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0d, + 0xb8, 0x00, 0x20, 0x0a, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x71, + 0xb7, 0x00, 0x20, 0x0a, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0d, + 0xb8, 0x00, 0x20, 0x16, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x8f, 0xb7, 0x00, 0x20, 0x16, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x81, 0x03, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x8b, 0xb7, 0x00, 0x20, 0x0a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0d, 0xb8, 0x00, 0x20, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0xf7, 0xb7, 0x00, 0x20, 0x16, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xa5, 0xb7, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xa5, 0xb7, 0x00, 0x20, + 0x11, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xa5, 0xb7, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xa5, 0xb7, 0x00, 0x20, + 0x0a, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x0d, 0xb8, 0x00, 0x20, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x82, + 0x03, 0x0e, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0d, 0xb8, 0x00, + 0x20, 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xcc, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 0x44, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, + 0x09, 0x00, 0x83, 0x03, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc4, 0xff, + 0xff, 0xff, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xe2, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x84, 0x03, 0x79, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd4, + 0xfe, 0xff, 0xff, 0xb7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x38, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa8, + 0xfd, 0xff, 0xff, 0x53, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x70, 0xfe, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x2e, 0x45, 0x5d, 0x00, 0x00, 0x00, + 0x54, 0x6f, 0x53, 0x43, 0x4f, 0x5f, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x96, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x51, 0xc7, 0x02, 0x20, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x0d, 0xc3, 0x02, 0x20, + 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0xd9, 0xc5, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x75, 0xc7, 0x02, 0x20, + 0xed, 0x09, 0x00, 0x86, 0x03, 0xa1, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x85, 0xc1, 0x02, + 0x20, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0xc5, 0xc3, 0x02, 0x20, 0x7c, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0xe5, 0xc5, 0x02, 0x20, 0x9a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0xc7, 0x02, + 0x20, 0xa1, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0xed, 0xc1, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0xc4, 0x02, + 0x20, 0x1d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x53, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x8d, 0xdb, 0x02, 0x20, 0x4f, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9b, 0x00, 0xed, 0x09, 0x00, 0x87, 0x03, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x35, 0xc6, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc9, 0xc7, 0x02, 0x20, 0xa1, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x25, 0xc2, + 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xd1, 0xbb, + 0x02, 0x20, 0x28, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x13, 0xbc, 0x02, 0x20, 0x18, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0xbc, + 0x02, 0x20, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x21, 0xbc, + 0x02, 0x20, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x51, 0xc4, 0x02, 0x20, 0x9d, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x59, 0xdc, + 0x02, 0x20, 0x9b, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0xb5, 0xdc, 0x02, 0x20, 0x9c, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb5, 0xdc, + 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0xf1, 0xc5, 0x02, 0x20, 0x9a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xc7, + 0x02, 0x20, 0xa0, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x88, 0x03, 0x05, 0x00, 0x00, 0x00, 0xf1, + 0xdb, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xc5, + 0xc4, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x01, 0xc6, 0x02, 0x20, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0xc8, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x11, 0xc5, 0x02, 0x20, 0x9d, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x35, 0xf1, 0x02, 0x20, 0x63, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xb5, + 0xac, 0x02, 0x20, 0x56, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x43, 0xbc, 0x02, 0x20, 0x7a, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x47, 0xc6, 0x02, 0x20, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, + 0xc8, 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x51, 0xc2, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, + 0x00, 0xed, 0x09, 0x00, 0x89, 0x03, 0x00, 0x00, + 0x11, 0xc5, 0x02, 0x20, 0x9d, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xa5, 0xbc, 0x02, 0x20, 0x7a, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x47, 0xc6, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x85, 0xc8, 0x02, 0x20, + 0xa1, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x51, 0xc2, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x11, 0xc5, 0x02, 0x20, + 0x9d, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x71, 0xbd, 0x02, 0x20, + 0x7a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x47, 0xc6, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x85, 0xc8, 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x51, 0xc2, 0x02, 0x20, + 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x8a, + 0x03, 0xcd, 0xf0, 0x02, 0x20, 0x06, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0xcd, 0xf0, 0x02, + 0x20, 0x2c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0xcd, 0xf0, 0x02, 0x20, 0x22, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0xcd, 0xf0, 0x02, + 0x20, 0xa1, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0xa9, 0xf0, 0x02, 0x20, 0x9d, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x57, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0xcd, 0xf0, 0x02, + 0x20, 0x59, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x8f, 0xf0, 0x02, + 0x20, 0x67, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0xcd, 0xf0, 0xed, + 0x09, 0x00, 0x8b, 0x03, 0x02, 0x20, 0x48, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x25, 0xf0, + 0x02, 0x20, 0x49, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x85, 0xf0, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0xf1, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4d, 0xf1, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x15, 0xac, + 0x02, 0x20, 0x06, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x15, 0xac, 0x02, 0x20, 0xa1, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xf1, 0xab, + 0x02, 0x20, 0x9d, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x35, 0xab, + 0x02, 0x20, 0x69, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0xd9, 0xab, 0x02, 0x20, 0x64, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x15, 0xac, 0x02, 0x20, 0x54, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x41, 0xab, + 0x02, 0x20, 0x67, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x7b, 0xab, 0x02, 0x20, 0x68, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x15, 0xac, + 0x02, 0x20, 0xed, 0x09, 0x00, 0x8c, 0x03, 0x63, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x55, + 0xac, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7d, 0xac, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0xd3, 0xf6, 0x02, 0x20, 0x2d, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xeb, + 0xf7, 0x02, 0x20, 0x33, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x43, + 0xf7, 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x5d, 0xf8, 0x02, 0x20, 0xa4, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x5d, + 0xf8, 0x02, 0x20, 0x9d, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0xed, 0x09, 0x00, + 0x8d, 0x03, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0b, 0xf7, 0x02, 0x20, 0x72, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0xab, 0xf7, 0x02, 0x20, + 0x76, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xb5, 0xf7, 0x02, 0x20, 0x4a, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0xbf, 0xf7, 0x02, 0x20, + 0x7a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x29, 0xf8, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3b, 0xf8, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x81, 0xbe, 0x02, 0x20, + 0x1c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x8d, 0xbe, 0x02, 0x20, 0x02, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x59, 0xc5, 0x02, 0x20, + 0x9d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x8e, 0x03, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0xe5, 0xbe, 0x02, + 0x20, 0x54, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x73, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x75, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, + 0x00, 0x12, 0x00, 0xed, 0x09, 0x00, 0x8f, 0x03, + 0x00, 0x00, 0x85, 0xc2, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x59, 0xc6, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb1, 0xc8, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xa1, 0xc5, + 0x02, 0x20, 0x0c, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x29, 0xab, 0x02, 0x20, 0x16, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, + 0xdd, 0x02, 0x20, 0x52, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x71, 0xdd, 0x02, 0x20, 0x9b, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0x91, 0x03, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x87, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0xd7, 0xaa, 0x02, 0x20, 0x68, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xf3, 0xaa, 0x02, 0x20, + 0x63, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x92, + 0x03, 0x54, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x11, 0xab, 0x02, 0x20, 0x5a, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x65, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x1d, 0xab, 0x02, 0x20, 0x48, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0xe5, 0xaa, 0x02, 0x20, 0x69, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x71, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x73, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x75, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4b, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0xed, + 0x09, 0x00, 0x93, 0x03, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0xf1, 0xbe, 0x02, 0x20, 0xa0, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xab, 0xdd, + 0x02, 0x20, 0xa4, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x6b, 0xc6, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0xc8, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xa1, 0xc5, + 0x02, 0x20, 0x2c, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x27, 0xbf, 0x02, 0x20, 0x32, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x94, 0x03, 0x0e, + 0x00, 0x00, 0x00, 0x51, 0xc0, 0x02, 0x20, 0x33, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x71, 0xc0, 0x02, 0x20, 0x28, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xff, + 0xbe, 0x02, 0x20, 0x22, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x09, 0xbf, 0x02, 0x20, 0x16, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, + 0xdd, 0x02, 0x20, 0x52, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x71, 0xdd, 0x02, 0x20, 0x9b, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0xed, 0x09, 0x00, + 0x95, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x87, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x13, 0xbf, 0x02, 0x20, + 0x5a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x96, 0x03, 0x1d, 0xbf, 0x02, + 0x20, 0x5d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x27, 0xbf, 0x02, + 0x20, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0xed, 0xbf, 0x02, 0x20, 0x48, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0xed, 0xbf, 0x02, + 0x20, 0x67, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x9d, 0xbf, 0x02, + 0x20, 0x69, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x71, 0xc0, 0x02, + 0x20, 0x71, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x73, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x71, 0xc0, 0x02, 0x20, 0x6b, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x75, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x91, 0xc0, 0x02, 0x20, 0x4a, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x91, 0xc0, 0x02, + 0x20, 0x6c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0xb1, 0xc0, 0x02, + 0x20, 0x4b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0xc7, 0xc0, 0xed, 0x09, 0x00, 0x97, 0x03, + 0x02, 0x20, 0xa0, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0xab, 0xdd, 0x02, 0x20, 0xa4, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0xcb, 0xc0, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x6b, 0xc6, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0xc8, 0x02, 0x20, 0x60, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xa1, 0xc5, + 0x02, 0x20, 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0x98, 0x03, 0x2e, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x31, 0xbf, 0x02, 0x20, 0x32, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x5d, + 0xc0, 0x02, 0x20, 0x33, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x7d, + 0xc0, 0x02, 0x20, 0x16, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x05, 0xdd, 0x02, 0x20, 0x52, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x71, + 0xdd, 0x02, 0x20, 0x9b, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, + 0x00, 0xed, 0x09, 0x00, 0x99, 0x03, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x53, 0xbf, 0x02, 0x20, + 0x62, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x7b, 0xbf, 0x02, 0x20, 0x46, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x53, 0xbf, 0x02, 0x20, + 0x47, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x7b, 0xbf, 0x02, 0x20, 0x63, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0x9a, + 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x65, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x31, 0xbf, 0x02, 0x20, 0x49, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x29, 0xc0, 0x02, + 0x20, 0x48, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x29, 0xc0, 0x02, 0x20, 0x67, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0xb9, 0xbf, 0x02, 0x20, 0x69, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x7d, 0xc0, 0x02, 0x20, 0x71, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x72, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x7d, 0xc0, 0x02, + 0x20, 0x6b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x9d, 0xc0, 0x02, + 0x20, 0x4a, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x9d, 0xc0, 0x02, 0x20, 0x6c, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0xab, 0xdd, 0x02, 0x20, 0xa4, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa1, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xed, + 0x09, 0x00, 0x9b, 0x03, 0x00, 0x00, 0xe9, 0xc0, + 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x6b, 0xc6, 0x02, 0x20, 0x9a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0xc8, + 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0xc9, + 0x02, 0x20, 0xa2, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0xe3, 0xc2, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0xc5, 0xc6, 0x02, 0x20, 0x4d, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0xc9, 0x02, 0x20, 0xa2, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xb9, 0xc2, + 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x35, 0xca, 0x02, 0x20, 0x97, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xda, + 0x02, 0x20, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x9d, 0xa5, + 0x02, 0x20, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0x9c, 0x03, 0x69, + 0xa4, 0x02, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x69, 0xa4, 0x02, 0x20, 0x2c, + 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x4f, + 0xf4, 0x02, 0x20, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x81, + 0xe2, 0x02, 0x20, 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcd, 0xd8, 0x02, 0x20, 0x53, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1d, + 0xd9, 0x02, 0x20, 0x5a, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xf9, 0xe2, 0x02, 0x20, 0x5e, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x2f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, + 0xf4, 0x02, 0x20, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xd7, + 0xa5, 0x02, 0x20, 0x54, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x5d, 0xe2, 0x02, 0x20, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x20, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, 0x20, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0x9d, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xc9, 0xe3, 0x02, 0x20, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xff, 0xe3, 0x02, 0x20, + 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x6d, 0xe4, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xa9, 0xe4, 0x02, 0x20, + 0x63, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x8d, 0xe5, 0x02, 0x20, 0x57, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xc9, 0xe5, 0x02, 0x20, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0x9e, 0x03, 0xa1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xe6, 0x02, + 0x20, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd5, 0xef, 0x02, 0x20, 0x9a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x02, + 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xe5, 0xe6, 0x02, + 0x20, 0x29, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x0d, 0xe7, 0x02, 0x20, 0x5a, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xc1, 0xe7, 0x02, + 0x20, 0x5b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0xa5, 0xe8, 0x02, 0x20, 0x5c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0xe6, 0x02, 0x20, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x47, 0xee, 0x02, + 0x20, 0x2f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x4d, 0xef, 0x02, 0x20, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0x00, 0xed, 0x09, 0x00, 0x9f, 0x03, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x05, 0xef, 0x02, 0x20, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xef, + 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0xe6, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x59, 0xef, 0x02, 0x20, 0x63, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc9, 0xef, + 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0xe6, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0xf9, 0xe6, 0x02, 0x20, 0x64, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0xf9, 0xe6, 0x02, 0x20, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xed, + 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0xe6, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xef, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0b, 0xf0, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0xa0, 0x03, 0x09, 0x00, 0x00, 0x00, 0xf9, + 0xe6, 0x02, 0x20, 0x29, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0xe9, 0xed, 0x02, 0x20, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, + 0xe6, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, 0x20, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x61, + 0xea, 0x02, 0x20, 0x07, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x61, 0xea, 0x02, 0x20, 0x19, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, + 0xef, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xf0, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xa7, + 0xea, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, 0x20, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0xed, 0x09, 0x00, 0xa1, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x05, 0xe9, 0x02, 0x20, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd5, 0xef, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x02, 0x20, + 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0xed, 0xea, 0x02, 0x20, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0xea, 0x02, 0x20, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd5, 0xef, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0xa2, + 0x03, 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0xa1, 0xeb, 0x02, + 0x20, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa1, 0xeb, 0x02, 0x20, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x4d, 0xe9, 0x02, 0x20, 0x5b, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x85, 0xe9, 0x02, + 0x20, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0xe6, 0x02, 0x20, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xf0, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x55, 0xec, 0x02, 0x20, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xef, 0xed, + 0x09, 0x00, 0xa3, 0x03, 0x02, 0x20, 0x9a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, + 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0xed, 0x02, 0x20, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xed, + 0x02, 0x20, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x47, 0xed, 0x02, 0x20, 0xa1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xe6, + 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe7, 0xef, 0x02, 0x20, 0x9a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf0, + 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf9, 0xe6, + 0x02, 0x20, 0x28, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0xa9, 0xec, 0x02, 0x20, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0xa4, 0x03, 0x63, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x9d, + 0xec, 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa5, 0xe6, 0x02, 0x20, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, + 0xef, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xf0, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0xb5, 0xda, 0x02, 0x20, 0x52, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xcd, + 0xd8, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x65, 0xdb, 0x02, 0x20, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, + 0xdb, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0xa1, + 0xda, 0x02, 0x20, 0x52, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0xcd, 0xd8, 0x02, 0x20, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xdb, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x83, 0xdb, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0xdb, 0x02, 0x20, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe5, 0xda, 0x02, 0x20, 0x52, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0xcd, + 0xd8, 0x02, 0x20, 0x50, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0xc5, 0xda, 0x02, 0x20, 0x51, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x00, 0xed, 0x09, 0x00, + 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0xdb, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0xdb, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4d, 0xdb, 0x02, 0x20, 0x9c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0xdb, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0xdb, 0x02, 0x20, + 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x5b, 0xd9, 0x02, 0x20, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0xdb, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0xdb, 0x02, 0x20, + 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xf7, 0xda, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0xdb, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0xdb, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0xa6, 0x03, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0xdb, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x83, 0xdb, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0xdb, 0x02, + 0x20, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0xdb, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x83, 0xdb, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3d, 0xa7, 0x02, 0x20, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xa7, 0x02, + 0x20, 0x18, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xaa, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb3, 0xaa, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0xa7, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, + 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xed, 0xa7, + 0x02, 0x20, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xaa, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb3, 0xaa, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1e, 0x00, + 0x00, 0x00, 0x8d, 0xa4, 0x02, 0x20, 0x1f, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x1e, 0x00, + 0x00, 0x00, 0x91, 0xa9, 0x02, 0x20, 0x64, 0x00, + 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfb, 0xa7, 0x02, 0x20, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xa7, + 0x02, 0x20, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd5, 0xa8, 0x02, 0x20, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x53, 0xa9, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0xaa, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xbd, 0xaa, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1f, 0x00, + 0x00, 0x00, 0xa1, 0xa4, 0x02, 0x20, 0x2a, 0x00, + 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x8d, 0xa4, + 0x02, 0x20, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x00, + 0x00, 0x00, 0x59, 0xa6, 0x02, 0x20, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0xa8, 0x03, 0xe5, 0xa6, 0x02, 0x20, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, + 0xaa, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb3, 0xaa, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x69, 0xa4, 0x02, 0x20, 0x06, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1d, + 0xa6, 0x02, 0x20, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x49, 0xa6, 0x02, 0x20, 0x29, + 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x51, + 0xa8, 0x02, 0x20, 0x1f, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0xeb, 0xa5, 0x02, 0x20, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, + 0xaa, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb3, 0xaa, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x71, 0xa8, 0x02, 0x20, 0x2f, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x91, + 0xa9, 0x02, 0x20, 0x5a, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x19, 0xa9, 0x02, 0x20, 0x64, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0xa9, 0x03, 0x00, 0x00, + 0x66, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe3, 0xa8, 0x02, 0x20, + 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd5, 0xa8, 0x02, 0x20, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0xa9, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x87, 0xaa, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb3, 0xaa, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0xcf, 0xa9, 0x02, 0x20, + 0x65, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0xcf, 0xa9, 0x02, 0x20, 0xa1, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0xa9, 0x02, 0x20, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x87, 0xaa, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb3, 0xaa, 0x02, 0x20, + 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x29, 0xaa, 0x02, 0x20, + 0x63, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x87, 0xaa, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb3, 0xaa, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0xaa, + 0x03, 0x64, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0xa5, 0x02, + 0x20, 0x65, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x09, 0xa5, 0x02, 0x20, 0x67, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0xa5, 0x02, + 0x20, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0xa5, 0x02, 0x20, 0xa1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0xa9, 0x02, + 0x20, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x87, 0xaa, 0x02, 0x20, 0x9a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0xaa, 0x02, + 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x27, 0x00, 0x00, 0x00, 0x35, 0xf4, 0x02, + 0x20, 0x28, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0xc1, 0xf4, 0x02, + 0x20, 0x63, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xf6, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc9, 0xf6, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, + 0x00, 0xcd, 0xf4, 0x02, 0x20, 0x18, 0x00, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xf6, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc9, 0xf6, 0x02, 0x20, 0xa5, 0x00, 0xed, + 0x09, 0x00, 0xab, 0x03, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xf1, 0xf3, + 0x02, 0x20, 0x32, 0x00, 0x00, 0x00, 0x27, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x2c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x27, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x29, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x00, + 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd5, 0xf3, 0x02, 0x20, 0x69, 0x00, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xd7, 0xf4, + 0x02, 0x20, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd5, 0xf3, 0x02, 0x20, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xf6, + 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc9, 0xf6, 0x02, 0x20, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x5d, 0xf5, 0x02, 0x20, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf3, + 0x02, 0x20, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0xac, 0x03, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x45, + 0xf5, 0x02, 0x20, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd5, 0xf3, 0x02, 0x20, 0xa4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, + 0xf3, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xab, 0xf6, 0x02, 0x20, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, + 0xf6, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x2b, + 0x00, 0x00, 0x00, 0x83, 0xf5, 0x02, 0x20, 0x34, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, + 0xf3, 0x02, 0x20, 0x28, 0x00, 0x00, 0x00, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x2b, + 0x00, 0x00, 0x00, 0xa1, 0xf5, 0x02, 0x20, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, + 0xf3, 0x02, 0x20, 0xa4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd5, 0xf3, 0x02, 0x20, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, + 0xf6, 0x02, 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc9, 0xf6, 0x02, 0x20, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0xed, 0x09, 0x00, + 0xad, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xbd, 0xf5, 0x02, 0x20, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xbd, 0xf5, 0x02, 0x20, + 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1d, 0xf6, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xab, 0xf6, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc9, 0xf6, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf5, 0x02, 0x20, + 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd5, 0xf3, 0x02, 0x20, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xab, 0xf6, 0x02, 0x20, + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc9, 0xf6, 0x02, 0x20, 0xa5, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0xf6, 0x02, 0x20, 0xa4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3b, 0xf6, 0x02, 0x20, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0xae, 0x03, 0xab, 0xf6, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc9, 0xf6, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xf6, 0x02, + 0x20, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd5, 0xf3, 0x02, 0x20, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xf6, 0x02, + 0x20, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc9, 0xf6, 0x02, 0x20, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0xaf, 0x03, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, + 0x00, 0xb0, 0x03, 0xa5, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xed, 0x09, 0x00, 0xb1, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0b, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe1, 0x0b, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x03, 0x20, 0xed, 0x09, 0x00, 0xb2, + 0x03, 0xc3, 0x15, 0x03, 0x20, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x03, + 0x20, 0x01, 0x16, 0x03, 0x20, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x0f, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x3b, 0x0f, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x12, 0x03, + 0x20, 0x6d, 0x16, 0x03, 0x20, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x02, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x02, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x04, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x05, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x6d, 0x03, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x35, 0x03, 0x03, + 0x20, 0xbd, 0x16, 0x03, 0x20, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x06, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x07, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x9d, 0x08, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x41, 0x09, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x0f, 0xed, + 0x09, 0x00, 0xb3, 0x03, 0x03, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3d, 0x11, 0x03, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0b, 0x11, 0x03, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x11, 0x03, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x11, 0x03, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x41, 0x10, 0x03, 0x20, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x97, 0x10, 0x03, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd9, 0x10, 0x03, 0x20, 0xdd, 0x16, + 0x03, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe3, 0x10, 0x03, 0x20, 0xfd, 0x16, + 0x03, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xed, 0x09, 0x00, 0xb4, 0x03, 0xc1, + 0x0c, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, + 0x0c, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, + 0x0a, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, + 0x0a, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, + 0x09, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, + 0x0a, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf9, + 0x0d, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, + 0x0d, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, + 0x21, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, + 0x22, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, + 0x0e, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x0e, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, + 0x01, 0x03, 0x20, 0x3f, 0x16, 0x03, 0x20, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xdd, + 0x03, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, + 0xb5, 0x03, 0x00, 0x00, 0x0f, 0x01, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0x0f, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xed, 0x10, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xa5, 0x11, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x09, 0x12, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x09, 0x00, 0xb6, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xed, 0x09, 0x00, 0xb7, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2d, + 0xe2, 0x93, 0xbe, 0x45, 0x15, 0xae, 0x78, 0x03, + 0x87, 0xa4, 0xb8, 0x38, 0xcf, 0x3f, 0x08, 0x67, + 0x09, 0x94, 0xeb, 0x26, 0xa8, 0x6b, 0xbd, 0x18, + 0x34, 0x1b, 0xbb, 0xbf, 0x72, 0xf7, 0x40, 0x35, + 0x48, 0x9c, 0x51, 0x2f, 0x3b, 0x55, 0xe3, 0xc0, + 0x9f, 0xd8, 0xd3, 0xf3, 0x8d, 0xb1, 0xff, 0xa7, + 0x3e, 0xdc, 0x86, 0x77, 0xd7, 0xa6, 0x11, 0xfb, + 0xf4, 0xba, 0x92, 0x91, 0x64, 0x83, 0xf1, 0x33, + 0xef, 0xda, 0x2c, 0xb5, 0xb2, 0x2b, 0x88, 0xd1, + 0x99, 0xcb, 0x8c, 0x84, 0x1d, 0x14, 0x81, 0x97, + 0x71, 0xca, 0x5f, 0xa3, 0x8b, 0x57, 0x3c, 0x82, + 0xc4, 0x52, 0x5c, 0x1c, 0xe8, 0xa0, 0x04, 0xb4, + 0x85, 0x4a, 0xf6, 0x13, 0x54, 0xb6, 0xdf, 0x0c, + 0x1a, 0x8e, 0xde, 0xe0, 0x39, 0xfc, 0x20, 0x9b, + 0x24, 0x4e, 0xa9, 0x98, 0x9e, 0xab, 0xf2, 0x60, + 0xd0, 0x6c, 0xea, 0xfa, 0xc7, 0xd9, 0x00, 0xd4, + 0x1f, 0x6e, 0x43, 0xbc, 0xec, 0x53, 0x89, 0xfe, + 0x7a, 0x5d, 0x49, 0xc9, 0x32, 0xc2, 0xf9, 0x9a, + 0xf8, 0x6d, 0x16, 0xdb, 0x59, 0x96, 0x44, 0xe9, + 0xcd, 0xe6, 0x46, 0x42, 0x8f, 0x0a, 0xc1, 0xcc, + 0xb9, 0x65, 0xb0, 0xd2, 0xc6, 0xac, 0x1e, 0x41, + 0x62, 0x29, 0x2e, 0x0e, 0x74, 0x50, 0x02, 0x5a, + 0xc3, 0x25, 0x7b, 0x8a, 0x2a, 0x5b, 0xf0, 0x06, + 0x0d, 0x47, 0x6f, 0x70, 0x9d, 0x7e, 0x10, 0xce, + 0x12, 0x27, 0xd5, 0x4c, 0x4f, 0xd6, 0x79, 0x30, + 0x68, 0x36, 0x75, 0x7d, 0xe4, 0xed, 0x80, 0x6a, + 0x90, 0x37, 0xa2, 0x5e, 0x76, 0xaa, 0xc5, 0x7f, + 0x3d, 0xaf, 0xa5, 0xe5, 0x19, 0x61, 0xfd, 0x4d, + 0x7c, 0xb7, 0x0b, 0xee, 0xad, 0x4b, 0x22, 0xf5, + 0xe7, 0x73, 0x23, 0x21, 0xc8, 0x05, 0xed, 0x09, + 0x00, 0xb8, 0x03, 0xe1, 0x66, 0xdd, 0xb3, 0x58, + 0x69, 0x63, 0x56, 0x0f, 0xa1, 0x31, 0x95, 0x17, + 0x07, 0x3a, 0x28, 0x80, 0x00, 0xb0, 0x09, 0x60, + 0xef, 0xb9, 0xfd, 0x10, 0x12, 0x9f, 0xe4, 0x69, + 0xba, 0xad, 0xf8, 0xc0, 0x38, 0xc2, 0x65, 0x4f, + 0x06, 0x94, 0xfc, 0x19, 0xde, 0x6a, 0x1b, 0x5d, + 0x4e, 0xa8, 0x82, 0x70, 0xed, 0xe8, 0xec, 0x72, + 0xb3, 0x15, 0xc3, 0xff, 0xab, 0xb6, 0x47, 0x44, + 0x01, 0xac, 0x25, 0xc9, 0xfa, 0x8e, 0x41, 0x1a, + 0x21, 0xcb, 0xd3, 0x0d, 0x6e, 0xfe, 0x26, 0x58, + 0xda, 0x32, 0x0f, 0x20, 0xa9, 0x9d, 0x84, 0x98, + 0x05, 0x9c, 0xbb, 0x22, 0x8c, 0x63, 0xe7, 0xc5, + 0xe1, 0x73, 0xc6, 0xaf, 0x24, 0x5b, 0x87, 0x66, + 0x27, 0xf7, 0x57, 0xf4, 0x96, 0xb1, 0xb7, 0x5c, + 0x8b, 0xd5, 0x54, 0x79, 0xdf, 0xaa, 0xf6, 0x3e, + 0xa3, 0xf1, 0x11, 0xca, 0xf5, 0xd1, 0x17, 0x7b, + 0x93, 0x83, 0xbc, 0xbd, 0x52, 0x1e, 0xeb, 0xae, + 0xcc, 0xd6, 0x35, 0x08, 0xc8, 0x8a, 0xb4, 0xe2, + 0xcd, 0xbf, 0xd9, 0xd0, 0x50, 0x59, 0x3f, 0x4d, + 0x62, 0x34, 0x0a, 0x48, 0x88, 0xb5, 0x56, 0x4c, + 0x2e, 0x6b, 0x9e, 0xd2, 0x3d, 0x3c, 0x03, 0x13, + 0xfb, 0x97, 0x51, 0x75, 0x4a, 0x91, 0x71, 0x23, + 0xbe, 0x76, 0x2a, 0x5f, 0xf9, 0xd4, 0x55, 0x0b, + 0xdc, 0x37, 0x31, 0x16, 0x74, 0xd7, 0x77, 0xa7, + 0xe6, 0x07, 0xdb, 0xa4, 0x2f, 0x46, 0xf3, 0x61, + 0x45, 0x67, 0xe3, 0x0c, 0xa2, 0x3b, 0x1c, 0x85, + 0x18, 0x04, 0x1d, 0x29, 0xa0, 0x8f, 0xb2, 0x5a, + 0xd8, 0xa6, 0x7e, 0xee, 0x8d, 0x53, 0x4b, 0xa1, + 0x9a, 0xc1, 0x0e, 0x7a, 0x49, 0xa5, 0x2c, 0x81, + 0xc4, 0xc7, 0x36, 0x2b, 0x7f, 0x43, 0x95, 0x33, + 0xf2, 0x6c, 0x68, 0x6d, 0xf0, 0x02, 0x28, 0xce, + 0xdd, 0x9b, 0xea, 0x5e, 0x99, 0x7c, 0x14, 0x86, + 0xcf, 0xed, 0x09, 0x00, 0xb9, 0x03, 0xe5, 0x42, + 0xb8, 0x40, 0x78, 0x2d, 0x3a, 0xe9, 0x64, 0x1f, + 0x92, 0x90, 0x7d, 0x39, 0x6f, 0xe0, 0x89, 0x30, + 0x80, 0x00, 0xb0, 0x09, 0x60, 0xef, 0xb9, 0xfd, + 0x10, 0x12, 0x9f, 0xe4, 0x69, 0xba, 0xad, 0xf8, + 0xc0, 0x38, 0xc2, 0x65, 0x4f, 0x06, 0x94, 0xfc, + 0x19, 0xde, 0x6a, 0x1b, 0x5d, 0x4e, 0xa8, 0x82, + 0x70, 0xed, 0xe8, 0xec, 0x72, 0xb3, 0x15, 0xc3, + 0xff, 0xab, 0xb6, 0x47, 0x44, 0x01, 0xac, 0x25, + 0xc9, 0xfa, 0x8e, 0x41, 0x1a, 0x21, 0xcb, 0xd3, + 0x0d, 0x6e, 0xfe, 0x26, 0x58, 0xda, 0x32, 0x0f, + 0x20, 0xa9, 0x9d, 0x84, 0x98, 0x05, 0x9c, 0xbb, + 0x22, 0x8c, 0x63, 0xe7, 0xc5, 0xe1, 0x73, 0xc6, + 0xaf, 0x24, 0x5b, 0x87, 0x66, 0x27, 0xf7, 0x57, + 0xf4, 0x96, 0xb1, 0xb7, 0x5c, 0x8b, 0xd5, 0x54, + 0x79, 0xdf, 0xaa, 0xf6, 0x3e, 0xa3, 0xf1, 0x11, + 0xca, 0xf5, 0xd1, 0x17, 0x7b, 0x93, 0x83, 0xbc, + 0xbd, 0x52, 0x1e, 0xeb, 0xae, 0xcc, 0xd6, 0x35, + 0x08, 0xc8, 0x8a, 0xb4, 0xe2, 0xcd, 0xbf, 0xd9, + 0xd0, 0x50, 0x59, 0x3f, 0x4d, 0x62, 0x34, 0x0a, + 0x48, 0x88, 0xb5, 0x56, 0x4c, 0x2e, 0x6b, 0x9e, + 0xd2, 0x3d, 0x3c, 0x03, 0x13, 0xfb, 0x97, 0x51, + 0x75, 0x4a, 0x91, 0x71, 0x23, 0xbe, 0x76, 0x2a, + 0x5f, 0xf9, 0xd4, 0x55, 0x0b, 0xdc, 0x37, 0x31, + 0x16, 0x74, 0xd7, 0x77, 0xa7, 0xe6, 0x07, 0xdb, + 0xa4, 0x2f, 0x46, 0xf3, 0x61, 0x45, 0x67, 0xe3, + 0x0c, 0xa2, 0x3b, 0x1c, 0x85, 0x18, 0x04, 0x1d, + 0x29, 0xa0, 0x8f, 0xb2, 0x5a, 0xd8, 0xa6, 0x7e, + 0xee, 0x8d, 0x53, 0x4b, 0xa1, 0x9a, 0xc1, 0x0e, + 0x7a, 0x49, 0xa5, 0x2c, 0x81, 0xc4, 0xc7, 0x36, + 0x2b, 0x7f, 0x43, 0x95, 0x33, 0xf2, 0x6c, 0x68, + 0x6d, 0xf0, 0x02, 0x28, 0xce, 0xdd, 0x9b, 0xea, + 0x5e, 0x99, 0x7c, 0x14, 0xed, 0x09, 0x5e, 0xba, + 0x03, 0x86, 0xcf, 0xe5, 0x42, 0xb8, 0x40, 0x78, + 0x2d, 0x3a, 0xe9, 0x64, 0x1f, 0x92, 0x90, 0x7d, + 0x39, 0x6f, 0xe0, 0x89, 0x30, 0xfc, 0x01, 0x06, + 0x09, 0x0c, 0x10, 0x13, 0x14, 0x00, 0x0a, 0x0f, + 0x14, 0x15, 0x16, 0x19, 0x1b, 0x1e, 0x20, 0x22, + 0x24, 0x27, 0x2a, 0x2d, 0x30, 0x34, 0x38, 0x3c, + 0x40, 0x44, 0x4a, 0x50, 0x55, 0x5a, 0x5f, 0x00, + 0x00, 0x00, 0x0a, 0x0f, 0x14, 0x15, 0x16, 0x19, + 0x1b, 0x1e, 0x20, 0x22, 0x24, 0x27, 0x2a, 0x2d, + 0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x4a, 0x50, + 0x55, 0x5a, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff -urN linux-2.4.21/drivers/bluetooth/hci_usb.c linux-2.4.22/drivers/bluetooth/hci_usb.c --- linux-2.4.21/drivers/bluetooth/hci_usb.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/bluetooth/hci_usb.c 2003-08-25 04:44:41.000000000 -0700 @@ -301,7 +301,8 @@ hci_usb_bulk_rx_submit(husb); #ifdef CONFIG_BLUEZ_USB_SCO - hci_usb_isoc_rx_submit(husb); + if (husb->isoc_iface) + hci_usb_isoc_rx_submit(husb); #endif } else { clear_bit(HCI_RUNNING, &hdev->flags); diff -urN linux-2.4.21/drivers/char/Config.in linux-2.4.22/drivers/char/Config.in --- linux-2.4.21/drivers/char/Config.in 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/char/Config.in 2003-08-25 04:44:41.000000000 -0700 @@ -18,7 +18,7 @@ bool ' serial port on GSC support' CONFIG_SERIAL_GSC fi if [ "$CONFIG_IA64" = "y" ]; then - bool 'Support for serial console port described by EFI HCDP table' CONFIG_SERIAL_HCDP + bool ' Support for serial port described by EFI HCDP table' CONFIG_SERIAL_HCDP fi if [ "$CONFIG_ARCH_ACORN" = "y" ]; then tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL @@ -161,6 +161,9 @@ if [ "$CONFIG_PPC64" ] ; then bool 'pSeries Hypervisor Virtual Console support' CONFIG_HVC_CONSOLE fi +if [ "$CONFIG_ALL_PPC" = "y" ]; then + tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL +fi source drivers/i2c/Config.in @@ -306,6 +309,9 @@ bool ' Generic SiS support' CONFIG_AGP_SIS bool ' ALI chipset support' CONFIG_AGP_ALI bool ' Serverworks LE/HE support' CONFIG_AGP_SWORKS + if [ "$CONFIG_X86" = "y" ]; then + bool ' NVIDIA chipset support' CONFIG_AGP_NVIDIA + fi if [ "$CONFIG_IA64" = "y" ]; then bool ' HP ZX1 AGP support' CONFIG_AGP_HP_ZX1 fi diff -urN linux-2.4.21/drivers/char/Makefile linux-2.4.22/drivers/char/Makefile --- linux-2.4.21/drivers/char/Makefile 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/char/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -248,6 +248,7 @@ obj-$(CONFIG_INTEL_RNG) += i810_rng.o obj-$(CONFIG_AMD_RNG) += amd768_rng.o obj-$(CONFIG_AMD_PM768) += amd76x_pm.o +obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o obj-$(CONFIG_ITE_GPIO) += ite_gpio.o obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o diff -urN linux-2.4.21/drivers/char/agp/agp.h linux-2.4.22/drivers/char/agp/agp.h --- linux-2.4.21/drivers/char/agp/agp.h 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/char/agp/agp.h 2003-08-25 04:44:41.000000000 -0700 @@ -166,6 +166,9 @@ #ifndef PCI_DEVICE_ID_VIA_8363_0 #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #endif +#ifndef PCI_DEVICE_ID_VIA_8601_0 +#define PCI_DEVICE_ID_VIA_8601_0 0x0601 +#endif #ifndef PCI_DEVICE_ID_VIA_82C694X_0 #define PCI_DEVICE_ID_VIA_82C694X_0 0x0605 #endif @@ -184,6 +187,24 @@ #ifndef PCI_DEVICE_ID_INTEL_830_M_1 #define PCI_DEVICE_ID_INTEL_830_M_1 0x3577 #endif +#ifndef PCI_DEVICE_ID_INTEL_855_GM_0 +#define PCI_DEVICE_ID_INTEL_855_GM_0 0x3580 +#endif +#ifndef PCI_DEVICE_ID_INTEL_855_GM_1 +#define PCI_DEVICE_ID_INTEL_855_GM_1 0x3582 +#endif +#ifndef PCI_DEVICE_ID_INTEL_855_PM_0 +#define PCI_DEVICE_ID_INTEL_855_PM_0 0x3340 +#endif +#ifndef PCI_DEVICE_ID_INTEL_855_PM_1 +#define PCI_DEVICE_ID_INTEL_855_PM_1 0x3342 +#endif +#ifndef PCI_DEVICE_ID_INTEL_865_G_0 +#define PCI_DEVICE_ID_INTEL_865_G_0 0x2570 +#endif +#ifndef PCI_DEVICE_ID_INTEL_865_G_1 +#define PCI_DEVICE_ID_INTEL_865_G_1 0x2572 +#endif #ifndef PCI_DEVICE_ID_INTEL_820_0 #define PCI_DEVICE_ID_INTEL_820_0 0x2500 #endif @@ -280,6 +301,28 @@ #define INTEL_NBXCFG 0x50 #define INTEL_ERRSTS 0x91 +/* Intel 855GM/852GM registers */ +#define I855_GMCH_CTRL 0x52 +#define I855_GMCH_ENABLED 0x4 +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_STOLEN_0M 0x0 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I85X_CAPID 0x44 +#define I85X_VARIANT_MASK 0x7 +#define I85X_VARIANT_SHIFT 5 +#define I855_GME 0x0 +#define I855_GM 0x4 +#define I852_GME 0x2 +#define I852_GM 0x5 +#define I855_PME 0x0 +#define I855_PM 0x4 +#define I852_PME 0x2 +#define I852_PM 0x5 + /* intel i830 registers */ #define I830_GMCH_CTRL 0x52 #define I830_GMCH_ENABLED 0x4 @@ -412,6 +455,17 @@ #define SVWRKS_POSTFLUSH 0x14 #define SVWRKS_DIRFLUSH 0x0c +/* NVIDIA registers */ +#define NVIDIA_0_APBASE 0x10 +#define NVIDIA_0_APSIZE 0x80 +#define NVIDIA_1_WBC 0xf0 +#define NVIDIA_2_GARTCTRL 0xd0 +#define NVIDIA_2_APBASE 0xd8 +#define NVIDIA_2_APLIMIT 0xdc +#define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4) +#define NVIDIA_3_APBASE 0x50 +#define NVIDIA_3_APLIMIT 0x54 + /* HP ZX1 SBA registers */ #define HP_ZX1_CTRL 0x200 #define HP_ZX1_IBASE 0x300 diff -urN linux-2.4.21/drivers/char/agp/agpgart_be.c linux-2.4.22/drivers/char/agp/agpgart_be.c --- linux-2.4.21/drivers/char/agp/agpgart_be.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/char/agp/agpgart_be.c 2003-08-25 04:44:41.000000000 -0700 @@ -23,6 +23,12 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ + +/* + * Intel(R) 855GM/852GM and 865G support, added by + * David Dawes . + */ + #include #include #include @@ -43,6 +49,9 @@ #include #include #include +#ifdef CONFIG_AGP_NVIDIA + #include +#endif #include #include "agp.h" @@ -577,7 +586,7 @@ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) SetPageReserved(page); - agp_bridge.gatt_table_real = (unsigned long *) table; + agp_bridge.gatt_table_real = (u32 *) table; agp_gatt_table = (void *)table; #ifdef CONFIG_X86 err = change_page_attr(virt_to_page(table), 1<device != PCI_DEVICE_ID_INTEL_830_M_0 && + agp_bridge.dev->device != PCI_DEVICE_ID_INTEL_845_G_0) { + switch (gmch_ctrl & I855_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + gtt_entries = MB(1) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_4M: + gtt_entries = MB(4) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_8M: + gtt_entries = MB(8) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_16M: + gtt_entries = MB(16) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_32M: + gtt_entries = MB(32) - KB(132); + break; + default: + gtt_entries = 0; + break; + } + } else + { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: + gtt_entries = KB(512) - KB(132); + break; + case I830_GMCH_GMS_STOLEN_1024: + gtt_entries = MB(1) - KB(132); + break; + case I830_GMCH_GMS_STOLEN_8192: + gtt_entries = MB(8) - KB(132); + break; + case I830_GMCH_GMS_LOCAL: + rdct = INREG8(intel_i830_private.registers, + I830_RDRAM_CHANNEL_TYPE); + gtt_entries = (I830_RDRAM_ND(rdct) + 1) * + MB(ddt[I830_RDRAM_DDT(rdct)]); + local = 1; + break; + default: + gtt_entries = 0; + break; + } } + if (gtt_entries > 0) + printk(KERN_INFO PFX "Detected %dK %s memory.\n", + gtt_entries / KB(1), local ? "local" : "stolen"); + else + printk(KERN_INFO PFX + "No pre-allocated video memory detected.\n"); gtt_entries /= KB(4); intel_i830_private.gtt_entries = gtt_entries; @@ -1192,9 +1231,16 @@ u16 gmch_ctrl; aper_size_info_fixed *values; - pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl); values = A_SIZE_FIX(agp_bridge.aperture_sizes); + if (agp_bridge.dev->device != PCI_DEVICE_ID_INTEL_830_M_0 && + agp_bridge.dev->device != PCI_DEVICE_ID_INTEL_845_G_0) { + agp_bridge.previous_size = agp_bridge.current_size = (void *) values; + agp_bridge.aperture_size_idx = 0; + return(values[0].size); + } + + pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl); if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { agp_bridge.previous_size = agp_bridge.current_size = (void *) values; agp_bridge.aperture_size_idx = 0; @@ -2450,8 +2496,8 @@ return retval; } - agp_bridge.gatt_table_real = page_dir.real; - agp_bridge.gatt_table = page_dir.remapped; + agp_bridge.gatt_table_real = (u32 *)page_dir.real; + agp_bridge.gatt_table = (u32 *)page_dir.remapped; agp_bridge.gatt_bus_addr = virt_to_bus(page_dir.real); /* Get the address for the gart region. @@ -2477,8 +2523,8 @@ { amd_page_map page_dir; - page_dir.real = agp_bridge.gatt_table_real; - page_dir.remapped = agp_bridge.gatt_table; + page_dir.real = (unsigned long *)agp_bridge.gatt_table_real; + page_dir.remapped = (unsigned long *)agp_bridge.gatt_table; amd_free_gatt_pages(); amd_free_page_map(&page_dir); @@ -3559,8 +3605,8 @@ return retval; } - agp_bridge.gatt_table_real = page_dir.real; - agp_bridge.gatt_table = page_dir.remapped; + agp_bridge.gatt_table_real = (u32 *)page_dir.real; + agp_bridge.gatt_table = (u32 *)page_dir.remapped; agp_bridge.gatt_bus_addr = virt_to_bus(page_dir.real); /* Get the address for the gart region. @@ -3588,8 +3634,8 @@ { serverworks_page_map page_dir; - page_dir.real = agp_bridge.gatt_table_real; - page_dir.remapped = agp_bridge.gatt_table; + page_dir.real = (unsigned long *)agp_bridge.gatt_table_real; + page_dir.remapped = (unsigned long *)agp_bridge.gatt_table; serverworks_free_gatt_pages(); serverworks_free_page_map(&page_dir); @@ -4003,6 +4049,330 @@ #endif /* CONFIG_AGP_SWORKS */ +#ifdef CONFIG_AGP_NVIDIA + +static struct _nvidia_private { + struct pci_dev *dev_1; + struct pci_dev *dev_2; + struct pci_dev *dev_3; + volatile u32 *aperture; + int num_active_entries; + off_t pg_offset; +} nvidia_private; + +static int nvidia_fetch_size(void) +{ + int i; + u8 size_value; + aper_size_info_8 *values; + + pci_read_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE, &size_value); + size_value &= 0x0f; + values = A_SIZE_8(agp_bridge.aperture_sizes); + + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { + if (size_value == values[i].size_value) { + agp_bridge.previous_size = + agp_bridge.current_size = (void *) (values + i); + agp_bridge.aperture_size_idx = i; + return values[i].size; + } + } + + return 0; +} + +#define SYSCFG 0xC0010010 +#define IORR_BASE0 0xC0010016 +#define IORR_MASK0 0xC0010017 +#define AMD_K7_NUM_IORR 2 + +static int nvidia_init_iorr(u32 base, u32 size) +{ + u32 base_hi, base_lo; + u32 mask_hi, mask_lo; + u32 sys_hi, sys_lo; + u32 iorr_addr, free_iorr_addr; + + /* Find the iorr that is already used for the base */ + /* If not found, determine the uppermost available iorr */ + free_iorr_addr = AMD_K7_NUM_IORR; + for(iorr_addr = 0; iorr_addr < AMD_K7_NUM_IORR; iorr_addr++) { + rdmsr(IORR_BASE0 + 2 * iorr_addr, base_lo, base_hi); + rdmsr(IORR_MASK0 + 2 * iorr_addr, mask_lo, mask_hi); + + if ((base_lo & 0xfffff000) == (base & 0xfffff000)) + break; + + if ((mask_lo & 0x00000800) == 0) + free_iorr_addr = iorr_addr; + } + + if (iorr_addr >= AMD_K7_NUM_IORR) { + iorr_addr = free_iorr_addr; + if (iorr_addr >= AMD_K7_NUM_IORR) + return -EINVAL; + } + + base_hi = 0x0; + base_lo = (base & ~0xfff) | 0x18; + mask_hi = 0xf; + mask_lo = ((~(size - 1)) & 0xfffff000) | 0x800; + wrmsr(IORR_BASE0 + 2 * iorr_addr, base_lo, base_hi); + wrmsr(IORR_MASK0 + 2 * iorr_addr, mask_lo, mask_hi); + + rdmsr(SYSCFG, sys_lo, sys_hi); + sys_lo |= 0x00100000; + wrmsr(SYSCFG, sys_lo, sys_hi); + + return 0; +} + +static int nvidia_configure(void) +{ + int i, rc, num_dirs; + u32 apbase, aplimit; + aper_size_info_8 *current_size; + u32 temp; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, NVIDIA_0_APBASE, &apbase); + apbase &= PCI_BASE_ADDRESS_MEM_MASK; + agp_bridge.gart_bus_addr = apbase; + aplimit = apbase + (current_size->size * 1024 * 1024) - 1; + pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APBASE, apbase); + pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APLIMIT, aplimit); + pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APBASE, apbase); + pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APLIMIT, aplimit); + if (0 != (rc = nvidia_init_iorr(apbase, current_size->size * 1024 * 1024))) + return rc; + + /* directory size is 64k */ + num_dirs = current_size->size / 64; + nvidia_private.num_active_entries = current_size->num_entries; + nvidia_private.pg_offset = 0; + if (num_dirs == 0) { + num_dirs = 1; + nvidia_private.num_active_entries /= (64 / current_size->size); + nvidia_private.pg_offset = (apbase & (64 * 1024 * 1024 - 1) & + ~(current_size->size * 1024 * 1024 - 1)) / PAGE_SIZE; + } + + /* attbase */ + for(i = 0; i < 8; i++) { + pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_ATTBASE(i), + (agp_bridge.gatt_bus_addr + (i % num_dirs) * 64 * 1024) | 1); + } + + /* gtlb control */ + pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp); + pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, + temp | 0x11); + + /* gart control */ + pci_read_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, &temp); + pci_write_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, + temp | 0x100); + + /* map aperture */ + nvidia_private.aperture = + (volatile u32 *) ioremap(apbase, 33 * PAGE_SIZE); + + return 0; +} + +static void nvidia_cleanup(void) +{ + aper_size_info_8 *previous_size; + u32 temp; + + /* gart control */ + pci_read_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, &temp); + pci_write_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, + temp & ~(0x100)); + + /* gtlb control */ + pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp); + pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, + temp & ~(0x11)); + + /* unmap aperture */ + iounmap((void *) nvidia_private.aperture); + + /* restore previous aperture size */ + previous_size = A_SIZE_8(agp_bridge.previous_size); + pci_write_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE, + previous_size->size_value); + + /* restore iorr for previous aperture size */ + nvidia_init_iorr(agp_bridge.gart_bus_addr, + previous_size->size * 1024 * 1024); +} + +static void nvidia_tlbflush(agp_memory * mem) +{ + int i; + unsigned long end; + u32 wbc_reg, wbc_mask, temp; + + /* flush chipset */ + switch(agp_bridge.type) { + case NVIDIA_NFORCE: + wbc_mask = 0x00010000; + break; + case NVIDIA_NFORCE2: + wbc_mask = 0x80000000; + break; + default: + wbc_mask = 0; + break; + } + + if (wbc_mask) { + pci_read_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, &wbc_reg); + wbc_reg |= wbc_mask; + pci_write_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, wbc_reg); + + end = jiffies + 3*HZ; + do { + pci_read_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, &wbc_reg); + if ((signed)(end - jiffies) <= 0) { + printk(KERN_ERR "TLB flush took more than 3 seconds.\n"); + } + } while (wbc_reg & wbc_mask); + } + + /* flush TLB entries */ + for(i = 0; i < 32 + 1; i++) + temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)]; + for(i = 0; i < 32 + 1; i++) + temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)]; +} + +static unsigned long nvidia_mask_memory(unsigned long addr, int type) +{ + /* Memory type is ignored */ + + return addr | agp_bridge.masks[0].mask; +} + +static int nvidia_insert_memory(agp_memory * mem, + off_t pg_start, int type) +{ + int i, j; + + if ((type != 0) || (mem->type != 0)) + return -EINVAL; + + if ((pg_start + mem->page_count) > + (nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE)) + return -EINVAL; + + for(j = pg_start; j < (pg_start + mem->page_count); j++) { + if (!PGE_EMPTY(agp_bridge.gatt_table[nvidia_private.pg_offset + j])) { + return -EBUSY; + } + } + + if (mem->is_flushed == FALSE) { + CACHE_FLUSH(); + mem->is_flushed = TRUE; + } + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { + agp_bridge.gatt_table[nvidia_private.pg_offset + j] = agp_bridge.mask_memory(mem->memory[i], mem->type); + } + + agp_bridge.tlb_flush(mem); + return 0; +} + +static int nvidia_remove_memory(agp_memory * mem, off_t pg_start, + int type) +{ + int i; + + if ((type != 0) || (mem->type != 0)) + return -EINVAL; + + for (i = pg_start; i < (mem->page_count + pg_start); i++) { + agp_bridge.gatt_table[nvidia_private.pg_offset + i] = + (unsigned long) agp_bridge.scratch_page; + } + + agp_bridge.tlb_flush(mem); + return 0; +} + +static aper_size_info_8 nvidia_generic_sizes[5] = +{ + {512, 131072, 7, 0}, + {256, 65536, 6, 8}, + {128, 32768, 5, 12}, + {64, 16384, 4, 14}, + /* The 32M mode still requires a 64k gatt */ + {32, 16384, 4, 15} +}; + +static gatt_mask nvidia_generic_masks[] = +{ + {0x00000001, 0} +}; + +static int __init nvidia_generic_setup (struct pci_dev *pdev) +{ + nvidia_private.dev_1 = + pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); + nvidia_private.dev_2 = + pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); + nvidia_private.dev_3 = + pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); + + if((nvidia_private.dev_1 == NULL) || + (nvidia_private.dev_2 == NULL) || + (nvidia_private.dev_3 == NULL)) { + printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " + "nForce/nForce2 chipset, but could not find " + "the secondary devices.\n"); + agp_bridge.type = NOT_SUPPORTED; + return -ENODEV; + } + + agp_bridge.masks = nvidia_generic_masks; + agp_bridge.aperture_sizes = (void *) nvidia_generic_sizes; + agp_bridge.size_type = U8_APER_SIZE; + agp_bridge.num_aperture_sizes = 5; + agp_bridge.dev_private_data = (void *) &nvidia_private; + agp_bridge.needs_scratch_page = FALSE; + agp_bridge.configure = nvidia_configure; + agp_bridge.fetch_size = nvidia_fetch_size; + agp_bridge.cleanup = nvidia_cleanup; + agp_bridge.tlb_flush = nvidia_tlbflush; + agp_bridge.mask_memory = nvidia_mask_memory; + agp_bridge.agp_enable = agp_generic_agp_enable; + agp_bridge.cache_flush = global_cache_flush; + agp_bridge.create_gatt_table = agp_generic_create_gatt_table; + agp_bridge.free_gatt_table = agp_generic_free_gatt_table; + agp_bridge.insert_memory = nvidia_insert_memory; + agp_bridge.remove_memory = nvidia_remove_memory; + agp_bridge.alloc_by_type = agp_generic_alloc_by_type; + agp_bridge.free_by_type = agp_generic_free_by_type; + agp_bridge.agp_alloc_page = agp_generic_alloc_page; + agp_bridge.agp_destroy_page = agp_generic_destroy_page; + agp_bridge.suspend = agp_generic_suspend; + agp_bridge.resume = agp_generic_resume; + agp_bridge.cant_use_aperture = 0; + + return 0; +} + +#endif /* CONFIG_AGP_NVIDIA */ + #ifdef CONFIG_AGP_HP_ZX1 #ifndef log2 @@ -4516,15 +4886,38 @@ { PCI_DEVICE_ID_INTEL_830_M_0, PCI_VENDOR_ID_INTEL, INTEL_I830_M, - "Intel", - "i830M", + "Intel(R)", + "830M", intel_830mp_setup }, - { PCI_DEVICE_ID_INTEL_845_G_0, + + { PCI_DEVICE_ID_INTEL_845_G_0, PCI_VENDOR_ID_INTEL, INTEL_I845_G, - "Intel", - "i845G", + "Intel(R)", + "845G", + intel_845_setup }, + + { PCI_DEVICE_ID_INTEL_855_GM_0, + PCI_VENDOR_ID_INTEL, + INTEL_I855_PM, + "Intel(R)", + "855PM", + intel_845_setup }, + + { PCI_DEVICE_ID_INTEL_855_PM_0, + PCI_VENDOR_ID_INTEL, + INTEL_I855_PM, + "Intel(R)", + "855PM", + intel_845_setup }, + + { PCI_DEVICE_ID_INTEL_865_G_0, + PCI_VENDOR_ID_INTEL, + INTEL_I865_G, + "Intel(R)", + "865G", intel_845_setup }, + { PCI_DEVICE_ID_INTEL_840_0, PCI_VENDOR_ID_INTEL, INTEL_I840, @@ -4565,12 +4958,24 @@ "SiS", "740", sis_generic_setup }, + { PCI_DEVICE_ID_SI_651, + PCI_VENDOR_ID_SI, + SIS_GENERIC, + "SiS", + "651", + sis_generic_setup }, { PCI_DEVICE_ID_SI_650, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "650", sis_generic_setup }, + { PCI_DEVICE_ID_SI_651, + PCI_VENDOR_ID_SI, + SIS_GENERIC, + "SiS", + "651", + sis_generic_setup }, { PCI_DEVICE_ID_SI_645, PCI_VENDOR_ID_SI, SIS_GENERIC, @@ -4583,6 +4988,12 @@ "SiS", "646", sis_generic_setup }, + { PCI_DEVICE_ID_SI_648, + PCI_VENDOR_ID_SI, + SIS_GENERIC, + "SiS", + "648", + sis_generic_setup }, { PCI_DEVICE_ID_SI_735, PCI_VENDOR_ID_SI, SIS_GENERIC, @@ -4595,6 +5006,12 @@ "SiS", "745", sis_generic_setup }, + { PCI_DEVICE_ID_SI_746, + PCI_VENDOR_ID_SI, + SIS_GENERIC, + "SiS", + "746", + sis_generic_setup }, { PCI_DEVICE_ID_SI_730, PCI_VENDOR_ID_SI, SIS_GENERIC, @@ -4658,6 +5075,12 @@ "Via", "MVP3", via_generic_setup }, + { PCI_DEVICE_ID_VIA_8601_0, + PCI_VENDOR_ID_VIA, + VIA_APOLLO_PLE133, + "Via", + "Apollo PLE133", + via_generic_setup }, { PCI_DEVICE_ID_VIA_82C691_0, PCI_VENDOR_ID_VIA, VIA_APOLLO_PRO, @@ -4682,17 +5105,29 @@ "Via", "Apollo Pro KT266", via_generic_setup }, + { PCI_DEVICE_ID_VIA_8375, + PCI_VENDOR_ID_VIA, + VIA_APOLLO_KM266, + "Via", + "Apollo Pro KM266 / KL266", + via_generic_setup }, + { PCI_DEVICE_ID_VIA_8377_0, + PCI_VENDOR_ID_VIA, + VIA_APOLLO_KT400, + "Via", + "Apollo Pro KT400", + via_generic_setup }, { PCI_DEVICE_ID_VIA_8377_0, PCI_VENDOR_ID_VIA, VIA_APOLLO_KT400, "Via", "Apollo Pro KT400", via_generic_setup }, - { PCI_DEVICE_ID_VIA_P4X333, + { PCI_DEVICE_ID_VIA_P4M266, PCI_VENDOR_ID_VIA, - VIA_APOLLO_P4X400, + VIA_APOLLO_P4M266, "Via", - "Apollo P4X400", + "Apollo P4M266", via_generic_setup }, { 0, PCI_VENDOR_ID_VIA, @@ -4702,6 +5137,27 @@ via_generic_setup }, #endif /* CONFIG_AGP_VIA */ +#ifdef CONFIG_AGP_NVIDIA + { PCI_DEVICE_ID_NVIDIA_NFORCE, + PCI_VENDOR_ID_NVIDIA, + NVIDIA_NFORCE, + "NVIDIA", + "nForce", + nvidia_generic_setup }, + { PCI_DEVICE_ID_NVIDIA_NFORCE2, + PCI_VENDOR_ID_NVIDIA, + NVIDIA_NFORCE2, + "NVIDIA", + "nForce2", + nvidia_generic_setup }, + { 0, + PCI_VENDOR_ID_NVIDIA, + NVIDIA_GENERIC, + "NVIDIA", + "Generic", + nvidia_generic_setup }, +#endif /* CONFIG_AGP_NVIDIA */ + #ifdef CONFIG_AGP_HP_ZX1 { PCI_DEVICE_ID_HP_ZX1_LBA, PCI_VENDOR_ID_HP, @@ -4888,10 +5344,14 @@ * with an external graphics * card. It will be initialized later */ + printk(KERN_ERR PFX "Detected an " + "Intel(R) 845G, but could not find the" + " secondary device. Assuming a " + "non-integrated video card.\n"); agp_bridge.type = INTEL_I845_G; break; } - printk(KERN_INFO PFX "Detected an Intel " + printk(KERN_INFO PFX "Detected an Intel(R) " "845G Chipset.\n"); agp_bridge.type = INTEL_I810; return intel_i830_setup(i810_dev); @@ -4913,10 +5373,118 @@ agp_bridge.type = INTEL_I830_M; break; } - printk(KERN_INFO PFX "Detected an Intel " + printk(KERN_INFO PFX "Detected an Intel(R) " "830M Chipset.\n"); agp_bridge.type = INTEL_I810; return intel_i830_setup(i810_dev); + case PCI_DEVICE_ID_INTEL_855_GM_0: + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_855_GM_1, NULL); + if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) { + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_855_GM_1, i810_dev); + } + if (i810_dev == NULL) { + /* + * We probably have an 855PM chipset + * with an external graphics + * card. It will be initialized later. + */ + agp_bridge.type = INTEL_I855_PM; + break; + } + { + u32 capval = 0; + const char *name = "855GM/852GM"; + + pci_read_config_dword(dev, I85X_CAPID, &capval); + switch ((capval >> I85X_VARIANT_SHIFT) & + I85X_VARIANT_MASK) { + case I855_GME: + name = "855GME"; + break; + case I855_GM: + name = "855GM"; + break; + case I852_GME: + name = "852GME"; + break; + case I852_GM: + name = "852GM"; + break; + } + printk(KERN_INFO PFX "Detected an Intel(R) " + "%s Chipset.\n", name); + } + agp_bridge.type = INTEL_I810; + return intel_i830_setup(i810_dev); + case PCI_DEVICE_ID_INTEL_855_PM_0: + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_855_PM_1, NULL); + if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) { + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_855_PM_1, i810_dev); + } + if (i810_dev == NULL) { + /* + * We probably have an 855PM chipset + * with an external graphics + * card. It will be initialized later. + */ + agp_bridge.type = INTEL_I855_PM; + break; + } + { + u32 capval = 0; + const char *name = "855PM/852PM"; + + pci_read_config_dword(dev, I85X_CAPID, &capval); + switch ((capval >> I85X_VARIANT_SHIFT) & + I85X_VARIANT_MASK) { + case I855_PME: + name = "855PME"; + break; + case I855_PM: + name = "855PM"; + break; + case I852_PME: + name = "852PME"; + break; + case I852_PM: + name = "852PM"; + break; + } + printk(KERN_INFO PFX "Detected an Intel(R) " + "%s Chipset.\n", name); + } + agp_bridge.type = INTEL_I810; + return intel_i830_setup(i810_dev); + case PCI_DEVICE_ID_INTEL_865_G_0: + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_865_G_1, NULL); + if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) { + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_865_G_1, i810_dev); + } + + if (i810_dev == NULL) { + /* + * We probably have a 865G chipset + * with an external graphics + * card. It will be initialized later + */ + printk(KERN_ERR PFX "Detected an " + "Intel(R) 865G, but could not" + " find the" + " secondary device. Assuming a " + "non-integrated video card.\n"); + agp_bridge.type = INTEL_I865_G; + break; + } + printk(KERN_INFO PFX "Detected an Intel(R) " + "865G Chipset.\n"); + agp_bridge.type = INTEL_I810; + return intel_i830_setup(i810_dev); default: break; } @@ -5012,7 +5580,11 @@ { long memory, index, result; - memory = (num_physpages << PAGE_SHIFT) >> 20; +#if PAGE_SHIFT < 20 + memory = num_physpages >> (20 - PAGE_SHIFT); +#else + memory = num_physpages << (PAGE_SHIFT - 20); +#endif index = 1; while ((memory > maxes_table[index].mem) && diff -urN linux-2.4.21/drivers/char/amd76x_pm.c linux-2.4.22/drivers/char/amd76x_pm.c --- linux-2.4.21/drivers/char/amd76x_pm.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/char/amd76x_pm.c 2003-08-25 04:44:41.000000000 -0700 @@ -78,6 +78,7 @@ #include #include #include +#include #include "amd76x_pm.h" diff -urN linux-2.4.21/drivers/char/au1000_gpio.c linux-2.4.22/drivers/char/au1000_gpio.c --- linux-2.4.21/drivers/char/au1000_gpio.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/au1000_gpio.c 2003-08-25 04:44:41.000000000 -0700 @@ -86,7 +86,7 @@ #ifdef CONFIG_USB_OHCI avail_mask &= ~((1<<4) | (1<<11)); -#ifndef CONFIG_AU1000_USB_DEVICE +#ifndef CONFIG_AU1X00_USB_DEVICE avail_mask &= ~((1<<5) | (1<<13)); #endif #endif diff -urN linux-2.4.21/drivers/char/au1000_ts.c linux-2.4.22/drivers/char/au1000_ts.c --- linux-2.4.21/drivers/char/au1000_ts.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/au1000_ts.c 2003-08-25 04:44:41.000000000 -0700 @@ -261,7 +261,7 @@ calc_clkdiv(int baud) { u32 sys_busclk = - (get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2); + (get_au1x00_speed() / (int)(inl(SYS_POWERCTRL)&0x03) + 2); return (sys_busclk / (2 * baud)) - 1; } @@ -269,7 +269,7 @@ calc_baudrate(u32 clkdiv) { u32 sys_busclk = - (get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2); + (get_au1x00_speed() / (int)(inl(SYS_POWERCTRL)&0x03) + 2); return sys_busclk / (2 * (clkdiv + 1)); } @@ -642,7 +642,7 @@ ts->y_plate_ohms = DEFAULT_Y_PLATE_OHMS; // set GPIO to SSI0 function - outl(inl(PIN_FUNCTION) & ~1, PIN_FUNCTION); + outl(inl(SYS_PINFUNC) & ~1, SYS_PINFUNC); // enable SSI0 clock and bring SSI0 out of reset outl(0, SSI0_CONTROL); diff -urN linux-2.4.21/drivers/char/au1000_usbraw.c linux-2.4.22/drivers/char/au1000_usbraw.c --- linux-2.4.21/drivers/char/au1000_usbraw.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/au1000_usbraw.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,575 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1x00 USB Device-Side Raw Block Driver (function layer) + * + * Copyright 2001-2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef DEBUG +#include + +#include +#include +#include +#include +#include + +#define USBRAW_MAJOR 190 // FIXME: need a legal major +#define USBRAW_NAME "usbraw" + +#define MAX_NUM_PORTS 2 + +#define IN_MAX_PACKET_SIZE 64 +#define OUT_MAX_PACKET_SIZE 64 + +// FIXME: when Au1x00 endpoints 3 and 5 are fixed, make NUM_PORTS=2 +#define NUM_PORTS 1 +#define NUM_EP 2*NUM_PORTS + +#define CONFIG_DESC_LEN \ + USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE + +/* must be power of two */ +#define READ_BUF_SIZE (1<<12) + +struct usb_raw_port { + unsigned char number; + spinlock_t port_lock; + + struct usb_endpoint_descriptor* out_desc; + struct usb_endpoint_descriptor* in_desc; + + int out_ep_addr; /* endpoint address of OUT endpoint */ + int in_ep_addr; /* endpoint address of IN endpoint */ + + __u8 read_buf[READ_BUF_SIZE]; // FIXME: allocate with get_free_pages + int read_nextin, read_nextout; + int read_count; + + wait_queue_head_t wait; + struct fasync_struct *fasync; // asynch notification + + int active; /* someone has this device open */ + int open_count; /* number of times this port has been opened */ +}; + +static struct usb_serial { + struct usb_device_descriptor* dev_desc; + struct usb_config_descriptor* config_desc; + struct usb_interface_descriptor* if_desc; + struct usb_string_descriptor * str_desc[6]; + void* str_desc_buf; + + usbdev_state_t dev_state; + + struct usb_raw_port port[NUM_PORTS]; +} usbraw; + +static struct usb_device_descriptor dev_desc = { + bLength:USB_DT_DEVICE_SIZE, + bDescriptorType:USB_DT_DEVICE, + bcdUSB:USBDEV_REV, //usb rev + bDeviceClass:USB_CLASS_PER_INTERFACE, //class (none) + bDeviceSubClass:0x00, //subclass (none) + bDeviceProtocol:0x00, //protocol (none) + bMaxPacketSize0:USBDEV_EP0_MAX_PACKET_SIZE, //max packet size for ep0 + idVendor:0x6d04, //vendor id + idProduct:0x0bc0, //product id + bcdDevice:0x0001, //BCD rev 0.1 + iManufacturer:0x01, //manufactuer string index + iProduct:0x02, //product string index + iSerialNumber:0x03, //serial# string index + bNumConfigurations:0x01 //num configurations +}; + +static struct usb_endpoint_descriptor ep_desc[] = { + { + // Bulk IN for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk IN for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + } +}; + +static struct usb_interface_descriptor if_desc = { + bLength:USB_DT_INTERFACE_SIZE, + bDescriptorType:USB_DT_INTERFACE, + bInterfaceNumber:0x00, + bAlternateSetting:0x00, + bNumEndpoints:NUM_EP, + bInterfaceClass:0xff, + bInterfaceSubClass:0xab, + bInterfaceProtocol:0x00, + iInterface:0x05 +}; + +static struct usb_config_descriptor config_desc = { + bLength:USB_DT_CONFIG_SIZE, + bDescriptorType:USB_DT_CONFIG, + wTotalLength:CONFIG_DESC_LEN, + bNumInterfaces:0x01, + bConfigurationValue:0x01, + iConfiguration:0x04, // configuration string + bmAttributes:0xc0, // self-powered + MaxPower:20 // 40 mA +}; + +// String[0] is a list of Language IDs supported by this device +static struct usb_string_descriptor string_desc0 = { + bLength:4, + bDescriptorType:USB_DT_STRING, + wData:{0x0409} // English, US +}; + +// These strings will be converted to Unicode in string_desc[] +static char *strings[5] = { + "Alchemy Semiconductor", // iManufacturer + "USB Raw Block Device", // iProduct + "0.1", // iSerialNumber + "USB Raw Config", // iConfiguration + "USB Raw Interface" // iInterface +}; + + +static void +receive_callback(struct usb_raw_port *port) +{ + int i, pkt_size; + usbdev_pkt_t* pkt; + + if ((pkt_size = usbdev_receive_packet(port->out_ep_addr, + &pkt)) <= 0) { + dbg(__FUNCTION__ ": usbdev_receive_packet returns %d", + pkt_size); + return; + } + + dbg(__FUNCTION__ ": ep%d, size=%d", port->out_ep_addr, pkt_size); + + spin_lock(&port->port_lock); + for (i=0; i < pkt_size; i++) { + port->read_buf[port->read_nextin++] = pkt->payload[i]; + port->read_nextin &= (READ_BUF_SIZE - 1); + if (++port->read_count == READ_BUF_SIZE) + break; + } + spin_unlock(&port->port_lock); + + /* free the packet */ + kfree(pkt); + + // async notify + if (port->fasync) + kill_fasync(&port->fasync, SIGIO, POLL_IN); + // wake up any read call + if (waitqueue_active(&port->wait)) + wake_up_interruptible(&port->wait); +} + +static void +transmit_callback(struct usb_raw_port *port, usbdev_pkt_t* pkt) +{ + dbg(__FUNCTION__ ": ep%d", port->in_ep_addr); + /* just free the returned packet */ + kfree(pkt); +} + + +static void +usbraw_callback(usbdev_cb_type_t cb_type, unsigned long arg, void* data) +{ + usbdev_pkt_t* pkt; + int i; + + switch (cb_type) { + case CB_NEW_STATE: + usbraw.dev_state = (usbdev_state_t)arg; + break; + case CB_PKT_COMPLETE: + pkt = (usbdev_pkt_t*)arg; + for (i=0; iep_addr == port->in_ep_addr) { + transmit_callback(port, pkt); + break; + } else if (pkt->ep_addr == port->out_ep_addr) { + receive_callback(port); + break; + } + } + break; + } +} + +/***************************************************************************** + * Here begins the driver interface functions + *****************************************************************************/ + +static unsigned int usbraw_poll(struct file * filp, poll_table * wait) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + unsigned long flags; + int count; + + poll_wait(filp, &port->wait, wait); + + spin_lock_irqsave(&port->port_lock, flags); + count = port->read_count; + spin_unlock_irqrestore(&port->port_lock, flags); + + if (count > 0) { + dbg(__FUNCTION__ ": count=%d", count); + return POLLIN | POLLRDNORM; + } + + return 0; +} + +static int usbraw_fasync(int fd, struct file *filp, int mode) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + return fasync_helper(fd, filp, mode, &port->fasync); +} + +static int usbraw_open(struct inode * inode, struct file *filp) +{ + int portNumber; + struct usb_raw_port *port; + unsigned long flags; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbraw.dev_state != CONFIGURED) + return -ENODEV; + + MOD_INC_USE_COUNT; + + /* set up our port structure making the tty driver remember + our port object, and us it */ + portNumber = MINOR(inode->i_rdev); + port = &usbraw.port[portNumber]; + filp->private_data = port; + + dbg(__FUNCTION__ ": port %d", port->number); + + spin_lock_irqsave(&port->port_lock, flags); + + ++port->open_count; + + if (!port->active) { + port->active = 1; + } + + /* flush read buffer */ + port->read_nextin = port->read_nextout = port->read_count = 0; + + spin_unlock_irqrestore(&port->port_lock, flags); + + return 0; +} + +static int usbraw_release(struct inode * inode, struct file * filp) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + unsigned long flags; + + dbg(__FUNCTION__ ": port %d", port->number); + + if (!port->active) { + err(__FUNCTION__ ": port not opened"); + return -ENODEV; + } + + usbraw_fasync(-1, filp, 0); + + spin_lock_irqsave(&port->port_lock, flags); + + --port->open_count; + + if (port->open_count <= 0) { + port->active = 0; + port->open_count = 0; + } + + spin_unlock_irqrestore(&port->port_lock, flags); + MOD_DEC_USE_COUNT; + return 0; +} + + +static ssize_t usbraw_read(struct file * filp, char * buf, + size_t count, loff_t * l) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + unsigned long flags; + int i, cnt; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbraw.dev_state != CONFIGURED) + return -ENODEV; + + do { + spin_lock_irqsave(&port->port_lock, flags); + cnt = port->read_count; + spin_unlock_irqrestore(&port->port_lock, flags); + if (cnt == 0) { + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + interruptible_sleep_on(&port->wait); + if (signal_pending(current)) + return -ERESTARTSYS; + } + } while (cnt == 0); + + count = (count > cnt) ? cnt : count; + + for (i=0; iread_buf[port->read_nextout++], &buf[i]); + port->read_nextout &= (READ_BUF_SIZE - 1); + spin_lock_irqsave(&port->port_lock, flags); + port->read_count--; + spin_unlock_irqrestore(&port->port_lock, flags); + if (port->read_count == 0) + break; + } + + return i+1; +} + +static ssize_t usbraw_write(struct file * filp, const char * buf, + size_t count, loff_t *ppos) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + usbdev_pkt_t* pkt; + int ret, max_pkt_sz; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbraw.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not opened"); + return -EINVAL; + } + + if (count == 0) { + dbg(__FUNCTION__ ": write request of 0 bytes"); + return (0); + } + + max_pkt_sz = port->in_desc->wMaxPacketSize; + count = (count > max_pkt_sz) ? max_pkt_sz : count; + + if ((ret = usbdev_alloc_packet(port->in_ep_addr, count, &pkt)) < 0) + return ret; + + copy_from_user(pkt->payload, buf, count); + + return usbdev_send_packet(port->in_ep_addr, pkt); +} + +static int usbraw_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -ENODEV; + } + // FIXME: need any IOCTLs? + + return -ENOIOCTLCMD; +} + + +static struct file_operations usbraw_fops = { + owner: THIS_MODULE, + write: usbraw_write, + read: usbraw_read, + poll: usbraw_poll, + ioctl: usbraw_ioctl, + fasync: usbraw_fasync, + open: usbraw_open, + release: usbraw_release, +}; + +void usbfn_raw_exit(void) +{ + /* kill the device layer */ + usbdev_exit(); + + unregister_chrdev(USBRAW_MAJOR, USBRAW_NAME); + + if (usbraw.str_desc_buf) + kfree(usbraw.str_desc_buf); +} + + +int usbfn_raw_init(void) +{ + int ret = 0, i, str_desc_len; + + /* register our character device */ + if ((ret = register_chrdev(USBRAW_MAJOR, USBRAW_NAME, + &usbraw_fops)) < 0) { + err("can't get major number"); + return ret; + } + info("registered"); + + /* + * initialize pointers to descriptors + */ + usbraw.dev_desc = &dev_desc; + usbraw.config_desc = &config_desc; + usbraw.if_desc = &if_desc; + + /* + * initialize the string descriptors + */ + + /* alloc buffer big enough for all string descriptors */ + str_desc_len = string_desc0.bLength; + for (i = 0; i < 5; i++) + str_desc_len += 2 + 2 * strlen(strings[i]); + usbraw.str_desc_buf = (void *) kmalloc(str_desc_len, GFP_KERNEL); + if (!usbraw.str_desc_buf) { + err(__FUNCTION__ ": failed to alloc string descriptors"); + ret = -ENOMEM; + goto out; + } + + usbraw.str_desc[0] = + (struct usb_string_descriptor *)usbraw.str_desc_buf; + memcpy(usbraw.str_desc[0], &string_desc0, string_desc0.bLength); + usbraw.str_desc[1] = (struct usb_string_descriptor *) + (usbraw.str_desc_buf + string_desc0.bLength); + for (i = 1; i < 6; i++) { + struct usb_string_descriptor *desc = usbraw.str_desc[i]; + char *str = strings[i - 1]; + int j, str_len = strlen(str); + + desc->bLength = 2 + 2 * str_len; + desc->bDescriptorType = USB_DT_STRING; + for (j = 0; j < str_len; j++) { + desc->wData[j] = (u16) str[j]; + } + if (i < 5) + usbraw.str_desc[i + 1] = + (struct usb_string_descriptor *) + ((u8 *) desc + desc->bLength); + } + + /* + * start the device layer. The device layer assigns us + * our endpoint addresses + */ + if ((ret = usbdev_init(&dev_desc, &config_desc, &if_desc, ep_desc, + usbraw.str_desc, usbraw_callback, NULL))) { + err(__FUNCTION__ ": device-layer init failed"); + goto out; + } + + /* initialize the devfs nodes for this device and let the user + know what ports we are bound to */ + for (i = 0; i < NUM_PORTS; ++i) { + struct usb_raw_port *port = &usbraw.port[i]; + + port->number = i; + port->in_desc = &ep_desc[NUM_PORTS*i]; + port->out_desc = &ep_desc[NUM_PORTS*i + 1]; + port->in_ep_addr = port->in_desc->bEndpointAddress & 0x0f; + port->out_ep_addr = port->out_desc->bEndpointAddress & 0x0f; + init_waitqueue_head(&port->wait); + spin_lock_init(&port->port_lock); + } + + out: + if (ret) + usbfn_raw_exit(); + return ret; +} + + +/* Module information */ +MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com"); +MODULE_DESCRIPTION("Au1x00 USB Device-Side Raw Block Driver"); +MODULE_LICENSE("GPL"); + +module_init(usbfn_raw_init); +module_exit(usbfn_raw_exit); diff -urN linux-2.4.21/drivers/char/au1000_usbtty.c linux-2.4.22/drivers/char/au1000_usbtty.c --- linux-2.4.21/drivers/char/au1000_usbtty.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/au1000_usbtty.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,764 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1x00 USB Device-Side Serial TTY Driver (function layer) + * + * Copyright 2001-2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * Derived from drivers/usb/serial/usbserial.c: + * + * Copyright (C) 1999 - 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (c) 2000 Peter Berger (pberger@brimson.com) + * Copyright (c) 2000 Al Borchers (borchers@steinerpoint.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef DEBUG +#include + +#include +#include +#include +#include +#include + + +/* local function prototypes */ +static int serial_open(struct tty_struct *tty, struct file *filp); +static void serial_close(struct tty_struct *tty, struct file *filp); +static int serial_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count); +static int serial_write_room(struct tty_struct *tty); +static int serial_chars_in_buffer(struct tty_struct *tty); +static void serial_throttle(struct tty_struct *tty); +static void serial_unthrottle(struct tty_struct *tty); +static int serial_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg); +static void serial_set_termios (struct tty_struct *tty, struct termios * old); + +#define SERIAL_TTY_MAJOR 189 // FIXME: need a legal major + +#define MAX_NUM_PORTS 2 + +#define IN_MAX_PACKET_SIZE 32 +#define OUT_MAX_PACKET_SIZE 32 + +// FIXME: when Au1x00 endpoints 3 and 5 are fixed, make NUM_PORTS=2 +#define NUM_PORTS 2 +#define NUM_EP 2*NUM_PORTS + +#define CONFIG_DESC_LEN \ + USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE + +struct usb_serial_port { + struct tty_struct *tty; /* the coresponding tty for this port */ + unsigned char number; + spinlock_t port_lock; + + struct usb_endpoint_descriptor* out_desc; + struct usb_endpoint_descriptor* in_desc; + + int out_ep_addr; /* endpoint address of OUT endpoint */ + int in_ep_addr; /* endpoint address of IN endpoint */ + + /* task queue for line discipline waking up on send packet complete */ + struct tq_struct send_complete_tq; + /* task queue for line discipline wakeup on receive packet complete */ + struct tq_struct receive_complete_tq; + + int active; /* someone has this device open */ + int writing; /* a packet write is in progress */ + int open_count; /* number of times this port has been opened */ + +}; + +static struct usb_serial { + usbdev_state_t dev_state; // current state of device layer + struct usb_device_descriptor* dev_desc; + struct usb_config_descriptor* config_desc; + struct usb_interface_descriptor* if_desc; + struct usb_string_descriptor * str_desc[6]; + void* str_desc_buf; + + struct usb_serial_port port[NUM_PORTS]; +} usbtty; + +static int serial_refcount; +static struct tty_driver serial_tty_driver; +static struct tty_struct * serial_tty[NUM_PORTS]; +static struct termios * serial_termios[NUM_PORTS]; +static struct termios * serial_termios_locked[NUM_PORTS]; + +static struct usb_device_descriptor dev_desc = { + bLength:USB_DT_DEVICE_SIZE, + bDescriptorType:USB_DT_DEVICE, + bcdUSB:USBDEV_REV, //usb rev + bDeviceClass:USB_CLASS_PER_INTERFACE, //class (none) + bDeviceSubClass:0x00, //subclass (none) + bDeviceProtocol:0x00, //protocol (none) + bMaxPacketSize0:USBDEV_EP0_MAX_PACKET_SIZE, //max packet size for ep0 + idVendor:0x6d04, //vendor id + idProduct:0x0bc0, //product id + bcdDevice:0x0001, //BCD rev 0.1 + iManufacturer:0x01, //manufactuer string index + iProduct:0x02, //product string index + iSerialNumber:0x03, //serial# string index + bNumConfigurations:0x01 //num configurations +}; + +static struct usb_endpoint_descriptor ep_desc[] = { + { + // Bulk IN for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk IN for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + } +}; + +static struct usb_interface_descriptor if_desc = { + bLength:USB_DT_INTERFACE_SIZE, + bDescriptorType:USB_DT_INTERFACE, + bInterfaceNumber:0x00, + bAlternateSetting:0x00, + bNumEndpoints:NUM_EP, + bInterfaceClass:0xff, + bInterfaceSubClass:0xab, + bInterfaceProtocol:0x00, + iInterface:0x05 +}; + +static struct usb_config_descriptor config_desc = { + bLength:USB_DT_CONFIG_SIZE, + bDescriptorType:USB_DT_CONFIG, + wTotalLength:CONFIG_DESC_LEN, + bNumInterfaces:0x01, + bConfigurationValue:0x01, + iConfiguration:0x04, // configuration string + bmAttributes:0xc0, // self-powered + MaxPower:20 // 40 mA +}; + +// String[0] is a list of Language IDs supported by this device +static struct usb_string_descriptor string_desc0 = { + bLength:4, + bDescriptorType:USB_DT_STRING, + wData:{0x0409} // English, US +}; + +// These strings will be converted to Unicode in string_desc[] +static char *strings[5] = { + "Alchemy Semiconductor", // iManufacturer + "WutzAMattaU", // iProduct + "1.0.doh!", // iSerialNumber + "Au1000 TTY Config", // iConfiguration + "Au1000 TTY Interface" // iInterface +}; + +static inline int +port_paranoia_check(struct usb_serial_port *port, const char *function) +{ + if (!port) { + err("%s: port is NULL", function); + return -1; + } + if (!port->tty) { + err("%s: port->tty is NULL", function); + return -1; + } + + return 0; +} + + +static void +port_rx_callback(struct usb_serial_port *port) +{ + dbg(__FUNCTION__ ": ep%d", port->out_ep_addr); + // mark a bh to push this data up to the tty + queue_task(&port->receive_complete_tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +static void +port_tx_callback(struct usb_serial_port *port, usbdev_pkt_t* pkt) +{ + dbg(__FUNCTION__ ": ep%d", port->in_ep_addr); + // mark a bh to wakeup any tty write system call on the port. + queue_task(&port->send_complete_tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); + + /* free the returned packet */ + kfree(pkt); +} + +static void +usbtty_callback(usbdev_cb_type_t cb_type, unsigned long arg, void* data) +{ + usbdev_pkt_t* pkt; + int i; + + switch (cb_type) { + case CB_NEW_STATE: + dbg(__FUNCTION__ ": new dev_state=%d", (int)arg); + usbtty.dev_state = (usbdev_state_t)arg; + break; + case CB_PKT_COMPLETE: + pkt = (usbdev_pkt_t*)arg; + for (i=0; iep_addr == port->in_ep_addr) { + port_tx_callback(port, pkt); + break; + } else if (pkt->ep_addr == port->out_ep_addr) { + port_rx_callback(port); + break; + } + } + break; + } +} + + +/***************************************************************************** + * Here begins the tty driver interface functions + *****************************************************************************/ + +static int serial_open(struct tty_struct *tty, struct file *filp) +{ + int portNumber; + struct usb_serial_port *port; + unsigned long flags; + + /* initialize the pointer incase something fails */ + tty->driver_data = NULL; + + MOD_INC_USE_COUNT; + + /* set up our port structure making the tty driver remember + our port object, and us it */ + portNumber = MINOR(tty->device); + port = &usbtty.port[portNumber]; + tty->driver_data = port; + port->tty = tty; + + if (usbtty.dev_state != CONFIGURED || + port_paranoia_check(port, __FUNCTION__)) { + /* + * the device-layer must be in the configured state before + * the function layer can operate. + */ + MOD_DEC_USE_COUNT; + return -ENODEV; + } + + dbg(__FUNCTION__ ": port %d", port->number); + + spin_lock_irqsave(&port->port_lock, flags); + + ++port->open_count; + + if (!port->active) { + port->active = 1; + + /* + * force low_latency on so that our tty_push actually forces + * the data through, otherwise it is scheduled, and with high + * data rates (like with OHCI) data can get lost. + */ + port->tty->low_latency = 1; + + } + + spin_unlock_irqrestore(&port->port_lock, flags); + + return 0; +} + + +static void serial_close(struct tty_struct *tty, struct file *filp) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + unsigned long flags; + + dbg(__FUNCTION__ ": port %d", port->number); + + if (!port->active) { + err(__FUNCTION__ ": port not opened"); + return; + } + + spin_lock_irqsave(&port->port_lock, flags); + + --port->open_count; + + if (port->open_count <= 0) { + port->active = 0; + port->open_count = 0; + } + + spin_unlock_irqrestore(&port->port_lock, flags); + MOD_DEC_USE_COUNT; +} + + +static int serial_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + usbdev_pkt_t* pkt; + int max_pkt_sz, ret; + unsigned long flags; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbtty.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -EINVAL; + } + + if (count == 0) { + dbg(__FUNCTION__ ": request of 0 bytes"); + return (0); + } + +#if 0 + if (port->writing) { + dbg(__FUNCTION__ ": already writing"); + return 0; + } +#endif + + max_pkt_sz = port->in_desc->wMaxPacketSize; + count = (count > max_pkt_sz) ? max_pkt_sz : count; + + if ((ret = usbdev_alloc_packet(port->in_ep_addr, count, &pkt))) + return ret; + + if (from_user) + copy_from_user(pkt->payload, buf, count); + else + memcpy(pkt->payload, buf, count); + + ret = usbdev_send_packet(port->in_ep_addr, pkt); + + spin_lock_irqsave(&port->port_lock, flags); + port->writing = 1; + spin_unlock_irqrestore(&port->port_lock, flags); + + return ret; +} + + +static int serial_write_room(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + int room = 0; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbtty.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -EINVAL; + } + + //room = port->writing ? 0 : port->in_desc->wMaxPacketSize; + room = port->in_desc->wMaxPacketSize; + + dbg(__FUNCTION__ ": %d", room); + return room; +} + + +static int serial_chars_in_buffer(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + int chars = 0; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbtty.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -EINVAL; + } + + //chars = port->writing ? usbdev_get_byte_count(port->in_ep_addr) : 0; + chars = usbdev_get_byte_count(port->in_ep_addr); + + dbg(__FUNCTION__ ": %d", chars); + return chars; +} + + +static void serial_throttle(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + // FIXME: anything to do? + dbg(__FUNCTION__); +} + + +static void serial_unthrottle(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + // FIXME: anything to do? + dbg(__FUNCTION__); +} + + +static int serial_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -ENODEV; + } + // FIXME: need any IOCTLs? + dbg(__FUNCTION__); + + return -ENOIOCTLCMD; +} + + +static void serial_set_termios(struct tty_struct *tty, struct termios *old) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + dbg(__FUNCTION__); + // FIXME: anything to do? +} + + +static void serial_break(struct tty_struct *tty, int break_state) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + dbg(__FUNCTION__); + // FIXME: anything to do? +} + + +static void port_send_complete(void *private) +{ + struct usb_serial_port *port = (struct usb_serial_port *) private; + struct tty_struct *tty; + unsigned long flags; + + dbg(__FUNCTION__ ": port %d, ep%d", port->number, port->in_ep_addr); + + tty = port->tty; + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) { + dbg(__FUNCTION__ ": write wakeup call."); + (tty->ldisc.write_wakeup) (tty); + } + + wake_up_interruptible(&tty->write_wait); + + spin_lock_irqsave(&port->port_lock, flags); + port->writing = usbdev_get_byte_count(port->in_ep_addr) <= 0 ? 0 : 1; + spin_unlock_irqrestore(&port->port_lock, flags); +} + + +static void port_receive_complete(void *private) +{ + struct usb_serial_port *port = (struct usb_serial_port *) private; + struct tty_struct *tty = port->tty; + usbdev_pkt_t* pkt = NULL; + int i, count; + + /* while there is a packet available */ + while ((count = usbdev_receive_packet(port->out_ep_addr, + &pkt)) != -ENODATA) { + if (count < 0) { + if (pkt) + kfree(pkt); + break; /* exit if error other than ENODATA */ + } + + dbg(__FUNCTION__ ": port %d, ep%d, size=%d", + port->number, port->out_ep_addr, count); + + for (i = 0; i < count; i++) { + /* if we insert more than TTY_FLIPBUF_SIZE characters, + we drop them. */ + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty_flip_buffer_push(tty); + } + /* this doesn't actually push the data through + unless tty->low_latency is set */ + tty_insert_flip_char(tty, pkt->payload[i], 0); + } + tty_flip_buffer_push(tty); + + kfree(pkt); /* make sure we free the packet */ + } + +} + + +static struct tty_driver serial_tty_driver = { + magic:TTY_DRIVER_MAGIC, + driver_name:"usbfn-tty", + name:"usb/ttsdev/%d", + major:SERIAL_TTY_MAJOR, + minor_start:0, + num:NUM_PORTS, + type:TTY_DRIVER_TYPE_SERIAL, + subtype:SERIAL_TYPE_NORMAL, + flags:TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, + refcount:&serial_refcount, + table:serial_tty, + termios:serial_termios, + termios_locked:serial_termios_locked, + + open:serial_open, + close:serial_close, + write:serial_write, + write_room:serial_write_room, + ioctl:serial_ioctl, + set_termios:serial_set_termios, + throttle:serial_throttle, + unthrottle:serial_unthrottle, + break_ctl:serial_break, + chars_in_buffer:serial_chars_in_buffer, +}; + + +void usbfn_tty_exit(void) +{ + int i; + + /* kill the device layer */ + usbdev_exit(); + + for (i=0; i < NUM_PORTS; i++) { + tty_unregister_devfs(&serial_tty_driver, i); + info("usb serial converter now disconnected from ttyUSBdev%d", + i); + } + + tty_unregister_driver(&serial_tty_driver); + + if (usbtty.str_desc_buf) + kfree(usbtty.str_desc_buf); +} + + +int usbfn_tty_init(void) +{ + int ret = 0, i, str_desc_len; + + /* register the tty driver */ + serial_tty_driver.init_termios = tty_std_termios; + serial_tty_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + + if (tty_register_driver(&serial_tty_driver)) { + err(__FUNCTION__ ": failed to register tty driver"); + ret = -ENXIO; + goto out; + } + + /* + * initialize pointers to descriptors + */ + usbtty.dev_desc = &dev_desc; + usbtty.config_desc = &config_desc; + usbtty.if_desc = &if_desc; + + /* + * initialize the string descriptors + */ + + /* alloc buffer big enough for all string descriptors */ + str_desc_len = string_desc0.bLength; + for (i = 0; i < 5; i++) + str_desc_len += 2 + 2 * strlen(strings[i]); + usbtty.str_desc_buf = (void *) kmalloc(str_desc_len, GFP_KERNEL); + if (!usbtty.str_desc_buf) { + err(__FUNCTION__ ": failed to alloc string descriptors"); + ret = -ENOMEM; + goto out; + } + + usbtty.str_desc[0] = + (struct usb_string_descriptor *)usbtty.str_desc_buf; + memcpy(usbtty.str_desc[0], &string_desc0, string_desc0.bLength); + usbtty.str_desc[1] = (struct usb_string_descriptor *) + (usbtty.str_desc_buf + string_desc0.bLength); + for (i = 1; i < 6; i++) { + struct usb_string_descriptor *desc = usbtty.str_desc[i]; + char *str = strings[i - 1]; + int j, str_len = strlen(str); + + desc->bLength = 2 + 2 * str_len; + desc->bDescriptorType = USB_DT_STRING; + for (j = 0; j < str_len; j++) { + desc->wData[j] = (u16) str[j]; + } + if (i < 5) + usbtty.str_desc[i + 1] = + (struct usb_string_descriptor *) + ((u8 *) desc + desc->bLength); + } + + /* + * start the device layer. The device layer assigns us + * our endpoint addresses + */ + if ((ret = usbdev_init(&dev_desc, &config_desc, &if_desc, ep_desc, + usbtty.str_desc, usbtty_callback, NULL))) { + err(__FUNCTION__ ": device-layer init failed"); + goto out; + } + + /* initialize the devfs nodes for this device and let the user + know what ports we are bound to */ + for (i = 0; i < NUM_PORTS; ++i) { + struct usb_serial_port *port; + tty_register_devfs(&serial_tty_driver, 0, i); + info("usbdev serial attached to ttyUSBdev%d " + "(or devfs usb/ttsdev/%d)", i, i); + port = &usbtty.port[i]; + port->number = i; + port->in_desc = &ep_desc[NUM_PORTS*i]; + port->out_desc = &ep_desc[NUM_PORTS*i + 1]; + port->in_ep_addr = port->in_desc->bEndpointAddress & 0x0f; + port->out_ep_addr = port->out_desc->bEndpointAddress & 0x0f; + port->send_complete_tq.routine = port_send_complete; + port->send_complete_tq.data = port; + port->receive_complete_tq.routine = port_receive_complete; + port->receive_complete_tq.data = port; + spin_lock_init(&port->port_lock); + } + + out: + if (ret) + usbfn_tty_exit(); + return ret; +} + + +/* Module information */ +MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com"); +MODULE_DESCRIPTION("Au1x00 USB Device-Side Serial TTY Driver"); +MODULE_LICENSE("GPL"); + +module_init(usbfn_tty_init); +module_exit(usbfn_tty_exit); diff -urN linux-2.4.21/drivers/char/au1x00-serial.c linux-2.4.22/drivers/char/au1x00-serial.c --- linux-2.4.21/drivers/char/au1x00-serial.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/au1x00-serial.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,3098 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Au1x00 serial port driver. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Derived almost entirely from drivers/char/serial.c: + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, + * 1998, 1999 Theodore Ts'o + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + */ + +static char *serial_version = "1.01"; +static char *serial_revdate = "2001-02-08"; + + +#include +#include + +#undef SERIAL_PARANOIA_CHECK +#define CONFIG_SERIAL_NOPAUSE_IO +#define SERIAL_DO_RESTART + + +/* Set of debugging defines */ + +#undef SERIAL_DEBUG_INTR +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_FLOW +#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT +#undef SERIAL_DEBUG_PCI +#undef SERIAL_DEBUG_AUTOCONF + +#ifdef MODULE +#undef CONFIG_AU1X00_SERIAL_CONSOLE +#endif + +#define CONFIG_SERIAL_RSA + +#define RS_STROBE_TIME (10*HZ) +#define RS_ISR_PASS_LIMIT 256 + +/* + * End of serial driver configuration section. + */ + +#include + +#include +#ifdef LOCAL_HEADERS +#include "serial_local.h" +#else +#include +#include +#include +#include +#define LOCAL_VERSTRING "" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE +#include +#endif +#ifdef CONFIG_MAGIC_SYSRQ +#include +#endif + +#include +#include +#include +#include + +#ifdef CONFIG_MAC_SERIAL +#define SERIAL_DEV_OFFSET 2 +#else +#define SERIAL_DEV_OFFSET 0 +#endif + +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#else +#define _INLINE_ +#endif + +static char *serial_name = "Serial driver"; + +static DECLARE_TASK_QUEUE(tq_serial); + +static struct tty_driver serial_driver, callout_driver; +static int serial_refcount; + +static struct timer_list serial_timer; + +extern unsigned long get_au1x00_uart_baud_base(void); + +/* serial subtype definitions */ +#ifndef SERIAL_TYPE_NORMAL +#define SERIAL_TYPE_NORMAL 1 +#define SERIAL_TYPE_CALLOUT 2 +#endif + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* + * IRQ_timeout - How long the timeout should be for each IRQ + * should be after the IRQ has been active. + */ + +static struct async_struct *IRQ_ports[NR_IRQS]; +static int IRQ_timeout[NR_IRQS]; +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE +static struct console sercons; +static int lsr_break_flag; +#endif +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +static unsigned long break_pressed; /* break, really ... */ +#endif + +static void autoconfig(struct serial_state * state); +static void change_speed(struct async_struct *info, struct termios *old); +static void rs_wait_until_sent(struct tty_struct *tty, int timeout); + +/* + * Here we define the default xmit fifo size used for each type of + * UART + */ +static struct serial_uart_config uart_config[] = { + { "unknown", 1, 0 }, + { "8250", 1, 0 }, + { "16450", 1, 0 }, + { "16550", 1, 0 }, + { 0, 0} +}; + + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in serial.h */ +}; + +#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) + +#ifndef PREPARE_FUNC +#define PREPARE_FUNC(dev) (dev->prepare) +#define ACTIVATE_FUNC(dev) (dev->activate) +#define DEACTIVATE_FUNC(dev) (dev->deactivate) +#endif + +#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) + +static struct tty_struct *serial_table[NR_PORTS]; +static struct termios *serial_termios[NR_PORTS]; +static struct termios *serial_termios_locked[NR_PORTS]; + + +#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) +#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ + kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) +#else +#define DBG_CNT(s) +#endif + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the copy_from_user blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char *tmp_buf; +#ifdef DECLARE_MUTEX +static DECLARE_MUTEX(tmp_buf_sem); +#else +static struct semaphore tmp_buf_sem = MUTEX; +#endif + +static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED; + +static inline int serial_paranoia_check(struct async_struct *info, + kdev_t device, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = + "Warning: bad magic number for serial struct (%s) in %s\n"; + static const char *badinfo = + "Warning: null async_struct for (%s) in %s\n"; + + if (!info) { + printk(badinfo, kdevname(device), routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, kdevname(device), routine); + return 1; + } +#endif + return 0; +} + +static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) +{ + return (au_readl(info->port+offset) & 0xffff); +} + +static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) +{ + au_writel(value & 0xffff, info->port+offset); +} + + +/* + * We used to support using pause I/O for certain machines. We + * haven't supported this for a while, but just in case it's badly + * needed for certain old 386 machines, I've left these #define's + * in.... + */ +#define serial_inp(info, offset) serial_in(info, offset) +#define serial_outp(info, offset, value) serial_out(info, offset, value) + + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_stop")) + return; + + spin_lock_irqsave(&serial_lock, flags); + if (info->IER & UART_IER_THRI) { + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_start(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_start")) + return; + + spin_lock_irqsave(&serial_lock, flags); + if (info->xmit.head != info->xmit.tail + && info->xmit.buf + && !(info->IER & UART_IER_THRI)) { + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + spin_unlock_irqrestore(&serial_lock, flags); +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * Note: rs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * rs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static _INLINE_ void rs_sched_event(struct async_struct *info, + int event) +{ + info->event |= 1 << event; + queue_task(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +static _INLINE_ void receive_chars(struct async_struct *info, + int *status, struct pt_regs * regs) +{ + struct tty_struct *tty = info->tty; + unsigned char ch; + int ignored = 0; + struct async_icount *icount; + + icount = &info->state->icount; + do { + ch = serial_inp(info, UART_RX); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + goto ignore_char; + *tty->flip.char_buf_ptr = ch; + icount->rx++; + +#ifdef SERIAL_DEBUG_INTR + printk("DR%02x:%02x...", ch, *status); +#endif + *tty->flip.flag_buf_ptr = 0; + if (*status & (UART_LSR_BI | UART_LSR_PE | + UART_LSR_FE | UART_LSR_OE)) { + /* + * For statistics only + */ + if (*status & UART_LSR_BI) { + *status &= ~(UART_LSR_FE | UART_LSR_PE); + icount->brk++; + /* + * We do the SysRQ and SAK checking + * here because otherwise the break + * may get masked by ignore_status_mask + * or read_status_mask. + */ +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (info->line == sercons.index) { + if (!break_pressed) { + break_pressed = jiffies; + goto ignore_char; + } + break_pressed = 0; + } +#endif + if (info->flags & ASYNC_SAK) + do_SAK(tty); + } else if (*status & UART_LSR_PE) + icount->parity++; + else if (*status & UART_LSR_FE) + icount->frame++; + if (*status & UART_LSR_OE) + icount->overrun++; + + /* + * Now check to see if character should be + * ignored, and mask off conditions which + * should be ignored. + */ + if (*status & info->ignore_status_mask) { + if (++ignored > 100) + break; + goto ignore_char; + } + *status &= info->read_status_mask; + +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if (info->line == sercons.index) { + /* Recover the break flag from console xmit */ + *status |= lsr_break_flag; + lsr_break_flag = 0; + } +#endif + if (*status & (UART_LSR_BI)) { +#ifdef SERIAL_DEBUG_INTR + printk("handling break...."); +#endif + *tty->flip.flag_buf_ptr = TTY_BREAK; + } else if (*status & UART_LSR_PE) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (*status & UART_LSR_FE) + *tty->flip.flag_buf_ptr = TTY_FRAME; + if (*status & UART_LSR_OE) { + /* + * Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + tty->flip.count++; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + goto ignore_char; + } + } +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (break_pressed && info->line == sercons.index) { + if (ch != 0 && + time_before(jiffies, break_pressed + HZ*5)) { + handle_sysrq(ch, regs, NULL, NULL); + break_pressed = 0; + goto ignore_char; + } + break_pressed = 0; + } +#endif + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + ignore_char: + *status = serial_inp(info, UART_LSR); + } while (*status & UART_LSR_DR); + tty_flip_buffer_push(tty); +} + +static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) +{ + int count; + + if (info->x_char) { + serial_outp(info, UART_TX, info->x_char); + info->state->icount.tx++; + info->x_char = 0; + if (intr_done) + *intr_done = 0; + return; + } + if (info->xmit.head == info->xmit.tail + || info->tty->stopped + || info->tty->hw_stopped) { + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + return; + } + + count = info->xmit_fifo_size; + do { + serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]); + info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); + info->state->icount.tx++; + if (info->xmit.head == info->xmit.tail) + break; + } while (--count > 0); + + if (CIRC_CNT(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + +#ifdef SERIAL_DEBUG_INTR + printk("THRE..."); +#endif + if (intr_done) + *intr_done = 0; + + if (info->xmit.head == info->xmit.tail) { + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } +} + +static _INLINE_ void check_modem_status(struct async_struct *info) +{ + int status; + struct async_icount *icount; + + status = serial_in(info, UART_MSR); + + if (status & UART_MSR_ANY_DELTA) { + icount = &info->state->icount; + /* update input line counters */ + if (status & UART_MSR_TERI) + icount->rng++; + if (status & UART_MSR_DDSR) + icount->dsr++; + if (status & UART_MSR_DDCD) { + icount->dcd++; +#ifdef CONFIG_HARD_PPS + if ((info->flags & ASYNC_HARDPPS_CD) && + (status & UART_MSR_DCD)) + hardpps(); +#endif + } + if (status & UART_MSR_DCTS) + icount->cts++; + wake_up_interruptible(&info->delta_msr_wait); + } + + if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { +#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) + printk("ttys%d CD now %s...", info->line, + (status & UART_MSR_DCD) ? "on" : "off"); +#endif + if (status & UART_MSR_DCD) + wake_up_interruptible(&info->open_wait); + else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_CALLOUT_NOHUP))) { +#ifdef SERIAL_DEBUG_OPEN + printk("doing serial hangup..."); +#endif + if (info->tty) + tty_hangup(info->tty); + } + } + if (info->flags & ASYNC_CTS_FLOW) { + if (info->tty->hw_stopped) { + if (status & UART_MSR_CTS) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx start..."); +#endif + info->tty->hw_stopped = 0; + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + return; + } + } else { + if (!(status & UART_MSR_CTS)) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx stop..."); +#endif + info->tty->hw_stopped = 1; + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + } + } +} + + + +/* + * This is the serial driver's interrupt routine for a single port + */ +static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) +{ + int status; + int pass_counter = 0; + struct async_struct * info; + +#ifdef SERIAL_DEBUG_INTR + printk("rs_interrupt_single(%d)...", irq); +#endif + + info = IRQ_ports[irq]; + if (!info || !info->tty) + return; + + do { + status = serial_inp(info, UART_LSR); +#ifdef SERIAL_DEBUG_INTR + printk("status = %x...", status); +#endif + if (status & UART_LSR_DR) + receive_chars(info, &status, regs); + check_modem_status(info); + if (status & UART_LSR_THRE) + transmit_chars(info, 0); + if (pass_counter++ > RS_ISR_PASS_LIMIT) { +#if 0 + printk("rs_single loop break.\n"); +#endif + break; + } + } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT)); + info->last_active = jiffies; +#ifdef SERIAL_DEBUG_INTR + printk("end.\n"); +#endif +} + + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_serial); +} + +static void do_softint(void *private_) +{ + struct async_struct *info = (struct async_struct *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); +#ifdef SERIAL_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif + } +} + +/* + * This subroutine is called when the RS_TIMER goes off. It is used + * by the serial driver to handle ports that do not have an interrupt + * (irq=0). This doesn't work very well for 16450's, but gives barely + * passable results for a 16550A. (Although at the expense of much + * CPU overhead). + */ +static void rs_timer(unsigned long dummy) +{ + static unsigned long last_strobe; + struct async_struct *info; + unsigned int i; + unsigned long flags; + + if ((jiffies - last_strobe) >= RS_STROBE_TIME) { + for (i=0; i < NR_IRQS; i++) { + info = IRQ_ports[i]; + if (!info) + continue; + spin_lock_irqsave(&serial_lock, flags); + rs_interrupt_single(i, NULL, NULL); + spin_unlock_irqrestore(&serial_lock, flags); + } + } + last_strobe = jiffies; + mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); + +#if 0 + if (IRQ_ports[0]) { + spin_lock_irqsave(&serial_lock, flags); + rs_interrupt_single(0, NULL, NULL); + spin_unlock_irqrestore(&serial_lock, flags); + + mod_timer(&serial_timer, jiffies + IRQ_timeout[0]); + } +#endif +} + +/* + * --------------------------------------------------------------- + * Low level utility subroutines for the serial driver: routines to + * figure out the appropriate timeout for an interrupt chain, routines + * to initialize and startup a serial port, and routines to shutdown a + * serial port. Useful stuff like that. + * --------------------------------------------------------------- + */ + +/* + * This routine figures out the correct timeout for a particular IRQ. + * It uses the smallest timeout of all of the serial ports in a + * particular interrupt chain. Now only used for IRQ 0.... + */ +static void figure_IRQ_timeout(int irq) +{ + struct async_struct *info; + int timeout = 60*HZ; /* 60 seconds === a long time :-) */ + + info = IRQ_ports[irq]; + if (!info) { + IRQ_timeout[irq] = 60*HZ; + return; + } + while (info) { + if (info->timeout < timeout) + timeout = info->timeout; + info = info->next_port; + } + if (!irq) + timeout = timeout / 2; + IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1; +} + + +static int startup(struct async_struct * info) +{ + unsigned long flags; + int retval=0; + void (*handler)(int, void *, struct pt_regs *); + struct serial_state *state= info->state; + unsigned long page; + + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + spin_lock_irqsave(&serial_lock, flags); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + + if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + free_page(page); + goto errout; + } + if (info->xmit.buf) + free_page(page); + else + info->xmit.buf = (unsigned char *) page; + + + if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { + au_writel(3, UART_MOD_CNTRL + state->port); + au_sync_delay(10); + } +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttys%d (irq %d)...", info->line, state->irq); +#endif + + + /* + * Clear the FIFO buffers and disable them + * (they will be reenabled in change_speed()) + */ + if (uart_config[state->type].flags & UART_CLEAR_FIFO) { + serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); + serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(info, UART_FCR, 0); + } + + /* + * Clear the interrupt registers. + */ + (void) serial_inp(info, UART_LSR); + (void) serial_inp(info, UART_RX); + (void) serial_inp(info, UART_IIR); + (void) serial_inp(info, UART_MSR); + + /* + * At this point there's no way the LSR could still be 0xFF; + * if it is, then bail out, because there's likely no UART + * here. + */ + if (!(info->flags & ASYNC_BUGGY_UART) && + (serial_inp(info, UART_LSR) == 0xff)) { + printk("LSR safety check engaged!\n"); + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + } else + retval = -ENODEV; + goto errout; + } + + /* + * Allocate the IRQ if necessary + */ +#if 0 + /* au1000, uart0 irq is 0 */ + if (state->irq && (!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { +#endif + if ((!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + retval = -EBUSY; + goto errout; + } else + handler = rs_interrupt_single; + + retval = request_irq(state->irq, handler, SA_SHIRQ, + "serial", &IRQ_ports[state->irq]); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + } + + /* + * Insert serial port into IRQ chain. + */ + info->prev_port = 0; + info->next_port = IRQ_ports[state->irq]; + if (info->next_port) + info->next_port->prev_port = info; + IRQ_ports[state->irq] = info; + figure_IRQ_timeout(state->irq); + + /* + * Now, initialize the UART + */ + serial_outp(info, UART_LCR, UART_LCR_WLEN8); + + info->MCR = 0; + if (info->tty->termios->c_cflag & CBAUD) + info->MCR = UART_MCR_DTR | UART_MCR_RTS; + { + if (state->irq != 0) + info->MCR |= UART_MCR_OUT2; + } + info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ + serial_outp(info, UART_MCR, info->MCR); + + /* + * Finally, enable interrupts + */ + info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; + serial_outp(info, UART_IER, info->IER); /* enable interrupts */ + + + /* + * And clear the interrupt registers again for luck. + */ + (void)serial_inp(info, UART_LSR); + (void)serial_inp(info, UART_RX); + (void)serial_inp(info, UART_IIR); + (void)serial_inp(info, UART_MSR); + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit.head = info->xmit.tail = 0; + + /* + * Set up serial timers... + */ + mod_timer(&serial_timer, jiffies + 2*HZ/100); + + /* + * Set up the tty->alt_speed kludge + */ + if (info->tty) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + } + + /* + * and set the speed of the serial port + */ + change_speed(info, 0); + + info->flags |= ASYNC_INITIALIZED; + spin_unlock_irqrestore(&serial_lock, flags); + return 0; + +errout: + spin_unlock_irqrestore(&serial_lock, flags); + return retval; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct async_struct * info) +{ + unsigned long flags; + struct serial_state *state; + int retval; + + if (!(info->flags & ASYNC_INITIALIZED)) + return; + + state = info->state; + +#ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d (irq %d)....", info->line, + state->irq); +#endif + + spin_lock_irqsave(&serial_lock, flags); + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be waken up + */ + 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] || + if ((!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 */ + info->MCR &= ~UART_MCR_OUT2; + info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ + + /* disable break condition */ + serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); + + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); + serial_outp(info, UART_MCR, info->MCR); + + /* disable FIFO's */ + serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(info, UART_FCR, 0); + + (void)serial_in(info, UART_RX); /* read data port to reset things */ + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; +#ifndef CONFIG_KGDB + au_writel(0, UART_MOD_CNTRL + state->port); + au_sync_delay(10); +#endif + spin_unlock_irqrestore(&serial_lock, flags); +} + + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct async_struct *info, + struct termios *old_termios) +{ + int quot = 0, baud_base, baud; + unsigned cflag, cval, fcr = 0; + int bits; + unsigned long flags; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + if (!CONFIGURED_SERIAL_PORT(info)) + return; + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS5: cval = 0x00; bits = 7; break; + case CS6: cval = 0x01; bits = 8; break; + case CS7: cval = 0x02; bits = 9; break; + case CS8: cval = 0x03; bits = 10; break; + /* Never happens, but GCC is too dumb to figure it out */ + default: cval = 0x00; bits = 7; break; + } + if (cflag & CSTOPB) { + cval |= 0x04; + bits++; + } + if (cflag & PARENB) { + cval |= UART_LCR_PARITY; + bits++; + } + if (!(cflag & PARODD)) + cval |= UART_LCR_EPAR; +#ifdef CMSPAR + if (cflag & CMSPAR) + cval |= UART_LCR_SPAR; +#endif + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(info->tty); + if (!baud) { + baud = 9600; /* B0 transition handled in rs_set_termios */ + } + baud_base = get_au1x00_uart_baud_base(); + + //if (baud == 38400 && + if (((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { + quot = info->state->custom_divisor; + } + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + /* If the quotient is zero refuse the change */ + if (!quot && old_termios) { + info->tty->termios->c_cflag &= ~CBAUD; + info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); + baud = tty_get_baud_rate(info->tty); + if (!baud) + baud = 9600; + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) + quot = info->state->custom_divisor; + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + } + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) + quot = baud_base / 9600; + + info->quot = quot; + info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + /* Set up FIFO's */ + if (uart_config[info->state->type].flags & UART_USE_FIFO) { + if ((info->state->baud_base / quot) < 2400) + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_1; + else + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8; + } + + /* CTS flow control flag and modem status interrupts */ + info->IER &= ~UART_IER_MSI; + if (info->flags & ASYNC_HARDPPS_CD) + info->IER |= UART_IER_MSI; + if (cflag & CRTSCTS) { + info->flags |= ASYNC_CTS_FLOW; + info->IER |= UART_IER_MSI; + } else + info->flags &= ~ASYNC_CTS_FLOW; + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else { + info->flags |= ASYNC_CHECK_CD; + info->IER |= UART_IER_MSI; + } + serial_out(info, UART_IER, info->IER); + + /* + * Set up parity check flag + */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; + if (I_INPCK(info->tty)) + info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) + info->read_status_mask |= UART_LSR_BI; + + /* + * Characters to ignore + */ + info->ignore_status_mask = 0; + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; + if (I_IGNBRK(info->tty)) { + info->ignore_status_mask |= UART_LSR_BI; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= UART_LSR_OE; + } + /* + * !!! ignore all characters if CREAD is not set + */ + if ((cflag & CREAD) == 0) + info->ignore_status_mask |= UART_LSR_DR; + spin_lock_irqsave(&serial_lock, flags); + + serial_outp(info, UART_CLK, quot & 0xffff); + serial_outp(info, UART_LCR, cval); + info->LCR = cval; /* Save LCR */ + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_put_char")) + return; + + if (!tty || !info->xmit.buf) + return; + + spin_lock_irqsave(&serial_lock, flags); + if (CIRC_SPACE(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) == 0) { + spin_unlock_irqrestore(&serial_lock, flags); + return; + } + + info->xmit.buf[info->xmit.head] = ch; + info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) + return; + + if (info->xmit.head == info->xmit.tail + || tty->stopped + || tty->hw_stopped + || !info->xmit.buf) + return; + + spin_lock_irqsave(&serial_lock, flags); + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, ret = 0; + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_write")) + return 0; + + if (!tty || !info->xmit.buf || !tmp_buf) + return 0; + + spin_lock_irqsave(&serial_lock, flags); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + int c1; + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!ret) + ret = -EFAULT; + break; + } + cli(); + c1 = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (c1 < c) + c = c1; + memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + spin_unlock_irqrestore(&serial_lock, flags); + buf += c; + count -= c; + ret += c; + } + up(&tmp_buf_sem); + } else { + cli(); + while (1) { + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) { + break; + } + memcpy(info->xmit.buf + info->xmit.head, buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + buf += c; + count -= c; + ret += c; + } + spin_unlock_irqrestore(&serial_lock, flags); + } + if (info->xmit.head != info->xmit.tail + && !tty->stopped + && !tty->hw_stopped + && !(info->IER & UART_IER_THRI)) { + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + return ret; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_write_room")) + return 0; + return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) + return 0; + return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) + return; + spin_lock_irqsave(&serial_lock, flags); + info->xmit.head = info->xmit.tail = 0; + spin_unlock_irqrestore(&serial_lock, flags); + wake_up_interruptible(&tty->write_wait); +#ifdef SERIAL_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct *tty, char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_send_char")) + return; + + info->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_throttle")) + return; + + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); + + if (tty->termios->c_cflag & CRTSCTS) + info->MCR &= ~UART_MCR_RTS; + + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("unthrottle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } + if (tty->termios->c_cflag & CRTSCTS) + info->MCR |= UART_MCR_RTS; + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct async_struct * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + struct serial_state *state = info->state; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = state->type; + tmp.line = state->line; + tmp.port = state->port; + if (HIGH_BITS_OFFSET) + tmp.port_high = state->port >> HIGH_BITS_OFFSET; + else + tmp.port_high = 0; + tmp.irq = state->irq; + tmp.flags = state->flags; + tmp.xmit_fifo_size = state->xmit_fifo_size; + tmp.baud_base = state->baud_base; + tmp.close_delay = state->close_delay; + tmp.closing_wait = state->closing_wait; + tmp.custom_divisor = state->custom_divisor; + tmp.hub6 = state->hub6; + tmp.io_type = state->io_type; + if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int set_serial_info(struct async_struct * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct serial_state old_state, *state; + unsigned int i,change_irq,change_port; + int retval = 0; + unsigned long new_port; + + if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) + return -EFAULT; + state = info->state; + old_state = *state; + + new_port = new_serial.port; + if (HIGH_BITS_OFFSET) + new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; + + change_irq = new_serial.irq != state->irq; + change_port = (new_port != ((int) state->port)) || + (new_serial.hub6 != state->hub6); + + if (!capable(CAP_SYS_ADMIN)) { + if (change_irq || change_port || + (new_serial.baud_base != state->baud_base) || + (new_serial.type != state->type) || + (new_serial.close_delay != state->close_delay) || + (new_serial.xmit_fifo_size != state->xmit_fifo_size) || + ((new_serial.flags & ~ASYNC_USR_MASK) != + (state->flags & ~ASYNC_USR_MASK))) + return -EPERM; + state->flags = ((state->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + info->flags = ((info->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + state->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + new_serial.irq = irq_cannonicalize(new_serial.irq); + + if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || + (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) || + (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || + (new_serial.type == PORT_STARTECH)) { + return -EINVAL; + } + + if ((new_serial.type != state->type) || + (new_serial.xmit_fifo_size <= 0)) + new_serial.xmit_fifo_size = + uart_config[new_serial.type].dfl_xmit_fifo_size; + + /* Make sure address is not already in use */ + if (new_serial.type) { + for (i = 0 ; i < NR_PORTS; i++) + if ((state != &rs_table[i]) && + (rs_table[i].port == new_port) && + rs_table[i].type) + return -EADDRINUSE; + } + + if ((change_port || change_irq) && (state->count > 1)) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + state->baud_base = new_serial.baud_base; + state->flags = ((state->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | + (info->flags & ASYNC_INTERNAL_FLAGS)); + state->custom_divisor = new_serial.custom_divisor; + state->close_delay = new_serial.close_delay * HZ/100; + state->closing_wait = new_serial.closing_wait * HZ/100; + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + info->xmit_fifo_size = state->xmit_fifo_size = + new_serial.xmit_fifo_size; + + if ((state->type != PORT_UNKNOWN) && state->port) { + release_region(state->port,8); + } + state->type = new_serial.type; + if (change_port || change_irq) { + /* + * We need to shutdown the serial port at the old + * port/irq combination. + */ + shutdown(info); + state->irq = new_serial.irq; + info->port = state->port = new_port; + info->hub6 = state->hub6 = new_serial.hub6; + if (info->hub6) + info->io_type = state->io_type = SERIAL_IO_HUB6; + else if (info->io_type == SERIAL_IO_HUB6) + info->io_type = state->io_type = SERIAL_IO_PORT; + } + if ((state->type != PORT_UNKNOWN) && state->port) { + request_region(state->port,8,"serial(set)"); + } + + +check_and_exit: + if (!state->port || !state->type) + return 0; + if (info->flags & ASYNC_INITIALIZED) { + if (((old_state.flags & ASYNC_SPD_MASK) != + (state->flags & ASYNC_SPD_MASK)) || + (old_state.custom_divisor != state->custom_divisor)) { + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + change_speed(info, 0); + } + } else { + retval = startup(info); + } + return retval; +} + + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct async_struct * info, unsigned int *value) +{ + unsigned char status; + unsigned int result; + unsigned long flags; + + spin_lock_irqsave(&serial_lock, flags); + status = serial_in(info, UART_LSR); + spin_unlock_irqrestore(&serial_lock, flags); + result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); + + /* + * If we're about to load something into the transmit + * register, we'll pretend the transmitter isn't empty to + * avoid a race condition (depending on when the transmit + * interrupt happens). + */ + if (info->x_char || + ((CIRC_CNT(info->xmit.head, info->xmit.tail, + SERIAL_XMIT_SIZE) > 0) && + !info->tty->stopped && !info->tty->hw_stopped)) + result &= TIOCSER_TEMT; + + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + return 0; +} + + +static int get_modem_info(struct async_struct * info, unsigned int *value) +{ + unsigned char control, status; + unsigned int result; + unsigned long flags; + + control = info->MCR; + spin_lock_irqsave(&serial_lock, flags); + status = serial_in(info, UART_MSR); + spin_unlock_irqrestore(&serial_lock, flags); + result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) + | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) +#ifdef TIOCM_OUT1 + | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) + | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) +#endif + | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) + | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) + | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) + | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); + + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + return 0; +} + +static int set_modem_info(struct async_struct * info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg; + unsigned long flags; + + if (copy_from_user(&arg, value, sizeof(int))) + return -EFAULT; + + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) + info->MCR |= UART_MCR_RTS; + if (arg & TIOCM_DTR) + info->MCR |= UART_MCR_DTR; +#ifdef TIOCM_OUT1 + if (arg & TIOCM_OUT1) + info->MCR |= UART_MCR_OUT1; + if (arg & TIOCM_OUT2) + info->MCR |= UART_MCR_OUT2; +#endif + if (arg & TIOCM_LOOP) + info->MCR |= UART_MCR_LOOP; + break; + case TIOCMBIC: + if (arg & TIOCM_RTS) + info->MCR &= ~UART_MCR_RTS; + if (arg & TIOCM_DTR) + info->MCR &= ~UART_MCR_DTR; +#ifdef TIOCM_OUT1 + if (arg & TIOCM_OUT1) + info->MCR &= ~UART_MCR_OUT1; + if (arg & TIOCM_OUT2) + info->MCR &= ~UART_MCR_OUT2; +#endif + if (arg & TIOCM_LOOP) + info->MCR &= ~UART_MCR_LOOP; + break; + case TIOCMSET: + info->MCR = ((info->MCR & ~(UART_MCR_RTS | +#ifdef TIOCM_OUT1 + UART_MCR_OUT1 | + UART_MCR_OUT2 | +#endif + UART_MCR_LOOP | + UART_MCR_DTR)) + | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) +#ifdef TIOCM_OUT1 + | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) + | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) +#endif + | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) + | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); + break; + default: + return -EINVAL; + } + spin_lock_irqsave(&serial_lock, flags); + info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); + return 0; +} + +static int do_autoconfig(struct async_struct * info) +{ + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (info->state->count > 1) + return -EBUSY; + + shutdown(info); + + autoconfig(info->state); + retval = startup(info); + if (retval) + return retval; + return 0; +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_break")) + return; + + if (!CONFIGURED_SERIAL_PORT(info)) + return; + spin_lock_irqsave(&serial_lock, flags); + if (break_state == -1) + info->LCR |= UART_LCR_SBC; + else + info->LCR &= ~UART_LCR_SBC; + serial_out(info, UART_LCR, info->LCR); + spin_unlock_irqrestore(&serial_lock, flags); +} + + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct async_icount cprev, cnow; /* kernel counter temps */ + struct serial_icounter_struct icount; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCMGET: + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERCONFIG: + return do_autoconfig(info); + + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + if (copy_to_user((struct async_struct *) arg, + info, sizeof(struct async_struct))) + return -EFAULT; + return 0; + + + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + spin_lock_irqsave(&serial_lock, flags); + /* note the counters on entry */ + cprev = info->state->icount; + spin_unlock_irqrestore(&serial_lock, flags); + /* Force modem status interrupts on */ + info->IER |= UART_IER_MSI; + serial_out(info, UART_IER, info->IER); + while (1) { + interruptible_sleep_on(&info->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + spin_lock_irqsave(&serial_lock, flags); + cnow = info->state->icount; /* atomic copy */ + spin_unlock_irqrestore(&serial_lock, flags); + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ + if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { + return 0; + } + cprev = cnow; + } + /* NOTREACHED */ + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + case TIOCGICOUNT: + spin_lock_irqsave(&serial_lock, flags); + cnow = info->state->icount; + spin_unlock_irqrestore(&serial_lock, flags); + icount.cts = cnow.cts; + icount.dsr = cnow.dsr; + icount.rng = cnow.rng; + icount.dcd = cnow.dcd; + icount.rx = cnow.rx; + icount.tx = cnow.tx; + icount.frame = cnow.frame; + icount.overrun = cnow.overrun; + icount.parity = cnow.parity; + icount.brk = cnow.brk; + icount.buf_overrun = cnow.buf_overrun; + + if (copy_to_user((void *)arg, &icount, sizeof(icount))) + return -EFAULT; + return 0; + case TIOCSERGWILD: + case TIOCSERSWILD: + /* "setserial -W" is called in Debian boot */ + printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + unsigned int cflag = tty->termios->c_cflag; + + if ( (cflag == old_termios->c_cflag) + && ( RELEVANT_IFLAG(tty->termios->c_iflag) + == RELEVANT_IFLAG(old_termios->c_iflag))) + return; + + change_speed(info, old_termios); + + /* Handle transition to B0 status */ + if ((old_termios->c_cflag & CBAUD) && + !(cflag & CBAUD)) { + info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && + (cflag & CBAUD)) { + info->MCR |= UART_MCR_DTR; + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) { + info->MCR |= UART_MCR_RTS; + } + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); + } + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * async structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->device, "rs_close")) + return; + + state = info->state; + + spin_lock_irqsave(&serial_lock, flags); + + if (tty_hung_up_p(filp)) { + DBG_CNT("before DEC-hung"); + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&serial_lock, flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_close ttys%d, count = %d\n", info->line, state->count); +#endif + if ((tty->count == 1) && (state->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("rs_close: bad serial port count; tty->count is 1, " + "state->count is %d\n", state->count); + state->count = 1; + } + if (--state->count < 0) { + printk("rs_close: bad serial port count for ttys%d: %d\n", + info->line, state->count); + state->count = 0; + } + if (state->count) { + DBG_CNT("before DEC-2"); + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&serial_lock, flags); + return; + } + info->flags |= ASYNC_CLOSING; + spin_unlock_irqrestore(&serial_lock, flags); + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ASYNC_NORMAL_ACTIVE) + info->state->normal_termios = *tty->termios; + if (info->flags & ASYNC_CALLOUT_ACTIVE) + info->state->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + info->IER &= ~UART_IER_RLSI; + info->read_status_mask &= ~UART_LSR_DR; + if (info->flags & ASYNC_INITIALIZED) { + serial_out(info, UART_IER, info->IER); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + rs_wait_until_sent(tty, info->timeout); + } + shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = 0; + if (info->blocked_open) { + if (info->close_delay) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| + ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + MOD_DEC_USE_COUNT; +} + +/* + * rs_wait_until_sent() --- wait until the transmitter is empty + */ +static void rs_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long orig_jiffies, char_time; + int lsr; + + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) + return; + + if (info->state->type == PORT_UNKNOWN) + return; + + if (info->xmit_fifo_size == 0) + return; /* Just in case.... */ + + orig_jiffies = jiffies; + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout && timeout < char_time) + char_time = timeout; + /* + * If the transmitter hasn't cleared in twice the approximate + * amount of time to send the entire FIFO, it probably won't + * ever clear. This assumes the UART isn't doing flow + * control, which is currently the case. Hence, if it ever + * takes longer than info->timeout, this is probably due to a + * UART bug of some kind. So, we clamp the timeout parameter at + * 2*info->timeout. + */ + if (!timeout || timeout > 2*info->timeout) + timeout = 2*info->timeout; +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); + printk("jiff=%lu...", jiffies); +#endif + while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) { +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("lsr = %d (jiff=%lu)...", lsr, jiffies); +#endif + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(char_time); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + set_current_state(TASK_RUNNING); +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); +#endif +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void rs_hangup(struct tty_struct *tty) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state = info->state; + + if (serial_paranoia_check(info, tty->device, "rs_hangup")) + return; + + state = info->state; + + rs_flush_buffer(tty); + if (info->flags & ASYNC_CLOSING) + return; + shutdown(info); + info->event = 0; + state->count = 0; + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct async_struct *info) +{ + DECLARE_WAITQUEUE(wait, current); + struct serial_state *state = info->state; + int retval; + int do_clocal = 0, extra_count = 0; + unsigned long flags; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ASYNC_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ASYNC_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ASYNC_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ASYNC_CALLOUT_ACTIVE) { + if (state->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, state->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttys%d, count = %d\n", + state->line, state->count); +#endif + spin_lock_irqsave(&serial_lock, flags); + if (!tty_hung_up_p(filp)) { + extra_count = 1; + state->count--; + } + spin_unlock_irqrestore(&serial_lock, flags); + info->blocked_open++; + while (1) { + spin_lock_irqsave(&serial_lock, flags); + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + (tty->termios->c_cflag & CBAUD)) + serial_out(info, UART_MCR, + serial_inp(info, UART_MCR) | + (UART_MCR_DTR | UART_MCR_RTS)); + spin_unlock_irqrestore(&serial_lock, flags); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ASYNC_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + !(info->flags & ASYNC_CLOSING) && + (do_clocal || (serial_in(info, UART_MSR) & + UART_MSR_DCD))) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + schedule(); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&info->open_wait, &wait); + if (extra_count) + state->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +static int get_async_struct(int line, struct async_struct **ret_info) +{ + struct async_struct *info; + struct serial_state *sstate; + + sstate = rs_table + line; + sstate->count++; + if (sstate->info) { + *ret_info = sstate->info; + return 0; + } + info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); + if (!info) { + sstate->count--; + return -ENOMEM; + } + memset(info, 0, sizeof(struct async_struct)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + info->magic = SERIAL_MAGIC; + info->port = sstate->port; + info->flags = sstate->flags; + info->io_type = sstate->io_type; + info->iomem_base = sstate->iomem_base; + info->iomem_reg_shift = sstate->iomem_reg_shift; + info->xmit_fifo_size = sstate->xmit_fifo_size; + info->line = line; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->state = sstate; + if (sstate->info) { + kfree(info); + *ret_info = sstate->info; + return 0; + } + *ret_info = sstate->info = info; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct async_struct *info; + int retval, line; + unsigned long page; + + MOD_INC_USE_COUNT; + line = MINOR(tty->device) - tty->driver.minor_start; + if ((line < 0) || (line >= NR_PORTS)) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + retval = get_async_struct(line, &info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + tty->driver_data = info; + info->tty = tty; + if (serial_paranoia_check(info, tty->device, "rs_open")) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, + info->state->count); +#endif + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + if (!tmp_buf) { + page = get_zeroed_page(GFP_KERNEL); + if (!page) { + MOD_DEC_USE_COUNT; + return -ENOMEM; + } + if (tmp_buf) + free_page(page); + else + tmp_buf = (unsigned char *) page; + } + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); + MOD_DEC_USE_COUNT; +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open returning after block_til_ready with %d\n", + retval); +#endif + MOD_DEC_USE_COUNT; + return retval; + } + + if ((info->state->count == 1) && + (info->flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->state->normal_termios; + else + *tty->termios = info->state->callout_termios; + change_speed(info, 0); + } +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + change_speed(info, 0); + } +#endif + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open ttys%d successful...", info->line); +#endif + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline int line_info(char *buf, struct serial_state *state) +{ + struct async_struct *info = state->info, scr_info; + char stat_buf[30], control, status; + int ret; + unsigned long flags; + + ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d", + state->line, uart_config[state->type].name, + state->port, state->irq); + + if (!state->port || (state->type == PORT_UNKNOWN)) { + ret += sprintf(buf+ret, "\n"); + return ret; + } + + /* + * Figure out the current RS-232 lines + */ + if (!info) { + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->port = state->port; + info->flags = state->flags; + info->quot = 0; + info->tty = 0; + } + spin_lock_irqsave(&serial_lock, flags); + status = serial_in(info, UART_MSR); + control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR); + spin_unlock_irqrestore(&serial_lock, flags); + + stat_buf[0] = 0; + stat_buf[1] = 0; + if (control & UART_MCR_RTS) + strcat(stat_buf, "|RTS"); + if (status & UART_MSR_CTS) + strcat(stat_buf, "|CTS"); + if (control & UART_MCR_DTR) + strcat(stat_buf, "|DTR"); + if (status & UART_MSR_DSR) + strcat(stat_buf, "|DSR"); + if (status & UART_MSR_DCD) + strcat(stat_buf, "|CD"); + if (status & UART_MSR_RI) + strcat(stat_buf, "|RI"); + + if (info->quot) { + ret += sprintf(buf+ret, " baud:%d", + state->baud_base / info->quot); + } + + ret += sprintf(buf+ret, " tx:%d rx:%d", + state->icount.tx, state->icount.rx); + + if (state->icount.frame) + ret += sprintf(buf+ret, " fe:%d", state->icount.frame); + + if (state->icount.parity) + ret += sprintf(buf+ret, " pe:%d", state->icount.parity); + + if (state->icount.brk) + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); + + if (state->icount.overrun) + ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); + + /* + * Last thing is the RS-232 status lines + */ + ret += sprintf(buf+ret, " %s\n", stat_buf+1); + return ret; +} + +int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n", + serial_version, LOCAL_VERSTRING, serial_revdate); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_table[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * --------------------------------------------------------------------- + * rs_init() and friends + * + * rs_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +/* + * This routine prints out the appropriate serial driver version + * number, and identifies which options were configured into this + * driver. + */ +static char serial_options[] __initdata = + " no serial options enabled\n"; +#undef SERIAL_OPT + +static _INLINE_ void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, + serial_version, LOCAL_VERSTRING, serial_revdate, + serial_options); +} + + +/* + * This routine is called by rs_init() to initialize a specific serial + * port. It determines what type of UART chip this serial port is + * using: 8250, 16450, 16550, 16550A. The important question is + * whether or not this UART is a 16550A or not, since this will + * determine whether or not we can use its FIFO features or not. + */ +static void autoconfig(struct serial_state * state) +{ + struct async_struct *info, scr_info; + unsigned long flags; + + +#ifdef SERIAL_DEBUG_AUTOCONF + printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line, + state->port, (unsigned) state->iomem_base); +#endif + + if (!CONFIGURED_SERIAL_PORT(state)) + return; + + if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { + au_writel(3, UART_MOD_CNTRL + state->port); + au_sync_delay(10); + } + + state->type = PORT_16550; + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->state = state; + info->port = state->port; + info->flags = state->flags; + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; + + + spin_lock_irqsave(&serial_lock, flags); + state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; + + if (info->port) { + request_region(info->port,8,"serial(auto)"); + } + + /* + * Reset the UART. + */ + serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(info, UART_FCR, 0); + (void)serial_in(info, UART_RX); + serial_outp(info, UART_IER, 0); + spin_unlock_irqrestore(&serial_lock, flags); +} + +int register_serial(struct serial_struct *req); +void unregister_serial(int line); + +/* + * The serial driver boot-time initialization code! + */ +static int __init rs_init(void) +{ + int i; + struct serial_state * state; + + init_bh(SERIAL_BH, do_serial_bh); + init_timer(&serial_timer); + serial_timer.function = rs_timer; + mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); + + for (i = 0; i < NR_IRQS; i++) { + IRQ_ports[i] = 0; + IRQ_timeout[i] = 0; + } +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + /* + * The interrupt of the serial console port + * can't be shared. + */ + if (sercons.flags & CON_CONSDEV) { + for(i = 0; i < NR_PORTS; i++) + if (i != sercons.index && + rs_table[i].irq == rs_table[sercons.index].irq) + rs_table[i].irq = 0; + } +#endif + show_serial_version(); + + /* Initialize the tty_driver structure */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + serial_driver.driver_name = "serial"; +#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) + serial_driver.name = "tts/%d"; +#else + serial_driver.name = "ttyS"; +#endif + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET; + serial_driver.num = NR_PORTS; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.put_char = rs_put_char; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + serial_driver.break_ctl = rs_break; + serial_driver.send_xchar = rs_send_xchar; + serial_driver.wait_until_sent = rs_wait_until_sent; + serial_driver.read_proc = rs_read_proc; + + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; +#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) + callout_driver.name = "cua/%d"; +#else + callout_driver.name = "cua"; +#endif + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + callout_driver.read_proc = 0; + callout_driver.proc_entry = 0; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register serial driver"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver"); + + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + state->baud_base = get_au1x00_uart_baud_base(); + state->magic = SSTATE_MAGIC; + state->line = i; + state->type = PORT_UNKNOWN; + state->custom_divisor = 0; + state->close_delay = 5*HZ/10; + state->closing_wait = 30*HZ; + state->callout_termios = callout_driver.init_termios; + state->normal_termios = serial_driver.init_termios; + state->icount.cts = state->icount.dsr = + state->icount.rng = state->icount.dcd = 0; + state->icount.rx = state->icount.tx = 0; + state->icount.frame = state->icount.parity = 0; + state->icount.overrun = state->icount.brk = 0; + state->irq = irq_cannonicalize(state->irq); + if (state->hub6) + state->io_type = SERIAL_IO_HUB6; + if (state->port && check_region(state->port,8)) { + continue; + } + + if (state->flags & ASYNC_BOOT_AUTOCONF) { + autoconfig(state); + } + } + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + if (state->type == PORT_UNKNOWN) { + continue; + } + printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n", + state->line + SERIAL_DEV_OFFSET, + (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", + state->port, state->irq, + uart_config[state->type].name); + tty_register_devfs(&serial_driver, 0, + serial_driver.minor_start + state->line); + tty_register_devfs(&callout_driver, 0, + callout_driver.minor_start + state->line); + } + return 0; +} + +/* + * register_serial and unregister_serial allows for 16x50 serial ports to be + * configured at run-time, to support PCMCIA modems. + */ + +/** + * register_serial - configure a 16x50 serial port at runtime + * @req: request structure + * + * Configure the serial port specified by the request. If the + * port exists and is in use an error is returned. If the port + * is not currently in the table it is added. + * + * The port is then probed and if neccessary the IRQ is autodetected + * If this fails an error is returned. + * + * On success the port is ready to use and the line number is returned. + */ + +int register_serial(struct serial_struct *req) +{ + int i; + unsigned long flags; + struct serial_state *state; + struct async_struct *info; + unsigned long port; + + port = req->port; + if (HIGH_BITS_OFFSET) + port += (unsigned long) req->port_high << HIGH_BITS_OFFSET; + + spin_lock_irqsave(&serial_lock, flags); + for (i = 0; i < NR_PORTS; i++) { + if ((rs_table[i].port == port) && + (rs_table[i].iomem_base == req->iomem_base)) + break; + } + if (i == NR_PORTS) { + for (i = 0; i < NR_PORTS; i++) + if ((rs_table[i].type == PORT_UNKNOWN) && + (rs_table[i].count == 0)) + break; + } + if (i == NR_PORTS) { + spin_unlock_irqrestore(&serial_lock, flags); + return -1; + } + state = &rs_table[i]; + if (rs_table[i].count) { + spin_unlock_irqrestore(&serial_lock, flags); + printk("Couldn't configure serial #%d (port=%ld,irq=%d): " + "device already open\n", i, port, req->irq); + return -1; + } + state->irq = req->irq; + state->port = port; + state->flags = req->flags; + state->io_type = req->io_type; + state->iomem_base = req->iomem_base; + state->iomem_reg_shift = req->iomem_reg_shift; + if (req->baud_base) + state->baud_base = req->baud_base; + if ((info = state->info) != NULL) { + info->port = port; + info->flags = req->flags; + info->io_type = req->io_type; + info->iomem_base = req->iomem_base; + info->iomem_reg_shift = req->iomem_reg_shift; + } + autoconfig(state); + if (state->type == PORT_UNKNOWN) { + spin_unlock_irqrestore(&serial_lock, flags); + printk("register_serial(): autoconfig failed\n"); + return -1; + } + spin_unlock_irqrestore(&serial_lock, flags); + + printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n", + state->line + SERIAL_DEV_OFFSET, + state->iomem_base ? "iomem" : "port", + state->iomem_base ? (unsigned long)state->iomem_base : + state->port, state->irq, uart_config[state->type].name); + tty_register_devfs(&serial_driver, 0, + serial_driver.minor_start + state->line); + tty_register_devfs(&callout_driver, 0, + callout_driver.minor_start + state->line); + return state->line + SERIAL_DEV_OFFSET; +} + +/** + * unregister_serial - deconfigure a 16x50 serial port + * @line: line to deconfigure + * + * The port specified is deconfigured and its resources are freed. Any + * user of the port is disconnected as if carrier was dropped. Line is + * the port number returned by register_serial(). + */ + +void unregister_serial(int line) +{ + unsigned long flags; + struct serial_state *state = &rs_table[line]; + + spin_lock_irqsave(&serial_lock, flags); + if (state->info && state->info->tty) + tty_hangup(state->info->tty); + state->type = PORT_UNKNOWN; + printk(KERN_INFO "tty%02d unloaded\n", state->line); + /* These will be hidden, because they are devices that will no longer + * be available to the system. (ie, PCMCIA modems, once ejected) + */ + tty_unregister_devfs(&serial_driver, + serial_driver.minor_start + state->line); + tty_unregister_devfs(&callout_driver, + callout_driver.minor_start + state->line); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void __exit rs_fini(void) +{ + unsigned long flags; + int e1, e2; + int i; + struct async_struct *info; + + /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ + del_timer_sync(&serial_timer); + spin_lock_irqsave(&serial_lock, flags); + remove_bh(SERIAL_BH); + if ((e1 = tty_unregister_driver(&serial_driver))) + printk("serial: failed to unregister serial driver (%d)\n", + e1); + if ((e2 = tty_unregister_driver(&callout_driver))) + printk("serial: failed to unregister callout driver (%d)\n", + e2); + spin_unlock_irqrestore(&serial_lock, flags); + + for (i = 0; i < NR_PORTS; i++) { + if ((info = rs_table[i].info)) { + rs_table[i].info = NULL; + kfree(info); + } + if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) { + release_region(rs_table[i].port, 8); + } + } + if (tmp_buf) { + unsigned long pg = (unsigned long) tmp_buf; + tmp_buf = NULL; + free_page(pg); + } +} + +module_init(rs_init); +module_exit(rs_fini); +MODULE_DESCRIPTION("Au1x00 serial driver"); + + +/* + * ------------------------------------------------------------ + * Serial console driver + * ------------------------------------------------------------ + */ +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + +static struct async_struct async_sercons; + +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct async_struct *info) +{ + unsigned int status, tmout = 0xffffff; + + do { + status = serial_in(info, UART_LSR); + + if (status & UART_LSR_BI) + lsr_break_flag = UART_LSR_BI; + + if (--tmout == 0) + break; + } while((status & BOTH_EMPTY) != BOTH_EMPTY); +} + + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console_lock must be held when we get here. + */ +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + static struct async_struct *info = &async_sercons; + int ier; + unsigned i; + + /* + * First save the IER then disable the interrupts + */ + ier = serial_in(info, UART_IER); + serial_out(info, UART_IER, 0x00); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(info); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(info, UART_TX, *s); + if (*s == 10) { + wait_for_xmitr(info); + serial_out(info, UART_TX, 13); + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + wait_for_xmitr(info); + serial_out(info, UART_IER, ier); +} + +/* + * Receive character from the serial port + */ +static int serial_console_wait_key(struct console *co) +{ + static struct async_struct *info; + int ier, c; + + info = &async_sercons; + + /* + * First save the IER then disable the interrupts so + * that the real driver for the port does not get the + * character. + */ + ier = serial_in(info, UART_IER); + serial_out(info, UART_IER, 0x00); + + while ((serial_in(info, UART_LSR) & UART_LSR_DR) == 0); + c = serial_in(info, UART_RX); + + /* + * Restore the interrupts + */ + serial_out(info, UART_IER, ier); + + return c; +} + +static kdev_t serial_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +static int __init serial_console_setup(struct console *co, char *options) +{ + static struct async_struct *info; + struct serial_state *state; + unsigned cval; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + int quot = 0; + char *s; + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + co->cflag = cflag; + + /* + * Divisor, bytesize and parity + */ + state = rs_table + co->index; + info = &async_sercons; + info->magic = SERIAL_MAGIC; + info->state = state; + info->port = state->port; + info->flags = state->flags; + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; + state->baud_base = get_au1x00_uart_baud_base(); + quot = state->baud_base / baud; + + cval = cflag & (CSIZE | CSTOPB); + cval >>= 4; + if (cflag & PARENB) + cval |= UART_LCR_PARITY; + if (!(cflag & PARODD)) + cval |= UART_LCR_EPAR; + + /* + * Disable UART interrupts, set DTR and RTS high + * and set speed. + */ + serial_out(info, UART_CLK, quot & 0xffff); + serial_out(info, UART_IER, 0); + serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); + + /* + * If we read 0xff from the LSR, there is no UART here. + */ + if (serial_in(info, UART_LSR) == 0xff) + return -1; + + return 0; +} + +static struct console sercons = { + .name = "ttyS", + .write = serial_console_write, + .device = serial_console_device, + .setup = serial_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ +void __init au1x00_serial_console_init(void) +{ + register_console(&sercons); +} +#endif + +/* + Local variables: + compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" + End: +*/ diff -urN linux-2.4.21/drivers/char/briq_panel.c linux-2.4.22/drivers/char/briq_panel.c --- linux-2.4.21/drivers/char/briq_panel.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/briq_panel.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,251 @@ +/* + * Drivers for the Total Impact PPC based computer "BRIQ" + * by Dr. Karsten Jeppesen + * + * + * 010407 Coding started + * + * 04/20/2002 1.1 Adapted to 2.4, small cleanups + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define TOTALIMPACT_VFD_MINOR 156 +#define VFD_IOPORT 0x0390 +#define LED_IOPORT 0x0398 +#define TI_VER "1.1 (04/20/2002)" +#define TI_MSG0 "Loading Linux" + +static int vfd_is_open; +static unsigned char vfd[40]; +static int vfd_cursor; +static unsigned char ledpb, led; + + +static void UpdateVFD( void ) +{ + int i; + outb(0x02, VFD_IOPORT); /* cursor home */ + for (i=0; i<20; i++) outb(vfd[i], VFD_IOPORT + 1); + outb(0xc0, VFD_IOPORT); /* cursor to next line */ + for (i=20; i<40; i++) outb(vfd[i], VFD_IOPORT + 1); + +} + +static void SetLED( char state) +{ + if ( state == 'R' ) led = 0x01; + else if ( state == 'G' ) led = 0x02; + else if ( state == 'Y' ) led = 0x03; + else if ( state == 'X' ) led = 0x00; + outb(led, LED_IOPORT); +} + +static int do_open(struct inode *ino, struct file *filep) +{ + if (vfd_is_open) return -EBUSY; + MOD_INC_USE_COUNT; + vfd_is_open = 1; + return(0); +} + +static int do_release(struct inode *ino, struct file *filep) +{ + if (!vfd_is_open) return -ENODEV; + MOD_DEC_USE_COUNT; + vfd_is_open = 0; + return(0); +} + + +static ssize_t do_read(struct file *file, char *buf, size_t count, + loff_t *ppos) +{ + unsigned short c; + unsigned char cp; + + /* Can't seek (pread) on this device */ + if (ppos != &file->f_pos) return -ESPIPE; + if (!vfd_is_open) return -ENODEV; + c = (inb( LED_IOPORT ) & 0x000c) | (ledpb & 0x0003); + SetLED(' '); + if ((!(ledpb & 0x0004)) && (c & 0x0004)) + { /* upper button released */ + cp = ' '; + ledpb = c; + if (copy_to_user(buf, &cp, 1)) return -EFAULT; + return(1); + } + else if ((!(ledpb & 0x0008)) && (c & 0x0008)) + { /* lower button released */ + cp = '\r'; + ledpb = c; + if (copy_to_user(buf, &cp, 1)) return -EFAULT; + return(1); + } else + { + ledpb = c; + return(0); + } +} + + +static void ScrollVFD( void ) +{ + int i; + for (i=0; i<20; i++) + { + vfd[i] = vfd[i+20]; + vfd[i+20] = ' '; + } + vfd_cursor = 20; +} + + +static ssize_t do_write(struct file *file, const char *buf, size_t len, + loff_t *ppos) +{ + size_t indx = len; + int i, esc=0; + /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) return -ESPIPE; + if (!vfd_is_open) return -EBUSY; + for (;;) + { + if (!indx) break; + if (esc) + { + SetLED(*buf); + esc = 0; + } + else if (*buf == 27) + { + esc = 1; + } + else if (*buf == 12) + { /* do a form feed */ + for (i=0; i<40; i++) vfd[i] = ' '; + vfd_cursor = 0; + } + else if (*buf == 10) + { + if (vfd_cursor < 20) vfd_cursor = 20; + else if (vfd_cursor < 40) vfd_cursor = 40; + else if (vfd_cursor < 60) vfd_cursor = 60; + if (vfd_cursor > 59) ScrollVFD(); + } + else + { + /* just a character */ + if (vfd_cursor > 39) ScrollVFD(); + vfd[vfd_cursor++] = *buf; + } + indx--; + buf++; + } + UpdateVFD(); + return len; +} + + +static struct file_operations vfd_fops = { + read: do_read, /* Read */ + write: do_write, /* Write */ + open: do_open, /* Open */ + release: do_release, /* Release */ +}; + + +static struct miscdevice ti_vfd_miscdev = { + TOTALIMPACT_VFD_MINOR, + "vfd", + &vfd_fops +}; + + +static int __init briq_panel_init(void) +{ + struct device_node *root = find_path_device("/"); + char *machine; + int i; + + machine = get_property(root, "model", NULL); + if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) + return -ENODEV; + + printk(KERN_INFO "ti_briq: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n", TI_VER); + + if (!request_region( VFD_IOPORT, 4, "BRIQ Front Panel")) + return -EBUSY; + if (!request_region( LED_IOPORT, 2, "BRIQ Front Panel")) { + release_region(VFD_IOPORT, 4); + return -EBUSY; + } + ledpb = inb( LED_IOPORT ) & 0x000c; + + if (misc_register(&ti_vfd_miscdev) < 0) { + release_region(VFD_IOPORT, 4); + release_region(LED_IOPORT, 2); + return -EBUSY; + } + + outb(0x38, VFD_IOPORT); /* Function set */ + outb(0x01, VFD_IOPORT); /* Clear display */ + outb(0x0c, VFD_IOPORT); /* Display on */ + outb(0x06, VFD_IOPORT); /* Entry normal */ + for (i=0; i<40; i++) vfd[i]=' '; +#ifndef MODULE + vfd[0] = 'L'; + vfd[1] = 'o'; + vfd[2] = 'a'; + vfd[3] = 'd'; + vfd[4] = 'i'; + vfd[5] = 'n'; + vfd[6] = 'g'; + vfd[7] = ' '; + vfd[8] = '.'; + vfd[9] = '.'; + vfd[10] = '.'; +#endif /* !MODULE */ + UpdateVFD(); + + return 0; +} + + +static void __exit briq_panel_exit(void) +{ + misc_deregister(&ti_vfd_miscdev); + release_region(VFD_IOPORT, 4); + release_region(LED_IOPORT, 2); +} + + +module_init(briq_panel_init); +module_exit(briq_panel_exit); + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Karsten Jeppesen "); +MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel"); +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.21/drivers/char/decserial.c linux-2.4.22/drivers/char/decserial.c --- linux-2.4.21/drivers/char/decserial.c 2001-09-09 10:43:02.000000000 -0700 +++ linux-2.4.22/drivers/char/decserial.c 2003-08-25 04:44:41.000000000 -0700 @@ -28,7 +28,7 @@ extern int dz_init(void); #endif -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SERIAL_DEC_CONSOLE #ifdef CONFIG_ZS extern void zs_serial_console_init(void); @@ -43,7 +43,7 @@ /* rs_init - starts up the serial interface - handle normal case of starting up the serial interface */ -#ifdef CONFIG_SERIAL +#ifdef CONFIG_SERIAL_DEC int __init rs_init(void) { @@ -70,12 +70,12 @@ #endif -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SERIAL_DEC_CONSOLE -/* serial_console_init handles the special case of starting +/* dec_serial_console_init handles the special case of starting * up the console on the serial port */ -void __init serial_console_init(void) +void __init dec_serial_console_init(void) { #if defined(CONFIG_ZS) && defined(CONFIG_DZ) if (IOASIC) diff -urN linux-2.4.21/drivers/char/drm-4.0/agpsupport.c linux-2.4.22/drivers/char/drm-4.0/agpsupport.c --- linux-2.4.21/drivers/char/drm-4.0/agpsupport.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.22/drivers/char/drm-4.0/agpsupport.c 2003-08-25 04:44:41.000000000 -0700 @@ -278,6 +278,7 @@ case VIA_APOLLO_KT400: head->chipset = "VIA Apollo KT400"; break; case VIA_APOLLO_P4X400: head->chipset = "VIA Apollo P4X400"; + break; #endif case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; diff -urN linux-2.4.21/drivers/char/ds1286.c linux-2.4.22/drivers/char/ds1286.c --- linux-2.4.21/drivers/char/ds1286.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/ds1286.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,529 @@ +/* + * DS1286 Real Time Clock interface for Linux + * + * Copyright (C) 1998, 1999, 2000 Ralf Baechle + * + * Based on code written by Paul Gortmaker. + * + * This driver allows use of the real time clock (built into nearly all + * computers) from user space. It exports the /dev/rtc interface supporting + * various ioctl() and also the /proc/rtc pseudo-file for status + * information. + * + * The ioctls can be used to set the interrupt behaviour and generation rate + * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make + * use of these timer interrupts, be they interval or alarm based. + * + * The /dev/rtc interface will block on reads until an interrupt has been + * received. If a RTC interrupt has already happened, it will output an + * unsigned long and then block. The output value contains the interrupt + * status in the low byte and the number of interrupts since the last read + * in the remaining high bytes. The /dev/rtc interface can also be used with + * the select(2) call. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DS1286_VERSION "1.0" + +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static DECLARE_WAIT_QUEUE_HEAD(ds1286_wait); + +static ssize_t ds1286_read(struct file *file, char *buf, + size_t count, loff_t *ppos); + +static int ds1286_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static unsigned int ds1286_poll(struct file *file, poll_table *wait); + +void ds1286_get_alm_time (struct rtc_time *alm_tm); +void ds1286_get_time(struct rtc_time *rtc_tm); +int ds1286_set_time(struct rtc_time *rtc_tm); + +void set_rtc_irq_bit(unsigned char bit); +void clear_rtc_irq_bit(unsigned char bit); + +static inline unsigned char ds1286_is_updating(void); + +static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED; + +/* + * Bits in rtc_status. (7 bits of room for future expansion) + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ +#define RTC_TIMER_ON 0x02 /* missed irq timer active */ + +unsigned char ds1286_status; /* bitmapped status byte. */ +unsigned long ds1286_freq; /* Current periodic IRQ rate */ + +unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +/* + * Now all the various file operations that we export. + */ + +static ssize_t ds1286_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + return -EIO; +} + +static int ds1286_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + + struct rtc_time wtime; + + switch (cmd) { + case RTC_AIE_OFF: /* Mask alarm int. enab. bit */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val |= RTC_TDM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_AIE_ON: /* Allow alarm interrupts. */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val &= ~RTC_TDM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val |= RTC_WAM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_WIE_ON: /* Allow watchdog interrupts. */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val &= ~RTC_WAM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_ALM_READ: /* Read the present alarm time */ + { + /* + * This returns a struct rtc_time. Reading >= 0xc0 + * means "don't care" or "match all". Only the tm_hour, + * tm_min, and tm_sec values are filled in. + */ + + ds1286_get_alm_time(&wtime); + break; + } + case RTC_ALM_SET: /* Store a time into the alarm */ + { + /* + * This expects a struct rtc_time. Writing 0xff means + * "don't care" or "match all". Only the tm_hour, + * tm_min and tm_sec are used. + */ + unsigned char hrs, min, sec; + struct rtc_time alm_tm; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&alm_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + hrs = alm_tm.tm_hour; + min = alm_tm.tm_min; + + if (hrs >= 24) + hrs = 0xff; + + if (min >= 60) + min = 0xff; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + + spin_lock(&ds1286_lock); + CMOS_WRITE(hrs, RTC_HOURS_ALARM); + CMOS_WRITE(min, RTC_MINUTES_ALARM); + spin_unlock(&ds1286_lock); + + return 0; + } + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + ds1286_get_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + return ds1286_set_time(&rtc_tm); + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int ds1286_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&ds1286_lock); + + if (ds1286_status & RTC_IS_OPEN) + goto out_busy; + + ds1286_status |= RTC_IS_OPEN; + + spin_lock_irq(&ds1286_lock); + return 0; + +out_busy: + spin_lock_irq(&ds1286_lock); + return -EBUSY; +} + +static int ds1286_release(struct inode *inode, struct file *file) +{ + ds1286_status &= ~RTC_IS_OPEN; + + return 0; +} + +static unsigned int ds1286_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &ds1286_wait, wait); + + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations ds1286_fops = { + .llseek = no_llseek, + .read = ds1286_read, + .poll = ds1286_poll, + .ioctl = ds1286_ioctl, + .open = ds1286_open, + .release = ds1286_release, +}; + +static struct miscdevice ds1286_dev= +{ + .minor = RTC_MINOR, + .name = "rtc", + .fops = &ds1286_fops, +}; + +int __init ds1286_init(void) +{ + printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); + return misc_register(&ds1286_dev); +} + +static char *days[] = { + "***", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +/* + * Info exported via "/proc/rtc". + */ +int get_ds1286_status(char *buf) +{ + char *p, *s; + struct rtc_time tm; + unsigned char hundredth, month, cmd, amode; + + p = buf; + + ds1286_get_time(&tm); + hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND); + BCD_TO_BIN(hundredth); + + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d.%02d\n" + "rtc_date\t: %04d-%02d-%02d\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, hundredth, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + + /* + * We implicitly assume 24hr mode here. Alarm values >= 0xc0 will + * match any value for that particular field. Values that are + * greater than a valid time, but less than 0xc0 shouldn't appear. + */ + ds1286_get_alm_time(&tm); + p += sprintf(p, "alarm\t\t: %s ", days[tm.tm_wday]); + if (tm.tm_hour <= 24) + p += sprintf(p, "%02d:", tm.tm_hour); + else + p += sprintf(p, "**:"); + + if (tm.tm_min <= 59) + p += sprintf(p, "%02d\n", tm.tm_min); + else + p += sprintf(p, "**\n"); + + month = CMOS_READ(RTC_MONTH); + p += sprintf(p, + "oscillator\t: %s\n" + "square_wave\t: %s\n", + (month & RTC_EOSC) ? "disabled" : "enabled", + (month & RTC_ESQW) ? "disabled" : "enabled"); + + amode = ((CMOS_READ(RTC_MINUTES_ALARM) & 0x80) >> 5) | + ((CMOS_READ(RTC_HOURS_ALARM) & 0x80) >> 6) | + ((CMOS_READ(RTC_DAY_ALARM) & 0x80) >> 7); + if (amode == 7) s = "each minute"; + else if (amode == 3) s = "minutes match"; + else if (amode == 1) s = "hours and minutes match"; + else if (amode == 0) s = "days, hours and minutes match"; + else s = "invalid"; + p += sprintf(p, "alarm_mode\t: %s\n", s); + + cmd = CMOS_READ(RTC_CMD); + p += sprintf(p, + "alarm_enable\t: %s\n" + "wdog_alarm\t: %s\n" + "alarm_mask\t: %s\n" + "wdog_alarm_mask\t: %s\n" + "interrupt_mode\t: %s\n" + "INTB_mode\t: %s_active\n" + "interrupt_pins\t: %s\n", + (cmd & RTC_TDF) ? "yes" : "no", + (cmd & RTC_WAF) ? "yes" : "no", + (cmd & RTC_TDM) ? "disabled" : "enabled", + (cmd & RTC_WAM) ? "disabled" : "enabled", + (cmd & RTC_PU_LVL) ? "pulse" : "level", + (cmd & RTC_IBH_LO) ? "low" : "high", + (cmd & RTC_IPSW) ? "unswapped" : "swapped"); + + return p - buf; +} + +/* + * Returns true if a clock update is in progress + */ +static inline unsigned char ds1286_is_updating(void) +{ + return CMOS_READ(RTC_CMD) & RTC_TE; +} + + +void ds1286_get_time(struct rtc_time *rtc_tm) +{ + unsigned char save_control; + unsigned int flags; + unsigned long uip_watchdog = jiffies; + + /* + * read RTC once any update in progress is done. The update + * can take just over 2ms. We wait 10 to 20ms. There is no need to + * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. + * If you need to know *exactly* when a second has started, enable + * periodic update complete interrupts, (via ioctl) and then + * immediately read /dev/rtc which will block until you get the IRQ. + * Once the read clears, read the RTC time (again via ioctl). Easy. + */ + + if (ds1286_is_updating() != 0) + while (jiffies - uip_watchdog < 2*HZ/100) + barrier(); + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + spin_lock_irqsave(&ds1286_lock, flags); + save_control = CMOS_READ(RTC_CMD); + CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + + rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); + rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); + rtc_tm->tm_hour = CMOS_READ(RTC_HOURS) & 0x1f; + rtc_tm->tm_mday = CMOS_READ(RTC_DATE); + rtc_tm->tm_mon = CMOS_READ(RTC_MONTH) & 0x1f; + rtc_tm->tm_year = CMOS_READ(RTC_YEAR); + + CMOS_WRITE(save_control, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + BCD_TO_BIN(rtc_tm->tm_sec); + BCD_TO_BIN(rtc_tm->tm_min); + BCD_TO_BIN(rtc_tm->tm_hour); + BCD_TO_BIN(rtc_tm->tm_mday); + BCD_TO_BIN(rtc_tm->tm_mon); + BCD_TO_BIN(rtc_tm->tm_year); + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + if (rtc_tm->tm_year < 45) + rtc_tm->tm_year += 30; + if ((rtc_tm->tm_year += 40) < 70) + rtc_tm->tm_year += 100; + + rtc_tm->tm_mon--; +} + +int ds1286_set_time(struct rtc_time *rtc_tm) +{ + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned char save_control; + unsigned int yrs, flags; + + + yrs = rtc_tm->tm_year + 1900; + mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm->tm_mday; + hrs = rtc_tm->tm_hour; + min = rtc_tm->tm_min; + sec = rtc_tm->tm_sec; + + if (yrs < 1970) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ((yrs -= 1940) > 255) /* They are unsigned */ + return -EINVAL; + + if (yrs >= 100) + yrs -= 100; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(yrs); + + spin_lock_irqsave(&ds1286_lock, flags); + save_control = CMOS_READ(RTC_CMD); + CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + + CMOS_WRITE(yrs, RTC_YEAR); + CMOS_WRITE(mon, RTC_MONTH); + CMOS_WRITE(day, RTC_DATE); + CMOS_WRITE(hrs, RTC_HOURS); + CMOS_WRITE(min, RTC_MINUTES); + CMOS_WRITE(sec, RTC_SECONDS); + CMOS_WRITE(0, RTC_HUNDREDTH_SECOND); + + CMOS_WRITE(save_control, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; +} + +void ds1286_get_alm_time(struct rtc_time *alm_tm) +{ + unsigned char cmd; + unsigned int flags; + + /* + * Only the values that we read from the RTC are set. That + * means only tm_wday, tm_hour, tm_min. + */ + spin_lock_irqsave(&ds1286_lock, flags); + alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM) & 0x7f; + alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM) & 0x1f; + alm_tm->tm_wday = CMOS_READ(RTC_DAY_ALARM) & 0x07; + cmd = CMOS_READ(RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + BCD_TO_BIN(alm_tm->tm_min); + BCD_TO_BIN(alm_tm->tm_hour); + alm_tm->tm_sec = 0; +} diff -urN linux-2.4.21/drivers/char/dummy_keyb.c linux-2.4.22/drivers/char/dummy_keyb.c --- linux-2.4.21/drivers/char/dummy_keyb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/dummy_keyb.c 2003-08-25 04:44:41.000000000 -0700 @@ -23,9 +23,12 @@ * CONFIG_VT. * */ + +#include #include #include #include +#include void kbd_leds(unsigned char leds) { @@ -41,6 +44,84 @@ return scancode; } +#ifdef CONFIG_INPUT +static unsigned char e0_keys[128] = { + 0, 0, 0, KEY_KPCOMMA, 0, KEY_INTL3, 0, 0, /* 0x00-0x07 */ + 0, 0, 0, 0, KEY_LANG1, KEY_LANG2, 0, 0, /* 0x08-0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ + 0, 0, 0, 0, KEY_KPENTER, KEY_RIGHTCTRL, KEY_VOLUMEUP, 0,/* 0x18-0x1f */ + 0, 0, 0, 0, 0, KEY_VOLUMEDOWN, KEY_MUTE, 0, /* 0x20-0x27 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ + 0, 0, 0, 0, 0, KEY_KPSLASH, 0, KEY_SYSRQ, /* 0x30-0x37 */ + KEY_RIGHTALT, KEY_BRIGHTNESSUP, KEY_BRIGHTNESSDOWN, + KEY_EJECTCD, 0, 0, 0, 0, /* 0x38-0x3f */ + 0, 0, 0, 0, 0, 0, 0, KEY_HOME, /* 0x40-0x47 */ + KEY_UP, KEY_PAGEUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END, /* 0x48-0x4f */ + KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, 0, 0, 0, 0, /* 0x50-0x57 */ + 0, 0, 0, KEY_LEFTMETA, KEY_RIGHTMETA, KEY_COMPOSE, KEY_POWER, 0, /* 0x58-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, 0, 0, KEY_MACRO, /* 0x68-0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ + 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */ +}; + +int kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + /* This code was copied from char/pc_keyb.c and will be + * superflous when the input layer is fully integrated. + * We don't need the high_keys handling, so this part + * has been removed. + */ + static int prev_scancode = 0; + + /* special prefix scancodes.. */ + if (scancode == 0xe0 || scancode == 0xe1) { + prev_scancode = scancode; + return 0; + } + + scancode &= 0x7f; + + if (prev_scancode) { + if (prev_scancode != 0xe0) { + if (prev_scancode == 0xe1 && scancode == 0x1d) { + prev_scancode = 0x100; + return 0; + } else if (prev_scancode == 0x100 && scancode == 0x45) { + *keycode = KEY_PAUSE; + prev_scancode = 0; + } else { + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown e1 escape sequence\n"); + prev_scancode = 0; + return 0; + } + } else { + prev_scancode = 0; + if (scancode == 0x2a || scancode == 0x36) + return 0; + } + if (e0_keys[scancode]) + *keycode = e0_keys[scancode]; + else { + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n", + scancode); + return 0; + } + } else { + switch (scancode) { + case 91: scancode = KEY_LINEFEED; break; + case 92: scancode = KEY_KPEQUAL; break; + case 125: scancode = KEY_INTL1; break; + } + *keycode = scancode; + } + return 1; +} + +#else int kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode) { @@ -48,6 +129,7 @@ return 1; } +#endif char kbd_unexpected_up(unsigned char keycode) { diff -urN linux-2.4.21/drivers/char/dz.c linux-2.4.22/drivers/char/dz.c --- linux-2.4.21/drivers/char/dz.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/dz.c 2003-08-25 04:44:41.000000000 -0700 @@ -35,28 +35,27 @@ #include #include #include -#include -#include #include #include #include #include -#include -#include -#include -#include -#include - #include #include + #include +#include +#include +#include +#include +#include +#include +#include +#include #define CONSOLE_LINE (3) /* for definition of struct console */ -extern int (*prom_printf) (char *,...); - #include "dz.h" #define DZ_INTR_DEBUG 1 @@ -211,13 +210,12 @@ if (!(status & DZ_DVAL)) goto ignore_char; - ch = UCHAR(status); /* grab the char */ #if 0 if (info->is_console) { if (ch == 0) - return; /* it's a break ... */ + return; /* it's a break ... */ } #endif @@ -862,7 +860,7 @@ tmp.type = info->type; tmp.line = info->line; tmp.port = info->port; - tmp.irq = SERIAL; + tmp.irq = dec_interrupt[DEC_IRQ_DZ11]; tmp.flags = info->flags; tmp.baud_base = info->baud_base; tmp.close_delay = info->close_delay; @@ -1404,7 +1402,7 @@ return 0; printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line, - info->port, SERIAL); + info->port, dec_interrupt[DEC_IRQ_DZ11]); tty_register_devfs(&serial_driver, 0, serial_driver.minor_start + info->line); @@ -1413,10 +1411,10 @@ } /* reset the chip */ -#ifndef CONFIG_SERIAL_CONSOLE +#ifndef CONFIG_SERIAL_DEC_CONSOLE dz_out(info, DZ_CSR, DZ_CLR); while ((tmp = dz_in(info, DZ_CSR)) & DZ_CLR); - wbflush(); + iob(); /* enable scanning */ dz_out(info, DZ_CSR, DZ_MSE); @@ -1428,13 +1426,14 @@ restore_flags(flags); - if (request_irq(SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0])) + if (request_irq(dec_interrupt[DEC_IRQ_DZ11], dz_interrupt, + SA_INTERRUPT, "DZ", lines[0])) panic("Unable to register DZ interrupt"); return 0; } -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SERIAL_DEC_CONSOLE static void dz_console_put_char(unsigned char ch) { unsigned long flags; @@ -1575,12 +1574,12 @@ static struct console dz_sercons = { - name: "ttyS", - write: dz_console_print, - device: dz_console_device, - setup: dz_console_setup, - flags: CON_CONSDEV | CON_PRINTBUFFER, - index: CONSOLE_LINE, + .name = "ttyS", + .write = dz_console_print, + .device = dz_console_device, + .setup = dz_console_setup, + .flags = CON_CONSDEV | CON_PRINTBUFFER, + .index = CONSOLE_LINE, }; void __init dz_serial_console_init(void) @@ -1588,6 +1587,6 @@ register_console(&dz_sercons); } -#endif /* CONFIG_SERIAL_CONSOLE */ +#endif /* CONFIG_SERIAL_DEC_CONSOLE */ MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/char/indydog.c linux-2.4.22/drivers/char/indydog.c --- linux-2.4.21/drivers/char/indydog.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/char/indydog.c 2003-08-25 04:44:41.000000000 -0700 @@ -22,10 +22,9 @@ #include #include #include -#include +#include static unsigned long indydog_alive; -static struct sgimc_misc_ctrl *mcmisc_regs; static int expect_close = 0; #ifdef CONFIG_WATCHDOG_NOWAYOUT @@ -37,56 +36,51 @@ MODULE_PARM(nowayout,"i"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); -static void indydog_ping() +static inline void indydog_ping(void) { - mcmisc_regs->watchdogt = 0; + sgimc->watchdogt = 0; } - /* * Allow only one person to hold it open */ - static int indydog_open(struct inode *inode, struct file *file) { u32 mc_ctrl0; - if( test_and_set_bit(0,&indydog_alive) ) + if (test_and_set_bit(0,&indydog_alive)) return -EBUSY; + if (nowayout) { MOD_INC_USE_COUNT; } - /* - * Activate timer - */ - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - mc_ctrl0 = mcmisc_regs->cpuctrl0 | SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; + /* Activate timer */ + mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; indydog_ping(); - printk("Started watchdog timer.\n"); + indydog_alive = 1; + printk(KERN_INFO "Started watchdog timer.\n"); + return 0; } static int indydog_release(struct inode *inode, struct file *file) { - /* - * Shut off the timer. - * Lock it in if it's a module and we set nowayout. - */ - if (expect_close) - { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; + /* Shut off the timer. + * Lock it in if it's a module and we set nowayout. */ + lock_kernel(); + if (expect_close) { + u32 mc_ctrl0 = sgimc->cpuctrl0; mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; - printk("Stopped watchdog timer.\n"); - } - else - { + sgimc->cpuctrl0 = mc_ctrl0; + printk(KERN_INFO "Stopped watchdog timer.\n"); + } else printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); - } - clear_bit(0,&indydog_alive); + clear_bit(0, &indydog_alive); + unlock_kernel(); + return 0; } @@ -99,13 +93,13 @@ /* * Refresh the timer. */ - if(len) { + if (len) { if (!nowayout) { size_t i; /* In case it was set long ago */ expect_close = 0; - + for (i = 0; i != len; i++) { char c; if (get_user(c, data + i)) @@ -161,9 +155,7 @@ static int __init watchdog_init(void) { - int ret; - - ret = misc_register(&indydog_miscdev); + int ret = misc_register(&indydog_miscdev); if (ret) return ret; diff -urN linux-2.4.21/drivers/char/ip27-rtc.c linux-2.4.22/drivers/char/ip27-rtc.c --- linux-2.4.21/drivers/char/ip27-rtc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/ip27-rtc.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,326 @@ +/* + * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip + * + * Real Time Clock interface for Linux + * + * TODO: Implement periodic interrupts. + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * + * Based on code written by Paul Gortmaker. + * + * This driver allows use of the real time clock (built into + * nearly all computers) from user space. It exports the /dev/rtc + * interface supporting various ioctl() and also the /proc/rtc + * pseudo-file for status information. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#define RTC_VERSION "1.09b" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +static void get_rtc_time(struct rtc_time *rtc_tm); + +/* + * Bits in rtc_status. (6 bits of room for future expansion) + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ +#define RTC_TIMER_ON 0x02 /* missed irq timer active */ + +static unsigned char rtc_status; /* bitmapped status byte. */ +static unsigned long rtc_freq; /* Current periodic IRQ rate */ +static struct m48t35_rtc *rtc; + +/* + * If this driver ever becomes modularised, it will be really nice + * to make the epoch retain its value across module reload... + */ + +static unsigned long epoch = 1970; /* year corresponding to 0x00 */ + +static const unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + + struct rtc_time wtime; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + get_rtc_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned int yrs; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + yrs = rtc_tm.tm_year + 1900; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; + + if (yrs < 1970) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ((yrs -= epoch) > 255) /* They are unsigned */ + return -EINVAL; + + if (yrs > 169) { + return -EINVAL; + } + if (yrs >= 100) + yrs -= 100; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(yrs); + + spin_lock_irq(&rtc_lock); + rtc->control |= M48T35_RTC_SET; + rtc->year = yrs; + rtc->month = mon; + rtc->date = day; + rtc->hour = hrs; + rtc->min = min; + rtc->sec = sec; + rtc->control &= ~M48T35_RTC_SET; + spin_unlock_irq(&rtc_lock); + + return 0; + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + /* + * No need for locking -- nobody else can do anything until this rmw + * is committed, and no timer is running. + */ + rtc_status &= ~RTC_IS_OPEN; + + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, +}; + +static struct miscdevice rtc_dev= +{ + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int __init rtc_init(void) +{ + nasid_t nid; + + nid = get_nasid(); + rtc = (struct m48t35_rtc *) + (KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); + + printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); + if (misc_register(&rtc_dev)) { + printk(KERN_ERR "rtc: cannot register misc device.\n"); + return -ENODEV; + } + if (!create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL)) { + printk(KERN_ERR "rtc: cannot create /proc/rtc.\n"); + misc_deregister(&rtc_dev); + return -ENOENT; + } + + + rtc_freq = 1024; + return 0; +} + +static void __exit rtc_exit (void) +{ + /* interrupts and timer disabled at this point by rtc_release */ + + remove_proc_entry ("rtc", NULL); + misc_deregister(&rtc_dev); +} + +module_init(rtc_init); +module_exit(rtc_exit); + +/* + * Info exported via "/proc/rtc". + */ + +static int rtc_get_status(char *buf) +{ + char *p; + struct rtc_time tm; + + /* + * Just emulate the standard /proc/rtc + */ + + p = buf; + + get_rtc_time(&tm); + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n" + "24hr\t\t: yes\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_get_status(page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static void get_rtc_time(struct rtc_time *rtc_tm) +{ + /* + * Do we need to wait for the last update to finish? + */ + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + spin_lock_irq(&rtc_lock); + rtc->control |= M48T35_RTC_READ; + rtc_tm->tm_sec = rtc->sec; + rtc_tm->tm_min = rtc->min; + rtc_tm->tm_hour = rtc->hour; + rtc_tm->tm_mday = rtc->date; + rtc_tm->tm_mon = rtc->month; + rtc_tm->tm_year = rtc->year; + rtc->control &= ~M48T35_RTC_READ; + spin_unlock_irq(&rtc_lock); + + BCD_TO_BIN(rtc_tm->tm_sec); + BCD_TO_BIN(rtc_tm->tm_min); + BCD_TO_BIN(rtc_tm->tm_hour); + BCD_TO_BIN(rtc_tm->tm_mday); + BCD_TO_BIN(rtc_tm->tm_mon); + BCD_TO_BIN(rtc_tm->tm_year); + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) + rtc_tm->tm_year += 100; + + rtc_tm->tm_mon--; +} diff -urN linux-2.4.21/drivers/char/ipmi/ipmi_kcs_intf.c linux-2.4.22/drivers/char/ipmi/ipmi_kcs_intf.c --- linux-2.4.21/drivers/char/ipmi/ipmi_kcs_intf.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/ipmi/ipmi_kcs_intf.c 2003-08-25 04:44:41.000000000 -0700 @@ -1025,16 +1025,16 @@ return rv; } -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI_INTERPRETER /* Retrieve the base physical address from ACPI tables. Originally from Hewlett-Packard simple bmc.c, a GPL KCS driver. */ #include /* A real hack, but everything's not there yet in 2.4. */ -#define COMPILER_DEPENDENT_UINT64 unsigned long -#include <../drivers/acpi/include/acpi.h> -#include <../drivers/acpi/include/actypes.h> +#include +#include +#include struct SPMITable { s8 Signature[4]; @@ -1059,7 +1059,7 @@ static unsigned long acpi_find_bmc(void) { acpi_status status; - acpi_table_header *spmi; + struct acpi_table_header *spmi; static unsigned long io_base = 0; if (io_base != 0) @@ -1085,7 +1085,7 @@ int rv = 0; int pos = 0; int i = 0; -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI_INTERPRETER unsigned long physaddr = 0; #endif @@ -1115,7 +1115,7 @@ (because they weren't already specified above). */ if (kcs_trydefaults) { -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI_INTERPRETER if ((physaddr = acpi_find_bmc())) { if (!check_mem_region(physaddr, 2)) { rv = init_one_kcs(0, diff -urN linux-2.4.21/drivers/char/ite_gpio.c linux-2.4.22/drivers/char/ite_gpio.c --- linux-2.4.21/drivers/char/ite_gpio.c 2001-09-09 10:43:02.000000000 -0700 +++ linux-2.4.22/drivers/char/ite_gpio.c 2003-08-25 04:44:41.000000000 -0700 @@ -30,9 +30,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include -#include #include #include #include diff -urN linux-2.4.21/drivers/char/keyboard.c linux-2.4.22/drivers/char/keyboard.c --- linux-2.4.21/drivers/char/keyboard.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/keyboard.c 2003-08-25 04:44:41.000000000 -0700 @@ -336,21 +336,6 @@ schedule_console_callback(); } -#ifdef CONFIG_FORWARD_KEYBOARD -extern int forward_chars; - -void put_queue(int ch) -{ - if (forward_chars == fg_console+1){ - kbd_forward_char (ch); - } else { - if (tty) { - tty_insert_flip_char(tty, ch, 0); - con_schedule_flip(tty); - } - } -} -#else void put_queue(int ch) { if (tty) { @@ -358,7 +343,6 @@ con_schedule_flip(tty); } } -#endif static void puts_queue(char *cp) { diff -urN linux-2.4.21/drivers/char/lcd.c linux-2.4.22/drivers/char/lcd.c --- linux-2.4.21/drivers/char/lcd.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/lcd.c 2003-08-25 04:44:41.000000000 -0700 @@ -14,6 +14,7 @@ #define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ +#include #include #include #include diff -urN linux-2.4.21/drivers/char/lcd.h linux-2.4.22/drivers/char/lcd.h --- linux-2.4.21/drivers/char/lcd.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/lcd.h 2003-08-25 04:44:41.000000000 -0700 @@ -37,10 +37,10 @@ #define LCD_DRIVER "Cobalt LCD Driver v2.10" -#define kLCD_IR 0xBF000000 -#define kLCD_DR 0xBF000010 -#define kGPI 0xBD000000 -#define kLED 0xBC000000 +#define kLCD_IR 0x0F000000 +#define kLCD_DR 0x0F000010 +#define kGPI 0x0D000000 +#define kLED 0x0C000000 #define kDD_R00 0x00 #define kDD_R01 0x27 @@ -53,7 +53,7 @@ // Flash definitions AMD 29F040 -#define kFlashBase 0xBFC00000 +#define kFlashBase 0x0FC00000 #define kFlash_Addr1 0x5555 #define kFlash_Addr2 0x2AAA @@ -74,21 +74,21 @@ // Macros -#define LCDWriteData(x) (*(volatile unsigned long *) kLCD_DR) = (x << 24) -#define LCDWriteInst(x) (*(volatile unsigned long *) kLCD_IR) = (x << 24) +#define LCDWriteData(x) outl((x << 24), kLCD_DR) +#define LCDWriteInst(x) outl((x << 24), kLCD_IR) -#define LCDReadData (((*(volatile unsigned long *) kLCD_DR) >> 24)) -#define LCDReadInst (((*(volatile unsigned long *) kLCD_IR) >> 24)) +#define LCDReadData (inl(kLCD_DR) >> 24) +#define LCDReadInst (inl(kLCD_IR) >> 24) -#define GPIRead (( (*(volatile unsigned long *) kGPI) >> 24)) +#define GPIRead (inl(kGPI) >> 24) -#define LEDSet(x) (*(volatile unsigned char *) kLED) = ((char)x) +#define LEDSet(x) outb((char)x, kLED) -#define WRITE_GAL(x,y) (*((volatile unsigned long *) (0xB4000000 | (x)) ) =y) -#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80) +#define WRITE_GAL(x,y) outl(y, 0x04000000 | (x)) +#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80) -#define WRITE_FLASH(x,y) (*((volatile unsigned char *) (kFlashBase | (x)) ) = y) -#define READ_FLASH(x) *((volatile unsigned char *) (kFlashBase | (x)) ) +#define WRITE_FLASH(x,y) outb((char)y, kFlashBase | (x)) +#define READ_FLASH(x) (inb(kFlashBase | (x))) diff -urN linux-2.4.21/drivers/char/mips_rtc.c linux-2.4.22/drivers/char/mips_rtc.c --- linux-2.4.21/drivers/char/mips_rtc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/mips_rtc.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,221 @@ +/* + * A simple generic Real Time Clock interface for Linux/MIPS + * + * Copyright (C) 1996 Paul Gortmaker + * + * Copyright (C) 2001 Monta Vista Software + * Author Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This is a simple generic RTC driver for MIPS boards configured + * with CONFIG_NEW_TIME_C. For now, it makes use of the two + * abstract kernel RTC functions introduced in include/asm-mips/time.h: + * + * extern unsigned long (*rtc_get_time)(void); + * extern int (*rtc_set_time)(unsigned long); + * + * It uses the same protocol as the original drivers/char/rtc.c driver, + * but only implements two ioctls: RTC_RD_TIME and RTC_SET_TIME. + * + * TODO : + * + * 1. we can extend the null rtc ops defined in arch/mips/time.c to + * at least record the elapsed time (by recording/checking jiffies) + * This way RTC_RD_TIME and RTC_SET_TIME will make more sense. + * (Maybe not. A machine without a real RTC is broken anymore. + * Just a thought.) + * + * 2. If we make use of timer bh, we can emulate many RTC functions + * such as RTC alarm interrupt, periodic interrupts, etc. + * + * 3. It is possible to extend the kernel RTC abstractions to more + * than two functions, so that perhaps we can implement more + * full-featured RTC driver and also have a better abstraction + * to support more RTC hardware than the original RTC driver. + * It needs to be done very carefully. + * + * Change Log : + * v1.0 - [jsun] initial version + */ + +#define RTC_VERSION "1.0" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Check machine + */ +#if !defined(CONFIG_MIPS) || !defined(CONFIG_NEW_TIME_C) +#error "This driver is for MIPS machines with CONFIG_NEW_TIME_C defined" +#endif + +#include + +static unsigned long rtc_status = 0; /* bitmapped status byte. */ + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ + +static spinlock_t rtc_lock; + +static int +rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct rtc_time rtc_tm; + ulong curr_time; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + curr_time = rtc_get_time(); + to_tm(curr_time, &rtc_tm); + rtc_tm.tm_year -= 1900; + return copy_to_user((void *) arg, &rtc_tm, sizeof(rtc_tm)) ? + -EFAULT : 0; + case RTC_SET_TIME: /* Set the RTC */ + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, + (struct rtc_time *) arg, + sizeof(struct rtc_time))) + return -EFAULT; + + curr_time = mktime(rtc_tm.tm_year + 1900, + rtc_tm.tm_mon + 1, /* tm_mon starts from 0 */ + rtc_tm.tm_mday, + rtc_tm.tm_hour, + rtc_tm.tm_min, + rtc_tm.tm_sec); + return rtc_set_time(curr_time); + default: + return -EINVAL; + } +} + +/* We use rtc_lock to protect against concurrent opens. So the BKL is not + * needed here. Or anywhere else in this driver. */ +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + + spin_unlock_irq(&rtc_lock); + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + rtc_status &= ~RTC_IS_OPEN; + spin_unlock_irq(&rtc_lock); + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + owner:THIS_MODULE, + llseek:no_llseek, + ioctl:rtc_ioctl, + open:rtc_open, + release:rtc_release, +}; + +static struct miscdevice rtc_dev = { + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int __init rtc_init(void) +{ + + misc_register(&rtc_dev); + create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL); + + printk(KERN_INFO "Generic MIPS RTC Driver v" RTC_VERSION "\n"); + + return 0; +} + +static void __exit rtc_exit(void) +{ + remove_proc_entry("driver/rtc", NULL); + misc_deregister(&rtc_dev); + +} + +module_init(rtc_init); +module_exit(rtc_exit); +EXPORT_NO_SYMBOLS; + +/* + * Info exported via "/proc/driver/rtc". + */ + +static int rtc_proc_output(char *buf) +{ + char *p; + struct rtc_time tm; + unsigned long curr_time; + + curr_time = rtc_get_time(); + to_tm(curr_time, &tm); + + p = buf; + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, 0L); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_proc_output(page); + if (len <= off + count) + *eof = 1; + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + return len; +} + +MODULE_AUTHOR("Jun Sun"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/char/misc.c linux-2.4.22/drivers/char/misc.c --- linux-2.4.21/drivers/char/misc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/misc.c 2003-08-25 04:44:41.000000000 -0700 @@ -66,10 +66,7 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8]; extern int psaux_init(void); -#ifdef CONFIG_SGI_NEWPORT_GFX extern void gfx_register(void); -#endif -extern void streamable_init(void); extern int rtc_DP8570A_init(void); extern int rtc_MK48T08_init(void); extern int ds1286_init(void); @@ -270,9 +267,6 @@ #ifdef CONFIG_SGI_NEWPORT_GFX gfx_register (); #endif -#ifdef CONFIG_SGI_IP22 - streamable_init (); -#endif #ifdef CONFIG_SGI_NEWPORT_GFX gfx_register (); #endif diff -urN linux-2.4.21/drivers/char/n_tty.c linux-2.4.22/drivers/char/n_tty.c --- linux-2.4.21/drivers/char/n_tty.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/n_tty.c 2003-08-25 04:44:41.000000000 -0700 @@ -1238,7 +1238,8 @@ else tty->minimum_to_wake = 1; } - if (tty->driver.chars_in_buffer(tty) < WAKEUP_CHARS) + if (tty->driver.chars_in_buffer(tty) < WAKEUP_CHARS && + tty->driver.write_room(tty) > 0) mask |= POLLOUT | POLLWRNORM; return mask; } diff -urN linux-2.4.21/drivers/char/qtronixmap.c linux-2.4.22/drivers/char/qtronixmap.c --- linux-2.4.21/drivers/char/qtronixmap.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/qtronixmap.c 2003-08-25 04:44:41.000000000 -0700 @@ -226,40 +226,40 @@ }; struct kbdiacr accent_table[MAX_DIACR] = { - {'`', 'A', 'À'}, {'`', 'a', 'à'}, - {'\'', 'A', 'Á'}, {'\'', 'a', 'á'}, - {'^', 'A', 'Â'}, {'^', 'a', 'â'}, - {'~', 'A', 'Ã'}, {'~', 'a', 'ã'}, - {'"', 'A', 'Ä'}, {'"', 'a', 'ä'}, - {'O', 'A', 'Å'}, {'o', 'a', 'å'}, - {'0', 'A', 'Å'}, {'0', 'a', 'å'}, - {'A', 'A', 'Å'}, {'a', 'a', 'å'}, - {'A', 'E', 'Æ'}, {'a', 'e', 'æ'}, - {',', 'C', 'Ç'}, {',', 'c', 'ç'}, - {'`', 'E', 'È'}, {'`', 'e', 'è'}, - {'\'', 'E', 'É'}, {'\'', 'e', 'é'}, - {'^', 'E', 'Ê'}, {'^', 'e', 'ê'}, - {'"', 'E', 'Ë'}, {'"', 'e', 'ë'}, - {'`', 'I', 'Ì'}, {'`', 'i', 'ì'}, - {'\'', 'I', 'Í'}, {'\'', 'i', 'í'}, - {'^', 'I', 'Î'}, {'^', 'i', 'î'}, - {'"', 'I', 'Ï'}, {'"', 'i', 'ï'}, - {'-', 'D', 'Ð'}, {'-', 'd', 'ð'}, - {'~', 'N', 'Ñ'}, {'~', 'n', 'ñ'}, - {'`', 'O', 'Ò'}, {'`', 'o', 'ò'}, - {'\'', 'O', 'Ó'}, {'\'', 'o', 'ó'}, - {'^', 'O', 'Ô'}, {'^', 'o', 'ô'}, - {'~', 'O', 'Õ'}, {'~', 'o', 'õ'}, - {'"', 'O', 'Ö'}, {'"', 'o', 'ö'}, - {'/', 'O', 'Ø'}, {'/', 'o', 'ø'}, - {'`', 'U', 'Ù'}, {'`', 'u', 'ù'}, - {'\'', 'U', 'Ú'}, {'\'', 'u', 'ú'}, - {'^', 'U', 'Û'}, {'^', 'u', 'û'}, - {'"', 'U', 'Ü'}, {'"', 'u', 'ü'}, - {'\'', 'Y', 'Ý'}, {'\'', 'y', 'ý'}, - {'T', 'H', 'Þ'}, {'t', 'h', 'þ'}, - {'s', 's', 'ß'}, {'"', 'y', 'ÿ'}, - {'s', 'z', 'ß'}, {'i', 'j', 'ÿ'}, + {'`', 'A', '\300'}, {'`', 'a', '\340'}, + {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, + {'^', 'A', '\302'}, {'^', 'a', '\342'}, + {'~', 'A', '\303'}, {'~', 'a', '\343'}, + {'"', 'A', '\304'}, {'"', 'a', '\344'}, + {'O', 'A', '\305'}, {'o', 'a', '\345'}, + {'0', 'A', '\305'}, {'0', 'a', '\345'}, + {'A', 'A', '\305'}, {'a', 'a', '\345'}, + {'A', 'E', '\306'}, {'a', 'e', '\346'}, + {',', 'C', '\307'}, {',', 'c', '\347'}, + {'`', 'E', '\310'}, {'`', 'e', '\350'}, + {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, + {'^', 'E', '\312'}, {'^', 'e', '\352'}, + {'"', 'E', '\313'}, {'"', 'e', '\353'}, + {'`', 'I', '\314'}, {'`', 'i', '\354'}, + {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, + {'^', 'I', '\316'}, {'^', 'i', '\356'}, + {'"', 'I', '\317'}, {'"', 'i', '\357'}, + {'-', 'D', '\320'}, {'-', 'd', '\360'}, + {'~', 'N', '\321'}, {'~', 'n', '\361'}, + {'`', 'O', '\322'}, {'`', 'o', '\362'}, + {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, + {'^', 'O', '\324'}, {'^', 'o', '\364'}, + {'~', 'O', '\325'}, {'~', 'o', '\365'}, + {'"', 'O', '\326'}, {'"', 'o', '\366'}, + {'/', 'O', '\330'}, {'/', 'o', '\370'}, + {'`', 'U', '\331'}, {'`', 'u', '\371'}, + {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, + {'^', 'U', '\333'}, {'^', 'u', '\373'}, + {'"', 'U', '\334'}, {'"', 'u', '\374'}, + {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, + {'T', 'H', '\336'}, {'t', 'h', '\376'}, + {'s', 's', '\337'}, {'"', 'y', '\377'}, + {'s', 'z', '\337'}, {'i', 'j', '\377'}, }; unsigned int accent_table_size = 68; diff -urN linux-2.4.21/drivers/char/random.c linux-2.4.22/drivers/char/random.c --- linux-2.4.21/drivers/char/random.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/random.c 2003-08-25 04:44:41.000000000 -0700 @@ -175,7 +175,7 @@ * chmod 600 $random_seed * poolfile=/proc/sys/kernel/random/poolsize * [ -r $poolfile ] && bytes=`cat $poolfile` || bytes=512 - * dd if=/dev/urandom of=$random_seed count=1 bs=bytes + * dd if=/dev/urandom of=$random_seed count=1 bs=$bytes * * and the following lines in an appropriate script which is run as * the system is shutdown: @@ -188,7 +188,7 @@ * chmod 600 $random_seed * poolfile=/proc/sys/kernel/random/poolsize * [ -r $poolfile ] && bytes=`cat $poolfile` || bytes=512 - * dd if=/dev/urandom of=$random_seed count=1 bs=bytes + * dd if=/dev/urandom of=$random_seed count=1 bs=$bytes * * For example, on most modern systems using the System V init * scripts, such code fragments would be found in @@ -251,6 +251,8 @@ #include #include #include +#include +#include #include #include @@ -2069,7 +2071,7 @@ static struct keydata *__check_and_rekey(time_t time) { struct keydata *keyptr; - spin_lock(&ip_lock); + spin_lock_bh(&ip_lock); keyptr = &ip_keydata[ip_cnt&1]; if (!keyptr->rekey_time || (time - keyptr->rekey_time) > REKEY_INTERVAL) { keyptr = &ip_keydata[1^(ip_cnt&1)]; @@ -2079,7 +2081,7 @@ mb(); ip_cnt++; } - spin_unlock(&ip_lock); + spin_unlock_bh(&ip_lock); return keyptr; } diff -urN linux-2.4.21/drivers/char/rocket_int.h linux-2.4.22/drivers/char/rocket_int.h --- linux-2.4.21/drivers/char/rocket_int.h 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/rocket_int.h 2003-08-25 04:44:41.000000000 -0700 @@ -7,6 +7,8 @@ * * Copyright 1994 Comtrol Corporation. All Rights Reserved. * + * Erroneously clashing license removed. This file is GPL + * (Kurt Robideau, Comtrol Corp, 20030610) * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -16,7 +18,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * */ /* diff -urN linux-2.4.21/drivers/char/sb1250_duart.c linux-2.4.22/drivers/char/sb1250_duart.c --- linux-2.4.21/drivers/char/sb1250_duart.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/sb1250_duart.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,18 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* * Driver support for the on-chip sb1250 dual-channel serial port, * running in asynchronous mode. Also, support for doing a serial console * on one of those ports - * - * The non-console part of this code is based heavily on the serial_21285.c - * driver also in this directory. See tty_driver.h for a description of some - * of the driver functions, though it (like most of the inline code documentation :) - * is a bit out of date. */ - +#include #include #include #include @@ -43,113 +37,183 @@ #include #include #include +#include +#include #include #include #include -#include #include #include #include +#include #include +#include /* Toggle spewing of debugging output */ #undef DUART_SPEW #define DEFAULT_CFLAGS (CS8 | B115200) +#define TX_INTEN 1 +#define DUART_INITIALIZED 2 -/* - Still not sure what the termios structures set up here are for, - but we have to supply pointers to them to register the tty driver -*/ +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define DUART_MAX_LINE 2 +char sb1250_duart_present[DUART_MAX_LINE] = {1,1}; +/* + * Still not sure what the termios structures set up here are for, + * but we have to supply pointers to them to register the tty driver + */ static struct tty_driver sb1250_duart_driver, sb1250_duart_callout_driver; -static int ref_count; -static struct tty_struct *duart_table[2]; -static struct termios *duart_termios[2]; -static struct termios *duart_termios_locked[2]; +static int duart_refcount; +static struct tty_struct *duart_table[DUART_MAX_LINE]; +static struct termios *duart_termios[DUART_MAX_LINE]; +static struct termios *duart_termios_locked[DUART_MAX_LINE]; -/* This lock protects both the open flags for all the uart states as - well as the reference count for the module */ +/* + * This lock protects both the open flags for all the uart states as + * well as the reference count for the module + */ static spinlock_t open_lock = SPIN_LOCK_UNLOCKED; -/* Protect the writing stuff from contention */ -//static spinlock_t console_lock = SPIN_LOCK_UNLOCKED; - -/* Bit fields of flags in the flags field below */ - -#define SD_WRITE_WAKE 0x000000001 - - typedef struct { - struct tty_struct *tty; - unsigned char outp_buf[CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE]; + unsigned char outp_buf[SERIAL_XMIT_SIZE]; unsigned int outp_head; unsigned int outp_tail; unsigned int outp_count; spinlock_t outp_lock; - unsigned int outp_stopped; unsigned int open; - unsigned long flags; + unsigned int line; unsigned int last_cflags; + unsigned long flags; + struct tty_struct *tty; + /* CSR addresses */ + u32 *status; + u32 *imr; + u32 *tx_hold; + u32 *rx_hold; + u32 *mode_1; + u32 *mode_2; + u32 *clk_sel; + u32 *cmd; } uart_state_t; -static uart_state_t uart_states[2] = { [0 ... 1] = { - tty: 0, - outp_head: 0, - outp_tail: 0, - outp_lock: SPIN_LOCK_UNLOCKED, - outp_count: 0, - open: 0, - flags: 0, - last_cflags: 0, -}}; +static uart_state_t uart_states[DUART_MAX_LINE]; /* * Inline functions local to this module */ - /* - * Mask out the passed interrupt lines at the duart level. This should be - * called while holding the associated outp_lock. + * In bug 1956, we get glitches that can mess up uart registers. This + * "write-mode-1 after any register access" is the accepted + * workaround. */ -static inline void duart_mask_ints(unsigned int line, unsigned int mask) +#if SIBYTE_1956_WAR +static unsigned int last_mode1[DUART_MAX_LINE]; +#endif + +static inline u32 READ_SERCSR(u32 *addr, int line) { - u64 tmp; - tmp = in64(IO_SPACE_BASE | A_DUART_IMRREG(line)); - tmp &= ~mask; - out64(tmp, IO_SPACE_BASE | A_DUART_IMRREG(line)); + u32 val = csr_in32(addr); +#if SIBYTE_1956_WAR + csr_out32(last_mode1[line], uart_states[line].mode_1); +#endif + return val; } - -/* Unmask the passed interrupt lines at the duart level */ -static inline void duart_unmask_ints(unsigned int line, unsigned int mask) +static inline void WRITE_SERCSR(u32 val, u32 *addr, int line) { - u64 tmp; - tmp = in64(IO_SPACE_BASE | A_DUART_IMRREG(line)); - tmp |= mask; - out64(tmp, IO_SPACE_BASE | A_DUART_IMRREG(line)); + csr_out32(val, addr); +#if SIBYTE_1956_WAR + csr_out32(last_mode1[line], uart_states[line].mode_1); +#endif } -static inline unsigned long get_status_reg(unsigned int line) +static void init_duart_port(uart_state_t *port, int line) { - return in64(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_STATUS)); + if (!(port->flags & DUART_INITIALIZED)) { + port->line = line; + port->status = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_STATUS)); + port->imr = (u32 *)(IO_SPACE_BASE | A_DUART_IMRREG(line)); + port->tx_hold = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_TX_HOLD)); + port->rx_hold = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_RX_HOLD)); + port->mode_1 = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_1)); + port->mode_2 = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_2)); + port->clk_sel = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_CLK_SEL)); + port->cmd = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_CMD)); + port->flags |= DUART_INITIALIZED; + } } -/* Derive which uart a call is for from the passed tty line. */ -static inline unsigned int get_line(struct tty_struct *tty) +/* + * Mask out the passed interrupt lines at the duart level. This should be + * called while holding the associated outp_lock. + */ +static inline void duart_mask_ints(unsigned int line, unsigned int mask) { - unsigned int line = MINOR(tty->device) - 64; - if (line > 1) - printk(KERN_CRIT "Invalid line\n"); - - return line; + uart_state_t *port = uart_states + line; + u64 tmp = READ_SERCSR(port->imr, line); + WRITE_SERCSR(tmp & ~mask, port->imr, line); } + +/* Unmask the passed interrupt lines at the duart level */ +static inline void duart_unmask_ints(unsigned int line, unsigned int mask) +{ + uart_state_t *port = uart_states + line; + u64 tmp = READ_SERCSR(port->imr, line); + WRITE_SERCSR(tmp | mask, port->imr, line); +} + +static inline void transmit_char_pio(uart_state_t *us) +{ + struct tty_struct *tty = us->tty; + int blocked = 0; + + if (spin_trylock(&us->outp_lock)) { + for (;;) { + if (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_RDY)) + break; + if (us->outp_count <= 0 || tty->stopped || tty->hw_stopped) { + break; + } else { + WRITE_SERCSR(us->outp_buf[us->outp_head], + us->tx_hold, us->line); + us->outp_head = (us->outp_head + 1) & (SERIAL_XMIT_SIZE-1); + if (--us->outp_count <= 0) + break; + } + udelay(10); + } + spin_unlock(&us->outp_lock); + } else { + blocked = 1; + } - -#define MIN(a, b) (((a)<(b))?(a):(b)) + if (!us->outp_count || tty->stopped || + tty->hw_stopped || blocked) { + us->flags &= ~TX_INTEN; + duart_mask_ints(us->line, M_DUART_IMR_TX); + } + + if (us->open && + (us->outp_count < (SERIAL_XMIT_SIZE/2))) { + /* + * We told the discipline at one point that we had no + * space, so it went to sleep. Wake it up when we hit + * half empty + */ + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + tty->ldisc.write_wakeup(tty); + wake_up_interruptible(&tty->write_wait); + } +} /* * Generic interrupt handler for both channels. dev_id is a pointer @@ -159,52 +223,44 @@ static void duart_int(int irq, void *dev_id, struct pt_regs *regs) { - unsigned int line; uart_state_t *us = (uart_state_t *)dev_id; - line = us-uart_states; + struct tty_struct *tty = us->tty; + unsigned int status = READ_SERCSR(us->status, us->line); + #ifdef DUART_SPEW -// setleds("INT!"); - printk("DUART INT\n"); + printk("DUART INT\n"); #endif - /* We could query the ISR to figure out why we are here, but since - we are here, we may as well just take care of both rx and tx */ - spin_lock(&us->outp_lock); - if (get_status_reg(line) & M_DUART_RX_RDY) { - do { - unsigned int status = get_status_reg(line); - unsigned int ch = in64(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_RX_HOLD)); - unsigned int flag = 0; - if (status & 0x10) { - tty_insert_flip_char(us->tty, 0, TTY_OVERRUN); } - if (status & 0x20) { - printk("Parity error!\n"); - flag = TTY_PARITY; - } else if (status & 0x40) { - printk("Frame error!\n"); - flag = TTY_FRAME; - } - tty_insert_flip_char(us->tty, ch, flag); - } while (get_status_reg(line) & M_DUART_RX_RDY); - tty_flip_buffer_push(us->tty); - } - if ((get_status_reg(line) & M_DUART_TX_RDY) && us->outp_count) { - do { - out64(us->outp_buf[us->outp_head], IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_TX_HOLD)); - us->outp_head = (us->outp_head + 1) & (CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1); - us->outp_count--; - } while ((get_status_reg(line) & M_DUART_TX_RDY) && us->outp_count); - - if (us->open && (us->flags & SD_WRITE_WAKE) && - (us->outp_count < (CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE/2))) { - /* We told the discipline at one point that we had no space, so it went - to sleep. Wake it up when we hit half empty */ - wake_up_interruptible(&us->tty->write_wait); + + if (status & M_DUART_RX_RDY) { + int counter = 2048; + unsigned int ch; + + if (status & M_DUART_OVRUN_ERR) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + if (status & M_DUART_PARITY_ERR) { + printk("Parity error!\n"); + } else if (status & M_DUART_FRM_ERR) { + printk("Frame error!\n"); } - if (!us->outp_count) { - duart_mask_ints(line, M_DUART_IMR_TX); + + while (counter > 0) { + if (!(READ_SERCSR(us->status, us->line) & M_DUART_RX_RDY)) + break; + ch = READ_SERCSR(us->rx_hold, us->line); + if (tty->flip.count < TTY_FLIPBUF_SIZE) { + *tty->flip.char_buf_ptr++ = ch; + *tty->flip.flag_buf_ptr++ = 0; + tty->flip.count++; + } + udelay(1); + counter--; } + tty_flip_buffer_push(tty); + } + + if (status & M_DUART_TX_RDY) { + transmit_char_pio(us); } - spin_unlock(&us->outp_lock); } /* @@ -214,19 +270,15 @@ /* Return the number of characters we can accomodate in a write at this instant */ static int duart_write_room(struct tty_struct *tty) { - unsigned long flags; + uart_state_t *us = (uart_state_t *) tty->driver_data; int retval; - uart_state_t *us = &uart_states[get_line(tty)]; - spin_lock_irqsave(&us->outp_lock, flags); - retval = CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE - uart_states[get_line(tty)].outp_count; - if (!retval) { - us->flags |= SD_WRITE_WAKE; - } - spin_unlock_irqrestore(&us->outp_lock, flags); + retval = SERIAL_XMIT_SIZE - us->outp_count; + #ifdef DUART_SPEW printk("duart_write_room called, returning %i\n", retval); #endif + return retval; } @@ -242,88 +294,119 @@ return size; } -/* Buffer up to count characters from buf to be written. If we don't have other - characters buffered, enable the tx interrupt to start sending */ +/* + * Buffer up to count characters from buf to be written. If we don't have + * other characters buffered, enable the tx interrupt to start sending + */ static int duart_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) + const unsigned char *buf, int count) { uart_state_t *us; + int c, t, total = 0; unsigned long flags; - unsigned int line; - int chars_written = 0; - if (from_user && verify_area(VERIFY_READ, buf, count)) { - return -EINVAL; - } + + if (!tty) return 0; + + us = tty->driver_data; + if (!us) return 0; + #ifdef DUART_SPEW printk("duart_write called for %i chars by %i (%s)\n", count, current->pid, current->comm); #endif - line = get_line(tty); - us = &uart_states[line]; + spin_lock_irqsave(&us->outp_lock, flags); - if (!count || (us->outp_count == CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE)) { - spin_unlock_irqrestore(&us->outp_lock, flags); - return 0; - } - if (us->outp_tail < us->outp_head) { - /* Straightforward case; copy from tail to head */ - chars_written += copy_buf(us->outp_buf + us->outp_tail, buf, - MIN(count, us->outp_head - us->outp_tail), from_user); - } else { - /* Copy from tail to end of buffer, wrap around and then - copy to head */ - chars_written += copy_buf(us->outp_buf + us->outp_tail, buf, - MIN(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE - us->outp_tail, count), - from_user); - if (chars_written < count) { - chars_written += copy_buf(us->outp_buf, buf + chars_written, - MIN(us->outp_head, count - chars_written), from_user); + + for (;;) { + c = count; + + t = SERIAL_XMIT_SIZE - us->outp_tail; + if (t < c) c = t; + + t = SERIAL_XMIT_SIZE - 1 - us->outp_count; + if (t < c) c = t; + + if (c <= 0) break; + + if (from_user) { + if (copy_from_user(us->outp_buf + us->outp_tail, buf, c)) { + spin_unlock_irqrestore(&us->outp_lock, flags); + return -EFAULT; + } + } else { + memcpy(us->outp_buf + us->outp_tail, buf, c); } + + us->outp_count += c; + us->outp_tail = (us->outp_tail + c) & (SERIAL_XMIT_SIZE - 1); + buf += c; + count -= c; + total += c; } - us->outp_tail = (us->outp_tail + chars_written) &(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1); - if (!(us->outp_count || us->outp_stopped)) { - duart_unmask_ints(line, M_DUART_IMR_TX); - } - us->outp_count += chars_written; + spin_unlock_irqrestore(&us->outp_lock, flags); - return chars_written; -} + + if (us->outp_count && !tty->stopped && + !tty->hw_stopped && !(us->flags & TX_INTEN)) { + us->flags |= TX_INTEN; + duart_unmask_ints(us->line, M_DUART_IMR_TX); + } + + return total; +} /* Buffer one character to be written. If there's not room for it, just drop it on the floor. This is used for echo, among other things */ static void duart_put_char(struct tty_struct *tty, u_char ch) { + uart_state_t *us = (uart_state_t *) tty->driver_data; unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; + #ifdef DUART_SPEW printk("duart_put_char called. Char is %x (%c)\n", (int)ch, ch); #endif + spin_lock_irqsave(&us->outp_lock, flags); - if (us->outp_count != CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE) { - us->outp_buf[us->outp_tail] = ch; - us->outp_tail = (us->outp_tail + 1) &(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1); - if (!(us->outp_count || us->outp_stopped)) { - duart_unmask_ints(line, M_DUART_IMR_TX); - } - us->outp_count++; + + if (us->outp_count >= SERIAL_XMIT_SIZE - 1) { + spin_unlock_irqrestore(&us->outp_lock, flags); + return; } + + us->outp_buf[us->outp_tail] = ch; + us->outp_tail = (us->outp_tail + 1) &(SERIAL_XMIT_SIZE-1); + us->outp_count++; + spin_unlock_irqrestore(&us->outp_lock, flags); } +static void duart_flush_chars(struct tty_struct * tty) +{ + uart_state_t *port; + + if (!tty) return; + + port = tty->driver_data; + + if (!port) return; + + if (port->outp_count <= 0 || tty->stopped || tty->hw_stopped) { + return; + } + + port->flags |= TX_INTEN; + duart_unmask_ints(port->line, M_DUART_IMR_TX); +} + /* Return the number of characters in the output buffer that have yet to be written */ static int duart_chars_in_buffer(struct tty_struct *tty) { + uart_state_t *us = (uart_state_t *) tty->driver_data; int retval; - unsigned long flags; - uart_state_t *us = &uart_states[get_line(tty)]; - spin_lock_irqsave(&us->outp_lock, flags); + retval = us->outp_count; - if (retval) { - us->flags |= SD_WRITE_WAKE; - } - spin_unlock_irqrestore(&us->outp_lock, flags); + #ifdef DUART_SPEW printk("duart_chars_in_buffer returning %i\n", retval); #endif @@ -334,19 +417,20 @@ transmit interrupt since we've nothing more to transmit */ static void duart_flush_buffer(struct tty_struct *tty) { + uart_state_t *us = (uart_state_t *) tty->driver_data; unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[get_line(tty)]; + #ifdef DUART_SPEW printk("duart_flush_buffer called\n"); #endif - duart_mask_ints(line, M_DUART_IMR_TX); spin_lock_irqsave(&us->outp_lock, flags); us->outp_head = us->outp_tail = us->outp_count = 0; - if (us->flags & SD_WRITE_WAKE) { - wake_up_interruptible(&us->tty->write_wait); - } spin_unlock_irqrestore(&us->outp_lock, flags); + + wake_up_interruptible(&us->tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + tty->ldisc.write_wakeup(tty); } @@ -355,6 +439,8 @@ { unsigned int mode_reg1 = 0, mode_reg2 = 0; unsigned int clk_divisor; + uart_state_t *port = uart_states + line; + switch (cflag & CSIZE) { case CS7: mode_reg1 |= V_DUART_BITS_PER_CHAR_7; @@ -366,10 +452,10 @@ break; } if (cflag & CSTOPB) { - mode_reg2 |= M_DUART_STOP_BIT_LEN_2; /* XXX was: 0x4; */ + mode_reg2 |= M_DUART_STOP_BIT_LEN_2; } if (!(cflag & PARENB)) { - mode_reg1 |= V_DUART_PARITY_MODE_NONE; /* XXX was: 0x8; */ + mode_reg1 |= V_DUART_PARITY_MODE_NONE; } if (cflag & PARODD) { mode_reg1 |= M_DUART_PARITY_TYPE_ODD; @@ -392,38 +478,24 @@ case B57600: clk_divisor = 85; break; case B115200: clk_divisor = 42; break; } - out64(mode_reg1, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_1)); - out64(mode_reg2, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_2)); - out64(clk_divisor, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_CLK_SEL)); - uart_states[line].last_cflags = cflag; + WRITE_SERCSR(mode_reg1, port->mode_1, port->line); + WRITE_SERCSR(mode_reg2, port->mode_2, port->line); + WRITE_SERCSR(clk_divisor, port->clk_sel, port->line); + port->last_cflags = cflag; } /* Handle notification of a termios change. */ static void duart_set_termios(struct tty_struct *tty, struct termios *old) { + uart_state_t *us = (uart_state_t *) tty->driver_data; + #ifdef DUART_SPEW printk("duart_set_termios called by %i (%s)\n", current->pid, current->comm); #endif if (old && tty->termios->c_cflag == old->c_cflag) return; - duart_set_cflag(get_line(tty), tty->termios->c_cflag); -} - -/* Stop pushing stuff into the fifo, now. Do the mask under the - outp_lock to avoid races involving turning the interrupt line on/off */ -static void duart_stop(struct tty_struct *tty) -{ - unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; -#ifdef DUART_SPEW - printk("duart_stop called\n"); -#endif - spin_lock_irqsave(&us->outp_lock, flags); - duart_mask_ints(get_line(tty), M_DUART_IMR_TX); - us->outp_stopped = 1; - spin_unlock_irqrestore(&us->outp_lock, flags); + duart_set_cflag(us->line, tty->termios->c_cflag); } static int duart_ioctl(struct tty_struct *tty, struct file * file, @@ -508,22 +580,34 @@ return 0; } -/* Stop pushing stuff into the fifo, now. Do the mask under the - outp_lock to avoid races involving turning the interrupt line on/off */ +/* XXXKW locking? */ static void duart_start(struct tty_struct *tty) { - unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; + uart_state_t *us = (uart_state_t *) tty->driver_data; + #ifdef DUART_SPEW printk("duart_start called\n"); #endif - spin_lock_irqsave(&us->outp_lock, flags); - if (us->outp_count) { - duart_unmask_ints(get_line(tty), M_DUART_IMR_TX); + + if (us->outp_count && !(us->flags & TX_INTEN)) { + us->flags |= TX_INTEN; + duart_unmask_ints(us->line, M_DUART_IMR_TX); + } +} + +/* XXXKW locking? */ +static void duart_stop(struct tty_struct *tty) +{ + uart_state_t *us = (uart_state_t *) tty->driver_data; + +#ifdef DUART_SPEW + printk("duart_stop called\n"); +#endif + + if (us->outp_count && (us->flags & TX_INTEN)) { + us->flags &= ~TX_INTEN; + duart_mask_ints(us->line, M_DUART_IMR_TX); } - us->outp_stopped = 0; - spin_unlock_irqrestore(&us->outp_lock, flags); } /* Not sure on the semantics of this; are we supposed to wait until the stuff @@ -534,17 +618,20 @@ static void duart_wait_until_sent(struct tty_struct *tty, int timeout) { - unsigned long target_time; - unsigned int line; - uart_state_t *us; + uart_state_t *us = (uart_state_t *) tty->driver_data; + unsigned long orig_jiffies; + + orig_jiffies = jiffies; #ifdef DUART_SPEW printk("duart_wait_until_sent(%d)+\n", timeout); #endif - target_time = jiffies + timeout; - line = get_line(tty); - us = &uart_states[line]; - while (!(get_status_reg(line) & M_DUART_TX_EMT) && (jiffies < target_time)) { + while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) { + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; } #ifdef DUART_SPEW printk("duart_wait_until_sent()-\n"); @@ -552,53 +639,54 @@ } /* + * duart_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void duart_hangup(struct tty_struct *tty) +{ + uart_state_t *us = (uart_state_t *) tty->driver_data; + + duart_flush_buffer(tty); + us->open = 0; + us->tty = 0; +} + +/* * Open a tty line. Note that this can be called multiple times, so ->open can * be >1. Only set up the tty struct if this is a "new" open, e.g. ->open was * zero */ static int duart_open(struct tty_struct *tty, struct file *filp) { - unsigned long flags; - unsigned int line; uart_state_t *us; + unsigned int line = MINOR(tty->device) - tty->driver.minor_start; + unsigned long flags; MOD_INC_USE_COUNT; -#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - if (get_line(tty) > 1) -#else - if (get_line(tty) > 0) -#endif - { + + if ((line < 0) || (line >= DUART_MAX_LINE) || !sb1250_duart_present[line]) { MOD_DEC_USE_COUNT; return -ENODEV; } + #ifdef DUART_SPEW - printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n", current->pid, current->comm, tty, - tty->read_wait, tty->write_wait); + printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n", + current->pid, current->comm, tty, tty->read_wait, + tty->write_wait); #endif - line = get_line(tty); - tty->driver_data = NULL; - us = &uart_states[line]; - + + us = uart_states + line; + tty->driver_data = us; + spin_lock_irqsave(&open_lock, flags); if (!us->open) { us->tty = tty; us->tty->termios->c_cflag = us->last_cflags; } us->open++; -#ifdef FORCED_INPUT - if (!line && (us->open == 1)) { - next_inp = inp_cmds; - init_timer(&inp_timer); - inp_timer.expires = jiffies + 20; - inp_timer.data = 0; - inp_timer.function = stuff_char; - stuff_char_tty = tty; - add_timer(&inp_timer); - } -#endif + us->flags &= ~TX_INTEN; duart_unmask_ints(line, M_DUART_IMR_RX); spin_unlock_irqrestore(&open_lock, flags); + return 0; } @@ -610,26 +698,48 @@ */ static void duart_close(struct tty_struct *tty, struct file *filp) { + uart_state_t *us = (uart_state_t *) tty->driver_data; unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; + #ifdef DUART_SPEW printk("duart_close called by %i (%s)\n", current->pid, current->comm); #endif + + if (!us || !us->open) + return; + spin_lock_irqsave(&open_lock, flags); - us->open--; -#if 0 - if (!us->open) { - /* Flushing TX stuff here is conservative */ - duart_mask_ints(line, M_DUART_IMR_IN | M_DUART_IMR_BRK | M_DUART_IMR_RX | M_DUART_IMR_TX); - spin_lock(&us->outp_lock); - us->outp_head = us->outp_tail = us->outp_count = us->outp_stopped = 0; - us->tty = NULL; - spin_unlock(&us->outp_lock); + if (tty_hung_up_p(filp)) { + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&open_lock, flags); + return; } -#endif - ref_count--; + + if (--us->open < 0) { + us->open = 0; + printk(KERN_ERR "duart: bad open count: %d\n", us->open); + } + if (us->open) { + spin_unlock_irqrestore(&open_lock, flags); + return; + } + spin_unlock_irqrestore(&open_lock, flags); + + tty->closing = 1; + + /* Stop accepting input */ + duart_mask_ints(us->line, M_DUART_IMR_RX); + /* Wait for FIFO to drain */ + while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) + ; + + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + MOD_DEC_USE_COUNT; } @@ -638,6 +748,8 @@ is called from tty_init, or as a part of the module init */ static int __init sb1250_duart_init(void) { + int i; + sb1250_duart_driver.magic = TTY_DRIVER_MAGIC; sb1250_duart_driver.driver_name = "serial"; #ifdef CONFIG_DEVFS_FS @@ -646,13 +758,13 @@ sb1250_duart_driver.name = "ttyS"; #endif sb1250_duart_driver.major = TTY_MAJOR; - sb1250_duart_driver.minor_start = 64; - sb1250_duart_driver.num = 2; + sb1250_duart_driver.minor_start = SB1250_DUART_MINOR_BASE; + sb1250_duart_driver.num = DUART_MAX_LINE; sb1250_duart_driver.type = TTY_DRIVER_TYPE_SERIAL; sb1250_duart_driver.subtype = SERIAL_TYPE_NORMAL; sb1250_duart_driver.init_termios = tty_std_termios; sb1250_duart_driver.flags = TTY_DRIVER_REAL_RAW; - sb1250_duart_driver.refcount = &ref_count; + sb1250_duart_driver.refcount = &duart_refcount; sb1250_duart_driver.table = duart_table; sb1250_duart_driver.termios = duart_termios; sb1250_duart_driver.termios_locked = duart_termios_locked; @@ -662,12 +774,14 @@ sb1250_duart_driver.write = duart_write; sb1250_duart_driver.put_char = duart_put_char; sb1250_duart_driver.write_room = duart_write_room; + sb1250_duart_driver.flush_chars = duart_flush_chars; sb1250_duart_driver.chars_in_buffer = duart_chars_in_buffer; sb1250_duart_driver.flush_buffer = duart_flush_buffer; sb1250_duart_driver.ioctl = duart_ioctl; sb1250_duart_driver.set_termios = duart_set_termios; sb1250_duart_driver.stop = duart_stop; sb1250_duart_driver.start = duart_start; + sb1250_duart_driver.hangup = duart_hangup; sb1250_duart_driver.wait_until_sent = duart_wait_until_sent; sb1250_duart_callout_driver = sb1250_duart_driver; @@ -679,16 +793,22 @@ sb1250_duart_callout_driver.major = TTYAUX_MAJOR; sb1250_duart_callout_driver.subtype = SERIAL_TYPE_CALLOUT; - duart_mask_ints(0, 0xf); - if (request_irq(K_INT_UART_0, duart_int, 0, "uart0", &uart_states[0])) { - panic("Couldn't get uart0 interrupt line"); - } -#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - duart_mask_ints(1, 0xf); - if (request_irq(K_INT_UART_1, duart_int, 0, "uart1", &uart_states[1])) { - panic("Couldn't get uart1 interrupt line"); + for (i=0; ioutp_lock); + duart_mask_ints(i, M_DUART_IMR_ALL); + if (request_irq(K_INT_UART_0+i, duart_int, 0, "uart", port)) { + panic("Couldn't get uart0 interrupt line"); + } + out64(M_DUART_RX_EN|M_DUART_TX_EN, + IO_SPACE_BASE | A_DUART_CHANREG(i, R_DUART_CMD)); + duart_set_cflag(i, DEFAULT_CFLAGS); } -#endif /* Interrupts are now active, our ISR can be called. */ @@ -698,10 +818,6 @@ if (tty_register_driver(&sb1250_duart_callout_driver)) { printk(KERN_ERR "Couldn't register sb1250 duart callout driver\n"); } - duart_set_cflag(0, DEFAULT_CFLAGS); -#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - duart_set_cflag(1, DEFAULT_CFLAGS); -#endif return 0; } @@ -709,10 +825,10 @@ static void __exit sb1250_duart_fini(void) { unsigned long flags; + int i; int ret; - save_flags(flags); - cli(); + save_and_cli(flags); ret = tty_unregister_driver(&sb1250_duart_callout_driver); if (ret) { printk(KERN_ERR "Unable to unregister sb1250 duart callout driver (%d)\n", ret); @@ -721,69 +837,85 @@ if (ret) { printk(KERN_ERR "Unable to unregister sb1250 duart serial driver (%d)\n", ret); } - free_irq(K_INT_UART_0, &uart_states[0]); - free_irq(K_INT_UART_1, &uart_states[1]); - - /* mask lines in the scd */ - disable_irq(K_INT_UART_0); - disable_irq(K_INT_UART_1); - + for (i=0; i"); +MODULE_AUTHOR("Justin Carlson, Broadcom Corp."); -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE /* - * Serial console stuff. - * Very basic, polling driver for doing serial console output. - * FIXME; there is a race here; we can't be sure that - * the tx is still empty without holding outp_lock for this line. - * Worst that can happen for now, though, is dropped characters. + * Serial console stuff. Very basic, polling driver for doing serial + * console output. The console_sem is held by the caller, so we + * shouldn't be interrupted for more console activity. + * XXXKW What about getting interrupted by uart driver activity? */ -static void ser_console_write(struct console *cons, const char *str, - unsigned int count) +void serial_outc(unsigned char c, int line) { - unsigned int i; - unsigned long flags; - spin_lock_irqsave(&uart_states[0].outp_lock, flags); - - for (i = 0; i < count; i++) { - if (str[i] == '\n') { - /* Expand LF -> CRLF */ - while (!(get_status_reg(0) & M_DUART_TX_RDY)) { - /* Spin, doing nothing. */ - } - out64('\r', IO_SPACE_BASE | A_DUART_CHANREG(0, R_DUART_TX_HOLD)); - } - while (!(get_status_reg(0) & M_DUART_TX_RDY)) { - /* Spin, doing nothing. */ - } - out64(str[i], IO_SPACE_BASE | A_DUART_CHANREG(0, R_DUART_TX_HOLD)); - } - spin_unlock_irqrestore(&uart_states[0].outp_lock, flags); + uart_state_t *port = uart_states + line; + while (!(READ_SERCSR(port->status, line) & M_DUART_TX_RDY)) ; + WRITE_SERCSR(c, port->tx_hold, line); + while (!(READ_SERCSR(port->status, port->line) & M_DUART_TX_EMT)) ; +} + +static void ser_console_write(struct console *cons, const char *s, + unsigned int count) +{ + int line = cons->index; + uart_state_t *port = uart_states + line; + u32 imr; + + imr = READ_SERCSR(port->imr, line); + WRITE_SERCSR(0, port->imr, line); + while (count--) { + if (*s == '\n') + serial_outc('\r', line); + serial_outc(*s++, line); + } + WRITE_SERCSR(imr, port->imr, line); } static kdev_t ser_console_device(struct console *c) { - return MKDEV(TTY_MAJOR, 64 + c->index); + return MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + c->index); } static int ser_console_setup(struct console *cons, char *str) { - /* Initialize the transmitter */ - - duart_set_cflag(0, DEFAULT_CFLAGS); + int i; + + for (i=0; imode_1, i); + WRITE_SERCSR(M_DUART_STOP_BIT_LEN_1, + port->mode_2, i); + WRITE_SERCSR(V_DUART_BAUD_RATE(115200), + port->clk_sel, i); + } return 0; } static struct console sb1250_ser_cons = { - name: "ttyS", + name: "duart", write: ser_console_write, device: ser_console_device, setup: ser_console_setup, @@ -796,4 +928,4 @@ register_console(&sb1250_ser_cons); } -#endif /* CONFIG_SERIAL_CONSOLE */ +#endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */ diff -urN linux-2.4.21/drivers/char/serial.c linux-2.4.22/drivers/char/serial.c --- linux-2.4.21/drivers/char/serial.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/serial.c 2003-08-25 04:44:41.000000000 -0700 @@ -4353,9 +4353,10 @@ #ifdef CONFIG_DDB5074 pbn_nec_nile4, #endif -#if 0 + + pbn_dci_pccom4, pbn_dci_pccom8, -#endif + pbn_xircom_combo, pbn_siig10x_0, @@ -4449,9 +4450,10 @@ { SPCI_FL_BASE0, 1, 520833, /* pbn_nec_nile4 */ 64, 3, NULL, 0x300 }, #endif -#if 0 /* PCI_DEVICE_ID_DCI_PCCOM8 ? */ /* pbn_dci_pccom8 */ - { SPCI_FL_BASE3, 8, 115200, 8 }, -#endif + + {SPCI_FL_BASE3, 4, 115200, 8}, /* pbn_dci_pccom4 */ + {SPCI_FL_BASE3, 8, 115200, 8}, /* pbn_dci_pccom8 */ + { SPCI_FL_BASE0, 1, 115200, /* pbn_xircom_combo */ 0, 0, pci_xircom_fn }, @@ -4912,11 +4914,12 @@ pbn_nec_nile4 }, #endif -#if 0 /* PCI_DEVICE_ID_DCI_PCCOM8 ? */ + { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_dci_pccom4 }, { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_dci_pccom8 }, -#endif { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, }, diff -urN linux-2.4.21/drivers/char/serial_tx3912.c linux-2.4.22/drivers/char/serial_tx3912.c --- linux-2.4.21/drivers/char/serial_tx3912.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/serial_tx3912.c 2003-08-25 04:44:41.000000000 -0700 @@ -752,6 +752,21 @@ outl(int2, TX3912_INT2_ENABLE); } +static int serial_console_wait_key(struct console *co) +{ + unsigned int int2, res; + + int2 = inl(TX3912_INT2_ENABLE); + outl(0, TX3912_INT2_ENABLE); + + while (!(inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_RXHOLDFULL)); + res = inl(TX3912_UARTA_DATA); + udelay(10); + + outl(int2, TX3912_INT2_ENABLE); + return res; +} + static void serial_console_write(struct console *co, const char *s, unsigned count) { diff -urN linux-2.4.21/drivers/char/serial_txx9.c linux-2.4.22/drivers/char/serial_txx9.c --- linux-2.4.21/drivers/char/serial_txx9.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/serial_txx9.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,1768 @@ +/* + * drivers/char/serial_txx9.c + * + * Copyright (C) 1999 Harald Koerfgen + * Copyright (C) 2000 Jim Pick + * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) + * Copyright (C) 2000-2002 Toshiba Corporation + * + * 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. + * + * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MAGIC_SYSRQ +#include +#endif + +#define DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static char *serial_version = "0.30-mvl"; +static char *serial_name = "TX39/49 Serial driver"; + +#define GS_INTERNAL_FLAGS (GS_TX_INTEN|GS_RX_INTEN|GS_ACTIVE) + +#define TXX9_SERIAL_MAGIC 0x39274927 + +#ifdef CONFIG_SERIAL +/* "ttyS","cua" is used for standard serial driver */ +#define TXX9_TTY_NAME "ttyTX" +#define TXX9_TTY_DEVFS_NAME "tts/TX%d" +#define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */ +#define TXX9_CU_NAME "cuatx" +#define TXX9_CU_DEVFS_NAME "cua/TX%d" +#else +/* acts like standard serial driver */ +#define TXX9_TTY_NAME "ttyS" +#define TXX9_TTY_DEVFS_NAME "tts/%d" +#define TXX9_TTY_MINOR_START 64 +#define TXX9_CU_NAME "cua" +#define TXX9_CU_DEVFS_NAME "cua/%d" +#endif +#define TXX9_TTY_MAJOR TTY_MAJOR +#define TXX9_TTYAUX_MAJOR TTYAUX_MAJOR + +#define TXX9_SERIAL_HAVE_CTS_LINE 1 + +#ifdef CONFIG_PCI +/* support for Toshiba TC86C001 SIO */ +#define ENABLE_SERIAL_TXX9_PCI +#endif + +/* + * Number of serial ports + */ +#ifdef ENABLE_SERIAL_TXX9_PCI +#define NR_PCI_BOARDS 4 +#define NR_PORTS (2 + NR_PCI_BOARDS) +#else +#define NR_PORTS 2 +#endif + +/* + * Hardware specific serial port structure + */ +static struct rs_port { + struct gs_port gs; /* Must be first field! */ + + unsigned long base; + int irq; + int baud_base; + int flags; + struct async_icount icount; + int x_char; /* XON/XOFF character */ + int read_status_mask; + int ignore_status_mask; + int quot; + char io_type; +#ifdef ENABLE_SERIAL_TXX9_PCI + struct pci_dev * pci_dev; +#endif +} rs_ports[NR_PORTS] +#ifdef CONFIG_TOSHIBA_RBTX4925 += { + /* NR_PORTS = 0 */ + {base: 0xff1f0000 + 0xf300, + irq: 36, + baud_base: 40000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,}, + /* NR_PORTS = 1 */ + {base: 0xff1f0000 + 0xf400, + irq: 37, + baud_base: 40000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,} +}; +#endif +#ifdef CONFIG_TOSHIBA_RBTX4927 += { + /* NR_PORTS = 0 */ + {base: 0xff1f0000 + 0xf300, + irq: 32, + baud_base: 50000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,}, + /* NR_PORTS = 1 */ + {base: 0xff1f0000 + 0xf400, + irq: 33, + baud_base: 50000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,} +}; +#endif + +/* TXX9 Serial Registers */ +#define TXX9_SILCR 0x00 +#define TXX9_SIDICR 0x04 +#define TXX9_SIDISR 0x08 +#define TXX9_SICISR 0x0c +#define TXX9_SIFCR 0x10 +#define TXX9_SIFLCR 0x14 +#define TXX9_SIBGR 0x18 +#define TXX9_SITFIFO 0x1c +#define TXX9_SIRFIFO 0x20 + +/* SILCR : Line Control */ +#define TXX9_SILCR_SCS_MASK 0x00000060 +#define TXX9_SILCR_SCS_IMCLK 0x00000000 +#define TXX9_SILCR_SCS_IMCLK_BG 0x00000020 +#define TXX9_SILCR_SCS_SCLK 0x00000040 +#define TXX9_SILCR_SCS_SCLK_BG 0x00000060 +#define TXX9_SILCR_UEPS 0x00000010 +#define TXX9_SILCR_UPEN 0x00000008 +#define TXX9_SILCR_USBL_MASK 0x00000004 +//#define TXX9_SILCR_USBL_1BIT 0x00000004 +//#define TXX9_SILCR_USBL_2BIT 0x00000000 +#define TXX9_SILCR_USBL_1BIT 0x00000000 +#define TXX9_SILCR_USBL_2BIT 0x00000004 +#define TXX9_SILCR_UMODE_MASK 0x00000003 +#define TXX9_SILCR_UMODE_8BIT 0x00000000 +#define TXX9_SILCR_UMODE_7BIT 0x00000001 + +/* SIDICR : DMA/Int. Control */ +#define TXX9_SIDICR_TDE 0x00008000 +#define TXX9_SIDICR_RDE 0x00004000 +#define TXX9_SIDICR_TIE 0x00002000 +#define TXX9_SIDICR_RIE 0x00001000 +#define TXX9_SIDICR_SPIE 0x00000800 +#define TXX9_SIDICR_CTSAC 0x00000600 +#define TXX9_SIDICR_STIE_MASK 0x0000003f +#define TXX9_SIDICR_STIE_OERS 0x00000020 +#define TXX9_SIDICR_STIE_CTSS 0x00000010 +#define TXX9_SIDICR_STIE_RBRKD 0x00000008 +#define TXX9_SIDICR_STIE_TRDY 0x00000004 +#define TXX9_SIDICR_STIE_TXALS 0x00000002 +#define TXX9_SIDICR_STIE_UBRKD 0x00000001 + +/* SIDISR : DMA/Int. Status */ +#define TXX9_SIDISR_UBRK 0x00008000 +#define TXX9_SIDISR_UVALID 0x00004000 +#define TXX9_SIDISR_UFER 0x00002000 +#define TXX9_SIDISR_UPER 0x00001000 +#define TXX9_SIDISR_UOER 0x00000800 +#define TXX9_SIDISR_ERI 0x00000400 +#define TXX9_SIDISR_TOUT 0x00000200 +#define TXX9_SIDISR_TDIS 0x00000100 +#define TXX9_SIDISR_RDIS 0x00000080 +#define TXX9_SIDISR_STIS 0x00000040 +#define TXX9_SIDISR_RFDN_MASK 0x0000001f + +/* SICISR : Change Int. Status */ +#define TXX9_SICISR_OERS 0x00000020 +#define TXX9_SICISR_CTSS 0x00000010 +#define TXX9_SICISR_RBRKD 0x00000008 +#define TXX9_SICISR_TRDY 0x00000004 +#define TXX9_SICISR_TXALS 0x00000002 +#define TXX9_SICISR_UBRKD 0x00000001 + +/* SIFCR : FIFO Control */ +#define TXX9_SIFCR_SWRST 0x00008000 +#define TXX9_SIFCR_RDIL_MASK 0x00000180 +#define TXX9_SIFCR_RDIL_1 0x00000000 +#define TXX9_SIFCR_RDIL_4 0x00000080 +#define TXX9_SIFCR_RDIL_8 0x00000100 +#define TXX9_SIFCR_RDIL_12 0x00000180 +#define TXX9_SIFCR_RDIL_MAX 0x00000180 +#define TXX9_SIFCR_TDIL_MASK 0x00000018 +#define TXX9_SIFCR_TDIL_MASK 0x00000018 +#define TXX9_SIFCR_TDIL_1 0x00000000 +#define TXX9_SIFCR_TDIL_4 0x00000001 +#define TXX9_SIFCR_TDIL_8 0x00000010 +#define TXX9_SIFCR_TDIL_MAX 0x00000010 +#define TXX9_SIFCR_TFRST 0x00000004 +#define TXX9_SIFCR_RFRST 0x00000002 +#define TXX9_SIFCR_FRSTE 0x00000001 +#define TXX9_SIO_TX_FIFO 8 +#define TXX9_SIO_RX_FIFO 16 + +/* SIFLCR : Flow Control */ +#define TXX9_SIFLCR_RCS 0x00001000 +#define TXX9_SIFLCR_TES 0x00000800 +#define TXX9_SIFLCR_RTSSC 0x00000200 +#define TXX9_SIFLCR_RSDE 0x00000100 +#define TXX9_SIFLCR_TSDE 0x00000080 +#define TXX9_SIFLCR_RTSTL_MASK 0x0000001e +#define TXX9_SIFLCR_RTSTL_MAX 0x0000001e +#define TXX9_SIFLCR_TBRK 0x00000001 + +/* SIBGR : Baudrate Control */ +#define TXX9_SIBGR_BCLK_MASK 0x00000300 +#define TXX9_SIBGR_BCLK_T0 0x00000000 +#define TXX9_SIBGR_BCLK_T2 0x00000100 +#define TXX9_SIBGR_BCLK_T4 0x00000200 +#define TXX9_SIBGR_BCLK_T6 0x00000300 +#define TXX9_SIBGR_BRD_MASK 0x000000ff + +static /*inline*/ unsigned int +sio_in(struct rs_port *port, int offset) +{ + if (port->io_type < 0) + /* don't use __raw_readl that does swapping for big endian */ + return (*(volatile unsigned long*)(port->base + offset)); + else + return inl(port->base + offset); +} + +static /*inline*/ void +sio_out(struct rs_port *port, int offset, unsigned int value) +{ + if (port->io_type < 0) + /* don't use __raw_writel that does swapping for big endian */ + (*(volatile unsigned long*)(port->base + offset))=(value); + else + outl(value, port->base + offset); +} + +static inline void +sio_mask(struct rs_port *port, int offset, unsigned int value) +{ + sio_out(port, offset, sio_in(port, offset) & ~value); +} +static inline void +sio_set(struct rs_port *port, int offset, unsigned int value) +{ + sio_out(port, offset, sio_in(port, offset) | value); +} + +/* + * Forward declarations for serial routines + */ +static void rs_disable_tx_interrupts (void * ptr); +static void rs_enable_tx_interrupts (void * ptr); +static void rs_disable_rx_interrupts (void * ptr); +static void rs_enable_rx_interrupts (void * ptr); +static int rs_get_CD (void * ptr); +static void rs_shutdown_port (void * ptr); +static int rs_set_real_termios (void *ptr); +static int rs_chars_in_buffer (void * ptr); +static void rs_hungup (void *ptr); +static void rs_getserial (void*, struct serial_struct *sp); +static void rs_close (void *ptr); + +/* + * Used by generic serial driver to access hardware + */ +static struct real_driver rs_real_driver = { + disable_tx_interrupts: rs_disable_tx_interrupts, + enable_tx_interrupts: rs_enable_tx_interrupts, + disable_rx_interrupts: rs_disable_rx_interrupts, + enable_rx_interrupts: rs_enable_rx_interrupts, + get_CD: rs_get_CD, + shutdown_port: rs_shutdown_port, + set_real_termios: rs_set_real_termios, + chars_in_buffer: rs_chars_in_buffer, + close: rs_close, + hungup: rs_hungup, + getserial: rs_getserial, +}; + +/* + * Structures and such for TTY sessions and usage counts + */ +static struct tty_driver rs_driver, rs_callout_driver; +static struct tty_struct *rs_table[NR_PORTS]; +static struct termios *rs_termios[NR_PORTS]; +static struct termios *rs_termios_locked[NR_PORTS]; +int rs_refcount; +int rs_initialized = 0; + +#ifdef CONFIG_SERIAL_TXX9_CONSOLE +static struct console sercons; +#endif +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +static unsigned long break_pressed; /* break, really ... */ +#endif + +static inline void receive_chars(struct rs_port *port, + int *status, struct pt_regs *regs) +{ + struct tty_struct *tty = port->gs.tty; + unsigned char ch; + struct async_icount *icount; + int max_count = 256; + + icount = &port->icount; + do { + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty->flip.tqueue.routine((void *) tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + return; // if TTY_DONT_FLIP is set + } + ch = sio_in(port, TXX9_SIRFIFO); + *tty->flip.char_buf_ptr = ch; + icount->rx++; + + *tty->flip.flag_buf_ptr = 0; + if (*status & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER | + TXX9_SIDISR_UFER | TXX9_SIDISR_UOER)) { + /* + * For statistics only + */ + if (*status & TXX9_SIDISR_UBRK) { + *status &= ~(TXX9_SIDISR_UFER | TXX9_SIDISR_UPER); + icount->brk++; + /* + * We do the SysRQ and SAK checking + * here because otherwise the break + * may get masked by ignore_status_mask + * or read_status_mask. + */ +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (port == &rs_ports[sercons.index]) { + if (!break_pressed) { + break_pressed = jiffies; + goto ignore_char; + } + break_pressed = 0; + } +#endif + if (port->gs.flags & ASYNC_SAK) + do_SAK(tty); + } else if (*status & TXX9_SIDISR_UPER) + icount->parity++; + else if (*status & TXX9_SIDISR_UFER) + icount->frame++; + if (*status & TXX9_SIDISR_UOER) + icount->overrun++; + + /* + * Mask off conditions which should be ignored. + */ + *status &= port->read_status_mask; + +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + /* Break flag is updated by reading RFIFO. */ +#endif + if (*status & (TXX9_SIDISR_UBRK)) { + *tty->flip.flag_buf_ptr = TTY_BREAK; + } else if (*status & TXX9_SIDISR_UPER) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (*status & TXX9_SIDISR_UFER) + *tty->flip.flag_buf_ptr = TTY_FRAME; + } +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (break_pressed && port == &rs_ports[sercons.index]) { + if (ch != 0 && + time_before(jiffies, break_pressed + HZ*5)) { + handle_sysrq(ch, regs, NULL, NULL); + break_pressed = 0; + goto ignore_char; + } + break_pressed = 0; + } +#endif + if ((*status & port->ignore_status_mask) == 0) { + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + } + if ((*status & TXX9_SIDISR_UOER) && + (tty->flip.count < TTY_FLIPBUF_SIZE)) { + /* + * Overrun is special, since it's reported + * immediately, and doesn't affect the current + * character + */ + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + tty->flip.count++; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + } +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + ignore_char: +#endif + *status = sio_in(port, TXX9_SIDISR); + } while ((!(*status & TXX9_SIDISR_UVALID)) && (max_count-- > 0)); + tty_flip_buffer_push(tty); +} + +static inline void transmit_chars(struct rs_port *port) +{ + int count; + + if (port->x_char) { + sio_out(port, TXX9_SITFIFO, port->x_char); + port->icount.tx++; + port->x_char = 0; + return; + } + if (port->gs.xmit_cnt <= 0 + || port->gs.tty->stopped + || port->gs.tty->hw_stopped) { + rs_disable_tx_interrupts(port); + return; + } + + count = TXX9_SIO_TX_FIFO; + do { + sio_out(port, TXX9_SITFIFO, port->gs.xmit_buf[port->gs.xmit_tail++]); + port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1; + port->icount.tx++; + if (--port->gs.xmit_cnt <= 0) + break; + } while (--count > 0); + + if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped || + port->gs.tty->hw_stopped) { + rs_disable_tx_interrupts(port); + } + + if (port->gs.xmit_cnt <= port->gs.wakeup_chars) { + if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + port->gs.tty->ldisc.write_wakeup) + (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); + wake_up_interruptible(&port->gs.tty->write_wait); + } +} + +static inline void check_modem_status(struct rs_port *port) +{ + /* We don't have a carrier detect line - but just respond + like we had one anyways so that open() becomes unblocked */ + wake_up_interruptible(&port->gs.open_wait); +} + +#define RS_ISR_PASS_LIMIT 256 + +static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + struct rs_port * port = (struct rs_port *)dev_id; + unsigned long flags; + int status; + int pass_counter = 0; + + local_irq_save(flags); + + if (!port || !port->gs.tty) { + local_irq_restore(flags); + return; + } + + do { + status = sio_in(port, TXX9_SIDISR); + if (!(sio_in(port, TXX9_SIDICR) & TXX9_SIDICR_TIE)) + status &= ~TXX9_SIDISR_TDIS; + if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | + TXX9_SIDISR_TOUT))) + break; + + if (status & TXX9_SIDISR_RDIS) + receive_chars(port, &status, regs); +#if 0 /* RTS/CTS are controled by HW. (if possible) */ + check_modem_status(port); +#endif + if (status & TXX9_SIDISR_TDIS) + transmit_chars(port); + /* Clear TX/RX Int. Status */ + sio_mask(port, TXX9_SIDISR, + TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | + TXX9_SIDISR_TOUT); + + if (pass_counter++ > RS_ISR_PASS_LIMIT) { + break; + } + } while (1); + local_irq_restore(flags); +} + +/* + *********************************************************************** + * Here are the routines that actually * + * interface with the generic_serial driver * + *********************************************************************** + */ +static void rs_disable_tx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + unsigned long flags; + + local_irq_save(flags); + port->gs.flags &= ~GS_TX_INTEN; + sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_TIE); + local_irq_restore(flags); +} + +static void rs_enable_tx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + unsigned long flags; + + local_irq_save(flags); + sio_set(port, TXX9_SIDICR, TXX9_SIDICR_TIE); + local_irq_restore(flags); +} + +static void rs_disable_rx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + unsigned long flags; + + local_irq_save(flags); + port->read_status_mask &= ~TXX9_SIDISR_RDIS; +#if 0 + sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_RIE); +#endif + local_irq_restore(flags); +} + +static void rs_enable_rx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + sio_set(port, TXX9_SIDICR, TXX9_SIDICR_RIE); +} + + +static int rs_get_CD (void * ptr) +{ + /* No Carried Detect in Hardware - just return true */ + return (1); +} + +static void rs_shutdown_port (void * ptr) +{ + struct rs_port *port = ptr; + + port->gs.flags &= ~GS_ACTIVE; + + free_irq(port->irq, port); + sio_out(port, TXX9_SIDICR, 0); /* disable all intrs */ + /* disable break condition */ + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); + +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + if (port == &rs_ports[sercons.index]) { +#endif + if (!port->gs.tty || (port->gs.tty->termios->c_cflag & HUPCL)) { + /* drop RTS */ + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + /* TXX9-SIO can not control DTR... */ + } + + /* reset FIFO's */ + sio_set(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); + /* clear reset */ + sio_mask(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); + /* Disable RX/TX */ + sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + } +#endif +} + +static int rs_set_real_termios (void *ptr) +{ + struct rs_port *port = ptr; + int quot = 0, baud_base, baud; + unsigned cflag, cval, fcr = 0; + int bits; + unsigned long flags; + + if (!port->gs.tty || !port->gs.tty->termios) + return 0; + cflag = port->gs.tty->termios->c_cflag; + cval = sio_in(port, TXX9_SILCR); + /* byte size and parity */ + cval &= ~TXX9_SILCR_UMODE_MASK; + switch (cflag & CSIZE) { + case CS7: + cval |= TXX9_SILCR_UMODE_7BIT; + bits = 9; + break; + case CS5: /* not supported */ + case CS6: /* not supported */ + case CS8: + default: + cval |= TXX9_SILCR_UMODE_8BIT; + bits = 10; + break; + } + cval &= ~TXX9_SILCR_USBL_MASK; + if (cflag & CSTOPB) { + cval |= TXX9_SILCR_USBL_2BIT; + bits++; + } else { + cval |= TXX9_SILCR_USBL_1BIT; + } + + cval &= ~(TXX9_SILCR_UPEN | TXX9_SILCR_UEPS); + if (cflag & PARENB) { + cval |= TXX9_SILCR_UPEN; + bits++; + } + if (!(cflag & PARODD)) + cval |= TXX9_SILCR_UEPS; + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(port->gs.tty); + if (!baud) + baud = 9600; /* B0 transition handled in rs_set_termios */ + baud_base = port->baud_base; + quot = (baud_base + baud / 2) / baud; + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) + quot = (baud_base + 9600 / 2) / 9600; + port->quot = quot; + + /* Set up FIFO's */ + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + fcr = TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1; + + /* CTS flow control flag */ + if (cflag & CRTSCTS) { + port->gs.flags |= ASYNC_CTS_FLOW; + if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE) + sio_out(port, TXX9_SIFLCR, + TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES | + TXX9_SIFLCR_RTSTL_MAX /* 15 */); + } else { + port->gs.flags &= ~ASYNC_CTS_FLOW; + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES | + TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); + } + + /* + * Set up parity check flag + */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + port->read_status_mask = TXX9_SIDISR_UOER | + TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS; + if (I_INPCK(port->gs.tty)) + port->read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER; + if (I_BRKINT(port->gs.tty) || I_PARMRK(port->gs.tty)) + port->read_status_mask |= TXX9_SIDISR_UBRK; + + /* + * Characters to ignore + */ + port->ignore_status_mask = 0; + if (I_IGNPAR(port->gs.tty)) + port->ignore_status_mask |= TXX9_SIDISR_UPER | TXX9_SIDISR_UFER; + if (I_IGNBRK(port->gs.tty)) { + port->ignore_status_mask |= TXX9_SIDISR_UBRK; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(port->gs.tty)) + port->ignore_status_mask |= TXX9_SIDISR_UOER; + } +#if 0 /* XXX: This cause problem with some programs(init, mingetty, etc) */ + /* + * !!! ignore all characters if CREAD is not set + */ + if ((cflag & CREAD) == 0) + port->ignore_status_mask |= TXX9_SIDISR_RDIS; +#endif + local_irq_save(flags); + cval &= ~TXX9_SILCR_SCS_IMCLK; + sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG); + sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0); + sio_out(port, TXX9_SIFCR, fcr); + local_irq_restore(flags); + return 0; +} + +static int rs_chars_in_buffer (void * ptr) +{ + struct rs_port *port = ptr; + + /* return 0 if transmitter disabled. */ + if (sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_TSDE) + return 0; + return (sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS) ? 0 : 1; +} + +/* ********************************************************************** * + * Here are the routines that actually * + * interface with the rest of the system * + * ********************************************************************** */ +static int rs_open (struct tty_struct * tty, struct file * filp) +{ + struct rs_port *port; + int retval, line; + + if (!rs_initialized) { + return -EIO; + } + + line = MINOR(tty->device) - tty->driver.minor_start; + + if ((line < 0) || (line >= NR_PORTS)) + return -ENODEV; + + /* Pre-initialized already */ + port = & rs_ports[line]; + + if (!port->base) + return -ENODEV; + + tty->driver_data = port; + port->gs.tty = tty; + port->gs.count++; + + /* + * Start up serial port + */ + retval = gs_init_port(&port->gs); + if (retval) { + port->gs.count--; + return retval; + } + + port->gs.flags |= GS_ACTIVE; + + if (port->gs.count == 1) { + MOD_INC_USE_COUNT; + + /* + * Clear the FIFO buffers and disable them + * (they will be reenabled in rs_set_real_termios()) + */ + sio_set(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | + TXX9_SIFCR_FRSTE); + /* clear reset */ + sio_mask(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | + TXX9_SIFCR_FRSTE); + sio_out(port, TXX9_SIDICR, 0); + + retval = request_irq(port->irq, rs_interrupt, SA_SHIRQ, + "serial_txx9", port); + if (retval) { + printk(KERN_ERR "serial_txx9: request_irq: err %d\n", + retval); + MOD_DEC_USE_COUNT; + port->gs.count--; + return retval; + } + /* + * Clear the interrupt registers. + */ + sio_out(port, TXX9_SIDISR, 0); + + /* HW RTS/CTS control */ + if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE) + sio_out(port, TXX9_SIFLCR, + TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES | + TXX9_SIFLCR_RTSTL_MAX /* 15 */); + } + + /* Enable RX/TX */ + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); + + /* + * Finally, enable interrupts + */ + rs_enable_rx_interrupts(port); + + /* + * and set the speed of the serial port + */ + rs_set_real_termios(port); + + retval = gs_block_til_ready(&port->gs, filp); + + if (retval) { + if (port->gs.count == 1) { + free_irq(port->irq, port); + MOD_DEC_USE_COUNT; + } + port->gs.count--; + return retval; + } + /* tty->low_latency = 1; */ + + if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = port->gs.normal_termios; + else + *tty->termios = port->gs.callout_termios; + rs_set_real_termios(port); + } +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + rs_set_real_termios(port); + } +#endif + port->gs.session = current->session; + port->gs.pgrp = current->pgrp; + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline int line_info(char *buf, struct rs_port *port) +{ + char stat_buf[30]; + int ret; + unsigned long flags; + + ret = sprintf(buf, "%d: uart:txx9 io%s:%lx irq:%d", + port - &rs_ports[0], + port->io_type < 0 ? "mem" : "port", + port->base, port->irq); + + if (!port->base) { + ret += sprintf(buf+ret, "\n"); + return ret; + } + + /* + * Figure out the current RS-232 lines + */ + stat_buf[0] = 0; + stat_buf[1] = 0; + local_irq_save(flags); + if (!(sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC)) + strcat(stat_buf, "|RTS"); + if (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS)) + strcat(stat_buf, "|CTS"); + local_irq_restore(flags); + + if (port->quot) { + ret += sprintf(buf+ret, " baud:%d", + port->baud_base / port->quot); + } + + ret += sprintf(buf+ret, " tx:%d rx:%d", + port->icount.tx, port->icount.rx); + + if (port->icount.frame) + ret += sprintf(buf+ret, " fe:%d", port->icount.frame); + + if (port->icount.parity) + ret += sprintf(buf+ret, " pe:%d", port->icount.parity); + + if (port->icount.brk) + ret += sprintf(buf+ret, " brk:%d", port->icount.brk); + + if (port->icount.overrun) + ret += sprintf(buf+ret, " oe:%d", port->icount.overrun); + + /* + * Last thing is the RS-232 status lines + */ + ret += sprintf(buf+ret, " %s\n", stat_buf+1); + return ret; +} + +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_ports[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +static void rs_close (void *ptr) +{ +#if 0 + struct rs_port *port = ptr; + free_irq(port->irq, port); +#endif + MOD_DEC_USE_COUNT; +} + +/* I haven't the foggiest why the decrement use count has to happen + here. The whole linux serial drivers stuff needs to be redesigned. + My guess is that this is a hack to minimize the impact of a bug + elsewhere. Thinking about it some more. (try it sometime) Try + running minicom on a serial port that is driven by a modularized + driver. Have the modem hangup. Then remove the driver module. Then + exit minicom. I expect an "oops". -- REW */ +static void rs_hungup (void *ptr) +{ + MOD_DEC_USE_COUNT; +} + +static void rs_getserial (void *ptr, struct serial_struct *sp) +{ + struct rs_port *port = ptr; + struct tty_struct *tty = port->gs.tty; + /* some applications (busybox, dbootstrap, etc.) look this */ + sp->line = MINOR(tty->device) - tty->driver.minor_start; +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ + struct rs_port *port = tty->driver_data; + unsigned long flags; + + if (!port->base) + return; + local_irq_save(flags); + if (break_state == -1) + sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); + else + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); + local_irq_restore(flags); +} + +static int get_modem_info(struct rs_port *port, unsigned int *value) +{ + unsigned int result; + unsigned long flags; + + local_irq_save(flags); + result = ((sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) + | ((sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); + local_irq_restore(flags); + return put_user(result,value); +} + +static int set_modem_info(struct rs_port *port, unsigned int cmd, + unsigned int *value) +{ + int error = 0; + unsigned int arg; + unsigned long flags; + + if (copy_from_user(&arg, value, sizeof(int))) + return -EFAULT; + + local_irq_save(flags); + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + break; + case TIOCMBIC: + if (arg & TIOCM_RTS) + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + break; + case TIOCMSET: + if (arg & TIOCM_RTS) + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + else + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + break; + default: + error = -EINVAL; + } + local_irq_restore(flags); + return error; +} + +static int rs_ioctl (struct tty_struct * tty, struct file * filp, + unsigned int cmd, unsigned long arg) +{ + int rc; + struct rs_port *port = tty->driver_data; + int ival; + + rc = 0; + switch (cmd) { + case TIOCMGET: + return get_modem_info(port, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(port, cmd, (unsigned int *) arg); + return 0; + case TIOCGSOFTCAR: + rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), + (unsigned int *) arg); + break; + case TIOCSSOFTCAR: + if ((rc = verify_area(VERIFY_READ, (void *) arg, + sizeof(int))) == 0) { + get_user(ival, (unsigned int *) arg); + tty->termios->c_cflag = + (tty->termios->c_cflag & ~CLOCAL) | + (ival ? CLOCAL : 0); + } + break; + case TIOCGSERIAL: + if ((rc = verify_area(VERIFY_WRITE, (void *) arg, + sizeof(struct serial_struct))) == 0) + rc = gs_getserial(&port->gs, (struct serial_struct *) arg); + break; + case TIOCSSERIAL: + if ((rc = verify_area(VERIFY_READ, (void *) arg, + sizeof(struct serial_struct))) == 0) + rc = gs_setserial(&port->gs, (struct serial_struct *) arg); + break; + default: + rc = -ENOIOCTLCMD; + break; + } + + return rc; +} + + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct * tty, char ch) +{ + struct rs_port *port = (struct rs_port *)tty->driver_data; + + port->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + rs_enable_tx_interrupts(tty); + } +} + + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct rs_port *port = (struct rs_port *)tty->driver_data; + unsigned long flags; + + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); + if (tty->termios->c_cflag & CRTSCTS) { + local_irq_save(flags); + /* drop RTS */ + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + local_irq_restore(flags); + } +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct rs_port *port = tty->driver_data; + unsigned long flags; + + if (I_IXOFF(tty)) { + if (port->x_char) + port->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } + if (tty->termios->c_cflag & CRTSCTS) { + local_irq_save(flags); + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + local_irq_restore(flags); + } +} + +/* ********************************************************************** * + * Here are the initialization routines. * + * ********************************************************************** */ + +static inline void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s\n", serial_name, serial_version); +} + +static int rs_init_portstructs(void) +{ + struct rs_port *port; + int i; + + /* Adjust the values in the "driver" */ + rs_driver.termios = rs_termios; + rs_driver.termios_locked = rs_termios_locked; + + port = rs_ports; + for (i=0; i < NR_PORTS;i++) { + port->gs.callout_termios = tty_std_termios; + port->gs.normal_termios = tty_std_termios; + port->gs.magic = TXX9_SERIAL_MAGIC; + port->gs.close_delay = HZ/2; + port->gs.closing_wait = 30 * HZ; + port->gs.rd = &rs_real_driver; +#ifdef NEW_WRITE_LOCKING + port->gs.port_write_sem = MUTEX; +#endif +#ifdef DECLARE_WAITQUEUE + init_waitqueue_head(&port->gs.open_wait); + init_waitqueue_head(&port->gs.close_wait); +#endif + port++; + } + + return 0; +} + +static int rs_init_drivers(void) +{ + int error; + + memset(&rs_driver, 0, sizeof(rs_driver)); + rs_driver.magic = TTY_DRIVER_MAGIC; + rs_driver.driver_name = "serial_txx9"; +#if defined(CONFIG_DEVFS_FS) + rs_driver.name = TXX9_TTY_DEVFS_NAME; +#else + rs_driver.name = TXX9_TTY_NAME; +#endif + rs_driver.major = TXX9_TTY_MAJOR; + rs_driver.minor_start = TXX9_TTY_MINOR_START; + rs_driver.num = NR_PORTS; + rs_driver.type = TTY_DRIVER_TYPE_SERIAL; + rs_driver.subtype = SERIAL_TYPE_NORMAL; + rs_driver.init_termios = tty_std_termios; + rs_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + rs_driver.refcount = &rs_refcount; + rs_driver.table = rs_table; + rs_driver.termios = rs_termios; + rs_driver.termios_locked = rs_termios_locked; + + rs_driver.open = rs_open; + rs_driver.close = gs_close; + rs_driver.write = gs_write; + rs_driver.put_char = gs_put_char; + rs_driver.flush_chars = gs_flush_chars; + rs_driver.write_room = gs_write_room; + rs_driver.chars_in_buffer = gs_chars_in_buffer; + rs_driver.flush_buffer = gs_flush_buffer; + rs_driver.ioctl = rs_ioctl; + rs_driver.throttle = rs_throttle; + rs_driver.unthrottle = rs_unthrottle; + rs_driver.set_termios = gs_set_termios; + rs_driver.stop = gs_stop; + rs_driver.start = gs_start; + rs_driver.hangup = gs_hangup; + rs_driver.break_ctl = rs_break; + rs_driver.read_proc = rs_read_proc; + + rs_callout_driver = rs_driver; +#if defined(CONFIG_DEVFS_FS) + rs_callout_driver.name = TXX9_CU_DEVFS_NAME; +#else + rs_callout_driver.name = TXX9_CU_NAME; +#endif + rs_callout_driver.major = TXX9_TTYAUX_MAJOR; + rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT; + rs_callout_driver.read_proc = 0; + rs_callout_driver.proc_entry = 0; + + if ((error = tty_register_driver(&rs_driver))) { + printk(KERN_ERR + "Couldn't register serial driver, error = %d\n", + error); + return 1; + } + if ((error = tty_register_driver(&rs_callout_driver))) { + tty_unregister_driver(&rs_driver); + printk(KERN_ERR + "Couldn't register callout driver, error = %d\n", + error); + return 1; + } + + return 0; +} + +/* + * This routine is called by txx9_rs_init() to initialize a specific serial + * port. + */ +static void txx9_config(struct rs_port *port) +{ + unsigned long flags; + + if (port - &rs_ports[0] != sercons.index) { + local_irq_save(flags); + /* + * Reset the UART. + */ + sio_out(port, TXX9_SIFCR, TXX9_SIFCR_SWRST); +#ifdef CONFIG_CPU_TX49XX + /* TX4925 BUG WORKAROUND. Accessing SIOC register + * immediately after soft reset causes bus error. */ + wbflush();/* change iob(); */ + udelay(1); +#endif + while (sio_in(port, TXX9_SIFCR) & TXX9_SIFCR_SWRST) + ; + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + sio_set(port, TXX9_SIFCR, + TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); + /* initial settings */ + sio_out(port, TXX9_SILCR, + TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | + TXX9_SILCR_SCS_IMCLK_BG); + sio_out(port, TXX9_SIBGR, + ((port->baud_base + 9600 / 2) / 9600) | + TXX9_SIBGR_BCLK_T0); + local_irq_restore(flags); + } + DBG("txx9_config: port->io_type is %d\n", port->io_type); + if (port->io_type < 0) + request_mem_region(port->base, 36, "serial_txx9"); + else + request_region(port->base, 36, "serial_txx9"); +} + +#ifdef ENABLE_SERIAL_TXX9_PCI +static int __devinit serial_txx9_init_one(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + int rc, i; + struct rs_port *port; + + rc = pci_enable_device(dev); + if (rc) return rc; + + /* find empty slot */ + for (i = 0; i < NR_PORTS && rs_ports[i].base; i++) + ; + if (i == NR_PORTS) + return -ENODEV; + port = &rs_ports[i]; + DBG("port number is %d\n",i); + + port->pci_dev = dev; + port->base = pci_resource_start(dev, 1); + + DBG("port->base is %x\n",(u32)port->base); + port->io_type = SERIAL_IO_PORT; + port->irq = dev->irq; + port->flags |= TXX9_SERIAL_HAVE_CTS_LINE; + port->baud_base = 66670000 / 16 / 2; /* 66.67MHz */ + DBG("port->baud_base %x\n",port->baud_base); + + txx9_config(port); + + printk(KERN_INFO + "%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n", + TXX9_TTY_NAME, i, port->base, port->irq); + return 0; +} + +static void __devexit serial_txx9_remove_one(struct pci_dev *dev) +{ + int i; + for (i = 0; i < NR_PORTS; i++) { + if (rs_ports[i].pci_dev == dev) { + rs_ports[i].irq = 0; + rs_ports[i].base = 0; + rs_ports[i].pci_dev = 0; + /* XXX NOT IMPLEMENTED YET */ + break; + } + } +} + +static struct pci_device_id serial_txx9_pci_tbl[] __devinitdata = { +#ifdef PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC + { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + 0 }, +#endif + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl); + +static struct pci_driver serial_txx9_pci_driver = { + name: "serial_txx9", + probe: serial_txx9_init_one, + remove: __devexit_p(serial_txx9_remove_one), + id_table: serial_txx9_pci_tbl, +}; + +/* + * Query PCI space for known serial boards + * If found, add them to the PCI device space in rs_table[] + */ +static void __devinit probe_serial_txx9_pci(void) +{ + /* Register call PCI serial devices. Null out + * the driver name upon failure, as a signal + * not to attempt to unregister the driver later + */ + if (pci_module_init (&serial_txx9_pci_driver) != 0) + serial_txx9_pci_driver.name = ""; + + return; +} +#endif /* ENABLE_SERIAL_TXX9_PCI */ + +static int __init txx9_rs_init(void) +{ + int rc; + struct rs_port *port; + int i; + +#ifndef ENABLE_SERIAL_TXX9_PCI + for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) { + if (port->base) + goto config_ok; + } + return -ENODEV; + config_ok: +#endif + + show_serial_version(); + rc = rs_init_portstructs (); + rs_init_drivers (); + for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) { + if (!port->base) + continue; + if (port->io_type < 0) { + if (check_mem_region(port->base, 36)) + continue; + } else { + if (check_region(port->base, 36)) + continue; + } + txx9_config(port); + printk(KERN_INFO + "%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n", + TXX9_TTY_NAME, i, port->base, port->irq); + } + + /* Note: I didn't do anything to enable the second UART */ + if (rc >= 0) + rs_initialized++; + +#ifdef ENABLE_SERIAL_TXX9_PCI + probe_serial_txx9_pci(); +#endif + return 0; +} + +/* + * This is for use by architectures that know their serial console + * attributes only at run time. Not to be invoked after rs_init(). + */ +int __init early_serial_txx9_setup(int line, unsigned long base, int irq, + int baud_base, int have_cts) +{ + if (line >= NR_PORTS) + return(-ENOENT); + rs_ports[line].base = base; + rs_ports[line].irq = irq; + rs_ports[line].baud_base = baud_base; + rs_ports[line].io_type = -1; /* virtual memory mapped */ + if (have_cts) + rs_ports[line].flags |= TXX9_SERIAL_HAVE_CTS_LINE; + return(0); +} + +static void __exit txx9_rs_fini(void) +{ + unsigned long flags; + int e1, e2; + int i; + + local_irq_save(flags); + if ((e1 = tty_unregister_driver(&rs_driver))) + printk("serial: failed to unregister serial driver (%d)\n", + e1); + if ((e2 = tty_unregister_driver(&rs_callout_driver))) + printk("serial: failed to unregister callout driver (%d)\n", + e2); + local_irq_restore(flags); + + for (i = 0; i < NR_PORTS; i++) { + if (!rs_ports[i].base) + continue; + if (rs_ports[i].io_type < 0) + release_mem_region(rs_ports[i].base, 36); + else + release_region(rs_ports[i].base, 36); + } + +#ifdef ENABLE_SERIAL_PCI + if (serial_txx9_pci_driver.name[0]) + pci_unregister_driver (&serial_txx9_pci_driver); +#endif +} + +module_init(txx9_rs_init); +module_exit(txx9_rs_fini); +MODULE_DESCRIPTION("TX39/49 serial driver"); +MODULE_AUTHOR("TOSHIBA Corporation"); +MODULE_LICENSE("GPL"); + +/* + * Begin serial console routines + */ +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct rs_port *port) +{ + unsigned int tmout = 1000000; + + do { + if (--tmout == 0) break; + } while (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS)); + + /* Wait for flow control if necessary */ +#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0 /* check conflict... */ + if (port->gs.flags & ASYNC_CONS_FLOW) { + tmout = 1000000; + while (--tmout && + (sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS)); + } +#endif +} + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console_lock must be held when we get here. + */ +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + struct rs_port *port = &rs_ports[co->index]; + int ier; + unsigned i; + + /* + * First save the IER then disable the interrupts + */ + ier = sio_in(port, TXX9_SIDICR); + sio_out(port, TXX9_SIDICR, 0); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(port); + + /* + * Send the character out. + * If a LF, also do CR... + */ + sio_out(port, TXX9_SITFIFO, *s); + if (*s == 10) { + wait_for_xmitr(port); + sio_out(port, TXX9_SITFIFO, 13); + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + wait_for_xmitr(port); + sio_out(port, TXX9_SIDICR, ier); +} + +static kdev_t serial_console_device(struct console *c) +{ + return MKDEV(TXX9_TTY_MAJOR, TXX9_TTY_MINOR_START + c->index); +} + +static __init int serial_console_setup(struct console *co, char *options) +{ + struct rs_port *port; + unsigned cval; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int doflow = 0; + int cflag = CREAD | HUPCL | CLOCAL; + int quot = 0; + char *s; + + if (co->index < 0 || co->index >= NR_PORTS) + return -1; + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + if (*s) doflow = (*s++ == 'r'); + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: cflag |= B1200; break; + case 2400: cflag |= B2400; break; + case 4800: cflag |= B4800; break; + case 19200: cflag |= B19200; break; + case 38400: cflag |= B38400; break; + case 57600: cflag |= B57600; break; + case 115200: cflag |= B115200; break; + default: + /* + * Set this to a sane value to prevent a divide error + */ + baud = 9600; + case 9600: cflag |= B9600; break; + } + + switch(bits) { + case 7: cflag |= CS7; break; + default: + case 8: cflag |= CS8; break; + } + switch(parity) { + case 'o': case 'O': cflag |= PARODD; break; + case 'e': case 'E': cflag |= PARENB; break; + } + co->cflag = cflag; + + port = &rs_ports[co->index]; + if (!port->base) + return -1; + + /* + * Divisor, bytesize and parity + */ +#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0 /* check conflict... */ + if (doflow) + port->gs.flags |= ASYNC_CONS_FLOW; +#endif + quot = port->baud_base / baud; + switch (cflag & CSIZE) { + case CS7: cval = TXX9_SILCR_UMODE_7BIT; break; + default: + case CS8: cval = TXX9_SILCR_UMODE_8BIT; break; + } + if (cflag & CSTOPB) + cval |= TXX9_SILCR_USBL_2BIT; + else + cval |= TXX9_SILCR_USBL_1BIT; + if (cflag & PARENB) + cval |= TXX9_SILCR_UPEN; + if (!(cflag & PARODD)) + cval |= TXX9_SILCR_UEPS; + + /* + * Disable UART interrupts, set DTR and RTS high + * and set speed. + */ + sio_out(port, TXX9_SIDICR, 0); + sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG); + sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0); + /* no RTS/CTS control */ + sio_out(port, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); + /* Enable RX/TX */ + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); + + /* console port should not use RTC/CTS. */ + port->flags &= ~TXX9_SERIAL_HAVE_CTS_LINE; + return 0; +} + +static struct console sercons = { + name: TXX9_TTY_NAME, + write: serial_console_write, + device: serial_console_device, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, +}; + +void __init txx9_serial_console_init(void) +{ + register_console(&sercons); +} + +#endif + +/******************************************************************************/ +/* BEG: KDBG Routines */ +/******************************************************************************/ + +#ifdef CONFIG_KGDB +int kgdb_init_count = 0; +#endif + +#ifdef CONFIG_KGDB +void txx9_sio_kgdb_hook(unsigned int port, unsigned int baud_rate) +{ + static struct resource kgdb_resource; + int ret; + + /* prevent initialization by driver */ + kgdb_resource.name = "serial_txx9(debug)"; + kgdb_resource.start = rs_ports[port].base; + kgdb_resource.end = rs_ports[port].base + 36 - 1; + kgdb_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + ret = request_resource(&iomem_resource, &kgdb_resource); + if(ret == -EBUSY) + printk(" serial_txx9(debug): request_resource failed\n"); + + return; +} +#endif /* CONFIG_KGDB */ + +#ifdef CONFIG_KGDB +void +txx9_sio_kdbg_init( unsigned int port_number ) +{ + if ( port_number == 1 ) { + txx9_sio_kgdb_hook( port_number, 38400 ); + } else { + printk("Bad Port Number [%u] != [1]\n",port_number); + } + return; +} +#endif /* CONFIG_KGDB */ + +#ifdef CONFIG_KGDB +u8 +txx9_sio_kdbg_rd( void ) +{ + unsigned int status,ch; + + if ( kgdb_init_count == 0 ) + { + txx9_sio_kdbg_init( 1 ); + kgdb_init_count = 1; + } + + while ( 1 ) + { + status = sio_in(&rs_ports[1], TXX9_SIDISR); + if ( status & 0x1f ) + { + ch = sio_in(&rs_ports[1], TXX9_SIRFIFO ); + break; + } + } + + return( ch ); +} +#endif /* CONFIG_KGDB */ + +#ifdef CONFIG_KGDB +int +txx9_sio_kdbg_wr( u8 ch ) +{ + unsigned int status; + + if ( kgdb_init_count == 0 ) + { + txx9_sio_kdbg_init( 1 ); + kgdb_init_count = 1; + } + + while ( 1 ) + { + status = sio_in(&rs_ports[1], TXX9_SICISR); + if (status & TXX9_SICISR_TRDY) + { + if ( ch == '\n' ) + { + txx9_sio_kdbg_wr( '\r' ); + } + sio_out(&rs_ports[1], TXX9_SITFIFO, (u32)ch ); + + break; + } + } + + return( 1 ); +} +#endif /* CONFIG_KGDB */ + +/******************************************************************************/ +/* END: KDBG Routines */ +/******************************************************************************/ + +void txx9_raw_output(char c) +{ + struct rs_port *port = &rs_ports[0]; + if ( c == '\n' ) + { + sio_out(port, TXX9_SITFIFO, '\r'); + wait_for_xmitr(port); + } + sio_out(port, TXX9_SITFIFO, c); + wait_for_xmitr(port); + return; +} diff -urN linux-2.4.21/drivers/char/sgiserial.c linux-2.4.22/drivers/char/sgiserial.c --- linux-2.4.21/drivers/char/sgiserial.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/sgiserial.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,2235 @@ +/* sgiserial.c: Serial port driver for SGI machines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +/* + * Note: This driver seems to have been derived from some + * version of the sbus/char/zs.c driver. A lot of clean-up + * and bug fixes seem to have happened to the Sun driver in + * the intervening time. As of 21.09.1999, I have merged in + * ONLY the changes necessary to fix observed functional + * problems on the Indy. Someone really ought to do a + * thorough pass to merge in the rest of the updates. + * Better still, someone really ought to make it a common + * code module for both platforms. kevink@mips.com + * + * 20010616 - Klaus Naumann : Make serial console work with + * any speed - not only 9600 + */ + +#include /* for CONFIG_KGDB */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sgiserial.h" + +#define NUM_SERIAL 1 /* One chip on board. */ +#define NUM_CHANNELS (NUM_SERIAL * 2) + +struct sgi_zslayout *zs_chips[NUM_SERIAL]; +struct sgi_zschannel *zs_channels[NUM_CHANNELS]; +struct sgi_zschannel *zs_conschan; +struct sgi_zschannel *zs_kgdbchan; + +struct sgi_serial zs_soft[NUM_CHANNELS]; +struct sgi_serial *zs_chain; /* IRQ servicing chain */ +static int zilog_irq = SGI_SERIAL_IRQ; + +/* Console hooks... */ +static int zs_cons_chanout; +static int zs_cons_chanin; +struct sgi_serial *zs_consinfo; + +static unsigned char kgdb_regs[16] = { + 0, 0, 0, /* write 0, 1, 2 */ + (Rx8 | RxENABLE), /* write 3 */ + (X16CLK | SB1 | PAR_EVEN), /* write 4 */ + (Tx8 | TxENAB), /* write 5 */ + 0, 0, 0, /* write 6, 7, 8 */ + (NV), /* write 9 */ + (NRZ), /* write 10 */ + (TCBR | RCBR), /* write 11 */ + 0, 0, /* BRG time constant, write 12 + 13 */ + (BRENABL), /* write 14 */ + (DCDIE) /* write 15 */ +}; + +static unsigned char zscons_regs[16] = { + 0, /* write 0 */ + (EXT_INT_ENAB | INT_ALL_Rx), /* write 1 */ + 0, /* write 2 */ + (Rx8 | RxENABLE), /* write 3 */ + (X16CLK), /* write 4 */ + (DTR | Tx8 | TxENAB), /* write 5 */ + 0, 0, 0, /* write 6, 7, 8 */ + (NV | MIE), /* write 9 */ + (NRZ), /* write 10 */ + (TCBR | RCBR), /* write 11 */ + 0, 0, /* BRG time constant, write 12 + 13 */ + (BRENABL), /* write 14 */ + (DCDIE | CTSIE | TxUIE | BRKIE) /* write 15 */ +}; + +#define ZS_CLOCK 3672000 /* Zilog input clock rate */ + +DECLARE_TASK_QUEUE(tq_serial); + +struct tty_driver serial_driver, callout_driver; +struct console *sgisercon; +static int serial_refcount; + +/* serial subtype definitions */ +#define SERIAL_TYPE_NORMAL 1 +#define SERIAL_TYPE_CALLOUT 2 + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +#undef SERIAL_DEBUG_OPEN + +static void change_speed(struct sgi_serial *info); + +static struct tty_struct *serial_table[NUM_CHANNELS]; +static struct termios *serial_termios[NUM_CHANNELS]; +static struct termios *serial_termios_locked[NUM_CHANNELS]; + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the memcpy_fromfs blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char tmp_buf[PAGE_SIZE]; /* This is cheating */ +static DECLARE_MUTEX(tmp_buf_sem); + +static inline int serial_paranoia_check(struct sgi_serial *info, + dev_t device, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = KERN_WARNING + "Warning: bad magic number for serial struct (%d, %d) in %s\n"; + static const char *badinfo = KERN_WARNING + "Warning: null sgi_serial for (%d, %d) in %s\n"; + + if (!info) { + printk(badinfo, MAJOR(device), MINOR(device), routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, MAJOR(device), MINOR(device), routine); + return 1; + } +#endif + return 0; +} + +/* + * This is used to figure out the divisor speeds and the timeouts + */ +static int baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 115200, 0 }; + +/* + * Reading and writing Zilog8530 registers. The delays are to make this + * driver work on the Sun4 which needs a settling delay after each chip + * register access, other machines handle this in hardware via auxiliary + * flip-flops which implement the settle time we do in software. + * + * read_zsreg() and write_zsreg() may get called from rs_kgdb_hook() before + * interrupts are enabled. Therefore we have to check ioc_iocontrol before we + * access it. + */ +static inline unsigned char read_zsreg(struct sgi_zschannel *channel, + unsigned char reg) +{ + unsigned char retval; + volatile unsigned char junk; + + udelay(2); + channel->control = reg; + junk = sgint->istat0; + udelay(1); + retval = channel->control; + return retval; +} + +static inline void write_zsreg(struct sgi_zschannel *channel, + unsigned char reg, unsigned char value) +{ + volatile unsigned char junk; + + udelay(2); + channel->control = reg; + junk = sgint->istat0; + udelay(1); + channel->control = value; + junk = sgint->istat0; + return; +} + +static inline void load_zsregs(struct sgi_zschannel *channel, unsigned char *regs) +{ + ZS_CLEARERR(channel); + ZS_CLEARFIFO(channel); + /* Load 'em up */ + write_zsreg(channel, R4, regs[R4]); + write_zsreg(channel, R10, regs[R10]); + write_zsreg(channel, R3, regs[R3] & ~RxENABLE); + write_zsreg(channel, R5, regs[R5] & ~TxENAB); + write_zsreg(channel, R1, regs[R1]); + write_zsreg(channel, R9, regs[R9]); + write_zsreg(channel, R11, regs[R11]); + write_zsreg(channel, R12, regs[R12]); + write_zsreg(channel, R13, regs[R13]); + write_zsreg(channel, R14, regs[R14]); + write_zsreg(channel, R15, regs[R15]); + write_zsreg(channel, R3, regs[R3]); + write_zsreg(channel, R5, regs[R5]); + return; +} + +/* Sets or clears DTR/RTS on the requested line */ +static inline void zs_rtsdtr(struct sgi_serial *ss, int set) +{ + if(set) { + ss->curregs[5] |= (RTS | DTR); + write_zsreg(ss->zs_channel, 5, ss->curregs[5]); + } else { + ss->curregs[5] &= ~(RTS | DTR); + write_zsreg(ss->zs_channel, 5, ss->curregs[5]); + } + return; +} + +static inline void kgdb_chaninit(struct sgi_serial *ss, int intson, int bps) +{ + int brg; + + if(intson) { + kgdb_regs[R1] = INT_ALL_Rx; + kgdb_regs[R9] |= MIE; + } else { + kgdb_regs[R1] = 0; + kgdb_regs[R9] &= ~MIE; + } + brg = BPS_TO_BRG(bps, ZS_CLOCK/ss->clk_divisor); + kgdb_regs[R12] = (brg & 255); + kgdb_regs[R13] = ((brg >> 8) & 255); + load_zsregs(ss->zs_channel, kgdb_regs); +} + +/* Utility routines for the Zilog */ +static inline int get_zsbaud(struct sgi_serial *ss) +{ + struct sgi_zschannel *channel = ss->zs_channel; + int brg; + + /* The baud rate is split up between two 8-bit registers in + * what is termed 'BRG time constant' format in my docs for + * the chip, it is a function of the clk rate the chip is + * receiving which happens to be constant. + */ + brg = ((read_zsreg(channel, 13)&0xff) << 8); + brg |= (read_zsreg(channel, 12)&0xff); + return BRG_TO_BPS(brg, (ZS_CLOCK/(ss->clk_divisor))); +} + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_stop")) + return; + + save_flags(flags); cli(); + if (info->curregs[5] & TxENAB) { + info->curregs[5] &= ~TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + } + restore_flags(flags); +} + +static void rs_start(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_start")) + return; + + save_flags(flags); cli(); + if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) { + info->curregs[5] |= TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + } + restore_flags(flags); +} + +/* Drop into either the boot monitor or kadb upon receiving a break + * from keyboard/console input. + */ +static void batten_down_hatches(void) +{ + ArcEnterInteractiveMode(); +#if 0 + /* If we are doing kadb, we call the debugger + * else we just drop into the boot monitor. + * Note that we must flush the user windows + * first before giving up control. + */ + printk("\n"); + if((((unsigned long)linux_dbvec)>=DEBUG_FIRSTVADDR) && + (((unsigned long)linux_dbvec)<=DEBUG_LASTVADDR)) + sp_enter_debugger(); + else + prom_halt(); + + /* XXX We want to notify the keyboard driver that all + * XXX keys are in the up state or else weird things + * XXX happen... + */ +#endif + return; +} + +/* On receive, this clears errors and the receiver interrupts */ +static inline void rs_recv_clear(struct sgi_zschannel *zsc) +{ + volatile unsigned char junk; + + udelay(2); + zsc->control = ERR_RES; + junk = sgint->istat0; + udelay(2); + zsc->control = RES_H_IUS; + junk = sgint->istat0; +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * Note: rs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * rs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static inline void rs_sched_event(struct sgi_serial *info, + int event) +{ + info->event |= 1 << event; + queue_task(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +#ifdef CONFIG_KGDB +extern void set_async_breakpoint(unsigned int epc); +#endif + +static inline void receive_chars(struct sgi_serial *info, struct pt_regs *regs) +{ + struct tty_struct *tty = info->tty; + volatile unsigned char junk; + unsigned char ch, stat; + + udelay(2); + ch = info->zs_channel->data; + junk = sgint->istat0; + udelay(2); + stat = read_zsreg(info->zs_channel, R1); + + /* If this is the console keyboard, we need to handle + * L1-A's here. + */ + if(info->is_cons) { + if(ch==0) { /* whee, break received */ + batten_down_hatches(); + rs_recv_clear(info->zs_channel); + return; + } else if (ch == 1) { + show_state(); + return; + } else if (ch == 2) { + show_buffers(); + return; + } + } + /* Look for kgdb 'stop' character, consult the gdb documentation + * for remote target debugging and arch/sparc/kernel/sparc-stub.c + * to see how all this works. + */ +#ifdef CONFIG_KGDB + if((info->kgdb_channel) && (ch =='\003')) { + set_async_breakpoint(read_32bit_cp0_register(CP0_EPC)); + goto clear_and_exit; + } +#endif + if(!tty) + goto clear_and_exit; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + queue_task(&tty->flip.tqueue, &tq_timer); + tty->flip.count++; + if(stat & PAR_ERR) + *tty->flip.flag_buf_ptr++ = TTY_PARITY; + else if(stat & Rx_OVR) + *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; + else if(stat & CRC_ERR) + *tty->flip.flag_buf_ptr++ = TTY_FRAME; + else + *tty->flip.flag_buf_ptr++ = 0; /* XXX */ + *tty->flip.char_buf_ptr++ = ch; + + queue_task(&tty->flip.tqueue, &tq_timer); + +clear_and_exit: + rs_recv_clear(info->zs_channel); + return; +} + +static inline void transmit_chars(struct sgi_serial *info) +{ + volatile unsigned char junk; + + /* P3: In theory we have to test readiness here because a + * serial console can clog the chip through zs_cons_put_char(). + * David did not do this. I think he relies on 3-chars FIFO in 8530. + * Let's watch for lost _output_ characters. XXX + */ + + /* SGI ADDENDUM: On most SGI machines, the Zilog does possess + * a 16 or 17 byte fifo, so no worries. -dm + */ + + if (info->x_char) { + /* Send next char */ + udelay(2); + info->zs_channel->data = info->x_char; + junk = sgint->istat0; + + info->x_char = 0; + goto clear_and_return; + } + + if((info->xmit_cnt <= 0) || info->tty->stopped) { + /* That's peculiar... */ + udelay(2); + info->zs_channel->control = RES_Tx_P; + junk = sgint->istat0; + goto clear_and_return; + } + + /* Send char */ + udelay(2); + info->zs_channel->data = info->xmit_buf[info->xmit_tail++]; + junk = sgint->istat0; + + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + + if (info->xmit_cnt < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + + if(info->xmit_cnt <= 0) { + udelay(2); + info->zs_channel->control = RES_Tx_P; + junk = sgint->istat0; + goto clear_and_return; + } + +clear_and_return: + /* Clear interrupt */ + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + return; +} + +static inline void status_handle(struct sgi_serial *info) +{ + volatile unsigned char junk; + unsigned char status; + + /* Get status from Read Register 0 */ + udelay(2); + status = info->zs_channel->control; + junk = sgint->istat0; + /* Clear status condition... */ + udelay(2); + info->zs_channel->control = RES_EXT_INT; + junk = sgint->istat0; + /* Clear the interrupt */ + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + +#if 0 + if(status & DCD) { + if((info->tty->termios->c_cflag & CRTSCTS) && + ((info->curregs[3] & AUTO_ENAB)==0)) { + info->curregs[3] |= AUTO_ENAB; + write_zsreg(info->zs_channel, 3, info->curregs[3]); + } + } else { + if((info->curregs[3] & AUTO_ENAB)) { + info->curregs[3] &= ~AUTO_ENAB; + write_zsreg(info->zs_channel, 3, info->curregs[3]); + } + } +#endif + /* Whee, if this is console input and this is a + * 'break asserted' status change interrupt, call + * the boot prom. + */ + if((status & BRK_ABRT) && info->break_abort) + batten_down_hatches(); + + /* XXX Whee, put in a buffer somewhere, the status information + * XXX whee whee whee... Where does the information go... + */ + return; +} + +/* + * This is the serial driver's generic interrupt routine + */ +void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + struct sgi_serial * info = (struct sgi_serial *) dev_id; + unsigned char zs_intreg; + + zs_intreg = read_zsreg(info->zs_next->zs_channel, 3); + + /* NOTE: The read register 3, which holds the irq status, + * does so for both channels on each chip. Although + * the status value itself must be read from the A + * channel and is only valid when read from channel A. + * Yes... broken hardware... + */ +#define CHAN_A_IRQMASK (CHARxIP | CHATxIP | CHAEXT) +#define CHAN_B_IRQMASK (CHBRxIP | CHBTxIP | CHBEXT) + + /* *** Chip 1 *** */ + /* Channel B -- /dev/ttyb, could be the console */ + if(zs_intreg & CHAN_B_IRQMASK) { + if (zs_intreg & CHBRxIP) + receive_chars(info, regs); + if (zs_intreg & CHBTxIP) + transmit_chars(info); + if (zs_intreg & CHBEXT) + status_handle(info); + } + + info=info->zs_next; + + /* Channel A -- /dev/ttya, could be the console */ + if(zs_intreg & CHAN_A_IRQMASK) { + if (zs_intreg & CHARxIP) + receive_chars(info, regs); + if (zs_intreg & CHATxIP) + transmit_chars(info); + if (zs_intreg & CHAEXT) + status_handle(info); + } +} + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_serial); +} + +static void do_softint(void *private_) +{ + struct sgi_serial *info = (struct sgi_serial *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); + } +} + +/* + * This routine is called from the scheduler tqueue when the interrupt + * routine has signalled that a hangup has occurred. The path of + * hangup processing is: + * + * serial interrupt routine -> (scheduler tqueue) -> + * do_serial_hangup() -> tty->hangup() -> rs_hangup() + * + */ +static void do_serial_hangup(void *private_) +{ + struct sgi_serial *info = (struct sgi_serial *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + tty_hangup(tty); +} + + +static int startup(struct sgi_serial * info) +{ + volatile unsigned char junk; + unsigned long flags; + + if (info->flags & ZILOG_INITIALIZED) + return 0; + + if (!info->xmit_buf) { + info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL); + if (!info->xmit_buf) + return -ENOMEM; + } + + save_flags(flags); cli(); + +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttys%d (irq %d)...\n", info->line, info->irq); +#endif + + /* + * Clear the FIFO buffers and disable them + * (they will be reenabled in change_speed()) + */ + ZS_CLEARFIFO(info->zs_channel); + info->xmit_fifo_size = 1; + + /* + * Clear the interrupt registers. + */ + udelay(2); + info->zs_channel->control = ERR_RES; + junk = sgint->istat0; + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + + /* + * Now, initialize the Zilog + */ + zs_rtsdtr(info, 1); + + /* + * Finally, enable sequencing and interrupts + */ + info->curregs[1] |= (info->curregs[1] & ~0x18) | (EXT_INT_ENAB|INT_ALL_Rx); + info->curregs[3] |= (RxENABLE | Rx8); + /* We enable Tx interrupts as needed. */ + info->curregs[5] |= (TxENAB | Tx8); + info->curregs[9] |= (NV | MIE); + write_zsreg(info->zs_channel, 3, info->curregs[3]); + write_zsreg(info->zs_channel, 5, info->curregs[5]); + write_zsreg(info->zs_channel, 9, info->curregs[9]); + + /* + * And clear the interrupt registers again for luck. + */ + udelay(2); + info->zs_channel->control = ERR_RES; + junk = sgint->istat0; + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + /* + * and set the speed of the serial port + */ + change_speed(info); + + info->flags |= ZILOG_INITIALIZED; + restore_flags(flags); + return 0; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct sgi_serial * info) +{ + unsigned long flags; + + if (!(info->flags & ZILOG_INITIALIZED)) + return; + +#ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d (irq %d)....", info->line, + info->irq); +#endif + + save_flags(flags); cli(); /* Disable interrupts */ + + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = 0; + } + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ZILOG_INITIALIZED; + restore_flags(flags); +} + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct sgi_serial *info) +{ + unsigned int port, cflag; + int i; + int brg; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + if (!(port = info->port)) + return; + i = cflag & CBAUD; + if (i & CBAUDEX) { + /* XXX CBAUDEX is not obeyed. + * It is impossible at a 32bits SPARC. + * But we have to report this to user ... someday. + */ + i = B9600; + } + if (i == 0) { + /* XXX B0, hangup the line. */ + do_serial_hangup(info); + } else if (baud_table[i]) { + info->zs_baud = baud_table[i]; + info->clk_divisor = 16; + + info->curregs[4] = X16CLK; + info->curregs[11] = TCBR | RCBR; + brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor); + info->curregs[12] = (brg & 255); + info->curregs[13] = ((brg >> 8) & 255); + info->curregs[14] = BRENABL; + } + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS5: + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx5; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx5; + break; + case CS6: + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx6; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx6; + break; + case CS7: + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx7; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx7; + break; + case CS8: + default: /* defaults to 8 bits */ + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx8; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx8; + break; + } + info->curregs[4] &= ~(0x0c); + if (cflag & CSTOPB) + info->curregs[4] |= SB2; + else + info->curregs[4] |= SB1; + + if (cflag & PARENB) + info->curregs[4] |= PAR_ENA; + else + info->curregs[4] &= ~PAR_ENA; + + if (!(cflag & PARODD)) + info->curregs[4] |= PAR_EVEN; + else + info->curregs[4] &= ~PAR_EVEN; + + /* Load up the new values */ + load_zsregs(info->zs_channel, info->curregs); + + return; +} + +/* This is for console output over ttya/ttyb */ +static void zs_cons_put_char(char ch) +{ + struct sgi_zschannel *chan = zs_conschan; + volatile unsigned char junk; + unsigned long flags; + int loops = 0; + + save_flags(flags); cli(); + while(((junk = chan->control) & Tx_BUF_EMP)==0 && loops < 10000) { + loops++; + udelay(2); + } + + udelay(2); + chan->data = ch; + junk = sgint->istat0; + restore_flags(flags); +} + +/* + * This is the more generic put_char function for the driver. + * In earlier versions of this driver, "rs_put_char" was the + * name of the console-specific fucntion, now called zs_cons_put_char + */ + +static void rs_put_char(struct tty_struct *tty, char ch) +{ + struct sgi_zschannel *chan = + ((struct sgi_serial *)tty->driver_data)->zs_channel; + volatile unsigned char junk; + unsigned long flags; + int loops = 0; + + save_flags(flags); cli(); + while(((junk = chan->control) & Tx_BUF_EMP)==0 && loops < 10000) { + loops++; + udelay(2); + } + + udelay(2); + chan->data = ch; + junk = sgint->istat0; + restore_flags(flags); +} + +/* These are for receiving and sending characters under the kgdb + * source level kernel debugger. + */ +int putDebugChar(char kgdb_char) +{ + struct sgi_zschannel *chan = zs_kgdbchan; + volatile unsigned char junk; + unsigned long flags; + + save_flags(flags); cli(); + udelay(2); + while((chan->control & Tx_BUF_EMP)==0) + udelay(2); + + udelay(2); + chan->data = kgdb_char; + junk = sgint->istat0; + restore_flags(flags); + + return 1; +} + +char getDebugChar(void) +{ + struct sgi_zschannel *chan = zs_kgdbchan; + unsigned char junk; + + while((chan->control & Rx_CH_AV)==0) + udelay(2); + + junk = sgint->istat0; + udelay(2); + return chan->data; +} + +/* + * Fair output driver allows a process to speak. + */ +static void rs_fair_output(void) +{ + int left; /* Output no more than that */ + unsigned long flags; + struct sgi_serial *info = zs_consinfo; + volatile unsigned char junk; + char c; + + if (info == 0) return; + if (info->xmit_buf == 0) return; + + save_flags(flags); cli(); + left = info->xmit_cnt; + while (left != 0) { + c = info->xmit_buf[info->xmit_tail]; + info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + restore_flags(flags); + + zs_cons_put_char(c); + + save_flags(flags); cli(); + left = min(info->xmit_cnt, left-1); + } + + /* Last character is being transmitted now (hopefully). */ + udelay(2); + zs_conschan->control = RES_Tx_P; + junk = sgint->istat0; + + restore_flags(flags); + return; +} + + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, total = 0; + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_write")) + return 0; + + if (!tty || !info->xmit_buf) + return 0; + + save_flags(flags); + while (1) { + cli(); + c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + + if (from_user) { + down(&tmp_buf_sem); + copy_from_user(tmp_buf, buf, c); + c = min(c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + up(&tmp_buf_sem); + } else + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + total += c; + } + + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { + /* + * The above test used to include the condition + * "&& !(info->curregs[5] & TxENAB)", but there + * is reason to suspect that it is never statisfied + * when the port is running. The problem may in fact + * have been masked by the fact that, if O_POST is set, + * there is always a rs_flush_xx operation following the + * rs_write, and the flush ignores that condition when + * it kicks off the transmit. + */ + /* Enable transmitter */ + info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB; + write_zsreg(info->zs_channel, 1, info->curregs[1]); + info->curregs[5] |= TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + + /* + * The following code is imported from the 2.3.6 Sun sbus zs.c + * driver, of which an earlier version served as the basis + * for sgiserial.c. Perhaps due to changes over time in + * the line discipline code, ns_write()s with from_user + * set would not otherwise actually kick-off output in + * Linux 2.2.x or later. Maybe it never really worked. + */ + + rs_put_char(tty, info->xmit_buf[info->xmit_tail++]); + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + } + + restore_flags(flags); + return total; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + int ret; + + if (serial_paranoia_check(info, tty->device, "rs_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) + return 0; + return info->xmit_cnt; +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) + return; + cli(); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + sti(); + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !info->xmit_buf) + return; + + /* Enable transmitter */ + save_flags(flags); cli(); + info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB; + write_zsreg(info->zs_channel, 1, info->curregs[1]); + info->curregs[5] |= TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + + /* + * Send a first (bootstrapping) character. A best solution is + * to call transmit_chars() here which handles output in a + * generic way. Current transmit_chars() not only transmits, + * but resets interrupts also what we do not desire here. + * XXX Discuss with David. + */ + if (info->zs_channel->control & Tx_BUF_EMP) { + volatile unsigned char junk; + + /* Send char */ + udelay(2); + info->zs_channel->data = info->xmit_buf[info->xmit_tail++]; + junk = sgint->istat0; + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + } + restore_flags(flags); +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", _tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_throttle")) + return; + + if (I_IXOFF(tty)) + info->x_char = STOP_CHAR(tty); + + /* Turn off RTS line */ + cli(); + info->curregs[5] &= ~RTS; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("unthrottle %s: %d....\n", _tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + info->x_char = START_CHAR(tty); + } + + /* Assert RTS line */ + cli(); + info->curregs[5] |= RTS; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct sgi_serial * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = info->type; + tmp.line = info->line; + tmp.port = info->port; + tmp.irq = info->irq; + tmp.flags = info->flags; + tmp.baud_base = info->baud_base; + tmp.close_delay = info->close_delay; + tmp.closing_wait = info->closing_wait; + tmp.custom_divisor = info->custom_divisor; + return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0; +} + +static int set_serial_info(struct sgi_serial * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct sgi_serial old_info; + int retval = 0; + + if (!new_info) + return -EFAULT; + copy_from_user(&new_serial,new_info,sizeof(new_serial)); + old_info = *info; + + if (!capable(CAP_SYS_ADMIN)) { + if ((new_serial.baud_base != info->baud_base) || + (new_serial.type != info->type) || + (new_serial.close_delay != info->close_delay) || + ((new_serial.flags & ~ZILOG_USR_MASK) != + (info->flags & ~ZILOG_USR_MASK))) + return -EPERM; + info->flags = ((info->flags & ~ZILOG_USR_MASK) | + (new_serial.flags & ZILOG_USR_MASK)); + info->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + if (info->count > 1) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + info->baud_base = new_serial.baud_base; + info->flags = ((info->flags & ~ZILOG_FLAGS) | + (new_serial.flags & ZILOG_FLAGS)); + info->type = new_serial.type; + info->close_delay = new_serial.close_delay; + info->closing_wait = new_serial.closing_wait; + +check_and_exit: + retval = startup(info); + return retval; +} + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct sgi_serial * info, unsigned int *value) +{ + volatile unsigned char junk; + unsigned char status; + + cli(); + udelay(2); + status = info->zs_channel->control; + junk = sgint->istat0; + sti(); + return put_user(status,value); +} + +static int get_modem_info(struct sgi_serial * info, unsigned int *value) +{ + unsigned char status; + unsigned int result; + + cli(); + status = info->zs_channel->control; + udelay(2); + sti(); + result = ((info->curregs[5] & RTS) ? TIOCM_RTS : 0) + | ((info->curregs[5] & DTR) ? TIOCM_DTR : 0) + | ((status & DCD) ? TIOCM_CAR : 0) + | ((status & SYNC) ? TIOCM_DSR : 0) + | ((status & CTS) ? TIOCM_CTS : 0); + if (put_user(result, value)) + return -EFAULT; + return 0; +} + +static int set_modem_info(struct sgi_serial * info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg; + + if (get_user(arg, value)) + return -EFAULT; + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) + info->curregs[5] |= RTS; + if (arg & TIOCM_DTR) + info->curregs[5] |= DTR; + break; + case TIOCMBIC: + if (arg & TIOCM_RTS) + info->curregs[5] &= ~RTS; + if (arg & TIOCM_DTR) + info->curregs[5] &= ~DTR; + break; + case TIOCMSET: + info->curregs[5] = ((info->curregs[5] & ~(RTS | DTR)) + | ((arg & TIOCM_RTS) ? RTS : 0) + | ((arg & TIOCM_DTR) ? DTR : 0)); + break; + default: + return -EINVAL; + } + cli(); + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); + return 0; +} + +/* + * This routine sends a break character out the serial port. + */ +static void send_break( struct sgi_serial * info, int duration) +{ + if (!info->port) + return; + current->state = TASK_INTERRUPTIBLE; + cli(); + write_zsreg(info->zs_channel, 5, (info->curregs[5] | SND_BRK)); + schedule_timeout(duration); + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); +} + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + struct sgi_serial * info = (struct sgi_serial *) tty->driver_data; + int retval; + + if (serial_paranoia_check(info, tty->device, "zs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && + (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TCSBRK: /* SVID version: non-zero arg --> no break */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + if (!arg) + send_break(info, HZ/4); /* 1/4 second */ + return 0; + case TCSBRKP: /* support for POSIX tcsendbreak() */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + send_break(info, arg ? arg*(HZ/10) : HZ/4); + return 0; + case TIOCGSOFTCAR: + if (put_user(C_CLOCAL(tty) ? 1 : 0, + (unsigned long *) arg)) + return -EFAULT; + return 0; + case TIOCSSOFTCAR: + if (get_user(arg, (unsigned long *) arg)) + return -EFAULT; + tty->termios->c_cflag = + ((tty->termios->c_cflag & ~CLOCAL) | + (arg ? CLOCAL : 0)); + return 0; + case TIOCMGET: + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + if (copy_to_user((struct sgi_serial *) arg, + info, sizeof(struct sgi_serial))) + return -EFAULT; + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + + if (tty->termios->c_cflag == old_termios->c_cflag) + return; + + change_speed(info); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * ZILOG structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct sgi_serial * info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->device, "rs_close")) + return; + + save_flags(flags); cli(); + + if (tty_hung_up_p(filp)) { + restore_flags(flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_close ttys%d, count = %d\n", info->line, info->count); +#endif + if ((tty->count == 1) && (info->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. Info->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("rs_close: bad serial port count; tty->count is 1, " + "info->count is %d\n", info->count); + info->count = 1; + } + if (--info->count < 0) { + printk("rs_close: bad serial port count for ttys%d: %d\n", + info->line, info->count); + info->count = 0; + } + if (info->count) { + restore_flags(flags); + return; + } + info->flags |= ZILOG_CLOSING; + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ZILOG_NORMAL_ACTIVE) + info->normal_termios = *tty->termios; + if (info->flags & ZILOG_CALLOUT_ACTIVE) + info->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + /** if (!info->iscons) ... **/ + info->curregs[3] &= ~RxENABLE; + write_zsreg(info->zs_channel, 3, info->curregs[3]); + info->curregs[1] &= ~(0x18); + write_zsreg(info->zs_channel, 1, info->curregs[1]); + ZS_CLEARFIFO(info->zs_channel); + + shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = 0; + if (tty->ldisc.num != ldiscs[N_TTY].num) { + if (tty->ldisc.close) + (tty->ldisc.close)(tty); + tty->ldisc = ldiscs[N_TTY]; + tty->termios->c_line = N_TTY; + if (tty->ldisc.open) + (tty->ldisc.open)(tty); + } + if (info->blocked_open) { + if (info->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE| + ZILOG_CLOSING); + wake_up_interruptible(&info->close_wait); + restore_flags(flags); +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +void rs_hangup(struct tty_struct *tty) +{ + struct sgi_serial * info = (struct sgi_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_hangup")) + return; + + rs_flush_buffer(tty); + shutdown(info); + info->event = 0; + info->count = 0; + info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct sgi_serial *info) +{ + DECLARE_WAITQUEUE(wait, current); + int retval; + int do_clocal = 0; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (info->flags & ZILOG_CLOSING) { + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + if (info->flags & ZILOG_HUP_NOTIFY) + return -EAGAIN; + else + return -ERESTARTSYS; +#else + return -EAGAIN; +#endif + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ZILOG_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ZILOG_CALLOUT_ACTIVE) && + (info->flags & ZILOG_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ZILOG_CALLOUT_ACTIVE) && + (info->flags & ZILOG_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ZILOG_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ZILOG_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ZILOG_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ZILOG_CALLOUT_ACTIVE) { + if (info->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttys%d, count = %d\n", + info->line, info->count); +#endif + info->count--; + info->blocked_open++; + while (1) { + cli(); + if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) + zs_rtsdtr(info, 1); + sti(); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ZILOG_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ZILOG_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ZILOG_CALLOUT_ACTIVE) && + !(info->flags & ZILOG_CLOSING) && do_clocal) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, info->count); +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (!tty_hung_up_p(filp)) + info->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, info->count); +#endif + if (retval) + return retval; + info->flags |= ZILOG_NORMAL_ACTIVE; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its ZILOG structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct sgi_serial *info; + int retval, line; + + line = MINOR(tty->device) - tty->driver.minor_start; + /* The zilog lines for the mouse/keyboard must be + * opened using their respective drivers. + */ + if ((line < 0) || (line >= NUM_CHANNELS)) + return -ENODEV; + info = zs_soft + line; + /* Is the kgdb running over this line? */ + if (info->kgdb_channel) + return -ENODEV; + if (serial_paranoia_check(info, tty->device, "rs_open")) + return -ENODEV; +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, + info->count); +#endif + info->count++; + tty->driver_data = info; + info->tty = tty; + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) + return retval; + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open returning after block_til_ready with %d\n", + retval); +#endif + return retval; + } + + if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->normal_termios; + else + *tty->termios = info->callout_termios; + change_speed(info); + } + + /* If this is the serial console change the speed to + * the right value + */ + if (info->is_cons) { + info->tty->termios->c_cflag = sgisercon->cflag; + change_speed(info); + } + + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open ttys%d successful...\n", info->line); +#endif + return 0; +} + +/* Finally, routines used to initialize the serial driver. */ + +static void show_serial_version(void) +{ + printk("SGI Zilog8530 serial driver version 1.00\n"); +} + +/* Return layout for the requested zs chip number. */ +static inline struct sgi_zslayout *get_zs(int chip) +{ + if (chip > 0) + panic("Wheee, bogus zs chip number requested."); + + return (struct sgi_zslayout *) (&sgioc->serport); +} + + +static inline void +rs_cons_check(struct sgi_serial *ss, int channel) +{ + int i, o, io; + static int msg_printed = 0; + + i = o = io = 0; + + /* Is this one of the serial console lines? */ + if((zs_cons_chanout != channel) && + (zs_cons_chanin != channel)) + return; + zs_conschan = ss->zs_channel; + zs_consinfo = ss; + + + + /* If this is console input, we handle the break received + * status interrupt on this line to mean prom_halt(). + */ + if(zs_cons_chanin == channel) { + ss->break_abort = 1; + i = 1; + } + if(o && i) + io = 1; + + /* Set flag variable for this port so that it cannot be + * opened for other uses by accident. + */ + ss->is_cons = 1; + + if(io) { + if (!msg_printed) { + printk("zs%d: console I/O\n", ((channel>>1)&1)); + msg_printed = 1; + } + + } else { + printk("zs%d: console %s\n", ((channel>>1)&1), + (i==1 ? "input" : (o==1 ? "output" : "WEIRD"))); + } +} + +/* rs_init inits the driver */ +int rs_init(void) +{ + unsigned long flags; + int chip, channel, i; + struct sgi_serial *info; + + + /* Setup base handler, and timer table. */ + init_bh(SERIAL_BH, do_serial_bh); + + show_serial_version(); + + /* Initialize the tty_driver structure */ + /* SGI: Not all of this is exactly right for us. */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; +#ifdef CONFIG_DEVFS_FS + serial_driver.name = "tts/%d"; +#else + serial_driver.name = "ttyS"; +#endif + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64; + serial_driver.num = NUM_CHANNELS; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; +#ifdef CONFIG_DEVFS_FS + callout_driver.name = "cua/%d"; +#else + callout_driver.name = "cua"; +#endif + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register serial driver"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver"); + + save_flags(flags); cli(); + + /* Set up our interrupt linked list */ + zs_chain = &zs_soft[0]; + zs_soft[0].zs_next = &zs_soft[1]; + zs_soft[1].zs_next = 0; + + for(chip = 0; chip < NUM_SERIAL; chip++) { + /* If we are doing kgdb over one of the channels on + * chip zero, kgdb_channel will be set to 1 by the + * rs_kgdb_hook() routine below. + */ + if(!zs_chips[chip]) { + zs_chips[chip] = get_zs(chip); + /* Two channels per chip */ + zs_channels[(chip*2)] = &zs_chips[chip]->channelB; + zs_channels[(chip*2)+1] = &zs_chips[chip]->channelA; + zs_soft[(chip*2)].kgdb_channel = 0; + zs_soft[(chip*2)+1].kgdb_channel = 0; + } + /* First, set up channel A on this chip. */ + channel = chip * 2; + zs_soft[channel].zs_channel = zs_channels[channel]; + zs_soft[channel].change_needed = 0; + zs_soft[channel].clk_divisor = 16; + zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); + zs_soft[channel].cons_mouse = 0; + /* If not keyboard/mouse and is console serial + * line, then enable receiver interrupts. + */ + if(zs_soft[channel].is_cons) { + write_zsreg(zs_soft[channel].zs_channel, R1, + (EXT_INT_ENAB | INT_ALL_Rx)); + write_zsreg(zs_soft[channel].zs_channel, R9, (NV | MIE)); + write_zsreg(zs_soft[channel].zs_channel, R10, (NRZ)); + write_zsreg(zs_soft[channel].zs_channel, R3, (Rx8|RxENABLE)); + write_zsreg(zs_soft[channel].zs_channel, R5, (Tx8 | TxENAB)); + } + /* If this is the kgdb line, enable interrupts because we + * now want to receive the 'control-c' character from the + * client attached to us asynchronously. + */ + if(zs_soft[channel].kgdb_channel) + kgdb_chaninit(&zs_soft[channel], 1, + zs_soft[channel].zs_baud); + + /* Now, channel B */ + channel++; + zs_soft[channel].zs_channel = zs_channels[channel]; + zs_soft[channel].change_needed = 0; + zs_soft[channel].clk_divisor = 16; + zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); + zs_soft[channel].cons_keyb = 0; + /* If console serial line, then enable receiver interrupts. */ + if(zs_soft[channel].is_cons) { + write_zsreg(zs_soft[channel].zs_channel, R1, + (EXT_INT_ENAB | INT_ALL_Rx)); + write_zsreg(zs_soft[channel].zs_channel, R9, + (NV | MIE)); + write_zsreg(zs_soft[channel].zs_channel, R10, + (NRZ)); + write_zsreg(zs_soft[channel].zs_channel, R3, + (Rx8|RxENABLE)); + write_zsreg(zs_soft[channel].zs_channel, R5, + (Tx8 | TxENAB | RTS | DTR)); + } + } + + for(info=zs_chain, i=0; info; info = info->zs_next, i++) + { + info->magic = SERIAL_MAGIC; + info->port = (int) info->zs_channel; + info->line = i; + info->tty = 0; + info->irq = zilog_irq; + info->custom_divisor = 16; + info->close_delay = 50; + info->closing_wait = 3000; + info->x_char = 0; + info->event = 0; + info->count = 0; + info->blocked_open = 0; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->tqueue_hangup.routine = do_serial_hangup; + info->tqueue_hangup.data = info; + info->callout_termios =callout_driver.init_termios; + info->normal_termios = serial_driver.init_termios; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + printk("tty%02d at 0x%04x (irq = %d)", info->line, + info->port, info->irq); + printk(" is a Zilog8530\n"); + } + + if (request_irq(zilog_irq, rs_interrupt, (SA_INTERRUPT), + "Zilog8530", zs_chain)) + panic("Unable to attach zs intr"); + restore_flags(flags); + + return 0; +} + +/* + * register_serial and unregister_serial allows for serial ports to be + * configured at run-time, to support PCMCIA modems. + */ +/* SGI: Unused at this time, just here to make things link. */ +int register_serial(struct serial_struct *req) +{ + return -1; +} + +void unregister_serial(int line) +{ + return; +} + +/* Hooks for running a serial console. con_init() calls this if the + * console is being run over one of the ttya/ttyb serial ports. + * 'chip' should be zero, as chip 1 drives the mouse/keyboard. + * 'channel' is decoded as 0=TTYA 1=TTYB, note that the channels + * are addressed backwards, channel B is first, then channel A. + */ +void +rs_cons_hook(int chip, int out, int line) +{ + int channel; + + if(chip) + panic("rs_cons_hook called with chip not zero"); + if(line != 0 && line != 1) + panic("rs_cons_hook called with line not ttya or ttyb"); + channel = line; + if(!zs_chips[chip]) { + zs_chips[chip] = get_zs(chip); + /* Two channels per chip */ + zs_channels[(chip*2)] = &zs_chips[chip]->channelB; + zs_channels[(chip*2)+1] = &zs_chips[chip]->channelA; + } + zs_soft[channel].zs_channel = zs_channels[channel]; + zs_soft[channel].change_needed = 0; + zs_soft[channel].clk_divisor = 16; + zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); + if(out) + zs_cons_chanout = ((chip * 2) + channel); + else + zs_cons_chanin = ((chip * 2) + channel); + + rs_cons_check(&zs_soft[channel], channel); +} + +/* This is called at boot time to prime the kgdb serial debugging + * serial line. The 'tty_num' argument is 0 for /dev/ttyd2 and 1 for + * /dev/ttyd1 (yes they are backwards on purpose) which is determined + * in setup_arch() from the boot command line flags. + */ +void +rs_kgdb_hook(int tty_num) +{ + int chip = 0; + + if(!zs_chips[chip]) { + zs_chips[chip] = get_zs(chip); + /* Two channels per chip */ + zs_channels[(chip*2)] = &zs_chips[chip]->channelA; + zs_channels[(chip*2)+1] = &zs_chips[chip]->channelB; + } + zs_soft[tty_num].zs_channel = zs_channels[tty_num]; + zs_kgdbchan = zs_soft[tty_num].zs_channel; + zs_soft[tty_num].change_needed = 0; + zs_soft[tty_num].clk_divisor = 16; + zs_soft[tty_num].zs_baud = get_zsbaud(&zs_soft[tty_num]); + zs_soft[tty_num].kgdb_channel = 1; /* This runs kgdb */ + zs_soft[tty_num ^ 1].kgdb_channel = 0; /* This does not */ + + /* Turn on transmitter/receiver at 8-bits/char */ + kgdb_chaninit(&zs_soft[tty_num], 0, 9600); + ZS_CLEARERR(zs_kgdbchan); + udelay(5); + ZS_CLEARFIFO(zs_kgdbchan); +} + +static void zs_console_write(struct console *co, const char *str, + unsigned int count) +{ + + while(count--) { + if(*str == '\n') + zs_cons_put_char('\r'); + zs_cons_put_char(*str++); + } + + /* Comment this if you want to have a strict interrupt-driven output */ + rs_fair_output(); +} + +static kdev_t zs_console_device(struct console *con) +{ + return MKDEV(TTY_MAJOR, 64 + con->index); +} + + +static int __init zs_console_setup(struct console *con, char *options) +{ + struct sgi_serial *info; + int baud; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + char *s, *dbaud; + int i, brg; + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } + else { + /* If the user doesn't set console=... try to read the + * PROM variable - if this fails use 9600 baud and + * inform the user about the problem + */ + dbaud = ArcGetEnvironmentVariable("dbaud"); + if(dbaud) baud = simple_strtoul(dbaud, NULL, 10); + else { + /* Use prom_printf() to make sure that the user + * is getting anything ... + */ + prom_printf("No dbaud set in PROM ?!? Using 9600.\n"); + baud = 9600; + } + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + con->cflag = cflag; + + rs_cons_hook(0, 0, con->index); + info = zs_soft + con->index; + info->is_cons = 1; + + printk("Console: ttyS%d (Zilog8530), %d baud\n", + info->line, baud); + + i = con->cflag & CBAUD; + if (con->cflag & CBAUDEX) { + i &= ~CBAUDEX; + con->cflag &= ~CBAUDEX; + } + info->zs_baud = baud; + + switch (con->cflag & CSIZE) { + case CS5: + zscons_regs[3] = Rx5 | RxENABLE; + zscons_regs[5] = Tx5 | TxENAB; + break; + case CS6: + zscons_regs[3] = Rx6 | RxENABLE; + zscons_regs[5] = Tx6 | TxENAB; + break; + case CS7: + zscons_regs[3] = Rx7 | RxENABLE; + zscons_regs[5] = Tx7 | TxENAB; + break; + default: + case CS8: + zscons_regs[3] = Rx8 | RxENABLE; + zscons_regs[5] = Tx8 | TxENAB; + break; + } + zscons_regs[5] |= DTR; + + if (con->cflag & PARENB) + zscons_regs[4] |= PAR_ENA; + if (!(con->cflag & PARODD)) + zscons_regs[4] |= PAR_EVEN; + + if (con->cflag & CSTOPB) + zscons_regs[4] |= SB2; + else + zscons_regs[4] |= SB1; + + sgisercon = con; + + brg = BPS_TO_BRG(baud, ZS_CLOCK / info->clk_divisor); + zscons_regs[12] = brg & 0xff; + zscons_regs[13] = (brg >> 8) & 0xff; + memcpy(info->curregs, zscons_regs, sizeof(zscons_regs)); + load_zsregs(info->zs_channel, zscons_regs); + ZS_CLEARERR(info->zs_channel); + ZS_CLEARFIFO(info->zs_channel); + return 0; +} + +static struct console sgi_console_driver = { + .name = "ttyS", + .write = zs_console_write, + .device = zs_console_device, + .setup = zs_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ +void __init sgi_serial_console_init(void) +{ + register_console(&sgi_console_driver); +} +__initcall(rs_init); diff -urN linux-2.4.21/drivers/char/sgiserial.h linux-2.4.22/drivers/char/sgiserial.h --- linux-2.4.21/drivers/char/sgiserial.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/sgiserial.h 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,444 @@ +/* sgiserial.h: Definitions for the SGI Zilog85C30 serial driver. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#ifndef _SGI_SERIAL_H +#define _SGI_SERIAL_H + +/* Just one channel */ +struct sgi_zschannel { +#ifdef __MIPSEB__ + volatile unsigned char unused0[3]; + volatile unsigned char control; + volatile unsigned char unused1[3]; + volatile unsigned char data; +#else /* __MIPSEL__ */ + volatile unsigned char control; + volatile unsigned char unused0[3]; + volatile unsigned char data; + volatile unsigned char unused1[3]; +#endif +}; + +/* The address space layout for each zs chip. Yes they are + * backwards. + */ +struct sgi_zslayout { + struct sgi_zschannel channelB; + struct sgi_zschannel channelA; +}; + +#define NUM_ZSREGS 16 + +struct serial_struct { + int type; + int line; + unsigned int port; + int irq; + int flags; + int xmit_fifo_size; + int custom_divisor; + int baud_base; + unsigned short close_delay; + char reserved_char[2]; + int hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + int reserved[4]; +}; + +/* + * For the close wait times, 0 means wait forever for serial port to + * flush its output. 65535 means don't wait at all. + */ +#define ZILOG_CLOSING_WAIT_INF 0 +#define ZILOG_CLOSING_WAIT_NONE 65535 + +/* + * Definitions for ZILOG_struct (and serial_struct) flags field + */ +#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes + on the callout port */ +#define ZILOG_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */ +#define ZILOG_SAK 0x0004 /* Secure Attention Key (Orange book) */ +#define ZILOG_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ + +#define ZILOG_SPD_MASK 0x0030 +#define ZILOG_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ + +#define ZILOG_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ +#define ZILOG_SPD_CUST 0x0030 /* Use user-specified divisor */ + +#define ZILOG_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */ +#define ZILOG_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */ +#define ZILOG_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ +#define ZILOG_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ +#define ZILOG_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ + +#define ZILOG_FLAGS 0x0FFF /* Possible legal ZILOG flags */ +#define ZILOG_USR_MASK 0x0430 /* Legal flags that non-privileged + * users can set or reset */ + +/* Internal flags used only by kernel/chr_drv/serial.c */ +#define ZILOG_INITIALIZED 0x80000000 /* Serial port was initialized */ +#define ZILOG_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ +#define ZILOG_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ +#define ZILOG_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ +#define ZILOG_CLOSING 0x08000000 /* Serial port is closing */ +#define ZILOG_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define ZILOG_CHECK_CD 0x02000000 /* i.e., CLOCAL */ + +/* Software state per channel */ + +#ifdef __KERNEL__ +/* + * This is our internal structure for each serial port's state. + * + * Many fields are paralleled by the structure used by the serial_struct + * structure. + * + * For definitions of the flags field, see tty.h + */ + +struct sgi_serial { + struct sgi_serial *zs_next; /* For IRQ servicing chain */ + struct sgi_zschannel *zs_channel; /* Channel registers */ + unsigned char read_reg_zero; + + char soft_carrier; /* Use soft carrier on this channel */ + char cons_keyb; /* Channel runs the keyboard */ + char cons_mouse; /* Channel runs the mouse */ + char break_abort; /* Is serial console in, so process brk/abrt */ + char kgdb_channel; /* Kgdb is running on this channel */ + char is_cons; /* Is this our console. */ + + /* We need to know the current clock divisor + * to read the bps rate the chip has currently + * loaded. + */ + unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */ + int zs_baud; + + /* Current write register values */ + unsigned char curregs[NUM_ZSREGS]; + + char change_needed; + + int magic; + int baud_base; + unsigned int port; + int irq; + int flags; /* defined in tty.h */ + int type; /* UART type */ + struct tty_struct *tty; + int read_status_mask; + int ignore_status_mask; + int timeout; + int xmit_fifo_size; + int custom_divisor; + int x_char; /* xon/xoff character */ + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + unsigned long event; + unsigned long last_active; + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + struct tq_struct tqueue; + struct tq_struct tqueue_hangup; + struct termios normal_termios; + struct termios callout_termios; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; +}; + + +#define SERIAL_MAGIC 0x5301 + +/* + * The size of the serial xmit buffer is 1 page. + */ +#define SERIAL_XMIT_SIZE PAGE_SIZE + +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at rs interrupt time. + */ +#define RS_EVENT_WRITE_WAKEUP 0 + +#endif /* __KERNEL__ */ + +/* Conversion routines to/from brg time constants from/to bits + * per second. + */ +#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) +#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) + +/* The Zilog register set */ + +#define FLAG 0x7e + +/* Write Register 0 */ +#define R0 0 /* Register selects */ +#define R1 1 +#define R2 2 +#define R3 3 +#define R4 4 +#define R5 5 +#define R6 6 +#define R7 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 + +#define NULLCODE 0 /* Null Code */ +#define POINT_HIGH 0x8 /* Select upper half of registers */ +#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */ +#define SEND_ABORT 0x18 /* HDLC Abort */ +#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */ +#define RES_Tx_P 0x28 /* Reset TxINT Pending */ +#define ERR_RES 0x30 /* Error Reset */ +#define RES_H_IUS 0x38 /* Reset highest IUS */ + +#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */ +#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */ +#define RES_EOM_L 0xC0 /* Reset EOM latch */ + +/* Write Register 1 */ + +#define EXT_INT_ENAB 0x1 /* Ext Int Enable */ +#define TxINT_ENAB 0x2 /* Tx Int Enable */ +#define PAR_SPEC 0x4 /* Parity is special condition */ + +#define RxINT_DISAB 0 /* Rx Int Disable */ +#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ +#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ +#define INT_ERR_Rx 0x18 /* Int on error only */ + +#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */ +#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */ +#define WT_RDY_ENAB 0x80 /* Wait/Ready Enable */ + +/* Write Register #2 (Interrupt Vector) */ + +/* Write Register 3 */ + +#define RxENABLE 0x1 /* Rx Enable */ +#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ +#define ADD_SM 0x4 /* Address Search Mode (SDLC) */ +#define RxCRC_ENAB 0x8 /* Rx CRC Enable */ +#define ENT_HM 0x10 /* Enter Hunt Mode */ +#define AUTO_ENAB 0x20 /* Auto Enables */ +#define Rx5 0x0 /* Rx 5 Bits/Character */ +#define Rx7 0x40 /* Rx 7 Bits/Character */ +#define Rx6 0x80 /* Rx 6 Bits/Character */ +#define Rx8 0xc0 /* Rx 8 Bits/Character */ + +/* Write Register 4 */ + +#define PAR_ENA 0x1 /* Parity Enable */ +#define PAR_EVEN 0x2 /* Parity Even/Odd* */ + +#define SYNC_ENAB 0 /* Sync Modes Enable */ +#define SB1 0x4 /* 1 stop bit/char */ +#define SB15 0x8 /* 1.5 stop bits/char */ +#define SB2 0xc /* 2 stop bits/char */ + +#define MONSYNC 0 /* 8 Bit Sync character */ +#define BISYNC 0x10 /* 16 bit sync character */ +#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ +#define EXTSYNC 0x30 /* External Sync Mode */ + +#define X1CLK 0x0 /* x1 clock mode */ +#define X16CLK 0x40 /* x16 clock mode */ +#define X32CLK 0x80 /* x32 clock mode */ +#define X64CLK 0xC0 /* x64 clock mode */ + +/* Write Register 5 */ + +#define TxCRC_ENAB 0x1 /* Tx CRC Enable */ +#define RTS 0x2 /* RTS */ +#define SDLC_CRC 0x4 /* SDLC/CRC-16 */ +#define TxENAB 0x8 /* Tx Enable */ +#define SND_BRK 0x10 /* Send Break */ +#define Tx5 0x0 /* Tx 5 bits (or less)/character */ +#define Tx7 0x20 /* Tx 7 bits/character */ +#define Tx6 0x40 /* Tx 6 bits/character */ +#define Tx8 0x60 /* Tx 8 bits/character */ +#define DTR 0x80 /* DTR */ + +/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ + +/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ + +/* Write Register 8 (transmit buffer) */ + +/* Write Register 9 (Master interrupt control) */ +#define VIS 1 /* Vector Includes Status */ +#define NV 2 /* No Vector */ +#define DLC 4 /* Disable Lower Chain */ +#define MIE 8 /* Master Interrupt Enable */ +#define STATHI 0x10 /* Status high */ +#define NORESET 0 /* No reset on write to R9 */ +#define CHRB 0x40 /* Reset channel B */ +#define CHRA 0x80 /* Reset channel A */ +#define FHWRES 0xc0 /* Force hardware reset */ + +/* Write Register 10 (misc control bits) */ +#define BIT6 1 /* 6 bit/8bit sync */ +#define LOOPMODE 2 /* SDLC Loop mode */ +#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */ +#define MARKIDLE 8 /* Mark/flag on idle */ +#define GAOP 0x10 /* Go active on poll */ +#define NRZ 0 /* NRZ mode */ +#define NRZI 0x20 /* NRZI mode */ +#define FM1 0x40 /* FM1 (transition = 1) */ +#define FM0 0x60 /* FM0 (transition = 0) */ +#define CRCPS 0x80 /* CRC Preset I/O */ + +/* Write Register 11 (Clock Mode control) */ +#define TRxCXT 0 /* TRxC = Xtal output */ +#define TRxCTC 1 /* TRxC = Transmit clock */ +#define TRxCBR 2 /* TRxC = BR Generator Output */ +#define TRxCDP 3 /* TRxC = DPLL output */ +#define TRxCOI 4 /* TRxC O/I */ +#define TCRTxCP 0 /* Transmit clock = RTxC pin */ +#define TCTRxCP 8 /* Transmit clock = TRxC pin */ +#define TCBR 0x10 /* Transmit clock = BR Generator output */ +#define TCDPLL 0x18 /* Transmit clock = DPLL output */ +#define RCRTxCP 0 /* Receive clock = RTxC pin */ +#define RCTRxCP 0x20 /* Receive clock = TRxC pin */ +#define RCBR 0x40 /* Receive clock = BR Generator output */ +#define RCDPLL 0x60 /* Receive clock = DPLL output */ +#define RTxCX 0x80 /* RTxC Xtal/No Xtal */ + +/* Write Register 12 (lower byte of baud rate generator time constant) */ + +/* Write Register 13 (upper byte of baud rate generator time constant) */ + +/* Write Register 14 (Misc control bits) */ +#define BRENABL 1 /* Baud rate generator enable */ +#define BRSRC 2 /* Baud rate generator source */ +#define DTRREQ 4 /* DTR/Request function */ +#define AUTOECHO 8 /* Auto Echo */ +#define LOOPBAK 0x10 /* Local loopback */ +#define SEARCH 0x20 /* Enter search mode */ +#define RMC 0x40 /* Reset missing clock */ +#define DISDPLL 0x60 /* Disable DPLL */ +#define SSBR 0x80 /* Set DPLL source = BR generator */ +#define SSRTxC 0xa0 /* Set DPLL source = RTxC */ +#define SFMM 0xc0 /* Set FM mode */ +#define SNRZI 0xe0 /* Set NRZI mode */ + +/* Write Register 15 (external/status interrupt control) */ +#define ZCIE 2 /* Zero count IE */ +#define DCDIE 8 /* DCD IE */ +#define SYNCIE 0x10 /* Sync/hunt IE */ +#define CTSIE 0x20 /* CTS IE */ +#define TxUIE 0x40 /* Tx Underrun/EOM IE */ +#define BRKIE 0x80 /* Break/Abort IE */ + + +/* Read Register 0 */ +#define Rx_CH_AV 0x1 /* Rx Character Available */ +#define ZCOUNT 0x2 /* Zero count */ +#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ +#define DCD 0x8 /* DCD */ +#define SYNC 0x10 /* Sync/hunt */ +#define CTS 0x20 /* CTS */ +#define TxEOM 0x40 /* Tx underrun */ +#define BRK_ABRT 0x80 /* Break/Abort */ + +/* Read Register 1 */ +#define ALL_SNT 0x1 /* All sent */ +/* Residue Data for 8 Rx bits/char programmed */ +#define RES3 0x8 /* 0/3 */ +#define RES4 0x4 /* 0/4 */ +#define RES5 0xc /* 0/5 */ +#define RES6 0x2 /* 0/6 */ +#define RES7 0xa /* 0/7 */ +#define RES8 0x6 /* 0/8 */ +#define RES18 0xe /* 1/8 */ +#define RES28 0x0 /* 2/8 */ +/* Special Rx Condition Interrupts */ +#define PAR_ERR 0x10 /* Parity error */ +#define Rx_OVR 0x20 /* Rx Overrun Error */ +#define CRC_ERR 0x40 /* CRC/Framing Error */ +#define END_FR 0x80 /* End of Frame (SDLC) */ + +/* Read Register 2 (channel b only) - Interrupt vector */ + +/* Read Register 3 (interrupt pending register) ch a only */ +#define CHBEXT 0x1 /* Channel B Ext/Stat IP */ +#define CHBTxIP 0x2 /* Channel B Tx IP */ +#define CHBRxIP 0x4 /* Channel B Rx IP */ +#define CHAEXT 0x8 /* Channel A Ext/Stat IP */ +#define CHATxIP 0x10 /* Channel A Tx IP */ +#define CHARxIP 0x20 /* Channel A Rx IP */ + +/* Read Register 8 (receive data register) */ + +/* Read Register 10 (misc status bits) */ +#define ONLOOP 2 /* On loop */ +#define LOOPSEND 0x10 /* Loop sending */ +#define CLK2MIS 0x40 /* Two clocks missing */ +#define CLK1MIS 0x80 /* One clock missing */ + +/* Read Register 12 (lower byte of baud rate generator constant) */ + +/* Read Register 13 (upper byte of baud rate generator constant) */ + +/* Read Register 15 (value of WR 15) */ + +/* Misc inlines */ +static inline void ZS_CLEARERR(struct sgi_zschannel *channel) +{ + volatile unsigned char junk; + + udelay(2); + channel->control = ERR_RES; + junk = sgint->istat0; +} + +static inline void ZS_CLEARFIFO(struct sgi_zschannel *channel) +{ + volatile unsigned char junk; + + udelay(2); + junk = channel->data; + udelay(2); + junk = sgint->istat0; + junk = channel->data; + udelay(2); + junk = sgint->istat0; + junk = channel->data; + udelay(2); + junk = sgint->istat0; +} + +#if 0 + +#define ZS_CLEARERR(channel) (channel->control = ERR_RES) +#define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \ + garbage = channel->data; \ + udelay(2); \ + garbage = channel->data; \ + udelay(2); \ + garbage = channel->data; \ + udelay(2); } while(0) + +#endif + +#endif /* !(_SGI_SERIAL_H) */ diff -urN linux-2.4.21/drivers/char/sh-sci.c linux-2.4.22/drivers/char/sh-sci.c --- linux-2.4.21/drivers/char/sh-sci.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/sh-sci.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: sh-sci.c,v 1.40 2000/04/15 06:57:29 gniibe Exp $ +/* $Id: sh-sci.c,v 1.1.1.1.2.7 2003/07/16 18:45:31 yoshii Exp $ * * linux/drivers/char/sh-sci.c * @@ -6,6 +6,7 @@ * Copyright (C) 1999, 2000 Niibe Yutaka * Copyright (C) 2000 Sugioka Toshinobu * Modified to support multiple serial ports. Stuart Menefy (May 2000). + * Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003). * * TTY code is based on sx.c (Specialix SX driver) by: * @@ -32,7 +33,7 @@ #include #include #include -#ifdef CONFIG_SERIAL_CONSOLE +#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SH_KGDB_CONSOLE) #include #endif @@ -50,17 +51,39 @@ #include "sh-sci.h" +#ifdef CONFIG_SH_KGDB +#include + +int kgdb_sci_setup(void); +static int kgdb_get_char(struct sci_port *port); +static void kgdb_put_char(struct sci_port *port, char c); +static void kgdb_handle_error(struct sci_port *port); +static struct sci_port *kgdb_sci_port; + +#ifdef CONFIG_SH_KGDB_CONSOLE +static struct console kgdbcons; +void __init kgdb_console_init(void); +#endif /* CONFIG_SH_KGDB_CONSOLE */ + +#endif /* CONFIG_SH_KGDB */ + #ifdef CONFIG_SERIAL_CONSOLE static struct console sercons; static struct sci_port* sercons_port=0; static int sercons_baud; -#endif +#ifdef CONFIG_MAGIC_SYSRQ +#include +static int break_pressed; +#endif /* CONFIG_MAGIC_SYSRQ */ +#endif /* CONFIG_SERIAL_CONSOLE */ /* Function prototypes */ +#if !defined(SCIF_ONLY) static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag); +#endif #ifndef SCI_ONLY static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag); -#if defined(__sh3__) +#if defined(__sh3__) && !defined(CONFIG_CPU_SUBTYPE_SH7300) static void sci_init_pins_irda(struct sci_port* port, unsigned int cflag); #endif #endif @@ -114,7 +137,7 @@ } #endif -#ifdef CONFIG_SH_STANDARD_BIOS +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) static void handle_error(struct sci_port *port) { /* Clear error flags */ @@ -156,7 +179,7 @@ return hexchars[x & 0xf]; } -#endif +#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ /* * Send the packet in buffer. The host gets one chance to read it. @@ -168,13 +191,22 @@ { int i; const unsigned char *p = buffer; -#ifdef CONFIG_SH_STANDARD_BIOS + +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) int checksum; + int usegdb=0; +#ifdef CONFIG_SH_STANDARD_BIOS /* This call only does a trap the first time it is * called, and so is safe to do here unconditionally */ - if (sh_bios_in_gdb_mode()) { + usegdb |= sh_bios_in_gdb_mode(); +#endif +#ifdef CONFIG_SH_KGDB + usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port)); +#endif + + if (usegdb) { /* $#. */ do { unsigned char c; @@ -197,15 +229,101 @@ put_char(port, lowhex(checksum)); } while (get_char(port) != '+'); } else -#endif +#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ for (i=0; itype == PORT_SCIF) { +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST | SCFCR_TCRST); +#else sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); +#endif } smr_val = sci_in(port, SCSMR) & 3; @@ -381,7 +505,7 @@ if (cflag & PARENB) smr_val |= 0x20; if (cflag & PARODD) - smr_val |= 0x10; + smr_val |= 0x30; if (cflag & CSTOPB) smr_val |= 0x08; sci_out(port, SCSMR, smr_val); @@ -461,14 +585,18 @@ while (1) { count = port->gs.xmit_cnt; if (port->type == PORT_SCIF) { +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + txroom = 64 - (sci_in(port, SCFDR)>>8); +#else txroom = 16 - (sci_in(port, SCFDR)>>8); +#endif } else { txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0; } if (count > txroom) count = txroom; - /* Don't copy pas the end of the source buffer */ + /* Don't copy past the end of the source buffer */ if (count > SERIAL_XMIT_SIZE - port->gs.xmit_tail) count = SERIAL_XMIT_SIZE - port->gs.xmit_tail; @@ -511,7 +639,11 @@ restore_flags(flags); } -static inline void sci_receive_chars(struct sci_port *port) +/* On SH3, SCIF may read end-of-break as a space->mark char */ +#define STEPFN(c) ({int __c=(c); (((__c-1)|(__c)) == -1); }) + +static inline void sci_receive_chars(struct sci_port *port, + struct pt_regs *regs) { int i, count; struct tty_struct *tty; @@ -525,7 +657,11 @@ tty = port->gs.tty; while (1) { if (port->type == PORT_SCIF) { +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + count = sci_in(port, SCFDR)&0x007f; +#else count = sci_in(port, SCFDR)&0x001f; +#endif } else { count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0; } @@ -534,7 +670,7 @@ if (tty->flip.count + count > TTY_FLIPBUF_SIZE) count = TTY_FLIPBUF_SIZE - tty->flip.count; - /* If for one reason or another, we can't copy more data, we're done! */ + /* If for any reason we can't copy more data, we're done! */ if (count == 0) break; @@ -543,8 +679,43 @@ tty->flip.flag_buf_ptr[0] = TTY_NORMAL; } else { for (i=0; iflip.char_buf_ptr[i] = sci_in(port, SCxRDR); + char c = sci_in(port, SCxRDR); status = sci_in(port, SCxSR); +#if defined(__SH3__) + /* Skip "chars" during break */ + if (port->break_flag) { + if ((c == 0) && + (status & SCxSR_FER(port))) { + count--; i--; + continue; + } + /* Nonzero => end-of-break */ + dprintk("scif: debounce<%02x>\n", c); + port->break_flag = 0; + if (STEPFN(c)) { + count--; i--; + continue; + } + } +#endif /* __SH3__ */ +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (break_pressed && (port == sercons_port)) { + if (c != 0 && + time_before(jiffies, + break_pressed + HZ*5)) { + handle_sysrq(c, regs, + NULL, NULL); + break_pressed = 0; + count--; i--; + continue; + } else if (c != 0) { + break_pressed = 0; + } + } +#endif /* CONFIG_SERIAL_CONSOLE && CONFIG_MAGIC_SYSRQ */ + + /* Store data and status */ + tty->flip.char_buf_ptr[i] = c; if (status&SCxSR_FER(port)) { tty->flip.flag_buf_ptr[i] = TTY_FRAME; dprintk("sci: frame error\n"); @@ -572,6 +743,10 @@ if (copied) /* Tell the rest of the system the news. New characters! */ tty_flip_buffer_push(tty); + else { + sci_in(port, SCxSR); /* dummy read */ + sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + } } static inline int sci_handle_errors(struct sci_port *port) @@ -624,13 +799,31 @@ struct tty_struct *tty = port->gs.tty; if (status&SCxSR_BRK(port) && tty->flip.countbreak_flag) + goto break_continue; + port->break_flag = 1; +#endif +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (port == sercons_port) { + if (break_pressed == 0) { + break_pressed = jiffies; + dprintk("sci: implied sysrq\n"); + goto break_continue; + } + /* Double break implies a real break */ + break_pressed = 0; + } +#endif /* Notify of BREAK */ copied++; *tty->flip.flag_buf_ptr++ = TTY_BREAK; dprintk("sci: BREAK detected\n"); } + break_continue: -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) +#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40) /* XXX: Handle SCIF overrun error */ if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { sci_out(port, SCLSR, 0); @@ -656,7 +849,7 @@ if (port->gs.flags & GS_ACTIVE) if (!(port->gs.flags & SCI_RX_THROTTLE)) { - sci_receive_chars(port); + sci_receive_chars(port, regs); return; } sci_disable_rx_interrupts(port); @@ -703,6 +896,28 @@ sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); } +static void sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs) +{ + unsigned short ssr_status, scr_status; + struct sci_port *port = ptr; + + ssr_status=sci_in(port,SCxSR); + scr_status=sci_in(port,SCSCR); + + if((ssr_status&0x0020) && (scr_status&0x0080)){ /* Tx Interrupt */ + sci_tx_interrupt(irq, ptr, regs); + } + if((ssr_status&0x0002) && (scr_status&0x0040)){ /* Rx Interrupt */ + sci_rx_interrupt(irq, ptr, regs); + } + if((ssr_status&0x0080) && (scr_status&0x0400)){ /* Error Interrupt */ + sci_er_interrupt(irq, ptr, regs); + } + if((ssr_status&0x0010) && (scr_status&0x0200)){ /* Break Interrupt */ + sci_br_interrupt(irq, ptr, regs); + } +} + static void do_softint(void *private_) { struct sci_port *port = (struct sci_port *) private_; @@ -811,7 +1026,7 @@ static int sci_open(struct tty_struct * tty, struct file * filp) { struct sci_port *port; - int retval, line; + int retval = 0, line; line = MINOR(tty->device) - SCI_MINOR_START; @@ -820,6 +1035,14 @@ port = &sci_ports[line]; +#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) + if (port->base == 0) { + port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); + if (!port->base) + goto failed_1; + } +#endif + tty->driver_data = port; port->gs.tty = tty; port->gs.count++; @@ -827,31 +1050,32 @@ port->event = 0; port->tqueue.routine = do_softint; port->tqueue.data = port; + port->break_flag = 0; + + if (port->gs.count == 1) { + MOD_INC_USE_COUNT; + + retval = sci_request_irq(port); + if (retval) { + goto failed_1; + } + } /* * Start up serial port */ retval = gs_init_port(&port->gs); if (retval) { - goto failed_1; + goto failed_2; } port->gs.flags |= GS_ACTIVE; sci_setsignals(port, 1,1); - if (port->gs.count == 1) { - MOD_INC_USE_COUNT; - - retval = sci_request_irq(port); - if (retval) { - goto failed_2; - } - } - retval = gs_block_til_ready(port, filp); if (retval) { - goto failed_3; + goto failed_2; } if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) { @@ -871,6 +1095,23 @@ } #endif +#ifdef CONFIG_SH_KGDB_CONSOLE + if (kgdbcons.cflag && kgdbcons.index == line) { + tty->termios->c_cflag = kgdbcons.cflag; + port->gs.baud = kgdb_baud; + sercons.cflag = 0; + sci_set_real_termios(port); + } +#elif CONFIG_SH_KGDB + /* Even for non-console, may defer to kgdb */ + if (port == kgdb_sci_port && kgdb_in_gdb_mode) { + tty->termios->c_cflag = kgdb_cflag; + port->gs.baud = kgdb_baud; + sercons.cflag = 0; + sci_set_real_termios(port); + } +#endif /* CONFIG_SH_KGDB */ + sci_enable_rx_interrupts(port); port->gs.session = current->session; @@ -878,11 +1119,10 @@ return 0; -failed_3: - sci_free_irq(port); failed_2: - MOD_DEC_USE_COUNT; + sci_free_irq(port); failed_1: + MOD_DEC_USE_COUNT; port->gs.count--; return retval; } @@ -975,6 +1215,7 @@ * was throttled */ port->gs.flags &= ~SCI_RX_THROTTLE; + sci_enable_rx_interrupts(port); return; } @@ -1110,14 +1351,27 @@ sci_br_interrupt, }; - for (i=0; i<4; i++) { - if (!port->irqs[i]) continue; - if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT, + if(port->irqs[0] == port->irqs[1]){ + if (!port->irqs[0]){ + printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n"); + return -ENODEV; + } + if (request_irq(port->irqs[0], sci_mpxed_interrupt, SA_INTERRUPT, "sci", port)) { printk(KERN_ERR "sci: Cannot allocate irq.\n"); return -ENODEV; } } + else{ + for (i=0; i<4; i++) { + if (!port->irqs[i]) continue; + if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT, + "sci", port)) { + printk(KERN_ERR "sci: Cannot allocate irq.\n"); + return -ENODEV; + } + } + } return 0; } @@ -1125,10 +1379,18 @@ { int i; - for (i=0; i<4; i++) { - if (!port->irqs[i]) continue; - free_irq(port->irqs[i], port); - } + if(port->irqs[0] == port->irqs[1]){ + if(!port->irqs[0]){ + printk("sci: sci_free_irq error\n"); + }else{ + free_irq(port->irqs[0], port); + } + }else{ + for (i=0; i<4; i++) { + if (!port->irqs[i]) continue; + free_irq(port->irqs[i], port); + } + } } static char banner[] __initdata = @@ -1202,6 +1464,12 @@ sercons_port = &sci_ports[co->index]; +#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) + sercons_port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); + if (!sercons_port->base) + return -EINVAL; +#endif + if (options) { baud = simple_strtoul(options, NULL, 10); s = options; @@ -1251,11 +1519,21 @@ break; } - co->cflag = cflag; - sercons_baud = baud; +#ifdef CONFIG_SH_KGDB + if (kgdb_in_gdb_mode && sercons_port == kgdb_sci_port) { + co->cflag = kgdb_cflag; + sercons_baud = kgdb_baud; + sercons_port->old_cflag = cflag; + } + else +#endif /* CONFIG_SH_KGDB */ + { + co->cflag = cflag; + sercons_baud = baud; - sci_set_termios_cflag(sercons_port, cflag, baud); - sercons_port->old_cflag = cflag; + sci_set_termios_cflag(sercons_port, cflag, baud); + sercons_port->old_cflag = cflag; + } return 0; } @@ -1288,3 +1566,110 @@ #endif } #endif /* CONFIG_SERIAL_CONSOLE */ + + +#ifdef CONFIG_SH_KGDB + +/* Initialise the KGDB serial port */ +int kgdb_sci_setup(void) +{ + int cflag = CREAD | HUPCL | CLOCAL; + + if ((kgdb_portnum < 0) || (kgdb_portnum >= SCI_NPORTS)) + return -1; + + kgdb_sci_port = &sci_ports[kgdb_portnum]; + + switch (kgdb_baud) { + case 115200: + cflag |= B115200; + break; + case 57600: + cflag |= B57600; + break; + case 38400: + cflag |= B38400; + break; + case 19200: + cflag |= B19200; + break; + case 9600: + default: + cflag |= B9600; + kgdb_baud = 9600; + break; + } + + switch (kgdb_bits) { + case '7': + cflag |= CS7; + break; + default: + case '8': + cflag |= CS8; + break; + } + + switch (kgdb_parity) { + case 'O': + cflag |= PARODD; + break; + case 'E': + cflag |= PARENB; + break; + } + + kgdb_cflag = cflag; + sci_set_termios_cflag(kgdb_sci_port, kgdb_cflag, kgdb_baud); + + /* Set up the interrupt for BREAK from GDB */ + /* Commented out for now since it may not be possible yet... + request_irq(kgdb_sci_port->irqs[0], kgdb_break_interrupt, + SA_INTERRUPT, "sci", kgdb_sci_port); + sci_enable_rx_interrupts(kgdb_sci_port); + */ + + /* Setup complete: initialize function pointers */ + kgdb_getchar = kgdb_sci_getchar; + kgdb_putchar = kgdb_sci_putchar; + + return 0; +} + +#ifdef CONFIG_SH_KGDB_CONSOLE + +/* Create a console device */ +static kdev_t kgdb_console_device(struct console *c) +{ + return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index); +} + +/* Set up the KGDB console */ +static int __init kgdb_console_setup(struct console *co, char *options) +{ + /* NB we ignore 'options' because we've already done the setup */ + co->cflag = kgdb_cflag; + + return 0; +} + +/* Register the KGDB console so we get messages (d'oh!) */ +void __init kgdb_console_init(void) +{ + register_console(&kgdbcons); +} + +/* The console structure for KGDB */ +static struct console kgdbcons = { + name:"ttySC", + write:kgdb_console_write, + device:kgdb_console_device, + wait_key:serial_console_wait_key, + setup:kgdb_console_setup, + flags:CON_PRINTBUFFER | CON_ENABLED, + index:-1, +}; + +#endif /* CONFIG_SH_KGDB_CONSOLE */ + +#endif /* CONFIG_SH_KGDB */ diff -urN linux-2.4.21/drivers/char/sh-sci.h linux-2.4.22/drivers/char/sh-sci.h --- linux-2.4.21/drivers/char/sh-sci.h 2001-06-27 13:55:29.000000000 -0700 +++ linux-2.4.22/drivers/char/sh-sci.h 2003-08-25 04:44:41.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: sh-sci.h,v 1.8 2000/03/08 15:19:39 gniibe Exp $ +/* $Id: sh-sci.h,v 1.1.1.1.2.3 2003/07/16 18:46:06 yoshii Exp $ * * linux/drivers/char/sh-sci.h * @@ -6,6 +6,7 @@ * Copyright (C) 1999, 2000 Niibe Yutaka * Copyright (C) 2000 Greg Banks * Modified to support multiple serial ports. Stuart Menefy (May 2000). + * Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003). * */ #include @@ -26,6 +27,8 @@ #define SH3_IRDA_IRQS { 52, 53, 55, 54 } #define SH4_SCIF_IRQS { 40, 41, 43, 42 } #define STB1_SCIF1_IRQS {23, 24, 26, 25 } +#define SH5_SCIF_IRQS { 39, 40, 42 } +#define SH7300_SCIF0_IRQS {80, 80, 80, 80 } #if defined(CONFIG_CPU_SUBTYPE_SH7708) # define SCI_NPORTS 1 @@ -35,6 +38,16 @@ # define SCSPTR 0xffffff7c /* 8 bit */ # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCI_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH7300) +# define SCI_NPORTS 1 +# define SCI_INIT { \ + { {}, PORT_SCIF, 0xA4430000, SH7300_SCIF0_IRQS, sci_init_pins_scif }, \ +} +# define SCPCR 0xA4050116 /* 16 bit SCIF */ +# define SCPDR 0xA4050136 /* 16 bit SCIF */ +# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ +# define SCIF_ONLY + #elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) # define SCI_NPORTS 3 # define SCI_INIT { \ @@ -59,7 +72,7 @@ 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \ 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ ) # define SCI_AND_SCIF -#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) +#elif defined(CONFIG_CPU_SUBTYPE_ST40) # define SCI_NPORTS 2 # define SCI_INIT { \ { {}, PORT_SCIF, 0xffe00000, STB1_SCIF1_IRQS, sci_init_pins_scif }, \ @@ -70,6 +83,25 @@ # define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY + +#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) +# include +# define SCIF_BASE_ADDR 0x01030000 +# define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR +# define SCIF_PTR2_OFFS 0x0000020 +# define SCIF_LSR2_OFFS 0x0000024 +# define SCI_NPORTS 1 +# define SCI_INIT { \ + { {}, PORT_SCIF, 0, \ + SH5_SCIF_IRQS, sci_init_pins_scif } \ +} +# define SCSPTR2 (SCIF_ADDR_SH5+SCIF_PTR2_OFFS) /* 16 bit SCIF */ +# define SCLSR2 (SCIF_ADDR_SH5+SCIF_LSR2_OFFS) /* 16 bit SCIF */ +# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0, + TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY + + #else # error CPU subtype not defined #endif @@ -107,7 +139,12 @@ #define SCIF_RDF 0x0002 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */ #define SCIF_DR 0x0001 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */ +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCIF_ORER 0x0200 +#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) +#else #define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK) +#endif #if defined(SCI_ONLY) # define SCxSR_TEND(port) SCI_TEND @@ -127,14 +164,25 @@ # define SCxSR_ERRORS(port) SCIF_ERRORS # define SCxSR_RDxF(port) SCIF_RDF # define SCxSR_TDxE(port) SCIF_TDFE +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +# define SCxSR_ORER(port) SCIF_ORER +#else # define SCxSR_ORER(port) 0x0000 +#endif # define SCxSR_FER(port) SCIF_FER # define SCxSR_PER(port) SCIF_PER # define SCxSR_BRK(port) SCIF_BRK +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +# define SCxSR_RDxF_CLEAR(port) (sci_in(port,SCxSR)&0xfffc) +# define SCxSR_ERROR_CLEAR(port) (sci_in(port,SCxSR)&0xfd73) +# define SCxSR_TDxE_CLEAR(port) (sci_in(port,SCxSR)&0xffdf) +# define SCxSR_BREAK_CLEAR(port) (sci_in(port,SCxSR)&0xffe3) +#else # define SCxSR_RDxF_CLEAR(port) 0x00fc # define SCxSR_ERROR_CLEAR(port) 0x0073 # define SCxSR_TDxE_CLEAR(port) 0x00df # define SCxSR_BREAK_CLEAR(port) 0x00e3 +#endif #else # define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) # define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) @@ -153,6 +201,7 @@ /* SCFCR */ #define SCFCR_RFRST 0x0002 #define SCFCR_TFRST 0x0004 +#define SCFCR_TCRST 0x4000 #define SCFCR_MCE 0x0008 #define SCI_MAJOR 204 @@ -202,6 +251,7 @@ struct async_icount icount; struct tq_struct tqueue; unsigned long event; + int break_flag; }; #define SCI_IN(size, offset) \ @@ -248,11 +298,16 @@ } #ifdef __sh3__ +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCIF_FNS(name, scif_offset, scif_size) \ + CPU_SCIF_FNS(name, scif_offset, scif_size) +#else #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size) #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size) +#endif #else #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ @@ -261,6 +316,18 @@ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +SCIF_FNS(SCSMR, 0x00, 16) +SCIF_FNS(SCBRR, 0x04, 8) +SCIF_FNS(SCSCR, 0x08, 16) +SCIF_FNS(SCTDSR, 0x0c, 8) +SCIF_FNS(SCFER, 0x10, 16) +SCIF_FNS(SCxSR, 0x14, 16) +SCIF_FNS(SCFCR, 0x18, 16) +SCIF_FNS(SCFDR, 0x1c, 16) +SCIF_FNS(SCxTDR, 0x20, 8) +SCIF_FNS(SCxRDR, 0x24, 8) +#else /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 */ /* name off sz off sz off sz off sz */ SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16) @@ -271,7 +338,9 @@ SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8) SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) +SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) SCIF_FNS(SCLSR, 0, 0, 0x24, 16) +#endif #define sci_in(port, reg) sci_##reg##_in(port) #define sci_out(port, reg, value) sci_##reg##_out(port, value) @@ -283,6 +352,13 @@ return ctrl_inb(SCSPTR)&0x01 ? 1 : 0; /* SCI */ return 1; } +#elif defined(CONFIG_CPU_SUBTYPE_SH7300) +static inline int sci_rxd_in(struct sci_port *port) +{ + if (port->base == 0xa4430000) + return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCIF0 */ + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) static inline int sci_rxd_in(struct sci_port *port) { @@ -307,7 +383,7 @@ #endif return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) +#elif defined(CONFIG_CPU_SUBTYPE_ST40) static inline int sci_rxd_in(struct sci_port *port) { if (port->base == 0xffe00000) @@ -316,6 +392,12 @@ return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ } +#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) +static inline int sci_rxd_in(struct sci_port *port) +{ + return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */ +} + #endif /* @@ -352,7 +434,11 @@ #define PCLK (current_cpu_data.module_clock) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCBRR_VALUE(bps) ((PCLK+16*bps)/(16*bps)-1) +#else #define SCBRR_VALUE(bps) ((PCLK+16*bps)/(32*bps)-1) +#endif #define BPS_2400 SCBRR_VALUE(2400) #define BPS_4800 SCBRR_VALUE(4800) #define BPS_9600 SCBRR_VALUE(9600) diff -urN linux-2.4.21/drivers/char/sonypi.c linux-2.4.22/drivers/char/sonypi.c --- linux-2.4.21/drivers/char/sonypi.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/sonypi.c 2003-08-25 04:44:41.000000000 -0700 @@ -120,9 +120,9 @@ static int ec_read16(u8 addr, u16 *value) { u8 val_lb, val_hb; - if (ec_read(addr, &val_lb)) + if (sonypi_ec_read(addr, &val_lb)) return -1; - if (ec_read(addr + 1, &val_hb)) + if (sonypi_ec_read(addr + 1, &val_hb)) return -1; *value = val_lb | (val_hb << 8); return 0; @@ -152,11 +152,11 @@ } static void __devinit sonypi_type2_srs(void) { - if (ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8)) + if (sonypi_ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8)) printk(KERN_WARNING "ec_write failed\n"); - if (ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF)) + if (sonypi_ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF)) printk(KERN_WARNING "ec_write failed\n"); - if (ec_write(SONYPI_SIRQ, sonypi_device.bits)) + if (sonypi_ec_write(SONYPI_SIRQ, sonypi_device.bits)) printk(KERN_WARNING "ec_write failed\n"); udelay(10); } @@ -175,11 +175,11 @@ } static void sonypi_type2_dis(void) { - if (ec_write(SONYPI_SHIB, 0)) + if (sonypi_ec_write(SONYPI_SHIB, 0)) printk(KERN_WARNING "ec_write failed\n"); - if (ec_write(SONYPI_SLOB, 0)) + if (sonypi_ec_write(SONYPI_SLOB, 0)) printk(KERN_WARNING "ec_write failed\n"); - if (ec_write(SONYPI_SIRQ, 0)) + if (sonypi_ec_write(SONYPI_SIRQ, 0)) printk(KERN_WARNING "ec_write failed\n"); } @@ -265,7 +265,7 @@ for (j = 5; j > 0; j--) { - while (sonypi_call2(0x91, 0x1) != 0) { + while (sonypi_call2(0x91, 0x1)) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); } @@ -277,7 +277,7 @@ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); } - if (i != 0) + if (i) break; } @@ -293,14 +293,12 @@ /* sets the bluetooth subsystem power state */ static void sonypi_setbluetoothpower(u8 state) { - state = (state != 0); - if (sonypi_device.bluetooth_power && state) - return; - if (!sonypi_device.bluetooth_power && !state) + state = !!state; + if (sonypi_device.bluetooth_power == state) return; sonypi_call2(0x96, state); - sonypi_call1(0x93); + sonypi_call1(0x82); sonypi_device.bluetooth_power = state; } @@ -312,10 +310,6 @@ v1 = inb_p(sonypi_device.ioport1); v2 = inb_p(sonypi_device.ioport2); - if (verbose > 1) - printk(KERN_INFO - "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); - for (i = 0; sonypi_eventtypes[i].model; i++) { if (sonypi_device.model != sonypi_eventtypes[i].model) continue; @@ -337,7 +331,11 @@ return; found: -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + if (verbose > 1) + printk(KERN_INFO + "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); + +#ifdef SONYPI_USE_INPUT if (useinput) { struct input_dev *jog_dev = &sonypi_device.jog_dev; if (event == SONYPI_EVENT_JOGDIAL_PRESSED) @@ -351,7 +349,7 @@ (event == SONYPI_EVENT_JOGDIAL_DOWN_PRESSED)) input_report_rel(jog_dev, REL_WHEEL, -1); } -#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */ +#endif /* SONYPI_USE_INPUT */ sonypi_pushq(event); } @@ -507,7 +505,7 @@ down(&sonypi_device.lock); switch (cmd) { case SONYPI_IOCGBRT: - if (ec_read(SONYPI_LCD_LIGHT, &val8)) { + if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) { ret = -EIO; break; } @@ -519,7 +517,7 @@ ret = -EFAULT; break; } - if (ec_write(SONYPI_LCD_LIGHT, val8)) + if (sonypi_ec_write(SONYPI_LCD_LIGHT, val8)) ret = -EIO; break; case SONYPI_IOCGBAT1CAP: @@ -555,7 +553,7 @@ ret = -EFAULT; break; case SONYPI_IOCGBATFLAGS: - if (ec_read(SONYPI_BAT_FLAGS, &val8)) { + if (sonypi_ec_read(SONYPI_BAT_FLAGS, &val8)) { ret = -EIO; break; } @@ -611,18 +609,14 @@ sonypi_type2_dis(); else sonypi_type1_dis(); -#ifndef CONFIG_ACPI /* disable ACPI mode */ - if (fnkeyinit) + if (!SONYPI_ACPI_ACTIVE && fnkeyinit) outb(0xf1, 0xb2); -#endif break; case PM_RESUME: -#ifndef CONFIG_ACPI /* Enable ACPI mode to get Fn key events */ - if (fnkeyinit) + if (!SONYPI_ACPI_ACTIVE && fnkeyinit) outb(0xf0, 0xb2); -#endif if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) sonypi_type2_srs(); else @@ -696,36 +690,44 @@ } for (i = 0; irq_list[i].irq; i++) { - if (!request_irq(irq_list[i].irq, sonypi_irq, - SA_SHIRQ, "sonypi", sonypi_irq)) { - sonypi_device.irq = irq_list[i].irq; - sonypi_device.bits = irq_list[i].bits; + + sonypi_device.irq = irq_list[i].irq; + sonypi_device.bits = irq_list[i].bits; + + /* Enable sonypi IRQ settings */ + if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) + sonypi_type2_srs(); + else + sonypi_type1_srs(); + + sonypi_call1(0x82); + sonypi_call2(0x81, 0xff); + if (compat) + sonypi_call1(0x92); + else + sonypi_call1(0x82); + + /* Now try requesting the irq from the system */ + if (!request_irq(sonypi_device.irq, sonypi_irq, + SA_SHIRQ, "sonypi", sonypi_irq)) break; - } + + /* If request_irq failed, disable sonypi IRQ settings */ + if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) + sonypi_type2_dis(); + else + sonypi_type1_dis(); } - if (!sonypi_device.irq ) { + + if (!irq_list[i].irq) { printk(KERN_ERR "sonypi: request_irq failed\n"); ret = -ENODEV; goto out3; } -#ifndef CONFIG_ACPI /* Enable ACPI mode to get Fn key events */ - if (fnkeyinit) + if (!SONYPI_ACPI_ACTIVE && fnkeyinit) outb(0xf0, 0xb2); -#endif - - if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) - sonypi_type2_srs(); - else - sonypi_type1_srs(); - - sonypi_call1(0x82); - sonypi_call2(0x81, 0xff); - if (compat) - sonypi_call1(0x92); - else - sonypi_call1(0x82); printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver v%d.%d.\n", SONYPI_DRIVER_MAJORVERSION, @@ -748,7 +750,7 @@ printk(KERN_INFO "sonypi: device allocated minor is %d\n", sonypi_misc_device.minor); -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#ifdef SONYPI_USE_INPUT if (useinput) { /* Initialize the Input Drivers: */ sonypi_device.jog_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); @@ -765,7 +767,7 @@ sonypi_device.jog_dev.name, sonypi_device.jog_dev.number); } -#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */ +#endif /* SONYPI_USE_INPUT */ #ifdef CONFIG_PM sonypi_device.pm = pm_register(PM_PCI_DEV, 0, sonypi_pm_callback); @@ -789,12 +791,12 @@ sonypi_call2(0x81, 0); /* make sure we don't get any more events */ -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#ifdef SONYPI_USE_INPUT if (useinput) { input_unregister_device(&sonypi_device.jog_dev); kfree(sonypi_device.jog_dev.name); } -#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */ +#endif /* SONYPI_USE_INPUT */ if (camera) sonypi_camera_off(); @@ -802,11 +804,9 @@ sonypi_type2_dis(); else sonypi_type1_dis(); -#ifndef CONFIG_ACPI /* disable ACPI mode */ - if (fnkeyinit) + if (!SONYPI_ACPI_ACTIVE && fnkeyinit) outb(0xf1, 0xb2); -#endif free_irq(sonypi_device.irq, sonypi_irq); release_region(sonypi_device.ioport1, sonypi_device.region_size); misc_deregister(&sonypi_misc_device); diff -urN linux-2.4.21/drivers/char/sonypi.h linux-2.4.22/drivers/char/sonypi.h --- linux-2.4.21/drivers/char/sonypi.h 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/sonypi.h 2003-08-25 04:44:41.000000000 -0700 @@ -37,7 +37,7 @@ #ifdef __KERNEL__ #define SONYPI_DRIVER_MAJORVERSION 1 -#define SONYPI_DRIVER_MINORVERSION 18 +#define SONYPI_DRIVER_MINORVERSION 20 #define SONYPI_DEVICE_MODEL_TYPE1 1 #define SONYPI_DEVICE_MODEL_TYPE2 2 @@ -335,6 +335,15 @@ unsigned char buf[SONYPI_BUF_SIZE]; }; +/* We enable input subsystem event forwarding if the input + * subsystem is compiled in, but only if sonypi is not into the + * kernel and input as a module... */ +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#if ! (defined(CONFIG_SONYPI) && defined(CONFIG_INPUT_MODULE)) +#define SONYPI_USE_INPUT +#endif +#endif + /* The name of the Jog Dial for the input device drivers */ #define SONYPI_INPUTNAME "Sony VAIO Jog Dial" @@ -351,7 +360,7 @@ struct sonypi_queue queue; int open_count; int model; -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#ifdef SONYPI_USE_INPUT struct input_dev jog_dev; #endif #ifdef CONFIG_PM @@ -373,14 +382,30 @@ #ifdef CONFIG_ACPI #include #if (ACPI_CA_VERSION > 0x20021121) -#define USE_ACPI +#ifdef CONFIG_ACPI_EC +#define SONYPI_USE_ACPI +#endif #endif #endif /* CONFIG_ACPI */ -#ifndef USE_ACPI +#ifdef CONFIG_ACPI +#ifdef SONYPI_USE_ACPI +extern int acpi_disabled; +#define SONYPI_ACPI_ACTIVE (!acpi_disabled) +#else +#define SONYPI_ACPI_ACTIVE 1 +#endif +#else /* CONFIG_ACPI */ +#define SONYPI_ACPI_ACTIVE 0 +#endif /* CONFIG_ACPI */ + extern int verbose; -static inline int ec_write(u8 addr, u8 value) { +static inline int sonypi_ec_write(u8 addr, u8 value) { +#ifdef SONYPI_USE_ACPI + if (!acpi_disabled) + return ec_write(addr, value); +#endif wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG); outb_p(0x81, SONYPI_CST_IOPORT); wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG); @@ -391,7 +416,11 @@ return 0; } -static inline int ec_read(u8 addr, u8 *value) { +static inline int sonypi_ec_read(u8 addr, u8 *value) { +#ifdef SONYPI_USE_ACPI + if (!acpi_disabled) + return ec_read(addr, value); +#endif wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG); outb_p(0x80, SONYPI_CST_IOPORT); wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG); @@ -400,7 +429,6 @@ *value = inb_p(SONYPI_DATA_IOPORT); return 0; } -#endif /* ! USE_ACPI */ #endif /* __KERNEL__ */ diff -urN linux-2.4.21/drivers/char/sysrq.c linux-2.4.22/drivers/char/sysrq.c --- linux-2.4.21/drivers/char/sysrq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/char/sysrq.c 2003-08-25 04:44:41.000000000 -0700 @@ -372,9 +372,9 @@ /* key2index calculation, -1 on invalid index */ static __inline__ int sysrq_key_table_key2index(int key) { int retval; - if ((key >= '0') & (key <= '9')) { + if ((key >= '0') && (key <= '9')) { retval = key - '0'; - } else if ((key >= 'a') & (key <= 'z')) { + } else if ((key >= 'a') && (key <= 'z')) { retval = key + 10 - 'a'; } else { retval = -1; diff -urN linux-2.4.21/drivers/char/tty_io.c linux-2.4.22/drivers/char/tty_io.c --- linux-2.4.21/drivers/char/tty_io.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/char/tty_io.c 2003-08-25 04:44:41.000000000 -0700 @@ -142,6 +142,7 @@ extern int serial167_init(void); extern long serial167_console_init(void); extern void console_8xx_init(void); +extern void au1x00_serial_console_init(void); extern int rs_8xx_init(void); extern void mac_scc_console_init(void); extern void hwc_console_init(void); @@ -154,10 +155,14 @@ extern void sa1100_rs_console_init(void); extern void sgi_serial_console_init(void); extern void sci_console_init(void); +extern void dec_serial_console_init(void); extern void tx3912_console_init(void); extern void tx3912_rs_init(void); extern void txx927_console_init(void); +extern void txx9_rs_init(void); +extern void txx9_serial_console_init(void); extern void sb1250_serial_console_init(void); +extern void arc_console_init(void); #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -2235,8 +2240,8 @@ #ifdef CONFIG_VT con_init(); #endif -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - au1000_serial_console_init(); +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + au1x00_serial_console_init(); #endif #ifdef CONFIG_SERIAL_CONSOLE #if (defined(CONFIG_8xx) || defined(CONFIG_8260)) @@ -2253,9 +2258,6 @@ #elif defined(CONFIG_SERIAL) serial_console_init(); #endif /* CONFIG_8xx */ -#ifdef CONFIG_SGI_SERIAL - sgi_serial_console_init(); -#endif #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC) || defined(CONFIG_MVME147_SCC) vme_scc_console_init(); #endif @@ -2266,6 +2268,9 @@ sci_console_init(); #endif #endif +#ifdef CONFIG_SERIAL_DEC_CONSOLE + dec_serial_console_init(); +#endif #ifdef CONFIG_TN3270_CONSOLE tub3270_con_init(); #endif @@ -2296,9 +2301,15 @@ #ifdef CONFIG_TXX927_SERIAL_CONSOLE txx927_console_init(); #endif +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + txx9_serial_console_init(); +#endif #ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE sb1250_serial_console_init(); #endif +#ifdef CONFIG_IP22_SERIAL + sgi_serial_console_init(); +#endif } static struct tty_driver dev_tty_driver, dev_syscons_driver; diff -urN linux-2.4.21/drivers/char/vac-serial.c linux-2.4.22/drivers/char/vac-serial.c --- linux-2.4.21/drivers/char/vac-serial.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/char/vac-serial.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,2905 @@ +/* + * vacserial.c: VAC UART serial driver + * This code stealed and adopted from linux/drivers/char/serial.c + * See that for author info + * + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + */ + +#undef SERIAL_PARANOIA_CHECK +#define CONFIG_SERIAL_NOPAUSE_IO +#define SERIAL_DO_RESTART + +#define CONFIG_SERIAL_SHARE_IRQ + +/* Set of debugging defines */ + +#undef SERIAL_DEBUG_INTR +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_FLOW +#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + +#define RS_STROBE_TIME (10*HZ) +#define RS_ISR_PASS_LIMIT 2 /* Beget is not a super-computer (old=256) */ + +#define IRQ_T(state) \ + ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) + +#define SERIAL_INLINE + +#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) +#define DBG_CNT(s) baget_printk("(%s):[%x] refc=%d, serc=%d, ttyc=%d-> %s\n", \ + kdevname(tty->device),(info->flags),serial_refcount,info->count,tty->count,s) +#else +#define DBG_CNT(s) +#endif + +#define QUAD_UART_SPEED /* Useful for Baget */ + +/* + * End of serial driver configuration section. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_CONSOLE +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define BAGET_VAC_UART_IRQ 0x35 + +/* + * Implementation note: + * It was descovered by means of advanced electronic tools, + * if the driver works via TX_READY interrupts then VIC generates + * strange self-eliminating traps. Thus, the driver is rewritten to work + * via TX_EMPTY + */ + +/* VAC-specific check/debug switches */ + +#undef CHECK_REG_INDEX +#undef DEBUG_IO_PORT_A + +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#endif + +static char *serial_name = "VAC Serial driver"; +static char *serial_version = "4.26"; + +static DECLARE_TASK_QUEUE(tq_serial); + +static struct tty_driver serial_driver, callout_driver; +static int serial_refcount; + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* + * IRQ_timeout - How long the timeout should be for each IRQ + * should be after the IRQ has been active. + */ + +static struct async_struct *IRQ_ports[NR_IRQS]; +static int IRQ_timeout[NR_IRQS]; +#ifdef CONFIG_SERIAL_CONSOLE +static struct console sercons; +#endif + +static void autoconfig(struct serial_state * info); +static void change_speed(struct async_struct *info); +static void rs_wait_until_sent(struct tty_struct *tty, int timeout); +static void rs_timer(unsigned long dummy); + +static struct timer_list vacs_timer; + +/* + * Here we define the default xmit fifo size used for each type of + * UART + */ +static struct serial_uart_config uart_config[] = { + { "unknown", 1, 0 }, /* Must go first -- used as unasigned */ + { "VAC UART", 1, 0 } +}; +#define VAC_UART_TYPE 1 /* Just index in above array */ + +static struct serial_state rs_table[] = { +/* + * VAC has tricky layout for pair of his SIO registers, + * so we need special function to access ones. + * To identify port we use their TX offset + */ + { 0, 9600, VAC_UART_B_TX, BAGET_VAC_UART_IRQ, + STD_COM_FLAGS }, /* VAC UART B */ + { 0, 9600, VAC_UART_A_TX, BAGET_VAC_UART_IRQ, + STD_COM_FLAGS } /* VAC UART A */ +}; + +#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) + +static struct tty_struct *serial_table[NR_PORTS]; +static struct termios *serial_termios[NR_PORTS]; +static struct termios *serial_termios_locked[NR_PORTS]; + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the copy_from_user blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char *tmp_buf; +static DECLARE_MUTEX(tmp_buf_sem); + +static inline int serial_paranoia_check(struct async_struct *info, + kdev_t device, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = + "Warning: bad magic number for serial struct (%s) in %s\n"; + static const char *badinfo = + "Warning: null async_struct for (%s) in %s\n"; + + if (!info) { + printk(badinfo, kdevname(device), routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, kdevname(device), routine); + return 1; + } +#endif + return 0; +} + +/* + To unify UART A/B access we will use following function + to compute register offsets by register index. + */ + +#define VAC_UART_MODE 0 +#define VAC_UART_TX 1 +#define VAC_UART_RX 2 +#define VAC_UART_INT_MASK 3 +#define VAC_UART_INT_STATUS 4 + +#define VAC_UART_REG_NR 5 + +static inline int uart_offset_map(unsigned long port, int reg_index) +{ + static const unsigned int ind_to_reg[VAC_UART_REG_NR][NR_PORTS] = { + { VAC_UART_B_MODE, VAC_UART_A_MODE }, + { VAC_UART_B_TX, VAC_UART_A_TX }, + { VAC_UART_B_RX, VAC_UART_A_RX }, + { VAC_UART_B_INT_MASK, VAC_UART_A_INT_MASK }, + { VAC_UART_B_INT_STATUS, VAC_UART_A_INT_STATUS } + }; +#ifdef CHECK_REG_INDEX + if (reg_index > VAC_UART_REG_NR) panic("vacserial: bad reg_index"); +#endif + return ind_to_reg[reg_index][port == VAC_UART_B_TX ? 0 : 1]; +} + +static inline unsigned int serial_inw(struct async_struct *info, int offset) +{ + int val = vac_inw(uart_offset_map(info->port,offset)); +#ifdef DEBUG_IO_PORT_A + if (info->port == VAC_UART_A_TX) + printk("UART_A_IN: reg = 0x%04x, val = 0x%04x\n", + uart_offset_map(info->port,offset), val); +#endif + return val; +} + +static inline unsigned int serial_inp(struct async_struct *info, int offset) +{ + return serial_inw(info, offset); +} + +static inline unsigned int serial_in(struct async_struct *info, int offset) +{ + return serial_inw(info, offset); +} + +static inline void serial_outw(struct async_struct *info,int offset, int value) +{ +#ifdef DEBUG_IO_PORT_A + if (info->port == VAC_UART_A_TX) + printk("UART_A_OUT: offset = 0x%04x, val = 0x%04x\n", + uart_offset_map(info->port,offset), value); +#endif + vac_outw(value, uart_offset_map(info->port,offset)); +} + +static inline void serial_outp(struct async_struct *info,int offset, int value) +{ + serial_outw(info,offset,value); +} + +static inline void serial_out(struct async_struct *info,int offset, int value) +{ + serial_outw(info,offset,value); +} + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_stop")) + return; + + save_flags(flags); cli(); + if (info->IER & VAC_UART_INT_TX_EMPTY) { + info->IER &= ~VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } + restore_flags(flags); +} + +static void rs_start(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_start")) + return; + + save_flags(flags); cli(); + if (info->xmit_cnt && info->xmit_buf + && !(info->IER & VAC_UART_INT_TX_EMPTY)) { + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } + restore_flags(flags); +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * Note: rs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * rs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static _INLINE_ void rs_sched_event(struct async_struct *info, + int event) +{ + info->event |= 1 << event; + queue_task(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +static _INLINE_ void receive_chars(struct async_struct *info, + int *status) +{ + struct tty_struct *tty = info->tty; + unsigned short rx; + unsigned char ch; + int ignored = 0; + struct async_icount *icount; + + icount = &info->state->icount; + do { + rx = serial_inw(info, VAC_UART_RX); + ch = VAC_UART_RX_DATA_MASK & rx; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + break; + *tty->flip.char_buf_ptr = ch; + icount->rx++; + +#ifdef SERIAL_DEBUG_INTR + baget_printk("DR%02x:%02x...", rx, *status); +#endif + *tty->flip.flag_buf_ptr = 0; + if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE + | VAC_UART_STATUS_RX_ERR_PARITY + | VAC_UART_STATUS_RX_ERR_FRAME + | VAC_UART_STATUS_RX_ERR_OVERRUN)) { + /* + * For statistics only + */ + if (*status & VAC_UART_STATUS_RX_BREAK_CHANGE) { + *status &= ~(VAC_UART_STATUS_RX_ERR_FRAME + | VAC_UART_STATUS_RX_ERR_PARITY); + icount->brk++; + } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) + icount->parity++; + else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) + icount->frame++; + if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) + icount->overrun++; + + /* + * Now check to see if character should be + * ignored, and mask off conditions which + * should be ignored. + */ + if (*status & info->ignore_status_mask) { + if (++ignored > 100) + break; + goto ignore_char; + } + *status &= info->read_status_mask; + + if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE)) { +#ifdef SERIAL_DEBUG_INTR + baget_printk("handling break...."); +#endif + *tty->flip.flag_buf_ptr = TTY_BREAK; + if (info->flags & ASYNC_SAK) + do_SAK(tty); + } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) + *tty->flip.flag_buf_ptr = TTY_FRAME; + if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) { + /* + * Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + if (tty->flip.count < TTY_FLIPBUF_SIZE) { + tty->flip.count++; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + } + } + } + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + ignore_char: + *status = serial_inw(info, VAC_UART_INT_STATUS); + } while ((*status & VAC_UART_STATUS_RX_READY)); + tty_flip_buffer_push(tty); +} + +static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) +{ + int count; + + if (info->x_char) { + serial_outw(info, VAC_UART_TX, + (((unsigned short)info->x_char)<<8)); + info->state->icount.tx++; + info->x_char = 0; + if (intr_done) + *intr_done = 0; + return; + } + if ((info->xmit_cnt <= 0) || info->tty->stopped || + info->tty->hw_stopped) { + info->IER &= ~VAC_UART_INT_TX_EMPTY; + serial_outw(info, VAC_UART_INT_MASK, info->IER); + return; + } + count = info->xmit_fifo_size; + do { + serial_out(info, VAC_UART_TX, + (unsigned short)info->xmit_buf[info->xmit_tail++] \ + << 8); + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->state->icount.tx++; + if (--info->xmit_cnt <= 0) + break; + } while (--count > 0); + + if (info->xmit_cnt < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + +#ifdef SERIAL_DEBUG_INTR + baget_printk("THRE..."); +#endif + if (intr_done) + *intr_done = 0; + + if (info->xmit_cnt <= 0) { + info->IER &= ~VAC_UART_INT_TX_EMPTY; + serial_outw(info, VAC_UART_INT_MASK, info->IER); + } +} + +static _INLINE_ void check_modem_status(struct async_struct *info) +{ +#if 0 /* VAC hasn't modem control */ + wake_up_interruptible(&info->open_wait); + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); +#endif +} + +#ifdef CONFIG_SERIAL_SHARE_IRQ + + +/* + * Specific functions needed for VAC UART interrupt enter/leave + */ + +#define VAC_INT_CTRL_UART_ENABLE \ + (VAC_INT_CTRL_TIMER_PIO10|VAC_INT_CTRL_UART_B_PIO7|VAC_INT_CTRL_UART_A_PIO7) + +#define VAC_INT_CTRL_UART_DISABLE(info) \ + (VAC_INT_CTRL_TIMER_PIO10 | \ + ((info->port == VAC_UART_A_TX) ? \ + (VAC_INT_CTRL_UART_A_DISABLE|VAC_INT_CTRL_UART_B_PIO7) : \ + (VAC_INT_CTRL_UART_A_PIO7|VAC_INT_CTRL_UART_B_DISABLE))) + +/* + * Following two functions were proposed by Pavel Osipenko + * to make VAC/VIC behaviour more regular. + */ +static void intr_begin(struct async_struct* info) +{ + serial_outw(info, VAC_UART_INT_MASK, 0); +} + +static void intr_end(struct async_struct* info) +{ + vac_outw(VAC_INT_CTRL_UART_DISABLE(info), VAC_INT_CTRL); + vac_outw(VAC_INT_CTRL_UART_ENABLE, VAC_INT_CTRL); + + serial_outw(info, VAC_UART_INT_MASK, info->IER); +} + +/* + * This is the serial driver's generic interrupt routine + */ +static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + int status; + struct async_struct * info; + int pass_counter = 0; + struct async_struct *end_mark = 0; + +#ifdef SERIAL_DEBUG_INTR + baget_printk("rs_interrupt(%d)...", irq); +#endif + + info = IRQ_ports[irq]; + if (!info) + return; + + do { + intr_begin(info); /* Mark we begin port handling */ + + if (!info->tty || + (serial_inw (info, VAC_UART_INT_STATUS) + & VAC_UART_STATUS_INTS) == 0) + { + if (!end_mark) + end_mark = info; + goto next; + } + end_mark = 0; + + info->last_active = jiffies; + + status = serial_inw(info, VAC_UART_INT_STATUS); +#ifdef SERIAL_DEBUG_INTR + baget_printk("status = %x...", status); +#endif + if (status & VAC_UART_STATUS_RX_READY) { + receive_chars(info, &status); + } + check_modem_status(info); + if (status & VAC_UART_STATUS_TX_EMPTY) + transmit_chars(info, 0); + + next: + intr_end(info); /* Mark this port handled */ + + info = info->next_port; + if (!info) { + info = IRQ_ports[irq]; + if (pass_counter++ > RS_ISR_PASS_LIMIT) { + break; /* Prevent infinite loops */ + } + continue; + } + } while (end_mark != info); +#ifdef SERIAL_DEBUG_INTR + baget_printk("end.\n"); +#endif + + +} +#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */ + + +/* The original driver was simplified here: + two functions were joined to reduce code */ + +#define rs_interrupt_single rs_interrupt + + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_serial); +} + +static void do_softint(void *private_) +{ + struct async_struct *info = (struct async_struct *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); + } +} + +/* + * --------------------------------------------------------------- + * Low level utility subroutines for the serial driver: routines to + * figure out the appropriate timeout for an interrupt chain, routines + * to initialize and startup a serial port, and routines to shutdown a + * serial port. Useful stuff like that. + * --------------------------------------------------------------- + */ + +/* + * This routine figures out the correct timeout for a particular IRQ. + * It uses the smallest timeout of all of the serial ports in a + * particular interrupt chain. Now only used for IRQ 0.... + */ +static void figure_IRQ_timeout(int irq) +{ + struct async_struct *info; + int timeout = 60*HZ; /* 60 seconds === a long time :-) */ + + info = IRQ_ports[irq]; + if (!info) { + IRQ_timeout[irq] = 60*HZ; + return; + } + while (info) { + if (info->timeout < timeout) + timeout = info->timeout; + info = info->next_port; + } + if (!irq) + timeout = timeout / 2; + IRQ_timeout[irq] = timeout ? timeout : 1; +} + +static int startup(struct async_struct * info) +{ + unsigned long flags; + int retval=0; + void (*handler)(int, void *, struct pt_regs *); + struct serial_state *state= info->state; + unsigned long page; + + page = get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + save_flags(flags); cli(); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + if (!state->port || !state->type) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + free_page(page); + goto errout; + } + if (info->xmit_buf) + free_page(page); + else + info->xmit_buf = (unsigned char *) page; + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("starting up ttys%d (irq %d)...", info->line, state->irq); +#endif + + if (uart_config[info->state->type].flags & UART_STARTECH) { + /* Wake up UART */ + serial_outp(info, VAC_UART_MODE, 0); + serial_outp(info, VAC_UART_INT_MASK, 0); + } + + /* + * Allocate the IRQ if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + + if (IRQ_ports[state->irq]) { +#ifdef CONFIG_SERIAL_SHARE_IRQ + free_irq(state->irq, NULL); + handler = rs_interrupt; +#else + retval = -EBUSY; + goto errout; +#endif /* CONFIG_SERIAL_SHARE_IRQ */ + } else + handler = rs_interrupt_single; + + + retval = request_irq(state->irq, handler, IRQ_T(state), + "serial", NULL); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + } + + /* + * Insert serial port into IRQ chain. + */ + info->prev_port = 0; + info->next_port = IRQ_ports[state->irq]; + if (info->next_port) + info->next_port->prev_port = info; + IRQ_ports[state->irq] = info; + figure_IRQ_timeout(state->irq); + + /* + * Clear the interrupt registers. + */ + /* (void) serial_inw(info, VAC_UART_INT_STATUS); */ /* (see above) */ + (void) serial_inw(info, VAC_UART_RX); + + /* + * Now, initialize the UART + */ + serial_outp(info, VAC_UART_MODE, VAC_UART_MODE_INITIAL); /*reset DLAB*/ + + /* + * Finally, enable interrupts + */ + info->IER = VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS | \ + VAC_UART_INT_RX_READY; + serial_outp(info, VAC_UART_INT_MASK, info->IER); /*enable interrupts*/ + + /* + * And clear the interrupt registers again for luck. + */ + (void)serial_inp(info, VAC_UART_INT_STATUS); + (void)serial_inp(info, VAC_UART_RX); + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + /* + * Set up serial timers... + */ + mod_timer(&vacs_timer, jiffies + 2*HZ/100); + + /* + * and set the speed of the serial port + */ + change_speed(info); + + info->flags |= ASYNC_INITIALIZED; + restore_flags(flags); + return 0; + +errout: + restore_flags(flags); + return retval; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct async_struct * info) +{ + unsigned long flags; + struct serial_state *state; + int retval; + + if (!(info->flags & ASYNC_INITIALIZED)) + return; + + state = info->state; + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("Shutting down serial port %d (irq %d)....", info->line, + state->irq); +#endif + + save_flags(flags); cli(); /* Disable interrupts */ + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be waken up + */ + 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, NULL); + retval = request_irq(state->irq, rs_interrupt_single, + IRQ_T(state), "serial", NULL); + + if (retval) + printk("serial shutdown: request_irq: error %d" + " Couldn't reacquire IRQ.\n", retval); + } else + free_irq(state->irq, NULL); + } + + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = 0; + } + + info->IER = 0; + serial_outp(info, VAC_UART_INT_MASK, 0x00); /* disable all intrs */ + + /* disable break condition */ + serial_out(info, VAC_UART_MODE, serial_inp(info, VAC_UART_MODE) & \ + ~VAC_UART_MODE_SEND_BREAK); + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; + restore_flags(flags); +} + +/* + * When we set line mode, we call this function + * for Baget-specific adjustments. + */ + +static inline unsigned short vac_uart_mode_fixup (unsigned short cval) +{ +#ifdef QUAD_UART_SPEED + /* + * When we are using 4-x advantage in speed: + * + * Disadvantage : can't support 75, 150 bauds + * Advantage : can support 19200, 38400 bauds + */ + char speed = 7 & (cval >> 10); + cval &= ~(7 << 10); + cval |= VAC_UART_MODE_BAUD(speed-2); +#endif + + /* + * In general, we have Tx and Rx ON all time + * and use int mask flag for their disabling. + */ + cval |= VAC_UART_MODE_RX_ENABLE; + cval |= VAC_UART_MODE_TX_ENABLE; + cval |= VAC_UART_MODE_CHAR_RX_ENABLE; + cval |= VAC_UART_MODE_CHAR_TX_ENABLE; + + /* Low 4 bits are not used in UART */ + cval &= ~0xf; + + return cval; +} + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct async_struct *info) +{ + unsigned short port; + int quot = 0, baud_base, baud; + unsigned cflag, cval; + int bits; + unsigned long flags; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + if (!(port = info->port)) + return; + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS7: cval = 0x0; bits = 9; break; + case CS8: cval = VAC_UART_MODE_8BIT_CHAR; bits = 10; break; + /* Never happens, but GCC is too dumb to figure it out */ + case CS5: + case CS6: + default: cval = 0x0; bits = 9; break; + } + cval &= ~VAC_UART_MODE_PARITY_ENABLE; + if (cflag & PARENB) { + cval |= VAC_UART_MODE_PARITY_ENABLE; + bits++; + } + if (cflag & PARODD) + cval |= VAC_UART_MODE_PARITY_ODD; + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(info->tty); + if (!baud) + baud = 9600; /* B0 transition handled in rs_set_termios */ + baud_base = info->state->baud_base; + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) + quot = info->state->custom_divisor; + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + /* If the quotient is ever zero, default to 9600 bps */ + if (!quot) + quot = baud_base / 9600; + info->quot = quot; + info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + serial_out(info, VAC_UART_INT_MASK, info->IER); + + /* + * Set up parity check flag + */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + info->read_status_mask = VAC_UART_STATUS_RX_ERR_OVERRUN | \ + VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_RX_READY; + if (I_INPCK(info->tty)) + info->read_status_mask |= VAC_UART_STATUS_RX_ERR_FRAME | \ + VAC_UART_STATUS_RX_ERR_PARITY; + if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) + info->read_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; + + /* + * Characters to ignore + */ + info->ignore_status_mask = 0; + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= VAC_UART_STATUS_RX_ERR_PARITY | \ + VAC_UART_STATUS_RX_ERR_FRAME; + if (I_IGNBRK(info->tty)) { + info->ignore_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= \ + VAC_UART_STATUS_RX_ERR_OVERRUN; + } + /* + * !!! ignore all characters if CREAD is not set + */ + if ((cflag & CREAD) == 0) + info->ignore_status_mask |= VAC_UART_STATUS_RX_READY; + save_flags(flags); cli(); + + + switch (baud) { + default: + case 9600: + cval |= VAC_UART_MODE_BAUD(7); + break; + case 4800: + cval |= VAC_UART_MODE_BAUD(6); + break; + case 2400: + cval |= VAC_UART_MODE_BAUD(5); + break; + case 1200: + cval |= VAC_UART_MODE_BAUD(4); + break; + case 600: + cval |= VAC_UART_MODE_BAUD(3); + break; + case 300: + cval |= VAC_UART_MODE_BAUD(2); + break; +#ifndef QUAD_UART_SPEED + case 150: +#else + case 38400: +#endif + cval |= VAC_UART_MODE_BAUD(1); + break; +#ifndef QUAD_UART_SPEED + case 75: +#else + case 19200: +#endif + cval |= VAC_UART_MODE_BAUD(0); + break; + } + + /* Baget VAC need some adjustments for computed value */ + cval = vac_uart_mode_fixup(cval); + + serial_outp(info, VAC_UART_MODE, cval); + restore_flags(flags); +} + +static void rs_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_put_char")) + return; + + if (!tty || !info->xmit_buf) + return; + + save_flags(flags); cli(); + if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { + restore_flags(flags); + return; + } + + info->xmit_buf[info->xmit_head++] = ch; + info->xmit_head &= SERIAL_XMIT_SIZE-1; + info->xmit_cnt++; + restore_flags(flags); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !info->xmit_buf) + return; + + save_flags(flags); cli(); + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + restore_flags(flags); +} + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, ret = 0; + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_write")) + return 0; + + if (!tty || !info->xmit_buf || !tmp_buf) + return 0; + + save_flags(flags); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + c = MIN(count, + MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!ret) + ret = -EFAULT; + break; + } + cli(); + c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + info->xmit_head = ((info->xmit_head + c) & + (SERIAL_XMIT_SIZE-1)); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + ret += c; + } + up(&tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, + MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = ((info->xmit_head + c) & + (SERIAL_XMIT_SIZE-1)); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + ret += c; + } + } + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped && + !(info->IER & VAC_UART_INT_TX_EMPTY)) { + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } + return ret; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + int ret; + + if (serial_paranoia_check(info, tty->device, "rs_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) + return 0; + return info->xmit_cnt; +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) + return; + + save_flags(flags); cli(); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + restore_flags(flags); + + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct *tty, char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_send_char")) + return; + + info->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + baget_printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_throttle")) + return; + + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + baget_printk("unthrottle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct async_struct * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + struct serial_state *state = info->state; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = state->type; + tmp.line = state->line; + tmp.port = state->port; + tmp.irq = state->irq; + tmp.flags = state->flags; + tmp.xmit_fifo_size = state->xmit_fifo_size; + tmp.baud_base = state->baud_base; + tmp.close_delay = state->close_delay; + tmp.closing_wait = state->closing_wait; + tmp.custom_divisor = state->custom_divisor; + tmp.hub6 = state->hub6; + if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int set_serial_info(struct async_struct * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct serial_state old_state, *state; + unsigned int i,change_irq,change_port; + int retval = 0; + + if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) + return -EFAULT; + state = info->state; + old_state = *state; + + change_irq = new_serial.irq != state->irq; + change_port = (new_serial.port != state->port) || + (new_serial.hub6 != state->hub6); + + if (!capable(CAP_SYS_ADMIN)) { + if (change_irq || change_port || + (new_serial.baud_base != state->baud_base) || + (new_serial.type != state->type) || + (new_serial.close_delay != state->close_delay) || + (new_serial.xmit_fifo_size != state->xmit_fifo_size) || + ((new_serial.flags & ~ASYNC_USR_MASK) != + (state->flags & ~ASYNC_USR_MASK))) + return -EPERM; + state->flags = ((state->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + info->flags = ((state->flags & ~ASYNC_USR_MASK) | + (info->flags & ASYNC_USR_MASK)); + state->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + new_serial.irq = new_serial.irq; + + if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) || + (new_serial.baud_base == 0) || (new_serial.type < PORT_UNKNOWN) || + (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || + (new_serial.type == PORT_STARTECH)) { + return -EINVAL; + } + + if ((new_serial.type != state->type) || + (new_serial.xmit_fifo_size <= 0)) + new_serial.xmit_fifo_size = + uart_config[state->type].dfl_xmit_fifo_size; + + /* Make sure address is not already in use */ + if (new_serial.type) { + for (i = 0 ; i < NR_PORTS; i++) + if ((state != &rs_table[i]) && + (rs_table[i].port == new_serial.port) && + rs_table[i].type) + return -EADDRINUSE; + } + + if ((change_port || change_irq) && (state->count > 1)) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + state->baud_base = new_serial.baud_base; + state->flags = ((state->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | + (info->flags & ASYNC_INTERNAL_FLAGS)); + state->custom_divisor = new_serial.custom_divisor; + state->type = new_serial.type; + state->close_delay = new_serial.close_delay * HZ/100; + state->closing_wait = new_serial.closing_wait * HZ/100; + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + info->xmit_fifo_size = state->xmit_fifo_size = + new_serial.xmit_fifo_size; + + release_region(state->port,8); + if (change_port || change_irq) { + /* + * We need to shutdown the serial port at the old + * port/irq combination. + */ + shutdown(info); + state->irq = new_serial.irq; + info->port = state->port = new_serial.port; + info->hub6 = state->hub6 = new_serial.hub6; + } + if (state->type != PORT_UNKNOWN) + request_region(state->port,8,"serial(set)"); + + +check_and_exit: + if (!state->port || !state->type) + return 0; + if (info->flags & ASYNC_INITIALIZED) { + if (((old_state.flags & ASYNC_SPD_MASK) != + (state->flags & ASYNC_SPD_MASK)) || + (old_state.custom_divisor != state->custom_divisor)) { + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + change_speed(info); + } + } else + retval = startup(info); + return retval; +} + + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct async_struct * info, unsigned int *value) +{ + unsigned short status; + unsigned int result; + unsigned long flags; + + save_flags(flags); cli(); + status = serial_inw(info, VAC_UART_INT_STATUS); + restore_flags(flags); + result = ((status & VAC_UART_STATUS_TX_EMPTY) ? TIOCSER_TEMT : 0); + return put_user(result,value); +} + + +static int get_modem_info(struct async_struct * info, unsigned int *value) +{ + unsigned int result; + + result = TIOCM_CAR | TIOCM_DSR; + return put_user(result,value); +} + +static int set_modem_info(struct async_struct * info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg; + + if (get_user(arg, value)) + return -EFAULT; + switch (cmd) { + default: + return -EINVAL; + } + return 0; +} + +static int do_autoconfig(struct async_struct * info) +{ + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (info->state->count > 1) + return -EBUSY; + + shutdown(info); + + autoconfig(info->state); + + retval = startup(info); + if (retval) + return retval; + return 0; +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_break")) + return; + + if (!info->port) + return; + save_flags(flags); cli(); + if (break_state == -1) + serial_outp(info, VAC_UART_MODE, + serial_inp(info, VAC_UART_MODE) | \ + VAC_UART_MODE_SEND_BREAK); + else + serial_outp(info, VAC_UART_MODE, + serial_inp(info, VAC_UART_MODE) & \ + ~VAC_UART_MODE_SEND_BREAK); + restore_flags(flags); +} + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + int error; + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct async_icount cprev, cnow; /* kernel counter temps */ + struct serial_icounter_struct *p_cuser; /* user space */ + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCMGET: + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERCONFIG: + return do_autoconfig(info); + + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + if (copy_to_user((struct async_struct *) arg, + info, sizeof(struct async_struct))) + return -EFAULT; + return 0; + + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + save_flags(flags); cli(); + /* note the counters on entry */ + cprev = info->state->icount; + restore_flags(flags); + while (1) { + interruptible_sleep_on(&info->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + save_flags(flags); cli(); + cnow = info->state->icount; /* atomic copy */ + restore_flags(flags); + if (cnow.rng == cprev.rng && + cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && + cnow.cts == cprev.cts) + return -EIO; /* no change => error */ + if ( ((arg & TIOCM_RNG) && + (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && + (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && + (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && + (cnow.cts != cprev.cts)) ) { + return 0; + } + cprev = cnow; + } + /* NOTREACHED */ + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + case TIOCGICOUNT: + save_flags(flags); cli(); + cnow = info->state->icount; + restore_flags(flags); + p_cuser = (struct serial_icounter_struct *) arg; + error = put_user(cnow.cts, &p_cuser->cts); + if (error) return error; + error = put_user(cnow.dsr, &p_cuser->dsr); + if (error) return error; + error = put_user(cnow.rng, &p_cuser->rng); + if (error) return error; + error = put_user(cnow.dcd, &p_cuser->dcd); + if (error) return error; + error = put_user(cnow.rx, &p_cuser->rx); + if (error) return error; + error = put_user(cnow.tx, &p_cuser->tx); + if (error) return error; + error = put_user(cnow.frame, &p_cuser->frame); + if (error) return error; + error = put_user(cnow.overrun, &p_cuser->overrun); + if (error) return error; + error = put_user(cnow.parity, &p_cuser->parity); + if (error) return error; + error = put_user(cnow.brk, &p_cuser->brk); + if (error) return error; + error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); + + if (error) return error; + return 0; + + case TIOCSERGWILD: + case TIOCSERSWILD: + /* "setserial -W" is called in Debian boot */ + printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned int cflag = tty->termios->c_cflag; + + if ( (cflag == old_termios->c_cflag) + && ( RELEVANT_IFLAG(tty->termios->c_iflag) + == RELEVANT_IFLAG(old_termios->c_iflag))) + return; + + change_speed(info); + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } + +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * async structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->device, "rs_close")) + return; + + state = info->state; + + save_flags(flags); cli(); + + if (tty_hung_up_p(filp)) { + DBG_CNT("before DEC-hung"); + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_close ttys%d, count = %d\n", + info->line, state->count); +#endif + if ((tty->count == 1) && (state->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + baget_printk("rs_close: bad serial port count; " + "tty->count is 1, " + "state->count is %d\n", state->count); + state->count = 1; + } + if (--state->count < 0) { + baget_printk("rs_close: bad serial port count for " + "ttys%d: %d\n", + info->line, state->count); + state->count = 0; + } + if (state->count) { + DBG_CNT("before DEC-2"); + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } + info->flags |= ASYNC_CLOSING; + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ASYNC_NORMAL_ACTIVE) + info->state->normal_termios = *tty->termios; + if (info->flags & ASYNC_CALLOUT_ACTIVE) + info->state->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + info->IER &= ~(VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS); + info->read_status_mask &= ~VAC_UART_STATUS_RX_READY; + if (info->flags & ASYNC_INITIALIZED) { + serial_outw(info, VAC_UART_INT_MASK, info->IER); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + rs_wait_until_sent(tty, info->timeout); + } + shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = 0; + if (info->blocked_open) { + if (info->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| + ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + MOD_DEC_USE_COUNT; + restore_flags(flags); +} + +/* + * rs_wait_until_sent() --- wait until the transmitter is empty + */ +static void rs_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long orig_jiffies, char_time; + int lsr; + + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) + return; + + if (info->state->type == PORT_UNKNOWN) + return; + + if (info->xmit_fifo_size == 0) + return; /* Just in case.... */ + + orig_jiffies = jiffies; + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout) + char_time = MIN(char_time, timeout); +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + baget_printk("In rs_wait_until_sent(%d) check=%lu...", + timeout, char_time); + baget_printk("jiff=%lu...", jiffies); +#endif + while (!((lsr = serial_inp(info, VAC_UART_INT_STATUS)) & \ + VAC_UART_STATUS_TX_EMPTY)) { +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + baget_printk("lsr = %d (jiff=%lu)...", lsr, jiffies); +#endif + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(char_time); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + current->state = TASK_RUNNING; +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + baget_printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); +#endif +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void rs_hangup(struct tty_struct *tty) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state = info->state; + + if (serial_paranoia_check(info, tty->device, "rs_hangup")) + return; + + state = info->state; + + rs_flush_buffer(tty); + shutdown(info); + info->event = 0; + state->count = 0; + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct async_struct *info) +{ + DECLARE_WAITQUEUE(wait, current); + struct serial_state *state = info->state; + int retval; + int do_clocal = 0, extra_count = 0; + unsigned long flags; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ASYNC_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ASYNC_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ASYNC_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ASYNC_CALLOUT_ACTIVE) { + if (state->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, state->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + baget_printk("block_til_ready before block: ttys%d, count = %d\n", + state->line, state->count); +#endif + save_flags(flags); cli(); + if (!tty_hung_up_p(filp)) { + extra_count = 1; + state->count--; + } + restore_flags(flags); + info->blocked_open++; + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ASYNC_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + !(info->flags & ASYNC_CLOSING)) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + baget_printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (extra_count) + state->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + baget_printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +static int get_async_struct(int line, struct async_struct **ret_info) +{ + struct async_struct *info; + struct serial_state *sstate; + + sstate = rs_table + line; + sstate->count++; + if (sstate->info) { + *ret_info = sstate->info; + return 0; + } + info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); + if (!info) { + sstate->count--; + return -ENOMEM; + } + memset(info, 0, sizeof(struct async_struct)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + info->magic = SERIAL_MAGIC; + info->port = sstate->port; + info->flags = sstate->flags; + info->xmit_fifo_size = sstate->xmit_fifo_size; + info->line = line; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->state = sstate; + if (sstate->info) { + kfree(info); + *ret_info = sstate->info; + return 0; + } + *ret_info = sstate->info = info; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct async_struct *info; + int retval, line; + unsigned long page; + + MOD_INC_USE_COUNT; + line = MINOR(tty->device) - tty->driver.minor_start; + if ((line < 0) || (line >= NR_PORTS)) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + retval = get_async_struct(line, &info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + tty->driver_data = info; + info->tty = tty; + if (serial_paranoia_check(info, tty->device, "rs_open")) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ + return -ENODEV; + } + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_open %s%d, count = %d\n", + tty->driver.name, info->line, + info->state->count); +#endif + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + if (!tmp_buf) { + page = get_free_page(GFP_KERNEL); + if (!page) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ + return -ENOMEM; + } + if (tmp_buf) + free_page(page); + else + tmp_buf = (unsigned char *) page; + } + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ + return retval; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_open returning after block_til_ready " + "with %d\n", + retval); +#endif + return retval; + } + + if ((info->state->count == 1) && + (info->flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->state->normal_termios; + else + *tty->termios = info->state->callout_termios; + change_speed(info); + } +#ifdef CONFIG_SERIAL_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + change_speed(info); + } +#endif + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_open ttys%d successful...", info->line); +#endif + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline int line_info(char *buf, struct serial_state *state) +{ + struct async_struct *info = state->info, scr_info; + int ret; + + ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", + state->line, uart_config[state->type].name, + state->port, state->irq); + + if (!state->port || (state->type == PORT_UNKNOWN)) { + ret += sprintf(buf+ret, "\n"); + return ret; + } + + /* + * Figure out the current RS-232 lines + */ + if (!info) { + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->port = state->port; + info->flags = state->flags; + info->quot = 0; + info->tty = 0; + } + + if (info->quot) { + ret += sprintf(buf+ret, " baud:%d", + state->baud_base / info->quot); + } + + ret += sprintf(buf+ret, " tx:%d rx:%d", + state->icount.tx, state->icount.rx); + + if (state->icount.frame) + ret += sprintf(buf+ret, " fe:%d", state->icount.frame); + + if (state->icount.parity) + ret += sprintf(buf+ret, " pe:%d", state->icount.parity); + + if (state->icount.brk) + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); + + if (state->icount.overrun) + ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); + + return ret; +} + +int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_table[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * --------------------------------------------------------------------- + * rs_init() and friends + * + * rs_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +/* + * This routine prints out the appropriate serial driver version + * number, and identifies which options were configured into this + * driver. + */ +static _INLINE_ void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s with", serial_name, serial_version); +#ifdef CONFIG_SERIAL_SHARE_IRQ + printk(" SHARE_IRQ"); +#endif +#define SERIAL_OPT +#ifdef CONFIG_SERIAL_DETECT_IRQ + printk(" DETECT_IRQ"); +#endif +#ifdef SERIAL_OPT + printk(" enabled\n"); +#else + printk(" no serial options enabled\n"); +#endif +#undef SERIAL_OPT +} + + +/* + * This routine is called by rs_init() to initialize a specific serial + * port. It determines what type of UART chip this serial port is + * using: 8250, 16450, 16550, 16550A. The important question is + * whether or not this UART is a 16550A or not, since this will + * determine whether or not we can use its FIFO features or not. + */ + +/* + * Functionality of this function is reduced: we already know we have a VAC, + * but still need to perform some important actions (see code :-). + */ +static void autoconfig(struct serial_state * state) +{ + struct async_struct *info, scr_info; + unsigned long flags; + + /* Setting up important parameters */ + state->type = VAC_UART_TYPE; + state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; + + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->port = state->port; + info->flags = state->flags; + + save_flags(flags); cli(); + + /* + Flush VAC input fifo */ + (void)serial_in(info, VAC_UART_RX); + (void)serial_in(info, VAC_UART_RX); + (void)serial_in(info, VAC_UART_RX); + (void)serial_in(info, VAC_UART_RX); + + /* Disable interrupts */ + serial_outp(info, VAC_UART_INT_MASK, 0); + + restore_flags(flags); +} + +int register_serial(struct serial_struct *req); +void unregister_serial(int line); + +EXPORT_SYMBOL(register_serial); +EXPORT_SYMBOL(unregister_serial); + +/* + * Important function for VAC UART check and reanimation. + */ + +static void rs_timer(unsigned long dummy) +{ + static unsigned long last_strobe = 0; + struct async_struct *info; + unsigned int i; + unsigned long flags; + + if ((jiffies - last_strobe) >= RS_STROBE_TIME) { + for (i=1; i < NR_IRQS; i++) { + info = IRQ_ports[i]; + if (!info) + continue; + save_flags(flags); cli(); +#ifdef CONFIG_SERIAL_SHARE_IRQ + if (info->next_port) { + do { + serial_out(info, VAC_UART_INT_MASK, 0); + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, + info->IER); + info = info->next_port; + } while (info); + rs_interrupt(i, NULL, NULL); + } else +#endif /* CONFIG_SERIAL_SHARE_IRQ */ + rs_interrupt_single(i, NULL, NULL); + restore_flags(flags); + } + } + last_strobe = jiffies; + mod_timer(&vacs_timer, jiffies + RS_STROBE_TIME); + + /* + * It looks this code for case we share IRQ with console... + */ + + if (IRQ_ports[0]) { + save_flags(flags); cli(); +#ifdef CONFIG_SERIAL_SHARE_IRQ + rs_interrupt(0, NULL, NULL); +#else + rs_interrupt_single(0, NULL, NULL); +#endif + restore_flags(flags); + + mod_timer(&vacs_timer, jiffies + IRQ_timeout[0] - 2); + } +} + +/* + * The serial driver boot-time initialization code! + */ +int __init rs_init(void) +{ + int i; + struct serial_state * state; + extern void atomwide_serial_init (void); + extern void dualsp_serial_init (void); + +#ifdef CONFIG_ATOMWIDE_SERIAL + atomwide_serial_init (); +#endif +#ifdef CONFIG_DUALSP_SERIAL + dualsp_serial_init (); +#endif + + init_bh(SERIAL_BH, do_serial_bh); + init_timer(&vacs_timer); + vacs_timer.function = rs_timer; + vacs_timer.expires = 0; + + for (i = 0; i < NR_IRQS; i++) { + IRQ_ports[i] = 0; + IRQ_timeout[i] = 0; + } + + +/* + * It is not a good idea to share interrupts with console, + * but it looks we cannot avoid it. + */ +#if 0 + +#ifdef CONFIG_SERIAL_CONSOLE + /* + * The interrupt of the serial console port + * can't be shared. + */ + if (sercons.flags & CON_CONSDEV) { + for(i = 0; i < NR_PORTS; i++) + if (i != sercons.index && + rs_table[i].irq == rs_table[sercons.index].irq) + rs_table[i].irq = 0; + } +#endif + +#endif + show_serial_version(); + + /* Initialize the tty_driver structure */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + serial_driver.driver_name = "serial"; + serial_driver.name = "ttyS"; + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64; + serial_driver.num = NR_PORTS; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.put_char = rs_put_char; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.send_xchar = rs_send_xchar; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + serial_driver.break_ctl = rs_break; + serial_driver.wait_until_sent = rs_wait_until_sent; + serial_driver.read_proc = rs_read_proc; + + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; + callout_driver.name = "cua"; + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + callout_driver.read_proc = 0; + callout_driver.proc_entry = 0; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register serial driver"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver"); + + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + state->magic = SSTATE_MAGIC; + state->line = i; + state->type = PORT_UNKNOWN; + state->custom_divisor = 0; + state->close_delay = 5*HZ/10; + state->closing_wait = 30*HZ; + state->callout_termios = callout_driver.init_termios; + state->normal_termios = serial_driver.init_termios; + state->icount.cts = state->icount.dsr = + state->icount.rng = state->icount.dcd = 0; + state->icount.rx = state->icount.tx = 0; + state->icount.frame = state->icount.parity = 0; + state->icount.overrun = state->icount.brk = 0; + state->irq = state->irq; + if (check_region(state->port,8)) + continue; + if (state->flags & ASYNC_BOOT_AUTOCONF) + autoconfig(state); + } + + /* + * Detect the IRQ only once every port is initialised, + * because some 16450 do not reset to 0 the MCR register. + */ + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + if (state->type == PORT_UNKNOWN) + continue; + printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n", + state->line, + (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", + state->port, state->irq, + uart_config[state->type].name); + } + return 0; +} + +/* + * register_serial and unregister_serial allows for serial ports to be + * configured at run-time, to support PCMCIA modems. + */ +int register_serial(struct serial_struct *req) +{ + int i; + unsigned long flags; + struct serial_state *state; + + save_flags(flags); + cli(); + for (i = 0; i < NR_PORTS; i++) { + if (rs_table[i].port == req->port) + break; + } + if (i == NR_PORTS) { + for (i = 0; i < NR_PORTS; i++) + if ((rs_table[i].type == PORT_UNKNOWN) && + (rs_table[i].count == 0)) + break; + } + if (i == NR_PORTS) { + restore_flags(flags); + return -1; + } + state = &rs_table[i]; + if (rs_table[i].count) { + restore_flags(flags); + printk("Couldn't configure serial #%d (port=%d,irq=%d): " + "device already open\n", i, req->port, req->irq); + return -1; + } + state->irq = req->irq; + state->port = req->port; + state->flags = req->flags; + + autoconfig(state); + if (state->type == PORT_UNKNOWN) { + restore_flags(flags); + printk("register_serial(): autoconfig failed\n"); + return -1; + } + restore_flags(flags); + + printk(KERN_INFO "tty%02d at 0x%04x (irq = %d) is a %s\n", + state->line, state->port, state->irq, + uart_config[state->type].name); + return state->line; +} + +void unregister_serial(int line) +{ + unsigned long flags; + struct serial_state *state = &rs_table[line]; + + save_flags(flags); + cli(); + if (state->info && state->info->tty) + tty_hangup(state->info->tty); + state->type = PORT_UNKNOWN; + printk(KERN_INFO "tty%02d unloaded\n", state->line); + restore_flags(flags); +} + +#ifdef MODULE +int init_module(void) +{ + return rs_init(); +} + +void cleanup_module(void) +{ + unsigned long flags; + int e1, e2; + int i; + + printk("Unloading %s: version %s\n", serial_name, serial_version); + save_flags(flags); + cli(); + + del_timer_sync(&vacs_timer); + remove_bh(SERIAL_BH); + + if ((e1 = tty_unregister_driver(&serial_driver))) + printk("SERIAL: failed to unregister serial driver (%d)\n", + e1); + if ((e2 = tty_unregister_driver(&callout_driver))) + printk("SERIAL: failed to unregister callout driver (%d)\n", + e2); + restore_flags(flags); + + for (i = 0; i < NR_PORTS; i++) { + if (rs_table[i].type != PORT_UNKNOWN) + release_region(rs_table[i].port, 8); + } + if (tmp_buf) { + free_page((unsigned long) tmp_buf); + tmp_buf = NULL; + } +} +#endif /* MODULE */ + + +/* + * ------------------------------------------------------------ + * Serial console driver + * ------------------------------------------------------------ + */ +#ifdef CONFIG_SERIAL_CONSOLE + +#define BOTH_EMPTY (VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_TX_EMPTY) + +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct async_struct *info) +{ + int lsr; + unsigned int tmout = 1000000; + + do { + lsr = serial_inp(info, VAC_UART_INT_STATUS); + if (--tmout == 0) break; + } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); +} + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + */ +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + struct serial_state *ser; + int ier; + unsigned i; + struct async_struct scr_info; /* serial_{in,out} because HUB6 */ + + ser = rs_table + co->index; + scr_info.magic = SERIAL_MAGIC; + scr_info.port = ser->port; + scr_info.flags = ser->flags; + + /* + * First save the IER then disable the interrupts + */ + ier = serial_inp(&scr_info, VAC_UART_INT_MASK); + serial_outw(&scr_info, VAC_UART_INT_MASK, 0x00); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(&scr_info); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_outp(&scr_info, VAC_UART_TX, (unsigned short)*s << 8); + if (*s == 10) { + wait_for_xmitr(&scr_info); + serial_outp(&scr_info, VAC_UART_TX, 13 << 8); + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + wait_for_xmitr(&scr_info); + serial_outp(&scr_info, VAC_UART_INT_MASK, ier); +} + +static kdev_t serial_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +static int __init serial_console_setup(struct console *co, char *options) +{ + struct serial_state *ser; + unsigned cval; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + int quot = 0; + char *s; + struct async_struct scr_info; /* serial_{in,out} because HUB6 */ + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + co->cflag = cflag; + + /* + * Divisor, bytesize and parity + */ + ser = rs_table + co->index; + scr_info.magic = SERIAL_MAGIC; + scr_info.port = ser->port; + scr_info.flags = ser->flags; + + quot = ser->baud_base / baud; + cval = cflag & (CSIZE | CSTOPB); + + cval >>= 4; + + cval &= ~VAC_UART_MODE_PARITY_ENABLE; + if (cflag & PARENB) + cval |= VAC_UART_MODE_PARITY_ENABLE; + if (cflag & PARODD) + cval |= VAC_UART_MODE_PARITY_ODD; + + /* + * Disable UART interrupts, set DTR and RTS high + * and set speed. + */ + switch (baud) { + default: + case 9600: + cval |= VAC_UART_MODE_BAUD(7); + break; + case 4800: + cval |= VAC_UART_MODE_BAUD(6); + break; + case 2400: + cval |= VAC_UART_MODE_BAUD(5); + break; + case 1200: + cval |= VAC_UART_MODE_BAUD(4); + break; + case 600: + cval |= VAC_UART_MODE_BAUD(3); + break; + case 300: + cval |= VAC_UART_MODE_BAUD(2); + break; +#ifndef QUAD_UART_SPEED + case 150: +#else + case 38400: +#endif + cval |= VAC_UART_MODE_BAUD(1); + break; +#ifndef QUAD_UART_SPEED + case 75: +#else + case 19200: +#endif + cval |= VAC_UART_MODE_BAUD(0); + break; + } + + /* Baget VAC need some adjustments for computed value */ + cval = vac_uart_mode_fixup(cval); + + serial_outp(&scr_info, VAC_UART_MODE, cval); + serial_outp(&scr_info, VAC_UART_INT_MASK, 0); + + return 0; +} + +static struct console sercons = { + .name = "ttyS", + .write = serial_console_write, + .device = serial_console_device, + .setup = serial_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ +long __init serial_console_init(long kmem_start, long kmem_end) +{ + register_console(&sercons); + return kmem_start; +} +#endif + +#ifdef CONFIG_KGDB +#undef PRINT_DEBUG_PORT_INFO + +/* + * This is the interface to the remote debugger stub. + * I've put that here to be able to control the serial + * device more directly. + */ + +static int initialized; + +static int rs_debug_init(struct async_struct *info) +{ + int quot; + + autoconfig(info); /* autoconfigure ttyS0, whatever that is */ + +#ifdef PRINT_DEBUG_PORT_INFO + baget_printk("kgdb debug interface:: tty%02d at 0x%04x", + info->line, info->port); + switch (info->type) { + case PORT_8250: + baget_printk(" is a 8250\n"); + break; + case PORT_16450: + baget_printk(" is a 16450\n"); + break; + case PORT_16550: + baget_printk(" is a 16550\n"); + break; + case PORT_16550A: + baget_printk(" is a 16550A\n"); + break; + case PORT_16650: + baget_printk(" is a 16650\n"); + break; + default: + baget_printk(" is of unknown type -- unusable\n"); + break; + } +#endif + + if (info->port == PORT_UNKNOWN) + return -1; + + /* + * Clear all interrupts + */ + + (void)serial_inp(info, VAC_UART_INT_STATUS); + (void)serial_inp(info, VAC_UART_RX); + + /* + * Now, initialize the UART + */ + serial_outp(info,VAC_UART_MODE,VAC_UART_MODE_INITIAL); /* reset DLAB */ + if (info->flags & ASYNC_FOURPORT) { + info->MCR = UART_MCR_DTR | UART_MCR_RTS; + info->MCR_noint = UART_MCR_DTR | UART_MCR_OUT1; + } else { + info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; + info->MCR_noint = UART_MCR_DTR | UART_MCR_RTS; + } + + info->MCR = info->MCR_noint; /* no interrupts, please */ + /* + * and set the speed of the serial port + * (currently hardwired to 9600 8N1 + */ + + quot = info->baud_base / 9600; /* baud rate is fixed to 9600 */ + /* FIXME: if rs_debug interface is needed, we need to set speed here */ + + return 0; +} + +int putDebugChar(char c) +{ + struct async_struct *info = rs_table; + + if (!initialized) { /* need to init device first */ + if (rs_debug_init(info) == 0) + initialized = 1; + else + return 0; + } + + while ((serial_inw(info, VAC_UART_INT_STATUS) & \ + VAC_UART_STATUS_TX_EMPTY) == 0) + ; + serial_out(info, VAC_UART_TX, (unsigned short)c << 8); + + return 1; +} + +char getDebugChar(void) +{ + struct async_struct *info = rs_table; + + if (!initialized) { /* need to init device first */ + if (rs_debug_init(info) == 0) + initialized = 1; + else + return 0; + } + while (!(serial_inw(info, VAC_UART_INT_STATUS) & \ + VAC_UART_STATUS_RX_READY)) + ; + + return(serial_inp(info, VAC_UART_RX)); +} + +#endif /* CONFIG_KGDB */ diff -urN linux-2.4.21/drivers/char/wdt_pci.c linux-2.4.22/drivers/char/wdt_pci.c --- linux-2.4.21/drivers/char/wdt_pci.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.22/drivers/char/wdt_pci.c 2003-08-25 04:44:41.000000000 -0700 @@ -557,7 +557,7 @@ ret = register_reboot_notifier (&wdtpci_notifier); if (ret) { - printk (KERN_ERR PFX "can't misc_register on minor=%d\n", WATCHDOG_MINOR); + printk (KERN_ERR PFX "can't register_reboot_notifier on minor=%d\n", WATCHDOG_MINOR); goto out_misc; } #ifdef CONFIG_WDT_501 diff -urN linux-2.4.21/drivers/gsc/dino.c linux-2.4.22/drivers/gsc/dino.c --- linux-2.4.21/drivers/gsc/dino.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/gsc/dino.c 2003-08-25 04:44:41.000000000 -0700 @@ -251,7 +251,7 @@ unsigned long flags; \ spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \ /* tell HW which IO Port address */ \ - gsc_writel((u32) addr & ~3, d->base_addr + DINO_PCI_ADDR); \ + gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \ /* generate I/O PORT read cycle */ \ v = gsc_read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \ spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \ @@ -267,7 +267,7 @@ { \ unsigned long flags; \ spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \ - /* tell HW which CFG address */ \ + /* tell HW which IO port address */ \ gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \ /* generate cfg write cycle */ \ gsc_write##type(cpu_to_le##size(val), d->base_addr+DINO_IO_DATA+(addr&mask)); \ @@ -467,7 +467,7 @@ * to set up the addresses of the devices on this bus. */ #define _8MB 0x00800000UL -static void __init +static int __init dino_card_setup(struct pci_bus *bus, unsigned long base_addr) { int i; @@ -482,7 +482,7 @@ 0xffffffffffffffffUL &~ _8MB, _8MB, NULL, NULL) < 0) { printk(KERN_WARNING "Dino: Failed to allocate memory region\n"); - return; + return -ENODEV; } bus->resource[1] = res; bus->resource[0] = &(dino_dev->hba.io_space); @@ -495,6 +495,7 @@ gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN); pcibios_assign_unassigned_resources(bus); + return 0; } static void __init diff -urN linux-2.4.21/drivers/hotplug/Config.in linux-2.4.22/drivers/hotplug/Config.in --- linux-2.4.21/drivers/hotplug/Config.in 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/Config.in 2003-08-25 04:44:41.000000000 -0700 @@ -11,6 +11,7 @@ if [ "$CONFIG_X86_IO_APIC" = "y" ]; then dep_tristate ' IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86 fi -dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_ACPI $CONFIG_HOTPLUG_PCI - +if [ "$CONFIG_ACPI_INTERPRETER" ]; then + dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_HOTPLUG_PCI +fi endmenu diff -urN linux-2.4.21/drivers/hotplug/Makefile linux-2.4.22/drivers/hotplug/Makefile --- linux-2.4.21/drivers/hotplug/Makefile 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -27,10 +27,6 @@ ibmphp_res.o \ ibmphp_hpc.o -ifdef CONFIG_HOTPLUG_PCI_ACPI - EXTRA_CFLAGS += -D_LINUX -I$(CURDIR)/../acpi -endif - acpiphp_objs := acpiphp_core.o \ acpiphp_glue.o \ acpiphp_pci.o \ diff -urN linux-2.4.21/drivers/hotplug/acpiphp.h linux-2.4.22/drivers/hotplug/acpiphp.h --- linux-2.4.21/drivers/hotplug/acpiphp.h 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/acpiphp.h 2003-08-25 04:44:41.000000000 -0700 @@ -5,8 +5,8 @@ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (c) 2001 IBM Corp. * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com) - * Copyright (c) 2002 NEC Corporation + * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) + * Copyright (c) 2002,2003 NEC Corporation * * All rights reserved. * @@ -26,15 +26,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Send feedback to , - * , - * + * * */ #ifndef _ACPIPHP_H #define _ACPIPHP_H -#include "include/acpi.h" +#include #include "pci_hotplug.h" #if ACPI_CA_VERSION < 0x20020201 @@ -71,7 +70,7 @@ return AE_OK; } #else /* ACPI_CA_VERSION < 0x20020201 */ -#include "acpi_bus.h" +#include #endif /* compatibility stuff for ACPI CA */ @@ -107,7 +106,7 @@ #define SLOT_MAGIC 0x67267322 /* name size which is used for entries in pcihpfs */ -#define SLOT_NAME_SIZE 32 /* ACPI{_SUN}-{BUS}:{DEV} */ +#define SLOT_NAME_SIZE 16 /* {_SUN} */ struct acpiphp_bridge; struct acpiphp_slot; @@ -270,11 +269,7 @@ #define FUNC_HAS_PS2 (0x00000040) #define FUNC_HAS_PS3 (0x00000080) -/* not yet */ -#define SLOT_SUPPORT_66MHZ (0x00010000) -#define SLOT_SUPPORT_100MHZ (0x00020000) -#define SLOT_SUPPORT_133MHZ (0x00040000) -#define SLOT_SUPPORT_PCIX (0x00080000) +#define FUNC_EXISTS (0x10000000) /* to make sure we call _EJ0 only for existing funcs */ /* function prototypes */ diff -urN linux-2.4.21/drivers/hotplug/acpiphp_core.c linux-2.4.22/drivers/hotplug/acpiphp_core.c --- linux-2.4.21/drivers/hotplug/acpiphp_core.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/acpiphp_core.c 2003-08-25 04:44:41.000000000 -0700 @@ -5,8 +5,8 @@ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (c) 2001 IBM Corp. * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com) - * Copyright (c) 2002 NEC Corporation + * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) + * Copyright (c) 2002,2003 NEC Corporation * * All rights reserved. * @@ -26,8 +26,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Send feedback to , - * , - * + * * */ @@ -57,7 +56,7 @@ static int num_slots; #define DRIVER_VERSION "0.4" -#define DRIVER_AUTHOR "Greg Kroah-Hartman , Takayoshi Kochi " +#define DRIVER_AUTHOR "Greg Kroah-Hartman , Takayoshi Kochi " #define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver" MODULE_AUTHOR(DRIVER_AUTHOR); @@ -376,10 +375,8 @@ */ static void make_slot_name (struct slot *slot) { - snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "ACPI%d-%02x:%02x", - slot->acpi_slot->sun, - slot->acpi_slot->bridge->bus, - slot->acpi_slot->device); + snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%u", + slot->acpi_slot->sun); } /** diff -urN linux-2.4.21/drivers/hotplug/acpiphp_glue.c linux-2.4.22/drivers/hotplug/acpiphp_glue.c --- linux-2.4.21/drivers/hotplug/acpiphp_glue.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/acpiphp_glue.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,9 +1,9 @@ /* * ACPI PCI HotPlug glue functions to ACPI CA subsystem * - * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com) + * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (c) 2002 NEC Corporation + * Copyright (c) 2002,2003 NEC Corporation * * All rights reserved. * @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to + * Send feedback to * */ @@ -230,11 +230,11 @@ * TBD: _TRA, etc. */ static void -decode_acpi_resource (acpi_resource *resource, struct acpiphp_bridge *bridge) +decode_acpi_resource (struct acpi_resource *resource, struct acpiphp_bridge *bridge) { - acpi_resource_address16 *address16_data; - acpi_resource_address32 *address32_data; - acpi_resource_address64 *address64_data; + struct acpi_resource_address16 *address16_data; + struct acpi_resource_address32 *address32_data; + struct acpi_resource_address64 *address64_data; struct pci_resource *res; u32 resource_type, producer_consumer, address_length; @@ -252,7 +252,7 @@ switch (resource->id) { case ACPI_RSTYPE_ADDRESS16: - address16_data = (acpi_resource_address16 *)&resource->data; + address16_data = (struct acpi_resource_address16 *)&resource->data; resource_type = address16_data->resource_type; producer_consumer = address16_data->producer_consumer; min_address_range = address16_data->min_address_range; @@ -264,7 +264,7 @@ break; case ACPI_RSTYPE_ADDRESS32: - address32_data = (acpi_resource_address32 *)&resource->data; + address32_data = (struct acpi_resource_address32 *)&resource->data; resource_type = address32_data->resource_type; producer_consumer = address32_data->producer_consumer; min_address_range = address32_data->min_address_range; @@ -276,7 +276,7 @@ break; case ACPI_RSTYPE_ADDRESS64: - address64_data = (acpi_resource_address64 *)&resource->data; + address64_data = (struct acpi_resource_address64 *)&resource->data; resource_type = address64_data->resource_type; producer_consumer = address64_data->producer_consumer; min_address_range = address64_data->min_address_range; @@ -296,7 +296,7 @@ break; } - resource = (acpi_resource *)((char*)resource + resource->length); + resource = (struct acpi_resource *)((char*)resource + resource->length); if (found && producer_consumer == ACPI_PRODUCER && address_length > 0) { switch (resource_type) { @@ -392,10 +392,10 @@ #if ACPI_CA_VERSION < 0x20020201 acpi_buffer buffer; #else - acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL}; + struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, + .pointer = NULL}; #endif - acpi_object *package; + union acpi_object *package; int i; /* default numbers */ @@ -425,7 +425,7 @@ return; } - package = (acpi_object *) buffer.pointer; + package = (union acpi_object *) buffer.pointer; if (!package || package->type != ACPI_TYPE_PACKAGE || package->package.count != 4 || !package->package.elements) { @@ -497,8 +497,8 @@ #if ACPI_CA_VERSION < 0x20020201 acpi_buffer buffer; #else - acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL}; + struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, + .pointer = NULL}; #endif struct acpiphp_bridge *bridge; @@ -613,6 +613,7 @@ bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->io_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("16bit I/O range: %04x-%04x\n", @@ -627,6 +628,7 @@ bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->io_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("32bit I/O range: %08x-%08x\n", @@ -648,6 +650,7 @@ bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->mem_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("32bit Memory range: %08x-%08x\n", @@ -667,6 +670,7 @@ bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->p_mem_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("32bit Prefetchable memory range: %08x-%08x\n", @@ -682,6 +686,7 @@ bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1); if (!bridge->p_mem_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n", @@ -747,7 +752,7 @@ /* find hot-pluggable slots, and then find P2P bridge */ -static int add_bridges (acpi_handle *handle) +static int add_bridge (acpi_handle handle) { acpi_status status; unsigned long tmp; @@ -802,36 +807,11 @@ } -/* callback routine to enumerate all the bridges in ACPI namespace */ -static acpi_status -find_host_bridge (acpi_handle handle, u32 lvl, void *context, void **rv) +static void remove_bridge (acpi_handle handle) { - acpi_status status; - acpi_device_info info; - char objname[5]; - acpi_buffer buffer = { .length = sizeof(objname), - .pointer = objname }; - - status = acpi_get_object_info(handle, &info); - if (ACPI_FAILURE(status)) { - dbg("%s: failed to get bridge information\n", __FUNCTION__); - return AE_OK; /* continue */ - } - - info.hardware_id[sizeof(info.hardware_id)-1] = '\0'; - - /* TBD use acpi_get_devices() API */ - if (info.current_status && - (info.valid & ACPI_VALID_HID) && - strcmp(info.hardware_id, ACPI_PCI_HOST_HID) == 0) { - acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); - dbg("checking PCI-hotplug capable bridges under [%s]\n", objname); - add_bridges(handle); - } - return AE_OK; + /* No-op for now .. */ } - static int power_on_slot (struct acpiphp_slot *slot) { acpi_status status; @@ -872,8 +852,8 @@ acpi_status status; struct acpiphp_func *func; struct list_head *l; - acpi_object_list arg_list; - acpi_object arg; + struct acpi_object_list arg_list; + union acpi_object arg; int retval = 0; @@ -884,9 +864,7 @@ list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - if (func->flags & FUNC_HAS_PS3) { - dbg("%s: executing _PS3 on %s\n", __FUNCTION__, - func->pci_dev->slot_name); + if (func->flags & (FUNC_HAS_PS3 | FUNC_EXISTS)) { status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); if (ACPI_FAILURE(status)) { warn("%s: _PS3 failed\n", __FUNCTION__); @@ -899,10 +877,8 @@ list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - if (func->flags & FUNC_HAS_EJ0) { - dbg("%s: executing _EJ0 on %s\n", __FUNCTION__, - func->pci_dev->slot_name); - + /* We don't want to call _EJ0 on non-existing functions. */ + if (func->flags & (FUNC_HAS_EJ0 | FUNC_EXISTS)) { /* _EJ0 method take one argument */ arg_list.count = 1; arg_list.pointer = &arg; @@ -915,6 +891,7 @@ retval = -1; goto err_exit; } + func->flags &= (~FUNC_EXISTS); } } @@ -996,6 +973,8 @@ retval = acpiphp_configure_function(func); if (retval) goto err_exit; + + func->flags |= FUNC_EXISTS; } slot->flags |= SLOT_ENABLED; @@ -1101,8 +1080,8 @@ { struct acpiphp_bridge *bridge; char objname[64]; - acpi_buffer buffer = { .length = sizeof(objname), - .pointer = objname }; + struct acpi_buffer buffer = { .length = sizeof(objname), + .pointer = objname }; bridge = (struct acpiphp_bridge *)context; @@ -1152,8 +1131,8 @@ { struct acpiphp_func *func; char objname[64]; - acpi_buffer buffer = { .length = sizeof(objname), - .pointer = objname }; + struct acpi_buffer buffer = { .length = sizeof(objname), + .pointer = objname }; acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); @@ -1190,25 +1169,26 @@ } +static struct acpi_pci_driver acpi_pci_hp_driver = { + .add = add_bridge, + .remove = remove_bridge, +}; + /** * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures * */ int acpiphp_glue_init (void) { - acpi_status status; + int num; if (list_empty(&pci_root_buses)) return -1; - status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_host_bridge, - NULL, NULL); + num = acpi_pci_register_driver(&acpi_pci_hp_driver); - if (ACPI_FAILURE(status)) { - err("%s: acpi_walk_namespace() failed\n", __FUNCTION__); + if (num <= 0) return -1; - } return 0; } @@ -1407,7 +1387,7 @@ if (sta != ACPI_STA_ALL) { retval = acpiphp_disable_slot(slot); if (retval) { - err("Error occured in enabling\n"); + err("Error occurred in enabling\n"); up(&slot->crit_sect); goto err_exit; } @@ -1418,7 +1398,7 @@ if (sta == ACPI_STA_ALL) { retval = acpiphp_enable_slot(slot); if (retval) { - err("Error occured in enabling\n"); + err("Error occurred in enabling\n"); up(&slot->crit_sect); goto err_exit; } @@ -1450,7 +1430,7 @@ /* * attention LED ON: 1 - * OFF: 0 + * OFF: 0 * * TBD * no direct attention led status information via ACPI diff -urN linux-2.4.21/drivers/hotplug/acpiphp_pci.c linux-2.4.22/drivers/hotplug/acpiphp_pci.c --- linux-2.4.21/drivers/hotplug/acpiphp_pci.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/acpiphp_pci.c 2003-08-25 04:44:41.000000000 -0700 @@ -4,7 +4,7 @@ * Copyright (c) 1995,2001 Compaq Computer Corporation * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (c) 2001,2002 IBM Corp. - * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com) + * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (c) 2002 NEC Corporation * @@ -25,7 +25,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to + * Send feedback to * */ diff -urN linux-2.4.21/drivers/hotplug/acpiphp_res.c linux-2.4.22/drivers/hotplug/acpiphp_res.c --- linux-2.4.21/drivers/hotplug/acpiphp_res.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/acpiphp_res.c 2003-08-25 04:44:41.000000000 -0700 @@ -5,7 +5,7 @@ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (c) 2001 IBM Corp. * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com) + * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (c) 2002 NEC Corporation * * All rights reserved. @@ -25,7 +25,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to , + * Send feedback to , * */ diff -urN linux-2.4.21/drivers/hotplug/ibmphp_ebda.c linux-2.4.22/drivers/hotplug/ibmphp_ebda.c --- linux-2.4.21/drivers/hotplug/ibmphp_ebda.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/hotplug/ibmphp_ebda.c 2003-08-25 04:44:41.000000000 -0700 @@ -292,6 +292,7 @@ rio_complete = 0; hs_complete = 0; + /* FIXME: This is x86-32 specific, and even then PC specific.. */ io_mem = ioremap ((0x40 << 4) + 0x0e, 2); if (!io_mem ) return -ENOMEM; @@ -299,6 +300,9 @@ iounmap (io_mem); debug ("returned ebda segment: %x\n", ebda_seg); + if(ebda_seg == 0) /* No EBDA */ + return -ENOENT; + io_mem = ioremap (ebda_seg<<4, 65000); if (!io_mem ) return -ENOMEM; diff -urN linux-2.4.21/drivers/i2c/Config.in linux-2.4.22/drivers/i2c/Config.in --- linux-2.4.21/drivers/i2c/Config.in 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/i2c/Config.in 2003-08-25 04:44:41.000000000 -0700 @@ -49,6 +49,11 @@ dep_tristate 'Keywest I2C interface in Apple Core99 machines' CONFIG_I2C_KEYWEST $CONFIG_I2C fi + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + dep_tristate 'SiByte SMBus interface' CONFIG_I2C_ALGO_SIBYTE $CONFIG_I2C + dep_tristate ' MAX1617 Temperature Sensor' CONFIG_I2C_MAX1617 $CONFIG_I2C_ALGO_SIBYTE + fi + # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here diff -urN linux-2.4.21/drivers/i2c/Makefile linux-2.4.22/drivers/i2c/Makefile --- linux-2.4.21/drivers/i2c/Makefile 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/i2c/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -5,7 +5,7 @@ O_TARGET := i2c.o export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \ - i2c-algo-ite.o i2c-proc.o + i2c-algo-ite.o i2c-proc.o i2c-algo-sibyte.o obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o @@ -21,6 +21,8 @@ obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o +obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o i2c-sibyte.o +obj-$(CONFIG_I2C_MAX1617) += i2c-max1617.o # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here diff -urN linux-2.4.21/drivers/i2c/i2c-algo-bit.c linux-2.4.22/drivers/i2c/i2c-algo-bit.c --- linux-2.4.21/drivers/i2c/i2c-algo-bit.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/i2c/i2c-algo-bit.c 2003-08-25 04:44:41.000000000 -0700 @@ -609,7 +609,7 @@ int __init i2c_algo_bit_init (void) { - printk("i2c-algo-bit.o: i2c bit algorithm module\n"); + printk(KERN_INFO "i2c-algo-bit.o: i2c bit algorithm module\n"); return 0; } diff -urN linux-2.4.21/drivers/i2c/i2c-algo-sibyte.c linux-2.4.22/drivers/i2c/i2c-algo-sibyte.c --- linux-2.4.21/drivers/i2c/i2c-algo-sibyte.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/i2c/i2c-algo-sibyte.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,231 @@ +/* ------------------------------------------------------------------------- */ +/* i2c-algo-sibyte.c i2c driver algorithms for bit-shift adapters */ +/* ------------------------------------------------------------------------- */ +/* Copyright (C) 2001,2002,2003 Broadcom Corporation + Copyright (C) 1995-2000 Simon G. Vogl + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU 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. */ +/* ------------------------------------------------------------------------- */ + +/* With some changes from Kyösti Mälkki and even + Frodo Looijaard . */ + +/* Ported for SiByte SOCs by Broadcom Corporation. */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +/* ----- global defines ----------------------------------------------- */ +#define SMB_CSR(a,r) ((long)(a->reg_base + r)) + +/* ----- global variables --------------------------------------------- */ + +/* module parameters: + */ +static int bit_scan=0; /* have a look at what's hanging 'round */ + + +static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data * data) +{ + struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; + int data_bytes = 0; + int error; + + while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY) + ; + + switch (size) { + case I2C_SMBUS_QUICK: + csr_out32((V_SMB_ADDR(addr) | (read_write == I2C_SMBUS_READ ? M_SMB_QDATA : 0) | + V_SMB_TT_QUICKCMD), SMB_CSR(adap, R_SMB_START)); + break; + case I2C_SMBUS_BYTE: + if (read_write == I2C_SMBUS_READ) { + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_RD1BYTE), + SMB_CSR(adap, R_SMB_START)); + data_bytes = 1; + } else { + csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR1BYTE), + SMB_CSR(adap, R_SMB_START)); + } + break; + case I2C_SMBUS_BYTE_DATA: + csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); + if (read_write == I2C_SMBUS_READ) { + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD1BYTE), + SMB_CSR(adap, R_SMB_START)); + data_bytes = 1; + } else { + csr_out32(V_SMB_LB(data->byte), SMB_CSR(adap, R_SMB_DATA)); + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE), + SMB_CSR(adap, R_SMB_START)); + } + break; + case I2C_SMBUS_WORD_DATA: + csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); + if (read_write == I2C_SMBUS_READ) { + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD2BYTE), + SMB_CSR(adap, R_SMB_START)); + data_bytes = 2; + } else { + csr_out32(V_SMB_LB(data->word & 0xff), SMB_CSR(adap, R_SMB_DATA)); + csr_out32(V_SMB_MB(data->word >> 8), SMB_CSR(adap, R_SMB_DATA)); + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE), + SMB_CSR(adap, R_SMB_START)); + } + break; + default: + return -1; /* XXXKW better error code? */ + } + + while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY) + ; + + error = csr_in32(SMB_CSR(adap, R_SMB_STATUS)); + if (error & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS)); + return -1; /* XXXKW better error code? */ + } + + if (data_bytes == 1) + data->byte = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xff; + if (data_bytes == 2) + data->word = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xffff; + + return 0; +} + +static int algo_control(struct i2c_adapter *adapter, + unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static u32 bit_func(struct i2c_adapter *adap) +{ + return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA); +} + + +/* -----exported algorithm data: ------------------------------------- */ + +static struct i2c_algorithm i2c_sibyte_algo = { + "SiByte algorithm", + I2C_ALGO_SIBYTE, + NULL, /* master_xfer */ + smbus_xfer, /* smbus_xfer */ + NULL, /* slave_xmit */ + NULL, /* slave_recv */ + algo_control, /* ioctl */ + bit_func, /* functionality */ +}; + +/* + * registering functions to load algorithms at runtime + */ +int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) +{ + int i; + struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; + + /* register new adapter to i2c module... */ + + i2c_adap->id |= i2c_sibyte_algo.id; + i2c_adap->algo = &i2c_sibyte_algo; + + /* Set the frequency to 100 kHz */ + csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); + csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); + + /* scan bus */ + if (bit_scan) { + union i2c_smbus_data data; + int rc; + printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n", + i2c_adap->name); + for (i = 0x00; i < 0x7f; i++) { + /* XXXKW is this a realistic probe? */ + rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE_DATA, &data); + if (!rc) { + printk("(%02x)",i); + } else + printk("."); + } + printk("\n"); + } + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif + i2c_add_adapter(i2c_adap); + + return 0; +} + + +int i2c_sibyte_del_bus(struct i2c_adapter *adap) +{ + int res; + + if ((res = i2c_del_adapter(adap)) < 0) + return res; + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif + return 0; +} + +int __init i2c_algo_sibyte_init (void) +{ + printk("i2c-algo-sibyte.o: i2c SiByte algorithm module\n"); + return 0; +} + + +EXPORT_SYMBOL(i2c_sibyte_add_bus); +EXPORT_SYMBOL(i2c_sibyte_del_bus); + +#ifdef MODULE +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); +MODULE_PARM(bit_scan, "i"); +MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); +MODULE_LICENSE("GPL"); + +int init_module(void) +{ + return i2c_algo_sibyte_init(); +} + +void cleanup_module(void) +{ +} +#endif diff -urN linux-2.4.21/drivers/i2c/i2c-core.c linux-2.4.22/drivers/i2c/i2c-core.c --- linux-2.4.21/drivers/i2c/i2c-core.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/i2c/i2c-core.c 2003-08-25 04:44:41.000000000 -0700 @@ -1264,7 +1264,7 @@ static int __init i2c_init(void) { - printk("i2c-core.o: i2c core module\n"); + printk(KERN_INFO "i2c-core.o: i2c core module\n"); memset(adapters,0,sizeof(adapters)); memset(drivers,0,sizeof(drivers)); adap_count=0; @@ -1311,6 +1311,15 @@ #ifdef CONFIG_I2C_RPXLITE extern int i2c_rpx_init(void); #endif + +#ifdef CONFIG_I2C_ALGO_SIBYTE + extern int i2c_algo_sibyte_init(void); + extern int i2c_sibyte_init(void); +#endif +#ifdef CONFIG_I2C_MAX1617 + extern int i2c_max1617_init(void); +#endif + #ifdef CONFIG_I2C_PROC extern int sensors_init(void); #endif @@ -1356,6 +1365,15 @@ i2c_rpx_init(); #endif + /* --------------------- SiByte -------- */ +#ifdef CONFIG_I2C_ALGO_SIBYTE + i2c_algo_sibyte_init(); + i2c_sibyte_init(); +#endif +#ifdef CONFIG_I2C_MAX1617 + i2c_max1617_init(); +#endif + /* -------------- proc interface ---- */ #ifdef CONFIG_I2C_PROC sensors_init(); diff -urN linux-2.4.21/drivers/i2c/i2c-dev.c linux-2.4.22/drivers/i2c/i2c-dev.c --- linux-2.4.21/drivers/i2c/i2c-dev.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/i2c/i2c-dev.c 2003-08-25 04:44:41.000000000 -0700 @@ -219,6 +219,7 @@ struct i2c_smbus_ioctl_data data_arg; union i2c_smbus_data temp; struct i2c_msg *rdwr_pa; + u8 **data_ptrs; int i,datasize,res; unsigned long funcs; @@ -248,7 +249,7 @@ return (copy_to_user((unsigned long *)arg,&funcs, sizeof(unsigned long)))?-EFAULT:0; - case I2C_RDWR: + case I2C_RDWR: if (copy_from_user(&rdwr_arg, (struct i2c_rdwr_ioctl_data *)arg, sizeof(rdwr_arg))) @@ -265,21 +266,28 @@ if (rdwr_pa == NULL) return -ENOMEM; + if (copy_from_user(rdwr_pa, rdwr_arg.msgs, + rdwr_arg.nmsgs * sizeof(struct i2c_msg))) { + kfree(rdwr_pa); + return -EFAULT; + } + + data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *), + GFP_KERNEL); + if (data_ptrs == NULL) { + kfree(rdwr_pa); + return -ENOMEM; + } + res = 0; for( i=0; i 8192) { res = -EINVAL; break; } + data_ptrs[i] = rdwr_pa[i].buf; rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL); if(rdwr_pa[i].buf == NULL) { @@ -287,10 +295,11 @@ break; } if(copy_from_user(rdwr_pa[i].buf, - rdwr_arg.msgs[i].buf, + data_ptrs[i], rdwr_pa[i].len)) { - res = -EFAULT; + ++i; /* Needs to be kfreed too */ + res = -EFAULT; break; } } @@ -298,21 +307,20 @@ int j; for (j = 0; j < i; ++j) kfree(rdwr_pa[j].buf); + kfree(data_ptrs); kfree(rdwr_pa); return res; } - if (!res) - { - res = i2c_transfer(client->adapter, - rdwr_pa, - rdwr_arg.nmsgs); - } + + res = i2c_transfer(client->adapter, + rdwr_pa, + rdwr_arg.nmsgs); while(i-- > 0) { if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) { if(copy_to_user( - rdwr_arg.msgs[i].buf, + data_ptrs[i], rdwr_pa[i].buf, rdwr_pa[i].len)) { @@ -321,6 +329,7 @@ } kfree(rdwr_pa[i].buf); } + kfree(data_ptrs); kfree(rdwr_pa); return res; diff -urN linux-2.4.21/drivers/i2c/i2c-max1617.c linux-2.4.22/drivers/i2c/i2c-max1617.c --- linux-2.4.21/drivers/i2c/i2c-max1617.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/i2c/i2c-max1617.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * SMBus/I2C device driver for the MAX1617 temperature sensor + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define IF_NAME "max1617" + +#define MAX1617_SMBUS_DEV 0x2A +#define MAX1617_LOCAL 0 +#define MAX1617_REMOTE 1 +#define MAX1617_STATUS 2 +#define MAX1617_POLL_PERIOD 10 + +static int max1617_verbose = 0; +static int max1617_polling = 1; + +/* Addresses to scan */ +static unsigned short normal_i2c[] = {MAX1617_SMBUS_DEV, I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; +static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c, normal_i2c_range, + probe, probe_range, + ignore, ignore_range, + force +}; + +struct max1617_info { + struct i2c_client *client; + struct timer_list timer; + int local; + int remote; +}; + +static int max1617_probe(struct i2c_adapter *adap); +static int max1617_detach(struct i2c_client *device); +static int max1617_command(struct i2c_client *device, unsigned int cmd, void *arg); +static void max1617_inc_use(struct i2c_client *device); +static void max1617_dec_use(struct i2c_client *device); + +struct i2c_driver i2c_driver_max1617 = { + name: IF_NAME, + id: I2C_DRIVERID_MAX1617, + flags: I2C_DF_NOTIFY, + attach_adapter: max1617_probe, + detach_client: max1617_detach, + command: max1617_command, + inc_use: max1617_inc_use, + dec_use: max1617_dec_use +}; +\ +static int max1617_read(struct i2c_client *client, unsigned char subaddr) +{ + return i2c_smbus_read_byte_data(client, subaddr); +} + +/* poll the device, check for temperature/status changes */ +static void max1617_update(unsigned long arg) +{ + struct max1617_info *m = (struct max1617_info *)arg; + int status, remote, local; + char statstr[50]; + + status = max1617_read(m->client, MAX1617_STATUS); + remote = max1617_read(m->client, MAX1617_REMOTE); + local = max1617_read(m->client, MAX1617_LOCAL); + if (status < 0 || remote < 0 || local < 0) { + printk(KERN_ERR IF_NAME ": sensor device did not respond.\n"); + } else { + statstr[0] = 0; + if (status & 0x80) strcat(statstr,"Busy "); + if (status & 0x40) strcat(statstr,"HiTempLcl "); + if (status & 0x20) strcat(statstr,"LoTempLcl "); + if (status & 0x10) strcat(statstr,"HiTempRem "); + if (status & 0x08) strcat(statstr,"LoTempRem "); + if (status & 0x04) strcat(statstr,"Fault "); + + if (max1617_verbose || (local != m->local) || (remote != m->remote)) { + printk(KERN_DEBUG IF_NAME ": Temperature - CPU: %dC Board: %dC Status:%02X [ %s]\n", + remote, local, status, statstr); + } + m->local = local; + m->remote = remote; + mod_timer(&m->timer, jiffies + (HZ * MAX1617_POLL_PERIOD)); + } +} + +/* attach to an instance of the device that was probed on a bus */ +static int max1617_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) +{ + struct max1617_info *m; + struct i2c_client *client; + int err; + + client = kmalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + client->adapter = adap; + client->addr = addr; + client->driver = &i2c_driver_max1617; + sprintf(client->name, "%s-%x", IF_NAME, addr); + if ((err = i2c_attach_client(client)) < 0) { + kfree(client); + return err; + } + + m = kmalloc(sizeof(*m), GFP_KERNEL); + if (m == NULL) { + i2c_detach_client(client); + kfree(client); + return -ENOMEM; + } + m->client = client; + m->remote = m->local = 0; + init_timer(&m->timer); + m->timer.data = (unsigned long)m; + m->timer.function = max1617_update; + if (max1617_polling) { + m->timer.expires = jiffies + (HZ * MAX1617_POLL_PERIOD); + add_timer(&m->timer); + } + client->data = m; + return 0; +} + +/* initiate probing on a particular bus */ +static int max1617_probe(struct i2c_adapter *adap) +{ + /* Look for this device on the given adapter (bus) */ + if (adap->id == (I2C_ALGO_SIBYTE | I2C_HW_SIBYTE)) + return i2c_probe(adap, &addr_data, &max1617_attach); + else + return 0; +} + +static int max1617_detach(struct i2c_client *device) +{ + struct max1617_info *m = (struct max1617_info *)device->data; + int rc = 0; + + if ((rc = i2c_detach_client(device)) != 0) { + printk(IF_NAME "detach failed: %d\n", rc); + } else { + kfree(device); + if (max1617_polling) + del_timer(&m->timer); + kfree(m); + } + return rc; +} + +static int max1617_command(struct i2c_client *device, unsigned int cmd, void *arg) +{ + return 0; +} + +static void max1617_inc_use(struct i2c_client *client) +{ +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif +} + +static void max1617_dec_use(struct i2c_client *client) +{ +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif +} + +void i2c_max1617_init(void) +{ + i2c_add_driver(&i2c_driver_max1617); +} + +EXPORT_NO_SYMBOLS; + +#ifdef MODULE +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("Max 1617 temperature sensor for SiByte SOC boards"); +MODULE_LICENSE("GPL"); + +int init_module(void) +{ + i2c_max1617_init(); + return 0; +} + +void cleanup_module(void) +{ + i2c_del_driver(&i2c_driver_max1617); +} +#endif diff -urN linux-2.4.21/drivers/i2c/i2c-sibyte.c linux-2.4.22/drivers/i2c/i2c-sibyte.c --- linux-2.4.21/drivers/i2c/i2c-sibyte.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/i2c/i2c-sibyte.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +static int sibyte_reg(struct i2c_client *client) +{ + return 0; +} + +static int sibyte_unreg(struct i2c_client *client) +{ + return 0; +} + +static void sibyte_inc_use(struct i2c_adapter *adap) +{ +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif +} + +static void sibyte_dec_use(struct i2c_adapter *adap) +{ +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif +} + +static struct i2c_algo_sibyte_data sibyte_board_data[2] = { + { NULL, 0, (void *)(KSEG1+A_SMB_BASE(0)) }, + { NULL, 1, (void *)(KSEG1+A_SMB_BASE(1)) } +}; + +static struct i2c_adapter sibyte_board_adapter[2] = { + { + name: "SiByte SMBus 0", + id: I2C_HW_SIBYTE, + algo: NULL, + algo_data: &sibyte_board_data[0], + inc_use: sibyte_inc_use, + dec_use: sibyte_dec_use, + client_register: sibyte_reg, + client_unregister: sibyte_unreg, + client_count: 0 + } , + { + name: "SiByte SMBus 1", + id: I2C_HW_SIBYTE, + algo: NULL, + algo_data: &sibyte_board_data[1], + inc_use: sibyte_inc_use, + dec_use: sibyte_dec_use, + client_register: sibyte_reg, + client_unregister: sibyte_unreg, + client_count: 0 + } +}; + +int __init i2c_sibyte_init(void) +{ + printk("i2c-swarm.o: i2c SMBus adapter module for SiByte board\n"); + if (i2c_sibyte_add_bus(&sibyte_board_adapter[0], K_SMB_FREQ_100KHZ) < 0) + return -ENODEV; + if (i2c_sibyte_add_bus(&sibyte_board_adapter[1], K_SMB_FREQ_400KHZ) < 0) + return -ENODEV; + return 0; +} + + +EXPORT_NO_SYMBOLS; + +#ifdef MODULE +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards"); +MODULE_LICENSE("GPL"); + +int init_module(void) +{ + return i2c_sibyte_init(); +} + +void cleanup_module(void) +{ + i2c_sibyte_del_bus(&sibyte_board_adapter[0]); + i2c_sibyte_del_bus(&sibyte_board_adapter[1]); +} + +#endif diff -urN linux-2.4.21/drivers/ide/Config.in linux-2.4.22/drivers/ide/Config.in --- linux-2.4.21/drivers/ide/Config.in 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/Config.in 2003-08-25 04:44:41.000000000 -0700 @@ -47,7 +47,7 @@ dep_tristate ' AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3 - dep_tristate ' AMD Viper support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI + dep_tristate ' AMD and nVidia IDE support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' AMD Viper ATA-66 Override' CONFIG_AMD74XX_OVERRIDE $CONFIG_BLK_DEV_AMD74XX dep_tristate ' CMD64{3|6|8|9} chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' Compaq Triflex IDE support' CONFIG_BLK_DEV_TRIFLEX $CONFIG_BLK_DEV_IDEDMA_PCI @@ -63,7 +63,7 @@ dep_tristate ' NS87415 chipset support' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL dep_tristate ' PROMISE PDC202{46|62|65|67} support' CONFIG_BLK_DEV_PDC202XX_OLD $CONFIG_BLK_DEV_IDEDMA_PCI - dep_mbool ' Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX_OLD $CONFIG_BLK_DEV_IDEDMA_PCI + dep_mbool ' Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX_OLD $CONFIG_BLK_DEV_IDEDMA_PCI dep_tristate ' PROMISE PDC202{68|69|70|71|75|76|77} support' CONFIG_BLK_DEV_PDC202XX_NEW $CONFIG_BLK_DEV_IDEDMA_PCI if [ "$CONFIG_BLK_DEV_PDC202XX_OLD" = "y" -o "$CONFIG_BLK_DEV_PDC202XX_OLD" = "m" -o "$CONFIG_BLK_DEV_PDC202XX_NEW" = "y" -o "$CONFIG_BLK_DEV_PDC202XX_NEW" = "m" ]; then bool ' Special FastTrak Feature' CONFIG_PDC202XX_FORCE @@ -93,7 +93,7 @@ define_bool CONFIG_BLK_DEV_IDEPCI $CONFIG_BLK_DEV_IDEDMA_PMAC fi fi - if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then + if [ "$CONFIG_SIBYTE_GENBUS_IDE" = "y" ]; then bool ' Broadcom SiByte onboard IDE support' CONFIG_BLK_DEV_IDE_SIBYTE fi if [ "$CONFIG_ARCH_ACORN" = "y" ]; then diff -urN linux-2.4.21/drivers/ide/Makefile linux-2.4.22/drivers/ide/Makefile --- linux-2.4.21/drivers/ide/Makefile 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -8,7 +8,6 @@ # In the future, some of these should be built conditionally. # -O_TARGET := idedriver.o export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-dma.o ide-lib.o setup-pci.o ide-io.o ide-disk.o @@ -29,24 +28,27 @@ # Core IDE code - must come before legacy -obj-$(CONFIG_BLK_DEV_IDE) += ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o ide-default.o -obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o -obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o -obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o -obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o +ide-core-objs := ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o ide-default.o ide-proc.o +ide-detect-objs := ide-probe.o ide-geometry.o + ifeq ($(CONFIG_BLK_DEV_IDEPCI),y) -obj-$(CONFIG_BLK_DEV_IDE) += setup-pci.o +ide-core-objs += setup-pci.o endif ifeq ($(CONFIG_BLK_DEV_IDEDMA_PCI),y) -obj-$(CONFIG_BLK_DEV_IDE) += ide-dma.o +ide-core-objs += ide-dma.o endif -obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o +# Initialisation order: +# Core sets up +# Legacy drivers may register a callback +# Drivers are pre initialised +# Probe inits the drivers and driver callbacks +# Raid scans the devices -ifeq ($(CONFIG_BLK_DEV_IDE),y) -obj-$(CONFIG_PROC_FS) += ide-proc.o -endif +obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o + +obj-$(CONFIG_BLK_DEV_IDE_SIBYTE) += ide-sibyte.o ifeq ($(CONFIG_BLK_DEV_IDE),y) obj-y += legacy/idedriver-legacy.o @@ -54,14 +56,33 @@ obj-y += arm/idedriver-arm.o else ifeq ($(CONFIG_BLK_DEV_HD_ONLY),y) + subdir-$(CONFIG_BLK_DEV_HD_ONLY) += legacy obj-y += legacy/idedriver-legacy.o endif endif +obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o + +obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o +obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o +obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o +obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o + +obj-$(CONFIG_BLK_DEV_IDE) += ide-detect.o ifeq ($(CONFIG_BLK_DEV_IDE),y) # RAID must be last of all obj-y += raid/idedriver-raid.o endif +list-multi := ide-core.o ide-detect.o +O_TARGET := idedriver.o + include $(TOPDIR)/Rules.make + +ide-core.o: $(ide-core-objs) + $(LD) -r -o $@ $(ide-core-objs) + +ide-detect.o: $(ide-detect-objs) + $(LD) -r -o $@ $(ide-detect-objs) + diff -urN linux-2.4.21/drivers/ide/ide-cd.c linux-2.4.22/drivers/ide/ide-cd.c --- linux-2.4.21/drivers/ide/ide-cd.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-cd.c 2003-08-25 04:44:41.000000000 -0700 @@ -765,6 +765,8 @@ if ((stat & ERR_STAT) != 0) cdrom_queue_request_sense(drive, wait, pc->sense, pc); } else if (blk_fs_request(rq)) { + int do_end_request = 0; + /* Handle errors from READ and WRITE requests. */ if (sense_key == NOT_READY) { @@ -773,7 +775,7 @@ /* Fail the request. */ printk ("%s: tray open\n", drive->name); - cdrom_end_request(drive, 0); + do_end_request = 1; } else if (sense_key == UNIT_ATTENTION) { /* Media change. */ cdrom_saw_media_change (drive); @@ -782,28 +784,31 @@ But be sure to give up if we've retried too many times. */ if (++rq->errors > ERROR_MAX) - cdrom_end_request(drive, 0); + do_end_request = 1; } 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(drive, 0); + do_end_request = 1; + } else if (sense_key == MEDIUM_ERROR) { + /* No point in re-trying a zillion times on a bad + * sector... If we got here the error is not correctable */ + ide_dump_status (drive, "media error (bad sector)", stat); + do_end_request = 1; } else if ((err & ~ABRT_ERR) != 0) { /* Go to the default handler for other errors. */ *startstop = DRIVER(drive)->error(drive, "cdrom_decode_status", stat); return 1; - } else if (sense_key == MEDIUM_ERROR) { - /* No point in re-trying a zillion times on a bad - * sector... If we got here the error is not correctable */ - ide_dump_status (drive, "media error (bad sector)", stat); - cdrom_end_request(drive, 0); } else if ((++rq->errors > ERROR_MAX)) { /* We've racked up too many retries. Abort. */ - cdrom_end_request(drive, 0); + do_end_request = 1; } + if (do_end_request) + cdrom_end_request(drive, 0); + /* If we got a CHECK_CONDITION status, queue a request sense command. */ if ((stat & ERR_STAT) != 0) diff -urN linux-2.4.21/drivers/ide/ide-default.c linux-2.4.22/drivers/ide/ide-default.c --- linux-2.4.21/drivers/ide/ide-default.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-default.c 2003-08-25 04:44:41.000000000 -0700 @@ -85,13 +85,10 @@ return ret; } -MODULE_DESCRIPTION("IDE Default Driver"); - int idedefault_init (void) { ide_register_module(&idedefault_module); return 0; } -module_init(idedefault_init); MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/ide/ide-dma.c linux-2.4.22/drivers/ide/ide-dma.c --- linux-2.4.21/drivers/ide/ide-dma.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-dma.c 2003-08-25 04:44:41.000000000 -0700 @@ -528,9 +528,10 @@ * the driver to resolve the problem, if a DMA transfer is still * in progress we continue to wait (arguably we need to add a * secondary 'I dont care what the drive thinks' timeout here) - * Finally if we have an interrupt but for some reason got the - * timeout first we complete the I/O. This can occur if an - * interrupt is lost or due to bugs. + * Finally if we have an interrupt we let it complete the I/O. + * But only one time - we clear expiry and if it's still not + * completed after WAIT_CMD, we error and retry in PIO. + * This can occur if an interrupt is lost or due to hang or bugs. */ static int dma_timer_expiry (ide_drive_t *drive) @@ -544,22 +545,24 @@ if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ return WAIT_CMD; - HWGROUP(drive)->expiry = NULL; /* one free ride for now */ + /* + * Clear the expiry handler in case we decide to wait more, + * next time timer expires it is an error + */ + HWGROUP(drive)->expiry = NULL; /* 1 dmaing, 2 error, 4 intr */ - if (dma_stat & 2) { /* ERROR */ - (void) hwif->ide_dma_end(drive); - return DRIVER(drive)->error(drive, - "dma_timer_expiry", hwif->INB(IDE_STATUS_REG)); - } + if (dma_stat & 2) /* ERROR */ + return -1; + if (dma_stat & 1) /* DMAing */ return WAIT_CMD; if (dma_stat & 4) /* Got an Interrupt */ - HWGROUP(drive)->handler(drive); + return WAIT_CMD; - return 0; + return 0; /* Unknown status -- reset the bus */ } /** diff -urN linux-2.4.21/drivers/ide/ide-floppy.c linux-2.4.22/drivers/ide/ide-floppy.c --- linux-2.4.21/drivers/ide/ide-floppy.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-floppy.c 2003-08-25 04:44:41.000000000 -0700 @@ -2195,7 +2195,6 @@ idefloppy_floppy_t *floppy; int failed = 0; - printk(KERN_INFO "ide-floppy driver " IDEFLOPPY_VERSION "\n"); #endif /* CLASSIC_BUILTINS_METHOD */ MOD_INC_USE_COUNT; #ifdef CLASSIC_BUILTINS_METHOD diff -urN linux-2.4.21/drivers/ide/ide-io.c linux-2.4.22/drivers/ide/ide-io.c --- linux-2.4.21/drivers/ide/ide-io.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-io.c 2003-08-25 04:44:41.000000000 -0700 @@ -896,15 +896,18 @@ ide_do_request(q->queuedata, IDE_NO_IRQ); } +EXPORT_SYMBOL(do_ide_request); + /* * 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 * all away */ -void ide_dma_timeout_retry(ide_drive_t *drive) +static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) { ide_hwif_t *hwif = HWIF(drive); struct request *rq; + ide_startstop_t ret = ide_stopped; /* * end current dma transaction @@ -914,8 +917,16 @@ /* * complain a little, later we might remove some of this verbosity */ - printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); - (void) hwif->ide_dma_timeout(drive); + + if (error < 0) { + printk(KERN_ERR "%s: error waiting for DMA\n", drive->name); + (void)HWIF(drive)->ide_dma_end(drive); + ret = DRIVER(drive)->error(drive, "dma timeout retry", + hwif->INB(IDE_STATUS_REG)); + } else { + printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); + (void) hwif->ide_dma_timeout(drive); + } /* * disable dma for now, but remember that we did so because of @@ -938,9 +949,9 @@ rq->current_nr_sectors = rq->bh->b_size >> 9; rq->hard_cur_sectors = rq->current_nr_sectors; rq->buffer = rq->bh->b_data; -} -EXPORT_SYMBOL(ide_dma_timeout_retry); + return ret; +} /** * ide_timer_expiry - handle lack of an IDE interrupt @@ -962,10 +973,9 @@ ide_handler_t *handler; ide_expiry_t *expiry; unsigned long flags; - unsigned long wait; + unsigned long wait = -1; spin_lock_irqsave(&io_request_lock, flags); - del_timer(&hwgroup->timer); if ((handler = hwgroup->handler) == NULL) { /* @@ -992,7 +1002,7 @@ } if ((expiry = hwgroup->expiry) != NULL) { /* continue */ - if ((wait = expiry(drive)) != 0) { + if ((wait = expiry(drive)) > 0) { /* reset timer */ hwgroup->timer.expires = jiffies + wait; add_timer(&hwgroup->timer); @@ -1028,16 +1038,15 @@ startstop = handler(drive); } else { if (drive->waiting_for_dma) { - startstop = ide_stopped; - ide_dma_timeout_retry(drive); + startstop = ide_dma_timeout_retry(drive, wait); } else { startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG)); } } set_recovery_timer(hwif); drive->service_time = jiffies - drive->service_start; - enable_irq(hwif->irq); spin_lock_irq(&io_request_lock); + enable_irq(hwif->irq); if (startstop == ide_stopped) hwgroup->busy = 0; } diff -urN linux-2.4.21/drivers/ide/ide-pnp.c linux-2.4.22/drivers/ide/ide-pnp.c --- linux-2.4.21/drivers/ide/ide-pnp.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-pnp.c 2003-08-25 04:44:41.000000000 -0700 @@ -16,6 +16,7 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include @@ -98,7 +99,7 @@ * Probe for ISA PnP IDE interfaces. */ -void __init pnpide_init(int enable) +static void pnpide_init(int enable) { struct pci_dev *dev = NULL; struct pnp_dev_t *dev_type; @@ -155,3 +156,26 @@ } } } + +static void __init pnpide_begin(void) +{ + pnpide_init(1); +} + +static int pnpide_init_module(void) +{ + ide_register_driver(pnpide_begin); + return 0; +} + +static void pnpide_unload(void) +{ + pnpide_init(0); +} + +module_init(pnpide_init_module); +module_exit(pnpide_unload); + +MODULE_AUTHOR("Andrey Panin"); +MODULE_DESCRIPTION("Enabler for ISAPNP IDE devices"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/ide/ide-probe.c linux-2.4.22/drivers/ide/ide-probe.c --- linux-2.4.21/drivers/ide/ide-probe.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-probe.c 2003-08-25 04:44:41.000000000 -0700 @@ -971,6 +971,7 @@ q->queuedata = HWGROUP(drive); blk_init_queue(q, do_ide_request); + blk_queue_throttle_sectors(q, 1); } #undef __IRQ_HELL_SPIN diff -urN linux-2.4.21/drivers/ide/ide-proc.c linux-2.4.22/drivers/ide/ide-proc.c --- linux-2.4.21/drivers/ide/ide-proc.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide-proc.c 2003-08-25 04:44:41.000000000 -0700 @@ -982,16 +982,11 @@ void proc_ide_destroy(void) { #ifdef CONFIG_BLK_DEV_IDEPCI - ide_pci_host_proc_t *p = ide_pci_host_proc_list; - char name[32]; + ide_pci_host_proc_t *p; - while ((p->name != NULL) && (p->set) && (p->get_info != NULL)) { - name[0] = '\0'; - sprintf(name, "ide/%s", p->name); + for (p = ide_pci_host_proc_list; p; p = p->next) { if (p->set == 2) remove_proc_entry(p->name, p->parent); - if (p->next == NULL) break; - p = p->next; } #endif /* CONFIG_BLK_DEV_IDEPCI */ remove_proc_entry("ide/drivers", proc_ide_root); diff -urN linux-2.4.21/drivers/ide/ide-sibyte.c linux-2.4.22/drivers/ide/ide-sibyte.c --- linux-2.4.21/drivers/ide/ide-sibyte.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/ide/ide-sibyte.c 2003-08-25 04:44:41.000000000 -0700 @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Derived loosely from ide-pmac.c, so: + * + * Copyright (C) 1998 Paul Mackerras. + * Copyright (C) 1995-1998 Mark Lord + */ +#include +#include + +#include + +#define SIBYTE_IDE_BASE (IO_SPACE_BASE + IDE_PHYS - mips_io_port_base) +#define SIBYTE_IDE_REG(pcaddr) (SIBYTE_IDE_BASE + ((pcaddr) << 5)) + +extern void sibyte_set_ideops(ide_hwif_t *hwif); + +void __init sibyte_ide_probe(void) +{ + int i; + ide_hwif_t *hwif = NULL; + + /* + * Find the first untaken slot in hwifs. Also set the io ops + * to the non-swapping SiByte versions. XXXKW It would be + * nice to find a safe place to do this outside of + * ide-sibyte.c so PCI-IDE would work without the SiByte + * driver. + */ + for (i = 0; i < MAX_HWIFS; i++) { + sibyte_set_ideops(&ide_hwifs[i]); + if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET] && (hwif == NULL)) { + hwif = &ide_hwifs[i]; + } + } + if (hwif == NULL) { + printk("No space for SiByte onboard IDE driver in ide_hwifs[]. Not enabled.\n"); + return; + } + + /* + * Set up our stuff; we're a little odd because our io_ports + * aren't in the usual place, and byte-swapping isn't + * necessary. + */ + hwif->hw.io_ports[IDE_DATA_OFFSET] = SIBYTE_IDE_REG(0x1f0); + hwif->hw.io_ports[IDE_ERROR_OFFSET] = SIBYTE_IDE_REG(0x1f1); + hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SIBYTE_IDE_REG(0x1f2); + hwif->hw.io_ports[IDE_SECTOR_OFFSET] = SIBYTE_IDE_REG(0x1f3); + hwif->hw.io_ports[IDE_LCYL_OFFSET] = SIBYTE_IDE_REG(0x1f4); + hwif->hw.io_ports[IDE_HCYL_OFFSET] = SIBYTE_IDE_REG(0x1f5); + hwif->hw.io_ports[IDE_SELECT_OFFSET] = SIBYTE_IDE_REG(0x1f6); + hwif->hw.io_ports[IDE_STATUS_OFFSET] = SIBYTE_IDE_REG(0x1f7); + hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SIBYTE_IDE_REG(0x3f6); + hwif->hw.irq = K_INT_GB_IDE; + hwif->irq = hwif->hw.irq; + hwif->noprobe = 0; + hwif->hw.ack_intr = NULL; + hwif->mmio = 2; + + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); + printk("SiByte onboard IDE configured as device %i\n", hwif-ide_hwifs); +} diff -urN linux-2.4.21/drivers/ide/ide.c linux-2.4.22/drivers/ide/ide.c --- linux-2.4.21/drivers/ide/ide.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/ide.c 2003-08-25 04:44:41.000000000 -0700 @@ -798,6 +798,7 @@ hwif->swdma_mask = old_hwif.swdma_mask; hwif->chipset = old_hwif.chipset; + hwif->hold = old_hwif.hold; #ifdef CONFIG_BLK_DEV_IDEPCI hwif->pci_dev = old_hwif.pci_dev; @@ -1414,6 +1415,8 @@ #endif } +EXPORT_SYMBOL_GPL(ide_add_generic_settings); + /* * Delay for *at least* 50ms. As we don't know how much time is left * until the next tick occurs, we wait an extra tick to be safe. @@ -2110,8 +2113,8 @@ #ifdef CONFIG_BLK_DEV_CMD640 case -14: /* "cmd640_vlb" */ { - extern int cmd640_vlb; /* flag for cmd640.c */ - cmd640_vlb = 1; + extern void init_cmd640_vlb (void); + init_cmd640_vlb(); goto done; } #endif /* CONFIG_BLK_DEV_CMD640 */ @@ -2210,6 +2213,44 @@ } /* + * Legacy interface registration + */ +#define NUM_DRIVER 32 + +/* + * Yes this is moronically simple, but why not - it works! + */ + +static __initdata ide_driver_call ide_scan[NUM_DRIVER]; +static int drivers_run = 0; + +void __init ide_register_driver(ide_driver_call scan) +{ + static int ide_scans = 0; + if(ide_scans == NUM_DRIVER) + panic("Too many IDE drivers"); + ide_scan[ide_scans++]=scan; + if(drivers_run) + { + printk(KERN_ERR "ide: late registration of driver.\n"); + scan(); + } +} + +EXPORT_SYMBOL(ide_register_driver); + +static void __init ide_scan_drivers(void) +{ + int i = 0; + while(ide_scan[i]) + { + (ide_scan[i])(); + i++; + } + drivers_run = 1; +} + +/* * probe_for_hwifs() finds/initializes "known" IDE interfaces */ static void __init probe_for_hwifs (void) @@ -2220,25 +2261,17 @@ ide_scan_pcibus(ide_scan_direction); } #endif /* CONFIG_BLK_DEV_IDEPCI */ + ide_scan_drivers(); + /* + * Unconverted drivers + */ #ifdef CONFIG_ETRAX_IDE { extern void init_e100_ide(void); init_e100_ide(); } #endif /* CONFIG_ETRAX_IDE */ -#ifdef CONFIG_BLK_DEV_CMD640 - { - extern void ide_probe_for_cmd640x(void); - ide_probe_for_cmd640x(); - } -#endif /* CONFIG_BLK_DEV_CMD640 */ -#ifdef CONFIG_BLK_DEV_PDC4030 - { - extern int ide_probe_for_pdc4030(void); - (void) ide_probe_for_pdc4030(); - } -#endif /* CONFIG_BLK_DEV_PDC4030 */ #ifdef CONFIG_BLK_DEV_IDE_PMAC { extern void pmac_ide_probe(void); @@ -2293,12 +2326,6 @@ buddha_init(); } #endif /* CONFIG_BLK_DEV_BUDDHA */ -#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) - { - extern void pnpide_init(int enable); - pnpide_init(1); - } -#endif /* CONFIG_BLK_DEV_ISAPNP */ } void __init ide_init_builtin_subdrivers (void) @@ -2355,6 +2382,10 @@ void __init ide_init_builtin_drivers (void) { /* + * Attach null driver + */ + idedefault_init(); + /* * Probe for special PCI and other "known" interface chipsets */ probe_for_hwifs (); @@ -2604,9 +2635,6 @@ up(&ide_setting_sem); return 1; } -#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) && defined(MODULE) - pnpide_init(0); -#endif /* CONFIG_BLK_DEV_ISAPNP */ #ifdef CONFIG_PROC_FS ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); ide_remove_proc_entries(drive->proc, generic_subdriver_entries); diff -urN linux-2.4.21/drivers/ide/legacy/pdc4030.c linux-2.4.22/drivers/ide/legacy/pdc4030.c --- linux-2.4.21/drivers/ide/legacy/pdc4030.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/legacy/pdc4030.c 2003-08-25 04:44:41.000000000 -0700 @@ -147,8 +147,6 @@ return pdc4030_cmd(drive, PROMISE_IDENTIFY); } -int enable_promise_support; - /* * setup_pdc4030() * Completes the setup of a Promise DC4030 controller card, once found. @@ -308,11 +306,6 @@ unsigned int index; ide_hwif_t *hwif; -#ifndef MODULE - if (enable_promise_support == 0) - return; -#endif - for (index = 0; index < MAX_HWIFS; index++) { hwif = &ide_hwifs[index]; if (hwif->chipset == ide_unknown && detect_pdc4030(hwif)) { @@ -362,7 +355,7 @@ void __init init_pdc4030(void) { - enable_promise_support = 1; + ide_register_driver(ide_probe_for_pdc4030); } #else @@ -373,9 +366,6 @@ int __init pdc4030_mod_init(void) { - if (enable_promise_support == 0) - enable_promise_support = 1; - if (!ide_probe_for_pdc4030()) return -ENODEV; return 0; @@ -387,9 +377,6 @@ unsigned int index; ide_hwif_t *hwif; - if (enable_promise_support == 0) - return; - for (index = 0; index < MAX_HWIFS; index++) { hwif = &ide_hwifs[index]; if (hwif->chipset == ide_pdc4030) { @@ -400,7 +387,6 @@ release_pdc4030(hwif, NULL); } } - enable_promise_support = 0; } module_exit(pdc4030_mod_exit); #endif diff -urN linux-2.4.21/drivers/ide/pci/alim15x3.c linux-2.4.22/drivers/ide/pci/alim15x3.c --- linux-2.4.21/drivers/ide/pci/alim15x3.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/alim15x3.c 2003-08-25 04:44:41.000000000 -0700 @@ -525,10 +525,14 @@ drive->init_speed = 0; + /* Set reasonable PIO timings first - some of them are needed + for DMA as well. */ + hwif->tuneproc(drive, 255); + if ((id->capability & 1) != 0 && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) - goto ata_pio; + goto no_dma_set; if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { if (id->dma_ultra & hwif->ultra_mask) { /* Force if Capable UltraDMA */ @@ -550,11 +554,9 @@ if (!config_chipset_for_dma(drive)) goto no_dma_set; } else { - goto ata_pio; + goto no_dma_set; } } else { -ata_pio: - hwif->tuneproc(drive, 255); no_dma_set: return hwif->ide_dma_off_quietly(drive); } diff -urN linux-2.4.21/drivers/ide/pci/cmd640.c linux-2.4.22/drivers/ide/pci/cmd640.c --- linux-2.4.21/drivers/ide/pci/cmd640.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/cmd640.c 2003-08-25 04:44:41.000000000 -0700 @@ -102,6 +102,7 @@ #define CMD640_PREFETCH_MASKS 1 #include +#include #include #include #include @@ -120,7 +121,8 @@ /* * This flag is set in ide.c by the parameter: ide0=cmd640_vlb */ -int cmd640_vlb = 0; + +static int cmd640_vlb = 0; /* * CMD640 specific registers definition. @@ -716,7 +718,7 @@ /* * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c */ -int __init ide_probe_for_cmd640x (void) +static void __init ide_probe_for_cmd640x (void) { #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED int second_port_toggled = 0; @@ -731,13 +733,13 @@ } else { cmd640_vlb = 0; /* Find out what kind of PCI probing is supported otherwise - Justin Gibbs will sulk.. */ + we break some Adaptec cards... */ if (pci_conf1() && probe_for_cmd640_pci1()) bus_type = "PCI (type1)"; else if (pci_conf2() && probe_for_cmd640_pci2()) bus_type = "PCI (type2)"; else - return 0; + return; } /* * Undocumented magic (there is no 0x5b reg in specs) @@ -745,7 +747,7 @@ put_cmd640_reg(0x5b, 0xbd); if (get_cmd640_reg(0x5b) != 0xbd) { printk(KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n"); - return 0; + return; } put_cmd640_reg(0x5b, 0); @@ -760,7 +762,7 @@ cmd640_chip_version = cfr & CFR_DEVREV; if (cmd640_chip_version == 0) { printk ("ide: bad cmd640 revision: %d\n", cmd640_chip_version); - return 0; + return; } /* @@ -874,6 +876,28 @@ #ifdef CMD640_DUMP_REGS CMD640_DUMP_REGS; #endif - return 1; + return; +} + +static int __init cmd640_init(void) +{ + ide_register_driver(ide_probe_for_cmd640x); + return 0; +} + +/* + * Called by the IDE core when compiled in and cmd640=vlb is + * selected. + */ +void init_cmd640_vlb(void) +{ + cmd640_vlb = 1; } +module_init(cmd640_init); + +MODULE_AUTHOR("See Source"); +MODULE_DESCRIPTION("IDE support for CMD640 controller"); +MODULE_PARM(cmd640_vlb, "i"); +MODULE_PARM_DESC(cmd640_vlb, "Set to enable scanning for VLB controllers"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/ide/pci/generic.c linux-2.4.22/drivers/ide/pci/generic.c --- linux-2.4.21/drivers/ide/pci/generic.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/generic.c 2003-08-25 04:44:41.000000000 -0700 @@ -140,6 +140,7 @@ { PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7}, { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8}, + { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9}, { 0, }, }; diff -urN linux-2.4.21/drivers/ide/pci/generic.h linux-2.4.22/drivers/ide/pci/generic.h --- linux-2.4.21/drivers/ide/pci/generic.h 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/generic.h 2003-08-25 04:44:41.000000000 -0700 @@ -127,6 +127,19 @@ .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, .bootable = ON_BOARD, .extra = 0, + },{ /* 9 */ + .vendor = PCI_VENDOR_ID_TOSHIBA, + .device = PCI_DEVICE_ID_TOSHIBA_PICCOLO, + .name = "Piccolo", + .init_chipset = init_chipset_generic, + .init_iops = NULL, + .init_hwif = init_hwif_generic, + .init_dma = init_dma_generic, + .channels = 2, + .autodma = NOAUTODMA, + .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, + .bootable = ON_BOARD, + .extra = 0, },{ .vendor = 0, .device = 0, diff -urN linux-2.4.21/drivers/ide/pci/hpt366.c linux-2.4.22/drivers/ide/pci/hpt366.c --- linux-2.4.21/drivers/ide/pci/hpt366.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/hpt366.c 2003-08-25 04:44:41.000000000 -0700 @@ -484,9 +484,12 @@ { u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive)); - if (!(speed)) + if (!speed) return 0; + if (pci_get_drvdata(HWIF(drive)->pci_dev) == NULL) + return 0; + (void) hpt3xx_tune_chipset(drive, speed); return ide_dma_enable(drive); } @@ -919,6 +922,8 @@ * Currently we always set up the PLL for the 372N */ + pci_set_drvdata(dev, NULL); + if(is_372n) { printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n"); @@ -957,6 +962,7 @@ pci_set_drvdata(dev, (void *) thirty_three_base_hpt370); printk("HPT37X: using 33MHz PCI clock\n"); } else if (pll == F_LOW_PCI_40) { + /* Unsupported */ } else if (pll == F_LOW_PCI_50) { if (hpt_minimum_revision(dev,8)) pci_set_drvdata(dev, NULL); @@ -971,7 +977,6 @@ if (hpt_minimum_revision(dev,8)) { printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n"); - pci_set_drvdata(dev, NULL); } else if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) sixty_six_base_hpt372); @@ -996,6 +1001,11 @@ if (pci_get_drvdata(dev)) goto init_hpt37X_done; + if (hpt_minimum_revision(dev,8)) + { + printk(KERN_ERR "HPT374: Only 33MHz PCI timings are supported.\n"); + return -EOPNOTSUPP; + } /* * adjust PLL based upon PCI clock, enable it, and wait for * stabilization. @@ -1021,9 +1031,7 @@ pci_write_config_dword(dev, 0x5c, pll & ~0x100); pci_write_config_byte(dev, 0x5b, 0x21); - if (hpt_minimum_revision(dev,8)) - return -EOPNOTSUPP; - else if (hpt_minimum_revision(dev,5)) + if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) fifty_base_hpt372); else if (hpt_minimum_revision(dev,4)) pci_set_drvdata(dev, (void *) fifty_base_hpt370a); @@ -1334,7 +1342,7 @@ struct pci_dev *findev = NULL; u8 pin1 = 0, pin2 = 0; unsigned int class_rev; - char *chipset_names[] = {"HPT366", "HPT366", "HPT368", + static char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A", "HPT372"}; if (PCI_FUNC(dev->devfn) & 1) @@ -1349,7 +1357,8 @@ if(d->device == PCI_DEVICE_ID_TTI_HPT372N) class_rev = 5; - strcpy(d->name, chipset_names[class_rev]); + if(class_rev < 6) + d->name = chipset_names[class_rev]; switch(class_rev) { case 5: diff -urN linux-2.4.21/drivers/ide/pci/pdc202xx_new.h linux-2.4.22/drivers/ide/pci/pdc202xx_new.h --- linux-2.4.21/drivers/ide/pci/pdc202xx_new.h 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/pdc202xx_new.h 2003-08-25 04:44:41.000000000 -0700 @@ -255,7 +255,7 @@ .vendor = PCI_VENDOR_ID_PROMISE, .device = PCI_DEVICE_ID_PROMISE_20275, .name = "PDC20275", - .init_setup = init_setup_pdcnew, + .init_setup = init_setup_pdc20276, .init_chipset = init_chipset_pdcnew, .init_iops = NULL, .init_hwif = init_hwif_pdc202new, @@ -287,7 +287,7 @@ .vendor = PCI_VENDOR_ID_PROMISE, .device = PCI_DEVICE_ID_PROMISE_20277, .name = "PDC20277", - .init_setup = init_setup_pdcnew, + .init_setup = init_setup_pdc20276, .init_chipset = init_chipset_pdcnew, .init_iops = NULL, .init_hwif = init_hwif_pdc202new, diff -urN linux-2.4.21/drivers/ide/pci/pdc202xx_old.c linux-2.4.22/drivers/ide/pci/pdc202xx_old.c --- linux-2.4.21/drivers/ide/pci/pdc202xx_old.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/pdc202xx_old.c 2003-08-25 04:44:41.000000000 -0700 @@ -168,9 +168,6 @@ pdc202xx_pio_verbose(reg64h), pdc202xx_pio_verbose(reg68h), pdc202xx_pio_verbose(reg6ch)); -#if 0 - p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n"); -#endif return (char *)p; } @@ -426,9 +423,9 @@ if (ultra_66) { /* * check to make sure drive on same channel - * is u66 capable + * is u66 capable. Ignore empty slots. */ - if (hwif->drives[!(drive->dn%2)].id) { + if (hwif->drives[!(drive->dn%2)].present) { if (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0078) { hwif->OUTB(CLKSPD | mask, (hwif->dma_master + 0x11)); } else { @@ -635,42 +632,7 @@ pdc202xx_reset_host(hwif); pdc202xx_reset_host(mate); -#if 0 - /* - * FIXME: Have to kick all the drives again :-/ - * What a pain in the ACE! - */ - if (hwif->present) { - u16 hunit = 0; - hwif->initializing = 1; - for (hunit = 0; hunit < MAX_DRIVES; ++hunit) { - ide_drive_t *hdrive = &hwif->drives[hunit]; - if (hdrive->present) { - if (hwif->ide_dma_check) - hwif->ide_dma_check(hdrive); - else - hwif->tuneproc(hdrive, 5); - } - } - hwif->initializing = 0; - } - if (mate->present) { - u16 munit = 0; - mate->initializing = 1; - for (munit = 0; munit < MAX_DRIVES; ++munit) { - ide_drive_t *mdrive = &mate->drives[munit]; - if (mdrive->present) { - if (mate->ide_dma_check) - mate->ide_dma_check(mdrive); - else - mate->tuneproc(mdrive, 5); - } - } - mate->initializing = 0; - } -#else hwif->tuneproc(drive, 5); -#endif } /* @@ -726,20 +688,6 @@ * reset leaves the timing registers intact, * but resets the drives. */ -#if 0 - if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || - (dev->device == PCI_DEVICE_ID_PROMISE_20265) || - (dev->device == PCI_DEVICE_ID_PROMISE_20263) || - (dev->device == PCI_DEVICE_ID_PROMISE_20262)) { - unsigned long high_16 = pci_resource_start(dev, 4); - byte udma_speed_flag = inb(high_16 + 0x001f); - outb(udma_speed_flag | 0x10, high_16 + 0x001f); - mdelay(100); - outb(udma_speed_flag & ~0x10, high_16 + 0x001f); - mdelay(2000); /* 2 seconds ?! */ - } - -#endif return dev->irq; } @@ -859,18 +807,6 @@ } } -#if 0 - if (dev->device == PCI_DEVICE_ID_PROMISE_20262) - if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || - (tmp & e->mask) != e->val)) - - if (d->enablebits[0].reg != d->enablebits[1].reg) { - d->enablebits[0].reg = d->enablebits[1].reg; - d->enablebits[0].mask = d->enablebits[1].mask; - d->enablebits[0].val = d->enablebits[1].val; - } -#endif - ide_setup_pci_device(dev, d); } @@ -884,22 +820,6 @@ "attached to I2O RAID controller.\n"); return; } - -#if 0 - { - u8 pri = 0, sec = 0; - - if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || - (tmp & e->mask) != e->val)) - - if (d->enablebits[0].reg != d->enablebits[1].reg) { - d->enablebits[0].reg = d->enablebits[1].reg; - d->enablebits[0].mask = d->enablebits[1].mask; - d->enablebits[0].val = d->enablebits[1].val; - } - } -#endif - ide_setup_pci_device(dev, d); } diff -urN linux-2.4.21/drivers/ide/pci/siimage.c linux-2.4.22/drivers/ide/pci/siimage.c --- linux-2.4.21/drivers/ide/pci/siimage.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/siimage.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,10 +1,24 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.02 Jan 30, 2003 + * linux/drivers/ide/pci/siimage.c Version 1.06 June 11, 2003 * * Copyright (C) 2001-2002 Andre Hedrick * Copyright (C) 2003 Red Hat * * May be copied or modified under the terms of the GNU General Public License + * + * Documentation available under NDA only + * + * + * FAQ Items: + * If you are using Marvell SATA-IDE adapters with Maxtor drives + * ensure the system is set up for ATA100/UDMA5 not UDMA6. + * + * If you are using WD drives with SATA bridges you must set the + * drive to "Single". "Master" will hang + * + * If you have strange problems with nVidia chipset systems please + * see the SI support documentation and update your system BIOS + * if neccessary */ #include @@ -30,12 +44,102 @@ static struct pci_dev *siimage_devs[SIIMAGE_MAX_DEVS]; static int n_siimage_devs; -static char * print_siimage_get_info (char *buf, struct pci_dev *dev, int index) +/** + * pdev_is_sata - check if device is SATA + * @pdev: PCI device to check + * + * Returns true if this is a SATA controller + */ + +static int pdev_is_sata(struct pci_dev *pdev) +{ + switch(pdev->device) + { + case PCI_DEVICE_ID_SII_3112: + case PCI_DEVICE_ID_SII_1210SA: + return 1; + case PCI_DEVICE_ID_SII_680: + return 0; + } + BUG(); +} + +/** + * is_sata - check if hwif is SATA + * @hwif: interface to check + * + * Returns true if this is a SATA controller + */ + +static inline int is_sata(ide_hwif_t *hwif) +{ + return pdev_is_sata(hwif->pci_dev); +} + +/** + * siimage_selreg - return register base + * @hwif: interface + * @r: config offset + * + * Turn a config register offset into the right address in either + * PCI space or MMIO space to access the control register in question + * Thankfully this is a configuration operation so isnt performance + * criticial. + */ + +static unsigned long siimage_selreg(ide_hwif_t *hwif, int r) +{ + unsigned long base = (unsigned long)hwif->hwif_data; + base += 0xA0 + r; + if(hwif->mmio) + base += (hwif->channel << 6); + else + base += (hwif->channel << 4); + return base; +} + +/** + * siimage_seldev - return register base + * @hwif: interface + * @r: config offset + * + * Turn a config register offset into the right address in either + * PCI space or MMIO space to access the control register in question + * including accounting for the unit shift. + */ + +static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) +{ + ide_hwif_t *hwif = HWIF(drive); + unsigned long base = (unsigned long)hwif->hwif_data; + base += 0xA0 + r; + if(hwif->mmio) + base += (hwif->channel << 6); + else + base += (hwif->channel << 4); + base |= drive->select.b.unit << drive->select.b.unit; + return base; +} + +/** + * print_siimage_get_info - print minimal proc information + * @buf: buffer to write into (kernel space) + * @dev: PCI device we are describing + * @index: Controller number + * + * Print the basic information for the state of the CMD680/SI3112 + * channel. We don't actually dump a lot of information out for + * this controller although we could expand it if we needed. + */ + +static char *print_siimage_get_info (char *buf, struct pci_dev *dev, int index) { char *p = buf; u8 mmio = (pci_get_drvdata(dev) != NULL) ? 1 : 0; - unsigned long bmdma = (mmio) ? ((unsigned long) pci_get_drvdata(dev)) : - (pci_resource_start(dev, 4)); + unsigned long bmdma = pci_resource_start(dev, 4); + + if(mmio) + bmdma = pci_resource_start(dev, 5); p += sprintf(p, "\nController: %d\n", index); p += sprintf(p, "SiI%x Chipset.\n", dev->device); @@ -43,18 +147,20 @@ p += sprintf(p, "MMIO Base 0x%lx\n", bmdma); p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma); p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma+8); - - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - p += sprintf(p, "--------------- drive0 --------- drive1 " - "-------- drive0 ---------- drive1 ------\n"); - p += sprintf(p, "PIO Mode: %s %s" - " %s %s\n", - "?", "?", "?", "?"); return (char *)p; } +/** + * siimage_get_info - proc callback + * @buffer: kernel buffer to complete + * @addr: written with base of data to return + * offset: seek offset + * count: bytes to fill in + * + * Called when the user reads data from the virtual file for this + * controller from /proc + */ + static int siimage_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; @@ -89,44 +195,56 @@ { ide_hwif_t *hwif = HWIF(drive); u8 mode = 0, scsc = 0; + unsigned long base = (unsigned long) hwif->hwif_data; if (hwif->mmio) - scsc = hwif->INB(HWIFADDR(0x4A)); + scsc = hwif->INB(base + 0x4A); else pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_SII_3112: - return 4; - case PCI_DEVICE_ID_SII_680: - if ((scsc & 0x30) == 0x10) /* 133 */ - mode = 4; - else if ((scsc & 0x30) == 0x20) /* 2xPCI */ - mode = 4; - else if ((scsc & 0x30) == 0x00) /* 100 */ - mode = 3; - else /* Disabled ? */ - BUG(); - break; - default: return 0; + if(is_sata(hwif)) + { + if(strstr(drive->id->model, "Maxtor")) + return 3; + return 4; } + + if ((scsc & 0x30) == 0x10) /* 133 */ + mode = 4; + else if ((scsc & 0x30) == 0x20) /* 2xPCI */ + mode = 4; + else if ((scsc & 0x30) == 0x00) /* 100 */ + mode = 3; + else /* Disabled ? */ + BUG(); + if (!eighty_ninty_three(drive)) mode = min(mode, (u8)1); return mode; } +/** + * siimage_taskfile_timing - turn timing data to a mode + * @hwif: interface to query + * + * Read the timing data for the interface and return the + * mode that is being used. + */ + static byte siimage_taskfile_timing (ide_hwif_t *hwif) { u16 timing = 0x328a; + unsigned long addr = siimage_selreg(hwif, 2); if (hwif->mmio) - timing = hwif->INW(SELADDR(2)); + timing = hwif->INW(addr); else - pci_read_config_word(hwif->pci_dev, SELREG(2), &timing); + pci_read_config_word(hwif->pci_dev, addr, &timing); switch (timing) { case 0x10c1: return 4; case 0x10c3: return 3; + case 0x1104: case 0x1281: return 2; case 0x2283: return 1; case 0x328a: @@ -140,37 +258,82 @@ * @mode_wanted: the target operating mode * * Load the timing settings for this device mode into the - * controller + * controller. If we are in PIO mode 3 or 4 turn on IORDY + * monitoring (bit 9). The TF timing is bits 31:16 */ static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) { ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u16 speedt = 0; - u8 unit = drive->select.b.unit; - - if (hwif->mmio) - speedt = hwif->INW(SELADDR(0x04|(unit<mmio) - hwif->OUTW(speedt, SELADDR(0x04|(unit<OUTW(speedt, addr); + hwif->OUTW(speedp, tfaddr); + /* Now set up IORDY */ + if(mode_wanted == 3 || mode_wanted == 4) + hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2); + else + hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2); + } else - pci_write_config_word(dev, SELADDR(0x04|(unit<pci_dev, addr, speedp); + pci_write_config_word(hwif->pci_dev, tfaddr, speedt); + pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp); + speedp &= ~0x200; + /* Set IORDY for mode 3 or 4 */ + if(mode_wanted == 3 || mode_wanted == 4) + speedp |= 0x200; + pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp); + } } +/** + * config_siimage_chipset_for_pio - set drive timings + * @drive: drive to tune + * @speed we want + * + * Compute the best pio mode we can for a given device. Also honour + * the timings for the driver when dealing with mixed devices. Some + * of this is ugly but its all wrapped up here + * + * The SI680 can also do VDMA - we need to start using that + * + * FIXME: we use the BIOS channel timings to avoid driving the task + * files too fast at the disk. We need to compute the master/slave + * drive PIO mode properly so that we can up the speed on a hotplug + * system. + */ + static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) { u8 channel_timings = siimage_taskfile_timing(HWIF(drive)); @@ -191,6 +354,16 @@ config_siimage_chipset_for_pio(drive, set_speed); } +/** + * siimage_tune_chipset - set controller timings + * @drive: Drive to set up + * @xferspeed: speed we want to achieve + * + * Tune the SII chipset for the desired mode. If we can't achieve + * the desired mode then tune for a lower one, but ultimately + * make the thing work. + */ + static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; @@ -200,30 +373,32 @@ ide_hwif_t *hwif = HWIF(drive); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; - u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); + unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : ((hwif->mmio) ? 0xB4 : 0x80)); + + unsigned long ma = siimage_seldev(drive, 0x08); + unsigned long ua = siimage_seldev(drive, 0x0C); if (hwif->mmio) { - scsc = hwif->INB(HWIFADDR(0x4A)); - mode = hwif->INB(HWIFADDR(addr_mask)); - multi = hwif->INW(SELADDR(0x08|(unit<INW(SELADDR(0x0C|(unit<INB(base + 0x4A); + mode = hwif->INB(base + addr_mask); + multi = hwif->INW(ma); + ultra = hwif->INW(ua); } else { pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); pci_read_config_byte(hwif->pci_dev, addr_mask, &mode); - pci_read_config_word(hwif->pci_dev, - SELREG(0x08|(unit<pci_dev, - SELREG(0x0C|(unit<pci_dev, ma, &multi); + pci_read_config_word(hwif->pci_dev, ua, &ultra); } mode &= ~((unit) ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; - scsc = (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) ? 1 : scsc; + scsc = is_sata(hwif) ? 1 : scsc; switch(speed) { case XFER_PIO_4: @@ -259,20 +434,26 @@ } if (hwif->mmio) { - hwif->OUTB(mode, HWIFADDR(addr_mask)); - hwif->OUTW(multi, SELADDR(0x08|(unit<OUTW(ultra, SELADDR(0x0C|(unit<OUTB(mode, base + addr_mask); + hwif->OUTW(multi, ma); + hwif->OUTW(ultra, ua); } else { pci_write_config_byte(hwif->pci_dev, addr_mask, mode); - pci_write_config_word(hwif->pci_dev, - SELREG(0x08|(unit<pci_dev, - SELREG(0x0C|(unit<pci_dev, ma, multi); + pci_write_config_word(hwif->pci_dev, ua, ultra); } - return (ide_config_drive_speed(drive, speed)); } +/** + * config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * Called by the IDE layer when it wants the timings set up. + * For the CMD680 we also need to set up the PIO timings and + * enable DMA. + */ + static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, siimage_ratemask(drive)); @@ -291,14 +472,22 @@ return ide_dma_enable(drive); } +/** + * siimage_configure_drive_for_dma - set up for DMA transfers + * @drive: drive we are going to set up + * + * Set up the drive for DMA, tune the controller and drive as + * required. If the drive isn't suitable for DMA or we hit + * other problems then we will drop down to PIO and set up + * PIO appropriately + */ + static int siimage_config_drive_for_dma (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; if ((id->capability & 1) != 0 && drive->autodma) { - if (!(hwif->atapi_dma)) - goto fast_ata_pio; /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; @@ -340,18 +529,28 @@ { ide_hwif_t *hwif = HWIF(drive); u8 dma_altstat = 0; + unsigned long addr = siimage_selreg(hwif, 1); /* return 1 if INTR asserted */ if ((hwif->INB(hwif->dma_status) & 4) == 4) return 1; /* return 1 if Device INTR asserted */ - pci_read_config_byte(hwif->pci_dev, SELREG(1), &dma_altstat); + pci_read_config_byte(hwif->pci_dev, addr, &dma_altstat); if (dma_altstat & 8) return 0; //return 1; return 0; } +/** + * siimage_mmio_ide_dma_count - DMA bytes done + * @drive + * + * If we are doing VDMA the CMD680 requires a little bit + * of more careful handling and we have to read the counts + * off ourselves. For non VDMA life is normal. + */ + static int siimage_mmio_ide_dma_count (ide_drive_t *drive) { #ifdef SIIMAGE_VIRTUAL_DMAPIO @@ -359,9 +558,10 @@ ide_hwif_t *hwif = HWIF(drive); u32 count = (rq->nr_sectors * SECTOR_SIZE); u32 rcount = 0; + unsigned long addr = siimage_selreg(hwif, 0x1C); - hwif->OUTL(count, SELADDR(0x1C)); - rcount = hwif->INL(SELADDR(0x1C)); + hwif->OUTL(count, addr); + rcount = hwif->INL(addr); printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n", drive->name, count, rcount, rq->nr_sectors); @@ -370,13 +570,22 @@ return __ide_dma_count(drive); } -/* returns 1 if dma irq issued, 0 otherwise */ +/** + * siimage_mmio_ide_dma_test_irq - check we caused an IRQ + * @drive: drive we are testing + * + * Check if we caused an IDE DMA interrupt. We may also have caused + * SATA status interrupts, if so we clean them up and continue. + */ + static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); + unsigned long base = (unsigned long)hwif->hwif_data; + unsigned long addr = siimage_selreg(hwif, 0x1); if (SATA_ERROR_REG) { - u32 ext_stat = hwif->INL(HWIFADDR(0x10)); + u32 ext_stat = hwif->INL(base + 0x10); u8 watchdog = 0; if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) { u32 sata_error = hwif->INL(SATA_ERROR_REG); @@ -403,7 +612,7 @@ return 1; /* return 1 if Device INTR asserted */ - if ((hwif->INB(SELADDR(1)) & 8) == 8) + if ((hwif->INB(addr) & 8) == 8) return 0; //return 1; return 0; @@ -412,9 +621,6 @@ static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive) { int temp = __ide_dma_verbose(drive); -#if 0 - drive->using_dma = 0; -#endif return temp; } @@ -432,11 +638,12 @@ { ide_hwif_t *hwif = HWIF(drive); u32 stat_config = 0; + unsigned long addr = siimage_selreg(hwif, 0); if (hwif->mmio) { - stat_config = hwif->INL(SELADDR(0)); + stat_config = hwif->INL(addr); } else - pci_read_config_dword(hwif->pci_dev, SELREG(0), &stat_config); + pci_read_config_dword(hwif->pci_dev, addr, &stat_config); switch (state) { case BUSSTATE_ON: @@ -458,6 +665,14 @@ return 0; } +/** + * siimage_reset_poll - wait for sata reset + * @drive: drive we are resetting + * + * Poll the SATA phy and see whether it has come back from the dead + * yet. + */ + static int siimage_reset_poll (ide_drive_t *drive) { if (SATA_STATUS_REG) { @@ -488,7 +703,8 @@ if (drive->media != ide_disk) return; - if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_SII_3112) { + if (is_sata(HWIF(drive))) + { drive->special.b.set_geometry = 0; drive->special.b.recalibrate = 0; } @@ -506,19 +722,21 @@ { ide_hwif_t *hwif = HWIF(drive); u8 reset = 0; + unsigned long addr = siimage_selreg(hwif, 0); if (hwif->mmio) { - reset = hwif->INB(SELADDR(0)); - hwif->OUTB((reset|0x03), SELADDR(0)); + reset = hwif->INB(addr); + hwif->OUTB((reset|0x03), addr); + /* FIXME:posting */ udelay(25); - hwif->OUTB(reset, SELADDR(0)); - (void) hwif->INB(SELADDR(0)); + hwif->OUTB(reset, addr); + (void) hwif->INB(addr); } else { - pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset); - pci_write_config_byte(hwif->pci_dev, SELREG(0), reset|0x03); + pci_read_config_byte(hwif->pci_dev, addr, &reset); + pci_write_config_byte(hwif->pci_dev, addr, reset|0x03); udelay(25); - pci_write_config_byte(hwif->pci_dev, SELREG(0), reset); - pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset); + pci_write_config_byte(hwif->pci_dev, addr, reset); + pci_read_config_byte(hwif->pci_dev, addr, &reset); } if (SATA_STATUS_REG) { @@ -546,11 +764,11 @@ static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char *name) { - if (dev->device == PCI_DEVICE_ID_SII_3112) + if(pdev_is_sata(dev)) goto sata_skip; printk(KERN_INFO "%s: BASE CLOCK ", name); - clocking &= ~0x03; + clocking &= 0x03; switch(clocking) { case 0x03: printk("DISABLED !\n"); break; case 0x02: printk("== 2X PCI \n"); break; @@ -570,10 +788,20 @@ #endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */ } +/** + * setup_mmio_siimage - switch an SI controller into MMIO + * @dev: PCI device we are configuring + * @name: device name + * + * Attempt to put the device into mmio mode. There are some slight + * complications here with certain systems where the mmio bar isnt + * mapped so we have to be sure we can fall back to I/O. + */ + static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) { unsigned long bar5 = pci_resource_start(dev, 5); - unsigned long len5 = pci_resource_len(dev, 5); + unsigned long barsize = pci_resource_len(dev, 5); u8 tmpbyte = 0; unsigned long addr; void *ioaddr; @@ -584,34 +812,37 @@ * spaces. */ - if(check_mem_region(bar5, len5)!=0) + if(!request_mem_region(bar5, barsize, name)) { printk(KERN_WARNING "siimage: IDE controller MMIO ports not available.\n"); return 0; } - ioaddr = ioremap_nocache(bar5, len5); + ioaddr = ioremap(bar5, barsize); if (ioaddr == NULL) + { + release_mem_region(bar5, barsize); return 0; + } pci_set_master(dev); pci_set_drvdata(dev, ioaddr); addr = (unsigned long) ioaddr; - if (dev->device == PCI_DEVICE_ID_SII_3112) { - writel(0, DEVADDR(0x148)); - writel(0, DEVADDR(0x1C8)); + if (pdev_is_sata(dev)) { + writel(0, addr + 0x148); + writel(0, addr + 0x1C8); } - writeb(0, DEVADDR(0xB4)); - writeb(0, DEVADDR(0xF4)); - tmpbyte = readb(DEVADDR(0x4A)); + writeb(0, addr + 0xB4); + writeb(0, addr + 0xF4); + tmpbyte = readb(addr + 0x4A); switch(tmpbyte & 0x30) { case 0x00: /* In 100 MHz clocking, try and switch to 133 */ - writeb(tmpbyte|0x10, DEVADDR(0x4A)); + writeb(tmpbyte|0x10, addr + 0x4A); break; case 0x10: /* On 133Mhz clocking */ @@ -622,34 +853,43 @@ case 0x30: /* Clocking is disabled */ /* 133 clock attempt to force it on */ - writeb(tmpbyte & ~0x20, DEVADDR(0x4A)); + writeb(tmpbyte & ~0x20, addr + 0x4A); break; } - writeb(0x72, DEVADDR(0xA1)); - writew(0x328A, DEVADDR(0xA2)); - writel(0x62DD62DD, DEVADDR(0xA4)); - writel(0x43924392, DEVADDR(0xA8)); - writel(0x40094009, DEVADDR(0xAC)); - writeb(0x72, DEVADDR(0xE1)); - writew(0x328A, DEVADDR(0xE2)); - writel(0x62DD62DD, DEVADDR(0xE4)); - writel(0x43924392, DEVADDR(0xE8)); - writel(0x40094009, DEVADDR(0xEC)); - - if (dev->device == PCI_DEVICE_ID_SII_3112) { - writel(0xFFFF0000, DEVADDR(0x108)); - writel(0xFFFF0000, DEVADDR(0x188)); - writel(0x00680000, DEVADDR(0x148)); - writel(0x00680000, DEVADDR(0x1C8)); + writeb( 0x72, addr + 0xA1); + writew( 0x328A, addr + 0xA2); + writel(0x62DD62DD, addr + 0xA4); + writel(0x43924392, addr + 0xA8); + writel(0x40094009, addr + 0xAC); + writeb( 0x72, addr + 0xE1); + writew( 0x328A, addr + 0xE2); + writel(0x62DD62DD, addr + 0xE4); + writel(0x43924392, addr + 0xE8); + writel(0x40094009, addr + 0xEC); + + if (pdev_is_sata(dev)) { + writel(0xFFFF0000, addr + 0x108); + writel(0xFFFF0000, addr + 0x188); + writel(0x00680000, addr + 0x148); + writel(0x00680000, addr + 0x1C8); } - tmpbyte = readb(DEVADDR(0x4A)); + tmpbyte = readb(addr + 0x4A); - proc_reports_siimage(dev, (tmpbyte>>=4), name); + proc_reports_siimage(dev, (tmpbyte>>4), name); return 1; } +/** + * init_chipset_siimage - set up an SI device + * @dev: PCI device + * @name: device name + * + * Perform the initial PCI set up for this device. Attempt to switch + * to 133MHz clocking if the system isn't already set up to do it. + */ + static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name) { u32 class_rev = 0; @@ -686,115 +926,134 @@ break; } - pci_read_config_byte(dev, 0x8A, &tmpbyte); - pci_write_config_byte(dev, 0xA1, 0x72); - pci_write_config_word(dev, 0xA2, 0x328A); + pci_read_config_byte(dev, 0x8A, &tmpbyte); + + pci_write_config_byte(dev, 0xA1, 0x72); + pci_write_config_word(dev, 0xA2, 0x328A); pci_write_config_dword(dev, 0xA4, 0x62DD62DD); pci_write_config_dword(dev, 0xA8, 0x43924392); pci_write_config_dword(dev, 0xAC, 0x40094009); - pci_write_config_byte(dev, 0xB1, 0x72); - pci_write_config_word(dev, 0xB2, 0x328A); + pci_write_config_byte(dev, 0xB1, 0x72); + pci_write_config_word(dev, 0xB2, 0x328A); pci_write_config_dword(dev, 0xB4, 0x62DD62DD); pci_write_config_dword(dev, 0xB8, 0x43924392); pci_write_config_dword(dev, 0xBC, 0x40094009); - pci_read_config_byte(dev, 0x8A, &tmpbyte); - proc_reports_siimage(dev, (tmpbyte>>=4), name); + proc_reports_siimage(dev, (tmpbyte>>4), name); return 0; } +/** + * init_mmio_iops_siimage - set up the iops for MMIO + * @hwif: interface to set up + * + * The basic setup here is fairly simple, we can use standard MMIO + * operations. However we do have to set the taskfile register offsets + * by hand as there isnt a standard defined layout for them this + * time. + * + * The hardware supports buffered taskfiles and also some rather nice + * extended PRD tables. Unfortunately right now we don't. + */ + static void __init init_mmio_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - unsigned long addr = (unsigned long) pci_get_drvdata(hwif->pci_dev); + void *addr = pci_get_drvdata(dev); u8 ch = hwif->channel; -// u16 i = 0; - hw_regs_t hw; + hw_regs_t hw; + unsigned long base; + + /* + * Fill in the basic HWIF bits + */ default_hwif_mmiops(hwif); + hwif->hwif_data = addr; + + /* + * Now set up the hw. We have to do this ourselves as + * the MMIO layout isnt the same as the the standard port + * based I/O + */ + memset(&hw, 0, sizeof(hw_regs_t)); + hw.priv = addr; -#if 1 -#ifdef SIIMAGE_BUFFERED_TASKFILE - hw.io_ports[IDE_DATA_OFFSET] = DEVADDR((ch) ? 0xD0 : 0x90); - hw.io_ports[IDE_ERROR_OFFSET] = DEVADDR((ch) ? 0xD1 : 0x91); - hw.io_ports[IDE_NSECTOR_OFFSET] = DEVADDR((ch) ? 0xD2 : 0x92); - hw.io_ports[IDE_SECTOR_OFFSET] = DEVADDR((ch) ? 0xD3 : 0x93); - hw.io_ports[IDE_LCYL_OFFSET] = DEVADDR((ch) ? 0xD4 : 0x94); - hw.io_ports[IDE_HCYL_OFFSET] = DEVADDR((ch) ? 0xD5 : 0x95); - hw.io_ports[IDE_SELECT_OFFSET] = DEVADDR((ch) ? 0xD6 : 0x96); - hw.io_ports[IDE_STATUS_OFFSET] = DEVADDR((ch) ? 0xD7 : 0x97); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A); -#else /* ! SIIMAGE_BUFFERED_TASKFILE */ - hw.io_ports[IDE_DATA_OFFSET] = DEVADDR((ch) ? 0xC0 : 0x80); - hw.io_ports[IDE_ERROR_OFFSET] = DEVADDR((ch) ? 0xC1 : 0x81); - hw.io_ports[IDE_NSECTOR_OFFSET] = DEVADDR((ch) ? 0xC2 : 0x82); - hw.io_ports[IDE_SECTOR_OFFSET] = DEVADDR((ch) ? 0xC3 : 0x83); - hw.io_ports[IDE_LCYL_OFFSET] = DEVADDR((ch) ? 0xC4 : 0x84); - hw.io_ports[IDE_HCYL_OFFSET] = DEVADDR((ch) ? 0xC5 : 0x85); - hw.io_ports[IDE_SELECT_OFFSET] = DEVADDR((ch) ? 0xC6 : 0x86); - hw.io_ports[IDE_STATUS_OFFSET] = DEVADDR((ch) ? 0xC7 : 0x87); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A); -#endif /* SIIMAGE_BUFFERED_TASKFILE */ -#else -#ifdef SIIMAGE_BUFFERED_TASKFILE - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - hw.io_ports[i] = DEVADDR((ch) ? 0xD0 : 0x90)|(i); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A); -#else /* ! SIIMAGE_BUFFERED_TASKFILE */ - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - hw.io_ports[i] = DEVADDR((ch) ? 0xC0 : 0x80)|(i); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A); -#endif /* SIIMAGE_BUFFERED_TASKFILE */ -#endif + base = (unsigned long)addr; + if(ch) + base += 0xC0; + else + base += 0x80; -#if 0 - printk(KERN_DEBUG "%s: ", hwif->name); - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i)); - printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i)); -#endif + /* + * The buffered task file doesn't have status/control + * so we can't currently use it sanely since we want to + * use LBA48 mode. + */ +// base += 0x10; +// hwif->addressing = 1; + + hw.io_ports[IDE_DATA_OFFSET] = base; + hw.io_ports[IDE_ERROR_OFFSET] = base + 1; + hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; + hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; + hw.io_ports[IDE_LCYL_OFFSET] = base + 4; + hw.io_ports[IDE_HCYL_OFFSET] = base + 5; + hw.io_ports[IDE_SELECT_OFFSET] = base + 6; + hw.io_ports[IDE_STATUS_OFFSET] = base + 7; + hw.io_ports[IDE_CONTROL_OFFSET] = base + 10; hw.io_ports[IDE_IRQ_OFFSET] = 0; - if (dev->device == PCI_DEVICE_ID_SII_3112) { - hw.sata_scr[SATA_STATUS_OFFSET] = DEVADDR((ch) ? 0x184 : 0x104); - hw.sata_scr[SATA_ERROR_OFFSET] = DEVADDR((ch) ? 0x188 : 0x108); - hw.sata_scr[SATA_CONTROL_OFFSET]= DEVADDR((ch) ? 0x180 : 0x100); - hw.sata_misc[SATA_MISC_OFFSET] = DEVADDR((ch) ? 0x1C0 : 0x140); - hw.sata_misc[SATA_PHY_OFFSET] = DEVADDR((ch) ? 0x1C4 : 0x144); - hw.sata_misc[SATA_IEN_OFFSET] = DEVADDR((ch) ? 0x1C8 : 0x148); + if (pdev_is_sata(dev)) { + base = (unsigned long) addr; + if(ch) + base += 0x80; + hw.sata_scr[SATA_STATUS_OFFSET] = base + 0x104; + hw.sata_scr[SATA_ERROR_OFFSET] = base + 0x108; + hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100; + hw.sata_misc[SATA_MISC_OFFSET] = base + 0x140; + hw.sata_misc[SATA_PHY_OFFSET] = base + 0x144; + hw.sata_misc[SATA_IEN_OFFSET] = base + 0x148; } - hw.priv = (void *) addr; -// hw.priv = pci_get_drvdata(hwif->pci_dev); hw.irq = hwif->pci_dev->irq; memcpy(&hwif->hw, &hw, sizeof(hw)); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); - if (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) { + if (is_sata(hwif)) { memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr)); memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc)); } -#ifdef SIIMAGE_BUFFERED_TASKFILE - hwif->addressing = 1; -#endif /* SIIMAGE_BUFFERED_TASKFILE */ hwif->irq = hw.irq; - hwif->hwif_data = pci_get_drvdata(hwif->pci_dev); + + base = (unsigned long) addr; #ifdef SIIMAGE_LARGE_DMA - hwif->dma_base = DEVADDR((ch) ? 0x18 : 0x10); - hwif->dma_base2 = DEVADDR((ch) ? 0x08 : 0x00); - hwif->dma_prdtable = (hwif->dma_base2 + 4); +/* Watch the brackets - even Ken and Dennis get some language design wrong */ + hwif->dma_base = base + (ch ? 0x18 : 0x10); + hwif->dma_base2 = base + (ch ? 0x08 : 0x00); + hwif->dma_prdtable = hwif->dma_base2 + 4; #else /* ! SIIMAGE_LARGE_DMA */ - hwif->dma_base = DEVADDR((ch) ? 0x08 : 0x00); - hwif->dma_base2 = DEVADDR((ch) ? 0x18 : 0x10); + hwif->dma_base = base + (ch ? 0x08 : 0x00); + hwif->dma_base2 = base + (ch ? 0x18 : 0x10); #endif /* SIIMAGE_LARGE_DMA */ hwif->mmio = 2; } +/** + * init_iops_siimage - set up iops + * @hwif: interface to set up + * + * Do the basic setup for the SIIMAGE hardware interface + * and then do the MMIO setup if we can. This is the first + * look in we get for setting up the hwif so that we + * can get the iops right before using them. + */ + static void __init init_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -802,27 +1061,47 @@ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; + + hwif->hwif_data = 0; hwif->rqsize = 128; - if ((dev->device == PCI_DEVICE_ID_SII_3112) && (!(class_rev))) - hwif->rqsize = 16; + if (is_sata(hwif)) + hwif->rqsize = 15; if (pci_get_drvdata(dev) == NULL) return; init_mmio_iops_siimage(hwif); } +/** + * ata66_siimage - check for 80 pin cable + * @hwif: interface to check + * + * Check for the presence of an ATA66 capable cable on the + * interface. + */ + static unsigned int __init ata66_siimage (ide_hwif_t *hwif) { + unsigned long addr = siimage_selreg(hwif, 0); if (pci_get_drvdata(hwif->pci_dev) == NULL) { u8 ata66 = 0; - pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66); + pci_read_config_byte(hwif->pci_dev, addr, &ata66); return (ata66 & 0x01) ? 1 : 0; } - return (hwif->INB(SELADDR(0)) & 0x01) ? 1 : 0; + return (hwif->INB(addr) & 0x01) ? 1 : 0; } +/** + * init_hwif_siimage - set up hwif structs + * @hwif: interface to set up + * + * We do the basic set up of the interface structure. The SIIMAGE + * requires several custom handlers so we override the default + * ide DMA handlers appropriately + */ + static void __init init_hwif_siimage (ide_hwif_t *hwif) { hwif->autodma = 0; @@ -833,7 +1112,7 @@ hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; - if(hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) + if(is_sata(hwif)) hwif->busproc = &siimage_busproc; if (!hwif->dma_base) { @@ -846,7 +1125,7 @@ hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - if (hwif->pci_dev->device != PCI_DEVICE_ID_SII_3112) + if (!is_sata(hwif)) hwif->atapi_dma = 1; hwif->ide_dma_check = &siimage_config_drive_for_dma; @@ -860,12 +1139,26 @@ } else { hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq; } - if (!noautodma) - hwif->autodma = 1; + + /* + * The BIOS often doesn't set up DMA on this controller + * so we always do it. + */ + + hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; } +/** + * init_dma_siimage - set up IDE DMA + * @hwif: interface + * @dmabase: DMA base address to use + * + * For the SI chips this requires no special set up so we can just + * let the IDE DMA core do the usual work. + */ + static void __init init_dma_siimage (ide_hwif_t *hwif, unsigned long dmabase) { ide_setup_dma(hwif, dmabase, 8); @@ -874,6 +1167,15 @@ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); +/** + * siimage_init_one - pci layer discovery entry + * @dev: PCI device + * @id: ident table entry + * + * Called by the PCI code when it finds an SI680 or SI3112 controller. + * We then use the IDE PCI generic helper to do most of the work. + */ + static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id) { ide_pci_device_t *d = &siimage_chipsets[id->driver_data]; @@ -887,6 +1189,7 @@ static struct pci_device_id siimage_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, { 0, }, }; diff -urN linux-2.4.21/drivers/ide/pci/siimage.h linux-2.4.22/drivers/ide/pci/siimage.h --- linux-2.4.21/drivers/ide/pci/siimage.h 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/siimage.h 2003-08-25 04:44:41.000000000 -0700 @@ -13,12 +13,6 @@ #undef SIIMAGE_BUFFERED_TASKFILE #undef SIIMAGE_LARGE_DMA -#if 0 -typedef struct ide_io_ops_s siimage_iops { - -} -#endif - #define SII_DEBUG 0 #if SII_DEBUG @@ -27,12 +21,6 @@ #define siiprintk(x...) #endif -#define ADJREG(B,R) ((B)|(R)|((hwif->channel)<<(4+(2*(!!hwif->mmio))))) -#define SELREG(R) ADJREG((0xA0),(R)) -#define SELADDR(R) ((((unsigned long)hwif->hwif_data)*(!!hwif->mmio))|SELREG((R))) -#define HWIFADDR(R) ((((unsigned long)hwif->hwif_data)*(!!hwif->mmio))|(R)) -#define DEVADDR(R) (((unsigned long) pci_get_drvdata(dev))|(R)) - #if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) #include @@ -85,6 +73,19 @@ .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, .bootable = ON_BOARD, .extra = 0, + },{ /* 2 */ + .vendor = PCI_VENDOR_ID_CMD, + .device = PCI_DEVICE_ID_SII_1210SA, + .name = "Adaptec AAR-1210SA", + .init_chipset = init_chipset_siimage, + .init_iops = init_iops_siimage, + .init_hwif = init_hwif_siimage, + .init_dma = init_dma_siimage, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, + .bootable = ON_BOARD, + .extra = 0, },{ .vendor = 0, .device = 0, diff -urN linux-2.4.21/drivers/ide/pci/sis5513.c linux-2.4.22/drivers/ide/pci/sis5513.c --- linux-2.4.21/drivers/ide/pci/sis5513.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/sis5513.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,8 +1,9 @@ /* - * linux/drivers/ide/pci/sis5513.c Version 0.14ac Sept 11, 2002 + * linux/drivers/ide/pci/sis5513.c Version 0.16ac+vp Jun 18, 2003 * * Copyright (C) 1999-2000 Andre Hedrick * Copyright (C) 2002 Lionel Bouton , Maintainer + * Copyright (C) 2003 Vojtech Pavlik * May be copied or modified under the terms of the GNU General Public License * * @@ -14,31 +15,33 @@ * for checking code correctness, providing patches. * * - * Original tests and design on the SiS620/5513 chipset. - * ATA100 tests and design on the SiS735/5513 chipset. + * Original tests and design on the SiS620 chipset. + * ATA100 tests and design on the SiS735 chipset. * ATA16/33 support from specs * ATA133 support for SiS961/962 by L.C. Chang + * ATA133 961/962/963 fixes by Vojtech Pavlik * * Documentation: - * SiS chipset documentation available under NDA to companies not - * individuals only. + * SiS chipset documentation available under NDA to companies only + * (not to individuals). */ /* - * Notes/Special cases: - * - SiS5513 derivatives usually have the same PCI IDE register layout when - * supporting the same UDMA modes. - * - There are exceptions : - * . SiS730 and SiS550 use the same layout than ATA_66 chipsets but support - * ATA_100 - * . ATA_133 capable chipsets mark a shift in SiS chipset designs : previously - * south and northbridge were integrated, making IDE (a southbridge function) - * capabilities easily deduced from the northbridge PCI id. With ATA_133, - * chipsets started to be split in the usual north/south bridges chips - * -> the driver needs to detect the correct southbridge when faced to newest - * northbridges. - * . On ATA133 capable chipsets when bit 30 of dword at 0x54 is 1 the - * configuration space is moved from 0x40 to 0x70. + * The original SiS5513 comes from a SiS5511/55112/5513 chipset. The original + * SiS5513 was also used in the SiS5596/5513 chipset. Thus if we see a SiS5511 + * or SiS5596, we can assume we see the first MWDMA-16 capable SiS5513 chip. + * + * Later SiS chipsets integrated the 5513 functionality into the NorthBridge, + * starting with SiS5571 and up to SiS745. The PCI ID didn't change, though. We + * can figure out that we have a more modern and more capable 5513 by looking + * for the respective NorthBridge IDs. + * + * Even later (96x family) SiS chipsets use the MuTIOL link and place the 5513 + * into the SouthBrige. Here we cannot rely on looking up the NorthBridge PCI + * ID, while the now ATA-133 capable 5513 still has the same PCI ID. + * Fortunately the 5513 can be 'unmasked' by fiddling with some config space + * bits, changing its device id to the true one - 5517 for 961 and 5518 for + * 962/963. */ #include @@ -57,94 +60,23 @@ #include #include -#include #include +#include "ide-timing.h" #include "ide_modes.h" #include "sis5513.h" -/* 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 - -/* Miscellaneous flags */ -#define SIS5513_LATENCY 0x01 - /* 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_100a 0x04 // SiS730 is ATA100 with ATA66 layout +#define ATA_100a 0x04 // SiS730/SiS550 is ATA100 with ATA66 layout #define ATA_100 0x05 #define ATA_133a 0x06 // SiS961b with 133 support -#define ATA_133 0x07 // SiS962 -/* 2/ variable holding the controller chipset family value */ -static u8 chipset_family; - - -/* - * Debug code: following IDE config registers' changes - */ -#ifdef DEBUG -/* Copy of IDE Config registers fewer will be used - * Some odd chipsets hang if unused registers are accessed - * -> We only access them in #DEBUG code (then we'll see if SiS did - * it right from day one) */ -static u8 ide_regs_copy[0xff]; - -/* Read config registers, print differences from previous read */ -static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) { - int i; - u8 reg_val; - u8 changed=0; - - printk("SIS5513: %s, changed registers:\n", info); - for(i=0; i<=0xff; i++) { - pci_read_config_byte(dev, i, ®_val); - if (reg_val != ide_regs_copy[i]) { - printk("%02x: %02x -> %02x\n", - i, ide_regs_copy[i], reg_val); - ide_regs_copy[i]=reg_val; - changed=1; - } - } - - if (!changed) { - printk("none\n"); - } -} - -/* Load config registers, no printing */ -static void sis5513_load_registers(struct pci_dev* dev) { - int i; - - for(i=0; i<=0xff; i++) { - pci_read_config_byte(dev, i, &(ide_regs_copy[i])); - } -} - -/* Print config space registers a la "lspci -vxxx" */ -static void sis5513_print_registers(struct pci_dev* dev, char* marker) { - int i,j; - - sis5513_load_registers(dev); - printk("SIS5513 %s\n", marker); - - for(i=0; i<=0xf; i++) { - printk("SIS5513 dump: %d" "0:", i); - for(j=0; j<=0xf; j++) { - printk(" %02x", ide_regs_copy[(i<<16)+j]); - } - printk("\n"); - } -} -#endif +#define ATA_133 0x07 // SiS962/963 +static u8 chipset_family; /* * Devices supported @@ -155,41 +87,38 @@ u8 chipset_family; u8 flags; } SiSHostChipInfo[] = { - { "SiS752", PCI_DEVICE_ID_SI_752, ATA_133, 0 }, - { "SiS751", PCI_DEVICE_ID_SI_751, ATA_133, 0 }, - { "SiS750", PCI_DEVICE_ID_SI_750, ATA_133, 0 }, - { "SiS748", PCI_DEVICE_ID_SI_748, ATA_133, 0 }, - { "SiS746", PCI_DEVICE_ID_SI_746, ATA_133, 0 }, - { "SiS745", PCI_DEVICE_ID_SI_745, ATA_133, 0 }, - { "SiS740", PCI_DEVICE_ID_SI_740, ATA_100, 0 }, - { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100, SIS5513_LATENCY }, - { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a, SIS5513_LATENCY }, - { "SiS652", PCI_DEVICE_ID_SI_652, ATA_133, 0 }, - { "SiS651", PCI_DEVICE_ID_SI_651, ATA_133, 0 }, - { "SiS650", PCI_DEVICE_ID_SI_650, ATA_133, 0 }, - { "SiS648", PCI_DEVICE_ID_SI_648, ATA_133, 0 }, - { "SiS646", PCI_DEVICE_ID_SI_646, ATA_133, 0 }, - { "SiS645", PCI_DEVICE_ID_SI_645, ATA_133, 0 }, - { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100, SIS5513_LATENCY }, - { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66, SIS5513_LATENCY }, - { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66, SIS5513_LATENCY }, - { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66, SIS5513_LATENCY }, - { "SiS550", PCI_DEVICE_ID_SI_550, ATA_100a, 0}, - { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66, 0}, - { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66, 0}, - { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33, 0}, - { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33, 0}, - { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33, 0}, - { "SiS5591", PCI_DEVICE_ID_SI_5591, ATA_33, 0}, - { "SiS5513", PCI_DEVICE_ID_SI_5513, ATA_16, 0}, - { "SiS5511", PCI_DEVICE_ID_SI_5511, ATA_16, 0}, + { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 }, + { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 }, + { "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 }, + { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100 }, + { "SiS633", PCI_DEVICE_ID_SI_633, ATA_100 }, + + { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a }, + { "SiS550", PCI_DEVICE_ID_SI_550, ATA_100a }, + + { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66 }, + { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66 }, + { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66 }, + { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66 }, + { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66 }, + + { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33 }, + { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33 }, + { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33 }, + { "SiS5591/2", PCI_DEVICE_ID_SI_5591, ATA_33 }, + { "SiS5582", PCI_DEVICE_ID_SI_5582, ATA_33 }, + { "SiS5581", PCI_DEVICE_ID_SI_5581, ATA_33 }, + + { "SiS5596", PCI_DEVICE_ID_SI_5596, ATA_16 }, + { "SiS5571", PCI_DEVICE_ID_SI_5571, ATA_16 }, + { "SiS551x", PCI_DEVICE_ID_SI_5511, ATA_16 }, }; /* Cycle time bits and values vary across chip dma capabilities These three arrays hold the register layout and the values to set. Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ -/* {ATA_00, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ +/* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ static u8 cycle_time_offset[] = {0,0,5,4,4,0,0}; static u8 cycle_time_range[] = {0,0,2,3,3,4,4}; static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { @@ -248,8 +177,6 @@ {40,12,4,12,5,34,12,5}, }; -static struct pci_dev *host_dev = NULL; - /* * Printing configuration */ @@ -257,8 +184,8 @@ static char* chipset_capability[] = { "ATA", "ATA 16", "ATA 33", "ATA 66", - "ATA 100", "ATA 100", - "ATA 133", "ATA 133" + "ATA 100 (1st gen)", "ATA 100 (2nd gen)", + "ATA 133 (1st gen)", "ATA 133 (2nd gen)" }; #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) @@ -331,8 +258,9 @@ // Configuration space remapped to 0x70 drive_pci = 0x70; } - pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos, ®dw0); - pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos+4, ®dw1); + pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, ®dw0); + pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, ®dw1); + p += sprintf(p, "Drive %d:\n", pos); } @@ -357,8 +285,7 @@ case ATA_100a: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break; case ATA_100: case ATA_133a: p += sprintf(p, cycle_time[reg01 & 0x0F]); break; - case ATA_133: - default: p += sprintf(p, "133+ ?"); break; + default: p += sprintf(p, "?"); break; } p += sprintf(p, " \t UDMA Cycle Time "); switch(chipset_family) { @@ -367,42 +294,39 @@ case ATA_100a: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break; case ATA_100: case ATA_133a: p += sprintf(p, cycle_time[reg11 & 0x0F]); break; - case ATA_133: - default: p += sprintf(p, "133+ ?"); break; + default: p += sprintf(p, "?"); break; } p += sprintf(p, "\n"); } + + if (chipset_family < ATA_133) { /* else case TODO */ + /* Data Active */ - p += sprintf(p, " Data Active Time "); - switch(chipset_family) { - case ATA_00: - case ATA_16: /* confirmed */ - case ATA_33: - case ATA_66: - case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; - case ATA_100: - case ATA_133a: 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(chipset_family) { - case ATA_00: - case ATA_16: - case ATA_33: - case ATA_66: - case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; - case ATA_100: - case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; - case ATA_133: - default: p += sprintf(p, "133+ ?"); break; - } - p += sprintf(p, "\n"); + p += sprintf(p, " Data Active Time "); + switch(chipset_family) { + case ATA_16: /* confirmed */ + case ATA_33: + case ATA_66: + case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; + case ATA_100: + case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; + default: p += sprintf(p, "?"); break; + } + p += sprintf(p, " \t Data Active Time "); + switch(chipset_family) { + case ATA_16: + case ATA_33: + case ATA_66: + case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; + case ATA_100: + case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; + default: p += sprintf(p, "?"); break; + } + p += sprintf(p, "\n"); /* Data Recovery */ /* warning: may need (reg&0x07) for pre ATA66 chips */ - if (chipset_family < ATA_133) { p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]); } @@ -430,7 +354,6 @@ p += sprintf(p, "\nSiS 5513 "); 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; @@ -497,39 +420,16 @@ len = (p - buffer) - offset; *addr = buffer + offset; - + return len > count ? count : len; } #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */ static u8 sis5513_ratemask (ide_drive_t *drive) { -#if 0 u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 }; u8 mode = rates[chipset_family]; -#else - u8 mode; - switch(chipset_family) { - case ATA_133: - case ATA_133a: - mode = 4; - break; - case ATA_100: - case ATA_100a: - mode = 3; - break; - case ATA_66: - mode = 2; - break; - case ATA_33: - return 1; - case ATA_16: - case ATA_00: - default: - return 0; - } -#endif if (!eighty_ninty_three(drive)) mode = min(mode, (u8)1); return mode; @@ -547,20 +447,12 @@ u8 reg4bh = 0; u8 rw_prefetch = (0x11 << drive->dn); -#ifdef DEBUG - printk("SIS5513: config_drive_art_rwp, drive %d\n", drive->dn); - sis5513_load_verify_registers(dev, "config_drive_art_rwp start"); -#endif - if (drive->media != ide_disk) return; pci_read_config_byte(dev, 0x4b, ®4bh); if ((reg4bh & rw_prefetch) != rw_prefetch) pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); -#ifdef DEBUG - sis5513_load_verify_registers(dev, "config_drive_art_rwp end"); -#endif } @@ -575,10 +467,6 @@ u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90}; u16 xfer_pio = drive->id->eide_pio_modes; -#ifdef DEBUG - sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start"); -#endif - config_drive_art_rwp(drive); pio = ide_get_best_pio_mode(drive, 255, pio, NULL); @@ -598,12 +486,6 @@ timing = (xfer_pio >= pio) ? xfer_pio : pio; -#ifdef DEBUG - printk("SIS5513: config_drive_art_rwp_pio, " - "drive %d, pio %d, timing %d\n", - drive->dn, pio, timing); -#endif - /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */ drive_pci = 0x40; /* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */ @@ -649,41 +531,24 @@ pci_read_config_dword(dev, drive_pci, &test3); test3 &= 0xc0c00fff; if (test3 & 0x08) { - test3 |= (unsigned long)ini_time_value[ATA_133-ATA_00][timing] << 12; - test3 |= (unsigned long)act_time_value[ATA_133-ATA_00][timing] << 16; - test3 |= (unsigned long)rco_time_value[ATA_133-ATA_00][timing] << 24; + test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12; + test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16; + test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24; } else { - test3 |= (unsigned long)ini_time_value[ATA_100-ATA_00][timing] << 12; - test3 |= (unsigned long)act_time_value[ATA_100-ATA_00][timing] << 16; - test3 |= (unsigned long)rco_time_value[ATA_100-ATA_00][timing] << 24; + test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12; + test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16; + test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24; } pci_write_config_dword(dev, drive_pci, test3); } - -#ifdef DEBUG - sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start"); -#endif } static int config_chipset_for_pio (ide_drive_t *drive, u8 pio) { -#if 0 + if (pio == 255) + pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; config_art_rwp_pio(drive, pio); - return ide_config_drive_speed(drive, (XFER_PIO_0 + pio)); -#else - u8 speed; - - switch(pio) { - case 4: speed = XFER_PIO_4; break; - case 3: speed = XFER_PIO_3; break; - case 2: speed = XFER_PIO_2; break; - case 1: speed = XFER_PIO_1; break; - default: speed = XFER_PIO_0; break; - } - - config_art_rwp_pio(drive, pio); - return ide_config_drive_speed(drive, speed); -#endif + return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4)); } static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) @@ -694,24 +559,8 @@ u8 drive_pci, reg, speed; u32 regdw; -#ifdef DEBUG - sis5513_load_verify_registers(dev, "sis5513_tune_chipset start"); -#endif - -#ifdef BROKEN_LEVEL -#ifdef DEBUG - printk("SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d\n", xferspeed, BROKEN_LEVEL); -#endif - if (xferspeed > BROKEN_LEVEL) xferspeed = BROKEN_LEVEL; -#endif - speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed); -#ifdef DEBUG - printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n", - drive->dn, xferspeed); -#endif - /* See config_art_rwp_pio for drive pci config registers */ drive_pci = 0x40; if (chipset_family >= ATA_133) { @@ -750,14 +599,14 @@ regdw &= 0xfffff00f; /* check if ATA133 enable */ if (regdw & 0x08) { - regdw |= (unsigned long)cycle_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 4; - regdw |= (unsigned long)cvs_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 8; + regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4; + regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8; } else { /* if ATA133 disable, we should not set speed above UDMA5 */ if (speed > XFER_UDMA_5) speed = XFER_UDMA_5; - regdw |= (unsigned long)cycle_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 4; - regdw |= (unsigned long)cvs_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 8; + regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4; + regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8; } pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); } else { @@ -767,7 +616,7 @@ reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family])) << cycle_time_offset[chipset_family]); /* set reg cycle time bits */ - reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0] + reg |= cycle_time_value[chipset_family][speed-XFER_UDMA_0] << cycle_time_offset[chipset_family]; pci_write_config_byte(dev, drive_pci+1, reg); } @@ -786,9 +635,7 @@ case XFER_PIO_0: default: return((int) config_chipset_for_pio(drive, 0)); } -#ifdef DEBUG - sis5513_load_verify_registers(dev, "sis5513_tune_chipset end"); -#endif + return ((int) ide_config_drive_speed(drive, speed)); } @@ -867,71 +714,121 @@ return sis5513_config_drive_xfer_rate(drive); } +/* + Future simpler config_xfer_rate : + When ide_find_best_mode is made bad-drive aware + - remove config_drive_xfer_rate and config_chipset_for_dma, + - replace config_xfer_rate with the following + +static int sis5513_config_xfer_rate (ide_drive_t *drive) +{ + u16 w80 = HWIF(drive)->udma_four; + u16 speed; + + config_drive_art_rwp(drive); + config_art_rwp_pio(drive, 5); + + speed = ide_find_best_mode(drive, + XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | + (chipset_family >= ATA_33 ? XFER_UDMA : 0) | + (w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) | + (w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) | + (w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0)); + + sis5513_tune_chipset(drive, speed); + + if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) + return HWIF(drive)->ide_dma_on(drive); + return HWIF(drive)->ide_dma_off_quietly(drive); +} +*/ + /* Chip detection and general config */ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name) { struct pci_dev *host; int i = 0; - /* Find the chip */ - for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !host_dev; i++) { - host = pci_find_device (PCI_VENDOR_ID_SI, - SiSHostChipInfo[i].host_id, - NULL); + chipset_family = 0; + + for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) { + + host = pci_find_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL); + if (!host) continue; - host_dev = host; chipset_family = SiSHostChipInfo[i].chipset_family; + + /* Special case for SiS630 : 630S/ET is ATA_100a */ + if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) { + u8 hostrev; + pci_read_config_byte(host, PCI_REVISION_ID, &hostrev); + if (hostrev >= 0x30) + chipset_family = ATA_100a; + } - /* check 100/133 chipset family */ - if (chipset_family == ATA_133) { - u32 reg54h; - u16 reg02h; - pci_read_config_dword(dev, 0x54, ®54h); - pci_write_config_dword(dev, 0x54, (reg54h & 0x7fffffff)); - pci_read_config_word(dev, 0x02, ®02h); - pci_write_config_dword(dev, 0x54, reg54h); - /* devid 5518 here means SiS962 or later - which supports ATA133 */ - if (reg02h != 0x5518) { - u8 reg49h; - unsigned long sbrev; - /* SiS961 family */ - - /* - * FIXME !!! GAK!!!!!!!!!! PCI DIRECT POKING - */ - outl(0x80001008, 0x0cf8); - sbrev = inl(0x0cfc); + printk(KERN_INFO "SIS5513: %s %s controller\n", + SiSHostChipInfo[i].name, chipset_capability[chipset_family]); + } - pci_read_config_byte(dev, 0x49, ®49h); - if (((sbrev & 0xff) == 0x10) && (reg49h & 0x80)) - chipset_family = ATA_133a; - else - chipset_family = ATA_100; + if (!chipset_family) { /* Belongs to pci-quirks */ + + u32 idemisc; + u16 trueid; + + /* Disable ID masking and register remapping */ + pci_read_config_dword(dev, 0x54, &idemisc); + pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff)); + pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); + pci_write_config_dword(dev, 0x54, idemisc); + + if (trueid == 0x5518) { + printk(KERN_INFO "SIS5513: SiS 962/963 MuTIOL IDE UDMA133 controller\n"); + chipset_family = ATA_133; } - } - printk(SiSHostChipInfo[i].name); - printk(" %s controller", chipset_capability[chipset_family]); - printk("\n"); + } -#ifdef DEBUG - sis5513_print_registers(dev, "pci_init_sis5513 start"); -#endif + if (!chipset_family) { /* Belongs to pci-quirks */ - if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) { - u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency); - } + struct pci_dev *lpc_bridge; + u16 trueid; + u8 prefctl; + u8 idecfg; + u8 sbrev; + + pci_read_config_byte(dev, 0x4a, &idecfg); + pci_write_config_byte(dev, 0x4a, idecfg | 0x10); + pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); + pci_write_config_byte(dev, 0x4a, idecfg); + + if (trueid == 0x5517) { /* SiS 961/961B */ + + lpc_bridge = pci_find_slot(0x00, 0x10); /* Bus 0, Dev 2, Fn 0 */ + pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev); + pci_read_config_byte(dev, 0x49, &prefctl); + + if (sbrev == 0x10 && (prefctl & 0x80)) { + printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n"); + chipset_family = ATA_133a; + } else { + printk(KERN_INFO "SIS5513: SiS 961 MuTIOL IDE UDMA100 controller\n"); + chipset_family = ATA_100; + } + } } + if (!chipset_family) + return -1; + /* Make general config ops here 1/ tell IDE channels to operate in Compatibility mode only 2/ tell old chips to allow per drive IDE timings */ - if (host_dev) { + + { u8 reg; u16 regw; + switch(chipset_family) { case ATA_133: /* SiS962 operation mode */ @@ -944,6 +841,8 @@ break; case ATA_133a: case ATA_100: + /* Fixup latency */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); /* Set compatibility bit */ pci_read_config_byte(dev, 0x49, ®); if (!(reg & 0x01)) { @@ -952,6 +851,9 @@ break; case ATA_100a: case ATA_66: + /* Fixup latency */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); + /* On ATA_66 chips the bit was elsewhere */ pci_read_config_byte(dev, 0x52, ®); if (!(reg & 0x04)) { @@ -972,8 +874,6 @@ pci_write_config_byte(dev, 0x52, reg|0x08); } break; - case ATA_00: - default: break; } #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) @@ -984,9 +884,7 @@ } #endif } -#ifdef DEBUG - sis5513_load_verify_registers(dev, "pci_init_sis5513 end"); -#endif + return 0; } @@ -1029,7 +927,7 @@ hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - if (!host_dev) + if (!chipset_family) return; if (!(hwif->udma_four)) @@ -1087,7 +985,7 @@ module_init(sis5513_ide_init); module_exit(sis5513_ide_exit); -MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick"); +MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik"); MODULE_DESCRIPTION("PCI driver module for SIS IDE"); MODULE_LICENSE("GPL"); @@ -1095,13 +993,10 @@ /* * TODO: - * - Get ridden of SisHostChipInfo[] completness dependancy. - * - Study drivers/ide/ide-timing.h. - * - Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them - * or remove ATA_00 define + * - CLEANUP + * - Use drivers/ide/ide-timing.h ! * - More checks in the config registers (force values instead of * relying on the BIOS setting them correctly). * - Further optimisations ? * . for example ATA66+ regs 0x48 & 0x4A */ - diff -urN linux-2.4.21/drivers/ide/pci/via82cxxx.c linux-2.4.22/drivers/ide/pci/via82cxxx.c --- linux-2.4.21/drivers/ide/pci/via82cxxx.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.22/drivers/ide/pci/via82cxxx.c 2003-08-25 04:44:41.000000000 -0700 @@ -484,7 +484,7 @@ for (i = 24; i >= 0; i -= 8) if (((u >> i) & 0x10) || (((u >> i) & 0x20) && - (((u >> i) & 7) < 8))) { + (((u >> i) & 7) < 6))) { /* BIOS 80-wire bit or * UDMA w/ < 60ns/cycle */ diff -urN linux-2.4.21/drivers/ide/raid/hptraid.c linux-2.4.22/drivers/ide/raid/hptraid.c --- linux-2.4.21/drivers/ide/raid/hptraid.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ide/raid/hptraid.c 2003-08-25 04:44:41.000000000 -0700 @@ -17,7 +17,30 @@ Copyright (C) 1994-96 Marc ZYNGIER Based on work done by Søren Schmidt for FreeBSD - + Changelog: + 15.06.2003 wweissmann@gmx.at + * correct values of raid-1 superbock + * re-add check for availability of all disks + * fix offset bug in raid-1 (introduced in raid 0+1 implementation) + + 14.06.2003 wweissmann@gmx.at + * superblock has wrong "disks" value on raid-1 + * fixup for raid-1 disknumbering + * do _NOT_ align size to 255*63 boundary + I WILL NOT USE FDISK TO DETERMINE THE VOLUME SIZE. + I WILL NOT USE FDISK TO DETERMINE THE VOLUME SIZE. + I WILL NOT USE FDISK TO DETERMINE THE VOLUME SIZE. + I WILL NOT ... + + 13.06.2003 wweissmann@gmx.at + * raid 0+1 support + * check if all disks of an array are available + * bump version number + + 29.05.2003 wweissmann@gmx.at + * release no more devices than available on unload + * remove static variables in raid-1 read path + */ #include @@ -34,6 +57,8 @@ #include #include "ataraid.h" +#include "hptraid.h" + static int hptraid_open(struct inode * inode, struct file * filp); static int hptraid_release(struct inode * inode, struct file * filp); @@ -41,26 +66,30 @@ static int hptraidspan_make_request (request_queue_t *q, int rw, struct buffer_head * bh); static int hptraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh); static int hptraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh); +static int hptraid01_make_request (request_queue_t *q, int rw, struct buffer_head * bh); struct hptdisk { - kdev_t device; + kdev_t device; /* disk-ID/raid 0+1 volume-ID */ unsigned long sectors; struct block_device *bdev; unsigned long last_pos; }; struct hptraid { - unsigned int stride; - unsigned int disks; - unsigned long sectors; + unsigned int stride; /* stripesize */ + unsigned int disks; /* number of disks in array */ + unsigned long sectors; /* disksize in sectors */ u_int32_t magic_0; + u_int32_t magic_1; struct geom geom; + int previous; /* most recently accessed disk in mirror */ struct hptdisk disk[8]; - unsigned long cutoff[8]; + unsigned long cutoff[8]; /* raid 0 cutoff */ unsigned int cutoff_disks[8]; + struct hptraid * raid01; /* sub arrays for raid 0+1 */ }; struct hptraid_dev { @@ -109,9 +138,30 @@ make_request: hptraid1_make_request }; + +static struct raid_device_operations hptraid01_ops = { + open: hptraid_open, + release: hptraid_release, + ioctl: hptraid_ioctl, + make_request: hptraid01_make_request +}; + +static __init struct { + struct raid_device_operations *op; + u_int8_t type; + char label[8]; +} oplist[] = { + {&hptraid0_ops, HPT_T_RAID_0, "RAID 0"}, + {&hptraid1_ops, HPT_T_RAID_1, "RAID 1"}, + {&hptraidspan_ops, HPT_T_SPAN, "SPAN"}, + {&hptraid01_ops, HPT_T_RAID_01_RAID_0, "RAID 0+1"}, + {0, 0} +}; + static struct hptraid raid[14]; -static int hptraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static int hptraid_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { unsigned int minor; unsigned char val; @@ -185,7 +235,10 @@ device = (bh->b_rdev >> SHIFT)&MAJOR_MASK; thisraid = &raid[device]; - /* Partitions need adding of the start sector of the partition to the requested sector */ + /* + * Partitions need adding of the start sector of the partition to the + * requested sector + */ rsect += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; @@ -216,58 +269,58 @@ return 1; } -static int hptraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh) +static int hptraid0_compute_request (struct hptraid *thisraid, + request_queue_t *q, + int rw, struct buffer_head * bh) { - unsigned long rsect; unsigned long rsect_left,rsect_accum = 0; unsigned long block; unsigned int disk=0,real_disk=0; int i; - int device; - struct hptraid *thisraid; - - rsect = bh->b_rsector; - /* Ok. We need to modify this sector number to a new disk + new sector number. + /* Ok. We need to modify this sector number to a new disk + new sector + * number. * If there are disks of different sizes, this gets tricky. * Example with 3 disks (1Gb, 4Gb and 5 GB): * The first 3 Gb of the "RAID" are evenly spread over the 3 disks. - * Then things get interesting. The next 2Gb (RAID view) are spread across disk 2 and 3 - * and the last 1Gb is disk 3 only. + * Then things get interesting. The next 2Gb (RAID view) are spread + * across disk 2 and 3 and the last 1Gb is disk 3 only. * - * the way this is solved is like this: We have a list of "cutoff" points where everytime - * a disk falls out of the "higher" count, we mark the max sector. So once we pass a cutoff - * point, we have to divide by one less. + * the way this is solved is like this: We have a list of "cutoff" + * points where everytime a disk falls out of the "higher" count, we + * mark the max sector. So once we pass a cutoff point, we have to + * divide by one less. */ - device = (bh->b_rdev >> SHIFT)&MAJOR_MASK; - thisraid = &raid[device]; if (thisraid->stride==0) thisraid->stride=1; - /* Partitions need adding of the start sector of the partition to the requested sector */ - - rsect += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; - - /* Woops we need to split the request to avoid crossing a stride barrier */ - if ((rsect/thisraid->stride) != ((rsect+(bh->b_size/512)-1)/thisraid->stride)) { + /* + * Woops we need to split the request to avoid crossing a stride + * barrier + */ + if ((bh->b_rsector/thisraid->stride) != + ((bh->b_rsector+(bh->b_size/512)-1)/thisraid->stride)) { return -1; } - rsect_left = rsect; + rsect_left = bh->b_rsector;; for (i=0;i<8;i++) { if (thisraid->cutoff_disks[i]==0) break; - if (rsect > thisraid->cutoff[i]) { + if (bh->b_rsector > thisraid->cutoff[i]) { /* we're in the wrong area so far */ rsect_left -= thisraid->cutoff[i]; - rsect_accum += thisraid->cutoff[i]/thisraid->cutoff_disks[i]; + rsect_accum += thisraid->cutoff[i] / + thisraid->cutoff_disks[i]; } else { block = rsect_left / thisraid->stride; disk = block % thisraid->cutoff_disks[i]; - block = (block / thisraid->cutoff_disks[i]) * thisraid->stride; - rsect = rsect_accum + (rsect_left % thisraid->stride) + block; + block = (block / thisraid->cutoff_disks[i]) * + thisraid->stride; + bh->b_rsector = rsect_accum + + (rsect_left % thisraid->stride) + block; break; } } @@ -286,7 +339,7 @@ /* All but the first disk have a 10 sector offset */ if (i>0) - rsect+=10; + bh->b_rsector+=10; /* @@ -295,7 +348,6 @@ */ bh->b_rdev = thisraid->disk[disk].device; - bh->b_rsector = rsect; /* * Let the main block layer submit the IO and resolve recursion: @@ -303,12 +355,39 @@ return 1; } +static int hptraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh) +{ + unsigned long rsect; + int device; + + /* + * save the sector, it must be restored before a request-split + * is performed + */ + rsect = bh->b_rsector; + + /* + * Partitions need adding of the start sector of the partition to the + * requested sector + */ + + bh->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; + + device = (bh->b_rdev >> SHIFT)&MAJOR_MASK; + if( hptraid0_compute_request(raid+device, q, rw, bh) != 1 ) { + /* request must be split => restore sector */ + bh->b_rsector = rsect; + return -1; + } + + return 1; +} + static int hptraid1_read_request (request_queue_t *q, int rw, struct buffer_head * bh) { int device; int dist; int bestsofar,bestdist,i; - static int previous; /* Reads are simple in principle. Pick a disk and go. Initially I cheat by just picking the one which the last known @@ -331,11 +410,15 @@ dist = -dist; if (dist>4095) dist=4095; - - if (bestdist==dist) { /* it's a tie; try to do some read balancing */ - if ((previous>bestsofar)&&(previous<=i)) + + /* it's a tie; try to do some read balancing */ + if (bestdist==dist) { + if ( (raid[device].previous>bestsofar) && + (raid[device].previous<=i) ) bestsofar = i; - previous = (previous + 1) % raid[device].disks; + raid[device].previous = + (raid[device].previous + 1) % + raid[device].disks; } else if (bestdist>dist) { bestdist = dist; bestsofar = i; @@ -343,7 +426,6 @@ } - bh->b_rsector += bestsofar?10:0; bh->b_rdev = raid[device].disk[bestsofar].device; raid[device].disk[bestsofar].last_pos = bh->b_rsector+(bh->b_size>>9); @@ -377,24 +459,49 @@ if (!bh1) BUG(); - /* dupe the bufferhead and update the parts that need to be different */ + /* + * dupe the bufferhead and update the parts that need to be + * different + */ memcpy(bh1, bh, sizeof(*bh)); bh1->b_end_io = ataraid_end_request; bh1->b_private = private; - bh1->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect+(i==0?0:10); /* partition offset */ + bh1->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; /* partition offset */ bh1->b_rdev = raid[device].disk[i].device; /* update the last known head position for the drive */ raid[device].disk[i].last_pos = bh1->b_rsector+(bh1->b_size>>9); + if( raid[device].raid01 ) { + if( hptraid0_compute_request( + raid[device].raid01 + + (bh1->b_rdev-1), + q, rw, bh1) != 1 ) { + /* + * If a split is requested then it is requested + * in the first iteration. This is true because + * of the cutoff is not used in raid 0+1. + */ + if(unlikely(i)) { + BUG(); + } + else { + kfree(private); + return -1; + } + } + } generic_make_request(rw,bh1); } return 0; } static int hptraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { - /* Read and Write are totally different cases; split them totally here */ + /* + * Read and Write are totally different cases; split them totally + * here + */ if (rw==READA) rw = READ; @@ -404,7 +511,43 @@ return hptraid1_write_request(q,rw,bh); } -#include "hptraid.h" +static int hptraid01_read_request (request_queue_t *q, int rw, struct buffer_head * bh) +{ + int rsector=bh->b_rsector; + int rdev=bh->b_rdev; + + /* select mirror volume */ + hptraid1_read_request(q, rw, bh); + + /* stripe volume is selected by "bh->b_rdev" */ + if( hptraid0_compute_request( + raid[(bh->b_rdev >> SHIFT)&MAJOR_MASK]. + raid01 + (bh->b_rdev-1) , + q, rw, bh) != 1 ) { + + /* request must be split => restore sector and device */ + bh->b_rsector = rsector; + bh->b_rdev = rdev; + return -1; + + } + + return 1; +} + +static int hptraid01_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { + /* + * Read and Write are totally different cases; split them totally + * here + */ + if (rw==READA) + rw = READ; + + if (rw==READ) + return hptraid01_read_request(q,rw,bh); + else + return hptraid1_write_request(q,rw,bh); +} static int read_disk_sb (int major, int minor, unsigned char *buffer,int bufsize) { @@ -456,77 +599,140 @@ return lba; } -static void __init probedisk(struct hptraid_dev *disk, int device, u_int8_t type) +static void writeentry(struct hptraid * raid, struct hptraid_dev * disk, + int index, struct highpoint_raid_conf * prom) { + + int j=0; + struct gendisk *gd; + struct block_device *bdev; + + bdev = bdget(MKDEV(disk->major,disk->minor)); + if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) { + raid->disk[index].bdev = bdev; + /* + * This is supposed to prevent others from stealing our + * underlying disks now blank the /proc/partitions table for + * the wrong partition table, so that scripts don't + * accidentally mount it and crash the kernel + */ + /* XXX: the 0 is an utter hack --hch */ + gd=get_gendisk(MKDEV(disk->major, 0)); + if (gd!=NULL) { + if (gd->major==disk->major) + for (j=1+(disk->minor<minor_shift); + j<((disk->minor+1)<minor_shift); + j++) gd->part[j].nr_sects=0; + } + } + raid->disk[index].device = MKDEV(disk->major,disk->minor); + raid->disk[index].sectors = maxsectors(disk->major,disk->minor); + raid->stride = (1<raid0_shift); + raid->disks = prom->raid_disks; + raid->sectors = prom->total_secs; + raid->sectors += raid->sectors&1?1:0; + raid->magic_0=prom->magic_0; + raid->magic_1=prom->magic_1; + +} + +static int probedisk(struct hptraid_dev *disk, int device, u_int8_t type) { - int i; + int i, j; struct highpoint_raid_conf *prom; static unsigned char block[4096]; - struct block_device *bdev; if (disk->device != -1) /* disk is occupied? */ - return; + return 0; if (maxsectors(disk->major,disk->minor)==0) - return; + return 0; if (read_disk_sb(disk->major,disk->minor,(unsigned char*)&block,sizeof(block))) - return; + return 0; prom = (struct highpoint_raid_conf*)&block[512]; if (prom->magic!= 0x5a7816f0) - return; + return 0; switch (prom->type) { case HPT_T_SPAN: case HPT_T_RAID_0: case HPT_T_RAID_1: + case HPT_T_RAID_01_RAID_0: if(prom->type != type) - return; + return 0; break; default: - printk(KERN_INFO "hptraid: only SPAN, RAID0 and RAID1 is currently supported \n"); - return; + printk(KERN_INFO "hptraid: unknown raid level-id %i\n", + prom->type); + return 0; } /* disk from another array? */ - if(raid[device].disks && prom->magic_0 != raid[device].magic_0) - return; + if (raid[device].disks) { /* only check if raid is not empty */ + if (type == HPT_T_RAID_01_RAID_0 ) { + if( prom->magic_1 != raid[device].magic_1) { + return 0; + } + } + else if (prom->magic_0 != raid[device].magic_0) { + return 0; + } + } i = prom->disk_number; if (i<0) - return; + return 0; if (i>8) - return; + return 0; - bdev = bdget(MKDEV(disk->major,disk->minor)); - if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) { - int j=0; - struct gendisk *gd; - raid[device].disk[i].bdev = bdev; - /* This is supposed to prevent others from stealing our underlying disks */ - /* now blank the /proc/partitions table for the wrong partition table, - so that scripts don't accidentally mount it and crash the kernel */ - /* XXX: the 0 is an utter hack --hch */ - gd=get_gendisk(MKDEV(disk->major, 0)); - if (gd!=NULL) { - if (gd->major==disk->major) - for (j=1+(disk->minor<minor_shift); - j<((disk->minor+1)<minor_shift); - j++) gd->part[j].nr_sects=0; + if ( type == HPT_T_RAID_01_RAID_0 ) { + + /* allocate helper raid devices for level 0+1 */ + if (raid[device].raid01 == NULL ) { + + raid[device].raid01= + kmalloc(2 * sizeof(struct hptraid),GFP_KERNEL); + if ( raid[device].raid01 == NULL ) { + printk(KERN_ERR "hptraid: out of memory\n"); + raid[device].disks=-1; + return -ENOMEM; + } + memset(raid[device].raid01, 0, + 2 * sizeof(struct hptraid)); } - } - raid[device].disk[i].device = MKDEV(disk->major,disk->minor); - raid[device].disk[i].sectors = maxsectors(disk->major,disk->minor); - raid[device].stride = (1<raid0_shift); - raid[device].disks = prom->raid_disks; - raid[device].sectors = prom->total_secs-(prom->total_secs%(255*63)); - raid[device].sectors += raid[device].sectors&1?1:0; - raid[device].magic_0=prom->magic_0; + + /* find free sub-stucture */ + for (j=0; j<2; j++) { + if ( raid[device].raid01[j].disks == 0 || + raid[device].raid01[j].magic_0 == prom->magic_0 ) + { + writeentry(raid[device].raid01+j, disk, + i, prom); + break; + } + } + + /* no free slot */ + if(j == 2) + return 0; + + raid[device].stride=raid[device].raid01[j].stride; + raid[device].disks=j+1; + raid[device].sectors=raid[device].raid01[j].sectors; + raid[device].disk[j].sectors=raid[device].raid01[j].sectors; + raid[device].magic_1=prom->magic_1; + } + else { + writeentry(raid+device, disk, i, prom); + } + disk->device=device; + return 1; } -static void __init fill_cutoff(int device) +static void fill_cutoff(struct hptraid * device) { int i,j; unsigned long smallest; @@ -537,111 +743,154 @@ for (i=0;i<8;i++) { smallest = ~0; for (j=0;j<8;j++) - if ((raid[device].disk[j].sectors < smallest) && (raid[device].disk[j].sectors>bar)) - smallest = raid[device].disk[j].sectors; + if ((device->disk[j].sectors < smallest) && (device->disk[j].sectors>bar)) + smallest = device->disk[j].sectors; count = 0; for (j=0;j<8;j++) - if (raid[device].disk[j].sectors >= smallest) + if (device->disk[j].sectors >= smallest) count++; smallest = smallest * count; bar = smallest; - raid[device].cutoff[i] = smallest; - raid[device].cutoff_disks[i] = count; + device->cutoff[i] = smallest; + device->cutoff_disks[i] = count; } } +static int count_disks(struct hptraid * raid) { + int i, count=0; + for (i=0;i<8;i++) { + if (raid->disk[i].device!=0) { + printk(KERN_INFO "Drive %i is %li Mb \n", + i,raid->disk[i].sectors/2048); + count++; + } + } + return count; +} + +static void raid1_fixup(struct hptraid * raid) { + int i, count=0; + for (i=0;i<8;i++) { + /* disknumbers and total disks values are bogus */ + if (raid->disk[i].device!=0) { + raid->disk[count]=raid->disk[i]; + if(i > count) { + memset(raid->disk+i, 0, sizeof(struct hptdisk)); + } + count++; + } + } + raid->disks=count; +} -static __init int hptraid_init_one(int device, u_int8_t type) +static int hptraid_init_one(int device, u_int8_t type, const char * label) { int i,count; - memset(raid+device, 0, sizeof(struct hptraid)); - for(i=0; i < 14; i++) { - probedisk(devlist+i, device, type); + for (i=0; i < 14; i++) { + if( probedisk(devlist+i, device, type) < 0 ) + return -EINVAL; + } + + /* Initialize raid levels */ + switch (type) { + case HPT_T_RAID_0: + fill_cutoff(raid+device); + break; + + case HPT_T_RAID_1: + raid1_fixup(raid+device); + break; + + case HPT_T_RAID_01_RAID_0: + for(i=0; i < 2 && raid[device].raid01 && + raid[device].raid01[i].disks; i++) { + fill_cutoff(raid[device].raid01+i); + /* initialize raid 0+1 volumes */ + raid[device].disk[i].device=i+1; + } + break; } - if(type == HPT_T_RAID_0) - fill_cutoff(device); - /* Initialize the gendisk structure */ ataraid_register_disk(device,raid[device].sectors); - count=0; + /* Verify that we have all disks */ + + count=count_disks(raid+device); - for (i=0;i<8;i++) { - if (raid[device].disk[i].device!=0) { - printk(KERN_INFO "Drive %i is %li Mb \n", - i,raid[device].disk[i].sectors/2048); - count++; - } + if (count != raid[device].disks) { + printk(KERN_INFO "%s consists of %i drives but found %i drives\n", + label, raid[device].disks, count); + return -ENODEV; } - if (count) { - printk(KERN_INFO "Raid array consists of %i drives. \n",count); + else if (count) { + printk(KERN_INFO "%s consists of %i drives.\n", + label, count); + if (type == HPT_T_RAID_01_RAID_0 ) { + for(i=0;ipci_dev; @@ -183,10 +183,9 @@ second_chance_to_dma: #endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */ - if ((hwif->mmio) && (hwif->dma_base)) + if (hwif->mmio && hwif->dma_base) return hwif->dma_base; - - if (hwif->mate && hwif->mate->dma_base) { + else if (hwif->mate && hwif->mate->dma_base) { dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8); } else { dma_base = (hwif->mmio) ? diff -urN linux-2.4.21/drivers/ieee1394/Config.in linux-2.4.22/drivers/ieee1394/Config.in --- linux-2.4.21/drivers/ieee1394/Config.in 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/Config.in 2003-08-25 04:44:41.000000000 -0700 @@ -40,6 +40,7 @@ fi bool 'Excessive debugging output' CONFIG_IEEE1394_VERBOSEDEBUG + bool "OUI Database built-in" CONFIG_IEEE1394_OUI_DB fi endmenu fi diff -urN linux-2.4.21/drivers/ieee1394/Makefile linux-2.4.22/drivers/ieee1394/Makefile --- linux-2.4.21/drivers/ieee1394/Makefile 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/Makefile 2003-08-25 04:44:41.000000000 -0700 @@ -8,7 +8,7 @@ list-multi := ieee1394.o ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \ - highlevel.o csr.o nodemgr.o dma.o iso.o + highlevel.o csr.o nodemgr.o oui.o dma.o iso.o obj-$(CONFIG_IEEE1394) += ieee1394.o obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o @@ -25,3 +25,7 @@ ieee1394.o: $(ieee1394-objs) $(LD) $(LDFLAGS) -r -o $@ $(ieee1394-objs) + +oui.o: oui.c +oui.c: oui.db oui2c.sh + $(CONFIG_SHELL) oui2c.sh < oui.db > $@ diff -urN linux-2.4.21/drivers/ieee1394/amdtp.c linux-2.4.22/drivers/ieee1394/amdtp.c --- linux-2.4.21/drivers/ieee1394/amdtp.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/amdtp.c 2003-08-25 04:44:41.000000000 -0700 @@ -62,6 +62,12 @@ * - Maybe make an ALSA interface, that is, create a file_ops * implementation that recognizes ALSA ioctls and uses defaults for * things that can't be controlled through ALSA (iso channel). + * + * Changes: + * + * - Audit copy_from_user in amdtp_write. + * Daniele Bellucci + * */ #include @@ -732,7 +738,7 @@ /* Fill IEEE1394 headers */ packet->db->header_desc.header[0] = - (SPEED_100 << 16) | (0x01 << 14) | + (IEEE1394_SPEED_100 << 16) | (0x01 << 14) | (s->iso_channel << 8) | (TCODE_ISO_DATA << 4); packet->db->header_desc.header[1] = size << 16; @@ -1112,7 +1118,8 @@ for (i = 0; i < count; i += length) { p = buffer_put_bytes(s->input, count - i, &length); - copy_from_user(p, buffer + i, length); + if (copy_from_user(p, buffer + i, length)) + return -EFAULT; if (s->input->length < s->input->size) continue; diff -urN linux-2.4.21/drivers/ieee1394/cmp.c linux-2.4.22/drivers/ieee1394/cmp.c --- linux-2.4.21/drivers/ieee1394/cmp.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/cmp.c 2003-08-25 04:44:41.000000000 -0700 @@ -137,7 +137,7 @@ } ch->host = host; - ch->u.ompr.rate = SPEED_100; + ch->u.ompr.rate = IEEE1394_SPEED_100; ch->u.ompr.bcast_channel_base = 63; ch->u.ompr.nplugs = 2; diff -urN linux-2.4.21/drivers/ieee1394/csr.c linux-2.4.22/drivers/ieee1394/csr.c --- linux-2.4.21/drivers/ieee1394/csr.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/csr.c 2003-08-25 04:44:41.000000000 -0700 @@ -19,6 +19,7 @@ #include #include /* needed for MODULE_PARM */ +#include #include "ieee1394_types.h" #include "hosts.h" @@ -87,6 +88,35 @@ 0x3f1)); } +/* + * HI == seconds (bits 0:2) + * LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31) + * + * Convert to units and then to HZ, for comparison to jiffies. + * + * By default this will end up being 800 units, or 100ms (125usec per + * unit). + * + * NOTE: The spec says 1/8000, but also says we can compute based on 1/8192 + * like CSR specifies. Should make our math less complex. + */ +static inline void calculate_expire(struct csr_control *csr) +{ + unsigned long units; + + /* Take the seconds, and convert to units */ + units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13; + + /* Add in the fractional units */ + units += (unsigned long)(csr->split_timeout_lo >> 19); + + /* Convert to jiffies */ + csr->expire = (unsigned long)(units * HZ) >> 13UL; + + /* Just to keep from rounding low */ + csr->expire++; +} + static void add_host(struct hpsb_host *host) { @@ -98,6 +128,7 @@ host->csr.node_ids = 0; host->csr.split_timeout_hi = 0; host->csr.split_timeout_lo = 800 << 19; + calculate_expire(&host->csr); host->csr.cycle_time = 0; host->csr.bus_time = 0; host->csr.bus_manager_id = 0x3f; @@ -334,10 +365,12 @@ case CSR_SPLIT_TIMEOUT_HI: host->csr.split_timeout_hi = be32_to_cpu(*(data++)) & 0x00000007; + calculate_expire(&host->csr); out; case CSR_SPLIT_TIMEOUT_LO: host->csr.split_timeout_lo = be32_to_cpu(*(data++)) & 0xfff80000; + calculate_expire(&host->csr); out; /* address gap */ @@ -408,7 +441,7 @@ * eventually. */ HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release " "broadcast channel 31. Ignoring.", - NODE_BUS_ARGS(nodeid)); + NODE_BUS_ARGS(host, nodeid)); data &= ~0x1; /* keep broadcast channel allocated */ } @@ -554,7 +587,7 @@ * eventually. */ HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release " "broadcast channel 31. Ignoring.", - NODE_BUS_ARGS(nodeid)); + NODE_BUS_ARGS(host, nodeid)); data &= ~0x100000000ULL; /* keep broadcast channel allocated */ } diff -urN linux-2.4.21/drivers/ieee1394/csr.h linux-2.4.22/drivers/ieee1394/csr.h --- linux-2.4.21/drivers/ieee1394/csr.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/csr.h 2003-08-25 04:44:41.000000000 -0700 @@ -2,6 +2,10 @@ #ifndef _IEEE1394_CSR_H #define _IEEE1394_CSR_H +#ifdef CONFIG_PREEMPT +#include +#endif + #define CSR_REGISTER_BASE 0xfffff0000000ULL /* register offsets relative to CSR_REGISTER_BASE */ @@ -37,6 +41,7 @@ quadlet_t state; quadlet_t node_ids; quadlet_t split_timeout_hi, split_timeout_lo; + unsigned long expire; // Calculated from split_timeout quadlet_t cycle_time; quadlet_t bus_time; quadlet_t bus_manager_id; diff -urN linux-2.4.21/drivers/ieee1394/dma.c linux-2.4.22/drivers/ieee1394/dma.c --- linux-2.4.21/drivers/ieee1394/dma.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/dma.c 2003-08-25 04:44:41.000000000 -0700 @@ -10,6 +10,7 @@ #include #include #include +#include #include "dma.h" /* dma_prog_region */ @@ -30,7 +31,7 @@ prog->n_pages = n_bytes / PAGE_SIZE; prog->kvirt = pci_alloc_consistent(dev, prog->n_pages * PAGE_SIZE, &prog->bus_addr); - if(!prog->kvirt) { + if (!prog->kvirt) { printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n"); dma_prog_region_free(prog); return -ENOMEM; @@ -43,7 +44,7 @@ void dma_prog_region_free(struct dma_prog_region *prog) { - if(prog->kvirt) { + if (prog->kvirt) { pci_free_consistent(prog->dev, prog->n_pages * PAGE_SIZE, prog->kvirt, prog->bus_addr); } @@ -74,7 +75,7 @@ n_pages = n_bytes / PAGE_SIZE; dma->kvirt = vmalloc_32(n_pages * PAGE_SIZE); - if(!dma->kvirt) { + if (!dma->kvirt) { printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n"); goto err; } @@ -86,7 +87,7 @@ /* allocate scatter/gather list */ dma->sglist = kmalloc(dma->n_pages * sizeof(struct scatterlist), GFP_KERNEL); - if(!dma->sglist) { + if (!dma->sglist) { printk(KERN_ERR "dma_region_alloc: kmalloc(sglist) failed\n"); goto err; } @@ -95,7 +96,7 @@ memset(dma->sglist, 0, dma->n_pages * sizeof(struct scatterlist)); /* fill scatter/gather list with pages */ - for(i = 0; i < dma->n_pages; i++) { + for (i = 0; i < dma->n_pages; i++) { unsigned long va = (unsigned long) dma->kvirt + i * PAGE_SIZE; dma->sglist[i].page = vmalloc_to_page((void *)va); @@ -105,7 +106,7 @@ /* map sglist to the IOMMU */ dma->n_dma_pages = pci_map_sg(dev, &dma->sglist[0], dma->n_pages, direction); - if(dma->n_dma_pages == 0) { + if (dma->n_dma_pages == 0) { printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n"); goto err; } @@ -122,18 +123,18 @@ void dma_region_free(struct dma_region *dma) { - if(dma->n_dma_pages) { + if (dma->n_dma_pages) { pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, dma->direction); dma->n_dma_pages = 0; dma->dev = NULL; } - if(dma->sglist) { + if (dma->sglist) { kfree(dma->sglist); dma->sglist = NULL; } - if(dma->kvirt) { + if (dma->kvirt) { vfree(dma->kvirt); dma->kvirt = NULL; dma->n_pages = 0; @@ -147,16 +148,18 @@ int i; unsigned long off = offset; - for(i = 0; i < dma->n_dma_pages; i++) { - if(off < sg_dma_len(&dma->sglist[i])) { + for (i = 0; i < dma->n_dma_pages; i++) { + if (off < sg_dma_len(&dma->sglist[i])) { *rem = off; - return i; + break; } off -= sg_dma_len(&dma->sglist[i]); } - panic("dma_region_find: offset %lu beyond end of DMA mapping\n", offset); + BUG_ON(i >= dma->n_dma_pages); + + return i; } dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset) @@ -172,7 +175,7 @@ int first, last; unsigned long rem; - if(!len) + if (!len) len = 1; first = dma_region_find(dma, offset, &rem); @@ -192,10 +195,10 @@ struct dma_region *dma = (struct dma_region*) area->vm_private_data; - if(!dma->kvirt) + if (!dma->kvirt) goto out; - if( (address < (unsigned long) area->vm_start) || + if ( (address < (unsigned long) area->vm_start) || (address > (unsigned long) area->vm_start + (PAGE_SIZE * dma->n_pages)) ) goto out; @@ -215,16 +218,16 @@ { unsigned long size; - if(!dma->kvirt) + if (!dma->kvirt) return -EINVAL; /* must be page-aligned */ - if(vma->vm_pgoff != 0) + if (vma->vm_pgoff != 0) return -EINVAL; /* check the length */ size = vma->vm_end - vma->vm_start; - if(size > (PAGE_SIZE * dma->n_pages)) + if (size > (PAGE_SIZE * dma->n_pages)) return -EINVAL; vma->vm_ops = &dma_region_vm_ops; diff -urN linux-2.4.21/drivers/ieee1394/dma.h linux-2.4.22/drivers/ieee1394/dma.h --- linux-2.4.21/drivers/ieee1394/dma.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/dma.h 2003-08-25 04:44:41.000000000 -0700 @@ -76,7 +76,7 @@ /* round up a number of bytes to be a multiple of the PAGE_SIZE */ static inline unsigned long round_up_to_page(unsigned long len) { - if(len % PAGE_SIZE) + if (len % PAGE_SIZE) len += PAGE_SIZE - (len % PAGE_SIZE); return len; } diff -urN linux-2.4.21/drivers/ieee1394/dv1394-private.h linux-2.4.22/drivers/ieee1394/dv1394-private.h --- linux-2.4.21/drivers/ieee1394/dv1394-private.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/dv1394-private.h 2003-08-25 04:44:41.000000000 -0700 @@ -97,7 +97,7 @@ omi->q[3] = 0; /* IT packet header */ - omi->q[4] = cpu_to_le32( (0x0 << 16) /* DMA_SPEED_100 */ + omi->q[4] = cpu_to_le32( (0x0 << 16) /* IEEE1394_SPEED_100 */ | (tag << 14) | (channel << 8) | (TCODE_ISO_DATA << 4) @@ -129,10 +129,10 @@ u32 temp = 0; temp |= 1 << 28; /* OUTPUT_LAST */ - if(want_timestamp) /* controller will update timestamp at DMA time */ + if (want_timestamp) /* controller will update timestamp at DMA time */ temp |= 1 << 27; - if(want_interrupt) + if (want_interrupt) temp |= 3 << 20; temp |= 3 << 18; /* must take branch */ diff -urN linux-2.4.21/drivers/ieee1394/dv1394.c linux-2.4.22/drivers/ieee1394/dv1394.c --- linux-2.4.21/drivers/ieee1394/dv1394.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/dv1394.c 2003-08-25 04:44:41.000000000 -0700 @@ -114,7 +114,7 @@ #include "ieee1394.h" #include "ieee1394_types.h" -#include "ieee1394_hotplug.h" +#include "nodemgr.h" #include "hosts.h" #include "ieee1394_core.h" #include "highlevel.h" @@ -209,14 +209,14 @@ static struct frame* frame_new(unsigned int frame_num, struct video_card *video) { struct frame *f = kmalloc(sizeof(*f), GFP_KERNEL); - if(!f) + if (!f) return NULL; f->video = video; f->frame_num = frame_num; f->header_pool = pci_alloc_consistent(f->video->ohci->dev, PAGE_SIZE, &f->header_pool_dma); - if(!f->header_pool) { + if (!f->header_pool) { printk(KERN_ERR "dv1394: failed to allocate CIP header pool\n"); kfree(f); return NULL; @@ -232,7 +232,7 @@ f->descriptor_pool = pci_alloc_consistent(f->video->ohci->dev, f->descriptor_pool_size, &f->descriptor_pool_dma); - if(!f->descriptor_pool) { + if (!f->descriptor_pool) { pci_free_consistent(f->video->ohci->dev, PAGE_SIZE, f->header_pool, f->header_pool_dma); kfree(f); return NULL; @@ -292,12 +292,12 @@ - if(video->pal_or_ntsc == DV1394_PAL) + if (video->pal_or_ntsc == DV1394_PAL) packets_per_frame = DV1394_PAL_PACKETS_PER_FRAME; else packets_per_frame = DV1394_NTSC_PACKETS_PER_FRAME; - while( full_packets < packets_per_frame ) { + while ( full_packets < packets_per_frame ) { empty_packet = first_packet = last_packet = mid_packet = 0; data_p = f->data + full_packets * 480; @@ -308,7 +308,7 @@ /* note: these should NOT cross a page boundary (DMA restriction) */ - if(f->n_packets >= MAX_PACKETS) { + if (f->n_packets >= MAX_PACKETS) { printk(KERN_ERR "dv1394: FATAL ERROR: max packet count exceeded\n"); return; } @@ -324,7 +324,7 @@ /* the whole CIP pool fits on one page, so no worries about boundaries */ - if( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) + if ( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) > PAGE_SIZE) { printk(KERN_ERR "dv1394: FATAL ERROR: no room to allocate CIP header\n"); return; @@ -339,7 +339,7 @@ /* is this an empty packet? */ - if(video->cip_accum > (video->cip_d - video->cip_n)) { + if (video->cip_accum > (video->cip_d - video->cip_n)) { empty_packet = 1; payload_size = 8; video->cip_accum -= (video->cip_d - video->cip_n); @@ -372,7 +372,7 @@ the timestamp before DMA starts on the next frame. */ - if(f->n_packets == 0) { + if (f->n_packets == 0) { first_packet = 1; } else if ( full_packets == (packets_per_frame-1) ) { last_packet = 1; @@ -391,12 +391,12 @@ need a timestamp. */ /* first packet in the frame needs a timestamp */ - if(first_packet) { + if (first_packet) { f->cip_syt1 = cip; - if(empty_packet) + if (empty_packet) first_packet_empty = 1; - } else if(first_packet_empty && (f->n_packets == 1) ) { + } else if (first_packet_empty && (f->n_packets == 1) ) { /* if the first packet was empty, the second packet's CIP header also needs a timestamp */ f->cip_syt2 = cip; @@ -410,7 +410,7 @@ 0xFFFF /* the timestamp is filled in later */); /* advance counter, only for full packets */ - if( ! empty_packet ) + if ( ! empty_packet ) video->continuity_counter++; /******************************/ @@ -420,7 +420,7 @@ /* first descriptor - OUTPUT_MORE_IMMEDIATE, for the controller's IT header */ fill_output_more_immediate( &(block->u.out.omi), 1, video->channel, 0, payload_size); - if(empty_packet) { + if (empty_packet) { /* second descriptor - OUTPUT_LAST for CIP header */ fill_output_last( &(block->u.out.u.empty.ol), @@ -433,18 +433,18 @@ sizeof(struct CIP_header), /* data size */ cip_dma); - if(first_packet) + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.empty.ol.q[3]); - else if(mid_packet) + else if (mid_packet) f->mid_frame_timestamp = &(block->u.out.u.empty.ol.q[3]); - else if(last_packet) { + else if (last_packet) { f->frame_end_timestamp = &(block->u.out.u.empty.ol.q[3]); f->frame_end_branch = &(block->u.out.u.empty.ol.q[2]); } branch_address = &(block->u.out.u.empty.ol.q[2]); n_descriptors = 3; - if(first_packet) + if (first_packet) f->first_n_descriptors = n_descriptors; } else { /* full packet */ @@ -460,7 +460,7 @@ we need to split it into two DMA descriptors */ /* does the 480-byte data payload cross a page boundary? */ - if( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) { + if ( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) { /* page boundary crossed */ @@ -487,11 +487,11 @@ dma_region_offset_to_bus(&video->dv_buf, data_p + PAGE_SIZE - (data_p % PAGE_SIZE) - (unsigned long) video->dv_buf.kvirt)); - if(first_packet) + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]); - else if(mid_packet) + else if (mid_packet) f->mid_frame_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]); - else if(last_packet) { + else if (last_packet) { f->frame_end_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]); f->frame_end_branch = &(block->u.out.u.full.u.cross.ol.q[2]); } @@ -499,7 +499,7 @@ branch_address = &(block->u.out.u.full.u.cross.ol.q[2]); n_descriptors = 5; - if(first_packet) + if (first_packet) f->first_n_descriptors = n_descriptors; full_packets++; @@ -522,11 +522,11 @@ dma_region_offset_to_bus(&video->dv_buf, data_p - (unsigned long) video->dv_buf.kvirt)); - if(first_packet) + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); - else if(mid_packet) + else if (mid_packet) f->mid_frame_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); - else if(last_packet) { + else if (last_packet) { f->frame_end_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); f->frame_end_branch = &(block->u.out.u.full.u.nocross.ol.q[2]); } @@ -534,7 +534,7 @@ branch_address = &(block->u.out.u.full.u.nocross.ol.q[2]); n_descriptors = 4; - if(first_packet) + if (first_packet) f->first_n_descriptors = n_descriptors; full_packets++; @@ -546,7 +546,7 @@ /* note: we are not linked into the active DMA chain yet */ - if(last_branch_address) { + if (last_branch_address) { *(last_branch_address) = cpu_to_le32(block_dma | n_descriptors); } @@ -572,7 +572,7 @@ video->n_clear_frames--; last_frame = video->first_clear_frame - 1; - if(last_frame == -1) + if (last_frame == -1) last_frame = video->n_frames-1; video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames; @@ -586,11 +586,11 @@ (unsigned long) f->frame_end_timestamp, (unsigned long) f->frame_end_branch); - if(video->active_frame != -1) { + if (video->active_frame != -1) { /* if DMA is already active, we are almost done */ /* just link us onto the active DMA chain */ - if(video->frames[last_frame]->frame_end_branch) { + if (video->frames[last_frame]->frame_end_branch) { u32 temp; /* point the previous frame's tail to this frame's head */ @@ -658,11 +658,11 @@ f->assigned_timestamp = (ts_cyc&0xF) << 12; /* now actually write the timestamp into the appropriate CIP headers */ - if(f->cip_syt1) { + if (f->cip_syt1) { f->cip_syt1->b[6] = f->assigned_timestamp >> 8; f->cip_syt1->b[7] = f->assigned_timestamp & 0xFF; } - if(f->cip_syt2) { + if (f->cip_syt2) { f->cip_syt2->b[6] = f->assigned_timestamp >> 8; f->cip_syt2->b[7] = f->assigned_timestamp & 0xFF; } @@ -714,10 +714,10 @@ { /* check if DMA is really running */ int i = 0; - while(i < 20) { + while (i < 20) { mb(); mdelay(1); - if(reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) { + if (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) { printk("DMA ACTIVE after %d msec\n", i); break; } @@ -729,7 +729,7 @@ reg_read(video->ohci, video->ohci_IsoXmitCommandPtr) ); - if( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { + if ( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { printk("DMA did NOT go active after 20ms, event = %x\n", reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & 0x1F); } else @@ -829,14 +829,14 @@ { int i; - for(i = 0; i < 1000; ++i) { + for (i = 0; i < 1000; ++i) { mdelay(1); - if(reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) { + if (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) { printk("DMA ACTIVE after %d msec\n", i); break; } } - if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { + if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { printk("DEAD, event = %x\n", reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); } else @@ -844,7 +844,7 @@ } #endif } - else if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { + else if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { debug_printk("DEAD, event = %x\n", reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); @@ -920,36 +920,36 @@ int retval = -EINVAL; debug_printk("dv1394: initialising %d\n", video->id); - if(init->api_version != DV1394_API_VERSION) + if (init->api_version != DV1394_API_VERSION) return -EINVAL; /* first sanitize all the parameters */ - if( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) ) + if ( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) ) return -EINVAL; - if( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) ) + if ( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) ) return -EINVAL; - if( (init->syt_offset == 0) || (init->syt_offset > 50) ) + if ( (init->syt_offset == 0) || (init->syt_offset > 50) ) /* default SYT offset is 3 cycles */ init->syt_offset = 3; - if( (init->channel > 63) || (init->channel < 0) ) + if ( (init->channel > 63) || (init->channel < 0) ) init->channel = 63; chan_mask = (u64)1 << init->channel; /* calculate what size DMA buffer is needed */ - if(init->format == DV1394_NTSC) + if (init->format == DV1394_NTSC) new_buf_size = DV1394_NTSC_FRAME_SIZE * init->n_frames; else new_buf_size = DV1394_PAL_FRAME_SIZE * init->n_frames; /* round up to PAGE_SIZE */ - if(new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE); + if (new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE); /* don't allow the user to allocate the DMA buffer more than once */ - if(video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) { + if (video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) { printk("dv1394: re-sizing the DMA buffer is not allowed\n"); return -EINVAL; } @@ -961,7 +961,7 @@ /* try to claim the ISO channel */ spin_lock_irqsave(&video->ohci->IR_channel_lock, flags); - if(video->ohci->ISO_channel_usage & chan_mask) { + if (video->ohci->ISO_channel_usage & chan_mask) { spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags); retval = -EBUSY; goto err; @@ -989,7 +989,7 @@ video->current_packet = -1; video->first_frame = 0; - if(video->pal_or_ntsc == DV1394_NTSC) { + if (video->pal_or_ntsc == DV1394_NTSC) { video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC; video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC; video->frame_size = DV1394_NTSC_FRAME_SIZE; @@ -1003,7 +1003,7 @@ /* find and claim DMA contexts on the OHCI card */ - if(video->ohci_it_ctx == -1) { + if (video->ohci_it_ctx == -1) { ohci1394_init_iso_tasklet(&video->it_tasklet, OHCI_ISO_TRANSMIT, it_tasklet_func, (unsigned long) video); @@ -1017,7 +1017,7 @@ debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx); } - if(video->ohci_ir_ctx == -1) { + if (video->ohci_ir_ctx == -1) { ohci1394_init_iso_tasklet(&video->ir_tasklet, OHCI_ISO_RECEIVE, ir_tasklet_func, (unsigned long) video); @@ -1031,20 +1031,20 @@ } /* allocate struct frames */ - for(i = 0; i < init->n_frames; i++) { + for (i = 0; i < init->n_frames; i++) { video->frames[i] = frame_new(i, video); - if(!video->frames[i]) { + if (!video->frames[i]) { printk(KERN_ERR "dv1394: Cannot allocate frame structs\n"); retval = -ENOMEM; goto err; } } - if(!video->dv_buf.kvirt) { + if (!video->dv_buf.kvirt) { /* allocate the ringbuffer */ retval = dma_region_alloc(&video->dv_buf, new_buf_size, video->ohci->dev, PCI_DMA_TODEVICE); - if(retval) + if (retval) goto err; video->dv_buf_size = new_buf_size; @@ -1055,10 +1055,10 @@ } /* set up the frame->data pointers */ - for(i = 0; i < video->n_frames; i++) + for (i = 0; i < video->n_frames; i++) video->frames[i]->data = (unsigned long) video->dv_buf.kvirt + i * video->frame_size; - if(!video->packet_buf.kvirt) { + if (!video->packet_buf.kvirt) { /* allocate packet buffer */ video->packet_buf_size = sizeof(struct packet) * video->n_frames * MAX_PACKETS; if (video->packet_buf_size % PAGE_SIZE) @@ -1066,7 +1066,7 @@ retval = dma_region_alloc(&video->packet_buf, video->packet_buf_size, video->ohci->dev, PCI_DMA_FROMDEVICE); - if(retval) + if (retval) goto err; debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n", @@ -1132,11 +1132,11 @@ video->dma_running = 0; - if( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) ) + if ( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) ) goto out; /* stop DMA if in progress */ - if( (video->active_frame != -1) || + if ( (video->active_frame != -1) || (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { @@ -1150,12 +1150,12 @@ /* wait until DMA really stops */ i = 0; - while(i < 1000) { + while (i < 1000) { /* wait 0.1 millisecond */ udelay(100); - if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || + if ( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { /* still active */ debug_printk("dv1394: stop_dma: DMA not stopped yet\n" ); @@ -1168,7 +1168,7 @@ i++; } - if(i == 1000) { + if (i == 1000) { printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10); } } @@ -1191,7 +1191,7 @@ stop_dma(video); /* release the DMA contexts */ - if(video->ohci_it_ctx != -1) { + if (video->ohci_it_ctx != -1) { video->ohci_IsoXmitContextControlSet = 0; video->ohci_IsoXmitContextControlClear = 0; video->ohci_IsoXmitCommandPtr = 0; @@ -1205,7 +1205,7 @@ video->ohci_it_ctx = -1; } - if(video->ohci_ir_ctx != -1) { + if (video->ohci_ir_ctx != -1) { video->ohci_IsoRcvContextControlSet = 0; video->ohci_IsoRcvContextControlClear = 0; video->ohci_IsoRcvCommandPtr = 0; @@ -1221,7 +1221,7 @@ } /* release the ISO channel */ - if(video->channel != -1) { + if (video->channel != -1) { u64 chan_mask; unsigned long flags; @@ -1235,8 +1235,8 @@ } /* free the frame structs */ - for(i = 0; i < DV1394_MAX_FRAMES; i++) { - if(video->frames[i]) + for (i = 0; i < DV1394_MAX_FRAMES; i++) { + if (video->frames[i]) frame_delete(video->frames[i]); video->frames[i] = NULL; } @@ -1246,7 +1246,7 @@ /* we can't free the DMA buffer unless it is guaranteed that no more user-space mappings exist */ - if(free_dv_buf) { + if (free_dv_buf) { dma_region_free(&video->dv_buf); video->dv_buf_size = 0; } @@ -1290,9 +1290,9 @@ /* serialize mmap */ down(&video->sem); - if( ! video_card_initialized(video) ) { + if ( ! video_card_initialized(video) ) { retval = do_dv1394_init_default(video); - if(retval) + if (retval) goto out; } @@ -1314,14 +1314,14 @@ poll_wait(file, &video->waitq, wait); spin_lock_irqsave(&video->spinlock, flags); - if( video->n_frames == 0 ) { + if ( video->n_frames == 0 ) { - } else if( video->active_frame == -1 ) { + } else if ( video->active_frame == -1 ) { /* nothing going on */ mask |= POLLOUT; } else { /* any clear/ready buffers? */ - if(video->n_clear_frames >0) + if (video->n_clear_frames >0) mask |= POLLOUT | POLLIN; } spin_unlock_irqrestore(&video->spinlock, flags); @@ -1353,17 +1353,17 @@ int target_frame; /* serialize this to prevent multi-threaded mayhem */ - if(file->f_flags & O_NONBLOCK) { - if(down_trylock(&video->sem)) + if (file->f_flags & O_NONBLOCK) { + if (down_trylock(&video->sem)) return -EAGAIN; } else { - if(down_interruptible(&video->sem)) + if (down_interruptible(&video->sem)) return -ERESTARTSYS; } - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) { + if (ret) { up(&video->sem); return ret; } @@ -1372,7 +1372,7 @@ ret = 0; add_wait_queue(&video->waitq, &wait); - while(count > 0) { + while (count > 0) { /* must set TASK_INTERRUPTIBLE *before* checking for free buffers; otherwise we could miss a wakeup if the interrupt @@ -1386,7 +1386,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); - if(video->frames[target_frame]->state == FRAME_CLEAR) { + if (video->frames[target_frame]->state == FRAME_CLEAR) { /* how much room is left in the target frame buffer */ cnt = video->frame_size - (video->write_off - target_frame * video->frame_size); @@ -1396,12 +1396,12 @@ cnt = 0; } - if(cnt > count) + if (cnt > count) cnt = count; if (cnt <= 0) { /* no room left, gotta wait */ - if(file->f_flags & O_NONBLOCK) { + if (file->f_flags & O_NONBLOCK) { if (!ret) ret = -EAGAIN; break; @@ -1417,8 +1417,8 @@ continue; /* start over from 'while(count > 0)...' */ } - if(copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) { - if(!ret) + if (copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) { + if (!ret) ret = -EFAULT; break; } @@ -1429,7 +1429,7 @@ buffer += cnt; ret += cnt; - if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) + if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) frame_prepare(video, target_frame); } @@ -1450,17 +1450,17 @@ int target_frame; /* serialize this to prevent multi-threaded mayhem */ - if(file->f_flags & O_NONBLOCK) { - if(down_trylock(&video->sem)) + if (file->f_flags & O_NONBLOCK) { + if (down_trylock(&video->sem)) return -EAGAIN; } else { - if(down_interruptible(&video->sem)) + if (down_interruptible(&video->sem)) return -ERESTARTSYS; } - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) { + if (ret) { up(&video->sem); return ret; } @@ -1474,7 +1474,7 @@ ret = 0; add_wait_queue(&video->waitq, &wait); - while(count > 0) { + while (count > 0) { /* must set TASK_INTERRUPTIBLE *before* checking for free buffers; otherwise we could miss a wakeup if the interrupt @@ -1488,7 +1488,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); - if(target_frame >= 0 && + if (target_frame >= 0 && video->n_clear_frames > 0 && video->frames[target_frame]->state == FRAME_CLEAR) { @@ -1500,12 +1500,12 @@ cnt = 0; } - if(cnt > count) + if (cnt > count) cnt = count; if (cnt <= 0) { /* no room left, gotta wait */ - if(file->f_flags & O_NONBLOCK) { + if (file->f_flags & O_NONBLOCK) { if (!ret) ret = -EAGAIN; break; @@ -1521,8 +1521,8 @@ continue; /* start over from 'while(count > 0)...' */ } - if(copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) { - if(!ret) + if (copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) { + if (!ret) ret = -EFAULT; break; } @@ -1533,7 +1533,7 @@ buffer += cnt; ret += cnt; - if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) { + if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) { spin_lock_irqsave(&video->spinlock, flags); video->n_clear_frames--; video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames; @@ -1563,11 +1563,11 @@ DECLARE_WAITQUEUE(wait, current); /* serialize this to prevent multi-threaded mayhem */ - if(file->f_flags & O_NONBLOCK) { - if(down_trylock(&video->sem)) + if (file->f_flags & O_NONBLOCK) { + if (down_trylock(&video->sem)) return -EAGAIN; } else { - if(down_interruptible(&video->sem)) + if (down_interruptible(&video->sem)) return -ERESTARTSYS; } @@ -1577,20 +1577,20 @@ case DV1394_IOC_SUBMIT_FRAMES: { unsigned int n_submit; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) + if (ret) goto out; } n_submit = (unsigned int) arg; - if(n_submit > video->n_frames) { + if (n_submit > video->n_frames) { ret = -EINVAL; goto out; } - while(n_submit > 0) { + while (n_submit > 0) { add_wait_queue(&video->waitq, &wait); set_current_state(TASK_INTERRUPTIBLE); @@ -1598,11 +1598,11 @@ spin_lock_irqsave(&video->spinlock, flags); /* wait until video->first_clear_frame is really CLEAR */ - while(video->frames[video->first_clear_frame]->state != FRAME_CLEAR) { + while (video->frames[video->first_clear_frame]->state != FRAME_CLEAR) { spin_unlock_irqrestore(&video->spinlock, flags); - if(signal_pending(current)) { + if (signal_pending(current)) { remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); ret = -EINTR; @@ -1631,7 +1631,7 @@ case DV1394_IOC_WAIT_FRAMES: { unsigned int n_wait; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = -EINVAL; goto out; } @@ -1642,7 +1642,7 @@ never actually have n_frames clear frames; at most only n_frames - 1 */ - if(n_wait > (video->n_frames-1) ) { + if (n_wait > (video->n_frames-1) ) { ret = -EINVAL; goto out; } @@ -1652,11 +1652,11 @@ spin_lock_irqsave(&video->spinlock, flags); - while(video->n_clear_frames < n_wait) { + while (video->n_clear_frames < n_wait) { spin_unlock_irqrestore(&video->spinlock, flags); - if(signal_pending(current)) { + if (signal_pending(current)) { remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); ret = -EINTR; @@ -1680,7 +1680,7 @@ case DV1394_IOC_RECEIVE_FRAMES: { unsigned int n_recv; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = -EINVAL; goto out; } @@ -1688,7 +1688,7 @@ n_recv = (unsigned int) arg; /* at least one frame must be active */ - if(n_recv > (video->n_frames-1) ) { + if (n_recv > (video->n_frames-1) ) { ret = -EINVAL; goto out; } @@ -1711,9 +1711,9 @@ } case DV1394_START_RECEIVE: case DV1394_IOC_START_RECEIVE: { - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) + if (ret) goto out; } @@ -1729,10 +1729,10 @@ case DV1394_INIT: case DV1394_IOC_INIT: { struct dv1394_init init; - if(arg == (unsigned long) NULL) { + if (arg == (unsigned long) NULL) { ret = do_dv1394_init_default(video); } else { - if(copy_from_user(&init, (void*)arg, sizeof(init))) { + if (copy_from_user(&init, (void*)arg, sizeof(init))) { ret = -EFAULT; goto out; } @@ -1750,7 +1750,7 @@ case DV1394_IOC_GET_STATUS: { struct dv1394_status status; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = -EINVAL; goto out; } @@ -1778,7 +1778,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); - if(copy_to_user((void*)arg, &status, sizeof(status))) { + if (copy_to_user((void*)arg, &status, sizeof(status))) { ret = -EFAULT; goto out; } @@ -1806,7 +1806,7 @@ /* if the device was opened through devfs, then file->private_data has already been set to video by devfs */ - if(file->private_data) { + if (file->private_data) { video = (struct video_card*) file->private_data; } else { @@ -1816,11 +1816,11 @@ unsigned long flags; spin_lock_irqsave(&dv1394_cards_lock, flags); - if(!list_empty(&dv1394_cards)) { + if (!list_empty(&dv1394_cards)) { struct video_card *p; list_for_each(lh, &dv1394_cards) { p = list_entry(lh, struct video_card, list); - if((p->id) == ieee1394_file_to_instance(file)) { + if ((p->id) == ieee1394_file_to_instance(file)) { video = p; break; } @@ -1828,7 +1828,7 @@ } spin_unlock_irqrestore(&dv1394_cards_lock, flags); - if(!video) { + if (!video) { debug_printk("dv1394: OHCI card %d not found", ieee1394_file_to_instance(file)); return -ENODEV; } @@ -1838,7 +1838,7 @@ #ifndef DV1394_ALLOW_MORE_THAN_ONE_OPEN - if( test_and_set_bit(0, &video->open) ) { + if ( test_and_set_bit(0, &video->open) ) { /* video is already open by someone else */ return -EBUSY; } @@ -1980,10 +1980,10 @@ struct dv1394_procfs_entry *p; spin_lock( &dv1394_procfs_lock); - if(!list_empty(&dv1394_procfs)) { + if (!list_empty(&dv1394_procfs)) { list_for_each(lh, &dv1394_procfs) { p = list_entry(lh, struct dv1394_procfs_entry, list); - if(!strncmp(p->name, name, sizeof(p->name))) { + if (!strncmp(p->name, name, sizeof(p->name))) { spin_unlock( &dv1394_procfs_lock); return p; } @@ -2000,7 +2000,7 @@ struct dv1394_procfs_entry *parent; p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL); - if(!p) { + if (!p) { printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n"); goto err; } @@ -2052,7 +2052,7 @@ struct dv1394_procfs_entry *p; p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL); - if(!p) { + if (!p) { printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n"); goto err; } @@ -2113,7 +2113,7 @@ spin_lock(&video->spinlock); - if(!video->dma_running) + if (!video->dma_running) goto out; irq_printk("ContextControl = %08x, CommandPtr = %08x\n", @@ -2122,24 +2122,24 @@ ); - if( (video->ohci_it_ctx != -1) && + if ( (video->ohci_it_ctx != -1) && (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { struct frame *f; unsigned int frame, i; - if(video->active_frame == -1) + if (video->active_frame == -1) frame = 0; else frame = video->active_frame; /* check all the DMA-able frames */ - for(i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) { + for (i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) { irq_printk("IRQ checking frame %d...", frame); f = video->frames[frame]; - if(f->state != FRAME_READY) { + if (f->state != FRAME_READY) { irq_printk("clear, skipping\n"); /* we don't own this frame */ continue; @@ -2148,7 +2148,7 @@ irq_printk("DMA\n"); /* check the frame begin semaphore to see if we can free the previous frame */ - if( *(f->frame_begin_timestamp) ) { + if ( *(f->frame_begin_timestamp) ) { int prev_frame; struct frame *prev_f; @@ -2158,13 +2158,13 @@ irq_printk(" BEGIN\n"); prev_frame = frame - 1; - if(prev_frame == -1) + if (prev_frame == -1) prev_frame += video->n_frames; prev_f = video->frames[prev_frame]; /* make sure we can actually garbage collect this frame */ - if( (prev_f->state == FRAME_READY) && + if ( (prev_f->state == FRAME_READY) && prev_f->done && (!f->done) ) { frame_reset(prev_f); @@ -2182,7 +2182,7 @@ /* see if we need to set the timestamp for the next frame */ - if( *(f->mid_frame_timestamp) ) { + if ( *(f->mid_frame_timestamp) ) { struct frame *next_frame; u32 begin_ts, ts_cyc, ts_off; @@ -2197,7 +2197,7 @@ /* prepare next frame and assign timestamp */ next_frame = video->frames[ (frame+1) % video->n_frames ]; - if(next_frame->state == FRAME_READY) { + if (next_frame->state == FRAME_READY) { irq_printk(" MIDDLE - next frame is ready, good\n"); } else { debug_printk("dv1394: Underflow! At least one frame has been dropped.\n"); @@ -2216,11 +2216,11 @@ ts_off %= 3072; next_frame->assigned_timestamp = ((ts_cyc&0xF) << 12) + ts_off; - if(next_frame->cip_syt1) { + if (next_frame->cip_syt1) { next_frame->cip_syt1->b[6] = next_frame->assigned_timestamp >> 8; next_frame->cip_syt1->b[7] = next_frame->assigned_timestamp & 0xFF; } - if(next_frame->cip_syt2) { + if (next_frame->cip_syt2) { next_frame->cip_syt2->b[6] = next_frame->assigned_timestamp >> 8; next_frame->cip_syt2->b[7] = next_frame->assigned_timestamp & 0xFF; } @@ -2228,7 +2228,7 @@ } /* see if the frame looped */ - if( *(f->frame_end_timestamp) ) { + if ( *(f->frame_end_timestamp) ) { *(f->frame_end_timestamp) = 0; @@ -2239,10 +2239,10 @@ - } /* for(each frame) */ + } /* for (each frame) */ } - if(wake) { + if (wake) { kill_fasync(&video->fasync, SIGIO, POLL_OUT); /* wake readers/writers/ioctl'ers */ @@ -2260,10 +2260,10 @@ spin_lock(&video->spinlock); - if(!video->dma_running) + if (!video->dma_running) goto out; - if( (video->ohci_ir_ctx != -1) && + if ( (video->ohci_ir_ctx != -1) && (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) { @@ -2298,16 +2298,15 @@ /* get the descriptor based on packet_buffer cursor */ f = video->frames[video->current_packet / MAX_PACKETS]; block = &(f->descriptor_pool[video->current_packet % MAX_PACKETS]); - xferstatus = le16_to_cpu(block->u.in.il.q[3] >> 16); + xferstatus = le32_to_cpu(block->u.in.il.q[3]) >> 16; xferstatus &= 0x1F; + irq_printk("ir_tasklet_func: xferStatus/resCount [%d] = 0x%08x\n", i, le32_to_cpu(block->u.in.il.q[3]) ); /* get the current frame */ f = video->frames[video->active_frame]; /* exclude empty packet */ if (packet_length > 8 && xferstatus == 0x11) { - irq_printk("ir_tasklet_func: xferStatus/resCount [%d] = 0x%08x\n", i, le32_to_cpu(block->u.in.il.q[3]) ); - /* check for start of frame */ /* DRD> Changed to check section type ([0]>>5==0) and dif sequence ([1]>>4==0) */ @@ -2384,12 +2383,12 @@ prev_i = (next_i == 0) ? (MAX_PACKETS * video->n_frames - 1) : (next_i - 1); f = video->frames[prev_i / MAX_PACKETS]; prev = &(f->descriptor_pool[prev_i % MAX_PACKETS]); - if(prev_i % (MAX_PACKETS/2)) { + if (prev_i % (MAX_PACKETS/2)) { prev->u.in.il.q[0] &= ~(3 << 20); /* no interrupt */ } else { prev->u.in.il.q[0] |= 3 << 20; /* enable interrupt */ } - prev->u.in.il.q[2] = (cpu_to_le32(next_dma) | 1); /* set Z=1 */ + prev->u.in.il.q[2] = cpu_to_le32(next_dma | 1); /* set Z=1 */ wmb(); /* wake up DMA in case it fell asleep */ @@ -2404,7 +2403,7 @@ } /* receive interrupt */ - if(wake) { + if (wake) { kill_fasync(&video->fasync, SIGIO, POLL_IN); /* wake readers/writers/ioctl'ers */ @@ -2438,10 +2437,10 @@ struct dv1394_devfs_entry *p; spin_lock( &dv1394_devfs_lock); - if(!list_empty(&dv1394_devfs)) { + if (!list_empty(&dv1394_devfs)) { list_for_each(lh, &dv1394_devfs) { p = list_entry(lh, struct dv1394_devfs_entry, list); - if(!strncmp(p->name, name, sizeof(p->name))) { + if (!strncmp(p->name, name, sizeof(p->name))) { goto found; } } @@ -2461,7 +2460,7 @@ struct dv1394_devfs_entry *parent; p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL); - if(!p) { + if (!p) { printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n"); goto err; } @@ -2515,7 +2514,7 @@ struct dv1394_devfs_entry *p; p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL); - if(!p) { + if (!p) { printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n"); goto err; } @@ -2594,7 +2593,7 @@ int i; video = kmalloc(sizeof(struct video_card), GFP_KERNEL); - if(!video) { + if (!video) { printk(KERN_ERR "dv1394: cannot allocate video_card\n"); goto err; } @@ -2638,7 +2637,7 @@ goto err_free; #endif - for(i = 0; i < DV1394_MAX_FRAMES; i++) + for (i = 0; i < DV1394_MAX_FRAMES; i++) video->frames[i] = NULL; dma_region_init(&video->dv_buf); @@ -2712,10 +2711,10 @@ /* find the corresponding video_cards */ spin_lock_irqsave(&dv1394_cards_lock, flags); - if(!list_empty(&dv1394_cards)) { + if (!list_empty(&dv1394_cards)) { list_for_each_safe(lh, templh, &dv1394_cards) { video = list_entry(lh, struct video_card, list); - if((video->id >> 2) == ohci->id) + if ((video->id >> 2) == ohci->id) dv1394_un_init(video); } } @@ -2805,32 +2804,32 @@ /* find the corresponding video_cards */ spin_lock_irqsave(&dv1394_cards_lock, flags); - if(!list_empty(&dv1394_cards)) { + if (!list_empty(&dv1394_cards)) { list_for_each(lh, &dv1394_cards) { video = list_entry(lh, struct video_card, list); - if((video->id >> 2) == ohci->id) + if ((video->id >> 2) == ohci->id) break; } } spin_unlock_irqrestore(&dv1394_cards_lock, flags); - if(!video) + if (!video) return; spin_lock_irqsave(&video->spinlock, flags); - if(!video->dma_running) + if (!video->dma_running) goto out; /* check IT context */ - if(video->ohci_it_ctx != -1) { + if (video->ohci_it_ctx != -1) { u32 ctx; ctx = reg_read(video->ohci, video->ohci_IsoXmitContextControlSet); - /* if(RUN but not ACTIVE) */ - if( (ctx & (1<<15)) && + /* if (RUN but not ACTIVE) */ + if ( (ctx & (1<<15)) && !(ctx & (1<<10)) ) { debug_printk("dv1394: IT context stopped due to bus reset; waking it up\n"); @@ -2860,13 +2859,13 @@ } /* check IR context */ - if(video->ohci_ir_ctx != -1) { + if (video->ohci_ir_ctx != -1) { u32 ctx; ctx = reg_read(video->ohci, video->ohci_IsoRcvContextControlSet); - /* if(RUN but not ACTIVE) */ - if( (ctx & (1<<15)) && + /* if (RUN but not ACTIVE) */ + if ( (ctx & (1<<15)) && !(ctx & (1<<10)) ) { debug_printk("dv1394: IR context stopped due to bus reset; waking it up\n"); diff -urN linux-2.4.21/drivers/ieee1394/dv1394.h linux-2.4.22/drivers/ieee1394/dv1394.h --- linux-2.4.21/drivers/ieee1394/dv1394.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/dv1394.h 2003-08-25 04:44:41.000000000 -0700 @@ -64,7 +64,7 @@ ioctl(fd, DV1394_INIT, &init); - while(1) { + while (1) { read( , buf, DV1394_NTSC_FRAME_SIZE ); write( , buf, DV1394_NTSC_FRAME_SIZE ); } @@ -145,7 +145,7 @@ (checks of system call return values omitted for brevity; always check return values in your code!) - while( frames left ) { + while ( frames left ) { struct pollfd *pfd = ...; @@ -157,15 +157,15 @@ poll(pfd, 1, -1); (or select(); add a timeout if you want) - if(pfd->revents) { + if (pfd->revents) { struct dv1394_status status; ioctl(dv1394_fd, DV1394_GET_STATUS, &status); - if(status.dropped_frames > 0) { + if (status.dropped_frames > 0) { reset_dv1394(); } else { - for(int i = 0; i < status.n_clear_frames; i++) { + for (int i = 0; i < status.n_clear_frames; i++) { copy_DV_frame(); } } diff -urN linux-2.4.21/drivers/ieee1394/eth1394.c linux-2.4.22/drivers/ieee1394/eth1394.c --- linux-2.4.21/drivers/ieee1394/eth1394.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/eth1394.c 2003-08-25 04:44:41.000000000 -0700 @@ -1,8 +1,9 @@ /* * eth1394.c -- Ethernet driver for Linux IEEE-1394 Subsystem * - * Copyright (C) 2001 Ben Collins + * Copyright (C) 2001-2003 Ben Collins * 2000 Bonin Franck + * 2003 Steve Kinneberg * * Mainly based on work by Emanuel Pirker and Andreas E. Bombe * @@ -21,22 +22,27 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* State of this driver: - * - * This driver intends to support RFC 2734, which describes a method for +/* This driver intends to support RFC 2734, which describes a method for * transporting IPv4 datagrams over IEEE-1394 serial busses. This driver * will ultimately support that method, but currently falls short in - * several areas. A few issues are: + * several areas. + * + * TODO: + * RFC 2734 related: + * - Add Config ROM entry + * - Add MCAP. Limited Multicast exists only to 224.0.0.1 and 224.0.0.2. * - * - Does not support send/recv over Async streams using GASP - * packet formats, as per the RFC for ARP requests. - * - Does not yet support fragmented packets. - * - Relies on hardware address being equal to the nodeid for some things. - * - Does not support multicast - * - Hardcoded address for sending packets, instead of using discovery - * (ARP, see first item) + * Non-RFC 2734 related: + * - Handle fragmented skb's coming from the networking layer. + * - Move generic GASP reception to core 1394 code + * - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead + * - Stability improvements + * - Performance enhancements + * - Change hardcoded 1394 bus address region to a dynamic memory space allocation + * - Consider garbage collecting old partial datagrams after X amount of time */ + #include #include @@ -53,9 +59,12 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -66,49 +75,190 @@ #include "ieee1394.h" #include "highlevel.h" #include "iso.h" +#include "nodemgr.h" #include "eth1394.h" #define ETH1394_PRINT_G(level, fmt, args...) \ - printk(level ETHER1394_DRIVER_NAME": "fmt, ## args) + printk(level "%s: " fmt, driver_name, ## args) #define ETH1394_PRINT(level, dev_name, fmt, args...) \ - printk(level ETHER1394_DRIVER_NAME": %s: " fmt, dev_name, ## args) + printk(level "%s: %s: " fmt, driver_name, dev_name, ## args) #define DEBUG(fmt, args...) \ - printk(KERN_ERR fmt, ## args) + printk(KERN_ERR "%s:%s[%d]: " fmt "\n", driver_name, __FUNCTION__, __LINE__, ## args) +#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) static char version[] __devinitdata = - "$Rev: 906 $ Ben Collins "; + "$Rev: 1010 $ Ben Collins "; + +struct fragment_info { + struct list_head list; + int offset; + int len; +}; + +struct partial_datagram { + struct list_head list; + u16 dgl; + u16 dg_size; + u16 ether_type; + struct sk_buff *skb; + char *pbuf; + struct list_head frag_info; +}; /* Our ieee1394 highlevel driver */ -#define ETHER1394_DRIVER_NAME "ether1394" +static const char driver_name[] = "eth1394"; static kmem_cache_t *packet_task_cache; static struct hpsb_highlevel eth1394_highlevel; /* Use common.lf to determine header len */ -static int hdr_type_len[] = { +static const int hdr_type_len[] = { sizeof (struct eth1394_uf_hdr), sizeof (struct eth1394_ff_hdr), sizeof (struct eth1394_sf_hdr), sizeof (struct eth1394_sf_hdr) }; +/* Change this to IEEE1394_SPEED_S100 to make testing easier */ +#define ETH1394_SPEED_DEF IEEE1394_SPEED_MAX + +/* For now, this needs to be 1500, so that XP works with us */ +#define ETH1394_DATA_LEN ETH_DATA_LEN + +static const u16 eth1394_speedto_maxpayload[] = { +/* S100, S200, S400, S800, S1600, S3200 */ + 512, 1024, 2048, 4096, 8192, 16384 +}; + MODULE_AUTHOR("Ben Collins (bcollins@debian.org)"); MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"); MODULE_LICENSE("GPL"); +/* The max_partial_datagrams parameter is the maximum number of fragmented + * datagrams per node that eth1394 will keep in memory. Providing an upper + * bound allows us to limit the amount of memory that partial datagrams + * consume in the event that some partial datagrams are never completed. This + * should probably change to a sysctl item or the like if possible. + */ +MODULE_PARM(max_partial_datagrams, "i"); +MODULE_PARM_DESC(max_partial_datagrams, + "Maximum number of partially received fragmented datagrams " + "(default = 25)."); +static int max_partial_datagrams = 25; + + +static int ether1394_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, + unsigned len); +static int ether1394_rebuild_header(struct sk_buff *skb); +static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr); +static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh); +static void ether1394_header_cache_update(struct hh_cache *hh, + struct net_device *dev, + unsigned char * haddr); +static int ether1394_mac_addr(struct net_device *dev, void *p); + +static inline void purge_partial_datagram(struct list_head *old); +static int ether1394_tx(struct sk_buff *skb, struct net_device *dev); static void ether1394_iso(struct hpsb_iso *iso); +static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr); + +static void eth1394_iso_shutdown(struct eth1394_priv *priv) +{ + priv->bc_state = ETHER1394_BC_CLOSED; + + if (priv->iso != NULL) { + if (!in_interrupt()) + hpsb_iso_shutdown(priv->iso); + priv->iso = NULL; + } +} + +static int ether1394_init_bc(struct net_device *dev) +{ + struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + + /* First time sending? Need a broadcast channel for ARP and for + * listening on */ + if (priv->bc_state == ETHER1394_BC_CHECK) { + quadlet_t bc; + + /* Get the local copy of the broadcast channel and check its + * validity (the IRM should validate it for us) */ + + bc = priv->host->csr.broadcast_channel; + + if ((bc & 0xc0000000) != 0xc0000000) { + /* broadcast channel not validated yet */ + ETH1394_PRINT(KERN_WARNING, dev->name, + "Error BROADCAST_CHANNEL register valid " + "bit not set, can't send IP traffic\n"); + + eth1394_iso_shutdown(priv); + + return -EAGAIN; + } + if (priv->broadcast_channel != (bc & 0x3f)) { + /* This really shouldn't be possible, but just in case + * the IEEE 1394 spec changes regarding broadcast + * channels in the future. */ + + eth1394_iso_shutdown(priv); + + if (in_interrupt()) + return -EAGAIN; + + priv->broadcast_channel = bc & 0x3f; + ETH1394_PRINT(KERN_INFO, dev->name, + "Changing to broadcast channel %d...\n", + priv->broadcast_channel); + + priv->iso = hpsb_iso_recv_init(priv->host, 16 * 4096, + 16, priv->broadcast_channel, + 1, ether1394_iso); + if (priv->iso == NULL) { + ETH1394_PRINT(KERN_ERR, dev->name, + "failed to change broadcast " + "channel\n"); + return -EAGAIN; + } + } + if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) { + ETH1394_PRINT(KERN_ERR, dev->name, + "Could not start data stream reception\n"); + + eth1394_iso_shutdown(priv); + + return -EAGAIN; + } + priv->bc_state = ETHER1394_BC_OPENED; + } + + return 0; +} /* This is called after an "ifup" */ static int ether1394_open (struct net_device *dev) { struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + unsigned long flags; + int ret; + + /* Something bad happened, don't even try */ + if (priv->bc_state == ETHER1394_BC_CLOSED) + return -EAGAIN; + + spin_lock_irqsave(&priv->lock, flags); + ret = ether1394_init_bc(dev); + spin_unlock_irqrestore(&priv->lock, flags); - /* Set the spinlock before grabbing IRQ! */ - priv->lock = SPIN_LOCK_UNLOCKED; + if (ret) + return ret; netif_start_queue (dev); return 0; @@ -139,116 +289,34 @@ netif_wake_queue (dev); } -/* We need to encapsulate the standard header with our own. We use the - * ethernet header's proto for our own. - * - * XXX: This is where we need to create a list of skb's for fragmented - * packets. */ -static inline void ether1394_encapsulate (struct sk_buff *skb, struct net_device *dev, - int proto, struct packet_task *ptask) -{ - union eth1394_hdr *hdr = - (union eth1394_hdr *)skb_push (skb, hdr_type_len[ETH1394_HDR_LF_UF]); - - hdr->words.word1 = 0; - hdr->common.lf = ETH1394_HDR_LF_UF; - hdr->words.word1 = htons(hdr->words.word1); - hdr->uf.ether_type = proto; - - /* Set the transmission type for the packet. Right now only ARP - * packets are sent via GASP. IP broadcast and IP multicast are not - * yet supported properly, they too should use GASP. */ - switch(proto) { - case __constant_htons(ETH_P_ARP): - ptask->tx_type = ETH1394_GASP; - break; - default: - ptask->tx_type = ETH1394_WRREQ; - } - return; -} - -/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the - * entire arphdr) is the same format as the ip1394 header, so they - * overlap. The rest needs to be munged a bit. The remainder of the - * arphdr is formatted based on hwaddr len and ipaddr len. We know what - * they'll be, so it's easy to judge. */ -static inline void ether1394_arp_to_1394arp (struct sk_buff *skb, struct net_device *dev) -{ - struct eth1394_priv *priv = - (struct eth1394_priv *)(dev->priv); - u16 phy_id = NODEID_TO_NODE(priv->host->node_id); - - unsigned char *arp_ptr = (unsigned char *)skb->data; - struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data; - unsigned char arp_data[2*(dev->addr_len+4)]; - - /* Copy the main data that we need */ - memcpy (arp_data, arp_ptr + sizeof(struct arphdr), sizeof (arp_data)); - - /* Extend the buffer enough for our new header */ - skb_put (skb, sizeof (struct eth1394_arp) - - (sizeof (arp_data) + sizeof (struct arphdr))); - -#define PROCESS_MEMBER(ptr,val,len) \ - memcpy (val, ptr, len); ptr += len - arp_ptr = arp_data + arp1394->hw_addr_len; - PROCESS_MEMBER (arp_ptr, &arp1394->sip, arp1394->ip_addr_len); - arp_ptr += arp1394->hw_addr_len; - PROCESS_MEMBER (arp_ptr, &arp1394->tip, arp1394->ip_addr_len); -#undef PROCESS_MEMBER - - /* Now add our own flavor of arp header fields to the orig one */ - arp1394->hw_addr_len = IP1394_HW_ADDR_LEN; - arp1394->hw_type = __constant_htons (ARPHRD_IEEE1394); - arp1394->s_uniq_id = cpu_to_le64 (priv->eui[phy_id]); - arp1394->max_rec = priv->max_rec[phy_id]; - arp1394->sspd = priv->sspd[phy_id]; - arp1394->fifo_hi = htons (priv->fifo_hi[phy_id]); - arp1394->fifo_lo = htonl (priv->fifo_lo[phy_id]); - - return; -} - static int ether1394_change_mtu(struct net_device *dev, int new_mtu) { - if ((new_mtu < 68) || (new_mtu > ETHER1394_REGION_ADDR_LEN)) + struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + int phy_id = NODEID_TO_NODE(priv->host->node_id); + + if ((new_mtu < 68) || (new_mtu > min(ETH1394_DATA_LEN, (int)(priv->maxpayload[phy_id] - + (sizeof(union eth1394_hdr) + ETHER1394_GASP_OVERHEAD))))) return -EINVAL; dev->mtu = new_mtu; return 0; } -static inline void ether1394_register_limits (int nodeid, unsigned char max_rec, - unsigned char sspd, u64 eui, u16 fifo_hi, - u32 fifo_lo, struct eth1394_priv *priv) +static inline void ether1394_register_limits(int nodeid, u16 maxpayload, + unsigned char sspd, u64 eui, u64 fifo, + struct eth1394_priv *priv) { - int i; - if (nodeid < 0 || nodeid >= ALL_NODES) { ETH1394_PRINT_G (KERN_ERR, "Cannot register invalid nodeid %d\n", nodeid); return; } - priv->max_rec[nodeid] = max_rec; - priv->sspd[nodeid] = sspd; - priv->fifo_hi[nodeid] = fifo_hi; - priv->fifo_lo[nodeid] = fifo_lo; - priv->eui[nodeid] = eui; - - /* 63 is used for broadcasts to all hosts. It is equal to the - * minimum of all registered nodes. A registered node is one with - * a nonzero offset. Set the values rediculously high to start. We - * know we have atleast one to change the default to. */ - sspd = 0xff; - max_rec = 0xff; - for (i = 0; i < ALL_NODES; i++) { - if (!priv->fifo_hi && !priv->fifo_lo) continue; /* Unregistered */ - if (priv->max_rec[i] < max_rec) max_rec = priv->max_rec[i]; - if (priv->sspd[i] < sspd) sspd = priv->sspd[i]; - } + priv->maxpayload[nodeid] = maxpayload; + priv->sspd[nodeid] = sspd; + priv->fifo[nodeid] = fifo; + priv->eui[nodeid] = eui; - priv->max_rec[ALL_NODES] = max_rec; - priv->sspd[ALL_NODES] = sspd; + priv->maxpayload[ALL_NODES] = min(priv->maxpayload[ALL_NODES], maxpayload); + priv->sspd[ALL_NODES] = min(priv->sspd[ALL_NODES], sspd); return; } @@ -256,40 +324,56 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) { unsigned long flags; + int i; struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; - int phy_id = NODEID_TO_NODE(priv->host->node_id); struct hpsb_host *host = priv->host; + int phy_id = NODEID_TO_NODE(host->node_id); + u64 guid = *((u64*)&(host->csr.rom[3])); + u16 maxpayload = 1 << (((be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf) + 1); spin_lock_irqsave (&priv->lock, flags); /* Clear the speed/payload/offset tables */ - memset (priv->max_rec, 0, sizeof (priv->max_rec)); + memset (priv->maxpayload, 0, sizeof (priv->maxpayload)); memset (priv->sspd, 0, sizeof (priv->sspd)); - memset (priv->fifo_hi, 0, sizeof (priv->fifo_hi)); - memset (priv->fifo_lo, 0, sizeof (priv->fifo_lo)); + memset (priv->fifo, 0, sizeof (priv->fifo)); + + priv->sspd[ALL_NODES] = ETH1394_SPEED_DEF; + priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[priv->sspd[ALL_NODES]]; priv->bc_state = ETHER1394_BC_CHECK; /* Register our limits now */ - ether1394_register_limits (phy_id, (be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf, - host->speed_map[(phy_id << 6) + phy_id], - (u64)(((u64)be32_to_cpu(host->csr.rom[3]) << 32) | - be32_to_cpu(host->csr.rom[4])), - ETHER1394_REGION_ADDR >> 32, - ETHER1394_REGION_ADDR & 0xffffffff, priv); - - /* We'll use our max_rec as the default mtu */ - if (set_mtu) - dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) - /* mtu = max_rec - */ - (sizeof (union eth1394_hdr) + 8); /* (hdr + GASP) */ - - /* Set our hardware address while we're at it */ - *(nodeid_t *)dev->dev_addr = htons (host->node_id); + ether1394_register_limits(phy_id, maxpayload, + host->speed_map[(phy_id << 6) + phy_id], + guid, ETHER1394_REGION_ADDR, priv); + + /* We'll use our maxpayload as the default mtu */ + if (set_mtu) { + dev->mtu = min(ETH1394_DATA_LEN, (int)(priv->maxpayload[phy_id] - + (sizeof(union eth1394_hdr) + ETHER1394_GASP_OVERHEAD))); + + /* Set our hardware address while we're at it */ + *(u64*)dev->dev_addr = guid; + *(u64*)dev->broadcast = ~0x0ULL; + } spin_unlock_irqrestore (&priv->lock, flags); -} -static int ether1394_tx (struct sk_buff *skb, struct net_device *dev); + for (i = 0; i < ALL_NODES; i++) { + struct list_head *lh, *n; + + spin_lock_irqsave(&priv->pdg[i].lock, flags); + if (!set_mtu) { + list_for_each_safe(lh, n, &priv->pdg[i].list) { + purge_partial_datagram(lh); + } + } + INIT_LIST_HEAD(&(priv->pdg[i].list)); + priv->pdg[i].sz = 0; + spin_unlock_irqrestore(&priv->pdg[i].lock, flags); + } +} /* This function is called by register_netdev */ static int ether1394_init_dev (struct net_device *dev) @@ -302,11 +386,21 @@ dev->tx_timeout = ether1394_tx_timeout; dev->change_mtu = ether1394_change_mtu; + dev->hard_header = ether1394_header; + dev->rebuild_header = ether1394_rebuild_header; + dev->hard_header_cache = ether1394_header_cache; + dev->header_cache_update= ether1394_header_cache_update; + dev->hard_header_parse = ether1394_header_parse; + dev->set_mac_address = ether1394_mac_addr; + dev->do_ioctl = ether1394_do_ioctl; + /* Some constants */ dev->watchdog_timeo = ETHER1394_TIMEOUT; - dev->flags = IFF_BROADCAST; /* TODO: Support MCAP */ - dev->features = NETIF_F_NO_CSUM|NETIF_F_SG|NETIF_F_HIGHDMA|NETIF_F_FRAGLIST; - dev->addr_len = 2; + dev->flags = IFF_BROADCAST | IFF_MULTICAST; + dev->features = NETIF_F_HIGHDMA; + dev->addr_len = ETH1394_ALEN; + dev->hard_header_len = ETH1394_HLEN; + dev->type = ARPHRD_IEEE1394; ether1394_reset_priv (dev, 1); @@ -320,6 +414,7 @@ */ static void ether1394_add_host (struct hpsb_host *host) { + int i; struct host_info *hi = NULL; struct net_device *dev = NULL; struct eth1394_priv *priv; @@ -328,10 +423,17 @@ if (version_printed++ == 0) ETH1394_PRINT_G (KERN_INFO, "%s\n", version); + /* We should really have our own alloc_hpsbdev() function in + * net_init.c instead of calling the one for ethernet then hijacking + * it for ourselves. That way we'd be a real networking device. */ dev = alloc_etherdev(sizeof (struct eth1394_priv)); - if (dev == NULL) + if (dev == NULL) { + ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to allocate " + "etherdevice for IEEE 1394 device %s-%d\n", + host->driver->name, host->id); goto out; + } SET_MODULE_OWNER(dev); @@ -339,13 +441,23 @@ priv = (struct eth1394_priv *)dev->priv; - priv->host = host; spin_lock_init(&priv->lock); + priv->host = host; + + for (i = 0; i < ALL_NODES; i++) { + spin_lock_init(&priv->pdg[i].lock); + INIT_LIST_HEAD(&priv->pdg[i].list); + priv->pdg[i].sz = 0; + } hi = hpsb_create_hostinfo(ð1394_highlevel, host, sizeof(*hi)); - if (hi == NULL) + if (hi == NULL) { + ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to create " + "hostinfo for IEEE 1394 device %s-%d\n", + host->driver->name, host->id); goto out; + } if (register_netdev (dev)) { ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n"); @@ -359,10 +471,10 @@ hi->dev = dev; /* Ignore validity in hopes that it will be set in the future. It'll - * check it on transmit. */ + * be checked when the eth device is opened. */ priv->broadcast_channel = host->csr.broadcast_channel & 0x3f; - priv->iso = hpsb_iso_recv_init(host, 8 * 4096, 8, priv->broadcast_channel, + priv->iso = hpsb_iso_recv_init(host, 16 * 4096, 16, priv->broadcast_channel, 1, ether1394_iso); if (priv->iso == NULL) { priv->bc_state = ETHER1394_BC_CLOSED; @@ -371,12 +483,10 @@ out: if (dev != NULL) - kfree (dev); + kfree(dev); if (hi) hpsb_destroy_hostinfo(ð1394_highlevel, host); - ETH1394_PRINT_G (KERN_ERR, "Out of memory\n"); - return; } @@ -388,11 +498,12 @@ if (hi != NULL) { struct eth1394_priv *priv = (struct eth1394_priv *)hi->dev->priv; - priv->bc_state = ETHER1394_BC_CLOSED; - unregister_netdev (hi->dev); - hpsb_iso_shutdown(priv->iso); + eth1394_iso_shutdown(priv); - kfree (hi->dev); + if (hi->dev) { + unregister_netdev (hi->dev); + kfree(hi->dev); + } } return; @@ -416,26 +527,140 @@ netif_wake_queue (dev); } +/****************************************** + * HW Header net device functions + ******************************************/ +/* These functions have been adapted from net/ethernet/eth.c */ + + +/* Create a fake MAC header for an arbitrary protocol layer. + * saddr=NULL means use device source address + * daddr=NULL means leave destination address (eg unresolved arp). */ +static int ether1394_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, + unsigned len) +{ + struct eth1394hdr *eth = (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN); + + eth->h_proto = htons(type); + + if (dev->flags & (IFF_LOOPBACK|IFF_NOARP)) + { + memset(eth->h_dest, 0, dev->addr_len); + return(dev->hard_header_len); + } + + if (daddr) + { + memcpy(eth->h_dest,daddr,dev->addr_len); + return dev->hard_header_len; + } + + return -dev->hard_header_len; + +} + + +/* Rebuild the faked MAC header. This is called after an ARP + * (or in future other address resolution) has completed on this + * sk_buff. We now let ARP fill in the other fields. + * + * This routine CANNOT use cached dst->neigh! + * Really, it is used only when dst->neigh is wrong. + */ +static int ether1394_rebuild_header(struct sk_buff *skb) +{ + struct eth1394hdr *eth = (struct eth1394hdr *)skb->data; + struct net_device *dev = skb->dev; + + switch (eth->h_proto) + { +#ifdef CONFIG_INET + case __constant_htons(ETH_P_IP): + return arp_find((unsigned char*)ð->h_dest, skb); +#endif + default: + printk(KERN_DEBUG + "%s: unable to resolve type %X addresses.\n", + dev->name, (int)eth->h_proto); + break; + } + + return 0; +} + +static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr) +{ + struct net_device *dev = skb->dev; + memcpy(haddr, dev->dev_addr, ETH1394_ALEN); + return ETH1394_ALEN; +} + + +static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh) +{ + unsigned short type = hh->hh_type; + struct eth1394hdr *eth = (struct eth1394hdr*)(((u8*)hh->hh_data) + 6); + struct net_device *dev = neigh->dev; + + if (type == __constant_htons(ETH_P_802_3)) { + return -1; + } + + eth->h_proto = type; + memcpy(eth->h_dest, neigh->ha, dev->addr_len); + + hh->hh_len = ETH1394_HLEN; + return 0; +} + +/* Called by Address Resolution module to notify changes in address. */ +static void ether1394_header_cache_update(struct hh_cache *hh, + struct net_device *dev, + unsigned char * haddr) +{ + memcpy(((u8*)hh->hh_data) + 6, haddr, dev->addr_len); +} + +static int ether1394_mac_addr(struct net_device *dev, void *p) +{ + if (netif_running(dev)) + return -EBUSY; + + /* Not going to allow setting the MAC address, we really need to use + * the real one suppliled by the hardware */ + return -EINVAL; + } + + + +/****************************************** + * Datagram reception code + ******************************************/ + /* Copied from net/ethernet/eth.c */ -static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct net_device *dev) +static inline u16 ether1394_type_trans(struct sk_buff *skb, + struct net_device *dev) { - struct ethhdr *eth; + struct eth1394hdr *eth; unsigned char *rawp; skb->mac.raw = skb->data; - skb_pull (skb, ETH_HLEN); - eth = skb->mac.ethernet; -#if 0 - if(*eth->h_dest & 1) { - if(memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0) + skb_pull (skb, ETH1394_HLEN); + eth = (struct eth1394hdr*)skb->mac.raw; + + if (*eth->h_dest & 1) { + if (memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0) skb->pkt_type = PACKET_BROADCAST; +#if 0 else skb->pkt_type = PACKET_MULTICAST; +#endif } else { - if(memcmp(eth->h_dest, dev->dev_addr, dev->addr_len)) + if (memcmp(eth->h_dest, dev->dev_addr, dev->addr_len)) skb->pkt_type = PACKET_OTHERHOST; } -#endif + if (ntohs (eth->h_proto) >= 1536) return eth->h_proto; @@ -449,102 +674,376 @@ /* Parse an encapsulated IP1394 header into an ethernet frame packet. * We also perform ARP translation here, if need be. */ -static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct net_device *dev, - nodeid_t srcid, nodeid_t destid) +static inline u16 ether1394_parse_encap(struct sk_buff *skb, + struct net_device *dev, + nodeid_t srcid, nodeid_t destid, + u16 ether_type) { - union eth1394_hdr *hdr = (union eth1394_hdr *)skb->data; - unsigned char src_hw[ETH_ALEN], dest_hw[ETH_ALEN]; + struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + u64 dest_hw; unsigned short ret = 0; /* Setup our hw addresses. We use these to build the * ethernet header. */ - *(u16 *)dest_hw = htons(destid); - *(u16 *)src_hw = htons(srcid); - - /* Remove the encapsulation header */ - hdr->words.word1 = ntohs(hdr->words.word1); - skb_pull (skb, hdr_type_len[hdr->common.lf]); + if (destid == (LOCAL_BUS | ALL_NODES)) + dest_hw = ~0ULL; /* broadcast */ + else + dest_hw = priv->eui[NODEID_TO_NODE(destid)]; /* If this is an ARP packet, convert it. First, we want to make * use of some of the fields, since they tell us a little bit * about the sending machine. */ - if (hdr->uf.ether_type == __constant_htons (ETH_P_ARP)) { + if (ether_type == __constant_htons (ETH_P_ARP)) { unsigned long flags; - u16 phy_id = NODEID_TO_NODE(srcid); - struct eth1394_priv *priv = - (struct eth1394_priv *)dev->priv; - struct eth1394_arp arp1394; + struct eth1394_arp *arp1394 = (struct eth1394_arp*)skb->data; struct arphdr *arp = (struct arphdr *)skb->data; unsigned char *arp_ptr = (unsigned char *)(arp + 1); + u64 fifo_addr = (u64)ntohs(arp1394->fifo_hi) << 32 | + ntohl(arp1394->fifo_lo); + u8 host_max_rec = (be32_to_cpu(priv->host->csr.rom[2]) >> + 12) & 0xf; + u8 max_rec = min(host_max_rec, (u8)(arp1394->max_rec)); + u16 maxpayload = min(eth1394_speedto_maxpayload[arp1394->sspd], + (u16)(1 << (max_rec + 1))); - memcpy (&arp1394, arp, sizeof (struct eth1394_arp)); /* Update our speed/payload/fifo_offset table */ spin_lock_irqsave (&priv->lock, flags); - ether1394_register_limits (phy_id, arp1394.max_rec, arp1394.sspd, - le64_to_cpu (arp1394.s_uniq_id), - ntohs (arp1394.fifo_hi), - ntohl (arp1394.fifo_lo), priv); + ether1394_register_limits(NODEID_TO_NODE(srcid), maxpayload, + arp1394->sspd, arp1394->s_uniq_id, + fifo_addr, priv); spin_unlock_irqrestore (&priv->lock, flags); -#define PROCESS_MEMBER(ptr,val,len) \ - memcpy (ptr, val, len); ptr += len - PROCESS_MEMBER (arp_ptr, src_hw, dev->addr_len); - PROCESS_MEMBER (arp_ptr, &arp1394.sip, 4); - PROCESS_MEMBER (arp_ptr, dest_hw, dev->addr_len); - PROCESS_MEMBER (arp_ptr, &arp1394.tip, 4); -#undef PROCESS_MEMBER - - arp->ar_hln = dev->addr_len; - arp->ar_hrd = __constant_htons (ARPHRD_ETHER); - - skb_trim (skb, sizeof (struct arphdr) + 2*(dev->addr_len+4)); + /* Now that we're done with the 1394 specific stuff, we'll + * need to alter some of the data. Believe it or not, all + * that needs to be done is sender_IP_address needs to be + * moved, the destination hardware address get stuffed + * in and the hardware address length set to 8. + * + * IMPORTANT: The code below overwrites 1394 specific data + * needed above data so keep the call to + * ether1394_register_limits() before munging the data for the + * higher level IP stack. */ + + arp->ar_hln = 8; + arp_ptr += arp->ar_hln; /* skip over sender unique id */ + *(u32*)arp_ptr = arp1394->sip; /* move sender IP addr */ + arp_ptr += arp->ar_pln; /* skip over sender IP addr */ + + if (arp->ar_op == 1) + /* just set ARP req target unique ID to 0 */ + memset(arp_ptr, 0, ETH1394_ALEN); + else + memcpy(arp_ptr, dev->dev_addr, ETH1394_ALEN); } /* Now add the ethernet header. */ - if (dev->hard_header (skb, dev, __constant_ntohs (hdr->uf.ether_type), - dest_hw, src_hw, skb->len) >= 0) + if (dev->hard_header (skb, dev, __constant_ntohs (ether_type), + &dest_hw, NULL, skb->len) >= 0) ret = ether1394_type_trans(skb, dev); return ret; } +static inline int fragment_overlap(struct list_head *frag_list, int offset, int len) +{ + struct list_head *lh; + struct fragment_info *fi; + + list_for_each(lh, frag_list) { + fi = list_entry(lh, struct fragment_info, list); + + if ( ! ((offset > (fi->offset + fi->len - 1)) || + ((offset + len - 1) < fi->offset))) + return 1; + } + return 0; +} + +static inline struct list_head *find_partial_datagram(struct list_head *pdgl, int dgl) +{ + struct list_head *lh; + struct partial_datagram *pd; + + list_for_each(lh, pdgl) { + pd = list_entry(lh, struct partial_datagram, list); + if (pd->dgl == dgl) + return lh; + } + return NULL; +} + +/* Assumes that new fragment does not overlap any existing fragments */ +static inline int new_fragment(struct list_head *frag_info, int offset, int len) +{ + struct list_head *lh; + struct fragment_info *fi, *fi2, *new; + + list_for_each(lh, frag_info) { + fi = list_entry(lh, struct fragment_info, list); + if ((fi->offset + fi->len) == offset) { + /* The new fragment can be tacked on to the end */ + fi->len += len; + /* Did the new fragment plug a hole? */ + fi2 = list_entry(lh->next, struct fragment_info, list); + if ((fi->offset + fi->len) == fi2->offset) { + /* glue fragments together */ + fi->len += fi2->len; + list_del(lh->next); + kfree(fi2); + } + return 0; + } else if ((offset + len) == fi->offset) { + /* The new fragment can be tacked on to the beginning */ + fi->offset = offset; + fi->len += len; + /* Did the new fragment plug a hole? */ + fi2 = list_entry(lh->prev, struct fragment_info, list); + if ((fi2->offset + fi2->len) == fi->offset) { + /* glue fragments together */ + fi2->len += fi->len; + list_del(lh); + kfree(fi); + } + return 0; + } else if (offset > (fi->offset + fi->len)) { + break; + } else if ((offset + len) < fi->offset) { + lh = lh->prev; + break; + } + } + + new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC); + if (!new) + return -ENOMEM; + + new->offset = offset; + new->len = len; + + list_add(&new->list, lh); + + return 0; +} + +static inline int new_partial_datagram(struct net_device *dev, + struct list_head *pdgl, int dgl, + int dg_size, char *frag_buf, + int frag_off, int frag_len) +{ + struct partial_datagram *new; + + new = kmalloc(sizeof(struct partial_datagram), GFP_ATOMIC); + if (!new) + return -ENOMEM; + + INIT_LIST_HEAD(&new->frag_info); + + if (new_fragment(&new->frag_info, frag_off, frag_len) < 0) { + kfree(new); + return -ENOMEM; + } + + new->dgl = dgl; + new->dg_size = dg_size; + + new->skb = dev_alloc_skb(dg_size + dev->hard_header_len + 15); + if (!new->skb) { + struct fragment_info *fi = list_entry(new->frag_info.next, + struct fragment_info, + list); + kfree(fi); + kfree(new); + return -ENOMEM; + } + + skb_reserve(new->skb, (dev->hard_header_len + 15) & ~15); + new->pbuf = skb_put(new->skb, dg_size); + memcpy(new->pbuf + frag_off, frag_buf, frag_len); + + list_add(&new->list, pdgl); + + return 0; +} + +static inline int update_partial_datagram(struct list_head *pdgl, struct list_head *lh, + char *frag_buf, int frag_off, int frag_len) +{ + struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list); + + if (new_fragment(&pd->frag_info, frag_off, frag_len) < 0) { + return -ENOMEM; + } + + memcpy(pd->pbuf + frag_off, frag_buf, frag_len); + + /* Move list entry to beginnig of list so that oldest partial + * datagrams percolate to the end of the list */ + list_del(lh); + list_add(lh, pdgl); + + return 0; +} + +static inline void purge_partial_datagram(struct list_head *old) +{ + struct partial_datagram *pd = list_entry(old, struct partial_datagram, list); + struct list_head *lh, *n; + + list_for_each_safe(lh, n, &pd->frag_info) { + struct fragment_info *fi = list_entry(lh, struct fragment_info, list); + list_del(lh); + kfree(fi); + } + list_del(old); + kfree_skb(pd->skb); + kfree(pd); +} + +static inline int is_datagram_complete(struct list_head *lh, int dg_size) +{ + struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list); + struct fragment_info *fi = list_entry(pd->frag_info.next, + struct fragment_info, list); + + return (fi->len == dg_size); +} + /* Packet reception. We convert the IP1394 encapsulation header to an * ethernet header, and fill it with some of our other fields. This is * an incoming packet from the 1394 bus. */ -static int ether1394_write (struct hpsb_host *host, int srcid, int destid, - quadlet_t *data, u64 addr, unsigned int len, u16 fl) +static int ether1394_data_handler(struct net_device *dev, int srcid, int destid, + char *buf, int len) { struct sk_buff *skb; - char *buf = (char *)data; unsigned long flags; - struct host_info *hi = hpsb_get_hostinfo(ð1394_highlevel, host); - struct net_device *dev; struct eth1394_priv *priv; + union eth1394_hdr *hdr = (union eth1394_hdr *)buf; + u16 ether_type = 0; /* initialized to clear warning */ + int hdr_len; - if (hi == NULL) { - ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %p\n", - host); - return RCODE_ADDRESS_ERROR; - } + priv = (struct eth1394_priv *)dev->priv; - dev = hi->dev; + /* First, did we receive a fragmented or unfragmented datagram? */ + hdr->words.word1 = ntohs(hdr->words.word1); - priv = (struct eth1394_priv *)dev->priv; + hdr_len = hdr_type_len[hdr->common.lf]; - /* A packet has been received by the ieee1394 bus. Build an skbuff - * around it so we can pass it to the high level network layer. */ + if (hdr->common.lf == ETH1394_HDR_LF_UF) { + /* An unfragmented datagram has been received by the ieee1394 + * bus. Build an skbuff around it so we can pass it to the + * high level network layer. */ - skb = dev_alloc_skb (len + dev->hard_header_len + 15); - if (!skb) { - HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n"); - priv->stats.rx_dropped++; - return RCODE_ADDRESS_ERROR; - } + skb = dev_alloc_skb(len + dev->hard_header_len + 15); + if (!skb) { + HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n"); + priv->stats.rx_dropped++; + return -1; + } + skb_reserve(skb, (dev->hard_header_len + 15) & ~15); + memcpy(skb_put(skb, len - hdr_len), buf + hdr_len, len - hdr_len); + ether_type = hdr->uf.ether_type; + } else { + /* A datagram fragment has been received, now the fun begins. */ + + struct list_head *pdgl, *lh; + struct partial_datagram *pd; + int fg_off; + int fg_len = len - hdr_len; + int dg_size; + int dgl; + int retval; + int sid = NODEID_TO_NODE(srcid); + struct pdg_list *pdg = &(priv->pdg[sid]); + + hdr->words.word3 = ntohs(hdr->words.word3); + /* The 4th header word is reserved so no need to do ntohs() */ + + if (hdr->common.lf == ETH1394_HDR_LF_FF) { + ether_type = hdr->ff.ether_type; + dgl = hdr->ff.dgl; + dg_size = hdr->ff.dg_size + 1; + fg_off = 0; + } else { + hdr->words.word2 = ntohs(hdr->words.word2); + dgl = hdr->sf.dgl; + dg_size = hdr->sf.dg_size + 1; + fg_off = hdr->sf.fg_off; + } + spin_lock_irqsave(&pdg->lock, flags); + + pdgl = &(pdg->list); + lh = find_partial_datagram(pdgl, dgl); - skb_reserve(skb, (dev->hard_header_len + 15) & ~15); + if (lh == NULL) { + if (pdg->sz == max_partial_datagrams) { + /* remove the oldest */ + purge_partial_datagram(pdgl->prev); + pdg->sz--; + } + + retval = new_partial_datagram(dev, pdgl, dgl, dg_size, + buf + hdr_len, fg_off, + fg_len); + if (retval < 0) { + spin_unlock_irqrestore(&pdg->lock, flags); + goto bad_proto; + } + pdg->sz++; + lh = find_partial_datagram(pdgl, dgl); + } else { + struct partial_datagram *pd; + + pd = list_entry(lh, struct partial_datagram, list); + + if (fragment_overlap(&pd->frag_info, fg_off, fg_len)) { + /* Overlapping fragments, obliterate old + * datagram and start new one. */ + purge_partial_datagram(lh); + retval = new_partial_datagram(dev, pdgl, dgl, + dg_size, + buf + hdr_len, + fg_off, fg_len); + if (retval < 0) { + pdg->sz--; + spin_unlock_irqrestore(&pdg->lock, flags); + goto bad_proto; + } + } else { + retval = update_partial_datagram(pdgl, lh, + buf + hdr_len, + fg_off, fg_len); + if (retval < 0) { + /* Couldn't save off fragment anyway + * so might as well obliterate the + * datagram now. */ + purge_partial_datagram(lh); + pdg->sz--; + spin_unlock_irqrestore(&pdg->lock, flags); + goto bad_proto; + } + } /* fragment overlap */ + } /* new datagram or add to existing one */ + + pd = list_entry(lh, struct partial_datagram, list); + + if (hdr->common.lf == ETH1394_HDR_LF_FF) { + pd->ether_type = ether_type; + } - memcpy (skb_put (skb, len), buf, len); + if (is_datagram_complete(lh, dg_size)) { + ether_type = pd->ether_type; + pdg->sz--; + skb = skb_get(pd->skb); + purge_partial_datagram(lh); + spin_unlock_irqrestore(&pdg->lock, flags); + } else { + /* Datagram is not complete, we're done for the + * moment. */ + spin_unlock_irqrestore(&pdg->lock, flags); + return 0; + } + } /* unframgented datagram or fragmented one */ /* Write metadata, and then pass to the receive level */ skb->dev = dev; @@ -554,9 +1053,11 @@ * converting to an ethernet frame header, aswell as arp * conversion if needed. ARP conversion is easier in this * direction, since we are using ethernet as our backend. */ - skb->protocol = ether1394_parse_encap (skb, dev, srcid, destid); + skb->protocol = ether1394_parse_encap(skb, dev, srcid, destid, + ether_type); - spin_lock_irqsave (&priv->lock, flags); + + spin_lock_irqsave(&priv->lock, flags); if (!skb->protocol) { priv->stats.rx_errors++; priv->stats.rx_dropped++; @@ -564,8 +1065,7 @@ goto bad_proto; } - netif_stop_queue(dev); - if (netif_rx (skb) == NET_RX_DROP) { + if (netif_rx(skb) == NET_RX_DROP) { priv->stats.rx_errors++; priv->stats.rx_dropped++; goto bad_proto; @@ -576,20 +1076,36 @@ priv->stats.rx_bytes += skb->len; bad_proto: - netif_start_queue(dev); - spin_unlock_irqrestore (&priv->lock, flags); + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); + spin_unlock_irqrestore(&priv->lock, flags); dev->last_rx = jiffies; - return RCODE_COMPLETE; + return 0; +} + +static int ether1394_write(struct hpsb_host *host, int srcid, int destid, + quadlet_t *data, u64 addr, unsigned int len, u16 flags) +{ + struct host_info *hi = hpsb_get_hostinfo(ð1394_highlevel, host); + + if (hi == NULL) { + ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n", + host->driver->name); + return RCODE_ADDRESS_ERROR; + } + + if (ether1394_data_handler(hi->dev, srcid, destid, (char*)data, len)) + return RCODE_ADDRESS_ERROR; + else + return RCODE_COMPLETE; } static void ether1394_iso(struct hpsb_iso *iso) { - struct sk_buff *skb; quadlet_t *data; char *buf; - unsigned long flags; struct host_info *hi = hpsb_get_hostinfo(ð1394_highlevel, iso->host); struct net_device *dev; struct eth1394_priv *priv; @@ -600,15 +1116,15 @@ int nready; if (hi == NULL) { - ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %s\n", - iso->host->driver->name); + ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n", + iso->host->driver->name); return; } dev = hi->dev; nready = hpsb_iso_n_ready(iso); - for(i = 0; i < nready; i++) { + for (i = 0; i < nready; i++) { struct hpsb_iso_packet_info *info = &iso->infos[iso->first_packet + i]; data = (quadlet_t*) (iso->data_buf.kvirt + info->offset); @@ -622,186 +1138,327 @@ priv = (struct eth1394_priv *)dev->priv; - if (info->channel != priv->broadcast_channel || - specifier_id != ETHER1394_GASP_SPECIFIER_ID) { + if (info->channel != (iso->host->csr.broadcast_channel & 0x3f) || + specifier_id != ETHER1394_GASP_SPECIFIER_ID) { /* This packet is not for us */ continue; } + ether1394_data_handler(dev, source_id, LOCAL_BUS | ALL_NODES, + buf, len); + } - /* A packet has been received by the ieee1394 bus. Build an skbuff - * around it so we can pass it to the high level network layer. */ - skb = dev_alloc_skb (len + dev->hard_header_len + 15); - if (!skb) { - HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n"); - priv->stats.rx_dropped++; - break; - } + hpsb_iso_recv_release_packets(iso, i); - skb_reserve(skb, (dev->hard_header_len + 15) & ~15); + dev->last_rx = jiffies; +} + +/****************************************** + * Datagram transmission code + ******************************************/ + +/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the entire + * arphdr) is the same format as the ip1394 header, so they overlap. The rest + * needs to be munged a bit. The remainder of the arphdr is formatted based + * on hwaddr len and ipaddr len. We know what they'll be, so it's easy to + * judge. + * + * Now that the EUI is used for the hardware address all we need to do to make + * this work for 1394 is to insert 2 quadlets that contain max_rec size, + * speed, and unicast FIFO address information between the sender_unique_id + * and the IP addresses. + */ +static inline void ether1394_arp_to_1394arp(struct sk_buff *skb, + struct net_device *dev) +{ + struct eth1394_priv *priv = (struct eth1394_priv *)(dev->priv); + u16 phy_id = NODEID_TO_NODE(priv->host->node_id); - memcpy (skb_put (skb, len), buf, len); + struct arphdr *arp = (struct arphdr *)skb->data; + unsigned char *arp_ptr = (unsigned char *)(arp + 1); + struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data; - /* Write metadata, and then pass to the receive level */ - skb->dev = dev; - skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ - - /* Parse the encapsulation header. This actually does the job of - * converting to an ethernet frame header, aswell as arp - * conversion if needed. ARP conversion is easier in this - * direction, since we are using ethernet as our backend. */ - skb->protocol = ether1394_parse_encap (skb, dev, source_id, - LOCAL_BUS | ALL_NODES); + /* Believe it or not, all that need to happen is sender IP get moved + * and set hw_addr_len, max_rec, sspd, fifo_hi and fifo_lo. */ + arp1394->hw_addr_len = 16; + arp1394->sip = *(u32*)(arp_ptr + ETH1394_ALEN); + arp1394->max_rec = (be32_to_cpu(priv->host->csr.rom[2]) >> 12) & 0xf; + arp1394->sspd = priv->sspd[phy_id]; + arp1394->fifo_hi = htons (priv->fifo[phy_id] >> 32); + arp1394->fifo_lo = htonl (priv->fifo[phy_id] & ~0x0); - spin_lock_irqsave (&priv->lock, flags); - if (!skb->protocol) { - priv->stats.rx_errors++; - priv->stats.rx_dropped++; - dev_kfree_skb_any(skb); - goto bad_proto; - } + return; +} - netif_stop_queue(dev); - if (netif_rx (skb) == NET_RX_DROP) { - priv->stats.rx_errors++; - priv->stats.rx_dropped++; - goto bad_proto; - } +/* We need to encapsulate the standard header with our own. We use the + * ethernet header's proto for our own. */ +static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload, + int proto, + union eth1394_hdr *hdr, + u16 dg_size, u16 dgl) +{ + unsigned int adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_UF]; + + /* Does it all fit in one packet? */ + if (dg_size <= adj_max_payload) { + hdr->uf.lf = ETH1394_HDR_LF_UF; + hdr->uf.ether_type = proto; + } else { + hdr->ff.lf = ETH1394_HDR_LF_FF; + hdr->ff.ether_type = proto; + hdr->ff.dg_size = dg_size - 1; + hdr->ff.dgl = dgl; + adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF]; + } + return((dg_size + (adj_max_payload - 1)) / adj_max_payload); +} - /* Statistics */ - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; +static inline unsigned int ether1394_encapsulate(struct sk_buff *skb, + unsigned int max_payload, + union eth1394_hdr *hdr) +{ + union eth1394_hdr *bufhdr; + int ftype = hdr->common.lf; + int hdrsz = hdr_type_len[ftype]; + unsigned int adj_max_payload = max_payload - hdrsz; + + switch(ftype) { + case ETH1394_HDR_LF_UF: + bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz); + bufhdr->words.word1 = htons(hdr->words.word1); + bufhdr->words.word2 = hdr->words.word2; + break; - bad_proto: - spin_unlock_irqrestore (&priv->lock, flags); + case ETH1394_HDR_LF_FF: + bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz); + bufhdr->words.word1 = htons(hdr->words.word1); + bufhdr->words.word2 = hdr->words.word2; + bufhdr->words.word3 = htons(hdr->words.word3); + bufhdr->words.word4 = 0; + + /* Set frag type here for future interior fragments */ + hdr->common.lf = ETH1394_HDR_LF_IF; + hdr->sf.fg_off = 0; + break; + + default: + hdr->sf.fg_off += adj_max_payload; + bufhdr = (union eth1394_hdr *)skb_pull(skb, adj_max_payload); + if (max_payload >= skb->len) + hdr->common.lf = ETH1394_HDR_LF_LF; + bufhdr->words.word1 = htons(hdr->words.word1); + bufhdr->words.word2 = htons(hdr->words.word2); + bufhdr->words.word3 = htons(hdr->words.word3); + bufhdr->words.word4 = 0; } - hpsb_iso_recv_release_packets(iso, i); + return min(max_payload, skb->len); +} - netif_start_queue(dev); - - dev->last_rx = jiffies; +static inline struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host *host) +{ + struct hpsb_packet *p; - return; + p = alloc_hpsb_packet(0); + if (p) { + p->host = host; + p->data = NULL; + p->generation = get_hpsb_generation(host); + p->type = hpsb_async; + } + return p; } +static inline int ether1394_prep_write_packet(struct hpsb_packet *p, + struct hpsb_host *host, + nodeid_t node, u64 addr, + void * data, int tx_len) +{ + p->node_id = node; + p->data = NULL; + + p->tcode = TCODE_WRITEB; + p->header[1] = (host->node_id << 16) | (addr >> 32); + p->header[2] = addr & 0xffffffff; + + p->header_size = 16; + p->expect_response = 1; + + if (hpsb_get_tlabel(p, !in_interrupt())) { + ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending " + "to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(host, node)); + return -1; + } + p->header[0] = (p->node_id << 16) | (p->tlabel << 10) + | (1 << 8) | (TCODE_WRITEB << 4); + + p->header[3] = tx_len << 16; + p->data_size = tx_len + (tx_len % 4 ? 4 - (tx_len % 4) : 0); + p->data = (quadlet_t*)data; -/* This function is our scheduled write */ -static void hpsb_write_sched (void *__ptask) + return 0; +} + +static inline void ether1394_prep_gasp_packet(struct hpsb_packet *p, + struct eth1394_priv *priv, + struct sk_buff *skb, int length) { - struct packet_task *ptask = (struct packet_task *)__ptask; - struct sk_buff *skb = ptask->skb; - struct net_device *dev = ptask->skb->dev; - struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; - unsigned long flags; - int status; - + p->header_size = 4; + p->tcode = TCODE_STREAM_DATA; + + p->header[0] = (length << 16) | (3 << 14) + | ((priv->broadcast_channel) << 8) + | (TCODE_STREAM_DATA << 4); + p->data_size = length; + p->data = ((quadlet_t*)skb->data) - 2; + p->data[0] = cpu_to_be32((priv->host->node_id << 16) | + ETHER1394_GASP_SPECIFIER_ID_HI); + p->data[1] = cpu_to_be32((ETHER1394_GASP_SPECIFIER_ID_LO << 24) | + ETHER1394_GASP_VERSION); + + /* Setting the node id to ALL_NODES (not LOCAL_BUS | ALL_NODES) + * prevents hpsb_send_packet() from setting the speed to an arbitrary + * value based on packet->node_id if packet->node_id is not set. */ + p->node_id = ALL_NODES; + p->speed_code = priv->sspd[ALL_NODES]; +} + +static inline void ether1394_free_packet(struct hpsb_packet *packet) +{ + if (packet->tcode != TCODE_STREAM_DATA) + hpsb_free_tlabel(packet); + packet->data = NULL; + free_hpsb_packet(packet); +} + +static void ether1394_complete_cb(void *__ptask); + +static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) +{ + struct eth1394_priv *priv = ptask->priv; + struct hpsb_packet *packet = NULL; + + packet = ether1394_alloc_common_packet(priv->host); + if (!packet) + return -1; + if (ptask->tx_type == ETH1394_GASP) { - status = hpsb_send_gasp(priv->host, priv->broadcast_channel, - get_hpsb_generation(priv->host), - (quadlet_t *)skb->data, skb->len, - ETHER1394_GASP_SPECIFIER_ID, - ETHER1394_GASP_VERSION); - } else { - status = hpsb_write(priv->host, ptask->dest_node, - get_hpsb_generation(priv->host), - ptask->addr, (quadlet_t *)skb->data, - skb->len); + int length = tx_len + (2 * sizeof(quadlet_t)); + + ether1394_prep_gasp_packet(packet, priv, ptask->skb, length); + } else if (ether1394_prep_write_packet(packet, priv->host, + ptask->dest_node, + ptask->addr, ptask->skb->data, + tx_len)) { + goto fail; } + ptask->packet = packet; + hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb, + ptask); + if (hpsb_send_packet(packet)) + return 0; + +fail: + if (packet) + ether1394_free_packet(packet); + + return -1; +} + + +/* Task function to be run when a datagram transmission is completed */ +static inline void ether1394_dg_complete(struct packet_task *ptask, int fail) +{ + struct sk_buff *skb = ptask->skb; + struct net_device *dev = skb->dev; + struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + unsigned long flags; + /* Statistics */ - spin_lock_irqsave (&priv->lock, flags); - if (!status) { - priv->stats.tx_bytes += skb->len; - priv->stats.tx_packets++; - } else { - //printk("Failed in hpsb_write_sched\n"); + spin_lock_irqsave(&priv->lock, flags); + if (fail) { priv->stats.tx_dropped++; priv->stats.tx_errors++; - if (netif_queue_stopped (dev)) - netif_wake_queue (dev); + } else { + priv->stats.tx_bytes += skb->len; + priv->stats.tx_packets++; } - spin_unlock_irqrestore (&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); - dev->trans_start = jiffies; - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); kmem_cache_free(packet_task_cache, ptask); +} - return; + +/* Callback for when a packet has been sent and the status of that packet is + * known */ +static void ether1394_complete_cb(void *__ptask) +{ + struct packet_task *ptask = (struct packet_task *)__ptask; + struct hpsb_packet *packet = ptask->packet; + int fail = 0; + + if (packet->tcode != TCODE_STREAM_DATA) + fail = hpsb_packet_success(packet); + + ether1394_free_packet(packet); + + ptask->outstanding_pkts--; + if (ptask->outstanding_pkts > 0 && !fail) + { + int tx_len; + + /* Add the encapsulation header to the fragment */ + tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload, + &ptask->hdr); + if (ether1394_send_packet(ptask, tx_len)) + ether1394_dg_complete(ptask, 1); + } else { + ether1394_dg_complete(ptask, fail); + } } + + /* Transmit a packet (called by kernel) */ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) { - int kmflags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL; - struct ethhdr *eth; + int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; + struct eth1394hdr *eth; struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; int proto; unsigned long flags; nodeid_t dest_node; - u64 addr; - struct packet_task *ptask = NULL; + eth1394_tx_type tx_type; int ret = 0; + unsigned int tx_len; + unsigned int max_payload; + u16 dg_size; + u16 dgl; + struct packet_task *ptask; + struct node_entry *ne; + + ptask = kmem_cache_alloc(packet_task_cache, kmflags); + if (ptask == NULL) { + ret = -ENOMEM; + goto fail; + } spin_lock_irqsave (&priv->lock, flags); if (priv->bc_state == ETHER1394_BC_CLOSED) { ETH1394_PRINT(KERN_ERR, dev->name, - "Cannot send packet, no broadcast channel available."); + "Cannot send packet, no broadcast channel available.\n"); ret = -EAGAIN; + spin_unlock_irqrestore (&priv->lock, flags); goto fail; } - /* First time sending? Need a broadcast channel for ARP and for - * listening on */ - if (priv->bc_state == ETHER1394_BC_CHECK) { - quadlet_t bc; - - /* Get the local copy of the broadcast channel and check its - * validity (the IRM should validate it for us) */ - - bc = priv->host->csr.broadcast_channel; - - if ((bc & 0xc0000000) != 0xc0000000) { - /* broadcast channel not validated yet */ - ETH1394_PRINT(KERN_WARNING, dev->name, - "Error BROADCAST_CHANNEL register valid " - "bit not set, can't send IP traffic\n"); - hpsb_iso_shutdown(priv->iso); - priv->bc_state = ETHER1394_BC_CLOSED; - ret = -EAGAIN; - spin_unlock_irqrestore (&priv->lock, flags); - goto fail; - } - if (priv->broadcast_channel != (bc & 0x3f)) { - /* This really shouldn't be possible, but just in case - * the IEEE 1394 spec changes regarding broadcast - * channels in the future. */ - hpsb_iso_shutdown(priv->iso); - - priv->broadcast_channel = bc & 0x3f; - ETH1394_PRINT(KERN_WARNING, dev->name, - "Changing to broadcast channel %d...\n", - priv->broadcast_channel); - - priv->iso = hpsb_iso_recv_init(priv->host, 8 * 4096, - 8, priv->broadcast_channel, - 1, ether1394_iso); - if (priv->iso == NULL) { - ret = -EAGAIN; - goto fail; - } - } - if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) { - ETH1394_PRINT(KERN_ERR, dev->name, - "Could not start async reception\n"); - hpsb_iso_shutdown(priv->iso); - priv->bc_state = ETHER1394_BC_CLOSED; - ret = -EAGAIN; - spin_unlock_irqrestore (&priv->lock, flags); - goto fail; - } - priv->bc_state = ETHER1394_BC_OPENED; + if ((ret = ether1394_init_bc(dev))) { + spin_unlock_irqrestore (&priv->lock, flags); + goto fail; } + spin_unlock_irqrestore (&priv->lock, flags); if ((skb = skb_share_check (skb, kmflags)) == NULL) { @@ -809,70 +1466,160 @@ goto fail; } - /* Get rid of the ethernet header, but save a pointer */ - eth = (struct ethhdr *)skb->data; - skb_pull (skb, ETH_HLEN); - - /* Save the destination id, and proto for our encapsulation, then - * toss the ethernet header aside like the cheap whore it is. */ - dest_node = ntohs (*(nodeid_t *)(eth->h_dest)); + /* Get rid of the fake eth1394 header, but save a pointer */ + eth = (struct eth1394hdr*)skb->data; + skb_pull(skb, ETH1394_HLEN); + + ne = hpsb_guid_get_entry(be64_to_cpu(*(u64*)eth->h_dest)); + if (!ne) + dest_node = LOCAL_BUS | ALL_NODES; + else + dest_node = ne->nodeid; + proto = eth->h_proto; /* If this is an ARP packet, convert it */ if (proto == __constant_htons (ETH_P_ARP)) ether1394_arp_to_1394arp (skb, dev); - ptask = kmem_cache_alloc(packet_task_cache, kmflags); - if (ptask == NULL) { - ret = -ENOMEM; - goto fail; + max_payload = priv->maxpayload[NODEID_TO_NODE(dest_node)]; + + /* This check should be unnecessary, but we'll keep it for safety for + * a while longer. */ + if (max_payload < 512) { + ETH1394_PRINT(KERN_WARNING, dev->name, + "max_payload too small: %d (setting to 512)\n", + max_payload); + max_payload = 512; } - /* Now add our encapsulation header */ - ether1394_encapsulate (skb, dev, proto, ptask); + /* Set the transmission type for the packet. ARP packets and IP + * broadcast packets are sent via GASP. */ + if (memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0 || + proto == __constant_htons(ETH_P_ARP) || + (proto == __constant_htons(ETH_P_IP) && + IN_MULTICAST(__constant_ntohl(skb->nh.iph->daddr)))) { + tx_type = ETH1394_GASP; + max_payload -= ETHER1394_GASP_OVERHEAD; + } else { + tx_type = ETH1394_WRREQ; + } - /* TODO: The above encapsulate function needs to recognize when a - * packet needs to be split for a specified node. It should create - * a list of skb's that we could then iterate over for the below - * call to schedule our writes. */ - - /* XXX: Right now we accept that we don't exactly follow RFC. When - * we do, we will send ARP requests via GASP format, and so we won't - * need this hack. */ + dg_size = skb->len; spin_lock_irqsave (&priv->lock, flags); - addr = (u64)priv->fifo_hi[NODEID_TO_NODE(dest_node)] << 32 | - priv->fifo_lo[NODEID_TO_NODE(dest_node)]; + dgl = priv->dgl[NODEID_TO_NODE(dest_node)]; + if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) + priv->dgl[NODEID_TO_NODE(dest_node)]++; spin_unlock_irqrestore (&priv->lock, flags); - if (!addr) - addr = ETHER1394_REGION_ADDR; - + ptask->hdr.words.word1 = 0; + ptask->hdr.words.word2 = 0; + ptask->hdr.words.word3 = 0; + ptask->hdr.words.word4 = 0; ptask->skb = skb; - ptask->addr = addr; - ptask->dest_node = dest_node; - /* TODO: When 2.4 is out of the way, give each of our ethernet - * dev's a workqueue to handle these. */ - INIT_TQUEUE(&ptask->tq, hpsb_write_sched, ptask); - schedule_task(&ptask->tq); + ptask->priv = priv; + ptask->tx_type = tx_type; + + if (tx_type != ETH1394_GASP) { + u64 addr; + /* This test is just temporary until ConfigROM support has + * been added to eth1394. Until then, we need an ARP packet + * after a bus reset from the current destination node so that + * we can get FIFO information. */ + if (priv->fifo[NODEID_TO_NODE(dest_node)] == 0ULL) { + ret = -EAGAIN; + goto fail; + } + + spin_lock_irqsave(&priv->lock, flags); + addr = priv->fifo[NODEID_TO_NODE(dest_node)]; + spin_unlock_irqrestore(&priv->lock, flags); + + ptask->addr = addr; + ptask->dest_node = dest_node; + } + + ptask->tx_type = tx_type; + ptask->max_payload = max_payload; + ptask->outstanding_pkts = ether1394_encapsulate_prep(max_payload, proto, + &ptask->hdr, dg_size, + dgl); + + /* Add the encapsulation header to the fragment */ + tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr); + dev->trans_start = jiffies; + if (ether1394_send_packet(ptask, tx_len)) + goto fail; + + netif_wake_queue(dev); return 0; fail: - printk("Failed in ether1394_tx\n"); + if (ptask) + kmem_cache_free(packet_task_cache, ptask); if (skb != NULL) - dev_kfree_skb (skb); + dev_kfree_skb(skb); spin_lock_irqsave (&priv->lock, flags); priv->stats.tx_dropped++; priv->stats.tx_errors++; - if (netif_queue_stopped (dev)) - netif_wake_queue (dev); spin_unlock_irqrestore (&priv->lock, flags); + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); + return 0; /* returning non-zero causes serious problems */ } +static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + switch(cmd) { + case SIOCETHTOOL: + return ether1394_ethtool_ioctl(dev, (void *) ifr->ifr_data); + + case SIOCGMIIPHY: /* Get address of MII PHY in use. */ + case SIOCGMIIREG: /* Read MII PHY register. */ + case SIOCSMIIREG: /* Write MII PHY register. */ + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, driver_name); + strcpy (info.version, "$Rev: 1010 $"); + /* FIXME XXX provide sane businfo */ + strcpy (info.bus_info, "ieee1394"); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + break; + } + case ETHTOOL_GSET: + case ETHTOOL_SSET: + case ETHTOOL_NWAY_RST: + case ETHTOOL_GLINK: + case ETHTOOL_GMSGLVL: + case ETHTOOL_SMSGLVL: + default: + return -EOPNOTSUPP; + } + + return 0; +} + /* Function for incoming 1394 packets */ static struct hpsb_address_ops addr_ops = { .write = ether1394_write, @@ -880,7 +1627,7 @@ /* Ieee1394 highlevel driver functions */ static struct hpsb_highlevel eth1394_highlevel = { - .name = ETHER1394_DRIVER_NAME, + .name = driver_name, .add_host = ether1394_add_host, .remove_host = ether1394_remove_host, .host_reset = ether1394_host_reset, diff -urN linux-2.4.21/drivers/ieee1394/eth1394.h linux-2.4.22/drivers/ieee1394/eth1394.h --- linux-2.4.21/drivers/ieee1394/eth1394.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/eth1394.h 2003-08-25 04:44:41.000000000 -0700 @@ -24,6 +24,8 @@ #ifndef __ETH1394_H #define __ETH1394_H +#include "ieee1394.h" + /* Register for incoming packets. This is 8192 bytes, which supports up to * 1600mbs. We'll need to change this if that ever becomes "small" :) */ #define ETHER1394_REGION_ADDR_LEN 8192 @@ -32,27 +34,38 @@ /* GASP identifier numbers for IPv4 over IEEE 1394 */ #define ETHER1394_GASP_SPECIFIER_ID 0x00005E +#define ETHER1394_GASP_SPECIFIER_ID_HI ((ETHER1394_GASP_SPECIFIER_ID >> 8) & 0xffff) +#define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff) #define ETHER1394_GASP_VERSION 1 +#define ETHER1394_GASP_OVERHEAD (2 * sizeof(quadlet_t)) /* GASP header overhead */ + /* Node set == 64 */ #define NODE_SET (ALL_NODES + 1) enum eth1394_bc_states { ETHER1394_BC_CLOSED, ETHER1394_BC_OPENED, ETHER1394_BC_CHECK }; +struct pdg_list { + struct list_head list; /* partial datagram list per node */ + unsigned int sz; /* partial datagram list size per node */ + spinlock_t lock; /* partial datagram lock */ +}; + /* Private structure for our ethernet driver */ struct eth1394_priv { struct net_device_stats stats; /* Device stats */ struct hpsb_host *host; /* The card for this dev */ - unsigned char max_rec[NODE_SET];/* Max payload per node */ + u16 maxpayload[NODE_SET]; /* Max payload per node */ unsigned char sspd[NODE_SET]; /* Max speed per node */ - u16 fifo_hi[ALL_NODES]; /* 16bit hi fifo offset per node */ - u32 fifo_lo[ALL_NODES]; /* 32bit lo fifo offset per node */ + u64 fifo[ALL_NODES]; /* FIFO offset per node */ u64 eui[ALL_NODES]; /* EUI-64 per node */ spinlock_t lock; /* Private lock */ int broadcast_channel; /* Async stream Broadcast Channel */ enum eth1394_bc_states bc_state; /* broadcast channel state */ struct hpsb_iso *iso; /* Async stream recv handle */ + struct pdg_list pdg[ALL_NODES]; /* partial RX datagram lists */ + int dgl[NODE_SET]; /* Outgoing datagram label per node */ }; struct host_info { @@ -60,16 +73,22 @@ struct net_device *dev; }; -typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type; -/* This is our task struct. It's used for the packet complete callback. */ -struct packet_task { - struct sk_buff *skb; /* Socket buffer we are sending */ - nodeid_t dest_node; /* Destination of the packet */ - u64 addr; /* Address */ - struct tq_struct tq; /* The task */ - eth1394_tx_type tx_type; /* Send data via GASP or Write Req. */ -}; +/* Define a fake hardware header format for the networking core. Note that + * header size cannot exceed 16 bytes as that is the size of the header cache. + * Also, we do not need the source address in the header so we omit it and + * keep the header to under 16 bytes */ +#define ETH1394_ALEN (8) +#define ETH1394_HLEN (10) + +struct eth1394hdr { + unsigned char h_dest[ETH1394_ALEN]; /* destination eth1394 addr */ + unsigned short h_proto; /* packet type ID field */ +} __attribute__((packed)); + + + +typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type; /* IP1394 headers */ #include @@ -77,14 +96,14 @@ /* Unfragmented */ #if defined __BIG_ENDIAN_BITFIELD struct eth1394_uf_hdr { - u8 lf:2; + u16 lf:2; u16 res:14; u16 ether_type; /* Ethernet packet type */ } __attribute__((packed)); #elif defined __LITTLE_ENDIAN_BITFIELD struct eth1394_uf_hdr { u16 res:14; - u8 lf:2; + u16 lf:2; u16 ether_type; } __attribute__((packed)); #else @@ -94,8 +113,8 @@ /* First fragment */ #if defined __BIG_ENDIAN_BITFIELD struct eth1394_ff_hdr { - u8 lf:2; - u8 res1:2; + u16 lf:2; + u16 res1:2; u16 dg_size:12; /* Datagram size */ u16 ether_type; /* Ethernet packet type */ u16 dgl; /* Datagram label */ @@ -104,8 +123,8 @@ #elif defined __LITTLE_ENDIAN_BITFIELD struct eth1394_ff_hdr { u16 dg_size:12; - u8 res1:2; - u8 lf:2; + u16 res1:2; + u16 lf:2; u16 ether_type; u16 dgl; u16 res2; @@ -117,21 +136,21 @@ /* XXX: Subsequent fragments, including last */ #if defined __BIG_ENDIAN_BITFIELD struct eth1394_sf_hdr { - u8 lf:2; - u8 res1:2; + u16 lf:2; + u16 res1:2; u16 dg_size:12; /* Datagram size */ - u8 res2:6; - u16 fg_off:10; /* Fragment offset */ + u16 res2:4; + u16 fg_off:12; /* Fragment offset */ u16 dgl; /* Datagram label */ u16 res3; } __attribute__((packed)); #elif defined __LITTLE_ENDIAN_BITFIELD struct eth1394_sf_hdr { u16 dg_size:12; - u8 res1:2; - u8 lf:2; - u16 fg_off:10; - u8 res2:6; + u16 res1:2; + u16 lf:2; + u16 fg_off:12; + u16 res2:4; u16 dgl; u16 res3; } __attribute__((packed)); @@ -141,13 +160,13 @@ #if defined __BIG_ENDIAN_BITFIELD struct eth1394_common_hdr { - u8 lf:2; + u16 lf:2; u16 pad1:14; } __attribute__((packed)); #elif defined __LITTLE_ENDIAN_BITFIELD struct eth1394_common_hdr { u16 pad1:14; - u8 lf:2; + u16 lf:2; } __attribute__((packed)); #else #error Unknown bit field type @@ -199,4 +218,17 @@ /* Network timeout */ #define ETHER1394_TIMEOUT 100000 +/* This is our task struct. It's used for the packet complete callback. */ +struct packet_task { + struct sk_buff *skb; + int outstanding_pkts; + eth1394_tx_type tx_type; + int max_payload; + struct hpsb_packet *packet; + struct eth1394_priv *priv; + union eth1394_hdr hdr; + u64 addr; + u16 dest_node; +}; + #endif /* __ETH1394_H */ diff -urN linux-2.4.21/drivers/ieee1394/highlevel.c linux-2.4.22/drivers/ieee1394/highlevel.c --- linux-2.4.21/drivers/ieee1394/highlevel.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/highlevel.c 2003-08-25 04:44:41.000000000 -0700 @@ -205,6 +205,29 @@ } +struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key) +{ + struct list_head *lh; + struct hl_host_info *hi; + struct hpsb_host *host = NULL; + + if (!hl) + return NULL; + + read_lock(&hl->host_info_lock); + list_for_each (lh, &hl->host_info_list) { + hi = list_entry(lh, struct hl_host_info, list); + if (hi->key == key) { + host = hi->host; + break; + } + } + read_unlock(&hl->host_info_lock); + + return host; +} + + void hpsb_register_highlevel(struct hpsb_highlevel *hl) { struct list_head *lh; diff -urN linux-2.4.21/drivers/ieee1394/highlevel.h linux-2.4.22/drivers/ieee1394/highlevel.h --- linux-2.4.21/drivers/ieee1394/highlevel.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/highlevel.h 2003-08-25 04:44:41.000000000 -0700 @@ -155,19 +155,28 @@ /* Retrieve a hostinfo pointer bound to this driver/host */ void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host); + /* Allocate a hostinfo pointer of data_size bound to this driver/host */ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, size_t data_size); + /* Free and remove the hostinfo pointer bound to this driver/host */ void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host); + /* Set an alternate lookup key for the hostinfo bound to this driver/host */ void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned long key); + /* Retrieve the alternate lookup key for the hostinfo bound to this driver/host */ unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host); -/* Retrive a hostinfo pointer bound to this driver using its alternate key */ + +/* Retrieve a hostinfo pointer bound to this driver using its alternate key */ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key); + /* Set the hostinfo pointer to something useful. Usually follows a call to * hpsb_create_hostinfo, where the size is 0. */ int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *data); +/* Retrieve hpsb_host using a highlevel handle and a key */ +struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key); + #endif /* IEEE1394_HIGHLEVEL_H */ diff -urN linux-2.4.21/drivers/ieee1394/hosts.c linux-2.4.22/drivers/ieee1394/hosts.c --- linux-2.4.21/drivers/ieee1394/hosts.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/hosts.c 2003-08-25 04:44:41.000000000 -0700 @@ -138,7 +138,10 @@ atomic_set(&h->generation, 0); - INIT_TQUEUE(&h->timeout_tq, (void (*)(void*))abort_timedouts, h); + init_timer(&h->timeout); + h->timeout.data = (unsigned long) h; + h->timeout.function = abort_timedouts; + h->timeout_interval = HZ / 20; // 50ms by default h->topology_map = h->csr.topology_map + 3; h->speed_map = (u8 *)(h->csr.speed_map + 2); diff -urN linux-2.4.21/drivers/ieee1394/hosts.h linux-2.4.22/drivers/ieee1394/hosts.h --- linux-2.4.21/drivers/ieee1394/hosts.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/hosts.h 2003-08-25 04:44:41.000000000 -0700 @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include "ieee1394_types.h" @@ -32,7 +32,8 @@ struct list_head pending_packets; spinlock_t pending_pkt_lock; - struct tq_struct timeout_tq; + struct timer_list timeout; + unsigned long timeout_interval; unsigned char iso_listen_count[64]; @@ -110,6 +111,7 @@ enum isoctl_cmd { /* rawiso API - see iso.h for the meanings of these commands + (they correspond exactly to the hpsb_iso_* API functions) * INIT = allocate resources * START = begin transmission/reception * STOP = halt transmission/reception @@ -131,6 +133,7 @@ RECV_STOP, RECV_RELEASE, RECV_SHUTDOWN, + RECV_FLUSH }; enum reset_types { diff -urN linux-2.4.21/drivers/ieee1394/ieee1394-ioctl.h linux-2.4.22/drivers/ieee1394/ieee1394-ioctl.h --- linux-2.4.21/drivers/ieee1394/ieee1394-ioctl.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ieee1394-ioctl.h 2003-08-25 04:44:41.000000000 -0700 @@ -100,6 +100,8 @@ _IOW ('#', 0x27, struct raw1394_iso_packets) #define RAW1394_IOC_ISO_XMIT_SYNC \ _IO ('#', 0x28) +#define RAW1394_IOC_ISO_RECV_FLUSH \ + _IO ('#', 0x29) #endif /* __IEEE1394_IOCTL_H */ diff -urN linux-2.4.21/drivers/ieee1394/ieee1394.h linux-2.4.22/drivers/ieee1394/ieee1394.h --- linux-2.4.21/drivers/ieee1394/ieee1394.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ieee1394.h 2003-08-25 04:44:41.000000000 -0700 @@ -46,18 +46,17 @@ #define ACKX_TIMEOUT (-4) -#define SPEED_100 0x00 -#define SPEED_200 0x01 -#define SPEED_400 0x02 -#define SPEED_800 0x03 -#define SPEED_1600 0x04 -#define SPEED_3200 0x05 +#define IEEE1394_SPEED_100 0x00 +#define IEEE1394_SPEED_200 0x01 +#define IEEE1394_SPEED_400 0x02 +#define IEEE1394_SPEED_800 0x03 +#define IEEE1394_SPEED_1600 0x04 +#define IEEE1394_SPEED_3200 0x05 /* The current highest tested speed supported by the subsystem */ -#define SPEED_MAX SPEED_800 +#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800 /* Maps speed values above to a string representation */ extern const char *hpsb_speedto_str[]; -extern const u8 hpsb_speedto_maxrec[]; #define SELFID_PWRCL_NO_POWER 0x0 diff -urN linux-2.4.21/drivers/ieee1394/ieee1394_core.c linux-2.4.22/drivers/ieee1394/ieee1394_core.c --- linux-2.4.21/drivers/ieee1394/ieee1394_core.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ieee1394_core.c 2003-08-25 04:44:41.000000000 -0700 @@ -41,7 +41,6 @@ #include "ieee1394_transactions.h" #include "csr.h" #include "nodemgr.h" -#include "ieee1394_hotplug.h" #include "dma.h" #include "iso.h" @@ -59,7 +58,6 @@ /* Some globals used */ const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; -const u8 hpsb_speedto_maxrec[] = { 0x7, 0x8, 0x9, 0x10, 0x11, 0x12 }; static void dump_packet(const char *text, quadlet_t *data, int size) { @@ -78,9 +76,12 @@ static void run_packet_complete(struct hpsb_packet *packet) { if (packet->complete_routine != NULL) { - packet->complete_routine(packet->complete_data); + void (*complete_routine)(void*) = packet->complete_routine; + void *complete_data = packet->complete_data; + packet->complete_routine = NULL; packet->complete_data = NULL; + complete_routine(complete_data); } return; } @@ -285,7 +286,7 @@ for (i = 0; i < (nodecount * 64); i += 64) { for (j = 0; j < nodecount; j++) { - map[i+j] = SPEED_MAX; + map[i+j] = IEEE1394_SPEED_MAX; } } @@ -380,8 +381,10 @@ } else { HPSB_NOTICE("Stopping out-of-control reset loop"); HPSB_NOTICE("Warning - topology map and speed map will not be valid"); + host->reset_retries = 0; } } else { + host->reset_retries = 0; build_speed_map(host, host->node_count); } @@ -436,7 +439,7 @@ spin_unlock_irqrestore(&host->pending_pkt_lock, flags); up(&packet->state_change); - schedule_task(&host->timeout_tq); + mod_timer(&host->timeout, jiffies + host->timeout_interval); } /** @@ -454,7 +457,7 @@ struct hpsb_packet *packet; int retval = 0; - if(rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 || + if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 || (rootid == -1 && gapcnt == -1)) { HPSB_DEBUG("Invalid Parameter: rootid = %d gapcnt = %d", rootid, gapcnt); @@ -466,22 +469,21 @@ return -ENOMEM; packet->host = host; - packet->header_size = 16; + packet->header_size = 8; packet->data_size = 0; packet->expect_response = 0; packet->no_waiter = 0; packet->type = hpsb_raw; packet->header[0] = 0; - if(rootid != -1) + if (rootid != -1) packet->header[0] |= rootid << 24 | 1 << 23; - if(gapcnt != -1) + if (gapcnt != -1) packet->header[0] |= gapcnt << 16 | 1 << 22; packet->header[1] = ~packet->header[0]; packet->generation = get_hpsb_generation(host); - HPSB_DEBUG("Sending PHY configuration packet (I hope)..."); if (!hpsb_send_packet(packet)) { retval = -EINVAL; goto fail; @@ -936,7 +938,7 @@ { unsigned long flags; struct hpsb_packet *packet; - struct list_head *lh; + struct list_head *lh, *tlh; LIST_HEAD(llist); host->driver->devctl(host, CANCEL_REQUESTS, 0); @@ -946,8 +948,9 @@ INIT_LIST_HEAD(&host->pending_packets); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); - list_for_each(lh, &llist) { + list_for_each_safe(lh, tlh, &llist) { packet = list_entry(lh, struct hpsb_packet, list); + list_del(&packet->list); packet->state = hpsb_complete; packet->ack_code = ACKX_ABORTED; up(&packet->state_change); @@ -955,28 +958,23 @@ } } -void abort_timedouts(struct hpsb_host *host) +void abort_timedouts(unsigned long __opaque) { + struct hpsb_host *host = (struct hpsb_host *)__opaque; unsigned long flags; struct hpsb_packet *packet; unsigned long expire; - struct list_head *lh, *next; + struct list_head *lh, *tlh; LIST_HEAD(expiredlist); spin_lock_irqsave(&host->csr.lock, flags); - expire = (host->csr.split_timeout_hi * 8000 - + (host->csr.split_timeout_lo >> 19)) - * HZ / 8000; - /* Avoid shortening of timeout due to rounding errors: */ - expire++; + expire = host->csr.expire; spin_unlock_irqrestore(&host->csr.lock, flags); - spin_lock_irqsave(&host->pending_pkt_lock, flags); - for (lh = host->pending_packets.next; lh != &host->pending_packets; lh = next) { + list_for_each_safe(lh, tlh, &host->pending_packets) { packet = list_entry(lh, struct hpsb_packet, list); - next = lh->next; if (time_before(packet->sendtime + expire, jiffies)) { list_del(&packet->list); list_add(&packet->list, &expiredlist); @@ -984,12 +982,13 @@ } if (!list_empty(&host->pending_packets)) - schedule_task(&host->timeout_tq); + mod_timer(&host->timeout, jiffies + host->timeout_interval); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); - list_for_each(lh, &expiredlist) { + list_for_each_safe(lh, tlh, &expiredlist) { packet = list_entry(lh, struct hpsb_packet, list); + list_del(&packet->list); packet->state = hpsb_complete; packet->ack_code = ACKX_TIMEOUT; up(&packet->state_change); @@ -1027,12 +1026,12 @@ { int retval; - if( (blocknum < 0) || (blocknum > 15) ) + if ( (blocknum < 0) || (blocknum > 15) ) return -EINVAL; write_lock(&ieee1394_chardevs_lock); - if(ieee1394_chardevs[blocknum].file_ops == NULL) { + if (ieee1394_chardevs[blocknum].file_ops == NULL) { /* grab the minor block */ ieee1394_chardevs[blocknum].file_ops = file_ops; ieee1394_chardevs[blocknum].module = module; @@ -1051,12 +1050,12 @@ /* release a block of minor numbers */ void ieee1394_unregister_chardev(int blocknum) { - if( (blocknum < 0) || (blocknum > 15) ) + if ( (blocknum < 0) || (blocknum > 15) ) return; write_lock(&ieee1394_chardevs_lock); - if(ieee1394_chardevs[blocknum].file_ops) { + if (ieee1394_chardevs[blocknum].file_ops) { ieee1394_chardevs[blocknum].file_ops = NULL; ieee1394_chardevs[blocknum].module = NULL; } @@ -1093,7 +1092,7 @@ goto out; /* don't need try_inc_mod_count if the driver is non-modular */ - if(*module && (try_inc_mod_count(*module) == 0)) + if (*module && (try_inc_mod_count(*module) == 0)) goto out; /* success! */ @@ -1137,7 +1136,7 @@ /* look up the driver */ - if(ieee1394_get_chardev(blocknum, &module, &file_ops) == 0) + if (ieee1394_get_chardev(blocknum, &module, &file_ops) == 0) return -ENODEV; /* redirect all subsequent requests to the driver's @@ -1150,7 +1149,7 @@ /* follow through with the open() */ retval = file_ops->open(inode, file); - if(retval == 0) { + if (retval == 0) { /* If the open() succeeded, then ieee1394 will be left with an extra module reference, so we discard it here. @@ -1162,7 +1161,7 @@ dropped by the VFS when the file is released. */ - if(THIS_MODULE) + if (THIS_MODULE) __MOD_DEC_USE_COUNT((struct module*) THIS_MODULE); /* note that if ieee1394 is compiled into the kernel, @@ -1175,7 +1174,7 @@ extra reference we gave to the task-specific driver */ - if(module) + if (module) __MOD_DEC_USE_COUNT(module); /* point the file's f_ops back to ieee1394. The VFS will then @@ -1206,7 +1205,7 @@ #ifdef CONFIG_PROC_FS /* Must be done before we start everything else, since the drivers * may use it. */ - ieee1394_procfs_entry = proc_mkdir( "ieee1394", proc_bus); + ieee1394_procfs_entry = proc_mkdir("ieee1394", proc_bus); if (ieee1394_procfs_entry == NULL) { HPSB_ERR("unable to create /proc/bus/ieee1394\n"); unregister_chrdev(IEEE1394_MAJOR, "ieee1394"); @@ -1256,7 +1255,6 @@ /** ieee1394_core.c **/ EXPORT_SYMBOL(hpsb_speedto_str); -EXPORT_SYMBOL(hpsb_speedto_maxrec); EXPORT_SYMBOL(hpsb_set_packet_complete_task); EXPORT_SYMBOL(alloc_hpsb_packet); EXPORT_SYMBOL(free_hpsb_packet); @@ -1297,6 +1295,7 @@ EXPORT_SYMBOL(hpsb_listen_channel); EXPORT_SYMBOL(hpsb_unlisten_channel); EXPORT_SYMBOL(hpsb_get_hostinfo); +EXPORT_SYMBOL(hpsb_get_host_bykey); EXPORT_SYMBOL(hpsb_create_hostinfo); EXPORT_SYMBOL(hpsb_destroy_hostinfo); EXPORT_SYMBOL(hpsb_set_hostinfo_key); @@ -1354,3 +1353,4 @@ EXPORT_SYMBOL(hpsb_iso_packet_sent); EXPORT_SYMBOL(hpsb_iso_packet_received); EXPORT_SYMBOL(hpsb_iso_wake); +EXPORT_SYMBOL(hpsb_iso_recv_flush); diff -urN linux-2.4.21/drivers/ieee1394/ieee1394_core.h linux-2.4.22/drivers/ieee1394/ieee1394_core.h --- linux-2.4.21/drivers/ieee1394/ieee1394_core.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ieee1394_core.h 2003-08-25 04:44:41.000000000 -0700 @@ -34,7 +34,7 @@ } __attribute__((packed)) state; /* These are core internal. */ - char tlabel; + signed char tlabel; char ack_code; char tcode; @@ -88,7 +88,7 @@ return list_entry(l, struct hpsb_packet, driver_list); } -void abort_timedouts(struct hpsb_host *host); +void abort_timedouts(unsigned long __opaque); void abort_requests(struct hpsb_host *host); struct hpsb_packet *alloc_hpsb_packet(size_t data_size); diff -urN linux-2.4.21/drivers/ieee1394/ieee1394_hotplug.h linux-2.4.22/drivers/ieee1394/ieee1394_hotplug.h --- linux-2.4.21/drivers/ieee1394/ieee1394_hotplug.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ieee1394_hotplug.h 2003-08-25 04:44:41.000000000 -0700 @@ -1,8 +1,7 @@ #ifndef _IEEE1394_HOTPLUG_H #define _IEEE1394_HOTPLUG_H -#include "ieee1394_core.h" -#include "nodemgr.h" +#include #define IEEE1394_MATCH_VENDOR_ID 0x0001 #define IEEE1394_MATCH_MODEL_ID 0x0002 @@ -26,57 +25,4 @@ void *driver_data; }; -struct hpsb_protocol_driver { - /* The name of the driver, e.g. SBP2 or IP1394 */ - const char *name; - - /* - * The device id table describing the protocols and/or devices - * supported by this driver. This is used by the nodemgr to - * decide if a driver could support a given node, but the - * probe function below can implement further protocol - * dependent or vendor dependent checking. - */ - struct ieee1394_device_id *id_table; - - /* - * The probe function is called when a device is added to the - * bus and the nodemgr finds a matching entry in the drivers - * device id table or when registering this driver and a - * previously unhandled device can be handled. The driver may - * decline to handle the device based on further investigation - * of the device (or whatever reason) in which case a negative - * error code should be returned, otherwise 0 should be - * returned. The driver may use the driver_data field in the - * unit directory to store per device driver specific data. - */ - int (*probe)(struct unit_directory *ud); - - /* - * The disconnect function is called when a device is removed - * from the bus or if it wasn't possible to read the guid - * after the last bus reset. - */ - void (*disconnect)(struct unit_directory *ud); - - /* - * The update function is called when the node has just - * survived a bus reset, i.e. it is still present on the bus. - * However, it may be necessary to reestablish the connection - * or login into the node again, depending on the protocol. - */ - void (*update)(struct unit_directory *ud); - - /* Driver in list of all registered drivers */ - struct list_head list; - - /* The list of unit directories managed by this driver */ - struct list_head unit_directories; -}; - -int hpsb_register_protocol(struct hpsb_protocol_driver *driver); -void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver); - -void hpsb_release_unit_directory(struct unit_directory *ud); - #endif /* _IEEE1394_HOTPLUG_H */ diff -urN linux-2.4.21/drivers/ieee1394/ieee1394_transactions.c linux-2.4.22/drivers/ieee1394/ieee1394_transactions.c --- linux-2.4.21/drivers/ieee1394/ieee1394_transactions.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ieee1394_transactions.c 2003-08-25 04:44:41.000000000 -0700 @@ -95,7 +95,7 @@ packet->data_size = 0; packet->expect_response = 0; packet->type = hpsb_raw; /* No CRC added */ - packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */ + packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */ } static void fill_async_stream_packet(struct hpsb_packet *packet, int length, @@ -147,6 +147,8 @@ spin_lock_irqsave(&tp->lock, flags); packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next); + if (packet->tlabel > 63) + packet->tlabel = find_first_zero_bit(tp->pool, 64); tp->next = (packet->tlabel + 1) % 64; /* Should _never_ happen */ BUG_ON(test_and_set_bit(packet->tlabel, tp->pool)); @@ -573,10 +575,6 @@ quadlet_t *buffer, size_t length, u32 specifier_id, unsigned int version) { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - int i; -#endif - struct hpsb_packet *packet; int retval = 0; u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8; @@ -604,14 +602,6 @@ memcpy(&(packet->data[2]), buffer, length - 4); -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG("GASP: packet->header_size = %d", packet->header_size); - HPSB_DEBUG("GASP: packet->data_size = %d", packet->data_size); - - for(i=0; i<(packet->data_size/4); i++) - HPSB_DEBUG("GASP: data[%d]: 0x%08x", i*4, be32_to_cpu(packet->data[i])); -#endif - packet->generation = generation; packet->no_waiter = 1; diff -urN linux-2.4.21/drivers/ieee1394/ieee1394_types.h linux-2.4.22/drivers/ieee1394/ieee1394_types.h --- linux-2.4.21/drivers/ieee1394/ieee1394_types.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ieee1394_types.h 2003-08-25 04:44:41.000000000 -0700 @@ -19,6 +19,15 @@ #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif +#ifndef BITS_TO_LONGS /* < 2.4.21-pre6 */ +#define BITS_TO_LONGS(bits) \ + (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) +#define DECLARE_BITMAP(name,bits) \ + unsigned long name[BITS_TO_LONGS(bits)] +#define CLEAR_BITMAP(name,bits) \ + memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long)) +#endif + /* Transaction Label handling */ struct hpsb_tlabel_pool { @@ -36,7 +45,7 @@ (_tp)->next = 0; \ (_tp)->allocations = 0; \ sema_init(&(_tp)->count, 63); \ -} while(0) +} while (0) typedef u32 quadlet_t; @@ -57,8 +66,9 @@ #define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK) /* Can be used to consistently print a node/bus ID. */ -#define NODE_BUS_FMT "%02d:%04d" -#define NODE_BUS_ARGS(nodeid) NODEID_TO_NODE(nodeid), NODEID_TO_BUS(nodeid) +#define NODE_BUS_FMT "%d-%02d:%04d" +#define NODE_BUS_ARGS(__host, __nodeid) \ + __host->id, NODEID_TO_NODE(__nodeid), NODEID_TO_BUS(__nodeid) #define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args) diff -urN linux-2.4.21/drivers/ieee1394/iso.c linux-2.4.22/drivers/ieee1394/iso.c --- linux-2.4.21/drivers/ieee1394/iso.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/iso.c 2003-08-25 04:44:41.000000000 -0700 @@ -10,6 +10,7 @@ */ #include +#include #include "iso.h" void hpsb_iso_stop(struct hpsb_iso *iso) @@ -24,7 +25,7 @@ void hpsb_iso_shutdown(struct hpsb_iso *iso) { - if(iso->flags & HPSB_ISO_DRIVER_INIT) { + if (iso->flags & HPSB_ISO_DRIVER_INIT) { hpsb_iso_stop(iso); iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ? XMIT_SHUTDOWN : RECV_SHUTDOWN, 0); @@ -32,7 +33,6 @@ } dma_region_free(&iso->data_buf); - kfree(iso->infos); kfree(iso); } @@ -47,7 +47,7 @@ int dma_direction; /* make sure driver supports the ISO API */ - if(!host->driver->isoctl) { + if (!host->driver->isoctl) { printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n", host->driver->name); return NULL; @@ -55,29 +55,26 @@ /* sanitize parameters */ - if(buf_packets < 2) + if (buf_packets < 2) buf_packets = 2; - if(irq_interval < 1 || irq_interval > buf_packets / 2) + if (irq_interval < 1 || irq_interval > buf_packets / 2) irq_interval = buf_packets / 2; - if(channel < -1 || channel >= 64) + if (channel < -1 || channel >= 64) return NULL; /* channel = -1 is OK for multi-channel recv but not for xmit */ - if(type == HPSB_ISO_XMIT && channel < 0) + if (type == HPSB_ISO_XMIT && channel < 0) return NULL; /* allocate and write the struct hpsb_iso */ - iso = kmalloc(sizeof(*iso), SLAB_KERNEL); - if(!iso) + iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL); + if (!iso) return NULL; - /* allocate ringbuffer of packet descriptors */ - iso->infos = kmalloc(buf_packets * sizeof(struct hpsb_iso_packet_info), SLAB_KERNEL); - if(!iso->infos) - return NULL; + iso->infos = (struct hpsb_iso_packet_info *)(iso + 1); iso->type = type; iso->host = host; @@ -93,7 +90,7 @@ iso->first_packet = 0; spin_lock_init(&iso->lock); - if(iso->type == HPSB_ISO_XMIT) { + if (iso->type == HPSB_ISO_XMIT) { iso->n_ready_packets = iso->buf_packets; dma_direction = PCI_DMA_TODEVICE; } else { @@ -106,7 +103,7 @@ iso->prebuffer = 0; /* allocate the packet buffer */ - if(dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) + if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) goto err; return iso; @@ -140,13 +137,13 @@ struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT, data_buf_size, buf_packets, channel, irq_interval, callback); - if(!iso) + if (!iso) return NULL; iso->speed = speed; /* tell the driver to start working */ - if(host->driver->isoctl(iso, XMIT_INIT, 0)) + if (host->driver->isoctl(iso, XMIT_INIT, 0)) goto err; iso->flags |= HPSB_ISO_DRIVER_INIT; @@ -167,11 +164,11 @@ struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV, data_buf_size, buf_packets, channel, irq_interval, callback); - if(!iso) + if (!iso) return NULL; /* tell the driver to start working */ - if(host->driver->isoctl(iso, RECV_INIT, 0)) + if (host->driver->isoctl(iso, RECV_INIT, 0)) goto err; iso->flags |= HPSB_ISO_DRIVER_INIT; @@ -184,29 +181,36 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel) { - if(iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) + if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) return -EINVAL; return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel); } int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) { - if(iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) + if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) return -EINVAL; return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); } int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) { - if(iso->type != HPSB_ISO_RECV || iso->channel != -1) + if (iso->type != HPSB_ISO_RECV || iso->channel != -1) return -EINVAL; return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask); } +int hpsb_iso_recv_flush(struct hpsb_iso *iso) +{ + if (iso->type != HPSB_ISO_RECV) + return -EINVAL; + return iso->host->driver->isoctl(iso, RECV_FLUSH, 0); +} + static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle) { int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle); - if(retval) + if (retval) return retval; iso->flags |= HPSB_ISO_DRIVER_STARTED; @@ -215,25 +219,25 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer) { - if(iso->type != HPSB_ISO_XMIT) + if (iso->type != HPSB_ISO_XMIT) return -1; - if(iso->flags & HPSB_ISO_DRIVER_STARTED) + if (iso->flags & HPSB_ISO_DRIVER_STARTED) return 0; - if(cycle < -1) + if (cycle < -1) cycle = -1; - else if(cycle >= 8000) + else if (cycle >= 8000) cycle %= 8000; iso->xmit_cycle = cycle; - if(prebuffer < 0) + if (prebuffer < 0) prebuffer = iso->buf_packets; - else if(prebuffer == 0) + else if (prebuffer == 0) prebuffer = 1; - if(prebuffer > iso->buf_packets) + if (prebuffer > iso->buf_packets) prebuffer = iso->buf_packets; iso->prebuffer = prebuffer; @@ -250,20 +254,20 @@ int retval = 0; int isoctl_args[3]; - if(iso->type != HPSB_ISO_RECV) + if (iso->type != HPSB_ISO_RECV) return -1; - if(iso->flags & HPSB_ISO_DRIVER_STARTED) + if (iso->flags & HPSB_ISO_DRIVER_STARTED) return 0; - if(cycle < -1) + if (cycle < -1) cycle = -1; - else if(cycle >= 8000) + else if (cycle >= 8000) cycle %= 8000; isoctl_args[0] = cycle; - if(tag_mask < 0) + if (tag_mask < 0) /* match all tags */ tag_mask = 0xF; isoctl_args[1] = tag_mask; @@ -271,7 +275,7 @@ isoctl_args[2] = sync; retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]); - if(retval) + if (retval) return retval; iso->flags |= HPSB_ISO_DRIVER_STARTED; @@ -285,15 +289,15 @@ unsigned int offset, unsigned short len, unsigned int *out_offset, unsigned short *out_len) { - if(offset >= iso->buf_size) + if (offset >= iso->buf_size) return -EFAULT; /* make sure the packet does not go beyond the end of the buffer */ - if(offset + len > iso->buf_size) + if (offset + len > iso->buf_size) return -EFAULT; /* check for wrap-around */ - if(offset + len < offset) + if (offset + len < offset) return -EFAULT; /* now we can trust 'offset' and 'length' */ @@ -310,18 +314,18 @@ unsigned long flags; int rv; - if(iso->type != HPSB_ISO_XMIT) + if (iso->type != HPSB_ISO_XMIT) return -EINVAL; /* is there space in the buffer? */ - if(iso->n_ready_packets <= 0) { + if (iso->n_ready_packets <= 0) { return -EBUSY; } info = &iso->infos[iso->first_packet]; /* check for bogus offset/length */ - if(hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len)) + if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len)) return -EFAULT; info->tag = tag; @@ -330,7 +334,7 @@ spin_lock_irqsave(&iso->lock, flags); rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info); - if(rv) + if (rv) goto out; /* increment cursors */ @@ -338,9 +342,9 @@ iso->xmit_cycle = (iso->xmit_cycle+1) % 8000; iso->n_ready_packets--; - if(iso->prebuffer != 0) { + if (iso->prebuffer != 0) { iso->prebuffer--; - if(iso->prebuffer <= 0) { + if (iso->prebuffer <= 0) { iso->prebuffer = 0; rv = do_iso_xmit_start(iso, iso->start_cycle); } @@ -353,7 +357,7 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso) { - if(iso->type != HPSB_ISO_XMIT) + if (iso->type != HPSB_ISO_XMIT) return -EINVAL; return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets); @@ -374,7 +378,7 @@ iso->n_ready_packets++; iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets; - if(iso->n_ready_packets == iso->buf_packets || error != 0) { + if (iso->n_ready_packets == iso->buf_packets || error != 0) { /* the buffer has run empty! */ atomic_inc(&iso->overflows); } @@ -388,7 +392,7 @@ unsigned long flags; spin_lock_irqsave(&iso->lock, flags); - if(iso->n_ready_packets == iso->buf_packets) { + if (iso->n_ready_packets == iso->buf_packets) { /* overflow! */ atomic_inc(&iso->overflows); } else { @@ -413,14 +417,14 @@ unsigned int i; int rv = 0; - if(iso->type != HPSB_ISO_RECV) + if (iso->type != HPSB_ISO_RECV) return -1; spin_lock_irqsave(&iso->lock, flags); - for(i = 0; i < n_packets; i++) { + for (i = 0; i < n_packets; i++) { rv = iso->host->driver->isoctl(iso, RECV_RELEASE, (unsigned long) &iso->infos[iso->first_packet]); - if(rv) + if (rv) break; iso->first_packet = (iso->first_packet+1) % iso->buf_packets; @@ -434,6 +438,6 @@ { wake_up_interruptible(&iso->waitq); - if(iso->callback) + if (iso->callback) iso->callback(iso); } diff -urN linux-2.4.21/drivers/ieee1394/iso.h linux-2.4.22/drivers/ieee1394/iso.h --- linux-2.4.21/drivers/ieee1394/iso.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/iso.h 2003-08-25 04:44:41.000000000 -0700 @@ -66,7 +66,7 @@ /* wait for buffer space */ wait_queue_head_t waitq; - int speed; /* SPEED_100, 200, or 400 */ + int speed; /* IEEE1394_SPEED_100, 200, or 400 */ int channel; /* -1 if multichannel */ /* greatest # of packets between interrupts - controls @@ -79,9 +79,6 @@ /* size of data_buf, in bytes (always a multiple of PAGE_SIZE) */ unsigned int buf_size; - /* ringbuffer of packet descriptors in regular kernel memory */ - struct hpsb_iso_packet_info *infos; - /* # of packets in the ringbuffer */ unsigned int buf_packets; @@ -118,6 +115,11 @@ /* cycle at which next packet will be transmitted, -1 if not known */ int xmit_cycle; + + /* ringbuffer of packet descriptors in regular kernel memory + * XXX Keep this last, since we use over-allocated memory from + * this entry to fill this field. */ + struct hpsb_iso_packet_info *infos; }; /* functions available to high-level drivers (e.g. raw1394) */ @@ -163,6 +165,10 @@ /* N packets have been read out of the buffer, re-use the buffer space */ int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets); +/* check for arrival of new packets immediately (even if irq_interval + has not yet been reached) */ +int hpsb_iso_recv_flush(struct hpsb_iso *iso); + /* returns # of packets ready to send or receive */ int hpsb_iso_n_ready(struct hpsb_iso *iso); diff -urN linux-2.4.21/drivers/ieee1394/nodemgr.c linux-2.4.22/drivers/ieee1394/nodemgr.c --- linux-2.4.21/drivers/ieee1394/nodemgr.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/nodemgr.c 2003-08-25 04:44:41.000000000 -0700 @@ -23,9 +23,9 @@ #include "ieee1394_types.h" #include "ieee1394.h" +#include "nodemgr.h" #include "hosts.h" #include "ieee1394_transactions.h" -#include "ieee1394_hotplug.h" #include "highlevel.h" #include "csr.h" #include "nodemgr.h" @@ -92,15 +92,26 @@ #ifdef CONFIG_PROC_FS -#define PUTF(fmt, args...) out += sprintf(out, fmt, ## args) +#define PUTF(fmt, args...) \ +do { \ + len += sprintf(page + len, fmt, ## args); \ + pos = begin + len; \ + if (pos < off) { \ + len = 0; \ + begin = pos; \ + } \ + if (pos > off + count) \ + goto done_proc; \ +} while (0) + static int raw1394_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct list_head *lh; struct node_entry *ne; - int len; - char *out = page; + off_t begin = 0, pos = 0; + int len = 0; if (down_interruptible(&nodemgr_serialize)) return -EINTR; @@ -114,7 +125,7 @@ continue; PUTF("Node[" NODE_BUS_FMT "] GUID[%016Lx]:\n", - NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid); + NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); /* Generic Node information */ PUTF(" Vendor ID: `%s' [0x%06x]\n", @@ -135,9 +146,9 @@ PUTF(" Nodes active : %d\n", ne->host->nodes_active); PUTF(" SelfIDs received: %d\n", ne->host->selfid_count); PUTF(" Irm ID : [" NODE_BUS_FMT "]\n", - NODE_BUS_ARGS(ne->host->irm_id)); + NODE_BUS_ARGS(ne->host, ne->host->irm_id)); PUTF(" BusMgr ID : [" NODE_BUS_FMT "]\n", - NODE_BUS_ARGS(ne->host->busmgr_id)); + NODE_BUS_ARGS(ne->host, ne->host->busmgr_id)); PUTF(" In Bus Reset : %s\n", ne->host->in_bus_reset ? "yes" : "no"); PUTF(" Root : %s\n", ne->host->is_root ? "yes" : "no"); PUTF(" Cycle Master : %s\n", ne->host->is_cycmst ? "yes" : "no"); @@ -180,18 +191,18 @@ } +done_proc: up(&nodemgr_serialize); - len = out - page; - len -= off; - if (len < count) { + *start = page + (off - begin); + len -= (off - begin); + if (len > count) + len = count; + else { *eof = 1; if (len <= 0) return 0; - } else - len = count; - - *start = page + off; + } return len; } @@ -371,10 +382,9 @@ nodemgr_process_config_rom (ne, busoptions); - HPSB_DEBUG("%s added: Node[" NODE_BUS_FMT "] GUID[%016Lx] [%s]", - (host->node_id == nodeid) ? "Host" : "Device", - NODE_BUS_ARGS(nodeid), (unsigned long long)guid, - ne->vendor_name ?: "Unknown"); + HPSB_DEBUG("%s added: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", + (host->node_id == nodeid) ? "Host" : "Node", + NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid); return ne; } @@ -522,8 +532,10 @@ ud->ne = ne; ud->address = address; - if (parent != NULL) + if (parent) { + ud->flags |= UNIT_DIRECTORY_LUN_DIRECTORY; ud->parent = parent; + } if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad)) @@ -600,35 +612,36 @@ break; case CONFIG_ROM_LOGICAL_UNIT_DIRECTORY: + ud->flags |= UNIT_DIRECTORY_HAS_LUN_DIRECTORY; ud_temp = nodemgr_process_unit_directory(ne, address + value * 4, ud); + if (ud_temp == NULL) + break; + /* inherit unspecified values */ - if (ud_temp != NULL) + if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID)) { - if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) && - !(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID)) - { - ud_temp->flags |= UNIT_DIRECTORY_VENDOR_ID; - ud_temp->vendor_id = ud->vendor_id; - } - if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && - !(ud_temp->flags & UNIT_DIRECTORY_MODEL_ID)) - { - ud_temp->flags |= UNIT_DIRECTORY_MODEL_ID; - ud_temp->model_id = ud->model_id; - } - if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) && - !(ud_temp->flags & UNIT_DIRECTORY_SPECIFIER_ID)) - { - ud_temp->flags |= UNIT_DIRECTORY_SPECIFIER_ID; - ud_temp->specifier_id = ud->specifier_id; - } - if ((ud->flags & UNIT_DIRECTORY_VERSION) && - !(ud_temp->flags & UNIT_DIRECTORY_VERSION)) - { - ud_temp->flags |= UNIT_DIRECTORY_VERSION; - ud_temp->version = ud->version; - } + ud_temp->flags |= UNIT_DIRECTORY_VENDOR_ID; + ud_temp->vendor_id = ud->vendor_id; + } + if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_MODEL_ID)) + { + ud_temp->flags |= UNIT_DIRECTORY_MODEL_ID; + ud_temp->model_id = ud->model_id; + } + if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_SPECIFIER_ID)) + { + ud_temp->flags |= UNIT_DIRECTORY_SPECIFIER_ID; + ud_temp->specifier_id = ud->specifier_id; + } + if ((ud->flags & UNIT_DIRECTORY_VERSION) && + !(ud_temp->flags & UNIT_DIRECTORY_VERSION)) + { + ud_temp->flags |= UNIT_DIRECTORY_VERSION; + ud_temp->version = ud->version; } break; @@ -1014,8 +1027,9 @@ struct unit_directory *ud; if (ne->nodeid != nodeid) { - HPSB_DEBUG("Node " NODE_BUS_FMT " changed to " NODE_BUS_FMT, - NODE_BUS_ARGS(ne->nodeid), NODE_BUS_ARGS(nodeid)); + HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, + NODE_BUS_ARGS(ne->host, ne->nodeid), + NODE_BUS_ARGS(ne->host, nodeid)); ne->nodeid = nodeid; } @@ -1046,7 +1060,7 @@ #ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT, - NODE_BUS_ARGS(nodeid)); + NODE_BUS_ARGS(host, nodeid)); #endif /* * Must retry a few times if config rom read returns zero (how long?). Will @@ -1059,7 +1073,7 @@ if (nodemgr_read_quadlet(host, nodeid, generation, addr, &buffer[0]) < 0) { HPSB_ERR("ConfigROM quadlet transaction error for node " - NODE_BUS_FMT, NODE_BUS_ARGS(nodeid)); + NODE_BUS_FMT, NODE_BUS_ARGS(host, nodeid)); return -1; } if (buffer[0]) @@ -1076,14 +1090,14 @@ if (header_size == 1) { HPSB_INFO("Node " NODE_BUS_FMT " has a minimal ROM. " "Vendor is %08x", - NODE_BUS_ARGS(nodeid), buffer[0] & 0x00ffffff); + NODE_BUS_ARGS(host, nodeid), buffer[0] & 0x00ffffff); return -1; } if (header_size < 4) { HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM " "format (%d quads), cannot parse", - NODE_BUS_ARGS(nodeid), header_size); + NODE_BUS_ARGS(host, nodeid), header_size); return -1; } @@ -1092,7 +1106,7 @@ addr, &buffer[i]) < 0) { HPSB_ERR("ConfigROM quadlet transaction " "error for node " NODE_BUS_FMT, - NODE_BUS_ARGS(nodeid)); + NODE_BUS_ARGS(host, nodeid)); return -1; } } @@ -1102,10 +1116,8 @@ static void nodemgr_remove_node(struct node_entry *ne) { - HPSB_DEBUG("%s removed: Node[" NODE_BUS_FMT "] GUID[%016Lx] [%s]", - (ne->host->node_id == ne->nodeid) ? "Host" : "Device", - NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid, - ne->vendor_name ?: "Unknown"); + HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", + NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); nodemgr_free_unit_directories(ne); list_del(&ne->list); @@ -1140,7 +1152,7 @@ * shouldn't be held responsible, so we'll allow it with a * warning. */ HPSB_WARN("Node " NODE_BUS_FMT " has invalid busID magic [0x%08x]", - NODE_BUS_ARGS(nodeid), buffer[1]); + NODE_BUS_ARGS(host, nodeid), buffer[1]); } guid = ((u64)buffer[3] << 32) | buffer[4]; @@ -1231,12 +1243,12 @@ /* If there is no bus manager then we should set the root node's * force_root bit to promote bus stability per the 1394 * spec. (8.4.2.6) */ - if (host->busmgr_id == 0x3f && host->node_count > 1) + if (host->busmgr_id == 0xffff && host->node_count > 1) { u16 root_node = host->node_count - 1; - struct node_entry *ne = hpsb_nodeid_get_entry(host, root_node); + struct node_entry *ne = find_entry_by_nodeid(host, root_node | LOCAL_BUS); - if (ne->busopt.cmc) + if (ne && ne->busopt.cmc) hpsb_send_phy_config(host, root_node, -1); else { HPSB_DEBUG("The root node is not cycle master capable; " @@ -1298,11 +1310,12 @@ * happens when we get a bus reset. */ while (!down_interruptible(&hi->reset_sem) && !down_interruptible(&nodemgr_serialize)) { - unsigned int generation; + unsigned int generation = 0; int i; - /* Pause for 1/4 second, to make sure things settle down. */ - for (i = HZ/4; i > 0; i-= HZ/16) { + /* Pause for 1/4 second in 1/16 second intervals, + * to make sure things settle down. */ + for (i = 0; i < 4 ; i++) { set_current_state(TASK_INTERRUPTIBLE); if (schedule_timeout(HZ/16)) goto caught_signal; @@ -1317,7 +1330,7 @@ /* If we get a reset before we are done waiting, then * start the the waiting over again */ while (!down_trylock(&hi->reset_sem)) - i = HZ/4; + i = 0; } if (!nodemgr_check_irm_capability(host, reset_cycles++)) { @@ -1453,7 +1466,7 @@ if (hi != NULL) { #ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG ("NodeMgr: Processing host reset for %s", host->driver->name); + HPSB_DEBUG ("NodeMgr: Processing host reset for %s", hi->daemon_name); #endif up(&hi->reset_sem); } else diff -urN linux-2.4.21/drivers/ieee1394/nodemgr.h linux-2.4.22/drivers/ieee1394/nodemgr.h --- linux-2.4.21/drivers/ieee1394/nodemgr.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/nodemgr.h 2003-08-25 04:44:41.000000000 -0700 @@ -20,6 +20,9 @@ #ifndef _IEEE1394_NODEMGR_H #define _IEEE1394_NODEMGR_H +#include "ieee1394_core.h" +#include "ieee1394_hotplug.h" + #define CONFIG_ROM_BUS_INFO_LENGTH(q) ((q) >> 24) #define CONFIG_ROM_BUS_CRC_LENGTH(q) (((q) >> 16) & 0xff) #define CONFIG_ROM_BUS_CRC(q) ((q) & 0xffff) @@ -77,12 +80,14 @@ u16 max_rec; /* Maximum packet size node can receive */ }; -#define UNIT_DIRECTORY_VENDOR_ID 0x01 -#define UNIT_DIRECTORY_MODEL_ID 0x02 -#define UNIT_DIRECTORY_SPECIFIER_ID 0x04 -#define UNIT_DIRECTORY_VERSION 0x08 -#define UNIT_DIRECTORY_VENDOR_TEXT 0x10 -#define UNIT_DIRECTORY_MODEL_TEXT 0x20 +#define UNIT_DIRECTORY_VENDOR_ID 0x01 +#define UNIT_DIRECTORY_MODEL_ID 0x02 +#define UNIT_DIRECTORY_SPECIFIER_ID 0x04 +#define UNIT_DIRECTORY_VERSION 0x08 +#define UNIT_DIRECTORY_VENDOR_TEXT 0x10 +#define UNIT_DIRECTORY_MODEL_TEXT 0x20 +#define UNIT_DIRECTORY_HAS_LUN_DIRECTORY 0x40 +#define UNIT_DIRECTORY_LUN_DIRECTORY 0x80 /* * A unit directory corresponds to a protocol supported by the @@ -152,6 +157,58 @@ quadlet_t quadlets[0]; }; +struct hpsb_protocol_driver { + /* The name of the driver, e.g. SBP2 or IP1394 */ + const char *name; + + /* + * The device id table describing the protocols and/or devices + * supported by this driver. This is used by the nodemgr to + * decide if a driver could support a given node, but the + * probe function below can implement further protocol + * dependent or vendor dependent checking. + */ + struct ieee1394_device_id *id_table; + + /* + * The probe function is called when a device is added to the + * bus and the nodemgr finds a matching entry in the drivers + * device id table or when registering this driver and a + * previously unhandled device can be handled. The driver may + * decline to handle the device based on further investigation + * of the device (or whatever reason) in which case a negative + * error code should be returned, otherwise 0 should be + * returned. The driver may use the driver_data field in the + * unit directory to store per device driver specific data. + */ + int (*probe)(struct unit_directory *ud); + + /* + * The disconnect function is called when a device is removed + * from the bus or if it wasn't possible to read the guid + * after the last bus reset. + */ + void (*disconnect)(struct unit_directory *ud); + + /* + * The update function is called when the node has just + * survived a bus reset, i.e. it is still present on the bus. + * However, it may be necessary to reestablish the connection + * or login into the node again, depending on the protocol. + */ + void (*update)(struct unit_directory *ud); + + /* Driver in list of all registered drivers */ + struct list_head list; + + /* The list of unit directories managed by this driver */ + struct list_head unit_directories; +}; + +int hpsb_register_protocol(struct hpsb_protocol_driver *driver); +void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver); +void hpsb_release_unit_directory(struct unit_directory *ud); + static inline int hpsb_node_entry_valid(struct node_entry *ne) { return ne->generation == get_hpsb_generation(ne->host); diff -urN linux-2.4.21/drivers/ieee1394/ohci1394.c linux-2.4.22/drivers/ieee1394/ohci1394.c --- linux-2.4.21/drivers/ieee1394/ohci1394.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/ohci1394.c 2003-08-25 04:44:41.000000000 -0700 @@ -97,6 +97,7 @@ #include #include #include +#include #include #include #include @@ -164,7 +165,7 @@ printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) static char version[] __devinitdata = - "$Rev: 896 $ Ben Collins "; + "$Rev: 1010 $ Ben Collins "; /* Module Parameters */ MODULE_PARM(phys_dma,"i"); @@ -428,7 +429,7 @@ d->buf_ind = 0; d->buf_offset = 0; - if(d->type == DMA_CTX_ISO) { + if (d->type == DMA_CTX_ISO) { /* Clear contextControl */ reg_write(ohci, d->ctrlClear, 0xffffffff); @@ -470,7 +471,7 @@ INIT_LIST_HEAD(&d->fifo_list); INIT_LIST_HEAD(&d->pending_list); - if(d->type == DMA_CTX_ISO) { + if (d->type == DMA_CTX_ISO) { /* enable interrupts */ reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << d->ctx); } @@ -490,8 +491,8 @@ DBGMSG(ohci->id,"Iso contexts reg: %08x implemented: %08x", reg, tmp); /* Count the number of contexts */ - for(i=0; i<32; i++) { - if(tmp & 1) ctx++; + for (i=0; i<32; i++) { + if (tmp & 1) ctx++; tmp >>= 1; } return ctx; @@ -502,6 +503,7 @@ /* Global initialization */ static void ohci_initialize(struct ti_ohci *ohci) { + char irq_buf[16]; quadlet_t buf; spin_lock_init(&ohci->phy_reg_lock); @@ -601,10 +603,15 @@ reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable); buf = reg_read(ohci, OHCI1394_Version); - PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%d] " +#ifndef __sparc__ + sprintf (irq_buf, "%d", ohci->dev->irq); +#else + sprintf (irq_buf, "%s", __irq_itoa(ohci->dev->irq)); +#endif + PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " "MMIO=[%lx-%lx] Max Packet=[%d]", ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), - ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq, + ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf, pci_resource_start(ohci->dev, 0), pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, ohci->max_packet_size); @@ -623,8 +630,10 @@ u32 cycleTimer; int idx = d->prg_ind; - DBGMSG(ohci->id, "Inserting packet for node %d, tlabel=%d, tcode=0x%x, speed=%d", - packet->node_id, packet->tlabel, packet->tcode, packet->speed_code); + DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT + ", tlabel=%d, tcode=0x%x, speed=%d", + NODE_BUS_ARGS(ohci->host, packet->node_id), packet->tlabel, + packet->tcode, packet->speed_code); d->prg_cpu[idx]->begin.address = 0; d->prg_cpu[idx]->begin.branchAddress = 0; @@ -648,8 +657,8 @@ if (packet->type == hpsb_raw) { d->prg_cpu[idx]->data[0] = cpu_to_le32(OHCI1394_TCODE_PHY<<4); - d->prg_cpu[idx]->data[1] = packet->header[0]; - d->prg_cpu[idx]->data[2] = packet->header[1]; + d->prg_cpu[idx]->data[1] = cpu_to_le32(packet->header[0]); + d->prg_cpu[idx]->data[2] = cpu_to_le32(packet->header[1]); } else { d->prg_cpu[idx]->data[0] = packet->speed_code<<16 | (packet->header[0] & 0xFFFF); @@ -808,8 +817,7 @@ } if (d->free_prgs == 0) - PRINT(KERN_INFO, ohci->id, - "Transmit DMA FIFO ctx=%d is full... waiting",d->ctx); + DBGMSG(ohci->id, "Transmit DMA FIFO ctx=%d is full... waiting", d->ctx); /* Is the context running ? (should be unless it is the first packet to be sent in this context) */ @@ -854,8 +862,8 @@ * case. I don't see anyone sending ISO packets from * interrupt context anyway... */ - if(ohci->it_legacy_context.ohci == NULL) { - if(in_interrupt()) { + if (ohci->it_legacy_context.ohci == NULL) { + if (in_interrupt()) { PRINT(KERN_ERR, ohci->id, "legacy IT context cannot be initialized during interrupt"); return 0; @@ -1081,7 +1089,7 @@ spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); DBGMSG(ohci->id, "Listening disabled on channel %d", arg); - if(ohci->ir_legacy_channels == 0) { + if (ohci->ir_legacy_channels == 0) { free_dma_rcv_ctx(&ohci->ir_legacy_context); DBGMSG(ohci->id, "ISO receive legacy context deactivated"); } @@ -1154,8 +1162,7 @@ u32 ContextMatch; }; -static void ohci_iso_recv_bufferfill_task(unsigned long data); -static void ohci_iso_recv_packetperbuf_task(unsigned long data); +static void ohci_iso_recv_task(unsigned long data); static void ohci_iso_recv_stop(struct hpsb_iso *iso); static void ohci_iso_recv_shutdown(struct hpsb_iso *iso); static int ohci_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync); @@ -1169,7 +1176,7 @@ int ret = -ENOMEM; recv = kmalloc(sizeof(*recv), SLAB_KERNEL); - if(!recv) + if (!recv) return -ENOMEM; iso->hostdata = recv; @@ -1181,7 +1188,7 @@ /* use buffer-fill mode, unless irq_interval is 1 (note: multichannel requires buffer-fill) */ - if(iso->irq_interval == 1 && iso->channel != -1) { + if (iso->irq_interval == 1 && iso->channel != -1) { recv->dma_mode = PACKET_PER_BUFFER_MODE; } else { recv->dma_mode = BUFFER_FILL_MODE; @@ -1189,12 +1196,12 @@ /* set nblocks, buf_stride, block_irq_interval */ - if(recv->dma_mode == BUFFER_FILL_MODE) { + if (recv->dma_mode == BUFFER_FILL_MODE) { recv->buf_stride = PAGE_SIZE; /* one block per page of data in the DMA buffer, minus the final guard page */ recv->nblocks = iso->buf_size/PAGE_SIZE - 1; - if(recv->nblocks < 3) { + if (recv->nblocks < 3) { DBGMSG(ohci->id, "ohci_iso_recv_init: DMA buffer too small"); goto err; } @@ -1202,9 +1209,9 @@ /* iso->irq_interval is in packets - translate that to blocks */ /* (err, sort of... 1 is always the safest value) */ recv->block_irq_interval = iso->irq_interval / recv->nblocks; - if(recv->block_irq_interval*4 > recv->nblocks) + if (recv->block_irq_interval*4 > recv->nblocks) recv->block_irq_interval = recv->nblocks/4; - if(recv->block_irq_interval < 1) + if (recv->block_irq_interval < 1) recv->block_irq_interval = 1; } else { @@ -1218,10 +1225,10 @@ max_packet_size = iso->buf_size / iso->buf_packets; - for(recv->buf_stride = 8; recv->buf_stride < max_packet_size; + for (recv->buf_stride = 8; recv->buf_stride < max_packet_size; recv->buf_stride *= 2); - if(recv->buf_stride*iso->buf_packets > iso->buf_size || + if (recv->buf_stride*iso->buf_packets > iso->buf_size || recv->buf_stride > PAGE_SIZE) { /* this shouldn't happen, but anyway... */ DBGMSG(ohci->id, "ohci_iso_recv_init: problem choosing a buffer stride"); @@ -1245,12 +1252,9 @@ ohci1394_init_iso_tasklet(&recv->task, iso->channel == -1 ? OHCI_ISO_MULTICHANNEL_RECEIVE : OHCI_ISO_RECEIVE, - recv->dma_mode == BUFFER_FILL_MODE ? - ohci_iso_recv_bufferfill_task : - ohci_iso_recv_packetperbuf_task, - (unsigned long) iso); + ohci_iso_recv_task, (unsigned long) iso); - if(ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) + if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) goto err; recv->task_active = 1; @@ -1262,7 +1266,7 @@ recv->CommandPtr = OHCI1394_IsoRcvCommandPtr + 32 * ctx; recv->ContextMatch = OHCI1394_IsoRcvContextMatch + 32 * ctx; - if(iso->channel == -1) { + if (iso->channel == -1) { /* clear multi-channel selection mask */ reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, 0xFFFFFFFF); reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, 0xFFFFFFFF); @@ -1300,7 +1304,7 @@ { struct ohci_iso_recv *recv = iso->hostdata; - if(recv->task_active) { + if (recv->task_active) { ohci_iso_recv_stop(iso); ohci1394_unregister_iso_tasklet(recv->ohci, &recv->task); recv->task_active = 0; @@ -1370,7 +1374,7 @@ struct ohci_iso_recv *recv = iso->hostdata; int reg, i; - if(channel < 32) { + if (channel < 32) { reg = listen ? OHCI1394_IRMultiChanMaskLoSet : OHCI1394_IRMultiChanMaskLoClear; i = channel; } else { @@ -1390,14 +1394,14 @@ struct ohci_iso_recv *recv = iso->hostdata; int i; - for(i = 0; i < 64; i++) { - if(mask & (1ULL << i)) { - if(i < 32) + for (i = 0; i < 64; i++) { + if (mask & (1ULL << i)) { + if (i < 32) reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoSet, (1 << i)); else reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiSet, (1 << (i-32))); } else { - if(i < 32) + if (i < 32) reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, (1 << i)); else reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, (1 << (i-32))); @@ -1420,7 +1424,7 @@ /* always keep ISO headers */ command = (1 << 30); - if(recv->dma_mode == BUFFER_FILL_MODE) + if (recv->dma_mode == BUFFER_FILL_MODE) command |= (1 << 31); reg_write(recv->ohci, recv->ContextControlSet, command); @@ -1428,7 +1432,7 @@ /* match on specified tags */ contextMatch = tag_mask << 28; - if(iso->channel == -1) { + if (iso->channel == -1) { /* enable multichannel reception */ reg_write(recv->ohci, recv->ContextControlSet, (1 << 28)); } else { @@ -1436,7 +1440,7 @@ contextMatch |= iso->channel; } - if(cycle != -1) { + if (cycle != -1) { u32 seconds; /* enable cycleMatch */ @@ -1457,7 +1461,7 @@ contextMatch |= cycle << 12; } - if(sync != -1) { + if (sync != -1) { /* set sync flag on first DMA descriptor */ struct dma_cmd *cmd = &recv->block[recv->block_dma]; cmd->control |= DMA_CTL_WAIT; @@ -1489,7 +1493,7 @@ reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer); /* check RUN */ - if(!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) { + if (!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) { PRINT(KERN_ERR, recv->ohci->id, "Error starting IR DMA (ContextControl 0x%08x)\n", reg_read(recv->ohci, recv->ContextControlSet)); @@ -1514,6 +1518,7 @@ so disable branch and enable interrupt */ next->branchAddress = 0; next->control |= cpu_to_le32(3 << 20); + next->status = cpu_to_le32(recv->buf_stride); /* link prev to next */ prev->branchAddress = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog, @@ -1521,7 +1526,7 @@ | 1); /* Z=1 */ /* disable interrupt on previous DMA descriptor, except at intervals */ - if((prev_i % recv->block_irq_interval) == 0) { + if ((prev_i % recv->block_irq_interval) == 0) { prev->control |= cpu_to_le32(3 << 20); /* enable interrupt */ } else { prev->control &= cpu_to_le32(~(3<<20)); /* disable interrupt */ @@ -1541,7 +1546,7 @@ len = info->len; /* add the wasted space for padding to 4 bytes */ - if(len % 4) + if (len % 4) len += 4 - (len % 4); /* add 8 bytes for the OHCI DMA data format overhead */ @@ -1550,7 +1555,7 @@ recv->released_bytes += len; /* have we released enough memory for one block? */ - while(recv->released_bytes > recv->buf_stride) { + while (recv->released_bytes > recv->buf_stride) { ohci_iso_recv_release_block(recv, recv->block_reader); recv->block_reader = (recv->block_reader + 1) % recv->nblocks; recv->released_bytes -= recv->buf_stride; @@ -1560,7 +1565,7 @@ static inline void ohci_iso_recv_release(struct hpsb_iso *iso, struct hpsb_iso_packet_info *info) { struct ohci_iso_recv *recv = iso->hostdata; - if(recv->dma_mode == BUFFER_FILL_MODE) { + if (recv->dma_mode == BUFFER_FILL_MODE) { ohci_iso_recv_bufferfill_release(recv, info); } else { ohci_iso_recv_release_block(recv, info - iso->infos); @@ -1573,7 +1578,7 @@ int wake = 0; int runaway = 0; - while(1) { + while (1) { /* we expect the next parsable packet to begin at recv->dma_offset */ /* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */ @@ -1586,7 +1591,7 @@ unsigned int this_block = recv->dma_offset/recv->buf_stride; /* don't loop indefinitely */ - if(runaway++ > 100000) { + if (runaway++ > 100000) { atomic_inc(&iso->overflows); PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - Runaway during buffer parsing!\n"); @@ -1594,7 +1599,7 @@ } /* stop parsing once we arrive at block_dma (i.e. don't get ahead of DMA) */ - if(this_block == recv->block_dma) + if (this_block == recv->block_dma) break; wake = 1; @@ -1606,7 +1611,7 @@ len = p[recv->dma_offset+2] | (p[recv->dma_offset+3] << 8); - if(len > 4096) { + if (len > 4096) { PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - bogus 'len' value %u\n", len); } @@ -1619,7 +1624,7 @@ recv->dma_offset += 4; /* check for wrap-around */ - if(recv->dma_offset >= recv->buf_stride*recv->nblocks) { + if (recv->dma_offset >= recv->buf_stride*recv->nblocks) { recv->dma_offset -= recv->buf_stride*recv->nblocks; } @@ -1630,12 +1635,12 @@ recv->dma_offset += len; /* payload is padded to 4 bytes */ - if(len % 4) { + if (len % 4) { recv->dma_offset += 4 - (len%4); } /* check for wrap-around */ - if(recv->dma_offset >= recv->buf_stride*recv->nblocks) { + if (recv->dma_offset >= recv->buf_stride*recv->nblocks) { /* uh oh, the packet data wraps from the last to the first DMA block - make the packet contiguous by copying its "tail" into the @@ -1644,7 +1649,7 @@ int guard_off = recv->buf_stride*recv->nblocks; int tail_len = len - (guard_off - offset); - if(tail_len > 0 && tail_len < recv->buf_stride) { + if (tail_len > 0 && tail_len < recv->buf_stride) { memcpy(iso->data_buf.kvirt + guard_off, iso->data_buf.kvirt, tail_len); @@ -1661,29 +1666,25 @@ recv->dma_offset += 4; /* check for wrap-around */ - if(recv->dma_offset >= recv->buf_stride*recv->nblocks) { + if (recv->dma_offset >= recv->buf_stride*recv->nblocks) { recv->dma_offset -= recv->buf_stride*recv->nblocks; } hpsb_iso_packet_received(iso, offset, len, cycle, channel, tag, sy); } - if(wake) + if (wake) hpsb_iso_wake(iso); } -static void ohci_iso_recv_bufferfill_task(unsigned long data) +static void ohci_iso_recv_bufferfill_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv) { - struct hpsb_iso *iso = (struct hpsb_iso*) data; - struct ohci_iso_recv *recv = iso->hostdata; - int loop; /* loop over all blocks */ - for(loop = 0; loop < recv->nblocks; loop++) { + for (loop = 0; loop < recv->nblocks; loop++) { /* check block_dma to see if it's done */ - struct dma_cmd *im = &recv->block[recv->block_dma]; /* check the DMA descriptor for new writes to xferStatus */ @@ -1694,18 +1695,18 @@ unsigned char event = xferstatus & 0x1F; - if(!event) { + if (!event) { /* nothing has happened to this block yet */ break; } - if(event != 0x11) { + if (event != 0x11) { atomic_inc(&iso->overflows); PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - OHCI error code 0x%02x\n", event); } - if(rescount != 0) { + if (rescount != 0) { /* the card is still writing to this block; we can't touch it until it's done */ break; @@ -1722,7 +1723,7 @@ /* advance block_dma */ recv->block_dma = (recv->block_dma + 1) % recv->nblocks; - if((recv->block_dma+1) % recv->nblocks == recv->block_reader) { + if ((recv->block_dma+1) % recv->nblocks == recv->block_reader) { atomic_inc(&iso->overflows); DBGMSG(recv->ohci->id, "ISO reception overflow - " "ran out of DMA blocks"); @@ -1733,15 +1734,13 @@ ohci_iso_recv_bufferfill_parse(iso, recv); } -static void ohci_iso_recv_packetperbuf_task(unsigned long data) +static void ohci_iso_recv_packetperbuf_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv) { - struct hpsb_iso *iso = (struct hpsb_iso*) data; - struct ohci_iso_recv *recv = iso->hostdata; int count; int wake = 0; /* loop over the entire buffer */ - for(count = 0; count < recv->nblocks; count++) { + for (count = 0; count < recv->nblocks; count++) { u32 packet_len = 0; /* pointer to the DMA descriptor */ @@ -1753,21 +1752,21 @@ unsigned char event = xferstatus & 0x1F; - if(!event) { + if (!event) { /* this packet hasn't come in yet; we are done for now */ goto out; } - if(event == 0x11) { + if (event == 0x11) { /* packet received successfully! */ /* rescount is the number of bytes *remaining* in the packet buffer, after the packet was written */ packet_len = recv->buf_stride - rescount; - } else if(event == 0x02) { + } else if (event == 0x02) { PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - packet too long for buffer\n"); - } else if(event) { + } else if (event) { PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - OHCI error code 0x%02x\n", event); } @@ -1806,10 +1805,20 @@ } out: - if(wake) + if (wake) hpsb_iso_wake(iso); } +static void ohci_iso_recv_task(unsigned long data) +{ + struct hpsb_iso *iso = (struct hpsb_iso*) data; + struct ohci_iso_recv *recv = iso->hostdata; + + if (recv->dma_mode == BUFFER_FILL_MODE) + ohci_iso_recv_bufferfill_task(iso, recv); + else + ohci_iso_recv_packetperbuf_task(iso, recv); +} /*********************************** * rawiso ISO transmission * @@ -1850,7 +1859,7 @@ int ret = -ENOMEM; xmit = kmalloc(sizeof(*xmit), SLAB_KERNEL); - if(!xmit) + if (!xmit) return -ENOMEM; iso->hostdata = xmit; @@ -1861,13 +1870,13 @@ prog_size = sizeof(struct iso_xmit_cmd) * iso->buf_packets; - if(dma_prog_region_alloc(&xmit->prog, prog_size, xmit->ohci->dev)) + if (dma_prog_region_alloc(&xmit->prog, prog_size, xmit->ohci->dev)) goto err; ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT, ohci_iso_xmit_task, (unsigned long) iso); - if(ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) + if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) goto err; xmit->task_active = 1; @@ -1893,7 +1902,7 @@ reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << xmit->task.context); /* halt DMA */ - if(ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) { + if (ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) { /* XXX the DMA context will lock up if you try to send too much data! */ PRINT(KERN_ERR, xmit->ohci->id, "you probably exceeded the OHCI card's bandwidth limit - " @@ -1905,7 +1914,7 @@ { struct ohci_iso_xmit *xmit = iso->hostdata; - if(xmit->task_active) { + if (xmit->task_active) { ohci_iso_xmit_stop(iso); ohci1394_unregister_iso_tasklet(xmit->ohci, &xmit->task); xmit->task_active = 0; @@ -1924,7 +1933,7 @@ int count; /* check the whole buffer if necessary, starting at pkt_dma */ - for(count = 0; count < iso->buf_packets; count++) { + for (count = 0; count < iso->buf_packets; count++) { int cycle; /* DMA descriptor */ @@ -1934,12 +1943,12 @@ u16 xferstatus = le32_to_cpu(cmd->output_last.status) >> 16; u8 event = xferstatus & 0x1F; - if(!event) { + if (!event) { /* packet hasn't been sent yet; we are done for now */ break; } - if(event != 0x11) + if (event != 0x11) PRINT(KERN_ERR, xmit->ohci->id, "IT DMA error - OHCI error code 0x%02x\n", event); @@ -1956,7 +1965,7 @@ cmd->output_last.status = 0; } - if(wake) + if (wake) hpsb_iso_wake(iso); } @@ -1973,7 +1982,7 @@ /* check that the packet doesn't cross a page boundary (we could allow this if we added OUTPUT_MORE descriptor support) */ - if(cross_bound(info->offset, info->len)) { + if (cross_bound(info->offset, info->len)) { PRINT(KERN_ERR, xmit->ohci->id, "rawiso xmit: packet %u crosses a page boundary", iso->first_packet); @@ -2036,7 +2045,7 @@ dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3); /* disable interrupt, unless required by the IRQ interval */ - if(prev_i % iso->irq_interval) { + if (prev_i % iso->irq_interval) { prev->output_last.control &= cpu_to_le32(~(3 << 20)); /* no interrupt */ } else { prev->output_last.control |= cpu_to_le32(3 << 20); /* enable interrupt */ @@ -2068,7 +2077,7 @@ dma_prog_region_offset_to_bus(&xmit->prog, iso->pkt_dma * sizeof(struct iso_xmit_cmd)) | 3); /* cycle match */ - if(cycle != -1) { + if (cycle != -1) { u32 start = cycle & 0x1FFF; /* 'cycle' is only mod 8000, but we also need two 'seconds' bits - @@ -2094,7 +2103,7 @@ udelay(100); /* check the RUN bit */ - if(!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) { + if (!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) { PRINT(KERN_ERR, xmit->ohci->id, "Error starting IT DMA (ContextControl 0x%08x)\n", reg_read(xmit->ohci, xmit->ContextControlSet)); return -1; @@ -2132,6 +2141,9 @@ case RECV_RELEASE: ohci_iso_recv_release(iso, (struct hpsb_iso_packet_info*) arg); return 0; + case RECV_FLUSH: + ohci_iso_recv_task((unsigned long) iso); + return 0; case RECV_SHUTDOWN: ohci_iso_recv_shutdown(iso); return 0; @@ -2451,7 +2463,7 @@ reg_write(ohci,OHCI1394_PhyReqFilterLoSet, 0x00000000); } - DBGMSG(ohci->id, "PhyReqFilter=%08x%08x\n", + DBGMSG(ohci->id, "PhyReqFilter=%08x%08x", reg_read(ohci,OHCI1394_PhyReqFilterHiSet), reg_read(ohci,OHCI1394_PhyReqFilterLoSet)); @@ -2699,19 +2711,29 @@ #ifdef OHCI1394_DEBUG if (datasize) - DBGMSG(ohci->id, - "Packet sent to node %d tcode=0x%X tLabel=" - "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d", - (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1]) - >>16)&0x3f, - (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) - >>4)&0xf, - (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) - >>10)&0x3f, - status&0x1f, (status>>5)&0x3, - le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3]) - >>16, - d->ctx); + if (((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa) + DBGMSG(ohci->id, + "Stream packet sent to channel %d tcode=0x%X " + "ack=0x%X spd=%d dataLength=%d ctx=%d", + (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>8)&0x3f, + (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf, + status&0x1f, (status>>5)&0x3, + le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16, + d->ctx); + else + DBGMSG(ohci->id, + "Packet sent to node %d tcode=0x%X tLabel=" + "%d ack=0x%X spd=%d dataLength=%d ctx=%d", + (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1]) + >>16)&0x3f, + (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) + >>4)&0xf, + (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) + >>10)&0x3f, + status&0x1f, (status>>5)&0x3, + le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3]) + >>16, + d->ctx); else DBGMSG(ohci->id, "Packet sent to node %d tcode=0x%X tLabel=" @@ -2806,7 +2828,7 @@ DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx); - if(d->ctrlClear) { + if (d->ctrlClear) { ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); if (d->type == DMA_CTX_ISO) { @@ -2968,7 +2990,7 @@ DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx); - if(d->ctrlClear) { + if (d->ctrlClear) { ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); if (d->type == DMA_CTX_ISO) { @@ -3164,7 +3186,7 @@ struct config_rom_ptr cr; memset(&cr, 0, sizeof(cr)); - memset(ohci->csr_config_rom_cpu, 0, sizeof (ohci->csr_config_rom_cpu)); + memset(ohci->csr_config_rom_cpu, 0, OHCI_CONFIG_ROM_LEN); cr.data = ohci->csr_config_rom_cpu; @@ -3259,7 +3281,7 @@ PRINT_G(KERN_ERR, fmt , ## args); \ ohci1394_pci_remove(dev); \ return err; \ -} while(0) +} while (0) static int __devinit ohci1394_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -3464,7 +3486,31 @@ case OHCI_INIT_DONE: hpsb_remove_host(ohci->host); + /* Clear out BUS Options */ + reg_write(ohci, OHCI1394_ConfigROMhdr, 0); + reg_write(ohci, OHCI1394_BusOptions, + (reg_read(ohci, OHCI1394_BusOptions) & 0x0000f007) | + 0x00ff0000); + memset(ohci->csr_config_rom_cpu, 0, OHCI_CONFIG_ROM_LEN); + case OHCI_INIT_HAVE_IRQ: + /* Clear interrupt registers */ + reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff); + + /* Disable IRM Contender */ + set_phy_reg(ohci, 4, ~0xc0 & get_phy_reg(ohci, 4)); + + /* Clear link control register */ + reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff); + + /* Let all other nodes know to ignore us */ + ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT); + /* Soft reset before we start - this disables * interrupts and clears linkEnable and LPS. */ ohci_soft_reset(ohci); @@ -3528,6 +3574,16 @@ } } + +#ifdef CONFIG_PM +static int ohci1394_pci_resume (struct pci_dev *dev) +{ + pci_enable_device(dev); + return 0; +} +#endif + + #define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10) static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = { @@ -3549,6 +3605,10 @@ .id_table = ohci1394_pci_tbl, .probe = ohci1394_pci_probe, .remove = ohci1394_pci_remove, + +#ifdef CONFIG_PM + .resume = ohci1394_pci_resume, +#endif /* PM */ }; @@ -3608,8 +3668,8 @@ usage = &ohci->ir_ctx_usage; /* only one receive context can be multichannel (OHCI sec 10.4.1) */ - if(tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { - if(test_and_set_bit(0, &ohci->ir_multichannel_used)) { + if (tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { + if (test_and_set_bit(0, &ohci->ir_multichannel_used)) { return r; } } @@ -3644,7 +3704,7 @@ else { clear_bit(tasklet->context, &ohci->ir_ctx_usage); - if(tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { + if (tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { clear_bit(0, &ohci->ir_multichannel_used); } } diff -urN linux-2.4.21/drivers/ieee1394/oui.db linux-2.4.22/drivers/ieee1394/oui.db --- linux-2.4.21/drivers/ieee1394/oui.db 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/ieee1394/oui.db 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,4931 @@ +000000 XEROX CORPORATION +000001 XEROX CORPORATION +000002 XEROX CORPORATION +000003 XEROX CORPORATION +000004 XEROX CORPORATION +000005 XEROX CORPORATION +000006 XEROX CORPORATION +000007 XEROX CORPORATION +000008 XEROX CORPORATION +000009 XEROX CORPORATION +00000A OMRON TATEISI ELECTRONICS CO. +00000B MATRIX CORPORATION +00000C CISCO SYSTEMS, INC. +00000D FIBRONICS LTD. +00000E FUJITSU LIMITED +00000F NEXT, INC. +000010 SYTEK INC. +000011 NORMEREL SYSTEMES +000012 INFORMATION TECHNOLOGY LIMITED +000013 CAMEX +000014 NETRONIX +000015 DATAPOINT CORPORATION +000016 DU PONT PIXEL SYSTEMS . +000017 TEKELEC +000018 WEBSTER COMPUTER CORPORATION +000019 APPLIED DYNAMICS INTERNATIONAL +00001A ADVANCED MICRO DEVICES +00001B NOVELL INC. +00001C BELL TECHNOLOGIES +00001D CABLETRON SYSTEMS, INC. +00001E TELSIST INDUSTRIA ELECTRONICA +00001F Telco Systems, Inc. +000020 DATAINDUSTRIER DIAB AB +000021 SUREMAN COMP. & COMMUN. CORP. +000022 VISUAL TECHNOLOGY INC. +000023 ABB INDUSTRIAL SYSTEMS AB +000024 CONNECT AS +000025 RAMTEK CORP. +000026 SHA-KEN CO., LTD. +000027 JAPAN RADIO COMPANY +000028 PRODIGY SYSTEMS CORPORATION +000029 IMC NETWORKS CORP. +00002A TRW - SEDD/INP +00002B CRISP AUTOMATION, INC +00002C AUTOTOTE LIMITED +00002D CHROMATICS INC +00002E SOCIETE EVIRA +00002F TIMEPLEX INC. +000030 VG LABORATORY SYSTEMS LTD +000031 QPSX COMMUNICATIONS PTY LTD +000032 Marconi plc +000033 EGAN MACHINERY COMPANY +000034 NETWORK RESOURCES CORPORATION +000035 SPECTRAGRAPHICS CORPORATION +000036 ATARI CORPORATION +000037 OXFORD METRICS LIMITED +000038 CSS LABS +000039 TOSHIBA CORPORATION +00003A CHYRON CORPORATION +00003B i Controls, Inc. +00003C AUSPEX SYSTEMS INC. +00003D UNISYS +00003E SIMPACT +00003F SYNTREX, INC. +000040 APPLICON, INC. +000041 ICE CORPORATION +000042 METIER MANAGEMENT SYSTEMS LTD. +000043 MICRO TECHNOLOGY +000044 CASTELLE CORPORATION +000045 FORD AEROSPACE & COMM. CORP. +000046 OLIVETTI NORTH AMERICA +000047 NICOLET INSTRUMENTS CORP. +000048 SEIKO EPSON CORPORATION +000049 APRICOT COMPUTERS, LTD +00004A ADC CODENOLL TECHNOLOGY CORP. +00004B ICL DATA OY +00004C NEC CORPORATION +00004D DCI CORPORATION +00004E AMPEX CORPORATION +00004F LOGICRAFT, INC. +000050 RADISYS CORPORATION +000051 HOB ELECTRONIC GMBH & CO. KG +000052 Intrusion.com, Inc. +000053 COMPUCORP +000054 MODICON, INC. +000055 COMMISSARIAT A L`ENERGIE ATOM. +000056 DR. B. STRUCK +000057 SCITEX CORPORATION LTD. +000058 RACORE COMPUTER PRODUCTS INC. +000059 HELLIGE GMBH +00005A SysKonnect GmbH +00005B ELTEC ELEKTRONIK AG +00005C TELEMATICS INTERNATIONAL INC. +00005D CS TELECOM +00005E USC INFORMATION SCIENCES INST +00005F SUMITOMO ELECTRIC IND., LTD. +000060 KONTRON ELEKTRONIK GMBH +000061 GATEWAY COMMUNICATIONS +000062 BULL HN INFORMATION SYSTEMS +000063 DR.ING.SEUFERT GMBH +000064 YOKOGAWA DIGITAL COMPUTER CORP +000065 NETWORK ASSOCIATES, INC. +000066 TALARIS SYSTEMS, INC. +000067 SOFT * RITE, INC. +000068 ROSEMOUNT CONTROLS +000069 CONCORD COMMUNICATIONS INC +00006A COMPUTER CONSOLES INC. +00006B SILICON GRAPHICS INC./MIPS +00006D CRAY COMMUNICATIONS, LTD. +00006E ARTISOFT, INC. +00006F MADGE NETWORKS LTD. +000070 HCL LIMITED +000071 ADRA SYSTEMS INC. +000072 MINIWARE TECHNOLOGY +000073 SIECOR CORPORATION +000074 RICOH COMPANY LTD. +000075 Nortel Networks +000076 ABEKAS VIDEO SYSTEM +000077 INTERPHASE CORPORATION +000078 LABTAM LIMITED +000079 NETWORTH INCORPORATED +00007A DANA COMPUTER INC. +00007B RESEARCH MACHINES +00007C AMPERE INCORPORATED +00007D SUN MICROSYSTEMS, INC. +00007E CLUSTRIX CORPORATION +00007F LINOTYPE-HELL AG +000080 CRAY COMMUNICATIONS A/S +000081 BAY NETWORKS +000082 LECTRA SYSTEMES SA +000083 TADPOLE TECHNOLOGY PLC +000084 SUPERNET +000085 CANON INC. +000086 MEGAHERTZ CORPORATION +000087 HITACHI, LTD. +000088 COMPUTER NETWORK TECH. CORP. +000089 CAYMAN SYSTEMS INC. +00008A DATAHOUSE INFORMATION SYSTEMS +00008B INFOTRON +00008C ALLOY COMPUTER PRODUCTS, INC. +00008D VERDIX CORPORATION +00008E SOLBOURNE COMPUTER, INC. +00008F RAYTHEON COMPANY +000090 MICROCOM +000091 ANRITSU CORPORATION +000092 COGENT DATA TECHNOLOGIES +000093 PROTEON INC. +000094 ASANTE TECHNOLOGIES +000095 SONY TEKTRONIX CORP. +000096 MARCONI ELECTRONICS LTD. +000097 EPOCH SYSTEMS +000098 CROSSCOMM CORPORATION +000099 MTX, INC. +00009A RC COMPUTER A/S +00009B INFORMATION INTERNATIONAL, INC +00009C ROLM MIL-SPEC COMPUTERS +00009D LOCUS COMPUTING CORPORATION +00009E MARLI S.A. +00009F AMERISTAR TECHNOLOGIES INC. +0000A0 TOKYO SANYO ELECTRIC CO. LTD. +0000A1 MARQUETTE ELECTRIC CO. +0000A2 BAY NETWORKS +0000A3 NETWORK APPLICATION TECHNOLOGY +0000A4 ACORN COMPUTERS LIMITED +0000A5 COMPATIBLE SYSTEMS CORP. +0000A6 NETWORK GENERAL CORPORATION +0000A7 NETWORK COMPUTING DEVICES INC. +0000A8 STRATUS COMPUTER INC. +0000A9 NETWORK SYSTEMS CORP. +0000AA XEROX CORPORATION +0000AB LOGIC MODELING CORPORATION +0000AC CONWARE COMPUTER CONSULTING +0000AD BRUKER INSTRUMENTS INC. +0000AE DASSAULT ELECTRONIQUE +0000AF NUCLEAR DATA INSTRUMENTATION +0000B0 RND-RAD NETWORK DEVICES +0000B1 ALPHA MICROSYSTEMS INC. +0000B2 TELEVIDEO SYSTEMS, INC. +0000B3 CIMLINC INCORPORATED +0000B4 EDIMAX COMPUTER COMPANY +0000B5 DATABILITY SOFTWARE SYS. INC. +0000B6 MICRO-MATIC RESEARCH +0000B7 DOVE COMPUTER CORPORATION +0000B8 SEIKOSHA CO., LTD. +0000B9 MCDONNELL DOUGLAS COMPUTER SYS +0000BA SIIG, INC. +0000BB TRI-DATA +0000BC ALLEN-BRADLEY CO. INC. +0000BD MITSUBISHI CABLE COMPANY +0000BE THE NTI GROUP +0000BF SYMMETRIC COMPUTER SYSTEMS +0000C0 WESTERN DIGITAL CORPORATION +0000C1 Madge Networks Ltd. +0000C2 INFORMATION PRESENTATION TECH. +0000C3 HARRIS CORP COMPUTER SYS DIV +0000C4 WATERS DIV. OF MILLIPORE +0000C5 FARALLON COMPUTING/NETOPIA +0000C6 EON SYSTEMS +0000C7 ARIX CORPORATION +0000C8 ALTOS COMPUTER SYSTEMS +0000C9 EMULEX CORPORATION +0000CA APPLITEK +0000CB COMPU-SHACK ELECTRONIC GMBH +0000CC DENSAN CO., LTD. +0000CD Centrecom Systems, Ltd. +0000CE MEGADATA CORP. +0000CF HAYES MICROCOMPUTER PRODUCTS +0000D0 DEVELCON ELECTRONICS LTD. +0000D1 ADAPTEC INCORPORATED +0000D2 SBE, INC. +0000D3 WANG LABORATORIES INC. +0000D4 PURE DATA LTD. +0000D5 MICROGNOSIS INTERNATIONAL +0000D6 PUNCH LINE HOLDING +0000D7 DARTMOUTH COLLEGE +0000D8 NOVELL, INC. +0000D9 NIPPON TELEGRAPH & TELEPHONE +0000DA ATEX +0000DB BRITISH TELECOMMUNICATIONS PLC +0000DC HAYES MICROCOMPUTER PRODUCTS +0000DD TCL INCORPORATED +0000DE CETIA +0000DF BELL & HOWELL PUB SYS DIV +0000E0 QUADRAM CORP. +0000E1 GRID SYSTEMS +0000E2 ACER TECHNOLOGIES CORP. +0000E3 INTEGRATED MICRO PRODUCTS LTD +0000E4 IN2 GROUPE INTERTECHNIQUE +0000E5 SIGMEX LTD. +0000E6 APTOR PRODUITS DE COMM INDUST +0000E7 STAR GATE TECHNOLOGIES +0000E8 ACCTON TECHNOLOGY CORP. +0000E9 ISICAD, INC. +0000EA UPNOD AB +0000EB MATSUSHITA COMM. IND. CO. LTD. +0000EC MICROPROCESS +0000ED APRIL +0000EE NETWORK DESIGNERS, LTD. +0000EF KTI +0000F0 SAMSUNG ELECTRONICS CO., LTD. +0000F1 MAGNA COMPUTER CORPORATION +0000F2 SPIDER COMMUNICATIONS +0000F3 GANDALF DATA LIMITED +0000F4 ALLIED TELESYN INTERNATIONAL +0000F5 DIAMOND SALES LIMITED +0000F6 APPLIED MICROSYSTEMS CORP. +0000F7 YOUTH KEEP ENTERPRISE CO LTD +0000F8 DIGITAL EQUIPMENT CORPORATION +0000F9 QUOTRON SYSTEMS INC. +0000FA MICROSAGE COMPUTER SYSTEMS INC +0000FB RECHNER ZUR KOMMUNIKATION +0000FC MEIKO +0000FD HIGH LEVEL HARDWARE +0000FE ANNAPOLIS MICRO SYSTEMS +0000FF CAMTEC ELECTRONICS LTD. +000100 EQUIP'TRANS +000102 3COM CORPORATION +000103 3COM CORPORATION +000104 DVICO Co., Ltd. +000105 BECKHOFF GmbH +000106 Tews Datentechnik GmbH +000107 Leiser GmbH +000108 AVLAB Technology, Inc. +000109 Nagano Japan Radio Co., Ltd. +00010A CIS TECHNOLOGY INC. +00010B Space CyberLink, Inc. +00010C System Talks Inc. +00010D CORECO, INC. +00010E Bri-Link Technologies Co., Ltd +00010F Nishan Systems, Inc. +000110 Gotham Networks +000111 iDigm Inc. +000112 Shark Multimedia Inc. +000113 OLYMPUS OPTICAL CO., LTD. +000114 KANDA TSUSHIN KOGYO CO., LTD. +000115 EXTRATECH CORPORATION +000116 Netspect Technologies, Inc. +000117 CANAL + +000118 EZ Digital Co., Ltd. +000119 Action Controls Pty. Ltd. +00011A EEH DataLink GmbH +00011B Unizone Technologies, Inc. +00011C Universal Talkware Corporation +00011D Centillium Communications +00011E Precidia Technologies, Inc. +00011F RC Networks, Inc. +000120 OSCILLOQUARTZ S.A. +000121 RapidStream Inc. +000122 Trend Communications, Ltd. +000123 DIGITAL ELECTRONICS CORP. +000124 Acer Incorporated +000125 YAESU MUSEN CO., LTD. +000126 PAC Labs +000127 The OPEN Group Limited +000128 EnjoyWeb, Inc. +000129 DFI Inc. +00012A Telematica Sistems Inteligente +00012B TELENET Co., Ltd. +00012C Aravox Technologies, Inc. +00012D Komodo Technology +00012E PC Partner Ltd. +00012F Twinhead International Corp +000130 Extreme Networks +000131 Detection Systems, Inc. +000132 Dranetz - BMI +000133 KYOWA Electronic Instruments C +000134 SIG Positec Systems AG +000135 KDC Corp. +000136 CyberTAN Technology, Inc. +000137 IT Farm Corporation +000138 XAVi Technologies Corp. +000139 Point Multimedia Systems +00013A SHELCAD COMMUNICATIONS, LTD. +00013B BNA SYSTEMS +00013C TIW SYSTEMS +00013D RiscStation Ltd. +00013E Ascom Tateco AB +00013F Neighbor World Co., Ltd. +000140 Sendtek Corporation +000141 CABLE PRINT +000142 Cisco Systems, Inc. +000143 Cisco Systems, Inc. +000144 Cereva Networks, Inc. +000145 WINSYSTEMS, INC. +000146 Tesco Controls, Inc. +000147 Zhone Technologies +000148 X-traWeb Inc. +000149 T.D.T. Transfer Data Test GmbH +00014A SONY COMPUTER SCIENCE LABS., I +00014B Ennovate Networks, Inc. +00014C Berkeley Process Control +00014D Shin Kin Enterprises Co., Ltd +00014E WIN Enterprises, Inc. +00014F LUMINOUS Networks, Inc. +000150 GILAT COMMUNICATIONS, LTD. +000151 Ensemble Communications +000152 CHROMATEK INC. +000153 ARCHTEK TELECOM CORPORATION +000154 G3M Corporation +000155 Promise Technology, Inc. +000156 FIREWIREDIRECT.COM, INC. +000157 SYSWAVE CO., LTD +000158 Electro Industries/Gauge Tech +000159 S1 Corporation +00015A Digital Video Broadcasting +00015B ITALTEL S.p.A/RF-UP-I +00015C CADANT INC. +00015D Pirus Networks +00015E BEST TECHNOLOGY CO., LTD. +00015F DIGITAL DESIGN GmbH +000160 ELMEX Co., LTD. +000161 Meta Machine Technology +000162 Cygnet Technologies, Inc. +000163 Cisco Systems, Inc. +000164 Cisco Systems, Inc. +000165 AirSwitch Corporation +000166 TC GROUP A/S +000167 HIOKI E.E. CORPORATION +000168 VITANA CORPORATION +000169 Celestix Networks Pte Ltd. +00016A ALITEC +00016B LightChip, Inc. +00016C FOXCONN +00016D Triton Network Systems +00016E Conklin Corporation +00016F HAITAI ELECTRONICS CO., LTD. +000170 ESE Embedded System Engineer'g +000171 Allied Data Technologies +000172 TechnoLand Co., LTD. +000173 JNI Corporation +000174 CyberOptics Corporation +000175 Radiant Communications Corp. +000176 Orient Silver Enterprises +000177 EDSL +000178 MARGI Systems, Inc. +000179 WIRELESS TECHNOLOGY, INC. +00017A Chengdu Maipu Electric Industrial Co., Ltd. +00017B Heidelberger Druckmaschinen AG +00017C AG-E GmbH +00017D ThermoQuest +00017E ADTEK System Science Co., Ltd. +00017F Experience Music Project +000180 AOpen, Inc. +000181 Nortel Networks +000182 DICA TECHNOLOGIES AG +000183 ANITE TELECOMS +000184 SIEB & MEYER AG +000185 Aloka Co., Ltd. +000186 DISCH GmbH +000187 i2SE GmbH +000188 LXCO Technologies ag +000189 Refraction Technology, Inc. +00018A ROI COMPUTER AG +00018B NetLinks Co., Ltd. +00018C Mega Vision +00018D AudeSi Technologies +00018E Logitec Corporation +00018F Kenetec, Inc. +000190 SMK-M +000191 SYRED Data Systems +000192 Texas Digital Systems +000193 Hanbyul Telecom Co., Ltd. +000194 Capital Equipment Corporation +000195 Sena Technologies, Inc. +000196 Cisco Systems, Inc. +000197 Cisco Systems, Inc. +000198 Darim Vision +000199 HeiSei Electronics +00019A LEUNIG GmbH +00019B Kyoto Microcomputer Co., Ltd. +00019C JDS Uniphase Inc. +00019D E-Control Systems, Inc. +00019E ESS Technology, Inc. +00019F Phonex Broadband +0001A0 Infinilink Corporation +0001A1 Mag-Tek, Inc. +0001A2 Logical Co., Ltd. +0001A3 GENESYS LOGIC, INC. +0001A4 Microlink Corporation +0001A5 Nextcomm, Inc. +0001A6 Scientific-Atlanta Arcodan A/S +0001A7 UNEX TECHNOLOGY CORPORATION +0001A8 Welltech Computer Co., Ltd. +0001A9 BMW AG +0001AA Airspan Communications, Ltd. +0001AB Main Street Networks +0001AC Sitara Networks, Inc. +0001AD Coach Master International d.b.a. CMI Worldwide, Inc. +0001AE Trex Enterprises +0001AF Motorola Computer Group +0001B0 Fulltek Technology Co., Ltd. +0001B1 General Bandwidth +0001B2 Digital Processing Systems, Inc. +0001B3 Precision Electronic Manufacturing +0001B4 Wayport, Inc. +0001B5 Turin Networks, Inc. +0001B6 SAEJIN T&M Co., Ltd. +0001B7 Centos, Inc. +0001B8 Netsensity, Inc. +0001B9 SKF Condition Monitoring +0001BA IC-Net, Inc. +0001BB Frequentis +0001BC Brains Corporation +0001BD Peterson Electro-Musical Products, Inc. +0001BE Gigalink Co., Ltd. +0001BF Teleforce Co., Ltd. +0001C0 CompuLab, Ltd. +0001C1 Exbit Technology +0001C2 ARK Research Corp. +0001C3 Acromag, Inc. +0001C4 NeoWave, Inc. +0001C5 Simpler Networks +0001C6 Quarry Technologies +0001C7 Cisco Systems, Inc. +0001C8 THOMAS CONRAD CORP. +0001C8 CONRAD CORP. +0001C9 Cisco Systems, Inc. +0001CA Geocast Network Systems, Inc. +0001CB NetGame, Ltd. +0001CC Japan Total Design Communication Co., Ltd. +0001CD ARtem +0001CE Custom Micro Products, Ltd. +0001CF Alpha Data Parallel Systems, Ltd. +0001D0 VitalPoint, Inc. +0001D1 CoNet Communications, Inc. +0001D2 MacPower Peripherals, Ltd. +0001D3 PAXCOMM, Inc. +0001D4 Leisure Time, Inc. +0001D5 HAEDONG INFO & COMM CO., LTD +0001D6 MAN Roland Druckmaschinen AG +0001D7 F5 Networks, Inc. +0001D8 Teltronics, Inc. +0001D9 Sigma, Inc. +0001DA WINCOMM Corporation +0001DB Freecom Technologies GmbH +0001DC Activetelco +0001DD Avail Networks +0001DE Trango Systems, Inc. +0001DF ISDN Communications, Ltd. +0001E0 Fast Systems, Inc. +0001E1 Kinpo Electronics, Inc. +0001E2 Ando Electric Corporation +0001E3 Siemens AG +0001E4 Sitera, Inc. +0001E5 Supernet, Inc. +0001E6 Hewlett-Packard Company +0001E7 Hewlett-Packard Company +0001E8 Force10 Networks, Inc. +0001E9 Litton Marine Systems B.V. +0001EA Cirilium Corp. +0001EB C-COM Corporation +0001EC Ericsson Group +0001ED SETA Corp. +0001EE Comtrol Europe, Ltd. +0001EF Camtel Technology Corp. +0001F0 Tridium, Inc. +0001F1 Innovative Concepts, Inc. +0001F3 QPS, Inc. +0001F4 Enterasys Networks +0001F5 ERIM S.A. +0001F6 Association of Musical Electronics Industry +0001F7 Image Display Systems, Inc. +0001F8 Adherent Systems, Ltd. +0001F9 TeraGlobal Communications Corp. +0001FA HOROSCAS +0001FB DoTop Technology, Inc. +0001FC Keyence Corporation +0001FD Digital Voice Systems, Inc. +0001FE DIGITAL EQUIPMENT CORPORATION +0001FF Data Direct Networks, Inc. +000200 Net & Sys Co., Ltd. +000201 IFM Electronic gmbh +000202 Amino Communications, Ltd. +000203 Woonsang Telecom, Inc. +000204 Bodmann Industries Elektronik GmbH +000205 Hitachi Denshi, Ltd. +000206 Telital R&D Denmark A/S +000208 Unify Networks, Inc. +000209 Shenzhen SED Information Technology Co., Ltd. +00020A Gefran Spa +00020B Native Networks, Inc. +00020C Metro-Optix +00020D Micronpc.com +00020E Laurel Networks, Inc. +00020F AATR +000210 Fenecom +000211 Nature Worldwide Technology Corp. +000212 SierraCom +000213 S.D.E.L. +000214 DTVRO +000215 Cotas Computer Technology A/B +000216 Cisco Systems, Inc. +000217 Cisco Systems, Inc. +000218 Advanced Scientific Corp +000219 Paralon Technologies +00021A Zuma Networks +00021B Kollmorgen-Servotronix +00021C Network Elements, Inc. +00021D Data General Communication Ltd. +00021E SIMTEL S.R.L. +00021F Aculab PLC +000220 Canon Aptex, Inc. +000221 DSP Application, Ltd. +000222 Chromisys, Inc. +000223 ClickTV +000224 Lantern Communications, Inc. +000225 Certus Technology, Inc. +000226 XESystems, Inc. +000227 ESD GmbH +000228 Necsom, Ltd. +000229 Adtec Corporation +00022A Asound Electronic +00022B Tamura Electric Works, Ltd. +00022C ABB Bomem, Inc. +00022D Agere Systems +00022E TEAC Corp. R& D +00022F P-Cube, Ltd. +000230 Intersoft Electronics +000231 Ingersoll-Rand +000232 Avision, Inc. +000233 Mantra Communications, Inc. +000234 Imperial Technology, Inc. +000235 Paragon Networks International +000236 INIT GmbH +000237 Cosmo Research Corp. +000238 Serome Technology, Inc. +000239 Visicom +00023A ZSK Stickmaschinen GmbH +00023B Redback Networks +00023C Creative Technology, Ltd. +00023D NuSpeed, Inc. +00023E Selta Telematica S.p.a +00023F Compal Electronics, Inc. +000240 Seedek Co., Ltd. +000241 Amer.com +000242 Videoframe Systems +000243 Raysis Co., Ltd. +000244 SURECOM Technology Co. +000245 Lampus Co, Ltd. +000246 All-Win Tech Co., Ltd. +000247 Great Dragon Information Technology (Group) Co., Ltd. +000248 Pila GmbH & Co. +000249 Aviv Infocom Co, Ltd. +00024A Cisco Systems, Inc. +00024B Cisco Systems, Inc. +00024C SiByte, Inc. +00024D Mannesman Dematic Colby Pty. Ltd. +00024E Datacard Group +00024F IPM Datacom S.R.L. +000250 Geyser Networks, Inc. +000251 Soma Networks +000252 Carrier Corporation +000253 Televideo, Inc. +000254 WorldGate +000255 IBM Corporation +000256 Alpha Processor, Inc. +000257 Microcom Corp. +000258 Flying Packets Communications +000259 Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group +00025A Catena Networks +00025B Cambridge Silicon Radio +00025C SCI Systems (Kunshan) Co., Ltd. +00025E High Technology Ltd +00025F Nortel Networks +000260 Accordion Networks, Inc. +000261 i3 Micro Technology AB +000262 Soyo Group Soyo Com Tech Co., Ltd +000263 UPS Manufacturing SRL +000264 AudioRamp.com +000265 Virditech Co. Ltd. +000266 Thermalogic Corporation +000267 NODE RUNNER, INC. +000268 Harris Government Communications +000269 Nadatel Co., Ltd +00026A Cocess Telecom Co., Ltd. +00026B BCM Computers Co., Ltd. +00026C Philips CFT +00026D Adept Telecom +00026E NeGeN Access, Inc. +00026F Senao International Co., Ltd. +000270 Crewave Co., Ltd. +000271 Vpacket Communications +000272 CC&C Technologies, Inc. +000273 Coriolis Networks +000274 Tommy Technologies Corp. +000275 SMART Technologies, Inc. +000276 Primax Electronics Ltd. +000277 Cash Systemes Industrie +000278 Samsung Electro-Mechanics Co., Ltd. +000279 Control Applications, Ltd. +00027A IOI Technology Corporation +00027B Amplify Net, Inc. +00027C Trilithic, Inc. +00027D Cisco Systems, Inc. +00027E Cisco Systems, Inc. +00027F ask-technologies.com +000280 Mu Net, Inc. +000281 Red-M (Communications) Ltd. +000282 ViaClix, Inc. +000283 Spectrum Controls, Inc. +000284 Alstom T&D P&C +000285 Riverstone Networks +000286 Occam Networks +000287 Adapcom +000288 GLOBAL VILLAGE COMMUNICATION +000289 DNE Technologies +00028A Ambit Microsystems Corporation +00028B VDSL Systems OY +00028C Micrel-Synergy Semiconductor +00028D Movita Technologies, Inc. +00028E Rapid 5 Networks, Inc. +00028F Globetek, Inc. +000290 Woorigisool, Inc. +000291 Open Network Co., Ltd. +000292 Logic Innovations, Inc. +000293 Solid Data Systems +000294 Tokyo Sokushin Co., Ltd. +000295 IP.Access Limited +000296 Lectron Co,. Ltd. +000297 C-COR.net +000298 Broadframe Corporation +000299 Apex, Inc. +00029A Storage Apps +00029B Kreatel Communications AB +00029D Merix Corp. +00029E Information Equipment Co., Ltd. +00029F L-3 Communication Aviation Recorders +0002A0 Flatstack Ltd. +0002A1 World Wide Packets +0002A2 Hilscher GmbH +0002A3 ABB Power Automation +0002A4 AddPac Technology Co., Ltd. +0002A5 Compaq Computer Corporation +0002A6 Effinet Systems Co., Ltd. +0002A7 Vivace Networks +0002A8 Air Link Technology +0002A9 RACOM, s.r.o. +0002AA PLcom Co., Ltd. +0002AB CTC Union Technologies Co., Ltd. +0002AC 3PAR data +0002AD Asahi Optical Co., Ltd. +0002AE Scannex Electronics Ltd. +0002AF TeleCruz Technology, Inc. +0002B0 Hokubu Communication & Industrial Co., Ltd. +0002B1 Anritsu, Ltd. +0002B2 Cablevision +0002B3 Intel Corporation +0002B4 DAPHNE +0002B5 Avnet, Inc. +0002B6 Acrosser Technology Co., Ltd. +0002B7 Watanabe Electric Industry Co., Ltd. +0002B8 WHI KONSULT AB +0002B9 Cisco Systems, Inc. +0002BA Cisco Systems, Inc. +0002BB Continuous Computing +0002BC LVL 7 Systems, Inc. +0002BD Bionet Co., Ltd. +0002BE Totsu Engineering, Inc. +0002BF dotRocket, Inc. +0002C0 Bencent Tzeng Industry Co., Ltd. +0002C1 Innovative Electronic Designs, Inc. +0002C2 Net Vision Telecom +0002C3 Arelnet Ltd. +0002C4 Vector International BUBA +0002C5 Evertz Microsystems Ltd. +0002C6 Data Track Technology PLC +0002C7 ALPS ELECTRIC Co., Ltd. +0002C8 Technocom Communications Technology (pte) Ltd +0002C9 Mellanox Technologies +0002CA EndPoints, Inc. +0002CB TriState Ltd. +0002CC M.C.C.I +0002CD TeleDream, Inc. +0002CE FoxJet, Inc. +0002CF ZyGate Communications, Inc. +0002D0 Comdial Corporation +0002D1 Vivotek, Inc. +0002D2 Workstation AG +0002D3 NetBotz, Inc. +0002D4 PDA Peripherals, Inc. +0002D5 ACR +0002D6 NICE Systems +0002D7 EMPEG Ltd +0002D8 BRECIS Communications Corporation +0002D9 Reliable Controls +0002DA ExiO Communications, Inc. +0002DB NETSEC +0002DC Fujitsu General Limited +0002DD Bromax Communications, Ltd. +0002DE Astrodesign, Inc. +0002DF Net Com Systems, Inc. +0002E0 ETAS GmbH +0002E1 Integrated Network Corporation +0002E2 NDC Infared Engineering +0002E3 LITE-ON Communications, Inc. +0002E4 JC HYUN Systems, Inc. +0002E5 Timeware Ltd. +0002E6 Gould Instrument Systems, Inc. +0002E7 CAB GmbH & Co KG +0002E8 E.D.&A. +0002E9 CS Systemes De Securite - C3S +0002EA Videonics, Inc. +0002EB Easent Communications +0002EC Maschoff Design Engineering +0002ED DXO Telecom Co., Ltd. +0002EE Nokia Danmark A/S +0002EF CCC Network Systems Group Ltd. +0002F0 AME Optimedia Technology Co., Ltd. +0002F1 Pinetron Co., Ltd. +0002F2 eDevice, Inc. +0002F3 Media Serve Co., Ltd. +0002F4 PCTEL, Inc. +0002F5 VIVE Synergies, Inc. +0002F6 Equipe Communications +0002F7 ARM +0002F8 SEAKR Engineering, Inc. +0002F9 Mimos Semiconductor SDN BHD +0002FA DX Antenna Co., Ltd. +0002FB Baumuller Aulugen-Systemtechnik GmbH +0002FC Cisco Systems, Inc. +0002FD Cisco Systems, Inc. +0002FE Viditec, Inc. +0002FF Handan Broad InfoCom +000300 NetContinuum, Inc. +000301 Avantas Networks Corporation +000302 Oasys Telecom, Inc. +000303 JAMA Electronics Co., Ltd. +000304 Pacific Broadband Communications +000305 Smart Network Devices GmbH +000306 Fusion In Tech Co., Ltd. +000307 Secure Works, Inc. +000308 AM Communications, Inc. +000309 Texcel Technology PLC +00030A Argus Technologies +00030B Hunter Technology, Inc. +00030C Telesoft Technologies Ltd. +00030D Uniwill Computer Corp. +00030E Core Communications Co., Ltd. +00030F Legend Digital China Ltd. +000310 Link Evolution Corp. +000311 Micro Technology Co., Ltd. +000312 TR-Systemtechnik GmbH +000313 Access Media SPA +000314 Teleware Network Systems +000315 Cidco Incorporated +000316 Nobell Communications, Inc. +000317 Merlin Systems, Inc. +000318 Cyras Systems, Inc. +000319 Infineon AG +00031A Beijing Broad Telecom Ltd., China +00031B Cellvision Systems, Inc. +00031C Svenska Hardvarufabriken AB +00031D Taiwan Commate Computer, Inc. +00031E Optranet, Inc. +00031F Condev Ltd. +000320 Xpeed, Inc. +000321 Reco Research Co., Ltd. +000322 IDIS Co., Ltd. +000323 Cornet Technology, Inc. +000324 Tottori SANYO Electric Co., Ltd. +000325 Arima Computer Corp. +000326 Iwasaki Information Systems Co., Ltd. +000327 ACT'L +000328 Mace Group, Inc. +000329 F3, Inc. +00032A UniData Communication Systems, Inc. +00032B GAI Datenfunksysteme GmbH +00032C ABB Industrie AG +00032D IBASE Technology, Inc. +00032E Scope Information Management, Ltd. +00032F Global Sun Technology, Inc. +000330 Imagenics, Co., Ltd. +000331 Cisco Systems, Inc. +000332 Cisco Systems, Inc. +000333 Digitel Co., Ltd. +000334 Newport Electronics +000335 Mirae Technology +000336 Zetes Technologies +000337 Vaone, Inc. +000338 Oak Technology +000339 Eurologic Systems, Ltd. +00033A Silicon Wave, Inc. +00033B TAMI Tech Co., Ltd. +00033C Daiden Co., Ltd. +00033D ILSHin Lab +00033E Tateyama System Laboratory Co., Ltd. +00033F BigBand Networks, Ltd. +000340 Floware Wireless Systems, Ltd. +000341 Axon Digital Design +000342 Nortel Networks +000343 Martin Professional A/S +000344 Tietech.Co., Ltd. +000345 Routrek Networks Corporation +000346 Hitachi Kokusai Electric, Inc. +000347 Intel Corporation +000348 Norscan Instruments, Ltd. +000349 Vidicode Datacommunicatie B.V. +00034A RIAS Corporation +00034B Nortel Networks +00034C Shanghai DigiVision Technology Co., Ltd. +00034D Chiaro Networks, Ltd. +00034E Pos Data Company, Ltd. +00034F Sur-Gard Security +000350 BTICINO SPA +000351 Diebold, Inc. +000352 Colubris Networks +000353 Mitac, Inc. +000354 Fiber Logic Communications +000355 TeraBeam Internet Systems +000356 Wincor Nixdorf GmbH & Co KG +000357 Intervoice-Brite, Inc. +000358 iCable System Co., Ltd. +000359 DigitalSis +00035A Phototron Limited +00035B BridgeWave Communications +00035C Saint Song Corp. +00035D Bosung Hi-Net Co., Ltd. +00035E Metropolitan Area Networks, Inc. +00035F Schuehle Mess - und. Kontrollsysteme +000360 PAC Interactive Technology, Inc. +000361 Widcomm, Inc. +000362 Vodtel Communications, Inc. +000363 Miraesys Co., Ltd. +000364 Scenix Semiconductor, Inc. +000365 Kira Information & Communications, Ltd. +000366 ASM Pacific Technology +000367 Jasmine Networks, Inc. +000368 Embedone Co., Ltd. +000369 Nippon Antenna Co., Ltd. +00036A Mainnet, Ltd. +00036B Cisco Systems, Inc. +00036C Cisco Systems, Inc. +00036D Runtop, Inc. +00036E Nicon Systems (Pty) Limited +00036F Telsey SPA +000370 NXTV, Inc. +000371 Acomz Networks Corp. +000372 ULAN +000373 Aselsan A.S +000374 Hunter Watertech +000375 NetMedia, Inc. +000376 Graphtec Technology, Inc. +000377 Gigabit Wireless +000378 HUMAX Co., Ltd. +000379 Proscend Communications, Inc. +00037A Taiyo Yuden Co., Ltd. +00037B IDEC IZUMI Corporation +00037C Coax Media +00037D Stellcom +00037E PORTech Communications, Inc. +00037F Atheros Communications, Inc. +000381 Ingenico International +000382 A-One Co., Ltd. +000383 Metera Networks, Inc. +000384 AETA +000385 Actelis Networks, Inc. +000386 Ho Net, Inc. +000387 Blaze Network Products +000388 Fastfame Technology Co., Ltd. +000389 Plantronics +00038A America Online, Inc. +00038B PLUS-ONE I&T, Inc. +00038C Total Impact +00038D PCS Revenue Control Systems, Inc. +00038E Atoga Systems, Inc. +00038F Weinschel Corporation +000390 Digital Video Communications, Inc. +000392 Hyundai Teletek Co., Ltd. +000393 Apple Computer, Inc. +000394 Connect One +000395 California Amplifier +000396 EZ Cast Co., Ltd. +000397 Watchfront Electronics +000398 WISI +000399 Dongju Informations & Communications Co., Ltd. +00039A nSine, Ltd. +00039B NetChip Technology, Inc. +00039C OptiMight Communications, Inc. +00039D Acer Communications & Multimedia, Inc. +00039E Tera System Co., Ltd. +00039F Cisco Systems, Inc. +0003A0 Cisco Systems, Inc. +0003A1 HIPER Information & Communication, Inc. +0003A2 Catapult Communications +0003A3 MAVIX, Ltd. +0003A4 Data Storage and Information Management +0003A5 Medea Corporation +0003A7 Unixtar Technology, Inc. +0003A8 IDOT Computers, Inc. +0003A9 AXCENT Media AG +0003AA Watlow +0003AB Bridge Information Systems +0003AC Fronius Schweissmaschinen +0003AD Emerson Energy Systems AB +0003AE Allied Advanced Manufacturing Pte, Ltd. +0003AF Paragea Communications +0003B0 Xsense Technology Corp. +0003B1 Abbott Laboratories HPD +0003B2 Radware +0003B3 IA Link Systems Co., Ltd. +0003B4 Macrotek International Corp. +0003B5 Entra Technology Co. +0003B6 QSI Corporation +0003B7 ZACCESS Systems +0003B8 NetKit Solutions, LLC +0003B9 Hualong Telecom Co., Ltd. +0003BA Sun Microsystems +0003BB Signal Communications Limited +0003BC COT GmbH +0003BD OmniCluster Technologies, Inc. +0003BE Netility +0003BF Centerpoint Broadband Technologies, Inc. +0003C0 RFTNC Co., Ltd. +0003C1 Packet Dynamics Ltd +0003C2 Solphone K.K. +0003C3 Micronik Multimedia +0003C4 Tomra Systems ASA +0003C5 Mobotix AG +0003C6 ICUE Systems, Inc. +0003C7 hopf Elektronik GmbH +0003C8 CML Emergency Services +0003C9 TECOM Co., Ltd. +0003CA MTS Systems Corp. +0003CB Nippon Systems Development Co., Ltd. +0003CC Momentum Computer, Inc. +0003CD Clovertech, Inc. +0003CE ETEN Technologies, Inc. +0003CF Muxcom, Inc. +0003D0 KOANKEISO Co., Ltd. +0003D1 Takaya Corporation +0003D2 Crossbeam Systems, Inc. +0003D3 Internet Energy Systems, Inc. +0003D4 Alloptic, Inc. +0003D5 Advanced Communications Co., Ltd. +0003D6 RADVision, Ltd. +0003D7 NextNet Wireless, Inc. +0003D8 iMPath Networks, Inc. +0003D9 Secheron SA +0003DA Takamisawa Cybernetics Co., Ltd. +0003DB Apogee Electronics Corp. +0003DC Lexar Media, Inc. +0003DD Comark Corp. +0003DE OTC Wireless +0003DF Desana Systems +0003E0 RadioFrame Networks, Inc. +0003E1 Winmate Communication, Inc. +0003E2 Comspace Corporation +0003E3 Cisco Systems, Inc. +0003E4 Cisco Systems, Inc. +0003E5 Hermstedt SG +0003E6 Entone Technologies, Inc. +0003E7 Logostek Co. Ltd. +0003E8 Wavelength Digital Limited +0003E9 Akara Canada, Inc. +0003EA Mega System Technologies, Inc. +0003EB Atrica +0003EC ICG Research, Inc. +0003ED Shinkawa Electric Co., Ltd. +0003EE MKNet Corporation +0003EF Oneline AG +0003F0 Redfern Broadband Networks +0003F1 Cicada Semiconductor, Inc. +0003F2 Seneca Networks +0003F3 Dazzle Multimedia, Inc. +0003F4 NetBurner +0003F5 Chip2Chip +0003F6 Allegro Networks, Inc. +0003F7 Plast-Control GmbH +0003F8 SanCastle Technologies, Inc. +0003F9 Pleiades Communications, Inc. +0003FA TiMetra Networks +0003FB Toko Seiki Company, Ltd. +0003FC Intertex Data AB +0003FD Cisco Systems, Inc. +0003FE Cisco Systems, Inc. +0003FF Connectix +000400 LEXMARK INTERNATIONAL, INC. +000401 Osaki Electric Co., Ltd. +000402 Nexsan Technologies, Ltd. +000403 Nexsi Corporation +000404 Makino Milling Machine Co., Ltd. +000405 ACN Technologies +000406 Fa. Metabox AG +000407 Topcon Positioning Systems, Inc. +000408 Sanko Electronics Co., Ltd. +000409 Cratos Networks +00040A Sage Systems +00040B 3com Europe Ltd. +00040C KANNO Work's Ltd. +00040D Avaya, Inc. +00040E AVM GmbH +00040F Asus Network Technologies, Inc. +000410 Spinnaker Networks, Inc. +000411 Inkra Networks, Inc. +000412 WaveSmith Networks, Inc. +000413 SNOM Technology AG +000414 Umezawa Musen Denki Co., Ltd. +000415 Rasteme Systems Co., Ltd. +000416 Parks S/A Comunicacoes Digitais +000417 ELAU AG +000418 Teltronic S.A.U. +000419 Fibercycle Networks, Inc. +00041A ines GmbH +00041B Digital Interfaces Ltd. +00041C ipDialog, Inc. +00041D Corega of America +00041E Shikoku Instrumentation Co., Ltd. +00041F Sony Computer Entertainment, Inc. +000420 Slim Devices, Inc. +000421 Ocular Networks +000422 Gordon Kapes, Inc. +000423 Intel Corporation +000424 TMC s.r.l. +000425 Atmel Corporation +000426 Autosys +000427 Cisco Systems, Inc. +000428 Cisco Systems, Inc. +000429 Pixord Corporation +00042A Wireless Networks, Inc. +00042B IT Access Co., Ltd. +00042C Minet, Inc. +00042D Sarian Systems, Ltd. +00042E Netous Technologies, Ltd. +00042F International Communications Products, Inc. +000430 Netgem +000431 Play Industries +000432 Voyetra Turtle Beach, Inc. +000433 Cyberboard A/S +000434 Accelent Systems, Inc. +000435 Comptek International, Inc. +000436 ELANsat Technologies, Inc. +000437 Powin Information Technology, Inc. +000438 Nortel Networks +000439 Rosco Entertainment Technology, Inc. +00043A Intelligent Telecommunications, Inc. +00043B Lava Computer Mfg., Inc. +00043C SONOS Co., Ltd. +00043D INDEL AG +00043E Telencomm +00043F Electronic Systems Technology, Inc. +000440 cyberPIXIE, Inc. +000441 Half Dome Systems, Inc. +000442 NACT +000443 Agilent Technologies, Inc. +000444 Wireless Home +000445 LMS Skalar Instruments GmbH +000446 CYZENTECH Co., Ltd. +000447 Acrowave Systems Co., Ltd. +000448 Polaroid Professional Imaging +000449 Mapletree Networks +00044A iPolicy Networks, Inc. +00044B NVIDIA +00044C JENOPTIK +00044D Cisco Systems, Inc. +00044E Cisco Systems, Inc. +00044F Leukhardt Systemelektronik GmbH +000450 DMD Computers SRL +000451 Medrad, Inc. +000452 RocketLogix, Inc. +000453 Yotta Yotta, Inc. +000454 Quadriga UK +000455 ANTARA.net +000456 PipingHot Networks +000457 Universal Access Technology, Inc. +000458 Fusion X Co., Ltd. +000459 Veristar Corporation +00045A The Linksys Group, Inc. +00045B Techsan Electronics Co., Ltd. +00045C Mobiwave Pte Ltd +00045D BEKA Elektronik +00045E Poly Trax Information Technology AG +00045F Evalue Technology, Inc. +000460 Knilink Technology, Inc. +000461 EPOX Computer Co., Ltd. +000462 DAKOS Data & Communication Co., Ltd. +000463 Philips Communication Security & Imaging +000464 Fantasma Networks, Inc. +000465 ist isdn support tecknik GmbH +000466 ARMITEL Co. +000467 Wuhan Research Institute +000468 Vivity, Inc. +000469 Innocom, Inc. +00046A Navini Networks +00046B Palm Wireless, Inc. +00046C Cyber Technology Co., Ltd. +00046D Cisco Systems, Inc. +00046E Cisco Systems, Inc. +00046F Digitel S/A Industria Eletronica +000470 ipUnplugged AB +000471 IPrad +000472 Telelynx, Inc. +000473 Photonex Corporation +000474 LEGRAND +000475 3 Com Corporation +000476 3 Com Corporation +000477 e-Appliance Corp. +000478 G. Star Technology Corporation +000479 Radius Co., Ltd. +00047A AXXESSIT ASA +00047B Schlumberger +00047C Skidata AG +00047D Pelco +00047E NKF Electronics +00047F Chr. Mayr GmbH & Co. KG +000480 Foundry Networks, Inc. +000481 Econolite Control Products, Inc. +000482 MediaLogic Corp. +000483 Deltron Technology, Inc. +000484 Amann GmbH +000485 PicoLight +000486 ITTC, University of Kansas +000487 Cogency Semiconductor, Inc. +000488 Eurotherm Action Incorporated. +000489 YAFO Networks, Inc. +00048A Temia Vertriebs GmbH +00048B Poscon Corporation +00048C Nayna Networks, Inc. +00048D Tone Commander Systems, Inc. +00048E Ohm Tech Labs, Inc. +00048F TD Systems Corp. +000490 Optical Access +000491 Technovision, Inc. +000492 Hive Internet, Ltd. +000493 Tsinghua Unisplendour Co., Ltd. +000494 Breezecom, Ltd. +000495 Tejas Networks +000496 Extreme Networks +000497 MacroSystem Digital Video AG +000499 Chino Corporation +00049A Cisco Systems, Inc. +00049B Cisco Systems, Inc. +00049C Surgient Networks, Inc. +00049D Ipanema Technologies +00049E Wirelink Co., Ltd. +00049F Metrowerks +0004A0 Verity Instruments, Inc. +0004A1 Pathway Connectivity +0004A2 L.S.I. Japan Co., Ltd. +0004A3 Microchip Technology, Inc. +0004A4 NetEnabled, Inc. +0004A5 Barco Projection Systems NV +0004A6 SAF Tehnika Ltd. +0004A7 FabiaTech Corporation +0004A8 Broadmax Technologies, Inc. +0004A9 SandStream Technologies, Inc. +0004AA Jetstream Communications +0004AB Comverse Network Systems, Inc. +0004AC IBM CORP. +0004AD Malibu Networks +0004AE Liquid Metronics +0004AF Digital Fountain, Inc. +0004B0 ELESIGN Co., Ltd. +0004B1 Signal Technology, Inc. +0004B2 ESSEGI SRL +0004B3 Videotek, Inc. +0004B4 CIAC +0004B5 Equitrac Corporation +0004B6 Tellumat (Pty) Ltd. +0004B7 AMB i.t. Holding +0004B8 Kumahira Co., Ltd. +0004B9 S.I. Soubou, Inc. +0004BA KDD Media Will Corporation +0004BB Bardac Corporation +0004BC Giantec, Inc. +0004BD Motorola BCS +0004BE OptXCon, Inc. +0004BF Versa Logic Corp. +0004C0 Cisco Systems, Inc. +0004C1 Cisco Systems, Inc. +0004C2 Magnipix, Inc. +0004C3 CASTOR Informatique +0004C4 Allen & Health +0004C5 ASE Technologies, USA +0004C6 Yamaha Motor Co., Ltd. +0004C7 NetMount +0004C8 LIBA Maschinefabrik GmbH +0004C9 Micro Electron Co., Ltd. +0004CA FreeMs Corp. +0004CB Tdsoft Communication, Ltd. +0004CC Peek Traffic BV. +0004CD Informedia Research Group +0004CE Patria Ailon +0004CF Seagate Technology +0004D0 Softlink s.r.o. +0004D1 Drew Technologies, Inc. +0004D2 Adcon Telemetry AG +0004D3 Toyokeiki Co., Ltd. +0004D4 Proview Electronics Co., Ltd. +0004D5 Hitachi Communication Systems, Inc. +0004D6 Takagi Industrial Co., Ltd. +0004D7 Omitec Instrumentation Ltd. +0004D8 IPWireless, Inc. +0004D9 Titan Electronics, Inc. +0004DA Relax Technology, Inc. +0004DB Tellus Group Corp. +0004DC Nortel Networks +0004DD Cisco Systems, Inc. +0004DE Cisco Systems, Inc. +0004DF Teracom Telematica Ltda. +0004E0 Procket Networks +0004E1 Infinior Microsystems +0004E2 SMC Networks, Inc. +0004E3 Accton Technology Corp. +0004E4 Daeryung Ind., Inc. +0004E5 Glonet Systems, Inc. +0004E6 Banyan Network Private Limited +0004E7 Lightpointe Communications, Inc +0004E8 IER, Inc. +0004E9 Infiniswitch Corporation +0004EA Hewlett-Packard Company +0004EB Paxonet Communications, Inc. +0004EC Memobox SA +0004ED Billion Electric Co., Ltd. +0004EE Lincoln Electric Company +0004EF Polestar Corp. +0004F0 International Computers, Ltd +0004F1 WhereNet +0004F2 Circa Communications, Ltd. +0004F3 FS FORTH-SYSTEME GmbH +0004F4 Infinite Electronics Inc. +0004F5 SnowShore Networks, Inc. +0004F6 Amphus +0004F7 Omega Band, Inc. +0004F8 QUALICABLE TV Industria E Com., Ltda +0004F9 Xtera Communications, Inc. +0004FA MIST Inc. +0004FB Commtech, Inc. +0004FC Stratus Computer (DE), Inc. +0004FD Japan Control Engineering Co., Ltd. +0004FE Pelago Networks +0004FF Acronet Co., Ltd. +000500 Cisco Systems, Inc. +000501 Cisco Systems, Inc. +000502 APPLE COMPUTER +000503 ICONAG +000504 Naray Information & Communication Enterprise +000505 Systems Integration Solutions, Inc. +000506 Reddo Networks AB +000507 Fine Appliance Corp. +000508 Inetcam, Inc. +000509 AVOC Nishimura Ltd. +00050A ICS Spa +00050B SICOM Systems, Inc. +00050C Network Photonics, Inc. +00050D Midstream Technologies, Inc. +00050E 3ware, Inc. +00050F Tanaka S/S Ltd. +000510 Infinite Shanghai Communication Terminals Ltd. +000511 Complementaty Technologies Ltd +000512 MeshNetworks, Inc. +000513 VTLinx Multimedia Systems, Inc. +000514 KDT Systems Co., Ltd. +000515 Nuark Co., Ltd. +000516 SMART Modular Technologies +000517 Shellcomm, Inc. +000518 Jupiters Technology +000519 Siemens Building Technologies AG, +00051A 3Com Europe Ltd. +00051B Magic Control Technology Corporation +00051C Xnet Technology Corp. +00051D Airocon, Inc. +00051E Rhapsody Networks +00051F Taijin Media Co., Ltd. +000520 Smartronix, Inc. +000521 Control Microsystems +000522 LEA*D Corporation, Inc. +000523 AVL List GmbH +000524 BTL System (HK) Limited +000525 Puretek Industrial Co., Ltd. +000526 IPAS GmbH +000527 SJ Tek Co. Ltd +000528 New Focus, Inc. +000529 Shanghai Broadan Communication Technology Co., Ltd +00052A Ikegami Tsushinki Co., Ltd. +00052B HORIBA, Ltd. +00052C Supreme Magic Corporation +00052D Zoltrix International Limited +00052E Cinta Networks +00052F Leviton Voice and Data +000530 Andiamo Systems, Inc. +000531 Cisco Systems, Inc. +000532 Cisco Systems, Inc. +000533 Sanera Systems, Inc. +000534 Northstar Engineering Ltd. +000535 Chip PC Ltd. +000536 Danam Communications, Inc. +000537 Nets Technology Co., Ltd. +000538 Merilus, Inc. +000539 A Brand New World in Sweden AB +00053A Willowglen Services Pte Ltd +00053B Harbour Networks Ltd., Co. Beijing +00053C Xircom +00053D Agere Systems +00053E KID Systeme GmbH +00053F VisionTek, Inc. +000540 FAST Corporation +000541 Advanced Systems Co., Ltd. +000542 Otari, Inc. +000543 IQ Wireless GmbH +000544 Valley Technologies, Inc. +000545 Internet Photonics +000546 KDD Network Systems Co., Ltd. +000547 Starent Networks +000548 Disco Corporation +000549 Salira Optical Network Systems +00054A Ario Data Networks, Inc. +00054B Micro Innovation AG +00054C RF Innovations Pty Ltd +00054D Brans Technologies, Inc. +00054E Philips Components +000550 Digi-Tech Communications Limited +000551 F & S Elektronik Systeme GmbH +000552 Xycotec Computer GmbH +000553 DVC Company, Inc. +000554 Rangestar Wireless +000555 Japan Cash Machine Co., Ltd. +000556 360 Systems +000557 Agile TV Corporation +000558 Synchronous, Inc. +000559 Intracom S.A. +00055A Power Dsine Ltd. +00055B Charles Industries, Ltd. +00055C Kowa Company, Ltd. +00055D D-Link Systems, Inc. +00055E Cisco Systems, Inc. +00055F Cisco Systems, Inc. +000560 LEADER COMM.CO., LTD +000561 nac Image Technology, Inc. +000562 Digital View Limited +000563 J-Works, Inc. +000564 Tsinghua Bitway Co., Ltd. +000565 Tailyn Communication Company Ltd. +000566 Secui.com Corporation +000567 Etymonic Design, Inc. +000568 Piltofish Networks AB +000569 VMWARE, Inc. +00056B C.P. Technology Co., Ltd. +00056C Hung Chang Co., Ltd. +00056D Pacific Corporation +00056E National Enhance Technology, Inc. +00056F Innomedia Technologies Pvt. Ltd. +000570 Baydel Ltd. +000571 Seiwa Electronics Co. +000572 Deonet Co., Ltd. +000573 Cisco Systems, Inc. +000574 Cisco Systems, Inc. +000575 CDS-Electronics BV +000576 NSM Technology Ltd. +000577 SM Information & Communication +000579 Universal Control Solution Corp. +00057A Hatteras Networks +00057B Chung Nam Electronic Co., Ltd. +00057C RCO Security AB +00057D Sun Communications, Inc. +00057E Eckelmann Steuerungstechnik GmbH +00057F Acqis Technology +000580 Fibrolan Ltd. +000581 Snell & Wilcox Ltd. +000582 ClearCube Technology +000583 ImageCom Limited +000584 AbsoluteValue Systems, Inc. +000585 Juniper Networks, Inc. +000586 Lucent Technologies +000587 Locus, Incorporated +000588 Sensoria Corp. +000589 National Datacomputer +00058A Netcom Co., Ltd. +00058B IPmental, Inc. +00058C Opentech Inc. +00058D Lynx Photonic Networks, Inc. +00058E Ahead Communications System GmbH +00058F CLCsoft co. +000590 Ascom Business Systems +000591 Active Silicon Ltd. +000592 Pultex Corp. +000593 Grammar Engine Inc. +000594 IXXAT Automation GmbH +000595 Alesis Corporation +000596 Genotech Co., Ltd. +000597 Eagle Traffic Control Systems +000598 CRONOS S.r.l. +000599 PEI Electronics, Inc. +00059A Cisco Systems, Inc. +00059B Cisco Systems, Inc. +00059C Kleinknecht GmbH, Ing. Buero +00059D Daniel Computing Systems, Inc. +00059E Zinwell Corporation +00059F Yotta Networks, Inc. +0005A0 MOBILINE Kft. +0005A1 Zenocom +0005A2 CELOX Networks +0005A3 QEI, Inc. +0005A4 Lucid Voice Ltd. +0005A5 KOTT +0005A6 Extron Electronics +0005A7 Hyperchip, Inc. +0005A8 WYLE ELECTRONICS +0005A9 Princeton Networks, Inc. +0005AA Moore Industries Int. +0005AB Cyber Fone, Inc. +0005AC Northern Digital, Inc. +0005AD Topspin Communications, Inc. +0005AE Mediaport USA +0005AF InnoScan Computing A/S +0005B0 Korea Computer Technology Co., Ltd. +0005B1 ASB Technology BV +0005B2 Medison Co., Ltd. +0005B3 Asahi-Engineering Co., Ltd. +0005B4 Aceex Corporation +0005B5 Broadcom Technologies +0005B6 INSYS Microelectronics GmbH +0005B7 Arbor Technology Corp. +0005B8 Electronic Design Associates, Inc. +0005B9 Airvana, Inc. +0005BA Area Netwoeks, Inc. +0005BC Resorsys Ltd. +0005BD ROAX BV +0005BE Kongsberg Seatex AS +0005BF JustEzy Technology, Inc. +0005C0 Digital Network Alacarte Co., Ltd. +0005C1 A-Kyung Motion, Inc. +0005C2 Digital Archway, Inc. +0005C3 Pacific Instruments, Inc. +0005C4 Telect, Inc. +0005C5 Flaga HF +0005C6 Triz Communications +0005C7 I/F-COM A/S +0005C8 VERYTECH +0005C9 LG Innotek +0005CA Hitron Technology, Inc. +0005CB ROIS Technologies, Inc. +0005CC Sumtel Communications, Inc. +0005CD Nippon Columbia +0005CE Prolink Microsystems Corporation +0005CF Thunder River Technologies, Inc. +0005D0 Solinet Systems +0005D1 Metavector Technologies +0005D2 DAP Technologies +0005D3 CAC, Inc. +0005D4 FutureSmart Networks, Inc. +0005D5 Speedcom Wireless +0005D6 Titan Wireless +0005D7 Vista Imaging, Inc. +0005D8 Arescom, Inc. +0005D9 Techno Valley, Inc. +0005DA Apex Automationstechnik +0005DB Nentec GmbH +0005DC Cisco Systems, Inc. +0005DD Cisco Systems, Inc. +0005DE Gi Fone Korea, Inc. +0005DF Electronic Innovation, Inc. +0005E0 Empirix Corp. +0005E1 Trellis Photonics, Ltd. +0005E2 Creativ Network Technologies +0005E3 LightSand Communications, Inc. +0005E4 Red Lion Controls L.P. +0005E5 Renishaw PLC +0005E6 Egenera, Inc. +0005E7 Netrake +0005E8 TurboWave, Inc. +0005E9 Unicess Networks, Inc. +0005EA Viewcast Corporation +0005EB Blue Ridge Networks, Inc. +0005EC Mosaic Systems Inc. +0005ED Technikum Joanneaum GmbH +0005EE BEWATOR Group +0005EF ADOIR Digital Technology +0005F0 SATEC +0005F1 VRcom, Inc. +0005F2 Power R, Inc. +0005F3 Weboyn +0005F4 SystemBase Co., Ltd. +0005F5 OYO Geospace Corp. +0005F6 Young Chang Co. Ltd. +0005F7 Analog Devices, Inc. +0005F8 Real Time Access, Inc. +0005F9 Diva Systems +0005FA IPOptical, Inc. +0005FB Sharegate +0005FC Schenck Pegasus Corp. +0005FD PacketLight Networks Ltd. +0005FE Traficon N.V. +0005FF SNS Solutions, Inc. +000600 Tokyo Electronic Industry Co., Ltd. +000601 Otanikeiki Co., Ltd. +000602 Cirkitech Electronics Co. +000603 Baker Hughes +000604 @Track Communications, Inc. +000605 Inncom International, Inc. +000606 RapidWan, Inc. +000607 Omni-Directional Control Technology Inc. +000608 At-Sky SAS +000609 Crossport Systems +00060A Blue2space.com +00060B Paceline Systems Corporation +00060C Melco Industries, Inc. +00060D Wave7 Optics +00060E IGSYS Systems, Inc. +00060F Narad Networks Inc +000610 Abeona Networks Inc +000611 Zeus Wireless, Inc. +000612 Accusys, Inc. +000613 Kawasaki Steel Corporation +000614 Prism Holdings +000615 Kimoto Electric Co., Ltd. +000616 Tel Net Co., Ltd. +000617 Redswitch Inc. +000618 DigiPower Manufacturing Inc. +000619 Connection Technology Systems +00061A Zetari Inc. +00061B Portable Systems, IBM Japan Co, Ltd +00061C Hoshino Metal Industries, Ltd. +00061D MIP Telecom, Inc. +00061E Maxan Systems +00061F Vision Components GmbH +000620 Serial System Ltd. +000621 Hinox, Co., Ltd. +000622 Chung Fu Chen Yeh Enterprise Corp. +000623 MGE UPS Systems France +000624 Gentner Communications +000625 The Linksys Group, Inc. +000626 MWE GmbH +000627 Uniwide Technologies, Inc. +000628 Cisco Systems, Inc. +000629 IBM CORPORATION +00062A Cisco Systems, Inc. +00062B INTRASERVER TECHNOLOGY +00062C Network Robots, Inc. +00062D TouchStar Technologies, L.L.C. +00062E Aristos Logic Corp. +00062F Pivotech Systems Inc. +000630 Adtranz Sweden +000631 Optical Solutions, Inc. +000632 Mesco Engineering GmbH +000633 Heimann Biometric Systems GmbH +000634 GTE Airfone Inc. +000635 PacketAir Networks, Inc. +000636 Jedai Broadband Networks +000637 Toptrend-Meta Information (ShenZhen) Inc. +000638 Sungjin C&C Co., Ltd. +000639 Newtec +00063A Dura Micro, Inc. +00063B Lineo Canada Corp. +00063C NMI Electronics Ltd +00063D Microwave Data Systems Inc. +00063E Opthos Inc. +00063F Everex Communications Inc. +000640 White Rock Networks +000641 ITCN +000642 Genetel Systems Inc. +000643 SONO Computer Co., Ltd. +000644 NEIX Inc. +000645 Meisei Electric Co. Ltd. +000646 ShenZhen XunBao Network Technology Co Ltd +000647 Etrali S.A. +000648 Seedsware, Inc. +000649 Quante +00064A Honeywell Co., Ltd. (KOREA) +00064B Alexon Co., Ltd. +00064C Invicta Networks, Inc. +00064D Sencore +00064E Broad Net Technology Inc. +00064F PRO-NETS Technology Corporation +000650 Tiburon Networks, Inc. +000651 Aspen Networks Inc. +000652 Cisco Systems, Inc. +000653 Cisco Systems, Inc. +000654 Maxxio Technologies +000655 Yipee, Inc. +000656 Tactel AB +000657 Market Central, Inc. +000658 Helmut Fischer GmbH & Co. KG +000659 EAL (Apeldoorn) B.V. +00065A Strix Systems +00065B Dell Computer Corp. +00065C Malachite Technologies, Inc. +00065D Heidelberg Web Systems +00065E Photuris, Inc. +00065F ECI Telecom - NGTS Ltd. +000660 NADEX Co., Ltd. +000661 NIA Home Technologies Corp. +000662 MBM Technology Ltd. +000663 Human Technology Co., Ltd. +000664 Fostex Corporation +000665 Summy Gikem, Inc. +000666 Roving Networks +000667 Tripp Lite +000668 Vicon Industries Inc. +000669 Datasound Laboratories Ltd +00066A InfiniCon Systems, Inc. +00066B Sysmex Corporation +00066C Robinson Corporation +00066D Compuprint S.P.A. +00066E Delta Electronics, Inc. +00066F Korea Data Systems +000670 Upponetti Oy +000671 Softing AG +000672 Netezza +000673 Optelecom, Inc. +000674 Spectrum Control, Inc. +000675 Banderacom, Inc. +000676 Novra Technologies, Inc. +000677 SICK AG +000678 Marantz Japan, Inc. +000679 Konami Corporation +00067A JMP Systems +00067B Toplink C&C Corporation +00067C CISCO SYSTEMS, INC. +00067D Takasago Ltd. +0006C1 CISCO SYSTEMS, INC. +000701 RACAL-DATACOM +000800 MULTITECH SYSTEMS, INC. +0008C7 COMPAQ COMPUTER CORPORATION +000A27 Apple Computer, Inc. +001000 CABLE TELEVISION +001001 MCK COMMUNICATIONS +001002 ACTIA +001003 IMATRON, INC. +001004 THE BRANTLEY COILE COMPANY,INC +001005 UEC COMMERCIAL +001006 RACAL RECORDERS LTD. +001007 CISCO SYSTEMS, INC. +001008 VIENNA SYSTEMS CORPORATION +001009 HORO QUARTZ +00100A WILLIAMS COMMUNICATIONS GROUP +00100B CISCO SYSTEMS, INC. +00100C ITO CO., LTD. +00100D CISCO SYSTEMS, INC. +00100E MICRO LINEAR COPORATION +00100F INDUSTRIAL CPU SYSTEMS +001010 INITIO CORPORATION +001011 CISCO SYSTEMS, INC. +001012 PROCESSOR SYSTEMS (I) PVT LTD +001013 INDUSTRIAL COMPUTER SOURCE +001014 CISCO SYSTEMS, INC. +001015 OOMON INC. +001016 T.SQWARE +001017 MICOS GMBH +001018 BROADCOM CORPORATION +001019 SIRONA DENTAL SYSTEMS +00101A PICTURETEL CORP. +00101B CORNET TECHNOLOGY, INC. +00101C OHM TECHNOLOGIES INTL, LLC +00101D WINBOND ELECTRONICS CORP. +00101E MATSUSHITA ELECTRONIC +00101F CISCO SYSTEMS, INC. +001020 WELCH ALLYN, DATA COLLECTION +001021 ENCANTO NETWORKS, INC. +001022 SATCOM MEDIA CORPORATION +001023 FLOWWISE NETWORKS, INC. +001024 NAGOYA ELECTRIC WORKS CO., LTD +001025 GRAYHILL INC. +001026 ACCELERATED NETWORKS, INC. +001027 L-3 COMMUNICATIONS EAST +001028 COMPUTER TECHNICA, INC. +001029 CISCO SYSTEMS, INC. +00102A ZF MICROSYSTEMS, INC. +00102B UMAX DATA SYSTEMS, INC. +00102C Lasat Networks A/S +00102D HITACHI SOFTWARE ENGINEERING +00102E NETWORK SYSTEMS & TECHNOLOGIES +00102F CISCO SYSTEMS, INC. +001030 WI-LAN, INC. +001031 OBJECTIVE COMMUNICATIONS, INC. +001032 ALTA TECHNOLOGY +001033 ACCESSLAN COMMUNICATIONS, INC. +001034 GNP COMPUTERS +001035 ELITEGROUP COMPUTER +001036 INTER-TEL INTEGRATED SYSTEMS +001037 CYQ'VE TECHNOLOGY CO., LTD. +001038 MICRO RESEARCH INSTITUTE, INC. +001039 VECTRON SYSTEMS GMBH +00103A DIAMOND NETWORK TECH +00103B HIPPI NETWORKING FORUM +00103C IC ENSEMBLE, INC. +00103D PHASECOM, LTD. +00103E NETSCHOOLS CORPORATION +00103F TOLLGRADE COMMUNICATIONS, INC. +001040 INTERMEC CORPORATION +001041 BRISTOL BABCOCK, INC. +001042 ALACRITECH +001043 A2 CORPORATION +001044 INNOLABS CORPORATION +001045 Nortel Networks +001046 ALCORN MCBRIDE INC. +001047 ECHO ELETRIC CO. LTD. +001048 HTRC AUTOMATION, INC. +001049 SHORELINE TELEWORKS, INC. +00104A THE PARVUC CORPORATION +00104B 3COM CORPORATION +00104C COMPUTER ACCESS TECHNOLOGY +00104D SURTEC INDUSTRIES, INC. +00104E CEOLOGIC +00104F STORAGE TECHNOLOGY CORPORATION +001050 RION CO., LTD. +001051 CMICRO CORPORATION +001052 METTLER-TOLEDO (ALBSTADT) GMBH +001053 COMPUTER TECHNOLOGY CORP. +001054 CISCO SYSTEMS, INC. +001055 FUJITSU MICROELECTRONICS, INC. +001056 SODICK CO., LTD. +001057 Rebel.com, Inc. +001058 ARROWPOINT COMMUNICATIONS,INC. +001059 DIABLO RESEARCH CO. LLC +00105A 3COM CORPORATION +00105B NET INSIGHT AB +00105C QUANTUM DESIGNS (H.K.) LTD. +00105D DRAGER, BUSINESS UNIT +00105E HEKIMIAN LABORATORIES, INC. +00105F IN-SNEC +001060 BILLIONTON SYSTEMS, INC. +001061 HOSTLINK CORP. +001062 NX SERVER, ILNC. +001063 STARGUIDE DIGITAL NETWORKS +001064 DIGITAL EQUIPMENT CORP. +001065 RADYNE CORPORATION +001066 ADVANCED CONTROL SYSTEMS, INC. +001067 REDBACK NETWORKS, INC. +001068 COMOS TELECOM +001069 HELIOSS COMMUNICATIONS, INC. +00106A DIGITAL MICROWAVE CORPORATION +00106B SONUS NETWORKS, INC. +00106C INFRATEC PLUS GMBH +00106D INTEGRITY COMMUNICATIONS, INC. +00106E TADIRAN COM. LTD. +00106F TRENTON TECHNOLOGY INC. +001070 CARADON TREND LTD. +001071 ADVANET INC. +001072 GVN TECHNOLOGIES, INC. +001073 TECHNOBOX, INC. +001074 ATEN INTERNATIONAL CO., LTD. +001075 Maxtor Corporation +001076 EUREM GMBH +001077 SAF DRIVE SYSTEMS, LTD. +001078 NUERA COMMUNICATIONS, INC. +001079 CISCO SYSTEMS, INC. +00107A AMBICOM, INC. +00107B CISCO SYSTEMS, INC. +00107C P-COM, INC. +00107D AURORA COMMUNICATIONS, LTD. +00107E BACHMANN ELECTRONIC GMBH +00107F CRESTRON ELECTRONICS, INC. +001080 METAWAVE COMMUNICATIONS +001081 DPS, INC. +001082 JNA TELECOMMUNICATIONS LIMITED +001083 HEWLETT-PACKARD COMPANY +001084 K-BOT COMMUNICATIONS +001085 POLARIS COMMUNICATIONS, INC. +001086 ATTO TECHNOLOGY, INC. +001087 Xstreamis PLC +001088 AMERICAN NETWORKS INC. +001089 WEBSONIC +00108A TERALOGIC, INC. +00108B LASERANIMATION SOLLINGER GMBH +00108C FUJITSU TELECOMMUNICATIONS +00108D JOHNSON CONTROLS, INC. +00108E HUGH SYMONS CONCEPT +00108F RAPTOR SYSTEMS +001090 CIMETRICS, INC. +001091 NO WIRES NEEDED BV +001092 NETCORE INC. +001093 CMS COMPUTERS, LTD. +001094 ADTECH, INC. +001095 THOMSON CONSUMER ELECTRONICS +001096 TRACEWELL SYSTEMS, INC. +001097 WINNET METROPOLITAN +001098 STARNET TECHNOLOGIES, INC. +001099 INNOMEDIA, INC. +00109A NETLINE +00109B VIXEL CORPORATION +00109C M-SYSTEM CO., LTD. +00109D CLARINET SYSTEMS, INC. +00109E AWARE, INC. +00109F PAVO, INC. +0010A0 INNOVEX TECHNOLOGIES, INC. +0010A1 KENDIN SEMICONDUCTOR, INC. +0010A2 TNS +0010A3 OMNITRONIX, INC. +0010A4 XIRCOM +0010A5 OXFORD INSTRUMENTS +0010A6 CISCO SYSTEMS, INC. +0010A7 UNEX TECHNOLOGY CORPORATION +0010A8 RELIANCE COMPUTER CORP. +0010A9 ADHOC TECHNOLOGIES +0010AA MEDIA4, INC. +0010AB KOITO INDUSTRIES, LTD. +0010AC IMCI TECHNOLOGIES +0010AD SOFTRONICS USB, INC. +0010AE SHINKO ELECTRIC INDUSTRIES CO. +0010AF TAC SYSTEMS, INC. +0010B0 MERIDIAN TECHNOLOGY CORP. +0010B1 FOR-A CO., LTD. +0010B2 COACTIVE AESTHETICS +0010B3 NOKIA MULTIMEDIA TERMINALS +0010B4 ATMOSPHERE NETWORKS +0010B5 ACCTON TECHNOLOGY CORPORATION +0010B6 ENTRATA COMMUNICATIONS CORP. +0010B7 COYOTE TECHNOLOGIES, LLC +0010B8 ISHIGAKI COMPUTER SYSTEM CO. +0010B9 MAXTOR CORP. +0010BA MARTINHO-DAVIS SYSTEMS, INC. +0010BB DATA & INFORMATION TECHNOLOGY +0010BC Nortel Networks +0010BD THE TELECOMMUNICATION +0010BE TELEXIS CORP. +0010BF INTER AIR WIRELESS +0010C0 ARMA, INC. +0010C1 OI ELECTRIC CO., LTD. +0010C2 WILLNET, INC. +0010C3 CSI-CONTROL SYSTEMS +0010C4 MEDIA LINKS CO., LTD. +0010C5 PROTOCOL TECHNOLOGIES, INC. +0010C6 USI +0010C7 DATA TRANSMISSION NETWORK +0010C8 COMMUNICATIONS ELECTRONICS +0010C9 MITSUBISHI ELECTRONICS +0010CA INTEGRAL ACCESS +0010CB FACIT K.K. +0010CC CLP COMPUTER LOGISTIK +0010CD INTERFACE CONCEPT +0010CE VOLAMP, LTD. +0010CF FIBERLANE COMMUNICATIONS +0010D0 WITCOM, LTD. +0010D1 Top Layer Networks, Inc. +0010D2 NITTO TSUSHINKI CO., LTD +0010D3 GRIPS ELECTRONIC GMBH +0010D4 STORAGE COMPUTER CORPORATION +0010D5 IMASDE CANARIAS, S.A. +0010D6 ITT A/CD +0010D7 ARGOSY RESEARCH INC. +0010D8 CALISTA +0010D9 IBM JAPAN, FUJISAWA MT+D +0010DA MOTION ENGINEERING, INC. +0010DB NETSCREEN TECHNOLOGIES, INC. +0010DC MICRO-STAR INTERNATIONAL +0010DD ENABLE SEMICONDUCTOR, INC. +0010DE INTERNATIONAL DATACASTING +0010DF RISE COMPUTER INC. +0010E0 COBALT MICROSERVER, INC. +0010E1 S.I. TECH, INC. +0010E2 ARRAYCOMM, INC. +0010E3 COMPAQ COMPUTER CORPORATION +0010E4 NSI CORPORATION +0010E5 SOLECTRON TEXAS +0010E6 APPLIED INTELLIGENT +0010E7 BREEZECOM +0010E8 TELOCITY, INCORPORATED +0010E9 RAIDTEC LTD. +0010EA ADEPT TECHNOLOGY +0010EB SELSIUS SYSTEMS, ILNC. +0010EC RPCG, LLC +0010ED SUNDANCE TECHNOLOGY, INC. +0010EE CTI PRODUCTS, INC. +0010EF DB NETWORKS, INC. +0010F0 RITTAL-WERK RUDOLF LOH +0010F1 I-O CORPORATION +0010F2 ANTEC +0010F3 NEXCOM INTERNATIONAL CO., LTD. +0010F4 VERTICAL NETWORKS, INC. +0010F5 AMHERST SYSTEMS, INC. +0010F6 CISCO SYSTEMS, INC. +0010F7 IRIICHI TECHNOLOGIES +0010F8 KENWOOD TMI CORPORATION +0010F9 UNIQUE SYSTEMS, INC. +0010FA ZAYANTE, INC. +0010FB ZIDA TECHNOLOGIES LIMITED +0010FC BROADBAND NETWORKS, INC. +0010FD COCOM A/S +0010FE DIGITAL EQUIPMENT CORPORATION +0010FF CISCO SYSTEMS, INC. +001C7C PERQ SYSTEMS CORPORATION +002000 LEXMARK INTERNATIONAL, INC. +002001 DSP SOLUTIONS, INC. +002002 SERITECH ENTERPRISE CO., LTD. +002003 PIXEL POWER LTD. +002004 YAMATAKE-HONEYWELL CO., LTD. +002005 SIMPLE TECHNOLOGY +002006 GARRETT COMMUNICATIONS, INC. +002007 SFA, INC. +002008 CABLE & COMPUTER TECHNOLOGY +002009 PACKARD BELL ELEC., INC. +00200A SOURCE-COMM CORP. +00200B OCTAGON SYSTEMS CORP. +00200C ADASTRA SYSTEMS CORP. +00200D CARL ZEISS +00200E SATELLITE TECHNOLOGY MGMT, INC +00200F TANBAC CO., LTD. +002010 JEOL SYSTEM TECHNOLOGY CO. LTD +002011 CANOPUS CO., LTD. +002012 CAMTRONICS MEDICAL SYSTEMS +002013 DIVERSIFIED TECHNOLOGY, INC. +002014 GLOBAL VIEW CO., LTD. +002015 ACTIS COMPUTER SA +002016 SHOWA ELECTRIC WIRE & CABLE CO +002017 ORBOTECH +002018 CIS TECHNOLOGY INC. +002019 OHLER GMBH +00201A N-BASE SWITCH COMMUNICATIONS +00201B NORTHERN TELECOM/NETWORK +00201C EXCEL, INC. +00201D KATANA PRODUCTS +00201E NETQUEST CORPORATION +00201F BEST POWER TECHNOLOGY, INC. +002020 MEGATRON COMPUTER INDUSTRIES +002021 ALGORITHMS SOFTWARE PVT. LTD. +002022 TEKNIQUE, INC. +002023 T.C. TECHNOLOGIES PTY. LTD +002024 PACIFIC COMMUNICATION SCIENCES +002025 CONTROL TECHNOLOGY, INC. +002026 AMKLY SYSTEMS, INC. +002027 MING FORTUNE INDUSTRY CO., LTD +002028 WEST EGG SYSTEMS, INC. +002029 TELEPROCESSING PRODUCTS, INC. +00202A N.V. DZINE +00202B ADVANCED TELECOMMUNICATIONS +00202C WELLTRONIX CO., LTD. +00202D TAIYO CORPORATION +00202E DAYSTAR DIGITAL +00202F ZETA COMMUNICATIONS, LTD. +002030 ANALOG & DIGITAL SYSTEMS +002031 ERTEC GMBH +002032 ALCATEL TAISEL +002033 SYNAPSE TECHNOLOGIES, INC. +002034 ROTEC INDUSTRIEAUTOMATION GMBH +002035 IBM CORPORATION +002036 BMC SOFTWARE +002037 SEAGATE TECHNOLOGY +002038 VME MICROSYSTEMS INTERNATIONAL +002039 SCINETS +00203A DIGITAL BI0METRICS INC. +00203B WISDM LTD. +00203C EUROTIME AB +00203D NOVAR ELECTRONICS CORPORATION +00203E LOGICAN TECHNOLOGIES, INC. +00203F JUKI CORPORATION +002040 Motorola Broadband Communications Sector +002041 DATA NET +002042 DATAMETRICS CORP. +002043 NEURON COMPANY LIMITED +002044 GENITECH PTY LTD +002045 ION Networks, Inc. +002046 CIPRICO, INC. +002047 STEINBRECHER CORP. +002048 Marconi Communications +002049 COMTRON, INC. +00204A PRONET GMBH +00204B AUTOCOMPUTER CO., LTD. +00204C MITRON COMPUTER PTE LTD. +00204D INOVIS GMBH +00204E NETWORK SECURITY SYSTEMS, INC. +00204F DEUTSCHE AEROSPACE AG +002050 KOREA COMPUTER INC. +002051 PHOENIX DATA COMMUNUNICATIONS +002052 RAGULA SYSTEMS +002053 HUNTSVILLE MICROSYSTEMS, INC. +002054 EASTERN RESEARCH, INC. +002055 ALTECH CO., LTD. +002056 NEOPRODUCTS +002057 TITZE DATENTECHNIK GMBH +002058 ALLIED SIGNAL INC. +002059 MIRO COMPUTER PRODUCTS AG +00205A COMPUTER IDENTICS +00205B SKYLINE TECHNOLOGY +00205C INTERNET SYSTEMS/ FLORIDA INC. +00205D NANOMATIC OY +00205E CASTLE ROCK, INC. +00205F GAMMADATA COMPUTER GMBH +002060 ALCATEL ITALIA S.P.A. +002061 DYNATECH COMMUNICATIONS, INC. +002062 SCORPION LOGIC, LTD. +002063 WIPRO INFOTECH LTD. +002064 PROTEC MICROSYSTEMS, INC. +002065 SUPERNET NETWORKING INC. +002066 GENERAL MAGIC, INC. +002068 ISDYNE +002069 ISDN SYSTEMS CORPORATION +00206A OSAKA COMPUTER CORP. +00206B MINOLTA CO., LTD. +00206C EVERGREEN TECHNOLOGY CORP. +00206D DATA RACE, INC. +00206E XACT, INC. +00206F FLOWPOINT CORPORATION +002070 HYNET, LTD. +002071 IBR GMBH +002072 WORKLINK INNOVATIONS +002073 FUSION SYSTEMS CORPORATION +002074 SUNGWOON SYSTEMS +002075 MOTOROLA COMMUNICATION ISRAEL +002076 REUDO CORPORATION +002077 KARDIOS SYSTEMS CORP. +002078 RUNTOP, INC. +002079 MIKRON GMBH +00207A WISE COMMUNICATIONS, INC. +00207B LEVEL ONE COMMUNICATIONS +00207C AUTEC GMBH +00207D ADVANCED COMPUTER APPLICATIONS +00207E FINECOM CO., LTD. +00207F KYOEI SANGYO CO., LTD. +002080 SYNERGY (UK) LTD. +002081 TITAN ELECTRONICS +002082 ONEAC CORPORATION +002083 PRESTICOM INCORPORATED +002084 OCE PRINTING SYSTEMS, GMBH +002085 EXIDE ELECTRONICS +002086 MICROTECH ELECTRONICS LIMITED +002087 MEMOTEC COMMUNICATIONS CORP. +002088 GLOBAL VILLAGE COMMUNICATION +002089 T3PLUS NETWORKING, INC. +00208A SONIX COMMUNICATIONS, LTD. +00208B LAPIS TECHNOLOGIES, INC. +00208C GALAXY NETWORKS, INC. +00208D CMD TECHNOLOGY +00208E CHEVIN SOFTWARE ENG. LTD. +00208F ECI TELECOM LTD. +002090 ADVANCED COMPRESSION +002091 J125, NATIONAL SECURITY AGENCY +002092 CHESS ENGINEERING B.V. +002093 LANDINGS TECHNOLOGY CORP. +002094 CUBIX CORPORATION +002095 RIVA ELECTRONICS +002096 SIEBE ENVIRONMENTAL CONTROLS +002097 APPLIED SIGNAL TECHNOLOGY +002098 HECTRONIC AB +002099 BON ELECTRIC CO., LTD. +00209A THE 3DO COMPANY +00209B ERSAT ELECTRONIC GMBH +00209C PRIMARY ACCESS CORP. +00209D LIPPERT AUTOMATIONSTECHNIK +00209E BROWN'S OPERATING SYSTEM +00209F MERCURY COMPUTER SYSTEMS, INC. +0020A0 OA LABORATORY CO., LTD. +0020A1 DOVATRON +0020A2 GALCOM NETWORKING LTD. +0020A3 DIVICOM INC. +0020A4 MULTIPOINT NETWORKS +0020A5 API ENGINEERING +0020A6 PROXIM, INC. +0020A7 PAIRGAIN TECHNOLOGIES, INC. +0020A8 SAST TECHNOLOGY CORP. +0020A9 WHITE HORSE INDUSTRIAL +0020AA DIGIMEDIA VISION LTD. +0020AB MICRO INDUSTRIES CORP. +0020AC INTERFLEX DATENSYSTEME GMBH +0020AD LINQ SYSTEMS +0020AE ORNET DATA COMMUNICATION TECH. +0020AF 3COM CORPORATION +0020B0 GATEWAY DEVICES, INC. +0020B1 COMTECH RESEARCH INC. +0020B2 GKD GESELLSCHAFT FUR +0020B3 SCLTEC COMMUNICATIONS SYSTEMS +0020B4 TERMA ELEKTRONIK AS +0020B5 YASKAWA ELECTRIC CORPORATION +0020B6 AGILE NETWORKS, INC. +0020B7 NAMAQUA COMPUTERWARE +0020B8 PRIME OPTION, INC. +0020B9 METRICOM, INC. +0020BA CENTER FOR HIGH PERFORMANCE +0020BB ZAX CORPORATION +0020BC JTEC PTY LTD. +0020BD NIOBRARA R & D CORPORATION +0020BE LAN ACCESS CORP. +0020BF AEHR TEST SYSTEMS +0020C0 PULSE ELECTRONICS, INC. +0020C1 TAIKO ELECTRIC WORKS, LTD. +0020C2 TEXAS MEMORY SYSTEMS, INC. +0020C3 COUNTER SOLUTIONS LTD. +0020C4 INET,INC. +0020C5 EAGLE TECHNOLOGY +0020C6 NECTEC +0020C7 AKAI Professional M.I. Corp. +0020C8 LARSCOM INCORPORATED +0020C9 VICTRON BV +0020CA DIGITAL OCEAN +0020CB PRETEC ELECTRONICS CORP. +0020CC DIGITAL SERVICES, LTD. +0020CD HYBRID NETWORKS, INC. +0020CE LOGICAL DESIGN GROUP, INC. +0020CF TEST & MEASUREMENT SYSTEMS INC +0020D0 VERSALYNX CORPORATION +0020D1 MICROCOMPUTER SYSTEMS (M) SDN. +0020D2 RAD DATA COMMUNICATIONS, LTD. +0020D3 OST (OUEST STANDARD TELEMATIQU +0020D4 CABLETRON - ZEITTNET INC. +0020D5 VIPA GMBH +0020D6 BREEZECOM +0020D7 JAPAN MINICOMPUTER SYSTEMS CO. +0020D8 NETWAVE TECHNOLOGIES, INC. +0020D9 PANASONIC TECHNOLOGIES, INC./ +0020DA XYLAN CORPORATION +0020DB XNET TECHNOLOGY, INC. +0020DC DENSITRON TAIWAN LTD. +0020DD AWA LTD. +0020DE JAPAN DIGITAL LABORAT'Y CO.LTD +0020DF KYOSAN ELECTRIC MFG. CO., LTD. +0020E0 PREMAX ELECTRONICS, INC. +0020E1 ALAMAR ELECTRONICS +0020E2 INFORMATION RESOURCE +0020E3 MCD KENCOM CORPORATION +0020E4 HSING TECH ENTERPRISE CO., LTD +0020E5 APEX DATA, INC. +0020E6 LIDKOPING MACHINE TOOLS AB +0020E7 B&W NUCLEAR SERVICE COMPANY +0020E8 DATATREK CORPORATION +0020E9 DANTEL +0020EA EFFICIENT NETWORKS, INC. +0020EB CINCINNATI MICROWAVE, INC. +0020EC TECHWARE SYSTEMS CORP. +0020ED GIGA-BYTE TECHNOLOGY CO., LTD. +0020EE GTECH CORPORATION +0020EF USC CORPORATION +0020F0 UNIVERSAL MICROELECTRONICS CO. +0020F1 ALTOS INDIA LIMITED +0020F2 SUN MICROSYSTEMS, INC. +0020F3 RAYNET CORPORATION +0020F4 SPECTRIX CORPORATION +0020F5 PANDATEL AG +0020F6 NET TEK AND KARLNET, INC. +0020F7 CYBERDATA +0020F8 CARRERA COMPUTERS, INC. +0020F9 PARALINK NETWORKS, INC. +0020FA GDE SYSTEMS, INC. +0020FB OCTEL COMMUNICATIONS CORP. +0020FC MATROX +0020FD ITV TECHNOLOGIES, INC. +0020FE TOPWARE INC. / GRAND COMPUTER +0020FF SYMMETRICAL TECHNOLOGIES +003000 ALLWELL TECHNOLOGY CORP. +003001 SMP +003002 Expand Networks +003003 Phasys Ltd. +003004 LEADTEK RESEARCH INC. +003005 Fujitsu Siemens Computers +003006 SUPERPOWER COMPUTER +003007 OPTI, INC. +003008 AVIO DIGITAL, INC. +003009 Tachion Networks, Inc. +00300A AZTECH SYSTEMS LTD. +00300B mPHASE Technologies, Inc. +00300C CONGRUENCY, LTD. +00300D MMC Technology, Inc. +00300E Klotz Digital AG +00300F IMT - Information Management T +003010 VISIONETICS INTERNATIONAL +003011 HMS FIELDBUS SYSTEMS AB +003012 DIGITAL ENGINEERING LTD. +003013 NEC Corporation +003014 DIVIO, INC. +003015 CP CLARE CORP. +003016 ISHIDA CO., LTD. +003017 TERASTACK LTD. +003018 Jetway Information Co., Ltd. +003019 CISCO SYSTEMS, INC. +00301A SMARTBRIDGES PTE. LTD. +00301B SHUTTLE, INC. +00301C ALTVATER AIRDATA SYSTEMS +00301D SKYSTREAM, INC. +00301E 3COM Europe Ltd. +00301F OPTICAL NETWORKS, INC. +003020 TSI, Inc.. +003021 HSING TECH. ENTERPRISE CO.,LTD +003022 Fong Kai Industrial Co., Ltd. +003023 COGENT COMPUTER SYSTEMS, INC. +003024 CISCO SYSTEMS, INC. +003025 CHECKOUT COMPUTER SYSTEMS, LTD +003026 HEITEL +003027 KERBANGO, INC. +003028 FASE Saldatura srl +003029 OPICOM +00302A SOUTHERN INFORMATION +00302B INALP NETWORKS, INC. +00302C SYLANTRO SYSTEMS CORPORATION +00302D QUANTUM BRIDGE COMMUNICATIONS +00302E Hoft & Wessel AG +00302F Smiths Industries +003030 HARMONIX CORPORATION +003031 LIGHTWAVE COMMUNICATIONS, INC. +003032 MAGICRAM, INC. +003033 ORIENT TELECOM CO., LTD. +003036 RMP ELEKTRONIKSYSTEME GMBH +003037 Packard Bell Nec Services +003038 XCP, INC. +003039 SOFTBOOK PRESS +00303A MAATEL +00303B PowerCom Technology +00303C ONNTO CORP. +00303D IVA CORPORATION +00303E Radcom Ltd. +00303F TurboComm Tech Inc. +003040 CISCO SYSTEMS, INC. +003041 SAEJIN T & M CO., LTD. +003042 DeTeWe-Deutsche Telephonwerke +003043 IDREAM TECHNOLOGIES, PTE. LTD. +003044 Portsmith LLC +003045 Village Networks, Inc. (VNI) +003046 Controlled Electronic Manageme +003047 NISSEI ELECTRIC CO., LTD. +003048 Supermicro Computer, Inc. +003049 BRYANT TECHNOLOGY, LTD. +00304A FRAUNHOFER INSTITUTE IMS +00304B ORBACOM SYSTEMS, INC. +00304C APPIAN COMMUNICATIONS, INC. +00304D ESI +00304E BUSTEC PRODUCTION LTD. +00304F PLANET Technology Corporation +003050 Versa Technology +003051 ORBIT AVIONIC & COMMUNICATION +003052 ELASTIC NETWORKS +003053 Basler AG +003054 CASTLENET TECHNOLOGY, INC. +003055 Hitachi Semiconductor America, +003056 Beck IPC GmbH +003057 E-Tel Corporation +003058 API MOTION +003059 DIGITAL-LOGIC AG +00305A TELGEN CORPORATION +00305B MODULE DEPARTMENT +00305C SMAR Laboratories Corp. +00305D DIGITRA SYSTEMS, INC. +00305E Abelko Innovation +00305F IMACON APS +003060 STARMATIX, INC. +003061 MobyTEL +003062 PATH 1 NETWORK TECHNOL'S INC. +003063 SANTERA SYSTEMS, INC. +003064 ADLINK TECHNOLOGY, INC. +003065 APPLE COMPUTER, INC. +003066 DIGITAL WIRELESS CORPORATION +003067 BIOSTAR MICROTECH INT'L CORP. +003068 CYBERNETICS TECH. CO., LTD. +003069 IMPACCT TECHNOLOGY CORP. +00306A PENTA MEDIA CO., LTD. +00306B CMOS SYSTEMS, INC. +00306C Hitex Holding GmbH +00306D LUCENT TECHNOLOGIES +00306E HEWLETT PACKARD +00306F SEYEON TECH. CO., LTD. +003070 1Net Corporation +003071 Cisco Systems, Inc. +003072 INTELLIBYTE INC. +003073 International Microsystems, In +003074 EQUIINET LTD. +003075 ADTECH +003076 Akamba Corporation +003077 ONPREM NETWORKS +003078 Cisco Systems, Inc. +003079 CQOS, INC. +00307A Advanced Technology & Systems +00307B Cisco Systems, Inc. +00307C ADID SA +00307D GRE AMERICA, INC. +00307E Redflex Communication Systems +00307F IRLAN LTD. +003080 CISCO SYSTEMS, INC. +003081 ALTOS C&C +003082 TAIHAN ELECTRIC WIRE CO., LTD. +003083 Ivron Systems +003084 ALLIED TELESYN INTERNAIONAL +003085 CISCO SYSTEMS, INC. +003086 Transistor Devices, Inc. +003087 VEGA GRIESHABER KG +003088 Siara Systems, Inc. +003089 Spectrapoint Wireless, LLC +00308A NICOTRA SISTEMI S.P.A +00308B Brix Networks +00308C ADVANCED DIGITAL INFORMATION +00308D PINNACLE SYSTEMS, INC. +00308E CROSS MATCH TECHNOLOGIES, INC. +00308F MICRILOR, Inc. +003090 CYRA TECHNOLOGIES, INC. +003091 TAIWAN FIRST LINE ELEC. CORP. +003092 ModuNORM GmbH +003093 SONNET TECHNOLOGIES, INC. +003094 Cisco Systems, Inc. +003095 Procomp Informatics, Ltd. +003096 CISCO SYSTEMS, INC. +003097 EXOMATIC AB +003098 Global Converging Technologies +003099 BOENIG UND KALLENBACH OHG +00309A ASTRO TERRA CORP. +00309B Smartware +00309C Timing Applications, Inc. +00309D Nimble Microsystems, Inc. +00309E WORKBIT CORPORATION. +00309F AMBER NETWORKS +0030A0 TYCO SUBMARINE SYSTEMS, LTD. +0030A1 OPTI TECH CO., LTD. +0030A2 Lightner Engineering +0030A3 CISCO SYSTEMS, INC. +0030A4 Woodwind Communications System +0030A5 ACTIVE POWER +0030A6 VIANET TECHNOLOGIES, LTD. +0030A7 SCHWEITZER ENGINEERING +0030A8 OL'E COMMUNICATIONS, INC. +0030A9 Netiverse, Inc. +0030AA AXUS MICROSYSTEMS, INC. +0030AB DELTA NETWORKS, INC. +0030AC Systeme Lauer GmbH & Co., Ltd. +0030AD SHANGHAI COMMUNICATION +0030AE Times N System, Inc. +0030AF Honeywell Reqelsysteme GmbH +0030B0 Convergenet Technologies +0030B1 GOC GESELLSCHAFT FUR OPTISCHE +0030B2 WESCAM - HEALDSBURG +0030B3 San Valley Systems, Inc. +0030B4 INTERSIL CORP. +0030B5 Tadiran Microwave Networks +0030B6 CISCO SYSTEMS, INC. +0030B7 Teletrol Systems, Inc. +0030B8 RiverDelta Networks +0030B9 ECTEL +0030BA AC&T SYSTEM CO., LTD. +0030BB CacheFlow, Inc. +0030BC Optronic AG +0030BD BELKIN COMPONENTS +0030BE City-Net Technology, Inc. +0030BF MULTIDATA GMBH +0030C0 Lara Technology, Inc. +0030C1 HEWLETT-PACKARD +0030C2 COMONE +0030C3 FLUECKIGER ELEKTRONIK AG +0030C4 Niigata Canotec Co., Inc. +0030C5 CADENCE DESIGN SYSTEMS +0030C6 CONTROL SOLUTIONS, INC. +0030C7 MACROMATE CORP. +0030C8 GAD LINE, LTD. +0030C9 LuxN, N +0030CA Discovery Com +0030CB OMNI FLOW COMPUTERS, INC. +0030CC Tenor Networks, Inc. +0030CD CONEXANT SYSTEMS, INC. +0030CE Zaffire +0030CF TWO TECHNOLOGIES, INC. +0030D1 INOVA CORPORATION +0030D2 WIN TECHNOLOGIES, CO., LTD. +0030D3 Agilent Technologies +0030D4 COMTIER +0030D5 DResearch GmbH +0030D6 MSC VERTRIEBS GMBH +0030D7 Innovative Systems, L.L.C. +0030D8 SITEK +0030D9 DATACORE SOFTWARE CORP. +0030DA COMTREND CO. +0030DB Mindready Solutions, Inc. +0030DC RIGHTECH CORPORATION +0030DD INDIGITA CORPORATION +0030DE WAGO Kontakttechnik GmbH +0030DF KB/TEL TELECOMUNICACIONES +0030E0 OXFORD SEMICONDUCTOR LTD. +0030E1 ACROTRON SYSTEMS, INC. +0030E2 GARNET SYSTEMS CO., LTD. +0030E3 SEDONA NETWORKS CORP. +0030E4 CHIYODA SYSTEM RIKEN +0030E5 Amper Datos S.A. +0030E6 SIEMENS MEDICAL SYSTEMS +0030E7 CNF MOBILE SOLUTIONS, INC. +0030E8 ENSIM CORP. +0030E9 GMA COMMUNICATION MANUFACT'G +0030EA TeraForce Technology Corporation +0030EB TURBONET COMMUNICATIONS, INC. +0030EC BORGARDT +0030ED Expert Magnetics Corp. +0030EE DSG Technology, Inc. +0030EF NEON TECHNOLOGY, INC. +0030F0 Uniform Industrial Corp. +0030F1 Accton Technology Corp. +0030F2 CISCO SYSTEMS, INC. +0030F3 At Work Computers +0030F4 STARDOT TECHNOLOGIES +0030F5 Wild Lab. Ltd. +0030F6 SECURELOGIX CORPORATION +0030F7 RAMIX INC. +0030F8 Dynapro Systems, Inc. +0030F9 Sollae Systems Co., Ltd. +0030FA TELICA, INC. +0030FB AZS Technology AG +0030FC Terawave Communications, Inc. +0030FD INTEGRATED SYSTEMS DESIGN +0030FE DSA GmbH +0030FF DATAFAB SYSTEMS, INC. +004000 PCI COMPONENTES DA AMZONIA LTD +004001 ZYXEL COMMUNICATIONS, INC. +004002 PERLE SYSTEMS LIMITED +004003 WESTINGHOUSE PROCESS CONTROL +004004 ICM CO. LTD. +004005 ANI COMMUNICATIONS INC. +004006 SAMPO TECHNOLOGY CORPORATION +004007 TELMAT INFORMATIQUE +004008 A PLUS INFO CORPORATION +004009 TACHIBANA TECTRON CO., LTD. +00400A PIVOTAL TECHNOLOGIES, INC. +00400B CISCO SYSTEMS, INC. +00400C GENERAL MICRO SYSTEMS, INC. +00400D LANNET DATA COMMUNICATIONS,LTD +00400E MEMOTEC COMMUNICATIONS, INC. +00400F DATACOM TECHNOLOGIES +004010 SONIC SYSTEMS, INC. +004011 ANDOVER CONTROLS CORPORATION +004012 WINDATA, INC. +004013 NTT DATA COMM. SYSTEMS CORP. +004014 COMSOFT GMBH +004015 ASCOM INFRASYS AG +004016 HADAX ELECTRONICS, INC. +004017 XCD INC. +004018 ADOBE SYSTEMS, INC. +004019 AEON SYSTEMS, INC. +00401A FUJI ELECTRIC CO., LTD. +00401B PRINTER SYSTEMS CORP. +00401C AST RESEARCH, INC. +00401D INVISIBLE SOFTWARE, INC. +00401E ICC +00401F COLORGRAPH LTD +004020 PINACL COMMUNICATION +004021 RASTER GRAPHICS +004022 KLEVER COMPUTERS, INC. +004023 LOGIC CORPORATION +004024 COMPAC INC. +004025 MOLECULAR DYNAMICS +004026 MELCO, INC. +004027 SMC MASSACHUSETTS, INC. +004028 NETCOMM LIMITED +004029 COMPEX +00402A CANOGA-PERKINS +00402B TRIGEM COMPUTER, INC. +00402C ISIS DISTRIBUTED SYSTEMS, INC. +00402D HARRIS ADACOM CORPORATION +00402E PRECISION SOFTWARE, INC. +00402F XLNT DESIGNS INC. +004030 GK COMPUTER +004031 KOKUSAI ELECTRIC CO., LTD +004032 DIGITAL COMMUNICATIONS +004033 ADDTRON TECHNOLOGY CO., LTD. +004034 BUSTEK CORPORATION +004035 OPCOM +004036 TRIBE COMPUTER WORKS, INC. +004037 SEA-ILAN, INC. +004038 TALENT ELECTRIC INCORPORATED +004039 OPTEC DAIICHI DENKO CO., LTD. +00403A IMPACT TECHNOLOGIES +00403B SYNERJET INTERNATIONAL CORP. +00403C FORKS, INC. +00403D TERADATA +00403E RASTER OPS CORPORATION +00403F SSANGYONG COMPUTER SYSTEMS +004040 RING ACCESS, INC. +004041 FUJIKURA LTD. +004042 N.A.T. GMBH +004043 NOKIA TELECOMMUNICATIONS +004044 QNIX COMPUTER CO., LTD. +004045 TWINHEAD CORPORATION +004046 UDC RESEARCH LIMITED +004047 WIND RIVER SYSTEMS +004048 SMD INFORMATICA S.A. +004049 TEGIMENTA AG +00404A WEST AUSTRALIAN DEPARTMENT +00404B MAPLE COMPUTER SYSTEMS +00404C HYPERTEC PTY LTD. +00404D TELECOMMUNICATIONS TECHNIQUES +00404E FLUENT, INC. +00404F SPACE & NAVAL WARFARE SYSTEMS +004050 IRONICS, INCORPORATED +004051 GRACILIS, INC. +004052 STAR TECHNOLOGIES, INC. +004053 AMPRO COMPUTERS +004054 CONNECTION MACHINES SERVICES +004055 METRONIX GMBH +004056 MCM JAPAN LTD. +004057 LOCKHEED - SANDERS +004058 KRONOS, INC. +004059 YOSHIDA KOGYO K. K. +00405A GOLDSTAR INFORMATION & COMM. +00405B FUNASSET LIMITED +00405C FUTURE SYSTEMS, INC. +00405D STAR-TEK, INC. +00405E NORTH HILLS ISRAEL +00405F AFE COMPUTERS LTD. +004060 COMENDEC LTD +004061 DATATECH ENTERPRISES CO., LTD. +004062 E-SYSTEMS, INC./GARLAND DIV. +004063 VIA TECHNOLOGIES, INC. +004064 KLA INSTRUMENTS CORPORATION +004065 GTE SPACENET +004066 HITACHI CABLE, LTD. +004067 OMNIBYTE CORPORATION +004068 EXTENDED SYSTEMS +004069 LEMCOM SYSTEMS, INC. +00406A KENTEK INFORMATION SYSTEMS,INC +00406B SYSGEN +00406C COPERNIQUE +00406D LANCO, INC. +00406E COROLLARY, INC. +00406F SYNC RESEARCH INC. +004070 INTERWARE CO., LTD. +004071 ATM COMPUTER GMBH +004072 APPLIED INNOVATION, INC. +004073 BASS ASSOCIATES +004074 CABLE AND WIRELESS +004075 M-TRADE (UK) LTD +004076 Sun Conversion Technologies +004077 MAXTON TECHNOLOGY CORPORATION +004078 WEARNES AUTOMATION PTE LTD +004079 JUKO MANUFACTURE COMPANY, LTD. +00407A SOCIETE D'EXPLOITATION DU CNIT +00407B SCIENTIFIC ATLANTA +00407C QUME CORPORATION +00407D EXTENSION TECHNOLOGY CORP. +00407E EVERGREEN SYSTEMS, INC. +00407F AGEMA INFRARED SYSTEMS AB +004080 ATHENIX CORPORATION +004081 MANNESMANN SCANGRAPHIC GMBH +004082 LABORATORY EQUIPMENT CORP. +004083 TDA INDUSTRIA DE PRODUTOS +004084 HONEYWELL INC. +004085 SAAB INSTRUMENTS AB +004086 MICHELS & KLEBERHOFF COMPUTER +004087 UBITREX CORPORATION +004088 MOBIUS TECHNOLOGIES, INC. +004089 MEIDENSHA CORPORATION +00408A TPS TELEPROCESSING SYS. GMBH +00408B RAYLAN CORPORATION +00408C AXIS COMMUNICATIONS AB +00408D THE GOODYEAR TIRE & RUBBER CO. +00408E DIGILOG, INC. +00408F WM-DATA MINFO AB +004090 ANSEL COMMUNICATIONS +004091 PROCOMP INDUSTRIA ELETRONICA +004092 ASP COMPUTER PRODUCTS, INC. +004093 PAXDATA NETWORKS LTD. +004094 SHOGRAPHICS, INC. +004095 R.P.T. INTERGROUPS INT'L LTD. +004096 Aironet Wireless Communication +004097 DATEX DIVISION OF +004098 DRESSLER GMBH & CO. +004099 NEWGEN SYSTEMS CORP. +00409A NETWORK EXPRESS, INC. +00409B HAL COMPUTER SYSTEMS INC. +00409C TRANSWARE +00409D DIGIBOARD, INC. +00409E CONCURRENT TECHNOLOGIES LTD. +00409F LANCAST/CASAT TECHNOLOGY, INC. +0040A0 GOLDSTAR CO., LTD. +0040A1 ERGO COMPUTING +0040A2 KINGSTAR TECHNOLOGY INC. +0040A3 MICROUNITY SYSTEMS ENGINEERING +0040A4 ROSE ELECTRONICS +0040A5 CLINICOMP INTL. +0040A6 Cray, Inc. +0040A7 ITAUTEC PHILCO S.A. +0040A8 IMF INTERNATIONAL LTD. +0040A9 DATACOM INC. +0040AA VALMET AUTOMATION INC. +0040AB ROLAND DG CORPORATION +0040AC SUPER WORKSTATION, INC. +0040AD SMA REGELSYSTEME GMBH +0040AE DELTA CONTROLS, INC. +0040AF DIGITAL PRODUCTS, INC. +0040B0 BYTEX CORPORATION, ENGINEERING +0040B1 CODONICS INC. +0040B2 SYSTEMFORSCHUNG +0040B3 PAR MICROSYSTEMS CORPORATION +0040B4 NEXTCOM K.K. +0040B5 VIDEO TECHNOLOGY COMPUTERS LTD +0040B6 COMPUTERM CORPORATION +0040B7 STEALTH COMPUTER SYSTEMS +0040B8 IDEA ASSOCIATES +0040B9 MACQ ELECTRONIQUE SA +0040BA ALLIANT COMPUTER SYSTEMS CORP. +0040BB GOLDSTAR CABLE CO., LTD. +0040BC ALGORITHMICS LTD. +0040BD STARLIGHT NETWORKS, INC. +0040BE BOEING DEFENSE & SPACE +0040BF CHANNEL SYSTEMS INTERN'L INC. +0040C0 VISTA CONTROLS CORPORATION +0040C1 BIZERBA-WERKE WILHEIM KRAUT +0040C2 APPLIED COMPUTING DEVICES +0040C3 FISCHER AND PORTER CO. +0040C4 KINKEI SYSTEM CORPORATION +0040C5 MICOM COMMUNICATIONS INC. +0040C6 FIBERNET RESEARCH, INC. +0040C7 RUBY TECH CORPORATION +0040C8 MILAN TECHNOLOGY CORPORATION +0040C9 NCUBE +0040CA FIRST INTERNAT'L COMPUTER, INC +0040CB LANWAN TECHNOLOGIES +0040CC SILCOM MANUF'G TECHNOLOGY INC. +0040CD TERA MICROSYSTEMS, INC. +0040CE NET-SOURCE, INC. +0040CF STRAWBERRY TREE, INC. +0040D0 MITAC INTERNATIONAL CORP. +0040D1 FUKUDA DENSHI CO., LTD. +0040D2 PAGINE CORPORATION +0040D3 KIMPSION INTERNATIONAL CORP. +0040D4 GAGE TALKER CORP. +0040D5 SARTORIUS AG +0040D6 LOCAMATION B.V. +0040D7 STUDIO GEN INC. +0040D8 OCEAN OFFICE AUTOMATION LTD. +0040D9 AMERICAN MEGATRENDS INC. +0040DA TELSPEC LTD +0040DB ADVANCED TECHNICAL SOLUTIONS +0040DC TRITEC ELECTRONIC GMBH +0040DD HONG TECHNOLOGIES +0040DE ELETTRONICA SAN GIORGIO +0040DF DIGALOG SYSTEMS, INC. +0040E0 ATOMWIDE LTD. +0040E1 MARNER INTERNATIONAL, INC. +0040E2 MESA RIDGE TECHNOLOGIES, INC. +0040E3 QUIN SYSTEMS LTD +0040E4 E-M TECHNOLOGY, INC. +0040E5 SYBUS CORPORATION +0040E6 C.A.E.N. +0040E7 ARNOS INSTRUMENTS & COMPUTER +0040E8 CHARLES RIVER DATA SYSTEMS,INC +0040E9 ACCORD SYSTEMS, INC. +0040EA PLAIN TREE SYSTEMS INC +0040EB MARTIN MARIETTA CORPORATION +0040EC MIKASA SYSTEM ENGINEERING +0040ED NETWORK CONTROLS INT'NATL INC. +0040EE OPTIMEM +0040EF HYPERCOM, INC. +0040F0 MICRO SYSTEMS, INC. +0040F1 CHUO ELECTRONICS CO., LTD. +0040F2 JANICH & KLASS COMPUTERTECHNIK +0040F3 NETCOR +0040F4 CAMEO COMMUNICATIONS, INC. +0040F5 OEM ENGINES +0040F6 KATRON COMPUTERS INC. +0040F7 POLAROID MEDICAL IMAGING SYS. +0040F8 SYSTEMHAUS DISCOM +0040F9 COMBINET +0040FA MICROBOARDS, INC. +0040FB CASCADE COMMUNICATIONS CORP. +0040FC IBR COMPUTER TECHNIK GMBH +0040FD LXE +0040FE SYMPLEX COMMUNICATIONS +0040FF TELEBIT CORPORATION +005000 NEXO COMMUNICATIONS, INC. +005001 YAMASHITA SYSTEMS CORP. +005002 OMNISEC AG +005003 GRETAG MACBETH AG +005004 3COM CORPORATION +005006 TAC AB +005007 SIEMENS TELECOMMUNICATION +005008 TIVA MICROCOMPUTER CORP. (TMC) +005009 PHILIPS BROADBAND NETWORKS +00500A IRIS TECHNOLOGIES, INC. +00500B CISCO SYSTEMS, INC. +00500C ETEK LABS, INC. +00500D SATORI ELECTORIC CO., LTD. +00500E CHROMATIS NETWORKS,INC. +00500F CISCO SYSTEMS, INC. +005010 NOVANET LEARNING, INC. +005012 CBL - GMBH +005013 Chaparral Technologies, Inc. +005014 CISCO SYSTEMS, INC. +005015 BRIGHT STAR ENGINEERING +005016 SST/WOODHEAD INDUSTRIES +005017 RSR S.R.L. +005018 ADVANCED MULTIMEDIA INTERNET +005019 SPRING TIDE NETWORKS, INC. +00501A UISIQN +00501B ABL CANADA, INC. +00501C JATOM SYSTEMS, INC. +00501E MIRANDA TECHNOLOGIES, INC. +00501F MRG SYSTEMS, LTD. +005020 MEDIASTAR CO., LTD. +005021 EIS INTERNATIONAL, INC. +005022 ZONET TECHNOLOGY, INC. +005023 PG DESIGN ELECTRONICS, INC. +005024 NAVIC SYSTEMS, INC. +005026 COSYSTEMS, INC. +005027 GENICOM CORPORATION +005028 AVAL COMMUNICATIONS +005029 1394 PRINTER WORKING GROUP +00502A CISCO SYSTEMS, INC. +00502B GENRAD LTD. +00502C SOYO COMPUTER, INC. +00502D ACCEL, INC. +00502E CAMBEX CORPORATION +00502F TOLLBRIDGE TECHNOLOGIES, INC. +005030 FUTURE PLUS SYSTEMS +005031 AEROFLEX LABORATORIES, INC. +005032 PICAZO COMMUNICATIONS, INC. +005033 MAYAN NETWORKS +005036 NETCAM, LTD. +005037 KOGA ELECTRONICS CO. +005038 DAIN TELECOM CO., LTD. +005039 MARINER NETWORKS +00503A DATONG ELECTRONICS LTD. +00503B MEDIAFIRE CORPORATION +00503C TSINGHUA NOVEL ELECTRONICS +00503E CISCO SYSTEMS, INC. +00503F ANCHOR GAMES +005040 EMWARE, INC. +005041 CTX OPTO ELECTRONIC CORP. +005042 SCI MANUFACTURING +005043 MARVELL SEMICONDUCTOR, INC. +005044 ASACA CORPORATION +005045 RIOWORKS SOLUTIONS, INC. +005046 MENICX INTERNATIONAL CO., LTD. +005048 INFOLIBRIA +005049 ELLACOYA NETWORKS, INC. +00504A ELTECO A.S. +00504B BARCONET N.V. +00504C GALIL MOTION CONTROL, INC. +00504D TOKYO ELECTRON DEVICE LTD. +00504E SIERRA MONITOR CORP. +00504F OLENCOM ELECTRONICS +005050 CISCO SYSTEMS, INC. +005051 IWATSU ELECTRIC CO., LTD. +005052 TIARA NETWORKS, INC. +005053 CISCO SYSTEMS, INC. +005054 CISCO SYSTEMS, INC. +005055 DOMS A/S +005056 VMWARE, INC. +005057 BROADBAND ACCESS SYSTEMS +005058 VEGASTREAM LIMITED +005059 SUITE TECHNOLOGY SYSTEMS +00505A NETWORK ALCHEMY, INC. +00505B KAWASAKI LSI U.S.A., INC. +00505C TUNDO CORPORATION +00505E DIGITEK MICROLOGIC S.A. +00505F BRAND INNOVATORS +005060 TANDBERG TELECOM AS +005062 KOUWELL ELECTRONICS CORP. ** +005063 OY COMSEL SYSTEM AB +005064 CAE ELECTRONICS +005065 DENSEI-LAMBAD Co., Ltd. +005066 ATECOM GMBH ADVANCED +005067 AEROCOMM, INC. +005068 ELECTRONIC INDUSTRIES +005069 PIXSTREAM INCORPORATED +00506A EDEVA, INC. +00506B SPX-ATEG +00506C G & L BEIJER ELECTRONICS AB +00506D VIDEOJET SYSTEMS +00506E CORDER ENGINEERING CORPORATION +00506F G-CONNECT +005070 CHAINTECH COMPUTER CO., LTD. +005071 AIWA CO., LTD. +005072 CORVIS CORPORATION +005073 CISCO SYSTEMS, INC. +005074 ADVANCED HI-TECH CORP. +005075 KESTREL SOLUTIONS +005076 IBM +005077 PROLIFIC TECHNOLOGY, INC. +005078 MEGATON HOUSE, LTD. +00507A XPEED, INC. +00507B MERLOT COMMUNICATIONS +00507C VIDEOCON AG +00507D IFP +00507E NEWER TECHNOLOGY +00507F DRAYTEK CORP. +005080 CISCO SYSTEMS, INC. +005081 MURATA MACHINERY, LTD. +005082 FORESSON CORPORATION +005083 GILBARCO, INC. +005084 ATL PRODUCTS +005086 TELKOM SA, LTD. +005087 TERASAKI ELECTRIC CO., LTD. +005088 AMANO CORPORATION +005089 SAFETY MANAGEMENT SYSTEMS +00508B COMPAQ COMPUTER CORPORATION +00508C RSI SYSTEMS +00508D ABIT COMPUTER CORPORATION +00508E OPTIMATION, INC. +00508F ASITA TECHNOLOGIES INT'L LTD. +005090 DCTRI +005091 NETACCESS, INC. +005092 RIGAKU INDUSTRIAL CORPORATION +005093 BOEING +005094 PACE MICRO TECHNOLOGY PLC +005095 PERACOM NETWORKS +005096 SALIX TECHNOLOGIES, INC. +005097 MMC-EMBEDDED +005098 GLOBALOOP, LTD. +005099 3COM EUROPE, LTD. +00509A TAG ELECTRONIC SYSTEMS +00509B SWITCHCORE AB +00509C BETA RESEARCH +00509D THE INDUSTREE B.V. +00509E LES TECHNOLOGIES +00509F HORIZON COMPUTER +0050A0 DELTA COMPUTER SYSTEMS, INC. +0050A1 CARLO GAVAZZI, INC. +0050A2 CISCO SYSTEMS, INC. +0050A3 TRANSMEDIA COMMUNICATIONS, INC +0050A4 IO TECH, INC. +0050A5 CAPITOL BUSINESS SYSTEMS, LTD. +0050A6 OPTRONICS +0050A7 CISCO SYSTEMS, INC. +0050A8 OPENCON SYSTEMS, INC. +0050A9 MOLDAT WIRELESS TECHNOLGIES +0050AA KONICA CORPORATION +0050AB NALTEC, INC. +0050AC MAPLE COMPUTER CORPORATION +0050AD COMMUNIQUE WIRELESS CORP. +0050AE IWAKI ELECTRONICS CO., LTD. +0050AF INTERGON, INC. +0050B0 TECHNOLOGY ATLANTA CORPORATION +0050B1 GIDDINGS & LEWIS +0050B2 BRODEL AUTOMATION +0050B3 VOICEBOARD CORPORATION +0050B4 SATCHWELL CONTROL SYSTEMS, LTD +0050B5 FICHET-BAUCHE +0050B6 GOOD WAY IND. CO., LTD. +0050B7 BOSER TECHNOLOGY CO., LTD. +0050B8 INOVA COMPUTERS GMBH & CO. KG +0050B9 XITRON TECHNOLOGIES, INC. +0050BA D-LINK +0050BB CMS TECHNOLOGIES +0050BC HAMMER STORAGE SOLUTIONS +0050BD CISCO SYSTEMS, INC. +0050BE FAST MULTIMEDIA AG +0050BF MOTOTECH INC. +0050C0 GATAN, INC. +0050C1 GEMFLEX NETWORKS, LTD. +0050C2 IEEE REGISTRATION AUTHORITY +0050C4 IMD +0050C5 ADS TECHNOLOGIES, INC. +0050C6 LOOP TELECOMMUNICATION +0050C8 ADDONICS COMMUNICATIONS, INC. +0050C9 MASPRO DENKOH CORP. +0050CA NET TO NET TECHNOLOGIES +0050CB JETTER +0050CC XYRATEX +0050CD DIGIANSWER A/S +0050CE LG INTERNATIONAL CORP. +0050CF VANLINK COMMUNICATION +0050D0 MINERVA SYSTEMS +0050D1 CISCO SYSTEMS, INC. +0050D2 BAE Systems Canada, Inc. +0050D3 DIGITAL AUDIO +0050D4 JOOHONG INFORMATION & +0050D5 AD SYSTEMS CORP. +0050D6 ATLAS COPCO TOOLS AB +0050D7 TELSTRAT +0050D8 UNICORN COMPUTER CORP. +0050D9 ENGETRON-ENGENHARIA ELETRONICA +0050DA 3COM CORPORATION +0050DB CONTEMPORARY CONTROL +0050DC TAS TELEFONBAU A. SCHWABE +0050DD SERRA SOLDADURA, S.A. +0050DE SIGNUM SYSTEMS CORP. +0050DF AIRFIBER, INC. +0050E1 NS TECH ELECTRONICS SDN BHD +0050E2 CISCO SYSTEMS, INC. +0050E3 TELEGATE +0050E4 APPLE COMPUTER, INC. +0050E6 HAKUSAN CORPORATION +0050E7 PARADISE INNOVATIONS (ASIA) +0050E8 NOMADIX INC. +0050EA XEL COMMUNICTIONS, INC. +0050EB ALPHA-TOP CORPORATION +0050EC OLICOM A/S +0050ED ANDA NETWORKS +0050EE TEK DIGITEL CORPORATION +0050EF SPE SYSTEMHAUS GMBH +0050F0 CISCO SYSTEMS, INC. +0050F1 LIBIT SIGNAL PROCESSING, LTD. +0050F2 MICROSOFT CORP. +0050F3 GLOBAL NET INFORMATION CO.,LTD +0050F4 SIGMATEK GMBH & CO. KG +0050F6 PAN-INTERNATIONAL +0050F7 VENTURE MANUFACTURING +0050F8 ENTREGA TECHNOLOGIES, INC. +0050FA OXTEL, LTD. +0050FB VSK ELECTRONICS +0050FC EDIMAX TECHNOLOGY CO., LTD. +0050FD ISIONCOMM CO., LTD. +0050FE PCTVNET ASA +0050FF HAKKO ELECTRONICS CO., LTD. +006000 XYCOM INC. +006001 INNOSYS, INC. +006002 SCREEN SUBTITLING SYSTEMS, LTD +006003 TERAOKA WEIGH SYSTEM PTE, LTD. +006004 COMPUTADORES MODULARES SA +006005 FEEDBACK DATA LTD. +006006 SOTEC CO., LTD +006007 ACRES GAMING, INC. +006008 3COM CORPORATION +006009 CISCO SYSTEMS, INC. +00600A SORD COMPUTER CORPORATION +00600B LOGWARE GMBH +00600C APPLIED DATA SYSTEMS, INC. +00600D MICRODESIGN GMBH +00600E WAVENET INTERNATIONAL, INC. +00600F WESTELL, INC. +006010 NETWORK MACHINES, INC. +006011 CRYSTAL SEMICONDUCTOR CORP. +006012 POWER COMPUTING CORPORATION +006013 NETSTAL MASCHINEN AG +006014 EDEC CO., LTD. +006015 NET2NET CORPORATION +006016 CLARIION +006017 TOKIMEC INC. +006018 STELLAR ONE CORPORATION +006019 BOEHRINGER MANNHEIM CORP. +00601A KEITHLEY INSTRUMENTS +00601B MESA ELECTRONICS +00601C TELXON CORPORATION +00601D LUCENT TECHNOLOGIES +00601E SOFTLAB, INC. +00601F STALLION TECHNOLOGIES +006020 PIVOTAL NETWORKING, INC. +006021 DSC CORPORATION +006022 VICOM SYSTEMS, INC. +006023 PERICOM SEMICONDUCTOR CORP. +006024 GRADIENT TECHNOLOGIES, INC. +006025 ACTIVE IMAGING PLC +006026 VIKING COMPONENTS, INC. +006027 Superior Modular Products +006028 MACROVISION CORPORATION +006029 CARY PERIPHERALS INC. +00602A SYMICRON COMPUTER +00602B PEAK AUDIO +00602C LINX DATA TERMINALS, INC. +00602D ALERTON TECHNOLOGIES, INC. +00602E CYCLADES CORPORATION +00602F CISCO SYSTEMS, INC. +006030 VILLAGE TRONIC +006031 HRK SYSTEMS +006032 I-CUBE, INC. +006033 ACUITY IMAGING, INC. +006034 ROBERT BOSCH GMBH +006035 DALLAS SEMICONDUCTOR, INC. +006036 AUSTRIAN RESEARCH CENTER +006037 PHILIPS SEMICONDUCTORS +006038 Nortel Networks +006039 SANCOM TECHNOLOGY, INC. +00603A QUICK CONTROLS LTD. +00603B AMTEC SPA +00603C HAGIWARA SYS-COM CO., LTD. +00603D 3CX +00603E CISCO SYSTEMS, INC. +00603F PATAPSCO DESIGNS +006040 NETRO CORP. +006041 Yokogawa Electric Corporation +006042 TKS (USA), INC. +006043 COMSOFT SYSTEMS, INC. +006044 LITTON/POLY-SCIENTIFIC +006045 PATHLIGHT TECHNOLOGIES +006046 VMETRO, INC. +006047 CISCO SYSTEMS, INC. +006048 EMC CORPORATION +006049 VINA TECHNOLOGIES +00604A SAIC IDEAS GROUP +00604B BIODATA GMBH +00604C SAT +00604D MMC NETWORKS, INC. +00604E CYCLE COMPUTER CORPORATION, INC. +00604F SUZUKI MFG. CO., LTD. +006050 INTERNIX INC. +006051 QUALITY SEMICONDUCTOR +006052 PERIPHERALS ENTERPRISE CO., L. +006053 TOYODA MACHINE WORKS, LTD. +006054 CONTROLWARE GMBH +006055 CORNELL UNIVERSITY +006056 NETWORK TOOLS, INC. +006057 MURATA MANUFACTURING CO., LTD. +006058 COPPER MOUNTAIN +006059 TECHNICAL COMMUNICATIONS CORP. +00605A CELCORE, INC. +00605B INTRASERVER TECHNOLOGY INC. +00605C CISCO SYSTEMS, INC. +00605D SCANIVALVE CORP. +00605E LIBERTY TECHNOLOGY NETWORKING +00605F NIPPON UNISOFT CORPORATION +006060 DAWNING TECHNOLOGIES, INC. +006061 WHISTLE COMMUNICATIONS CORP. +006062 TELESYNC, INC. +006063 PSION DACOM PLC. +006064 NETCOMM LIMITED +006065 BERNECKER & RAINER +006066 LACROIX TECHNOLGIE +006067 ACER NETXUS INC. +006068 EICON TECHNOLOGY CORPORATION +006069 BROCADE COMMUNICATIONS SYSTEMS +00606A MITSUBISHI WIRELESS COMM. INC. +00606B AICHI ELECTRONICS CO.,LTD. +00606C ARESCOM +00606D DIGITAL EQUIPMENT CORP. +00606E DAVICOM SEMICONDUCTOR, INC. +00606F CLARION CORPORATION OF AMERICA +006070 CISCO SYSTEMS, INC. +006071 MIDAS LAB, INC. +006072 VXL INSTRUMENTS, LIMITED +006073 REDCREEK COMMUNICATIONS, INC. +006074 QSC AUDIO PRODUCTS +006075 PENTEK, INC. +006076 SCHLUMBERGER TECHNOLOGIES +006077 PRISA NETWORKS +006078 POWER MEASUREMENT LTD. +006079 WAVEPHORE NETWORKS, INC. +00607A DVS GMBH +00607B FORE SYSTEMS, INC. +00607C WAVEACCESS, LTD. +00607D SENTIENT NETWORKS INC. +00607E GIGALABS, INC. +00607F AURORA TECHNOLOGIES, INC. +006080 MICROTRONIX DATACOM LTD. +006081 TV/COM INTERNATIONAL +006082 NOVALINK TECHNOLOGIES, INC. +006083 CISCO SYSTEMS, INC. +006084 DIGITAL VIDEO +006085 STORAGE CONCEPTS +006086 LOGIC REPLACEMENT TECH. LTD. +006087 KANSAI ELECTRIC CO., LTD. +006088 WHITE MOUNTAIN DSP, INC. +006089 XATA +00608A CITADEL COMPUTER +00608B CONFERTECH INTERNATIONAL +00608C 3COM CORPORATION +00608D UNIPULSE CORP. +00608E HE ELECTRONICS, TECHNOLOGIE & +00608F TEKRAM TECHNOLOGY CO., LTD. +006090 ABLE COMMUNICATIONS, INC. +006091 FIRST PACIFIC NETWORKS, INC. +006092 MICRO/SYS, INC. +006093 VARIAN +006094 IBM CORP. +006095 ACCU-TIME SYSTEMS, INC. +006096 T.S. MICROTECH INC. +006097 3COM CORPORATION +006098 HT COMMUNICATIONS +006099 LAN MEDIA CORPORATION +00609A NJK TECHNO CO. +00609B ASTRO-MED, INC. +00609C PERKIN-ELMER CORPORATION +00609D PMI FOOD EQUIPMENT GROUP +00609E X3 - INFORMATION TECHNOLOGY +00609F PHAST CORPORATION +0060A0 SWITCHED NETWORK +0060A1 VPNET +0060A2 NIHON UNISYS LIMITED CO. +0060A3 CONTINUUM TECHNOLOGY CORP. +0060A4 GRINAKER SYSTEM TECHNOLOGIES +0060A5 PERFORMANCE TELECOM CORP. +0060A6 PARTICLE MEASURING SYSTEMS +0060A7 MICROSENS GMBH & CO. KG +0060A8 TIDOMAT AB +0060A9 GESYTEC MBH +0060AA INTELLIGENT DEVICES INC. (IDI) +0060AB LARSCOM INCORPORATED +0060AC RESILIENCE CORPORATION +0060AD MEGACHIPS CORPORATION +0060AE TRIO INFORMATION SYSTEMS AB +0060AF PACIFIC MICRO DATA, INC. +0060B0 HEWLETT-PACKARD CO. +0060B1 INPUT/OUTPUT, INC. +0060B2 PROCESS CONTROL CORP. +0060B3 Z-COM, INC. +0060B4 GLENAYRE R&D INC. +0060B5 KEBA GMBH +0060B6 LAND COMPUTER CO., LTD. +0060B7 CHANNELMATIC, INC. +0060B8 CORELIS INC. +0060B9 NITSUKO CORPORATION +0060BA SAHARA NETWORKS, INC. +0060BB CABLETRON - NETLINK, INC. +0060BC KEUNYOUNG ELECTRONICS & +0060BD HUBBELL-PULSECOM +0060BE WEBTRONICS +0060BF MACRAIGOR SYSTEMS, INC. +0060C0 NERA AS +0060C1 WAVESPAN CORPORATION +0060C2 MPL AG +0060C3 NETVISION CORPORATION +0060C4 SOLITON SYSTEMS K.K. +0060C5 ANCOT CORP. +0060C6 DCS AG +0060C7 AMATI COMMUNICATIONS CORP. +0060C8 KUKA WELDING SYSTEMS & ROBOTS +0060C9 CONTROLNET, INC. +0060CA HARMONIC SYSTEMS INCORPORATED +0060CB HITACHI ZOSEN CORPORATION +0060CC EMTRAK, INCORPORATED +0060CD VIDEOSERVER, INC. +0060CE ACCLAIM COMMUNICATIONS +0060CF ALTEON NETWORKS, INC. +0060D0 SNMP RESEARCH INCORPORATED +0060D1 CASCADE COMMUNICATIONS +0060D2 LUCENT TECHNOLOGIES TAIWAN +0060D3 AT&T +0060D4 ELDAT COMMUNICATION LTD. +0060D5 MIYACHI TECHNOS CORP. +0060D6 NOVATEL WIRELESS TECHNOLOGIES +0060D7 ECOLE POLYTECHNIQUE FEDERALE +0060D8 ELMIC SYSTEMS, INC. +0060D9 TRANSYS NETWORKS INC. +0060DA JBM ELECTRONICS CO. +0060DB NTP ELEKTRONIK A/S +0060DC TOYO COMMUNICATION EQUIPMENT +0060DD MYRICOM, INC. +0060DE KAYSER-THREDE GMBH +0060DF INRANGE TECHNOLOGIES CORP. +0060E0 AXIOM TECHNOLOGY CO., LTD. +0060E1 ORCKIT COMMUNICATIONS LTD. +0060E2 QUEST ENGINEERING & DEV. +0060E3 ARBIN INSTRUMENTS +0060E4 COMPUSERVE, INC. +0060E5 FUJI AUTOMATION CO., LTD. +0060E6 SHOMITI SYSTEMS INCORPORATED +0060E7 RANDATA +0060E8 HITACHI COMPUTER PRODUCTS +0060E9 ATOP TECHNOLOGIES, INC. +0060EA STREAMLOGIC +0060EB FOURTHTRACK SYSTEMS +0060EC HERMARY OPTO ELECTRONICS INC. +0060ED RICARDO TEST AUTOMATION LTD. +0060EE APOLLO +0060EF FLYTECH TECHNOLOGY CO., LTD. +0060F0 JOHNSON & JOHNSON MEDICAL, INC +0060F1 EXP COMPUTER, INC. +0060F2 LASERGRAPHICS, INC. +0060F3 NETCOM SYSTEMS, INC. +0060F4 ADVANCED COMPUTER SOLUTIONS, +0060F5 ICON WEST, INC. +0060F6 NEXTEST COMMUNICATION +0060F7 DATAFUSION SYSTEMS +0060F8 LORAN INTERNATIONAL TECHN. INC +0060F9 DIAMOND LANE COMMUNICATIONS +0060FA EDUCATIONAL TECHNOLOGY +0060FB PACKETEER, INC. +0060FC CONSERVATION THROUGH +0060FD NETICS, INC. +0060FE LYNX SYSTEM DEVELOPERS, INC. +0060FF QUVIS, INC. +0070B0 M/A-COM INC. COMPANIES +0070B3 DATA RECALL LTD. +008000 MULTITECH SYSTEMS, INC. +008001 PERIPHONICS CORPORATION +008002 SATELCOM (UK) LTD +008003 HYTEC ELECTRONICS LTD. +008004 ANTLOW COMMUNICATIONS, LTD. +008005 CACTUS COMPUTER INC. +008006 COMPUADD CORPORATION +008007 DLOG NC-SYSTEME +008008 DYNATECH COMPUTER SYSTEMS +008009 JUPITER SYSTEMS, INC. +00800A JAPAN COMPUTER CORP. +00800B CSK CORPORATION +00800C VIDECOM LIMITED +00800D VOSSWINKEL F.U. +00800E ATLANTIX CORPORATION +00800F STANDARD MICROSYSTEMS +008010 COMMODORE INTERNATIONAL +008011 DIGITAL SYSTEMS INT'L. INC. +008012 INTEGRATED MEASUREMENT SYSTEMS +008013 THOMAS-CONRAD CORPORATION +008014 ESPRIT SYSTEMS +008015 SEIKO SYSTEMS, INC. +008016 WANDEL AND GOLTERMANN +008017 PFU LIMITED +008018 KOBE STEEL, LTD. +008019 DAYNA COMMUNICATIONS, INC. +00801A BELL ATLANTIC +00801B KODIAK TECHNOLOGY +00801C NEWPORT SYSTEMS SOLUTIONS +00801D INTEGRATED INFERENCE MACHINES +00801E XINETRON, INC. +00801F KRUPP ATLAS ELECTRONIK GMBH +008020 NETWORK PRODUCTS +008021 NEWBRIDGE RESEARCH CORP. +008022 SCAN-OPTICS +008023 INTEGRATED BUSINESS NETWORKS +008024 KALPANA, INC. +008025 STOLLMANN GMBH +008026 NETWORK PRODUCTS CORPORATION +008027 ADAPTIVE SYSTEMS, INC. +008028 TRADPOST (HK) LTD +008029 EAGLE TECHNOLOGY, INC. +00802A TEST SYSTEMS & SIMULATIONS INC +00802B INTEGRATED MARKETING CO +00802C THE SAGE GROUP PLC +00802D XYLOGICS INC +00802E CASTLE ROCK COMPUTING +00802F NATIONAL INSTRUMENTS CORP. +008030 NEXUS ELECTRONICS +008031 BASYS, CORP. +008032 ACCESS CO., LTD. +008033 FORMATION, INC. +008034 SMT GOUPIL +008035 TECHNOLOGY WORKS, INC. +008036 REFLEX MANUFACTURING SYSTEMS +008037 Ericsson Group +008038 DATA RESEARCH & APPLICATIONS +008039 ALCATEL STC AUSTRALIA +00803A VARITYPER, INC. +00803B APT COMMUNICATIONS, INC. +00803C TVS ELECTRONICS LTD +00803D SURIGIKEN CO., LTD. +00803E SYNERNETICS +00803F TATUNG COMPANY +008040 JOHN FLUKE MANUFACTURING CO. +008041 VEB KOMBINAT ROBOTRON +008042 FORCE COMPUTERS +008043 NETWORLD, INC. +008044 SYSTECH COMPUTER CORP. +008045 MATSUSHITA ELECTRIC IND. CO +008046 UNIVERSITY OF TORONTO +008047 IN-NET CORP. +008048 COMPEX INCORPORATED +008049 NISSIN ELECTRIC CO., LTD. +00804A PRO-LOG +00804B EAGLE TECHNOLOGIES PTY.LTD. +00804C CONTEC CO., LTD. +00804D CYCLONE MICROSYSTEMS, INC. +00804E APEX COMPUTER COMPANY +00804F DAIKIN INDUSTRIES, LTD. +008050 ZIATECH CORPORATION +008051 FIBERMUX +008052 TECHNICALLY ELITE CONCEPTS +008053 INTELLICOM, INC. +008054 FRONTIER TECHNOLOGIES CORP. +008055 FERMILAB +008056 SPHINX ELEKTRONIK GMBH +008057 ADSOFT, LTD. +008058 PRINTER SYSTEMS CORPORATION +008059 STANLEY ELECTRIC CO., LTD +00805A TULIP COMPUTERS INTERNAT'L B.V +00805B CONDOR SYSTEMS, INC. +00805C AGILIS CORPORATION +00805D CANSTAR +00805E LSI LOGIC CORPORATION +00805F COMPAQ COMPUTER CORPORATION +008060 NETWORK INTERFACE CORPORATION +008061 LITTON SYSTEMS, INC. +008062 INTERFACE CO. +008063 RICHARD HIRSCHMANN GMBH & CO. +008064 WYSE TECHNOLOGY +008065 CYBERGRAPHIC SYSTEMS PTY LTD. +008066 ARCOM CONTROL SYSTEMS, LTD. +008067 SQUARE D COMPANY +008068 YAMATECH SCIENTIFIC LTD. +008069 COMPUTONE SYSTEMS +00806A ERI (EMPAC RESEARCH INC.) +00806B SCHMID TELECOMMUNICATION +00806C CEGELEC PROJECTS LTD +00806D CENTURY SYSTEMS CORP. +00806E NIPPON STEEL CORPORATION +00806F ONELAN LTD. +008070 COMPUTADORAS MICRON +008071 SAI TECHNOLOGY +008072 MICROPLEX SYSTEMS LTD. +008073 DWB ASSOCIATES +008074 FISHER CONTROLS +008075 PARSYTEC GMBH +008076 MCNC +008077 BROTHER INDUSTRIES, LTD. +008078 PRACTICAL PERIPHERALS, INC. +008079 MICROBUS DESIGNS LTD. +00807A AITECH SYSTEMS LTD. +00807B ARTEL COMMUNICATIONS CORP. +00807C FIBERCOM, INC. +00807D EQUINOX SYSTEMS INC. +00807E SOUTHERN PACIFIC LTD. +00807F DY-4 INCORPORATED +008080 DATAMEDIA CORPORATION +008081 KENDALL SQUARE RESEARCH CORP. +008082 PEP MODULAR COMPUTERS GMBH +008083 AMDAHL +008084 THE CLOUD INC. +008085 H-THREE SYSTEMS CORPORATION +008086 COMPUTER GENERATION INC. +008087 OKI ELECTRIC INDUSTRY CO., LTD +008088 VICTOR COMPANY OF JAPAN, LTD. +008089 TECNETICS (PTY) LTD. +00808A SUMMIT MICROSYSTEMS CORP. +00808B DACOLL LIMITED +00808C NetScout Systems, Inc. +00808D WESTCOAST TECHNOLOGY B.V. +00808E RADSTONE TECHNOLOGY +00808F C. ITOH ELECTRONICS, INC. +008090 MICROTEK INTERNATIONAL, INC. +008091 TOKYO ELECTRIC CO.,LTD +008092 JAPAN COMPUTER INDUSTRY, INC. +008093 XYRON CORPORATION +008094 ALFA LAVAL AUTOMATION AB +008095 BASIC MERTON HANDELSGES.M.B.H. +008096 HUMAN DESIGNED SYSTEMS, INC. +008097 CENTRALP AUTOMATISMES +008098 TDK CORPORATION +008099 KLOCKNER MOELLER IPC +00809A NOVUS NETWORKS LTD +00809B JUSTSYSTEM CORPORATION +00809C LUXCOM, INC. +00809D Commscraft Ltd. +00809E DATUS GMBH +00809F ALCATEL BUSINESS SYSTEMS +0080A0 EDISA HEWLETT PACKARD S/A +0080A1 MICROTEST, INC. +0080A2 CREATIVE ELECTRONIC SYSTEMS +0080A3 LANTRONIX +0080A4 LIBERTY ELECTRONICS +0080A5 SPEED INTERNATIONAL +0080A6 REPUBLIC TECHNOLOGY, INC. +0080A7 MEASUREX CORP. +0080A8 VITACOM CORPORATION +0080A9 CLEARPOINT RESEARCH +0080AA MAXPEED +0080AB DUKANE NETWORK INTEGRATION +0080AC IMLOGIX, DIVISION OF GENESYS +0080AD CNET TECHNOLOGY, INC. +0080AE HUGHES NETWORK SYSTEMS +0080AF ALLUMER CO., LTD. +0080B0 ADVANCED INFORMATION +0080B1 SOFTCOM A/S +0080B2 NETWORK EQUIPMENT TECHNOLOGIES +0080B3 AVAL DATA CORPORATION +0080B4 SOPHIA SYSTEMS +0080B5 UNITED NETWORKS INC. +0080B6 THEMIS COMPUTER +0080B7 STELLAR COMPUTER +0080B8 BUG, INCORPORATED +0080B9 ARCHE TECHNOLIGIES INC. +0080BA SPECIALIX (ASIA) PTE, LTD +0080BB HUGHES LAN SYSTEMS +0080BC HITACHI ENGINEERING CO., LTD +0080BD THE FURUKAWA ELECTRIC CO., LTD +0080BE ARIES RESEARCH +0080BF TAKAOKA ELECTRIC MFG. CO. LTD. +0080C0 PENRIL DATACOMM +0080C1 LANEX CORPORATION +0080C2 IEEE 802 COMMITTEE +0080C3 BICC INFORMATION SYSTEMS & SVC +0080C4 DOCUMENT TECHNOLOGIES, INC. +0080C5 NOVELLCO DE MEXICO +0080C6 NATIONAL DATACOMM CORPORATION +0080C7 XIRCOM +0080C8 D-LINK SYSTEMS, INC. +0080C9 ALBERTA MICROELECTRONIC CENTRE +0080CA NETCOM RESEARCH INCORPORATED +0080CB FALCO DATA PRODUCTS +0080CC MICROWAVE BYPASS SYSTEMS +0080CD MICRONICS COMPUTER, INC. +0080CE BROADCAST TELEVISION SYSTEMS +0080CF EMBEDDED PERFORMANCE INC. +0080D0 COMPUTER PERIPHERALS, INC. +0080D1 KIMTRON CORPORATION +0080D2 SHINNIHONDENKO CO., LTD. +0080D3 SHIVA CORP. +0080D4 CHASE RESEARCH LTD. +0080D5 CADRE TECHNOLOGIES +0080D6 NUVOTECH, INC. +0080D7 FANTUM ENGINEERING, INC. +0080D8 NETWORK PERIPHERALS INC. +0080D9 EMK ELEKTRONIK +0080DA BRUEL & KJAER +0080DB GRAPHON CORPORATION +0080DC PICKER INTERNATIONAL +0080DD GMX INC/GIMIX +0080DE GIPSI S.A. +0080DF ADC CODENOLL TECHNOLOGY CORP. +0080E0 XTP SYSTEMS, INC. +0080E1 STMICROELECTRONICS +0080E2 T.D.I. CO., LTD. +0080E3 CORAL NETWORK CORPORATION +0080E4 NORTHWEST DIGITAL SYSTEMS, INC +0080E5 MYLEX CORPORATION +0080E6 PEER NETWORKS, INC. +0080E7 LYNWOOD SCIENTIFIC DEV. LTD. +0080E8 CUMULUS CORPORATIION +0080E9 MADGE NETWORKS +0080EA ADVA Optical Networking Ltd. +0080EB COMPCONTROL B.V. +0080EC SUPERCOMPUTING SOLUTIONS, INC. +0080ED IQ TECHNOLOGIES, INC. +0080EE THOMSON CSF +0080EF RATIONAL +0080F0 KYUSHU MATSUSHITA ELECTRIC CO. +0080F1 OPUS SYSTEMS +0080F2 RAYCOM SYSTEMS INC +0080F3 SUN ELECTRONICS CORP. +0080F4 TELEMECANIQUE ELECTRIQUE +0080F5 QUANTEL LTD +0080F6 SYNERGY MICROSYSTEMS +0080F7 ZENITH ELECTRONICS +0080F8 MIZAR, INC. +0080F9 HEURIKON CORPORATION +0080FA RWT GMBH +0080FB BVM LIMITED +0080FC AVATAR CORPORATION +0080FD EXSCEED CORPRATION +0080FE AZURE TECHNOLOGIES, INC. +0080FF SOC. DE TELEINFORMATIQUE RTC +009000 DIAMOND MULTIMEDIA +009001 NISHIMU ELCTRONICS INDUSTRIES +009002 ALLGON AB +009003 APLIO +009004 3COM EUROPE LTD. +009005 PROTECH SYSTEMS CO., LTD. +009006 HAMAMATSU PHOTONICS K.K. +009007 DOMEX TECHNOLOGY CORP. +009008 HAN A SYSTEMS, INC. +009009 i Controls, Inc. +00900A PROTON ELECTRONIC INDUSTRIAL +00900B LANNER ELECTRONICS, INC. +00900C CISCO SYSTEMS, INC. +00900D OVERLAND DATA INC. +00900E HANDLINK TECHNOLOGIES, INC. +00900F KAWASAKI HEAVY INDUSTRIES, LTD +009010 SIMULATION LABORATORIES, INC. +009011 WAVTRACE, INC. +009012 GLOBESPAN SEMICONDUCTOR, INC. +009013 SAMSAN CORP. +009014 ROTORK INSTRUMENTS, LTD. +009015 CENTIGRAM COMMUNICATIONS CORP. +009016 ZAC +009017 ZYPCOM, INC. +009018 ITO ELECTRIC INDUSTRY CO, LTD. +009019 HERMES ELECTRONICS CO., LTD. +00901A UNISPHERE SOLUTIONS +00901B DIGITAL CONTROLS +00901C MPS SOFTWARE GMBH +00901D PEC (NZ) LTD. +00901E SELESTA INGEGNE RIA S.P.A. +00901F ADTEC PRODUCTIONS, INC. +009020 PHILIPS ANALYTICAL X-RAY B.V. +009021 CISCO SYSTEMS, INC. +009022 IVEX +009023 ZILOG INC. +009024 PIPELINKS, INC. +009025 VISION SYSTEMS LTD. PTY +009026 ADVANCED SWITCHING +009027 INTEL CORPORATION +009028 NIPPON SIGNAL CO., LTD. +009029 CRYPTO AG +00902A COMMUNICATION DEVICES, INC. +00902B CISCO SYSTEMS, INC. +00902C DATA & CONTROL EQUIPMENT LTD. +00902D DATA ELECTRONICS +00902E NAMCO LIMITED +00902F NETCORE SYSTEMS, INC. +009030 HONEYWELL-DATING +009031 MYSTICOM, LTD. +009032 PELCOMBE GROUP LTD. +009033 INNOVAPHONE GMBH +009034 IMAGIC, INC. +009035 ALPHA TELECOM, INC. +009036 ENS, INC. +009037 ACUCOMM, INC. +009038 FOUNTAIN TECHNOLOGIES, INC. +009039 SHASTA NETWORKS +00903A NIHON MEDIA TOOL INC. +00903B TRIEMS RESEARCH LAB, INC. +00903C ATLANTIC NETWORK SYSTEMS +00903D BIOPAC SYSTEMS, INC. +00903E N.V. PHILIPS INDUSTRIAL +00903F AZTEC RADIOMEDIA +009040 CASTLE NETWORKS, INC. +009041 APPLIED DIGITAL ACCESS +009042 ECCS +009043 NICHIBEI DENSHI CO., LTD. +009044 ASSURED DIGITAL, INC. +009045 MARIPOSA TECHNOLOGY +009046 DEXDYNE, LTD. +009047 GIGA FAST E. LTD. +009048 ZEAL CORPORATION +009049 ENTRIDIA CORPORATION +00904A CONCUR SYSTEM TECHNOLOGIES +00904B GEMTEK TECHNOLOGY CO., LTD. +00904C EPIGRAM, INC. +00904D SPEC S.A. +00904E DELEM BV +00904F ABB POWER T&D COMPANY, INC. +009050 TELESTE OY +009051 ULTIMATE TECHNOLOGY CORP. +009052 SELCOM ELETTRONICA S.R.L. +009053 DAEWOO ELECTRONICS CO., LTD. +009054 INNOVATIVE SEMICONDUCTORS, INC +009055 PARKER HANNIFIN CORPORATION +009056 TELESTREAM, INC. +009057 AANETCOM, INC. +009058 ULTRA ELECTRONICS LTD. +009059 TELECOM DEVICE K.K. +00905A DEARBORN GROUP, INC. +00905B RAYMOND AND LAE ENGINEERING +00905C EDMI +00905D NETCOM SICHERHEITSTECHNIK GMBH +00905E RAULAND-BORG CORPORATION +00905F CISCO SYSTEMS, INC. +009060 SYSTEM CREATE CORP. +009061 PACIFIC RESEARCH & ENGINEERING +009062 ICP VORTEX COMPUTERSYSTEME +009063 COHERENT COMMUNICATIONS +009064 THOMSON BROADCAST SYSTEMS +009065 FINISAR CORPORATION +009066 Troika Networks, Inc. +009067 WALKABOUT COMPUTERS, INC. +009068 DVT CORP. +009069 JUNIPER NETWORKS, INC. +00906A TURNSTONE SYSTEMS, INC. +00906B APPLIED RESOURCES, INC. +00906C GWT GLOBAL WEIGHING +00906D CISCO SYSTEMS, INC. +00906E PRAXON, INC. +00906F CISCO SYSTEMS, INC. +009070 NEO NETWORKS, INC. +009071 BADGER TECHNOLOGY, INC. +009072 SIMRAD AS +009073 GAIO TECHNOLOGY +009074 ARGON NETWORKS, INC. +009075 NEC DO BRASIL S.A. +009076 FMT AIRCRAFT GATE SUPPORT +009077 ADVANCED FIBRE COMMUNICATIONS +009078 MER TELEMANAGEMENT +009079 CLEARONE INC. +00907A SPECTRALINK CORP. +00907B E-TECH, INC. +00907C DIGITALCAST, INC. +00907D HOME WIRELESS NETWORKS +00907E VETRONIX CORP. +00907F WATCHGUARD TECHNOLOGIES, INC. +009080 NOT LIMITED, INC. +009081 ALOHA NETWORKS, INC. +009082 FORCE INSTITUTE +009083 TURBO COMMUNICATION, INC. +009084 ATECH SYSTEM +009085 GOLDEN ENTERPRISES, INC. +009086 CISCO SYSTEMS, INC. +009087 ITIS +009088 BAXALL SECURITY LTD. +009089 SOFTCOM MICROSYSTEMS, INC. +00908A BAYLY COMMUNICATIONS, INC. +00908B CELL COMPUTING, INC. +00908C ETREND ELECTRONICS, INC. +00908D VICKERS ELECTRONICS SYSTEMS +00908E Nortel Networks Broadband Access +00908F AUDIOCODES LTD. +009090 I-BUS +009091 DIGITALSCAPE, INC. +009092 CISCO SYSTEMS, INC. +009093 NANAO CORPORATION +009094 OSPREY TECHNOLOGIES, INC. +009095 UNIVERSAL AVIONICS +009096 ASKEY COMPUTER CORP. +009097 SYCAMORE NETWORKS +009098 SBC DESIGNS, INC. +009099 ALLIED TELESIS,K.K. +00909A ONE WORLD SYSTEMS, INC. +00909B MARKPOINT AB +00909C COMBOX, LTD. +00909D GSE SYSTEMS, INC. +00909E DELPHI ENGINEERING GROUP +00909F DIGI-DATA CORPORATION +0090A0 8X8 INC. +0090A1 FLYING PIG SYSTEMS, LTD. +0090A2 CYBERTAN TECHNOLOGY, INC. +0090A3 MEDIALINCS CO., LTD. +0090A4 ALTIGA NETWORKS +0090A5 SPECTRA LOGIC +0090A6 CISCO SYSTEMS, INC. +0090A7 CLIENTEC CORPORATION +0090A8 NINETILES NETWORKS LTD. +0090A9 WESTERN DIGITAL +0090AA INDIGO ACTIVE VISION +0090AB CISCO SYSTEMS, INC. +0090AC OPTIVISION, INC. +0090AD ASPECT ELECTRONICS, INC. +0090AE ITALTEL SPA +0090AF J. MORITA MFG. CORP. +0090B0 VADEM +0090B1 CISCO SYSTEMS, INC. +0090B2 AVICI SYSTEMS INC. +0090B3 AGRANAT SYSTEMS +0090B4 WILLOWBROOK TECHNOLOGIES +0090B5 NIKON CORPORATION +0090B6 FIBEX SYSTEMS +0090B7 DIGITAL LIGHTWAVE, INC. +0090B8 ROHDE & SCHWARZ GMBH & CO. KG +0090B9 BERAN INSTRUMENTS LTD. +0090BA VALID NETWORKS, INC. +0090BB TAINET COMMUNICATION SYSTEM +0090BC TELEMANN CO., LTD. +0090BD OMNIA COMMUNICATIONS, INC. +0090BE IBC/INTEGRATED BUSINESS +0090BF CISCO SYSTEMS, INC. +0090C0 K.J. LAW ENGINEERS, INC. +0090C1 EDA INDUSTRIES +0090C2 JK MICROSYSTEMS, INC. +0090C3 TOPIC SEMICONDUCTOR CORP. +0090C4 JAVELIN SYSTEMS, INC. +0090C5 INTERNET MAGIC, INC. +0090C6 OPTIM SYSTEMS, INC. +0090C7 ICOM INC. +0090C8 WAVERIDER COMMUNICATIONS +0090C9 PRODUCTIVITY ENHANCEMENT +0090CA ACCORD VIDEO +0090CB WIRELESS ONLINE, INC. +0090CC PLANEX COMMUNICATIONS, INC. +0090CD ENT-EMPRESA NACIONAL +0090CE TETRA GMBH +0090CF NORTEL +0090D0 ALCATEL BELL +0090D1 LEICHU ENTERPRISE CO., LTD. +0090D2 ARTEL VIDEO SYSTEMS +0090D3 GIESECKE & DEVRIENT GMBH +0090D4 BINDVIEW DEVELOPMENT CORP. +0090D5 EUPHONIX, INC. +0090D6 CRYSTAL GROUP +0090D7 NETBOOST CORP. +0090D8 WHITECROSS SYSTEMS +0090D9 CISCO SYSTEMS, INC. +0090DA DYNARC, INC. +0090DB NEXT LEVEL COMMUNICATIONS +0090DC TECO INFORMATION SYSTEMS +0090DD THE MIHARU COMMUNICATIONS +0090DE CARDKEY SYSTEMS, INC. +0090DF MITSUBISHI CHEMICAL +0090E0 SYSTRAN CORP. +0090E1 TELENA S.P.A. +0090E2 DISTRIBUTED PROCESSING +0090E3 AVEX ELECTRONICS INC. +0090E4 NEC AMERICA, INC. +0090E5 TEKNEMA, INC. +0090E6 ACER LABORATORIES, INC. +0090E7 HORSCH ELEKTRONIK AG +0090E8 MOXA TECHNOLOGIES CORP., LTD. +0090E9 JANZ COMPUTER AG +0090EA ALPHA TECHNOLOGIES, INC. +0090EB SENTRY TELECOM SYSTEMS +0090EC PYRESCOM +0090ED CENTRAL SYSTEM RESEARCH +0090EE PERSONAL COMMUNICATIONS +0090EF INTEGRIX, INC. +0090F0 HARMONIC LIGHTWAVES, LTD. +0090F1 DOT HILL SYSTEMS CORPORATION +0090F2 CISCO SYSTEMS, INC. +0090F3 ASPECT COMMUNICATIONS +0090F4 LIGHTNING INSTRUMENTATION +0090F5 CLEVO CO. +0090F6 ESCALATE NETWORKS, INC. +0090F7 NBASE COMMUNICATIONS LTD. +0090F8 MEDIATRIX TELECOM +0090F9 LEITCH +0090FA GIGANET, INC. +0090FB PORTWELL, INC. +0090FC NETWORK COMPUTING DEVICES +0090FD COPPERCOM, INC. +0090FE ELECOM CO., LTD. (LANEED DIV. +0090FF TELLUS TECHNOLOGY INC. +009D8E CARDIAC RECORDERS, INC. +00A000 CENTILLION NETWORKS, INC. +00A001 WATKINS-JOHNSON COMPANY +00A002 LEEDS & NORTHRUP AUSTRALIA +00A003 STAEFA CONTROL SYSTEM +00A004 NETPOWER, INC. +00A005 DANIEL INSTRUMENTS, LTD. +00A006 IMAGE DATA PROCESSING +00A007 APEXX TECHNOLOGY, INC. +00A008 NETCORP +00A009 WHITETREE NETWORK +00A00A R.D.C. COMMUNICATION +00A00B COMPUTEX CO., LTD. +00A00C KINGMAX TECHNOLOGY, INC. +00A00D THE PANDA PROJECT +00A00E VISUAL NETWORKS, INC. +00A00F Broadband Technologies +00A010 SYSLOGIC DATENTECHNIK AG +00A011 MUTOH INDUSTRIES LTD. +00A012 B.A.T.M. ADVANCED TECHNOLOGIES +00A013 TELTREND LTD. +00A014 CSIR +00A015 WYLE +00A016 MICROPOLIS CORP. +00A017 J B M CORPORATION +00A018 CREATIVE CONTROLLERS, INC. +00A019 NEBULA CONSULTANTS, INC. +00A01A BINAR ELEKTRONIK AB +00A01B PREMISYS COMMUNICATIONS, INC. +00A01C NASCENT NETWORKS CORPORATION +00A01D SIXNET +00A01E EST CORPORATION +00A01F TRICORD SYSTEMS, INC. +00A020 CITICORP/TTI +00A021 GENERAL DYNAMICS- +00A022 CENTRE FOR DEVELOPMENT OF +00A023 APPLIED CREATIVE TECHNOLOGY, +00A024 3COM CORPORATION +00A025 REDCOM LABS INC. +00A026 TELDAT, S.A. +00A027 FIREPOWER SYSTEMS, INC. +00A028 CONNER PERIPHERALS +00A029 COULTER CORPORATION +00A02A TRANCELL SYSTEMS +00A02B TRANSITIONS RESEARCH CORP. +00A02C INTERWAVE COMMUNICATIONS +00A02D 1394 Trade Association +00A02E BRAND COMMUNICATIONS, LTD. +00A02F PIRELLI CAVI +00A030 CAPTOR NV/SA +00A031 HAZELTINE CORPORATION, MS 1-17 +00A032 GES SINGAPORE PTE. LTD. +00A033 IMC MESS-SYSTEME GMBH +00A034 AXEL +00A035 CYLINK CORPORATION +00A036 APPLIED NETWORK TECHNOLOGY +00A037 DATASCOPE CORPORATION +00A038 EMAIL ELECTRONICS +00A039 ROSS TECHNOLOGY, INC. +00A03A KUBOTEK CORPORATION +00A03B TOSHIN ELECTRIC CO., LTD. +00A03C EG&G NUCLEAR INSTRUMENTS +00A03D OPTO - 22 +00A03E ATM FORUM +00A03F COMPUTER SOCIETY MICROPROCES'R +00A040 APPLE COMPUTER +00A041 LEYBOLD-INFICON +00A042 SPUR PRODUCTS CORP. +00A043 AMERICAN TECHNOLOGY LABS, INC. +00A044 NTT INTELLIGENT TECHNOLOGY +00A045 PHOENIX CONTACT GMBH & CO. +00A046 SCITEX CORP. LTD. +00A047 INTEGRATED FITNESS CORP. +00A048 QUESTECH, LTD. +00A049 DIGITECH INDUSTRIES, INC. +00A04A NISSHIN ELECTRIC CO., LTD. +00A04B TFL LAN INC. +00A04C INNOVATIVE SYSTEMS & TECH. INC +00A04D EDA INSTRUMENTS, INC. +00A04E VOELKER TECHNOLOGIES, INC. +00A04F AMERITEC CORP. +00A050 CYPRESS SEMICONDUCTOR +00A051 ANGIA COMMUNICATIONS. INC. +00A052 STANILITE ELECTRONICS PTY. LTD +00A053 COMPACT DEVICES, INC. +00A055 LINKTECH, INC. +00A056 MICROPROSS +00A057 ELSA AG +00A058 GLORY, LTD. +00A059 HAMILTON HALLMARK +00A05A KOFAX IMAGE PRODUCTS +00A05B MARQUIP, INC. +00A05C INVENTORY CONVERSION, INC./ +00A05D CS COMPUTER SYSTEME GMBH +00A05E MYRIAD LOGIC INC. +00A05F BTG ENGINEERING BV +00A060 ACER PERIPHERALS, INC. +00A061 PURITAN BENNETT +00A062 AES PRODATA +00A063 JRL SYSTEMS, INC. +00A064 KVB/ANALECT +00A065 NEXLAND, INC. +00A066 ISA CO., LTD. +00A067 NETWORK SERVICES GROUP +00A068 BHP LIMITED +00A069 TrueTime +00A06A VERILINK CORP. +00A06B DMS DORSCH MIKROSYSTEM GMBH +00A06C SHINDENGEN ELECTRIC MFG. +00A06D MANNESMANN TALLY CORPORATION +00A06E AUSTRON, INC. +00A06F THE APPCON GROUP, INC. +00A070 COASTCOM +00A071 VIDEO LOTTERY TECHNOLOGIES,INC +00A072 OVATION SYSTEMS LTD. +00A073 COM21, INC. +00A074 PERCEPTION TECHNOLOGY +00A075 MICRON TECHNOLOGY, INC. +00A076 CARDWARE LAB, INC. +00A077 FUJITSU NEXION, INC. +00A078 Marconi Communications +00A079 ALPS ELECTRIC (USA), INC. +00A07A ADVANCED PERIPHERALS +00A07B DAWN COMPUTER INCORPORATION +00A07C TONYANG NYLON CO., LTD. +00A07D SEEQ TECHNOLOGY, INC. +00A07E AVID TECHNOLOGY, INC. +00A07F GSM-SYNTEL, LTD. +00A080 ANTARES MICROSYSTEMS +00A081 ALCATEL DATA NETWORKS +00A082 NKT ELEKTRONIK A/S +00A083 ASIMMPHONY TURKEY +00A084 DATAPLEX PTY. LTD. +00A086 AMBER WAVE SYSTEMS, INC. +00A087 MITEL SEMICONDUCTOR, LTD. +00A088 ESSENTIAL COMMUNICATIONS +00A089 XPOINT TECHNOLOGIES, INC. +00A08A BROOKTROUT TECHNOLOGY, INC. +00A08B ASTON ELECTRONIC DESIGNS LTD. +00A08C MULTIMEDIA LANS, INC. +00A08D JACOMO CORPORATION +00A08E Nokia Internet Communications +00A08F DESKNET SYSTEMS, INC. +00A090 TIMESTEP CORPORATION +00A091 APPLICOM INTERNATIONAL +00A092 H. BOLLMANN MANUFACTURERS, LTD +00A093 B/E AEROSPACE +00A094 COMSAT CORPORATION +00A095 ACACIA NETWORKS, INC. +00A096 MITSUMI ELECTRIC CO., LTD. +00A097 JC INFORMATION SYSTEMS +00A098 NETWORK APPLIANCE CORP. +00A099 K-NET LTD. +00A09A NIHON KOHDEN AMERICA +00A09B QPSX COMMUNICATIONS, LTD. +00A09C XYPLEX, INC. +00A09D JOHNATHON FREEMAN TECHNOLOGIES +00A09E ICTV +00A09F COMMVISION CORP. +00A0A0 COMPACT DATA, LTD. +00A0A1 EPIC DATA INC. +00A0A2 DIGICOM S.P.A. +00A0A3 RELIABLE POWER METERS +00A0A4 MICROS SYSTEMS, INC. +00A0A5 TEKNOR MICROSYSTEME, INC. +00A0A6 M.I. SYSTEMS, K.K. +00A0A7 VORAX CORPORATION +00A0A8 RENEX CORPORATION +00A0A9 GN NETTEST (CANADA) INC. +00A0AA SPACELABS MEDICAL +00A0AB NETCS INFORMATIONSTECHNIK GMBH +00A0AC GILAT SATELLITE NETWORKS, LTD. +00A0AD MARCONI SPA +00A0AE NUCOM SYSTEMS, INC. +00A0AF WMS INDUSTRIES +00A0B0 I-O DATA DEVICE, INC. +00A0B1 FIRST VIRTUAL CORPORATION +00A0B2 SHIMA SEIKI +00A0B3 ZYKRONIX +00A0B4 TEXAS MICROSYSTEMS, INC. +00A0B5 3H TECHNOLOGY +00A0B6 SANRITZ AUTOMATION CO., LTD. +00A0B7 CORDANT, INC. +00A0B8 SYMBIOS LOGIC INC. +00A0B9 EAGLE TECHNOLOGY, INC. +00A0BA PATTON ELECTRONICS CO. +00A0BB HILAN GMBH +00A0BC VIASAT, INCORPORATED +00A0BD I-TECH CORP. +00A0BE INTEGRATED CIRCUIT SYSTEMS,INC +00A0BF WIRELESS DATA GROUP MOTOROLA +00A0C0 DIGITAL LINK CORP. +00A0C1 ORTIVUS MEDICAL AB +00A0C2 R.A. SYSTEMS CO., LTD. +00A0C3 UNICOMPUTER GMBH +00A0C4 CRISTIE ELECTRONICS LTD. +00A0C5 ZYXEL COMMUNICATION +00A0C6 QUALCOMM INCORPORATED +00A0C7 TADIRAN TELECOMMUNICATIONS +00A0C8 ADTRAN INC. +00A0C9 INTEL CORPORATION - HF1-06 +00A0CA FUJITSU DENSO LTD. +00A0CB ARK TELECOMMUNICATIONS, INC. +00A0CC LITE-ON COMMUNICATIONS, INC. +00A0CD DR. JOHANNES HEIDENHAIN GMBH +00A0CE ASTROCOM CORPORATION +00A0CF SOTAS, INC. +00A0D0 TEN X TECHNOLOGY, INC. +00A0D1 INVENTEC CORPORATION +00A0D2 ALLIED TELESIS INTERNATIONAL +00A0D3 INSTEM COMPUTER SYSTEMS, LTD. +00A0D4 RADIOLAN, INC. +00A0D5 SIERRA WIRELESS INC. +00A0D6 SBE, INC. +00A0D7 KASTEN CHASE APPLIED RESEARCH +00A0D8 SPECTRA - TEK +00A0D9 CONVEX COMPUTER CORPORATION +00A0DA INTEGRATED SYSTEMS +00A0DB FISHER & PAYKEL PRODUCTION +00A0DC O.N. ELECTRONIC CO., LTD. +00A0DD AZONIX CORPORATION +00A0DE YAMAHA CORPORATION +00A0DF STS TECHNOLOGIES, INC. +00A0E0 TENNYSON TECHNOLOGIES PTY LTD +00A0E1 WESTPORT RESEARCH +00A0E2 KEISOKU GIKEN CORP. +00A0E3 XKL SYSTEMS CORP. +00A0E4 OPTIQUEST +00A0E5 NHC COMMUNICATIONS +00A0E6 DIALOGIC CORPORATION +00A0E7 CENTRAL DATA CORPORATION +00A0E8 REUTERS HOLDINGS PLC +00A0E9 ELECTRONIC RETAILING SYSTEMS +00A0EA ETHERCOM CORP. +00A0EB FASTCOMM COMMUNICATIONS CORP. +00A0EC TRANSMITTON LTD. +00A0ED PRI AUTOMATION +00A0EE NASHOBA NETWORKS +00A0EF LUCIDATA LTD. +00A0F0 TORONTO MICROELECTRONICS INC. +00A0F1 MTI +00A0F2 INFOTEK COMMUNICATIONS, INC. +00A0F3 STAUBLI +00A0F4 GE +00A0F5 RADGUARD LTD. +00A0F6 AUTOGAS SYSTEMS, INC. +00A0F7 V.I COMPUTER CORP. +00A0F8 SYMBOL TECHNOLOGIES, INC. +00A0F9 BINTEC COMMUNICATIONS GMBH +00A0FA Marconi Communication GmbH +00A0FB TORAY ENGINEERING CO., LTD. +00A0FC IMAGE SCIENCES, INC. +00A0FD SCITEX DIGITAL PRINTING, INC. +00A0FE BOSTON TECHNOLOGY, INC. +00A0FF TELLABS OPERATIONS, INC. +00AA00 INTEL CORPORATION +00AA01 INTEL CORPORATION +00AA02 INTEL CORPORATION +00AA3C OLIVETTI TELECOM SPA (OLTECO) +00B009 Grass Valley Group +00B017 InfoGear Technology Corp. +00B019 Casi-Rusco +00B01C Westport Technologies +00B01E Rantic Labs, Inc. +00B02A ORSYS GmbH +00B02D ViaGate Technologies, Inc. +00B03B HiQ Networks +00B048 Marconi Communications Inc. +00B04A Cisco Systems, Inc. +00B052 Intellon Corporation +00B064 Cisco Systems, Inc. +00B069 Honewell Oy +00B06D Jones Futurex Inc. +00B080 Mannesmann Ipulsys B.V. +00B086 LocSoft Limited +00B08E Cisco Systems, Inc. +00B091 Transmeta Corp. +00B094 Alaris, Inc. +00B09A Morrow Technologies Corp. +00B09D Point Grey Research Inc. +00B0AC SIAE-Microelettronica S.p.A. +00B0AE Symmetricom +00B0B3 Xstreamis PLC +00B0C2 Cisco Systems, Inc. +00B0C7 Tellabs Operations, Inc. +00B0CE TECHNOLOGY RESCUE +00B0D0 Dell Computer Corp. +00B0DB Nextcell, Inc. +00B0DF Reliable Data Technology, Inc. +00B0E7 British Federal Ltd. +00B0EC EACEM +00B0EE Ajile Systems, Inc. +00B0F0 CALY NETWORKS +00B0F5 NetWorth Technologies, Inc. +00BB01 OCTOTHORPE CORP. +00BBF0 UNGERMANN-BASS INC. +00C000 LANOPTICS, LTD. +00C001 DIATEK PATIENT MANAGMENT +00C002 SERCOMM CORPORATION +00C003 GLOBALNET COMMUNICATIONS +00C004 JAPAN BUSINESS COMPUTER CO.LTD +00C005 LIVINGSTON ENTERPRISES, INC. +00C006 NIPPON AVIONICS CO., LTD. +00C007 PINNACLE DATA SYSTEMS, INC. +00C008 SECO SRL +00C009 KT TECHNOLOGY (S) PTE LTD +00C00A MICRO CRAFT +00C00B NORCONTROL A.S. +00C00C RELIA TECHNOLGIES +00C00D ADVANCED LOGIC RESEARCH, INC. +00C00E PSITECH, INC. +00C00F QUANTUM SOFTWARE SYSTEMS LTD. +00C010 HIRAKAWA HEWTECH CORP. +00C011 INTERACTIVE COMPUTING DEVICES +00C012 NETSPAN CORPORATION +00C013 NETRIX +00C014 TELEMATICS CALABASAS INT'L,INC +00C015 NEW MEDIA CORPORATION +00C016 ELECTRONIC THEATRE CONTROLS +00C017 FORTE NETWORKS +00C018 LANART CORPORATION +00C019 LEAP TECHNOLOGY, INC. +00C01A COROMETRICS MEDICAL SYSTEMS +00C01B SOCKET COMMUNICATIONS, INC. +00C01C INTERLINK COMMUNICATIONS LTD. +00C01D GRAND JUNCTION NETWORKS, INC. +00C01E LA FRANCAISE DES JEUX +00C01F S.E.R.C.E.L. +00C020 ARCO ELECTRONIC, CONTROL LTD. +00C021 NETEXPRESS +00C022 LASERMASTER TECHNOLOGIES, INC. +00C023 TUTANKHAMON ELECTRONICS +00C024 EDEN SISTEMAS DE COMPUTACAO SA +00C025 DATAPRODUCTS CORPORATION +00C026 LANS TECHNOLOGY CO., LTD. +00C027 CIPHER SYSTEMS, INC. +00C028 JASCO CORPORATION +00C029 KABEL RHEYDT AG +00C02A OHKURA ELECTRIC CO., LTD. +00C02B GERLOFF GESELLSCHAFT FUR +00C02C CENTRUM COMMUNICATIONS, INC. +00C02D FUJI PHOTO FILM CO., LTD. +00C02E NETWIZ +00C02F OKUMA CORPORATION +00C030 INTEGRATED ENGINEERING B. V. +00C031 DESIGN RESEARCH SYSTEMS, INC. +00C032 I-CUBED LIMITED +00C033 TELEBIT COMMUNICATIONS APS +00C034 TRANSACTION NETWORK +00C035 QUINTAR COMPANY +00C036 RAYTECH ELECTRONIC CORP. +00C037 DYNATEM +00C038 RASTER IMAGE PROCESSING SYSTEM +00C039 TDK SEMICONDUCTOR CORPORATION +00C03A MEN-MIKRO ELEKTRONIK GMBH +00C03B MULTIACCESS COMPUTING CORP. +00C03C TOWER TECH S.R.L. +00C03D WIESEMANN & THEIS GMBH +00C03E FA. GEBR. HELLER GMBH +00C03F STORES AUTOMATED SYSTEMS, INC. +00C040 ECCI +00C041 DIGITAL TRANSMISSION SYSTEMS +00C042 DATALUX CORP. +00C043 STRATACOM +00C044 EMCOM CORPORATION +00C045 ISOLATION SYSTEMS, LTD. +00C046 KEMITRON LTD. +00C047 UNIMICRO SYSTEMS, INC. +00C048 BAY TECHNICAL ASSOCIATES +00C049 U.S. ROBOTICS, INC. +00C04A GROUP 2000 AG +00C04B CREATIVE MICROSYSTEMS +00C04C DEPARTMENT OF FOREIGN AFFAIRS +00C04D MITEC, INC. +00C04E COMTROL CORPORATION +00C04F DELL COMPUTER CORPORATION +00C050 TOYO DENKI SEIZO K.K. +00C051 ADVANCED INTEGRATION RESEARCH +00C052 BURR-BROWN +00C053 DAVOX CORPORATION +00C054 NETWORK PERIPHERALS, LTD. +00C055 MODULAR COMPUTING TECHNOLOGIES +00C056 SOMELEC +00C057 MYCO ELECTRONICS +00C058 DATAEXPERT CORP. +00C059 NIPPON DENSO CO., LTD. +00C05A SEMAPHORE COMMUNICATIONS CORP. +00C05B NETWORKS NORTHWEST, INC. +00C05C ELONEX PLC +00C05D L&N TECHNOLOGIES +00C05E VARI-LITE, INC. +00C05F FINE-PAL COMPANY LIMITED +00C060 ID SCANDINAVIA AS +00C061 SOLECTEK CORPORATION +00C062 IMPULSE TECHNOLOGY +00C063 MORNING STAR TECHNOLOGIES, INC +00C064 GENERAL DATACOMM IND. INC. +00C065 SCOPE COMMUNICATIONS, INC. +00C066 DOCUPOINT, INC. +00C067 UNITED BARCODE INDUSTRIES +00C068 PHILIP DRAKE ELECTRONICS LTD. +00C069 ADAPTIVE BROADBAND CORPORATION +00C06A ZAHNER-ELEKTRIK GMBH & CO. KG +00C06B OSI PLUS CORPORATION +00C06C SVEC COMPUTER CORP. +00C06D BOCA RESEARCH, INC. +00C06E HAFT TECHNOLOGY, INC. +00C06F KOMATSU LTD. +00C070 SECTRA SECURE-TRANSMISSION AB +00C071 AREANEX COMMUNICATIONS, INC. +00C072 KNX LTD. +00C073 XEDIA CORPORATION +00C074 TOYODA AUTOMATIC LOOM +00C075 XANTE CORPORATION +00C076 I-DATA INTERNATIONAL A-S +00C077 DAEWOO TELECOM LTD. +00C078 COMPUTER SYSTEMS ENGINEERING +00C079 FONSYS CO.,LTD. +00C07A PRIVA B.V. +00C07B ASCEND COMMUNICATIONS, INC. +00C07C HIGHTECH INFORMATION +00C07D RISC DEVELOPMENTS LTD. +00C07E KUBOTA CORPORATION ELECTRONIC +00C07F NUPON COMPUTING CORP. +00C080 NETSTAR, INC. +00C081 METRODATA LTD. +00C082 MOORE PRODUCTS CO. +00C083 TRACE MOUNTAIN PRODUCTS, INC. +00C084 DATA LINK CORP. LTD. +00C085 ELECTRONICS FOR IMAGING, INC. +00C086 THE LYNK CORPORATION +00C087 UUNET TECHNOLOGIES, INC. +00C088 EKF ELEKTRONIK GMBH +00C089 TELINDUS DISTRIBUTION +00C08A LAUTERBACH DATENTECHNIK GMBH +00C08B RISQ MODULAR SYSTEMS, INC. +00C08C PERFORMANCE TECHNOLOGIES, INC. +00C08D TRONIX PRODUCT DEVELOPMENT +00C08E NETWORK INFORMATION TECHNOLOGY +00C08F MATSUSHITA ELECTRIC WORKS, LTD +00C090 PRAIM S.R.L. +00C091 JABIL CIRCUIT, INC. +00C092 MENNEN MEDICAL INC. +00C093 ALTA RESEARCH CORP. +00C094 VMX INC. +00C095 ZNYX +00C096 TAMURA CORPORATION +00C097 ARCHIPEL SA +00C098 CHUNTEX ELECTRONIC CO., LTD. +00C099 YOSHIKI INDUSTRIAL CO.,LTD. +00C09A PHOTONICS CORPORATION +00C09B RELIANCE COMM/TEC, R-TEC +00C09C TOA ELECTRONIC LTD. +00C09D DISTRIBUTED SYSTEMS INT'L, INC +00C09E CACHE COMPUTERS, INC. +00C09F QUANTA COMPUTER, INC. +00C0A0 ADVANCE MICRO RESEARCH, INC. +00C0A1 TOKYO DENSHI SEKEI CO. +00C0A2 INTERMEDIUM A/S +00C0A3 DUAL ENTERPRISES CORPORATION +00C0A4 UNIGRAF OY +00C0A5 DICKENS DATA SYSTEMS +00C0A6 EXICOM AUSTRALIA PTY. LTD +00C0A7 SEEL LTD. +00C0A8 GVC CORPORATION +00C0A9 BARRON MCCANN LTD. +00C0AA SILICON VALLEY COMPUTER +00C0AB Telco Systems, Inc. +00C0AC GAMBIT COMPUTER COMMUNICATIONS +00C0AD MARBEN COMMUNICATION SYSTEMS +00C0AE TOWERCOM CO. INC. DBA PC HOUSE +00C0AF TEKLOGIX INC. +00C0B0 GCC TECHNOLOGIES,INC. +00C0B1 GENIUS NET CO. +00C0B2 NORAND CORPORATION +00C0B3 COMSTAT DATACOMM CORPORATION +00C0B4 MYSON TECHNOLOGY, INC. +00C0B5 CORPORATE NETWORK SYSTEMS,INC. +00C0B6 MERIDIAN DATA, INC. +00C0B7 AMERICAN POWER CONVERSION CORP +00C0B8 FRASER'S HILL LTD. +00C0B9 FUNK SOFTWARE, INC. +00C0BA NETVANTAGE +00C0BB FORVAL CREATIVE, INC. +00C0BC TELECOM AUSTRALIA/CSSC +00C0BD INEX TECHNOLOGIES, INC. +00C0BE ALCATEL - SEL +00C0BF TECHNOLOGY CONCEPTS, LTD. +00C0C0 SHORE MICROSYSTEMS, INC. +00C0C1 QUAD/GRAPHICS, INC. +00C0C2 INFINITE NETWORKS LTD. +00C0C3 ACUSON COMPUTED SONOGRAPHY +00C0C4 COMPUTER OPERATIONAL +00C0C5 SID INFORMATICA +00C0C6 PERSONAL MEDIA CORP. +00C0C7 SPARKTRUM MICROSYSTEMS, INC. +00C0C8 MICRO BYTE PTY. LTD. +00C0C9 ELSAG BAILEY PROCESS +00C0CA ALFA, INC. +00C0CB CONTROL TECHNOLOGY CORPORATION +00C0CC TELESCIENCES CO SYSTEMS, INC. +00C0CD COMELTA, S.A. +00C0CE CEI SYSTEMS & ENGINEERING PTE +00C0CF IMATRAN VOIMA OY +00C0D0 RATOC SYSTEM INC. +00C0D1 COMTREE TECHNOLOGY CORPORATION +00C0D2 SYNTELLECT, INC. +00C0D3 OLYMPUS IMAGE SYSTEMS, INC. +00C0D4 AXON NETWORKS, INC. +00C0D5 QUANCOM ELECTRONIC GMBH +00C0D6 J1 SYSTEMS, INC. +00C0D7 TAIWAN TRADING CENTER DBA +00C0D8 UNIVERSAL DATA SYSTEMS +00C0D9 QUINTE NETWORK CONFIDENTIALITY +00C0DA NICE SYSTEMS LTD. +00C0DB IPC CORPORATION (PTE) LTD. +00C0DC EOS TECHNOLOGIES, INC. +00C0DD QLogic Corporation +00C0DE ZCOMM, INC. +00C0DF KYE SYSTEMS CORP. +00C0E0 DSC COMMUNICATION CORP. +00C0E1 SONIC SOLUTIONS +00C0E2 CALCOMP, INC. +00C0E3 OSITECH COMMUNICATIONS, INC. +00C0E4 SIEMENS BUILDING +00C0E5 GESPAC, S.A. +00C0E6 Verilink Corporation +00C0E7 FIBERDATA AB +00C0E8 PLEXCOM, INC. +00C0E9 OAK SOLUTIONS, LTD. +00C0EA ARRAY TECHNOLOGY LTD. +00C0EB SEH COMPUTERTECHNIK GMBH +00C0EC DAUPHIN TECHNOLOGY +00C0ED US ARMY ELECTRONIC +00C0EE KYOCERA CORPORATION +00C0EF ABIT CORPORATION +00C0F0 KINGSTON TECHNOLOGY CORP. +00C0F1 SHINKO ELECTRIC CO., LTD. +00C0F2 TRANSITION NETWORKS +00C0F3 NETWORK COMMUNICATIONS CORP. +00C0F4 INTERLINK SYSTEM CO., LTD. +00C0F5 METACOMP, INC. +00C0F6 CELAN TECHNOLOGY INC. +00C0F7 ENGAGE COMMUNICATION, INC. +00C0F8 ABOUT COMPUTING INC. +00C0F9 HARRIS AND JEFFRIES, INC. +00C0FA CANARY COMMUNICATIONS, INC. +00C0FB ADVANCED TECHNOLOGY LABS +00C0FC ELASTIC REALITY, INC. +00C0FD PROSUM +00C0FE APTEC COMPUTER SYSTEMS, INC. +00C0FF DOT HILL SYSTEMS CORPORATION +00CBBD Cambridge Broadband Ltd. +00CF1C COMMUNICATION MACHINERY CORP. +00D000 FERRAN SCIENTIFIC, INC. +00D001 VST TECHNOLOGIES, INC. +00D002 DITECH CORPORATION +00D003 COMDA ENTERPRISES CORP. +00D004 PENTACOM LTD. +00D005 ZHS ZEITMANAGEMENTSYSTEME +00D006 CISCO SYSTEMS, INC. +00D007 MIC ASSOCIATES, INC. +00D008 MACTELL CORPORATION +00D009 HSING TECH. ENTERPRISE CO. LTD +00D00A LANACCESS TELECOM S.A. +00D00B RHK TECHNOLOGY, INC. +00D00C SNIJDER MICRO SYSTEMS +00D00D MICROMERITICS INSTRUMENT +00D00E PLURIS, INC. +00D00F SPEECH DESIGN GMBH +00D010 CONVERGENT NETWORKS, INC. +00D011 PRISM VIDEO, INC. +00D012 GATEWORKS CORP. +00D013 PRIMEX AEROSPACE COMPANY +00D014 ROOT, INC. +00D015 UNIVEX MICROTECHNOLOGY CORP. +00D016 SCM MICROSYSTEMS, INC. +00D017 SYNTECH INFORMATION CO., LTD. +00D018 QWES. COM, INC. +00D019 DAINIPPON SCREEN CORPORATE +00D01A URMET SUD S.P.A. +00D01B MIMAKI ENGINEERING CO., LTD. +00D01C SBS TECHNOLOGIES, +00D01D FURUNO ELECTRIC CO., LTD. +00D01E PINGTEL CORP. +00D01F CTAM PTY. LTD. +00D020 AIM SYSTEM, INC. +00D021 REGENT ELECTRONICS CORP. +00D022 INCREDIBLE TECHNOLOGIES, INC. +00D023 INFORTREND TECHNOLOGY, INC. +00D024 Cognex Corporation +00D025 XROSSTECH, INC. +00D026 HIRSCHMANN AUSTRIA GMBH +00D027 APPLIED AUTOMATION, INC. +00D028 OMNEON VIDEO NETWORKS +00D029 WAKEFERN FOOD CORPORATION +00D02A FLEXION SYSTEMS +00D02B JETCELL, INC. +00D02C CAMPBELL SCIENTIFIC, INC. +00D02D ADEMCO +00D02E COMMUNICATION AUTOMATION CORP. +00D02F VLSI TECHNOLOGY INC. +00D030 SAFETRAN SYSTEMS CORP. +00D031 INDUSTRIAL LOGIC CORPORATION +00D032 YANO ELECTRIC CO., LTD. +00D033 DALIAN DAXIAN NETWORK +00D034 ORMEC SYSTEMS CORP. +00D035 BEHAVIOR TECH. COMPUTER CORP. +00D036 TECHNOLOGY ATLANTA CORP. +00D037 PHILIPS-DVS-LO BDR +00D038 FIVEMERE, LTD. +00D039 UTILICOM, INC. +00D03A ZONEWORX, INC. +00D03B VISION PRODUCTS PTY. LTD. +00D03C Vieo, Inc. +00D03E ROCKETCHIPS, INC. +00D03F AMERICAN COMMUNICATION +00D040 SYSMATE CO., LTD. +00D041 AMIGO TECHNOLOGY CO., LTD. +00D042 MAHLO GMBH & CO. UG +00D043 ZONAL RETAIL DATA SYSTEMS +00D044 ALIDIAN NETWORKS, INC. +00D045 KVASER AB +00D046 DOLBY LABORATORIES, INC. +00D047 XN TECHNOLOGIES +00D048 ECTON, INC. +00D049 IMPRESSTEK CO., LTD. +00D04A PRESENCE TECHNOLOGY GMBH +00D04B LA CIE GROUP S.A. +00D04C EUROTEL TELECOM LTD. +00D04D DIV OF RESEARCH & STATISTICS +00D04E LOGIBAG +00D04F BITRONICS, INC. +00D050 ISKRATEL +00D051 O2 MICRO, INC. +00D052 ASCEND COMMUNICATIONS, INC. +00D053 CONNECTED SYSTEMS +00D054 SAS INSTITUTE INC. +00D055 KATHREIN-WERKE KG +00D056 SOMAT CORPORATION +00D057 ULTRAK, INC. +00D058 CISCO SYSTEMS, INC. +00D059 AMBIT MICROSYSTEMS CORP. +00D05A SYMBIONICS, LTD. +00D05B ACROLOOP MOTION CONTROL +00D05C TECHNOTREND SYSTEMTECHNIK GMBH +00D05D INTELLIWORXX, INC. +00D05E STRATABEAM TECHNOLOGY, INC. +00D05F VALCOM, INC. +00D060 PANASONIC EUROPEAN +00D061 TREMON ENTERPRISES CO., LTD. +00D062 DIGIGRAM +00D063 CISCO SYSTEMS, INC. +00D064 MULTITEL +00D065 TOKO ELECTRIC +00D066 WINTRISS ENGINEERING CORP. +00D067 CAMPIO COMMUNICATIONS +00D068 IWILL CORPORATION +00D069 TECHNOLOGIC SYSTEMS +00D06A LINKUP SYSTEMS CORPORATION +00D06B SR TELECOM INC. +00D06C SHAREWAVE, INC. +00D06D ACRISON, INC. +00D06E TRENDVIEW RECORDERS LTD. +00D06F KMC CONTROLS +00D070 LONG WELL ELECTRONICS CORP. +00D071 ECHELON CORP. +00D072 BROADLOGIC +00D073 ACN ADVANCED COMMUNICATIONS +00D074 TAQUA SYSTEMS, INC. +00D075 ALARIS MEDICAL SYSTEMS, INC. +00D076 MERRILL LYNCH & CO., INC. +00D077 LUCENT TECHNOLOGIES +00D078 ELTEX OF SWEDEN AB +00D079 CISCO SYSTEMS, INC. +00D07A AMAQUEST COMPUTER CORP. +00D07B COMCAM INTERNATIONAL LTD. +00D07C KOYO ELECTRONICS INC. CO.,LTD. +00D07D COSINE COMMUNICATIONS +00D07E KEYCORP LTD. +00D07F STRATEGY & TECHNOLOGY, LIMITED +00D080 EXABYTE CORPORATION +00D081 REAL TIME DEVICES USA, INC. +00D082 IOWAVE INC. +00D083 INVERTEX, INC. +00D084 NEXCOMM SYSTEMS, INC. +00D085 OTIS ELEVATOR COMPANY +00D086 FOVEON, INC. +00D087 MICROFIRST INC. +00D088 MAINSAIL NETWORKS, INC. +00D089 DYNACOLOR, INC. +00D08A PHOTRON USA +00D08B ADVA Limited +00D08C GENOA TECHNOLOGY, INC. +00D08D PHOENIX GROUP, INC. +00D08E NVISION INC. +00D08F ARDENT TECHNOLOGIES, INC. +00D090 CISCO SYSTEMS, INC. +00D091 SMARTSAN SYSTEMS, INC. +00D092 GLENAYRE WESTERN MULTIPLEX +00D093 TQ - COMPONENTS GMBH +00D094 TIMELINE VISTA, INC. +00D095 XYLAN CORPORATION +00D096 3COM EUROPE LTD. +00D097 CISCO SYSTEMS, INC. +00D098 IPS AUTOMATION +00D099 ELCARD OY +00D09A FILANET CORPORATION +00D09B SPECTEL LTD. +00D09C KAPADIA COMMUNICATIONS +00D09D VERIS INDUSTRIES +00D09E 2WIRE, INC. +00D09F NOVTEK TEST SYSTEMS +00D0A0 MIPS DENMARK +00D0A1 OSKAR VIERLING GMBH + CO. KG +00D0A2 INTEGRATED DEVICE +00D0A3 VOCAL DATA, INC. +00D0A4 ALANTRO COMMUNICATIONS +00D0A5 AMERICAN ARIUM +00D0A6 LANBIRD TECHNOLOGY CO., LTD. +00D0A7 TOKYO SOKKI KENKYUJO CO., LTD. +00D0A8 NETWORK ENGINES, INC. +00D0A9 SHINANO KENSHI CO., LTD. +00D0AA CHASE COMMUNICATIONS +00D0AB DELTAKABEL TELECOM CV +00D0AC GRAYSON WIRELESS +00D0AD TL INDUSTRIES +00D0AE ORESIS COMMUNICATIONS, INC. +00D0AF CUTLER-HAMMER, INC. +00D0B0 BITSWITCH LTD. +00D0B1 OMEGA ELECTRONICS SA +00D0B2 XIOTECH CORPORATION +00D0B3 DRS FLIGHT SAFETY AND +00D0B4 KATSUJIMA CO., LTD. +00D0B5 DOTCOM +00D0B6 CRESCENT NETWORKS, INC. +00D0B7 INTEL CORPOTATION +00D0B8 IOMEGA CORP. +00D0B9 MICROTEK INTERNATIONAL, INC. +00D0BA CISCO SYSTEMS, INC. +00D0BB CISCO SYSTEMS, INC. +00D0BC CISCO SYSTEMS, INC. +00D0BD SICAN GMBH +00D0BE EMUTEC INC. +00D0BF PIVOTAL TECHNOLOGIES +00D0C0 CISCO SYSTEMS, INC. +00D0C1 HARMONIC DATA SYSTEMS, LTD. +00D0C2 BALTHAZAR TECHNOLOGY AB +00D0C3 VIVID TECHNOLOGY PTE, LTD. +00D0C4 TERATECH CORPORATION +00D0C5 COMPUTATIONAL SYSTEMS, INC. +00D0C6 THOMAS & BETTS CORP. +00D0C7 PATHWAY, INC. +00D0C8 I/O CONSULTING A/S +00D0C9 ADVANTECH CO., LTD. +00D0CA INTRINSYC SOFTWARE INC. +00D0CB DASAN CO., LTD. +00D0CC TECHNOLOGIES LYRE INC. +00D0CD ATAN TECHNOLOGY INC. +00D0CE ASYST ELECTRONIC +00D0CF MORETON BAY +00D0D0 ZHONGXING TELECOM LTD. +00D0D1 SIROCCO SYSTEMS, INC. +00D0D2 EPILOG CORPORATION +00D0D3 CISCO SYSTEMS, INC. +00D0D4 V-BITS, INC. +00D0D5 GRUNDIG AG +00D0D6 AETHRA TELECOMUNICAZIONI +00D0D7 B2C2, INC. +00D0D8 3Com Corporation +00D0D9 DEDICATED MICROCOMPUTERS +00D0DA TAICOM DATA SYSTEMS CO., LTD. +00D0DB MCQUAY INTERNATIONAL +00D0DC MODULAR MINING SYSTEMS, INC. +00D0DD SUNRISE TELECOM, INC. +00D0DE PHILIPS MULTIMEDIA NETWORK +00D0DF KUZUMI ELECTRONICS, INC. +00D0E0 DOOIN ELECTRONICS CO. +00D0E1 AVIONITEK ISRAEL INC. +00D0E2 MRT MICRO, INC. +00D0E3 ELE-CHEM ENGINEERING CO., LTD. +00D0E4 CISCO SYSTEMS, INC. +00D0E5 SOLIDUM SYSTEMS CORP. +00D0E6 IBOND INC. +00D0E7 VCON TELECOMMUNICATION LTD. +00D0E8 MAC SYSTEM CO., LTD. +00D0E9 ADVANTAGE CENTURY +00D0EA NEXTONE COMMUNICATIONS, INC. +00D0EB LIGHTERA NETWORKS, INC. +00D0EC NAKAYO TELECOMMUNICATIONS, INC +00D0ED XIOX +00D0EE DICTAPHONE CORPORATION +00D0EF IGT +00D0F0 CONVISION TECHNOLOGY GMBH +00D0F1 SEGA ENTERPRISES, LTD. +00D0F2 MONTEREY NETWORKS +00D0F3 SOLARI DI UDINE SPA +00D0F4 CARINTHIAN TECH INSTITUTE +00D0F5 ORANGE MICRO, INC. +00D0F6 NORTHCHURCH COMMUNICATIONS INC +00D0F7 NEXT NETS CORPORATION +00D0F8 FUJIAN STAR TERMINAL +00D0F9 ACUTE COMMUNICATIONS CORP. +00D0FA RACAL GUARDATA +00D0FB TEK MICROSYSTEMS, INCORPORATED +00D0FC GRANITE MICROSYSTEMS +00D0FD OPTIMA TELE.COM, INC. +00D0FE ASTRAL POINT +00D0FF CISCO SYSTEMS, INC. +00DD00 UNGERMANN-BASS INC. +00DD01 UNGERMANN-BASS INC. +00DD02 UNGERMANN-BASS INC. +00DD03 UNGERMANN-BASS INC. +00DD04 UNGERMANN-BASS INC. +00DD05 UNGERMANN-BASS INC. +00DD06 UNGERMANN-BASS INC. +00DD07 UNGERMANN-BASS INC. +00DD08 UNGERMANN-BASS INC. +00DD09 UNGERMANN-BASS INC. +00DD0A UNGERMANN-BASS INC. +00DD0B UNGERMANN-BASS INC. +00DD0C UNGERMANN-BASS INC. +00DD0D UNGERMANN-BASS INC. +00DD0E UNGERMANN-BASS INC. +00DD0F UNGERMANN-BASS INC. +00E000 FUJITSU, LTD +00E001 STRAND LIGHTING LIMITED +00E002 CROSSROADS SYSTEMS, INC. +00E003 NOKIA WIRELESS BUSINESS COMMUN +00E004 PMC-SIERRA, INC. +00E005 TECHNICAL CORP. +00E006 SILICON INTEGRATED SYS. CORP. +00E007 NETWORK ALCHEMY LTD. +00E008 AMAZING CONTROLS! INC. +00E009 MARATHON TECHNOLOGIES CORP. +00E00A DIBA, INC. +00E00B ROOFTOP COMMUNICATIONS CORP. +00E00C MOTOROLA +00E00D RADIANT SYSTEMS +00E00E AVALON IMAGING SYSTEMS, INC. +00E00F SHANGHAI BAUD DATA +00E010 HESS SB-AUTOMATENBAU GMBH +00E011 UNIDEN SAN DIEGO +00E012 PLUTO TECHNOLOGIES +00E013 EASTERN ELECTRONIC CO., LTD. +00E014 CISCO SYSTEMS, INC. +00E015 HEIWA CORPORATION +00E016 RAPID CITY COMMUNICATIONS +00E017 EXXACT GMBH +00E018 ASUSTEK COMPUTER INC. +00E019 ING. GIORDANO ELETTRONICA +00E01A COMTEC SYSTEMS. CO., LTD. +00E01B SPHERE COMMUNICATIONS, INC. +00E01C MOBILITY ELECTRONICSY +00E01D WEBTV NETWORKS, INC. +00E01E CISCO SYSTEMS, INC. +00E01F AVIDIA SYSTEMS, INC. +00E020 TECNOMEN OY +00E021 FREEGATE CORP. +00E022 MEDIALIGHT INC. +00E023 TELRAD +00E024 GADZOOX NETWORKS +00E025 DIT CO., LTD. +00E026 EASTMAN KODAK CO. +00E027 DUX, INC. +00E028 APTIX CORPORATION +00E029 STANDARD MICROSYSTEMS CORP. +00E02A TANDBERG TELEVISION AS +00E02B EXTREME NETWORKS +00E02C AST COMPUTER +00E02D INNOMEDIALOGIC, INC. +00E02E SPC ELECTRONICS CORPORATION +00E02F MCNS HOLDINGS, L.P. +00E030 MELITA INTERNATIONAL CORP. +00E031 HAGIWARA ELECTRIC CO., LTD. +00E032 MISYS FINANCIAL SYSTEMS, LTD. +00E033 E.E.P.D. GMBH +00E034 CISCO SYSTEMS, INC. +00E035 LOUGHBOROUGH SOUND IMAGES, PLC +00E036 PIONEER CORPORATION +00E037 CENTURY CORPORATION +00E038 PROXIMA CORPORATION +00E039 PARADYNE CORP. +00E03A CABLETRON SYSTEMS, INC. +00E03B PROMINET CORPORATION +00E03C ADVANSYS +00E03D FOCON ELECTRONIC SYSTEMS A/S +00E03E ALFATECH, INC. +00E03F JATON CORPORATION +00E040 DESKSTATION TECHNOLOGY, INC. +00E041 CSPI +00E042 PACOM DATA LTD. +00E043 VITALCOM +00E044 LSICS CORPORATION +00E045 TOUCHWAVE, INC. +00E046 BENTLY NEVADA CORP. +00E047 INFOCUS SYSTEMS +00E048 SDL COMMUNICATIONS, INC. +00E049 MICROWI ELECTRONIC GMBH +00E04A ENHANCED MESSAGING SYSTEMS,INC +00E04B JUMP INDUSTRIELLE +00E04C REALTEK SEMICONDUCTOR CORP. +00E04D INTERNET INITIATIVE JAPAN, INC +00E04E SANYO DENKI CO., LTD. +00E04F CISCO SYSTEMS, INC. +00E050 EXECUTONE INFORMATION +00E051 TALX CORPORATION +00E052 FOUNDRY NETWORKS, INC. +00E053 CELLPORT LABS, INC. +00E054 KODAI HITEC CO., LTD. +00E055 INGENIERIA ELECTRONICA +00E056 HOLONTECH CORPORATION +00E057 HAN MICROTELECOM. CO., LTD. +00E058 PHASE ONE DENMARK A/S +00E059 CONTROLLED ENVIRONMENTS, LTD. +00E05A GALEA NETWORK SECURITY +00E05B WEST END SYSTEMS CORP. +00E05C MATSUSHITA KOTOBUKI +00E05D UNITEC CO., LTD. +00E05E JAPAN AVIATION ELECTRONICS +00E05F E-NET, INC. +00E060 SHERWOOD +00E061 EDGEPOINT NETWORKS, INC. +00E062 HOST ENGINEERING +00E063 CABLETRON - YAGO SYSTEMS, INC. +00E064 SAMSUNG ELECTRONICS +00E065 OPTICAL ACCESS INTERNATIONAL +00E066 PROMAX SYSTEMS, INC. +00E067 EAC AUTOMATION-CONSULTING GMBH +00E068 MERRIMAC SYSTEMS INC. +00E069 JAYCOR NETWORKS, INC. +00E06A KAPSCH AG +00E06B W&G SPECIAL PRODUCTS +00E06C BALTIMORE TECHNOLOGIES, LTD. +00E06D COMPUWARE CORPORATION +00E06E FAR SYSTEMS SPA +00E06F TERAYON CORP. +00E070 DH TECHNOLOGY +00E071 EPIS MICROCOMPUTER +00E072 LYNK +00E073 NATIONAL AMUSEMENT +00E074 TIERNAN COMMUNICATIONS, INC. +00E075 ATLAS COMPUTER EQUIPMENT, INC. +00E076 DEVELOPMENT CONCEPTS, INC. +00E077 WEBGEAR, INC. +00E078 BERKELEY NETWORKS +00E079 A.T.N.R. +00E07A MIKRODIDAKT AB +00E07B BAY NETWORKS +00E07C METTLER-TOLEDO, INC. +00E07D NETRONIX, INC. +00E07E WALT DISNEY IMAGINEERING +00E07F LOGISTISTEM SRL +00E080 CONTROL RESOURCES CORPORATION +00E081 TYAN COMPUTER CORP. +00E082 ANERMA +00E083 JATO TECHNOLOGIES, INC. +00E084 COMPULITE R&D +00E085 GLOBAL MAINTECH, INC. +00E086 CYBEX COMPUTER PRODUCTS +00E087 LECROY +00E088 LTX CORPORATION +00E089 ION Networks, Inc. +00E08A GEC AVERY, LTD. +00E08B QLOGIC CORP. +00E08C NEOPARADIGM LABS, INC. +00E08D PRESSURE SYSTEMS, INC. +00E08E UTSTARCOM +00E08F CISCO SYSTEMS, INC. +00E090 BECKMAN LAB. AUTOMATION DIV. +00E091 LG ELECTRONICS, INC. +00E092 ADMTEK INCORPORATED +00E093 ACKFIN NETWORKS +00E094 OSAI SRL +00E095 ADVANCED-VISION TECHNOLGIES +00E096 SHIMADZU CORPORATION +00E097 CARRIER ACCESS CORPORATION +00E098 ABOCOM SYSTEMS, INC. +00E099 SAMSON AG +00E09A POSITRON INDUSTRIES, INC. +00E09B ENGAGE NETWORKS, INC. +00E09C MII +00E09D SARNOFF CORPORATION +00E09E QUANTUM CORPORATION +00E09F PIXEL VISION +00E0A0 WILTRON CO. +00E0A1 HIMA PAUL HILDEBRANDT +00E0A2 MICROSLATE INC. +00E0A3 CISCO SYSTEMS, INC. +00E0A4 ESAOTE S.P.A. +00E0A5 COMCORE SEMICONDUCTOR, INC. +00E0A6 TELOGY NETWORKS, INC. +00E0A7 IPC INFORMATION SYSTEMS, INC. +00E0A8 SAT GMBH&CO +00E0A9 FUNAI ELECTRIC CO., LTD. +00E0AA ELECTROSONIC LTD. +00E0AB DIMAT S.A. +00E0AC MIDSCO, INC. +00E0AD EES TECHNOLOGY, LTD. +00E0AE XAQTI CORPORATION +00E0AF GENERAL DYNAMICS INFORMATION +00E0B0 CISCO SYSTEMS, INC. +00E0B1 PACKET ENGINES, INC. +00E0B2 TELMAX COMMUNICATIONS CORP. +00E0B3 ETHERWAN SYSTEMS, INC. +00E0B4 TECHNO SCOPE CO., LTD. +00E0B5 ARDENT COMMUNICATIONS CORP. +00E0B6 Entrada Networks +00E0B7 PI GROUP, LTD. +00E0B8 GATEWAY 2000 +00E0B9 BYAS SYSTEMS +00E0BA BERGHOF AUTOMATIONSTECHNIK +00E0BB NBX CORPORATION +00E0BC SYMON COMMUNICATIONS, INC. +00E0BD INTERFACE SYSTEMS, INC. +00E0BE GENROCO INTERNATIONAL, INC. +00E0BF TORRENT NETWORKING +00E0C0 SEIWA ERECTRIC MFG. CO., LTD. +00E0C1 MEMOREX TELEX JAPAN, LTD. +00E0C2 NECSY SPA +00E0C3 SAKAI SYSTEM DEVELOPMENT CORP. +00E0C4 HORNER ELECTRIC, INC. +00E0C5 BCOM ELECTRONICS INC. +00E0C6 LINK2IT, L.L.C. +00E0C7 EUROTECH SRL +00E0C8 VIRTUAL ACCESS, LTD. +00E0C9 AUTOMATEDLOGIC CORPORATION +00E0CA BEST DATA PRODUCTS +00E0CB RESON, INC. +00E0CC HERO SYSTEMS, LTD. +00E0CD SENSIS CORPORATION +00E0CE ARN +00E0CF INTEGRATED DEVICE +00E0D0 NETSPEED, INC. +00E0D1 TELSIS LIMITED +00E0D2 VERSANET COMMUNICATIONS, INC. +00E0D3 DATENTECHNIK GMBH +00E0D4 EXCELLENT COMPUTER +00E0D5 ARCXEL TECHNOLOGIES, INC. +00E0D6 COMPUTER & COMMUNICATION +00E0D7 SUNSHINE ELECTRONICS, INC. +00E0D8 LANBIT COMPUTER, INC. +00E0D9 TAZMO CO., LTD. +00E0DA ASSURED ACCESS +00E0DB VIAVIDEO COMMUNICATIONS +00E0DC NEXWARE CORP. +00E0DD ZENITH ELECTRONICS CORPORATION +00E0DE DATAX NV +00E0DF KE KOMMUNIKATIONS-ELECTRONIK +00E0E0 SI ELECTRONICS, LTD. +00E0E1 G2 NETWORKS, ILNC. +00E0E2 INNOVA CORP. +00E0E3 SK-ELEKTRONIK GMBH +00E0E4 FANUC ROBOTICS NORTH AMERICA, +00E0E5 CINCO NETWORKS, INC. +00E0E6 INCAA DATACOM B.V. +00E0E7 RAYTHEON E-SYSTEMS, INC. +00E0E8 GRETACODER DATA SYSTEMS AG +00E0E9 DATA LABS, INC. +00E0EA INNOVAT COMMUNICATIONS, INC. +00E0EB DIGICOM SYSTEMS, INCORPORATED +00E0EC CELESTICA INC. +00E0ED SILICOM, LTD. +00E0EE MAREL HF +00E0EF DIONEX +00E0F0 ABLER TECHNOLOGY, INC. +00E0F1 THAT CORPORATION +00E0F2 ARLOTTO COMNET, INC. +00E0F3 WEBSPRINT COMMUNICATIONS, INC. +00E0F4 INSIDE TECHNOLOGY A/S +00E0F5 TELES AG +00E0F6 DECISION EUROPE +00E0F7 CISCO SYSTEMS, INC. +00E0F8 DIANA CONTROL AB +00E0F9 CISCO SYSTEMS, INC. +00E0FA TRL TECHNOLOGY, LTD. +00E0FB LEIGHTRONIX, INC. +00E0FC HUAWEI TECHNOLOGIES CO., LTD. +00E0FD A-TREND TECHNOLOGY CO., LTD. +00E0FE CISCO SYSTEMS, INC. +00E0FF SECURITY DYNAMICS TECHNOLOGIES +00E6D3 NIXDORF COMPUTER CORP. +020701 RACAL-DATACOM +021C7C PERQ SYSTEMS CORPORATION +026086 LOGIC REPLACEMENT TECH. LTD. +02608C 3COM CORPORATION +027001 RACAL-DATACOM +0270B0 M/A-COM INC. COMPANIES +0270B3 DATA RECALL LTD +029D8E CARDIAC RECORDERS INC. +02AA3C OLIVETTI TELECOMM SPA (OLTECO) +02BB01 OCTOTHORPE CORP. +02C08C 3COM CORPORATION +02CF1C COMMUNICATION MACHINERY CORP. +02E6D3 NIXDORF COMPUTER CORPORATION +040AE0 XMIT AG COMPUTER NETWORKS +04E0C4 TRIUMPH-ADLER AG +080001 COMPUTERVISION CORPORATION +080002 BRIDGE COMMUNICATIONS INC. +080003 ADVANCED COMPUTER COMM. +080004 CROMEMCO INCORPORATED +080005 SYMBOLICS INC. +080006 SIEMENS AG +080007 APPLE COMPUTER INC. +080008 BOLT BERANEK AND NEWMAN INC. +080009 HEWLETT PACKARD +08000A NESTAR SYSTEMS INCORPORATED +08000B UNISYS CORPORATION +08000C MIKLYN DEVELOPMENT CO. +08000D INTERNATIONAL COMPUTERS LTD. +08000E NCR CORPORATION +08000F MITEL CORPORATION +080011 TEKTRONIX INC. +080012 BELL ATLANTIC INTEGRATED SYST. +080013 EXXON +080014 EXCELAN +080015 STC BUSINESS SYSTEMS +080016 BARRISTER INFO SYS CORP +080017 NATIONAL SEMICONDUCTOR +080018 PIRELLI FOCOM NETWORKS +080019 GENERAL ELECTRIC CORPORATION +08001A TIARA/ 10NET +08001B DATA GENERAL +08001C KDD-KOKUSAI DEBNSIN DENWA CO. +08001D ABLE COMMUNICATIONS INC. +08001E APOLLO COMPUTER INC. +08001F SHARP CORPORATION +080020 SUN MICROSYSTEMS INC. +080021 3M COMPANY +080022 NBI INC. +080023 MATSUHITA GRAPHIC COMM SYS INC +080024 10NET COMMUNICATIONS/DCA +080025 CONTROL DATA +080026 NORSK DATA A.S. +080027 CADMUS COMPUTER SYSTEMS +080028 TEXAS INSTRUMENTS +080029 MEGATEK CORPORATION +08002A MOSAIC TECHNOLOGIES INC. +08002B DIGITAL EQUIPMENT CORPORATION +08002C BRITTON LEE INC. +08002D LAN-TEC INC. +08002E METAPHOR COMPUTER SYSTEMS +08002F PRIME COMPUTER INC. +080030 NETWORK RESEARCH CORPORATION +080030 CERN +080030 ROYAL MELBOURNE INST OF TECH +080031 LITTLE MACHINES INC. +080032 TIGAN INCORPORATED +080033 BAUSCH & LOMB +080034 FILENET CORPORATION +080035 MICROFIVE CORPORATION +080036 INTERGRAPH CORPORATION +080037 FUJI-XEROX CO. LTD. +080038 CII HONEYWELL BULL +080039 SPIDER SYSTEMS LIMITED +08003A ORCATECH INC. +08003B TORUS SYSTEMS LIMITED +08003C SCHLUMBERGER WELL SERVICES +08003D CADNETIX CORPORATIONS +08003E CODEX CORPORATION +08003F FRED KOSCHARA ENTERPRISES +080040 FERRANTI COMPUTER SYS. LIMITED +080041 RACAL-MILGO INFORMATION SYS.. +080042 JAPAN MACNICS CORP. +080043 PIXEL COMPUTER INC. +080044 DAVID SYSTEMS INC. +080045 CONCURRENT COMPUTER CORP. +080046 SONY CORPORATION LTD. +080047 SEQUENT COMPUTER SYSTEMS INC. +080048 EUROTHERM GAUGING SYSTEMS +080049 UNIVATION +08004A BANYAN SYSTEMS INC. +08004B PLANNING RESEARCH CORP. +08004C HYDRA COMPUTER SYSTEMS INC. +08004D CORVUS SYSTEMS INC. +08004E 3COM EUROPE LTD. +08004F CYGNET SYSTEMS +080050 DAISY SYSTEMS CORP. +080051 EXPERDATA +080052 INSYSTEC +080053 MIDDLE EAST TECH. UNIVERSITY +080055 STANFORD TELECOMM. INC. +080056 STANFORD LINEAR ACCEL. CENTER +080057 EVANS & SUTHERLAND +080058 SYSTEMS CONCEPTS +080059 A/S MYCRON +08005A IBM CORPORATION +08005B VTA TECHNOLOGIES INC. +08005C FOUR PHASE SYSTEMS +08005D GOULD INC. +08005E COUNTERPOINT COMPUTER INC. +08005F SABER TECHNOLOGY CORP. +080060 INDUSTRIAL NETWORKING INC. +080061 JAROGATE LTD. +080062 GENERAL DYNAMICS +080063 PLESSEY +080064 AUTOPHON AG +080065 GENRAD INC. +080066 AGFA CORPORATION +080067 COMDESIGN +080068 RIDGE COMPUTERS +080069 SILICON GRAPHICS INC. +08006A ATT BELL LABORATORIES +08006B ACCEL TECHNOLOGIES INC. +08006C SUNTEK TECHNOLOGY INT'L +08006D WHITECHAPEL COMPUTER WORKS +08006E MASSCOMP +08006F PHILIPS APELDOORN B.V. +080070 MITSUBISHI ELECTRIC CORP. +080071 MATRA (DSIE) +080072 XEROX CORP UNIV GRANT PROGRAM +080073 TECMAR INC. +080074 CASIO COMPUTER CO. LTD. +080075 DANSK DATA ELECTRONIK +080076 PC LAN TECHNOLOGIES +080077 TSL COMMUNICATIONS LTD. +080078 ACCELL CORPORATION +080079 THE DROID WORKS +08007A INDATA +08007B SANYO ELECTRIC CO. LTD. +08007C VITALINK COMMUNICATIONS CORP. +08007E AMALGAMATED WIRELESS(AUS) LTD +08007F CARNEGIE-MELLON UNIVERSITY +080080 AES DATA INC. +080081 ,ASTECH INC. +080082 VERITAS SOFTWARE +080083 SEIKO INSTRUM. AND ELECTRONICS +080084 TOMEN ELECTRONICS CORP. +080085 ELXSI +080086 IMAGEN CORPORATION +080087 XYPLEX +080088 MCDATA CORPORATION +080089 KINETICS +08008A PERFORMANCE TECHNOLOGY +08008B PYRAMID TECHNOLOGY CORP. +08008C NETWORK RESEARCH CORPORATION +08008D XYVISION INC. +08008E TANDEM COMPUTERS +08008F CHIPCOM CORPORATION +080090 SONOMA SYSTEMS +08BBCC AK-NORD EDV VERTRIEBSGES. MBH +10005A IBM CORPORATION +1000E8 NATIONAL SEMICONDUCTOR +800010 ATT BELL LABORATORIES +A06A00 Verilink Corporation +AA0000 DIGITAL EQUIPMENT CORPORATION +AA0001 DIGITAL EQUIPMENT CORPORATION +AA0002 DIGITAL EQUIPMENT CORPORATION +AA0003 DIGITAL EQUIPMENT CORPORATION +AA0004 DIGITAL EQUIPMENT CORPORATION diff -urN linux-2.4.21/drivers/ieee1394/oui2c.sh linux-2.4.22/drivers/ieee1394/oui2c.sh --- linux-2.4.21/drivers/ieee1394/oui2c.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/ieee1394/oui2c.sh 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,23 @@ +#!/bin/sh + +cat < + +#ifdef CONFIG_IEEE1394_OUI_DB +struct oui_list_struct { + int oui; + char *name; +} oui_list[] = { +EOF + +while read oui name; do + echo " { 0x$oui, \"$name\" }," +done + +cat < #include #include +#include #include #include #include @@ -1459,6 +1460,14 @@ case have_intr: reg_write(lynx, PCI_INT_ENABLE, 0); free_irq(lynx->dev->irq, lynx); + + /* Disable IRM Contender */ + if (lynx->phyic.reg_1394a) + set_phy_reg(lynx, 4, ~0xc0 & get_phy_reg(lynx, 4)); + + /* Let all other nodes know to ignore us */ + lynx_devctl(lynx->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT); + case have_iomappings: reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); /* Fix buggy cards with autoboot pin not tied low: */ @@ -1506,6 +1515,7 @@ return error; \ } while (0) + char irq_buf[16]; struct hpsb_host *host; struct ti_lynx *lynx; /* shortcut to currently handled device */ struct ti_pcl pcl; @@ -1605,12 +1615,18 @@ /* Fix buggy cards with autoboot pin not tied low: */ reg_write(lynx, DMA0_CHAN_CTRL, 0); +#ifndef __sparc__ + sprintf (irq_buf, "%d", dev->irq); +#else + sprintf (irq_buf, "%s", __irq_itoa(dev->irq)); +#endif + if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ, PCILYNX_DRIVER_NAME, lynx)) { - PRINT(KERN_INFO, lynx->id, "allocated interrupt %d", dev->irq); + PRINT(KERN_INFO, lynx->id, "allocated interrupt %s", irq_buf); lynx->state = have_intr; } else { - FAIL("failed to allocate shared interrupt %d", dev->irq); + FAIL("failed to allocate shared interrupt %s", irq_buf); } /* alloc_pcl return values are not checked, it is expected that the diff -urN linux-2.4.21/drivers/ieee1394/raw1394.c linux-2.4.22/drivers/ieee1394/raw1394.c --- linux-2.4.21/drivers/ieee1394/raw1394.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/raw1394.c 2003-08-25 04:44:42.000000000 -0700 @@ -44,11 +44,11 @@ #include "ieee1394.h" #include "ieee1394_types.h" #include "ieee1394_core.h" +#include "nodemgr.h" #include "hosts.h" #include "highlevel.h" #include "iso.h" #include "ieee1394_transactions.h" -#include "ieee1394_hotplug.h" #include "raw1394.h" #include "raw1394-private.h" @@ -602,7 +602,7 @@ if (fi->listen_channels & (1ULL << channel)) { req->req.error = RAW1394_ERROR_ALREADY; } else { - if(hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) { + if (hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) { req->req.error = RAW1394_ERROR_ALREADY; } else { fi->listen_channels |= 1ULL << channel; @@ -1567,8 +1567,8 @@ req->req.length, ((req->req.misc >> 8) & 0xFF), (req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF)); /* check addressrange */ - if ((((req->req.address) & ~(0xFFFFFFFFFFFF)) != 0) || - (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFF)) != 0)) { + if ((((req->req.address) & ~((u64)0xFFFFFFFFFFFFLL)) != 0) || + (((req->req.address + req->req.length) & ~((u64)0xFFFFFFFFFFFFLL)) != 0)) { req->req.length = 0; return (-EINVAL); } @@ -2009,7 +2009,7 @@ list_for_each(lh, &fi->req_complete) { req = list_entry(lh, struct pending_request, list); - if(req->req.type == RAW1394_REQ_RAWISO_ACTIVITY) { + if (req->req.type == RAW1394_REQ_RAWISO_ACTIVITY) { return 1; } } @@ -2025,17 +2025,17 @@ spin_lock_irqsave(&fi->reqlists_lock, flags); /* only one ISO activity event may be in the queue */ - if(!__rawiso_event_in_queue(fi)) { + if (!__rawiso_event_in_queue(fi)) { struct pending_request *req = __alloc_pending_request(SLAB_ATOMIC); - if(req) { + if (req) { req->file_info = fi; req->req.type = RAW1394_REQ_RAWISO_ACTIVITY; req->req.generation = get_hpsb_generation(fi->host); __queue_complete_req(req); } else { /* on allocation failure, signal an overflow */ - if(fi->iso_handle) { + if (fi->iso_handle) { atomic_inc(&fi->iso_handle->overflows); } } @@ -2055,7 +2055,7 @@ if (hi != NULL) { list_for_each(lh, &hi->file_info_list) { struct file_info *fi = list_entry(lh, struct file_info, list); - if(fi->iso_handle == iso) + if (fi->iso_handle == iso) queue_rawiso_event(fi); } } @@ -2080,7 +2080,7 @@ { struct raw1394_iso_status stat; - if(copy_from_user(&stat, uaddr, sizeof(stat))) + if (copy_from_user(&stat, uaddr, sizeof(stat))) return -EFAULT; fi->iso_handle = hpsb_iso_xmit_init(fi->host, @@ -2090,13 +2090,13 @@ stat.config.speed, stat.config.irq_interval, rawiso_activity_cb); - if(!fi->iso_handle) + if (!fi->iso_handle) return -ENOMEM; fi->iso_state = RAW1394_ISO_XMIT; raw1394_iso_fill_status(fi->iso_handle, &stat); - if(copy_to_user(uaddr, &stat, sizeof(stat))) + if (copy_to_user(uaddr, &stat, sizeof(stat))) return -EFAULT; /* queue an event to get things started */ @@ -2109,7 +2109,7 @@ { struct raw1394_iso_status stat; - if(copy_from_user(&stat, uaddr, sizeof(stat))) + if (copy_from_user(&stat, uaddr, sizeof(stat))) return -EFAULT; fi->iso_handle = hpsb_iso_recv_init(fi->host, @@ -2118,13 +2118,13 @@ stat.config.channel, stat.config.irq_interval, rawiso_activity_cb); - if(!fi->iso_handle) + if (!fi->iso_handle) return -ENOMEM; fi->iso_state = RAW1394_ISO_RECV; raw1394_iso_fill_status(fi->iso_handle, &stat); - if(copy_to_user(uaddr, &stat, sizeof(stat))) + if (copy_to_user(uaddr, &stat, sizeof(stat))) return -EFAULT; return 0; } @@ -2135,7 +2135,7 @@ struct hpsb_iso *iso = fi->iso_handle; raw1394_iso_fill_status(fi->iso_handle, &stat); - if(copy_to_user(uaddr, &stat, sizeof(stat))) + if (copy_to_user(uaddr, &stat, sizeof(stat))) return -EFAULT; /* reset overflow counter */ @@ -2151,20 +2151,20 @@ unsigned int packet = fi->iso_handle->first_packet; int i; - if(copy_from_user(&upackets, uaddr, sizeof(upackets))) + if (copy_from_user(&upackets, uaddr, sizeof(upackets))) return -EFAULT; - if(upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) + if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) return -EINVAL; /* ensure user-supplied buffer is accessible and big enough */ - if(verify_area(VERIFY_WRITE, upackets.infos, + if (verify_area(VERIFY_WRITE, upackets.infos, upackets.n_packets * sizeof(struct raw1394_iso_packet_info))) return -EFAULT; /* copy the packet_infos out */ - for(i = 0; i < upackets.n_packets; i++) { - if(__copy_to_user(&upackets.infos[i], + for (i = 0; i < upackets.n_packets; i++) { + if (__copy_to_user(&upackets.infos[i], &fi->iso_handle->infos[packet], sizeof(struct raw1394_iso_packet_info))) return -EFAULT; @@ -2181,28 +2181,28 @@ struct raw1394_iso_packets upackets; int i, rv; - if(copy_from_user(&upackets, uaddr, sizeof(upackets))) + if (copy_from_user(&upackets, uaddr, sizeof(upackets))) return -EFAULT; - if(upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) + if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) return -EINVAL; /* ensure user-supplied buffer is accessible and big enough */ - if(verify_area(VERIFY_READ, upackets.infos, + if (verify_area(VERIFY_READ, upackets.infos, upackets.n_packets * sizeof(struct raw1394_iso_packet_info))) return -EFAULT; /* copy the infos structs in and queue the packets */ - for(i = 0; i < upackets.n_packets; i++) { + for (i = 0; i < upackets.n_packets; i++) { struct raw1394_iso_packet_info info; - if(__copy_from_user(&info, &upackets.infos[i], + if (__copy_from_user(&info, &upackets.infos[i], sizeof(struct raw1394_iso_packet_info))) return -EFAULT; rv = hpsb_iso_xmit_queue_packet(fi->iso_handle, info.offset, info.len, info.tag, info.sy); - if(rv) + if (rv) return rv; } @@ -2211,7 +2211,7 @@ static void raw1394_iso_shutdown(struct file_info *fi) { - if(fi->iso_handle) + if (fi->iso_handle) hpsb_iso_shutdown(fi->iso_handle); fi->iso_handle = NULL; @@ -2223,7 +2223,7 @@ { struct file_info *fi = file->private_data; - if(fi->iso_state == RAW1394_ISO_INACTIVE) + if (fi->iso_state == RAW1394_ISO_INACTIVE) return -EINVAL; return dma_region_mmap(&fi->iso_handle->data_buf, file, vma); @@ -2250,7 +2250,7 @@ case RAW1394_IOC_ISO_RECV_START: { /* copy args from user-space */ int args[3]; - if(copy_from_user(&args[0], (void*) arg, sizeof(args))) + if (copy_from_user(&args[0], (void*) arg, sizeof(args))) return -EFAULT; return hpsb_iso_recv_start(fi->iso_handle, args[0], args[1], args[2]); } @@ -2264,7 +2264,7 @@ case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: { /* copy the u64 from user-space */ u64 mask; - if(copy_from_user(&mask, (void*) arg, sizeof(mask))) + if (copy_from_user(&mask, (void*) arg, sizeof(mask))) return -EFAULT; return hpsb_iso_recv_set_channel_mask(fi->iso_handle, mask); } @@ -2274,6 +2274,8 @@ return raw1394_iso_recv_packets(fi, (void*) arg); case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: return hpsb_iso_recv_release_packets(fi->iso_handle, arg); + case RAW1394_IOC_ISO_RECV_FLUSH: + return hpsb_iso_recv_flush(fi->iso_handle); case RAW1394_IOC_ISO_SHUTDOWN: raw1394_iso_shutdown(fi); return 0; @@ -2287,7 +2289,7 @@ case RAW1394_IOC_ISO_XMIT_START: { /* copy two ints from user-space */ int args[2]; - if(copy_from_user(&args[0], (void*) arg, sizeof(args))) + if (copy_from_user(&args[0], (void*) arg, sizeof(args))) return -EFAULT; return hpsb_iso_xmit_start(fi->iso_handle, args[0], args[1]); } @@ -2375,7 +2377,7 @@ struct arm_addr *arm_addr = NULL; int another_host; - if(fi->iso_state != RAW1394_ISO_INACTIVE) + if (fi->iso_state != RAW1394_ISO_INACTIVE) raw1394_iso_shutdown(fi); for (i = 0; i < 64; i++) { diff -urN linux-2.4.21/drivers/ieee1394/sbp2.c linux-2.4.22/drivers/ieee1394/sbp2.c --- linux-2.4.21/drivers/ieee1394/sbp2.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/sbp2.c 2003-08-25 04:44:42.000000000 -0700 @@ -4,6 +4,8 @@ * Copyright (C) 2000 James Goodwin, Filanet Corporation (www.filanet.com) * jamesg@filanet.com (JSG) * + * Copyright (C) 2003 Ben Collins + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -27,283 +29,17 @@ * driver. It also registers as a SCSI lower-level driver in order to accept * SCSI commands for transport using SBP-2. * - * - * Driver Loading: - * - * Currently, the SBP-2 driver is supported only as a module. Because the - * Linux SCSI stack is not Plug-N-Play aware, module load order is - * important. Assuming the SCSI core drivers are either built into the - * kernel or already loaded as modules, you should load the IEEE-1394 modules - * in the following order: - * - * ieee1394 (e.g. insmod ieee1394) - * ohci1394 (e.g. insmod ohci1394) - * sbp2 (e.g. insmod sbp2) - * - * The SBP-2 driver will attempt to discover any attached SBP-2 devices when first - * loaded, or after any IEEE-1394 bus reset (e.g. a hot-plug). It will then print - * out a debug message indicating if it was able to discover a SBP-2 device. - * - * Currently, the SBP-2 driver will catch any attached SBP-2 devices during the - * initial scsi bus scan (when the driver is first loaded). To add or remove - * SBP-2 devices "after" this initial scan (i.e. if you plug-in or un-plug a - * device after the SBP-2 driver is loaded), you must either use the scsi procfs - * add-single-device, remove-single-device, or a shell script such as - * rescan-scsi-bus.sh. - * * The easiest way to add/detect new SBP-2 devices is to run the shell script - * rescan-scsi-bus.sh (or re-load the SBP-2 driver). This script may be - * found at: + * rescan-scsi-bus.sh. This script may be found at: * http://www.garloff.de/kurt/linux/rescan-scsi-bus.sh * - * As an alternative, you may manually add/remove SBP-2 devices via the procfs with - * add-single-device or remove-single-device , where: - * = host (starting at zero for first SCSI adapter) - * = bus (normally zero) - * = target (starting at zero for first SBP-2 device) - * = lun (normally zero) - * - * e.g. To manually add/detect a new SBP-2 device - * echo "scsi add-single-device 0 0 0 0" > /proc/scsi/scsi - * - * e.g. To manually remove a SBP-2 device after it's been unplugged - * echo "scsi remove-single-device 0 0 0 0" > /proc/scsi/scsi - * - * e.g. To check to see which SBP-2/SCSI devices are currently registered - * cat /proc/scsi/scsi - * - * After scanning for new SCSI devices (above), you may access any attached - * SBP-2 storage devices as if they were SCSI devices (e.g. mount /dev/sda1, - * fdisk, mkfs, etc.). - * - * - * Module Load Options: - * - * sbp2_max_speed - Force max speed allowed - * (2 = 400mb, 1 = 200mb, 0 = 100mb. default = 2) - * sbp2_serialize_io - Serialize all I/O coming down from the scsi drivers - * (0 = deserialized, 1 = serialized, default = 0) - * sbp2_max_sectors, - Change max sectors per I/O supported (default = 255) - * sbp2_exclusive_login - Set to zero if you'd like to allow multiple hosts the ability - * to log in at the same time. Sbp2 device must support this, - * and you must know what you're doing (default = 1) - * - * (e.g. insmod sbp2 sbp2_serialize_io = 1) - * - * - * Current Support: - * - * The SBP-2 driver is still in an early state, but supports a variety of devices. - * I have read/written many gigabytes of data from/to SBP-2 drives, and have seen - * performance of more than 25 MBytes/s on individual drives (limit of the media - * transfer rate). - * - * - * Following are a sampling of devices that have been tested successfully: - * - * - Western Digital IEEE-1394 hard drives - * - Maxtor IEEE-1394 hard drives - * - VST (SmartDisk) IEEE-1394 hard drives and Zip drives (several flavors) - * - LaCie IEEE-1394 hard drives (several flavors) - * - QPS IEEE-1394 CD-RW/DVD drives and hard drives - * - BusLink IEEE-1394 hard drives - * - Iomega IEEE-1394 Zip/Jazz/Peerless drives - * - ClubMac IEEE-1394 hard drives - * - FirePower IEEE-1394 hard drives - * - EzQuest IEEE-1394 hard drives and CD-RW drives - * - Castlewood/ADS IEEE-1394 ORB drives - * - Evergreen IEEE-1394 hard drives and CD-RW drives - * - Addonics IEEE-1394 CD-RW drives - * - Bellstor IEEE-1394 hard drives and CD-RW drives - * - APDrives IEEE-1394 hard drives - * - Fujitsu IEEE-1394 MO drives - * - Sony IEEE-1394 CD-RW drives - * - Epson IEEE-1394 scanners - * - ADS IEEE-1394 memory stick and compact flash readers - * - SBP-2 bridge-based devices (LSI, Oxford Semiconductor, Indigita bridges) - * - Various other standard IEEE-1394 hard drives and enclosures - * - * - * Performance Issues: - * - * - Make sure you are "not" running fat/fat32 on your attached SBP-2 drives. You'll - * get much better performance formatting the drive ext2 (but you will lose the - * ability to easily move the drive between Windows/Linux). - * + * You may access any attached SBP-2 storage devices as if they were SCSI + * devices (e.g. mount /dev/sda1, fdisk, mkfs, etc.). * * Current Issues: * * - Error Handling: SCSI aborts and bus reset requests are handled somewhat * but the code needs additional debugging. - * - * - Module: The SBP-2 driver is currently only supported as a module. It would not take - * much work to allow it to be compiled into the kernel, but you'd have to - * add some init code to the kernel to support this... and modules are much - * more flexible anyway. ;-) - * - * - Hot-plugging: Interaction with the SCSI stack and support for hot-plugging could - * stand some improvement. - * - * - * History: - * - * 07/25/00 - Initial revision (JSG) - * 08/11/00 - Following changes/bug fixes were made (JSG): - * * Bug fix to SCSI procfs code (still needs to be synched with 2.4 kernel). - * * Bug fix where request sense commands were actually sent on the bus. - * * Changed bus reset/abort code to deal with devices that spin up quite - * slowly (which result in SCSI time-outs). - * * "More" properly pull information from device's config rom, for enumeration - * of SBP-2 devices, and determining SBP-2 register offsets. - * * Change Simplified Direct Access Device type to Direct Access Device type in - * returned inquiry data, in order to make the SCSI stack happy. - * * Modified driver to register with the SCSI stack "before" enumerating any attached - * SBP-2 devices. This means that you'll have to use procfs scsi-add-device or - * some sort of script to discover new SBP-2 devices. - * * Minor re-write of some code and other minor changes. - * 08/28/00 - Following changes/bug fixes were made (JSG): - * * Bug fixes to scatter/gather support (case of one s/g element) - * * Updated direction table for scsi commands (mostly DVD commands) - * * Retries when trying to detect SBP-2 devices (for slow devices) - * * Slightly better error handling (previously none) when commands time-out. - * * Misc. other bug fixes and code reorganization. - * 09/13/00 - Following changes/bug fixes were made (JSG) - * * Moved detection/enumeration code to a kernel thread which is woken up when IEEE-1394 - * bus resets occur. - * * Added code to handle bus resets and hot-plugging while devices are mounted, but full - * hot-plug support is not quite there yet. - * * Now use speed map to determine speed and max payload sizes for ORBs - * * Clean-up of code and reorganization - * 09/19/00 - Added better hot-plug support and other minor changes (JSG) - * 10/15/00 - Fixes for latest 2.4.0 test kernel, minor fix for hot-plug race. (JSG) - * 12/03/00 - Created pool of request packet structures for use in sending out sbp2 command - * and agent reset requests. This removes the kmallocs/kfrees in the critical I/O paths, - * and also deals with some subtle race conditions related to allocating and freeing - * packets. (JSG) - * 12/09/00 - Improved the sbp2 device detection by actually reading the root and unit - * directory (khk@khk.net) - * 12/23/00 - Following changes/enhancements were made (JSG) - * * Only do SCSI to RBC command conversion for Direct Access and Simplified - * Direct Access Devices (this is pulled from the config rom root directory). - * This is needed because doing the conversion for all device types broke the - * Epson scanner. Still looking for a better way of determining when to convert - * commands (for RBC devices). Thanks to khk for helping on this! - * * Added ability to "emulate" physical dma support, for host adapters such as TILynx. - * * Determine max payload and speed by also looking at the host adapter's max_rec field. - * 01/19/01 - Added checks to sbp2 login and made the login time-out longer. Also fixed a compile - * problem for 2.4.0. (JSG) - * 01/24/01 - Fixed problem when individual s/g elements are 64KB or larger. Needed to break - * up these larger elements, since the sbp2 page table element size is only 16 bits. (JSG) - * 01/29/01 - Minor byteswap fix for login response (used for reconnect and log out). - * 03/07/01 - Following changes/enhancements were made (JSG) - * * Changes to allow us to catch the initial scsi bus scan (for detecting sbp2 - * devices when first loading sbp2.o). To disable this, un-define - * SBP2_SUPPORT_INITIAL_BUS_SCAN. - * * Temporary fix to deal with many sbp2 devices that do not support individual - * transfers of greater than 128KB in size. - * * Mode sense conversion from 6 byte to 10 byte versions for CDRW/DVD devices. (Mark Burton) - * * Define allowing support for goofy sbp2 devices that do not support mode - * sense command at all, allowing them to be mounted rw (such as 1394 memory - * stick and compact flash readers). Define SBP2_MODE_SENSE_WRITE_PROTECT_HACK - * if you need this fix. - * 03/29/01 - Major performance enhancements and misc. other changes. Thanks to Daniel Berlin for many of - * changes and suggestions for change: - * * Now use sbp2 doorbell and link commands on the fly (instead of serializing requests) - * * Removed all bit fields in an attempt to run on PPC machines (still needs a little more work) - * * Added large request break-up/linking support for sbp2 chipsets that do not support transfers - * greater than 128KB in size. - * * Bumped up max commands per lun to two, and max total outstanding commands to eight. - * 04/03/01 - Minor clean-up. Write orb pointer directly if no outstanding commands (saves one 1394 bus - * transaction). Added module load options (bus scan, mode sense hack, max speed, serialize_io, - * no_large_transfers). Better bus reset handling while I/O pending. Set serialize_io to 1 by - * default (debugging of deserialized I/O in progress). - * 04/04/01 - Added workaround for PPC Pismo firewire chipset. See #define below. (Daniel Berlin) - * 04/20/01 - Minor clean-up. Allocate more orb structures when running with sbp2 target chipsets with - * 128KB max transfer limit. - * 06/16/01 - Converted DMA interfaces to pci_dma - Ben Collins - * - * - * 11/17/01 - Various bugfixes/cleanups: - * * Remember to logout of device in sbp2_disconnect. - * * If we fail to reconnect to a device after bus reset - * remember to release unit directory, so the ieee1394 - * knows we no longer manage it. - * * Unregister scsi hosts in sbp2_remove_host when a - * hpsb_host goes away. - * * Remove stupid hack in sbp2_remove_host. - * * Switched to "manual" module initialization - * (i.e. not scsi_module.c) and moved sbp2_cleanup - * moved sbp2scsi_release to sbp2_module_ext. The - * release function is called once pr. registered - * scsi host, but sbp2_cleanup should only be called - * upon module unload. Moved much initialization - * from sbp2scsi_detect to sbp2_module_init. - * Kristian Hogsberg - * 01/06/02 - Misc bug fixes/enhancements: (JSG) - * * Enable use_new_eh_code for scsi stuff. - * * Do not write all ones for NULL ORB high/low fields, but - * rather leave reserved areas zeroed (per SBP2 spec). - * * Use newer scsi transfer direction passed down instead of our - * direction table. - * * Bumped login time-out to 20 seconds, as some devices are slow. - * * Fixed a couple scsi unregister bugs on module unload - * 01/13/02 - Fixed compatibility with certain SBP2 devices, such as Iomega - * 1394 devices (Peerless, Jazz). Also a bit of clean-up of the - * driver, thanks to H.J.Lu (hjl@lucon.org). Removed mode_sense_hack - * module load option, as it's been fixed in the 2.4 scsi stack. - * 02/10/02 - Added support for max_sectors, minor fix for inquiry command, make - * up sbp2 device type from inquiry response data if not part of - * device's 1394 unit directory. (JSG) - * 02/18/02 - Code clean-up and enhancements: (JSG) - * * Finish cleaning out hacked code for dealing with broken sbp2 devices - * which do not support requests of 128KB or greater. Now use - * max_sectors scsi host entry to limit transfer sizes. - * * Change status fifo address from a single address to a set of addresses, - * with each sbp2 device having its own status fifo address. This makes - * it easier to match the status write to the sbp2 device instance. - * * Minor change to use lun when logging into sbp2 devices. First step in - * supporting multi-lun devices such as CD/DVD changer devices. - * * Added a new module load option for setting max sectors. For use by folk - * who'd like to bump up the max scsi transfer size supported. - * * Enabled deserialized operation by default, allowing for better performance, - * particularily when running with multiple sbp2 devices. For debugging, - * you may enable serialization through use of the sbp2_serialize_io module - * load option (e.g. insmod sbp2 sbp2_serialize_io=1). - * 02/20/02 - Added a couple additional module load options. - * Needed to bump down max commands per lun because of the !%@&*^# QPS CDRW - * drive I have, which doesn't seem to get along with other sbp2 devices - * (or handle linked commands well). - * 04/21/02 - Added some additional debug capabilities: - * * Able to handle phys dma requests directly, if host controller has phys - * dma disabled (e.g. insmod ohci1394 phys_dma=0). Undefine CONFIG_IEEE1394_SBP2_PHYS_DMA - * if you'd like to disable sbp2 driver from registering for phys address range. - * * New packet dump debug define (CONFIG_IEEE1394_SBP2_PACKET_DUMP) which allows - * dumping of all sbp2 related packets sent and received. Especially effective - * when phys dma is disabled on ohci controller (e.g. insmod ohci1394 phys_dma=0). - * * Added new sbp2 module load option (sbp2_exclusive_login) for allowing - * non-exclusive login to sbp2 device, for special multi-host applications. - * 04/23/02 - Fix for Sony CD-ROM drives. Only send fetch agent reset to sbp2 device if it - * returns the dead bit in status. Thanks to Chandan (chandan@toad.net) for this one. - * 04/27/02 - Fix sbp2 login problem on SMP systems, enable real spinlocks by default. (JSG) - * 06/09/02 - Don't force 36-bute SCSI inquiry, but leave in a define for badly behaved devices. (JSG) - * 02/04/03 - Fixed a SMP deadlock (don't hold sbp2_command_lock while calling sbp2scsi_complete_command). - * Also save/restore irq flags in sbp2scsi_complete_command - Sancho Dauskardt - * - */ - - -/* - * Includes */ #include @@ -321,6 +57,8 @@ #include #include #include +#include + #include #include #include @@ -343,15 +81,15 @@ #include "ieee1394.h" #include "ieee1394_types.h" #include "ieee1394_core.h" +#include "nodemgr.h" #include "hosts.h" #include "nodemgr.h" #include "highlevel.h" #include "ieee1394_transactions.h" -#include "ieee1394_hotplug.h" #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 906 $ James Goodwin "; + "$Rev: 1010 $ Ben Collins "; /* * Module load parameter definitions @@ -367,7 +105,7 @@ */ MODULE_PARM(sbp2_max_speed,"i"); MODULE_PARM_DESC(sbp2_max_speed, "Force max speed (3 = 800mb, 2 = 400mb default, 1 = 200mb, 0 = 100mb)"); -static int sbp2_max_speed = SPEED_MAX; +static int sbp2_max_speed = IEEE1394_SPEED_MAX; /* * Set sbp2_serialize_io to 1 if you'd like only one scsi command sent @@ -489,6 +227,13 @@ #define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args) +/* If you get the linux-2.4 scsi_{add,remove}_single_device patch, you can + * enable this define to make use of it. This provides better hotplug + * support. The mentioned patch is not part of the kernel proper though, + * because it is considered somewhat of a hack. */ +//#define SBP2_USE_SCSI_ADDREM_HACK + + /* * Globals */ @@ -502,9 +247,10 @@ static Scsi_Host_Template scsi_driver_template; +const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC }; + static struct hpsb_highlevel sbp2_highlevel = { .name = SBP2_DEVICE_NAME, - .add_host = sbp2_add_host, .remove_host = sbp2_remove_host, }; @@ -815,22 +561,22 @@ /* Free our DMA's */ static void sbp2util_free_command_dma(struct sbp2_command_info *command) { - struct sbp2scsi_host_info *hi; + struct hpsb_host *host; - hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel, + host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)command->Current_SCpnt->device->host->hostt); - if (!hi) { - printk(KERN_ERR "%s: hi == NULL\n", __FUNCTION__); + if (!host) { + printk(KERN_ERR "%s: host == NULL\n", __FUNCTION__); return; } if (command->cmd_dma) { if (command->dma_type == CMD_DMA_SINGLE) { - pci_unmap_single(hi->host->pdev, command->cmd_dma, + pci_unmap_single(host->pdev, command->cmd_dma, command->dma_size, command->dma_dir); SBP2_DMA_FREE("single bulk"); } else if (command->dma_type == CMD_DMA_PAGE) { - pci_unmap_page(hi->host->pdev, command->cmd_dma, + pci_unmap_page(host->pdev, command->cmd_dma, command->dma_size, command->dma_dir); SBP2_DMA_FREE("single page"); } /* XXX: Check for CMD_DMA_NONE bug */ @@ -839,7 +585,7 @@ } if (command->sge_buffer) { - pci_unmap_sg(hi->host->pdev, command->sge_buffer, + pci_unmap_sg(host->pdev, command->sge_buffer, command->dma_size, command->dma_dir); SBP2_DMA_FREE("scatter list"); command->sge_buffer = NULL; @@ -873,7 +619,7 @@ static int sbp2scsi_detect(Scsi_Host_Template *tpnt) { struct Scsi_Host *scsi_host; - struct sbp2scsi_host_info *hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel, (unsigned long)tpnt); + struct hpsb_host *host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)tpnt); SBP2_DEBUG("sbp2scsi_detect"); @@ -881,7 +627,7 @@ if (!(scsi_host = scsi_register(tpnt, 0))) return 0; - scsi_set_pci_device(scsi_host, hi->host->pdev); + scsi_set_pci_device(scsi_host, host->pdev); tpnt->present = 1; @@ -892,81 +638,112 @@ { struct sbp2scsi_host_info *hi; - SBP2_DEBUG("sbp2_probe"); - hi = hpsb_get_hostinfo(&sbp2_highlevel, ud->ne->host); + SBP2_DEBUG(__FUNCTION__); + + /* Don't probe UD's that have the LUN flag. We'll probe the LUN(s) + * instead. */ + if (ud->flags & UNIT_DIRECTORY_HAS_LUN_DIRECTORY) + return -1; - return sbp2_start_device(hi, ud); + /* This will only add it if it doesn't exist */ + hi = sbp2_add_host(ud->ne->host); + + if (!hi) + return -1; + + return sbp2_start_ud(hi, ud); } static void sbp2_disconnect(struct unit_directory *ud) { - struct scsi_id_instance_data *scsi_id = ud->driver_data; + struct scsi_id_group *scsi_group = ud->driver_data; + struct list_head *lh, *next; + struct scsi_id_instance_data *scsi_id; SBP2_DEBUG("sbp2_disconnect"); - if (scsi_id) { - sbp2_logout_device(scsi_id); - sbp2_remove_device(scsi_id); + list_for_each_safe (lh, next, &scsi_group->scsi_id_list) { + scsi_id = list_entry(lh, struct scsi_id_instance_data, list); + if (scsi_id) { + sbp2_logout_device(scsi_id); + sbp2_remove_device(scsi_id); + } } + + kfree(scsi_group); } static void sbp2_update(struct unit_directory *ud) { struct sbp2scsi_host_info *hi; - struct scsi_id_instance_data *scsi_id = ud->driver_data; + struct scsi_id_group *scsi_group = ud->driver_data; + struct list_head *lh, *next; + struct scsi_id_instance_data *scsi_id; unsigned long flags; SBP2_DEBUG("sbp2_update"); hi = hpsb_get_hostinfo(&sbp2_highlevel, ud->ne->host); - if (sbp2_reconnect_device(scsi_id)) { - - /* - * Ok, reconnect has failed. Perhaps we didn't - * reconnect fast enough. Try doing a regular login. - */ - if (sbp2_login_device(scsi_id)) { - /* Login failed too, just remove the device. */ - SBP2_ERR("sbp2_reconnect_device failed!"); - sbp2_remove_device(scsi_id); - hpsb_release_unit_directory(ud); - return; + list_for_each_safe (lh, next, &scsi_group->scsi_id_list) { + scsi_id = list_entry(lh, struct scsi_id_instance_data, list); + + if (sbp2_reconnect_device(scsi_id)) { + /* + * Ok, reconnect has failed. Perhaps we didn't + * reconnect fast enough. Try doing a regular login. + */ + if (sbp2_login_device(scsi_id)) { + /* Login failed too, just remove the device. */ + SBP2_ERR("sbp2_reconnect_device failed!"); + sbp2_remove_device(scsi_id); + continue; + } } - } - /* Set max retries to something large on the device. */ - sbp2_set_busy_timeout(scsi_id); + /* Set max retries to something large on the device. */ + sbp2_set_busy_timeout(scsi_id); - /* Do a SBP-2 fetch agent reset. */ - sbp2_agent_reset(scsi_id, 0); + /* Do a SBP-2 fetch agent reset. */ + sbp2_agent_reset(scsi_id, 0); - /* Get the max speed and packet size that we can use. */ - sbp2_max_speed_and_size(scsi_id); + /* Get the max speed and packet size that we can use. */ + sbp2_max_speed_and_size(scsi_id); - /* Complete any pending commands with busy (so they get - * retried) and remove them from our queue - */ - spin_lock_irqsave(&hi->sbp2_command_lock, flags); - sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); - spin_unlock_irqrestore(&hi->sbp2_command_lock, flags); + /* Complete any pending commands with busy (so they get + * retried) and remove them from our queue + */ + spin_lock_irqsave(&hi->sbp2_command_lock, flags); + sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); + spin_unlock_irqrestore(&hi->sbp2_command_lock, flags); + } + + if (list_empty(&scsi_group->scsi_id_list)) { + hpsb_release_unit_directory(ud); + kfree(scsi_group); + } } /* * We go ahead and allocate some memory for our host info structure, and * init some structures. */ -static void sbp2_add_host(struct hpsb_host *host) +static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host) { struct sbp2scsi_host_info *hi; SBP2_DEBUG("sbp2_add_host"); + /* Check for existing hostinfo */ + hi = hpsb_get_hostinfo(&sbp2_highlevel, host); + if (hi) + return hi; + /* Allocate some memory for our host info structure */ hi = hpsb_create_hostinfo(&sbp2_highlevel, host, sizeof(*hi)); if (hi == NULL) { SBP2_ERR("out of memory in sbp2_add_host"); - return; + return NULL; } /* Initialize some host stuff */ @@ -981,7 +758,7 @@ if (SCSI_REGISTER_HOST(&hi->sht)) { SBP2_ERR("Failed to register scsi template for ieee1394 host"); hpsb_destroy_hostinfo(&sbp2_highlevel, host); - return; + return NULL; } for (hi->scsi_host = scsi_hostlist; hi->scsi_host; hi->scsi_host = hi->scsi_host->next) @@ -992,12 +769,12 @@ SBP2_ERR("Failed to register scsi host for ieee1394 host"); SCSI_UNREGISTER_HOST(&hi->sht); hpsb_destroy_hostinfo(&sbp2_highlevel, host); - return; + return NULL; } hi->scsi_host->max_id = SBP2SCSI_MAX_SCSI_IDS; - return; + return hi; } @@ -1014,34 +791,61 @@ if (hi) SCSI_UNREGISTER_HOST(&hi->sht); - else - SBP2_ERR("attempt to remove unknown host %p", host); } +static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *ud) +{ + struct scsi_id_instance_data *scsi_id; + struct scsi_id_group *scsi_group; + struct list_head *lh, *next; + + SBP2_DEBUG("sbp2_start_ud"); + + scsi_group = kmalloc(sizeof(*scsi_group), GFP_KERNEL); + if (!scsi_group) { + SBP2_ERR ("Could not allocate memory for scsi_group"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&scsi_group->scsi_id_list); + ud->driver_data = scsi_group; + sbp2_parse_unit_directory(scsi_group, ud); + + list_for_each_safe (lh, next, &scsi_group->scsi_id_list) { + scsi_id = list_entry(lh, struct scsi_id_instance_data, list); + + scsi_id->ne = ud->ne; + scsi_id->hi = hi; + scsi_id->speed_code = IEEE1394_SPEED_100; + scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; + atomic_set(&scsi_id->sbp2_login_complete, 0); + INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); + INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); + scsi_id->sbp2_command_orb_lock = SPIN_LOCK_UNLOCKED; + + sbp2_start_device(scsi_id); + } + + /* Check to see if any of our devices survived the ordeal */ + if (list_empty(&scsi_group->scsi_id_list)) { + kfree(scsi_group); + return -ENODEV; + } + + return 0; +} + + /* * This function is where we first pull the node unique ids, and then * allocate memory and register a SBP-2 device. */ -static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_directory *ud) +static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) { - struct scsi_id_instance_data *scsi_id = NULL; - struct node_entry *ne; + struct sbp2scsi_host_info *hi = scsi_id->hi; int i; SBP2_DEBUG("sbp2_start_device"); - ne = ud->ne; - - /* - * This really is a "new" device plugged in. Let's allocate memory - * for our scsi id instance data. - */ - scsi_id = (struct scsi_id_instance_data *)kmalloc(sizeof(struct scsi_id_instance_data), - GFP_KERNEL); - if (!scsi_id) - goto alloc_fail_first; - memset(scsi_id, 0, sizeof(struct scsi_id_instance_data)); - - scsi_id->hi = hi; /* Login FIFO DMA */ scsi_id->login_response = @@ -1130,7 +934,9 @@ } kfree(scsi_id); -alloc_fail_first: + + list_del(&scsi_id->list); + SBP2_ERR ("Could not allocate memory for scsi_id"); return -ENOMEM; @@ -1138,31 +944,6 @@ SBP2_DMA_ALLOC("consistent DMA region for login ORB"); /* - * Initialize some of the fields in this structure - */ - scsi_id->ne = ne; - scsi_id->ud = ud; - scsi_id->speed_code = SPEED_100; - scsi_id->max_payload_size = hpsb_speedto_maxrec[SPEED_100]; - ud->driver_data = scsi_id; - - atomic_set(&scsi_id->sbp2_login_complete, 0); - - /* - * Initialize structures needed for the command orb pool. - */ - INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); - INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); - scsi_id->sbp2_command_orb_lock = SPIN_LOCK_UNLOCKED; - - /* - * Make sure that we've gotten ahold of the sbp2 management agent - * address. Also figure out the command set being used (SCSI or - * RBC). - */ - sbp2_parse_unit_directory(scsi_id); - - /* * Find an empty spot to stick our scsi id instance data. */ for (i = 0; i < hi->scsi_host->max_id; i++) { @@ -1216,6 +997,12 @@ */ sbp2_max_speed_and_size(scsi_id); +#ifdef SBP2_USE_SCSI_ADDREM_HACK + /* Try to hook ourselves into the SCSI subsystem */ + if (scsi_add_single_device(hi->scsi_host, 0, scsi_id->id, 0)) + SBP2_INFO("Unable to connect SBP-2 device into the SCSI subsystem"); +#endif + return 0; } @@ -1286,6 +1073,8 @@ SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->id); + list_del(&scsi_id->list); + kfree(scsi_id); } @@ -1362,6 +1151,8 @@ scsi_id->query_logins_orb->lun_misc |= ORB_SET_NOTIFY(1); if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) { scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun); + SBP2_DEBUG("sbp2_query_logins: set lun to %d", + ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun)); } SBP2_DEBUG("sbp2_query_logins: lun_misc initialized"); @@ -1379,7 +1170,7 @@ SBP2_DEBUG("sbp2_query_logins: orb byte-swapped"); - sbp2util_packet_dump(scsi_id->query_logins_orb, sizeof(stuct sbp2_query_logins_orb), + sbp2util_packet_dump(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb), "sbp2 query logins orb", scsi_id->query_logins_orb_dma); memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); @@ -1474,6 +1265,8 @@ /* Set the lun if we were able to pull it from the device's unit directory */ if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) { scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun); + SBP2_DEBUG("sbp2_query_logins: set lun to %d", + ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun)); } SBP2_DEBUG("sbp2_login_device: lun_misc initialized"); @@ -1514,7 +1307,8 @@ atomic_set(&scsi_id->sbp2_login_complete, 0); - SBP2_DEBUG("sbp2_login_device: prepared to write"); + SBP2_DEBUG("sbp2_login_device: prepared to write to %08x", + (unsigned int)scsi_id->sbp2_management_agent_addr); hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); SBP2_DEBUG("sbp2_login_device: written"); @@ -1625,8 +1419,14 @@ SBP2_INFO("Logged out of SBP-2 device"); - return(0); +#ifdef SBP2_USE_SCSI_ADDREM_HACK + /* Now that we are logged out of the SBP-2 device, lets + * try to un-hook ourselves from the SCSI subsystem */ + if (scsi_remove_single_device(hi->scsi_host, 0, scsi_id->id, 0)) + SBP2_INFO("Unable to disconnect SBP-2 device from the SCSI subsystem"); +#endif + return 0; } /* @@ -1745,50 +1545,50 @@ * directory. Used to determine things like sbp2 management agent offset, * and command set used (SCSI or RBC). */ -static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id) +static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group, + struct unit_directory *ud) { - struct unit_directory *ud; + struct scsi_id_instance_data *scsi_id; + struct list_head *lh; + u64 management_agent_addr; + u32 command_set_spec_id, command_set, unit_characteristics, + firmware_revision, workarounds; int i; SBP2_DEBUG("sbp2_parse_unit_directory"); - /* Initialize some fields, in case an entry does not exist */ - scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED; - scsi_id->sbp2_management_agent_addr = 0x0; - scsi_id->sbp2_command_set_spec_id = 0x0; - scsi_id->sbp2_command_set = 0x0; - scsi_id->sbp2_unit_characteristics = 0x0; - scsi_id->sbp2_firmware_revision = 0x0; - - ud = scsi_id->ud; + management_agent_addr = 0x0; + command_set_spec_id = 0x0; + command_set = 0x0; + unit_characteristics = 0x0; + firmware_revision = 0x0; /* Handle different fields in the unit directory, based on keys */ for (i = 0; i < ud->length; i++) { switch (CONFIG_ROM_KEY(ud->quadlets[i])) { case SBP2_CSR_OFFSET_KEY: /* Save off the management agent address */ - scsi_id->sbp2_management_agent_addr = + management_agent_addr = CSR_REGISTER_BASE + (CONFIG_ROM_VALUE(ud->quadlets[i]) << 2); SBP2_DEBUG("sbp2_management_agent_addr = %x", - (unsigned int) scsi_id->sbp2_management_agent_addr); + (unsigned int) management_agent_addr); break; case SBP2_COMMAND_SET_SPEC_ID_KEY: /* Command spec organization */ - scsi_id->sbp2_command_set_spec_id + command_set_spec_id = CONFIG_ROM_VALUE(ud->quadlets[i]); SBP2_DEBUG("sbp2_command_set_spec_id = %x", - (unsigned int) scsi_id->sbp2_command_set_spec_id); + (unsigned int) command_set_spec_id); break; case SBP2_COMMAND_SET_KEY: /* Command set used by sbp2 device */ - scsi_id->sbp2_command_set - = CONFIG_ROM_VALUE(ud->quadlets[i]); + command_set = CONFIG_ROM_VALUE(ud->quadlets[i]); SBP2_DEBUG("sbp2_command_set = %x", - (unsigned int) scsi_id->sbp2_command_set); + (unsigned int) command_set); break; case SBP2_UNIT_CHARACTERISTICS_KEY: @@ -1796,10 +1596,10 @@ * Unit characterisitcs (orb related stuff * that I'm not yet paying attention to) */ - scsi_id->sbp2_unit_characteristics + unit_characteristics = CONFIG_ROM_VALUE(ud->quadlets[i]); SBP2_DEBUG("sbp2_unit_characteristics = %x", - (unsigned int) scsi_id->sbp2_unit_characteristics); + (unsigned int) unit_characteristics); break; case SBP2_DEVICE_TYPE_AND_LUN_KEY: @@ -1807,21 +1607,29 @@ * Device type and lun (used for * detemining type of sbp2 device) */ + scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL); + if (!scsi_id) { + SBP2_ERR("Out of memory adding scsi_id, not all LUN's will be added"); + break; + } + memset(scsi_id, 0, sizeof(*scsi_id)); + scsi_id->sbp2_device_type_and_lun = CONFIG_ROM_VALUE(ud->quadlets[i]); SBP2_DEBUG("sbp2_device_type_and_lun = %x", (unsigned int) scsi_id->sbp2_device_type_and_lun); + list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list); break; case SBP2_FIRMWARE_REVISION_KEY: /* Firmware revision */ - scsi_id->sbp2_firmware_revision + firmware_revision = CONFIG_ROM_VALUE(ud->quadlets[i]); if (sbp2_force_inquiry_hack) SBP2_INFO("sbp2_firmware_revision = %x", - (unsigned int) scsi_id->sbp2_firmware_revision); + (unsigned int) firmware_revision); else SBP2_DEBUG("sbp2_firmware_revision = %x", - (unsigned int) scsi_id->sbp2_firmware_revision); + (unsigned int) firmware_revision); break; default: @@ -1831,7 +1639,7 @@ /* This is the start of our broken device checking. We try to hack * around oddities and known defects. */ - scsi_id->workarounds = 0x0; + workarounds = 0x0; /* If the vendor id is 0xa0b8 (Symbios vendor id), then we have a * bridge with 128KB max transfer size limitation. For sanity, we @@ -1842,28 +1650,60 @@ * host gets initialized. That way we can down-force the * sbp2_max_sectors to account for it. That is not currently * possible. */ - if ((scsi_id->sbp2_firmware_revision & 0xffff00) == + if ((firmware_revision & 0xffff00) == SBP2_128KB_BROKEN_FIRMWARE && (sbp2_max_sectors * 512) > (128 * 1024)) { SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.", - NODE_BUS_ARGS(scsi_id->ne->nodeid)); + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); SBP2_WARN("WARNING: Current sbp2_max_sectors setting is larger than 128KB (%d sectors)!", sbp2_max_sectors); - scsi_id->workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER; + workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER; } /* Check for a blacklisted set of devices that require us to force * a 36 byte host inquiry. This can be overriden as a module param * (to force all hosts). */ for (i = 0; i < NUM_BROKEN_INQUIRY_DEVS; i++) { - if ((scsi_id->sbp2_firmware_revision & 0xffff00) == + if ((firmware_revision & 0xffff00) == sbp2_broken_inquiry_list[i]) { SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", - NODE_BUS_ARGS(scsi_id->ne->nodeid)); - scsi_id->workarounds |= SBP2_BREAKAGE_INQUIRY_HACK; + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); + workarounds |= SBP2_BREAKAGE_INQUIRY_HACK; break; /* No need to continue. */ } } + + /* If this is a logical unit directory entry, process the parent + * to get the common values. */ + if (ud->flags & UNIT_DIRECTORY_LUN_DIRECTORY) { + sbp2_parse_unit_directory(scsi_group, ud->parent); + } else { + /* If our list is empty, add a base scsi_id (happens in a normal + * case where there is no logical_unit_number entry */ + if (list_empty(&scsi_group->scsi_id_list)) { + scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL); + if (!scsi_id) { + SBP2_ERR("Out of memory adding scsi_id"); + return; + } + memset(scsi_id, 0, sizeof(*scsi_id)); + + scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED; + list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list); + } + + /* Update the generic fields in all the LUN's */ + list_for_each (lh, &scsi_group->scsi_id_list) { + scsi_id = list_entry(lh, struct scsi_id_instance_data, list); + + scsi_id->sbp2_management_agent_addr = management_agent_addr; + scsi_id->sbp2_command_set_spec_id = command_set_spec_id; + scsi_id->sbp2_command_set = command_set; + scsi_id->sbp2_unit_characteristics = unit_characteristics; + scsi_id->sbp2_firmware_revision = firmware_revision; + scsi_id->workarounds = workarounds; + } + } } /* @@ -1894,11 +1734,12 @@ /* Payload size is the lesser of what our speed supports and what * our host supports. */ - scsi_id->max_payload_size = min(hpsb_speedto_maxrec[scsi_id->speed_code], + scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code], (u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1)); - SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]", - NODE_BUS_ARGS(scsi_id->ne->nodeid), hpsb_speedto_str[scsi_id->speed_code], + SBP2_ERR("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]", + NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid), + hpsb_speedto_str[scsi_id->speed_code], 1 << ((u32)scsi_id->max_payload_size + 2)); return(0); @@ -3053,28 +2894,27 @@ int length, int hostno, int inout) { Scsi_Device *scd; - struct Scsi_Host *host; - struct sbp2scsi_host_info *hi; + struct Scsi_Host *scsi_host; + struct hpsb_host *host; char *pos = buffer; /* if someone is sending us data, just throw it away */ if (inout) return length; - for (host = scsi_hostlist; host; host = host->next) - if (host->host_no == hostno) + for (scsi_host = scsi_hostlist; scsi_host; scsi_host = scsi_host->next) + if (scsi_host->host_no == hostno) break; - if (!host) /* if we couldn't find it, we return an error */ + if (!scsi_host) /* if we couldn't find it, we return an error */ return -ESRCH; - hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel, (unsigned long)host->hostt); - if (!hi) /* shouldn't happen, but... */ + host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)scsi_host->hostt); + if (!host) /* shouldn't happen, but... */ return -ESRCH; SPRINTF("Host scsi%d : SBP-2 IEEE-1394 (%s)\n", hostno, - hi->host->driver->name); - SPRINTF("Driver version : %s\n", version); + host->driver->name); SPRINTF("\nModule options :\n"); SPRINTF(" max_speed : %s\n", hpsb_speedto_str[sbp2_max_speed]); @@ -3082,9 +2922,9 @@ SPRINTF(" serialize_io : %s\n", sbp2_serialize_io ? "yes" : "no"); SPRINTF(" exclusive_login : %s\n", sbp2_exclusive_login ? "yes" : "no"); - SPRINTF("\nAttached devices : %s\n", host->host_queue ? "" : "none"); + SPRINTF("\nAttached devices : %s\n", scsi_host->host_queue ? "" : "none"); - for (scd = host->host_queue; scd; scd = scd->next) { + for (scd = scsi_host->host_queue; scd; scd = scd->next) { int i; SPRINTF(" [Channel: %02d, Id: %02d, Lun: %02d] ", scd->channel, @@ -3117,7 +2957,7 @@ } -MODULE_AUTHOR("James Goodwin "); +MODULE_AUTHOR("Ben Collins "); MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver"); MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME); MODULE_LICENSE("GPL"); @@ -3149,6 +2989,8 @@ { SBP2_DEBUG("sbp2_module_init"); + printk(KERN_INFO "sbp2: %s\n", version); + /* Module load debug option to force one command at a time (serializing I/O) */ if (sbp2_serialize_io) { SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)"); diff -urN linux-2.4.21/drivers/ieee1394/sbp2.h linux-2.4.22/drivers/ieee1394/sbp2.h --- linux-2.4.21/drivers/ieee1394/sbp2.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/sbp2.h 2003-08-25 04:44:42.000000000 -0700 @@ -388,7 +388,6 @@ /* * Values pulled from the device's unit directory */ - struct unit_directory *ud; u32 sbp2_command_set_spec_id; u32 sbp2_command_set; u32 sbp2_unit_characteristics; @@ -407,6 +406,8 @@ struct list_head sbp2_command_orb_inuse; struct list_head sbp2_command_orb_completed; + struct list_head list; + /* Node entry, as retrieved from NodeMgr entries */ struct node_entry *ne; @@ -417,6 +418,13 @@ u32 workarounds; }; + +/* Describes a per-ud scsi_id group */ +struct scsi_id_group { + struct list_head scsi_id_list; +}; + + /* * Sbp2 host data structure (one per sbp2 host) */ @@ -461,14 +469,15 @@ /* * IEEE-1394 core driver related prototypes */ -static void sbp2_add_host(struct hpsb_host *host); +static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host); static void sbp2_remove_host(struct hpsb_host *host); static int sbp2_probe(struct unit_directory *ud); static void sbp2_disconnect(struct unit_directory *ud); static void sbp2_update(struct unit_directory *ud); -static int sbp2_start_device(struct sbp2scsi_host_info *hi, - struct unit_directory *ud); +static int sbp2_start_ud(struct sbp2scsi_host_info *hi, + struct unit_directory *ud); +static int sbp2_start_device(struct scsi_id_instance_data *scsi_id); static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id); #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA @@ -502,7 +511,8 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data); static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd); static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, Scsi_Cmnd *SCpnt); -static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id); +static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group, + struct unit_directory *ud); static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id); static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id); diff -urN linux-2.4.21/drivers/ieee1394/video1394.c linux-2.4.22/drivers/ieee1394/video1394.c --- linux-2.4.21/drivers/ieee1394/video1394.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/ieee1394/video1394.c 2003-08-25 04:44:42.000000000 -0700 @@ -46,7 +46,7 @@ #include "ieee1394.h" #include "ieee1394_types.h" -#include "ieee1394_hotplug.h" +#include "nodemgr.h" #include "hosts.h" #include "ieee1394_core.h" #include "highlevel.h" @@ -594,7 +594,7 @@ it_prg[i].begin.status = 0; it_prg[i].data[0] = cpu_to_le32( - (SPEED_100 << 16) + (IEEE1394_SPEED_100 << 16) | (/* tag */ 1 << 14) | (d->channel << 8) | (TCODE_ISO_DATA << 4)); @@ -713,7 +713,7 @@ struct dma_iso_ctx *d; int i; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; /* if channel < 0, find lowest available one */ @@ -810,7 +810,7 @@ v.channel); } - if(copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user((void *)arg, &v, sizeof(v))) return -EFAULT; return 0; @@ -824,7 +824,7 @@ u64 mask; struct dma_iso_ctx *d; - if(copy_from_user(&channel, (void *)arg, sizeof(int))) + if (copy_from_user(&channel, (void *)arg, sizeof(int))) return -EFAULT; if (channel<0 || channel>(ISO_CHANNELS-1)) { @@ -860,7 +860,7 @@ struct video1394_wait v; struct dma_iso_ctx *d; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -924,7 +924,7 @@ struct dma_iso_ctx *d; int i; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -953,12 +953,12 @@ } #if 1 - while(d->buffer_status[v.buffer]!= + while (d->buffer_status[v.buffer]!= VIDEO1394_BUFFER_READY) { spin_unlock_irqrestore(&d->lock, flags); interruptible_sleep_on(&d->waitq); spin_lock_irqsave(&d->lock, flags); - if(signal_pending(current)) { + if (signal_pending(current)) { spin_unlock_irqrestore(&d->lock,flags); return -EINTR; } @@ -995,7 +995,7 @@ spin_unlock_irqrestore(&d->lock, flags); v.buffer=i; - if(copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user((void *)arg, &v, sizeof(v))) return -EFAULT; return 0; @@ -1007,7 +1007,9 @@ struct video1394_queue_variable qv; struct dma_iso_ctx *d; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + qv.packet_sizes = NULL; + + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); @@ -1019,12 +1021,22 @@ } if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { + unsigned int *psizes; + int buf_size = d->nb_cmd * sizeof(unsigned int); + if (copy_from_user(&qv, (void *)arg, sizeof(qv))) return -EFAULT; - if (!access_ok(VERIFY_READ, qv.packet_sizes, - d->nb_cmd * sizeof(unsigned int))) { + + psizes = kmalloc(buf_size, GFP_KERNEL); + if (!psizes) + return -ENOMEM; + + if (copy_from_user(psizes, qv.packet_sizes, buf_size)) { + kfree(psizes); return -EFAULT; } + + qv.packet_sizes = psizes; } spin_lock_irqsave(&d->lock,flags); @@ -1033,6 +1045,8 @@ PRINT(KERN_ERR, ohci->id, "Buffer %d is already used",v.buffer); spin_unlock_irqrestore(&d->lock,flags); + if (qv.packet_sizes) + kfree(qv.packet_sizes); return -EFAULT; } @@ -1086,6 +1100,10 @@ reg_write(ohci, d->ctrlSet, 0x1000); } } + + if (qv.packet_sizes) + kfree(qv.packet_sizes); + return 0; } @@ -1095,7 +1113,7 @@ struct video1394_wait v; struct dma_iso_ctx *d; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); @@ -1112,10 +1130,10 @@ return 0; case VIDEO1394_BUFFER_QUEUED: #if 1 - while(d->buffer_status[v.buffer]!= + while (d->buffer_status[v.buffer]!= VIDEO1394_BUFFER_READY) { interruptible_sleep_on(&d->waitq); - if(signal_pending(current)) return -EINTR; + if (signal_pending(current)) return -EINTR; } #else if (wait_event_interruptible(d->waitq, diff -urN linux-2.4.21/drivers/input/keybdev.c linux-2.4.22/drivers/input/keybdev.c --- linux-2.4.21/drivers/input/keybdev.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/input/keybdev.c 2003-08-25 04:44:42.000000000 -0700 @@ -172,7 +172,8 @@ if (type != EV_KEY) return; if (emulate_raw(code, down)) - printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", code); + if(code < BTN_MISC) + printk(KERN_WARNING "keybdev.c: can't emulate rawmode for keycode %d\n", code); tasklet_schedule(&keyboard_tasklet); } diff -urN linux-2.4.21/drivers/isdn/Config.in linux-2.4.22/drivers/isdn/Config.in --- linux-2.4.21/drivers/isdn/Config.in 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/isdn/Config.in 2003-08-25 04:44:42.000000000 -0700 @@ -8,6 +8,7 @@ if [ "$CONFIG_INET" != "n" ]; then bool ' Support synchronous PPP' CONFIG_ISDN_PPP if [ "$CONFIG_ISDN_PPP" != "n" ]; then + bool ' PPP filtering for ISDN' CONFIG_IPPP_FILTER $CONFIG_FILTER bool ' Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ bool ' Support generic MP (RFC 1717)' CONFIG_ISDN_MPP dep_tristate ' Support BSD compression' CONFIG_ISDN_PPP_BSDCOMP $CONFIG_ISDN diff -urN linux-2.4.21/drivers/isdn/hisax/avma1_cs.c linux-2.4.22/drivers/isdn/hisax/avma1_cs.c --- linux-2.4.21/drivers/isdn/hisax/avma1_cs.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/isdn/hisax/avma1_cs.c 2003-08-25 04:44:42.000000000 -0700 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff -urN linux-2.4.21/drivers/isdn/hisax/config.c linux-2.4.22/drivers/isdn/hisax/config.c --- linux-2.4.21/drivers/isdn/hisax/config.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/isdn/hisax/config.c 2003-08-25 04:44:42.000000000 -0700 @@ -1925,6 +1925,8 @@ break; case PH_DEACTIVATE | INDICATION: st->l1.l1l2(st, pr, NULL); + clear_bit(BC_FLG_BUSY, &bcs->Flag); + skb_queue_purge(&bcs->squeue); bcs->hw.b_if = NULL; break; case PH_DATA | INDICATION: @@ -2012,6 +2014,9 @@ else set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; + case PH_DEACTIVATE | REQUEST: + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + skb_queue_purge(&bcs->squeue); default: B_L2L1(b_if, pr, arg); break; diff -urN linux-2.4.21/drivers/isdn/hisax/hisax_fcpcipnp.c linux-2.4.22/drivers/isdn/hisax/hisax_fcpcipnp.c --- linux-2.4.21/drivers/isdn/hisax/hisax_fcpcipnp.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/isdn/hisax/hisax_fcpcipnp.c 2003-08-25 04:44:42.000000000 -0700 @@ -515,6 +515,7 @@ } skb_push(bcs->tx_skb, bcs->tx_cnt); bcs->tx_cnt = 0; + hdlc_fill_fifo(bcs); } static inline void hdlc_xpr_irq(struct fritz_bcs *bcs) diff -urN linux-2.4.21/drivers/isdn/hisax/st5481_d.c linux-2.4.22/drivers/isdn/hisax/st5481_d.c --- linux-2.4.21/drivers/isdn/hisax/st5481_d.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/isdn/hisax/st5481_d.c 2003-08-25 04:44:42.000000000 -0700 @@ -162,8 +162,8 @@ {ST_L1_F8, EV_TIMER3, l1_timer3}, {ST_L1_F8, EV_IND_DP, l1_go_f3}, {ST_L1_F8, EV_IND_AP, l1_go_f6}, - {ST_L1_F8, EV_IND_AI8, l1_go_f8}, - {ST_L1_F8, EV_IND_AI10, l1_go_f8}, + {ST_L1_F8, EV_IND_AI8, l1_go_f7}, + {ST_L1_F8, EV_IND_AI10, l1_go_f7}, {ST_L1_F8, EV_IND_RSY, l1_ignore}, }; diff -urN linux-2.4.21/drivers/isdn/isdn_net.c linux-2.4.22/drivers/isdn/isdn_net.c --- linux-2.4.21/drivers/isdn/isdn_net.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/isdn/isdn_net.c 2003-08-25 04:44:42.000000000 -0700 @@ -1296,6 +1296,16 @@ restore_flags(flags); return 0; /* STN (skb to nirvana) ;) */ } +#ifdef CONFIG_IPPP_FILTER + if (isdn_ppp_autodial_filter(skb, lp)) { + isdn_ppp_free(lp); + isdn_net_unbind_channel(lp); + restore_flags(flags); + isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered"); + dev_kfree_skb(skb); + return 0; + } +#endif restore_flags(flags); isdn_net_dial(); /* Initiate dialing */ netif_stop_queue(ndev); @@ -1793,9 +1803,6 @@ { isdn_net_local *lp = (isdn_net_local *) ndev->priv; isdn_net_local *olp = lp; /* original 'lp' */ -#ifdef CONFIG_ISDN_PPP - int proto = PPP_PROTOCOL(skb->data); -#endif #ifdef CONFIG_ISDN_X25 struct concap_proto *cprot = lp -> netdev -> cprot; #endif @@ -1855,14 +1862,7 @@ break; #ifdef CONFIG_ISDN_PPP case ISDN_NET_ENCAP_SYNCPPP: - /* - * If encapsulation is syncppp, don't reset - * huptimer on LCP packets. - */ - if (proto != PPP_LCP) { - olp->huptimer = 0; - lp->huptimer = 0; - } + /* huptimer is done in isdn_ppp_push_higher */ isdn_ppp_receive(lp->netdev, olp, skb); return; #endif diff -urN linux-2.4.21/drivers/isdn/isdn_ppp.c linux-2.4.22/drivers/isdn/isdn_ppp.c --- linux-2.4.21/drivers/isdn/isdn_ppp.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/isdn/isdn_ppp.c 2003-08-25 04:44:42.000000000 -0700 @@ -13,6 +13,9 @@ #include #include #include +#ifdef CONFIG_IPPP_FILTER +#include +#endif #include "isdn_common.h" #include "isdn_ppp.h" @@ -108,8 +111,8 @@ struct ippp_struct *is; if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": ppp_slot(%d) out of range\n", - lp->ppp_slot); + printk(KERN_ERR "%s: ppp_slot(%d) out of range\n", + __FUNCTION__, lp->ppp_slot); return 0; } @@ -128,8 +131,8 @@ spin_unlock(&lp->netdev->pb->lock); #endif /* CONFIG_ISDN_MPP */ if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": ppp_slot(%d) now invalid\n", - lp->ppp_slot); + printk(KERN_ERR "%s: ppp_slot(%d) now invalid\n", + __FUNCTION__, lp->ppp_slot); restore_flags(flags); return 0; } @@ -229,8 +232,8 @@ isdn_ppp_wakeup_daemon(isdn_net_local * lp) { if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": ppp_slot(%d) out of range\n", - lp->ppp_slot); + printk(KERN_ERR "%s: ppp_slot(%d) out of range\n", + __FUNCTION__, lp->ppp_slot); return; } ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK; @@ -248,8 +251,8 @@ struct ippp_struct *is; if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n", - slot); + printk(KERN_ERR "%s: slot(%d) out of range\n", + __FUNCTION__, slot); return 0; } is = ippp_table[slot]; @@ -324,7 +327,10 @@ */ is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */ #endif - +#ifdef CONFIG_IPPP_FILTER + is->pass_filter.filter = NULL; + is->active_filter.filter = NULL; +#endif is->state = IPPP_OPEN; return 0; @@ -344,7 +350,7 @@ is = file->private_data; if (!is) { - printk(KERN_ERR __FUNCTION__": no file->private_data\n"); + printk(KERN_ERR "%s: no file->private_data\n", __FUNCTION__); return; } if (is->debug & 0x1) @@ -354,7 +360,7 @@ isdn_net_dev *p = is->lp->netdev; if (!p) { - printk(KERN_ERR __FUNCTION__": no lp->netdev\n"); + printk(KERN_ERR "%s: no lp->netdev\n", __FUNCTION__); return; } is->state &= ~IPPP_CONNECT; /* -> effect: no call of wakeup */ @@ -379,6 +385,16 @@ slhc_free(is->slcomp); is->slcomp = NULL; #endif +#ifdef CONFIG_IPPP_FILTER + if (is->pass_filter.filter) { + kfree(is->pass_filter.filter); + is->pass_filter.filter = NULL; + } + if (is->active_filter.filter) { + kfree(is->active_filter.filter); + is->active_filter.filter = NULL; + } +#endif /* TODO: if this was the previous master: link the stuff to the new master */ if(is->comp_stat) @@ -588,6 +604,39 @@ } return set_arg((void *)arg,&pci,sizeof(struct pppcallinfo)); } +#ifdef CONFIG_IPPP_FILTER + case PPPIOCSPASS: + case PPPIOCSACTIVE: + { + struct sock_fprog uprog, *filtp; + struct sock_filter *code = NULL; + int len, err; + + if (copy_from_user(&uprog, (void *) arg, sizeof(uprog))) + return -EFAULT; + if (uprog.len > 0 && uprog.len < 65536) { + len = uprog.len * sizeof(struct sock_filter); + code = kmalloc(len, GFP_KERNEL); + if (code == NULL) + return -ENOMEM; + if (copy_from_user(code, uprog.filter, len)) { + kfree(code); + return -EFAULT; + } + err = sk_chk_filter(code, uprog.len); + if (err) { + kfree(code); + return err; + } + } + filtp = (cmd == PPPIOCSPASS) ? &is->pass_filter : &is->active_filter; + if (filtp->filter) + kfree(filtp->filter); + filtp->filter = code; + filtp->len = uprog.len; + break; + } +#endif /* CONFIG_IPPP_FILTER */ default: break; } @@ -977,6 +1026,7 @@ { struct net_device *dev = &net_dev->dev; struct ippp_struct *is, *mis; + isdn_net_local *mlp = NULL; int slot; slot = lp->ppp_slot; @@ -988,7 +1038,8 @@ is = ippp_table[slot]; if (lp->master) { // FIXME? - slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot; + mlp = (isdn_net_local *) lp->master->priv; + slot = mlp->ppp_slot; if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n", lp->ppp_slot); @@ -1026,8 +1077,8 @@ if (is->debug & 0x20) printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n"); if (net_dev->local->ppp_slot < 0) { - printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n", - net_dev->local->ppp_slot); + printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n", + __FUNCTION__, net_dev->local->ppp_slot); goto drop_packet; } if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) { @@ -1052,8 +1103,8 @@ skb_put(skb, skb_old->len + 128); memcpy(skb->data, skb_old->data, skb_old->len); if (net_dev->local->ppp_slot < 0) { - printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n", - net_dev->local->ppp_slot); + printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n", + __FUNCTION__, net_dev->local->ppp_slot); goto drop_packet; } pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp, @@ -1082,9 +1133,36 @@ return; } - /* Reset hangup-timer */ - lp->huptimer = 0; - +#ifdef CONFIG_IPPP_FILTER + /* check if the packet passes the pass and active filters + * the filter instructions are constructed assuming + * a four-byte PPP header on each packet (which is still present) */ + skb_push(skb, 4); + skb->data[0] = 0; /* indicate inbound */ + + if (is->pass_filter.filter + && sk_run_filter(skb, is->pass_filter.filter, + is->pass_filter.len) == 0) { + if (is->debug & 0x2) + printk(KERN_DEBUG "IPPP: inbound frame filtered.\n"); + kfree_skb(skb); + return; + } + if (!(is->active_filter.filter + && sk_run_filter(skb, is->active_filter.filter, + is->active_filter.len) == 0)) { + if (is->debug & 0x2) + printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); + lp->huptimer = 0; + if (mlp) + mlp->huptimer = 0; + } + skb_pull(skb, 4); +#else /* CONFIG_IPPP_FILTER */ + lp->huptimer = 0; + if (mlp) + mlp->huptimer = 0; +#endif /* CONFIG_IPPP_FILTER */ skb->dev = dev; skb->mac.raw = skb->data; netif_rx(skb); @@ -1121,7 +1199,6 @@ return skb_push(skb,len); } - /* * send ppp frame .. we expect a PIDCOMPressable proto -- * (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP) @@ -1188,7 +1265,6 @@ goto unlock; } ipt = ippp_table[slot]; - lp->huptimer = 0; /* * after this line .. requeueing in the device queue is no longer allowed!!! @@ -1199,6 +1275,34 @@ */ skb_pull(skb,IPPP_MAX_HEADER); +#ifdef CONFIG_IPPP_FILTER + /* check if we should pass this packet + * the filter instructions are constructed assuming + * a four-byte PPP header on each packet */ + skb_push(skb, 4); + skb->data[0] = 1; /* indicate outbound */ + *(u_int16_t *)(skb->data + 2) = htons(proto); + + if (ipt->pass_filter.filter + && sk_run_filter(skb, ipt->pass_filter.filter, + ipt->pass_filter.len) == 0) { + if (ipt->debug & 0x4) + printk(KERN_DEBUG "IPPP: outbound frame filtered.\n"); + kfree_skb(skb); + goto unlock; + } + if (!(ipt->active_filter.filter + && sk_run_filter(skb, ipt->active_filter.filter, + ipt->active_filter.len) == 0)) { + if (ipt->debug & 0x4) + printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); + lp->huptimer = 0; + } + skb_pull(skb, 4); +#else /* CONFIG_IPPP_FILTER */ + lp->huptimer = 0; +#endif /* CONFIG_IPPP_FILTER */ + if (ipt->debug & 0x4) printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len); if (ipts->debug & 0x40) @@ -1340,6 +1444,50 @@ return retval; } +#ifdef CONFIG_IPPP_FILTER +/* + * check if this packet may trigger auto-dial. + */ + +int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp) +{ + struct ippp_struct *is = ippp_table[lp->ppp_slot]; + u_int16_t proto; + int drop = 0; + + switch (ntohs(skb->protocol)) { + case ETH_P_IP: + proto = PPP_IP; + break; + case ETH_P_IPX: + proto = PPP_IPX; + break; + default: + printk(KERN_ERR "isdn_ppp_autodial_filter: unsupported protocol 0x%x.\n", + skb->protocol); + return 1; + } + + /* the filter instructions are constructed assuming + * a four-byte PPP header on each packet. we have to + * temporarily remove part of the fake header stuck on + * earlier. + */ + skb_pull(skb, IPPP_MAX_HEADER - 4); + skb->data[0] = 1; /* indicate outbound */ + *(u_int16_t *)(skb->data + 2) = htons(proto); + + drop |= is->pass_filter.filter + && sk_run_filter(skb, is->pass_filter.filter, + is->pass_filter.len) == 0; + drop |= is->active_filter.filter + && sk_run_filter(skb, is->active_filter.filter, + is->active_filter.len) == 0; + + skb_push(skb, IPPP_MAX_HEADER - 4); + return drop; +} +#endif #ifdef CONFIG_ISDN_MPP /* this is _not_ rfc1990 header, but something we convert both short and long @@ -1392,8 +1540,8 @@ struct ippp_struct * is; if (lp->ppp_slot < 0) { - printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n", - lp->ppp_slot); + printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", + __FUNCTION__, lp->ppp_slot); return(-EINVAL); } @@ -1443,8 +1591,8 @@ stats = &mp->stats; slot = lp->ppp_slot; if (slot < 0 || slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d)\n", - lp->ppp_slot); + printk(KERN_ERR "%s: lp->ppp_slot(%d)\n", + __FUNCTION__, lp->ppp_slot); stats->frame_drops++; dev_kfree_skb(skb); spin_unlock_irqrestore(&mp->lock, flags); @@ -1480,8 +1628,8 @@ for (lpq = net_dev->queue;;) { slot = lpq->ppp_slot; if (slot < 0 || slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": lpq->ppp_slot(%d)\n", - lpq->ppp_slot); + printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n", + __FUNCTION__, lpq->ppp_slot); } else { u32 lls = ippp_table[slot]->last_link_seqno; if (MP_LT(lls, minseq)) @@ -1714,8 +1862,8 @@ unsigned int tot_len; if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n", - lp->ppp_slot); + printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", + __FUNCTION__, lp->ppp_slot); return; } if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { @@ -2491,8 +2639,8 @@ printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n", lp->ppp_slot); if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n", - lp->ppp_slot); + printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", + __FUNCTION__, lp->ppp_slot); return; } is = ippp_table[lp->ppp_slot]; @@ -2501,8 +2649,8 @@ if(lp->master) { int slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot; if (slot < 0 || slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n", - slot); + printk(KERN_ERR "%s: slot(%d) out of range\n", + __FUNCTION__, slot); return; } mis = ippp_table[slot]; @@ -2665,8 +2813,8 @@ if(!skb || skb->len < 3) return; if (slot < 0 || slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": lp->ppp_slot(%d) out of range\n", - slot); + printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", + __FUNCTION__, slot); return; } is = ippp_table[slot]; @@ -2688,8 +2836,8 @@ if (lp->master) { slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot; if (slot < 0 || slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR __FUNCTION__": slot(%d) out of range\n", - slot); + printk(KERN_ERR "%s: slot(%d) out of range\n", + __FUNCTION__, slot); return; } mis = ippp_table[slot]; diff -urN linux-2.4.21/drivers/isdn/isdn_ppp.h linux-2.4.22/drivers/isdn/isdn_ppp.h --- linux-2.4.21/drivers/isdn/isdn_ppp.h 2001-12-21 09:41:54.000000000 -0800 +++ linux-2.4.22/drivers/isdn/isdn_ppp.h 2003-08-25 04:44:42.000000000 -0700 @@ -19,6 +19,7 @@ extern void isdn_ppp_cleanup(void); extern int isdn_ppp_free(isdn_net_local *); extern int isdn_ppp_bind(isdn_net_local *); +extern int isdn_ppp_autodial_filter(struct sk_buff *, isdn_net_local *); extern int isdn_ppp_xmit(struct sk_buff *, struct net_device *); extern void isdn_ppp_receive(isdn_net_dev *, isdn_net_local *, struct sk_buff *); extern int isdn_ppp_dev_ioctl(struct net_device *, struct ifreq *, int); diff -urN linux-2.4.21/drivers/isdn/tpam/tpam_queues.c linux-2.4.22/drivers/isdn/tpam/tpam_queues.c --- linux-2.4.21/drivers/isdn/tpam/tpam_queues.c 2001-12-21 09:41:54.000000000 -0800 +++ linux-2.4.22/drivers/isdn/tpam/tpam_queues.c 2003-08-25 04:44:42.000000000 -0700 @@ -146,6 +146,7 @@ do { hpic = readl(card->bar0 + TPAM_HPIC_REGISTER); if (waiting_too_long++ > 0xfffffff) { + kfree_skb(skb); spin_unlock(&card->lock); printk(KERN_ERR "TurboPAM(tpam_irq): " "waiting too long...\n"); diff -urN linux-2.4.21/drivers/macintosh/adb.c linux-2.4.22/drivers/macintosh/adb.c --- linux-2.4.21/drivers/macintosh/adb.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/macintosh/adb.c 2003-08-25 04:44:42.000000000 -0700 @@ -252,6 +252,10 @@ { adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + if (adb_probe_task_pid < 0) { + adb_probe_task_pid = 0; + printk(KERN_ERR "adb: failed to create probe task !\n"); + } } int @@ -592,7 +596,6 @@ return (*original_address != 0); } - /* * /dev/adb device driver. */ @@ -636,6 +639,27 @@ spin_unlock_irqrestore(&state->lock, flags); } +static int +do_adb_query(struct adb_request *req) +{ + int ret = -EINVAL; + + switch(req->data[1]) + { + case ADB_QUERY_GETDEVINFO: + if (req->nbytes < 3) + break; + req->reply[0] = adb_handler[req->data[2]].original_address; + req->reply[1] = adb_handler[req->data[2]].handler_id; + req->complete = 1; + req->reply_len = 2; + adb_write_done(req); + ret = 0; + break; + } + return ret; +} + static int adb_open(struct inode *inode, struct file *file) { struct adbdev_state *state; @@ -655,6 +679,7 @@ return 0; } +/* FIXME: Should wait completion, dequeue & delete pending requests */ static int adb_release(struct inode *inode, struct file *file) { struct adbdev_state *state = file->private_data; @@ -772,9 +797,17 @@ /* If a probe is in progress or we are sleeping, wait for it to complete */ down(&adb_probe_mutex); + /* Queries are special requests sent to the ADB driver itself */ + if (req->data[0] == ADB_QUERY) { + if (count > 1) + ret = do_adb_query(req); + else + ret = -EINVAL; + up(&adb_probe_mutex); + } /* Special case for ADB_BUSRESET request, all others are sent to the controller */ - if ((req->data[0] == ADB_PACKET)&&(count > 1) + else if ((req->data[0] == ADB_PACKET)&&(count > 1) &&(req->data[1] == ADB_BUSRESET)) { ret = do_adb_reset_bus(); up(&adb_probe_mutex); diff -urN linux-2.4.21/drivers/macintosh/adbhid.c linux-2.4.22/drivers/macintosh/adbhid.c --- linux-2.4.21/drivers/macintosh/adbhid.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/macintosh/adbhid.c 2003-08-25 04:44:42.000000000 -0700 @@ -42,6 +42,12 @@ #include #include #include + +#include +#ifdef CONFIG_ALL_PPC +#include +#endif + #ifdef CONFIG_PMAC_BACKLIGHT #include #endif @@ -65,7 +71,7 @@ 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 98, 96, 0, 74, 0, 0,117, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73,183,181,124, 63, 64, 65, 61, 66, 67,191, 87,190, 99, 0, 70, 0, 68,101, 88, - 0,119,110,102,104,111, 62,107, 60,109, 59, 54,100, 97,116,116 + 0,119,110,102,104,111, 62,107, 60,109, 59, 54,100, 97,126,116 }; struct adbhid { @@ -154,6 +160,17 @@ return; case 0x3f: /* ignore Powerbook Fn key */ return; +#ifdef CONFIG_ALL_PPC + case 0x7e: /* Power key on PBook 3400 needs remapping */ + switch(pmac_call_feature(PMAC_FTR_GET_MB_INFO, + NULL, PMAC_MB_INFO_MODEL, 0)) { + case PMAC_TYPE_COMET: + case PMAC_TYPE_HOOPER: + case PMAC_TYPE_KANGA: + keycode = 0x7f; + } + break; +#endif /* CONFIG_ALL_PPC */ } if (adbhid[id]->keycode[keycode]) @@ -306,13 +323,12 @@ case 0xa: /* brightness decrease */ #ifdef CONFIG_PMAC_BACKLIGHT if (!disable_kernel_backlight) { - if (!down || backlight < 0) - break; - if (backlight > BACKLIGHT_OFF) - set_backlight_level(backlight-1); - else - set_backlight_level(BACKLIGHT_OFF); - break; + if (down && backlight >= 0) { + if (backlight > BACKLIGHT_OFF) + set_backlight_level(backlight-1); + else + set_backlight_level(BACKLIGHT_OFF); + } } #endif /* CONFIG_PMAC_BACKLIGHT */ input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); @@ -320,13 +336,12 @@ case 0x9: /* brightness increase */ #ifdef CONFIG_PMAC_BACKLIGHT if (!disable_kernel_backlight) { - if (!down || backlight < 0) - break; - if (backlight < BACKLIGHT_MAX) - set_backlight_level(backlight+1); - else - set_backlight_level(BACKLIGHT_MAX); - break; + if (down && backlight >= 0) { + if (backlight < BACKLIGHT_MAX) + set_backlight_level(backlight+1); + else + set_backlight_level(BACKLIGHT_MAX); + } } #endif /* CONFIG_PMAC_BACKLIGHT */ input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down); diff -urN linux-2.4.21/drivers/macintosh/apm_emu.c linux-2.4.22/drivers/macintosh/apm_emu.c --- linux-2.4.21/drivers/macintosh/apm_emu.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/macintosh/apm_emu.c 2003-08-25 04:44:42.000000000 -0700 @@ -436,40 +436,40 @@ int percentage = -1; int time_units = -1; int real_count = 0; - int charge = -1; - int current = 0; int i; char * p = buf; char charging = 0; + long charge = -1; + long current = 0; + unsigned long btype = 0; ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0); for (i=0; i 0) { battery_status = 0x03; battery_flag = 0x08; } else if (percentage <= APM_CRITICAL) { @@ -516,6 +516,7 @@ static int __init apm_emu_init(void) { struct proc_dir_entry *apm_proc; + int retval; if (sys_ctrler != SYS_CTRLER_PMU) { printk(KERN_INFO "apm_emu: Requires a machine with a PMU.\n"); @@ -523,10 +524,18 @@ } apm_proc = create_proc_info_entry("apm", 0, NULL, apm_emu_get_info); - if (apm_proc) - SET_MODULE_OWNER(apm_proc); + if (!apm_proc) { + printk(KERN_ERR "apm_emu: create_proc_info_entry failed.\n"); + return -ENOENT; + } + SET_MODULE_OWNER(apm_proc); - misc_register(&apm_device); + retval = misc_register(&apm_device); + if (retval < 0) { + printk(KERN_ERR "apm_emu: misc_register failed\n"); + remove_proc_entry("apm", NULL); + return retval; + } pmu_register_sleep_notifier(&apm_sleep_notifier); diff -urN linux-2.4.21/drivers/macintosh/macio-adb.c linux-2.4.22/drivers/macintosh/macio-adb.c --- linux-2.4.21/drivers/macintosh/macio-adb.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/macintosh/macio-adb.c 2003-08-25 04:44:42.000000000 -0700 @@ -218,7 +218,6 @@ out_8(&adb->ctrl.r, DTB + CRE); } else { out_8(&adb->ctrl.r, DTB); - req->complete = 1; current_req = req->next; complete = 1; if (current_req) @@ -238,7 +237,6 @@ for (i = 0; i < req->reply_len; ++i) req->reply[i] = in_8(&adb->data[i].r); } - req->complete = 1; current_req = req->next; complete = 1; if (current_req) @@ -255,8 +253,16 @@ out_8(&adb->intr.r, 0); } spin_unlock(&macio_lock); - if (complete && req && req->done) - (*req->done)(req); + if (complete && req) { + void (*done)(struct adb_request *) = req->done; + mb(); + req->complete = 1; + /* Here, we assume that if the request has a done member, the + * struct request will survive to setting req->complete to 1 + */ + if (done) + (*done)(req); + } if (ibuf_len) adb_input(ibuf, ibuf_len, regs, autopoll); } diff -urN linux-2.4.21/drivers/macintosh/mediabay.c linux-2.4.22/drivers/macintosh/mediabay.c --- linux-2.4.21/drivers/macintosh/mediabay.c 2002-02-25 11:37:58.000000000 -0800 +++ linux-2.4.22/drivers/macintosh/mediabay.c 2003-08-25 04:44:42.000000000 -0700 @@ -109,7 +109,7 @@ #ifdef CONFIG_BLK_DEV_IDE /* check the busy bit in the media-bay ide interface (assumes the media-bay contains an ide device) */ -#define MB_IDE_READY(i) ((inb(media_bays[i].cd_base + 0x70) & 0x80) == 0) +#define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0) #endif /* Note: All delays are not in milliseconds and converted to HZ relative @@ -577,7 +577,8 @@ MBDBG("mediabay %d IDE ready\n", i); } break; - } + } else if (bay->timer > 0) + bay->timer--; if (bay->timer == 0) { printk("\nIDE Timeout in bay %d !\n", i); MBDBG("mediabay%d: nIDE Timeout !\n", i); @@ -756,7 +757,7 @@ struct media_bay_info* bay = &media_bays[n]; if (!np->parent || np->n_addrs == 0 || !request_OF_resource(np, 0, NULL)) { np = np->next; - printk(KERN_ERR "media-bay: Can't request IO resource !\n"); + printk(KERN_ERR "mediabay: Can't request IO resource !\n"); continue; } bay->mb_type = mb_ohare; @@ -771,7 +772,7 @@ bay->mb_type = mb_ohare; bay->ops = &ohare_mb_ops; } else { - printk(KERN_ERR "mediabay: Unknown bay type !\n"); + printk(KERN_ERR "media-bay: Unknown bay type !\n"); np = np->next; continue; } @@ -782,7 +783,7 @@ MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE); #ifdef MB_USE_INTERRUPTS if (np->n_intrs == 0) { - printk(KERN_ERR "media bay %d has no irq\n",n); + printk(KERN_ERR "media-bay %d has no irq\n",n); np = np->next; continue; } @@ -823,8 +824,9 @@ pmu_register_sleep_notifier(&mb_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ - kernel_thread(media_bay_task, NULL, - CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + if (kernel_thread(media_bay_task, NULL, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0) + printk(KERN_ERR "media-bay: Cannot create polling thread !\n"); } } diff -urN linux-2.4.21/drivers/macintosh/via-cuda.c linux-2.4.22/drivers/macintosh/via-cuda.c --- linux-2.4.21/drivers/macintosh/via-cuda.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/macintosh/via-cuda.c 2003-08-25 04:44:42.000000000 -0700 @@ -37,7 +37,6 @@ #ifdef CONFIG_MAC #define CUDA_IRQ IRQ_MAC_ADB #define __openfirmware -#define eieio() #else #define CUDA_IRQ vias->intrs[0].line #endif @@ -175,8 +174,8 @@ /* for us by the main VIA driver in arch/m68k/mac/via.c */ #ifndef CONFIG_MAC - via[IFR] = 0x7f; eieio(); /* clear interrupts by writing 1s */ - via[IER] = IER_SET|SR_INT; eieio(); /* enable interrupt from SR */ + out_8(&via[IFR], 0x7f); /* clear interrupts by writing 1s */ + out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */ #endif /* enable autopoll */ @@ -244,7 +243,8 @@ #endif /* CONFIG_ADB */ #define WAIT_FOR(cond, what) \ - do { \ + do { \ + int x; \ for (x = 1000; !(cond); --x) { \ if (x == 0) { \ printk("Timeout waiting for " what "\n"); \ @@ -257,40 +257,40 @@ static int cuda_init_via() { - int x; - - via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ; /* TACK & TIP out */ - via[B] |= TACK | TIP; /* negate them */ - via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT; /* SR data in */ - eieio(); - x = via[SR]; eieio(); /* clear any left-over data */ + out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ); /* TACK & TIP out */ + out_8(&via[B], in_8(&via[B]) | TACK | TIP); /* negate them */ + out_8(&via[ACR] ,(in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT); /* SR data in */ + (void)in_8(&via[SR]); /* clear any left-over data */ #ifndef CONFIG_MAC - via[IER] = 0x7f; eieio(); /* disable interrupts from VIA */ + out_8(&via[IER], 0x7f); /* disable interrupts from VIA */ + (void)in_8(&via[IER]); #endif - eieio(); /* delay 4ms and then clear any pending interrupt */ mdelay(4); - x = via[SR]; eieio(); + (void)in_8(&via[SR]); + out_8(&via[IFR], in_8(&via[IFR]) & 0x7f); /* sync with the CUDA - assert TACK without TIP */ - via[B] &= ~TACK; eieio(); + out_8(&via[B], in_8(&via[B]) & ~TACK); /* wait for the CUDA to assert TREQ in response */ - WAIT_FOR((via[B] & TREQ) == 0, "CUDA response to sync"); + WAIT_FOR((in_8(&via[B]) & TREQ) == 0, "CUDA response to sync"); /* wait for the interrupt and then clear it */ - WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (2)"); - x = via[SR]; eieio(); + WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)"); + (void)in_8(&via[SR]); + out_8(&via[IFR], in_8(&via[IFR]) & 0x7f); /* finish the sync by negating TACK */ - via[B] |= TACK; eieio(); + out_8(&via[B], in_8(&via[B]) | TACK); /* wait for the CUDA to negate TREQ and the corresponding interrupt */ - WAIT_FOR(via[B] & TREQ, "CUDA response to sync (3)"); - WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (4)"); - x = via[SR]; eieio(); - via[B] |= TIP; eieio(); /* should be unnecessary */ + WAIT_FOR(in_8(&via[B]) & TREQ, "CUDA response to sync (3)"); + WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)"); + (void)in_8(&via[SR]); + out_8(&via[IFR], in_8(&via[IFR]) & 0x7f); + out_8(&via[B], in_8(&via[B]) | TIP); /* should be unnecessary */ return 0; } @@ -413,55 +413,59 @@ req = current_req; if (req == 0) return; - if ((via[B] & TREQ) == 0) + if ((in_8(&via[B]) & TREQ) == 0) return; /* a byte is coming in from the CUDA */ /* set the shift register to shift out and send a byte */ - via[ACR] |= SR_OUT; eieio(); - via[SR] = req->data[0]; eieio(); - via[B] &= ~TIP; + out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT); + out_8(&via[SR], req->data[0]); + out_8(&via[B], in_8(&via[B]) & ~TIP); cuda_state = sent_first_byte; } void cuda_poll() { - if (via[IFR] & SR_INT) { - unsigned long flags; + unsigned long flags; - /* cuda_interrupt only takes a normal lock, we disable - * interrupts here to avoid re-entering and thus deadlocking. - * An option would be to disable only the IRQ source with - * disable_irq(), would that work on m68k ? --BenH - */ - local_irq_save(flags); - cuda_interrupt(0, 0, 0); - local_irq_restore(flags); - } + /* cuda_interrupt only takes a normal lock, we disable + * interrupts here to avoid re-entering and thus deadlocking. + * An option would be to disable only the IRQ source with + * disable_irq(), would that work on m68k ? --BenH + */ + local_irq_save(flags); + cuda_interrupt(0, 0, 0); + local_irq_restore(flags); } static void cuda_interrupt(int irq, void *arg, struct pt_regs *regs) { - int x, status; + int status; struct adb_request *req = NULL; unsigned char ibuf[16]; int ibuf_len = 0; int complete = 0; + unsigned char virq; - if ((via[IFR] & SR_INT) == 0) - return; - spin_lock(&cuda_lock); - status = (~via[B] & (TIP|TREQ)) | (via[ACR] & SR_OUT); eieio(); + + virq = in_8(&via[IFR]) & 0x7f; + out_8(&via[IFR], virq); + if ((virq & SR_INT) == 0) { + spin_unlock(&cuda_lock); + return; + } + + status = (~in_8(&via[B]) & (TIP|TREQ)) | (in_8(&via[ACR]) & SR_OUT); /* printk("cuda_interrupt: state=%d status=%x\n", cuda_state, status); */ switch (cuda_state) { case idle: /* CUDA has sent us the first byte of data - unsolicited */ if (status != TREQ) printk("cuda: state=idle, status=%x\n", status); - x = via[SR]; eieio(); - via[B] &= ~TIP; eieio(); + (void)in_8(&via[SR]); + out_8(&via[B], in_8(&via[B]) & ~TIP); cuda_state = reading; reply_ptr = cuda_rbuf; reading_reply = 0; @@ -471,8 +475,8 @@ /* CUDA has sent us the first byte of data of a reply */ if (status != TREQ) printk("cuda: state=awaiting_reply, status=%x\n", status); - x = via[SR]; eieio(); - via[B] &= ~TIP; eieio(); + (void)in_8(&via[SR]); + out_8(&via[B], in_8(&via[B]) & ~TIP); cuda_state = reading; reply_ptr = current_req->reply; reading_reply = 1; @@ -481,16 +485,16 @@ case sent_first_byte: if (status == TREQ + TIP + SR_OUT) { /* collision */ - via[ACR] &= ~SR_OUT; eieio(); - x = via[SR]; eieio(); - via[B] |= TIP | TACK; eieio(); + out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT); + (void)in_8(&via[SR]); + out_8(&via[B], in_8(&via[B]) | TIP | TACK); cuda_state = idle; } else { /* assert status == TIP + SR_OUT */ if (status != TIP + SR_OUT) printk("cuda: state=sent_first_byte status=%x\n", status); - via[SR] = current_req->data[1]; eieio(); - via[B] ^= TACK; eieio(); + out_8(&via[SR], current_req->data[1]); + out_8(&via[B], in_8(&via[B]) ^ TACK); data_index = 2; cuda_state = sending; } @@ -499,9 +503,9 @@ case sending: req = current_req; if (data_index >= req->nbytes) { - via[ACR] &= ~SR_OUT; eieio(); - x = via[SR]; eieio(); - via[B] |= TACK | TIP; eieio(); + out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT); + (void)in_8(&via[SR]); + out_8(&via[B], in_8(&via[B]) | TACK | TIP); req->sent = 1; if (req->reply_expected) { cuda_state = awaiting_reply; @@ -513,27 +517,27 @@ cuda_start(); } } else { - via[SR] = req->data[data_index++]; eieio(); - via[B] ^= TACK; eieio(); + out_8(&via[SR], req->data[data_index++]); + out_8(&via[B], in_8(&via[B]) ^ TACK); } break; case reading: - *reply_ptr++ = via[SR]; eieio(); + *reply_ptr++ = in_8(&via[SR]); if (status == TIP) { /* that's all folks */ - via[B] |= TACK | TIP; eieio(); + out_8(&via[B], in_8(&via[B]) | TACK | TIP); cuda_state = read_done; } else { /* assert status == TIP | TREQ */ if (status != TIP + TREQ) printk("cuda: state=reading status=%x\n", status); - via[B] ^= TACK; eieio(); + out_8(&via[B], in_8(&via[B]) ^ TACK); } break; case read_done: - x = via[SR]; eieio(); + (void)in_8(&via[SR]); if (reading_reply) { req = current_req; req->reply_len = reply_ptr - req->reply; @@ -548,7 +552,6 @@ memmove(req->reply, req->reply + 2, req->reply_len); } } - req->complete = 1; current_req = req->next; complete = 1; } else { @@ -563,7 +566,7 @@ memcpy(ibuf, cuda_rbuf, ibuf_len); } if (status == TREQ) { - via[B] &= ~TIP; eieio(); + out_8(&via[B], in_8(&via[B]) & ~TIP); cuda_state = reading; reply_ptr = cuda_rbuf; reading_reply = 0; @@ -577,8 +580,16 @@ printk("cuda_interrupt: unknown cuda_state %d?\n", cuda_state); } spin_unlock(&cuda_lock); - if (complete && req && req->done) - (*req->done)(req); + if (complete && req) { + void (*done)(struct adb_request *) = req->done; + mb(); + req->complete = 1; + /* Here, we assume that if the request has a done member, the + * struct request will survive to setting req->complete to 1 + */ + if (done) + (*done)(req); + } if (ibuf_len) cuda_input(ibuf, ibuf_len, regs); } diff -urN linux-2.4.21/drivers/macintosh/via-pmu.c linux-2.4.22/drivers/macintosh/via-pmu.c --- linux-2.4.21/drivers/macintosh/via-pmu.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/macintosh/via-pmu.c 2003-08-25 04:44:42.000000000 -0700 @@ -345,11 +345,6 @@ } else pmu_kind = PMU_UNKNOWN; -#ifdef CONFIG_PMAC_PBOOK - if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) - can_sleep = 1; -#endif /* CONFIG_PMAC_PBOOK */ - via = (volatile unsigned char *) ioremap(vias->addrs->address, 0x2000); out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */ @@ -410,6 +405,8 @@ bright_req_3.complete = 1; #ifdef CONFIG_PMAC_PBOOK batt_req.complete = 1; + if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) + can_sleep = 1; #endif if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU", @@ -436,12 +433,20 @@ #ifdef CONFIG_PMAC_PBOOK if (machine_is_compatible("AAPL,3400/2400") || - machine_is_compatible("AAPL,3500")) + machine_is_compatible("AAPL,3500")) { + int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO, + NULL, PMAC_MB_INFO_MODEL, 0); pmu_battery_count = 1; - else if (machine_is_compatible("AAPL,PowerBook1998") || - machine_is_compatible("PowerBook1,1")) + if (mb == PMAC_TYPE_COMET) + pmu_batteries[0].flags |= PMU_BATT_TYPE_COMET; + else + pmu_batteries[0].flags |= PMU_BATT_TYPE_HOOPER; + } else if (machine_is_compatible("AAPL,PowerBook1998") || + machine_is_compatible("PowerBook1,1")) { pmu_battery_count = 2; - else { + pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART; + pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART; + } else { struct device_node* prim = find_devices("power-mgt"); u32 *prim_info = NULL; if (prim) @@ -449,6 +454,9 @@ if (prim_info) { /* Other stuffs here yet unknown */ pmu_battery_count = (prim_info[6] >> 16) & 0xff; + pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART; + if (pmu_battery_count > 1) + pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART; } } #endif /* CONFIG_PMAC_PBOOK */ @@ -558,148 +566,12 @@ #ifdef CONFIG_PMAC_PBOOK -/* - * WARNING ! This code probably needs some debugging... -- BenH. +/* This new version of the code for 2400/3400/3500 powerbooks + * is inspired from the implementation in gkrellm-pmu */ -#ifdef NEW_OHARE_CODE -static void __pmac -done_battery_state_ohare(struct adb_request* req) -{ - unsigned int bat_flags = 0; - int current = 0; - unsigned int capa, max, voltage, time; - int lrange[] = { 0, 275, 850, 1680, 2325, - 2765, 3160, 3500, 3830, 4115, - 4360, 4585, 4795, 4990, 5170, - 5340, 5510, 5710, 5930, 6150, - 6370, 6500 - }; - - if (req->reply[0] & 0x01) - pmu_power_flags |= PMU_PWR_AC_PRESENT; - else - pmu_power_flags &= ~PMU_PWR_AC_PRESENT; - - if (req->reply[0] & 0x04) { - int vb, i, j, k, charge, pcharge; - bat_flags |= PMU_BATT_PRESENT; - vb = (req->reply[1] << 8) | req->reply[2]; - voltage = ((vb * 2650) + 726650)/100; - vb *= 100; - current = req->reply[5]; - if ((req->reply[0] & 0x01) == 0 && (current > 200)) - vb += (current - 200) * 15; - else if (req->reply[0] & 0x02) - vb = (vb - 2000); - i = (33000 - vb) / 10; - j = i - (i % 100); - k = j/100; - if (k <= 0) - charge = 0; - else if (k >= 21) - charge = 650000; - else - charge = (lrange[k + 1] - lrange[k]) * (i - j) + (lrange[k] * 100); - charge = (1000 - charge / 650) / 10; - if (req->reply[0] & 0x40) { - pcharge = (req->reply[6] << 8) + req->reply[7]; - if (pcharge > 6500) - pcharge = 6500; - pcharge *= 100; - pcharge = (1000 - pcharge / 650) / 10; - if (pcharge < charge) - charge = pcharge; - } - capa = charge; - max = 100; - time = (charge * 16440) / current; - current = -current; - - } else - capa = max = current = voltage = time = 0; - - if (req->reply[0] & 0x02) - bat_flags |= PMU_BATT_CHARGING; - - pmu_batteries[pmu_cur_battery].flags = bat_flags; - pmu_batteries[pmu_cur_battery].charge = capa; - pmu_batteries[pmu_cur_battery].max_charge = max; - pmu_batteries[pmu_cur_battery].current = current; - pmu_batteries[pmu_cur_battery].voltage = voltage; - pmu_batteries[pmu_cur_battery].time_remaining = time; -} -#else /* NEW_OHARE_CODE */ static void __pmac done_battery_state_ohare(struct adb_request* req) { - unsigned int bat_flags = 0; - int current = 0; - unsigned int capa, max, voltage, time; - int lrange[] = { 0, 275, 850, 1680, 2325, - 2765, 3160, 3500, 3830, 4115, - 4360, 4585, 4795, 4990, 5170, - 5340, 5510, 5710, 5930, 6150, - 6370, 6500 - }; - - if (req->reply[0] & 0x01) - pmu_power_flags |= PMU_PWR_AC_PRESENT; - else - pmu_power_flags &= ~PMU_PWR_AC_PRESENT; - - if (req->reply[0] & 0x04) { - int vb, i, j, charge, pcharge; - bat_flags |= PMU_BATT_PRESENT; - vb = (req->reply[1] << 8) | req->reply[2]; - voltage = ((vb * 2650) + 726650)/100; - current = *((signed char *)&req->reply[5]); - if ((req->reply[0] & 0x01) == 0 && (current > 200)) - vb += (current - 200) * 15; - else if (req->reply[0] & 0x02) - vb = (vb - 10) * 100; - i = (33000 - vb) / 10; - j = i - (i % 100); - if (j <= 0) - charge = 0; - else if (j >= 21) - charge = 650000; - else - charge = (lrange[j + 1] - lrange[j]) * (i - j) + (lrange[j] * 100); - charge = (1000 - charge / 650) / 10; - if (req->reply[0] & 0x40) { - pcharge = (req->reply[6] << 8) + req->reply[7]; - if (pcharge > 6500) - pcharge = 6500; - pcharge *= 100; - pcharge = (1000 - pcharge / 650) / 10; - if (pcharge < charge) - charge = pcharge; - } - capa = charge; - max = 100; - time = (charge * 274) / current; - current = -current; - - } else - capa = max = current = voltage = time = 0; - - if ((req->reply[0] & 0x02) && (current > 0)) - bat_flags |= PMU_BATT_CHARGING; - if (req->reply[0] & 0x04) /* CHECK THIS ONE */ - bat_flags |= PMU_BATT_PRESENT; - - pmu_batteries[pmu_cur_battery].flags = bat_flags; - pmu_batteries[pmu_cur_battery].charge = capa; - pmu_batteries[pmu_cur_battery].max_charge = max; - pmu_batteries[pmu_cur_battery].current = current; - pmu_batteries[pmu_cur_battery].voltage = voltage; - pmu_batteries[pmu_cur_battery].time_remaining = time; -} -#endif /* NEW_OHARE_CODE */ - - static void __pmac -done_battery_state_comet(struct adb_request* req) -{ /* format: * [0] : flags * 0x01 : AC indicator @@ -718,57 +590,62 @@ * [6][7] : pcharge * --tkoba */ + unsigned int bat_flags = PMU_BATT_TYPE_HOOPER; + long pcharge, charge, vb, vmax, lmax; + long vmax_charging, vmax_charged; + long current, voltage, time, max; + int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO, + NULL, PMAC_MB_INFO_MODEL, 0); - unsigned int bat_flags = 0; - int current = 0; - unsigned int max = 100; - unsigned int charge, voltage, time; - int lrange[] = { 0, 600, 750, 900, 1000, 1080, - 1180, 1250, 1300, 1340, 1360, - 1390, 1420, 1440, 1470, 1490, - 1520, 1550, 1580, 1610, 1650, - 1700 - }; - if (req->reply[0] & 0x01) pmu_power_flags |= PMU_PWR_AC_PRESENT; else pmu_power_flags &= ~PMU_PWR_AC_PRESENT; + + if (mb == PMAC_TYPE_COMET) { + vmax_charged = 189; + vmax_charging = 213; + lmax = 6500; + } else { + vmax_charged = 330; + vmax_charging = 330; + lmax = 6500; + } + vmax = vmax_charged; - if (req->reply[0] & 0x04) { /* battery exist */ - int vb, i; + /* If battery installed */ + if (req->reply[0] & 0x04) { bat_flags |= PMU_BATT_PRESENT; + if (req->reply[0] & 0x02) + bat_flags |= PMU_BATT_CHARGING; vb = (req->reply[1] << 8) | req->reply[2]; - voltage = ((vb * 2650) + 726650)/100; - vb *= 10; + voltage = (vb * 265 + 72665) / 10; current = req->reply[5]; - if ((req->reply[0] & 0x01) == 0 && (current > 200)) - vb += ((current - 200) * 3); /* vb = 500<->1800 */ - else if (req->reply[0] & 0x02) - vb = ((vb - 800) * 1700/13)/100; /* in charging vb = 1300<->2130 */ - - if (req->reply[0] & 0x20) { /* full charged */ - charge = max; - } else { - if (lrange[21] < vb) - charge = max; - else { - if (vb < lrange[1]) - charge = 0; - else { - for (i=21; vb < lrange[i]; --i); - charge = (i * 100)/21; - } - } - if (charge > max) charge = max; + if ((req->reply[0] & 0x01) == 0) { + if (current > 200) + vb += ((current - 200) * 15)/100; + } else if (req->reply[0] & 0x02) { + vb = (vb * 97) / 100; + vmax = vmax_charging; } - time = (charge * 72); + charge = (100 * vb) / vmax; + if (req->reply[0] & 0x40) { + pcharge = (req->reply[6] << 8) + req->reply[7]; + if (pcharge > lmax) + pcharge = lmax; + pcharge *= 100; + pcharge = 100 - pcharge / lmax; + if (pcharge < charge) + charge = pcharge; + } + if (current > 0) + time = (charge * 16440) / current; + else + time = 0; + max = 100; current = -current; } else - max = current = voltage = time = 0; - - if (req->reply[0] & 0x02) - bat_flags |= PMU_BATT_CHARGING; + charge = max = current = voltage = time = 0; pmu_batteries[pmu_cur_battery].flags = bat_flags; pmu_batteries[pmu_cur_battery].charge = charge; @@ -800,7 +677,7 @@ * [8][9] : voltage */ - unsigned int bat_flags = 0; + unsigned int bat_flags = PMU_BATT_TYPE_SMART; int current; unsigned int capa, max, voltage; @@ -858,17 +735,10 @@ { if (!batt_req.complete) return; - if (pmu_kind == PMU_OHARE_BASED) { - int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO, - NULL, PMAC_MB_INFO_MODEL, 0); - - if (mb == PMAC_TYPE_COMET) - pmu_request(&batt_req, done_battery_state_comet, - 1, PMU_BATTERY_STATE); - else - pmu_request(&batt_req, done_battery_state_ohare, - 1, PMU_BATTERY_STATE); - } else + if (pmu_kind == PMU_OHARE_BASED) + pmu_request(&batt_req, done_battery_state_ohare, + 1, PMU_BATTERY_STATE); + else pmu_request(&batt_req, done_battery_state_smart, 2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1); } @@ -1220,9 +1090,14 @@ static inline void pmu_done(struct adb_request *req) { + void (*done)(struct adb_request *) = req->done; + mb(); req->complete = 1; - if (req->done) - (*req->done)(req); + /* Here, we assume that if the request has a done member, the + * struct request will survive to setting req->complete to 1 + */ + if (done) + (*done)(req); } static void __openfirmware @@ -1557,7 +1432,8 @@ wait_for_ack(); send_byte(PMU_INT_ACK); adb_int_pending = 0; -no_free_slot: +no_free_slot: + ; } else if (current_req) pmu_start(); } @@ -1714,6 +1590,259 @@ return via != 0; } +struct pmu_i2c_hdr { + u8 bus; + u8 mode; + u8 bus2; + u8 address; + u8 sub_addr; + u8 comb_addr; + u8 count; +}; + +int +pmu_i2c_combined_read(int bus, int addr, int subaddr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_COMBINED; + hdr->bus2 = 0; + hdr->sub_addr = subaddr; + hdr->comb_addr = addr | 1; + hdr->count = len; + + req.nbytes = sizeof(struct pmu_i2c_hdr) + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) { + memcpy(data, &req.reply[1], req.reply_len - 1); + return req.reply_len - 1; + } + } + return -1; +} + +int +pmu_i2c_stdsub_write(int bus, int addr, int subaddr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_STDSUB; + hdr->bus2 = 0; + hdr->sub_addr = subaddr; + hdr->comb_addr = addr & 0xfe; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len); + req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + return len; + } + return -1; +} + +int +pmu_i2c_simple_read(int bus, int addr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr | 1; + hdr->mode = PMU_I2C_MODE_SIMPLE; + hdr->bus2 = 0; + hdr->sub_addr = 0; + hdr->comb_addr = 0; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + req.nbytes = sizeof(struct pmu_i2c_hdr) + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) { + memcpy(data, &req.reply[1], req.reply_len - 1); + return req.reply_len - 1; + } + } + return -1; +} + +int +pmu_i2c_simple_write(int bus, int addr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_SIMPLE; + hdr->bus2 = 0; + hdr->sub_addr = 0; + hdr->comb_addr = 0; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len); + req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + return len; + } + return -1; +} + + #if defined(DEBUG_SLEEP) || defined(DEBUG_FREQ) /* N.B. This doesn't work on the 3400 */ void @@ -2794,6 +2923,10 @@ EXPORT_SYMBOL(pmu_poll); EXPORT_SYMBOL(pmu_suspend); EXPORT_SYMBOL(pmu_resume); +EXPORT_SYMBOL(pmu_i2c_combined_read); +EXPORT_SYMBOL(pmu_i2c_stdsub_write); +EXPORT_SYMBOL(pmu_i2c_simple_read); +EXPORT_SYMBOL(pmu_i2c_simple_write); #ifdef CONFIG_PMAC_PBOOK EXPORT_SYMBOL(pmu_register_sleep_notifier); EXPORT_SYMBOL(pmu_unregister_sleep_notifier); diff -urN linux-2.4.21/drivers/md/md.c linux-2.4.22/drivers/md/md.c --- linux-2.4.21/drivers/md/md.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/md/md.c 2003-08-25 04:44:42.000000000 -0700 @@ -1805,10 +1805,12 @@ int err = 0, resync_interrupted = 0; kdev_t dev = mddev_to_kdev(mddev); +#if 0 /* ->active is not currently reliable */ if (atomic_read(&mddev->active)>1) { printk(STILL_IN_USE, mdidx(mddev)); OUT(-EBUSY); } +#endif if (mddev->pers) { /* @@ -2623,6 +2625,7 @@ case BLKRAGET: case BLKRASET: case BLKFLSBUF: + case BLKSSZGET: case BLKBSZGET: case BLKBSZSET: err = blk_ioctl (dev, cmd, arg); @@ -2741,12 +2744,17 @@ goto done_unlock; case STOP_ARRAY: - if (!(err = do_md_stop (mddev, 0))) + if (inode->i_bdev->bd_openers > 1) + err = -EBUSY; + else if (!(err = do_md_stop (mddev, 0))) mddev = NULL; goto done_unlock; case STOP_ARRAY_RO: - err = do_md_stop (mddev, 1); + if (inode->i_bdev->bd_openers > 1) + err = -EBUSY; + else + err = do_md_stop (mddev, 1); goto done_unlock; /* @@ -3155,7 +3163,7 @@ loff_t l = *pos; mddev_t *mddev; - if (l > 0x10000) + if (l >= 0x10000) return NULL; if (!l--) /* header */ @@ -3166,7 +3174,9 @@ mddev = list_entry(tmp, mddev_t, all_mddevs); return mddev; } - return (void*)2;/* tail */ + if (!l--) + return (void*)2;/* tail */ + return NULL; } static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) diff -urN linux-2.4.21/drivers/md/raid5.c linux-2.4.22/drivers/md/raid5.c --- linux-2.4.21/drivers/md/raid5.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/md/raid5.c 2003-08-25 04:44:42.000000000 -0700 @@ -882,7 +882,7 @@ /* check if the array has lost two devices and, if so, some requests might * need to be failed */ - if (failed > 1 && to_read+to_write) { + if (failed > 1 && to_read+to_write+written) { for (i=disks; i--; ) { /* fail all writes first */ if (sh->bh_write[i]) to_write--; @@ -891,6 +891,14 @@ bh->b_reqnext = return_fail; return_fail = bh; } + /* and fail all 'written' */ + if (sh->bh_written[i]) written--; + while ((bh = sh->bh_written[i])) { + sh->bh_written[i] = bh->b_reqnext; + bh->b_reqnext = return_fail; + return_fail = bh; + } + /* fail any reads if this device is non-operational */ if (!conf->disks[i].operational) { spin_lock_irq(&conf->device_lock); diff -urN linux-2.4.21/drivers/media/video/Config.in linux-2.4.22/drivers/media/video/Config.in --- linux-2.4.21/drivers/media/video/Config.in 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/Config.in 2003-08-25 04:44:42.000000000 -0700 @@ -24,6 +24,9 @@ dep_tristate ' W9966CF Webcam (FlyCam Supra and others) Video For Linux' CONFIG_VIDEO_W9966 $CONFIG_VIDEO_DEV $CONFIG_PARPORT fi fi +if [ "$CONFIG_SIBYTE_SWARM" = "y" -a "$CONFIG_I2C" != "n" ]; then + dep_tristate ' Philips 7114H decoder (for Swarm)' CONFIG_VIDEO_SWARM_7114H $CONFIG_VIDEO_DEV $CONFIG_I2C_ALGO_SIBYTE +fi dep_tristate ' CPiA Video For Linux' CONFIG_VIDEO_CPIA $CONFIG_VIDEO_DEV if [ "$CONFIG_VIDEO_CPIA" != "n" ]; then if [ "$CONFIG_PARPORT_1284" != "n" ]; then @@ -36,8 +39,8 @@ dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV $CONFIG_I2C dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV $CONFIG_I2C if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_SGI" = "y" ]; then - dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_SGI + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV fi dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV $CONFIG_PCI fi diff -urN linux-2.4.21/drivers/media/video/Makefile linux-2.4.22/drivers/media/video/Makefile --- linux-2.4.21/drivers/media/video/Makefile 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -57,6 +57,7 @@ obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o obj-$(CONFIG_VIDEO_MEYE) += meye.o +obj-$(CONFIG_VIDEO_SWARM_7114H) += swarm_saa7114h.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o # Extract lists of the multi-part drivers. diff -urN linux-2.4.21/drivers/media/video/audiochip.h linux-2.4.22/drivers/media/video/audiochip.h --- linux-2.4.21/drivers/media/video/audiochip.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/audiochip.h 2003-08-25 04:44:42.000000000 -0700 @@ -3,9 +3,6 @@ /* ---------------------------------------------------------------------- */ -#define MIN(a,b) (((a)>(b))?(b):(a)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - /* v4l device was opened in Radio mode */ #define AUDC_SET_RADIO _IO('m',2) /* select from TV,radio,extern,MUTE */ diff -urN linux-2.4.21/drivers/media/video/bttv-cards.c linux-2.4.22/drivers/media/video/bttv-cards.c --- linux-2.4.21/drivers/media/video/bttv-cards.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/bttv-cards.c 2003-08-25 04:44:42.000000000 -0700 @@ -21,22 +21,20 @@ You 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__ 1 +*/ -#include +#include #include #include #include #include #include +#include #include #include "bttvp.h" -#include "tuner.h" #include "bt832.h" /* fwd decl */ @@ -61,6 +59,7 @@ static void adtvk503_audio(struct bttv *btv, struct video_audio *v, int set); static void rv605_muxsel(struct bttv *btv, unsigned int input); static void eagle_muxsel(struct bttv *btv, unsigned int input); +static void xguard_muxsel(struct bttv *btv, unsigned int input); static int terratec_active_radio_upgrade(struct bttv *btv); static int tea5757_read(struct bttv *btv); @@ -153,13 +152,16 @@ { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, { 0x6607107d, BTTV_WINFAST2000, "Leadtek WinFast VC 100" }, { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, + { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, - { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV" }, { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, + // some cards ship with byteswapped IDs ... + { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, + { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, @@ -167,6 +169,7 @@ { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, + { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" }, { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" }, @@ -196,6 +199,33 @@ { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, + { 0x1430aa00, BTTV_PV143, "Provideo PV143A" }, + { 0x1431aa00, BTTV_PV143, "Provideo PV143B" }, + { 0x1432aa00, BTTV_PV143, "Provideo PV143C" }, + { 0x1433aa00, BTTV_PV143, "Provideo PV143D" }, + + { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" }, + { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" }, + { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" }, + { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" }, + + { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" }, + { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" }, + { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" }, + { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" }, + + { 0xa1550000, BTTV_IVC200, "IVC-200" }, + { 0xa1550001, BTTV_IVC200, "IVC-200" }, + { 0xa1550002, BTTV_IVC200, "IVC-200" }, + { 0xa1550003, BTTV_IVC200, "IVC-200" }, + { 0xa1550100, BTTV_IVC200, "IVC-200G" }, + { 0xa1550101, BTTV_IVC200, "IVC-200G" }, + { 0xa1550102, BTTV_IVC200, "IVC-200G" }, + { 0xa1550103, BTTV_IVC200, "IVC-200G" }, + + { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, + { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, + { 0x010115cb, BTTV_GMV1, "AG GMV1" }, { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, @@ -206,19 +236,11 @@ { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" }, { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" }, { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" }, - - { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" }, - { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" }, - { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" }, - { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" }, - { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" }, - { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" }, - { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" }, - { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" }, + { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, // likely broken, vendor id doesn't match the other magic views ... //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, - + { 0, -1, NULL } }; @@ -322,7 +344,7 @@ },{ /* ---- card 0x08 ---------------------------------- */ - .name = "Lifeview FlyVideo II (Bt848) LR26", + .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", .video_inputs = 4, .audio_inputs = 1, .tuner = 0, @@ -629,7 +651,7 @@ .pll = PLL_28, .tuner_type = -1, },{ - .name = "Formac iProTV", + .name = "Formac iProTV, Formac ProTV I (bt848)", .video_inputs = 4, .audio_inputs = 1, .tuner = 0, @@ -737,7 +759,7 @@ .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 }, .needs_tvaudio = 1, .pll = PLL_28, - .tuner_type = -1, + .tuner_type = 1, },{ .name = "Pinnacle PCTV Studio/Rave", .video_inputs = 3, @@ -921,7 +943,7 @@ /* ---- card 0x34 ---------------------------------- */ /* David Härdeman */ .name = "Pinnacle PCTV Studio Pro", - .video_inputs = 3, + .video_inputs = 4, .audio_inputs = 1, .tuner = 0, .svhs = 3, @@ -1548,11 +1570,13 @@ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, + .gpiomask = 0x01, + .audiomux = { 0, 0, 0, 0, 1 }, .muxsel = { 3, 0, 1, 2}, .needs_tvaudio = 0, .pll = PLL_28, },{ - .name = "Formac ProTV II", + .name = "Formac ProTV II (bt878)", .video_inputs = 4, .audio_inputs = 1, .tuner = 0, @@ -1571,8 +1595,8 @@ not soldered here, though unknown wiring. Card lacks: external audio in, pci subsystem id. */ - },{ + /* ---- card 0x60 ---------------------------------- */ .name = "MachTV", .video_inputs = 3, @@ -1621,17 +1645,166 @@ .svhs = 2, .gpiomask = 0x001e8007, .muxsel = { 2, 3, 1, 0 }, - /* Tuner, Radio, external, internal, mute, stereo */ - .audiomux = { 0x00060000, 0x000, 0x000000, 0x000000, 0x07, 0x0000 }, /* Sub: 0x00180000 */ + /* Tuner, Radio, external, internal, off, on */ + .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = 2, .audio_hook = adtvk503_audio, +},{ + + /* ---- card 0x64 ---------------------------------- */ + .name = "Hercules Smart TV Stereo", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x00, + .muxsel = { 2, 3, 1, 1 }, + .needs_tvaudio = 1, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = 5, + /* Notes: + - card lacks subsystem ID + - stereo variant w/ daughter board with tda9874a @0xb0 + - Audio Routing: + always from tda9874 independent of GPIO (?) + external line in: unknown + - Other chips: em78p156elp @ 0x96 (probably IR remote control) + hef4053 (instead 4052) for unknown function + */ +},{ + .name = "Pace TV & Radio Card", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .muxsel = { 2, 3, 1, 1}, // Tuner, CVid, SVid, CVid over SVid connector + .gpiomask = 0, + .no_tda9875 = 1, + .no_tda7432 = 1, + .tuner_type = 1, + .has_radio = 1, + .pll = PLL_28, + /* Bt878, Bt832, FI1246 tuner; no pci subsystem id + only internal line out: (4pin header) RGGL + Radio must be decoded by msp3410d (not routed through)*/ + // .digital_mode = DIGITAL_MODE_CAMERA, // todo! +},{ + /* Chris Willing */ + .name = "IVC-200", + .video_inputs = 1, + .audio_inputs = 0, + .tuner = -1, + .tuner_type = -1, + .svhs = -1, + .gpiomask = 0xdf, + .muxsel = { 2 }, + .pll = PLL_28, +},{ + .name = "Grand X-Guard / Trust 814PCI", + .video_inputs = 16, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .tuner_type = 4, + .gpiomask2 = 0xff, + .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, + .muxsel_hook = xguard_muxsel, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .pll = PLL_28, +},{ + + /* ---- card 0x68 ---------------------------------- */ + .name = "Nebula Electronics DigiTV", + .video_inputs = 0, + .audio_inputs = 0, + .svhs = -1, + .muxsel = { 2, 3, 1, 0}, + .needs_tvaudio = 0, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + /* Jorge Boncompte - DTI2 */ + .name = "ProVideo PV143", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 0 }, + .audiomux = { 0 }, + .needs_tvaudio = 0, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + /* M.Klahr@phytec.de */ + .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, /* card has no tuner */ + .svhs = 3, + .gpiomask = 0x00, + .muxsel = { 2, 3, 1, 0}, + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "PHYTEC VD-009-X1 Combi (bt878)", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, /* card has no tuner */ + .svhs = 3, + .gpiomask = 0x00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + + /* ---- card 0x6c ---------------------------------- */ + .name = "PHYTEC VD-009 MiniDIN (bt878)", + .video_inputs = 10, + .audio_inputs = 0, + .tuner = -1, /* card has no tuner */ + .svhs = 9, + .gpiomask = 0x00, + .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio + via the upper nibble of muxsel. here: used for + xternal video-mux */ + .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "PHYTEC VD-009 Combi (bt878)", + .video_inputs = 10, + .audio_inputs = 0, + .tuner = -1, /* card has no tuner */ + .svhs = 9, + .gpiomask = 0x00, + .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio + via the upper nibble of muxsel. here: used for + xternal video-mux */ + .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, }}; -const unsigned int bttv_num_tvcards = - (sizeof(bttv_tvcards)/sizeof(bttv_tvcards[0])); +const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); /* ----------------------------------------------------------------------- */ @@ -1663,12 +1836,14 @@ printk(KERN_INFO "bttv%d: detected: %s [card=%d], " "PCI subsystem ID is %04x:%04x\n", btv->nr,cards[type].name,cards[type].cardnr, - btv->cardid & 0xffff, btv->cardid >> 16); + btv->cardid & 0xffff, + (btv->cardid >> 16) & 0xffff); btv->type = cards[type].cardnr; } else { /* 404 */ printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n", - btv->nr, btv->cardid&0xffff, btv->cardid>>16); + btv->nr, btv->cardid & 0xffff, + (btv->cardid >> 16) & 0xffff); printk(KERN_DEBUG "please mail id, board name and " "the correct card= insmod option to kraxel@bytesex.org\n"); } @@ -2241,7 +2416,7 @@ tuner = eeprom_data[9]; radio = eeprom_data[blk2-1] & 0x01; - if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) + if (tuner < ARRAY_SIZE(hauppauge_tuner)) btv->tuner_type = hauppauge_tuner[tuner].id; if (radio) btv->has_radio = 1; @@ -2293,14 +2468,6 @@ * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be * unpacked with unzip). */ -static char *firm_altera = "/usr/lib/video4linux/hcwamc.rbf"; -MODULE_PARM(firm_altera,"s"); -MODULE_PARM_DESC(firm_altera,"WinTV/PVR firmware " - "(driver CD => unzip pvr45xxx.exe => hcwamc.rbf)"); - -/* drivers/sound/sound_firmware.c => soundcore.o */ -extern int mod_firmware_load(const char *fn, char **fp); - #define PVR_GPIO_DELAY 10 #define BTTV_ALT_DATA 0x000001 @@ -2345,6 +2512,16 @@ return 0; } +#ifndef CONFIG_FW_LOADER +/* old 2.4.x way -- via soundcore's mod_firmware_load */ + +static char *firm_altera = "/usr/lib/video4linux/hcwamc.rbf"; +MODULE_PARM(firm_altera,"s"); +MODULE_PARM_DESC(firm_altera,"WinTV/PVR firmware " + "(driver CD => unzip pvr45xxx.exe => hcwamc.rbf)"); + +extern int mod_firmware_load(const char *fn, char **fp); + int __devinit pvr_boot(struct bttv *btv) { u32 microlen; @@ -2352,8 +2529,11 @@ int result; microlen = mod_firmware_load(firm_altera, (char**) µ); - if (!microlen) + if (!microlen) { + printk(KERN_WARNING "bttv%d: altera firmware not found [%s]\n", + btv->nr, firm_altera); return -1; + } printk(KERN_INFO "bttv%d: uploading altera firmware [%s] ...\n", btv->nr, firm_altera); @@ -2363,6 +2543,26 @@ vfree(micro); return result; } +#else +/* new 2.5.x way -- via hotplug firmware loader */ + +int __devinit pvr_boot(struct bttv *btv) +{ + const struct firmware *fw_entry; + struct device *dev = btv->dev->dev; + int result; + + result = request_firmware(&fw_entry, "hcwamc.rbf", dev); + if (result != 0) { + printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", + btv->nr); + return rc; + } + result = pvr_altera_load(btv, fw_entry->data, fw_entry->size); + release_firmware(fw_entry); + return result; +} +#endif /* ----------------------------------------------------------------------- */ /* some osprey specific stuff */ @@ -2613,7 +2813,8 @@ 0x00 }; unsigned int i; int tmp; - + u32 val; + /* Initialise GPIO-connevted stuff */ btwrite(1<<13,BT848_GPIO_OUT_EN); /* Reset pin only */ btwrite(0,BT848_GPIO_DATA); @@ -2632,6 +2833,7 @@ setting BT848_ADC_AGC_EN disable the AGC tboult@eecs.lehigh.edu */ + btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC); /* Initialise MAX517 DAC */ @@ -2643,16 +2845,36 @@ * same chips - but the R/W bit is included in the address * argument so the numbers are different */ + printk(KERN_INFO "Initialising 12C508 PIC chip ...\n"); - for (i = 0; i < sizeof(vals)/sizeof(int); i++) { - tmp=bttv_I2CWrite(btv,0x1E,vals[i],0,1); - printk(KERN_INFO "I2C Write(0x08) = %i\nI2C Read () = %x\n\n", - tmp,bttv_I2CRead(btv,0x1F,NULL)); + /* First of all, enable the clock line. This is used in the PXC200-F */ + val = btread(BT848_GPIO_DMA_CTL); + val |= BT848_GPIO_DMA_CTL_GPCLKMODE; + btwrite(val, BT848_GPIO_DMA_CTL); + + /* Then, push to 0 the reset pin long enough to reset the * + * device same as above for the reset line, but not the same + * value sent to the GPIO-connected stuff + * which one is the good one? */ + btwrite( (1<<2), BT848_GPIO_OUT_EN); /* only the reset pin */ + btwrite(0, BT848_GPIO_DATA); + udelay(10); + btwrite(1<<2, BT848_GPIO_DATA); + + for (i = 0; i < ARRAY_SIZE(vals); i++) { + tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); + if (tmp != -1) { + printk(KERN_INFO + "I2C Write(%2.2x) = %i\nI2C Read () = %2.2x\n\n", + vals[i],tmp,bttv_I2CRead(btv,0x1F,NULL)); + } } + printk(KERN_INFO "PXC200 Initialised.\n"); } + /* ----------------------------------------------------------------------- */ /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ /* @@ -2742,8 +2964,8 @@ /* Low-level stuff */ static int tea5757_read(struct bttv *btv) { + unsigned long timeout; int value = 0; - long timeout; int i; /* better safe than sorry */ @@ -3196,6 +3418,34 @@ mdelay(1); } +// The Grandtec X-Guard framegrabber card uses two Dual 4-channel +// video multiplexers to provide up to 16 video inputs. These +// multiplexers are controlled by the lower 8 GPIO pins of the +// bt878. The multiplexers probably Pericom PI5V331Q or similar. + +// xxx0 is pin xxx of multiplexer U5, +// yyy1 is pin yyy of multiplexer U2 + +#define ENA0 0x01 +#define ENB0 0x02 +#define ENA1 0x04 +#define ENB1 0x08 + +#define IN10 0x10 +#define IN00 0x20 +#define IN11 0x40 +#define IN01 0x80 + +static void xguard_muxsel(struct bttv *btv, unsigned int input) +{ + static const int masks[] = { + ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, + ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, + ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, + ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, + }; + btwrite(masks[input%16], BT848_GPIO_DATA); +} /* ----------------------------------------------------------------------- */ /* motherboard chipset specific stuff */ diff -urN linux-2.4.21/drivers/media/video/bttv-driver.c linux-2.4.22/drivers/media/video/bttv-driver.c --- linux-2.4.21/drivers/media/video/bttv-driver.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/bttv-driver.c 2003-08-25 04:44:42.000000000 -0700 @@ -20,7 +20,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include @@ -32,10 +31,7 @@ #include #include #include -#include #include -#include -#include #include #include #include @@ -45,8 +41,12 @@ #include #include +#include +#include +#include +#include + #include "bttvp.h" -#include "tuner.h" #define DEBUG(x) /* Debug driver */ #define MIN(a,b) (((a)>(b))?(b):(a)) @@ -61,7 +61,7 @@ struct bttv bttvs[BTTV_MAX]; /* configuration variables */ -#if defined(__sparc__) || defined(__powerpc__) || defined(__hppa__) +#ifdef __BIG_ENDIAN static unsigned int bigendian=1; #else static unsigned int bigendian=0; @@ -609,7 +609,7 @@ .sram = 2, } }; -#define TVNORMS (sizeof(tvnorms)/sizeof(struct tvnorm)) +#define TVNORMS ARRAY_SIZE(tvnorms) /* used to switch between the bt848's analog/digital video capture modes */ void bt848A_set_timing(struct bttv *btv) @@ -734,7 +734,7 @@ BT848_COLOR_FMT_YCrCb422, BT848_COLOR_FMT_YCrCb411, }; -#define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(palette2fmt[0])) +#define PALETTEFMT_MAX ARRAY_SIZE(palette2fmt) static int make_rawrisctab(struct bttv *btv, u32 *ro, u32 *re, u32 *vbuf) { @@ -776,7 +776,7 @@ u32 todo; u32 **rp; int inter; - u32 cbadr, cradr; + unsigned long cbadr, cradr; unsigned long vadr=(unsigned long) vbuf; u32 shift, csize; @@ -1055,6 +1055,7 @@ *(ro++)=cpu_to_le32(btv->bus_vbi_even); *(re++)=cpu_to_le32(BT848_RISC_JUMP); *(re++)=cpu_to_le32(btv->bus_vbi_odd); + return; } if (ncr < 0) { /* bitmap was pased */ memcpy(clipmap, (unsigned char *)cr, VIDEO_CLIPMAP_SIZE); @@ -1756,6 +1757,7 @@ case VIDIOCSPICT: { struct video_picture p; + if (copy_from_user(&p, arg,sizeof(p))) return -EFAULT; if (p.palette > PALETTEFMT_MAX) @@ -2737,10 +2739,11 @@ btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL); } - btv->picture.colour=254<<7; - btv->picture.brightness=128<<8; - btv->picture.hue=128<<8; - btv->picture.contrast=0xd8<<7; + btv->picture.colour = 254<<7; + btv->picture.brightness = 128<<8; + btv->picture.hue = 128<<8; + btv->picture.contrast = 0xd8<<7; + btv->picture.palette = VIDEO_PALETTE_RGB24; val = chroma_agc ? BT848_SCLOOP_CAGC : 0; btwrite(val, BT848_E_SCLOOP); @@ -2819,7 +2822,7 @@ unsigned int i; printk(KERN_DEBUG "bttv%d: irq loop=%d risc=%x, bits:", btv->nr, count, stat>>28); - for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) { + for (i = 0; i < ARRAY_SIZE(irq_name); i++) { if (stat & (1 << i)) printk(" %s",irq_name[i]); if (astat & (1 << i)) @@ -3173,6 +3176,7 @@ static int bttv_init_module(void) { + int rc; bttv_num = 0; printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n", @@ -3189,7 +3193,13 @@ bttv_check_chipset(); - return pci_module_init(&bttv_pci_driver); + rc = pci_module_init(&bttv_pci_driver); + if (-ENODEV == rc) { + /* plenty of people trying to use bttv for the cx2388x ... */ + if (NULL != pci_find_device(0x14f1, 0x8800, NULL)) + printk("bttv doesn't support your Conexant 2388x card.\n"); + } + return rc; } static void bttv_cleanup_module(void) diff -urN linux-2.4.21/drivers/media/video/bttv-if.c linux-2.4.22/drivers/media/video/bttv-if.c --- linux-2.4.21/drivers/media/video/bttv-if.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/bttv-if.c 2003-08-25 04:44:42.000000000 -0700 @@ -25,16 +25,12 @@ */ -#define __NO_VERSION__ 1 - -#include #include #include #include #include "bttvp.h" -#include "tuner.h" static struct i2c_algo_bit_data bttv_i2c_algo_template; static struct i2c_adapter bttv_i2c_adap_template; @@ -206,7 +202,7 @@ static int attach_inform(struct i2c_client *client) { - struct bttv *btv = (struct bttv*)client->adapter->data; + struct bttv *btv = i2c_get_adapdata(client->adapter); if (btv->tuner_type != UNSET) bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); @@ -216,22 +212,15 @@ if (bttv_debug) printk("bttv%d: i2c attach [client=%s]\n", - btv->nr,client->name); + btv->nr, i2c_clientname(client)); return 0; } void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) { - int i; - - for (i = 0; i < I2C_CLIENTS_MAX; i++) { - if (NULL == btv->i2c_adap.clients[i]) - continue; - if (NULL == btv->i2c_adap.clients[i]->driver->command) - continue; - btv->i2c_adap.clients[i]->driver->command - (btv->i2c_adap.clients[i],cmd,arg); - } + if (0 != btv->i2c_rc) + return; + i2c_clients_command(&btv->i2c_adap, cmd, arg); } void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg) @@ -254,14 +243,14 @@ static struct i2c_adapter bttv_i2c_adap_template = { .inc_use = bttv_inc_use, .dec_use = bttv_dec_use, - .name = "bt848", + I2C_DEVNAME("bt848"), .id = I2C_HW_B_BT848, .client_register = attach_inform, }; static struct i2c_client bttv_i2c_client_template = { - .name = "bttv internal use only", - .id = -1, + I2C_DEVNAME("bttv internal"), + .id = -1, }; @@ -335,10 +324,10 @@ memcpy(&btv->i2c_client, &bttv_i2c_client_template, sizeof(struct i2c_client)); - sprintf(btv->i2c_adap.name+strlen(btv->i2c_adap.name), - " #%d", btv->nr); + sprintf(btv->i2c_adap.name, "bt848 #%d", btv->nr); + btv->i2c_algo.data = btv; - btv->i2c_adap.data = btv; + i2c_set_adapdata(&btv->i2c_adap, btv); btv->i2c_adap.algo_data = &btv->i2c_algo; btv->i2c_client.adapter = &btv->i2c_adap; diff -urN linux-2.4.21/drivers/media/video/bttv.h linux-2.4.22/drivers/media/video/bttv.h --- linux-2.4.21/drivers/media/video/bttv.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/bttv.h 2003-08-25 04:44:42.000000000 -0700 @@ -90,6 +90,7 @@ #define BTTV_SENSORAY311 0x49 #define BTTV_RV605 0x4a #define BTTV_WINDVR 0x4c +#define BTTV_GRANDTEC 0x4d #define BTTV_KWORLD 0x4e #define BTTV_HAUPPAUGEPVR 0x50 #define BTTV_GVBCTV5PCI 0x51 @@ -110,6 +111,10 @@ #define BTTV_EURESYS_PICOLO 0x61 #define BTTV_PV150 0x62 #define BTTV_AD_TVK503 0x63 +#define BTTV_IVC200 0x66 +#define BTTV_XGUARD 0x67 +#define BTTV_NEBULA_DIGITV 0x68 +#define BTTV_PV143 0x69 /* i2c address list */ #define I2C_TSA5522 0xc2 @@ -247,7 +252,6 @@ /* i2c */ -#define I2C_CLIENTS_MAX 16 extern void bttv_bit_setscl(void *data, int state); extern void bttv_bit_setsda(void *data, int state); extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); diff -urN linux-2.4.21/drivers/media/video/bttvp.h linux-2.4.22/drivers/media/video/bttvp.h --- linux-2.4.21/drivers/media/video/bttvp.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/bttvp.h 2003-08-25 04:44:42.000000000 -0700 @@ -25,7 +25,8 @@ #ifndef _BTTVP_H_ #define _BTTVP_H_ -#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,104) +#include +#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,107) #include #include @@ -35,6 +36,8 @@ #include "bt848.h" #include "bttv.h" #include "audiochip.h" +#include "tuner.h" +#include "i2c-compat.h" #ifdef __KERNEL__ @@ -53,8 +56,7 @@ #define dprintk if (bttv_debug) printk #define vprintk if (bttv_verbose) printk -/* Anybody who uses more than four? */ -#define BTTV_MAX 4 +#define BTTV_MAX 16 extern unsigned int bttv_num; /* number of Bt848s in use */ extern struct bttv bttvs[BTTV_MAX]; diff -urN linux-2.4.21/drivers/media/video/cpia_pp.c linux-2.4.22/drivers/media/video/cpia_pp.c --- linux-2.4.21/drivers/media/video/cpia_pp.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/cpia_pp.c 2003-08-25 04:44:42.000000000 -0700 @@ -383,8 +383,8 @@ return -EINVAL; } if((err = ReadPacket(cam, buffer, 8)) < 0) { - return err; DBG("Error reading command result\n"); + return err; } memcpy(data, buffer, databytes); } else if(command[0] == DATA_OUT) { diff -urN linux-2.4.21/drivers/media/video/i2c-compat.h linux-2.4.22/drivers/media/video/i2c-compat.h --- linux-2.4.21/drivers/media/video/i2c-compat.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/media/video/i2c-compat.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,53 @@ +/* + * some i2c layer compatibility stuff -- to avoid cluttering up the + * i2c modules with tons of #ifdefs + */ + + +static inline void *i2c_get_adapdata(struct i2c_adapter *dev) +{ + return dev->data; +} + +static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) +{ + dev->data = data; +} + +static inline void *i2c_get_clientdata(struct i2c_client *dev) +{ + return dev->data; +} + +static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) +{ + dev->data = data; +} + +#define I2C_DEVNAME(str) .name = str + +static inline char *i2c_clientname(struct i2c_client *c) +{ + return c->name; +} + +static inline void i2c_clients_command(struct i2c_adapter *adap, + unsigned int cmd, void *arg) +{ + int i; + + for (i = 0; i < I2C_CLIENT_MAX; i++) { + if (NULL == adap->clients[i]) + continue; + if (NULL == adap->clients[i]->driver->command) + continue; + adap->clients[i]->driver->command(adap->clients[i],cmd,arg); + } +} + + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -urN linux-2.4.21/drivers/media/video/meye.c linux-2.4.22/drivers/media/video/meye.c --- linux-2.4.21/drivers/media/video/meye.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/meye.c 2003-08-25 04:44:42.000000000 -0700 @@ -161,6 +161,34 @@ } } +/****************************************************************************/ +/* dma_alloc_coherent / dma_free_coherent ported from 2.5 */ +/****************************************************************************/ + +void *dma_alloc_coherent(struct pci_dev *dev, size_t size, + dma_addr_t *dma_handle, int gfp) +{ + void *ret; + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); + + if (dev == NULL || ((u32)dev->dma_mask < 0xffffffff)) + gfp |= GFP_DMA; + ret = (void *)__get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_phys(ret); + } + return ret; +} + +void dma_free_coherent(struct pci_dev *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} + /* return a page table pointing to N pages of locked memory */ static int ptable_alloc(void) { u32 *pt; @@ -168,9 +196,10 @@ memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); - meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev, - PAGE_SIZE, - &meye.mchip_dmahandle); + meye.mchip_ptable[MCHIP_NB_PAGES] = dma_alloc_coherent(meye.mchip_dev, + PAGE_SIZE, + &meye.mchip_dmahandle, + GFP_KERNEL); if (!meye.mchip_ptable[MCHIP_NB_PAGES]) { meye.mchip_dmahandle = 0; return -1; @@ -178,16 +207,17 @@ pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; for (i = 0; i < MCHIP_NB_PAGES; i++) { - meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev, - PAGE_SIZE, - pt); + meye.mchip_ptable[i] = dma_alloc_coherent(meye.mchip_dev, + PAGE_SIZE, + pt, + GFP_KERNEL); if (!meye.mchip_ptable[i]) { int j; pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; for (j = 0; j < i; ++j) { - pci_free_consistent(meye.mchip_dev, - PAGE_SIZE, - meye.mchip_ptable[j], *pt); + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable[j], *pt); pt++; } meye.mchip_dmahandle = 0; @@ -205,17 +235,17 @@ pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; for (i = 0; i < MCHIP_NB_PAGES; i++) { if (meye.mchip_ptable[i]) - pci_free_consistent(meye.mchip_dev, - PAGE_SIZE, - meye.mchip_ptable[i], *pt); + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable[i], *pt); pt++; } if (meye.mchip_ptable[MCHIP_NB_PAGES]) - pci_free_consistent(meye.mchip_dev, - PAGE_SIZE, - meye.mchip_ptable[MCHIP_NB_PAGES], - meye.mchip_dmahandle); + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable[MCHIP_NB_PAGES], + meye.mchip_dmahandle); memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); meye.mchip_dmahandle = 0; @@ -614,25 +644,25 @@ /* stop any existing HIC action and wait for any dma to complete then reset the dma engine */ static void mchip_hic_stop(void) { - int i = 0; + int i, j; meye.mchip_mode = MCHIP_HIC_MODE_NOOP; - if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) + if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) return; - mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); - mchip_delay(MCHIP_HIC_CMD, 0); - while (!mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) { - /* resetting HIC */ + for (i = 0; i < 20; ++i) { mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); mchip_delay(MCHIP_HIC_CMD, 0); + for (j = 0; j < 100; ++j) { + if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) + return; + wait_ms(1); + } + printk(KERN_ERR "meye: need to reset HIC!\n"); + mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET); wait_ms(250); - if (i++ > 20) { - printk(KERN_ERR "meye: resetting HIC hanged!\n"); - break; - } } - wait_ms(100); + printk(KERN_ERR "meye: resetting HIC hanged!\n"); } /****************************************************************************/ @@ -1392,6 +1422,8 @@ mchip_hic_stop(); + mchip_dma_free(); + /* disable interrupts */ mchip_set(MCHIP_MM_INTA, 0x0); @@ -1404,8 +1436,6 @@ pci_disable_device(meye.mchip_dev); - mchip_dma_free(); - if (meye.grab_fbuffer) rvfree(meye.grab_fbuffer, gbuffers*gbufsize); diff -urN linux-2.4.21/drivers/media/video/meye.h linux-2.4.22/drivers/media/video/meye.h --- linux-2.4.21/drivers/media/video/meye.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/meye.h 2003-08-25 04:44:42.000000000 -0700 @@ -31,7 +31,7 @@ #define _MEYE_PRIV_H_ #define MEYE_DRIVER_MAJORVERSION 1 -#define MEYE_DRIVER_MINORVERSION 6 +#define MEYE_DRIVER_MINORVERSION 7 #include #include diff -urN linux-2.4.21/drivers/media/video/msp3400.c linux-2.4.22/drivers/media/video/msp3400.c --- linux-2.4.21/drivers/media/video/msp3400.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/msp3400.c 2003-08-25 04:44:42.000000000 -0700 @@ -45,18 +45,13 @@ #include #include #include -#include #include - -#ifdef CONFIG_SMP -#include #include -#endif -/* kernel_thread */ -#define __KERNEL_SYSCALLS__ -#include +#include +#include #include "audiochip.h" +#include "i2c-compat.h" #include "msp3400.h" /* insmod parameters */ @@ -103,9 +98,9 @@ struct timer_list wake_stereo; }; -#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) -#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff)+'@' >= 'D') -#define HAVE_RADIO(msp) ((msp->rev1 & 0xff)+'@' >= 'G') +#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) +#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') +#define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@') #define MSP3400_MAX 4 static struct i2c_client *msps[MSP3400_MAX]; @@ -124,7 +119,7 @@ MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); MODULE_AUTHOR("Gerd Knorr"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */ /* ---------------------------------------------------------------------- */ @@ -360,7 +355,7 @@ static void msp3400c_set_scart(struct i2c_client *client, int in, int out) { - struct msp3400c *msp = client->data; + struct msp3400c *msp = i2c_get_clientdata(client); if (-1 == scarts[out][in]) return; @@ -424,7 +419,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type) { - struct msp3400c *msp = client->data; + struct msp3400c *msp = i2c_get_clientdata(client); int i; dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type); @@ -482,9 +477,16 @@ /* turn on/off nicam + stereo */ static void msp3400c_setstereo(struct i2c_client *client, int mode) { - static char *strmode[] = { "0", "mono", "stereo", "3", - "lang1", "5", "6", "7", "lang2" }; - struct msp3400c *msp = client->data; + static char *strmode[16] = { +#if __GNUC__ >= 3 + [ 0 ... 15 ] = "invalid", +#endif + [ VIDEO_SOUND_MONO ] = "mono", + [ VIDEO_SOUND_STEREO ] = "stereo", + [ VIDEO_SOUND_LANG1 ] = "lang1", + [ VIDEO_SOUND_LANG2 ] = "lang2", + }; + struct msp3400c *msp = i2c_get_clientdata(client); int nicam=0; /* channel source: FM/AM or nicam */ int src=0; @@ -613,7 +615,7 @@ static void msp3400c_restore_dfp(struct i2c_client *client) { - struct msp3400c *msp = client->data; + struct msp3400c *msp = i2c_get_clientdata(client); int i; for (i = 0; i < DFP_COUNT; i++) { @@ -641,7 +643,7 @@ static int autodetect_stereo(struct i2c_client *client) { - struct msp3400c *msp = client->data; + struct msp3400c *msp = i2c_get_clientdata(client); int val; int newstereo = msp->stereo; int newnicam = msp->nicam_on; @@ -744,7 +746,7 @@ /* stereo/multilang monitoring */ static void watch_stereo(struct i2c_client *client) { - struct msp3400c *msp = client->data; + struct msp3400c *msp = i2c_get_clientdata(client); if (autodetect_stereo(client)) { if (msp->stereo & VIDEO_SOUND_STEREO) @@ -765,24 +767,17 @@ static int msp3400c_thread(void *data) { struct i2c_client *client = data; - struct msp3400c *msp = client->data; + struct msp3400c *msp = i2c_get_clientdata(client); struct CARRIER_DETECT *cd; int count, max1,max2,val1,val2, val,this; -#ifdef CONFIG_SMP lock_kernel(); -#endif - daemonize(); sigfillset(¤t->blocked); strcpy(current->comm,"msp3400"); - msp->thread = current; - -#ifdef CONFIG_SMP unlock_kernel(); -#endif printk("msp3400: daemon started\n"); if(msp->notify != NULL) @@ -1024,22 +1019,15 @@ static int msp3410d_thread(void *data) { struct i2c_client *client = data; - struct msp3400c *msp = client->data; + struct msp3400c *msp = i2c_get_clientdata(client); int mode,val,i,std; -#ifdef CONFIG_SMP lock_kernel(); -#endif - daemonize(); sigfillset(¤t->blocked); strcpy(current->comm,"msp3410 [auto]"); - msp->thread = current; - -#ifdef CONFIG_SMP unlock_kernel(); -#endif printk("msp3410: daemon started\n"); if(msp->notify != NULL) @@ -1265,9 +1253,9 @@ static struct i2c_client client_template = { - .name = "(unset)", - .flags = I2C_CLIENT_ALLOW_USE, - .driver = &driver, + I2C_DEVNAME("(unset)"), + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; static int msp_attach(struct i2c_adapter *adap, int addr, @@ -1276,7 +1264,7 @@ DECLARE_MUTEX_LOCKED(sem); struct msp3400c *msp; struct i2c_client *c; - int i; + int i, rc; client_template.adapter = adap; client_template.addr = addr; @@ -1304,7 +1292,7 @@ for (i = 0; i < DFP_COUNT; i++) msp->dfp_regs[i] = -1; - c->data = msp; + i2c_set_clientdata(c, msp); init_waitqueue_head(&msp->wq); if (-1 == msp3400c_reset(c)) { @@ -1348,7 +1336,7 @@ msp->wake_stereo.data = (unsigned long)msp; /* hello world :-) */ - printk(KERN_INFO "msp34xx: init: chip=%s",c->name); + printk(KERN_INFO "msp34xx: init: chip=%s",i2c_clientname(c)); if (HAVE_NICAM(msp)) printk(" +nicam"); if (HAVE_SIMPLE(msp)) @@ -1360,9 +1348,12 @@ /* startup control thread */ MOD_INC_USE_COUNT; msp->notify = &sem; - kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread, - (void *)c, 0); - down(&sem); + rc = kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread, + (void *)c, 0); + if (rc < 0) + printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); + else + down(&sem); msp->notify = NULL; wake_up_interruptible(&msp->wq); @@ -1382,7 +1373,7 @@ static int msp_detach(struct i2c_client *client) { DECLARE_MUTEX_LOCKED(sem); - struct msp3400c *msp = (struct msp3400c*)client->data; + struct msp3400c *msp = i2c_get_clientdata(client); int i; /* shutdown control thread */ @@ -1421,7 +1412,7 @@ static void msp_wake_thread(struct i2c_client *client) { - struct msp3400c *msp = (struct msp3400c*)client->data; + struct msp3400c *msp = i2c_get_clientdata(client); msp3400c_setvolume(client,msp->muted,0,0); msp->watch_stereo=0; @@ -1433,7 +1424,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct msp3400c *msp = (struct msp3400c*)client->data; + struct msp3400c *msp = i2c_get_clientdata(client); __u16 *sarg = arg; #if 0 int *iarg = (int*)arg; @@ -1505,7 +1496,7 @@ if (r->reg < 0 || r->reg >= DFP_COUNT) return -EINVAL; - for (i = 0; i < sizeof(bl_dfp)/sizeof(int); i++) + for (i = 0; i < ARRAY_SIZE(bl_dfp); i++) if (r->reg == bl_dfp[i]) return -EINVAL; msp->dfp_regs[r->reg] = r->value; @@ -1537,8 +1528,8 @@ VIDEO_AUDIO_MUTABLE; if (msp->muted) va->flags |= VIDEO_AUDIO_MUTE; - va->volume=MAX(msp->left,msp->right); - va->balance=(32768*MIN(msp->left,msp->right))/ + va->volume=max(msp->left,msp->right); + va->balance=(32768*min(msp->left,msp->right))/ (va->volume ? va->volume : 1); va->balance=(msp->leftright)? (65535-va->balance) : va->balance; @@ -1559,9 +1550,9 @@ dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); msp->muted = (va->flags & VIDEO_AUDIO_MUTE); - msp->left = (MIN(65536 - va->balance,32768) * + msp->left = (min(65536 - va->balance,32768) * va->volume) / 32768; - msp->right = (MIN(va->balance,32768) * + msp->right = (min(va->balance,(__u16)32768) * va->volume) / 32768; msp->bass = va->bass; msp->treble = va->treble; @@ -1572,8 +1563,8 @@ if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) { msp->watch_stereo=0; del_timer(&msp->wake_stereo); - msp->stereo = va->mode; - msp3400c_setstereo(client,va->mode); + msp->stereo = va->mode & 0x0f; + msp3400c_setstereo(client,va->mode & 0x0f); } break; } diff -urN linux-2.4.21/drivers/media/video/swarm_saa7114h.c linux-2.4.22/drivers/media/video/swarm_saa7114h.c --- linux-2.4.21/drivers/media/video/swarm_saa7114h.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/media/video/swarm_saa7114h.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1695 @@ +/* + saa7114h - Philips SAA7114H video decoder driver + + Copyright (C) 2001,2002,2003 Broadcom Corporation + + From saa7111.c: + Copyright (C) 1998 Dave Perks + From cpia.c: + (C) Copyright 1999-2000 Peter Pregler + (C) Copyright 1999-2000 Scott J. Bertin + (C) Copyright 1999-2000 Johannes Erdfelt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU 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. + */ + +/* + * Important note: this driver is reasonably functional, and has been + * tested with the "camserv" v4l application. But it primarily a + * proof-of-concept, and example for setting up FIFO-mode. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define SAA_BRIGHTNESS 0x0a +#define SAA_CONTRAST 0x0b +#define SAA_SATURATION 0x0c +#define SAA_HUE 0x0d + +#define DECODER_STATUS 0x1f +#define SLICER_STATUS_0 0x60 +#define SLICER_STATUS_1 0x61 +#define SLICER_STATUS_2 0x62 +#define SCALER_STATUS 0x8f + +#define NUM_FRAME 2 +#define MAX_HORIZ 720 +#define MAX_VERT 480 +#define MIN_HORIZ 180 +#define MIN_VERT 120 +#define MAX_PER_PIXEL 3 +#define MAX_FRAME_SIZE (MAX_HORIZ*MAX_VERT*MAX_PER_PIXEL) +#define MAX_MMAP_SIZE (PAGE_ALIGN(MAX_FRAME_SIZE*NUM_FRAME)) +#define RAW_PER_PIXEL 2 +#define RAW_LINE_PAD 8 +#define RAW_LINE_SIZE (((MAX_HORIZ*RAW_PER_PIXEL)+RAW_LINE_PAD+0x1f) & ~0x1f) +#define RAW_FRAME_SIZE (RAW_LINE_SIZE*MAX_VERT) + +#define NUM_DESCR 64 +#define INTR_PKT_CNT 8 + +/* Extensions to videodev.h IOCTL definitions */ +#define VIDIOREADREG _IOR('v', 50, int) +#define VIDIOWRITEREG _IOW('v', 50, int) +#define VIDIOGRABFRAME _IOR('v', 51, int) +#define VIDIOSHOWEAV _IOR('v', 52, int) + +#define IF_NAME "saa7114h" + +#define MAC2_CSR(r) (KSEG1 + A_MAC_REGISTER(2, r)) +#define MAC2_DMARX0_CSR(r) (KSEG1 + A_MAC_DMA_REGISTER(2, DMA_RX, 0, r)) + +/* Options */ +#define DMA_DEINTERLACE 1 +#define LAZY_READ 1 +#define NULL_DMA 0 + +/* Debug filters */ +#define DBG_NULL 0x0000 +#define DBG_IO 0x0001 +#define DBG_DESCR 0x0002 +#define DBG_INTR 0x0004 +#define DBG_CONVERT 0x0008 +#define DBG_FRAMING 0x0010 +#define DBG_REGISTER 0x0020 +#define DBG_CALL 0x0040 +#define DBG_FRAMING_LOUD 0x0080 + +/* XXXKW make this settable through /proc... */ +#define DEBUG_LVL (DBG_NULL) + +#if DEBUG_LVL +#define DBG(l, p) do { if (DEBUG_LVL & l) p; } while (0) +#else +#define DBG(l, p) +#endif + +/* ----------------------------------------------------------------------- */ + +enum { + FRAME_READY, /* Ready to grab into */ + FRAME_GRABBING, /* In the process of being grabbed into */ + FRAME_DONE, /* Finished grabbing, but not been synced yet */ + FRAME_UNUSED, /* Unused (belongs to driver, but can't be used) */ +}; + +struct saa_frame { + uint8_t *data; + uint8_t *pos; + int width; + int height; + uint32_t size; + volatile int state; + wait_queue_head_t read_wait; +}; + +typedef struct fifo_descr_s { + uint64_t descr_a; + uint64_t descr_b; +} fifo_descr_t; + +typedef unsigned long paddr_t; + +typedef struct fifo_s { + unsigned ringsz; + fifo_descr_t *descrtab; + fifo_descr_t *descrtab_end; + fifo_descr_t *next_descr; + paddr_t descrtab_phys; + void *dma_buf; /* DMA buffer */ +} fifo_t; + +struct saa7114h { + struct i2c_client *client; + struct video_device *vd; + struct video_window vw; + struct video_picture vp; + uint8_t reg[256]; + + fifo_t ff; + void *frame_buf; /* hold frames for the client */ + struct saa_frame frame[NUM_FRAME]; /* point into frame_buf */ + int hwframe; + int swframe; + + uint16_t depth; + uint16_t palette; + uint8_t bright; + uint8_t contrast; + uint8_t hue; + uint8_t sat; + + struct proc_dir_entry *proc_entry; + struct semaphore param_lock; + struct semaphore busy_lock; + + int dma_enable; + int opened; + int irq; + int interlaced; +}; + +static int saa7114h_probe(struct i2c_adapter *adap); +static int saa7114h_detach(struct i2c_client *device); + +struct i2c_driver i2c_driver_saa7114h = +{ + name: "saa7114h", /* name */ + id: I2C_DRIVERID_SAA7114H, /* ID */ + flags: I2C_DF_NOTIFY, /* XXXKW do I care? */ + attach_adapter: saa7114h_probe, + detach_client: saa7114h_detach +}; + +/* ----------------------------------------------------------------------- + * VM assist for MMAPed space + * ----------------------------------------------------------------------- */ + +/* Given PGD from the address space's page table, return the kernel + * virtual mapping of the physical memory mapped at ADR. + */ +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) +{ + unsigned long ret = 0UL; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, adr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, adr); + pte = *ptep; + if (pte_present(pte)) { + ret = (unsigned long) page_address(pte_page(pte)); + ret |= (adr & (PAGE_SIZE-1)); + } + } + } + return ret; +} + +/* Here we want the physical address of the memory. + * This is used when initializing the contents of the + * area and marking the pages as reserved. + */ +static inline unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = __pa(kva); + return ret; +} + +static void *rvmalloc(unsigned long size) +{ + void *mem; + unsigned long adr, page; + + /* Round it off to PAGE_SIZE */ + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + mem = vmalloc_32(size); + if (!mem) + return NULL; + + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr = (unsigned long) mem; + while (size > 0) { + page = kvirt_to_pa(adr); + mem_map_reserve(virt_to_page(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + + return mem; +} + +static void rvfree(void *mem, unsigned long size) +{ + unsigned long adr, page; + + if (!mem) + return; + + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + adr = (unsigned long) mem; + while (size > 0) { + page = kvirt_to_pa(adr); + mem_map_unreserve(virt_to_page(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + vfree(mem); +} + +/* ----------------------------------------------------------------------- + * Control interface (i2c) + * ----------------------------------------------------------------------- */ + +static int saa7114h_reg_read(struct saa7114h *dev, unsigned char subaddr) +{ + return i2c_smbus_read_byte_data(dev->client, subaddr); +} + +static int saa7114h_reg_write(struct saa7114h *dev, unsigned char subaddr, int data) +{ + return i2c_smbus_write_byte_data(dev->client, subaddr, data & 0xff); +} + +static int saa7114h_reg_init(struct saa7114h *dev, unsigned const char *data, unsigned int len) +{ + int rc = 0; + int val; + + while (len && !rc) { + dev->reg[data[0]] = data[1]; + rc = saa7114h_reg_write(dev, data[0], data[1]); + if (!rc && (data[0] != 0)) { + val = saa7114h_reg_read(dev, data[0]); + if ((val < 0) || (val != data[1])) { + printk(KERN_ERR + IF_NAME ": init readback mismatch reg %02x = %02x (should be %02x)\n", + data[0], val, data[1]); + } + } + len -= 2; + data += 2; + } + return rc; +} + +/* ----------------------------------------------------------------------- + * /proc interface + * ----------------------------------------------------------------------- */ + +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry *saa7114h_proc_root=NULL; + +static int decoder_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *out = page; + int len, status; + struct saa7114h *decoder = data; + + out += sprintf(out, " SWARM saa7114h\n------------------\n"); + status = saa7114h_reg_read(decoder, DECODER_STATUS); + out += sprintf(out, " Decoder status = %02x\n", status); + if (status & 0x80) + out += sprintf(out, " interlaced\n"); + if (status & 0x40) + out += sprintf(out, " not locked\n"); + if (status & 0x02) + out += sprintf(out, " Macrovision detected\n"); + if (status & 0x01) + out += sprintf(out, " color\n"); + out += sprintf(out, " Brightness = %02x\n", decoder->bright); + out += sprintf(out, " Contrast = %02x\n", decoder->contrast); + out += sprintf(out, " Saturation = %02x\n", decoder->sat); + out += sprintf(out, " Hue = %02x\n\n", decoder->hue); + + out += sprintf(out, " Scaler status = %02x\n", + (int)saa7114h_reg_read(decoder, SCALER_STATUS)); + + len = out - page; + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) return 0; + } else + len = count; + + *start = page + off; + return len; +} + +static int decoder_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct saa7114h *d = data; + int retval; + unsigned int cmd, reg, reg_val; + + if (down_interruptible(&d->param_lock)) + return -ERESTARTSYS; + +#define VALUE \ + ({ \ + char *_p; \ + unsigned long int _ret; \ + while (count && isspace(*buffer)) { \ + buffer++; \ + count--; \ + } \ + _ret = simple_strtoul(buffer, &_p, 16); \ + if (_p == buffer) \ + retval = -EINVAL; \ + else { \ + count -= _p - buffer; \ + buffer = _p; \ + } \ + _ret; \ + }) + + retval = 0; + while (count && !retval) { + cmd = VALUE; + if (retval) + break; + switch (cmd) { + case 1: + reg = VALUE; + if (retval) + break; + reg_val = VALUE; + if (retval) + break; + printk(IF_NAME ": write reg %x <- %x\n", reg, reg_val); + if (saa7114h_reg_write(d, reg, reg_val) == -1) + retval = -EINVAL; + break; + case 2: + reg = VALUE; + if (retval) + break; + reg_val = saa7114h_reg_read(d, reg); + if (reg_val == -1) + retval = -EINVAL; + else + printk(IF_NAME ": read reg %x -> %x\n", reg, reg_val); + break; + default: + break; + } + } + up(&d->param_lock); + + return retval; +} + +static void create_proc_decoder(struct saa7114h *decoder) +{ + char name[8]; + struct proc_dir_entry *ent; + + if (!saa7114h_proc_root || !decoder) + return; + + sprintf(name, "video%d", decoder->vd->minor); + + ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, saa7114h_proc_root); + if (!ent) { + printk(KERN_INFO IF_NAME ": Unable to initialize /proc/saa7114h/%s\n", name); + return; + } + + ent->data = decoder; + ent->read_proc = decoder_read_proc; + ent->write_proc = decoder_write_proc; + ent->size = 3626; /* XXXKW ??? */ + decoder->proc_entry = ent; +} + +static void destroy_proc_decoder(struct saa7114h *decoder) +{ + char name[7]; + + if (!decoder || !decoder->proc_entry) + return; + + sprintf(name, "video%d", decoder->vd->minor); + remove_proc_entry(name, saa7114h_proc_root); + decoder->proc_entry = NULL; +} + +static void proc_saa7114h_create(void) +{ + saa7114h_proc_root = create_proc_entry("saa7114h", S_IFDIR, 0); + + if (saa7114h_proc_root) + saa7114h_proc_root->owner = THIS_MODULE; + else + printk(KERN_INFO IF_NAME ": Unable to initialize /proc/saa7114h\n"); +} + +static void proc_saa7114h_destroy(void) +{ + remove_proc_entry("saa7114h", 0); +} +#endif /* CONFIG_PROC_FS */ + + +/* ----------------------------------------------------------------------- + * Initialization + * ----------------------------------------------------------------------- */ + +static int dma_setup(struct saa7114h *d) +{ + int i; + void *curbuf; + + /* Reset the port */ + out64(M_MAC_PORT_RESET, MAC2_CSR(R_MAC_ENABLE)); + in64(MAC2_CSR(R_MAC_ENABLE)); + + /* Zero everything out, disable filters */ + out64(0, MAC2_CSR(R_MAC_TXD_CTL)); + out64(M_MAC_ALLPKT_EN, MAC2_CSR(R_MAC_ADFILTER_CFG)); + out64(V_MAC_RX_RD_THRSH(4) | V_MAC_RX_RL_THRSH(4), + MAC2_CSR(R_MAC_THRSH_CFG)); + for (i=0; iff.descrtab = kmalloc(NUM_DESCR * sizeof(fifo_descr_t), GFP_KERNEL); + d->ff.descrtab_phys = __pa(d->ff.descrtab); + d->ff.descrtab_end = d->ff.descrtab + NUM_DESCR; + d->ff.next_descr = d->ff.descrtab; + d->ff.ringsz = NUM_DESCR; +#if 0 + /* XXXKW this won't work because the physical may not be + contiguous; how do I handle a bigger alloc then? */ + d->ff.dma_buf = rvmalloc(RAW_LINE_SIZE*NUM_DESCR); + printk(KERN_DEBUG IF_NAME ": DMA buffer allocated (%p)\n", + d->ff.dma_buf); +#else + d->ff.dma_buf = kmalloc(RAW_LINE_SIZE*NUM_DESCR, GFP_KERNEL); +#endif + if (!d->ff.dma_buf) { + printk(KERN_ERR IF_NAME ": couldn't allocate DMA buffer\n"); + return -ENOMEM; + } + memset(d->ff.dma_buf, 0, RAW_LINE_SIZE*NUM_DESCR); + + for (i=0, curbuf=d->ff.dma_buf; iff.ringsz; i++, curbuf+=RAW_LINE_SIZE) { + d->ff.descrtab[i].descr_a = (__pa(curbuf) | + V_DMA_DSCRA_A_SIZE(RAW_LINE_SIZE >> 5)); + d->ff.descrtab[i].descr_b = 0; + } + + out64(V_DMA_INT_PKTCNT(INTR_PKT_CNT) | M_DMA_EOP_INT_EN | + V_DMA_RINGSZ(d->ff.ringsz) | M_DMA_TDX_EN, + MAC2_DMARX0_CSR(R_MAC_DMA_CONFIG0)); + out64(M_DMA_L2CA, MAC2_DMARX0_CSR(R_MAC_DMA_CONFIG1)); + out64(d->ff.descrtab_phys, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_BASE)); + + /* Enable interrupts and DMA */ + out64(M_MAC_INT_EOP_COUNT<0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16) + +static void yuvconvert_inplace(uint8_t *data, uint32_t in_uyvy, int out_fmt, int mmap) +{ + int y, u, v, r, g, b, y1; + uint8_t *src, *dst; + + if (out_fmt == VIDEO_PALETTE_RGB24) { + src = (uint8_t *)((int)data + in_uyvy); + dst = (uint8_t *)((int)data + in_uyvy + (in_uyvy >> 1)); + DBG(DBG_CONVERT, printk(KERN_DEBUG "inplace: %p %p %p\n", data, src, dst)); + while (src > data) { + if ((int)(src-data) < 4) + break; + //printk("freaky %p %p\n", src, data); + y1 = (*(--src) - 16) * 76310; + v = *(--src) - 128; + y = (*(--src) - 16) * 76310; + u = *(--src) - 128; + r = 104635 * v; + g = -25690 * u + -53294 * v; + b = 132278 * u; + /* XXXKW what on earth is up with mmap? */ + if (mmap) { + *(--dst) = LIMIT(r+y1); + *(--dst) = LIMIT(g+y1); + *(--dst) = LIMIT(b+y1); + *(--dst) = LIMIT(r+y); + *(--dst) = LIMIT(g+y); + *(--dst) = LIMIT(b+y); + } else { + *(--dst) = LIMIT(b+y1); + *(--dst) = LIMIT(g+y1); + *(--dst) = LIMIT(r+y1); + *(--dst) = LIMIT(b+y); + *(--dst) = LIMIT(g+y); + *(--dst) = LIMIT(r+y); + } + } + } +} + +static int saa7114h_get_cparams(struct saa7114h *decoder) +{ + /* XXX check for error code */ + decoder->bright = saa7114h_reg_read(decoder, SAA_BRIGHTNESS); + decoder->contrast = saa7114h_reg_read(decoder, SAA_CONTRAST); + decoder->sat = saa7114h_reg_read(decoder, SAA_SATURATION); + decoder->hue = saa7114h_reg_read(decoder, SAA_HUE); + + decoder->vp.brightness = (uint16_t)decoder->bright << 8; + decoder->vp.contrast = (uint16_t)decoder->contrast << 9; + decoder->vp.colour = decoder->sat << 9; + decoder->vp.hue = ((int16_t)decoder->hue + 128) << 8; + return 0; +} + +static int saa7114h_set_cparams(struct saa7114h *decoder) +{ + decoder->bright = decoder->vp.brightness >> 8; + decoder->contrast = decoder->vp.contrast >> 9; + decoder->sat = decoder->vp.colour >> 9; + decoder->hue = (uint8_t)((int8_t)(decoder->vp.hue >> 8) - 128); + + return (saa7114h_reg_write(decoder, SAA_BRIGHTNESS, decoder->bright) || + saa7114h_reg_write(decoder, SAA_CONTRAST, decoder->contrast) || + saa7114h_reg_write(decoder, SAA_SATURATION, decoder->sat) || + saa7114h_reg_write(decoder, SAA_HUE, decoder->hue)); +} + +/* ----------------------------------------------------------------------- + * Custom IOCTL support + * ----------------------------------------------------------------------- */ + +unsigned char eav[625][2]; +static int grab_frame(struct saa7114h *d, void *user_buf, int print_eav) +{ + int cur_idx = 0; + int to_go = 625; + int delta; + int i, len, eav_val, sav_val; + int started = 0; + uint8_t *buf; + fifo_descr_t *cur_d; + int swptr = d->ff.next_descr - d->ff.descrtab; + int hwptr; + + DBG(DBG_CALL, printk(IF_NAME ": grabbing frame\n")); + + /* Check for Macrovision -- if it's on, DMA won't happen */ + if (saa7114h_reg_read(d, DECODER_STATUS) & 0x2) + return -EACCES; + + out64(d->ff.ringsz, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + do { + hwptr = (unsigned) (((in64(MAC2_DMARX0_CSR(R_MAC_DMA_CUR_DSCRADDR)) & + M_DMA_CURDSCR_ADDR) - + d->ff.descrtab_phys) / + sizeof(fifo_descr_t)); + delta = (hwptr + d->ff.ringsz - swptr) % d->ff.ringsz; + + if (delta == 0) { +#if 0 + uint64_t val = in64(MAC2_DMARX0_CSR(R_MAC_STATUS)); + printk("mac status: %08x%08x\n", + (u32)(val >> 32), (u32)(val&0xffffffff)); +#endif + } + + for (i=0; iff.next_descr; + if (++d->ff.next_descr == d->ff.descrtab_end) + d->ff.next_descr = d->ff.descrtab; + + if (!(cur_d->descr_a & M_DMA_ETHRX_SOP)) { + printk("bogus RX\n"); + continue; + } + cur_d->descr_a &= ~M_DMA_ETHRX_SOP; + len = G_DMA_DSCRB_PKT_SIZE(cur_d->descr_b); + buf = (uint8_t *)__va(cur_d->descr_a & M_DMA_DSCRA_A_ADDR); + if (len != (d->vw.width*RAW_PER_PIXEL)+RAW_LINE_PAD) { + printk("funny size %d\n", len); + continue; + } + eav_val = buf[1]; + sav_val = buf[5]; + if (eav_val == 0xf1) { /* end of field 2, V-blank */ + if (started) { + started = 0; + delta = to_go = 0; + /* just let DMA finish in background */ + } else { + started = 1; + } + } + if (started) { + eav[cur_idx][0] = eav_val; + eav[cur_idx++][1] = sav_val; + if (copy_to_user(user_buf, &buf[6], 1440)) + return -EFAULT; + user_buf += 1440; + } + } + swptr = hwptr; + if (delta) { + if (started) + to_go -= delta; + if (delta > to_go) + delta = to_go; + out64(delta, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } + } while (to_go); + + if (print_eav) { + for (i=0; iff.next_descr - d->ff.descrtab; + int hwptr; + + status_val = in64(MAC2_CSR(R_MAC_STATUS)); + + /* Process finished decsriptors */ + hwptr = (unsigned) (((in64(MAC2_DMARX0_CSR(R_MAC_DMA_CUR_DSCRADDR)) & + M_DMA_CURDSCR_ADDR) - d->ff.descrtab_phys) / + sizeof(fifo_descr_t)); + delta = (hwptr + d->ff.ringsz - swptr) % d->ff.ringsz; + if (!delta) { + if (status_val & M_MAC_INT_EOP_SEEN<ff.ringsz; + } else { + /* XXXKW why would this happen? */ + return; + } + } + + for (i=0; iff.next_descr; + if (++d->ff.next_descr == d->ff.descrtab_end) + d->ff.next_descr = d->ff.descrtab; + + if (!(cur_d->descr_a & M_DMA_ETHRX_SOP)) { + printk(KERN_DEBUG "bogus RX\n"); + continue; + } + cur_d->descr_a &= ~M_DMA_ETHRX_SOP; + if (!d->dma_enable) + continue; + + len = G_DMA_DSCRB_PKT_SIZE(cur_d->descr_b); + buf = (uint8_t *)__va(cur_d->descr_a & M_DMA_DSCRA_A_ADDR); + if (len != (d->vw.width*RAW_PER_PIXEL)+RAW_LINE_PAD) { + printk(KERN_DEBUG "funny size %d\n", len); +// continue; + } + len -= RAW_LINE_PAD; + eav_val = buf[1]; + DBG(DBG_FRAMING_LOUD, + printk(KERN_DEBUG "eav: %02x len: %d\n", eav_val, len)); + if (eav_val == 0xf1) { /* end of field 2, V-blank: start-of-frame */ + switch (d->frame[d->hwframe].state) { + case FRAME_UNUSED: + DBG(DBG_FRAMING, + printk(KERN_ERR "capture to unused frame %d\n", + d->hwframe)); + break; + case FRAME_READY: + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame started %d\n", + d->hwframe)); + /* start this frame (skip eav/sav) */ + memcpy(d->frame[d->hwframe].pos, &buf[6], len); +#if DMA_DEINTERLACE + if (!d->interlaced) + memcpy(d->frame[d->hwframe].pos-len, &buf[6], len); + d->frame[d->hwframe].pos += len*2; +#else + d->frame[d->hwframe].pos += len; +#endif + d->frame[d->hwframe].state = FRAME_GRABBING; + /* XXXKW check pos overflow */ + break; + case FRAME_GRABBING: + /* kick over to new frame */ + d->frame[d->hwframe].size = d->frame[d->hwframe].pos - + d->frame[d->hwframe].data; + d->frame[d->hwframe].state = FRAME_DONE; + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame finished %d\n", + d->frame[d->hwframe].size)); + /* wake up a waiting reader */ + DBG(DBG_IO, printk(KERN_DEBUG "wakeup\n")); + wake_up(&d->frame[d->hwframe].read_wait); + d->hwframe = (d->hwframe + 1) % NUM_FRAME; + if (d->frame[d->hwframe].state == FRAME_READY) { + /* start this frame */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame bumped %d\n", + d->hwframe)); + memcpy(d->frame[d->hwframe].pos, &buf[6], len); +#if DMA_DEINTERLACE + if (!d->interlaced) + memcpy(d->frame[d->hwframe].pos-len, &buf[6], len); + d->frame[d->hwframe].pos += len*2; +#else + d->frame[d->hwframe].pos += len; +#endif + d->frame[d->hwframe].state = FRAME_GRABBING; + } else { + /* drop on the floor, + note that we've stopped DMA'ing */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame capture halted\n")); + d->dma_enable = 0; + } + break; + case FRAME_DONE: + /* drop on the floor (must be waiting for sw) */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame capture halted\n")); + d->dma_enable = 0; + break; + } + } else { + switch (d->frame[d->hwframe].state) { + case FRAME_UNUSED: + DBG(DBG_FRAMING, + printk(KERN_ERR "capture to unused frame %d\n", + d->hwframe)); + break; + case FRAME_READY: + /* drop on the floor (must have dropped something) */ + DBG(DBG_FRAMING_LOUD, + printk(KERN_DEBUG "missed SOF\n")); + break; + case FRAME_DONE: + /* drop on the floor (must be waiting for sw) */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame overflow\n")); + d->dma_enable = 0; + break; + case FRAME_GRABBING: +#if DMA_DEINTERLACE + if (eav_val == 0xb6) { + d->frame[d->hwframe].pos = d->frame[d->hwframe].data; + } + memcpy(d->frame[d->hwframe].pos, &buf[6], len); + if (!d->interlaced) + memcpy(d->frame[d->hwframe].pos-len, &buf[6], len); + d->frame[d->hwframe].pos += len*2; +#else + memcpy(d->frame[d->hwframe].pos, &buf[6], len); + d->frame[d->hwframe].pos += len; +#endif + /* XXXKW check pos overflow */ + break; + } + } + } + + if (d->dma_enable) { + out64(delta, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + DBG(DBG_DESCR, + printk(KERN_DEBUG IF_NAME ": interrupt adds %d -> %d descrs\n", + delta, (int)in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)))); + } +} + +/* ----------------------------------------------------------------------- + * /dev/video interface + * ----------------------------------------------------------------------- */ + +static int saa7114h_open(struct video_device *vd, int nb) +{ + struct saa7114h *d = vd->priv; + uint32_t status; + + if (!d || d->opened) + return -EBUSY; + + d->opened = 1; + DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ": open\n")); + + /* XXKW Should check this periodically!? */ + status = saa7114h_reg_read(d, DECODER_STATUS); + d->interlaced = ((status & 0x80) != 0); + +#if !NULL_DMA + if (d->dma_enable) { + printk(IF_NAME ": open found DMA on?!\n"); +#if LAZY_READ + } +#else + } else { + int descr; + d->dma_enable = 1; + DBG(DBG_DESCR, printk(IF_NAME ": open enabling DMA\n")); + /* Force capture to start into frame buffer 0 */ + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + DBG(DBG_DESCR, + printk(IF_NAME ": open adds %d -> %d descrs\n", + d->ff.ringsz-desc, descr)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif +#endif + + return 0; +} + +static void saa7114h_release(struct video_device *vd) +{ + struct saa7114h *d = vd->priv; + + DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ": release\n")); + d->opened = 0; + d->dma_enable = 0; + + /* XXXKW do a clean drain of outstanding DMAs? toss leftover + buffer contents to avoid stale pictures? */ + + return; +} + +static long saa7114h_read(struct video_device *vd, char *buf, + unsigned long count, int noblock) +{ + struct saa7114h *d = vd->priv; + int descr, status; + + if (!d) + return -ENODEV; + + /* XXKW Should check this periodically!? */ + status = saa7114h_reg_read(d, DECODER_STATUS); +// d->interlaced = ((status & 0x80) != 0); + +#if !NULL_DMA +#if LAZY_READ + if (!d->dma_enable) { + DBG(DBG_DESCR, printk(KERN_DEBUG IF_NAME ": enabling DMA\n")); + /* Give the buffer to the DMA engine (force ptr reset) */ + d->swframe = d->hwframe; + d->frame[d->swframe].state = FRAME_READY; +#if DMA_DEINTERLACE + d->frame[d->swframe].pos = d->frame[d->swframe].data+d->vw.width*RAW_PER_PIXEL; +#else + d->frame[d->swframe].pos = d->frame[d->swframe].data; +#endif + /* Fire up the DMA engine again if it stopped */ + d->dma_enable = 1; + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif +#endif + + /* XXXKW mmap/read mixture could break the swframe sequence */ + + if (d->frame[d->swframe].state != FRAME_DONE) { + if (noblock) + return -EAGAIN; + else { + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": sleeping for frame\n")); + interruptible_sleep_on(&d->frame[d->swframe].read_wait); + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": awakened\n")); + if (signal_pending(current)) + return -ERESTARTSYS; + } + } + + if (count < d->frame[d->swframe].size) + return -EFAULT; + + count = d->frame[d->swframe].size; + yuvconvert_inplace(d->frame[d->swframe].data, d->frame[d->swframe].size, d->vp.palette, 0); + copy_to_user(buf, d->frame[d->swframe].data, d->frame[d->swframe].size); + d->swframe = (d->swframe + 1) % NUM_FRAME; + /* XXXKW doesn't do format conversion!!! */ +#if !NULL_DMA +#if !LAZY_READ + /* XXXKW Fire up the DMA engine again if it stopped ??? */ + if (!d->dma_enable) { + DBG(DBG_DESCR, printk(KERN_DEBUG IF_NAME ": enabling DMA\n")); + /* Fire up the DMA engine again if it stopped */ + d->dma_enable = 1; + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif +#endif + + return count; +} + +static int saa7114h_ioctl(struct video_device *vd, unsigned int cmd, void *arg) +{ + struct saa7114h *d = vd->priv; + int val, reg, retval = 0; + + if (!d) + return -ENODEV; + + switch (cmd) { + case VIDIOCGCHAN: + { + struct video_channel v; + + if (copy_from_user(&v, arg, sizeof(v))) { + retval = -EFAULT; + break; + } + if (v.channel != 0) { + retval = -EINVAL; + break; + } + + v.channel = 0; + strcpy(v.name, "Camera"); + v.tuners = 0; + v.flags = 0; + v.type = VIDEO_TYPE_CAMERA; + v.norm = 0; + + if (copy_to_user(arg, &v, sizeof(v))) + retval = -EFAULT; + break; + } + + case VIDIOCSCHAN: + { + int v; + + if (copy_from_user(&v, arg, sizeof(v))) + retval = -EFAULT; + + if (retval == 0 && v != 0) + retval = -EINVAL; + + break; + } + + case VIDIOCGCAP: + { + struct video_capability b; + + strcpy(b.name, "Philips SAA7114H Decoder"); + b.type = VID_TYPE_CAPTURE /* | VID_TYPE_TELETEXT */ | VID_TYPE_SCALES; + b.channels = 1; + b.audios = 0; + b.maxwidth = MAX_HORIZ; + b.maxheight = MAX_VERT; + /* XXXKW find real values */ + b.minwidth = 48; + b.minheight = 48; + + if (copy_to_user(arg, &b, sizeof(b))) + retval = -EFAULT; + + break; + } + + /* image properties */ + case VIDIOCGPICT: + if (copy_to_user(arg, &d->vp, sizeof(struct video_picture))) + retval = -EFAULT; + break; + + case VIDIOCSPICT: + { + struct video_picture vp; + + /* copy_from_user */ + if (copy_from_user(&vp, arg, sizeof(vp))) { + retval = -EFAULT; + break; + } + + down(&d->param_lock); + /* brightness, colour, contrast need not check 0-65535 */ + memcpy( &d->vp, &vp, sizeof(vp) ); + /* update cam->params.colourParams */ + saa7114h_set_cparams(d); + up(&d->param_lock); + break; + } + + /* get/set capture window */ + case VIDIOCGWIN: + if (copy_to_user(arg, &d->vw, sizeof(struct video_window))) + retval = -EFAULT; + break; + + case VIDIOCSWIN: + { + /* copy_from_user, check validity, copy to internal structure */ + struct video_window vw; + if (copy_from_user(&vw, arg, sizeof(vw))) { + retval = -EFAULT; + break; + } + + if (vw.clipcount != 0) { /* clipping not supported */ + retval = -EINVAL; + break; + } + if (vw.clips != NULL) { /* clipping not supported */ + retval = -EINVAL; + break; + } + if ((vw.width > MAX_HORIZ || vw.width < MIN_HORIZ) || + (vw.height > MAX_VERT || vw.height < MIN_VERT)) { + retval = -EINVAL; + break; + } + + /* we set the video window to something smaller or equal to what + * is requested by the user??? + */ + down(&d->param_lock); + if (vw.width != d->vw.width || vw.height != d->vw.height) { + uint32_t scale_factor; + /* XXXKW base percentage on input stream, not MAX? */ + + /* Assert scaler reset */ + saa7114h_reg_write(d, 0x88, 0x98); + + /* Vertical scaling */ + scale_factor = (MAX_VERT*1024) / vw.height; + saa7114h_reg_write(d, 0x9e, vw.height & 0xff); + saa7114h_reg_write(d, 0x9f, (vw.height >> 8) & 0xf); + saa7114h_reg_write(d, 0xb0, scale_factor & 0xff); + saa7114h_reg_write(d, 0xb1, (scale_factor >> 8) & 0xff); + saa7114h_reg_write(d, 0xb2, scale_factor & 0xff); + saa7114h_reg_write(d, 0xb3, (scale_factor >> 8) & 0xff); + /* Horizontal scaling */ + scale_factor = (MAX_HORIZ*1024) / vw.width; + saa7114h_reg_write(d, 0x9c, vw.width & 0xff); + saa7114h_reg_write(d, 0x9d, (vw.width >> 8) & 0xf); + saa7114h_reg_write(d, 0xa8, scale_factor & 0xff); + saa7114h_reg_write(d, 0xa9, (scale_factor >> 8) & 0xff); + saa7114h_reg_write(d, 0xac, (scale_factor >> 1) & 0xff); + saa7114h_reg_write(d, 0xad, (scale_factor >> 9) & 0xff); +#if 0 + /* prescaler + saa7114h_reg_write(d, 0xa0, 2); + saa7114h_reg_write(d, 0xa1, 1); + saa7114h_reg_write(d, 0xa2, 1); + */ +#endif + + /* Release scaler reset */ + saa7114h_reg_write(d, 0x88, 0xb8); + d->vw.width = vw.width; + d->vw.height = vw.height; + } + up(&d->param_lock); + break; + } + + /* mmap interface */ + case VIDIOCGMBUF: + { + struct video_mbuf vm; + int i; + + memset(&vm, 0, sizeof(vm)); + vm.size = MAX_FRAME_SIZE*NUM_FRAME; + vm.frames = NUM_FRAME; + for (i = 0; i < NUM_FRAME; i++) + vm.offsets[i] = MAX_FRAME_SIZE * i; + + if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm))) + retval = -EFAULT; + + break; + } + + case VIDIOCMCAPTURE: + { + struct video_mmap vm; + int descr, status; + + if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) { + retval = -EFAULT; + break; + } + if (vm.frame<0||vm.frame>NUM_FRAME) { + retval = -EINVAL; + break; + } + + DBG(DBG_CALL, + printk(KERN_DEBUG IF_NAME ":ioctl MCAPTURE %d\n", vm.frame)); + + d->vp.palette = vm.format; + /* XXXKW set depth? */ + /* XXXKW match/update for vm.width, vm.height */ + + /* XXKW Should check this periodically!? */ + status = saa7114h_reg_read(d, DECODER_STATUS); +// d->interlaced = ((status & 0x80) != 0); + + /* Give the buffer to the DMA engine */ + /* XXXKW vm.frame vs d->swframe!! mmap/read mismatch */ +#if DMA_DEINTERLACE + d->frame[vm.frame].pos = d->frame[vm.frame].data + d->vw.width*RAW_PER_PIXEL; +#else + d->frame[vm.frame].pos = d->frame[vm.frame].data; +#endif +#if !NULL_DMA + d->frame[vm.frame].state = FRAME_READY; + /* Fire up the DMA engine again if it stopped */ + if (!d->dma_enable) { + d->dma_enable = 1; + d->hwframe = d->swframe = vm.frame; + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + DBG(DBG_DESCR, + printk(KERN_DEBUG IF_NAME ": capture adds %d -> %d descrs\n", + d->ff.ringsz-descr, descr)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif + break; + } + + case VIDIOCSYNC: + { + int frame; + + if (copy_from_user((void *)&frame, arg, sizeof(int))) { + retval = -EFAULT; + break; + } + + if (frame<0 || frame >= NUM_FRAME) { + retval = -EINVAL; + break; + } + + DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ":ioctl CSYNC %d\n", frame)); + + switch (d->frame[frame].state) { + case FRAME_UNUSED: + DBG(DBG_IO, + printk(KERN_ERR IF_NAME ":sync to unused frame %d\n", frame)); + retval = -EINVAL; + break; + + case FRAME_READY: + case FRAME_GRABBING: + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": sleeping for frame %d\n", frame)); + interruptible_sleep_on(&d->frame[frame].read_wait); + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": awakened\n")); + if (signal_pending(current)) + return -ERESTARTSYS; + case FRAME_DONE: +#if !NULL_DMA + yuvconvert_inplace(d->frame[frame].data, + d->frame[frame].size, + d->vp.palette, 1); + d->frame[frame].state = FRAME_UNUSED; +#endif + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": sync finished %d\n", + frame)); + break; + } + break; + } + + case VIDIOREADREG: + reg = *(int *)arg; + DBG(DBG_REGISTER, printk(KERN_DEBUG IF_NAME ": read of %02x\n", reg)); + if ((reg > 0xEF) || (reg < 0)) + return -EINVAL; + val = saa7114h_reg_read((struct saa7114h *)vd->priv, reg); + if (val == -1) + return -EIO; + *(int *)arg = val; + break; + case VIDIOWRITEREG: + if (copy_from_user(®, arg, sizeof(int)) || + copy_from_user(&val, arg+sizeof(int), sizeof(int))) + return -EFAULT; + DBG(DBG_REGISTER, printk(KERN_DEBUG IF_NAME ": write of %02x <- %02x\n", reg, val)); + if ((reg > 0xEF) || (reg < 0)) + return -EINVAL; + val = saa7114h_reg_write((struct saa7114h *)vd->priv, reg, val); + if (val == -1) + return -EIO; + break; + case VIDIOGRABFRAME: + return grab_frame((struct saa7114h *)vd->priv, arg, 0); + case VIDIOSHOWEAV: + return grab_frame((struct saa7114h *)vd->priv, arg, 1); + default: + retval = -EINVAL; + break; + } + + return retval; +} + +static int saa7114h_mmap(struct video_device *vd, const char *adr, + unsigned long size) +{ + struct saa7114h *d = vd->priv; + unsigned long start = (unsigned long)adr; + unsigned long page, pos; + + if (!d) + return -ENODEV; + + if (size > MAX_MMAP_SIZE) { + printk("mmap: bad size %lu > %lu\n", size, MAX_MMAP_SIZE); + return -EINVAL; + } + + /* make this _really_ smp-safe */ + if (down_interruptible(&d->busy_lock)) + return -EINTR; + + pos = (unsigned long)(d->frame_buf); + while (size > 0) { + page = kvirt_to_pa(pos); + if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) { + up(&d->busy_lock); + return -EAGAIN; + } + start += PAGE_SIZE; + pos += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + up(&d->busy_lock); + + return 0; +} + +/* ----------------------------------------------------------------------- + * Device probing and initialization + * ----------------------------------------------------------------------- */ + +/* Default values to program into SAA7114H */ +static const unsigned char reg_init[] = { + 0x00, 0x00, /* 00 - ID byte */ + + /*front end */ + 0x01, 0x08, /* 01 - Horizontal increment -> recommended delay */ + 0x02, 0xC4, /* 02 - AI Control 1 (CVBS AI23) */ + 0x03, 0x10, /* 03 - AI Control 2 */ + 0x04, 0x90, /* 04 - AI Control 3 (Gain ch 1) */ + 0x05, 0x90, /* 05 - AI Control 4 (Gain ch 2) */ + + /* decoder */ + 0x06, 0xEB, /* 06 - Horiz sync start */ + 0x07, 0xE0, /* 07 - Horiz sync stop */ + 0x08, 0x98, /* 08 - Sync control */ + 0x09, 0x40, /* 09 - L Control */ + 0x0a, 0x80, /* 0a - L Brightness */ + 0x0b, 0x44, /* 0b - L Contrast */ + 0x0c, 0x40, /* 0c - C Saturation */ + 0x0d, 0x00, /* 0d - C Hue */ + 0x0e, 0x89, /* 0e - C Control 1 */ + 0x0f, 0x0f, /* 0f - C Gain (??? 0x2A recommended) */ + 0x10, 0x0E, /* 10 - C Control 2 */ + 0x11, 0x00, /* 11 - Mode/Delay */ + 0x12, 0x00, /* 12 - RT signal control */ + 0x13, 0x00, /* 13 - RT/X output */ + 0x14, 0x00, /* 14 - Analog, Compat */ + 0x15, 0x11, /* 15 - VGATE start */ + 0x16, 0xFE, /* 16 - VGATE stop */ + 0x17, 0x40, /* 17 - Misc VGATE (disable LLC2) */ + 0x18, 0x40, /* 18 - Raw data gain - 128 */ + 0x19, 0x80, /* 19 - Raw data offset - 0 */ + + /* Global settings */ + 0x88, 0x98, /* 88 - AI1x on, AI2x off; decoder/slicer off; ACLK gen off */ + 0x83, 0x00, /* 83 - X-port output disabled */ + 0x84, 0xF0, /* 84 - I-port V/G output framing, IGP1=0=IGP0=0 */ + 0x85, 0x00, /* 85 - I-port default polarities, X-port signals */ + 0x86, 0x40, /* 86 - more IGP1/0, FIFO level, only video transmitted */ + 0x87, 0x01, /* 87 - ICK default, IDQ default, I-port output enabled */ + + /* Task A: scaler input config and output format */ + 0x90, 0x00, /* 90 - Task handling */ + 0x91, 0x08, /* 91 - Scalar input and format */ + 0x92, 0x10, /* 92 - Reference signal def */ + 0x93, 0x80, /* 93 - I-port output */ + + /* Task B */ + 0xc0, 0x42, /* 90 - Task handling */ + 0xc1, 0x08, /* 91 - Scalar input and format */ + 0xc2, 0x10, /* 92 - Reference signal def */ + 0xc3, 0x80, /* 93 - I-port output */ + + /* Input and Output windows */ + 0x94, 0x10, /* - */ + 0x95, 0x00, /* - */ + 0x96, 0xD0, /* - */ + 0x97, 0x02, /* - */ + 0x98, 0x0A, /* - */ + 0x99, 0x00, /* - */ + 0x9a, 0xF2, /* - */ + 0x9b, 0x00, /* - */ + 0x9c, 0xD0, /* - */ + 0x9d, 0x02, /* - */ + 0xc4, 0x10, /* - */ + 0xc5, 0x00, /* - */ + 0xc6, 0xD0, /* - */ + 0xc7, 0x02, /* - */ + 0xc8, 0x0A, /* - */ + 0xc9, 0x00, /* - */ + 0xca, 0xF2, /* - */ + 0xcb, 0x00, /* - */ + 0xcc, 0xD0, /* - */ + 0xcd, 0x02, /* - */ + + 0x9e, 0xf0, /* - */ + 0x9f, 0x00, /* - */ + 0xce, 0xf0, /* - */ + 0xcf, 0x00, /* - */ + + /* Prefiltering and prescaling */ + 0xa0, 0x01, /* - */ + 0xa1, 0x00, /* - */ + 0xa2, 0x00, /* - */ + 0xa4, 0x80, /* - */ + 0xa5, 0x40, /* - */ + 0xa6, 0x40, /* - */ + 0xd4, 0x80, /* - */ + 0xd5, 0x40, /* - */ + 0xd6, 0x40, /* - */ + + /* Horizontal phase scaling */ + 0xa8, 0x00, /* - */ + 0xa9, 0x04, /* - */ + 0xaa, 0x00, /* - */ + 0xd8, 0x00, /* - */ + 0xd9, 0x04, /* - */ + 0xda, 0x00, /* - */ + + 0xac, 0x00, /* - */ + 0xad, 0x02, /* - */ + 0xae, 0x00, /* - */ + 0xdc, 0x00, /* - */ + 0xdd, 0x02, /* - */ + 0xde, 0x00, /* - */ + + /* Vertical phase scaling */ + 0xb0, 0x00, /* - */ + 0xb1, 0x04, /* - */ + 0xb2, 0x00, /* - */ + 0xb3, 0x04, /* - */ + 0xe0, 0x00, /* - */ + 0xe1, 0x04, /* - */ + 0xe2, 0x00, /* - */ + 0xe3, 0x04, /* - */ + 0xb4, 0x00, /* b4 - vscale mode control */ + 0xe4, 0x00, /* b4 - vscale mode control */ + + /* Task enables */ + 0x80, 0x10, /* 80 - LLC->ICLK, dq->IDQ, scaler->F/V timing, task enables */ + + /* Reset the slicer */ + 0x88, 0xb8, /* 88 - AI1x on, AI2x off; decoder/slicer on; ACLK gen off */ +}; + +static int saa7114h_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) +{ + struct i2c_client *client; + struct video_device *vd; + struct saa7114h *decoder; + int err; + int val, i; + + client = kmalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + client->adapter = adap; + client->addr = addr; + client->driver = &i2c_driver_saa7114h; + strcpy(client->name, IF_NAME); + + decoder = kmalloc(sizeof(*decoder), GFP_KERNEL); + if (decoder == NULL) { + kfree(client); + return -ENOMEM; + } + memset(decoder, 0, sizeof(struct saa7114h)); + decoder->client = client; + decoder->dma_enable = 0; + decoder->palette = VIDEO_PALETTE_UYVY; + decoder->depth = 16; + decoder->vw.width = MAX_HORIZ; + decoder->vw.height = MAX_VERT; + decoder->frame_buf = rvmalloc(MAX_FRAME_SIZE*NUM_FRAME); + if (!decoder->frame_buf) { + kfree(decoder); + kfree(client); + return -ENOMEM; + } + /* XXXKW use clear_page? */ + memset(decoder->frame_buf, 0, MAX_FRAME_SIZE*NUM_FRAME); + printk("saa7114h_attach: frame_buf = (fb=%8p / %08lx)\n", + decoder->frame_buf, kvirt_to_pa((int)decoder->frame_buf)); + for (i=0; iframe[i].data = decoder->frame_buf+i*MAX_FRAME_SIZE; +#if NULL_DMA + decoder->frame[i].state = FRAME_DONE; +#else + decoder->frame[i].state = FRAME_UNUSED; +#endif + init_waitqueue_head(&decoder->frame[i].read_wait); + } + decoder->irq = K_INT_MAC_2; + if (request_irq + (decoder->irq, saa7114h_interrupt, 0, "Philips SAA7114h", decoder)) { + rvfree(decoder->frame_buf, MAX_FRAME_SIZE*NUM_FRAME); + kfree(decoder); + kfree(client); + return -ENOMEM; + } + init_MUTEX(&decoder->param_lock); + init_MUTEX(&decoder->busy_lock); + + if ((err = i2c_attach_client(client)) < 0) { + kfree(client); + kfree(decoder); + return err; + } + + if (saa7114h_reg_init(decoder, reg_init, sizeof(reg_init)) || + saa7114h_get_cparams(decoder)) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + return -ENODEV; + } + + vd = kmalloc(sizeof(*vd), GFP_KERNEL); + memset(vd, 0, sizeof(*vd)); + if (vd == NULL) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + return -ENOMEM; + } + vd->priv = decoder; + strcpy(vd->name, IF_NAME); + vd->type = VID_TYPE_CAPTURE; + vd->hardware = VID_HARDWARE_SAA7114H; + vd->open = saa7114h_open; + vd->close = saa7114h_release; + vd->read = saa7114h_read; + vd->ioctl = saa7114h_ioctl; + vd->mmap = saa7114h_mmap; + + if ((err = video_register_device(vd, VFL_TYPE_GRABBER, -1)) < 0) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + kfree(vd); + return err; + } + + client->data = vd; + decoder->vd = vd; + + /* Turn on the ITRDY - preserve the GENO pin for syncser */ + val = in64(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)); + out64(M_MAC_MDIO_OUT | (val & M_MAC_GENC), + KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)); + + if ((err = dma_setup(decoder))) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + kfree(vd); + return err; + } + + printk("saa7114h_attach successful\n"); + +#ifdef CONFIG_PROC_FS + proc_saa7114h_create(); + create_proc_decoder(vd->priv); +#endif + + MOD_INC_USE_COUNT; + + return 0; +} + +/* Addresses to scan */ +static unsigned short normal_i2c[] = {I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {0x20, 0x21, I2C_CLIENT_END}; +static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c, normal_i2c_range, + probe, probe_range, + ignore, ignore_range, + force +}; + +static int saa7114h_probe(struct i2c_adapter *adap) +{ + /* Look for this device on the given adapter (bus) */ + if (adap->id == (I2C_ALGO_SIBYTE | I2C_HW_SIBYTE)) + return i2c_probe(adap, &addr_data, &saa7114h_attach); + else + return 0; +} + +static int saa7114h_detach(struct i2c_client *device) +{ +#if 0 + kfree(device->data); + MOD_DEC_USE_COUNT; +#endif +#ifdef CONFIG_PROC_FS + destroy_proc_decoder(((struct video_device *)device->data)->priv); + proc_saa7114h_destroy(); +#endif + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static int __init swarm_7114h_init(void) +{ + return i2c_add_driver(&i2c_driver_saa7114h); +} + +static void __exit swarm_7114h_cleanup(void) +{ +} + +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("Philips SAA7114H Driver for Broadcom SWARM board"); + +module_init(swarm_7114h_init); +module_exit(swarm_7114h_cleanup); diff -urN linux-2.4.21/drivers/media/video/tda7432.c linux-2.4.22/drivers/media/video/tda7432.c --- linux-2.4.21/drivers/media/video/tda7432.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tda7432.c 2003-08-25 04:44:42.000000000 -0700 @@ -51,6 +51,7 @@ #include "bttv.h" #include "audiochip.h" #include "id.h" +#include "i2c-compat.h" #ifndef VIDEO_AUDIO_BALANCE # define VIDEO_AUDIO_BALANCE 32 @@ -260,7 +261,7 @@ static int tda7432_set(struct i2c_client *client) { - struct tda7432 *t = client->data; + struct tda7432 *t = i2c_get_clientdata(client); unsigned char buf[16]; d2printk("tda7432: In tda7432_set\n"); @@ -287,7 +288,7 @@ static void do_tda7432_init(struct i2c_client *client) { - struct tda7432 *t = client->data; + struct tda7432 *t = i2c_get_clientdata(client); d2printk("tda7432: In tda7432_init\n"); t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ @@ -328,11 +329,10 @@ memcpy(client,&client_template,sizeof(struct i2c_client)); client->adapter = adap; client->addr = addr; - client->data = t; + i2c_set_clientdata(client, t); do_tda7432_init(client); MOD_INC_USE_COUNT; - strcpy(client->name,"TDA7432"); printk(KERN_INFO "tda7432: init\n"); i2c_attach_client(client); @@ -348,7 +348,7 @@ static int tda7432_detach(struct i2c_client *client) { - struct tda7432 *t = client->data; + struct tda7432 *t = i2c_get_clientdata(client); do_tda7432_init(client); i2c_detach_client(client); @@ -361,7 +361,7 @@ static int tda7432_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct tda7432 *t = client->data; + struct tda7432 *t = i2c_get_clientdata(client); d2printk("tda7432: In tda7432_command\n"); switch (cmd) { @@ -525,9 +525,9 @@ static struct i2c_client client_template = { - .name = "tda7432", - .id = -1, - .driver = &driver, + I2C_DEVNAME("tda7432"), + .id = -1, + .driver = &driver, }; static int tda7432_init(void) diff -urN linux-2.4.21/drivers/media/video/tda9875.c linux-2.4.22/drivers/media/video/tda9875.c --- linux-2.4.21/drivers/media/video/tda9875.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tda9875.c 2003-08-25 04:44:42.000000000 -0700 @@ -33,6 +33,7 @@ #include "bttv.h" #include "audiochip.h" #include "id.h" +#include "i2c-compat.h" MODULE_PARM(debug,"i"); MODULE_LICENSE("GPL"); @@ -158,10 +159,11 @@ static void tda9875_set(struct i2c_client *client) { - struct tda9875 *tda = client->data; + struct tda9875 *tda = i2c_get_clientdata(client); unsigned char a; - dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n",tda->lvol,tda->rvol,tda->bass,tda->treble); + dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n", + tda->lvol,tda->rvol,tda->bass,tda->treble); a = tda->lvol & 0xff; @@ -176,7 +178,7 @@ static void do_tda9875_init(struct i2c_client *client) { - struct tda9875 *t = client->data; + struct tda9875 *t = i2c_get_clientdata(client); dprintk("In tda9875_init\n"); tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/ tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ @@ -256,7 +258,7 @@ memcpy(client,&client_template,sizeof(struct i2c_client)); client->adapter = adap; client->addr = addr; - client->data = t; + i2c_set_clientdata(client, t); if(!tda9875_checkit(adap,addr)) { kfree(t); @@ -265,7 +267,6 @@ do_tda9875_init(client); MOD_INC_USE_COUNT; - strcpy(client->name,"TDA9875"); printk(KERN_INFO "tda9875: init\n"); i2c_attach_client(client); @@ -281,7 +282,7 @@ static int tda9875_detach(struct i2c_client *client) { - struct tda9875 *t = client->data; + struct tda9875 *t = i2c_get_clientdata(client); do_tda9875_init(client); i2c_detach_client(client); @@ -294,7 +295,7 @@ static int tda9875_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct tda9875 *t = client->data; + struct tda9875 *t = i2c_get_clientdata(client); dprintk("In tda9875_command...\n"); @@ -316,17 +317,15 @@ /* min is -84 max is 24 */ left = (t->lvol+84)*606; right = (t->rvol+84)*606; - va->volume=MAX(left,right); - va->balance=(32768*MIN(left,right))/ + va->volume=max(left,right); + va->balance=(32768*min(left,right))/ (va->volume ? va->volume : 1); va->balance=(leftbalance) : va->balance; va->bass = (t->bass+12)*2427; /* min -12 max +15 */ va->treble = (t->treble+12)*2730;/* min -12 max +12 */ - va->mode |= VIDEO_SOUND_MONO; - break; /* VIDIOCGAUDIO case */ } @@ -336,9 +335,9 @@ int left,right; dprintk("VIDEOCSAUDIO...\n"); - left = (MIN(65536 - va->balance,32768) * + left = (min(65536 - va->balance,32768) * va->volume) / 32768; - right = (MIN(va->balance,32768) * + right = (min(va->balance,(__u16)32768) * va->volume) / 32768; t->lvol = ((left/606)-84) & 0xff; if (t->lvol > 24) @@ -397,9 +396,9 @@ static struct i2c_client client_template = { - .name = "tda9875", - .id = -1, - .driver = &driver, + I2C_DEVNAME("tda9875"), + .id = -1, + .driver = &driver, }; static int tda9875_init(void) diff -urN linux-2.4.21/drivers/media/video/tda9887.c linux-2.4.22/drivers/media/video/tda9887.c --- linux-2.4.21/drivers/media/video/tda9887.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tda9887.c 2003-08-25 04:44:42.000000000 -0700 @@ -7,8 +7,9 @@ #include #include -#include "id.h" #include "audiochip.h" +#include "id.h" +#include "i2c-compat.h" /* Chips: TDA9885 (PAL, NTSC) @@ -293,8 +294,6 @@ unsigned char *buf = NULL; int rc; - printk("tda9887_configure\n"); - if (t->radio) { dprintk("tda9885/6/7: FM Radio mode\n"); buf = buf_fm_stereo; @@ -359,9 +358,9 @@ return -ENOMEM; memset(t,0,sizeof(*t)); t->client = client_template; - t->client.data = t; t->pinnacle_id = -1; t->tvnorm=VIDEO_MODE_PAL; + i2c_set_clientdata(&t->client, t); i2c_attach_client(&t->client); MOD_INC_USE_COUNT; @@ -370,28 +369,19 @@ static int tda9887_probe(struct i2c_adapter *adap) { - int rc; - switch (adap->id) { case I2C_ALGO_BIT | I2C_HW_B_BT848: case I2C_ALGO_BIT | I2C_HW_B_RIVA: case I2C_ALGO_SAA7134: - printk("tda9887: probing %s i2c adapter [id=0x%x]\n", - adap->name,adap->id); - rc = i2c_probe(adap, &addr_data, tda9887_attach); + return i2c_probe(adap, &addr_data, tda9887_attach); break; - default: - printk("tda9887: ignoring %s i2c adapter [id=0x%x]\n", - adap->name,adap->id); - rc = 0; - /* nothing */ } - return rc; + return 0; } static int tda9887_detach(struct i2c_client *client) { - struct tda9887 *t = (struct tda9887*)client->data; + struct tda9887 *t = i2c_get_clientdata(client); i2c_detach_client(client); kfree(t); @@ -402,7 +392,7 @@ static int tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct tda9887 *t = (struct tda9887*)client->data; + struct tda9887 *t = i2c_get_clientdata(client); switch (cmd) { @@ -457,9 +447,9 @@ }; static struct i2c_client client_template = { - .name = "tda9887", - .flags = I2C_CLIENT_ALLOW_USE, - .driver = &driver, + I2C_DEVNAME("tda9887"), + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; static int tda9887_init_module(void) diff -urN linux-2.4.21/drivers/media/video/tuner.c linux-2.4.22/drivers/media/video/tuner.c --- linux-2.4.21/drivers/media/video/tuner.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tuner.c 2003-08-25 04:44:42.000000000 -0700 @@ -14,6 +14,8 @@ #include "tuner.h" #include "audiochip.h" +#include "i2c-compat.h" +# define strlcpy(dest,src,len) strncpy(dest,src,(len)-1) /* Addresses to scan */ static unsigned short normal_i2c[] = {I2C_CLIENT_END}; @@ -222,8 +224,13 @@ 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, + + { "HITACHI V7-J180AT", HITACHI, NTSC, + 16*170.00, 16*450.00, 0x01,0x02,0x00,0x8e,940 }, + { "Philips PAL_MK (FI1216 MK)", Philips, PAL, + 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, }; -#define TUNERS (sizeof(tuners)/sizeof(tuners[0])) +#define TUNERS ARRAY_SIZE(tuners) /* ---------------------------------------------------------------------- */ @@ -231,7 +238,7 @@ { unsigned char byte; - struct tuner *t = (struct tuner*)c->data; + struct tuner *t = i2c_get_clientdata(c); if (t->type == TUNER_MT2032) return 0; @@ -281,7 +288,7 @@ { unsigned char buf[21]; int ret,xogc,xok=0; - struct tuner *t = (struct tuner*)c->data; + struct tuner *t = i2c_get_clientdata(c); buf[0]=0; ret=i2c_master_send(c,buf,1); @@ -529,7 +536,7 @@ { unsigned char buf[21]; int lint_try,ret,sel,lock=0; - struct tuner *t = (struct tuner*)c->data; + struct tuner *t = i2c_get_clientdata(c); dprintk("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",rfin,if1,if2,from,to); @@ -586,18 +593,19 @@ int if2,from,to; // signal bandwidth and picture carrier - if(norm==VIDEO_MODE_NTSC) { + if (norm==VIDEO_MODE_NTSC) { from=40750*1000; to=46750*1000; if2=45750*1000; - } - else { // Pal + } else { + // Pal from=32900*1000; to=39900*1000; if2=38900*1000; } - mt2032_set_if_freq(c,freq* 1000*1000/16, 1090*1000*1000, if2, from, to); + mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, + 1090*1000*1000, if2, from, to); } @@ -607,7 +615,7 @@ u8 config; u16 div; struct tunertype *tun; - struct tuner *t = c->data; + struct tuner *t = i2c_get_clientdata(c); unsigned char buffer[4]; int rc; @@ -733,19 +741,20 @@ } -static void mt2032_set_radio_freq(struct i2c_client *c, int freq) +static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) { - struct tuner *t = (struct tuner*)c->data; + struct tuner *t = i2c_get_clientdata(c); int if2 = t->radio_if2; // per Manual for FM tuning: first if center freq. 1085 MHz - mt2032_set_if_freq(c,freq* 1000*1000/16, 1085*1000*1000,if2,if2,if2); + mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, + 1085*1000*1000,if2,if2,if2); } static void set_radio_freq(struct i2c_client *c, unsigned int freq) { struct tunertype *tun; - struct tuner *t = (struct tuner*)c->data; + struct tuner *t = i2c_get_clientdata(c); unsigned char buffer[4]; unsigned div; int rc; @@ -807,19 +816,20 @@ if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) return -ENOMEM; memcpy(client,&client_template,sizeof(struct i2c_client)); - client->data = t = kmalloc(sizeof(struct tuner),GFP_KERNEL); + t = kmalloc(sizeof(struct tuner),GFP_KERNEL); if (NULL == t) { kfree(client); return -ENOMEM; } memset(t,0,sizeof(struct tuner)); + i2c_set_clientdata(client, t); t->type = UNSET; t->radio_if2 = 10700*1000; // 10.7MHz - FM radio if (type < TUNERS) { t->type = type; printk("tuner(bttv): type forced to %d (%s) [insmod]\n",t->type,tuners[t->type].name); - strncpy(client->name, tuners[t->type].name, sizeof(client->name)); + strlcpy(client->name, tuners[t->type].name, sizeof(client->name)); } i2c_attach_client(client); if (t->type == TUNER_MT2032) @@ -831,34 +841,26 @@ static int tuner_probe(struct i2c_adapter *adap) { - int rc; - if (0 != addr) { normal_i2c_range[0] = addr; normal_i2c_range[1] = addr; } this_adap = 0; + switch (adap->id) { case I2C_ALGO_BIT | I2C_HW_B_BT848: case I2C_ALGO_BIT | I2C_HW_B_RIVA: case I2C_ALGO_SAA7134: case I2C_ALGO_SAA7146: - printk("tuner: probing %s i2c adapter [id=0x%x]\n", - adap->name,adap->id); - rc = i2c_probe(adap, &addr_data, tuner_attach); + return i2c_probe(adap, &addr_data, tuner_attach); break; - default: - printk("tuner: ignoring %s i2c adapter [id=0x%x]\n", - adap->name,adap->id); - rc = 0; - /* nothing */ } - return rc; + return 0; } static int tuner_detach(struct i2c_client *client) { - struct tuner *t = (struct tuner*)client->data; + struct tuner *t = i2c_get_clientdata(client); i2c_detach_client(client); kfree(t); @@ -870,7 +872,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct tuner *t = (struct tuner*)client->data; + struct tuner *t = i2c_get_clientdata(client); unsigned int *iarg = (int*)arg; switch (cmd) { @@ -886,7 +888,7 @@ t->type = *iarg; printk("tuner: type set to %d (%s)\n", t->type,tuners[t->type].name); - strncpy(client->name, tuners[t->type].name, sizeof(client->name)); + strlcpy(client->name, tuners[t->type].name, sizeof(client->name)); if (t->type == TUNER_MT2032) mt2032_init(client); break; @@ -970,9 +972,9 @@ }; static struct i2c_client client_template = { - .name = "(tuner unset)", - .flags = I2C_CLIENT_ALLOW_USE, - .driver = &driver, + I2C_DEVNAME("(tuner unset)"), + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; static int tuner_init_module(void) diff -urN linux-2.4.21/drivers/media/video/tuner.h linux-2.4.22/drivers/media/video/tuner.h --- linux-2.4.21/drivers/media/video/tuner.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tuner.h 2003-08-25 04:44:42.000000000 -0700 @@ -64,9 +64,8 @@ #define TUNER_LG_PAL_NEW_TAPC 37 #define TUNER_PHILIPS_FM1216ME_MK3 38 #define TUNER_LG_NTSC_NEW_TAPC 39 - - - +#define TUNER_HITACHI_NTSC 40 +#define TUNER_PHILIPS_PAL_MK 41 #define NOTUNER 0 #define PAL 1 /* PAL_BG */ @@ -83,6 +82,7 @@ #define SHARP 6 #define Samsung 7 #define Microtune 8 +#define HITACHI 9 #define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */ #define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */ diff -urN linux-2.4.21/drivers/media/video/tvaudio.c linux-2.4.22/drivers/media/video/tvaudio.c --- linux-2.4.21/drivers/media/video/tvaudio.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tvaudio.c 2003-08-25 04:44:42.000000000 -0700 @@ -30,9 +30,10 @@ #include #include "audiochip.h" -#include "tvaudio.h" #include "id.h" +#include "i2c-compat.h" +#include "tvaudio.h" /* ---------------------------------------------------------------------- */ /* insmod args */ @@ -40,12 +41,13 @@ MODULE_PARM(debug,"i"); static int debug = 0; /* insmod parameter */ -#define dprintk if (debug) printk - MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips"); MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr"); MODULE_LICENSE("GPL"); +#define UNSET (-1U) +#define dprintk if (debug) printk + /* ---------------------------------------------------------------------- */ /* our structs */ @@ -160,22 +162,24 @@ unsigned char buffer[2]; if (-1 == subaddr) { - dprintk("%s: chip_write: 0x%x\n", chip->c.name, val); + dprintk("%s: chip_write: 0x%x\n", + i2c_clientname(&chip->c), val); chip->shadow.bytes[1] = val; buffer[0] = val; if (1 != i2c_master_send(&chip->c,buffer,1)) { printk(KERN_WARNING "%s: I/O error (write 0x%x)\n", - chip->c.name, val); + i2c_clientname(&chip->c), val); return -1; } } else { - dprintk("%s: chip_write: reg%d=0x%x\n", chip->c.name, subaddr, val); + dprintk("%s: chip_write: reg%d=0x%x\n", + i2c_clientname(&chip->c), subaddr, val); chip->shadow.bytes[subaddr+1] = val; buffer[0] = subaddr; buffer[1] = val; if (2 != i2c_master_send(&chip->c,buffer,2)) { printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n", - chip->c.name, subaddr, val); + i2c_clientname(&chip->c), subaddr, val); return -1; } } @@ -200,10 +204,10 @@ if (1 != i2c_master_recv(&chip->c,&buffer,1)) { printk(KERN_WARNING "%s: I/O error (read)\n", - chip->c.name); + i2c_clientname(&chip->c)); return -1; } - dprintk("%s: chip_read: 0x%x\n",chip->c.name,buffer); + dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer); return buffer; } @@ -219,11 +223,11 @@ if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { printk(KERN_WARNING "%s: I/O error (read2)\n", - chip->c.name); + i2c_clientname(&chip->c)); return -1; } dprintk("%s: chip_read2: reg%d=0x%x\n", - chip->c.name,subaddr,read[0]); + i2c_clientname(&chip->c),subaddr,read[0]); return read[0]; } @@ -236,7 +240,7 @@ /* update our shadow register set; print bytes if (debug > 0) */ dprintk("%s: chip_cmd(%s): reg=%d, data:", - chip->c.name,name,cmd->bytes[0]); + i2c_clientname(&chip->c),name,cmd->bytes[0]); for (i = 1; i < cmd->count; i++) { dprintk(" 0x%x",cmd->bytes[i]); chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i]; @@ -245,7 +249,7 @@ /* send data to the chip */ if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { - printk(KERN_WARNING "%s: I/O error (%s)\n", chip->c.name, name); + printk(KERN_WARNING "%s: I/O error (%s)\n", i2c_clientname(&chip->c), name); return -1; } return 0; @@ -269,24 +273,20 @@ struct CHIPSTATE *chip = data; struct CHIPDESC *desc = chiplist + chip->type; -#ifdef CONFIG_SMP lock_kernel(); -#endif daemonize(); sigfillset(¤t->blocked); - strcpy(current->comm,chip->c.name); + strcpy(current->comm,i2c_clientname(&chip->c)); chip->thread = current; -#ifdef CONFIG_SMP unlock_kernel(); -#endif - dprintk("%s: thread started\n", chip->c.name); + dprintk("%s: thread started\n", i2c_clientname(&chip->c)); if(chip->notify != NULL) up(chip->notify); for (;;) { interruptible_sleep_on(&chip->wq); - dprintk("%s: thread wakeup\n", chip->c.name); + dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c)); if (chip->done || signal_pending(current)) break; @@ -302,7 +302,7 @@ } chip->thread = NULL; - dprintk("%s: thread exiting\n", chip->c.name); + dprintk("%s: thread exiting\n", i2c_clientname(&chip->c)); if(chip->notify != NULL) up(chip->notify); @@ -317,7 +317,7 @@ if (mode == chip->prevmode) return; - dprintk("%s: thread checkmode\n", chip->c.name); + dprintk("%s: thread checkmode\n", i2c_clientname(&chip->c)); chip->prevmode = mode; if (mode & VIDEO_SOUND_STEREO) @@ -765,9 +765,9 @@ static int tda9874a_dic = -1; /* device id. code */ /* insmod options for tda9874a */ -static int tda9874a_SIF = -1; -static int tda9874a_AMSEL = -1; -static int tda9874a_STD = -1; +static unsigned int tda9874a_SIF = UNSET; +static unsigned int tda9874a_AMSEL = UNSET; +static unsigned int tda9874a_STD = UNSET; MODULE_PARM(tda9874a_SIF,"i"); MODULE_PARM(tda9874a_AMSEL,"i"); MODULE_PARM(tda9874a_STD,"i"); @@ -982,7 +982,7 @@ dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); if((dic == 0x11)||(dic == 0x07)) { - dprintk("tvaudio: found tda9874%s.\n",(dic == 0x11) ? "a (new)":"h (old)"); + printk("tvaudio: found tda9874%s.\n", (dic == 0x11) ? "a":"h"); tda9874a_dic = dic; /* remember device id. */ return 1; } @@ -991,35 +991,27 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) { - if(tda9874a_SIF != -1) { - if(tda9874a_SIF == 1) - tda9874a_GCONR = 0xc0; /* sound IF input 1 */ - else if(tda9874a_SIF == 2) - tda9874a_GCONR = 0xc1; /* sound IF input 2 */ - else - printk(KERN_WARNING "tda9874a: SIF parameter must be 1 or 2.\n"); - } + if (tda9874a_SIF > 2) + tda9874a_SIF = 1; + if (tda9874a_STD >= 8) + tda9874a_STD = 0; + if(tda9874a_AMSEL > 1) + tda9874a_AMSEL = 0; - if(tda9874a_STD != -1) { - if((tda9874a_STD >= 0)&&(tda9874a_STD <= 8)) { - tda9874a_ESP = tda9874a_STD; - tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1; - } else { - printk(KERN_WARNING "tda9874a: STD parameter must be between 0 and 8.\n"); - } - } + if(tda9874a_SIF == 1) + tda9874a_GCONR = 0xc0; /* sound IF input 1 */ + else + tda9874a_GCONR = 0xc1; /* sound IF input 2 */ - if(tda9874a_AMSEL != -1) { - if(tda9874a_AMSEL == 0) - tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */ - else if(tda9874a_AMSEL == 1) - tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */ - else - printk(KERN_WARNING "tda9874a: AMSEL parameter must be 0 or 1.\n"); - } + tda9874a_ESP = tda9874a_STD; + tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1; - tda9874a_setup(chip); + if(tda9874a_AMSEL == 0) + tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */ + else + tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */ + tda9874a_setup(chip); return 0; } @@ -1133,6 +1125,87 @@ #define PIC16C54_MISC_SWITCH_TUNER 0x40 /* bit 6 , Switch to Line-in */ #define PIC16C54_MISC_SWITCH_LINE 0x80 /* bit 7 , Switch to Tuner */ +/* ---------------------------------------------------------------------- */ +/* audio chip descriptions - defines+functions for TA8874Z */ + +// write 1st byte +#define TA8874Z_LED_STE 0x80 +#define TA8874Z_LED_BIL 0x40 +#define TA8874Z_LED_EXT 0x20 +#define TA8874Z_MONO_SET 0x10 +#define TA8874Z_MUTE 0x08 +#define TA8874Z_F_MONO 0x04 +#define TA8874Z_MODE_SUB 0x02 +#define TA8874Z_MODE_MAIN 0x01 + +// write 2nd byte +//#define TA8874Z_TI 0x80 // test mode +#define TA8874Z_SEPARATION 0x3f +#define TA8874Z_SEPARATION_DEFAULT 0x10 + +// read +#define TA8874Z_B1 0x80 +#define TA8874Z_B0 0x40 +#define TA8874Z_CHAG_FLAG 0x20 + +// B1 B0 +// mono L H +// stereo L L +// BIL H L + +static int ta8874z_getmode(struct CHIPSTATE *chip) +{ + int val, mode; + + val = chip_read(chip); + mode = VIDEO_SOUND_MONO; + if (val & TA8874Z_B1){ + mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; + }else if (!(val & TA8874Z_B0)){ + mode |= VIDEO_SOUND_STEREO; + } + //dprintk ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); + return mode; +} + +static audiocmd ta8874z_stereo = { 2, {0, TA8874Z_SEPARATION_DEFAULT}}; +static audiocmd ta8874z_mono = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}; +static audiocmd ta8874z_main = {2, { 0, TA8874Z_SEPARATION_DEFAULT}}; +static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}}; + +static void ta8874z_setmode(struct CHIPSTATE *chip, int mode) +{ + int update = 1; + audiocmd *t = NULL; + dprintk("ta8874z_setmode(): mode: 0x%02x\n", mode); + + switch(mode){ + case VIDEO_SOUND_MONO: + t = &ta8874z_mono; + break; + case VIDEO_SOUND_STEREO: + t = &ta8874z_stereo; + break; + case VIDEO_SOUND_LANG1: + t = &ta8874z_main; + break; + case VIDEO_SOUND_LANG2: + t = &ta8874z_sub; + break; + default: + update = 0; + } + + if(update) + chip_cmd(chip, "TA8874Z", t); +} + +static int ta8874z_checkit(struct CHIPSTATE *chip) +{ + int rc; + rc = chip_read(chip); + return ((rc & 0x1f) == 0x1f) ? 1 : 0; +} /* ---------------------------------------------------------------------- */ /* audio chip descriptions - struct CHIPDESC */ @@ -1144,9 +1217,11 @@ int tda9855 = 1; int tda9873 = 1; int tda9874a = 1; -int tea6300 = 0; +int tea6300 = 0; // address clash with msp34xx int tea6420 = 1; int pic16c54 = 1; +int ta8874z = 0; // address clash with tda9840 + MODULE_PARM(tda8425,"i"); MODULE_PARM(tda9840,"i"); MODULE_PARM(tda9850,"i"); @@ -1156,6 +1231,7 @@ MODULE_PARM(tea6300,"i"); MODULE_PARM(tea6420,"i"); MODULE_PARM(pic16c54,"i"); +MODULE_PARM(ta8874z,"i"); static struct CHIPDESC chiplist[] = { { @@ -1320,7 +1396,23 @@ PIC16C54_MISC_SND_NOTMUTE}, .inputmute = PIC16C54_MISC_SND_MUTE, }, - { name: NULL } /* EOF */ + { + .name = "ta8874z", + .id = -1, + //.id = I2C_DRIVERID_TA8874Z, + .checkit = ta8874z_checkit, + .insmodopt = &ta8874z, + .addr_lo = I2C_TDA9840 >> 1, + .addr_hi = I2C_TDA9840 >> 1, + .registers = 2, + + .getmode = ta8874z_getmode, + .setmode = ta8874z_setmode, + .checkmode = generic_checkmode, + + .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, + }, + { .name = NULL } /* EOF */ }; @@ -1332,6 +1424,7 @@ { struct CHIPSTATE *chip; struct CHIPDESC *desc; + int rc; chip = kmalloc(sizeof(*chip),GFP_KERNEL); if (!chip) @@ -1340,7 +1433,7 @@ memcpy(&chip->c,&client_template,sizeof(struct i2c_client)); chip->c.adapter = adap; chip->c.addr = addr; - chip->c.data = chip; + i2c_set_clientdata(&chip->c, chip); /* find description for the chip */ dprintk("tvaudio: chip found @ i2c-addr=0x%x\n", addr<<1); @@ -1358,14 +1451,14 @@ dprintk("tvaudio: no matching chip description found\n"); return -EIO; } - printk("tvaudio: found %s\n",desc->name); + printk("tvaudio: found %s @ 0x%x\n", desc->name, addr<<1); dprintk("tvaudio: matches:%s%s%s.\n", (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "", (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "", (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); /* fill required data structures */ - strcpy(chip->c.name,desc->name); + strcpy(i2c_clientname(&chip->c),desc->name); chip->type = desc-chiplist; chip->shadow.count = desc->registers+1; chip->prevmode = -1; @@ -1400,8 +1493,12 @@ chip->wt.function = chip_thread_wake; chip->wt.data = (unsigned long)chip; init_waitqueue_head(&chip->wq); - kernel_thread(chip_thread,(void *)chip,0); - down(&sem); + rc = kernel_thread(chip_thread,(void *)chip,0); + if (rc < 0) + printk(KERN_WARNING "%s: kernel_thread() failed\n", + i2c_clientname(&chip->c)); + else + down(&sem); chip->notify = NULL; wake_up_interruptible(&chip->wq); } @@ -1413,16 +1510,15 @@ switch (adap->id) { case I2C_ALGO_BIT | I2C_HW_B_BT848: case I2C_ALGO_BIT | I2C_HW_B_RIVA: + case I2C_ALGO_SAA7134: return i2c_probe(adap, &addr_data, chip_attach); - default: - /* ignore this i2c bus */ - return 0; } + return 0; } static int chip_detach(struct i2c_client *client) { - struct CHIPSTATE *chip = client->data; + struct CHIPSTATE *chip = i2c_get_clientdata(client); del_timer(&chip->wt); if (NULL != chip->thread) { @@ -1448,10 +1544,10 @@ unsigned int cmd, void *arg) { __u16 *sarg = arg; - struct CHIPSTATE *chip = client->data; + struct CHIPSTATE *chip = i2c_get_clientdata(client); struct CHIPDESC *desc = chiplist + chip->type; - dprintk("%s: chip_command 0x%x\n",chip->c.name,cmd); + dprintk("%s: chip_command 0x%x\n",i2c_clientname(&chip->c),cmd); switch (cmd) { case AUDC_SET_INPUT: @@ -1479,8 +1575,8 @@ if (desc->flags & CHIP_HAS_VOLUME) { va->flags |= VIDEO_AUDIO_VOLUME; - va->volume = MAX(chip->left,chip->right); - va->balance = (32768*MIN(chip->left,chip->right))/ + va->volume = max(chip->left,chip->right); + va->balance = (32768*min(chip->left,chip->right))/ (va->volume ? va->volume : 1); } if (desc->flags & CHIP_HAS_BASSTREBLE) { @@ -1502,9 +1598,9 @@ struct video_audio *va = arg; if (desc->flags & CHIP_HAS_VOLUME) { - chip->left = (MIN(65536 - va->balance,32768) * + chip->left = (min(65536 - va->balance,32768) * va->volume) / 32768; - chip->right = (MIN(va->balance,32768) * + chip->right = (min(va->balance,(__u16)32768) * va->volume) / 32768; chip_write(chip,desc->leftreg,desc->volfunc(chip->left)); chip_write(chip,desc->rightreg,desc->volfunc(chip->right)); @@ -1558,9 +1654,9 @@ static struct i2c_client client_template = { - .name = "(unset)", - .flags = I2C_CLIENT_ALLOW_USE, - .driver = &driver, + I2C_DEVNAME("(unset)"), + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; static int audiochip_init_module(void) diff -urN linux-2.4.21/drivers/media/video/tvaudio.h linux-2.4.22/drivers/media/video/tvaudio.h --- linux-2.4.21/drivers/media/video/tvaudio.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tvaudio.h 2003-08-25 04:44:42.000000000 -0700 @@ -3,7 +3,7 @@ */ #define I2C_TDA8425 0x82 -#define I2C_TDA9840 0x84 +#define I2C_TDA9840 0x84 /* also used by TA8874Z */ #define I2C_TDA985x_L 0xb4 /* also used by 9873 */ #define I2C_TDA985x_H 0xb6 #define I2C_TDA9874 0xb0 /* also used by 9875 */ diff -urN linux-2.4.21/drivers/media/video/tvmixer.c linux-2.4.22/drivers/media/video/tvmixer.c --- linux-2.4.21/drivers/media/video/tvmixer.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/media/video/tvmixer.c 2003-08-25 04:44:42.000000000 -0700 @@ -10,21 +10,18 @@ #include #include #include -#include - #include #include + +#include #include -#include "audiochip.h" -#include "id.h" +# include "i2c-compat.h" +# define strlcpy(dest,src,len) strncpy(dest,src,(len)-1) #define DEV_MAX 4 -static int debug = 0; static int devnr = -1; - -MODULE_PARM(debug,"i"); MODULE_PARM(devnr,"i"); MODULE_AUTHOR("Gerd Knorr"); @@ -88,8 +85,8 @@ if (cmd == SOUND_MIXER_INFO) { mixer_info info; - strncpy(info.id, "tv card", sizeof(info.id)); - strncpy(info.name, client->name, sizeof(info.name)); + strlcpy(info.id, "tv card", sizeof(info.id)); + strlcpy(info.name, i2c_clientname(client), sizeof(info.name)); info.modify_counter = 42 /* FIXME */; if (copy_to_user((void *)arg, &info, sizeof(info))) return -EFAULT; @@ -97,8 +94,8 @@ } if (cmd == SOUND_OLD_MIXER_INFO) { _old_mixer_info info; - strncpy(info.id, "tv card", sizeof(info.id)); - strncpy(info.name, client->name, sizeof(info.name)); + strlcpy(info.id, "tv card", sizeof(info.id)); + strlcpy(info.name, i2c_clientname(client), sizeof(info.name)); if (copy_to_user((void *)arg, &info, sizeof(info))) return -EFAULT; return 0; @@ -136,16 +133,16 @@ case MIXER_WRITE(SOUND_MIXER_VOLUME): left = mix_to_v4l(val); right = mix_to_v4l(val >> 8); - va.volume = MAX(left,right); - va.balance = (32768*MIN(left,right)) / (va.volume ? va.volume : 1); + va.volume = max(left,right); + va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1); va.balance = (leftdriver->command(client,VIDIOCSAUDIO,&va); client->driver->command(client,VIDIOCGAUDIO,&va); /* fall throuth */ case MIXER_READ(SOUND_MIXER_VOLUME): - left = (MIN(65536 - va.balance,32768) * + left = (min(65536 - va.balance,32768) * va.volume) / 32768; - right = (MIN(va.balance,32768) * + right = (min(va.balance,(u16)32768) * va.volume) / 32768; ret = v4l_to_mix2(left,right); break; @@ -237,8 +234,6 @@ { int i; - if (debug) - printk("tvmixer: adapter %s\n",adap->name); for (i=0; iclients[i]) continue; @@ -260,12 +255,8 @@ break; default: /* ignore that one */ - if (debug) - printk("tvmixer: %s is not a tv card\n", - client->adapter->name); return -1; } - printk("tvmixer: debug: %s\n",client->name); /* unregister ?? */ for (i = 0; i < DEV_MAX; i++) { @@ -274,7 +265,8 @@ unregister_sound_mixer(devices[i].minor); devices[i].dev = NULL; devices[i].minor = -1; - printk("tvmixer: %s unregistered (#1)\n",client->name); + printk("tvmixer: %s unregistered (#1)\n", + i2c_clientname(client)); return 0; } } @@ -289,25 +281,13 @@ } /* audio chip with mixer ??? */ - if (NULL == client->driver->command) { - if (debug) - printk("tvmixer: %s: driver->command is NULL\n", - client->driver->name); + if (NULL == client->driver->command) return -1; - } memset(&va,0,sizeof(va)); - if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) { - if (debug) - printk("tvmixer: %s: VIDIOCGAUDIO failed\n", - client->name); + if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) return -1; - } - if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) { - if (debug) - printk("tvmixer: %s: has no volume control\n", - client->name); + if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) return -1; - } /* everything is fine, register */ if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) { @@ -345,7 +325,7 @@ if (devices[i].minor != -1) { unregister_sound_mixer(devices[i].minor); printk("tvmixer: %s unregistered (#2)\n", - devices[i].dev->name); + i2c_clientname(devices[i].dev)); } } } diff -urN linux-2.4.21/drivers/message/fusion/Makefile linux-2.4.22/drivers/message/fusion/Makefile --- linux-2.4.21/drivers/message/fusion/Makefile 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/message/fusion/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -9,7 +9,7 @@ # parent makefile. # # Note 3! If you want to turn on various debug defines for an extended period of -# time but don't want them lingering around in the Makefile when you pass it on +# time but don't want them lingering around in the Makefile when you pass it on # to someone else, use the MPT_CFLAGS env variable (thanks Steve). -nromer #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-{ LSI_LOGIC @@ -28,6 +28,7 @@ #EXTRA_CFLAGS += -DMPT_DEBUG #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME #EXTRA_CFLAGS += -DMPT_DEBUG_SG +#EXTRA_CFLAGS += -DMPTSCSIH_DBG_TIMEOUT # # driver/module specifics... # @@ -36,7 +37,8 @@ #CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ # # For mptscsih: -#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV +#CFLAGS_mptscsih.o += -DMPT_DEBUG_DV +#CFLAGS_mptscsih.o += -DMPT_DEBUG_DV_TINY #CFLAGS_mptscsih.o += -DMPT_DEBUG_RESET #CFLAGS_mptscsih.o += -DMPT_DEBUG_NEH # diff -urN linux-2.4.21/drivers/message/fusion/isense.c linux-2.4.22/drivers/message/fusion/isense.c --- linux-2.4.21/drivers/message/fusion/isense.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/isense.c 2003-08-25 04:44:42.000000000 -0700 @@ -9,9 +9,9 @@ * Written By: Steven J. Ralston * (yes I wrote some of the orig. code back in 1991!) * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:lstephens@lsil.com) * - * $Id: isense.c,v 1.33 2002/02/27 18:44:19 sralston Exp $ + * $Id: isense.c,v 1.34 2003/03/18 22:49:48 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -89,7 +89,9 @@ #define my_VERSION MPT_LINUX_VERSION_COMMON #define MYNAM "isense" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62) EXPORT_NO_SYMBOLS; +#endif MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/message/fusion/linux_compat.h linux-2.4.22/drivers/message/fusion/linux_compat.h --- linux-2.4.21/drivers/message/fusion/linux_compat.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/linux_compat.h 2003-08-25 04:44:42.000000000 -0700 @@ -75,11 +75,11 @@ typedef void (*__cleanup_module_func_t)(void); #define module_init(x) \ int init_module(void) __attribute__((alias(#x))); \ - extern inline __init_module_func_t __init_module_inline(void) \ + static inline __init_module_func_t __init_module_inline(void) \ { return x; } #define module_exit(x) \ void cleanup_module(void) __attribute__((alias(#x))); \ - extern inline __cleanup_module_func_t __cleanup_module_inline(void) \ + static inline __cleanup_module_func_t __cleanup_module_inline(void) \ { return x; } #else @@ -247,8 +247,10 @@ /* * We use our new error handling code if the kernel version is 2.4.18 or newer. + * Remark: 5/5/03 use old EH code with 2.4 kernels as it runs in a background thread + * 2.4 kernels choke on a call to schedule via eh thread. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) #define MPT_SCSI_USE_NEW_EH #endif @@ -270,6 +272,13 @@ #define mptscsih_sync_irq(_irq) synchronize_irq() #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,58) +#define mpt_inc_use_count() +#define mpt_dec_use_count() +#else +#define mpt_inc_use_count() MOD_INC_USE_COUNT +#define mpt_dec_use_count() MOD_DEC_USE_COUNT +#endif /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff -urN linux-2.4.21/drivers/message/fusion/lsi/mpi_tool.h linux-2.4.22/drivers/message/fusion/lsi/mpi_tool.h --- linux-2.4.21/drivers/message/fusion/lsi/mpi_tool.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/lsi/mpi_tool.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2001 LSI Logic Corporation. - * - * - * Name: MPI_TOOL.H - * Title: MPI Toolbox structures and definitions - * Creation Date: July 30, 2001 - * - * MPI Version: 01.02.02 - * - * Version History - * --------------- - * - * Date Version Description - * -------- -------- ------------------------------------------------------ - * 08-08-01 01.02.01 Original release. - * 08-29-01 01.02.02 Added DIAG_DATA_UPLOAD_HEADER and related defines. - * -------------------------------------------------------------------------- - */ - -#ifndef MPI_TOOL_H -#define MPI_TOOL_H - -#define MPI_TOOLBOX_CLEAN_TOOL (0x00) -#define MPI_TOOLBOX_MEMORY_MOVE_TOOL (0x01) -#define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02) - - -/****************************************************************************/ -/* Toolbox reply */ -/****************************************************************************/ - -typedef struct _MSG_TOOLBOX_REPLY -{ - U8 Tool; /* 00h */ - U8 Reserved; /* 01h */ - U8 MsgLength; /* 02h */ - U8 Function; /* 03h */ - U16 Reserved1; /* 04h */ - U8 Reserved2; /* 06h */ - U8 MsgFlags; /* 07h */ - U32 MsgContext; /* 08h */ - U16 Reserved3; /* 0Ch */ - U16 IOCStatus; /* 0Eh */ - U32 IOCLogInfo; /* 10h */ -} MSG_TOOLBOX_REPLY, MPI_POINTER PTR_MSG_TOOLBOX_REPLY, - ToolboxReply_t, MPI_POINTER pToolboxReply_t; - - -/****************************************************************************/ -/* Toolbox Clean Tool request */ -/****************************************************************************/ - -typedef struct _MSG_TOOLBOX_CLEAN_REQUEST -{ - U8 Tool; /* 00h */ - U8 Reserved; /* 01h */ - U8 ChainOffset; /* 02h */ - U8 Function; /* 03h */ - U16 Reserved1; /* 04h */ - U8 Reserved2; /* 06h */ - U8 MsgFlags; /* 07h */ - U32 MsgContext; /* 08h */ - U32 Flags; /* 0Ch */ -} MSG_TOOLBOX_CLEAN_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_CLEAN_REQUEST, - ToolboxCleanRequest_t, MPI_POINTER pToolboxCleanRequest_t; - -#define MPI_TOOLBOX_CLEAN_NVSRAM (0x00000001) -#define MPI_TOOLBOX_CLEAN_SEEPROM (0x00000002) -#define MPI_TOOLBOX_CLEAN_FLASH (0x00000004) - - -/****************************************************************************/ -/* Toolbox Memory Move request */ -/****************************************************************************/ - -typedef struct _MSG_TOOLBOX_MEM_MOVE_REQUEST -{ - U8 Tool; /* 00h */ - U8 Reserved; /* 01h */ - U8 ChainOffset; /* 02h */ - U8 Function; /* 03h */ - U16 Reserved1; /* 04h */ - U8 Reserved2; /* 06h */ - U8 MsgFlags; /* 07h */ - U32 MsgContext; /* 08h */ - SGE_SIMPLE_UNION SGL; /* 0Ch */ -} MSG_TOOLBOX_MEM_MOVE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_MEM_MOVE_REQUEST, - ToolboxMemMoveRequest_t, MPI_POINTER pToolboxMemMoveRequest_t; - - -/****************************************************************************/ -/* Toolbox Diagnostic Data Upload request */ -/****************************************************************************/ - -typedef struct _MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST -{ - U8 Tool; /* 00h */ - U8 Reserved; /* 01h */ - U8 ChainOffset; /* 02h */ - U8 Function; /* 03h */ - U16 Reserved1; /* 04h */ - U8 Reserved2; /* 06h */ - U8 MsgFlags; /* 07h */ - U32 MsgContext; /* 08h */ - U32 Flags; /* 0Ch */ - U32 Reserved3; /* 10h */ - SGE_SIMPLE_UNION SGL; /* 14h */ -} MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, - ToolboxDiagDataUploadRequest_t, MPI_POINTER pToolboxDiagDataUploadRequest_t; - -typedef struct _DIAG_DATA_UPLOAD_HEADER -{ - U32 DiagDataLength; /* 00h */ - U8 FormatCode; /* 04h */ - U8 Reserved; /* 05h */ - U16 Reserved1; /* 06h */ -} DIAG_DATA_UPLOAD_HEADER, MPI_POINTER PTR_DIAG_DATA_UPLOAD_HEADER, - DiagDataUploadHeader_t, MPI_POINTER pDiagDataUploadHeader_t; - -#define MPI_TB_DIAG_FORMAT_SCSI_PRINTF_1 (0x01) -#define MPI_TB_DIAG_FORMAT_SCSI_2 (0x02) -#define MPI_TB_DIAG_FORMAT_SCSI_3 (0x03) -#define MPI_TB_DIAG_FORMAT_FC_TRACE_1 (0x04) - - -#endif - - diff -urN linux-2.4.21/drivers/message/fusion/mptbase.c linux-2.4.22/drivers/message/fusion/mptbase.c --- linux-2.4.21/drivers/message/fusion/mptbase.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/mptbase.c 2003-08-25 04:44:42.000000000 -0700 @@ -47,9 +47,9 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:lstephens@lsil.com) * - * $Id: mptbase.c,v 1.126 2002/12/16 15:28:45 pdelaney Exp $ + * $Id: mptbase.c,v 1.130 2003/05/07 14:08:30 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -123,8 +123,10 @@ /* * cmd line parameters */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59) MODULE_PARM(PortIo, "0-1i"); MODULE_PARM_DESC(PortIo, "[0]=Use mmap, 1=Use port io"); +#endif static int PortIo = 0; #ifdef MFCNT @@ -444,7 +446,7 @@ */ if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth)) || (mf < ioc->req_frames)) ) { - printk(MYIOC_s_WARN_FMT + printk(MYIOC_s_WARN_FMT "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx); cb_idx = 0; pa = 0; @@ -452,14 +454,14 @@ } if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth)) || (mr < ioc->reply_frames)) ) { - printk(MYIOC_s_WARN_FMT + printk(MYIOC_s_WARN_FMT "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr); cb_idx = 0; pa = 0; freeme = 0; } if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) { - printk(MYIOC_s_WARN_FMT + printk(MYIOC_s_WARN_FMT "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx); cb_idx = 0; pa = 0; @@ -577,7 +579,7 @@ CONFIGPARMS *pCfg; unsigned long flags; - dprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n", + dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n", ioc->name, mf, reply)); pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *))); @@ -600,7 +602,7 @@ u16 status; status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; - dprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n", + dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n", status, le32_to_cpu(pReply->IOCLogInfo))); pCfg->status = status; @@ -684,7 +686,7 @@ MptEvHandlers[i] = NULL; last_drv_idx = i; if (cbfunc != mpt_base_reply) { - MOD_INC_USE_COUNT; + mpt_inc_use_count(); } break; } @@ -704,7 +706,7 @@ void mpt_deregister(int cb_idx) { - if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { + if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { MptCallbacks[cb_idx] = NULL; MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; MptEvHandlers[cb_idx] = NULL; @@ -714,7 +716,7 @@ isense_idx++; if (cb_idx != mpt_base_index) { - MOD_DEC_USE_COUNT; + mpt_dec_use_count(); } } } @@ -944,7 +946,7 @@ * mpt_add_sge - Place a simple SGE at address pAddr. * @pAddr: virtual address for SGE * @flagslength: SGE flags and data transfer length - * @dma_addr: Physical address + * @dma_addr: Physical address * * This routine places a MPT request frame back on the MPT adapter's * FreeQ. @@ -974,7 +976,7 @@ * @pAddr: virtual address for SGE * @next: nextChainOffset value (u32's) * @length: length of next SGL segment - * @dma_addr: Physical address + * @dma_addr: Physical address * * This routine places a MPT request frame back on the MPT adapter's * FreeQ. @@ -987,7 +989,7 @@ u32 tmp = dma_addr & 0xFFFFFFFF; pChain->Length = cpu_to_le16(length); - pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size(); + pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size(); pChain->NextChainOffset = next; @@ -1070,7 +1072,7 @@ CHIPREG_WRITE32(&iocp->chip->IntStatus, 0); - if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) { + if ((r = WaitForDoorbellAck(iocp, 2, sleepFlag)) < 0) { return -2; } @@ -1084,7 +1086,7 @@ (req_as_bytes[(ii*4) + 2] << 16) | (req_as_bytes[(ii*4) + 3] << 24)); CHIPREG_WRITE32(&iocp->chip->Doorbell, word); - if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) { + if ((r = WaitForDoorbellAck(iocp, 2, sleepFlag)) < 0) { r = -3; break; } @@ -1278,17 +1280,19 @@ u32 psize; int ii; int r = -ENODEV; - u64 mask = 0xffffffffffffffff; + u64 mask = 0xffffffffffffffffULL; if (pci_enable_device(pdev)) return r; if (!pci_set_dma_mask(pdev, mask)) { - dprintk((KERN_INFO MYNAM - ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); - } else if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) { - printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n"); - return r; + dprintk((KERN_INFO MYNAM ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); + } else { + if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) { + printk(KERN_WARNING MYNAM + ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n"); + return r; + } } ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); @@ -1510,7 +1514,7 @@ /* NEW! 20010220 -sralston * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets. */ - if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030) + if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030) || (ioc->chip_type == C1035) || (ioc->chip_type == FC929X)) mpt_detect_bound_ports(ioc, pdev); @@ -1551,20 +1555,23 @@ int r; int ii; int handlers; + int ret = 0; + int reset_alt_ioc_active = 0; printk(KERN_INFO MYNAM ": Initiating %s %s\n", ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); - /* Disable reply interrupts */ + /* Disable reply interrupts (also blocks FreeQ) */ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); ioc->active = 0; - /* NOTE: Access to IOC's request FreeQ is now blocked! */ if (ioc->alt_ioc) { - /* Disable alt-IOC's reply interrupts for a bit ... */ + if (ioc->alt_ioc->active) + reset_alt_ioc_active = 1; + + /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */ CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF); ioc->alt_ioc->active = 0; - /* NOTE: Access to alt-IOC's request FreeQ is now blocked! */ } hard = 1; @@ -1572,15 +1579,29 @@ hard = 0; if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) { - printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n", - ioc->name); + if (hard_reset_done == -4) { + printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n", + ioc->name); + + if (reset_alt_ioc_active && ioc->alt_ioc) { + /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ + dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", + ioc->alt_ioc->name)); + CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); + ioc->alt_ioc->active = 1; + } + + } else { + printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n", + ioc->name); + } return -1; } /* hard_reset_done = 0 if a soft reset was performed * and 1 if a hard reset was performed. */ - if (hard_reset_done && ioc->alt_ioc) { + if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) { if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) alt_ioc_ready = 1; else @@ -1589,42 +1610,55 @@ ioc->alt_ioc->name, r); } - /* Get IOC facts! */ + /* Get IOC facts! Allow 1 retry */ if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0) - return -2; - if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { + r = GetIocFacts(ioc, sleepFlag, reason); + + if (r) { + ret = -2; + } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { MptDisplayIocCapabilities(ioc); } if (alt_ioc_ready) { - if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) - return -2; - if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { + if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { + /* Retry - alt IOC was initialized once + */ + r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); + } + if (r) { + alt_ioc_ready = 0; + reset_alt_ioc_active = 0; + } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { MptDisplayIocCapabilities(ioc->alt_ioc); } } - /* - * Prime reply & request queues! + /* Prime reply & request queues! * (mucho alloc's) Must be done prior to * init as upper addresses are needed for init. + * If fails, continue with alt-ioc processing */ - if ((r = PrimeIocFifos(ioc)) != 0) - return -3; + if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0)) + ret = -3; - // May need to check/upload firmware & data here! - if ((r = SendIocInit(ioc, sleepFlag)) != 0) - return -4; + /* May need to check/upload firmware & data here! + * If fails, continue with alt-ioc processing + */ + if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0)) + ret = -4; // NEW! if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) { printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n", ioc->alt_ioc->name, r); alt_ioc_ready = 0; + reset_alt_ioc_active = 0; } if (alt_ioc_ready) { if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { alt_ioc_ready = 0; + reset_alt_ioc_active = 0; printk(KERN_WARNING MYNAM ": alt-%s: (%d) init failure WARNING!\n", ioc->alt_ioc->name, r); @@ -1636,13 +1670,18 @@ ddlprintk((MYIOC_s_INFO_FMT "firmware upload required!\n", ioc->name)); - r = mpt_do_upload(ioc, sleepFlag); - if (r != 0) - printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); + /* Controller is not operational, cannot do upload + */ + if (ret == 0) { + r = mpt_do_upload(ioc, sleepFlag); + if (r != 0) + printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); + } + /* Handle the alt IOC too */ if ((alt_ioc_ready) && (ioc->alt_ioc->upload_fw)){ ddlprintk((MYIOC_s_INFO_FMT - "Alt-ioc firmware upload required!\n", + "Alt-ioc firmware upload required!\n", ioc->name)); r = mpt_do_upload(ioc->alt_ioc, sleepFlag); if (r != 0) @@ -1651,12 +1690,13 @@ } } + if (ret == 0) { + /* Enable! (reply interrupt) */ + CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); + ioc->active = 1; + } - /* Enable! (reply interrupt) */ - CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); - ioc->active = 1; - - if (ioc->alt_ioc) { + if (reset_alt_ioc_active && ioc->alt_ioc) { /* (re)Enable alt-IOC! (reply interrupt) */ dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", ioc->alt_ioc->name)); @@ -1668,7 +1708,7 @@ * Enable MPT base driver management of EventNotification * and EventAck handling. */ - if (!ioc->facts.EventState) + if ((ret == 0) && (!ioc->facts.EventState)) (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */ if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) @@ -1682,7 +1722,7 @@ * routine calls HardResetHandler, which calls into here again, * and we try GetLanConfigPages again... */ - if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { + if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { if ((int)ioc->chip_type <= (int)FC929) { /* * Pre-fetch FC port WWN and stuff... @@ -1712,11 +1752,11 @@ */ mpt_GetScsiPortSettings(ioc, 0); - /* Get version and length of SDP 1 + /* Get version and length of SDP 1 */ mpt_readScsiDevicePageHeaders(ioc, 0); - /* Find IM volumes + /* Find IM volumes */ if (ioc->facts.MsgVersion >= 0x0102) mpt_findImVolumes(ioc); @@ -1738,24 +1778,24 @@ if (hard_reset_done) { r = handlers = 0; for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { - if (MptResetHandlers[ii]) { + if ((ret == 0) && MptResetHandlers[ii]) { dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n", ioc->name, ii)); r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET); handlers++; + } - if (alt_ioc_ready) { - dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", - ioc->name, ioc->alt_ioc->name, ii)); - r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); - handlers++; - } + if (alt_ioc_ready && MptResetHandlers[ii]) { + dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", + ioc->name, ioc->alt_ioc->name, ii)); + r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); + handlers++; } } /* FIXME? Examine results here? */ } - return 0; + return ret; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1830,7 +1870,7 @@ ddlprintk((KERN_INFO MYNAM ": Pushing FW onto adapter\n")); if ((ret = mpt_downloadboot(this, NO_SLEEP)) < 0) { - printk(KERN_WARNING MYNAM + printk(KERN_WARNING MYNAM ": firmware downloadboot failure (%d)!\n", ret); } } @@ -2014,8 +2054,8 @@ * * Returns: * 1 - DIAG reset and READY - * 0 - READY initially OR soft reset and READY - * -1 - Any failure on KickStart + * 0 - READY initially OR soft reset and READY + * -1 - Any failure on KickStart * -2 - Msg Unit Reset Failed * -3 - IO Unit Reset Failed * -4 - IOC owned by a PEER @@ -2058,7 +2098,7 @@ else statefault = 4; } - } + } /* * Check to see if IOC is in FAULT state. @@ -2106,9 +2146,7 @@ * Loop here waiting for IOC to come READY. */ ii = 0; - cntdn = HZ * 15; - if (sleepFlag != CAN_SLEEP) - cntdn *= 10; /* 1500 iterations @ 1msec per */ + cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */ while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { if (ioc_state == MPI_IOC_STATE_OPERATIONAL) { @@ -2199,7 +2237,7 @@ int req_sz; int reply_sz; u32 status; - + /* IOC *must* NOT be in RESET state! */ if (ioc->last_state == MPI_IOC_STATE_RESET) { printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n", @@ -2260,7 +2298,7 @@ facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize); /* - * FC f/w version changed between 1.1 and 1.2 + * FC f/w version changed between 1.1 and 1.2 * Old: u16{Major(4),Minor(4),SubMinor(8)} * New: u32{Major(8),Minor(8),Unit(8),Dev(8)} */ @@ -2433,10 +2471,10 @@ if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) { if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw)) ioc_init.Flags = MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE; - else + else ioc->upload_fw = 1; } - ddlprintk((MYIOC_s_INFO_FMT "flags %d, upload_fw %d \n", + ddlprintk((MYIOC_s_INFO_FMT "flags %d, upload_fw %d \n", ioc->name, ioc_init.Flags, ioc->upload_fw)); if ((int)ioc->chip_type <= (int)FC929) { @@ -2482,9 +2520,7 @@ * LoopInit and TargetDiscovery! */ count = 0; - cntdn = HZ * 60; /* chg'd from 30 to 60 seconds */ - if (sleepFlag != CAN_SLEEP) - cntdn *= 10; /* scale for 1msec delays */ + cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */ state = mpt_GetIocState(ioc, 1); while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) { if (sleepFlag == CAN_SLEEP) { @@ -2570,8 +2606,8 @@ * Outputs: frags - number of fragments needed * Return NULL if failed. */ -void * -mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz) +void * +mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz) { fw_image_t **cached_fw = NULL; u8 *mem = NULL; @@ -2580,7 +2616,7 @@ int bytes_left, bytes, num_frags; int sz, ii; - /* cached_fw + /* cached_fw */ sz = ioc->num_fw_frags * sizeof(void *); mem = kmalloc(sz, GFP_ATOMIC); @@ -2737,8 +2773,8 @@ ioc->num_fw_frags = ioc->req_sz - sizeof(FWUpload_t) + sizeof(dma_addr_t) + sizeof(u32) -1; ioc->num_fw_frags /= sizeof(dma_addr_t) + sizeof(u32); - ioc->cached_fw = (fw_image_t **) mpt_alloc_fw_memory(ioc, - ioc->facts.FWImageSize, &num_frags, &alloc_sz); + ioc->cached_fw = (fw_image_t **) mpt_alloc_fw_memory(ioc, + ioc->facts.FWImageSize, &num_frags, &alloc_sz); if (ioc->cached_fw == NULL) { /* Major Failure. @@ -2785,8 +2821,8 @@ sgeoffset += sizeof(u32) + sizeof(dma_addr_t); } - mpt_add_sge(&request[sgeoffset], - MPT_SGE_FLAGS_SSIMPLE_READ |(u32) ioc->cached_fw[ii]->size, + mpt_add_sge(&request[sgeoffset], + MPT_SGE_FLAGS_SSIMPLE_READ |(u32) ioc->cached_fw[ii]->size, ioc->cached_fw[ii]->fw_dma); sgeoffset += sizeof(u32) + sizeof(dma_addr_t); @@ -3133,8 +3169,8 @@ * 0 - no reset due to History bit, READY * -1 - no reset due to History bit but not READY * OR reset but failed to come READY - * -2 - no reset, could not enter DIAG mode - * -3 - reset but bad FW bit + * -2 - no reset, could not enter DIAG mode + * -3 - reset but bad FW bit */ static int KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) @@ -3277,7 +3313,7 @@ /* * Disable the ARM (Bug fix) - * + * */ CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM); mdelay (1); @@ -3326,7 +3362,7 @@ #ifdef MPT_DEBUG if (ioc->alt_ioc) diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); - dprintk((MYIOC_s_INFO_FMT + dprintk((MYIOC_s_INFO_FMT "DbG2b: diag0=%08x, diag1=%08x\n", ioc->name, diag0val, diag1val)); #endif @@ -3343,18 +3379,18 @@ } } if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) { - printk(KERN_WARNING MYNAM + printk(KERN_WARNING MYNAM ": firmware downloadboot failure (%d)!\n", count); } } else { /* Wait for FW to reload and for board * to go to the READY state. - * Maximum wait is 30 seconds. + * Maximum wait is 60 seconds. * If fail, no error will check again * with calling program. */ - for (count = 0; count < 30; count ++) { + for (count = 0; count < 60; count ++) { doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); doorbell &= MPI_IOC_STATE_MASK; @@ -3472,15 +3508,13 @@ dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n", ioc->name, reset_type)); CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<chip->IntStatus, 0); - if (!failcnt && (t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0) + if (!failcnt && (t = WaitForDoorbellAck(ioc, 4, sleepFlag)) < 0) failcnt++; if (!failcnt) { @@ -3774,7 +3808,7 @@ (req_as_bytes[(ii*4) + 3] << 24)); CHIPREG_WRITE32(&ioc->chip->Doorbell, word); - if ((t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0) + if ((t = WaitForDoorbellAck(ioc, 4, sleepFlag)) < 0) failcnt++; } @@ -3818,10 +3852,12 @@ static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) { - int cntdn = HZ * howlong; + int cntdn; int count = 0; u32 intstat; + cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; + if (sleepFlag == CAN_SLEEP) { while (--cntdn) { intstat = CHIPREG_READ32(&ioc->chip->IntStatus); @@ -3832,7 +3868,6 @@ count++; } } else { - cntdn *= 10; /* convert to msec */ while (--cntdn) { intstat = CHIPREG_READ32(&ioc->chip->IntStatus); if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) @@ -3840,7 +3875,6 @@ mdelay (1); count++; } - count /= 10; } if (cntdn) { @@ -3869,10 +3903,11 @@ static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) { - int cntdn = HZ * howlong; + int cntdn; int count = 0; u32 intstat; + cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; if (sleepFlag == CAN_SLEEP) { while (--cntdn) { intstat = CHIPREG_READ32(&ioc->chip->IntStatus); @@ -3883,7 +3918,6 @@ count++; } } else { - cntdn *= 10; /* convert to msec */ while (--cntdn) { intstat = CHIPREG_READ32(&ioc->chip->IntStatus); if (intstat & MPI_HIS_DOORBELL_INTERRUPT) @@ -3891,7 +3925,6 @@ mdelay(1); count++; } - count /= 10; } if (cntdn) { @@ -4275,7 +4308,7 @@ int ii; int data, rc = 0; - /* Allocate memory + /* Allocate memory */ if (!ioc->spi_data.nvram) { int sz; @@ -4454,12 +4487,17 @@ ioc->spi_data.sdp0version = cfg.hdr->PageVersion; ioc->spi_data.sdp0length = cfg.hdr->PageLength; + dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n", + ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length)); + + dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n", + ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length)); return 0; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes + * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes * @ioc: Pointer to a Adapter Strucutre * @portnum: IOC port number * @@ -4802,7 +4840,7 @@ */ in_isr = in_interrupt(); if (in_isr) { - dprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n", + dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n", ioc->name)); return -EPERM; } @@ -4810,7 +4848,7 @@ /* Get and Populate a free Frame */ if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) { - dprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n", + dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n", ioc->name)); return -EAGAIN; } @@ -4843,7 +4881,7 @@ mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); - dprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n", + dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n", ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); /* Append pCfg pointer to end of mf @@ -4890,7 +4928,7 @@ { MPT_ADAPTER *ioc = (MPT_ADAPTER *) data; - dprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name)); + dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name)); /* Perform a FW reload */ if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) @@ -4900,7 +4938,7 @@ * Hard reset clean-up will wake up * process and free all resources. */ - dprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name)); + dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name)); return; } @@ -4921,9 +4959,12 @@ dprintk((KERN_WARNING MYNAM ": IOC %s_reset routed to MPT base driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); - if (reset_phase == MPT_IOC_PRE_RESET) { + if (reset_phase == MPT_IOC_SETUP_RESET) { + ; + } else if (reset_phase == MPT_IOC_PRE_RESET) { /* If the internal config Q is not empty - * delete timer. MF resources will be freed when * the FIFO's are primed. @@ -4941,10 +4982,9 @@ } else { CONFIGPARMS *pNext; - /* Search the configQ for internal commands. + /* Search the configQ for internal commands. * Flush the Q, and wake up all suspended threads. */ -#if 1 spin_lock_irqsave(&ioc->FreeQlock, flags); if (! Q_IS_EMPTY(&ioc->configQ)){ pCfg = (CONFIGPARMS *)ioc->configQ.head; @@ -4961,23 +5001,6 @@ } while (pCfg != (CONFIGPARMS *)&ioc->configQ); } spin_unlock_irqrestore(&ioc->FreeQlock, flags); -#else - while (1) { - spin_lock_irqsave(&ioc->FreeQlock, flags); - if (! Q_IS_EMPTY(&ioc->configQ)){ - spin_unlock_irqrestore(&ioc->FreeQlock, flags); - break; - } - pCfg = (CONFIGPARMS *)ioc->configQ.head; - - Q_DEL_ITEM(&pCfg->linkage); - spin_unlock_irqrestore(&ioc->FreeQlock, flags); - - pCfg->status = MPT_CONFIG_ERROR; - pCfg->wait_done = 1; - wake_up(&mpt_waitq); - } -#endif } return 1; /* currently means nothing really */ @@ -5425,6 +5448,29 @@ /* FIXME: If do_ioc_recovery fails, repeat.... */ + + /* The SCSI driver needs to adjust timeouts on all current + * commands prior to the diagnostic reset being issued. + * Prevents timeouts occuring during a diagnostic reset...very bad. + * For all other protocol drivers, this is a no-op. + */ + { + int ii; + int r = 0; + + for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { + if (MptResetHandlers[ii]) { + dprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n", + ioc->name, ii)); + r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET); + if (ioc->alt_ioc) { + dprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n", + ioc->name, ioc->alt_ioc->name, ii)); + r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET); + } + } + } + } if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) { printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n", @@ -5836,7 +5882,7 @@ isense_idx = last_drv_idx; r = 1; } - MOD_INC_USE_COUNT; + mpt_inc_use_count(); return r; } @@ -5855,7 +5901,7 @@ mpt_ScsiOpcodesPtr = NULL; printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n"); isense_idx = -1; - MOD_DEC_USE_COUNT; + mpt_dec_use_count(); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff -urN linux-2.4.21/drivers/message/fusion/mptbase.h linux-2.4.22/drivers/message/fusion/mptbase.h --- linux-2.4.21/drivers/message/fusion/mptbase.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/mptbase.h 2003-08-25 04:44:42.000000000 -0700 @@ -11,9 +11,9 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:lstephens@lsil.com) * - * $Id: mptbase.h,v 1.144 2003/01/28 21:31:56 pdelaney Exp $ + * $Id: mptbase.h,v 1.149 2003/05/07 14:08:31 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -80,8 +80,8 @@ #define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "2.05.00+" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.00+" +#define MPT_LINUX_VERSION_COMMON "2.05.05+" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.05+" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -93,7 +93,7 @@ */ #define MPT_MAX_ADAPTERS 18 #define MPT_MAX_PROTOCOL_DRIVERS 16 -#define MPT_MAX_BUS 1 +#define MPT_MAX_BUS 1 /* Do not change */ #define MPT_MAX_FC_DEVICES 255 #define MPT_MAX_SCSI_DEVICES 16 #define MPT_LAST_LUN 31 @@ -383,12 +383,9 @@ u8 maxWidth; /* 0 if narrow, 1 if wide*/ u8 negoFlags; /* bit field, 0 if WDTR/SDTR/QAS allowed */ u8 raidVolume; /* set, if RAID Volume */ -#ifdef ABORT_FIX - u8 numAborts; -#else - u8 rsvd; -#endif - u16 rsvd1raid; + u8 type; /* byte 0 of Inquiry data */ + u8 cflags; /* controller flags */ + u8 rsvd1raid; int npaths; u16 fc_phys_lun; u16 fc_xlat_lun; @@ -400,11 +397,8 @@ ScsiCmndTracker WaitQ; ScsiCmndTracker SentQ; ScsiCmndTracker DoneQ; + u32 num_luns; //--- LUN split here? -#ifdef MPT_SAVE_AUTOSENSE - u8 sense[SCSI_STD_SENSE_BYTES]; /* 18 */ - u8 rsvd2[2]; /* alignment */ -#endif u32 luns; /* Max LUNs is 32 */ u8 inq_data[SCSI_STD_INQUIRY_BYTES]; /* 36 */ u8 pad0[4]; @@ -428,13 +422,15 @@ * Fibre Channel (SCSI) target device and associated defines... */ #define MPT_TARGET_DEFAULT_DV_STATUS 0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,55) +#define MPT_TARGET_FLAGS_CONFIGURED 0x02 +#define MPT_TARGET_FLAGS_Q_YES 0x08 +#else #define MPT_TARGET_FLAGS_VALID_NEGO 0x01 #define MPT_TARGET_FLAGS_VALID_INQUIRY 0x02 -#ifdef MPT_SAVE_AUTOSENSE -#define MPT_TARGET_FLAGS_VALID_SENSE 0x04 -#endif #define MPT_TARGET_FLAGS_Q_YES 0x08 #define MPT_TARGET_FLAGS_VALID_56 0x10 +#endif #define MPT_TARGET_NO_NEGO_WIDE 0x01 #define MPT_TARGET_NO_NEGO_SYNC 0x02 @@ -603,7 +599,7 @@ dma_addr_t sense_buf_pool_dma; u32 sense_buf_low_dma; int mtrr_reg; - void *pcidev; /* struct pci_dev pointer */ + struct pci_dev *pcidev; /* struct pci_dev pointer */ u8 *memmap; /* mmap address */ struct Scsi_Host *sh; /* Scsi Host pointer */ ScsiCfgData spi_data; /* Scsi config. data */ @@ -616,6 +612,12 @@ int eventTypes; /* Event logging parameters */ int eventContext; /* Next event context */ int eventLogSize; /* Max number of cached events */ +#ifdef MPTSCSIH_DBG_TIMEOUT + int timeout_hard; + int timeout_delta; + int timeout_cnt; + int timeout_maxcnt; +#endif struct _mpt_ioctl_events *events; /* pointer to event log */ fw_image_t **cached_fw; /* Pointer to FW SG List */ Q_TRACKER configQ; /* linked list of config. requests */ @@ -656,6 +658,7 @@ /* reset_phase defs */ #define MPT_IOC_PRE_RESET 0 #define MPT_IOC_POST_RESET 1 +#define MPT_IOC_SETUP_RESET 2 /* * Invent MPT host event (super-set of MPI Events) @@ -758,6 +761,19 @@ #define nehprintk(x) #endif +#if defined(MPT_DEBUG_CONFIG) || defined(MPT_DEBUG) +#define dcprintk(x) printk x +#else +#define dcprintk(x) +#endif + +#if defined(MPT_DEBUG_SCSI) || defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME) +#define dsprintk(x) printk x +#else +#define dsprintk(x) +#endif + + #define MPT_INDEX_2_MFPTR(ioc,idx) \ (MPT_FRAME_HDR*)( (u8*)(ioc)->req_frames + (ioc)->req_sz * (idx) ) diff -urN linux-2.4.21/drivers/message/fusion/mptctl.c linux-2.4.22/drivers/message/fusion/mptctl.c --- linux-2.4.21/drivers/message/fusion/mptctl.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/mptctl.c 2003-08-25 04:44:42.000000000 -0700 @@ -32,9 +32,9 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston, Noah Romer * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:lstephens@lsil.com) * - * $Id: mptctl.c,v 1.63 2002/12/03 21:26:33 pdelaney Exp $ + * $Id: mptctl.c,v 1.66 2003/05/07 14:08:32 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -102,7 +102,9 @@ #define my_VERSION MPT_LINUX_VERSION_COMMON #define MYNAM "mptctl" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62) EXPORT_NO_SYMBOLS; +#endif MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); @@ -136,7 +138,7 @@ static int mptctl_replace_fw (unsigned long arg); static int mptctl_do_reset(unsigned long arg); -static int mptctl_hp_hostinfo(unsigned long arg); +static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd); static int mptctl_hp_targetinfo(unsigned long arg); /* @@ -267,8 +269,12 @@ */ iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK; if (iocStatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED) { - if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) - mod_timer(&ioc->ioctl->timer, jiffies + HZ); + if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) { + ioc->ioctl->reset &= ~MPTCTL_RESET_OK; + del_timer (&ioc->ioctl->timer); + ioc->ioctl->timer.expires = jiffies + HZ; + add_timer(&ioc->ioctl->timer); + } } ioc->ioctl->tmPtr = NULL; @@ -334,6 +340,7 @@ */ ioc->ioctl->wait_done = 1; wake_up (&mptctl_wait); + } else if (reply && cmd == MPI_FUNCTION_FW_DOWNLOAD) { /* Two paths to FW DOWNLOAD! */ // NOTE: Expects/requires non-Turbo reply! @@ -518,9 +525,12 @@ { MPT_IOCTL *ioctl = ioc->ioctl; dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); - if (reset_phase == MPT_IOC_PRE_RESET){ + if (reset_phase == MPT_IOC_SETUP_RESET){ + ; + } else if (reset_phase == MPT_IOC_PRE_RESET){ /* Someone has called the reset handler to * do a hard reset. No more replies from the FW. @@ -537,13 +547,15 @@ } } else { + ioctl->tmPtr = NULL; + /* Set the status and continue IOCTL * processing. All memory will be free'd * by originating thread after wake_up is * called. */ if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){ - ioctl->status = MPT_IOCTL_STATUS_DID_IOCRESET; + ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET; /* Wake up the calling process */ @@ -625,7 +637,11 @@ return -ENODEV; } - + if (!iocp->active) { + printk(KERN_ERR "%s::mptctl_ioctl() @%d - Controller disabled.\n", + __FILE__, __LINE__); + return -EFAULT; + } /* Handle those commands that are just returning * information stored in the driver. @@ -656,25 +672,19 @@ dctlprintk((MYIOC_s_INFO_FMT ": mptctl_ioctl()\n", iocp->name)); - switch(cmd) { - case MPTFWDOWNLOAD: + if (cmd == MPTFWDOWNLOAD) ret = mptctl_fw_download(arg); - break; - case MPTCOMMAND: + else if (cmd == MPTCOMMAND) ret = mptctl_mpt_command(arg); - break; - case MPTHARDRESET: + else if (cmd == MPTHARDRESET) ret = mptctl_do_reset(arg); - break; - case HP_GETHOSTINFO: - ret = mptctl_hp_hostinfo(arg); - break; - case HP_GETTARGETINFO: + else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK)) + ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd)); + else if (cmd == HP_GETTARGETINFO) ret = mptctl_hp_targetinfo(arg); - break; - default: + else ret = -EINVAL; - } + up(&mptctl_syscall_sem_ioc[iocp->id]); @@ -702,7 +712,7 @@ return -ENODEV; /* (-6) No such device or address */ } - if (mpt_HardResetHandler(iocp, NO_SLEEP) != 0) { + if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) { printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n", __FILE__, __LINE__); return -1; @@ -871,7 +881,7 @@ * 96 8 * 64 4 */ - maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) - sizeof(FWDownloadTCSGE_t)) + maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) - sizeof(FWDownloadTCSGE_t)) / (sizeof(dma_addr_t) + sizeof(u32)); if (numfrags > maxfrags) { ret = -EMLINK; @@ -1225,10 +1235,16 @@ u8 revision; dctlprintk((": mptctl_getiocinfo called.\n")); - if (data_size == sizeof(struct mpt_ioctl_iocinfo)) - cim_rev = 1; - else if (data_size == (sizeof(struct mpt_ioctl_iocinfo) - sizeof(struct mpt_ioctl_pci_info))) + /* Add of PCI INFO results in unaligned access for + * IA64 and Sparc. Reset long to int. Return no PCI + * data for obsolete format. + */ + if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0)) cim_rev = 0; + else if (data_size == sizeof(struct mpt_ioctl_iocinfo)) + cim_rev = 1; + else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12)) + cim_rev = 0; /* obsolete */ else return -EFAULT; @@ -1412,7 +1428,7 @@ /* Get number of devices */ - if ( (sh = ioc->sh) != NULL) { + if ((sh = ioc->sh) != NULL) { max_id = sh->max_id - 1; hd = (MPT_SCSI_HOST *) sh->hostdata; @@ -1435,9 +1451,8 @@ pdata++; - if (maxWordsLeft <= 0) { + if (maxWordsLeft <= 0) break; - } } } } @@ -1710,7 +1725,7 @@ /* Allocate memory for the new FW image */ newFwSize = karg.newImageSize; - fwmem = mpt_alloc_fw_memory(ioc, newFwSize, &num_frags, &alloc_sz); + fwmem = mpt_alloc_fw_memory(ioc, newFwSize, &num_frags, &alloc_sz); if (fwmem == NULL) return -ENOMEM; @@ -1730,7 +1745,7 @@ } - /* Free the old FW image + /* Free the old FW image */ if (ioc->cached_fw) { mpt_free_fw_memory(ioc, 0); @@ -1812,22 +1827,20 @@ MPT_FRAME_HDR *mf = NULL; MPIHeader_t *hdr; char *psge; - MptSge_t *this_sge = NULL; - MptSge_t *sglbuf = NULL; struct buflist bufIn; /* data In buffer */ struct buflist bufOut; /* data Out buffer */ - dma_addr_t sglbuf_dma; - dma_addr_t dma_addr; + dma_addr_t dma_addr_in; + dma_addr_t dma_addr_out; int dir; /* PCI data direction */ int sgSize = 0; /* Num SG elements */ - int this_alloc; - int iocnum, flagsLength; - int sz, rc = 0; - int msgContext; + int iocnum, flagsLength; + int sz, rc = 0; + int msgContext; int tm_flags_set = 0; u16 req_idx; dctlprintk(("mptctl_do_mpt_command called.\n")); + bufIn.kptr = bufOut.kptr = NULL; if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { @@ -1854,7 +1867,7 @@ if (karg.dataOutSize > 0) sz += sizeof(dma_addr_t) + sizeof(u32); - if ( sz > ioc->req_sz) { + if (sz > ioc->req_sz) { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " "Request frame too large (%d) maximum (%d)\n", __FILE__, __LINE__, sz, ioc->req_sz); @@ -1897,12 +1910,16 @@ switch (hdr->Function) { case MPI_FUNCTION_IOC_FACTS: case MPI_FUNCTION_PORT_FACTS: + karg.dataOutSize = karg.dataInSize = 0; + break; + case MPI_FUNCTION_CONFIG: case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND: case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND: case MPI_FUNCTION_FW_UPLOAD: case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: case MPI_FUNCTION_FW_DOWNLOAD: + case MPI_FUNCTION_FC_PRIMITIVE_SEND: break; case MPI_FUNCTION_SCSI_IO_REQUEST: @@ -1938,7 +1955,7 @@ cpu_to_le32(ioc->sense_buf_low_dma + (req_idx * MPT_SENSE_BUFFER_ALLOC)); - if ( (hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { + if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { if (hd->Targets) pTarget = hd->Targets[target]; } @@ -1949,11 +1966,10 @@ /* Have the IOCTL driver set the direction based * on the dataOutSize (ordering issue with Sparc). */ - if (karg.dataOutSize > 0 ) { + if (karg.dataOutSize > 0) { scsidir = MPI_SCSIIO_CONTROL_WRITE; dataSize = karg.dataOutSize; - } - else { + } else { scsidir = MPI_SCSIIO_CONTROL_READ; dataSize = karg.dataInSize; } @@ -2006,11 +2022,10 @@ /* Have the IOCTL driver set the direction based * on the dataOutSize (ordering issue with Sparc). */ - if (karg.dataOutSize > 0 ) { + if (karg.dataOutSize > 0) { scsidir = MPI_SCSIIO_CONTROL_WRITE; dataSize = karg.dataOutSize; - } - else { + } else { scsidir = MPI_SCSIIO_CONTROL_READ; dataSize = karg.dataInSize; } @@ -2030,7 +2045,7 @@ break; case MPI_FUNCTION_SCSI_TASK_MGMT: - { + { MPT_SCSI_HOST *hd = NULL; if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " @@ -2038,7 +2053,7 @@ __FILE__, __LINE__); rc = -EFAULT; goto done_free_mem; - } else if (mptctl_set_tm_flags(hd) != 0) { + } else if (mptctl_set_tm_flags(hd) != 0) { rc = -EPERM; goto done_free_mem; } @@ -2063,7 +2078,7 @@ } if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) || - (pInit->MaxBuses != ioc->facts.MaxBuses) || + (pInit->MaxBuses != ioc->facts.MaxBuses) || (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) || (pInit->HostMfaHighAddr != high_addr) || (pInit->SenseBufferHighAddr != sense_high)) { @@ -2095,7 +2110,6 @@ MPI_FUNCTION_FC_LINK_SRVC_BUF_POST MPI_FUNCTION_FC_LINK_SRVC_RSP MPI_FUNCTION_FC_ABORT - MPI_FUNCTION_FC_PRIMITIVE_SEND MPI_FUNCTION_LAN_SEND MPI_FUNCTION_LAN_RECEIVE MPI_FUNCTION_LAN_RESET @@ -2113,7 +2127,7 @@ * preceede the data in (read) SGE. psgList is used to free the * allocated memory. */ - psge = (char *) ( ((int *) mf) + karg.dataSgeOffset); + psge = (char *) (((int *) mf) + karg.dataSgeOffset); flagsLength = 0; /* bufIn and bufOut are used for user to kernel space transfers @@ -2121,30 +2135,18 @@ bufIn.kptr = bufOut.kptr = NULL; bufIn.len = bufOut.len = 0; - if (karg.dataOutSize > 0 ) + if (karg.dataOutSize > 0) sgSize ++; - if (karg.dataInSize > 0 ) + if (karg.dataInSize > 0) sgSize ++; if (sgSize > 0) { - /* Allocate memory for the SGL. - * Used to free kernel memory once - * the MF is freed. - */ - sglbuf = pci_alloc_consistent (ioc->pcidev, - sgSize*sizeof(MptSge_t), &sglbuf_dma); - if (sglbuf == NULL) { - rc = -ENOMEM; - goto done_free_mem; - } - this_sge = sglbuf; - /* Set up the dataOut memory allocation */ if (karg.dataOutSize > 0) { dir = PCI_DMA_TODEVICE; - if (karg.dataInSize > 0 ) { + if (karg.dataInSize > 0) { flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_DIRECTION | mpt_addr_size() ) @@ -2153,22 +2155,25 @@ flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE; } flagsLength |= karg.dataOutSize; - - this_alloc = karg.dataOutSize; - bufOut.len = this_alloc; + bufOut.len = karg.dataOutSize; bufOut.kptr = pci_alloc_consistent( - ioc->pcidev, this_alloc, &dma_addr); + ioc->pcidev, bufOut.len, &dma_addr_out); if (bufOut.kptr == NULL) { rc = -ENOMEM; goto done_free_mem; } else { + /* Set up this SGE. + * Copy to MF and to sglbuf + */ + mpt_add_sge(psge, flagsLength, dma_addr_out); + psge += (sizeof(u32) + sizeof(dma_addr_t)); + /* Copy user data to kernel space. */ if (copy_from_user(bufOut.kptr, karg.dataOutBufPtr, bufOut.len)) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - Unable " "to read user data " @@ -2177,16 +2182,6 @@ rc = -EFAULT; goto done_free_mem; } - - /* Set up this SGE. - * Copy to MF and to sglbuf - */ - mpt_add_sge(psge, flagsLength, dma_addr); - psge += (sizeof(u32) + sizeof(dma_addr_t)); - - this_sge->FlagsLength = flagsLength; - this_sge->Address = dma_addr; - this_sge++; } } @@ -2195,10 +2190,10 @@ flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; flagsLength |= karg.dataInSize; - this_alloc = karg.dataInSize; - bufIn.len = this_alloc; + bufIn.len = karg.dataInSize; bufIn.kptr = pci_alloc_consistent(ioc->pcidev, - this_alloc, &dma_addr); + bufIn.len, &dma_addr_in); + if (bufIn.kptr == NULL) { rc = -ENOMEM; goto done_free_mem; @@ -2206,11 +2201,7 @@ /* Set up this SGE * Copy to MF and to sglbuf */ - mpt_add_sge(psge, flagsLength, dma_addr); - - this_sge->FlagsLength = flagsLength; - this_sge->Address = dma_addr; - this_sge++; + mpt_add_sge(psge, flagsLength, dma_addr_in); } } } else { @@ -2234,7 +2225,7 @@ if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) { rc = mpt_send_handshake_request(mptctl_id, ioc->id, - sizeof(SCSITaskMgmt_t), (u32*)mf, NO_SLEEP); + sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP); if (rc == 0) { wait_event(mptctl_wait, ioc->ioctl->wait_done); } else { @@ -2242,45 +2233,41 @@ tm_flags_set= 0; del_timer(&ioc->ioctl->timer); ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE; - ioc->ioctl->status = MPT_IOCTL_STATUS_TM_FAILED; + ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED; + mpt_free_msg_frame(mptctl_id, ioc->id, mf); } } else { mpt_put_msg_frame(mptctl_id, ioc->id, mf); wait_event(mptctl_wait, ioc->ioctl->wait_done); } - /* The command is complete. * Return data to the user. + mf = NULL; + + /* MF Cleanup: + * If command failed and failure triggered a diagnostic reset + * OR a diagnostic reset happens during command processing, + * no data, messaging queues are reset (mf cannot be accessed), + * and status is DID_IOCRESET * - * If command completed, mf has been freed so cannot - * use this memory. + * If a user-requested bus reset fails to be handshaked, then + * mf is returned to free queue and status is TM_FAILED. * - * If timeout, a recovery mechanism has been called. - * Need to free the mf. + * Otherise, the command completed and the mf was freed + # by ISR (mf cannot be touched). */ if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) { - - /* A timeout - there is no data to return to the - * the user other than an error. - * The timer callback deleted the + /* The timer callback deleted the * timer and reset the adapter queues. */ printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - " "Timeout Occurred on IOCTL! Reset IOC.\n", __FILE__, __LINE__); tm_flags_set= 0; rc = -ETIME; - - /* Free memory and return to the calling function - */ - goto done_free_mem; } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TM_FAILED) { - /* User TM request failed! + /* User TM request failed! mf has not been freed. */ rc = -ENODATA; } else { - /* Callback freed request frame. - */ - mf = NULL; - /* If a valid reply frame, copy to the user. * Offset 2: reply length in U32's */ @@ -2338,42 +2325,31 @@ } done_free_mem: - /* Clear status bits. - */ - ioc->ioctl->status = 0; + /* Clear all status bits except TMTIMER_ACTIVE, this bit is cleared + * upon completion of the TM command. + * ioc->ioctl->status = 0; + */ + ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_TIMER_ACTIVE | MPT_IOCTL_STATUS_TM_FAILED | + MPT_IOCTL_STATUS_COMMAND_GOOD | MPT_IOCTL_STATUS_SENSE_VALID | + MPT_IOCTL_STATUS_RF_VALID | MPT_IOCTL_STATUS_DID_IOCRESET); if (tm_flags_set) mptctl_free_tm_flags(ioc); - if (sglbuf) { - this_sge = sglbuf; - - /* Free the allocated memory. - */ - if (bufOut.kptr != NULL ) { - dma_addr = this_sge->Address; - this_sge++; /* go to next structure */ - this_alloc = bufOut.len; - pci_free_consistent(ioc->pcidev, - this_alloc, (void *) bufOut.kptr, dma_addr); - } - - if (bufIn.kptr != NULL ) { - dma_addr = this_sge->Address; - this_alloc = bufIn.len; - - pci_free_consistent(ioc->pcidev, - this_alloc, (void *) bufIn.kptr, dma_addr); - } - - this_alloc = sgSize * sizeof(MptSge_t); + /* Free the allocated memory. + */ + if (bufOut.kptr != NULL) { pci_free_consistent(ioc->pcidev, - this_alloc, (void *) sglbuf, sglbuf_dma); + bufOut.len, (void *) bufOut.kptr, dma_addr_out); + } + if (bufIn.kptr != NULL) { + pci_free_consistent(ioc->pcidev, + bufIn.len, (void *) bufIn.kptr, dma_addr_in); } - /* mf will be null if allocation failed OR - * if command completed OK (callback freed) + /* mf is null if command issued successfully + * otherwise, failure occured after mf acquired. */ if (mf) mpt_free_msg_frame(mptctl_id, ioc->id, mf); @@ -2393,7 +2369,7 @@ * -ENOMEM if memory allocation error */ static int -mptctl_hp_hostinfo(unsigned long arg) +mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) { hp_host_info_t *uarg = (hp_host_info_t *) arg; MPT_ADAPTER *ioc; @@ -2404,9 +2380,18 @@ CONFIGPARMS cfg; ConfigPageHeader_t hdr; int iocnum; - int rc; + int rc, cim_rev; dctlprintk((": mptctl_hp_hostinfo called.\n")); + /* Reset long to int. Should affect IA64 and SPARC only + */ + if (data_size == sizeof(hp_host_info_t)) + cim_rev = 1; + else if (data_size == sizeof(hp_host_info_rev0_t)) + cim_rev = 0; /* obsolete */ + else + return -EFAULT; + if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) { printk(KERN_ERR "%s@%d::mptctl_hp_host_info - " "Unable to read in hp_host_info struct @ %p\n", @@ -2436,7 +2421,7 @@ karg.bus = pdev->bus->number; /* Save the SCSI host no. if - * SCSI driver loaded + * SCSI driver loaded */ if (ioc->sh != NULL) karg.host_no = ioc->sh->host_no; @@ -2524,7 +2509,7 @@ if (ioc->sh != NULL) { MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; - if (hd) { + if (hd && (cim_rev == 1)) { karg.hard_resets = hd->hard_resets; karg.soft_resets = hd->soft_resets; karg.timeouts = hd->timeouts; @@ -2618,7 +2603,7 @@ if ((rc = mpt_config(ioc, &cfg)) == 0) { np = le32_to_cpu(pg0_alloc->NegotiatedParameters); - karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ? + karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ? HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8; if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) { @@ -2697,7 +2682,7 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51) -#define owner_THIS_MODULE owner: THIS_MODULE, +#define owner_THIS_MODULE .owner = THIS_MODULE, #else #define owner_THIS_MODULE #endif @@ -2883,6 +2868,8 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ err = register_ioctl32_conversion(MPTIOCINFO, NULL); if (++where && err) goto out_fail; + err = register_ioctl32_conversion(MPTIOCINFO1, NULL); + if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTTARGETINFO, NULL); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTTEST, NULL); @@ -2943,6 +2930,7 @@ printk(KERN_ERR MYNAM ": ERROR: Failed to register ioctl32_conversion!" " (%d:err=%d)\n", where, err); unregister_ioctl32_conversion(MPTIOCINFO); + unregister_ioctl32_conversion(MPTIOCINFO1); unregister_ioctl32_conversion(MPTTARGETINFO); unregister_ioctl32_conversion(MPTTEST); unregister_ioctl32_conversion(MPTEVENTQUERY); diff -urN linux-2.4.21/drivers/message/fusion/mptctl.h linux-2.4.22/drivers/message/fusion/mptctl.h --- linux-2.4.21/drivers/message/fusion/mptctl.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/mptctl.h 2003-08-25 04:44:42.000000000 -0700 @@ -18,9 +18,9 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:lstephens@lsil.com) * - * $Id: mptctl.h,v 1.13 2002/12/03 21:26:33 pdelaney Exp $ + * $Id: mptctl.h,v 1.14 2003/03/18 22:49:51 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -90,6 +90,7 @@ #endif /*}*/ #define MPTIOCINFO _IOWR(MPT_MAGIC_NUMBER,17,struct mpt_ioctl_iocinfo) +#define MPTIOCINFO1 _IOWR(MPT_MAGIC_NUMBER,17,struct mpt_ioctl_iocinfo_rev0) #define MPTTARGETINFO _IOWR(MPT_MAGIC_NUMBER,18,struct mpt_ioctl_targetinfo) #define MPTTEST _IOWR(MPT_MAGIC_NUMBER,19,struct mpt_ioctl_test) #define MPTEVENTQUERY _IOWR(MPT_MAGIC_NUMBER,21,struct mpt_ioctl_eventquery) @@ -99,7 +100,7 @@ #define MPTFWREPLACE _IOWR(MPT_MAGIC_NUMBER,25,struct mpt_ioctl_replace_fw) /* - * SPARC PLATFORM REMARK: + * SPARC PLATFORM REMARKS: * IOCTL data structures that contain pointers * will have different sizes in the driver and applications * (as the app. will not use 8-byte pointers). @@ -107,6 +108,8 @@ * The driver will convert data from * mpt_fw_xfer32 (mpt_ioctl_command32) to mpt_fw_xfer (mpt_ioctl_command) * internally. + * + * If data structures change size, must handle as in IOCGETINFO. */ struct mpt_fw_xfer { unsigned int iocnum; /* IOC unit number */ @@ -154,11 +157,11 @@ struct mpt_ioctl_pci_info { union { struct { - unsigned long deviceNumber : 5; - unsigned long functionNumber : 3; - unsigned long busNumber : 24; + unsigned int deviceNumber : 5; + unsigned int functionNumber : 3; + unsigned int busNumber : 24; } bits; - unsigned long asUlong; + unsigned int asUlong; } u; }; @@ -189,6 +192,27 @@ struct mpt_ioctl_pci_info pciInfo; /* Added Rev 1 */ }; +/* Original structure, must always accept these + * IOCTLs. 4 byte pads can occur based on arch with + * above structure. Wish to re-align, but cannot. + */ +struct mpt_ioctl_iocinfo_rev0 { + mpt_ioctl_header hdr; + int adapterType; /* SCSI or FCP */ + int port; /* port number */ + int pciId; /* PCI Id. */ + int hwRev; /* hardware revision */ + int subSystemDevice; /* PCI subsystem Device ID */ + int subSystemVendor; /* PCI subsystem Vendor ID */ + int numDevices; /* number of devices */ + int FWVersion; /* FW Version (integer) */ + int BIOSVersion; /* BIOS Version (integer) */ + char driverVersion[MPT_IOCTL_VERSION_LENGTH]; /* Driver Version (string) */ + char busChangeEvent; + char hostId; + char rsvd[2]; +}; + /* * Device Information Page * Report the number of, and ids of, all targets @@ -318,6 +342,7 @@ #define CPQFCTS_IOC_MAGIC 'Z' #define HP_IOC_MAGIC 'Z' #define HP_GETHOSTINFO _IOR(HP_IOC_MAGIC, 20, hp_host_info_t) +#define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t) #define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t) /* All HP IOCTLs must include this header @@ -330,7 +355,7 @@ unsigned int lun; } hp_header_t; -/* +/* * Header: * iocnum required (input) * host ignored @@ -353,12 +378,35 @@ u32 bus_phys_width; u32 base_io_addr; u32 rsvd; + unsigned int hard_resets; /* driver initiated resets */ + unsigned int soft_resets; /* ioc, external resets */ + unsigned int timeouts; /* num timeouts */ +} hp_host_info_t; + +/* replace ulongs with uints, need to preserve backwards + * compatibility. + */ +typedef struct _hp_host_info_rev0 { + hp_header_t hdr; + u16 vendor; + u16 device; + u16 subsystem_vendor; + u16 subsystem_id; + u8 devfn; + u8 bus; + ushort host_no; /* SCSI Host number, if scsi driver not loaded*/ + u8 fw_version[16]; /* string */ + u8 serial_number[24]; /* string */ + u32 ioc_status; + u32 bus_phys_width; + u32 base_io_addr; + u32 rsvd; unsigned long hard_resets; /* driver initiated resets */ unsigned long soft_resets; /* ioc, external resets */ unsigned long timeouts; /* num timeouts */ -} hp_host_info_t; +} hp_host_info_rev0_t; -/* +/* * Header: * iocnum required (input) * host required diff -urN linux-2.4.21/drivers/message/fusion/mptlan.c linux-2.4.22/drivers/message/fusion/mptlan.c --- linux-2.4.21/drivers/message/fusion/mptlan.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/mptlan.c 2003-08-25 04:44:42.000000000 -0700 @@ -26,7 +26,7 @@ * Copyright (c) 2000-2002 LSI Logic Corporation * Originally By: Noah Romer * - * $Id: mptlan.c,v 1.53 2002/10/17 20:15:58 pdelaney Exp $ + * $Id: mptlan.c,v 1.55 2003/05/07 14:08:32 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -154,7 +154,7 @@ static int mpt_lan_reset(struct net_device *dev); static int mpt_lan_close(struct net_device *dev); static void mpt_lan_post_receive_buckets(void *dev_id); -static void mpt_lan_wake_post_buckets_task(struct net_device *dev, +static void mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority); static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg); static int mpt_lan_receive_post_reply(struct net_device *dev, @@ -242,7 +242,7 @@ // would Oops because mf has already been set // to NULL. So after return from this func, // mpt_interrupt() will attempt to put (NULL) mf ptr - // item back onto it's adapter FreeQ - Oops!:-( + // item back onto its adapter FreeQ - Oops!:-( // It's Ok, since mpt_lan_send_turbo() *currently* // always returns 0, but..., just in case: @@ -339,12 +339,15 @@ struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); if (priv->mpt_rxfidx == NULL) return (1); - if (reset_phase == MPT_IOC_PRE_RESET) { + if (reset_phase == MPT_IOC_SETUP_RESET) { + ; + } else if (reset_phase == MPT_IOC_PRE_RESET) { int i; unsigned long flags; @@ -868,7 +871,7 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static inline void mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority) -/* +/* * @priority: 0 = put it on the timer queue, 1 = put it on the immediate queue */ { @@ -878,8 +881,6 @@ if (priority) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41) schedule_work(&priv->post_buckets_task); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,40) - schedule_task(&priv->post_buckets_task); #else queue_task(&priv->post_buckets_task, &tq_immediate); mark_bh(IMMEDIATE_BH); @@ -887,8 +888,6 @@ } else { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41) schedule_delayed_work(&priv->post_buckets_task, 1); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,40) - schedule_task(&priv->post_buckets_task); #else queue_task(&priv->post_buckets_task, &tq_timer); #endif @@ -1191,7 +1190,7 @@ remaining, atomic_read(&priv->buckets_out)); if ((remaining < priv->bucketthresh) && - ((atomic_read(&priv->buckets_out) - remaining) > + ((atomic_read(&priv->buckets_out) - remaining) > MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH)) { printk (KERN_WARNING MYNAM " Mismatch between driver's " @@ -1525,7 +1524,7 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -void __init mpt_lan_exit(void) +static void mpt_lan_exit(void) { int i; @@ -1534,10 +1533,11 @@ for (i = 0; mpt_landev[i] != NULL; i++) { struct net_device *dev = mpt_landev[i]; - printk (KERN_INFO MYNAM ": %s/%s: Fusion MPT LAN device unregistered\n", + printk (KERN_INFO ": %s/%s: Fusion MPT LAN device unregistered\n", IOC_AND_NETDEV_NAMES_s_s(dev)); unregister_fcdev(dev); - mpt_landev[i] = (struct net_device *) 0xdeadbeef; /* Debug */ + //mpt_landev[i] = (struct net_device *) 0xdeadbeef; /* Debug */ + mpt_landev[i] = NULL; } if (LanCtx >= 0) { @@ -1550,9 +1550,10 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59) MODULE_PARM(tx_max_out_p, "i"); MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME! +#endif module_init(mpt_lan_init); module_exit(mpt_lan_exit); diff -urN linux-2.4.21/drivers/message/fusion/mptscsih.c linux-2.4.22/drivers/message/fusion/mptscsih.c --- linux-2.4.21/drivers/message/fusion/mptscsih.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/mptscsih.c 2003-08-25 04:44:42.000000000 -0700 @@ -24,9 +24,9 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Original author: Steven J. Ralston * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:lstephens@lsil.com) * - * $Id: mptscsih.c,v 1.106 2003/01/28 21:31:57 pdelaney Exp $ + * $Id: mptscsih.c,v 1.1.2.4 2003/05/07 14:08:34 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -174,17 +174,14 @@ static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx); static void post_pendingQ_commands(MPT_SCSI_HOST *hd); -static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag); -static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag); +static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, int sleepFlag); +static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, int sleepFlag); static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); static VirtDevice *mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen); void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56); -#ifdef MPT_SAVE_AUTOSENSE -static void clear_sense_flag(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq); -#endif static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq); static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id); @@ -200,7 +197,7 @@ static void mptscsih_domainValidation(void *hd); static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); -static int mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int target); +static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); static void mptscsih_fillbuf(char *buffer, int size, int index, int width); #endif @@ -270,6 +267,10 @@ static struct mptscsih_driver_setup driver_setup = MPTSCSIH_DRIVER_SETUP; +#ifdef MPTSCSIH_DBG_TIMEOUT +static Scsi_Cmnd *foo_to[8]; +#endif + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Private inline routines... @@ -743,9 +744,9 @@ atomic_dec(&queue_depth); - /* writeSDP1 will use the ScsiDoneCtx - * There is no processing for the reply. - * Just return to the calling function. + /* Remark: writeSDP1 will use the ScsiDoneCtx + * If a SCSI I/O cmd, device disabled by OS and + * completion done. Cannot touch sc struct. Just free mem. */ if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST) printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n", ioc->name); @@ -763,6 +764,26 @@ pScsiReq = (SCSIIORequest_t *) mf; pScsiReply = (SCSIIOReply_t *) mr; +#ifdef MPTSCSIH_DBG_TIMEOUT + if (ioc->timeout_cnt > 0) { + int ii, left = 0; + + for (ii=0; ii < 8; ii++) { + if (sc == foo_to[ii]) { + printk(MYIOC_s_INFO_FMT "complete (%p, %ld)\n", + ioc->name, sc, jiffies); + foo_to[ii] = NULL; + } + if (foo_to[ii] != NULL) + left++; + } + + if (left == 0) { + ioc->timeout_maxcnt = 0; + ioc->timeout_cnt = 0; + } + } +#endif if (pScsiReply == NULL) { /* special context reply handling */ @@ -774,16 +795,13 @@ dlen = le32_to_cpu(pScsiReq->DataLength); if (dlen >= SCSI_STD_INQUIRY_BYTES) { mptscsih_initTarget(hd, - hd->port, + sc->channel, sc->target, pScsiReq->LUN[1], sc->buffer, dlen); } } -#ifdef MPT_SAVE_AUTOSENSE - clear_sense_flag(hd, pScsiReq); -#endif } else { u32 xfer_cnt; u16 status; @@ -871,9 +889,6 @@ * precedence! */ sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus; -#ifdef MPT_SAVE_AUTOSENSE - clear_sense_flag(hd, pScsiReq); -#endif if (scsi_state == 0) { ; } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { @@ -915,7 +930,7 @@ && xfer_cnt >= SCSI_STD_INQUIRY_BYTES ) { mptscsih_initTarget(hd, - hd->port, + sc->channel, sc->target, pScsiReq->LUN[1], sc->buffer, @@ -926,9 +941,6 @@ case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus; -#ifdef MPT_SAVE_AUTOSENSE - clear_sense_flag(hd, pScsiReq); -#endif if (scsi_state == 0) { ; } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { @@ -999,7 +1011,7 @@ && xfer_cnt >= SCSI_STD_INQUIRY_BYTES ) { mptscsih_initTarget(hd, - hd->port, + sc->channel, sc->target, pScsiReq->LUN[1], sc->buffer, @@ -1238,7 +1250,7 @@ /* Flush the doneQ. */ - dprintk((KERN_INFO MYNAM ": flush_doneQ called\n")); + dtmprintk((KERN_INFO MYNAM ": flush_doneQ called\n")); while (1) { spin_lock_irqsave(&hd->freedoneQlock, flags); if (Q_IS_EMPTY(&hd->doneQ)) { @@ -1305,6 +1317,22 @@ return; } +static void +mptscsih_reset_timeouts (MPT_SCSI_HOST *hd) +{ + Scsi_Cmnd *SCpnt = NULL; + int ii; + int max = hd->ioc->req_depth; + + for (ii= 0; ii < max; ii++) { + if ((SCpnt = hd->ScsiLookup[ii]) != NULL) { + mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60)); + dtmprintk((MYIOC_s_WARN_FMT "resetting SCpnt=%p timeout + 60HZ", + (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt)); + } + } +} + /* * mptscsih_flush_running_cmds - For each command found, search * Scsi_Host instance taskQ and reply to OS. @@ -1320,6 +1348,7 @@ { Scsi_Cmnd *SCpnt = NULL; MPT_FRAME_HDR *mf = NULL; + MPT_DONE_Q *buffer = NULL; int ii; int max = hd->ioc->req_depth; @@ -1333,7 +1362,6 @@ /* Command found. */ - #ifndef MPT_SCSI_USE_NEW_EH /* Search taskQ, if found, delete. */ @@ -1352,11 +1380,9 @@ hd->ScsiLookup[ii] = NULL; mf = MPT_INDEX_2_MFPTR(hd->ioc, ii); - dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n", - mf, SCpnt)); + dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n", mf, SCpnt)); /* Set status, free OS resources (SG DMA buffers) - * Do OS callback * Free driver resources (chain, msg buffers) */ if (SCpnt->use_sg) { @@ -1372,87 +1398,45 @@ } SCpnt->result = DID_RESET << 16; SCpnt->host_scribble = NULL; - MPT_HOST_LOCK(flags); - SCpnt->scsi_done(SCpnt); /* Issue the command callback */ - MPT_HOST_UNLOCK(flags); /* Free Chain buffers */ mptscsih_freeChainBuffers(hd, ii); /* Free Message frames */ mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); - } - } - - return; -} - -#ifdef DROP_TEST -/* mptscsih_flush_drop_test - Free resources and do callback if - * DROP_TEST enabled. - * - * @hd: Pointer to a SCSI HOST structure - * - * Returns: None. - * - * Must be called while new I/Os are being queued. - */ -static void -mptscsih_flush_drop_test (MPT_SCSI_HOST *hd) -{ - Scsi_Cmnd *sc; - unsigned long flags; - u16 req_idx; - /* Free resources for the drop test MF - * and chain buffers. - */ - if (dropMfPtr) { - req_idx = le16_to_cpu(dropMfPtr->u.frame.hwhdr.msgctxu.fld.req_idx); - sc = hd->ScsiLookup[req_idx]; - if (sc == NULL) { - printk(MYIOC_s_ERR_FMT "Drop Test: NULL ScsiCmd ptr!\n", - ioc->name); - } else { - /* unmap OS resources, set status, do callback - * free driver resources +#if 1 + /* Post to doneQ, do not reply until POST phase + * of reset handler....prevents new commands from + * being queued. */ - if (sc->use_sg) { - pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer, - sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction)); - } else if (sc->request_bufflen) { - scPrivate *my_priv; + spin_lock_irqsave(&hd->freedoneQlock, flags); + if (!Q_IS_EMPTY(&hd->freeQ)) { + buffer = hd->freeQ.head; + Q_DEL_ITEM(buffer); - my_priv = (scPrivate *) &sc->SCp; - pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1, - sc->request_bufflen, - scsi_to_pci_dma_dir(sc->sc_data_direction)); - } + /* Set the Scsi_Cmnd pointer + */ + buffer->argp = (void *)SCpnt; - sc->host_scribble = NULL; - sc->result = DID_RESET << 16; - hd->ScsiLookup[req_idx] = NULL; - atomic_dec(&queue_depth); - MPT_HOST_LOCK(flags); - sc->scsi_done(sc); /* Issue callback */ - MPT_HOST_UNLOCK(flags); + /* Add to the doneQ + */ + Q_ADD_TAIL(&hd->doneQ.head, buffer, MPT_DONE_Q); + spin_unlock_irqrestore(&hd->freedoneQlock, flags); + } else { + spin_unlock_irqrestore(&hd->freedoneQlock, flags); + SCpnt->scsi_done(SCpnt); + } +#else + MPT_HOST_LOCK(flags); + SCpnt->scsi_done(SCpnt); /* Issue the command callback */ + MPT_HOST_UNLOCK(flags); +#endif } - - mptscsih_freeChainBuffers(hd, req_idx); - mpt_free_msg_frame(ScsiDoneCtx, ioc->id, dropMfPtr); - printk(MYIOC_s_INFO_FMT "Free'd Dropped cmd (%p)\n", - hd->ioc->name, sc); - printk(MYIOC_s_INFO_FMT "mf (%p) reqidx (%4x)\n", - hd->ioc->name, dropMfPtr, req_idx); - printk(MYIOC_s_INFO_FMT "Num Tot (%d) Good (%d) Bad (%d) \n", - hd->ioc->name, dropTestNum, - dropTestOK, dropTestBad); } - dropMfPtr = NULL; return; } -#endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -1630,6 +1614,7 @@ int sz, ii; int numSGE = 0; int scale; + int ioc_cap; u8 *mem; if (! BeenHereDoneThat++) { @@ -1668,265 +1653,287 @@ this = mpt_adapter_find_first(); while (this != NULL) { - int portnum; - for (portnum=0; portnum < this->facts.NumberOfPorts; portnum++) { + /* 20010202 -sralston + * Added sanity check on readiness of the MPT adapter. + */ + if (this->last_state != MPI_IOC_STATE_OPERATIONAL) { + printk(MYIOC_s_WARN_FMT "Skipping because it's not operational!\n", + this->name); + continue; + } - /* 20010215 -sralston - * Added sanity check on SCSI Initiator-mode enabled - * for this MPT adapter. - */ - if (!(this->pfacts[portnum].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) { - printk(MYIOC_s_WARN_FMT "Skipping because SCSI Initiator mode is NOT enabled!\n", - this->name); - continue; - } + if (!this->active) { + printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", + this->name); + continue; + } + + + /* Sanity check - ensure at least 1 port is INITIATOR capable + */ + ioc_cap = 0; + for (ii=0; ii < this->facts.NumberOfPorts; ii++) { + if (this->pfacts[ii].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) + ioc_cap ++; + } + + if (!ioc_cap) { + printk(MYIOC_s_WARN_FMT "Skipping because SCSI Initiator mode is NOT enabled!\n", + this->name); + continue; + } - /* 20010202 -sralston - * Added sanity check on readiness of the MPT adapter. - */ - if (this->last_state != MPI_IOC_STATE_OPERATIONAL) { - printk(MYIOC_s_WARN_FMT "Skipping because it's not operational!\n", - this->name); - continue; - } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) - tpnt->proc_dir = &proc_mpt_scsihost; + tpnt->proc_dir = &proc_mpt_scsihost; #endif - tpnt->proc_info = mptscsih_proc_info; - sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST)); - if (sh != NULL) { - spin_lock_irqsave(&this->FreeQlock, flags); - sh->io_port = 0; - sh->n_io_port = 0; - sh->irq = 0; - - /* Yikes! This is important! - * Otherwise, by default, linux - * only scans target IDs 0-7! - * pfactsN->MaxDevices unreliable - * (not supported in early - * versions of the FW). - * max_id = 1 + actual max id, - * max_lun = 1 + actual last lun, - * see hosts.h :o( + tpnt->proc_info = mptscsih_proc_info; + sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST)); + if (sh != NULL) { + spin_lock_irqsave(&this->FreeQlock, flags); + sh->io_port = 0; + sh->n_io_port = 0; + sh->irq = 0; + + /* Yikes! This is important! + * Otherwise, by default, linux + * only scans target IDs 0-7! + * pfactsN->MaxDevices unreliable + * (not supported in early + * versions of the FW). + * max_id = 1 + actual max id, + * max_lun = 1 + actual last lun, + * see hosts.h :o( + */ + if ((int)this->chip_type > (int)FC929) + sh->max_id = MPT_MAX_SCSI_DEVICES; + else { + /* For FC, increase the queue depth + * from MPT_SCSI_CAN_QUEUE (31) + * to MPT_FC_CAN_QUEUE (63). */ - if ((int)this->chip_type > (int)FC929) - sh->max_id = MPT_MAX_SCSI_DEVICES; - else { - /* For FC, increase the queue depth - * from MPT_SCSI_CAN_QUEUE (31) - * to MPT_FC_CAN_QUEUE (63). - */ - sh->can_queue = MPT_FC_CAN_QUEUE; - sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; - } - sh->max_lun = MPT_LAST_LUN + 1; + sh->can_queue = MPT_FC_CAN_QUEUE; + sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; + } + sh->max_lun = MPT_LAST_LUN + 1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) - sh->max_sectors = MPT_SCSI_MAX_SECTORS; + sh->max_sectors = MPT_SCSI_MAX_SECTORS; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) || defined CONFIG_HIGHIO - sh->highmem_io = 1; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) || defined CONFIG_HIGHIO + sh->highmem_io = 1; #endif - sh->this_id = this->pfacts[portnum].PortSCSIID; + /* MPI uses {port, bus, id, lun}, but logically maps + * devices on different ports to different buses, i.e., + * bus 1 may be the 2nd bus on port 0 or the 1st bus on port 1. + * Map bus to channel, ignore port number in SCSI.... + * hd->port = 0; + * If max_channel > 0, need to adjust mem alloc, free, DV + * and all access to VirtDev + */ + sh->max_channel = 0; + sh->this_id = this->pfacts[0].PortSCSIID; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44) - /* OS entry to allow host drivers to force - * a queue depth on a per device basis. - */ - sh->select_queue_depths = mptscsih_select_queue_depths; + /* OS entry to allow host drivers to force + * a queue depth on a per device basis. + */ + sh->select_queue_depths = mptscsih_select_queue_depths; #endif - /* Required entry. - */ - sh->unique_id = this->id; - - /* Verify that we won't exceed the maximum - * number of chain buffers - * We can optimize: ZZ = req_sz/sizeof(SGE) - * For 32bit SGE's: - * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ - * + (req_sz - 64)/sizeof(SGE) - * A slightly different algorithm is required for - * 64bit SGEs. - */ - scale = this->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); - if (sizeof(dma_addr_t) == sizeof(u64)) { - numSGE = (scale - 1) * (this->facts.MaxChainDepth-1) + scale + - (this->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); - } else { - numSGE = 1 + (scale - 1) * (this->facts.MaxChainDepth-1) + scale + - (this->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); - } - - if (numSGE < sh->sg_tablesize) { - /* Reset this value */ - dprintk((MYIOC_s_INFO_FMT - "Resetting sg_tablesize to %d from %d\n", - this->name, numSGE, sh->sg_tablesize)); - sh->sg_tablesize = numSGE; - } + /* Required entry. + */ + sh->unique_id = this->id; - /* Set the pci device pointer in Scsi_Host structure. - */ - scsi_set_pci_device(sh, this->pcidev); + /* Verify that we won't exceed the maximum + * number of chain buffers + * We can optimize: ZZ = req_sz/sizeof(SGE) + * For 32bit SGE's: + * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ + * + (req_sz - 64)/sizeof(SGE) + * A slightly different algorithm is required for + * 64bit SGEs. + */ + scale = this->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); + if (sizeof(dma_addr_t) == sizeof(u64)) { + numSGE = (scale - 1) * (this->facts.MaxChainDepth-1) + scale + + (this->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); + } else { + numSGE = 1 + (scale - 1) * (this->facts.MaxChainDepth-1) + scale + + (this->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); + } - spin_unlock_irqrestore(&this->FreeQlock, flags); + if (numSGE < sh->sg_tablesize) { + /* Reset this value */ + dprintk((MYIOC_s_INFO_FMT + "Resetting sg_tablesize to %d from %d\n", + this->name, numSGE, sh->sg_tablesize)); + sh->sg_tablesize = numSGE; + } - hd = (MPT_SCSI_HOST *) sh->hostdata; - hd->ioc = this; - hd->max_sge = sh->sg_tablesize; + /* Set the pci device pointer in Scsi_Host structure. + */ + scsi_set_pci_device(sh, this->pcidev); - if ((int)this->chip_type > (int)FC929) - hd->is_spi = 1; + spin_unlock_irqrestore(&this->FreeQlock, flags); - if (DmpService && - (this->chip_type == FC919 || this->chip_type == FC929)) - hd->is_multipath = 1; + hd = (MPT_SCSI_HOST *) sh->hostdata; + hd->ioc = this; + hd->max_sge = sh->sg_tablesize; - hd->port = 0; /* FIXME! */ + if ((int)this->chip_type > (int)FC929) + hd->is_spi = 1; - /* SCSI needs Scsi_Cmnd lookup table! - * (with size equal to req_depth*PtrSz!) - */ - sz = hd->ioc->req_depth * sizeof(void *); - mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) - goto done; + if (DmpService && + (this->chip_type == FC919 || this->chip_type == FC929)) + hd->is_multipath = 1; - memset(mem, 0, sz); - hd->ScsiLookup = (struct scsi_cmnd **) mem; + /* SCSI needs Scsi_Cmnd lookup table! + * (with size equal to req_depth*PtrSz!) + */ + sz = hd->ioc->req_depth * sizeof(void *); + mem = kmalloc(sz, GFP_ATOMIC); + if (mem == NULL) + goto done; - dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", - this->name, hd->ScsiLookup, sz)); + memset(mem, 0, sz); + hd->ScsiLookup = (struct scsi_cmnd **) mem; - if (mptscsih_initChainBuffers(hd, 1) < 0) - goto done; + dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", + this->name, hd->ScsiLookup, sz)); - /* Allocate memory for free and doneQ's - */ - sz = sh->can_queue * sizeof(MPT_DONE_Q); - mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) - goto done; + if (mptscsih_initChainBuffers(hd, 1) < 0) + goto done; - memset(mem, 0xFF, sz); - hd->memQ = mem; + /* Allocate memory for free and doneQ's + */ + sz = sh->can_queue * sizeof(MPT_DONE_Q); + mem = kmalloc(sz, GFP_ATOMIC); + if (mem == NULL) + goto done; - /* Initialize the free, done and pending Qs. - */ - Q_INIT(&hd->freeQ, MPT_DONE_Q); - Q_INIT(&hd->doneQ, MPT_DONE_Q); - Q_INIT(&hd->pendingQ, MPT_DONE_Q); - spin_lock_init(&hd->freedoneQlock); + memset(mem, 0xFF, sz); + hd->memQ = mem; - mem = hd->memQ; - for (ii=0; ii < sh->can_queue; ii++) { - freedoneQ = (MPT_DONE_Q *) mem; - Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q); - mem += sizeof(MPT_DONE_Q); - } + /* Initialize the free, done and pending Qs. + */ + Q_INIT(&hd->freeQ, MPT_DONE_Q); + Q_INIT(&hd->doneQ, MPT_DONE_Q); + Q_INIT(&hd->pendingQ, MPT_DONE_Q); + spin_lock_init(&hd->freedoneQlock); + + mem = hd->memQ; + for (ii=0; ii < sh->can_queue; ii++) { + freedoneQ = (MPT_DONE_Q *) mem; + Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q); + mem += sizeof(MPT_DONE_Q); + } - /* Initialize this Scsi_Host - * internal task Q. - */ - Q_INIT(&hd->taskQ, MPT_FRAME_HDR); - hd->taskQcnt = 0; + /* Initialize this Scsi_Host + * internal task Q. + */ + Q_INIT(&hd->taskQ, MPT_FRAME_HDR); + hd->taskQcnt = 0; - /* Allocate memory for the device structures. - * A non-Null pointer at an offset - * indicates a device exists. - * max_id = 1 + maximum id (hosts.h) - */ - sz = sh->max_id * sizeof(void *); - mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) - goto done; + /* Allocate memory for the device structures. + * A non-Null pointer at an offset + * indicates a device exists. + * max_id = 1 + maximum id (hosts.h) + */ + sz = sh->max_id * sizeof(void *); + mem = kmalloc(sz, GFP_ATOMIC); + if (mem == NULL) + goto done; - memset(mem, 0, sz); - hd->Targets = (VirtDevice **) mem; + memset(mem, 0, sz); + hd->Targets = (VirtDevice **) mem; - dprintk((KERN_INFO " Targets @ %p, sz=%d\n", hd->Targets, sz)); + dprintk((KERN_INFO " Targets @ %p, sz=%d\n", hd->Targets, sz)); - /* Clear the TM flags - */ - hd->tmPending = 0; + /* Clear the TM flags + */ + hd->tmPending = 0; #ifdef MPT_SCSI_USE_NEW_EH - hd->tmState = TM_STATE_NONE; + hd->tmState = TM_STATE_NONE; #endif - hd->resetPending = 0; - hd->abortSCpnt = NULL; - hd->tmPtr = NULL; - hd->numTMrequests = 0; - - /* Clear the pointer used to store - * single-threaded commands, i.e., those - * issued during a bus scan, dv and - * configuration pages. - */ - hd->cmdPtr = NULL; - - /* Attach the SCSI Host to the IOC structure - */ - this->sh = sh; + hd->resetPending = 0; + hd->abortSCpnt = NULL; + hd->tmPtr = NULL; + hd->numTMrequests = 0; - /* Initialize this SCSI Hosts' timers - * To use, set the timer expires field - * and add_timer - */ - init_timer(&hd->timer); - hd->timer.data = (unsigned long) hd; - hd->timer.function = mptscsih_timer_expired; + /* Clear the pointer used to store + * single-threaded commands, i.e., those + * issued during a bus scan, dv and + * configuration pages. + */ + hd->cmdPtr = NULL; - init_timer(&hd->TMtimer); - hd->TMtimer.data = (unsigned long) hd; - hd->TMtimer.function = mptscsih_taskmgmt_timeout; - hd->qtag_tick = jiffies; + /* Attach the SCSI Host to the IOC structure + */ + this->sh = sh; - /* Moved Earlier Pam D */ - /* this->sh = sh; */ + /* Initialize this SCSI Hosts' timers + * To use, set the timer expires field + * and add_timer + */ + init_timer(&hd->timer); + hd->timer.data = (unsigned long) hd; + hd->timer.function = mptscsih_timer_expired; + + init_timer(&hd->TMtimer); + hd->TMtimer.data = (unsigned long) hd; + hd->TMtimer.function = mptscsih_taskmgmt_timeout; + hd->qtag_tick = jiffies; + + /* Moved Earlier Pam D */ + /* this->sh = sh; */ + +#ifdef MPTSCSIH_DBG_TIMEOUT + hd->ioc->timeout_hard = 0; + hd->ioc->timeout_delta = 30 * HZ; + hd->ioc->timeout_maxcnt = 0; + hd->ioc->timeout_cnt = 0; + for (ii=0; ii < 8; ii++) + foo_to[ii] = NULL; +#endif - if (hd->is_spi) { - /* Update with the driver setup - * values. - */ - if (hd->ioc->spi_data.maxBusWidth > driver_setup.max_width) - hd->ioc->spi_data.maxBusWidth = driver_setup.max_width; - if (hd->ioc->spi_data.minSyncFactor < driver_setup.min_sync_fac) - hd->ioc->spi_data.minSyncFactor = driver_setup.min_sync_fac; + if (hd->is_spi) { + /* Update with the driver setup + * values. + */ + if (hd->ioc->spi_data.maxBusWidth > driver_setup.max_width) + hd->ioc->spi_data.maxBusWidth = driver_setup.max_width; + if (hd->ioc->spi_data.minSyncFactor < driver_setup.min_sync_fac) + hd->ioc->spi_data.minSyncFactor = driver_setup.min_sync_fac; - if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) - hd->ioc->spi_data.maxSyncOffset = 0; + if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) + hd->ioc->spi_data.maxSyncOffset = 0; - hd->negoNvram = 0; + hd->negoNvram = 0; #ifdef MPTSCSIH_DISABLE_DOMAIN_VALIDATION - hd->negoNvram = MPT_SCSICFG_USE_NVRAM; + hd->negoNvram = MPT_SCSICFG_USE_NVRAM; #endif - if (driver_setup.dv == 0) - hd->negoNvram = MPT_SCSICFG_USE_NVRAM; + if (driver_setup.dv == 0) + hd->negoNvram = MPT_SCSICFG_USE_NVRAM; - hd->ioc->spi_data.forceDv = 0; - for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) - hd->ioc->spi_data.dvStatus[ii] = MPT_SCSICFG_NEGOTIATE; + hd->ioc->spi_data.forceDv = 0; + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) + hd->ioc->spi_data.dvStatus[ii] = MPT_SCSICFG_NEGOTIATE; - if (hd->negoNvram == 0) { - for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) - hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_NOT_DONE; - } - - ddvprintk((MYIOC_s_INFO_FMT - "dv %x width %x factor %x \n", - hd->ioc->name, driver_setup.dv, - driver_setup.max_width, - driver_setup.min_sync_fac)); - + if (hd->negoNvram == 0) { + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) + hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_NOT_DONE; } - mpt_scsi_hosts++; + ddvprintk((MYIOC_s_INFO_FMT + "dv %x width %x factor %x \n", + hd->ioc->name, driver_setup.dv, + driver_setup.max_width, + driver_setup.min_sync_fac)); } - } /* for each adapter port */ + mpt_scsi_hosts++; + } this = mpt_adapter_find_next(this); } @@ -2251,11 +2258,129 @@ return ((info.pos > info.offset) ? info.pos - info.offset : 0); } +#ifndef MPTSCSIH_DBG_TIMEOUT static int mptscsih_user_command(MPT_ADAPTER *ioc, char *pbuf, int len) { /* Not yet implemented */ return len; } +#else +#define is_digit(c) ((c) >= '0' && (c) <= '9') +#define digit_to_bin(c) ((c) - '0') +#define is_space(c) ((c) == ' ' || (c) == '\t') + +#define UC_DBG_TIMEOUT 0x01 +#define UC_DBG_HARDRESET 0x02 + +static int skip_spaces(char *ptr, int len) +{ + int cnt, c; + + for (cnt = len; cnt > 0 && (c = *ptr++) && is_space(c); cnt --); + + return (len - cnt); +} + +static int get_int_arg(char *ptr, int len, ulong *pv) +{ + int cnt, c; + ulong v; + for (v = 0, cnt = len; cnt > 0 && (c=*ptr++) && is_digit(c); cnt --) { + v = (v * 10) + digit_to_bin(c); + } + + if (pv) + *pv = v; + + return (len - cnt); +} + + +static int is_keyword(char *ptr, int len, char *verb) +{ + int verb_len = strlen(verb); + + if (len >= strlen(verb) && !memcmp(verb, ptr, verb_len)) + return verb_len; + else + return 0; +} + +#define SKIP_SPACES(min_spaces) \ + if ((arg_len = skip_spaces(ptr,len)) < (min_spaces)) \ + return -EINVAL; \ + ptr += arg_len; \ + len -= arg_len; + +#define GET_INT_ARG(v) \ + if (!(arg_len = get_int_arg(ptr,len, &(v)))) \ + return -EINVAL; \ + ptr += arg_len; \ + len -= arg_len; + +static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length) +{ + char *ptr = buffer; + char btmp[24]; /* REMOVE */ + int arg_len; + int len = length; + int cmd; + ulong number = 1; + ulong delta = 10; + + if ((len > 0) && (ptr[len -1] == '\n')) + --len; + + if (len < 22) { + strncpy(btmp, buffer, len); + btmp[len+1]='\0'; + } else { + strncpy(btmp, buffer, 22); + btmp[23]='\0'; + } + printk("user_command: ioc %d, buffer %s, length %d\n", + ioc->id, btmp, length); + + if ((arg_len = is_keyword(ptr, len, "timeout")) != 0) + cmd = UC_DBG_TIMEOUT; + else if ((arg_len = is_keyword(ptr, len, "hardreset")) != 0) + cmd = UC_DBG_HARDRESET; + else + return -EINVAL; + + ptr += arg_len; + len -= arg_len; + + switch(cmd) { + case UC_DBG_TIMEOUT: + SKIP_SPACES(1); + GET_INT_ARG(number); + SKIP_SPACES(1); + GET_INT_ARG(delta); + break; + } + + printk("user_command: cnt=%ld delta=%ld\n", number, delta); + + if (len) + return -EINVAL; + else { + if (cmd == UC_DBG_HARDRESET) { + ioc->timeout_hard = 1; + } else if (cmd == UC_DBG_TIMEOUT) { + /* process this command ... + */ + ioc->timeout_maxcnt = 0; + ioc->timeout_delta = delta < 2 ? 2 : delta; + ioc->timeout_cnt = 0; + ioc->timeout_maxcnt = number < 8 ? number: 8; + } + } + /* Not yet implemented */ + return length; +} +#endif + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** @@ -2318,19 +2443,6 @@ #define ADD_INDEX_LOG(req_ent) do { } while(0) #endif -#ifdef DROP_TEST -#define DROP_IOC 1 /* IOC to force failures */ -#define DROP_TARGET 3 /* Target ID to force failures */ -#define DROP_THIS_CMD 10000 /* iteration to drop command */ -static int dropCounter = 0; -static int dropTestOK = 0; /* num did good */ -static int dropTestBad = 0; /* num did bad */ -static int dropTestNum = 0; /* total = good + bad + incomplete */ -static int numTotCmds = 0; -static MPT_FRAME_HDR *dropMfPtr = NULL; -static int numTMrequested = 0; -#endif - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mptscsih_put_msgframe - Wrapper routine to post message frame to F/W. @@ -2403,49 +2515,16 @@ dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n", (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done)); -#ifdef MPT_SAVE_AUTOSENSE - /* 20000617 -sralston - * GRRRRR... Shouldn't have to do this but... - * Do explicit check for REQUEST_SENSE and cached SenseData. - * If yes, return cached SenseData. - */ - if (SCpnt->cmnd[0] == REQUEST_SENSE) { - u8 *dest = NULL; - int sz; - - if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_VALID_SENSE)) { - pTarget->tflags &= ~MPT_TARGET_FLAGS_VALID_SENSE; //sjr-moved-here - if (!SCpnt->use_sg) { - dest = SCpnt->request_buffer; - } else { - struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer; - if (sg) - dest = (u8 *)(ulong)sg_dma_address(sg); - } - - if (dest) { - sz = MIN (SCSI_STD_SENSE_BYTES, SCpnt->request_bufflen); - memcpy(dest, pTarget->sense, sz); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - SCpnt->resid = SCpnt->request_bufflen - sz; -#endif - SCpnt->result = 0; - SCpnt->scsi_done(SCpnt); - - //sjr-moved-up//pTarget->tflags &= ~MPT_TARGET_FLAGS_VALID_SENSE; - - return 0; - } - } - } -#endif - if (hd->resetPending) { /* Prevent new commands from being issued - * while reloading the FW. + * while reloading the FW. Reset timer to 60 seconds, + * as the FW can take some time to come ready. + * For New EH, cmds on doneQ posted to FW. */ did_errcode = 1; + mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60)); + dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n", + (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt)); goto did_error; } @@ -2500,8 +2579,8 @@ /* Use the above information to set up the message frame */ - pScsiReq->TargetID = target; - pScsiReq->Bus = hd->port; + pScsiReq->TargetID = (u8) target; + pScsiReq->Bus = (u8) SCpnt->channel; pScsiReq->ChainOffset = 0; pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; pScsiReq->CDBLength = SCpnt->cmd_len; @@ -2526,6 +2605,9 @@ for (ii=0; ii < cmd_len; ii++) pScsiReq->CDB[ii] = SCpnt->cmnd[ii]; + for (ii=cmd_len; ii < 16; ii++) + pScsiReq->CDB[ii] = 0; + /* DataLength */ pScsiReq->DataLength = cpu_to_le32(datalen); @@ -2551,39 +2633,6 @@ hd->ScsiLookup[my_idx] = SCpnt; SCpnt->host_scribble = NULL; -#ifdef DROP_TEST - numTotCmds++; - /* If the IOC number and target match, increment - * counter. If counter matches DROP_THIS, do not - * issue command to FW to force a reset. - * Save the MF pointer so we can free resources - * when task mgmt completes. - */ - if ((hd->ioc->id == DROP_IOC) && (target == DROP_TARGET)) { - dropCounter++; - - if (dropCounter == DROP_THIS_CMD) { - dropCounter = 0; - - /* If global is set, then we are already - * doing something - so keep issuing commands. - */ - if (dropMfPtr == NULL) { - dropTestNum++; - dropMfPtr = mf; - atomic_inc(&queue_depth); - printk(MYIOC_s_INFO_FMT - "Dropped SCSI cmd (%p)\n", - hd->ioc->name, SCpnt); - printk("mf (%p) req (%4x) tot cmds (%d)\n", - mf, my_idx, numTotCmds); - - return 0; - } - } - } -#endif - /* SCSI specific processing */ issueCmd = 1; if (hd->is_spi) { @@ -2636,6 +2685,18 @@ } } +#ifdef MPTSCSIH_DBG_TIMEOUT + if (hd->ioc->timeout_cnt < hd->ioc->timeout_maxcnt) { + foo_to[hd->ioc->timeout_cnt] = SCpnt; + hd->ioc->timeout_cnt++; + //mod_timer(&SCpnt->eh_timeout, jiffies + hd->ioc->timeout_delta); + issueCmd = 0; + printk(MYIOC_s_WARN_FMT + "to pendingQ: (sc=%p, mf=%p, time=%ld)\n", + hd->ioc->name, SCpnt, mf, jiffies); + } +#endif + if (issueCmd) { mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", @@ -2679,6 +2740,8 @@ SCpnt->result = (DID_BUS_BUSY << 16); spin_lock_irqsave(&hd->freedoneQlock, flags); if (!Q_IS_EMPTY(&hd->freeQ)) { + dtmprintk((MYIOC_s_WARN_FMT "SCpnt=%p to doneQ\n", + (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt)); buffer = hd->freeQ.head; Q_DEL_ITEM(buffer); @@ -2774,7 +2837,7 @@ * Returns 0 for SUCCESS or -1 if FAILED. */ static int -mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag) +mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, int sleepFlag) { MPT_ADAPTER *ioc = NULL; int rc = -1; @@ -2789,19 +2852,18 @@ return 0; ioc = hd->ioc; - dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); - if (ioc == NULL) { printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n"); - return 0; + return FAILED; } + dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); // SJR - CHECKME - Can we avoid this here? // (mpt_HardResetHandler has this check...) spin_lock_irqsave(&ioc->diagLock, flags); if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) { spin_unlock_irqrestore(&ioc->diagLock, flags); - return 0; + return FAILED; } spin_unlock_irqrestore(&ioc->diagLock, flags); @@ -2811,6 +2873,39 @@ if (hd->numTMrequests > MPT_HOST_TOO_MANY_TM) doTask = 0; +#ifdef MPT_SCSI_USE_NEW_EH + /* Wait a fixed amount of time for the TM pending flag to be cleared. + * If we time out and not bus reset, then we return a FAILED status to the caller. + * The call to mptscsih_tm_pending_wait() will set the pending flag if we are + * successful. Otherwise, reload the FW. + */ + if (mptscsih_tm_pending_wait(hd) == FAILED) { + if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) { + nehprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: " + "Timed out waiting for last TM (%d) to complete! \n", + hd->ioc->name, hd->tmPending)); + return FAILED; + } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { + nehprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: " + "Timed out waiting for last TM (%d) to complete! \n", + hd->ioc->name, hd->tmPending)); + return FAILED; + } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { + nehprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: " + "Timed out waiting for last TM (%d) to complete! \n", + hd->ioc->name, hd->tmPending)); + if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) + return FAILED; + + doTask = 0; + } + } else { + spin_lock_irqsave(&hd->ioc->FreeQlock, flags); + hd->tmPending |= (1 << type); + spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + } +#endif + /* Is operational? */ ioc_raw_state = mpt_GetIocState(hd->ioc, 0); @@ -2818,7 +2913,7 @@ #ifdef MPT_DEBUG_RESET if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { printk(MYIOC_s_WARN_FMT - "TM Handler: IOC Not operational! state 0x%x Calling HardResetHandler\n", + "TM Handler: IOC Not operational(0x%x)!\n", hd->ioc->name, ioc_raw_state); } #endif @@ -2830,23 +2925,23 @@ */ if (hd->hard_resets < -1) hd->hard_resets++; - rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag); + rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, sleepFlag); if (rc) { printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); } else { dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name)); } } -#ifdef DROP_TEST - numTMrequested++; - if (numTMrequested > 5) { - rc = 0; /* set to 1 to force a hard reset */ - numTMrequested = 0; - } +#ifdef MPTSCSIH_DBG_TIMEOUT + if (hd->ioc->timeout_hard) + rc = 1; #endif - if (rc || ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw)) { - dtmprintk((MYIOC_s_INFO_FMT "Falling through to HardReset! \n", + /* Only fall through to the HRH if this is a bus reset + */ + if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || + ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { + dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", hd->ioc->name)); rc = mpt_HardResetHandler(hd->ioc, sleepFlag); } @@ -2860,7 +2955,6 @@ return rc; } - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mptscsih_IssueTaskMgmt - Generic send Task Management function. @@ -2880,7 +2974,7 @@ * else other non-zero value returned. */ static int -mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag) +mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, int sleepFlag) { MPT_FRAME_HDR *mf; SCSITaskMgmt_t *pScsiTm; @@ -2902,7 +2996,7 @@ */ pScsiTm = (SCSITaskMgmt_t *) mf; pScsiTm->TargetID = target; - pScsiTm->Bus = hd->port; + pScsiTm->Bus = channel; pScsiTm->ChainOffset = 0; pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; @@ -2976,6 +3070,9 @@ return FAILED; } + if (hd->resetPending) + return FAILED; + printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p, numIOs=%d)\n", hd->ioc->name, SCpnt, atomic_read(&queue_depth)); @@ -2998,19 +3095,6 @@ return SUCCESS; } - /* Wait a fixed amount of time for the TM pending flag to be cleared. - * If we time out, then we return a FAILED status to the caller. This - * call to mptscsih_tm_pending_wait() will set the pending flag if we are - * successful. - */ - if (mptscsih_tm_pending_wait(hd) == FAILED){ - nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " - "Timed out waiting for previous TM to complete! " - "(sc = %p)\n", - hd->ioc->name, SCpnt)); - return FAILED; - } - /* If this command is pended, then timeout/hang occurred * during DV. Post command and flush pending Q * and then following up with the reset request. @@ -3019,7 +3103,7 @@ mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); post_pendingQ_commands(hd); nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " - "Found command in pending queue! (sc=%p)\n", + "Posting pended cmd! (sc=%p)\n", hd->ioc->name, SCpnt)); } @@ -3035,7 +3119,7 @@ hd->abortSCpnt = SCpnt; if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, - SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP) + SCpnt->channel, SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP) < 0) { /* The TM request failed and the subsequent FW-reload failed! @@ -3078,29 +3162,19 @@ return FAILED; } + if (hd->resetPending) + return FAILED; + printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p, numIOs=%d)\n", hd->ioc->name, SCpnt, atomic_read(&queue_depth)); - /* Unsupported for SCSI. Suppored for FCP + /* Unsupported for SCSI. Supported for FCP */ if (hd->is_spi) return FAILED; - /* Wait a fixed amount of time for the TM pending flag to be cleared. - * If we time out, then we return a FAILED status to the caller. This - * call to mptscsih_tm_pending_wait() will set the pending flag if we are - * successful. - */ - if (mptscsih_tm_pending_wait(hd) == FAILED) { - nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: " - "Timed out waiting for previous TM to complete! " - "(sc = %p)\n", - hd->ioc->name, SCpnt)); - return FAILED; - } - if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, - SCpnt->target, 0, 0, NO_SLEEP) + SCpnt->channel, SCpnt->target, 0, 0, NO_SLEEP) < 0){ /* The TM request failed and the subsequent FW-reload failed! * Fatal error case. @@ -3144,22 +3218,9 @@ if (hd->timeouts < -1) hd->timeouts++; - /* Wait a fixed amount of time for the TM pending flag to be cleared. - * If we time out, then we return a FAILED status to the caller. This - * call to mptscsih_tm_pending_wait() will set the pending flag if we are - * successful. - */ - if (mptscsih_tm_pending_wait(hd) == FAILED) { - nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: " - "Timed out waiting for previous TM to complete! " - "(sc = %p)\n", - hd->ioc->name, SCpnt)); - return FAILED; - } - /* We are now ready to execute the task management request. */ if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, - 0, 0, 0, NO_SLEEP) + SCpnt->channel, 0, 0, 0, NO_SLEEP) < 0){ /* The TM request failed and the subsequent FW-reload failed! @@ -3238,7 +3299,7 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) { unsigned long flags; - int loop_count = 60 * 4; /* Wait 60 seconds */ + int loop_count = 2 * 10 * 4; /* Wait 2 seconds */ int status = FAILED; do { @@ -3251,6 +3312,8 @@ break; } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + //set_current_state(TASK_INTERRUPTIBLE); + //schedule_timeout(HZ/4); mdelay(250); } while (--loop_count); @@ -3379,10 +3442,6 @@ mytaskQ_bh_active = 1; spin_unlock_irqrestore(&mytaskQ_lock, flags); - /* - * Oh how cute, no alloc/free/mgmt needed if we use - * (bottom/unused portion of) MPT request frame. - */ ptaskfoo = (struct mpt_work_struct *) &mptscsih_ptaskfoo; MPT_INIT_WORK(&mptscsih_ptaskfoo, mptscsih_taskmgmt_bh, (void *) SCpnt); @@ -3567,6 +3626,15 @@ continue; } +#ifdef MPTSCSIH_DBG_TIMEOUT + if (ioc->timeout_hard == 1) { + mptscsih_TMHandler(hd, + MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, + 0, 0, 0, 0, CAN_SLEEP); + + } +#endif + spin_lock_irqsave(&ioc->FreeQlock, flags); if (Q_IS_EMPTY(&hd->taskQ)) { spin_unlock_irqrestore(&ioc->FreeQlock, flags); @@ -3659,7 +3727,9 @@ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); mf = NULL; - if (mptscsih_TMHandler(hd, task_type, SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP) < 0) { + if (mptscsih_TMHandler(hd, task_type, SCpnt->channel, + SCpnt->target, SCpnt->lun, + ctx2abort, CAN_SLEEP) < 0) { /* The TM request failed and the subsequent FW-reload failed! * Fatal error case. @@ -3765,10 +3835,7 @@ */ if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) hd->abortSCpnt = NULL; -#ifdef DROP_TEST - if (dropMfPtr) - dropTestBad++; -#endif + /* If an internal command is present * or the TM failed - reload the FW. * FC FW may respond FAILED to an ABORT @@ -3802,17 +3869,9 @@ hd->abortSCpnt = NULL; flush_doneQ(hd); -#ifdef DROP_TEST - if (dropMfPtr) - dropTestOK++; -#endif } } -#ifdef DROP_TEST - mptscsih_flush_drop_test(hd); -#endif - #ifndef MPT_SCSI_USE_NEW_EH /* * Signal to _bh thread that we finished. @@ -3837,19 +3896,9 @@ * This is anyones guess quite frankly. */ int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) -mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, - sector_t capacity, int *ip) -{ -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) -mptscsih_bios_param(Disk * disk, struct block_device *bdev, int *ip) -{ - sector_t capacity = disk->capacity; -#else mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip) { unsigned capacity = disk->capacity; -#endif int size; size = capacity; @@ -3869,43 +3918,6 @@ * Called once per device the bus scan. Use it to force the queue_depth * member to 1 if a device does not support Q tags. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) -int -mptscsih_slave_attach(Scsi_Device *device) -{ - struct Scsi_Host *host = device->host; - VirtDevice *pTarget; - MPT_SCSI_HOST *hd; - - hd = (MPT_SCSI_HOST *)host->hostdata; - if (hd && (hd->Targets != NULL)) { - pTarget = hd->Targets[device->id]; - if (pTarget) { - if (!device->tagged_supported || - !(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) { - scsi_adjust_queue_depth(device, 0, 1); - - } else if ((pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) - && (pTarget->inq_data[0] & 0x1f) == 0x00 - && (pTarget->minSyncFactor <= MPT_ULTRA160 || !hd->is_spi)) { - scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, - MPT_SCSI_CMD_PER_DEV_HIGH); - } else { - scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, - MPT_SCSI_CMD_PER_DEV_LOW); - } -#if 0 - /* Original Code for 2.5 */ - } else { - scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, - device->host->can_queue >> 1); - } -#endif - } - } - return 0; -} -#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) */ void mptscsih_select_queue_depths(struct Scsi_Host *sh, Scsi_Device *sdList) { @@ -3948,14 +3960,21 @@ /* error case - No Inq. Data */ device->queue_depth = 1; } - dprintk((MYIOC_s_INFO_FMT - "target = %d, sync factor = %x, queue depth = %d\n", - hd->ioc->name, pTarget->target_id, - pTarget->minSyncFactor, device->queue_depth)); + + if (pTarget != NULL) { + printk(MYIOC_s_INFO_FMT + "scsi%d: Id=%d Lun=%d: Queue depth=%d\n", + hd->ioc->name, sh->host_no, + device->id, device->lun, device->queue_depth); + + dprintk((MYIOC_s_INFO_FMT + "Id = %d, sync factor = %x\n", + hd->ioc->name, pTarget->target_id, + pTarget->minSyncFactor)); + } } } } -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -3994,34 +4013,6 @@ sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc)); - /* save sense data to the target device - */ - if (hd->is_spi && target) { -#ifdef MPT_SAVE_AUTOSENSE - int sz; - - sz = MIN(pReq->SenseBufferLength, sense_count); - if (sz > SCSI_STD_SENSE_BYTES) - sz = SCSI_STD_SENSE_BYTES; - memcpy(target->sense, sense_data, sz); - target->tflags |= MPT_TARGET_FLAGS_VALID_SENSE; -#endif - -#ifdef ABORT_FIX - if (sz >= SCSI_STD_SENSE_BYTES) { - if ((sense_data[02] == ABORTED_COMMAND) && - (sense_data[12] == 0x47) && (sense_data[13] == 0x00)){ - target->numAborts++; - if ((target->raidVolume == 0) && (target->numAborts > 5)) { - target->numAborts = 0; - target->minSyncFactor++; - hd->ioc->spi_data.dvStatus[index] |= MPT_SCSICFG_NEGOTIATE; - } - } - } -#endif - } - /* Log SMART data (asc = 0x5D, non-IM case only) if required. */ if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { @@ -4204,7 +4195,8 @@ dtmprintk((KERN_WARNING MYNAM ": IOC %s_reset routed to SCSI host driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); /* If a FW reload request arrives after base installed but * before all scsi hosts have been attached, then an alt_ioc @@ -4215,28 +4207,26 @@ else hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; - if (reset_phase == MPT_IOC_PRE_RESET) { - dtmprintk((MYIOC_s_WARN_FMT "Do Pre-Diag Reset handling\n", - ioc->name)); - + if (reset_phase == MPT_IOC_SETUP_RESET) { + dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name)); /* Clean Up: * 1. Set Hard Reset Pending Flag * All new commands go to doneQ */ hd->resetPending = 1; + /* 2. Reset timeouts on all running commands + */ + mptscsih_reset_timeouts (hd); + + } else if (reset_phase == MPT_IOC_PRE_RESET) { + dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name)); + /* 2. Flush running commands - * Clean drop test code - if compiled * Clean ScsiLookup (and associated memory) * AND clean mytaskQ */ - /* 2a. Drop Test Command. - */ -#ifdef DROP_TEST - mptscsih_flush_drop_test(hd); -#endif - /* 2b. Reply to OS all known outstanding I/O commands. */ mptscsih_flush_running_cmds(hd); @@ -4266,14 +4256,16 @@ */ clean_taskQ(hd); #endif - dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset handling complete.\n", - ioc->name)); + +#ifdef MPTSCSIH_DBG_TIMEOUT + ioc->timeout_hard = 0; +#endif + dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name)); } else { ScsiCfgData *pSpi = NULL; - dtmprintk((MYIOC_s_WARN_FMT "Do Post-Diag Reset handling\n", - ioc->name)); + dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name)); /* Once a FW reload begins, all new OS commands are * redirected to the doneQ w/ a reset status. @@ -4332,16 +4324,15 @@ */ flush_doneQ(hd); - dtmprintk((MYIOC_s_WARN_FMT "Post-Reset handling complete.\n", - ioc->name)); - - - /* 8. Set then flag to force DV and re-read IOC Page 3 + /* 8. Set flag to force DV and re-read IOC Page 3 */ - pSpi = &ioc->spi_data; - pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; - ddvtprintk(("Set reload IOC Pg3 Flag\n")); + if (hd->is_spi) { + pSpi = &ioc->spi_data; + pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; + ddvtprintk(("Set reload IOC Pg3 Flag\n")); + } + dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); } return 1; /* currently means nothing really */ @@ -4797,7 +4788,7 @@ /* * Need to check ASC here; if it is "special," then * the ASCQ is variable, and indicates failed component number. - * We must treat the ASCQ as a "dont care" while searching the + * We must treat the ASCQ as a "don't care" while searching the * mptscsih_ASCQ_Table[] by masking it off, and then restoring it later * on when we actually need to identify the failed component. */ @@ -5076,7 +5067,7 @@ u8 factor = MPT_ASYNC; u8 offset = 0; u8 version, nfactor; - u8 noQas = 1; + u8 noQas = 0; ddvtprintk((KERN_INFO "set Target: (id %d) byte56 0x%x\n", id, byte56)); @@ -5087,9 +5078,20 @@ } return; } + + /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine + * support. If available, default QAS to off and allow enabling. + * If not available, default QAS to on, turn off for non-disks. + */ + if (target->tflags & MPT_TARGET_FLAGS_VALID_56) + noQas = 1; + /* Set flags based on Inquiry data */ if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { + if ((target->inq_data[0] & 0x1F) != 0x00) + noQas = 1; + version = target->inq_data[2] & 0x07; if (version < 2) { width = 0; @@ -5197,7 +5199,7 @@ /* Disable QAS if mixed configuration case */ - if ((noQas) && (!pspi_data->noQas) && ((target->inq_data[0] & 0x1F) == 0x00)){ + if ((noQas) && (!pspi_data->noQas) && ((target->inq_data[0] & 0x1F) != 0x03)){ VirtDevice *vdev; int ii; @@ -5209,30 +5211,11 @@ vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; } } - } return; } -#ifdef MPT_SAVE_AUTOSENSE -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * Clear sense valid flag. - */ -static void clear_sense_flag(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) -{ - VirtDevice *target; - int index = (int) pReq->TargetID; - - if ((target = hd->Targets[index])) { - target->tflags &= ~MPT_TARGET_FLAGS_VALID_SENSE; - } - - return; -} -#endif - /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return. * Else set the NEED_DV flag after Read Capacity Issued (disks) * or Mode Sense (cdroms). @@ -5634,10 +5617,6 @@ /* If target struct exists, clear sense valid flag. */ -#ifdef MPT_SAVE_AUTOSENSE - clear_sense_flag(hd, pReq); -#endif - if (mr == NULL) { completionCode = MPT_SCANDV_GOOD; } else { @@ -5688,13 +5667,10 @@ completionCode = MPT_SCANDV_SOME_ERROR; } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) { -#ifdef MPT_SAVE_AUTOSENSE - VirtDevice *target; -#endif u8 *sense_data; int sz; - /* save sense data in global & target structure + /* save sense data in global structure */ completionCode = MPT_SCANDV_SENSE; hd->pLocal->scsiStatus = pReply->SCSIStatus; @@ -5705,15 +5681,6 @@ SCSI_STD_SENSE_BYTES); memcpy(hd->pLocal->sense, sense_data, sz); -#ifdef MPT_SAVE_AUTOSENSE - target = hd->Targets[pReq->TargetID]; - if (target) { - memcpy(target->sense, sense_data, sz); - target->tflags - |= MPT_TARGET_FLAGS_VALID_SENSE; - } -#endif - ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n", sense_data)); } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) { @@ -5796,6 +5763,8 @@ * for bus reset. */ #ifndef MPT_SCSI_USE_NEW_EH + SCSIIORequest_t *pReq = (SCSIIORequest_t *) hd->cmdPtr; + spin_lock_irqsave(&hd->ioc->FreeQlock, flags); if (hd->tmPending) { spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); @@ -5803,9 +5772,8 @@ } else hd->tmPending = 1; spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); - if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, - 0, 0, 0, NO_SLEEP) < 0) { + pReq->Bus, 0, 0, 0, NO_SLEEP) < 0) { printk(MYIOC_s_WARN_FMT "TM FAILED!\n", hd->ioc->name); } #else @@ -6524,7 +6492,7 @@ * Return: None. */ static int -mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id) +mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) { MPT_ADAPTER *ioc = hd->ioc; VirtDevice *pTarget = NULL; @@ -6552,6 +6520,7 @@ int patt; int repeat; int retcode = 0; + int nfactor = MPT_ULTRA320; char firstPass = 1; char doFallback = 0; char readPage0; @@ -6564,11 +6533,14 @@ if (ioc->spi_data.sdp0length == 0) return 0; - if (id == ioc->pfacts[portnum].PortSCSIID) + /* If multiple buses are used, require that the initiator + * id be the same on all buses. + */ + if (id == ioc->pfacts[0].PortSCSIID) return 0; lun = 0; - bus = 0; + bus = (u8) bus_number; ddvtprintk((MYIOC_s_NOTE_FMT "DV started: numIOs %d bus=%d, id %d dv @ %p\n", ioc->name, atomic_read(&queue_depth), bus, id, &dv)); @@ -6673,16 +6645,33 @@ /* Skip this ID? Set cfg.hdr to force config page write */ - if ((ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID) && - (!(ioc->spi_data.nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE))) { - - ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n", - ioc->name, bus, id, lun)); - - dv.cmd = MPT_SET_MAX; - mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); - cfg.hdr = &header1; - goto target_done; + { + ScsiCfgData *pspi_data = &hd->ioc->spi_data; + if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { + /* Set the factor from nvram */ + nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8; + if (nfactor < pspi_data->minSyncFactor ) + nfactor = pspi_data->minSyncFactor; + + if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE)) { + + ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n", + ioc->name, bus, id, lun)); + + dv.cmd = MPT_SET_MAX; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + cfg.hdr = &header1; + + /* Save the final negotiated settings to + * SCSI device page 1. + */ + cfg.physAddr = cfg1_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + cfg.dir = 1; + mpt_config(hd->ioc, &cfg); + goto target_done; + } + } } /* Finish iocmd inititialization - hidden or visible disk? */ @@ -6804,6 +6793,14 @@ } } + /* Reset the size for disks + */ + inq0 = (*pbuf1) & 0x1F; + if ((inq0 == 0) && pTarget && !pTarget->raidVolume) { + sz = 0x40; + iocmd.size = sz; + } + /* Another GEM workaround. Check peripheral device type, * if PROCESSOR, quit DV. */ @@ -6813,6 +6810,26 @@ if (mptscsih_do_cmd(hd, &iocmd) < 0) goto target_done; + if (sz == 0x40) { + if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A) + && (pTarget->minSyncFactor > 0x09)) { + if ((pbuf1[56] & 0x04) == 0) + ; + else if ((pbuf1[56] & 0x01) == 1) { + pTarget->minSyncFactor = nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; + } else { + pTarget->minSyncFactor = nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; + } + + dv.max.factor = pTarget->minSyncFactor; + + if ((pbuf1[56] & 0x02) == 0) { + pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; + } + } + } + if (doFallback) dv.cmd = MPT_FALLBACK; else @@ -7320,19 +7337,16 @@ dv.cmd = MPT_SAVE; mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); -#if 0 - /* Double writes to SDP1 can cause problems, - * skip here since unnecessary - */ - /* Save the final negotiated settings to + /* Double writes to SDP1 can cause problems, + * skip save of the final negotiated settings to * SCSI device page 1. - */ + * cfg.hdr = &header1; cfg.physAddr = cfg1_dma_addr; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.dir = 1; mpt_config(hd->ioc, &cfg); -#endif + */ } /* If this is a RAID Passthrough, enable internal IOs diff -urN linux-2.4.21/drivers/message/fusion/mptscsih.h linux-2.4.22/drivers/message/fusion/mptscsih.h --- linux-2.4.21/drivers/message/fusion/mptscsih.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/mptscsih.h 2003-08-25 04:44:42.000000000 -0700 @@ -17,10 +17,10 @@ * * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston - * (mailto:netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:sjralston1@netscape.net) + * (mailto:lstephens@lsil.com) * - * $Id: mptscsih.h,v 1.22 2002/12/16 15:28:48 pdelaney Exp $ + * $Id: mptscsih.h,v 1.1.2.2 2003/05/07 14:08:35 pdelaney Exp $ */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -72,7 +72,7 @@ /* * Try to keep these at 2^N-1 */ -#define MPT_FC_CAN_QUEUE 63 +#define MPT_FC_CAN_QUEUE 127 #if defined MPT_SCSI_USE_NEW_EH #define MPT_SCSI_CAN_QUEUE 127 #else @@ -217,11 +217,7 @@ #define x_scsi_taskmgmt_bh mptscsih_taskmgmt_bh #define x_scsi_old_abort mptscsih_old_abort #define x_scsi_old_reset mptscsih_old_reset -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) -#define x_scsi_slave_attach mptscsih_slave_attach -#else #define x_scsi_select_queue_depths mptscsih_select_queue_depths -#endif #define x_scsi_proc_info mptscsih_proc_info /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -241,86 +237,18 @@ extern int x_scsi_old_abort(Scsi_Cmnd *); extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int); #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) -extern int x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev, - sector_t capacity, int *ip); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) -extern int x_scsi_bios_param(Disk *, struct block_device *, int *); -#else extern int x_scsi_bios_param(Disk *, kdev_t, int *); -#endif extern void x_scsi_taskmgmt_bh(void *); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) -extern int x_scsi_slave_attach(Scsi_Device *); -#else extern void x_scsi_select_queue_depths(struct Scsi_Host *, Scsi_Device *); -#endif - extern int x_scsi_proc_info(char *, char **, off_t, int, int, int); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) #define PROC_SCSI_DECL #else -#define PROC_SCSI_DECL proc_name: "mptscsih", +#define PROC_SCSI_DECL .proc_name = "mptscsih", #endif #ifdef MPT_SCSI_USE_NEW_EH - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) - -#define MPT_SCSIHOST { \ - PROC_SCSI_DECL \ - .proc_info = x_scsi_proc_info, \ - .name = "MPT SCSI Host", \ - .detect = x_scsi_detect, \ - .release = x_scsi_release, \ - .info = x_scsi_info, \ - .command = NULL, \ - .queuecommand = x_scsi_queuecommand, \ - .slave_attach = x_scsi_slave_attach, \ - .eh_strategy_handler = NULL, \ - .eh_abort_handler = x_scsi_abort, \ - .eh_device_reset_handler = x_scsi_dev_reset, \ - .eh_bus_reset_handler = x_scsi_bus_reset, \ - .eh_host_reset_handler = x_scsi_host_reset, \ - .bios_param = x_scsi_bios_param, \ - .can_queue = MPT_SCSI_CAN_QUEUE, \ - .this_id = -1, \ - .sg_tablesize = MPT_SCSI_SG_DEPTH, \ - .max_sectors = MPT_SCSI_MAX_SECTORS, \ - .cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \ - .unchecked_isa_dma = 0, \ - .use_clustering = ENABLE_CLUSTERING, \ -} - -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) - -#define MPT_SCSIHOST { \ - PROC_SCSI_DECL \ - .proc_info = x_scsi_proc_info, \ - .name = "MPT SCSI Host", \ - .detect = x_scsi_detect, \ - .release = x_scsi_release, \ - .info = x_scsi_info, \ - .command = NULL, \ - .queuecommand = x_scsi_queuecommand, \ - .eh_strategy_handler = NULL, \ - .eh_abort_handler = x_scsi_abort, \ - .eh_device_reset_handler = x_scsi_dev_reset, \ - .eh_bus_reset_handler = x_scsi_bus_reset, \ - .eh_host_reset_handler = x_scsi_host_reset, \ - .bios_param = x_scsi_bios_param, \ - .can_queue = MPT_SCSI_CAN_QUEUE, \ - .this_id = -1, \ - .sg_tablesize = MPT_SCSI_SG_DEPTH, \ - .max_sectors = MPT_SCSI_MAX_SECTORS, \ - .cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \ - .unchecked_isa_dma = 0, \ - .use_clustering = ENABLE_CLUSTERING, \ -} - -#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */ - #define MPT_SCSIHOST { \ .next = NULL, \ PROC_SCSI_DECL \ @@ -346,8 +274,6 @@ .use_new_eh_code = 1 \ } -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */ - #else /* MPT_SCSI_USE_NEW_EH */ #define MPT_SCSIHOST { \ diff -urN linux-2.4.21/drivers/message/fusion/scsi3.h linux-2.4.22/drivers/message/fusion/scsi3.h --- linux-2.4.21/drivers/message/fusion/scsi3.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/message/fusion/scsi3.h 2003-08-25 04:44:42.000000000 -0700 @@ -7,7 +7,7 @@ * Copyright (c) 1996-2002 Steven J. Ralston * Written By: Steven J. Ralston (19960517) * (mailto:sjralston1@netscape.net) - * (mailto:Pam.Delaney@lsil.com) + * (mailto:lstephens@lsil.com) * * $Id: scsi3.h,v 1.9 2002/02/27 18:45:02 sralston Exp $ */ diff -urN linux-2.4.21/drivers/mtd/chips/gen_probe.c linux-2.4.22/drivers/mtd/chips/gen_probe.c --- linux-2.4.21/drivers/mtd/chips/gen_probe.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/mtd/chips/gen_probe.c 2003-08-25 04:44:42.000000000 -0700 @@ -277,6 +277,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001; extern cfi_cmdset_fn_t cfi_cmdset_0002; +extern cfi_cmdset_fn_t cfi_cmdset_0020; static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, int primary) diff -urN linux-2.4.21/drivers/mtd/maps/octagon-5066.c linux-2.4.22/drivers/mtd/maps/octagon-5066.c --- linux-2.4.21/drivers/mtd/maps/octagon-5066.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/mtd/maps/octagon-5066.c 2003-08-25 04:44:42.000000000 -0700 @@ -244,7 +244,6 @@ } if (OctProbe() != 0) { printk(KERN_NOTICE "5066: Octagon Probe Failed, is this an Octagon 5066 SBC?\n"); - iounmap((void *)iomapadr); ret = -EAGAIN; goto out_unmap; } diff -urN linux-2.4.21/drivers/net/3c59x.c linux-2.4.22/drivers/net/3c59x.c --- linux-2.4.21/drivers/net/3c59x.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/3c59x.c 2003-08-25 04:44:42.000000000 -0700 @@ -166,6 +166,11 @@ - Rename wait_for_completion() to issue_and_wait() to avoid completion.h clash. + LK1.1.18ac 01Jul02 akpm + - Fix for undocumented transceiver power-up bit on some 3c566B's + (Donald Becker, Rahul Karnik) + + - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details. - Also see Documentation/networking/vortex.txt */ @@ -181,8 +186,8 @@ #define DRV_NAME "3c59x" -#define DRV_VERSION "LK1.1.16" -#define DRV_RELDATE "19 July 2001" +#define DRV_VERSION "LK1.1.18-ac" +#define DRV_RELDATE "1 July 2002" @@ -400,7 +405,7 @@ EEPROM_8BIT=0x10, /* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */ HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100, INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800, - EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000 }; + EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000 }; enum vortex_chips { CH_3C590 = 0, @@ -424,6 +429,7 @@ CH_3C905B_2, CH_3C905B_FX, CH_3C905C, + CH_3C905C2, CH_3C980, CH_3C9805, @@ -442,6 +448,8 @@ CH_3CCFEM656_1, CH_3C450, CH_3C920, + CH_3C982A, + CH_3C982B, }; @@ -495,10 +503,12 @@ PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c905C Tornado", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + {"3c905C Tornado 2", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c980 Cyclone", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, - {"3c982 Dual Port Server Cyclone", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + {"3c980C Python-T", + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3cSOHO100-TX Hurricane", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, @@ -509,7 +519,7 @@ HAS_HWCKSM, 128, }, {"3c556B Laptop Hurricane", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| - HAS_HWCKSM, 128, }, + WNO_XCVR_PWR|HAS_HWCKSM, 128, }, {"3c575 [Megahertz] 10/100 LAN CardBus", PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, @@ -535,6 +545,11 @@ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c920 Tornado", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + {"3c982 Hydra Dual Port A", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + {"3c982 Hydra Dual Port B", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + {0,}, /* 0 terminated list. */ }; @@ -561,6 +576,7 @@ { 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 }, { 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX }, { 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C }, + { 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C2 }, { 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 }, { 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 }, @@ -579,6 +595,8 @@ { 0x10B7, 0x6564, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFEM656_1 }, { 0x10B7, 0x4500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C450 }, { 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C920 }, + { 0x10B7, 0x1201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982A }, + { 0x10B7, 0x1202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982B }, {0,} /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, vortex_pci_tbl); @@ -1190,6 +1208,10 @@ if (vp->drv_flags & INVERT_MII_PWR) n |= 0x4000; outw(n, ioaddr + Wn2_ResetOptions); + if (vp->drv_flags & WNO_XCVR_PWR) { + EL3WINDOW(0); + outw(0x0800, ioaddr); + } } /* Extract our information from the EEPROM data. */ diff -urN linux-2.4.21/drivers/net/8139cp.c linux-2.4.22/drivers/net/8139cp.c --- linux-2.4.21/drivers/net/8139cp.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/8139cp.c 2003-08-25 04:44:42.000000000 -0700 @@ -1771,7 +1771,6 @@ long pciaddr; unsigned int addr_len, i; u8 pci_rev, cache_size; - u16 pci_command; unsigned int board_type = (unsigned int) ent->driver_data; #ifndef MODULE @@ -1837,7 +1836,7 @@ } /* Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) { + if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) { cp->pci_using_dac = 1; } else { rc = pci_set_dma_mask(pdev, (u64) 0xffffffff); @@ -1929,12 +1928,8 @@ } /* enable busmastering and memory-write-invalidate */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - if (!(pci_command & PCI_COMMAND_INVALIDATE)) { - pci_command |= PCI_COMMAND_INVALIDATE; - pci_write_config_word(pdev, PCI_COMMAND, pci_command); - } pci_set_master(pdev); + pci_set_mwi(pdev); if (cp->wol_enabled) cp_set_d3_state (cp); diff -urN linux-2.4.21/drivers/net/8139too.c linux-2.4.22/drivers/net/8139too.c --- linux-2.4.21/drivers/net/8139too.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/8139too.c 2003-08-25 04:44:42.000000000 -0700 @@ -978,7 +978,7 @@ dev->irq = pdev->irq; - /* dev->priv/tp zeroed and aligned in init_etherdev */ + /* dev->priv/tp zeroed and aligned in alloc_etherdev */ tp = dev->priv; /* note: tp->chipset set in rtl8139_init_board */ @@ -1687,7 +1687,7 @@ entry = tp->cur_tx % NUM_TX_DESC; if (likely(len < TX_BUF_SIZE)) { - if(len < ETH_ZLEN) + if (len < ETH_ZLEN) memset(tp->tx_buf[entry], 0, ETH_ZLEN); skb_copy_and_csum_dev(skb, tp->tx_buf[entry]); dev_kfree_skb(skb); @@ -2074,7 +2074,7 @@ RTL_W16 (IntrStatus, ackstat); DPRINTK ("%s: interrupt status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n", - dev->name, ackstat, status, RTL_R16 (IntrStatus)); + dev->name, status, ackstat, RTL_R16 (IntrStatus)); if (netif_running (dev) && (status & RxAckBits)) rtl8139_rx_interrupt (dev, tp, ioaddr); @@ -2146,7 +2146,7 @@ spin_unlock_irqrestore (&tp->lock, flags); - synchronize_irq (); + synchronize_irq (); /* racy, but that's ok here */ free_irq (dev->irq, dev); rtl8139_tx_clear (tp); diff -urN linux-2.4.21/drivers/net/Config.in linux-2.4.22/drivers/net/Config.in --- linux-2.4.21/drivers/net/Config.in 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/Config.in 2003-08-25 04:44:42.000000000 -0700 @@ -172,6 +172,7 @@ fi dep_tristate ' Apricot Xen-II on board Ethernet' CONFIG_APRICOT $CONFIG_ISA + dep_tristate ' Broadcom 4400 ethernet support (EXPERIMENTAL)' CONFIG_B44 $CONFIG_PCI $CONFIG_EXPERIMENTAL dep_tristate ' CS89x0 support' CONFIG_CS89x0 $CONFIG_ISA dep_tristate ' DECchip Tulip (dc21x4x) PCI support' CONFIG_TULIP $CONFIG_PCI if [ "$CONFIG_TULIP" = "y" -o "$CONFIG_TULIP" = "m" ]; then @@ -209,7 +210,9 @@ if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then tristate ' TI ThunderLAN support' CONFIG_TLAN fi - dep_tristate ' TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_PCI + if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then + dep_tristate ' TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_PCI + fi dep_tristate ' VIA Rhine support' CONFIG_VIA_RHINE $CONFIG_PCI dep_mbool ' Use MMIO instead of PIO (EXPERIMENTAL)' CONFIG_VIA_RHINE_MMIO $CONFIG_VIA_RHINE $CONFIG_EXPERIMENTAL dep_tristate ' Winbond W89c840 Ethernet support' CONFIG_WINBOND_840 $CONFIG_PCI @@ -257,6 +260,9 @@ fi dep_tristate 'D-Link DL2000-based Gigabit Ethernet support' CONFIG_DL2K $CONFIG_PCI dep_tristate 'Intel(R) PRO/1000 Gigabit Ethernet support' CONFIG_E1000 $CONFIG_PCI +if [ "$CONFIG_E1000" != "n" ]; then + bool ' Use Rx Polling (NAPI)' CONFIG_E1000_NAPI +fi dep_tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS $CONFIG_SBUS dep_tristate 'National Semiconductor DP83820 support' CONFIG_NS83820 $CONFIG_PCI dep_tristate 'Packet Engines Hamachi GNIC-II support' CONFIG_HAMACHI $CONFIG_PCI @@ -271,6 +277,10 @@ dep_tristate 'iSeries Virtual Ethernet driver support' CONFIG_VETH $CONFIG_PPC_ISERIES fi +if [ "$CONFIG_4xx" = "y" ]; then + source drivers/net/ibm_emac/Config.in +fi + bool 'FDDI driver support' CONFIG_FDDI if [ "$CONFIG_FDDI" = "y" ]; then if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then @@ -304,8 +314,8 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP fi - if [ ! "$CONFIG_ATM" = "n" ]; then - dep_tristate ' PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP $CONFIG_EXPERIMENTAL + if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then + dep_tristate ' PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP $CONFIG_ATM fi fi diff -urN linux-2.4.21/drivers/net/Makefile linux-2.4.22/drivers/net/Makefile --- linux-2.4.21/drivers/net/Makefile 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -25,10 +25,16 @@ obj-y += tulip/tulip.o endif +obj-$(CONFIG_OCP_NET) += ibm_emac/ocp.o + ifeq ($(CONFIG_E1000),y) obj-y += e1000/e1000.o endif +ifeq ($(CONFIG_BONDING),y) + obj-y += bonding/bonding.o +endif + ifeq ($(CONFIG_ISDN_PPP),y) obj-$(CONFIG_ISDN) += slhc.o endif @@ -36,6 +42,7 @@ subdir-$(CONFIG_NET_PCMCIA) += pcmcia subdir-$(CONFIG_NET_WIRELESS) += wireless subdir-$(CONFIG_TULIP) += tulip +subdir-$(CONFIG_OCP_NET) += ibm_emac subdir-$(CONFIG_IRDA) += irda subdir-$(CONFIG_TR) += tokenring subdir-$(CONFIG_WAN) += wan @@ -46,6 +53,7 @@ subdir-$(CONFIG_SKFP) += skfp subdir-$(CONFIG_E100) += e100 subdir-$(CONFIG_E1000) += e1000 +subdir-$(CONFIG_BONDING) += bonding # # link order important here @@ -143,6 +151,7 @@ obj-$(CONFIG_LNE390) += lne390.o 8390.o obj-$(CONFIG_NE3210) += ne3210.o 8390.o obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o +obj-$(CONFIG_B44) += b44.o obj-$(CONFIG_PPP) += ppp_generic.o slhc.o obj-$(CONFIG_PPP_ASYNC) += ppp_async.o @@ -158,7 +167,6 @@ obj-$(CONFIG_STRIP) += strip.o obj-$(CONFIG_DUMMY) += dummy.o -obj-$(CONFIG_BONDING) += bonding.o obj-$(CONFIG_DE600) += de600.o obj-$(CONFIG_DE620) += de620.o obj-$(CONFIG_AT1500) += lance.o @@ -229,7 +237,7 @@ obj-$(CONFIG_ETHER00) +=ether00.o obj-$(CONFIG_DL2K) += dl2k.o obj-$(CONFIG_R8169) += r8169.o -obj-$(CONFIG_AMD8111_ETH) += amd8111e.o +obj-$(CONFIG_AMD8111_ETH) += amd8111e.o mii.o # non-drivers/net drivers who want mii lib obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o diff -urN linux-2.4.21/drivers/net/Makefile.lib linux-2.4.22/drivers/net/Makefile.lib --- linux-2.4.21/drivers/net/Makefile.lib 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/Makefile.lib 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,76 @@ +# These drivers all require crc32.o +obj-$(CONFIG_8139CP) += crc32.o +obj-$(CONFIG_8139TOO) += crc32.o +obj-$(CONFIG_A2065) += crc32.o +obj-$(CONFIG_ADAPTEC_STARFIRE) += crc32.o +obj-$(CONFIG_AMD8111_ETH) += crc32.o +obj-$(CONFIG_ARM_AM79C961A) += crc32.o +obj-$(CONFIG_AT1700) += crc32.o +obj-$(CONFIG_ATP) += crc32.o +obj-$(CONFIG_BMAC) += crc32.o +obj-$(CONFIG_DE4X5) += crc32.o +obj-$(CONFIG_DECLANCE) += crc32.o +obj-$(CONFIG_DEPCA) += crc32.o +obj-$(CONFIG_DL2K) += crc32.o +obj-$(CONFIG_DM9102) += crc32.o +obj-$(CONFIG_EPIC100) += crc32.o +obj-$(CONFIG_EWRK3) += crc32.o +obj-$(CONFIG_FEALNX) += crc32.o +obj-$(CONFIG_GMAC) += crc32.o +obj-$(CONFIG_HAPPYMEAL) += crc32.o +obj-$(CONFIG_MACE) += crc32.o +obj-$(CONFIG_MACMACE) += crc32.o +obj-$(CONFIG_PCNET32) += crc32.o +obj-$(CONFIG_R8169) += crc32.o +obj-$(CONFIG_SGI_IOC3_ETH) += crc32.o +obj-$(CONFIG_SIS900) += crc32.o +obj-$(CONFIG_SMC9194) += crc32.o +obj-$(CONFIG_SUNBMAC) += crc32.o +obj-$(CONFIG_SUNDANCE) += crc32.o +obj-$(CONFIG_SUNGEM) += crc32.o +obj-$(CONFIG_SUNLANCE) += crc32.o +obj-$(CONFIG_SUNQE) += crc32.o +obj-$(CONFIG_TYPHOON) += crc32.o +obj-$(CONFIG_VIA_RHINE) += crc32.o +obj-$(CONFIG_WINBOND_840) += crc32.o +obj-$(CONFIG_YELLOWFIN) += crc32.o + +# These rely on drivers/net/7990.o which requires crc32.o +obj-$(CONFIG_HPLANCE) += crc32.o +obj-$(CONFIG_MVME147_NET) += crc32.o + +# These rely on drivers/net/8390.o which requires crc32.o +obj-$(CONFIG_OAKNET) += crc32.o +obj-$(CONFIG_NE2K_PCI) += crc32.o +obj-$(CONFIG_STNIC) += crc32.o +obj-$(CONFIG_MAC8390) += crc32.o +obj-$(CONFIG_APNE) += crc32.o +obj-$(CONFIG_PCMCIA_PCNET) += crc32.o +obj-$(CONFIG_ARM_ETHERH) += crc32.o +obj-$(CONFIG_WD80x3) += crc32.o +obj-$(CONFIG_EL2) += crc32.o +obj-$(CONFIG_NE2000) += crc32.o +obj-$(CONFIG_NE2_MCA) += crc32.o +obj-$(CONFIG_HPLAN) += crc32.o +obj-$(CONFIG_HPLAN_PLUS) += crc32.o +obj-$(CONFIG_ULTRA) += crc32.o +obj-$(CONFIG_ULTRAMCA) += crc32.o +obj-$(CONFIG_ULTRA32) += crc32.o +obj-$(CONFIG_E2100) += crc32.o +obj-$(CONFIG_ES3210) += crc32.o +obj-$(CONFIG_LNE390) += crc32.o +obj-$(CONFIG_NE3210) += crc32.o +obj-$(CONFIG_AC3200) += crc32.o +obj-$(CONFIG_ARIADNE2) += crc32.o +obj-$(CONFIG_HYDRA) += crc32.o + +# drivers/net/pcmcia +obj-$(CONFIG_PCMCIA_FMVJ18X) += crc32.o +obj-$(CONFIG_PCMCIA_SMC91C92) += crc32.o +obj-$(CONFIG_PCMCIA_XIRTULIP) += crc32.o + +# drivers/net/tulip +obj-$(CONFIG_TULIP) += crc32.o + +# drivers/net/ibm_emac +obj-$(CONFIG_OCP_NET) += crc32.o diff -urN linux-2.4.21/drivers/net/acenic.c linux-2.4.22/drivers/net/acenic.c --- linux-2.4.21/drivers/net/acenic.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/net/acenic.c 2003-08-25 04:44:42.000000000 -0700 @@ -1865,7 +1865,9 @@ } else { printk(KERN_DEBUG "%s: BUG... transmitter died. Kicking it.\n", dev->name); +#if 0 netif_wake_queue(dev); +#endif } } @@ -3017,9 +3019,6 @@ return 0; case ETHTOOL_SSET: - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - link = readl(®s->GigLnkState); if (link & LNK_1000MB) speed = SPEED_1000; diff -urN linux-2.4.21/drivers/net/amd8111e.c linux-2.4.22/drivers/net/amd8111e.c --- linux-2.4.21/drivers/net/amd8111e.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/amd8111e.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,6 +1,6 @@ /* Advanced Micro Devices Inc. AMD8111E Linux Network Driver - * Copyright (C) 2002 Advanced Micro Devices + * Copyright (C) 2003 Advanced Micro Devices * * * Copyright 2001,2002 Jeff Garzik [ 8139cp.c,tg3.c ] @@ -41,6 +41,20 @@ Kernel Mode Revision History: + 3.0.0 + Initial Revision. + 3.0.1 + 1. Dynamic interrupt coalescing. + 2. Removed prev_stats. + 3. MII support. + 4. Dynamic IPG support + 3.0.2 05/29/2003 + 1. Bug fix: Fixed failure to send jumbo packets larger than 4k. + 2. Bug fix: Fixed VLAN support failure. + 3. Bug fix: Fixed receive interrupt coalescing bug. + 4. Dynamic IPG support is disabled by default. + 3.0.3 06/05/2003 + 1. Bug fix: Fixed failure to close the interface if SMP is enabled. */ @@ -77,13 +91,16 @@ #include "amd8111e.h" #define MODULE_NAME "amd8111e" -#define MODULE_VERSION "3.0.0" +#define MODULE_VERSION "3.0.3" MODULE_AUTHOR("Advanced Micro Devices, Inc."); -MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.0"); +MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.3"); MODULE_LICENSE("GPL"); - MODULE_PARM(speed_duplex, "1-" __MODULE_STRING (MAX_UNITS) "i"); MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex"); +MODULE_PARM(coalesce, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0: Disable"); +MODULE_PARM(dynamic_ipg, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable"); static struct pci_device_id amd8111e_pci_tbl[] __devinitdata = { @@ -92,6 +109,88 @@ { 0, } }; +/* +This function will read the PHY registers. +*/ +static int amd8111e_read_phy(struct amd8111e_priv* lp, int phy_id, int reg, u32* val) +{ + void * mmio = lp->mmio; + unsigned int reg_val; + unsigned int repeat= REPEAT_CNT; + + reg_val = readl(mmio + PHY_ACCESS); + while (reg_val & PHY_CMD_ACTIVE) + reg_val = readl( mmio + PHY_ACCESS ); + + writel( PHY_RD_CMD | ((phy_id & 0x1f) << 21) | + ((reg & 0x1f) << 16), mmio +PHY_ACCESS); + do{ + reg_val = readl(mmio + PHY_ACCESS); + udelay(30); /* It takes 30 us to read/write data */ + } while (--repeat && (reg_val & PHY_CMD_ACTIVE)); + if(reg_val & PHY_RD_ERR) + goto err_phy_read; + + *val = reg_val & 0xffff; + return 0; +err_phy_read: + *val = 0; + return -EINVAL; + +} + +/* +This function will write into PHY registers. +*/ +static int amd8111e_write_phy(struct amd8111e_priv* lp,int phy_id, int reg, u32 val) +{ + unsigned int repeat = REPEAT_CNT + void * mmio = lp->mmio; + unsigned int reg_val; + + reg_val = readl(mmio + PHY_ACCESS); + while (reg_val & PHY_CMD_ACTIVE) + reg_val = readl( mmio + PHY_ACCESS ); + + writel( PHY_WR_CMD | ((phy_id & 0x1f) << 21) | + ((reg & 0x1f) << 16)|val, mmio + PHY_ACCESS); + + do{ + reg_val = readl(mmio + PHY_ACCESS); + udelay(30); /* It takes 30 us to read/write the data */ + } while (--repeat && (reg_val & PHY_CMD_ACTIVE)); + + if(reg_val & PHY_RD_ERR) + goto err_phy_write; + + return 0; + +err_phy_write: + return -EINVAL; + +} +/* +This is the mii register read function provided to the mii interface. +*/ +static int amd8111e_mdio_read(struct net_device * dev, int phy_id, int reg_num) +{ + struct amd8111e_priv* lp = dev->priv; + unsigned int reg_val; + + amd8111e_read_phy(lp,phy_id,reg_num,®_val); + return reg_val; + +} + +/* +This is the mii register write function provided to the mii interface. +*/ +static void amd8111e_mdio_write(struct net_device * dev, int phy_id, int reg_num, int val) +{ + struct amd8111e_priv* lp = dev->priv; + + amd8111e_write_phy(lp, phy_id, reg_num, val); +} /* This function will set PHY speed. During initialization sets the original speed to 100 full. @@ -99,26 +198,39 @@ static void amd8111e_set_ext_phy(struct net_device *dev) { struct amd8111e_priv *lp = (struct amd8111e_priv *)dev->priv; - unsigned long reg_val = 0; - void * mmio = lp->mmio; - struct amd8111e_link_config *link_config = &lp->link_config; + u32 bmcr,advert,tmp; - if(!lp->opened){ - /* Initializing SPEED_100 and DUPLEX_FULL as original values */ - link_config->orig_speed = SPEED_100; - link_config->orig_duplex = DUPLEX_FULL; - link_config->orig_phy_option = XPHYSP |XPHYFD; - } - reg_val = lp->ext_phy_option; - - /* Disable port manager */ - writel((u32) EN_PMGR, mmio + CMD3 ); + /* Determine mii register values to set the speed */ + advert = amd8111e_mdio_read(dev, PHY_ID, MII_ADVERTISE); + tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4); + switch (lp->ext_phy_option){ + + default: + case SPEED_AUTONEG: /* advertise all values */ + tmp |= ( ADVERTISE_10HALF|ADVERTISE_10FULL| + ADVERTISE_100HALF|ADVERTISE_100FULL) ; + break; + case SPEED10_HALF: + tmp |= ADVERTISE_10HALF; + break; + case SPEED10_FULL: + tmp |= ADVERTISE_10FULL; + break; + case SPEED100_HALF: + tmp |= ADVERTISE_100HALF; + break; + case SPEED100_FULL: + tmp |= ADVERTISE_100FULL; + break; + } + + if(advert != tmp) + amd8111e_mdio_write(dev, PHY_ID, MII_ADVERTISE, tmp); + /* Restart auto negotiation */ + bmcr = amd8111e_mdio_read(dev, PHY_ID, MII_BMCR); + bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); + amd8111e_mdio_write(dev, PHY_ID, MII_BMCR, bmcr); - /* Reset PHY */ - writel((u32)XPHYRST | lp->ext_phy_option, mmio + CTRL2); - - /* Enable port manager */ - writel((u32)VAL1 | EN_PMGR, mmio + CMD3 ); } /* @@ -156,7 +268,7 @@ } /* - This will set the receive buffer length corresponding to the mtu size of network interface. +This will set the receive buffer length corresponding to the mtu size of networkinterface. */ static inline void amd8111e_set_rx_buff_len(struct net_device* dev) { @@ -226,13 +338,13 @@ lp->rx_ring[i].buff_phy_addr = cpu_to_le32(lp->rx_dma_addr[i]); lp->rx_ring[i].buff_count = cpu_to_le16(lp->rx_buff_len); - lp->rx_ring[i].rx_dr_offset10 = cpu_to_le16(OWN_BIT); + lp->rx_ring[i].rx_flags = cpu_to_le16(OWN_BIT); } /* Initializing transmit descriptors */ for (i = 0; i < NUM_TX_RING_DR; i++) { lp->tx_ring[i].buff_phy_addr = 0; - lp->tx_ring[i].tx_dr_offset2 = 0; + lp->tx_ring[i].tx_flags = 0; lp->tx_ring[i].buff_count = 0; } @@ -253,6 +365,65 @@ err_no_mem: return -ENOMEM; } +/* This function will set the interrupt coalescing according to the input arguments */ +static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod) +{ + unsigned int timeout; + unsigned int event_count; + + struct amd8111e_priv *lp = dev->priv; + void* mmio = lp->mmio; + struct amd8111e_coalesce_conf * coal_conf = &lp->coal_conf; + + + switch(cmod) + { + case RX_INTR_COAL : + timeout = coal_conf->rx_timeout; + event_count = coal_conf->rx_event_count; + if( timeout > MAX_TIMEOUT || + event_count > MAX_EVENT_COUNT ) + return -EINVAL; + + timeout = timeout * DELAY_TIMER_CONV; + writel(VAL0|STINTEN, mmio+INTEN0); + writel((u32)DLY_INT_A_R0|( event_count<< 16 )|timeout, + mmio+DLY_INT_A); + break; + + case TX_INTR_COAL : + timeout = coal_conf->tx_timeout; + event_count = coal_conf->tx_event_count; + if( timeout > MAX_TIMEOUT || + event_count > MAX_EVENT_COUNT ) + return -EINVAL; + + + timeout = timeout * DELAY_TIMER_CONV; + writel(VAL0|STINTEN,mmio+INTEN0); + writel((u32)DLY_INT_B_T0|( event_count<< 16 )|timeout, + mmio+DLY_INT_B); + break; + + case DISABLE_COAL: + writel(0,mmio+STVAL); + writel(STINTEN, mmio+INTEN0); + writel(0, mmio +DLY_INT_B); + writel(0, mmio+DLY_INT_A); + break; + case ENABLE_COAL: + /* Start the timer */ + writel((u32)SOFT_TIMER_FREQ, mmio+STVAL); /* 0.5 sec */ + writel(VAL0|STINTEN, mmio+INTEN0); + break; + default: + break; + + } + return 0; + +} + /* This function initializes the device registers and starts the device. */ @@ -267,13 +438,17 @@ if(amd8111e_init_ring(dev)) return -ENOMEM; + + /* enable the port manager and set auto negotiation always */ + writel((u32) VAL1|EN_PMGR, mmio + CMD3 ); + writel((u32)XPHYANE|XPHYRST , mmio + CTRL2); amd8111e_set_ext_phy(dev); /* set control registers */ reg_val = readl(mmio + CTRL1); - - writel( reg_val| XMTSP_128 | CACHE_ALIGN | B1_MASK, mmio + CTRL1 ); + reg_val &= ~XMTSP_MASK; + writel( reg_val| XMTSP_128 | CACHE_ALIGN, mmio + CTRL1 ); /* enable interrupt */ writel( APINT5EN | APINT4EN | APINT3EN | APINT2EN | APINT1EN | @@ -288,15 +463,21 @@ writew((u32)NUM_TX_RING_DR, mmio + XMT_RING_LEN0); writew((u16)NUM_RX_RING_DR, mmio + RCV_RING_LEN0); + + /* set default IPG to 96 */ + writew((u32)DEFAULT_IPG,mmio+IPG); + writew((u32)(DEFAULT_IPG-IFS1_DELTA), mmio + IFS1); if(lp->options & OPTION_JUMBO_ENABLE){ writel((u32)VAL2|JUMBO, mmio + CMD3); /* Reset REX_UFLO */ writel( REX_UFLO, mmio + CMD2); /* Should not set REX_UFLO for jumbo frames */ - writel( VAL0 | APAD_XMT | REX_RTRY, mmio + CMD2); - }else + writel( VAL0 | APAD_XMT|REX_RTRY , mmio + CMD2); + }else{ writel( VAL0 | APAD_XMT | REX_RTRY|REX_UFLO, mmio + CMD2); + writel((u32)JUMBO, mmio + CMD3); + } #if AMD8111E_VLAN_TAG_USED writel((u32) VAL2|VSIZE|VL_TAG_DEL, mmio + CMD3); @@ -306,11 +487,20 @@ /* Setting the MAC address to the device */ for(i = 0; i < ETH_ADDR_LEN; i++) writeb( dev->dev_addr[i], mmio + PADR + i ); + + /* Enable interrupt coalesce */ + if(lp->options & OPTION_INTR_COAL_ENABLE){ + printk(KERN_INFO "%s: Interrupt Coalescing Enabled.\n", + dev->name); + amd8111e_set_coalesce(dev,ENABLE_COAL); + } /* set RUN bit to start the chip */ writel(VAL2 | RDMD0, mmio + CMD0); writel(VAL0 | INTREN | RUN, mmio + CMD0); + /* To avoid PCI posting bug */ + readl(mmio+CMD0); return 0; } /* @@ -383,7 +573,7 @@ writew(MIB_CLEAR, mmio + MIB_ADDR); /* Clear LARF */ - AMD8111E_WRITE_REG64(mmio, LADRF,logic_filter); + amd8111e_writeq(*(u64*)logic_filter,mmio+LADRF); /* SRAM_SIZE register */ reg_val = readl(mmio + SRAM_SIZE); @@ -393,8 +583,11 @@ #if AMD8111E_VLAN_TAG_USED writel(VAL2|VSIZE|VL_TAG_DEL, mmio + CMD3 ); #endif - /* CMD2 register */ - reg_val = readl(mmio + CMD2); + /* Set default value to CTRL1 Register */ + writel(CTRL1_DEFAULT, mmio + CTRL1); + + /* To avoid PCI posting bug */ + readl(mmio + CMD2); } @@ -412,6 +605,9 @@ /* Clear INT0 */ intr0 = readl(lp->mmio + INT0); writel(intr0, lp->mmio + INT0); + + /* To avoid PCI posting bug */ + readl(lp->mmio + INT0); } @@ -421,6 +617,9 @@ static void amd8111e_stop_chip(struct amd8111e_priv* lp) { writel(RUN, lp->mmio + CMD0); + + /* To avoid PCI posting bug */ + readl(lp->mmio + CMD0); } /* @@ -467,11 +666,10 @@ struct amd8111e_priv* lp = dev->priv; int tx_index = lp->tx_complete_idx & TX_RING_DR_MOD_MASK; int status; - /* Complete all the transmit packet */ while (lp->tx_complete_idx != lp->tx_idx){ tx_index = lp->tx_complete_idx & TX_RING_DR_MOD_MASK; - status = le16_to_cpu(lp->tx_ring[tx_index].tx_dr_offset2); + status = le16_to_cpu(lp->tx_ring[tx_index].tx_flags); if(status & OWN_BIT) break; /* It still hasn't been Txed */ @@ -487,11 +685,15 @@ lp->tx_skbuff[tx_index] = 0; lp->tx_dma_addr[tx_index] = 0; } - lp->tx_complete_idx++; + lp->tx_complete_idx++; + /*COAL update tx coalescing parameters */ + lp->coal_conf.tx_packets++; + lp->coal_conf.tx_bytes += lp->tx_ring[tx_index].buff_count; if (netif_queue_stopped(dev) && lp->tx_complete_idx > lp->tx_idx - NUM_TX_BUFFERS +2){ /* The ring is no longer full, clear tbusy. */ + /* lp->tx_full = 0; */ netif_wake_queue (dev); } } @@ -516,33 +718,31 @@ /* If we own the next entry, it's a new packet. Send it up. */ while(++num_rx_pkt <= max_rx_pkt){ - if(lp->rx_ring[rx_index].rx_dr_offset10 & OWN_BIT) + if(lp->rx_ring[rx_index].rx_flags & OWN_BIT) return 0; /* check if err summary bit is set */ - if(le16_to_cpu(lp->rx_ring[rx_index].rx_dr_offset10) & ERR_BIT){ + if(le16_to_cpu(lp->rx_ring[rx_index].rx_flags) & ERR_BIT){ /* * There is a tricky error noted by John Murphy, * to Russ Nelson: Even with full-sized * buffers it's possible for a jabber packet to use two * buffers, with only the last correctly noting the error. */ /* reseting flags */ - lp->rx_ring[rx_index].rx_dr_offset10 &= - cpu_to_le16(RESET_RX_FLAGS); + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; goto err_next_pkt; } /* check for STP and ENP */ - status = le16_to_cpu(lp->rx_ring[rx_index].rx_dr_offset10); + status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags); if(!((status & STP_BIT) && (status & ENP_BIT))){ /* reseting flags */ - lp->rx_ring[rx_index].rx_dr_offset10 &= - cpu_to_le16(RESET_RX_FLAGS); + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; goto err_next_pkt; } pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4; #if AMD8111E_VLAN_TAG_USED - vtag = le16_to_cpu(lp->rx_ring[rx_index].rx_dr_offset10) & TT_MASK; + vtag = le16_to_cpu(lp->rx_ring[rx_index].rx_flags) & TT_MASK; /*MAC will strip vlan tag*/ if(lp->vlgrp != NULL && vtag !=0) min_pkt_len =MIN_PKT_LEN - 4; @@ -551,16 +751,14 @@ min_pkt_len =MIN_PKT_LEN; if (pkt_len < min_pkt_len) { - lp->rx_ring[rx_index].rx_dr_offset10 &= - cpu_to_le16(RESET_RX_FLAGS); + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; lp->stats.rx_errors++; goto err_next_pkt; } if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){ /* if allocation fail, ignore that pkt and go to next one */ - lp->rx_ring[rx_index].rx_dr_offset10 &= - cpu_to_le16(RESET_RX_FLAGS); + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; lp->stats.rx_errors++; goto err_next_pkt; } @@ -580,22 +778,26 @@ #if AMD8111E_VLAN_TAG_USED - vtag = lp->rx_ring[rx_index].rx_dr_offset10 & TT_MASK; + vtag = lp->rx_ring[rx_index].rx_flags & TT_MASK; if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){ amd8111e_vlan_rx(lp, skb, lp->rx_ring[rx_index].tag_ctrl_info); } else #endif - dev->last_rx = jiffies; netif_rx (skb); + /*COAL update rx coalescing parameters*/ + lp->coal_conf.rx_packets++; + lp->coal_conf.rx_bytes += pkt_len; + + dev->last_rx = jiffies; err_next_pkt: lp->rx_ring[rx_index].buff_phy_addr = cpu_to_le32(lp->rx_dma_addr[rx_index]); lp->rx_ring[rx_index].buff_count = cpu_to_le16(lp->rx_buff_len-2); - lp->rx_ring[rx_index].rx_dr_offset10 |= cpu_to_le16(OWN_BIT); + lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT); rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK; } @@ -603,8 +805,8 @@ } /* -This function will store the original speed to restore later, if autoneg is turned on. This speed will be set later when the autoneg is turned off. If the link status indicates that link is down, that will be indicated to the kernel */ - +This function will indicate the link status to the kernel. +*/ static int amd8111e_link_change(struct net_device* dev) { struct amd8111e_priv *lp = dev->priv; @@ -614,21 +816,11 @@ status0 = readl(lp->mmio + STAT0); if(status0 & LINK_STATS){ - if(status0 & AUTONEG_COMPLETE){ - /* keeping the original speeds */ - if((lp->link_config.speed != SPEED_INVALID)&& - (lp->link_config.duplex != DUPLEX_INVALID)){ - lp->link_config.orig_speed = lp->link_config.speed; - lp->link_config.orig_duplex = lp->link_config.duplex; - lp->link_config.orig_phy_option = lp->ext_phy_option; - } - - lp->link_config.speed = SPEED_INVALID; - lp->link_config.duplex = DUPLEX_INVALID; + if(status0 & AUTONEG_COMPLETE) lp->link_config.autoneg = AUTONEG_ENABLE; - netif_carrier_on(dev); - return 0; - } + else + lp->link_config.autoneg = AUTONEG_DISABLE; + if(status0 & FULL_DPLX) lp->link_config.duplex = DUPLEX_FULL; else @@ -638,13 +830,17 @@ lp->link_config.speed = SPEED_10; else if(speed == PHY_SPEED_100) lp->link_config.speed = SPEED_100; - lp->link_config.autoneg = AUTONEG_DISABLE; + + printk(KERN_INFO "%s: Link is Up. Speed is %s Mbps %s Duplex\n", dev->name, + (lp->link_config.speed == SPEED_100) ? "100": "10", + (lp->link_config.duplex == DUPLEX_FULL)? "Full": "Half"); netif_carrier_on(dev); } else{ lp->link_config.speed = SPEED_INVALID; lp->link_config.duplex = DUPLEX_INVALID; lp->link_config.autoneg = AUTONEG_INVALID; + printk(KERN_INFO "%s: Link is Down.\n",dev->name); netif_carrier_off(dev); } @@ -671,114 +867,236 @@ } /* -This function retuurns the reads the mib registers and returns the hardware statistics. It adds the previous statistics with new values.*/ +This function reads the mib registers and returns the hardware statistics. It updates previous internal driver statistics with new values. +*/ static struct net_device_stats *amd8111e_get_stats(struct net_device * dev) { struct amd8111e_priv *lp = dev->priv; void * mmio = lp->mmio; unsigned long flags; - struct net_device_stats *prev_stats = &lp->prev_stats; + /* struct net_device_stats *prev_stats = &lp->prev_stats; */ struct net_device_stats* new_stats = &lp->stats; if(!lp->opened) - return prev_stats; + return &lp->stats; spin_lock_irqsave (&lp->lock, flags); /* stats.rx_packets */ - new_stats->rx_packets = prev_stats->rx_packets+ - amd8111e_read_mib(mmio, rcv_broadcast_pkts)+ - amd8111e_read_mib(mmio, rcv_multicast_pkts)+ - amd8111e_read_mib(mmio, rcv_unicast_pkts); + new_stats->rx_packets = amd8111e_read_mib(mmio, rcv_broadcast_pkts)+ + amd8111e_read_mib(mmio, rcv_multicast_pkts)+ + amd8111e_read_mib(mmio, rcv_unicast_pkts); /* stats.tx_packets */ - new_stats->tx_packets = prev_stats->tx_packets+ - amd8111e_read_mib(mmio, xmt_packets); + new_stats->tx_packets = amd8111e_read_mib(mmio, xmt_packets); /*stats.rx_bytes */ - new_stats->rx_bytes = prev_stats->rx_bytes+ - amd8111e_read_mib(mmio, rcv_octets); + new_stats->rx_bytes = amd8111e_read_mib(mmio, rcv_octets); /* stats.tx_bytes */ - new_stats->tx_bytes = prev_stats->tx_bytes+ - amd8111e_read_mib(mmio, xmt_octets); + new_stats->tx_bytes = amd8111e_read_mib(mmio, xmt_octets); /* stats.rx_errors */ - new_stats->rx_errors = prev_stats->rx_errors+ - amd8111e_read_mib(mmio, rcv_undersize_pkts)+ - amd8111e_read_mib(mmio, rcv_fragments)+ - amd8111e_read_mib(mmio, rcv_jabbers)+ - amd8111e_read_mib(mmio, rcv_alignment_errors)+ - amd8111e_read_mib(mmio, rcv_fcs_errors)+ - amd8111e_read_mib(mmio, rcv_miss_pkts); + new_stats->rx_errors = amd8111e_read_mib(mmio, rcv_undersize_pkts)+ + amd8111e_read_mib(mmio, rcv_fragments)+ + amd8111e_read_mib(mmio, rcv_jabbers)+ + amd8111e_read_mib(mmio, rcv_alignment_errors)+ + amd8111e_read_mib(mmio, rcv_fcs_errors)+ + amd8111e_read_mib(mmio, rcv_miss_pkts); /* stats.tx_errors */ - new_stats->tx_errors = prev_stats->tx_errors+ - amd8111e_read_mib(mmio, xmt_underrun_pkts); + new_stats->tx_errors = amd8111e_read_mib(mmio, xmt_underrun_pkts); /* stats.rx_dropped*/ - new_stats->rx_dropped = prev_stats->rx_dropped+ - amd8111e_read_mib(mmio, rcv_miss_pkts); + new_stats->rx_dropped = amd8111e_read_mib(mmio, rcv_miss_pkts); /* stats.tx_dropped*/ - new_stats->tx_dropped = prev_stats->tx_dropped+ - amd8111e_read_mib(mmio, xmt_underrun_pkts); + new_stats->tx_dropped = amd8111e_read_mib(mmio, xmt_underrun_pkts); /* stats.multicast*/ - new_stats->multicast = prev_stats->multicast+ - amd8111e_read_mib(mmio, rcv_multicast_pkts); + new_stats->multicast = amd8111e_read_mib(mmio, rcv_multicast_pkts); /* stats.collisions*/ - new_stats->collisions = prev_stats->collisions+ - amd8111e_read_mib(mmio, xmt_collisions); + new_stats->collisions = amd8111e_read_mib(mmio, xmt_collisions); /* stats.rx_length_errors*/ - new_stats->rx_length_errors = prev_stats->rx_length_errors+ + new_stats->rx_length_errors = amd8111e_read_mib(mmio, rcv_undersize_pkts)+ amd8111e_read_mib(mmio, rcv_oversize_pkts); /* stats.rx_over_errors*/ - new_stats->rx_over_errors = prev_stats->rx_over_errors+ - amd8111e_read_mib(mmio, rcv_miss_pkts); + new_stats->rx_over_errors = amd8111e_read_mib(mmio, rcv_miss_pkts); /* stats.rx_crc_errors*/ - new_stats->rx_crc_errors = prev_stats->rx_crc_errors+ - amd8111e_read_mib(mmio, rcv_fcs_errors); + new_stats->rx_crc_errors = amd8111e_read_mib(mmio, rcv_fcs_errors); /* stats.rx_frame_errors*/ - new_stats->rx_frame_errors = prev_stats->rx_frame_errors+ + new_stats->rx_frame_errors = amd8111e_read_mib(mmio, rcv_alignment_errors); /* stats.rx_fifo_errors */ - new_stats->rx_fifo_errors = prev_stats->rx_fifo_errors+ - amd8111e_read_mib(mmio, rcv_miss_pkts); + new_stats->rx_fifo_errors = amd8111e_read_mib(mmio, rcv_miss_pkts); /* stats.rx_missed_errors */ - new_stats->rx_missed_errors = prev_stats->rx_missed_errors+ - amd8111e_read_mib(mmio, rcv_miss_pkts); + new_stats->rx_missed_errors = amd8111e_read_mib(mmio, rcv_miss_pkts); /* stats.tx_aborted_errors*/ - new_stats->tx_aborted_errors = prev_stats->tx_aborted_errors+ + new_stats->tx_aborted_errors = amd8111e_read_mib(mmio, xmt_excessive_collision); /* stats.tx_carrier_errors*/ - new_stats->tx_carrier_errors = prev_stats->tx_carrier_errors+ + new_stats->tx_carrier_errors = amd8111e_read_mib(mmio, xmt_loss_carrier); /* stats.tx_fifo_errors*/ - new_stats->tx_fifo_errors = prev_stats->tx_fifo_errors+ - amd8111e_read_mib(mmio, xmt_underrun_pkts); + new_stats->tx_fifo_errors = amd8111e_read_mib(mmio, xmt_underrun_pkts); /* stats.tx_window_errors*/ - new_stats->tx_window_errors = prev_stats->tx_window_errors+ + new_stats->tx_window_errors = amd8111e_read_mib(mmio, xmt_late_collision); + /* Reset the mibs for collecting new statistics */ + /* writew(MIB_CLEAR, mmio + MIB_ADDR);*/ + spin_unlock_irqrestore (&lp->lock, flags); return new_stats; } +/* This function recalculate the interupt coalescing mode on every interrupt +according to the datarate and the packet rate. +*/ +static int amd8111e_calc_coalesce(struct net_device *dev) +{ + struct amd8111e_priv *lp = dev->priv; + struct amd8111e_coalesce_conf * coal_conf = &lp->coal_conf; + int tx_pkt_rate; + int rx_pkt_rate; + int tx_data_rate; + int rx_data_rate; + int rx_pkt_size; + int tx_pkt_size; + + tx_pkt_rate = coal_conf->tx_packets - coal_conf->tx_prev_packets; + coal_conf->tx_prev_packets = coal_conf->tx_packets; + + tx_data_rate = coal_conf->tx_bytes - coal_conf->tx_prev_bytes; + coal_conf->tx_prev_bytes = coal_conf->tx_bytes; + + rx_pkt_rate = coal_conf->rx_packets - coal_conf->rx_prev_packets; + coal_conf->rx_prev_packets = coal_conf->rx_packets; + + rx_data_rate = coal_conf->rx_bytes - coal_conf->rx_prev_bytes; + coal_conf->rx_prev_bytes = coal_conf->rx_bytes; + + if(rx_pkt_rate < 800){ + if(coal_conf->rx_coal_type != NO_COALESCE){ + + coal_conf->rx_timeout = 0x0; + coal_conf->rx_event_count = 0; + amd8111e_set_coalesce(dev,RX_INTR_COAL); + coal_conf->rx_coal_type = NO_COALESCE; + } + } + else{ + + rx_pkt_size = rx_data_rate/rx_pkt_rate; + if (rx_pkt_size < 128){ + if(coal_conf->rx_coal_type != NO_COALESCE){ + + coal_conf->rx_timeout = 0; + coal_conf->rx_event_count = 0; + amd8111e_set_coalesce(dev,RX_INTR_COAL); + coal_conf->rx_coal_type = NO_COALESCE; + } + } + else if ( (rx_pkt_size >= 128) && (rx_pkt_size < 512) ){ + + if(coal_conf->rx_coal_type != LOW_COALESCE){ + coal_conf->rx_timeout = 1; + coal_conf->rx_event_count = 4; + amd8111e_set_coalesce(dev,RX_INTR_COAL); + coal_conf->rx_coal_type = LOW_COALESCE; + } + } + else if ((rx_pkt_size >= 512) && (rx_pkt_size < 1024)){ + + if(coal_conf->rx_coal_type != MEDIUM_COALESCE){ + coal_conf->rx_timeout = 1; + coal_conf->rx_event_count = 4; + amd8111e_set_coalesce(dev,RX_INTR_COAL); + coal_conf->rx_coal_type = MEDIUM_COALESCE; + } + + } + else if(rx_pkt_size >= 1024){ + if(coal_conf->rx_coal_type != HIGH_COALESCE){ + coal_conf->rx_timeout = 2; + coal_conf->rx_event_count = 3; + amd8111e_set_coalesce(dev,RX_INTR_COAL); + coal_conf->rx_coal_type = HIGH_COALESCE; + } + } + } + /* NOW FOR TX INTR COALESC */ + if(tx_pkt_rate < 800){ + if(coal_conf->tx_coal_type != NO_COALESCE){ + + coal_conf->tx_timeout = 0x0; + coal_conf->tx_event_count = 0; + amd8111e_set_coalesce(dev,TX_INTR_COAL); + coal_conf->tx_coal_type = NO_COALESCE; + } + } + else{ + + tx_pkt_size = tx_data_rate/tx_pkt_rate; + if (tx_pkt_size < 128){ + + if(coal_conf->tx_coal_type != NO_COALESCE){ + + coal_conf->tx_timeout = 0; + coal_conf->tx_event_count = 0; + amd8111e_set_coalesce(dev,TX_INTR_COAL); + coal_conf->tx_coal_type = NO_COALESCE; + } + + } + else if ( (tx_pkt_size >= 128) && (tx_pkt_size < 512) ){ + + if(coal_conf->tx_coal_type != LOW_COALESCE){ + coal_conf->tx_timeout = 1; + coal_conf->tx_event_count = 2; + amd8111e_set_coalesce(dev,TX_INTR_COAL); + coal_conf->tx_coal_type = LOW_COALESCE; + + } + } + else if ((tx_pkt_size >= 512) && (tx_pkt_size < 1024)){ + + if(coal_conf->tx_coal_type != MEDIUM_COALESCE){ + coal_conf->tx_timeout = 2; + coal_conf->tx_event_count = 5; + amd8111e_set_coalesce(dev,TX_INTR_COAL); + coal_conf->tx_coal_type = MEDIUM_COALESCE; + } + + } + else if(tx_pkt_size >= 1024){ + if (tx_pkt_size >= 1024){ + if(coal_conf->tx_coal_type != HIGH_COALESCE){ + coal_conf->tx_timeout = 4; + coal_conf->tx_event_count = 8; + amd8111e_set_coalesce(dev,TX_INTR_COAL); + coal_conf->tx_coal_type = HIGH_COALESCE; + } + } + } + } + return 0; + +} /* -This is device interrupt function. It handles transmit, receive and link change interrupts. +This is device interrupt function. It handles transmit, receive,link change and hardware timer interrupts. */ static void amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -791,7 +1109,7 @@ if(dev == NULL) return; - spin_lock (&lp->lock); + if (regs) spin_lock (&lp->lock); /* disabling interrupt */ writel(INTREN, mmio + CMD0); @@ -819,15 +1137,20 @@ /* Check if Link Change Interrupt has occurred. */ if (intr0 & LCINT) amd8111e_link_change(dev); - + + /* Check if Hardware Timer Interrupt has occurred. */ + if (intr0 & STINT) + amd8111e_calc_coalesce(dev); + err_no_interrupt: writel( VAL0 | INTREN,mmio + CMD0); - spin_unlock(&lp->lock); - return; - + + if (regs) spin_unlock(&lp->lock); + } + /* -This function closes the network interface and copies the new set of statistics into the previous statistics structure so that most recent statistics will be available after the interface is down. +This function closes the network interface and updates the statistics so that most recent statistics will be available after the interface is down. */ static int amd8111e_close(struct net_device * dev) { @@ -842,10 +1165,15 @@ netif_carrier_off(lp->amd8111e_net_dev); - spin_unlock_irq(&lp->lock); + /* Delete ipg timer */ + if(lp->options & OPTION_DYN_IPG_ENABLE) + del_timer_sync(&lp->ipg_data.ipg_timer); + spin_unlock_irq(&lp->lock); free_irq(dev->irq, dev); - memcpy(&lp->prev_stats,amd8111e_get_stats(dev), sizeof(lp->prev_stats)); + + /* Update the statistics before closing */ + amd8111e_get_stats(dev); lp->opened = 0; return 0; } @@ -867,7 +1195,12 @@ spin_unlock_irq(&lp->lock); return -ENOMEM; } - + /* Start ipg timer */ + if(lp->options & OPTION_DYN_IPG_ENABLE){ + add_timer(&lp->ipg_data.ipg_timer); + printk(KERN_INFO "%s: Dynamic IPG Enabled.\n",dev->name); + } + lp->opened = 1; spin_unlock_irq(&lp->lock); @@ -905,11 +1238,10 @@ lp->tx_ring[tx_index].buff_count = cpu_to_le16(skb->len); lp->tx_skbuff[tx_index] = skb; - lp->tx_ring[tx_index].tx_dr_offset2 = 0; + lp->tx_ring[tx_index].tx_flags = 0; #if AMD8111E_VLAN_TAG_USED if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){ - lp->tx_ring[tx_index].tag_ctrl_cmd |= cpu_to_le32(TCC_VLAN_INSERT); lp->tx_ring[tx_index].tag_ctrl_info = @@ -923,7 +1255,7 @@ (u32) cpu_to_le32(lp->tx_dma_addr[tx_index]); /* Set FCS and LTINT bits */ - lp->tx_ring[tx_index].tx_dr_offset2 |= + lp->tx_ring[tx_index].tx_flags |= cpu_to_le16(OWN_BIT | STP_BIT | ENP_BIT|ADD_FCS_BIT|LTINT_BIT); lp->tx_idx++; @@ -946,16 +1278,54 @@ static char* amd8111e_read_regs(struct amd8111e_priv* lp) { void * mmio = lp->mmio; - unsigned char * reg_buff; + u32 * reg_buff; - int i; - reg_buff = kmalloc( AMD8111E_REG_DUMP_LEN,GFP_KERNEL); if(NULL == reg_buff) return NULL; - for (i=0; i < AMD8111E_REG_DUMP_LEN; i+=4) - reg_buff[i]= readl(mmio + i); - return reg_buff; + + /* Read only necessary registers */ + reg_buff[0] = readl(mmio + XMT_RING_BASE_ADDR0); + reg_buff[1] = readl(mmio + XMT_RING_LEN0); + reg_buff[2] = readl(mmio + RCV_RING_BASE_ADDR0); + reg_buff[3] = readl(mmio + RCV_RING_LEN0); + reg_buff[4] = readl(mmio + CMD0); + reg_buff[5] = readl(mmio + CMD2); + reg_buff[6] = readl(mmio + CMD3); + reg_buff[7] = readl(mmio + CMD7); + reg_buff[8] = readl(mmio + INT0); + reg_buff[9] = readl(mmio + INTEN0); + reg_buff[10] = readl(mmio + LADRF); + reg_buff[11] = readl(mmio + LADRF+4); + reg_buff[12] = readl(mmio + STAT0); + + return (char *)reg_buff; +} +/* +amd8111e crc generator implementation is different from the kernel +ether_crc() function. +*/ +int amd8111e_ether_crc(int len, char* mac_addr) +{ + int i,byte; + unsigned char octet; + u32 crc= INITCRC; + + for(byte=0; byte < len; byte++){ + octet = mac_addr[byte]; + for( i=0;i < 8; i++){ + /*If the next bit form the input stream is 1,subtract the divisor (CRC32) from the dividend(crc).*/ + if( (octet & 0x1) ^ (crc & 0x1) ){ + crc >>= 1; + crc ^= CRC32; + } + else + crc >>= 1; + + octet >>= 1; + } + } + return crc; } /* This function sets promiscuos mode, all-multi mode or the multicast address @@ -967,9 +1337,8 @@ struct amd8111e_priv *lp = dev->priv; u32 mc_filter[2] ; int i,bit_num; - if(dev->flags & IFF_PROMISC){ - printk("%s: Setting promiscuous mode.\n",dev->name); + printk(KERN_INFO "%s: Setting promiscuous mode.\n",dev->name); writel( VAL2 | PROM, lp->mmio + CMD2); return; } @@ -980,7 +1349,7 @@ mc_filter[1] = mc_filter[0] = 0xffffffff; lp->mc_list = dev->mc_list; lp->options |= OPTION_MULTICAST_ENABLE; - AMD8111E_WRITE_REG64(lp->mmio, LADRF,mc_filter); + amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF); return; } if( dev->mc_count == 0 ){ @@ -988,7 +1357,7 @@ mc_filter[1] = mc_filter[0] = 0; lp->mc_list = 0; lp->options &= ~OPTION_MULTICAST_ENABLE; - AMD8111E_WRITE_REG64(lp->mmio, LADRF,mc_filter); + amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF); /* disable promiscous mode */ writel(PROM, lp->mmio + CMD2); return; @@ -999,14 +1368,16 @@ mc_filter[1] = mc_filter[0] = 0; for (i = 0, mc_ptr = dev->mc_list; mc_ptr && i < dev->mc_count; i++, mc_ptr = mc_ptr->next) { - bit_num = ether_crc(ETH_ALEN, mc_ptr->dmi_addr) >> 26; - + bit_num = ( amd8111e_ether_crc(ETH_ALEN,mc_ptr->dmi_addr) >> 26 ) & 0x3f; mc_filter[bit_num >> 5] |= 1 << (bit_num & 31); } + amd8111e_writeq(*(u64*)mc_filter,lp->mmio+ LADRF); + + /* To eliminate PCI posting bug */ + readl(lp->mmio + CMD2); - AMD8111E_WRITE_REG64(lp->mmio, LADRF, mc_filter); - return; } + /* This function handles all the ethtool ioctls. It gives driver info, gets/sets driver speed, gets memory mapped register values, forces auto negotiation, sets/gets WOL options for ethtool application. */ @@ -1029,6 +1400,7 @@ strcpy (info.driver, MODULE_NAME); strcpy (info.version, MODULE_VERSION); memset(&info.fw_version, 0, sizeof(info.fw_version)); + sprintf(info.fw_version,"%u",chip_version); strcpy (info.bus_info, pci_dev->slot_name); info.eedump_len = 0; info.regdump_len = AMD8111E_REG_DUMP_LEN; @@ -1036,85 +1408,27 @@ return -EFAULT; return 0; } - case ETHTOOL_GSET:{ - struct ethtool_cmd cmd = { ETHTOOL_GSET }; - - if (!lp->opened) - return -EAGAIN; - - cmd.supported = SUPPORTED_Autoneg | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_MII; - - cmd.advertising = ADVERTISED_Autoneg | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_MII; - cmd.speed = lp->link_config.speed; - cmd.duplex = lp->link_config.duplex; - cmd.port = 0; - cmd.phy_address = PHY_ID; - cmd.transceiver = XCVR_EXTERNAL; - cmd.autoneg = lp->link_config.autoneg; - cmd.maxtxpkt = 0; /* not implemented interrupt coalasing */ - cmd.maxrxpkt = 0; /* not implemented interrupt coalasing */ - if (copy_to_user(useraddr, &cmd, sizeof(cmd))) + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&lp->lock); + mii_ethtool_gset(&lp->mii_if, &ecmd); + spin_unlock_irq(&lp->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) return -EFAULT; return 0; - } + } + /* set settings */ case ETHTOOL_SSET: { - - struct ethtool_cmd cmd; - - if (!lp->opened) - return -EAGAIN; - if (copy_from_user(&cmd, useraddr, sizeof(cmd))) + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) return -EFAULT; spin_lock_irq(&lp->lock); - - if(cmd.autoneg == AUTONEG_ENABLE){ - /* keeping the original speeds */ - if((lp->link_config.speed != SPEED_INVALID)&& - (lp->link_config.duplex != DUPLEX_INVALID)){ - lp->link_config.orig_speed = lp->link_config.speed; - lp->link_config.orig_duplex = lp->link_config.duplex; - lp->link_config.orig_phy_option = lp->ext_phy_option; - } - - lp->ext_phy_option = XPHYANE; - } - else if(cmd.speed == SPEED_100 && cmd.duplex == DUPLEX_HALF) - lp->ext_phy_option = XPHYSP; - else if(cmd.speed == SPEED_100 && cmd.duplex == DUPLEX_FULL) - lp->ext_phy_option = XPHYSP |XPHYFD; - else if(cmd.speed == SPEED_10 && cmd.duplex == DUPLEX_HALF) - lp->ext_phy_option = 0; - else if(cmd.speed == SPEED_10 && cmd.duplex == DUPLEX_FULL) - lp->ext_phy_option = XPHYFD; - else { - /* setting the original speed */ - cmd.speed = lp->link_config.orig_speed; - cmd.duplex = lp->link_config.orig_duplex; - lp->ext_phy_option = lp->link_config.orig_phy_option; - } - lp->link_config.autoneg = cmd.autoneg; - if (cmd.autoneg == AUTONEG_ENABLE) { - - lp->link_config.speed = SPEED_INVALID; - lp->link_config.duplex = DUPLEX_INVALID; - } else { - lp->link_config.speed = cmd.speed; - lp->link_config.duplex = cmd.duplex; - } - amd8111e_set_ext_phy(dev); + r = mii_ethtool_sset(&lp->mii_if, &ecmd); spin_unlock_irq(&lp->lock); - return 0; + return r; } case ETHTOOL_GREGS: { struct ethtool_regs regs; @@ -1140,24 +1454,17 @@ kfree(regbuf); return ret; } + /* restart autonegotiation */ case ETHTOOL_NWAY_RST: { - int ret; - spin_lock_irq(&lp->lock); - if(lp->link_config.autoneg == AUTONEG_ENABLE){ - lp->ext_phy_option = XPHYANE; - amd8111e_set_ext_phy(dev); - ret = 0; - }else - ret = -EINVAL; - spin_unlock_irq(&lp->lock); - return ret; + return mii_nway_restart(&lp->mii_if); } + /* get link status */ case ETHTOOL_GLINK: { - struct ethtool_value val = { ETHTOOL_GLINK }; - - val.data = netif_carrier_ok(dev) ? 1 : 0; + struct ethtool_value val = {ETHTOOL_GLINK}; + val.data = mii_link_ok(&lp->mii_if); if (copy_to_user(useraddr, &val, sizeof(val))) return -EFAULT; + return 0; } case ETHTOOL_GWOL: { struct ethtool_wolinfo wol_info = { ETHTOOL_GWOL }; @@ -1196,60 +1503,6 @@ } return -EOPNOTSUPP; } -static int amd8111e_read_phy(struct amd8111e_priv* lp, int phy_id, int reg, u32* val) -{ - void * mmio = lp->mmio; - unsigned int reg_val; - unsigned int repeat= REPEAT_CNT; - - reg_val = readl(mmio + PHY_ACCESS); - while (reg_val & PHY_CMD_ACTIVE) - reg_val = readl( mmio + PHY_ACCESS ); - - writel( PHY_RD_CMD | ((phy_id & 0x1f) << 21) | - ((reg & 0x1f) << 16), mmio +PHY_ACCESS); - do{ - reg_val = readl(mmio + PHY_ACCESS); - udelay(30); /* It takes 30 us to read/write data */ - } while (--repeat && (reg_val & PHY_CMD_ACTIVE)); - if(reg_val & PHY_RD_ERR) - goto err_phy_read; - - *val = reg_val & 0xffff; - return 0; -err_phy_read: - *val = 0; - return -EINVAL; - -} -static int amd8111e_write_phy(struct amd8111e_priv* lp,int phy_id, int reg, u32 val) -{ - unsigned int repeat = REPEAT_CNT - void * mmio = lp->mmio; - unsigned int reg_val; - - - reg_val = readl(mmio + PHY_ACCESS); - while (reg_val & PHY_CMD_ACTIVE) - reg_val = readl( mmio + PHY_ACCESS ); - - writel( PHY_WR_CMD | ((phy_id & 0x1f) << 21) | - ((reg & 0x1f) << 16)|val, mmio + PHY_ACCESS); - - do{ - reg_val = readl(mmio + PHY_ACCESS); - udelay(30); /* It takes 30 us to read/write the data */ - } while (--repeat && (reg_val & PHY_CMD_ACTIVE)); - - if(reg_val & PHY_RD_ERR) - goto err_phy_write; - - return 0; - -err_phy_write: - return -EINVAL; - -} static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; @@ -1317,15 +1570,10 @@ dev->mtu = new_mtu; - /* if (new_mtu > ETH_DATA_LEN) - lp->options |= OPTION_JUMBO_ENABLE; - else - lp->options &= ~OPTION_JUMBO_ENABLE; - */ err = amd8111e_restart(dev); spin_unlock_irq(&lp->lock); - - netif_start_queue(dev); + if(!err) + netif_start_queue(dev); return err; } @@ -1351,73 +1599,41 @@ { writel( VAL1|MPPLBA, lp->mmio + CMD3); writel( VAL0|MPEN_SW, lp->mmio + CMD7); + + /* To eliminate PCI posting bug */ + readl(lp->mmio + CMD7); return 0; } static int amd8111e_enable_link_change(struct amd8111e_priv* lp) { + /* Adapter is already stoped/suspended/interrupt-disabled */ writel(VAL0|LCMODE_SW,lp->mmio + CMD7); - return 0; -} - -/* -This function sets the power state of the device. When the device go to lower power states 1,2, and 3 it enables the wake on lan -*/ -static int amd8111e_set_power_state(struct amd8111e_priv* lp, u32 state) -{ - u16 power_control; - int pm = lp->pm_cap; - - pci_read_config_word(lp->pci_dev, - pm + PCI_PM_CTRL, - &power_control); - - power_control |= PCI_PM_CTRL_PME_STATUS; - power_control &= ~(PCI_PM_CTRL_STATE_MASK); - switch (state) { - case 0: - power_control |= 0; - pci_write_config_word(lp->pci_dev, - pm + PCI_PM_CTRL, - power_control); - return 0; - - case 1: - power_control |= 1; - break; - - case 2: - power_control |= 2; - break; - - case 3: - power_control |= 3; - break; - default: - - printk(KERN_WARNING "%s: Invalid power state (%d) requested.\n", - lp->amd8111e_net_dev->name, state); - return -EINVAL; - } - if(lp->options & OPTION_WAKE_MAGIC_ENABLE) - amd8111e_enable_magicpkt(lp); - if(lp->options & OPTION_WAKE_PHY_ENABLE) - amd8111e_enable_link_change(lp); - - /* Setting new power state. */ - pci_write_config_word(lp->pci_dev, pm + PCI_PM_CTRL, power_control); - + /* To eliminate PCI posting bug */ + readl(lp->mmio + CMD7); return 0; +} +/* This function is called when a packet transmission fails to complete within a resonable period, on the assumption that an interrupts have been failed or the interface is locked up. This function will reinitialize the hardware */ +static void amd8111e_tx_timeout(struct net_device *dev) +{ + struct amd8111e_priv* lp = dev->priv; + int err; + printk(KERN_ERR "%s: transmit timed out, resetting\n", + dev->name); + spin_lock_irq(&lp->lock); + err = amd8111e_restart(dev); + spin_unlock_irq(&lp->lock); + if(!err) + netif_wake_queue(dev); } static int amd8111e_suspend(struct pci_dev *pci_dev, u32 state) { struct net_device *dev = pci_get_drvdata(pci_dev); struct amd8111e_priv *lp = dev->priv; - int err; if (!netif_running(dev)) return 0; @@ -1431,37 +1647,54 @@ /* stop chip */ spin_lock_irq(&lp->lock); + if(lp->options & OPTION_DYN_IPG_ENABLE) + del_timer_sync(&lp->ipg_data.ipg_timer); amd8111e_stop_chip(lp); spin_unlock_irq(&lp->lock); - err = amd8111e_set_power_state(lp, state); - if (err) { + if(lp->options & OPTION_WOL_ENABLE){ + /* enable wol */ + if(lp->options & OPTION_WAKE_MAGIC_ENABLE) + amd8111e_enable_magicpkt(lp); + if(lp->options & OPTION_WAKE_PHY_ENABLE) + amd8111e_enable_link_change(lp); - spin_lock_irq(&lp->lock); - amd8111e_restart(dev); - spin_unlock_irq(&lp->lock); + pci_enable_wake(pci_dev, 3, 1); + pci_enable_wake(pci_dev, 4, 1); /* D3 cold */ - netif_device_attach(dev); } - return err; + else{ + pci_enable_wake(pci_dev, 3, 0); + pci_enable_wake(pci_dev, 4, 0); /* 4 == D3 cold */ + } + + pci_save_state(pci_dev, lp->pm_state); + pci_set_power_state(pci_dev, 3); + + return 0; } static int amd8111e_resume(struct pci_dev *pci_dev) { struct net_device *dev = pci_get_drvdata(pci_dev); struct amd8111e_priv *lp = dev->priv; - int err; if (!netif_running(dev)) return 0; - err = amd8111e_set_power_state(lp, 0); - if (err) - return err; + pci_set_power_state(pci_dev, 0); + pci_restore_state(pci_dev, lp->pm_state); + + pci_enable_wake(pci_dev, 3, 0); + pci_enable_wake(pci_dev, 4, 0); /* D3 cold */ netif_device_attach(dev); spin_lock_irq(&lp->lock); amd8111e_restart(dev); + /* Restart ipg timer */ + if(lp->options & OPTION_DYN_IPG_ENABLE) + mod_timer(&lp->ipg_data.ipg_timer, + jiffies + (IPG_CONVERGE_TIME * HZ)); spin_unlock_irq(&lp->lock); return 0; @@ -1480,6 +1713,65 @@ pci_set_drvdata(pdev, NULL); } } +static void amd8111e_config_ipg(struct net_device* dev) +{ + struct amd8111e_priv *lp = dev->priv; + struct ipg_info* ipg_data = &lp->ipg_data; + void * mmio = lp->mmio; + unsigned int prev_col_cnt = ipg_data->col_cnt; + unsigned int total_col_cnt; + unsigned int tmp_ipg; + + if(lp->link_config.duplex == DUPLEX_FULL){ + ipg_data->ipg = DEFAULT_IPG; + return; + } + + if(ipg_data->ipg_state == SSTATE){ + + if(ipg_data->timer_tick == IPG_STABLE_TIME){ + + ipg_data->timer_tick = 0; + ipg_data->ipg = MIN_IPG - IPG_STEP; + ipg_data->current_ipg = MIN_IPG; + ipg_data->diff_col_cnt = 0xFFFFFFFF; + ipg_data->ipg_state = CSTATE; + } + else + ipg_data->timer_tick++; + } + + if(ipg_data->ipg_state == CSTATE){ + + /* Get the current collision count */ + + total_col_cnt = ipg_data->col_cnt = + amd8111e_read_mib(mmio, xmt_collisions); + + if ((total_col_cnt - prev_col_cnt) < + (ipg_data->diff_col_cnt)){ + + ipg_data->diff_col_cnt = + total_col_cnt - prev_col_cnt ; + + ipg_data->ipg = ipg_data->current_ipg; + } + + ipg_data->current_ipg += IPG_STEP; + + if (ipg_data->current_ipg <= MAX_IPG) + tmp_ipg = ipg_data->current_ipg; + else{ + tmp_ipg = ipg_data->ipg; + ipg_data->ipg_state = SSTATE; + } + writew((u32)tmp_ipg, mmio + IPG); + writew((u32)(tmp_ipg - IFS1_DELTA), mmio + IFS1); + } + mod_timer(&lp->ipg_data.ipg_timer, jiffies + (IPG_CONVERGE_TIME * HZ)); + return; + +} static int __devinit amd8111e_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -1488,7 +1780,6 @@ unsigned long reg_addr,reg_len; struct amd8111e_priv* lp; struct net_device* dev; - unsigned int chip_version; err = pci_enable_device(pdev); if(err){ @@ -1547,11 +1838,16 @@ #endif lp = dev->priv; - memset (lp, 0, sizeof (*lp)); lp->pci_dev = pdev; lp->amd8111e_net_dev = dev; lp->pm_cap = pm_cap; + /* setting mii default values */ + lp->mii_if.dev = dev; + lp->mii_if.mdio_read = amd8111e_mdio_read; + lp->mii_if.mdio_write = amd8111e_mdio_write; + lp->mii_if.phy_id = PHY_ID; + spin_lock_init(&lp->lock); lp->mmio = ioremap(reg_addr, reg_len); @@ -1565,12 +1861,14 @@ /* Initializing MAC address */ for(i = 0; i < ETH_ADDR_LEN; i++) dev->dev_addr[i] =readb(lp->mmio + PADR + i); - /* Setting user defined speed */ - if (speed_duplex[card_idx] > sizeof(speed_duplex_mapping)) - lp->ext_phy_option = XPHYANE; - else - lp->ext_phy_option = - speed_duplex_mapping[speed_duplex[card_idx]]; + + /* Setting user defined parametrs */ + lp->ext_phy_option = speed_duplex[card_idx]; + if(coalesce[card_idx]) + lp->options |= OPTION_INTR_COAL_ENABLE; + if(dynamic_ipg[card_idx++]) + lp->options |= OPTION_DYN_IPG_ENABLE; + /* Initialize driver entry points */ dev->open = amd8111e_open; dev->hard_start_xmit = amd8111e_start_xmit; @@ -1580,6 +1878,8 @@ dev->do_ioctl = amd8111e_ioctl; dev->change_mtu = amd8111e_change_mtu; dev->irq =pdev->irq; + dev->tx_timeout = amd8111e_tx_timeout; + dev->watchdog_timeo = AMD8111E_TX_TIMEOUT; #if AMD8111E_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; @@ -1589,10 +1889,6 @@ /* Set receive buffer length and set jumbo option*/ amd8111e_set_rx_buff_len(dev); - - - /* dev->tx_timeout = tg3_tx_timeout; */ - /* dev->watchdog_timeo = TG3_TX_TIMEOUT; */ err = register_netdev(dev); if (err) { @@ -1603,15 +1899,26 @@ pci_set_drvdata(pdev, dev); + /* Initialize software ipg timer */ + if(lp->options & OPTION_DYN_IPG_ENABLE){ + init_timer(&lp->ipg_data.ipg_timer); + lp->ipg_data.ipg_timer.data = (unsigned long) dev; + lp->ipg_data.ipg_timer.function = (void *)&amd8111e_config_ipg; + lp->ipg_data.ipg_timer.expires = jiffies + + IPG_CONVERGE_TIME * HZ; + lp->ipg_data.ipg = DEFAULT_IPG; + lp->ipg_data.ipg_state = CSTATE; + }; + /* display driver and device information */ - chip_version = (readl(lp->mmio + CHIPID) & 0xf0000000)>>28; - printk("%s: AMD-8111e Driver Version: %s\n",dev->name,MODULE_VERSION); - printk("%s: [ Rev %x ] PCI 10/100BaseT Ethernet ", dev->name, chip_version); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i],i == 5 ? ' ' : ':'); - printk("\n"); - return 0; + chip_version = (readl(lp->mmio + CHIPID) & 0xf0000000)>>28; + printk(KERN_INFO "%s: AMD-8111e Driver Version: %s\n", dev->name,MODULE_VERSION); + printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet ", dev->name, chip_version); + for (i = 0; i < 6; i++) + printk("%2.2x%c",dev->dev_addr[i],i == 5 ? ' ' : ':'); + printk( "\n"); + return 0; err_iounmap: iounmap((void *) lp->mmio); diff -urN linux-2.4.21/drivers/net/amd8111e.h linux-2.4.22/drivers/net/amd8111e.h --- linux-2.4.21/drivers/net/amd8111e.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/amd8111e.h 2003-08-25 04:44:42.000000000 -0700 @@ -1,4 +1,7 @@ /* + * Advanced Micro Devices Inc. AMD8111E Linux Network Driver + * Copyright (C) 2003 Advanced Micro Devices + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -27,73 +30,14 @@ Kernel Mode Revision History: - + 3.0.0 + Initial Revision. + 3.0.1 */ #ifndef _AMD811E_H #define _AMD811E_H -/* Hardware definitions */ - -#define B31_MASK 0x80000000 -#define B30_MASK 0X40000000 -#define B29_MASK 0x20000000 -#define B28_MASK 0x10000000 -#define B27_MASK 0x08000000 -#define B26_MASK 0x04000000 -#define B25_MASK 0x02000000 -#define B24_MASK 0x01000000 -#define B23_MASK 0x00800000 -#define B22_MASK 0x00400000 -#define B21_MASK 0x00200000 -#define B20_MASK 0x00100000 -#define B19_MASK 0x00080000 -#define B18_MASK 0x00040000 -#define B17_MASK 0x00020000 -#define B16_MASK 0x00010000 - -#define B15_MASK 0x8000 -#define B14_MASK 0x4000 -#define B13_MASK 0x2000 -#define B12_MASK 0x1000 -#define B11_MASK 0x0800 -#define B10_MASK 0x0400 -#define B9_MASK 0x0200 -#define B8_MASK 0x0100 -#define B7_MASK 0x0080 -#define B6_MASK 0x0040 -#define B5_MASK 0x0020 -#define B4_MASK 0x0010 -#define B3_MASK 0x0008 -#define B2_MASK 0x0004 -#define B1_MASK 0x0002 -#define B0_MASK 0x0001 - -/* PCI register offset */ -#define PCI_ID_REG 0x00 -#define PCI_COMMAND_REG 0x04 -/* #define MEMEN_BIT B1_MASK */ -/* #define IOEN_BIT B0_MASK */ -#define PCI_REV_ID_REG 0x08 -#define PCI_MEM_BASE_REG 0x10 -/* #define MEMBASE_MASK 0xFFFFF000 */ -/* #define MEMBASE_SIZE 4096 */ -#define PCI_INTR_REG 0x3C -#define PCI_STATUS_REG 0x06 -#define PCI_CAP_ID_REG_OFFSET 0x34 -#define PCI_PMC_REG_OFFSET 0x36 -#define PCI_PMCSR_REG_OFFSET 0x38 - -/* #define NEW_CAP 0x0010 */ -#define PME_EN 0x0100 - -#define PARTID_MASK 0xFFFFF000 -#define PARTID_START_BIT 12 - -/* #define LANCE_DWIO_RESET_PORT 0x18 -#define LANCE_WIO_RESET_PORT 0x14 */ -#define MIB_OFFSET 0x28 - /* Command style register access Registers CMD0, CMD2, CMD3,CMD7 and INTEN0 uses a write access technique called command style access. It allows the write to selected bits of this register without altering the bits that are not selected. Command style registers are divided into 4 bytes that can be written independently. Higher order bit of each byte is the value bit that specifies the value that will be written into the selected bits of register. @@ -155,7 +99,7 @@ #define XMT_RING_LEN2 0x148 /* Transmit Ring2 length register */ #define XMT_RING_LEN3 0x14C /* Transmit Ring3 length register */ -#define RCV_RING_LEN0 0x150 /* Transmit Ring0 length register */ +#define RCV_RING_LEN0 0x150 /* Receive Ring0 length register */ #define SRAM_SIZE 0x178 /* SRAM size register */ #define SRAM_BOUNDARY 0x17A /* SRAM boundary register */ @@ -164,391 +108,398 @@ #define PADR 0x160 /* Physical address register */ +#define IFS1 0x18C /* Inter-frame spacing Part1 register */ +#define IFS 0x18D /* Inter-frame spacing register */ +#define IPG 0x18E /* Inter-frame gap register */ /* 64bit register */ #define LADRF 0x168 /* Logical address filter register */ -/* 8bit regsisters */ - -#define IFS1 0x18C /* Inter-frame spacing Part1 register */ -#define IFS 0x18D /* Inter-frame spacing register */ /* Register Bit Definitions */ +typedef enum { + + ASF_INIT_DONE = (1 << 1), + ASF_INIT_PRESENT = (1 << 0), + +}STAT_ASF_BITS; + +typedef enum { + + MIB_CMD_ACTIVE = (1 << 15 ), + MIB_RD_CMD = (1 << 13 ), + MIB_CLEAR = (1 << 12 ), + MIB_ADDRESS = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)| + (1 << 4) | (1 << 5), +}MIB_ADDR_BITS; + + +typedef enum { + + PMAT_DET = (1 << 12), + MP_DET = (1 << 11), + LC_DET = (1 << 10), + SPEED_MASK = (1 << 9)|(1 << 8)|(1 << 7), + FULL_DPLX = (1 << 6), + LINK_STATS = (1 << 5), + AUTONEG_COMPLETE = (1 << 4), + MIIPD = (1 << 3), + RX_SUSPENDED = (1 << 2), + TX_SUSPENDED = (1 << 1), + RUNNING = (1 << 0), + +}STAT0_BITS; -/* STAT_ASF 0x00, 32bit register */ -#define ASF_INIT_DONE B1_MASK -#define ASF_INIT_PRESENT B0_MASK - -/* MIB_ADDR 0x14, 16bit register */ -#define MIB_CMD_ACTIVE B15_MASK -#define MIB_RD_CMD B13_MASK -#define MIB_CLEAR B12_MASK -#define MIB_ADDRESS 0x0000003F /* 5:0 */ - -/* QOS_ADDR 0x1C, 16bit register */ -#define QOS_CMD_ACTIVE B15_MASK -#define QOS_WR_CMD B14_MASK -#define QOS_RD_CMD B13_MASK -#define QOS_ADDRESS 0x0000001F /* 4:0 */ - -/* STAT0 0x30, 32bit register */ -#define PAUSE_PEND B14_MASK -#define PAUSING B13_MASK -#define PMAT_DET B12_MASK -#define MP_DET B11_MASK -#define LC_DET B10_MASK -#define SPEED_MASK 0x0380 /* 9:7 */ -#define FULL_DPLX B6_MASK -#define LINK_STATS B5_MASK -#define AUTONEG_COMPLETE B4_MASK -#define MIIPD B3_MASK -#define RX_SUSPENDED B2_MASK -#define TX_SUSPENDED B1_MASK -#define RUNNING B0_MASK #define PHY_SPEED_10 0x2 #define PHY_SPEED_100 0x3 /* INT0 0x38, 32bit register */ -#define INTR B31_MASK -#define PCSINT B28_MASK -#define LCINT B27_MASK -#define APINT5 B26_MASK -#define APINT4 B25_MASK -#define APINT3 B24_MASK -#define TINT_SUM B23_MASK -#define APINT2 B22_MASK -#define APINT1 B21_MASK -#define APINT0 B20_MASK -#define MIIPDTINT B19_MASK -#define MCCIINT B18_MASK -#define MCCINT B17_MASK -#define MREINT B16_MASK -#define RINT_SUM B15_MASK -#define SPNDINT B14_MASK -#define MPINT B13_MASK -#define SINT B12_MASK -#define TINT3 B11_MASK -#define TINT2 B10_MASK -#define TINT1 B9_MASK -#define TINT0 B8_MASK -#define UINT B7_MASK -#define STINT B4_MASK -#define RINT3 B3_MASK -#define RINT2 B2_MASK -#define RINT1 B1_MASK -#define RINT0 B0_MASK - -/* INTEN0 0x40, 32bit register */ -#define VAL3 B31_MASK /* VAL bit for byte 3 */ -#define VAL2 B23_MASK /* VAL bit for byte 2 */ -#define VAL1 B15_MASK /* VAL bit for byte 1 */ -#define VAL0 B7_MASK /* VAL bit for byte 0 */ -/* VAL3 */ -#define PSCINTEN B28_MASK -#define LCINTEN B27_MASK -#define APINT5EN B26_MASK -#define APINT4EN B25_MASK -#define APINT3EN B24_MASK -/* VAL2 */ -#define APINT2EN B22_MASK -#define APINT1EN B21_MASK -#define APINT0EN B20_MASK -#define MIIPDTINTEN B19_MASK -#define MCCIINTEN B18_MASK -#define MCCINTEN B17_MASK -#define MREINTEN B16_MASK -/* VAL1 */ -#define SPNDINTEN B14_MASK -#define MPINTEN B13_MASK -#define SINTEN B12_MASK -#define TINTEN3 B11_MASK -#define TINTEN2 B10_MASK -#define TINTEN1 B9_MASK -#define TINTEN0 B8_MASK -/* VAL0 */ -#define STINTEN B4_MASK -#define RINTEN3 B3_MASK -#define RINTEN2 B2_MASK -#define RINTEN1 B1_MASK -#define RINTEN0 B0_MASK - -#define INTEN0_CLEAR 0x1F7F7F1F /* Command style register */ - -/* CMD0 0x48, 32bit register */ -/* VAL2 */ -#define RDMD3 B19_MASK -#define RDMD2 B18_MASK -#define RDMD1 B17_MASK -#define RDMD0 B16_MASK -/* VAL1 */ -#define TDMD3 B11_MASK -#define TDMD2 B10_MASK -#define TDMD1 B9_MASK -#define TDMD0 B8_MASK -/* VAL0 */ -#define UINTCMD B6_MASK -#define RX_FAST_SPND B5_MASK -#define TX_FAST_SPND B4_MASK -#define RX_SPND B3_MASK -#define TX_SPND B2_MASK -#define INTREN B1_MASK -#define RUN B0_MASK - -#define CMD0_CLEAR 0x000F0F7F /* Command style register */ - -/* CMD2 0x50, 32bit register */ -/* VAL3 */ -#define CONDUIT_MODE B29_MASK -/* VAL2 */ -#define RPA B19_MASK -#define DRCVPA B18_MASK -#define DRCVBC B17_MASK -#define PROM B16_MASK -/* VAL1 */ -#define ASTRP_RCV B13_MASK -#define FCOLL B12_MASK -#define EMBA B11_MASK -#define DXMT2PD B10_MASK -#define LTINTEN B9_MASK -#define DXMTFCS B8_MASK -/* VAL0 */ -#define APAD_XMT B6_MASK -#define DRTY B5_MASK -#define INLOOP B4_MASK -#define EXLOOP B3_MASK -#define REX_RTRY B2_MASK -#define REX_UFLO B1_MASK -#define REX_LCOL B0_MASK - -#define CMD2_CLEAR 0x3F7F3F7F /* Command style register */ - -/* CMD3 0x54, 32bit register */ -/* VAL3 */ -#define ASF_INIT_DONE_ALIAS B29_MASK -/* VAL2 */ -#define JUMBO B21_MASK -#define VSIZE B20_MASK -#define VLONLY B19_MASK -#define VL_TAG_DEL B18_MASK -/* VAL1 */ -#define EN_PMGR B14_MASK -#define INTLEVEL B13_MASK -#define FORCE_FULL_DUPLEX B12_MASK -#define FORCE_LINK_STATUS B11_MASK -#define APEP B10_MASK -#define MPPLBA B9_MASK -/* VAL0 */ -#define RESET_PHY_PULSE B2_MASK -#define RESET_PHY B1_MASK -#define PHY_RST_POL B0_MASK -/* CMD7 0x64, 32bit register */ -/* VAL0 */ -#define PMAT_SAVE_MATCH B4_MASK -#define PMAT_MODE B3_MASK -#define MPEN_SW B1_MASK -#define LCMODE_SW B0_MASK - -#define CMD7_CLEAR 0x0000001B /* Command style register */ -/* CTRL0 0x68, 32bit register */ -#define PHY_SEL 0x03000000 /* 25:24 */ -#define RESET_PHY_WIDTH 0x00FF0000 /* 23:16 */ -#define BSWP_REGS B10_MASK -#define BSWP_DESC B9_MASK -#define BSWP_DATA B8_MASK -#define CACHE_ALIGN B4_MASK -#define BURST_LIMIT 0x0000000F /* 3:0 */ - -/* CTRL1 0x6C, 32bit register */ -#define SLOTMOD_MASK 0x03000000 /* 25:24 */ -#define XMTSP_MASK 0x300 /* 17:16 */ -#define XMTSP_128 0x200 -#define XMTSP_64 0x100 -#define CRTL1_DEFAULT 0x00000017 - -/* CTRL2 0x70, 32bit register */ -#define FS_MASK 0x00070000 /* 18:16 */ -#define FMDC_MASK 0x00000300 /* 9:8 */ -#define XPHYRST B7_MASK -#define XPHYANE B6_MASK -#define XPHYFD B5_MASK -#define XPHYSP B3_MASK /* 4:3 */ -#define APDW_MASK 0x00000007 /* 2:0 */ - -/* RCV_RING_CFG 0x78, 16bit register */ -#define RCV_DROP3 B11_MASK -#define RCV_DROP2 B10_MASK -#define RCV_DROP1 B9_MASK -#define RCV_DROP0 B8_MASK -#define RCV_RING_DEFAULT 0x0030 /* 5:4 */ -#define RCV_RING3_EN B3_MASK -#define RCV_RING2_EN B2_MASK -#define RCV_RING1_EN B1_MASK -#define RCV_RING0_EN B0_MASK +typedef enum { + + INTR = (1 << 31), + PCSINT = (1 << 28), + LCINT = (1 << 27), + APINT5 = (1 << 26), + APINT4 = (1 << 25), + APINT3 = (1 << 24), + TINT_SUM = (1 << 23), + APINT2 = (1 << 22), + APINT1 = (1 << 21), + APINT0 = (1 << 20), + MIIPDTINT = (1 << 19), + MCCINT = (1 << 17), + MREINT = (1 << 16), + RINT_SUM = (1 << 15), + SPNDINT = (1 << 14), + MPINT = (1 << 13), + SINT = (1 << 12), + TINT3 = (1 << 11), + TINT2 = (1 << 10), + TINT1 = (1 << 9), + TINT0 = (1 << 8), + UINT = (1 << 7), + STINT = (1 << 4), + RINT0 = (1 << 0), + +}INT0_BITS; + +typedef enum { + + VAL3 = (1 << 31), /* VAL bit for byte 3 */ + VAL2 = (1 << 23), /* VAL bit for byte 2 */ + VAL1 = (1 << 15), /* VAL bit for byte 1 */ + VAL0 = (1 << 7), /* VAL bit for byte 0 */ + +}VAL_BITS; + +typedef enum { + + /* VAL3 */ + LCINTEN = (1 << 27), + APINT5EN = (1 << 26), + APINT4EN = (1 << 25), + APINT3EN = (1 << 24), + /* VAL2 */ + APINT2EN = (1 << 22), + APINT1EN = (1 << 21), + APINT0EN = (1 << 20), + MIIPDTINTEN = (1 << 19), + MCCIINTEN = (1 << 18), + MCCINTEN = (1 << 17), + MREINTEN = (1 << 16), + /* VAL1 */ + SPNDINTEN = (1 << 14), + MPINTEN = (1 << 13), + TINTEN3 = (1 << 11), + SINTEN = (1 << 12), + TINTEN2 = (1 << 10), + TINTEN1 = (1 << 9), + TINTEN0 = (1 << 8), + /* VAL0 */ + STINTEN = (1 << 4), + RINTEN0 = (1 << 0), + + INTEN0_CLEAR = 0x1F7F7F1F, /* Command style register */ + +}INTEN0_BITS; + +typedef enum { + /* VAL2 */ + RDMD0 = (1 << 16), + /* VAL1 */ + TDMD3 = (1 << 11), + TDMD2 = (1 << 10), + TDMD1 = (1 << 9), + TDMD0 = (1 << 8), + /* VAL0 */ + UINTCMD = (1 << 6), + RX_FAST_SPND = (1 << 5), + TX_FAST_SPND = (1 << 4), + RX_SPND = (1 << 3), + TX_SPND = (1 << 2), + INTREN = (1 << 1), + RUN = (1 << 0), + + CMD0_CLEAR = 0x000F0F7F, /* Command style register */ + +}CMD0_BITS; + +typedef enum { + + /* VAL3 */ + CONDUIT_MODE = (1 << 29), + /* VAL2 */ + RPA = (1 << 19), + DRCVPA = (1 << 18), + DRCVBC = (1 << 17), + PROM = (1 << 16), + /* VAL1 */ + ASTRP_RCV = (1 << 13), + RCV_DROP0 = (1 << 12), + EMBA = (1 << 11), + DXMT2PD = (1 << 10), + LTINTEN = (1 << 9), + DXMTFCS = (1 << 8), + /* VAL0 */ + APAD_XMT = (1 << 6), + DRTY = (1 << 5), + INLOOP = (1 << 4), + EXLOOP = (1 << 3), + REX_RTRY = (1 << 2), + REX_UFLO = (1 << 1), + REX_LCOL = (1 << 0), + + CMD2_CLEAR = 0x3F7F3F7F, /* Command style register */ + +}CMD2_BITS; + +typedef enum { + + /* VAL3 */ + ASF_INIT_DONE_ALIAS = (1 << 29), + /* VAL2 */ + JUMBO = (1 << 21), + VSIZE = (1 << 20), + VLONLY = (1 << 19), + VL_TAG_DEL = (1 << 18), + /* VAL1 */ + EN_PMGR = (1 << 14), + INTLEVEL = (1 << 13), + FORCE_FULL_DUPLEX = (1 << 12), + FORCE_LINK_STATUS = (1 << 11), + APEP = (1 << 10), + MPPLBA = (1 << 9), + /* VAL0 */ + RESET_PHY_PULSE = (1 << 2), + RESET_PHY = (1 << 1), + PHY_RST_POL = (1 << 0), + +}CMD3_BITS; + + +typedef enum { + + /* VAL0 */ + PMAT_SAVE_MATCH = (1 << 4), + PMAT_MODE = (1 << 3), + MPEN_SW = (1 << 1), + LCMODE_SW = (1 << 0), + + CMD7_CLEAR = 0x0000001B /* Command style register */ + +}CMD7_BITS; + + +typedef enum { + + RESET_PHY_WIDTH = (0xF << 16) | (0xF<< 20), /* 0x00FF0000 */ + XMTSP_MASK = (1 << 9) | (1 << 8), /* 9:8 */ + XMTSP_128 = (1 << 9), /* 9 */ + XMTSP_64 = (1 << 8), + CACHE_ALIGN = (1 << 4), + BURST_LIMIT_MASK = (0xF << 0 ), + CTRL1_DEFAULT = 0x00010111, + +}CTRL1_BITS; + +typedef enum { + + FMDC_MASK = (1 << 9)|(1 << 8), /* 9:8 */ + XPHYRST = (1 << 7), + XPHYANE = (1 << 6), + XPHYFD = (1 << 5), + XPHYSP = (1 << 4) | (1 << 3), /* 4:3 */ + APDW_MASK = (1 << 2) | (1 << 1) | (1 << 0), /* 2:0 */ + +}CTRL2_BITS; /* XMT_RING_LIMIT 0x7C, 32bit register */ -#define XMT_RING2_LIMIT 0x00FF0000 /* 23:16 */ -#define XMT_RING1_LIMIT 0x0000FF00 /* 15:8 */ -#define XMT_RING0_LIMIT 0x000000FF /* 7:0 */ - -/* AUTOPOLL0 0x88, 16bit register */ -#define AP_REG0_EN B15_MASK -#define AP_REG0_ADDR_MASK 0x1F00 /* 12:8 */ -#define AP_PHY0_ADDR_MASK 0x001F /* 4:0 */ +typedef enum { + + XMT_RING2_LIMIT = (0xFF << 16), /* 23:16 */ + XMT_RING1_LIMIT = (0xFF << 8), /* 15:8 */ + XMT_RING0_LIMIT = (0xFF << 0), /* 7:0 */ + +}XMT_RING_LIMIT_BITS; + +typedef enum { + + AP_REG0_EN = (1 << 15), + AP_REG0_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ + AP_PHY0_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ + +}AUTOPOLL0_BITS; /* AUTOPOLL1 0x8A, 16bit register */ -#define AP_REG1_EN B15_MASK -#define AP_REG1_ADDR_MASK 0x1F00 /* 12:8 */ -#define AP_PRE_SUP1 B6_MASK -#define AP_PHY1_DFLT B5_MASK -#define AP_PHY1_ADDR_MASK 0x001F /* 4:0 */ - -/* AUTOPOLL2 0x8C, 16bit register */ -#define AP_REG2_EN B15_MASK -#define AP_REG2_ADDR_MASK 0x1F00 /* 12:8 */ -#define AP_PRE_SUP2 B6_MASK -#define AP_PHY2_DFLT B5_MASK -#define AP_PHY2_ADDR_MASK 0x001F /* 4:0 */ - -/* AUTOPOLL3 0x8E, 16bit register */ -#define AP_REG3_EN B15_MASK -#define AP_REG3_ADDR_MASK 0x1F00 /* 12:8 */ -#define AP_PRE_SUP3 B6_MASK -#define AP_PHY3_DFLT B5_MASK -#define AP_PHY3_ADDR_MASK 0x001F /* 4:0 */ - -/* AUTOPOLL4 0x90, 16bit register */ -#define AP_REG4_EN B15_MASK -#define AP_REG4_ADDR_MASK 0x1F00 /* 12:8 */ -#define AP_PRE_SUP4 B6_MASK -#define AP_PHY4_DFLT B5_MASK -#define AP_PHY4_ADDR_MASK 0x001F /* 4:0 */ - -/* AUTOPOLL5 0x92, 16bit register */ -#define AP_REG5_EN B15_MASK -#define AP_REG5_ADDR_MASK 0x1F00 /* 12:8 */ -#define AP_PRE_SUP5 B6_MASK -#define AP_PHY5_DFLT B5_MASK -#define AP_PHY5_ADDR_MASK 0x001F /* 4:0 */ +typedef enum { + + AP_REG1_EN = (1 << 15), + AP_REG1_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ + AP_PRE_SUP1 = (1 << 6), + AP_PHY1_DFLT = (1 << 5), + AP_PHY1_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ + +}AUTOPOLL1_BITS; + + +typedef enum { + + AP_REG2_EN = (1 << 15), + AP_REG2_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ + AP_PRE_SUP2 = (1 << 6), + AP_PHY2_DFLT = (1 << 5), + AP_PHY2_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ + +}AUTOPOLL2_BITS; + +typedef enum { + + AP_REG3_EN = (1 << 15), + AP_REG3_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ + AP_PRE_SUP3 = (1 << 6), + AP_PHY3_DFLT = (1 << 5), + AP_PHY3_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ + +}AUTOPOLL3_BITS; + + +typedef enum { + + AP_REG4_EN = (1 << 15), + AP_REG4_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ + AP_PRE_SUP4 = (1 << 6), + AP_PHY4_DFLT = (1 << 5), + AP_PHY4_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ + +}AUTOPOLL4_BITS; + + +typedef enum { + + AP_REG5_EN = (1 << 15), + AP_REG5_ADDR_MASK = (0xF << 8) |(1 << 12),/* 12:8 */ + AP_PRE_SUP5 = (1 << 6), + AP_PHY5_DFLT = (1 << 5), + AP_PHY5_ADDR_MASK = (0xF << 0) |(1 << 4),/* 4:0 */ + +}AUTOPOLL5_BITS; + + + /* AP_VALUE 0x98, 32bit ragister */ -#define AP_VAL_ACTIVE B31_MASK -#define AP_VAL_RD_CMD B29_MASK -#define AP_ADDR 0x00070000 /* 18:16 */ -#define AP_VAL 0x0000FFFF /* 15:0 */ - -/* PCS_ANEG 0x9C, 32bit register */ -#define SYNC_LOST B10_MASK -#define IMATCH B9_MASK -#define CMATCH B8_MASK -#define PCS_AN_IDLE B1_MASK -#define PCS_AN_CFG B0_MASK - -/* DLY_INT_A 0xA8, 32bit register */ -#define DLY_INT_A_R3 B31_MASK -#define DLY_INT_A_R2 B30_MASK -#define DLY_INT_A_R1 B29_MASK -#define DLY_INT_A_R0 B28_MASK -#define DLY_INT_A_T3 B27_MASK -#define DLY_INT_A_T2 B26_MASK -#define DLY_INT_A_T1 B25_MASK -#define DLY_INT_A_T0 B24_MASK -#define EVENT_COUNT_A 0x00FF0000 /* 20:16 */ -#define MAX_DELAY_TIME_A 0x000007FF /* 10:0 */ - -/* DLY_INT_B 0xAC, 32bit register */ -#define DLY_INT_B_R3 B31_MASK -#define DLY_INT_B_R2 B30_MASK -#define DLY_INT_B_R1 B29_MASK -#define DLY_INT_B_R0 B28_MASK -#define DLY_INT_B_T3 B27_MASK -#define DLY_INT_B_T2 B26_MASK -#define DLY_INT_B_T1 B25_MASK -#define DLY_INT_B_T0 B24_MASK -#define EVENT_COUNT_B 0x00FF0000 /* 20:16 */ -#define MAX_DELAY_TIME_B 0x000007FF /* 10:0 */ - -/* DFC_THRESH2 0xC0, 16bit register */ -#define DFC_THRESH2_HIGH 0xFF00 /* 15:8 */ -#define DFC_THRESH2_LOW 0x00FF /* 7:0 */ - -/* DFC_THRESH3 0xC2, 16bit register */ -#define DFC_THRESH3_HIGH 0xFF00 /* 15:8 */ -#define DFC_THRESH3_LOW 0x00FF /* 7:0 */ - -/* DFC_THRESH0 0xC4, 16bit register */ -#define DFC_THRESH0_HIGH 0xFF00 /* 15:8 */ -#define DFC_THRESH0_LOW 0x00FF /* 7:0 */ - -/* DFC_THRESH1 0xC6, 16bit register */ -#define DFC_THRESH1_HIGH 0xFF00 /* 15:8 */ -#define DFC_THRESH1_LOW 0x00FF /* 7:0 */ +typedef enum { + + AP_VAL_ACTIVE = (1 << 31), + AP_VAL_RD_CMD = ( 1 << 29), + AP_ADDR = (1 << 18)|(1 << 17)|(1 << 16), /* 18:16 */ + AP_VAL = (0xF << 0) | (0xF << 4) |( 0xF << 8) | + (0xF << 12), /* 15:0 */ + +}AP_VALUE_BITS; + +typedef enum { + + DLY_INT_A_R3 = (1 << 31), + DLY_INT_A_R2 = (1 << 30), + DLY_INT_A_R1 = (1 << 29), + DLY_INT_A_R0 = (1 << 28), + DLY_INT_A_T3 = (1 << 27), + DLY_INT_A_T2 = (1 << 26), + DLY_INT_A_T1 = (1 << 25), + DLY_INT_A_T0 = ( 1 << 24), + EVENT_COUNT_A = (0xF << 16) | (0x1 << 20),/* 20:16 */ + MAX_DELAY_TIME_A = (0xF << 0) | (0xF << 4) | (1 << 8)| + (1 << 9) | (1 << 10), /* 10:0 */ + +}DLY_INT_A_BITS; + +typedef enum { + + DLY_INT_B_R3 = (1 << 31), + DLY_INT_B_R2 = (1 << 30), + DLY_INT_B_R1 = (1 << 29), + DLY_INT_B_R0 = (1 << 28), + DLY_INT_B_T3 = (1 << 27), + DLY_INT_B_T2 = (1 << 26), + DLY_INT_B_T1 = (1 << 25), + DLY_INT_B_T0 = ( 1 << 24), + EVENT_COUNT_B = (0xF << 16) | (0x1 << 20),/* 20:16 */ + MAX_DELAY_TIME_B = (0xF << 0) | (0xF << 4) | (1 << 8)| + (1 << 9) | (1 << 10), /* 10:0 */ +}DLY_INT_B_BITS; + /* FLOW_CONTROL 0xC8, 32bit register */ -#define PAUSE_LEN_CHG B30_MASK -#define FFC_EN B28_MASK -#define DFC_RING3_EN B27_MASK -#define DFC_RING2_EN B26_MASK -#define DFC_RING1_EN B25_MASK -#define DFC_RING0_EN B24_MASK -#define FIXP_CONGEST B21_MASK -#define FPA B20_MASK -#define NPA B19_MASK -#define FIXP B18_MASK -#define FCPEN B17_MASK -#define FCCMD B16_MASK -#define PAUSE_LEN 0x0000FFFF /* 15:0 */ - -/* FFC THRESH 0xCC, 32bit register */ -#define FFC_HIGH 0xFFFF0000 /* 31:16 */ -#define FFC_LOW 0x0000FFFF /* 15:0 */ +typedef enum { + + PAUSE_LEN_CHG = (1 << 30), + FTPE = (1 << 22), + FRPE = (1 << 21), + NAPA = (1 << 20), + NPA = (1 << 19), + FIXP = ( 1 << 18), + FCCMD = ( 1 << 16), + PAUSE_LEN = (0xF << 0) | (0xF << 4) |( 0xF << 8) | (0xF << 12), /* 15:0 */ + +}FLOW_CONTROL_BITS; /* PHY_ ACCESS 0xD0, 32bit register */ -#define PHY_CMD_ACTIVE B31_MASK -#define PHY_WR_CMD B30_MASK -#define PHY_RD_CMD B29_MASK -#define PHY_RD_ERR B28_MASK -#define PHY_PRE_SUP B27_MASK -#define PHY_ADDR 0x03E00000 /* 25:21 */ -#define PHY_REG_ADDR 0x001F0000 /* 20:16 */ -#define PHY_DATA 0x0000FFFF /* 15:0 */ - -/* LED0..3 0xE0..0xE6, 16bit register */ -#define LEDOUT B15_MASK -#define LEDPOL B14_MASK -#define LEDDIS B13_MASK -#define LEDSTRETCH B12_MASK -#define LED1000 B8_MASK -#define LED100 B7_MASK -#define LEDMP B6_MASK -#define LEDFD B5_MASK -#define LEDLINK B4_MASK -#define LEDRCVMAT B3_MASK -#define LEDXMT B2_MASK -#define LEDRCV B1_MASK -#define LEDCOLOUT B0_MASK - -/* EEPROM_ACC 0x17C, 16bit register */ -#define PVALID B15_MASK -#define PREAD B14_MASK -#define EEDET B13_MASK -#define EEN B4_MASK -#define ECS B2_MASK -#define EESK B1_MASK -#define edi_edo b0_MASK +typedef enum { + + PHY_CMD_ACTIVE = (1 << 31), + PHY_WR_CMD = (1 << 30), + PHY_RD_CMD = (1 << 29), + PHY_RD_ERR = (1 << 28), + PHY_PRE_SUP = (1 << 27), + PHY_ADDR = (1 << 21) | (1 << 22) | (1 << 23)| + (1 << 24) |(1 << 25),/* 25:21 */ + PHY_REG_ADDR = (1 << 16) | (1 << 17) | (1 << 18)| (1 << 19) | (1 << 20),/* 20:16 */ + PHY_DATA = (0xF << 0)|(0xF << 4) |(0xF << 8)| + (0xF << 12),/* 15:0 */ + +}PHY_ACCESS_BITS; + /* PMAT0 0x190, 32bit register */ -#define PMR_ACTIVE B31_MASK -#define PMR_WR_CMD B30_MASK -#define PMR_RD_CMD B29_MASK -#define PMR_BANK B28_MASK -#define PMR_ADDR 0x007F0000 /* 22:16 */ -#define PMR_B4 0x000000FF /* 15:0 */ +typedef enum { + PMR_ACTIVE = (1 << 31), + PMR_WR_CMD = (1 << 30), + PMR_RD_CMD = (1 << 29), + PMR_BANK = (1 <<28), + PMR_ADDR = (0xF << 16)|(1 << 20)|(1 << 21)| + (1 << 22),/* 22:16 */ + PMR_B4 = (0xF << 0) | (0xF << 4),/* 15:0 */ +}PMAT0_BITS; + /* PMAT1 0x194, 32bit register */ -#define PMR_B3 0xFF000000 /* 31:24 */ -#define PMR_B2 0x00FF0000 /* 23:16 */ -#define PMR_B1 0x0000FF00 /* 15:8 */ -#define PMR_B0 0x000000FF /* 7:0 */ +typedef enum { + PMR_B3 = (0xF << 24) | (0xF <<28),/* 31:24 */ + PMR_B2 = (0xF << 16) |(0xF << 20),/* 23:16 */ + PMR_B1 = (0xF << 8) | (0xF <<12), /* 15:8 */ + PMR_B0 = (0xF << 0)|(0xF << 4),/* 7:0 */ +}PMAT1_BITS; /************************************************************************/ /* */ @@ -615,7 +566,7 @@ #define PCI_VENDOR_ID_AMD 0x1022 #define PCI_DEVICE_ID_AMD8111E_7462 0x7462 -#define MAX_UNITS 16 /* Maximum number of devices possible */ +#define MAX_UNITS 8 /* Maximum number of devices possible */ #define NUM_TX_BUFFERS 32 /* Number of transmit buffers */ #define NUM_RX_BUFFERS 32 /* Number of receive buffers */ @@ -637,45 +588,73 @@ #define MIN_PKT_LEN 60 #define ETH_ADDR_LEN 6 +#define AMD8111E_TX_TIMEOUT (3 * HZ)/* 3 sec */ +#define SOFT_TIMER_FREQ 0xBEBC /* 0.5 sec */ +#define DELAY_TIMER_CONV 50 /* msec to 10 usec conversion. + Only 500 usec resolution */ #define OPTION_VLAN_ENABLE 0x0001 #define OPTION_JUMBO_ENABLE 0x0002 #define OPTION_MULTICAST_ENABLE 0x0004 #define OPTION_WOL_ENABLE 0x0008 #define OPTION_WAKE_MAGIC_ENABLE 0x0010 #define OPTION_WAKE_PHY_ENABLE 0x0020 +#define OPTION_INTR_COAL_ENABLE 0x0040 +#define OPTION_DYN_IPG_ENABLE 0x0080 #define PHY_REG_ADDR_MASK 0x1f +/* ipg parameters */ +#define DEFAULT_IPG 0x60 +#define IFS1_DELTA 36 +#define IPG_CONVERGE_TIME 0.5 +#define IPG_STABLE_TIME 5 +#define MIN_IPG 96 +#define MAX_IPG 255 +#define IPG_STEP 16 +#define CSTATE 1 +#define SSTATE 2 + /* Assume contoller gets data 10 times the maximum processing time */ #define REPEAT_CNT 10; /* amd8111e decriptor flag definitions */ +typedef enum { -#define OWN_BIT B15_MASK -#define ADD_FCS_BIT B13_MASK -#define LTINT_BIT B12_MASK -#define STP_BIT B9_MASK -#define ENP_BIT B8_MASK -#define KILL_BIT B6_MASK -#define TCC_MASK 0x0003 -#define TCC_VLAN_INSERT B1_MASK -#define TCC_VLAN_REPLACE 0x0003 -#define RESET_RX_FLAGS 0x0000 + OWN_BIT = (1 << 15), + ADD_FCS_BIT = (1 << 13), + LTINT_BIT = (1 << 12), + STP_BIT = (1 << 9), + ENP_BIT = (1 << 8), + KILL_BIT = (1 << 6), + TCC_VLAN_INSERT = (1 << 1), + TCC_VLAN_REPLACE = (1 << 1) |( 1<< 0), + +}TX_FLAG_BITS; + +typedef enum { + ERR_BIT = (1 << 14), + FRAM_BIT = (1 << 13), + OFLO_BIT = (1 << 12), + CRC_BIT = (1 << 11), + PAM_BIT = (1 << 6), + LAFM_BIT = (1 << 5), + BAM_BIT = (1 << 4), + TT_VLAN_TAGGED = (1 << 3) |(1 << 2),/* 0x000 */ + TT_PRTY_TAGGED = (1 << 3),/* 0x0008 */ + +}RX_FLAG_BITS; -#define ERR_BIT B14_MASK -#define FRAM_BIT B13_MASK -#define OFLO_BIT B12_MASK -#define CRC_BIT B11_MASK -#define PAM_BIT B6_MASK -#define LAFM_BIT B5_MASK -#define BAM_BIT B4_MASK +#define RESET_RX_FLAGS 0x0000 #define TT_MASK 0x000c -#define TT_VLAN_TAGGED 0x000c -#define TT_PRTY_TAGGED 0x0008 +#define TCC_MASK 0x0003 /* driver ioctl parameters */ #define PHY_ID 0x01 /* currently it is fixed */ -#define AMD8111E_REG_DUMP_LEN 4096 /* Memory mapped register length */ +#define AMD8111E_REG_DUMP_LEN 13*sizeof(u32) + +/* crc generator constants */ +#define CRC32 0xedb88320 +#define INITCRC 0xFFFFFFFF /* amd8111e desriptor format */ @@ -683,7 +662,7 @@ u16 buff_count; /* Size of the buffer pointed by this descriptor */ - u16 tx_dr_offset2; + u16 tx_flags; u16 tag_ctrl_info; @@ -704,7 +683,7 @@ u16 buff_count; /* Len of the buffer pointed by descriptor. */ - u16 rx_dr_offset10; + u16 rx_flags; u32 buff_phy_addr; @@ -719,10 +698,58 @@ u16 speed; u8 duplex; u8 autoneg; - u16 orig_speed; - u8 orig_duplex; u8 reserved; /* 32bit alignment */ }; + +enum coal_type{ + + NO_COALESCE, + LOW_COALESCE, + MEDIUM_COALESCE, + HIGH_COALESCE, + +}; + +enum coal_mode{ + RX_INTR_COAL, + TX_INTR_COAL, + DISABLE_COAL, + ENABLE_COAL, + +}; +#define MAX_TIMEOUT 40 +#define MAX_EVENT_COUNT 31 +struct amd8111e_coalesce_conf{ + + unsigned int rx_timeout; + unsigned int rx_event_count; + unsigned long rx_packets; + unsigned long rx_prev_packets; + unsigned long rx_bytes; + unsigned long rx_prev_bytes; + unsigned int rx_coal_type; + + unsigned int tx_timeout; + unsigned int tx_event_count; + unsigned long tx_packets; + unsigned long tx_prev_packets; + unsigned long tx_bytes; + unsigned long tx_prev_bytes; + unsigned int tx_coal_type; + +}; +struct ipg_info{ + + unsigned int ipg_state; + unsigned int ipg; + unsigned int current_ipg; + unsigned int col_cnt; + unsigned int diff_col_cnt; + unsigned int timer_tick; + unsigned int prev_ipg; + struct timer_list ipg_timer; +}; + struct amd8111e_priv{ struct amd8111e_tx_dr* tx_ring; @@ -742,45 +769,54 @@ void * mmio; spinlock_t lock; /* Guard lock */ - unsigned long rx_idx, tx_idx; /* The next free ring entry */ - unsigned long tx_complete_idx; + unsigned long rx_idx, tx_idx; /* The next free ring entry */ + unsigned long tx_complete_idx; unsigned long tx_ring_complete_idx; unsigned long tx_ring_idx; - int rx_buff_len; /* Buffer length of rx buffers */ + unsigned int rx_buff_len; /* Buffer length of rx buffers */ int options; /* Options enabled/disabled for the device */ + unsigned long ext_phy_option; + struct amd8111e_link_config link_config; int pm_cap; + u32 pm_state[12]; struct net_device *next; + int mii; + struct mii_if_info mii_if; #if AMD8111E_VLAN_TAG_USED struct vlan_group *vlgrp; #endif char opened; struct net_device_stats stats; - struct net_device_stats prev_stats; struct dev_mc_list* mc_list; + struct amd8111e_coalesce_conf coal_conf; + + struct ipg_info ipg_data; }; -#define AMD8111E_READ_REG64(_memMapBase, _offset, _pUlData) \ - *(u32*)(_pUlData) = readl(_memMapBase + (_offset)); \ - *((u32*)(_pUlData))+1) = readl(_memMapBase + ((_offset)+4)) - -#define AMD8111E_WRITE_REG64(_memMapBase, _offset, _pUlData) \ - writel(*(u32*)(_pUlData), _memMapBase + (_offset)); \ - writel(*(u32*)((u8*)(_pUlData)+4), _memMapBase + ((_offset)+4)) \ + +/* kernel provided writeq does not write 64 bits into the amd8111e device register instead writes only higher 32bits data into lower 32bits of the register. +BUG? */ +#define amd8111e_writeq(_UlData,_memMap) \ + writel(*(u32*)(&_UlData), _memMap); \ + writel(*(u32*)((u8*)(&_UlData)+4), _memMap+4) /* maps the external speed options to internal value */ -static unsigned char speed_duplex_mapping[] = { +typedef enum { + SPEED_AUTONEG, + SPEED10_HALF, + SPEED10_FULL, + SPEED100_HALF, + SPEED100_FULL, +}EXT_PHY_OPTION; - XPHYANE, /* Auto-negotiation, speed_duplex option 0 */ - 0, /* 10M Half, speed_duplex option 1 */ - XPHYFD, /* 10M Full, speed_duplex option 2 */ - XPHYSP, /* 100M Half, speed_duplex option 3 */ - XPHYFD | XPHYSP /* 100M Full, speed_duplex option 4 */ -}; static int card_idx; static int speed_duplex[MAX_UNITS] = { 0, }; +static int coalesce[MAX_UNITS] = {1,1,1,1,1,1,1,1}; +static int dynamic_ipg[MAX_UNITS] = {0,0,0,0,0,0,0,0}; +static unsigned int chip_version; #endif /* _AMD8111E_H */ diff -urN linux-2.4.21/drivers/net/apne.c linux-2.4.22/drivers/net/apne.c --- linux-2.4.21/drivers/net/apne.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/apne.c 2003-08-25 04:44:42.000000000 -0700 @@ -285,6 +285,7 @@ /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (" unable to get memory for dev->priv.\n"); + free_irq(IRQ_AMIGA_PORTS, dev); return -ENOMEM; } diff -urN linux-2.4.21/drivers/net/arcnet/arcnet.c linux-2.4.22/drivers/net/arcnet/arcnet.c --- linux-2.4.21/drivers/net/arcnet/arcnet.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/arcnet/arcnet.c 2003-08-25 04:44:42.000000000 -0700 @@ -343,7 +343,7 @@ dev->hard_header_len = sizeof(struct archdr); dev->mtu = choose_mtu(); - dev->addr_len = 1; + dev->addr_len = ARCNET_ALEN; dev->tx_queue_len = 30; dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */ dev->watchdog_timeo = TX_TIMEOUT; diff -urN linux-2.4.21/drivers/net/arcnet/rfc1201.c linux-2.4.22/drivers/net/arcnet/rfc1201.c --- linux-2.4.21/drivers/net/arcnet/rfc1201.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/arcnet/rfc1201.c 2003-08-25 04:44:42.000000000 -0700 @@ -56,6 +56,7 @@ void __init arcnet_rfc1201_init(void) { arc_proto_map[ARC_P_IP] + = arc_proto_map[ARC_P_IPV6] = arc_proto_map[ARC_P_ARP] = arc_proto_map[ARC_P_RARP] = arc_proto_map[ARC_P_IPX] @@ -114,6 +115,8 @@ switch (soft->proto) { case ARC_P_IP: return htons(ETH_P_IP); + case ARC_P_IPV6: + return htons(ETH_P_IPV6); case ARC_P_ARP: return htons(ETH_P_ARP); case ARC_P_RARP: @@ -388,6 +391,9 @@ case ETH_P_IP: soft->proto = ARC_P_IP; break; + case ETH_P_IPV6: + soft->proto = ARC_P_IPV6; + break; case ETH_P_ARP: soft->proto = ARC_P_ARP; break; diff -urN linux-2.4.21/drivers/net/atari_pamsnet.c linux-2.4.22/drivers/net/atari_pamsnet.c --- linux-2.4.21/drivers/net/atari_pamsnet.c 2001-10-16 21:56:29.000000000 -0700 +++ linux-2.4.22/drivers/net/atari_pamsnet.c 2003-08-25 04:44:42.000000000 -0700 @@ -170,7 +170,7 @@ static void pamsnet_intr(int irq, void *data, struct pt_regs *fp); -static struct timer_list pamsnet_timer = { function: amsnet_tick }; +static struct timer_list pamsnet_timer = { function: pamsnet_tick }; #define STRAM_ADDR(a) (((a) & 0xff000000) == 0) diff -urN linux-2.4.21/drivers/net/b44.c linux-2.4.22/drivers/net/b44.c --- linux-2.4.21/drivers/net/b44.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/b44.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1881 @@ +/* b44.c: Broadcom 4400 device driver. + * + * Copyright (C) 2002 David S. Miller (davem@redhat.com) + * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "b44.h" + +#define DRV_MODULE_NAME "b44" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "0.9" +#define DRV_MODULE_RELDATE "Jul 14, 2003" + +#define B44_DEF_MSG_ENABLE \ + (NETIF_MSG_DRV | \ + NETIF_MSG_PROBE | \ + NETIF_MSG_LINK | \ + NETIF_MSG_TIMER | \ + NETIF_MSG_IFDOWN | \ + NETIF_MSG_IFUP | \ + NETIF_MSG_RX_ERR | \ + NETIF_MSG_TX_ERR) + +/* length of time before we decide the hardware is borked, + * and dev->tx_timeout() should be called to fix the problem + */ +#define B44_TX_TIMEOUT (5 * HZ) + +/* hardware minimum and maximum for a single frame's data payload */ +#define B44_MIN_MTU 60 +#define B44_MAX_MTU 1500 + +#define B44_RX_RING_SIZE 512 +#define B44_DEF_RX_RING_PENDING 200 +#define B44_RX_RING_BYTES (sizeof(struct dma_desc) * \ + B44_RX_RING_SIZE) +#define B44_TX_RING_SIZE 512 +#define B44_DEF_TX_RING_PENDING (B44_TX_RING_SIZE - 1) +#define B44_TX_RING_BYTES (sizeof(struct dma_desc) * \ + B44_TX_RING_SIZE) + +#define TX_RING_GAP(BP) \ + (B44_TX_RING_SIZE - (BP)->tx_pending) +#define TX_BUFFS_AVAIL(BP) \ + (((BP)->tx_cons <= (BP)->tx_prod) ? \ + (BP)->tx_cons + (BP)->tx_pending - (BP)->tx_prod : \ + (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP)) +#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1)) + +#define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64) + +/* minimum number of free TX descriptors required to wake up TX process */ +#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + +MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); +MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver"); +MODULE_LICENSE("GPL"); +MODULE_PARM(b44_debug, "i"); +MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value"); + +static int b44_debug = -1; /* -1 == use B44_DEF_MSG_ENABLE as value */ + +#ifndef PCI_DEVICE_ID_BCM4401 +#define PCI_DEVICE_ID_BCM4401 0x4401 +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#define IRQ_RETVAL(x) +#define irqreturn_t void +#endif + +static struct pci_device_id b44_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { } /* terminate list with empty entry */ +}; + +MODULE_DEVICE_TABLE(pci, b44_pci_tbl); + +static void b44_halt(struct b44 *); +static void b44_init_rings(struct b44 *); +static int b44_init_hw(struct b44 *); + +static int b44_wait_bit(struct b44 *bp, unsigned long reg, + u32 bit, unsigned long timeout, const int clear) +{ + unsigned long i; + + for (i = 0; i < timeout; i++) { + u32 val = br32(reg); + + if (clear && !(val & bit)) + break; + if (!clear && (val & bit)) + break; + udelay(10); + } + if (i == timeout) { + printk(KERN_ERR PFX "%s: BUG! Timeout waiting for bit %08x of register " + "%lx to %s.\n", + bp->dev->name, + bit, reg, + (clear ? "clear" : "set")); + return -ENODEV; + } + return 0; +} + +/* Sonics SiliconBackplane support routines. ROFL, you should see all the + * buzz words used on this company's website :-) + * + * All of these routines must be invoked with bp->lock held and + * interrupts disabled. + */ + +#define SBID_SDRAM 0 +#define SBID_PCI_MEM 1 +#define SBID_PCI_CFG 2 +#define SBID_PCI_DMA 3 +#define SBID_SDRAM_SWAPPED 4 +#define SBID_ENUM 5 +#define SBID_REG_SDRAM 6 +#define SBID_REG_ILINE20 7 +#define SBID_REG_EMAC 8 +#define SBID_REG_CODEC 9 +#define SBID_REG_USB 10 +#define SBID_REG_PCI 11 +#define SBID_REG_MIPS 12 +#define SBID_REG_EXTIF 13 +#define SBID_EXTIF 14 +#define SBID_EJTAG 15 +#define SBID_MAX 16 + +static u32 ssb_get_addr(struct b44 *bp, u32 id, u32 instance) +{ + switch (id) { + case SBID_PCI_DMA: + return 0x40000000; + case SBID_ENUM: + return 0x18000000; + case SBID_REG_EMAC: + return 0x18000000; + case SBID_REG_CODEC: + return 0x18001000; + case SBID_REG_PCI: + return 0x18002000; + default: + return 0; + }; +} + +static u32 ssb_get_core_rev(struct b44 *bp) +{ + return (br32(B44_SBIDHIGH) & SBIDHIGH_RC_MASK); +} + +static u32 ssb_pci_setup(struct b44 *bp, u32 cores) +{ + u32 bar_orig, pci_rev, val; + + pci_read_config_dword(bp->pdev, SSB_BAR0_WIN, &bar_orig); + pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, + ssb_get_addr(bp, SBID_REG_PCI, 0)); + pci_rev = ssb_get_core_rev(bp); + + val = br32(B44_SBINTVEC); + val |= cores; + bw32(B44_SBINTVEC, val); + + val = br32(SSB_PCI_TRANS_2); + val |= SSB_PCI_PREF | SSB_PCI_BURST; + bw32(SSB_PCI_TRANS_2, val); + + pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, bar_orig); + + return pci_rev; +} + +static void ssb_core_disable(struct b44 *bp) +{ + if (br32(B44_SBTMSLOW) & SBTMSLOW_RESET) + return; + + bw32(B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK)); + b44_wait_bit(bp, B44_SBTMSLOW, SBTMSLOW_REJECT, 100000, 0); + b44_wait_bit(bp, B44_SBTMSHIGH, SBTMSHIGH_BUSY, 100000, 1); + bw32(B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK | + SBTMSLOW_REJECT | SBTMSLOW_RESET)); + br32(B44_SBTMSLOW); + udelay(1); + bw32(B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET)); + br32(B44_SBTMSLOW); + udelay(1); +} + +static void ssb_core_reset(struct b44 *bp) +{ + u32 val; + + ssb_core_disable(bp); + bw32(B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC)); + br32(B44_SBTMSLOW); + udelay(1); + + /* Clear SERR if set, this is a hw bug workaround. */ + if (br32(B44_SBTMSHIGH) & SBTMSHIGH_SERR) + bw32(B44_SBTMSHIGH, 0); + + val = br32(B44_SBIMSTATE); + if (val & (SBIMSTATE_IBE | SBIMSTATE_TO)) + bw32(B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO)); + + bw32(B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC)); + br32(B44_SBTMSLOW); + udelay(1); + + bw32(B44_SBTMSLOW, (SBTMSLOW_CLOCK)); + br32(B44_SBTMSLOW); + udelay(1); +} + +static int ssb_core_unit(struct b44 *bp) +{ +#if 0 + u32 val = br32(B44_SBADMATCH0); + u32 base; + + type = val & SBADMATCH0_TYPE_MASK; + switch (type) { + case 0: + base = val & SBADMATCH0_BS0_MASK; + break; + + case 1: + base = val & SBADMATCH0_BS1_MASK; + break; + + case 2: + default: + base = val & SBADMATCH0_BS2_MASK; + break; + }; +#endif + return 0; +} + +static int ssb_is_core_up(struct b44 *bp) +{ + return ((br32(B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK)) + == SBTMSLOW_CLOCK); +} + +static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index) +{ + u32 val; + + val = ((u32) data[2]) << 24; + val |= ((u32) data[3]) << 16; + val |= ((u32) data[4]) << 8; + val |= ((u32) data[5]) << 0; + bw32(B44_CAM_DATA_LO, val); + val = (CAM_DATA_HI_VALID | + (((u32) data[0]) << 8) | + (((u32) data[1]) << 0)); + bw32(B44_CAM_DATA_HI, val); + bw32(B44_CAM_CTRL, (CAM_CTRL_WRITE | + (index << CAM_CTRL_INDEX_SHIFT))); + b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1); +} + +static inline void __b44_disable_ints(struct b44 *bp) +{ + bw32(B44_IMASK, 0); +} + +static void b44_disable_ints(struct b44 *bp) +{ + __b44_disable_ints(bp); + + /* Flush posted writes. */ + br32(B44_IMASK); +} + +static void b44_enable_ints(struct b44 *bp) +{ + bw32(B44_IMASK, bp->imask); +} + +static int b44_readphy(struct b44 *bp, int reg, u32 *val) +{ + int err; + + bw32(B44_EMAC_ISTAT, EMAC_INT_MII); + bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START | + (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) | + (bp->phy_addr << MDIO_DATA_PMD_SHIFT) | + (reg << MDIO_DATA_RA_SHIFT) | + (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT))); + err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0); + *val = br32(B44_MDIO_DATA) & MDIO_DATA_DATA; + + return err; +} + +static int b44_writephy(struct b44 *bp, int reg, u32 val) +{ + bw32(B44_EMAC_ISTAT, EMAC_INT_MII); + bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START | + (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) | + (bp->phy_addr << MDIO_DATA_PMD_SHIFT) | + (reg << MDIO_DATA_RA_SHIFT) | + (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) | + (val & MDIO_DATA_DATA))); + return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0); +} + +static int b44_phy_reset(struct b44 *bp) +{ + u32 val; + int err; + + err = b44_writephy(bp, MII_BMCR, BMCR_RESET); + if (err) + return err; + udelay(100); + err = b44_readphy(bp, MII_BMCR, &val); + if (!err) { + if (val & BMCR_RESET) { + printk(KERN_ERR PFX "%s: PHY Reset would not complete.\n", + bp->dev->name); + err = -ENODEV; + } + } + + return 0; +} + +static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags) +{ + u32 val; + + bp->flags &= ~(B44_FLAG_TX_PAUSE | B44_FLAG_RX_PAUSE); + bp->flags |= pause_flags; + + val = br32(B44_RXCONFIG); + if (pause_flags & B44_FLAG_RX_PAUSE) + val |= RXCONFIG_FLOW; + else + val &= ~RXCONFIG_FLOW; + bw32(B44_RXCONFIG, val); + + val = br32(B44_MAC_FLOW); + if (pause_flags & B44_FLAG_TX_PAUSE) + val |= (MAC_FLOW_PAUSE_ENAB | + (0xc0 & MAC_FLOW_RX_HI_WATER)); + else + val &= ~MAC_FLOW_PAUSE_ENAB; + bw32(B44_MAC_FLOW, val); +} + +static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) +{ + u32 pause_enab = bp->flags & (B44_FLAG_TX_PAUSE | + B44_FLAG_RX_PAUSE); + + if (local & ADVERTISE_PAUSE_CAP) { + if (local & ADVERTISE_PAUSE_ASYM) { + if (remote & LPA_PAUSE_CAP) + pause_enab |= (B44_FLAG_TX_PAUSE | + B44_FLAG_RX_PAUSE); + else if (remote & LPA_PAUSE_ASYM) + pause_enab |= B44_FLAG_RX_PAUSE; + } else { + if (remote & LPA_PAUSE_CAP) + pause_enab |= (B44_FLAG_TX_PAUSE | + B44_FLAG_RX_PAUSE); + } + } else if (local & ADVERTISE_PAUSE_ASYM) { + if ((remote & LPA_PAUSE_CAP) && + (remote & LPA_PAUSE_ASYM)) + pause_enab |= B44_FLAG_TX_PAUSE; + } + + __b44_set_flow_ctrl(bp, pause_enab); +} + +static int b44_setup_phy(struct b44 *bp) +{ + u32 val; + int err; + + if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0) + goto out; + if ((err = b44_writephy(bp, B44_MII_ALEDCTRL, + val & MII_ALEDCTRL_ALLMSK)) != 0) + goto out; + if ((err = b44_readphy(bp, B44_MII_TLEDCTRL, &val)) != 0) + goto out; + if ((err = b44_writephy(bp, B44_MII_TLEDCTRL, + val | MII_TLEDCTRL_ENABLE)) != 0) + goto out; + + if (!(bp->flags & B44_FLAG_FORCE_LINK)) { + u32 adv = ADVERTISE_CSMA; + + if (bp->flags & B44_FLAG_ADV_10HALF) + adv |= ADVERTISE_10HALF; + if (bp->flags & B44_FLAG_ADV_10FULL) + adv |= ADVERTISE_10FULL; + if (bp->flags & B44_FLAG_ADV_100HALF) + adv |= ADVERTISE_100HALF; + if (bp->flags & B44_FLAG_ADV_100FULL) + adv |= ADVERTISE_100FULL; + + if (bp->flags & B44_FLAG_PAUSE_AUTO) + adv |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + + if ((err = b44_writephy(bp, MII_ADVERTISE, adv)) != 0) + goto out; + if ((err = b44_writephy(bp, MII_BMCR, (BMCR_ANENABLE | + BMCR_ANRESTART))) != 0) + goto out; + } else { + u32 bmcr; + + if ((err = b44_readphy(bp, MII_BMCR, &bmcr)) != 0) + goto out; + bmcr &= ~(BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100); + if (bp->flags & B44_FLAG_100_BASE_T) + bmcr |= BMCR_SPEED100; + if (bp->flags & B44_FLAG_FULL_DUPLEX) + bmcr |= BMCR_FULLDPLX; + if ((err = b44_writephy(bp, MII_BMCR, bmcr)) != 0) + goto out; + + /* Since we will not be negotiating there is no safe way + * to determine if the link partner supports flow control + * or not. So just disable it completely in this case. + */ + b44_set_flow_ctrl(bp, 0, 0); + } + +out: + return err; +} + +static void b44_stats_update(struct b44 *bp) +{ + unsigned long reg; + u32 *val; + + val = &bp->hw_stats.tx_good_octets; + for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { + *val++ += br32(reg); + } + val = &bp->hw_stats.rx_good_octets; + for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { + *val++ += br32(reg); + } +} + +static void b44_link_report(struct b44 *bp) +{ + if (!netif_carrier_ok(bp->dev)) { + printk(KERN_INFO PFX "%s: Link is down.\n", bp->dev->name); + } else { + printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n", + bp->dev->name, + (bp->flags & B44_FLAG_100_BASE_T) ? 100 : 10, + (bp->flags & B44_FLAG_FULL_DUPLEX) ? "full" : "half"); + + printk(KERN_INFO PFX "%s: Flow control is %s for TX and " + "%s for RX.\n", + bp->dev->name, + (bp->flags & B44_FLAG_TX_PAUSE) ? "on" : "off", + (bp->flags & B44_FLAG_RX_PAUSE) ? "on" : "off"); + } +} + +static void b44_check_phy(struct b44 *bp) +{ + u32 bmsr, aux; + + if (!b44_readphy(bp, MII_BMSR, &bmsr) && + !b44_readphy(bp, B44_MII_AUXCTRL, &aux) && + (bmsr != 0xffff)) { + if (aux & MII_AUXCTRL_SPEED) + bp->flags |= B44_FLAG_100_BASE_T; + else + bp->flags &= ~B44_FLAG_100_BASE_T; + if (aux & MII_AUXCTRL_DUPLEX) + bp->flags |= B44_FLAG_FULL_DUPLEX; + else + bp->flags &= ~B44_FLAG_FULL_DUPLEX; + + if (!netif_carrier_ok(bp->dev) && + (bmsr & BMSR_LSTATUS)) { + u32 val = br32(B44_TX_CTRL); + u32 local_adv, remote_adv; + + if (bp->flags & B44_FLAG_FULL_DUPLEX) + val |= TX_CTRL_DUPLEX; + else + val &= ~TX_CTRL_DUPLEX; + bw32(B44_TX_CTRL, val); + + if (!(bp->flags & B44_FLAG_FORCE_LINK) && + !b44_readphy(bp, MII_ADVERTISE, &local_adv) && + !b44_readphy(bp, MII_LPA, &remote_adv)) + b44_set_flow_ctrl(bp, local_adv, remote_adv); + + /* Link now up */ + netif_carrier_on(bp->dev); + b44_link_report(bp); + } else if (netif_carrier_ok(bp->dev) && !(bmsr & BMSR_LSTATUS)) { + /* Link now down */ + netif_carrier_off(bp->dev); + b44_link_report(bp); + } + + if (bmsr & BMSR_RFAULT) + printk(KERN_WARNING PFX "%s: Remote fault detected in PHY\n", + bp->dev->name); + if (bmsr & BMSR_JCD) + printk(KERN_WARNING PFX "%s: Jabber detected in PHY\n", + bp->dev->name); + } +} + +static void b44_timer(unsigned long __opaque) +{ + struct b44 *bp = (struct b44 *) __opaque; + + spin_lock_irq(&bp->lock); + + b44_check_phy(bp); + + b44_stats_update(bp); + + spin_unlock_irq(&bp->lock); + + bp->timer.expires = jiffies + HZ; + add_timer(&bp->timer); +} + +static void b44_tx(struct b44 *bp) +{ + u32 cur, cons; + + cur = br32(B44_DMATX_STAT) & DMATX_STAT_CDMASK; + cur /= sizeof(struct dma_desc); + + /* XXX needs updating when NETIF_F_SG is supported */ + for (cons = bp->tx_cons; cons != cur; cons = NEXT_TX(cons)) { + struct ring_info *rp = &bp->tx_buffers[cons]; + struct sk_buff *skb = rp->skb; + + if (unlikely(skb == NULL)) + BUG(); + + pci_unmap_single(bp->pdev, + pci_unmap_addr(rp, mapping), + skb->len, + PCI_DMA_TODEVICE); + rp->skb = NULL; + dev_kfree_skb_irq(skb); + } + + bp->tx_cons = cons; + if (netif_queue_stopped(bp->dev) && + TX_BUFFS_AVAIL(bp) > B44_TX_WAKEUP_THRESH) + netif_wake_queue(bp->dev); + + bw32(B44_GPTIMER, 0); +} + +/* Works like this. This chip writes a 'struct rx_header" 30 bytes + * before the DMA address you give it. So we allocate 30 more bytes + * for the RX buffer, DMA map all of it, skb_reserve the 30 bytes, then + * point the chip at 30 bytes past where the rx_header will go. + */ +static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) +{ + struct dma_desc *dp; + struct ring_info *src_map, *map; + struct rx_header *rh; + struct sk_buff *skb; + dma_addr_t mapping; + int dest_idx; + u32 ctrl; + + src_map = NULL; + if (src_idx >= 0) + src_map = &bp->rx_buffers[src_idx]; + dest_idx = dest_idx_unmasked & (B44_RX_RING_SIZE - 1); + map = &bp->rx_buffers[dest_idx]; + skb = dev_alloc_skb(RX_PKT_BUF_SZ); + if (skb == NULL) + return -ENOMEM; + + skb->dev = bp->dev; + mapping = pci_map_single(bp->pdev, skb->data, + RX_PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + skb_reserve(skb, bp->rx_offset); + + rh = (struct rx_header *) + (skb->data - bp->rx_offset); + rh->len = 0; + rh->flags = 0; + + map->skb = skb; + pci_unmap_addr_set(map, mapping, mapping); + + if (src_map != NULL) + src_map->skb = NULL; + + ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - bp->rx_offset)); + if (dest_idx == (B44_RX_RING_SIZE - 1)) + ctrl |= DESC_CTRL_EOT; + + dp = &bp->rx_ring[dest_idx]; + dp->ctrl = cpu_to_le32(ctrl); + dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset); + + return RX_PKT_BUF_SZ; +} + +static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) +{ + struct dma_desc *src_desc, *dest_desc; + struct ring_info *src_map, *dest_map; + struct rx_header *rh; + int dest_idx; + u32 ctrl; + + dest_idx = dest_idx_unmasked & (B44_RX_RING_SIZE - 1); + dest_desc = &bp->rx_ring[dest_idx]; + dest_map = &bp->rx_buffers[dest_idx]; + src_desc = &bp->rx_ring[src_idx]; + src_map = &bp->rx_buffers[src_idx]; + + dest_map->skb = src_map->skb; + rh = (struct rx_header *) src_map->skb->data; + rh->len = 0; + rh->flags = 0; + pci_unmap_addr_set(dest_map, mapping, + pci_unmap_addr(src_map, mapping)); + + ctrl = src_desc->ctrl; + if (dest_idx == (B44_RX_RING_SIZE - 1)) + ctrl |= cpu_to_le32(DESC_CTRL_EOT); + else + ctrl &= cpu_to_le32(~DESC_CTRL_EOT); + + dest_desc->ctrl = ctrl; + dest_desc->addr = src_desc->addr; + src_map->skb = NULL; +} + +static int b44_rx(struct b44 *bp, int budget) +{ + int received; + u32 cons, prod; + + received = 0; + prod = br32(B44_DMARX_STAT) & DMARX_STAT_CDMASK; + prod /= sizeof(struct dma_desc); + cons = bp->rx_cons; + + while (cons != prod && budget > 0) { + struct ring_info *rp = &bp->rx_buffers[cons]; + struct sk_buff *skb = rp->skb; + dma_addr_t map = pci_unmap_addr(rp, mapping); + struct rx_header *rh; + u16 len; + + pci_dma_sync_single(bp->pdev, map, + RX_PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + rh = (struct rx_header *) skb->data; + len = cpu_to_le16(rh->len); + if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) || + (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) { + drop_it: + b44_recycle_rx(bp, cons, bp->rx_prod); + drop_it_no_recycle: + bp->stats.rx_dropped++; + goto next_pkt; + } + + if (len == 0) { + int i = 0; + + do { + udelay(2); + barrier(); + len = cpu_to_le16(rh->len); + } while (len == 0 && i++ < 5); + if (len == 0) + goto drop_it; + } + + /* Omit CRC. */ + len -= 4; + + if (len > RX_COPY_THRESHOLD) { + int skb_size; + skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); + if (skb_size < 0) + goto drop_it; + pci_unmap_single(bp->pdev, map, + skb_size, PCI_DMA_FROMDEVICE); + /* Leave out rx_header */ + skb_put(skb, len+bp->rx_offset); + skb_pull(skb,bp->rx_offset); + } else { + struct sk_buff *copy_skb; + + b44_recycle_rx(bp, cons, bp->rx_prod); + copy_skb = dev_alloc_skb(len + 2); + if (copy_skb == NULL) + goto drop_it_no_recycle; + + copy_skb->dev = bp->dev; + skb_reserve(copy_skb, 2); + skb_put(copy_skb, len); + /* DMA sync done above, copy just the actual packet */ + memcpy(copy_skb->data, skb->data+bp->rx_offset, len); + + skb = copy_skb; + } + skb->ip_summed = CHECKSUM_NONE; + skb->protocol = eth_type_trans(skb, bp->dev); + netif_receive_skb(skb); + bp->dev->last_rx = jiffies; + received++; + budget--; + next_pkt: + bp->rx_prod = (bp->rx_prod + 1) & + (B44_RX_RING_SIZE - 1); + cons = (cons + 1) & (B44_RX_RING_SIZE - 1); + } + + bp->rx_cons = cons; + bw32(B44_DMARX_PTR, cons * sizeof(struct dma_desc)); + + return received; +} + +static int b44_poll(struct net_device *netdev, int *budget) +{ + struct b44 *bp = netdev->priv; + int done; + + spin_lock_irq(&bp->lock); + + if (bp->istat & (ISTAT_TX | ISTAT_TO)) { + /* spin_lock(&bp->tx_lock); */ + b44_tx(bp); + /* spin_unlock(&bp->tx_lock); */ + } + spin_unlock_irq(&bp->lock); + + done = 1; + if (bp->istat & ISTAT_RX) { + int orig_budget = *budget; + int work_done; + + if (orig_budget > netdev->quota) + orig_budget = netdev->quota; + + work_done = b44_rx(bp, orig_budget); + + *budget -= work_done; + netdev->quota -= work_done; + + if (work_done >= orig_budget) + done = 0; + } + + if (bp->istat & ISTAT_ERRORS) { + spin_lock_irq(&bp->lock); + b44_halt(bp); + b44_init_rings(bp); + b44_init_hw(bp); + netif_wake_queue(bp->dev); + spin_unlock_irq(&bp->lock); + done = 1; + } + + if (done) { + netif_rx_complete(netdev); + b44_enable_ints(bp); + } + + return (done ? 0 : 1); +} + +static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct b44 *bp = dev->priv; + unsigned long flags; + u32 istat, imask; + int handled = 0; + + spin_lock_irqsave(&bp->lock, flags); + + istat = br32(B44_ISTAT); + imask = br32(B44_IMASK); + + /* ??? What the fuck is the purpose of the interrupt mask + * ??? register if we have to mask it out by hand anyways? + */ + istat &= imask; + if (istat) { + handled = 1; + if (netif_rx_schedule_prep(dev)) { + /* NOTE: These writes are posted by the readback of + * the ISTAT register below. + */ + bp->istat = istat; + __b44_disable_ints(bp); + __netif_rx_schedule(dev); + } else { + printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", + dev->name); + } + + bw32(B44_ISTAT, istat); + br32(B44_ISTAT); + } + spin_unlock_irqrestore(&bp->lock, flags); + return IRQ_RETVAL(handled); +} + +static void b44_tx_timeout(struct net_device *dev) +{ + struct b44 *bp = dev->priv; + + printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", + dev->name); + + spin_lock_irq(&bp->lock); + + b44_halt(bp); + b44_init_rings(bp); + b44_init_hw(bp); + + spin_unlock_irq(&bp->lock); + + netif_wake_queue(dev); +} + +static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct b44 *bp = dev->priv; + dma_addr_t mapping; + u32 len, entry, ctrl; + + len = skb->len; + spin_lock_irq(&bp->lock); + + /* This is a hard error, log it. */ + if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { + netif_stop_queue(dev); + spin_unlock_irq(&bp->lock); + printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", + dev->name); + return 1; + } + + entry = bp->tx_prod; + mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); + + bp->tx_buffers[entry].skb = skb; + pci_unmap_addr_set(&bp->tx_buffers[entry], mapping, mapping); + + ctrl = (len & DESC_CTRL_LEN); + ctrl |= DESC_CTRL_IOC | DESC_CTRL_SOF | DESC_CTRL_EOF; + if (entry == (B44_TX_RING_SIZE - 1)) + ctrl |= DESC_CTRL_EOT; + + bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl); + bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset); + + entry = NEXT_TX(entry); + + bp->tx_prod = entry; + + wmb(); + + bw32(B44_DMATX_PTR, entry * sizeof(struct dma_desc)); + if (bp->flags & B44_FLAG_BUGGY_TXPTR) + bw32(B44_DMATX_PTR, entry * sizeof(struct dma_desc)); + if (bp->flags & B44_FLAG_REORDER_BUG) + br32(B44_DMATX_PTR); + + if (TX_BUFFS_AVAIL(bp) < 1) + netif_stop_queue(dev); + + spin_unlock_irq(&bp->lock); + + dev->trans_start = jiffies; + + return 0; +} + +static int b44_change_mtu(struct net_device *dev, int new_mtu) +{ + struct b44 *bp = dev->priv; + + if (new_mtu < B44_MIN_MTU || new_mtu > B44_MAX_MTU) + return -EINVAL; + + if (!netif_running(dev)) { + /* We'll just catch it later when the + * device is up'd. + */ + dev->mtu = new_mtu; + return 0; + } + + spin_lock_irq(&bp->lock); + b44_halt(bp); + dev->mtu = new_mtu; + b44_init_rings(bp); + b44_init_hw(bp); + spin_unlock_irq(&bp->lock); + + return 0; +} + +/* Free up pending packets in all rx/tx rings. + * + * The chip has been shut down and the driver detached from + * the networking, so no interrupts or new tx packets will + * end up in the driver. bp->lock is not held and we are not + * in an interrupt context and thus may sleep. + */ +static void b44_free_rings(struct b44 *bp) +{ + struct ring_info *rp; + int i; + + for (i = 0; i < B44_RX_RING_SIZE; i++) { + rp = &bp->rx_buffers[i]; + + if (rp->skb == NULL) + continue; + pci_unmap_single(bp->pdev, + pci_unmap_addr(rp, mapping), + RX_PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + dev_kfree_skb_any(rp->skb); + rp->skb = NULL; + } + + /* XXX needs changes once NETIF_F_SG is set... */ + for (i = 0; i < B44_TX_RING_SIZE; i++) { + rp = &bp->tx_buffers[i]; + + if (rp->skb == NULL) + continue; + pci_unmap_single(bp->pdev, + pci_unmap_addr(rp, mapping), + rp->skb->len, + PCI_DMA_TODEVICE); + dev_kfree_skb_any(rp->skb); + rp->skb = NULL; + } +} + +/* Initialize tx/rx rings for packet processing. + * + * The chip has been shut down and the driver detached from + * the networking, so no interrupts or new tx packets will + * end up in the driver. bp->lock is not held and we are not + * in an interrupt context and thus may sleep. + */ +static void b44_init_rings(struct b44 *bp) +{ + int i; + + b44_free_rings(bp); + + memset(bp->rx_ring, 0, B44_RX_RING_BYTES); + memset(bp->tx_ring, 0, B44_TX_RING_BYTES); + + for (i = 0; i < bp->rx_pending; i++) { + if (b44_alloc_rx_skb(bp, -1, i) < 0) + break; + } +} + +/* + * Must not be invoked with interrupt sources disabled and + * the hardware shutdown down. + */ +static void b44_free_consistent(struct b44 *bp) +{ + if (bp->rx_buffers) { + kfree(bp->rx_buffers); + bp->rx_buffers = NULL; + } + if (bp->tx_buffers) { + kfree(bp->tx_buffers); + bp->tx_buffers = NULL; + } + if (bp->rx_ring) { + pci_free_consistent(bp->pdev, DMA_TABLE_BYTES, + bp->rx_ring, bp->rx_ring_dma); + bp->rx_ring = NULL; + } + if (bp->tx_ring) { + pci_free_consistent(bp->pdev, DMA_TABLE_BYTES, + bp->tx_ring, bp->tx_ring_dma); + bp->tx_ring = NULL; + } +} + +/* + * Must not be invoked with interrupt sources disabled and + * the hardware shutdown down. Can sleep. + */ +static int b44_alloc_consistent(struct b44 *bp) +{ + int size; + + size = B44_RX_RING_SIZE * sizeof(struct ring_info); + bp->rx_buffers = kmalloc(size, GFP_KERNEL); + if (!bp->rx_buffers) + goto out_err; + memset(bp->rx_buffers, 0, size); + + size = B44_TX_RING_SIZE * sizeof(struct ring_info); + bp->tx_buffers = kmalloc(size, GFP_KERNEL); + if (!bp->tx_buffers) + goto out_err; + memset(bp->tx_buffers, 0, size); + + size = DMA_TABLE_BYTES; + bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); + if (!bp->rx_ring) + goto out_err; + + bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma); + if (!bp->tx_ring) + goto out_err; + + return 0; + +out_err: + b44_free_consistent(bp); + return -ENOMEM; +} + +/* bp->lock is held. */ +static void b44_clear_stats(struct b44 *bp) +{ + unsigned long reg; + + bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); + for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) + br32(reg); + for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) + br32(reg); +} + +/* bp->lock is held. */ +static void b44_chip_reset(struct b44 *bp) +{ + if (ssb_is_core_up(bp)) { + bw32(B44_RCV_LAZY, 0); + bw32(B44_ENET_CTRL, ENET_CTRL_DISABLE); + b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1); + bw32(B44_DMATX_CTRL, 0); + bp->tx_prod = bp->tx_cons = 0; + if (br32(B44_DMARX_STAT) & DMARX_STAT_EMASK) { + b44_wait_bit(bp, B44_DMARX_STAT, DMARX_STAT_SIDLE, + 100, 0); + } + bw32(B44_DMARX_CTRL, 0); + bp->rx_prod = bp->rx_cons = 0; + } else { + ssb_pci_setup(bp, (bp->core_unit == 0 ? + SBINTVEC_ENET0 : + SBINTVEC_ENET1)); + } + + ssb_core_reset(bp); + + b44_clear_stats(bp); + + /* Make PHY accessible. */ + bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE | + (0x0d & MDIO_CTRL_MAXF_MASK))); + br32(B44_MDIO_CTRL); + + if (!(br32(B44_DEVCTRL) & DEVCTRL_IPP)) { + bw32(B44_ENET_CTRL, ENET_CTRL_EPSEL); + br32(B44_ENET_CTRL); + bp->flags &= ~B44_FLAG_INTERNAL_PHY; + } else { + u32 val = br32(B44_DEVCTRL); + + if (val & DEVCTRL_EPR) { + bw32(B44_DEVCTRL, (val & ~DEVCTRL_EPR)); + br32(B44_DEVCTRL); + udelay(100); + } + bp->flags |= B44_FLAG_INTERNAL_PHY; + } +} + +/* bp->lock is held. */ +static void b44_halt(struct b44 *bp) +{ + b44_disable_ints(bp); + b44_chip_reset(bp); +} + +/* bp->lock is held. */ +static void __b44_set_mac_addr(struct b44 *bp) +{ + bw32(B44_CAM_CTRL, 0); + if (!(bp->dev->flags & IFF_PROMISC)) { + u32 val; + + __b44_cam_write(bp, bp->dev->dev_addr, 0); + val = br32(B44_CAM_CTRL); + bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE); + } +} + +static int b44_set_mac_addr(struct net_device *dev, void *p) +{ + struct b44 *bp = dev->priv; + struct sockaddr *addr = p; + + if (netif_running(dev)) + return -EBUSY; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + spin_lock_irq(&bp->lock); + __b44_set_mac_addr(bp); + spin_unlock_irq(&bp->lock); + + return 0; +} + +/* Called at device open time to get the chip ready for + * packet processing. Invoked with bp->lock held. + */ +static void __b44_set_rx_mode(struct net_device *); +static int b44_init_hw(struct b44 *bp) +{ + u32 val; + + b44_disable_ints(bp); + b44_chip_reset(bp); + b44_phy_reset(bp); + b44_setup_phy(bp); + val = br32(B44_MAC_CTRL); + bw32(B44_MAC_CTRL, val | MAC_CTRL_CRC32_ENAB); + bw32(B44_RCV_LAZY, (1 << RCV_LAZY_FC_SHIFT)); + + /* This sets the MAC address too. */ + __b44_set_rx_mode(bp->dev); + + /* MTU + eth header + possible VLAN tag + struct rx_header */ + bw32(B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); + bw32(B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); + + bw32(B44_TX_WMARK, 56); /* XXX magic */ + bw32(B44_DMATX_CTRL, DMATX_CTRL_ENABLE); + bw32(B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); + bw32(B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | + (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + bw32(B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); + + bw32(B44_DMARX_PTR, bp->rx_pending); + bp->rx_prod = bp->rx_pending; + + bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); + + val = br32(B44_ENET_CTRL); + bw32(B44_ENET_CTRL, (val | ENET_CTRL_ENABLE)); + + return 0; +} + +static int b44_open(struct net_device *dev) +{ + struct b44 *bp = dev->priv; + int err; + + err = b44_alloc_consistent(bp); + if (err) + return err; + + err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev); + if (err) + goto err_out_free; + + spin_lock_irq(&bp->lock); + + b44_init_rings(bp); + err = b44_init_hw(bp); + if (err) + goto err_out_noinit; + bp->flags |= B44_FLAG_INIT_COMPLETE; + + spin_unlock_irq(&bp->lock); + + init_timer(&bp->timer); + bp->timer.expires = jiffies + HZ; + bp->timer.data = (unsigned long) bp; + bp->timer.function = b44_timer; + add_timer(&bp->timer); + + b44_enable_ints(bp); + + return 0; + +err_out_noinit: + b44_halt(bp); + b44_free_rings(bp); + spin_unlock_irq(&bp->lock); + free_irq(dev->irq, dev); +err_out_free: + b44_free_consistent(bp); + return err; +} + +#if 0 +/*static*/ void b44_dump_state(struct b44 *bp) +{ + u32 val32, val32_2, val32_3, val32_4, val32_5; + u16 val16; + + pci_read_config_word(bp->pdev, PCI_STATUS, &val16); + printk("DEBUG: PCI status [%04x] \n", val16); + +} +#endif + +static int b44_close(struct net_device *dev) +{ + struct b44 *bp = dev->priv; + + netif_stop_queue(dev); + + del_timer_sync(&bp->timer); + + spin_lock_irq(&bp->lock); + +#if 0 + b44_dump_state(bp); +#endif + b44_halt(bp); + b44_free_rings(bp); + bp->flags &= ~B44_FLAG_INIT_COMPLETE; + netif_carrier_off(bp->dev); + + spin_unlock_irq(&bp->lock); + + free_irq(dev->irq, dev); + + b44_free_consistent(bp); + + return 0; +} + +static struct net_device_stats *b44_get_stats(struct net_device *dev) +{ + struct b44 *bp = dev->priv; + struct net_device_stats *nstat = &bp->stats; + struct b44_hw_stats *hwstat = &bp->hw_stats; + + /* Convert HW stats into netdevice stats. */ + nstat->rx_packets = hwstat->rx_pkts; + nstat->tx_packets = hwstat->tx_pkts; + nstat->rx_bytes = hwstat->rx_octets; + nstat->tx_bytes = hwstat->tx_octets; + nstat->tx_errors = (hwstat->tx_jabber_pkts + + hwstat->tx_oversize_pkts + + hwstat->tx_underruns + + hwstat->tx_excessive_cols + + hwstat->tx_late_cols); + nstat->multicast = hwstat->tx_multicast_pkts; + nstat->collisions = hwstat->tx_total_cols; + + nstat->rx_length_errors = (hwstat->rx_oversize_pkts + + hwstat->rx_undersize); + nstat->rx_over_errors = hwstat->rx_missed_pkts; + nstat->rx_frame_errors = hwstat->rx_align_errs; + nstat->rx_crc_errors = hwstat->rx_crc_errs; + nstat->rx_errors = (hwstat->rx_jabber_pkts + + hwstat->rx_oversize_pkts + + hwstat->rx_missed_pkts + + hwstat->rx_crc_align_errs + + hwstat->rx_undersize + + hwstat->rx_crc_errs + + hwstat->rx_align_errs + + hwstat->rx_symbol_errs); + + nstat->tx_aborted_errors = hwstat->tx_underruns; + nstat->tx_carrier_errors = hwstat->tx_carrier_lost; + + return nstat; +} + +static void __b44_load_mcast(struct b44 *bp, struct net_device *dev) +{ + struct dev_mc_list *mclist; + int i, num_ents; + + num_ents = min_t(int, dev->mc_count, B44_MCAST_TABLE_SIZE); + mclist = dev->mc_list; + for (i = 0; mclist && i < num_ents; i++, mclist = mclist->next) { + __b44_cam_write(bp, mclist->dmi_addr, i + 1); + } +} + +static void __b44_set_rx_mode(struct net_device *dev) +{ + struct b44 *bp = dev->priv; + u32 val; + + val = br32(B44_RXCONFIG); + val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); + if (dev->flags & IFF_PROMISC) { + val |= RXCONFIG_PROMISC; + bw32(B44_RXCONFIG, val); + } else { + __b44_set_mac_addr(bp); + + if (dev->flags & IFF_ALLMULTI) + val |= RXCONFIG_ALLMULTI; + else + __b44_load_mcast(bp, dev); + + bw32(B44_RXCONFIG, val); + val = br32(B44_CAM_CTRL); + bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE); + } +} + +static void b44_set_rx_mode(struct net_device *dev) +{ + struct b44 *bp = dev->priv; + + spin_lock_irq(&bp->lock); + __b44_set_rx_mode(dev); + spin_unlock_irq(&bp->lock); +} + +static int b44_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + struct b44 *bp = dev->priv; + struct pci_dev *pci_dev = bp->pdev; + u32 ethcmd; + + if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO:{ + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_MODULE_NAME); + strcpy (info.version, DRV_MODULE_VERSION); + memset(&info.fw_version, 0, sizeof(info.fw_version)); + strcpy (info.bus_info, pci_dev->slot_name); + info.eedump_len = 0; + info.regdump_len = 0; + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + case ETHTOOL_GSET: { + struct ethtool_cmd cmd = { ETHTOOL_GSET }; + + if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) + return -EAGAIN; + cmd.supported = (SUPPORTED_Autoneg); + cmd.supported |= (SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_MII); + + cmd.advertising = 0; + if (bp->flags & B44_FLAG_ADV_10HALF) + cmd.advertising |= ADVERTISE_10HALF; + if (bp->flags & B44_FLAG_ADV_10FULL) + cmd.advertising |= ADVERTISE_10FULL; + if (bp->flags & B44_FLAG_ADV_100HALF) + cmd.advertising |= ADVERTISE_100HALF; + if (bp->flags & B44_FLAG_ADV_100FULL) + cmd.advertising |= ADVERTISE_100FULL; + cmd.advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + cmd.speed = (bp->flags & B44_FLAG_100_BASE_T) ? + SPEED_100 : SPEED_10; + cmd.duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ? + DUPLEX_FULL : DUPLEX_HALF; + cmd.port = 0; + cmd.phy_address = bp->phy_addr; + cmd.transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ? + XCVR_INTERNAL : XCVR_EXTERNAL; + cmd.autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ? + AUTONEG_DISABLE : AUTONEG_ENABLE; + cmd.maxtxpkt = 0; + cmd.maxrxpkt = 0; + if (copy_to_user(useraddr, &cmd, sizeof(cmd))) + return -EFAULT; + return 0; + } + case ETHTOOL_SSET: { + struct ethtool_cmd cmd; + + if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) + return -EAGAIN; + + if (copy_from_user(&cmd, useraddr, sizeof(cmd))) + return -EFAULT; + + /* We do not support gigabit. */ + if (cmd.autoneg == AUTONEG_ENABLE) { + if (cmd.advertising & + (ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full)) + return -EINVAL; + } else if ((cmd.speed != SPEED_100 && + cmd.speed != SPEED_10) || + (cmd.duplex != DUPLEX_HALF && + cmd.duplex != DUPLEX_FULL)) { + return -EINVAL; + } + + spin_lock_irq(&bp->lock); + + if (cmd.autoneg == AUTONEG_ENABLE) { + bp->flags &= ~B44_FLAG_FORCE_LINK; + bp->flags &= ~(B44_FLAG_ADV_10HALF | + B44_FLAG_ADV_10FULL | + B44_FLAG_ADV_100HALF | + B44_FLAG_ADV_100FULL); + if (cmd.advertising & ADVERTISE_10HALF) + bp->flags |= B44_FLAG_ADV_10HALF; + if (cmd.advertising & ADVERTISE_10FULL) + bp->flags |= B44_FLAG_ADV_10FULL; + if (cmd.advertising & ADVERTISE_100HALF) + bp->flags |= B44_FLAG_ADV_100HALF; + if (cmd.advertising & ADVERTISE_100FULL) + bp->flags |= B44_FLAG_ADV_100FULL; + } else { + bp->flags |= B44_FLAG_FORCE_LINK; + if (cmd.speed == SPEED_100) + bp->flags |= B44_FLAG_100_BASE_T; + if (cmd.duplex == DUPLEX_FULL) + bp->flags |= B44_FLAG_FULL_DUPLEX; + } + + b44_setup_phy(bp); + + spin_unlock_irq(&bp->lock); + + return 0; + } + + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + edata.data = bp->msg_enable; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + bp->msg_enable = edata.data; + return 0; + } + case ETHTOOL_NWAY_RST: { + u32 bmcr; + int r; + + spin_lock_irq(&bp->lock); + b44_readphy(bp, MII_BMCR, &bmcr); + b44_readphy(bp, MII_BMCR, &bmcr); + r = -EINVAL; + if (bmcr & BMCR_ANENABLE) { + b44_writephy(bp, MII_BMCR, + bmcr | BMCR_ANRESTART); + r = 0; + } + spin_unlock_irq(&bp->lock); + + return r; + } + case ETHTOOL_GLINK: { + struct ethtool_value edata = { ETHTOOL_GLINK }; + edata.data = netif_carrier_ok(bp->dev) ? 1 : 0; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + case ETHTOOL_GRINGPARAM: { + struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM }; + + ering.rx_max_pending = B44_RX_RING_SIZE - 1; + ering.rx_pending = bp->rx_pending; + + /* XXX ethtool lacks a tx_max_pending, oops... */ + + if (copy_to_user(useraddr, &ering, sizeof(ering))) + return -EFAULT; + return 0; + } + case ETHTOOL_SRINGPARAM: { + struct ethtool_ringparam ering; + + if (copy_from_user(&ering, useraddr, sizeof(ering))) + return -EFAULT; + + if ((ering.rx_pending > B44_RX_RING_SIZE - 1) || + (ering.rx_mini_pending != 0) || + (ering.rx_jumbo_pending != 0) || + (ering.tx_pending > B44_TX_RING_SIZE - 1)) + return -EINVAL; + + spin_lock_irq(&bp->lock); + + bp->rx_pending = ering.rx_pending; + bp->tx_pending = ering.tx_pending; + + b44_halt(bp); + b44_init_rings(bp); + b44_init_hw(bp); + netif_wake_queue(bp->dev); + spin_unlock_irq(&bp->lock); + + return 0; + } + case ETHTOOL_GPAUSEPARAM: { + struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM }; + + epause.autoneg = + (bp->flags & B44_FLAG_PAUSE_AUTO) != 0; + epause.rx_pause = + (bp->flags & B44_FLAG_RX_PAUSE) != 0; + epause.tx_pause = + (bp->flags & B44_FLAG_TX_PAUSE) != 0; + if (copy_to_user(useraddr, &epause, sizeof(epause))) + return -EFAULT; + return 0; + } + case ETHTOOL_SPAUSEPARAM: { + struct ethtool_pauseparam epause; + + if (copy_from_user(&epause, useraddr, sizeof(epause))) + return -EFAULT; + + spin_lock_irq(&bp->lock); + if (epause.autoneg) + bp->flags |= B44_FLAG_PAUSE_AUTO; + else + bp->flags &= ~B44_FLAG_PAUSE_AUTO; + if (epause.rx_pause) + bp->flags |= B44_FLAG_RX_PAUSE; + else + bp->flags &= ~B44_FLAG_RX_PAUSE; + if (epause.tx_pause) + bp->flags |= B44_FLAG_TX_PAUSE; + else + bp->flags &= ~B44_FLAG_TX_PAUSE; + if (bp->flags & B44_FLAG_PAUSE_AUTO) { + b44_halt(bp); + b44_init_rings(bp); + b44_init_hw(bp); + } else { + __b44_set_flow_ctrl(bp, bp->flags); + } + spin_unlock_irq(&bp->lock); + + return 0; + } + }; + + return -EOPNOTSUPP; +} + +static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; + struct b44 *bp = dev->priv; + int err; + + switch (cmd) { + case SIOCETHTOOL: + return b44_ethtool_ioctl(dev, (void *) ifr->ifr_data); + + case SIOCGMIIPHY: + data->phy_id = bp->phy_addr; + + /* fallthru */ + case SIOCGMIIREG: { + u32 mii_regval; + + spin_lock_irq(&bp->lock); + err = b44_readphy(bp, data->reg_num & 0x1f, &mii_regval); + spin_unlock_irq(&bp->lock); + + data->val_out = mii_regval; + + return err; + } + + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + spin_lock_irq(&bp->lock); + err = b44_writephy(bp, data->reg_num & 0x1f, data->val_in); + spin_unlock_irq(&bp->lock); + + return err; + + default: + /* do nothing */ + break; + }; + return -EOPNOTSUPP; +} + +/* Read 128-bytes of EEPROM. */ +static int b44_read_eeprom(struct b44 *bp, u8 *data) +{ + long i; + u16 *ptr = (u16 *) data; + + for (i = 0; i < 128; i += 2) + ptr[i / 2] = readw(bp->regs + 4096 + i); + + return 0; +} + +static int __devinit b44_get_invariants(struct b44 *bp) +{ + u8 eeprom[128]; + int err; + + err = b44_read_eeprom(bp, &eeprom[0]); + if (err) + goto out; + + bp->dev->dev_addr[0] = eeprom[79]; + bp->dev->dev_addr[1] = eeprom[78]; + bp->dev->dev_addr[2] = eeprom[81]; + bp->dev->dev_addr[3] = eeprom[80]; + bp->dev->dev_addr[4] = eeprom[83]; + bp->dev->dev_addr[5] = eeprom[82]; + + bp->phy_addr = eeprom[90] & 0x1f; + bp->mdc_port = (eeprom[90] >> 14) & 0x1; + + /* With this, plus the rx_header prepended to the data by the + * hardware, we'll land the ethernet header on a 2-byte boundary. + */ + bp->rx_offset = 30; + + bp->imask = IMASK_DEF; + + bp->core_unit = ssb_core_unit(bp); + bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0); + + /* XXX - really required? + bp->flags |= B44_FLAG_BUGGY_TXPTR; + */ +out: + return err; +} + +static int __devinit b44_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static int b44_version_printed = 0; + unsigned long b44reg_base, b44reg_len; + struct net_device *dev; + struct b44 *bp; + int err, i; + + if (b44_version_printed++ == 0) + printk(KERN_INFO "%s", version); + + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR PFX "Cannot enable PCI device, " + "aborting.\n"); + return err; + } + + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { + printk(KERN_ERR PFX "Cannot find proper PCI device " + "base address, aborting.\n"); + err = -ENODEV; + goto err_out_disable_pdev; + } + + err = pci_request_regions(pdev, DRV_MODULE_NAME); + if (err) { + printk(KERN_ERR PFX "Cannot obtain PCI resources, " + "aborting.\n"); + goto err_out_disable_pdev; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, (u64) 0xffffffff); + if (err) { + printk(KERN_ERR PFX "No usable DMA configuration, " + "aborting.\n"); + goto err_out_free_res; + } + + b44reg_base = pci_resource_start(pdev, 0); + b44reg_len = pci_resource_len(pdev, 0); + + dev = alloc_etherdev(sizeof(*bp)); + if (!dev) { + printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + err = -ENOMEM; + goto err_out_free_res; + } + + SET_MODULE_OWNER(dev); + + /* No interesting netdevice features in this card... */ + dev->features |= 0; + + bp = dev->priv; + bp->pdev = pdev; + bp->dev = dev; + if (b44_debug >= 0) + bp->msg_enable = (1 << b44_debug) - 1; + else + bp->msg_enable = B44_DEF_MSG_ENABLE; + + spin_lock_init(&bp->lock); + + bp->regs = (unsigned long) ioremap(b44reg_base, b44reg_len); + if (bp->regs == 0UL) { + printk(KERN_ERR PFX "Cannot map device registers, " + "aborting.\n"); + err = -ENOMEM; + goto err_out_free_dev; + } + + bp->rx_pending = B44_DEF_RX_RING_PENDING; + bp->tx_pending = B44_DEF_TX_RING_PENDING; + + dev->open = b44_open; + dev->stop = b44_close; + dev->hard_start_xmit = b44_start_xmit; + dev->get_stats = b44_get_stats; + dev->set_multicast_list = b44_set_rx_mode; + dev->set_mac_address = b44_set_mac_addr; + dev->do_ioctl = b44_ioctl; + dev->tx_timeout = b44_tx_timeout; + dev->poll = b44_poll; + dev->weight = 64; + dev->watchdog_timeo = B44_TX_TIMEOUT; + dev->change_mtu = b44_change_mtu; + dev->irq = pdev->irq; + + err = b44_get_invariants(bp); + if (err) { + printk(KERN_ERR PFX "Problem fetching invariants of chip, " + "aborting.\n"); + goto err_out_iounmap; + } + + /* By default, advertise all speed/duplex settings. */ + bp->flags |= (B44_FLAG_ADV_10HALF | B44_FLAG_ADV_10FULL | + B44_FLAG_ADV_100HALF | B44_FLAG_ADV_100FULL); + + /* By default, auto-negotiate PAUSE. */ + bp->flags |= B44_FLAG_PAUSE_AUTO; + + err = register_netdev(dev); + if (err) { + printk(KERN_ERR PFX "Cannot register net device, " + "aborting.\n"); + goto err_out_iounmap; + } + + pci_set_drvdata(pdev, dev); + + pci_save_state(bp->pdev, bp->pci_cfg_state); + + printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); + for (i = 0; i < 6; i++) + printk("%2.2x%c", dev->dev_addr[i], + i == 5 ? '\n' : ':'); + + return 0; + +err_out_iounmap: + iounmap((void *) bp->regs); + +err_out_free_dev: + kfree(dev); + +err_out_free_res: + pci_release_regions(pdev); + +err_out_disable_pdev: + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + return err; +} + +static void __devexit b44_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + if (dev) { + unregister_netdev(dev); + iounmap((void *) ((struct b44 *)(dev->priv))->regs); + kfree(dev); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + } +} + +static struct pci_driver b44_driver = { + .name = DRV_MODULE_NAME, + .id_table = b44_pci_tbl, + .probe = b44_init_one, + .remove = __devexit_p(b44_remove_one), +}; + +static int __init b44_init(void) +{ + return pci_module_init(&b44_driver); +} + +static void __exit b44_cleanup(void) +{ + pci_unregister_driver(&b44_driver); +} + +module_init(b44_init); +module_exit(b44_cleanup); + diff -urN linux-2.4.21/drivers/net/b44.h linux-2.4.22/drivers/net/b44.h --- linux-2.4.21/drivers/net/b44.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/b44.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,543 @@ +#ifndef _B44_H +#define _B44_H + +/* Register layout. */ +#define B44_DEVCTRL 0x0000UL /* Device Control */ +#define DEVCTRL_PFE 0x00000080 /* Pattern Filtering Enable */ +#define DEVCTRL_IPP 0x00000400 /* Internal EPHY Present */ +#define DEVCTRL_EPR 0x00008000 /* EPHY Reset */ +#define DEVCTRL_PME 0x00001000 /* PHY Mode Enable */ +#define DEVCTRL_PMCE 0x00002000 /* PHY Mode Clocks Enable */ +#define DEVCTRL_PADDR 0x0007c000 /* PHY Address */ +#define DEVCTRL_PADDR_SHIFT 18 +#define B44_BIST_STAT 0x000CUL /* Built-In Self-Test Status */ +#define B44_WKUP_LEN 0x0010UL /* Wakeup Length */ +#define WKUP_LEN_P0_MASK 0x0000007f /* Pattern 0 */ +#define WKUP_LEN_D0 0x00000080 +#define WKUP_LEN_P1_MASK 0x00007f00 /* Pattern 1 */ +#define WKUP_LEN_P1_SHIFT 8 +#define WKUP_LEN_D1 0x00008000 +#define WKUP_LEN_P2_MASK 0x007f0000 /* Pattern 2 */ +#define WKUP_LEN_P2_SHIFT 16 +#define WKUP_LEN_D2 0x00000000 +#define WKUP_LEN_P3_MASK 0x7f000000 /* Pattern 3 */ +#define WKUP_LEN_P3_SHIFT 24 +#define WKUP_LEN_D3 0x80000000 +#define B44_ISTAT 0x0020UL /* Interrupt Status */ +#define ISTAT_PME 0x00000040 /* Power Management Event */ +#define ISTAT_TO 0x00000080 /* General Purpose Timeout */ +#define ISTAT_DSCE 0x00000400 /* Descriptor Error */ +#define ISTAT_DATAE 0x00000800 /* Data Error */ +#define ISTAT_DPE 0x00001000 /* Descr. Protocol Error */ +#define ISTAT_RDU 0x00002000 /* Receive Descr. Underflow */ +#define ISTAT_RFO 0x00004000 /* Receive FIFO Overflow */ +#define ISTAT_TFU 0x00008000 /* Transmit FIFO Underflow */ +#define ISTAT_RX 0x00010000 /* RX Interrupt */ +#define ISTAT_TX 0x01000000 /* TX Interrupt */ +#define ISTAT_EMAC 0x04000000 /* EMAC Interrupt */ +#define ISTAT_MII_WRITE 0x08000000 /* MII Write Interrupt */ +#define ISTAT_MII_READ 0x10000000 /* MII Read Interrupt */ +#define ISTAT_ERRORS (ISTAT_DSCE|ISTAT_DATAE|ISTAT_DPE|ISTAT_RDU|ISTAT_RFO|ISTAT_TFU) +#define B44_IMASK 0x0024UL /* Interrupt Mask */ +#define IMASK_DEF (ISTAT_ERRORS | ISTAT_TO | ISTAT_RX | ISTAT_TX) +#define B44_GPTIMER 0x0028UL /* General Purpose Timer */ +#define B44_FILT_ADDR 0x0090UL /* ENET Filter Address */ +#define B44_FILT_DATA 0x0094UL /* ENET Filter Data */ +#define B44_TXBURST 0x00A0UL /* TX Max Burst Length */ +#define B44_RXBURST 0x00A4UL /* RX Max Burst Length */ +#define B44_MAC_CTRL 0x00A8UL /* MAC Control */ +#define MAC_CTRL_CRC32_ENAB 0x00000001 /* CRC32 Generation Enable */ +#define MAC_CTRL_PHY_PDOWN 0x00000004 /* Onchip EPHY Powerdown */ +#define MAC_CTRL_PHY_EDET 0x00000008 /* Onchip EPHY Energy Detected */ +#define MAC_CTRL_PHY_LEDCTRL 0x000000e0 /* Onchip EPHY LED Control */ +#define MAC_CTRL_PHY_LEDCTRL_SHIFT 5 +#define B44_MAC_FLOW 0x00ACUL /* MAC Flow Control */ +#define MAC_FLOW_RX_HI_WATER 0x000000ff /* Receive FIFO HI Water Mark */ +#define MAC_FLOW_PAUSE_ENAB 0x00008000 /* Enable Pause Frame Generation */ +#define B44_RCV_LAZY 0x0100UL /* Lazy Interrupt Control */ +#define RCV_LAZY_TO_MASK 0x00ffffff /* Timeout */ +#define RCV_LAZY_FC_MASK 0xff000000 /* Frame Count */ +#define RCV_LAZY_FC_SHIFT 24 +#define B44_DMATX_CTRL 0x0200UL /* DMA TX Control */ +#define DMATX_CTRL_ENABLE 0x00000001 /* Enable */ +#define DMATX_CTRL_SUSPEND 0x00000002 /* Suepend Request */ +#define DMATX_CTRL_LPBACK 0x00000004 /* Loopback Enable */ +#define DMATX_CTRL_FAIRPRIOR 0x00000008 /* Fair Priority */ +#define DMATX_CTRL_FLUSH 0x00000010 /* Flush Request */ +#define B44_DMATX_ADDR 0x0204UL /* DMA TX Descriptor Ring Address */ +#define B44_DMATX_PTR 0x0208UL /* DMA TX Last Posted Descriptor */ +#define B44_DMATX_STAT 0x020CUL /* DMA TX Current Active Desc. + Status */ +#define DMATX_STAT_CDMASK 0x00000fff /* Current Descriptor Mask */ +#define DMATX_STAT_SMASK 0x0000f000 /* State Mask */ +#define DMATX_STAT_SDISABLED 0x00000000 /* State Disabled */ +#define DMATX_STAT_SACTIVE 0x00001000 /* State Active */ +#define DMATX_STAT_SIDLE 0x00002000 /* State Idle Wait */ +#define DMATX_STAT_SSTOPPED 0x00003000 /* State Stopped */ +#define DMATX_STAT_SSUSP 0x00004000 /* State Suspend Pending */ +#define DMATX_STAT_EMASK 0x000f0000 /* Error Mask */ +#define DMATX_STAT_ENONE 0x00000000 /* Error None */ +#define DMATX_STAT_EDPE 0x00010000 /* Error Desc. Protocol Error */ +#define DMATX_STAT_EDFU 0x00020000 /* Error Data FIFO Underrun */ +#define DMATX_STAT_EBEBR 0x00030000 /* Error Bus Error on Buffer Read */ +#define DMATX_STAT_EBEDA 0x00040000 /* Error Bus Error on Desc. Access */ +#define DMATX_STAT_FLUSHED 0x00100000 /* Flushed */ +#define B44_DMARX_CTRL 0x0210UL /* DMA RX Control */ +#define DMARX_CTRL_ENABLE 0x00000001 /* Enable */ +#define DMARX_CTRL_ROMASK 0x000000fe /* Receive Offset Mask */ +#define DMARX_CTRL_ROSHIFT 1 /* Receive Offset Shift */ +#define B44_DMARX_ADDR 0x0214UL /* DMA RX Descriptor Ring Address */ +#define B44_DMARX_PTR 0x0218UL /* DMA RX Last Posted Descriptor */ +#define B44_DMARX_STAT 0x021CUL /* DMA RX Current Active Desc. + Status */ +#define DMARX_STAT_CDMASK 0x00000fff /* Current Descriptor Mask */ +#define DMARX_STAT_SMASK 0x0000f000 /* State Mask */ +#define DMARX_STAT_SDISABLED 0x00000000 /* State Disbaled */ +#define DMARX_STAT_SACTIVE 0x00001000 /* State Active */ +#define DMARX_STAT_SIDLE 0x00002000 /* State Idle Wait */ +#define DMARX_STAT_SSTOPPED 0x00003000 /* State Stopped */ +#define DMARX_STAT_EMASK 0x000f0000 /* Error Mask */ +#define DMARX_STAT_ENONE 0x00000000 /* Error None */ +#define DMARX_STAT_EDPE 0x00010000 /* Error Desc. Protocol Error */ +#define DMARX_STAT_EDFO 0x00020000 /* Error Data FIFO Overflow */ +#define DMARX_STAT_EBEBW 0x00030000 /* Error Bus Error on Buffer Write */ +#define DMARX_STAT_EBEDA 0x00040000 /* Error Bus Error on Desc. Access */ +#define B44_DMAFIFO_AD 0x0220UL /* DMA FIFO Diag Address */ +#define DMAFIFO_AD_OMASK 0x0000ffff /* Offset Mask */ +#define DMAFIFO_AD_SMASK 0x000f0000 /* Select Mask */ +#define DMAFIFO_AD_SXDD 0x00000000 /* Select Transmit DMA Data */ +#define DMAFIFO_AD_SXDP 0x00010000 /* Select Transmit DMA Pointers */ +#define DMAFIFO_AD_SRDD 0x00040000 /* Select Receive DMA Data */ +#define DMAFIFO_AD_SRDP 0x00050000 /* Select Receive DMA Pointers */ +#define DMAFIFO_AD_SXFD 0x00080000 /* Select Transmit FIFO Data */ +#define DMAFIFO_AD_SXFP 0x00090000 /* Select Transmit FIFO Pointers */ +#define DMAFIFO_AD_SRFD 0x000c0000 /* Select Receive FIFO Data */ +#define DMAFIFO_AD_SRFP 0x000c0000 /* Select Receive FIFO Pointers */ +#define B44_DMAFIFO_LO 0x0224UL /* DMA FIFO Diag Low Data */ +#define B44_DMAFIFO_HI 0x0228UL /* DMA FIFO Diag High Data */ +#define B44_RXCONFIG 0x0400UL /* EMAC RX Config */ +#define RXCONFIG_DBCAST 0x00000001 /* Disable Broadcast */ +#define RXCONFIG_ALLMULTI 0x00000002 /* Accept All Multicast */ +#define RXCONFIG_NORX_WHILE_TX 0x00000004 /* Receive Disable While Transmitting */ +#define RXCONFIG_PROMISC 0x00000008 /* Promiscuous Enable */ +#define RXCONFIG_LPBACK 0x00000010 /* Loopback Enable */ +#define RXCONFIG_FLOW 0x00000020 /* Flow Control Enable */ +#define RXCONFIG_FLOW_ACCEPT 0x00000040 /* Accept Unicast Flow Control Frame */ +#define RXCONFIG_RFILT 0x00000080 /* Reject Filter */ +#define B44_RXMAXLEN 0x0404UL /* EMAC RX Max Packet Length */ +#define B44_TXMAXLEN 0x0408UL /* EMAC TX Max Packet Length */ +#define B44_MDIO_CTRL 0x0410UL /* EMAC MDIO Control */ +#define MDIO_CTRL_MAXF_MASK 0x0000007f /* MDC Frequency */ +#define MDIO_CTRL_PREAMBLE 0x00000080 /* MII Preamble Enable */ +#define B44_MDIO_DATA 0x0414UL /* EMAC MDIO Data */ +#define MDIO_DATA_DATA 0x0000ffff /* R/W Data */ +#define MDIO_DATA_TA_MASK 0x00030000 /* Turnaround Value */ +#define MDIO_DATA_TA_SHIFT 16 +#define MDIO_TA_VALID 2 +#define MDIO_DATA_RA_MASK 0x007c0000 /* Register Address */ +#define MDIO_DATA_RA_SHIFT 18 +#define MDIO_DATA_PMD_MASK 0x0f800000 /* Physical Media Device */ +#define MDIO_DATA_PMD_SHIFT 23 +#define MDIO_DATA_OP_MASK 0x30000000 /* Opcode */ +#define MDIO_DATA_OP_SHIFT 28 +#define MDIO_OP_WRITE 1 +#define MDIO_OP_READ 2 +#define MDIO_DATA_SB_MASK 0xc0000000 /* Start Bits */ +#define MDIO_DATA_SB_SHIFT 30 +#define MDIO_DATA_SB_START 0x40000000 /* Start Of Frame */ +#define B44_EMAC_IMASK 0x0418UL /* EMAC Interrupt Mask */ +#define B44_EMAC_ISTAT 0x041CUL /* EMAC Interrupt Status */ +#define EMAC_INT_MII 0x00000001 /* MII MDIO Interrupt */ +#define EMAC_INT_MIB 0x00000002 /* MIB Interrupt */ +#define EMAC_INT_FLOW 0x00000003 /* Flow Control Interrupt */ +#define B44_CAM_DATA_LO 0x0420UL /* EMAC CAM Data Low */ +#define B44_CAM_DATA_HI 0x0424UL /* EMAC CAM Data High */ +#define CAM_DATA_HI_VALID 0x00010000 /* Valid Bit */ +#define B44_CAM_CTRL 0x0428UL /* EMAC CAM Control */ +#define CAM_CTRL_ENABLE 0x00000001 /* CAM Enable */ +#define CAM_CTRL_MSEL 0x00000002 /* Mask Select */ +#define CAM_CTRL_READ 0x00000004 /* Read */ +#define CAM_CTRL_WRITE 0x00000008 /* Read */ +#define CAM_CTRL_INDEX_MASK 0x003f0000 /* Index Mask */ +#define CAM_CTRL_INDEX_SHIFT 16 +#define CAM_CTRL_BUSY 0x80000000 /* CAM Busy */ +#define B44_ENET_CTRL 0x042CUL /* EMAC ENET Control */ +#define ENET_CTRL_ENABLE 0x00000001 /* EMAC Enable */ +#define ENET_CTRL_DISABLE 0x00000002 /* EMAC Disable */ +#define ENET_CTRL_SRST 0x00000004 /* EMAC Soft Reset */ +#define ENET_CTRL_EPSEL 0x00000008 /* External PHY Select */ +#define B44_TX_CTRL 0x0430UL /* EMAC TX Control */ +#define TX_CTRL_DUPLEX 0x00000001 /* Full Duplex */ +#define TX_CTRL_FMODE 0x00000002 /* Flow Mode */ +#define TX_CTRL_SBENAB 0x00000004 /* Single Backoff Enable */ +#define TX_CTRL_SMALL_SLOT 0x00000008 /* Small Slottime */ +#define B44_TX_WMARK 0x0434UL /* EMAC TX Watermark */ +#define B44_MIB_CTRL 0x0438UL /* EMAC MIB Control */ +#define MIB_CTRL_CLR_ON_READ 0x00000001 /* Autoclear on Read */ +#define B44_TX_GOOD_O 0x0500UL /* MIB TX Good Octets */ +#define B44_TX_GOOD_P 0x0504UL /* MIB TX Good Packets */ +#define B44_TX_O 0x0508UL /* MIB TX Octets */ +#define B44_TX_P 0x050CUL /* MIB TX Packets */ +#define B44_TX_BCAST 0x0510UL /* MIB TX Broadcast Packets */ +#define B44_TX_MCAST 0x0514UL /* MIB TX Multicast Packets */ +#define B44_TX_64 0x0518UL /* MIB TX <= 64 byte Packets */ +#define B44_TX_65_127 0x051CUL /* MIB TX 65 to 127 byte Packets */ +#define B44_TX_128_255 0x0520UL /* MIB TX 128 to 255 byte Packets */ +#define B44_TX_256_511 0x0524UL /* MIB TX 256 to 511 byte Packets */ +#define B44_TX_512_1023 0x0528UL /* MIB TX 512 to 1023 byte Packets */ +#define B44_TX_1024_MAX 0x052CUL /* MIB TX 1024 to max byte Packets */ +#define B44_TX_JABBER 0x0530UL /* MIB TX Jabber Packets */ +#define B44_TX_OSIZE 0x0534UL /* MIB TX Oversize Packets */ +#define B44_TX_FRAG 0x0538UL /* MIB TX Fragment Packets */ +#define B44_TX_URUNS 0x053CUL /* MIB TX Underruns */ +#define B44_TX_TCOLS 0x0540UL /* MIB TX Total Collisions */ +#define B44_TX_SCOLS 0x0544UL /* MIB TX Single Collisions */ +#define B44_TX_MCOLS 0x0548UL /* MIB TX Multiple Collisions */ +#define B44_TX_ECOLS 0x054CUL /* MIB TX Excessive Collisions */ +#define B44_TX_LCOLS 0x0550UL /* MIB TX Late Collisions */ +#define B44_TX_DEFERED 0x0554UL /* MIB TX Defered Packets */ +#define B44_TX_CLOST 0x0558UL /* MIB TX Carrier Lost */ +#define B44_TX_PAUSE 0x055CUL /* MIB TX Pause Packets */ +#define B44_RX_GOOD_O 0x0580UL /* MIB RX Good Octets */ +#define B44_RX_GOOD_P 0x0584UL /* MIB RX Good Packets */ +#define B44_RX_O 0x0588UL /* MIB RX Octets */ +#define B44_RX_P 0x058CUL /* MIB RX Packets */ +#define B44_RX_BCAST 0x0590UL /* MIB RX Broadcast Packets */ +#define B44_RX_MCAST 0x0594UL /* MIB RX Multicast Packets */ +#define B44_RX_64 0x0598UL /* MIB RX <= 64 byte Packets */ +#define B44_RX_65_127 0x059CUL /* MIB RX 65 to 127 byte Packets */ +#define B44_RX_128_255 0x05A0UL /* MIB RX 128 to 255 byte Packets */ +#define B44_RX_256_511 0x05A4UL /* MIB RX 256 to 511 byte Packets */ +#define B44_RX_512_1023 0x05A8UL /* MIB RX 512 to 1023 byte Packets */ +#define B44_RX_1024_MAX 0x05ACUL /* MIB RX 1024 to max byte Packets */ +#define B44_RX_JABBER 0x05B0UL /* MIB RX Jabber Packets */ +#define B44_RX_OSIZE 0x05B4UL /* MIB RX Oversize Packets */ +#define B44_RX_FRAG 0x05B8UL /* MIB RX Fragment Packets */ +#define B44_RX_MISS 0x05BCUL /* MIB RX Missed Packets */ +#define B44_RX_CRCA 0x05C0UL /* MIB RX CRC Align Errors */ +#define B44_RX_USIZE 0x05C4UL /* MIB RX Undersize Packets */ +#define B44_RX_CRC 0x05C8UL /* MIB RX CRC Errors */ +#define B44_RX_ALIGN 0x05CCUL /* MIB RX Align Errors */ +#define B44_RX_SYM 0x05D0UL /* MIB RX Symbol Errors */ +#define B44_RX_PAUSE 0x05D4UL /* MIB RX Pause Packets */ +#define B44_RX_NPAUSE 0x05D8UL /* MIB RX Non-Pause Packets */ +#define B44_SBIPSFLAG 0x0F08UL /* SB Initiator Port OCP Slave Flag */ +#define SBIPSFLAG_IMASK1 0x0000003f /* Which sbflags --> mips interrupt 1 */ +#define SBIPSFLAG_ISHIFT1 0 +#define SBIPSFLAG_IMASK2 0x00003f00 /* Which sbflags --> mips interrupt 2 */ +#define SBIPSFLAG_ISHIFT2 8 +#define SBIPSFLAG_IMASK3 0x003f0000 /* Which sbflags --> mips interrupt 3 */ +#define SBIPSFLAG_ISHIFT3 16 +#define SBIPSFLAG_IMASK4 0x3f000000 /* Which sbflags --> mips interrupt 4 */ +#define SBIPSFLAG_ISHIFT4 24 +#define B44_SBTPSFLAG 0x0F18UL /* SB Target Port OCP Slave Flag */ +#define SBTPS_NUM0_MASK 0x0000003f +#define SBTPS_F0EN0 0x00000040 +#define B44_SBADMATCH3 0x0F60UL /* SB Address Match 3 */ +#define B44_SBADMATCH2 0x0F68UL /* SB Address Match 2 */ +#define B44_SBADMATCH1 0x0F70UL /* SB Address Match 1 */ +#define B44_SBIMSTATE 0x0F90UL /* SB Initiator Agent State */ +#define SBIMSTATE_PC 0x0000000f /* Pipe Count */ +#define SBIMSTATE_AP_MASK 0x00000030 /* Arbitration Priority */ +#define SBIMSTATE_AP_BOTH 0x00000000 /* Use both timeslices and token */ +#define SBIMSTATE_AP_TS 0x00000010 /* Use timeslices only */ +#define SBIMSTATE_AP_TK 0x00000020 /* Use token only */ +#define SBIMSTATE_AP_RSV 0x00000030 /* Reserved */ +#define SBIMSTATE_IBE 0x00020000 /* In Band Error */ +#define SBIMSTATE_TO 0x00040000 /* Timeout */ +#define B44_SBINTVEC 0x0F94UL /* SB Interrupt Mask */ +#define SBINTVEC_PCI 0x00000001 /* Enable interrupts for PCI */ +#define SBINTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */ +#define SBINTVEC_ILINE20 0x00000004 /* Enable interrupts for iline20 */ +#define SBINTVEC_CODEC 0x00000008 /* Enable interrupts for v90 codec */ +#define SBINTVEC_USB 0x00000010 /* Enable interrupts for usb */ +#define SBINTVEC_EXTIF 0x00000020 /* Enable interrupts for external i/f */ +#define SBINTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */ +#define B44_SBTMSLOW 0x0F98UL /* SB Target State Low */ +#define SBTMSLOW_RESET 0x00000001 /* Reset */ +#define SBTMSLOW_REJECT 0x00000002 /* Reject */ +#define SBTMSLOW_CLOCK 0x00010000 /* Clock Enable */ +#define SBTMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ +#define SBTMSLOW_PE 0x40000000 /* Power Management Enable */ +#define SBTMSLOW_BE 0x80000000 /* BIST Enable */ +#define B44_SBTMSHIGH 0x0F9CUL /* SB Target State High */ +#define SBTMSHIGH_SERR 0x00000001 /* S-error */ +#define SBTMSHIGH_INT 0x00000002 /* Interrupt */ +#define SBTMSHIGH_BUSY 0x00000004 /* Busy */ +#define SBTMSHIGH_GCR 0x20000000 /* Gated Clock Request */ +#define SBTMSHIGH_BISTF 0x40000000 /* BIST Failed */ +#define SBTMSHIGH_BISTD 0x80000000 /* BIST Done */ +#define B44_SBBWA0 0x0FA0UL /* SB Bandwidth Allocation Table 0 */ +#define SBBWA0_TAB0_MASK 0x0000ffff /* Lookup Table 0 */ +#define SBBWA0_TAB0_SHIFT 0 +#define SBBWA0_TAB1_MASK 0xffff0000 /* Lookup Table 0 */ +#define SBBWA0_TAB1_SHIFT 16 +#define B44_SBIMCFGLOW 0x0FA8UL /* SB Initiator Configuration Low */ +#define SBIMCFGLOW_STO_MASK 0x00000003 /* Service Timeout */ +#define SBIMCFGLOW_RTO_MASK 0x00000030 /* Request Timeout */ +#define SBIMCFGLOW_RTO_SHIFT 4 +#define SBIMCFGLOW_CID_MASK 0x00ff0000 /* Connection ID */ +#define SBIMCFGLOW_CID_SHIFT 16 +#define B44_SBIMCFGHIGH 0x0FACUL /* SB Initiator Configuration High */ +#define SBIMCFGHIGH_IEM_MASK 0x0000000c /* Inband Error Mode */ +#define SBIMCFGHIGH_TEM_MASK 0x00000030 /* Timeout Error Mode */ +#define SBIMCFGHIGH_TEM_SHIFT 4 +#define SBIMCFGHIGH_BEM_MASK 0x000000c0 /* Bus Error Mode */ +#define SBIMCFGHIGH_BEM_SHIFT 6 +#define B44_SBADMATCH0 0x0FB0UL /* SB Address Match 0 */ +#define SBADMATCH0_TYPE_MASK 0x00000003 /* Address Type */ +#define SBADMATCH0_AD64 0x00000004 /* Reserved */ +#define SBADMATCH0_AI0_MASK 0x000000f8 /* Type0 Size */ +#define SBADMATCH0_AI0_SHIFT 3 +#define SBADMATCH0_AI1_MASK 0x000001f8 /* Type1 Size */ +#define SBADMATCH0_AI1_SHIFT 3 +#define SBADMATCH0_AI2_MASK 0x000001f8 /* Type2 Size */ +#define SBADMATCH0_AI2_SHIFT 3 +#define SBADMATCH0_ADEN 0x00000400 /* Enable */ +#define SBADMATCH0_ADNEG 0x00000800 /* Negative Decode */ +#define SBADMATCH0_BS0_MASK 0xffffff00 /* Type0 Base Address */ +#define SBADMATCH0_BS0_SHIFT 8 +#define SBADMATCH0_BS1_MASK 0xfffff000 /* Type1 Base Address */ +#define SBADMATCH0_BS1_SHIFT 12 +#define SBADMATCH0_BS2_MASK 0xffff0000 /* Type2 Base Address */ +#define SBADMATCH0_BS2_SHIFT 16 +#define B44_SBTMCFGLOW 0x0FB8UL /* SB Target Configuration Low */ +#define SBTMCFGLOW_CD_MASK 0x000000ff /* Clock Divide Mask */ +#define SBTMCFGLOW_CO_MASK 0x0000f800 /* Clock Offset Mask */ +#define SBTMCFGLOW_CO_SHIFT 11 +#define SBTMCFGLOW_IF_MASK 0x00fc0000 /* Interrupt Flags Mask */ +#define SBTMCFGLOW_IF_SHIFT 18 +#define SBTMCFGLOW_IM_MASK 0x03000000 /* Interrupt Mode Mask */ +#define SBTMCFGLOW_IM_SHIFT 24 +#define B44_SBTMCFGHIGH 0x0FBCUL /* SB Target Configuration High */ +#define SBTMCFGHIGH_BM_MASK 0x00000003 /* Busy Mode */ +#define SBTMCFGHIGH_RM_MASK 0x0000000C /* Retry Mode */ +#define SBTMCFGHIGH_RM_SHIFT 2 +#define SBTMCFGHIGH_SM_MASK 0x00000030 /* Stop Mode */ +#define SBTMCFGHIGH_SM_SHIFT 4 +#define SBTMCFGHIGH_EM_MASK 0x00000300 /* Error Mode */ +#define SBTMCFGHIGH_EM_SHIFT 8 +#define SBTMCFGHIGH_IM_MASK 0x00000c00 /* Interrupt Mode */ +#define SBTMCFGHIGH_IM_SHIFT 10 +#define B44_SBBCFG 0x0FC0UL /* SB Broadcast Configuration */ +#define SBBCFG_LAT_MASK 0x00000003 /* SB Latency */ +#define SBBCFG_MAX0_MASK 0x000f0000 /* MAX Counter 0 */ +#define SBBCFG_MAX0_SHIFT 16 +#define SBBCFG_MAX1_MASK 0x00f00000 /* MAX Counter 1 */ +#define SBBCFG_MAX1_SHIFT 20 +#define B44_SBBSTATE 0x0FC8UL /* SB Broadcast State */ +#define SBBSTATE_SRD 0x00000001 /* ST Reg Disable */ +#define SBBSTATE_HRD 0x00000002 /* Hold Reg Disable */ +#define B44_SBACTCNFG 0x0FD8UL /* SB Activate Configuration */ +#define B44_SBFLAGST 0x0FE8UL /* SB Current SBFLAGS */ +#define B44_SBIDLOW 0x0FF8UL /* SB Identification Low */ +#define SBIDLOW_CS_MASK 0x00000003 /* Config Space Mask */ +#define SBIDLOW_AR_MASK 0x00000038 /* Num Address Ranges Supported */ +#define SBIDLOW_AR_SHIFT 3 +#define SBIDLOW_SYNCH 0x00000040 /* Sync */ +#define SBIDLOW_INIT 0x00000080 /* Initiator */ +#define SBIDLOW_MINLAT_MASK 0x00000f00 /* Minimum Backplane Latency */ +#define SBIDLOW_MINLAT_SHIFT 8 +#define SBIDLOW_MAXLAT_MASK 0x0000f000 /* Maximum Backplane Latency */ +#define SBIDLOW_MAXLAT_SHIFT 12 +#define SBIDLOW_FIRST 0x00010000 /* This Initiator is First */ +#define SBIDLOW_CW_MASK 0x000c0000 /* Cycle Counter Width */ +#define SBIDLOW_CW_SHIFT 18 +#define SBIDLOW_TP_MASK 0x00f00000 /* Target Ports */ +#define SBIDLOW_TP_SHIFT 20 +#define SBIDLOW_IP_MASK 0x0f000000 /* Initiator Ports */ +#define SBIDLOW_IP_SHIFT 24 +#define B44_SBIDHIGH 0x0FFCUL /* SB Identification High */ +#define SBIDHIGH_RC_MASK 0x0000000f /* Revision Code */ +#define SBIDHIGH_CC_MASK 0x0000fff0 /* Core Code */ +#define SBIDHIGH_CC_SHIFT 4 +#define SBIDHIGH_VC_MASK 0xffff0000 /* Vendor Code */ +#define SBIDHIGH_VC_SHIFT 16 + +#define CORE_CODE_ILINE20 0x801 +#define CORE_CODE_SDRAM 0x803 +#define CORE_CODE_PCI 0x804 +#define CORE_CODE_MIPS 0x805 +#define CORE_CODE_ENET 0x806 +#define CORE_CODE_CODEC 0x807 +#define CORE_CODE_USB 0x808 +#define CORE_CODE_ILINE100 0x80a +#define CORE_CODE_EXTIF 0x811 + +/* SSB PCI config space registers. */ +#define SSB_BAR0_WIN 0x80 +#define SSB_BAR1_WIN 0x84 +#define SSB_SPROM_CONTROL 0x88 +#define SSB_BAR1_CONTROL 0x8c + +/* SSB core and hsot control registers. */ +#define SSB_CONTROL 0x0000UL +#define SSB_ARBCONTROL 0x0010UL +#define SSB_ISTAT 0x0020UL +#define SSB_IMASK 0x0024UL +#define SSB_MBOX 0x0028UL +#define SSB_BCAST_ADDR 0x0050UL +#define SSB_BCAST_DATA 0x0054UL +#define SSB_PCI_TRANS_0 0x0100UL +#define SSB_PCI_TRANS_1 0x0104UL +#define SSB_PCI_TRANS_2 0x0108UL +#define SSB_SPROM 0x0800UL + +#define SSB_PCI_MEM 0x00000000 +#define SSB_PCI_IO 0x00000001 +#define SSB_PCI_CFG0 0x00000002 +#define SSB_PCI_CFG1 0x00000003 +#define SSB_PCI_PREF 0x00000004 +#define SSB_PCI_BURST 0x00000008 +#define SSB_PCI_MASK0 0xfc000000 +#define SSB_PCI_MASK1 0xfc000000 +#define SSB_PCI_MASK2 0xc0000000 + +#define br32(REG) readl(bp->regs + (REG)) +#define bw32(REG,VAL) writel((VAL), bp->regs + (REG)) + +/* 4400 PHY registers */ +#define B44_MII_AUXCTRL 24 /* Auxiliary Control */ +#define MII_AUXCTRL_DUPLEX 0x0001 /* Full Duplex */ +#define MII_AUXCTRL_SPEED 0x0002 /* 1=100Mbps, 0=10Mbps */ +#define MII_AUXCTRL_FORCED 0x0004 /* Forced 10/100 */ +#define B44_MII_ALEDCTRL 26 /* Activity LED */ +#define MII_ALEDCTRL_ALLMSK 0x7fff +#define B44_MII_TLEDCTRL 27 /* Traffic Meter LED */ +#define MII_TLEDCTRL_ENABLE 0x0040 + +/* XXX Add this to mii.h */ +#ifndef ADVERTISE_PAUSE +#define ADVERTISE_PAUSE_CAP 0x0400 +#endif +#ifndef ADVERTISE_PAUSE_ASYM +#define ADVERTISE_PAUSE_ASYM 0x0800 +#endif +#ifndef LPA_PAUSE +#define LPA_PAUSE_CAP 0x0400 +#endif +#ifndef LPA_PAUSE_ASYM +#define LPA_PAUSE_ASYM 0x0800 +#endif + +struct dma_desc { + u32 ctrl; + u32 addr; +}; + +/* There are only 12 bits in the DMA engine for descriptor offsetting + * so the table must be aligned on a boundary of this. + */ +#define DMA_TABLE_BYTES 4096 + +#define DESC_CTRL_LEN 0x00001fff +#define DESC_CTRL_CMASK 0x0ff00000 /* Core specific bits */ +#define DESC_CTRL_EOT 0x10000000 /* End of Table */ +#define DESC_CTRL_IOC 0x20000000 /* Interrupt On Completion */ +#define DESC_CTRL_EOF 0x40000000 /* End of Frame */ +#define DESC_CTRL_SOF 0x80000000 /* Start of Frame */ + +#define RX_COPY_THRESHOLD 256 + +struct rx_header { + u16 len; + u16 flags; + u16 pad[12]; +}; +#define RX_HEADER_LEN 28 + +#define RX_FLAG_OFIFO 0x00000001 /* FIFO Overflow */ +#define RX_FLAG_CRCERR 0x00000002 /* CRC Error */ +#define RX_FLAG_SERR 0x00000004 /* Receive Symbol Error */ +#define RX_FLAG_ODD 0x00000008 /* Frame has odd number of nibbles */ +#define RX_FLAG_LARGE 0x00000010 /* Frame is > RX MAX Length */ +#define RX_FLAG_MCAST 0x00000020 /* Dest is Multicast Address */ +#define RX_FLAG_BCAST 0x00000040 /* Dest is Broadcast Address */ +#define RX_FLAG_MISS 0x00000080 /* Received due to promisc mode */ +#define RX_FLAG_LAST 0x00000800 /* Last buffer in frame */ +#define RX_FLAG_ERRORS (RX_FLAG_ODD | RX_FLAG_SERR | RX_FLAG_CRCERR | RX_FLAG_OFIFO) + +struct ring_info { + struct sk_buff *skb; + DECLARE_PCI_UNMAP_ADDR(mapping); +}; + +#define B44_MCAST_TABLE_SIZE 32 + +/* SW copy of device statistics, kept up to date by periodic timer + * which probes HW values. Must have same relative layout as HW + * register above, because b44_stats_update depends upon this. + */ +struct b44_hw_stats { + u32 tx_good_octets, tx_good_pkts, tx_octets; + u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; + u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255; + u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max; + u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts; + u32 tx_underruns, tx_total_cols, tx_single_cols; + u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols; + u32 tx_defered, tx_carrier_lost, tx_pause_pkts; + u32 __pad1[8]; + + u32 rx_good_octets, rx_good_pkts, rx_octets; + u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts; + u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255; + u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max; + u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts; + u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize; + u32 rx_crc_errs, rx_align_errs, rx_symbol_errs; + u32 rx_pause_pkts, rx_nonpause_pkts; +}; + +struct b44 { + spinlock_t lock; + + u32 imask, istat; + + struct dma_desc *rx_ring, *tx_ring; + + u32 tx_prod, tx_cons; + u32 rx_prod, rx_cons; + + struct ring_info *rx_buffers; + struct ring_info *tx_buffers; + + u32 dma_offset; + u32 flags; +#define B44_FLAG_INIT_COMPLETE 0x00000001 +#define B44_FLAG_BUGGY_TXPTR 0x00000002 +#define B44_FLAG_REORDER_BUG 0x00000004 +#define B44_FLAG_PAUSE_AUTO 0x00008000 +#define B44_FLAG_FULL_DUPLEX 0x00010000 +#define B44_FLAG_100_BASE_T 0x00020000 +#define B44_FLAG_TX_PAUSE 0x00040000 +#define B44_FLAG_RX_PAUSE 0x00080000 +#define B44_FLAG_FORCE_LINK 0x00100000 +#define B44_FLAG_ADV_10HALF 0x01000000 +#define B44_FLAG_ADV_10FULL 0x02000000 +#define B44_FLAG_ADV_100HALF 0x04000000 +#define B44_FLAG_ADV_100FULL 0x08000000 +#define B44_FLAG_INTERNAL_PHY 0x10000000 + + u32 rx_offset; + + u32 msg_enable; + + struct timer_list timer; + + struct net_device_stats stats; + struct b44_hw_stats hw_stats; + + unsigned long regs; + struct pci_dev *pdev; + struct net_device *dev; + + dma_addr_t rx_ring_dma, tx_ring_dma; + + u32 rx_pending; + u32 tx_pending; + u32 pci_cfg_state[64 / sizeof(u32)]; + u8 phy_addr; + u8 mdc_port; + u8 core_unit; +}; + +#endif /* _B44_H */ diff -urN linux-2.4.21/drivers/net/bmac.c linux-2.4.22/drivers/net/bmac.c --- linux-2.4.21/drivers/net/bmac.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/bmac.c 2003-08-25 04:44:42.000000000 -0700 @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -67,7 +69,6 @@ volatile struct dbdma_cmd *tx_cmds; /* xmit dma command list */ volatile struct dbdma_cmd *rx_cmds; /* recv dma command list */ struct device_node *node; - int is_bmac_plus; struct sk_buff *rx_bufs[N_RX_RING]; int rx_fill; int rx_empty; @@ -80,6 +81,8 @@ int timeout_active; int sleeping; int opened; + int is_bmac_plus; + u32 device_id; unsigned short hash_use_count[64]; unsigned short hash_table_mask[4]; struct net_device *next_bmac; @@ -153,6 +156,7 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats *bmac_stats(struct net_device *dev); static void bmac_set_multicast(struct net_device *dev); +static int bmac_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static void bmac_reset_and_enable(struct net_device *dev); static void bmac_start_chip(struct net_device *dev); static void bmac_init_chip(struct net_device *dev); @@ -1053,7 +1057,7 @@ { struct dev_mc_list *dmi = dev->mc_list; char *addrs; - int i, j, bit, byte; + int i; unsigned short rx_cfg; u32 crc; @@ -1189,7 +1193,7 @@ read_srom(struct net_device *dev, unsigned int addr, unsigned int addr_len) { unsigned short data, val; - int i; + unsigned int i; /* send out the address we want to read from */ for (i = 0; i < addr_len; i++) { @@ -1303,6 +1307,7 @@ struct bmac_data *bp; unsigned char *addr; struct net_device *dev; + u32 *deviceid; if (bmac->n_addrs != 3 || bmac->n_intrs != 3) { printk(KERN_ERR "can't use BMAC %s: need 3 addrs and 3 intrs\n", @@ -1356,6 +1361,10 @@ goto err_out; dev->irq = bmac->intrs[0].line; + deviceid = (u32 *)get_property(bmac, "device-id", NULL); + if (deviceid) + bp->device_id = *deviceid; + bmac_enable_and_reset_chip(dev); bmwrite(dev, INTDISABLE, DisableAll); @@ -1378,6 +1387,7 @@ dev->get_stats = bmac_stats; dev->set_multicast_list = bmac_set_multicast; dev->set_mac_address = bmac_set_address; + dev->do_ioctl = bmac_do_ioctl; bmac_get_station_address(dev, addr); if (bmac_verify_checksum(dev) != 0) @@ -1451,6 +1461,56 @@ kfree(dev); } +static int bmac_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + struct bmac_data *bp = (struct bmac_data *) dev->priv; + u32 ethcmd; + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, "bmac"); + info.version[0] = '\0'; + snprintf(info.fw_version, 31, "chip id %x", bp->device_id); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + case ETHTOOL_GSET: + case ETHTOOL_SSET: + case ETHTOOL_NWAY_RST: + case ETHTOOL_GLINK: + case ETHTOOL_GMSGLVL: + case ETHTOOL_SMSGLVL: + default: + ; + } + + return -EOPNOTSUPP; +} + +static int bmac_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + switch(cmd) { + case SIOCETHTOOL: + return bmac_ethtool_ioctl(dev, (void *) ifr->ifr_data); + + case SIOCGMIIPHY: + case SIOCDEVPRIVATE: + case SIOCGMIIREG: + case SIOCDEVPRIVATE+1: + case SIOCSMIIREG: + case SIOCDEVPRIVATE+2: + default: + ; + } + return -EOPNOTSUPP; +} + static int bmac_open(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; diff -urN linux-2.4.21/drivers/net/bonding/Makefile linux-2.4.22/drivers/net/bonding/Makefile --- linux-2.4.21/drivers/net/bonding/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/bonding/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,14 @@ +# +# Makefile for the Ethernet Bonding driver +# + +O_TARGET := bonding.o + +obj-y := bond_main.o \ + bond_3ad.o \ + bond_alb.o + +obj-m := $(O_TARGET) + +include $(TOPDIR)/Rules.make + diff -urN linux-2.4.21/drivers/net/bonding/bond_3ad.c linux-2.4.22/drivers/net/bonding/bond_3ad.c --- linux-2.4.21/drivers/net/bonding/bond_3ad.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/bonding/bond_3ad.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,2505 @@ +/* + * Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * + * Changes: + * + * 2003/05/01 - Tsippy Mendelson and + * Amir Noam + * - Added support for lacp_rate module param. + * + * 2003/05/01 - Shmulik Hen + * - Based on discussion on mailing list, changed locking scheme + * to use lock/unlock or lock_bh/unlock_bh appropriately instead + * of lock_irqsave/unlock_irqrestore. The new scheme helps exposing + * hidden bugs and solves system hangs that occurred due to the fact + * that holding lock_irqsave doesn't prevent softirqs from running. + * This also increases total throughput since interrupts are not + * blocked on each transmitted packets or monitor timeout. + * + * 2003/05/01 - Shmulik Hen + * - Renamed bond_3ad_link_status_changed() to + * bond_3ad_handle_link_change() for compatibility with TLB. + * + * 2003/05/20 - Amir Noam + * - Fix long fail over time when releasing last slave of an active + * aggregator - send LACPDU on unbind of slave to tell partner this + * port is no longer aggregatable. + * + * 2003/06/25 - Tsippy Mendelson + * - Send LACPDU as highest priority packet to further fix the above + * problem on very high Tx traffic load where packets may get dropped + * by the slave. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "bonding.h" +#include "bond_3ad.h" + +// General definitions +#define AD_SHORT_TIMEOUT 1 +#define AD_LONG_TIMEOUT 0 +#define AD_STANDBY 0x2 +#define AD_MAX_TX_IN_SECOND 3 +#define AD_COLLECTOR_MAX_DELAY 0 + +// Timer definitions(43.4.4 in the 802.3ad standard) +#define AD_FAST_PERIODIC_TIME 1 +#define AD_SLOW_PERIODIC_TIME 30 +#define AD_SHORT_TIMEOUT_TIME (3*AD_FAST_PERIODIC_TIME) +#define AD_LONG_TIMEOUT_TIME (3*AD_SLOW_PERIODIC_TIME) +#define AD_CHURN_DETECTION_TIME 60 +#define AD_AGGREGATE_WAIT_TIME 2 + +// Port state definitions(43.4.2.2 in the 802.3ad standard) +#define AD_STATE_LACP_ACTIVITY 0x1 +#define AD_STATE_LACP_TIMEOUT 0x2 +#define AD_STATE_AGGREGATION 0x4 +#define AD_STATE_SYNCHRONIZATION 0x8 +#define AD_STATE_COLLECTING 0x10 +#define AD_STATE_DISTRIBUTING 0x20 +#define AD_STATE_DEFAULTED 0x40 +#define AD_STATE_EXPIRED 0x80 + +// Port Variables definitions used by the State Machines(43.4.7 in the 802.3ad standard) +#define AD_PORT_BEGIN 0x1 +#define AD_PORT_LACP_ENABLED 0x2 +#define AD_PORT_ACTOR_CHURN 0x4 +#define AD_PORT_PARTNER_CHURN 0x8 +#define AD_PORT_READY 0x10 +#define AD_PORT_READY_N 0x20 +#define AD_PORT_MATCHED 0x40 +#define AD_PORT_STANDBY 0x80 +#define AD_PORT_SELECTED 0x100 +#define AD_PORT_MOVED 0x200 + +// Port Key definitions +// key is determined according to the link speed, duplex and +// user key(which is yet not supported) +// ------------------------------------------------------------ +// Port key : | User key | Speed |Duplex| +// ------------------------------------------------------------ +// 16 6 1 0 +#define AD_DUPLEX_KEY_BITS 0x1 +#define AD_SPEED_KEY_BITS 0x3E +#define AD_USER_KEY_BITS 0xFFC0 + +//dalloun +#define AD_LINK_SPEED_BITMASK_1MBPS 0x1 +#define AD_LINK_SPEED_BITMASK_10MBPS 0x2 +#define AD_LINK_SPEED_BITMASK_100MBPS 0x4 +#define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 +//endalloun + +// compare MAC addresses +#define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN) + +static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}}; +static u16 ad_ticks_per_sec; + +// ================= 3AD api to bonding and kernel code ================== +static u16 __get_link_speed(struct port *port); +static u8 __get_duplex(struct port *port); +static inline void __initialize_port_locks(struct port *port); +static inline void __deinitialize_port_locks(struct port *port); +//conversions +static void __ntohs_lacpdu(struct lacpdu *lacpdu); +static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par); + + +// ================= ad code helper functions ================== +//needed by ad_rx_machine(...) +static void __record_pdu(struct lacpdu *lacpdu, struct port *port); +static void __record_default(struct port *port); +static void __update_selected(struct lacpdu *lacpdu, struct port *port); +static void __update_default_selected(struct port *port); +static void __choose_matched(struct lacpdu *lacpdu, struct port *port); +static void __update_ntt(struct lacpdu *lacpdu, struct port *port); + +//needed for ad_mux_machine(..) +static void __attach_bond_to_agg(struct port *port); +static void __detach_bond_from_agg(struct port *port); +static int __agg_ports_are_ready(struct aggregator *aggregator); +static void __set_agg_ports_ready(struct aggregator *aggregator, int val); + +//needed for ad_agg_selection_logic(...) +static u32 __get_agg_bandwidth(struct aggregator *aggregator); +static struct aggregator *__get_active_agg(struct aggregator *aggregator); + + +// ================= main 802.3ad protocol functions ================== +static int ad_lacpdu_send(struct port *port); +static int ad_marker_send(struct port *port, struct marker *marker); +static void ad_mux_machine(struct port *port); +static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port); +static void ad_tx_machine(struct port *port); +static void ad_periodic_machine(struct port *port); +static void ad_port_selection_logic(struct port *port); +static void ad_agg_selection_logic(struct aggregator *aggregator); +static void ad_clear_agg(struct aggregator *aggregator); +static void ad_initialize_agg(struct aggregator *aggregator); +static void ad_initialize_port(struct port *port, int lacp_fast); +static void ad_initialize_lacpdu(struct lacpdu *Lacpdu); +static void ad_enable_collecting_distributing(struct port *port); +static void ad_disable_collecting_distributing(struct port *port); +static void ad_marker_info_received(struct marker *marker_info, struct port *port); +static void ad_marker_response_received(struct marker *marker, struct port *port); + + +///////////////////////////////////////////////////////////////////////////////// +// ================= api to bonding and kernel code ================== +///////////////////////////////////////////////////////////////////////////////// + +/** + * __get_bond_by_port - get the port's bonding struct + * @port: the port we're looking at + * + * Return @port's bonding struct, or %NULL if it can't be found. + */ +static inline struct bonding *__get_bond_by_port(struct port *port) +{ + if (port->slave == NULL) { + return NULL; + } + + return bond_get_bond_by_slave(port->slave); +} + +/** + * __get_first_port - get the first port in the bond + * @bond: the bond we're looking at + * + * Return the port of the first slave in @bond, or %NULL if it can't be found. + */ +static inline struct port *__get_first_port(struct bonding *bond) +{ + struct slave *slave = bond->next; + + if (slave == (struct slave *)bond) { + return NULL; + } + + return &(SLAVE_AD_INFO(slave).port); +} + +/** + * __get_next_port - get the next port in the bond + * @port: the port we're looking at + * + * Return the port of the slave that is next in line of @port's slave in the + * bond, or %NULL if it can't be found. + */ +static inline struct port *__get_next_port(struct port *port) +{ + struct bonding *bond = __get_bond_by_port(port); + struct slave *slave = port->slave; + + // If there's no bond for this port, or this is the last slave + if ((bond == NULL) || (slave->next == bond->next)) { + return NULL; + } + + return &(SLAVE_AD_INFO(slave->next).port); +} + +/** + * __get_first_agg - get the first aggregator in the bond + * @bond: the bond we're looking at + * + * Return the aggregator of the first slave in @bond, or %NULL if it can't be + * found. + */ +static inline struct aggregator *__get_first_agg(struct port *port) +{ + struct bonding *bond = __get_bond_by_port(port); + + // If there's no bond for this port, or this is the last slave + if ((bond == NULL) || (bond->next == (struct slave *)bond)) { + return NULL; + } + + return &(SLAVE_AD_INFO(bond->next).aggregator); +} + +/** + * __get_next_agg - get the next aggregator in the bond + * @aggregator: the aggregator we're looking at + * + * Return the aggregator of the slave that is next in line of @aggregator's + * slave in the bond, or %NULL if it can't be found. + */ +static inline struct aggregator *__get_next_agg(struct aggregator *aggregator) +{ + struct slave *slave = aggregator->slave; + struct bonding *bond = bond_get_bond_by_slave(slave); + + // If there's no bond for this aggregator, or this is the last slave + if ((bond == NULL) || (slave->next == bond->next)) { + return NULL; + } + + return &(SLAVE_AD_INFO(slave->next).aggregator); +} + +/** + * __disable_port - disable the port's slave + * @port: the port we're looking at + * + */ +static inline void __disable_port(struct port *port) +{ + bond_set_slave_inactive_flags(port->slave); +} + +/** + * __enable_port - enable the port's slave, if it's up + * @port: the port we're looking at + * + */ +static inline void __enable_port(struct port *port) +{ + struct slave *slave = port->slave; + + if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) { + bond_set_slave_active_flags(slave); + } +} + +/** + * __port_is_enabled - check if the port's slave is in active state + * @port: the port we're looking at + * + */ +static inline int __port_is_enabled(struct port *port) +{ + return(port->slave->state == BOND_STATE_ACTIVE); +} + +/** + * __get_agg_selection_mode - get the aggregator selection mode + * @port: the port we're looking at + * + * Get the aggregator selection mode. Can be %BANDWIDTH or %COUNT. + */ +static inline u32 __get_agg_selection_mode(struct port *port) +{ + struct bonding *bond = __get_bond_by_port(port); + + if (bond == NULL) { + return AD_BANDWIDTH; + } + + return BOND_AD_INFO(bond).agg_select_mode; +} + +/** + * __check_agg_selection_timer - check if the selection timer has expired + * @port: the port we're looking at + * + */ +static inline int __check_agg_selection_timer(struct port *port) +{ + struct bonding *bond = __get_bond_by_port(port); + + if (bond == NULL) { + return 0; + } + + return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0; +} + +/** + * __get_rx_machine_lock - lock the port's RX machine + * @port: the port we're looking at + * + */ +static inline void __get_rx_machine_lock(struct port *port) +{ + spin_lock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); +} + +/** + * __release_rx_machine_lock - unlock the port's RX machine + * @port: the port we're looking at + * + */ +static inline void __release_rx_machine_lock(struct port *port) +{ + spin_unlock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); +} + +/** + * __get_link_speed - get a port's speed + * @port: the port we're looking at + * + * Return @port's speed in 802.3ad bitmask format. i.e. one of: + * 0, + * %AD_LINK_SPEED_BITMASK_10MBPS, + * %AD_LINK_SPEED_BITMASK_100MBPS, + * %AD_LINK_SPEED_BITMASK_1000MBPS + */ +static u16 __get_link_speed(struct port *port) +{ + struct slave *slave = port->slave; + u16 speed; + + /* this if covers only a special case: when the configuration starts with + * link down, it sets the speed to 0. + * This is done in spite of the fact that the e100 driver reports 0 to be + * compatible with MVT in the future.*/ + if (slave->link != BOND_LINK_UP) { + speed=0; + } else { + switch (slave->speed) { + case SPEED_10: + speed = AD_LINK_SPEED_BITMASK_10MBPS; + break; + + case SPEED_100: + speed = AD_LINK_SPEED_BITMASK_100MBPS; + break; + + case SPEED_1000: + speed = AD_LINK_SPEED_BITMASK_1000MBPS; + break; + + default: + speed = 0; // unknown speed value from ethtool. shouldn't happen + break; + } + } + + BOND_PRINT_DBG(("Port %d Received link speed %d update from adapter", port->actor_port_number, speed)); + return speed; +} + +/** + * __get_duplex - get a port's duplex + * @port: the port we're looking at + * + * Return @port's duplex in 802.3ad bitmask format. i.e.: + * 0x01 if in full duplex + * 0x00 otherwise + */ +static u8 __get_duplex(struct port *port) +{ + struct slave *slave = port->slave; + + u8 retval; + + // handling a special case: when the configuration starts with + // link down, it sets the duplex to 0. + if (slave->link != BOND_LINK_UP) { + retval=0x0; + } else { + switch (slave->duplex) { + case DUPLEX_FULL: + retval=0x1; + BOND_PRINT_DBG(("Port %d Received status full duplex update from adapter", port->actor_port_number)); + break; + case DUPLEX_HALF: + default: + retval=0x0; + BOND_PRINT_DBG(("Port %d Received status NOT full duplex update from adapter", port->actor_port_number)); + break; + } + } + return retval; +} + +/** + * __initialize_port_locks - initialize a port's RX machine spinlock + * @port: the port we're looking at + * + */ +static inline void __initialize_port_locks(struct port *port) +{ + // make sure it isn't called twice + spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); +} + +/** + * __deinitialize_port_locks - deinitialize a port's RX machine spinlock + * @port: the port we're looking at + * + */ +static inline void __deinitialize_port_locks(struct port *port) +{ +} + +//conversions +/** + * __ntohs_lacpdu - convert the contents of a LACPDU to host byte order + * @lacpdu: the speicifed lacpdu + * + * For each multi-byte field in the lacpdu, convert its content + */ +static void __ntohs_lacpdu(struct lacpdu *lacpdu) +{ + if (lacpdu) { + lacpdu->actor_system_priority = ntohs(lacpdu->actor_system_priority); + lacpdu->actor_key = ntohs(lacpdu->actor_key); + lacpdu->actor_port_priority = ntohs(lacpdu->actor_port_priority); + lacpdu->actor_port = ntohs(lacpdu->actor_port); + lacpdu->partner_system_priority = ntohs(lacpdu->partner_system_priority); + lacpdu->partner_key = ntohs(lacpdu->partner_key); + lacpdu->partner_port_priority = ntohs(lacpdu->partner_port_priority); + lacpdu->partner_port = ntohs(lacpdu->partner_port); + lacpdu->collector_max_delay = ntohs(lacpdu->collector_max_delay); + } +} + +/** + * __ad_timer_to_ticks - convert a given timer type to AD module ticks + * @timer_type: which timer to operate + * @par: timer parameter. see below + * + * If @timer_type is %current_while_timer, @par indicates long/short timer. + * If @timer_type is %periodic_timer, @par is one of %FAST_PERIODIC_TIME, + * %SLOW_PERIODIC_TIME. + */ +static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) +{ + u16 retval=0; //to silence the compiler + + switch (timer_type) { + case AD_CURRENT_WHILE_TIMER: // for rx machine usage + if (par) { // for short or long timeout + retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout + } else { + retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout + } + break; + case AD_ACTOR_CHURN_TIMER: // for local churn machine + retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); + break; + case AD_PERIODIC_TIMER: // for periodic machine + retval = (par*ad_ticks_per_sec); // long timeout + break; + case AD_PARTNER_CHURN_TIMER: // for remote churn machine + retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); + break; + case AD_WAIT_WHILE_TIMER: // for selection machine + retval = (AD_AGGREGATE_WAIT_TIME*ad_ticks_per_sec); + break; + } + return retval; +} + + +///////////////////////////////////////////////////////////////////////////////// +// ================= ad_rx_machine helper functions ================== +///////////////////////////////////////////////////////////////////////////////// + +/** + * __record_pdu - record parameters from a received lacpdu + * @lacpdu: the lacpdu we've received + * @port: the port we're looking at + * + * Record the parameter values for the Actor carried in a received lacpdu as + * the current partner operational parameter values and sets + * actor_oper_port_state.defaulted to FALSE. + */ +static void __record_pdu(struct lacpdu *lacpdu, struct port *port) +{ + // validate lacpdu and port + if (lacpdu && port) { + // record the new parameter values for the partner operational + port->partner_oper_port_number = lacpdu->actor_port; + port->partner_oper_port_priority = lacpdu->actor_port_priority; + port->partner_oper_system = lacpdu->actor_system; + port->partner_oper_system_priority = lacpdu->actor_system_priority; + port->partner_oper_key = lacpdu->actor_key; + // zero partener's lase states + port->partner_oper_port_state = 0; + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY); + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_TIMEOUT); + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_AGGREGATION); + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION); + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_COLLECTING); + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DISTRIBUTING); + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DEFAULTED); + port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_EXPIRED); + + // set actor_oper_port_state.defaulted to FALSE + port->actor_oper_port_state &= ~AD_STATE_DEFAULTED; + + // set the partner sync. to on if the partner is sync. and the port is matched + if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) { + port->partner_oper_port_state |= AD_STATE_SYNCHRONIZATION; + } else { + port->partner_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; + } + } +} + +/** + * __record_default - record default parameters + * @port: the port we're looking at + * + * This function records the default parameter values for the partner carried + * in the Partner Admin parameters as the current partner operational parameter + * values and sets actor_oper_port_state.defaulted to TRUE. + */ +static void __record_default(struct port *port) +{ + // validate the port + if (port) { + // record the partner admin parameters + port->partner_oper_port_number = port->partner_admin_port_number; + port->partner_oper_port_priority = port->partner_admin_port_priority; + port->partner_oper_system = port->partner_admin_system; + port->partner_oper_system_priority = port->partner_admin_system_priority; + port->partner_oper_key = port->partner_admin_key; + port->partner_oper_port_state = port->partner_admin_port_state; + + // set actor_oper_port_state.defaulted to true + port->actor_oper_port_state |= AD_STATE_DEFAULTED; + } +} + +/** + * __update_selected - update a port's Selected variable from a received lacpdu + * @lacpdu: the lacpdu we've received + * @port: the port we're looking at + * + * Update the value of the selected variable, using parameter values from a + * newly received lacpdu. The parameter values for the Actor carried in the + * received PDU are compared with the corresponding operational parameter + * values for the ports partner. If one or more of the comparisons shows that + * the value(s) received in the PDU differ from the current operational values, + * then selected is set to FALSE and actor_oper_port_state.synchronization is + * set to out_of_sync. Otherwise, selected remains unchanged. + */ +static void __update_selected(struct lacpdu *lacpdu, struct port *port) +{ + // validate lacpdu and port + if (lacpdu && port) { + // check if any parameter is different + if ((lacpdu->actor_port != port->partner_oper_port_number) || + (lacpdu->actor_port_priority != port->partner_oper_port_priority) || + MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) || + (lacpdu->actor_system_priority != port->partner_oper_system_priority) || + (lacpdu->actor_key != port->partner_oper_key) || + ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) + ) { + // update the state machine Selected variable + port->sm_vars &= ~AD_PORT_SELECTED; + } + } +} + +/** + * __update_default_selected - update a port's Selected variable from Partner + * @port: the port we're looking at + * + * This function updates the value of the selected variable, using the partner + * administrative parameter values. The administrative values are compared with + * the corresponding operational parameter values for the partner. If one or + * more of the comparisons shows that the administrative value(s) differ from + * the current operational values, then Selected is set to FALSE and + * actor_oper_port_state.synchronization is set to OUT_OF_SYNC. Otherwise, + * Selected remains unchanged. + */ +static void __update_default_selected(struct port *port) +{ + // validate the port + if (port) { + // check if any parameter is different + if ((port->partner_admin_port_number != port->partner_oper_port_number) || + (port->partner_admin_port_priority != port->partner_oper_port_priority) || + MAC_ADDRESS_COMPARE(&(port->partner_admin_system), &(port->partner_oper_system)) || + (port->partner_admin_system_priority != port->partner_oper_system_priority) || + (port->partner_admin_key != port->partner_oper_key) || + ((port->partner_admin_port_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) + ) { + // update the state machine Selected variable + port->sm_vars &= ~AD_PORT_SELECTED; + } + } +} + +/** + * __choose_matched - update a port's matched variable from a received lacpdu + * @lacpdu: the lacpdu we've received + * @port: the port we're looking at + * + * Update the value of the matched variable, using parameter values from a + * newly received lacpdu. Parameter values for the partner carried in the + * received PDU are compared with the corresponding operational parameter + * values for the actor. Matched is set to TRUE if all of these parameters + * match and the PDU parameter partner_state.aggregation has the same value as + * actor_oper_port_state.aggregation and lacp will actively maintain the link + * in the aggregation. Matched is also set to TRUE if the value of + * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates + * an individual link and lacp will actively maintain the link. Otherwise, + * matched is set to FALSE. LACP is considered to be actively maintaining the + * link if either the PDU's actor_state.lacp_activity variable is TRUE or both + * the actor's actor_oper_port_state.lacp_activity and the PDU's + * partner_state.lacp_activity variables are TRUE. + */ +static void __choose_matched(struct lacpdu *lacpdu, struct port *port) +{ + // validate lacpdu and port + if (lacpdu && port) { + // check if all parameters are alike + if (((lacpdu->partner_port == port->actor_port_number) && + (lacpdu->partner_port_priority == port->actor_port_priority) && + !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && + (lacpdu->partner_system_priority == port->actor_system_priority) && + (lacpdu->partner_key == port->actor_oper_port_key) && + ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || + // or this is individual link(aggregation == FALSE) + ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) + ) { + // update the state machine Matched variable + port->sm_vars |= AD_PORT_MATCHED; + } else { + port->sm_vars &= ~AD_PORT_MATCHED; + } + } +} + +/** + * __update_ntt - update a port's ntt variable from a received lacpdu + * @lacpdu: the lacpdu we've received + * @port: the port we're looking at + * + * Updates the value of the ntt variable, using parameter values from a newly + * received lacpdu. The parameter values for the partner carried in the + * received PDU are compared with the corresponding operational parameter + * values for the Actor. If one or more of the comparisons shows that the + * value(s) received in the PDU differ from the current operational values, + * then ntt is set to TRUE. Otherwise, ntt remains unchanged. + */ +static void __update_ntt(struct lacpdu *lacpdu, struct port *port) +{ + // validate lacpdu and port + if (lacpdu && port) { + // check if any parameter is different + if ((lacpdu->partner_port != port->actor_port_number) || + (lacpdu->partner_port_priority != port->actor_port_priority) || + MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || + (lacpdu->partner_system_priority != port->actor_system_priority) || + (lacpdu->partner_key != port->actor_oper_port_key) || + ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || + ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) || + ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || + ((lacpdu->partner_state & AD_STATE_AGGREGATION) != (port->actor_oper_port_state & AD_STATE_AGGREGATION)) + ) { + // set ntt to be TRUE + port->ntt = 1; + } + } +} + +/** + * __attach_bond_to_agg + * @port: the port we're looking at + * + * Handle the attaching of the port's control parser/multiplexer and the + * aggregator. This function does nothing since the parser/multiplexer of the + * receive and the parser/multiplexer of the aggregator are already combined. + */ +static void __attach_bond_to_agg(struct port *port) +{ + port=NULL; // just to satisfy the compiler + // This function does nothing since the parser/multiplexer of the receive + // and the parser/multiplexer of the aggregator are already combined +} + +/** + * __detach_bond_from_agg + * @port: the port we're looking at + * + * Handle the detaching of the port's control parser/multiplexer from the + * aggregator. This function does nothing since the parser/multiplexer of the + * receive and the parser/multiplexer of the aggregator are already combined. + */ +static void __detach_bond_from_agg(struct port *port) +{ + port=NULL; // just to satisfy the compiler + // This function does nothing sience the parser/multiplexer of the receive + // and the parser/multiplexer of the aggregator are already combined +} + +/** + * __agg_ports_are_ready - check if all ports in an aggregator are ready + * @aggregator: the aggregator we're looking at + * + */ +static int __agg_ports_are_ready(struct aggregator *aggregator) +{ + struct port *port; + int retval = 1; + + if (aggregator) { + // scan all ports in this aggregator to verfy if they are all ready + for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { + if (!(port->sm_vars & AD_PORT_READY_N)) { + retval = 0; + break; + } + } + } + + return retval; +} + +/** + * __set_agg_ports_ready - set value of Ready bit in all ports of an aggregator + * @aggregator: the aggregator we're looking at + * @val: Should the ports' ready bit be set on or off + * + */ +static void __set_agg_ports_ready(struct aggregator *aggregator, int val) +{ + struct port *port; + + for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { + if (val) { + port->sm_vars |= AD_PORT_READY; + } else { + port->sm_vars &= ~AD_PORT_READY; + } + } +} + +/** + * __get_agg_bandwidth - get the total bandwidth of an aggregator + * @aggregator: the aggregator we're looking at + * + */ +static u32 __get_agg_bandwidth(struct aggregator *aggregator) +{ + u32 bandwidth=0; + u32 basic_speed; + + if (aggregator->num_of_ports) { + basic_speed = __get_link_speed(aggregator->lag_ports); + switch (basic_speed) { + case AD_LINK_SPEED_BITMASK_1MBPS: + bandwidth = aggregator->num_of_ports; + break; + case AD_LINK_SPEED_BITMASK_10MBPS: + bandwidth = aggregator->num_of_ports * 10; + break; + case AD_LINK_SPEED_BITMASK_100MBPS: + bandwidth = aggregator->num_of_ports * 100; + break; + case AD_LINK_SPEED_BITMASK_1000MBPS: + bandwidth = aggregator->num_of_ports * 1000; + break; + default: + bandwidth=0; // to silent the compilor .... + } + } + return bandwidth; +} + +/** + * __get_active_agg - get the current active aggregator + * @aggregator: the aggregator we're looking at + * + */ +static struct aggregator *__get_active_agg(struct aggregator *aggregator) +{ + struct aggregator *retval = NULL; + + for (; aggregator; aggregator = __get_next_agg(aggregator)) { + if (aggregator->is_active) { + retval = aggregator; + break; + } + } + + return retval; +} + +/** + * __update_lacpdu_from_port - update a port's lacpdu fields + * @port: the port we're looking at + * + */ +static inline void __update_lacpdu_from_port(struct port *port) +{ + struct lacpdu *lacpdu = &port->lacpdu; + + /* update current actual Actor parameters */ + /* lacpdu->subtype initialized + * lacpdu->version_number initialized + * lacpdu->tlv_type_actor_info initialized + * lacpdu->actor_information_length initialized + */ + + lacpdu->actor_system_priority = port->actor_system_priority; + lacpdu->actor_system = port->actor_system; + lacpdu->actor_key = port->actor_oper_port_key; + lacpdu->actor_port_priority = port->actor_port_priority; + lacpdu->actor_port = port->actor_port_number; + lacpdu->actor_state = port->actor_oper_port_state; + + /* lacpdu->reserved_3_1 initialized + * lacpdu->tlv_type_partner_info initialized + * lacpdu->partner_information_length initialized + */ + + lacpdu->partner_system_priority = port->partner_oper_system_priority; + lacpdu->partner_system = port->partner_oper_system; + lacpdu->partner_key = port->partner_oper_key; + lacpdu->partner_port_priority = port->partner_oper_port_priority; + lacpdu->partner_port = port->partner_oper_port_number; + lacpdu->partner_state = port->partner_oper_port_state; + + /* lacpdu->reserved_3_2 initialized + * lacpdu->tlv_type_collector_info initialized + * lacpdu->collector_information_length initialized + * collector_max_delay initialized + * reserved_12[12] initialized + * tlv_type_terminator initialized + * terminator_length initialized + * reserved_50[50] initialized + */ + + /* Convert all non u8 parameters to Big Endian for transmit */ + __ntohs_lacpdu(lacpdu); +} + +////////////////////////////////////////////////////////////////////////////////////// +// ================= main 802.3ad protocol code ====================================== +////////////////////////////////////////////////////////////////////////////////////// + +/** + * ad_lacpdu_send - send out a lacpdu packet on a given port + * @port: the port we're looking at + * + * Returns: 0 on success + * < 0 on error + */ +static int ad_lacpdu_send(struct port *port) +{ + struct slave *slave = port->slave; + struct sk_buff *skb; + struct lacpdu_header *lacpdu_header; + int length = sizeof(struct lacpdu_header); + struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR; + + skb = dev_alloc_skb(length); + if (!skb) { + return -ENOMEM; + } + + skb->dev = slave->dev; + skb->mac.raw = skb->data; + skb->nh.raw = skb->data + ETH_HLEN; + skb->protocol = PKT_TYPE_LACPDU; + skb->priority = TC_PRIO_CONTROL; + + lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); + + lacpdu_header->ad_header.destination_address = lacpdu_multicast_address; + /* Note: source addres is set to be the member's PERMANENT address, because we use it + to identify loopback lacpdus in receive. */ + lacpdu_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr)); + lacpdu_header->ad_header.length_type = PKT_TYPE_LACPDU; + + lacpdu_header->lacpdu = port->lacpdu; // struct copy + + dev_queue_xmit(skb); + + return 0; +} + +/** + * ad_marker_send - send marker information/response on a given port + * @port: the port we're looking at + * @marker: marker data to send + * + * Returns: 0 on success + * < 0 on error + */ +static int ad_marker_send(struct port *port, struct marker *marker) +{ + struct slave *slave = port->slave; + struct sk_buff *skb; + struct marker_header *marker_header; + int length = sizeof(struct marker_header); + struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR; + + skb = dev_alloc_skb(length + 16); + if (!skb) { + return -ENOMEM; + } + + skb_reserve(skb, 16); + + skb->dev = slave->dev; + skb->mac.raw = skb->data; + skb->nh.raw = skb->data + ETH_HLEN; + skb->protocol = PKT_TYPE_LACPDU; + + marker_header = (struct marker_header *)skb_put(skb, length); + + marker_header->ad_header.destination_address = lacpdu_multicast_address; + /* Note: source addres is set to be the member's PERMANENT address, because we use it + to identify loopback MARKERs in receive. */ + marker_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr)); + marker_header->ad_header.length_type = PKT_TYPE_LACPDU; + + marker_header->marker = *marker; // struct copy + + dev_queue_xmit(skb); + + return 0; +} + +/** + * ad_mux_machine - handle a port's mux state machine + * @port: the port we're looking at + * + */ +static void ad_mux_machine(struct port *port) +{ + mux_states_t last_state; + + // keep current State Machine state to compare later if it was changed + last_state = port->sm_mux_state; + + if (port->sm_vars & AD_PORT_BEGIN) { + port->sm_mux_state = AD_MUX_DETACHED; // next state + } else { + switch (port->sm_mux_state) { + case AD_MUX_DETACHED: + if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY + port->sm_mux_state = AD_MUX_WAITING; // next state + } + break; + case AD_MUX_WAITING: + // if SELECTED == FALSE return to DETACH state + if (!(port->sm_vars & AD_PORT_SELECTED)) { // if UNSELECTED + port->sm_vars &= ~AD_PORT_READY_N; + // in order to withhold the Selection Logic to check all ports READY_N value + // every callback cycle to update ready variable, we check READY_N and update READY here + __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); + port->sm_mux_state = AD_MUX_DETACHED; // next state + break; + } + + // check if the wait_while_timer expired + if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) { + port->sm_vars |= AD_PORT_READY_N; + } + + // in order to withhold the selection logic to check all ports READY_N value + // every callback cycle to update ready variable, we check READY_N and update READY here + __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); + + // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state + if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) { + port->sm_mux_state = AD_MUX_ATTACHED; // next state + } + break; + case AD_MUX_ATTACHED: + // check also if agg_select_timer expired(so the edable port will take place only after this timer) + if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) { + port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state + } else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if UNSELECTED or STANDBY + port->sm_vars &= ~AD_PORT_READY_N; + // in order to withhold the selection logic to check all ports READY_N value + // every callback cycle to update ready variable, we check READY_N and update READY here + __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); + port->sm_mux_state = AD_MUX_DETACHED;// next state + } + break; + case AD_MUX_COLLECTING_DISTRIBUTING: + if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) || + !(port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION) + ) { + port->sm_mux_state = AD_MUX_ATTACHED;// next state + + } else { + // if port state hasn't changed make + // sure that a collecting distributing + // port in an active aggregator is enabled + if (port->aggregator && + port->aggregator->is_active && + !__port_is_enabled(port)) { + + __enable_port(port); + } + } + break; + default: //to silence the compiler + break; + } + } + + // check if the state machine was changed + if (port->sm_mux_state != last_state) { + BOND_PRINT_DBG(("Mux Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_mux_state)); + switch (port->sm_mux_state) { + case AD_MUX_DETACHED: + __detach_bond_from_agg(port); + port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; + ad_disable_collecting_distributing(port); + port->actor_oper_port_state &= ~AD_STATE_COLLECTING; + port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING; + port->ntt = 1; + break; + case AD_MUX_WAITING: + port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0); + break; + case AD_MUX_ATTACHED: + __attach_bond_to_agg(port); + port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; + port->actor_oper_port_state &= ~AD_STATE_COLLECTING; + port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING; + ad_disable_collecting_distributing(port); + port->ntt = 1; + break; + case AD_MUX_COLLECTING_DISTRIBUTING: + port->actor_oper_port_state |= AD_STATE_COLLECTING; + port->actor_oper_port_state |= AD_STATE_DISTRIBUTING; + ad_enable_collecting_distributing(port); + port->ntt = 1; + break; + default: //to silence the compiler + break; + } + } +} + +/** + * ad_rx_machine - handle a port's rx State Machine + * @lacpdu: the lacpdu we've received + * @port: the port we're looking at + * + * If lacpdu arrived, stop previous timer (if exists) and set the next state as + * CURRENT. If timer expired set the state machine in the proper state. + * In other cases, this function checks if we need to switch to other state. + */ +static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) +{ + rx_states_t last_state; + + // Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback) + __get_rx_machine_lock(port); + + // keep current State Machine state to compare later if it was changed + last_state = port->sm_rx_state; + + // check if state machine should change state + // first, check if port was reinitialized + if (port->sm_vars & AD_PORT_BEGIN) { + port->sm_rx_state = AD_RX_INITIALIZE; // next state + } + // check if port is not enabled + else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) { + port->sm_rx_state = AD_RX_PORT_DISABLED; // next state + } + // check if new lacpdu arrived + else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) { + port->sm_rx_timer_counter = 0; // zero timer + port->sm_rx_state = AD_RX_CURRENT; + } else { + // if timer is on, and if it is expired + if (port->sm_rx_timer_counter && !(--port->sm_rx_timer_counter)) { + switch (port->sm_rx_state) { + case AD_RX_EXPIRED: + port->sm_rx_state = AD_RX_DEFAULTED; // next state + break; + case AD_RX_CURRENT: + port->sm_rx_state = AD_RX_EXPIRED; // next state + break; + default: //to silence the compiler + break; + } + } else { + // if no lacpdu arrived and no timer is on + switch (port->sm_rx_state) { + case AD_RX_PORT_DISABLED: + if (port->sm_vars & AD_PORT_MOVED) { + port->sm_rx_state = AD_RX_INITIALIZE; // next state + } else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) { + port->sm_rx_state = AD_RX_EXPIRED; // next state + } else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) { + port->sm_rx_state = AD_RX_LACP_DISABLED; // next state + } + break; + default: //to silence the compiler + break; + + } + } + } + + // check if the State machine was changed or new lacpdu arrived + if ((port->sm_rx_state != last_state) || (lacpdu)) { + BOND_PRINT_DBG(("Rx Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_rx_state)); + switch (port->sm_rx_state) { + case AD_RX_INITIALIZE: + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { + port->sm_vars &= ~AD_PORT_LACP_ENABLED; + } else { + port->sm_vars |= AD_PORT_LACP_ENABLED; + } + port->sm_vars &= ~AD_PORT_SELECTED; + __record_default(port); + port->actor_oper_port_state &= ~AD_STATE_EXPIRED; + port->sm_vars &= ~AD_PORT_MOVED; + port->sm_rx_state = AD_RX_PORT_DISABLED; // next state + + /*- Fall Through -*/ + + case AD_RX_PORT_DISABLED: + port->sm_vars &= ~AD_PORT_MATCHED; + break; + case AD_RX_LACP_DISABLED: + port->sm_vars &= ~AD_PORT_SELECTED; + __record_default(port); + port->partner_oper_port_state &= ~AD_STATE_AGGREGATION; + port->sm_vars |= AD_PORT_MATCHED; + port->actor_oper_port_state &= ~AD_STATE_EXPIRED; + break; + case AD_RX_EXPIRED: + //Reset of the Synchronization flag. (Standard 43.4.12) + //This reset cause to disable this port in the COLLECTING_DISTRIBUTING state of the + //mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port. + port->partner_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; + port->sm_vars &= ~AD_PORT_MATCHED; + port->partner_oper_port_state |= AD_SHORT_TIMEOUT; + port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT)); + port->actor_oper_port_state |= AD_STATE_EXPIRED; + break; + case AD_RX_DEFAULTED: + __update_default_selected(port); + __record_default(port); + port->sm_vars |= AD_PORT_MATCHED; + port->actor_oper_port_state &= ~AD_STATE_EXPIRED; + break; + case AD_RX_CURRENT: + // detect loopback situation + if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) { + // INFO_RECEIVED_LOOPBACK_FRAMES + printk(KERN_ERR "bonding: An illegal loopback occurred on adapter (%s)\n", + port->slave->dev->name); + printk(KERN_ERR "Check the configuration to verify that all Adapters " + "are connected to 802.3ad compliant switch ports\n"); + __release_rx_machine_lock(port); + return; + } + __update_selected(lacpdu, port); + __update_ntt(lacpdu, port); + __record_pdu(lacpdu, port); + __choose_matched(lacpdu, port); + port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)); + port->actor_oper_port_state &= ~AD_STATE_EXPIRED; + // verify that if the aggregator is enabled, the port is enabled too. + //(because if the link goes down for a short time, the 802.3ad will not + // catch it, and the port will continue to be disabled) + if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) { + __enable_port(port); + } + break; + default: //to silence the compiler + break; + } + } + __release_rx_machine_lock(port); +} + +/** + * ad_tx_machine - handle a port's tx state machine + * @port: the port we're looking at + * + */ +static void ad_tx_machine(struct port *port) +{ + // check if tx timer expired, to verify that we do not send more than 3 packets per second + if (port->sm_tx_timer_counter && !(--port->sm_tx_timer_counter)) { + // check if there is something to send + if (port->ntt && (port->sm_vars & AD_PORT_LACP_ENABLED)) { + __update_lacpdu_from_port(port); + // send the lacpdu + if (ad_lacpdu_send(port) >= 0) { + BOND_PRINT_DBG(("Sent LACPDU on port %d", port->actor_port_number)); + // mark ntt as false, so it will not be sent again until demanded + port->ntt = 0; + } + } + // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND + port->sm_tx_timer_counter=ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; + } +} + +/** + * ad_periodic_machine - handle a port's periodic state machine + * @port: the port we're looking at + * + * Turn ntt flag on priodically to perform periodic transmission of lacpdu's. + */ +static void ad_periodic_machine(struct port *port) +{ + periodic_states_t last_state; + + // keep current state machine state to compare later if it was changed + last_state = port->sm_periodic_state; + + // check if port was reinitialized + if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) || + (!(port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY) && !(port->partner_oper_port_state & AD_STATE_LACP_ACTIVITY)) + ) { + port->sm_periodic_state = AD_NO_PERIODIC; // next state + } + // check if state machine should change state + else if (port->sm_periodic_timer_counter) { + // check if periodic state machine expired + if (!(--port->sm_periodic_timer_counter)) { + // if expired then do tx + port->sm_periodic_state = AD_PERIODIC_TX; // next state + } else { + // If not expired, check if there is some new timeout parameter from the partner state + switch (port->sm_periodic_state) { + case AD_FAST_PERIODIC: + if (!(port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) { + port->sm_periodic_state = AD_SLOW_PERIODIC; // next state + } + break; + case AD_SLOW_PERIODIC: + if ((port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) { + // stop current timer + port->sm_periodic_timer_counter = 0; + port->sm_periodic_state = AD_PERIODIC_TX; // next state + } + break; + default: //to silence the compiler + break; + } + } + } else { + switch (port->sm_periodic_state) { + case AD_NO_PERIODIC: + port->sm_periodic_state = AD_FAST_PERIODIC; // next state + break; + case AD_PERIODIC_TX: + if (!(port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) { + port->sm_periodic_state = AD_SLOW_PERIODIC; // next state + } else { + port->sm_periodic_state = AD_FAST_PERIODIC; // next state + } + break; + default: //to silence the compiler + break; + } + } + + // check if the state machine was changed + if (port->sm_periodic_state != last_state) { + BOND_PRINT_DBG(("Periodic Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_periodic_state)); + switch (port->sm_periodic_state) { + case AD_NO_PERIODIC: + port->sm_periodic_timer_counter = 0; // zero timer + break; + case AD_FAST_PERIODIC: + port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_FAST_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle + break; + case AD_SLOW_PERIODIC: + port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_SLOW_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle + break; + case AD_PERIODIC_TX: + port->ntt = 1; + break; + default: //to silence the compiler + break; + } + } +} + +/** + * ad_port_selection_logic - select aggregation groups + * @port: the port we're looking at + * + * Select aggregation groups, and assign each port for it's aggregetor. The + * selection logic is called in the inititalization (after all the handshkes), + * and after every lacpdu receive (if selected is off). + */ +static void ad_port_selection_logic(struct port *port) +{ + struct aggregator *aggregator, *free_aggregator = NULL, *temp_aggregator; + struct port *last_port = NULL, *curr_port; + int found = 0; + + // if the port is already Selected, do nothing + if (port->sm_vars & AD_PORT_SELECTED) { + return; + } + + // if the port is connected to other aggregator, detach it + if (port->aggregator) { + // detach the port from its former aggregator + temp_aggregator=port->aggregator; + for (curr_port=temp_aggregator->lag_ports; curr_port; last_port=curr_port, curr_port=curr_port->next_port_in_aggregator) { + if (curr_port == port) { + temp_aggregator->num_of_ports--; + if (!last_port) {// if it is the first port attached to the aggregator + temp_aggregator->lag_ports=port->next_port_in_aggregator; + } else {// not the first port attached to the aggregator + last_port->next_port_in_aggregator=port->next_port_in_aggregator; + } + + // clear the port's relations to this aggregator + port->aggregator = NULL; + port->next_port_in_aggregator=NULL; + port->actor_port_aggregator_identifier=0; + + BOND_PRINT_DBG(("Port %d left LAG %d", port->actor_port_number, temp_aggregator->aggregator_identifier)); + // if the aggregator is empty, clear its parameters, and set it ready to be attached + if (!temp_aggregator->lag_ports) { + ad_clear_agg(temp_aggregator); + } + break; + } + } + if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list + printk(KERN_WARNING "bonding: Warning: Port %d (on %s) was " + "related to aggregator %d but was not on its port list\n", + port->actor_port_number, port->slave->dev->name, + port->aggregator->aggregator_identifier); + } + } + // search on all aggregators for a suitable aggregator for this port + for (aggregator = __get_first_agg(port); aggregator; + aggregator = __get_next_agg(aggregator)) { + + // keep a free aggregator for later use(if needed) + if (!aggregator->lag_ports) { + if (!free_aggregator) { + free_aggregator=aggregator; + } + continue; + } + // check if current aggregator suits us + if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) && // if all parameters match AND + !MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(port->partner_oper_system)) && + (aggregator->partner_system_priority == port->partner_oper_system_priority) && + (aggregator->partner_oper_aggregator_key == port->partner_oper_key) + ) && + ((MAC_ADDRESS_COMPARE(&(port->partner_oper_system), &(null_mac_addr)) && // partner answers + !aggregator->is_individual) // but is not individual OR + ) + ) { + // attach to the founded aggregator + port->aggregator = aggregator; + port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; + port->next_port_in_aggregator=aggregator->lag_ports; + port->aggregator->num_of_ports++; + aggregator->lag_ports=port; + BOND_PRINT_DBG(("Port %d joined LAG %d(existing LAG)", port->actor_port_number, port->aggregator->aggregator_identifier)); + + // mark this port as selected + port->sm_vars |= AD_PORT_SELECTED; + found = 1; + break; + } + } + + // the port couldn't find an aggregator - attach it to a new aggregator + if (!found) { + if (free_aggregator) { + // assign port a new aggregator + port->aggregator = free_aggregator; + port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; + + // update the new aggregator's parameters + // if port was responsed from the end-user + if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) {// if port is full duplex + port->aggregator->is_individual = 0; + } else { + port->aggregator->is_individual = 1; + } + + port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key; + port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key; + port->aggregator->partner_system=port->partner_oper_system; + port->aggregator->partner_system_priority = port->partner_oper_system_priority; + port->aggregator->partner_oper_aggregator_key = port->partner_oper_key; + port->aggregator->receive_state = 1; + port->aggregator->transmit_state = 1; + port->aggregator->lag_ports = port; + port->aggregator->num_of_ports++; + + // mark this port as selected + port->sm_vars |= AD_PORT_SELECTED; + + BOND_PRINT_DBG(("Port %d joined LAG %d(new LAG)", port->actor_port_number, port->aggregator->aggregator_identifier)); + } else { + printk(KERN_ERR "bonding: Port %d (on %s) did not find a suitable aggregator\n", + port->actor_port_number, port->slave->dev->name); + } + } + // if all aggregator's ports are READY_N == TRUE, set ready=TRUE in all aggregator's ports + // else set ready=FALSE in all aggregator's ports + __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); + + if (!__check_agg_selection_timer(port) && (aggregator = __get_first_agg(port))) { + ad_agg_selection_logic(aggregator); + } +} + +/** + * ad_agg_selection_logic - select an aggregation group for a team + * @aggregator: the aggregator we're looking at + * + * It is assumed that only one aggregator may be selected for a team. + * The logic of this function is to select (at first time) the aggregator with + * the most ports attached to it, and to reselect the active aggregator only if + * the previous aggregator has no more ports related to it. + * + * FIXME: this function MUST be called with the first agg in the bond, or + * __get_active_agg() won't work correctly. This function should be better + * called with the bond itself, and retrieve the first agg from it. + */ +static void ad_agg_selection_logic(struct aggregator *aggregator) +{ + struct aggregator *best_aggregator = NULL, *active_aggregator = NULL; + struct aggregator *last_active_aggregator = NULL, *origin_aggregator; + struct port *port; + u16 num_of_aggs=0; + + origin_aggregator = aggregator; + + //get current active aggregator + last_active_aggregator = __get_active_agg(aggregator); + + // search for the aggregator with the most ports attached to it. + do { + // count how many candidate lag's we have + if (aggregator->lag_ports) { + num_of_aggs++; + } + if (aggregator->is_active && !aggregator->is_individual && // if current aggregator is the active aggregator + MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr))) { // and partner answers to 802.3ad PDUs + if (aggregator->num_of_ports) { // if any ports attached to the current aggregator + best_aggregator=NULL; // disregard the best aggregator that was chosen by now + break; // stop the selection of other aggregator if there are any ports attached to this active aggregator + } else { // no ports attached to this active aggregator + aggregator->is_active = 0; // mark this aggregator as not active anymore + } + } + if (aggregator->num_of_ports) { // if any ports attached + if (best_aggregator) { // if there is a candidte aggregator + //The reasons for choosing new best aggregator: + // 1. if current agg is NOT individual and the best agg chosen so far is individual OR + // current and best aggs are both individual or both not individual, AND + // 2a. current agg partner reply but best agg partner do not reply OR + // 2b. current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply AND + // current has more ports/bandwidth, or same amount of ports but current has faster ports, THEN + // current agg become best agg so far + + //if current agg is NOT individual and the best agg chosen so far is individual change best_aggregator + if (!aggregator->is_individual && best_aggregator->is_individual) { + best_aggregator=aggregator; + } + // current and best aggs are both individual or both not individual + else if ((aggregator->is_individual && best_aggregator->is_individual) || + (!aggregator->is_individual && !best_aggregator->is_individual)) { + // current and best aggs are both individual or both not individual AND + // current agg partner reply but best agg partner do not reply + if ((MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) && + !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) { + best_aggregator=aggregator; + } + // current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply + else if (! (!MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) && + MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) { + if ((__get_agg_selection_mode(aggregator->lag_ports) == AD_BANDWIDTH)&& + (__get_agg_bandwidth(aggregator) > __get_agg_bandwidth(best_aggregator))) { + best_aggregator=aggregator; + } else if (__get_agg_selection_mode(aggregator->lag_ports) == AD_COUNT) { + if (((aggregator->num_of_ports > best_aggregator->num_of_ports) && + (aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS))|| + ((aggregator->num_of_ports == best_aggregator->num_of_ports) && + ((u16)(aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS) > + (u16)(best_aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS)))) { + best_aggregator=aggregator; + } + } + } + } + } else { + best_aggregator=aggregator; + } + } + aggregator->is_active = 0; // mark all aggregators as not active anymore + } while ((aggregator = __get_next_agg(aggregator))); + + // if we have new aggregator selected, don't replace the old aggregator if it has an answering partner, + // or if both old aggregator and new aggregator don't have answering partner + if (best_aggregator) { + if (last_active_aggregator && last_active_aggregator->lag_ports && last_active_aggregator->lag_ports->is_enabled && + (MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) || // partner answers OR + (!MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) && // both old and new + !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) // partner do not answer + ) { + // if new aggregator has link, and old aggregator does not, replace old aggregator.(do nothing) + // -> don't replace otherwise. + if (!(!last_active_aggregator->actor_oper_aggregator_key && best_aggregator->actor_oper_aggregator_key)) { + best_aggregator=NULL; + last_active_aggregator->is_active = 1; // don't replace good old aggregator + + } + } + } + + // if there is new best aggregator, activate it + if (best_aggregator) { + for (aggregator = __get_first_agg(best_aggregator->lag_ports); + aggregator; + aggregator = __get_next_agg(aggregator)) { + + BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d", + aggregator->aggregator_identifier, aggregator->num_of_ports, + aggregator->actor_oper_aggregator_key, aggregator->partner_oper_aggregator_key, + aggregator->is_individual, aggregator->is_active)); + } + + // check if any partner replys + if (best_aggregator->is_individual) { + printk(KERN_WARNING "bonding: Warning: No 802.3ad response from the link partner " + "for any adapters in the bond\n"); + } + + // check if there are more than one aggregator + if (num_of_aggs > 1) { + BOND_PRINT_DBG(("Warning: More than one Link Aggregation Group was " + "found in the bond. Only one group will function in the bond")); + } + + best_aggregator->is_active = 1; + BOND_PRINT_DBG(("LAG %d choosed as the active LAG", best_aggregator->aggregator_identifier)); + BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d", + best_aggregator->aggregator_identifier, best_aggregator->num_of_ports, + best_aggregator->actor_oper_aggregator_key, best_aggregator->partner_oper_aggregator_key, + best_aggregator->is_individual, best_aggregator->is_active)); + + // disable the ports that were related to the former active_aggregator + if (last_active_aggregator) { + for (port=last_active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) { + __disable_port(port); + } + } + } + + // if the selected aggregator is of join individuals(partner_system is NULL), enable their ports + active_aggregator = __get_active_agg(origin_aggregator); + + if (active_aggregator) { + if (!MAC_ADDRESS_COMPARE(&(active_aggregator->partner_system), &(null_mac_addr))) { + for (port=active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) { + __enable_port(port); + } + } + } +} + +/** + * ad_clear_agg - clear a given aggregator's parameters + * @aggregator: the aggregator we're looking at + * + */ +static void ad_clear_agg(struct aggregator *aggregator) +{ + if (aggregator) { + aggregator->is_individual = 0; + aggregator->actor_admin_aggregator_key = 0; + aggregator->actor_oper_aggregator_key = 0; + aggregator->partner_system = null_mac_addr; + aggregator->partner_system_priority = 0; + aggregator->partner_oper_aggregator_key = 0; + aggregator->receive_state = 0; + aggregator->transmit_state = 0; + aggregator->lag_ports = NULL; + aggregator->is_active = 0; + aggregator->num_of_ports = 0; + BOND_PRINT_DBG(("LAG %d was cleared", aggregator->aggregator_identifier)); + } +} + +/** + * ad_initialize_agg - initialize a given aggregator's parameters + * @aggregator: the aggregator we're looking at + * + */ +static void ad_initialize_agg(struct aggregator *aggregator) +{ + if (aggregator) { + ad_clear_agg(aggregator); + + aggregator->aggregator_mac_address = null_mac_addr; + aggregator->aggregator_identifier = 0; + aggregator->slave = NULL; + } +} + +/** + * ad_initialize_port - initialize a given port's parameters + * @aggregator: the aggregator we're looking at + * @lacp_fast: boolean. whether fast periodic should be used + * + */ +static void ad_initialize_port(struct port *port, int lacp_fast) +{ + if (port) { + port->actor_port_number = 1; + port->actor_port_priority = 0xff; + port->actor_system = null_mac_addr; + port->actor_system_priority = 0xffff; + port->actor_port_aggregator_identifier = 0; + port->ntt = 0; + port->actor_admin_port_key = 1; + port->actor_oper_port_key = 1; + port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; + port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; + + if (lacp_fast) { + port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; + } + + port->partner_admin_system = null_mac_addr; + port->partner_oper_system = null_mac_addr; + port->partner_admin_system_priority = 0xffff; + port->partner_oper_system_priority = 0xffff; + port->partner_admin_key = 1; + port->partner_oper_key = 1; + port->partner_admin_port_number = 1; + port->partner_oper_port_number = 1; + port->partner_admin_port_priority = 0xff; + port->partner_oper_port_priority = 0xff; + port->partner_admin_port_state = 1; + port->partner_oper_port_state = 1; + port->is_enabled = 1; + // ****** private parameters ****** + port->sm_vars = 0x3; + port->sm_rx_state = 0; + port->sm_rx_timer_counter = 0; + port->sm_periodic_state = 0; + port->sm_periodic_timer_counter = 0; + port->sm_mux_state = 0; + port->sm_mux_timer_counter = 0; + port->sm_tx_state = 0; + port->sm_tx_timer_counter = 0; + port->slave = NULL; + port->aggregator = NULL; + port->next_port_in_aggregator = NULL; + port->transaction_id = 0; + + ad_initialize_lacpdu(&(port->lacpdu)); + } +} + +/** + * ad_enable_collecting_distributing - enable a port's transmit/receive + * @port: the port we're looking at + * + * Enable @port if it's in an active aggregator + */ +static void ad_enable_collecting_distributing(struct port *port) +{ + if (port->aggregator->is_active) { + BOND_PRINT_DBG(("Enabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier)); + __enable_port(port); + } +} + +/** + * ad_disable_collecting_distributing - disable a port's transmit/receive + * @port: the port we're looking at + * + */ +static void ad_disable_collecting_distributing(struct port *port) +{ + if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) { + BOND_PRINT_DBG(("Disabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier)); + __disable_port(port); + } +} + +#if 0 +/** + * ad_marker_info_send - send a marker information frame + * @port: the port we're looking at + * + * This function does nothing since we decided not to implement send and handle + * response for marker PDU's, in this stage, but only to respond to marker + * information. + */ +static void ad_marker_info_send(struct port *port) +{ + struct marker marker; + u16 index; + + // fill the marker PDU with the appropriate values + marker.subtype = 0x02; + marker.version_number = 0x01; + marker.tlv_type = AD_MARKER_INFORMATION_SUBTYPE; + marker.marker_length = 0x16; + // convert requester_port to Big Endian + marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8)); + marker.requester_system = port->actor_system; + // convert requester_port(u32) to Big Endian + marker.requester_transaction_id = (((++port->transaction_id & 0xFF) << 24) |((port->transaction_id & 0xFF00) << 8) |((port->transaction_id & 0xFF0000) >> 8) |((port->transaction_id & 0xFF000000) >> 24)); + marker.pad = 0; + marker.tlv_type_terminator = 0x00; + marker.terminator_length = 0x00; + for (index=0; index<90; index++) { + marker.reserved_90[index]=0; + } + + // send the marker information + if (ad_marker_send(port, &marker) >= 0) { + BOND_PRINT_DBG(("Sent Marker Information on port %d", port->actor_port_number)); + } +} +#endif + +/** + * ad_marker_info_received - handle receive of a Marker information frame + * @marker_info: Marker info received + * @port: the port we're looking at + * + */ +static void ad_marker_info_received(struct marker *marker_info,struct port *port) +{ + struct marker marker; + + // copy the received marker data to the response marker + //marker = *marker_info; + memcpy(&marker, marker_info, sizeof(struct marker)); + // change the marker subtype to marker response + marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE; + // send the marker response + + if (ad_marker_send(port, &marker) >= 0) { + BOND_PRINT_DBG(("Sent Marker Response on port %d", port->actor_port_number)); + } +} + +/** + * ad_marker_response_received - handle receive of a marker response frame + * @marker: marker PDU received + * @port: the port we're looking at + * + * This function does nothing since we decided not to implement send and handle + * response for marker PDU's, in this stage, but only to respond to marker + * information. + */ +static void ad_marker_response_received(struct marker *marker, struct port *port) +{ + marker=NULL; // just to satisfy the compiler + port=NULL; // just to satisfy the compiler + // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW +} + +/** + * ad_initialize_lacpdu - initialize a given lacpdu structure + * @lacpdu: lacpdu structure to initialize + * + */ +static void ad_initialize_lacpdu(struct lacpdu *lacpdu) +{ + u16 index; + + // initialize lacpdu data + lacpdu->subtype = 0x01; + lacpdu->version_number = 0x01; + lacpdu->tlv_type_actor_info = 0x01; + lacpdu->actor_information_length = 0x14; + // lacpdu->actor_system_priority updated on send + // lacpdu->actor_system updated on send + // lacpdu->actor_key updated on send + // lacpdu->actor_port_priority updated on send + // lacpdu->actor_port updated on send + // lacpdu->actor_state updated on send + lacpdu->tlv_type_partner_info = 0x02; + lacpdu->partner_information_length = 0x14; + for (index=0; index<=2; index++) { + lacpdu->reserved_3_1[index]=0; + } + // lacpdu->partner_system_priority updated on send + // lacpdu->partner_system updated on send + // lacpdu->partner_key updated on send + // lacpdu->partner_port_priority updated on send + // lacpdu->partner_port updated on send + // lacpdu->partner_state updated on send + for (index=0; index<=2; index++) { + lacpdu->reserved_3_2[index]=0; + } + lacpdu->tlv_type_collector_info = 0x03; + lacpdu->collector_information_length= 0x10; + lacpdu->collector_max_delay = AD_COLLECTOR_MAX_DELAY; + for (index=0; index<=11; index++) { + lacpdu->reserved_12[index]=0; + } + lacpdu->tlv_type_terminator = 0x00; + lacpdu->terminator_length = 0; + for (index=0; index<=49; index++) { + lacpdu->reserved_50[index]=0; + } +} + +////////////////////////////////////////////////////////////////////////////////////// +// ================= AD exported functions to the main bonding code ================== +////////////////////////////////////////////////////////////////////////////////////// + +// Check aggregators status in team every T seconds +#define AD_AGGREGATOR_SELECTION_TIMER 8 + +static u16 aggregator_identifier; + +/** + * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures + * @bond: bonding struct to work on + * @tick_resolution: tick duration (millisecond resolution) + * @lacp_fast: boolean. whether fast periodic should be used + * + * Can be called only after the mac address of the bond is set. + */ +void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast) +{ + // check that the bond is not initialized yet + if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->device->dev_addr))) { + + aggregator_identifier = 0; + + BOND_AD_INFO(bond).lacp_fast = lacp_fast; + BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; + BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->device->dev_addr); + + // initialize how many times this module is called in one second(should be about every 100ms) + ad_ticks_per_sec = tick_resolution; + + // initialize the aggregator selection timer(to activate an aggregation selection after initialize) + BOND_AD_INFO(bond).agg_select_timer = (AD_AGGREGATOR_SELECTION_TIMER * ad_ticks_per_sec); + BOND_AD_INFO(bond).agg_select_mode = AD_BANDWIDTH; + } +} + +/** + * bond_3ad_bind_slave - initialize a slave's port + * @slave: slave struct to work on + * + * Returns: 0 on success + * < 0 on error + */ +int bond_3ad_bind_slave(struct slave *slave) +{ + struct bonding *bond = bond_get_bond_by_slave(slave); + struct port *port; + struct aggregator *aggregator; + + if (bond == NULL) { + printk(KERN_CRIT "The slave %s is not attached to its bond\n", slave->dev->name); + return -1; + } + + //check that the slave has not been intialized yet. + if (SLAVE_AD_INFO(slave).port.slave != slave) { + + // port initialization + port = &(SLAVE_AD_INFO(slave).port); + + ad_initialize_port(port, BOND_AD_INFO(bond).lacp_fast); + + port->slave = slave; + port->actor_port_number = SLAVE_AD_INFO(slave).id; + // key is determined according to the link speed, duplex and user key(which is yet not supported) + // ------------------------------------------------------------ + // Port key : | User key | Speed |Duplex| + // ------------------------------------------------------------ + // 16 6 1 0 + port->actor_admin_port_key = 0; // initialize this parameter + port->actor_admin_port_key |= __get_duplex(port); + port->actor_admin_port_key |= (__get_link_speed(port) << 1); + port->actor_oper_port_key = port->actor_admin_port_key; + // if the port is not full duplex, then the port should be not lacp Enabled + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { + port->sm_vars &= ~AD_PORT_LACP_ENABLED; + } + // actor system is the bond's system + port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; + // tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) + port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; + port->aggregator = NULL; + port->next_port_in_aggregator = NULL; + + __disable_port(port); + __initialize_port_locks(port); + + + // aggregator initialization + aggregator = &(SLAVE_AD_INFO(slave).aggregator); + + ad_initialize_agg(aggregator); + + aggregator->aggregator_mac_address = *((struct mac_addr *)bond->device->dev_addr); + aggregator->aggregator_identifier = (++aggregator_identifier); + aggregator->slave = slave; + aggregator->is_active = 0; + aggregator->num_of_ports = 0; + } + + return 0; +} + +/** + * bond_3ad_unbind_slave - deinitialize a slave's port + * @slave: slave struct to work on + * + * Search for the aggregator that is related to this port, remove the + * aggregator and assign another aggregator for other port related to it + * (if any), and remove the port. + */ +void bond_3ad_unbind_slave(struct slave *slave) +{ + struct port *port, *prev_port, *temp_port; + struct aggregator *aggregator, *new_aggregator, *temp_aggregator; + int select_new_active_agg = 0; + + // find the aggregator related to this slave + aggregator = &(SLAVE_AD_INFO(slave).aggregator); + + // find the port related to this slave + port = &(SLAVE_AD_INFO(slave).port); + + // if slave is null, the whole port is not initialized + if (!port->slave) { + printk(KERN_WARNING "bonding: Trying to unbind an uninitialized port on %s\n", slave->dev->name); + return; + } + + BOND_PRINT_DBG(("Unbinding Link Aggregation Group %d", aggregator->aggregator_identifier)); + + /* Tell the partner that this port is not suitable for aggregation */ + port->actor_oper_port_state &= ~AD_STATE_AGGREGATION; + __update_lacpdu_from_port(port); + ad_lacpdu_send(port); + + // check if this aggregator is occupied + if (aggregator->lag_ports) { + // check if there are other ports related to this aggregator except + // the port related to this slave(thats ensure us that there is a + // reason to search for new aggregator, and that we will find one + if ((aggregator->lag_ports != port) || (aggregator->lag_ports->next_port_in_aggregator)) { + // find new aggregator for the related port(s) + new_aggregator = __get_first_agg(port); + for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) { + // if the new aggregator is empty, or it connected to to our port only + if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) { + break; + } + } + // if new aggregator found, copy the aggregator's parameters + // and connect the related lag_ports to the new aggregator + if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) { + BOND_PRINT_DBG(("Some port(s) related to LAG %d - replaceing with LAG %d", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier)); + + if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) { + printk(KERN_INFO "bonding: Removing an active aggregator\n"); + // select new active aggregator + select_new_active_agg = 1; + } + + new_aggregator->is_individual = aggregator->is_individual; + new_aggregator->actor_admin_aggregator_key = aggregator->actor_admin_aggregator_key; + new_aggregator->actor_oper_aggregator_key = aggregator->actor_oper_aggregator_key; + new_aggregator->partner_system = aggregator->partner_system; + new_aggregator->partner_system_priority = aggregator->partner_system_priority; + new_aggregator->partner_oper_aggregator_key = aggregator->partner_oper_aggregator_key; + new_aggregator->receive_state = aggregator->receive_state; + new_aggregator->transmit_state = aggregator->transmit_state; + new_aggregator->lag_ports = aggregator->lag_ports; + new_aggregator->is_active = aggregator->is_active; + new_aggregator->num_of_ports = aggregator->num_of_ports; + + // update the information that is written on the ports about the aggregator + for (temp_port=aggregator->lag_ports; temp_port; temp_port=temp_port->next_port_in_aggregator) { + temp_port->aggregator=new_aggregator; + temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; + } + + // clear the aggregator + ad_clear_agg(aggregator); + + if (select_new_active_agg) { + ad_agg_selection_logic(__get_first_agg(port)); + } + } else { + printk(KERN_WARNING "bonding: Warning: unbinding aggregator, " + "and could not find a new aggregator for its ports\n"); + } + } else { // in case that the only port related to this aggregator is the one we want to remove + select_new_active_agg = aggregator->is_active; + // clear the aggregator + ad_clear_agg(aggregator); + if (select_new_active_agg) { + printk(KERN_INFO "Removing an active aggregator\n"); + // select new active aggregator + ad_agg_selection_logic(__get_first_agg(port)); + } + } + } + + BOND_PRINT_DBG(("Unbinding port %d", port->actor_port_number)); + // find the aggregator that this port is connected to + temp_aggregator = __get_first_agg(port); + for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) { + prev_port = NULL; + // search the port in the aggregator's related ports + for (temp_port=temp_aggregator->lag_ports; temp_port; prev_port=temp_port, temp_port=temp_port->next_port_in_aggregator) { + if (temp_port == port) { // the aggregator found - detach the port from this aggregator + if (prev_port) { + prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator; + } else { + temp_aggregator->lag_ports = temp_port->next_port_in_aggregator; + } + temp_aggregator->num_of_ports--; + if (temp_aggregator->num_of_ports==0) { + select_new_active_agg = temp_aggregator->is_active; + // clear the aggregator + ad_clear_agg(temp_aggregator); + if (select_new_active_agg) { + printk(KERN_INFO "Removing an active aggregator\n"); + // select new active aggregator + ad_agg_selection_logic(__get_first_agg(port)); + } + } + break; + } + } + } + port->slave=NULL; +} + +/** + * bond_3ad_state_machine_handler - handle state machines timeout + * @bond: bonding struct to work on + * + * The state machine handling concept in this module is to check every tick + * which state machine should operate any function. The execution order is + * round robin, so when we have an interaction between state machines, the + * reply of one to each other might be delayed until next tick. + * + * This function also complete the initialization when the agg_select_timer + * times out, and it selects an aggregator for the ports that are yet not + * related to any aggregator, and selects the active aggregator for a bond. + */ +void bond_3ad_state_machine_handler(struct bonding *bond) +{ + struct port *port; + struct aggregator *aggregator; + + read_lock(&bond->lock); + + //check if there are any slaves + if (bond->next == (struct slave *)bond) { + goto end; + } + + if ((bond->device->flags & IFF_UP) != IFF_UP) { + goto end; + } + + // check if agg_select_timer timer after initialize is timed out + if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { + // select the active aggregator for the bond + if ((port = __get_first_port(bond))) { + if (!port->slave) { + printk(KERN_WARNING "bonding: Warning: bond's first port is uninitialized\n"); + goto end; + } + + aggregator = __get_first_agg(port); + ad_agg_selection_logic(aggregator); + } + } + + // for each port run the state machines + for (port = __get_first_port(bond); port; port = __get_next_port(port)) { + if (!port->slave) { + printk(KERN_WARNING "bonding: Warning: Found an uninitialized port\n"); + goto end; + } + + ad_rx_machine(NULL, port); + ad_periodic_machine(port); + ad_port_selection_logic(port); + ad_mux_machine(port); + ad_tx_machine(port); + + // turn off the BEGIN bit, since we already handled it + if (port->sm_vars & AD_PORT_BEGIN) { + port->sm_vars &= ~AD_PORT_BEGIN; + } + } + +end: + read_unlock(&bond->lock); + + + if ((bond->device->flags & IFF_UP) == IFF_UP) { + /* re-arm the timer */ + mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + (AD_TIMER_INTERVAL * HZ / 1000)); + } +} + +/** + * bond_3ad_rx_indication - handle a received frame + * @lacpdu: received lacpdu + * @slave: slave struct to work on + * @length: length of the data received + * + * It is assumed that frames that were sent on this NIC don't returned as new + * received frames (loopback). Since only the payload is given to this + * function, it check for loopback. + */ +void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length) +{ + struct port *port; + + if (length >= sizeof(struct lacpdu)) { + + port = &(SLAVE_AD_INFO(slave).port); + + if (!port->slave) { + printk(KERN_WARNING "bonding: Warning: port of slave %s is uninitialized\n", slave->dev->name); + return; + } + + switch (lacpdu->subtype) { + case AD_TYPE_LACPDU: + __ntohs_lacpdu(lacpdu); + BOND_PRINT_DBG(("Received LACPDU on port %d", port->actor_port_number)); + ad_rx_machine(lacpdu, port); + break; + + case AD_TYPE_MARKER: + // No need to convert fields to Little Endian since we don't use the marker's fields. + + switch (((struct marker *)lacpdu)->tlv_type) { + case AD_MARKER_INFORMATION_SUBTYPE: + BOND_PRINT_DBG(("Received Marker Information on port %d", port->actor_port_number)); + ad_marker_info_received((struct marker *)lacpdu, port); + break; + + case AD_MARKER_RESPONSE_SUBTYPE: + BOND_PRINT_DBG(("Received Marker Response on port %d", port->actor_port_number)); + ad_marker_response_received((struct marker *)lacpdu, port); + break; + + default: + BOND_PRINT_DBG(("Received an unknown Marker subtype on slot %d", port->actor_port_number)); + } + } + } +} + +/** + * bond_3ad_adapter_speed_changed - handle a slave's speed change indication + * @slave: slave struct to work on + * + * Handle reselection of aggregator (if needed) for this port. + */ +void bond_3ad_adapter_speed_changed(struct slave *slave) +{ + struct port *port; + + port = &(SLAVE_AD_INFO(slave).port); + + // if slave is null, the whole port is not initialized + if (!port->slave) { + printk(KERN_WARNING "bonding: Warning: speed changed for uninitialized port on %s\n", + slave->dev->name); + return; + } + + port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; + port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); + BOND_PRINT_DBG(("Port %d changed speed", port->actor_port_number)); + // there is no need to reselect a new aggregator, just signal the + // state machines to reinitialize + port->sm_vars |= AD_PORT_BEGIN; +} + +/** + * bond_3ad_adapter_duplex_changed - handle a slave's duplex change indication + * @slave: slave struct to work on + * + * Handle reselection of aggregator (if needed) for this port. + */ +void bond_3ad_adapter_duplex_changed(struct slave *slave) +{ + struct port *port; + + port=&(SLAVE_AD_INFO(slave).port); + + // if slave is null, the whole port is not initialized + if (!port->slave) { + printk(KERN_WARNING "bonding: Warning: duplex changed for uninitialized port on %s\n", + slave->dev->name); + return; + } + + port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; + port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); + BOND_PRINT_DBG(("Port %d changed duplex", port->actor_port_number)); + // there is no need to reselect a new aggregator, just signal the + // state machines to reinitialize + port->sm_vars |= AD_PORT_BEGIN; +} + +/** + * bond_3ad_handle_link_change - handle a slave's link status change indication + * @slave: slave struct to work on + * @status: whether the link is now up or down + * + * Handle reselection of aggregator (if needed) for this port. + */ +void bond_3ad_handle_link_change(struct slave *slave, char link) +{ + struct port *port; + + port = &(SLAVE_AD_INFO(slave).port); + + // if slave is null, the whole port is not initialized + if (!port->slave) { +#ifdef BONDING_DEBUG + printk(KERN_WARNING "bonding: Warning: link status changed for uninitialized port on %s\n", + slave->dev->name); +#endif + return; + } + + // on link down we are zeroing duplex and speed since some of the adaptors(ce1000.lan) report full duplex/speed instead of N/A(duplex) / 0(speed) + // on link up we are forcing recheck on the duplex and speed since some of he adaptors(ce1000.lan) report + if (link == BOND_LINK_UP) { + port->is_enabled = 1; + port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; + port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); + port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; + port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); + } else { + /* link has failed */ + port->is_enabled = 0; + port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; + port->actor_oper_port_key= (port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS); + } + //BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN"))); + // there is no need to reselect a new aggregator, just signal the + // state machines to reinitialize + port->sm_vars |= AD_PORT_BEGIN; +} + +/** + * bond_3ad_get_active_agg_info - get information of the active aggregator + * @bond: bonding struct to work on + * @ad_info: ad_info struct to fill with the bond's info + * + * Returns: 0 on success + * < 0 on error + */ +int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) +{ + struct aggregator *aggregator = NULL; + struct port *port; + + for (port = __get_first_port(bond); port; port = __get_next_port(port)) { + if (port->aggregator && port->aggregator->is_active) { + aggregator = port->aggregator; + break; + } + } + + if (aggregator) { + ad_info->aggregator_id = aggregator->aggregator_identifier; + ad_info->ports = aggregator->num_of_ports; + ad_info->actor_key = aggregator->actor_oper_aggregator_key; + ad_info->partner_key = aggregator->partner_oper_aggregator_key; + memcpy(ad_info->partner_system, aggregator->partner_system.mac_addr_value, ETH_ALEN); + return 0; + } + + return -1; +} + +int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) +{ + slave_t *slave, *start_at; + struct bonding *bond = (struct bonding *) dev->priv; + struct ethhdr *data = (struct ethhdr *)skb->data; + int slave_agg_no; + int slaves_in_agg; + int agg_id; + struct ad_info ad_info; + + if (!IS_UP(dev)) { /* bond down */ + dev_kfree_skb(skb); + return 0; + } + + if (bond == NULL) { + printk(KERN_CRIT "bonding: Error: bond is NULL on device %s\n", dev->name); + dev_kfree_skb(skb); + return 0; + } + + read_lock(&bond->lock); + slave = bond->prev; + + /* check if bond is empty */ + if ((slave == (struct slave *) bond) || (bond->slave_cnt == 0)) { + printk(KERN_DEBUG "ERROR: bond is empty\n"); + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + if (bond_3ad_get_active_agg_info(bond, &ad_info)) { + printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n"); + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + slaves_in_agg = ad_info.ports; + agg_id = ad_info.aggregator_id; + + if (slaves_in_agg == 0) { + /*the aggregator is empty*/ + printk(KERN_DEBUG "ERROR: active aggregator is empty\n"); + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + /* we're at the root, get the first slave */ + if ((slave == NULL) || (slave->dev == NULL)) { + /* no suitable interface, frame not sent */ + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + slave_agg_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % slaves_in_agg; + while (slave != (slave_t *)bond) { + struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; + + if (agg && (agg->aggregator_identifier == agg_id)) { + slave_agg_no--; + if (slave_agg_no < 0) { + break; + } + } + + slave = slave->prev; + if (slave == NULL) { + printk(KERN_ERR "bonding: Error: slave is NULL\n"); + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + } + + if (slave == (slave_t *)bond) { + printk(KERN_ERR "bonding: Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id); + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + start_at = slave; + + do { + int slave_agg_id = 0; + struct aggregator *agg; + + if (slave == NULL) { + printk(KERN_ERR "bonding: Error: slave is NULL\n"); + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + agg = SLAVE_AD_INFO(slave).port.aggregator; + + if (agg) { + slave_agg_id = agg->aggregator_identifier; + } + + if (SLAVE_IS_OK(slave) && + agg && (slave_agg_id == agg_id)) { + skb->dev = slave->dev; + skb->priority = 1; + dev_queue_xmit(skb); + read_unlock(&bond->lock); + return 0; + } + } while ((slave = slave->next) != start_at); + + /* no suitable interface, frame not sent */ + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; +} + +int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype) +{ + struct bonding *bond = (struct bonding *)dev->priv; + struct slave *slave = NULL; + int ret = NET_RX_DROP; + + if (!(dev->flags & IFF_MASTER)) { + goto out; + } + + read_lock(&bond->lock); + slave = bond_get_slave_by_dev((struct bonding *)dev->priv, + skb->real_dev); + if (slave == NULL) { + goto out_unlock; + } + + bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); + + ret = NET_RX_SUCCESS; + +out_unlock: + read_unlock(&bond->lock); +out: + dev_kfree_skb(skb); + + return ret; +} + diff -urN linux-2.4.21/drivers/net/bonding/bond_3ad.h linux-2.4.22/drivers/net/bonding/bond_3ad.h --- linux-2.4.21/drivers/net/bonding/bond_3ad.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/bonding/bond_3ad.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,298 @@ +/* + * Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * + * Changes: + * + * 2003/05/01 - Tsippy Mendelson and + * Amir Noam + * - Added support for lacp_rate module param. + * + * 2003/05/01 - Shmulik Hen + * - Renamed bond_3ad_link_status_changed() to + * bond_3ad_handle_link_change() for compatibility with TLB. + */ + +#ifndef __BOND_3AD_H__ +#define __BOND_3AD_H__ + +#include +#include +#include + +// General definitions +#define BOND_ETH_P_LACPDU 0x8809 +#define PKT_TYPE_LACPDU __constant_htons(BOND_ETH_P_LACPDU) +#define AD_TIMER_INTERVAL 100 /*msec*/ + +#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02} +#define AD_MULTICAST_LACPDU_ADDR {MULTICAST_LACPDU_ADDR} + +#define AD_LACP_SLOW 0 +#define AD_LACP_FAST 1 + +typedef struct mac_addr { + u8 mac_addr_value[ETH_ALEN]; +} mac_addr_t; + +typedef enum { + AD_BANDWIDTH = 0, + AD_COUNT +} agg_selection_t; + +// rx machine states(43.4.11 in the 802.3ad standard) +typedef enum { + AD_RX_DUMMY, + AD_RX_INITIALIZE, // rx Machine + AD_RX_PORT_DISABLED, // rx Machine + AD_RX_LACP_DISABLED, // rx Machine + AD_RX_EXPIRED, // rx Machine + AD_RX_DEFAULTED, // rx Machine + AD_RX_CURRENT // rx Machine +} rx_states_t; + +// periodic machine states(43.4.12 in the 802.3ad standard) +typedef enum { + AD_PERIODIC_DUMMY, + AD_NO_PERIODIC, // periodic machine + AD_FAST_PERIODIC, // periodic machine + AD_SLOW_PERIODIC, // periodic machine + AD_PERIODIC_TX // periodic machine +} periodic_states_t; + +// mux machine states(43.4.13 in the 802.3ad standard) +typedef enum { + AD_MUX_DUMMY, + AD_MUX_DETACHED, // mux machine + AD_MUX_WAITING, // mux machine + AD_MUX_ATTACHED, // mux machine + AD_MUX_COLLECTING_DISTRIBUTING // mux machine +} mux_states_t; + +// tx machine states(43.4.15 in the 802.3ad standard) +typedef enum { + AD_TX_DUMMY, + AD_TRANSMIT // tx Machine +} tx_states_t; + +// rx indication types +typedef enum { + AD_TYPE_LACPDU = 1, // type lacpdu + AD_TYPE_MARKER // type marker +} pdu_type_t; + +// rx marker indication types +typedef enum { + AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype + AD_MARKER_RESPONSE_SUBTYPE // marker response subtype +} marker_subtype_t; + +// timers types(43.4.9 in the 802.3ad standard) +typedef enum { + AD_CURRENT_WHILE_TIMER, + AD_ACTOR_CHURN_TIMER, + AD_PERIODIC_TIMER, + AD_PARTNER_CHURN_TIMER, + AD_WAIT_WHILE_TIMER +} ad_timers_t; + +#pragma pack(1) + +typedef struct ad_header { + struct mac_addr destination_address; + struct mac_addr source_address; + u16 length_type; +} ad_header_t; + +// Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) +typedef struct lacpdu { + u8 subtype; // = LACP(= 0x01) + u8 version_number; + u8 tlv_type_actor_info; // = actor information(type/length/value) + u8 actor_information_length; // = 20 + u16 actor_system_priority; + struct mac_addr actor_system; + u16 actor_key; + u16 actor_port_priority; + u16 actor_port; + u8 actor_state; + u8 reserved_3_1[3]; // = 0 + u8 tlv_type_partner_info; // = partner information + u8 partner_information_length; // = 20 + u16 partner_system_priority; + struct mac_addr partner_system; + u16 partner_key; + u16 partner_port_priority; + u16 partner_port; + u8 partner_state; + u8 reserved_3_2[3]; // = 0 + u8 tlv_type_collector_info; // = collector information + u8 collector_information_length; // = 16 + u16 collector_max_delay; + u8 reserved_12[12]; + u8 tlv_type_terminator; // = terminator + u8 terminator_length; // = 0 + u8 reserved_50[50]; // = 0 +} lacpdu_t; + +typedef struct lacpdu_header { + struct ad_header ad_header; + struct lacpdu lacpdu; +} lacpdu_header_t; + +// Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) +typedef struct marker { + u8 subtype; // = 0x02 (marker PDU) + u8 version_number; // = 0x01 + u8 tlv_type; // = 0x01 (marker information) + // = 0x02 (marker response information) + u8 marker_length; // = 0x16 + u16 requester_port; // The number assigned to the port by the requester + struct mac_addr requester_system; // The requester's system id + u32 requester_transaction_id; // The transaction id allocated by the requester, + u16 pad; // = 0 + u8 tlv_type_terminator; // = 0x00 + u8 terminator_length; // = 0x00 + u8 reserved_90[90]; // = 0 +} marker_t; + +typedef struct marker_header { + struct ad_header ad_header; + struct marker marker; +} marker_header_t; + +#pragma pack() + +struct slave; +struct bonding; +struct ad_info; +struct port; + +#ifdef __ia64__ +#pragma pack(8) +#endif + +// aggregator structure(43.4.5 in the 802.3ad standard) +typedef struct aggregator { + struct mac_addr aggregator_mac_address; + u16 aggregator_identifier; + u16 is_individual; // BOOLEAN + u16 actor_admin_aggregator_key; + u16 actor_oper_aggregator_key; + struct mac_addr partner_system; + u16 partner_system_priority; + u16 partner_oper_aggregator_key; + u16 receive_state; // BOOLEAN + u16 transmit_state; // BOOLEAN + struct port *lag_ports; + // ****** PRIVATE PARAMETERS ****** + struct slave *slave; // pointer to the bond slave that this aggregator belongs to + u16 is_active; // BOOLEAN. Indicates if this aggregator is active + u16 num_of_ports; +} aggregator_t; + +// port structure(43.4.6 in the 802.3ad standard) +typedef struct port { + u16 actor_port_number; + u16 actor_port_priority; + struct mac_addr actor_system; // This parameter is added here although it is not specified in the standard, just for simplification + u16 actor_system_priority; // This parameter is added here although it is not specified in the standard, just for simplification + u16 actor_port_aggregator_identifier; + u16 ntt; // BOOLEAN + u16 actor_admin_port_key; + u16 actor_oper_port_key; + u8 actor_admin_port_state; + u8 actor_oper_port_state; + struct mac_addr partner_admin_system; + struct mac_addr partner_oper_system; + u16 partner_admin_system_priority; + u16 partner_oper_system_priority; + u16 partner_admin_key; + u16 partner_oper_key; + u16 partner_admin_port_number; + u16 partner_oper_port_number; + u16 partner_admin_port_priority; + u16 partner_oper_port_priority; + u8 partner_admin_port_state; + u8 partner_oper_port_state; + u16 is_enabled; // BOOLEAN + // ****** PRIVATE PARAMETERS ****** + u16 sm_vars; // all state machines variables for this port + rx_states_t sm_rx_state; // state machine rx state + u16 sm_rx_timer_counter; // state machine rx timer counter + periodic_states_t sm_periodic_state;// state machine periodic state + u16 sm_periodic_timer_counter; // state machine periodic timer counter + mux_states_t sm_mux_state; // state machine mux state + u16 sm_mux_timer_counter; // state machine mux timer counter + tx_states_t sm_tx_state; // state machine tx state + u16 sm_tx_timer_counter; // state machine tx timer counter(allways on - enter to transmit state 3 time per second) + struct slave *slave; // pointer to the bond slave that this port belongs to + struct aggregator *aggregator; // pointer to an aggregator that this port related to + struct port *next_port_in_aggregator; // Next port on the linked list of the parent aggregator + u32 transaction_id; // continuous number for identification of Marker PDU's; + struct lacpdu lacpdu; // the lacpdu that will be sent for this port +} port_t; + +// system structure +typedef struct ad_system { + u16 sys_priority; + struct mac_addr sys_mac_addr; +} ad_system_t; + +#ifdef __ia64__ +#pragma pack() +#endif + +// ================= AD Exported structures to the main bonding code ================== +#define BOND_AD_INFO(bond) ((bond)->ad_info) +#define SLAVE_AD_INFO(slave) ((slave)->ad_info) + +struct ad_bond_info { + ad_system_t system; // 802.3ad system structure + u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes + u32 agg_select_mode; // Mode of selection of active aggregator(bandwidth/count) + int lacp_fast; /* whether fast periodic tx should be + * requested + */ + struct timer_list ad_timer; + struct packet_type ad_pkt_type; +}; + +struct ad_slave_info { + struct aggregator aggregator; // 802.3ad aggregator structure + struct port port; // 802.3ad port structure + spinlock_t rx_machine_lock; // To avoid race condition between callback and receive interrupt + u16 id; +}; + +// ================= AD Exported functions to the main bonding code ================== +void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast); +int bond_3ad_bind_slave(struct slave *slave); +void bond_3ad_unbind_slave(struct slave *slave); +void bond_3ad_state_machine_handler(struct bonding *bond); +void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length); +void bond_3ad_adapter_speed_changed(struct slave *slave); +void bond_3ad_adapter_duplex_changed(struct slave *slave); +void bond_3ad_handle_link_change(struct slave *slave, char link); +int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); +int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); +int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype); +#endif //__BOND_3AD_H__ + diff -urN linux-2.4.21/drivers/net/bonding/bond_alb.c linux-2.4.22/drivers/net/bonding/bond_alb.c --- linux-2.4.21/drivers/net/bonding/bond_alb.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/bonding/bond_alb.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1576 @@ +/* + * Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * + * Changes: + * + * 2003/06/25 - Shmulik Hen + * - Fixed signed/unsigned calculation errors that caused load sharing + * to collapse to one slave under very heavy UDP Tx stress. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bonding.h" +#include "bond_alb.h" + + +#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */ +#define BOND_TLB_REBALANCE_INTERVAL 10 /* in seconds, periodic re-balancing + * used for division - never set + * to zero !!! + */ +#define BOND_ALB_LP_INTERVAL 1 /* in seconds periodic send of + * learning packets to the switch + */ + +#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \ + * ALB_TIMER_TICKS_PER_SEC) + +#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \ + * ALB_TIMER_TICKS_PER_SEC) + +#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table. + * Note that this value MUST NOT be smaller + * because the key hash table BYTE wide ! + */ + + +#define TLB_NULL_INDEX 0xffffffff +#define MAX_LP_RETRY 3 + +/* rlb defs */ +#define RLB_HASH_TABLE_SIZE 256 +#define RLB_NULL_INDEX 0xffffffff +#define RLB_UPDATE_DELAY 2*ALB_TIMER_TICKS_PER_SEC /* 2 seconds */ +#define RLB_ARP_BURST_SIZE 2 +#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb + * rebalance interval (5 min). + */ +/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is + * promiscuous after failover + */ +#define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC + +#pragma pack(1) +struct learning_pkt { + u8 mac_dst[ETH_ALEN]; + u8 mac_src[ETH_ALEN]; + u16 type; + u8 padding[ETH_ZLEN - (2*ETH_ALEN + 2)]; +}; + +struct arp_pkt { + u16 hw_addr_space; + u16 prot_addr_space; + u8 hw_addr_len; + u8 prot_addr_len; + u16 op_code; + u8 mac_src[ETH_ALEN]; /* sender hardware address */ + u32 ip_src; /* sender IP address */ + u8 mac_dst[ETH_ALEN]; /* target hardware address */ + u32 ip_dst; /* target IP address */ +}; +#pragma pack() + +/* Forward declaration */ +static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]); + +static inline u8 +_simple_hash(u8 *hash_start, int hash_size) +{ + int i; + u8 hash = 0; + + for (i=0; iload_history = 1 + entry->tx_bytes / + BOND_TLB_REBALANCE_INTERVAL; + entry->tx_bytes = 0; + } + entry->tx_slave = NULL; + entry->next = TLB_NULL_INDEX; + entry->prev = TLB_NULL_INDEX; +} + +static inline void +tlb_init_slave(struct slave *slave) +{ + struct tlb_slave_info *slave_info = &(SLAVE_TLB_INFO(slave)); + + slave_info->load = 0; + slave_info->head = TLB_NULL_INDEX; +} + +/* Caller must hold bond lock for read */ +static inline void +tlb_clear_slave(struct bonding *bond, struct slave *slave, u8 save_load) +{ + struct tlb_client_info *tx_hash_table = NULL; + u32 index, next_index; + + /* clear slave from tx_hashtbl */ + _lock_tx_hashtbl(bond); + tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; + + if (tx_hash_table) { + index = SLAVE_TLB_INFO(slave).head; + while (index != TLB_NULL_INDEX) { + next_index = tx_hash_table[index].next; + tlb_init_table_entry(bond, index, save_load); + index = next_index; + } + } + _unlock_tx_hashtbl(bond); + + tlb_init_slave(slave); +} + +/* Must be called before starting the monitor timer */ +static int +tlb_initialize(struct bonding *bond) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + int i; + size_t size; + +#if(TLB_HASH_TABLE_SIZE != 256) + /* Key to the hash table is byte wide. Check the size! */ + #error Hash Table size is wrong. +#endif + + spin_lock_init(&(bond_info->tx_hashtbl_lock)); + + _lock_tx_hashtbl(bond); + if (bond_info->tx_hashtbl != NULL) { + printk (KERN_ERR "%s: TLB hash table is not NULL\n", + bond->device->name); + _unlock_tx_hashtbl(bond); + return -1; + } + + size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info); + bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL); + if (bond_info->tx_hashtbl == NULL) { + printk (KERN_ERR "%s: Failed to allocate TLB hash table\n", + bond->device->name); + _unlock_tx_hashtbl(bond); + return -1; + } + + memset(bond_info->tx_hashtbl, 0, size); + for (i=0; itx_hashtbl == NULL) { + _unlock_tx_hashtbl(bond); + return; + } + kfree(bond_info->tx_hashtbl); + bond_info->tx_hashtbl = NULL; + _unlock_tx_hashtbl(bond); +} + +/* Caller must hold bond lock for read */ +static struct slave* +tlb_get_least_loaded_slave(struct bonding *bond) +{ + struct slave *slave; + struct slave *least_loaded; + s64 curr_gap, max_gap; + + /* Find the first enabled slave */ + slave = bond_get_first_slave(bond); + while (slave) { + if (SLAVE_IS_OK(slave)) { + break; + } + slave = bond_get_next_slave(bond, slave); + } + + if (!slave) { + return NULL; + } + + least_loaded = slave; + max_gap = (s64)(slave->speed * 1000000) - + (s64)(SLAVE_TLB_INFO(slave).load * 8); + + /* Find the slave with the largest gap */ + slave = bond_get_next_slave(bond, slave); + while (slave) { + if (SLAVE_IS_OK(slave)) { + curr_gap = (s64)(slave->speed * 1000000) - + (s64)(SLAVE_TLB_INFO(slave).load * 8); + if (max_gap < curr_gap) { + least_loaded = slave; + max_gap = curr_gap; + } + } + slave = bond_get_next_slave(bond, slave); + } + + return least_loaded; +} + +/* Caller must hold bond lock for read */ +struct slave* +tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct tlb_client_info *hash_table = NULL; + struct slave *assigned_slave = NULL; + + _lock_tx_hashtbl(bond); + + hash_table = bond_info->tx_hashtbl; + if (hash_table == NULL) { + printk (KERN_ERR "%s: TLB hash table is NULL\n", + bond->device->name); + _unlock_tx_hashtbl(bond); + return NULL; + } + + assigned_slave = hash_table[hash_index].tx_slave; + if (!assigned_slave) { + assigned_slave = tlb_get_least_loaded_slave(bond); + + if (assigned_slave) { + struct tlb_slave_info *slave_info = + &(SLAVE_TLB_INFO(assigned_slave)); + u32 next_index = slave_info->head; + + hash_table[hash_index].tx_slave = assigned_slave; + hash_table[hash_index].next = next_index; + hash_table[hash_index].prev = TLB_NULL_INDEX; + + if (next_index != TLB_NULL_INDEX) { + hash_table[next_index].prev = hash_index; + } + + slave_info->head = hash_index; + slave_info->load += + hash_table[hash_index].load_history; + } + } + + if (assigned_slave) { + hash_table[hash_index].tx_bytes += skb_len; + } + + _unlock_tx_hashtbl(bond); + + return assigned_slave; +} + +/*********************** rlb specific functions ***************************/ +static inline void +_lock_rx_hashtbl(struct bonding *bond) +{ + spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); +} + +static inline void +_unlock_rx_hashtbl(struct bonding *bond) +{ + spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); +} + +/* when an ARP REPLY is received from a client update its info + * in the rx_hashtbl + */ +static void +rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) +{ + u32 hash_index; + struct rlb_client_info *client_info = NULL; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + + _lock_rx_hashtbl(bond); + + if (bond_info->rx_hashtbl == NULL) { + _unlock_rx_hashtbl(bond); + return; + } + hash_index = _simple_hash((u8*)&(arp->ip_src), 4); + client_info = &(bond_info->rx_hashtbl[hash_index]); + + if ((client_info->assigned) && + (client_info->ip_src == arp->ip_dst) && + (client_info->ip_dst == arp->ip_src)) { + + /* update the clients MAC address */ + memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN); + client_info->ntt = 1; + bond_info->rx_ntt = 1; + } + + _unlock_rx_hashtbl(bond); +} + +static int +rlb_arp_recv(struct sk_buff *skb, + struct net_device *dev, + struct packet_type* ptype) +{ + struct bonding *bond = (struct bonding *)dev->priv; + int ret = NET_RX_DROP; + struct arp_pkt *arp = (struct arp_pkt *)skb->data; + + if (!(dev->flags & IFF_MASTER)) { + goto out; + } + + if (!arp) { + printk(KERN_ERR "Packet has no ARP data\n"); + goto out; + } + + if (skb->len < sizeof(struct arp_pkt)) { + printk(KERN_ERR "Packet is too small to be an ARP\n"); + goto out; + } + + if (arp->op_code == htons(ARPOP_REPLY)) { + /* update rx hash table for this ARP */ + rlb_update_entry_from_arp(bond, arp); + BOND_PRINT_DBG(("Server received an ARP Reply from client")); + } + + ret = NET_RX_SUCCESS; + +out: + dev_kfree_skb(skb); + + return ret; +} + +/* Caller must hold bond lock for read */ +static struct slave* +rlb_next_rx_slave(struct bonding *bond) +{ + struct slave *rx_slave = NULL, *slave = NULL; + unsigned int i = 0; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + + slave = bond_info->next_rx_slave; + if (slave == NULL) { + slave = bond->next; + } + + /* this loop uses the circular linked list property of the + * slave's list to go through all slaves + */ + for (i = 0; i < bond->slave_cnt; i++, slave = slave->next) { + + if (SLAVE_IS_OK(slave)) { + if (!rx_slave) { + rx_slave = slave; + } + else if (slave->speed > rx_slave->speed) { + rx_slave = slave; + } + } + } + + if (rx_slave) { + bond_info->next_rx_slave = rx_slave->next; + } + + return rx_slave; +} + +/* teach the switch the mac of a disabled slave + * on the primary for fault tolerance + * + * Caller must hold bond->ptrlock for write or bond lock for write + */ +static void +rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[]) +{ + if (!bond->current_slave) { + return; + } + if (!bond->alb_info.primary_is_promisc) { + bond->alb_info.primary_is_promisc = 1; + dev_set_promiscuity(bond->current_slave->dev, 1); + } + bond->alb_info.rlb_promisc_timeout_counter = 0; + + alb_send_learning_packets(bond->current_slave, addr); +} + +/* slave being removed should not be active at this point + * + * Caller must hold bond lock for read + */ +static void +rlb_clear_slave(struct bonding *bond, struct slave *slave) +{ + struct rlb_client_info *rx_hash_table = NULL; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u32 index, next_index; + + /* clear slave from rx_hashtbl */ + _lock_rx_hashtbl(bond); + rx_hash_table = bond_info->rx_hashtbl; + + if (rx_hash_table == NULL) { + _unlock_rx_hashtbl(bond); + return; + } + + index = bond_info->rx_hashtbl_head; + for (; index != RLB_NULL_INDEX; index = next_index) { + next_index = rx_hash_table[index].next; + + if (rx_hash_table[index].slave == slave) { + struct slave *assigned_slave = rlb_next_rx_slave(bond); + + if (assigned_slave) { + rx_hash_table[index].slave = assigned_slave; + if (memcmp(rx_hash_table[index].mac_dst, + mac_bcast, ETH_ALEN)) { + bond_info->rx_hashtbl[index].ntt = 1; + bond_info->rx_ntt = 1; + /* A slave has been removed from the + * table because it is either disabled + * or being released. We must retry the + * update to avoid clients from not + * being updated & disconnecting when + * there is stress + */ + bond_info->rlb_update_retry_counter = + RLB_UPDATE_RETRY; + } + } else { /* there is no active slave */ + rx_hash_table[index].slave = NULL; + } + } + } + + _unlock_rx_hashtbl(bond); + + write_lock(&bond->ptrlock); + if (slave != bond->current_slave) { + rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr); + } + write_unlock(&bond->ptrlock); +} + +static void +rlb_update_client(struct rlb_client_info *client_info) +{ + int i = 0; + + if (client_info->slave == NULL) { + return; + } + + for (i=0; iip_dst, + client_info->slave->dev, + client_info->ip_src, + client_info->mac_dst, + client_info->slave->dev->dev_addr, + client_info->mac_dst); + } +} + +/* sends ARP REPLIES that update the clients that need updating */ +static void +rlb_update_rx_clients(struct bonding *bond) +{ + u32 hash_index; + struct rlb_client_info *client_info = NULL; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + + _lock_rx_hashtbl(bond); + + if (bond_info->rx_hashtbl == NULL) { + _unlock_rx_hashtbl(bond); + return; + } + + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { + client_info = &(bond_info->rx_hashtbl[hash_index]); + if (client_info->ntt) { + rlb_update_client(client_info); + if (bond_info->rlb_update_retry_counter == 0) { + client_info->ntt = 0; + } + } + } + + /* do not update the entries again untill this counter is zero so that + * not to confuse the clients. + */ + bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY; + + _unlock_rx_hashtbl(bond); +} + +/* The slave was assigned a new mac address - update the clients */ +static void +rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave) +{ + u32 hash_index; + u8 ntt = 0; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + struct rlb_client_info* client_info = NULL; + + _lock_rx_hashtbl(bond); + + if (bond_info->rx_hashtbl == NULL) { + _unlock_rx_hashtbl(bond); + return; + } + + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { + client_info = &(bond_info->rx_hashtbl[hash_index]); + + if ((client_info->slave == slave) && + memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) { + client_info->ntt = 1; + ntt = 1; + } + } + + // update the team's flag only after the whole iteration + if (ntt) { + bond_info->rx_ntt = 1; + //fasten the change + bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY; + } + + _unlock_rx_hashtbl(bond); +} + +/* mark all clients using src_ip to be updated */ +static void +rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip) +{ + u32 hash_index; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + struct rlb_client_info *client_info = NULL; + + _lock_rx_hashtbl(bond); + + if (bond_info->rx_hashtbl == NULL) { + _unlock_rx_hashtbl(bond); + return; + } + + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { + client_info = &(bond_info->rx_hashtbl[hash_index]); + + if (!client_info->slave) { + printk(KERN_ERR "Bonding: Error: found a client with no" + " channel in the client's hash table\n"); + continue; + } + /*update all clients using this src_ip, that are not assigned + * to the team's address (current_slave) and have a known + * unicast mac address. + */ + if ((client_info->ip_src == src_ip) && + memcmp(client_info->slave->dev->dev_addr, + bond->device->dev_addr, ETH_ALEN) && + memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) { + client_info->ntt = 1; + bond_info->rx_ntt = 1; + } + } + + _unlock_rx_hashtbl(bond); +} + +/* Caller must hold both bond and ptr locks for read */ +struct slave* +rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct rlb_client_info *client_info = NULL; + u32 hash_index = 0; + struct slave *assigned_slave = NULL; + u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + _lock_rx_hashtbl(bond); + + if (bond_info->rx_hashtbl == NULL) { + _unlock_rx_hashtbl(bond); + return NULL; + } + + hash_index = _simple_hash((u8 *)&arp->ip_dst, 4); + client_info = &(bond_info->rx_hashtbl[hash_index]); + + if (client_info->assigned == 1) { + if ((client_info->ip_src == arp->ip_src) && + (client_info->ip_dst == arp->ip_dst)) { + /* the entry is already assigned to this client */ + + if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) { + /* update mac address from arp */ + memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); + } + + assigned_slave = client_info->slave; + if (assigned_slave) { + _unlock_rx_hashtbl(bond); + return assigned_slave; + } + } else { + /* the entry is already assigned to some other client, + * move the old client to primary (current_slave) so + * that the new client can be assigned to this entry. + */ + if (bond->current_slave && + client_info->slave != bond->current_slave) { + client_info->slave = bond->current_slave; + rlb_update_client(client_info); + } + } + } + /* assign a new slave */ + assigned_slave = rlb_next_rx_slave(bond); + + if (assigned_slave) { + client_info->ip_src = arp->ip_src; + client_info->ip_dst = arp->ip_dst; + /* arp->mac_dst is broadcast for arp reqeusts. + * will be updated with clients actual unicast mac address + * upon receiving an arp reply. + */ + memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); + client_info->slave = assigned_slave; + + if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) { + client_info->ntt = 1; + bond->alb_info.rx_ntt = 1; + } + else { + client_info->ntt = 0; + } + + if (!client_info->assigned) { + u32 prev_tbl_head = bond_info->rx_hashtbl_head; + bond_info->rx_hashtbl_head = hash_index; + client_info->next = prev_tbl_head; + if (prev_tbl_head != RLB_NULL_INDEX) { + bond_info->rx_hashtbl[prev_tbl_head].prev = + hash_index; + } + client_info->assigned = 1; + } + } + + _unlock_rx_hashtbl(bond); + + return assigned_slave; +} + +/* chooses (and returns) transmit channel for arp reply + * does not choose channel for other arp types since they are + * sent on the current_slave + */ +static struct slave* +rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) +{ + struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw; + struct slave *tx_slave = NULL; + + if (arp->op_code == __constant_htons(ARPOP_REPLY)) { + /* the arp must be sent on the selected + * rx channel + */ + tx_slave = rlb_choose_channel(bond, arp); + if (tx_slave) { + memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN); + } + BOND_PRINT_DBG(("Server sent ARP Reply packet")); + } else if (arp->op_code == __constant_htons(ARPOP_REQUEST)) { + + /* Create an entry in the rx_hashtbl for this client as a + * place holder. + * When the arp reply is received the entry will be updated + * with the correct unicast address of the client. + */ + rlb_choose_channel(bond, arp); + + /* The ARP relpy packets must be delayed so that + * they can cancel out the influence of the ARP request. + */ + bond->alb_info.rlb_update_delay_counter = RLB_UPDATE_DELAY; + + /* arp requests are broadcast and are sent on the primary + * the arp request will collapse all clients on the subnet to + * the primary slave. We must register these clients to be + * updated with their assigned mac. + */ + rlb_req_update_subnet_clients(bond, arp->ip_src); + BOND_PRINT_DBG(("Server sent ARP Request packet")); + } + + return tx_slave; +} + +/* Caller must hold bond lock for read */ +static void +rlb_rebalance(struct bonding *bond) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct slave *assigned_slave = NULL; + u32 hash_index; + struct rlb_client_info *client_info = NULL; + u8 ntt = 0; + + _lock_rx_hashtbl(bond); + + if (bond_info->rx_hashtbl == NULL) { + _unlock_rx_hashtbl(bond); + return; + } + + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { + client_info = &(bond_info->rx_hashtbl[hash_index]); + assigned_slave = rlb_next_rx_slave(bond); + if (assigned_slave && (client_info->slave != assigned_slave)){ + client_info->slave = assigned_slave; + client_info->ntt = 1; + ntt = 1; + } + } + + /* update the team's flag only after the whole iteration */ + if (ntt) { + bond_info->rx_ntt = 1; + } + _unlock_rx_hashtbl(bond); +} + +/* Caller must hold rx_hashtbl lock */ +static inline void +rlb_init_table_entry(struct rlb_client_info *entry) +{ + entry->next = RLB_NULL_INDEX; + entry->prev = RLB_NULL_INDEX; + entry->assigned = 0; + entry->ntt = 0; +} + +static int +rlb_initialize(struct bonding *bond) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type); + int i; + size_t size; + + spin_lock_init(&(bond_info->rx_hashtbl_lock)); + + _lock_rx_hashtbl(bond); + if (bond_info->rx_hashtbl != NULL) { + printk (KERN_ERR "%s: RLB hash table is not NULL\n", + bond->device->name); + _unlock_rx_hashtbl(bond); + return -1; + } + + size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info); + bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL); + if (bond_info->rx_hashtbl == NULL) { + printk (KERN_ERR "%s: Failed to allocate" + " RLB hash table\n", bond->device->name); + _unlock_rx_hashtbl(bond); + return -1; + } + + bond_info->rx_hashtbl_head = RLB_NULL_INDEX; + + for (i=0; irx_hashtbl + i); + } + _unlock_rx_hashtbl(bond); + + /* register to receive ARPs */ + + /*initialize packet type*/ + pk_type->type = __constant_htons(ETH_P_ARP); + pk_type->dev = bond->device; + pk_type->func = rlb_arp_recv; + pk_type->data = (void*)1; /* understand shared skbs */ + + dev_add_pack(pk_type); + + return 0; +} + +static void +rlb_deinitialize(struct bonding *bond) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + + dev_remove_pack(&(bond_info->rlb_pkt_type)); + + _lock_rx_hashtbl(bond); + if (bond_info->rx_hashtbl == NULL) { + _unlock_rx_hashtbl(bond); + return; + } + kfree(bond_info->rx_hashtbl); + bond_info->rx_hashtbl = NULL; + _unlock_rx_hashtbl(bond); +} + +/*********************** tlb/rlb shared functions *********************/ + +static void +alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) +{ + struct sk_buff *skb = NULL; + struct learning_pkt pkt; + char *data = NULL; + int i; + unsigned int size = sizeof(struct learning_pkt); + + memset(&pkt, 0, size); + memcpy(pkt.mac_dst, mac_addr, ETH_ALEN); + memcpy(pkt.mac_src, mac_addr, ETH_ALEN); + pkt.type = __constant_htons(ETH_P_LOOP); + + for (i=0; i < MAX_LP_RETRY; i++) { + skb = NULL; + skb = dev_alloc_skb(size); + if (!skb) { + return; + } + + data = skb_put(skb, size); + memcpy(data, &pkt, size); + skb->mac.raw = data; + skb->nh.raw = data + ETH_HLEN; + skb->protocol = pkt.type; + skb->priority = TC_PRIO_CONTROL; + skb->dev = slave->dev; + dev_queue_xmit(skb); + } + +} + +/* hw is a boolean parameter that determines whether we should try and + * set the hw address of the hw as well as the hw address of the net_device + */ +static int +alb_set_mac_addr(struct slave *slave, u8 addr[], int hw) +{ + struct net_device *dev = NULL; + struct sockaddr s_addr; + + dev = slave->dev; + + if (!hw) { + memcpy(dev->dev_addr, addr, ETH_ALEN); + return 0; + } + + /* for rlb each slave must have a unique hw mac addresses so that */ + /* each slave will receive packets destined to a different mac */ + memcpy(s_addr.sa_data, addr, ETH_ALEN); + s_addr.sa_family = dev->type; + if (dev->set_mac_address(dev, &s_addr)) { + printk(KERN_DEBUG "bonding: Error: alb_set_mac_addr:" + " dev->set_mac_address of dev %s failed!" + " ALB mode requires that the base driver" + " support setting the hw address also when" + " the network device's interface is open\n", + dev->name); + return -EOPNOTSUPP; + } + return 0; +} + +/* Caller must hold bond lock for write or ptrlock for write*/ +static void +alb_swap_mac_addr(struct bonding *bond, + struct slave *slave1, + struct slave *slave2) +{ + u8 tmp_mac_addr[ETH_ALEN]; + struct slave *disabled_slave = NULL; + u8 slaves_state_differ; + + slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2)); + + memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN); + alb_set_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled); + alb_set_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled); + + /* fasten the change in the switch */ + if (SLAVE_IS_OK(slave1)) { + alb_send_learning_packets(slave1, slave1->dev->dev_addr); + if (bond->alb_info.rlb_enabled) { + /* inform the clients that the mac address + * has changed + */ + rlb_req_update_slave_clients(bond, slave1); + } + } + else { + disabled_slave = slave1; + } + + if (SLAVE_IS_OK(slave2)) { + alb_send_learning_packets(slave2, slave2->dev->dev_addr); + if (bond->alb_info.rlb_enabled) { + /* inform the clients that the mac address + * has changed + */ + rlb_req_update_slave_clients(bond, slave2); + } + } + else { + disabled_slave = slave2; + } + + if (bond->alb_info.rlb_enabled && slaves_state_differ) { + /* A disabled slave was assigned an active mac addr */ + rlb_teach_disabled_mac_on_primary(bond, + disabled_slave->dev->dev_addr); + } +} + +/** + * alb_change_hw_addr_on_detach + * @bond: bonding we're working on + * @slave: the slave that was just detached + * + * We assume that @slave was already detached from the slave list. + * + * If @slave's permanent hw address is different both from its current + * address and from @bond's address, then somewhere in the bond there's + * a slave that has @slave's permanet address as its current address. + * We'll make sure that that slave no longer uses @slave's permanent address. + * + * Caller must hold bond lock + */ +static void +alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave) +{ + struct slave *tmp_slave; + int perm_curr_diff; + int perm_bond_diff; + + perm_curr_diff = memcmp(slave->perm_hwaddr, + slave->dev->dev_addr, + ETH_ALEN); + perm_bond_diff = memcmp(slave->perm_hwaddr, + bond->device->dev_addr, + ETH_ALEN); + if (perm_curr_diff && perm_bond_diff) { + tmp_slave = bond_get_first_slave(bond); + while (tmp_slave) { + if (!memcmp(slave->perm_hwaddr, + tmp_slave->dev->dev_addr, + ETH_ALEN)) { + break; + } + tmp_slave = bond_get_next_slave(bond, tmp_slave); + } + + if (tmp_slave) { + alb_swap_mac_addr(bond, slave, tmp_slave); + } + } +} + +/** + * alb_handle_addr_collision_on_attach + * @bond: bonding we're working on + * @slave: the slave that was just attached + * + * checks uniqueness of slave's mac address and handles the case the + * new slave uses the bonds mac address. + * + * If the permanent hw address of @slave is @bond's hw address, we need to + * find a different hw address to give @slave, that isn't in use by any other + * slave in the bond. This address must be, of course, one of the premanent + * addresses of the other slaves. + * + * We go over the slave list, and for each slave there we compare its + * permanent hw address with the current address of all the other slaves. + * If no match was found, then we've found a slave with a permanent address + * that isn't used by any other slave in the bond, so we can assign it to + * @slave. + * + * assumption: this function is called before @slave is attached to the + * bond slave list. + * + * caller must hold the bond lock for write since the mac addresses are compared + * and may be swapped. + */ +static int +alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave) +{ + struct slave *tmp_slave1, *tmp_slave2; + + if (bond->slave_cnt == 0) { + /* this is the first slave */ + return 0; + } + + /* if slave's mac address differs from bond's mac address + * check uniqueness of slave's mac address against the other + * slaves in the bond. + */ + if (memcmp(slave->perm_hwaddr, bond->device->dev_addr, ETH_ALEN)) { + tmp_slave1 = bond_get_first_slave(bond); + for (; tmp_slave1; tmp_slave1 = bond_get_next_slave(bond, tmp_slave1)) { + if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr, + ETH_ALEN)) { + break; + } + } + if (tmp_slave1) { + /* a slave was found that is using the mac address + * of the new slave + */ + printk(KERN_ERR "bonding: Warning: the hw address " + "of slave %s is not unique - cannot enslave it!" + , slave->dev->name); + return -EINVAL; + } + return 0; + } + + /* the slave's address is equal to the address of the bond + * search for a spare address in the bond for this slave. + */ + tmp_slave1 = bond_get_first_slave(bond); + for (; tmp_slave1; tmp_slave1 = bond_get_next_slave(bond, tmp_slave1)) { + + tmp_slave2 = bond_get_first_slave(bond); + for (; tmp_slave2; tmp_slave2 = bond_get_next_slave(bond, tmp_slave2)) { + + if (!memcmp(tmp_slave1->perm_hwaddr, + tmp_slave2->dev->dev_addr, + ETH_ALEN)) { + + break; + } + } + + if (!tmp_slave2) { + /* no slave has tmp_slave1's perm addr + * as its curr addr + */ + break; + } + } + + if (tmp_slave1) { + alb_set_mac_addr(slave, tmp_slave1->perm_hwaddr, + bond->alb_info.rlb_enabled); + + printk(KERN_WARNING "bonding: Warning: the hw address " + "of slave %s is in use by the bond; " + "giving it the hw address of %s\n", + slave->dev->name, tmp_slave1->dev->name); + } else { + printk(KERN_CRIT "bonding: Error: the hw address " + "of slave %s is in use by the bond; " + "couldn't find a slave with a free hw " + "address to give it (this should not have " + "happened)\n", slave->dev->name); + return -EFAULT; + } + + return 0; +} + +/************************ exported alb funcions ************************/ + +int +bond_alb_initialize(struct bonding *bond, int rlb_enabled) +{ + int res; + + res = tlb_initialize(bond); + if (res) { + return res; + } + + if (rlb_enabled) { + bond->alb_info.rlb_enabled = 1; + /* initialize rlb */ + res = rlb_initialize(bond); + if (res) { + tlb_deinitialize(bond); + return res; + } + } + + return 0; +} + +void +bond_alb_deinitialize(struct bonding *bond) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + + tlb_deinitialize(bond); + + if (bond_info->rlb_enabled) { + rlb_deinitialize(bond); + } +} + +int +bond_alb_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct bonding *bond = (struct bonding *) dev->priv; + struct ethhdr *eth_data = (struct ethhdr *)skb->data; + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct slave *tx_slave = NULL; + char do_tx_balance = 1; + int hash_size = 0; + u32 hash_index = 0; + u8 *hash_start = NULL; + u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + if (!IS_UP(dev)) { /* bond down */ + dev_kfree_skb(skb); + return 0; + } + + /* make sure that the current_slave and the slaves list do + * not change during tx + */ + read_lock(&bond->lock); + + if (bond->slave_cnt == 0) { + /* no suitable interface, frame not sent */ + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + read_lock(&bond->ptrlock); + + switch (ntohs(skb->protocol)) { + case ETH_P_IP: + if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) || + (skb->nh.iph->daddr == 0xffffffff)) { + do_tx_balance = 0; + break; + } + hash_start = (char*)&(skb->nh.iph->daddr); + hash_size = 4; + break; + + case ETH_P_IPV6: + if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) { + do_tx_balance = 0; + break; + } + + hash_start = (char*)&(skb->nh.ipv6h->daddr); + hash_size = 16; + break; + + case ETH_P_IPX: + if (skb->nh.ipxh->ipx_checksum != + __constant_htons(IPX_NO_CHECKSUM)) { + /* something is wrong with this packet */ + do_tx_balance = 0; + break; + } + + if (skb->nh.ipxh->ipx_type != + __constant_htons(IPX_TYPE_NCP)) { + /* The only protocol worth balancing in + * this family since it has an "ARP" like + * mechanism + */ + do_tx_balance = 0; + break; + } + + hash_start = (char*)eth_data->h_dest; + hash_size = ETH_ALEN; + break; + + case ETH_P_ARP: + do_tx_balance = 0; + if (bond_info->rlb_enabled) { + tx_slave = rlb_arp_xmit(skb, bond); + } + break; + + default: + do_tx_balance = 0; + break; + } + + if (do_tx_balance) { + hash_index = _simple_hash(hash_start, hash_size); + tx_slave = tlb_choose_channel(bond, hash_index, skb->len); + } + + if (!tx_slave) { + /* unbalanced or unassigned, send through primary */ + tx_slave = bond->current_slave; + bond_info->unbalanced_load += skb->len; + } + + if (tx_slave && SLAVE_IS_OK(tx_slave)) { + skb->dev = tx_slave->dev; + if (tx_slave != bond->current_slave) { + memcpy(eth_data->h_source, + tx_slave->dev->dev_addr, + ETH_ALEN); + } + dev_queue_xmit(skb); + } else { + /* no suitable interface, frame not sent */ + if (tx_slave) { + tlb_clear_slave(bond, tx_slave, 0); + } + dev_kfree_skb(skb); + } + + read_unlock(&bond->ptrlock); + read_unlock(&bond->lock); + return 0; +} + +void +bond_alb_monitor(struct bonding *bond) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + struct slave *slave = NULL; + + read_lock(&bond->lock); + + if ((bond->slave_cnt == 0) || !(bond->device->flags & IFF_UP)) { + bond_info->tx_rebalance_counter = 0; + bond_info->lp_counter = 0; + goto out; + } + + bond_info->tx_rebalance_counter++; + bond_info->lp_counter++; + + /* send learning packets */ + if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) { + /* change of current_slave involves swapping of mac addresses. + * in order to avoid this swapping from happening while + * sending the learning packets, the ptrlock must be held for + * read. + */ + read_lock(&bond->ptrlock); + slave = bond_get_first_slave(bond); + while (slave) { + alb_send_learning_packets(slave,slave->dev->dev_addr); + slave = bond_get_next_slave(bond, slave); + } + read_unlock(&bond->ptrlock); + + bond_info->lp_counter = 0; + } + + /* rebalance tx traffic */ + if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) { + read_lock(&bond->ptrlock); + slave = bond_get_first_slave(bond); + while (slave) { + tlb_clear_slave(bond, slave, 1); + if (slave == bond->current_slave) { + SLAVE_TLB_INFO(slave).load = + bond_info->unbalanced_load / + BOND_TLB_REBALANCE_INTERVAL; + bond_info->unbalanced_load = 0; + } + slave = bond_get_next_slave(bond, slave); + } + read_unlock(&bond->ptrlock); + bond_info->tx_rebalance_counter = 0; + } + + /* handle rlb stuff */ + if (bond_info->rlb_enabled) { + /* the following code changes the promiscuity of the + * the current_slave. It needs to be locked with a + * write lock to protect from other code that also + * sets the promiscuity. + */ + write_lock(&bond->ptrlock); + if (bond_info->primary_is_promisc && + (++bond_info->rlb_promisc_timeout_counter >= + RLB_PROMISC_TIMEOUT)) { + + bond_info->rlb_promisc_timeout_counter = 0; + + /* If the primary was set to promiscuous mode + * because a slave was disabled then + * it can now leave promiscuous mode. + */ + dev_set_promiscuity(bond->current_slave->dev, -1); + bond_info->primary_is_promisc = 0; + } + write_unlock(&bond->ptrlock); + + if (bond_info->rlb_rebalance == 1) { + bond_info->rlb_rebalance = 0; + rlb_rebalance(bond); + } + + /* check if clients need updating */ + if (bond_info->rx_ntt) { + if (bond_info->rlb_update_delay_counter) { + --bond_info->rlb_update_delay_counter; + } else { + rlb_update_rx_clients(bond); + if (bond_info->rlb_update_retry_counter) { + --bond_info->rlb_update_retry_counter; + } else { + bond_info->rx_ntt = 0; + } + } + } + } + +out: + read_unlock(&bond->lock); + + if (bond->device->flags & IFF_UP) { + /* re-arm the timer */ + mod_timer(&(bond_info->alb_timer), + jiffies + (HZ/ALB_TIMER_TICKS_PER_SEC)); + } +} + +/* assumption: called before the slave is attched to the bond + * and not locked by the bond lock + */ +int +bond_alb_init_slave(struct bonding *bond, struct slave *slave) +{ + int err = 0; + + err = alb_set_mac_addr(slave, slave->perm_hwaddr, + bond->alb_info.rlb_enabled); + if (err) { + return err; + } + + /* caller must hold the bond lock for write since the mac addresses + * are compared and may be swapped. + */ + write_lock_bh(&bond->lock); + + err = alb_handle_addr_collision_on_attach(bond, slave); + + write_unlock_bh(&bond->lock); + + if (err) { + return err; + } + + tlb_init_slave(slave); + + /* order a rebalance ASAP */ + bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; + + if (bond->alb_info.rlb_enabled) { + bond->alb_info.rlb_rebalance = 1; + } + + return 0; +} + +/* Caller must hold bond lock for write */ +void +bond_alb_deinit_slave(struct bonding *bond, struct slave *slave) +{ + if (bond->slave_cnt > 1) { + alb_change_hw_addr_on_detach(bond, slave); + } + + tlb_clear_slave(bond, slave, 0); + + if (bond->alb_info.rlb_enabled) { + bond->alb_info.next_rx_slave = NULL; + rlb_clear_slave(bond, slave); + } +} + +/* Caller must hold bond lock for read */ +void +bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, + char link) +{ + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + + if (link == BOND_LINK_DOWN) { + tlb_clear_slave(bond, slave, 0); + if (bond->alb_info.rlb_enabled) { + rlb_clear_slave(bond, slave); + } + } else if (link == BOND_LINK_UP) { + /* order a rebalance ASAP */ + bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; + if (bond->alb_info.rlb_enabled) { + bond->alb_info.rlb_rebalance = 1; + /* If the updelay module parameter is smaller than the + * forwarding delay of the switch the rebalance will + * not work because the rebalance arp replies will + * not be forwarded to the clients.. + */ + } + } +} + +/** + * bond_alb_assign_current_slave - assign new current_slave + * @bond: our bonding struct + * @new_slave: new slave to assign + * + * Set the bond->current_slave to @new_slave and handle + * mac address swapping and promiscuity changes as needed. + * + * Caller must hold bond ptrlock for write (or bond lock for write) + */ +void +bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave) +{ + struct slave *swap_slave = bond->current_slave; + + if (bond->current_slave == new_slave) { + return; + } + + if (bond->current_slave && bond->alb_info.primary_is_promisc) { + dev_set_promiscuity(bond->current_slave->dev, -1); + bond->alb_info.primary_is_promisc = 0; + bond->alb_info.rlb_promisc_timeout_counter = 0; + } + + bond->current_slave = new_slave; + + if (!new_slave || (bond->slave_cnt == 0)) { + return; + } + + /* set the new current_slave to the bonds mac address + * i.e. swap mac addresses of old current_slave and new current_slave + */ + if (!swap_slave) { + /* find slave that is holding the bond's mac address */ + swap_slave = bond_get_first_slave(bond); + while (swap_slave) { + if (!memcmp(swap_slave->dev->dev_addr, + bond->device->dev_addr, ETH_ALEN)) { + break; + } + swap_slave = bond_get_next_slave(bond, swap_slave); + } + } + + /* current_slave must be set before calling alb_swap_mac_addr */ + if (swap_slave) { + /* swap mac address */ + alb_swap_mac_addr(bond, swap_slave, new_slave); + } else { + /* set the new_slave to the bond mac address */ + alb_set_mac_addr(new_slave, bond->device->dev_addr, + bond->alb_info.rlb_enabled); + /* fasten bond mac on new current slave */ + alb_send_learning_packets(new_slave, bond->device->dev_addr); + } +} + diff -urN linux-2.4.21/drivers/net/bonding/bond_alb.h linux-2.4.22/drivers/net/bonding/bond_alb.h --- linux-2.4.21/drivers/net/bonding/bond_alb.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/bonding/bond_alb.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,127 @@ +/* + * Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + */ + +#ifndef __BOND_ALB_H__ +#define __BOND_ALB_H__ + +#include + +struct bonding; +struct slave; + +#define BOND_ALB_INFO(bond) ((bond)->alb_info) +#define SLAVE_TLB_INFO(slave) ((slave)->tlb_info) + +struct tlb_client_info { + struct slave *tx_slave; /* A pointer to slave used for transmiting + * packets to a Client that the Hash function + * gave this entry index. + */ + u32 tx_bytes; /* Each Client acumulates the BytesTx that + * were tranmitted to it, and after each + * CallBack the LoadHistory is devided + * by the balance interval + */ + u32 load_history; /* This field contains the amount of Bytes + * that were transmitted to this client by + * the server on the previous balance + * interval in Bps. + */ + u32 next; /* The next Hash table entry index, assigned + * to use the same adapter for transmit. + */ + u32 prev; /* The previous Hash table entry index, + * assigned to use the same + */ +}; + +/* ------------------------------------------------------------------------- + * struct rlb_client_info contains all info related to a specific rx client + * connection. This is the Clients Hash Table entry struct + * ------------------------------------------------------------------------- + */ +struct rlb_client_info { + u32 ip_src; /* the server IP address */ + u32 ip_dst; /* the client IP address */ + u8 mac_dst[ETH_ALEN]; /* the client MAC address */ + u32 next; /* The next Hash table entry index */ + u32 prev; /* The previous Hash table entry index */ + u8 assigned; /* checking whether this entry is assigned */ + u8 ntt; /* flag - need to transmit client info */ + struct slave *slave; /* the slave assigned to this client */ +}; + +struct tlb_slave_info { + u32 head; /* Index to the head of the bi-directional clients + * hash table entries list. The entries in the list + * are the entries that were assigned to use this + * slave for transmit. + */ + u32 load; /* Each slave sums the loadHistory of all clients + * assigned to it + */ +}; + +struct alb_bond_info { + struct timer_list alb_timer; + struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */ + spinlock_t tx_hashtbl_lock; + u32 unbalanced_load; + int tx_rebalance_counter; + int lp_counter; + /* -------- rlb parameters -------- */ + int rlb_enabled; + struct packet_type rlb_pkt_type; + struct rlb_client_info *rx_hashtbl; /* Receive hash table */ + spinlock_t rx_hashtbl_lock; + u32 rx_hashtbl_head; + u8 rx_ntt; /* flag - need to transmit + * to all rx clients + */ + struct slave *next_rx_slave;/* next slave to be assigned + * to a new rx client for + */ + u32 rlb_interval_counter; + u8 primary_is_promisc; /* boolean */ + u32 rlb_promisc_timeout_counter;/* counts primary + * promiscuity time + */ + u32 rlb_update_delay_counter; + u32 rlb_update_retry_counter;/* counter of retries + * of client update + */ + u8 rlb_rebalance; /* flag - indicates that the + * rx traffic should be + * rebalanced + */ +}; + +int bond_alb_initialize(struct bonding *bond, int rlb_enabled); +void bond_alb_deinitialize(struct bonding *bond); +int bond_alb_init_slave(struct bonding *bond, struct slave *slave); +void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave); +void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link); +void bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave); +int bond_alb_xmit(struct sk_buff *skb, struct net_device *dev); +void bond_alb_monitor(struct bonding *bond); + +#endif /* __BOND_ALB_H__ */ + diff -urN linux-2.4.21/drivers/net/bonding/bond_main.c linux-2.4.22/drivers/net/bonding/bond_main.c --- linux-2.4.21/drivers/net/bonding/bond_main.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/bonding/bond_main.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,4030 @@ +/* + * originally based on the dummy device. + * + * Copyright 1999, Thomas Davis, tadavis@lbl.gov. + * Licensed under the GPL. Based on dummy.c, and eql.c devices. + * + * bonding.c: an Ethernet Bonding driver + * + * This is useful to talk to a Cisco EtherChannel compatible equipment: + * Cisco 5500 + * Sun Trunking (Solaris) + * Alteon AceDirector Trunks + * Linux Bonding + * and probably many L2 switches ... + * + * How it works: + * ifconfig bond0 ipaddress netmask up + * will setup a network device, with an ip address. No mac address + * will be assigned at this time. The hw mac address will come from + * the first slave bonded to the channel. All slaves will then use + * this hw mac address. + * + * ifconfig bond0 down + * will release all slaves, marking them as down. + * + * ifenslave bond0 eth0 + * will attach eth0 to bond0 as a slave. eth0 hw mac address will either + * a: be used as initial mac address + * b: if a hw mac address already is there, eth0's hw mac address + * will then be set from bond0. + * + * v0.1 - first working version. + * v0.2 - changed stats to be calculated by summing slaves stats. + * + * Changes: + * Arnaldo Carvalho de Melo + * - fix leaks on failure at bond_init + * + * 2000/09/30 - Willy Tarreau + * - added trivial code to release a slave device. + * - fixed security bug (CAP_NET_ADMIN not checked) + * - implemented MII link monitoring to disable dead links : + * All MII capable slaves are checked every milliseconds + * (100 ms seems good). This value can be changed by passing it to + * insmod. A value of zero disables the monitoring (default). + * - fixed an infinite loop in bond_xmit_roundrobin() when there's no + * good slave. + * - made the code hopefully SMP safe + * + * 2000/10/03 - Willy Tarreau + * - optimized slave lists based on relevant suggestions from Thomas Davis + * - implemented active-backup method to obtain HA with two switches: + * stay as long as possible on the same active interface, while we + * also monitor the backup one (MII link status) because we want to know + * if we are able to switch at any time. ( pass "mode=1" to insmod ) + * - lots of stress testings because we need it to be more robust than the + * wires ! :-> + * + * 2000/10/09 - Willy Tarreau + * - added up and down delays after link state change. + * - optimized the slaves chaining so that when we run forward, we never + * repass through the bond itself, but we can find it by searching + * backwards. Renders the deletion more difficult, but accelerates the + * scan. + * - smarter enslaving and releasing. + * - finer and more robust SMP locking + * + * 2000/10/17 - Willy Tarreau + * - fixed two potential SMP race conditions + * + * 2000/10/18 - Willy Tarreau + * - small fixes to the monitoring FSM in case of zero delays + * 2000/11/01 - Willy Tarreau + * - fixed first slave not automatically used in trunk mode. + * 2000/11/10 : spelling of "EtherChannel" corrected. + * 2000/11/13 : fixed a race condition in case of concurrent accesses to ioctl(). + * 2000/12/16 : fixed improper usage of rtnl_exlock_nowait(). + * + * 2001/1/3 - Chad N. Tindel + * - The bonding driver now simulates MII status monitoring, just like + * a normal network device. It will show that the link is down iff + * every slave in the bond shows that their links are down. If at least + * one slave is up, the bond's MII status will appear as up. + * + * 2001/2/7 - Chad N. Tindel + * - Applications can now query the bond from user space to get + * information which may be useful. They do this by calling + * the BOND_INFO_QUERY ioctl. Once the app knows how many slaves + * are in the bond, it can call the BOND_SLAVE_INFO_QUERY ioctl to + * get slave specific information (# link failures, etc). See + * for more details. The structs of interest + * are ifbond and ifslave. + * + * 2001/4/5 - Chad N. Tindel + * - Ported to 2.4 Kernel + * + * 2001/5/2 - Jeffrey E. Mast + * - When a device is detached from a bond, the slave device is no longer + * left thinking that is has a master. + * + * 2001/5/16 - Jeffrey E. Mast + * - memset did not appropriately initialized the bond rw_locks. Used + * rwlock_init to initialize to unlocked state to prevent deadlock when + * first attempting a lock + * - Called SET_MODULE_OWNER for bond device + * + * 2001/5/17 - Tim Anderson + * - 2 paths for releasing for slave release; 1 through ioctl + * and 2) through close. Both paths need to release the same way. + * - the free slave in bond release is changing slave status before + * the free. The netdev_set_master() is intended to change slave state + * so it should not be done as part of the release process. + * - Simple rule for slave state at release: only the active in A/B and + * only one in the trunked case. + * + * 2001/6/01 - Tim Anderson + * - Now call dev_close when releasing a slave so it doesn't screw up + * out routing table. + * + * 2001/6/01 - Chad N. Tindel + * - Added /proc support for getting bond and slave information. + * Information is in /proc/net//info. + * - Changed the locking when calling bond_close to prevent deadlock. + * + * 2001/8/05 - Janice Girouard + * - correct problem where refcnt of slave is not incremented in bond_ioctl + * so the system hangs when halting. + * - correct locking problem when unable to malloc in bond_enslave. + * - adding bond_xmit_xor logic. + * - adding multiple bond device support. + * + * 2001/8/13 - Erik Habbinga + * - correct locking problem with rtnl_exlock_nowait + * + * 2001/8/23 - Janice Girouard + * - bzero initial dev_bonds, to correct oops + * - convert SIOCDEVPRIVATE to new MII ioctl calls + * + * 2001/9/13 - Takao Indoh + * - Add the BOND_CHANGE_ACTIVE ioctl implementation + * + * 2001/9/14 - Mark Huth + * - Change MII_LINK_READY to not check for end of auto-negotiation, + * but only for an up link. + * + * 2001/9/20 - Chad N. Tindel + * - Add the device field to bonding_t. Previously the net_device + * corresponding to a bond wasn't available from the bonding_t + * structure. + * + * 2001/9/25 - Janice Girouard + * - add arp_monitor for active backup mode + * + * 2001/10/23 - Takao Indoh + * - Various memory leak fixes + * + * 2001/11/5 - Mark Huth + * - Don't take rtnl lock in bond_mii_monitor as it deadlocks under + * certain hotswap conditions. + * Note: this same change may be required in bond_arp_monitor ??? + * - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr + * - Handle hot swap ethernet interface deregistration events to remove + * kernel oops following hot swap of enslaved interface + * + * 2002/1/2 - Chad N. Tindel + * - Restore original slave flags at release time. + * + * 2002/02/18 - Erik Habbinga + * - bond_release(): calling kfree on our_slave after call to + * bond_restore_slave_flags, not before + * - bond_enslave(): saving slave flags into original_flags before + * call to netdev_set_master, so the IFF_SLAVE flag doesn't end + * up in original_flags + * + * 2002/04/05 - Mark Smith and + * Steve Mead + * - Port Gleb Natapov's multicast support patchs from 2.4.12 + * to 2.4.18 adding support for multicast. + * + * 2002/06/10 - Tony Cureington + * - corrected uninitialized pointer (ifr.ifr_data) in bond_check_dev_link; + * actually changed function to use MIIPHY, then MIIREG, and finally + * ETHTOOL to determine the link status + * - fixed bad ifr_data pointer assignments in bond_ioctl + * - corrected mode 1 being reported as active-backup in bond_get_info; + * also added text to distinguish type of load balancing (rr or xor) + * - change arp_ip_target module param from "1-12s" (array of 12 ptrs) + * to "s" (a single ptr) + * + * 2002/08/30 - Jay Vosburgh + * - Removed acquisition of xmit_lock in set_multicast_list; caused + * deadlock on SMP (lock is held by caller). + * - Revamped SIOCGMIIPHY, SIOCGMIIREG portion of bond_check_dev_link(). + * + * 2002/09/18 - Jay Vosburgh + * - Fixed up bond_check_dev_link() (and callers): removed some magic + * numbers, banished local MII_ defines, wrapped ioctl calls to + * prevent EFAULT errors + * + * 2002/9/30 - Jay Vosburgh + * - make sure the ip target matches the arp_target before saving the + * hw address. + * + * 2002/9/30 - Dan Eisner + * - make sure my_ip is set before taking down the link, since + * not all switches respond if the source ip is not set. + * + * 2002/10/8 - Janice Girouard + * - read in the local ip address when enslaving a device + * - add primary support + * - make sure 2*arp_interval has passed when a new device + * is brought on-line before taking it down. + * + * 2002/09/11 - Philippe De Muyter + * - Added bond_xmit_broadcast logic. + * - Added bond_mode() support function. + * + * 2002/10/26 - Laurent Deniel + * - allow to register multicast addresses only on active slave + * (useful in active-backup mode) + * - add multicast module parameter + * - fix deletion of multicast groups after unloading module + * + * 2002/11/06 - Kameshwara Rayaprolu + * - Changes to prevent panic from closing the device twice; if we close + * the device in bond_release, we must set the original_flags to down + * so it won't be closed again by the network layer. + * + * 2002/11/07 - Tony Cureington + * - Fix arp_target_hw_addr memory leak + * - Created activebackup_arp_monitor function to handle arp monitoring + * in active backup mode - the bond_arp_monitor had several problems... + * such as allowing slaves to tx arps sequentially without any delay + * for a response + * - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote + * this function to just handle arp monitoring in load-balancing mode; + * it is a lot more compact now + * - Changes to ensure one and only one slave transmits in active-backup + * mode + * - Robustesize parameters; warn users about bad combinations of + * parameters; also if miimon is specified and a network driver does + * not support MII or ETHTOOL, inform the user of this + * - Changes to support link_failure_count when in arp monitoring mode + * - Fix up/down delay reported in /proc + * - Added version; log version; make version available from "modinfo -d" + * - Fixed problem in bond_check_dev_link - if the first IOCTL (SIOCGMIIPH) + * failed, the ETHTOOL ioctl never got a chance + * + * 2002/11/16 - Laurent Deniel + * - fix multicast handling in activebackup_arp_monitor + * - remove one unnecessary and confusing current_slave == slave test + * in activebackup_arp_monitor + * + * 2002/11/17 - Laurent Deniel + * - fix bond_slave_info_query when slave_id = num_slaves + * + * 2002/11/19 - Janice Girouard + * - correct ifr_data reference. Update ifr_data reference + * to mii_ioctl_data struct values to avoid confusion. + * + * 2002/11/22 - Bert Barbe + * - Add support for multiple arp_ip_target + * + * 2002/12/13 - Jay Vosburgh + * - Changed to allow text strings for mode and multicast, e.g., + * insmod bonding mode=active-backup. The numbers still work. + * One change: an invalid choice will cause module load failure, + * rather than the previous behavior of just picking one. + * - Minor cleanups; got rid of dup ctype stuff, atoi function + * + * 2003/02/07 - Jay Vosburgh + * - Added use_carrier module parameter that causes miimon to + * use netif_carrier_ok() test instead of MII/ETHTOOL ioctls. + * - Minor cleanups; consolidated ioctl calls to one function. + * + * 2003/02/07 - Tony Cureington + * - Fix bond_mii_monitor() logic error that could result in + * bonding round-robin mode ignoring links after failover/recovery + * + * 2003/03/17 - Jay Vosburgh + * - kmalloc fix (GPF_KERNEL to GPF_ATOMIC) reported by + * Shmulik dot Hen at intel.com. + * - Based on discussion on mailing list, changed use of + * update_slave_cnt(), created wrapper functions for adding/removing + * slaves, changed bond_xmit_xor() to check slave_cnt instead of + * checking slave and slave->dev (which only worked by accident). + * - Misc code cleanup: get arp_send() prototype from header file, + * add max_bonds to bonding.txt. + * + * 2003/03/18 - Tsippy Mendelson and + * Shmulik Hen + * - Make sure only bond_attach_slave() and bond_detach_slave() can + * manipulate the slave list, including slave_cnt, even when in + * bond_release_all(). + * - Fixed hang in bond_release() with traffic running: + * netdev_set_master() must not be called from within the bond lock. + * + * 2003/03/18 - Tsippy Mendelson and + * Shmulik Hen + * - Fixed hang in bond_enslave() with traffic running: + * netdev_set_master() must not be called from within the bond lock. + * + * 2003/03/18 - Amir Noam + * - Added support for getting slave's speed and duplex via ethtool. + * Needed for 802.3ad and other future modes. + * + * 2003/03/18 - Tsippy Mendelson and + * Shmulik Hen + * - Enable support of modes that need to use the unique mac address of + * each slave. + * * bond_enslave(): Moved setting the slave's mac address, and + * openning it, from the application to the driver. This breaks + * backward comaptibility with old versions of ifenslave that open + * the slave before enalsving it !!!. + * * bond_release(): The driver also takes care of closing the slave + * and restoring its original mac address. + * - Removed the code that restores all base driver's flags. + * Flags are automatically restored once all undo stages are done + * properly. + * - Block possibility of enslaving before the master is up. This + * prevents putting the system in an unstable state. + * + * 2003/03/18 - Amir Noam , + * Tsippy Mendelson and + * Shmulik Hen + * - Added support for IEEE 802.3ad Dynamic link aggregation mode. + * + * 2003/05/01 - Amir Noam + * - Added ABI version control to restore compatibility between + * new/old ifenslave and new/old bonding. + * + * 2003/05/01 - Shmulik Hen + * - Fixed bug in bond_release_all(): save old value of current_slave + * before setting it to NULL. + * - Changed driver versioning scheme to include version number instead + * of release date (that is already in another field). There are 3 + * fields X.Y.Z where: + * X - Major version - big behavior changes + * Y - Minor version - addition of features + * Z - Extra version - minor changes and bug fixes + * The current version is 1.0.0 as a base line. + * + * 2003/05/01 - Tsippy Mendelson and + * Amir Noam + * - Added support for lacp_rate module param. + * - Code beautification and style changes (mainly in comments). + * new version - 1.0.1 + * + * 2003/05/01 - Shmulik Hen + * - Based on discussion on mailing list, changed locking scheme + * to use lock/unlock or lock_bh/unlock_bh appropriately instead + * of lock_irqsave/unlock_irqrestore. The new scheme helps exposing + * hidden bugs and solves system hangs that occurred due to the fact + * that holding lock_irqsave doesn't prevent softirqs from running. + * This also increases total throughput since interrupts are not + * blocked on each transmitted packets or monitor timeout. + * new version - 2.0.0 + * + * 2003/05/01 - Shmulik Hen + * - Added support for Transmit load balancing mode. + * - Concentrate all assignments of current_slave to a single point + * so specific modes can take actions when the primary adapter is + * changed. + * - Take the updelay parameter into consideration during bond_enslave + * since some adapters loose their link during setting the device. + * - Renamed bond_3ad_link_status_changed() to + * bond_3ad_handle_link_change() for compatibility with TLB. + * new version - 2.1.0 + * + * 2003/05/01 - Tsippy Mendelson + * - Added support for Adaptive load balancing mode which is + * equivalent to Transmit load balancing + Receive load balancing. + * new version - 2.2.0 + * + * 2003/05/15 - Jay Vosburgh + * - Applied fix to activebackup_arp_monitor posted to bonding-devel + * by Tony Cureington . Fixes ARP + * monitor endless failover bug. Version to 2.2.10 + * + * 2003/05/20 - Amir Noam + * - Fixed bug in ABI version control - Don't commit to a specific + * ABI version if receiving unsupported ioctl commands. + * + * 2003/05/22 - Jay Vosburgh + * - In conjunction with fix for ifenslave -c, in + * bond_change_active(), changing to the already active slave + * is no longer an error (it successfully does nothing). + * + * 2003/06/30 - Amir Noam + * - Fixed bond_change_active() for ALB/TLB modes. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "bonding.h" +#include "bond_3ad.h" +#include "bond_alb.h" + +#define DRV_VERSION "2.2.14" +#define DRV_RELDATE "June 30, 2003" +#define DRV_NAME "bonding" +#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" + +static const char *version = +DRV_NAME ".c:v" DRV_VERSION " (" DRV_RELDATE ")\n"; + +/* monitor all links that often (in milliseconds). <=0 disables monitoring */ +#ifndef BOND_LINK_MON_INTERV +#define BOND_LINK_MON_INTERV 0 +#endif + +#ifndef BOND_LINK_ARP_INTERV +#define BOND_LINK_ARP_INTERV 0 +#endif + +#ifndef MAX_ARP_IP_TARGETS +#define MAX_ARP_IP_TARGETS 16 +#endif + +struct bond_parm_tbl { + char *modename; + int mode; +}; + +static int arp_interval = BOND_LINK_ARP_INTERV; +static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, }; +static u32 arp_target[MAX_ARP_IP_TARGETS] = { 0, } ; +static int arp_ip_count = 0; +static u32 my_ip = 0; +char *arp_target_hw_addr = NULL; + +static char *primary= NULL; + +static int app_abi_ver = 0; +static int orig_app_abi_ver = -1; /* This is used to save the first ABI version + * we receive from the application. Once set, + * it won't be changed, and the module will + * refuse to enslave/release interfaces if the + * command comes from an application using + * another ABI version. + */ + +static int max_bonds = BOND_DEFAULT_MAX_BONDS; +static int miimon = BOND_LINK_MON_INTERV; +static int use_carrier = 1; +static int bond_mode = BOND_MODE_ROUNDROBIN; +static int updelay = 0; +static int downdelay = 0; + +static char *mode = NULL; + +static struct bond_parm_tbl bond_mode_tbl[] = { +{ "balance-rr", BOND_MODE_ROUNDROBIN}, +{ "active-backup", BOND_MODE_ACTIVEBACKUP}, +{ "balance-xor", BOND_MODE_XOR}, +{ "broadcast", BOND_MODE_BROADCAST}, +{ "802.3ad", BOND_MODE_8023AD}, +{ "balance-tlb", BOND_MODE_TLB}, +{ "balance-alb", BOND_MODE_ALB}, +{ NULL, -1}, +}; + +static int multicast_mode = BOND_MULTICAST_ALL; +static char *multicast = NULL; + +static struct bond_parm_tbl bond_mc_tbl[] = { +{ "disabled", BOND_MULTICAST_DISABLED}, +{ "active", BOND_MULTICAST_ACTIVE}, +{ "all", BOND_MULTICAST_ALL}, +{ NULL, -1}, +}; + +static int lacp_fast = 0; +static char *lacp_rate = NULL; + +static struct bond_parm_tbl bond_lacp_tbl[] = { +{ "slow", AD_LACP_SLOW}, +{ "fast", AD_LACP_FAST}, +{ NULL, -1}, +}; + +static int first_pass = 1; +static struct bonding *these_bonds = NULL; +static struct net_device *dev_bonds = NULL; + +MODULE_PARM(max_bonds, "i"); +MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); +MODULE_PARM(miimon, "i"); +MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); +MODULE_PARM(use_carrier, "i"); +MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)"); +MODULE_PARM(mode, "s"); +MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor"); +MODULE_PARM(arp_interval, "i"); +MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); +MODULE_PARM(arp_ip_target, "1-" __MODULE_STRING(MAX_ARP_IP_TARGETS) "s"); +MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); +MODULE_PARM(updelay, "i"); +MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds"); +MODULE_PARM(downdelay, "i"); +MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds"); +MODULE_PARM(primary, "s"); +MODULE_PARM_DESC(primary, "Primary network device to use"); +MODULE_PARM(multicast, "s"); +MODULE_PARM_DESC(multicast, "Mode for multicast support : 0 for none, 1 for active slave, 2 for all slaves (default)"); +MODULE_PARM(lacp_rate, "s"); +MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)"); + +static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev); +static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev); +static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *bond_get_stats(struct net_device *dev); +static void bond_mii_monitor(struct net_device *dev); +static void loadbalance_arp_monitor(struct net_device *dev); +static void activebackup_arp_monitor(struct net_device *dev); +static int bond_event(struct notifier_block *this, unsigned long event, void *ptr); +static void bond_mc_list_destroy(struct bonding *bond); +static void bond_mc_add(bonding_t *bond, void *addr, int alen); +static void bond_mc_delete(bonding_t *bond, void *addr, int alen); +static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst, int gpf_flag); +static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2); +static void bond_set_promiscuity(bonding_t *bond, int inc); +static void bond_set_allmulti(bonding_t *bond, int inc); +static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list); +static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old); +static int bond_enslave(struct net_device *master, struct net_device *slave); +static int bond_release(struct net_device *master, struct net_device *slave); +static int bond_release_all(struct net_device *master); +static int bond_sethwaddr(struct net_device *master, struct net_device *slave); + +/* + * bond_get_info is the interface into the /proc filesystem. This is + * a different interface than the BOND_INFO_QUERY ioctl. That is done + * through the generic networking ioctl interface, and bond_info_query + * is the internal function which provides that information. + */ +static int bond_get_info(char *buf, char **start, off_t offset, int length); + +/* Caller must hold bond->ptrlock for write */ +static inline struct slave* +bond_assign_current_slave(struct bonding *bond,struct slave *newslave) +{ + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + bond_alb_assign_current_slave(bond, newslave); + } else { + bond->current_slave = newslave; + } + + return bond->current_slave; +} + +/* #define BONDING_DEBUG 1 */ + +/* several macros */ + +static void arp_send_all(slave_t *slave) +{ + int i; + + for (i = 0; (idev, + my_ip, arp_target_hw_addr, slave->dev->dev_addr, + arp_target_hw_addr); + } +} + + +static const char * +bond_mode_name(void) +{ + switch (bond_mode) { + case BOND_MODE_ROUNDROBIN : + return "load balancing (round-robin)"; + case BOND_MODE_ACTIVEBACKUP : + return "fault-tolerance (active-backup)"; + case BOND_MODE_XOR : + return "load balancing (xor)"; + case BOND_MODE_BROADCAST : + return "fault-tolerance (broadcast)"; + case BOND_MODE_8023AD: + return "IEEE 802.3ad Dynamic link aggregation"; + case BOND_MODE_TLB: + return "transmit load balancing"; + case BOND_MODE_ALB: + return "adaptive load balancing"; + default: + return "unknown"; + } +} + +static const char * +multicast_mode_name(void) +{ + switch(multicast_mode) { + case BOND_MULTICAST_DISABLED : + return "disabled"; + case BOND_MULTICAST_ACTIVE : + return "active slave only"; + case BOND_MULTICAST_ALL : + return "all slaves"; + default : + return "unknown"; + } +} + +void bond_set_slave_inactive_flags(slave_t *slave) +{ + slave->state = BOND_STATE_BACKUP; + slave->dev->flags |= IFF_NOARP; +} + +void bond_set_slave_active_flags(slave_t *slave) +{ + slave->state = BOND_STATE_ACTIVE; + slave->dev->flags &= ~IFF_NOARP; +} + +/* + * This function counts and verifies the the number of attached + * slaves, checking the count against the expected value (given that incr + * is either 1 or -1, for add or removal of a slave). Only + * bond_xmit_xor() uses the slave_cnt value, but this is still a good + * consistency check. + */ +static inline void +update_slave_cnt(bonding_t *bond, int incr) +{ + slave_t *slave = NULL; + int expect = bond->slave_cnt + incr; + + bond->slave_cnt = 0; + for (slave = bond->prev; slave != (slave_t*)bond; + slave = slave->prev) { + bond->slave_cnt++; + } + + if (expect != bond->slave_cnt) + BUG(); +} + +/* + * Set MAC. Differs from eth_mac_addr in that we allow changes while + * netif_running(). + */ +static int +bond_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + return 0; +} + +/* + * This function detaches the slave from the list . + * WARNING: no check is made to verify if the slave effectively + * belongs to . It returns in case it's needed. + * Nothing is freed on return, structures are just unchained. + * If the bond->current_slave pointer was pointing to , + * it's replaced with bond->next, or NULL if not applicable. + * + * bond->lock held for writing by caller. + */ +static slave_t * +bond_detach_slave(bonding_t *bond, slave_t *slave) +{ + if ((bond == NULL) || (slave == NULL) || + ((void *)bond == (void *)slave)) { + printk(KERN_ERR + "bond_detach_slave(): trying to detach " + "slave %p from bond %p\n", bond, slave); + return slave; + } + + if (bond->next == slave) { /* is the slave at the head ? */ + if (bond->prev == slave) { /* is the slave alone ? */ + bond->prev = bond->next = (slave_t *)bond; + } else { /* not alone */ + bond->next = slave->next; + slave->next->prev = (slave_t *)bond; + bond->prev->next = slave->next; + } + } else { + slave->prev->next = slave->next; + if (bond->prev == slave) { /* is this slave the last one ? */ + bond->prev = slave->prev; + } else { + slave->next->prev = slave->prev; + } + } + + update_slave_cnt(bond, -1); + + /* no need to hold ptrlock since bond lock is + * already held for writing + */ + if (slave == bond->current_slave) { + if ( bond->next != (slave_t *)bond) { /* found one slave */ + bond_assign_current_slave(bond, bond->next); + } else { + bond_assign_current_slave(bond, NULL); + } + } + + return slave; +} + +/* + * This function attaches the slave to the list . + * + * bond->lock held for writing by caller. + */ +static void +bond_attach_slave(struct bonding *bond, struct slave *new_slave) +{ + /* + * queue to the end of the slaves list, make the first element its + * successor, the last one its predecessor, and make it the bond's + * predecessor. + * + * Just to clarify, so future bonding driver hackers don't go through + * the same confusion stage I did trying to figure this out, the + * slaves are stored in a double linked circular list, sortof. + * In the ->next direction, the last slave points to the first slave, + * bypassing bond; only the slaves are in the ->next direction. + * In the ->prev direction, however, the first slave points to bond + * and bond points to the last slave. + * + * It looks like a circle with a little bubble hanging off one side + * in the ->prev direction only. + * + * When going through the list once, its best to start at bond->prev + * and go in the ->prev direction, testing for bond. Doing this + * in the ->next direction doesn't work. Trust me, I know this now. + * :) -mts 2002.03.14 + */ + new_slave->prev = bond->prev; + new_slave->prev->next = new_slave; + bond->prev = new_slave; + new_slave->next = bond->next; + + update_slave_cnt(bond, 1); +} + + +/* + * Less bad way to call ioctl from within the kernel; this needs to be + * done some other way to get the call out of interrupt context. + * Needs "ioctl" variable to be supplied by calling context. + */ +#define IOCTL(dev, arg, cmd) ({ \ + int ret; \ + mm_segment_t fs = get_fs(); \ + set_fs(get_ds()); \ + ret = ioctl(dev, arg, cmd); \ + set_fs(fs); \ + ret; }) + +/* + * Get link speed and duplex from the slave's base driver + * using ethtool. If for some reason the call fails or the + * values are invalid, fake speed and duplex to 100/Full + * and return error. + */ +static int bond_update_speed_duplex(struct slave *slave) +{ + struct net_device *dev = slave->dev; + static int (* ioctl)(struct net_device *, struct ifreq *, int); + struct ifreq ifr; + struct ethtool_cmd etool; + + ioctl = dev->do_ioctl; + if (ioctl) { + etool.cmd = ETHTOOL_GSET; + ifr.ifr_data = (char*)&etool; + if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) { + slave->speed = etool.speed; + slave->duplex = etool.duplex; + } else { + goto err_out; + } + } else { + goto err_out; + } + + switch (slave->speed) { + case SPEED_10: + case SPEED_100: + case SPEED_1000: + break; + default: + goto err_out; + } + + switch (slave->duplex) { + case DUPLEX_FULL: + case DUPLEX_HALF: + break; + default: + goto err_out; + } + + return 0; + +err_out: + /* Fake speed and duplex */ + slave->speed = SPEED_100; + slave->duplex = DUPLEX_FULL; + return -1; +} + +/* + * if supports MII link status reporting, check its link status. + * + * We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(), + * depening upon the setting of the use_carrier parameter. + * + * Return either BMSR_LSTATUS, meaning that the link is up (or we + * can't tell and just pretend it is), or 0, meaning that the link is + * down. + * + * If reporting is non-zero, instead of faking link up, return -1 if + * both ETHTOOL and MII ioctls fail (meaning the device does not + * support them). If use_carrier is set, return whatever it says. + * It'd be nice if there was a good way to tell if a driver supports + * netif_carrier, but there really isn't. + */ +static int +bond_check_dev_link(struct net_device *dev, int reporting) +{ + static int (* ioctl)(struct net_device *, struct ifreq *, int); + struct ifreq ifr; + struct mii_ioctl_data *mii; + struct ethtool_value etool; + + if (use_carrier) { + return netif_carrier_ok(dev) ? BMSR_LSTATUS : 0; + } + + ioctl = dev->do_ioctl; + if (ioctl) { + /* TODO: set pointer to correct ioctl on a per team member */ + /* bases to make this more efficient. that is, once */ + /* we determine the correct ioctl, we will always */ + /* call it and not the others for that team */ + /* member. */ + + /* + * We cannot assume that SIOCGMIIPHY will also read a + * register; not all network drivers (e.g., e100) + * support that. + */ + + /* Yes, the mii is overlaid on the ifreq.ifr_ifru */ + mii = (struct mii_ioctl_data *)&ifr.ifr_data; + if (IOCTL(dev, &ifr, SIOCGMIIPHY) == 0) { + mii->reg_num = MII_BMSR; + if (IOCTL(dev, &ifr, SIOCGMIIREG) == 0) { + return mii->val_out & BMSR_LSTATUS; + } + } + + /* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */ + /* for a period of time so we attempt to get link status */ + /* from it last if the above MII ioctls fail... */ + etool.cmd = ETHTOOL_GLINK; + ifr.ifr_data = (char*)&etool; + if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) { + if (etool.data == 1) { + return BMSR_LSTATUS; + } else { +#ifdef BONDING_DEBUG + printk(KERN_INFO + ":: SIOCETHTOOL shows link down \n"); +#endif + return 0; + } + } + + } + + /* + * If reporting, report that either there's no dev->do_ioctl, + * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we + * cannot report link status). If not reporting, pretend + * we're ok. + */ + return reporting ? -1 : BMSR_LSTATUS; +} + +static u16 bond_check_mii_link(bonding_t *bond) +{ + int has_active_interface = 0; + + read_lock_bh(&bond->lock); + read_lock(&bond->ptrlock); + has_active_interface = (bond->current_slave != NULL); + read_unlock(&bond->ptrlock); + read_unlock_bh(&bond->lock); + + return (has_active_interface ? BMSR_LSTATUS : 0); +} + +/* register to receive lacpdus on a bond */ +static void bond_register_lacpdu(struct bonding *bond) +{ + struct packet_type* pk_type = &(BOND_AD_INFO(bond).ad_pkt_type); + + /* initialize packet type */ + pk_type->type = PKT_TYPE_LACPDU; + pk_type->dev = bond->device; + pk_type->func = bond_3ad_lacpdu_recv; + pk_type->data = (void*)1; /* understand shared skbs */ + + dev_add_pack(pk_type); +} + +/* unregister to receive lacpdus on a bond */ +static void bond_unregister_lacpdu(struct bonding *bond) +{ + dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); +} + +static int bond_open(struct net_device *dev) +{ + struct bonding *bond = (struct bonding *)(dev->priv); + struct timer_list *timer = &((struct bonding *)(dev->priv))->mii_timer; + struct timer_list *arp_timer = &((struct bonding *)(dev->priv))->arp_timer; + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer); + + /* bond_alb_initialize must be called before the timer + * is started. + */ + if (bond_alb_initialize(bond, (bond_mode == BOND_MODE_ALB))) { + /* something went wrong - fail the open operation */ + return -1; + } + + init_timer(alb_timer); + alb_timer->expires = jiffies + 1; + alb_timer->data = (unsigned long)bond; + alb_timer->function = (void *)&bond_alb_monitor; + add_timer(alb_timer); + } + + MOD_INC_USE_COUNT; + + if (miimon > 0) { /* link check interval, in milliseconds. */ + init_timer(timer); + timer->expires = jiffies + (miimon * HZ / 1000); + timer->data = (unsigned long)dev; + timer->function = (void *)&bond_mii_monitor; + add_timer(timer); + } + + if (arp_interval> 0) { /* arp interval, in milliseconds. */ + init_timer(arp_timer); + arp_timer->expires = jiffies + (arp_interval * HZ / 1000); + arp_timer->data = (unsigned long)dev; + if (bond_mode == BOND_MODE_ACTIVEBACKUP) { + arp_timer->function = (void *)&activebackup_arp_monitor; + } else { + arp_timer->function = (void *)&loadbalance_arp_monitor; + } + add_timer(arp_timer); + } + + if (bond_mode == BOND_MODE_8023AD) { + struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer); + init_timer(ad_timer); + ad_timer->expires = jiffies + (AD_TIMER_INTERVAL * HZ / 1000); + ad_timer->data = (unsigned long)bond; + ad_timer->function = (void *)&bond_3ad_state_machine_handler; + add_timer(ad_timer); + + /* register to receive LACPDUs */ + bond_register_lacpdu(bond); + } + + return 0; +} + +static int bond_close(struct net_device *master) +{ + bonding_t *bond = (struct bonding *) master->priv; + + write_lock_bh(&bond->lock); + + if (miimon > 0) { /* link check interval, in milliseconds. */ + del_timer(&bond->mii_timer); + } + if (arp_interval> 0) { /* arp interval, in milliseconds. */ + del_timer(&bond->arp_timer); + if (arp_target_hw_addr != NULL) { + kfree(arp_target_hw_addr); + arp_target_hw_addr = NULL; + } + } + + if (bond_mode == BOND_MODE_8023AD) { + del_timer_sync(&(BOND_AD_INFO(bond).ad_timer)); + + /* Unregister the receive of LACPDUs */ + bond_unregister_lacpdu(bond); + } + + bond_mc_list_destroy (bond); + + write_unlock_bh(&bond->lock); + + /* Release the bonded slaves */ + bond_release_all(master); + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer)); + + bond_alb_deinitialize(bond); + } + + MOD_DEC_USE_COUNT; + return 0; +} + +/* + * flush all members of flush->mc_list from device dev->mc_list + */ +static void bond_mc_list_flush(struct net_device *dev, struct net_device *flush) +{ + struct dev_mc_list *dmi; + + for (dmi = flush->mc_list; dmi != NULL; dmi = dmi->next) + dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); + + if (bond_mode == BOND_MODE_8023AD) { + /* del lacpdu mc addr from mc list */ + u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR; + + dev_mc_delete(dev, lacpdu_multicast, ETH_ALEN, 0); + } +} + +/* + * Totally destroys the mc_list in bond + */ +static void bond_mc_list_destroy(struct bonding *bond) +{ + struct dev_mc_list *dmi; + + dmi = bond->mc_list; + while (dmi) { + bond->mc_list = dmi->next; + kfree(dmi); + dmi = bond->mc_list; + } +} + +/* + * Add a Multicast address to every slave in the bonding group + */ +static void bond_mc_add(bonding_t *bond, void *addr, int alen) +{ + slave_t *slave; + switch (multicast_mode) { + case BOND_MULTICAST_ACTIVE : + /* write lock already acquired */ + if (bond->current_slave != NULL) + dev_mc_add(bond->current_slave->dev, addr, alen, 0); + break; + case BOND_MULTICAST_ALL : + for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) + dev_mc_add(slave->dev, addr, alen, 0); + break; + case BOND_MULTICAST_DISABLED : + break; + } +} + +/* + * Remove a multicast address from every slave in the bonding group + */ +static void bond_mc_delete(bonding_t *bond, void *addr, int alen) +{ + slave_t *slave; + switch (multicast_mode) { + case BOND_MULTICAST_ACTIVE : + /* write lock already acquired */ + if (bond->current_slave != NULL) + dev_mc_delete(bond->current_slave->dev, addr, alen, 0); + break; + case BOND_MULTICAST_ALL : + for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) + dev_mc_delete(slave->dev, addr, alen, 0); + break; + case BOND_MULTICAST_DISABLED : + break; + } +} + +/* + * Copy all the Multicast addresses from src to the bonding device dst + */ +static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst, + int gpf_flag) +{ + struct dev_mc_list *dmi, *new_dmi; + + for (dmi = src; dmi != NULL; dmi = dmi->next) { + new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag); + + if (new_dmi == NULL) { + return -ENOMEM; + } + + new_dmi->next = dst->mc_list; + dst->mc_list = new_dmi; + + new_dmi->dmi_addrlen = dmi->dmi_addrlen; + memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen); + new_dmi->dmi_users = dmi->dmi_users; + new_dmi->dmi_gusers = dmi->dmi_gusers; + } + return 0; +} + +/* + * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise + */ +static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2) +{ + return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 && + dmi1->dmi_addrlen == dmi2->dmi_addrlen; +} + +/* + * Push the promiscuity flag down to all slaves + */ +static void bond_set_promiscuity(bonding_t *bond, int inc) +{ + slave_t *slave; + switch (multicast_mode) { + case BOND_MULTICAST_ACTIVE : + /* write lock already acquired */ + if (bond->current_slave != NULL) + dev_set_promiscuity(bond->current_slave->dev, inc); + break; + case BOND_MULTICAST_ALL : + for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) + dev_set_promiscuity(slave->dev, inc); + break; + case BOND_MULTICAST_DISABLED : + break; + } +} + +/* + * Push the allmulti flag down to all slaves + */ +static void bond_set_allmulti(bonding_t *bond, int inc) +{ + slave_t *slave; + switch (multicast_mode) { + case BOND_MULTICAST_ACTIVE : + /* write lock already acquired */ + if (bond->current_slave != NULL) + dev_set_allmulti(bond->current_slave->dev, inc); + break; + case BOND_MULTICAST_ALL : + for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) + dev_set_allmulti(slave->dev, inc); + break; + case BOND_MULTICAST_DISABLED : + break; + } +} + +/* + * returns dmi entry if found, NULL otherwise + */ +static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi, + struct dev_mc_list *mc_list) +{ + struct dev_mc_list *idmi; + + for (idmi = mc_list; idmi != NULL; idmi = idmi->next) { + if (dmi_same(dmi, idmi)) { + return idmi; + } + } + return NULL; +} + +static void set_multicast_list(struct net_device *master) +{ + bonding_t *bond = master->priv; + struct dev_mc_list *dmi; + + if (multicast_mode == BOND_MULTICAST_DISABLED) + return; + /* + * Lock the private data for the master + */ + write_lock_bh(&bond->lock); + + /* set promiscuity flag to slaves */ + if ( (master->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC) ) + bond_set_promiscuity(bond, 1); + + if ( !(master->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC) ) + bond_set_promiscuity(bond, -1); + + /* set allmulti flag to slaves */ + if ( (master->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI) ) + bond_set_allmulti(bond, 1); + + if ( !(master->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI) ) + bond_set_allmulti(bond, -1); + + bond->flags = master->flags; + + /* looking for addresses to add to slaves' mc list */ + for (dmi = master->mc_list; dmi != NULL; dmi = dmi->next) { + if (bond_mc_list_find_dmi(dmi, bond->mc_list) == NULL) + bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen); + } + + /* looking for addresses to delete from slaves' list */ + for (dmi = bond->mc_list; dmi != NULL; dmi = dmi->next) { + if (bond_mc_list_find_dmi(dmi, master->mc_list) == NULL) + bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen); + } + + + /* save master's multicast list */ + bond_mc_list_destroy (bond); + bond_mc_list_copy (master->mc_list, bond, GFP_ATOMIC); + + write_unlock_bh(&bond->lock); +} + +/* + * Update the mc list and multicast-related flags for the new and + * old active slaves (if any) according to the multicast mode + */ +static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old) +{ + struct dev_mc_list *dmi; + + switch(multicast_mode) { + case BOND_MULTICAST_ACTIVE : + if (bond->device->flags & IFF_PROMISC) { + if (old != NULL && new != old) + dev_set_promiscuity(old->dev, -1); + dev_set_promiscuity(new->dev, 1); + } + if (bond->device->flags & IFF_ALLMULTI) { + if (old != NULL && new != old) + dev_set_allmulti(old->dev, -1); + dev_set_allmulti(new->dev, 1); + } + /* first remove all mc addresses from old slave if any, + and _then_ add them to new active slave */ + if (old != NULL && new != old) { + for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next) + dev_mc_delete(old->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); + } + for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next) + dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); + break; + case BOND_MULTICAST_ALL : + /* nothing to do: mc list is already up-to-date on all slaves */ + break; + case BOND_MULTICAST_DISABLED : + break; + } +} + +/* enslave device to bond device */ +static int bond_enslave(struct net_device *master_dev, + struct net_device *slave_dev) +{ + bonding_t *bond = NULL; + slave_t *new_slave = NULL; + unsigned long rflags = 0; + int err = 0; + struct dev_mc_list *dmi; + struct in_ifaddr **ifap; + struct in_ifaddr *ifa; + int link_reporting; + struct sockaddr addr; + + if (master_dev == NULL || slave_dev == NULL) { + return -ENODEV; + } + bond = (struct bonding *) master_dev->priv; + + if (slave_dev->do_ioctl == NULL) { + printk(KERN_DEBUG + "Warning : no link monitoring support for %s\n", + slave_dev->name); + } + + + /* bond must be initialized by bond_open() before enslaving */ + if (!(master_dev->flags & IFF_UP)) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Error, master_dev is not up\n"); +#endif + return -EPERM; + } + + /* already enslaved */ + if (master_dev->flags & IFF_SLAVE || slave_dev->flags & IFF_SLAVE) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Error, Device was already enslaved\n"); +#endif + return -EBUSY; + } + + if (app_abi_ver >= 1) { + /* The application is using an ABI, which requires the + * slave interface to be closed. + */ + if ((slave_dev->flags & IFF_UP)) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Error, slave_dev is up\n"); +#endif + return -EPERM; + } + + if (slave_dev->set_mac_address == NULL) { + printk(KERN_CRIT + "The slave device you specified does not support" + " setting the MAC address.\n"); + printk(KERN_CRIT + "Your kernel likely does not support slave" + " devices.\n"); + + return -EOPNOTSUPP; + } + } else { + /* The application is not using an ABI, which requires the + * slave interface to be open. + */ + if (!(slave_dev->flags & IFF_UP)) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Error, slave_dev is not running\n"); +#endif + return -EINVAL; + } + + if ((bond_mode == BOND_MODE_8023AD) || + (bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + printk(KERN_ERR + "bonding: Error: to use %s mode, you must " + "upgrade ifenslave.\n", bond_mode_name()); + return -EOPNOTSUPP; + } + } + + if ((new_slave = kmalloc(sizeof(slave_t), GFP_KERNEL)) == NULL) { + return -ENOMEM; + } + memset(new_slave, 0, sizeof(slave_t)); + + /* save slave's original flags before calling + * netdev_set_master and dev_open + */ + new_slave->original_flags = slave_dev->flags; + + if (app_abi_ver >= 1) { + /* save slave's original ("permanent") mac address for + * modes that needs it, and for restoring it upon release, + * and then set it to the master's address + */ + memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); + + if (bond->slave_cnt > 0) { + /* set slave to master's mac address + * The application already set the master's + * mac address to that of the first slave + */ + memcpy(addr.sa_data, master_dev->dev_addr, ETH_ALEN); + addr.sa_family = slave_dev->type; + err = slave_dev->set_mac_address(slave_dev, &addr); + if (err) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Error %d calling set_mac_address\n", err); +#endif + goto err_free; + } + } + + /* open the slave since the application closed it */ + err = dev_open(slave_dev); + if (err) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Openning slave %s failed\n", slave_dev->name); +#endif + goto err_restore_mac; + } + } + + err = netdev_set_master(slave_dev, master_dev); + if (err) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Error %d calling netdev_set_master\n", err); +#endif + if (app_abi_ver < 1) { + goto err_free; + } else { + goto err_close; + } + } + + new_slave->dev = slave_dev; + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + /* bond_alb_init_slave() must be called before all other stages since + * it might fail and we do not want to have to undo everything + */ + err = bond_alb_init_slave(bond, new_slave); + if (err) { + goto err_unset_master; + } + } + + if (multicast_mode == BOND_MULTICAST_ALL) { + /* set promiscuity level to new slave */ + if (master_dev->flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, 1); + + /* set allmulti level to new slave */ + if (master_dev->flags & IFF_ALLMULTI) + dev_set_allmulti(slave_dev, 1); + + /* upload master's mc_list to new slave */ + for (dmi = master_dev->mc_list; dmi != NULL; dmi = dmi->next) + dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); + } + + if (bond_mode == BOND_MODE_8023AD) { + /* add lacpdu mc addr to mc list */ + u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR; + + dev_mc_add(slave_dev, lacpdu_multicast, ETH_ALEN, 0); + } + + write_lock_bh(&bond->lock); + + bond_attach_slave(bond, new_slave); + new_slave->delay = 0; + new_slave->link_failure_count = 0; + + if (miimon > 0 && !use_carrier) { + link_reporting = bond_check_dev_link(slave_dev, 1); + + if ((link_reporting == -1) && (arp_interval == 0)) { + /* + * miimon is set but a bonded network driver + * does not support ETHTOOL/MII and + * arp_interval is not set. Note: if + * use_carrier is enabled, we will never go + * here (because netif_carrier is always + * supported); thus, we don't need to change + * the messages for netif_carrier. + */ + printk(KERN_ERR + "bond_enslave(): MII and ETHTOOL support not " + "available for interface %s, and " + "arp_interval/arp_ip_target module parameters " + "not specified, thus bonding will not detect " + "link failures! see bonding.txt for details.\n", + slave_dev->name); + } else if (link_reporting == -1) { + /* unable get link status using mii/ethtool */ + printk(KERN_WARNING + "bond_enslave: can't get link status from " + "interface %s; the network driver associated " + "with this interface does not support " + "MII or ETHTOOL link status reporting, thus " + "miimon has no effect on this interface.\n", + slave_dev->name); + } + } + + /* check for initial state */ + if ((miimon <= 0) || + (bond_check_dev_link(slave_dev, 0) == BMSR_LSTATUS)) { + if (updelay) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Initial state of slave_dev is " + "BOND_LINK_BACK\n"); +#endif + new_slave->link = BOND_LINK_BACK; + new_slave->delay = updelay; + } + else { +#ifdef BONDING_DEBUG + printk(KERN_DEBUG "Initial state of slave_dev is " + "BOND_LINK_UP\n"); +#endif + new_slave->link = BOND_LINK_UP; + } + new_slave->jiffies = jiffies; + } + else { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "Initial state of slave_dev is " + "BOND_LINK_DOWN\n"); +#endif + new_slave->link = BOND_LINK_DOWN; + } + + if (bond_update_speed_duplex(new_slave) && + (new_slave->link != BOND_LINK_DOWN)) { + + printk(KERN_WARNING + "bond_enslave(): failed to get speed/duplex from %s, " + "speed forced to 100Mbps, duplex forced to Full.\n", + new_slave->dev->name); + if (bond_mode == BOND_MODE_8023AD) { + printk(KERN_WARNING + "Operation of 802.3ad mode requires ETHTOOL support " + "in base driver for proper aggregator selection.\n"); + } + } + + /* if we're in active-backup mode, we need one and only one active + * interface. The backup interfaces will have their NOARP flag set + * because we need them to be completely deaf and not to respond to + * any ARP request on the network to avoid fooling a switch. Thus, + * since we guarantee that current_slave always point to the last + * usable interface, we just have to verify this interface's flag. + */ + if (bond_mode == BOND_MODE_ACTIVEBACKUP) { + if (((bond->current_slave == NULL) + || (bond->current_slave->dev->flags & IFF_NOARP)) + && (new_slave->link != BOND_LINK_DOWN)) { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "This is the first active slave\n"); +#endif + /* first slave or no active slave yet, and this link + is OK, so make this interface the active one */ + bond_assign_current_slave(bond, new_slave); + bond_set_slave_active_flags(new_slave); + bond_mc_update(bond, new_slave, NULL); + } + else { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "This is just a backup slave\n"); +#endif + bond_set_slave_inactive_flags(new_slave); + } + if (((struct in_device *)slave_dev->ip_ptr) != NULL) { + read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags); + ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list); + ifa = *ifap; + if (ifa != NULL) + my_ip = ifa->ifa_address; + read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags); + } + + /* if there is a primary slave, remember it */ + if (primary != NULL) { + if (strcmp(primary, new_slave->dev->name) == 0) { + bond->primary_slave = new_slave; + } + } + } else if (bond_mode == BOND_MODE_8023AD) { + /* in 802.3ad mode, the internal mechanism + * will activate the slaves in the selected + * aggregator + */ + bond_set_slave_inactive_flags(new_slave); + /* if this is the first slave */ + if (new_slave == bond->next) { + SLAVE_AD_INFO(new_slave).id = 1; + /* Initialize AD with the number of times that the AD timer is called in 1 second + * can be called only after the mac address of the bond is set + */ + bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL, + lacp_fast); + } else { + SLAVE_AD_INFO(new_slave).id = + SLAVE_AD_INFO(new_slave->prev).id + 1; + } + + bond_3ad_bind_slave(new_slave); + } else if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + new_slave->state = BOND_STATE_ACTIVE; + if ((bond->current_slave == NULL) && (new_slave->link != BOND_LINK_DOWN)) { + /* first slave or no active slave yet, and this link + * is OK, so make this interface the active one + */ + bond_assign_current_slave(bond, new_slave); + } + + /* if there is a primary slave, remember it */ + if (primary != NULL) { + if (strcmp(primary, new_slave->dev->name) == 0) { + bond->primary_slave = new_slave; + } + } + } else { +#ifdef BONDING_DEBUG + printk(KERN_CRIT "This slave is always active in trunk mode\n"); +#endif + /* always active in trunk mode */ + new_slave->state = BOND_STATE_ACTIVE; + if (bond->current_slave == NULL) + bond_assign_current_slave(bond, new_slave); + } + + write_unlock_bh(&bond->lock); + + if (app_abi_ver < 1) { + /* + * !!! This is to support old versions of ifenslave. + * We can remove this in 2.5 because our ifenslave takes + * care of this for us. + * We check to see if the master has a mac address yet. + * If not, we'll give it the mac address of our slave device. + */ + int ndx = 0; + + for (ndx = 0; ndx < slave_dev->addr_len; ndx++) { +#ifdef BONDING_DEBUG + printk(KERN_DEBUG + "Checking ndx=%d of master_dev->dev_addr\n", ndx); +#endif + if (master_dev->dev_addr[ndx] != 0) { +#ifdef BONDING_DEBUG + printk(KERN_DEBUG + "Found non-zero byte at ndx=%d\n", ndx); +#endif + break; + } + } + if (ndx == slave_dev->addr_len) { + /* + * We got all the way through the address and it was + * all 0's. + */ +#ifdef BONDING_DEBUG + printk(KERN_DEBUG "%s doesn't have a MAC address yet. ", + master_dev->name); + printk(KERN_DEBUG "Going to give assign it from %s.\n", + slave_dev->name); +#endif + bond_sethwaddr(master_dev, slave_dev); + } + } + + printk (KERN_INFO "%s: enslaving %s as a%s interface with a%s link.\n", + master_dev->name, slave_dev->name, + new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup", + new_slave->link != BOND_LINK_DOWN ? "n up" : " down"); + + /* enslave is successful */ + return 0; + +/* Undo stages on error */ +err_unset_master: + netdev_set_master(slave_dev, NULL); + +err_close: + dev_close(slave_dev); + +err_restore_mac: + memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); + addr.sa_family = slave_dev->type; + slave_dev->set_mac_address(slave_dev, &addr); + +err_free: + kfree(new_slave); + return err; +} + +/* + * This function changes the active slave to slave . + * It returns -EINVAL in the following cases. + * - is not found in the list. + * - There is not active slave now. + * - is already active. + * - The link state of is not BOND_LINK_UP. + * - is not running. + * In these cases, this fuction does nothing. + * In the other cases, currnt_slave pointer is changed and 0 is returned. + */ +static int bond_change_active(struct net_device *master_dev, struct net_device *slave_dev) +{ + bonding_t *bond; + slave_t *slave; + slave_t *oldactive = NULL; + slave_t *newactive = NULL; + int ret = 0; + + if (master_dev == NULL || slave_dev == NULL) { + return -ENODEV; + } + + bond = (struct bonding *) master_dev->priv; + write_lock_bh(&bond->lock); + slave = (slave_t *)bond; + oldactive = bond->current_slave; + + while ((slave = slave->prev) != (slave_t *)bond) { + if(slave_dev == slave->dev) { + newactive = slave; + break; + } + } + + /* + * Changing to the current active: do nothing; return success. + */ + if (newactive && (newactive == oldactive)) { + write_unlock_bh(&bond->lock); + return 0; + } + + if ((newactive != NULL)&& + (oldactive != NULL)&& + (newactive->link == BOND_LINK_UP)&& + IS_UP(newactive->dev)) { + if (bond_mode == BOND_MODE_ACTIVEBACKUP) { + bond_set_slave_inactive_flags(oldactive); + bond_set_slave_active_flags(newactive); + } + + bond_mc_update(bond, newactive, oldactive); + bond_assign_current_slave(bond, newactive); + printk("%s : activate %s(old : %s)\n", + master_dev->name, newactive->dev->name, + oldactive->dev->name); + } else { + ret = -EINVAL; + } + write_unlock_bh(&bond->lock); + return ret; +} + +/* Choose a new valid interface from the pool, set it active + * and make it the current slave. If no valid interface is + * found, the oldest slave in BACK state is choosen and + * activated. If none is found, it's considered as no + * interfaces left so the current slave is set to NULL. + * The result is a pointer to the current slave. + * + * Since this function sends messages tails through printk, the caller + * must have started something like `printk(KERN_INFO "xxxx ");'. + * + * Warning: Caller must hold ptrlock for writing. + */ +slave_t *change_active_interface(bonding_t *bond) +{ + slave_t *newslave, *oldslave; + slave_t *bestslave = NULL; + int mintime; + + newslave = oldslave = bond->current_slave; + + if (newslave == NULL) { /* there were no active slaves left */ + if (bond->next != (slave_t *)bond) { /* found one slave */ + newslave = bond_assign_current_slave(bond, bond->next); + } else { + + printk (" but could not find any %s interface.\n", + (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other"); + bond_assign_current_slave(bond, NULL); + return NULL; /* still no slave, return NULL */ + } + } else if (bond_mode == BOND_MODE_ACTIVEBACKUP) { + /* make sure oldslave doesn't send arps - this could + * cause a ping-pong effect between interfaces since they + * would be able to tx arps - in active backup only one + * slave should be able to tx arps, and that should be + * the current_slave; the only exception is when all + * slaves have gone down, then only one non-current slave can + * send arps at a time; clearing oldslaves' mc list is handled + * later in this function. + */ + bond_set_slave_inactive_flags(oldslave); + } + + mintime = updelay; + + /* first try the primary link; if arping, a link must tx/rx traffic + * before it can be considered the current_slave - also, we would skip + * slaves between the current_slave and primary_slave that may be up + * and able to arp + */ + if ((bond->primary_slave != NULL) && (arp_interval == 0)) { + if (IS_UP(bond->primary_slave->dev)) + newslave = bond->primary_slave; + } + + do { + if (IS_UP(newslave->dev)) { + if (newslave->link == BOND_LINK_UP) { + /* this one is immediately usable */ + if (bond_mode == BOND_MODE_ACTIVEBACKUP) { + bond_set_slave_active_flags(newslave); + bond_mc_update(bond, newslave, oldslave); + printk (" and making interface %s the active one.\n", + newslave->dev->name); + } + else { + printk (" and setting pointer to interface %s.\n", + newslave->dev->name); + } + + bond_assign_current_slave(bond, newslave); + return newslave; + } + else if (newslave->link == BOND_LINK_BACK) { + /* link up, but waiting for stabilization */ + if (newslave->delay < mintime) { + mintime = newslave->delay; + bestslave = newslave; + } + } + } + } while ((newslave = newslave->next) != oldslave); + + /* no usable backup found, we'll see if we at least got a link that was + coming back for a long time, and could possibly already be usable. + */ + + if (bestslave != NULL) { + /* early take-over. */ + printk (" and making interface %s the active one %d ms earlier.\n", + bestslave->dev->name, + (updelay - bestslave->delay)*miimon); + + bestslave->delay = 0; + bestslave->link = BOND_LINK_UP; + bestslave->jiffies = jiffies; + bond_set_slave_active_flags(bestslave); + bond_mc_update(bond, bestslave, oldslave); + bond_assign_current_slave(bond, bestslave); + return bestslave; + } + + if ((bond_mode == BOND_MODE_ACTIVEBACKUP) && + (multicast_mode == BOND_MULTICAST_ACTIVE) && + (oldslave != NULL)) { + /* flush bonds (master's) mc_list from oldslave since it wasn't + * updated (and deleted) above + */ + bond_mc_list_flush(oldslave->dev, bond->device); + if (bond->device->flags & IFF_PROMISC) { + dev_set_promiscuity(oldslave->dev, -1); + } + if (bond->device->flags & IFF_ALLMULTI) { + dev_set_allmulti(oldslave->dev, -1); + } + } + + printk (" but could not find any %s interface.\n", + (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other"); + + /* absolutely nothing found. let's return NULL */ + bond_assign_current_slave(bond, NULL); + return NULL; +} + +/* + * Try to release the slave device from the bond device + * It is legal to access current_slave without a lock because all the function + * is write-locked. + * + * The rules for slave state should be: + * for Active/Backup: + * Active stays on all backups go down + * for Bonded connections: + * The first up interface should be left on and all others downed. + */ +static int bond_release(struct net_device *master, struct net_device *slave) +{ + bonding_t *bond; + slave_t *our_slave, *old_current; + struct sockaddr addr; + + if (master == NULL || slave == NULL) { + return -ENODEV; + } + + bond = (struct bonding *) master->priv; + + /* master already enslaved, or slave not enslaved, + or no slave for this master */ + if ((master->flags & IFF_SLAVE) || !(slave->flags & IFF_SLAVE)) { + printk (KERN_DEBUG "%s: cannot release %s.\n", master->name, slave->name); + return -EINVAL; + } + + write_lock_bh(&bond->lock); + bond->current_arp_slave = NULL; + our_slave = (slave_t *)bond; + old_current = bond->current_slave; + while ((our_slave = our_slave->prev) != (slave_t *)bond) { + if (our_slave->dev == slave) { + int mac_addr_differ = memcmp(bond->device->dev_addr, + our_slave->perm_hwaddr, + ETH_ALEN); + if (!mac_addr_differ && (bond->slave_cnt > 1)) { + printk(KERN_WARNING "WARNING: the permanent HWaddr of %s " + "- %02X:%02X:%02X:%02X:%02X:%02X - " + "is still in use by %s. Set the HWaddr " + "of %s to a different address " + "to avoid conflicts.\n", + slave->name, + slave->dev_addr[0], + slave->dev_addr[1], + slave->dev_addr[2], + slave->dev_addr[3], + slave->dev_addr[4], + slave->dev_addr[5], + bond->device->name, + slave->name); + } + + /* Inform AD package of unbinding of slave. */ + if (bond_mode == BOND_MODE_8023AD) { + /* must be called before the slave is + * detached from the list + */ + bond_3ad_unbind_slave(our_slave); + } + + /* release the slave from its bond */ + bond_detach_slave(bond, our_slave); + + if (bond->primary_slave == our_slave) { + bond->primary_slave = NULL; + } + + printk (KERN_INFO "%s: releasing %s interface %s", + master->name, + (our_slave->state == BOND_STATE_ACTIVE) ? "active" : "backup", + slave->name); + + if (our_slave == old_current) { + /* find a new interface and be verbose */ + change_active_interface(bond); + } else { + printk(".\n"); + } + + if (bond->current_slave == NULL) { + printk(KERN_INFO + "%s: now running without any active interface !\n", + master->name); + } + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + /* must be called only after the slave has been + * detached from the list and the current_slave + * has been replaced (if our_slave == old_current) + */ + bond_alb_deinit_slave(bond, our_slave); + } + + break; + } + + } + write_unlock_bh(&bond->lock); + + if (our_slave == (slave_t *)bond) { + /* if we get here, it's because the device was not found */ + printk (KERN_INFO "%s: %s not enslaved\n", master->name, slave->name); + return -EINVAL; + } + + /* undo settings and restore original values */ + + if (multicast_mode == BOND_MULTICAST_ALL) { + /* flush master's mc_list from slave */ + bond_mc_list_flush (slave, master); + + /* unset promiscuity level from slave */ + if (master->flags & IFF_PROMISC) + dev_set_promiscuity(slave, -1); + + /* unset allmulti level from slave */ + if (master->flags & IFF_ALLMULTI) + dev_set_allmulti(slave, -1); + } + + netdev_set_master(slave, NULL); + + /* close slave before restoring its mac address */ + dev_close(slave); + + if (app_abi_ver >= 1) { + /* restore original ("permanent") mac address */ + memcpy(addr.sa_data, our_slave->perm_hwaddr, ETH_ALEN); + addr.sa_family = slave->type; + slave->set_mac_address(slave, &addr); + } + + /* restore the original state of the + * IFF_NOARP flag that might have been + * set by bond_set_slave_inactive_flags() + */ + if ((our_slave->original_flags & IFF_NOARP) == 0) { + slave->flags &= ~IFF_NOARP; + } + + kfree(our_slave); + + /* if the last slave was removed, zero the mac address + * of the master so it will be set by the application + * to the mac address of the first slave + */ + if (bond->next == (slave_t*)bond) { + memset(master->dev_addr, 0, master->addr_len); + } + + return 0; /* deletion OK */ +} + +/* + * This function releases all slaves. + */ +static int bond_release_all(struct net_device *master) +{ + bonding_t *bond; + slave_t *our_slave, *old_current; + struct net_device *slave_dev; + struct sockaddr addr; + int err = 0; + + if (master == NULL) { + return -ENODEV; + } + + if (master->flags & IFF_SLAVE) { + return -EINVAL; + } + + bond = (struct bonding *) master->priv; + + write_lock_bh(&bond->lock); + if (bond->next == (struct slave *) bond) { + err = -EINVAL; + goto out; + } + + old_current = bond->current_slave; + bond_assign_current_slave(bond, NULL); + bond->current_arp_slave = NULL; + bond->primary_slave = NULL; + + while ((our_slave = bond->prev) != (slave_t *)bond) { + /* Inform AD package of unbinding of slave + * before slave is detached from the list. + */ + if (bond_mode == BOND_MODE_8023AD) { + bond_3ad_unbind_slave(our_slave); + } + + slave_dev = our_slave->dev; + bond_detach_slave(bond, our_slave); + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + /* must be called only after the slave + * has been detached from the list + */ + bond_alb_deinit_slave(bond, our_slave); + } + + /* now that the slave is detached, unlock and perform + * all the undo steps that should not be called from + * within a lock. + */ + write_unlock_bh(&bond->lock); + + if (multicast_mode == BOND_MULTICAST_ALL + || (multicast_mode == BOND_MULTICAST_ACTIVE + && old_current == our_slave)) { + + /* flush master's mc_list from slave */ + bond_mc_list_flush (slave_dev, master); + + /* unset promiscuity level from slave */ + if (master->flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, -1); + + /* unset allmulti level from slave */ + if (master->flags & IFF_ALLMULTI) + dev_set_allmulti(slave_dev, -1); + } + + netdev_set_master(slave_dev, NULL); + + /* close slave before restoring its mac address */ + dev_close(slave_dev); + + if (app_abi_ver >= 1) { + /* restore original ("permanent") mac address*/ + memcpy(addr.sa_data, our_slave->perm_hwaddr, ETH_ALEN); + addr.sa_family = slave_dev->type; + slave_dev->set_mac_address(slave_dev, &addr); + } + + /* restore the original state of the IFF_NOARP flag that might have + * been set by bond_set_slave_inactive_flags() + */ + if ((our_slave->original_flags & IFF_NOARP) == 0) { + slave_dev->flags &= ~IFF_NOARP; + } + + kfree(our_slave); + + /* re-acquire the lock before getting the next slave */ + write_lock_bh(&bond->lock); + } + + /* zero the mac address of the master so it will be + * set by the application to the mac address of the + * first slave + */ + memset(master->dev_addr, 0, master->addr_len); + + printk (KERN_INFO "%s: released all slaves\n", master->name); + +out: + write_unlock_bh(&bond->lock); + + return err; +} + +/* this function is called regularly to monitor each slave's link. */ +static void bond_mii_monitor(struct net_device *master) +{ + bonding_t *bond = (struct bonding *) master->priv; + slave_t *slave, *bestslave, *oldcurrent; + int slave_died = 0; + + read_lock(&bond->lock); + + /* we will try to read the link status of each of our slaves, and + * set their IFF_RUNNING flag appropriately. For each slave not + * supporting MII status, we won't do anything so that a user-space + * program could monitor the link itself if needed. + */ + + bestslave = NULL; + slave = (slave_t *)bond; + + read_lock(&bond->ptrlock); + oldcurrent = bond->current_slave; + read_unlock(&bond->ptrlock); + + while ((slave = slave->prev) != (slave_t *)bond) { + /* use updelay+1 to match an UP slave even when updelay is 0 */ + int mindelay = updelay + 1; + struct net_device *dev = slave->dev; + int link_state; + u16 old_speed = slave->speed; + u8 old_duplex = slave->duplex; + + link_state = bond_check_dev_link(dev, 0); + + switch (slave->link) { + case BOND_LINK_UP: /* the link was up */ + if (link_state == BMSR_LSTATUS) { + /* link stays up, tell that this one + is immediately available */ + if (IS_UP(dev) && (mindelay > -2)) { + /* -2 is the best case : + this slave was already up */ + mindelay = -2; + bestslave = slave; + } + break; + } + else { /* link going down */ + slave->link = BOND_LINK_FAIL; + slave->delay = downdelay; + if (slave->link_failure_count < UINT_MAX) { + slave->link_failure_count++; + } + if (downdelay > 0) { + printk (KERN_INFO + "%s: link status down for %sinterface " + "%s, disabling it in %d ms.\n", + master->name, + IS_UP(dev) + ? ((bond_mode == BOND_MODE_ACTIVEBACKUP) + ? ((slave == oldcurrent) + ? "active " : "backup ") + : "") + : "idle ", + dev->name, + downdelay * miimon); + } + } + /* no break ! fall through the BOND_LINK_FAIL test to + ensure proper action to be taken + */ + case BOND_LINK_FAIL: /* the link has just gone down */ + if (link_state != BMSR_LSTATUS) { + /* link stays down */ + if (slave->delay <= 0) { + /* link down for too long time */ + slave->link = BOND_LINK_DOWN; + /* in active/backup mode, we must + * completely disable this interface + */ + if ((bond_mode == BOND_MODE_ACTIVEBACKUP) || + (bond_mode == BOND_MODE_8023AD)) { + bond_set_slave_inactive_flags(slave); + } + printk(KERN_INFO + "%s: link status definitely down " + "for interface %s, disabling it", + master->name, + dev->name); + + /* notify ad that the link status has changed */ + if (bond_mode == BOND_MODE_8023AD) { + bond_3ad_handle_link_change(slave, BOND_LINK_DOWN); + } + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN); + } + + write_lock(&bond->ptrlock); + if (slave == bond->current_slave) { + /* find a new interface and be verbose */ + change_active_interface(bond); + } else { + printk(".\n"); + } + write_unlock(&bond->ptrlock); + slave_died = 1; + } else { + slave->delay--; + } + } else { + /* link up again */ + slave->link = BOND_LINK_UP; + slave->jiffies = jiffies; + printk(KERN_INFO + "%s: link status up again after %d ms " + "for interface %s.\n", + master->name, + (downdelay - slave->delay) * miimon, + dev->name); + + if (IS_UP(dev) && (mindelay > -1)) { + /* -1 is a good case : this slave went + down only for a short time */ + mindelay = -1; + bestslave = slave; + } + } + break; + case BOND_LINK_DOWN: /* the link was down */ + if (link_state != BMSR_LSTATUS) { + /* the link stays down, nothing more to do */ + break; + } else { /* link going up */ + slave->link = BOND_LINK_BACK; + slave->delay = updelay; + + if (updelay > 0) { + /* if updelay == 0, no need to + advertise about a 0 ms delay */ + printk (KERN_INFO + "%s: link status up for interface" + " %s, enabling it in %d ms.\n", + master->name, + dev->name, + updelay * miimon); + } + } + /* no break ! fall through the BOND_LINK_BACK state in + case there's something to do. + */ + case BOND_LINK_BACK: /* the link has just come back */ + if (link_state != BMSR_LSTATUS) { + /* link down again */ + slave->link = BOND_LINK_DOWN; + printk(KERN_INFO + "%s: link status down again after %d ms " + "for interface %s.\n", + master->name, + (updelay - slave->delay) * miimon, + dev->name); + } else { + /* link stays up */ + if (slave->delay == 0) { + /* now the link has been up for long time enough */ + slave->link = BOND_LINK_UP; + slave->jiffies = jiffies; + + if (bond_mode == BOND_MODE_8023AD) { + /* prevent it from being the active one */ + slave->state = BOND_STATE_BACKUP; + } + else if (bond_mode != BOND_MODE_ACTIVEBACKUP) { + /* make it immediately active */ + slave->state = BOND_STATE_ACTIVE; + } else if (slave != bond->primary_slave) { + /* prevent it from being the active one */ + slave->state = BOND_STATE_BACKUP; + } + + printk(KERN_INFO + "%s: link status definitely up " + "for interface %s.\n", + master->name, + dev->name); + + /* notify ad that the link status has changed */ + if (bond_mode == BOND_MODE_8023AD) { + bond_3ad_handle_link_change(slave, BOND_LINK_UP); + } + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + bond_alb_handle_link_change(bond, slave, BOND_LINK_UP); + } + + write_lock(&bond->ptrlock); + if ( (bond->primary_slave != NULL) + && (slave == bond->primary_slave) ) + change_active_interface(bond); + write_unlock(&bond->ptrlock); + } + else + slave->delay--; + + /* we'll also look for the mostly eligible slave */ + if (bond->primary_slave == NULL) { + if (IS_UP(dev) && (slave->delay < mindelay)) { + mindelay = slave->delay; + bestslave = slave; + } + } else if ( (IS_UP(bond->primary_slave->dev)) || + ( (!IS_UP(bond->primary_slave->dev)) && + (IS_UP(dev) && (slave->delay < mindelay)) ) ) { + mindelay = slave->delay; + bestslave = slave; + } + } + break; + } /* end of switch */ + + bond_update_speed_duplex(slave); + + if (bond_mode == BOND_MODE_8023AD) { + if (old_speed != slave->speed) { + bond_3ad_adapter_speed_changed(slave); + } + if (old_duplex != slave->duplex) { + bond_3ad_adapter_duplex_changed(slave); + } + } + + } /* end of while */ + + /* + * if there's no active interface and we discovered that one + * of the slaves could be activated earlier, so we do it. + */ + read_lock(&bond->ptrlock); + oldcurrent = bond->current_slave; + read_unlock(&bond->ptrlock); + + /* no active interface at the moment or need to bring up the primary */ + if (oldcurrent == NULL) { /* no active interface at the moment */ + if (bestslave != NULL) { /* last chance to find one ? */ + if (bestslave->link == BOND_LINK_UP) { + printk (KERN_INFO + "%s: making interface %s the new active one.\n", + master->name, bestslave->dev->name); + } else { + printk (KERN_INFO + "%s: making interface %s the new " + "active one %d ms earlier.\n", + master->name, bestslave->dev->name, + (updelay - bestslave->delay) * miimon); + + bestslave->delay = 0; + bestslave->link = BOND_LINK_UP; + bestslave->jiffies = jiffies; + + /* notify ad that the link status has changed */ + if (bond_mode == BOND_MODE_8023AD) { + bond_3ad_handle_link_change(bestslave, BOND_LINK_UP); + } + + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + bond_alb_handle_link_change(bond, bestslave, BOND_LINK_UP); + } + } + + if (bond_mode == BOND_MODE_ACTIVEBACKUP) { + bond_set_slave_active_flags(bestslave); + bond_mc_update(bond, bestslave, NULL); + } else if (bond_mode != BOND_MODE_8023AD) { + bestslave->state = BOND_STATE_ACTIVE; + } + write_lock(&bond->ptrlock); + bond_assign_current_slave(bond, bestslave); + write_unlock(&bond->ptrlock); + } else if (slave_died) { + /* print this message only once a slave has just died */ + printk(KERN_INFO + "%s: now running without any active interface !\n", + master->name); + } + } + + read_unlock(&bond->lock); + /* re-arm the timer */ + mod_timer(&bond->mii_timer, jiffies + (miimon * HZ / 1000)); +} + +/* + * this function is called regularly to monitor each slave's link + * ensuring that traffic is being sent and received when arp monitoring + * is used in load-balancing mode. if the adapter has been dormant, then an + * arp is transmitted to generate traffic. see activebackup_arp_monitor for + * arp monitoring in active backup mode. + */ +static void loadbalance_arp_monitor(struct net_device *master) +{ + bonding_t *bond; + slave_t *slave; + int the_delta_in_ticks = arp_interval * HZ / 1000; + int next_timer = jiffies + (arp_interval * HZ / 1000); + + bond = (struct bonding *) master->priv; + if (master->priv == NULL) { + mod_timer(&bond->arp_timer, next_timer); + return; + } + + /* TODO: investigate why rtnl_shlock_nowait and rtnl_exlock_nowait + * are called below and add comment why they are required... + */ + if ((!IS_UP(master)) || rtnl_shlock_nowait()) { + mod_timer(&bond->arp_timer, next_timer); + return; + } + + if (rtnl_exlock_nowait()) { + rtnl_shunlock(); + mod_timer(&bond->arp_timer, next_timer); + return; + } + + read_lock(&bond->lock); + + /* see if any of the previous devices are up now (i.e. they have + * xmt and rcv traffic). the current_slave does not come into + * the picture unless it is null. also, slave->jiffies is not needed + * here because we send an arp on each slave and give a slave as + * long as it needs to get the tx/rx within the delta. + * TODO: what about up/down delay in arp mode? it wasn't here before + * so it can wait + */ + slave = (slave_t *)bond; + while ((slave = slave->prev) != (slave_t *)bond) { + + if (slave->link != BOND_LINK_UP) { + + if (((jiffies - slave->dev->trans_start) <= + the_delta_in_ticks) && + ((jiffies - slave->dev->last_rx) <= + the_delta_in_ticks)) { + + slave->link = BOND_LINK_UP; + slave->state = BOND_STATE_ACTIVE; + + /* primary_slave has no meaning in round-robin + * mode. the window of a slave being up and + * current_slave being null after enslaving + * is closed. + */ + write_lock(&bond->ptrlock); + if (bond->current_slave == NULL) { + printk(KERN_INFO + "%s: link status definitely up " + "for interface %s, ", + master->name, + slave->dev->name); + change_active_interface(bond); + } else { + printk(KERN_INFO + "%s: interface %s is now up\n", + master->name, + slave->dev->name); + } + write_unlock(&bond->ptrlock); + } + } else { + /* slave->link == BOND_LINK_UP */ + + /* not all switches will respond to an arp request + * when the source ip is 0, so don't take the link down + * if we don't know our ip yet + */ + if (((jiffies - slave->dev->trans_start) >= + (2*the_delta_in_ticks)) || + (((jiffies - slave->dev->last_rx) >= + (2*the_delta_in_ticks)) && my_ip !=0)) { + slave->link = BOND_LINK_DOWN; + slave->state = BOND_STATE_BACKUP; + if (slave->link_failure_count < UINT_MAX) { + slave->link_failure_count++; + } + printk(KERN_INFO + "%s: interface %s is now down.\n", + master->name, + slave->dev->name); + + write_lock(&bond->ptrlock); + if (slave == bond->current_slave) { + change_active_interface(bond); + } + write_unlock(&bond->ptrlock); + } + } + + /* note: if switch is in round-robin mode, all links + * must tx arp to ensure all links rx an arp - otherwise + * links may oscillate or not come up at all; if switch is + * in something like xor mode, there is nothing we can + * do - all replies will be rx'ed on same link causing slaves + * to be unstable during low/no traffic periods + */ + if (IS_UP(slave->dev)) { + arp_send_all(slave); + } + } + + read_unlock(&bond->lock); + rtnl_exunlock(); + rtnl_shunlock(); + + /* re-arm the timer */ + mod_timer(&bond->arp_timer, next_timer); +} + +/* + * When using arp monitoring in active-backup mode, this function is + * called to determine if any backup slaves have went down or a new + * current slave needs to be found. + * The backup slaves never generate traffic, they are considered up by merely + * receiving traffic. If the current slave goes down, each backup slave will + * be given the opportunity to tx/rx an arp before being taken down - this + * prevents all slaves from being taken down due to the current slave not + * sending any traffic for the backups to receive. The arps are not necessarily + * necessary, any tx and rx traffic will keep the current slave up. While any + * rx traffic will keep the backup slaves up, the current slave is responsible + * for generating traffic to keep them up regardless of any other traffic they + * may have received. + * see loadbalance_arp_monitor for arp monitoring in load balancing mode + */ +static void activebackup_arp_monitor(struct net_device *master) +{ + bonding_t *bond; + slave_t *slave; + int the_delta_in_ticks = arp_interval * HZ / 1000; + int next_timer = jiffies + (arp_interval * HZ / 1000); + + bond = (struct bonding *) master->priv; + if (master->priv == NULL) { + mod_timer(&bond->arp_timer, next_timer); + return; + } + + if (!IS_UP(master)) { + mod_timer(&bond->arp_timer, next_timer); + return; + } + + read_lock(&bond->lock); + + /* determine if any slave has come up or any backup slave has + * gone down + * TODO: what about up/down delay in arp mode? it wasn't here before + * so it can wait + */ + slave = (slave_t *)bond; + while ((slave = slave->prev) != (slave_t *)bond) { + + if (slave->link != BOND_LINK_UP) { + if ((jiffies - slave->dev->last_rx) <= + the_delta_in_ticks) { + + slave->link = BOND_LINK_UP; + write_lock(&bond->ptrlock); + if ((bond->current_slave == NULL) && + ((jiffies - slave->dev->trans_start) <= + the_delta_in_ticks)) { + bond_assign_current_slave(bond, slave); + bond_set_slave_active_flags(slave); + bond_mc_update(bond, slave, NULL); + bond->current_arp_slave = NULL; + } else if (bond->current_slave != slave) { + /* this slave has just come up but we + * already have a current slave; this + * can also happen if bond_enslave adds + * a new slave that is up while we are + * searching for a new slave + */ + bond_set_slave_inactive_flags(slave); + bond->current_arp_slave = NULL; + } + + if (slave == bond->current_slave) { + printk(KERN_INFO + "%s: %s is up and now the " + "active interface\n", + master->name, + slave->dev->name); + } else { + printk(KERN_INFO + "%s: backup interface %s is " + "now up\n", + master->name, + slave->dev->name); + } + + write_unlock(&bond->ptrlock); + } + } else { + read_lock(&bond->ptrlock); + if ((slave != bond->current_slave) && + (bond->current_arp_slave == NULL) && + (((jiffies - slave->dev->last_rx) >= + 3*the_delta_in_ticks) && (my_ip != 0))) { + /* a backup slave has gone down; three times + * the delta allows the current slave to be + * taken out before the backup slave. + * note: a non-null current_arp_slave indicates + * the current_slave went down and we are + * searching for a new one; under this + * condition we only take the current_slave + * down - this gives each slave a chance to + * tx/rx traffic before being taken out + */ + read_unlock(&bond->ptrlock); + slave->link = BOND_LINK_DOWN; + if (slave->link_failure_count < UINT_MAX) { + slave->link_failure_count++; + } + bond_set_slave_inactive_flags(slave); + printk(KERN_INFO + "%s: backup interface %s is now down\n", + master->name, + slave->dev->name); + } else { + read_unlock(&bond->ptrlock); + } + } + } + + read_lock(&bond->ptrlock); + slave = bond->current_slave; + read_unlock(&bond->ptrlock); + + if (slave != NULL) { + + /* if we have sent traffic in the past 2*arp_intervals but + * haven't xmit and rx traffic in that time interval, select + * a different slave. slave->jiffies is only updated when + * a slave first becomes the current_slave - not necessarily + * after every arp; this ensures the slave has a full 2*delta + * before being taken out. if a primary is being used, check + * if it is up and needs to take over as the current_slave + */ + if ((((jiffies - slave->dev->trans_start) >= + (2*the_delta_in_ticks)) || + (((jiffies - slave->dev->last_rx) >= + (2*the_delta_in_ticks)) && (my_ip != 0))) && + ((jiffies - slave->jiffies) >= 2*the_delta_in_ticks)) { + + slave->link = BOND_LINK_DOWN; + if (slave->link_failure_count < UINT_MAX) { + slave->link_failure_count++; + } + printk(KERN_INFO "%s: link status down for " + "active interface %s, disabling it", + master->name, + slave->dev->name); + write_lock(&bond->ptrlock); + slave = change_active_interface(bond); + write_unlock(&bond->ptrlock); + bond->current_arp_slave = slave; + if (slave != NULL) { + slave->jiffies = jiffies; + } + + } else if ((bond->primary_slave != NULL) && + (bond->primary_slave != slave) && + (bond->primary_slave->link == BOND_LINK_UP)) { + /* at this point, slave is the current_slave */ + printk(KERN_INFO + "%s: changing from interface %s to primary " + "interface %s\n", + master->name, + slave->dev->name, + bond->primary_slave->dev->name); + + /* primary is up so switch to it */ + bond_set_slave_inactive_flags(slave); + bond_mc_update(bond, bond->primary_slave, slave); + write_lock(&bond->ptrlock); + bond_assign_current_slave(bond, bond->primary_slave); + write_unlock(&bond->ptrlock); + slave = bond->primary_slave; + bond_set_slave_active_flags(slave); + slave->jiffies = jiffies; + } else { + bond->current_arp_slave = NULL; + } + + /* the current slave must tx an arp to ensure backup slaves + * rx traffic + */ + if ((slave != NULL) && (my_ip != 0)) { + arp_send_all(slave); + } + } + + /* if we don't have a current_slave, search for the next available + * backup slave from the current_arp_slave and make it the candidate + * for becoming the current_slave + */ + if (slave == NULL) { + + if ((bond->current_arp_slave == NULL) || + (bond->current_arp_slave == (slave_t *)bond)) { + bond->current_arp_slave = bond->prev; + } + + if (bond->current_arp_slave != (slave_t *)bond) { + bond_set_slave_inactive_flags(bond->current_arp_slave); + slave = bond->current_arp_slave->next; + + /* search for next candidate */ + do { + if (IS_UP(slave->dev)) { + slave->link = BOND_LINK_BACK; + bond_set_slave_active_flags(slave); + arp_send_all(slave); + slave->jiffies = jiffies; + bond->current_arp_slave = slave; + break; + } + + /* if the link state is up at this point, we + * mark it down - this can happen if we have + * simultaneous link failures and + * change_active_interface doesn't make this + * one the current slave so it is still marked + * up when it is actually down + */ + if (slave->link == BOND_LINK_UP) { + slave->link = BOND_LINK_DOWN; + if (slave->link_failure_count < + UINT_MAX) { + slave->link_failure_count++; + } + + bond_set_slave_inactive_flags(slave); + printk(KERN_INFO + "%s: backup interface " + "%s is now down.\n", + master->name, + slave->dev->name); + } + } while ((slave = slave->next) != + bond->current_arp_slave->next); + } + } + + read_unlock(&bond->lock); + mod_timer(&bond->arp_timer, next_timer); +} + +static int bond_sethwaddr(struct net_device *master, struct net_device *slave) +{ +#ifdef BONDING_DEBUG + printk(KERN_CRIT "bond_sethwaddr: master=%x\n", (unsigned int)master); + printk(KERN_CRIT "bond_sethwaddr: slave=%x\n", (unsigned int)slave); + printk(KERN_CRIT "bond_sethwaddr: slave->addr_len=%d\n", slave->addr_len); +#endif + memcpy(master->dev_addr, slave->dev_addr, slave->addr_len); + return 0; +} + +static int bond_info_query(struct net_device *master, struct ifbond *info) +{ + bonding_t *bond = (struct bonding *) master->priv; + slave_t *slave; + + info->bond_mode = bond_mode; + info->num_slaves = 0; + info->miimon = miimon; + + read_lock_bh(&bond->lock); + for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) { + info->num_slaves++; + } + read_unlock_bh(&bond->lock); + + return 0; +} + +static int bond_slave_info_query(struct net_device *master, + struct ifslave *info) +{ + bonding_t *bond = (struct bonding *) master->priv; + slave_t *slave; + int cur_ndx = 0; + + if (info->slave_id < 0) { + return -ENODEV; + } + + read_lock_bh(&bond->lock); + for (slave = bond->prev; + slave != (slave_t *)bond && cur_ndx < info->slave_id; + slave = slave->prev) { + cur_ndx++; + } + read_unlock_bh(&bond->lock); + + if (slave != (slave_t *)bond) { + strcpy(info->slave_name, slave->dev->name); + info->link = slave->link; + info->state = slave->state; + info->link_failure_count = slave->link_failure_count; + } else { + return -ENODEV; + } + + return 0; +} + +static int bond_ethtool_ioctl(struct net_device *master_dev, struct ifreq *ifr) +{ + void *addr = ifr->ifr_data; + uint32_t cmd; + + if (get_user(cmd, (uint32_t *) addr)) + return -EFAULT; + + switch (cmd) { + + case ETHTOOL_GDRVINFO: + { + struct ethtool_drvinfo info; + char *endptr; + + if (copy_from_user(&info, addr, sizeof(info))) + return -EFAULT; + + if (strcmp(info.driver, "ifenslave") == 0) { + int new_abi_ver; + + new_abi_ver = simple_strtoul(info.fw_version, + &endptr, 0); + if (*endptr) { + printk(KERN_ERR + "bonding: Error: got invalid ABI" + " version from application\n"); + + return -EINVAL; + } + + if (orig_app_abi_ver == -1) { + orig_app_abi_ver = new_abi_ver; + } + + app_abi_ver = new_abi_ver; + } + + strncpy(info.driver, DRV_NAME, 32); + strncpy(info.version, DRV_VERSION, 32); + snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION); + + if (copy_to_user(addr, &info, sizeof(info))) + return -EFAULT; + + return 0; + } + break; + default: + return -EOPNOTSUPP; + } +} + +static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd) +{ + struct net_device *slave_dev = NULL; + struct ifbond *u_binfo = NULL, k_binfo; + struct ifslave *u_sinfo = NULL, k_sinfo; + struct mii_ioctl_data *mii = NULL; + int prev_abi_ver = orig_app_abi_ver; + int ret = 0; + +#ifdef BONDING_DEBUG + printk(KERN_INFO "bond_ioctl: master=%s, cmd=%d\n", + master_dev->name, cmd); +#endif + + switch (cmd) { + case SIOCETHTOOL: + return bond_ethtool_ioctl(master_dev, ifr); + + case SIOCGMIIPHY: + mii = (struct mii_ioctl_data *)&ifr->ifr_data; + if (mii == NULL) { + return -EINVAL; + } + mii->phy_id = 0; + /* Fall Through */ + case SIOCGMIIREG: + /* + * We do this again just in case we were called by SIOCGMIIREG + * instead of SIOCGMIIPHY. + */ + mii = (struct mii_ioctl_data *)&ifr->ifr_data; + if (mii == NULL) { + return -EINVAL; + } + if (mii->reg_num == 1) { + mii->val_out = bond_check_mii_link( + (struct bonding *)master_dev->priv); + } + return 0; + case BOND_INFO_QUERY_OLD: + case SIOCBONDINFOQUERY: + u_binfo = (struct ifbond *)ifr->ifr_data; + if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) { + return -EFAULT; + } + ret = bond_info_query(master_dev, &k_binfo); + if (ret == 0) { + if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) { + return -EFAULT; + } + } + return ret; + case BOND_SLAVE_INFO_QUERY_OLD: + case SIOCBONDSLAVEINFOQUERY: + u_sinfo = (struct ifslave *)ifr->ifr_data; + if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) { + return -EFAULT; + } + ret = bond_slave_info_query(master_dev, &k_sinfo); + if (ret == 0) { + if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) { + return -EFAULT; + } + } + return ret; + } + + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + + if (orig_app_abi_ver == -1) { + /* no orig_app_abi_ver was provided yet, so we'll use the + * current one from now on, even if it's 0 + */ + orig_app_abi_ver = app_abi_ver; + + } else if (orig_app_abi_ver != app_abi_ver) { + printk(KERN_ERR + "bonding: Error: already using ifenslave ABI " + "version %d; to upgrade ifenslave to version %d, " + "you must first reload bonding.\n", + orig_app_abi_ver, app_abi_ver); + return -EINVAL; + } + + slave_dev = dev_get_by_name(ifr->ifr_slave); + +#ifdef BONDING_DEBUG + printk(KERN_INFO "slave_dev=%x: \n", (unsigned int)slave_dev); + printk(KERN_INFO "slave_dev->name=%s: \n", slave_dev->name); +#endif + + if (slave_dev == NULL) { + ret = -ENODEV; + } else { + switch (cmd) { + case BOND_ENSLAVE_OLD: + case SIOCBONDENSLAVE: + ret = bond_enslave(master_dev, slave_dev); + break; + case BOND_RELEASE_OLD: + case SIOCBONDRELEASE: + ret = bond_release(master_dev, slave_dev); + break; + case BOND_SETHWADDR_OLD: + case SIOCBONDSETHWADDR: + ret = bond_sethwaddr(master_dev, slave_dev); + break; + case BOND_CHANGE_ACTIVE_OLD: + case SIOCBONDCHANGEACTIVE: + if ((bond_mode == BOND_MODE_ACTIVEBACKUP) || + (bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + ret = bond_change_active(master_dev, slave_dev); + } + else { + ret = -EINVAL; + } + break; + default: + ret = -EOPNOTSUPP; + } + dev_put(slave_dev); + } + + if (ret < 0) { + /* The ioctl failed, so there's no point in changing the + * orig_app_abi_ver. We'll restore it's value just in case + * we've changed it earlier in this function. + */ + orig_app_abi_ver = prev_abi_ver; + } + + return ret; +} + +#ifdef CONFIG_NET_FASTROUTE +static int bond_accept_fastpath(struct net_device *dev, struct dst_entry *dst) +{ + return -1; +} +#endif + +/* + * in broadcast mode, we send everything to all usable interfaces. + */ +static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *dev) +{ + slave_t *slave, *start_at; + struct bonding *bond = (struct bonding *) dev->priv; + struct net_device *device_we_should_send_to = 0; + + if (!IS_UP(dev)) { /* bond down */ + dev_kfree_skb(skb); + return 0; + } + + read_lock(&bond->lock); + + read_lock(&bond->ptrlock); + slave = start_at = bond->current_slave; + read_unlock(&bond->ptrlock); + + if (slave == NULL) { /* we're at the root, get the first slave */ + /* no suitable interface, frame not sent */ + read_unlock(&bond->lock); + dev_kfree_skb(skb); + return 0; + } + + do { + if (IS_UP(slave->dev) + && (slave->link == BOND_LINK_UP) + && (slave->state == BOND_STATE_ACTIVE)) { + if (device_we_should_send_to) { + struct sk_buff *skb2; + if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) { + printk(KERN_ERR "bond_xmit_broadcast: skb_clone() failed\n"); + continue; + } + + skb2->dev = device_we_should_send_to; + skb2->priority = 1; + dev_queue_xmit(skb2); + } + device_we_should_send_to = slave->dev; + } + } while ((slave = slave->next) != start_at); + + if (device_we_should_send_to) { + skb->dev = device_we_should_send_to; + skb->priority = 1; + dev_queue_xmit(skb); + } else + dev_kfree_skb(skb); + + /* frame sent to all suitable interfaces */ + read_unlock(&bond->lock); + return 0; +} + +static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev) +{ + slave_t *slave, *start_at; + struct bonding *bond = (struct bonding *) dev->priv; + + if (!IS_UP(dev)) { /* bond down */ + dev_kfree_skb(skb); + return 0; + } + + read_lock(&bond->lock); + + read_lock(&bond->ptrlock); + slave = start_at = bond->current_slave; + read_unlock(&bond->ptrlock); + + if (slave == NULL) { /* we're at the root, get the first slave */ + /* no suitable interface, frame not sent */ + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + do { + if (IS_UP(slave->dev) + && (slave->link == BOND_LINK_UP) + && (slave->state == BOND_STATE_ACTIVE)) { + + skb->dev = slave->dev; + skb->priority = 1; + dev_queue_xmit(skb); + + write_lock(&bond->ptrlock); + bond_assign_current_slave(bond, slave->next); + write_unlock(&bond->ptrlock); + + read_unlock(&bond->lock); + return 0; + } + } while ((slave = slave->next) != start_at); + + /* no suitable interface, frame not sent */ + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; +} + +/* + * in XOR mode, we determine the output device by performing xor on + * the source and destination hw adresses. If this device is not + * enabled, find the next slave following this xor slave. + */ +static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev) +{ + slave_t *slave, *start_at; + struct bonding *bond = (struct bonding *) dev->priv; + struct ethhdr *data = (struct ethhdr *)skb->data; + int slave_no; + + if (!IS_UP(dev)) { /* bond down */ + dev_kfree_skb(skb); + return 0; + } + + read_lock(&bond->lock); + slave = bond->prev; + + /* we're at the root, get the first slave */ + if (bond->slave_cnt == 0) { + /* no suitable interface, frame not sent */ + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; + } + + slave_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % bond->slave_cnt; + + while ( (slave_no > 0) && (slave != (slave_t *)bond) ) { + slave = slave->prev; + slave_no--; + } + start_at = slave; + + do { + if (IS_UP(slave->dev) + && (slave->link == BOND_LINK_UP) + && (slave->state == BOND_STATE_ACTIVE)) { + + skb->dev = slave->dev; + skb->priority = 1; + dev_queue_xmit(skb); + + read_unlock(&bond->lock); + return 0; + } + } while ((slave = slave->next) != start_at); + + /* no suitable interface, frame not sent */ + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; +} + +/* + * in active-backup mode, we know that bond->current_slave is always valid if + * the bond has a usable interface. + */ +static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev) +{ + struct bonding *bond = (struct bonding *) dev->priv; + int ret; + + if (!IS_UP(dev)) { /* bond down */ + dev_kfree_skb(skb); + return 0; + } + + /* if we are sending arp packets, try to at least + identify our own ip address */ + if ( (arp_interval > 0) && (my_ip == 0) && + (skb->protocol == __constant_htons(ETH_P_ARP) ) ) { + char *the_ip = (((char *)skb->data)) + + sizeof(struct ethhdr) + + sizeof(struct arphdr) + + ETH_ALEN; + memcpy(&my_ip, the_ip, 4); + } + + /* if we are sending arp packets and don't know + * the target hw address, save it so we don't need + * to use a broadcast address. + * don't do this if in active backup mode because the slaves must + * receive packets to stay up, and the only ones they receive are + * broadcasts. + */ + if ( (bond_mode != BOND_MODE_ACTIVEBACKUP) && + (arp_ip_count == 1) && + (arp_interval > 0) && (arp_target_hw_addr == NULL) && + (skb->protocol == __constant_htons(ETH_P_IP) ) ) { + struct ethhdr *eth_hdr = + (struct ethhdr *) (((char *)skb->data)); + struct iphdr *ip_hdr = (struct iphdr *)(eth_hdr + 1); + + if (arp_target[0] == ip_hdr->daddr) { + arp_target_hw_addr = kmalloc(ETH_ALEN, GFP_KERNEL); + if (arp_target_hw_addr != NULL) + memcpy(arp_target_hw_addr, eth_hdr->h_dest, ETH_ALEN); + } + } + + read_lock(&bond->lock); + + read_lock(&bond->ptrlock); + if (bond->current_slave != NULL) { /* one usable interface */ + skb->dev = bond->current_slave->dev; + read_unlock(&bond->ptrlock); + skb->priority = 1; + ret = dev_queue_xmit(skb); + read_unlock(&bond->lock); + return 0; + } + else { + read_unlock(&bond->ptrlock); + } + + /* no suitable interface, frame not sent */ +#ifdef BONDING_DEBUG + printk(KERN_INFO "There was no suitable interface, so we don't transmit\n"); +#endif + dev_kfree_skb(skb); + read_unlock(&bond->lock); + return 0; +} + +static struct net_device_stats *bond_get_stats(struct net_device *dev) +{ + bonding_t *bond = dev->priv; + struct net_device_stats *stats = bond->stats, *sstats; + slave_t *slave; + + memset(bond->stats, 0, sizeof(struct net_device_stats)); + + read_lock_bh(&bond->lock); + + for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) { + sstats = slave->dev->get_stats(slave->dev); + + stats->rx_packets += sstats->rx_packets; + stats->rx_bytes += sstats->rx_bytes; + stats->rx_errors += sstats->rx_errors; + stats->rx_dropped += sstats->rx_dropped; + + stats->tx_packets += sstats->tx_packets; + stats->tx_bytes += sstats->tx_bytes; + stats->tx_errors += sstats->tx_errors; + stats->tx_dropped += sstats->tx_dropped; + + stats->multicast += sstats->multicast; + stats->collisions += sstats->collisions; + + stats->rx_length_errors += sstats->rx_length_errors; + stats->rx_over_errors += sstats->rx_over_errors; + stats->rx_crc_errors += sstats->rx_crc_errors; + stats->rx_frame_errors += sstats->rx_frame_errors; + stats->rx_fifo_errors += sstats->rx_fifo_errors; + stats->rx_missed_errors += sstats->rx_missed_errors; + + stats->tx_aborted_errors += sstats->tx_aborted_errors; + stats->tx_carrier_errors += sstats->tx_carrier_errors; + stats->tx_fifo_errors += sstats->tx_fifo_errors; + stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors; + stats->tx_window_errors += sstats->tx_window_errors; + + } + + read_unlock_bh(&bond->lock); + return stats; +} + +static int bond_get_info(char *buf, char **start, off_t offset, int length) +{ + bonding_t *bond = these_bonds; + int len = 0; + off_t begin = 0; + u16 link; + slave_t *slave = NULL; + + len += sprintf(buf + len, "%s\n", version); + + while (bond != NULL) { + /* + * This function locks the mutex, so we can't lock it until + * afterwards + */ + link = bond_check_mii_link(bond); + + len += sprintf(buf + len, "Bonding Mode: %s\n", + bond_mode_name()); + + if ((bond_mode == BOND_MODE_ACTIVEBACKUP) || + (bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + read_lock_bh(&bond->lock); + read_lock(&bond->ptrlock); + if (bond->current_slave != NULL) { + len += sprintf(buf + len, + "Currently Active Slave: %s\n", + bond->current_slave->dev->name); + } + read_unlock(&bond->ptrlock); + read_unlock_bh(&bond->lock); + } + + len += sprintf(buf + len, "MII Status: "); + len += sprintf(buf + len, + link == BMSR_LSTATUS ? "up\n" : "down\n"); + len += sprintf(buf + len, "MII Polling Interval (ms): %d\n", + miimon); + len += sprintf(buf + len, "Up Delay (ms): %d\n", + updelay * miimon); + len += sprintf(buf + len, "Down Delay (ms): %d\n", + downdelay * miimon); + len += sprintf(buf + len, "Multicast Mode: %s\n", + multicast_mode_name()); + + read_lock_bh(&bond->lock); + + if (bond_mode == BOND_MODE_8023AD) { + struct ad_info ad_info; + + len += sprintf(buf + len, "\n802.3ad info\n"); + + if (bond_3ad_get_active_agg_info(bond, &ad_info)) { + len += sprintf(buf + len, "bond %s has no active aggregator\n", bond->device->name); + } else { + len += sprintf(buf + len, "Active Aggregator Info:\n"); + + len += sprintf(buf + len, "\tAggregator ID: %d\n", ad_info.aggregator_id); + len += sprintf(buf + len, "\tNumber of ports: %d\n", ad_info.ports); + len += sprintf(buf + len, "\tActor Key: %d\n", ad_info.actor_key); + len += sprintf(buf + len, "\tPartner Key: %d\n", ad_info.partner_key); + len += sprintf(buf + len, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n", + ad_info.partner_system[0], + ad_info.partner_system[1], + ad_info.partner_system[2], + ad_info.partner_system[3], + ad_info.partner_system[4], + ad_info.partner_system[5]); + } + } + + for (slave = bond->prev; slave != (slave_t *)bond; + slave = slave->prev) { + len += sprintf(buf + len, "\nSlave Interface: %s\n", slave->dev->name); + + len += sprintf(buf + len, "MII Status: "); + + len += sprintf(buf + len, + slave->link == BOND_LINK_UP ? + "up\n" : "down\n"); + len += sprintf(buf + len, "Link Failure Count: %d\n", + slave->link_failure_count); + + if (app_abi_ver >= 1) { + len += sprintf(buf + len, + "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n", + slave->perm_hwaddr[0], + slave->perm_hwaddr[1], + slave->perm_hwaddr[2], + slave->perm_hwaddr[3], + slave->perm_hwaddr[4], + slave->perm_hwaddr[5]); + } + + if (bond_mode == BOND_MODE_8023AD) { + struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; + + if (agg) { + len += sprintf(buf + len, "Aggregator ID: %d\n", + agg->aggregator_identifier); + } else { + len += sprintf(buf + len, "Aggregator ID: N/A\n"); + } + } + } + read_unlock_bh(&bond->lock); + + /* + * Figure out the calcs for the /proc/net interface + */ + *start = buf + (offset - begin); + len -= (offset - begin); + if (len > length) { + len = length; + } + if (len < 0) { + len = 0; + } + + + bond = bond->next_bond; + } + return len; +} + +static int bond_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct bonding *this_bond = (struct bonding *)these_bonds; + struct bonding *last_bond; + struct net_device *event_dev = (struct net_device *)ptr; + + /* while there are bonds configured */ + while (this_bond != NULL) { + if (this_bond == event_dev->priv ) { + switch (event) { + case NETDEV_UNREGISTER: + /* + * remove this bond from a linked list of + * bonds + */ + if (this_bond == these_bonds) { + these_bonds = this_bond->next_bond; + } else { + for (last_bond = these_bonds; + last_bond != NULL; + last_bond = last_bond->next_bond) { + if (last_bond->next_bond == + this_bond) { + last_bond->next_bond = + this_bond->next_bond; + } + } + } + return NOTIFY_DONE; + + default: + return NOTIFY_DONE; + } + } else if (this_bond->device == event_dev->master) { + switch (event) { + case NETDEV_UNREGISTER: + bond_release(this_bond->device, event_dev); + break; + } + return NOTIFY_DONE; + } + this_bond = this_bond->next_bond; + } + return NOTIFY_DONE; +} + +static struct notifier_block bond_netdev_notifier = { + notifier_call: bond_event, +}; + +static int __init bond_init(struct net_device *dev) +{ + bonding_t *bond, *this_bond, *last_bond; + int count; + +#ifdef BONDING_DEBUG + printk (KERN_INFO "Begin bond_init for %s\n", dev->name); +#endif + bond = kmalloc(sizeof(struct bonding), GFP_KERNEL); + if (bond == NULL) { + return -ENOMEM; + } + memset(bond, 0, sizeof(struct bonding)); + + /* initialize rwlocks */ + rwlock_init(&bond->lock); + rwlock_init(&bond->ptrlock); + + bond->stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); + if (bond->stats == NULL) { + kfree(bond); + return -ENOMEM; + } + memset(bond->stats, 0, sizeof(struct net_device_stats)); + + bond->next = bond->prev = (slave_t *)bond; + bond->current_slave = NULL; + bond->current_arp_slave = NULL; + bond->device = dev; + dev->priv = bond; + + /* Initialize the device structure. */ + switch (bond_mode) { + case BOND_MODE_ACTIVEBACKUP: + dev->hard_start_xmit = bond_xmit_activebackup; + break; + case BOND_MODE_ROUNDROBIN: + dev->hard_start_xmit = bond_xmit_roundrobin; + break; + case BOND_MODE_XOR: + dev->hard_start_xmit = bond_xmit_xor; + break; + case BOND_MODE_BROADCAST: + dev->hard_start_xmit = bond_xmit_broadcast; + break; + case BOND_MODE_8023AD: + dev->hard_start_xmit = bond_3ad_xmit_xor; + break; + case BOND_MODE_TLB: + case BOND_MODE_ALB: + dev->hard_start_xmit = bond_alb_xmit; + break; + default: + printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode); + kfree(bond->stats); + kfree(bond); + return -EINVAL; + } + + dev->get_stats = bond_get_stats; + dev->open = bond_open; + dev->stop = bond_close; + dev->set_multicast_list = set_multicast_list; + dev->do_ioctl = bond_ioctl; + + /* + * Fill in the fields of the device structure with ethernet-generic + * values. + */ + + ether_setup(dev); + + dev->set_mac_address = bond_set_mac_address; + dev->tx_queue_len = 0; + dev->flags |= IFF_MASTER|IFF_MULTICAST; +#ifdef CONFIG_NET_FASTROUTE + dev->accept_fastpath = bond_accept_fastpath; +#endif + + printk(KERN_INFO "%s registered with", dev->name); + if (miimon > 0) { + printk(" MII link monitoring set to %d ms", miimon); + updelay /= miimon; + downdelay /= miimon; + } else { + printk("out MII link monitoring"); + } + printk(", in %s mode.\n", bond_mode_name()); + + printk(KERN_INFO "%s registered with", dev->name); + if (arp_interval > 0) { + printk(" ARP monitoring set to %d ms with %d target(s):", + arp_interval, arp_ip_count); + for (count=0 ; countbond_proc_dir = proc_mkdir(dev->name, proc_net); + if (bond->bond_proc_dir == NULL) { + printk(KERN_ERR "%s: Cannot init /proc/net/%s/\n", + dev->name, dev->name); + kfree(bond->stats); + kfree(bond); + return -ENOMEM; + } + bond->bond_proc_info_file = + create_proc_info_entry("info", 0, bond->bond_proc_dir, + bond_get_info); + if (bond->bond_proc_info_file == NULL) { + printk(KERN_ERR "%s: Cannot init /proc/net/%s/info\n", + dev->name, dev->name); + remove_proc_entry(dev->name, proc_net); + kfree(bond->stats); + kfree(bond); + return -ENOMEM; + } +#endif /* CONFIG_PROC_FS */ + + if (first_pass == 1) { + these_bonds = bond; + register_netdevice_notifier(&bond_netdev_notifier); + first_pass = 0; + } else { + last_bond = these_bonds; + this_bond = these_bonds->next_bond; + while (this_bond != NULL) { + last_bond = this_bond; + this_bond = this_bond->next_bond; + } + last_bond->next_bond = bond; + } + + return 0; +} + +/* +static int __init bond_probe(struct net_device *dev) +{ + bond_init(dev); + return 0; +} + */ + +/* + * Convert string input module parms. Accept either the + * number of the mode or its string name. + */ +static inline int +bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) +{ + int i; + + for (i = 0; tbl[i].modename != NULL; i++) { + if ((isdigit(*mode_arg) && + tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || + (0 == strncmp(mode_arg, tbl[i].modename, + strlen(tbl[i].modename)))) { + return tbl[i].mode; + } + } + + return -1; +} + + +static int __init bonding_init(void) +{ + int no; + int err; + + /* Find a name for this unit */ + static struct net_device *dev_bond = NULL; + + printk(KERN_INFO "%s", version); + + /* + * Convert string parameters. + */ + if (mode) { + bond_mode = bond_parse_parm(mode, bond_mode_tbl); + if (bond_mode == -1) { + printk(KERN_WARNING + "bonding_init(): Invalid bonding mode \"%s\"\n", + mode == NULL ? "NULL" : mode); + return -EINVAL; + } + } + + if (multicast) { + multicast_mode = bond_parse_parm(multicast, bond_mc_tbl); + if (multicast_mode == -1) { + printk(KERN_WARNING + "bonding_init(): Invalid multicast mode \"%s\"\n", + multicast == NULL ? "NULL" : multicast); + return -EINVAL; + } + } + + if (lacp_rate) { + if (bond_mode != BOND_MODE_8023AD) { + printk(KERN_WARNING + "lacp_rate param is irrelevant in mode %s\n", + bond_mode_name()); + } else { + lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl); + if (lacp_fast == -1) { + printk(KERN_WARNING + "bonding_init(): Invalid lacp rate " + "\"%s\"\n", + lacp_rate == NULL ? "NULL" : lacp_rate); + + return -EINVAL; + } + } + } + + if (max_bonds < 1 || max_bonds > INT_MAX) { + printk(KERN_WARNING + "bonding_init(): max_bonds (%d) not in range %d-%d, " + "so it was reset to BOND_DEFAULT_MAX_BONDS (%d)", + max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS); + max_bonds = BOND_DEFAULT_MAX_BONDS; + } + dev_bond = dev_bonds = kmalloc(max_bonds*sizeof(struct net_device), + GFP_KERNEL); + if (dev_bond == NULL) { + return -ENOMEM; + } + memset(dev_bonds, 0, max_bonds*sizeof(struct net_device)); + + if (miimon < 0) { + printk(KERN_WARNING + "bonding_init(): miimon module parameter (%d), " + "not in range 0-%d, so it was reset to %d\n", + miimon, INT_MAX, BOND_LINK_MON_INTERV); + miimon = BOND_LINK_MON_INTERV; + } + + if (updelay < 0) { + printk(KERN_WARNING + "bonding_init(): updelay module parameter (%d), " + "not in range 0-%d, so it was reset to 0\n", + updelay, INT_MAX); + updelay = 0; + } + + if (downdelay < 0) { + printk(KERN_WARNING + "bonding_init(): downdelay module parameter (%d), " + "not in range 0-%d, so it was reset to 0\n", + downdelay, INT_MAX); + downdelay = 0; + } + + /* reset values for 802.3ad */ + if (bond_mode == BOND_MODE_8023AD) { + if (arp_interval != 0) { + printk(KERN_WARNING "bonding_init(): ARP monitoring" + "can't be used simultaneously with 802.3ad, " + "disabling ARP monitoring\n"); + arp_interval = 0; + } + + if (miimon == 0) { + printk(KERN_ERR + "bonding_init(): miimon must be specified, " + "otherwise bonding will not detect link failure, " + "speed and duplex which are essential " + "for 802.3ad operation\n"); + printk(KERN_ERR "Forcing miimon to 100msec\n"); + miimon = 100; + } + + if (multicast_mode != BOND_MULTICAST_ALL) { + printk(KERN_ERR + "bonding_init(): Multicast mode must " + "be set to ALL for 802.3ad\n"); + printk(KERN_ERR "Forcing Multicast mode to ALL\n"); + multicast_mode = BOND_MULTICAST_ALL; + } + } + + /* reset values for TLB/ALB */ + if ((bond_mode == BOND_MODE_TLB) || + (bond_mode == BOND_MODE_ALB)) { + if (miimon == 0) { + printk(KERN_ERR + "bonding_init(): miimon must be specified, " + "otherwise bonding will not detect link failure " + "and link speed which are essential " + "for TLB/ALB load balancing\n"); + printk(KERN_ERR "Forcing miimon to 100msec\n"); + miimon = 100; + } + + if (multicast_mode != BOND_MULTICAST_ACTIVE) { + printk(KERN_ERR + "bonding_init(): Multicast mode must " + "be set to ACTIVE for TLB/ALB\n"); + printk(KERN_ERR "Forcing Multicast mode to ACTIVE\n"); + multicast_mode = BOND_MULTICAST_ACTIVE; + } + } + + if (bond_mode == BOND_MODE_ALB) { + printk(KERN_INFO + "In ALB mode you might experience client disconnections" + " upon reconnection of a link if the bonding module" + " updelay parameter (%d msec) is incompatible with the" + " forwarding delay time of the switch\n", updelay); + } + + if (miimon == 0) { + if ((updelay != 0) || (downdelay != 0)) { + /* just warn the user the up/down delay will have + * no effect since miimon is zero... + */ + printk(KERN_WARNING + "bonding_init(): miimon module parameter not " + "set and updelay (%d) or downdelay (%d) module " + "parameter is set; updelay and downdelay have " + "no effect unless miimon is set\n", + updelay, downdelay); + } + } else { + /* don't allow arp monitoring */ + if (arp_interval != 0) { + printk(KERN_WARNING + "bonding_init(): miimon (%d) and arp_interval " + "(%d) can't be used simultaneously, " + "disabling ARP monitoring\n", + miimon, arp_interval); + arp_interval = 0; + } + + if ((updelay % miimon) != 0) { + /* updelay will be rounded in bond_init() when it + * is divided by miimon, we just inform user here + */ + printk(KERN_WARNING + "bonding_init(): updelay (%d) is not a multiple " + "of miimon (%d), updelay rounded to %d ms\n", + updelay, miimon, (updelay / miimon) * miimon); + } + + if ((downdelay % miimon) != 0) { + /* downdelay will be rounded in bond_init() when it + * is divided by miimon, we just inform user here + */ + printk(KERN_WARNING + "bonding_init(): downdelay (%d) is not a " + "multiple of miimon (%d), downdelay rounded " + "to %d ms\n", + downdelay, miimon, + (downdelay / miimon) * miimon); + } + } + + if (arp_interval < 0) { + printk(KERN_WARNING + "bonding_init(): arp_interval module parameter (%d), " + "not in range 0-%d, so it was reset to %d\n", + arp_interval, INT_MAX, BOND_LINK_ARP_INTERV); + arp_interval = BOND_LINK_ARP_INTERV; + } + + for (arp_ip_count=0 ; + (arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count]; + arp_ip_count++ ) { + /* not complete check, but should be good enough to + catch mistakes */ + if (!isdigit(arp_ip_target[arp_ip_count][0])) { + printk(KERN_WARNING + "bonding_init(): bad arp_ip_target module " + "parameter (%s), ARP monitoring will not be " + "performed\n", + arp_ip_target[arp_ip_count]); + arp_interval = 0; + } else { + u32 ip = in_aton(arp_ip_target[arp_ip_count]); + arp_target[arp_ip_count] = ip; + } + } + + + if ( (arp_interval > 0) && (arp_ip_count==0)) { + /* don't allow arping if no arp_ip_target given... */ + printk(KERN_WARNING + "bonding_init(): arp_interval module parameter " + "(%d) specified without providing an arp_ip_target " + "parameter, arp_interval was reset to 0\n", + arp_interval); + arp_interval = 0; + } + + if ((miimon == 0) && (arp_interval == 0)) { + /* miimon and arp_interval not set, we need one so things + * work as expected, see bonding.txt for details + */ + printk(KERN_ERR + "bonding_init(): either miimon or " + "arp_interval and arp_ip_target module parameters " + "must be specified, otherwise bonding will not detect " + "link failures! see bonding.txt for details.\n"); + } + + if ((primary != NULL) && (bond_mode != BOND_MODE_ACTIVEBACKUP) && + (bond_mode != BOND_MODE_TLB) && + (bond_mode != BOND_MODE_ALB)){ + /* currently, using a primary only makes sense + * in active backup, TLB or ALB modes + */ + printk(KERN_WARNING + "bonding_init(): %s primary device specified but has " + "no effect in %s mode\n", + primary, bond_mode_name()); + primary = NULL; + } + + + for (no = 0; no < max_bonds; no++) { + dev_bond->init = bond_init; + + err = dev_alloc_name(dev_bond,"bond%d"); + if (err < 0) { + kfree(dev_bonds); + return err; + } + SET_MODULE_OWNER(dev_bond); + if (register_netdev(dev_bond) != 0) { + kfree(dev_bonds); + return -EIO; + } + dev_bond++; + } + return 0; +} + +static void __exit bonding_exit(void) +{ + struct net_device *dev_bond = dev_bonds; + struct bonding *bond; + int no; + + unregister_netdevice_notifier(&bond_netdev_notifier); + + for (no = 0; no < max_bonds; no++) { + +#ifdef CONFIG_PROC_FS + bond = (struct bonding *) dev_bond->priv; + remove_proc_entry("info", bond->bond_proc_dir); + remove_proc_entry(dev_bond->name, proc_net); +#endif + unregister_netdev(dev_bond); + kfree(bond->stats); + kfree(dev_bond->priv); + + dev_bond->priv = NULL; + dev_bond++; + } + kfree(dev_bonds); +} + +module_init(bonding_init); +module_exit(bonding_exit); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION); + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -urN linux-2.4.21/drivers/net/bonding/bonding.h linux-2.4.22/drivers/net/bonding/bonding.h --- linux-2.4.21/drivers/net/bonding/bonding.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/bonding/bonding.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,181 @@ +/* + * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'. + * + * Portions are (c) Copyright 1995 Simon "Guru Aleph-Null" Janes + * NCM: Network and Communications Management, Inc. + * + * BUT, I'm the one who modified it for ethernet, so: + * (c) Copyright 1999, Thomas Davis, tadavis@lbl.gov + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + * + * + * 2003/03/18 - Amir Noam , + * Tsippy Mendelson and + * Shmulik Hen + * - Added support for IEEE 802.3ad Dynamic link aggregation mode. + * + * 2003/05/01 - Tsippy Mendelson and + * Amir Noam + * - Code beautification and style changes (mainly in comments). + * + * 2003/05/01 - Shmulik Hen + * - Added support for Transmit load balancing mode. + */ + +#ifndef _LINUX_BONDING_H +#define _LINUX_BONDING_H + +#include +#include +#include "bond_3ad.h" +#include "bond_alb.h" + +#ifdef BONDING_DEBUG + +// use this like so: BOND_PRINT_DBG(("foo = %d, bar = %d", foo, bar)); +#define BOND_PRINT_DBG(X) \ +do { \ + printk(KERN_DEBUG "%s (%d)", __FUNCTION__, __LINE__); \ + printk X; \ + printk("\n"); \ +} while(0) + +#else +#define BOND_PRINT_DBG(X) +#endif /* BONDING_DEBUG */ + +#define IS_UP(dev) ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \ + (netif_running(dev) && netif_carrier_ok(dev))) + +/* Checks whether the dev is ready for transmit. We do not check netif_running + * since a device can be stopped by the driver for short periods of time for + * maintainance. dev_queue_xmit() handles this by queing the packet until the + * the dev is running again. Keeping packets ordering requires sticking the + * same dev as much as possible + */ +#define SLAVE_IS_OK(slave) \ + ((((slave)->dev->flags & (IFF_UP)) == (IFF_UP)) && \ + netif_carrier_ok((slave)->dev) && \ + ((slave)->link == BOND_LINK_UP) && \ + ((slave)->state == BOND_STATE_ACTIVE)) + + +typedef struct slave { + struct slave *next; + struct slave *prev; + struct net_device *dev; + short delay; + unsigned long jiffies; + char link; /* one of BOND_LINK_XXXX */ + char state; /* one of BOND_STATE_XXXX */ + unsigned short original_flags; + u32 link_failure_count; + u16 speed; + u8 duplex; + u8 perm_hwaddr[ETH_ALEN]; + struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ + struct tlb_slave_info tlb_info; +} slave_t; + +/* + * Here are the locking policies for the two bonding locks: + * + * 1) Get bond->lock when reading/writing slave list. + * 2) Get bond->ptrlock when reading/writing bond->current_slave. + * (It is unnecessary when the write-lock is put with bond->lock.) + * 3) When we lock with bond->ptrlock, we must lock with bond->lock + * beforehand. + */ +typedef struct bonding { + slave_t *next; + slave_t *prev; + slave_t *current_slave; + slave_t *primary_slave; + slave_t *current_arp_slave; + __s32 slave_cnt; + rwlock_t lock; + rwlock_t ptrlock; + struct timer_list mii_timer; + struct timer_list arp_timer; + struct net_device_stats *stats; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *bond_proc_dir; + struct proc_dir_entry *bond_proc_info_file; +#endif /* CONFIG_PROC_FS */ + struct bonding *next_bond; + struct net_device *device; + struct dev_mc_list *mc_list; + unsigned short flags; + struct ad_bond_info ad_info; + struct alb_bond_info alb_info; +} bonding_t; + +/* Forward declarations */ +void bond_set_slave_active_flags(slave_t *slave); +void bond_set_slave_inactive_flags(slave_t *slave); + +/** + * These functions can be used for iterating the slave list + * (which is circular) + * Caller must hold bond lock for read + */ +extern inline struct slave* +bond_get_first_slave(struct bonding *bond) +{ + /* if there are no slaves return NULL */ + if (bond->next == (slave_t *)bond) { + return NULL; + } + return bond->next; +} + +/** + * Caller must hold bond lock for read + */ +extern inline struct slave* +bond_get_next_slave(struct bonding *bond, struct slave *slave) +{ + /* If we have reached the last slave return NULL */ + if (slave->next == bond->next) { + return NULL; + } + return slave->next; +} + +/** + * Returns NULL if the net_device does not belong to any of the bond's slaves + * + * Caller must hold bond lock for read + */ +extern inline struct slave* +bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev) +{ + struct slave *our_slave = bond->next; + + /* check if the list of slaves is empty */ + if (our_slave == (slave_t *)bond) { + return NULL; + } + + for (; our_slave; our_slave = bond_get_next_slave(bond, our_slave)) { + if (our_slave->dev == slave_dev) { + break; + } + } + return our_slave; +} + +extern inline struct bonding* +bond_get_bond_by_slave(struct slave *slave) +{ + if (!slave || !slave->dev->master) { + return NULL; + } + + return (struct bonding *)(slave->dev->master->priv); +} + +#endif /* _LINUX_BONDING_H */ + diff -urN linux-2.4.21/drivers/net/bonding.c linux-2.4.22/drivers/net/bonding.c --- linux-2.4.21/drivers/net/bonding.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/bonding.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,3302 +0,0 @@ -/* - * originally based on the dummy device. - * - * Copyright 1999, Thomas Davis, tadavis@lbl.gov. - * Licensed under the GPL. Based on dummy.c, and eql.c devices. - * - * bonding.c: an Ethernet Bonding driver - * - * This is useful to talk to a Cisco EtherChannel compatible equipment: - * Cisco 5500 - * Sun Trunking (Solaris) - * Alteon AceDirector Trunks - * Linux Bonding - * and probably many L2 switches ... - * - * How it works: - * ifconfig bond0 ipaddress netmask up - * will setup a network device, with an ip address. No mac address - * will be assigned at this time. The hw mac address will come from - * the first slave bonded to the channel. All slaves will then use - * this hw mac address. - * - * ifconfig bond0 down - * will release all slaves, marking them as down. - * - * ifenslave bond0 eth0 - * will attach eth0 to bond0 as a slave. eth0 hw mac address will either - * a: be used as initial mac address - * b: if a hw mac address already is there, eth0's hw mac address - * will then be set from bond0. - * - * v0.1 - first working version. - * v0.2 - changed stats to be calculated by summing slaves stats. - * - * Changes: - * Arnaldo Carvalho de Melo - * - fix leaks on failure at bond_init - * - * 2000/09/30 - Willy Tarreau - * - added trivial code to release a slave device. - * - fixed security bug (CAP_NET_ADMIN not checked) - * - implemented MII link monitoring to disable dead links : - * All MII capable slaves are checked every milliseconds - * (100 ms seems good). This value can be changed by passing it to - * insmod. A value of zero disables the monitoring (default). - * - fixed an infinite loop in bond_xmit_roundrobin() when there's no - * good slave. - * - made the code hopefully SMP safe - * - * 2000/10/03 - Willy Tarreau - * - optimized slave lists based on relevant suggestions from Thomas Davis - * - implemented active-backup method to obtain HA with two switches: - * stay as long as possible on the same active interface, while we - * also monitor the backup one (MII link status) because we want to know - * if we are able to switch at any time. ( pass "mode=1" to insmod ) - * - lots of stress testings because we need it to be more robust than the - * wires ! :-> - * - * 2000/10/09 - Willy Tarreau - * - added up and down delays after link state change. - * - optimized the slaves chaining so that when we run forward, we never - * repass through the bond itself, but we can find it by searching - * backwards. Renders the deletion more difficult, but accelerates the - * scan. - * - smarter enslaving and releasing. - * - finer and more robust SMP locking - * - * 2000/10/17 - Willy Tarreau - * - fixed two potential SMP race conditions - * - * 2000/10/18 - Willy Tarreau - * - small fixes to the monitoring FSM in case of zero delays - * 2000/11/01 - Willy Tarreau - * - fixed first slave not automatically used in trunk mode. - * 2000/11/10 : spelling of "EtherChannel" corrected. - * 2000/11/13 : fixed a race condition in case of concurrent accesses to ioctl(). - * 2000/12/16 : fixed improper usage of rtnl_exlock_nowait(). - * - * 2001/1/3 - Chad N. Tindel - * - The bonding driver now simulates MII status monitoring, just like - * a normal network device. It will show that the link is down iff - * every slave in the bond shows that their links are down. If at least - * one slave is up, the bond's MII status will appear as up. - * - * 2001/2/7 - Chad N. Tindel - * - Applications can now query the bond from user space to get - * information which may be useful. They do this by calling - * the BOND_INFO_QUERY ioctl. Once the app knows how many slaves - * are in the bond, it can call the BOND_SLAVE_INFO_QUERY ioctl to - * get slave specific information (# link failures, etc). See - * for more details. The structs of interest - * are ifbond and ifslave. - * - * 2001/4/5 - Chad N. Tindel - * - Ported to 2.4 Kernel - * - * 2001/5/2 - Jeffrey E. Mast - * - When a device is detached from a bond, the slave device is no longer - * left thinking that is has a master. - * - * 2001/5/16 - Jeffrey E. Mast - * - memset did not appropriately initialized the bond rw_locks. Used - * rwlock_init to initialize to unlocked state to prevent deadlock when - * first attempting a lock - * - Called SET_MODULE_OWNER for bond device - * - * 2001/5/17 - Tim Anderson - * - 2 paths for releasing for slave release; 1 through ioctl - * and 2) through close. Both paths need to release the same way. - * - the free slave in bond release is changing slave status before - * the free. The netdev_set_master() is intended to change slave state - * so it should not be done as part of the release process. - * - Simple rule for slave state at release: only the active in A/B and - * only one in the trunked case. - * - * 2001/6/01 - Tim Anderson - * - Now call dev_close when releasing a slave so it doesn't screw up - * out routing table. - * - * 2001/6/01 - Chad N. Tindel - * - Added /proc support for getting bond and slave information. - * Information is in /proc/net//info. - * - Changed the locking when calling bond_close to prevent deadlock. - * - * 2001/8/05 - Janice Girouard - * - correct problem where refcnt of slave is not incremented in bond_ioctl - * so the system hangs when halting. - * - correct locking problem when unable to malloc in bond_enslave. - * - adding bond_xmit_xor logic. - * - adding multiple bond device support. - * - * 2001/8/13 - Erik Habbinga - * - correct locking problem with rtnl_exlock_nowait - * - * 2001/8/23 - Janice Girouard - * - bzero initial dev_bonds, to correct oops - * - convert SIOCDEVPRIVATE to new MII ioctl calls - * - * 2001/9/13 - Takao Indoh - * - Add the BOND_CHANGE_ACTIVE ioctl implementation - * - * 2001/9/14 - Mark Huth - * - Change MII_LINK_READY to not check for end of auto-negotiation, - * but only for an up link. - * - * 2001/9/20 - Chad N. Tindel - * - Add the device field to bonding_t. Previously the net_device - * corresponding to a bond wasn't available from the bonding_t - * structure. - * - * 2001/9/25 - Janice Girouard - * - add arp_monitor for active backup mode - * - * 2001/10/23 - Takao Indoh - * - Various memory leak fixes - * - * 2001/11/5 - Mark Huth - * - Don't take rtnl lock in bond_mii_monitor as it deadlocks under - * certain hotswap conditions. - * Note: this same change may be required in bond_arp_monitor ??? - * - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr - * - Handle hot swap ethernet interface deregistration events to remove - * kernel oops following hot swap of enslaved interface - * - * 2002/1/2 - Chad N. Tindel - * - Restore original slave flags at release time. - * - * 2002/02/18 - Erik Habbinga - * - bond_release(): calling kfree on our_slave after call to - * bond_restore_slave_flags, not before - * - bond_enslave(): saving slave flags into original_flags before - * call to netdev_set_master, so the IFF_SLAVE flag doesn't end - * up in original_flags - * - * 2002/04/05 - Mark Smith and - * Steve Mead - * - Port Gleb Natapov's multicast support patchs from 2.4.12 - * to 2.4.18 adding support for multicast. - * - * 2002/06/10 - Tony Cureington - * - corrected uninitialized pointer (ifr.ifr_data) in bond_check_dev_link; - * actually changed function to use MIIPHY, then MIIREG, and finally - * ETHTOOL to determine the link status - * - fixed bad ifr_data pointer assignments in bond_ioctl - * - corrected mode 1 being reported as active-backup in bond_get_info; - * also added text to distinguish type of load balancing (rr or xor) - * - change arp_ip_target module param from "1-12s" (array of 12 ptrs) - * to "s" (a single ptr) - * - * 2002/08/30 - Jay Vosburgh - * - Removed acquisition of xmit_lock in set_multicast_list; caused - * deadlock on SMP (lock is held by caller). - * - Revamped SIOCGMIIPHY, SIOCGMIIREG portion of bond_check_dev_link(). - * - * 2002/09/18 - Jay Vosburgh - * - Fixed up bond_check_dev_link() (and callers): removed some magic - * numbers, banished local MII_ defines, wrapped ioctl calls to - * prevent EFAULT errors - * - * 2002/9/30 - Jay Vosburgh - * - make sure the ip target matches the arp_target before saving the - * hw address. - * - * 2002/9/30 - Dan Eisner - * - make sure my_ip is set before taking down the link, since - * not all switches respond if the source ip is not set. - * - * 2002/10/8 - Janice Girouard - * - read in the local ip address when enslaving a device - * - add primary support - * - make sure 2*arp_interval has passed when a new device - * is brought on-line before taking it down. - * - * 2002/09/11 - Philippe De Muyter - * - Added bond_xmit_broadcast logic. - * - Added bond_mode() support function. - * - * 2002/10/26 - Laurent Deniel - * - allow to register multicast addresses only on active slave - * (useful in active-backup mode) - * - add multicast module parameter - * - fix deletion of multicast groups after unloading module - * - * 2002/11/06 - Kameshwara Rayaprolu - * - Changes to prevent panic from closing the device twice; if we close - * the device in bond_release, we must set the original_flags to down - * so it won't be closed again by the network layer. - * - * 2002/11/07 - Tony Cureington - * - Fix arp_target_hw_addr memory leak - * - Created activebackup_arp_monitor function to handle arp monitoring - * in active backup mode - the bond_arp_monitor had several problems... - * such as allowing slaves to tx arps sequentially without any delay - * for a response - * - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote - * this function to just handle arp monitoring in load-balancing mode; - * it is a lot more compact now - * - Changes to ensure one and only one slave transmits in active-backup - * mode - * - Robustesize parameters; warn users about bad combinations of - * parameters; also if miimon is specified and a network driver does - * not support MII or ETHTOOL, inform the user of this - * - Changes to support link_failure_count when in arp monitoring mode - * - Fix up/down delay reported in /proc - * - Added version; log version; make version available from "modinfo -d" - * - Fixed problem in bond_check_dev_link - if the first IOCTL (SIOCGMIIPH) - * failed, the ETHTOOL ioctl never got a chance - * - * 2002/11/16 - Laurent Deniel - * - fix multicast handling in activebackup_arp_monitor - * - remove one unnecessary and confusing current_slave == slave test - * in activebackup_arp_monitor - * - * 2002/11/17 - Laurent Deniel - * - fix bond_slave_info_query when slave_id = num_slaves - * - * 2002/11/19 - Janice Girouard - * - correct ifr_data reference. Update ifr_data reference - * to mii_ioctl_data struct values to avoid confusion. - * - * 2002/11/22 - Bert Barbe - * - Add support for multiple arp_ip_target - * - * 2002/12/13 - Jay Vosburgh - * - Changed to allow text strings for mode and multicast, e.g., - * insmod bonding mode=active-backup. The numbers still work. - * One change: an invalid choice will cause module load failure, - * rather than the previous behavior of just picking one. - * - Minor cleanups; got rid of dup ctype stuff, atoi function - * - * 2003/02/07 - Jay Vosburgh - * - Added use_carrier module parameter that causes miimon to - * use netif_carrier_ok() test instead of MII/ETHTOOL ioctls. - * - Minor cleanups; consolidated ioctl calls to one function. - * - * 2003/02/07 - Tony Cureington - * - Fix bond_mii_monitor() logic error that could result in - * bonding round-robin mode ignoring links after failover/recovery - * - * 2003/03/17 - Jay Vosburgh - * - kmalloc fix (GPF_KERNEL to GPF_ATOMIC) reported by - * Shmulik dot Hen at intel.com. - * - Based on discussion on mailing list, changed use of - * update_slave_cnt(), created wrapper functions for adding/removing - * slaves, changed bond_xmit_xor() to check slave_cnt instead of - * checking slave and slave->dev (which only worked by accident). - * - Misc code cleanup: get arp_send() prototype from header file, - * add max_bonds to bonding.txt. - * - * 2003/03/18 - Tsippy Mendelson and - * Shmulik Hen - * - Make sure only bond_attach_slave() and bond_detach_slave() can - * manipulate the slave list, including slave_cnt, even when in - * bond_release_all(). - * - Fixed hang in bond_release() while traffic is running. - * netdev_set_master() must not be called from within the bond lock. - * - * 2003/03/18 - Tsippy Mendelson and - * Shmulik Hen - * - Fixed hang in bond_enslave(): netdev_set_master() must not be - * called from within the bond lock while traffic is running. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define DRV_VERSION "2.4.20-20030320" -#define DRV_RELDATE "March 20, 2003" -#define DRV_NAME "bonding" -#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" - -static const char *version = -DRV_NAME ".c:v" DRV_VERSION " (" DRV_RELDATE ")\n"; - -/* monitor all links that often (in milliseconds). <=0 disables monitoring */ -#ifndef BOND_LINK_MON_INTERV -#define BOND_LINK_MON_INTERV 0 -#endif - -#ifndef BOND_LINK_ARP_INTERV -#define BOND_LINK_ARP_INTERV 0 -#endif - -#ifndef MAX_ARP_IP_TARGETS -#define MAX_ARP_IP_TARGETS 16 -#endif - -static int arp_interval = BOND_LINK_ARP_INTERV; -static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, }; -static unsigned long arp_target[MAX_ARP_IP_TARGETS] = { 0, } ; -static int arp_ip_count = 0; -static u32 my_ip = 0; -char *arp_target_hw_addr = NULL; - -static char *primary= NULL; - -static int max_bonds = BOND_DEFAULT_MAX_BONDS; -static int miimon = BOND_LINK_MON_INTERV; -static int use_carrier = 1; -static int bond_mode = BOND_MODE_ROUNDROBIN; -static int updelay = 0; -static int downdelay = 0; - -static char *mode = NULL; - -static struct bond_parm_tbl bond_mode_tbl[] = { -{ "balance-rr", BOND_MODE_ROUNDROBIN}, -{ "active-backup", BOND_MODE_ACTIVEBACKUP}, -{ "balance-xor", BOND_MODE_XOR}, -{ "broadcast", BOND_MODE_BROADCAST}, -{ NULL, -1}, -}; - -static int multicast_mode = BOND_MULTICAST_ALL; -static char *multicast = NULL; - -static struct bond_parm_tbl bond_mc_tbl[] = { -{ "disabled", BOND_MULTICAST_DISABLED}, -{ "active", BOND_MULTICAST_ACTIVE}, -{ "all", BOND_MULTICAST_ALL}, -{ NULL, -1}, -}; - -static int first_pass = 1; -static struct bonding *these_bonds = NULL; -static struct net_device *dev_bonds = NULL; - -MODULE_PARM(max_bonds, "i"); -MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); -MODULE_PARM(miimon, "i"); -MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); -MODULE_PARM(use_carrier, "i"); -MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 09 for off, 1 for on (default)"); -MODULE_PARM(mode, "s"); -MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor"); -MODULE_PARM(arp_interval, "i"); -MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); -MODULE_PARM(arp_ip_target, "1-" __MODULE_STRING(MAX_ARP_IP_TARGETS) "s"); -MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); -MODULE_PARM(updelay, "i"); -MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds"); -MODULE_PARM(downdelay, "i"); -MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds"); -MODULE_PARM(primary, "s"); -MODULE_PARM_DESC(primary, "Primary network device to use"); -MODULE_PARM(multicast, "s"); -MODULE_PARM_DESC(multicast, "Mode for multicast support : 0 for none, 1 for active slave, 2 for all slaves (default)"); - -static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev); -static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev); -static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *bond_get_stats(struct net_device *dev); -static void bond_mii_monitor(struct net_device *dev); -static void loadbalance_arp_monitor(struct net_device *dev); -static void activebackup_arp_monitor(struct net_device *dev); -static int bond_event(struct notifier_block *this, unsigned long event, void *ptr); -static void bond_restore_slave_flags(slave_t *slave); -static void bond_mc_list_destroy(struct bonding *bond); -static void bond_mc_add(bonding_t *bond, void *addr, int alen); -static void bond_mc_delete(bonding_t *bond, void *addr, int alen); -static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst, int gpf_flag); -static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2); -static void bond_set_promiscuity(bonding_t *bond, int inc); -static void bond_set_allmulti(bonding_t *bond, int inc); -static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list); -static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old); -static void bond_set_slave_inactive_flags(slave_t *slave); -static void bond_set_slave_active_flags(slave_t *slave); -static int bond_enslave(struct net_device *master, struct net_device *slave); -static int bond_release(struct net_device *master, struct net_device *slave); -static int bond_release_all(struct net_device *master); -static int bond_sethwaddr(struct net_device *master, struct net_device *slave); - -/* - * bond_get_info is the interface into the /proc filesystem. This is - * a different interface than the BOND_INFO_QUERY ioctl. That is done - * through the generic networking ioctl interface, and bond_info_query - * is the internal function which provides that information. - */ -static int bond_get_info(char *buf, char **start, off_t offset, int length); - -/* #define BONDING_DEBUG 1 */ - -/* several macros */ - -#define IS_UP(dev) ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \ - (netif_running(dev) && netif_carrier_ok(dev))) - -static void arp_send_all(slave_t *slave) -{ - int i; - - for (i = 0; (idev, - my_ip, arp_target_hw_addr, slave->dev->dev_addr, - arp_target_hw_addr); - } -} - - -static const char * -bond_mode_name(void) -{ - switch (bond_mode) { - case BOND_MODE_ROUNDROBIN : - return "load balancing (round-robin)"; - case BOND_MODE_ACTIVEBACKUP : - return "fault-tolerance (active-backup)"; - case BOND_MODE_XOR : - return "load balancing (xor)"; - case BOND_MODE_BROADCAST : - return "fault-tolerance (broadcast)"; - default : - return "unknown"; - } -} - -static const char * -multicast_mode_name(void) -{ - switch(multicast_mode) { - case BOND_MULTICAST_DISABLED : - return "disabled"; - case BOND_MULTICAST_ACTIVE : - return "active slave only"; - case BOND_MULTICAST_ALL : - return "all slaves"; - default : - return "unknown"; - } -} - -static void bond_restore_slave_flags(slave_t *slave) -{ - slave->dev->flags = slave->original_flags; -} - -static void bond_set_slave_inactive_flags(slave_t *slave) -{ - slave->state = BOND_STATE_BACKUP; - slave->dev->flags |= IFF_NOARP; -} - -static void bond_set_slave_active_flags(slave_t *slave) -{ - slave->state = BOND_STATE_ACTIVE; - slave->dev->flags &= ~IFF_NOARP; -} - -/* - * This function counts and verifies the the number of attached - * slaves, checking the count against the expected value (given that incr - * is either 1 or -1, for add or removal of a slave). Only - * bond_xmit_xor() uses the slave_cnt value, but this is still a good - * consistency check. - */ -static inline void -update_slave_cnt(bonding_t *bond, int incr) -{ - slave_t *slave = NULL; - int expect = bond->slave_cnt + incr; - - bond->slave_cnt = 0; - for (slave = bond->prev; slave != (slave_t*)bond; - slave = slave->prev) { - bond->slave_cnt++; - } - - if (expect != bond->slave_cnt) - BUG(); -} - -/* - * This function detaches the slave from the list . - * WARNING: no check is made to verify if the slave effectively - * belongs to . It returns in case it's needed. - * Nothing is freed on return, structures are just unchained. - * If the bond->current_slave pointer was pointing to , - * it's replaced with slave->next, or if not applicable. - * - * bond->lock held by caller. - */ -static slave_t * -bond_detach_slave(bonding_t *bond, slave_t *slave) -{ - if ((bond == NULL) || (slave == NULL) || - ((void *)bond == (void *)slave)) { - printk(KERN_ERR - "bond_detach_slave(): trying to detach " - "slave %p from bond %p\n", bond, slave); - return slave; - } - - if (bond->next == slave) { /* is the slave at the head ? */ - if (bond->prev == slave) { /* is the slave alone ? */ - write_lock(&bond->ptrlock); - bond->current_slave = NULL; /* no slave anymore */ - write_unlock(&bond->ptrlock); - bond->prev = bond->next = (slave_t *)bond; - } else { /* not alone */ - bond->next = slave->next; - slave->next->prev = (slave_t *)bond; - bond->prev->next = slave->next; - - write_lock(&bond->ptrlock); - if (bond->current_slave == slave) { - bond->current_slave = slave->next; - } - write_unlock(&bond->ptrlock); - } - } else { - slave->prev->next = slave->next; - if (bond->prev == slave) { /* is this slave the last one ? */ - bond->prev = slave->prev; - } else { - slave->next->prev = slave->prev; - } - - write_lock(&bond->ptrlock); - if (bond->current_slave == slave) { - bond->current_slave = slave->next; - } - write_unlock(&bond->ptrlock); - } - - update_slave_cnt(bond, -1); - - return slave; -} - -static void -bond_attach_slave(struct bonding *bond, struct slave *new_slave) -{ - /* - * queue to the end of the slaves list, make the first element its - * successor, the last one its predecessor, and make it the bond's - * predecessor. - * - * Just to clarify, so future bonding driver hackers don't go through - * the same confusion stage I did trying to figure this out, the - * slaves are stored in a double linked circular list, sortof. - * In the ->next direction, the last slave points to the first slave, - * bypassing bond; only the slaves are in the ->next direction. - * In the ->prev direction, however, the first slave points to bond - * and bond points to the last slave. - * - * It looks like a circle with a little bubble hanging off one side - * in the ->prev direction only. - * - * When going through the list once, its best to start at bond->prev - * and go in the ->prev direction, testing for bond. Doing this - * in the ->next direction doesn't work. Trust me, I know this now. - * :) -mts 2002.03.14 - */ - new_slave->prev = bond->prev; - new_slave->prev->next = new_slave; - bond->prev = new_slave; - new_slave->next = bond->next; - - update_slave_cnt(bond, 1); -} - - -/* - * Less bad way to call ioctl from within the kernel; this needs to be - * done some other way to get the call out of interrupt context. - * Needs "ioctl" variable to be supplied by calling context. - */ -#define IOCTL(dev, arg, cmd) ({ \ - int ret; \ - mm_segment_t fs = get_fs(); \ - set_fs(get_ds()); \ - ret = ioctl(dev, arg, cmd); \ - set_fs(fs); \ - ret; }) - -/* - * if supports MII link status reporting, check its link status. - * - * We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(), - * depening upon the setting of the use_carrier parameter. - * - * Return either BMSR_LSTATUS, meaning that the link is up (or we - * can't tell and just pretend it is), or 0, meaning that the link is - * down. - * - * If reporting is non-zero, instead of faking link up, return -1 if - * both ETHTOOL and MII ioctls fail (meaning the device does not - * support them). If use_carrier is set, return whatever it says. - * It'd be nice if there was a good way to tell if a driver supports - * netif_carrier, but there really isn't. - */ -static int -bond_check_dev_link(struct net_device *dev, int reporting) -{ - static int (* ioctl)(struct net_device *, struct ifreq *, int); - struct ifreq ifr; - struct mii_ioctl_data *mii; - struct ethtool_value etool; - - if (use_carrier) { - return netif_carrier_ok(dev) ? BMSR_LSTATUS : 0; - } - - ioctl = dev->do_ioctl; - if (ioctl) { - /* TODO: set pointer to correct ioctl on a per team member */ - /* bases to make this more efficient. that is, once */ - /* we determine the correct ioctl, we will always */ - /* call it and not the others for that team */ - /* member. */ - - /* - * We cannot assume that SIOCGMIIPHY will also read a - * register; not all network drivers (e.g., e100) - * support that. - */ - - /* Yes, the mii is overlaid on the ifreq.ifr_ifru */ - mii = (struct mii_ioctl_data *)&ifr.ifr_data; - if (IOCTL(dev, &ifr, SIOCGMIIPHY) == 0) { - mii->reg_num = MII_BMSR; - if (IOCTL(dev, &ifr, SIOCGMIIREG) == 0) { - return mii->val_out & BMSR_LSTATUS; - } - } - - /* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */ - /* for a period of time so we attempt to get link status */ - /* from it last if the above MII ioctls fail... */ - etool.cmd = ETHTOOL_GLINK; - ifr.ifr_data = (char*)&etool; - if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) { - if (etool.data == 1) { - return BMSR_LSTATUS; - } else { -#ifdef BONDING_DEBUG - printk(KERN_INFO - ":: SIOCETHTOOL shows link down \n"); -#endif - return 0; - } - } - - } - - /* - * If reporting, report that either there's no dev->do_ioctl, - * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we - * cannot report link status). If not reporting, pretend - * we're ok. - */ - return reporting ? -1 : BMSR_LSTATUS; -} - -static u16 bond_check_mii_link(bonding_t *bond) -{ - int has_active_interface = 0; - unsigned long flags; - - read_lock_irqsave(&bond->lock, flags); - read_lock(&bond->ptrlock); - has_active_interface = (bond->current_slave != NULL); - read_unlock(&bond->ptrlock); - read_unlock_irqrestore(&bond->lock, flags); - - return (has_active_interface ? BMSR_LSTATUS : 0); -} - -static int bond_open(struct net_device *dev) -{ - struct timer_list *timer = &((struct bonding *)(dev->priv))->mii_timer; - struct timer_list *arp_timer = &((struct bonding *)(dev->priv))->arp_timer; - MOD_INC_USE_COUNT; - - if (miimon > 0) { /* link check interval, in milliseconds. */ - init_timer(timer); - timer->expires = jiffies + (miimon * HZ / 1000); - timer->data = (unsigned long)dev; - timer->function = (void *)&bond_mii_monitor; - add_timer(timer); - } - - if (arp_interval> 0) { /* arp interval, in milliseconds. */ - init_timer(arp_timer); - arp_timer->expires = jiffies + (arp_interval * HZ / 1000); - arp_timer->data = (unsigned long)dev; - if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - arp_timer->function = (void *)&activebackup_arp_monitor; - } else { - arp_timer->function = (void *)&loadbalance_arp_monitor; - } - add_timer(arp_timer); - } - return 0; -} - -static int bond_close(struct net_device *master) -{ - bonding_t *bond = (struct bonding *) master->priv; - unsigned long flags; - - write_lock_irqsave(&bond->lock, flags); - - if (miimon > 0) { /* link check interval, in milliseconds. */ - del_timer(&bond->mii_timer); - } - if (arp_interval> 0) { /* arp interval, in milliseconds. */ - del_timer(&bond->arp_timer); - if (arp_target_hw_addr != NULL) { - kfree(arp_target_hw_addr); - arp_target_hw_addr = NULL; - } - } - - /* Release the bonded slaves */ - bond_release_all(master); - bond_mc_list_destroy (bond); - - write_unlock_irqrestore(&bond->lock, flags); - - MOD_DEC_USE_COUNT; - return 0; -} - -/* - * flush all members of flush->mc_list from device dev->mc_list - */ -static void bond_mc_list_flush(struct net_device *dev, struct net_device *flush) -{ - struct dev_mc_list *dmi; - - for (dmi = flush->mc_list; dmi != NULL; dmi = dmi->next) - dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); -} - -/* - * Totally destroys the mc_list in bond - */ -static void bond_mc_list_destroy(struct bonding *bond) -{ - struct dev_mc_list *dmi; - - dmi = bond->mc_list; - while (dmi) { - bond->mc_list = dmi->next; - kfree(dmi); - dmi = bond->mc_list; - } -} - -/* - * Add a Multicast address to every slave in the bonding group - */ -static void bond_mc_add(bonding_t *bond, void *addr, int alen) -{ - slave_t *slave; - switch (multicast_mode) { - case BOND_MULTICAST_ACTIVE : - /* write lock already acquired */ - if (bond->current_slave != NULL) - dev_mc_add(bond->current_slave->dev, addr, alen, 0); - break; - case BOND_MULTICAST_ALL : - for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) - dev_mc_add(slave->dev, addr, alen, 0); - break; - case BOND_MULTICAST_DISABLED : - break; - } -} - -/* - * Remove a multicast address from every slave in the bonding group - */ -static void bond_mc_delete(bonding_t *bond, void *addr, int alen) -{ - slave_t *slave; - switch (multicast_mode) { - case BOND_MULTICAST_ACTIVE : - /* write lock already acquired */ - if (bond->current_slave != NULL) - dev_mc_delete(bond->current_slave->dev, addr, alen, 0); - break; - case BOND_MULTICAST_ALL : - for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) - dev_mc_delete(slave->dev, addr, alen, 0); - break; - case BOND_MULTICAST_DISABLED : - break; - } -} - -/* - * Copy all the Multicast addresses from src to the bonding device dst - */ -static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst, - int gpf_flag) -{ - struct dev_mc_list *dmi, *new_dmi; - - for (dmi = src; dmi != NULL; dmi = dmi->next) { - new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag); - - if (new_dmi == NULL) { - return -ENOMEM; - } - - new_dmi->next = dst->mc_list; - dst->mc_list = new_dmi; - - new_dmi->dmi_addrlen = dmi->dmi_addrlen; - memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen); - new_dmi->dmi_users = dmi->dmi_users; - new_dmi->dmi_gusers = dmi->dmi_gusers; - } - return 0; -} - -/* - * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise - */ -static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2) -{ - return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 && - dmi1->dmi_addrlen == dmi2->dmi_addrlen; -} - -/* - * Push the promiscuity flag down to all slaves - */ -static void bond_set_promiscuity(bonding_t *bond, int inc) -{ - slave_t *slave; - switch (multicast_mode) { - case BOND_MULTICAST_ACTIVE : - /* write lock already acquired */ - if (bond->current_slave != NULL) - dev_set_promiscuity(bond->current_slave->dev, inc); - break; - case BOND_MULTICAST_ALL : - for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) - dev_set_promiscuity(slave->dev, inc); - break; - case BOND_MULTICAST_DISABLED : - break; - } -} - -/* - * Push the allmulti flag down to all slaves - */ -static void bond_set_allmulti(bonding_t *bond, int inc) -{ - slave_t *slave; - switch (multicast_mode) { - case BOND_MULTICAST_ACTIVE : - /* write lock already acquired */ - if (bond->current_slave != NULL) - dev_set_allmulti(bond->current_slave->dev, inc); - break; - case BOND_MULTICAST_ALL : - for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) - dev_set_allmulti(slave->dev, inc); - break; - case BOND_MULTICAST_DISABLED : - break; - } -} - -/* - * returns dmi entry if found, NULL otherwise - */ -static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi, - struct dev_mc_list *mc_list) -{ - struct dev_mc_list *idmi; - - for (idmi = mc_list; idmi != NULL; idmi = idmi->next) { - if (dmi_same(dmi, idmi)) { - return idmi; - } - } - return NULL; -} - -static void set_multicast_list(struct net_device *master) -{ - bonding_t *bond = master->priv; - struct dev_mc_list *dmi; - unsigned long flags = 0; - - if (multicast_mode == BOND_MULTICAST_DISABLED) - return; - /* - * Lock the private data for the master - */ - write_lock_irqsave(&bond->lock, flags); - - /* set promiscuity flag to slaves */ - if ( (master->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC) ) - bond_set_promiscuity(bond, 1); - - if ( !(master->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC) ) - bond_set_promiscuity(bond, -1); - - /* set allmulti flag to slaves */ - if ( (master->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI) ) - bond_set_allmulti(bond, 1); - - if ( !(master->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI) ) - bond_set_allmulti(bond, -1); - - bond->flags = master->flags; - - /* looking for addresses to add to slaves' mc list */ - for (dmi = master->mc_list; dmi != NULL; dmi = dmi->next) { - if (bond_mc_list_find_dmi(dmi, bond->mc_list) == NULL) - bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen); - } - - /* looking for addresses to delete from slaves' list */ - for (dmi = bond->mc_list; dmi != NULL; dmi = dmi->next) { - if (bond_mc_list_find_dmi(dmi, master->mc_list) == NULL) - bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen); - } - - - /* save master's multicast list */ - bond_mc_list_destroy (bond); - bond_mc_list_copy (master->mc_list, bond, GFP_ATOMIC); - - write_unlock_irqrestore(&bond->lock, flags); -} - -/* - * Update the mc list and multicast-related flags for the new and - * old active slaves (if any) according to the multicast mode - */ -static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old) -{ - struct dev_mc_list *dmi; - - switch(multicast_mode) { - case BOND_MULTICAST_ACTIVE : - if (bond->device->flags & IFF_PROMISC) { - if (old != NULL && new != old) - dev_set_promiscuity(old->dev, -1); - dev_set_promiscuity(new->dev, 1); - } - if (bond->device->flags & IFF_ALLMULTI) { - if (old != NULL && new != old) - dev_set_allmulti(old->dev, -1); - dev_set_allmulti(new->dev, 1); - } - /* first remove all mc addresses from old slave if any, - and _then_ add them to new active slave */ - if (old != NULL && new != old) { - for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next) - dev_mc_delete(old->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); - } - for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next) - dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); - break; - case BOND_MULTICAST_ALL : - /* nothing to do: mc list is already up-to-date on all slaves */ - break; - case BOND_MULTICAST_DISABLED : - break; - } -} - -/* enslave device to bond device */ -static int bond_enslave(struct net_device *master_dev, - struct net_device *slave_dev) -{ - bonding_t *bond = NULL; - slave_t *new_slave = NULL; - unsigned long flags = 0; - unsigned long rflags = 0; - int ndx = 0; - int err = 0; - struct dev_mc_list *dmi; - struct in_ifaddr **ifap; - struct in_ifaddr *ifa; - int link_reporting; - - if (master_dev == NULL || slave_dev == NULL) { - return -ENODEV; - } - bond = (struct bonding *) master_dev->priv; - - if (slave_dev->do_ioctl == NULL) { - printk(KERN_DEBUG - "Warning : no link monitoring support for %s\n", - slave_dev->name); - } - - /* not running. */ - if ((slave_dev->flags & IFF_UP) != IFF_UP) { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "Error, slave_dev is not running\n"); -#endif - return -EINVAL; - } - - /* already enslaved */ - if (master_dev->flags & IFF_SLAVE || slave_dev->flags & IFF_SLAVE) { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "Error, Device was already enslaved\n"); -#endif - return -EBUSY; - } - - if ((new_slave = kmalloc(sizeof(slave_t), GFP_ATOMIC)) == NULL) { - return -ENOMEM; - } - memset(new_slave, 0, sizeof(slave_t)); - - /* save flags before call to netdev_set_master */ - new_slave->original_flags = slave_dev->flags; - err = netdev_set_master(slave_dev, master_dev); - - if (err) { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "Error %d calling netdev_set_master\n", err); -#endif - goto err_free; - } - - new_slave->dev = slave_dev; - - if (multicast_mode == BOND_MULTICAST_ALL) { - /* set promiscuity level to new slave */ - if (master_dev->flags & IFF_PROMISC) - dev_set_promiscuity(slave_dev, 1); - - /* set allmulti level to new slave */ - if (master_dev->flags & IFF_ALLMULTI) - dev_set_allmulti(slave_dev, 1); - - /* upload master's mc_list to new slave */ - for (dmi = master_dev->mc_list; dmi != NULL; dmi = dmi->next) - dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); - } - - write_lock_irqsave(&bond->lock, flags); - - bond_attach_slave(bond, new_slave); - new_slave->delay = 0; - new_slave->link_failure_count = 0; - - if (miimon > 0 && !use_carrier) { - link_reporting = bond_check_dev_link(slave_dev, 1); - - if ((link_reporting == -1) && (arp_interval == 0)) { - /* - * miimon is set but a bonded network driver - * does not support ETHTOOL/MII and - * arp_interval is not set. Note: if - * use_carrier is enabled, we will never go - * here (because netif_carrier is always - * supported); thus, we don't need to change - * the messages for netif_carrier. - */ - printk(KERN_ERR - "bond_enslave(): MII and ETHTOOL support not " - "available for interface %s, and " - "arp_interval/arp_ip_target module parameters " - "not specified, thus bonding will not detect " - "link failures! see bonding.txt for details.\n", - slave_dev->name); - } else if (link_reporting == -1) { - /* unable get link status using mii/ethtool */ - printk(KERN_WARNING - "bond_enslave: can't get link status from " - "interface %s; the network driver associated " - "with this interface does not support " - "MII or ETHTOOL link status reporting, thus " - "miimon has no effect on this interface.\n", - slave_dev->name); - } - } - - /* check for initial state */ - if ((miimon <= 0) || - (bond_check_dev_link(slave_dev, 0) == BMSR_LSTATUS)) { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "Initial state of slave_dev is BOND_LINK_UP\n"); -#endif - new_slave->link = BOND_LINK_UP; - new_slave->jiffies = jiffies; - } - else { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "Initial state of slave_dev is BOND_LINK_DOWN\n"); -#endif - new_slave->link = BOND_LINK_DOWN; - } - - /* if we're in active-backup mode, we need one and only one active - * interface. The backup interfaces will have their NOARP flag set - * because we need them to be completely deaf and not to respond to - * any ARP request on the network to avoid fooling a switch. Thus, - * since we guarantee that current_slave always point to the last - * usable interface, we just have to verify this interface's flag. - */ - if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - if (((bond->current_slave == NULL) - || (bond->current_slave->dev->flags & IFF_NOARP)) - && (new_slave->link == BOND_LINK_UP)) { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "This is the first active slave\n"); -#endif - /* first slave or no active slave yet, and this link - is OK, so make this interface the active one */ - bond->current_slave = new_slave; - bond_set_slave_active_flags(new_slave); - bond_mc_update(bond, new_slave, NULL); - } - else { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "This is just a backup slave\n"); -#endif - bond_set_slave_inactive_flags(new_slave); - } - read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags); - ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list); - ifa = *ifap; - my_ip = ifa->ifa_address; - read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags); - - /* if there is a primary slave, remember it */ - if (primary != NULL) - if( strcmp(primary, new_slave->dev->name) == 0) - bond->primary_slave = new_slave; - } else { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "This slave is always active in trunk mode\n"); -#endif - /* always active in trunk mode */ - new_slave->state = BOND_STATE_ACTIVE; - if (bond->current_slave == NULL) - bond->current_slave = new_slave; - } - - write_unlock_irqrestore(&bond->lock, flags); - - /* - * !!! This is to support old versions of ifenslave. We can remove - * this in 2.5 because our ifenslave takes care of this for us. - * We check to see if the master has a mac address yet. If not, - * we'll give it the mac address of our slave device. - */ - for (ndx = 0; ndx < slave_dev->addr_len; ndx++) { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "Checking ndx=%d of master_dev->dev_addr\n", - ndx); -#endif - if (master_dev->dev_addr[ndx] != 0) { -#ifdef BONDING_DEBUG - printk(KERN_CRIT "Found non-zero byte at ndx=%d\n", - ndx); -#endif - break; - } - } - if (ndx == slave_dev->addr_len) { - /* - * We got all the way through the address and it was - * all 0's. - */ -#ifdef BONDING_DEBUG - printk(KERN_CRIT "%s doesn't have a MAC address yet. ", - master_dev->name); - printk(KERN_CRIT "Going to give assign it from %s.\n", - slave_dev->name); -#endif - bond_sethwaddr(master_dev, slave_dev); - } - - printk (KERN_INFO "%s: enslaving %s as a%s interface with a%s link.\n", - master_dev->name, slave_dev->name, - new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup", - new_slave->link == BOND_LINK_UP ? "n up" : " down"); - - /* enslave is successful */ - return 0; -err_free: - kfree(new_slave); - return err; -} - -/* - * This function changes the active slave to slave . - * It returns -EINVAL in the following cases. - * - is not found in the list. - * - There is not active slave now. - * - is already active. - * - The link state of is not BOND_LINK_UP. - * - is not running. - * In these cases, this fuction does nothing. - * In the other cases, currnt_slave pointer is changed and 0 is returned. - */ -static int bond_change_active(struct net_device *master_dev, struct net_device *slave_dev) -{ - bonding_t *bond; - slave_t *slave; - slave_t *oldactive = NULL; - slave_t *newactive = NULL; - unsigned long flags; - int ret = 0; - - if (master_dev == NULL || slave_dev == NULL) { - return -ENODEV; - } - - bond = (struct bonding *) master_dev->priv; - write_lock_irqsave(&bond->lock, flags); - slave = (slave_t *)bond; - oldactive = bond->current_slave; - - while ((slave = slave->prev) != (slave_t *)bond) { - if(slave_dev == slave->dev) { - newactive = slave; - break; - } - } - - if ((newactive != NULL)&& - (oldactive != NULL)&& - (newactive != oldactive)&& - (newactive->link == BOND_LINK_UP)&& - IS_UP(newactive->dev)) { - bond_set_slave_inactive_flags(oldactive); - bond_set_slave_active_flags(newactive); - bond_mc_update(bond, newactive, oldactive); - bond->current_slave = newactive; - printk("%s : activate %s(old : %s)\n", - master_dev->name, newactive->dev->name, - oldactive->dev->name); - } - else { - ret = -EINVAL; - } - write_unlock_irqrestore(&bond->lock, flags); - return ret; -} - -/* Choose a new valid interface from the pool, set it active - * and make it the current slave. If no valid interface is - * found, the oldest slave in BACK state is choosen and - * activated. If none is found, it's considered as no - * interfaces left so the current slave is set to NULL. - * The result is a pointer to the current slave. - * - * Since this function sends messages tails through printk, the caller - * must have started something like `printk(KERN_INFO "xxxx ");'. - * - * Warning: must put locks around the call to this function if needed. - */ -slave_t *change_active_interface(bonding_t *bond) -{ - slave_t *newslave, *oldslave; - slave_t *bestslave = NULL; - int mintime; - - read_lock(&bond->ptrlock); - newslave = oldslave = bond->current_slave; - read_unlock(&bond->ptrlock); - - if (newslave == NULL) { /* there were no active slaves left */ - if (bond->next != (slave_t *)bond) { /* found one slave */ - write_lock(&bond->ptrlock); - newslave = bond->current_slave = bond->next; - write_unlock(&bond->ptrlock); - } else { - - printk (" but could not find any %s interface.\n", - (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other"); - write_lock(&bond->ptrlock); - bond->current_slave = (slave_t *)NULL; - write_unlock(&bond->ptrlock); - return NULL; /* still no slave, return NULL */ - } - } else if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - /* make sure oldslave doesn't send arps - this could - * cause a ping-pong effect between interfaces since they - * would be able to tx arps - in active backup only one - * slave should be able to tx arps, and that should be - * the current_slave; the only exception is when all - * slaves have gone down, then only one non-current slave can - * send arps at a time; clearing oldslaves' mc list is handled - * later in this function. - */ - bond_set_slave_inactive_flags(oldslave); - } - - mintime = updelay; - - /* first try the primary link; if arping, a link must tx/rx traffic - * before it can be considered the current_slave - also, we would skip - * slaves between the current_slave and primary_slave that may be up - * and able to arp - */ - if ((bond->primary_slave != NULL) && (arp_interval == 0)) { - if (IS_UP(bond->primary_slave->dev)) - newslave = bond->primary_slave; - } - - do { - if (IS_UP(newslave->dev)) { - if (newslave->link == BOND_LINK_UP) { - /* this one is immediately usable */ - if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - bond_set_slave_active_flags(newslave); - bond_mc_update(bond, newslave, oldslave); - printk (" and making interface %s the active one.\n", - newslave->dev->name); - } - else { - printk (" and setting pointer to interface %s.\n", - newslave->dev->name); - } - - write_lock(&bond->ptrlock); - bond->current_slave = newslave; - write_unlock(&bond->ptrlock); - return newslave; - } - else if (newslave->link == BOND_LINK_BACK) { - /* link up, but waiting for stabilization */ - if (newslave->delay < mintime) { - mintime = newslave->delay; - bestslave = newslave; - } - } - } - } while ((newslave = newslave->next) != oldslave); - - /* no usable backup found, we'll see if we at least got a link that was - coming back for a long time, and could possibly already be usable. - */ - - if (bestslave != NULL) { - /* early take-over. */ - printk (" and making interface %s the active one %d ms earlier.\n", - bestslave->dev->name, - (updelay - bestslave->delay)*miimon); - - bestslave->delay = 0; - bestslave->link = BOND_LINK_UP; - bestslave->jiffies = jiffies; - bond_set_slave_active_flags(bestslave); - bond_mc_update(bond, bestslave, oldslave); - write_lock(&bond->ptrlock); - bond->current_slave = bestslave; - write_unlock(&bond->ptrlock); - return bestslave; - } - - if ((bond_mode == BOND_MODE_ACTIVEBACKUP) && - (multicast_mode == BOND_MULTICAST_ACTIVE) && - (oldslave != NULL)) { - /* flush bonds (master's) mc_list from oldslave since it wasn't - * updated (and deleted) above - */ - bond_mc_list_flush(oldslave->dev, bond->device); - if (bond->device->flags & IFF_PROMISC) { - dev_set_promiscuity(oldslave->dev, -1); - } - if (bond->device->flags & IFF_ALLMULTI) { - dev_set_allmulti(oldslave->dev, -1); - } - } - - printk (" but could not find any %s interface.\n", - (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other"); - - /* absolutely nothing found. let's return NULL */ - write_lock(&bond->ptrlock); - bond->current_slave = (slave_t *)NULL; - write_unlock(&bond->ptrlock); - return NULL; -} - -/* - * Try to release the slave device from the bond device - * It is legal to access current_slave without a lock because all the function - * is write-locked. - * - * The rules for slave state should be: - * for Active/Backup: - * Active stays on all backups go down - * for Bonded connections: - * The first up interface should be left on and all others downed. - */ -static int bond_release(struct net_device *master, struct net_device *slave) -{ - bonding_t *bond; - slave_t *our_slave, *old_current; - unsigned long flags; - - if (master == NULL || slave == NULL) { - return -ENODEV; - } - - bond = (struct bonding *) master->priv; - - /* master already enslaved, or slave not enslaved, - or no slave for this master */ - if ((master->flags & IFF_SLAVE) || !(slave->flags & IFF_SLAVE)) { - printk (KERN_DEBUG "%s: cannot release %s.\n", master->name, slave->name); - return -EINVAL; - } - - write_lock_irqsave(&bond->lock, flags); - bond->current_arp_slave = NULL; - our_slave = (slave_t *)bond; - old_current = bond->current_slave; - while ((our_slave = our_slave->prev) != (slave_t *)bond) { - if (our_slave->dev == slave) { - bond_detach_slave(bond, our_slave); - - printk (KERN_INFO "%s: releasing %s interface %s", - master->name, - (our_slave->state == BOND_STATE_ACTIVE) ? "active" : "backup", - slave->name); - - if (our_slave == old_current) { - /* find a new interface and be verbose */ - change_active_interface(bond); - } else { - printk(".\n"); - } - - if (bond->current_slave == NULL) { - printk(KERN_INFO - "%s: now running without any active interface !\n", - master->name); - } - - if (bond->primary_slave == our_slave) { - bond->primary_slave = NULL; - } - - break; - } - - } - write_unlock_irqrestore(&bond->lock, flags); - - if (our_slave == (slave_t *)bond) { - /* if we get here, it's because the device was not found */ - printk (KERN_INFO "%s: %s not enslaved\n", master->name, slave->name); - return -EINVAL; - } - - /* undo settings and restore original values */ - - if (multicast_mode == BOND_MULTICAST_ALL) { - /* flush master's mc_list from slave */ - bond_mc_list_flush (slave, master); - - /* unset promiscuity level from slave */ - if (master->flags & IFF_PROMISC) - dev_set_promiscuity(slave, -1); - - /* unset allmulti level from slave */ - if (master->flags & IFF_ALLMULTI) - dev_set_allmulti(slave, -1); - } - - netdev_set_master(slave, NULL); - - /* only restore its RUNNING flag if monitoring set it down */ - if (slave->flags & IFF_UP) { - slave->flags |= IFF_RUNNING; - } - - if (slave->flags & IFF_NOARP || - bond->current_slave != NULL) { - dev_close(slave); - our_slave->original_flags &= ~IFF_UP; - } - - bond_restore_slave_flags(our_slave); - - kfree(our_slave); - - return 0; /* deletion OK */ -} - -/* - * This function releases all slaves. - * Warning: must put write-locks around the call to this function. - */ -static int bond_release_all(struct net_device *master) -{ - bonding_t *bond; - slave_t *our_slave; - struct net_device *slave_dev; - - if (master == NULL) { - return -ENODEV; - } - - if (master->flags & IFF_SLAVE) { - return -EINVAL; - } - - bond = (struct bonding *) master->priv; - bond->current_arp_slave = NULL; - bond->current_slave = NULL; - bond->primary_slave = NULL; - - while ((our_slave = bond->prev) != (slave_t *)bond) { - slave_dev = our_slave->dev; - bond_detach_slave(bond, our_slave); - - if (multicast_mode == BOND_MULTICAST_ALL - || (multicast_mode == BOND_MULTICAST_ACTIVE - && bond->current_slave == our_slave)) { - - /* flush master's mc_list from slave */ - bond_mc_list_flush (slave_dev, master); - - /* unset promiscuity level from slave */ - if (master->flags & IFF_PROMISC) - dev_set_promiscuity(slave_dev, -1); - - /* unset allmulti level from slave */ - if (master->flags & IFF_ALLMULTI) - dev_set_allmulti(slave_dev, -1); - } - - kfree(our_slave); - - /* - * Can be safely called from inside the bond lock - * since traffic and timers have already stopped - */ - netdev_set_master(slave_dev, NULL); - - /* only restore its RUNNING flag if monitoring set it down */ - if (slave_dev->flags & IFF_UP) - slave_dev->flags |= IFF_RUNNING; - - if (slave_dev->flags & IFF_NOARP) - dev_close(slave_dev); - } - - printk (KERN_INFO "%s: released all slaves\n", master->name); - - return 0; -} - -/* this function is called regularly to monitor each slave's link. */ -static void bond_mii_monitor(struct net_device *master) -{ - bonding_t *bond = (struct bonding *) master->priv; - slave_t *slave, *bestslave, *oldcurrent; - unsigned long flags; - int slave_died = 0; - - read_lock_irqsave(&bond->lock, flags); - - /* we will try to read the link status of each of our slaves, and - * set their IFF_RUNNING flag appropriately. For each slave not - * supporting MII status, we won't do anything so that a user-space - * program could monitor the link itself if needed. - */ - - bestslave = NULL; - slave = (slave_t *)bond; - - read_lock(&bond->ptrlock); - oldcurrent = bond->current_slave; - read_unlock(&bond->ptrlock); - - while ((slave = slave->prev) != (slave_t *)bond) { - /* use updelay+1 to match an UP slave even when updelay is 0 */ - int mindelay = updelay + 1; - struct net_device *dev = slave->dev; - int link_state; - - link_state = bond_check_dev_link(dev, 0); - - switch (slave->link) { - case BOND_LINK_UP: /* the link was up */ - if (link_state == BMSR_LSTATUS) { - /* link stays up, tell that this one - is immediately available */ - if (IS_UP(dev) && (mindelay > -2)) { - /* -2 is the best case : - this slave was already up */ - mindelay = -2; - bestslave = slave; - } - break; - } - else { /* link going down */ - slave->link = BOND_LINK_FAIL; - slave->delay = downdelay; - if (slave->link_failure_count < UINT_MAX) { - slave->link_failure_count++; - } - if (downdelay > 0) { - printk (KERN_INFO - "%s: link status down for %sinterface " - "%s, disabling it in %d ms.\n", - master->name, - IS_UP(dev) - ? ((bond_mode == BOND_MODE_ACTIVEBACKUP) - ? ((slave == oldcurrent) - ? "active " : "backup ") - : "") - : "idle ", - dev->name, - downdelay * miimon); - } - } - /* no break ! fall through the BOND_LINK_FAIL test to - ensure proper action to be taken - */ - case BOND_LINK_FAIL: /* the link has just gone down */ - if (link_state != BMSR_LSTATUS) { - /* link stays down */ - if (slave->delay <= 0) { - /* link down for too long time */ - slave->link = BOND_LINK_DOWN; - /* in active/backup mode, we must - completely disable this interface */ - if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - bond_set_slave_inactive_flags(slave); - } - printk(KERN_INFO - "%s: link status definitely down " - "for interface %s, disabling it", - master->name, - dev->name); - - read_lock(&bond->ptrlock); - if (slave == bond->current_slave) { - read_unlock(&bond->ptrlock); - /* find a new interface and be verbose */ - change_active_interface(bond); - } else { - read_unlock(&bond->ptrlock); - printk(".\n"); - } - slave_died = 1; - } else { - slave->delay--; - } - } else { - /* link up again */ - slave->link = BOND_LINK_UP; - slave->jiffies = jiffies; - printk(KERN_INFO - "%s: link status up again after %d ms " - "for interface %s.\n", - master->name, - (downdelay - slave->delay) * miimon, - dev->name); - - if (IS_UP(dev) && (mindelay > -1)) { - /* -1 is a good case : this slave went - down only for a short time */ - mindelay = -1; - bestslave = slave; - } - } - break; - case BOND_LINK_DOWN: /* the link was down */ - if (link_state != BMSR_LSTATUS) { - /* the link stays down, nothing more to do */ - break; - } else { /* link going up */ - slave->link = BOND_LINK_BACK; - slave->delay = updelay; - - if (updelay > 0) { - /* if updelay == 0, no need to - advertise about a 0 ms delay */ - printk (KERN_INFO - "%s: link status up for interface" - " %s, enabling it in %d ms.\n", - master->name, - dev->name, - updelay * miimon); - } - } - /* no break ! fall through the BOND_LINK_BACK state in - case there's something to do. - */ - case BOND_LINK_BACK: /* the link has just come back */ - if (link_state != BMSR_LSTATUS) { - /* link down again */ - slave->link = BOND_LINK_DOWN; - printk(KERN_INFO - "%s: link status down again after %d ms " - "for interface %s.\n", - master->name, - (updelay - slave->delay) * miimon, - dev->name); - } else { - /* link stays up */ - if (slave->delay == 0) { - /* now the link has been up for long time enough */ - slave->link = BOND_LINK_UP; - slave->jiffies = jiffies; - - if (bond_mode != BOND_MODE_ACTIVEBACKUP) { - /* make it immediately active */ - slave->state = BOND_STATE_ACTIVE; - } else if (slave != bond->primary_slave) { - /* prevent it from being the active one */ - slave->state = BOND_STATE_BACKUP; - } - - printk(KERN_INFO - "%s: link status definitely up " - "for interface %s.\n", - master->name, - dev->name); - - if ( (bond->primary_slave != NULL) - && (slave == bond->primary_slave) ) - change_active_interface(bond); - } - else - slave->delay--; - - /* we'll also look for the mostly eligible slave */ - if (bond->primary_slave == NULL) { - if (IS_UP(dev) && (slave->delay < mindelay)) { - mindelay = slave->delay; - bestslave = slave; - } - } else if ( (IS_UP(bond->primary_slave->dev)) || - ( (!IS_UP(bond->primary_slave->dev)) && - (IS_UP(dev) && (slave->delay < mindelay)) ) ) { - mindelay = slave->delay; - bestslave = slave; - } - } - break; - } /* end of switch */ - } /* end of while */ - - /* - * if there's no active interface and we discovered that one - * of the slaves could be activated earlier, so we do it. - */ - read_lock(&bond->ptrlock); - oldcurrent = bond->current_slave; - read_unlock(&bond->ptrlock); - - /* no active interface at the moment or need to bring up the primary */ - if (oldcurrent == NULL) { /* no active interface at the moment */ - if (bestslave != NULL) { /* last chance to find one ? */ - if (bestslave->link == BOND_LINK_UP) { - printk (KERN_INFO - "%s: making interface %s the new active one.\n", - master->name, bestslave->dev->name); - } else { - printk (KERN_INFO - "%s: making interface %s the new " - "active one %d ms earlier.\n", - master->name, bestslave->dev->name, - (updelay - bestslave->delay) * miimon); - - bestslave->delay = 0; - bestslave->link = BOND_LINK_UP; - bestslave->jiffies = jiffies; - } - - if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - bond_set_slave_active_flags(bestslave); - bond_mc_update(bond, bestslave, NULL); - } else { - bestslave->state = BOND_STATE_ACTIVE; - } - write_lock(&bond->ptrlock); - bond->current_slave = bestslave; - write_unlock(&bond->ptrlock); - } else if (slave_died) { - /* print this message only once a slave has just died */ - printk(KERN_INFO - "%s: now running without any active interface !\n", - master->name); - } - } - - read_unlock_irqrestore(&bond->lock, flags); - /* re-arm the timer */ - mod_timer(&bond->mii_timer, jiffies + (miimon * HZ / 1000)); -} - -/* - * this function is called regularly to monitor each slave's link - * ensuring that traffic is being sent and received when arp monitoring - * is used in load-balancing mode. if the adapter has been dormant, then an - * arp is transmitted to generate traffic. see activebackup_arp_monitor for - * arp monitoring in active backup mode. - */ -static void loadbalance_arp_monitor(struct net_device *master) -{ - bonding_t *bond; - unsigned long flags; - slave_t *slave; - int the_delta_in_ticks = arp_interval * HZ / 1000; - int next_timer = jiffies + (arp_interval * HZ / 1000); - - bond = (struct bonding *) master->priv; - if (master->priv == NULL) { - mod_timer(&bond->arp_timer, next_timer); - return; - } - - read_lock_irqsave(&bond->lock, flags); - - /* TODO: investigate why rtnl_shlock_nowait and rtnl_exlock_nowait - * are called below and add comment why they are required... - */ - if ((!IS_UP(master)) || rtnl_shlock_nowait()) { - mod_timer(&bond->arp_timer, next_timer); - read_unlock_irqrestore(&bond->lock, flags); - return; - } - - if (rtnl_exlock_nowait()) { - rtnl_shunlock(); - mod_timer(&bond->arp_timer, next_timer); - read_unlock_irqrestore(&bond->lock, flags); - return; - } - - /* see if any of the previous devices are up now (i.e. they have - * xmt and rcv traffic). the current_slave does not come into - * the picture unless it is null. also, slave->jiffies is not needed - * here because we send an arp on each slave and give a slave as - * long as it needs to get the tx/rx within the delta. - * TODO: what about up/down delay in arp mode? it wasn't here before - * so it can wait - */ - slave = (slave_t *)bond; - while ((slave = slave->prev) != (slave_t *)bond) { - - if (slave->link != BOND_LINK_UP) { - - if (((jiffies - slave->dev->trans_start) <= - the_delta_in_ticks) && - ((jiffies - slave->dev->last_rx) <= - the_delta_in_ticks)) { - - slave->link = BOND_LINK_UP; - slave->state = BOND_STATE_ACTIVE; - - /* primary_slave has no meaning in round-robin - * mode. the window of a slave being up and - * current_slave being null after enslaving - * is closed. - */ - read_lock(&bond->ptrlock); - if (bond->current_slave == NULL) { - read_unlock(&bond->ptrlock); - printk(KERN_INFO - "%s: link status definitely up " - "for interface %s, ", - master->name, - slave->dev->name); - change_active_interface(bond); - } else { - read_unlock(&bond->ptrlock); - printk(KERN_INFO - "%s: interface %s is now up\n", - master->name, - slave->dev->name); - } - } - } else { - /* slave->link == BOND_LINK_UP */ - - /* not all switches will respond to an arp request - * when the source ip is 0, so don't take the link down - * if we don't know our ip yet - */ - if (((jiffies - slave->dev->trans_start) >= - (2*the_delta_in_ticks)) || - (((jiffies - slave->dev->last_rx) >= - (2*the_delta_in_ticks)) && my_ip !=0)) { - slave->link = BOND_LINK_DOWN; - slave->state = BOND_STATE_BACKUP; - if (slave->link_failure_count < UINT_MAX) { - slave->link_failure_count++; - } - printk(KERN_INFO - "%s: interface %s is now down.\n", - master->name, - slave->dev->name); - - read_lock(&bond->ptrlock); - if (slave == bond->current_slave) { - read_unlock(&bond->ptrlock); - change_active_interface(bond); - } else { - read_unlock(&bond->ptrlock); - } - } - } - - /* note: if switch is in round-robin mode, all links - * must tx arp to ensure all links rx an arp - otherwise - * links may oscillate or not come up at all; if switch is - * in something like xor mode, there is nothing we can - * do - all replies will be rx'ed on same link causing slaves - * to be unstable during low/no traffic periods - */ - if (IS_UP(slave->dev)) { - arp_send_all(slave); - } - } - - rtnl_exunlock(); - rtnl_shunlock(); - read_unlock_irqrestore(&bond->lock, flags); - - /* re-arm the timer */ - mod_timer(&bond->arp_timer, next_timer); -} - -/* - * When using arp monitoring in active-backup mode, this function is - * called to determine if any backup slaves have went down or a new - * current slave needs to be found. - * The backup slaves never generate traffic, they are considered up by merely - * receiving traffic. If the current slave goes down, each backup slave will - * be given the opportunity to tx/rx an arp before being taken down - this - * prevents all slaves from being taken down due to the current slave not - * sending any traffic for the backups to receive. The arps are not necessarily - * necessary, any tx and rx traffic will keep the current slave up. While any - * rx traffic will keep the backup slaves up, the current slave is responsible - * for generating traffic to keep them up regardless of any other traffic they - * may have received. - * see loadbalance_arp_monitor for arp monitoring in load balancing mode - */ -static void activebackup_arp_monitor(struct net_device *master) -{ - bonding_t *bond; - unsigned long flags; - slave_t *slave; - int the_delta_in_ticks = arp_interval * HZ / 1000; - int next_timer = jiffies + (arp_interval * HZ / 1000); - - bond = (struct bonding *) master->priv; - if (master->priv == NULL) { - mod_timer(&bond->arp_timer, next_timer); - return; - } - - read_lock_irqsave(&bond->lock, flags); - - if (!IS_UP(master)) { - mod_timer(&bond->arp_timer, next_timer); - read_unlock_irqrestore(&bond->lock, flags); - return; - } - - /* determine if any slave has come up or any backup slave has - * gone down - * TODO: what about up/down delay in arp mode? it wasn't here before - * so it can wait - */ - slave = (slave_t *)bond; - while ((slave = slave->prev) != (slave_t *)bond) { - - if (slave->link != BOND_LINK_UP) { - if ((jiffies - slave->dev->last_rx) <= - the_delta_in_ticks) { - - slave->link = BOND_LINK_UP; - write_lock(&bond->ptrlock); - if ((bond->current_slave == NULL) && - ((jiffies - slave->dev->trans_start) <= - the_delta_in_ticks)) { - bond->current_slave = slave; - bond_set_slave_active_flags(slave); - bond_mc_update(bond, slave, NULL); - bond->current_arp_slave = NULL; - } else if (bond->current_slave != slave) { - /* this slave has just come up but we - * already have a current slave; this - * can also happen if bond_enslave adds - * a new slave that is up while we are - * searching for a new slave - */ - bond_set_slave_inactive_flags(slave); - bond->current_arp_slave = NULL; - } - - if (slave == bond->current_slave) { - printk(KERN_INFO - "%s: %s is up and now the " - "active interface\n", - master->name, - slave->dev->name); - } else { - printk(KERN_INFO - "%s: backup interface %s is " - "now up\n", - master->name, - slave->dev->name); - } - - write_unlock(&bond->ptrlock); - } - } else { - read_lock(&bond->ptrlock); - if ((slave != bond->current_slave) && - (bond->current_arp_slave == NULL) && - (((jiffies - slave->dev->last_rx) >= - 3*the_delta_in_ticks) && (my_ip != 0))) { - /* a backup slave has gone down; three times - * the delta allows the current slave to be - * taken out before the backup slave. - * note: a non-null current_arp_slave indicates - * the current_slave went down and we are - * searching for a new one; under this - * condition we only take the current_slave - * down - this gives each slave a chance to - * tx/rx traffic before being taken out - */ - read_unlock(&bond->ptrlock); - slave->link = BOND_LINK_DOWN; - if (slave->link_failure_count < UINT_MAX) { - slave->link_failure_count++; - } - bond_set_slave_inactive_flags(slave); - printk(KERN_INFO - "%s: backup interface %s is now down\n", - master->name, - slave->dev->name); - } else { - read_unlock(&bond->ptrlock); - } - } - } - - read_lock(&bond->ptrlock); - slave = bond->current_slave; - read_unlock(&bond->ptrlock); - - if (slave != NULL) { - - /* if we have sent traffic in the past 2*arp_intervals but - * haven't xmit and rx traffic in that time interval, select - * a different slave. slave->jiffies is only updated when - * a slave first becomes the current_slave - not necessarily - * after every arp; this ensures the slave has a full 2*delta - * before being taken out. if a primary is being used, check - * if it is up and needs to take over as the current_slave - */ - if ((((jiffies - slave->dev->trans_start) >= - (2*the_delta_in_ticks)) || - (((jiffies - slave->dev->last_rx) >= - (2*the_delta_in_ticks)) && (my_ip != 0))) && - ((jiffies - slave->jiffies) >= 2*the_delta_in_ticks)) { - - slave->link = BOND_LINK_DOWN; - if (slave->link_failure_count < UINT_MAX) { - slave->link_failure_count++; - } - printk(KERN_INFO "%s: link status down for " - "active interface %s, disabling it", - master->name, - slave->dev->name); - slave = change_active_interface(bond); - bond->current_arp_slave = slave; - if (slave != NULL) { - slave->jiffies = jiffies; - } - - } else if ((bond->primary_slave != NULL) && - (bond->primary_slave != slave) && - (bond->primary_slave->link == BOND_LINK_UP)) { - /* at this point, slave is the current_slave */ - printk(KERN_INFO - "%s: changing from interface %s to primary " - "interface %s\n", - master->name, - slave->dev->name, - bond->primary_slave->dev->name); - - /* primary is up so switch to it */ - bond_set_slave_inactive_flags(slave); - bond_mc_update(bond, bond->primary_slave, slave); - write_lock(&bond->ptrlock); - bond->current_slave = bond->primary_slave; - write_unlock(&bond->ptrlock); - slave = bond->primary_slave; - bond_set_slave_active_flags(slave); - slave->jiffies = jiffies; - } else { - bond->current_arp_slave = NULL; - } - - /* the current slave must tx an arp to ensure backup slaves - * rx traffic - */ - if ((slave != NULL) && - (((jiffies - slave->dev->last_rx) >= the_delta_in_ticks) && - (my_ip != 0))) { - arp_send_all(slave); - } - } - - /* if we don't have a current_slave, search for the next available - * backup slave from the current_arp_slave and make it the candidate - * for becoming the current_slave - */ - if (slave == NULL) { - - if ((bond->current_arp_slave == NULL) || - (bond->current_arp_slave == (slave_t *)bond)) { - bond->current_arp_slave = bond->prev; - } - - if (bond->current_arp_slave != (slave_t *)bond) { - bond_set_slave_inactive_flags(bond->current_arp_slave); - slave = bond->current_arp_slave->next; - - /* search for next candidate */ - do { - if (IS_UP(slave->dev)) { - slave->link = BOND_LINK_BACK; - bond_set_slave_active_flags(slave); - arp_send_all(slave); - slave->jiffies = jiffies; - bond->current_arp_slave = slave; - break; - } - - /* if the link state is up at this point, we - * mark it down - this can happen if we have - * simultaneous link failures and - * change_active_interface doesn't make this - * one the current slave so it is still marked - * up when it is actually down - */ - if (slave->link == BOND_LINK_UP) { - slave->link = BOND_LINK_DOWN; - if (slave->link_failure_count < - UINT_MAX) { - slave->link_failure_count++; - } - - bond_set_slave_inactive_flags(slave); - printk(KERN_INFO - "%s: backup interface " - "%s is now down.\n", - master->name, - slave->dev->name); - } - } while ((slave = slave->next) != - bond->current_arp_slave->next); - } - } - - mod_timer(&bond->arp_timer, next_timer); - read_unlock_irqrestore(&bond->lock, flags); -} - -typedef uint32_t in_addr_t; - -int -my_inet_aton(char *cp, unsigned long *the_addr) { - static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; - in_addr_t val; - char c; - union iaddr { - uint8_t bytes[4]; - uint32_t word; - } res; - uint8_t *pp = res.bytes; - int digit,base; - - res.word = 0; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, isdigit=decimal. - */ - if (!isdigit(c)) goto ret_0; - val = 0; base = 10; digit = 0; - for (;;) { - if (isdigit(c)) { - val = (val * base) + (c - '0'); - c = *++cp; - digit = 1; - } else { - break; - } - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp > res.bytes + 2 || val > 0xff) { - goto ret_0; - } - *pp++ = val; - c = *++cp; - } else - break; - } - /* - * Check for trailing characters. - */ - if (c != '\0' && (!isascii(c) || !isspace(c))) { - goto ret_0; - } - /* - * Did we get a valid digit? - */ - if (!digit) { - goto ret_0; - } - - /* Check whether the last part is in its limits depending on - the number of parts in total. */ - if (val > max[pp - res.bytes]) { - goto ret_0; - } - - if (the_addr != NULL) { - *the_addr = res.word | htonl (val); - } - - return (1); - -ret_0: - return (0); -} - -static int bond_sethwaddr(struct net_device *master, struct net_device *slave) -{ -#ifdef BONDING_DEBUG - printk(KERN_CRIT "bond_sethwaddr: master=%x\n", (unsigned int)master); - printk(KERN_CRIT "bond_sethwaddr: slave=%x\n", (unsigned int)slave); - printk(KERN_CRIT "bond_sethwaddr: slave->addr_len=%d\n", slave->addr_len); -#endif - memcpy(master->dev_addr, slave->dev_addr, slave->addr_len); - return 0; -} - -static int bond_info_query(struct net_device *master, struct ifbond *info) -{ - bonding_t *bond = (struct bonding *) master->priv; - slave_t *slave; - unsigned long flags; - - info->bond_mode = bond_mode; - info->num_slaves = 0; - info->miimon = miimon; - - read_lock_irqsave(&bond->lock, flags); - for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) { - info->num_slaves++; - } - read_unlock_irqrestore(&bond->lock, flags); - - return 0; -} - -static int bond_slave_info_query(struct net_device *master, - struct ifslave *info) -{ - bonding_t *bond = (struct bonding *) master->priv; - slave_t *slave; - int cur_ndx = 0; - unsigned long flags; - - if (info->slave_id < 0) { - return -ENODEV; - } - - read_lock_irqsave(&bond->lock, flags); - for (slave = bond->prev; - slave != (slave_t *)bond && cur_ndx < info->slave_id; - slave = slave->prev) { - cur_ndx++; - } - read_unlock_irqrestore(&bond->lock, flags); - - if (slave != (slave_t *)bond) { - strcpy(info->slave_name, slave->dev->name); - info->link = slave->link; - info->state = slave->state; - info->link_failure_count = slave->link_failure_count; - } else { - return -ENODEV; - } - - return 0; -} - -static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd) -{ - struct net_device *slave_dev = NULL; - struct ifbond *u_binfo = NULL, k_binfo; - struct ifslave *u_sinfo = NULL, k_sinfo; - struct mii_ioctl_data *mii = NULL; - int ret = 0; - -#ifdef BONDING_DEBUG - printk(KERN_INFO "bond_ioctl: master=%s, cmd=%d\n", - master_dev->name, cmd); -#endif - - switch (cmd) { - case SIOCGMIIPHY: - mii = (struct mii_ioctl_data *)&ifr->ifr_data; - if (mii == NULL) { - return -EINVAL; - } - mii->phy_id = 0; - /* Fall Through */ - case SIOCGMIIREG: - /* - * We do this again just in case we were called by SIOCGMIIREG - * instead of SIOCGMIIPHY. - */ - mii = (struct mii_ioctl_data *)&ifr->ifr_data; - if (mii == NULL) { - return -EINVAL; - } - if (mii->reg_num == 1) { - mii->val_out = bond_check_mii_link( - (struct bonding *)master_dev->priv); - } - return 0; - case BOND_INFO_QUERY_OLD: - case SIOCBONDINFOQUERY: - u_binfo = (struct ifbond *)ifr->ifr_data; - if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) { - return -EFAULT; - } - ret = bond_info_query(master_dev, &k_binfo); - if (ret == 0) { - if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) { - return -EFAULT; - } - } - return ret; - case BOND_SLAVE_INFO_QUERY_OLD: - case SIOCBONDSLAVEINFOQUERY: - u_sinfo = (struct ifslave *)ifr->ifr_data; - if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) { - return -EFAULT; - } - ret = bond_slave_info_query(master_dev, &k_sinfo); - if (ret == 0) { - if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) { - return -EFAULT; - } - } - return ret; - } - - if (!capable(CAP_NET_ADMIN)) { - return -EPERM; - } - - slave_dev = dev_get_by_name(ifr->ifr_slave); - -#ifdef BONDING_DEBUG - printk(KERN_INFO "slave_dev=%x: \n", (unsigned int)slave_dev); - printk(KERN_INFO "slave_dev->name=%s: \n", slave_dev->name); -#endif - - if (slave_dev == NULL) { - ret = -ENODEV; - } else { - switch (cmd) { - case BOND_ENSLAVE_OLD: - case SIOCBONDENSLAVE: - ret = bond_enslave(master_dev, slave_dev); - break; - case BOND_RELEASE_OLD: - case SIOCBONDRELEASE: - ret = bond_release(master_dev, slave_dev); - break; - case BOND_SETHWADDR_OLD: - case SIOCBONDSETHWADDR: - ret = bond_sethwaddr(master_dev, slave_dev); - break; - case BOND_CHANGE_ACTIVE_OLD: - case SIOCBONDCHANGEACTIVE: - if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - ret = bond_change_active(master_dev, slave_dev); - } - else { - ret = -EINVAL; - } - break; - default: - ret = -EOPNOTSUPP; - } - dev_put(slave_dev); - } - return ret; -} - -#ifdef CONFIG_NET_FASTROUTE -static int bond_accept_fastpath(struct net_device *dev, struct dst_entry *dst) -{ - return -1; -} -#endif - -/* - * in broadcast mode, we send everything to all usable interfaces. - */ -static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *dev) -{ - slave_t *slave, *start_at; - struct bonding *bond = (struct bonding *) dev->priv; - unsigned long flags; - struct net_device *device_we_should_send_to = 0; - - if (!IS_UP(dev)) { /* bond down */ - dev_kfree_skb(skb); - return 0; - } - - read_lock_irqsave(&bond->lock, flags); - - read_lock(&bond->ptrlock); - slave = start_at = bond->current_slave; - read_unlock(&bond->ptrlock); - - if (slave == NULL) { /* we're at the root, get the first slave */ - /* no suitable interface, frame not sent */ - read_unlock_irqrestore(&bond->lock, flags); - dev_kfree_skb(skb); - return 0; - } - - do { - if (IS_UP(slave->dev) - && (slave->link == BOND_LINK_UP) - && (slave->state == BOND_STATE_ACTIVE)) { - if (device_we_should_send_to) { - struct sk_buff *skb2; - if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) { - printk(KERN_ERR "bond_xmit_broadcast: skb_clone() failed\n"); - continue; - } - - skb2->dev = device_we_should_send_to; - skb2->priority = 1; - dev_queue_xmit(skb2); - } - device_we_should_send_to = slave->dev; - } - } while ((slave = slave->next) != start_at); - - if (device_we_should_send_to) { - skb->dev = device_we_should_send_to; - skb->priority = 1; - dev_queue_xmit(skb); - } else - dev_kfree_skb(skb); - - /* frame sent to all suitable interfaces */ - read_unlock_irqrestore(&bond->lock, flags); - return 0; -} - -static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev) -{ - slave_t *slave, *start_at; - struct bonding *bond = (struct bonding *) dev->priv; - unsigned long flags; - - if (!IS_UP(dev)) { /* bond down */ - dev_kfree_skb(skb); - return 0; - } - - read_lock_irqsave(&bond->lock, flags); - - read_lock(&bond->ptrlock); - slave = start_at = bond->current_slave; - read_unlock(&bond->ptrlock); - - if (slave == NULL) { /* we're at the root, get the first slave */ - /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); - read_unlock_irqrestore(&bond->lock, flags); - return 0; - } - - do { - if (IS_UP(slave->dev) - && (slave->link == BOND_LINK_UP) - && (slave->state == BOND_STATE_ACTIVE)) { - - skb->dev = slave->dev; - skb->priority = 1; - dev_queue_xmit(skb); - - write_lock(&bond->ptrlock); - bond->current_slave = slave->next; - write_unlock(&bond->ptrlock); - - read_unlock_irqrestore(&bond->lock, flags); - return 0; - } - } while ((slave = slave->next) != start_at); - - /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); - read_unlock_irqrestore(&bond->lock, flags); - return 0; -} - -/* - * in XOR mode, we determine the output device by performing xor on - * the source and destination hw adresses. If this device is not - * enabled, find the next slave following this xor slave. - */ -static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev) -{ - slave_t *slave, *start_at; - struct bonding *bond = (struct bonding *) dev->priv; - unsigned long flags; - struct ethhdr *data = (struct ethhdr *)skb->data; - int slave_no; - - if (!IS_UP(dev)) { /* bond down */ - dev_kfree_skb(skb); - return 0; - } - - read_lock_irqsave(&bond->lock, flags); - slave = bond->prev; - - /* we're at the root, get the first slave */ - if (bond->slave_cnt == 0) { - /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); - read_unlock_irqrestore(&bond->lock, flags); - return 0; - } - - slave_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % bond->slave_cnt; - - while ( (slave_no > 0) && (slave != (slave_t *)bond) ) { - slave = slave->prev; - slave_no--; - } - start_at = slave; - - do { - if (IS_UP(slave->dev) - && (slave->link == BOND_LINK_UP) - && (slave->state == BOND_STATE_ACTIVE)) { - - skb->dev = slave->dev; - skb->priority = 1; - dev_queue_xmit(skb); - - read_unlock_irqrestore(&bond->lock, flags); - return 0; - } - } while ((slave = slave->next) != start_at); - - /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); - read_unlock_irqrestore(&bond->lock, flags); - return 0; -} - -/* - * in active-backup mode, we know that bond->current_slave is always valid if - * the bond has a usable interface. - */ -static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev) -{ - struct bonding *bond = (struct bonding *) dev->priv; - unsigned long flags; - int ret; - - if (!IS_UP(dev)) { /* bond down */ - dev_kfree_skb(skb); - return 0; - } - - /* if we are sending arp packets, try to at least - identify our own ip address */ - if ( (arp_interval > 0) && (my_ip == 0) && - (skb->protocol == __constant_htons(ETH_P_ARP) ) ) { - char *the_ip = (((char *)skb->data)) - + sizeof(struct ethhdr) - + sizeof(struct arphdr) + - ETH_ALEN; - memcpy(&my_ip, the_ip, 4); - } - - /* if we are sending arp packets and don't know - * the target hw address, save it so we don't need - * to use a broadcast address. - * don't do this if in active backup mode because the slaves must - * receive packets to stay up, and the only ones they receive are - * broadcasts. - */ - if ( (bond_mode != BOND_MODE_ACTIVEBACKUP) && - (arp_ip_count == 1) && - (arp_interval > 0) && (arp_target_hw_addr == NULL) && - (skb->protocol == __constant_htons(ETH_P_IP) ) ) { - struct ethhdr *eth_hdr = - (struct ethhdr *) (((char *)skb->data)); - struct iphdr *ip_hdr = (struct iphdr *)(eth_hdr + 1); - - if (arp_target[0] == ip_hdr->daddr) { - arp_target_hw_addr = kmalloc(ETH_ALEN, GFP_KERNEL); - if (arp_target_hw_addr != NULL) - memcpy(arp_target_hw_addr, eth_hdr->h_dest, ETH_ALEN); - } - } - - read_lock_irqsave(&bond->lock, flags); - - read_lock(&bond->ptrlock); - if (bond->current_slave != NULL) { /* one usable interface */ - skb->dev = bond->current_slave->dev; - read_unlock(&bond->ptrlock); - skb->priority = 1; - ret = dev_queue_xmit(skb); - read_unlock_irqrestore(&bond->lock, flags); - return 0; - } - else { - read_unlock(&bond->ptrlock); - } - - /* no suitable interface, frame not sent */ -#ifdef BONDING_DEBUG - printk(KERN_INFO "There was no suitable interface, so we don't transmit\n"); -#endif - dev_kfree_skb(skb); - read_unlock_irqrestore(&bond->lock, flags); - return 0; -} - -static struct net_device_stats *bond_get_stats(struct net_device *dev) -{ - bonding_t *bond = dev->priv; - struct net_device_stats *stats = bond->stats, *sstats; - slave_t *slave; - unsigned long flags; - - memset(bond->stats, 0, sizeof(struct net_device_stats)); - - read_lock_irqsave(&bond->lock, flags); - - for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) { - sstats = slave->dev->get_stats(slave->dev); - - stats->rx_packets += sstats->rx_packets; - stats->rx_bytes += sstats->rx_bytes; - stats->rx_errors += sstats->rx_errors; - stats->rx_dropped += sstats->rx_dropped; - - stats->tx_packets += sstats->tx_packets; - stats->tx_bytes += sstats->tx_bytes; - stats->tx_errors += sstats->tx_errors; - stats->tx_dropped += sstats->tx_dropped; - - stats->multicast += sstats->multicast; - stats->collisions += sstats->collisions; - - stats->rx_length_errors += sstats->rx_length_errors; - stats->rx_over_errors += sstats->rx_over_errors; - stats->rx_crc_errors += sstats->rx_crc_errors; - stats->rx_frame_errors += sstats->rx_frame_errors; - stats->rx_fifo_errors += sstats->rx_fifo_errors; - stats->rx_missed_errors += sstats->rx_missed_errors; - - stats->tx_aborted_errors += sstats->tx_aborted_errors; - stats->tx_carrier_errors += sstats->tx_carrier_errors; - stats->tx_fifo_errors += sstats->tx_fifo_errors; - stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors; - stats->tx_window_errors += sstats->tx_window_errors; - - } - - read_unlock_irqrestore(&bond->lock, flags); - return stats; -} - -static int bond_get_info(char *buf, char **start, off_t offset, int length) -{ - bonding_t *bond = these_bonds; - int len = 0; - off_t begin = 0; - u16 link; - slave_t *slave = NULL; - unsigned long flags; - - while (bond != NULL) { - /* - * This function locks the mutex, so we can't lock it until - * afterwards - */ - link = bond_check_mii_link(bond); - - len += sprintf(buf + len, "Bonding Mode: %s\n", - bond_mode_name()); - - if (bond_mode == BOND_MODE_ACTIVEBACKUP) { - read_lock_irqsave(&bond->lock, flags); - read_lock(&bond->ptrlock); - if (bond->current_slave != NULL) { - len += sprintf(buf + len, - "Currently Active Slave: %s\n", - bond->current_slave->dev->name); - } - read_unlock(&bond->ptrlock); - read_unlock_irqrestore(&bond->lock, flags); - } - - len += sprintf(buf + len, "MII Status: "); - len += sprintf(buf + len, - link == BMSR_LSTATUS ? "up\n" : "down\n"); - len += sprintf(buf + len, "MII Polling Interval (ms): %d\n", - miimon); - len += sprintf(buf + len, "Up Delay (ms): %d\n", - updelay * miimon); - len += sprintf(buf + len, "Down Delay (ms): %d\n", - downdelay * miimon); - len += sprintf(buf + len, "Multicast Mode: %s\n", - multicast_mode_name()); - - read_lock_irqsave(&bond->lock, flags); - for (slave = bond->prev; slave != (slave_t *)bond; - slave = slave->prev) { - len += sprintf(buf + len, "\nSlave Interface: %s\n", slave->dev->name); - - len += sprintf(buf + len, "MII Status: "); - - len += sprintf(buf + len, - slave->link == BOND_LINK_UP ? - "up\n" : "down\n"); - len += sprintf(buf + len, "Link Failure Count: %d\n", - slave->link_failure_count); - } - read_unlock_irqrestore(&bond->lock, flags); - - /* - * Figure out the calcs for the /proc/net interface - */ - *start = buf + (offset - begin); - len -= (offset - begin); - if (len > length) { - len = length; - } - if (len < 0) { - len = 0; - } - - - bond = bond->next_bond; - } - return len; -} - -static int bond_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct bonding *this_bond = (struct bonding *)these_bonds; - struct bonding *last_bond; - struct net_device *event_dev = (struct net_device *)ptr; - - /* while there are bonds configured */ - while (this_bond != NULL) { - if (this_bond == event_dev->priv ) { - switch (event) { - case NETDEV_UNREGISTER: - /* - * remove this bond from a linked list of - * bonds - */ - if (this_bond == these_bonds) { - these_bonds = this_bond->next_bond; - } else { - for (last_bond = these_bonds; - last_bond != NULL; - last_bond = last_bond->next_bond) { - if (last_bond->next_bond == - this_bond) { - last_bond->next_bond = - this_bond->next_bond; - } - } - } - return NOTIFY_DONE; - - default: - return NOTIFY_DONE; - } - } else if (this_bond->device == event_dev->master) { - switch (event) { - case NETDEV_UNREGISTER: - bond_release(this_bond->device, event_dev); - break; - } - return NOTIFY_DONE; - } - this_bond = this_bond->next_bond; - } - return NOTIFY_DONE; -} - -static struct notifier_block bond_netdev_notifier = { - notifier_call: bond_event, -}; - -static int __init bond_init(struct net_device *dev) -{ - bonding_t *bond, *this_bond, *last_bond; - int count; - -#ifdef BONDING_DEBUG - printk (KERN_INFO "Begin bond_init for %s\n", dev->name); -#endif - bond = kmalloc(sizeof(struct bonding), GFP_KERNEL); - if (bond == NULL) { - return -ENOMEM; - } - memset(bond, 0, sizeof(struct bonding)); - - /* initialize rwlocks */ - rwlock_init(&bond->lock); - rwlock_init(&bond->ptrlock); - - bond->stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); - if (bond->stats == NULL) { - kfree(bond); - return -ENOMEM; - } - memset(bond->stats, 0, sizeof(struct net_device_stats)); - - bond->next = bond->prev = (slave_t *)bond; - bond->current_slave = NULL; - bond->current_arp_slave = NULL; - bond->device = dev; - dev->priv = bond; - - /* Initialize the device structure. */ - switch (bond_mode) { - case BOND_MODE_ACTIVEBACKUP: - dev->hard_start_xmit = bond_xmit_activebackup; - break; - case BOND_MODE_ROUNDROBIN: - dev->hard_start_xmit = bond_xmit_roundrobin; - break; - case BOND_MODE_XOR: - dev->hard_start_xmit = bond_xmit_xor; - break; - case BOND_MODE_BROADCAST: - dev->hard_start_xmit = bond_xmit_broadcast; - break; - default: - printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode); - kfree(bond->stats); - kfree(bond); - return -EINVAL; - } - - dev->get_stats = bond_get_stats; - dev->open = bond_open; - dev->stop = bond_close; - dev->set_multicast_list = set_multicast_list; - dev->do_ioctl = bond_ioctl; - - /* - * Fill in the fields of the device structure with ethernet-generic - * values. - */ - - ether_setup(dev); - - dev->tx_queue_len = 0; - dev->flags |= IFF_MASTER|IFF_MULTICAST; -#ifdef CONFIG_NET_FASTROUTE - dev->accept_fastpath = bond_accept_fastpath; -#endif - - printk(KERN_INFO "%s registered with", dev->name); - if (miimon > 0) { - printk(" MII link monitoring set to %d ms", miimon); - updelay /= miimon; - downdelay /= miimon; - } else { - printk("out MII link monitoring"); - } - printk(", in %s mode.\n", bond_mode_name()); - - printk(KERN_INFO "%s registered with", dev->name); - if (arp_interval > 0) { - printk(" ARP monitoring set to %d ms with %d target(s):", - arp_interval, arp_ip_count); - for (count=0 ; countbond_proc_dir = proc_mkdir(dev->name, proc_net); - if (bond->bond_proc_dir == NULL) { - printk(KERN_ERR "%s: Cannot init /proc/net/%s/\n", - dev->name, dev->name); - kfree(bond->stats); - kfree(bond); - return -ENOMEM; - } - bond->bond_proc_info_file = - create_proc_info_entry("info", 0, bond->bond_proc_dir, - bond_get_info); - if (bond->bond_proc_info_file == NULL) { - printk(KERN_ERR "%s: Cannot init /proc/net/%s/info\n", - dev->name, dev->name); - remove_proc_entry(dev->name, proc_net); - kfree(bond->stats); - kfree(bond); - return -ENOMEM; - } -#endif /* CONFIG_PROC_FS */ - - if (first_pass == 1) { - these_bonds = bond; - register_netdevice_notifier(&bond_netdev_notifier); - first_pass = 0; - } else { - last_bond = these_bonds; - this_bond = these_bonds->next_bond; - while (this_bond != NULL) { - last_bond = this_bond; - this_bond = this_bond->next_bond; - } - last_bond->next_bond = bond; - } - - return 0; -} - -/* -static int __init bond_probe(struct net_device *dev) -{ - bond_init(dev); - return 0; -} - */ - -/* - * Convert string input module parms. Accept either the - * number of the mode or its string name. - */ -static inline int -bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) -{ - int i; - - for (i = 0; tbl[i].modename != NULL; i++) { - if ((isdigit(*mode_arg) && - tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || - (0 == strncmp(mode_arg, tbl[i].modename, - strlen(tbl[i].modename)))) { - return tbl[i].mode; - } - } - - return -1; -} - - -static int __init bonding_init(void) -{ - int no; - int err; - - /* Find a name for this unit */ - static struct net_device *dev_bond = NULL; - - printk(KERN_INFO "%s", version); - - /* - * Convert string parameters. - */ - if (mode) { - bond_mode = bond_parse_parm(mode, bond_mode_tbl); - if (bond_mode == -1) { - printk(KERN_WARNING - "bonding_init(): Invalid bonding mode \"%s\"\n", - mode == NULL ? "NULL" : mode); - return -EINVAL; - } - } - - if (multicast) { - multicast_mode = bond_parse_parm(multicast, bond_mc_tbl); - if (multicast_mode == -1) { - printk(KERN_WARNING - "bonding_init(): Invalid multicast mode \"%s\"\n", - multicast == NULL ? "NULL" : multicast); - return -EINVAL; - } - } - - if (max_bonds < 1 || max_bonds > INT_MAX) { - printk(KERN_WARNING - "bonding_init(): max_bonds (%d) not in range %d-%d, " - "so it was reset to BOND_DEFAULT_MAX_BONDS (%d)", - max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS); - max_bonds = BOND_DEFAULT_MAX_BONDS; - } - dev_bond = dev_bonds = kmalloc(max_bonds*sizeof(struct net_device), - GFP_KERNEL); - if (dev_bond == NULL) { - return -ENOMEM; - } - memset(dev_bonds, 0, max_bonds*sizeof(struct net_device)); - - if (miimon < 0) { - printk(KERN_WARNING - "bonding_init(): miimon module parameter (%d), " - "not in range 0-%d, so it was reset to %d\n", - miimon, INT_MAX, BOND_LINK_MON_INTERV); - miimon = BOND_LINK_MON_INTERV; - } - - if (updelay < 0) { - printk(KERN_WARNING - "bonding_init(): updelay module parameter (%d), " - "not in range 0-%d, so it was reset to 0\n", - updelay, INT_MAX); - updelay = 0; - } - - if (downdelay < 0) { - printk(KERN_WARNING - "bonding_init(): downdelay module parameter (%d), " - "not in range 0-%d, so it was reset to 0\n", - downdelay, INT_MAX); - downdelay = 0; - } - - if (miimon == 0) { - if ((updelay != 0) || (downdelay != 0)) { - /* just warn the user the up/down delay will have - * no effect since miimon is zero... - */ - printk(KERN_WARNING - "bonding_init(): miimon module parameter not " - "set and updelay (%d) or downdelay (%d) module " - "parameter is set; updelay and downdelay have " - "no effect unless miimon is set\n", - updelay, downdelay); - } - } else { - /* don't allow arp monitoring */ - if (arp_interval != 0) { - printk(KERN_WARNING - "bonding_init(): miimon (%d) and arp_interval " - "(%d) can't be used simultaneously, " - "disabling ARP monitoring\n", - miimon, arp_interval); - arp_interval = 0; - } - - if ((updelay % miimon) != 0) { - /* updelay will be rounded in bond_init() when it - * is divided by miimon, we just inform user here - */ - printk(KERN_WARNING - "bonding_init(): updelay (%d) is not a multiple " - "of miimon (%d), updelay rounded to %d ms\n", - updelay, miimon, (updelay / miimon) * miimon); - } - - if ((downdelay % miimon) != 0) { - /* downdelay will be rounded in bond_init() when it - * is divided by miimon, we just inform user here - */ - printk(KERN_WARNING - "bonding_init(): downdelay (%d) is not a " - "multiple of miimon (%d), downdelay rounded " - "to %d ms\n", - downdelay, miimon, - (downdelay / miimon) * miimon); - } - } - - if (arp_interval < 0) { - printk(KERN_WARNING - "bonding_init(): arp_interval module parameter (%d), " - "not in range 0-%d, so it was reset to %d\n", - arp_interval, INT_MAX, BOND_LINK_ARP_INTERV); - arp_interval = BOND_LINK_ARP_INTERV; - } - - for (arp_ip_count=0 ; - (arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count]; - arp_ip_count++ ) { - /* TODO: check and log bad ip address */ - if (my_inet_aton(arp_ip_target[arp_ip_count], - &arp_target[arp_ip_count]) == 0) { - printk(KERN_WARNING - "bonding_init(): bad arp_ip_target module " - "parameter (%s), ARP monitoring will not be " - "performed\n", - arp_ip_target[arp_ip_count]); - arp_interval = 0; - } - } - - - if ( (arp_interval > 0) && (arp_ip_count==0)) { - /* don't allow arping if no arp_ip_target given... */ - printk(KERN_WARNING - "bonding_init(): arp_interval module parameter " - "(%d) specified without providing an arp_ip_target " - "parameter, arp_interval was reset to 0\n", - arp_interval); - arp_interval = 0; - } - - if ((miimon == 0) && (arp_interval == 0)) { - /* miimon and arp_interval not set, we need one so things - * work as expected, see bonding.txt for details - */ - printk(KERN_ERR - "bonding_init(): either miimon or " - "arp_interval and arp_ip_target module parameters " - "must be specified, otherwise bonding will not detect " - "link failures! see bonding.txt for details.\n"); - } - - if ((primary != NULL) && (bond_mode != BOND_MODE_ACTIVEBACKUP)){ - /* currently, using a primary only makes sence - * in active backup mode - */ - printk(KERN_WARNING - "bonding_init(): %s primary device specified but has " - " no effect in %s mode\n", - primary, bond_mode_name()); - primary = NULL; - } - - - for (no = 0; no < max_bonds; no++) { - dev_bond->init = bond_init; - - err = dev_alloc_name(dev_bond,"bond%d"); - if (err < 0) { - kfree(dev_bonds); - return err; - } - SET_MODULE_OWNER(dev_bond); - if (register_netdev(dev_bond) != 0) { - kfree(dev_bonds); - return -EIO; - } - dev_bond++; - } - return 0; -} - -static void __exit bonding_exit(void) -{ - struct net_device *dev_bond = dev_bonds; - struct bonding *bond; - int no; - - unregister_netdevice_notifier(&bond_netdev_notifier); - - for (no = 0; no < max_bonds; no++) { - -#ifdef CONFIG_PROC_FS - bond = (struct bonding *) dev_bond->priv; - remove_proc_entry("info", bond->bond_proc_dir); - remove_proc_entry(dev_bond->name, proc_net); -#endif - unregister_netdev(dev_bond); - kfree(bond->stats); - kfree(dev_bond->priv); - - dev_bond->priv = NULL; - dev_bond++; - } - kfree(dev_bonds); -} - -module_init(bonding_init); -module_exit(bonding_exit); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION); - -/* - * Local variables: - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - */ diff -urN linux-2.4.21/drivers/net/cs89x0.c linux-2.4.22/drivers/net/cs89x0.c --- linux-2.4.21/drivers/net/cs89x0.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/cs89x0.c 2003-08-25 04:44:42.000000000 -0700 @@ -1629,16 +1629,21 @@ } -static int set_mac_address(struct net_device *dev, void *addr) +static int set_mac_address(struct net_device *dev, void *p) { int i; + struct sockaddr *addr = p; + if (netif_running(dev)) return -EBUSY; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + if (net_debug) { printk("%s: Setting MAC address to ", dev->name); - for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]); + for (i = 0; i < dev->addr_len; i++) + printk(" %2.2x", dev->dev_addr[i]); printk(".\n"); } /* set the Ethernet address */ diff -urN linux-2.4.21/drivers/net/dgrs.c linux-2.4.22/drivers/net/dgrs.c --- linux-2.4.21/drivers/net/dgrs.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/dgrs.c 2003-08-25 04:44:42.000000000 -0700 @@ -1279,8 +1279,10 @@ dev->init = dgrs_probe1; SET_MODULE_OWNER(dev); ether_setup(dev); - if (register_netdev(dev) != 0) + if (register_netdev(dev) != 0) { + kfree(dev); return -EIO; + } priv->next_dev = dgrs_root_dev; dgrs_root_dev = dev; diff -urN linux-2.4.21/drivers/net/dl2k.h linux-2.4.22/drivers/net/dl2k.h --- linux-2.4.21/drivers/net/dl2k.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/dl2k.h 2003-08-25 04:44:42.000000000 -0700 @@ -243,7 +243,6 @@ VLANTagInsert = 0x0000000010000000, TFDDone = 0x80000000, VIDShift = 32, - CFI = 0x0000100000000000, UsePriorityShift = 48, }; diff -urN linux-2.4.21/drivers/net/e100/e100.h linux-2.4.22/drivers/net/e100/e100.h --- linux-2.4.21/drivers/net/e100/e100.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e100/e100.h 2003-08-25 04:44:42.000000000 -0700 @@ -60,7 +60,14 @@ #include #include -#define E100_REGS_LEN 1 +#define E100_CABLE_UNKNOWN 0 +#define E100_CABLE_OK 1 +#define E100_CABLE_OPEN_NEAR 2 /* Open Circuit Near End */ +#define E100_CABLE_OPEN_FAR 3 /* Open Circuit Far End */ +#define E100_CABLE_SHORT_NEAR 4 /* Short Circuit Near End */ +#define E100_CABLE_SHORT_FAR 5 /* Short Circuit Far End */ + +#define E100_REGS_LEN 2 /* * Configure parameters for buffers per controller. * If the machine this is being used on is a faster machine (i.e. > 150MHz) @@ -105,8 +112,6 @@ #define E100_MAX_CU_IDLE_WAIT 50 /* Max udelays in wait_cus_idle */ /* HWI feature related constant */ -#define HWI_MAX_LOOP 100 -#define MAX_SAME_RESULTS 3 #define HWI_REGISTER_GRANULARITY 80 /* register granularity = 80 Cm */ #define HWI_NEAR_END_BOUNDARY 1000 /* Near end is defined as < 10 meters */ @@ -942,7 +947,6 @@ #ifdef CONFIG_PM u32 pci_state[16]; #endif - char ifname[IFNAMSIZ]; #ifdef E100_CU_DEBUG u8 last_cmd; u8 last_sub_cmd; @@ -956,7 +960,10 @@ #define E100_SPEED_100_FULL 4 /********* function prototypes *************/ +extern int e100_open(struct net_device *); +extern int e100_close(struct net_device *); extern void e100_isolate_driver(struct e100_private *bdp); +extern unsigned char e100_hw_init(struct e100_private *); extern void e100_sw_reset(struct e100_private *bdp, u32 reset_cmd); extern u8 e100_start_cu(struct e100_private *bdp, tcb_t *tcb); extern void e100_free_non_tx_cmd(struct e100_private *bdp, @@ -981,14 +988,13 @@ #define TEST_TIMEOUT 0x08 enum test_offsets { - E100_EEPROM_TEST_FAIL = 0, - E100_CHIP_TIMEOUT, - E100_ROM_TEST_FAIL, - E100_REG_TEST_FAIL, - E100_MAC_TEST_FAIL, - E100_LPBK_MAC_FAIL, - E100_LPBK_PHY_FAIL, - E100_MAX_TEST_RES + test_link, + test_eeprom, + test_self_test, + test_loopback_mac, + test_loopback_phy, + cable_diag, + max_test_res, /* must be last */ }; #endif diff -urN linux-2.4.21/drivers/net/e100/e100_main.c linux-2.4.22/drivers/net/e100/e100_main.c --- linux-2.4.21/drivers/net/e100/e100_main.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e100/e100_main.c 2003-08-25 04:44:42.000000000 -0700 @@ -46,36 +46,32 @@ /* Change Log * - * 2.2.21 02/11/03 - * o Removed marketing brand strings. Instead, Using generic string - * "Intel(R) PRO/100 Network Connection" for all adapters. - * o Implemented ethtool -S option - * o Strip /proc/net/PRO_LAN_Adapters files for kernel driver - * o Bug fix: Read wrong byte in EEPROM when offset is odd number - * o Bug fix: PHY loopback test fails on ICH devices - * o Bug fix: System panic on e100_close when repeating Hot Remove and - * Add in a team - * o Bug fix: Linux Bonding driver claims adapter's link loss because of - * not updating last_rx field - * o Bug fix: e100 does not check validity of MAC address - * o New feature: added ICH5 support + * 2.3.18 07/08/03 + * o Bug fix: read skb->len after freeing skb + * [Andrew Morton] akpm@zip.com.au + * o Bug fix: 82557 (with National PHY) timeout during init + * [Adam Kropelin] akropel1@rochester.rr.com + * o Feature add: allow to change Wake On LAN when EEPROM disabled * - * 2.1.27 11/20/02 - * o Bug fix: Device command timeout due to SMBus processing during init - * o Bug fix: Not setting/clearing I (Interrupt) bit in tcb correctly - * o Bug fix: Not using EEPROM WoL setting as default in ethtool - * o Bug fix: Not able to set autoneg on using ethtool when interface down - * o Bug fix: Not able to change speed/duplex using ethtool/mii - * when interface up - * o Bug fix: Ethtool shows autoneg on when forced to 100/Full - * o Bug fix: Compiler error when CONFIG_PROC_FS not defined - * o Bug fix: 2.5.44 e100 doesn't load with preemptive kernel enabled - * (sleep while holding spinlock) - * o Bug fix: 2.1.24-k1 doesn't display complete statistics - * o Bug fix: System panic due to NULL watchdog timer dereference during - * ifconfig down, rmmod and insmod - * - * 2.1.24 10/7/02 + * 2.3.13 05/08/03 + * o Feature remove: /proc/net/PRO_LAN_Adapters support gone completely + * o Feature remove: IDIAG support (use ethtool -t instead) + * o Cleanup: fixed spelling mistakes found by community + * o Feature add: ethtool cable diag test + * o Feature add: ethtool parameter support (ring size, xsum, flow ctrl) + * o Cleanup: move e100_asf_enable under CONFIG_PM to avoid warning + * [Stephen Rothwell (sfr@canb.auug.org.au)] + * o Bug fix: don't call any netif_carrier_* until netdev registered. + * [Andrew Morton (akpm@digeo.com)] + * o Cleanup: replace (skb->len - skb->data_len) with skb_headlen(skb) + * [jmorris@intercode.com.au] + * o Bug fix: cleanup of Tx skbs after running ethtool diags + * o Bug fix: incorrect reporting of ethtool diag overall results + * o Bug fix: must hold xmit_lock before stopping queue in ethtool + * operations that require reset h/w and driver structures. + * o Bug fix: statistic command failure would stop statistic collection. + * + * 2.2.21 02/11/03 */ #include @@ -121,14 +117,13 @@ extern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags); static int e100_ethtool_test(struct net_device *, struct ifreq *); static int e100_ethtool_gstrings(struct net_device *, struct ifreq *); -static char *test_strings[] = { - "E100_EEPROM_TEST_FAIL", - "E100_CHIP_TIMEOUT", - "E100_ROM_TEST_FAIL", - "E100_REG_TEST_FAIL", - "E100_MAC_TEST_FAIL", - "E100_LPBK_MAC_FAIL", - "E100_LPBK_PHY_FAIL" +static char test_strings[][ETH_GSTRING_LEN] = { + "Link test (on/offline)", + "Eeprom test (on/offline)", + "Self test (offline)", + "Mac loopback (offline)", + "Phy loopback (offline)", + "Cable diagnostic (offline)" }; static int e100_ethtool_led_blink(struct net_device *, struct ifreq *); @@ -139,10 +134,10 @@ nxmit_cb_entry_t *); static void e100_free_nontx_list(struct e100_private *); static void e100_non_tx_background(unsigned long); - +static inline void e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb); /* Global Data structures and variables */ char e100_copyright[] __devinitdata = "Copyright (c) 2003 Intel Corporation"; -char e100_driver_version[]="2.2.21-k1"; +char e100_driver_version[]="2.3.18-k1"; const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver"; char e100_short_driver_name[] = "e100"; static int e100nics = 0; @@ -155,6 +150,7 @@ static int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); static int e100_suspend(struct pci_dev *pcid, u32 state); static int e100_resume(struct pci_dev *pcid); +static unsigned char e100_asf_enabled(struct e100_private *bdp); struct notifier_block e100_notifier_reboot = { .notifier_call = e100_notify_reboot, .next = NULL, @@ -182,8 +178,6 @@ static u8 e100_D101M_checksum(struct e100_private *, struct sk_buff *); static u8 e100_D102_check_checksum(rfd_t *); static int e100_ioctl(struct net_device *, struct ifreq *, int); -static int e100_open(struct net_device *); -static int e100_close(struct net_device *); static int e100_change_mtu(struct net_device *, int); static int e100_xmit_frame(struct sk_buff *, struct net_device *); static unsigned char e100_init(struct e100_private *); @@ -193,7 +187,6 @@ static void e100intr(int, void *, struct pt_regs *); static void e100_print_brd_conf(struct e100_private *); static void e100_set_multi(struct net_device *); -void e100_set_speed_duplex(struct e100_private *); static u8 e100_pci_setup(struct pci_dev *, struct e100_private *); static u8 e100_sw_init(struct e100_private *); @@ -215,7 +208,6 @@ static unsigned char e100_clr_cntrs(struct e100_private *); static unsigned char e100_load_microcode(struct e100_private *); -static unsigned char e100_hw_init(struct e100_private *); static unsigned char e100_setup_iaaddr(struct e100_private *, u8 *); static unsigned char e100_update_stats(struct e100_private *bdp); @@ -228,7 +220,6 @@ char *); unsigned char e100_wait_exec_cmplx(struct e100_private *, u32, u8, u8); void e100_exec_cmplx(struct e100_private *, u32, u8); -static unsigned char e100_asf_enabled(struct e100_private *bdp); /** * e100_get_rx_struct - retrieve cell to hold skb buff from the pool @@ -638,25 +629,7 @@ } else { bdp->rfd_size = 16; } - e100_check_options(e100nics, bdp); - if (!e100_init(bdp)) { - printk(KERN_ERR "e100: Failed to initialize, instance #%d\n", - e100nics); - rc = -ENODEV; - goto err_pci; - } - - /* Check if checksum is valid */ - cal_checksum = e100_eeprom_calculate_chksum(bdp); - read_checksum = e100_eeprom_read(bdp, (bdp->eeprom_size - 1)); - if (cal_checksum != read_checksum) { - printk(KERN_ERR "e100: Corrupted EEPROM on instance #%d\n", - e100nics); - rc = -ENODEV; - goto err_pci; - } - dev->vlan_rx_register = e100_vlan_rx_register; dev->vlan_rx_add_vid = e100_vlan_rx_add_vid; dev->vlan_rx_kill_vid = e100_vlan_rx_kill_vid; @@ -674,15 +647,32 @@ dev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - e100nics++; - - e100_get_speed_duplex_caps(bdp); - if ((rc = register_netdev(dev)) != 0) { goto err_pci; } - memcpy(bdp->ifname, dev->name, IFNAMSIZ); - bdp->ifname[IFNAMSIZ-1] = 0; + + e100_check_options(e100nics, bdp); + + if (!e100_init(bdp)) { + printk(KERN_ERR "e100: Failed to initialize, instance #%d\n", + e100nics); + rc = -ENODEV; + goto err_unregister_netdev; + } + + /* Check if checksum is valid */ + cal_checksum = e100_eeprom_calculate_chksum(bdp); + read_checksum = e100_eeprom_read(bdp, (bdp->eeprom_size - 1)); + if (cal_checksum != read_checksum) { + printk(KERN_ERR "e100: Corrupted EEPROM on instance #%d\n", + e100nics); + rc = -ENODEV; + goto err_unregister_netdev; + } + + e100nics++; + + e100_get_speed_duplex_caps(bdp); printk(KERN_NOTICE "e100: %s: %s\n", @@ -691,23 +681,24 @@ bdp->wolsupported = 0; bdp->wolopts = 0; + if (bdp->rev_id >= D101A4_REV_ID) + bdp->wolsupported = WAKE_PHY | WAKE_MAGIC; + if (bdp->rev_id >= D101MA_REV_ID) + bdp->wolsupported |= WAKE_UCAST | WAKE_ARP; /* Check if WoL is enabled on EEPROM */ if (e100_eeprom_read(bdp, EEPROM_ID_WORD) & BIT_5) { /* Magic Packet WoL is enabled on device by default */ /* if EEPROM WoL bit is TRUE */ - bdp->wolsupported = WAKE_MAGIC; bdp->wolopts = WAKE_MAGIC; - if (bdp->rev_id >= D101A4_REV_ID) - bdp->wolsupported = WAKE_PHY | WAKE_MAGIC; - if (bdp->rev_id >= D101MA_REV_ID) - bdp->wolsupported |= WAKE_UCAST | WAKE_ARP; } printk(KERN_NOTICE "\n"); goto out; +err_unregister_netdev: + unregister_netdev(dev); err_pci: iounmap(bdp->scb); pci_release_regions(pcid); @@ -973,7 +964,7 @@ } } -static int +int e100_open(struct net_device *dev) { struct e100_private *bdp; @@ -1011,7 +1002,11 @@ mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ)); - netif_start_queue(dev); + if (dev->flags & IFF_UP) + /* Otherwise process may sleep forever */ + netif_wake_queue(dev); + else + netif_start_queue(dev); e100_start_ru(bdp); if ((rc = request_irq(dev->irq, &e100intr, SA_SHIRQ, @@ -1032,7 +1027,7 @@ return rc; } -static int +int e100_close(struct net_device *dev) { struct e100_private *bdp = dev->priv; @@ -1073,17 +1068,18 @@ goto exit2; } - if (!TCBS_AVAIL(bdp->tcb_pool) || + /* tcb list may be empty temporarily during releasing resources */ + if (!TCBS_AVAIL(bdp->tcb_pool) || (bdp->tcb_phys == 0) || (bdp->non_tx_command_state != E100_NON_TX_IDLE)) { notify_stop = true; rc = 1; goto exit1; } - e100_prepare_xmit_buff(bdp, skb); - bdp->drv_stats.net_stats.tx_bytes += skb->len; + e100_prepare_xmit_buff(bdp, skb); + dev->trans_start = jiffies; exit1: @@ -1284,10 +1280,8 @@ /* read NIC's part number */ e100_rd_pwa_no(bdp); - if (!e100_hw_init(bdp)) { - printk(KERN_ERR "e100: hw init failed\n"); + if (!e100_hw_init(bdp)) return false; - } /* Interrupts are enabled after device reset */ e100_disable_clear_intr(bdp); @@ -1329,6 +1323,8 @@ spin_lock_init(&(bdp->bd_non_tx_lock)); spin_lock_init(&(bdp->config_lock)); spin_lock_init(&(bdp->mdi_access_lock)); + /* Initialize configuration data */ + e100_config_init(bdp); return 1; } @@ -1383,11 +1379,11 @@ * true - If the adapter was initialized * false - If the adapter failed initialization */ -unsigned char __devinit +unsigned char e100_hw_init(struct e100_private *bdp) { if (!e100_phy_init(bdp)) - return false; + goto err; e100_sw_reset(bdp, PORT_SELECTIVE_RESET); @@ -1397,27 +1393,25 @@ /* Load the CU BASE (set to 0, because we use linear mode) */ if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0)) - return false; + goto err; if (!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE, 0)) - return false; + goto err; /* Load interrupt microcode */ if (e100_load_microcode(bdp)) { bdp->flags |= DF_UCODE_LOADED; } - e100_config_init(bdp); - if (!e100_config(bdp)) { - return false; - } + if (!e100_config(bdp)) + goto err; if (!e100_setup_iaaddr(bdp, bdp->device->dev_addr)) - return false; + goto err; /* Clear the internal counters */ if (!e100_clr_cntrs(bdp)) - return false; + goto err; /* Change for 82558 enhancement */ /* If 82558/9 and if the user has enabled flow control, set up the @@ -1430,6 +1424,9 @@ } return true; +err: + printk(KERN_ERR "e100: hw init failed\n"); + return false; } /** @@ -1590,9 +1587,22 @@ void e100_free_tcb_pool(struct e100_private *bdp) { + tcb_t *tcb; + int i; + /* Return tx skbs */ + for (i = 0; i < bdp->params.TxDescriptors; i++) { + tcb = bdp->tcb_pool.data; + tcb += bdp->tcb_pool.head; + e100_tx_skb_free(bdp, tcb); + if (NEXT_TCB_TOUSE(bdp->tcb_pool.head) == bdp->tcb_pool.tail) + break; + bdp->tcb_pool.head = NEXT_TCB_TOUSE(bdp->tcb_pool.head); + } pci_free_consistent(bdp->pdev, sizeof (tcb_t) * bdp->params.TxDescriptors, bdp->tcb_pool.data, bdp->tcb_phys); + bdp->tcb_pool.head = 0; + bdp->tcb_pool.tail = 1; bdp->tcb_phys = 0; } @@ -1746,12 +1756,10 @@ e100_set_multi(dev); } } - - /* Update the statistics needed by the upper interface */ - /* This should be the last statistic related command - * as it's async. now */ - e100_dump_stats_cntrs(bdp); } + /* Issue command to dump statistics from device. */ + /* Check for command completion on next watchdog timer. */ + e100_dump_stats_cntrs(bdp); wmb(); @@ -2050,13 +2058,14 @@ skb->ip_summed = CHECKSUM_NONE; } + bdp->drv_stats.net_stats.rx_bytes += skb->len; + if(bdp->vlgrp && (rfd_status & CB_STATUS_VLAN)) { vlan_hwaccel_rx(skb, bdp->vlgrp, be16_to_cpu(rfd->vlanid)); } else { netif_rx(skb); } dev->last_rx = jiffies; - bdp->drv_stats.net_stats.rx_bytes += skb->len; rfd_cnt++; } /* end of rfd loop */ @@ -2199,10 +2208,10 @@ (tcb->tbd_ptr)->tbd_buf_addr = cpu_to_le32(pci_map_single(bdp->pdev, skb->data, - (skb->len - skb->data_len), + skb_headlen(skb), PCI_DMA_TODEVICE)); (tcb->tbd_ptr)->tbd_buf_cnt = - cpu_to_le16(skb->len - skb->data_len); + cpu_to_le16(skb_headlen(skb)); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, tbd_arr_ptr++, frag++) { @@ -2542,6 +2551,7 @@ pcmd_complete = e100_cmd_complete_location(bdp); if (*pcmd_complete != le32_to_cpu(DUMP_RST_STAT_COMPLETED) && *pcmd_complete != le32_to_cpu(DUMP_STAT_COMPLETED)) { + *pcmd_complete = 0; return false; } @@ -3039,23 +3049,6 @@ e100_sw_reset(bdp, PORT_SELECTIVE_RESET); } -void -e100_set_speed_duplex(struct e100_private *bdp) -{ - int carrier_ok; - /* Device may lose link with some siwtches when */ - /* changing speed/duplex to non-autoneg. e100 */ - /* needs to remember carrier state in order to */ - /* start watchdog timer for recovering link */ - if ((carrier_ok = netif_carrier_ok(bdp->device))) - e100_isolate_driver(bdp); - e100_phy_set_speed_duplex(bdp, true); - e100_config_fc(bdp); /* re-config flow-control if necessary */ - e100_config(bdp); - if (carrier_ok) - e100_deisolate_driver(bdp, false); -} - static void e100_tcb_add_C_bit(struct e100_private *bdp) { @@ -3211,6 +3204,144 @@ case ETHTOOL_PHYS_ID: rc = e100_ethtool_led_blink(dev,ifr); break; +#ifdef ETHTOOL_GRINGPARAM + case ETHTOOL_GRINGPARAM: { + struct ethtool_ringparam ering; + struct e100_private *bdp = dev->priv; + memset((void *) &ering, 0, sizeof(ering)); + ering.rx_max_pending = E100_MAX_RFD; + ering.tx_max_pending = E100_MAX_TCB; + ering.rx_pending = bdp->params.RxDescriptors; + ering.tx_pending = bdp->params.TxDescriptors; + rc = copy_to_user(ifr->ifr_data, &ering, sizeof(ering)) + ? -EFAULT : 0; + return rc; + } +#endif +#ifdef ETHTOOL_SRINGPARAM + case ETHTOOL_SRINGPARAM: { + struct ethtool_ringparam ering; + struct e100_private *bdp = dev->priv; + if (copy_from_user(&ering, ifr->ifr_data, sizeof(ering))) + return -EFAULT; + if (ering.rx_pending > E100_MAX_RFD + || ering.rx_pending < E100_MIN_RFD) + return -EINVAL; + if (ering.tx_pending > E100_MAX_TCB + || ering.tx_pending < E100_MIN_TCB) + return -EINVAL; + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + /* Use new values to open interface */ + bdp->params.RxDescriptors = ering.rx_pending; + bdp->params.TxDescriptors = ering.tx_pending; + e100_hw_init(bdp); + e100_open(dev); + } + else { + bdp->params.RxDescriptors = ering.rx_pending; + bdp->params.TxDescriptors = ering.tx_pending; + } + return 0; + } +#endif +#ifdef ETHTOOL_GPAUSEPARAM + case ETHTOOL_GPAUSEPARAM: { + struct ethtool_pauseparam epause; + struct e100_private *bdp = dev->priv; + memset((void *) &epause, 0, sizeof(epause)); + if ((bdp->flags & IS_BACHELOR) + && (bdp->params.b_params & PRM_FC)) { + epause.autoneg = 1; + if (bdp->flags && DF_LINK_FC_CAP) { + epause.rx_pause = 1; + epause.tx_pause = 1; + } + if (bdp->flags && DF_LINK_FC_TX_ONLY) + epause.tx_pause = 1; + } + rc = copy_to_user(ifr->ifr_data, &epause, sizeof(epause)) + ? -EFAULT : 0; + return rc; + } +#endif +#ifdef ETHTOOL_SPAUSEPARAM + case ETHTOOL_SPAUSEPARAM: { + struct ethtool_pauseparam epause; + struct e100_private *bdp = dev->priv; + if (!(bdp->flags & IS_BACHELOR)) + return -EINVAL; + if (copy_from_user(&epause, ifr->ifr_data, sizeof(epause))) + return -EFAULT; + if (epause.autoneg == 1) + bdp->params.b_params |= PRM_FC; + else + bdp->params.b_params &= ~PRM_FC; + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + e100_hw_init(bdp); + e100_open(dev); + } + return 0; + } +#endif +#ifdef ETHTOOL_GRXCSUM + case ETHTOOL_GRXCSUM: + case ETHTOOL_GTXCSUM: + case ETHTOOL_GSG: + { struct ethtool_value eval; + struct e100_private *bdp = dev->priv; + memset((void *) &eval, 0, sizeof(eval)); + if ((ecmd.cmd == ETHTOOL_GRXCSUM) + && (bdp->params.b_params & PRM_XSUMRX)) + eval.data = 1; + else + eval.data = 0; + rc = copy_to_user(ifr->ifr_data, &eval, sizeof(eval)) + ? -EFAULT : 0; + return rc; + } +#endif +#ifdef ETHTOOL_SRXCSUM + case ETHTOOL_SRXCSUM: + case ETHTOOL_STXCSUM: + case ETHTOOL_SSG: + { struct ethtool_value eval; + struct e100_private *bdp = dev->priv; + if (copy_from_user(&eval, ifr->ifr_data, sizeof(eval))) + return -EFAULT; + if (ecmd.cmd == ETHTOOL_SRXCSUM) { + if (eval.data == 1) { + if (bdp->rev_id >= D101MA_REV_ID) + bdp->params.b_params |= PRM_XSUMRX; + else + return -EINVAL; + } else { + if (bdp->rev_id >= D101MA_REV_ID) + bdp->params.b_params &= ~PRM_XSUMRX; + else + return 0; + } + } else { + if (eval.data == 1) + return -EINVAL; + else + return 0; + } + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + e100_hw_init(bdp); + e100_open(dev); + } + return 0; + } +#endif default: break; } //switch @@ -3284,10 +3415,6 @@ int ethtool_new_speed_duplex; struct ethtool_cmd ecmd; - if (!capable(CAP_NET_ADMIN)) { - return -EPERM; - } - bdp = dev->priv; if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd))) { return -EFAULT; @@ -3296,7 +3423,13 @@ if ((ecmd.autoneg == AUTONEG_ENABLE) && (bdp->speed_duplex_caps & SUPPORTED_Autoneg)) { bdp->params.e100_speed_duplex = E100_AUTONEG; - e100_set_speed_duplex(bdp); + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + e100_hw_init(bdp); + e100_open(dev); + } } else { if (ecmd.speed == SPEED_10) { if (ecmd.duplex == DUPLEX_HALF) { @@ -3327,7 +3460,13 @@ if (bdp->speed_duplex_caps & ethtool_new_speed_duplex) { bdp->params.e100_speed_duplex = e100_new_speed_duplex; - e100_set_speed_duplex(bdp); + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + e100_hw_init(bdp); + e100_open(dev); + } } else { return -EOPNOTSUPP; } @@ -3362,14 +3501,14 @@ struct ethtool_test *info; int rc = -EFAULT; - info = kmalloc(sizeof(*info) + E100_MAX_TEST_RES * sizeof(u64), + info = kmalloc(sizeof(*info) + max_test_res * sizeof(u64), GFP_ATOMIC); if (!info) return -ENOMEM; memset((void *) info, 0, sizeof(*info) + - E100_MAX_TEST_RES * sizeof(u64)); + max_test_res * sizeof(u64)); if (copy_from_user(info, ifr->ifr_data, sizeof(*info))) goto exit; @@ -3377,7 +3516,7 @@ info->flags = e100_run_diag(dev, info->data, info->flags); if (!copy_to_user(ifr->ifr_data, info, - sizeof(*info) + E100_MAX_TEST_RES * sizeof(u64))) + sizeof(*info) + max_test_res * sizeof(u64))) rc = 0; exit: kfree(info); @@ -3391,9 +3530,8 @@ u32 regs_buff[E100_REGS_LEN]; struct ethtool_regs regs = {ETHTOOL_GREGS}; void *addr = ifr->ifr_data; + u16 mdi_reg; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; bdp = dev->priv; if(copy_from_user(®s, addr, sizeof(regs))) @@ -3403,6 +3541,8 @@ regs_buff[0] = readb(&(bdp->scb->scb_cmd_hi)) << 24 | readb(&(bdp->scb->scb_cmd_low)) << 16 | readw(&(bdp->scb->scb_status)); + e100_mdi_read(bdp, MII_NCONFIG, bdp->phy_addr, &mdi_reg); + regs_buff[1] = mdi_reg; if(copy_to_user(addr, ®s, sizeof(regs))) return -EFAULT; @@ -3419,14 +3559,17 @@ { struct e100_private *bdp; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - bdp = dev->priv; if ((bdp->speed_duplex_caps & SUPPORTED_Autoneg) && (bdp->params.e100_speed_duplex == E100_AUTONEG)) { - e100_set_speed_duplex(bdp); + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + e100_hw_init(bdp); + e100_open(dev); + } } else { return -EFAULT; } @@ -3452,7 +3595,7 @@ info.n_stats = E100_STATS_LEN; info.regdump_len = E100_REGS_LEN * sizeof(u32); info.eedump_len = (bdp->eeprom_size << 1); - info.testinfo_len = E100_MAX_TEST_RES; + info.testinfo_len = max_test_res; if (copy_to_user(ifr->ifr_data, &info, sizeof (info))) return -EFAULT; @@ -3471,9 +3614,6 @@ void *ptr; u8 *eeprom_data_bytes = (u8 *)eeprom_data; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - bdp = dev->priv; if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd))) @@ -3751,9 +3891,6 @@ struct ethtool_wolinfo wolinfo; int res = 0; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - bdp = dev->priv; if (copy_from_user(&wolinfo, ifr->ifr_data, sizeof (wolinfo))) { @@ -3802,15 +3939,15 @@ switch (info.string_set) { case ETH_SS_TEST: { int ret = 0; - if (info.len > E100_MAX_TEST_RES) - info.len = E100_MAX_TEST_RES; + if (info.len > max_test_res) + info.len = max_test_res; strings = kmalloc(info.len * ETH_GSTRING_LEN, GFP_ATOMIC); if (!strings) return -ENOMEM; memset(strings, 0, info.len * ETH_GSTRING_LEN); for (i = 0; i < info.len; i++) { - sprintf(strings + i * ETH_GSTRING_LEN, "%-31s", + sprintf(strings + i * ETH_GSTRING_LEN, "%s", test_strings[i]); } if (copy_to_user(ifr->ifr_data, &info, sizeof (info))) @@ -3879,7 +4016,13 @@ bdp->params.e100_speed_duplex = E100_SPEED_10_FULL; else bdp->params.e100_speed_duplex = E100_SPEED_10_HALF; - e100_set_speed_duplex(bdp); + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + e100_hw_init(bdp); + e100_open(dev); + } } else /* Only allows changing speed/duplex */ @@ -4105,13 +4248,13 @@ static int e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) { - struct pci_dev *pdev; + struct pci_dev *pdev = NULL; switch(event) { case SYS_DOWN: case SYS_HALT: case SYS_POWER_OFF: - pci_for_each_dev(pdev) { + while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { if(pci_dev_driver(pdev) == &e100_driver) { /* If net_device struct is allocated? */ if (pci_get_drvdata(pdev)) @@ -4162,7 +4305,6 @@ return 0; } -#endif /* CONFIG_PM */ /** * e100_asf_enabled - checks if ASF is configured on the current adaper @@ -4188,6 +4330,7 @@ } return false; } +#endif /* CONFIG_PM */ #ifdef E100_CU_DEBUG unsigned char diff -urN linux-2.4.21/drivers/net/e100/e100_phy.c linux-2.4.22/drivers/net/e100/e100_phy.c --- linux-2.4.21/drivers/net/e100/e100_phy.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e100/e100_phy.c 2003-08-25 04:44:42.000000000 -0700 @@ -628,8 +628,6 @@ u16 control; unsigned long expires; - e100_phy_reset(bdp); - bdp->flags |= DF_SPEED_FORCED; e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control); @@ -912,11 +910,16 @@ u16 ctrl_reg; ctrl_reg = BMCR_RESET; e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, ctrl_reg); + /* ieee 802.3 : The reset process shall be completed */ + /* within 0.5 seconds from the settting of PHY reset bit. */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 2); } unsigned char __devinit e100_phy_init(struct e100_private *bdp) { + e100_phy_reset(bdp); e100_phy_address_detect(bdp); e100_phy_isolate(bdp); e100_phy_id_detect(bdp); diff -urN linux-2.4.21/drivers/net/e100/e100_test.c linux-2.4.22/drivers/net/e100/e100_test.c --- linux-2.4.21/drivers/net/e100/e100_test.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e100/e100_test.c 2003-08-25 04:44:42.000000000 -0700 @@ -25,7 +25,7 @@ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ -#include "e100.h" +#include "e100_phy.h" #include "e100_config.h" extern u16 e100_eeprom_read(struct e100_private *, u16); @@ -46,6 +46,7 @@ static void e100_diag_loopback_cu_ru_exec(struct e100_private *); static u8 e100_diag_check_pkt(u8 *); static void e100_diag_loopback_free(struct e100_private *); +static int e100_cable_diag(struct e100_private *bdp); #define LB_PACKET_SIZE 1500 @@ -60,46 +61,52 @@ e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags) { struct e100_private* bdp = dev->priv; - u8 test_result = true; - - e100_isolate_driver(bdp); + u8 test_result = 0; + if (!e100_get_link_state(bdp)) { + test_result = ETH_TEST_FL_FAILED; + test_info[test_link] = true; + } + if (!e100_diag_eeprom(dev)) { + test_result = ETH_TEST_FL_FAILED; + test_info[test_eeprom] = true; + } if (flags & ETH_TEST_FL_OFFLINE) { u8 fail_mask; - - fail_mask = e100_diag_selftest(dev); - if (fail_mask) { - test_result = false; - if (fail_mask & REGISTER_TEST_FAIL) - test_info [E100_REG_TEST_FAIL] = true; - if (fail_mask & ROM_TEST_FAIL) - test_info [E100_ROM_TEST_FAIL] = true; - if (fail_mask & SELF_TEST_FAIL) - test_info [E100_MAC_TEST_FAIL] = true; - if (fail_mask & TEST_TIMEOUT) - test_info [E100_CHIP_TIMEOUT] = true; + if (netif_running(dev)) { + spin_lock_bh(&dev->xmit_lock); + e100_close(dev); + spin_unlock_bh(&dev->xmit_lock); + } + if (e100_diag_selftest(dev)) { + test_result = ETH_TEST_FL_FAILED; + test_info[test_self_test] = true; } fail_mask = e100_diag_loopback(dev); if (fail_mask) { - test_result = false; + test_result = ETH_TEST_FL_FAILED; if (fail_mask & PHY_LOOPBACK) - test_info [E100_LPBK_PHY_FAIL] = true; + test_info[test_loopback_phy] = true; if (fail_mask & MAC_LOOPBACK) - test_info [E100_LPBK_MAC_FAIL] = true; + test_info[test_loopback_mac] = true; } - } - if (!e100_diag_eeprom(dev)) { - test_result = false; - test_info [E100_EEPROM_TEST_FAIL] = true; + test_info[cable_diag] = e100_cable_diag(bdp); + /* Need hw init regardless of netif_running */ + e100_hw_init(bdp); + if (netif_running(dev)) { + e100_open(dev); + } + } + else { + test_info[test_self_test] = false; + test_info[test_loopback_phy] = false; + test_info[test_loopback_mac] = false; + test_info[cable_diag] = false; } - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ * 2); - e100_deisolate_driver(bdp, false); - - return flags | (test_result ? 0 : ETH_TEST_FL_FAILED); + return flags | test_result; } /** @@ -126,8 +133,6 @@ } } - e100_configure_device(bdp); - return retval; } @@ -165,14 +170,14 @@ u8 rc = 0; printk(KERN_DEBUG "%s: PHY loopback test starts\n", dev->name); - e100_sw_reset(dev->priv, PORT_SELECTIVE_RESET); + e100_hw_init(dev->priv); if (!e100_diag_one_loopback(dev, PHY_LOOPBACK)) { rc |= PHY_LOOPBACK; } printk(KERN_DEBUG "%s: PHY loopback test ends\n", dev->name); printk(KERN_DEBUG "%s: MAC loopback test starts\n", dev->name); - e100_sw_reset(dev->priv, PORT_SELECTIVE_RESET); + e100_hw_init(dev->priv); if (!e100_diag_one_loopback(dev, MAC_LOOPBACK)) { rc |= MAC_LOOPBACK; } @@ -257,15 +262,10 @@ if (set_loopback) /* Set PHY loopback mode */ e100_phy_set_loopback(bdp); - else { /* Back to normal speed and duplex */ - if (bdp->params.e100_speed_duplex == E100_AUTONEG) - /* Reset PHY and do autoneg */ - e100_phy_autoneg(bdp); - else - /* Reset PHY and force speed and duplex */ - e100_force_speed_duplex(bdp); - } - /* Wait for PHY state change */ + else + /* Reset PHY loopback mode */ + e100_phy_reset(bdp); + /* Wait for PHY state change */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ); } else { /* For MAC loopback wait 500 msec to take effect */ @@ -348,10 +348,6 @@ e100_diag_loopback_cu_ru_exec(struct e100_private *bdp) { /*load CU & RU base */ - if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0)) - printk(KERN_ERR "e100: SCB_CUC_LOAD_BASE failed\n"); - if(!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE, 0)) - printk(KERN_ERR "e100: SCB_RUC_LOAD_BASE failed!\n"); if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START, 0)) printk(KERN_ERR "e100: SCB_RUC_START failed!\n"); @@ -433,3 +429,72 @@ bdp->loopback.dma_handle); } +static int +e100_cable_diag(struct e100_private *bdp) +{ + int saved_open_circut = 0xffff; + int saved_short_circut = 0xffff; + int saved_distance = 0xffff; + int saved_same = 0; + int cable_status = E100_CABLE_UNKNOWN; + int i; + + /* If we have link, */ + if (e100_get_link_state(bdp)) + return E100_CABLE_OK; + + if (bdp->rev_id < D102_REV_ID) + return E100_CABLE_UNKNOWN; + + /* Disable MDI/MDI-X auto switching */ + e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr, + MDI_MDIX_RESET_ALL_MASK); + /* Set to 100 Full as required by cable test */ + e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, + BMCR_SPEED100 | BMCR_FULLDPLX); + + /* Test up to 100 times */ + for (i = 0; i < 100; i++) { + u16 ctrl_reg; + int distance, open_circut, short_circut, near_end; + + /* Enable and execute cable test */ + e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, + (HWI_TEST_ENABLE | HWI_TEST_EXECUTE)); + /* Wait for cable test finished */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/100 + 1); + /* Read results */ + e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg); + distance = ctrl_reg & HWI_TEST_DISTANCE; + open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM; + short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM; + + if ((distance == saved_distance) && + (open_circut == saved_open_circut) && + (short_circut == saved_short_circut)) + saved_same++; + else { + saved_same = 0; + saved_distance = distance; + saved_open_circut = open_circut; + saved_short_circut = short_circut; + } + /* If results are the same 3 times */ + if (saved_same == 3) { + near_end = ((distance * HWI_REGISTER_GRANULARITY) < + HWI_NEAR_END_BOUNDARY); + if (open_circut) + cable_status = (near_end) ? + E100_CABLE_OPEN_NEAR : E100_CABLE_OPEN_FAR; + if (short_circut) + cable_status = (near_end) ? + E100_CABLE_SHORT_NEAR : E100_CABLE_SHORT_FAR; + break; + } + } + /* Reset cable test */ + e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, HWI_RESET_ALL_MASK); + return cable_status; +} + diff -urN linux-2.4.21/drivers/net/e1000/Makefile linux-2.4.22/drivers/net/e1000/Makefile --- linux-2.4.21/drivers/net/e1000/Makefile 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e1000/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -1,7 +1,7 @@ ################################################################################ # # -# Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. +# Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free diff -urN linux-2.4.21/drivers/net/e1000/e1000.h linux-2.4.22/drivers/net/e1000/e1000.h --- linux-2.4.21/drivers/net/e1000/e1000.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e1000/e1000.h 2003-08-25 04:44:42.000000000 -0700 @@ -63,6 +63,9 @@ #include #include #include +#ifdef NETIF_F_TSO +#include +#endif #include #include #include @@ -131,6 +134,7 @@ uint64_t dma; unsigned long length; unsigned long time_stamp; + unsigned int next_to_watch; }; struct e1000_desc_ring { @@ -166,7 +170,6 @@ struct timer_list watchdog_timer; struct timer_list phy_info_timer; struct vlan_group *vlgrp; - char *id_string; uint32_t bd_number; uint32_t rx_buffer_len; uint32_t part_num; @@ -215,9 +218,11 @@ struct e1000_phy_info phy_info; struct e1000_phy_stats phy_stats; + uint32_t test_icr; + struct e1000_desc_ring test_tx_ring; + struct e1000_desc_ring test_rx_ring; uint32_t pci_state[16]; - char ifname[IFNAMSIZ]; }; #endif /* _E1000_H_ */ diff -urN linux-2.4.21/drivers/net/e1000/e1000_ethtool.c linux-2.4.22/drivers/net/e1000/e1000_ethtool.c --- linux-2.4.21/drivers/net/e1000/e1000_ethtool.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e1000/e1000_ethtool.c 2003-08-25 04:44:42.000000000 -0700 @@ -40,15 +40,60 @@ extern void e1000_reset(struct e1000_adapter *adapter); extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); -static char e1000_gstrings_stats[][ETH_GSTRING_LEN] = { - "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", - "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", - "rx_length_errors", "rx_over_errors", "rx_crc_errors", - "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors", - "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors", - "tx_heartbeat_errors", "tx_window_errors", +struct e1000_stats { + char stat_string[ETH_GSTRING_LEN]; + int sizeof_stat; + int stat_offset; }; -#define E1000_STATS_LEN sizeof(e1000_gstrings_stats) / ETH_GSTRING_LEN + +#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ + offsetof(struct e1000_adapter, m) +static struct e1000_stats e1000_gstrings_stats[] = { + { "rx_packets", E1000_STAT(net_stats.rx_packets) }, + { "tx_packets", E1000_STAT(net_stats.tx_packets) }, + { "rx_bytes", E1000_STAT(net_stats.rx_bytes) }, + { "tx_bytes", E1000_STAT(net_stats.tx_bytes) }, + { "rx_errors", E1000_STAT(net_stats.rx_errors) }, + { "tx_errors", E1000_STAT(net_stats.tx_errors) }, + { "rx_dropped", E1000_STAT(net_stats.rx_dropped) }, + { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, + { "multicast", E1000_STAT(net_stats.multicast) }, + { "collisions", E1000_STAT(net_stats.collisions) }, + { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) }, + { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, + { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, + { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, + { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, + { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, + { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, + { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) }, + { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, + { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, + { "tx_window_errors", E1000_STAT(net_stats.tx_window_errors) }, + { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, + { "tx_deferred_ok", E1000_STAT(stats.dc) }, + { "tx_single_coll_ok", E1000_STAT(stats.scc) }, + { "tx_multi_coll_ok", E1000_STAT(stats.mcc) }, + { "rx_long_length_errors", E1000_STAT(stats.roc) }, + { "rx_short_length_errors", E1000_STAT(stats.ruc) }, + { "rx_align_errors", E1000_STAT(stats.algnerrc) }, + { "tx_tcp_seg_good", E1000_STAT(stats.tsctc) }, + { "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) }, + { "rx_flow_control_xon", E1000_STAT(stats.xonrxc) }, + { "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) }, + { "tx_flow_control_xon", E1000_STAT(stats.xontxc) }, + { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) }, + { "rx_csum_offload_good", E1000_STAT(hw_csum_good) }, + { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) } +}; +#define E1000_STATS_LEN \ + sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats) +static char e1000_gstrings_test[][ETH_GSTRING_LEN] = { + "Register test (offline)", "Eeprom test (offline)", + "Interrupt test (offline)", "Loopback test (offline)", + "Link test (on/offline)" +}; +#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN static void e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd) @@ -154,6 +199,7 @@ strncpy(drvinfo->fw_version, "N/A", 32); strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32); drvinfo->n_stats = E1000_STATS_LEN; + drvinfo->testinfo_len = E1000_TEST_LEN; #define E1000_REGS_LEN 32 drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t); drvinfo->eedump_len = adapter->hw.eeprom.word_size * 2; @@ -164,6 +210,7 @@ struct ethtool_regs *regs, uint32_t *regs_buff) { struct e1000_hw *hw = &adapter->hw; + uint16_t phy_data; regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id; @@ -182,6 +229,62 @@ regs_buff[10] = E1000_READ_REG(hw, TDT); regs_buff[11] = E1000_READ_REG(hw, TIDV); + regs_buff[12] = adapter->hw.phy_type; /* PHY type (IGP=1, M88=0) */ + if(hw->phy_type == e1000_phy_igp) { + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_PHY_AGC_A); + e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_A & + IGP01E1000_PHY_PAGE_SELECT, &phy_data); + regs_buff[13] = (uint32_t)phy_data; /* cable length */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_PHY_AGC_B); + e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_B & + IGP01E1000_PHY_PAGE_SELECT, &phy_data); + regs_buff[14] = (uint32_t)phy_data; /* cable length */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_PHY_AGC_C); + e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_C & + IGP01E1000_PHY_PAGE_SELECT, &phy_data); + regs_buff[15] = (uint32_t)phy_data; /* cable length */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_PHY_AGC_D); + e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_D & + IGP01E1000_PHY_PAGE_SELECT, &phy_data); + regs_buff[16] = (uint32_t)phy_data; /* cable length */ + regs_buff[17] = 0; /* extended 10bt distance (not needed) */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0); + e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS & + IGP01E1000_PHY_PAGE_SELECT, &phy_data); + regs_buff[18] = (uint32_t)phy_data; /* cable polarity */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_PHY_PCS_INIT_REG); + e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG & + IGP01E1000_PHY_PAGE_SELECT, &phy_data); + regs_buff[19] = (uint32_t)phy_data; /* cable polarity */ + regs_buff[20] = 0; /* polarity correction enabled (always) */ + regs_buff[22] = 0; /* phy receive errors (unavailable) */ + regs_buff[23] = regs_buff[18]; /* mdix mode */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0); + } else { + e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); + regs_buff[13] = (uint32_t)phy_data; /* cable length */ + regs_buff[14] = 0; /* Dummy (to align w/ IGP phy reg dump) */ + regs_buff[15] = 0; /* Dummy (to align w/ IGP phy reg dump) */ + regs_buff[16] = 0; /* Dummy (to align w/ IGP phy reg dump) */ + e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + regs_buff[17] = (uint32_t)phy_data; /* extended 10bt distance */ + regs_buff[18] = regs_buff[13]; /* cable polarity */ + regs_buff[19] = 0; /* Dummy (to align w/ IGP phy reg dump) */ + regs_buff[20] = regs_buff[17]; /* polarity correction */ + /* phy receive errors */ + regs_buff[22] = adapter->phy_stats.receive_errors; + regs_buff[23] = regs_buff[13]; /* mdix mode */ + } + regs_buff[21] = adapter->phy_stats.idle_errors; /* phy idle errors */ + e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); + regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */ + regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ + return; } @@ -219,7 +322,7 @@ uint16_t i; for (i = 0; i < last_word - first_word + 1; i++) if((ret_val = e1000_read_eeprom(hw, first_word + i, 1, - &eeprom_buff[i]))) + &eeprom_buff[i]))) break; } geeprom_error: @@ -249,7 +352,7 @@ first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_buff = kmalloc(max_len, GFP_KERNEL); - if(eeprom_buff == NULL) + if(!eeprom_buff) return -ENOMEM; ptr = (void *)eeprom_buff; @@ -284,6 +387,766 @@ return ret_val; } +#define REG_PATTERN_TEST(R, M, W) \ +{ \ + uint32_t pat, value; \ + uint32_t test[] = \ + {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ + for(pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) { \ + E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \ + value = E1000_READ_REG(&adapter->hw, R); \ + if(value != (test[pat] & W & M)) { \ + *data = (adapter->hw.mac_type < e1000_82543) ? \ + E1000_82542_##R : E1000_##R; \ + return 1; \ + } \ + } \ +} + +#define REG_SET_AND_CHECK(R, M, W) \ +{ \ + uint32_t value; \ + E1000_WRITE_REG(&adapter->hw, R, W & M); \ + value = E1000_READ_REG(&adapter->hw, R); \ + if ((W & M) != (value & M)) { \ + *data = (adapter->hw.mac_type < e1000_82543) ? \ + E1000_82542_##R : E1000_##R; \ + return 1; \ + } \ +} + +static int +e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) +{ + uint32_t value; + uint32_t i; + + /* The status register is Read Only, so a write should fail. + * Some bits that get toggled are ignored. + */ + value = (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833)); + E1000_WRITE_REG(&adapter->hw, STATUS, (0xFFFFFFFF)); + if(value != (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833))) { + *data = 1; + return 1; + } + + REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF); + REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF); + REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF); + REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF); + REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF); + REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF); + REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF); + REG_PATTERN_TEST(RDH, 0x0000FFFF, 0x0000FFFF); + REG_PATTERN_TEST(RDT, 0x0000FFFF, 0x0000FFFF); + REG_PATTERN_TEST(FCRTH, 0x0000FFF8, 0x0000FFF8); + REG_PATTERN_TEST(FCTTV, 0x0000FFFF, 0x0000FFFF); + REG_PATTERN_TEST(TIPG, 0x3FFFFFFF, 0x3FFFFFFF); + REG_PATTERN_TEST(TDBAH, 0xFFFFFFFF, 0xFFFFFFFF); + REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF); + + REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000); + REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0x003FFFFB); + REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000); + + if(adapter->hw.mac_type >= e1000_82543) { + + REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0xFFFFFFFF); + REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF); + REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF); + REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF); + REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF); + + for(i = 0; i < E1000_RAR_ENTRIES; i++) { + REG_PATTERN_TEST(RA + ((i << 1) << 2), 0xFFFFFFFF, + 0xFFFFFFFF); + REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF, + 0xFFFFFFFF); + } + + } else { + + REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF); + REG_PATTERN_TEST(RDBAL, 0xFFFFF000, 0xFFFFFFFF); + REG_PATTERN_TEST(TXCW, 0x0000FFFF, 0x0000FFFF); + REG_PATTERN_TEST(TDBAL, 0xFFFFF000, 0xFFFFFFFF); + + } + + for(i = 0; i < E1000_MC_TBL_SIZE; i++) + REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF); + + return 0; +} + +static int +e1000_eeprom_test(struct e1000_adapter *adapter, uint64_t *data) +{ + uint16_t temp; + uint16_t checksum = 0; + uint16_t i; + + *data = 0; + /* Read and add up the contents of the EEPROM */ + for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { + if((e1000_read_eeprom(&adapter->hw, i, 1, &temp)) < 0) { + *data = 1; + break; + } + checksum += temp; + } + + /* If Checksum is not Correct return error else test passed */ + if((checksum != (uint16_t) EEPROM_SUM) && !(*data)) + *data = 2; + + return *data; +} + +static void +e1000_test_intr(int irq, + void *data, + struct pt_regs *regs) +{ + struct net_device *netdev = (struct net_device *) data; + struct e1000_adapter *adapter = netdev->priv; + + adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR); + + return; +} + +static int +e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) +{ + struct net_device *netdev = adapter->netdev; + uint32_t icr, mask, i=0; + + *data = 0; + + /* Hook up test interrupt handler just for this test */ + if(request_irq + (netdev->irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)) { + *data = 1; + return -1; + } + + /* Disable all the interrupts */ + E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); + msec_delay(10); + + /* Interrupts are disabled, so read interrupt cause + * register (icr) twice to verify that there are no interrupts + * pending. icr is clear on read. + */ + icr = E1000_READ_REG(&adapter->hw, ICR); + icr = E1000_READ_REG(&adapter->hw, ICR); + + if(icr != 0) { + /* if icr is non-zero, there is no point + * running other interrupt tests. + */ + *data = 2; + i = 10; + } + + /* Test each interrupt */ + for(; i < 10; i++) { + + /* Interrupt to test */ + mask = 1 << i; + + /* Disable the interrupt to be reported in + * the cause register and then force the same + * interrupt and see if one gets posted. If + * an interrupt was posted to the bus, the + * test failed. + */ + adapter->test_icr = 0; + E1000_WRITE_REG(&adapter->hw, IMC, mask); + E1000_WRITE_REG(&adapter->hw, ICS, mask); + msec_delay(10); + + if(adapter->test_icr & mask) { + *data = 3; + break; + } + + /* Enable the interrupt to be reported in + * the cause register and then force the same + * interrupt and see if one gets posted. If + * an interrupt was not posted to the bus, the + * test failed. + */ + adapter->test_icr = 0; + E1000_WRITE_REG(&adapter->hw, IMS, mask); + E1000_WRITE_REG(&adapter->hw, ICS, mask); + msec_delay(10); + + if(!(adapter->test_icr & mask)) { + *data = 4; + break; + } + + /* Disable the other interrupts to be reported in + * the cause register and then force the other + * interrupts and see if any get posted. If + * an interrupt was posted to the bus, the + * test failed. + */ + adapter->test_icr = 0; + E1000_WRITE_REG(&adapter->hw, IMC, ~mask); + E1000_WRITE_REG(&adapter->hw, ICS, ~mask); + msec_delay(10); + + if(adapter->test_icr) { + *data = 5; + break; + } + } + + /* Disable all the interrupts */ + E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); + msec_delay(10); + + /* Unhook test interrupt handler */ + free_irq(netdev->irq, netdev); + + return *data; +} + +static void +e1000_free_desc_rings(struct e1000_adapter *adapter) +{ + struct e1000_desc_ring *txdr = &adapter->test_tx_ring; + struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; + struct pci_dev *pdev = adapter->pdev; + int i; + + if(txdr->desc && txdr->buffer_info) { + for(i = 0; i < txdr->count; i++) { + if(txdr->buffer_info[i].dma) + pci_unmap_single(pdev, txdr->buffer_info[i].dma, + txdr->buffer_info[i].length, + PCI_DMA_TODEVICE); + if(txdr->buffer_info[i].skb) + dev_kfree_skb(txdr->buffer_info[i].skb); + } + } + + if(rxdr->desc && rxdr->buffer_info) { + for(i = 0; i < rxdr->count; i++) { + if(rxdr->buffer_info[i].dma) + pci_unmap_single(pdev, rxdr->buffer_info[i].dma, + rxdr->buffer_info[i].length, + PCI_DMA_FROMDEVICE); + if(rxdr->buffer_info[i].skb) + dev_kfree_skb(rxdr->buffer_info[i].skb); + } + } + + if(txdr->desc) + pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma); + if(rxdr->desc) + pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma); + + if(txdr->buffer_info) + kfree(txdr->buffer_info); + if(rxdr->buffer_info) + kfree(rxdr->buffer_info); + + return; +} + +static int +e1000_setup_desc_rings(struct e1000_adapter *adapter) +{ + struct e1000_desc_ring *txdr = &adapter->test_tx_ring; + struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; + struct pci_dev *pdev = adapter->pdev; + uint32_t rctl; + int size, i, ret_val; + + /* Setup Tx descriptor ring and Tx buffers */ + + txdr->count = 80; + + size = txdr->count * sizeof(struct e1000_buffer); + if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { + ret_val = 1; + goto err_nomem; + } + memset(txdr->buffer_info, 0, size); + + txdr->size = txdr->count * sizeof(struct e1000_tx_desc); + E1000_ROUNDUP(txdr->size, 4096); + if(!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) { + ret_val = 2; + goto err_nomem; + } + memset(txdr->desc, 0, txdr->size); + txdr->next_to_use = txdr->next_to_clean = 0; + + E1000_WRITE_REG(&adapter->hw, TDBAL, + ((uint64_t) txdr->dma & 0x00000000FFFFFFFF)); + E1000_WRITE_REG(&adapter->hw, TDBAH, ((uint64_t) txdr->dma >> 32)); + E1000_WRITE_REG(&adapter->hw, TDLEN, + txdr->count * sizeof(struct e1000_tx_desc)); + E1000_WRITE_REG(&adapter->hw, TDH, 0); + E1000_WRITE_REG(&adapter->hw, TDT, 0); + E1000_WRITE_REG(&adapter->hw, TCTL, + E1000_TCTL_PSP | E1000_TCTL_EN | + E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT | + E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT); + + for(i = 0; i < txdr->count; i++) { + struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i); + struct sk_buff *skb; + unsigned int size = 1024; + + if(!(skb = alloc_skb(size, GFP_KERNEL))) { + ret_val = 3; + goto err_nomem; + } + skb_put(skb, size); + txdr->buffer_info[i].skb = skb; + txdr->buffer_info[i].length = skb->len; + txdr->buffer_info[i].dma = + pci_map_single(pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma); + tx_desc->lower.data = cpu_to_le32(skb->len); + tx_desc->lower.data |= E1000_TXD_CMD_EOP; + tx_desc->lower.data |= E1000_TXD_CMD_IFCS; + tx_desc->lower.data |= E1000_TXD_CMD_RPS; + tx_desc->upper.data = 0; + } + + /* Setup Rx descriptor ring and Rx buffers */ + + rxdr->count = 80; + + size = rxdr->count * sizeof(struct e1000_buffer); + if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { + ret_val = 4; + goto err_nomem; + } + memset(rxdr->buffer_info, 0, size); + + rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc); + if(!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) { + ret_val = 5; + goto err_nomem; + } + memset(rxdr->desc, 0, rxdr->size); + rxdr->next_to_use = rxdr->next_to_clean = 0; + + rctl = E1000_READ_REG(&adapter->hw, RCTL); + E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN); + E1000_WRITE_REG(&adapter->hw, RDBAL, + ((uint64_t) rxdr->dma & 0xFFFFFFFF)); + E1000_WRITE_REG(&adapter->hw, RDBAH, ((uint64_t) rxdr->dma >> 32)); + E1000_WRITE_REG(&adapter->hw, RDLEN, rxdr->size); + E1000_WRITE_REG(&adapter->hw, RDH, 0); + E1000_WRITE_REG(&adapter->hw, RDT, 0); + rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | + E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | + (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT); + E1000_WRITE_REG(&adapter->hw, RCTL, rctl); + + for(i = 0; i < rxdr->count; i++) { + struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i); + struct sk_buff *skb; + + if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + 2, GFP_KERNEL))) { + ret_val = 6; + goto err_nomem; + } + skb_reserve(skb, 2); + rxdr->buffer_info[i].skb = skb; + rxdr->buffer_info[i].length = E1000_RXBUFFER_2048; + rxdr->buffer_info[i].dma = + pci_map_single(pdev, skb->data, E1000_RXBUFFER_2048, + PCI_DMA_FROMDEVICE); + rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma); + memset(skb->data, 0x00, skb->len); + } + + return 0; + + err_nomem: + e1000_free_desc_rings(adapter); + return ret_val; +} + +static void +e1000_phy_disable_receiver(struct e1000_adapter *adapter) +{ + /* Write out to PHY registers 29 and 30 to disable the Receiver. */ + e1000_write_phy_reg(&adapter->hw, 29, 0x001F); + e1000_write_phy_reg(&adapter->hw, 30, 0x8FFC); + e1000_write_phy_reg(&adapter->hw, 29, 0x001A); + e1000_write_phy_reg(&adapter->hw, 30, 0x8FF0); + + return; +} + +static void +e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter) +{ + uint16_t phy_reg; + + /* Because we reset the PHY above, we need to re-force TX_CLK in the + * Extended PHY Specific Control Register to 25MHz clock. This + * value defaults back to a 2.5MHz clock when the PHY is reset. + */ + e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); + phy_reg |= M88E1000_EPSCR_TX_CLK_25; + e1000_write_phy_reg(&adapter->hw, + M88E1000_EXT_PHY_SPEC_CTRL, phy_reg); + + /* In addition, because of the s/w reset above, we need to enable + * CRS on TX. This must be set for both full and half duplex + * operation. + */ + e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg); + phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX; + e1000_write_phy_reg(&adapter->hw, + M88E1000_PHY_SPEC_CTRL, phy_reg); +} + +static int +e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter) +{ + uint32_t ctrl_reg; + uint16_t phy_reg; + + /* Setup the Device Control Register for PHY loopback test. */ + + ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); + ctrl_reg |= (E1000_CTRL_ILOS | /* Invert Loss-Of-Signal */ + E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ + E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ + E1000_CTRL_SPD_1000 | /* Force Speed to 1000 */ + E1000_CTRL_FD); /* Force Duplex to FULL */ + + E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg); + + /* Read the PHY Specific Control Register (0x10) */ + e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg); + + /* Clear Auto-Crossover bits in PHY Specific Control Register + * (bits 6:5). + */ + phy_reg &= ~M88E1000_PSCR_AUTO_X_MODE; + e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, phy_reg); + + /* Perform software reset on the PHY */ + e1000_phy_reset(&adapter->hw); + + /* Have to setup TX_CLK and TX_CRS after software reset */ + e1000_phy_reset_clk_and_crs(adapter); + + e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100); + + /* Wait for reset to complete. */ + udelay(500); + + /* Have to setup TX_CLK and TX_CRS after software reset */ + e1000_phy_reset_clk_and_crs(adapter); + + /* Write out to PHY registers 29 and 30 to disable the Receiver. */ + e1000_phy_disable_receiver(adapter); + + /* Set the loopback bit in the PHY control register. */ + e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); + phy_reg |= MII_CR_LOOPBACK; + e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); + + /* Setup TX_CLK and TX_CRS one more time. */ + e1000_phy_reset_clk_and_crs(adapter); + + /* Check Phy Configuration */ + e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); + if(phy_reg != 0x4100) + return 9; + + e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); + if(phy_reg != 0x0070) + return 10; + + e1000_read_phy_reg(&adapter->hw, 29, &phy_reg); + if(phy_reg != 0x001A) + return 11; + + return 0; +} + +static int +e1000_integrated_phy_loopback(struct e1000_adapter *adapter) +{ + uint32_t ctrl_reg = 0; + uint32_t stat_reg = 0; + + adapter->hw.autoneg = FALSE; + + if(adapter->hw.phy_type == e1000_phy_m88) { + /* Auto-MDI/MDIX Off */ + e1000_write_phy_reg(&adapter->hw, + M88E1000_PHY_SPEC_CTRL, 0x0808); + /* reset to update Auto-MDI/MDIX */ + e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); + /* autoneg off */ + e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); + } + /* force 1000, set loopback */ + e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140); + + /* Now set up the MAC to the same speed/duplex as the PHY. */ + ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); + ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ + ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ + E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ + E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ + E1000_CTRL_FD); /* Force Duplex to FULL */ + + if(adapter->hw.media_type == e1000_media_type_copper && + adapter->hw.phy_type == e1000_phy_m88) { + ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ + } else { + /* Set the ILOS bit on the fiber Nic is half + * duplex link is detected. */ + stat_reg = E1000_READ_REG(&adapter->hw, STATUS); + if((stat_reg & E1000_STATUS_FD) == 0) + ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); + } + + E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg); + + /* Disable the receiver on the PHY so when a cable is plugged in, the + * PHY does not begin to autoneg when a cable is reconnected to the NIC. + */ + if(adapter->hw.phy_type == e1000_phy_m88) + e1000_phy_disable_receiver(adapter); + + udelay(500); + + return 0; +} + +static int +e1000_set_phy_loopback(struct e1000_adapter *adapter) +{ + uint16_t phy_reg = 0; + uint16_t count = 0; + + switch (adapter->hw.mac_type) { + case e1000_82543: + if(adapter->hw.media_type == e1000_media_type_copper) { + /* Attempt to setup Loopback mode on Non-integrated PHY. + * Some PHY registers get corrupted at random, so + * attempt this 10 times. + */ + while(e1000_nonintegrated_phy_loopback(adapter) && + count++ < 10); + if(count < 11) + return 0; + } + break; + + case e1000_82544: + case e1000_82540: + case e1000_82545: + case e1000_82546: + case e1000_82541: + case e1000_82547: + return e1000_integrated_phy_loopback(adapter); + break; + + default: + /* Default PHY loopback work is to read the MII + * control register and assert bit 14 (loopback mode). + */ + e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); + phy_reg |= MII_CR_LOOPBACK; + e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); + return 0; + break; + } + + return 8; +} + +static int +e1000_setup_loopback_test(struct e1000_adapter *adapter) +{ + uint32_t rctl; + + if(adapter->hw.media_type == e1000_media_type_fiber) { + if(adapter->hw.mac_type == e1000_82545 || + adapter->hw.mac_type == e1000_82546) + return e1000_set_phy_loopback(adapter); + else { + rctl = E1000_READ_REG(&adapter->hw, RCTL); + rctl |= E1000_RCTL_LBM_TCVR; + E1000_WRITE_REG(&adapter->hw, RCTL, rctl); + return 0; + } + } else if(adapter->hw.media_type == e1000_media_type_copper) + return e1000_set_phy_loopback(adapter); + + return 7; +} + +static void +e1000_loopback_cleanup(struct e1000_adapter *adapter) +{ + uint32_t rctl; + uint16_t phy_reg; + + rctl = E1000_READ_REG(&adapter->hw, RCTL); + rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); + E1000_WRITE_REG(&adapter->hw, RCTL, rctl); + + if(adapter->hw.media_type == e1000_media_type_copper || + (adapter->hw.media_type == e1000_media_type_fiber && + (adapter->hw.mac_type == e1000_82545 || + adapter->hw.mac_type == e1000_82546))) { + adapter->hw.autoneg = TRUE; + e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); + if(phy_reg & MII_CR_LOOPBACK) { + phy_reg &= ~MII_CR_LOOPBACK; + e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); + e1000_phy_reset(&adapter->hw); + } + } +} + +static void +e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) +{ + memset(skb->data, 0xFF, frame_size); + frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size; + memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); + memset(&skb->data[frame_size / 2 + 10], 0xBE, 1); + memset(&skb->data[frame_size / 2 + 12], 0xAF, 1); +} + +static int +e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) +{ + frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size; + if(*(skb->data + 3) == 0xFF) { + if((*(skb->data + frame_size / 2 + 10) == 0xBE) && + (*(skb->data + frame_size / 2 + 12) == 0xAF)) { + return 0; + } + } + return 13; +} + +static int +e1000_run_loopback_test(struct e1000_adapter *adapter) +{ + struct e1000_desc_ring *txdr = &adapter->test_tx_ring; + struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; + struct pci_dev *pdev = adapter->pdev; + int i; + + E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); + + for(i = 0; i < 64; i++) { + e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); + pci_dma_sync_single(pdev, txdr->buffer_info[i].dma, + txdr->buffer_info[i].length, + PCI_DMA_TODEVICE); + } + E1000_WRITE_REG(&adapter->hw, TDT, i); + + msec_delay(200); + + pci_dma_sync_single(pdev, rxdr->buffer_info[0].dma, + rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE); + + return e1000_check_lbtest_frame(rxdr->buffer_info[0].skb, 1024); +} + +static int +e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data) +{ + if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback; + if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback; + *data = e1000_run_loopback_test(adapter); + e1000_loopback_cleanup(adapter); + e1000_free_desc_rings(adapter); +err_loopback: + return *data; +} + +static int +e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) +{ + *data = 0; + e1000_check_for_link(&adapter->hw); + + if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { + *data = 1; + } + return *data; +} + +static int +e1000_ethtool_test(struct e1000_adapter *adapter, + struct ethtool_test *eth_test, uint64_t *data) +{ + boolean_t if_running = netif_running(adapter->netdev); + + if(eth_test->flags == ETH_TEST_FL_OFFLINE) { + /* Offline tests */ + + /* Link test performed before hardware reset so autoneg doesn't + * interfere with test result */ + if(e1000_link_test(adapter, &data[4])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + if(if_running) + e1000_down(adapter); + else + e1000_reset(adapter); + + if(e1000_reg_test(adapter, &data[0])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + e1000_reset(adapter); + if(e1000_eeprom_test(adapter, &data[1])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + e1000_reset(adapter); + if(e1000_intr_test(adapter, &data[2])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + e1000_reset(adapter); + if(e1000_loopback_test(adapter, &data[3])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + e1000_reset(adapter); + if(if_running) + e1000_up(adapter); + } else { + /* Online tests */ + if(e1000_link_test(adapter, &data[4])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + /* Offline tests aren't run; pass by default */ + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + } + return 0; +} + static void e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) { @@ -427,8 +1290,6 @@ } case ETHTOOL_SSET: { struct ethtool_cmd ecmd; - if(!capable(CAP_NET_ADMIN)) - return -EPERM; if(copy_from_user(&ecmd, addr, sizeof(ecmd))) return -EFAULT; return e1000_ethtool_sset(adapter, &ecmd); @@ -443,24 +1304,46 @@ case ETHTOOL_GSTRINGS: { struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS }; char *strings = NULL; + int err = 0; if(copy_from_user(&gstrings, addr, sizeof(gstrings))) return -EFAULT; switch(gstrings.string_set) { - case ETH_SS_STATS: + case ETH_SS_TEST: + gstrings.len = E1000_TEST_LEN; + strings = kmalloc(E1000_TEST_LEN * ETH_GSTRING_LEN, + GFP_KERNEL); + if(!strings) + return -ENOMEM; + memcpy(strings, e1000_gstrings_test, E1000_TEST_LEN * + ETH_GSTRING_LEN); + break; + case ETH_SS_STATS: { + int i; gstrings.len = E1000_STATS_LEN; - strings = *e1000_gstrings_stats; + strings = kmalloc(E1000_STATS_LEN * ETH_GSTRING_LEN, + GFP_KERNEL); + if(!strings) + return -ENOMEM; + for(i=0; i < E1000_STATS_LEN; i++) { + memcpy(&strings[i * ETH_GSTRING_LEN], + e1000_gstrings_stats[i].stat_string, + ETH_GSTRING_LEN); + } break; + } default: return -EOPNOTSUPP; } if(copy_to_user(addr, &gstrings, sizeof(gstrings))) - return -EFAULT; + err = -EFAULT; addr += offsetof(struct ethtool_gstrings, data); - if(copy_to_user(addr, strings, + if(!err && copy_to_user(addr, strings, gstrings.len * ETH_GSTRING_LEN)) - return -EFAULT; - return 0; + err = -EFAULT; + + kfree(strings); + return err; } case ETHTOOL_GREGS: { struct ethtool_regs regs = {ETHTOOL_GREGS}; @@ -479,8 +1362,6 @@ return 0; } case ETHTOOL_NWAY_RST: { - if(!capable(CAP_NET_ADMIN)) - return -EPERM; if(netif_running(netdev)) { e1000_down(adapter); e1000_up(adapter); @@ -509,8 +1390,6 @@ } case ETHTOOL_SWOL: { struct ethtool_wolinfo wol; - if(!capable(CAP_NET_ADMIN)) - return -EPERM; if(copy_from_user(&wol, addr, sizeof(wol)) != 0) return -EFAULT; return e1000_ethtool_swol(adapter, &wol); @@ -522,16 +1401,14 @@ void *ptr; int err = 0; + if(copy_from_user(&eeprom, addr, sizeof(eeprom))) + return -EFAULT; + eeprom_buff = kmalloc(hw->eeprom.word_size * 2, GFP_KERNEL); - if(eeprom_buff == NULL) + if(!eeprom_buff) return -ENOMEM; - if(copy_from_user(&eeprom, addr, sizeof(eeprom))) { - err = -EFAULT; - goto err_geeprom_ioctl; - } - if((err = e1000_ethtool_geeprom(adapter, &eeprom, eeprom_buff))) goto err_geeprom_ioctl; @@ -554,9 +1431,6 @@ case ETHTOOL_SEEPROM: { struct ethtool_eeprom eeprom; - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - if(copy_from_user(&eeprom, addr, sizeof(eeprom))) return -EFAULT; @@ -565,18 +1439,42 @@ } case ETHTOOL_GSTATS: { struct { - struct ethtool_stats cmd; + struct ethtool_stats eth_stats; uint64_t data[E1000_STATS_LEN]; } stats = { {ETHTOOL_GSTATS, E1000_STATS_LEN} }; int i; for(i = 0; i < E1000_STATS_LEN; i++) - stats.data[i] = - ((unsigned long *)&adapter->net_stats)[i]; + stats.data[i] = (e1000_gstrings_stats[i].sizeof_stat == + sizeof(uint64_t)) ? + *(uint64_t *)((char *)adapter + + e1000_gstrings_stats[i].stat_offset) : + *(uint32_t *)((char *)adapter + + e1000_gstrings_stats[i].stat_offset); if(copy_to_user(addr, &stats, sizeof(stats))) return -EFAULT; return 0; } + case ETHTOOL_TEST: { + struct { + struct ethtool_test eth_test; + uint64_t data[E1000_TEST_LEN]; + } test = { {ETHTOOL_TEST} }; + int err; + + if(copy_from_user(&test.eth_test, addr, sizeof(test.eth_test))) + return -EFAULT; + + test.eth_test.len = E1000_TEST_LEN; + + if((err = e1000_ethtool_test(adapter, &test.eth_test, + test.data))) + return err; + + if(copy_to_user(addr, &test, sizeof(test)) != 0) + return -EFAULT; + return 0; + } default: return -EOPNOTSUPP; } diff -urN linux-2.4.21/drivers/net/e1000/e1000_hw.c linux-2.4.22/drivers/net/e1000/e1000_hw.c --- linux-2.4.21/drivers/net/e1000/e1000_hw.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e1000/e1000_hw.c 2003-08-25 04:44:42.000000000 -0700 @@ -135,6 +135,41 @@ e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000); e1000_write_phy_reg(hw,0x0000,0x3300); + + + if(hw->mac_type == e1000_82547) { + uint16_t fused, fine, coarse; + + /* Move to analog registers page */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_ANALOG_REGS_PAGE); + + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); + + if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused); + + fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; + coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK; + + if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { + coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10; + fine -= IGP01E1000_ANALOG_FUSE_FINE_1; + } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH) + fine -= IGP01E1000_ANALOG_FUSE_FINE_10; + + fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) | + (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) | + (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK); + + e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused); + e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS, + IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL); + } + /* Return to first page of registers */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_IEEE_REGS_PAGE); + } } } @@ -185,6 +220,7 @@ break; case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: hw->mac_type = e1000_82546; break; case E1000_DEV_ID_82541EI: @@ -258,10 +294,20 @@ msec_delay(5); } - if(hw->mac_type > e1000_82543) - E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST)); - else - E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); + switch(hw->mac_type) { + case e1000_82544: + case e1000_82540: + case e1000_82545: + case e1000_82546: + case e1000_82541: + /* These controllers can't ack the 64-bit write when issuing the + * reset, so use IO-mapping as a workaround to issue the reset */ + E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST)); + break; + default: + E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); + break; + } /* Force a reload from the EEPROM if necessary */ if(hw->mac_type < e1000_82540) { @@ -288,9 +334,7 @@ /* Configure activity LED after PHY reset */ led_ctrl = E1000_READ_REG(hw, LEDCTL); led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= IGP_ACTIVITY_LED_ENABLE; - if(hw->mac_type == e1000_82547) - led_ctrl |= IGP_LED3_MODE; + led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); E1000_WRITE_REG(hw, LEDCTL, led_ctrl); } @@ -688,7 +732,8 @@ static int32_t e1000_setup_copper_link(struct e1000_hw *hw) { - uint32_t ctrl, led_ctrl; + uint32_t ctrl; + uint32_t led_ctrl; int32_t ret_val; uint16_t i; uint16_t phy_data; @@ -737,9 +782,7 @@ /* Configure activity LED after PHY reset */ led_ctrl = E1000_READ_REG(hw, LEDCTL); led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= IGP_ACTIVITY_LED_ENABLE; - if(hw->mac_type == e1000_82547) - led_ctrl |= IGP_LED3_MODE; + led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); E1000_WRITE_REG(hw, LEDCTL, led_ctrl); if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { @@ -2252,7 +2295,8 @@ void e1000_phy_hw_reset(struct e1000_hw *hw) { - uint32_t ctrl, ctrl_ext, led_ctrl; + uint32_t ctrl, ctrl_ext; + uint32_t led_ctrl; DEBUGFUNC("e1000_phy_hw_reset"); @@ -2293,9 +2337,7 @@ /* Configure activity LED after PHY reset */ led_ctrl = E1000_READ_REG(hw, LEDCTL); led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= IGP_ACTIVITY_LED_ENABLE; - if(hw->mac_type == e1000_82547) - led_ctrl |= IGP_LED3_MODE; + led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); E1000_WRITE_REG(hw, LEDCTL, led_ctrl); } } @@ -3801,6 +3843,7 @@ case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: case E1000_DEV_ID_82541EI: case E1000_DEV_ID_82541EP: case E1000_DEV_ID_82547EI: @@ -3842,6 +3885,7 @@ case E1000_DEV_ID_82545EM_FIBER: case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: case E1000_DEV_ID_82541EI: case E1000_DEV_ID_82541EP: case E1000_DEV_ID_82547EI: @@ -3896,6 +3940,7 @@ case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: case E1000_DEV_ID_82541EI: case E1000_DEV_ID_82541EP: case E1000_DEV_ID_82547EI: @@ -3949,6 +3994,7 @@ case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: case E1000_DEV_ID_82541EI: case E1000_DEV_ID_82541EP: case E1000_DEV_ID_82547EI: @@ -4206,7 +4252,11 @@ status = E1000_READ_REG(hw, STATUS); hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? e1000_bus_type_pcix : e1000_bus_type_pci; - if(hw->bus_type == e1000_bus_type_pci) { + + if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) { + hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ? + e1000_bus_speed_66 : e1000_bus_speed_120; + } else if(hw->bus_type == e1000_bus_type_pci) { hw->bus_speed = (status & E1000_STATUS_PCI66) ? e1000_bus_speed_66 : e1000_bus_speed_33; } else { diff -urN linux-2.4.21/drivers/net/e1000/e1000_hw.h linux-2.4.22/drivers/net/e1000/e1000_hw.h --- linux-2.4.21/drivers/net/e1000/e1000_hw.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e1000/e1000_hw.h 2003-08-25 04:44:42.000000000 -0700 @@ -99,6 +99,7 @@ e1000_bus_speed_33, e1000_bus_speed_66, e1000_bus_speed_100, + e1000_bus_speed_120, e1000_bus_speed_133, e1000_bus_speed_reserved } e1000_bus_speed; @@ -314,10 +315,11 @@ #define E1000_DEV_ID_82545EM_FIBER 0x1011 #define E1000_DEV_ID_82546EB_COPPER 0x1010 #define E1000_DEV_ID_82546EB_FIBER 0x1012 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D #define E1000_DEV_ID_82541EI 0x1013 #define E1000_DEV_ID_82541EP 0x1018 #define E1000_DEV_ID_82547EI 0x1019 -#define NUM_DEV_IDS 19 +#define NUM_DEV_IDS 20 #define NODE_ADDRESS_SIZE 6 #define ETH_LENGTH_OF_ADDRESS 6 @@ -601,7 +603,7 @@ #define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ #define E1000_EERD 0x00014 /* EEPROM Read - RW */ #define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ -#define E1000_FLA 0x0001C /* Flash Access Register - RW */ +#define E1000_FLA 0x0001C /* Flash Access - RW */ #define E1000_MDIC 0x00020 /* MDI Control - RW */ #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ @@ -730,6 +732,7 @@ * the registers function in the same manner. */ #define E1000_82542_CTRL E1000_CTRL +#define E1000_82542_CTRL_DUP E1000_CTRL_DUP #define E1000_82542_STATUS E1000_STATUS #define E1000_82542_EECD E1000_EECD #define E1000_82542_EERD E1000_EERD @@ -1485,7 +1488,6 @@ #define E1000_COLLISION_DISTANCE 64 #define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE #define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE -#define E1000_GB_HDX_COLLISION_DISTANCE 512 #define E1000_COLD_SHIFT 12 /* The number of Transmit and Receive Descriptors must be a multiple of 8 */ @@ -1666,6 +1668,7 @@ #define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ #define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */ +#define IGP01E1000_IEEE_REGS_PAGE 0x0000 /* IGP01E1000 Specific Registers */ #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */ #define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */ @@ -1688,6 +1691,7 @@ * speed = 1000 Mbps. */ #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 +#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0 #define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ @@ -1978,6 +1982,22 @@ #define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed * on Link-Up */ #define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */ +/* IGP01E1000 Analog Register */ +#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x0011 +#define IGP01E1000_ANALOG_FUSE_STATUS 0x0010 +#define IGP01E1000_ANALOG_FUSE_CONTROL 0x001C +#define IGP01E1000_ANALOG_FUSE_BYPASS 0x001E + +#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000 +#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80 +#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070 +#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100 +#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002 + +#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH 0x0040 +#define IGP01E1000_ANALOG_FUSE_COARSE_10 0x0010 +#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080 +#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500 /* Bit definitions for valid PHY IDs. */ #define M88E1000_E_PHY_ID 0x01410C50 diff -urN linux-2.4.21/drivers/net/e1000/e1000_main.c linux-2.4.22/drivers/net/e1000/e1000_main.c --- linux-2.4.21/drivers/net/e1000/e1000_main.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e1000/e1000_main.c 2003-08-25 04:44:42.000000000 -0700 @@ -30,67 +30,38 @@ /* Change Log * - * 5.0.43 3/5/03 - * o Feature: Added support for 82541 and 82547 hardware. - * o Feature: Added support for Intel Gigabit PHY (IGP) and a variety of - * eeproms. - * o Feature: Added support for TCP Segmentation Offload (TSO). - * o Feature: Added MII ioctl. - * o Feature: Added support for statistics reporting through ethtool. - * o Cleanup: Removed proprietary hooks for ANS. - * o Cleanup: Miscellaneous code changes to improve CPU utilization. - * - Replaced "%" with conditionals and "+-" operators. - * - Implemented dynamic Interrupt Throttle Rate (ITR). - * - Reduced expensive PCI reads of ICR in interrupt. - * o Bug fix: Request IRQ after descriptor ring setup to avoid panic in - * shared interrupt instances. - * - * 4.4.18 11/27/02 - * o Feature: Added user-settable knob for interrupt throttle rate (ITR). - * o Cleanup: removed large static array allocations. - * o Cleanup: C99 struct initializer format. - * o Bug fix: restore VLAN settings when interface is brought up. - * o Bug fix: return cleanly in probe if error in detecting MAC type. - * o Bug fix: Wake up on magic packet by default only if enabled in eeprom. - * o Bug fix: Validate MAC address in set_mac. - * o Bug fix: Throw away zero-length Tx skbs. - * o Bug fix: Make ethtool EEPROM acceses work on older versions of ethtool. - * - * 4.4.12 10/15/02 + * 5.1.13 5/28/03 + * o Bug fix: request_irq() failure resulted in freeing resources twice! + * [Don Fry (brazilnut@us.ibm.com)] + * o Bug fix: fix VLAN support on ppc64 [Mark Rakes (mrakes@vivato.net)] + * o Bug fix: missing Tx cleanup opportunities during interrupt handling. + * o Bug fix: alloc_etherdev failure didn't cleanup regions in probe. + * o Cleanup: s/int/unsigned int/ for descriptor ring indexes. + * + * 5.1.11 5/6/03 + * o Feature: Added support for 82546EB (Quad-port) hardware. + * o Feature: Added support for Diagnostics through Ethtool. + * o Cleanup: Removed /proc support. + * o Cleanup: Removed proprietary IDIAG interface. + * o Bug fix: TSO bug fixes. + * + * 5.0.42 3/5/03 */ char e1000_driver_name[] = "e1000"; char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -char e1000_driver_version[] = "5.0.43-k1"; +char e1000_driver_version[] = "5.1.13-k1"; char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table * - * Private driver_data field (last one) stores an index into e1000_strings * Wildcard entries (PCI_ANY_ID) should come last * Last entry must be all 0s * * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, - * Class, Class Mask, String Index } + * Class, Class Mask, private data (not used) } */ static struct pci_device_id e1000_pci_tbl[] __devinitdata = { - /* Intel(R) PRO/1000 Network Connection */ - {0x8086, 0x1000, 0x8086, 0x1000, 0, 0, 0}, - {0x8086, 0x1001, 0x8086, 0x1003, 0, 0, 0}, - {0x8086, 0x1004, 0x8086, 0x1004, 0, 0, 0}, - {0x8086, 0x1008, 0x8086, 0x1107, 0, 0, 0}, - {0x8086, 0x1009, 0x8086, 0x1109, 0, 0, 0}, - {0x8086, 0x100C, 0x8086, 0x1112, 0, 0, 0}, - {0x8086, 0x100E, 0x8086, 0x001E, 0, 0, 0}, - /* Compaq Gigabit Ethernet Server Adapter */ - {0x8086, 0x1000, 0x0E11, PCI_ANY_ID, 0, 0, 1}, - {0x8086, 0x1001, 0x0E11, PCI_ANY_ID, 0, 0, 1}, - {0x8086, 0x1004, 0x0E11, PCI_ANY_ID, 0, 0, 1}, - /* IBM Mobile, Desktop & Server Adapters */ - {0x8086, 0x1000, 0x1014, PCI_ANY_ID, 0, 0, 2}, - {0x8086, 0x1001, 0x1014, PCI_ANY_ID, 0, 0, 2}, - {0x8086, 0x1004, 0x1014, PCI_ANY_ID, 0, 0, 2}, - /* Generic */ {0x8086, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -106,6 +77,7 @@ {0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* required last entry */ @@ -114,12 +86,6 @@ MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); -static char *e1000_strings[] = { - "Intel(R) PRO/1000 Network Connection", - "HP Gigabit Ethernet Server Adapter", - "IBM Mobile, Desktop & Server Adapters" -}; - /* Local Function Prototypes */ int e1000_up(struct e1000_adapter *adapter); @@ -130,7 +96,7 @@ static int e1000_init_module(void); static void e1000_exit_module(void); static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void e1000_remove(struct pci_dev *pdev); +static void __devexit e1000_remove(struct pci_dev *pdev); static int e1000_sw_init(struct e1000_adapter *adapter); static int e1000_open(struct net_device *netdev); static int e1000_close(struct net_device *netdev); @@ -156,7 +122,13 @@ static inline void e1000_irq_enable(struct e1000_adapter *adapter); static void e1000_intr(int irq, void *data, struct pt_regs *regs); static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter); +#ifdef CONFIG_E1000_NAPI +static int e1000_clean(struct net_device *netdev, int *budget); +static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter, + int *work_done, int work_to_do); +#else static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter); +#endif static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter); static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, @@ -189,7 +161,6 @@ .priority = 0 }; - /* Exported from other modules */ extern void e1000_check_options(struct e1000_adapter *adapter); @@ -228,8 +199,9 @@ printk(KERN_INFO "%s\n", e1000_copyright); ret = pci_module_init(&e1000_driver); - if(ret >= 0) + if(ret >= 0) { register_reboot_notifier(&e1000_notifier_reboot); + } return ret; } @@ -269,12 +241,8 @@ e1000_alloc_rx_buffers(adapter); if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, - netdev->name, netdev)) { - e1000_reset_hw(&adapter->hw); - e1000_free_tx_resources(adapter); - e1000_free_rx_resources(adapter); + netdev->name, netdev)) return -1; - } mod_timer(&adapter->watchdog_timer, jiffies); e1000_irq_enable(adapter); @@ -418,6 +386,10 @@ netdev->do_ioctl = &e1000_ioctl; netdev->tx_timeout = &e1000_tx_timeout; netdev->watchdog_timeo = 5 * HZ; +#ifdef CONFIG_E1000_NAPI + netdev->poll = &e1000_clean; + netdev->weight = 64; +#endif netdev->vlan_rx_register = e1000_vlan_rx_register; netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid; netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid; @@ -428,7 +400,6 @@ netdev->base_addr = adapter->hw.io_base; adapter->bd_number = cards_found; - adapter->id_string = e1000_strings[ent->driver_data]; /* setup the private structure */ @@ -445,6 +416,12 @@ netdev->features = NETIF_F_SG; } +#ifdef NETIF_F_TSO + if((adapter->hw.mac_type >= e1000_82544) && + (adapter->hw.mac_type != e1000_82547)) + netdev->features |= NETIF_F_TSO; +#endif + if(pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -483,15 +460,14 @@ (void (*)(void *))e1000_tx_timeout_task, netdev); register_netdev(netdev); - memcpy(adapter->ifname, netdev->name, IFNAMSIZ); - adapter->ifname[IFNAMSIZ-1] = 0; /* we're going to reset, so assume we have no link for now */ netif_carrier_off(netdev); netif_stop_queue(netdev); - printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string); + printk(KERN_INFO "%s: Intel(R) PRO/1000 Network Connection\n", + netdev->name); e1000_check_options(adapter); /* Initial Wake on LAN setting @@ -516,9 +492,9 @@ err_eeprom: iounmap(adapter->hw.hw_addr); err_ioremap: - pci_release_regions(pdev); kfree(netdev); err_alloc_etherdev: + pci_release_regions(pdev); return -ENOMEM; } @@ -551,7 +527,6 @@ e1000_phy_hw_reset(&adapter->hw); - iounmap(adapter->hw.hw_addr); pci_release_regions(pdev); @@ -814,8 +789,9 @@ e1000_config_collision_dist(&adapter->hw); - /* Setup Transmit Descriptor Settings for this adapter */ - adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_IDE; + /* Setup Transmit Descriptor Settings for eop descriptor */ + adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP | + E1000_TXD_CMD_IFCS; if(adapter->hw.report_tx_early == 1) adapter->txd_cmd |= E1000_TXD_CMD_RS; @@ -993,35 +969,38 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter) { + struct e1000_desc_ring *tx_ring = &adapter->tx_ring; + struct e1000_buffer *buffer_info; struct pci_dev *pdev = adapter->pdev; unsigned long size; - int i; + unsigned int i; /* Free all the Tx ring sk_buffs */ - for(i = 0; i < adapter->tx_ring.count; i++) { - if(adapter->tx_ring.buffer_info[i].skb) { + for(i = 0; i < tx_ring->count; i++) { + buffer_info = &tx_ring->buffer_info[i]; + if(buffer_info->skb) { pci_unmap_page(pdev, - adapter->tx_ring.buffer_info[i].dma, - adapter->tx_ring.buffer_info[i].length, + buffer_info->dma, + buffer_info->length, PCI_DMA_TODEVICE); - dev_kfree_skb(adapter->tx_ring.buffer_info[i].skb); + dev_kfree_skb(buffer_info->skb); - adapter->tx_ring.buffer_info[i].skb = NULL; + buffer_info->skb = NULL; } } - size = sizeof(struct e1000_buffer) * adapter->tx_ring.count; - memset(adapter->tx_ring.buffer_info, 0, size); + size = sizeof(struct e1000_buffer) * tx_ring->count; + memset(tx_ring->buffer_info, 0, size); /* Zero out the descriptor ring */ - memset(adapter->tx_ring.desc, 0, adapter->tx_ring.size); + memset(tx_ring->desc, 0, tx_ring->size); - adapter->tx_ring.next_to_use = 0; - adapter->tx_ring.next_to_clean = 0; + tx_ring->next_to_use = 0; + tx_ring->next_to_clean = 0; E1000_WRITE_REG(&adapter->hw, TDH, 0); E1000_WRITE_REG(&adapter->hw, TDT, 0); @@ -1037,17 +1016,17 @@ static void e1000_free_rx_resources(struct e1000_adapter *adapter) { + struct e1000_desc_ring *rx_ring = &adapter->rx_ring; struct pci_dev *pdev = adapter->pdev; e1000_clean_rx_ring(adapter); - kfree(adapter->rx_ring.buffer_info); - adapter->rx_ring.buffer_info = NULL; + kfree(rx_ring->buffer_info); + rx_ring->buffer_info = NULL; - pci_free_consistent(pdev, adapter->rx_ring.size, - adapter->rx_ring.desc, adapter->rx_ring.dma); + pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma); - adapter->rx_ring.desc = NULL; + rx_ring->desc = NULL; } /** @@ -1058,35 +1037,38 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) { + struct e1000_desc_ring *rx_ring = &adapter->rx_ring; + struct e1000_buffer *buffer_info; struct pci_dev *pdev = adapter->pdev; unsigned long size; - int i; + unsigned int i; /* Free all the Rx ring sk_buffs */ - for(i = 0; i < adapter->rx_ring.count; i++) { - if(adapter->rx_ring.buffer_info[i].skb) { + for(i = 0; i < rx_ring->count; i++) { + buffer_info = &rx_ring->buffer_info[i]; + if(buffer_info->skb) { pci_unmap_single(pdev, - adapter->rx_ring.buffer_info[i].dma, - adapter->rx_ring.buffer_info[i].length, + buffer_info->dma, + buffer_info->length, PCI_DMA_FROMDEVICE); - dev_kfree_skb(adapter->rx_ring.buffer_info[i].skb); + dev_kfree_skb(buffer_info->skb); - adapter->rx_ring.buffer_info[i].skb = NULL; + buffer_info->skb = NULL; } } - size = sizeof(struct e1000_buffer) * adapter->rx_ring.count; - memset(adapter->rx_ring.buffer_info, 0, size); + size = sizeof(struct e1000_buffer) * rx_ring->count; + memset(rx_ring->buffer_info, 0, size); /* Zero out the descriptor ring */ - memset(adapter->rx_ring.desc, 0, adapter->rx_ring.size); + memset(rx_ring->desc, 0, rx_ring->size); - adapter->rx_ring.next_to_clean = 0; - adapter->rx_ring.next_to_use = 0; + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; E1000_WRITE_REG(&adapter->hw, RDH, 0); E1000_WRITE_REG(&adapter->hw, RDT, 0); @@ -1336,7 +1318,7 @@ struct e1000_adapter *adapter = (struct e1000_adapter *) data; struct net_device *netdev = adapter->netdev; struct e1000_desc_ring *txdr = &adapter->tx_ring; - int i; + unsigned int i; e1000_check_for_link(&adapter->hw); @@ -1413,14 +1395,67 @@ #define E1000_TX_FLAGS_CSUM 0x00000001 #define E1000_TX_FLAGS_VLAN 0x00000002 +#define E1000_TX_FLAGS_TSO 0x00000004 #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 #define E1000_TX_FLAGS_VLAN_SHIFT 16 static inline boolean_t +e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb) +{ +#ifdef NETIF_F_TSO + struct e1000_context_desc *context_desc; + unsigned int i; + uint8_t ipcss, ipcso, tucss, tucso, hdr_len; + uint16_t ipcse, tucse, mss; + + if(skb_shinfo(skb)->tso_size) { + hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); + mss = skb_shinfo(skb)->tso_size; + skb->nh.iph->tot_len = 0; + skb->nh.iph->check = 0; + skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, + IPPROTO_TCP, + 0); + ipcss = skb->nh.raw - skb->data; + ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data; + ipcse = skb->h.raw - skb->data - 1; + tucss = skb->h.raw - skb->data; + tucso = (void *)&(skb->h.th->check) - (void *)skb->data; + tucse = 0; + + i = adapter->tx_ring.next_to_use; + context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i); + + context_desc->lower_setup.ip_fields.ipcss = ipcss; + context_desc->lower_setup.ip_fields.ipcso = ipcso; + context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse); + context_desc->upper_setup.tcp_fields.tucss = tucss; + context_desc->upper_setup.tcp_fields.tucso = tucso; + context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse); + context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss); + context_desc->tcp_seg_setup.fields.hdr_len = hdr_len; + context_desc->cmd_and_length = cpu_to_le32( + E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | + E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP | + (skb->len - (hdr_len))); + + if(++i == adapter->tx_ring.count) i = 0; + adapter->tx_ring.next_to_use = i; + + return TRUE; + } +#endif + + return FALSE; +} + +static inline boolean_t e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) { struct e1000_context_desc *context_desc; - int i; + unsigned int i; uint8_t css, cso; if(skb->ip_summed == CHECKSUM_HW) { @@ -1434,8 +1469,7 @@ context_desc->upper_setup.tcp_fields.tucso = cso; context_desc->upper_setup.tcp_fields.tucse = 0; context_desc->tcp_seg_setup.data = 0; - context_desc->cmd_and_length = - cpu_to_le32(adapter->txd_cmd | E1000_TXD_CMD_DEXT); + context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT); if(++i == adapter->tx_ring.count) i = 0; adapter->tx_ring.next_to_use = i; @@ -1450,25 +1484,39 @@ #define E1000_MAX_DATA_PER_TXD (1<tx_ring; - int len = skb->len, offset = 0, size, count = 0, i; + struct e1000_buffer *buffer_info; + int len = skb->len; + unsigned int offset = 0, size, count = 0, i; - int f; +#ifdef NETIF_F_TSO + unsigned int tso = skb_shinfo(skb)->tso_size; +#endif + unsigned int nr_frags = skb_shinfo(skb)->nr_frags; + unsigned int f; len -= skb->data_len; i = tx_ring->next_to_use; while(len) { + buffer_info = &tx_ring->buffer_info[i]; size = min(len, E1000_MAX_DATA_PER_TXD); - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = +#ifdef NETIF_F_TSO + /* Workaround for premature desc write-backs + * in TSO mode. Append 4-byte sentinel desc */ + if(tso && !nr_frags && size == len && size > 4) + size -= 4; +#endif + buffer_info->length = size; + buffer_info->dma = pci_map_single(adapter->pdev, skb->data + offset, size, PCI_DMA_TODEVICE); - tx_ring->buffer_info[i].time_stamp = jiffies; + buffer_info->time_stamp = jiffies; len -= size; offset += size; @@ -1476,7 +1524,7 @@ if(++i == tx_ring->count) i = 0; } - for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) { + for(f = 0; f < nr_frags; f++) { struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; @@ -1484,15 +1532,22 @@ offset = 0; while(len) { + buffer_info = &tx_ring->buffer_info[i]; size = min(len, E1000_MAX_DATA_PER_TXD); - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = +#ifdef NETIF_F_TSO + /* Workaround for premature desc write-backs + * in TSO mode. Append 4-byte sentinel desc */ + if(tso && f == (nr_frags-1) && size == len && size > 4) + size -= 4; +#endif + buffer_info->length = size; + buffer_info->dma = pci_map_page(adapter->pdev, frag->page, frag->page_offset + offset, size, PCI_DMA_TODEVICE); - tx_ring->buffer_info[i].time_stamp = jiffies; + buffer_info->time_stamp = jiffies; len -= size; offset += size; @@ -1500,8 +1555,9 @@ if(++i == tx_ring->count) i = 0; } } - if(--i < 0) i = tx_ring->count - 1; + i = (i == 0) ? tx_ring->count - 1 : i - 1; tx_ring->buffer_info[i].skb = skb; + tx_ring->buffer_info[first].next_to_watch = i; return count; } @@ -1511,11 +1567,15 @@ { struct e1000_desc_ring *tx_ring = &adapter->tx_ring; struct e1000_tx_desc *tx_desc = NULL; - uint32_t txd_upper, txd_lower; - int i; - - txd_upper = 0; - txd_lower = adapter->txd_cmd; + struct e1000_buffer *buffer_info; + uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS; + unsigned int i; + + if(tx_flags & E1000_TX_FLAGS_TSO) { + txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D | + E1000_TXD_CMD_TSE; + txd_upper |= (E1000_TXD_POPTS_IXSM | E1000_TXD_POPTS_TXSM) << 8; + } if(tx_flags & E1000_TX_FLAGS_CSUM) { txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; @@ -1530,15 +1590,16 @@ i = tx_ring->next_to_use; while(count--) { + buffer_info = &tx_ring->buffer_info[i]; tx_desc = E1000_TX_DESC(*tx_ring, i); - tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); + tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); tx_desc->lower.data = - cpu_to_le32(txd_lower | tx_ring->buffer_info[i].length); + cpu_to_le32(txd_lower | buffer_info->length); tx_desc->upper.data = cpu_to_le32(txd_upper); if(++i == tx_ring->count) i = 0; } - tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP); + tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd); /* Force memory writes to complete before letting h/w * know there are new descriptors to fetch. (Only @@ -1598,7 +1659,8 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct e1000_adapter *adapter = netdev->priv; - int tx_flags = 0; + unsigned int first; + unsigned int tx_flags = 0; if(skb->len <= 0) { dev_kfree_skb_any(skb); @@ -1623,10 +1685,14 @@ tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } - if(e1000_tx_csum(adapter, skb)) + first = adapter->tx_ring.next_to_use; + + if(e1000_tso(adapter, skb)) + tx_flags |= E1000_TX_FLAGS_TSO; + else if(e1000_tx_csum(adapter, skb)) tx_flags |= E1000_TX_FLAGS_CSUM; - e1000_tx_queue(adapter, e1000_tx_map(adapter, skb), tx_flags); + e1000_tx_queue(adapter, e1000_tx_map(adapter, skb, first), tx_flags); netdev->trans_start = jiffies; @@ -1858,6 +1924,7 @@ } if((hw->mac_type <= e1000_82546) && + (hw->phy_type == e1000_phy_m88) && !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp)) adapter->phy_stats.receive_errors += phy_tmp; } @@ -1904,7 +1971,9 @@ struct net_device *netdev = data; struct e1000_adapter *adapter = netdev->priv; uint32_t icr = E1000_READ_REG(&adapter->hw, ICR); - int i; +#ifndef CONFIG_E1000_NAPI + unsigned int i; +#endif if(!icr) return; /* Not our interrupt */ @@ -1914,12 +1983,52 @@ mod_timer(&adapter->watchdog_timer, jiffies); } +#ifdef CONFIG_E1000_NAPI + if(netif_rx_schedule_prep(netdev)) { + + /* Disable interrupts and register for poll. The flush + of the posted write is intentionally left out. + */ + + atomic_inc(&adapter->irq_sem); + E1000_WRITE_REG(&adapter->hw, IMC, ~0); + __netif_rx_schedule(netdev); + } +#else for(i = 0; i < E1000_MAX_INTR; i++) - if(!e1000_clean_rx_irq(adapter) && + if(!e1000_clean_rx_irq(adapter) & !e1000_clean_tx_irq(adapter)) break; +#endif +} +#ifdef CONFIG_E1000_NAPI +/** + * e1000_clean - NAPI Rx polling callback + * @adapter: board private structure + **/ + +static int +e1000_clean(struct net_device *netdev, int *budget) +{ + struct e1000_adapter *adapter = netdev->priv; + int work_to_do = min(*budget, netdev->quota); + int work_done = 0; + + e1000_clean_tx_irq(adapter); + e1000_clean_rx_irq(adapter, &work_done, work_to_do); + + *budget -= work_done; + netdev->quota -= work_done; + + if(work_done < work_to_do) { + netif_rx_complete(netdev); + e1000_irq_enable(adapter); + } + + return (work_done >= work_to_do); } +#endif /** * e1000_clean_tx_irq - Reclaim resources after transmit completes @@ -1932,39 +2041,48 @@ struct e1000_desc_ring *tx_ring = &adapter->tx_ring; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - struct e1000_tx_desc *tx_desc; - int i, cleaned = FALSE; + struct e1000_tx_desc *tx_desc, *eop_desc; + struct e1000_buffer *buffer_info; + unsigned int i, eop; + boolean_t cleaned = FALSE; i = tx_ring->next_to_clean; - tx_desc = E1000_TX_DESC(*tx_ring, i); + eop = tx_ring->buffer_info[i].next_to_watch; + eop_desc = E1000_TX_DESC(*tx_ring, eop); - while(tx_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { + while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { - cleaned = TRUE; + for(cleaned = FALSE; !cleaned; ) { + tx_desc = E1000_TX_DESC(*tx_ring, i); + buffer_info = &tx_ring->buffer_info[i]; - if(tx_ring->buffer_info[i].dma) { + if(buffer_info->dma) { - pci_unmap_page(pdev, - tx_ring->buffer_info[i].dma, - tx_ring->buffer_info[i].length, - PCI_DMA_TODEVICE); + pci_unmap_page(pdev, + buffer_info->dma, + buffer_info->length, + PCI_DMA_TODEVICE); - tx_ring->buffer_info[i].dma = 0; - } + buffer_info->dma = 0; + } - if(tx_ring->buffer_info[i].skb) { + if(buffer_info->skb) { - dev_kfree_skb_any(tx_ring->buffer_info[i].skb); + dev_kfree_skb_any(buffer_info->skb); - tx_ring->buffer_info[i].skb = NULL; - } + buffer_info->skb = NULL; + } - tx_desc->buffer_addr = 0; - tx_desc->lower.data = 0; - tx_desc->upper.data = 0; + tx_desc->buffer_addr = 0; + tx_desc->lower.data = 0; + tx_desc->upper.data = 0; - if(++i == tx_ring->count) i = 0; - tx_desc = E1000_TX_DESC(*tx_ring, i); + cleaned = (i == eop); + if(++i == tx_ring->count) i = 0; + } + + eop = tx_ring->buffer_info[i].next_to_watch; + eop_desc = E1000_TX_DESC(*tx_ring, eop); } tx_ring->next_to_clean = i; @@ -1981,31 +2099,46 @@ **/ static boolean_t +#ifdef CONFIG_E1000_NAPI +e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done, + int work_to_do) +#else e1000_clean_rx_irq(struct e1000_adapter *adapter) +#endif { struct e1000_desc_ring *rx_ring = &adapter->rx_ring; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc; + struct e1000_buffer *buffer_info; struct sk_buff *skb; unsigned long flags; uint32_t length; uint8_t last_byte; - int i, cleaned = FALSE; + unsigned int i; + boolean_t cleaned = FALSE; i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC(*rx_ring, i); while(rx_desc->status & E1000_RXD_STAT_DD) { + buffer_info = &rx_ring->buffer_info[i]; + +#ifdef CONFIG_E1000_NAPI + if(*work_done >= work_to_do) + break; + + (*work_done)++; +#endif cleaned = TRUE; pci_unmap_single(pdev, - rx_ring->buffer_info[i].dma, - rx_ring->buffer_info[i].length, + buffer_info->dma, + buffer_info->length, PCI_DMA_FROMDEVICE); - skb = rx_ring->buffer_info[i].skb; + skb = buffer_info->skb; length = le16_to_cpu(rx_desc->length); if(!(rx_desc->status & E1000_RXD_STAT_EOP)) { @@ -2016,7 +2149,7 @@ dev_kfree_skb_irq(skb); rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; + buffer_info->skb = NULL; if(++i == rx_ring->count) i = 0; @@ -2044,7 +2177,7 @@ dev_kfree_skb_irq(skb); rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; + buffer_info->skb = NULL; if(++i == rx_ring->count) i = 0; @@ -2060,16 +2193,27 @@ e1000_rx_checksum(adapter, rx_desc, skb); skb->protocol = eth_type_trans(skb, netdev); +#ifdef CONFIG_E1000_NAPI + if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) { + vlan_hwaccel_receive_skb(skb, adapter->vlgrp, + le16_to_cpu(rx_desc->special & + E1000_RXD_SPC_VLAN_MASK)); + } else { + netif_receive_skb(skb); + } +#else /* CONFIG_E1000_NAPI */ if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) { vlan_hwaccel_rx(skb, adapter->vlgrp, - (rx_desc->special & E1000_RXD_SPC_VLAN_MASK)); + le16_to_cpu(rx_desc->special & + E1000_RXD_SPC_VLAN_MASK)); } else { netif_rx(skb); } +#endif /* CONFIG_E1000_NAPI */ netdev->last_rx = jiffies; rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; + buffer_info->skb = NULL; if(++i == rx_ring->count) i = 0; @@ -2095,13 +2239,15 @@ struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc; + struct e1000_buffer *buffer_info; struct sk_buff *skb; int reserve_len = 2; - int i; + unsigned int i; i = rx_ring->next_to_use; + buffer_info = &rx_ring->buffer_info[i]; - while(!rx_ring->buffer_info[i].skb) { + while(!buffer_info->skb) { rx_desc = E1000_RX_DESC(*rx_ring, i); skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len); @@ -2119,15 +2265,15 @@ skb->dev = netdev; - rx_ring->buffer_info[i].skb = skb; - rx_ring->buffer_info[i].length = adapter->rx_buffer_len; - rx_ring->buffer_info[i].dma = + buffer_info->skb = skb; + buffer_info->length = adapter->rx_buffer_len; + buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma); + rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); if((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i) { /* Force memory writes to complete before letting h/w @@ -2140,6 +2286,7 @@ } if(++i == rx_ring->count) i = 0; + buffer_info = &rx_ring->buffer_info[i]; } rx_ring->next_to_use = i; @@ -2518,7 +2665,6 @@ return NOTIFY_DONE; } - static int e1000_suspend(struct pci_dev *pdev, uint32_t state) { diff -urN linux-2.4.21/drivers/net/e1000/e1000_osdep.h linux-2.4.22/drivers/net/e1000/e1000_osdep.h --- linux-2.4.21/drivers/net/e1000/e1000_osdep.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/e1000/e1000_osdep.h 2003-08-25 04:44:42.000000000 -0700 @@ -27,7 +27,7 @@ *******************************************************************************/ -/* glue for the OS independant part of e1000 +/* glue for the OS independent part of e1000 * includes register access macros */ diff -urN linux-2.4.21/drivers/net/eepro.c linux-2.4.22/drivers/net/eepro.c --- linux-2.4.21/drivers/net/eepro.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/eepro.c 2003-08-25 04:44:42.000000000 -0700 @@ -1716,7 +1716,7 @@ static int n_eepro; /* For linux 2.1.xx */ -MODULE_AUTHOR("Pascal Dupuis for the 2.1 stuff (locking,...)"); +MODULE_AUTHOR("Pascal Dupuis, and aris@cathedrallabs.org"); MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver"); MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/net/eepro100.c linux-2.4.22/drivers/net/eepro100.c --- linux-2.4.21/drivers/net/eepro100.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/eepro100.c 2003-08-25 04:44:42.000000000 -0700 @@ -2392,6 +2392,7 @@ { 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, 0x1050, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x1059, 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, }, diff -urN linux-2.4.21/drivers/net/eexpress.c linux-2.4.22/drivers/net/eexpress.c --- linux-2.4.21/drivers/net/eexpress.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.22/drivers/net/eexpress.c 2003-08-25 04:44:42.000000000 -0700 @@ -654,7 +654,7 @@ buf = skb_padto(buf, ETH_ZLEN); if(buf == NULL) return 0; - length = buf->len; + length = ETH_ZLEN; } disable_irq(dev->irq); diff -urN linux-2.4.21/drivers/net/gmac.c linux-2.4.22/drivers/net/gmac.c --- linux-2.4.21/drivers/net/gmac.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/net/gmac.c 2003-08-25 04:44:42.000000000 -0700 @@ -1622,6 +1622,7 @@ gm->of_node = gmac; if (!request_OF_resource(gmac, 0, " (gmac)")) { printk(KERN_ERR "GMAC: can't request IO resource !\n"); + gm->of_node = NULL; goto out_unreg; } dev->base_addr = gmac->addrs[0].address; diff -urN linux-2.4.21/drivers/net/hamradio/mkiss.c linux-2.4.22/drivers/net/hamradio/mkiss.c --- linux-2.4.21/drivers/net/hamradio/mkiss.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/hamradio/mkiss.c 2003-08-25 04:44:42.000000000 -0700 @@ -330,6 +330,12 @@ return; } ax->rcount -= 2; + /* dl9sau bugfix: the trailling two bytes flexnet crc + * will not be passed to the kernel. thus we have + * to correct the kissparm signature, because it + * indicates a crc but there's none + */ + *ax->rbuff &= ~0x20; } } diff -urN linux-2.4.21/drivers/net/ibm_emac/Config.in linux-2.4.22/drivers/net/ibm_emac/Config.in --- linux-2.4.21/drivers/net/ibm_emac/Config.in 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/Config.in 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,24 @@ +# +# On-chip network configuration +# +mainmenu_option next_comment +comment 'On-chip net devices' +if [ "$CONFIG_IBM_OCP" = "y" ]; then + bool ' IBM on-chip ethernet' CONFIG_IBM_OCP_ENET + if [ "$CONFIG_IBM_OCP_ENET" = "y" ]; then + bool ' Verbose error messages' CONFIG_IBM_OCP_ENET_ERROR_MSG + int ' Number of receive buffers' CONFIG_IBM_OCP_ENET_RX_BUFF 64 + int ' Number of transmit buffers' CONFIG_IBM_OCP_ENET_TX_BUFF 8 + int ' Frame gap' CONFIG_IBM_OCP_ENET_GAP 8 + int ' Skb reserve amount' CONFIG_IBM_OCP_ENET_SKB_RES 0 + fi + if [ "$CONFIG_IBM_OCP_ENET" = "y" ]; then + define_bool CONFIG_OCP_NET y + if [ "$CONFIG_NP405H" = "y" -o "$CONFIG_NP405L" = "y" \ + -o "$CONFIG_440" = "y" ]; then + define_int CONFIG_IBM_OCP_MAL_CNT 1 + define_bool CONFIG_IBM_OCP_ZMII y + fi + fi +fi +endmenu diff -urN linux-2.4.21/drivers/net/ibm_emac/Makefile linux-2.4.22/drivers/net/ibm_emac/Makefile --- linux-2.4.21/drivers/net/ibm_emac/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,26 @@ +# +# Makefile for the On-chip ethernet drivers +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + + +obj-y := +obj-m := + +O_TARGET := ocp.o + +# Module support doesn't work yet. +export-objs := + +obj-$(CONFIG_IBM_OCP_ENET) += ibm_ocp_enet.o ibm_ocp_phy.o ibm_ocp_mal.o + +# Only need this if you want to see additional debug messages +ifeq ($(CONFIG_IBM_OCP_ENET_ERROR_MSG), y) +obj-$(CONFIG_IBM_OCP_ENET) += ibm_ocp_debug.o +endif + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_emac.h linux-2.4.22/drivers/net/ibm_emac/ibm_emac.h --- linux-2.4.21/drivers/net/ibm_emac/ibm_emac.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_emac.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,195 @@ +/* + * ibm_emac.h + * + * + * Armin Kuster akuster@mvista.com + * June, 2002 + * + * Copyright 2002 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + * Version: 1.0: 06/02/02 - armin + * pulled all emac defined out od enet.h + * + */ + +#ifndef _IBM_OCP_EMAC_H_ +#define _IBM_OCP_EMAC_H_ +/* General defines needed for the driver */ + +/* Emac */ +typedef struct emac_regs { + u32 em0mr0; + u32 em0mr1; + u32 em0tmr0; + u32 em0tmr1; + u32 em0rmr; + u32 em0isr; + u32 em0iser; + u32 em0iahr; + u32 em0ialr; + u32 em0vtpid; + u32 em0vtci; + u32 em0ptr; + u32 em0iaht1; + u32 em0iaht2; + u32 em0iaht3; + u32 em0iaht4; + u32 em0gaht1; + u32 em0gaht2; + u32 em0gaht3; + u32 em0gaht4; + u32 em0lsal; + u32 em0lsah; + u32 em0ipgvr; + u32 em0stacr; + u32 em0trtr; + u32 em0rwmr; +} emac_t; + + +/* MODE REG 0 */ +#define EMAC_M0_RXI 0x80000000 +#define EMAC_M0_TXI 0x40000000 +#define EMAC_M0_SRST 0x20000000 +#define EMAC_M0_TXE 0x10000000 +#define EMAC_M0_RXE 0x08000000 +#define EMAC_M0_WKE 0x04000000 + +/* MODE Reg 1 */ +#define EMAC_M1_FDE 0x80000000 +#define EMAC_M1_ILE 0x40000000 +#define EMAC_M1_VLE 0x20000000 +#define EMAC_M1_EIFC 0x10000000 +#define EMAC_M1_APP 0x08000000 +#define EMAC_M1_AEMI 0x02000000 +#define EMAC_M1_IST 0x01000000 +#define EMAC_M1_MF_1000MBPS 0x00800000 /* 0's for 10MBPS */ +#define EMAC_M1_MF_100MBPS 0x00400000 +#define EMAC_M1_RFS_4K 0x00300000 /* ~4k for 512 byte */ +#define EMAC_M1_RFS_2K 0x00200000 +#define EMAC_M1_RFS_1K 0x00100000 +#define EMAC_M1_TX_FIFO_2K 0x00080000 /* 0's for 512 byte */ +#define EMAC_M1_TX_FIFO_1K 0x00040000 +#define EMAC_M1_TR0_DEPEND 0x00010000 /* 0'x for single packet */ +#define EMAC_M1_TR0_MULTI 0x00008000 +#define EMAC_M1_TR1_DEPEND 0x00004000 +#define EMAC_M1_TR1_MULTI 0x00002000 +#define EMAC_M1_JUMBO_ENABLE 0x00001000 + +/* Transmit Mode Register 0 */ +#define EMAC_TXM0_GNP0 0x80000000 +#define EMAC_TXM0_GNP1 0x40000000 +#define EMAC_TXM0_GNPD 0x20000000 +#define EMAC_TXM0_FC 0x10000000 + +/* Receive Mode Register */ +#define EMAC_RMR_SP 0x80000000 +#define EMAC_RMR_SFCS 0x40000000 +#define EMAC_RMR_ARRP 0x20000000 +#define EMAC_RMR_ARP 0x10000000 +#define EMAC_RMR_AROP 0x08000000 +#define EMAC_RMR_ARPI 0x04000000 +#define EMAC_RMR_PPP 0x02000000 +#define EMAC_RMR_PME 0x01000000 +#define EMAC_RMR_PMME 0x00800000 +#define EMAC_RMR_IAE 0x00400000 +#define EMAC_RMR_MIAE 0x00200000 +#define EMAC_RMR_BAE 0x00100000 +#define EMAC_RMR_MAE 0x00080000 + +/* Interrupt Status & enable Regs */ +#define EMAC_ISR_OVR 0x02000000 +#define EMAC_ISR_PP 0x01000000 +#define EMAC_ISR_BP 0x00800000 +#define EMAC_ISR_RP 0x00400000 +#define EMAC_ISR_SE 0x00200000 +#define EMAC_ISR_ALE 0x00100000 +#define EMAC_ISR_BFCS 0x00080000 +#define EMAC_ISR_PTLE 0x00040000 +#define EMAC_ISR_ORE 0x00020000 +#define EMAC_ISR_IRE 0x00010000 +#define EMAC_ISR_DBDM 0x00000200 +#define EMAC_ISR_DB0 0x00000100 +#define EMAC_ISR_SE0 0x00000080 +#define EMAC_ISR_TE0 0x00000040 +#define EMAC_ISR_DB1 0x00000020 +#define EMAC_ISR_SE1 0x00000010 +#define EMAC_ISR_TE1 0x00000008 +#define EMAC_ISR_MOS 0x00000002 +#define EMAC_ISR_MOF 0x00000001 + +/* STA CONTROL REG */ +#define EMAC_STACR_OC 0x00008000 +#define EMAC_STACR_PHYE 0x00004000 +#define EMAC_STACR_WRITE 0x00002000 +#define EMAC_STACR_READ 0x00001000 +#define EMAC_STACR_CLK_83MHZ 0x00000800 /* 0's for 50Mhz */ +#define EMAC_STACR_CLK_66MHZ 0x00000400 +#define EMAC_STACR_CLK_100MHZ 0x00000C00 + +/* Transmit Request Threshold Register */ +#define EMAC_TRTR_256 0x18000000 /* 0's for 64 Bytes */ +#define EMAC_TRTR_192 0x10000000 +#define EMAC_TRTR_128 0x01000000 + + +#define EMAC_TX_CTRL_GFCS 0x0200 +#define EMAC_TX_CTRL_GP 0x0100 +#define EMAC_TX_CTRL_ISA 0x0080 +#define EMAC_TX_CTRL_RSA 0x0040 +#define EMAC_TX_CTRL_IVT 0x0020 +#define EMAC_TX_CTRL_RVT 0x0010 + +#define EMAC_TX_CTRL_DFLT ( \ + MAL_TX_CTRL_LAST | MAL_TX_CTRL_READY | MAL_TX_CTRL_INTR | \ + EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP ) + +/* madmal transmit status / Control bits */ +#define EMAC_TX_ST_BFCS 0x0200 +#define EMAC_TX_ST_BPP 0x0100 +#define EMAC_TX_ST_LCS 0x0080 +#define EMAC_TX_ST_ED 0x0040 +#define EMAC_TX_ST_EC 0x0020 +#define EMAC_TX_ST_LC 0x0010 +#define EMAC_TX_ST_MC 0x0008 +#define EMAC_TX_ST_SC 0x0004 +#define EMAC_TX_ST_UR 0x0002 +#define EMAC_TX_ST_SQE 0x0001 + +#define EMAC_TX_ST_DEFAULT 0x03F3 + +/* madmal receive status / Control bits */ +#define EMAC_RX_ST_OE 0x0200 +#define EMAC_RX_ST_PP 0x0100 +#define EMAC_RX_ST_BP 0x0080 +#define EMAC_RX_ST_RP 0x0040 +#define EMAC_RX_ST_SE 0x0020 +#define EMAC_RX_ST_AE 0x0010 +#define EMAC_RX_ST_BFCS 0x0008 +#define EMAC_RX_ST_PTL 0x0004 +#define EMAC_RX_ST_ORE 0x0002 +#define EMAC_RX_ST_IRE 0x0001 +#define EMAC_BAD_RX_PACKET 0x02ff + + +#endif diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_debug.c linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_debug.c --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_debug.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_debug.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,264 @@ +/* + * ibm_ocp_debug.c + * + * This has all the debug routines that where in *_enet.c + * + * Armin Kuster akuster@mvista.com + * April , 2002 + * + * Copyright 2002 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + * TODO: + * + * Version 1.0: (04/15/02) + * initial release + * These are all the debug routines from *_enet.c and a few new ones. + * this was done to reduce the *_enet.c code. + * + * Version 1.1: 04/24/02 + * fixed missind EMAC_DEV macros - Todd + * + */ + +#include +#include +#include +#include +#include "ibm_ocp_mal.h" +#include "ibm_ocp_zmii.h" +#include "ibm_ocp_enet.h" + +extern int +emac_phy_read(struct net_device *dev, int mii_id, int reg); + +void emac_phy_dump(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + unsigned long i; + uint data; + + printk(KERN_DEBUG " Prepare for Phy dump....\n"); + for (i = 0; i < 0x1A; i++) { + data = emac_phy_read(dev, fep->mii_phy_addr, i); + printk(KERN_DEBUG "Phy reg 0x%lx ==> %4x\n", i, data); + if (i == 0x07) + i = 0x0f; + } +} + +void +emac_desc_dump(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + int curr_slot; + + printk(KERN_DEBUG "dumping the receive descriptors: current slot is %d\n", + fep->rx_slot); + for (curr_slot = 0; curr_slot < NUM_RX_BUFF; curr_slot++) { + printk(KERN_DEBUG "Desc %02d: status 0x%04x, length %3d, addr 0x%x\n", + curr_slot, + fep->rx_desc[curr_slot].ctrl, + fep->rx_desc[curr_slot].data_len, + (unsigned int) fep->rx_desc[curr_slot].data_ptr); + } +} + +void +emac_mac_dump(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + volatile emac_t *emacp = fep->emacp; + + printk(KERN_DEBUG "EMAC DEBUG ********** \n"); + printk(KERN_DEBUG "EMAC_M0 ==> 0x%x\n", in_be32(&emacp->em0mr0)); + printk(KERN_DEBUG "EMAC_M1 ==> 0x%x\n", in_be32(&emacp->em0mr1)); + printk(KERN_DEBUG "EMAC_TXM0==> 0x%x\n", in_be32(&emacp->em0tmr0)); + printk(KERN_DEBUG "EMAC_TXM1==> 0x%x\n", in_be32(&emacp->em0tmr1)); + printk(KERN_DEBUG "EMAC_RXM ==> 0x%x\n", in_be32(&emacp->em0rmr)); + printk(KERN_DEBUG "EMAC_ISR ==> 0x%x\n", in_be32(&emacp->em0isr)); + printk(KERN_DEBUG "EMAC_IER ==> 0x%x\n", in_be32(&emacp->em0iser)); + printk(KERN_DEBUG "EMAC_IAH ==> 0x%x\n", in_be32(&emacp->em0iahr)); + printk(KERN_DEBUG "EMAC_IAL ==> 0x%x\n", in_be32(&emacp->em0ialr)); + printk(KERN_DEBUG "EMAC_VLAN_TPID_REG ==> 0x%x\n", in_be32(&emacp->em0vtpid)); +} + +void +emac_mal_dump(struct net_device *dev) +{ + struct ibm_ocp_mal* mal = ((struct ocp_enet_private*)dev->priv)->mal; + + printk(KERN_DEBUG " MAL DEBUG ********** \n"); + printk(KERN_DEBUG " MCR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALCR)); + printk(KERN_DEBUG " ESR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALESR)); + printk(KERN_DEBUG " IER ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALIER)); +#ifdef CONFIG_40x + printk(KERN_DEBUG " DBR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALDBR)); +#endif /* CONFIG_40x */ + printk(KERN_DEBUG " TXCASR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCASR)); + printk(KERN_DEBUG " TXCARR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCARR)); + printk(KERN_DEBUG " TXEOBISR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXEOBISR)); + printk(KERN_DEBUG " TXDEIR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXDEIR)); + printk(KERN_DEBUG " RXCASR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCASR)); + printk(KERN_DEBUG " RXCARR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCARR)); + printk(KERN_DEBUG " RXEOBISR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRXEOBISR)); + printk(KERN_DEBUG " RXDEIR ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRXDEIR)); + printk(KERN_DEBUG " TXCTP0R ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP0R)); + printk(KERN_DEBUG " TXCTP1R ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP1R)); + printk(KERN_DEBUG " TXCTP2R ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP2R)); + printk(KERN_DEBUG " TXCTP3R ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP3R)); + printk(KERN_DEBUG " RXCTP0R ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCTP0R)); + printk(KERN_DEBUG " RXCTP1R ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCTP1R)); + printk(KERN_DEBUG " RCBS0 ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRCBS0)); + printk(KERN_DEBUG " RCBS1 ==> 0x%x\n", + (unsigned int) get_mal_dcrn(mal, DCRN_MALRCBS1)); +} + +void +emac_serr_dump_0(struct net_device *dev) +{ + struct ibm_ocp_mal* mal = ((struct ocp_enet_private*)dev->priv)->mal; + unsigned long int mal_error, plb_error, plb_addr; + + mal_error = get_mal_dcrn(mal, DCRN_MALESR); + printk(KERN_DEBUG "ppc405_eth_serr: %s channel %ld \n", + (mal_error & 0x40000000) ? "Receive" : + "Transmit", (mal_error & 0x3e000000) >> 25); + printk(KERN_DEBUG " ----- latched error -----\n"); + if (mal_error & MALESR_DE) + printk(KERN_DEBUG " DE: descriptor error\n"); + if (mal_error & MALESR_OEN) + printk(KERN_DEBUG + " ONE: OPB non-fullword error\n"); + if (mal_error & MALESR_OTE) + printk(KERN_DEBUG " OTE: OPB timeout error\n"); + if (mal_error & MALESR_OSE) + printk(KERN_DEBUG " OSE: OPB slave error\n"); + + if (mal_error & MALESR_PEIN) { + plb_error = mfdcr(DCRN_PLB0_BESR); + printk(KERN_DEBUG + " PEIN: PLB error, PLB0_BESR is 0x%x\n", + (unsigned int) plb_error); + plb_addr = mfdcr(DCRN_PLB0_BEAR); + printk(KERN_DEBUG + " PEIN: PLB error, PLB0_BEAR is 0x%x\n", + (unsigned int) plb_addr); + } +} + +void +emac_serr_dump_1(struct net_device *dev) +{ + struct ibm_ocp_mal* mal = ((struct ocp_enet_private*)dev->priv)->mal; + int mal_error = get_mal_dcrn(mal, DCRN_MALESR); + + printk(KERN_DEBUG " ----- cumulative errors -----\n"); + if (mal_error & MALESR_DEI) + printk(KERN_DEBUG + " DEI: descriptor error interrupt\n"); + if (mal_error & MALESR_ONEI) + printk(KERN_DEBUG + " OPB non-fullword error interrupt\n"); + if (mal_error & MALESR_OTEI) + printk(KERN_DEBUG + " OTEI: timeout error interrupt\n"); + if (mal_error & MALESR_OSEI) + printk(KERN_DEBUG + " OSEI: slave error interrupt\n"); + if (mal_error & MALESR_PBEI) + printk(KERN_DEBUG + " PBEI: PLB bus error interrupt\n"); +} + +void +emac_err_dump(struct net_device *dev, int em0isr) +{ + printk(KERN_DEBUG "%s: on-chip ethernet error:\n", dev->name); + + if (em0isr & EMAC_ISR_OVR) + printk(KERN_DEBUG " OVR: overrun\n"); + if (em0isr & EMAC_ISR_PP) + printk(KERN_DEBUG " PP: control pause packet\n"); + if (em0isr & EMAC_ISR_BP) + printk(KERN_DEBUG " BP: packet error\n"); + if (em0isr & EMAC_ISR_RP) + printk(KERN_DEBUG " RP: runt packet\n"); + if (em0isr & EMAC_ISR_SE) + printk(KERN_DEBUG " SE: short event\n"); + if (em0isr & EMAC_ISR_ALE) + printk(KERN_DEBUG + " ALE: odd number of nibbles in packet\n"); + if (em0isr & EMAC_ISR_BFCS) + printk(KERN_DEBUG " BFCS: bad FCS\n"); + if (em0isr & EMAC_ISR_PTLE) + printk(KERN_DEBUG " PTLE: oversized packet\n"); + if (em0isr & EMAC_ISR_ORE) + printk(KERN_DEBUG + " ORE: packet length field > max allowed LLC\n"); + if (em0isr & EMAC_ISR_IRE) + printk(KERN_DEBUG " IRE: In Range error\n"); + if (em0isr & EMAC_ISR_DBDM) + printk(KERN_DEBUG " DBDM: xmit error or SQE\n"); + if (em0isr & EMAC_ISR_DB0) + printk(KERN_DEBUG + " DB0: xmit error or SQE on TX channel 0\n"); + if (em0isr & EMAC_ISR_SE0) + printk(KERN_DEBUG + " SE0: Signal Quality Error test failure from TX channel 0\n"); + if (em0isr & EMAC_ISR_TE0) + printk(KERN_DEBUG " TE0: xmit channel 0 aborted\n"); + if (em0isr & EMAC_ISR_DB1) + printk(KERN_DEBUG + " DB1: xmit error or SQE on TX channel \n"); + if (em0isr & EMAC_ISR_SE1) + printk(KERN_DEBUG + " SE1: Signal Quality Error test failure from TX channel 1\n"); + if (em0isr & EMAC_ISR_TE1) + printk(KERN_DEBUG " TE1: xmit channel 1 aborted\n"); + if (em0isr & EMAC_ISR_MOS) + printk(KERN_DEBUG " MOS\n"); + if (em0isr & EMAC_ISR_MOF) + printk(KERN_DEBUG " MOF\n"); + + emac_mac_dump(dev); + emac_mal_dump(dev); +} diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_enet.c linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_enet.c --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_enet.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_enet.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1458 @@ +/* + * ibm_ocp_enet.c + * + * Ethernet driver for the built in ethernet on the IBM 4xx PowerPC + * processors. + * + * (c) 2003 Benjamin Herrenschmidt + * + * Based on original work by + * + * Armin Kuster + * Johnnie Peters + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + * TODO + * - Check for races in the "remove" code path + * - Add some Power Management to the MAC and the PHY + * - Audit remaining of non-rewritten code (--BenH) + * - Cleanup message display using msglevel mecanism + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ibm_ocp_enet.h" + +//#define MDIO_DEBUG(fmt) printk fmt +#define MDIO_DEBUG(fmt) + +//#define LINK_DEBUG(fmt) printk fmt +#define LINK_DEBUG(fmt) + +//#define PKT_DEBUG(fmt) printk fmt +#define PKT_DEBUG(fmt) + +#define DRV_NAME "emac" +#define DRV_VERSION "2.0" +#define DRV_AUTHOR "Benjamin Herrenschmidt " +#define DRV_DESC "IBM OCP EMAC Ethernet driver" + +MODULE_AUTHOR(DRV_AUTHOR); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_LICENSE("GPL"); + +static int skb_res = SKB_RES; +MODULE_PARM(skb_res, "i"); +MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n" + "The 405 handles a misaligned IP header fine but\n" + "this can help if you are routing to a tunnel or a\n" + "device that needs aligned data. 0..2"); + +#define ZMII_PRIV(ocpdev) ((struct ibm_ocp_zmii*)ocp_get_drvdata(ocpdev)) + +static unsigned int zmii_enable[][4] = { + {ZMII_SMII0, ZMII_RMII0, ZMII_MII0, + ~(ZMII_MDI1 | ZMII_MDI2 | ZMII_MDI3)}, + {ZMII_SMII1, ZMII_RMII1, ZMII_MII1, + ~(ZMII_MDI0 | ZMII_MDI2 | ZMII_MDI3)}, + {ZMII_SMII2, ZMII_RMII2, ZMII_MII2, + ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)}, + {ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)} +}; +static unsigned int mdi_enable[] = + { ZMII_MDI0, ZMII_MDI1, ZMII_MDI2, ZMII_MDI3 }; + +static unsigned int zmii_speed = 0x0; +static unsigned int zmii_speed100[] = { ZMII_MII0_100MB, ZMII_MII1_100MB }; + +/* Since multiple EMACs share MDIO lines in various ways, we need + * to avoid re-using the same PHY ID in cases where the arch didn't + * setup precise emac_phy_map entries + */ +static u32 busy_phy_map = 0; + +static struct net_device_stats * +emac_stats(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + return &fep->stats; +} + +static int +emac_init_zmii(struct ocp_device *ocpdev, int mode) +{ + struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev); + struct zmii_regs *zmiip; + const char *mode_name[] = { "SMII", "RMII", "MII" }; + + if (zmii){ + /* We have already initialized ZMII device, + so just increment refcount and return */ + zmii->users++; + return 0; + } + + zmii = kmalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL); + if (zmii == NULL) { + printk(KERN_ERR "zmii%d: Out of memory allocating ZMII structure!\n", + ocpdev->def->index); + return -ENOMEM; + } + memset(zmii, 0, sizeof(*zmii)); + + zmiip = (struct zmii_regs *)ioremap(ocpdev->def->paddr, sizeof(*zmiip)); + if (zmiip == NULL){ + printk(KERN_ERR "zmii%d: Cannot ioremap bridge registers!\n", + ocpdev->def->index); + + kfree(zmii); + return -ENOMEM; + } + + if (mode == ZMII_AUTO) { + if (zmiip->fer & (ZMII_MII0 | ZMII_MII1 | + ZMII_MII2 | ZMII_MII3)) + mode = MII; + if (zmiip->fer & (ZMII_RMII0 | ZMII_RMII1 | + ZMII_RMII2 | ZMII_RMII3)) + mode = RMII; + if (zmiip->fer & (ZMII_SMII0 | ZMII_SMII1 | + ZMII_SMII2 | ZMII_SMII3)) + mode = SMII; + + /* Failsafe: ZMII_AUTO is invalid index into the arrays, + so force SMII if all else fails. */ + + if (mode == ZMII_AUTO) + mode = SMII; + } + + zmii->base = zmiip; + zmii->mode = mode; + zmii->users++; + ocp_set_drvdata(ocpdev, zmii); + + printk(KERN_NOTICE "zmii%d: bridge in %s mode\n", ocpdev->def->index, + mode_name[mode]); + return 0; +} + +static void +emac_enable_zmii_port(struct ocp_device *ocpdev, int input) +{ + u32 mask; + struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev); + + mask = in_be32(&zmii->base->fer); + mask &= zmii_enable[input][MDI]; /* turn all non enabled MDI's off */ + mask |= zmii_enable[input][zmii->mode] | mdi_enable[input]; + out_be32(&zmii->base->fer, mask); +} + +static void +emac_zmii_port_speed(struct ocp_device *ocpdev, int input, int speed) +{ + struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev); + + if (speed == 100) + zmii_speed |= zmii_speed100[input]; + else + zmii_speed &= ~zmii_speed100[input]; + + out_be32(&zmii->base->ssr, zmii_speed); +} + +static void +emac_fini_zmii(struct ocp_device *ocpdev) +{ + struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev); + BUG_ON(!zmii || zmii->users == 0); + + if (!--zmii->users){ + ocp_set_drvdata(ocpdev, NULL); + iounmap((void*)zmii->base); + kfree(zmii); + } +} + +int +emac_phy_read(struct net_device *dev, int mii_id, int reg) +{ + register int i; + uint32_t stacr; + struct ocp_enet_private *fep = dev->priv; + volatile emac_t *emacp = fep->emacp; + + MDIO_DEBUG(("%s: phy_read, id: 0x%x, reg: 0x%x\n", dev->name, mii_id, reg)); + + /* Enable proper ZMII port */ + if (fep->zmii_dev) + emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input); + /* Use the EMAC that has the MDIO port */ + if (fep->mdio_dev) { + dev = fep->mdio_dev; + fep = dev->priv; + } + + /* Wait for data transfer complete bit */ + for (i = 0; i < OCP_RESET_DELAY; ++i) { + if (emacp->em0stacr & EMAC_STACR_OC) + break; + udelay(MDIO_DELAY); /* changed to 2 with new scheme -armin */ + } + if ((emacp->em0stacr & EMAC_STACR_OC) == 0) { + printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name); + return -1; + } + + /* Clear the speed bits and make a read request to the PHY */ + stacr = ((EMAC_STACR_READ | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ); + stacr |= ((mii_id & 0x1F) << 5); + + out_be32(&emacp->em0stacr, stacr); + stacr = in_be32(&emacp->em0stacr); + /* Wait for data transfer complete bit */ + for (i = 0; i < OCP_RESET_DELAY; ++i) { + if ((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) + break; + udelay(MDIO_DELAY); + } + if ((stacr & EMAC_STACR_OC) == 0) { + printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name); + return -1; + } + + /* Check for a read error */ + if (stacr & EMAC_STACR_PHYE) { + MDIO_DEBUG(("OCP MDIO PHY error !\n")); + return -1; + } + + MDIO_DEBUG((" -> 0x%x\n", stacr >> 16)); + + return (stacr >> 16); +} + + +void +emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) +{ + register int i = 0; + uint32_t stacr; + struct ocp_enet_private *fep = dev->priv; + volatile emac_t *emacp = fep->emacp; + + MDIO_DEBUG(("%s phy_write, id: 0x%x, reg: 0x%x, data: 0x%x\n", + dev->name, mii_id, reg, data)); + + /* Enable proper ZMII port */ + if (fep->zmii_dev) + emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input); + /* Use the EMAC that has the MDIO port */ + if (fep->mdio_dev) { + dev = fep->mdio_dev; + fep = dev->priv; + } + + /* Wait for data transfer complete bit */ + for (i = 0; i < OCP_RESET_DELAY; ++i) { + if (emacp->em0stacr & EMAC_STACR_OC) + break; + udelay(MDIO_DELAY); /* changed to 2 with new scheme -armin */ + } + if ((emacp->em0stacr & EMAC_STACR_OC) == 0) { + printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); + return; + } + + /* Clear the speed bits and make a read request to the PHY */ + + stacr = ((EMAC_STACR_WRITE | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ); + stacr |= ((mii_id & 0x1f) << 5) | ((data & 0xffff) << 16); + + out_be32(&emacp->em0stacr, stacr); + + /* Wait for data transfer complete bit */ + for (i = 0; i < OCP_RESET_DELAY; ++i) { + if ((stacr = emacp->em0stacr) & EMAC_STACR_OC) + break; + udelay(MDIO_DELAY); + } + if ((emacp->em0stacr & EMAC_STACR_OC) == 0) + printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); + + /* Check for a write error */ + if ((stacr & EMAC_STACR_PHYE) != 0) { + MDIO_DEBUG(("OCP MDIO PHY error !\n")); + } +} + +static void +emac_wakeup_irq(int irq, void *param, struct pt_regs *regs) +{ + struct net_device *dev = param; + + /* On Linux the 405 ethernet will always be active if configured + * in. This interrupt should never occur. + */ + printk(KERN_INFO "%s: WakeUp interrupt !\n", dev->name); +} + +static void +emac_txeob_dev(void *param, u32 chanmask) +{ + struct net_device *dev = param; + struct ocp_enet_private *fep = dev->priv; + unsigned long flags; + + spin_lock_irqsave(&fep->lock, flags); + + PKT_DEBUG(("emac_txeob_dev() entry, tx_cnt: %d\n", fep->tx_cnt)); + + while (fep->tx_cnt && + !(fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_READY)) { + + /* Tell the system the transmit completed. */ + dev_kfree_skb_irq(fep->tx_skb[fep->ack_slot]); + + if (fep->tx_desc[fep->ack_slot].ctrl & + (EMAC_TX_ST_EC | EMAC_TX_ST_MC | EMAC_TX_ST_SC)) + fep->stats.collisions++; + + fep->tx_skb[fep->ack_slot] = (struct sk_buff *) NULL; + if (++fep->ack_slot == NUM_TX_BUFF) + fep->ack_slot = 0; + + fep->tx_cnt--; + } + if (fep->tx_cnt < NUM_TX_BUFF) + netif_wake_queue(dev); + + PKT_DEBUG(("emac_txeob_dev() exit, tx_cnt: %d\n", fep->tx_cnt)); + + spin_unlock_irqrestore(&fep->lock, flags); +} + +/* + Fill/Re-fill the rx chain with valid ctrl/ptrs. + This function will fill from rx_slot up to the parm end. + So to completely fill the chain pre-set rx_slot to 0 and + pass in an end of 0. + */ +static void +emac_rx_fill(struct net_device *dev, int end) +{ + int i; + struct ocp_enet_private *fep = dev->priv; + unsigned char *ptr; + + i = fep->rx_slot; + do { + if (fep->rx_skb[i] != NULL) { + /*We will trust the skb is still in a good state */ + ptr = (char *) virt_to_phys(fep->rx_skb[i]->data); + } else { + + /* We don't want the 16 bytes skb_reserve done by dev_alloc_skb, + * it breaks our cache line alignement. However, we still allocate + * +16 so that we end up allocating the exact same size as + * dev_alloc_skb() would do. + * Also, because of the skb_res, the max DMA size we give to EMAC + * is slighly wrong, causing it to potentially DMA 2 more bytes + * from a broken/oversized packet. These 16 bytes will take care + * that we don't walk on somebody else toes with that. + */ + fep->rx_skb[i] = + alloc_skb(DESC_RX_BUF_SIZE + 16, GFP_ATOMIC); + + if (fep->rx_skb[i] == NULL) { + /* Keep rx_slot here, the next time clean/fill is called + * we will try again before the MAL wraps back here + * If the MAL tries to use this descriptor with + * the EMPTY bit off it will cause the + * rxde interrupt. That is where we will + * try again to allocate an sk_buff. + */ + break; + + } + + if (skb_res) + skb_reserve(fep->rx_skb[i], skb_res); + + /* We must NOT consistent_sync the cache line right after the + * buffer, so we must crop our sync size to account for the + * reserved space + */ + consistent_sync((void *) fep->rx_skb[i]-> + data, (DESC_RX_BUF_SIZE-skb_res), + PCI_DMA_FROMDEVICE); + ptr = (char *) virt_to_phys(fep->rx_skb[i]->data); + } + fep->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR | /*could be smarter about this to avoid ints at high loads */ + (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0); + + fep->rx_desc[i].data_ptr = ptr; + /* + * 440GP uses the previously reserved bits in the + * data_len to encode the upper 4-bits of the buffer + * physical address (ERPN). Initialize these. + */ + fep->rx_desc[i].data_len = 0; + } while ((i = (i + 1) % NUM_RX_BUFF) != end); + + fep->rx_slot = i; +} + +static void +emac_rx_clean(struct net_device *dev, int call_rx_fill) +{ + int i; + int error, frame_length; + struct ocp_enet_private *fep = dev->priv; + unsigned short ctrl; + int slots_walked = 0; + + i = fep->rx_slot; + + PKT_DEBUG(("emac_rx_clean() entry, call_rx_fill: %d, rx_slot: %d\n", call_rx_fill, fep->rx_slot)); + + do { + if (fep->rx_skb[i] == NULL) + goto skip; /*we have already handled the packet but haved failed to alloc */ + /* + since rx_desc is in uncached mem we don't keep reading it directly + we pull out a local copy of ctrl and do the checks on the copy. + */ + ctrl = fep->rx_desc[i].ctrl; + if (ctrl & MAL_RX_CTRL_EMPTY) + break; /*we don't have any more ready packets */ + + if (ctrl & EMAC_BAD_RX_PACKET) { + + fep->stats.rx_errors++; + fep->stats.rx_dropped++; + + if (ctrl & EMAC_RX_ST_OE) + fep->stats.rx_fifo_errors++; + if (ctrl & EMAC_RX_ST_AE) + fep->stats.rx_frame_errors++; + if (ctrl & EMAC_RX_ST_BFCS) + fep->stats.rx_crc_errors++; + if (ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL | + EMAC_RX_ST_ORE | EMAC_RX_ST_IRE)) + fep->stats.rx_length_errors++; + } else { + + /* Send the skb up the chain. */ + frame_length = fep->rx_desc[i].data_len - 4; + + skb_put(fep->rx_skb[i], frame_length); + fep->rx_skb[i]->dev = dev; + fep->rx_skb[i]->protocol = + eth_type_trans(fep->rx_skb[i], dev); + + error = netif_rx(fep->rx_skb[i]); + if ((error == NET_RX_DROP) || (error == NET_RX_BAD)) { + fep->stats.rx_dropped++; + } else { + fep->stats.rx_packets++; + fep->stats.rx_bytes += frame_length; + } + fep->rx_skb[i] = NULL; + } + skip: + slots_walked = 1; + + } while ((i = (i + 1) % NUM_RX_BUFF) != fep->rx_slot); + + PKT_DEBUG(("emac_rx_clean() exit, rx_slot: %d\n", fep->rx_slot)); + + if (slots_walked && call_rx_fill) + emac_rx_fill(dev, i); +} + +static void +emac_rxeob_dev(void *param, u32 chanmask) +{ + struct net_device *dev = param; + struct ocp_enet_private *fep = dev->priv; + unsigned long flags; + + spin_lock_irqsave(&fep->lock, flags); + emac_rx_clean(dev, 1); + spin_unlock_irqrestore(&fep->lock, flags); +} + +/* + * This interrupt should never occurr, we don't program + * the MAL for contiunous mode. + */ +static void +emac_txde_dev(void *param, u32 chanmask) +{ + struct net_device *dev = param; + struct ocp_enet_private *fep = dev->priv; + + printk(KERN_WARNING "%s: transmit descriptor error\n", dev->name); + + emac_mac_dump(dev); + emac_mal_dump(dev); + + /* Reenable the transmit channel */ + mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask); +} + +/* + * This interrupt should be very rare at best. This occurs when + * the hardware has a problem with the receive descriptors. The manual + * states that it occurs when the hardware cannot the receive descriptor + * empty bit is not set. The recovery mechanism will be to + * traverse through the descriptors, handle any that are marked to be + * handled and reinitialize each along the way. At that point the driver + * will be restarted. + */ +static void +emac_rxde_dev(void *param, u32 chanmask) +{ + struct net_device *dev = param; + struct ocp_enet_private *fep = dev->priv; + unsigned long flags; + + printk(KERN_WARNING "%s: receive descriptor error\n", fep->ndev->name); + + emac_mac_dump(dev); + emac_mal_dump(dev); + emac_desc_dump(dev); + + /* Disable RX channel */ + spin_lock_irqsave(&fep->lock, flags); + mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask); + + /* For now, charge the error against all emacs */ + fep->stats.rx_errors++; + + /* so do we have any good packets still? */ + emac_rx_clean(dev,0); + + /* When the interface is restarted it resets processing to the + * first descriptor in the table. + */ + + fep->rx_slot = 0; + emac_rx_fill(dev, 0); + + set_mal_dcrn(fep->mal, DCRN_MALRXEOBISR, fep->commac.rx_chan_mask); + set_mal_dcrn(fep->mal, DCRN_MALRXDEIR, fep->commac.rx_chan_mask); + + /* Reenable the receive channels */ + mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask); + spin_unlock_irqrestore(&fep->lock, flags); +} + +static void +emac_mac_irq(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = dev_instance; + struct ocp_enet_private *fep = dev->priv; + volatile emac_t *emacp = fep->emacp; + unsigned long tmp_em0isr; + + /* EMAC interrupt */ + tmp_em0isr = in_be32(&emacp->em0isr); + if (tmp_em0isr & (EMAC_ISR_TE0 | EMAC_ISR_TE1)) { + /* This error is a hard transmit error - could retransmit */ + fep->stats.tx_errors++; + + /* Reenable the transmit channel */ + mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask); + + } else { + fep->stats.rx_errors++; + } + + if (tmp_em0isr & EMAC_ISR_RP) + fep->stats.rx_length_errors++; + if (tmp_em0isr & EMAC_ISR_ALE) + fep->stats.rx_frame_errors++; + if (tmp_em0isr & EMAC_ISR_BFCS) + fep->stats.rx_crc_errors++; + if (tmp_em0isr & EMAC_ISR_PTLE) + fep->stats.rx_length_errors++; + if (tmp_em0isr & EMAC_ISR_ORE) + fep->stats.rx_length_errors++; + if (tmp_em0isr & EMAC_ISR_TE0) + fep->stats.tx_aborted_errors++; + + emac_err_dump(dev, tmp_em0isr); + + out_be32(&emacp->em0isr, tmp_em0isr); +} + +static int +emac_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + unsigned short ctrl; + unsigned long flags; + struct ocp_enet_private *fep = dev->priv; + volatile emac_t *emacp = fep->emacp; + + spin_lock_irqsave(&fep->lock, flags); + + PKT_DEBUG(("emac_start_xmit() entry, queue stopped: %d, fep->tx_cnt: %d\n", + netif_queue_stopped(dev), fep->tx_cnt)); + + /* That shouldn't happen... */ + if (netif_queue_stopped(dev) || (fep->tx_cnt == NUM_TX_BUFF)) { + printk("%s: start_xmit called on full queue !\n", dev->name); + BUG(); + } + + if (++fep->tx_cnt == NUM_TX_BUFF) { + PKT_DEBUG(("emac_start_xmit() stopping queue\n")); + netif_stop_queue(dev); + } + + /* Store the skb buffer for later ack by the transmit end of buffer + * interrupt. + */ + fep->tx_skb[fep->tx_slot] = skb; + consistent_sync((void *) skb->data, skb->len, PCI_DMA_TODEVICE); + + ctrl = EMAC_TX_CTRL_DFLT; + if ((NUM_TX_BUFF - 1) == fep->tx_slot) + ctrl |= MAL_TX_CTRL_WRAP; + fep->tx_desc[fep->tx_slot].data_ptr = (char *) virt_to_phys(skb->data); + fep->tx_desc[fep->tx_slot].data_len = (short) skb->len; + fep->tx_desc[fep->tx_slot].ctrl = ctrl; + + /* Send the packet out. */ + out_be32(&emacp->em0tmr0, EMAC_TXM0_GNP0); + + if (++fep->tx_slot == NUM_TX_BUFF) + fep->tx_slot = 0; + + fep->stats.tx_packets++; + fep->stats.tx_bytes += skb->len; + + PKT_DEBUG(("emac_start_xmit() exitn")); + + spin_unlock_irqrestore(&fep->lock, flags); + + return 0; +} + +static int +emac_adjust_to_link(struct ocp_enet_private *fep) +{ + volatile emac_t *emacp = fep->emacp; + unsigned long mode_reg; + int full_duplex, speed; + + full_duplex = 0; + speed = SPEED_10; + + /* set receive fifo to 4k and tx fifo to 2k */ + mode_reg = EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K | EMAC_M1_APP | + EMAC_M1_TR0_MULTI; + + /* Read link mode on PHY */ + if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) { + /* If an error occurred, we don't deal with it yet */ + full_duplex = (fep->phy_mii.duplex == DUPLEX_FULL); + speed = fep->phy_mii.speed; + } + + /* set speed (default is 10Mb) */ + if (speed == SPEED_100) { + mode_reg |= EMAC_M1_MF_100MBPS; + if (fep->zmii_dev) + emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input, 100); + } else { + mode_reg &= ~EMAC_M1_MF_100MBPS; + if (fep->zmii_dev) + emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input, 10); + } + + if (full_duplex) + mode_reg |= EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_IST; + else + mode_reg &= ~(EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_ILE); + + LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n", + fep->ndev->name, speed, full_duplex, fep->opened)); + + printk(KERN_INFO "%s: Speed: %s, %s duplex.\n", + fep->ndev->name, + speed == SPEED_100 ? "100" : "10", + full_duplex ? "Full" : "Half"); + if (fep->opened) + out_be32(&emacp->em0mr1, mode_reg); + + return 0; +} + +static void +__emac_set_multicast_list(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + volatile emac_t *emacp = fep->emacp; + + if (dev->flags & IFF_PROMISC) { + + /* If promiscuous mode is set then we do not need anything else */ + out_be32(&emacp->em0rmr, EMAC_RMR_PME); + + } else if (dev->flags & IFF_ALLMULTI || 32 < dev->mc_count) { + + /* Must be setting up to use multicast. Now check for promiscuous + * multicast + */ + out_be32(&emacp->em0rmr, + EMAC_RMR_IAE | EMAC_RMR_BAE | EMAC_RMR_PMME); + } else if (dev->flags & IFF_MULTICAST && 0 < dev->mc_count) { + + unsigned short em0gaht[4] = { 0, 0, 0, 0 }; + struct dev_mc_list *dmi; + + /* Need to hash on the multicast address. */ + for (dmi = dev->mc_list; dmi; dmi = dmi->next) { + unsigned long mc_crc; + unsigned int bit_number; + + mc_crc = ether_crc(6, (char *) dmi->dmi_addr); + bit_number = 63 - (mc_crc >> 26); /* MSB: 0 LSB: 63 */ + em0gaht[bit_number >> 4] |= + 0x8000 >> (bit_number & 0x0f); + } + emacp->em0gaht1 = em0gaht[0]; + emacp->em0gaht2 = em0gaht[1]; + emacp->em0gaht3 = em0gaht[2]; + emacp->em0gaht4 = em0gaht[3]; + + /* Turn on multicast addressing */ + out_be32(&emacp->em0rmr, + EMAC_RMR_IAE | EMAC_RMR_BAE | EMAC_RMR_MAE); + + } else { + /* If multicast mode is not set then we are + * turning it off at this point + */ + out_be32(&emacp->em0rmr, EMAC_RMR_IAE | EMAC_RMR_BAE); + + } +} + +static void +emac_init_rings(struct net_device *dev) +{ + struct ocp_enet_private *ep = dev->priv; + int loop; + + ep->tx_desc = (struct mal_descriptor *) ((char *) ep->mal->tx_virt_addr + + (ep->mal_tx_chan * MAL_DT_ALIGN)); + ep->rx_desc = (struct mal_descriptor *) ((char *) ep->mal->rx_virt_addr + + (ep->mal_rx_chan * MAL_DT_ALIGN)); + + /* Fill in the transmit descriptor ring. */ + for (loop = 0; loop < NUM_TX_BUFF; loop++) { + if (ep->tx_skb[loop]) + dev_kfree_skb_irq(ep->tx_skb[loop]); + ep->tx_skb[loop] = NULL; + ep->tx_desc[loop].ctrl = 0; + ep->tx_desc[loop].data_len = 0; + ep->tx_desc[loop].data_ptr = NULL; + } + ep->tx_desc[loop - 1].ctrl |= MAL_TX_CTRL_WRAP; + + /* Format the receive descriptor ring. */ + ep->rx_slot = 0; + emac_rx_fill(dev, 0); + if (ep->rx_slot != 0) { + printk(KERN_ERR + "%s: Not enough mem for RxChain durning Open?\n", + dev->name); + /*We couldn't fill the ring at startup? + *We could clean up and fail to open but right now we will try to + *carry on. It may be a sign of a bad NUM_RX_BUFF value + */ + } + + ep->tx_cnt = 0; + ep->tx_slot = 0; + ep->ack_slot = 0; +} + +static void +emac_reset_configure(struct ocp_enet_private *fep) +{ + volatile emac_t *emacp = fep->emacp; + int i; + + mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask); + mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask); + + /* Reset the EMAC */ + out_be32(&emacp->em0mr0, EMAC_M0_SRST); + udelay(20); + for (i=0; i<100; i++) { + if ((in_be32(&emacp->em0mr0) & EMAC_M0_SRST) == 0) + break; + udelay(10); + } + + if (i >= 100) { + printk(KERN_ERR "%s: Cannot reset EMAC\n", fep->ndev->name); + return; + } + + /* Switch IRQs off for now */ + out_be32(&emacp->em0iser, 0); + + /* Configure MAL rx channel */ + mal_set_rcbs(fep->mal, fep->mal_rx_chan, DESC_BUF_SIZE_REG); + + /* set the high address */ + out_be32(&emacp->em0iahr, (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]); + + /* set the low address */ + out_be32(&emacp->em0ialr, + (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16) + | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]); + + /* Adjust to link */ + if (netif_carrier_ok(fep->ndev)) + emac_adjust_to_link(fep); + + /* enable broadcast and individual address */ + out_be32(&emacp->em0rmr, EMAC_RMR_IAE | EMAC_RMR_BAE); + + + /* Reconfigure multicast */ + __emac_set_multicast_list(fep->ndev); + + /* set transmit request threshold register */ + out_be32(&emacp->em0trtr, EMAC_TRTR_256); + + + /* set receive low/high water mark register */ +#ifdef CONFIG_440 + /* 440GP has a 64 byte burst length */ + out_be32(&emacp->em0rwmr, 0x80009000); + out_be32(&emacp->em0tmr1, 0xf8640000); +#else + /* 405s have a 16 byte burst length */ + out_be32(&emacp->em0rwmr, 0x0f002000); +#endif /* CONFIG_440 */ + + /* set frame gap */ + out_be32(&emacp->em0ipgvr, CONFIG_IBM_OCP_ENET_GAP); + + /* Init ring buffers */ + emac_init_rings(fep->ndev); +} + +static void +emac_kick(struct ocp_enet_private *fep) +{ + volatile emac_t *emacp = fep->emacp; + unsigned long emac_ier; + + emac_ier = EMAC_ISR_PP | EMAC_ISR_BP | EMAC_ISR_RP | + EMAC_ISR_SE | EMAC_ISR_PTLE | EMAC_ISR_ALE | + EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE; + + out_be32(&emacp->em0iser, emac_ier); + + /* enable all MAL transmit and receive channels */ + mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask); + mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask); + + /* set transmit and receive enable */ + out_be32(&emacp->em0mr0, EMAC_M0_TXE | EMAC_M0_RXE); +} + +static void +emac_start_link(struct ocp_enet_private *fep, struct ethtool_cmd *ep) +{ + u32 advertise; + int autoneg; + int forced_speed; + int forced_duplex; + + /* Default advertise */ + advertise = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + autoneg = fep->want_autoneg; + forced_speed = fep->phy_mii.speed; + forced_duplex = fep->phy_mii.duplex; + + /* Setup link parameters */ + if (ep) { + if (ep->autoneg == AUTONEG_ENABLE) { + advertise = ep->advertising; + autoneg = 1; + } else { + autoneg = 0; + forced_speed = ep->speed; + forced_duplex = ep->duplex; + } + } + + /* Configure PHY & start aneg */ + fep->want_autoneg = autoneg; + if (autoneg) { + LINK_DEBUG(("%s: start link aneg, advertise: 0x%x\n", + fep->ndev->name, advertise)); + fep->phy_mii.def->ops->setup_aneg(&fep->phy_mii, advertise); + } else { + LINK_DEBUG(("%s: start link forced, speed: %d, duplex: %d\n", + fep->ndev->name, forced_speed, forced_duplex)); + fep->phy_mii.def->ops->setup_forced(&fep->phy_mii, forced_speed, + forced_duplex); + } + fep->timer_ticks = 0; + mod_timer(&fep->link_timer, jiffies + HZ); +} + +static void +emac_link_timer(unsigned long data) +{ + struct ocp_enet_private *fep = (struct ocp_enet_private *)data; + int link; + + if (fep->going_away) + return; + + spin_lock_irq(&fep->lock); + + link = fep->phy_mii.def->ops->poll_link(&fep->phy_mii); + LINK_DEBUG(("%s: poll_link: %d\n", fep->ndev->name, link)); + + if (link == netif_carrier_ok(fep->ndev)) { + if (!link && fep->want_autoneg && (++fep->timer_ticks) > 10) + emac_start_link(fep, NULL); + goto out; + } + printk(KERN_INFO "%s: Link is %s\n", fep->ndev->name, link ? "Up" : "Down"); + if (link) { + netif_carrier_on(fep->ndev); + /* Chip needs a full reset on config change. That sucks, so I + * should ultimately move that to some tasklet to limit + * latency peaks caused by this code + */ + emac_reset_configure(fep); + emac_kick(fep); + } else { + fep->timer_ticks = 0; + netif_carrier_off(fep->ndev); + } +out: + mod_timer(&fep->link_timer, jiffies + HZ); + spin_unlock_irq(&fep->lock); +} + +static void +emac_set_multicast_list(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + + spin_lock_irq(&fep->lock); + __emac_set_multicast_list(dev); + spin_unlock_irq(&fep->lock); +} + +static int +emac_ethtool(struct net_device *dev, void* ep_user) +{ + struct ocp_enet_private *fep = dev->priv; + struct ethtool_cmd ecmd; + unsigned long features = fep->phy_mii.def->features; + + if (copy_from_user(&ecmd, ep_user, sizeof(ecmd))) + return -EFAULT; + + switch(ecmd.cmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info; + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GDRVINFO; + strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN); + strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN); + info.fw_version[0] = '\0'; + sprintf(info.bus_info, "OCP EMAC %d", fep->ocpdev->def->index); + info.regdump_len = 0; + if (copy_to_user(ep_user, &info, sizeof(info))) + return -EFAULT; + return 0; + } + + case ETHTOOL_GSET: + ecmd.supported = features; + ecmd.port = PORT_MII; + ecmd.transceiver = XCVR_EXTERNAL; + ecmd.phy_address = fep->mii_phy_addr; + spin_lock_irq(&fep->lock); + ecmd.autoneg = fep->want_autoneg; + ecmd.speed = fep->phy_mii.speed; + ecmd.duplex = fep->phy_mii.duplex; + spin_unlock_irq(&fep->lock); + if (copy_to_user(ep_user, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + + case ETHTOOL_SSET: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (ecmd.autoneg != AUTONEG_ENABLE && + ecmd.autoneg != AUTONEG_DISABLE) + return -EINVAL; + if (ecmd.autoneg == AUTONEG_ENABLE && + ecmd.advertising == 0) + return -EINVAL; + if (ecmd.duplex != DUPLEX_HALF && ecmd.duplex != DUPLEX_FULL) + return -EINVAL; + if (ecmd.autoneg == AUTONEG_DISABLE) + switch(ecmd.speed) { + case SPEED_10: + if (ecmd.duplex == DUPLEX_HALF && + (features & SUPPORTED_10baseT_Half) == 0) + return -EINVAL; + if (ecmd.duplex == DUPLEX_FULL && + (features & SUPPORTED_10baseT_Full) == 0) + return -EINVAL; + break; + case SPEED_100: + if (ecmd.duplex == DUPLEX_HALF && + (features & SUPPORTED_100baseT_Half) == 0) + return -EINVAL; + if (ecmd.duplex == DUPLEX_FULL && + (features & SUPPORTED_100baseT_Full) == 0) + return -EINVAL; + break; + default: + return -EINVAL; + } + else if ((features & SUPPORTED_Autoneg) == 0) + return -EINVAL; + spin_lock_irq(&fep->lock); + emac_start_link(fep, &ecmd); + spin_unlock_irq(&fep->lock); + return 0; + + case ETHTOOL_NWAY_RST: + if (!fep->want_autoneg) + return -EINVAL; + spin_lock_irq(&fep->lock); + emac_start_link(fep, NULL); + spin_unlock_irq(&fep->lock); + return 0; + + case ETHTOOL_GLINK: { + struct ethtool_value edata; + memset(&edata, 0, sizeof(edata)); + edata.cmd = ETHTOOL_GLINK; + edata.data = netif_carrier_ok(dev); + if (copy_to_user(ep_user, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + } + + return -EOPNOTSUPP; +} + +static int +emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct ocp_enet_private *fep = dev->priv; + uint *data = (uint *) & rq->ifr_data; + + switch (cmd) { + case SIOCETHTOOL: + return emac_ethtool(dev, rq->ifr_data); + case SIOCDEVPRIVATE: + case SIOCGMIIPHY: + data[0] = fep->mii_phy_addr; + /*FALLTHRU*/ + case SIOCDEVPRIVATE + 1: + case SIOCGMIIREG: + data[3] = emac_phy_read(dev, fep->mii_phy_addr, data[1]); + return 0; + case SIOCDEVPRIVATE + 2: + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + emac_phy_write(dev, fep->mii_phy_addr, data[1], data[2]); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int +emac_open(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + int rc; + + spin_lock_irq(&fep->lock); + + fep->opened = 1; + + /* Reset & configure the chip */ + emac_reset_configure(fep); + + spin_unlock_irq(&fep->lock); + + /* Request our interrupt lines */ + rc = request_irq(dev->irq, emac_mac_irq, 0, "OCP EMAC MAC", dev); + if (rc != 0) + goto bail; + rc = request_irq(fep->wol_irq, emac_wakeup_irq, 0, "OCP EMAC Wakeup", dev); + if (rc != 0) { + free_irq(dev->irq, dev); + goto bail; + } + /* Kick the chip rx & tx channels into life */ + spin_lock_irq(&fep->lock); + emac_kick(fep); + spin_unlock_irq(&fep->lock); + + netif_start_queue(dev); +bail: + return rc; +} + +static int +emac_close(struct net_device *dev) +{ + struct ocp_enet_private *fep = dev->priv; + volatile emac_t *emacp = fep->emacp; + + /* XXX Stop IRQ emitting here */ + spin_lock_irq(&fep->lock); + fep->opened = 0; + mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask); + mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask); + netif_stop_queue(dev); + + out_be32(&emacp->em0mr0, EMAC_M0_SRST); + udelay(10); + + if (emacp->em0mr0 & EMAC_M0_SRST) { + /*not sure what to do here hopefully it clears before another open */ + printk(KERN_ERR "%s: Phy SoftReset didn't clear, no link?\n", + dev->name); + } + + /* Free the irq's */ + free_irq(dev->irq, dev); + free_irq(fep->wol_irq, dev); + + spin_unlock_irq(&fep->lock); + + return 0; +} + +static void +emac_remove(struct ocp_device *ocpdev) +{ + struct net_device *dev = ocp_get_drvdata(ocpdev); + struct ocp_enet_private *ep = dev->priv; + + /* FIXME: locking, races, ... */ + ep->going_away = 1; + ocp_set_drvdata(ocpdev, NULL); + if (ep->zmii_dev) + emac_fini_zmii(ep->zmii_dev); + + unregister_netdev(dev); + del_timer_sync(&ep->link_timer); + mal_unregister_commac(ep->mal, &ep->commac); + iounmap((void *)ep->emacp); + kfree(dev); +} + +struct mal_commac_ops emac_commac_ops = { + .txeob = &emac_txeob_dev, + .txde = &emac_txde_dev, + .rxeob = &emac_rxeob_dev, + .rxde = &emac_rxde_dev, +}; + +static int +emac_probe(struct ocp_device *ocpdev) +{ + int rc = 0, i; + bd_t *bd; + struct net_device *ndev; + struct ocp_enet_private *ep; + struct ocp_device *maldev; + struct ibm_ocp_mal *mal; + struct ocp_func_emac_data *emacdata; + struct ocp_device *mdiodev; + struct net_device *mdio_ndev = NULL; + int commac_reg = 0; + u32 phy_map; + + emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions; + if (emacdata == NULL) { + printk(KERN_ERR "emac%d: Missing additional datas !\n", ocpdev->def->index); + return -ENODEV; + } + + /* Wait for MAL to show up */ + maldev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_MAL, emacdata->mal_idx); + if (maldev == NULL) + return -EAGAIN; + /* Check if MAL driver attached yet */ + mal = (struct ibm_ocp_mal *)ocp_get_drvdata(maldev); + if (mal == NULL) + return -EAGAIN; + + /* If we depend on another EMAC for MDIO, wait for it to show up */ + if (emacdata->mdio_idx >= 0 && emacdata->mdio_idx != ocpdev->def->index) { + mdiodev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_EMAC, emacdata->mdio_idx); + if (mdiodev == NULL) + return -EAGAIN; + mdio_ndev = (struct net_device *)ocp_get_drvdata(mdiodev); + if (mdio_ndev == NULL) + return -EAGAIN; + } + + /* Allocate our net_device structure */ + ndev = alloc_etherdev(sizeof (struct ocp_enet_private)); + if (ndev == NULL) { + printk(KERN_ERR + "emac%d: Could not allocate ethernet device.\n", ocpdev->def->index); + return -ENOMEM; + } + ep = ndev->priv; + memset(ep, 0, sizeof(*ep)); + ep->ndev = ndev; + ep->ocpdev = ocpdev; + ndev->irq = ocpdev->def->irq; + ep->wol_irq = emacdata->wol_irq; + ep->mdio_dev = mdio_ndev; + ocp_set_drvdata(ocpdev, ndev); + spin_lock_init(&ep->lock); + + /* Fill out MAL informations and register commac */ + ep->mal = mal; + ep->mal_tx_chan = emacdata->mal_tx1_chan; + ep->mal_rx_chan = emacdata->mal_rx_chan; + ep->commac.ops = &emac_commac_ops; + ep->commac.dev = ndev; + ep->commac.tx_chan_mask = MAL_CHAN_MASK(ep->mal_tx_chan); + ep->commac.rx_chan_mask = MAL_CHAN_MASK(ep->mal_rx_chan); + rc = mal_register_commac(ep->mal, &ep->commac); + if (rc != 0) + goto bail; + commac_reg = 1; + + /* Map our MMIOs */ + ep->emacp = (volatile emac_t *)ioremap(ocpdev->def->paddr, sizeof (emac_t)); + + /* Check if we need to attach to a ZMII */ + if (emacdata->zmii_idx >= 0) { + ep->zmii_input = emacdata->zmii_mux; + ep->zmii_dev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_ZMII, emacdata->zmii_idx); + if (ep->zmii_dev == NULL) + printk(KERN_WARNING "emac%d: ZMII %d requested but not found !\n", + ocpdev->def->index, emacdata->zmii_idx); + else if ((rc = emac_init_zmii(ep->zmii_dev, ZMII_AUTO)) != 0) + goto bail; + } + + /* Reset the EMAC */ + out_be32(&ep->emacp->em0mr0, EMAC_M0_SRST); + udelay(20); + for (i=0; i<100; i++) { + if ((in_be32(&ep->emacp->em0mr0) & EMAC_M0_SRST) == 0) + break; + udelay(10); + } + + if (i >= 100) { + printk(KERN_ERR "emac%d: Cannot reset EMAC\n", ocpdev->def->index); + rc = -ENXIO; + goto bail; + } + + /* Init link monitoring timer */ + init_timer(&ep->link_timer); + ep->link_timer.function = emac_link_timer; + ep->link_timer.data = (unsigned long) ep; + ep->timer_ticks = 0; + + /* Fill up the mii_phy structure */ + ep->phy_mii.dev = ndev; + ep->phy_mii.mdio_read = emac_phy_read; + ep->phy_mii.mdio_write = emac_phy_write; + + /* Find PHY */ + phy_map = emac_phy_map[ocpdev->def->index] | busy_phy_map; + for (i = 0; i <= 0x1f; i++, phy_map >>= 1) { + if ((phy_map & 0x1) == 0) { + int val = emac_phy_read(ndev, i, MII_BMCR); + if (val != 0xffff && val != -1) + break; + } + } + if (i == 0x20) { + printk(KERN_WARNING "emac%d: Can't find PHY.\n", ocpdev->def->index); + rc = -ENODEV; + goto bail; + } + busy_phy_map |= 1 << i; + ep->mii_phy_addr = i; + rc = mii_phy_probe(&ep->phy_mii, i); + if (rc) { + printk(KERN_WARNING "emac%d: Failed to probe PHY type.\n", ocpdev->def->index); + rc = -ENODEV; + goto bail; + } + + /* Setup initial PHY config & startup aneg */ + if (ep->phy_mii.def->ops->init) + ep->phy_mii.def->ops->init(&ep->phy_mii); + netif_carrier_off(ndev); + if (ep->phy_mii.def->features & SUPPORTED_Autoneg) + ep->want_autoneg = 1; + emac_start_link(ep, NULL); + + + /* read the MAC Address */ + bd = (bd_t *) __res; + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = bd->BD_EMAC_ADDR(ocpdev->def->index, i); /* Marco to disques array */ + + /* Fill in the driver function table */ + ndev->open = &emac_open; + ndev->hard_start_xmit = &emac_start_xmit; + ndev->stop = &emac_close; + ndev->get_stats = &emac_stats; + ndev->set_multicast_list = &emac_set_multicast_list; + ndev->do_ioctl = &emac_ioctl; + + SET_MODULE_OWNER(ndev); + + rc = register_netdev(ndev); + if (rc != 0) + goto bail; + + printk("%s: IBM emac, MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + ndev->name, + ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], + ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); + printk(KERN_INFO "%s: Found %s PHY (0x%02x)\n", + ndev->name, ep->phy_mii.def->name, ep->mii_phy_addr); + + +bail: + if (rc && commac_reg) + mal_unregister_commac(ep->mal, &ep->commac); + if (rc && ndev) + kfree(ndev); + + return rc; + +} + +/* Structure for a device driver */ +static struct ocp_device_id emac_ids[] = +{ + { .vendor = OCP_ANY_ID, .function = OCP_FUNC_EMAC }, + { .vendor = OCP_VENDOR_INVALID } +}; + +static struct ocp_driver emac_driver = +{ + .name = "emac", + .id_table = emac_ids, + + .probe = emac_probe, + .remove = emac_remove, +}; + +static int __init +emac_init(void) +{ + int rc; + + printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n"); + printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n"); + + if (skb_res > 2) { + printk(KERN_WARNING "Invalid skb_res: %d, cropping to 2\n", skb_res); + skb_res = 2; + } + rc = ocp_register_driver(&emac_driver); + if (rc == 0) { + ocp_unregister_driver(&emac_driver); + return -ENODEV; + } + + return 0; +} + + + +static void __exit +emac_exit(void) +{ + ocp_unregister_driver(&emac_driver); +} + +module_init(emac_init); +module_exit(emac_exit); diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_enet.h linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_enet.h --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_enet.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_enet.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,160 @@ +/* + * ibm_ocp_enet.h + * + * Ethernet driver for the built in ethernet on the IBM 405 PowerPC + * processor. + * + * Armin Kuster akuster@mvista.com + * Sept, 2001 + * + * Orignial driver + * Johnnie Peters + * jpeters@mvista.com + * + * Copyright 2000 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + * Version: 1.0: Name change - armin + * Version: 1.0: Added extern prototypes for new mal func. - David M. + * : removed #ifdef for irqs.i - Armin + * : added irq_resourse to private data struct. + * + * Version: 1.1: Added new min/max value for phy & removed unused phy_id_done - * - andrew May + * Version: 1.2: added all emac extern protos here - Armin + * + * Version: 1.3: Using CONFIG_IBM_OCP_ZMII instead of ZMII_NUMS > 0 + * + * Version: 1.3: Name change *_driver to *_dev + * Version: 1.4: removed irq_resource & BL_* defines + * + */ + +#ifndef _IBM_OCP_ENET_H_ +#define _IBM_OCP_ENET_H_ + +#include +#include +#include /* For phys_addr_t */ + +#include "ibm_emac.h" +#include "ibm_ocp_phy.h" +#include "ibm_ocp_zmii.h" +#include "ibm_ocp_mal.h" + +#ifndef CONFIG_IBM_OCP_ENET_TX_BUFF +#define NUM_TX_BUFF 64 +#define NUM_RX_BUFF 64 +#else +#define NUM_TX_BUFF CONFIG_IBM_OCP_ENET_TX_BUFF +#define NUM_RX_BUFF CONFIG_IBM_OCP_ENET_RX_BUFF +#endif + +/* This does 16 byte alignment, exactly what we need. + * The packet length includes FCS, but we don't want to + * include that when passing upstream as it messes up + * bridging applications. + */ +#ifndef CONFIG_IBM_OCP_ENET_SKB_RES +#define SKB_RES 2 +#else +#define SKB_RES CONFIG_IBM_OCP_ENET_SKB_RES +#endif + +/* Note about alignement. alloc_skb() returns a cache line + * aligned buffer. However, dev_alloc_skb() will add 16 more + * bytes and "reserve" them, so our buffer will actually end + * on a half cache line. What we do is to use directly + * alloc_skb, allocate 16 more bytes to match the total amount + * allocated by dev_alloc_skb(), but we don't reserve. + */ +#define MAX_NUM_BUF_DESC 255 +#define DESC_RX_BUF_SIZE 1536 +#define DESC_BUF_SIZE_REG (DESC_RX_BUF_SIZE / 16) + +/* Transmitter timeout. */ +#define TX_TIMEOUT (2*HZ) +#define OCP_RESET_DELAY 50 +#define MDIO_DELAY 2 + +/* Power managment shift registers */ +#define IBM_CPM_EMMII 0 /* Shift value for MII */ +#define IBM_CPM_EMRX 1 /* Shift value for recv */ +#define IBM_CPM_EMTX 2 /* Shift value for MAC */ +#define IBM_CPM_EMAC(x) (((x)>>IBM_CPM_EMMII) | ((x)>>IBM_CPM_EMRX) | ((x)>>IBM_CPM_EMTX)) + +#ifdef CONFIG_IBM_OCP_ENET_ERROR_MSG +void emac_serr_dump_0(struct net_device *dev); +void emac_serr_dump_1(struct net_device *dev); +void emac_err_dump(struct net_device *dev, int em0isr); +void emac_phy_dump(struct net_device *); +void emac_desc_dump(struct net_device *); +void emac_mac_dump(struct net_device *); +void emac_mal_dump(struct net_device *); +#else +#define emac_serr_dump_0(dev) do { } while (0) +#define emac_serr_dump_1(dev) do { } while (0) +#define emac_err_dump(dev,x) do { } while (0) +#define emac_phy_dump(dev) do { } while (0) +#define emac_desc_dump(dev) do { } while (0) +#define emac_mac_dump(dev) do { } while (0) +#define emac_mal_dump(dev) do { } while (0) +#endif + + +struct ocp_enet_private { + struct sk_buff *tx_skb[NUM_TX_BUFF]; + struct sk_buff *rx_skb[NUM_RX_BUFF]; + struct mal_descriptor *tx_desc; + struct mal_descriptor *rx_desc; + struct mal_descriptor *rx_dirty; + struct net_device_stats stats; + int tx_cnt; + int rx_slot; + int dirty_rx; + int tx_slot; + int ack_slot; + + struct mii_phy phy_mii; + int mii_phy_addr; + int want_autoneg; + int timer_ticks; + struct timer_list link_timer; + struct net_device *mdio_dev; + + struct ocp_device *zmii_dev; + int zmii_input; + + struct ibm_ocp_mal *mal; + int mal_tx_chan, mal_rx_chan; + struct mal_commac commac; + + int opened; + int going_away; + int wol_irq; + volatile emac_t *emacp; + struct ocp_device *ocpdev; + struct net_device *ndev; + spinlock_t lock; +}; + + +#endif /* _IBM_OCP_ENET_H_ */ diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_mal.c linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_mal.c --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_mal.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_mal.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,484 @@ +/* + * ibm_ocp_mal.c + * + * Armin Kuster akuster@mvista.com + * Juen, 2002 + * + * Copyright 2002 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + * TODO: Move to a separate module + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ibm_ocp_mal.h" + +// Locking: Should we share a lock with the client ? The client could provide +// a lock pointer (optionally) in the commac structure... I don't think this is +// really necessary though + + +/* This lock protects the commac list. On today UP implementations, it's + * really only used as IRQ protection in mal_{register,unregister}_commac() + */ +static rwlock_t mal_list_lock = RW_LOCK_UNLOCKED; + +int +mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac) +{ + unsigned long flags; + + write_lock_irqsave(&mal_list_lock, flags); + + /* Don't let multiple commacs claim the same channel */ + if ( (mal->tx_chan_mask & commac->tx_chan_mask) || + (mal->rx_chan_mask & commac->rx_chan_mask) ) { + write_unlock(&mal_list_lock); + return -EBUSY; + } + + mal->tx_chan_mask |= commac->tx_chan_mask; + mal->rx_chan_mask |= commac->rx_chan_mask; + + list_add(&commac->list, &mal->commac); + + write_unlock_irqrestore(&mal_list_lock, flags); + + MOD_INC_USE_COUNT; + + return 0; +} + +int +mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac) +{ + unsigned long flags; + + write_lock_irqsave(&mal_list_lock, flags); + + mal->tx_chan_mask &= ~commac->tx_chan_mask; + mal->rx_chan_mask &= ~commac->rx_chan_mask; + + list_del_init(&commac->list); + + write_unlock_irqrestore(&mal_list_lock, flags); + + MOD_DEC_USE_COUNT; + + return 0; +} + +int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size) +{ + switch (channel) { + case 0: + set_mal_dcrn(mal, DCRN_MALRCBS0, size); + break; +#ifdef DCRN_RCBS1 + case 1: + set_mal_dcrn(mal, DCRN_MALRCBS1, size); + break; +#endif +#ifdef DCRN_RCBS2 + case 2: + set_mal_dcrn(mal, DCRN_MALRCBS2, size); + break; +#endif +#ifdef DCRN_RCBS3 + case 3: + set_mal_dcrn(mal, DCRN_MALRCBS3, size); + break; +#endif + default: + return -EINVAL; + } + + return 0; +} + +static void +mal_serr(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ibm_ocp_mal *mal = dev_instance; + unsigned long mal_error; + + /* + * This SERR applies to one of the devices on the MAL, here we charge + * it against the first EMAC registered for the MAL. + */ + + mal_error = get_mal_dcrn(mal, DCRN_MALESR); + + printk(KERN_ERR "%s: System Error (MALESR=%lx)\n", + "MAL" /* FIXME: get the name right */, mal_error); + + /* FIXME: decipher error */ + /* DIXME: distribute to commacs, if possible */ + + /* Clear the error status register */ + set_mal_dcrn(mal, DCRN_MALESR, mal_error); +} + +static void +mal_txeob(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ibm_ocp_mal *mal = dev_instance; + struct list_head *l; + unsigned long isr; + + isr = get_mal_dcrn(mal, DCRN_MALTXEOBISR); + set_mal_dcrn(mal, DCRN_MALTXEOBISR, isr); + + read_lock(&mal_list_lock); + list_for_each(l, &mal->commac) { + struct mal_commac *mc = list_entry(l, struct mal_commac, list); + + if (isr & mc->tx_chan_mask) { + mc->ops->txeob(mc->dev, isr & mc->tx_chan_mask); + } + } + read_unlock(&mal_list_lock); +} + +static void +mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ibm_ocp_mal *mal = dev_instance; + struct list_head *l; + unsigned long isr; + + + isr = get_mal_dcrn(mal, DCRN_MALRXEOBISR); + set_mal_dcrn(mal, DCRN_MALRXEOBISR, isr); + + read_lock(&mal_list_lock); + list_for_each(l, &mal->commac) { + struct mal_commac *mc = list_entry(l, struct mal_commac, list); + + if (isr & mc->rx_chan_mask) { + mc->ops->rxeob(mc->dev, isr & mc->rx_chan_mask); + } + } + read_unlock(&mal_list_lock); +} + +static void +mal_txde(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ibm_ocp_mal *mal = dev_instance; + struct list_head *l; + unsigned long deir; + + deir = get_mal_dcrn(mal, DCRN_MALTXDEIR); + + /* FIXME: print which MAL correctly */ + printk(KERN_WARNING "%s: Tx descriptor error (MALTXDEIR=%lx)\n", + "MAL", deir); + + read_lock(&mal_list_lock); + list_for_each(l, &mal->commac) { + struct mal_commac *mc = list_entry(l, struct mal_commac, list); + + if (deir & mc->tx_chan_mask) { + mc->ops->txde(mc->dev, deir & mc->tx_chan_mask); + } + } + read_unlock(&mal_list_lock); +} + +/* + * This interrupt should be very rare at best. This occurs when + * the hardware has a problem with the receive descriptors. The manual + * states that it occurs when the hardware cannot the receive descriptor + * empty bit is not set. The recovery mechanism will be to + * traverse through the descriptors, handle any that are marked to be + * handled and reinitialize each along the way. At that point the driver + * will be restarted. + */ +static void +mal_rxde(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ibm_ocp_mal *mal = dev_instance; + struct list_head *l; + unsigned long deir; + + deir = get_mal_dcrn(mal, DCRN_MALRXDEIR); + + /* + * This really is needed. This case encountered in stress testing. + */ + if (deir == 0) + return; + + /* FIXME: print which MAL correctly */ + printk(KERN_WARNING "%s: Rx descriptor error (MALRXDEIR=%lx)\n", + "MAL", deir); + + read_lock(&mal_list_lock); + list_for_each(l, &mal->commac) { + struct mal_commac *mc = list_entry(l, struct mal_commac, list); + + if (deir & mc->rx_chan_mask) { + mc->ops->rxde(mc->dev, deir & mc->rx_chan_mask); + } + } + read_unlock(&mal_list_lock); +} + +static int __init +mal_probe(struct ocp_device *ocpdev) +{ + struct ibm_ocp_mal *mal = NULL; + struct ocp_func_mal_data *maldata; + int err = 0; + + maldata = (struct ocp_func_mal_data *)ocpdev->def->additions; + if (maldata == NULL) { + printk(KERN_ERR "mal%d: Missing additional datas !\n", ocpdev->def->index); + return -ENODEV; + } + + mal = kmalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL); + if (mal == NULL) { + printk(KERN_ERR "mal%d: Out of memory allocating MAL structure !\n", + ocpdev->def->index); + return -ENOMEM; + } + memset(mal, 0, sizeof(*mal)); + + switch (ocpdev->def->index) { + case 0: + mal->dcrbase = DCRN_MAL_BASE; + break; +#ifdef DCRN_MAL1_BASE + case 1: + mal->dcrbase = DCRN_MAL1_BASE; + break; +#endif + default: + BUG(); + } + mal->serr_irq = BL_MAL_SERR; + mal->txde_irq = BL_MAL_TXDE; + mal->txeob_irq = BL_MAL_TXEOB; + mal->rxde_irq = BL_MAL_RXDE; + mal->rxeob_irq = BL_MAL_RXEOB; + + mal->num_tx_channels = maldata->num_tx_chans; + mal->num_rx_channels = maldata->num_rx_chans; + + /**************************/ + + INIT_LIST_HEAD(&mal->commac); + + + set_mal_dcrn(mal, DCRN_MALRXCARR, 0xFFFFFFFF); + set_mal_dcrn(mal, DCRN_MALTXCARR, 0xFFFFFFFF); + + set_mal_dcrn(mal, DCRN_MALCR, MALCR_MMSR); /* 384 */ + /* FIXME: Add delay */ + + /* Set the MAL configuration register */ + set_mal_dcrn(mal, DCRN_MALCR, + MALCR_PLBB | MALCR_OPBBL | MALCR_LEA | + MALCR_PLBLT_DEFAULT); + + /* It would be nice to allocate buffers separately for each + * channel, but we can't because the channels share the upper + * 13 bits of address lines. Each channels buffer must also + * be 4k aligned, so we allocate 4k for each channel. This is + * inefficient FIXME: do better, if possible */ + + mal->tx_virt_addr = consistent_alloc(GFP_KERNEL, + MAL_DT_ALIGN * mal->num_tx_channels, + &mal->tx_phys_addr); + if (mal->tx_virt_addr == NULL) { + printk(KERN_ERR "mal%d: Out of memory allocating MAL descriptors !\n", + ocpdev->def->index); + err = -ENOMEM; + goto fail; + } + + /* God, oh, god, I hate DCRs */ + set_mal_dcrn(mal, DCRN_MALTXCTP0R, mal->tx_phys_addr); +#ifdef DCRN_MALTXCTP1R + if (mal->num_tx_channels > 1) + set_mal_dcrn(mal, DCRN_MALTXCTP1R, + mal->tx_phys_addr + MAL_DT_ALIGN); +#endif /* DCRN_MALTXCTP1R */ +#ifdef DCRN_MALTXCTP2R + if (mal->num_tx_channels > 2) + set_mal_dcrn(mal, DCRN_MALTXCTP2R, + mal->tx_phys_addr + 2*MAL_DT_ALIGN); +#endif /* DCRN_MALTXCTP2R */ +#ifdef DCRN_MALTXCTP3R + if (mal->num_tx_channels > 3) + set_mal_dcrn(mal, DCRN_MALTXCTP3R, + mal->tx_phys_addr + 3*MAL_DT_ALIGN); +#endif /* DCRN_MALTXCTP3R */ +#ifdef DCRN_MALTXCTP4R + if (mal->num_tx_channels > 4) + set_mal_dcrn(mal, DCRN_MALTXCTP4R, + mal->tx_phys_addr + 4*MAL_DT_ALIGN); +#endif /* DCRN_MALTXCTP4R */ +#ifdef DCRN_MALTXCTP5R + if (mal->num_tx_channels > 5) + set_mal_dcrn(mal, DCRN_MALTXCTP5R, + mal->tx_phys_addr + 5*MAL_DT_ALIGN); +#endif /* DCRN_MALTXCTP5R */ +#ifdef DCRN_MALTXCTP6R + if (mal->num_tx_channels > 6) + set_mal_dcrn(mal, DCRN_MALTXCTP6R, + mal->tx_phys_addr + 6*MAL_DT_ALIGN); +#endif /* DCRN_MALTXCTP6R */ +#ifdef DCRN_MALTXCTP7R + if (mal->num_tx_channels > 7) + set_mal_dcrn(mal, DCRN_MALTXCTP7R, + mal->tx_phys_addr + 7*MAL_DT_ALIGN); +#endif /* DCRN_MALTXCTP7R */ + + mal->rx_virt_addr = consistent_alloc(GFP_KERNEL, + MAL_DT_ALIGN * mal->num_rx_channels, + &mal->rx_phys_addr); + + set_mal_dcrn(mal, DCRN_MALRXCTP0R, mal->rx_phys_addr); +#ifdef DCRN_MALRXCTP1R + if (mal->num_rx_channels > 1) + set_mal_dcrn(mal, DCRN_MALRXCTP1R, + mal->rx_phys_addr + MAL_DT_ALIGN); +#endif /* DCRN_MALRXCTP1R */ +#ifdef DCRN_MALRXCTP2R + if (mal->num_rx_channels > 2) + set_mal_dcrn(mal, DCRN_MALRXCTP2R, + mal->rx_phys_addr + 2*MAL_DT_ALIGN); +#endif /* DCRN_MALRXCTP2R */ +#ifdef DCRN_MALRXCTP3R + if (mal->num_rx_channels > 3) + set_mal_dcrn(mal, DCRN_MALRXCTP3R, + mal->rx_phys_addr + 3*MAL_DT_ALIGN); +#endif /* DCRN_MALRXCTP3R */ + + err = request_irq(mal->serr_irq, mal_serr, 0 ,"MAL SERR", mal); + if (err) + goto fail; + err = request_irq(mal->txde_irq, mal_txde,0, "MAL TX DE ", mal); + if (err) + goto fail; + err = request_irq(mal->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal); + if (err) + goto fail; + err = request_irq(mal->rxde_irq, mal_rxde, 0, "MAL RX DE", mal); + if (err) + goto fail; + err = request_irq(mal->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal); + if (err) + goto fail; + + set_mal_dcrn(mal, DCRN_MALIER, + MALIER_DE | MALIER_NE | MALIER_TE | + MALIER_OPBE | MALIER_PLBE); + + /* Advertise me to the rest of the world */ + ocp_set_drvdata(ocpdev, mal); + + printk(KERN_INFO "mal%d: Initialized, %d tx channels, %d rx channels\n", + ocpdev->def->index, mal->num_tx_channels, mal->num_rx_channels); + + return 0; + + fail: + /* FIXME: dispose requested IRQs ! */ + if (err && mal) + kfree(mal); + return err; +} + +static void __exit +mal_remove(struct ocp_device *ocpdev) +{ + struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev); + + ocp_set_drvdata(ocpdev, NULL); + + /* FIXME: shut down the MAL, deal with dependency with emac */ + free_irq(mal->serr_irq, mal); + free_irq(mal->txde_irq, mal); + free_irq(mal->txeob_irq, mal); + free_irq(mal->rxde_irq, mal); + free_irq(mal->rxeob_irq, mal); + + if (mal->tx_virt_addr) + consistent_free(mal->tx_virt_addr); + if (mal->rx_virt_addr) + consistent_free(mal->rx_virt_addr); + + kfree(mal); +} + +/* Structure for a device driver */ +static struct ocp_device_id mal_ids[] = +{ + { .vendor = OCP_ANY_ID, .function = OCP_FUNC_MAL }, + { .vendor = OCP_VENDOR_INVALID } +}; + +static struct ocp_driver mal_driver = +{ + .name = "mal", + .id_table = mal_ids, + + .probe = mal_probe, + .remove = mal_remove, +}; + +static int __init +init_mals(void) +{ + int rc; + + rc = ocp_register_driver(&mal_driver); + if (rc == 0) { + ocp_unregister_driver(&mal_driver); + return -ENODEV; + } + + return 0; +} + +static void __exit +exit_mals(void) +{ + ocp_unregister_driver(&mal_driver); +} + +module_init(init_mals); +module_exit(exit_mals); diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_mal.h linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_mal.h --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_mal.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_mal.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,147 @@ +/* + * 06/02/02 -Armin + * added new mal functions and defines from ibm_ocp_enet.h + */ + +#ifndef _IBM_OCP_MAL_H +#define _IBM_OCP_MAL_H + +#include + +#define MAL_DT_ALIGN (4096) /* Alignment for each channel's descriptor table */ + +#define MAL_CHAN_MASK(chan) (0x80000000 >> (chan)) + +/* MAL Buffer Descriptor structure */ +struct mal_descriptor { + volatile unsigned short ctrl; /* MAL / Commac status control bits */ + volatile short data_len; /* Max length is 4K-1 (12 bits) */ + unsigned char *data_ptr; /* pointer to actual data buffer */ +} __attribute__((packed)); + +/* the following defines are for the MadMAL status and control registers. */ +/* MADMAL transmit and receive status/control bits */ +#define MAL_RX_CTRL_EMPTY 0x8000 +#define MAL_RX_CTRL_WRAP 0x4000 +#define MAL_RX_CTRL_CM 0x2000 +#define MAL_RX_CTRL_LAST 0x1000 +#define MAL_RX_CTRL_FIRST 0x0800 +#define MAL_RX_CTRL_INTR 0x0400 + +#define MAL_TX_CTRL_READY 0x8000 +#define MAL_TX_CTRL_WRAP 0x4000 +#define MAL_TX_CTRL_CM 0x2000 +#define MAL_TX_CTRL_LAST 0x1000 +#define MAL_TX_CTRL_INTR 0x0400 + +struct mal_commac_ops { + void (*txeob)(void *dev, u32 chanmask); + void (*txde)(void *dev, u32 chanmask); + void (*rxeob)(void *dev, u32 chanmask); + void (*rxde)(void *dev, u32 chanmask); +}; + +struct mal_commac { + struct mal_commac_ops *ops; + void *dev; + u32 tx_chan_mask, rx_chan_mask; + struct list_head list; +}; + +/* FIXME: Work this out better */ +#define MAL_MAX_TX_CHANNELS (EMAC_NUMS*2) +#define MAL_MAX_RX_CHANNELS (EMAC_NUMS) + +struct ibm_ocp_mal { + int dcrbase; + int serr_irq, txeob_irq, txde_irq, rxeob_irq, rxde_irq; + + struct list_head commac; + u32 tx_chan_mask, rx_chan_mask; + + int num_tx_channels; + dma_addr_t tx_phys_addr; + struct mal_descriptor *tx_virt_addr; + + int num_rx_channels; + dma_addr_t rx_phys_addr; + struct mal_descriptor *rx_virt_addr; +}; + +#ifdef DCRN_MAL1_BASE +#define NUM_MALS 2 +#else +#define NUM_MALS 1 +#endif + +extern struct ibm_ocp_mal mal_table[NUM_MALS]; + +#define GET_MAL_STANZA(base,dcrn) \ + case base: \ + x = mfdcr(dcrn(base)); \ + break; + +#define SET_MAL_STANZA(base,dcrn, val) \ + case base: \ + mtdcr(dcrn(base), (val)); \ + break; + +#define GET_MAL0_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL_BASE,dcrn) +#define SET_MAL0_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL_BASE,dcrn,val) + +#ifdef DCRN_MAL1_BASE +#define GET_MAL1_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL1_BASE,dcrn) +#define SET_MAL1_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL1_BASE,dcrn,val) +#else /* ! DCRN_MAL1_BASE */ +#define GET_MAL1_STANZA(dcrn) +#define SET_MAL1_STANZA(dcrn,val) +#endif + + +#define get_mal_dcrn(mal, dcrn) ({ \ + u32 x; \ + switch ((mal)->dcrbase) { \ + GET_MAL0_STANZA(dcrn) \ + GET_MAL1_STANZA(dcrn) \ + default: \ + BUG(); \ + } \ +x; }) + +#define set_mal_dcrn(mal, dcrn, val) do { \ + switch ((mal)->dcrbase) { \ + SET_MAL0_STANZA(dcrn,val) \ + SET_MAL1_STANZA(dcrn,val) \ + default: \ + BUG(); \ + } } while (0) + + +static inline void mal_enable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask) +{ + set_mal_dcrn(mal, DCRN_MALTXCASR, + get_mal_dcrn(mal, DCRN_MALTXCASR) | chanmask); +} + +static inline void mal_disable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask) +{ + set_mal_dcrn(mal, DCRN_MALTXCARR, chanmask); +} + +static inline void mal_enable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask) +{ + set_mal_dcrn(mal, DCRN_MALRXCASR, + get_mal_dcrn(mal, DCRN_MALRXCASR) | chanmask); +} + +static inline void mal_disable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask) +{ + set_mal_dcrn(mal, DCRN_MALRXCARR, chanmask); +} + +extern int mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac); +extern int mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac); + +extern int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size); + +#endif /* _IBM_OCP_MAL_H */ diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_phy.c linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_phy.c --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_phy.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_phy.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,243 @@ +/* + * ibm_ocp_phy.c + * + * PHY drivers for the ibm ocp ethernet driver. Borrowed + * from sungem_phy.c, though I only kept the generic MII + * driver for now. + * + * This file should be shared with other drivers or eventually + * merged as the "low level" part of miilib + * + * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org) + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ibm_ocp_phy.h" + + +static inline int __phy_read(struct mii_phy* phy, int id, int reg) +{ + return phy->mdio_read(phy->dev, id, reg); +} + +static inline void __phy_write(struct mii_phy* phy, int id, int reg, int val) +{ + phy->mdio_write(phy->dev, id, reg, val); +} + +static inline int phy_read(struct mii_phy* phy, int reg) +{ + return phy->mdio_read(phy->dev, phy->mii_id, reg); +} + +static inline void phy_write(struct mii_phy* phy, int reg, int val) +{ + phy->mdio_write(phy->dev, phy->mii_id, reg, val); +} + +static int reset_one_mii_phy(struct mii_phy* phy, int phy_id) +{ + u16 val; + int limit = 10000; + + val = __phy_read(phy, phy_id, MII_BMCR); + val &= ~BMCR_ISOLATE; + val |= BMCR_RESET; + __phy_write(phy, phy_id, MII_BMCR, val); + + udelay(100); + + while (limit--) { + val = __phy_read(phy, phy_id, MII_BMCR); + if ((val & BMCR_RESET) == 0) + break; + udelay(10); + } + if ((val & BMCR_ISOLATE) && limit > 0) + __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE); + + return (limit <= 0); +} + +static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) +{ + u16 ctl, adv; + + phy->autoneg = 1; + phy->speed = SPEED_10; + phy->duplex = DUPLEX_HALF; + phy->pause = 0; + phy->advertising = advertise; + + /* Setup standard advertise */ + adv = phy_read(phy, MII_ADVERTISE); + adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); + if (advertise & ADVERTISED_10baseT_Half) + adv |= ADVERTISE_10HALF; + if (advertise & ADVERTISED_10baseT_Full) + adv |= ADVERTISE_10FULL; + if (advertise & ADVERTISED_100baseT_Half) + adv |= ADVERTISE_100HALF; + if (advertise & ADVERTISED_100baseT_Full) + adv |= ADVERTISE_100FULL; + phy_write(phy, MII_ADVERTISE, adv); + + /* Start/Restart aneg */ + ctl = phy_read(phy, MII_BMCR); + ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); + phy_write(phy, MII_BMCR, ctl); + + return 0; +} + +static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd) +{ + u16 ctl; + + phy->autoneg = 0; + phy->speed = speed; + phy->duplex = fd; + phy->pause = 0; + + ctl = phy_read(phy, MII_BMCR); + ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE); + + /* First reset the PHY */ + phy_write(phy, MII_BMCR, ctl | BMCR_RESET); + + /* Select speed & duplex */ + switch(speed) { + case SPEED_10: + break; + case SPEED_100: + ctl |= BMCR_SPEED100; + break; + case SPEED_1000: + default: + return -EINVAL; + } + if (fd == DUPLEX_FULL) + ctl |= BMCR_FULLDPLX; + phy_write(phy, MII_BMCR, ctl); + + return 0; +} + +static int genmii_poll_link(struct mii_phy *phy) +{ + u16 status; + + (void)phy_read(phy, MII_BMSR); + status = phy_read(phy, MII_BMSR); + if ((status & BMSR_LSTATUS) == 0) + return 0; + if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE)) + return 0; + return 1; +} + +static int genmii_read_link(struct mii_phy *phy) +{ + u16 lpa; + + if (phy->autoneg) { + lpa = phy_read(phy, MII_LPA); + + if (lpa & (LPA_10FULL | LPA_100FULL)) + phy->duplex = DUPLEX_FULL; + else + phy->duplex = DUPLEX_HALF; + if (lpa & (LPA_100FULL | LPA_100HALF)) + phy->speed = SPEED_100; + else + phy->speed = SPEED_10; + phy->pause = 0; + } + /* On non-aneg, we assume what we put in BMCR is the speed, + * though magic-aneg shouldn't prevent this case from occurring + */ + + return 0; +} + + +#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ + SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII) +#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \ + SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full) + + +/* Generic implementation for most 10/100 PHYs */ +static struct mii_phy_ops generic_phy_ops = { + setup_aneg: genmii_setup_aneg, + setup_forced: genmii_setup_forced, + poll_link: genmii_poll_link, + read_link: genmii_read_link +}; + +static struct mii_phy_def genmii_phy_def = { + phy_id: 0x00000000, + phy_id_mask: 0x00000000, + name: "Generic MII", + features: MII_BASIC_FEATURES, + magic_aneg: 0, + ops: &generic_phy_ops +}; + +static struct mii_phy_def* mii_phy_table[] = { + &genmii_phy_def, + NULL +}; + +int mii_phy_probe(struct mii_phy *phy, int mii_id) +{ + int rc; + u32 id; + struct mii_phy_def* def; + int i; + + phy->autoneg = 0; + phy->advertising = 0; + phy->mii_id = mii_id; + phy->speed = 0; + phy->duplex = 0; + phy->pause = 0; + + /* Take PHY out of isloate mode and reset it. */ + rc = reset_one_mii_phy(phy, mii_id); + if (rc) + return -ENODEV; + + /* Read ID and find matching entry */ + id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2)) + & 0xfffffff0; + for (i=0; (def = mii_phy_table[i]) != NULL; i++) + if ((id & def->phy_id_mask) == def->phy_id) + break; + /* Should never be NULL (we have a generic entry), but... */ + if (def == NULL) + return -ENODEV; + + phy->def = def; + + /* Setup default advertising */ + phy->advertising = def->features; + + return 0; +} + +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_phy.h linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_phy.h --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_phy.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_phy.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,90 @@ + +/* + * ibm_ocp_phy.h + * + * + * Benjamin Herrenschmidt + * February 2003 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * This file basically duplicates sungem_phy.{c,h} with different PHYs + * supported. I'm looking into merging that in a single mii layer more + * flexible than mii.c + */ + +#ifndef _IBM_OCP_PHY_H_ +#define _IBM_OCP_PHY_H_ + +struct mii_phy; + +/* Operations supported by any kind of PHY */ +struct mii_phy_ops +{ + int (*init)(struct mii_phy *phy); + int (*suspend)(struct mii_phy *phy, int wol_options); + int (*setup_aneg)(struct mii_phy *phy, u32 advertise); + int (*setup_forced)(struct mii_phy *phy, int speed, int fd); + int (*poll_link)(struct mii_phy *phy); + int (*read_link)(struct mii_phy *phy); +}; + +/* Structure used to statically define an mii/gii based PHY */ +struct mii_phy_def +{ + u32 phy_id; /* Concatenated ID1 << 16 | ID2 */ + u32 phy_id_mask; /* Significant bits */ + u32 features; /* Ethtool SUPPORTED_* defines */ + int magic_aneg; /* Autoneg does all speed test for us */ + const char* name; + const struct mii_phy_ops* ops; +}; + +/* An instance of a PHY, partially borrowed from mii_if_info */ +struct mii_phy +{ + struct mii_phy_def* def; + int advertising; + int mii_id; + + /* 1: autoneg enabled, 0: disabled */ + int autoneg; + + /* forced speed & duplex (no autoneg) + * partner speed & duplex & pause (autoneg) + */ + int speed; + int duplex; + int pause; + + /* Provided by host chip */ + struct net_device* dev; + int (*mdio_read) (struct net_device *dev, int mii_id, int reg); + void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val); +}; + +/* Pass in a struct mii_phy with dev, mdio_read and mdio_write + * filled, the remaining fields will be filled on return + */ +extern int mii_phy_probe(struct mii_phy *phy, int mii_id); + +#endif /* _IBM_OCP_PHY_H_ */ diff -urN linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_zmii.h linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_zmii.h --- linux-2.4.21/drivers/net/ibm_emac/ibm_ocp_zmii.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/ibm_emac/ibm_ocp_zmii.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,109 @@ +/* + * ocp_zmii.h + * + * Defines for the IBM ZMII bridge + * + * Armin Kuster akuster@mvista.com + * Dec, 2001 + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You 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. + * + * V 1.2 (04/19/02 ) - Armin + * added support for emac 2 & 3 + */ + +#ifndef _OCP_ZMII_H_ +#define _OCP_ZMII_H_ + +#include + +/* ZMII bridge registers */ +struct zmii_regs { + u32 fer; /* Function enable reg */ + u32 ssr; /* Spedd select reg */ + u32 smiirs; /* SMII status reg */ +}; + +/* ZMII device */ +struct ibm_ocp_zmii { + struct zmii_regs *base; + int mode; + int users;/* number of EMACs using this ZMII bridge */ +}; + +/* Fuctional Enable Reg */ + +#define ZMII_MDI0 0x80000000 +#define ZMII_SMII0 0x40000000 +#define ZMII_RMII0 0x20000000 +#define ZMII_MII0 0x10000000 +#define ZMII_MDI1 0x08000000 +#define ZMII_SMII1 0x04000000 +#define ZMII_RMII1 0x02000000 +#define ZMII_MII1 0x01000000 +#define ZMII_MDI2 0x00800000 +#define ZMII_SMII2 0x00400000 +#define ZMII_RMII2 0x00200000 +#define ZMII_MII2 0x00100000 +#define ZMII_MDI3 0x00080000 +#define ZMII_SMII3 0x00040000 +#define ZMII_RMII3 0x00020000 +#define ZMII_MII3 0x00010000 + +/* Speed Selection reg */ + +#define ZMII_SCI0 0x40000000 +#define ZMII_FSS0 0x20000000 +#define ZMII_SP0 0x10000000 +#define ZMII_SCI1 0x04000000 +#define ZMII_FSS1 0x02000000 +#define ZMII_SP1 0x01000000 +#define ZMII_SCI2 0x00400000 +#define ZMII_FSS2 0x00200000 +#define ZMII_SP2 0x00100000 +#define ZMII_SCI3 0x00040000 +#define ZMII_FSS3 0x00020000 +#define ZMII_SP3 0x00010000 + +#define ZMII_MII0_100MB ZMII_SP0 +#define ZMII_MII0_10MB ~ZMII_SP0 +#define ZMII_MII1_100MB ZMII_SP1 +#define ZMII_MII1_10MB ~ZMII_SP1 +#define ZMII_MII2_100MB ZMII_SP2 +#define ZMII_MII2_10MB ~ZMII_SP2 +#define ZMII_MII3_100MB ZMII_SP3 +#define ZMII_MII3_10MB ~ZMII_SP3 + +/* SMII Status reg */ + +#define ZMII_STS0 0xFF000000 /* EMAC0 smii status mask */ +#define ZMII_STS1 0x00FF0000 /* EMAC1 smii status mask */ + + +#define SMII 0 +#define RMII 1 +#define MII 2 +#define MDI 3 +#define ZMII_AUTO 4 + +#endif /* _OCP_ZMII_H_ */ diff -urN linux-2.4.21/drivers/net/ioc3-eth.c linux-2.4.22/drivers/net/ioc3-eth.c --- linux-2.4.21/drivers/net/ioc3-eth.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/ioc3-eth.c 2003-08-25 04:44:42.000000000 -0700 @@ -1841,9 +1841,6 @@ return -EFAULT; return 0; } else if (ecmd.cmd == ETHTOOL_SSET) { - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Verify the settings we care about. */ if (ecmd.autoneg != AUTONEG_ENABLE && ecmd.autoneg != AUTONEG_DISABLE) diff -urN linux-2.4.21/drivers/net/irda/irda-usb.c linux-2.4.22/drivers/net/irda/irda-usb.c --- linux-2.4.21/drivers/net/irda/irda-usb.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/net/irda/irda-usb.c 2003-08-25 04:44:42.000000000 -0700 @@ -30,23 +30,21 @@ * IMPORTANT NOTE * -------------- * - * As of kernel 2.4.10, this is the state of compliance and testing of + * As of kernel 2.4.21, this is the state of compliance and testing of * this driver (irda-usb) with regards to the USB low level drivers... * * This driver has been tested SUCCESSFULLY with the following drivers : * o usb-uhci (For Intel/Via USB controllers) + * o uhci (Alternate/JE driver for Intel/Via USB controllers) * o usb-ohci (For other USB controllers) * * This driver has NOT been tested with the following drivers : - * o usb-ehci (USB 2.0 controllers) + * o ehci-hcd (USB 2.0 controllers) * - * This driver WON'T WORK with the following drivers : - * o uhci (Alternate/JE driver for Intel/Via USB controllers) - * Amongst the reasons : - * o uhci doesn't implement USB_ZERO_PACKET - * o uhci non-compliant use of urb->timeout - * The final fix for USB_ZERO_PACKET in uhci is likely to be in 2.4.19 and - * 2.5.8. With this fix, the driver will work properly. More on that later. + * Note that all HCD drivers do USB_ZERO_PACKET and timeout properly, + * so we don't have to worry about that anymore. + * One common problem is the failure to set the address on the dongle, + * but this happens before the driver gets loaded... * * Jean II */ @@ -81,8 +79,10 @@ /* These are the currently known IrDA USB dongles. Add new dongles here */ static struct usb_device_id dongles[] = { - /* ACTiSYS Corp, ACT-IR2000U FIR-USB Adapter */ + /* ACTiSYS Corp., ACT-IR2000U FIR-USB Adapter */ { USB_DEVICE(0x9c4, 0x011), driver_info: IUC_SPEED_BUG | IUC_NO_WINDOW }, + /* Look like ACTiSYS, Report : IBM Corp., IBM UltraPort IrDA */ + { USB_DEVICE(0x4428, 0x012), driver_info: IUC_SPEED_BUG | IUC_NO_WINDOW }, /* KC Technology Inc., KC-180 USB IrDA Device */ { USB_DEVICE(0x50f, 0x180), driver_info: IUC_SPEED_BUG | IUC_NO_WINDOW }, /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ @@ -167,7 +167,8 @@ IRDA_DEBUG(2, "%s(), changing speed to %d\n", __FUNCTION__, self->new_speed); self->speed = self->new_speed; - self->new_speed = -1; + /* We will do ` self->new_speed = -1; ' in the completion + * handler just in case the current URB fail - Jean II */ switch (self->speed) { case 2400: @@ -208,7 +209,8 @@ if (self->new_xbofs != -1) { IRDA_DEBUG(2, "%s(), changing xbofs to %d\n", __FUNCTION__, self->new_xbofs); self->xbofs = self->new_xbofs; - self->new_xbofs = -1; + /* We will do ` self->new_xbofs = -1; ' in the completion + * handler just in case the current URB fail - Jean II */ switch (self->xbofs) { case 48: @@ -285,7 +287,8 @@ /*------------------------------------------------------------------*/ /* - * Note : this function will be called with both speed_urb and empty_urb... + * Speed URB callback + * Now, we can only get called for the speed URB. */ static void speed_bulk_callback(struct urb *purb) { @@ -294,10 +297,9 @@ IRDA_DEBUG(2, "%s()\n", __FUNCTION__); /* We should always have a context */ - if (self == NULL) { - WARNING("%s(), Bug : self == NULL\n", __FUNCTION__); - return; - } + ASSERT(self != NULL, return;); + /* We should always be called for the speed URB */ + ASSERT(purb == &self->speed_urb, return;); /* Check for timeout and other USB nasties */ if(purb->status != USB_ST_NOERROR) { @@ -313,12 +315,14 @@ } /* urb is now available */ - purb->status = USB_ST_NOERROR; + //purb->status = USB_ST_NOERROR; -> tested above - /* If it was the speed URB, allow the stack to send more packets */ - if(purb == &self->speed_urb) { - netif_wake_queue(self->netdev); - } + /* New speed and xbof is now commited in hardware */ + self->new_speed = -1; + self->new_xbofs = -1; + + /* Allow the stack to send more packets */ + netif_wake_queue(self->netdev); } /*------------------------------------------------------------------*/ @@ -333,6 +337,9 @@ s32 speed; s16 xbofs; int res, mtt; + int err = 1; /* Failed */ + + IRDA_DEBUG(4, __FUNCTION__ "() on %s\n", netdev->name); netif_stop_queue(netdev); @@ -342,10 +349,9 @@ /* Check if the device is still there. * We need to check self->present under the spinlock because * of irda_usb_disconnect() is synchronous - Jean II */ - if ((!self) || (!self->present)) { + if (!self->present) { IRDA_DEBUG(0, "%s(), Device is gone...\n", __FUNCTION__); - spin_unlock_irqrestore(&self->lock, flags); - return 1; /* Failed */ + goto drop; } /* Check if we need to change the number of xbofs */ @@ -372,6 +378,7 @@ irda_usb_change_speed_xbofs(self); netdev->trans_start = jiffies; /* Will netif_wake_queue() in callback */ + err = 0; /* No error */ goto drop; } } @@ -386,7 +393,7 @@ * Also, we don't use directly skb_cow(), because it require * headroom >= 16, which force unnecessary copies - Jean II */ if (skb_headroom(skb) < USB_IRDA_HEADER) { - IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), Insuficient skb headroom.\n", __FUNCTION__); if (skb_cow(skb, USB_IRDA_HEADER)) { WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); goto drop; @@ -478,7 +485,7 @@ /* Drop silently the skb and exit */ dev_kfree_skb(skb); spin_unlock_irqrestore(&self->lock, flags); - return 0; + return err; /* Usually 1 */ } /*------------------------------------------------------------------*/ @@ -494,10 +501,9 @@ IRDA_DEBUG(2, "%s()\n", __FUNCTION__); /* We should always have a context */ - if (self == NULL) { - WARNING("%s(), Bug : self == NULL\n", __FUNCTION__); - return; - } + ASSERT(self != NULL, return;); + /* We should always be called for the speed URB */ + ASSERT(purb == &self->tx_urb, return;); /* Free up the skb */ dev_kfree_skb_any(skb); @@ -530,10 +536,21 @@ return; } - /* If we need to change the speed or xbofs, do it now */ + /* If changes to speed or xbofs is pending... */ if ((self->new_speed != -1) || (self->new_xbofs != -1)) { - IRDA_DEBUG(1, "%s(), Changing speed now...\n", __FUNCTION__); - irda_usb_change_speed_xbofs(self); + if ((self->new_speed != self->speed) || + (self->new_xbofs != self->xbofs)) { + /* We haven't changed speed yet (because of + * IUC_SPEED_BUG), so do it now - Jean II */ + IRDA_DEBUG(1, __FUNCTION__ "(), Changing speed now...\n"); + irda_usb_change_speed_xbofs(self); + } else { + /* New speed and xbof is now commited in hardware */ + self->new_speed = -1; + self->new_xbofs = -1; + /* Done, waiting for next packet */ + netif_wake_queue(self->netdev); + } } else { /* Otherwise, allow the stack to send more packets */ netif_wake_queue(self->netdev); @@ -558,11 +575,13 @@ int done = 0; /* If we have made any progress */ IRDA_DEBUG(0, "%s(), Network layer thinks we timed out!\n", __FUNCTION__); + ASSERT(self != NULL, return;); /* Protect us from USB callbacks, net Tx and else. */ spin_lock_irqsave(&self->lock, flags); - if ((!self) || (!self->present)) { + /* self->present *MUST* be read under spinlock */ + if (!self->present) { WARNING("%s(), device not present!\n", __FUNCTION__); netif_stop_queue(netdev); spin_unlock_irqrestore(&self->lock, flags); @@ -677,36 +696,7 @@ /*------------------------------------------------------------------*/ /* * Submit a Rx URB to the USB layer to handle reception of a frame - * - * Important note : - * The function process_urb() in usb-uhci.c contains the following code : - * > urb->complete ((struct urb *) urb); - * > // Re-submit the URB if ring-linked - * > if (is_ring && (urb->status != -ENOENT) && !contains_killed) { - * > urb->dev=usb_dev; - * > uhci_submit_urb (urb); - * > } - * The way I see it is that if we submit more than one Rx URB at a - * time, the Rx URB can be automatically re-submitted after the - * completion handler is called. - * We make sure to disable this feature by setting urb->next to NULL - * - * My take is that it's a questionable feature, and quite difficult - * to control and to make work effectively. - * The outcome (re-submited or not) depend on various complex - * test ('is_ring' and 'contains_killed'), and the completion handler - * don't have this information, so basically the driver has no way - * to know if URB are resubmitted or not. Yuck ! - * If everything is perfect, it's cool, but the problem is when - * an URB is killed (timeout, call to unlink_urb(), ...), things get - * messy... - * The other problem is that this scheme deal only with the URB - * and ignore everything about the associated buffer. So, it would - * resubmit URB even if the buffer is still in use or non-existent. - * On the other hand, submitting ourself in the completion callback - * is quite trivial and work well (this function). - * Moreover, this scheme doesn't allow to have an idle URB, which is - * necessary to overcome some URB failures. + * Mostly called by the completion callback of the previous URB. * * Jean II */ @@ -1127,7 +1117,10 @@ /* Initialize QoS for this device */ irda_init_max_qos_capabilies(&self->qos); - self->qos.baud_rate.bits = desc->wBaudRate; + /* See spec section 7.2 for meaning. + * Values are little endian (as most USB stuff), the IrDA stack + * use it in native order (see parameters.c). - Jean II */ + self->qos.baud_rate.bits = le16_to_cpu(desc->wBaudRate); self->qos.min_turn_time.bits = desc->bmMinTurnaroundTime; self->qos.additional_bofs.bits = desc->bmAdditionalBOFs; self->qos.window_size.bits = desc->bmWindowSize; @@ -1138,7 +1131,7 @@ /* Don't always trust what the dongle tell us */ if(self->capability & IUC_SIR_ONLY) - self->qos.baud_rate.bits &= 0xff; + self->qos.baud_rate.bits &= 0x00ff; if(self->capability & IUC_SMALL_PKT) self->qos.data_size.bits = 0x07; if(self->capability & IUC_NO_WINDOW) @@ -1338,13 +1331,14 @@ */ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc) { + /* Values are little endian */ printk("bLength=%x\n", desc->bLength); printk("bDescriptorType=%x\n", desc->bDescriptorType); - printk("bcdSpecRevision=%x\n", desc->bcdSpecRevision); + printk("bcdSpecRevision=%x\n", le16_to_cpu(desc->bcdSpecRevision)); printk("bmDataSize=%x\n", desc->bmDataSize); printk("bmWindowSize=%x\n", desc->bmWindowSize); printk("bmMinTurnaroundTime=%d\n", desc->bmMinTurnaroundTime); - printk("wBaudRate=%x\n", desc->wBaudRate); + printk("wBaudRate=%x\n", le16_to_cpu(desc->wBaudRate)); printk("bmAdditionalBOFs=%x\n", desc->bmAdditionalBOFs); printk("bIrdaRateSniff=%x\n", desc->bIrdaRateSniff); printk("bMaxUnicastList=%x\n", desc->bMaxUnicastList); diff -urN linux-2.4.21/drivers/net/irda/ma600.c linux-2.4.22/drivers/net/irda/ma600.c --- linux-2.4.21/drivers/net/irda/ma600.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.22/drivers/net/irda/ma600.c 2003-08-25 04:44:42.000000000 -0700 @@ -51,9 +51,9 @@ #undef ASSERT(expr, func) #define ASSERT(expr, func) \ if(!(expr)) { \ - printk( "Assertion failed! %s,%s,%s,line=%d\n",\ - #expr,__FILE__,__FUNCTION__,__LINE__); \ - ##func} + printk( "Assertion failed! %s,%s,%s,line=%d\n",\ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + func} #endif /* convert hex value to ascii hex */ diff -urN linux-2.4.21/drivers/net/mac8390.c linux-2.4.22/drivers/net/mac8390.c --- linux-2.4.21/drivers/net/mac8390.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/mac8390.c 2003-08-25 04:44:42.000000000 -0700 @@ -380,7 +380,7 @@ #if LINUX_VERSION_CODE > 0x20118 MODULE_AUTHOR("David Huggins-Daines and others"); MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver"); -MODUEL_LICENSE("GPL"); +MODULE_LICENSE("GPL"); #endif int init_module(void) diff -urN linux-2.4.21/drivers/net/mace.c linux-2.4.22/drivers/net/mace.c --- linux-2.4.21/drivers/net/mace.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/mace.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,8 +1,12 @@ /* * Network device driver for the MACE ethernet controller on * Apple Powermacs. Assumes it's under a DBDMA controller. + * + * MACE is beleived to be an AMD 79C940 * * Copyright (C) 1996 Paul Mackerras. + * + * TODO: Use a spinlock for smp safety (backport 2.5 version ?) */ #include @@ -16,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -82,7 +88,10 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats *mace_stats(struct net_device *dev); static void mace_set_multicast(struct net_device *dev); +static int mace_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int mace_ethtool_ioctl(struct net_device *dev, void *useraddr); static void mace_reset(struct net_device *dev); +static void mace_restart(struct net_device *dev); static int mace_set_address(struct net_device *dev, void *addr); static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); @@ -226,6 +235,7 @@ dev->get_stats = mace_stats; dev->set_multicast_list = mace_set_multicast; dev->set_mac_address = mace_set_address; + dev->do_ioctl = mace_do_ioctl; ether_setup(dev); @@ -362,6 +372,90 @@ return 0; } +static int mace_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + switch(cmd) { + case SIOCETHTOOL: + return mace_ethtool_ioctl(dev, (void *) ifr->ifr_data); + + case SIOCGMIIPHY: /* Get address of MII PHY in use. */ + case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ + case SIOCGMIIREG: /* Read MII PHY register. */ + case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ + case SIOCSMIIREG: /* Write MII PHY register. */ + case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ + default: + return -EOPNOTSUPP; + } +} + +static int mace_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + struct mace_data *mp = (struct mace_data *) dev->priv; + u32 ethcmd; + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { .cmd = ETHTOOL_GDRVINFO }; + struct mace_data *mp = dev->priv; + strcpy (info.driver, "mace"); + info.version[0] = '\0'; + snprintf(info.fw_version, 31, "chip revision %d.%d", mp->chipid >> 8, mp->chipid & 0xff); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + case ETHTOOL_GSET: { + struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; + + cmd.supported = SUPPORTED_10baseT_Half | + SUPPORTED_AUI | + SUPPORTED_MII; + cmd.advertising = SUPPORTED_10baseT_Half; + cmd.port = mp->port_aaui ? PORT_AUI : PORT_MII; + cmd.speed = SPEED_10; + if (copy_to_user(useraddr, &cmd, sizeof(cmd))) + return -EFAULT; + return 0; + } + case ETHTOOL_SSET: { + struct ethtool_cmd cmd; + + if (copy_from_user(&cmd, useraddr, sizeof(cmd))) + return -EFAULT; + + if (cmd.autoneg != AUTONEG_DISABLE) + return -EINVAL; + if (cmd.speed != SPEED_10) + return -EINVAL; + if ((cmd.port == PORT_AUI) != mp->port_aaui) { + int aaui = (cmd.port == PORT_AUI); + unsigned long flags; + + printk("%s: switching port to: %s\n", + dev->name, aaui ? "AAUI" : "MII"); + mp->port_aaui = aaui; + save_flags(flags); + cli(); + mace_restart(dev); + restore_flags(flags); + } + return 0; + } + case ETHTOOL_NWAY_RST: + case ETHTOOL_GLINK: + case ETHTOOL_GMSGLVL: + case ETHTOOL_SMSGLVL: + default: + break; + } + + return -EOPNOTSUPP; +} + static int mace_open(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; @@ -473,10 +567,7 @@ static inline void mace_set_timeout(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; - unsigned long flags; - save_flags(flags); - cli(); if (mp->timeout_active) del_timer(&mp->tx_timeout); mp->tx_timeout.expires = jiffies + TX_TIMEOUT; @@ -484,7 +575,6 @@ mp->tx_timeout.data = (unsigned long) dev; add_timer(&mp->tx_timeout); mp->timeout_active = 1; - restore_flags(flags); } static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) @@ -763,31 +853,17 @@ } } -static void mace_tx_timeout(unsigned long data) +static void mace_restart(struct net_device *dev) { - struct net_device *dev = (struct net_device *) data; struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; volatile struct dbdma_regs *td = mp->tx_dma; volatile struct dbdma_regs *rd = mp->rx_dma; volatile struct dbdma_cmd *cp; - unsigned long flags; int i; - save_flags(flags); - cli(); - mp->timeout_active = 0; - if (mp->tx_active == 0 && !mp->tx_bad_runt) - goto out; - - /* update various counters */ - mace_handle_misc_intrs(mp, in_8(&mb->ir)); - - cp = mp->tx_cmds + NCMDS_TX * mp->tx_empty; - /* turn off both tx and rx and reset the chip */ out_8(&mb->maccc, 0); - printk(KERN_ERR "mace: transmit timeout - resetting\n"); dbdma_reset(td); mace_reset(dev); @@ -825,7 +901,29 @@ /* turn it back on */ out_8(&mb->imr, RCVINT); out_8(&mb->maccc, mp->maccc); +} + +static void mace_tx_timeout(unsigned long data) +{ + struct net_device *dev = (struct net_device *) data; + struct mace_data *mp = (struct mace_data *) dev->priv; + volatile struct mace *mb = mp->mace; + unsigned long flags; + + save_flags(flags); + cli(); + mp->timeout_active = 0; + if (mp->tx_active == 0 && !mp->tx_bad_runt) + goto out; + + /* update various counters */ + mace_handle_misc_intrs(mp, in_8(&mb->ir)); + + printk(KERN_ERR "mace: transmit timeout - resetting\n"); + /* Kick chip */ + mace_restart(dev); + out: restore_flags(flags); } diff -urN linux-2.4.21/drivers/net/macmace.c linux-2.4.22/drivers/net/macmace.c --- linux-2.4.21/drivers/net/macmace.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/macmace.c 2003-08-25 04:44:42.000000000 -0700 @@ -320,8 +320,8 @@ /* Allocate the DMA ring buffers */ - mp->rx_ring = (void *) __get_free_pages(GFP_DMA, N_RX_PAGES); - mp->tx_ring = (void *) __get_free_pages(GFP_DMA, 0); + mp->rx_ring = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, N_RX_PAGES); + mp->tx_ring = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, 0); if (mp->tx_ring==NULL || mp->rx_ring==NULL) { if (mp->rx_ring) free_pages((u32) mp->rx_ring, N_RX_PAGES); diff -urN linux-2.4.21/drivers/net/macsonic.c linux-2.4.22/drivers/net/macsonic.c --- linux-2.4.21/drivers/net/macsonic.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/macsonic.c 2003-08-25 04:44:42.000000000 -0700 @@ -142,7 +142,7 @@ int __init macsonic_init(struct net_device* dev) { - struct sonic_local* lp; + struct sonic_local* lp = NULL; int i; /* Allocate the entire chunk of memory for the descriptors. diff -urN linux-2.4.21/drivers/net/myri_sbus.c linux-2.4.22/drivers/net/myri_sbus.c --- linux-2.4.21/drivers/net/myri_sbus.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/myri_sbus.c 2003-08-25 04:44:42.000000000 -0700 @@ -764,10 +764,14 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh) { unsigned short type = hh->hh_type; - unsigned char *pad = (unsigned char *) hh->hh_data; - struct ethhdr *eth = (struct ethhdr *) (pad + MYRI_PAD_LEN); + unsigned char *pad; + struct ethhdr *eth; struct net_device *dev = neigh->dev; + pad = ((unsigned char *) hh->hh_data) + + HH_DATA_OFF(sizeof(*eth) + MYRI_PAD_LEN); + eth = (struct ethhdr *) (pad + MYRI_PAD_LEN); + if (type == __constant_htons(ETH_P_802_3)) return -1; @@ -786,7 +790,8 @@ /* Called by Address Resolution module to notify changes in address. */ void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) { - memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); + memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)), + haddr, dev->addr_len); } static int myri_change_mtu(struct net_device *dev, int new_mtu) diff -urN linux-2.4.21/drivers/net/ne2k-pci.c linux-2.4.22/drivers/net/ne2k-pci.c --- linux-2.4.21/drivers/net/ne2k-pci.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/ne2k-pci.c 2003-08-25 04:44:42.000000000 -0700 @@ -634,6 +634,7 @@ unregister_netdev(dev); release_region(dev->base_addr, NE_IO_EXTENT); + kfree(dev->priv); kfree(dev); pci_set_drvdata(pdev, NULL); } diff -urN linux-2.4.21/drivers/net/ns83820.c linux-2.4.22/drivers/net/ns83820.c --- linux-2.4.21/drivers/net/ns83820.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/ns83820.c 2003-08-25 04:44:42.000000000 -0700 @@ -1766,7 +1766,7 @@ int using_dac = 0; /* See if we can set the dma mask early on; failure is fatal. */ - if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffff)) { + if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) { using_dac = 1; } else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) { using_dac = 0; diff -urN linux-2.4.21/drivers/net/pci-skeleton.c linux-2.4.22/drivers/net/pci-skeleton.c --- linux-2.4.21/drivers/net/pci-skeleton.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/pci-skeleton.c 2003-08-25 04:44:42.000000000 -0700 @@ -602,7 +602,7 @@ *ioaddr_out = NULL; *dev_out = NULL; - /* dev zeroed in init_etherdev */ + /* dev zeroed in alloc_etherdev */ dev = alloc_etherdev (sizeof (*tp)); if (dev == NULL) { printk (KERN_ERR PFX "unable to alloc new ethernet\n"); @@ -789,7 +789,7 @@ dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; - /* dev->priv/tp zeroed and aligned in init_etherdev */ + /* dev->priv/tp zeroed and aligned in alloc_etherdev */ tp = dev->priv; /* note: tp->chipset set in netdrv_init_board */ diff -urN linux-2.4.21/drivers/net/pcmcia/aironet4500_cs.c linux-2.4.22/drivers/net/pcmcia/aironet4500_cs.c --- linux-2.4.21/drivers/net/pcmcia/aironet4500_cs.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/pcmcia/aironet4500_cs.c 2003-08-25 04:44:42.000000000 -0700 @@ -282,7 +282,7 @@ }; memset(dev,0,sizeof(struct net_device)); dev->priv = kmalloc(sizeof(struct awc_private), GFP_KERNEL); - if (!dev->priv ) {printk(KERN_CRIT "out of mem on dev priv alloc \n"); return NULL;}; + if (!dev->priv ) {printk(KERN_CRIT "out of mem on dev priv alloc \n"); kfree(dev); return NULL;}; memset(dev->priv,0,sizeof(struct awc_private)); // link->dev->minor = dev->minor; diff -urN linux-2.4.21/drivers/net/pcmcia/wavelan_cs.h linux-2.4.22/drivers/net/pcmcia/wavelan_cs.h --- linux-2.4.21/drivers/net/pcmcia/wavelan_cs.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/pcmcia/wavelan_cs.h 2003-08-25 04:44:42.000000000 -0700 @@ -489,7 +489,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 32 /* Dump packet on the screen */ +#undef DEBUG_PACKET_DUMP /* 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 */ diff -urN linux-2.4.21/drivers/net/pcnet32.c linux-2.4.22/drivers/net/pcnet32.c --- linux-2.4.21/drivers/net/pcnet32.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/pcnet32.c 2003-08-25 04:44:42.000000000 -0700 @@ -974,7 +974,9 @@ } skb_reserve (rx_skbuff, 2); } - lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, rx_skbuff->len, PCI_DMA_FROMDEVICE); + + if (lp->rx_dma_addr[i] == 0) + lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, rx_skbuff->len, PCI_DMA_FROMDEVICE); lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ); lp->rx_ring[i].status = le16_to_cpu(0x8000); @@ -1009,7 +1011,7 @@ /* ReInit Ring */ lp->a.write_csr (ioaddr, 0, 1); i = 0; - while (i++ < 100) + while (i++ < 1000) if (lp->a.read_csr (ioaddr, 0) & 0x0100) break; @@ -1100,6 +1102,7 @@ lp->tx_skbuff[entry] = skb; lp->tx_dma_addr[entry] = pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); lp->tx_ring[entry].base = (u32)le32_to_cpu(lp->tx_dma_addr[entry]); + wmb(); /* Make sure owner changes after all others are visible */ lp->tx_ring[entry].status = le16_to_cpu(status); lp->cur_tx++; diff -urN linux-2.4.21/drivers/net/plip.c linux-2.4.22/drivers/net/plip.c --- linux-2.4.21/drivers/net/plip.c 2001-09-30 12:26:07.000000000 -0700 +++ linux-2.4.22/drivers/net/plip.c 2003-08-25 04:44:42.000000000 -0700 @@ -1097,7 +1097,10 @@ if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0) { - struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2); + struct ethhdr *eth; + + eth = (struct ethhdr*)(((u8*)hh->hh_data) + + HH_DATA_OFF(sizeof(*eth))); plip_rewrite_address (neigh->dev, eth); } @@ -1177,7 +1180,7 @@ struct plip_local *rcv = &nl->rcv_data; netif_stop_queue (dev); - DISABLE(dev->irq); + disable_parport_interrupts(dev); synchronize_irq(); if (dev->irq == -1) diff -urN linux-2.4.21/drivers/net/ppp_deflate.c linux-2.4.22/drivers/net/ppp_deflate.c --- linux-2.4.21/drivers/net/ppp_deflate.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/ppp_deflate.c 2003-08-25 04:44:42.000000000 -0700 @@ -394,10 +394,10 @@ /* Check the sequence number. */ seq = (ibuf[PPP_HDRLEN] << 8) + ibuf[PPP_HDRLEN+1]; - if (seq != state->seqno) { + if (seq != (state->seqno & 0xffff)) { if (state->debug) printk(KERN_DEBUG "z_decompress%d: bad seq # %d, expected %d\n", - state->unit, seq, state->seqno); + state->unit, seq, state->seqno & 0xffff); return DECOMP_ERROR; } ++state->seqno; diff -urN linux-2.4.21/drivers/net/ppp_generic.c linux-2.4.22/drivers/net/ppp_generic.c --- linux-2.4.21/drivers/net/ppp_generic.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/ppp_generic.c 2003-08-25 04:44:42.000000000 -0700 @@ -666,8 +666,10 @@ if (code == 0) break; err = -EFAULT; - if (copy_from_user(code, uprog.filter, len)) + if (copy_from_user(code, uprog.filter, len)) { + kfree(code); break; + } err = sk_chk_filter(code, uprog.len); if (err) { kfree(code); diff -urN linux-2.4.21/drivers/net/pppoe.c linux-2.4.22/drivers/net/pppoe.c --- linux-2.4.21/drivers/net/pppoe.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/pppoe.c 2003-08-25 04:44:42.000000000 -0700 @@ -605,7 +605,8 @@ /* Delete the old binding */ delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote); - dev_put(po->pppoe_dev); + if(po->pppoe_dev) + dev_put(po->pppoe_dev); memset(po, 0, sizeof(struct pppox_opt)); po->sk = sk; diff -urN linux-2.4.21/drivers/net/r8169.c linux-2.4.22/drivers/net/r8169.c --- linux-2.4.21/drivers/net/r8169.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/r8169.c 2003-08-25 04:44:42.000000000 -0700 @@ -42,6 +42,7 @@ #include #include #include + #include #define RTL8169_VERSION "1.2" @@ -364,8 +365,8 @@ *ioaddr_out = NULL; *dev_out = NULL; - // dev zeroed in init_etherdev - dev = init_etherdev(NULL, sizeof (*tp)); + // dev zeroed in alloc_etherdev + dev = alloc_etherdev(sizeof (*tp)); if (dev == NULL) { printk(KERN_ERR PFX "unable to alloc new ethernet\n"); return -ENOMEM; @@ -389,18 +390,18 @@ printk(KERN_ERR PFX "region #1 not an MMIO resource, aborting\n"); rc = -ENODEV; - goto err_out; + goto err_out_disable; } // check for weird/broken PCI region reporting if (mmio_len < RTL_MIN_IO_SIZE) { printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n"); rc = -ENODEV; - goto err_out; + goto err_out_disable; } rc = pci_request_regions(pdev, dev->name); if (rc) - goto err_out; + goto err_out_disable; // enable PCI bus-mastering pci_set_master(pdev); @@ -448,8 +449,10 @@ err_out_free_res: pci_release_regions(pdev); +err_out_disable: + pci_disable_device(pdev); + err_out: - unregister_netdev(dev); kfree(dev); return rc; } @@ -462,7 +465,7 @@ void *ioaddr = NULL; static int board_idx = -1; static int printed_version = 0; - int i; + int i, rc; int option = -1, Cap10_100 = 0, Cap1000 = 0; assert(pdev != NULL); @@ -475,20 +478,18 @@ printed_version = 1; } - i = rtl8169_init_board(pdev, &dev, &ioaddr); - if (i < 0) { - return i; - } + rc = rtl8169_init_board(pdev, &dev, &ioaddr); + if (rc) + return rc; tp = dev->priv; assert(ioaddr != NULL); assert(dev != NULL); assert(tp != NULL); - // Get MAC address // - for (i = 0; i < MAC_ADDR_LEN; i++) { + // Get MAC address. FIXME: read EEPROM + for (i = 0; i < MAC_ADDR_LEN; i++) dev->dev_addr[i] = RTL_R8(MAC0 + i); - } dev->open = rtl8169_open; dev->hard_start_xmit = rtl8169_start_xmit; @@ -505,11 +506,20 @@ tp->pci_dev = pdev; tp->mmio_addr = ioaddr; + spin_lock_init(&tp->lock); + + rc = register_netdev(dev); + if (rc) { + iounmap(ioaddr); + pci_release_regions(pdev); + pci_disable_device(pdev); + kfree(dev); + return rc; + } + printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name, rtl_chip_info[tp->chipset].name); - spin_lock_init(&tp->lock); - pci_set_drvdata(pdev, dev); printk(KERN_INFO "%s: %s at 0x%lx, " @@ -621,7 +631,7 @@ rtl8169_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = (struct rtl8169_private *) (dev->priv); + struct rtl8169_private *tp = dev->priv; assert(dev != NULL); assert(tp != NULL); @@ -634,6 +644,7 @@ memset(dev, 0xBC, sizeof (struct net_device) + sizeof (struct rtl8169_private)); + pci_disable_device(pdev); kfree(dev); pci_set_drvdata(pdev, NULL); } @@ -821,10 +832,9 @@ void *ioaddr = tp->mmio_addr; int entry = tp->cur_tx % NUM_TX_DESC; - if(skb->len < ETH_ZLEN) - { + if (skb->len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); - if(skb == NULL) + if (skb == NULL) return 0; } diff -urN linux-2.4.21/drivers/net/rcpci45.c linux-2.4.22/drivers/net/rcpci45.c --- linux-2.4.21/drivers/net/rcpci45.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/rcpci45.c 2003-08-25 04:44:42.000000000 -0700 @@ -75,10 +75,6 @@ #define NEW_MULTICAST -/* PCI/45 Configuration space values */ -#define RC_PCI45_VENDOR_ID 0x4916 -#define RC_PCI45_DEVICE_ID 0x1960 - #define MAX_ETHER_SIZE 1520 #define MAX_NMBR_RCV_BUFFERS 96 #define RC_POSTED_BUFFERS_LOW_MARK MAX_NMBR_RCV_BUFFERS-16 @@ -116,7 +112,7 @@ static int RC_allocate_and_post_buffers (struct net_device *, int); static struct pci_device_id rcpci45_pci_table[] __devinitdata = { - {RC_PCI45_VENDOR_ID, RC_PCI45_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + { PCI_VENDOR_ID_REDCREEK, PCI_DEVICE_ID_RC45, PCI_ANY_ID, PCI_ANY_ID,}, {} }; MODULE_DEVICE_TABLE (pci, rcpci45_pci_table); @@ -206,7 +202,7 @@ * messages. Thus, we need contiguous physical pages of * memory. */ - pDpa->msgbuf = kmalloc (MSG_BUF_SIZE, GFP_DMA|GFP_ATOMIC|GFP_KERNEL); + pDpa->msgbuf = kmalloc (MSG_BUF_SIZE, GFP_DMA | GFP_KERNEL); if (!pDpa->msgbuf) { printk (KERN_ERR "(rcpci45 driver:) \ Could not allocate %d byte memory for the \ @@ -999,7 +995,7 @@ } p = (PU32) kmalloc (sizeof (U32) + numBuffers * sizeof (singleB), - GFP_DMA|GFP_ATOMIC|GFP_KERNEL); + GFP_DMA | GFP_ATOMIC); if (!p) { printk (KERN_WARNING "%s unable to allocate TCB\n", diff -urN linux-2.4.21/drivers/net/sis900.c linux-2.4.22/drivers/net/sis900.c --- linux-2.4.21/drivers/net/sis900.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/sis900.c 2003-08-25 04:44:42.000000000 -0700 @@ -201,7 +201,7 @@ static int sis900_close(struct net_device *net_dev); static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd); static struct net_device_stats *sis900_get_stats(struct net_device *net_dev); -static u16 sis900_compute_hashtable_index(u8 *addr, u8 revision); +static u16 sis900_mcast_bitnr(u8 *addr, u8 revision); static void set_rx_mode(struct net_device *net_dev); static void sis900_reset(struct net_device *net_dev); static void sis630_set_eq(struct net_device *net_dev, u8 revision); @@ -213,7 +213,7 @@ static void sis900_set_mode (long ioaddr, int speed, int duplex); /** - * sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model + * sis900_get_mac_addr - Get MAC address for stand alone SiS900 model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * @@ -243,7 +243,7 @@ } /** - * sis630e_get_mac_addr: - Get MAC address for SiS630E model + * sis630e_get_mac_addr - Get MAC address for SiS630E model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * @@ -276,7 +276,7 @@ /** - * sis635_get_mac_addr: - Get MAC address for SIS635 model + * sis635_get_mac_addr - Get MAC address for SIS635 model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * @@ -312,7 +312,7 @@ } /** - * sis96x_get_mac_addr: - Get MAC address for SiS962 or SiS963 model + * sis96x_get_mac_addr - Get MAC address for SiS962 or SiS963 model * @pci_dev: the sis900 pci device * @net_dev: the net device to get address for * @@ -354,7 +354,7 @@ } /** - * sis900_probe: - Probe for sis900 device + * sis900_probe - Probe for sis900 device * @pci_dev: the sis900 pci device * @pci_id: the pci device ID * @@ -499,7 +499,7 @@ } /** - * sis900_mii_probe: - Probe MII PHY for sis900 + * sis900_mii_probe - Probe MII PHY for sis900 * @net_dev: the net device to probe for * * Search for total of 32 possible mii phy addresses. @@ -528,7 +528,7 @@ mii_status = mdio_read(net_dev, phy_addr, MII_STATUS); if (mii_status == 0xffff || mii_status == 0x0000) - /* the mii is not accessable, try next one */ + /* the mii is not accessible, try next one */ continue; if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) { @@ -593,7 +593,7 @@ current->state = TASK_INTERRUPTIBLE; schedule_timeout(0); poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit); - if (jiffies >= timeout) { + if (time_after_eq(jiffies, timeout)) { printk(KERN_WARNING "%s: reset phy and link down now\n", net_dev->name); return -ETIME; } @@ -619,7 +619,7 @@ } /** - * sis900_default_phy: - Select default PHY for sis900 mac. + * sis900_default_phy - Select default PHY for sis900 mac. * @net_dev: the net device to probe for * * Select first detected PHY with link as default. @@ -672,7 +672,7 @@ /** - * sis900_set_capability: - set the media capability of network adapter. + * sis900_set_capability - set the media capability of network adapter. * @net_dev : the net device to probe for * @phy : default PHY * @@ -702,7 +702,7 @@ #define eeprom_delay() inl(ee_addr) /** - * read_eeprom: - Read Serial EEPROM + * read_eeprom - Read Serial EEPROM * @ioaddr: base i/o address * @location: the EEPROM location to read * @@ -752,7 +752,7 @@ /* Read and write the MII management registers using software-generated serial MDIO protocol. Note that the command bits and data bits are - send out seperately */ + send out separately */ #define mdio_delay() inl(mdio_addr) static void mdio_idle(long mdio_addr) @@ -777,7 +777,7 @@ } /** - * mdio_read: - read MII PHY register + * mdio_read - read MII PHY register * @net_dev: the net device to read * @phy_id: the phy address to read * @location: the phy regiester id to read @@ -819,7 +819,7 @@ } /** - * mdio_write: - write MII PHY register + * mdio_write - write MII PHY register * @net_dev: the net device to write * @phy_id: the phy address to write * @location: the phy regiester id to write @@ -873,7 +873,7 @@ /** - * sis900_reset_phy: - reset sis900 mii phy. + * sis900_reset_phy - reset sis900 mii phy. * @net_dev: the net device to write * @phy_addr: default phy address * @@ -896,7 +896,7 @@ } /** - * sis900_open: - open sis900 device + * sis900_open - open sis900 device * @net_dev: the net device to open * * Do some initialization and start net interface. @@ -953,7 +953,7 @@ } /** - * sis900_init_rxfilter: - Initialize the Rx filter + * sis900_init_rxfilter - Initialize the Rx filter * @net_dev: the net device to initialize for * * Set receive filter address to our MAC address @@ -991,7 +991,7 @@ } /** - * sis900_init_tx_ring: - Initialize the Tx descriptor ring + * sis900_init_tx_ring - Initialize the Tx descriptor ring * @net_dev: the net device to initialize for * * Initialize the Tx descriptor ring, @@ -1024,7 +1024,7 @@ } /** - * sis900_init_rx_ring: - Initialize the Rx descriptor ring + * sis900_init_rx_ring - Initialize the Rx descriptor ring * @net_dev: the net device to initialize for * * Initialize the Rx descriptor ring, @@ -1078,7 +1078,7 @@ } /** - * sis630_set_eq: - set phy equalizer value for 630 LAN + * sis630_set_eq - set phy equalizer value for 630 LAN * @net_dev: the net device to set equalizer value * @revision: 630 LAN revision number * @@ -1166,7 +1166,7 @@ } /** - * sis900_timer: - sis900 timer routine + * sis900_timer - sis900 timer routine * @data: pointer to sis900 net device * * On each timer ticks we check two things, @@ -1236,7 +1236,7 @@ } /** - * sis900_check_mode: - check the media mode for sis900 + * sis900_check_mode - check the media mode for sis900 * @net_dev: the net device to be checked * @mii_phy: the mii phy * @@ -1267,7 +1267,7 @@ } /** - * sis900_set_mode: - Set the media mode of mac register. + * sis900_set_mode - Set the media mode of mac register. * @ioaddr: the address of the device * @speed : the transmit speed to be determined * @duplex: the duplex mode to be determined @@ -1311,7 +1311,7 @@ } /** - * sis900_auto_negotiate: Set the Auto-Negotiation Enable/Reset bit. + * sis900_auto_negotiate - Set the Auto-Negotiation Enable/Reset bit. * @net_dev: the net device to read mode for * @phy_addr: mii phy address * @@ -1345,7 +1345,7 @@ /** - * sis900_read_mode: - read media mode for sis900 internal phy + * sis900_read_mode - read media mode for sis900 internal phy * @net_dev: the net device to read mode for * @speed : the transmit speed to be determined * @duplex : the duplex mode to be determined @@ -1402,7 +1402,7 @@ } /** - * sis900_tx_timeout: - sis900 transmit timeout routine + * sis900_tx_timeout - sis900 transmit timeout routine * @net_dev: the net device to transmit * * print transmit timeout status @@ -1457,7 +1457,7 @@ } /** - * sis900_start_xmit: - sis900 start transmit routine + * sis900_start_xmit - sis900 start transmit routine * @skb: socket buffer pointer to put the data being transmitted * @net_dev: the net device to transmit with * @@ -1527,7 +1527,7 @@ } /** - * sis900_interrupt: - sis900 interrupt handler + * sis900_interrupt - sis900 interrupt handler * @irq: the irq number * @dev_instance: the client data object * @regs: snapshot of processor context @@ -1586,7 +1586,7 @@ } /** - * sis900_rx: - sis900 receive routine + * sis900_rx - sis900 receive routine * @net_dev: the net device which receives data * * Process receive interrupt events, @@ -1725,7 +1725,7 @@ } /** - * sis900_finish_xmit: - finish up transmission of packets + * sis900_finish_xmit - finish up transmission of packets * @net_dev: the net device to be transmitted on * * Check for error condition and free socket buffer etc @@ -1795,7 +1795,7 @@ } /** - * sis900_close: - close sis900 device + * sis900_close - close sis900 device * @net_dev: the net device to be closed * * Disable interrupts, stop the Tx and Rx Status Machine @@ -1851,7 +1851,7 @@ } /** - * netdev_ethtool_ioctl: - For the basic support of ethtool + * netdev_ethtool_ioctl - For the basic support of ethtool * @net_dev: the net device to command for * @useraddr: start address of interface request * @@ -1885,7 +1885,7 @@ } /** - * mii_ioctl: - process MII i/o control command + * mii_ioctl - process MII i/o control command * @net_dev: the net device to command for * @rq: parameter for command * @cmd: the i/o command @@ -1924,7 +1924,7 @@ } /** - * sis900_get_stats: - Get sis900 read/write statistics + * sis900_get_stats - Get sis900 read/write statistics * @net_dev: the net device to get statistics for * * get tx/rx statistics for sis900 @@ -1939,7 +1939,7 @@ } /** - * sis900_set_config: - Set media type by net_device.set_config + * sis900_set_config - Set media type by net_device.set_config * @dev: the net device for media type change * @map: ifmap passed by ifconfig * @@ -1976,7 +1976,7 @@ status = mdio_read(dev, mii_phy->phy_addr, MII_CONTROL); /* enable auto negotiation and reset the negotioation - (I dont really know what the auto negatiotiation reset + (I don't really know what the auto negatiotiation reset really means, but it sounds for me right to do one here)*/ mdio_write(dev, mii_phy->phy_addr, MII_CONTROL, status | MII_CNTL_AUTO | MII_CNTL_RST_AUTO); @@ -2036,7 +2036,7 @@ } /** - * sis900_compute_hashtable_index: - compute hashtable index + * sis900_mcast_bitnr - compute hashtable index * @addr: multicast address * @revision: revision id of chip * @@ -2046,7 +2046,7 @@ * multicast hash table. */ -static u16 sis900_compute_hashtable_index(u8 *addr, u8 revision) +static inline u16 sis900_mcast_bitnr(u8 *addr, u8 revision) { u32 crc = ether_crc(6, addr); @@ -2059,7 +2059,7 @@ } /** - * set_rx_mode: - Set SiS900 receive mode + * set_rx_mode - Set SiS900 receive mode * @net_dev: the net device to be set * * Set SiS900 receive mode for promiscuous, multicast, or broadcast mode. @@ -2100,9 +2100,11 @@ struct dev_mc_list *mclist; rx_mode = RFAAB; for (i = 0, mclist = net_dev->mc_list; mclist && i < net_dev->mc_count; - i++, mclist = mclist->next) - set_bit(sis900_compute_hashtable_index(mclist->dmi_addr, revision), - mc_filter); + i++, mclist = mclist->next) { + unsigned int bit_nr = + sis900_mcast_bitnr(mclist->dmi_addr, revision); + mc_filter[bit_nr >> 4] |= (1 << bit_nr); + } } /* update Multicast Hash Table in Receive Filter */ @@ -2131,7 +2133,7 @@ } /** - * sis900_reset: - Reset sis900 MAC + * sis900_reset - Reset sis900 MAC * @net_dev: the net device to reset * * reset sis900 MAC and wait until finished @@ -2166,7 +2168,7 @@ } /** - * sis900_remove: - Remove sis900 device + * sis900_remove - Remove sis900 device * @pci_dev: the pci device to be removed * * remove and release SiS900 net device @@ -2195,10 +2197,10 @@ } static struct pci_driver sis900_pci_driver = { - name: SIS900_MODULE_NAME, - id_table: sis900_pci_tbl, - probe: sis900_probe, - remove: __devexit_p(sis900_remove), + .name = SIS900_MODULE_NAME, + .id_table = sis900_pci_tbl, + .probe = sis900_probe, + .remove = __devexit_p(sis900_remove), }; static int __init sis900_init_module(void) diff -urN linux-2.4.21/drivers/net/sk98lin/skge.c linux-2.4.22/drivers/net/sk98lin/skge.c --- linux-2.4.21/drivers/net/sk98lin/skge.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/sk98lin/skge.c 2003-08-25 04:44:42.000000000 -0700 @@ -498,7 +498,7 @@ } /* Configure DMA attributes. */ - if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) && + if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) && pci_set_dma_mask(pdev, (u64) 0xffffffff)) continue; diff -urN linux-2.4.21/drivers/net/skfp/fplustm.c linux-2.4.22/drivers/net/skfp/fplustm.c --- linux-2.4.21/drivers/net/skfp/fplustm.c 2001-03-20 12:04:59.000000000 -0800 +++ linux-2.4.22/drivers/net/skfp/fplustm.c 2003-08-25 04:44:42.000000000 -0700 @@ -390,7 +390,7 @@ outpw(FM_A(FM_TREQ0),(unsigned)t_requ) ; } -void set_int(p,l) +static void set_int(p,l) char *p; int l; { diff -urN linux-2.4.21/drivers/net/sonic.c linux-2.4.22/drivers/net/sonic.c --- linux-2.4.21/drivers/net/sonic.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/sonic.c 2003-08-25 04:44:42.000000000 -0700 @@ -113,15 +113,6 @@ if (sonic_debug > 2) printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev); - /* - * Block a timer-based transmit from overlapping. This could better be - * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. - */ - if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) { - printk("%s: Transmitter access conflict.\n", dev->name); - return 1; - } - /* * Map the packet data into the logical DMA address space */ diff -urN linux-2.4.21/drivers/net/sundance.c linux-2.4.22/drivers/net/sundance.c --- linux-2.4.21/drivers/net/sundance.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/sundance.c 2003-08-25 04:44:42.000000000 -0700 @@ -71,19 +71,36 @@ Versin LK1.06b (D-Link): - New tx scheme, adaptive tx_coalesce + + Version LK1.07 (D-Link): + - Fix tx bugs in big-endian machines + - Remove unused max_interrupt_work module parameter, the new + NAPI-like rx scheme doesn't need it. + - Remove redundancy get_stats() in intr_handler(), those + I/O access could affect performance in ARM-based system + - Add Linux software VLAN support + + Version LK1.08 (D-Link): + - Fix bug of custom mac address + (StationAddr register only accept word write) + + Version LK1.09 (D-Link): + - Fix the flowctrl bug. + - Set Pause bit in MII ANAR if flow control enabled. + + Version LK1.09a (ICPlus): + - Add the delay time in reading the contents of EEPROM */ #define DRV_NAME "sundance" -#define DRV_VERSION "1.01+LK1.06b" -#define DRV_RELDATE "6-Nov-2002" +#define DRV_VERSION "1.01+LK1.09a" +#define DRV_RELDATE "10-Jul-2003" /* The user-configurable values. These may be modified when a driver module is loaded.*/ static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ -/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static int max_interrupt_work = 0; /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). Typical is a 64 element hash table based on the Ethernet CRC. */ static int multicast_filter_limit = 32; @@ -129,8 +146,7 @@ /* Operational parameters that usually are not changed. */ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (4*HZ) - -#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ #ifndef __KERNEL__ #define __KERNEL__ @@ -181,12 +197,10 @@ MODULE_DESCRIPTION("Sundance Alta Ethernet driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(rx_copybreak, "i"); MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "s"); MODULE_PARM(flowctrl, "i"); -MODULE_PARM_DESC(max_interrupt_work, "Sundance Alta maximum events handled per interrupt"); MODULE_PARM_DESC(debug, "Sundance Alta debug level (0-5)"); MODULE_PARM_DESC(rx_copybreak, "Sundance Alta copy breakpoint for copy-only-tiny-frames"); MODULE_PARM_DESC(flowctrl, "Sundance Alta flow control [0|1]"); @@ -502,6 +516,7 @@ static void netdev_error(struct net_device *dev, int intr_status); static void netdev_error(struct net_device *dev, int intr_status); static void set_rx_mode(struct net_device *dev); +static int __set_mac_addr(struct net_device *dev); static struct net_device_stats *get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int netdev_close(struct net_device *dev); @@ -662,8 +677,8 @@ np->an_enable = 1; } } - if (flowctrl == 0) - np->flowctrl = 0; + if (flowctrl == 1) + np->flowctrl = 1; } /* Fibre PHY? */ @@ -678,6 +693,9 @@ /* Reset PHY */ mdio_write (dev, np->phys[0], MII_BMCR, BMCR_RESET); mdelay (300); + /* If flow control enabled, we need to advertise it.*/ + if (np->flowctrl) + mdio_write (dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising | 0x0400); mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART); /* Force media type */ if (!np->an_enable) { @@ -729,12 +747,14 @@ return 0; } +#define eeprom_delay(ee_addr) readl(ee_addr) /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */ static int __devinit eeprom_read(long ioaddr, int location) { - int boguscnt = 1000; /* Typical 190 ticks. */ + int boguscnt = 10000; /* Typical 1900 ticks. */ writew(0x0200 | (location & 0xff), ioaddr + EECtrl); do { + eeprom_delay(ioaddr + EECtrl); if (! (readw(ioaddr + EECtrl) & 0x8000)) { return readw(ioaddr + EEData); } @@ -847,17 +867,18 @@ if (netif_msg_ifup(np)) printk(KERN_DEBUG "%s: netdev_open() irq %d.\n", dev->name, dev->irq); - init_ring(dev); writel(np->rx_ring_dma, ioaddr + RxListPtr); /* The Tx list pointer is written as packets are queued. */ - for (i = 0; i < 6; i++) - writeb(dev->dev_addr[i], ioaddr + StationAddr + i); - /* Initialize other registers. */ + __set_mac_addr(dev); +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + writew(dev->mtu + 18, ioaddr + MaxFrameSize); +#else writew(dev->mtu + 14, ioaddr + MaxFrameSize); +#endif if (dev->mtu > 2047) writel(readl(ioaddr + ASICCtrl) | 0x0C, ioaddr + ASICCtrl); @@ -879,7 +900,7 @@ writeb(0x01, ioaddr + DebugCtrl1); netif_start_queue(dev); - writew(StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1); + writew (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1); if (netif_msg_ifup(np)) printk(KERN_DEBUG "%s: Done netdev_open(), status: Rx %x Tx %x " @@ -925,7 +946,7 @@ printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d " "negotiated capability %4.4x.\n", dev->name, duplex ? "full" : "half", np->phys[0], negotiated); - writew(duplex ? 0x20 : 0, ioaddr + MACCtrl0); + writew(readw(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0); } } @@ -951,7 +972,7 @@ { struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; - long flag; + unsigned long flag; netif_stop_queue(dev); tasklet_disable(&np->tx_tasklet); @@ -966,11 +987,11 @@ for (i=0; itx_ring_dma + i*sizeof(*np->tx_ring), - np->tx_ring[i].next_desc, - np->tx_ring[i].status, - (np->tx_ring[i].status >> 2) & 0xff, - np->tx_ring[i].frag[0].addr, - np->tx_ring[i].frag[0].length); + le32_to_cpu(np->tx_ring[i].next_desc), + le32_to_cpu(np->tx_ring[i].status), + (le32_to_cpu(np->tx_ring[i].status) >> 2) & 0xff, + le32_to_cpu(np->tx_ring[i].frag[0].addr), + le32_to_cpu(np->tx_ring[i].frag[0].length)); } printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n", readl(dev->base_addr + TxListPtr), @@ -1157,7 +1178,6 @@ struct net_device *dev = (struct net_device *)dev_instance; struct netdev_private *np; long ioaddr; - int boguscnt = max_interrupt_work; int hw_frame_id; int tx_cnt; int tx_status; @@ -1226,11 +1246,14 @@ int entry = np->dirty_tx % TX_RING_SIZE; struct sk_buff *skb; int sw_frame_id; - sw_frame_id = (np->tx_ring[entry].status >> 2) & 0xff; - if (sw_frame_id == hw_frame_id && - !(np->tx_ring[entry].status & 0x00010000)) + sw_frame_id = (le32_to_cpu( + np->tx_ring[entry].status) >> 2) & 0xff; + if (sw_frame_id == hw_frame_id && + !(le32_to_cpu(np->tx_ring[entry].status) + & 0x00010000)) break; - if (sw_frame_id == (hw_frame_id + 1) % TX_RING_SIZE) + if (sw_frame_id == (hw_frame_id + 1) % + TX_RING_SIZE) break; skb = np->tx_skbuff[entry]; /* Free the original skb. */ @@ -1248,7 +1271,8 @@ for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) { int entry = np->dirty_tx % TX_RING_SIZE; struct sk_buff *skb; - if (!(np->tx_ring[entry].status & 0x00010000)) + if (!(le32_to_cpu(np->tx_ring[entry].status) + & 0x00010000)) break; skb = np->tx_skbuff[entry]; /* Free the original skb. */ @@ -1271,15 +1295,7 @@ /* Abnormal error summary/uncommon events handlers. */ if (intr_status & (IntrPCIErr | LinkChange | StatsMax)) netdev_error(dev, intr_status); - if (--boguscnt < 0) { - get_stats(dev); - if (netif_msg_hw(np)) - printk(KERN_WARNING "%s: Too much work at interrupt, " - "status=0x%4.4x / 0x%4.4x.\n", - dev->name, intr_status, readw(ioaddr + IntrClear)); - break; - } - } while (1); + } while (0); if (netif_msg_intr(np)) printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", dev->name, readw(ioaddr + IntrStatus)); @@ -1447,9 +1463,12 @@ "full" : "half"); } check_duplex (dev); - if (np->flowctrl == 0) - writew(readw(ioaddr + MACCtrl0) & ~EnbFlowCtrl, + if (np->flowctrl && np->mii_if.full_duplex) { + writew(readw(ioaddr + MulticastFilter1+2) | 0x0200, + ioaddr + MulticastFilter1+2); + writew(readw(ioaddr + MACCtrl0) | EnbFlowCtrl, ioaddr + MACCtrl0); + } } if (intr_status & StatsMax) { get_stats(dev); @@ -1463,8 +1482,8 @@ static struct net_device_stats *get_stats(struct net_device *dev) { - long ioaddr = dev->base_addr; struct netdev_private *np = dev->priv; + long ioaddr = dev->base_addr; int i; /* We should lock this segment of code for SMP eventually, although @@ -1477,7 +1496,7 @@ np->stats.collisions += readb(ioaddr + StatsLateColl); np->stats.collisions += readb(ioaddr + StatsMultiColl); np->stats.collisions += readb(ioaddr + StatsOneColl); - readb(ioaddr + StatsCarrierError); + np->stats.tx_carrier_errors += readb(ioaddr + StatsCarrierError); readb(ioaddr + StatsTxDefer); for (i = StatsTxDefer; i <= StatsMcastRx; i++) readb(ioaddr + i); @@ -1492,6 +1511,7 @@ static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; + struct netdev_private *np = dev->priv; u16 mc_filter[4]; /* Multicast hash filter */ u32 rx_mode; int i; @@ -1524,11 +1544,28 @@ writeb(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode); return; } + if (np->mii_if.full_duplex && np->flowctrl) + mc_filter[3] |= 0x0200; + for (i = 0; i < 4; i++) writew(mc_filter[i], ioaddr + MulticastFilter0 + i*2); writeb(rx_mode, ioaddr + RxMode); } +static int __set_mac_addr(struct net_device *dev) +{ + u16 addr16; + + addr16 = (dev->dev_addr[0] | (dev->dev_addr[1] << 8)); + writew(addr16, dev->base_addr + StationAddr); + addr16 = (dev->dev_addr[2] | (dev->dev_addr[3] << 8)); + writew(addr16, dev->base_addr + StationAddr+2); + addr16 = (dev->dev_addr[4] | (dev->dev_addr[5] << 8)); + writew(addr16, dev->base_addr + StationAddr+4); + return 0; +} + + static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) { struct netdev_private *np = dev->priv; @@ -1615,6 +1652,7 @@ struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data; int rc; int i; + long ioaddr = dev->base_addr; if (!netif_running(dev)) return -EINVAL; @@ -1632,11 +1670,12 @@ for (i=0; itx_ring_dma + i*sizeof(*np->tx_ring), - np->tx_ring[i].next_desc, - np->tx_ring[i].status, - (np->tx_ring[i].status >> 2) & 0xff, - np->tx_ring[i].frag[0].addr, - np->tx_ring[i].frag[0].length); + le32_to_cpu(np->tx_ring[i].next_desc), + le32_to_cpu(np->tx_ring[i].status), + (le32_to_cpu(np->tx_ring[i].status) >> 2) + & 0xff, + le32_to_cpu(np->tx_ring[i].frag[0].addr), + le32_to_cpu(np->tx_ring[i].frag[0].length)); } printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n", readl(dev->base_addr + TxListPtr), @@ -1646,6 +1685,7 @@ np->dirty_tx, np->dirty_tx % TX_RING_SIZE); printk(KERN_DEBUG "cur_rx=%d dirty_rx=%d\n", np->cur_rx, np->dirty_rx); printk(KERN_DEBUG "cur_task=%d\n", np->cur_task); + printk(KERN_DEBUG "TxStatus=%04x\n", readw(ioaddr + TxStatus)); return 0; } @@ -1753,10 +1793,10 @@ } static struct pci_driver sundance_driver = { - name: DRV_NAME, - id_table: sundance_pci_tbl, - probe: sundance_probe1, - remove: __devexit_p(sundance_remove1), + .name = DRV_NAME, + .id_table = sundance_pci_tbl, + .probe = sundance_probe1, + .remove = __devexit_p(sundance_remove1), }; static int __init sundance_init(void) diff -urN linux-2.4.21/drivers/net/sungem.c linux-2.4.22/drivers/net/sungem.c --- linux-2.4.21/drivers/net/sungem.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/sungem.c 2003-08-25 04:44:42.000000000 -0700 @@ -2616,9 +2616,6 @@ return 0; case ETHTOOL_SSET: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Verify the settings we care about. */ if (ecmd.autoneg != AUTONEG_ENABLE && ecmd.autoneg != AUTONEG_DISABLE) diff -urN linux-2.4.21/drivers/net/sunhme.c linux-2.4.22/drivers/net/sunhme.c --- linux-2.4.21/drivers/net/sunhme.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/sunhme.c 2003-08-25 04:44:42.000000000 -0700 @@ -2480,9 +2480,6 @@ return -EFAULT; return 0; } else if (ecmd.cmd == ETHTOOL_SSET) { - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Verify the settings we care about. */ if (ecmd.autoneg != AUTONEG_ENABLE && ecmd.autoneg != AUTONEG_DISABLE) @@ -2801,8 +2798,8 @@ dev->watchdog_timeo = 5*HZ; dev->do_ioctl = &happy_meal_ioctl; - /* Happy Meal can do it all... */ - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; + /* Happy Meal can do it all... except VLAN. */ + dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_VLAN_CHALLENGED; dev->irq = sdev->irqs[0]; @@ -3091,8 +3088,12 @@ #ifdef __sparc__ hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); - if (hp->hm_revision == 0xff) - hp->hm_revision = 0xa0; + if (hp->hm_revision == 0xff) { + unsigned char prev; + + pci_read_config_byte(pdev, PCI_REVISION_ID, &prev); + hp->hm_revision = 0xc0 | (prev & 0x0f); + } #else /* works with this on non-sparc hosts */ hp->hm_revision = 0x20; @@ -3101,7 +3102,7 @@ /* Now enable the feature flags we can. */ if (hp->hm_revision == 0x20 || hp->hm_revision == 0x21) hp->happy_flags = HFLAG_20_21; - else if (hp->hm_revision != 0xa0) + else if (hp->hm_revision != 0xa0 && hp->hm_revision != 0xc0) hp->happy_flags = HFLAG_NOT_A0; if (qp != NULL) diff -urN linux-2.4.21/drivers/net/tc35815.c linux-2.4.22/drivers/net/tc35815.c --- linux-2.4.21/drivers/net/tc35815.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/tc35815.c 2003-08-25 04:44:42.000000000 -0700 @@ -7,9 +7,6 @@ * Based on skelton.c by Donald Becker. * Copyright (C) 2000-2001 Toshiba Corporation * - * Cleaned up various non portable stuff (save_and_cli etc) and made it - * build on x86 platforms -- Alan Cox 20020302 - * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -29,13 +26,10 @@ * You 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. - * - * TODO: - * Switch to spin_lock not lock_kernel for scalability. */ static const char *version = - "tc35815.c:v0.00-ac 26/07/2000 by Toshiba Corporation\n"; + "tc35815.c:v0.00 26/07/2000 by Toshiba Corporation\n"; #include @@ -405,14 +399,8 @@ }; -#if defined(__mips__) -/* MIPS weirdness */ extern unsigned long tc_readl(volatile __u32 *addr); extern void tc_writel(unsigned long data, volatile __u32 *addr); -#else -#define tc_readl readl -#define tc_writel writel -#endif dma_addr_t priv_dma_handle; @@ -477,6 +465,7 @@ static void tc35815_chip_reset(struct net_device *dev); static void tc35815_chip_init(struct net_device *dev); static void tc35815_phy_chip_init(struct net_device *dev); +static int tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data); /* A list of all installed tc35815 devices. */ static struct net_device *root_tc35815_dev = NULL; @@ -507,7 +496,7 @@ return -ENODEV; if (pdev) { - unsigned long pci_memaddr; + unsigned int pci_memaddr; unsigned int pci_irq_line; printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device); @@ -571,12 +560,12 @@ /* Retrieve and print the ethernet address. */ while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) - cpu_relax(); + ; for (i = 0; i < 6; i += 2) { unsigned short data; tc_writel(PROM_Busy | PROM_Read | (i / 2 + 2), &tr->PROM_Ctl); while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) - cpu_relax(); + ; data = tc_readl(&tr->PROM_Data); dev->dev_addr[i] = data & 0xff; dev->dev_addr[i+1] = data >> 8; @@ -842,7 +831,6 @@ panic("%s: Illegal queue state.", dev->name); } -#if 0 static void print_buf(char *add, int length) { int i; @@ -859,7 +847,6 @@ } printk("\n"); } -#endif static void print_eth(char *add) { @@ -920,8 +907,7 @@ struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr; int flags; - save_flags(flags); - cli(); + save_and_cli(flags); printk(KERN_WARNING "%s: transmit timed out, status %#x\n", dev->name, tc_readl(&tr->Tx_Stat)); /* Try to restart the adaptor. */ @@ -977,8 +963,7 @@ dma_cache_wback_inv((unsigned long)buf, length); #endif - save_flags(flags); - cli(); + save_and_cli(flags); /* failsafe... */ if (lp->tfd_start != lp->tfd_end) @@ -1428,8 +1413,7 @@ unsigned long flags; if (netif_running(dev)) { - save_flags(flags); - cli(); + save_and_cli(flags); /* Update the statistics from the device registers. */ lp->stats.rx_missed_errors = tc_readl(&tr->Miss_Cnt); restore_flags(flags); @@ -1537,11 +1521,10 @@ { unsigned long data; int flags; - save_flags(flags); - cli(); + save_and_cli(flags); tc_writel(MD_CA_Busy | (phy << 5) | phy_reg, &tr->MD_CA); while (tc_readl(&tr->MD_CA) & MD_CA_Busy) - cpu_relax(); + ; data = tc_readl(&tr->MD_Data); restore_flags(flags); return data; @@ -1550,12 +1533,11 @@ static void tc_phy_write(unsigned long d, struct tc35815_regs *tr, int phy, int phy_reg) { int flags; - save_flags(flags); - cli(); + save_and_cli(flags); tc_writel(d, &tr->MD_Data); tc_writel(MD_CA_Busy | MD_CA_Wr | (phy << 5) | phy_reg, &tr->MD_CA); while (tc_readl(&tr->MD_CA) & MD_CA_Busy) - cpu_relax(); + ; restore_flags(flags); } @@ -1643,7 +1625,7 @@ /* reset the controller */ tc_writel(MAC_Reset, &tr->MAC_Ctl); while (tc_readl(&tr->MAC_Ctl) & MAC_Reset) - cpu_relax(); + ; tc_writel(0, &tr->MAC_Ctl); @@ -1680,8 +1662,7 @@ tc_writel(CAM_Ena_Bit(CAM_ENTRY_SOURCE), &tr->CAM_Ena); tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl); - save_flags(flags); - cli(); + save_and_cli(flags); tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl); @@ -1715,6 +1696,39 @@ restore_flags(flags); } +static int tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) +{ + int len = 0; + off_t pos = 0; + off_t begin = 0; + struct net_device *dev; + + len += sprintf(buffer, "TC35815 statistics:\n"); + for (dev = root_tc35815_dev; dev; dev = ((struct tc35815_local *)dev->priv)->next_module) { + struct tc35815_local *lp = (struct tc35815_local *)dev->priv; + len += sprintf(buffer + len, + "%s: tx_ints %d, rx_ints %d, max_tx_qlen %d\n", + dev->name, + lp->lstats.tx_ints, + lp->lstats.rx_ints, + lp->lstats.max_tx_qlen); + pos = begin + len; + + if (pos < offset) { + len = 0; + begin = pos; + } + + if (pos > offset+length) break; + } + + *start = buffer + (offset - begin); + len -= (offset - begin); + + if (len > length) len = length; + + return len; +} /* XXX */ void diff -urN linux-2.4.21/drivers/net/tg3.c linux-2.4.22/drivers/net/tg3.c --- linux-2.4.21/drivers/net/tg3.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/tg3.c 2003-08-25 04:44:42.000000000 -0700 @@ -29,10 +29,6 @@ #include #include -#ifndef PCI_DMA_BUS_IS_PHYS -#define PCI_DMA_BUS_IS_PHYS 1 -#endif - #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define TG3_VLAN_TAG_USED 1 #else @@ -50,8 +46,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5" -#define DRV_MODULE_RELDATE "March 21, 2003" +#define DRV_MODULE_VERSION "1.6" +#define DRV_MODULE_RELDATE "June 11, 2003" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -2224,73 +2220,17 @@ schedule_task(&tp->reset_task); } -#if !PCI_DMA_BUS_IS_PHYS -static void tg3_set_txd_addr(struct tg3 *tp, int entry, dma_addr_t mapping) -{ - if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry]; - - txd->addr_hi = ((u64) mapping >> 32); - txd->addr_lo = ((u64) mapping & 0xffffffff); - } else { - unsigned long txd; - - txd = (tp->regs + - NIC_SRAM_WIN_BASE + - NIC_SRAM_TX_BUFFER_DESC); - txd += (entry * TXD_SIZE); - - if (sizeof(dma_addr_t) != sizeof(u32)) - writel(((u64) mapping >> 32), - txd + TXD_ADDR + TG3_64BIT_REG_HIGH); - - writel(((u64) mapping & 0xffffffff), - txd + TXD_ADDR + TG3_64BIT_REG_LOW); - } -} -#endif - static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, u32 guilty_entry, int guilty_len, u32 last_plus_one, u32 *start, u32 mss) { + struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC); dma_addr_t new_addr; u32 entry = *start; int i; -#if !PCI_DMA_BUS_IS_PHYS - /* IOMMU, just map the guilty area again which is guarenteed to - * use different addresses. - */ - - i = 0; - while (entry != guilty_entry) { - entry = NEXT_TX(entry); - i++; - } - if (i == 0) { - new_addr = pci_map_single(tp->pdev, skb->data, guilty_len, - PCI_DMA_TODEVICE); - } else { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; - - new_addr = pci_map_page(tp->pdev, - frag->page, frag->page_offset, - guilty_len, PCI_DMA_TODEVICE); - } - pci_unmap_single(tp->pdev, pci_unmap_addr(&tp->tx_buffers[guilty_entry], - mapping), - guilty_len, PCI_DMA_TODEVICE); - tg3_set_txd_addr(tp, guilty_entry, new_addr); - pci_unmap_addr_set(&tp->tx_buffers[guilty_entry], mapping, - new_addr); - *start = last_plus_one; -#else - /* Oh well, no IOMMU, have to allocate a whole new SKB. */ - struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC); - if (!new_skb) { dev_kfree_skb(skb); return -1; @@ -2327,7 +2267,6 @@ } dev_kfree_skb(skb); -#endif return 0; } @@ -6703,7 +6642,7 @@ } /* Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) { + if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) { pci_using_dac = 1; } else { err = pci_set_dma_mask(pdev, (u64) 0xffffffff); diff -urN linux-2.4.21/drivers/net/tlan.c linux-2.4.22/drivers/net/tlan.c --- linux-2.4.21/drivers/net/tlan.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/tlan.c 2003-08-25 04:44:42.000000000 -0700 @@ -166,19 +166,18 @@ * Thanks to Gunnar Eikman *******************************************************************************/ - #include - -#include "tlan.h" - #include #include #include +#include #include #include #include +#include #include +#include "tlan.h" typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 ); @@ -208,7 +207,6 @@ MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)"); MODULE_PARM_DESC(debug, "ThunderLAN debug mask"); MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)"); -EXPORT_NO_SYMBOLS; /* Define this to enable Link beat monitoring */ #undef MONITOR @@ -218,10 +216,11 @@ static int bbuf; static u8 *TLanPadBuffer; +static dma_addr_t TLanPadBufferDMA; static char TLanSignature[] = "TLAN"; -static const char tlan_banner[] = "ThunderLAN driver v1.15\n"; -static int tlan_have_pci; -static int tlan_have_eisa; +static const char tlan_banner[] = "ThunderLAN driver v1.15\n"; +static int tlan_have_pci; +static int tlan_have_eisa; const char *media[] = { "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ", @@ -347,6 +346,27 @@ static int TLan_EeReadByte( struct net_device *, u8, u8 * ); +static void +TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb) +{ + unsigned long addr = (unsigned long)skb; + tag->buffer[9].address = (u32)addr; + addr >>= 31; /* >>= 32 is undefined for 32bit arch, stupid C */ + addr >>= 1; + tag->buffer[8].address = (u32)addr; +} + +static struct sk_buff * +TLan_GetSKB( struct tlan_list_tag *tag) +{ + unsigned long addr = tag->buffer[8].address; + addr <<= 31; + addr <<= 1; + addr |= tag->buffer[9].address; + return (struct sk_buff *) addr; +} + + static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = { TLan_HandleInvalid, TLan_HandleTxEOF, @@ -422,10 +442,10 @@ unregister_netdev( dev ); if ( priv->dmaStorage ) { - kfree( priv->dmaStorage ); + pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA ); } - release_region( dev->base_addr, 0x10 ); + pci_release_regions(pdev); kfree( dev ); @@ -433,10 +453,10 @@ } static struct pci_driver tlan_driver = { - name: "tlan", - id_table: tlan_pci_tbl, - probe: tlan_init_one, - remove: __devexit_p(tlan_remove_one), + .name = "tlan", + .id_table = tlan_pci_tbl, + .probe = tlan_init_one, + .remove = __devexit_p(tlan_remove_one), }; static int __init tlan_probe(void) @@ -445,8 +465,7 @@ printk(KERN_INFO "%s", tlan_banner); - TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE, - GFP_KERNEL); + TLanPadBuffer = (u8 *) pci_alloc_consistent(NULL, TLAN_MIN_FRAME_SIZE, &TLanPadBufferDMA); if (TLanPadBuffer == NULL) { printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n"); @@ -471,7 +490,7 @@ if (TLanDevicesInstalled == 0) { pci_unregister_driver(&tlan_driver); - kfree(TLanPadBuffer); + pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA); return -ENODEV; } return 0; @@ -512,26 +531,44 @@ TLanPrivateInfo *priv; u8 pci_rev; u16 device_id; - int reg; + int reg, rc = -ENODEV; + + if (pdev) { + rc = pci_enable_device(pdev); + if (rc) + return rc; - if (pdev && pci_enable_device(pdev)) - return -EIO; + rc = pci_request_regions(pdev, TLanSignature); + if (rc) { + printk(KERN_ERR "TLAN: Could not reserve IO regions\n"); + goto err_out; + } + } - dev = init_etherdev(NULL, sizeof(TLanPrivateInfo)); + dev = alloc_etherdev(sizeof(TLanPrivateInfo)); if (dev == NULL) { printk(KERN_ERR "TLAN: Could not allocate memory for device.\n"); - return -ENOMEM; + rc = -ENOMEM; + goto err_out_regions; } SET_MODULE_OWNER(dev); priv = dev->priv; + priv->pciDev = pdev; + /* Is this a PCI device? */ if (pdev) { u32 pci_io_base = 0; priv->adapter = &board_info[ent->driver_data]; + rc = pci_set_dma_mask(pdev, 0xFFFFFFFF); + if (rc) { + printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n"); + goto err_out_free_dev; + } + pci_read_config_byte ( pdev, PCI_REVISION_ID, &pci_rev); for ( reg= 0; reg <= 5; reg ++ ) { @@ -544,9 +581,8 @@ } if (!pci_io_base) { printk(KERN_ERR "TLAN: No IO mappings available\n"); - unregister_netdev(dev); - kfree(dev); - return -ENODEV; + rc = -EIO; + goto err_out_free_dev; } dev->base_addr = pci_io_base; @@ -592,19 +628,22 @@ /* This will be used when we get an adapter error from * within our irq handler */ - INIT_LIST_HEAD(&priv->tlan_tqueue.list); - priv->tlan_tqueue.sync = 0; - priv->tlan_tqueue.routine = (void *)(void*)TLan_tx_timeout; - priv->tlan_tqueue.data = dev; + INIT_TQUEUE(&priv->tlan_tqueue, (void *)(void*)TLan_tx_timeout, dev); spin_lock_init(&priv->lock); - if (TLan_Init(dev)) { + rc = TLan_Init(dev); + if (rc) { + printk(KERN_ERR "TLAN: Could not set up device.\n"); + goto err_out_free_dev; + } + + rc = register_netdev(dev); + if (rc) { printk(KERN_ERR "TLAN: Could not register device.\n"); - unregister_netdev(dev); - kfree(dev); - return -EAGAIN; - } else { + goto err_out_uninit; + } + TLanDevicesInstalled++; boards_found++; @@ -625,8 +664,19 @@ priv->adapter->deviceLabel, priv->adapterRev); return 0; - } +err_out_uninit: + pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, + priv->dmaStorageDMA ); +err_out_free_dev: + kfree(dev); +err_out_regions: + if (pdev) + pci_release_regions(pdev); +err_out: + if (pdev) + pci_disable_device(pdev); + return rc; } @@ -639,7 +689,7 @@ dev = TLan_Eisa_Devices; priv = dev->priv; if (priv->dmaStorage) { - kfree(priv->dmaStorage); + pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA ); } release_region( dev->base_addr, 0x10); unregister_netdev( dev ); @@ -657,7 +707,7 @@ if (tlan_have_eisa) TLan_Eisa_Cleanup(); - kfree( TLanPadBuffer ); + pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA); } @@ -792,15 +842,6 @@ priv = dev->priv; - if (!priv->is_eisa) /* EISA devices have already requested IO */ - if (!request_region( dev->base_addr, 0x10, TLanSignature )) { - printk(KERN_ERR "TLAN: %s: IO port region 0x%lx size 0x%x in use.\n", - dev->name, - dev->base_addr, - 0x10 ); - return -EIO; - } - if ( bbuf ) { dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS ) * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE ); @@ -808,21 +849,25 @@ dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS ) * ( sizeof(TLanList) ); } - priv->dmaStorage = kmalloc(dma_size, GFP_KERNEL | GFP_DMA); + priv->dmaStorage = pci_alloc_consistent(priv->pciDev, dma_size, &priv->dmaStorageDMA); + priv->dmaSize = dma_size; + if ( priv->dmaStorage == NULL ) { printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n", dev->name ); - release_region( dev->base_addr, 0x10 ); return -ENOMEM; } memset( priv->dmaStorage, 0, dma_size ); priv->rxList = (TLanList *) ( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 ); + priv->rxListDMA = ( ( ( (u32) priv->dmaStorageDMA ) + 7 ) & 0xFFFFFFF8 ); priv->txList = priv->rxList + TLAN_NUM_RX_LISTS; + priv->txListDMA = priv->rxListDMA + sizeof(TLanList) * TLAN_NUM_RX_LISTS; if ( bbuf ) { priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS ); - priv->txBuffer = priv->rxBuffer - + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE ); + priv->rxBufferDMA =priv->txListDMA + sizeof(TLanList) * TLAN_NUM_TX_LISTS; + priv->txBuffer = priv->rxBuffer + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE ); + priv->txBufferDMA = priv->rxBufferDMA + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE ); } err = 0; @@ -1003,6 +1048,7 @@ { TLanPrivateInfo *priv = dev->priv; TLanList *tail_list; + dma_addr_t tail_list_phys; u8 *tail_buffer; int pad; unsigned long flags; @@ -1014,6 +1060,7 @@ } tail_list = priv->txList + priv->txTail; + tail_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txTail; if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) { TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s is busy (Head=%d Tail=%d)\n", dev->name, priv->txHead, priv->txTail ); @@ -1028,8 +1075,8 @@ tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE ); memcpy( tail_buffer, skb->data, skb->len ); } else { - tail_list->buffer[0].address = virt_to_bus( skb->data ); - tail_list->buffer[9].address = (u32) skb; + tail_list->buffer[0].address = pci_map_single(priv->pciDev, skb->data, skb->len, PCI_DMA_TODEVICE); + TLan_StoreSKB(tail_list, skb); } pad = TLAN_MIN_FRAME_SIZE - skb->len; @@ -1038,7 +1085,7 @@ tail_list->frameSize = (u16) skb->len + pad; tail_list->buffer[0].count = (u32) skb->len; tail_list->buffer[1].count = TLAN_LAST_BUFFER | (u32) pad; - tail_list->buffer[1].address = virt_to_bus( TLanPadBuffer ); + tail_list->buffer[1].address = TLanPadBufferDMA; } else { tail_list->frameSize = (u16) skb->len; tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len; @@ -1051,14 +1098,14 @@ if ( ! priv->txInProgress ) { priv->txInProgress = 1; TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Starting TX on buffer %d\n", priv->txTail ); - outl( virt_to_bus( tail_list ), dev->base_addr + TLAN_CH_PARM ); + outl( tail_list_phys, dev->base_addr + TLAN_CH_PARM ); outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD ); } else { TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n", priv->txTail ); if ( priv->txTail == 0 ) { - ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = virt_to_bus( tail_list ); + ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = tail_list_phys; } else { - ( priv->txList + ( priv->txTail - 1 ) )->forward = virt_to_bus( tail_list ); + ( priv->txList + ( priv->txTail - 1 ) )->forward = tail_list_phys; } } spin_unlock_irqrestore(&priv->lock, flags); @@ -1344,6 +1391,7 @@ TLanPrivateInfo *priv = dev->priv; int eoc = 0; TLanList *head_list; + dma_addr_t head_list_phys; u32 ack = 0; u16 tmpCStat; @@ -1353,7 +1401,10 @@ while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) { ack++; if ( ! bbuf ) { - dev_kfree_skb_any( (struct sk_buff *) head_list->buffer[9].address ); + struct sk_buff *skb = TLan_GetSKB(head_list); + pci_unmap_single(priv->pciDev, head_list->buffer[0].address, skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); + head_list->buffer[8].address = 0; head_list->buffer[9].address = 0; } @@ -1374,8 +1425,9 @@ if ( eoc ) { TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail ); head_list = priv->txList + priv->txHead; + head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead; if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) { - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM ); + outl(head_list_phys, dev->base_addr + TLAN_CH_PARM ); ack |= TLAN_HC_GO; } else { priv->txInProgress = 0; @@ -1468,9 +1520,11 @@ void *t; u32 frameSize; u16 tmpCStat; + dma_addr_t head_list_phys; TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail ); head_list = priv->rxList + priv->rxHead; + head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) { frameSize = head_list->frameSize; @@ -1498,17 +1552,16 @@ struct sk_buff *new_skb; /* - * I changed the algorithm here. What we now do - * is allocate the new frame. If this fails we - * simply recycle the frame. - */ + * I changed the algorithm here. What we now do + * is allocate the new frame. If this fails we + * simply recycle the frame. + */ new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 ); if ( new_skb != NULL ) { - /* If this ever happened it would be a problem */ - /* not any more - ac */ - skb = (struct sk_buff *) head_list->buffer[9].address; + skb = TLan_GetSKB(head_list); + pci_unmap_single(priv->pciDev, head_list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); skb_trim( skb, frameSize ); priv->stats.rx_bytes += frameSize; @@ -1519,9 +1572,9 @@ new_skb->dev = dev; skb_reserve( new_skb, 2 ); t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE ); - head_list->buffer[0].address = virt_to_bus( t ); + head_list->buffer[0].address = pci_map_single(priv->pciDev, new_skb->data, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); head_list->buffer[8].address = (u32) t; - head_list->buffer[9].address = (u32) new_skb; + TLan_StoreSKB(head_list, new_skb); } else printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" ); } @@ -1529,11 +1582,12 @@ head_list->forward = 0; head_list->cStat = 0; tail_list = priv->rxList + priv->rxTail; - tail_list->forward = virt_to_bus( head_list ); + tail_list->forward = head_list_phys; CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS ); CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS ); head_list = priv->rxList + priv->rxHead; + head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; } if (!ack) @@ -1545,7 +1599,8 @@ if ( eoc ) { TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail ); head_list = priv->rxList + priv->rxHead; - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM ); + head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; + outl(head_list_phys, dev->base_addr + TLAN_CH_PARM ); ack |= TLAN_HC_GO | TLAN_HC_RT; priv->rxEocCount++; } @@ -1611,7 +1666,7 @@ * host_int The contents of the HOST_INT * port. * - * This driver is structured to determine EOC occurances by + * This driver is structured to determine EOC occurrences by * reading the CSTAT member of the list structure. Tx EOC * interrupts are disabled via the DIO INTDIS register. * However, TLAN chips before revision 3.0 didn't have this @@ -1624,15 +1679,17 @@ { TLanPrivateInfo *priv = dev->priv; TLanList *head_list; + dma_addr_t head_list_phys; u32 ack = 1; host_int = 0; if ( priv->tlanRev < 0x30 ) { TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", priv->txHead, priv->txTail ); head_list = priv->txList + priv->txHead; + head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead; if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) { netif_stop_queue(dev); - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM ); + outl( head_list_phys, dev->base_addr + TLAN_CH_PARM ); ack |= TLAN_HC_GO; } else { priv->txInProgress = 0; @@ -1683,10 +1740,9 @@ printk( "TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error ); TLan_ReadAndClearStats( dev, TLAN_RECORD ); outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD ); - - queue_task(&priv->tlan_tqueue, &tq_immediate); - mark_bh(IMMEDIATE_BH); - + + schedule_task(&priv->tlan_tqueue); + netif_wake_queue(dev); ack = 0; } else { @@ -1733,7 +1789,7 @@ * host_int The contents of the HOST_INT * port. * - * This driver is structured to determine EOC occurances by + * This driver is structured to determine EOC occurrences by * reading the CSTAT member of the list structure. Rx EOC * interrupts are disabled via the DIO INTDIS register. * However, TLAN chips before revision 3.0 didn't have this @@ -1745,13 +1801,13 @@ u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = dev->priv; - TLanList *head_list; + dma_addr_t head_list_phys; u32 ack = 1; if ( priv->tlanRev < 0x30 ) { TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail ); - head_list = priv->rxList + priv->rxHead; - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM ); + head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; + outl( head_list_phys, dev->base_addr + TLAN_CH_PARM ); ack |= TLAN_HC_GO | TLAN_HC_RT; priv->rxEocCount++; } @@ -1888,6 +1944,7 @@ TLanPrivateInfo *priv = dev->priv; int i; TLanList *list; + dma_addr_t list_phys; struct sk_buff *skb; void *t = NULL; @@ -1897,12 +1954,13 @@ list = priv->txList + i; list->cStat = TLAN_CSTAT_UNUSED; if ( bbuf ) { - list->buffer[0].address = virt_to_bus( priv->txBuffer + ( i * TLAN_MAX_FRAME_SIZE ) ); + list->buffer[0].address = priv->txBufferDMA + ( i * TLAN_MAX_FRAME_SIZE ); } else { list->buffer[0].address = 0; } list->buffer[2].count = 0; list->buffer[2].address = 0; + list->buffer[8].address = 0; list->buffer[9].address = 0; } @@ -1910,11 +1968,12 @@ priv->rxTail = TLAN_NUM_RX_LISTS - 1; for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) { list = priv->rxList + i; + list_phys = priv->rxListDMA + sizeof(TLanList) * i; list->cStat = TLAN_CSTAT_READY; list->frameSize = TLAN_MAX_FRAME_SIZE; list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER; if ( bbuf ) { - list->buffer[0].address = virt_to_bus( priv->rxBuffer + ( i * TLAN_MAX_FRAME_SIZE ) ); + list->buffer[0].address = priv->rxBufferDMA + ( i * TLAN_MAX_FRAME_SIZE ); } else { skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 ); if ( skb == NULL ) { @@ -1925,14 +1984,14 @@ skb_reserve( skb, 2 ); t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE ); } - list->buffer[0].address = virt_to_bus( t ); + list->buffer[0].address = pci_map_single(priv->pciDev, t, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); list->buffer[8].address = (u32) t; - list->buffer[9].address = (u32) skb; + TLan_StoreSKB(list, skb); } list->buffer[1].count = 0; list->buffer[1].address = 0; if ( i < TLAN_NUM_RX_LISTS - 1 ) - list->forward = virt_to_bus( list + 1 ); + list->forward = list_phys + sizeof(TLanList); else list->forward = 0; } @@ -1950,23 +2009,26 @@ if ( ! bbuf ) { for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) { list = priv->txList + i; - skb = (struct sk_buff *) list->buffer[9].address; + skb = TLan_GetSKB(list); if ( skb ) { + pci_unmap_single(priv->pciDev, list->buffer[0].address, skb->len, PCI_DMA_TODEVICE); dev_kfree_skb_any( skb ); + list->buffer[8].address = 0; list->buffer[9].address = 0; } } for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) { list = priv->rxList + i; - skb = (struct sk_buff *) list->buffer[9].address; + skb = TLan_GetSKB(list); if ( skb ) { + pci_unmap_single(priv->pciDev, list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); dev_kfree_skb_any( skb ); + list->buffer[8].address = 0; list->buffer[9].address = 0; } } } - } /* TLan_FreeLists */ @@ -2271,8 +2333,8 @@ printk("TLAN: Partner capability: "); for (i = 5; i <= 10; i++) if (partner & (1<base_addr, TLAN_LED_REG, TLAN_LED_LINK ); @@ -2304,7 +2366,7 @@ if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) { outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 ); } - outl( virt_to_bus( priv->rxList ), dev->base_addr + TLAN_CH_PARM ); + outl( priv->rxListDMA, dev->base_addr + TLAN_CH_PARM ); outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD ); } else { printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name ); @@ -2376,7 +2438,7 @@ * dev A pointer to the device structure of the * TLAN device having the PHYs to be detailed. * - * This function prints the registers a PHY (aka tranceiver). + * This function prints the registers a PHY (aka transceiver). * ********************************************************************/ @@ -2492,7 +2554,7 @@ /* Wait for 50 ms and powerup * This is abitrary. It is intended to make sure the - * tranceiver settles. + * transceiver settles. */ TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP ); @@ -2512,7 +2574,7 @@ TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value ); TLan_MiiSync(dev->base_addr); /* Wait for 500 ms and reset the - * tranceiver. The TLAN docs say both 50 ms and + * transceiver. The TLAN docs say both 50 ms and * 500 ms, so do the longer, just in case. */ TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET ); @@ -2627,7 +2689,7 @@ TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl ); } - /* Wait for 2 sec to give the tranceiver time + /* Wait for 2 sec to give the transceiver time * to establish link. */ TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET ); diff -urN linux-2.4.21/drivers/net/tlan.h linux-2.4.22/drivers/net/tlan.h --- linux-2.4.21/drivers/net/tlan.h 2001-07-02 14:03:04.000000000 -0700 +++ linux-2.4.22/drivers/net/tlan.h 2003-08-25 04:44:42.000000000 -0700 @@ -169,15 +169,22 @@ typedef struct tlan_private_tag { struct net_device *nextDevice; + struct pci_dev *pciDev; void *dmaStorage; + dma_addr_t dmaStorageDMA; + unsigned int dmaSize; u8 *padBuffer; TLanList *rxList; + dma_addr_t rxListDMA; u8 *rxBuffer; + dma_addr_t rxBufferDMA; u32 rxHead; u32 rxTail; u32 rxEocCount; TLanList *txList; + dma_addr_t txListDMA; u8 *txBuffer; + dma_addr_t txBufferDMA; u32 txHead; u32 txInProgress; u32 txTail; diff -urN linux-2.4.21/drivers/net/tulip/tulip_core.c linux-2.4.22/drivers/net/tulip/tulip_core.c --- linux-2.4.21/drivers/net/tulip/tulip_core.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/tulip/tulip_core.c 2003-08-25 04:44:42.000000000 -0700 @@ -63,7 +63,7 @@ /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \ || defined(__sparc_) || defined(__ia64__) \ - || defined(__sh__) || defined(__mips__) + || defined(__sh__) || defined(__mips__) || defined(__SH5__) static int rx_copybreak = 1518; #else static int rx_copybreak = 100; @@ -231,6 +231,7 @@ { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT }, + { 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, /* ALi 1563 integrated ethernet */ { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); @@ -1403,12 +1404,14 @@ csr0 &= ~0xfff10000; /* zero reserved bits 31:20, 16 */ /* DM9102A has troubles with MRM & clear reserved bits 24:22, 20, 16, 7:1 */ - if (pdev->vendor == 0x1282 && pdev->device == 0x9102) + if ((pdev->vendor == 0x1282 && pdev->device == 0x9102) + || (pdev->vendor == 0x10b9 && pdev->device == 0x5261)) csr0 &= ~0x01f100ff; #if defined(__sparc__) /* DM9102A needs 32-dword alignment/burst length on sparc - chip bug? */ - if (pdev->vendor == 0x1282 && pdev->device == 0x9102) + if ((pdev->vendor == 0x1282 && pdev->device == 0x9102) + || (pdev->vendor == 0x10b9 && pdev->device == 0x5261)) csr0 = (csr0 & ~0xff00) | 0xe000; #endif diff -urN linux-2.4.21/drivers/net/typhoon.c linux-2.4.22/drivers/net/typhoon.c --- linux-2.4.21/drivers/net/typhoon.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/typhoon.c 2003-08-25 04:44:42.000000000 -0700 @@ -40,7 +40,7 @@ /* Set the copy breakpoint for the copy-only-tiny-frames scheme. * Setting to > 1518 effectively disables this feature. */ -static int rx_copybreak = 0; +static int rx_copybreak = 200; /* end user-configurable values */ @@ -85,8 +85,8 @@ #define PKT_BUF_SZ 1536 #define DRV_MODULE_NAME "typhoon" -#define DRV_MODULE_VERSION "1.0" -#define DRV_MODULE_RELDATE "03/02/14" +#define DRV_MODULE_VERSION "1.4.1" +#define DRV_MODULE_RELDATE "03/06/26" #define PFX DRV_MODULE_NAME ": " #define ERR_PFX KERN_ERR PFX @@ -150,7 +150,7 @@ #define TYPHOON_CRYPTO_DES 1 #define TYPHOON_CRYPTO_3DES 2 #define TYPHOON_CRYPTO_VARIABLE 4 -#define TYPHOON_FIBER 5 +#define TYPHOON_FIBER 8 enum typhoon_cards { TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR, @@ -1798,7 +1798,7 @@ u32 intr_status; intr_status = readl(ioaddr + TYPHOON_REG_INTR_STATUS); - if(!intr_status) + if(!(intr_status & TYPHOON_INTR_HOST_INT)) return; writel(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS); @@ -2134,7 +2134,7 @@ return 0; } -#if CONFIG_PM +#ifdef CONFIG_PM static int typhoon_resume(struct pci_dev *pdev) { @@ -2482,7 +2482,7 @@ .id_table = typhoon_pci_tbl, .probe = typhoon_init_one, .remove = __devexit_p(typhoon_remove_one), -#if CONFIG_PM +#ifdef CONFIG_PM .suspend = typhoon_suspend, .resume = typhoon_resume, .enable_wake = typhoon_enable_wake, diff -urN linux-2.4.21/drivers/net/via-rhine.c linux-2.4.22/drivers/net/via-rhine.c --- linux-2.4.21/drivers/net/via-rhine.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/via-rhine.c 2003-08-25 04:44:42.000000000 -0700 @@ -2,6 +2,8 @@ /* Written 1998-2001 by Donald Becker. + Current Maintainer: Roger Luethi + This software may be used and distributed according to the terms of the GNU General Public License (GPL), incorporated herein by reference. Drivers based on or derived from this code fall under the GPL and must @@ -9,8 +11,9 @@ a complete program and may only be used when the entire operating system is licensed under the GPL. - This driver is designed for the VIA VT86C100A Rhine-I. - It also works with the 6102 Rhine-II, and 6105/6105M Rhine-III. + This driver is designed for the VIA VT86C100A Rhine-I. + It also works with the Rhine-II (6102) and Rhine-III (6105/6105L/6105LOM + and management NIC 6105M). The author may be reached as becker@scyld.com, or C/O Scyld Computing Corporation @@ -115,11 +118,18 @@ - Force flushing for PCI posted writes - More reset code changes + LK1.1.18 (Roger Luethi) + - No filtering multicast in promisc mode (Edward Peng) + - Fix for Rhine-I Tx timeouts + + LK1.1.19 (Roger Luethi) + - Increase Tx threshold for unspecified errors + */ #define DRV_NAME "via-rhine" -#define DRV_VERSION "1.1.17" -#define DRV_RELDATE "March-1-2003" +#define DRV_VERSION "1.1.19" +#define DRV_RELDATE "July-12-2003" /* A few user-configurable values. @@ -139,7 +149,7 @@ Both 'options[]' and 'full_duplex[]' should exist for driver interoperability. The media type is usually passed in 'options[]'. - The default is autonegotation for speed and duplex. + The default is autonegotiation for speed and duplex. This should rarely be overridden. Use option values 0x10/0x20 for 10Mbps, 0x100,0x200 for 100Mbps. Use option values 0x10 and 0x100 for forcing half duplex fixed speed. @@ -386,17 +396,17 @@ { "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256, CanHaveMII | HasWOL }, { "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256, - CanHaveMII | HasWOL }, + CanHaveMII | HasWOL }, { "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256, - CanHaveMII | HasWOL }, + CanHaveMII | HasWOL }, }; static struct pci_device_id via_rhine_pci_tbl[] __devinitdata = { {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A}, {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102}, - {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, - {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M}, + {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, /* 6105{,L,LOM} */ + {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M}, {0,} /* terminate list */ }; MODULE_DEVICE_TABLE(pci, via_rhine_pci_tbl); @@ -441,7 +451,7 @@ IntrRxWakeUp=0x8000, IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260, IntrTxDescRace=0x080000, /* mapped from IntrStatus2 */ - IntrTxErrSummary=0x082210, + IntrTxErrSummary=0x082218, }; /* The Rx and Tx buffer descriptors. */ @@ -1264,7 +1274,7 @@ if (skb->len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); - if(skb == NULL) + if (skb == NULL) return 0; } @@ -1650,11 +1660,22 @@ printk(KERN_INFO "%s: Tx descriptor write-back race.\n", dev->name); } - if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace )) + if ((intr_status & IntrTxError) && ~( IntrTxAborted | IntrTxUnderrun | + IntrTxDescRace )) { + if (np->tx_thresh < 0xE0) { + writeb(np->tx_thresh += 0x20, ioaddr + TxConfig); + } + if (debug > 1) + printk(KERN_INFO "%s: Unspecified error. Tx " + "threshold now %2.2x.\n", + dev->name, np->tx_thresh); + } + if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace | + IntrTxError )) via_rhine_restart_tx(dev); if (intr_status & ~( IntrLinkChange | IntrStatsMax | IntrTxUnderrun | - IntrTxError | IntrTxAborted | IntrNormalSummary | + IntrTxError | IntrTxAborted | IntrNormalSummary | IntrTxDescRace )) { if (debug > 1) printk(KERN_ERR "%s: Something Wicked happened! %8.8x.\n", @@ -1690,6 +1711,8 @@ /* Unconditionally log net taps. */ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); rx_mode = 0x1C; + writel(0xffffffff, ioaddr + MulticastFilter0); + writel(0xffffffff, ioaddr + MulticastFilter1); } else if ((dev->mc_count > multicast_filter_limit) || (dev->flags & IFF_ALLMULTI)) { /* Too many to match, or accept all multicasts. */ diff -urN linux-2.4.21/drivers/net/wan/cosa.c linux-2.4.22/drivers/net/wan/cosa.c --- linux-2.4.21/drivers/net/wan/cosa.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wan/cosa.c 2003-08-25 04:44:42.000000000 -0700 @@ -228,8 +228,8 @@ /* NOTE: DMA is not autoprobed!!! */ static int dma[MAX_CARDS+1] = { 1, 7, 1, 7, 1, 7, 1, 7, 0, }; #else -int io[MAX_CARDS+1] = { 0, }; -int dma[MAX_CARDS+1] = { 0, }; +static int io[MAX_CARDS+1]; +static int dma[MAX_CARDS+1]; #endif /* IRQ can be safely autoprobed */ static int irq[MAX_CARDS+1] = { -1, -1, -1, -1, -1, -1, 0, }; diff -urN linux-2.4.21/drivers/net/wan/sbni.c linux-2.4.22/drivers/net/wan/sbni.c --- linux-2.4.21/drivers/net/wan/sbni.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/wan/sbni.c 2003-08-25 04:44:42.000000000 -0700 @@ -1552,13 +1552,13 @@ static u32 calc_crc32( u32 crc, u8 *p, u32 len ) { - register u32 _crc __asm ( "ax" ); + register u32 _crc; _crc = crc; __asm __volatile ( "xorl %%ebx, %%ebx\n" - "movl %1, %%esi\n" - "movl %2, %%ecx\n" + "movl %2, %%esi\n" + "movl %3, %%ecx\n" "movl $crc32tab, %%edi\n" "shrl $2, %%ecx\n" "jz 1f\n" @@ -1594,7 +1594,7 @@ "jnz 0b\n" "1:\n" - "movl %2, %%ecx\n" + "movl %3, %%ecx\n" "andl $3, %%ecx\n" "jz 2f\n" @@ -1619,9 +1619,9 @@ "xorb 2(%%esi), %%bl\n" "xorl (%%edi,%%ebx,4), %%eax\n" "2:\n" - : - : "a" (_crc), "g" (p), "g" (len) - : "ax", "bx", "cx", "dx", "si", "di" + : "=a" (_crc) + : "0" (_crc), "g" (p), "g" (len) + : "bx", "cx", "dx", "si", "di" ); return _crc; diff -urN linux-2.4.21/drivers/net/wan/sdla_chdlc.c linux-2.4.22/drivers/net/wan/sdla_chdlc.c --- linux-2.4.21/drivers/net/wan/sdla_chdlc.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/net/wan/sdla_chdlc.c 2003-08-25 04:44:42.000000000 -0700 @@ -591,8 +591,7 @@ if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){ - printk (KERN_INFO "%s: - Failed to set interrupt triggers!\n", + printk (KERN_INFO "%s: Failed to set interrupt triggers!\n", card->devname); return -EIO; } @@ -1089,13 +1088,11 @@ set_bit(0,&chdlc_priv_area->config_chdlc); chdlc_priv_area->config_chdlc_timeout=jiffies; - del_timer(&chdlc_priv_area->poll_delay_timer); /* Start the CHDLC configuration after 1sec delay. * This will give the interface initilization time * to finish its configuration */ - chdlc_priv_area->poll_delay_timer.expires=jiffies+HZ; - add_timer(&chdlc_priv_area->poll_delay_timer); + mod_timer(&chdlc_priv_area->poll_delay_timer, jiffies + HZ); return err; } diff -urN linux-2.4.21/drivers/net/wan/sdla_fr.c linux-2.4.22/drivers/net/wan/sdla_fr.c --- linux-2.4.21/drivers/net/wan/sdla_fr.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/net/wan/sdla_fr.c 2003-08-25 04:44:42.000000000 -0700 @@ -4541,9 +4541,7 @@ { fr_channel_t* chan = dev->priv; - del_timer(&chan->fr_arp_timer); - chan->fr_arp_timer.expires = jiffies + (chan->inarp_interval * HZ); - add_timer(&chan->fr_arp_timer); + mod_timer(&chan->fr_arp_timer, jiffies + (chan->inarp_interval) * HZ); return; } diff -urN linux-2.4.21/drivers/net/wan/sdla_x25.c linux-2.4.22/drivers/net/wan/sdla_x25.c --- linux-2.4.21/drivers/net/wan/sdla_x25.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wan/sdla_x25.c 2003-08-25 04:44:42.000000000 -0700 @@ -1267,9 +1267,7 @@ connect(card); S508_S514_unlock(card, &smp_flags); - del_timer(&card->u.x.x25_timer); - card->u.x.x25_timer.expires=jiffies+HZ; - add_timer(&card->u.x.x25_timer); + mod_timer(&card->u.x.x25_timer, jiffies + HZ); } } /* Device is not up until the we are in connected state */ diff -urN linux-2.4.21/drivers/net/wan/z85230.c linux-2.4.22/drivers/net/wan/z85230.c --- linux-2.4.21/drivers/net/wan/z85230.c 2001-11-09 14:03:11.000000000 -0800 +++ linux-2.4.22/drivers/net/wan/z85230.c 2003-08-25 04:44:42.000000000 -0700 @@ -1451,7 +1451,6 @@ c->tx_next_skb=NULL; c->tx_ptr=c->tx_next_ptr; - netif_wake_queue(c->netdevice); if(c->tx_skb==NULL) { /* Idle on */ @@ -1513,7 +1512,6 @@ /* ABUNDER off */ write_zsreg(c, R10, c->regs[10]); write_zsctrl(c, RES_Tx_CRC); -//??? write_zsctrl(c, RES_EOM_L); while(c->txcount && (read_zsreg(c,R0)&Tx_BUF_EMP)) { @@ -1523,6 +1521,10 @@ } } + /* + * Since we emptied tx_skb we can ask for more + */ + netif_wake_queue(c->netdevice); } /** @@ -1540,7 +1542,6 @@ { struct sk_buff *skb; - netif_wake_queue(c->netdevice); /* Actually this can happen.*/ if(c->tx_skb==NULL) return; @@ -1795,7 +1796,6 @@ z8530_tx_begin(c); spin_unlock_irqrestore(c->lock, flags); - netif_wake_queue(c->netdevice); return 0; } diff -urN linux-2.4.21/drivers/net/wireless/airo.c linux-2.4.22/drivers/net/wireless/airo.c --- linux-2.4.21/drivers/net/wireless/airo.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/airo.c 2003-08-25 04:44:42.000000000 -0700 @@ -97,12 +97,12 @@ infront of the label, that statistic will not be included in the list of statistics in the /proc filesystem */ -#define IGNLABEL 0&(int) +#define IGNLABEL(comment) 0 static char *statsLabels[] = { "RxOverrun", - IGNLABEL "RxPlcpCrcErr", - IGNLABEL "RxPlcpFormatErr", - IGNLABEL "RxPlcpLengthErr", + IGNLABEL("RxPlcpCrcErr"), + IGNLABEL("RxPlcpFormatErr"), + IGNLABEL("RxPlcpLengthErr"), "RxMacCrcErr", "RxMacCrcOk", "RxWepErr", @@ -146,15 +146,15 @@ "HostRxBc", "HostRxUc", "HostRxDiscard", - IGNLABEL "HmacTxMc", - IGNLABEL "HmacTxBc", - IGNLABEL "HmacTxUc", - IGNLABEL "HmacTxFail", - IGNLABEL "HmacRxMc", - IGNLABEL "HmacRxBc", - IGNLABEL "HmacRxUc", - IGNLABEL "HmacRxDiscard", - IGNLABEL "HmacRxAccepted", + IGNLABEL("HmacTxMc"), + IGNLABEL("HmacTxBc"), + IGNLABEL("HmacTxUc"), + IGNLABEL("HmacTxFail"), + IGNLABEL("HmacRxMc"), + IGNLABEL("HmacRxBc"), + IGNLABEL("HmacRxUc"), + IGNLABEL("HmacRxDiscard"), + IGNLABEL("HmacRxAccepted"), "SsidMismatch", "ApMismatch", "RatesMismatch", @@ -162,26 +162,26 @@ "AuthTimeout", "AssocReject", "AssocTimeout", - IGNLABEL "ReasonOutsideTable", - IGNLABEL "ReasonStatus1", - IGNLABEL "ReasonStatus2", - IGNLABEL "ReasonStatus3", - IGNLABEL "ReasonStatus4", - IGNLABEL "ReasonStatus5", - IGNLABEL "ReasonStatus6", - IGNLABEL "ReasonStatus7", - IGNLABEL "ReasonStatus8", - IGNLABEL "ReasonStatus9", - IGNLABEL "ReasonStatus10", - IGNLABEL "ReasonStatus11", - IGNLABEL "ReasonStatus12", - IGNLABEL "ReasonStatus13", - IGNLABEL "ReasonStatus14", - IGNLABEL "ReasonStatus15", - IGNLABEL "ReasonStatus16", - IGNLABEL "ReasonStatus17", - IGNLABEL "ReasonStatus18", - IGNLABEL "ReasonStatus19", + IGNLABEL("ReasonOutsideTable"), + IGNLABEL("ReasonStatus1"), + IGNLABEL("ReasonStatus2"), + IGNLABEL("ReasonStatus3"), + IGNLABEL("ReasonStatus4"), + IGNLABEL("ReasonStatus5"), + IGNLABEL("ReasonStatus6"), + IGNLABEL("ReasonStatus7"), + IGNLABEL("ReasonStatus8"), + IGNLABEL("ReasonStatus9"), + IGNLABEL("ReasonStatus10"), + IGNLABEL("ReasonStatus11"), + IGNLABEL("ReasonStatus12"), + IGNLABEL("ReasonStatus13"), + IGNLABEL("ReasonStatus14"), + IGNLABEL("ReasonStatus15"), + IGNLABEL("ReasonStatus16"), + IGNLABEL("ReasonStatus17"), + IGNLABEL("ReasonStatus18"), + IGNLABEL("ReasonStatus19"), "RxMan", "TxMan", "RxRefresh", @@ -654,9 +654,38 @@ u16 currentXmitRate; u16 apDevExtensions; u16 normalizedSignalStrength; - u16 _reserved1; + u16 shortPreamble; u8 apIP[4]; - u16 _reserved[7]; + u8 noisePercent; /* Noise percent in last second */ + u8 noisedBm; /* Noise dBm in last second */ + u8 noiseAvePercent; /* Noise percent in last minute */ + u8 noiseAvedBm; /* Noise dBm in last minute */ + u8 noiseMaxPercent; /* Highest noise percent in last minute */ + u8 noiseMaxdBm; /* Highest noise dbm in last minute */ + u16 load; + u8 carrier[4]; + u16 assocStatus; +#define STAT_NOPACKETS 0 +#define STAT_NOCARRIERSET 10 +#define STAT_GOTCARRIERSET 11 +#define STAT_WRONGSSID 20 +#define STAT_BADCHANNEL 25 +#define STAT_BADBITRATES 30 +#define STAT_BADPRIVACY 35 +#define STAT_APFOUND 40 +#define STAT_APREJECTED 50 +#define STAT_AUTHENTICATING 60 +#define STAT_DEAUTHENTICATED 61 +#define STAT_AUTHTIMEOUT 62 +#define STAT_ASSOCIATING 70 +#define STAT_DEASSOCIATED 71 +#define STAT_ASSOCTIMEOUT 72 +#define STAT_NOTAIROAP 73 +#define STAT_ASSOCIATED 80 +#define STAT_LEAPING 90 +#define STAT_LEAPFAILED 91 +#define STAT_LEAPTIMEDOUT 92 +#define STAT_LEAPCOMPLETE 93 } StatusRid; typedef struct { @@ -894,7 +923,7 @@ #ifdef WIRELESS_EXT // Frequency list (map channels to frequencies) -const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, +static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; // A few details needed for WEP (Wireless Equivalent Privacy) @@ -929,8 +958,8 @@ static void OUT4500( struct airo_info *, u16 register, u16 value ); static unsigned short IN4500( struct airo_info *, u16 register ); static u16 setup_card(struct airo_info*, u8 *mac); -static int enable_MAC( struct airo_info *ai, Resp *rsp ); -static void disable_MAC(struct airo_info *ai); +static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ); +static void disable_MAC(struct airo_info *ai, int lock); static void enable_interrupts(struct airo_info*); static void disable_interrupts(struct airo_info*); static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp); @@ -944,11 +973,11 @@ static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen, int whichbap); static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd); -static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len); +static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock); static int PC4500_writerid(struct airo_info*, u16 rid, const void - *pBuf, int len); + *pBuf, int len, int lock); static int do_writerid( struct airo_info*, u16 rid, const void *rid_data, - int len ); + int len, int dummy ); static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw); static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket); static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket); @@ -976,7 +1005,7 @@ int open; struct net_device *dev; /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we - use the high bit to mark wether it is in use. */ + use the high bit to mark whether it is in use. */ #define MAX_FIDS 6 int fids[MAX_FIDS]; int registered; @@ -992,19 +1021,21 @@ #define FLAG_PROMISC IFF_PROMISC /* 0x100 - include/linux/if.h */ #define FLAG_RADIO_OFF 0x02 /* User disabling of MAC */ #define FLAG_RADIO_DOWN 0x08 /* ifup/ifdown disabling of MAC */ -#define FLAG_LOCKED 2 /* 0x04 - use as a bit offset */ #define FLAG_FLASHING 0x10 #define FLAG_ADHOC 0x01 /* Needed by MIC */ #define FLAG_MIC_CAPABLE 0x20 #define FLAG_UPDATE_MULTI 0x40 #define FLAG_UPDATE_UNI 0x80 #define FLAG_802_11 0x200 +#define FLAG_PENDING_XMIT 0x400 +#define FLAG_PENDING_XMIT11 0x800 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); unsigned short *flash; tdsRssiEntry *rssi; struct semaphore sem; struct task_struct *task; + struct tq_struct stats_task; struct tq_struct promisc_task; struct { struct sk_buff *skb; @@ -1062,7 +1093,7 @@ ai->task = NULL; } rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT, - list, sizeof(*list)); + list, sizeof(*list), 1); list->len = le16_to_cpu(list->len); list->index = le16_to_cpu(list->index); @@ -1077,7 +1108,7 @@ static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) { int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM, - wkr, sizeof(*wkr)); + wkr, sizeof(*wkr), 1); wkr->len = le16_to_cpu(wkr->len); wkr->kindex = le16_to_cpu(wkr->kindex); @@ -1086,17 +1117,17 @@ } /* In the writeXXXRid routines we copy the rids so that we don't screwup * the originals when we endian them... */ -static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm) { +static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lock) { int rc; WepKeyRid wkr = *pwkr; wkr.len = cpu_to_le16(wkr.len); wkr.kindex = cpu_to_le16(wkr.kindex); wkr.klen = cpu_to_le16(wkr.klen); - rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr)); + rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock); if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc); if (perm) { - rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr)); + rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock); if (rc!=SUCCESS) { printk(KERN_ERR "airo: WEP_PERM set %x\n", rc); } @@ -1106,7 +1137,7 @@ static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) { int i; - int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr)); + int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1); ssidr->len = le16_to_cpu(ssidr->len); for(i = 0; i < 3; i++) { @@ -1123,10 +1154,10 @@ for(i = 0; i < 3; i++) { ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len); } - rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr)); + rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), 1); return rc; } -static int readConfigRid(struct airo_info*ai) { +static int readConfigRid(struct airo_info*ai, int lock) { int rc; u16 *s; ConfigRid cfg; @@ -1134,7 +1165,7 @@ if (ai->config.len) return SUCCESS; - rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg)); + rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock); if (rc != SUCCESS) return rc; @@ -1163,7 +1194,7 @@ } } } -static int writeConfigRid(struct airo_info*ai) { +static int writeConfigRid(struct airo_info*ai, int lock) { u16 *s; ConfigRid cfgr; @@ -1190,33 +1221,34 @@ for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++) *s = cpu_to_le16(*s); - return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr)); + return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock); } static int readStatusRid(struct airo_info*ai, StatusRid *statr) { - int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr)); + int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), 1); u16 *s; statr->len = le16_to_cpu(statr->len); for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s); - for(s = &statr->beaconPeriod; s <= &statr->_reserved[9]; s++) + for(s = &statr->beaconPeriod; s <= &statr->shortPreamble; s++) *s = le16_to_cpu(*s); - + statr->load = le16_to_cpu(statr->load); + statr->assocStatus = le16_to_cpu(statr->assocStatus); return rc; } static int readAPListRid(struct airo_info*ai, APListRid *aplr) { - int rc = PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr)); + int rc = PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1); aplr->len = le16_to_cpu(aplr->len); return rc; } static int writeAPListRid(struct airo_info*ai, APListRid *aplr) { int rc; aplr->len = cpu_to_le16(aplr->len); - rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr)); + rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), 1); return rc; } static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) { - int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr)); + int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), 1); u16 *s; capr->len = le16_to_cpu(capr->len); @@ -1227,8 +1259,8 @@ *s = le16_to_cpu(*s); return rc; } -static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid) { - int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr)); +static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) { + int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr), lock); u32 *i; sr->len = le16_to_cpu(sr->len); @@ -1248,8 +1280,8 @@ * is open (to pipeline changes and speed-up card setup). If * those changes are not yet commited, do it now - Jean II */ if(info->need_commit) { - disable_MAC(info); - writeConfigRid(info); + disable_MAC(info, 1); + writeConfigRid(info, 1); } if (info->wifidev != dev) { @@ -1257,7 +1289,7 @@ info->flags &= ~FLAG_RADIO_DOWN; enable_interrupts(info); } - enable_MAC(info, &rsp); + enable_MAC(info, &rsp, 1); netif_start_queue(dev); return 0; @@ -1321,6 +1353,7 @@ u32 *fids = priv->fids; if (down_trylock(&priv->sem) != 0) { + priv->flags |= FLAG_PENDING_XMIT; netif_stop_queue(dev); priv->xmit.task.routine = (void (*)(void *))airo_do_xmit; priv->xmit.task.data = (void *)dev; @@ -1329,6 +1362,7 @@ } status = transmit_802_3_packet (priv, fids[fid], skb->data); up(&priv->sem); + priv->flags &= ~FLAG_PENDING_XMIT; i = 0; if ( status == SUCCESS ) { @@ -1340,14 +1374,12 @@ } if (i < MAX_FIDS / 2) netif_wake_queue(dev); - else - netif_stop_queue(dev); dev_kfree_skb(skb); } static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { s16 len; - int i; + int i, j; struct airo_info *priv = dev->priv; u32 *fids = priv->fids; @@ -1358,19 +1390,23 @@ /* Find a vacant FID */ for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ ); + for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ ); - if ( i == MAX_FIDS / 2 ) { - priv->stats.tx_fifo_errors++; - dev_kfree_skb(skb); - } else { - /* check min length*/ - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - /* Mark fid as used & save length for later */ - fids[i] |= (len << 16); - priv->xmit.skb = skb; - priv->xmit.fid = i; - airo_do_xmit(dev); + if ( j >= MAX_FIDS / 2 ) { + netif_stop_queue(dev); + + if (i == MAX_FIDS / 2) { + priv->stats.tx_fifo_errors++; + return 1; + } } + /* check min length*/ + len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + /* Mark fid as used & save length for later */ + fids[i] |= (len << 16); + priv->xmit.skb = skb; + priv->xmit.fid = i; + airo_do_xmit(dev); return 0; } @@ -1383,6 +1419,7 @@ u32 *fids = priv->fids; if (down_trylock(&priv->sem) != 0) { + priv->flags |= FLAG_PENDING_XMIT11; netif_stop_queue(dev); priv->xmit11.task.routine = (void (*)(void *))airo_do_xmit11; priv->xmit11.task.data = (void *)dev; @@ -1391,6 +1428,7 @@ } status = transmit_802_11_packet (priv, fids[fid], skb->data); up(&priv->sem); + priv->flags &= ~FLAG_PENDING_XMIT11; i = MAX_FIDS / 2; if ( status == SUCCESS ) { @@ -1402,14 +1440,12 @@ } if (i < MAX_FIDS) netif_wake_queue(dev); - else - netif_stop_queue(dev); dev_kfree_skb(skb); } static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { s16 len; - int i; + int i, j; struct airo_info *priv = dev->priv; u32 *fids = priv->fids; @@ -1420,45 +1456,61 @@ /* Find a vacant FID */ for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ ); + for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ ); - if ( i == MAX_FIDS ) { - priv->stats.tx_fifo_errors++; - dev_kfree_skb(skb); - } else { - /* check min length*/ - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - /* Mark fid as used & save length for later */ - fids[i] |= (len << 16); - priv->xmit11.skb = skb; - priv->xmit11.fid = i; - airo_do_xmit11(dev); + if ( j >= MAX_FIDS ) { + netif_stop_queue(dev); + + if (i == MAX_FIDS) { + priv->stats.tx_fifo_errors++; + return 1; + } } + /* check min length*/ + len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + /* Mark fid as used & save length for later */ + fids[i] |= (len << 16); + priv->xmit11.skb = skb; + priv->xmit11.fid = i; + airo_do_xmit11(dev); return 0; } -struct net_device_stats *airo_get_stats(struct net_device *dev) -{ - struct airo_info *local = dev->priv; +static void airo_read_stats(struct airo_info *ai) { StatsRid stats_rid; u32 *vals = stats_rid.vals; - /* Get stats out of the card */ - readStatsRid(local, &stats_rid, RID_STATS); + if (down_trylock(&ai->sem) == 0) { + readStatsRid(ai, &stats_rid, RID_STATS, 0); + up(&ai->sem); - local->stats.rx_packets = vals[43] + vals[44] + vals[45]; - local->stats.tx_packets = vals[39] + vals[40] + vals[41]; - local->stats.rx_bytes = vals[92]; - local->stats.tx_bytes = vals[91]; - local->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4]; - local->stats.tx_errors = vals[42] + local->stats.tx_fifo_errors; - local->stats.multicast = vals[43]; - local->stats.collisions = vals[89]; - - /* detailed rx_errors: */ - local->stats.rx_length_errors = vals[3]; - local->stats.rx_crc_errors = vals[4]; - local->stats.rx_frame_errors = vals[2]; - local->stats.rx_fifo_errors = vals[0]; + ai->stats.rx_packets = vals[43] + vals[44] + vals[45]; + ai->stats.tx_packets = vals[39] + vals[40] + vals[41]; + ai->stats.rx_bytes = vals[92]; + ai->stats.tx_bytes = vals[91]; + ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4]; + ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors; + ai->stats.multicast = vals[43]; + ai->stats.collisions = vals[89]; + + /* detailed rx_errors: */ + ai->stats.rx_length_errors = vals[3]; + ai->stats.rx_crc_errors = vals[4]; + ai->stats.rx_frame_errors = vals[2]; + ai->stats.rx_fifo_errors = vals[0]; + } else { + ai->stats_task.routine = (void (*)(void *))airo_read_stats; + ai->stats_task.data = (void *)ai; + schedule_task(&ai->stats_task); + } +} + +struct net_device_stats *airo_get_stats(struct net_device *dev) +{ + struct airo_info *local = dev->priv; + + /* Get stats out of the card if available */ + airo_read_stats(local); return &local->stats; } @@ -1513,9 +1565,9 @@ memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len); ai->need_commit = 1; - disable_MAC(ai); - writeConfigRid (ai); - enable_MAC(ai, &rsp); + disable_MAC(ai, 1); + writeConfigRid (ai, 1); + enable_MAC(ai, &rsp, 1); memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len); if (ai->wifidev) memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len); @@ -1544,7 +1596,7 @@ * stack (i.e. the network stack won't try to broadcast * anything on the interface and routes are gone. Jean II */ ai->flags |= FLAG_RADIO_DOWN; - disable_MAC(ai); + disable_MAC(ai, 1); #endif disable_interrupts( ai ); } @@ -1557,6 +1609,8 @@ { struct airo_info *ai = dev->priv; flush_scheduled_tasks(); + disable_interrupts(ai); + free_irq( dev->irq, dev ); if (ai->flash) kfree(ai->flash); if (ai->rssi) @@ -1571,8 +1625,6 @@ } ai->registered = 0; } - disable_interrupts(ai); - free_irq( dev->irq, dev ); if (auto_wep) del_timer_sync(&ai->timer); if (freeres) { /* PCMCIA frees this stuff, so only for PCI and ISA */ @@ -1768,6 +1820,9 @@ int i; struct airo_info *ai = dev->priv; + + if (down_interruptible(&ai->sem)) + return -1; waitbusy (ai); OUT4500(ai,COMMAND,CMD_SOFTRESET); set_current_state (TASK_UNINTERRUPTIBLE); @@ -1777,6 +1832,7 @@ schedule_timeout (HZ/5); if ( setup_card(ai, dev->dev_addr ) != SUCCESS ) { printk( KERN_ERR "airo: MAC could not be enabled\n" ); + up(&ai->sem); return -1; } else { printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", @@ -1794,6 +1850,7 @@ } enable_interrupts( ai ); netif_wake_queue(dev); + up(&ai->sem); return 0; } @@ -1806,9 +1863,7 @@ StatusRid status_rid; if (down_trylock(&ai->sem) == 0) { - __set_bit(FLAG_LOCKED, &ai->flags); - PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid)); - clear_bit(FLAG_LOCKED, &ai->flags); + PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0); up(&ai->sem); wrqu.data.length = 0; wrqu.data.flags = 0; @@ -1829,9 +1884,7 @@ MICRid mic_rid; if (down_trylock(&ai->sem) == 0) { - __set_bit(FLAG_LOCKED, &ai->flags); - PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid)); - clear_bit(FLAG_LOCKED, &ai->flags); + PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); up(&ai->sem); #ifdef MICSUPPORT micinit (ai, &mic_rid); @@ -1869,7 +1922,8 @@ if ( status & EV_MIC ) { OUT4500( apriv, EVACK, EV_MIC ); - airo_read_mic( apriv ); + if (apriv->flags & FLAG_MIC_CAPABLE) + airo_read_mic( apriv ); } if ( status & EV_LINK ) { #if WIRELESS_EXT > 13 @@ -2060,6 +2114,28 @@ } } if (len) { +#if WIRELESS_EXT > 15 +#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ + if (apriv->spy_data.spy_number > 0) { + char *sa; + struct iw_quality wstats; + /* Prepare spy data : addr + qual */ + sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6); + if (!(apriv->flags & FLAG_802_11)) { + bap_setup (apriv, fid, 8, BAP0); + bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); + } + wstats.qual = hdr.rssi[0]; + if (apriv->rssi) + wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; + else + wstats.level = (hdr.rssi[1] + 321) / 2; + wstats.updated = 3; + /* Update spy records */ + wireless_spy_update(dev, sa, &wstats); + } +#endif /* IW_WIRELESS_SPY */ +#else /* WIRELESS_EXT > 15 */ #ifdef WIRELESS_SPY if (apriv->spy_number > 0) { int i; @@ -2085,6 +2161,7 @@ } } #endif /* WIRELESS_SPY */ +#endif /* WIRELESS_EXT > 15 */ OUT4500( apriv, EVACK, EV_RX); if (apriv->flags & FLAG_802_11) { @@ -2116,17 +2193,23 @@ if ( ( apriv->fids[i] & 0xffff ) == fid ) { len = apriv->fids[i] >> 16; index = i; - /* Set up to be used again */ - apriv->fids[i] &= 0xffff; } } if (index != -1) { - netif_wake_queue(dev); if (status & EV_TXEXC) get_tx_error(apriv, index); - } - OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); - if (index==-1) { + OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); + /* Set up to be used again */ + apriv->fids[index] &= 0xffff; + if (index < MAX_FIDS / 2) { + if (!(apriv->flags & FLAG_PENDING_XMIT)) + netif_wake_queue(dev); + } else { + if (!(apriv->flags & FLAG_PENDING_XMIT11)) + netif_wake_queue(apriv->wifidev); + } + } else { + OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" ); } } @@ -2172,7 +2255,7 @@ return rc; } -static int enable_MAC( struct airo_info *ai, Resp *rsp ) { +static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) { int rc; Cmd cmd; @@ -2185,7 +2268,7 @@ if (ai->flags & (FLAG_RADIO_OFF|FLAG_RADIO_DOWN)) return SUCCESS; memset(&cmd, 0, sizeof(cmd)); cmd.cmd = MAC_ENABLE; - if (test_bit(FLAG_LOCKED, &ai->flags) != 0) + if (!lock) return issuecommand(ai, &cmd, rsp); if (down_interruptible(&ai->sem)) @@ -2195,13 +2278,13 @@ return rc; } -static void disable_MAC( struct airo_info *ai ) { +static void disable_MAC( struct airo_info *ai, int lock ) { Cmd cmd; Resp rsp; memset(&cmd, 0, sizeof(cmd)); cmd.cmd = MAC_DISABLE; // disable in case already enabled - if (test_bit(FLAG_LOCKED, &ai->flags) != 0) { + if (!lock) { issuecommand(ai, &cmd, &rsp); return; } @@ -2219,7 +2302,7 @@ /* Enable the interrupts */ OUT4500( ai, EVINTEN, STATUS_INTS ); /* Note there is a race condition between the last two lines that - I dont know how to get rid of right now... */ + I don't know how to get rid of right now... */ } static void disable_interrupts( struct airo_info *ai ) { @@ -2279,13 +2362,13 @@ CapabilityRid cap_rid; // general configuration (read/modify/write) - status = readConfigRid(ai); + status = readConfigRid(ai, 1); if ( status != SUCCESS ) return ERROR; status = readCapabilityRid(ai, &cap_rid); if ( status != SUCCESS ) return ERROR; - status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid)); + status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),1); if ( status == SUCCESS ) { if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL) memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); @@ -2349,14 +2432,14 @@ } } - status = writeConfigRid(ai); + status = writeConfigRid(ai, 1); if ( status != SUCCESS ) return ERROR; /* Set up the SSID list */ status = writeSsidRid(ai, &mySsid); if ( status != SUCCESS ) return ERROR; - status = enable_MAC(ai, &rsp); + status = enable_MAC(ai, &rsp, 1); if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) { printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 ); return ERROR; @@ -2500,7 +2583,7 @@ u16 next; int words; int i; - long flags; + unsigned long flags; spin_lock_irqsave(&ai->aux_lock, flags); page = IN4500(ai, SWS0+whichbap); @@ -2571,13 +2654,12 @@ /* Note, that we are using BAP1 which is also used by transmit, so * we must get a lock. */ -static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len) +static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock) { - u16 status, dolock = 0; + u16 status; int rc = SUCCESS; - if (test_bit(FLAG_LOCKED, &ai->flags) == 0) { - dolock = 1; + if (lock) { if (down_interruptible(&ai->sem)) return ERROR; } @@ -2605,7 +2687,7 @@ // read remainder of the rid rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1); done: - if (dolock) + if (lock) up(&ai->sem); return rc; } @@ -2613,13 +2695,14 @@ /* Note, that we are using BAP1 which is also used by transmit, so * make sure this isnt called when a transmit is happening */ static int PC4500_writerid(struct airo_info *ai, u16 rid, - const void *pBuf, int len) + const void *pBuf, int len, int lock) { - u16 status, dolock = 0; + u16 status; int rc = SUCCESS; - if (test_bit(FLAG_LOCKED, &ai->flags) == 0) { - dolock = 1; + *(u16*)pBuf = cpu_to_le16((u16)len); + + if (lock) { if (down_interruptible(&ai->sem)) return ERROR; } @@ -2637,7 +2720,7 @@ // ---now commit the rid data rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS); done: - if (dolock) + if (lock) up(&ai->sem); return rc; } @@ -2646,6 +2729,7 @@ one for now. */ static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw) { + unsigned int loop = 3000; Cmd cmd; Resp rsp; u16 txFid; @@ -2656,17 +2740,22 @@ if (down_interruptible(&ai->sem)) return ERROR; if (issuecommand(ai, &cmd, &rsp) != SUCCESS) { - txFid = 0; + txFid = ERROR; goto done; } if ( (rsp.status & 0xFF00) != 0) { - txFid = 0; + txFid = ERROR; goto done; } /* wait for the allocate event/indication * It makes me kind of nervous that this can just sit here and spin, * but in practice it only loops like four times. */ - while ( (IN4500(ai, EVSTAT) & EV_ALLOC) == 0) ; + while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop); + if (!loop) { + txFid = ERROR; + goto done; + } + // get the allocated fid and acknowledge txFid = IN4500(ai, TXALLOCFID); OUT4500(ai, EVACK, EV_ALLOC); @@ -2707,7 +2796,7 @@ len >>= 16; - if (len < ETH_ALEN * 2) { + if (len <= ETH_ALEN * 2) { printk( KERN_WARNING "Short packet %d\n", len ); return ERROR; } @@ -3158,10 +3247,10 @@ return -ENOMEM; } - readStatsRid(apriv, &stats, rid); + readStatsRid(apriv, &stats, rid, 1); j = 0; - for(i=0; (int)statsLabels[i]!=-1 && + for(i=0; statsLabels[i]!=(char *)-1 && i*44096) { @@ -3193,18 +3282,21 @@ return value; } +static int airo_config_commit(struct net_device *dev, + struct iw_request_info *info, void *zwrq, + char *extra); + static void proc_config_on_close( struct inode *inode, struct file *file ) { struct proc_data *data = file->private_data; struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = dev->priv; - Resp rsp; char *line; - int need_reset = 0; if ( !data->writelen ) return; - readConfigRid(ai); + readConfigRid(ai, 1); + ai->need_commit = 1; line = data->wbuffer; while( line[0] ) { @@ -3212,19 +3304,22 @@ if ( !strncmp( line, "Mode: ", 6 ) ) { line += 6; if ((ai->config.rmode & 0xff) >= RXMODE_RFMON) - need_reset = 1; + ai->need_commit = 2; ai->config.rmode &= 0xfe00; ai->flags &= ~FLAG_802_11; ai->config.opmode &= 0xFF00; + ai->config.scanMode = SCANMODE_ACTIVE; if ( line[0] == 'a' ) { ai->config.opmode |= 0; } else { ai->config.opmode |= 1; if ( line[0] == 'r' ) { ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; + ai->config.scanMode = SCANMODE_PASSIVE; ai->flags |= FLAG_802_11; } else if ( line[0] == 'y' ) { ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER; + ai->config.scanMode = SCANMODE_PASSIVE; ai->flags |= FLAG_802_11; } else if ( line[0] == 'l' ) ai->config.rmode |= RXMODE_LANMON; @@ -3390,22 +3485,7 @@ while( line[0] && line[0] != '\n' ) line++; if ( line[0] ) line++; } - disable_MAC(ai); - if (need_reset) { - APListRid APList_rid; - SsidRid SSID_rid; - - readAPListRid(ai, &APList_rid); - readSsidRid(ai, &SSID_rid); - reset_airo_card(dev); - disable_MAC(ai); - writeSsidRid(ai, &SSID_rid); - writeAPListRid(ai, &APList_rid); - } - writeConfigRid(ai); - enable_MAC(ai, &rsp); - if (need_reset) - airo_set_promisc(ai); + airo_config_commit(dev, NULL, NULL, NULL); } static char *get_rmode(u16 mode) { @@ -3443,7 +3523,7 @@ data->maxwritelen = 2048; data->on_close = proc_config_on_close; - readConfigRid(ai); + readConfigRid(ai, 1); i = sprintf( data->rbuffer, "Mode: %s\n" @@ -3535,9 +3615,9 @@ offset < data->writelen ) offset++; offset++; } - disable_MAC(ai); + disable_MAC(ai, 1); writeSsidRid(ai, &SSID_rid); - enable_MAC(ai, &rsp); + enable_MAC(ai, &rsp, 1); } inline static u8 hexVal(char c) { @@ -3576,20 +3656,20 @@ } } } - disable_MAC(ai); + disable_MAC(ai, 1); writeAPListRid(ai, &APList_rid); - enable_MAC(ai, &rsp); + enable_MAC(ai, &rsp, 1); } /* This function wraps PC4500_writerid with a MAC disable */ static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data, - int len ) { + int len, int dummy ) { int rc; Resp rsp; - disable_MAC(ai); - rc = PC4500_writerid(ai, rid, rid_data, len); - enable_MAC(ai, &rsp); + disable_MAC(ai, 1); + rc = PC4500_writerid(ai, rid, rid_data, len, 1); + enable_MAC(ai, &rsp, 1); return rc; } @@ -3617,7 +3697,7 @@ } static int set_wep_key(struct airo_info *ai, u16 index, - const char *key, u16 keylen, int perm ) { + const char *key, u16 keylen, int perm, int lock ) { static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; WepKeyRid wkr; @@ -3639,7 +3719,7 @@ printk(KERN_INFO "Setting key %d\n", index); } - writeWepKeyRid(ai, &wkr, perm); + writeWepKeyRid(ai, &wkr, perm, lock); return 0; } @@ -3662,7 +3742,7 @@ (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) { index = data->wbuffer[0] - '0'; if (data->wbuffer[1] == '\n') { - set_wep_key(ai, index, 0, 0, 1); + set_wep_key(ai, index, 0, 0, 1, 1); return; } j = 2; @@ -3681,7 +3761,7 @@ break; } } - set_wep_key(ai, index, key, i/3, 1); + set_wep_key(ai, index, key, i/3, 1, 1); } static int proc_wepkey_open( struct inode *inode, struct file *file ) { @@ -3937,10 +4017,9 @@ add_timer(&apriv->timer); return; } - __set_bit(FLAG_LOCKED, &apriv->flags); - readConfigRid(apriv); - disable_MAC(apriv); + readConfigRid(apriv, 0); + disable_MAC(apriv, 0); switch(apriv->config.authType) { case AUTH_ENCRYPT: /* So drop to OPEN */ @@ -3948,13 +4027,13 @@ break; case AUTH_SHAREDKEY: if (apriv->keyindex < auto_wep) { - set_wep_key(apriv, apriv->keyindex, 0, 0, 0); + set_wep_key(apriv, apriv->keyindex, 0, 0, 0, 0); apriv->config.authType = AUTH_SHAREDKEY; apriv->keyindex++; } else { /* Drop to ENCRYPT */ apriv->keyindex = 0; - set_wep_key(apriv, apriv->defindex, 0, 0, 0); + set_wep_key(apriv, apriv->defindex, 0, 0, 0, 0); apriv->config.authType = AUTH_ENCRYPT; } break; @@ -3962,9 +4041,8 @@ apriv->config.authType = AUTH_SHAREDKEY; } apriv->need_commit = 1; - writeConfigRid(apriv); - enable_MAC(apriv, &rsp); - clear_bit(FLAG_LOCKED, &apriv->flags); + writeConfigRid(apriv, 0); + enable_MAC(apriv, &rsp, 0); up(&apriv->sem); /* Schedule check to see if the change worked */ @@ -4144,9 +4222,11 @@ struct airo_info *local = dev->priv; StatusRid status_rid; /* Card status info */ - readStatusRid(local, &status_rid); + if ((local->config.opmode & 0xFF) == MODE_STA_ESS) + status_rid.channel = local->config.channelSet; + else + readStatusRid(local, &status_rid); - /* Will return zero in infrastructure mode */ #ifdef WEXT_USECHANNELS fwrq->m = ((int)status_rid.channel) + 1; fwrq->e = 0; @@ -4200,9 +4280,9 @@ SSID_rid.ssids[index].len = dwrq->length - 1; } /* Write it to the card */ - disable_MAC(local); + disable_MAC(local, 1); writeSsidRid(local, &SSID_rid); - enable_MAC(local, &rsp); + enable_MAC(local, &rsp, 1); return 0; } @@ -4264,9 +4344,9 @@ memset(&APList_rid, 0, sizeof(APList_rid)); APList_rid.len = sizeof(APList_rid); memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN); - disable_MAC(local); + disable_MAC(local, 1); writeAPListRid(local, &APList_rid); - enable_MAC(local, &rsp); + enable_MAC(local, &rsp, 1); } return 0; } @@ -4515,28 +4595,52 @@ char *extra) { struct airo_info *local = dev->priv; + int commit = 1; + + if ((local->config.rmode & 0xff) >= RXMODE_RFMON) + commit = 2; switch(*uwrq) { case IW_MODE_ADHOC: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_STA_IBSS; + local->config.rmode &= 0xfe00; + local->config.scanMode = SCANMODE_ACTIVE; + local->flags &= ~FLAG_802_11; break; case IW_MODE_INFRA: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_STA_ESS; + local->config.rmode &= 0xfe00; + local->config.scanMode = SCANMODE_ACTIVE; + local->flags &= ~FLAG_802_11; break; case IW_MODE_MASTER: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP; + local->config.rmode &= 0xfe00; + local->config.scanMode = SCANMODE_ACTIVE; + local->flags &= ~FLAG_802_11; break; case IW_MODE_REPEAT: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP_RPTR; + local->config.rmode &= 0xfe00; + local->config.scanMode = SCANMODE_ACTIVE; + local->flags &= ~FLAG_802_11; + break; + case IW_MODE_MONITOR: + local->config.opmode &= 0xFF00; + local->config.opmode |= MODE_STA_ESS; + local->config.rmode &= 0xfe00; + local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; + local->config.scanMode = SCANMODE_PASSIVE; + local->flags |= FLAG_802_11; break; default: return -EINVAL; } - local->need_commit = 1; + local->need_commit = commit; return -EINPROGRESS; /* Call commit handler */ } @@ -4622,7 +4726,7 @@ /* Copy the key in the driver */ memcpy(key.key, extra, dwrq->length); /* Send the key to the card */ - set_wep_key(local, index, key.key, key.len, 1); + set_wep_key(local, index, key.key, key.len, 1, 1); } /* WE specify that if a valid key is set, encryption * should be enabled (user may turn it off later) @@ -4636,7 +4740,7 @@ /* Do we want to just set the transmit key index ? */ int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; if ((index>=0) && (index<(cap_rid.softCap&0x80)?4:1)) { - set_wep_key(local, index, 0, 0, 1); + set_wep_key(local, index, 0, 0, 1, 1); } else /* Don't complain if only change the mode */ if(!dwrq->flags & IW_ENCODE_MODE) { @@ -4841,7 +4945,7 @@ readCapabilityRid(local, &cap_rid); dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(range)); + memset(range, 0, sizeof(*range)); range->min_nwid = 0x0000; range->max_nwid = 0x0000; range->num_channels = 14; @@ -5132,7 +5236,7 @@ Resp rsp; /* Note : you may have realised that, as this is a SET operation, - * this is priviledged and therefore a normal user can't + * this is privileged and therefore a normal user can't * perform scanning. * This is not an error, while the device perform scanning, * traffic doesn't flow, so it's a perfect DoS... @@ -5154,7 +5258,7 @@ /*------------------------------------------------------------------*/ /* - * Translate scan data returned from the card to a card independant + * Translate scan data returned from the card to a card independent * format that the Wireless Tools will understand - Jean II */ static inline char *airo_translate_scan(struct net_device *dev, @@ -5281,7 +5385,7 @@ * consequences are begnign. So I don't bother fixing it - Javier */ /* Try to read the first entry of the scan result */ - rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList)); + rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1); if((rc) || (BSSList.index == 0xffff)) { /* Client error, no scan results... * The caller need to restart the scan. */ @@ -5297,7 +5401,7 @@ /* Read next entry */ rc = PC4500_readrid(ai, RID_BSSLISTNEXT, - &BSSList, sizeof(BSSList)); + &BSSList, sizeof(BSSList), 1); } /* Length of data */ dwrq->length = (current_ev - extra); @@ -5307,6 +5411,7 @@ } #endif /* WIRELESS_EXT > 13 */ +#if WIRELESS_EXT <= 15 #ifdef WIRELESS_SPY /*------------------------------------------------------------------*/ /* @@ -5369,6 +5474,7 @@ return 0; } #endif /* WIRELESS_SPY */ +#endif /* WIRELESS_EXT <= 15 */ /*------------------------------------------------------------------*/ /* @@ -5387,9 +5493,22 @@ /* Some of the "SET" function may have modified some of the * parameters. It's now time to commit them in the card */ - disable_MAC(local); - writeConfigRid(local); - enable_MAC(local, &rsp); + disable_MAC(local, 1); + if (local->need_commit > 1) { + APListRid APList_rid; + SsidRid SSID_rid; + + readAPListRid(local, &APList_rid); + readSsidRid(local, &SSID_rid); + reset_airo_card(dev); + disable_MAC(local, 1); + writeSsidRid(local, &SSID_rid); + writeAPListRid(local, &APList_rid); + } + writeConfigRid(local, 1); + enable_MAC(local, &rsp, 1); + if (local->need_commit > 1) + airo_set_promisc(local); return 0; } @@ -5426,6 +5545,12 @@ (iw_handler) NULL, /* SIOCGIWPRIV */ (iw_handler) NULL, /* SIOCSIWSTATS */ (iw_handler) NULL, /* SIOCGIWSTATS */ +#if WIRELESS_EXT > 15 + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ +#else /* WIRELESS_EXT > 15 */ #ifdef WIRELESS_SPY (iw_handler) airo_set_spy, /* SIOCSIWSPY */ (iw_handler) airo_get_spy, /* SIOCGIWSPY */ @@ -5435,6 +5560,7 @@ #endif /* WIRELESS_SPY */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ +#endif /* WIRELESS_EXT > 15 */ (iw_handler) airo_set_wap, /* SIOCSIWAP */ (iw_handler) airo_get_wap, /* SIOCGIWAP */ (iw_handler) NULL, /* -- hole -- */ @@ -5488,6 +5614,10 @@ standard: (iw_handler *) airo_handler, private: (iw_handler *) airo_private_handler, private_args: (struct iw_priv_args *) airo_private_args, +#if WIRELESS_EXT > 15 + spy_offset: ((void *) (&((struct airo_info *) NULL)->spy_data) - + (void *) NULL), +#endif /* WIRELESS_EXT > 15 */ }; #endif /* WIRELESS_EXT > 12 */ @@ -5822,7 +5952,7 @@ break; } - /* Seperate R/W functions bracket legality here + /* Separate R/W functions bracket legality here */ if ( com.command <= AIROGMICSTATS ) rc = readrids(dev,&com); @@ -5860,7 +5990,6 @@ * * TODO : * o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs) - * o Find the noise level * * Jean */ @@ -5873,7 +6002,7 @@ /* Get stats out of the card */ readStatusRid(local, &status_rid); - readStatsRid(local, &stats_rid, RID_STATS); + readStatsRid(local, &stats_rid, RID_STATS, 1); /* The status */ local->wstats.status = status_rid.mode; @@ -5884,8 +6013,13 @@ local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm; else local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; - local->wstats.qual.noise = 0; - local->wstats.qual.updated = 3; + if (status_rid.len >= 124) { + local->wstats.qual.noise = 256 - status_rid.noisedBm; + local->wstats.qual.updated = 7; + } else { + local->wstats.qual.noise = 0; + local->wstats.qual.updated = 3; + } /* Packets discarded in the wireless adapter due to wireless * specific problems */ @@ -5900,6 +6034,7 @@ #endif /* WIRELESS_EXT */ #ifdef CISCO_EXT +#define RIDS_SIZE 2048 /* * This just translates from driver IOCTL codes to the command codes to * feed to the radio's host interface. Things can be added/deleted @@ -5908,7 +6043,7 @@ */ static int readrids(struct net_device *dev, aironet_ioctl *comp) { unsigned short ridcode; - unsigned char iobuf[2048]; + unsigned char *iobuf; struct airo_info *ai = dev->priv; if (ai->flags & FLAG_FLASHING) @@ -5917,7 +6052,7 @@ switch(comp->command) { case AIROGCAP: ridcode = RID_CAPABILITIES; break; - case AIROGCFG: writeConfigRid (ai); + case AIROGCFG: writeConfigRid (ai, 1); ridcode = RID_CONFIG; break; case AIROGSLIST: ridcode = RID_SSID; break; case AIROGVLIST: ridcode = RID_APLIST; break; @@ -5946,15 +6081,21 @@ break; } - PC4500_readrid(ai,ridcode,iobuf,sizeof(iobuf)); + if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL) + return -ENOMEM; + + PC4500_readrid(ai,ridcode,iobuf,RIDS_SIZE, 1); /* get the count of bytes in the rid docs say 1st 2 bytes is it. * then return it to the user * 9/22/2000 Honor user given length */ if (copy_to_user(comp->data, iobuf, - min((int)comp->len, (int)sizeof(iobuf)))) + min((int)comp->len, (int)RIDS_SIZE))) { + kfree (iobuf); return -EFAULT; + } + kfree (iobuf); return 0; } @@ -5966,8 +6107,8 @@ struct airo_info *ai = dev->priv; int ridcode, enabled; Resp rsp; - static int (* writer)(struct airo_info *, u16 rid, const void *, int); - unsigned char iobuf[2048]; + static int (* writer)(struct airo_info *, u16 rid, const void *, int, int); + unsigned char *iobuf; /* Only super-user can write RIDs */ if (!capable(CAP_NET_ADMIN)) @@ -5996,7 +6137,7 @@ * same with MAC off */ case AIROPMACON: - if (enable_MAC(ai, &rsp) != 0) + if (enable_MAC(ai, &rsp, 1) != 0) return -EIO; return 0; @@ -6005,7 +6146,7 @@ * as disable_MAC. it's probably so short the compiler does not gen one. */ case AIROPMACOFF: - disable_MAC(ai); + disable_MAC(ai, 1); return 0; /* This command merely clears the counts does not actually store any data @@ -6013,25 +6154,36 @@ * writerid routines. */ case AIROPSTCLR: - PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,sizeof(iobuf)); + if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL) + return -ENOMEM; + + PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDS_SIZE, 1); enabled = ai->micstats.enabled; memset(&ai->micstats,0,sizeof(ai->micstats)); ai->micstats.enabled = enabled; if (copy_to_user(comp->data, iobuf, - min((int)comp->len, (int)sizeof(iobuf)))) + min((int)comp->len, (int)RIDS_SIZE))) { + kfree (iobuf); return -EFAULT; + } + kfree (iobuf); return 0; default: return -EOPNOTSUPP; /* Blarg! */ } - if(comp->len > sizeof(iobuf)) + if(comp->len > RIDS_SIZE) return -EINVAL; - if (copy_from_user(iobuf,comp->data,comp->len)) + if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL) + return -ENOMEM; + + if (copy_from_user(iobuf,comp->data,comp->len)) { + kfree (iobuf); return -EFAULT; + } if (comp->command == AIROPCFG) { ConfigRid *cfg = (ConfigRid *)iobuf; @@ -6045,8 +6197,11 @@ ai->flags &= ~FLAG_ADHOC; } - if((*writer)(ai, ridcode, iobuf,comp->len)) + if((*writer)(ai, ridcode, iobuf,comp->len,1)) { + kfree (iobuf); return -EIO; + } + kfree (iobuf); return 0; } @@ -6125,7 +6280,7 @@ */ int cmdreset(struct airo_info *ai) { - disable_MAC(ai); + disable_MAC(ai, 1); if(!waitbusy (ai)){ printk(KERN_INFO "Waitbusy hang before RESET\n"); diff -urN linux-2.4.21/drivers/net/wireless/airport.c linux-2.4.22/drivers/net/wireless/airport.c --- linux-2.4.21/drivers/net/wireless/airport.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/airport.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,4 +1,4 @@ -/* airport.c 0.13b +/* airport.c 0.13d * * A driver for "Hermes" chipset based Apple Airport wireless * card. @@ -95,7 +95,7 @@ netif_device_detach(dev); - priv->hw_unavailable = 1; + priv->hw_unavailable++; orinoco_unlock(priv, &flags); @@ -121,14 +121,15 @@ netif_device_attach(dev); - if (priv->open) { + priv->hw_unavailable--; + + if (priv->open && (! priv->hw_unavailable)) { err = __orinoco_up(dev); if (err) printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n", dev->name, err); } - priv->hw_unavailable = 0; spin_unlock_irqrestore(&priv->lock, flags); @@ -140,8 +141,21 @@ static int airport_hard_reset(struct orinoco_private *priv) { + /* It would be nice to power cycle the Airport for a real hard + * reset, but for some reason although it appears to + * re-initialize properly, it falls in a screaming heap + * shortly afterwards. */ +#if 0 + struct net_device *dev = priv->ndev; struct airport *card = priv->card; + /* Vitally important. If we don't do this it seems we get an + * interrupt somewhere during the power cycle, since + * hw_unavailable is already set it doesn't get ACKed, we get + * into an interrupt loop and the the PMU decides to turn us + * off. */ + disable_irq(dev->irq); + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(HZ); @@ -149,6 +163,10 @@ current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(HZ); + enable_irq(dev->irq); + schedule_timeout(HZ); +#endif + return 0; } @@ -209,7 +227,7 @@ /* Reset it before we get the interrupt */ hermes_init(hw); - if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) { + if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", dev)) { printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq); goto failed; } @@ -251,7 +269,7 @@ card->ndev_registered = 0; if (card->irq_requested) - free_irq(dev->irq, priv); + free_irq(dev->irq, dev); card->irq_requested = 0; if (card->vaddr) @@ -269,11 +287,10 @@ kfree(dev); } /* airport_detach */ -static char version[] __initdata = "airport.c 0.13b (Benjamin Herrenschmidt )"; +static char version[] __initdata = "airport.c 0.13d (Benjamin Herrenschmidt )"; MODULE_AUTHOR("Benjamin Herrenschmidt "); MODULE_DESCRIPTION("Driver for the Apple Airport wireless card."); MODULE_LICENSE("Dual MPL/GPL"); -EXPORT_NO_SYMBOLS; static int __init init_airport(void) @@ -282,15 +299,11 @@ printk(KERN_DEBUG "%s\n", version); - MOD_INC_USE_COUNT; - /* Lookup card in device tree */ airport_node = find_devices("radio"); if (airport_node && !strcmp(airport_node->parent->name, "mac-io")) airport_dev = airport_attach(airport_node); - MOD_DEC_USE_COUNT; - return airport_dev ? 0 : -ENODEV; } diff -urN linux-2.4.21/drivers/net/wireless/hermes.c linux-2.4.22/drivers/net/wireless/hermes.c --- linux-2.4.21/drivers/net/wireless/hermes.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/hermes.c 2003-08-25 04:44:42.000000000 -0700 @@ -544,4 +544,9 @@ return 0; } +static void __exit exit_hermes(void) +{ +} + module_init(init_hermes); +module_exit(exit_hermes); diff -urN linux-2.4.21/drivers/net/wireless/hermes.h linux-2.4.22/drivers/net/wireless/hermes.h --- linux-2.4.21/drivers/net/wireless/hermes.h 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/hermes.h 2003-08-25 04:44:42.000000000 -0700 @@ -250,7 +250,6 @@ u16 scanreason; /* ??? */ struct hermes_scan_apinfo aps[35]; /* Scan result */ } __attribute__ ((packed)); - #define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000) #define HERMES_LINKSTATUS_CONNECTED (0x0001) #define HERMES_LINKSTATUS_DISCONNECTED (0x0002) @@ -368,7 +367,7 @@ if (hw->io_space) { insw(hw->iobase + off, buf, count); } else { - int i; + unsigned i; u16 *p; /* This needs to *not* byteswap (like insw()) but @@ -388,7 +387,7 @@ if (hw->io_space) { outsw(hw->iobase + off, buf, count); } else { - int i; + unsigned i; const u16 *p; /* This needs to *not* byteswap (like outsw()) but @@ -401,6 +400,21 @@ } } +static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count) +{ + unsigned i; + + off = off << hw->reg_spacing;; + + if (hw->io_space) { + for (i = 0; i < count; i++) + outw(0, hw->iobase + off); + } else { + for (i = 0; i < count; i++) + writew(0, hw->iobase + off); + } +} + #define HERMES_READ_RECORD(hw, bap, rid, buf) \ (hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf))) #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \ diff -urN linux-2.4.21/drivers/net/wireless/orinoco.c linux-2.4.22/drivers/net/wireless/orinoco.c --- linux-2.4.21/drivers/net/wireless/orinoco.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/orinoco.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,4 +1,4 @@ -/* orinoco.c 0.13b - (formerly known as dldwd_cs.c and orinoco_cs.c) +/* orinoco.c 0.13d - (formerly known as dldwd_cs.c and orinoco_cs.c) * * A driver for Hermes or Prism 2 chipset based PCMCIA wireless * adaptors, with Lucent/Agere, Intersil or Symbol firmware. @@ -345,11 +345,45 @@ * we are connected (avoids cofusing the firmware), and only * give LINKSTATUS printk()s if the status has changed. * + * v0.13b -> v0.13c - 11 Mar 2003 - David Gibson + * o Cleanup: use dev instead of priv in various places. + * o Bug fix: Don't ReleaseConfiguration on RESET_PHYSICAL event + * if we're in the middle of a (driver initiated) hard reset. + * o Bug fix: ETH_ZLEN is supposed to include the header + * (Dionysus Blazakis & Manish Karir) + * o Convert to using workqueues instead of taskqueues (and + * backwards compatibility macros for pre 2.5.41 kernels). + * o Drop redundant (I think...) MOD_{INC,DEC}_USE_COUNT in + * airport.c + * o New orinoco_tmd.c init module from Joerg Dorchain for + * TMD7160 based PCI to PCMCIA bridges (similar to + * orinoco_plx.c). + * + * v0.13c -> v0.13d - 22 Apr 2003 - David Gibson + * o Make hw_unavailable a counter, rather than just a flag, this + * is necessary to avoid some races (such as a card being + * removed in the middle of orinoco_reset(). + * o Restore Release/RequestConfiguration in the PCMCIA event handler + * when dealing with a driver initiated hard reset. This is + * necessary to prevent hangs due to a spurious interrupt while + * the reset is in progress. + * o Clear the 802.11 header when transmitting, even though we + * don't use it. This fixes a long standing bug on some + * firmwares, which seem to get confused if that isn't done. + * o Be less eager to de-encapsulate SNAP frames, only do so if + * the OUI is 00:00:00 or 00:00:f8, leave others alone. The old + * behaviour broke CDP (Cisco Discovery Protocol). + * o Use dev instead of priv for free_irq() as well as + * request_irq() (oops). + * o Attempt to reset rather than giving up if we get too many + * IRQs. + * o Changed semantics of __orinoco_down() so it can be called + * safely with hw_unavailable set. It also now clears the + * linkstatus (since we're going to have to reassociate). + * * TODO - * o New wireless extensions API (patch from Moustafa * Youssef, updated by Jim Carter). - * o Fix PCMCIA hard resets with pcmcia-cs. * o Handle de-encapsulation within network layer, provide 802.11 * headers (patch from Thomas 'Dent' Mirlacher) * o Fix possible races in SPY handling. @@ -373,7 +407,7 @@ * flag after taking the lock, and if it is set, give up on whatever * they are doing and drop the lock again. The orinoco_lock() * function handles this (it unlocks and returns -EBUSY if - * hw_unavailable is true). */ + * hw_unavailable is non-zero). */ #include @@ -522,7 +556,7 @@ /* Hardware control routines */ -static int __orinoco_program_rids(struct orinoco_private *priv); +static int __orinoco_program_rids(struct net_device *dev); static int __orinoco_hw_set_bitrate(struct orinoco_private *priv); static int __orinoco_hw_setup_wep(struct orinoco_private *priv); @@ -535,14 +569,14 @@ static void __orinoco_set_multicast_list(struct net_device *dev); /* Interrupt handling routines */ -static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw); -static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw); -static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw); -static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw); -static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw); -static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw); -static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw); -static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw); +static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw); +static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw); +static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw); +static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw); +static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw); +static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw); +static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw); +static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw); /* ioctl() routines */ static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq); @@ -577,7 +611,7 @@ struct hermes *hw = &priv->hw; int err; - err = __orinoco_program_rids(priv); + err = __orinoco_program_rids(dev); if (err) { printk(KERN_ERR "%s: Error %d configuring card\n", dev->name, err); @@ -606,14 +640,25 @@ netif_stop_queue(dev); - err = hermes_disable_port(hw, 0); - if (err) { - printk(KERN_ERR "%s: Error %d disabling MAC port\n", - dev->name, err); - return err; + if (! priv->hw_unavailable) { + if (! priv->broken_disableport) { + err = hermes_disable_port(hw, 0); + if (err) { + /* Some firmwares (e.g. Intersil 1.3.x) seem + * to have problems disabling the port, oh + * well, too bad. */ + printk(KERN_WARNING "%s: Error %d disabling MAC port\n", + dev->name, err); + priv->broken_disableport = 1; + } + } + hermes_set_irqmask(hw, 0); + hermes_write_regn(hw, EVACK, 0xffff); } - hermes_set_irqmask(hw, 0); - hermes_write_regn(hw, EVACK, 0xffff); + + /* firmware will have to reassociate */ + priv->last_linkstatus = 0xffff; + priv->connected = 0; return 0; } @@ -656,38 +701,38 @@ if (err) return err; - priv->open = 1; - err = __orinoco_up(dev); + if (! err) + priv->open = 1; + orinoco_unlock(priv, &flags); return err; } -static int orinoco_stop(struct net_device *dev) +int orinoco_stop(struct net_device *dev) { struct orinoco_private *priv = dev->priv; int err = 0; /* We mustn't use orinoco_lock() here, because we need to be - able to close the interface, even if hw_unavailable is set + able to close the interface even if hw_unavailable is set (e.g. as we're released after a PC Card removal) */ spin_lock_irq(&priv->lock); priv->open = 0; - if (! priv->hw_unavailable) - err = __orinoco_down(dev); + err = __orinoco_down(dev); spin_unlock_irq(&priv->lock); return err; } -static int __orinoco_program_rids(struct orinoco_private *priv) +static int __orinoco_program_rids(struct net_device *dev) { - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = dev->priv; hermes_t *hw = &priv->hw; int err; struct hermes_idstring idbuf; @@ -873,51 +918,84 @@ } /* xyzzy */ -static int orinoco_reconfigure(struct orinoco_private *priv) +static int orinoco_reconfigure(struct net_device *dev) { + struct orinoco_private *priv = dev->priv; struct hermes *hw = &priv->hw; unsigned long flags; int err = 0; - orinoco_lock(priv, &flags); + if (priv->broken_disableport) { + schedule_work(&priv->reset_work); + return 0; + } + err = orinoco_lock(priv, &flags); + if (err) + return err; + + err = hermes_disable_port(hw, 0); if (err) { - printk(KERN_ERR "%s: Unable to disable port in orinco_reconfigure()\n", - priv->ndev->name); + printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n", + dev->name); + priv->broken_disableport = 1; goto out; } - err = __orinoco_program_rids(priv); - if (err) + err = __orinoco_program_rids(dev); + if (err) { + printk(KERN_WARNING "%s: Unable to reconfigure card\n", + dev->name); goto out; + } err = hermes_enable_port(hw, 0); if (err) { - printk(KERN_ERR "%s: Unable to enable port in orinco_reconfigure()\n", - priv->ndev->name); + printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n", + dev->name); goto out; } out: + if (err) { + printk(KERN_WARNING "%s: Resetting instead...\n", dev->name); + schedule_work(&priv->reset_work); + err = 0; + } + orinoco_unlock(priv, &flags); return err; } /* This must be called from user context, without locks held - use - * schedule_task() */ + * schedule_work() */ static void orinoco_reset(struct net_device *dev) { struct orinoco_private *priv = dev->priv; + struct hermes *hw = &priv->hw; int err; unsigned long flags; err = orinoco_lock(priv, &flags); if (err) + /* When the hardware becomes available again, whatever + * detects that is responsible for re-initializing + * it. So no need for anything further*/ return; - priv->hw_unavailable = 1; + netif_stop_queue(dev); + + /* Shut off interrupts. Depending on what state the hardware + * is in, this might not work, but we'll try anyway */ + hermes_set_irqmask(hw, 0); + hermes_write_regn(hw, EVACK, 0xffff); + + priv->hw_unavailable++; + priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */ + priv->connected = 0; + orinoco_unlock(priv, &flags); if (priv->hard_reset) @@ -936,18 +1014,22 @@ return; } - spin_lock_irqsave(&priv->lock, flags); + spin_lock_irq(&priv->lock); /* This has to be called from user context */ - priv->hw_unavailable = 0; + priv->hw_unavailable--; - err = __orinoco_up(dev); - if (err) { - printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n", - dev->name, err); - } else - dev->trans_start = jiffies; + /* priv->open or priv->hw_unavailable might have changed while + * we dropped the lock */ + if (priv->open && (! priv->hw_unavailable)) { + err = __orinoco_up(dev); + if (err) { + printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n", + dev->name, err); + } else + dev->trans_start = jiffies; + } - orinoco_unlock(priv, &flags); + spin_unlock_irq(&priv->lock); return; } @@ -979,10 +1061,18 @@ } } +/* Does the frame have a SNAP header indicating it should be + * de-encapsulated to Ethernet-II? */ static inline int -is_snap(struct header_struct *hdr) +is_ethersnap(struct header_struct *hdr) { - return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3); + /* We de-encapsulate all packets which, a) have SNAP headers + * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header + * and where b) the OUI of the SNAP header is 00:00:00 or + * 00:00:f8 - we need both because different APs appear to use + * different OUIs for some reason */ + return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0) + && ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) ); } static void @@ -1140,7 +1230,8 @@ return 0; } -static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]) +static int orinoco_hw_get_bssid(struct orinoco_private *priv, + char buf[ETH_ALEN]) { hermes_t *hw = &priv->hw; int err = 0; @@ -1159,7 +1250,7 @@ } static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, - char buf[IW_ESSID_MAX_SIZE+1]) + char buf[IW_ESSID_MAX_SIZE+1]) { hermes_t *hw = &priv->hw; int err = 0; @@ -1236,9 +1327,8 @@ } if ( (channel < 1) || (channel > NUM_CHANNELS) ) { - struct net_device *dev = priv->ndev; - - printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel); + printk(KERN_WARNING "%s: Channel out of range (%d)!\n", + priv->ndev->name, channel); err = -EBUSY; goto out; @@ -1253,8 +1343,8 @@ return err ? err : freq; } -static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates, - s32 *rates, int max) +static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, + int *numrates, s32 *rates, int max) { hermes_t *hw = &priv->hw; struct hermes_idstring list; @@ -1354,9 +1444,9 @@ */ void orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct orinoco_private *priv = (struct orinoco_private *) dev_id; + struct net_device *dev = (struct net_device *)dev_id; + struct orinoco_private *priv = dev->priv; hermes_t *hw = &priv->hw; - struct net_device *dev = priv->ndev; int count = MAX_IRQLOOPS_PER_IRQ; u16 evstat, events; /* These are used to detect a runaway interrupt situation */ @@ -1380,11 +1470,11 @@ while (events && count--) { if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) { - printk(KERN_CRIT "%s: IRQ handler is looping too \ -much! Shutting down.\n", - dev->name); - /* Perform an emergency shutdown */ + printk(KERN_WARNING "%s: IRQ handler is looping too " + "much! Resetting.\n", dev->name); + /* Disable interrupts for now */ hermes_set_irqmask(hw, 0); + schedule_work(&priv->reset_work); break; } @@ -1395,21 +1485,21 @@ } if (events & HERMES_EV_TICK) - __orinoco_ev_tick(priv, hw); + __orinoco_ev_tick(dev, hw); if (events & HERMES_EV_WTERR) - __orinoco_ev_wterr(priv, hw); + __orinoco_ev_wterr(dev, hw); if (events & HERMES_EV_INFDROP) - __orinoco_ev_infdrop(priv, hw); + __orinoco_ev_infdrop(dev, hw); if (events & HERMES_EV_INFO) - __orinoco_ev_info(priv, hw); + __orinoco_ev_info(dev, hw); if (events & HERMES_EV_RX) - __orinoco_ev_rx(priv, hw); + __orinoco_ev_rx(dev, hw); if (events & HERMES_EV_TXEXC) - __orinoco_ev_txexc(priv, hw); + __orinoco_ev_txexc(dev, hw); if (events & HERMES_EV_TX) - __orinoco_ev_tx(priv, hw); + __orinoco_ev_tx(dev, hw); if (events & HERMES_EV_ALLOC) - __orinoco_ev_alloc(priv, hw); + __orinoco_ev_alloc(dev, hw); hermes_write_regn(hw, EVACK, events); @@ -1420,22 +1510,22 @@ orinoco_unlock(priv, &flags); } -static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw) { - printk(KERN_DEBUG "%s: TICK\n", priv->ndev->name); + printk(KERN_DEBUG "%s: TICK\n", dev->name); } -static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw) { /* This seems to happen a fair bit under load, but ignoring it seems to work fine...*/ printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n", - priv->ndev->name); + dev->name); } -static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) { - printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev->name); + printk(KERN_WARNING "%s: Information frame lost.\n", dev->name); } static void print_linkstatus(struct net_device *dev, u16 status) @@ -1472,9 +1562,9 @@ dev->name, s, status); } -static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) { - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = dev->priv; u16 infofid; struct { u16 len; @@ -1573,9 +1663,9 @@ } } -static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) { - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = dev->priv; struct net_device_stats *stats = &priv->stats; struct iw_statistics *wstats = &priv->wstats; struct sk_buff *skb = NULL; @@ -1664,7 +1754,7 @@ * So, check ourselves */ if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) || ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) || - is_snap(&hdr)) { + is_ethersnap(&hdr)) { /* These indicate a SNAP within 802.2 LLC within 802.11 frame which we'll need to de-encapsulate to the original EthernetII frame. */ @@ -1726,9 +1816,9 @@ return; } -static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) { - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = dev->priv; struct net_device_stats *stats = &priv->stats; u16 fid = hermes_read_regn(hw, TXCOMPLFID); struct hermes_tx_descriptor desc; @@ -1752,8 +1842,9 @@ hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); } -static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw) { + struct orinoco_private *priv = dev->priv; struct net_device_stats *stats = &priv->stats; stats->tx_packets++; @@ -1761,9 +1852,10 @@ hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); } -static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw) +static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw) { - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = dev->priv; + u16 fid = hermes_read_regn(hw, ALLOCFID); if (fid != priv->txfid) { @@ -1945,7 +2037,7 @@ TRACE_ENTER(dev->name); - /* No need to lock, the resetting flag is already set in + /* No need to lock, the hw_unavailable flag is already set in * alloc_orinocodev() */ priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; @@ -2081,8 +2173,6 @@ priv->wep_on = 0; priv->tx_key = 0; - priv->hw_unavailable = 0; - err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); if (err == -EIO) { /* Try workaround for old Symbol firmware bug */ @@ -2102,6 +2192,12 @@ goto out; } + /* Make the hardware available, as long as it hasn't been + * removed elsewhere (e.g. by PCMCIA hot unplug) */ + spin_lock_irq(&priv->lock); + priv->hw_unavailable--; + spin_unlock_irq(&priv->lock); + printk(KERN_DEBUG "%s: ready\n", dev->name); out: @@ -2267,7 +2363,7 @@ /* Length of the packet body */ /* FIXME: what if the skb is smaller than this? */ - len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN); + len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN); eh = (struct ethhdr *)skb->data; @@ -2281,6 +2377,12 @@ goto fail; } + /* Clear the 802.11 header and data length fields - some + * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused + * if this isn't done. */ + hermes_clear_words(hw, HERMES_DATA0, + HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); + /* Encapsulate Ethernet-II frames */ if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */ struct header_struct hdr; @@ -2362,7 +2464,7 @@ stats->tx_errors++; - schedule_task(&priv->timeout_task); + schedule_work(&priv->reset_work); } static int @@ -2532,7 +2634,7 @@ } err = orinoco_hw_get_bitratelist(priv, &numrates, - range.bitrate, IW_MAX_BITRATES); + range.bitrate, IW_MAX_BITRATES); if (err) return err; range.num_bitrates = numrates; @@ -3128,7 +3230,7 @@ rrq->value = 5500000; else rrq->value = val * 1000000; - break; + break; case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */ case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */ for (i = 0; i < BITRATE_TABLE_SIZE; i++) @@ -3754,7 +3856,7 @@ printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name); - schedule_task(&priv->timeout_task); + schedule_work(&priv->reset_work); break; case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */ @@ -3839,7 +3941,7 @@ } if (! err && changed && netif_running(dev)) { - err = orinoco_reconfigure(priv); + err = orinoco_reconfigure(dev); } TRACE_EXIT(dev->name); @@ -3924,7 +4026,7 @@ DEBUG_REC(PRIID,WORDS), DEBUG_REC(PRISUPRANGE,WORDS), DEBUG_REC(CFIACTRANGES,WORDS), - DEBUG_REC(NICSERNUM,WORDS), + DEBUG_REC(NICSERNUM,XSTRING), DEBUG_REC(NICID,WORDS), DEBUG_REC(MFISUPRANGE,WORDS), DEBUG_REC(CFISUPRANGE,WORDS), @@ -4062,7 +4164,7 @@ priv->hw_unavailable = 1; /* orinoco_init() must clear this * before anything else touches the * hardware */ - INIT_TQUEUE(&priv->timeout_task, (void (*)(void *))orinoco_reset, dev); + INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev); priv->last_linkstatus = 0xffff; priv->connected = 0; @@ -4079,13 +4181,14 @@ EXPORT_SYMBOL(__orinoco_up); EXPORT_SYMBOL(__orinoco_down); +EXPORT_SYMBOL(orinoco_stop); EXPORT_SYMBOL(orinoco_reinit_firmware); EXPORT_SYMBOL(orinoco_interrupt); /* Can't be declared "const" or the whole __initdata section will * become const */ -static char version[] __initdata = "orinoco.c 0.13b (David Gibson and others)"; +static char version[] __initdata = "orinoco.c 0.13d (David Gibson and others)"; static int __init init_orinoco(void) { diff -urN linux-2.4.21/drivers/net/wireless/orinoco.h linux-2.4.22/drivers/net/wireless/orinoco.h --- linux-2.4.21/drivers/net/wireless/orinoco.h 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/orinoco.h 2003-08-25 04:44:42.000000000 -0700 @@ -11,9 +11,20 @@ #include #include #include -#include +#include #include "hermes.h" +/* Workqueue / task queue backwards compatibility stuff */ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) +#include +#else +#include +#define work_struct tq_struct +#define INIT_WORK INIT_TQUEUE +#define schedule_work schedule_task +#endif + /* To enable debug messages */ //#define ORINOCO_DEBUG 3 @@ -42,7 +53,7 @@ /* Synchronisation stuff */ spinlock_t lock; int hw_unavailable; - struct tq_struct timeout_task; + struct work_struct reset_work; /* driver state */ int open; @@ -72,6 +83,7 @@ int has_sensitivity; int nicbuf_size; u16 channel_mask; + int broken_disableport; /* Configuration paramaters */ u32 iw_mode; @@ -111,8 +123,8 @@ int (*hard_reset)(struct orinoco_private *)); extern int __orinoco_up(struct net_device *dev); extern int __orinoco_down(struct net_device *dev); -int orinoco_reinit_firmware(struct net_device *dev); - +extern int orinoco_stop(struct net_device *dev); +extern int orinoco_reinit_firmware(struct net_device *dev); extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs); /********************************************************************/ diff -urN linux-2.4.21/drivers/net/wireless/orinoco_cs.c linux-2.4.22/drivers/net/wireless/orinoco_cs.c --- linux-2.4.21/drivers/net/wireless/orinoco_cs.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/orinoco_cs.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,4 +1,4 @@ -/* orinoco_cs.c 0.13b - (formerly known as dldwd_cs.c) +/* orinoco_cs.c 0.13d - (formerly known as dldwd_cs.c) * * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/ @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +37,6 @@ #include #include #include -#include #include "orinoco.h" @@ -269,19 +267,12 @@ 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) { -#ifdef PCMCIA_DEBUG - printk(KERN_DEBUG "orinoco_cs: detach postponed, '%s' " - "still locked\n", link->dev->dev_name); -#endif - link->state |= DEV_STALE_LINK; - return; + orinoco_cs_release((u_long)link); + if (link->state & DEV_CONFIG) { + link->state |= DEV_STALE_LINK; + return; + } } /* Break the link with Card Services */ @@ -472,7 +463,7 @@ link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = orinoco_interrupt; - link->irq.Instance = priv; + link->irq.Instance = dev; CS_CHECK(RequestIRQ, link->handle, &link->irq); } @@ -549,18 +540,13 @@ dev_link_t *link = (dev_link_t *) arg; struct net_device *dev = link->priv; struct orinoco_private *priv = dev->priv; + unsigned long flags; - /* - 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 (priv->open) { - DEBUG(0, "orinoco_cs: release postponed, '%s' still open\n", - link->dev->dev_name); - link->state |= DEV_STALE_CONFIG; - return; - } + /* We're committed to taking the device away now, so mark the + * hardware as unavailable */ + spin_lock_irqsave(&priv->lock, flags); + priv->hw_unavailable++; + spin_unlock_irqrestore(&priv->lock, flags); /* Don't bother checking to see if these succeed or not */ CardServices(ReleaseConfiguration, link->handle); @@ -593,14 +579,9 @@ orinoco_lock(priv, &flags); netif_device_detach(dev); - priv->hw_unavailable = 1; + priv->hw_unavailable++; orinoco_unlock(priv, &flags); - -/* if (link->open) */ -/* orinoco_cs_stop(dev); */ - - mod_timer(&link->release, jiffies + HZ / 20); } break; @@ -619,13 +600,8 @@ a better way, short of rewriting the PCMCIA layer to not suck :-( */ if (! test_bit(0, &card->hard_reset_in_progress)) { - err = orinoco_lock(priv, &flags); - if (err) { - printk(KERN_ERR "%s: hw_unavailable on SUSPEND/RESET_PHYSICAL\n", - dev->name); - break; - } - + spin_lock_irqsave(&priv->lock, flags); + err = __orinoco_down(dev); if (err) printk(KERN_WARNING "%s: %s: Error %d downing interface\n", @@ -634,9 +610,9 @@ err); netif_device_detach(dev); - priv->hw_unavailable = 1; - - orinoco_unlock(priv, &flags); + priv->hw_unavailable++; + + spin_unlock_irqrestore(&priv->lock, flags); } CardServices(ReleaseConfiguration, link->handle); @@ -653,10 +629,6 @@ CardServices(RequestConfiguration, link->handle, &link->conf); - /* If we're only getting these events because - of the ResetCard in the hard reset, we - don't need to do anything - orinoco_reset() - will handle reinitialization. */ if (! test_bit(0, &card->hard_reset_in_progress)) { err = orinoco_reinit_firmware(dev); if (err) { @@ -668,9 +640,9 @@ spin_lock_irqsave(&priv->lock, flags); netif_device_attach(dev); - priv->hw_unavailable = 0; + priv->hw_unavailable--; - if (priv->open) { + if (priv->open && ! priv->hw_unavailable) { err = __orinoco_up(dev); if (err) printk(KERN_ERR "%s: Error %d restarting card\n", @@ -678,7 +650,7 @@ } - orinoco_unlock(priv, &flags); + spin_unlock_irqrestore(&priv->lock, flags); } } break; @@ -693,7 +665,7 @@ /* Can't be declared "const" or the whole __initdata section will * become const */ -static char version[] __initdata = "orinoco_cs.c 0.13b (David Gibson and others)"; +static char version[] __initdata = "orinoco_cs.c 0.13d (David Gibson and others)"; static int __init init_orinoco_cs(void) @@ -722,7 +694,6 @@ if (dev_list) DEBUG(0, "orinoco_cs: Removing leftover devices.\n"); while (dev_list != NULL) { - del_timer(&dev_list->release); if (dev_list->state & DEV_CONFIG) orinoco_cs_release((u_long) dev_list); orinoco_cs_detach(dev_list); diff -urN linux-2.4.21/drivers/net/wireless/orinoco_pci.c linux-2.4.22/drivers/net/wireless/orinoco_pci.c --- linux-2.4.21/drivers/net/wireless/orinoco_pci.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/orinoco_pci.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,4 +1,4 @@ -/* orinoco_pci.c 0.13b +/* orinoco_pci.c 0.13d * * Driver for Prism II devices that have a direct PCI interface * (i.e., not in a Pcmcia or PLX bridge) @@ -143,8 +143,6 @@ unsigned long timeout; u16 reg; - TRACE_ENTER(priv->ndev->name); - /* Assert the reset until the card notice */ hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK); printk(KERN_NOTICE "Reset done"); @@ -181,8 +179,6 @@ } printk(KERN_NOTICE "pci_cor : reg = 0x%X - %lX - %lX\n", reg, timeout, jiffies); - TRACE_EXIT(priv->ndev->name); - return 0; } @@ -232,7 +228,7 @@ hermes_struct_init(&(priv->hw), dev->base_addr, HERMES_MEM, HERMES_32BIT_REGSPACING); pci_set_drvdata(pdev, dev); - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, priv); + err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev); if (err) { printk(KERN_ERR "orinoco_pci: Error allocating IRQ %d.\n", pdev->irq); err = -EBUSY; @@ -264,7 +260,7 @@ unregister_netdev(dev); if (dev->irq) - free_irq(dev->irq, priv); + free_irq(dev->irq, dev); kfree(dev); } @@ -286,7 +282,7 @@ unregister_netdev(dev); if (dev->irq) - free_irq(dev->irq, priv); + free_irq(dev->irq, dev); if (priv->hw.iobase) iounmap((unsigned char *) priv->hw.iobase); @@ -321,7 +317,7 @@ netif_device_detach(dev); - priv->hw_unavailable = 1; + priv->hw_unavailable++; orinoco_unlock(priv, &flags); @@ -348,15 +344,15 @@ netif_device_attach(dev); - if (priv->open) { + priv->hw_unavailable--; + + if (priv->open && (! priv->hw_unavailable)) { err = __orinoco_up(dev); if (err) printk(KERN_ERR "%s: Error %d restarting card on orinoco_pci_resume()\n", dev->name, err); } - priv->hw_unavailable = 0; - spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -378,7 +374,7 @@ .resume = orinoco_pci_resume, }; -static char version[] __initdata = "orinoco_pci.c 0.13b (David Gibson & Jean Tourrilhes )"; +static char version[] __initdata = "orinoco_pci.c 0.13d (David Gibson & Jean Tourrilhes )"; MODULE_AUTHOR("David Gibson "); MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface"); MODULE_LICENSE("Dual MPL/GPL"); diff -urN linux-2.4.21/drivers/net/wireless/orinoco_plx.c linux-2.4.22/drivers/net/wireless/orinoco_plx.c --- linux-2.4.21/drivers/net/wireless/orinoco_plx.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/net/wireless/orinoco_plx.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,4 +1,4 @@ -/* orinoco_plx.c 0.13b +/* orinoco_plx.c 0.13d * * Driver for Prism II devices which would usually be driven by orinoco_cs, * but are connected to the PCI bus by a PLX9052. @@ -243,7 +243,7 @@ HERMES_IO, HERMES_16BIT_REGSPACING); pci_set_drvdata(pdev, dev); - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, priv); + err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev); if (err) { printk(KERN_ERR "orinoco_plx: Error allocating IRQ %d.\n", pdev->irq); err = -EBUSY; @@ -266,7 +266,7 @@ unregister_netdev(dev); if (dev->irq) - free_irq(dev->irq, priv); + free_irq(dev->irq, dev); kfree(priv); } @@ -285,7 +285,6 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = dev->priv; if (! dev) BUG(); @@ -293,7 +292,7 @@ unregister_netdev(dev); if (dev->irq) - free_irq(dev->irq, priv); + free_irq(dev->irq, dev); pci_set_drvdata(pdev, NULL); @@ -334,7 +333,7 @@ .resume = 0, }; -static char version[] __initdata = "orinoco_plx.c 0.13b (Daniel Barlow , David Gibson )"; +static char version[] __initdata = "orinoco_plx.c 0.13d (Daniel Barlow , David Gibson )"; MODULE_AUTHOR("Daniel Barlow "); MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge"); #ifdef MODULE_LICENSE diff -urN linux-2.4.21/drivers/net/wireless/orinoco_tmd.c linux-2.4.22/drivers/net/wireless/orinoco_tmd.c --- linux-2.4.21/drivers/net/wireless/orinoco_tmd.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/net/wireless/orinoco_tmd.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,240 @@ +/* orinoco_tmd.c 0.01 + * + * Driver for Prism II devices which would usually be driven by orinoco_cs, + * but are connected to the PCI bus by a TMD7160. + * + * Copyright (C) 2003 Joerg Dorchain + * based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + + * Caution: this is experimental and probably buggy. For success and + * failure reports for different cards and adaptors, see + * orinoco_tmd_pci_id_table near the end of the file. If you have a + * card we don't have the PCI id for, and looks like it should work, + * drop me mail with the id and "it works"/"it doesn't work". + * + * Note: if everything gets detected fine but it doesn't actually send + * or receive packets, your first port of call should probably be to + * try newer firmware in the card. Especially if you're doing Ad-Hoc + * modes + * + * The actual driving is done by orinoco.c, this is just resource + * allocation stuff. + * + * This driver is modeled after the orinoco_plx driver. The main + * difference is that the TMD chip has only IO port ranges and no + * memory space, i.e. no access to the CIS. Compared to the PLX chip, + * the io range functionalities are exchanged. + * + * Pheecom sells cards with the TMD chip as "ASIC version" + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "hermes.h" +#include "orinoco.h" + +static char dev_info[] = "orinoco_tmd"; + +#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA | COR_FUNC_ENA) /* Enable PC card with level triggered irqs and irq requests */ + + +static int orinoco_tmd_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int err = 0; + u32 reg, addr; + struct orinoco_private *priv = NULL; + unsigned long pccard_ioaddr = 0; + unsigned long pccard_iolen = 0; + struct net_device *dev = NULL; + int netdev_registered = 0; + + err = pci_enable_device(pdev); + if (err) + return -EIO; + + printk(KERN_DEBUG "TMD setup\n"); + pccard_ioaddr = pci_resource_start(pdev, 2); + pccard_iolen = pci_resource_len(pdev, 2); + if (! request_region(pccard_ioaddr, pccard_iolen, dev_info)) { + printk(KERN_ERR "orinoco_tmd: I/O resource at 0x%lx len 0x%lx busy\n", + pccard_ioaddr, pccard_iolen); + pccard_ioaddr = 0; + err = -EBUSY; + goto fail; + } + addr = pci_resource_start(pdev, 1); + outb(COR_VALUE, addr); + mdelay(1); + reg = inb(addr); + if (reg != COR_VALUE) { + printk(KERN_ERR "orinoco_tmd: Error setting TMD COR values %x should be %x\n", reg, COR_VALUE); + err = -EIO; + goto fail; + } + + dev = alloc_orinocodev(0, NULL); + if (! dev) { + err = -ENOMEM; + goto fail; + } + + priv = dev->priv; + dev->base_addr = pccard_ioaddr; + SET_MODULE_OWNER(dev); + + printk(KERN_DEBUG + "Detected Orinoco/Prism2 TMD device at %s irq:%d, io addr:0x%lx\n", + pdev->slot_name, pdev->irq, pccard_ioaddr); + + hermes_struct_init(&(priv->hw), dev->base_addr, + HERMES_IO, HERMES_16BIT_REGSPACING); + pci_set_drvdata(pdev, dev); + + err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, + dev); + if (err) { + printk(KERN_ERR "orinoco_tmd: Error allocating IRQ %d.\n", + pdev->irq); + err = -EBUSY; + goto fail; + } + dev->irq = pdev->irq; + + err = register_netdev(dev); + if (err) + goto fail; + netdev_registered = 1; + + return 0; /* succeeded */ + + fail: + printk(KERN_DEBUG "orinoco_tmd: init_one(), FAIL!\n"); + + if (priv) { + if (dev->irq) + free_irq(dev->irq, dev); + + kfree(priv); + } + + if (pccard_ioaddr) + release_region(pccard_ioaddr, pccard_iolen); + + pci_disable_device(pdev); + + return err; +} + +static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + if (! dev) + BUG(); + + unregister_netdev(dev); + + if (dev->irq) + free_irq(dev->irq, dev); + + pci_set_drvdata(pdev, NULL); + + kfree(dev); + + release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); + + pci_disable_device(pdev); +} + + +static struct pci_device_id orinoco_tmd_pci_id_table[] __devinitdata = { + {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,}, /* NDC and OEMs, e.g. pheecom */ + {0,}, +}; + +MODULE_DEVICE_TABLE(pci, orinoco_tmd_pci_id_table); + +static struct pci_driver orinoco_tmd_driver = { + .name = "orinoco_tmd", + .id_table = orinoco_tmd_pci_id_table, + .probe = orinoco_tmd_init_one, + .remove = __devexit_p(orinoco_tmd_remove_one), + .suspend = 0, + .resume = 0, +}; + +static char version[] __initdata = "orinoco_tmd.c 0.01 (Joerg Dorchain )"; +MODULE_AUTHOR("Joerg Dorchain "); +MODULE_DESCRIPTION("Driver for wireless LAN cards using the TMD7160 PCI bridge"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("Dual MPL/GPL"); +#endif + +static int __init orinoco_tmd_init(void) +{ + printk(KERN_DEBUG "%s\n", version); + return pci_module_init(&orinoco_tmd_driver); +} + +extern void __exit orinoco_tmd_exit(void) +{ + pci_unregister_driver(&orinoco_tmd_driver); + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(HZ); +} + +module_init(orinoco_tmd_init); +module_exit(orinoco_tmd_exit); + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -urN linux-2.4.21/drivers/pci/Makefile linux-2.4.22/drivers/pci/Makefile --- linux-2.4.21/drivers/pci/Makefile 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/pci/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -29,7 +29,6 @@ obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC32) += setup-irq.o obj-$(CONFIG_SGI_IP27) += setup-irq.o -obj-$(CONFIG_SGI_IP32) += setup-irq.o ifndef CONFIG_X86 obj-y += syscall.o diff -urN linux-2.4.21/drivers/pci/pci.ids linux-2.4.22/drivers/pci/pci.ids --- linux-2.4.21/drivers/pci/pci.ids 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/pci/pci.ids 2003-08-25 04:44:42.000000000 -0700 @@ -7,7 +7,8 @@ # so if you have anything to contribute, please visit the home page or # send a diff -u against the most recent pci.ids to pci-ids@ucw.cz. # -# $Id: pci.ids,v 1.46 2002/08/14 17:38:51 mares Exp $ +# Daily snapshot on Thu 2003-05-29 10:00:04 +# Modded on Fri 2003-05-30 03:13:05 # # Vendors, devices and subsystems. Please keep sorted. @@ -21,6 +22,8 @@ 001a Ascend Communications, Inc. 0033 Paradyne corp. 003d Lockheed Martin-Marietta Corp +# Real TJN ID is e159, but they got it wrong several times --mj +0059 Tiger Jet Network Inc. (Wrong ID) 0070 Hauppauge computer works Inc. 0100 Ncipher Corp Ltd 0675 Dynalink @@ -98,7 +101,8 @@ f130 NetFlex-3/P ThunderLAN 1.0 f150 NetFlex-3/P ThunderLAN 2.3 0e55 HaSoTec GmbH -1000 LSI Logic / Symbios Logic (formerly NCR) +# Formerly NCR +1000 LSI Logic / Symbios Logic 0001 53c810 1000 1000 8100S 0002 53c820 @@ -123,7 +127,7 @@ 0020 53c1010 Ultra3 SCSI Adapter 1de1 1020 DC-390U3W 0021 53c1010 66MHz Ultra3 SCSI Adapter - 0030 53c1030 + 0030 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI 1028 1010 LSI U320 SCSI Controller 0040 53c1035 008f 53c875J @@ -158,9 +162,20 @@ 0017 PROTO-3 PCI Prototyping board 9100 INI-9100/9100W SCSI Host 1002 ATI Technologies Inc + 4136 Radeon IGP 320 M +# New support forthcoming in XFree86 4.3.0 + 4144 Radeon R300 AD [Radeon 9500 Pro] +# New support forthcoming in XFree86 4.3.0 + 4145 Radeon R300 AE [Radeon 9500 Pro] +# New support forthcoming in XFree86 4.3.0 + 4146 Radeon R300 AF [Radeon 9500 Pro] +# Update: Oops, AF was a typo above for 4147, should be AG + 4147 Radeon R300 AG [FireGL Z1/X1] 4158 68800AX [Mach32] - 4242 Radeon 8500 DV + 4242 Radeon R200 BB [Radeon All in Wonder 8500DV] 1002 02aa Radeon 8500 AIW DV Edition + 4336 Radeon Mobility U1 + 4337 Radeon IGP 340M 4354 215CT [Mach64 CT] 4358 210888CX [Mach64 CX] 4554 210888ET [Mach64 ET] @@ -210,6 +225,8 @@ 4752 Rage XL 1002 0008 Rage XL 1002 4752 Rage XL + 1002 8008 Rage XL + 1028 00d1 PowerEdge 2550 4753 Rage XC 1002 4753 Rage XC 4754 3D Rage I/II 215GT [Mach64 GT] @@ -227,6 +244,20 @@ 475a 3D Rage IIC AGP 1002 0087 Rage 3D IIC 1002 475a Rage IIC AGP + 4964 Radeon R250 Id [Radeon 9000] + 4965 Radeon R250 Ie [Radeon 9000] + 4966 Radeon R250 If [Radeon 9000] + 10f1 0002 R250 If [Tachyon G9000 PRO] + 148c 2039 R250 If [Radeon 9000 Pro "Evil Commando"] + 1509 9a00 R250 If [Radeon 9000 "AT009"] +# New subdevice - 3D Prophet 9000 PCI by Hercules. AGP version probably would have same ID, so not specified. + 1681 0040 R250 If [3D prophet 9000] + 174b 7176 R250 If [Sapphire Radeon 9000 Pro] + 174b 7192 R250 If [Radeon 9000 "Atlantis"] + 17af 2005 R250 If [Excalibur Radeon 9000 Pro] + 17af 2006 R250 If [Excalibur Radeon 9000] + 4967 Radeon R250 Ig [Radeon 9000] + 496e Radeon R250 [Radeon 9000] (Secondary) 4c42 3D Rage LT Pro AGP-133 0e11 b0e8 Rage 3D LT Pro 0e11 b10e 3D Rage LT Pro (Compaq Armada 1750) @@ -245,7 +276,9 @@ 1002 0044 Rage LT Pro 1002 4c49 Rage LT Pro 4c4d Rage Mobility P/M AGP 2x + 0e11 b111 Armada M700 1002 0084 Xpert 98 AGP 2X (Mobility) + 1014 0154 ThinkPad A20m 4c4e Rage Mobility L AGP 2x 4c50 3D Rage LT Pro 1002 4c50 Rage LT Pro @@ -253,16 +286,39 @@ 4c52 Rage Mobility P/M 4c53 Rage Mobility L 4c54 264LT [Mach64 LT] - 4c57 Radeon Mobility M7 LW + 4c57 Radeon Mobility M7 LW [Radeon Mobility 7500] + 1014 0517 ThinkPad T30 1028 00e6 Radeon Mobility M7 LW (Dell Inspiron 8100) - 4c58 Radeon Mobility M7 LX [Radeon Mobility FireGL 7800] + 144d c006 Radeon Mobility M7 LW in vpr Matrix 170B4 +# Update: More correct labelling for this FireGL chipset + 4c58 Radeon RV200 LX [Mobility FireGL 7800 M7] 4c59 Radeon Mobility M6 LY 1014 0235 ThinkPad A30p (2653-64G) 1014 0239 ThinkPad X22/X23/X24 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 4c5a Radeon Mobility M6 LZ +# Update: Add M9 to product name + 4c64 Radeon R250 Ld [Radeon Mobility 9000 M9] +# Update: Add M9 to product name + 4c65 Radeon R250 Le [Radeon Mobility 9000 M9] +# Update: Add M9 to product name + 4c66 Radeon R250 Lf [Radeon Mobility 9000 M9] +# Update: Add M9 to product name + 4c67 Radeon R250 Lg [Radeon Mobility 9000 M9] 4d46 Rage Mobility M4 AGP 4d4c Rage Mobility M4 AGP + 4e44 Radeon R300 ND [Radeon 9700 Pro] + 4e45 Radeon R300 NE [Radeon 9500 Pro] + 1002 0002 Radeon R300 NE [Radeon 9500 Pro] + 4e46 Radeon R300 NF [Radeon 9700] +# Update: This is FireGL X1, not Radeon 9700 + 4e47 Radeon R300 NG [FireGL X1] + 4e48 Radeon R350 [Radeon 9800] + 4e64 Radeon R300 [Radeon 9700 Pro] (Secondary) + 4e65 Radeon R300 [Radeon 9500 Pro] (Secondary) + 4e66 Radeon R300 [Radeon 9700] (Secondary) + 4e67 Radeon R300 [FireGL X1] (Secondary) + 4e68 Radeon R350 [Radeon 9800] (Secondary) 5041 Rage 128 PA/PRO 5042 Rage 128 PB/PRO AGP 2x 5043 Rage 128 PC/PRO AGP 4x @@ -289,7 +345,7 @@ 504d Rage 128 PM/PRO 504e Rage 128 PN/PRO AGP 2x 504f Rage 128 PO/PRO AGP 4x - 5050 Rage 128 PP/PRO TMDS + 5050 Rage 128 PP/PRO TMDS [Xpert 128] 1002 0008 Xpert 128 5051 Rage 128 PQ/PRO AGP 2x TMDS 5052 Rage 128 PR/PRO AGP 4x TMDS @@ -299,7 +355,8 @@ 5056 Rage 128 PV/PRO TMDS 5057 Rage 128 PW/PRO AGP 2x TMDS 5058 Rage 128 PX/PRO AGP 4x TMDS - 5144 Radeon QD +# Update: This same chip is used in all 32Mb and 64Mb SDR/DDR orig Radeons, and is now known as 7200 + 5144 Radeon R100 QD [Radeon 7200] 1002 0008 Radeon 7000/Radeon VE 1002 0009 Radeon 7000/Radeon 1002 000a Radeon 7000/Radeon @@ -313,34 +370,59 @@ 1002 028a Radeon 7000/Radeon 1002 02aa Radeon AIW 1002 053a Radeon 7000/Radeon - 5145 Radeon QE - 5146 Radeon QF - 5147 Radeon QG + 5145 Radeon R100 QE + 5146 Radeon R100 QF + 5147 Radeon R100 QG 5148 Radeon R200 QH [Radeon 8500] - 1002 0152 FireGL 8800 - 1002 0172 FireGL 8700 + 1002 010a FireGL 8800 64Mb + 1002 0152 FireGL 8800 128Mb + 1002 0162 FireGL 8700 32Mb + 1002 0172 FireGL 8700 64Mb 5149 Radeon R200 QI 514a Radeon R200 QJ 514b Radeon R200 QK 514c Radeon R200 QL [Radeon 8500 LE] 1002 003a Radeon R200 QL [Radeon 8500 LE] 1002 013a Radeon 8500 - 5157 Radeon 7500 QW + 148c 2026 R200 QL [Radeon 8500 Evil Master II Multi Display Edition] + 174b 7149 Radeon R200 QL [Sapphire Radeon 8500 LE] +# New: Radeon 9100 is basically a Radeon 8500LE branded as 9100 by Sapphire + 514d Radeon R200 QM [Radeon 9100] +# New: Radeon 8500LE chip + 514e Radeon R200 QN [Radeon 8500LE] +# New: Radeon 8500LE chip + 514f Radeon R200 QO [Radeon 8500LE] + 5157 Radeon RV200 QW [Radeon 7500] 1002 013a Radeon 7500 + 1458 4000 RV200 QW [RADEON 7500 PRO MAYA AR] + 148c 2024 RV200 QW [Radeon 7500LE Dual Display] + 148c 2025 RV200 QW [Radeon 7500 Evil Master Multi Display Edition] + 148c 2036 RV200 QW [Radeon 7500 PCI Dual Display] + 174b 7147 RV200 QW [Sapphire Radeon 7500LE] 174b 7161 Radeon RV200 QW [Radeon 7500 LE] - 5158 Radeon 7500 QX - 5159 Radeon VE QY + 17af 0202 RV200 QW [Excalibur Radeon 7500LE] + 5158 Radeon RV200 QX [Radeon 7500] +# Update: More correct name + 5159 Radeon RV100 QY [Radeon 7000/VE] 1002 000a Radeon 7000/Radeon VE + 1002 000b Radeon 7000 1002 0038 Radeon 7000/Radeon VE 1002 003a Radeon 7000/Radeon VE 1002 00ba Radeon 7000/Radeon VE 1002 013a Radeon 7000/Radeon VE - 174b 7112 Radeon 7000 64M TVO - 515a Radeon VE QZ + 1458 4002 RV100 QY [RADEON 7000 PRO MAYA AV Series] + 148c 2003 RV100 QY [Radeon 7000 Multi-Display Edition] + 148c 2023 RV100 QY [Radeon 7000 Evil Master Multi-Display] + 174b 7112 RV100 QY [Sapphire Radeon VE 7000] + 1787 0202 RV100 QY [Excalibur Radeon 7000] +# Update: More correct name + 515a Radeon RV100 QZ [Radeon 7000/VE] 5168 Radeon R200 Qh 5169 Radeon R200 Qi 516a Radeon R200 Qj 516b Radeon R200 Qk +# new: This one is not in ATI documentation, but is in XFree86 source code + 516c Radeon R200 Ql 5245 Rage 128 RE/SG 1002 0008 Xpert 128 1002 0028 Rage 128 AIW @@ -360,6 +442,7 @@ 1002 0088 Xpert 99 5345 Rage 128 SE/4x 5346 Rage 128 SF/4x AGP 2x + 1002 0048 RAGE 128 16MB VGA TVOUT AMC PAL 5347 Rage 128 SG/4x AGP 4x 5348 Rage 128 SH 534b Rage 128 SK/4x @@ -390,6 +473,9 @@ 1002 5654 Mach64VT Reference 5655 264VT3 [Mach64 VT3] 5656 264VT4 [Mach64 VT4] + 700f PCI Bridge [IGP 320M] + 7010 PCI Bridge [IGP 340M] + cab2 RS200/RS200M AGP Bridge [IGP 340M] 1003 ULSI Systems 0201 US201 1004 VLSI Technology Inc @@ -419,7 +505,10 @@ 1004 0306 QSound ThunderBird PCI Audio Support Registers 122d 1208 DSP368 Audio Support Registers 1483 5022 XWave Thunder 3D Audio Support Registers + 0307 Thunderbird + 0308 Thunderbird 0702 VAS96011 [Golden Gate II] + 0703 Tollgate 1005 Avance Logic Inc. [ALI] 2064 ALG2032/2064 2128 ALG2364A @@ -492,13 +581,14 @@ 0014 DECchip 21041 [Tulip Pass 3] 1186 0100 DE-530+ 0016 DGLPB [OPPO] + 0017 PV-PCI Graphics Controller (ZLXp-L) 0019 DECchip 21142/43 1011 500a DE500A Fast Ethernet 1011 500b DE500B Fast Ethernet 1014 0001 10/100 EtherJet Cardbus 1025 0315 ALN315 Fast Ethernet - 1033 800c PC-9821-CS01 - 1033 800d PC-9821NR-B06 + 1033 800c PC-9821-CS01 100BASE-TX Interface Card + 1033 800d PC-9821NR-B06 100BASE-TX Interface Card 108d 0016 Rapidfire 2327 10/100 Ethernet 108d 0017 GoCard 2250 Ethernet 10/100 Cardbus 10b8 2005 SMC8032DT Extreme Ethernet 10/100 @@ -522,6 +612,7 @@ 1374 0002 Cardbus Ethernet Card 10/100 1374 0007 Cardbus Ethernet Card 10/100 1374 0008 Cardbus Ethernet Card 10/100 + 1385 2100 FA510 1395 0001 10/100 Ethernet CardBus PC Card 13d1 ab01 EtherFast 10/100 Cardbus (PCMPC200) 8086 0001 EtherExpress PRO/100 Mobile CardBus 32 @@ -581,8 +672,8 @@ 1014 1010 CS4610 SoundFusion Audio Accelerator 6003 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator] 1013 4280 Crystal SoundFusion PCI Audio Accelerator - 1681 0050 Hercules Game Theater XP - 1681 a011 Hercules Fortissimo III 7.1 + 1681 0050 Game Theater XP + 1681 a011 Fortissimo III 7.1 6004 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator] 6005 Crystal CS4281 PCI Audio 1013 4281 Crystal CS4281 PCI Audio @@ -608,7 +699,9 @@ 0020 MCA 0022 IBM27-82351 002d Python - 002e ServeRAID-3x + 002e ServeRAID Controller + 1014 002e ServeRAID-3x + 1014 022e ServeRAID-4H 0036 Miami 003a CPU to PCI Bridge 003e 16/4 Token ring UTP/STP controller @@ -644,18 +737,25 @@ 00b7 256-bit Graphics Rasterizer [Fire GL1] 1902 00b8 Fire GL1 00be ATM 622MBPS Controller (1410be00) + 00dc Advanced Systems Management Adapter (ASMA) 00fc CPC710 Dual Bridge and Memory Controller (PCI-64) 0105 CPC710 Dual Bridge and Memory Controller (PCI-32) + 010f Remote Supervisor Adapter (RSA) 0142 Yotta Video Compositor Input 1014 0143 Yotta Input Controller (ytin) 0144 Yotta Video Compositor Output 1014 0145 Yotta Output Controller (ytout) 0156 405GP PLB to PCI Bridge 01a7 PCI-X to PCI-X Bridge - 01bd Netfinity ServeRAID controller - 01be ServeRAID-4M - 01bf ServeRAID-4L - 022e ServeRAID-4H + 01bd ServeRAID Controller + 1014 01be ServeRAID-4M + 1014 01bf ServeRAID-4L + 1014 0208 ServeRAID-4Mx + 1014 020e ServeRAID-4Lx + 1014 022e ServeRAID-4H + 1014 0258 ServeRAID-5i + 1014 0259 ServeRAID-5i + 0302 XA-32 chipset [Summit] ffff MPIC-2 interrupt controller 1015 LSI Logic Corp of Canada 1016 ICL Personal Systems @@ -700,7 +800,11 @@ 1020 Hitachi Computer Products 1021 OKI Electric Industry Co. Ltd. 1022 Advanced Micro Devices [AMD] - 2000 79c970 [PCnet LANCE] + 1100 K8 NorthBridge + 1101 K8 NorthBridge + 1102 K8 NorthBridge + 1103 K8 NorthBridge + 2000 79c970 [PCnet32 LANCE] 1014 2000 NetFinity 10/100 Fast Ethernet 103c 104c Ethernet with LAN remote power Adapter 103c 1064 Ethernet with LAN remote power Adapter @@ -743,19 +847,23 @@ 7443 AMD-768 [Opus] ACPI 1043 8044 A7M-D Mainboard 7445 AMD-768 [Opus] Audio + 7446 AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible) 7448 AMD-768 [Opus] PCI 7449 AMD-768 [Opus] USB + 7450 AMD-8131 PCI-X Bridge + 7451 AMD-8131 PCI-X APIC 7454 AMD-8151 System Controller 7455 AMD-8151 AGP Bridge 7460 AMD-8111 PCI 7461 AMD-8111 USB 7462 AMD-8111 Ethernet + 7464 AMD-8111 USB 7468 AMD-8111 LPC 7469 AMD-8111 IDE 746a AMD-8111 SMBus 2.0 746b AMD-8111 ACPI 746d AMD-8111 AC97 Audio - 756b AMD-8111 ACPI + 746e AMD-8111 MC97 Modem 1023 Trident Microsystems 0194 82C194 2000 4DWave DX @@ -768,6 +876,8 @@ 8520 CyberBlade i1 0e11 b16e CyberBlade i1 AGP 1023 8520 CyberBlade i1 AGP + 8620 CyberBlade/i1 + 1014 0502 ThinkPad T30 8820 CyberBlade XPAi1 9320 TGUI 9320 9350 GUI Accelerator @@ -876,13 +986,15 @@ 1028 00d0 PowerEdge Expandable RAID Controller 3/Si 0005 PowerEdge Expandable RAID Controller 3/Di 0006 PowerEdge Expandable RAID Controller 3/Di - 0007 Remote Assistant Card 3 - 0008 PowerEdge Expandable RAID Controller 3/Di + 0007 Remote Access Controller:DRAC III + 0008 Remote Access Controller + 0009 BMC/SMIC device not present 000a PowerEdge Expandable RAID Controller 3 - 1027 0121 PowerEdge Expandable RAID Controller 3/Di 1028 0106 PowerEdge Expandable RAID Controller 3/Di 1028 011b PowerEdge Expandable RAID Controller 3/Di - 000c Embedded Systems Management Device 4 + 1028 0121 PowerEdge Expandable RAID Controller 3/Di + 000c Remote Access Controller:ERA or ERA/O + 000d BMC/SMIC device 000e PowerEdge Expandable RAID Controller 000f PowerEdge Expandable RAID Controller 4/Di 1029 Siemens Nixdorf IS @@ -892,9 +1004,11 @@ 102b Matrox Graphics, Inc. # DJ: I've a suspicion that 0010 is a duplicate of 0d10. 0010 MGA-I [Impression?] + 0100 MGA 1064SG [Mystique] 0518 MGA-II [Athena] 0519 MGA 2064W [Millennium] 051a MGA 1064SG [Mystique] + 102b 0100 MGA-1064SG Mystique 102b 1100 MGA-1084SG Mystique 102b 1200 MGA-1084SG Mystique 1100 102b MGA-1084SG Mystique @@ -989,10 +1103,10 @@ 102b 5f52 4Sight II 102b 9010 Millennium G400 Dual Head 1458 0400 GA-G400 - 1705 0001 Digital First Millennium G450 32MB SGRAM - 1705 0002 Digital First Millennium G450 16MB SGRAM - 1705 0003 Digital First Millennium G450 32MB - 1705 0004 Digital First Millennium G450 16MB + 1705 0001 Millennium G450 32MB SGRAM + 1705 0002 Millennium G450 16MB SGRAM + 1705 0003 Millennium G450 32MB + 1705 0004 Millennium G450 16MB b16f 0e11 MGA-G400 AGP 0527 MGA Parhelia AGP 102b 0840 Parhelia 128Mb @@ -1037,6 +1151,7 @@ 0009 r4x00 0020 ATM Meteor 155 102f 00f8 ATM Meteor 155 + 0180 TX4927 1030 TMC Research 1031 Miro Computer Products AG 5601 DC20 ASIC @@ -1050,17 +1165,22 @@ 0003 ATM Controller 0004 R4000 PCI Bridge 0005 PCI to 486-like bus Bridge - 0006 GUI Accelerator + 0006 PC-9800 Graphic Accelerator 0007 PCI to UX-Bus Bridge - 0008 GUI Accelerator - 0009 GUI Accelerator for W98 + 0008 PC-9800 Graphic Accelerator + 0009 PCI to PC9800 Core-Graph Bridge + 0016 PCI to VL Bridge 001a [Nile II] 0021 Vrc4373 [Nile I] 0029 PowerVR PCX1 002a PowerVR 3D + 002c Star Alpha 2 + 002d PCI to C-bus Bridge 0035 USB 1179 0001 USB 12ee 7000 Root Hub + 1799 0001 Root Hub + 003b PCI to C-bus Bridge 003e NAPCCARD Cardbus Controller 0046 PowerVR PCX2 [midas] 005a Vrc5074 [Nile 4] @@ -1077,11 +1197,13 @@ 0074 56k Voice Modem 1033 8014 RCV56ACF 56k Voice Modem 009b Vrc5476 + 00a5 VRC4173 00a6 VRC5477 AC97 00cd IEEE 1394 [OrangeLink] Host Controller 12ee 8011 Root hub 00e0 USB 2.0 12ee 7001 Root hub + 1799 0002 Root Hub 1034 Framatome Connectors USA Inc. 1035 Comp. & Comm. Research Lab 1036 Future Domain Corp. @@ -1089,7 +1211,8 @@ 1037 Hitachi Micro Systems 1038 AMP, Inc 1039 Silicon Integrated Systems [SiS] - 0001 5591/5592 AGP +# This is what all my tests report. I don't know if this is equivalent to "5591/5592 AGP". + 0001 SiS 530 Virtual PCI-to-PCI bridge (AGP) 0002 SG86C202 0006 85C501/2/3 0008 85C503/5513 @@ -1099,8 +1222,12 @@ 1039 0000 SiS5597 SVGA (Shared RAM) 0204 82C204 0205 SG86C205 - 0300 300/200 + 0300 SiS300/305 PCI/AGP VGA Display Adapter 107d 2720 Leadtek WinFast VR300 + 0310 SiS315H PCI/AGP VGA Display Adapter + 0315 SiS315 PCI/AGP VGA Display Adapter + 0325 SiS315PRO PCI/AGP VGA Display Adapter + 0330 SiS330 [Xabre] PCI/AGP VGA Display Adapter 0406 85C501/2 0496 85C496 0530 530 Host @@ -1111,24 +1238,30 @@ 0630 630 Host 0633 633 Host 0635 635 Host - 0645 645 Host - 0646 645DX Host + 0645 SiS645 Host & Memory & AGP Controller + 0646 SiS645DX Host & Memory & AGP Controller + 0648 SiS 645xx 0650 650 Host + 0651 SiS651 Host 0730 730 Host 0733 733 Host 0735 735 Host 0740 740 Host 0745 745 Host 0746 746 Host + 0755 SiS 755 Host Bridge 0900 SiS900 10/100 Ethernet 1039 0900 SiS900 10/100 Ethernet Adapter 0961 SiS961 [MuTIOL Media IO] + 0962 SiS962 [MuTIOL Media IO] 3602 83C602 5107 5107 5300 SiS540 PCI Display Adapter + 5315 SiS550 AGP/VGA VGA Display Adapter 5401 486 PCI Chipset 5511 5511/5512 5513 5513 [IDE] + 1019 0970 P6STP-FL motherboard 1039 5513 SiS5513 EIDE Controller (A,B step) 5517 5517 5571 5571 @@ -1142,8 +1275,10 @@ 6205 VGA Controller 6236 6236 3D-AGP 6300 SiS630 GUI Accelerator+3D - 6306 6306 3D-AGP + 1019 0970 P6STP-FL motherboard + 6306 SiS530 3D PCI/AGP 1039 6306 SiS530,620 GUI Accelerator+3D + 6325 SiS65x/M650/740 PCI/AGP VGA Display Adapter 6326 86C326 5598/6326 1039 6326 SiS6326 GUI Accelerator 1092 0a50 SpeedStar A50 @@ -1151,11 +1286,14 @@ 1092 4910 SpeedStar A70 1092 4920 SpeedStar A70 1569 6326 SiS6326 GUI Accelerator - 7001 7001 + 7001 USB 1.0 Controller + 1039 7000 Onboard USB Controller + 7002 USB 2.0 Controller + 1509 7002 Onboard USB Controller 7007 FireWire Controller - 7012 SiS7012 PCI Audio Accelerator - 7013 56k Winmodem (Smart Link HAMR5600 compatible) - 7016 SiS7016 10/100 Ethernet Adapter + 7012 Sound Controller + 7013 Intel 537 [56k Winmodem] + 7016 10/100 Ethernet Adapter 1039 7016 SiS7016 10/100 Ethernet Adapter 7018 SiS PCI Audio Accelerator 1014 01b6 SiS PCI Audio Accelerator @@ -1212,6 +1350,7 @@ 103c 1226 Keystone SP2 103c 1227 Powerbar SP2 103c 1282 Everest SP2 + 1054 PCI Local Bus Adapter 1064 79C970 PCnet Ethernet Controller 108b Visualize FXe 10c1 NetServer Smart IRQ Router @@ -1223,7 +1362,8 @@ 121c NetServer PCI COM Port Decoder 1229 zx1 System Bus Adapter 122a zx1 I/O Controller - 122e zx1 Local Bus Adapter + 122e PCI-X/AGP Local Bus Adapter + 127c sx1000 I/O Controller 1290 Auxiliary Diva Serial Port 2910 E2910A PCIBus Exerciser 2925 E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer @@ -1232,13 +1372,14 @@ 1040 Accelgraphics Inc. 1041 Computrend 1042 Micron - 1000 FDC 37C665 - 1001 37C922 + 1000 PC Tech RZ1000 + 1001 PC Tech RZ1001 3000 Samurai_0 3010 Samurai_1 3020 Samurai_IDE 1043 Asustek Computer, Inc. 0675 ISDNLink P-IN100-ST-D + 4021 v7100 Combo Deluxe [GeForce2 MX + TV tuner] 4057 V8200 GeForce 3 1044 Distributed Processing Technology 1012 Domino RAID Engine @@ -1314,6 +1455,9 @@ 104a SGS Thomson Microelectronics 0008 STG 2000X 0009 STG 1764X + 0010 STG4000 [3D Prophet Kyro Series] +# From + 0210 STPC Atlas ISA Bridge 0981 DEC-Tulip compatible 10/100 Ethernet 1746 STG 1764X 2774 DEC-Tulip compatible 10/100 Ethernet @@ -1326,6 +1470,7 @@ 0500 100 MBit LAN Controller 0508 TMS380C2X Compressor Interface 1000 Eagle i/f AS + 104c PCI1510 PC card Cardbus Controller 3d04 TVP4010 [Permedia] 3d07 TVP4020 [Permedia 2] 1011 4d10 Comet @@ -1369,9 +1514,12 @@ 8026 TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) 8027 PCI4451 IEEE-1394 Controller 1028 00e6 PCI4451 IEEE-1394 Controller (Dell Inspiron 8100) + 8029 PCI4510 IEEE-1394 Controller + 8400 ACX 100 22Mbps Wireless Interface a001 TDC1570 a100 TDC1561 a102 TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f + a106 TMS320C6205 ac10 PCI1050 ac11 PCI1053 ac12 PCI1130 @@ -1383,6 +1531,7 @@ ac19 PCI1221 ac1a PCI1210 ac1b PCI1450 + 0e11 b113 Armada M700 ac1c PCI1225 ac1d PCI1251A ac1e PCI1211 @@ -1397,6 +1546,7 @@ ac41 PCI4410 PC card Cardbus Controller ac42 PCI4451 PC card Cardbus Controller 1028 00e6 PCI4451 PC card CardBus Controller (Dell Inspiron 8100) + ac44 PCI4510 PC card Cardbus Controller ac50 PCI1410 PC card Cardbus Controller ac51 PCI1420 1014 023b ThinkPad T23 (2647-4MG) @@ -1405,6 +1555,8 @@ ac52 PCI1451 PC card Cardbus Controller ac53 PCI1421 PC card Cardbus Controller ac55 PCI1250 PC card Cardbus Controller + 1014 0512 ThinkPad T30 + ac56 PCI1510 PC card Cardbus Controller ac60 PCI2040 PCI to DSP Bridge Controller fe00 FireWire Host Controller fe03 12C01A FireWire Host Controller @@ -1430,6 +1582,7 @@ 1050 0840 W89C840 Ethernet Adapter 0940 W89C940 5a5a W89C940F + 6692 W6692 9970 W9970CF 1051 Anigma, Inc. 1052 ?Young Micro Systems @@ -1446,6 +1599,8 @@ 0001 MPC105 [Eagle] 0002 MPC106 [Grackle] 0003 MPC8240 [Kahlua] + 0004 MPC107 + 0006 MPC8245 [Unity] 0100 MC145575 [HFC-PCI] 0431 KTI829c 100VG 1801 Audio I/O Controller (MIDI) @@ -1483,6 +1638,8 @@ 0d38 20263 105a 4d39 Fasttrak66 1275 20275 + 3376 PDC20376 + 1043 809e A7V8X motherboard 4d30 20267 105a 4d33 Ultra100 105a 4d39 Fasttrak100 @@ -1495,12 +1652,14 @@ 4d68 20268 105a 4d68 Ultra100TX2 4d69 20269 + 105a 4d68 Ultra133TX2 5275 PDC20276 IDE 105a 0275 SuperTrak SX6000 IDE 5300 DC5300 6268 20268R 6269 PDC20271 - 105a 6269 Fasttrack tx2 + 105a 6269 FastTrak TX2/TX2000 + 6621 PDC20621 [SX4000] 4 Channel IDE RAID Controller 7275 PDC20277 105b Foxconn International, Inc. 105c Wipro Infotech Limited @@ -1538,6 +1697,7 @@ 13cc 0009 Barco Metheus 5 Megapixel, Dual Head 13cc 000a Barco Metheus 5 Megapixel, Dual Head 5348 Revolution 4 + 105d 0037 Revolution IV-FP AGP (For SGI 1600SW) 105e Vtech Computers Ltd 105f Infotronic America Inc 1060 United Microelectronics [UMC] @@ -1615,6 +1775,11 @@ 002e UniNorth 1.5 PCI 002f UniNorth 1.5 Internal PCI 0030 UniNorth/Pangea FireWire + 0031 UniNorth 2 FireWire + 0032 UniNorth 2 GMAC (Sun GEM) + 0033 UniNorth 2 ATA/100 + 0034 UniNorth 2 AGP + 1645 Tigon3 Gigabit Ethernet NIC (BCM5701) 106c Hyundai Electronics America 8801 Dual Pentium ISA/PCI Motherboard 8802 PowerPC ISA/PCI Motherboard @@ -1671,6 +1836,7 @@ 2100 QLA2100 64-bit Fibre Channel Adapter 1077 0001 QLA2100 64-bit Fibre Channel Adapter 2200 QLA2200 + 1077 0002 QLA2200 2300 QLA2300 64-bit FC-AL Adapter 2312 QLA2312 Fibre Channel Adapter 1078 Cyrix Corporation @@ -1726,7 +1892,8 @@ 1087 Cache Computer 1088 Microcomputer Systems (M) Son 1089 Data General Corporation -108a SBS Technologies (formerly Bit3 Computer Corp.) +# Formerly Bit3 Computer Corp. +108a SBS Technologies 0001 VME Bridge Model 617 0010 VME Bridge Model 618 0040 dataBLIZZARD @@ -1818,8 +1985,10 @@ b081 IMAQ-PXI-1422 b091 IMAQ-PXI-1411 c801 PCI-GPIB + c831 PCI-GPIB bridge 1094 First International Computers [FIC] 1095 CMD Technology Inc + 0240 Adaptec AAR-1210SA SATA HostRAID Controller 0640 PCI0640 0643 PCI0643 0646 PCI0646 @@ -1834,6 +2003,7 @@ 1095 0670 USB0670 0673 USB0673 0680 PCI0680 + 3112 Silicon Image SiI 3112 SATARaid Controller 1096 Alacron 1097 Appian Technology 1098 Quantum Designs (H.K.) Ltd @@ -1853,8 +2023,10 @@ 036c Bt879(??) Video Capture 13e9 0070 Win/TV (Video Section) 036e Bt878 Video Capture - 0070 13eb WinTV/GO + 0070 13eb WinTV Series 0070 ff01 Viewcast Osprey 200 + 107d 6606 WinFast TV 2000 + 11bd 0012 PCTV pro (TV + FM stereo receiver) 11bd 001c PCTV Sat (DBC receiver) 127a 0001 Bt878 Mediastream Controller NTSC 127a 0002 Bt878 Mediastream Controller PAL BG @@ -1869,6 +2041,7 @@ 1851 1850 FlyVideo'98 - Video 1851 1851 FlyVideo II 1852 1852 FlyVideo'98 - Video (with FM Tuner) + bd11 1200 PCTV pro (TV + FM stereo receiver) 036f Bt879 Video Capture 127a 0044 Bt879 Video Capture NTSC 127a 0122 Bt879 Video Capture PAL I @@ -1904,10 +2077,11 @@ 1851 1851 FlyVideo'98 EZ - video 1852 1852 FlyVideo'98 (with FM Tuner) 0878 Bt878 Audio Capture - 0070 13eb WinTV/GO + 0070 13eb WinTV Series 0070 ff01 Viewcast Osprey 200 1002 0001 TV-Wonder 1002 0003 TV-Wonder/VE + 11bd 0012 PCTV pro (TV + FM stereo receiver, audio section) 11bd 001c PCTV Sat (DBC receiver) 127a 0001 Bt878 Video Capture (Audio Section) 127a 0002 Bt878 Video Capture (Audio Section) @@ -1920,6 +2094,7 @@ 14f1 0002 Bt878 Video Capture (Audio Section) 14f1 0003 Bt878 Video Capture (Audio Section) 14f1 0048 Bt878 Video Capture (Audio Section) + bd11 1200 PCTV pro (TV + FM stereo receiver, audio section) 0879 Bt879 Audio Capture 127a 0044 Bt879 Video Capture (Audio Section) 127a 0122 Bt879 Video Capture (Audio Section) @@ -1961,7 +2136,9 @@ 10a2 Quantum Corporation 10a3 Everex Systems Inc 10a4 Globe Manufacturing Sales -10a5 Racal Interlan +10a5 Smart Link Ltd. + 3052 SmartPCI562 56K Modem + 5449 SmartPCI561 modem 10a6 Informtech Industrial Ltd. 10a7 Benchmarq Microelectronics 10a8 Sierra Semiconductor @@ -1976,6 +2153,7 @@ 0007 RPCEX 0008 DiVO VIP 0009 Alteon Gigabit Ethernet + 10a9 8002 Acenic Gigabit Ethernet 0010 AMP Video I/O 0011 GRIP 0012 SGH PSHAC GSN @@ -1987,6 +2165,7 @@ 1006 Dual JPEG 4 1007 Dual JPEG 5 1008 Cesium + 100a IOC4 I/O controller 2001 Fibre Channel 2002 ASDE 8001 O2 1394 @@ -2027,7 +2206,9 @@ 15ed 1003 MCCS 16-port Serial Hot Swap 9036 9036 9050 PCI <-> IOBus Bridge + 10b5 2036 SatPak GPS 10b5 2273 SH-ARC SoHard ARCnet card + 10b5 9050 MP9050 1522 0001 RockForce 4 Port V.90 Data/Fax/Voice Modem 1522 0002 RockForce 2 Port V.90 Data/Fax/Voice Modem 1522 0003 RockForce 6 Port V.90 Data/Fax/Voice Modem @@ -2038,6 +2219,7 @@ 15ed 1001 Macrolink MCCS 16-port Serial 15ed 1002 Macrolink MCCS 8-port Serial Hot Swap 15ed 1003 Macrolink MCCS 16-port Serial Hot Swap + 5654 5634 OpenLine4 Telephony Card d531 c002 PCIntelliCAN 2xSJA1000 CAN bus d84d 4006 EX-4006 1P d84d 4008 EX-4008 1P EPP/ECP @@ -2058,6 +2240,7 @@ d84d 4078 EX-4078 2S(16C552) RS-232+1P 9054 PCI <-> IOBus Bridge 10b5 2455 Wessex Techology PHIL-PCI + 12d9 0002 PCI Prosody Card rev 1.5 9060 9060 906d 9060SD 125c 0640 Aries 16000P @@ -2065,8 +2248,7 @@ 9080 9080 10b5 9080 9080 [real subsystem ID not set] 129d 0002 Aculab PCI Prosidy card - a001 GTEK Jetport II 2 port serial adaptor - c001 GTEK Cyclone 16/32 port serial adaptor + 12d9 0002 PCI Prosody Card 10b6 Madge Networks 0001 Smart 16/4 PCI Ringnode 0002 Smart 16/4 PCI Ringnode Mk2 @@ -2094,6 +2276,7 @@ 1001 Collage 155 ATM Server Adapter 10b7 3Com Corporation 0001 3c985 1000BaseSX (SX/TX) + 0910 3C910-A01 1006 MINI PCI type 3B Data Fax Modem 1007 Mini PCI 56k Winmodem 10b7 615c Mini PCI 56K Modem @@ -2172,19 +2355,28 @@ 1028 0095 Integrated 3C905C-TX Fast Etherlink for PC Management NIC 10b7 1000 3C905C-TX Fast Etherlink for PC Management NIC 10b7 7000 10/100 Mini PCI Ethernet Adapter + 9201 3C920B-EMB Integrated Fast Ethernet Controller + 9300 3CSOHO100B-TX [910-A01] 9800 3c980-TX [Fast Etherlink XL Server Adapter] 10b7 9800 3c980-TX Fast Etherlink XL Server Adapter 9805 3c980-TX 10/100baseTX NIC [Python-T] 10b7 1201 3c982-TXM 10/100baseTX Dual Port A [Hydra] 10b7 1202 3c982-TXM 10/100baseTX Dual Port B [Hydra] 10b7 9805 3c980 10/100baseTX NIC [Python-T] - 9900 3C990-TX Typhoon - 9902 3CR990-TX-95 56-bit Typhoon Client - 9903 3CR990-TX-97 168-bit Typhoon Client + 10f1 2462 Thunder K7 S2462 + 9900 3C990-TX [Typhoon] + 9902 3CR990-TX-95 [Typhoon 56-bit] + 9903 3CR990-TX-97 [Typhoon 168-bit] 9904 3C990B-TX-M/3C990BSVR [Typhoon2] + 10b7 1000 3CR990B-TX-M [Typhoon2] + 10b7 2000 3CR990BSVR [Typhoon2 Server] 9905 3CR990-FX-95/97/95 [Typhon Fiber] - 9908 3CR990SVR95 56-bit Typhoon Server - 9909 3CR990SVR97 Typhoon Server + 10b7 1101 3CR990-FX-95 [Typhoon Fiber 56-bit] + 10b7 1102 3CR990-FX-97 [Typhoon Fiber 168-bit] + 10b7 2101 3CR990-FX-95 Server [Typhoon Fiber 56-bit] + 10b7 2102 3CR990-FX-97 Server [Typhoon Fiber 168-bit] + 9908 3CR990SVR95 [Typhoon Server 56-bit] + 9909 3CR990SVR97 [Typhoon Server 168-bit] 990b 3C990SVR [Typhoon Server] 10b8 Standard Microsystems Corp [SMC] 0005 83C170QF @@ -2207,7 +2399,7 @@ 1001 FDC 37C922 a011 83C170QF b106 SMC34C90 -10b9 ALi Corporation. [ALi] +10b9 ALi Corporation 0111 C-Media CMI8738/C3DX Audio Device (OEM) 10b9 0111 C-Media CMI8738/C3DX Audio Device (OEM) 1435 M1435 @@ -2229,7 +2421,7 @@ 1541 M1541 10b9 1541 ALI M1541 Aladdin V/V+ AGP System Controller 1543 M1543 - 1563 M1563 South Bridge supporting HT Technology + 1563 M1563 HyperTransport South Bridge 1621 M1621 1631 ALI M1631 PCI North Bridge Aladdin Pro III 1632 M1632M Northbridge+Trident @@ -2238,9 +2430,9 @@ 1646 M1646 Northbridge+Trident 1647 M1647 Northbridge [MAGiK 1 / MobileMAGiK 1] 1651 M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM] - 1671 M1671 Super P4 Northbridge [AGP4X,PCI, and SDR/DDR] - 1681 M1681 P4 Northbridge [AGP8X,HT, and SDR/DDR] - 1687 M1687 K8 Northbridge [AGP8X and HT] + 1671 M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR] + 1681 M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR] + 1687 M1687 K8 Northbridge [AGP8X and HyperTransport] 3141 M3141 3143 M3143 3145 M3145 @@ -2261,14 +2453,20 @@ 5239 USB 2.0 Controller 5243 M1541 PCI to AGP Controller 5247 PCI to AGP Controller - 5249 HTT to PCI Bridge + 5249 M5249 HTT to PCI Bridge 5251 M5251 P1394 OHCI 1.0 Controller 5253 M5253 P1394 OHCI 1.1 Controller 5261 M5261 Ethernet Controller + 5450 Lucent Technologies Soft Modem AMR 5451 M5451 PCI AC-Link Controller Audio Device + 1014 0506 ThinkPad R30 5453 M5453 PCI AC-Link Controller Modem Device 5455 M5455 PCI AC-Link Controller Audio Device - 5457 M5457 AC-Link Modem Interface Controller + 5457 Intel 537 [M5457 AC-Link Modem] +# Same but more usefull for driver's lookup + 5459 SmartLink SmartPCI561 56K Modem +# SmartLink PCI SoftModem + 545a SmartLink SmartPCI563 56K Modem 5471 M5471 Memory Stick Controller 5473 M5473 SD-MMC Controller 7101 M7101 PMU @@ -2291,7 +2489,7 @@ 10c6 Rambus Inc. 10c7 Media Vision 10c8 Neomagic Corporation - 0001 NM2070 [MagicGraph NM2070] + 0001 NM2070 [MagicGraph 128] 0002 NM2090 [MagicGraph 128V] 0003 NM2093 [MagicGraph 128ZV] 0004 NM2160 [MagicGraph 128XD] @@ -2313,13 +2511,14 @@ 10f7 830b MagicGraph 128XD 10f7 830d MagicGraph 128XD 10f7 8312 MagicGraph 128XD - 0005 [MagicMedia 256AV] + 0005 NM2200 [MagicGraph 256AV] + 1014 00dd ThinkPad 570 0006 NM2360 [MagicMedia 256ZX] 0016 NM2380 [MagicMedia 256XL+] 10c8 0016 MagicMedia 256XL+ - 0025 [MagicMedia 256AV+] - 0083 [MagicGraph 128ZV Plus] - 8005 [MagicMedia 256AV Audio] + 0025 NM2230 [MagicGraph 256AV+] + 0083 NM2093 [MagicGraph 128ZV+] + 8005 NM2200 [MagicMedia 256AV Audio] 0e11 b0d1 MagicMedia 256AV Audio Device on Discovery 0e11 b126 MagicMedia 256AV Audio Device on Durango 1014 00dd MagicMedia 256AV Audio Device on BlackTip Thinkpad @@ -2332,7 +2531,7 @@ 110a 8005 MagicMedia 256AV Audio Device 14c0 0004 MagicMedia 256AV Audio Device 8006 NM2360 [MagicMedia 256ZX Audio] - 8016 NM2360 [MagicMedia 256ZX Audio] + 8016 NM2380 [MagicMedia 256XL+ Audio] 10c9 Dataexpert Corporation 10ca Fujitsu Microelectr., Inc. 10cb Omron Corporation @@ -2377,7 +2576,7 @@ 0008 NV1 [EDGE 3D] 0009 NV1 [EDGE 3D] 0010 NV2 [Mutara V08] - 0020 NV4 [Riva TnT] + 0020 NV4 [RIVA TNT] 1043 0200 V3400 TNT 1048 0c18 Erazor II SGRAM 1048 0c1b Erazor II @@ -2394,15 +2593,17 @@ 1092 4914 Viper V550 1092 8225 Viper V550 10b4 273d Velocity 4400 + 10b4 273e Velocity 4400 10b4 2740 Velocity 4400 10de 0020 Riva TNT 1102 1015 Graphics Blaster CT6710 1102 1016 Graphics Blaster RIVA TNT - 0028 NV5 [Riva TnT2] + 0028 NV5 [RIVA TNT2/TNT2 Pro] 1043 0200 AGP-V3800 SGRAM 1043 0201 AGP-V3800 SDRAM 1043 0205 PCI-V3800 1043 4000 AGP-V3800PRO + 1048 0c21 Synergy II 1092 4804 Viper V770 1092 4a00 Viper V770 1092 4a02 Viper V770 Ultra @@ -2414,7 +2615,7 @@ 1102 1020 3D Blaster RIVA TNT2 1102 1026 3D Blaster RIVA TNT2 Digital 14af 5810 Maxi Gamer Xentor - 0029 NV5 [Riva TnT2 Ultra] + 0029 NV5 [RIVA TNT2 Ultra] 1043 0200 AGP-V3800 Deluxe 1043 0201 AGP-V3800 Ultra SDRAM 1043 0205 PCI-V3800 Ultra @@ -2424,16 +2625,18 @@ 14af 5820 Maxi Gamer Xentor 32 002a NV5 [Riva TnT2] 002b NV5 [Riva TnT2] - 002c NV6 [Vanta] + 002c NV6 [Vanta/Vanta LT] 1043 0200 AGP-V3800 Combat SDRAM 1043 0201 AGP-V3800 Combat 1092 6820 Viper V730 1102 1031 CT6938 VANTA 8MB 1102 1034 CT6894 VANTA 16MB 14af 5008 Maxi Gamer Phoenix 2 - 002d RIVA TNT2 Model 64 + 002d NV5M64 [RIVA TNT2 Model 64/Model 64 Pro] 1043 0200 AGP-V3800M 1043 0201 AGP-V3800M + 1048 0c3a Erazor III LT + 10de 001e M64 AGP4x 1102 1023 CT6892 RIVA TNT2 Value 1102 1024 CT6932 RIVA TNT2 Value 32Mb 1102 102c CT6931 RIVA TNT2 Value [Jumper] @@ -2441,7 +2644,19 @@ 1554 1041 PixelView RIVA TNT2 M64 32MB 002e NV6 [Vanta] 002f NV6 [Vanta] - 00a0 NV5 [Riva TNT2] + 0060 nForce2 ISA Bridge + 1043 80ad A7N8X Mainboard + 0064 nForce2 SMBus (MCP) + 0065 nForce2 IDE + 0066 nForce2 Ethernet Controller + 0067 nForce2 USB Controller + 1043 0c11 A7N8X Mainboard + 0068 nForce2 USB Controller + 1043 0c11 A7N8X Mainboard + 006a nForce2 AC97 Audio Controler (MCP) + 006b nForce MultiMedia audio [Via VT82C686B] + 006e nForce2 FireWire (IEEE 1394) Controller + 00a0 NV5 [Aladdin TNT2] 14af 5810 Maxi Gamer Xentor 0100 NV10 [GeForce 256 SDR] 1043 0200 AGP-V6600 SGRAM @@ -2450,40 +2665,53 @@ 1043 4009 AGP-V6600 SDRAM 1102 102d CT6941 GeForce 256 14af 5022 3D Prophet SE - 0101 NV10 [GeForce 256 DDR] + 0101 NV10DDR [GeForce 256 DDR] 1043 0202 AGP-V6800 DDR 1043 400a AGP-V6800 DDR SGRAM 1043 400b AGP-V6800 DDR SDRAM 1102 102e CT6971 GeForce 256 DDR 14af 5021 3D Prophet DDR-DVI - 0103 NV10 [Quadro] - 0110 NV11 [GeForce2 MX] + 0103 NV10GL [Quadro] + 0110 NV11 [GeForce2 MX/MX 400] 1043 4015 AGP-V7100 Pro 1043 4031 V7100 Pro with TV output + 1462 8817 MSI GeForce2 MX400 Pro32S [MS-8817] + 14af 7102 3D Prophet II MX 14af 7103 3D Prophet II MX Dual-Display - 0111 NV11 [GeForce2 MX DDR] + 0111 NV11DDR [GeForce2 MX 100 DDR/200 DDR] 0112 NV11 [GeForce2 Go] - 0113 NV11 [GeForce2 MXR] - 0150 NV15 [GeForce2 GTS] + 0113 NV11GL [Quadro2 MXR/EX] + 0150 NV15 [GeForce2 GTS/Pro] 1043 4016 V7700 AGP Video Card 107d 2840 WinFast GeForce2 GTS with TV output 1462 8831 Creative GeForce2 Pro - 0151 NV15 [GeForce2 Ti] - 0152 NV15 [GeForce2 Ultra, Bladerunner] + 0151 NV15DDR [GeForce2 Ti] + 1043 405f V7700Ti + 0152 NV15BR [GeForce2 Ultra, Bladerunner] 1048 0c56 GLADIAC Ultra - 0153 NV15 [Quadro2 Pro] - 0170 NV17 [GeForce4 MX460] - 0171 NV17 [GeForce4 MX440] - 0172 NV17 [GeForce4 MX420] - 0173 NV1x + 0153 NV15GL [Quadro2 Pro] + 0170 NV17 [GeForce4 MX 460] + 0171 NV17 [GeForce4 MX 440] + 10b0 0002 Gainward Pro/600 TV + 1462 8661 G4MX440-VTP + 1462 8730 MX440SES-T (MS-8873) + 147b 8f00 Abit Siluro GeForce4MX440 + 0172 NV17 [GeForce4 MX 420] + 0173 NV17 [GeForce4 MX 440-SE] 0174 NV17 [GeForce4 440 Go] 0175 NV17 [GeForce4 420 Go] 0176 NV17 [GeForce4 420 Go 32M] - 0178 Quadro4 500XGL + 0178 NV17GL [Quadro4 550 XGL] 0179 NV17 [GeForce4 440 Go 64M] - 017a Quadro4 200/400NVS - 017b Quadro4 550XGL - 017c Quadro4 550 GoGL + 017a NV17GL [Quadro4 200/400 NVS] + 017b NV17GL [Quadro4 550 XGL] + 017c NV17GL [Quadro4 550 GoGL] + 0181 NV18 [GeForce4 MX 440 AGP 8x] + 0182 NV18 [GeForce4 MX 440SE AGP 8x] + 0183 NV18 [GeForce4 MX 420 AGP 8x] + 0188 NV18GL [Quadro4 580 XGL] + 018a NV18GL [Quadro4 NVS] + 018b NV18GL [Quadro4 380 XGL] 01a0 NV15 [GeForce2 - nForce GPU] 01a4 nForce CPU bridge 01ab nForce 420 Memory Controller (DDR) @@ -2495,31 +2723,54 @@ 01b7 nForce AGP to PCI Bridge 01b8 nForce PCI-to-PCI bridge 01bc nForce IDE + 01c1 Intel 537 [nForce MC97 Modem] + 01c2 nForce USB Controller + 01c3 nForce Ethernet Controller + 01e8 nForce2 AGP + 01f0 NV18 [GeForce4 MX - nForce GPU] 0200 NV20 [GeForce3] 1043 402f AGP-V8200 DDR - 0201 NV20 [GeForce3 Ti200] - 0202 NV20 [GeForce3 Ti500] + 0201 NV20 [GeForce3 Ti 200] + 0202 NV20 [GeForce3 Ti 500] 1043 405b V8200 T5 - 0203 NV20 [Quadro DCC] - 0250 NV25 [GeForce4 Ti4600] - 0251 NV25 [GeForce4 Ti4400] - 0253 NV25 [GeForce4 Ti4200] - 0258 Quadro4 900XGL - 0259 Quadro4 750XGL - 025b Quadro4 700XGL + 1545 002f Xtasy 6964 + 0203 NV20DCC [Quadro DCC] + 0250 NV25 [GeForce4 Ti 4600] + 0251 NV25 [GeForce4 Ti 4400] + 0252 NV25 [GeForce4 Ti] + 0253 NV25 [GeForce4 Ti 4200] + 107d 2896 WinFast A250 LE TD (Dual VGA/TV-out/DVI) + 147b 8f09 Siluro (Dual VGA/TV-out/DVI) + 0258 NV25GL [Quadro4 900 XGL] + 0259 NV25GL [Quadro4 750 XGL] + 025b NV25GL [Quadro4 700 XGL] + 0280 NV28 [GeForce4 Ti 4800] + 0281 NV28 [GeForce4 Ti 4200 AGP 8x] + 0282 NV28 [GeForce4 Ti 4800 SE] + 0286 NV28 [GeForce4 Ti 4200 Go AGP 8x] + 0288 NV28GL [Quadro4 980 XGL] + 0289 NV28GL [Quadro4 780 XGL] + 0300 NV30 [GeForce FX] + 0301 NV30 [GeForce FX 5800 Ultra] + 0302 NV30 [GeForce FX 5800] + 0308 NV30GL [Quadro FX 2000] + 0309 NV30GL [Quadro FX 1000] 10df Emulex Corporation - 10df Light Pulse Fibre Channel Adapter 1ae5 LP6000 Fibre Channel Host Adapter + f085 LP850 Fibre Channel Adapter + f095 LP952 Fibre Channel Adapter + f098 LP982 Fibre Channel Adapter f700 LP7000 Fibre Channel Host Adapter f800 LP8000 Fibre Channel Host Adapter f900 LP9000 Fibre Channel Host Adapter + f980 LP9802 Fibre Channel Adapter 10e0 Integrated Micro Solutions Inc. 5026 IMS5026/27/28 5027 IMS5027 5028 IMS5028 8849 IMS8849 8853 IMS8853 - 9128 IMS9129 [Twin turbo 128] + 9128 IMS9128 [Twin turbo 128] 10e1 Tekram Technology Co.,Ltd. 0391 TRM-S1040 10e1 0391 DC-315U SCSI-3 Host Adapter @@ -2529,6 +2780,7 @@ 10e3 Tundra Semiconductor Corp. 0000 CA91C042 [Universe] 0860 CA91C860 [QSpan] + 0862 CA91C862A [QSpan-II] 10e4 Tandem Computers 10e5 Micro Industries Corporation 10e6 Gainbery Computer Products Inc. @@ -2558,6 +2810,7 @@ 2010 CyberPro 2000A 5000 CyberPro 5000 5050 CyberPro 5050 + 5202 CyberPro 5202 10eb Artists Graphics 0101 3GA 8111 Twist3 Frame Grabber @@ -2580,6 +2833,7 @@ 1186 1300 DFE-538TX 1186 1320 SN5200 1186 8139 DRN-32TX + 11f6 8139 FN22-3(A) LinxPRO Ethernet Adapter 1259 2500 AT-2500TX 1259 2503 AT-2500TX/ACPI 1429 d010 ND010 @@ -2595,9 +2849,11 @@ 8e2e 7100 KF-230TX/2 a0a0 0007 ALN-325C 8169 RTL-8169 + 1371 434e ProG-2000L + 8197 SmartLAN56 56K Modem 10ed Ascii Corporation 7310 V7310 -10ee Xilinx, Inc. +10ee Xilinx Corporation 3fc0 RME Digi96 3fc1 RME Digi96/8 3fc2 RME Digi96/8 Pro @@ -2620,6 +2876,7 @@ 10fa Truevision 000c TARGA 1000 10fb Thesys Gesellschaft für Mikroelektronik mbH + 186f TH 6255 10fc I-O Data Device, Inc. # What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives 0003 Cardbus IDE Controller @@ -2651,14 +2908,21 @@ 1102 8040 CT4760 SBLive! 1102 8051 CT4850 SBLive! Value 1102 8061 SBLive! Player 5.1 + 1102 8064 SB Live! 5.1 Model SB0100 + 1102 8065 SBLive! 5.1 Digital Model SB0220 0004 SB Audigy 1102 0051 SB0090 Audigy Player + 1102 0053 SB0090 Audigy Player/OEM + 0006 [SB Live! Value] EMU10k1X 4001 SB Audigy FireWire Port + 1102 0010 SB Audigy FireWire Port 7002 SB Live! MIDI/Game Port 1102 0020 Gameport Joystick 7003 SB Audigy MIDI/Game port - 1102 0040 SB Audigy MIDI/Gameport - 8938 ES1371 + 1102 0040 SB Audigy MIDI/Game Port + 7004 [SB Live! Value] Input device controller + 8064 SB0100 [SBLive! 5.1 OEM] + 8938 Ectiva EV1938 1103 Triones Technologies, Inc. 0003 HPT343 # Revisions: 01=HPT366, 03=HPT370, 04=HPT370A, 05=HPT372 @@ -2669,23 +2933,32 @@ 0006 HPT302 0007 HPT371 0008 HPT374 + 0009 HPT372N 1104 RasterOps Corp. 1105 Sigma Designs, Inc. 1105 REALmagic Xcard MPEG 1/2/3/4 DVD Decoder 8300 REALmagic Hollywood Plus DVD Decoder 8400 EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder 1106 VIA Technologies, Inc. + 0102 Embedded VIA Ethernet Controller 0130 VT6305 1394.A Controller 0305 VT8363/8365 [KT133/KM133] 1043 8033 A7V Mainboard + 1043 803e A7V-E Mainboard 1043 8042 A7V133/A7V133-C Mainboard 147b a401 KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard 0391 VT8371 [KX133] 0501 VT8501 [Apollo MVP4] 0505 VT82C505 - 0561 VT82C561 - 0571 VT82C586B PIPC Bus Master IDE - 1458 5002 GA-7VAX Mainboard +# Shares chip with :0576. The VT82C576M has :1571 instead of :0561. + 0561 VT82C576MV + 0571 VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE + 1019 0985 P6VXA Motherboard + 1043 8052 VT8233A Bus Master ATA100/66/33 IDE + 1043 808c A7V8X motherboard + 1106 0571 VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE + 1179 0001 Magnia Z310 + 1458 5002 GA-7VAX Mainboard 0576 VT82C576 3V [Apollo Master] 0585 VT82C585VP [Apollo VP1/VPX] 0586 VT82C586/A/B PCI-to-ISA [Apollo VP] @@ -2698,24 +2971,35 @@ 0598 VT82C598 [Apollo MVP3] 0601 VT8601 [Apollo ProMedia] 0605 VT8605 [ProSavage PM133] + 1043 802c CUV4X mainboard 0680 VT82C680 [Apollo P6] 0686 VT82C686 [Apollo Super South] + 1019 0985 P6VXA Motherboard + 1043 802c CUV4X mainboard 1043 8033 A7V Mainboard + 1043 803e A7V-E Mainboard + 1043 8040 A7M266 Mainboard 1043 8042 A7V133/A7V133-C Mainboard 1106 0000 VT82C686/A PCI to ISA Bridge 1106 0686 VT82C686/A PCI to ISA Bridge + 1179 0001 Magnia Z310 + 147b a702 KG7-Lite Mainboard 0691 VT82C693A/694x [Apollo PRO133x] + 1019 0985 P6VXA Motherboard + 1179 0001 Magnia Z310 1458 0691 VT82C691 Apollo Pro System Controller 0693 VT82C693 [Apollo Pro Plus] 0698 VT82C693A [Apollo Pro133 AGP] 0926 VT82C926 [Amazon] 1000 VT82C570MV 1106 VT82C570MV - 1571 VT82C416MV + 1571 VT82C576M/VT82C586 1595 VT82C595/97 [Apollo VP2/97] 3038 USB 0925 1234 USB Controller - 1234 0925 MVP3 USB Controller + 1019 0985 P6VXA Motherboard + 1043 808c A7V8X motherboard + 1179 0001 Magnia Z310 3040 VT82C586B ACPI 3043 VT86C100A [Rhine] 10bd 0000 VT86C100A Fast Ethernet Adapter @@ -2725,41 +3009,60 @@ 3050 VT82C596 Power Management 3051 VT82C596 Power Management 3057 VT82C686 [Apollo Super ACPI] + 1019 0985 P6VXA Motherboard 1043 8033 A7V Mainboard + 1043 803e A7V-E Mainboard + 1043 8040 A7M266 Mainboard 1043 8042 A7V133/A7V133-C Mainboard + 1179 0001 Magnia Z310 3058 VT82C686 AC97 Audio Controller 0e11 b194 Soundmax integrated digital audio + 1019 0985 P6VXA Motherboard 1106 4511 Onboard Audio on EP7KXA 1458 7600 Onboard Audio 1462 3091 MS-6309 Onboard Audio 15dd 7609 Onboard Audio - 3059 VT8233 AC97 Audio Controller - 1458 a002 GA-7VAX Onboard Audio (Realtek ALC650) + 3059 VT8233/A/8235 AC97 Audio Controller + 1043 8095 A7V8X Motherboard (Realtek ALC650 codec) + 1458 a002 GA-7VAX Onboard Audio (Realtek ALC650) 3065 VT6102 [Rhine-II] + 1106 0102 VT6102 [Rhine II] Embeded Ethernet Controller on VT8235 1186 1400 DFE-530TX rev A 1186 1401 DFE-530TX rev B - 3068 AC97 Modem Controller + 13b9 1421 LD-10/100AL PCI Fast Ethernet Adapter (rev.B) + 3068 Intel 537 [AC97 Modem] 3074 VT8233 PCI to ISA Bridge + 1043 8052 VT8233A 3091 VT8633 [Apollo Pro266] - 3099 VT8367 [KT266] - 1043 8064 A7V266-E - 1043 807f A7V333 + 3099 VT8366/A/7 [Apollo KT266/A/333] + 1043 8064 A7V266-E Mainboard + 1043 807f A7V333 Mainboard 3101 VT8653 Host Bridge 3102 VT8662 Host Bridge 3103 VT8615 Host Bridge 3104 USB 2.0 + 1043 808c A7V8X motherboard 1458 5004 GA-7VAX Mainboard + 3106 VT6105 [Rhine-III] 3109 VT8233C PCI to ISA Bridge 3112 VT8361 [KLE133] Host Bridge + 3116 VT8375 [KM266/KL266] Host Bridge +# found on EPIA M6000/9000 mainboard + 3122 VT8623 [Apollo CLE266] integrated CastleRock graphics +# found on EPIA M6000/9000 mainboard + 3123 VT8623 [Apollo CLE266] 3128 VT8753 [P4X266 AGP] 3133 VT3133 Host Bridge 3147 VT8233A ISA Bridge 3148 P4M266 Host Bridge 3156 P/KN266 Host Bridge - 3177 VT8233A ISA Bridge - 1458 5001 GA-7VAX Mainboard + 3168 VT8374 P4X400 Host Controller/AGP Bridge + 3177 VT8235 ISA Bridge + 1043 808c A7V8X motherboard + 1458 5001 GA-7VAX Mainboard 3189 VT8377 [KT400 AGP] Host Bridge - 1458 5000 GA-7VAX Mainboard + 1043 807f A7V8X motherboard + 1458 5000 GA-7VAX Mainboard 5030 VT82C596 ACPI [Apollo PRO] 6100 VT85C100A [Rhine II] 8231 VT8231 [PCI-to-ISA Bridge] @@ -2770,12 +3073,13 @@ 8596 VT82C596 [Apollo PRO AGP] 8597 VT82C597 [Apollo VP3 AGP] 8598 VT82C598/694x [Apollo MVP3/Pro133x AGP] + 1019 0985 P6VXA Motherboard 8601 VT8601 [Apollo ProMedia AGP] 8605 VT8605 [PM133 AGP] 8691 VT82C691 [Apollo Pro] 8693 VT82C693 [Apollo Pro Plus] PCI Bridge b091 VT8633 [Apollo Pro266 AGP] - b099 VT8367 [KT333 AGP] + b099 VT8366/A/7 [Apollo KT266/A/333 AGP] b101 VT8653 AGP Bridge b102 VT8362 AGP Bridge b103 VT8615 AGP Bridge @@ -2797,6 +3101,12 @@ 110a Siemens Nixdorf AG 0002 Pirahna 2-port 0005 Tulip controller, power management, switch extender + 0006 FSC PINC (I/O-APIC) + 0015 FSC Multiprocessor Interrupt Controller + 001d FSC Copernicus Management Controller + 007b FSC Remote Service Controller, mailbox device + 007c FSC Remote Service Controller, shared memory device + 007d FSC Remote Service Controller, SMIC device 2102 DSCC4 WAN adapter 4942 FPGA I-Bus Tracer for MBD 6120 SZB6120 @@ -2811,8 +3121,8 @@ 6037 Firepower Powerized SMP I/O ASIC 6073 Firepower Powerized SMP I/O ASIC 1111 Santa Cruz Operation -# DJ: Some people say that 0x1112 is Rockwell International -1112 RNS - Div. of Meret Communications Inc +# Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom +1112 Osicom Technologies Inc 2200 FDDI Adapter 2300 Fast Ethernet Adapter 2340 4 Port Fast Ethernet Adapter @@ -2822,6 +3132,7 @@ 103c 1207 EN-1207D Fast Ethernet Adapter 1113 1211 EN-1207D Fast Ethernet Adapter 1216 EN-1216 Ethernet Adapter + 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?] 1217 EN-1217 Ethernet Adapter 5105 10Mbps Network card 9211 EN-1207D Fast Ethernet Adapter @@ -2962,9 +3273,14 @@ 0001 MVC IM-PCI Video frame grabber/processor 1130 Computervision 1131 Philips Semiconductors + 1561 USB 1.1 Host Controller + 1562 USB 2.0 Host Controller + 3400 SmartPCI56(UCB1500) 56K Modem 7130 SAA7130 Video Broadcast Decoder + 7133 SAA7133 Audio+video broadcast decoder # PCI audio and video broadcast decoder (http://www.semiconductors.philips.com/pip/saa7134hl) 7134 SAA7134 + 7135 SAA7135 Audio+video broadcast decoder 7145 SAA7145 7146 SAA7146 114b 2003 DVRaptor Video Edit/Capture Card @@ -2993,6 +3309,7 @@ 1133 e004 DIVA 2.0 U e005 DIVA LOW 1133 e005 DIVA 2.01 S/T + e00b DIVA 2.02 e010 DIVA Server BRI-2M 1133 e010 DIVA Server BRI-2M e012 DIVA Server BRI-8M @@ -3041,15 +3358,15 @@ 1144 Cincinnati Milacron 0001 Noservo controller 1145 Workbit Corporation - f007 NinjaSCSI-32 KME 8007 NinjaSCSI-32 Workbit + f007 NinjaSCSI-32 KME f010 NinjaSCSI-32 Workbit f012 NinjaSCSI-32 Logitec f013 NinjaSCSI-32 Logitec f015 NinjaSCSI-32 Melco 1146 Force Computers 1147 Interface Corp -1148 SysKonnect +1148 Syskonnect (Schneider & Koch) 4000 FDDI Adapter 0e11 b03b Netelligent 100 FDDI DAS Fibre SC 0e11 b03c Netelligent 100 FDDI SAS Fibre SC @@ -3067,29 +3384,37 @@ 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64) 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS) 4200 Token Ring adapter - 4300 SK-98xx Gigabit Ethernet Server Adapter - 1148 9821 SK-9821 Gigabit Ethernet 1000Base-T Server Adapter - 1148 9822 SK-9822 Gigabit Ethernet 1000Base-T Dual Port Server Adapter - 1148 9841 SK-9841 Gigabit Ethernet 1000Base-LX Server Adapter - 1148 9842 SK-9842 Gigabit Ethernet 1000Base-LX Dual Port Server Adapter - 1148 9843 SK-9843 Gigabit Ethernet 1000Base-SX Server Adapter - 1148 9844 SK-9844 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter - 1148 9861 SK-9861 Gigabit Ethernet 1000Base-SX Server Adapter - 1148 9862 SK-9862 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter - 1148 9871 SK-9871 Gigabit Ethernet 1000Base-ZX Server Adapter - 1148 9872 SK-9872 Gigabit Ethernet 1000Base-ZX Dual Port Server Adapter + 4300 Gigabit Ethernet + 1148 9821 SK-9821 (1000Base-T single link) + 1148 9822 SK-9822 (1000Base-T dual link) + 1148 9841 SK-9841 (1000Base-LX single link) + 1148 9842 SK-9842 (1000Base-LX dual link) + 1148 9843 SK-9843 (1000Base-SX single link) + 1148 9844 SK-9844 (1000Base-SX dual link) + 1148 9861 SK-9861 (1000Base-SX VF45 single link) + 1148 9862 SK-9862 (1000Base-SX VF45 dual link) +# Information got from SysKonnekt + 1148 9871 SK-9871 (1000Base-ZX single link) +# Information got from SysKonnekt + 1148 9872 SK-9872 (1000Base-ZX dual link) + 1259 2970 AT-2970SX [Allied Telesyn] + 1259 2972 AT-2970T [Allied Telesyn] + 1259 2975 AT-2970SX [Allied Telesyn] + 1259 2977 AT-2970T [Allied Telesyn] 4320 SK-98xx Gigabit Ethernet Server Adapter - 1148 9521 SK-9521 10/100/1000Base-T Adapter 1148 5021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter 1148 5041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter 1148 5043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter 1148 5051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter + 1148 9521 SK-9521 10/100/1000Base-T Adapter 4400 Gigabit Ethernet 1149 Win System Corporation 114a VMIC 5579 VMIPCI-5579 (Reflective Memory Card) + 5587 VMIPCI-5587 (Reflective Memory Card) + 6504 VMIC PCI 7755 FPGA 7587 VMIVME-7587 114b Canopus Co., Ltd 114c Annabooks @@ -3200,11 +3525,13 @@ 0001 Motion TPEG Recorder/Player with audio 1166 ServerWorks 0005 CNB20-LE Host Bridge + 0006 CNB20HE Host Bridge 0007 CNB20-LE Host Bridge 0008 CNB20HE Host Bridge 0009 CNB20LE Host Bridge 0010 CIOB30 0011 CMIC-HE + 0012 CMIC-LE 0013 CNB20-HE Host Bridge 0014 CNB20-HE Host Bridge 0015 CMIC-GC Host Bridge @@ -3270,7 +3597,9 @@ 0465 RL5c465 0466 RL5c466 0475 RL5c475 + 144d c006 vpr Matrix 170B4 CardBus bridge 0476 RL5c476 II + 1014 0185 ThinkPad A/T/X Series 104d 80df Vaio PCG-FX403 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0477 RL5c477 @@ -3279,7 +3608,9 @@ 0522 R5C522 IEEE 1394 Controller 1014 01cf ThinkPad A30p (2653-64G) 0551 R5C551 IEEE 1394 Controller + 144d c006 vpr Matrix 170B4 0552 R5C552 IEEE 1394 Controller + 1014 0511 ThinkPad A/T/X Series 1181 Telmatics International 1183 Fujikura Ltd 1184 Forks Inc @@ -3371,7 +3702,9 @@ 4240 AMCC S933Q Intelligent Serial Card 11aa Actel 11ab Galileo Technology Ltd. - 0146 GT-64010 + 0146 GT-64010/64010A System Controller + 4611 GT-64115 System Controller + 4620 GT-64120/64120A/64121A System Controller 4801 GT-48001 f003 GT-64010 Primary Image Piranha Image Generator 11ac Canon Information Systems Research Aust. @@ -3467,6 +3800,7 @@ 0443 LT WinModem 0444 LT WinModem 0445 LT WinModem + 8086 2203 PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card) 0446 LT WinModem 0447 LT WinModem 0448 WinModem 56k @@ -3496,6 +3830,7 @@ 044e LT WinModem 044f V90 WildWire Modem 0450 LT WinModem + 144f 4005 Magnia SG20 0451 LT WinModem 0452 LT WinModem 0453 LT WinModem @@ -3506,15 +3841,18 @@ 0458 LT WinModem 0459 LT WinModem 045a LT WinModem + 045c LT WinModem 0461 V90 WildWire Modem 0462 V90 WildWire Modem 0480 Venus Modem (V90, 56KFlex) 5801 USB 5802 USS-312 USB Controller +# 4 port PCI USB Controller made by Agere (formely Lucent) + 5803 USS-344S USB Controller 5811 FW323 dead 0800 FireWire Host Bus Adapter 11c2 Sand Microelectronics -11c3 NEC Corp +11c3 NEC Corporation 11c4 Document Technologies, Inc 11c5 Shiva Corporation 11c6 Dainippon Screen Mfg. Co. Ltd @@ -3568,6 +3906,7 @@ 11e1 GEC Plessey Semi Inc. 11e2 Samsung Information Systems America 11e3 Quicklogic Corporation + 5030 PC Watchdog 11e4 Second Wave Inc 11e5 IIX Consulting 11e6 Mitsui-Zosen System Research @@ -3629,6 +3968,11 @@ 1200 CSS Corporation 1201 Vista Controls Corp 1202 Network General Corp. + 4300 Gigabit Ethernet Adapter + 1202 9841 SK-9841 LX + 1202 9842 SK-9841 LX dual link + 1202 9843 SK-9843 SX + 1202 9844 SK-9843 SX dual link 1203 Bayer Corporation, Agfa Division 1204 Lattice Semiconductor Corporation 1205 Array Corporation @@ -3675,6 +4019,7 @@ 6933 OZ6933 Cardbus Controller 1025 1016 Travelmate 612 TX 6972 OZ6912 Cardbus Controller + 1179 0001 Magnia Z310 1218 Hybricon Corp. 1219 First Virtual Corporation 121a 3Dfx Interactive, Inc. @@ -3696,7 +4041,6 @@ 139c 0016 Raven 139c 0017 Raven 14af 0002 Maxi Gamer Phoenix - 3030 3030 Skywell Magic TwinPower 0004 Voodoo Banshee [Velocity 100] 0005 Voodoo 3 121a 0004 Voodoo3 AGP @@ -3808,7 +4152,7 @@ 1249 Samsung Electronics Co., Ltd. 124a AEG Electrocom GmbH 124b SBS/Greenspring Modular I/O - 0040 cPCI-200 Four Slot IndustryPack carrier + 0040 PCI-40A or cPCI-200 Quad IndustryPack carrier 124b 9080 PCI9080 Bridge 124c Solitron Technologies, Inc. 124d Stallion Technologies, Inc. @@ -3853,6 +4197,7 @@ 125d 8888 Solo-1 Audio Adapter 525f c888 ES1969 SOLO-1 AudioDrive (+ES1938) 1978 ES1978 Maestro 2E + 0e11 b112 Armada M700 1033 803c ES1978 Maestro-2E Audiodrive 1033 8058 ES1978 Maestro-2E Audiodrive 1092 4000 Monster Sound MX400 @@ -3884,6 +4229,10 @@ 1260 Harris Semiconductor 3873 Prism 2.5 Wavelan chipset 1186 3501 DWL-520 Wireless PCI Adapter + 1668 0414 HWP01170-01 802.11b PCI Wireless Adapter + 1737 3874 WMP11 Wireless 802.11b PCI Adapter + 8086 2513 Wireless 802.11b MiniPCI Adapter + 3890 D-Links DWL-g650 A1 8130 HMP8130 NTSC/PAL Video Decoder 8131 HMP8131 NTSC/PAL Video Decoder 1261 Matsushita-Kotobuki Electronics Industries, Ltd. @@ -3919,6 +4268,7 @@ 1273 Hughes Network Systems 0002 DirecPC 1274 Ensoniq + 1171 ES1373 [AudioPCI] (also Creative Labs CT5803) 1371 ES1371 [AudioPCI-97] 0e11 0024 AudioPCI on Motherboard Compaq Deskpro 0e11 b1a7 ES1371, ES1373 AudioPCI @@ -3989,6 +4339,7 @@ 1277 Comstream 1278 Transtech Parallel Systems Ltd. 0701 TPE3/TM3 PowerPC Node + 0710 TPE5 PowerPC PCI board 1279 Transmeta Corporation 0295 Northbridge 0395 LongRun Northbridge @@ -4184,6 +4535,7 @@ 12ae 0001 Gigabit Ethernet-SX (Universal) 1410 0104 Gigabit Ethernet-SX PCI Adapter 0002 AceNIC Gigabit Ethernet (Copper) + 10a9 8002 Acenic Gigabit Ethernet 12ae 0002 Gigabit Ethernet-T (3C986-T) 12af TDK USA Corp 12b0 Jorge Scientific Corp @@ -4214,7 +4566,7 @@ 12b9 00ab USR 56k Internal Voice Modem (Model 5609) 12b9 00ac USR 56k Internal Voice Modem (Model 3298) 12b9 00ad USR 56k Internal FAX Modem (Model 5610) -12ba PMC Sierra +12ba BittWare, Inc. 12bb Nippon Unisoft Corporation 12bc Array Microsystems 12bd Computerm Corp. @@ -4278,11 +4630,14 @@ 00a0 ITNT2 12d3 Vingmed Sound A/S 12d4 Ulticom (Formerly DGM&S) + 0200 T1 Card 12d5 Equator Technologies 12d6 Analogic Corp 12d7 Biotronic SRL 12d8 Pericom Semiconductor 12d9 Aculab PLC + 0002 PCI Prosody + 0004 cPCI Prosody 12da True Time Inc. 12db Annapolis Micro Systems, Inc 12dc Symicron Computer Communication Ltd. @@ -4400,6 +4755,7 @@ 0036 PCI-DAS64/M2/16 0037 PCI-DAS64/M3/16 004c PCI-DAS1000 + 004d PCI-QUAD04 1308 Jato Technologies Inc. 0001 NetCelerator Adapter 1308 0001 NetCelerator Adapter @@ -4486,6 +4842,8 @@ 1330 MMC Networks 1331 Radisys Corp. 1332 Micro Memory + 5415 MM-5415CN PCI Memory Module with Battery Backup + 5425 MM-5425CN PCI 64/66 Memory Module with Battery Backup 1334 Redcreek Communications, Inc 1335 Videomail, Inc 1337 Third Planet Publishing @@ -4523,7 +4881,11 @@ 134f Algo System Co Ltd 1350 Systec Co. Ltd 1351 Sonix Inc -1353 Dassault A.T. +1353 Thales Idatys + 0002 Proserver + 0003 PCI-FUT + 0004 PCI-S0 + 0005 PCI-FUT-S0 1354 Dwave System Inc 1355 Kratos Analytical Ltd 1356 The Logical Co @@ -4531,7 +4893,19 @@ 135a Brain Boxes 135b Giganet Inc 135c Quatech Inc + 0010 QSC-100 + 0020 DSC-100 + 0030 DSC-200/300 + 0040 QSC-200/300 + 0050 ESC-100D + 0060 ESC-100M 00f0 MPAC-100 Syncronous Serial Card (Zilog 85230) + 0170 QSCLP-100 + 0180 DSCLP-100 + 0190 SSCLP-100 + 01a0 QSCLP-200/300 + 01b0 DSCLP-200/300 + 01c0 SSCLP-200/300 135d ABB Network Partner AB 135e Sealevel Systems Inc 7101 Single Port RS-232/422/485/530 @@ -4579,6 +4953,7 @@ 1384 Reality Simulation Systems Inc 1385 Netgear 4100 802.11b Wireless Adapter (MA301) + 4105 MA311 802.11b wireless adapter 620a GA620 622a GA622 630a GA630 @@ -4631,6 +5006,10 @@ 0006 6500 Public Key Processor 0007 7811 Security Processor 0012 7951 Security Processor + 0014 78XX Security Processor + 0016 8065 Security Processor + 0017 8165 Security Processor + 0018 8154 Security Processor 13a4 Rascom Inc 13a5 Audio Digital Imaging Inc 13a6 Videonics Inc @@ -4681,7 +5060,10 @@ 13ce Cocom A/S 13cf Studio Audio & Video Ltd 13d0 Techsan Electronics Co Ltd +# http://www.b2c2inc.com/products/pc-specs.html + 2103 B2C2 Sky2PC PCI [SkyStar2] 13d1 Abocom Systems Inc + ab02 ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter ab06 RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter 13d2 Shark Multimedia Inc 13d3 IMC Networks @@ -4708,7 +5090,7 @@ 13e6 Argosy research Inc 13e7 NAC Incorporated 13e8 Chip Express Corporation -13e9 Chip Express Corporation +13e9 Intraserver Technology Inc 13ea Dallas Semiconductor 13eb Hauppauge Computer Works Inc 13ec Zydacron Inc @@ -4729,9 +5111,11 @@ 0101 CM8338B 13f6 0101 CMI8338-031 PCI Audio Device 0111 CM8738 + 1019 0970 P6STP-FL motherboard 1043 8077 CMI8738 6-channel audio controller 1043 80e2 CMI8738 6ch-MX 13f6 0111 CMI8738/C3DX PCI Audio Device + 1681 a000 Gamesurround MUSE XL 0211 CM8738 13f7 Wildfire Communications 13f8 Ad Lib Multimedia Inc @@ -4778,6 +5162,7 @@ 1411 Ikos Systems Inc 1412 IC Ensemble Inc 1712 ICE1712 [Envy24] + 1724 ICE1724 [Envy24HT] 1413 Addonics 1414 Microsoft Corporation 1415 Oxford Semiconductor Ltd @@ -4875,7 +5260,7 @@ 0001 NextMove PCI 1460 DYNARC INC 1461 Avermedia Technologies Inc -1462 Micro-star International Co Ltd +1462 Micro-Star International Co., Ltd. 1463 Fast Corporation 1464 Interactive Circuits & Systems Ltd 1465 GN NETTEST Telecom DIV. @@ -4886,6 +5271,7 @@ 146a IFR 146b Parascan Technologies Ltd 146c Ruby Tech Corp. + 1430 FE-1430TX Fast Ethernet PCI Adapter 146d Tachyon, INC. 146e Williams Electronics Games, Inc. 146f Multi Dimensional Consulting Inc @@ -4936,6 +5322,7 @@ 149b SEIKO Instruments Inc 149c OVISLINK Corp. 149d NEWTEK Inc + 0001 Video Toaster for PC 149e Mapletree Networks Inc. 149f LECTRON Co Ltd 14a0 SOFTING GmBH @@ -4954,6 +5341,7 @@ 14ad Time Space Radio AB 14ae CTI, Inc 14af Guillemot Corporation + 7102 3D Prophet II MX 14b0 BST Communication Technology Ltd 14b1 Nextcom K.K. 14b2 ENNOVATE Networks Inc @@ -4961,6 +5349,14 @@ 0000 DSL NIC 14b4 PHILIPS Business Electronics B.V. 14b5 Creamware GmBH + 0200 Scope + 0300 Pulsar + 0400 Pulsar2 + 0600 Pulsar2 + 0800 DSP-Board + 0900 DSP-Board + 0a00 DSP-Board + 0b00 DSP-Board 14b6 Quantum Data Corp. 14b7 PROXIM Inc 0001 Symphony 4110 @@ -4971,6 +5367,7 @@ 0350 PC4800 4500 PC4500 4800 PC4800 + a504 Cisco Aironet Wireless 802.11b 14ba INTERNIX Inc. 14bb SEMTECH Corporation 14bc Globespan Semiconductor Inc. @@ -5043,40 +5440,44 @@ 14e3 AMTELCO 14e4 Broadcom Corporation 1644 NetXtreme BCM5700 Gigabit Ethernet - 1014 0277 Broadcom Vigil B5700 1000BaseTX + 1014 0277 Broadcom Vigil B5700 1000Base-T 1028 00d1 Broadcom BCM5700 1028 0106 Broadcom BCM5700 - 1028 0109 Broadcom BCM5700 1000BaseTX + 1028 0109 Broadcom BCM5700 1000Base-T 1028 010a Broadcom BCM5700 1000BaseTX - 10b7 1000 3C996-T 1000BaseTX - 10b7 1001 3C996B-T 1000BaseTX - 10b7 1002 3C996C-T 1000BaseTX - 10b7 1003 3C997-T 1000BaseTX Dual Port - 10b7 1004 3C996-SX 1000BaseSX - 10b7 1005 3C997-SX 1000BaseSX Dual Port + 10b7 1000 3C996-T 1000Base-T + 10b7 1001 3C996B-T 1000Base-T + 10b7 1002 3C996C-T 1000Base-T + 10b7 1003 3C997-T 1000Base-T Dual Port + 10b7 1004 3C996-SX 1000Base-SX + 10b7 1005 3C997-SX 1000Base-SX Dual Port 10b7 1008 3C942 Gigabit LOM (31X31) - 14e4 0002 NetXtreme 1000BaseSX - 14e4 0003 NetXtreme 1000BaseSX - 14e4 0004 NetXtreme 1000BaseTX + 14e4 0002 NetXtreme 1000Base-SX + 14e4 0003 NetXtreme 1000Base-SX + 14e4 0004 NetXtreme 1000Base-T 14e4 1028 NetXtreme 1000BaseTX - 14e4 1644 BCM5700 1000BaseTX + 14e4 1644 BCM5700 1000Base-T 1645 NetXtreme BCM5701 Gigabit Ethernet 0e11 007c NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T) 0e11 007d NC6770 Gigabit Server Adapter (PCI-X, 1000-SX) 0e11 0085 NC7780 Gigabit Server Adapter (embedded, WOL) 0e11 0099 NC7780 Gigabit Server Adapter (embedded, WOL) 0e11 009a NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T) - 1028 0121 Broadcom BCM5701 1000BaseTX - 10b7 1004 3C996-SX 1000BaseSX - 10b7 1006 3C996B-T 1000BaseTX - 10b7 1007 3C1000-T 1000BaseTX - 10b7 1008 3C940-BR01 1000BaseTX - 14e4 0001 BCM5701 1000BaseTX - 14e4 0005 BCM5701 1000BaseTX - 14e4 0006 BCM5701 1000BaseTX - 14e4 0007 BCM5701 1000BaseSX - 14e4 0008 BCM5701 1000BaseTX - 14e4 8008 BCM5701 1000BaseTX + 0e11 00c1 NC6770 Gigabit Server Adapter (PCI-X, 1000-SX) + 1028 0121 Broadcom BCM5701 1000Base-T + 10a9 8010 SGI IO9 Gigabit Ethernet (Copper) + 10a9 8011 SGI Gigabit Ethernet (Copper) + 10a9 8012 SGI Gigabit Ethernet (Fiber) + 10b7 1004 3C996-SX 1000Base-SX + 10b7 1006 3C996B-T 1000Base-T + 10b7 1007 3C1000-T 1000Base-T + 10b7 1008 3C940-BR01 1000Base-T + 14e4 0001 BCM5701 1000Base-T + 14e4 0005 BCM5701 1000Base-T + 14e4 0006 BCM5701 1000Base-T + 14e4 0007 BCM5701 1000Base-SX + 14e4 0008 BCM5701 1000Base-T + 14e4 8008 BCM5701 1000Base-T 1646 NetXtreme BCM5702 Gigabit Ethernet 0e11 00bb NC7760 1000BaseTX 1028 0126 Broadcom BCM5702 1000BaseTX @@ -5084,19 +5485,57 @@ 1647 NetXtreme BCM5703 Gigabit Ethernet 0e11 0099 NC7780 1000BaseTX 0e11 009a NC7770 1000BaseTX + 10a9 8010 SGI IO9 Gigabit Ethernet (Copper) 14e4 0009 BCM5703 1000BaseTX 14e4 000a BCM5703 1000BaseSX 14e4 000b BCM5703 1000BaseTX 14e4 8009 BCM5703 1000BaseTX 14e4 800a BCM5703 1000BaseTX 1648 NetXtreme BCM5704 Gigabit Ethernet + 0e11 00cf NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + 0e11 00d0 NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + 0e11 00d1 NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + 10b7 2000 3C998-T Dual Port 10/100/1000 PCI-X + 10b7 3000 3C999-T Quad Port 10/100/1000 PCI-X + 1166 1648 NetXtreme CIOB-E 1000Base-T 164d NetXtreme BCM5702FE Gigabit Ethernet - 16a6 NetXtreme BCM5702X Gigabit Ethernet - 16a7 NetXtreme BCM5703X Gigabit Ethernet + 1653 NetXtreme BCM5705 Gigabit Ethernet + 165d NetXtreme BCM5705M Gigabit Ethernet + 1696 NetXtreme BCM5782 Gigabit Ethernet + 14e4 000d NetXtreme BCM5782 1000Base-T + 169c NetXtreme BCM5788 Gigabit Ethernet + 16a6 NetXtreme BCM5702 Gigabit Ethernet + 0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T) + 1028 0126 BCM5702 1000Base-T + 14e4 000c BCM5702 1000Base-T + 14e4 8009 BCM5702 1000Base-T + 16a7 NetXtreme BCM5703 Gigabit Ethernet + 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + 14e4 0009 NetXtreme BCM5703 1000Base-T + 14e4 000a NetXtreme BCM5703 1000Base-SX + 14e4 000b NetXtreme BCM5703 1000Base-T + 14e4 800a NetXtreme BCM5703 1000Base-T 16a8 NetXtreme BCM5704S Gigabit Ethernet - 16c6 NetXtreme BCM5702A3 Gigabit Ethernet - 16c7 NetXtreme BCM5703A3 Gigabit Ethernet - 4212 BCM v.90 56k modem + 10b7 2001 3C998-SX Dual Port 1000-SX PCI-X + 16c6 NetXtreme BCM5702 Gigabit Ethernet + 10b7 1100 3C1000B-T 10/100/1000 PCI + 14e4 000c BCM5702 1000Base-T + 14e4 8009 BCM5702 1000Base-T + 16c7 NetXtreme BCM5703 Gigabit Ethernet + 14e4 0009 NetXtreme BCM5703 1000Base-T + 14e4 000a NetXtreme BCM5703 1000Base-SX + 4210 BCM4210 iLine10 HomePNA 2.0 + 4211 BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem + 4212 BCM4212 v.90 56k modem + 4301 BCM4301 802.11b + 4320 BCM94306 802.11g + 4401 BCM4401 100Base-T + 1043 80a8 A7V8X motherboard + 4402 BCM4402 Integrated 10/100BaseT + 4410 BCM4413 iLine32 HomePNA 2.0 + 4411 BCM4413 V.90 56k modem + 4412 BCM4413 10/100BaseT 5820 BCM5820 Crypto Accelerator 5821 BCM5821 Crypto Accelerator 14e5 Pixelfusion Ltd @@ -5181,6 +5620,9 @@ 122d 4302 Dell MP3930V-W(C) MiniPCI 1610 ADSL AccessRunner PCI Arbitration Device 1611 AccessRunner PCI ADSL Interface Device + 1620 ADSL AccessRunner V2 PCI Arbitration Device + 1621 AccessRunner V2 PCI ADSL Interface Device + 1622 AccessRunner V2 PCI ADSL Yukon WAN Adapter 1803 HCF 56k Modem 0e11 0023 623-LAN Grizzly 0e11 0043 623-LAN Yogi @@ -5318,8 +5760,14 @@ 1522 0400 RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem 1522 0500 RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem 1522 0600 RockForce+ 2 Port V.90 Data/Fax/Voice Modem + 1522 0700 RockForce+ 4 Port V.90 Data/Fax/Voice Modem + 1522 0800 RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem 1523 MUSIC Semiconductors 1524 ENE Technology Inc + 1211 CB1211 Cardbus Controller + 1225 CB1225 Cardbus Controller + 1410 CB1410 Cardbus Controller + 1420 CB1420 Cardbus Controller 1525 IMPACT Technologies 1526 ISS, Inc 1527 SOLECTRON @@ -5350,6 +5798,8 @@ 1541 MACHONE Communications 1542 VIVID Technology Inc 1543 SILICON Laboratories + 3052 Intel 537 [Winmodem] + 4c22 Si3036 MC'97 DAA 1544 DCM DATA Systems 1545 VISIONTEK 1546 IOI Technology Corp @@ -5580,6 +6030,7 @@ 1607 Lava Semiconductor Manufacturing Inc 1608 Automated Wagering International 1609 Scimetric Instruments Inc +1612 Telesynergy Research Inc. 1619 FarSite Communications Ltd 0400 FarSync T2P (2 port X.21/V.35/V.24) 0440 FarSync T4P (4 port X.21/V.35/V.24) @@ -5588,22 +6039,40 @@ 2002 Fast Universal Data Output 1638 Standard Microsystems Corp [SMC] 1100 SMC2602W EZConnect / Addtron AWA-100 +163c Smart Link Ltd. + 3052 SmartLink SmartPCI562 56K Modem + 5449 SmartPCI561 Modem 1657 Brocade Communications Systems, Inc. +165a Epix Inc + c100 PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232] + d200 PIXCI(R) D2X Digital Video Capture Board [custom QL5232] + d300 PIXCI(R) D3X Digital Video Capture Board [custom QL5232] 165d Hsing Tech. Enterprise Co., Ltd. 1661 Worldspace Corp. -1668 Action Tec Electronics Inc +1668 Actiontec Electronics Inc +1681 Hercules +16ab Global Sun Technology Inc + 1102 PCMCIA-to-PCI Wireless Network Bridge +16be Creatix Polymedia GmbH +16ca CENATEK Inc + 0001 Rocket Drive DL 16ec U.S. Robotics 3685 Wireless Access PCI Adapter Model 022415 16f6 VideoTele.com, Inc. +1705 Digital First, Inc. 170b NetOctave Inc 170c YottaYotta Inc. +172a Accelerated Encryption +1737 Linksys 173b Altima (nee Broadcom) 03e8 AC1000 Gigabit Ethernet 03ea AC9100 Gigabit Ethernet + 173b 0001 AC1002 1743 Peppercon AG 8139 ROL/F-100 Fast Ethernet Adapter with ROL 174b PC Partner Limited 175e Sanera Systems, Inc. +1787 Hightech Information System Ltd. # also used by Struck Innovative Systeme for joint developments 1796 Research Centre Juelich 0001 SIS1100 [Gigabit link] @@ -5612,7 +6081,22 @@ 0004 CAMAC Controller 0005 PROFIBUS 0006 AMCC HOTlink +1799 Belkin +17af Hightech Information System Ltd. +17cc NetChip Technology, Inc + 2280 USB 2.0 1813 Ambient Technologies Inc + 4000 HaM controllerless modem + 16be 0001 V9x HAM Data Fax Modem + 4100 HaM plus Data Fax Modem + 16be 0002 V9x HAM 1394 +1851 Microtune, Inc. +1852 Anritsu Corp. +1888 Varisys Ltd + 0301 VMFX1 FPGA PMC module + 0601 VSM2 dual PMC carrier + 0710 VS14x series PowerPC PCI board + 0720 VS24x series PowerPC PCI board 1a08 Sierra semiconductor 0000 SC15064 1b13 Jaton Corp @@ -5625,7 +6109,12 @@ 2020 DC-390 690c 690c dc29 DC290 +1fc0 Tumsan Oy + 0300 E2200 Dual E1/Rawpipe Card +2000 Smart Link Ltd. 2001 Temporal Research Ltd +2003 Smart Link Ltd. +2004 Smart Link Ltd. 21c3 21st Century Computer Corp. 2348 Racore 2010 8142 100VG/AnyLAN @@ -5637,7 +6126,11 @@ 3000 Hansol Electronics Inc. 3142 Post Impression Systems. 3388 Hint Corp + 0013 HiNT HC4 PCI to ISDN bridge, Multimedia audio controller + 0014 HiNT HC4 PCI to ISDN bridge, Network controller 0021 HB1-SE33 PCI-PCI Bridge + 101a E.Band [AudioTrak Inca88] + 101b E.Band [AudioTrak Inca88] 8011 VXPro II Chipset 3388 8011 VXPro II Chipset CPU to PCI Bridge 8012 VXPro II Chipset @@ -5668,6 +6161,8 @@ 3d3d 0127 Permedia3 Create! 000a GLINT R3 3d3d 0121 Oxygen VX1 + 000c GLINT R3 [Oxygen VX1] + 3d3d 0144 Oxygen VX1-4X AGP [Permedia 4] 0100 Permedia II 2D+3D 1004 Permedia 3d04 Permedia @@ -5695,6 +6190,7 @@ 0100 AladdinCARD 0200 CPC 4444 Internext Compression Inc + 0803 iTVC15 MPEG-2 Encoder 4468 Bridgeport machines 4594 Cogetec Informatique Inc 45fb Baldor Electric Company @@ -5740,6 +6236,7 @@ 5143 Qualcomm Inc 5145 Ensoniq (Old) 3031 Concert AudioPCI +5168 Animation Technologies Inc. 5301 Alliance Semiconductor Corp. 0001 ProMotion aT3D 5333 S3 Inc. @@ -5848,7 +6345,9 @@ 8c10 86C270-294 Savage/MX-MV 8c11 82C270-294 Savage/MX 8c12 86C270-294 Savage/IX-MV + 1014 017f ThinkPad T20 8c13 86C270-294 Savage/IX + 1179 0001 Magnia Z310 8c22 SuperSavage MX/128 8c24 SuperSavage MX/64 8c26 SuperSavage MX/64C @@ -5859,10 +6358,10 @@ 8c2e SuperSavage IX/C SDR 1014 01fc ThinkPad T23 (2647-4MG) 8c2f SuperSavage IX/C DDR -# Integrated in VIA ProSavage PN133 North Bridge - 8d01 VT8603 [ProSavage PN133] AGP4X VGA Controller (Twister) + 8d01 86C380 [ProSavageDDR K4M266] 8d02 VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK) - 8d04 VT8751 [ProSavageDDR P4M266] VGA Controller + 8d03 VT8751 [ProSavageDDR P4M266] + 8d04 VT8375 [ProSavage8 KM266/KL266] 9102 86C410 Savage 2000 1092 5932 Viper II Z200 1092 5934 Viper II Z200 @@ -5874,6 +6373,7 @@ 1092 5a57 Viper II Z200 ca00 SonicVibes 544c Teralogic Inc + 0350 TL880-based HDTV/ATSC tuner 5455 Technische University Berlin 4458 S5933 5519 Cnet Technologies, Inc. @@ -5881,6 +6381,7 @@ 0001 I-30xx Scanner Interface 5555 Genroco, Inc 0003 TURBOstor HFP-832 [HiPPI NIC] +5654 VoiceTronix Pty Ltd 5700 Netpower 6356 UltraStor 6374 c't Magazin für Computertechnik @@ -5916,7 +6417,7 @@ 0e11 b123 NC1634 Gigabit Ethernet Adapter (1000-SX) 1014 0119 Netfinity Gigabit Ethernet SX Adapter 8086 1000 PRO/1000 Gigabit Server Adapter - 1001 82543GC Gigabit Ethernet Controller + 1001 82543GC Gigabit Ethernet Controller (Fiber) 0e11 004a NC6136 Gigabit Server Adapter 1014 01ea Netfinity Gigabit Ethernet SX Adapter 8086 1003 PRO/1000 F Server Adapter @@ -5924,44 +6425,46 @@ 8086 200e Pro 100 LAN+Modem 56 Cardbus II 8086 2013 Pro 100 SR Mobile Combo Adapter 8086 2017 Pro 100 S Combo Mobile Adapter - 1004 82543GC Gigabit Ethernet Controller + 1004 82543GC Gigabit Ethernet Controller (Copper) 0e11 0049 NC7132 Gigabit Upgrade Module 0e11 b1a4 NC7131 Gigabit Server Adapter 1014 10f2 Gigabit Ethernet Server Adapter 8086 1004 PRO/1000 T Server Adapter 8086 2004 PRO/1000 T Server Adapter - 1008 82544EI Gigabit Ethernet Controller + 1008 82544EI Gigabit Ethernet Controller (Copper) 8086 1107 PRO/1000 XT Server Adapter 8086 2107 PRO/1000 XT Server Adapter 8086 2110 PRO/1000 XT Server Adapter - 1009 82544EI Gigabit Ethernet Controller + 1009 82544EI Gigabit Ethernet Controller (Fiber) 8086 1109 PRO/1000 XF Server Adapter 8086 2109 PRO/1000 XF Server Adapter - 100c 82544GC Gigabit Ethernet Controller + 100c 82544GC Gigabit Ethernet Controller (Copper) 8086 1112 PRO/1000 T Desktop Adapter 8086 2112 PRO/1000 T Desktop Adapter - 100d 82544GC Gigabit Ethernet Controller + 100d 82544GC Gigabit Ethernet Controller (LOM) 100e 82540EM Gigabit Ethernet Controller 8086 001e PRO/1000 MT Desktop Adapter 8086 002e PRO/1000 MT Desktop Adapter - 100f 82545EM Gigabit Ethernet Controller + 100f 82545EM Gigabit Ethernet Controller (Copper) 8086 1001 PRO/1000 MT Server Adapter - 1010 82546EB Gigabit Ethernet Controller + 1010 82546EB Gigabit Ethernet Controller (Copper) 8086 1011 PRO/1000 MT Dual Port Server Adapter - 1011 82545EM Gigabit Ethernet Controller + 1011 82545EM Gigabit Ethernet Controller (Fiber) 8086 1002 PRO/1000 MF Server Adapter - 1012 82546EB Gigabit Ethernet Controller + 1012 82546EB Gigabit Ethernet Controller (Fiber) 8086 1012 PRO/1000 MF Dual Port Server Adapter + 1015 82540EM Gigabit Ethernet Controller (LOM) 1029 82559 Ethernet Controller 1030 82559 InBusiness 10/100 1031 82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller - 1014 0209 ThinkPad A30p (2653-64G) + 1014 0209 ThinkPad A/T/X Series 104d 80e7 Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 107b 5350 EtherExpress PRO/100 VE 1179 0001 EtherExpress PRO/100 VE 144d c000 EtherExpress PRO/100 VE 144d c001 EtherExpress PRO/100 VE 144d c003 EtherExpress PRO/100 VE + 144d c006 vpr Matrix 170B4 1032 82801CAM (ICH3) PRO/100 VE Ethernet Controller 1033 82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller 1034 82801CAM (ICH3) PRO/100 VM Ethernet Controller @@ -5975,16 +6478,25 @@ 103c 82801BD PRO/100 VM (CNR) Ethernet Controller 103d 82801BD PRO/100 VE (MOB) Ethernet Controller 103e 82801BD PRO/100 VM (MOB) Ethernet Controller + 1040 536EP Data Fax Modem + 16be 1040 V.9X DSP Data Fax Modem + 1043 PRO/Wireless LAN 2100 3B Mini PCI Adapter 1059 82551QM Ethernet Controller 1130 82815 815 Chipset Host Bridge and Memory Controller Hub + 1025 1016 Travelmate 612 TX 1043 8027 TUSL2-C Mainboard 104d 80df Vaio PCG-FX403 + 8086 4532 D815EEA2 mainboard + 8086 4557 D815EGEW Mainboard 1131 82815 815 Chipset AGP Bridge 1132 82815 CGC [Chipset Graphics Controller] 1025 1016 Travelmate 612 TX 104d 80df Vaio PCG-FX403 + 8086 4532 D815EEA2 Mainboard + 8086 4557 D815EGEW Mainboard 1161 82806AA PCI64 Hub Advanced Programmable Interrupt Controller 8086 1161 82806AA PCI64 Hub APIC + 1162 Xscale 80200 Big Endian Companion Chip 1200 Intel IXP1200 Network Processor 172a 0000 AEP SSL Accelerator 1209 82559ER @@ -6026,13 +6538,16 @@ 1014 01f2 10/100 Ethernet Server Adapter 1014 0207 Ethernet Pro/100 S 1014 0232 10/100 Dual Port Server Adapter + 1014 023a ThinkPad R30 1014 105c Netfinity 10/100 + 1014 2205 ThinkPad A22p 1014 305c 10/100 EtherJet Management Adapter 1014 405c 10/100 EtherJet Adapter with Alert on LAN 1014 505c 10/100 EtherJet Secure Management Adapter 1014 605c 10/100 EtherJet Secure Management Adapter 1014 705c 10/100 Netfinity 10/100 Ethernet Security Adapter 1014 805c 10/100 Netfinity 10/100 Ethernet Security Adapter + 1028 009b PowerEdge 2550 1033 8000 PC-9821X-B06 1033 8016 PK-UG-X006 1033 801f PK-UG-X006 @@ -6163,6 +6678,7 @@ 8086 8000 82806AA PCI64 Hub Controller (HRes) 1460 82870P2 P64H2 Hub PCI Bridge 1461 82870P2 P64H2 I/OxAPIC + 15d9 3480 P4DP6 1462 82870P2 P64H2 Hot Plug Controller 1960 80960RP [i960RP Microprocessor] 101e 0431 MegaRAID 431 RAID Controller @@ -6214,20 +6730,34 @@ 2428 82801AB PCI Bridge 2440 82801BA ISA Bridge (LPC) 2442 82801BA/BAM USB (Hub #1) + 1014 01c6 Netvista A40/A40p + 1025 1016 Travelmate 612 TX 104d 80df Vaio PCG-FX403 147b 0507 TH7II-RAID + 8086 4532 D815EEA2 mainboard + 8086 4557 D815EGEW Mainboard 2443 82801BA/BAM SMBus + 1014 01c6 Netvista A40/A40p + 1025 1016 Travelmate 612 TX 1043 8027 TUSL2-C Mainboard 104d 80df Vaio PCG-FX403 147b 0507 TH7II-RAID + 8086 4532 D815EEA2 mainboard + 8086 4557 D815EGEW Mainboard 2444 82801BA/BAM USB (Hub #2) + 1025 1016 Travelmate 612 TX 104d 80df Vaio PCG-FX403 147b 0507 TH7II-RAID + 8086 4532 D815EEA2 mainboard 2445 82801BA/BAM AC'97 Audio + 1014 01c6 Netvista A40/A40p + 1025 1016 Travelmate 612 TX 104d 80df Vaio PCG-FX403 1462 3370 STAC9721 AC 147b 0507 TH7II-RAID - 2446 82801BA/BAM AC'97 Modem + 8086 4557 D815EGEW Mainboard + 2446 Intel 537 [82801BA/BAM AC'97 Modem] + 1025 1016 Travelmate 612 TX 104d 80df Vaio PCG-FX403 2448 82801BAM/CAM PCI Bridge 2449 82801BA/BAM/CA/CAM Ethernet Controller @@ -6244,8 +6774,12 @@ 1014 023d EtherExpress PRO/100 VE 1014 0244 EtherExpress PRO/100 VE 1014 0245 EtherExpress PRO/100 VE + 1014 0265 PRO/100 VE Desktop Connection + 1014 0267 PRO/100 VE Desktop Connection + 1014 026a PRO/100 VE Desktop Connection 109f 315d EtherExpress PRO/100 VE 109f 3181 EtherExpress PRO/100 VE + 1179 ff01 PRO/100 VE Network Connection 1186 7801 EtherExpress PRO/100 VE 144d 2602 HomePNA 1M CNR 8086 3010 EtherExpress PRO/100 VE @@ -6261,10 +6795,13 @@ 1025 1016 Travelmate 612TX 104d 80df Vaio PCG-FX403 244b 82801BA IDE U100 + 1014 01c6 Netvista A40/A40p 1043 8027 TUSL2-C Mainboard 147b 0507 TH7II-RAID + 8086 4532 D815EEA2 mainboard + 8086 4557 D815EGEW Mainboard 244c 82801BAM ISA Bridge (LPC) - 244e 82801BA/CA/DB PCI Bridge + 244e 82801BA/CA/DB/EB PCI Bridge 2450 82801E ISA Bridge (LPC) 2452 82801E USB 2453 82801E SMBus @@ -6272,41 +6809,80 @@ 245b 82801E IDE U100 245d 82801E Ethernet Controller 1 245e 82801E PCI Bridge - 2480 82801CA ISA Bridge (LPC) + 2480 82801CA LPC Interface Controller 2482 82801CA/CAM USB (Hub #1) - 1014 0220 ThinkPad T23 (2647-4MG) or A30p (2653-64G) + 1014 0220 ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP - 2483 82801CA/CAM SMBus - 1014 0220 ThinkPad T23 (2647-4MG) or A30p (2653-64G) + 15d9 3480 P4DP6 + 8086 1958 vpr Matrix 170B4 + 2483 82801CA/CAM SMBus Controller + 1014 0220 ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + 15d9 3480 P4DP6 + 8086 1958 vpr Matrix 170B4 2484 82801CA/CAM USB (Hub #2) - 1014 0220 ThinkPad T23 (2647-4MG) or A30p (2653-64G) + 1014 0220 ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP - 2485 82801CA/CAM AC'97 Audio - 1014 0222 ThinkPad T23 (2647-4MG) + 15d9 3480 P4DP6 + 8086 1958 vpr Matrix 170B4 + 2485 82801CA/CAM AC'97 Audio Controller + 1014 0222 ThinkPad T23 (2647-4MG) or A30p (2653-64G) + 1014 0508 ThinkPad T30 + 1014 051c ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP - 2486 82801CA/CAM AC'97 Modem - 1014 0223 ThinkPad A30p (2653-64G) + 144d c006 vpr Matrix 170B4 + 2486 82801CA/CAM AC'97 Modem Controller + 1014 0223 ThinkPad A/T/X Series 1014 0503 ThinkPad R31 2656BBG + 1014 051a ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + 1179 0001 Toshiba Satellite 1110 Z15 internal Modem 134d 4c21 Dell Inspiron 2100 internal modem + 144d 2115 vpr Matrix 170B4 internal modem + 14f1 5421 MD56ORD V.92 MDC Modem 2487 82801CA/CAM USB (Hub #3) - 1014 0220 ThinkPad T23 (2647-4MG) or A30p (2653-64G) + 1014 0220 ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + 15d9 3480 P4DP6 + 8086 1958 vpr Matrix 170B4 248a 82801CAM IDE U100 - 1014 0220 ThinkPad T23 (2647-4MG) or A30p (2653-64G) + 1014 0220 ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP - 248b 82801CA IDE U100 + 8086 1958 vpr Matrix 170B4 + 248b 82801CA Ultra ATA Storage Controller + 15d9 3480 P4DP6 248c 82801CAM ISA Bridge (LPC) - 24c0 82801DB ISA Bridge (LPC) + 24c0 82801DB LPC Interface Controller + 1462 5800 845PE Max (MS-6580) 24c2 82801DB USB (Hub #1) - 24c3 82801DB SMBus + 1462 5800 845PE Max (MS-6580) + 24c3 82801DB/DBM SMBus Controller + 1462 5800 845PE Max (MS-6580) 24c4 82801DB USB (Hub #2) - 24c5 82801DB AC'97 Audio - 24c6 82801DB AC'97 Modem + 1462 5800 845PE Max (MS-6580) + 24c5 82801DB AC'97 Audio Controller + 1462 5800 845PE Max (MS-6580) + 24c6 82801DB AC'97 Modem Controller 24c7 82801DB USB (Hub #3) - 24cb 82801DB ICH4 IDE - 24cd 82801DB USB EHCI Controller + 1462 5800 845PE Max (MS-6580) + 24ca 82801DBM Ultra ATA Storage Controller + 24cb 82801DB Ultra ATA Storage Controller + 1462 5800 845PE Max (MS-6580) + 24cc 82801DBM LPC Interface Controller + 24cd 82801DB USB2 + 1462 3981 845PE Max (MS-6580) Onboard USB EHCI Controller + 24d0 82801EB LPC Interface Controller + 24d1 82801EB Ultra ATA Storage Controller + 24d2 82801EB USB + 24d3 82801EB SMBus Controller + 24d4 82801EB USB + 24d5 82801EB AC'97 Audio Controller + 24d6 82801EB AC'97 Modem Controller + 24d7 82801EB USB + 24db 82801EB Ultra ATA Storage Controller + 24dc 82801EB LPC Interface Controller + 24dd 82801EB USB2 + 24de 82801EB USB 2500 82820 820 (Camino) Chipset Host Bridge (MCH) 1028 0095 Precision Workstation 220 Chipset 1043 801c P3C-2000 system chipset @@ -6322,24 +6898,48 @@ 2532 82850 850 (Tehama) Chipset AGP Bridge 2533 82860 860 (Wombat) Chipset AGP Bridge 2534 82860 860 (Wombat) Chipset PCI Bridge - 2540 e7500 [Plumas] DRAM Controller - 2541 e7500 [Plumas] DRAM Controller Error Reporting - 2543 e7500 [Plumas] HI_B Virtual PCI Bridge (F0) - 2544 e7500 [Plumas] HI_B Virtual PCI Bridge (F1) - 2545 e7500 [Plumas] HI_C Virtual PCI Bridge (F0) - 2546 e7500 [Plumas] HI_C Virtual PCI Bridge (F1) - 2547 e7500 [Plumas] HI_D Virtual PCI Bridge (F0) - 2548 e7500 [Plumas] HI_D Virtual PCI Bridge (F1) + 2540 E7500 Memory Controller Hub + 15d9 3480 P4DP6 + 2541 E7000 Series Host RASUM Controller + 15d9 3480 P4DP6 + 2543 E7000 Series Hub Interface B PCI-to-PCI Bridge + 2544 E7000 Series Hub Interface B RASUM Controller + 2545 E7000 Series Hub Interface C PCI-to-PCI Bridge + 2546 E7000 Series Hub Interface C RASUM Controller + 2547 E7000 Series Hub Interface D PCI-to-PCI Bridge + 2548 E7000 Series Hub Interface D RASUM Controller + 254c E7501 Memory Controller Hub + 2550 E7505 Memory Controller Hub + 2551 E7000 Series RAS Controller + 2552 E7000 Series Processor to AGP Controller + 2553 E7000 Series Hub Interface B PCI-to-PCI Bridge + 2554 E7000 Series Hub Interface B PCI-to-PCI Bridge RAS Controller + 255d E7205 Memory Controller Hub 2560 82845G/GL [Brookdale-G] Chipset Host Bridge + 1462 5800 845PE Max (MS-6580) 2561 82845G/GL [Brookdale-G] Chipset AGP Bridge 2562 82845G/GL [Brookdale-G] Chipset Integrated Graphics Device + 2570 82865G/PE/P Processor to I/O Controller + 2571 82865G/PE/P Processor to AGP Controller + 2572 82865G Integrated Graphics Device + 2573 82865G/PE/P Processor to PCI to CSA Bridge + 2576 82864G/PE/P Processor to I/O Memory Interface + 2578 82875P Memory Controller Hub + 2579 82875P Processor to AGP Controller + 257b 82875P Processor to PCI to CSA Bridge + 257e 82875P Processor to I/O Memory Interface 3092 Integrated RAID + 3340 82855PM Processor to I/O Controller + 3341 82855PM Processor to AGP Controller 3575 82830 830 Chipset Host Bridge - 1014 021d ThinkPad T23 (2647-4MG) or A30p (2653-64G) + 1014 021d ThinkPad A/T/X Series 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 3576 82830 830 Chipset AGP Bridge 3577 82830 CGC [Chipset Graphics Controller] + 1014 0513 ThinkPad A/T/X Series 3578 82830 830 Chipset Host Bridge + 3580 82852/855GM Host Bridge + 3582 82852/855GM Integrated Graphics Device 5200 EtherExpress PRO/100 Intelligent Server 5201 EtherExpress PRO/100 Intelligent Server 8086 0001 EtherExpress PRO/100 Server Ethernet Adapter @@ -6355,6 +6955,7 @@ 7113 82371AB/EB/MB PIIX4 ACPI 7120 82810 GMCH [Graphics Memory Controller Hub] 7121 82810 CGC [Chipset Graphics Controller] + 8086 4341 Cayman (CA810) Mainboard 7122 82810 DC-100 GMCH [Graphics Memory Controller Hub] 7123 82810 DC-100 CGC [Chipset Graphics Controller] 7124 82810E DC-133 GMCH [Graphics Memory Controller Hub] @@ -6366,6 +6967,7 @@ 7181 440LX/EX - 82443LX/EX AGP bridge 7190 440BX/ZX/DX - 82443BX/ZX/DX Host bridge 0e11 0500 Armada 1750 Laptop System Chipset + 0e11 b110 Armada M700 1179 0001 Toshiba Tecra 8100 Laptop System Chipset 7191 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge 7192 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) @@ -6484,6 +7086,8 @@ 7478 AHA-2944/2944W / AIC-7874 7578 AHA-3944/3944W / AIC-7875 7678 AHA-4944W/UW / AIC-7876 + 7710 ANA-7711F Network Accelerator Card (NAC) - Optical + 7711 ANA-7711C Network Accelerator Card (NAC) - Copper 7778 AIC-787x 7810 AIC-7810 7815 AIC-7815 RAID+Memory Controller IC @@ -6560,15 +7164,49 @@ 9005 62a1 19160 Ultra160 SCSI Controller 0083 AIC-7892D U160/m 008f AIC-7892P U160/m + 1179 0001 Magnia Z310 + 15d9 9005 Onboard SCSI Host Adapter 00c0 AHA-3960D / AIC-7899A U160/m 0e11 f620 Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter 9005 f620 AHA-3960D U160/m 00c1 AIC-7899B U160/m 00c3 AIC-7899D U160/m 00c5 RAID subsystem HBA + 1028 00c5 PowerEdge 2550 00cf AIC-7899P U160/m + 1028 00d1 PowerEdge 2550 + 10f1 2462 Thunder K7 S2462 + 15d9 9005 Onboard SCSI Host Adapter + 0250 ServeRAID Controller + 1014 0279 ServeRAID-xx + 1014 028c ServeRAID-xx 0285 AAC-RAID 1028 0287 PowerEdge Expandable RAID Controller 320/DC + 8000 ASC-29320A U320 + 800f AIC-7901 U320 + 8010 ASC-39320 U320 + 8011 ASC-32320D U320 + 0e11 00ac U320 + 9005 0041 ASC-39320D U320 + 8012 ASC-29320 U320 + 8013 ASC-29320B U320 + 8014 ASC-29320LP U320 + 801e AIC-7901A U320 + 801f AIC-7902 U320 + 8080 ASC-29320A U320 w/HostRAID + 808f AIC-7901 U320 w/HostRAID + 8090 ASC-39320 U320 w/HostRAID + 8091 ASC-39320D U320 w/HostRAID + 8092 ASC-29320 U320 w/HostRAID + 8093 ASC-29320B U320 w/HostRAID + 8094 ASC-29320LP U320 w/HostRAID + 8095 ASC-39320(B) U320 w/HostRAID + 8096 ASC-39320A U320 w/HostRAID + 8097 ASC-29320ALP U320 w/HostRAID + 809c ASC-39320D(B) U320 w/HostRAID + 809d AIC-7902(B) U320 w/HostRAID + 809e AIC-7901A U320 w/HostRAID + 809f AIC-7902 U320 w/HostRAID 907f Atronics 2015 IDE-2015PL 919a Gigapixel Corp @@ -6589,6 +7227,8 @@ aa42 Scitex Digital Video ac1e Digital Receiver Technology Inc b1b3 Shiva Europe Limited +# Pinnacle should be 11bd, but they got it wrong several times --mj +bd11 Pinnacle Systems, Inc. (Wrong ID) c001 TSI Telsys c0a9 Micron/Crucial Technology c0de Motorola @@ -6596,6 +7236,9 @@ ca50 Varian Australia Pty Ltd cafe Chrysalis-ITS cccc Catapult Communications +cddd Tyzx, Inc. + 0101 DeepSea 1 High Speed Stereo Vision Frame Grabber + 0200 DeepSea 2 High Speed Stereo Vision Frame Grabber d4d4 Dy4 Systems Inc 0601 PCI Mezzanine Card d531 I+ME ACTIA GmbH @@ -6604,12 +7247,17 @@ e000 Winbond e000 W89C940 e159 Tiger Jet Network Inc. - 0001 Model 300 128k + 0001 Intel 537 0059 0001 128k ISDN-S/T Adapter 0059 0003 128k ISDN-U Adapter 0002 Tiger100APC ISDN chipset e4bf EKF Elektronik GmbH ea01 Eagle Technology +# The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID. +ea60 RME + 9896 Digi32 + 9897 Digi32 Pro + 9898 Digi32/8 eabb Aashima Technology B.V. eace Endace Measurement Systems, Ltd 3100 DAG 3.10 OC-3/OC-12 @@ -6625,15 +7273,29 @@ 422e DAG 4.2E Dual Gigabit Ethernet ec80 Belkin Corporation ec00 F5D6000 -ecc0 Echo Corporation +ecc0 Echo Digital Audio Corporation + 0050 Gina24_301 + 0051 Gina24_361 + 0060 Layla24 + 0070 Mona_301_80 + 0071 Mona_301_66 + 0072 Mona_361 + 0080 Mia edd8 ARK Logic Inc a091 1000PV [Stingray] a099 2000PV [Stingray] a0a1 2000MT a0a9 2000MI +f1d0 AJA Video +# All boards I have seen have this ID not efac, though all docs say efac... + cafe KONA SD SMPTE 259M I/O + efac KONA SD SMPTE 259M I/O + facd KONA HD SMPTE 292M I/O fa57 Fast Search & Transfer ASA febd Ultraview Corp. -feda Epigram Inc +feda Broadcom Inc (nee Epigram) + a0fa BCM4210 iLine10 HomePNA 2.0 + a10e BCM4230 iLine10 HomePNA 2.0 fffe VMWare Inc 0710 Virtual SVGA ffff Illegal Vendor ID diff -urN linux-2.4.21/drivers/pcmcia/au1000_db1x00.c linux-2.4.22/drivers/pcmcia/au1000_db1x00.c --- linux-2.4.21/drivers/pcmcia/au1000_db1x00.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/pcmcia/au1000_db1x00.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,269 @@ +/* + * + * Alchemy Semi Db1x00 boards specific pcmcia routines. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "cs_internal.h" + +#include +#include +#include + +#include +#include + +#include + +static BCSR * const bcsr = (BCSR *)0xAE000000; + +static int db1x00_pcmcia_init(struct pcmcia_init *init) +{ + bcsr->pcmcia = 0; /* turn off power */ + au_sync_delay(2); + return PCMCIA_NUM_SOCKS; +} + +static int db1x00_pcmcia_shutdown(void) +{ + bcsr->pcmcia = 0; /* turn off power */ + au_sync_delay(2); + return 0; +} + +static int +db1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) +{ + u32 inserted; + unsigned char vs; + + if(sock > PCMCIA_MAX_SOCK) return -1; + + state->ready = 0; + state->vs_Xv = 0; + state->vs_3v = 0; + state->detect = 0; + + if (sock == 0) { + vs = bcsr->status & 0x3; + inserted = !(bcsr->status & (1<<4)); + } + else { + vs = (bcsr->status & 0xC)>>2; + inserted = !(bcsr->status & (1<<5)); + } + + DEBUG(KERN_DEBUG "db1x00 socket %d: inserted %d, vs %d\n", + sock, inserted, vs); + + if (inserted) { + switch (vs) { + case 0: + case 2: + state->vs_3v=1; + break; + case 3: /* 5V */ + break; + default: + /* return without setting 'detect' */ + printk(KERN_ERR "db1x00 bad VS (%d)\n", + vs); + return -1; + } + state->detect = 1; + state->ready = 1; + } + else { + /* if the card was previously inserted and then ejected, + * we should turn off power to it + */ + if ((sock == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) { + bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST | + BCSR_PCMCIA_PC0DRVEN | + BCSR_PCMCIA_PC0VPP | + BCSR_PCMCIA_PC0VCC); + } + else if ((sock == 1) && (bcsr->pcmcia & BCSR_PCMCIA_PC1RST)) { + bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST | + BCSR_PCMCIA_PC1DRVEN | + BCSR_PCMCIA_PC1VPP | + BCSR_PCMCIA_PC1VCC); + } + } + + state->bvd1=1; + state->bvd2=1; + state->wrprot=0; + return 1; +} + + +static int db1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info) +{ + if(info->sock > PCMCIA_MAX_SOCK) return -1; + + if(info->sock == 0) { + info->irq = AU1000_GPIO_2; + } + else + info->irq = AU1000_GPIO_5; + + return 0; +} + + +static int +db1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) +{ + u16 pwr; + int sock = configure->sock; + + if(sock > PCMCIA_MAX_SOCK) return -1; + + DEBUG(KERN_DEBUG "socket %d Vcc %dV Vpp %dV, reset %d\n", + sock, configure->vcc, configure->vpp, configure->reset); + + /* pcmcia reg was set to zero at init time. Be careful when + * initializing a socket not to wipe out the settings of the + * other socket. + */ + pwr = bcsr->pcmcia; + pwr &= ~(0xf << sock*8); /* clear voltage settings */ + + switch(configure->vcc){ + case 0: /* Vcc 0 */ + pwr |= SET_VCC_VPP(0,0,sock); + break; + case 50: /* Vcc 5V */ + switch(configure->vpp) { + case 0: + pwr |= SET_VCC_VPP(2,0,sock); + break; + case 50: + pwr |= SET_VCC_VPP(2,1,sock); + break; + case 12: + pwr |= SET_VCC_VPP(2,2,sock); + break; + case 33: + default: + pwr |= SET_VCC_VPP(0,0,sock); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + case 33: /* Vcc 3.3V */ + switch(configure->vpp) { + case 0: + pwr |= SET_VCC_VPP(1,0,sock); + break; + case 12: + pwr |= SET_VCC_VPP(1,2,sock); + break; + case 33: + pwr |= SET_VCC_VPP(1,1,sock); + break; + case 50: + default: + pwr |= SET_VCC_VPP(0,0,sock); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + default: /* what's this ? */ + pwr |= SET_VCC_VPP(0,0,sock); + printk(KERN_ERR "%s: bad Vcc %d\n", + __FUNCTION__, configure->vcc); + break; + } + + bcsr->pcmcia = pwr; + au_sync_delay(300); + + if (sock == 0) { + if (!configure->reset) { + pwr |= BCSR_PCMCIA_PC0DRVEN; + bcsr->pcmcia = pwr; + au_sync_delay(300); + pwr |= BCSR_PCMCIA_PC0RST; + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + else { + pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN); + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + } + else { + if (!configure->reset) { + pwr |= BCSR_PCMCIA_PC1DRVEN; + bcsr->pcmcia = pwr; + au_sync_delay(300); + pwr |= BCSR_PCMCIA_PC1RST; + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + else { + pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN); + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + } + return 0; +} + +struct pcmcia_low_level db1x00_pcmcia_ops = { + db1x00_pcmcia_init, + db1x00_pcmcia_shutdown, + db1x00_pcmcia_socket_state, + db1x00_pcmcia_get_irq_info, + db1x00_pcmcia_configure_socket +}; diff -urN linux-2.4.21/drivers/pcmcia/au1000_generic.c linux-2.4.22/drivers/pcmcia/au1000_generic.c --- linux-2.4.21/drivers/pcmcia/au1000_generic.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/pcmcia/au1000_generic.c 2003-08-25 04:44:42.000000000 -0700 @@ -2,7 +2,7 @@ * * Alchemy Semi Au1000 pcmcia driver * - * Copyright 2001 MontaVista Software Inc. + * Copyright 2001-2003 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -132,13 +132,16 @@ #endif }; +static spinlock_t pcmcia_lock = SPIN_LOCK_UNLOCKED; + +extern const unsigned long mips_io_port_base; + static int __init au1000_pcmcia_driver_init(void) { servinfo_t info; struct pcmcia_init pcmcia_init; struct pcmcia_state state; unsigned int i; - unsigned long timing3; printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE); @@ -156,6 +159,10 @@ #if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) pcmcia_low_level=&pb1x00_pcmcia_ops; +#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) + pcmcia_low_level=&db1x00_pcmcia_ops; +#elif defined(CONFIG_MIPS_XXS1500) + pcmcia_low_level=&xxs1500_pcmcia_ops; #else #error Unsupported AU1000 board. #endif @@ -192,18 +199,31 @@ pcmcia_socket[i].k_state=state; pcmcia_socket[i].cs_state.csc_mask=SS_DETECT; + /* + * PCMCIA drivers use the inb/outb macros to access the + * IO registers. Since mips_io_port_base is added to the + * access address, we need to subtract it here. + */ if (i == 0) { pcmcia_socket[i].virt_io = - (u32)ioremap((ioaddr_t)0xF00000000, 0x1000); - pcmcia_socket[i].phys_attr = (memaddr_t)0xF40000000; - pcmcia_socket[i].phys_mem = (memaddr_t)0xF80000000; + (u32)ioremap((ioaddr_t)AU1X_SOCK0_IO, 0x1000) - + mips_io_port_base; + pcmcia_socket[i].phys_attr = + (ioaddr_t)AU1X_SOCK0_PHYS_ATTR; + pcmcia_socket[i].phys_mem = + (ioaddr_t)AU1X_SOCK0_PHYS_MEM; } +#ifndef CONFIG_MIPS_XXS1500 else { pcmcia_socket[i].virt_io = - (u32)ioremap((ioaddr_t)0xF08000000, 0x1000); - pcmcia_socket[i].phys_attr = (memaddr_t)0xF48000000; - pcmcia_socket[i].phys_mem = (memaddr_t)0xF88000000; + (u32)ioremap((ioaddr_t)AU1X_SOCK1_IO, 0x1000) - + mips_io_port_base; + pcmcia_socket[i].phys_attr = + (ioaddr_t)AU1X_SOCK1_PHYS_ATTR; + pcmcia_socket[i].phys_mem = + (ioaddr_t)AU1X_SOCK1_PHYS_MEM; } +#endif } /* Only advertise as many sockets as we can detect: */ @@ -234,7 +254,8 @@ flush_scheduled_tasks(); for(i=0; i < socket_count; i++) { if (pcmcia_socket[i].virt_io) - iounmap((void *)pcmcia_socket[i].virt_io); + iounmap((void *)pcmcia_socket[i].virt_io + + mips_io_port_base); } DEBUG(1, "au1000: shutdown complete\n"); } @@ -585,8 +606,7 @@ } } - save_flags(flags); - cli(); + spin_lock_irqsave(&pcmcia_lock, flags); start=map->sys_start; if(map->sys_stop==0) @@ -603,7 +623,7 @@ map->sys_stop=map->sys_start+(map->sys_stop-start); pcmcia_socket[sock].mem_map[map->map]=*map; - restore_flags(flags); + spin_unlock_irqrestore(&pcmcia_lock, flags); DEBUG(3, "set_mem_map %d start %x stop %x card_start %x\n", map->map, map->sys_start, map->sys_stop, map->card_start); diff -urN linux-2.4.21/drivers/pcmcia/au1000_pb1x00.c linux-2.4.22/drivers/pcmcia/au1000_pb1x00.c --- linux-2.4.21/drivers/pcmcia/au1000_pb1x00.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/pcmcia/au1000_pb1x00.c 2003-08-25 04:44:42.000000000 -0700 @@ -54,7 +54,7 @@ #define PCMCIA_IRQ AU1000_GPIO_15 #elif defined (CONFIG_MIPS_PB1500) #include -#define PCMCIA_IRQ AU1000_GPIO_11 /* fixme */ +#define PCMCIA_IRQ AU1500_GPIO_203 #elif defined (CONFIG_MIPS_PB1100) #include #define PCMCIA_IRQ AU1000_GPIO_11 @@ -81,9 +81,9 @@ #else /* fixme -- take care of the Pb1500 at some point */ u16 pcr; - pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */ - pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */ + pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(500); return PCMCIA_NUM_SOCKS; #endif @@ -101,9 +101,9 @@ return 0; #else u16 pcr; - pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */ - pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */ + pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(2); return 0; #endif @@ -122,9 +122,14 @@ vs0 = (vs0 >> 4) & 0x3; vs1 = (vs1 >> 12) & 0x3; #else - vs0 = (au_readw(PB1100_BOARD_STATUS) >> 4) & 0x3; + vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3; +#ifdef CONFIG_MIPS_PB1500 + inserted0 = !((au_readl(GPIO2_PIN_STATE) >> 1) & 0x1); /* gpio 201 */ +#else /* Pb1100 */ inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */ #endif + inserted1 = 0; +#endif state->ready = 0; state->vs_Xv = 0; @@ -144,7 +149,7 @@ /* return without setting 'detect' */ printk(KERN_ERR "pb1x00 bad VS (%d)\n", vs0); - return; + return 0; } state->detect = 1; } @@ -162,7 +167,7 @@ /* return without setting 'detect' */ printk(KERN_ERR "pb1x00 bad VS (%d)\n", vs1); - return; + return 0; } state->detect = 1; } @@ -323,7 +328,7 @@ #else - pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; + pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x, reset %d\n", configure->vcc, configure->vpp, pcr, configure->reset); @@ -382,26 +387,27 @@ break; } - au_writew(pcr, PB1100_MEM_PCMCIA); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(300); if (!configure->reset) { - pcr |= PB1100_PC_DRV_EN; - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr |= PC_DRV_EN; + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(100); - pcr |= PB1100_PC_DEASSERT_RST; - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr |= PC_DEASSERT_RST; + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(100); } else { - pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(100); } #endif return 0; } + struct pcmcia_low_level pb1x00_pcmcia_ops = { pb1x00_pcmcia_init, pb1x00_pcmcia_shutdown, diff -urN linux-2.4.21/drivers/pcmcia/au1000_xxs1500.c linux-2.4.22/drivers/pcmcia/au1000_xxs1500.c --- linux-2.4.21/drivers/pcmcia/au1000_xxs1500.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/pcmcia/au1000_xxs1500.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,191 @@ +/* + * + * MyCable board specific pcmcia routines. + * + * Copyright 2003 MontaVista Software Inc. + * Author: Pete Popov, MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute 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 it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "cs_internal.h" + +#include +#include +#include + +#include +#include +#include + +#if 0 +#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) +#else +#define DEBUG(x,args...) +#endif + +static int xxs1500_pcmcia_init(struct pcmcia_init *init) +{ + return PCMCIA_NUM_SOCKS; +} + +static int xxs1500_pcmcia_shutdown(void) +{ + /* turn off power */ + au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30), + GPIO2_OUTPUT); + au_sync_delay(100); + + /* assert reset */ + au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20), + GPIO2_OUTPUT); + au_sync_delay(100); + return 0; +} + + +static int +xxs1500_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) +{ + u32 inserted; u32 vs; + unsigned long gpio, gpio2; + + if(sock > PCMCIA_MAX_SOCK) return -1; + + gpio = au_readl(SYS_PINSTATERD); + gpio2 = au_readl(GPIO2_PINSTATE); + + vs = gpio2 & ((1<<8) | (1<<9)); + inserted = (!(gpio & 0x1) && !(gpio & 0x2)); + + state->ready = 0; + state->vs_Xv = 0; + state->vs_3v = 0; + state->detect = 0; + + if (inserted) { + switch (vs) { + case 0: + case 1: + case 2: + state->vs_3v=1; + break; + case 3: /* 5V */ + default: + /* return without setting 'detect' */ + printk(KERN_ERR "au1x00_cs: unsupported VS\n", + vs); + return; + } + state->detect = 1; + } + + if (state->detect) { + state->ready = 1; + } + + state->bvd1= gpio2 & (1<<10); + state->bvd2 = gpio2 & (1<<11); + state->wrprot=0; + return 1; +} + + +static int xxs1500_pcmcia_get_irq_info(struct pcmcia_irq_info *info) +{ + + if(info->sock > PCMCIA_MAX_SOCK) return -1; + info->irq = PCMCIA_IRQ; + return 0; +} + + +static int +xxs1500_pcmcia_configure_socket(const struct pcmcia_configure *configure) +{ + + if(configure->sock > PCMCIA_MAX_SOCK) return -1; + + DEBUG("Vcc %dV Vpp %dV, reset %d\n", + configure->vcc, configure->vpp, configure->reset); + + switch(configure->vcc){ + case 33: /* Vcc 3.3V */ + /* turn on power */ + DEBUG("turn on power\n"); + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), + GPIO2_OUTPUT); + au_sync_delay(100); + break; + case 50: /* Vcc 5V */ + default: /* what's this ? */ + printk(KERN_ERR "au1x00_cs: unsupported VCC\n"); + case 0: /* Vcc 0 */ + /* turn off power */ + au_sync_delay(100); + au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30), + GPIO2_OUTPUT); + break; + } + + if (!configure->reset) { + DEBUG("deassert reset\n"); + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<4))|(1<<20), + GPIO2_OUTPUT); + au_sync_delay(100); + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<5))|(1<<21), + GPIO2_OUTPUT); + } + else { + DEBUG("assert reset\n"); + au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20), + GPIO2_OUTPUT); + } + au_sync_delay(100); + return 0; +} + +struct pcmcia_low_level xxs1500_pcmcia_ops = { + xxs1500_pcmcia_init, + xxs1500_pcmcia_shutdown, + xxs1500_pcmcia_socket_state, + xxs1500_pcmcia_get_irq_info, + xxs1500_pcmcia_configure_socket +}; diff -urN linux-2.4.21/drivers/pcmcia/i82092.c linux-2.4.22/drivers/pcmcia/i82092.c --- linux-2.4.21/drivers/pcmcia/i82092.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/pcmcia/i82092.c 2003-08-25 04:44:42.000000000 -0700 @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -24,6 +26,7 @@ #include "i82092aa.h" #include "i82365.h" +#include "cirrus.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("Red Hat, Inc. - Arjan Van De Ven "); @@ -41,8 +44,15 @@ subdevice:PCI_ANY_ID, class: 0, class_mask:0, - }, - {} + }, + { + vendor:PCI_VENDOR_ID_CIRRUS, + device:PCI_DEVICE_ID_CIRRUS_6729, + subvendor:PCI_ANY_ID, + subdevice:PCI_ANY_ID, + class: 0, class_mask:0, + }, + {} }; static struct pci_driver i82092aa_pci_drv = { @@ -88,14 +98,18 @@ void *info; /* to be passed to the handler */ struct pci_dev *dev; /* The PCI device for the socket */ + + int type; /* Type of socket */ +#define IS_I82092 0x0001 +#define IS_PD6729 0x0002 }; #define MAX_SOCKETS 4 static struct socket_info sockets[MAX_SOCKETS]; static int socket_count; /* shortcut */ -int membase = -1; -int isa_setup; +static int membase = -1; +static int isa_setup; MODULE_PARM(membase, "i"); MODULE_PARM(isa_setup, "i"); @@ -105,6 +119,7 @@ unsigned char configbyte; struct pci_dev *parent; int i; + int type; enter("i82092aa_pci_probe"); @@ -114,7 +129,18 @@ /* Since we have no memory BARs some firmware we may not have had PCI_COMMAND_MEM enabled, yet the device needs it. */ - pci_read_config_byte(dev, PCI_COMMAND, &configbyte); + + // pci_read_config_byte(dev, PCI_COMMAND, &configbyte); + if (dev->vendor == PCI_VENDOR_ID_CIRRUS) { + type = IS_PD6729; + configbyte = 0; /* always 2 sockets */ + printk(KERN_INFO "Cirrus PD6729 PCI to PCMCIA Bridge \n"); + } else { + type = IS_I82092; + pci_read_config_byte(dev, 0x40, &configbyte); /* PCI Configuration Control */ + printk(KERN_INFO "Intel I82092AA PCI to PCMCIA Bridge \n"); + } + if (!(configbyte | PCI_COMMAND_MEMORY)) { dprintk(KERN_DEBUG "Enabling PCI_COMMAND_MEMORY\n"); configbyte |= PCI_COMMAND_MEMORY; @@ -201,6 +227,7 @@ sockets[i].cap.map_size = 0x1000; sockets[i].cap.irq_mask = 0; sockets[i].cap.pci_irq = dev->irq; + sockets[i].type = type; /* Trick the resource code into doing the right thing... */ sockets[i].cap.cb_dev = dev; @@ -213,10 +240,11 @@ } } - /* Now, specifiy that all interrupts are to be done as PCI interrupts */ - configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */ - pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */ - + if (type == IS_I82092) { + /* Now, specifiy that all interrupts are to be done as PCI interrupts */ + configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */ + pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */ + } /* Register the interrupt handler */ dprintk(KERN_DEBUG "Requesting interrupt %i \n",dev->irq); @@ -238,6 +266,7 @@ enter("i82092aa_pci_remove"); free_irq(dev->irq, i82092aa_interrupt); + flush_scheduled_tasks(); leave("i82092aa_pci_remove"); } @@ -652,6 +681,7 @@ static int i82092aa_set_socket(unsigned int sock, socket_state_t *state) { unsigned char reg; + unsigned long flags; enter("i82092aa_set_socket"); @@ -738,9 +768,26 @@ /* now write the value and clear the (probably bogus) pending stuff by doing a dummy read*/ + spin_lock_irqsave(&port_lock,flags); + indirect_write(sock,I365_CSCINT,reg); (void)indirect_read(sock,I365_CSC); + if (sockets[sock].type == IS_PD6729) { + /* Configure PD6729 bridge for PCI interrupts */ + reg |= 0x30; /* management IRQ: PCI INTA = "irq 3" */ + indirect_write(sock,I365_CSCINT,reg); + (void)indirect_read(sock,I365_CSC); + + reg = indirect_read(sock,I365_INTCTL); + reg |= 0x03; /* card IRQ: PCI INTA = "irq 3" */ + indirect_write(sock,I365_INTCTL,reg); + + indirect_write(sock, PD67_EXT_INDEX, PD67_EXT_CTL_1); + indirect_write(sock, PD67_EXT_DATA, PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ); + } + spin_unlock_irqrestore(&port_lock,flags); + leave("i82092aa_set_socket"); return 0; } @@ -766,9 +813,10 @@ io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0; /* check this out later */ io->flags = 0; - if (addr & I365_IOCTL_16BIT(map)) - io->flags |= MAP_AUTOSZ; - + io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0; + io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0; + io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0; + leave("i82092aa_get_io_map"); return 0; } @@ -786,7 +834,7 @@ leave("i82092aa_set_io_map with invalid map"); return -EINVAL; } - if ((io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)){ + if (io->start > 0xffff || io->stop > 0xffff || io->stop < io->start){ leave("i82092aa_set_io_map with invalid io"); return -EINVAL; } @@ -803,9 +851,10 @@ ioctl = indirect_read(sock,I365_IOCTL) & ~I365_IOCTL_MASK(map); - if (io->flags & (MAP_16BIT|MAP_AUTOSZ)) - ioctl |= I365_IOCTL_16BIT(map); - + if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); + if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); + if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); + indirect_write(sock,I365_IOCTL,ioctl); /* Turn the window back on if needed */ @@ -864,11 +913,19 @@ mem->flags |= MAP_WRPROT; if (i & I365_MEM_REG) mem->flags |= MAP_ATTRIB; - mem->card_start = ( (unsigned long)(i & 0x3fff)<12) + mem->sys_start; - mem->card_start &= 0x3ffffff; + if (sockets[sock].type == IS_PD6729) { + /* Take care of high byte */ + indirect_write(sock,PD67_EXT_INDEX, PD67_MEM_PAGE(map)); + addr = indirect_read16(sock, PD67_EXT_DATA) << 24; + mem->sys_stop += addr; mem->sys_start += addr; + mem->card_start = (unsigned long)(i) + mem->sys_start; + } else { + mem->card_start = ((unsigned long)(i & 0x3fff)<12) + mem->sys_start; + mem->card_start &= 0x3ffffff; + } + dprintk("Card %i is from %lx to %lx \n",sock,mem->sys_start,mem->sys_stop); - leave("i82092aa_get_mem_map"); return 0; @@ -895,7 +952,9 @@ if (!(mem->flags & MAP_ACTIVE)) return 0; - if ( (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) || + if (sockets[sock].type == IS_PD6729) { + ; /* PD6729 accepts high byte */ + } else if ( (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) || ((mem->sys_start >> 24) != membase) || ((mem->sys_stop >> 24) != membase) || (mem->speed > 1000) ) { leave("i82092aa_set_mem_map: invalid address / speed"); @@ -904,7 +963,6 @@ } - /* printk("set_mem_map: Setting map %i range to %x - %x on socket %i, speed is %i, active = %i \n",map, mem->sys_start,mem->sys_stop,sock,mem->speed,mem->flags & MAP_ACTIVE); */ /* write the start address */ @@ -935,6 +993,12 @@ indirect_write16(sock,base+I365_W_STOP,i); + if (sockets[sock].type == IS_PD6729) { + /* Take care of high byte */ + indirect_write(sock, PD67_EXT_INDEX, PD67_MEM_PAGE(map)); + indirect_write16(sock, PD67_EXT_DATA, mem->sys_start >> 24); + } + /* card start */ i = (((mem->card_start - mem->sys_start) >> 12) - (membase << 12)) & 0x3fff; @@ -947,7 +1011,9 @@ /* printk("requesting normal memory for socket %i\n",sock);*/ } indirect_write16(sock,base+I365_W_OFF,i); - indirect_write(sock, I365_CPAGE, membase); + if (sockets[sock].type == IS_I82092) { + indirect_write(sock, I365_CPAGE, membase); + } /* Enable the window if necessary */ indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map)); diff -urN linux-2.4.21/drivers/pcmcia/rsrc_mgr.c linux-2.4.22/drivers/pcmcia/rsrc_mgr.c --- linux-2.4.21/drivers/pcmcia/rsrc_mgr.c 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.22/drivers/pcmcia/rsrc_mgr.c 2003-08-25 04:44:42.000000000 -0700 @@ -419,14 +419,17 @@ void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), int force_low, socket_info_t *s) { - resource_map_t *m; + resource_map_t *m, *n; static int done = 0; if (!probe_mem || done++) return; - for (m = mem_db.next; m != &mem_db; m = m->next) + + for (m = mem_db.next; m != &mem_db; m = n) { + n = m->next; if (do_mem_probe(m->base, m->num, is_valid, do_cksum, s)) return; + } } #endif /* CONFIG_ISA */ diff -urN linux-2.4.21/drivers/pcmcia/ti113x.h linux-2.4.22/drivers/pcmcia/ti113x.h --- linux-2.4.21/drivers/pcmcia/ti113x.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/pcmcia/ti113x.h 2003-08-25 04:44:42.000000000 -0700 @@ -167,6 +167,32 @@ new |= I365_INTR_ENA; if (new != reg) exca_writeb(socket, I365_INTCTL, new); + + /* + * If ISA interrupts don't work, then fall back to routing card + * interrupts to the PCI interrupt of the socket. + * + * Tweaking this when we are using serial PCI IRQs causes hangs + * --rmk + */ + if (!socket->cap.irq_mask) { + u8 irqmux, devctl; + + devctl = config_readb(socket, TI113X_DEVICE_CONTROL); + if ((devctl & TI113X_DCR_IMODE_MASK) != TI12XX_DCR_IMODE_ALL_SERIAL) { + printk (KERN_INFO "ti113x: Routing card interrupts to PCI\n"); + + devctl &= ~TI113X_DCR_IMODE_MASK; + + irqmux = config_readl(socket, TI122X_IRQMUX); + irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */ + irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */ + + config_writel(socket, TI122X_IRQMUX, irqmux); + config_writeb(socket, TI113X_DEVICE_CONTROL, devctl); + } + } + return 0; } diff -urN linux-2.4.21/drivers/s390/Config.in linux-2.4.22/drivers/s390/Config.in --- linux-2.4.21/drivers/s390/Config.in 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/s390/Config.in 2003-08-25 04:44:42.000000000 -0700 @@ -80,6 +80,7 @@ tristate 'Universal TUN/TAP device driver support' CONFIG_TUN bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET bool 'Token Ring driver support' CONFIG_TR + dep_tristate 'Cisco 7000 support' CONFIG_C7000 m bool 'FDDI driver support' CONFIG_FDDI comment 'S/390 network device drivers' bool 'Channel Device Configuration' CONFIG_CHANDEV diff -urN linux-2.4.21/drivers/s390/block/dasd.c linux-2.4.22/drivers/s390/block/dasd.c --- linux-2.4.21/drivers/s390/block/dasd.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd.c 2003-08-25 04:44:42.000000000 -0700 @@ -6,6 +6,8 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * + * $Revision: 1.289 $ + * * History of changes (starts July 2000) * 11/09/00 complete redesign after code review * 02/01/01 added dynamic registration of ioctls @@ -33,6 +35,7 @@ * 06/26/01 hopefully fixed PL030172SBA,PL030234SBA * 07/09/01 fixed PL030324MSH (wrong statistics output) * 07/16/01 merged in new fixes for handling low-mem situations + * 01/22/01 fixed PL030579KBE (wrong statistics) */ #include @@ -70,7 +73,6 @@ #include #include #include -#include #include "dasd_int.h" @@ -84,8 +86,9 @@ #include "dasd_diag.h" #endif /* CONFIG_DASD_DIAG */ -/* SECTION: exported variables of dasd.c */ - +/******************************************************************************** + * SECTION: exported variables of dasd.c + ********************************************************************************/ debug_info_t *dasd_debug_area; MODULE_AUTHOR ("Holger Smolinski "); @@ -94,6 +97,9 @@ MODULE_SUPPORTED_DEVICE ("dasd"); MODULE_PARM (dasd, "1-" __MODULE_STRING (256) "s"); MODULE_PARM (dasd_disciplines, "1-" __MODULE_STRING (8) "s"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)) +MODULE_LICENSE ("GPL"); +#endif EXPORT_SYMBOL (dasd_chanq_enq_head); EXPORT_SYMBOL (dasd_debug_area); EXPORT_SYMBOL (dasd_chanq_enq); @@ -103,6 +109,7 @@ EXPORT_SYMBOL (dasd_start_IO); EXPORT_SYMBOL (dasd_term_IO); EXPORT_SYMBOL (dasd_schedule_bh); +EXPORT_SYMBOL (dasd_schedule_bh_timed); EXPORT_SYMBOL (dasd_int_handler); EXPORT_SYMBOL (dasd_oper_handler); EXPORT_SYMBOL (dasd_alloc_request); @@ -115,17 +122,24 @@ EXPORT_SYMBOL (dasd_set_normalized_cda); EXPORT_SYMBOL (dasd_device_from_kdev); -/* SECTION: Constant definitions to be used within this file */ + +/******************************************************************************** + * SECTION: Constant definitions to be used within this file + ********************************************************************************/ #define PRINTK_HEADER DASD_NAME":" -#undef DASD_PROFILE /* fill profile information - used for */ +#define DASD_PROFILE /* fill profile information - used for */ /* statistics and perfomance */ -#define DASD_MIN_SIZE_FOR_QUEUE 32 -#undef CONFIG_DYNAMIC_QUEUE_MIN_SIZE -#define DASD_CHANQ_MAX_SIZE 6 - -/* SECTION: prototypes for static functions of dasd.c */ +#ifndef CONFIG_PROC_FS /* DASD_PROFILE doesn't make sense */ +#undef DASD_PROFILE /* without procfs */ +#endif /* not CONFIG_PROC_FS */ + +#define DASD_CHANQ_MAX_SIZE 4 + +/******************************************************************************** + * SECTION: prototypes for static functions of dasd.c + ********************************************************************************/ static request_fn_proc do_dasd_request; static int dasd_set_device_level (unsigned int, dasd_discipline_t *, int); @@ -147,7 +161,11 @@ static struct block_device_operations dasd_device_operations; static inline dasd_device_t ** dasd_device_from_devno (int); static void dasd_process_queues (dasd_device_t * device); -/* SECTION: static variables of dasd.c */ +static int dasd_sleep_on_immediate (ccw_req_t *cqr); + +/******************************************************************************** + * SECTION: static variables of dasd.c + ********************************************************************************/ static devfs_handle_t dasd_devfs_handle; static wait_queue_head_t dasd_init_waitq; @@ -155,7 +173,9 @@ #ifdef CONFIG_DASD_DYNAMIC -/* SECTION: managing dynamic configuration of dasd_driver */ +/******************************************************************************** + * SECTION: managing dynamic configuration of dasd_driver + ********************************************************************************/ static struct list_head dasd_devreg_head = LIST_HEAD_INIT (dasd_devreg_head); @@ -188,15 +208,17 @@ #endif /* CONFIG_DASD_DYNAMIC */ -/* SECTION: managing setup of dasd_driver */ +/******************************************************************************** + * SECTION: managing setup of dasd_driver + ********************************************************************************/ /* default setting is probeonly, autodetect */ -static int dasd_probeonly = 1; /* is true, when probeonly mode is active */ -static int dasd_autodetect = 1; /* is true, when autodetection is active */ +static int dasd_probeonly = 0; /* is true, when probeonly mode is active */ +static int dasd_autodetect = 0; /* is true, when autodetection is active */ static dasd_range_t dasd_range_head = { list:LIST_HEAD_INIT (dasd_range_head.list) }; -static spinlock_t range_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t range_lock = SPIN_LOCK_UNLOCKED; /* * function: dasd_create_range @@ -210,20 +232,24 @@ int i; if ( from > to ) { - printk (KERN_WARNING PRINTK_HEADER - "Adding device range %04x-%04x: range invalid, ignoring.\n", - from, - to); + + MESSAGE (KERN_WARNING, + "Adding device range %04x-%04x: " + "range invalid, ignoring.", + from, + to); return NULL; } for (i=from;i<=to;i++) { if (dasd_device_from_devno(i)) { - printk (KERN_WARNING PRINTK_HEADER - "device range %04x-%04x: device %04x is already in a range.\n", - from, - to, - i); + + MESSAGE (KERN_WARNING, + "device range %04x-%04x: device " + "%04x is already in a range.", + from, + to, + i); } } range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL); @@ -392,7 +418,9 @@ return -ENODEV; } -/* SECTION: parsing the dasd= parameter of the parmline/insmod cmdline */ +/******************************************************************************** + * SECTION: parsing the dasd= parameter of the parmline/insmod cmdline + ********************************************************************************/ /* * char *dasd[] is intended to hold the ranges supplied by the dasd= statement @@ -426,11 +454,14 @@ *end = '\0'; end++; } - dasd[count] = kmalloc (len * sizeof (char), GFP_ATOMIC); + dasd[count] = kmalloc (len * sizeof (char), + GFP_ATOMIC); if (dasd[count] == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "can't store dasd= parameter no %d\n", - count + 1); + + MESSAGE (KERN_WARNING, + "can't store dasd= parameter no" + " %d", + count + 1); break; } memset (dasd[count], 0, len * sizeof (char)); @@ -500,10 +531,13 @@ int val,i,start; buffer=(char*)kmalloc((strlen(str)+1)*sizeof(char),GFP_ATOMIC); + if (buffer==NULL) { - printk (KERN_WARNING PRINTK_HEADER - "can't parse dasd= parameter %s due to low memory\n", - str); + + MESSAGE (KERN_WARNING, + "can't parse dasd= parameter %s due " + "to low memory", + str); } /* remove leading '0x' */ @@ -528,7 +562,7 @@ val = simple_strtoul (buffer, &buffer, 16); /* check for features - e.g. (ro) ; the '\0', ')' and '-' stops check */ - *features = DASD_DEFAULT_FEATURES; + *features = DASD_FEATURE_DEFAULT; if (temp[i]=='(') { @@ -545,14 +579,18 @@ (*features) |= DASD_FEATURE_READONLY; break; } - printk (KERN_WARNING PRINTK_HEADER - "unsupported feature: %s, ignoring setting", - buffer); + + MESSAGE (KERN_WARNING, + "unsupported feature: %s, " + "ignoring setting", + buffer); } } } *stra = temp+i; + if ((val > 65535) || (val < 0)) + return -EINVAL; return val; } @@ -569,22 +607,23 @@ int features; int rc = 0; - if (*str) { - /* turn off probeonly mode, if any dasd parameter is present */ - dasd_probeonly = 0; - dasd_autodetect = 0; - } while (*str) { temp = *str; from = 0; to = 0; if (strcmp ("autodetect", *str) == 0) { dasd_autodetect = 1; - printk (KERN_INFO "turning to autodetection mode\n"); + + MESSAGE (KERN_INFO, "%s", + "turning to autodetection mode"); + break; } else if (strcmp ("probeonly", *str) == 0) { dasd_probeonly = 1; - printk (KERN_INFO "turning to probeonly mode\n"); + + MESSAGE (KERN_INFO, "%s", + "turning to probeonly mode"); + break; } else { /* turn off autodetect mode, if any range is present */ @@ -609,20 +648,16 @@ return rc; } -/* SECTION: Dealing with devices registered to multiple major numbers */ +/******************************************************************************** + * SECTION: Dealing with devices registered to multiple major numbers + ********************************************************************************/ static spinlock_t dasd_major_lock = SPIN_LOCK_UNLOCKED; -static major_info_t dasd_major_info[] = { - { - list:LIST_HEAD_INIT (dasd_major_info[1].list) - }, - { - list:LIST_HEAD_INIT (dasd_major_info[0].list), - gendisk:{ - INIT_GENDISK (94, DASD_NAME, DASD_PARTN_BITS, DASD_PER_MAJOR) - }, - flags:DASD_MAJOR_INFO_IS_STATIC} +static struct list_head dasd_major_info = LIST_HEAD_INIT(dasd_major_info); +static major_info_t dasd_major_static = { + gendisk:{INIT_GENDISK(94, DASD_NAME, DASD_PARTN_BITS, DASD_PER_MAJOR)}, + flags: DASD_MAJOR_INFO_IS_STATIC }; static major_info_t * @@ -658,8 +693,11 @@ if (major_info == NULL) { major_info = get_new_major_info (); if (!major_info) { - printk (KERN_WARNING PRINTK_HEADER - "Cannot get memory to allocate another major number\n"); + + MESSAGE (KERN_WARNING, "%s", + "Cannot get memory to allocate another " + "major number"); + return -ENOMEM; } } @@ -686,10 +724,12 @@ /* register blockdevice */ rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations); if (rc < 0) { - printk (KERN_WARNING PRINTK_HEADER - "Cannot register to major no %d, rc = %d\n", - major, - rc); + + MESSAGE (KERN_WARNING, + "Cannot register to major no %d, rc = %d", + major, + rc); + goto out_reg_blkdev; } else { major_info->flags |= DASD_MAJOR_INFO_REGISTERED; @@ -698,7 +738,7 @@ /* Insert the new major info into dasd_major_info if needed (dynamic major) */ if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) { spin_lock_irqsave (&dasd_major_lock, flags); - list_add_tail (&major_info->list, &dasd_major_info[0].list); + list_add_tail (&major_info->list, &dasd_major_info); spin_unlock_irqrestore (&dasd_major_lock, flags); } @@ -791,10 +831,11 @@ /* unregister blockdevice */ rc = devfs_unregister_blkdev (major, DASD_NAME); if (rc < 0) { - printk (KERN_WARNING PRINTK_HEADER - "Unable to unregister from major no %d, rc = %d\n", - major, - rc); + + MESSAGE (KERN_WARNING, + "Unable to unregister from major no %d, rc = %d", + major, + rc); } else { major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED; } @@ -844,10 +885,12 @@ rc = devfs_unregister_blkdev (major, DASD_NAME); if (rc < 0) { - printk (KERN_WARNING PRINTK_HEADER - "Cannot unregister from major no %d, rc = %d\n", - major, - rc); + + MESSAGE (KERN_WARNING, + "Cannot unregister from major no %d, rc = %d", + major, + rc); + return rc; } else { major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED; @@ -874,20 +917,23 @@ dasd_device_t * dasd_device_from_kdev (kdev_t kdev) { - major_info_t *major_info = NULL; + major_info_t *major_info; + dasd_device_t *device; struct list_head *l; unsigned long flags; + device = NULL; spin_lock_irqsave (&dasd_major_lock, flags); - list_for_each (l, &dasd_major_info[0].list) { + list_for_each (l, &dasd_major_info) { major_info = list_entry (l, major_info_t, list); - if (major_info->gendisk.major == MAJOR (kdev)) + if (major_info->gendisk.major == MAJOR (kdev)) { + device = major_info->dasd_device[MINOR (kdev) >> + DASD_PARTN_BITS]; break; + } } spin_unlock_irqrestore (&dasd_major_lock, flags); - if (major_info != &dasd_major_info[0]) - return major_info->dasd_device[MINOR (kdev) >> DASD_PARTN_BITS]; - return NULL; + return device; } /* @@ -900,21 +946,29 @@ dasd_device_from_devno (int devno) { major_info_t *major_info; + dasd_device_t **device; struct list_head *l; - int devindex = dasd_devindex_from_devno (devno); + int devindex; unsigned long flags; spin_lock_irqsave (&dasd_major_lock, flags); - list_for_each (l, &dasd_major_info[0].list) { + devindex = dasd_devindex_from_devno (devno); + if (devindex < 0) { + spin_unlock_irqrestore (&dasd_major_lock, flags); + return NULL; + } + + device = NULL; + list_for_each (l, &dasd_major_info) { major_info = list_entry (l, major_info_t, list); if (devindex < DASD_PER_MAJOR) { - spin_unlock_irqrestore (&dasd_major_lock, flags); - return &major_info->dasd_device[devindex]; + device = &major_info->dasd_device[devindex]; + break; } devindex -= DASD_PER_MAJOR; } spin_unlock_irqrestore (&dasd_major_lock, flags); - return NULL; + return device; } /* @@ -945,9 +999,33 @@ return -ENODEV; } +/* + * function: dasd_check_bp_block + * checks the blocksize and returns 0 if valid. + */ + +static int +dasd_check_bp_block (dasd_device_t *device) +{ + int rc; + switch (device->sizes.bp_block) { + case 512: + case 1024: + case 2048: + case 4096: + rc = 0; + break; + default: + rc = -EMEDIUMTYPE; + } + + return rc; +} -/* SECTION: managing dasd disciplines */ +/******************************************************************************** + * SECTION: managing dasd disciplines + ********************************************************************************/ /* anchor and spinlock for list of disciplines */ static struct list_head dasd_disc_head = LIST_HEAD_INIT(dasd_disc_head); @@ -955,14 +1033,18 @@ /* * function dasd_discipline_enq - * chains the discpline given as argument to the head of disiplines - * head chaining policy is required to allow module disciplines to - * be preferred against those, who are statically linked + * chains the discpline given as argument to the tail of disiplines. + * Exception: DIAG is always queued to the head, to ensure that CMS RESERVED + * minidisks are invariably accessed using DIAG. */ static inline void -dasd_discipline_enq (dasd_discipline_t * d) +dasd_discipline_enq (dasd_discipline_t *discipline) { - list_add(&d->list, &dasd_disc_head); + if (strncmp (discipline->name, "DIAG", 4) == 0) { + list_add (&discipline->list, &dasd_disc_head); + } else { + list_add_tail (&discipline->list, &dasd_disc_head); + } } /* @@ -970,59 +1052,88 @@ * removes the discipline given as argument from the list of disciplines */ static inline void -dasd_discipline_deq (dasd_discipline_t * d) +dasd_discipline_deq (dasd_discipline_t * discipline) { - list_del(&d->list); + if (&discipline->list) { + list_del (&discipline->list); + } } void -dasd_discipline_add (dasd_discipline_t * d) +dasd_discipline_add (dasd_discipline_t * discipline) { unsigned long flags; MOD_INC_USE_COUNT; spin_lock_irqsave (&discipline_lock,flags); - dasd_discipline_enq (d); + dasd_discipline_enq (discipline); spin_unlock_irqrestore (&discipline_lock,flags); - dasd_enable_ranges (&dasd_range_head, d, DASD_STATE_ONLINE); + + dasd_enable_ranges (&dasd_range_head, + discipline, + DASD_STATE_ONLINE); } -void dasd_discipline_del (dasd_discipline_t * d) +void dasd_discipline_del (dasd_discipline_t * discipline) { unsigned long flags; + + dasd_disable_ranges(&dasd_range_head, + discipline, + DASD_STATE_DEL, + 1); + spin_lock_irqsave (&discipline_lock,flags); - dasd_disable_ranges(&dasd_range_head, d, DASD_STATE_DEL, 1); - dasd_discipline_deq (d); + dasd_discipline_deq (discipline); spin_unlock_irqrestore (&discipline_lock,flags); MOD_DEC_USE_COUNT; } +/* + * function dasd_find_disc + * checks the list of disciplines for the first one able to access the device + */ static inline dasd_discipline_t * -dasd_find_disc (dasd_device_t * device, dasd_discipline_t *d) +dasd_find_disc (dasd_device_t * device, dasd_discipline_t *discipline) { dasd_discipline_t *t; - struct list_head *l = d ? &d->list : dasd_disc_head.next; + struct list_head *l = discipline ? + &discipline->list : dasd_disc_head.next; + do { t = list_entry(l,dasd_discipline_t,list); + if ( ( t->id_check == NULL || t->id_check (&device->devinfo) == 0 ) && ( t->check_characteristics == NULL || t->check_characteristics (device) == 0 ) ) break; l = l->next; - if ( d || + if ( discipline || l == &dasd_disc_head ) { t = NULL; break; } } while ( 1 ); + return t; } -/* SECTION: profiling stuff */ +/******************************************************************************** + * SECTION: profiling stuff + ********************************************************************************/ + +#ifdef CONFIG_PROC_FS static dasd_profile_info_t dasd_global_profile; +#endif /* CONFIG_PROC_FS */ #ifdef DASD_PROFILE + +#define DASD_PROFILE_ON 1 +#define DASD_PROFILE_OFF 0 + +static unsigned int dasd_profile_level = DASD_PROFILE_OFF; + /* * macro: dasd_profile_add_counter * increments counter in global and local profiling structures @@ -1032,7 +1143,7 @@ { \ int ind; \ long help; \ - for (ind = 0, help = value >> 3; \ + for (ind = 0, help = value >> 2; \ ind < 31 && help; \ help = help >> 1, ind++) {} \ dasd_global_profile.counter[ind]++; \ @@ -1086,56 +1197,134 @@ dasd_profile_add_counter (irqtime / sectors, dasd_io_time2ps, device); dasd_profile_add_counter (endtime, dasd_io_time3, device); } -#endif +#endif /* DASD_PROFILE */ -/* SECTION: All the gendisk stuff */ +/******************************************************************************** + * SECTION: All the gendisk stuff + ********************************************************************************/ -/* SECTION: Managing wrappers for ccwcache */ +/******************************************************************************** + * SECTION: Managing wrappers for ccwcache + ********************************************************************************/ /* * function dasd_alloc_request * tries to return space for a channel program of length cplength with * additional data of size datasize. - * If the ccwcache cannot fulfill the request it tries the emergeny requests - * before giving up finally + * If the ccwcache cannot fulfill the request it tries the lowmem requests + * before giving up finally. * FIXME: initialization of ccw_req_t should be done by function of ccwcache */ ccw_req_t * -dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* device) +dasd_alloc_request (char *magic, int cplength, int datasize, + dasd_device_t *device) { - ccw_req_t *rv = NULL; + ccw_req_t *cqr; + unsigned long size_needed; + unsigned long data_offset, ccw_offset; + dasd_lowmem_t *lowmem; + + if ((cqr = ccw_alloc_request (magic, cplength, datasize)) != NULL) { + return cqr; + } + + /* Sanity checks */ + if (magic == NULL || datasize > PAGE_SIZE || + cplength == 0 || (cplength * sizeof(ccw1_t)) > PAGE_SIZE) + BUG(); - if ((rv = ccw_alloc_request (magic, cplength, datasize)) != NULL) { - return rv; + /* use lowmem page only for ERP or */ + /* if there are less than 2 requests on queue */ + if (device->queue.head != NULL && + device->queue.head->next != NULL && + device->queue.head->status != CQR_STATUS_ERROR) { + return NULL; + } + + /* We try to keep things together in memory */ + size_needed = (sizeof (ccw_req_t) + 7) & (~7L); + data_offset = ccw_offset = 0; + if (size_needed + datasize <= PAGE_SIZE) { + /* Keep data with the request */ + data_offset = size_needed; + size_needed += (datasize + 7) & (~7L); + } + if (size_needed + cplength*sizeof(ccw1_t) <= PAGE_SIZE) { + /* Keep CCWs with request */ + ccw_offset = size_needed; + size_needed += (cplength*sizeof(ccw1_t)) & (~7L); } - if ((((sizeof (ccw_req_t) + 7) & -8) + - cplength * sizeof (ccw1_t) + datasize) > PAGE_SIZE) { - BUG (); + + /* take page from lowmem_pool for request */ + list_for_each_entry (lowmem, &device->lowmem_pool, list) { + list_del (&lowmem->list); + cqr = (ccw_req_t *) lowmem; + memset (cqr, 0, PAGE_SIZE); + cqr->flags |= CQR_FLAGS_LM_CQR; + break; + } + if (cqr == NULL) + return NULL; + + /* take page from lowmem_pool for the extra data */ + if (data_offset == 0) { + + list_for_each_entry (lowmem, &device->lowmem_pool, list) { + list_del (&lowmem->list); + cqr->data = (void *) lowmem; + memset (cqr->data, 0, PAGE_SIZE); + break; + } + if (cqr->data == NULL) { + printk(KERN_DEBUG PRINTK_HEADER + "Couldn't allocate data area\n"); + + lowmem = (dasd_lowmem_t *) cqr; + list_add (&lowmem->list, &device->lowmem_pool); + return NULL; } - if (device->lowmem_cqr==NULL) { - DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request, - "(%04x) Low memory! Using emergency request %p.", - device->devinfo.devno, - device->lowmem_ccws); - - device->lowmem_cqr=device->lowmem_ccws; - rv = device->lowmem_ccws; - memset (rv, 0, PAGE_SIZE); - strncpy ((char *) (&rv->magic), magic, 4); - ASCEBC ((char *) (&rv->magic), 4); - rv->cplength = cplength; - rv->datasize = datasize; - rv->data = (void *) ((long) rv + PAGE_SIZE - datasize); - rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t)); - } else { - DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request, - "(%04x) Refusing emergency mem for request " - "NULL, already in use at %p.", - device->devinfo.devno, - device->lowmem_ccws); - } - return rv; + } else { + /* Extra data already allocated with the request */ + cqr->data = (void *) ((addr_t) cqr + data_offset); + } + + /* take page from lowmem_pool for the channel program */ + if (ccw_offset == 0) { + + list_for_each_entry (lowmem, &device->lowmem_pool, list) { + list_del (&lowmem->list); + cqr->cpaddr = (ccw1_t *) lowmem; + memset (cqr->cpaddr, 0, PAGE_SIZE); + break; + } + + if (cqr->cpaddr == NULL) { + printk (KERN_DEBUG PRINTK_HEADER + "Couldn't allocate channel program area\n"); + if (data_offset == 0) { + lowmem = (dasd_lowmem_t *) cqr->data; + list_add (&lowmem->list, &device->lowmem_pool); + } + lowmem = (dasd_lowmem_t *) cqr; + list_add (&lowmem->list, &device->lowmem_pool); + return NULL; + } + } else { + /* Channel program already allocated with the request */ + cqr->cpaddr = (ccw1_t *) ((addr_t) cqr + ccw_offset); + } + + /* use the remaining memory of the cqr page for IDALs */ + cqr->lowmem_idal_ptr = (void *) ((addr_t) cqr + size_needed); + + strncpy ((char *)(&cqr->magic), magic, 4); + + ASCEBC((char *)(&cqr->magic), 4); + cqr->cplength = cplength; + cqr->datasize = datasize; + + return cqr; } /* @@ -1143,87 +1332,147 @@ * returns a ccw_req_t to the appropriate cache or emergeny request line */ void -dasd_free_request (ccw_req_t * request, dasd_device_t* device) +dasd_free_request (ccw_req_t *cqr, dasd_device_t* device) { + unsigned long size_needed; + dasd_lowmem_t *lowmem; + #ifdef CONFIG_ARCH_S390X ccw1_t* ccw; - /* clear any idals used for chain */ - ccw=request->cpaddr-1; + /* clear any idals used for chain (might be in lowmen cqr page, */ + /* in seperate lowmen page or kmalloced */ + ccw=cqr->cpaddr-1; do { ccw++; - if ((ccw->cda < (unsigned long) device->lowmem_idals ) || - (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE) ) - clear_normalized_cda (ccw); - else { - if (device->lowmem_idal_ptr != device->lowmem_idals) - DASD_MESSAGE (KERN_WARNING, device, - "Freeing emergency idals from request at %p.", - request); - device->lowmem_idal_ptr = device->lowmem_idals; - device->lowmem_cqr=NULL; + if ((cqr->flags & CQR_FLAGS_LM_CQR) && + (ccw->cda >= (unsigned long) cqr) && + (ccw->cda < (unsigned long) cqr + PAGE_SIZE)) { + /* IDAL is on the car lowmem page */ + continue; + } + + if ((cqr->flags & CQR_FLAGS_LM_IDAL) && + (ccw->cda >= (unsigned long) cqr->lowmem_idal) && + (ccw->cda < (unsigned long) cqr->lowmem_idal + PAGE_SIZE)) { + /* IDAL is on seperate lowmem page */ + continue; } + + /* IDAL was build by set_normalized_cda */ + clear_normalized_cda (ccw); + } while ((ccw->flags & CCW_FLAG_CC) || (ccw->flags & CCW_FLAG_DC) ); #endif - if (request != device->lowmem_ccws) { - /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */ - ccw_free_request (request); - } else { - DASD_MESSAGE (KERN_WARNING, device, - "Freeing emergency request at %p", - request); - device->lowmem_cqr=NULL; - } + /* give idal lowmem page back to lowmem_pool */ + if (cqr->flags & CQR_FLAGS_LM_IDAL) { + lowmem = (dasd_lowmem_t *) cqr->lowmem_idal; + list_add (&lowmem->list, &device->lowmem_pool); + cqr->flags &= ~CQR_FLAGS_LM_IDAL; + } + + /* give cqr lowmem pages back to lowmem_pool */ + if (cqr->flags & CQR_FLAGS_LM_CQR) { + + /* make the same decisions as in dasd_alloc_request */ + size_needed = (sizeof (ccw_req_t) + 7) & (~7L); + if (size_needed + cqr->datasize <= PAGE_SIZE) { + /* We kept the data with the request */ + size_needed += (cqr->datasize + 7) & (~7L); + } else { + lowmem = (dasd_lowmem_t *) cqr->data; + list_add (&lowmem->list, &device->lowmem_pool); + } + + if (size_needed + cqr->cplength * sizeof(ccw1_t) > PAGE_SIZE) { + /* We didn't keep the CCWs with request */ + lowmem = (dasd_lowmem_t *) cqr->cpaddr; + list_add (&lowmem->list, &device->lowmem_pool); + } + lowmem = (dasd_lowmem_t *) cqr; + list_add (&lowmem->list, &device->lowmem_pool); + } else { + ccw_free_request (cqr); + } } +/* + * function dasd_set_normalized_cda + * calls set_normalized_cda to build IDALs. + * If this did not work because of low memory, we try to use memory from the + * lowmem pool. + */ int -dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, - ccw_req_t* request, dasd_device_t* device ) +dasd_set_normalized_cda (ccw1_t *cp, unsigned long address, + ccw_req_t *cqr, dasd_device_t *device) { #ifdef CONFIG_ARCH_S390X + int rc; int nridaws; + dasd_lowmem_t *lowmem; int count = cp->count; - if (set_normalized_cda (cp, address)!=-ENOMEM) { - return 0; - } - - if ((device->lowmem_cqr!=NULL) && (device->lowmem_cqr!=request)) { - DASD_MESSAGE (KERN_WARNING, device, - "Refusing emergency idals for request %p, memory" - " is already in use for request %p", - request, - device->lowmem_cqr); - return -ENOMEM; - } - device->lowmem_cqr=request; - if (device->lowmem_idal_ptr == device->lowmem_idals) { - DASD_MESSAGE (KERN_WARNING,device, - "Low memory! Using emergency IDALs for request %p.\n", - request); + /* use lowmem idal page if already assinged */ + if (!(cqr->flags & CQR_FLAGS_LM_IDAL)) { + rc = set_normalized_cda (cp, (void *)address); + if (rc !=-ENOMEM) { + return rc; + } } + + /* get number of idal words needed */ nridaws = ((address & (IDA_BLOCK_SIZE-1)) + count + (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG; - if ( device->lowmem_idal_ptr>=device->lowmem_idals + PAGE_SIZE ) { - /* Ouch! No Idals left for emergency request */ - BUG(); - } + + /* check if we need an additional IDALs page */ + if (!(cqr->flags & CQR_FLAGS_LM_IDAL)) { + /* we got no lowmem cqr page OR */ + /* there is no space left for IDALs */ + if ((!(cqr->flags & CQR_FLAGS_LM_CQR)) || + ((cqr->lowmem_idal_ptr + nridaws * sizeof(unsigned long)) > + ((void *) cqr + PAGE_SIZE))) { + + /* use lowmem page only for ERP or */ + /* if there are less than 2 requests on queue */ + if (device->queue.head != NULL && + device->queue.head->next != NULL && + device->queue.head->status != CQR_STATUS_ERROR) { + return -ENOMEM; + } + + list_for_each_entry (lowmem, &device->lowmem_pool, + list) { + list_del (&lowmem->list); + cqr->lowmem_idal = (void *)lowmem; + cqr->lowmem_idal_ptr = (void *) lowmem; + memset (cqr->lowmem_idal, 0, PAGE_SIZE); + cqr->flags |= CQR_FLAGS_LM_IDAL; + break; + } + } + + } + + /* now we (should) have an valid lowmem_idal_ptr and enough space for */ + /* the IDALs - fill the idals table */ cp->flags |= CCW_FLAG_IDA; - cp->cda = (__u32)(unsigned long)device->lowmem_idal_ptr; + cp->cda = (__u32)(unsigned long)cqr->lowmem_idal_ptr; do { - *((long*)device->lowmem_idal_ptr) = address; - address = (address & -(IDA_BLOCK_SIZE)) + (IDA_BLOCK_SIZE); + *((long*)cqr->lowmem_idal_ptr) = address; + address = (address & -(IDA_BLOCK_SIZE)) + (IDA_BLOCK_SIZE); + cqr->lowmem_idal_ptr += sizeof(unsigned long); nridaws --; - device->lowmem_idal_ptr += sizeof(unsigned long); } while ( nridaws > 0 ); #else - cp -> cda = address; + cp->cda = address; #endif return 0; } -/* SECTION: (de)queueing of requests to channel program queues */ +/******************************************************************************** + * SECTION: (de)queueing of requests to channel program queues + ********************************************************************************/ /* * function dasd_chanq_enq @@ -1245,22 +1494,26 @@ #ifdef DASD_PROFILE - /* save profile information for non erp cqr */ - if (cqr->refers == NULL) { - unsigned int counter = 0; - ccw_req_t *ptr; - dasd_device_t *device = cqr->device; - - /* count the length of the chanq for statistics */ - for (ptr = q->head; - ptr->next != NULL && counter <=31; - ptr = ptr->next) { - counter++; - } - - dasd_global_profile.dasd_io_nr_req[counter]++; - device->profile.dasd_io_nr_req[counter]++; - } + if (dasd_profile_level == DASD_PROFILE_ON) { + + /* save profile information for non erp cqr */ + if (cqr->refers == NULL) { + unsigned int counter = 0; + ccw_req_t *ptr; + dasd_device_t *device = cqr->device; + + /* count the length of the chanq for statistics */ + for (ptr = q->head; + ptr->next != NULL && counter <=31; + ptr = ptr->next) { + counter++; + } + + dasd_global_profile.dasd_io_nr_req[counter]++; + device->profile.dasd_io_nr_req[counter]++; + } + + } /* end if DASD_PROFILE_ON */ #endif } @@ -1276,7 +1529,10 @@ q->head = cqr; if (q->tail == NULL) q->tail = cqr; - check_then_set (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED); + + check_then_set (&cqr->status, + CQR_STATUS_FILLED, + CQR_STATUS_QUEUED); } /* @@ -1302,7 +1558,7 @@ while (prev && prev->next != cqr) prev = prev->next; if (prev == NULL) - return; + return; /* request not in chanq */ prev->next = cqr->next; if (prev->next == NULL) q->tail = prev; @@ -1310,7 +1566,87 @@ cqr->next = NULL; } -/* SECTION: Managing the device queues etc. */ +/******************************************************************************** + * SECTION: Managing the device queues etc. + ********************************************************************************/ + +/* + * DASD_RESREL_TIMEOUT + * + * A timer is used to suspend the current reserve/release request + * if it doesn't return within a certain time. + */ +void +dasd_resrel_timeout (unsigned long cqr_ptr) +{ + dasd_device_t *device = ((ccw_req_t *) cqr_ptr)->device; + ccw_req_t *cqr; + unsigned long flags; + + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + cqr = device->queue.head; + + switch (cqr->status) { + case CQR_STATUS_FILLED: + case CQR_STATUS_QUEUED: + /* request was not started - just set to failed */ + cqr->status = CQR_STATUS_FAILED; + break; + + case CQR_STATUS_IN_IO: + case CQR_STATUS_ERROR: + if (device->discipline->term_IO (cqr) != 0); + cqr->status = CQR_STATUS_FAILED; + break; + + default: + ; /* DONE and FAILED are ok */ + } + + dasd_schedule_bh (device); + + s390irq_spin_unlock_irqrestore (device->devinfo.irq, + flags); + +} /* end dasd_resrel_timeout */ + +/* + * Call unconditional reserve to break the reserve of an other system. + * Timeout the request if it doesn't succseed within a certain time. + */ +static int +dasd_steal_lock (dasd_device_t *device) +{ + ccw_req_t *cqr; + int rc = 0; + + if (!device->discipline->steal_lock) + rc = -EINVAL; + + cqr = device->discipline->steal_lock (device); + + if (cqr) { + struct timer_list res_timer; + + init_timer(&res_timer); + res_timer.function = dasd_resrel_timeout; + res_timer.data = (unsigned long) cqr; + res_timer.expires = jiffies + 4 * HZ; + add_timer(&res_timer); + + rc = dasd_sleep_on_immediate (cqr); + + del_timer_sync(&res_timer); + dasd_free_request (cqr, + device); + } else { + rc = -ENOMEM; + } + + return rc; + +} /* end dasd_steal_lock */ /* * DASD_TERM_IO @@ -1331,55 +1667,57 @@ BUG (); } irq = device->devinfo.irq; - if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) { - DASD_MESSAGE (KERN_WARNING, device, - " ccw_req_t 0x%08x magic doesn't match" - " discipline 0x%08x\n", - cqr->magic, - *(unsigned int *) device->discipline->name); + if (strncmp ((char *) &cqr->magic, + device->discipline->ebcname, 4)) { + + DEV_MESSAGE (KERN_WARNING, device, + " ccw_req_t 0x%08x magic doesn't match" + " discipline 0x%08x", + cqr->magic, + *(unsigned int *) device->discipline->name); + return -EINVAL; } while ((retries < 5 ) && (cqr->status == CQR_STATUS_IN_IO) ) { - if ( retries < 2 ) - rc = halt_IO(irq, (long)cqr, - cqr->options | DOIO_WAIT_FOR_INTERRUPT); - else - rc = clear_IO(irq, (long)cqr, - cqr->options | DOIO_WAIT_FOR_INTERRUPT); - + rc = clear_IO (irq, + (long)cqr, + cqr->options); + switch (rc) { case 0: /* termination successful */ check_then_set (&cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_FAILED); - asm volatile ("STCK %0":"=m" (cqr->stopclk)); + cqr->stopclk = get_clock (); + break; case -ENODEV: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "device gone, retry\n"); + DBF_DEV_EVENT (DBF_ERR, device, "%s", + "device gone, retry"); break; case -EIO: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "I/O error, retry\n"); + DBF_DEV_EVENT (DBF_ERR, device, "%s", + "I/O error, retry"); break; case -EBUSY: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "device busy, retry later\n"); + DBF_DEV_EVENT (DBF_ERR, device, "%s", + "device busy, retry later"); break; default: - DASD_MESSAGE (KERN_ERR, device, - "line %d unknown RC=%d, please report" - " to linux390@de.ibm.com\n", - __LINE__, - rc); + DEV_MESSAGE (KERN_ERR, device, + "line %d unknown RC=%d, please " + "report to linux390@de.ibm.com", + __LINE__, + rc); BUG (); break; } + dasd_schedule_bh (device); retries ++; } return rc; @@ -1401,27 +1739,30 @@ BUG (); } irq = device->devinfo.irq; - if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) { - DASD_MESSAGE (KERN_WARNING, device, - " ccw_req_t 0x%08x magic doesn't match" - " discipline 0x%08x\n", - cqr->magic, - *(unsigned int *) device->discipline->name); + if (strncmp ((char *) &cqr->magic, + device->discipline->ebcname, 4)) { + + DEV_MESSAGE (KERN_ERR, device, + " ccw_req_t 0x%08x magic doesn't match" + " discipline 0x%08x", + cqr->magic, + *(unsigned int *) device->discipline->name); + return -EINVAL; } - asm volatile ("STCK %0":"=m" (now)); - cqr->startclk = now; + now = get_clock (); - rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options); + cqr->startclk = now; + if (device->accessible) + rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options); + else + rc = -EBUSY; switch (rc) { case 0: if (cqr->options & DOIO_WAIT_FOR_INTERRUPT) { /* request already finished (synchronous IO) */ - DASD_MESSAGE (KERN_ERR, device, "%s", - " do_IO finished request... " - "DOIO_WAIT_FOR_INTERRUPT was set"); check_then_set (&cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_DONE); @@ -1436,12 +1777,22 @@ } break; case -EBUSY: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "device busy, retry later\n"); + DBF_DEV_EVENT (DBF_ERR, device, "%s", + "device busy, retry later"); + + if (!timer_pending(&device->timer)) { + init_timer (&device->timer); + device->timer.function = dasd_schedule_bh_timed; + device->timer.data = (unsigned long) device; + device->timer.expires = jiffies + (HZ >> 4); + add_timer (&device->timer); + } else { + mod_timer(&device->timer, jiffies + (HZ >> 4)); + } break; case -ETIMEDOUT: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "request timeout - terminated\n"); + DBF_DEV_EVENT (DBF_ERR, device, "%s", + "request timeout - terminated"); case -ENODEV: case -EIO: check_then_set (&cqr->status, @@ -1452,9 +1803,11 @@ dasd_schedule_bh (device); break; default: - DASD_MESSAGE (KERN_ERR, device, - "line %d unknown RC=%d, please report" - " to linux390@de.ibm.com\n", __LINE__, rc); + DEV_MESSAGE (KERN_ERR, device, + "line %d unknown RC=%d, please report" + " to linux390@de.ibm.com", + __LINE__, + rc); BUG (); break; } @@ -1465,43 +1818,83 @@ /* * function dasd_sleep_on_req * attempts to start the IO and waits for completion - * FIXME: replace handmade sleeping by wait_event */ int -dasd_sleep_on_req (ccw_req_t * req) +dasd_sleep_on_req (ccw_req_t * cqr) { unsigned long flags; - int cs; - int rc = 0; - dasd_device_t *device = (dasd_device_t *) req->device; + dasd_device_t *device = (dasd_device_t *) cqr->device; - if ( signal_pending(current) ) { + if (signal_pending(current)) { return -ERESTARTSYS; } - s390irq_spin_lock_irqsave (device->devinfo.irq, flags); - dasd_chanq_enq (&device->queue, req); + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + + dasd_chanq_enq (&device->queue, + cqr); + /* let the bh start the request to keep them in order */ dasd_schedule_bh (device); - do { - s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags); - wait_event ( device->wait_q, - (((cs = req->status) == CQR_STATUS_DONE) || - (cs == CQR_STATUS_FAILED) || - signal_pending(current))); - s390irq_spin_lock_irqsave (device->devinfo.irq, flags); - if ( signal_pending(current) ) { - rc = -ERESTARTSYS; - if (req->status == CQR_STATUS_IN_IO ) - device->discipline->term_IO(req); - break; - } else if ( req->status == CQR_STATUS_FAILED) { - rc = -EIO; - break; - } - } while (cs != CQR_STATUS_DONE && cs != CQR_STATUS_FAILED); - s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags); - return rc; -} /* end dasd_sleep_on_req */ + + s390irq_spin_unlock_irqrestore (device->devinfo.irq, + flags); + + wait_event (device->wait_q, + cqr->flags & CQR_FLAGS_FINALIZED); + + if (cqr->status == CQR_STATUS_FAILED) { + return -EIO; + } + + return 0; + +} /* end dasd_sleep_on_req */ + +/* + * function dasd_sleep_on_immediate + * same as dasd_sleep_on_req, but attempts to start the IO immediately + * (killing the actual running IO). + */ +static int +dasd_sleep_on_immediate (ccw_req_t *cqr) +{ + unsigned long flags; + dasd_device_t *device = (dasd_device_t *) cqr->device; + + if (signal_pending(current)) + return -ERESTARTSYS; + + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + + /* terminate currently running IO */ + if (device->queue.head->status == CQR_STATUS_IN_IO) { + + device->discipline->term_IO (device->queue.head); + + device->queue.head->status = CQR_STATUS_QUEUED; + } + + dasd_chanq_enq_head (&device->queue, + cqr); + + /* let the bh start the request to keep them in order */ + dasd_schedule_bh (device); + + s390irq_spin_unlock_irqrestore (device->devinfo.irq, + flags); + + wait_event (device->wait_q, + cqr->flags & CQR_FLAGS_FINALIZED); + + if (cqr->status == CQR_STATUS_FAILED) { + return -EIO; + } + + return 0; + +} /* end dasd_sleep_on_immediate */ /* * function dasd_end_request @@ -1547,12 +1940,17 @@ unsigned long long now; int rc = 0; - asm volatile ("STCK %0":"=m" (now)); - if (cqr->expires && cqr->expires + cqr->startclk < now) { - DASD_MESSAGE (KERN_ERR, ((dasd_device_t *) cqr->device), - "IO timeout 0x%08lx%08lx usecs in req %p\n", - (long) (cqr->expires >> 44), - (long) (cqr->expires >> 12), cqr); + now = get_clock (); + + if (cqr->expires && + cqr->expires + cqr->startclk < now) { + + DBF_DEV_EVENT (DBF_WARNING, ((dasd_device_t *) cqr->device), + "IO timeout 0x%08lx%08lx usecs in req %p", + (long) (cqr->expires >> 44), + (long) (cqr->expires >> 12), + cqr); + cqr->expires <<= 1; rc = -EIO; } @@ -1569,22 +1967,36 @@ { dasd_device_t *device = cqr->device; - asm volatile ("STCK %0":"=m" (cqr->endclk)); + cqr->endclk = get_clock (); + if (cqr->req) { + #ifdef DASD_PROFILE - dasd_profile_add (cqr); + if (dasd_profile_level == DASD_PROFILE_ON) { + dasd_profile_add (cqr); + } #endif + dasd_end_request (cqr->req, (cqr->status == CQR_STATUS_DONE)); /* free request if nobody is waiting on it */ dasd_free_request (cqr, cqr->device); } else { - if ( cqr == device->init_cqr && /* bring late devices online */ - device->level <= DASD_STATE_ONLINE ) { - device->timer.function = dasd_enable_single_device; - device->timer.data = (unsigned long) device; - device->timer.expires = jiffies; - add_timer(&device->timer); + if (cqr == device->init_cqr && /* bring late devices online */ + device->level <= DASD_STATE_ONLINE ) { + if (!timer_pending(&device->late_timer)) { + init_timer(&device->late_timer); + device->late_timer.function = dasd_enable_single_device; + device->late_timer.data = (unsigned long) device; + device->late_timer.expires = jiffies; + add_timer(&device->late_timer); + } else { + mod_timer(&device->late_timer, jiffies); + } + } else { + /* notify sleep_on_xxx about finished cqr */ + cqr->flags |= CQR_FLAGS_FINALIZED; } + /* notify sleeping task about finished postprocessing */ wake_up (&device->wait_q); @@ -1606,12 +2018,10 @@ dasd_chanq_t *qp = &device->queue; int irq = device->devinfo.irq; ccw_req_t *final_requests = NULL; - static int chanq_min_size = DASD_MIN_SIZE_FOR_QUEUE; int chanq_max_size = DASD_CHANQ_MAX_SIZE; ccw_req_t *cqr = NULL, *temp; dasd_erp_postaction_fn_t erp_postaction; - s390irq_spin_lock_irqsave (irq, flags); /* First we dechain the requests, processed with completed status */ @@ -1628,16 +2038,10 @@ qp->head->retries--; - if (qp->head->dstat->flag & DEVSTAT_HALT_FUNCTION) { - - check_then_set (&qp->head->status, - CQR_STATUS_ERROR, - CQR_STATUS_FAILED); - - asm volatile ("STCK %0":"=m" (qp->head->stopclk)); - - } else if ((device->discipline->erp_action == NULL ) || - ((erp_action = device->discipline->erp_action (qp->head)) == NULL) ) { + if ((qp->head->dstat == NULL ) || + ((qp->head->dstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) == 0 ) || + (device->discipline->erp_action == NULL ) || + ((erp_action = device->discipline->erp_action (qp->head)) == NULL) ) { erp_cqr = dasd_default_erp_action (qp->head); @@ -1651,12 +2055,12 @@ if (qp->head->status == CQR_STATUS_DONE) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "ERP successful"); + DBF_DEV_EVENT (DBF_NOTICE, device, "%s", + "ERP successful"); } else { - DASD_MESSAGE (KERN_ERR, device, "%s", - "ERP unsuccessful"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "ERP unsuccessful"); } if ((device->discipline->erp_postaction == NULL )|| @@ -1685,66 +2089,61 @@ } /* end while over completed requests */ if (cqr) - cqr->next = NULL; + cqr->next = NULL; /* terminate final_requests queue */ + /* Now clean the requests with final status */ while (final_requests) { temp = final_requests; final_requests = temp->next; dasd_finalize_request (temp); } + /* Now we try to fetch requests from the request queue */ - for (temp = cqr; temp != NULL; temp = temp->next) + for (temp = qp->head; temp != NULL; temp = temp->next) { if (temp->status == CQR_STATUS_QUEUED) chanq_max_size--; + } + while ((atomic_read(&device->plugged) == 0) && + (queue) && (!queue->plugged) && (!list_empty (&queue->queue_head)) && - (req = dasd_next_request (queue)) != NULL) { + (req = dasd_next_request (queue)) && + (qp->head == NULL || chanq_max_size > 0)) { /* queue empty or certain critera fulfilled -> transfer */ - if (qp->head == NULL || - chanq_max_size > 0 || (req->nr_sectors >= chanq_min_size)) { - ccw_req_t *cqr = NULL; - if (is_read_only(device->kdev) && req->cmd == WRITE) { - - DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler, - "(%04x) Rejecting write request %p\n", - device->devinfo.devno, - req); + cqr = NULL; + if (is_read_only(device->kdev) && req->cmd == WRITE) { - dasd_end_request (req, 0); - dasd_dequeue_request (queue,req); - } else { - /* relocate request according to partition table */ - req->sector += - device->major_info->gendisk. - part[MINOR (req->rq_dev)].start_sect; - cqr = device->discipline->build_cp_from_req (device, req); - if (cqr == NULL) { - - DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler, - "(%04x) CCW creation failed " - "on request %p\n", - device->devinfo.devno, - req); - /* revert relocation of request */ - req->sector -= - device->major_info->gendisk. - part[MINOR (req->rq_dev)].start_sect; - break; /* terminate request queue loop */ - - } -#ifdef CONFIG_DYNAMIC_QUEUE_MIN_SIZE - chanq_min_size = - (chanq_min_size + req->nr_sectors) >> 1; -#endif /* CONFIG_DYNAMIC_QUEUE_MIN_SIZE */ - dasd_dequeue_request (queue, req); - dasd_chanq_enq (qp, cqr); + DBF_EVENT (DBF_ERR, + "(%04x) Rejecting write request %p", + device->devinfo.devno, + req); + dasd_dequeue_request (queue,req); + dasd_end_request (req, 0); + continue; + } + cqr = device->discipline->build_cp_from_req (device, req); + + if (cqr == NULL || IS_ERR(cqr)) { + if (cqr == ERR_PTR(-ENOMEM)) { + break; } - } else { /* queue not empty OR criteria not met */ - break; /* terminate request queue loop */ - } - } - /* we process the requests with non-final status */ + + MESSAGE (KERN_EMERG, + "(%04x) CCW creation failed " + "on request %p", + device->devinfo.devno, req); + dasd_dequeue_request (queue,req); + dasd_end_request (req, 0); + continue; + } + dasd_dequeue_request (queue, req); + dasd_chanq_enq (qp, cqr); + chanq_max_size--; + + } + + /* we process the requests with non-final status */ if (qp->head) { switch (qp->head->status) { case CQR_STATUS_QUEUED: @@ -1764,6 +2163,10 @@ /* just wait */ break; default: + MESSAGE (KERN_EMERG, + "invalid cqr (%p) detected with status %02x ", + qp->head, + qp->head->status); BUG (); } } @@ -1786,6 +2189,18 @@ } /* + * function dasd_schedule_bh_timed + * retriggers the dasd_schedule_bh function (called by timer queue) + */ +void +dasd_schedule_bh_timed (unsigned long device_ptr) +{ + dasd_device_t *device = (dasd_device_t *) device_ptr; + + dasd_schedule_bh (device); +} + +/* * function dasd_schedule_bh * schedules the request_fn to run with next run_bh cycle */ @@ -1842,30 +2257,43 @@ if (device_addr == NULL) { - printk (KERN_DEBUG PRINTK_HEADER - "unable to find device for state change pending " - "interrupt: devno%04x\n", - stat->devno); + MESSAGE (KERN_DEBUG, + "unable to find device for state change pending " + "interrupt: devno%04x", + stat->devno); return; } /* re-activate first request in queue */ cqr = (*device_addr)->queue.head; + + if (cqr == NULL) { + MESSAGE (KERN_DEBUG, + "got state change pending interrupt on" + "idle device: %04x", + stat->devno); + return; + } if (cqr->status == CQR_STATUS_PENDING) { - DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s", - "device request queue restarted by " - "state change pending interrupt\n"); + DEV_MESSAGE (KERN_DEBUG, (*device_addr), "%s", + "device request queue restarted by " + "state change pending interrupt"); - del_timer (&(*device_addr)->timer); + del_timer_sync (&(*device_addr)->blocking_timer); check_then_set (&cqr->status, CQR_STATUS_PENDING, CQR_STATUS_QUEUED); - dasd_schedule_bh (*device_addr); - } + if (cqr->status == CQR_STATUS_IN_IO) { + cqr->status = CQR_STATUS_QUEUED; + DEV_MESSAGE (KERN_WARNING, (*device_addr), "%s", + "redriving state change pending condition while in IO"); + } + + dasd_schedule_bh (*device_addr); } /* end dasd_handle_state_change_pending */ @@ -1879,50 +2307,50 @@ int ip; ccw_req_t *cqr; dasd_device_t *device; - unsigned long long now; - dasd_era_t era = dasd_era_none; /* default is everything is okay */ + dasd_era_t era; devstat_t *stat = (devstat_t *)ds; if (stat == NULL) { BUG(); } - DASD_DRIVER_DEBUG_EVENT (6, dasd_int_handler, - "Interrupt: IRQ %02x, stat %02x, devno %04x", - irq, - stat->dstat, - stat->devno); - asm volatile ("STCK %0":"=m" (now)); + + DBF_EVENT (DBF_DEBUG, + "Int: IRQ %02x, CS/DS %04x, flag %08x, devno %04x, ip %08x", + irq, + ((stat->cstat<<8)|stat->dstat), + stat->flag, + stat->devno, + stat->intparm); /* first of all check for state change pending interrupt */ if ((stat->dstat & DEV_STAT_ATTENTION ) && (stat->dstat & DEV_STAT_DEV_END ) && (stat->dstat & DEV_STAT_UNIT_EXCEP) ) { - DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, - "State change Interrupt: %04x", - stat->devno); + + DBF_EVENT (DBF_NOTICE, + "State change Interrupt: %04x", + stat->devno); + dasd_handle_state_change_pending (stat); return; } ip = stat->intparm; if (!ip) { /* no intparm: unsolicited interrupt */ - DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, - "Unsolicited Interrupt: %04x", - stat->devno); - printk (KERN_DEBUG PRINTK_HEADER - "unsolicited interrupt: irq 0x%x devno %04x\n", - irq, - stat->devno); + + MESSAGE (KERN_DEBUG, + "unsolicited interrupt: irq 0x%x devno %04x", + irq, + stat->devno); return; } - if (ip & 0x80000001) { - DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, - "spurious Interrupt: %04x", - stat->devno); - printk (KERN_DEBUG PRINTK_HEADER - "spurious interrupt: irq 0x%x devno %04x, parm %08x\n", - irq, - stat->devno,ip); + + if (ip & 0x80000001) { /* check for invalid 'cqr' address */ + + MESSAGE (KERN_DEBUG, + "spurious interrupt: irq 0x%x devno %04x, parm %08x", + irq, + stat->devno,ip); return; } @@ -1930,19 +2358,16 @@ /* check status - the request might have been killed because of dyn dettach */ if (cqr->status != CQR_STATUS_IN_IO) { - DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler, - "invalid status %02x on device %04x", - cqr->status, - stat->devno); - - printk (KERN_DEBUG PRINTK_HEADER - "invalid status: irq 0x%x devno %04x, status %02x\n", - irq, - stat->devno, - cqr->status); + + MESSAGE (KERN_DEBUG, + "invalid status: irq 0x%x devno %04x, status %02x", + irq, + stat->devno, + cqr->status); return; } + /* some consistency checks */ device = (dasd_device_t *) cqr->device; if (device == NULL || device != ds-offsetof(dasd_device_t,dev_status)) { @@ -1955,73 +2380,98 @@ BUG(); } - /* first of all lets try to find out the appropriate era_action */ - DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04x", - ((stat->cstat<<8)|stat->dstat)); - /* first of all lets try to find out the appropriate era_action */ - if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL || - stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) { - /* anything abnormal ? */ - if (device->discipline->examine_error == NULL || - stat->flag & DEVSTAT_HALT_FUNCTION) { - era = dasd_era_fatal; - } else { - era = device->discipline->examine_error (cqr, stat); - } - DASD_DRIVER_DEBUG_EVENT (1, dasd_int_handler," era_code %d", - era); - } - if ( era == dasd_era_none ) { - check_then_set(&cqr->status, - CQR_STATUS_IN_IO, - CQR_STATUS_DONE); - - cqr->stopclk=now; - /* start the next queued request if possible -> fast_io */ - if (cqr->next && - cqr->next->status == CQR_STATUS_QUEUED) { - if (device->discipline->start_IO (cqr->next) != 0) { - printk (KERN_WARNING PRINTK_HEADER - "Interrupt fastpath failed!\n"); - } - } - } else { /* error */ + if (stat->flag & DEVSTAT_HALT_FUNCTION) { + era = dasd_era_fatal; + + } else if (stat->flag & DEVSTAT_FINAL_STATUS && + stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && + stat->cstat == 0) { + /* received 'ok' for running IO */ + era = dasd_era_none; + + } else if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL) { + /* got sense data */ if (cqr->dstat == NULL) cqr->dstat = kmalloc (sizeof (devstat_t), GFP_ATOMIC); if (cqr->dstat) { memcpy (cqr->dstat, stat, sizeof (devstat_t)); } else { - PRINT_ERR ("no memory for dstat...ignoring\n"); + MESSAGE (KERN_DEBUG, "%s", + "no memory for dstat...ignoring"); } - #ifdef ERP_DEBUG - /* dump sense data */ - if (device->discipline && + if (device->discipline && device->discipline->dump_sense ) { - + device->discipline->dump_sense (device, cqr); } #endif + if (device->discipline->examine_error == NULL) { + era = dasd_era_recover; + } else { + era = device->discipline->examine_error (cqr, stat); + } - switch (era) { - case dasd_era_fatal: - check_then_set (&cqr->status, - CQR_STATUS_IN_IO, - CQR_STATUS_FAILED); + } else if (stat->flag & DEVSTAT_NOT_OPER) { + /* path became offline or similar */ + /* => retry to see if there are any other pathes available */ + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Device or a path became not operational while in IO"); + era = dasd_era_recover; + + } else if (stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END) || + stat->cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN) ) { + /* received device state apart from (channel end & device end) */ + /* OR any kind of channel check (e.g. IFCC, DATA_CHECK or ..... */ + /* we got no sense data, therefore we just retry */ + DEV_MESSAGE (KERN_DEBUG, device, + "Status without sense (IFCC,...) CS/DS %04x flag %08x", + ((stat->cstat<<8)|stat->dstat), + stat->flag); + era = dasd_era_recover; - cqr->stopclk = now; - break; - case dasd_era_recover: - check_then_set (&cqr->status, - CQR_STATUS_IN_IO, - CQR_STATUS_ERROR); - break; - default: - BUG (); + } else { + /* any other kind of interrupt - just retry */ + DEV_MESSAGE (KERN_DEBUG, device, + "Got unclassified interrupt CS/DS %04x flag %08x", + ((stat->cstat<<8)|stat->dstat), + stat->flag); + era = dasd_era_recover; + } + + switch (era) { + case dasd_era_none: + check_then_set(&cqr->status, + CQR_STATUS_IN_IO, + CQR_STATUS_DONE); + cqr->stopclk = get_clock (); + /* start the next queued request if possible -> fast_io */ + if (cqr->next && + cqr->next->status == CQR_STATUS_QUEUED) { + if (device->discipline->start_IO (cqr->next) != 0) { + MESSAGE (KERN_WARNING, "%s", + "Interrupt fastpath failed!"); + } } - } + break; + case dasd_era_fatal: + check_then_set (&cqr->status, + CQR_STATUS_IN_IO, + CQR_STATUS_FAILED); + cqr->stopclk = get_clock (); + break; + case dasd_era_recover: + check_then_set (&cqr->status, + CQR_STATUS_IN_IO, + CQR_STATUS_ERROR); + break; + default: + BUG (); + } + + /* handle special device initialization request */ if ( cqr == device->init_cqr && ( cqr->status == CQR_STATUS_DONE || cqr->status == CQR_STATUS_FAILED )){ @@ -2033,59 +2483,47 @@ } /* end dasd_int_handler */ -/* SECTION: Some stuff related to error recovery */ +/******************************************************************************** + * SECTION: Some stuff related to error recovery + ********************************************************************************/ /* * DEFAULT_ERP_ACTION * * DESCRIPTION - * sets up the default-ERP ccw_req_t, namely one, which performs a TIC - * to the original channel program with a retry counter of 16 + * just retries the current cqr * * PARAMETER * cqr failed CQR * * RETURN VALUES - * erp CQR performing the ERP + * cqr modified CQR */ ccw_req_t * dasd_default_erp_action (ccw_req_t * cqr) { dasd_device_t *device = cqr->device; - ccw_req_t *erp = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device); - - printk (KERN_DEBUG PRINTK_HEADER "Default ERP called... \n"); - - if (!erp) { - - DASD_MESSAGE (KERN_ERR, device, "%s", - "Unable to allocate ERP request"); - + // just retry - there is nothing to save ... I got no sense data.... + if (cqr->retries > 0) { + DEV_MESSAGE (KERN_DEBUG, device, + "default ERP called (%i retries left)", + cqr->retries); + check_then_set (&cqr->status, CQR_STATUS_ERROR, - CQR_STATUS_FAILED); - - asm volatile ("STCK %0":"=m" (cqr->stopclk)); - - return cqr; - } - - erp->cpaddr->cmd_code = CCW_CMD_TIC; - erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr; - erp->function = dasd_default_erp_action; - erp->refers = cqr; - erp->device = cqr->device; - erp->magic = cqr->magic; - erp->retries = 16; - - erp->status = CQR_STATUS_FILLED; - - dasd_chanq_enq_head (&device->queue, - erp); - - return erp; - + CQR_STATUS_QUEUED); + } else { + DEV_MESSAGE (KERN_WARNING, device, "%s", + "default ERP called (NO retry left)"); + + check_then_set (&cqr->status, + CQR_STATUS_ERROR, + CQR_STATUS_FAILED); + + cqr->stopclk = get_clock (); + } + return cqr; } /* end dasd_default_erp_action */ /* @@ -2141,26 +2579,21 @@ /* save ptr to original cqr */ cqr = erp; - /* set corresponding status to original cqr */ + /* set corresponding status for original cqr */ if (success) { - - check_then_set (&cqr->status, - CQR_STATUS_ERROR, - CQR_STATUS_DONE); + cqr->status = CQR_STATUS_DONE; } else { - - check_then_set (&cqr->status, - CQR_STATUS_ERROR, - CQR_STATUS_FAILED); - - asm volatile ("STCK %0":"=m" (cqr->stopclk)); + cqr->status = CQR_STATUS_FAILED; + cqr->stopclk = get_clock (); } return cqr; } /* end default_erp_postaction */ -/* SECTION: The helpers of the struct file_operations */ +/******************************************************************************** + * SECTION: The helpers of the struct file_operations + ********************************************************************************/ /* * function dasd_format @@ -2175,39 +2608,41 @@ { int rc = 0; int openct = atomic_read (&device->open_count); + ccw_req_t *req; if (openct > 1) { - DASD_MESSAGE (KERN_WARNING, device, "%s", - "dasd_format: device is open! expect errors."); + + DEV_MESSAGE (KERN_WARNING, device, "%s", + "dasd_format: device is open! " + "expect errors."); } - DASD_MESSAGE (KERN_INFO, device, - "formatting units %d to %d (%d B blocks) flags %d", - fdata->start_unit, - fdata->stop_unit, - fdata->blksize, - fdata->intensity); + + DBF_DEV_EVENT (DBF_NOTICE, device, + "formatting units %d to %d (%d B blocks) flags %d", + fdata->start_unit, + fdata->stop_unit, + fdata->blksize, + fdata->intensity); + while ((!rc) && (fdata->start_unit <= fdata->stop_unit)) { - ccw_req_t *req; - dasd_format_fn_t ffn = device->discipline->format_device; - ffn = device->discipline->format_device; - if (ffn == NULL) + + if (device->discipline->format_device == NULL) break; - req = ffn (device, fdata); + + req = device->discipline->format_device (device, fdata); if (req == NULL) { rc = -ENOMEM; break; } if ((rc = dasd_sleep_on_req (req)) != 0) { - DASD_MESSAGE (KERN_WARNING, device, - " Formatting of unit %d failed with rc = %d\n", - fdata->start_unit, rc); + + DEV_MESSAGE (KERN_WARNING, device, + " Formatting of unit %d failed " + "with rc = %d", + fdata->start_unit, rc); break; } dasd_free_request (req, device); /* request is no longer used */ - if ( signal_pending(current) ) { - rc = -ERESTARTSYS; - break; - } fdata->start_unit++; } return rc; @@ -2258,6 +2693,9 @@ return 0; } +/* + * handle the re-read partition table IOCTL (BLKRRPART) + */ static int dasd_revalidate (dasd_device_t * device) { @@ -2267,8 +2705,9 @@ int openct = atomic_read (&device->open_count); int start = MINOR (kdev); if (openct != 1) { - DASD_MESSAGE (KERN_WARNING, device, "%s", - "BLKRRPART: device is open! expect errors."); + + DEV_MESSAGE (KERN_WARNING, device, "%s", + "BLKRRPART: device is open! expect errors."); } for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) { int major = device->major_info->gendisk.major; @@ -2279,6 +2718,15 @@ return rc; } + +/* + * function do_dasd_ioctl + * Implementation of the DASD API. + * Changes to the API should be binary compatible to privous versions + * of the user-space applications by means of any already existing tool + * (e.g. dasdfmt) must work with the new kernel API. + */ + static int do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data) { @@ -2287,10 +2735,12 @@ major_info_t *major_info; if (!device) { - printk (KERN_WARNING PRINTK_HEADER - "No device registered as device (%d:%d)\n", - MAJOR (inp->i_rdev), - MINOR (inp->i_rdev)); + + MESSAGE (KERN_WARNING, + "No device registered as device (%d:%d)", + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); + return -EINVAL; } if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) { @@ -2298,225 +2748,356 @@ return -EINVAL; } major_info = device->major_info; -#if 0 - printk (KERN_DEBUG PRINTK_HEADER - "ioctl 0x%08x %s'0x%x'%d(%d) on /dev/%s (%d:%d," - " devno 0x%04x on irq %d) with data %8lx\n", - no, - _IOC_DIR (no) == _IOC_NONE ? "0" : - _IOC_DIR (no) == _IOC_READ ? "r" : - _IOC_DIR (no) == _IOC_WRITE ? "w" : - _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u", - _IOC_TYPE (no), - _IOC_NR (no), - _IOC_SIZE (no), - device->name, - MAJOR (inp->i_rdev), - MINOR (inp->i_rdev), - device->devinfo.devno, - device->devinfo.irq, - data); -#endif + + DBF_DEV_EVENT (DBF_DEBUG, device, + "ioctl 0x%08x %s'0x%x'%d(%d) with data %8lx", + no, + (_IOC_DIR (no) == _IOC_NONE ? "0" : + _IOC_DIR (no) == _IOC_READ ? "r" : + _IOC_DIR (no) == _IOC_WRITE ? "w" : + _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u"), + _IOC_TYPE (no), + _IOC_NR (no), + _IOC_SIZE (no), + data); + switch (no) { - case DASDAPIVER: { - int ver = DASD_API_VERSION; - rc = put_user(ver, (int *) data); - break; + case DASDAPIVER: { /* retrun dasd API version */ + int ver = DASD_API_VERSION; + rc = put_user(ver, (int *) data); + break; + } + case BLKGETSIZE: { /* Return device size in # of sectors */ + long blocks = major_info->gendisk.sizes + [MINOR (inp->i_rdev)] << 1; + rc = put_user(blocks, (long *) data); + break; + } + case BLKGETSIZE64:{ + u64 blocks = major_info->gendisk.sizes + [MINOR (inp->i_rdev)]; + rc = put_user(blocks << 10, (u64 *) data); + break; + } + case BLKRRPART: { /* reread partition table */ + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + rc = dasd_revalidate (device); + break; } - case BLKGETSIZE:{ /* Return device size */ - long blocks = major_info->gendisk.sizes - [MINOR (inp->i_rdev)] << 1; - rc = put_user(blocks, (long *) data); - break; - } - case BLKGETSIZE64:{ - u64 blocks = major_info->gendisk.sizes - [MINOR (inp->i_rdev)]; - rc = put_user(blocks << 10, (u64 *) data); - break; - } - case BLKRRPART:{ - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - rc = dasd_revalidate (device); - break; - } - case HDIO_GETGEO:{ - struct hd_geometry geo = { 0, }; - rc = dasd_fillgeo (inp->i_rdev, &geo); - if (rc) - break; + case HDIO_GETGEO: { /* return disk geometry */ + struct hd_geometry geo = { 0, }; + rc = dasd_fillgeo (inp->i_rdev, &geo); + if (rc) + break; - rc = copy_to_user ((struct hd_geometry *) data, &geo, - sizeof (struct hd_geometry)); - if (rc) - rc = -EFAULT; - break; - } - case BIODASDDISABLE:{ - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - if ( device->level > DASD_STATE_ACCEPT) { - dasd_deactivate_queue(device); - if ( device->request_queue) - dasd_flush_request_queues(device,0); - dasd_flush_chanq(device,0); - dasd_disable_blkdev(device); - dasd_set_device_level (device->devinfo.devno, - device->discipline, - DASD_STATE_ACCEPT); - } + rc = copy_to_user ((struct hd_geometry *) data, &geo, + sizeof (struct hd_geometry)); + if (rc) + rc = -EFAULT; + break; + } + case BIODASDDISABLE: { /* disable device */ + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; break; + } + + if ( device->level > DASD_STATE_ACCEPT) { + dasd_deactivate_queue(device); + if ( device->request_queue) + dasd_flush_request_queues(device,0); + dasd_flush_chanq(device,0); + dasd_disable_blkdev(device); + dasd_set_device_level (device->devinfo.devno, + device->discipline, + DASD_STATE_ACCEPT); + } + + break; } - case BIODASDENABLE:{ - dasd_range_t range = { - from: device->devinfo.devno, - to: device->devinfo.devno - }; - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - dasd_enable_ranges (&range, device->discipline, 0); + case BIODASDENABLE: { /* enable device */ + dasd_range_t range = { + from: device->devinfo.devno, + to: device->devinfo.devno + }; + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; break; + } + dasd_enable_ranges (&range, device->discipline, 0); + break; } - case BIODASDFMT:{ - /* fdata == NULL is no longer a valid arg to dasd_format ! */ - int partn = MINOR (inp->i_rdev) & - ((1 << major_info->gendisk.minor_shift) - 1); - format_data_t fdata; + case BIODASDFMT: { /* format device */ + /* fdata == NULL is no longer a valid arg to dasd_format ! */ + int partn = MINOR (inp->i_rdev) & + ((1 << major_info->gendisk.minor_shift) - 1); + format_data_t fdata; + + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + if (dasd_features_from_devno(device->devinfo.devno)&DASD_FEATURE_READONLY) { + rc = -EROFS; + break; + } + if (!data) { + rc = -EINVAL; + break; + } + rc = copy_from_user (&fdata, (void *) data, + sizeof (format_data_t)); + if (rc) { + rc = -EFAULT; + break; + } + if (partn != 0) { - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - if (dasd_features_from_devno(device->devinfo.devno)&DASD_FEATURE_READONLY) { - rc = -EROFS; - break; + DEV_MESSAGE (KERN_WARNING, device, "%s", + "Cannot low-level format a partition"); + + return -EINVAL; + } + rc = dasd_format (device, &fdata); + break; + } + case BIODASDSATTR: { /* Set Attributes (cache operations) */ + + attrib_data_t attrib; + + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + + if (!data) { + rc = -EINVAL; + break; + } + + if (!device->discipline->set_attrib) { + rc = -EINVAL; + break; + } + + rc = copy_from_user (&attrib, (void *) data, + sizeof (attrib_data_t)); + if (rc) { + rc = -EFAULT; + break; + } + + rc = device->discipline->set_attrib (device, + &attrib); + break; + } + case BIODASDPRRST: { /* reset device profile information */ + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + memset (&device->profile, 0, + sizeof (dasd_profile_info_t)); + break; + } + case BIODASDPRRD: { /* return device profile information */ + rc = copy_to_user((long *)data, + (long *)&device->profile, + sizeof(dasd_profile_info_t)); + if (rc) + rc = -EFAULT; + break; + } + case BIODASDRSRV: { /* reserve device */ + ccw_req_t *cqr; + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + + if (!device->discipline->reserve) { + rc = -EINVAL; + break; + } + + cqr = device->discipline->reserve (device); + + if (cqr) { + struct timer_list res_timer; + + init_timer (&res_timer); + res_timer.function = dasd_resrel_timeout; + res_timer.data = (unsigned long) cqr; + res_timer.expires = jiffies + 2 * HZ; + add_timer (&res_timer); + + rc = dasd_sleep_on_immediate (cqr); + + del_timer_sync (&res_timer); + dasd_free_request (cqr, + device); + } else { + rc = -ENOMEM; + } + break; + } + case BIODASDRLSE: { /* release device */ + ccw_req_t *cqr; + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + + if (!device->discipline->release) { + rc = -EINVAL; + break; + } + + cqr = device->discipline->release (device); + + if (cqr) { + struct timer_list rel_timer; + + init_timer (&rel_timer); + rel_timer.function = dasd_resrel_timeout; + rel_timer.data = (unsigned long) cqr; + rel_timer.expires = jiffies + 2 * HZ; + add_timer (&rel_timer); + + rc = dasd_sleep_on_immediate (cqr); + + del_timer_sync (&rel_timer); /* in case of interrupt */ + dasd_free_request (cqr, + device); + } else { + rc = -ENOMEM; + } + break; + } + case BIODASDSLCK: { /* steal lock - unconditional reserve device */ + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + + rc = dasd_steal_lock (device); + break; + } + case BIODASDINFO: /* return dasd information */ + case BIODASDINFO2: { /* return dasd information2 (incl. format and features) */ + dasd_information2_t dasd_info; + + unsigned long flags; + + if (!device->discipline->fill_info) { + rc = -EINVAL; + break; + } + + rc = device->discipline->fill_info (device, + &dasd_info); + + dasd_info.label_block = device->sizes.pt_block; + dasd_info.devno = device->devinfo.devno; + dasd_info.schid = device->devinfo.irq; + dasd_info.cu_type = device->devinfo.sid_data.cu_type; + dasd_info.cu_model = device->devinfo.sid_data.cu_model; + dasd_info.dev_type = device->devinfo.sid_data.dev_type; + dasd_info.dev_model = device->devinfo.sid_data.dev_model; + dasd_info.open_count = + atomic_read (&device->open_count); + dasd_info.status = device->level; + + /* check if device is really formatted - LDL / CDL was returned by 'fill_info' */ + if ((device->level < DASD_STATE_READY) || + (dasd_check_bp_block (device) ) ) { + dasd_info.format = DASD_FORMAT_NONE; + } + + dasd_info.features = + dasd_features_from_devno (device->devinfo.devno); + + if (device->discipline) { + memcpy (dasd_info.type, + device->discipline->name, 4); + } else { + memcpy (dasd_info.type, "none", 4); + } + dasd_info.req_queue_len = 0; + dasd_info.chanq_len = 0; + + if ((device->request_queue ) && + (device->request_queue->request_fn) ) { + struct list_head *l; + ccw_req_t *cqr = device->queue.head; + spin_lock_irqsave (&io_request_lock, flags); + list_for_each (l, + &device->request_queue-> + queue_head) { + dasd_info.req_queue_len++; } - if (!data) { - rc = -EINVAL; - break; - } - rc = copy_from_user (&fdata, (void *) data, - sizeof (format_data_t)); - if (rc) { - rc = -EFAULT; - break; - } - if (partn != 0) { - DASD_MESSAGE (KERN_WARNING, device, "%s", - "Cannot low-level format a partition"); - return -EINVAL; - } - rc = dasd_format (device, &fdata); - break; - } - case BIODASDPRRST:{ /* reset device profile information */ - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - memset (&device->profile, 0, - sizeof (dasd_profile_info_t)); - break; - } - case BIODASDPRRD:{ /* retrun device profile information */ - rc = copy_to_user((long *)data, - (long *)&device->profile, - sizeof(dasd_profile_info_t)); - if (rc) - rc = -EFAULT; - break; - } - case BIODASDRSRV:{ /* reserve */ - ccw_req_t *req; - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - req = device->discipline->reserve (device); - rc = dasd_sleep_on_req (req); - dasd_free_request (req, device); - break; - } - case BIODASDRLSE:{ /* release */ - ccw_req_t *req; - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - req = device->discipline->release (device); - rc = dasd_sleep_on_req (req); - dasd_free_request (req, device); - break; - } - case BIODASDSLCK:{ /* steal lock - unconditional reserve */ - ccw_req_t *req; - if (!capable (CAP_SYS_ADMIN)) { - rc = -EACCES; - break; - } - req = device->discipline->steal_lock (device); - rc = dasd_sleep_on_req (req); - dasd_free_request (req, device); - break; - } - case BIODASDINFO:{ - dasd_information_t dasd_info; - unsigned long flags; - rc = device->discipline->fill_info (device, &dasd_info); - dasd_info.label_block = device->sizes.pt_block; - dasd_info.devno = device->devinfo.devno; - dasd_info.schid = device->devinfo.irq; - dasd_info.cu_type = device->devinfo.sid_data.cu_type; - dasd_info.cu_model = device->devinfo.sid_data.cu_model; - dasd_info.dev_type = device->devinfo.sid_data.dev_type; - dasd_info.dev_model = device->devinfo.sid_data.dev_model; - dasd_info.open_count = - atomic_read (&device->open_count); - dasd_info.status = device->level; - if (device->discipline) { - memcpy (dasd_info.type, - device->discipline->name, 4); - } else { - memcpy (dasd_info.type, "none", 4); - } - dasd_info.req_queue_len = 0; - dasd_info.chanq_len = 0; - if (device->request_queue->request_fn) { - struct list_head *l; - ccw_req_t *cqr = device->queue.head; - spin_lock_irqsave (&io_request_lock, flags); - list_for_each (l, - &device->request_queue-> - queue_head) { - dasd_info.req_queue_len++; - } - spin_unlock_irqrestore (&io_request_lock, - flags); - s390irq_spin_lock_irqsave (device->devinfo.irq, - flags); - while (cqr) { - cqr = cqr->next; - dasd_info.chanq_len++; - } - s390irq_spin_unlock_irqrestore (device->devinfo. - irq, flags); - } - rc = - copy_to_user ((long *) data, (long *) &dasd_info, - sizeof (dasd_information_t)); - if (rc) - rc = -EFAULT; - break; - } + spin_unlock_irqrestore (&io_request_lock, + flags); + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + while (cqr) { + cqr = cqr->next; + dasd_info.chanq_len++; + } + s390irq_spin_unlock_irqrestore (device->devinfo. + irq, flags); + } + + rc = copy_to_user ((long *) data, (long *) &dasd_info, + ((no == (unsigned int) BIODASDINFO2) ? + sizeof (dasd_information2_t) : + sizeof (dasd_information_t))); + + if (rc) + rc = -EFAULT; + break; + } + case BIODASDPSRD: { /* Performance Statistics Read */ + + ccw_req_t *cqr; + dasd_rssd_perf_stats_t *stats; + + if ((!device->discipline->read_stats) || + (!device->discipline->ret_stats ) ) { + rc = -EINVAL; + break; + } + + cqr = device->discipline->read_stats (device); + + if (cqr) { + + if ((rc = dasd_sleep_on_req (cqr)) == 0) { + + if ((stats = device->discipline->ret_stats (cqr)) != NULL) { + + rc = copy_to_user ((long *) data, + (long *) stats, + sizeof (dasd_rssd_perf_stats_t)); + } else { + + rc = -EFAULT; + } + } + + dasd_free_request (cqr, + device); + + } else { + rc = -ENOMEM; + } + break; + } #if 0 /* needed for XFS */ - case BLKBSZSET:{ + case BLKBSZSET: { int bsz; rc = copy_from_user ((long *)&bsz,(long *)data,sizeof(int)); if ( rc ) { @@ -2528,10 +3109,46 @@ rc = -EINVAL; } break; - } + } #endif /* 0 */ + case BLKROSET: { + int intval; + dasd_range_t *temp; + int devindex = 0; + unsigned long flags; + struct list_head *l; + int major=MAJOR(device->kdev); + int minor; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (inp->i_rdev != device->kdev) + // ro setting is not allowed for partitions + return -EINVAL; + if (get_user(intval, (int *)(data))) + return -EFAULT; + spin_lock_irqsave (&range_lock, flags); + list_for_each (l, &dasd_range_head.list) { + temp = list_entry (l, dasd_range_t, list); + if (device->devinfo.devno >= temp->from && device->devinfo.devno <= temp->to) { + spin_unlock_irqrestore (&range_lock, flags); + if (intval) + temp->features |= DASD_FEATURE_READONLY; + else + temp->features &= ~DASD_FEATURE_READONLY; + goto continue_blkroset; + } + devindex += temp->to - temp->from + 1; + } + spin_unlock_irqrestore (&range_lock, flags); + return(-ENODEV); +continue_blkroset: + for (minor = MINOR(device->kdev); minor < MINOR(device->kdev) + (1 << DASD_PARTN_BITS); minor++) + set_device_ro(MKDEV(major,minor), intval); + return 0; + } + case BLKBSZGET: case BLKSSZGET: - case BLKROSET: case BLKROGET: case BLKRASET: case BLKRAGET: @@ -2541,37 +3158,41 @@ case BLKELVSET: return blk_ioctl (inp->i_rdev, no, data); break; - default:{ + default: { - dasd_ioctl_list_t *old = dasd_find_ioctl (no); - if (old) { - if ( old->owner ) - __MOD_INC_USE_COUNT(old->owner); - rc = old->handler (inp, no, data); - if ( old->owner ) - __MOD_DEC_USE_COUNT(old->owner); - } else { - DASD_MESSAGE (KERN_INFO, device, - "ioctl 0x%08x=%s'0x%x'%d(%d) data %8lx\n", - no, - _IOC_DIR (no) == _IOC_NONE ? "0" : - _IOC_DIR (no) == _IOC_READ ? "r" : - _IOC_DIR (no) == _IOC_WRITE ? "w" : - _IOC_DIR (no) == - (_IOC_READ | _IOC_WRITE) ? "rw" : "u", - _IOC_TYPE (no), - _IOC_NR (no), - _IOC_SIZE (no), - data); - rc = -ENOTTY; - } - break; + dasd_ioctl_list_t *old = dasd_find_ioctl (no); + if (old) { + if ( old->owner ) + __MOD_INC_USE_COUNT(old->owner); + rc = old->handler (inp, no, data); + if ( old->owner ) + __MOD_DEC_USE_COUNT(old->owner); + } else { + + DBF_DEV_EVENT (DBF_INFO, device, + "unknown ioctl 0x%08x=%s'0x%x'%d(%d) data %8lx", + no, + (_IOC_DIR (no) == _IOC_NONE ? "0" : + _IOC_DIR (no) == _IOC_READ ? "r" : + _IOC_DIR (no) == _IOC_WRITE ? "w" : + _IOC_DIR (no) == + (_IOC_READ | _IOC_WRITE) ? "rw" : "u"), + _IOC_TYPE (no), + _IOC_NR (no), + _IOC_SIZE (no), + data); + + rc = -ENOTTY; + } + break; } } return rc; } -/* SECTION: The members of the struct file_operations */ +/******************************************************************************** + * SECTION: The members of the struct file_operations + ********************************************************************************/ static int dasd_ioctl (struct inode *inp, struct file *filp, @@ -2597,26 +3218,32 @@ goto fail; } if (dasd_probeonly) { - printk ("\n" KERN_INFO PRINTK_HEADER - "No access to device (%d:%d) due to probeonly mode\n", - MAJOR (inp->i_rdev), - MINOR (inp->i_rdev)); + + MESSAGE (KERN_INFO, + "No access to device (%d:%d) due to probeonly mode", + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); + rc = -EPERM; goto fail; } spin_lock_irqsave(&discipline_lock,flags); device = dasd_device_from_kdev (inp->i_rdev); if (!device) { - printk (KERN_WARNING PRINTK_HEADER - "No device registered as (%d:%d)\n", - MAJOR (inp->i_rdev), - MINOR (inp->i_rdev)); + + MESSAGE (KERN_WARNING, + "No device registered as (%d:%d)", + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); + rc = -ENODEV; goto unlock; } if (device->level <= DASD_STATE_ACCEPT ) { - DASD_MESSAGE (KERN_WARNING, device, " %s", - " Cannot open unrecognized device\n"); + + DBF_DEV_EVENT (DBF_ERR, device, " %s", + " Cannot open unrecognized device"); + rc = -ENODEV; goto unlock; } @@ -2648,17 +3275,21 @@ } device = dasd_device_from_kdev (inp->i_rdev); if (!device) { - printk (KERN_WARNING PRINTK_HEADER - "No device registered as %d:%d\n", - MAJOR (inp->i_rdev), - MINOR (inp->i_rdev)); + + MESSAGE (KERN_WARNING, + "No device registered as %d:%d", + MAJOR (inp->i_rdev), + MINOR (inp->i_rdev)); + rc = -EINVAL; goto out; } if (device->level < DASD_STATE_ACCEPT ) { - DASD_MESSAGE (KERN_WARNING, device, " %s", - " Cannot release unrecognized device\n"); + + DBF_DEV_EVENT (DBF_ERR, device, " %s", + " Cannot release unrecognized device"); + rc = -ENODEV; goto out; } @@ -2669,8 +3300,9 @@ __MOD_DEC_USE_COUNT(device->discipline->owner); } else if ( count == -1 ) { /* paranoia only */ atomic_set (&device->open_count,0); - printk (KERN_WARNING PRINTK_HEADER - "release called with open count==0\n"); + + MESSAGE (KERN_WARNING, "%s", + "release called with open count==0"); } out: return rc; @@ -2685,7 +3317,9 @@ ioctl:dasd_ioctl, }; -/* SECTION: Management of device list */ +/******************************************************************************** + * SECTION: Management of device list + ********************************************************************************/ int dasd_fillgeo(int kdev,struct hd_geometry *geo) { @@ -2708,24 +3342,27 @@ int dasd_device_name (char *str, int index, int partition, struct gendisk *hd) { - int len = 0; + major_info_t *major_info; + struct list_head *l; char first, second, third; + int len; - if (hd) { - major_info_t *major_info = NULL; - struct list_head *l; - - list_for_each (l, &dasd_major_info[0].list) { - major_info = list_entry (l, major_info_t, list); - if (&major_info->gendisk == hd) { - break; - } - index += DASD_PER_MAJOR; - } - if (major_info == &dasd_major_info[0]) { - return -EINVAL; - } - } + if (hd == NULL) + return -EINVAL; + + major_info = NULL; + list_for_each (l, &dasd_major_info) { + major_info = list_entry (l, major_info_t, list); + if (&major_info->gendisk == hd) + break; + index += DASD_PER_MAJOR; + } + if (major_info == NULL || &major_info->gendisk != hd) { + /* list empty or hd not found in list */ + return -EINVAL; + } + + len = 0; third = index % 26; second = ((index - 26) / 26) % 26; first = (((index - 702) / 26) / 26) % 26; @@ -2777,7 +3414,8 @@ cqr->status != CQR_STATUS_FAILED ) { cqr->status = CQR_STATUS_FAILED; - asm volatile ("STCK %0":"=m" (cqr->stopclk)); + + cqr->stopclk = get_clock (); } dasd_schedule_bh(device); @@ -2802,6 +3440,56 @@ } } +static inline void dasd_do_hotplug_event (dasd_device_t* device, int eventid) { +#ifdef CONFIG_HOTPLUG + int i; + char *argv[3], *envp[8]; + char devno[20],major[20],minor[20],devname[26],action[20]; + + /* setup command line arguments */ + i=0; + argv[i++] = hotplug_path; + argv[i++] = "dasd"; + argv[i++] = 0; + + /* minimal environment */ + i=0; + envp[i++] = "HOME=/"; + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + + /* device information and event*/ + sprintf (devno, "DEVNO=%04x", device->devinfo.devno); + sprintf (major, "MAJOR=%d", MAJOR(device->kdev)); + sprintf (minor, "MINOR=%d", MINOR(device->kdev)); + sprintf (devname, "DASDNAME=%s",device->name); + switch (eventid) { + case DASD_HOTPLUG_EVENT_ADD: + sprintf (action,"ACTION=add"); + break; + case DASD_HOTPLUG_EVENT_REMOVE: + sprintf (action,"ACTION=remove"); + break; + case DASD_HOTPLUG_EVENT_PARTCHK: + sprintf (action,"ACTION=partchk"); + break; + case DASD_HOTPLUG_EVENT_PARTREMOVE: + sprintf (action,"ACTION=partremove"); + break; + default: + BUG(); + } + envp[i++] = devno; + envp[i++] = major; + envp[i++] = minor; + envp[i++] = devname; + envp[i++] = action; + envp[i++] = 0; + + call_usermodehelper (argv [0], argv, envp); +#endif +} + + static int dasd_disable_volume ( dasd_device_t * device, int force ) { @@ -2810,8 +3498,9 @@ int count = atomic_read (&device->open_count); if ( count ) { - DASD_MESSAGE (KERN_EMERG, device, "%s", - "device has vanished although it was open!"); + + DEV_MESSAGE (KERN_EMERG, device, "%s", + "device has vanished although it was open!"); } if ( force ) { dasd_deactivate_queue(device); @@ -2824,9 +3513,11 @@ /* unregister partitions ('ungrok_partitions') */ devfs_register_partitions(&device->major_info->gendisk, MINOR(device->kdev),1); + dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_PARTREMOVE); - DASD_MESSAGE (KERN_WARNING, device, - "disabling device, target state: %d",target); + DBF_DEV_EVENT (DBF_ERR, device, + "disabling device, target state: %d", + target); dasd_set_device_level (device->devinfo.devno, device->discipline, @@ -2836,7 +3527,7 @@ static void dasd_disable_ranges (dasd_range_t *range, - dasd_discipline_t *d, + dasd_discipline_t *discipline, int all, int force ) { dasd_range_t *rrange; @@ -2858,14 +3549,15 @@ } device = *dptr; if (device == NULL || - (d != NULL && - device -> discipline != d)) + (discipline != NULL && + device -> discipline != discipline)) continue; dasd_disable_volume(device, force); } rrange = list_entry (rrange->list.next, dasd_range_t, list); } while ( all && rrange && rrange != range ); + } static void @@ -2877,10 +3569,13 @@ } static void -dasd_enable_ranges (dasd_range_t *range, dasd_discipline_t *d, int all ) +dasd_enable_ranges (dasd_range_t *range, + dasd_discipline_t *discipline, + int all) { int retries = 0; int j; + int do_again; kdev_t tempdev; dasd_range_t *rrange; @@ -2888,6 +3583,7 @@ return; do { + do_again = 0; if (range == &dasd_range_head) { rrange = list_entry (range->list.next, dasd_range_t, list); @@ -2898,26 +3594,40 @@ for (j = rrange->from; j <= rrange->to; j++) { if ( dasd_devindex_from_devno(j) < 0 ) continue; - dasd_set_device_level (j, d, DASD_STATE_ONLINE); + if (-EAGAIN == dasd_set_device_level + (j, discipline, DASD_STATE_ONLINE)) + do_again = 1; } rrange = list_entry (rrange->list.next, dasd_range_t, list); } while ( all && rrange && rrange != range ); - if (atomic_read (&dasd_init_pending) == 0) /* we are done, exit loop */ + if ((atomic_read (&dasd_init_pending) == 0) && + (!do_again)) /* we are done, exit loop */ break; if ( retries == 0 ) { - printk (KERN_INFO PRINTK_HEADER - "waiting for responses...\n"); + + MESSAGE (KERN_INFO, "%s", + "waiting for responses..."); + } else if ( retries < 5 ) { - printk (KERN_INFO PRINTK_HEADER - "waiting a little bit longer...\n"); + + DBF_EVENT (DBF_NOTICE, "%s", + "waiting a little bit longer..."); + } else { - printk (KERN_INFO PRINTK_HEADER - "giving up, enable late devices manually!\n"); + + MESSAGE (KERN_INFO, "%s", + "giving up, enable late devices manually!"); break; } - interruptible_sleep_on_timeout (&dasd_init_waitq, (1 * HZ)); + + /* prevent scheduling if called by bh (timer) */ + if (!in_interrupt()) { + interruptible_sleep_on_timeout (&dasd_init_waitq, + (1 * HZ) ); + } + retries ++; } while (1); /* now setup block devices */ @@ -2939,9 +3649,9 @@ device = *dptr; if (device == NULL ) continue; - if ( ((d == NULL && device->discipline != NULL) || - (device->discipline == d )) && - device->level >= DASD_STATE_READY && + if ( ((discipline == NULL && device->discipline != NULL) || + (device->discipline == discipline )) && + device->level == DASD_STATE_ONLINE && device->request_queue == NULL ) { if (dasd_features_from_devno(j)&DASD_FEATURE_READONLY) { for (tempdev=device->kdev; @@ -2949,9 +3659,8 @@ tempdev++) set_device_ro (tempdev, 1); - printk (KERN_WARNING PRINTK_HEADER - "setting read-only mode for device /dev/%s\n", - device->name); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "setting read-only mode "); } dasd_setup_blkdev(device); dasd_setup_partitions(device); @@ -2971,13 +3680,17 @@ static void dasd_not_oper_handler (int irq, int status) { - dasd_device_t *device = NULL; - major_info_t *major_info = NULL; + dasd_device_t *device; + major_info_t *major_info; + ccw_req_t* cqr; struct list_head *l; - int i, devno = -ENODEV; + unsigned long flags; + int i, devno; /* find out devno of leaving device: CIO has already deleted this information ! */ - list_for_each (l, &dasd_major_info[0].list) { + devno = -ENODEV; + device = NULL; + list_for_each (l, &dasd_major_info) { major_info = list_entry (l, major_info_t, list); for (i = 0; i < DASD_PER_MAJOR; i++) { device = major_info->dasd_device[i]; @@ -2990,17 +3703,44 @@ break; } - DASD_DRIVER_DEBUG_EVENT (5, dasd_not_oper_handler, - "called for devno %04x", - devno); - if (devno < 0) { - printk (KERN_WARNING PRINTK_HEADER - "not_oper_handler called on irq 0x%04x no devno!\n", - irq); + + MESSAGE (KERN_WARNING, + "not_oper_handler called on irq 0x%04x no devno!", + irq); return; } - dasd_disable_volume(device, 1); + switch (status) { + case DEVSTAT_DEVICE_GONE: + case DEVSTAT_REVALIDATE: //FIXME + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "device is gone, disabling it permanently\n"); + dasd_disable_volume(device, 1); + break; + case DEVSTAT_NOT_ACC: + case DEVSTAT_NOT_ACC_ERR: + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "device is not accessible, disabling it temporary\n"); + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + device->accessible = 0; + if (status == DEVSTAT_NOT_ACC_ERR) { + cqr = device->queue.head; + while (cqr) { + if (cqr->status == CQR_STATUS_QUEUED) + break; + if (cqr->status == CQR_STATUS_IN_IO) + cqr->status = CQR_STATUS_QUEUED; + cqr = cqr->next; + } + } + s390irq_spin_unlock_irqrestore(device->devinfo.irq, + flags); + + break; + default: + panic ("dasd not operational handler was called with illegal status\n"); + } } /* @@ -3014,56 +3754,62 @@ { int devno; int rc = 0; - major_info_t *major_info = NULL; + major_info_t *major_info; dasd_range_t *rptr,range; - dasd_device_t *device = NULL; + dasd_device_t *device; struct list_head *l; + unsigned long flags; int i; + devno = get_devno_by_irq (irq); if (devno == -ENODEV) { rc = -ENODEV; goto out; } - DASD_DRIVER_DEBUG_EVENT (5, dasd_oper_handler, - "called for devno %04x", - devno); - /* find out devno of device */ - list_for_each (l, &dasd_major_info[0].list) { + device = NULL; + list_for_each (l, &dasd_major_info) { major_info = list_entry (l, major_info_t, list); for (i = 0; i < DASD_PER_MAJOR; i++) { device = major_info->dasd_device[i]; - if (device && device->devinfo.irq == irq) { - devno = device->devinfo.devno; + if (device && device->devinfo.irq == irq) break; - } + else + device = NULL; } - if (devno != -ENODEV) + if (device) break; } - if (devno < 0) { - BUG(); - } + if ( device && - device->level == DASD_STATE_READY ) { - dasd_set_device_level (device->devinfo.devno, - device->discipline, DASD_STATE_ONLINE); + (device->level == DASD_STATE_ONLINE) && + (!device->accessible) ) { + s390irq_spin_lock_irqsave (device->devinfo.irq, + flags); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "device is accessible again, reenabling it\n"); + device->accessible = 1; + s390irq_spin_unlock_irqrestore(device->devinfo.irq, + flags); + + dasd_schedule_bh(device); } else { - if (dasd_autodetect) { - rptr = dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES); - if ( rptr == NULL ) { - rc = -ENOMEM; - goto out; - } - } else { - range.from = devno; - range.to = devno; - rptr = ⦥ - } - dasd_enable_ranges (rptr, NULL, 0); + + if (dasd_autodetect) { + rptr = dasd_add_range (devno, devno, DASD_FEATURE_DEFAULT); + if ( rptr == NULL ) { + rc = -ENOMEM; + goto out; + } + } else { + range.from = devno; + range.to = devno; + rptr = ⦥ + } + dasd_enable_ranges (rptr, NULL, 0); } out: return rc; @@ -3075,13 +3821,16 @@ { dasd_device_t **device_addr; - DASD_DRIVER_DEBUG_EVENT (1, dasd_find_device_addr, - "devno %04x", - devno); + DBF_EVENT (DBF_INFO, + "devno %04x", + devno); + if ( dasd_devindex_from_devno (devno) < 0 ) { - DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr, - "no dasd: devno %04x", - devno); + + DBF_EXC (DBF_ALERT, + "no dasd: devno %04x", + devno); + return NULL; } /* allocate major numbers on demand for new devices */ @@ -3090,9 +3839,8 @@ if ((rc = dasd_register_major (NULL)) <= 0) { - DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr, - "%s", - "out of major numbers!"); + DBF_EXC (DBF_ALERT, "%s", + "out of major numbers!"); break; } } @@ -3100,86 +3848,110 @@ } static inline int -dasd_state_del_to_new (dasd_device_t **addr ) +dasd_state_del_to_new (dasd_device_t **addr, int devno) { + int i; dasd_device_t* device; - int rc = 0; - if (*addr == NULL) { /* allocate device descriptor on demand for new device */ - device = kmalloc (sizeof (dasd_device_t), GFP_ATOMIC); - if (device == NULL ) { - rc = -ENOMEM; - goto out; - } - memset (device, 0, sizeof (dasd_device_t)); + dasd_lowmem_t *lowmem; + int rc; + + + /* allocate device descriptor on demand for new device */ + if (*addr != NULL) { + BUG (); + } + + device = kmalloc (sizeof (dasd_device_t), GFP_ATOMIC); + if (device == NULL) { + return -ENOMEM; + } + + memset (device, 0, sizeof (dasd_device_t)); + dasd_plug_device (device); + device->accessible = 1; + INIT_LIST_HEAD (&device->lowmem_pool); + + /* allocate pages for lowmem pool */ + for (i = 0; i < DASD_LOWMEM_PAGES; i++) { + + lowmem = (void *) get_free_page (GFP_ATOMIC|GFP_DMA); + if (lowmem == NULL) { + break; + } + + list_add (&lowmem->list, &device->lowmem_pool); + } + + if (i < DASD_LOWMEM_PAGES) { + /* didn't get the needed lowmem pages */ + list_for_each_entry (lowmem, &device->lowmem_pool, list) { + MESSAGE (KERN_DEBUG, + " not enough memory - " + "Free page again :%p", + devno, lowmem); + free_page ((unsigned long) lowmem); + } + kfree (device); + rc = -ENOMEM; + } else { *addr = device; - device->lowmem_ccws = (void*)get_free_page (GFP_ATOMIC|GFP_DMA); - if (device->lowmem_ccws == NULL) { - rc = -ENOMEM; - goto noccw; - } -#ifdef CONFIG_ARCH_S390X - device->lowmem_idals = - device->lowmem_idal_ptr = (void*) get_free_page (GFP_ATOMIC|GFP_DMA); - if (device->lowmem_idals == NULL) { - rc = -ENOMEM; - goto noidal; - } -#endif -} - goto out; -#ifdef CONFIG_ARCH_S390X - noidal: - free_page ((long) device->lowmem_ccws); -#endif - noccw: - kfree(device); - out: + rc = 0; + } return rc; } static inline int -dasd_state_new_to_del (dasd_device_t **addr ) +dasd_state_new_to_del (dasd_device_t **addr, int devno) { + dasd_lowmem_t *lowmem; + dasd_device_t *device = *addr; + + /* free private area */ if (device && device->private) { kfree(device->private); - device->private = NULL; } -#ifdef CONFIG_ARCH_S390X - free_page ((long)(device->lowmem_idals)); -#endif - free_page((long)(device->lowmem_ccws)); + + /* free lowmem_pool */ + list_for_each_entry (lowmem, &device->lowmem_pool, list) { + free_page ((unsigned long) lowmem); + } + + /* free device */ kfree(device); *addr = NULL; return 0; } static inline int -dasd_state_new_to_known (dasd_device_t **dptr, int devno, dasd_discipline_t *disc) +dasd_state_new_to_known (dasd_device_t **dptr, + int devno, + dasd_discipline_t *discipline) { int rc = 0; umode_t devfs_perm = S_IFBLK | S_IRUSR | S_IWUSR; struct list_head *l; - major_info_t *major_info = NULL; + major_info_t *major_info, *tmp; int i; dasd_device_t *device = *dptr; devfs_handle_t dir; char buffer[5]; - - list_for_each (l, &dasd_major_info[0].list) { - major_info = list_entry (l, major_info_t, list); + major_info = NULL; + list_for_each (l, &dasd_major_info) { + tmp = list_entry (l, major_info_t, list); for (i = 0; i < DASD_PER_MAJOR; i++) { - if (major_info->dasd_device[i] == device) { - device->kdev = MKDEV (major_info->gendisk.major, + if (tmp->dasd_device[i] == device) { + device->kdev = MKDEV (tmp->gendisk.major, i << DASD_PARTN_BITS); + major_info = tmp; break; } } - if (i < DASD_PER_MAJOR) /* we found one */ + if (major_info != NULL) /* we found one */ break; } - if ( major_info == NULL || major_info == &dasd_major_info[0] ) + if ( major_info == NULL ) BUG(); device->major_info = major_info; @@ -3192,18 +3964,24 @@ rc = get_dev_info_by_devno (devno, &device->devinfo); if ( rc ) { + /* returns -EUSERS if boxed !!*/ + if (rc == -EUSERS) { + device->level = DASD_STATE_BOXED; + } goto out; } - DASD_DRIVER_DEBUG_EVENT (5, dasd_state_new_to_known, - "got devinfo CU-type %04x and dev-type %04x", - device->devinfo.sid_data.cu_type, - device->devinfo.sid_data.dev_type); - + DBF_EVENT (DBF_NOTICE, + "got devinfo CU-type %04x and dev-type %04x", + device->devinfo.sid_data.cu_type, + device->devinfo.sid_data.dev_type); + if ( devno != device->devinfo.devno ) BUG(); - device->discipline = dasd_find_disc (device, disc); + + device->discipline = dasd_find_disc (device, + discipline); if ( device->discipline == NULL ) { rc = -ENODEV; goto out; @@ -3221,6 +3999,7 @@ MINOR(device->kdev), devfs_perm, &dasd_device_operations,NULL); + dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_ADD); device->level = DASD_STATE_KNOWN; out: return rc; @@ -3233,7 +4012,7 @@ /* don't reset to zeros because of persistent data durich detach/attach! */ devfs_unregister(device->devfs_entry); devfs_unregister(device->major_info->gendisk.de_arr[MINOR(device->kdev) >> DASD_PARTN_BITS]); - + dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_REMOVE); return rc; } @@ -3241,12 +4020,21 @@ dasd_state_known_to_accept (dasd_device_t *device) { int rc = 0; - device->debug_area = debug_register (device->name, 0, 2, - 3 * sizeof (long)); - debug_register_view (device->debug_area, &debug_sprintf_view); - debug_register_view (device->debug_area, &debug_hex_ascii_view); - DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area created", - device); + + /* register 'device' debug area, used for all DBF_DEV_XXX calls*/ + device->debug_area = debug_register (device->name, + 0, /* size of debug area */ + 2, /* number of areas */ + 8 * sizeof (long)); + + debug_register_view (device->debug_area, + &debug_sprintf_view); + + debug_set_level (device->debug_area, + DBF_ERR); + + DBF_DEV_EVENT (DBF_EMERG, device, "%s", + "debug area created"); if (device->discipline->int_handler) { rc = s390_request_irq_special (device->devinfo.irq, @@ -3255,7 +4043,10 @@ 0, DASD_NAME, &device->dev_status); if ( rc ) { - printk("No request IRQ\n"); + + MESSAGE (KERN_DEBUG, "%s", + "No request IRQ"); + goto out; } } @@ -3272,10 +4063,15 @@ if (device->discipline->int_handler) { free_irq (device->devinfo.irq, &device->dev_status); } - DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area deleted", - device); - if ( device->debug_area != NULL ) + + DBF_DEV_EVENT (DBF_EMERG, device, + "%p debug area deleted", + device); + + if (device->debug_area != NULL) { debug_unregister (device->debug_area); + device->debug_area = NULL; + } device->discipline = NULL; device->level = DASD_STATE_KNOWN; out: @@ -3297,18 +4093,17 @@ s390irq_spin_lock_irqsave (device->devinfo.irq, flags); rc = device->discipline->start_IO (device->init_cqr); + if ( ! rc ) + device->level = DASD_STATE_INIT; s390irq_spin_unlock_irqrestore(device->devinfo.irq, flags); - if ( rc ) - goto out; - device->level = DASD_STATE_INIT; } else { rc = -ENOMEM; } } else { rc = dasd_state_init_to_ready ( device ); } - out: + return rc; } @@ -3318,15 +4113,8 @@ int rc = 0; if (device->discipline->do_analysis != NULL) if ( device->discipline->do_analysis (device) == 0 ) - switch (device->sizes.bp_block) { - case 512: - case 1024: - case 2048: - case 4096: - break; - default: - rc = -EMEDIUMTYPE; - } + rc = dasd_check_bp_block (device); + if ( device->init_cqr ) { /* This pointer is no longer needed, BUT dont't free the */ /* memory, because this is done in bh for finished request!!!! */ @@ -3362,8 +4150,10 @@ dasd_state_ready_to_online (dasd_device_t *device ) { int rc = 0; - dasd_unplug_device (device); - device->level = DASD_STATE_ONLINE; + if (!(rc = dasd_check_bp_block (device))) { + dasd_unplug_device (device); + device->level = DASD_STATE_ONLINE; + } return rc; } @@ -3383,6 +4173,7 @@ int i; int major = MAJOR(device->kdev); int minor = MINOR(device->kdev); + request_queue_t *request_queue; for (i = 0; i < (1 << DASD_PARTN_BITS); i++) { if (i == 0) @@ -3399,11 +4190,16 @@ device->major_info->gendisk.part[minor+i].start_sect = 0; device->major_info->gendisk.part[minor+i].nr_sects = 0; } - device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL); - device->request_queue->queuedata = device; - blk_init_queue (device->request_queue, do_dasd_request); - blk_queue_headactive (device->request_queue, 0); - elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP); + + request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL); + if (request_queue) { + request_queue->queuedata = device; + blk_init_queue (request_queue, do_dasd_request); + blk_queue_headactive (request_queue, 1); + elevator_init (&(request_queue->elevator),ELEVATOR_NOOP); + } + device->request_queue = request_queue; + return rc; } @@ -3424,6 +4220,19 @@ int i; int major = MAJOR(device->kdev); int minor = MINOR(device->kdev); + request_queue_t *q = device->request_queue; + struct request *req; + long flags; + + spin_lock_irqsave(&io_request_lock, flags); + while (q && + !list_empty(&q->queue_head) && + (req = dasd_next_request(q)) != NULL) { + + dasd_end_request(req, 0); + dasd_dequeue_request(q, req); + } + spin_unlock_irqrestore(&io_request_lock, flags); for (i = 0; i < (1 << DASD_PARTN_BITS); i++) { destroy_buffers(MKDEV(major,minor+i)); @@ -3453,6 +4262,7 @@ 1 << DASD_PARTN_BITS, &dasd_device_operations, (device->sizes.blocks << device->sizes.s2b_shift)); + dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_PARTCHK); } static inline void @@ -3467,14 +4277,7 @@ } devfs_register_partitions(&device->major_info->gendisk, MINOR(device->kdev),1); -} - -static inline void -dasd_resetup_partitions ( dasd_device_t * device ) -{ - BUG(); - dasd_destroy_partitions ( device ) ; - dasd_setup_partitions ( device ) ; + dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_PARTREMOVE); } /* @@ -3505,11 +4308,11 @@ from_state = device->level; } - DASD_DRIVER_DEBUG_EVENT (3, dasd_set_device_level, - "devno %04x; from %i to %i", - devno, - from_state, - to_state); + DBF_EVENT (DBF_INFO, + "devno %04x; from %i to %i", + devno, + from_state, + to_state); if ( from_state == to_state ) goto out; @@ -3520,20 +4323,30 @@ /* First check for bringup */ if ( from_state <= DASD_STATE_DEL && to_state >= DASD_STATE_NEW ) { - rc = dasd_state_del_to_new(device_addr); + rc = dasd_state_del_to_new(device_addr, devno); if ( rc ) { goto bringup_fail; } device = *device_addr; } - if ( from_state <= DASD_STATE_NEW && + + /* reprobe boxed devices */ + if (device->level == DASD_STATE_BOXED) { + rc = s390_trigger_resense (device->devinfo.irq); + if ( rc ) { + goto bringup_fail; + } + } + + if ( device->level <= DASD_STATE_BOXED && to_state >= DASD_STATE_KNOWN ) { rc = dasd_state_new_to_known( device_addr, devno, discipline ); if ( rc ) { goto bringup_fail; } } - if ( from_state <= DASD_STATE_KNOWN && + + if ( device->level <= DASD_STATE_KNOWN && to_state >= DASD_STATE_ACCEPT ) { rc = dasd_state_known_to_accept(device); if ( rc ) { @@ -3543,19 +4356,21 @@ if ( dasd_probeonly ) { goto out; } - if ( from_state <= DASD_STATE_ACCEPT && + + if ( device->level <= DASD_STATE_ACCEPT && to_state >= DASD_STATE_INIT ) { rc = dasd_state_accept_to_init(device); if ( rc ) { goto bringup_fail; } } - if ( from_state <= DASD_STATE_INIT && + if ( device->level <= DASD_STATE_INIT && to_state >= DASD_STATE_READY ) { rc = -EAGAIN; goto out; } - if ( from_state <= DASD_STATE_READY && + + if ( device->level <= DASD_STATE_READY && to_state >= DASD_STATE_ONLINE ) { rc = dasd_state_ready_to_online(device); if ( rc ) { @@ -3564,50 +4379,57 @@ } goto out; bringup_fail: /* revert changes */ -#if 0 - printk (KERN_DEBUG PRINTK_HEADER - "failed to set device from state %d to %d at " - "level %d rc %d. Reverting...\n", - from_state, - to_state, - device->level, - rc); -#endif - to_state = from_state; - from_state = device->level; + + DBF_DEV_EVENT (DBF_ERR, device, + "failed to set device from state %d to %d at " + "level %d rc %d. Reverting...", + from_state, + to_state, + device->level, + rc); + + if (device->level <= DASD_STATE_NEW) { + /* Revert - device can not be accessed */ + to_state = from_state; + from_state = device->level; + } /* now do a shutdown */ shutdown: - if ( from_state >= DASD_STATE_ONLINE && + if ( device->level >= DASD_STATE_ONLINE && to_state <= DASD_STATE_READY ) if (dasd_state_online_to_ready(device)) BUG(); - if ( from_state >= DASD_STATE_READY && + if ( device->level >= DASD_STATE_READY && to_state <= DASD_STATE_ACCEPT ) if ( dasd_state_ready_to_accept(device)) BUG(); - if ( from_state >= DASD_STATE_ACCEPT && + if ( device->level >= DASD_STATE_ACCEPT && to_state <= DASD_STATE_KNOWN ) if ( dasd_state_accept_to_known(device)) BUG(); - if ( from_state >= DASD_STATE_KNOWN && + if ( device->level >= DASD_STATE_KNOWN && to_state <= DASD_STATE_NEW ) if ( dasd_state_known_to_new(device)) BUG(); - if ( from_state >= DASD_STATE_NEW && + if ( device->level >= DASD_STATE_NEW && to_state <= DASD_STATE_DEL) - if (dasd_state_new_to_del(device_addr)) + if (dasd_state_new_to_del(device_addr, devno)) BUG(); goto out; out: return rc; } -/* SECTION: Procfs stuff */ +/******************************************************************************** + * SECTION: Procfs stuff + ********************************************************************************/ +#ifdef CONFIG_PROC_FS + typedef struct { char *data; int len; @@ -3640,29 +4462,53 @@ int index = 0; MOD_INC_USE_COUNT; - spin_lock_irqsave(&discipline_lock,flags); + + spin_lock_irqsave(&discipline_lock, + flags); + info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t)); + if (info == NULL) { - printk (KERN_WARNING "No memory available for data\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory available for data (tempinfo)"); + + spin_unlock_irqrestore(&discipline_lock, + flags); + MOD_DEC_USE_COUNT; + return -ENOMEM; + } else { file->private_data = (void *) info; } - list_for_each (l, &dasd_major_info[0].list) { + list_for_each (l, &dasd_major_info) { size += 128 * 1 << (MINORBITS - DASD_PARTN_BITS); } info->data = (char *) vmalloc (size); - DASD_DRIVER_DEBUG_EVENT (1, dasd_devices_open, "area: %p, size 0x%x", - info->data, - size); + if (size && info->data == NULL) { - printk (KERN_WARNING "No memory available for data\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory available for data (info->data)"); + vfree (info); + + spin_unlock_irqrestore(&discipline_lock, + flags); + MOD_DEC_USE_COUNT; + return -ENOMEM; } - list_for_each (l, &dasd_major_info[0].list) { + + DBF_EVENT (DBF_NOTICE, + "procfs-area: %p, size 0x%x allocated", + info->data, + size); + + list_for_each (l, &dasd_major_info) { temp = list_entry (l, major_info_t, list); for (i = 0; i < 1 << (MINORBITS - DASD_PARTN_BITS); i++) { dasd_device_t *device; @@ -3673,8 +4519,8 @@ continue; features = dasd_features_from_devno(devno); - if (features < DASD_DEFAULT_FEATURES) - features = DASD_DEFAULT_FEATURES; + if (features < DASD_FEATURE_DEFAULT) + features = DASD_FEATURE_DEFAULT; device = temp->dasd_device[i]; if (device) { @@ -3702,45 +4548,45 @@ sprintf (info->data + len, "detected"); break; + case DASD_STATE_BOXED: + len += + sprintf (info->data + len, + "boxed"); + break; case DASD_STATE_ACCEPT: - len += sprintf (info->data + len,"accepted"); + len += sprintf (info->data + len, + "accepted"); break; case DASD_STATE_INIT: - len += - sprintf (info->data + len, - "busy "); + len += sprintf (info->data + len, + "busy "); break; case DASD_STATE_READY: + len += sprintf (info->data + len, + "ready "); + break; case DASD_STATE_ONLINE: - if ( atomic_read(&device->plugged) ) - len += - sprintf (info->data + len, - "fenced "); - else - len += - sprintf (info->data + len, - "active "); - if ( device->sizes.bp_block == 512 || - device->sizes.bp_block == 1024 || - device->sizes.bp_block == 2048 || - device->sizes.bp_block == 4096 ) - len += - sprintf (info->data + len, - "at blocksize: %d, %ld blocks, %ld MB", - device->sizes.bp_block, - device->sizes.blocks, - ((device-> - sizes.bp_block >> 9) * - device->sizes. - blocks) >> 11); - else - len += - sprintf (info->data + len, - "n/f "); + len += sprintf (info->data + len, + "active "); + + if (dasd_check_bp_block (device)) + len += + sprintf (info->data + len, + "n/f "); + else + len += + sprintf (info->data + len, + "at blocksize: %d, %ld blocks, %ld MB", + device->sizes.bp_block, + device->sizes.blocks, + ((device-> + sizes.bp_block >> 9) * + device->sizes. + blocks) >> 11); break; default: len += - sprintf (info->data + len, + sprintf (info->data + len, "no stat"); break; } @@ -3769,7 +4615,9 @@ index += 1 << (MINORBITS - DASD_PARTN_BITS); } info->len = len; - spin_unlock_irqrestore(&discipline_lock,flags); + + spin_unlock_irqrestore(&discipline_lock, + flags); return rc; } @@ -3793,22 +4641,250 @@ } } +/* + * scan for device range in given string (e.g. 0x0150-0x0155). + * devnos are always hex and leading 0x are ignored. + */ +static char * +dasd_parse_range (char *buffer, dasd_range_t *range) +{ + char *str; + + /* remove optional 'device ' and 'range=' and search for nexet digit */ + for (str = buffer + 4; isspace(*str); str++); + + if (strncmp (str, "device ", 7) == 0) + for (str = str + 7; isspace(*str); str++); + + if (strncmp (str, "range=", 6) == 0) + for (str = str + 6; isspace(*str); str++); + + range->to = range->from = dasd_strtoul (str, + &str, + &(range->features)); + + if (*str == '-') { + str++; + range->to = dasd_strtoul (str, + &str, + &(range->features)); + } + + /* remove blanks after device range */ + for (; isspace(*str); str++); + + if (range->from < 0 || range->to < 0) { + MESSAGE (KERN_WARNING, + "/proc/dasd/devices: range parse error in '%s'", + buffer); + return ERR_PTR (-EINVAL); + } + + return str; + +} /* end dasd_parse_range */ + +/* + * Enable / Disable the given devices + */ +static void +dasd_proc_set (char *buffer) +{ + dasd_range_t range; + char *str; + + str = dasd_parse_range (buffer, + &range); + + /* Negative numbers in str/from/to indicate errors */ + if (IS_ERR (str) || (range.from < 0) || (range.to < 0) + || (range.from > 65535) || (range.to > 65535)) + return; + + if (strncmp (str, "on", 2) == 0) { + dasd_enable_ranges (&range, NULL, 0); + + } else if (strncmp (str, "off", 3) == 0) { + dasd_disable_ranges (&range, NULL, 0, 1); + + } else { + MESSAGE (KERN_WARNING, + "/proc/dasd/devices: " + "only 'on' and 'off' are alowed in 'set' " + "command ('%s'/'%s')", + buffer, + str); + } + + return; + +} /* end dasd_proc_set */ + +/* + * Add the given devices + */ +static void +dasd_proc_add (char *buffer) +{ + dasd_range_t range; + char *str; + + str = dasd_parse_range (buffer, + &range); + + /* Negative numbers in str/from/to indicate errors */ + if (IS_ERR (str) || (range.from < 0) || (range.to < 0) + || (range.from > 65535) || (range.to > 65535)) + return; + + dasd_add_range (range.from, range.to, range.features); + dasd_enable_ranges (&range, NULL, 0); + + return; + +} /* end dasd_proc_add */ + +/* + * Break the lock of a given 'boxed' dasd. + * If the dasd in not in status 'boxed' just return. + */ +static int +dasd_break_boxed (dasd_range_t *range, + dasd_device_t *device) +{ + int rc = 0; + dasd_discipline_t *discipline; + struct list_head *lh = dasd_disc_head.next; + + /* check devixe status */ + if (device->level != DASD_STATE_BOXED) { + MESSAGE (KERN_WARNING, + "/proc/dasd/devices: the given device (%04X) " + "is not 'boxed')", + device->devinfo.devno); + rc = -EINVAL; + goto out; + } + + /* force eckd discipline */ + do { + discipline = list_entry(lh, + dasd_discipline_t, + list); + + if (strncmp (discipline->name, range->discipline, 4) == 0) + break; /* discipline found */ + + lh = lh->next; /* check next discipline in list */ + if (lh == &dasd_disc_head) { + discipline = NULL; + break; + } + } while ( 1 ); + device->discipline = discipline; + + if (device->discipline == NULL) { + MESSAGE (KERN_WARNING, "%s", + "/proc/dasd/devices: discipline not found " + "in discipline list"); + rc = -EINVAL; + goto out; + } + + /* register the int handler to enable IO */ + rc = s390_request_irq_special (device->devinfo.irq, + device->discipline->int_handler, + dasd_not_oper_handler, + 0, + DASD_NAME, + &device->dev_status); + if ( rc ) + goto out; + + rc = dasd_steal_lock (device); + + /* unregister the int handler to enable re-sensing */ + free_irq (device->devinfo.irq, + &device->dev_status); + + device->discipline = NULL; + device->level = DASD_STATE_NEW; + + out: + return rc; + +} /* end dasd_break_boxed */ + +/* + * Handle the procfs call 'brk . + */ +static void +dasd_proc_brk (char *buffer) +{ + char *str; + dasd_range_t range; + dasd_device_t *device; + int rc = 0; + + str = dasd_parse_range (buffer, + &range); + + if (IS_ERR (str)) + return; + + if (range.from != range.to) { + MESSAGE (KERN_WARNING, "%s", + "/proc/dasd/devices: 'brk " + "is only allowed for a single device (no ranges)"); + return; + } + + /* check for discipline = 'eckd' */ + if (strncmp(str, "eckd", 4) != 0) { + MESSAGE (KERN_WARNING, + "/proc/dasd/devices: 'brk " + "is only allowed for 'eckd' (%s)", + str); + return; + } + + memcpy (range.discipline, "ECKD", 4); + + device = *(dasd_device_from_devno (range.from)); + if (device == NULL) { + MESSAGE (KERN_WARNING, + "/proc/dasd/devices: no device found for devno (%04X)", + range.from); + return; + } + + rc = dasd_break_boxed (&range, + device); + if (rc == 0) { + /* trigger CIO to resense the device */ + s390_trigger_resense (device->devinfo.irq); + + // get the device online now + dasd_enable_ranges (&range, + NULL, + 0); + } + +} /* end dasd_proc_brk */ + static ssize_t dasd_devices_write (struct file *file, const char *user_buf, size_t user_len, loff_t * offset) { char *buffer; - int off = 0; - char *temp; - dasd_range_t range; - int features; if (user_len > PAGE_SIZE) return -EINVAL; - + buffer = vmalloc (user_len+1); if (buffer == NULL) return -ENOMEM; + if (copy_from_user (buffer, user_buf, user_len)) { vfree (buffer); return -EFAULT; @@ -3821,60 +4897,29 @@ buffer[user_len] = '\0'; } - printk (KERN_INFO PRINTK_HEADER "/proc/dasd/devices: '%s'\n", buffer); - if (strncmp (buffer, "set ", 4) && strncmp (buffer, "add ", 4)) { - printk (KERN_WARNING PRINTK_HEADER - "/proc/dasd/devices: only 'set' and 'add' are supported verbs\n"); - return -EINVAL; - } - off += 4; - while (buffer[off] && !isalnum (buffer[off])) - off++; - if (!strncmp (buffer + off, "device", strlen ("device"))) { - off += strlen ("device"); - while (buffer[off] && !isalnum (buffer[off])) - off++; - } - if (!strncmp (buffer + off, "range=", strlen ("range="))) { - off += strlen ("range="); - while (buffer[off] && !isalnum (buffer[off])) - off++; - } - - temp = buffer + off; - range.from = dasd_strtoul (temp, &temp, &features); - range.to = range.from; - - if (*temp == '-') { - temp++; - range.to = dasd_strtoul (temp, &temp, &features); - } + MESSAGE (KERN_INFO, + "/proc/dasd/devices: '%s'", + buffer); + + if (strncmp (buffer, "set ", 4) == 0) { + /* handle 'set on/off' */ + dasd_proc_set (buffer); + + } else if (strncmp (buffer, "add ", 4) == 0) { + /* handle 'add ' */ + dasd_proc_add (buffer); + + } else if (strncmp (buffer, "brk ", 4) == 0) { + /* handle 'brk ' */ + dasd_proc_brk (buffer); - if (range.from == -EINVAL || - range.to == -EINVAL ) { - - printk (KERN_WARNING PRINTK_HEADER - "/proc/dasd/devices: range parse error in '%s'\n", - buffer); } else { - off = (long) temp - (long) buffer; - if (!strncmp (buffer, "add", strlen ("add"))) { - dasd_add_range (range.from, range.to, features); - dasd_enable_ranges (&range, NULL, 0); - } else { - while (buffer[off] && !isalnum (buffer[off])) - off++; - if (!strncmp (buffer + off, "on", strlen ("on"))) { - dasd_enable_ranges (&range, NULL, 0); - } else if (!strncmp (buffer + off, "off", strlen ("off"))) { - dasd_disable_ranges (&range, NULL, 0, 1); - } else { - printk (KERN_WARNING PRINTK_HEADER - "/proc/dasd/devices: parse error in '%s'\n", - buffer); - } - } - } + MESSAGE (KERN_WARNING, "%s", + "/proc/dasd/devices: only 'set' ,'add' and " + "'brk' are supported verbs"); + vfree (buffer); + return -EINVAL; + } vfree (buffer); return user_len; @@ -3895,9 +4940,9 @@ } static struct file_operations dasd_devices_file_ops = { - read:dasd_generic_read, /* read */ + read:dasd_generic_read, /* read */ write:dasd_devices_write, /* write */ - open:dasd_devices_open, /* open */ + open:dasd_devices_open, /* open */ release:dasd_devices_close, /* close */ }; @@ -3914,22 +4959,41 @@ MOD_INC_USE_COUNT; info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t)); + if (info == NULL) { - printk (KERN_WARNING "No memory available for data\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory available for data (tempinfo)"); + MOD_DEC_USE_COUNT; return -ENOMEM; } else { file->private_data = (void *) info; } - info->data = (char *) vmalloc (PAGE_SIZE); /* FIXME! determine space needed in a better way */ + /* FIXME! determine space needed in a better way */ + info->data = (char *) vmalloc (PAGE_SIZE); + if (info->data == NULL) { - printk (KERN_WARNING "No memory available for data\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory available for data (info->data)"); + vfree (info); file->private_data = NULL; MOD_DEC_USE_COUNT; return -ENOMEM; } + /* check for active profiling */ + if (dasd_profile_level == DASD_PROFILE_OFF) { + + info->len = sprintf (info->data, + "Statistics are off - they might be " + "switched on using 'echo set on > " + "/proc/dasd/statistics'\n"); + return rc; + } + /* prevent couter 'ouverflow' on output */ for (shift = 0, help = dasd_global_profile.dasd_io_reqs; help > 9999999; help = help >> 1, shift++) ; @@ -3958,7 +5022,15 @@ } len += sprintf (info->data + len, "\n"); - len += sprintf (info->data + len, "Histogram of I/O times (microseconds)\n"); + for (; i < 32; i++) { + len += sprintf (info->data + len, "%7d ", + dasd_global_profile.dasd_io_secs[i] >> shift); + } + len += sprintf (info->data + len, "\n"); + + len += sprintf (info->data + len, + "Histogram of I/O times (microseconds)\n"); + for (i = 0; i < 16; i++) { len += sprintf (info->data + len, "%7d ", dasd_global_profile.dasd_io_times[i] >> shift); @@ -4008,7 +5080,9 @@ len += sprintf (info->data + len, "\n"); len += sprintf (info->data + len, - "Histogram of I/O time between ssch and irq per sector\n"); + "Histogram of I/O time between ssch and irq per " + "sector\n"); + for (i = 0; i < 16; i++) { len += sprintf (info->data + len, "%7d ", dasd_global_profile.dasd_io_time2ps[i] >> shift); @@ -4064,23 +5138,89 @@ if (buffer == NULL) return -ENOMEM; + if (copy_from_user (buffer, user_buf, user_len)) { vfree (buffer); return -EFAULT; } + buffer[user_len] = 0; - printk (KERN_INFO PRINTK_HEADER "/proc/dasd/statictics: '%s'\n", - buffer); - if (strncmp (buffer, "reset", 4)) { - memset (&dasd_global_profile, 0, sizeof (dasd_profile_info_t)); + + MESSAGE (KERN_INFO, + "/proc/dasd/statictics: '%s'", + buffer); + +#ifdef DASD_PROFILE + /* check for valid verbs */ + if (strncmp (buffer, "reset", 5) && + strncmp (buffer, "set ", 4) ) { + + MESSAGE (KERN_WARNING, "%s", + "/proc/dasd/statistics: only 'set' and " + "'reset' are supported verbs"); + + return -EINVAL; } + + if (!strncmp (buffer, "reset", 5)) { + + /* reset the statistics */ + memset (&dasd_global_profile, + 0, + sizeof (dasd_profile_info_t)); + + MESSAGE (KERN_INFO, "%s", + "Statictics reset"); + + } else { + + /* 'set xxx' was given */ + int offset = 4; + + while (buffer[offset] && !isalnum (buffer[offset])) + offset++; + + if (!strncmp (buffer + offset, "on", 2)) { + + /* switch on statistics profiling */ + dasd_profile_level = DASD_PROFILE_ON; + + MESSAGE (KERN_INFO, "%s", + "Statictics switched on"); + + } else if (!strncmp (buffer + offset, "off", 3)) { + + /* switch off and reset statistics profiling */ + memset (&dasd_global_profile, + 0, + sizeof (dasd_profile_info_t)); + + dasd_profile_level = DASD_PROFILE_OFF; + + MESSAGE (KERN_INFO, "%s", + "Statictics switched off"); + + } else { + + MESSAGE (KERN_WARNING, "%s", + "/proc/dasd/statistics: only 'set on' and " + "'set off' are supported verbs"); + } + } +#else + MESSAGE (KERN_WARNING, "%s", + "/proc/dasd/statistics: is not activated in this " + "kernel"); + + +#endif /* DASD_PROFILE */ return user_len; } static struct file_operations dasd_statistics_file_ops = { - read:dasd_generic_read, /* read */ - open:dasd_statistics_open, /* open */ + read:dasd_generic_read, /* read */ write:dasd_statistics_write, /* write */ + open:dasd_statistics_open, /* open */ release:dasd_devices_close, /* close */ }; @@ -4113,6 +5253,11 @@ remove_proc_entry ("dasd", &proc_root); } +#endif /* CONFIG_PROC_FS */ + +/******************************************************************************** + * SECTION: Initializing the driver + ********************************************************************************/ int dasd_request_module ( void *name ) { int rc = -ERESTARTSYS; @@ -4124,16 +5269,17 @@ } while ( (rc=request_module(name)) != 0 ) { DECLARE_WAIT_QUEUE_HEAD(wait); - printk ( KERN_INFO "request_module returned %d for %s\n", + + MESSAGE (KERN_INFO, + "request_module returned %d for %s", rc, (char*)name); + sleep_on_timeout(&wait,5* HZ); /* wait in steps of 5 seconds */ } return rc; } - -/* SECTION: Initializing the driver */ int __init dasd_init (void) { @@ -4142,40 +5288,56 @@ major_info_t *major_info = NULL; struct list_head *l; - printk (KERN_INFO PRINTK_HEADER "initializing...\n"); - dasd_debug_area = debug_register (DASD_NAME, 0, 2, 5 * sizeof (long)); - debug_register_view (dasd_debug_area, &debug_sprintf_view); - debug_register_view (dasd_debug_area, &debug_hex_ascii_view); + MESSAGE (KERN_INFO, "%s", + "initializing..."); init_waitqueue_head (&dasd_init_waitq); + /* register 'common' DASD debug area, used faor all DBF_XXX calls*/ + dasd_debug_area = debug_register (DASD_NAME, + 0, /* size of debug area */ + 2, /* number of areas */ + 8 * sizeof (long)); + + debug_register_view (dasd_debug_area, + &debug_sprintf_view); + if (dasd_debug_area == NULL) { goto failed; } - DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", - "ENTRY"); - dasd_devfs_handle = devfs_mk_dir (NULL, DASD_NAME, NULL); + + debug_set_level (dasd_debug_area, + DBF_ERR); + + DBF_EVENT (DBF_EMERG, "%s", + "debug area created"); + + dasd_devfs_handle = devfs_mk_dir (NULL, + DASD_NAME, + NULL); + if (dasd_devfs_handle < 0) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", - "no devfs"); + + DBF_EVENT (DBF_ALERT, "%s", + "no devfs"); goto failed; } - list_for_each (l, &dasd_major_info[0].list) { + + list_add_tail(&dasd_major_static.list, &dasd_major_info); + list_for_each (l, &dasd_major_info) { major_info = list_entry (l, major_info_t, list); if ((rc = dasd_register_major (major_info)) > 0) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "major %d: success", - major_info->gendisk.major); - printk (KERN_INFO PRINTK_HEADER - "Registered successfully to major no %u\n", - major_info->gendisk.major); + + MESSAGE (KERN_INFO, + "Registered successfully to major no %u", + major_info->gendisk.major); } else { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "major %d: failed", - major_info->gendisk.major); - printk (KERN_WARNING PRINTK_HEADER - "Couldn't register successfully to major no %d\n", - major_info->gendisk.major); + + MESSAGE (KERN_WARNING, + "Couldn't register successfully to " + "major no %d", + major_info->gendisk.major); + /* revert registration of major infos */ goto failed; } @@ -4185,18 +5347,24 @@ #endif /* ! MODULE */ rc = dasd_parse (dasd); if (rc) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", - "invalid range found"); + + DBF_EVENT (DBF_ALERT, "%s", + "invalid range found"); goto failed; } +#ifdef CONFIG_PROC_FS rc = dasd_proc_init (); if (rc) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", "no proc-FS"); + + DBF_EVENT (DBF_ALERT, "%s", + "no proc-FS"); goto failed; } +#endif /* CONFIG_PROC_FS */ + genhd_dasd_name = dasd_device_name; - genhd_dasd_ioctl = dasd_ioctl; + genhd_dasd_ioctl = dasd_ioctl; if (dasd_autodetect) { /* update device range to all devices */ for (irq = get_irq_first (); irq != -ENODEV; @@ -4204,10 +5372,14 @@ int devno = get_devno_by_irq (irq); int index = dasd_devindex_from_devno (devno); if (index == -ENODEV) { /* not included in ranges */ - DASD_DRIVER_DEBUG_EVENT (2, dasd_init, - "add %04x to range", - devno); - dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES); + + DBF_EVENT (DBF_CRIT, + "add %04x to range", + devno); + + dasd_add_range (devno, + devno, + DASD_FEATURE_DEFAULT); } } } @@ -4216,15 +5388,15 @@ #ifdef CONFIG_DASD_DIAG rc = dasd_diag_init (); if (rc == 0) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "DIAG discipline %s", - "success"); - printk (KERN_INFO PRINTK_HEADER - "Registered DIAG discipline successfully\n"); + + MESSAGE (KERN_INFO, "%s", + "Registered DIAG discipline successfully"); + } else { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "DIAG discipline %s", - "failed"); + + DBF_EVENT (DBF_ALERT, "%s", + "Register DIAG discipline failed"); + goto failed; } #endif /* CONFIG_DASD_DIAG */ @@ -4235,13 +5407,14 @@ #ifdef CONFIG_DASD_ECKD rc = dasd_eckd_init (); if (rc == 0) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "ECKD discipline %s", "success"); - printk (KERN_INFO PRINTK_HEADER - "Registered ECKD discipline successfully\n"); + + MESSAGE (KERN_INFO, "%s", + "Registered ECKD discipline successfully"); } else { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "ECKD discipline %s", "failed"); + + DBF_EVENT (DBF_ALERT, "%s", + "Register ECKD discipline failed"); + goto failed; } #endif /* CONFIG_DASD_ECKD */ @@ -4251,14 +5424,14 @@ #ifdef CONFIG_DASD_FBA rc = dasd_fba_init (); if (rc == 0) { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "FBA discipline %s", "success"); - - printk (KERN_INFO PRINTK_HEADER - "Registered FBA discipline successfully\n"); + + MESSAGE (KERN_INFO, "%s", + "Registered FBA discipline successfully"); } else { - DASD_DRIVER_DEBUG_EVENT (1, dasd_init, - "FBA discipline %s", "failed"); + + DBF_EVENT (DBF_ALERT, "%s", + "Register FBA discipline failed"); + goto failed; } #endif /* CONFIG_DASD_FBA */ @@ -4276,12 +5449,16 @@ rc = 0; goto out; failed: - printk (KERN_INFO PRINTK_HEADER - "initialization not performed due to errors\n"); + + MESSAGE (KERN_INFO, "%s", + "initialization not performed due to errors"); + cleanup_dasd (); out: - DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", "LEAVE"); - printk (KERN_INFO PRINTK_HEADER "initialization finished\n"); + + MESSAGE (KERN_INFO, "%s", + "initialization finished"); + return rc; } @@ -4293,57 +5470,60 @@ struct list_head *l,*n; dasd_range_t *range; - printk (KERN_INFO PRINTK_HEADER "shutting down\n"); - DASD_DRIVER_DEBUG_EVENT(0,"cleanup_dasd","%s","ENTRY"); - dasd_disable_ranges (&dasd_range_head, NULL, 1, 1); - if (MACHINE_IS_VM) { + MESSAGE (KERN_INFO, "%s", + "shutting down"); + + dasd_disable_ranges (&dasd_range_head, + NULL, 1, 1); + #ifdef CONFIG_DASD_DIAG + if (MACHINE_IS_VM) { dasd_diag_cleanup (); - DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd", - "DIAG discipline %s", "success"); - printk (KERN_INFO PRINTK_HEADER - "De-Registered DIAG discipline successfully\n"); -#endif /* CONFIG_DASD_ECKD_BUILTIN */ + + MESSAGE (KERN_INFO, "%s", + "De-Registered DIAG discipline successfully"); } +#endif /* CONFIG_DASD_DIAG */ + #ifdef CONFIG_DASD_FBA dasd_fba_cleanup (); - DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd", - "FBA discipline %s", "success"); - printk (KERN_INFO PRINTK_HEADER - "De-Registered FBA discipline successfully\n"); -#endif /* CONFIG_DASD_ECKD_BUILTIN */ + + MESSAGE (KERN_INFO, "%s", + "De-Registered FBA discipline successfully"); +#endif /* CONFIG_DASD_FBA */ + #ifdef CONFIG_DASD_ECKD dasd_eckd_cleanup (); - DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd", - "ECKD discipline %s", "success"); - printk (KERN_INFO PRINTK_HEADER - "De-Registered ECKD discipline successfully\n"); -#endif /* CONFIG_DASD_ECKD_BUILTIN */ - genhd_dasd_name = NULL; - genhd_dasd_ioctl = NULL; + MESSAGE (KERN_INFO, "%s", + "De-Registered ECKD discipline successfully"); +#endif /* CONFIG_DASD_ECKD */ + + genhd_dasd_name = NULL; + genhd_dasd_ioctl = NULL; + +#ifdef CONFIG_PROC_FS dasd_proc_cleanup (); +#endif /* CONFIG_PROC_FS */ - list_for_each_safe (l, n, &dasd_major_info[0].list) { + list_for_each_safe (l, n, &dasd_major_info) { major_info = list_entry (l, major_info_t, list); for (i = 0; i < DASD_PER_MAJOR; i++) { kfree (major_info->dasd_device[i]); } if ((major_info->flags & DASD_MAJOR_INFO_REGISTERED) && (rc = dasd_unregister_major (major_info)) == 0) { - DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd", - "major %d: success", - major_info->gendisk.major); - printk (KERN_INFO PRINTK_HEADER - "Unregistered successfully from major no %u\n", + + MESSAGE (KERN_INFO, + "Unregistered successfully from major no %u", major_info->gendisk.major); } else { - DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd", - "major %d: failed", - major_info->gendisk.major); - printk (KERN_WARNING PRINTK_HEADER - "Couldn't unregister successfully from major no %d rc = %d\n", - major_info->gendisk.major, rc); + + MESSAGE (KERN_WARNING, + "Couldn't unregister successfully from major " + "no %d rc = %d", + major_info->gendisk.major, + rc); } } list_for_each_safe (l, n, &dasd_range_head.list) { @@ -4360,10 +5540,14 @@ #endif /* MODULE */ if (dasd_devfs_handle) devfs_unregister(dasd_devfs_handle); - if (dasd_debug_area != NULL ) + + if (dasd_debug_area != NULL ) { debug_unregister(dasd_debug_area); - printk (KERN_INFO PRINTK_HEADER "shutdown completed\n"); - DASD_DRIVER_DEBUG_EVENT(0,"cleanup_dasd","%s","LEAVE"); + dasd_debug_area = NULL; + } + + MESSAGE (KERN_INFO, "%s", + "shutdown completed"); } #ifdef MODULE diff -urN linux-2.4.21/drivers/s390/block/dasd_3990_erp.c linux-2.4.22/drivers/s390/block/dasd_3990_erp.c --- linux-2.4.21/drivers/s390/block/dasd_3990_erp.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd_3990_erp.c 2003-08-25 04:44:42.000000000 -0700 @@ -5,6 +5,8 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * + * $Revision: 1.50 $ + * * History of changes: * 05/14/01 fixed PL030160GTO (BUG() in erp_action_5) */ @@ -41,7 +43,9 @@ char *nl, *end_cqr, *begin, - *end; + *end, + buffer[80]; + /* dump sense data */ if (device->discipline && @@ -54,83 +58,130 @@ /* log the channel program */ while (loop_cqr != NULL) { - DASD_MESSAGE (KERN_ERR, device, - "(%s) ERP chain report for req: %p", - caller == 0 ? "EXAMINE" : "ACTION", - loop_cqr); + DEV_MESSAGE (KERN_ERR, device, + "(%s) ERP chain report for req: %p", + caller == 0 ? "EXAMINE" : "ACTION", + loop_cqr); nl = (char *) loop_cqr; end_cqr = nl + sizeof (ccw_req_t); while (nl < end_cqr) { + + sprintf (buffer, + "%p: %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x", + nl, + nl[0], nl[1], nl[2], nl[3], + nl[4], nl[5], nl[6], nl[7], + nl[8], nl[9], nl[10], nl[11], + nl[12], nl[13], nl[14], nl[15]); + + DEV_MESSAGE (KERN_ERR, device, "%s", + buffer); - DASD_MESSAGE (KERN_ERR, device, - "%p: %02x%02x%02x%02x %02x%02x%02x%02x " - "%02x%02x%02x%02x %02x%02x%02x%02x", - nl, - nl[0], nl[1], nl[2], nl[3], - nl[4], nl[5], nl[6], nl[7], - nl[8], nl[9], nl[10], nl[11], - nl[12], nl[13], nl[14], nl[15]); nl +=16; } - + + DEV_MESSAGE (KERN_ERR, device, + "DATA area is at: %p", + loop_cqr->data); + + nl = (char *) loop_cqr->data; + end_cqr = nl + loop_cqr->datasize; + + while (nl < end_cqr) { + + sprintf (buffer, + "%p: %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x", + nl, + nl[0], nl[1], nl[2], nl[3], + nl[4], nl[5], nl[6], nl[7], + nl[8], nl[9], nl[10], nl[11], + nl[12], nl[13], nl[14], nl[15]); + + DEV_MESSAGE (KERN_ERR, device, "%s", + buffer); + + nl +=16; + } + nl = (char *) loop_cqr->cpaddr; if (loop_cqr->cplength > 40) { /* log only parts of the CP */ - DASD_MESSAGE (KERN_ERR, device, "%s", + DEV_MESSAGE (KERN_ERR, device, "%s", "Start of channel program:"); for (i = 0; i < 20; i += 2) { - DASD_MESSAGE (KERN_ERR, device, - "%p: %02x%02x%02x%02x %02x%02x%02x%02x " - "%02x%02x%02x%02x %02x%02x%02x%02x", - nl, - nl[0], nl[1], nl[2], nl[3], - nl[4], nl[5], nl[6], nl[7], - nl[8], nl[9], nl[10], nl[11], - nl[12], nl[13], nl[14], nl[15]); + sprintf (buffer, + "%p: %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x", + nl, + nl[0], nl[1], nl[2], nl[3], + nl[4], nl[5], nl[6], nl[7], + nl[8], nl[9], nl[10], nl[11], + nl[12], nl[13], nl[14], nl[15]); + DEV_MESSAGE (KERN_ERR, device, "%s", + buffer); + nl += 16; } - DASD_MESSAGE (KERN_ERR, device, "%s", - "End of channel program:"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "End of channel program:"); nl = (char *) loop_cqr->cpaddr; nl += ((loop_cqr->cplength - 10) * 8); for (i = 0; i < 20; i += 2) { - DASD_MESSAGE (KERN_ERR, device, - "%p: %02x%02x%02x%02x %02x%02x%02x%02x " - "%02x%02x%02x%02x %02x%02x%02x%02x", - nl, - nl[0], nl[1], nl[2], nl[3], - nl[4], nl[5], nl[6], nl[7], - nl[8], nl[9], nl[10], nl[11], - nl[12], nl[13], nl[14], nl[15]); + sprintf (buffer, + "%p: %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x", + nl, + nl[0], nl[1], nl[2], nl[3], + nl[4], nl[5], nl[6], nl[7], + nl[8], nl[9], nl[10], nl[11], + nl[12], nl[13], nl[14], nl[15]); + + DEV_MESSAGE (KERN_ERR, device, "%s", + buffer); nl += 16; } } else { /* log the whole CP */ - DASD_MESSAGE (KERN_ERR, device, "%s", + DEV_MESSAGE (KERN_ERR, device, "%s", "Channel program (complete):"); for (i = 0; i < (loop_cqr->cplength + 4); i += 2) { - DASD_MESSAGE (KERN_ERR, device, - "%p: %02x%02x%02x%02x %02x%02x%02x%02x " - "%02x%02x%02x%02x %02x%02x%02x%02x", - nl, - nl[0], nl[1], nl[2], nl[3], - nl[4], nl[5], nl[6], nl[7], - nl[8], nl[9], nl[10], nl[11], - nl[12], nl[13], nl[14], nl[15]); + sprintf (buffer, + "%p: %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x", + nl, + nl[0], nl[1], nl[2], nl[3], + nl[4], nl[5], nl[6], nl[7], + nl[8], nl[9], nl[10], nl[11], + nl[12], nl[13], nl[14], nl[15]); + + DEV_MESSAGE (KERN_ERR, device, "%s", + buffer); nl += 16; } @@ -150,29 +201,34 @@ nl -= 10*8; /* start some bytes before */ - DASD_MESSAGE (KERN_ERR, device, - "Failed CCW (%p) (area):", - (void *)(long)cpa); + DEV_MESSAGE (KERN_ERR, device, + "Failed CCW (%p) (area):", + (void *)(long)cpa); for (i = 0; i < 20; i += 2) { - DASD_MESSAGE (KERN_ERR, device, - "%p: %02x%02x%02x%02x %02x%02x%02x%02x " - "%02x%02x%02x%02x %02x%02x%02x%02x", - nl, - nl[0], nl[1], nl[2], nl[3], - nl[4], nl[5], nl[6], nl[7], - nl[8], nl[9], nl[10], nl[11], - nl[12], nl[13], nl[14], nl[15]); + sprintf (buffer, + "%p: %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x" + " %02x%02x%02x%02x", + nl, + nl[0], nl[1], nl[2], nl[3], + nl[4], nl[5], nl[6], nl[7], + nl[8], nl[9], nl[10], nl[11], + nl[12], nl[13], nl[14], nl[15]); + + DEV_MESSAGE (KERN_ERR, device, "%s", + buffer); nl += 16; } } else { - DASD_MESSAGE (KERN_ERR, device, - "Failed CCW (%p) already logged", - (void *)(long)cpa); + DEV_MESSAGE (KERN_ERR, device, + "Failed CCW (%p) already logged", + (void *)(long)cpa); } } @@ -216,9 +272,9 @@ if (( sense[0] & SNS0_CMD_REJECT ) && (!(sense[2] & SNS2_ENV_DATA_PRESENT)) ) { - DASD_MESSAGE (KERN_ERR, device, "%s", - "EXAMINE 24: Command Reject detected - " - "fatal error"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "EXAMINE 24: Command Reject detected - " + "fatal error"); return dasd_era_fatal; } @@ -227,9 +283,9 @@ if (( sense[1] & SNS1_INV_TRACK_FORMAT ) && (!(sense[2] & SNS2_ENV_DATA_PRESENT)) ) { - DASD_MESSAGE (KERN_ERR, device, "%s", - "EXAMINE 24: Invalid Track Format detected " - "- fatal error"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "EXAMINE 24: Invalid Track Format detected " + "- fatal error"); return dasd_era_fatal; } @@ -237,10 +293,10 @@ /* check for 'No Record Found' */ if (sense[1] & SNS1_NO_REC_FOUND) { - DASD_MESSAGE (KERN_ERR, device, - "EXAMINE 24: No Record Found detected %s", - cqr == device->init_cqr ? " " : - "- fatal error"); + DEV_MESSAGE (KERN_ERR, device, + "EXAMINE 24: No Record Found detected %s", + cqr == device->init_cqr ? " " : + "- fatal error"); return dasd_era_fatal; } @@ -274,8 +330,9 @@ return dasd_era_none; case 0x01: - DASD_MESSAGE (KERN_ERR, device, "%s", - "EXAMINE 32: fatal error"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "EXAMINE 32: fatal error"); + return dasd_era_fatal; default: @@ -405,20 +462,24 @@ dasd_device_t *device = erp->device; - DASD_MESSAGE (KERN_INFO, device, - "blocking request queue for %is", - (int) expires); + DEV_MESSAGE (KERN_INFO, device, + "blocking request queue for %is", + (int) expires); check_then_set (&erp->status, CQR_STATUS_ERROR, CQR_STATUS_PENDING); /* restart queue after some time */ - device->timer.function = dasd_3990_erp_restart_queue; - device->timer.data = (unsigned long) erp; - device->timer.expires = jiffies + (expires * HZ); - - add_timer(&device->timer); + if (!timer_pending(&device->blocking_timer)) { + init_timer(&device->blocking_timer); + device->blocking_timer.function = dasd_3990_erp_restart_queue; + device->blocking_timer.data = (unsigned long) erp; + device->blocking_timer.expires = jiffies + (expires * HZ); + add_timer(&device->blocking_timer); + } else { + mod_timer(&device->blocking_timer, jiffies + (expires * HZ)); + } } /* end dasd_3990_erp_block_queue */ @@ -453,8 +514,8 @@ /* 'restart' the device queue */ if (cqr->status == CQR_STATUS_PENDING) { - DASD_MESSAGE (KERN_INFO, device, "%s", - "request queue restarted by MIH"); + DEV_MESSAGE (KERN_INFO, device, "%s", + "request queue restarted by MIH"); check_then_set (&cqr->status, CQR_STATUS_PENDING, @@ -498,9 +559,9 @@ } else { /* issue a message and wait for 'device ready' interrupt */ - DASD_MESSAGE (KERN_ERR, device, "%s", - "is offline or not installed - " - "INTERVENTION REQUIRED!!"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "is offline or not installed - " + "INTERVENTION REQUIRED!!"); dasd_3990_erp_block_queue (erp, 60); @@ -538,11 +599,11 @@ if ((erp->lpm & ioinfo[irq]->opm) != 0x00) { - DASD_MESSAGE (KERN_DEBUG, device, - "try alternate lpm=%x (lpum=%x / opm=%x)", - erp->lpm, - erp->dstat->lpum, - ioinfo[irq]->opm); + DEV_MESSAGE (KERN_DEBUG, device, + "try alternate lpm=%x (lpum=%x / opm=%x)", + erp->lpm, + erp->dstat->lpum, + ioinfo[irq]->opm); /* reset status to queued to handle the request again... */ check_then_set (&erp->status, @@ -553,11 +614,11 @@ } else { - DASD_MESSAGE (KERN_ERR, device, - "No alternate channel path left (lpum=%x / " - "opm=%x) -> permanent error", - erp->dstat->lpum, - ioinfo[irq]->opm); + DEV_MESSAGE (KERN_ERR, device, + "No alternate channel path left (lpum=%x / " + "opm=%x) -> permanent error", + erp->dstat->lpum, + ioinfo[irq]->opm); /* post request with permanent error */ check_then_set (&erp->status, @@ -598,8 +659,8 @@ if (!dctl_cqr) { - DASD_MESSAGE (KERN_ERR, device, "%s", - "Unable to allocate DCTL-CQR"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Unable to allocate DCTL-CQR"); check_then_set (&erp->status, CQR_STATUS_ERROR, @@ -620,8 +681,9 @@ if (dasd_set_normalized_cda(ccw, __pa (DCTL_data), dctl_cqr, erp->device)) { dasd_free_request (dctl_cqr, erp->device); - DASD_MESSAGE (KERN_ERR, device, "%s", - "Unable to allocate DCTL-CQR"); + + DEV_MESSAGE (KERN_ERR, device, "%s", + "Unable to allocate DCTL-CQR"); check_then_set (&erp->status, CQR_STATUS_ERROR, @@ -635,7 +697,8 @@ dctl_cqr->lpm = LPM_ANYPATH; dctl_cqr->expires = 5 * TOD_MIN; dctl_cqr->retries = 2; - asm volatile ("STCK %0":"=m" (dctl_cqr->buildclk)); + + dctl_cqr->buildclk = get_clock (); dctl_cqr->status = CQR_STATUS_FILLED; @@ -706,17 +769,16 @@ } else { - if (sense[25] & 0x1D) { /* state change pending */ + if (sense[25] == 0x1D) { /* state change pending */ - DASD_MESSAGE (KERN_INFO, device, "%s", - "waiting for state change pending " - "int"); + DEV_MESSAGE (KERN_INFO, device, "%s", + "waiting for state change pending " + "int"); dasd_3990_erp_block_queue (erp, 30); - } else { - + DEV_MESSAGE (KERN_INFO, device, "redriving request immediately, %d retries left", erp->retries); /* no state change pending - retry */ check_then_set (&erp->status, CQR_STATUS_ERROR, @@ -793,98 +855,98 @@ case 0x00: /* No Message */ break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Invalid Command"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Invalid Command"); break; case 0x02: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Invalid Command " - "Sequence"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Invalid Command " + "Sequence"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - CCW Count less than " - "required"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - CCW Count less than " + "required"); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Invalid Parameter"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Invalid Parameter"); break; case 0x05: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Diagnostic of Sepecial" - " Command Violates File Mask"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Diagnostic of Sepecial" + " Command Violates File Mask"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Channel Returned with " - "Incorrect retry CCW"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Channel Returned with " + "Incorrect retry CCW"); break; case 0x08: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Reset Notification"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Reset Notification"); break; case 0x09: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Storage Path Restart"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Storage Path Restart"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, - "FORMAT 0 - Channel requested " - "... %02x", - sense[8]); + DEV_MESSAGE (KERN_WARNING, device, + "FORMAT 0 - Channel requested " + "... %02x", + sense[8]); break; case 0x0B: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Invalid Defective/" - "Alternate Track Pointer"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Invalid Defective/" + "Alternate Track Pointer"); break; case 0x0C: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - DPS Installation " - "Check"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - DPS Installation " + "Check"); break; case 0x0E: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Command Invalid on " - "Secondary Address"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Command Invalid on " + "Secondary Address"); break; case 0x0F: - DASD_MESSAGE (KERN_WARNING, device, - "FORMAT 0 - Status Not As " - "Required: reason %02x", - sense[8]); + DEV_MESSAGE (KERN_WARNING, device, + "FORMAT 0 - Status Not As " + "Required: reason %02x", + sense[8]); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Reseved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Reseved"); } } else { switch (msg_no) { case 0x00: /* No Message */ break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Device Error Source"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Device Error Source"); break; case 0x02: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Reserved"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, - "FORMAT 0 - Device Fenced - " - "device = %02x", - sense[4]); + DEV_MESSAGE (KERN_WARNING, device, + "FORMAT 0 - Device Fenced - " + "device = %02x", + sense[4]); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Data Pinned for " - "Device"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Data Pinned for " + "Device"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 0 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 0 - Reserved"); } } break; @@ -894,348 +956,348 @@ case 0x00: /* No Message */ break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Device Status 1 not as " - "expected"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Device Status 1 not as " + "expected"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Index missing"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Index missing"); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Interruption cannot be reset"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Interruption cannot be reset"); break; case 0x05: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Device did not respond to " - "selection"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Device did not respond to " + "selection"); break; case 0x06: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Device check-2 error or Set " - "Sector is not complete"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Device check-2 error or Set " + "Sector is not complete"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Head address does not " - "compare"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Head address does not " + "compare"); break; case 0x08: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Device status 1 not valid"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Device status 1 not valid"); break; case 0x09: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Device not ready"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Device not ready"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Track physical address did " - "not compare"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Track physical address did " + "not compare"); break; case 0x0B: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Missing device address bit"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Missing device address bit"); break; case 0x0C: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Drive motor switch is off"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Drive motor switch is off"); break; case 0x0D: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Seek incomplete"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Seek incomplete"); break; case 0x0E: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Cylinder address did not " - "compare"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Cylinder address did not " + "compare"); break; case 0x0F: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Offset active cannot be " - "reset"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Offset active cannot be " + "reset"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 1 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 1 - Reserved"); } break; case 0x20: /* Format 2 - 3990 Equipment Checks */ switch (msg_no) { case 0x08: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 2 - 3990 check-2 error"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 2 - 3990 check-2 error"); break; case 0x0E: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 2 - Support facility errors"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 2 - Support facility errors"); break; case 0x0F: - DASD_MESSAGE (KERN_WARNING, device, - "FORMAT 2 - Microcode detected error %02x", - sense[8]); + DEV_MESSAGE (KERN_WARNING, device, + "FORMAT 2 - Microcode detected error %02x", + sense[8]); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 2 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 2 - Reserved"); } break; case 0x30: /* Format 3 - 3990 Control Checks */ switch (msg_no) { case 0x0F: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 3 - Allegiance terminated"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 3 - Allegiance terminated"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 3 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 3 - Reserved"); } break; case 0x40: /* Format 4 - Data Checks */ switch (msg_no) { case 0x00: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Home address area error"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Home address area error"); break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Count area error"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Count area error"); break; case 0x02: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Key area error"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Key area error"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Data area error"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Data area error"); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No sync byte in home address " + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No sync byte in home address " "area"); break; case 0x05: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No sync byte in count address " - "area"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No sync byte in count address " + "area"); break; case 0x06: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No sync byte in key area"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No sync byte in key area"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No sync byte in data area"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No sync byte in data area"); break; case 0x08: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Home address area error; " - "offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Home address area error; " + "offset active"); break; case 0x09: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Count area error; offset " - "active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Count area error; offset " + "active"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Key area error; offset " - "active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Key area error; offset " + "active"); break; case 0x0B: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Data area error; " - "offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Data area error; " + "offset active"); break; case 0x0C: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No sync byte in home " - "address area; offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No sync byte in home " + "address area; offset active"); break; case 0x0D: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No syn byte in count " - "address area; offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No syn byte in count " + "address area; offset active"); break; case 0x0E: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No sync byte in key area; " - "offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No sync byte in key area; " + "offset active"); break; case 0x0F: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - No syn byte in data area; " - "offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - No syn byte in data area; " + "offset active"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 4 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 4 - Reserved"); } break; case 0x50: /* Format 5 - Data Check with displacement information */ switch (msg_no) { case 0x00: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the " - "home address area"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the " + "home address area"); break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the count area"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the count area"); break; case 0x02: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the key area"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the key area"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the data area"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the data area"); break; case 0x08: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the " - "home address area; offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the " + "home address area; offset active"); break; case 0x09: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the count area; " - "offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the count area; " + "offset active"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the key area; " - "offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the key area; " + "offset active"); break; case 0x0B: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Data Check in the data area; " - "offset active"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Data Check in the data area; " + "offset active"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 5 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 5 - Reserved"); } break; case 0x60: /* Format 6 - Usage Statistics/Overrun Errors */ switch (msg_no) { case 0x00: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel A"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel A"); break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel B"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel B"); break; case 0x02: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel C"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel C"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel D"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel D"); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel E"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel E"); break; case 0x05: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel F"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel F"); break; case 0x06: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel G"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel G"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Overrun on channel H"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Overrun on channel H"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 6 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 6 - Reserved"); } break; case 0x70: /* Format 7 - Device Connection Control Checks */ switch (msg_no) { case 0x00: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - RCC initiated by a connection " - "check alert"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - RCC initiated by a connection " + "check alert"); break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - RCC 1 sequence not " - "successful"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - RCC 1 sequence not " + "successful"); break; case 0x02: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - RCC 1 and RCC 2 sequences not " - "successful"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - RCC 1 and RCC 2 sequences not " + "successful"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Invalid tag-in during " - "selection sequence"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Invalid tag-in during " + "selection sequence"); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - extra RCC required"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - extra RCC required"); break; case 0x05: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Invalid DCC selection " - "response or timeout"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Invalid DCC selection " + "response or timeout"); break; case 0x06: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Missing end operation; device " - "transfer complete"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Missing end operation; device " + "transfer complete"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Missing end operation; device " - "transfer incomplete"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Missing end operation; device " + "transfer incomplete"); break; case 0x08: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Invalid tag-in for an " - "immediate command sequence"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Invalid tag-in for an " + "immediate command sequence"); break; case 0x09: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Invalid tag-in for an " - "extended command sequence"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Invalid tag-in for an " + "extended command sequence"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - 3990 microcode time out when " - "stopping selection"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - 3990 microcode time out when " + "stopping selection"); break; case 0x0B: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - No response to selection " - "after a poll interruption"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - No response to selection " + "after a poll interruption"); break; case 0x0C: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Permanent path error (DASD " - "controller not available)"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Permanent path error (DASD " + "controller not available)"); break; case 0x0D: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - DASD controller not available" - " on disconnected command chain"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - DASD controller not available" + " on disconnected command chain"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 7 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 7 - Reserved"); } break; @@ -1243,52 +1305,52 @@ switch (msg_no) { case 0x00: /* No Message */ case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - Error correction code " - "hardware fault"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - Error correction code " + "hardware fault"); break; case 0x03: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - Unexpected end operation " - "response code"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - Unexpected end operation " + "response code"); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - End operation with transfer " - "count not zero"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - End operation with transfer " + "count not zero"); break; case 0x05: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - End operation with transfer " - "count zero"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - End operation with transfer " + "count zero"); break; case 0x06: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - DPS checks after a system " - "reset or selective reset"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - DPS checks after a system " + "reset or selective reset"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - DPS cannot be filled"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - DPS cannot be filled"); break; case 0x08: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - Short busy time-out during " - "device selection"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - Short busy time-out during " + "device selection"); break; case 0x09: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - DASD controller failed to " - "set or reset the long busy latch"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - DASD controller failed to " + "set or reset the long busy latch"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - No interruption from device " - "during a command chain"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - No interruption from device " + "during a command chain"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 8 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 8 - Reserved"); } break; @@ -1297,94 +1359,97 @@ case 0x00: break; /* No Message */ case 0x06: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 9 - Device check-2 error"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 9 - Device check-2 error"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 9 - Head address did not compare"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 9 - Head address did not compare"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 9 - Track physical address did " - "not compare while oriented"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 9 - Track physical address did " + "not compare while oriented"); break; case 0x0E: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 9 - Cylinder address did not " - "compare"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 9 - Cylinder address did not " + "compare"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT 9 - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT 9 - Reserved"); } break; case 0xF0: /* Format F - Cache Storage Checks */ switch (msg_no) { case 0x00: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Operation Terminated"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Operation Terminated"); break; case 0x01: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Subsystem Processing Error"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Subsystem Processing Error"); break; case 0x02: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Cache or nonvolatile storage " - "equipment failure"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Cache or nonvolatile storage " + "equipment failure"); break; case 0x04: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Caching terminated"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Caching terminated"); break; case 0x06: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Cache fast write access not " - "authorized"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Cache fast write access not " + "authorized"); break; case 0x07: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Track format incorrect"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Track format incorrect"); break; case 0x09: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Caching reinitiated"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Caching reinitiated"); break; case 0x0A: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Nonvolatile storage " - "terminated"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Nonvolatile storage " + "terminated"); break; case 0x0B: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Volume is suspended duplex"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Volume is suspended duplex"); break; case 0x0C: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Subsystem status connot be " - "determined"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Subsystem status connot be " + "determined"); break; case 0x0D: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - Caching status reset to " - "default"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - Caching status reset to " + "default"); break; case 0x0E: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT F - DASD Fast Write inhibited"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT F - DASD Fast Write inhibited"); break; default: - DASD_MESSAGE (KERN_WARNING, device, "%s", - "FORMAT D - Reserved"); + DEV_MESSAGE (KERN_WARNING, device, "%s", + "FORMAT D - Reserved"); } break; default: /* unknown message format - should not happen */ - + DEV_MESSAGE (KERN_WARNING, device, + "unknown message format %02x", + msg_format); + } /* end switch message format */ - + } /* end dasd_3990_handle_env_data */ /* @@ -1412,8 +1477,8 @@ /* env data present (ACTION 10 - retry should work) */ if (sense[2] & SNS2_ENV_DATA_PRESENT) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Command Reject - environmental data present"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Command Reject - environmental data present"); dasd_3990_handle_env_data (erp, sense); @@ -1422,8 +1487,8 @@ } else { /* fatal error - set status to FAILED */ - DASD_MESSAGE (KERN_ERR, device, "%s", - "Command Reject - Fatal error"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Command Reject - Fatal error"); erp = dasd_3990_erp_cleanup (erp, CQR_STATUS_FAILED); @@ -1460,9 +1525,9 @@ } else { /* issue a message and wait for 'device ready' interrupt */ - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "bus out parity error or BOPC requested by " - "channel"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "bus out parity error or BOPC requested by " + "channel"); dasd_3990_erp_block_queue (erp, 60); @@ -1495,22 +1560,22 @@ if (sense[1] & SNS1_WRITE_INHIBITED) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Write inhibited path encountered"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Write inhibited path encountered"); /* vary path offline */ - DASD_MESSAGE (KERN_ERR, device, "%s", - "Path should be varied off-line. " - "This is not implemented yet \n - please report " - "to linux390@de.ibm.com"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Path should be varied off-line. " + "This is not implemented yet \n - please report " + "to linux390@de.ibm.com"); erp = dasd_3990_erp_action_1 (erp); } else if (sense[2] & SNS2_ENV_DATA_PRESENT) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Equipment Check - " - "environmental data present"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Equipment Check - " + "environmental data present"); dasd_3990_handle_env_data (erp, sense); @@ -1519,17 +1584,18 @@ sense); } else if (sense[1] & SNS1_PERM_ERR) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Equipment Check - retry exhausted or " - "undesirable"); + + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Equipment Check - retry exhausted or " + "undesirable"); erp = dasd_3990_erp_action_1 (erp); } else { /* all other equipment checks - Action 5 */ /* rest is done when retries == 0 */ - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Equipment check or processing error"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Equipment check or processing error"); erp = dasd_3990_erp_action_5 (erp); } @@ -1561,9 +1627,9 @@ if (sense[2] & SNS2_CORRECTABLE) { /* correctable data check */ /* issue message that the data has been corrected */ - DASD_MESSAGE (KERN_EMERG, device, "%s", - "Data recovered during retry with PCI " - "fetch mode active"); + DEV_MESSAGE (KERN_EMERG, device, "%s", + "Data recovered during retry with PCI " + "fetch mode active"); /* not possible to handle this situation in Linux */ panic("No way to inform appliction about the possibly " @@ -1571,26 +1637,26 @@ } else if (sense[2] & SNS2_ENV_DATA_PRESENT) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Uncorrectable data check recovered secondary " - "addr of duplex pair"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Uncorrectable data check recovered secondary " + "addr of duplex pair"); erp = dasd_3990_erp_action_4 (erp, sense); } else if (sense[1] & SNS1_PERM_ERR) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Uncorrectable data check with internal " - "retry exhausted"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Uncorrectable data check with internal " + "retry exhausted"); erp = dasd_3990_erp_action_1 (erp); } else { /* all other data checks */ - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Uncorrectable data check with retry count " - "exhausted..."); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Uncorrectable data check with retry count " + "exhausted..."); erp = dasd_3990_erp_action_5 (erp); } @@ -1619,9 +1685,9 @@ erp->function = dasd_3990_erp_overrun; - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Overrun - service overrun or overrun" - " error requested by channel"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Overrun - service overrun or overrun" + " error requested by channel"); erp = dasd_3990_erp_action_5 (erp); @@ -1651,9 +1717,9 @@ if (sense[2] & SNS2_ENV_DATA_PRESENT) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Track format error when destaging or " - "staging data"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Track format error when destaging or " + "staging data"); dasd_3990_handle_env_data (erp, sense); @@ -1662,9 +1728,9 @@ sense); } else { - DASD_MESSAGE (KERN_ERR, device, "%s", - "Invalid Track Format - Fatal error should have " - "been handled within the interrupt handler"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Invalid Track Format - Fatal error should have " + "been handled within the interrupt handler"); erp= dasd_3990_erp_cleanup (erp, CQR_STATUS_FAILED); @@ -1692,8 +1758,8 @@ dasd_device_t *device = default_erp->device; - DASD_MESSAGE (KERN_ERR, device, "%s", - "End-of-Cylinder - must never happen"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "End-of-Cylinder - must never happen"); /* implement action 7 - BUG */ return dasd_3990_erp_cleanup (default_erp, @@ -1721,8 +1787,8 @@ erp->function = dasd_3990_erp_env_data; - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Environmental data present"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Environmental data present"); dasd_3990_handle_env_data (erp, sense); @@ -1761,9 +1827,9 @@ dasd_device_t *device = default_erp->device; - DASD_MESSAGE (KERN_ERR, device, "%s", - "No Record Found - Fatal error should " - "have been handled within the interrupt handler"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "No Record Found - Fatal error should " + "have been handled within the interrupt handler"); return dasd_3990_erp_cleanup (default_erp, CQR_STATUS_FAILED); @@ -1789,8 +1855,8 @@ dasd_device_t *device = erp->device; - DASD_MESSAGE (KERN_ERR, device, "%s", - "File Protected"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "File Protected"); return dasd_3990_erp_cleanup (erp, CQR_STATUS_FAILED); @@ -1921,8 +1987,8 @@ erp->retries = 256; erp->function = dasd_3990_erp_action_10_32; - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Perform logging requested"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Perform logging requested"); return erp; @@ -1960,8 +2026,8 @@ char *LO_data; /* LO_eckd_data_t */ ccw1_t *ccw; - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Write not finished because of unexpected condition"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Write not finished because of unexpected condition"); default_erp->function = dasd_3990_erp_action_1B_32; @@ -1975,8 +2041,8 @@ /* for imprecise ending just do default erp */ if (sense[1] & 0x01) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Imprecise ending is set - just retry"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Imprecise ending is set - just retry"); return default_erp; } @@ -1987,9 +2053,9 @@ if (cpa == 0) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Unable to determine address of the CCW " - "to be restarted"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Unable to determine address of the CCW " + "to be restarted"); return dasd_3990_erp_cleanup (default_erp, CQR_STATUS_FAILED); @@ -2004,8 +2070,8 @@ if (!erp) { - DASD_MESSAGE (KERN_ERR, device, "%s", - "Unable to allocate ERP"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Unable to allocate ERP"); return dasd_3990_erp_cleanup (default_erp, CQR_STATUS_FAILED); @@ -2023,8 +2089,8 @@ if ((sense[3] == 0x01) && (LO_data[1] & 0x01) ){ - DASD_MESSAGE (KERN_ERR, device, "%s", - "BUG - this should not happen"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "BUG - this should not happen"); return dasd_3990_erp_cleanup (default_erp, CQR_STATUS_FAILED); @@ -2060,8 +2126,8 @@ if (dasd_set_normalized_cda (ccw, __pa (DE_data), erp, device)) { dasd_free_request (erp, device); - DASD_MESSAGE (KERN_ERR, device, "%s", - "Unable to allocate ERP"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Unable to allocate ERP"); return dasd_3990_erp_cleanup (default_erp, CQR_STATUS_FAILED); @@ -2076,8 +2142,8 @@ if (dasd_set_normalized_cda (ccw, __pa (LO_data), erp, device)){ dasd_free_request (erp, device); - DASD_MESSAGE (KERN_ERR, device, "%s", - "Unable to allocate ERP"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Unable to allocate ERP"); return dasd_3990_erp_cleanup (default_erp, CQR_STATUS_FAILED); @@ -2132,9 +2198,9 @@ char *LO_data; /* LO_eckd_data_t */ ccw1_t *ccw; - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Write not finished because of unexpected condition" - " - follow on"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Write not finished because of unexpected condition" + " - follow on"); /* determine the original cqr */ cqr = previous_erp; @@ -2146,8 +2212,8 @@ /* for imprecise ending just do default erp */ if (sense[1] & 0x01) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Imprecise ending is set - just retry"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Imprecise ending is set - just retry"); check_then_set (&previous_erp->status, CQR_STATUS_ERROR, @@ -2162,9 +2228,9 @@ if (cpa == 0) { - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "Unable to determine address of the CCW " - "to be restarted"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Unable to determine address of the CCW " + "to be restarted"); check_then_set (&previous_erp->status, CQR_STATUS_ERROR, @@ -2181,8 +2247,8 @@ if ((sense[3] == 0x01) && (LO_data[1] & 0x01) ){ - DASD_MESSAGE (KERN_ERR, device, "%s", - "BUG - this should not happen"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "BUG - this should not happen"); check_then_set (&previous_erp->status, CQR_STATUS_ERROR, @@ -2337,7 +2403,7 @@ switch (sense[28]) { case 0x17: /* issue a Diagnostic Control command with an - * Inhibit Write subcommand and controler modifier */ + * Inhibit Write subcommand and controler modifier */ erp = dasd_3990_erp_DCTL (erp, 0x20); break; @@ -2351,7 +2417,7 @@ break; default: - /* should not happen - continue */ + ; /* should not happen - continue */ } } @@ -2389,11 +2455,11 @@ /* set to suspended duplex state then restart */ dasd_device_t *device = erp->device; - DASD_MESSAGE (KERN_ERR, device, "%s", - "Set device to suspended duplex state should be " - "done!\n" - "This is not implemented yet (for compound ERP)" - " - please report to linux390@de.ibm.com"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Set device to suspended duplex state should be " + "done!\n" + "This is not implemented yet (for compound ERP)" + " - please report to linux390@de.ibm.com"); } @@ -2490,10 +2556,10 @@ switch (sense[25]) { case 0x00: /* success */ - DASD_MESSAGE (KERN_DEBUG, device, - "ERP called for successful request %p" - " - NO ERP necessary", - erp); + DEV_MESSAGE (KERN_DEBUG, device, + "ERP called for successful request %p" + " - NO ERP necessary", + erp); erp = dasd_3990_erp_cleanup (erp, CQR_STATUS_DONE); @@ -2501,9 +2567,9 @@ break; case 0x01: /* fatal error */ - DASD_MESSAGE (KERN_ERR, device, "%s", - "Fatal error should have been " - "handled within the interrupt handler"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "Fatal error should have been " + "handled within the interrupt handler"); erp = dasd_3990_erp_cleanup (erp, CQR_STATUS_FAILED); @@ -2515,12 +2581,12 @@ break; case 0x0F: /* length mismatch during update write command */ - DASD_MESSAGE (KERN_ERR, device, "%s", - "update write command error - should not " - "happen;\n" - "Please send this message together with " - "the above sense data to linux390@de." - "ibm.com"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "update write command error - should not " + "happen;\n" + "Please send this message together with " + "the above sense data to linux390@de." + "ibm.com"); erp = dasd_3990_erp_cleanup (erp, CQR_STATUS_FAILED); @@ -2532,12 +2598,12 @@ break; case 0x15: /* next track outside defined extend */ - DASD_MESSAGE (KERN_ERR, device, "%s", - "next track outside defined extend - " - "should not happen;\n" - "Please send this message together with " - "the above sense data to linux390@de." - "ibm.com"); + DEV_MESSAGE (KERN_ERR, device, "%s", + "next track outside defined extend - " + "should not happen;\n" + "Please send this message together with " + "the above sense data to linux390@de." + "ibm.com"); erp= dasd_3990_erp_cleanup (erp, CQR_STATUS_FAILED); @@ -2550,9 +2616,9 @@ break; case 0x1C: /* invalid data */ - DASD_MESSAGE (KERN_EMERG, device, "%s", - "Data recovered during retry with PCI " - "fetch mode active"); + DEV_MESSAGE (KERN_EMERG, device, "%s", + "Data recovered during retry with PCI " + "fetch mode active"); /* not possible to handle this situation in Linux */ panic("Invalid data - No way to inform appliction about " @@ -2560,16 +2626,16 @@ break; case 0x1D: /* state-change pending */ - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "A State change pending condition exists " - "for the subsystem or device"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "A State change pending condition exists " + "for the subsystem or device"); erp = dasd_3990_erp_action_4 (erp, sense); break; - default: /* all others errors - default erp */ - + default: + ; /* all others errors - default erp */ } } @@ -2642,25 +2708,47 @@ { dasd_device_t *device = cqr->device; + ccw1_t *ccw; /* allocate additional request block */ - ccw_req_t *erp = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device); + ccw_req_t *erp = dasd_alloc_request ((char *) &cqr->magic, 2, 0, cqr->device); if (!erp) { - - DASD_MESSAGE (KERN_ERR, device, "%s", - "Unable to allocate ERP request"); + if (cqr->retries <= 0) { + DEV_MESSAGE (KERN_ERR, device, "%s", + "Unable to allocate ERP request (NO retries left)"); - check_then_set (&cqr->status, - CQR_STATUS_ERROR, - CQR_STATUS_FAILED); + check_then_set (&cqr->status, + CQR_STATUS_ERROR, + CQR_STATUS_FAILED); + cqr->stopclk = get_clock (); + + } else { + DEV_MESSAGE (KERN_ERR, device, + "Unable to allocate ERP request (%i retries left)", + cqr->retries); + + if (!timer_pending(&device->timer)) { + init_timer (&device->timer); + device->timer.function = dasd_schedule_bh_timed; + device->timer.data = (unsigned long) device; + device->timer.expires = jiffies + (HZ << 3); + add_timer (&device->timer); + } else { + mod_timer(&device->timer, jiffies + (HZ << 3)); + } + } return cqr; } /* initialize request with default TIC to current ERP/CQR */ - erp->cpaddr->cmd_code = CCW_CMD_TIC; - erp->cpaddr->cda = (long)(cqr->cpaddr); + ccw = erp->cpaddr; + ccw->cmd_code = CCW_CMD_NOOP; + ccw->flags = CCW_FLAG_CC; + ccw++; + ccw->cmd_code = CCW_CMD_TIC; + ccw->cda = (long)(cqr->cpaddr); erp->function = dasd_3990_erp_add_erp; erp->refers = cqr; erp->device = cqr->device; @@ -2738,7 +2826,7 @@ } /* check sense data; byte 0-2,25,27 */ - if (!((strncmp (cqr1->dstat->ii.sense.data, + if (!((memcmp (cqr1->dstat->ii.sense.data, cqr2->dstat->ii.sense.data, 3) == 0) && (cqr1->dstat->ii.sense.data[27] == @@ -2859,10 +2947,10 @@ break; } default: - DASD_MESSAGE (KERN_DEBUG, device, - "invalid subcommand modifier 0x%x " - "for Diagnostic Control Command", - sense[25]); + DEV_MESSAGE (KERN_DEBUG, device, + "invalid subcommand modifier 0x%x " + "for Diagnostic Control Command", + sense[25]); } } @@ -2877,10 +2965,10 @@ } else { /* no retry left and no additional special handling necessary */ - DASD_MESSAGE (KERN_ERR, device, - "no retries left for erp %p - " - "set status to FAILED", - erp); + DEV_MESSAGE (KERN_ERR, device, + "no retries left for erp %p - " + "set status to FAILED", + erp); check_then_set (&erp->status, CQR_STATUS_ERROR, @@ -2940,7 +3028,7 @@ if (erp->retries > 0) { - char *sense = erp->dstat->ii.sense.data; + char *sense = erp->refers->dstat->ii.sense.data; /* check for special retries */ if (erp->function == dasd_3990_erp_action_4) { @@ -2959,10 +3047,10 @@ } else { /* simple retry */ - DASD_MESSAGE (KERN_DEBUG, device, - "%i retries left for erp %p", - erp->retries, - erp); + DEV_MESSAGE (KERN_DEBUG, device, + "%i retries left for erp %p", + erp->retries, + erp); /* handle the request again... */ check_then_set (&erp->status, @@ -3006,26 +3094,20 @@ __u32 cpa = cqr->dstat->cpa; #ifdef ERP_DEBUG - DASD_MESSAGE (KERN_DEBUG, device, - "entering 3990 ERP for " - "0x%04X on sch %d = /dev/%s ", - device->devinfo.devno, - device->devinfo.irq, - device->name); - /* print current erp_chain */ - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "ERP chain at BEGINNING of ERP-ACTION"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "ERP chain at BEGINNING of ERP-ACTION"); { ccw_req_t *temp_erp = NULL; + for (temp_erp = cqr; temp_erp != NULL; temp_erp = temp_erp->refers){ - DASD_MESSAGE (KERN_DEBUG, device, - " erp %p refers to %p", - temp_erp, - temp_erp->refers); + DEV_MESSAGE (KERN_DEBUG, device, + " erp %p refers to %p", + temp_erp, + temp_erp->refers); } } #endif /* ERP_DEBUG */ @@ -3034,10 +3116,10 @@ if ((cqr->dstat->cstat == 0x00 ) && (cqr->dstat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) ) { - DASD_MESSAGE (KERN_DEBUG, device, - "ERP called for successful request %p" - " - NO ERP necessary", - cqr); + DEV_MESSAGE (KERN_DEBUG, device, + "ERP called for successful request %p" + " - NO ERP necessary", + cqr); check_then_set (&cqr->status, CQR_STATUS_ERROR, @@ -3047,10 +3129,10 @@ } /* check if sense data are available */ if (!cqr->dstat->ii.sense.data) { - DASD_MESSAGE (KERN_DEBUG, device, - "ERP called witout sense data avail ..." - "request %p - NO ERP possible", - cqr); + DEV_MESSAGE (KERN_DEBUG, device, + "ERP called witout sense data avail ..." + "request %p - NO ERP possible", + cqr); check_then_set (&cqr->status, CQR_STATUS_ERROR, @@ -3074,18 +3156,18 @@ #ifdef ERP_DEBUG /* print current erp_chain */ - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "ERP chain at END of ERP-ACTION"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "ERP chain at END of ERP-ACTION"); { ccw_req_t *temp_erp = NULL; for (temp_erp = erp; temp_erp != NULL; temp_erp = temp_erp->refers) { - DASD_MESSAGE (KERN_DEBUG, device, - " erp %p refers to %p", - temp_erp, - temp_erp->refers); + DEV_MESSAGE (KERN_DEBUG, device, + " erp %p refers to %p", + temp_erp, + temp_erp->refers); } } #endif /* ERP_DEBUG */ @@ -3098,35 +3180,32 @@ } /* enqueue added ERP request */ - if ((erp != cqr ) && + if ((erp != device->queue.head ) && (erp->status == CQR_STATUS_FILLED) ){ dasd_chanq_enq_head (&device->queue, erp); } else { - if ((erp->status == CQR_STATUS_FILLED )|| - (erp != cqr ) ){ - /* something strange happened - log the error and throw a BUG() */ - DASD_MESSAGE (KERN_ERR, device, "%s", - "Problems with ERP chain!!! BUG"); - + if ((erp->status == CQR_STATUS_FILLED ) || (erp != device->queue.head)) { + /* something strange happened - log the error and panic */ /* print current erp_chain */ - DASD_MESSAGE (KERN_DEBUG, device, "%s", - "ERP chain at END of ERP-ACTION"); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "ERP chain at END of ERP-ACTION"); { ccw_req_t *temp_erp = NULL; for (temp_erp = erp; temp_erp != NULL; temp_erp = temp_erp->refers) { - DASD_MESSAGE (KERN_DEBUG, device, - " erp %p (function %p) refers to %p", - temp_erp, - temp_erp->function, - temp_erp->refers); + DEV_MESSAGE (KERN_DEBUG, device, + " erp %p (function %p)" + " refers to %p", + temp_erp, + temp_erp->function, + temp_erp->refers); } } - BUG(); + panic ("Problems with ERP chain!!! Please report to linux390@de.ibm.com"); } } @@ -3136,112 +3215,6 @@ } /* end dasd_3990_erp_action */ /* - * DASD_3990_ERP_POSTACTION - * - * DESCRIPTION - * Frees all ERPs of the current ERP Chain and set the status - * of the original CQR either to CQR_STATUS_DONE if ERP was successful - * or to CQR_STATUS_FAILED if ERP was NOT successful. - * - * PARAMETER - * erp current erp_head - * - * RETURN VALUES - * cqr pointer to the original CQR - */ -ccw_req_t * -dasd_3990_erp_postaction (ccw_req_t *erp) -{ - - ccw_req_t *cqr = NULL, - *free_erp = NULL; - dasd_device_t *device = erp->device; - int success; - - if (erp->refers == NULL || - erp->function == NULL ) { - - BUG (); - } - - if (erp->status == CQR_STATUS_DONE) - success = 1; - else - success = 0; - -#ifdef ERP_DEBUG - - /* print current erp_chain */ - printk (KERN_DEBUG PRINTK_HEADER - "3990 ERP postaction called for erp chain:\n"); - { - ccw_req_t *temp_erp = NULL; - - for (temp_erp = erp; - temp_erp != NULL; - temp_erp = temp_erp->refers) { - - printk (KERN_DEBUG PRINTK_HEADER - " erp %p refers to %p with erp function %p\n", - temp_erp, temp_erp->refers, temp_erp->function); - } - } - -#endif /* ERP_DEBUG */ - - /* free all ERPs - but NOT the original cqr */ - while (erp->refers != NULL) { - - free_erp = erp; - erp = erp->refers; - - /* remove the request from the device queue */ - dasd_chanq_deq (&device->queue, - free_erp); - - /* free the finished erp request */ - dasd_free_request (free_erp, free_erp->device); - } - - /* save ptr to original cqr */ - cqr = erp; - - /* set corresponding status to original cqr */ - if (success) { - - check_then_set (&cqr->status, - CQR_STATUS_ERROR, - CQR_STATUS_DONE); - } else { - - check_then_set (&cqr->status, - CQR_STATUS_ERROR, - CQR_STATUS_FAILED); - } - -#ifdef ERP_DEBUG - /* print current erp_chain */ - printk (KERN_DEBUG PRINTK_HEADER - "3990 ERP postaction finished with remaining chain:\n"); - { - ccw_req_t *temp_erp = NULL; - - for (temp_erp = cqr; - temp_erp != NULL; - temp_erp = temp_erp->refers) { - - printk (KERN_DEBUG PRINTK_HEADER - " erp %p refers to %p \n", temp_erp, - temp_erp->refers); - } - } -#endif /* ERP_DEBUG */ - - return cqr; - -} /* end dasd_3990_erp_postaction */ - -/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only. This must remain at the end diff -urN linux-2.4.21/drivers/s390/block/dasd_diag.c linux-2.4.22/drivers/s390/block/dasd_diag.c --- linux-2.4.21/drivers/s390/block/dasd_diag.c 2001-09-30 12:26:07.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd_diag.c 2003-08-25 04:44:42.000000000 -0700 @@ -5,13 +5,16 @@ * ...............: by Hartmunt Penner * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 - + * + * $Revision: 1.47 $ + * * History of changes * 07/13/00 Added fixup sections for diagnoses ans saved some registers * 07/14/00 fixed constraints in newly generated inline asm * 10/05/00 adapted to 'new' DASD driver * fixed return codes of dia250() * fixed partition handling and HDIO_GETGEO + * 10/01/02 fixed Bugzilla 1341 */ #include @@ -20,7 +23,7 @@ #include #include -#include /* HDIO_GETGEO */ +#include #include #include #include @@ -29,6 +32,7 @@ #include #include #include +#include #include "dasd_int.h" #include "dasd_diag.h" @@ -38,62 +42,50 @@ #endif /* PRINTK_HEADER */ #define PRINTK_HEADER DASD_NAME"(diag):" +#ifdef MODULE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)) +MODULE_LICENSE("GPL"); +#endif +#endif + dasd_discipline_t dasd_diag_discipline; typedef struct dasd_diag_private_t { - dasd_diag_characteristics_t rdc_data; + diag210_t rdc_data; diag_rw_io_t iob; diag_init_io_t iib; unsigned long *label; } dasd_diag_private_t; static __inline__ int -dia210 (void *devchar) -{ - int rc; - - __asm__ __volatile__ (" diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - ".section .fixup,\"ax\"\n" - "2: lhi %0,3\n" - " bras 1,3f\n" - " .long 1b\n" - "3: l 1,0(1)\n" - " br 1\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,2b\n" ".previous\n":"=d" (rc) - :"d" ((void *) __pa (devchar)) - :"1"); - return rc; -} - -static __inline__ int dia250 (void *iob, int cmd) { - __asm__ __volatile__ (" lr 0,%1\n" - " diag 0,%0,0x250\n" + unsigned long addr; + int rc; + + addr = __pa(iob); + __asm__ __volatile__ (" lhi %0,11\n" + " lr 0,%2\n" + " diag 0,%1,0x250\n" "0: ipm %0\n" " srl %0,28\n" " or %0,1\n" "1:\n" - ".section .fixup,\"ax\"\n" - "2: lhi %0,3\n" - " bras 1,3f\n" - " .long 1b\n" - "3: l 1,0(1)\n" - " br 1\n" - ".previous\n" +#ifndef CONFIG_ARCH_S390X ".section __ex_table,\"a\"\n" " .align 4\n" - " .long 0b,2b\n" ".previous\n":"+d" (cmd) - :"d" ((void *) __pa (iob)) - :"0", "1", "cc"); - return cmd; + " .long 0b,1b\n" + ".previous\n" +#else + ".section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 0b,1b\n" + ".previous\n" +#endif + : "+&d" (rc) + : "d" (cmd), "d" (addr) : "0", "1", "cc"); + return rc; } static __inline__ int @@ -144,13 +136,18 @@ iob->key = 0; iob->flags = 2; iob->block_count = cqr->cplength >> 1; - iob->interrupt_params = (u32) cqr; + iob->interrupt_params = (u32)(addr_t) cqr; iob->bio_list = __pa (cqr->cpaddr); - asm volatile ("STCK %0":"=m" (cqr->startclk)); + cqr->startclk = get_clock (); + rc = dia250 (iob, RW_BIO); if (rc > 8) { - PRINT_WARN ("dia250 returned CC %d\n", rc); + + MESSAGE (KERN_WARNING, + "dia250 returned CC %d", + rc); + check_then_set (&cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_ERROR); } else if (rc == 0) { @@ -176,41 +173,56 @@ int done_fast_io = 0; int devno; unsigned long flags; + int subcode; + /* + * Get the external interruption subcode. VM stores + * this in the 'cpu address' field associated with + * the external interrupt. For diag 250 the subcode + * needs to be 3. + */ + subcode = S390_lowcore.cpu_addr; + if ((subcode & 0xff00) != 0x0300) + return; irq_enter(cpu, -1); if (!ip) { /* no intparm: unsolicited interrupt */ - printk (KERN_WARNING PRINTK_HEADER - "caught unsolicited interrupt\n"); + + MESSAGE (KERN_DEBUG, "%s", + "caught unsolicited interrupt"); + irq_exit(cpu, -1); return; } if (ip & 0x80000001) { - printk (KERN_WARNING PRINTK_HEADER - "caught spurious interrupt with parm %08x\n", ip); + + MESSAGE (KERN_DEBUG, + "caught spurious interrupt with parm %08x", + ip); + irq_exit(cpu, -1); return; } - cqr = (ccw_req_t *) ip; + cqr = (ccw_req_t *)(addr_t) ip; device = (dasd_device_t *) cqr->device; devno = device->devinfo.devno; + if (device == NULL) { - printk (KERN_WARNING PRINTK_HEADER - " INT on devno 0x%04X = /dev/%s (%d:%d)" - " belongs to NULL device\n", - devno, device->name, MAJOR (device->kdev), - MINOR (device->kdev)); + + DEV_MESSAGE (KERN_WARNING, device, "%s", + " belongs to NULL device"); } + if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) { - printk (KERN_WARNING PRINTK_HEADER - "0x%04X : /dev/%s (%d:%d)" - " magic number of ccw_req_t 0x%08X doesn't match" - " discipline 0x%08X\n", - devno, device->name, - MAJOR (device->kdev), MINOR (device->kdev), - cqr->magic, *(int *) (&device->discipline->name)); + + DEV_MESSAGE (KERN_WARNING, device, + " magic number of ccw_req_t 0x%08X doesn't match" + " discipline 0x%08X", + cqr->magic, + *(int *) (&device->discipline->name)); + irq_exit(cpu, -1); return; } @@ -219,7 +231,7 @@ s390irq_spin_lock_irqsave (device->devinfo.irq, flags); - asm volatile ("STCK %0":"=m" (cqr->stopclk)); + cqr->stopclk = get_clock (); switch (status) { case 0x00: @@ -254,52 +266,60 @@ { int rc = 0; int bsize; - int label_block; dasd_diag_private_t *private; - dasd_diag_characteristics_t *rdc_data; + diag210_t *rdc_data; ccw_req_t *cqr; long *label; int sb; if (device == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "Null device pointer passed to characteristics checker\n"); + + MESSAGE (KERN_WARNING, "%s", + "Null device pointer passed to characteristics " + "checker"); + return -ENODEV; } device->private = kmalloc (sizeof (dasd_diag_private_t), GFP_KERNEL); + if (device->private == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "memory allocation failed for private data\n"); + + MESSAGE (KERN_WARNING, "%s", + "memory allocation failed for private data"); + rc = -ENOMEM; goto fail; } private = (dasd_diag_private_t *) device->private; rdc_data = (void *) &(private->rdc_data); - rdc_data->dev_nr = device->devinfo.devno; - rdc_data->rdc_len = sizeof (dasd_diag_characteristics_t); + rdc_data->vrdcdvno = device->devinfo.devno; + rdc_data->vrdclen = sizeof (diag210_t); - rc = dia210 (rdc_data); + rc = diag210 (rdc_data); if ( rc != 0) { goto fail; } - if (rdc_data->vdev_class != DEV_CLASS_FBA && - rdc_data->vdev_class != DEV_CLASS_ECKD && - rdc_data->vdev_class != DEV_CLASS_CKD) { + if (rdc_data->vrdcvcla != DEV_CLASS_FBA && + rdc_data->vrdcvcla != DEV_CLASS_ECKD && + rdc_data->vrdcvcla != DEV_CLASS_CKD) { rc = -ENOTSUPP; goto fail; } -#if 0 - printk (KERN_INFO PRINTK_HEADER - "%04X: %04X on real %04X/%02X\n", - rdc_data->dev_nr, - rdc_data->vdev_type, rdc_data->rdev_type, rdc_data->rdev_model); -#endif + + DBF_EVENT (DBF_INFO, + "%04X: %04X on real %04X/%02X", + rdc_data->vrdcdvno, + rdc_data->vrdcvtyp, + rdc_data->vrdccrty, + rdc_data->vrdccrmd); + + /* Figure out position of label block */ - if (private->rdc_data.vdev_class == DEV_CLASS_FBA) { + if (private->rdc_data.vrdcvcla == DEV_CLASS_FBA) { device->sizes.pt_block = 1; - } else if (private->rdc_data.vdev_class == DEV_CLASS_ECKD || - private->rdc_data.vdev_class == DEV_CLASS_CKD) { + } else if (private->rdc_data.vrdcvcla == DEV_CLASS_ECKD || + private->rdc_data.vrdcvcla == DEV_CLASS_CKD) { device->sizes.pt_block = 2; } else { BUG(); @@ -319,9 +339,12 @@ cqr = dasd_alloc_request (dasd_diag_discipline.name, sizeof (diag_bio_t) / sizeof (ccw1_t), 0, device); + if (cqr == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "No memory to allocate initialization request\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); + free_page ((long) private->label); rc = -ENOMEM; goto fail; @@ -334,11 +357,12 @@ cqr->device = device; cqr->status = CQR_STATUS_FILLED; memset (iob, 0, sizeof (diag_rw_io_t)); - iob->dev_nr = rdc_data->dev_nr; + iob->dev_nr = rdc_data->vrdcdvno; iob->block_count = 1; - iob->interrupt_params = (u32) cqr; + iob->interrupt_params = (u32)(addr_t) cqr; iob->bio_list = __pa (bio); rc = dia250 (iob, RW_BIO); + dasd_free_request(cqr, device); if (rc == 0) { if (label[3] != bsize || label[0] != 0xc3d4e2f1 || /* != CMS1 */ @@ -357,13 +381,16 @@ device->sizes.blocks = label[7]; device->sizes.bp_block = bsize; device->sizes.s2b_shift = 0; /* bits to shift 512 to get a block */ + for (sb = 512; sb < bsize; sb = sb << 1) + device->sizes.s2b_shift++; - printk (KERN_INFO PRINTK_HEADER - "/dev/%s (%04X): capacity (%dkB blks): %ldkB\n", - device->name, device->devinfo.devno, - (device->sizes.bp_block >> 10), - (device->sizes.blocks << device->sizes.s2b_shift) >> 1); + + DEV_MESSAGE (KERN_INFO, device, + "capacity (%dkB blks): %ldkB", + (device->sizes.bp_block >> 10), + (device->sizes.blocks << device->sizes.s2b_shift) >> 1); + free_page ((long) private->label); rc = 0; goto out; @@ -380,12 +407,9 @@ dasd_diag_fill_geometry (struct dasd_device_t *device, struct hd_geometry *geo) { int rc = 0; - dasd_diag_private_t *private = (dasd_diag_private_t *) device->private; unsigned long sectors = device->sizes.blocks << device->sizes.s2b_shift; unsigned long tracks = sectors >> 6; - unsigned long trk_rem = sectors & ((1 << 6) - 1); /* 64k per track */ unsigned long cyls = tracks >> 4; - unsigned long cyls_rem = tracks & ((1 << 4) - 1); /* 16 head per cyl */ switch (device->sizes.bp_block) { case 512: @@ -420,14 +444,19 @@ diag_bio_t *bio; int bhct; long size; + unsigned long reloc_sector = req->sector + + device->major_info->gendisk.part[MINOR (req->rq_dev)].start_sect; if (!noblk) { - PRINT_ERR ("No blocks to read/write...returning\n"); - return NULL; + + MESSAGE (KERN_ERR, "%s", + "No blocks to read/write...returning"); + + return ERR_PTR(-EINVAL); } if (req->cmd == READ) { rw_cmd = MDSK_READ_REQ; - } else if (req->cmd == WRITE) { + } else { rw_cmd = MDSK_WRITE_REQ; } bhct = 0; @@ -439,11 +468,11 @@ /* Build the request */ rw_cp = dasd_alloc_request (dasd_diag_discipline.name, bhct << 1, 0, device); if (!rw_cp) { - return NULL; + return ERR_PTR(-ENOMEM); } bio = (diag_bio_t *) (rw_cp->cpaddr); - block = req->sector >> device->sizes.s2b_shift; + block = reloc_sector >> device->sizes.s2b_shift; for (bh = req->bh; bh; bh = bh->b_reqnext) { memset (bio, 0, sizeof (diag_bio_t)); for (size = 0; size < bh->b_size; size += byt_per_blk) { @@ -454,7 +483,9 @@ block++; } } - asm volatile ("STCK %0":"=m" (rw_cp->buildclk)); + + rw_cp->buildclk = get_clock (); + rw_cp->device = device; rw_cp->expires = 50 * TOD_SEC; /* 50 seconds */ rw_cp->req = req; @@ -463,14 +494,15 @@ } static int -dasd_diag_fill_info (dasd_device_t * device, dasd_information_t * info) +dasd_diag_fill_info (dasd_device_t * device, dasd_information2_t * info) { int rc = 0; info->FBA_layout = 1; - info->characteristics_size = sizeof (dasd_diag_characteristics_t); + info->format = DASD_FORMAT_LDL; + info->characteristics_size = sizeof (diag210_t); memcpy (info->characteristics, &((dasd_diag_private_t *) device->private)->rdc_data, - sizeof (dasd_diag_characteristics_t)); + sizeof (diag210_t)); info->confdata_size = 0; return rc; } @@ -501,26 +533,32 @@ examine_error:dasd_diag_examine_error, build_cp_from_req:dasd_diag_build_cp_from_req, dump_sense:dasd_diag_dump_sense, - int_handler:dasd_ext_handler, + int_handler:(void *) dasd_ext_handler, fill_info:dasd_diag_fill_info, + list:LIST_HEAD_INIT(dasd_diag_discipline.list), }; int dasd_diag_init (void) { int rc = 0; + if (MACHINE_IS_VM) { - printk (KERN_INFO PRINTK_HEADER - "%s discipline initializing\n", - dasd_diag_discipline.name); + + MESSAGE (KERN_INFO, + "%s discipline initializing", + dasd_diag_discipline.name); + ASCEBC (dasd_diag_discipline.ebcname, 4); ctl_set_bit (0, 9); register_external_interrupt (0x2603, dasd_ext_handler); dasd_discipline_add (&dasd_diag_discipline); } else { - printk (KERN_INFO PRINTK_HEADER - "Machine is not VM: %s discipline not initializing\n", - dasd_diag_discipline.name); + + MESSAGE (KERN_INFO, + "Machine is not VM: %s discipline not initializing", + dasd_diag_discipline.name); + rc = -EINVAL; } return rc; @@ -530,16 +568,19 @@ dasd_diag_cleanup (void) { if (MACHINE_IS_VM) { - printk (KERN_INFO PRINTK_HEADER - "%s discipline cleaning up\n", - dasd_diag_discipline.name); + + MESSAGE (KERN_INFO, + "%s discipline cleaning up", + dasd_diag_discipline.name); + dasd_discipline_del (&dasd_diag_discipline); unregister_external_interrupt (0x2603, dasd_ext_handler); ctl_clear_bit (0, 9); } else { - printk (KERN_INFO PRINTK_HEADER - "Machine is not VM: %s discipline not initializing\n", - dasd_diag_discipline.name); + + MESSAGE (KERN_INFO, + "Machine is not VM: %s discipline not initializing", + dasd_diag_discipline.name); } } diff -urN linux-2.4.21/drivers/s390/block/dasd_diag.h linux-2.4.22/drivers/s390/block/dasd_diag.h --- linux-2.4.21/drivers/s390/block/dasd_diag.h 2001-08-05 13:12:41.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd_diag.h 2003-08-25 04:44:42.000000000 -0700 @@ -5,6 +5,11 @@ * ...............: by Hartmunt Penner * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 + * + * $Revision: 1.7 $ + * + * History of changes + * */ #define MDSK_WRITE_REQ 0x01 @@ -18,21 +23,6 @@ #define DEV_CLASS_ECKD 0x04 #define DEV_CLASS_CKD 0x04 -typedef struct dasd_diag_characteristics_t { - u16 dev_nr; - u16 rdc_len; - u8 vdev_class; - u8 vdev_type; - u8 vdev_status; - u8 vdev_flags; - u8 rdev_class; - u8 rdev_type; - u8 rdev_model; - u8 rdev_features; -} __attribute__ ((packed, aligned (4))) - - dasd_diag_characteristics_t; - typedef struct diag_bio_t { u8 type; u8 status; diff -urN linux-2.4.21/drivers/s390/block/dasd_eckd.c linux-2.4.22/drivers/s390/block/dasd_eckd.c --- linux-2.4.21/drivers/s390/block/dasd_eckd.c 2002-02-25 11:38:03.000000000 -0800 +++ linux-2.4.22/drivers/s390/block/dasd_eckd.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,10 +1,13 @@ /* * File...........: linux/drivers/s390/block/dasd_eckd.c * Author(s)......: Holger Smolinski - Carsten Otte + * Horst Hummel + * Carsten Otte * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 - + * + * $Revision $ + * * History of changes (starts July 2000) * 07/11/00 Enabled rotational position sensing * 07/14/00 Reorganized the format process for better ERP @@ -42,7 +45,6 @@ #undef PRINTK_HEADER #endif /* PRINTK_HEADER */ #define PRINTK_HEADER DASD_NAME"(eckd):" -#undef CDL_PRINTK #define ECKD_C0(i) (i->home_bytes) #define ECKD_F(i) (i->formula) @@ -55,21 +57,27 @@ #define ECKD_F7(i) (i->factor7) #define ECKD_F8(i) (i->factor8) +#ifdef MODULE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)) +MODULE_LICENSE("GPL"); +#endif +#endif + dasd_discipline_t dasd_eckd_discipline; -typedef struct -dasd_eckd_private_t { +typedef struct dasd_eckd_private_t { dasd_eckd_characteristics_t rdc_data; - dasd_eckd_confdata_t conf_data; - eckd_count_t count_area[5]; - int uses_cdl; + dasd_eckd_confdata_t conf_data; + eckd_count_t count_area[5]; + int uses_cdl; + attrib_data_t attrib; /* e.g. cache operations */ } dasd_eckd_private_t; #ifdef CONFIG_DASD_DYNAMIC static devreg_t dasd_eckd_known_devices[] = { { - ci: { hc: {ctype:0x3880, dtype: 3390}}, + ci: { hc: {ctype:0x3880, dtype: 0x3390}}, flag:(DEVREG_MATCH_CU_TYPE | DEVREG_MATCH_DEV_TYPE | DEVREG_TYPE_DEVCHARS), oper_func:dasd_oper_handler @@ -143,7 +151,10 @@ break; } default: - INTERNAL_ERROR ("unknown formula%d\n", rdc->formula); + + MESSAGE (KERN_ERR, + "unknown formula%d", + rdc->formula); } return bpr; } @@ -190,10 +201,35 @@ return rpt; } +static inline void +check_XRC (ccw1_t *de_ccw, + DE_eckd_data_t *data, + dasd_device_t *device) +{ + + dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private; + + /* switch on System Time Stamp - needed for XRC Support */ + if (private->rdc_data.facilities.XRC_supported) { + + data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ + data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ + + data->ep_sys_time = get_clock (); + + de_ccw->count = sizeof (DE_eckd_data_t); + de_ccw->flags |= CCW_FLAG_SLI; + } + + return; + +} /* end check_XRC */ + static inline int define_extent (ccw1_t * de_ccw, DE_eckd_data_t * data, - int trk, int totrk, int cmd, dasd_device_t * device, ccw_req_t* cqr) + int trk, int totrk, + int cmd, dasd_device_t * device, ccw_req_t* cqr) { int rc=0; ch_t geo, beg, end; @@ -207,8 +243,10 @@ end.head = totrk % geo.head; memset (de_ccw, 0, sizeof (ccw1_t)); + de_ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT; de_ccw->count = 16; + if ((rc=dasd_set_normalized_cda (de_ccw, __pa (data), cqr, device))) return rc; @@ -224,40 +262,86 @@ case DASD_ECKD_CCW_READ_KD_MT: case DASD_ECKD_CCW_READ_COUNT: data->mask.perm = 0x1; - data->attributes.operation = 0x3; /* enable seq. caching */ + data->attributes.operation = private->attrib.operation; break; case DASD_ECKD_CCW_WRITE: case DASD_ECKD_CCW_WRITE_MT: case DASD_ECKD_CCW_WRITE_KD: case DASD_ECKD_CCW_WRITE_KD_MT: data->mask.perm = 0x02; - data->attributes.operation = 0x3; /* enable seq. caching */ + data->attributes.operation = private->attrib.operation; + + check_XRC (de_ccw, + data, + device); break; case DASD_ECKD_CCW_WRITE_CKD: case DASD_ECKD_CCW_WRITE_CKD_MT: - data->attributes.operation = 0x1; /* format through cache */ + data->attributes.operation = DASD_BYPASS_CACHE; + + check_XRC (de_ccw, + data, + device); break; case DASD_ECKD_CCW_ERASE: case DASD_ECKD_CCW_WRITE_HOME_ADDRESS: case DASD_ECKD_CCW_WRITE_RECORD_ZERO: data->mask.perm = 0x3; data->mask.auth = 0x1; - data->attributes.operation = 0x1; /* format through cache */ + data->attributes.operation = DASD_BYPASS_CACHE; + + check_XRC (de_ccw, + data, + device); break; default: - INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd); + + MESSAGE (KERN_ERR, + "unknown opcode 0x%x", + cmd); + break; } - data->attributes.mode = 0x3; + + data->attributes.mode = 0x3; /* ECKD */ + if (private->rdc_data.cu_type == 0x2105 - && !(private->uses_cdl && trk < 2) - ) { - data->reserved |= 0x40; + && !(private->uses_cdl && trk < 2) ) { + + data->ga_extended |= 0x40; } - data->beg_ext.cyl = beg.cyl; + + /* check for sequential prestage - enhance cylinder range */ + if (data->attributes.operation == DASD_SEQ_PRESTAGE || + data->attributes.operation == DASD_SEQ_ACCESS ) { + + if (end.cyl + private->attrib.nr_cyl < geo.cyl) { + + end.cyl += private->attrib.nr_cyl; + + DBF_DEV_EVENT (DBF_NOTICE, device, + "Enhanced DE Cylinder from %x to %x", + (totrk / geo.head), + end.cyl); + + + } else { + end.cyl = (geo.cyl -1); + + DBF_DEV_EVENT (DBF_NOTICE, device, + "Enhanced DE Cylinder from %x to " + "End of device %x", + (totrk / geo.head), + end.cyl); + + } + } + + data->beg_ext.cyl = beg.cyl; data->beg_ext.head = beg.head; - data->end_ext.cyl = end.cyl; + data->end_ext.cyl = end.cyl; data->end_ext.head = end.head; + return rc; } @@ -266,7 +350,11 @@ LO_eckd_data_t * data, int trk, int rec_on_trk, - int no_rec, int cmd, dasd_device_t * device, int reclen, ccw_req_t* cqr) + int no_rec, + int cmd, + dasd_device_t * device, + int reclen, + ccw_req_t* cqr) { int rc=0; dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private; @@ -276,10 +364,14 @@ ch_t seek = { trk / (geo.head), trk % (geo.head) }; int sector = 0; -#ifdef CDL_PRINTK - printk ("Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d\n", trk, - rec_on_trk, no_rec, cmd, reclen); -#endif + DBF_EVENT (DBF_INFO, + "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d", + trk, + rec_on_trk, + no_rec, + cmd, + reclen); + memset (lo_ccw, 0, sizeof (ccw1_t)); lo_ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD; lo_ccw->count = 16; @@ -365,7 +457,10 @@ data->operation.operation = 0x0b; break; default: - INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd); + + MESSAGE (KERN_ERR, + "unknown opcode 0x%x", + cmd); } memcpy (&(data->seek_addr), &seek, sizeof (ch_t)); memcpy (&(data->search_arg), &seek, sizeof (ch_t)); @@ -391,79 +486,113 @@ static int dasd_eckd_check_characteristics (struct dasd_device_t *device) { - int rc = 0; + int rc = 0; void *conf_data; - void *rdc_data; - int conf_len; + void *rdc_data; + int conf_len; dasd_eckd_private_t *private; if (device == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "Null device pointer passed to characteristics checker\n"); + + MESSAGE (KERN_WARNING, "%s", + "Null device pointer passed to characteristics " + "checker"); + return -ENODEV; } - device->private = kmalloc (sizeof (dasd_eckd_private_t), GFP_KERNEL); + device->private = kmalloc (sizeof (dasd_eckd_private_t), + GFP_KERNEL); + if (device->private == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "memory allocation failed for private data\n"); + + MESSAGE (KERN_WARNING, "%s", + "memory allocation failed for private data"); + rc = -ENOMEM; goto fail; } - private = (dasd_eckd_private_t *) device->private; + + private = (dasd_eckd_private_t *) device->private; rdc_data = (void *) &(private->rdc_data); - rc = read_dev_chars (device->devinfo.irq, &rdc_data, 64); + + /* Read Device Characteristics */ + rc = read_dev_chars (device->devinfo.irq, + &rdc_data, + 64); if (rc) { - printk (KERN_WARNING PRINTK_HEADER - "Read device characteristics returned error %d\n", rc); + + MESSAGE (KERN_WARNING, + "Read device characteristics returned error %d", + rc); + goto fail; } - printk (KERN_INFO PRINTK_HEADER - "%04X on sch %d: %04X/%02X(CU:%04X/%02X) " - "Cyl:%d Head:%d Sec:%d\n", - device->devinfo.devno, device->devinfo.irq, - private->rdc_data.dev_type, private->rdc_data.dev_model, - private->rdc_data.cu_type, private->rdc_data.cu_model.model, - private->rdc_data.no_cyl, private->rdc_data.trk_per_cyl, - private->rdc_data.sec_per_trk); - rc = read_conf_data (device->devinfo.irq, &conf_data, &conf_len, + + DEV_MESSAGE (KERN_INFO, device, + "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", + private->rdc_data.dev_type, + private->rdc_data.dev_model, + private->rdc_data.cu_type, + private->rdc_data.cu_model.model, + private->rdc_data.no_cyl, + private->rdc_data.trk_per_cyl, + private->rdc_data.sec_per_trk); + + /* set default cache operations */ + private->attrib.operation = DASD_SEQ_ACCESS; + private->attrib.nr_cyl = 0x02; + + /* Read Configuration Data */ + rc = read_conf_data (device->devinfo.irq, + &conf_data, + &conf_len, LPM_ANYPATH); if (rc == -EOPNOTSUPP) { rc = 0; /* this one is ok */ } if (rc) { - printk (KERN_WARNING PRINTK_HEADER - "Read configuration data returned error %d\n", rc); + + MESSAGE (KERN_WARNING, + "Read configuration data returned error %d", + rc); + goto fail; } if (conf_data == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "No configuration data retrieved\n"); + + MESSAGE (KERN_WARNING, "%s", + "No configuration data retrieved"); + goto out; /* no errror */ } if (conf_len != sizeof (dasd_eckd_confdata_t)) { - printk (KERN_WARNING PRINTK_HEADER - "sizes of configuration data mismatch" - "%d (read) vs %ld (expected)\n", - conf_len, sizeof (dasd_eckd_confdata_t)); + + MESSAGE (KERN_WARNING, + "sizes of configuration data mismatch" + "%d (read) vs %ld (expected)", + conf_len, + sizeof (dasd_eckd_confdata_t)); + goto out; /* no errror */ } memcpy (&private->conf_data, conf_data, sizeof (dasd_eckd_confdata_t)); - printk (KERN_INFO PRINTK_HEADER - "%04X on sch %d: %04X/%02X(CU:%04X/%02X): " - "Configuration data read\n", - device->devinfo.devno, device->devinfo.irq, + + DEV_MESSAGE (KERN_INFO, device, + "%04X/%02X(CU:%04X/%02X): Configuration data read", private->rdc_data.dev_type, private->rdc_data.dev_model, private->rdc_data.cu_type, private->rdc_data.cu_model.model); goto out; + fail: - if ( rc ) { + if (device->private) { kfree (device->private); device->private = NULL; } + out: return rc; } @@ -498,8 +627,9 @@ 2 * sizeof (LO_eckd_data_t), device); if (cqr == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "No memory to allocate initialization request\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); goto out; } DE_data = cqr->data; @@ -557,13 +687,17 @@ } cqr->device = device; cqr->retries = 0; + cqr->buildclk = get_clock (); cqr->status = CQR_STATUS_FILLED; dasd_chanq_enq (&device->queue, cqr); goto out; + clear_cqr: dasd_free_request (cqr,device); - printk (KERN_WARNING PRINTK_HEADER - "No memory to allocate initialization request\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); + cqr=NULL; out: return cqr; @@ -578,14 +712,17 @@ char *cdl_msg; int status; int i; + private->uses_cdl = 1; status = device->init_cqr->status; dasd_chanq_deq (&device->queue, device->init_cqr); dasd_free_request (device->init_cqr, device); /* Free the cqr and cleanup device->sizes */ if ( status != CQR_STATUS_DONE ) { - DASD_MESSAGE (KERN_WARNING,device,"%s", - "volume analysis returned unformatted disk"); + + DEV_MESSAGE (KERN_WARNING, device, "%s", + "volume analysis returned unformatted disk"); + return -EMEDIUMTYPE; } /* Check Track 0 for Compatible Disk Layout */ @@ -614,8 +751,9 @@ } } else { if (private->count_area[3].record == 1) { - DASD_MESSAGE (KERN_WARNING, device, "%s", - "Trk 0: no records after VTOC!"); + + DEV_MESSAGE (KERN_WARNING, device, "%s", + "Trk 0: no records after VTOC!"); } } if (count_area != NULL && /* we found notthing violating our disk layout */ @@ -631,8 +769,10 @@ } } if (device->sizes.bp_block == 0) { - DASD_MESSAGE (KERN_WARNING, device, "%s", - "Volume has incompatible disk layout"); + + DEV_MESSAGE (KERN_WARNING, device, "%s", + "Volume has incompatible disk layout"); + return -EMEDIUMTYPE; } device->sizes.s2b_shift = 0; /* bits to shift 512 to get a block */ @@ -647,18 +787,21 @@ device->sizes.bp_block)); cdl_msg = private-> - uses_cdl ? "compatible disk layout" : "classic disk layout"; + uses_cdl ? "compatible disk layout" : "linux disk layout"; + + DEV_MESSAGE (KERN_INFO, device, + "(%dkB blks): %dkB at %dkB/trk %s", + (device->sizes.bp_block >> 10), + ((private->rdc_data.no_cyl * + private->rdc_data.trk_per_cyl * + recs_per_track (&private->rdc_data, 0, + device->sizes.bp_block) * + (device->sizes.bp_block >> 9)) >> 1), + ((recs_per_track (&private->rdc_data, 0, + device->sizes.bp_block) * + device->sizes.bp_block) >> 10), + cdl_msg); - DASD_MESSAGE (KERN_INFO, device, "(%dkB blks): %dkB at %dkB/trk %s", - (device->sizes.bp_block >> 10), - (private->rdc_data.no_cyl * - private->rdc_data.trk_per_cyl * - recs_per_track (&private->rdc_data, 0, - device->sizes.bp_block) * - (device->sizes.bp_block >> 9)) >> 1, - (recs_per_track (&private->rdc_data, 0, - device->sizes.bp_block) * - device->sizes.bp_block) >> 10, cdl_msg); return 0; } @@ -703,13 +846,21 @@ int wrccws = rpt; int datasize = sizeof (DE_eckd_data_t) + sizeof (LO_eckd_data_t); - if (fdata->start_unit >= (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)){ - DASD_MESSAGE (KERN_INFO, device, "Track no %d too big!", fdata->start_unit); + if (fdata->start_unit >= + (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)){ + + DEV_MESSAGE (KERN_INFO, device, + "Track no %d too big!", + fdata->start_unit); + return NULL; } if ( fdata->start_unit > fdata->stop_unit) { - DASD_MESSAGE (KERN_INFO, device, "Track %d reached! ending.", - fdata->start_unit); + + DEV_MESSAGE (KERN_INFO, device, + "Track %d reached! ending.", + fdata->start_unit); + return NULL; } switch (fdata->blksize) { @@ -719,8 +870,11 @@ case 4096: break; default: - printk (KERN_WARNING PRINTK_HEADER - "Invalid blocksize %d...terminating!\n", fdata->blksize); + + MESSAGE (KERN_WARNING, + "Invalid blocksize %d...terminating!", + fdata->blksize); + return NULL; } switch (fdata->intensity) { @@ -734,8 +888,11 @@ case 0x0c: break; default: - printk (KERN_WARNING PRINTK_HEADER - "Invalid flags 0x%x...terminating!\n", fdata->intensity); + + MESSAGE (KERN_WARNING, + "Invalid flags 0x%x...terminating!", + fdata->intensity); + return NULL; } @@ -745,9 +902,12 @@ (fdata->start_unit % private->rdc_data.no_cyl == 0 && (fdata->start_unit / private->rdc_data.no_cyl) % (private->rdc_data.no_cyl / 20))) { - DASD_MESSAGE (KERN_INFO, device, - "Format Cylinder: %d Flags: %d", - fdata->start_unit / private->rdc_data.trk_per_cyl, fdata->intensity); + + DBF_DEV_EVENT (DBF_NOTICE, device, + "Format Cylinder: %d Flags: %d", + fdata->start_unit / private->rdc_data.trk_per_cyl, + fdata->intensity); + } if ((fdata->intensity & ~0x8) & 0x04) { wrccws = 1; @@ -789,14 +949,14 @@ switch (fdata->intensity & ~0x08) { case 0x03: if (define_extent (last_ccw, DE_data, fdata->start_unit, fdata->start_unit, - DASD_ECKD_CCW_WRITE_HOME_ADDRESS, + DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device, fcp)) { goto clear_fcp; } last_ccw->flags |= CCW_FLAG_CC; last_ccw++; if (locate_record (last_ccw, LO_data, fdata->start_unit, 0, wrccws, - DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device, + DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device, device->sizes.bp_block, fcp)) { goto clear_fcp; } @@ -811,7 +971,7 @@ last_ccw->flags |= CCW_FLAG_CC; last_ccw++; if (locate_record (last_ccw, LO_data, fdata->start_unit, 0, wrccws, - DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, + DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, device->sizes.bp_block, fcp)) { goto clear_fcp; } @@ -837,11 +997,19 @@ last_ccw++; break; default: - PRINT_WARN ("Unknown format flags...%d\n", fdata->intensity); + + MESSAGE (KERN_WARNING, + "Unknown format flags...%d", + fdata->intensity); + return NULL; } if (fdata->intensity & 0x02) { - PRINT_WARN ("Unsupported format flag...%d\n", fdata->intensity); + + MESSAGE (KERN_WARNING, + "Unsupported format flag...%d", + fdata->intensity); + return NULL; } if (fdata->intensity & 0x01) { /* write record zero */ @@ -913,6 +1081,7 @@ } (last_ccw - 1)->flags &= ~(CCW_FLAG_CC | CCW_FLAG_DC); fcp->device = device; + fcp->buildclk = get_clock (); fcp->status = CQR_STATUS_FILLED; } goto out; @@ -939,8 +1108,10 @@ case 0x9343: return dasd_9343_erp_examine (cqr, stat); default: - printk (KERN_WARNING PRINTK_HEADER - "default (unknown CU type) - RECOVERABLE return \n"); + + MESSAGE (KERN_WARNING, "%s", + "default (unknown CU type) - RECOVERABLE return"); + return dasd_era_recover; } } @@ -1015,26 +1186,36 @@ int byt_per_blk = device->sizes.bp_block; int shift = device->sizes.s2b_shift; int blk_per_trk = recs_per_track (&(private->rdc_data), 0, byt_per_blk); - int btrk = (req->sector >> shift) / blk_per_trk; - int etrk = ((req->sector + req->nr_sectors - 1) >> shift) / blk_per_trk; - int recid = req->sector >> shift; + unsigned long reloc_sector = req->sector + + device->major_info->gendisk.part[MINOR(req->rq_dev)].start_sect; + int btrk = (reloc_sector >> shift) / blk_per_trk; + int etrk = ((reloc_sector + req->nr_sectors - 1) >> shift) / blk_per_trk; + int recid = reloc_sector >> shift; int locate4k_set = 0; int nlocs = 0; + int errcode; if (req->cmd == READ) { rw_cmd = DASD_ECKD_CCW_READ_MT; } else if (req->cmd == WRITE) { rw_cmd = DASD_ECKD_CCW_WRITE_MT; } else { - PRINT_ERR ("Unknown command %d\n", req->cmd); - return NULL; + + MESSAGE (KERN_ERR, + "Unknown command %d", + req->cmd); + + return ERR_PTR(-EINVAL); } /* Build the request */ /* count bhs to prevent errors, when bh smaller than block */ bhct = 0; for (bh = req->bh; bh; bh = bh->b_reqnext) { - if (bh->b_size < byt_per_blk) - BUG(); + if (bh->b_size < byt_per_blk) { + MESSAGE(KERN_ERR, "ignoring bogus sized request: %d<%d", + bh->b_size, byt_per_blk); + return ERR_PTR(-EINVAL); + } bhct+= bh->b_size >> (device->sizes.s2b_shift+9); } if (btrk < 2 && private->uses_cdl) { @@ -1050,12 +1231,13 @@ sizeof (LO_eckd_data_t), device); if (!rw_cp) { - return NULL; + return ERR_PTR(-ENOMEM); } DE_data = rw_cp->data; LO_data = rw_cp->data + sizeof (DE_eckd_data_t); ccw = rw_cp->cpaddr; - if (define_extent (ccw, DE_data, btrk, etrk, rw_cmd, device, rw_cp)) { + if ((errcode = define_extent (ccw, DE_data, btrk, etrk, + rw_cmd, device, rw_cp))) { goto clear_rw_cp; } ccw->flags |= CCW_FLAG_CC; @@ -1068,25 +1250,25 @@ && private->uses_cdl) { /* Do a locate record for our special blocks */ int cmd = dasd_eckd_cdl_cmd (device,recid, req->cmd); - if (locate_record (ccw, + if ((errcode = locate_record (ccw, LO_data++, recid / blk_per_trk, recid % blk_per_trk + 1, 1, cmd, device, - dasd_eckd_cdl_reclen(device, recid), rw_cp)) { + dasd_eckd_cdl_reclen(device, recid), rw_cp))) { goto clear_rw_cp; } } else { // Do a locate record for standard blocks */ - if (locate_record (ccw, + if ((errcode = locate_record (ccw, LO_data++, recid /blk_per_trk, recid %blk_per_trk + 1, - (((req->sector + + (((reloc_sector + req->nr_sectors) >> shift) - recid), rw_cmd, device, - device->sizes.bp_block, rw_cp)) { + device->sizes.bp_block, rw_cp))) { goto clear_rw_cp; } locate4k_set = 1; @@ -1105,25 +1287,32 @@ 0xE5, byt_per_blk - ccw->count); } } - if (dasd_set_normalized_cda (ccw, __pa (bh->b_data+size), rw_cp, device)) { + if ((errcode = dasd_set_normalized_cda (ccw, __pa (bh->b_data+size), + rw_cp, device))) { goto clear_rw_cp; } recid++; } bh = bh->b_reqnext; } - ccw->flags &= ~(CCW_FLAG_DC | CCW_FLAG_CC); - rw_cp->device = device; + ccw->flags &= ~(CCW_FLAG_DC | CCW_FLAG_CC); + rw_cp->device = device; rw_cp->expires = 5 * TOD_MIN; /* 5 minutes */ - rw_cp->req = req; - rw_cp->lpm = LPM_ANYPATH; - rw_cp->retries = 2; - asm volatile ("STCK %0":"=m" (rw_cp->buildclk)); - check_then_set (&rw_cp->status, CQR_STATUS_EMPTY, CQR_STATUS_FILLED); + rw_cp->req = req; + rw_cp->lpm = LPM_ANYPATH; + rw_cp->retries = 256; + + rw_cp->buildclk = get_clock (); + + check_then_set (&rw_cp->status, + CQR_STATUS_EMPTY, + CQR_STATUS_FILLED); + goto out; clear_rw_cp: - dasd_free_request (rw_cp, device); - rw_cp=NULL; + dasd_free_request (rw_cp, + device); + rw_cp=ERR_PTR(errcode); out: return rw_cp; } @@ -1176,18 +1365,31 @@ ccw_req_t * dasd_eckd_reserve (struct dasd_device_t * device) { - ccw_req_t *cqr = - dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device); + ccw_req_t *cqr; + + cqr = dasd_alloc_request (dasd_eckd_discipline.name, + 1 + 1, 32, device); if (cqr == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "No memory to allocate initialization request\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); + return NULL; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE; + cqr->cpaddr->flags |= CCW_FLAG_SLI; + cqr->cpaddr->count = 32; + + if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data), + cqr, device)) { + dasd_free_request (cqr, device); + return NULL; + } + cqr->device = device; cqr->retries = 0; cqr->expires = 10 * TOD_SEC; - cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */ + cqr->buildclk = get_clock (); cqr->status = CQR_STATUS_FILLED; return cqr; } @@ -1202,18 +1404,31 @@ ccw_req_t * dasd_eckd_release (struct dasd_device_t * device) { - ccw_req_t *cqr = - dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device); + ccw_req_t *cqr; + + cqr = dasd_alloc_request (dasd_eckd_discipline.name, + 1 + 1, 32, device); if (cqr == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "No memory to allocate initialization request\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); + return NULL; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE; + cqr->cpaddr->flags |= CCW_FLAG_SLI; + cqr->cpaddr->count = 32; + + if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data), + cqr, device)) { + dasd_free_request (cqr, device); + return NULL; + } + cqr->device = device; cqr->retries = 0; cqr->expires = 10 * TOD_SEC; - cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */ + cqr->buildclk = get_clock (); cqr->status = CQR_STATUS_FILLED; return cqr; @@ -1229,18 +1444,31 @@ ccw_req_t * dasd_eckd_steal_lock (struct dasd_device_t * device) { - ccw_req_t *cqr = - dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device); + ccw_req_t *cqr; + + cqr = dasd_alloc_request (dasd_eckd_discipline.name, + 1 + 1, 32, device); if (cqr == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "No memory to allocate initialization request\n"); + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); + return NULL; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK; + cqr->cpaddr->flags |= CCW_FLAG_SLI; + cqr->cpaddr->count = 32; + + if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data), + cqr, device)) { + dasd_free_request (cqr, device); + return NULL; + } + cqr->device = device; cqr->retries = 0; cqr->expires = 10 * TOD_SEC; - cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */ + cqr->buildclk = get_clock (); cqr->status = CQR_STATUS_FILLED; return cqr; } @@ -1274,14 +1502,17 @@ } static int -dasd_eckd_fill_info (dasd_device_t * device, dasd_information_t * info) +dasd_eckd_fill_info (dasd_device_t * device, dasd_information2_t * info) { int rc = 0; info->label_block = 2; - if (((dasd_eckd_private_t *) device->private)->uses_cdl) + if (((dasd_eckd_private_t *) device->private)->uses_cdl) { info->FBA_layout = 0; - else - info->FBA_layout = 1; + info->format = DASD_FORMAT_CDL; + } else { + info->FBA_layout = 1; + info->format = DASD_FORMAT_LDL; + } info->characteristics_size = sizeof (dasd_eckd_characteristics_t); memcpy (info->characteristics, &((dasd_eckd_private_t *) device->private)->rdc_data, @@ -1293,6 +1524,138 @@ return rc; } +/* + * DASD_ECKD_READ_STATS + * + * DESCRIPTION + * build the channel program to read the performance statistics + * of the attached subsystem + */ +ccw_req_t * +dasd_eckd_read_stats (struct dasd_device_t * device) +{ + + int rc; + ccw1_t *ccw; + ccw_req_t *cqr; + dasd_psf_prssd_data_t *prssdp; + dasd_rssd_perf_stats_t *statsp; + + cqr = dasd_alloc_request (dasd_eckd_discipline.name, + 1 /* PSF */ + 1 /* RSSD */, + (sizeof (dasd_psf_prssd_data_t) + + sizeof (dasd_rssd_perf_stats_t) ), + device); + + if (cqr == NULL) { + + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate initialization request"); + + return NULL; + } + + cqr->device = device; + cqr->retries = 0; + cqr->expires = 10 * TOD_SEC; + + /* Prepare for Read Subsystem Data */ + prssdp = (dasd_psf_prssd_data_t *) cqr->data; + + memset (prssdp, 0, sizeof (dasd_psf_prssd_data_t)); + + prssdp->order = PSF_ORDER_PRSSD; + prssdp->suborder = 0x01; /* Perfomance Statistics */ + prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */ + + ccw = cqr->cpaddr; + + ccw->cmd_code = DASD_ECKD_CCW_PSF; + ccw->count = sizeof (dasd_psf_prssd_data_t); + ccw->flags |= CCW_FLAG_CC; + + if ((rc = dasd_set_normalized_cda (ccw,__pa (prssdp), cqr, device))) { + + dasd_free_request (cqr, + device); + return NULL; + } + + ccw++; + + /* Read Subsystem Data - Performance Statistics */ + statsp = (dasd_rssd_perf_stats_t *) (prssdp + 1); + memset (statsp, 0, sizeof (dasd_rssd_perf_stats_t)); + + ccw->cmd_code = DASD_ECKD_CCW_RSSD; + ccw->count = sizeof (dasd_rssd_perf_stats_t); + + if ((rc = dasd_set_normalized_cda (ccw,__pa (statsp), cqr, device))) { + + dasd_free_request (cqr, + device); + return NULL; + } + cqr->buildclk = get_clock (); + cqr->status = CQR_STATUS_FILLED; + + return cqr; +} /* end dasd_eckd_rstat */ + +/* + * DASD_ECKD_RET_STATS + * + * DESCRIPTION + * returns pointer to Performance Statistics Data. + */ +dasd_rssd_perf_stats_t * +dasd_eckd_ret_stats (ccw_req_t *cqr) +{ + + dasd_psf_prssd_data_t *prssdp; + dasd_rssd_perf_stats_t *statsp; + + if (cqr == NULL) { + + return NULL; + } + + /* Prepare for Read Subsystem Data */ + prssdp = (dasd_psf_prssd_data_t *) cqr->data; + statsp = (dasd_rssd_perf_stats_t *) (prssdp + 1); + + return statsp; + +} /* end dasd_eckd_rstat */ + + +/* + * DASD_ECKD_SET_ATTRUB + * + * DESCRIPTION + * stores the attributes for cache operation to be used in Define Extend (DE). + */ +int +dasd_eckd_set_attrib (dasd_device_t *device, + attrib_data_t *attrib) +{ + int rc = 0; + dasd_eckd_private_t *private; + + private = (dasd_eckd_private_t *) device->private; + private->attrib = *attrib; + + DBF_DEV_EVENT (DBF_ERR, device, + "cache operation mode set to " + "%x (%i cylinder prestage)", + private->attrib.operation, + private->attrib.nr_cyl); + + + return rc; + +} /* end dasd_eckd_set_attrib */ + static char* dasd_eckd_dump_sense (struct dasd_device_t *device, ccw_req_t *req) @@ -1304,8 +1667,10 @@ int len, sl, sct; if (page == NULL) { - printk (KERN_ERR PRINTK_HEADER - "No memory to dump sense data\n"); + + MESSAGE (KERN_ERR, "%s", + "No memory to dump sense data"); + return NULL; } @@ -1318,17 +1683,27 @@ len += sprintf (page + len, KERN_ERR PRINTK_HEADER "Failing CCW: %p\n", (void *) (long) stat->cpa); { + ccw1_t *act = req->cpaddr; int i = req->cplength; + do { -#ifdef ERP_DEBUG - printk (KERN_ERR "CCW %p: %08X %08X\n", - act, ((int *) act)[0], ((int *) act)[1]); - printk (KERN_ERR "DAT: %08X %08X %08X %08X\n", - ((int *) act->cda)[0], ((int *) act->cda)[1], - ((int *) act->cda)[2], ((int *) act->cda)[3]); -#endif /* ERP_DEBUG */ + + DBF_EVENT (DBF_INFO, + "CCW %p: %08X %08X", + act, + ((int *) act)[0], + ((int *) act)[1]); + + DBF_EVENT (DBF_INFO, + "DAT: %08X %08X %08X %08X", + ((int *) (addr_t) act->cda)[0], + ((int *) (addr_t) act->cda)[1], + ((int *) (addr_t) act->cda)[2], + ((int *) (addr_t) act->cda)[3]); + act++; + } while (--i); } if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL) { @@ -1353,13 +1728,15 @@ } else { /* 32 Byte Sense Data */ len += sprintf (page + len, KERN_ERR PRINTK_HEADER - "32 Byte: Format: %x Exception class %x\n", + "32 Byte: Format: %x " + "Exception class %x\n", sense[6] & 0x0f, sense[22] >> 4); } } - printk ("Sense data:\n%s", - page); + MESSAGE (KERN_ERR, + "Sense data:\n%s", + page); free_page ((unsigned long) page); @@ -1371,7 +1748,7 @@ owner: THIS_MODULE, name:"ECKD", ebcname:"ECKD", - max_blocks:255, + max_blocks:240, id_check:dasd_eckd_id_check, check_characteristics:dasd_eckd_check_characteristics, init_analysis:dasd_eckd_init_analysis, @@ -1391,14 +1768,21 @@ steal_lock:dasd_eckd_steal_lock, merge_cp:dasd_eckd_merge_cp, fill_info:dasd_eckd_fill_info, + read_stats:dasd_eckd_read_stats, + ret_stats:dasd_eckd_ret_stats, + set_attrib:dasd_eckd_set_attrib, + list:LIST_HEAD_INIT(dasd_eckd_discipline.list), }; int dasd_eckd_init (void) { int rc = 0; - printk (KERN_INFO PRINTK_HEADER - "%s discipline initializing\n", dasd_eckd_discipline.name); + + MESSAGE (KERN_INFO, + "%s discipline initializing", + dasd_eckd_discipline.name); + ASCEBC (dasd_eckd_discipline.ebcname, 4); dasd_discipline_add (&dasd_eckd_discipline); #ifdef CONFIG_DASD_DYNAMIC @@ -1407,10 +1791,12 @@ for (i = 0; i < sizeof (dasd_eckd_known_devices) / sizeof (devreg_t); i++) { - printk (KERN_INFO PRINTK_HEADER - "We are interested in: CU %04X/%02x\n", - dasd_eckd_known_devices[i].ci.hc.ctype, - dasd_eckd_known_devices[i].ci.hc.cmode); + + MESSAGE (KERN_INFO, + "We are interested in: CU %04X/%02x", + dasd_eckd_known_devices[i].ci.hc.ctype, + dasd_eckd_known_devices[i].ci.hc.cmode); + s390_device_register (&dasd_eckd_known_devices[i]); } } @@ -1421,18 +1807,23 @@ void dasd_eckd_cleanup (void) { - printk (KERN_INFO PRINTK_HEADER - "%s discipline cleaning up\n", dasd_eckd_discipline.name); + + MESSAGE (KERN_INFO, + "%s discipline cleaning up", + dasd_eckd_discipline.name); + #ifdef CONFIG_DASD_DYNAMIC { int i; for (i = 0; i < sizeof (dasd_eckd_known_devices) / sizeof (devreg_t); i++) { - printk (KERN_INFO PRINTK_HEADER - "We were interested in: CU %04X/%02x\n", - dasd_eckd_known_devices[i].ci.hc.ctype, - dasd_eckd_known_devices[i].ci.hc.cmode); + + MESSAGE (KERN_INFO, + "We were interested in: CU %04X/%02x", + dasd_eckd_known_devices[i].ci.hc.ctype, + dasd_eckd_known_devices[i].ci.hc.cmode); + s390_device_unregister (&dasd_eckd_known_devices[i]); } } diff -urN linux-2.4.21/drivers/s390/block/dasd_eckd.h linux-2.4.22/drivers/s390/block/dasd_eckd.h --- linux-2.4.21/drivers/s390/block/dasd_eckd.h 2001-09-30 12:26:07.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd_eckd.h 2003-08-25 04:44:42.000000000 -0700 @@ -1,78 +1,96 @@ +/* + * File...........: linux/drivers/s390/block/dasd_eckd.h + * Author(s)......: Holger Smolinski + * Horst Hummel + * Bugreports.to..: + * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 + * + * $Revision: 1.14 $ + * + * History of changes + * + */ + #ifndef DASD_ECKD_H #define DASD_ECKD_H #include "dasd_3990_erp.h" #include "dasd_9343_erp.h" -#define DASD_ECKD_CCW_WRITE 0x05 -#define DASD_ECKD_CCW_READ 0x06 +/******************************************************************************* + * SECTION: CCW Definitions + ******************************************************************************/ +#define DASD_ECKD_CCW_WRITE 0x05 +#define DASD_ECKD_CCW_READ 0x06 #define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09 -#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a -#define DASD_ECKD_CCW_WRITE_KD 0x0d -#define DASD_ECKD_CCW_READ_KD 0x0e -#define DASD_ECKD_CCW_ERASE 0x11 -#define DASD_ECKD_CCW_READ_COUNT 0x12 -#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15 -#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16 -#define DASD_ECKD_CCW_WRITE_CKD 0x1d -#define DASD_ECKD_CCW_READ_CKD 0x1e -#define DASD_ECKD_CCW_LOCATE_RECORD 0x47 -#define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 -#define DASD_ECKD_CCW_WRITE_MT 0x85 -#define DASD_ECKD_CCW_READ_MT 0x86 -#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d -#define DASD_ECKD_CCW_READ_KD_MT 0x8e -#define DASD_ECKD_CCW_RELEASE 0x94 -#define DASD_ECKD_CCW_READ_CKD_MT 0x9e -#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d -#define DASD_ECKD_CCW_RESERVE 0xB4 -#define DASD_ECKD_CCW_SLCK 0x14 /* steal lock - unconditional reserve */ +#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a +#define DASD_ECKD_CCW_WRITE_KD 0x0d +#define DASD_ECKD_CCW_READ_KD 0x0e +#define DASD_ECKD_CCW_ERASE 0x11 +#define DASD_ECKD_CCW_READ_COUNT 0x12 +#define DASD_ECKD_CCW_SLCK 0x14 +#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15 +#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16 +#define DASD_ECKD_CCW_WRITE_CKD 0x1d +#define DASD_ECKD_CCW_READ_CKD 0x1e +#define DASD_ECKD_CCW_PSF 0x27 +#define DASD_ECKD_CCW_RSSD 0x3e +#define DASD_ECKD_CCW_LOCATE_RECORD 0x47 +#define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 +#define DASD_ECKD_CCW_WRITE_MT 0x85 +#define DASD_ECKD_CCW_READ_MT 0x86 +#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d +#define DASD_ECKD_CCW_READ_KD_MT 0x8e +#define DASD_ECKD_CCW_RELEASE 0x94 +#define DASD_ECKD_CCW_READ_CKD_MT 0x9e +#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d +#define DASD_ECKD_CCW_RESERVE 0xB4 + +/* + *Perform Subsystem Function / Sub-Orders + */ +#define PSF_ORDER_PRSSD 0x18 + + +/******************************************************************************* + * SECTION: Type Definitions + ******************************************************************************/ -typedef - struct eckd_count_t { +typedef struct eckd_count_t { __u16 cyl; __u16 head; __u8 record; __u8 kl; __u16 dl; -} __attribute__ ((packed)) +} __attribute__ ((packed)) eckd_count_t; - eckd_count_t; -typedef - struct ch_t { +typedef struct ch_t { __u16 cyl; __u16 head; -} __attribute__ ((packed)) +} __attribute__ ((packed)) ch_t; - ch_t; -typedef - struct chs_t { +typedef struct chs_t { __u16 cyl; __u16 head; __u32 sector; -} __attribute__ ((packed)) +} __attribute__ ((packed)) chs_t; - chs_t; -typedef - struct chr_t { +typedef struct chr_t { __u16 cyl; __u16 head; __u8 record; -} __attribute__ ((packed)) +} __attribute__ ((packed)) chr_t; - chr_t; -typedef - struct geom_t { +typedef struct geom_t { __u16 cyl; __u16 head; __u32 sector; -} __attribute__ ((packed)) +} __attribute__ ((packed)) geom_t; - geom_t; typedef struct eckd_home_t { __u8 skip_control[14]; @@ -83,12 +101,10 @@ __u8 reserved; __u8 key_length; __u8 reserved2[2]; -} __attribute__ ((packed)) +} __attribute__ ((packed)) eckd_home_t; - eckd_home_t; -typedef - struct DE_eckd_data_t { +typedef struct DE_eckd_data_t { struct { unsigned char perm:2; /* Permissions on this extent */ unsigned char reserved:1; @@ -103,18 +119,20 @@ unsigned char cfw:1; /* Cache fast write */ unsigned char dfw:1; /* DASD fast write */ } __attribute__ ((packed)) attributes; - __u16 short blk_size; /* Blocksize */ + __u16 blk_size; /* Blocksize */ __u16 fast_write_id; - __u8 unused; - __u8 reserved; + __u8 ga_additional; /* Global Attributes Additional */ + __u8 ga_extended; /* Global Attributes Extended */ ch_t beg_ext; ch_t end_ext; -} __attribute__ ((packed)) + unsigned long long ep_sys_time; /* Extended Parameter - System Time Stamp */ + __u8 ep_format; /* Extended Parameter format byte */ + __u8 ep_prio; /* Extended Parameter priority I/O byte */ + __u8 ep_reserved[6]; /* Extended Parameter Reserved */ +} __attribute__ ((packed)) DE_eckd_data_t; - DE_eckd_data_t; -typedef - struct LO_eckd_data_t { +typedef struct LO_eckd_data_t { struct { unsigned char orientation:2; unsigned char operation:6; @@ -130,12 +148,10 @@ chr_t search_arg; __u8 sector; __u16 length; -} __attribute__ ((packed)) +} __attribute__ ((packed)) LO_eckd_data_t; - LO_eckd_data_t; -typedef - struct dasd_eckd_characteristics_t { +typedef struct dasd_eckd_characteristics_t { __u16 cu_type; struct { unsigned char support:2; @@ -154,7 +170,8 @@ unsigned char reserved2:4; unsigned char reserved3:8; unsigned char defect_wr:1; - unsigned char reserved4:2; + unsigned char XRC_supported:1; + unsigned char reserved4:1; unsigned char striping:1; unsigned char reserved5:4; unsigned char cfw:1; @@ -205,9 +222,7 @@ __u8 factor8; __u8 reserved2[3]; __u8 reserved3[10]; -} __attribute__ ((packed)) - - dasd_eckd_characteristics_t; +} __attribute__ ((packed)) dasd_eckd_characteristics_t; typedef struct dasd_eckd_confdata_t { struct { @@ -324,9 +339,20 @@ __u8 log_dev_address; unsigned char reserved2[12]; } __attribute__ ((packed)) neq; -} __attribute__ ((packed)) +} __attribute__ ((packed)) dasd_eckd_confdata_t; + +/* + * Perform Subsystem Function - Prepare for Read Subsystem Data + */ +typedef struct dasd_psf_prssd_data_t { + unsigned char order; + unsigned char flags; + unsigned char reserved[4]; + unsigned char suborder; + unsigned char varies[9]; +} __attribute__((packed)) dasd_psf_prssd_data_t; + - dasd_eckd_confdata_t; int dasd_eckd_init (void); void dasd_eckd_cleanup (void); diff -urN linux-2.4.21/drivers/s390/block/dasd_fba.c linux-2.4.22/drivers/s390/block/dasd_fba.c --- linux-2.4.21/drivers/s390/block/dasd_fba.c 2001-09-30 12:26:07.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd_fba.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,9 +1,12 @@ - /* * File...........: linux/drivers/s390/block/dasd_fba.c * Author(s)......: Holger Smolinski * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 + * + * $Revision: 1.49 $ + * + * History of changes * fixed partition handling and HDIO_GETGEO */ @@ -38,6 +41,12 @@ #define DASD_FBA_CCW_LOCATE 0x43 #define DASD_FBA_CCW_DEFINE_EXTENT 0x63 +#ifdef MODULE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)) +MODULE_LICENSE("GPL"); +#endif +#endif + dasd_discipline_t dasd_fba_discipline; typedef struct @@ -123,35 +132,46 @@ dasd_fba_private_t *private; if (device == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "Null device pointer passed to characteristics checker\n"); + + MESSAGE (KERN_WARNING, "%s", + "Null device pointer passed to characteristics " + "checker"); + return -ENODEV; } device->private = kmalloc (sizeof (dasd_fba_private_t), GFP_KERNEL); + if (device->private == NULL) { - printk (KERN_WARNING PRINTK_HEADER - "memory allocation failed for private data\n"); + + MESSAGE (KERN_WARNING, "%s", + "memory allocation failed for private data"); + rc = -ENOMEM; goto fail; } private = (dasd_fba_private_t *) device->private; rdc_data = (void *) &(private->rdc_data); rc = read_dev_chars (device->devinfo.irq, &rdc_data, 32); + if (rc) { - printk (KERN_WARNING PRINTK_HEADER - "Read device characteristics returned error %d\n", rc); + + MESSAGE (KERN_WARNING, + "Read device characteristics returned error %d", + rc); + goto fail; } - printk (KERN_INFO PRINTK_HEADER - "%04X on sch %d: %04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)\n", - device->devinfo.devno, device->devinfo.irq, - device->devinfo.sid_data.dev_type, - device->devinfo.sid_data.dev_model, - device->devinfo.sid_data.cu_type, - device->devinfo.sid_data.cu_model, - (private->rdc_data.blk_bdsa * - (private->rdc_data.blk_size >> 9)) >> 11, - private->rdc_data.blk_size); + + DEV_MESSAGE (KERN_INFO, device, + "%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)", + device->devinfo.sid_data.dev_type, + device->devinfo.sid_data.dev_model, + device->devinfo.sid_data.cu_type, + device->devinfo.sid_data.cu_model, + ((private->rdc_data.blk_bdsa * + (private->rdc_data.blk_size >> 9)) >> 11), + private->rdc_data.blk_size); + goto out; fail: if ( rc ) { @@ -180,9 +200,11 @@ device->sizes.bp_block = bs; break; default: - printk (KERN_INFO PRINTK_HEADER - "/dev/%s (%04X): unknown blocksize %d\n", - device->name, device->devinfo.devno, bs); + + DEV_MESSAGE (KERN_INFO, device, + "unknown blocksize %d", + bs); + return -EMEDIUMTYPE; } device->sizes.s2b_shift = 0; /* bits to shift 512 to get a block */ @@ -247,8 +269,11 @@ { if (cqr->function == dasd_default_erp_action) return dasd_default_erp_postaction; - printk (KERN_WARNING PRINTK_HEADER - "unknown ERP action %p\n", cqr->function); + + MESSAGE (KERN_WARNING, + "unknown ERP action %p", + cqr->function); + return NULL; } @@ -265,14 +290,20 @@ struct buffer_head *bh; dasd_fba_private_t *private = (dasd_fba_private_t *) device->private; int byt_per_blk = device->sizes.bp_block; + unsigned long reloc_sector = req->sector + + device->major_info->gendisk.part[MINOR (req->rq_dev)].start_sect; if (req->cmd == READ) { rw_cmd = DASD_FBA_CCW_READ; } else if (req->cmd == WRITE) { rw_cmd = DASD_FBA_CCW_WRITE; } else { - PRINT_ERR ("Unknown command %d\n", req->cmd); - return NULL; + + MESSAGE (KERN_ERR, + "Unknown command %d\n", + req->cmd); + + return ERR_PTR(-EINVAL); } /* Build the request */ /* count hs to prevent errors, when bh smaller than block */ @@ -300,14 +331,14 @@ device); } if (!rw_cp) { - return NULL; + return ERR_PTR(-ENOMEM); } DE_data = rw_cp->data; LO_data = rw_cp->data + sizeof (DE_fba_data_t); ccw = rw_cp->cpaddr; if (define_extent (ccw, DE_data, req->cmd, byt_per_blk, - req->sector, req->nr_sectors, rw_cp, device)) { + reloc_sector, req->nr_sectors, rw_cp, device)) { goto clear_rw_cp; } ccw->flags |= CCW_FLAG_CC; @@ -363,11 +394,12 @@ } static int -dasd_fba_fill_info (dasd_device_t * device, dasd_information_t * info) +dasd_fba_fill_info (dasd_device_t * device, dasd_information2_t * info) { int rc = 0; info->label_block = 1; info->FBA_layout = 1; + info->format = DASD_FORMAT_LDL; info->characteristics_size = sizeof (dasd_fba_characteristics_t); memcpy (info->characteristics, &((dasd_fba_private_t *) device->private)->rdc_data, @@ -410,14 +442,18 @@ dump_sense:dasd_fba_dump_sense, int_handler:dasd_int_handler, fill_info:dasd_fba_fill_info, + list:LIST_HEAD_INIT(dasd_fba_discipline.list), }; int dasd_fba_init (void) { int rc = 0; - printk (KERN_INFO PRINTK_HEADER - "%s discipline initializing\n", dasd_fba_discipline.name); + + MESSAGE (KERN_INFO, + "%s discipline initializing", + dasd_fba_discipline.name); + ASCEBC (dasd_fba_discipline.ebcname, 4); dasd_discipline_add (&dasd_fba_discipline); #ifdef CONFIG_DASD_DYNAMIC @@ -426,12 +462,15 @@ for (i = 0; i < sizeof (dasd_fba_known_devices) / sizeof (devreg_t); i++) { - printk (KERN_INFO PRINTK_HEADER - "We are interested in: Dev %04X/%02X @ CU %04X/%02x\n", - dasd_fba_known_devices[i].ci.hc.dtype, - dasd_fba_known_devices[i].ci.hc.dmode, - dasd_fba_known_devices[i].ci.hc.ctype, - dasd_fba_known_devices[i].ci.hc.cmode); + + MESSAGE (KERN_INFO, + "We are interested in: " + "Dev %04X/%02X @ CU %04X/%02x", + dasd_fba_known_devices[i].ci.hc.dtype, + dasd_fba_known_devices[i].ci.hc.dmode, + dasd_fba_known_devices[i].ci.hc.ctype, + dasd_fba_known_devices[i].ci.hc.cmode); + s390_device_register (&dasd_fba_known_devices[i]); } } @@ -441,8 +480,11 @@ void dasd_fba_cleanup( void ) { - printk ( KERN_INFO PRINTK_HEADER - "%s discipline cleaning up\n", dasd_fba_discipline.name); + + MESSAGE (KERN_INFO, + "%s discipline cleaning up", + dasd_fba_discipline.name); + #ifdef CONFIG_DASD_DYNAMIC { int i; diff -urN linux-2.4.21/drivers/s390/block/dasd_fba.h linux-2.4.22/drivers/s390/block/dasd_fba.h --- linux-2.4.21/drivers/s390/block/dasd_fba.h 2001-08-05 13:12:41.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd_fba.h 2003-08-25 04:44:42.000000000 -0700 @@ -1,3 +1,15 @@ +/* + * File...........: linux/drivers/s390/block/dasd_fba.h + * Author(s)......: Holger Smolinski + * Horst Hummel + * Bugreports.to..: + * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 + * + * $Revision: 1.6 $ + * + * History of changes + * + */ #ifndef DASD_FBA_H #define DASD_FBA_H diff -urN linux-2.4.21/drivers/s390/block/dasd_int.h linux-2.4.22/drivers/s390/block/dasd_int.h --- linux-2.4.21/drivers/s390/block/dasd_int.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/s390/block/dasd_int.h 2003-08-25 04:44:42.000000000 -0700 @@ -1,9 +1,12 @@ /* - * File...........: linux/drivers/s390/block/dasd.c + * File...........: linux/drivers/s390/block/dasd_int.h * Author(s)......: Holger Smolinski + * Horst Hummel * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * + * $Revision: 1.26 $ + * * History of changes (starts July 2000) * 02/01/01 added dynamic registration of ioctls */ @@ -11,8 +14,6 @@ #ifndef DASD_INT_H #define DASD_INT_H -#define DASD_API_VERSION 0 - #include #define CONFIG_DASD_DYNAMIC @@ -28,14 +29,19 @@ #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01 #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02 -#define DASD_STATE_DEL -1 -#define DASD_STATE_NEW 0 -#define DASD_STATE_KNOWN 1 -#define DASD_STATE_ACCEPT 2 -#define DASD_STATE_INIT 3 -#define DASD_STATE_READY 4 -#define DASD_STATE_ONLINE 5 - +#define DASD_STATE_DEL -1 /* "unknown" */ +#define DASD_STATE_NEW 0 /* memory for dasd_device_t and lowmem ccw/idals allocated */ +#define DASD_STATE_BOXED 1 /* boxed dasd could not be analysed "plugged" */ +#define DASD_STATE_KNOWN 2 /* major_info/devinfo/discipline/devfs-'device'/gendisk - "detected" */ +#define DASD_STATE_ACCEPT 3 /* irq requested - "accepted" */ +#define DASD_STATE_INIT 4 /* init_cqr started - "busy" */ +#define DASD_STATE_READY 5 /* init finished - "fenced(plugged)" */ +#define DASD_STATE_ONLINE 6 /* unplugged "active" */ + +#define DASD_HOTPLUG_EVENT_ADD 0 +#define DASD_HOTPLUG_EVENT_REMOVE 1 +#define DASD_HOTPLUG_EVENT_PARTCHK 2 +#define DASD_HOTPLUG_EVENT_PARTREMOVE 3 #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01 #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02 @@ -61,7 +67,9 @@ #include #include -/* Kernel Version Compatibility section */ +/******************************************************************************** + * SECTION: Kernel Version Compatibility section + ********************************************************************************/ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) typedef struct request *request_queue_t; #define block_device_operations file_operations @@ -102,6 +110,7 @@ *q = req->next; req->next = NULL; } + #else #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \ do { \ @@ -124,9 +133,12 @@ { blkdev_dequeue_request (req); } -#endif +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) */ + +/******************************************************************************** + * SECTION: Type definitions + ********************************************************************************/ -/* dasd_range_t are used for dynamic device att-/detachment */ typedef struct dasd_devreg_t { devreg_t devreg; /* the devreg itself */ /* build a linked list of devregs, needed for cleanup */ @@ -153,27 +165,6 @@ #define DASD_SENSE_BIT_2 0x20 #define DASD_SENSE_BIT_3 0x10 -#define check_then_set(where,from,to) \ -do { \ - if ((*(where)) != (from) ) { \ - printk (KERN_ERR PRINTK_HEADER "was %d\n", *(where)); \ - BUG(); \ - } \ - (*(where)) = (to); \ -} while (0) - -#define DASD_MESSAGE(d_loglevel,d_device,d_string,d_args...)\ -do { \ - int d_devno = d_device->devinfo.devno; \ - int d_irq = d_device->devinfo.irq; \ - char *d_name = d_device->name; \ - int d_major = MAJOR(d_device->kdev); \ - int d_minor = MINOR(d_device->kdev); \ - printk(d_loglevel PRINTK_HEADER \ - "/dev/%s(%d:%d),%04x@0x%x:" \ - d_string "\n",d_name,d_major,d_minor,d_devno,d_irq,d_args ); \ -} while(0) - /* * struct dasd_sizes_t * represents all data needed to access dasd with properly set up sectors @@ -196,68 +187,164 @@ ccw_req_t *tail; } dasd_chanq_t; -#define DASD_DEVICE_FORMAT_STRING "Device: %p" -#define DASD_DEVICE_DEBUG_EVENT(d_level, d_device, d_str, d_data...)\ -do {\ - if ( d_device->debug_area != NULL )\ - debug_sprintf_event(d_device->debug_area,d_level,\ - DASD_DEVICE_FORMAT_STRING d_str "\n",\ - d_device, d_data);\ +/* + * struct dasd_lowmem_t + * represents a queue of pages for lowmem request + */ +typedef struct { + struct list_head list; +} dasd_lowmem_t; + +#define DASD_LOWMEM_PAGES 2 /* # of lowmem pages per device (min 2) */ + +/******************************************************************************** + * SECTION: MACROS + ********************************************************************************/ + +/* + * CHECK_THEN_SET + * + * Change 'where' value from 'from' to 'to'. + ' BUG if the 'from' value doesn't match. + */ +#define check_then_set(where,from,to) \ +do { \ + if ((*(where)) != (from) ) { \ + printk (KERN_ERR PRINTK_HEADER "was %d\n", *(where)); \ + BUG(); \ + } \ + (*(where)) = (to); \ } while(0) -#define DASD_DEVICE_DEBUG_EXCEPTION(d_level, d_device, d_str, d_data...)\ -do {\ - if ( d_device->debug_area != NULL )\ - debug_sprintf_exception(d_device->debug_area,d_level,\ - DASD_DEVICE_FORMAT_STRING d_str "\n",\ - d_device, d_data);\ + + +/******************************************************************************** + * SECION: MACROs for klogd and s390 debug feature (dbf) + ********************************************************************************/ + +#define DBF_DEV_EVENT(d_level, d_device, d_str, d_data...) \ +do { \ + if (d_device->debug_area != NULL) \ + debug_sprintf_event(d_device->debug_area, \ + d_level, \ + d_str "\n", \ + d_data); \ +} while(0) + +#define DBF_DEV_EXC(d_level, d_device, d_str, d_data...) \ +do { \ + if (d_device->debug_area != NULL) \ + debug_sprintf_exception(d_device->debug_area, \ + d_level, \ + d_str "\n", \ + d_data); \ +} while(0) + +#define DBF_EVENT(d_level, d_str, d_data...)\ +do { \ + if (dasd_debug_area != NULL) \ + debug_sprintf_event(dasd_debug_area, \ + d_level,\ + d_str "\n", \ + d_data); \ +} while(0) + +#define DBF_EXC(d_level, d_str, d_data...)\ +do { \ + if (dasd_debug_area != NULL) \ + debug_sprintf_exception(dasd_debug_area, \ + d_level,\ + d_str "\n", \ + d_data); \ } while(0) -#define DASD_DRIVER_FORMAT_STRING "Driver: <[%p]>" -#define DASD_DRIVER_DEBUG_EVENT(d_level, d_fn, d_str, d_data...)\ -do {\ - if ( dasd_debug_area != NULL )\ - debug_sprintf_event(dasd_debug_area, d_level,\ - DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "\n",\ - d_fn, d_data);\ +/* definition of dbf debug levels */ +#define DBF_EMERG 0 /* system is unusable */ +#define DBF_ALERT 1 /* action must be taken immediately */ +#define DBF_CRIT 2 /* critical conditions */ +#define DBF_ERR 3 /* error conditions */ +#define DBF_WARNING 4 /* warning conditions */ +#define DBF_NOTICE 5 /* normal but significant condition */ +#define DBF_INFO 6 /* informational */ +#define DBF_DEBUG 6 /* debug-level messages */ + +/* messages to be written via klogd and dbf */ +#define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\ +do { \ + int d_devno = d_device->devinfo.devno; \ + int d_irq = d_device->devinfo.irq; \ + char *d_name = d_device->name; \ + int d_major = MAJOR(d_device->kdev); \ + int d_minor = MINOR(d_device->kdev); \ +\ + printk(d_loglevel PRINTK_HEADER \ + " /dev/%-7s(%3d:%3d),%04x@%02x: " \ + d_string "\n", \ + d_name, \ + d_major, \ + d_minor, \ + d_devno, \ + d_irq, \ + d_args); \ +\ + DBF_DEV_EVENT(DBF_ALERT, \ + d_device, \ + d_string, \ + d_args); \ } while(0) -#define DASD_DRIVER_DEBUG_EXCEPTION(d_level, d_fn, d_str, d_data...)\ -do {\ - if ( dasd_debug_area != NULL )\ - debug_sprintf_exception(dasd_debug_area, d_level,\ - DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "\n",\ - d_fn, d_data);\ + +#define MESSAGE(d_loglevel,d_string,d_args...)\ +do { \ + printk(d_loglevel PRINTK_HEADER \ + " " d_string "\n", \ + d_args); \ +\ + DBF_EVENT(DBF_ALERT, \ + d_string, \ + d_args); \ } while(0) struct dasd_device_t; struct request; -/* - * signatures for the functions of dasd_discipline_t +/******************************************************************************** + * SECTION: signatures for the functions of dasd_discipline_t * make typecasts much easier - */ -typedef ccw_req_t *(*dasd_erp_action_fn_t) (ccw_req_t * cqr); + ********************************************************************************/ + +typedef int (*dasd_ck_id_fn_t) (s390_dev_info_t *); +typedef int (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *); +typedef int (*dasd_fill_geometry_fn_t) (struct dasd_device_t *, + struct hd_geometry *); +typedef int (*dasd_do_analysis_fn_t) (struct dasd_device_t *); +typedef int (*dasd_io_starter_fn_t) (ccw_req_t *); +typedef int (*dasd_io_stopper_fn_t) (ccw_req_t *); +typedef int (*dasd_info_fn_t) (struct dasd_device_t *, + dasd_information2_t *); +typedef int (*dasd_use_count_fn_t) (int); +typedef int (*dasd_set_attrib_fn_t) (struct dasd_device_t *, + struct attrib_data_t *); +typedef void (*dasd_int_handler_fn_t) (int irq, void *, + struct pt_regs *); +typedef char * (*dasd_dump_sense_fn_t) (struct dasd_device_t *, + ccw_req_t *); +typedef ccw_req_t *(*dasd_format_fn_t) (struct dasd_device_t *, + struct format_data_t *); +typedef ccw_req_t *(*dasd_init_analysis_fn_t ) (struct dasd_device_t *); +typedef ccw_req_t *(*dasd_cp_builder_fn_t) (struct dasd_device_t *, + struct request *); +typedef ccw_req_t *(*dasd_reserve_fn_t) (struct dasd_device_t *); +typedef ccw_req_t *(*dasd_release_fn_t) (struct dasd_device_t *); +typedef ccw_req_t *(*dasd_steal_lock_fn_t) (struct dasd_device_t *); +typedef ccw_req_t *(*dasd_merge_cp_fn_t) (struct dasd_device_t *); +typedef ccw_req_t *(*dasd_erp_action_fn_t) (ccw_req_t * cqr); typedef ccw_req_t *(*dasd_erp_postaction_fn_t) (ccw_req_t * cqr); +typedef ccw_req_t *(*dasd_read_stats_fn_t) (struct dasd_device_t *); -typedef int (*dasd_ck_id_fn_t) (s390_dev_info_t *); -typedef int (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *); -typedef int (*dasd_fill_geometry_fn_t) (struct dasd_device_t *, struct hd_geometry *); -typedef ccw_req_t *(*dasd_format_fn_t) (struct dasd_device_t *, struct format_data_t *); -typedef ccw_req_t *(*dasd_init_analysis_fn_t) (struct dasd_device_t *); -typedef int (*dasd_do_analysis_fn_t) (struct dasd_device_t *); -typedef int (*dasd_io_starter_fn_t) (ccw_req_t *); -typedef int (*dasd_io_stopper_fn_t) (ccw_req_t *); -typedef void (*dasd_int_handler_fn_t)(int irq, void *, struct pt_regs *); -typedef dasd_era_t (*dasd_error_examine_fn_t) (ccw_req_t *, devstat_t * stat); -typedef dasd_erp_action_fn_t (*dasd_error_analyse_fn_t) (ccw_req_t *); -typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t) (ccw_req_t *); -typedef ccw_req_t *(*dasd_cp_builder_fn_t)(struct dasd_device_t *,struct request *); -typedef char *(*dasd_dump_sense_fn_t)(struct dasd_device_t *,ccw_req_t *); -typedef ccw_req_t *(*dasd_reserve_fn_t)(struct dasd_device_t *); -typedef ccw_req_t *(*dasd_release_fn_t)(struct dasd_device_t *); -typedef ccw_req_t *(*dasd_steal_lock_fn_t)(struct dasd_device_t *); -typedef ccw_req_t *(*dasd_merge_cp_fn_t)(struct dasd_device_t *); -typedef int (*dasd_info_fn_t) (struct dasd_device_t *, dasd_information_t *); -typedef int (*dasd_use_count_fn_t) (int); +typedef dasd_rssd_perf_stats_t * (*dasd_ret_stats_fn_t) (ccw_req_t *); +typedef dasd_era_t (*dasd_error_examine_fn_t) (ccw_req_t *, + devstat_t * stat); +typedef dasd_erp_action_fn_t (*dasd_error_analyse_fn_t) (ccw_req_t *); +typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t) (ccw_req_t *); /* * the dasd_discipline_t is @@ -270,31 +357,31 @@ char ebcname[8]; /* a name used for tagging and printks */ char name[8]; /* a name used for tagging and printks */ int max_blocks; /* maximum number of blocks to be chained */ - dasd_ck_id_fn_t id_check; /* to check sense data */ - dasd_ck_characteristics_fn_t check_characteristics; /* to check the characteristics */ - dasd_init_analysis_fn_t init_analysis; /* to start the analysis of the volume */ - dasd_do_analysis_fn_t do_analysis; /* to complete the analysis of the volume */ - dasd_fill_geometry_fn_t fill_geometry; /* to set up hd_geometry */ - dasd_io_starter_fn_t start_IO; - dasd_io_stopper_fn_t term_IO; - dasd_format_fn_t format_device; /* to format the device */ - dasd_error_examine_fn_t examine_error; - dasd_error_analyse_fn_t erp_action; - dasd_erp_analyse_fn_t erp_postaction; - dasd_cp_builder_fn_t build_cp_from_req; - dasd_dump_sense_fn_t dump_sense; - dasd_int_handler_fn_t int_handler; - dasd_reserve_fn_t reserve; - dasd_release_fn_t release; - dasd_steal_lock_fn_t steal_lock; - dasd_merge_cp_fn_t merge_cp; - dasd_info_fn_t fill_info; + dasd_ck_id_fn_t id_check; /* check sense data */ + dasd_ck_characteristics_fn_t check_characteristics; /* check the characteristics */ + dasd_init_analysis_fn_t init_analysis; /* start the analysis of the volume */ + dasd_do_analysis_fn_t do_analysis; /* complete the analysis of the volume */ + dasd_fill_geometry_fn_t fill_geometry; /* set up hd_geometry */ + dasd_io_starter_fn_t start_IO; + dasd_io_stopper_fn_t term_IO; + dasd_format_fn_t format_device; /* format the device */ + dasd_error_examine_fn_t examine_error; + dasd_error_analyse_fn_t erp_action; + dasd_erp_analyse_fn_t erp_postaction; + dasd_cp_builder_fn_t build_cp_from_req; + dasd_dump_sense_fn_t dump_sense; + dasd_int_handler_fn_t int_handler; + dasd_reserve_fn_t reserve; + dasd_release_fn_t release; + dasd_steal_lock_fn_t steal_lock; + dasd_merge_cp_fn_t merge_cp; + dasd_info_fn_t fill_info; + dasd_read_stats_fn_t read_stats; + dasd_ret_stats_fn_t ret_stats; /* return performance statistics */ + dasd_set_attrib_fn_t set_attrib; /* set attributes (cache operations */ struct list_head list; /* used for list of disciplines */ } dasd_discipline_t; -#define DASD_DEFAULT_FEATURES 0 -#define DASD_FEATURE_READONLY 1 - /* dasd_range_t are used for ordering the DASD devices */ typedef struct dasd_range_t { unsigned int from; /* first DASD in range */ @@ -326,7 +413,9 @@ struct dasd_chanq_t queue; wait_queue_head_t wait_q; request_queue_t *request_queue; - struct timer_list timer; + struct timer_list timer; /* used for start_IO */ + struct timer_list late_timer; /* to get late devices online */ + struct timer_list blocking_timer; /* used for ERP */ devstat_t dev_status; /* needed ONLY!! for request_irq */ dasd_sizes_t sizes; char name[16]; /* The name of the device in /dev */ @@ -340,35 +429,37 @@ dasd_profile_info_t profile; ccw_req_t *init_cqr; atomic_t plugged; - void* lowmem_cqr; - void* lowmem_ccws; - void* lowmem_idals; - void* lowmem_idal_ptr; + int accessible; /* set to !=0 if doing IO is permitted */ + struct list_head lowmem_pool; } dasd_device_t; -int dasd_init (void); -void dasd_discipline_add(dasd_discipline_t *); -void dasd_discipline_del(dasd_discipline_t *); -int dasd_start_IO (ccw_req_t *); -int dasd_term_IO (ccw_req_t *); -void dasd_int_handler (int , void *, struct pt_regs *); -ccw_req_t *dasd_default_erp_action (ccw_req_t *); -ccw_req_t *dasd_default_erp_postaction (ccw_req_t *); -inline void dasd_chanq_deq (dasd_chanq_t *, ccw_req_t *); -inline void dasd_chanq_enq (dasd_chanq_t *, ccw_req_t *); -inline void dasd_chanq_enq_head (dasd_chanq_t *, ccw_req_t *); -ccw_req_t *dasd_alloc_request (char *, int, int, dasd_device_t *); -void dasd_free_request (ccw_req_t *, dasd_device_t *); -int dasd_oper_handler (int irq, devreg_t * devreg); -void dasd_schedule_bh (dasd_device_t *); -int dasd_sleep_on_req(ccw_req_t*); -int dasd_set_normalized_cda ( ccw1_t * cp, unsigned long address, ccw_req_t* request, dasd_device_t* device ); -dasd_device_t * dasd_device_from_kdev (kdev_t kdev); + +int dasd_init (void); +void dasd_discipline_add (dasd_discipline_t *); +void dasd_discipline_del (dasd_discipline_t *); +int dasd_start_IO (ccw_req_t *); +int dasd_term_IO (ccw_req_t *); +void dasd_int_handler (int , void *, struct pt_regs *); +void dasd_free_request (ccw_req_t *, dasd_device_t *); +int dasd_oper_handler (int irq, devreg_t * devreg); +void dasd_schedule_bh (dasd_device_t *); +void dasd_schedule_bh_timed (unsigned long); +int dasd_sleep_on_req (ccw_req_t*); +int dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, + ccw_req_t* request, + dasd_device_t* device ); +ccw_req_t * dasd_default_erp_action (ccw_req_t *); +ccw_req_t * dasd_default_erp_postaction (ccw_req_t *); +inline void dasd_chanq_deq (dasd_chanq_t *, ccw_req_t *); +inline void dasd_chanq_enq (dasd_chanq_t *, ccw_req_t *); +inline void dasd_chanq_enq_head (dasd_chanq_t *, ccw_req_t *); +ccw_req_t * dasd_alloc_request (char *, int, int, dasd_device_t *); +dasd_device_t * dasd_device_from_kdev (kdev_t kdev); extern debug_info_t *dasd_debug_area; extern int (*genhd_dasd_name) (char *, int, int, struct gendisk *); extern int (*genhd_dasd_ioctl) (struct inode *inp, struct file *filp, - unsigned int no, unsigned long data); + unsigned int no, unsigned long data); #endif /* __KERNEL__ */ diff -urN linux-2.4.21/drivers/s390/char/con3215.c linux-2.4.22/drivers/s390/char/con3215.c --- linux-2.4.21/drivers/s390/char/con3215.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/s390/char/con3215.c 2003-08-25 04:44:42.000000000 -0700 @@ -462,30 +462,35 @@ if ((raw = req->info) == NULL) return; /* That shouldn't happen ... */ if (req->type == RAW3215_READ && raw->tty != NULL) { - char *cchar; + unsigned int cchar; tty = raw->tty; - count = 160 - req->residual; - if (MACHINE_IS_P390) { - slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE); - if (count > slen) - count = slen; - } else + count = 160 - req->residual; + if (MACHINE_IS_P390) { + slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE); + if (count > slen) + count = slen; + } else if (count >= TTY_FLIPBUF_SIZE - tty->flip.count) count = TTY_FLIPBUF_SIZE - tty->flip.count - 1; EBCASC(raw->inbuf, count); - if ((cchar = ctrlchar_handle(raw->inbuf, count, tty))) { - if (cchar == (char *)-1) - goto in_out; + cchar = ctrlchar_handle(raw->inbuf, count, tty); + switch (cchar & CTRLCHAR_MASK) { + case CTRLCHAR_SYSRQ: + break; + + case CTRLCHAR_CTRL: tty->flip.count++; *tty->flip.flag_buf_ptr++ = TTY_NORMAL; - *tty->flip.char_buf_ptr++ = *cchar; + *tty->flip.char_buf_ptr++ = cchar; tty_flip_buffer_push(raw->tty); - } else { + break; + + case CTRLCHAR_NONE: memcpy(tty->flip.char_buf_ptr, raw->inbuf, count); if (count < 2 || - (strncmp(raw->inbuf+count-2, "^n", 2) || + (strncmp(raw->inbuf+count-2, "^n", 2) && strncmp(raw->inbuf+count-2, "\252n", 2)) ) { /* don't add the auto \n */ tty->flip.char_buf_ptr[count] = '\n'; @@ -498,12 +503,12 @@ tty->flip.flag_buf_ptr += count; tty->flip.count += count; tty_flip_buffer_push(raw->tty); + break; } } else if (req->type == RAW3215_WRITE) { raw->count -= req->len; raw->written -= req->len; } -in_out: raw->flags &= ~RAW3215_WORKING; raw3215_free_req(req); /* check for empty wait */ @@ -823,7 +828,8 @@ * The console structure for the 3215 console */ static struct console con3215 = { - name: "tty3215", + name: "ttyS", + index: 0, write: con3215_write, device: con3215_device, unblank: con3215_unblank, @@ -1120,6 +1126,9 @@ */ void __init tty3215_init(void) { + /* Don't bother registering the tty if we already skipped the console */ + if (!CONSOLE_IS_3215) + return; /* * Initialize the tty_driver structure * Entries in tty3215_driver that are NOT initialized: diff -urN linux-2.4.21/drivers/s390/char/ctrlchar.c linux-2.4.22/drivers/s390/char/ctrlchar.c --- linux-2.4.21/drivers/s390/char/ctrlchar.c 2001-09-30 12:26:07.000000000 -0700 +++ linux-2.4.22/drivers/s390/char/ctrlchar.c 2003-08-25 04:44:42.000000000 -0700 @@ -8,32 +8,30 @@ */ #include -#include -#include -#include - +#include #include +#include +#include -#include -#include -#include -#include -#include +#include "ctrlchar.h" #ifdef CONFIG_MAGIC_SYSRQ static int ctrlchar_sysrq_key; static struct tq_struct ctrlchar_tq; static void -ctrlchar_handle_sysrq(struct tty_struct *tty) { - handle_sysrq(ctrlchar_sysrq_key, NULL, NULL, tty); +ctrlchar_handle_sysrq(void *tty) +{ + handle_sysrq(ctrlchar_sysrq_key, NULL, NULL, (struct tty_struct*) tty); } #endif -void ctrlchar_init(void) { +void +ctrlchar_init(void) +{ #ifdef CONFIG_MAGIC_SYSRQ static int init_done = 0; - + if (init_done++) return; INIT_LIST_HEAD(&ctrlchar_tq.list); @@ -48,49 +46,43 @@ * @param buf Console input buffer. * @param len Length of valid data in buffer. * @param tty The tty struct for this console. - * @return NULL, if nothing matched, (char *)-1, if buffer contents - * should be ignored, otherwise pointer to char to be inserted. + * @return CTRLCHAR_NONE, if nothing matched, + * CTRLCHAR_SYSRQ, if sysrq was encountered + * otherwise char to be inserted logically or'ed + * with CTRLCHAR_CTRL */ -char *ctrlchar_handle(const char *buf, int len, struct tty_struct *tty) { - - static char ret; - +unsigned int +ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) +{ if ((len < 2) || (len > 3)) - return NULL; + return CTRLCHAR_NONE; + /* hat is 0xb1 in codepage 037 (US etc.) and thus */ /* converted to 0x5e in ascii ('^') */ if ((buf[0] != '^') && (buf[0] != '\252')) - return NULL; - switch (buf[1]) { + return CTRLCHAR_NONE; + #ifdef CONFIG_MAGIC_SYSRQ - case '-': - if (len == 3) { - ctrlchar_sysrq_key = buf[2]; - ctrlchar_tq.data = tty; - queue_task(&ctrlchar_tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); - return (char *)-1; - } - break; + /* racy */ + if (len == 3 && buf[1] == '-') { + ctrlchar_sysrq_key = buf[2]; + ctrlchar_tq.data = tty; + queue_task(&ctrlchar_tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); + return CTRLCHAR_SYSRQ; + } #endif - case 'c': - if (len == 2) { - ret = INTR_CHAR(tty); - return &ret; - } - break; - case 'd': - if (len == 2) { - ret = EOF_CHAR(tty); - return &ret; - } - break; - case 'z': - if (len == 2) { - ret = SUSP_CHAR(tty); - return &ret; - } - break; + + if (len != 2) + return CTRLCHAR_NONE; + + switch (tolower(buf[1])) { + case 'c': + return INTR_CHAR(tty) | CTRLCHAR_CTRL; + case 'd': + return EOF_CHAR(tty) | CTRLCHAR_CTRL; + case 'z': + return SUSP_CHAR(tty) | CTRLCHAR_CTRL; } - return NULL; + return CTRLCHAR_NONE; } diff -urN linux-2.4.21/drivers/s390/char/ctrlchar.h linux-2.4.22/drivers/s390/char/ctrlchar.h --- linux-2.4.21/drivers/s390/char/ctrlchar.h 2001-07-25 14:12:02.000000000 -0700 +++ linux-2.4.22/drivers/s390/char/ctrlchar.h 2003-08-25 04:44:42.000000000 -0700 @@ -7,9 +7,15 @@ * */ -#include -#include #include +extern unsigned int +ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty); extern void ctrlchar_init(void); -extern char *ctrlchar_handle(const char *buf, int len, struct tty_struct *tty); + + +#define CTRLCHAR_NONE (1 << 8) +#define CTRLCHAR_CTRL (2 << 8) +#define CTRLCHAR_SYSRQ (3 << 8) + +#define CTRLCHAR_MASK (~0xffu) diff -urN linux-2.4.21/drivers/s390/misc/chandev.c linux-2.4.22/drivers/s390/misc/chandev.c --- linux-2.4.21/drivers/s390/misc/chandev.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/s390/misc/chandev.c 2003-08-25 04:44:42.000000000 -0700 @@ -2470,6 +2470,7 @@ goto BadArgs; } + break; case del_auto_msck_stridx*stridx_mult: case (del_auto_msck_stridx*stridx_mult)|iscomma: switch(ints[0]) @@ -2482,6 +2483,7 @@ default: goto BadArgs; } + break; case del_noauto_stridx*stridx_mult: chandev_free_all_list((list **)&chandev_noauto_head); break; diff -urN linux-2.4.21/drivers/s390/net/Makefile linux-2.4.22/drivers/s390/net/Makefile --- linux-2.4.21/drivers/s390/net/Makefile 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/s390/net/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -12,6 +12,9 @@ obj-$(CONFIG_IUCV) += iucv.o fsm.o obj-$(CONFIG_CTC) += ctc.o fsm.o obj-$(CONFIG_IUCV) += netiucv.o +obj-$(CONFIG_C7000) += c7000.o +obj-$(CONFIG_QETH) += qeth.o +export-objs += qeth.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/s390/net/c7000.c linux-2.4.22/drivers/s390/net/c7000.c --- linux-2.4.21/drivers/s390/net/c7000.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/s390/net/c7000.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,3293 @@ +/* + Cisco/7000 driver -- Copyright (C) 2000 UTS Global LLC. + Author: Bob Scardapane (UTS Global LLC). + Version: 3. + + To use this driver, run the LINUX command: + + insmod c7000 base0=0xYYYY lhost0=s1 uhost0=s2 lappl0=s3 uappl0=s4 dbg=x + + base0=0xYYYY defines the base unit address of the interface. + lhost0=s1 defines the local host name. + uhost0=s2 defines the unit host name. + lappl0=s3 defines the local application name. + uappl0=s4 defines the unit application name. + dbg=x defines the message level. Higher values will result in + additional diagnostic messages. + + Additional interfaces are defined on insmod by using the variable + name groups "base1,lhost1,lappl1,uhost1,uappl1", etc... up to three + additional groups. + + In addition, the module will automatically detect the unit base + addresses by scanning all active irq's for a control unit type + of 0x3088 and a model of 0x61 (CLAW mode). The noauto parameter + can be used to suppress automatic detection. + + The values of lhostx, lapplx, uhostx and uapplx default to: + + lapplx - TCPIP + lhostx - UTS + uapplx - TCPIP + uhostx - C7011 + + Note that the values passed in the insmod command will always + override the automatic detection of the unit base addreeses and + the default values of lapplx, lhostx, uapplx and uhostx. + + The parameter noauto can be used to disable automatic detection of + devices: + + noauto=1 (disable automatic detection) + noauto=0 (Enable automatic detectio. This is the default value.) + + The values in base0 - base3 will be copied to the bases array when + the module is loaded. + + To configure the interface(s), run the LINUX command(s): + + ifconfig ci0 ... + ifconfig ci1 ... + ifconfig ci2 ... + ifconfig ci3 ... + + There is one device structure for each controller in the c7000_devices + array. The base address of each controller is in the bases array. + These arrays parallel each other. There is also one c7000_controller + structure for each controller. This structure is pointed to by field + priv in the individual device structure. + + In each c7000_controller, there are embedded c7000_unit structures. + There is one c7000_unit structure per device number that makes up + a controller (currently 2 units per controller). +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + Global defines +*/ + +/* + Maximum number of controllers. +*/ + +#define MAX_C7000 4 + +/* + Number of units per controller. +*/ + +#define NUNITS 2 + +/* + Define indexes of read and write units in the cunits array. +*/ + +#define C7000_RD 0 +#define C7000_WR 1 + +/* + Number of device buffers. +*/ + +#define C7000_MAXBUF 40 + +/* + Transmission queue length. +*/ + +#define C7000_TXQUEUE_LEN 100 +/* + Size of the IP packet data. +*/ + +#define C7000_DATAL 4096 + +/* + Size of the read header data. +*/ + +#define C7000_READHDRL 4 + +/* + Size of read flag byte. +*/ + +#define C7000_READFFL 1 + +/* + Size of a device buffer. This is how it is arranged in memory: + 4096 (IP packet data) + 4 (read header) + 1 (read flag) = 4101. +*/ + +#define C7000_BUFSIZE C7000_DATAL + C7000_READHDRL + C7000_READFFL + +/* + Size of sigsmod data. +*/ + +#define C7000_SIGSMODL 1 + +/* + Flag value that indicates a read was completed in the flag + field of a c7000_rd_header. +*/ + +#define FLAG_FF 0xff +/* + Size of C7000 sense id data. +*/ + +#define SIDL 32 + +/* + Maximum number of read and write retries. +*/ + +#define C7000_MAX_RETRIES 3 + +/* + Define sense byte0 value for a box reset. +*/ + +#define C7000_BOX_RESET 0x41 + +/* + CCW commands. +*/ + +#define C7000_WRITE_CCW 0x01 /* normal write */ +#define C7000_READ_CCW 0x02 /* normal read */ +#define C7000_NOOP_CCW 0x03 /* no operation */ +#define C7000_SIGSMOD_CCW 0x05 /* signal status modifier */ +#define C7000_TIC_CCW 0x08 /* transfer in channel */ +#define C7000_READHDR_CCW 0x12 /* read header */ +#define C7000_READFF_CCW 0x22 /* read FF flag */ +#define C7000_SID_CCW 0xe4 /* sense identification */ + +/* + Control commands. +*/ + +#define C7000_SYS_VALIDATE 1 +#define C7000_SYS_VALIDATE_RESP 2 +#define C7000_CONN_REQ 33 +#define C7000_CONN_RESP 34 +#define C7000_CONN_CONFRM 35 +#define C7000_DISCONN 36 +#define C7000_BOXERROR 65 + +/* + State machine values. +*/ + +#define C7000_INIT 1 +#define C7000_HALT 2 +#define C7000_SID 3 +#define C7000_SYSVAL 4 +#define C7000_CONNECT 5 +#define C7000_READY 6 +#define C7000_READ 7 +#define C7000_WRITE 8 +#define C7000_DISC 9 +#define C7000_STOP 10 +#define C7000_STOPPED 11 +#define C7000_ERROR 12 + +/* + The lower subchannel is used for read operations and the one that is + one higher is used for write operations. + + Both subchannels are initially in state C7000_INIT. A transition to + state C7000_HALT occurs when halt_IO is issued on each. When the + halts completes a transition to state C7000_SID occurs and a channel + program is issued to do a sense identification on both subchannels. + + When the sense identification completes, the state C7000_SYSVAL is + entered on the read subchannel. A read channel program is issued. + + When the sense identification completes, the write subchannel enters + state C7000_SYSVAL and a system validation request is written. The + read subchannel is also put into this state. + + When both the system validation response is read and an inbound system + validation request is read, the inbound system validation request is + responded to and both subchannels enter the C7000_CONNECT state. + + A read channel program is posted to look for the inbound connect + request. When that is received a connection confirmation is written. + The state of both subchannels is then changed to C7000_READY. A + read channel program is then posted and the state is changed to + C7000_READ. When a read completes, the packet is sent to the higher + layers and the read channel program is restarted. + + When there is a packet to be written, state C7000_WRITE is entered + and a channel program is issued to write the data. The subchannel + is in state C7000_READY when there is nothing to be written. + + When the stop method is executed, a disconnect message is sent and + the state is changed to C7000_DISC in both subchannels. A halt_IO + will be issued to both subchannels and state C7000_STOP will be entered. + When the halt IO completes, state C7000_STOPPED will be set. + + State C7000_ERROR is set when an error occurs in the interrupt + routine. Recycle the interface (ifconfig down / ifconfig up) + to reset this state. +*/ + +/* + Results from c7000_check_csw. +*/ + +enum c7000_rupt { + C7000_NORMAL, + C7000_CHANERR, + C7000_UCK, + C7000_UCK_RESET, + C7000_UE, + C7000_ATTN, + C7000_BUSY, + C7000_OTHER +}; + +/* + Bits set in device structure tbusy field. +*/ + +#define TB_TX 0 /* sk buffer handling in progress */ +#define TB_STOP 1 /* network device stop in progress */ +#define TB_RETRY 2 /* retry in progress */ +#define TB_NOBUFFER 3 /* no buffer on free queue */ + +/* + Bit in c7000_unit.flag_a that indicates the bh routine is busy. +*/ + +#define C7000_BH_ACTIVE 0 + +#define CPrintk(level, args...) \ + if (level <= dbg) \ + printk(args) + +/* + Maximum length of a system validation string. +*/ + +#define NAMLEN 8 + +#define Err_Conn_Confirm 1 +#define Err_Names_not_Matched 166 +#define Err_C7000_NOT_READY 167 +#define Err_Duplicate 170 +#define Err_Closing 171 +#define Err_No_Such_App 172 +#define Err_Host_Not_Ready 173 +#define Err_CLOSING 174 +#define Err_Dup_Link 175 +#define Err_Wrong_Version 179 +#define Err_Wrong_Frame_Size 180 + +/* + Define a macro to extract the logical link identifier from + the c7000 read header command field. +*/ + +#define C7000_LINKID(cmd) ((unsigned char)cmd >> 3) + +/* + Define the control unit type for a Cisco 7000. +*/ + +#define C7000_CU_TYPE 0x3088 + +/* + Define the control unit model for a Cisco 7000. +*/ + +#define C7000_CU_MODEL 0x61 + +/* + Define the default system validate parameters (lapplx, + lhostx, uapplx, uhostx). +*/ + +#define C7000_DFLT_LAPPL "TCPIP" +#define C7000_DFLT_LHOST "UTS" +#define C7000_DFLT_UAPPL "TCPIP" +#define C7000_DFLT_UHOST "C7011" + +/* + Global variables. +*/ + +/* + Base device addresses of the controllers. +*/ + +static int base0 = -1; +static int base1 = -1; +static int base2 = -1; +static int base3 = -1; + +static int bases[MAX_C7000]; + +/* + Local application names. +*/ + +static char *lappl0; +static char *lappl1; +static char *lappl2; +static char *lappl3; + +/* + Local host names. +*/ + +static char *lhost0; +static char *lhost1; +static char *lhost2; +static char *lhost3; + +/* + Unit application names. +*/ + +static char *uappl0; +static char *uappl1; +static char *uappl2; +static char *uappl3; + +/* + Unit hosts names. +*/ + +static char *uhost0; +static char *uhost1; +static char *uhost2; +static char *uhost3; + +/* + Debugging level (higher numbers emit lower priority messages). +*/ + +static unsigned int dbg = 0; + +/* + Parameter that controls auto detection. +*/ + +static int noauto = 0; + +/* + Interface names. +*/ + +static char ifnames[MAX_C7000][8] = {"ci0", "ci1", "ci2", "ci3"}; + +/* + One device structure per controller. +*/ + +/* RBH Try out the new code for 2.4.0 */ +#define NEWSTUFF + +#ifdef NEWSTUFF +#define STRUCT_NET_DEVICE struct net_device +#else +#define STRUCT_NET_DEVICE struct device +#endif + +STRUCT_NET_DEVICE c7000_devices[MAX_C7000]; + +/* + Scratch variable filled in with controller name. +*/ + +static char *controller; + +/* + Identify parameters that can be passed on the LINUX insmod command. +*/ + +MODULE_AUTHOR("Robert Scardapane (UTS Global)"); +MODULE_DESCRIPTION("Network module for Cisco 7000 box."); + +MODULE_PARM(base0, "1i"); +MODULE_PARM_DESC(base0, "Base unit address for 1st C7000 box."); +MODULE_PARM(base1, "1i"); +MODULE_PARM_DESC(base1, "Base unit address for 2nd C7000 box."); +MODULE_PARM(base2, "1i"); +MODULE_PARM_DESC(base2, "Base unit address for 3rd C7000 box."); +MODULE_PARM(base3, "1i"); +MODULE_PARM_DESC(base3, "Base unit address for 4th C7000 box."); + +MODULE_PARM(lappl0, "s"); +MODULE_PARM_DESC(lappl0, "Application name for 1st C7000 box."); +MODULE_PARM(lappl1, "s"); +MODULE_PARM_DESC(lappl1, "Application name for 2nd C7000 box."); +MODULE_PARM(lappl2, "s"); +MODULE_PARM_DESC(lappl2, "Application name for 3rd C7000 box."); +MODULE_PARM(lappl3, "s"); +MODULE_PARM_DESC(lappl3, "Application name for 4th C7000 box."); + +MODULE_PARM(lhost0, "s"); +MODULE_PARM_DESC(lhost0, "Host name for 1st C7000 box."); +MODULE_PARM(lhost1, "s"); +MODULE_PARM_DESC(lhost1, "Host name for 2nd C7000 box."); +MODULE_PARM(lhost2, "s"); +MODULE_PARM_DESC(lhost2, "Host name for 3rd C7000 box."); +MODULE_PARM(lhost3, "s"); +MODULE_PARM_DESC(lhost3, "Host name for 4th C7000 box."); + +MODULE_PARM(uhost0, "s"); +MODULE_PARM_DESC(uhost0, "Unit name for 1st C7000 box."); +MODULE_PARM(uhost1, "s"); +MODULE_PARM_DESC(uhost1, "Unit name for 2nd C7000 box."); +MODULE_PARM(uhost2, "s"); +MODULE_PARM_DESC(uhost2, "Unit name for 3rd C7000 box."); +MODULE_PARM(uhost3, "s"); +MODULE_PARM_DESC(uhost3, "Unit name for 4th C7000 box."); + +MODULE_PARM(uappl0, "s"); +MODULE_PARM_DESC(uappl0, "Unit application name for 1st C7000 box."); +MODULE_PARM(uappl1, "s"); +MODULE_PARM_DESC(uappl1, "Unit application name for 2nd C7000 box."); +MODULE_PARM(uappl2, "s"); +MODULE_PARM_DESC(uappl2, "Unit application name for 3rd C7000 box."); +MODULE_PARM(uappl3, "s"); +MODULE_PARM_DESC(uappl3, "Unit application name for 4th C7000 box."); + +MODULE_PARM(dbg, "1i"); +MODULE_PARM_DESC(dbg, "Message level for debugging."); + +MODULE_PARM(noauto, "1i"); +MODULE_PARM_DESC(noauto, "Control automatic detection of unit base addresses."); + +/* + Structure used to manage unit buffers. +*/ + +struct c7000_buffer { + ccw1_t ccws[7]; /* channel program */ + struct c7000_buffer *next; /* list pointer */ + char *data; /* pointer to actual data */ + int len; /* length of the data */ +}; + +/* + C7000 Control Block. + */ + +struct c7000_control_blk { + unsigned char cmd; + unsigned char ver; + unsigned char link_id; + unsigned char correlator; + unsigned char ret_code; + unsigned char resvd1[3]; + unsigned char unitname[NAMLEN]; + unsigned char hostname[NAMLEN]; + unsigned short rdsize; /* read frame size */ + unsigned short wrtsize; /* write frame size */ + unsigned char resvd2[4]; +}; + +/* + Per unit structure contained within the c7000_controller structure. +*/ + +struct c7000_unit { + ccw1_t ccws[5]; /* control ccws */ + int devno; /* device number */ + int irq; /* subchannel number */ + int IO_active; /* IO activity flag */ + int state; /* fsm state */ + int retries; /* retry counter */ + unsigned long flag_a; /* bh activity flag */ + devstat_t devstat; /* device status */ +#ifdef NEWSTUFF + wait_queue_head_t wait; /* sleep q head */ +#else + struct wait_queue *wait; /* sleep q pointer */ +#endif + struct c7000_controller *cntlp; /* controller pointer */ + struct c7000_buffer *free; /* free buffer anchor */ + struct c7000_buffer *proc_head; /* proc head */ + struct c7000_buffer *proc_tail; /* proc tail */ + struct c7000_buffer *bh_head; /* bh head */ + struct c7000_buffer *bh_tail; /* bh tail */ + struct tq_struct tq; /* bh scheduling */ + char senseid[SIDL]; /* sense id data */ + struct c7000_control_blk control_blk; /* control block */ + unsigned char sigsmod; /* sigsmod flag */ + unsigned char readhdr[4]; /* read header */ + unsigned char readff; /* readff flag */ +}; + +/* + Private structure pointed to by dev->priv. +*/ + +struct c7000_controller { + struct net_device_stats stats; /* statistics */ + STRUCT_NET_DEVICE *dev; /* -> device struct */ + unsigned int base_addr; /* base address */ + char lappl[NAMLEN]; /* local appl */ + char lhost[NAMLEN]; /* local host */ + char uappl[NAMLEN]; /* unit appl */ + char uhost[NAMLEN]; /* unit host */ + unsigned char version; /* version = 2 */ + unsigned char linkid; /* link id */ + struct c7000_unit cunits[NUNITS]; /* embedded units */ +#ifdef NEWSTUFF + int tbusy; +#endif +}; + +/* + This is the structure returned by the C7000_READHDR_CCW. +*/ + +struct c7000_rd_header { + unsigned short len; /* packet length */ + unsigned char cmd; /* command code */ + unsigned char flag; /* flag */ +}; + +/* + Set the device structure transmission busy flag. +*/ + +#ifdef NEWSTUFF +#define c7000_set_busy(dev) netif_stop_queue(dev) +#else +static __inline__ void +c7000_set_busy(STRUCT_NET_DEVICE *dev) +{ + dev->tbusy = 1; + eieio(); + return; +} +#endif + +/* + Clear the device structure transmission busy flag. +*/ + +#ifdef NEWSTUFF +#define c7000_clear_busy(dev) netif_wake_queue(dev) +#else +static __inline__ void +c7000_clear_busy(STRUCT_NET_DEVICE *dev) +{ + dev->tbusy = 0; + eieio(); + return; +} +#endif + +/* + Extract the device structure transmission busy flag. +*/ + +#ifdef NEWSTUFF +#define c7000_check_busy(dev) netif_queue_stopped(dev) +#else +static __inline__ int +c7000_check_busy(STRUCT_NET_DEVICE *dev) +{ + eieio(); + return(dev->tbusy); +} +#endif + +/* + Set a bit in the device structure transmission busy flag. +*/ + +static __inline__ void +c7000_setbit_busy(int nr, STRUCT_NET_DEVICE *dev) +{ +#ifdef NEWSTUFF + netif_stop_queue(dev); + test_and_set_bit(nr, &((struct c7000_controller *)dev->priv)->tbusy); +#else + set_bit(nr, (void *)&dev->tbusy); +#endif + return; +} + +/* + Clear a bit in the device structure transmission busy flag. +*/ + +static __inline__ void +c7000_clearbit_busy(int nr, STRUCT_NET_DEVICE *dev) +{ +#ifdef NEWSTUFF + clear_bit(nr, &((struct c7000_controller *)dev->priv)->tbusy); + netif_wake_queue(dev); +#else + clear_bit(nr, (void *)&dev->tbusy); +#endif + return; +} + +/* + Test and set a bit in the device structure transmission busy flag. +*/ + +static __inline__ int +c7000_ts_busy(int nr, STRUCT_NET_DEVICE *dev) +{ +#ifdef NEWSTUFF + netif_stop_queue(dev); + return test_and_set_bit(nr, &((struct c7000_controller *)dev->priv)->tbusy); +#else + return(test_and_set_bit(nr, (void *)&dev->tbusy)); +#endif +} + +/* + Set the C7000 controller in the error state. +*/ + +static void +c7000_error(struct c7000_controller *ccp) +{ + int i; + struct c7000_unit *cup; + STRUCT_NET_DEVICE *dev = ccp->dev; + + for (i = 0; i < NUNITS; i++) { + cup = &ccp->cunits[i]; + cup->state = C7000_ERROR; + } + + if (dev != NULL) +#ifdef NEWSTUFF + /* RBH XXX Should we be doing this? */ + dev->state &= ~__LINK_STATE_START; +#else + dev->flags &= ~IFF_RUNNING; +#endif + + CPrintk(0, "c7000: c7000_error: base unit 0x%x is down\n", ccp->base_addr); + return; +} + +/* + Based on the SENSE ID information, fill in the + controller name. Note that this is the SENSE ID + information saved by LINUX/390 at boot time. +*/ + +static int +c7000_check_type(senseid_t *id) +{ + + switch (id->cu_type) { + + case C7000_CU_TYPE: + + if (id->cu_model == C7000_CU_MODEL) { + controller = "C7000 "; + return(0); + } + + break; + + default: + break; + } + + return(-1); +} + +/* + Check the device information for the controller. +*/ + +static int +c7000_check_devices(int devno) +{ + int i; + s390_dev_info_t temp; + + /* + Get the SENSE ID information for each device. + */ + + for (i = devno; i < (devno + NUNITS); i++) { + + if (get_dev_info_by_devno(devno, &temp) != 0) + return(-1); + + if (c7000_check_type(&temp.sid_data) == -1) + return(-1); + } + + CPrintk(1, "c7000: c7000_check_devices: device type is %s\n", controller); + return(0); +} + +/* + Issue a halt I/O to device pointed to by cup. +*/ + +static int +c7000_haltio(struct c7000_unit *cup) +{ + __u32 parm; + __u8 flags = 0x00; + __u32 saveflags; + DECLARE_WAITQUEUE(wait, current); + int rc; + + s390irq_spin_lock_irqsave(cup->irq, saveflags); + parm = (unsigned long)cup; + + if ((rc = halt_IO(cup->irq, parm, flags)) != 0) { + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return(rc); + } + + /* + Wait for the halt I/O to finish. + */ + + add_wait_queue(&cup->wait, &wait); + current->state = TASK_UNINTERRUPTIBLE; + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + schedule(); + remove_wait_queue(&cup->wait, &wait); + return(0); +} + +/* + Issue a start I/O to device pointed to by cup. +*/ + +static int +c7000_doio(struct c7000_unit *cup) +{ + __u32 parm; + __u8 flags = 0x00; + __u32 saveflags; + DECLARE_WAITQUEUE(wait, current); + int rc; + + /* + Do no further I/O while the device is in the ERROR, STOP + or STOPPED state. + */ + + if (cup->state == C7000_ERROR || cup->state == C7000_STOP || cup->state == C7000_STOPPED) + return(-1); + + s390irq_spin_lock_irqsave(cup->irq, saveflags); + parm = (unsigned long)cup; + + if ((rc = do_IO(cup->irq, &cup->ccws[0], parm, 0xff, flags)) != 0) { + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return(rc); + } + + /* + Wait for the I/O to complete. + */ + + add_wait_queue(&cup->wait, &wait); + current->state = TASK_UNINTERRUPTIBLE; + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + schedule(); + remove_wait_queue(&cup->wait, &wait); + + /* + Interrupt handling may have marked the device in ERROR. + */ + + if (cup->state == C7000_ERROR) + return(-1); + + return(0); +} + +/* + Build a channel program to do a sense id channel program. +*/ + +static void +c7000_bld_senseid_chpgm(struct c7000_unit *cup) +{ + ccw1_t *ccwp; + + ccwp = &cup->ccws[0]; + ccwp->cmd_code = C7000_SID_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(&cup->senseid); + ccwp->count = SIDL; + ccwp++; + ccwp->cmd_code = C7000_NOOP_CCW; + ccwp->flags = CCW_FLAG_SLI; + ccwp->cda = (__u32)NULL; + ccwp->count = 1; + return; +} + +/* + Build a channel program to write a control message. +*/ + +static void +c7000_bld_wrtctl_chpgm(struct c7000_unit *cup) +{ + ccw1_t *ccwp; + + ccwp = &cup->ccws[0]; + ccwp->cmd_code = C7000_WRITE_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(&cup->control_blk); + ccwp->count = sizeof(struct c7000_control_blk); + ccwp++; + ccwp->cmd_code = C7000_READFF_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(&cup->readff); + ccwp->count = C7000_READFFL; + ccwp++; + ccwp->cmd_code = C7000_TIC_CCW; + ccwp->flags = 0; + ccwp->cda = (__u32)virt_to_phys(ccwp + 1); + ccwp->count = 0; + ccwp++; + ccwp->cmd_code = C7000_NOOP_CCW; + ccwp->flags = CCW_FLAG_SLI; + ccwp->cda = (__u32)NULL; + ccwp->count = 1; + return; +} + +/* + Build a write channel program to write the indicated buffer. +*/ + +static void +c7000_bld_wrt_chpgm(struct c7000_unit *cup, struct c7000_buffer *buf) +{ + ccw1_t *ccwp; + struct c7000_controller *ccp = cup->cntlp; + + ccwp = &buf->ccws[0]; + ccwp->cmd_code = C7000_WRITE_CCW | (ccp->linkid << 3); + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(buf->data); + ccwp->count = buf->len; + ccwp++; + ccwp->cmd_code = C7000_READFF_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(buf->data + C7000_DATAL + C7000_READHDRL); + ccwp->count = C7000_READFFL; + ccwp++; + ccwp->cmd_code = C7000_TIC_CCW; + ccwp->flags = 0; + ccwp->cda = (__u32)virt_to_phys(ccwp + 1); + ccwp->count = 0; + ccwp++; + ccwp->cmd_code = C7000_NOOP_CCW; + ccwp->flags = (CCW_FLAG_SLI); + ccwp->cda = (__u32)NULL; + ccwp->count = 1; + return; +} + +/* + Build a channel program to read a control message. +*/ + +static void +c7000_bld_readctl_chpgm(struct c7000_unit *cup) +{ + ccw1_t *ccwp; + + ccwp = &cup->ccws[0]; + ccwp->cmd_code = C7000_READ_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(&cup->control_blk); + ccwp->count = sizeof(struct c7000_control_blk); + ccwp++; + ccwp->cmd_code = C7000_READHDR_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(&cup->readhdr); + ccwp->count = C7000_READHDRL; + ccwp++; + ccwp->cmd_code = C7000_SIGSMOD_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(&cup->sigsmod); + ccwp->count = C7000_SIGSMODL; + ccwp++; + ccwp->cmd_code = C7000_TIC_CCW; + ccwp->flags = 0; + ccwp->cda = (__u32)virt_to_phys(ccwp + 1); + ccwp->count = 0; + ccwp++; + ccwp->cmd_code = C7000_NOOP_CCW; + ccwp->flags = (CCW_FLAG_SLI); + ccwp->cda = (__u32)NULL; + ccwp->count = 1; + return; +} + +/* + Build a channel program to read the indicated buffer. +*/ + +static void +c7000_bld_read_chpgm(struct c7000_unit *cup, struct c7000_buffer *buf) +{ + ccw1_t *ccwp; + + ccwp = &buf->ccws[0]; + ccwp->cmd_code = C7000_READ_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(buf->data); + ccwp->count = C7000_DATAL; + ccwp++; + ccwp->cmd_code = C7000_READHDR_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(buf->data + C7000_DATAL); + ccwp->count = C7000_READHDRL; + ccwp++; + ccwp->cmd_code = C7000_SIGSMOD_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC); + ccwp->cda = (__u32)virt_to_phys(&cup->sigsmod); + ccwp->count = C7000_SIGSMODL; + ccwp++; + ccwp->cmd_code = C7000_TIC_CCW; + ccwp->flags = 0; + ccwp->cda = (__u32)virt_to_phys(ccwp + 3); + ccwp->count = 0; + ccwp++; + ccwp->cmd_code = C7000_READFF_CCW; + ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC | CCW_FLAG_PCI); + ccwp->cda = (__u32)virt_to_phys(&cup->readff); + ccwp->count = C7000_READFFL; + ccwp++; + ccwp->cmd_code = C7000_TIC_CCW; + ccwp->flags = 0; + ccwp->cda = (__u32)virt_to_phys(ccwp + 1); + ccwp->count = 0; + ccwp++; + ccwp->cmd_code = C7000_NOOP_CCW; + ccwp->flags = (CCW_FLAG_SLI); + ccwp->cda = (__u32)NULL; + ccwp->count = 1; + return; +} + +/* + Allocate buffer structure headers and buffers for all units + A return value of 0 means that all allocations worked. A -1 + means that an allocation failed. It is expected that the caller + will call c7000_free_buffers when -1 is returned. +*/ + +static int +c7000_alloc_buffers(STRUCT_NET_DEVICE *dev) +{ + int i; + int j; + char *data; + struct c7000_buffer *bufptr; + struct c7000_controller *ccp = (struct c7000_controller *) dev->priv; + struct c7000_unit *cup; + + for (i = 0; i < NUNITS; i++) { + cup = &ccp->cunits[i]; + cup->free = NULL; + + for (j = 0; j < C7000_MAXBUF; j++) { + bufptr = kmalloc(sizeof(struct c7000_buffer), GFP_KERNEL); + data = kmalloc(C7000_BUFSIZE, GFP_KERNEL); + + if (bufptr == NULL) + { + if(data) + kfree(data); + return(-1); + } + + /* + Place filled in buffer header on free anchor. + */ + + bufptr->next = cup->free; + bufptr->data = data; + bufptr->len = 0; + cup->free = bufptr; + + if (data == NULL) + return(-1); + + memset(data, '\0', C7000_BUFSIZE); + } + + } + + CPrintk(1, "c7000: c7000_alloc_buffers: allocated buffers for base unit 0x%lx\n", dev->base_addr); + return(0); +} + +/* + Free buffers on a chain. +*/ + +static void +c7000_free_chain(struct c7000_buffer *buf) +{ + char *data; + struct c7000_buffer *bufptr = buf; + struct c7000_buffer *tmp; + + while (bufptr != NULL) { + data = bufptr->data; + + if (data != NULL) + kfree(data); + + tmp = bufptr; + bufptr = bufptr->next; + kfree(tmp); + } + + return; +} + +/* + Free buffers on all possible chains for all units. +*/ + +static void +c7000_free_buffers(STRUCT_NET_DEVICE *dev) +{ + int i; + struct c7000_controller *ccp = (struct c7000_controller *) dev->priv; + struct c7000_unit *cup; + + for (i = 0; i < NUNITS; i++) { + cup = &ccp->cunits[i]; + c7000_free_chain(cup->free); + cup->free = NULL; + c7000_free_chain(cup->proc_head); + cup->proc_head = cup->proc_tail = NULL; + c7000_free_chain(cup->bh_head); + cup->bh_head = cup->bh_tail = NULL; + } + + CPrintk(1, "c7000: c7000_free_buffers: freed buffers for base unit 0x%lx\n", dev->base_addr); + return; +} + +/* + Obtain a free buffer. Return a pointer to the c7000_buffer + structure OR NULL. +*/ + +struct c7000_buffer * +c7000_get_buffer(struct c7000_unit *cup) +{ + struct c7000_buffer *buf; + + buf = cup->free; + + if (buf == NULL) + return(NULL); + + cup->free = buf->next; + buf->next = NULL; + return(buf); +} + +/* + Release a buffer to the free list. +*/ + +void +c7000_release_buffer(struct c7000_unit *cup, struct c7000_buffer *buf) +{ + struct c7000_buffer *tmp; + + tmp = cup->free; + cup->free = buf; + buf->next = tmp; + return; +} + +/* + Queue a buffer on the end of the processing (proc) chain. +*/ + +void +c7000_queue_buffer(struct c7000_unit *cup, struct c7000_buffer *buf) +{ + buf->next = NULL; + + if (cup->proc_head == NULL) { + cup->proc_head = cup->proc_tail = buf; + return; + } + + cup->proc_tail->next = buf; + cup->proc_tail = buf; + return; +} + +/* + Dequeue a buffer from the start of the processing (proc) chain. +*/ + +struct c7000_buffer * +c7000_dequeue_buffer(struct c7000_unit *cup) +{ + struct c7000_buffer *buf = cup->proc_head; + + if (buf == NULL) + return(NULL); + + cup->proc_head = buf->next; + + if (cup->proc_head == NULL) + cup->proc_tail = NULL; + + buf->next = NULL; + return(buf); +} + +/* + Queue a buffer on the end of the bh routine chain. +*/ + +void +c7000_queue_bh_buffer(struct c7000_unit *cup, struct c7000_buffer *buf) +{ + buf->next = NULL; + + if (cup->bh_head == NULL) { + cup->bh_head = cup->bh_tail = buf; + return; + } + + cup->bh_tail->next = buf; + cup->bh_tail = buf; + return; +} + +/* + Dequeue a buffer from the start of the bh routine chain. +*/ + +struct c7000_buffer * +c7000_dequeue_bh_buffer(struct c7000_unit *cup) +{ + struct c7000_buffer *buf = cup->bh_head; + + if (buf == NULL) + return(NULL); + + cup->bh_head = buf->next; + + if (cup->bh_head == NULL) + cup->bh_tail = NULL; + + buf->next = NULL; + return(buf); +} + +/* + Build up a list of buffers to read. Each buffer is described + by one c7000_buffer structure. The c7000_buffer structure + contains a channel segment that will read that one buffer. + The channel program segments are chained together via TIC + CCWS. +*/ + +static int +c7000_bld_read_chain(struct c7000_unit *cup) +{ + struct c7000_buffer *buf, *pbuf = NULL; + struct c7000_rd_header *head; + int num = 0; + + while (cup->free != NULL) { + + /* + Obtain a buffer for a read channel segment. + */ + + if ((buf = c7000_get_buffer(cup)) == NULL) { + CPrintk(0, "c7000: c7000_bld_read_chain: can not obtain a read buffer for unit 0x%x\n", cup->devno); + return(-ENOMEM); + } + + num++; + buf->len = 0; + + /* + Clear out the read header flag. + */ + + head = (struct c7000_rd_header *)(buf->data + C7000_DATAL); + head->flag = 0x00; + c7000_queue_buffer(cup, buf); + + /* + Build the read channel program segment. + */ + + c7000_bld_read_chpgm(cup, buf); + + /* + Chain the prior (if any) channel program segment to + this one. + */ + + if (pbuf != NULL) + pbuf->ccws[3].cda = pbuf->ccws[5].cda = (__u32)virt_to_phys(&buf->ccws[0]); + + pbuf = buf; + } + + CPrintk(1, "c7000: c7000_bld_read_chain: chained %d buffers for unit 0x%x\n", num, cup->devno); + return(0); +} + +/* + Build up a list of buffers to write. Each buffer is described + by one c7000_buffer structure. The c7000_buffer structure + contains a channel segment that will write that one buffer. + The channel program segments are chained together via TIC + CCWS. +*/ + +static void +c7000_bld_wrt_chain(struct c7000_unit *cup) +{ + struct c7000_buffer *buf = cup->proc_head, *pbuf = NULL; + int num = 0; + + while (buf != NULL) { + c7000_bld_wrt_chpgm(cup, buf); + + /* + Chain the channel program segments together. + */ + + if (pbuf != NULL) + pbuf->ccws[2].cda = (__u32)virt_to_phys(&buf->ccws[0]); + + pbuf = buf; + buf = buf->next; + num++; + } + + CPrintk(1, "c7000: c7000_bld_wrt_chain: chained %d buffers for unit 0x%x\n", num, cup->devno); + return; +} + +/* + Interrupt handler bottom half (bh) routine. + Process all of the buffers on the c7000_unit bh chain. + The bh chain is populated by the interrupt routine when + a READ channel program completes on a buffer. +*/ + +static void +c7000_irq_bh(struct c7000_unit *cup) +{ + struct c7000_buffer *buf, *pbuf; + struct c7000_rd_header *head; + struct sk_buff *skb; + struct c7000_controller *ccp; + STRUCT_NET_DEVICE *dev; + int rc; + __u16 data_length; + __u32 parm; + __u8 flags = 0x00; + __u32 saveflags; + + ccp = cup->cntlp; + dev = ccp->dev; + + s390irq_spin_lock_irqsave(cup->irq, saveflags); + + /* + Process all buffers sent to bh by the interrupt routine. + */ + + while (cup->bh_head != NULL) { + buf = c7000_dequeue_bh_buffer(cup); + + /* + Deference the data as a c7000 header. + */ + + head = (struct c7000_rd_header *)(buf->data + C7000_DATAL); + + /* + If it is a control message, release the buffer and + continue the loop. + */ + + if (C7000_LINKID(head->cmd) == 0) { + CPrintk(0, "c7000: c7000_irq_bh: unexpected control command %d on unit 0x%x\n", head->cmd, cup->devno); + c7000_release_buffer(cup, buf); + continue; + } + + /* + Allocate a socket buffer. + */ + + data_length = head->len; + skb = dev_alloc_skb(data_length); + + /* + Copy the data to the skb. + Send it to the upper layers. + */ + + if (skb != NULL) { + memcpy(skb_put(skb, data_length), buf->data, data_length); + skb->dev = dev; + skb->protocol = htons(ETH_P_IP); + skb->pkt_type = PACKET_HOST; + skb->mac.raw = skb->data; + skb->ip_summed = CHECKSUM_UNNECESSARY; + netif_rx(skb); + ccp->stats.rx_packets++; + } else { + CPrintk(0, "c7000: c7000_irq_bh: can not allocate a skb for unit 0x%x\n", cup->devno); + ccp->stats.rx_dropped++; + } + + /* + Rechain the buffer on the processing list. + */ + + head->flag = 0x00; + buf->len = 0; + pbuf = cup->proc_tail; + c7000_queue_buffer(cup, buf); + + /* + Rechain the buffer on the running channel program. + */ + + if (pbuf != NULL) + pbuf->ccws[3].cda = pbuf->ccws[5].cda = (__u32)virt_to_phys(&buf->ccws[0]); + + } + + /* + Restart the READ channel program if IO_active is 0. + */ + + if (test_and_set_bit(0, (void *)&cup->IO_active) == 0) { + + if ((rc = c7000_bld_read_chain(cup)) != 0) { + CPrintk(0, "c7000: c7000_irq_bh: can not build read chain for unit 0x%x, return code %d\n", cup->devno, rc); + c7000_error(cup->cntlp); + clear_bit(C7000_BH_ACTIVE, (void *)&cup->flag_a); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return; + } + + parm = (__u32)cup; + cup->state = C7000_READ; + + if ((rc = do_IO(cup->irq, &cup->proc_head->ccws[0], parm, 0xff, flags)) != 0) { + CPrintk(0, "c7000: c7000_irq_bh: can not start READ IO to unit 0x%x, return code %d\n", cup->devno, rc); + c7000_error(cup->cntlp); + clear_bit(C7000_BH_ACTIVE, (void *)&cup->flag_a); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return; + } + + CPrintk(1, "c7000: c7000_irq_bh: started READ IO to unit 0x%x\n", cup->devno); + } + + /* + Clear the bh active indication. + */ + + clear_bit(C7000_BH_ACTIVE, (void *)&cup->flag_a); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return; +} + +/* + Send a system validate control command to a unit. +*/ + +static int +c7000_send_sysval(struct c7000_unit *cup) +{ + int rc; + struct c7000_controller *ccp = cup->cntlp; + struct c7000_control_blk *ctlblkp = &(cup->control_blk); + + CPrintk(1, "c7000: c7000_send_sysval: send sysval for device 0x%x\n", cup->devno); + + /* + Build the system validate control message. + */ + + memset(ctlblkp, '\0', sizeof(struct c7000_control_blk)); + ctlblkp->cmd = C7000_SYS_VALIDATE; + ctlblkp->correlator = 0; + ctlblkp->link_id = ccp->linkid; + ctlblkp->ver = ccp->version; + memcpy(ctlblkp->hostname, ccp->lhost, NAMLEN); + memcpy(ctlblkp->unitname, ccp->uhost, NAMLEN); + ctlblkp->rdsize = C7000_DATAL; + ctlblkp->wrtsize = C7000_DATAL; + + /* + Build the channel program. + */ + + c7000_bld_wrtctl_chpgm(cup); + + /* + Do the IO and wait for write to complete. + */ + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_send_sysval failed with rc = %d for unit 0x%x\n", rc, cup->devno); + return(-1); + } + + return(0); +} + +/* + Send a system validate response control command to a unit. +*/ + +static int +c7000_send_sysval_resp(struct c7000_unit *cup, unsigned char correlator, int ret_code) +{ + int rc; + struct c7000_controller *ccp = cup->cntlp; + struct c7000_control_blk *ctlblkp = &(cup->control_blk); + + CPrintk(1, "c7000: c7000_send_sysval_resp: send sysval response for device 0x%x\n", cup->devno); + + /* + Build the system validate response control message. + */ + + memset(ctlblkp, '\0', sizeof(struct c7000_control_blk)); + ctlblkp->cmd = C7000_SYS_VALIDATE_RESP; + ctlblkp->correlator = correlator; + ctlblkp->ret_code = ret_code; + ctlblkp->link_id = ccp->linkid; + ctlblkp->ver = ccp->version; + memcpy(ctlblkp->hostname, ccp->lhost, NAMLEN); + memcpy(ctlblkp->unitname, ccp->uhost, NAMLEN); + ctlblkp->rdsize = C7000_DATAL; + ctlblkp->wrtsize = C7000_DATAL; + + /* + Build the channel program. + */ + + c7000_bld_wrtctl_chpgm(cup); + + /* + Do the IO and wait for write to complete. + */ + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_send_sysval_resp failed with rc = %d for unit 0x%x\n", rc, cup->devno); + return(-1); + } + + return(0); +} + +/* + Check the information read in a SYS_VALIDATE control message. +*/ + +static int +c7000_checkinfo(struct c7000_unit *cup) +{ + struct c7000_controller *ccp = cup->cntlp; + struct c7000_control_blk *ctlblkp = &cup->control_blk; + int ret_code = 0; + + if (memcmp(ccp->lhost, ctlblkp->hostname, NAMLEN) || + memcmp(ccp->uhost, ctlblkp->unitname, NAMLEN)) + ret_code = Err_Names_not_Matched; + + if (ctlblkp->ver != ccp->version) + ret_code = Err_Wrong_Version; + + if ((ctlblkp->rdsize < C7000_DATAL) || (ctlblkp->wrtsize < C7000_DATAL)) + ret_code = Err_Wrong_Frame_Size; + + if (ret_code != 0) + CPrintk(0, "c7000: c7000_checkinfo: ret_code %d for device 0x%x\n", ret_code, cup->devno); + + return(ret_code); +} + +/* + Keep reading until a sysval response comes in or an error. +*/ + +static int +c7000_get_sysval_resp(struct c7000_unit *cup) +{ + struct c7000_controller *ccp = cup->cntlp; + int resp = 1; + int req = 1; + int rc; + int ret_code = 0; + + CPrintk(1, "c7000: c7000_get_sysval_resp: get sysval response for unit 0x%x\n", cup->devno); + + /* + Wait for the response to C7000_SYS_VALIDATE and for an + inbound C7000_SYS_VALIDATE. + */ + + while (resp || req) { + + /* + Build the read channel program. + */ + + c7000_bld_readctl_chpgm(cup); + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_get_sysval_resp: failed with rc = %d for unit 0x%x\n", rc, cup->devno); + return(-1); + } + + /* + Process the control message. + */ + + switch (cup->control_blk.cmd) { + + /* + Check that response is positive and return + with success. Otherwise, return with an + error. + */ + + case C7000_SYS_VALIDATE_RESP: + + if (cup->control_blk.ret_code == 0) + resp = 0; + else { + CPrintk(0, "c7000: c7000_get_sysval_resp: receive sysval response for device 0x%x, return code %d\n", + cup->devno, + cup->control_blk.ret_code); + return(-1); + } + + break; + + /* + Check that the request is reasonable and + send a SYS_VALIDATE_RESP. Otherwise, + return with an error. + */ + + case C7000_SYS_VALIDATE: + CPrintk(1, "c7000: c7000_get_sysval_resp: receive sysval for device 0x%x\n", cup->devno); + req = 0; + ret_code = c7000_checkinfo(cup); + + if (c7000_send_sysval_resp(&ccp->cunits[C7000_WR], cup->control_blk.correlator, ret_code) != 0) + return(-1); + + if (ret_code != 0) + return(-1); + + break; + + /* + Anything else is unexpected and will result + in a return with an error. + */ + + default: + CPrintk(0, "c7000: c7000_get_sysval_resp: receive unexpected command for device 0x%x, command %d\n", cup->devno, cup->control_blk.cmd); + return(-1); + break; + } + + } + + return(0); +} + +/* + Send a connection confirm control message. +*/ + +static int +c7000_conn_confrm(struct c7000_unit *cup, unsigned char correlator, int linkid) +{ + int rc; + struct c7000_controller *ccp = cup->cntlp; + struct c7000_control_blk *ctlblkp = &(cup->control_blk); + + CPrintk(1, "c7000: c7000_conn_confrm: send the connection confirmation message for unit 0x%x\n", cup->devno); + + /* + Build the connection confirm control message. + */ + + memset(ctlblkp, '\0', sizeof(struct c7000_control_blk)); + ctlblkp->cmd = C7000_CONN_CONFRM; + ctlblkp->ver = ccp->version; + ctlblkp->link_id = linkid; + ctlblkp->correlator = correlator; + ctlblkp->rdsize = 0; + ctlblkp->wrtsize = 0; + memcpy(ctlblkp->hostname, ccp->lappl, NAMLEN); + memcpy(ctlblkp->unitname, ccp->uappl, NAMLEN); + + /* + Build the channel program. + */ + + c7000_bld_wrtctl_chpgm(cup); + + /* + Do the IO and wait for write to complete. + */ + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_conn_confrm: failed with rc = %d for unit 0x%x\n", rc, cup->devno); + return(-1); + } + + return(0); +} + +/* + Send a connection request control message. +*/ + +static int +c7000_send_conn(struct c7000_unit *cup) +{ + int rc; + struct c7000_controller *ccp = cup->cntlp; + struct c7000_control_blk *ctlblkp = &(cup->control_blk); + + CPrintk(1, "c7000: c7000_send_conn: send the connection request message for unit 0x%x\n", cup->devno); + + /* + Build the connection request control message. + */ + + memset(ctlblkp, '\0', sizeof(struct c7000_control_blk)); + ctlblkp->cmd = C7000_CONN_REQ; + ctlblkp->ver = ccp->version; + ctlblkp->link_id = 0; + ctlblkp->correlator = 0; + ctlblkp->rdsize = C7000_DATAL; + ctlblkp->wrtsize = C7000_DATAL; + memcpy(ctlblkp->hostname, ccp->lappl, NAMLEN); + memcpy(ctlblkp->unitname, ccp->uappl, NAMLEN); + + /* + Build the channel program. + */ + + c7000_bld_wrtctl_chpgm(cup); + + /* + Do the IO and wait for write to complete. + */ + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_send_conn: failed with rc = %d for unit 0x%x\n", rc, cup->devno); + return(-1); + } + + return(0); +} + +/* + Send a disconnect control message to the link with the value of + linkid. +*/ + +static int +c7000_send_disc(struct c7000_unit *cup, int linkid) +{ + int rc; + struct c7000_controller *ccp = cup->cntlp; + struct c7000_control_blk *ctlblkp = &(cup->control_blk); + + CPrintk(1, "c7000: c7000_send_disc: send disconnect message for unit 0x%x\n", cup->devno); + + /* + Build the disconnect control message. + */ + + memset(ctlblkp, '\0', sizeof(struct c7000_control_blk)); + ctlblkp->cmd = C7000_DISCONN; + ctlblkp->ver = ccp->version; + ctlblkp->link_id = linkid; + ctlblkp->correlator = 0; + ctlblkp->rdsize = C7000_DATAL; + ctlblkp->wrtsize = C7000_DATAL; + memcpy(ctlblkp->hostname, ccp->lappl, NAMLEN); + memcpy(ctlblkp->unitname, ccp->uappl, NAMLEN); + + /* + Build the channel program. + */ + + c7000_bld_wrtctl_chpgm(cup); + + /* + Do the IO and wait for write to complete. + */ + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_send_disc: failed with rc = %d for unit 0x%x\n", rc, cup->devno); + return(-1); + } + + return(0); +} + +/* + Resolve the race condition based on the link identifier value. + The adapter microcode assigns the identifiers. A higher value implies + that the race was lost. A side effect of this function is that + ccp->linkid is set to the link identifier to be used for this + connection (provided that 0 is returned). +*/ + +static int +c7000_resolve_race(struct c7000_unit *cup, int local_linkid, int remote_linkid) +{ + struct c7000_controller *ccp = cup->cntlp; + + CPrintk(1, "c7000: c7000_resolve_race: for unit 0x%x, local linkid %d, remote linkid %d\n", cup->devno, local_linkid, remote_linkid); + + /* + This local link identifier should not be zero.. + */ + + if (local_linkid == 0) { + CPrintk(0, "c7000: c7000_resolve_race: error for unit 0x%x, local linkid is null\n", cup->devno); + return(-1); + } + + /* + This indicates that there is no race. Just use our + local link identifier. + */ + + if (remote_linkid == 0) { + ccp->linkid = local_linkid; + return(0); + } + + /* + Send a connection confirm message if we lost the race to + the winning link identifier. + + Either way, save the winning link identifier. + */ + + if (local_linkid > remote_linkid) { + + if (c7000_conn_confrm(&ccp->cunits[C7000_WR], cup->control_blk.correlator, remote_linkid) != 0) { + CPrintk(0, "c7000: c7000_resolve_race: failed for unit 0x%x\n", cup->devno); + return(-1); + } + + ccp->linkid = remote_linkid; + } else { + ccp->linkid = local_linkid; + } + + return(0); +} + +/* + Get connected by processing the connection request/response/confirm + control messages. A connection request has already been sent by + calling function c7000_send_conn. +*/ + +static int +c7000_get_conn(struct c7000_unit *cup) +{ + struct c7000_controller *ccp = cup->cntlp; + int rc; + int cont = 1; + int remote_linkid = 0; + int local_linkid = 0; + + CPrintk(1, "c7000: c7000_get_conn: read the connected message for unit 0x%x\n", cup->devno); + ccp->linkid = 0; + + while (cont == 1) { + + /* + Build the read channel program. + */ + + c7000_bld_readctl_chpgm(cup); + + /* + Start the channel program to read a control message. + */ + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_get_conn: failed with rc = %d for unit 0x%x\n", rc, cup->devno); + return(-1); + } + + /* + Process the control message that was received based + on the command code. + */ + + CPrintk(1, "c7000: c7000_get_conn: received command %d for unit 0x%x\n", cup->control_blk.cmd, cup->devno); + + switch(cup->control_blk.cmd) { + + /* + Save the remote link_id in the message for + a check in c7000_resolve_race. + */ + + case C7000_CONN_REQ: + remote_linkid = cup->control_blk.link_id; + break; + + /* + A connection response received. Resolve + the network race condition (if any) by + comparing the link identifier values. + */ + + case C7000_CONN_RESP: + + if (cup->control_blk.ret_code != 0) { + CPrintk(0, "c7000: c7000_get_conn: failed for unit 0x%x , connection response return code %d\n", + cup->devno, cup->control_blk.ret_code); + return(-1); + } + + local_linkid = cup->control_blk.link_id; + + if (c7000_resolve_race(cup, local_linkid, remote_linkid) != 0) + return(-1); + + break; + + /* + Got a confirmation to our connection request. + Disconnect the remote link identifier (if any). + Break out of the loop. + */ + + case C7000_CONN_CONFRM: + + if (remote_linkid != 0) { + + if (c7000_send_disc(&ccp->cunits[C7000_WR], remote_linkid) != 0) { + CPrintk(0, "c7000: c7000_get_conn: send disconnect failed for unit 0x%x\n", cup->devno); + return(-1); + } + + } + + cont = 0; + break; + + /* + Got a disconnect to our connection request. + Break out of the loop. + */ + + case C7000_DISCONN: + cont = 0; + break; + + /* + Anything else must be an error. + Return with an error immediately. + */ + + default: + CPrintk(0, "c7000: c7000_get_conn: failed for unit 0x%x unexpected command %d\n", + cup->devno, cup->control_blk.cmd); + return(-1); + } + + } + + /* + Be sure that we now have a link identifier. + */ + + if (ccp->linkid == 0) + return(-1); + + return(0); +} + +/* + Get statistics method. +*/ + +struct net_device_stats * +c7000_stats(STRUCT_NET_DEVICE *dev) +{ + struct c7000_controller *ccp = (struct c7000_controller *)dev->priv; + + return(&ccp->stats); +} + +/* + Open method. +*/ + +static int +c7000_open(STRUCT_NET_DEVICE *dev) +{ + int i; + struct c7000_controller *ccp = (struct c7000_controller *)dev->priv; + struct c7000_unit *cup; + int rc; + __u32 parm; + __u8 flags = 0x00; + + c7000_set_busy(dev); + + /* + Allocate space for the unit buffers. + */ + + if (c7000_alloc_buffers(dev) == -1) { + CPrintk(0, "c7000: c7000_open: can not allocate buffer space for base unit 0x%lx\n", dev->base_addr); + c7000_free_buffers(dev); /* free partially allocated buffers */ + c7000_clear_busy(dev); + return(-ENOMEM); + } + + /* + Perform the initialization for all units. + */ + + for (i = 0; i < NUNITS; i++) { + cup = &ccp->cunits[i]; + + /* + Initialize task queue structure used for the bottom + half routine. + */ + +#ifndef NEWSTUFF + cup->tq.next = NULL; +#endif + cup->tq.sync = 0; + cup->tq.routine = (void *)(void *)c7000_irq_bh; + cup->tq.data = cup; + cup->state = C7000_HALT; +#ifdef NEWSTUFF + init_waitqueue_head(&cup->wait); +#endif + CPrintk(1, "c7000: c7000_open: issuing halt to unit 0x%x\n", cup->devno); + + /* + Issue a halt I/O to the unit + */ + + if ((rc = c7000_haltio(cup)) != 0) { + CPrintk(0, "c7000: c7000_open: halt_IO failed with rc = %d for unit 0x%x\n", rc, cup->devno); + continue; + } + + cup->IO_active = 0; + cup->flag_a = 0; + cup->sigsmod = 0x00; + + CPrintk(1, "c7000: c7000_open: halt complete for unit 0x%x\n", cup->devno); + } + + /* + On each subchannel send a sense id. + */ + + for (i = 0; i < NUNITS; i++) { + cup = &ccp->cunits[i]; + + /* + Build SENSE ID channel program. + */ + + c7000_bld_senseid_chpgm(cup); + + /* + Issue the start I/O for SENSE ID channel program. + */ + + CPrintk(1, "c7000: c7000_open: issuing SENSEID to unit 0x%x\n", cup->devno); + + if ((rc = c7000_doio(cup)) != 0) { + CPrintk(0, "c7000: c7000_open: SENSEID failed with rc = %d for unit 0x%x\n", rc, cup->devno); + c7000_clear_busy(dev); + return(-EIO); + } + + CPrintk(1, "c7000: c7000_open: SENSEID complete for unit 0x%x\n", cup->devno); + } + + /* + Send the system validation control message. + */ + + cup = &ccp->cunits[C7000_WR]; + + if (c7000_send_sysval(cup) != 0) { + CPrintk(0, "c7000: c7000_open: can not send sysval for unit 0x%x\n", cup->devno); + c7000_clear_busy(dev); + return(-EIO); + } + + CPrintk(1, "c7000: c7000_open: successfully sent sysval for unit 0x%x\n", cup->devno); + /* + Get the system validation response message. + */ + + cup = &ccp->cunits[C7000_RD]; + + if (c7000_get_sysval_resp(cup) != 0) { + CPrintk(0, "c7000: c7000_open: can not read sysval response for unit 0x%x\n", cup->devno); + c7000_clear_busy(dev); + return(-EIO); + } + + CPrintk(1, "c7000: c7000_open: successfully received sysval reply for unit 0x%x\n", cup->devno); + ccp->cunits[C7000_RD].state = ccp->cunits[C7000_WR].state = C7000_CONNECT; + + cup = &ccp->cunits[C7000_WR]; + + /* + Send a connection request. + */ + + if (c7000_send_conn(cup) != 0) { + CPrintk(0, "c7000: c7000_open: connection failed for unit 0x%x\n", cup->devno); + c7000_clear_busy(dev); + return(-EIO); + } + + cup = &ccp->cunits[C7000_RD]; + + /* + Get the response to our connection request Note that a + network race may occur. This is handled in c7000_get_conn. + */ + + if (c7000_get_conn(cup) != 0) { + CPrintk(0, "c7000: c7000_open: unit 0x%x has connected\n", cup->devno); + c7000_clear_busy(dev); + return(-EIO); + } + + CPrintk(1, "c7000: c7000_open: successfully received connection request for unit 0x%x\n", cup->devno); + ccp->cunits[C7000_RD].state = ccp->cunits[C7000_WR].state = C7000_READY; + + /* + Clear the interface statistics. + */ + + memset(&ccp->stats, '\0', sizeof(struct net_device_stats)); + + if ((rc = c7000_bld_read_chain(cup)) != 0) { + c7000_clear_busy(dev); + return(rc); + } + + /* + Start the C7000_READ channel program but do not wait for it's + completion. + */ + + cup->state = C7000_READ; + parm = (__u32) cup; + set_bit(0, (void *)&cup->IO_active); + + if ((rc = do_IO(cup->irq, &cup->proc_head->ccws[0], parm, 0xff, flags)) != 0) { + CPrintk(0, "c7000: c7000_open: READ failed with return code %d for unit 0x%x\n", rc, cup->devno); + c7000_error(cup->cntlp); + clear_bit(0, (void *)&cup->IO_active); + c7000_clear_busy(dev); + return(-EIO); + } + +#ifdef NEWSTUFF + netif_start_queue(dev); +#else + dev->start = 1; +#endif + CPrintk(0, "c7000: c7000_open: base unit 0x%lx is opened\n", dev->base_addr); + c7000_clear_busy(dev); + MOD_INC_USE_COUNT; /* increment module usage count */ + return(0); +} + +/* + Stop method. +*/ + +static int +c7000_stop(STRUCT_NET_DEVICE *dev) +{ + int i; + struct c7000_controller *ccp = (struct c7000_controller *)dev->priv; + struct c7000_unit *cup; + int rc; + +#ifdef NEWSTUFF +/* nothing? */ +#else + dev->start = 0; +#endif + c7000_set_busy(dev); + + /* + Send a disconnect message. + */ + + ccp->cunits[C7000_RD].state = ccp->cunits[C7000_WR].state = C7000_DISC; + cup = &ccp->cunits[C7000_WR]; + + if (c7000_send_disc(cup, ccp->linkid) != 0) { + CPrintk(0, "c7000: c7000_stop: send of disconnect message failed for unit 0x%x\n", cup->devno); + } + + CPrintk(1, "c7000: c7000_stop: successfully sent disconnect message to unit 0x%x\n", cup->devno); + + /* + Issue a halt I/O to all units. + */ + + for (i = 0; i < NUNITS; i++) { + cup = &ccp->cunits[i]; + cup->state = C7000_STOP; + CPrintk(1, "c7000: c7000_stop: issuing halt to unit 0x%x\n", cup->devno); + + if ((rc = c7000_haltio(cup)) != 0) { + CPrintk(0, "c7000: c7000_stop: halt_IO failed with rc = %d for unit 0x%x\n", rc, cup->devno); + continue; + } + + CPrintk(1, "c7000: c7000_stop: halt complete for unit 0x%x\n", cup->devno); + } + + c7000_free_buffers(dev); + CPrintk(0, "c7000: c7000_stop: base unit 0x%lx is stopped\n", dev->base_addr); + MOD_DEC_USE_COUNT; /* Decrement module usage count */ + return(0); +} + +/* + Configure the interface. +*/ + +static int +c7000_config(STRUCT_NET_DEVICE *dev, struct ifmap *map) +{ + CPrintk(1, "c7000: c7000_config: entered for base unit 0x%lx\n", dev->base_addr); + return(0); +} + +/* + Transmit a packet. +*/ + +static int +c7000_xmit(struct sk_buff *skb, STRUCT_NET_DEVICE *dev) +{ + struct c7000_controller *ccp = (struct c7000_controller *)dev->priv; + struct c7000_unit *cup; + __u32 saveflags; + __u32 parm; + __u8 flags = 0x00; + struct c7000_buffer *buf, *pbuf; + int rc; + + CPrintk(1, "c7000: c7000_xmit: entered for base unit 0x%lx\n", dev->base_addr); + + /* + When the skb pointer is NULL return. + */ + + if (skb == NULL) { + CPrintk(0, "c7000: c7000_xmit: skb pointer is null for base unit 0x%lx\n", dev->base_addr); + ccp->stats.tx_dropped++; + return(-EIO); + } + + cup = &ccp->cunits[C7000_WR]; + + /* + Lock the irq. + */ + + s390irq_spin_lock_irqsave(cup->irq, saveflags); + + /* + When the device transmission busy flag is on , no data + can be sent. Unlock the irq and return EBUSY. + */ + + if (c7000_check_busy(dev)) { + CPrintk(1, "c7000: c7000_xmit: c7000_check_busy returns true for base unit 0x%lx\n", dev->base_addr); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return(-EBUSY); + } + + /* + Set the device transmission busy flag on atomically. + */ + + if (c7000_ts_busy(TB_TX, dev)) { + CPrintk(1, "c7000: c7000_xmit: c7000_ts_busy returns true for base unit 0x%lx\n", dev->base_addr); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return(-EBUSY); + } + + CPrintk(1, "c7000: c7000_xmit: set TB_TX for unit 0x%x\n", cup->devno); + + /* + Obtain a free buffer. If none are free then mark tbusy + with TB_NOBUFFER and return EBUSY. + */ + + if ((buf = c7000_get_buffer(cup)) == NULL) { + CPrintk(1, "c7000: c7000_xmit: setting TB_NOBUFFER for base unit 0x%lx\n", dev->base_addr); + c7000_setbit_busy(TB_NOBUFFER, dev); + c7000_clearbit_busy(TB_TX, dev); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return(-EBUSY); + } + + CPrintk(1, "c7000: c7000_xmit: Got buffer for unit 0x%x\n", cup->devno); + + /* + Save the length of the skb data and then copy it to the + buffer. Queue the buffer on the processing list. + */ + + buf->len = skb->len; + memcpy(buf->data, skb->data, skb->len); + memset(buf->data + C7000_DATAL + C7000_READHDRL, '\0', C7000_READFFL); + pbuf = cup->proc_tail; + c7000_queue_buffer(cup, buf); + + /* + Chain the buffer to the running channel program. + */ + + if (test_bit(0, (void *)&cup->IO_active) && pbuf != NULL) { + c7000_bld_wrt_chpgm(cup, buf); + pbuf->ccws[2].cda = (__u32)virt_to_phys(&buf->ccws[0]); + } + + /* + Free the socket buffer. + */ + + dev_kfree_skb(skb); + + /* + If the unit is not currently doing IO, build a channel + program and start the IO for the buffers on the processing + chain. + */ + + if (test_and_set_bit(0, (void *)&cup->IO_active) == 0) { + CPrintk(1, "c7000: c7000_xmit: start IO for unit 0x%x\n", cup->devno); + c7000_bld_wrt_chain(cup); + parm = (__u32) cup; + cup->state = C7000_WRITE; + + if ((rc = do_IO(cup->irq, &cup->proc_head->ccws[0], parm, 0xff, flags)) != 0) { + CPrintk(0, "c7000: c7000_xmit: do_IO failed with return code %d for unit 0x%x\n", rc, cup->devno); + c7000_error(cup->cntlp); + c7000_clearbit_busy(TB_TX, dev); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + return(-EIO); + } + + dev->trans_start = jiffies; + CPrintk(1, "c7000: c7000_xmit: do_IO succeeds for unit 0x%x\n", cup->devno); + } + + /* + If the free chain is now NULL, set the TB_NOBUFFER flag. + */ + + if (cup->free == NULL) { + CPrintk(1, "c7000: c7000_xmit: setting TB_NOBUFFER for base unit 0x%lx\n", dev->base_addr); + c7000_setbit_busy(TB_NOBUFFER, dev); + } + + c7000_clearbit_busy(TB_TX, dev); + s390irq_spin_unlock_irqrestore(cup->irq, saveflags); + CPrintk(1, "c7000: c7000_xmit: exits for unit 0x%x\n", cup->devno); + return(0); +} + +/* + Handle an ioctl from a user process. +*/ + +static int +c7000_ioctl(STRUCT_NET_DEVICE *dev, struct ifreq *ifr, int cmd) +{ + CPrintk(1, "c7000: c7000_ioctl: entered for base unit 0x%lx with cmd %d\n", dev->base_addr, cmd); + return(0); +} + +/* + Analyze the interrupt status and return a value + that identifies the type. +*/ + +static enum c7000_rupt +c7000_check_csw(devstat_t *devstat) +{ + + /* + Check for channel detected conditions (except PCI). + */ + + if ((devstat->cstat & ~SCHN_STAT_PCI) != 0) { + CPrintk(0, "c7000: c7000_check_csw: channel status 0x%x for unit 0x%x\n", devstat->cstat, devstat->devno); + return(C7000_CHANERR); + } + + /* + Fast path the normal cases. + */ + + if (devstat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) + return(C7000_NORMAL); + + if (devstat->cstat == SCHN_STAT_PCI) + return(C7000_NORMAL); + + /* + Check for exceptions. + */ + + if (devstat->dstat & DEV_STAT_UNIT_CHECK) { + CPrintk(0, "c7000: c7000_check_csw: unit check for unit 0x%x, sense byte0 0x%2.2x\n", devstat->devno, devstat->ii.sense.data[0]); + + if (devstat->ii.sense.data[0] == C7000_BOX_RESET) + return(C7000_UCK_RESET); + else + return(C7000_UCK); + + } else if (devstat->dstat & DEV_STAT_UNIT_EXCEP) { + CPrintk(0, "c7000: c7000_check_csw: unit exception for unit 0x%x\n", devstat->devno); + return(C7000_UE); + + } else if (devstat->dstat & DEV_STAT_ATTENTION) { + CPrintk(0, "c7000: c7000_check_csw: attention for unit 0x%x\n", devstat->devno); + return(C7000_ATTN); + + } else if (devstat->dstat & DEV_STAT_BUSY) { + CPrintk(0, "c7000: c7000_check_csw: busy for unit 0x%x\n", devstat->devno); + return(C7000_BUSY); + + } else { + CPrintk(0, "c7000: c7000_check_csw: channel status 0x%2.2x , device status 0x%2.2x, devstat flags 0x%8.8x for unit 0x%x\n", + devstat->cstat, devstat->dstat, devstat->flag, devstat->devno); + return(C7000_OTHER); + } + + /* NOT REACHED */ + +} + +/* + Retry the last CCW chain to the unit. +*/ + +static void +c7000_retry_io(struct c7000_unit *cup) +{ + int rc; + __u32 parm; + __u8 flags = 0x00; + ccw1_t *ccwp; + + if (++cup->retries > C7000_MAX_RETRIES) { + c7000_error(cup->cntlp); + CPrintk(0, "c7000: c7000_retry_io: retry IO for unit 0x%x exceeds maximum retry count\n", cup->devno); + return; + } + + set_bit(0, (void *)&cup->IO_active); + parm = (__u32)cup; + + if (cup->state == C7000_READ || cup->state == C7000_WRITE) + ccwp = &cup->proc_head->ccws[0]; + else + ccwp = &cup->ccws[0]; + + if ((rc = do_IO(cup->irq, ccwp, parm, 0xff, flags)) != 0) { + CPrintk(0, "c7000: c7000_retry_io: can not retry IO for unit 0x%x, return code %d\n", cup->devno, rc); + clear_bit(0, (void *)&cup->IO_active); + c7000_error(cup->cntlp); + } + + CPrintk(1, "c7000: c7000_retry_io: retry IO for unit 0x%x, retry count %d\n", cup->devno, cup->retries); + return; +} + +/* + Process a read interrupt by scanning the list of buffers + for ones that have completed and queue them for the bottom + half to process. +*/ + +static void +c7000_proc_rintr(struct c7000_unit *cup) +{ + struct c7000_buffer *buf; + struct c7000_rd_header *head; + int num_read = 0; + + while (cup->proc_head != NULL) { + head = (struct c7000_rd_header *)(cup->proc_head->data + C7000_DATAL); + + /* + The flag byte in the read header will be set to + FLAG_FF when the buffer has been read. + */ + + if (head->flag != FLAG_FF) + break; + + /* + Dequeue the buffer from the proc chain + and enqueue it on the bh chain for + the bh routine to process. + */ + + buf = c7000_dequeue_buffer(cup); + c7000_queue_bh_buffer(cup, buf); + num_read++; + } + + CPrintk(1, "c7000: c7000_proc_rintr: %d buffers read for unit 0x%x\n", num_read, cup->devno); + return; +} + +/* + Process all completed buffers on the proc chain. + A buffer is completed if it's READFF flag is FLAG_FF. +*/ + +static int +c7000_proc_wintr(struct c7000_unit *cup) +{ + struct c7000_controller *ccp = cup->cntlp; + struct c7000_buffer *buf; + int num_write = 0; + + if (cup->proc_head == NULL) { + CPrintk(0, "c7000: c7000_proc_wintr: unexpected NULL processing chain pointer for unit 0x%x\n", cup->devno); + return(num_write); + } + + while (cup->proc_head != NULL) { + + /* + Check if the buffer has completed. + */ + + if (*(cup->proc_head->data + C7000_DATAL + C7000_READHDRL) != FLAG_FF) + break; + + /* + Remove buffer from top of processing chain. + Place it on free list. + */ + + buf = c7000_dequeue_buffer(cup); + c7000_release_buffer(cup, buf); + num_write++; + + /* + Update transmitted packets statistic. + */ + + ccp->stats.tx_packets++; + } + + CPrintk(1, "c7000: c7000_proc_wintr: %d buffers written for unit 0x%x\n", num_write, cup->devno); + return(num_write); +} + +/* + Interrupt handler. +*/ + +static void +c7000_intr(int irq, void *initparm, struct pt_regs *regs) +{ + devstat_t *devstat = ((devstat_t *) initparm); + struct c7000_unit *cup = NULL; + struct c7000_controller *ccp = NULL; + STRUCT_NET_DEVICE *dev = NULL; + __u32 parm; + __u8 flags = 0x00; + int rc; + + /* + Discard unsolicited interrupts + */ + + if (devstat->intparm == 0) { + CPrintk(0, "c7000: c7000_intr: unsolicited interrupt for device 0x%x, cstat = 0x%2.2x, dstat = 0x%2.2x, flag = 0x%8.8x\n", + devstat->devno, devstat->cstat, devstat->dstat, devstat->flag); + return; + } + + /* + Obtain the c7000_unit structure pointer. + */ + + cup = (struct c7000_unit *)(devstat->intparm); + + /* + Obtain the c7000_controller structure and device structure + pointers. + */ + + if (cup == NULL) { + CPrintk(0, "c7000: c7000_intr: c7000_unit pointer is NULL in devstat\n"); + return; + } + + ccp = cup->cntlp; + + if (ccp == NULL) { + CPrintk(0, "c7000: c7000_intr: c7000_cntlp pointer is NULL in c7000_unit structure 0x%x for unit 0x%x\n", (int)cup, cup->devno); + return; + } + + dev = ccp->dev; + + if (dev == NULL) { + CPrintk(0, "c7000: c7000_intr: device pointer is NULL in c7000_controller structure 0x%x for unit 0x%x\n", (int)ccp, cup->devno); + return; + } + + /* + Finite state machine (fsm) handling. + */ + + CPrintk(1, "c7000: c7000_intr: entered with state %d flag 0x%8.8x for unit 0x%x\n", cup->state, devstat->flag, cup->devno); + + switch(cup->state) { + + /* + Not expected to be here when in INIT state. + */ + + case C7000_INIT: + + break; + + /* + Enter state C7000_SID and wakeup the sleeping + process in c7000_open. + */ + + case C7000_HALT: + + if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0) + break; + + cup->state = C7000_SID; + wake_up(&cup->wait); + break; + + /* + Enter state C7000_SYSVAL and wakeup the sleeping + process in c7000_open. + */ + + case C7000_SID: + + if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0) + break; + + if (c7000_check_csw(devstat) != 0) { + c7000_retry_io(cup); + + if (cup->state == C7000_ERROR) + wake_up(&cup->wait); + + break; + } + + cup->retries = 0; + cup->state = C7000_SYSVAL; + wake_up(&cup->wait); + break; + + /* + Wakeup the sleeping process in c7000_open. + */ + + case C7000_SYSVAL: + + if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0) + break; + + if (c7000_check_csw(devstat) != 0) { + c7000_retry_io(cup); + + if (cup->state == C7000_ERROR) + wake_up(&cup->wait); + + break; + } + + cup->retries = 0; + wake_up(&cup->wait); + break; + + /* + Wakeup the sleeping process in c7000_open. + */ + + case C7000_CONNECT: + + if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0) + break; + + if (c7000_check_csw(devstat) != 0) { + c7000_retry_io(cup); + + if (cup->state == C7000_ERROR) + wake_up(&cup->wait); + + break; + } + + cup->retries = 0; + wake_up(&cup->wait); + break; + + /* + Not expected to be entered here. + */ + + case C7000_READY: + break; + + /* + Process the data that was just read. + */ + + case C7000_READ: + + if ((devstat->flag & (DEVSTAT_PCI | DEVSTAT_FINAL_STATUS)) == 0) + break; + + CPrintk(1, "c7000: c7000_intr: process read interrupt for unit 0x%x , devstat flag = 0x%8.8x\n", cup->devno, devstat->flag); + + /* + Check for serious errors. + */ + + if (c7000_check_csw(devstat) != 0) { + ccp->stats.rx_errors++; + c7000_error(cup->cntlp); + break; + } + + /* + Build the bottom half buffer list. + */ + + c7000_proc_rintr(cup); + + /* + When final status is received clear + the IO active bit. + */ + + if (devstat->flag & DEVSTAT_FINAL_STATUS) { + clear_bit(0, (void *)&cup->IO_active); + } + + /* + If there are free buffers redrive the IO. + */ + + if ((devstat->flag & DEVSTAT_FINAL_STATUS) && + (cup->free != NULL)) { + c7000_bld_read_chain(cup); + parm = (__u32)cup; + set_bit(0, (void *)&cup->IO_active); + + if ((rc = do_IO(cup->irq, &cup->proc_head->ccws[0], parm, 0xff, flags)) != 0) { + clear_bit(0, (void *)&cup->IO_active); + CPrintk(0, "c7000: c7000_intr: do_IO failed with return code %d for unit 0x%x\n", rc, cup->devno); + c7000_error(cup->cntlp); + break; + } + + CPrintk(1, "c7000: c7000_intr: started read io for unit 0x%x\n", cup->devno); + } + + /* + Initiate bottom half routine to process + data that was read. + */ + + if (test_and_set_bit(C7000_BH_ACTIVE, (void *)&cup->flag_a) == 0) { + queue_task(&cup->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); + } + + break; + + /* + Free the transmitted buffers and restart the channel + process (if necessary). + */ + + case C7000_WRITE: + + if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0) + break; + + if (c7000_check_csw(devstat) != 0) { + ccp->stats.tx_errors++; + c7000_error(cup->cntlp); + break; + } + + /* + If at least one buffer was freed, clear + the NOBUFFER indication. + */ + + if (c7000_proc_wintr(cup) != 0) { + c7000_clearbit_busy(TB_NOBUFFER, dev); + } + + /* + Restart the channel program if there are more + buffers on the processing chain. + */ + + if (cup->proc_head != NULL) { + c7000_bld_wrt_chain(cup); + parm = (__u32)cup; + set_bit(0, (void *)&cup->IO_active); + + if ((rc = do_IO(cup->irq, &cup->proc_head->ccws[0], parm, 0xff, flags)) != 0) { + CPrintk(0, "c7000: c7000_intr: do_IO failed with return code %d for unit 0x%x\n", rc, cup->devno); + clear_bit(0, (void *)&cup->IO_active); + c7000_error(cup->cntlp); + break; + } + + dev->trans_start = jiffies; + } else { + clear_bit(0, (void *)&cup->IO_active); + cup->state = C7000_READY; + } + + break; + + /* + Disconnect message completed. Wakeup the + sleeping process in c7000_stop. + */ + + case C7000_DISC: + if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0) + break; + + if (c7000_check_csw(devstat) != 0) { + c7000_retry_io(cup); + + if (cup->state == C7000_ERROR) + wake_up(&cup->wait); + + break; + } + + cup->retries = 0; + wake_up(&cup->wait); + break; + + /* + Subchannel is now halted. Wakeup the sleeping + process in c7000_stop. Set the state to C7000_STOPPED. + */ + + case C7000_STOP: + + cup->state = C7000_STOPPED; + wake_up(&cup->wait); + break; + + /* + When in error state, stay there until the + interface is recycled. + */ + + case C7000_ERROR: + + break; + + /* + Should not reach here + */ + + default: + CPrintk(0, "c7000: c7000_intr: entered default case for unit 0x%x, state %d\n", cup->devno, cup->state); + break; + + } + + CPrintk(1, "c7000: c7000_intr: exited with state %d for unit 0x%x\n", cup->state, cup->devno); + return; +} + +/* + Fill in system validation name padding it with blanks. +*/ + +static void +c7000_fill_name(char *dst, char *src) +{ + char *tmp = dst; + int i; + + for (i = 0; i < NAMLEN; i++, tmp++) + *tmp = ' '; + + for (i = 0; i < NAMLEN && *src != '\0'; i++) + *dst++ = *src++; + + return; +} + +/* + Initialization routine called when the device is registered. +*/ + +static int +c7000_init(STRUCT_NET_DEVICE *dev) +{ + struct c7000_controller *ccp; + int i; + int unitaddr; + int irq; + + /* + Find the position of base_addr in the bases array. + */ + + for (i = 0; i < MAX_C7000; i++) + if (bases[i] == dev->base_addr) + break; + + if (i == MAX_C7000) + return(-ENODEV); + + /* + Make sure it is a C7000 type of device. + */ + + if (c7000_check_devices(dev->base_addr) != 0) { + CPrintk(0, "c7000: c7000_init: base unit 0x%lx is not the right type\n", dev->base_addr); + return(-ENODEV); + } + + /* + Initialize the device structure functions. + Note that ARP is not done on the CLAW interface. + There is no ethernet header. + */ + + dev->mtu = C7000_DATAL; + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->type = ARPHRD_SLIP; + dev->tx_queue_len = C7000_TXQUEUE_LEN; + dev->flags = IFF_NOARP; + dev->open = c7000_open; + dev->stop = c7000_stop; + dev->set_config = c7000_config; + dev->hard_start_xmit = c7000_xmit; + dev->do_ioctl = c7000_ioctl; + dev->get_stats = c7000_stats; + + /* + Allocate space for a private data structure. + */ + + if ((ccp = dev->priv = kmalloc(sizeof(struct c7000_controller), GFP_KERNEL)) == NULL) { + CPrintk(0, "c7000: c7000_init: base unit 0x%lx can not be initialized\n", dev->base_addr); + return(-ENOMEM); + } + + CPrintk(1, "c7000: c7000_init: allocated a c7000_controller structure at address 0x%x\n", (int)ccp); + memset(ccp, '\0', sizeof(struct c7000_controller)); + ccp->dev = dev; + ccp->base_addr = dev->base_addr; + + /* + Populate the system validation name with default values. + */ + + c7000_fill_name(ccp->lappl, C7000_DFLT_LAPPL); + c7000_fill_name(ccp->lhost, C7000_DFLT_LHOST); + c7000_fill_name(ccp->uappl, C7000_DFLT_UAPPL); + c7000_fill_name(ccp->uhost, C7000_DFLT_UHOST); + + /* + When values have been supplied, replace the prior defaults. + */ + + if (i == 0) { + + if (lappl0 != NULL) + c7000_fill_name(ccp->lappl, lappl0); + + if (lhost0 != NULL) + c7000_fill_name(ccp->lhost, lhost0); + + if (uappl0 != NULL) + c7000_fill_name(ccp->uappl, uappl0); + + if (uhost0 != NULL) + c7000_fill_name(ccp->uhost, uhost0); + + } else if (i == 1) { + + if (lappl1 != NULL) + c7000_fill_name(ccp->lappl, lappl1); + + if (lhost1 != NULL) + c7000_fill_name(ccp->lhost, lhost1); + + if (uappl1 != NULL) + c7000_fill_name(ccp->uappl, uappl1); + + if (uhost1 != NULL) + c7000_fill_name(ccp->uhost, uhost1); + + } else if (i == 2) { + + if (lappl2 != NULL) + c7000_fill_name(ccp->lappl, lappl2); + + if (lhost2 != NULL) + c7000_fill_name(ccp->lhost, lhost2); + + if (uappl2 != NULL) + c7000_fill_name(ccp->uappl, uappl2); + + if (uhost2 != NULL) + c7000_fill_name(ccp->uhost, uhost2); + + } else { + + if (lappl3 != NULL) + c7000_fill_name(ccp->lappl, lappl3); + + if (lhost3 != NULL) + c7000_fill_name(ccp->lhost, lhost3); + + if (uappl3 != NULL) + c7000_fill_name(ccp->uappl, uappl3); + + if (uhost3 != NULL) + c7000_fill_name(ccp->uhost, uhost3); + + } + + CPrintk(1, "c7000: c7000_init: lappl = %8.8s lhost = %8.8s uappl = %8.8s uhost = %8.8s for base unit 0x%x\n", ccp->lappl, ccp->lhost, ccp->uappl, ccp->uhost, ccp->base_addr); + ccp->version = 2; + ccp->linkid = 0; + + /* + Initialize the fields in the embedded cunits + array. This type of controller occupies a range + of three contiguous device numbers. + */ + + for (i = 0; i < NUNITS; i++) { + unitaddr = dev->base_addr + i; + + /* + Get the subchannel number. + */ + + if ((irq = ccp->cunits[i].irq = get_irq_by_devno(unitaddr)) == -1) { + CPrintk(0, "c7000: c7000_init: can not get subchannel for unit 0x%x\n", unitaddr); + return(-ENODEV); + } + + /* + Get control of the subchannel. + */ + + if (request_irq(irq, c7000_intr, SA_INTERRUPT, dev->name, &ccp->cunits[i].devstat) != 0) { + CPrintk(0, "c7000: c7000_init: can not get control of subchannel 0x%x for unit 0x%x\n", irq, unitaddr); + return(-EBUSY); + } + + CPrintk(1, "c7000: c7000_init: obtained control of subchannel 0x%x for unit 0x%x\n", irq, unitaddr); + ccp->cunits[i].devno = unitaddr; + ccp->cunits[i].IO_active = 0; + ccp->cunits[i].state = C7000_INIT; + ccp->cunits[i].cntlp = ccp; + CPrintk(1, "c7000: c7000_init: initialized unit 0x%x on subchannel 0x%x\n", unitaddr, irq); + } + + return(0); +} + +/* + Probe for the Cisco 7000 unit base addresses. +*/ + +static void +c7000_probe(void) +{ + s390_dev_info_t d; + int i; + int j; + int idx; + + /* + Probe for up to MAX_C7000 devices. + Get the first irq into variable idx. + */ + + idx = get_irq_first(); + + for (j = 0; j < MAX_C7000; j++) { + + if (idx < 0) + break; + + /* + Continue scanning the irq's. Variable idx + maintains the location from the prior scan. + */ + + for (i = idx; i >= 0; i = get_irq_next(i)) { + + /* + Ignore invalid irq's. + */ + + if (get_dev_info_by_irq(i, &d) < 0) + continue; + + /* + A Cisco 7000 is defined as a 3088 model + type 0x61. + */ + + if (d.sid_data.cu_type == C7000_CU_TYPE && + d.sid_data.cu_model == C7000_CU_MODEL) { + CPrintk(0, "c7000_probe: unit probe found 0x%x\n", d.devno); + bases[j] = d.devno; + + /* + Skip the write irq and setup idx + to probe for the next box. + */ + + idx = get_irq_next(i + 1); + break; + } + + } + + } + + return; +} + +/* + Module loading. Register each C7000 interface found via probing + or insmod command parameters. +*/ + +int +init_module(void) +{ + int result; + int i; + + for (i = 0 ; i < MAX_C7000; i++) + bases[i] = -1; + + /* + Perform automatic detection provided it has not been disabled + by the noauto parameter. + */ + + if (noauto == 0) + c7000_probe(); + + /* + Populate bases array from the module basex parameters replacing + what probing found above. + */ + + if (base0 != -1) + bases[0] = base0; + + if (base1 != -1) + bases[1] = base1; + + if (base2 != -1) + bases[2] = base2; + + if (base3 != -1) + bases[3] = base3; + + for (i = 0; i < MAX_C7000; i++) { + + if (bases[i] == -1) + continue; + + /* + Initialize the device structure. + */ + + memset(&c7000_devices[i], '\0', sizeof(STRUCT_NET_DEVICE)); +#ifdef NEWSTUFF + strcpy(c7000_devices[i].name, ifnames[i]); +#else + c7000_devices[i].name = &ifnames[i][0]; +#endif + c7000_devices[i].base_addr = bases[i]; + c7000_devices[i].init = c7000_init; + + /* + Register the device. This creates the interface + such as ci0. + */ + + if ((result = register_netdev(&c7000_devices[i])) != 0) { + CPrintk(0, "c7000: init_module: error %d registering base unit 0x%x\n", + result, bases[i]); + c7000_devices[i].base_addr = -1; + } else { + CPrintk(1, "c7000: init_module: registered base unit 0x%x on interface %s\n", bases[i], ifnames[i]); + } + + } + + CPrintk(0, "c7000: init_module: module loaded\n"); + return(0); +} + +/* + Module unloading. Unregister the interface and free kernel + allocated memory. +*/ + +void +cleanup_module(void) +{ + int i; + int j; + struct c7000_controller *ccp; + + for (i = 0; i < MAX_C7000; i++) { + + if (bases[i] == -1) + continue; + + /* + If the device was registered, it must be unregistered + prior to unloading the module. + */ + + if (c7000_devices[i].base_addr != -1) { + + ccp = (struct c7000_controller *) c7000_devices[i].priv; + + if (ccp != NULL) { + + for (j = 0; j < NUNITS ; j++) { + CPrintk(1, "c7000: clean_module: free subchannel 0x%x for unit 0x%x\n", ccp->cunits[j].irq, ccp->cunits[j].devno); + free_irq(ccp->cunits[j].irq, &ccp->cunits[j].devstat); + } + + CPrintk(1, "c7000: clean_module: free a c7000_controller structure at address 0x%x\n", (int)ccp); + kfree(ccp); + } + + unregister_netdev(&c7000_devices[i]); + } + + bases[i] = -1; + } + + CPrintk(0, "c7000: clean_module: module unloaded\n"); + return; +} diff -urN linux-2.4.21/drivers/s390/net/ctcmain.c linux-2.4.22/drivers/s390/net/ctcmain.c --- linux-2.4.21/drivers/s390/net/ctcmain.c 2002-02-25 11:38:03.000000000 -0800 +++ linux-2.4.22/drivers/s390/net/ctcmain.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,5 +1,5 @@ /* - * $Id: ctcmain.c,v 1.55 2001/12/03 14:28:45 felfert Exp $ + * $Id: ctcmain.c,v 1.60 2003/06/18 11:16:32 cotte Exp $ * * CTC / ESCON network driver * @@ -35,7 +35,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.55 $ + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.60 $ * */ @@ -301,20 +301,44 @@ ctc_profile prof; unsigned char *trans_skb_data; + + __u16 logflags; + } channel; #define CHANNEL_FLAGS_READ 0 #define CHANNEL_FLAGS_WRITE 1 #define CHANNEL_FLAGS_INUSE 2 #define CHANNEL_FLAGS_BUFSIZE_CHANGED 4 +#define CHANNEL_FLAGS_FAILED 8 #define CHANNEL_FLAGS_RWMASK 1 #define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK) +#define LOG_FLAG_ILLEGALPKT 1 +#define LOG_FLAG_ILLEGALSIZE 2 +#define LOG_FLAG_OVERRUN 4 +#define LOG_FLAG_NOMEM 8 + /** * Linked list of all detected channels. */ static channel *channels = NULL; +#define CTC_LOGLEVEL_INFO 1 +#define CTC_LOGLEVEL_NOTICE 2 +#define CTC_LOGLEVEL_WARN 4 +#define CTC_LOGLEVEL_EMERG 8 +#define CTC_LOGLEVEL_ERR 16 +#define CTC_LOGLEVEL_DEBUG 32 +#define CTC_LOGLEVEL_CRIT 64 + +#define CTC_LOGLEVEL_DEFAULT \ +(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT) + +#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1) + +static int loglevel = CTC_LOGLEVEL_DEFAULT; + #ifdef CTC_CHANDEV static int activated; #endif @@ -336,7 +360,13 @@ struct proc_dir_entry *proc_dentry; struct proc_dir_entry *proc_stat_entry; struct proc_dir_entry *proc_ctrl_entry; + struct proc_dir_entry *proc_loglevel_entry; int proc_registered; + + /** + * Timer for restarting after I/O Errors + */ + fsm_timer restart_timer; } ctc_priv; /** @@ -387,7 +417,7 @@ */ static void print_banner(void) { static int printed = 0; - char vbuf[] = "$Revision: 1.55 $"; + char vbuf[] = "$Revision: 1.60 $"; char *version = vbuf; if (printed) @@ -398,16 +428,17 @@ *p = '\0'; } else version = " ??? "; - printk(KERN_INFO - "CTC driver Version%swith" + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO + "CTC driver Version%swith" #ifndef CTC_CHANDEV - "out" + "out" #endif - " CHANDEV support" + " CHANDEV support" #ifdef DEBUG - " (DEBUG-VERSION, " __DATE__ __TIME__ ")" + " (DEBUG-VERSION, " __DATE__ __TIME__ ")" #endif - " initialized\n", version); + " initialized\n", version); printed = 1; } @@ -464,9 +495,10 @@ default: type = channel_type_unknown; - printk(KERN_INFO - "channel: Unknown model found " - "3088-%02x\n", id->cu_model); + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO + "channel: Unknown model found " + "3088-%02x\n", id->cu_model); } break; @@ -517,6 +549,7 @@ DEV_EVENT_TXUP, DEV_EVENT_RXDOWN, DEV_EVENT_TXDOWN, + DEV_EVENT_RESTART, /** * MUST be always the last element!! */ @@ -530,6 +563,7 @@ "TX up", "RX down", "TX down", + "Restart", }; /** @@ -699,6 +733,8 @@ ll_header *header; int i; + if (!(loglevel & CTC_LOGLEVEL_DEBUG)) + return; p += offset; bl = *((__u16*)p); p += 2; @@ -745,16 +781,25 @@ skb_pull(pskb, LL_HEADER_LENGTH); if ((ch->protocol == CTC_PROTO_S390) && (header->type != ETH_P_IP)) { - /** - * Check packet type only if we stick strictly - * to S/390's protocol of OS390. This only - * supports IP. Otherwise allow any packet - * type. - */ - printk(KERN_WARNING - "%s Illegal packet type 0x%04x " - "received, dropping\n", - dev->name, header->type); +#ifndef DEBUG + if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) { +#endif + /** + * Check packet type only if we stick strictly + * to S/390's protocol of OS390. This only + * supports IP. Otherwise allow any packet + * type. + */ + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s Illegal packet type 0x%04x " + "received, dropping\n", + dev->name, header->type); + ch->logflags |= LOG_FLAG_ILLEGALPKT; +#ifndef DEBUG + } +#endif + #ifdef DEBUG ctc_dump_skb(pskb, -6); #endif @@ -763,15 +808,20 @@ return; } pskb->protocol = ntohs(header->type); - header->length -= LL_HEADER_LENGTH; - if ((header->length == 0) || - (header->length > skb_tailroom(pskb)) || - (header->length > len)) { - printk(KERN_WARNING - "%s Illegal packet size %d " - "received (MTU=%d blocklen=%d), " - "dropping\n", dev->name, header->length, - dev->mtu, len); + if (header->length <= LL_HEADER_LENGTH) { +#ifndef DEBUG + if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) { +#endif + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s Illegal packet size %d " + "received (MTU=%d blocklen=%d), " + "dropping\n", dev->name, header->length, + dev->mtu, len); + ch->logflags |= LOG_FLAG_ILLEGALSIZE; +#ifndef DEBUG + } +#endif #ifdef DEBUG ctc_dump_skb(pskb, -6); #endif @@ -779,11 +829,22 @@ privptr->stats.rx_length_errors++; return; } - if (header->length > skb_tailroom(pskb)) { - printk(KERN_WARNING - "%s Illegal packet size %d " - "(beyond the end of received data), " - "dropping\n", dev->name, header->length); + header->length -= LL_HEADER_LENGTH; + len -= LL_HEADER_LENGTH; + if ((header->length > skb_tailroom(pskb)) || + (header->length > len)) { +#ifndef DEBUG + if (!(ch->logflags & LOG_FLAG_OVERRUN)) { +#endif + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s Illegal packet size %d " + "(beyond the end of received data), " + "dropping\n", dev->name, header->length); + ch->logflags |= LOG_FLAG_OVERRUN; +#ifndef DEBUG + } +#endif #ifdef DEBUG ctc_dump_skb(pskb, -6); #endif @@ -793,12 +854,20 @@ } skb_put(pskb, header->length); pskb->mac.raw = pskb->data; - len -= (LL_HEADER_LENGTH + header->length); + len -= header->length; skb = dev_alloc_skb(pskb->len); if (!skb) { - printk(KERN_WARNING - "%s Out of memory in ctc_unpack_skb\n", - dev->name); +#ifndef DEBUG + if (!(ch->logflags & LOG_FLAG_NOMEM)) { +#endif + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s Out of memory in ctc_unpack_skb\n", + dev->name); + ch->logflags |= LOG_FLAG_NOMEM; +#ifndef DEBUG + } +#endif privptr->stats.rx_dropped++; return; } @@ -811,11 +880,29 @@ ctc_tty_netif_rx(skb); else netif_rx(skb); + /** + * Successful rx; reset logflags + */ + ch->logflags = 0; privptr->stats.rx_packets++; privptr->stats.rx_bytes += skb->len; if (len > 0) { skb_pull(pskb, header->length); - skb_put(pskb, LL_HEADER_LENGTH); + if (skb_tailroom(pskb) < LL_HEADER_LENGTH) { +#ifndef DEBUG + if (!(ch->logflags & LOG_FLAG_OVERRUN)) { +#endif + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s Buffer overrun in ctc_unpack_skb\n", + dev->name); + ch->logflags |= LOG_FLAG_OVERRUN; +#ifndef DEBUG + } +#endif + return; + } + skb_put(pskb, LL_HEADER_LENGTH); } } } @@ -846,24 +933,28 @@ fsm_event(ch->fsm, CH_EVENT_IO_SUCCESS, ch); break; case -EBUSY: - printk(KERN_INFO "ch-%04x: Busy !\n", ch->devno); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ch-%04x: Busy !\n", ch->devno); fsm_event(ch->fsm, CH_EVENT_IO_EBUSY, ch); break; case -ENODEV: - printk(KERN_EMERG - "ch-%04x: Invalid device called for IO\n", - ch->devno); + if (loglevel & CTC_LOGLEVEL_EMERG) + printk(KERN_EMERG + "ch-%04x: Invalid device called for IO\n", + ch->devno); fsm_event(ch->fsm, CH_EVENT_IO_ENODEV, ch); break; case -EIO: - printk(KERN_EMERG - "ch-%04x: Status pending... \n", ch->devno); + if (loglevel & CTC_LOGLEVEL_EMERG) + printk(KERN_EMERG + "ch-%04x: Status pending... \n", ch->devno); fsm_event(ch->fsm, CH_EVENT_IO_EIO, ch); break; default: - printk(KERN_EMERG - "ch-%04x: Unknown error in do_IO %04x\n", - ch->devno, return_code); + if (loglevel & CTC_LOGLEVEL_EMERG) + printk(KERN_EMERG + "ch-%04x: Unknown error in do_IO %04x\n", + ch->devno, return_code); fsm_event(ch->fsm, CH_EVENT_IO_UNKNOWN, ch); } } @@ -878,49 +969,58 @@ if (sense & SNS0_INTERVENTION_REQ) { if (sense & 0x01) { if (ch->protocol != CTC_PROTO_LINUX_TTY) - printk(KERN_DEBUG - "ch-%04x: Interface disc. or Sel. reset " - "(remote)\n", ch->devno); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ch-%04x: Interface disc. or Sel. reset " + "(remote)\n", ch->devno); fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch); } else { - printk(KERN_DEBUG "ch-%04x: System reset (remote)\n", - ch->devno); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "ch-%04x: System reset (remote)\n", + ch->devno); fsm_event(ch->fsm, CH_EVENT_UC_RSRESET, ch); } } else if (sense & SNS0_EQUIPMENT_CHECK) { if (sense & SNS0_BUS_OUT_CHECK) { - printk(KERN_WARNING - "ch-%04x: Hardware malfunction (remote)\n", - ch->devno); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ch-%04x: Hardware malfunction (remote)\n", + ch->devno); fsm_event(ch->fsm, CH_EVENT_UC_HWFAIL, ch); } else { - printk(KERN_WARNING - "ch-%04x: Read-data parity error (remote)\n", - ch->devno); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ch-%04x: Read-data parity error (remote)\n", + ch->devno); fsm_event(ch->fsm, CH_EVENT_UC_RXPARITY, ch); } } else if (sense & SNS0_BUS_OUT_CHECK) { if (sense & 0x04) { - printk(KERN_WARNING - "ch-%04x: Data-streaming timeout)\n", - ch->devno); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ch-%04x: Data-streaming timeout)\n", + ch->devno); fsm_event(ch->fsm, CH_EVENT_UC_TXTIMEOUT, ch); } else { - printk(KERN_WARNING - "ch-%04x: Data-transfer parity error\n", - ch->devno); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ch-%04x: Data-transfer parity error\n", + ch->devno); fsm_event(ch->fsm, CH_EVENT_UC_TXPARITY, ch); } } else if (sense & SNS0_CMD_REJECT) { - printk(KERN_WARNING "ch-%04x: Command reject\n", - ch->devno); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ch-%04x: Command reject\n", + ch->devno); } else if (sense == 0) { - printk(KERN_DEBUG "ch-%04x: Unit check ZERO\n", ch->devno); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "ch-%04x: Unit check ZERO\n", ch->devno); fsm_event(ch->fsm, CH_EVENT_UC_ZERO, ch); } else { - printk(KERN_WARNING - "ch-%04x: Unit Check with sense code: %02x\n", - ch->devno, sense); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ch-%04x: Unit Check with sense code: %02x\n", + ch->devno, sense); fsm_event(ch->fsm, CH_EVENT_UC_UNKNOWN, ch); } } @@ -944,7 +1044,7 @@ ch->trans_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC|GFP_DMA); if (ch->trans_skb == NULL) { - if (warn) + if (warn && (loglevel & CTC_LOGLEVEL_WARN)) printk(KERN_WARNING "ch-%04x: Couldn't alloc %s trans_skb\n", ch->devno, @@ -957,7 +1057,7 @@ virt_to_phys(ch->trans_skb->data))) { dev_kfree_skb(ch->trans_skb); ch->trans_skb = NULL; - if (warn) + if (warn && (loglevel & CTC_LOGLEVEL_WARN)) printk(KERN_WARNING "ch-%04x: set_normalized_cda for %s " "trans_skb failed, dropping packets\n", @@ -1009,7 +1109,7 @@ if (duration > ch->prof.tx_time) ch->prof.tx_time = duration; - if (ch->devstat->rescnt != 0) + if ((ch->devstat->rescnt != 0) && (loglevel & CTC_LOGLEVEL_DEBUG)) printk(KERN_DEBUG "%s: TX not complete, remaining %d bytes\n", dev->name, ch->devstat->rescnt); @@ -1110,15 +1210,17 @@ fsm_deltimer(&ch->timer); if (len < 8) { - printk(KERN_WARNING "%s: got packet with length %d < 8\n", - dev->name, len); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: got packet with length %d < 8\n", + dev->name, len); privptr->stats.rx_dropped++; privptr->stats.rx_length_errors++; goto again; } if (len > ch->max_bufsize) { - printk(KERN_WARNING "%s: got packet with length %d > %d\n", - dev->name, len, ch->max_bufsize); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: got packet with length %d > %d\n", + dev->name, len, ch->max_bufsize); privptr->stats.rx_dropped++; privptr->stats.rx_length_errors++; goto again; @@ -1137,8 +1239,9 @@ break; } if ((len < block_len) || (len > check_len)) { - printk(KERN_WARNING "%s: got block length %d != rx length %d\n", - dev->name, block_len, len); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: got block length %d != rx length %d\n", + dev->name, block_len, len); #ifdef DEBUG ctc_dump_skb(skb, 0); #endif @@ -1177,9 +1280,11 @@ channel *ch = (channel *)arg; int rc; - if (fsm_getstate(fi) == CH_STATE_TXIDLE) - printk(KERN_DEBUG "ch-%04x: remote side issued READ?, " - "init ...\n", ch->devno); + if (fsm_getstate(fi) == CH_STATE_TXIDLE) { + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "ch-%04x: remote side issued READ?, " + "init ...\n", ch->devno); + } fsm_deltimer(&ch->timer); if (ctc_checkalloc_buffer(ch, 1)) return; @@ -1253,7 +1358,8 @@ fsm_deltimer(&ch->timer); buflen = *((__u16 *)ch->trans_skb->data); #ifdef DEBUG - printk(KERN_DEBUG "%s: Initial RX count %d\n", dev->name, buflen); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: Initial RX count %d\n", dev->name, buflen); #endif if (buflen >= CTC_INITIAL_BLOCKLEN) { if (ctc_checkalloc_buffer(ch, 1)) @@ -1268,8 +1374,9 @@ fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXUP, dev); } else { - printk(KERN_DEBUG "%s: Initial RX count %d not %d\n", - dev->name, buflen, CTC_INITIAL_BLOCKLEN); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: Initial RX count %d not %d\n", + dev->name, buflen, CTC_INITIAL_BLOCKLEN); ch_action_firstio(fi, event, arg); } } @@ -1318,19 +1425,22 @@ net_device *dev; if (ch == NULL) { - printk(KERN_WARNING "ch_action_start ch=NULL\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ch_action_start ch=NULL\n"); return; } if (ch->netdev == NULL) { - printk(KERN_WARNING "ch_action_start dev=NULL, irq=%d\n", - ch->irq); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ch_action_start dev=NULL, irq=%d\n", + ch->irq); return; } dev = ch->netdev; #ifdef DEBUG - printk(KERN_DEBUG "%s: %s channel start\n", dev->name, - (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: %s channel start\n", dev->name, + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); #endif if (ch->trans_skb != NULL) { @@ -1347,12 +1457,14 @@ ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[1].count = 0; } - if (ctc_checkalloc_buffer(ch, 0)) - printk(KERN_NOTICE - "%s: Could not allocate %s trans_skb, delaying " - "allocation until first transfer\n", - dev->name, - (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); + if (ctc_checkalloc_buffer(ch, 0)) { + if (loglevel & CTC_LOGLEVEL_NOTICE) + printk(KERN_NOTICE + "%s: Could not allocate %s trans_skb, delaying " + "allocation until first transfer\n", + dev->name, + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); + } #if LINUX_VERSION_CODE >= 0x020400 INIT_LIST_HEAD(&ch->tq.list); @@ -1385,7 +1497,8 @@ ccw_check_return_code(ch, rc); } #ifdef DEBUG - printk(KERN_DEBUG "ctc: %s(): leaving\n", __FUNCTION__); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "ctc: %s(): leaving\n", __FUNCTION__); #endif } @@ -1525,10 +1638,11 @@ return; } - printk(KERN_DEBUG "%s: Error %s during %s channel setup state=%s\n", - dev->name, ch_event_names[event], - (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX", - fsm_getstate_str(fi)); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: Error %s during %s channel setup state=%s\n", + dev->name, ch_event_names[event], + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX", + fsm_getstate_str(fi)); if (CHANNEL_DIRECTION(ch->flags) == READ) { fsm_newstate(fi, CH_STATE_RXERR); fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev); @@ -1555,8 +1669,9 @@ net_device *dev = ch->netdev; fsm_deltimer(&ch->timer); - printk(KERN_DEBUG "%s: %s channel restart\n", dev->name, - (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: %s channel restart\n", dev->name, + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch); oldstate = fsm_getstate(fi); fsm_newstate(fi, CH_STATE_STARTWAIT); @@ -1587,8 +1702,9 @@ if (event == CH_EVENT_TIMER) { fsm_deltimer(&ch->timer); - printk(KERN_DEBUG "%s: Timeout during RX init handshake\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: Timeout during RX init handshake\n", + dev->name); if (ch->retry++ < 3) ch_action_restart(fi, event, arg); else { @@ -1597,8 +1713,9 @@ DEV_EVENT_RXDOWN, dev); } } else - printk(KERN_WARNING "%s: Error during RX init handshake\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "%s: Error during RX init handshake\n", + dev->name); } /** @@ -1615,8 +1732,10 @@ net_device *dev = ch->netdev; fsm_newstate(fi, CH_STATE_RXERR); - printk(KERN_WARNING "%s: RX initialization failed\n", dev->name); - printk(KERN_WARNING "%s: RX <-> RX connection detected\n", dev->name); + if (loglevel & CTC_LOGLEVEL_WARN) { + printk(KERN_WARNING "%s: RX initialization failed\n", dev->name); + printk(KERN_WARNING "%s: RX <-> RX connection detected\n", dev->name); + } fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev); } @@ -1634,8 +1753,9 @@ net_device *dev = ch->netdev; fsm_deltimer(&ch->timer); - printk(KERN_DEBUG "%s: Got remote disconnect, re-initializing ...\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: Got remote disconnect, re-initializing ...\n", + dev->name); /** * Notify device statemachine @@ -1665,8 +1785,9 @@ if (event == CH_EVENT_TIMER) { fsm_deltimer(&ch->timer); - printk(KERN_DEBUG "%s: Timeout during TX init handshake\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: Timeout during TX init handshake\n", + dev->name); if (ch->retry++ < 3) ch_action_restart(fi, event, arg); else { @@ -1675,8 +1796,9 @@ DEV_EVENT_TXDOWN, dev); } } else - printk(KERN_WARNING "%s: Error during TX init handshake\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "%s: Error during TX init handshake\n", + dev->name); } /** @@ -1694,14 +1816,16 @@ fsm_deltimer(&ch->timer); if (ch->retry++ > 3) { - printk(KERN_DEBUG "%s: TX retry failed, restarting channel\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: TX retry failed, restarting channel\n", + dev->name); fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev); ch_action_restart(fi, event, arg); } else { struct sk_buff *skb; - printk(KERN_DEBUG "%s: TX retry %d\n", dev->name, ch->retry); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: TX retry %d\n", dev->name, ch->retry); if ((skb = skb_peek(&ch->io_queue))) { int rc = 0; @@ -1709,8 +1833,9 @@ ch->ccw[4].count = skb->len; if (set_normalized_cda(&ch->ccw[4], virt_to_phys(skb->data))) { - printk(KERN_DEBUG "%s: IDAL alloc failed, " - "restarting channel\n", dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: IDAL alloc failed, " + "restarting channel\n", dev->name); fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev); ch_action_restart(fi, event, arg); @@ -1747,15 +1872,27 @@ fsm_deltimer(&ch->timer); if (CHANNEL_DIRECTION(ch->flags) == READ) { - printk(KERN_DEBUG "%s: RX I/O error\n", dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: RX I/O error\n", dev->name); fsm_newstate(fi, CH_STATE_RXERR); fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev); } else { - printk(KERN_DEBUG "%s: TX I/O error\n", dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: TX I/O error\n", dev->name); fsm_newstate(fi, CH_STATE_TXERR); fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev); } } + +static void ch_action_reinit(fsm_instance *fi, int event, void *arg) +{ + channel *ch = (channel *)arg; + net_device *dev = ch->netdev; + ctc_priv *privptr = dev->priv; + + ch_action_iofatal(fi, event, arg); + fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev); +} /** * The statemachine for a channel. @@ -1777,7 +1914,7 @@ { CH_STATE_STARTWAIT, CH_EVENT_FINSTAT, ch_action_setmode }, { CH_STATE_STARTWAIT, CH_EVENT_TIMER, ch_action_setuperr }, { CH_STATE_STARTWAIT, CH_EVENT_IO_ENODEV, ch_action_iofatal }, - { CH_STATE_STARTWAIT, CH_EVENT_IO_EIO, ch_action_iofatal }, + { CH_STATE_STARTWAIT, CH_EVENT_IO_EIO, ch_action_reinit }, { CH_STATE_STARTWAIT, CH_EVENT_MC_FAIL, ch_action_fail }, { CH_STATE_STARTRETRY, CH_EVENT_STOP, ch_action_haltio }, @@ -1792,7 +1929,7 @@ { CH_STATE_SETUPWAIT, CH_EVENT_UC_RSRESET, ch_action_setuperr }, { CH_STATE_SETUPWAIT, CH_EVENT_TIMER, ch_action_setmode }, { CH_STATE_SETUPWAIT, CH_EVENT_IO_ENODEV, ch_action_iofatal }, - { CH_STATE_SETUPWAIT, CH_EVENT_IO_EIO, ch_action_iofatal }, + { CH_STATE_SETUPWAIT, CH_EVENT_IO_EIO, ch_action_reinit }, { CH_STATE_SETUPWAIT, CH_EVENT_MC_FAIL, ch_action_fail }, { CH_STATE_RXINIT, CH_EVENT_STOP, ch_action_haltio }, @@ -1803,7 +1940,7 @@ { CH_STATE_RXINIT, CH_EVENT_TIMER, ch_action_rxiniterr }, { CH_STATE_RXINIT, CH_EVENT_ATTNBUSY, ch_action_rxinitfail }, { CH_STATE_RXINIT, CH_EVENT_IO_ENODEV, ch_action_iofatal }, - { CH_STATE_RXINIT, CH_EVENT_IO_EIO, ch_action_iofatal }, + { CH_STATE_RXINIT, CH_EVENT_IO_EIO, ch_action_reinit }, { CH_STATE_RXINIT, CH_EVENT_UC_ZERO, ch_action_firstio }, { CH_STATE_RXINIT, CH_EVENT_MC_FAIL, ch_action_fail }, @@ -1813,7 +1950,7 @@ { CH_STATE_RXIDLE, CH_EVENT_UC_RCRESET, ch_action_rxdisc }, // { CH_STATE_RXIDLE, CH_EVENT_UC_RSRESET, ch_action_rxretry }, { CH_STATE_RXIDLE, CH_EVENT_IO_ENODEV, ch_action_iofatal }, - { CH_STATE_RXIDLE, CH_EVENT_IO_EIO, ch_action_iofatal }, + { CH_STATE_RXIDLE, CH_EVENT_IO_EIO, ch_action_reinit }, { CH_STATE_RXIDLE, CH_EVENT_MC_FAIL, ch_action_fail }, { CH_STATE_RXIDLE, CH_EVENT_UC_ZERO, ch_action_rx }, @@ -1824,7 +1961,7 @@ { CH_STATE_TXINIT, CH_EVENT_UC_RSRESET, ch_action_txiniterr }, { CH_STATE_TXINIT, CH_EVENT_TIMER, ch_action_txiniterr }, { CH_STATE_TXINIT, CH_EVENT_IO_ENODEV, ch_action_iofatal }, - { CH_STATE_TXINIT, CH_EVENT_IO_EIO, ch_action_iofatal }, + { CH_STATE_TXINIT, CH_EVENT_IO_EIO, ch_action_reinit }, { CH_STATE_TXINIT, CH_EVENT_MC_FAIL, ch_action_fail }, { CH_STATE_TXIDLE, CH_EVENT_STOP, ch_action_haltio }, @@ -1833,7 +1970,7 @@ { CH_STATE_TXIDLE, CH_EVENT_UC_RCRESET, fsm_action_nop }, { CH_STATE_TXIDLE, CH_EVENT_UC_RSRESET, fsm_action_nop }, { CH_STATE_TXIDLE, CH_EVENT_IO_ENODEV, ch_action_iofatal }, - { CH_STATE_TXIDLE, CH_EVENT_IO_EIO, ch_action_iofatal }, + { CH_STATE_TXIDLE, CH_EVENT_IO_EIO, ch_action_reinit }, { CH_STATE_TXIDLE, CH_EVENT_MC_FAIL, ch_action_fail }, { CH_STATE_TERM, CH_EVENT_STOP, fsm_action_nop }, @@ -1857,7 +1994,7 @@ { CH_STATE_TX, CH_EVENT_UC_RSRESET, ch_action_txretry }, { CH_STATE_TX, CH_EVENT_TIMER, ch_action_txretry }, { CH_STATE_TX, CH_EVENT_IO_ENODEV, ch_action_iofatal }, - { CH_STATE_TX, CH_EVENT_IO_EIO, ch_action_iofatal }, + { CH_STATE_TX, CH_EVENT_IO_EIO, ch_action_reinit }, { CH_STATE_TX, CH_EVENT_MC_FAIL, ch_action_fail }, { CH_STATE_RXERR, CH_EVENT_STOP, ch_action_haltio }, @@ -1889,14 +2026,16 @@ char name[10]; if ((ch = (channel *)kmalloc(sizeof(channel), GFP_KERNEL)) == NULL) { - printk(KERN_WARNING "ctc: Out of memory in add_channel\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ctc: Out of memory in add_channel\n"); return -1; } memset(ch, 0, sizeof(channel)); if ((ch->ccw = (ccw1_t *)kmalloc(sizeof(ccw1_t) * 8, GFP_KERNEL|GFP_DMA)) == NULL) { kfree(ch); - printk(KERN_WARNING "ctc: Out of memory in add_channel\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ctc: Out of memory in add_channel\n"); return -1; } @@ -1932,20 +2071,23 @@ ch->irq = irq; ch->devno = devno; ch->type = type; + loglevel = CTC_LOGLEVEL_DEFAULT; sprintf(name, "ch-%04x", devno); ch->fsm = init_fsm(name, ch_state_names, ch_event_names, NR_CH_STATES, NR_CH_EVENTS, ch_fsm, CH_FSM_LEN, GFP_KERNEL); if (ch->fsm == NULL) { - printk(KERN_WARNING - "ctc: Could not create FSM in add_channel\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: Could not create FSM in add_channel\n"); kfree(ch); return -1; } fsm_newstate(ch->fsm, CH_STATE_IDLE); if ((ch->devstat = (devstat_t*)kmalloc(sizeof(devstat_t), GFP_KERNEL)) == NULL) { - printk(KERN_WARNING "ctc: Out of memory in add_channel\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ctc: Out of memory in add_channel\n"); kfree_fsm(ch->fsm); kfree(ch); return -1; @@ -1954,9 +2096,10 @@ while (*c && ((*c)->devno < devno)) c = &(*c)->next; if ((*c)->devno == devno) { - printk(KERN_DEBUG - "ctc: add_channel: device %04x already in list, " - "using old entry\n", (*c)->devno); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: add_channel: device %04x already in list, " + "using old entry\n", (*c)->devno); kfree(ch->devstat); kfree_fsm(ch->fsm); kfree(ch); @@ -2006,14 +2149,16 @@ } } if (print_result) { - if (nr_escon + nr_ctca) - printk(KERN_INFO - "ctc: %d CTC/A channel%s and %d ESCON " - "channel%s found.\n", - nr_ctca, (nr_ctca == 1) ? "s" : "", - nr_escon, (nr_escon == 1) ? "s" : ""); - else - printk(KERN_INFO "ctc: No channel devices found.\n"); + if (loglevel & CTC_LOGLEVEL_INFO) { + if (nr_escon + nr_ctca) + printk(KERN_INFO + "ctc: %d CTC/A channel%s and %d ESCON " + "channel%s found.\n", + nr_ctca, (nr_ctca == 1) ? "s" : "", + nr_escon, (nr_escon == 1) ? "s" : ""); + else + printk(KERN_INFO "ctc: No channel devices found.\n"); + } } print_result = 0; } @@ -2079,28 +2224,32 @@ channel *ch = channels; #ifdef DEBUG - printk(KERN_DEBUG - "ctc: %s(): searching for ch with devno %d and type %d\n", - __FUNCTION__, devno, type); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: %s(): searching for ch with devno %d and type %d\n", + __FUNCTION__, devno, type); #endif while (ch && ((ch->devno != devno) || (ch->type != type))) { #ifdef DEBUG - printk(KERN_DEBUG - "ctc: %s(): ch=0x%p (devno=%d, type=%d\n", - __FUNCTION__, ch, ch->devno, ch->type); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: %s(): ch=0x%p (devno=%d, type=%d\n", + __FUNCTION__, ch, ch->devno, ch->type); #endif ch = ch->next; } #ifdef DEBUG - printk(KERN_DEBUG - "ctc: %s(): ch=0x%pq (devno=%d, type=%d\n", - __FUNCTION__, ch, ch->devno, ch->type); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: %s(): ch=0x%pq (devno=%d, type=%d\n", + __FUNCTION__, ch, ch->devno, ch->type); #endif if (!ch) { - printk(KERN_WARNING "ctc: %s(): channel with devno %d " - "and type %d not found in channel list\n", - __FUNCTION__, devno, type); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ctc: %s(): channel with devno %d " + "and type %d not found in channel list\n", + __FUNCTION__, devno, type); } else { if (ch->flags & CHANNEL_FLAGS_INUSE) @@ -2197,39 +2346,43 @@ */ if (ch == NULL) { if ((ch = find_channel_by_irq(irq)) == NULL) { - printk(KERN_WARNING - "ctc: Got unsolicited irq: %04x c-%02x d-%02x" - "f-%02x\n", devstat->devno, devstat->cstat, - devstat->dstat, devstat->flag); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: Got unsolicited irq: %04x c-%02x d-%02x" + "f-%02x\n", devstat->devno, devstat->cstat, + devstat->dstat, devstat->flag); goto done; } } dev = (net_device *)(ch->netdev); if (dev == NULL) { - printk(KERN_CRIT - "ctc: ctc_irq_handler dev = NULL irq=%d, ch=0x%p\n", - irq, ch); + if (loglevel & CTC_LOGLEVEL_CRIT) + printk(KERN_CRIT + "ctc: ctc_irq_handler dev = NULL irq=%d, ch=0x%p\n", + irq, ch); goto done; } - if (intparm == NULL) + if ((intparm == NULL) && (loglevel & CTC_LOGLEVEL_DEBUG)) printk(KERN_DEBUG "%s: Channel %04x found by IRQ %d\n", dev->name, ch->devno, irq); #ifdef DEBUG - printk(KERN_DEBUG - "%s: interrupt for device: %04x received c-%02x d-%02x " - "f-%02x\n", dev->name, devstat->devno, devstat->cstat, - devstat->dstat, devstat->flag); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "%s: interrupt for device: %04x received c-%02x d-%02x " + "f-%02x\n", dev->name, devstat->devno, devstat->cstat, + devstat->dstat, devstat->flag); #endif /* Check for good subchannel return code, otherwise error message */ if (devstat->cstat) { fsm_event(ch->fsm, CH_EVENT_SC_UNKNOWN, ch); - printk(KERN_WARNING - "%s: subchannel check for device: %04x - %02x %02x " - "%02x\n", dev->name, ch->devno, devstat->cstat, - devstat->dstat, devstat->flag); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s: subchannel check for device: %04x - %02x %02x " + "%02x\n", dev->name, ch->devno, devstat->cstat, + devstat->dstat, devstat->flag); goto done; } @@ -2274,6 +2427,7 @@ ctc_priv *privptr = dev->priv; int direction; + fsm_deltimer(&privptr->restart_timer); fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX); for (direction = READ; direction <= WRITE; direction++) { channel *ch = privptr->channel[direction]; @@ -2301,6 +2455,19 @@ } } +static void dev_action_restart(fsm_instance *fi, int event, void *arg) +{ + net_device *dev = (net_device *)arg; + ctc_priv *privptr = dev->priv; + + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: Restarting\n", dev->name); + dev_action_stop(fi, event, arg); + fsm_event(privptr->fsm, DEV_EVENT_STOP, dev); + fsm_addtimer(&privptr->restart_timer, CTC_TIMEOUT_5SEC, + DEV_EVENT_START, dev); +} + /** * Called from channel statemachine * when a channel is up and running. @@ -2324,9 +2491,10 @@ case DEV_STATE_STARTWAIT_RX: if (event == DEV_EVENT_RXUP) { fsm_newstate(fi, DEV_STATE_RUNNING); - printk(KERN_INFO - "%s: connected with remote side\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO + "%s: connected with remote side\n", + dev->name); if (privptr->protocol == CTC_PROTO_LINUX_TTY) ctc_tty_setcarrier(dev, 1); ctc_clear_busy(dev); @@ -2335,9 +2503,10 @@ case DEV_STATE_STARTWAIT_TX: if (event == DEV_EVENT_TXUP) { fsm_newstate(fi, DEV_STATE_RUNNING); - printk(KERN_INFO - "%s: connected with remote side\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO + "%s: connected with remote side\n", + dev->name); if (privptr->protocol == CTC_PROTO_LINUX_TTY) ctc_tty_setcarrier(dev, 1); ctc_clear_busy(dev); @@ -2402,43 +2571,50 @@ } static const fsm_node dev_fsm[] = { - { DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start }, + { DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start }, - { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_START, dev_action_start }, - { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown }, - { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown }, - - { DEV_STATE_STOPWAIT_RX, DEV_EVENT_START, dev_action_start }, - { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXUP, dev_action_chup }, - { DEV_STATE_STOPWAIT_RX, DEV_EVENT_TXUP, dev_action_chup }, - { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXDOWN, dev_action_chdown }, - - { DEV_STATE_STOPWAIT_TX, DEV_EVENT_START, dev_action_start }, - { DEV_STATE_STOPWAIT_TX, DEV_EVENT_RXUP, dev_action_chup }, - { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXUP, dev_action_chup }, - { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXDOWN, dev_action_chdown }, - - { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP, dev_action_stop }, - { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP, dev_action_chup }, - { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP, dev_action_chup }, - { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown }, - { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown }, - - { DEV_STATE_STARTWAIT_TX, DEV_EVENT_STOP, dev_action_stop }, - { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXUP, dev_action_chup }, - { DEV_STATE_STARTWAIT_TX, DEV_EVENT_TXUP, dev_action_chup }, - { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXDOWN, dev_action_chdown }, - - { DEV_STATE_STARTWAIT_RX, DEV_EVENT_STOP, dev_action_stop }, - { DEV_STATE_STARTWAIT_RX, DEV_EVENT_RXUP, dev_action_chup }, - { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXUP, dev_action_chup }, - { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXDOWN, dev_action_chdown }, - - { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop }, - { DEV_STATE_RUNNING, DEV_EVENT_RXDOWN, dev_action_chdown }, - { DEV_STATE_RUNNING, DEV_EVENT_TXDOWN, dev_action_chdown }, - { DEV_STATE_RUNNING, DEV_EVENT_TXUP, fsm_action_nop }, - { DEV_STATE_RUNNING, DEV_EVENT_RXUP, fsm_action_nop }, + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_START, dev_action_start }, + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown }, + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown }, + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart }, + + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_START, dev_action_start }, + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXUP, dev_action_chup }, + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_TXUP, dev_action_chup }, + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXDOWN, dev_action_chdown }, + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RESTART, dev_action_restart }, + + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_START, dev_action_start }, + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_RXUP, dev_action_chup }, + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXUP, dev_action_chup }, + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXDOWN, dev_action_chdown }, + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_RESTART, dev_action_restart }, + + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP, dev_action_stop }, + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP, dev_action_chup }, + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP, dev_action_chup }, + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown }, + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown }, + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart }, + + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_STOP, dev_action_stop }, + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXUP, dev_action_chup }, + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_TXUP, dev_action_chup }, + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXDOWN, dev_action_chdown }, + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RESTART, dev_action_restart }, + + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_STOP, dev_action_stop }, + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_RXUP, dev_action_chup }, + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXUP, dev_action_chup }, + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXDOWN, dev_action_chdown }, + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_RESTART, dev_action_restart }, + + { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop }, + { DEV_STATE_RUNNING, DEV_EVENT_RXDOWN, dev_action_chdown }, + { DEV_STATE_RUNNING, DEV_EVENT_TXDOWN, dev_action_chdown }, + { DEV_STATE_RUNNING, DEV_EVENT_TXUP, fsm_action_nop }, + { DEV_STATE_RUNNING, DEV_EVENT_RXUP, fsm_action_nop }, + { DEV_STATE_RUNNING, DEV_EVENT_RESTART, dev_action_restart }, }; static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node); @@ -2633,14 +2809,16 @@ * Some sanity checks ... */ if (skb == NULL) { - printk(KERN_WARNING "%s: NULL sk_buff passed\n", dev->name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "%s: NULL sk_buff passed\n", dev->name); privptr->stats.tx_dropped++; return 0; } if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) { - printk(KERN_WARNING - "%s: Got sk_buff with head room < %ld bytes\n", - dev->name, LL_HEADER_LENGTH + 2); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s: Got sk_buff with head room < %ld bytes\n", + dev->name, LL_HEADER_LENGTH + 2); dev_kfree_skb(skb); privptr->stats.tx_dropped++; return 0; @@ -2725,7 +2903,8 @@ privptr = (ctc_priv *)dev->priv; if ((privptr->proc_ctrl_entry->low_ino == ino) || - (privptr->proc_stat_entry->low_ino == ino)) + (privptr->proc_stat_entry->low_ino == ino) || + (privptr->proc_loglevel_entry->low_ino == ino)) return dev; } ch = ch->next; @@ -2844,6 +3023,91 @@ return ret; } +#define LOGLEVEL_BUFSIZE 10 + +static int ctc_loglevel_open(struct inode *inode, struct file *file) +{ + file->private_data = kmalloc(LOGLEVEL_BUFSIZE, GFP_KERNEL); + if (file->private_data == NULL) + return -ENOMEM; + MOD_INC_USE_COUNT; + return 0; +} + +static int ctc_loglevel_close(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + MOD_DEC_USE_COUNT; + return 0; +} + +static ssize_t ctc_loglevel_write(struct file *file, const char *buf, size_t count, + loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + net_device *dev; + ctc_priv *privptr; + char *e; + int bs1; + char tmp[40]; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + if (off != &file->f_pos) + return -ESPIPE; + + privptr = (ctc_priv *)dev->priv; + + if (count >= 3) + return -EINVAL; + + if (copy_from_user(tmp, buf, count)) + return -EFAULT; + tmp[count+1] = '\0'; + bs1 = simple_strtoul(tmp, &e, 0); + + if ((bs1 > CTC_LOGLEVEL_MAX) || + (e && (!isspace(*e)))) + return -EINVAL; + + loglevel = bs1; + return count; +} + +static ssize_t ctc_loglevel_read(struct file *file, char *buf, size_t count, + loff_t *off) +{ + unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino; + char *sbuf = (char *)file->private_data; + net_device *dev; + ctc_priv *privptr; + ssize_t ret = 0; + char *p = sbuf; + int l; + + if (!(dev = find_netdev_by_ino(ino))) + return -ENODEV; + if (off != &file->f_pos) + return -ESPIPE; + + privptr = (ctc_priv *)dev->priv; + + if (file->f_pos == 0) + sprintf(sbuf, "0x%02x\n", loglevel); + + l = strlen(sbuf); + p = sbuf; + if (file->f_pos < l) { + p += file->f_pos; + l = strlen(p); + ret = (count > l) ? l : count; + if (copy_to_user(buf, p, ret)) + return -EFAULT; + } + file->f_pos += ret; + return ret; +} + #define STATS_BUFSIZE 2048 static int ctc_stat_open(struct inode *inode, struct file *file) @@ -2946,6 +3210,13 @@ release: ctc_ctrl_close, }; +static struct file_operations ctc_loglevel_fops = { + read: ctc_loglevel_read, + write: ctc_loglevel_write, + open: ctc_loglevel_open, + release: ctc_loglevel_close, +}; + static struct inode_operations ctc_stat_iops = { #if LINUX_VERSION_CODE < 0x020363 default_file_ops: &ctc_stat_fops @@ -2956,6 +3227,11 @@ default_file_ops: &ctc_ctrl_fops #endif }; +static struct inode_operations ctc_loglevel_iops = { +#if LINUX_VERSION_CODE < 0x020363 + default_file_ops: &ctc_loglevel_fops +#endif +}; static struct proc_dir_entry stat_entry = { 0, /* low_ino */ @@ -2981,6 +3257,18 @@ &ctc_ctrl_iops /* ops */ }; +static struct proc_dir_entry loglevel_entry = { + 0, /* low_ino */ + 8, /* namelen */ + "loglevel", /* name */ + S_IFREG | S_IRUSR | S_IWUSR, /* mode */ + 1, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 0, /* size */ + &ctc_loglevel_iops /* ops */ +}; + #if LINUX_VERSION_CODE < 0x020363 static struct proc_dir_entry ctc_dir = { 0, /* low_ino */ @@ -3023,8 +3311,10 @@ * If not registered, register main proc dir-entry now */ #if LINUX_VERSION_CODE > 0x020362 +#ifdef CONFIG_PROC_FS if (!ctc_dir) ctc_dir = proc_mkdir("ctc", proc_net); +#endif #else if (ctc_dir.low_ino == 0) proc_net_register(&ctc_dir); @@ -3037,12 +3327,14 @@ */ static void ctc_proc_destroy_main(void) { #if LINUX_VERSION_CODE > 0x020362 +#ifdef CONFIG_PROC_FS remove_proc_entry("ctc", proc_net); +#endif #else proc_net_unregister(ctc_dir.low_ino); #endif } -#endif MODULE +#endif /* MODULE */ /** * Create a device specific subdirectory in /proc/net/ctc/ with the @@ -3069,12 +3361,19 @@ privptr->proc_dentry); privptr->proc_ctrl_entry->proc_fops = &ctc_ctrl_fops; privptr->proc_ctrl_entry->proc_iops = &ctc_ctrl_iops; + privptr->proc_loglevel_entry = + create_proc_entry("loglevel", + S_IFREG | S_IRUSR | S_IWUSR, + privptr->proc_dentry); + privptr->proc_loglevel_entry->proc_fops = &ctc_loglevel_fops; + privptr->proc_loglevel_entry->proc_iops = &ctc_loglevel_iops; #else privptr->proc_dentry->name = dev->name; privptr->proc_dentry->namelen = strlen(dev->name); proc_register(&ctc_dir, privptr->proc_dentry); proc_register(privptr->proc_dentry, privptr->proc_stat_entry); proc_register(privptr->proc_dentry, privptr->proc_ctrl_entry); + proc_register(privptr->proc_dentry, privptr->proc_loglevel_entry); #endif privptr->proc_registered = 1; } @@ -3089,11 +3388,14 @@ if (!privptr->proc_registered) return; #if LINUX_VERSION_CODE > 0x020362 + remove_proc_entry("loglevel", privptr->proc_dentry); remove_proc_entry("statistics", privptr->proc_dentry); remove_proc_entry("buffersize", privptr->proc_dentry); remove_proc_entry(privptr->proc_dentry->name, ctc_dir); #else proc_unregister(privptr->proc_dentry, + privptr->proc_loglevel_entry->low_ino); + proc_unregister(privptr->proc_dentry, privptr->proc_stat_entry->low_ino); proc_unregister(privptr->proc_dentry, privptr->proc_ctrl_entry->low_ino); @@ -3144,8 +3446,9 @@ int noauto = 0; #ifdef DEBUG - printk(KERN_DEBUG - "ctc: parse_opts(): *setup='%s', maxip=%d\n", *setup, maxip); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: parse_opts(): *setup='%s', maxip=%d\n", *setup, maxip); #endif if (*setup) { *dev_name = *setup; @@ -3154,8 +3457,9 @@ strncmp(cur, "noauto", 6)) { if ((*setup = strchr(cur, ':'))) *(*setup)++ = '\0'; - printk(KERN_WARNING - "ctc: Invalid device name or option '%s'\n", + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: Invalid device name or option '%s'\n", cur); return 1; } @@ -3185,10 +3489,11 @@ ints[i++] = simple_strtoul(cur, NULL, 0); #ifdef DEBUG - printk(KERN_DEBUG - "ctc: %s: ints[%d]=%d\n", - __FUNCTION__, - i-1, ints[i-1]); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: %s: ints[%d]=%d\n", + __FUNCTION__, + i-1, ints[i-1]); #endif if ((cur = strchr(cur, ':')) != NULL) cur++; @@ -3303,36 +3608,41 @@ read_dev = -1; proto = CTC_PROTO_S390; #ifdef DEBUG - printk(KERN_DEBUG - "ctc: ctc_setup(): setup='%s' dev_name='%s'," - " ints[0]=%d)\n", - setup, dev_name, ints[0]); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: ctc_setup(): setup='%s' dev_name='%s'," + " ints[0]=%d)\n", + setup, dev_name, ints[0]); #endif DEBUG if (dev_name == NULL) { /** * happens if device name is not specified in * parameter line (cf. init/main.c:get_options() */ - printk(KERN_WARNING - "ctc: %s(): Device name not specified\n", - __FUNCTION__); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: %s(): Device name not specified\n", + __FUNCTION__); ctc_setup_return; } #ifdef DEBUG - printk(KERN_DEBUG "name=´%s´ argc=%d\n", dev_name, ints[0]); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "name=´%s´ argc=%d\n", dev_name, ints[0]); #endif if (strcmp(dev_name, "noauto") == 0) { - printk(KERN_INFO "ctc: autoprobing disabled\n"); + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO "ctc: autoprobing disabled\n"); ctc_no_auto = 1; continue; } if (find_param(dev_name) != NULL) { - printk(KERN_WARNING - "ctc: Definition for device %s already set. " - "Ignoring second definition\n", dev_name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: Definition for device %s already set. " + "Ignoring second definition\n", dev_name); continue; } @@ -3340,9 +3650,10 @@ case 3: /* protocol type passed */ proto = ints[3]; if (proto > CTC_PROTO_MAX) { - printk(KERN_WARNING - "%s: wrong protocol type " - "passed\n", dev_name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s: wrong protocol type " + "passed\n", dev_name); ctc_setup_return; } case 2: /* write channel passed */ @@ -3353,22 +3664,25 @@ write_dev = read_dev + 1; break; default: - printk(KERN_WARNING - "ctc: wrong number of parameter " - "passed (is: %d, expected: [1..3]\n", - ints[0]); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: wrong number of parameter " + "passed (is: %d, expected: [1..3]\n", + ints[0]); ctc_setup_return; } par = alloc_param(); if (!par) { #ifdef MODULE - printk(KERN_WARNING - "ctc: Couldn't allocate setup param block\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: Couldn't allocate setup param block\n"); #else - printk(KERN_WARNING - "ctc: Number of device definitions in " - " kernel commandline exceeds builtin limit " - " of %d devices.\n", MAX_STATIC_DEVICES); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: Number of device definitions in " + " kernel commandline exceeds builtin limit " + " of %d devices.\n", MAX_STATIC_DEVICES); #endif ctc_setup_return; } @@ -3379,8 +3693,9 @@ par->next = params; params = par; #ifdef DEBUG - printk(KERN_DEBUG "%s: protocol=%x read=%04x write=%04x\n", - dev_name, proto, read_dev, write_dev); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "%s: protocol=%x read=%04x write=%04x\n", + dev_name, proto, read_dev, write_dev); #endif } ctc_setup_return; @@ -3488,9 +3803,13 @@ privptr->proc_ctrl_entry = (struct proc_dir_entry *) (((char *)privptr) + sizeof(ctc_priv) + sizeof(ctc_template) + sizeof(stat_entry)); + privptr->proc_loglevel_entry = (struct proc_dir_entry *) + (((char *)privptr) + sizeof(ctc_priv) + + sizeof(ctc_template) + sizeof(stat_entry) + sizeof(ctrl_entry)); memcpy(privptr->proc_dentry, &ctc_template, sizeof(ctc_template)); memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry)); memcpy(privptr->proc_ctrl_entry, &ctrl_entry, sizeof(ctrl_entry)); + memcpy(privptr->proc_loglevel_entry, &loglevel_entry, sizeof(loglevel_entry)); privptr->fsm = init_fsm("ctcdev", dev_state_names, dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, dev_fsm, DEV_FSM_LEN, GFP_KERNEL); @@ -3501,6 +3820,7 @@ return NULL; } fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); + fsm_settimer(privptr->fsm, &privptr->restart_timer); dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2; dev->hard_start_xmit = ctc_tx; dev->open = ctc_open; @@ -3540,10 +3860,11 @@ if (get_dev_info_by_irq(ch->irq, &devinfo)) ch->devno = devinfo.devno; else - printk(KERN_WARNING - "ctc_chandev_msck_notify: " - "get_dev_info_by_irq failed for " - "irq %d\n", ch->irq); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc_chandev_msck_notify: " + "get_dev_info_by_irq failed for " + "irq %d\n", ch->irq); } } switch (newstatus) { @@ -3552,18 +3873,27 @@ case chandev_status_gone: for (direction = READ; direction <= WRITE; direction++) { channel *ch = privptr->channel[direction]; + ch->flags |= CHANNEL_FLAGS_FAILED; fsm_event(ch->fsm, CH_EVENT_MC_FAIL, ch); } - printk(KERN_WARNING - "ctc: %s channel deactivated\n", device->name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: %s channel deactivated\n", device->name); break; case chandev_status_all_chans_good: for (direction = READ; direction <= WRITE; direction++) { channel *ch = privptr->channel[direction]; + if (!(ch->flags & CHANNEL_FLAGS_FAILED)) + fsm_event(ch->fsm, CH_EVENT_MC_FAIL, ch); + } + for (direction = READ; direction <= WRITE; direction++) { + channel *ch = privptr->channel[direction]; + ch->flags &= ~CHANNEL_FLAGS_FAILED; fsm_event(ch->fsm, CH_EVENT_MC_GOOD, ch); } - printk(KERN_WARNING - "ctc: %s channel activated\n", device->name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: %s channel activated\n", device->name); break; default: break; @@ -3605,8 +3935,9 @@ type = channel_type_escon; break; default: - printk(KERN_WARNING "ctc_chandev_probe called with " - "unsupported channel type %d\n", info->chan_type); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ctc_chandev_probe called with " + "unsupported channel type %d\n", info->chan_type); return -ENODEV; } devno[READ] = info->read.devno; @@ -3622,7 +3953,8 @@ if (!dev) { - printk(KERN_WARNING "ctc_init_netdevice failed\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ctc_init_netdevice failed\n"); return -ENODEV; } @@ -3653,10 +3985,11 @@ dev->name, privptr->channel[direction]->devstat); if (rc) { - printk(KERN_WARNING - "%s: requested irq %d is busy rc=%02x\n", - dev->name, privptr->channel[direction]->irq, - rc); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s: requested irq %d is busy rc=%02x\n", + dev->name, privptr->channel[direction]->irq, + rc); if (direction == WRITE) { FREE_IRQ(privptr->channel[READ]->irq, privptr->channel[READ]->devstat); @@ -3681,12 +4014,13 @@ print_banner(); - printk(KERN_INFO - "%s: read: ch %04x (irq %04x), " - "write: ch %04x (irq %04x) proto: %d\n", - dev->name, privptr->channel[READ]->devno, - privptr->channel[READ]->irq, privptr->channel[WRITE]->devno, - privptr->channel[WRITE]->irq, proto); + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO + "%s: read: ch %04x (irq %04x), " + "write: ch %04x (irq %04x) proto: %d\n", + dev->name, privptr->channel[READ]->devno, + privptr->channel[READ]->irq, privptr->channel[WRITE]->devno, + privptr->channel[WRITE]->irq, proto); chandev_initdevice(info, dev, 0, dev->name, (proto == CTC_PROTO_LINUX_TTY) @@ -3779,10 +4113,11 @@ dev->name, privptr->channel[direction]->devstat); if (rc) { - printk(KERN_WARNING - "%s: requested irq %d is busy rc=%02x\n", - dev->name, privptr->channel[direction]->irq, - rc); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "%s: requested irq %d is busy rc=%02x\n", + dev->name, privptr->channel[direction]->irq, + rc); if (direction == WRITE) { FREE_IRQ(privptr->channel[READ]->irq, privptr->channel[READ]->devstat); @@ -3801,12 +4136,13 @@ print_banner(); - printk(KERN_INFO - "%s: read: ch %04x (irq %04x), " - "write: ch %04x (irq %04x) proto: %d\n", - dev->name, privptr->channel[READ]->devno, - privptr->channel[READ]->irq, privptr->channel[WRITE]->devno, - privptr->channel[WRITE]->irq, proto); + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO + "%s: read: ch %04x (irq %04x), " + "write: ch %04x (irq %04x) proto: %d\n", + dev->name, privptr->channel[READ]->devno, + privptr->channel[READ]->irq, privptr->channel[WRITE]->devno, + privptr->channel[WRITE]->irq, proto); return 0; } @@ -3853,11 +4189,12 @@ #ifdef CTC_CHANDEV chandev_unregister(ctc_chandev_probe, 1); #endif - printk(KERN_INFO "CTC driver unloaded\n"); + if (loglevel & CTC_LOGLEVEL_INFO) + printk(KERN_INFO "CTC driver unloaded\n"); } #define ctc_init init_module -#endif MODULE +#endif /* MODULE */ /** * Initialize module. @@ -3878,8 +4215,9 @@ print_banner(); #if defined(DEBUG) && !defined(CTC_CHANDEV) - printk(KERN_DEBUG - "ctc: init_module(): got string '%s'\n", ctc); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: init_module(): got string '%s'\n", ctc); #endif #ifndef CTC_CHANDEV @@ -3939,24 +4277,28 @@ (cnt[itype])++); } #ifdef DEBUG - printk(KERN_DEBUG "ctc: %s(): probing for device %s\n", - __FUNCTION__, dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG "ctc: %s(): probing for device %s\n", + __FUNCTION__, dev->name); #endif probed = 1; if (ctc_probe(dev) == 0) { ctc_priv *privptr = (ctc_priv *)dev->priv; #ifdef DEBUG - printk(KERN_DEBUG - "ctc: %s(): probing succeeded\n", - __FUNCTION__); - printk(KERN_DEBUG - "ctc: %s(): registering device %s\n", - __FUNCTION__, dev->name); + if (loglevel & CTC_LOGLEVEL_DEBUG) { + printk(KERN_DEBUG + "ctc: %s(): probing succeeded\n", + __FUNCTION__); + printk(KERN_DEBUG + "ctc: %s(): registering device %s\n", + __FUNCTION__, dev->name); + } #endif if (ctc_netdev_register(dev) != 0) { - printk(KERN_WARNING - "ctc: Couldn't register %s\n", - dev->name); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING + "ctc: Couldn't register %s\n", + dev->name); FREE_IRQ( privptr->channel[READ]->irq, privptr->channel[READ]->devstat); @@ -3969,17 +4311,19 @@ dev = NULL; } else { #ifdef DEBUG - printk(KERN_DEBUG - "ctc: %s(): register succeed\n", - __FUNCTION__); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: %s(): register succeed\n", + __FUNCTION__); #endif activated++; } } else { #ifdef DEBUG - printk(KERN_DEBUG - "ctc: %s(): probing failed\n", - __FUNCTION__); + if (loglevel & CTC_LOGLEVEL_DEBUG) + printk(KERN_DEBUG + "ctc: %s(): probing failed\n", + __FUNCTION__); #endif dev = NULL; } @@ -3988,7 +4332,8 @@ #endif /* CHANDEV */ #if !defined(CTC_CHANDEV) && defined(MODULE) if (!activated) { - printk(KERN_WARNING "ctc: No devices registered\n"); + if (loglevel & CTC_LOGLEVEL_WARN) + printk(KERN_WARNING "ctc: No devices registered\n"); ret = -ENODEV; } #endif diff -urN linux-2.4.21/drivers/s390/net/ctctty.c linux-2.4.22/drivers/s390/net/ctctty.c --- linux-2.4.21/drivers/s390/net/ctctty.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/s390/net/ctctty.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,5 +1,5 @@ /* - * $Id: ctctty.c,v 1.8 2001/05/16 16:28:31 felfert Exp $ + * $Id: ctctty.c,v 1.11 2003/05/14 15:27:54 felfert Exp $ * * CTC / ESCON network driver, tty interface. * @@ -88,6 +88,7 @@ struct semaphore write_sem; struct tq_struct tq; struct timer_list stoptimer; + struct timer_list flowtimer; } ctc_tty_info; /* Description of one CTC-tty */ @@ -114,7 +115,7 @@ static char *ctc_ttyname = CTC_TTY_NAME; #endif -char *ctc_tty_revision = "$Revision: 1.8 $"; +char *ctc_tty_revision = "$Revision: 1.11 $"; static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC; static int ctc_tty_shuttingdown = 0; @@ -163,35 +164,44 @@ static int ctc_tty_readmodem(ctc_tty_info *info) { - int ret = 1; + int c; struct tty_struct *tty; + struct sk_buff *skb; - if ((tty = info->tty)) { - if (info->mcr & UART_MCR_RTS) { - int c = TTY_FLIPBUF_SIZE - tty->flip.count; - struct sk_buff *skb; - - if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) { - int len = skb->len; - if (len > c) - len = c; - memcpy(tty->flip.char_buf_ptr, skb->data, len); - skb_pull(skb, len); - memset(tty->flip.flag_buf_ptr, 0, len); - tty->flip.count += len; - tty->flip.char_buf_ptr += len; - tty->flip.flag_buf_ptr += len; - tty_flip_buffer_push(tty); - if (skb->len > 0) - skb_queue_head(&info->rx_queue, skb); - else { - kfree_skb(skb); - ret = skb_queue_len(&info->rx_queue); - } - } + if (!(tty = info->tty)) + return 0; + + /* If the upper layer is flow blocked or just + * has no room for data we schedule a timer to + * try again later - wilder + */ + c = TTY_FLIPBUF_SIZE - tty->flip.count; + if ( !(info->mcr & UART_MCR_RTS) || (c <= 0) ) { + /* can't do any work now, wake up later */ + mod_timer(&info->flowtimer, jiffies+(HZ/100) ); + return 0; + } + + if ((skb = skb_dequeue(&info->rx_queue))) { + int len = skb->len; + if (len > c) + len = c; + memcpy(tty->flip.char_buf_ptr, skb->data, len); + skb_pull(skb, len); + memset(tty->flip.flag_buf_ptr, 0, len); + tty->flip.count += len; + tty->flip.char_buf_ptr += len; + tty->flip.flag_buf_ptr += len; + tty_flip_buffer_push(tty); + + if (skb->len > 0){ + skb_queue_head(&info->rx_queue, skb); + }else { + kfree_skb(skb); } } - return ret; + + return skb_queue_len(&info->rx_queue); } void @@ -234,6 +244,11 @@ dev_kfree_skb(skb); return; } + if ( !(info->tty) ) { + dev_kfree_skb(skb); + return; + } + if (skb->len < 6) { dev_kfree_skb(skb); return; @@ -244,7 +259,7 @@ } skb_pull(skb, sizeof(__u32)); - i = *((int *)skb->data); + i = *((__u32 *)skb->data); skb_pull(skb, sizeof(info->mcr)); if (i & UART_MCR_RTS) { info->msr |= UART_MSR_CTS; @@ -270,7 +285,12 @@ /* Direct deliver failed or queue wasn't empty. * Queue up for later dequeueing via timer-irq. */ - skb_queue_tail(&info->rx_queue, skb); + if (skb_queue_len(&info->rx_queue) < 50) + skb_queue_tail(&info->rx_queue, skb); + else { + kfree_skb(skb); + printk(KERN_DEBUG "ctctty: RX overrun\n"); + } /* Schedule dequeuing */ queue_task(&info->tq, &tq_immediate); mark_bh(IMMEDIATE_BH); @@ -330,6 +350,13 @@ skb_queue_head(&info->tx_queue, skb); else kfree_skb(skb); + + /* The connection is not up yet, try again in one second. - wilder */ + if ( rc == -EBUSY ){ + mod_timer(&info->flowtimer, jiffies+(HZ) ); + return 0; + } + } else { struct tty_struct *tty = info->tty; @@ -484,6 +511,18 @@ info->flags &= ~CTC_ASYNC_NETDEV_OPEN; } +/* Run from the timer queue when we are flow blocked + * to kick start the bottom half - wilder */ +static void +ctc_tty_startupbh(unsigned long data) +{ + ctc_tty_info *info = (ctc_tty_info *)data; + if (( !ctc_tty_shuttingdown) && info) { + queue_task(&info->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); + } +} + /* * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on. @@ -577,6 +616,12 @@ if (ctc_tty_paranoia_check(info, tty->device, "ctc_tty_write_room")) return 0; + +/* wilder */ + if (skb_queue_len(&info->tx_queue) > 10 ) { + return 0; + } + return CTC_TTY_XMIT_SIZE; } @@ -1262,6 +1307,9 @@ init_timer(&info->stoptimer); info->stoptimer.function = ctc_tty_stopdev; info->stoptimer.data = (unsigned long)info; + init_timer(&info->flowtimer); + info->flowtimer.function = ctc_tty_startupbh; + info->flowtimer.data = (unsigned long)info; info->mcr = UART_MCR_RTS; } return 0; diff -urN linux-2.4.21/drivers/s390/net/fsm.h linux-2.4.22/drivers/s390/net/fsm.h --- linux-2.4.21/drivers/s390/net/fsm.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/s390/net/fsm.h 2003-08-25 04:44:42.000000000 -0700 @@ -1,4 +1,4 @@ -/* $Id: fsm.h,v 1.4 2001/09/24 10:38:02 mschwide Exp $ +/* $Id: fsm.h,v 1.5 2002/08/05 09:07:56 heicarst Exp $ */ #ifndef _FSM_H_ #define _FSM_H_ diff -urN linux-2.4.21/drivers/s390/net/iucv.c linux-2.4.22/drivers/s390/net/iucv.c --- linux-2.4.21/drivers/s390/net/iucv.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/s390/net/iucv.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,5 +1,5 @@ /* - * $Id: iucv.c,v 1.32 2002/02/12 21:52:20 felfert Exp $ + * $Id: iucv.c,v 1.41 2003/06/24 16:05:32 felfert Exp $ * * IUCV network driver * @@ -29,7 +29,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.32 $ + * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.41 $ * */ @@ -89,6 +89,8 @@ static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED; +static int messagesDisabled = 0; + /***************INTERRUPT HANDLING ***************/ typedef struct { @@ -302,7 +304,7 @@ if (debuglevel < 3) return; - printk(KERN_DEBUG __FUNCTION__ ": %s\n", title); + printk(KERN_DEBUG "%s: %s\n", __FUNCTION__, title); printk(" "); for (i = 0; i < len; i++) { if (!(i % 16) && i != 0) @@ -318,7 +320,7 @@ #define iucv_debug(lvl, fmt, args...) \ do { \ if (debuglevel >= lvl) \ - printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n" , ## args); \ + printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n", ## args); \ } while (0) #else @@ -338,7 +340,7 @@ static void iucv_banner(void) { - char vbuf[] = "$Revision: 1.32 $"; + char vbuf[] = "$Revision: 1.41 $"; char *version = vbuf; if ((version = strchr(version, ':'))) { @@ -384,6 +386,14 @@ return -ENOMEM; } memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE); +#if 0 + /* Show parameter pool on startup */ + { + int i; + for (i = 0; i < PARAM_POOL_SIZE; i++) + printk("iparm[%d] at %p\n", i, &iucv_param_pool[i]); + } +#endif /* Initialize task queue */ INIT_LIST_HEAD(&iucv_tq.list); @@ -429,7 +439,7 @@ grab_param(void) { iucv_param *ret; - static int i = 0; + int i = 0; while (atomic_compare_and_swap(0, 1, &iucv_param_pool[i].in_use)) { i++; @@ -1047,6 +1057,7 @@ iucv_handle_t handle, void *pgm_data) { iparml_control *parm; + iparml_control local_parm; struct list_head *lh; ulong b2f0_result = 0; ulong flags; @@ -1103,24 +1114,50 @@ EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget)); } + /* In order to establish an IUCV connection, the procedure is: + * + * b2f0(CONNECT) + * take the ippathid from the b2f0 call + * register the handler to the ippathid + * + * Unfortunately, the ConnectionEstablished message gets sent after the + * b2f0(CONNECT) call but before the register is handled. + * + * In order for this race condition to be eliminated, the IUCV Control + * Interrupts must be disabled for the above procedure. + * + * David Kennedy + */ + + /* Enable everything but IUCV Control messages */ + iucv_setmask(~(AllInterrupts)); + messagesDisabled = 1; + parm->ipflags1 = (__u8)flags1; b2f0_result = b2f0(CONNECT, parm); + memcpy(&local_parm, parm, sizeof(local_parm)); + release_param(parm); + parm = &local_parm; if (b2f0_result) { - release_param(parm); + iucv_setmask(~0); + messagesDisabled = 0; return b2f0_result; } add_pathid_result = iucv_add_pathid(parm->ippathid, h); *pathid = parm->ippathid; + /* Enable everything again */ + iucv_setmask(IUCVControlInterruptsFlag); + if (msglim) *msglim = parm->ipmsglim; if (flags1_out) *flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0; if (add_pathid_result) { - iucv_sever(parm->ippathid, no_memory); + iucv_sever(*pathid, no_memory); printk(KERN_WARNING "%s: add_pathid failed with rc =" " %d\n", __FUNCTION__, add_pathid_result); return(add_pathid_result); @@ -1736,6 +1773,7 @@ { iparml_db *parm; ulong b2f0_result; + iucv_param save_param; iucv_debug(2, "entering"); @@ -1752,7 +1790,13 @@ parm->ipmsgtag = msgtag; parm->ipflags1 = (IPNORPY | flags1); /* one way priority message */ + memcpy((void *)&save_param, (void *)parm, sizeof(iucv_param)); b2f0_result = b2f0(SEND, parm); + if (b2f0_result != 0) { + printk("b2f0 call returned %lx\n", b2f0_result); + iucv_dumpit("PL before:", &save_param, sizeof(iucv_param)); + iucv_dumpit("PL after:", parm, sizeof(iucv_param)); + } if ((b2f0_result == 0) && (msgid)) *msgid = parm->ipmsgid; @@ -2103,6 +2147,24 @@ return b2f0_result; } +void +iucv_setmask_cpu0 (void *result) +{ + iparml_set_mask *parm; + + if (smp_processor_id() != 0) + return; + + iucv_debug(1, "entering"); + parm = (iparml_set_mask *)grab_param(); + parm->ipmask = *((__u8*)result); + *((ulong *)result) = b2f0(SETMASK, parm); + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", *((ulong *)result)); + iucv_debug(1, "exiting"); +} + /* * Name: iucv_setmask * Purpose: This function enables or disables the following IUCV @@ -2113,28 +2175,25 @@ * 0x40 - Priority_MessagePendingInterruptsFlag * 0x20 - Nonpriority_MessageCompletionInterruptsFlag * 0x10 - Priority_MessageCompletionInterruptsFlag + * 0x08 - IUCVControlInterruptsFlag * Output: NA * Return: b2f0_result - return code from CP */ int iucv_setmask (int SetMaskFlag) { - iparml_set_mask *parm; - ulong b2f0_result = 0; - - iucv_debug(1, "entering"); - - parm = (iparml_set_mask *)grab_param(); - - parm->ipmask = (__u8)SetMaskFlag; - - b2f0_result = b2f0(SETMASK, parm); - release_param(parm); + union { + ulong result; + __u8 param; + } u; - iucv_debug(1, "b2f0_result = %ld", b2f0_result); - iucv_debug(1, "exiting"); + u.param = SetMaskFlag; + if (smp_processor_id() == 0) + iucv_setmask_cpu0(&u); + else + smp_call_function(iucv_setmask_cpu0, &u, 0, 1); - return b2f0_result; + return u.result; } /** @@ -2250,6 +2309,10 @@ /* end of if statement */ switch (int_buf->iptype) { case 0x01: /* connection pending */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } spin_lock_irqsave(&iucv_lock, flags); list_for_each(lh, &iucv_handler_table) { h = list_entry(lh, handler, list); @@ -2298,11 +2361,17 @@ break; case 0x02: /*connection complete */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } if (h) { if (interrupt->ConnectionComplete) + { interrupt->ConnectionComplete( (iucv_ConnectionComplete *)int_buf, h->pgm_data); + } else iucv_debug(1, "ConnectionComplete not called"); @@ -2311,6 +2380,10 @@ break; case 0x03: /* connection severed */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } if (h) { if (interrupt->ConnectionSevered) interrupt->ConnectionSevered( @@ -2324,6 +2397,10 @@ break; case 0x04: /* connection quiesced */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } if (h) { if (interrupt->ConnectionQuiesced) interrupt->ConnectionQuiesced( @@ -2336,6 +2413,10 @@ break; case 0x05: /* connection resumed */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } if (h) { if (interrupt->ConnectionResumed) interrupt->ConnectionResumed( diff -urN linux-2.4.21/drivers/s390/net/iucv.h linux-2.4.22/drivers/s390/net/iucv.h --- linux-2.4.21/drivers/s390/net/iucv.h 2001-09-30 12:26:07.000000000 -0700 +++ linux-2.4.22/drivers/s390/net/iucv.h 2003-08-25 04:44:42.000000000 -0700 @@ -62,6 +62,9 @@ #define Priority_MessagePendingInterruptsFlag 0x40 #define Nonpriority_MessageCompletionInterruptsFlag 0x20 #define Priority_MessageCompletionInterruptsFlag 0x10 +#define IUCVControlInterruptsFlag 0x08 +#define AllInterrupts 0xf8 + /* * Mapping of external interrupt buffers should be used with the corresponding * interrupt types. @@ -446,7 +449,7 @@ * buflen - Length of reply buffer. * Output: residual_buffer - Address of buffer updated by the number * of bytes you have moved. - * residual_length - Contains on the the following values + * residual_length - Contains one of the following values: * If the answer buffer is the same length as the reply, this field * contains zero. * If the answer buffer is longer than the reply, this field contains @@ -480,7 +483,7 @@ * buffer - Address of array of reply buffers. * buflen - Total length of reply buffers. * Output: residual_buffer - Address of buffer which IUCV is currently working on. - * residual_length - Contains on the the following values + * residual_length - Contains one of the following values: * If the answer buffer is the same length as the reply, this field * contains zero. * If the answer buffer is longer than the reply, this field contains @@ -735,6 +738,7 @@ * 0x40 - Priority_MessagePendingInterruptsFlag * 0x20 - Nonpriority_MessageCompletionInterruptsFlag * 0x10 - Priority_MessageCompletionInterruptsFlag + * 0x08 - IUCVControlInterruptsFlag * Output: NA * Return: Return code from CP IUCV call. */ diff -urN linux-2.4.21/drivers/s390/net/netiucv.c linux-2.4.22/drivers/s390/net/netiucv.c --- linux-2.4.21/drivers/s390/net/netiucv.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/s390/net/netiucv.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,5 +1,5 @@ /* - * $Id: netiucv.c,v 1.17 2002/02/12 21:52:20 felfert Exp $ + * $Id: netiucv.c,v 1.23 2003/06/24 16:05:32 felfert Exp $ * * IUCV network driver * @@ -28,7 +28,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: IUCV network driver $Revision: 1.17 $ + * RELEASE-TAG: IUCV network driver $Revision: 1.23 $ * */ @@ -96,6 +96,8 @@ unsigned long txlen; unsigned long tx_time; struct timeval send_stamp; + unsigned long tx_pending; + unsigned long tx_max_pending; } connection_profile; /** @@ -108,6 +110,7 @@ struct sk_buff *rx_buff; struct sk_buff *tx_buff; struct sk_buff_head collect_queue; + struct sk_buff_head commit_queue; spinlock_t collect_lock; int collect_len; int max_buffsize; @@ -443,6 +446,10 @@ iucv_connection *conn = (iucv_connection *)pgm_data; iucv_event ev; +#ifdef DEBUG + printk(KERN_DEBUG "%s() called\n", __FUNCTION__); +#endif + ev.conn = conn; ev.data = (void *)eib; fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev); @@ -619,10 +626,11 @@ iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data; netiucv_priv *privptr = NULL; /* Shut up, gcc! skb is always below 2G. */ - struct sk_buff *skb = (struct sk_buff *)(unsigned long)eib->ipmsgtag; + __u32 single_flag = eib->ipmsgtag; __u32 txbytes = 0; __u32 txpackets = 0; __u32 stat_maxcq = 0; + struct sk_buff *skb; unsigned long saveflags; ll_header header; @@ -632,13 +640,17 @@ fsm_deltimer(&conn->timer); if (conn && conn->netdev && conn->netdev->priv) privptr = (netiucv_priv *)conn->netdev->priv; - if (skb) { + conn->prof.tx_pending--; + if (single_flag) { + if ((skb = skb_dequeue(&conn->commit_queue))) { + atomic_dec(&skb->users); + dev_kfree_skb_any(skb); + } if (privptr) { privptr->stats.tx_packets++; privptr->stats.tx_bytes += (skb->len - NETIUCV_HDRLEN - NETIUCV_HDRLEN); } - dev_kfree_skb_any(skb); } conn->tx_buff->data = conn->tx_buff->tail = conn->tx_buff->head; conn->tx_buff->len = 0; @@ -672,11 +684,17 @@ conn->tx_buff->data, conn->tx_buff->len); conn->prof.doios_multi++; conn->prof.txlen += conn->tx_buff->len; + conn->prof.tx_pending++; + if (conn->prof.tx_pending > conn->prof.tx_max_pending) + conn->prof.tx_max_pending = conn->prof.tx_pending; if (rc != 0) { fsm_deltimer(&conn->timer); + conn->prof.tx_pending--; fsm_newstate(fi, CONN_STATE_IDLE); if (privptr) privptr->stats.tx_errors += txpackets; + printk(KERN_DEBUG "iucv_send returned %08x\n", + rc); } else { if (privptr) { privptr->stats.tx_packets += txpackets; @@ -764,6 +782,13 @@ printk(KERN_DEBUG "%s() called\n", __FUNCTION__); #endif switch (state) { + case CONN_STATE_SETUPWAIT: + printk(KERN_INFO "%s: Remote dropped connection\n", + netdev->name); + conn->handle = 0; + fsm_newstate(fi, CONN_STATE_STOPPED); + fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); + break; case CONN_STATE_IDLE: case CONN_STATE_TX: printk(KERN_INFO "%s: Remote dropped connection\n", @@ -807,10 +832,15 @@ printk(KERN_DEBUG "%s('%s'): connecting ...\n", conn->netdev->name, conn->userid); #endif + + /* We must set the state before calling iucv_connect because the callback + * handler could be called at any point after the connection request is + * sent. */ + + fsm_newstate(fi, CONN_STATE_SETUPWAIT); rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic, conn->userid, iucv_host, 0, NULL, NULL, conn->handle, conn); - fsm_newstate(fi, CONN_STATE_SETUPWAIT); switch (rc) { case 0: return; @@ -885,6 +915,7 @@ if (conn->handle) iucv_unregister_program(conn->handle); conn->handle = 0; + netiucv_purge_skb_queue(&conn->commit_queue); fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); } @@ -928,6 +959,7 @@ { CONN_STATE_TX, CONN_EVENT_RX, conn_action_rx }, { CONN_STATE_TX, CONN_EVENT_TXDONE, conn_action_txdone }, + { CONN_STATE_IDLE, CONN_EVENT_TXDONE, conn_action_txdone }, }; static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); @@ -1130,14 +1162,21 @@ CONN_EVENT_TIMER, conn); conn->prof.send_stamp = xtime; - rc = iucv_send(conn->pathid, NULL, 0, 0, - /* Shut up, gcc! nskb is always below 2G. */ - (__u32)(((unsigned long)nskb)&0xffffffff), 0, - nskb->data, nskb->len); + rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */, + 0, nskb->data, nskb->len); conn->prof.doios_single++; conn->prof.txlen += skb->len; + conn->prof.tx_pending++; + if (conn->prof.tx_pending > conn->prof.tx_max_pending) + conn->prof.tx_max_pending = conn->prof.tx_pending; if (rc != 0) { + netiucv_priv *privptr; fsm_deltimer(&conn->timer); + fsm_newstate(conn->fsm, CONN_STATE_IDLE); + conn->prof.tx_pending--; + privptr = (netiucv_priv *)conn->netdev->priv; + if (privptr) + privptr->stats.tx_errors++; if (copied) dev_kfree_skb(nskb); else { @@ -1148,9 +1187,13 @@ skb_pull(skb, NETIUCV_HDRLEN); skb_trim(skb, skb->len - NETIUCV_HDRLEN); } + printk(KERN_DEBUG "iucv_send returned %08x\n", + rc); } else { if (copied) dev_kfree_skb(skb); + atomic_inc(&nskb->users); + skb_queue_tail(&conn->commit_queue, nskb); } } @@ -1549,12 +1592,7 @@ if (!(dev = find_netdev_by_ino(ino))) return -ENODEV; privptr = (netiucv_priv *)dev->priv; - privptr->conn->prof.maxmulti = 0; - privptr->conn->prof.maxcqueue = 0; - privptr->conn->prof.doios_single = 0; - privptr->conn->prof.doios_multi = 0; - privptr->conn->prof.txlen = 0; - privptr->conn->prof.tx_time = 0; + memset(&(privptr->conn->prof), 0, sizeof(privptr->conn->prof)); return count; } @@ -1593,6 +1631,10 @@ privptr->conn->prof.txlen); p += sprintf(p, "Max. TX IO-time: %ld\n", privptr->conn->prof.tx_time); + p += sprintf(p, "Pending transmits: %ld\n", + privptr->conn->prof.tx_pending); + p += sprintf(p, "Max. pending transmits: %ld\n", + privptr->conn->prof.tx_max_pending); } l = strlen(sbuf); p = sbuf; @@ -1725,8 +1767,10 @@ * If not registered, register main proc dir-entry now */ #if LINUX_VERSION_CODE > 0x020362 +#ifdef CONFIG_PROC_FS if (!netiucv_dir) netiucv_dir = proc_mkdir("iucv", proc_net); +#endif #else if (netiucv_dir.low_ino == 0) proc_net_register(&netiucv_dir); @@ -1741,7 +1785,9 @@ netiucv_proc_destroy_main(void) { #if LINUX_VERSION_CODE > 0x020362 +#ifdef CONFIG_PROC_FS remove_proc_entry("iucv", proc_net); +#endif #else proc_net_unregister(netiucv_dir.low_ino); #endif @@ -1833,6 +1879,7 @@ if (conn) { memset(conn, 0, sizeof(iucv_connection)); skb_queue_head_init(&conn->collect_queue); + skb_queue_head_init(&conn->commit_queue); conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; conn->netdev = dev; @@ -2005,7 +2052,7 @@ static void netiucv_banner(void) { - char vbuf[] = "$Revision: 1.17 $"; + char vbuf[] = "$Revision: 1.23 $"; char *version = vbuf; if ((version = strchr(version, ':'))) { @@ -2066,7 +2113,7 @@ netiucv_proc_create_main(); while (p) { - if (isalnum(*p)) { + if (isalnum(*p) || (*p == '$')) { username[i++] = *p++; username[i] = '\0'; if (i > 8) { diff -urN linux-2.4.21/drivers/s390/net/qeth.c linux-2.4.22/drivers/s390/net/qeth.c --- linux-2.4.21/drivers/s390/net/qeth.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/s390/net/qeth.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,10946 @@ +/* + * + * linux/drivers/s390/net/qeth.c ($Revision: 1.337 $) + * + * Linux on zSeries OSA Express and HiperSockets support + * + * Copyright 2000,2003 IBM Corporation + * + * Author(s): Utz Bacher + * Cornelia Huck (chandev stuff, + * numerous bugfixes) + * Frank Pavlic (query/purge ARP, SNMP, fixes) + * Andreas Herrmann (bugfixes) + * + * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * The driver supports in general all QDIO driven network devices on the + * Hydra card. + * + * For all devices, three channels must be available to the driver. One + * channel is the read channel, one is the write channel and the third + * one is the channel used to control QDIO. + * + * There are several stages from the channel recognition to the running + * network device: + * - The channels are scanned and ordered due to the parameters (see + * MODULE_PARM_DESC) + * - The card is hardsetup: this means, that the communication channels + * are prepared + * - The card is softsetup: this means, that commands are issued + * to activate the network parameters + * - After that, data can flow through the card (transported by QDIO) + * + *IPA Takeover: + * /proc/qeth_ipa_takeover provides the possibility to add and remove + * certain ranges of IP addresses to the driver. As soon as these + * addresses have to be set by the driver, the driver uses the OSA + * Address Takeover mechanism. + * reading out of the proc-file displays the registered addresses; + * writing into it changes the information. Only one command at one + * time must be written into the file. Subsequent commands are ignored. + * The following commands are available: + * inv4 + * inv6 + * add4 /[:] + * add6 /[:] + * del4 /[:] + * del6 /[:] + * inv4 and inv6 toggle the IPA takeover behaviour for all interfaces: + * when inv4 was input once, all addresses specified with add4 are not + * set using the takeover mechanism, but all other IPv4 addresses are set so. + * + * add# adds an address range, del# deletes an address range. # corresponds + * to the IP version (4 or 6). + * is a 8 or 32byte hexadecimal view of the IP address. + * specifies the number of bits which are set in the network mask. + * is optional and specifies the interface name to which the + * address range is bound. + * E. g. + * add4 C0a80100/24 + * activates all addresses in the 192.168.10 subnet for address takeover. + * Note, that the address is not taken over before an according ifconfig + * is executed. + * + *VIPA: + * add_vipa4 : + * add_vipa6 : + * del_vipa4 : + * del_vipa6 : + * + * the specified address is set/unset as VIPA on the specified interface. + * use the src_vipa package to exploit this out of arbitrary applications. + * + *Proxy ARP: + * + * add_rxip4 : + * add_rxip6 : + * del_rxip4 : + * del_rxip6 : + * + * the specified address is set/unset as "do not fail a gratuitous ARP" + * on the specified interface. this can be used to act as a proxy ARP. + */ + +void volatile qeth_eyecatcher(void) +{ + return; +} + +#include + +#ifndef CONFIG_CHANDEV +#error "qeth can only be compiled with chandev support" +#endif /* CONFIG_CHANDEV */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PROC_FS +#include +#endif /* CONFIG_PROC_FS */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include "qeth_mpc.h" +#include "qeth.h" + +/****************** MODULE PARAMETER VARIABLES ********************/ +static int qeth_sparebufs=0; +MODULE_PARM(qeth_sparebufs,"i"); +MODULE_PARM_DESC(qeth_sparebufs,"the number of pre-allocated spare buffers " \ + "reserved for low memory situations"); + +static int global_stay_in_mem=0; + +/****************** MODULE STUFF **********************************/ +#define VERSION_QETH_C "$Revision: 1.337 $" +static const char *version="qeth S/390 OSA-Express driver (" \ + VERSION_QETH_C "/" VERSION_QETH_H "/" VERSION_QETH_MPC_H + QETH_VERSION_IPV6 QETH_VERSION_VLAN ")"; + +MODULE_AUTHOR("Utz Bacher "); +MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \ + "Copyright 2000,2003 IBM Corporation\n"); +MODULE_LICENSE("GPL"); + +/******************** HERE WE GO ***********************************/ + +#define PROCFILE_SLEEP_SEM_MAX_VALUE 0 +#define PROCFILE_IOCTL_SEM_MAX_VALUE 3 +static struct semaphore qeth_procfile_ioctl_lock; +static struct semaphore qeth_procfile_ioctl_sem; +static qeth_card_t *firstcard=NULL; + +static sparebufs_t sparebufs[MAX_SPARE_BUFFERS]; +static int sparebuffer_count; + +static unsigned int known_devices[][10]=QETH_MODELLIST_ARRAY; + +static spinlock_t setup_lock; +static rwlock_t list_lock=RW_LOCK_UNLOCKED; + +static debug_info_t *qeth_dbf_setup=NULL; +static debug_info_t *qeth_dbf_data=NULL; +static debug_info_t *qeth_dbf_misc=NULL; +static debug_info_t *qeth_dbf_control=NULL; +static debug_info_t *qeth_dbf_trace=NULL; +static debug_info_t *qeth_dbf_sense=NULL; +static debug_info_t *qeth_dbf_qerr=NULL; + +static int proc_file_registration; +#ifdef QETH_PERFORMANCE_STATS +static int proc_perf_file_registration; +#define NOW qeth_get_micros() +#endif /* QETH_PERFORMANCE_STATS */ +static int proc_ipato_file_registration; + +static int ipato_inv4=0,ipato_inv6=0; +static ipato_entry_t *ipato_entries=NULL; +static spinlock_t ipato_list_lock; + +typedef struct { + char *data; + int len; +} tempinfo_t; + +/* thought I could get along without forward declarations... + * just lazyness here */ +static int qeth_reinit_thread(void*); +static void qeth_schedule_recovery(qeth_card_t *card); + +inline static int QETH_IP_VERSION(struct sk_buff *skb) +{ + switch (skb->protocol) { + case ETH_P_IPV6: return 6; + case ETH_P_IP: return 4; + default: return 0; + } +} +/* not a macro, as one of the arguments is atomic_read */ +static inline int qeth_min(int a,int b) +{ + if (a>22); /* time>>12 is microseconds, we divide it + by 1024 */ +} + +#ifdef QETH_PERFORMANCE_STATS +static inline unsigned int qeth_get_micros(void) +{ + __u64 time; + + asm volatile ("STCK %0" : "=m" (time)); + return (int) (time>>12); +} +#endif /* QETH_PERFORMANCE_STATS */ + +static void qeth_delay_millis(unsigned long msecs) +{ + unsigned int start; + + start=qeth_get_millis(); + while (qeth_get_millis()-starttimeout) { + goto out; + } + schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ); + } + out: + set_task_state(current,TASK_RUNNING); +} + +static void qeth_get_mac_for_ipm(__u32 ipm,char *mac,struct net_device *dev) { + if (dev->type==ARPHRD_IEEE802_TR) + ip_tr_mc_map(ipm,mac); + else + ip_eth_mc_map(ipm,mac); +} + +#define HEXDUMP16(importance,header,ptr) \ +PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ + *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \ + *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \ + *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \ + *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \ + *(((char*)ptr)+12),*(((char*)ptr)+13), \ + *(((char*)ptr)+14),*(((char*)ptr)+15)); \ +PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ + *(((char*)ptr)+16),*(((char*)ptr)+17), \ + *(((char*)ptr)+18),*(((char*)ptr)+19), \ + *(((char*)ptr)+20),*(((char*)ptr)+21), \ + *(((char*)ptr)+22),*(((char*)ptr)+23), \ + *(((char*)ptr)+24),*(((char*)ptr)+25), \ + *(((char*)ptr)+26),*(((char*)ptr)+27), \ + *(((char*)ptr)+28),*(((char*)ptr)+29), \ + *(((char*)ptr)+30),*(((char*)ptr)+31)); + +#define atomic_swap(a,b) xchg((int*)a.counter,b) + +#ifdef QETH_DBF_LIKE_HELL + +#define my_read_lock(x) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"rd_lck"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + read_lock(x); \ +} while (0) +#define my_read_unlock(x) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"rd_unlck"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + read_unlock(x); \ +} while (0) +#define my_write_lock(x) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"wr_lck"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + write_lock(x); \ +} while (0) +#define my_write_unlock(x) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"wr_unlck"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + write_unlock(x); \ +} while (0) + +#define my_spin_lock(x) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"sp_lck"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + spin_lock(x); \ +} while (0) +#define my_spin_unlock(x) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"sp_unlck"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + spin_unlock(x); \ +} while (0) +#define my_spin_lock_irqsave(x,y) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"sp_lck_i"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + spin_lock_irqsave(x,y); \ +} while (0) +#define my_spin_unlock_irqrestore(x,y) do { \ + void *ptr=x; \ + QETH_DBF_TEXT6(0,trace,"sp_nlk_i"); \ + QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \ + spin_unlock_irqrestore(x,y); \ +} while (0) + +#else /* QETH_DBF_LIKE_HELL */ + +#define my_read_lock(x) read_lock(x) +#define my_write_lock(x) write_lock(x) +#define my_read_unlock(x) read_unlock(x) +#define my_write_unlock(x) write_unlock(x) + +#define my_spin_lock(x) spin_lock(x) +#define my_spin_unlock(x) spin_unlock(x) +#define my_spin_lock_irqsave(x,y) spin_lock_irqsave(x,y) +#define my_spin_unlock_irqrestore(x,y) spin_unlock_irqrestore(x,y) + +#endif /* QETH_DBF_LIKE_HELL */ + +static int inline my_spin_lock_nonbusy(qeth_card_t *card,spinlock_t *lock) +{ + for (;;) { + if (card) { + if (atomic_read(&card->shutdown_phase)) return -1; + } + if (spin_trylock(lock)) return 0; + qeth_wait_nonbusy(QETH_IDLE_WAIT_TIME); + } +} + +#ifdef CONFIG_ARCH_S390X +#define QETH_GET_ADDR(x) ((__u32)(unsigned long)x) +#else /* CONFIG_ARCH_S390X */ +#define QETH_GET_ADDR(x) ((__u32)x) +#endif /* CONFIG_ARCH_S390X */ + +static int qeth_does_card_exist(qeth_card_t *card) +{ + qeth_card_t *c=firstcard; + int rc=0; + + my_read_lock(&list_lock); + while (c) { + if (c==card) { + rc=1; + break; + } + c=c->next; + } + my_read_unlock(&list_lock); + return rc; +} + +static inline qeth_card_t *qeth_get_card_by_irq(int irq) +{ + qeth_card_t *card; + + my_read_lock(&list_lock); + card=firstcard; + while (card) { + if ((card->irq0==irq)&& + (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK)) break; + if ((card->irq1==irq)&& + (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK)) break; + if ((card->irq2==irq)&& + (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK)) break; + card=card->next; + } + my_read_unlock(&list_lock); + + return card; +} + +static int qeth_getxdigit(char c) +{ + if ((c>='0') && (c<='9')) return c-'0'; + if ((c>='a') && (c<='f')) return c+10-'a'; + if ((c>='A') && (c<='F')) return c+10-'A'; + return -1; +} + +static qeth_card_t *qeth_get_card_by_name(char *name) +{ + qeth_card_t *card; + + my_read_lock(&list_lock); + card=firstcard; + while (card) { + if (!strncmp(name,card->dev_name,DEV_NAME_LEN)) break; + card=card->next; + } + my_read_unlock(&list_lock); + + return card; +} + +static void qeth_convert_addr_to_text(int version,__u8 *addr,char *text) +{ + if (version==4) { + sprintf(text,"%02x%02x%02x%02x", + addr[0],addr[1],addr[2],addr[3]); + } else { + sprintf(text,"%02x%02x%02x%02x%02x%02x%02x%02x" \ + "%02x%02x%02x%02x%02x%02x%02x%02x", + addr[0],addr[1],addr[2],addr[3], + addr[4],addr[5],addr[6],addr[7], + addr[8],addr[9],addr[10],addr[11], + addr[12],addr[13],addr[14],addr[15]); + } +} + +static int qeth_convert_text_to_addr(int version,char *text,__u8 *addr) +{ + int olen=(version==4)?4:16; + + while (olen--) { + if ( (!isxdigit(*text)) || (!isxdigit(*(text+1))) ) + return -EINVAL; + *addr=(qeth_getxdigit(*text)<<4)+qeth_getxdigit(*(text+1)); + addr++; + text+=2; + } + return 0; +} + +static void qeth_add_ipato_entry(int version,__u8 *addr,int mask_bits, + char *dev_name) +{ + ipato_entry_t *entry,*e; + int len=(version==4)?4:16; + + entry=(ipato_entry_t*)kmalloc(sizeof(ipato_entry_t),GFP_KERNEL); + if (!entry) { + PRINT_ERR("not enough memory for ipato allocation\n"); + return; + } + entry->version=version; + memcpy(entry->addr,addr,len); + if (dev_name) { + strncpy(entry->dev_name,dev_name,DEV_NAME_LEN); + if (qeth_get_card_by_name(dev_name)->options.ena_ipat!= + ENABLE_TAKEOVER) + PRINT_WARN("IP takeover is not enabled on %s! " \ + "Ignoring line\n",dev_name); + } else + memset(entry->dev_name,0,DEV_NAME_LEN); + entry->mask_bits=mask_bits; + entry->next=NULL; + + my_spin_lock(&ipato_list_lock); + if (ipato_entries) { + e=ipato_entries; + while (e) { + if ( (e->version==version) && + (e->mask_bits==mask_bits) && + ( ((dev_name)&&!strncmp(e->dev_name,dev_name, + DEV_NAME_LEN)) || + (!dev_name) ) && + (!memcmp(e->addr,addr,len)) ) { + PRINT_INFO("ipato to be added does already " \ + "exist\n"); + kfree(entry); + goto out; + } + if (e->next) e=e->next; else break; + } + e->next=entry; + } else + ipato_entries=entry; +out: + my_spin_unlock(&ipato_list_lock); +} + +static void qeth_del_ipato_entry(int version,__u8 *addr,int mask_bits, + char *dev_name) +{ + ipato_entry_t *e,*e_before; + int len=(version==4)?4:16; + int found=0; + + my_spin_lock(&ipato_list_lock); + e=ipato_entries; + if ( (e->version==version) && + (e->mask_bits==mask_bits) && + (!memcmp(e->addr,addr,len)) ) { + ipato_entries=e->next; + kfree(e); + } else while (e) { + e_before=e; + e=e->next; + if (!e) break; + if ( (e->version==version) && + (e->mask_bits==mask_bits) && + ( ((dev_name)&&!strncmp(e->dev_name,dev_name, + DEV_NAME_LEN)) || + (!dev_name) ) && + (!memcmp(e->addr,addr,len)) ) { + e_before->next=e->next; + kfree(e); + found=1; + break; + } + } + if (!found) + PRINT_INFO("ipato to be deleted does not exist\n"); + my_spin_unlock(&ipato_list_lock); +} + +static void qeth_convert_addr_to_bits(__u8 *addr,char *bits,int len) +{ + int i,j; + __u8 octet; + + for (i=0;i=0;j--) { + bits[i*8+j]=(octet&1)?1:0; + octet>>=1; + } + } +} + +static int qeth_is_ipa_covered_by_ipato_entries(int version,__u8 *addr, + qeth_card_t *card) +{ + char *memarea,*addr_bits,*entry_bits; + int len=(version==4)?4:16; + int invert=(version==4)?ipato_inv4:ipato_inv6; + int result=0; + ipato_entry_t *e; + + if (card->options.ena_ipat!=ENABLE_TAKEOVER) { + return 0; + } + + memarea=kmalloc(256,GFP_KERNEL); + if (!memarea) { + PRINT_ERR("not enough memory to check out whether to " \ + "use ipato\n"); + return 0; + } + addr_bits=memarea; + entry_bits=memarea+128; + qeth_convert_addr_to_bits(addr,addr_bits,len); + e=ipato_entries; + while (e) { + qeth_convert_addr_to_bits(e->addr,entry_bits,len); + if ( (!memcmp(addr_bits,entry_bits, + __min(len*8,e->mask_bits))) && + ( (e->dev_name[0]&& + (!strncmp(e->dev_name,card->dev_name,DEV_NAME_LEN))) || + (!e->dev_name[0]) ) ) { + result=1; + break; + } + e=e->next; + } + + kfree(memarea); + if (invert) + return !result; + else + return result; +} + +static void qeth_set_dev_flag_running(qeth_card_t *card) +{ + if (card) { + card->dev->flags|=IFF_RUNNING; +/* + clear_bit(__LINK_STATE_DOWN,&dev->flags); +*/ + } +} + +static void qeth_set_dev_flag_norunning(qeth_card_t *card) +{ + if (card) { + card->dev->flags&=~IFF_RUNNING; +/* + set_bit(__LINK_STATE_DOWN,&dev->flags); +*/ + } +} + +static void qeth_restore_dev_flag_state(qeth_card_t *card) +{ + if (card) { + if (card->saved_dev_flags&IFF_RUNNING) + card->dev->flags|=IFF_RUNNING; + else + card->dev->flags&=~IFF_RUNNING; +/* + if (card->saved_dev_flags&__LINK_STATE_DOWN) + set_bit(__LINK_STATE_DOWN,&card->dev->flags); + else + clear_bit(__LINK_STATE_DOWN,&card->dev->flags); +*/ + } +} + +static void qeth_save_dev_flag_state(qeth_card_t *card) +{ + if (card) { + card->saved_dev_flags=card->dev->flags&IFF_RUNNING; +/* + card->saved_dev_flags=card->dev->flags&__LINK_STATE_DOWN; +*/ + } +} + +static inline int netif_is_busy(struct net_device *dev) +{ + return(test_bit(__LINK_STATE_XOFF,&dev->flags)); +} + +static int qeth_open(struct net_device *dev) +{ + char dbf_text[15]; + qeth_card_t *card; + + card=(qeth_card_t *)dev->priv; + sprintf(dbf_text,"open%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_TEXT2(0,setup,dbf_text); + + qeth_save_dev_flag_state(card); + + netif_start_queue(dev); + if (!atomic_swap(&((qeth_card_t*)dev->priv)->is_open,1)) { + MOD_INC_USE_COUNT; + } + return 0; +} + +static int qeth_set_config(struct net_device *dev,struct ifmap *map) +{ + qeth_card_t *card=(qeth_card_t*)dev->priv; + char dbf_text[15]; + + sprintf(dbf_text,"nscf%04x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return -EOPNOTSUPP; +} + +static int qeth_is_multicast_skb_at_all(struct sk_buff *skb,int version) +{ + int i; + if (skb->dst && skb->dst->neighbour) { + i=skb->dst->neighbour->type; + return ((i==RTN_BROADCAST)|| + (i==RTN_MULTICAST)|| + (i==RTN_ANYCAST))?i:0; + } + /* ok, we've to try it somehow else */ + if (version==4) { + return ((skb->nh.raw[16]&0xf0)==0xe0)?RTN_MULTICAST:0; + } else if (version==6) { + return (skb->nh.raw[24]==0xff)?RTN_MULTICAST:0; + } + return 0; +} + +static int qeth_get_prioqueue(qeth_card_t *card,struct sk_buff *skb, + int multicast,int version) +{ + if (!version) return QETH_DEFAULT_QUEUE; + switch (card->no_queues) { + case 1: + return 0; + case 4: + if ( (card->can_do_async_iqd) && + (card->options.async_iqd==ASYNC_IQD) ) { + return card->no_queues-1; + } + if (card->is_multicast_different) { + if (multicast) { + return card->is_multicast_different& + (card->no_queues-1); + } else { + return 0; + } + } + if (card->options.do_prio_queueing) { + if (version==4) { + if (card->options.do_prio_queueing== + PRIO_QUEUEING_TOS) { + if (skb->nh.iph->tos& + IP_TOS_NOTIMPORTANT) { + return 3; + } + if (skb->nh.iph->tos& + IP_TOS_LOWDELAY) { + return 0; + } + if (skb->nh.iph->tos& + IP_TOS_HIGHTHROUGHPUT) { + return 1; + } + if (skb->nh.iph->tos& + IP_TOS_HIGHRELIABILITY) { + return 2; + } + return QETH_DEFAULT_QUEUE; + } + if (card->options.do_prio_queueing== + PRIO_QUEUEING_PREC) { + return 3-(skb->nh.iph->tos>>6); + } + } else if (version==6) { +/******************** + ******************** +TODO: IPv6!!! +********************/ + } + return card->options.default_queue; + } else return card->options.default_queue; + default: + return 0; + } +} + +static void qeth_wakeup(qeth_card_t *card) { + char dbf_text[15]; + + sprintf(dbf_text,"wkup%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + + atomic_set(&card->data_has_arrived,1); + spin_lock(&card->wait_q_lock); + if (atomic_read(&card->wait_q_active)) { + wake_up(&card->wait_q); + } + spin_unlock(&card->wait_q_lock); +} + +static int qeth_check_idx_response(unsigned char *buffer) +{ + if (!buffer) + return 0; + if ((buffer[2]&0xc0)==0xc0) { + return -EIO; + } + return 0; +} + +static int qeth_get_cards_problem(qeth_card_t *card,unsigned char *buffer, + int irq,int dstat,int cstat,int rqparam, + char *irb,char *sense) +{ + char dbf_text[15]; + int problem=0; + + if (atomic_read(&card->shutdown_phase)) return 0; + if (dstat&DEV_STAT_UNIT_CHECK) { + if (irq==card->irq2) { + sprintf(dbf_text,"ACHK%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + problem=PROBLEM_ACTIVATE_CHECK_CONDITION; + goto out; + } + if (sense[SENSE_RESETTING_EVENT_BYTE]& + SENSE_RESETTING_EVENT_FLAG) { + sprintf(dbf_text,"REVN%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + problem=PROBLEM_RESETTING_EVENT_INDICATOR; + goto out; + } + if (sense[SENSE_COMMAND_REJECT_BYTE]& + SENSE_COMMAND_REJECT_FLAG) { + sprintf(dbf_text,"CREJ%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + problem=PROBLEM_COMMAND_REJECT; + goto out; + } + if ( (sense[2]==0xaf)&&(sense[3]==0xfe) ) { + sprintf(dbf_text,"AFFE%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + problem=PROBLEM_AFFE; + goto out; + } + if ( (!sense[0]) && (!sense[1]) && + (!sense[2]) && (!sense[3]) ) { + sprintf(dbf_text,"ZSNS%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + problem=PROBLEM_ZERO_SENSE_DATA; + goto out; + } + sprintf(dbf_text,"GCHK%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + problem=PROBLEM_GENERAL_CHECK; + goto out; + } + if (cstat& (SCHN_STAT_CHN_CTRL_CHK|SCHN_STAT_INTF_CTRL_CHK| + SCHN_STAT_CHN_DATA_CHK|SCHN_STAT_CHAIN_CHECK| + SCHN_STAT_PROT_CHECK|SCHN_STAT_PROG_CHECK) ) { + sprintf(dbf_text,"GCHK%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_HEX1(0,misc,irb,__max(QETH_DBF_MISC_LEN,64)); + PRINT_WARN("check on irq x%x, dstat=x%x, cstat=x%x, " \ + "rqparam=x%x\n",irq,dstat,cstat,rqparam); + HEXDUMP16(WARN,"irb: ",irb); + HEXDUMP16(WARN,"irb: ",((char*)irb)+32); + problem=PROBLEM_GENERAL_CHECK; + goto out; + } + if (qeth_check_idx_response(buffer)) { + PRINT_WARN("received an IDX TERMINATE on irq 0x%X/0x%X " \ + "with cause code 0x%02x%s\n", + card->irq0,card->irq1,buffer[4], + (buffer[4]==0x22)?" -- try another portname":""); + sprintf(dbf_text,"RTRM%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + problem=PROBLEM_RECEIVED_IDX_TERMINATE; + goto out; + } + if (IS_IPA(buffer) && !IS_IPA_REPLY(buffer)) { + if ( *(PDU_ENCAPSULATION(buffer))==IPA_CMD_STOPLAN ) { + atomic_set(&card->is_startlaned,0); + /* we don't do a netif_stop_queue(card->dev); + we better discard all packets -- + the outage could take longer */ + PRINT_WARN("Link failure on %s (CHPID 0x%X) -- " \ + "there is a network problem or someone " \ + "pulled the cable or disabled the port." + "Discarding outgoing packets.\n", + card->dev_name,card->chpid); + sprintf(dbf_text,"CBOT%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + qeth_set_dev_flag_norunning(card); + problem=0; + goto out; + } + /* we checked for buffer!=0 in IS_IPA */ + if ( *(PDU_ENCAPSULATION(buffer))==IPA_CMD_STARTLAN ) { + if (!atomic_read(&card->is_startlaned)) { + atomic_set(&card->is_startlaned,1); + problem=PROBLEM_CARD_HAS_STARTLANED; + } + goto out; + } + if ( *(PDU_ENCAPSULATION(buffer))== + IPA_CMD_REGISTER_LOCAL_ADDR ) { + sprintf(dbf_text,"irla%04x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + if ( *(PDU_ENCAPSULATION(buffer))== + IPA_CMD_UNREGISTER_LOCAL_ADDR ) { + sprintf(dbf_text,"irla%04x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + PRINT_WARN("probably a problem on %s: received data is " \ + "IPA, but not a reply: command=0x%x\n", + card->dev_name,*(PDU_ENCAPSULATION(buffer)+1)); + sprintf(dbf_text,"INRP%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + goto out; + } + /* no probs */ +out: + if (problem) { + sprintf(dbf_text,"gcpr%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%4x",dstat,cstat,problem); + QETH_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"%8x",rqparam); + QETH_DBF_TEXT3(0,trace,dbf_text); + if (buffer) + QETH_DBF_HEX3(0,trace,&buffer,sizeof(void*)); + QETH_DBF_HEX3(0,trace,&irb,sizeof(void*)); + QETH_DBF_HEX3(0,trace,&sense,sizeof(void*)); + } + atomic_set(&card->problem,problem); + return problem; +} + + +static void qeth_issue_next_read(qeth_card_t *card) +{ + int result,result2; + char dbf_text[15]; + + sprintf(dbf_text,"isnr%04x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + + /* set up next read ccw */ + memcpy(&card->dma_stuff->read_ccw,READ_CCW,sizeof(ccw1_t)); + card->dma_stuff->read_ccw.count=QETH_BUFSIZE; + /* recbuf is not yet used by read channel program */ + card->dma_stuff->read_ccw.cda=QETH_GET_ADDR(card->dma_stuff->recbuf); + + /* we don't s390irq_spin_lock_irqsave(card->irq0,flags), as + we are only called in the interrupt handler */ + result=do_IO(card->irq0,&card->dma_stuff->read_ccw, + MPC_SETUP_STATE,0,0); + if (result) { + qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); + result2=do_IO(card->irq0,&card->dma_stuff->read_ccw, + MPC_SETUP_STATE,0,0); + PRINT_WARN("read handler on irq x%x, read: do_IO " \ + "returned %i, next try returns %i\n", + card->irq0,result,result2); + sprintf(dbf_text,"IsNR%04x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%04x%04x",(__s16)result,(__s16)result2); + QETH_DBF_TEXT1(0,trace,dbf_text); + } +} + +static int qeth_is_to_recover(qeth_card_t *card,int problem) +{ + switch (problem) { + case PROBLEM_CARD_HAS_STARTLANED: + return 1; + case PROBLEM_RECEIVED_IDX_TERMINATE: + if (atomic_read(&card->in_recovery)) { + return 1; + } else { + qeth_set_dev_flag_norunning(card); + return 0; + } + case PROBLEM_ACTIVATE_CHECK_CONDITION: + return 1; + case PROBLEM_RESETTING_EVENT_INDICATOR: + return 1; + case PROBLEM_COMMAND_REJECT: + return 0; + case PROBLEM_ZERO_SENSE_DATA: + return 0; + case PROBLEM_GENERAL_CHECK: + return 1; + case PROBLEM_BAD_SIGA_RESULT: + return 1; + case PROBLEM_USER_TRIGGERED_RECOVERY: + return 1; + case PROBLEM_AFFE: + return 1; + case PROBLEM_MACHINE_CHECK: + return 1; + case PROBLEM_TX_TIMEOUT: + return 1; + } + return 0; +} + +static int qeth_wait_for_event(atomic_t *var,unsigned int timeout) +{ + unsigned int start; + int retval; + char dbf_text[15]; + + QETH_DBF_TEXT5(0,trace,"wait4evn"); + sprintf(dbf_text,"%08x",timeout); + QETH_DBF_TEXT5(0,trace,dbf_text); + QETH_DBF_HEX5(0,trace,&var,sizeof(void*)); + + start=qeth_get_millis(); + for (;;) { + set_task_state(current,TASK_INTERRUPTIBLE); + if (atomic_read(var)) { + retval=0; + goto out; + } + if (qeth_get_millis()-start>timeout) { + retval=-ETIME; + goto out; + } + schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ); + } + out: + set_task_state(current,TASK_RUNNING); + + return retval; +} + +static int qeth_get_spare_buf(void) +{ + int i=0; + char dbf_text[15]; + + while (iinbound_buffer_pool_entry_used[entry_no]=BUFFER_UNUSED; +} + +static inline int qeth_get_empty_buffer_pool_entry(qeth_card_t *card) +{ + int i; + int max_buffers=card->options.inbound_buffer_count; + + for (i=0;iinbound_buffer_pool_entry_used[i], + BUFFER_USED)==BUFFER_UNUSED) return i; + } + return -1; +} + +static inline void qeth_clear_input_buffer(qeth_card_t *card,int bufno) +{ + qdio_buffer_t *buffer; + int i; + int elements,el_m_1; + void *ptr; +#ifdef QETH_DBF_LIKE_HELL + char dbf_text[15]; + + sprintf(dbf_text,"clib%4x",card->irq0); + QETH_DBF_TEXT6(0,trace,dbf_text); + sprintf(dbf_text,"bufno%3x",bufno); + QETH_DBF_TEXT6(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + + buffer=&card->inbound_qdio_buffers[bufno]; + elements=BUFFER_MAX_ELEMENTS; + el_m_1=elements-1; + + for (i=0;ielement[i].flags=SBAL_FLAGS_LAST_ENTRY; + else + buffer->element[i].flags=0; + + buffer->element[i].length=PAGE_SIZE; + ptr=INBOUND_BUFFER_POS(card,bufno,i); + if (card->do_pfix) { + /* we assume here, that ptr&(PAGE_SIZE-1)==0 */ + buffer->element[i].addr=(void *)pfix_get_page_addr(ptr); + card->real_inb_buffer_addr[bufno][i]=ptr; + } else { + buffer->element[i].addr=ptr; + } + } +} + +static void qeth_queue_input_buffer(qeth_card_t *card,int bufno, + unsigned int under_int) +{ + int count=0,start=0,stop=0,pos; + int result; + int cnt1,cnt2=0; + int wrapped=0; + int i; + int requeue_counter; + char dbf_text[15]; + int no; + +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"qibf%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",under_int,bufno); + QETH_DBF_TEXT5(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + atomic_inc(&card->requeue_counter); + if (atomic_read(&card->requeue_counter) > QETH_REQUEUE_THRESHOLD) { + if (!spin_trylock(&card->requeue_input_lock)) { +#ifndef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"qibl%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + return; + } + requeue_counter=atomic_read(&card->requeue_counter); + pos=atomic_read(&card->requeue_position); + + start=pos; + /* omit the situation with 128 simultaneously + enqueued buffers, as then we can't benefit from PCI + avoidance anymore -- therefore we let count not grow as + big as requeue_counter */ + while ( (!atomic_read(&card->inbound_buffer_refcnt[pos])) && + (countdev_name); + sprintf(dbf_text,"QINB%4x",card->irq0); + QETH_DBF_TEXT2(1,trace,dbf_text); + goto out; + } + card->inbound_buffer_entry_no[pos]= + no|SPAREBUF_MASK; + } + card->inbound_buffer_entry_no[pos]=no; + atomic_set(&card->inbound_buffer_refcnt[pos],1); + count++; + if (pos>=QDIO_MAX_BUFFERS_PER_Q-1) { + pos=0; + wrapped=1; + } else pos++; + } + /* stop points to the position after the last element */ + stop=pos; + +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"qibi%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"%4x",requeue_counter); + QETH_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",start,stop); + QETH_DBF_TEXT3(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + if (wrapped) { + cnt1=QDIO_MAX_BUFFERS_PER_Q-start; + cnt2=stop; + } else { + cnt1=count; + /* cnt2 is already set to 0 */ + } + + atomic_sub(count,&card->requeue_counter); + /* this is the only place where card->requeue_position is + written to, so that's ok (as it is in a lock) */ + atomic_set(&card->requeue_position, + (atomic_read(&card->requeue_position)+count) + &(QDIO_MAX_BUFFERS_PER_Q-1)); + + if (cnt1) { + for (i=start;iirq2, + QDIO_FLAG_SYNC_INPUT|under_int, + 0,start,cnt1, + NULL); + if (result) { + PRINT_WARN("qeth_queue_input_buffer's " \ + "do_QDIO returnd %i " \ + "(irq 0x%x)\n", + result,card->irq2); + sprintf(dbf_text,"QIDQ%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",result, + requeue_counter); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",start,cnt1); + QETH_DBF_TEXT1(1,trace,dbf_text); + } + } + if (cnt2) { + for (i=0;iirq2, + QDIO_FLAG_SYNC_INPUT|under_int,0, + 0,cnt2, + NULL); + if (result) { + PRINT_WARN("qeth_queue_input_buffer's " \ + "do_QDIO returnd %i " \ + "(irq 0x%x)\n", + result,card->irq2); + sprintf(dbf_text,"QIDQ%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",result, + requeue_counter); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",0,cnt2); + QETH_DBF_TEXT1(1,trace,dbf_text); + } + } +out: + my_spin_unlock(&card->requeue_input_lock); + } + +} + +static inline struct sk_buff *qeth_get_skb(unsigned int len) +{ + struct sk_buff *skb; + +#ifdef QETH_VLAN + skb=dev_alloc_skb(len+VLAN_HLEN); + if (skb) skb_reserve(skb,VLAN_HLEN); +#else /* QETH_VLAN */ + skb=dev_alloc_skb(len); +#endif /* QETH_VLAN */ + return skb; +} + +static struct sk_buff *qeth_get_next_skb(qeth_card_t *card, + int *element_ptr,int *pos_in_el_ptr, + void **hdr_ptr, + qdio_buffer_t *buffer) +{ + int length; + char *data_ptr; + int step,len_togo,element,pos_in_el; + int curr_len; + int max_elements; + struct sk_buff *skb; + char dbf_text[15]; + + max_elements=BUFFER_MAX_ELEMENTS; + +#define SBALE_LEN(x) ((x>=max_elements)?0:(buffer->element[x].length)) +#define SBALE_ADDR(x) (buffer->element[x].addr) + + element=*element_ptr; + + if (element>=max_elements) { + PRINT_WARN("irq 0x%x: error in interpreting buffer (data " \ + "too long), %i elements.\n",card->irq0,element); + sprintf(dbf_text,"IEDL%4x",card->irq0); + QETH_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",*element_ptr,*pos_in_el_ptr); + QETH_DBF_TEXT0(1,trace,dbf_text); + QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN, + QETH_DBF_MISC_LEN); + return NULL; + } + + pos_in_el=*pos_in_el_ptr; + + curr_len=SBALE_LEN(element); + if (curr_len>PAGE_SIZE) { + PRINT_WARN("irq 0x%x: bad element length in element %i: " \ + "0x%x\n",card->irq0,element,curr_len); + sprintf(dbf_text,"BELN%4x",card->irq0); + QETH_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"%4x",curr_len); + QETH_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",*element_ptr,*pos_in_el_ptr); + QETH_DBF_TEXT0(1,trace,dbf_text); + QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN, + QETH_DBF_MISC_LEN); + return NULL; + } + /* header fits in current element? */ + if (curr_lenirq0); + QETH_DBF_TEXT6(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + return NULL; /* no more data in buffer */ + } + /* set hdr to next element */ + element++; + pos_in_el=0; + curr_len=SBALE_LEN(element); + /* does it fit in there? */ + if (curr_lenirq0); + QETH_DBF_TEXT6(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + return NULL; + } + } + + *hdr_ptr=SBALE_ADDR(element)+pos_in_el; + + length=*(__u16*)((char*)(*hdr_ptr)+QETH_HEADER_LEN_POS); + +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"gnHd%4x",card->irq0); + QETH_DBF_TEXT6(0,trace,dbf_text); + QETH_DBF_HEX6(0,trace,hdr_ptr,sizeof(void*)); +#endif /* QETH_DBF_LIKE_HELL */ + + pos_in_el+=QETH_HEADER_SIZE; + if (curr_len<=pos_in_el) { + /* switch to next element for data */ + pos_in_el=0; + element++; + curr_len=SBALE_LEN(element); + if (!curr_len) { + PRINT_WARN("irq 0x%x: inb. buffer with more headers " \ + "than data areas (%i elements).\n", + card->irq0,element); + sprintf(dbf_text,"IEMH%4x",card->irq0); + QETH_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%4x",element,*element_ptr, + *pos_in_el_ptr); + QETH_DBF_TEXT0(1,trace,dbf_text); + QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN, + QETH_DBF_MISC_LEN); + return NULL; + } + } + + data_ptr=SBALE_ADDR(element)+pos_in_el; + + if (card->options.fake_ll==FAKE_LL) { + skb=qeth_get_skb(length+QETH_FAKE_LL_LEN); + if (!skb) goto nomem; + skb_pull(skb,QETH_FAKE_LL_LEN); + if (!skb) { + dev_kfree_skb_irq(skb); + goto nomem; + } + } else { + skb=qeth_get_skb(length); + if (!skb) goto nomem; + } + + if (card->easy_copy_cap) + memcpy(skb_put(skb,length),data_ptr,length); + +#ifdef QETH_DBF_LIKE_HELL + QETH_DBF_HEX6(0,trace,&data_ptr,sizeof(void*)); + QETH_DBF_HEX6(0,trace,&skb,sizeof(void*)); +#endif /* QETH_DBF_LIKE_HELL */ + + len_togo=length; + while (1) { + step=qeth_min(len_togo,curr_len-pos_in_el); + if (!step) { + PRINT_WARN("irq 0x%x: unexpected end of buffer, " \ + "length of element %i is 0. Discarding " \ + "packet.\n",card->irq0,element); + sprintf(dbf_text,"IEUE%4x",card->irq0); + QETH_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%4x",element,*element_ptr, + *pos_in_el_ptr); + QETH_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",len_togo,step); + QETH_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",curr_len,pos_in_el); + QETH_DBF_TEXT0(1,trace,dbf_text); + QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN, + QETH_DBF_MISC_LEN); + dev_kfree_skb_irq(skb); + return NULL; + } + if (!card->easy_copy_cap) + memcpy(skb_put(skb,step),data_ptr,step); + len_togo-=step; + if (len_togo) { + pos_in_el=0; + element++; + curr_len=SBALE_LEN(element); + data_ptr=SBALE_ADDR(element); + } else { +#ifdef QETH_INBOUND_PACKING_1_PACKET_PER_SBALE + element++; + /* we don't need to calculate curr_len */ + pos_in_el=0; +#else /* QETH_INBOUND_PACKING_1_PACKET_PER_SBALE */ + pos_in_el+=step; +#endif /* QETH_INBOUND_PACKING_1_PACKET_PER_SBALE */ + break; + } + } + +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"%4x%4x",element,pos_in_el); + QETH_DBF_TEXT6(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + + *element_ptr=element; + *pos_in_el_ptr=pos_in_el; + + return skb; + +nomem: + if (net_ratelimit()) { + PRINT_WARN("no memory for packet from %s\n",card->dev_name); + } + sprintf(dbf_text,"NOMM%4x",card->irq0); + QETH_DBF_TEXT0(0,trace,dbf_text); + return NULL; +} + +static void qeth_transform_outbound_addrs(qeth_card_t *card, + qdio_buffer_t *buffer) +{ + int i; + void *ptr; + + if (card->do_pfix) { + for (i=0;ielement[i].addr; + buffer->element[i].addr=(void *)pfix_get_addr(ptr); + } + } +} +static void qeth_get_linux_addrs_for_buffer(qeth_card_t *card,int buffer_no) +{ + int i; + void *ptr; + + if (card->do_pfix) { + for (i=0;iinbound_qdio_buffers[buffer_no]. + element[i].addr; + card->inbound_qdio_buffers[buffer_no].element[i].addr= + card->real_inb_buffer_addr[buffer_no][i]+ + ((unsigned long)ptr&(PAGE_SIZE-1)); + } + } +} + +static void qeth_read_in_buffer(qeth_card_t *card,int buffer_no) +{ + struct sk_buff *skb; + void *hdr_ptr; + int element=0,pos_in_el=0; + int version; + qdio_buffer_t *buffer; + unsigned short cast_type; +#ifdef QETH_VLAN + __u16 *vlan_tag; +#endif + int i; + int max_elements; + char dbf_text[15]; + struct net_device *dev; + + dev=card->dev; + max_elements=BUFFER_MAX_ELEMENTS; + + buffer=&card->inbound_qdio_buffers[buffer_no]; + + /* inform about errors */ + if (buffer->element[15].flags&0xff) { + PRINT_WARN("on irq 0x%x: incoming SBALF 15 on buffer " \ + "0x%x are 0x%x\n",card->irq0,buffer_no, + buffer->element[15].flags&0xff); + sprintf(dbf_text,"SF##%2x%2x",buffer_no, + buffer->element[15].flags&0xff); + *((__u16*)(&dbf_text[2]))=(__u16)card->irq0; + QETH_DBF_HEX1(1,trace,dbf_text,QETH_DBF_TRACE_LEN); + } + + for (i=0;ielement[i].flags&SBAL_FLAGS_LAST_ENTRY) { + buffer->element[i+1].length=0; + break; + } + } +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.bufs_rec++; +#endif /* QETH_PERFORMANCE_STATS */ + +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"ribX%4x",card->irq0); + dbf_text[3]=buffer_no; + QETH_DBF_HEX6(0,trace,dbf_text,QETH_DBF_TRACE_LEN); +#endif /* QETH_DBF_LIKE_HELL */ + + while ((skb=qeth_get_next_skb(card,&element,&pos_in_el, + &hdr_ptr,buffer))) { + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.skbs_rec++; +#endif /* QETH_PERFORMANCE_STATS */ + + if (skb) { + skb->dev=dev; + +#ifdef QETH_IPV6 + if ( (*(__u16 *)(hdr_ptr))&(QETH_HEADER_PASSTHRU) ) { + skb->protocol=card->type_trans(skb,dev); + } else +#endif /* QETH_IPV6 */ + { + version=((*(__u16 *)(hdr_ptr))& + (QETH_HEADER_IPV6))?6:4; + skb->protocol=htons((version==4)?ETH_P_IP: + (version==6)?ETH_P_IPV6: + ETH_P_ALL); + cast_type=(*(__u16 *)(hdr_ptr))& + (QETH_CAST_FLAGS); + if (cast_type==QETH_CAST_UNICAST) { + skb->pkt_type=PACKET_HOST; + } else if (cast_type==QETH_CAST_MULTICAST) { + skb->pkt_type=PACKET_MULTICAST; + } else if (cast_type==QETH_CAST_BROADCAST) { + skb->pkt_type=PACKET_BROADCAST; + } else if ( (cast_type==QETH_CAST_ANYCAST) || + (cast_type==QETH_CAST_NOCAST) ) { + sprintf(dbf_text,"ribf%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"castan%2x",cast_type); + QETH_DBF_TEXT2(1,trace,dbf_text); + skb->pkt_type=PACKET_HOST; + } else { + PRINT_WARN("adapter is using an " \ + "unknown casting value " \ + "of 0x%x. Using " \ + "unicasting instead.\n", + cast_type); + skb->pkt_type=PACKET_HOST; + sprintf(dbf_text,"ribf%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"castun%2x",cast_type); + QETH_DBF_TEXT2(1,trace,dbf_text); + } + + if (card->options.fake_ll==FAKE_LL) { + skb->mac.raw=skb->data-QETH_FAKE_LL_LEN; + if (skb->pkt_type==PACKET_MULTICAST) { + switch (skb->protocol) { +#ifdef QETH_IPV6 + case __constant_htons(ETH_P_IPV6): + ndisc_mc_map((struct in6_addr *) + skb->data+QETH_FAKE_LL_V6_ADDR_POS, + skb->mac.raw+ + QETH_FAKE_LL_DEST_MAC_POS, + card->dev,0); + break; +#endif /* QETH_IPV6 */ + case __constant_htons(ETH_P_IP): + qeth_get_mac_for_ipm(*(__u32*) + skb->data+QETH_FAKE_LL_V4_ADDR_POS, + skb->mac.raw+ + QETH_FAKE_LL_DEST_MAC_POS, + card->dev); + break; + default: + memcpy(skb->mac.raw+ + QETH_FAKE_LL_DEST_MAC_POS, + card->dev->dev_addr, + QETH_FAKE_LL_ADDR_LEN); + } + } else if (skb->pkt_type==PACKET_BROADCAST) { + memset(skb->mac.raw+ + QETH_FAKE_LL_DEST_MAC_POS,0xff, + QETH_FAKE_LL_ADDR_LEN); + } else { + memcpy(skb->mac.raw+ + QETH_FAKE_LL_DEST_MAC_POS, + card->dev->dev_addr, + QETH_FAKE_LL_ADDR_LEN); + } + if (*(__u8*)(hdr_ptr+11)& + QETH_EXT_HEADER_SRC_MAC_ADDRESS) { + memcpy(skb->mac.raw+ + QETH_FAKE_LL_SRC_MAC_POS, + hdr_ptr+QETH_FAKE_LL_SRC_MAC_POS_IN_QDIO_HDR, + QETH_FAKE_LL_ADDR_LEN); + } else { + /* clear source MAC for security reasons */ + memset(skb->mac.raw+ + QETH_FAKE_LL_DEST_MAC_POS,0, + QETH_FAKE_LL_ADDR_LEN); + } + memcpy(skb->mac.raw+ + QETH_FAKE_LL_PROT_POS, + &skb->protocol, + QETH_FAKE_LL_PROT_LEN); + } else { + skb->mac.raw=skb->data; + } + + skb->ip_summed=card->options.checksum_type; + if (card->options.checksum_type==HW_CHECKSUMMING) { + /* do we have a checksummed packet? */ + if (*(__u8*)(hdr_ptr+11)& + QETH_EXT_HEADER_CSUM_TRANSP_REQ) { + /* skb->ip_summed is set already */ + + /* vlan is not an issue here, it's still in + * the QDIO header, not pushed in the + * skb yet */ + int ip_len=(skb->data[0]&0x0f)<<2; + + if (*(__u8*)(hdr_ptr+11)& + QETH_EXT_HEADER_CSUM_TRANSP_FRAME_TYPE) { + /* get the UDP checksum */ + skb->csum=*(__u16*) + (&skb->data[ip_len+ + QETH_UDP_CSUM_OFFSET]); + } else { + /* get the TCP checksum */ + skb->csum=*(__u16*) + (&skb->data[ip_len+ + QETH_TCP_CSUM_OFFSET]); + } + } else { + /* make the stack check it */ + skb->ip_summed=SW_CHECKSUMMING; + } + } + +#ifdef QETH_VLAN + if (*(__u8*)(hdr_ptr+11)& + QETH_EXT_HEADER_VLAN_FRAME) { + vlan_tag=(__u16 *)skb_push(skb, + VLAN_HLEN); + /* + if (*(__u8*)(hdr_ptr+11) & + QETH_EXT_HEADER_INCLUDE_VLAN_TAG) { + *vlan_tag = *(__u16*)(hdr_ptr+28); + *(vlan_tag+1)= *(__u16*)(hdr_ptr+30); + } else { + */ + *vlan_tag = *(__u16*)(hdr_ptr+12); + *(vlan_tag+1) = skb->protocol; + /* + } + */ + skb->protocol= + __constant_htons(ETH_P_8021Q); + } +#endif + } + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.inbound_time+= + NOW-card->perf_stats.inbound_start_time; + card->perf_stats.inbound_cnt++; +#endif /* QETH_PERFORMANCE_STATS */ + +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"rxpk%4x",card->irq0); + QETH_DBF_TEXT6(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + + netif_rx(skb); + + card->stats->rx_packets++; + card->stats->rx_bytes+=skb->len; + } else { + PRINT_WARN("%s: dropped packet, no buffers " \ + "available.\n",card->dev_name); + sprintf(dbf_text,"DROP%4x",card->irq0); + QETH_DBF_TEXT2(1,trace,dbf_text); + card->stats->rx_dropped++; + } + } + atomic_set(&card->inbound_buffer_refcnt[buffer_no],0); + qeth_put_buffer_pool_entry(card,card->inbound_buffer_entry_no[ + buffer_no]); +} + +static void qeth_fill_header(qeth_hdr_t *hdr,struct sk_buff *skb, + int version,int multicast) +{ +#ifdef QETH_DBF_LIKE_HELL + char dbf_text[15]; +#endif /* QETH_DBF_LIKE_HELL */ +#ifdef QETH_VLAN + qeth_card_t *card; +#endif + + hdr->id=1; + hdr->ext_flags=0; + +#ifdef QETH_VLAN + /* before we're going to overwrite + this location with next hop ip + */ + card = (qeth_card_t *)skb->dev->priv; + if ((card->vlangrp != NULL) && + (version == 4) && + vlan_tx_tag_present(skb)) + { + hdr->ext_flags = QETH_EXT_HEADER_VLAN_FRAME; + hdr->vlan_id = vlan_tx_tag_get(skb); + } +#endif + + hdr->length=skb->len-QETH_HEADER_SIZE; /* as skb->len includes + the header now */ + + /* yes, I know this is doubled code, but a small little bit + faster maybe */ + if (version==4) { /* IPv4 */ + if (multicast==RTN_MULTICAST) { + hdr->flags=QETH_CAST_MULTICAST; + } else if (multicast==RTN_BROADCAST) { + hdr->flags=QETH_CAST_BROADCAST; + } else { + hdr->flags=QETH_CAST_UNICAST; + } + *((__u32*)(&hdr->dest_addr[0]))=0; + *((__u32*)(&hdr->dest_addr[4]))=0; + *((__u32*)(&hdr->dest_addr[8]))=0; + if ((skb->dst) && (skb->dst->neighbour)) { + *((__u32*)(&hdr->dest_addr[12]))= + *((__u32*)skb->dst->neighbour->primary_key); + } else { + /* fill in destination address used + * in ip header */ + *((__u32*)(&hdr->dest_addr[12]))= + skb->nh.iph->daddr; + } + } else if (version==6) { /* IPv6 or passthru */ + if (multicast==RTN_MULTICAST) { + hdr->flags=QETH_CAST_MULTICAST| + QETH_HEADER_PASSTHRU| + QETH_HEADER_IPV6; + } else if (multicast==RTN_ANYCAST) { + hdr->flags=QETH_CAST_ANYCAST| + QETH_HEADER_PASSTHRU| + QETH_HEADER_IPV6; + } else if (multicast==RTN_BROADCAST) { + hdr->flags=QETH_CAST_BROADCAST| + QETH_HEADER_PASSTHRU| + QETH_HEADER_IPV6; + } else { /* default: RTN_UNICAST */ + hdr->flags=QETH_CAST_UNICAST| + QETH_HEADER_PASSTHRU| + QETH_HEADER_IPV6; + } + + if ((skb->dst) && (skb->dst->neighbour)) { + memcpy(hdr->dest_addr, + skb->dst->neighbour->primary_key,16); + } else { + /* fill in destination address used + * in ip header */ + memcpy(hdr->dest_addr, + &skb->nh.ipv6h->daddr,16); + } + } else { /* passthrough */ + if (!memcmp(skb->data+QETH_HEADER_SIZE, + skb->dev->broadcast,6)) { /* broadcast? */ + hdr->flags=QETH_CAST_BROADCAST|QETH_HEADER_PASSTHRU; + } else { + hdr->flags=QETH_CAST_UNICAST|QETH_HEADER_PASSTHRU; + } + } +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"filhdr%2x",version); + QETH_DBF_TEXT6(0,trace,dbf_text); + sprintf(dbf_text,"%2x",multicast); + QETH_DBF_TEXT6(0,trace,dbf_text); + QETH_DBF_HEX6(0,trace,&skb,sizeof(void*)); + QETH_DBF_HEX6(0,trace,&skb->data,sizeof(void*)); + QETH_DBF_HEX6(0,misc,hdr,__max(QETH_HEADER_SIZE,QETH_DBF_MISC_LEN)); + QETH_DBF_HEX6(0,data,skb->data, + __max(QETH_DBF_DATA_LEN,QETH_DBF_DATA_LEN)); +#endif /* QETH_DBF_LIKE_HELL */ +} + +static int inline qeth_fill_buffer(qdio_buffer_t *buffer,char *dataptr, + int length,int element) +{ + int length_here; + int first_lap=1; +#ifdef QETH_DBF_LIKE_HELL + char dbf_text[15]; +#endif /* QETH_DBF_LIKE_HELL */ + int first_element=element; + + while (length>0) { + /* length_here is the remaining amount of data in this page */ + length_here=PAGE_SIZE-((unsigned long)dataptr&(PAGE_SIZE-1)); + if (lengthelement[element].addr=dataptr; + buffer->element[element].length=length_here; + length-=length_here; + if (!length) { + if (first_lap) { + buffer->element[element].flags=0; + } else { + buffer->element[element].flags= + SBAL_FLAGS_LAST_FRAG; + } + } else { + if (first_lap) { + buffer->element[element].flags= + SBAL_FLAGS_FIRST_FRAG; + } else { + buffer->element[element].flags= + SBAL_FLAGS_MIDDLE_FRAG; + } + } + dataptr=dataptr+length_here; + element++; + if (element>QDIO_MAX_ELEMENTS_PER_BUFFER) { + PRINT_ERR("qeth_fill_buffer: IP packet too big!\n"); + QETH_DBF_TEXT1(0,trace,"IPpktobg"); + QETH_DBF_HEX1(1,trace,&dataptr,sizeof(void*)); + buffer->element[first_element].length=0; + break; + } + first_lap=0; + } +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"filbuf%2x",element); + QETH_DBF_TEXT6(0,trace,dbf_text); + QETH_DBF_HEX3(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX3(0,misc,buffer+QETH_DBF_MISC_LEN,QETH_DBF_MISC_LEN); +#endif /* QETH_DBF_LIKE_HELL */ + + return element; +} + +static void qeth_flush_packed_packets(qeth_card_t *card,int queue, + int under_int) +{ + qdio_buffer_t *buffer; + int result; + int position; + int position_for_do_qdio; + char dbf_text[15]; + int last_pci; + + position=card->outbound_first_free_buffer[queue]; + /* can happen, when in the time between deciding to pack and sending + the next packet the lower mark was reached: */ + if (!card->outbound_ringbuffer[queue]->ringbuf_element[position]. + next_element_to_fill) + return; + + buffer=&card->outbound_ringbuffer[queue]->buffer[position]; + buffer->element[card->outbound_ringbuffer[queue]-> + ringbuf_element[position]. + next_element_to_fill-1].flags|=SBAL_FLAGS_LAST_ENTRY; + + card->dev->trans_start=jiffies; + +#ifdef QETH_PERFORMANCE_STATS + if (card->outbound_buffer_send_state[queue][position]== + SEND_STATE_DONT_PACK) { + card->perf_stats.bufs_sent_dont_pack++; + } else if (card->outbound_buffer_send_state[queue][position]== + SEND_STATE_PACK) { + card->perf_stats.bufs_sent_pack++; + } + card->perf_stats.bufs_sent++; +#endif /* QETH_PERFORMANCE_STATS */ + + position_for_do_qdio=position; + + position=(position+1)&(QDIO_MAX_BUFFERS_PER_Q-1); + card->outbound_first_free_buffer[queue]=position; + + card->outbound_bytes_in_buffer[queue]=0; + /* we can override that, as we have at most 127 buffers enqueued */ + card->outbound_ringbuffer[queue]->ringbuf_element[position]. + next_element_to_fill=0; + + atomic_inc(&card->outbound_used_buffers[queue]); + +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"flsp%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"%4x%2x%2x",position_for_do_qdio,under_int,queue); + QETH_DBF_TEXT5(0,trace,dbf_text); + QETH_DBF_HEX5(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX5(0,misc,buffer+QETH_DBF_MISC_LEN,QETH_DBF_MISC_LEN); +#endif /* QETH_DBF_LIKE_HELL */ + + /* we always set the outbound pci flag, don't care, whether the + * adapter honors it or not */ + switch (card->send_state[queue]) { + case SEND_STATE_DONT_PACK: + if (atomic_read(&card->outbound_used_buffers[queue]) + outbound_ringbuffer[queue]-> + buffer[position_for_do_qdio].element[0].flags|=0x40; + atomic_set(&card->last_pci_pos[queue],position_for_do_qdio); + break; + case SEND_STATE_PACK: + last_pci=atomic_read(&card->last_pci_pos[queue]); + if (position_for_do_qdiooutbound_used_buffers[queue])>= + last_pci) { + /* set the PCI bit */ + card->outbound_ringbuffer[queue]-> + buffer[position_for_do_qdio]. + element[0].flags|=0x40; + atomic_set(&card->last_pci_pos[queue], + position_for_do_qdio); + } + } + + qeth_transform_outbound_addrs(card, + &card->outbound_ringbuffer[queue]-> + buffer[position_for_do_qdio]); + /* this has to be at the end, otherwise a buffer could be flushed + twice (see coment in qeth_do_send_packet) */ + result=do_QDIO(card->irq2,QDIO_FLAG_SYNC_OUTPUT|under_int,queue, + position_for_do_qdio,1, + NULL); + + if (result) { + PRINT_WARN("Outbound do_QDIO returned %i " \ + "(irq 0x%x)\n",result,card->irq2); + sprintf(dbf_text,"FLSP%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"odoQ%4x",result); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"%4x%2x%2x",position_for_do_qdio, + under_int,queue); + QETH_DBF_TEXT5(0,trace,dbf_text); + QETH_DBF_HEX5(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX5(0,misc,buffer+QETH_DBF_MISC_LEN, + QETH_DBF_MISC_LEN); + } +} + +#define ERROR_NONE 0 +#define ERROR_RETRY 1 +#define ERROR_LINK_FAILURE 2 +#define ERROR_KICK_THAT_PUPPY 3 +static inline int qeth_determine_send_error(int cc,int qdio_error,int sbalf15) +{ + char dbf_text[15]; + + switch (cc&3) { + case 0: + if (qdio_error) + return ERROR_LINK_FAILURE; + return ERROR_NONE; + case 2: + if (cc&QDIO_SIGA_ERROR_B_BIT_SET) { + QETH_DBF_TEXT3(0,trace,"sigacc2b"); + return ERROR_KICK_THAT_PUPPY; + } + if (qeth_sbalf15_in_retrieable_range(sbalf15)) + return ERROR_RETRY; + return ERROR_LINK_FAILURE; + /* look at qdio_error and sbalf 15 */ + case 1: + PRINT_WARN("siga returned cc 1! cc=0x%x, " \ + "qdio_error=0x%x, sbalf15=0x%x\n", + cc,qdio_error,sbalf15); + + QETH_DBF_TEXT3(0,trace,"siga-cc1"); + QETH_DBF_TEXT2(0,qerr,"siga-cc1"); + sprintf(dbf_text,"%1x%2x%2x",cc,qdio_error,sbalf15); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_TEXT2(0,qerr,dbf_text); + return ERROR_LINK_FAILURE; + case 3: + QETH_DBF_TEXT3(0,trace,"siga-cc3"); + return ERROR_KICK_THAT_PUPPY; + } + return ERROR_LINK_FAILURE; /* should never happen */ +} + +static void qeth_free_buffer(qeth_card_t *card,int queue,int bufno, + int qdio_error,int siga_error) +{ + struct sk_buff *skb; + int error; + int retries; + int sbalf15; + char dbf_text[15]; + qdio_buffer_t *buffer; + + switch (card->outbound_buffer_send_state[queue][bufno]) { + case SEND_STATE_DONT_PACK: /* fallthrough */ + case SEND_STATE_PACK: +#ifdef QETH_DBF_LIKE_HELL + sprintf(dbf_text,"frbf%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%4x",queue,bufno, + card->outbound_buffer_send_state[queue][bufno]); + QETH_DBF_TEXT5(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + + buffer=&card->outbound_ringbuffer[queue]->buffer[bufno]; + sbalf15=buffer->element[15].flags&0xff; + error=qeth_determine_send_error(siga_error,qdio_error,sbalf15); + if (error==ERROR_KICK_THAT_PUPPY) { + sprintf(dbf_text,"KP%4x%2x",card->irq0,queue); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_TEXT2(0,qerr,dbf_text); + QETH_DBF_TEXT2(1,setup,dbf_text); + sprintf(dbf_text,"%2x%2x%2x%2x",bufno, + siga_error,qdio_error,sbalf15); + QETH_DBF_TEXT2(1,trace,dbf_text); + QETH_DBF_TEXT2(1,qerr,dbf_text); + PRINT_ERR("Outbound queue x%x on irq x%x (%s); " \ + "errs: siga: x%x, qdio: x%x, flags15: " \ + "x%x. The device will be taken down.\n", + queue,card->irq0,card->dev_name, + siga_error,qdio_error,sbalf15); + netif_stop_queue(card->dev); + qeth_set_dev_flag_norunning(card); + atomic_set(&card->problem,PROBLEM_BAD_SIGA_RESULT); + qeth_schedule_recovery(card); + } else if (error==ERROR_RETRY) { + /* analyze, how many retries we did so far */ + retries=card->send_retries[queue][bufno]; + + sprintf(dbf_text,"Rt%4x%2x",card->irq0,queue); + QETH_DBF_TEXT4(0,trace,dbf_text); + sprintf(dbf_text,"b%2x:%2x%2x",bufno, + sbalf15,retries); + QETH_DBF_TEXT4(0,trace,dbf_text); + + if (++retries>SEND_RETRIES_ALLOWED) { + error=ERROR_LINK_FAILURE; + QETH_DBF_TEXT4(1,trace,"ndegelnd"); + } + /* else error stays RETRY for the switch statemnet */ + } else if (error==ERROR_LINK_FAILURE) { + /* we don't want to log failures resulting from + * too many retries */ + sprintf(dbf_text,"Fail%4x",card->irq0); + QETH_DBF_TEXT3(1,trace,dbf_text); + QETH_DBF_HEX3(0,misc,buffer,QETH_DBF_MISC_LEN); + QETH_DBF_HEX3(0,misc,buffer+QETH_DBF_MISC_LEN, + QETH_DBF_MISC_LEN); + } + + while ((skb=skb_dequeue(&card->outbound_ringbuffer[queue]-> + ringbuf_element[bufno].skb_list))) { + switch (error) { + case ERROR_NONE: + atomic_dec(&skb->users); + dev_kfree_skb_irq(skb); + break; + case ERROR_RETRY: + QETH_DBF_TEXT3(0,qerr,"RETRY!!!"); + QETH_DBF_TEXT4(0,trace,"RETRY!!!"); + /* retry packet async (quickly) ... */ + atomic_dec(&skb->users); + dev_kfree_skb_irq(skb); + break; + case ERROR_LINK_FAILURE: + case ERROR_KICK_THAT_PUPPY: + QETH_DBF_TEXT4(0,trace,"endeglnd"); + dst_link_failure(skb); + atomic_dec(&skb->users); + dev_kfree_skb_irq(skb); + break; + } + } + break; + default: + PRINT_WARN("oops... wrong send_state on %s. " \ + "shouldn't happen " \ + "(line %i). q=%i, bufno=x%x, state=%i\n", + card->dev_name,__LINE__,queue,bufno, + card->outbound_buffer_send_state[queue][bufno]); + sprintf(dbf_text,"UPSf%4x",card->irq0); + QETH_DBF_TEXT0(1,trace,dbf_text); + QETH_DBF_TEXT0(1,qerr,dbf_text); + sprintf(dbf_text,"%2x%2x%4x",queue,bufno, + card->outbound_buffer_send_state[queue][bufno]); + QETH_DBF_TEXT0(1,trace,dbf_text); + QETH_DBF_TEXT0(1,qerr,dbf_text); + } + card->outbound_buffer_send_state[queue][bufno]=SEND_STATE_INACTIVE; + card->send_retries[queue][bufno]=0; +} + +static void qeth_free_all_skbs(qeth_card_t *card) +{ + int q,b; + + for (q=0;qno_queues;q++) + for (b=0;boutbound_buffer_send_state[q][b]!= + SEND_STATE_INACTIVE) + qeth_free_buffer(card,q,b,0,0); +} + +static inline void qeth_flush_buffer(qeth_card_t *card,int queue, + int under_int) +{ +#ifdef QETH_DBF_LIKE_HELL + char dbf_text[15]; + sprintf(dbf_text,"flsb%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%2x",queue,under_int, + card->outbound_buffer_send_state[queue][ + card->outbound_first_free_buffer[queue] ]); + QETH_DBF_TEXT5(0,trace,dbf_text); +#endif /* QETH_DBF_LIKE_HELL */ + + switch (card->outbound_buffer_send_state[queue][ + card->outbound_first_free_buffer[queue] ]) { + case SEND_STATE_DONT_PACK: break; + case SEND_STATE_PACK: + qeth_flush_packed_packets(card,queue,under_int); + break; + default:break; + } +} +#ifdef QETH_VLAN + +void qeth_insert_ipv6_vlan_tag(struct sk_buff *__skb) +{ + + /* Move the mac addresses to the beginning of the new header. + * We are using three memcpys instead of one memmove to save + * cycles. + */ +#define TMP_CPYSIZE 4 + __u16 *tag; + tag = (__u16*)skb_push(__skb, VLAN_HLEN); + memcpy(__skb->data, + __skb->data+TMP_CPYSIZE,TMP_CPYSIZE); + memcpy(__skb->data+TMP_CPYSIZE, + __skb->data+(2*TMP_CPYSIZE),TMP_CPYSIZE); + memcpy(__skb->data+(2*TMP_CPYSIZE), + __skb->data+(3*TMP_CPYSIZE),TMP_CPYSIZE); + tag = (__u16*)(__skb->data+(3*TMP_CPYSIZE)); + + /*first two bytes = ETH_P_8021Q (0x8100) + *second two bytes = VLANID + */ + + *tag = __constant_htons(ETH_P_8021Q); + *(tag+1) = vlan_tx_tag_get(__skb); + *(tag+1)=htons(*(tag+1)); +#undef TMP_CPYSIZE +} +#endif + + + +static void qeth_send_packet_fast(qeth_card_t *card,struct sk_buff *skb, + struct net_device *dev, + int queue,int version,int multicast) +{ + qeth_ringbuffer_element_t *mybuffer; + int position; + qeth_hdr_t *hdr; + char *dataptr; + char dbf_text[15]; + struct sk_buff *nskb; + + position=card->outbound_first_free_buffer[queue]; + + card->outbound_buffer_send_state[queue][position]=SEND_STATE_DONT_PACK; + + mybuffer=&card->outbound_ringbuffer[queue]->ringbuf_element[position]; + if (skb_headroom(skb)realloc_message)) { + card->realloc_message=1; + PRINT_WARN("%s: not enough headroom in skb. " \ + "Try increasing the " \ + "add_hhlen parameter by %i.\n", + card->dev_name, + QETH_HEADER_SIZE-skb_headroom(skb)); + } + PRINT_STUPID("%s: not enough headroom in skb (missing: %i)\n", + card->dev_name,QETH_HEADER_SIZE-skb_headroom(skb)); + sprintf(dbf_text,"NHRf%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb), + version,multicast,queue); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_HEX3(0,trace,&skb->head,sizeof(void*)); + QETH_DBF_HEX3(0,trace,&skb->data,sizeof(void*)); + nskb=skb_realloc_headroom(skb,QETH_HEADER_SIZE); + if (!nskb) { + PRINT_WARN("%s: could not realloc headroom\n", + card->dev_name); + sprintf(dbf_text,"CNRf%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + dev_kfree_skb_irq(skb); + return; + } + dev_kfree_skb_irq(skb); + skb=nskb; + } +#ifdef QETH_VLAN + if ( (card->vlangrp != NULL) && + vlan_tx_tag_present(skb) && + (version==6)) { + qeth_insert_ipv6_vlan_tag(skb); + } +#endif + hdr=(qeth_hdr_t*)(skb_push(skb,QETH_HEADER_SIZE)); + /* sanity check, the Linux memory allocation scheme should + never present us cases like this one (the 32bytes header plus + the first 40 bytes of the paket cross a 4k boundary) */ + dataptr=(char*)hdr; + if ( (((unsigned long)dataptr)&(~(PAGE_SIZE-1))) != + ( ((unsigned long)dataptr+QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE)& + (~(PAGE_SIZE-1)) ) ) { + PRINT_ERR("%s: packet misaligned -- the first %i bytes " \ + "are not in the same page. Discarding packet!\n", + card->dev_name, + QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE); + PRINT_ERR("head=%p, data=%p\n",skb->head,skb->data); + sprintf(dbf_text,"PMAf%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb), + version,multicast,queue); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_HEX1(0,trace,&skb->head,sizeof(void*)); + QETH_DBF_HEX1(1,trace,&skb->data,sizeof(void*)); + dev_kfree_skb_irq(skb); + return; + } + + atomic_inc(&skb->users); + skb_queue_tail(&mybuffer->skb_list,skb); + qeth_fill_header(hdr,skb,version,multicast); + /* we need to write to next_element_to_fill as + qeth_flush_packed_packets checks it */ + card->outbound_ringbuffer[queue]->ringbuf_element[position]. + next_element_to_fill= + qeth_fill_buffer(&card->outbound_ringbuffer[queue]-> + buffer[position],(char *)hdr, + skb->len,0); + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.skbs_sent_dont_pack++; +#endif /* QETH_PERFORMANCE_STATS */ + + qeth_flush_packed_packets(card,queue,0); +} + +/* no checks, if all elements are used, as then we would not be here (at most + 127 buffers are enqueued) */ +static void qeth_send_packet_packed(qeth_card_t *card,struct sk_buff *skb, + struct net_device *dev, + int queue,int version,int multicast) +{ + qeth_ringbuffer_element_t *mybuffer; + int elements_needed; + int element_to_fill; + int buffer_no; + int length; + char *dataptr; + qeth_hdr_t *hdr; + char dbf_text[15]; + struct sk_buff *nskb; + + /* sanity check, dev->hard_header_len should prevent this */ + if (skb_headroom(skb)realloc_message)) { + card->realloc_message=1; + PRINT_WARN("%s: not enough headroom in skb. " \ + "Try increasing the " \ + "add_hhlen parameter by %i.\n", + card->dev_name, + QETH_HEADER_SIZE-skb_headroom(skb)); + } + PRINT_STUPID("%s: not enough headroom in skb (missing: %i)\n", + card->dev_name,QETH_HEADER_SIZE-skb_headroom(skb)); + sprintf(dbf_text,"NHRp%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb), + version,multicast,queue); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_HEX3(0,trace,&skb->head,sizeof(void*)); + QETH_DBF_HEX3(0,trace,&skb->data,sizeof(void*)); + nskb=skb_realloc_headroom(skb,QETH_HEADER_SIZE); + if (!nskb) { + PRINT_WARN("%s: could not realloc headroom\n", + card->dev_name); + sprintf(dbf_text,"CNRp%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + dev_kfree_skb_irq(skb); + return; + } + dev_kfree_skb_irq(skb); + skb=nskb; + } +#ifdef QETH_VLAN + if ( (card->vlangrp != NULL) && + vlan_tx_tag_present(skb) && + (version==6)) { + qeth_insert_ipv6_vlan_tag(skb); + } + +#endif + hdr=(qeth_hdr_t*)(skb_push(skb,QETH_HEADER_SIZE)); + + length=skb->len; + + /* sanity check, the Linux memory allocation scheme should + never present us cases like this one (the 32bytes header plus + the first 40 bytes of the paket cross a 4k boundary) */ + dataptr=(char*)hdr; + if ( (((unsigned long)dataptr)&(~(PAGE_SIZE-1))) != + ( ((unsigned long)dataptr+QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE)& + (~(PAGE_SIZE-1)) ) ) { + PRINT_ERR("%s: packet misaligned -- the first %i bytes " \ + "are not in the same page. Discarding packet!\n", + card->dev_name, + QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE); + sprintf(dbf_text,"PMAp%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb), + version,multicast,queue); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_HEX1(0,trace,&skb->head,sizeof(void*)); + QETH_DBF_HEX1(1,trace,&skb->data,sizeof(void*)); + dev_kfree_skb_irq(skb); + return; + } + + buffer_no=card->outbound_first_free_buffer[queue]; + + element_to_fill=card->outbound_ringbuffer[queue]-> + ringbuf_element[buffer_no]. + next_element_to_fill; + + elements_needed=1+( ( (((unsigned long)dataptr)&(PAGE_SIZE-1))+ + length ) >>PAGE_SHIFT); + if ( (elements_needed>(QDIO_MAX_ELEMENTS_PER_BUFFER-element_to_fill)) || + ( (elements_needed== + (QDIO_MAX_ELEMENTS_PER_BUFFER-element_to_fill)) && + ((element_to_fill>>PAGE_SHIFT)== + card->outbound_bytes_in_buffer[queue]) ) ) { + qeth_flush_packed_packets(card,queue,0); + element_to_fill=0; + card->outbound_bytes_in_buffer[queue]=0; + buffer_no=(buffer_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1); + } + + if (!element_to_fill) + card->outbound_buffer_send_state[queue][buffer_no] + =SEND_STATE_PACK; + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.skbs_sent_pack++; +#endif /* QETH_PERFORMANCE_STATS */ + + mybuffer=&card->outbound_ringbuffer[queue]->ringbuf_element[buffer_no]; + atomic_inc(&skb->users); + skb_queue_tail(&mybuffer->skb_list,skb); + qeth_fill_header(hdr,skb,version,multicast); + card->outbound_bytes_in_buffer[queue]+=length+QETH_HEADER_SIZE; + card->outbound_ringbuffer[queue]->ringbuf_element[buffer_no]. + next_element_to_fill= + qeth_fill_buffer(&card->outbound_ringbuffer[queue]-> + buffer[buffer_no], + dataptr,length,element_to_fill); +} + +static void qeth_alloc_spare_bufs(void) +{ + int i; + int dont_alloc_more=0; + char dbf_text[15]; + + sparebuffer_count=0; + for (i=0;iirq0); + QETH_DBF_TEXT6(0,trace,dbf_text); + sprintf(dbf_text,"%c %c%4x",(version==4)?'4':((version==6)?'6':'0'), + (multicast)?'m':'_',queue); + QETH_DBF_TEXT6(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x", + card->outbound_first_free_buffer[queue], + atomic_read(&card->outbound_used_buffers[queue])); + QETH_DBF_TEXT6(0,trace,dbf_text); + if (qeth_sbal_packing_on_card(card->type)) { + switch (card->send_state[queue]) { + case SEND_STATE_DONT_PACK: + QETH_DBF_TEXT6(0,trace,"usngfast"); + break; + case SEND_STATE_PACK: + QETH_DBF_TEXT6(0,trace,"usngpack"); + break; + } + } else { + QETH_DBF_TEXT6(0,trace,"usngfast"); + } +#endif /* QETH_DBF_LIKE_HELL */ + + if (atomic_read(&card->outbound_used_buffers[queue]) + >=QDIO_MAX_BUFFERS_PER_Q-1) { + sprintf(dbf_text,"cdbs%4x",card->irq0); + QETH_DBF_TEXT2(1,trace,dbf_text); + netif_stop_queue(dev); + return -EBUSY; + } + + /* we are not called under int, so we just spin */ + /* happens around once a second under heavy traffic. takes a little + * bit less than 10usec in avg. on a z900 */ + if (atomic_compare_and_swap(QETH_LOCK_UNLOCKED,QETH_LOCK_NORMAL, + &card->outbound_ringbuffer_lock[queue])) { + sprintf(dbf_text,"SPIN%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + while (atomic_compare_and_swap + (QETH_LOCK_UNLOCKED,QETH_LOCK_NORMAL, + &card->outbound_ringbuffer_lock[queue])) + ; + sprintf(dbf_text,"spin%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + } + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.skbs_sent++; +#endif /* QETH_PERFORMANCE_STATS */ + + if (qeth_sbal_packing_on_card(card->type)) { + switch (card->send_state[queue]) { + case SEND_STATE_DONT_PACK: + qeth_send_packet_fast(card,skb,dev,queue, + version,multicast); + if (atomic_read(&card->outbound_used_buffers[queue]) + >=HIGH_WATERMARK_PACK) { + card->send_state[queue]=SEND_STATE_PACK; + *((__u16*)(&dbf_text2[6]))=card->irq0; + QETH_DBF_HEX3(0,trace,dbf_text2, + QETH_DBF_TRACE_LEN); +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.sc_dp_p++; +#endif /* QETH_PERFORMANCE_STATS */ + } + break; + case SEND_STATE_PACK: + qeth_send_packet_packed(card,skb,dev,queue, + version,multicast); + break; + default: + result=-EBUSY; + sprintf(dbf_text,"UPSs%4x",card->irq0); + QETH_DBF_TEXT0(1,trace,dbf_text); + PRINT_ALL("oops... shouldn't happen (line %i:%i).\n", + __LINE__,card->send_state[queue]); + } + } else { + qeth_send_packet_fast(card,skb,dev,queue, + version,multicast); + } + +again: + /* ATOMIC: (NORMAL->UNLOCKED, FLUSH->NORMAL) */ + if (atomic_dec_return(&card->outbound_ringbuffer_lock[queue])) { + qeth_flush_buffer(card,queue,0); + card->send_state[queue]=SEND_STATE_DONT_PACK; + goto again; + } + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.outbound_time+= + NOW-card->perf_stats.outbound_start_time; + card->perf_stats.outbound_cnt++; +#endif /* QETH_PERFORMANCE_STATS */ + + card->stats->tx_packets++; + card->stats->tx_bytes+=skb->len; + + return result; +} + +static int qeth_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) +{ + qeth_card_t *card; + char dbf_text[15]; + int result; + + card=(qeth_card_t*)(dev->priv); + + if (skb==NULL) + return 0; + +#ifdef QETH_DBF_LIKE_HELL + QETH_DBF_HEX4(0,data,skb->data,__max(QETH_DBF_DATA_LEN,skb->len)); +#endif /* QETH_DBF_LIKE_HELL */ + + netif_stop_queue(dev); + + if (!card) { + QETH_DBF_TEXT2(0,trace,"XMNSNOCD"); + dst_link_failure(skb); + dev_kfree_skb_irq(skb); + return 0; + } + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.outbound_start_time=NOW; +#endif /* QETH_PERFORMANCE_STATS */ + + if (!atomic_read(&card->is_startlaned)) { + card->stats->tx_carrier_errors++; + sprintf(dbf_text,"XMNS%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + dst_link_failure(skb); + dev_kfree_skb_irq(skb); + return 0; + } + + result=qeth_do_send_packet(card,skb,dev); + + if (!result) + netif_wake_queue(card->dev); + + return result; +} + +static struct net_device_stats* qeth_get_stats(struct net_device *dev) +{ + qeth_card_t *card; + char dbf_text[15]; + + card=(qeth_card_t*)(dev->priv); + + sprintf(dbf_text,"gtst%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return card->stats; +} + +static int qeth_change_mtu(struct net_device *dev,int new_mtu) +{ + qeth_card_t *card; + char dbf_text[15]; + + card=(qeth_card_t*)(dev->priv); + + sprintf(dbf_text,"mtu %4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"%8x",new_mtu); + QETH_DBF_TEXT2(0,trace,dbf_text); + + if (new_mtu<64) return -EINVAL; + if (new_mtu>65535) return -EINVAL; + if ((!qeth_is_supported(IPA_IP_FRAGMENTATION)) && + (!qeth_mtu_is_valid(card,new_mtu))) + return -EINVAL; + dev->mtu=new_mtu; + return 0; +} + +static void qeth_start_softsetup_thread(qeth_card_t *card) +{ + char dbf_text[15]; + if (!atomic_read(&card->shutdown_phase)) { + sprintf(dbf_text,"stss%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + up(&card->softsetup_thread_sem); + } +} + +static int qeth_sleepon(qeth_card_t *card,int timeout) +{ + unsigned long flags; + unsigned long start; + int retval; + char dbf_text[15]; + + DECLARE_WAITQUEUE (current_wait_q,current); + + sprintf(dbf_text,"slpn%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"%08x",timeout); + QETH_DBF_TEXT5(0,trace,dbf_text); + + add_wait_queue(&card->wait_q,¤t_wait_q); + atomic_set(&card->wait_q_active,1); + start=qeth_get_millis(); + for (;;) { + set_task_state(current,TASK_INTERRUPTIBLE); + if (atomic_read(&card->data_has_arrived)) { + atomic_set(&card->data_has_arrived,0); + retval=0; + goto out; + } + if (qeth_get_millis()-start>timeout) { + retval=-ETIME; + goto out; + } + schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ); + } + out: + spin_lock_irqsave(&card->wait_q_lock,flags); + atomic_set(&card->wait_q_active,0); + spin_unlock_irqrestore(&card->wait_q_lock,flags); + + /* we've got to check once again to close the window */ + if (atomic_read(&card->data_has_arrived)) { + atomic_set(&card->data_has_arrived,0); + retval=0; + } + + set_task_state(current,TASK_RUNNING); + remove_wait_queue(&card->wait_q,¤t_wait_q); + + return retval; +} + +static void qeth_wakeup_ioctl(qeth_card_t *card) { + char dbf_text[15]; + + sprintf(dbf_text,"wkup%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + + atomic_set(&card->ioctl_data_has_arrived,1); + spin_lock(&card->ioctl_wait_q_lock); + if (atomic_read(&card->ioctl_wait_q_active)) { + wake_up(&card->ioctl_wait_q); + } + spin_unlock(&card->ioctl_wait_q_lock); +} + +static int qeth_sleepon_ioctl(qeth_card_t *card,int timeout) +{ + unsigned long flags; + unsigned long start; + int retval; + char dbf_text[15]; + + DECLARE_WAITQUEUE (current_wait_q,current); + + sprintf(dbf_text,"ioctlslpn%4x",card->irq0); + QETH_DBF_TEXT5(0,trace,dbf_text); + sprintf(dbf_text,"%08x",timeout); + QETH_DBF_TEXT5(0,trace,dbf_text); + + save_flags(flags); + add_wait_queue(&card->ioctl_wait_q,¤t_wait_q); + atomic_set(&card->ioctl_wait_q_active,1); + start=qeth_get_millis(); + for (;;) { + set_task_state(current,TASK_INTERRUPTIBLE); + if (atomic_read(&card->ioctl_data_has_arrived)) { + atomic_set(&card->ioctl_data_has_arrived,0); + retval=0; + goto out; + } + if (qeth_get_millis()-start>timeout) { + retval=-ETIME; + goto out; + } + schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ); + } + out: + spin_lock_irqsave(&card->ioctl_wait_q_lock,flags); + atomic_set(&card->ioctl_wait_q_active,0); + spin_unlock_irqrestore(&card->ioctl_wait_q_lock,flags); + + /* we've got to check once again to close the window */ + if (atomic_read(&card->ioctl_data_has_arrived)) { + atomic_set(&card->ioctl_data_has_arrived,0); + retval=0; + } + + set_task_state(current,TASK_RUNNING); + remove_wait_queue(&card->ioctl_wait_q,¤t_wait_q); + + return retval; +} + +static void qeth_wakeup_procfile(void) +{ + QETH_DBF_TEXT5(0,trace,"procwkup"); + if (atomic_read(&qeth_procfile_ioctl_sem.count)< + PROCFILE_SLEEP_SEM_MAX_VALUE) + up(&qeth_procfile_ioctl_sem); +} + + +static int qeth_sleepon_procfile(void) +{ + QETH_DBF_TEXT5(0,trace,"procslp"); + if (down_interruptible(&qeth_procfile_ioctl_sem)) { + up(&qeth_procfile_ioctl_sem); + return -ERESTARTSYS; + } + return 0; +} + +static char* qeth_send_control_data(qeth_card_t *card,unsigned char *buffer, + int len,unsigned long intparam) +{ + unsigned long flags; + int result,result2; + char dbf_text[15]; + unsigned char *rec_buf; + int setip=(intparam&IPA_SETIP_FLAG)?1:0; + +again: + if (atomic_read(&card->shutdown_phase)== + QETH_REMOVE_CARD_QUICK) return NULL; + if (atomic_read(&card->escape_softsetup)) + return NULL; + + /* we lock very early to synchronize access to seqnos */ + if (atomic_swap(&card->write_busy,1)) { + qeth_wait_nonbusy(QETH_IDLE_WAIT_TIME); + sprintf(dbf_text,"LSCD%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + goto again; + } + memcpy(card->dma_stuff->sendbuf,card->send_buf,QETH_BUFSIZE); + + memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(buffer), + &card->seqno.trans_hdr,QETH_SEQ_NO_LENGTH); + card->seqno.trans_hdr++; + + memcpy(QETH_PDU_HEADER_SEQ_NO(buffer), + &card->seqno.pdu_hdr,QETH_SEQ_NO_LENGTH); + card->seqno.pdu_hdr++; + memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(buffer), + &card->seqno.pdu_hdr_ack,QETH_SEQ_NO_LENGTH); + + /* there is noone doing this except sleep and this function */ + atomic_set(&card->data_has_arrived,0); + + memcpy(&card->dma_stuff->write_ccw,WRITE_CCW,sizeof(ccw1_t)); + card->dma_stuff->write_ccw.count=len; + card->dma_stuff->write_ccw.cda= + QETH_GET_ADDR(card->dma_stuff->sendbuf); + + sprintf(dbf_text,"scdw%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"%8x",len); + QETH_DBF_TEXT4(0,trace,dbf_text); + QETH_DBF_HEX4(0,trace,&intparam,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,control,buffer,QETH_DBF_CONTROL_LEN); + + s390irq_spin_lock_irqsave(card->irq1,flags); + result=do_IO(card->irq1,&card->dma_stuff->write_ccw,intparam,0,0); + if (result) { + qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); + result2=do_IO(card->irq1,&card->dma_stuff->write_ccw, + intparam,0,0); + if (result2!=-ENODEV) + PRINT_WARN("qeth_send_control_data: do_IO " \ + "returned %i, next try returns %i\n", + result,result2); + result=result2; + } + s390irq_spin_unlock_irqrestore(card->irq1,flags); + + if (result) { + QETH_DBF_TEXT2(0,trace,"scd:doio"); + sprintf(dbf_text,"%4x",(__s16)result); + QETH_DBF_TEXT2(0,trace,dbf_text); + return NULL; + } + + if (intparam==IPA_IOCTL_STATE) { + if (qeth_sleepon_ioctl(card,QETH_IPA_TIMEOUT)) { + QETH_DBF_TEXT2(0,trace,"scd:ioctime"); + /* re-enable qeth_send_control_data again */ + atomic_set(&card->write_busy,0); + return NULL; + } + rec_buf=card->ipa_buf; + sprintf(dbf_text,"scro%4x",card->irq0); + } else { + if (qeth_sleepon(card,(setip)?QETH_IPA_TIMEOUT: + QETH_MPC_TIMEOUT)) { + QETH_DBF_TEXT2(0,trace,"scd:time"); + /* re-enable qeth_send_control_data again */ + atomic_set(&card->write_busy,0); + return NULL; + } + rec_buf=card->ipa_buf; + sprintf(dbf_text,"scri%4x",card->irq0); + } + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_HEX2(0,control,rec_buf,QETH_DBF_CONTROL_LEN); + + memcpy(&card->seqno.pdu_hdr_ack, + QETH_PDU_HEADER_SEQ_NO(rec_buf), + QETH_SEQ_NO_LENGTH); + + return rec_buf; +} + +static int qeth_send_ipa_cmd(qeth_card_t *card,ipa_cmd_t *cmd,int update_cmd, + int ipatype) +{ + unsigned char *buffer; + ipa_cmd_t *reply; + int ipa_cmd; + int result; + + /* don't muck around with ipv6 if there's no use to do so */ + if ( (cmd->prot_version==6) && + (!qeth_is_supported(IPA_IPv6)) ) return 0; + + ipa_cmd=cmd->command; + + memcpy(card->send_buf,IPA_PDU_HEADER, + IPA_PDU_HEADER_SIZE); + + memcpy(QETH_IPA_CMD_DEST_ADDR(card->send_buf), + &card->token.ulp_connection_r,QETH_MPC_TOKEN_LENGTH); + + memcpy(card->send_buf+IPA_PDU_HEADER_SIZE, + cmd,sizeof(ipa_cmd_t)); + + buffer=qeth_send_control_data(card,card->send_buf, + IPA_PDU_HEADER_SIZE+sizeof(ipa_cmd_t), + ipatype); + + if (!buffer) { + if (atomic_read(&card->escape_softsetup)) result=0; + else result=-1; + } else { + reply=(ipa_cmd_t*)PDU_ENCAPSULATION(buffer); + if ((update_cmd)&&(reply)) memcpy(cmd,reply,sizeof(ipa_cmd_t)); + result=reply->return_code; + + if ((ipa_cmd==IPA_CMD_SETASSPARMS)&&(result==0)) { + result=reply->data.setassparms.return_code; + } + if ((ipa_cmd==IPA_CMD_SETADAPTERPARMS)&&(result==0)) { + result=reply->data.setadapterparms.return_code; + } + } + return result; +} + +static void qeth_fill_ipa_cmd(qeth_card_t *card,ipa_cmd_t *cmd, + __u8 command,int ip_vers) +{ + memset(cmd,0,sizeof(ipa_cmd_t)); + cmd->command=command; + cmd->initiator=INITIATOR_HOST; + cmd->seq_no=card->seqno.ipa++; + cmd->adapter_type=qeth_get_adapter_type_for_ipa(card->link_type); + cmd->rel_adapter_no=(__u8)card->options.portno; + cmd->prim_version_no=1; + cmd->param_count=1; + cmd->prot_version=ip_vers; + cmd->ipa_supported=0; + cmd->ipa_enabled=0; +} + +static int qeth_send_startstoplan(qeth_card_t *card,__u8 ipacmd,__u16 ip_vers) +{ + ipa_cmd_t cmd; + int result; + + qeth_fill_ipa_cmd(card,&cmd,ipacmd,0); + cmd.param_count=0; + cmd.prot_version=ip_vers; + cmd.ipa_supported=0; + cmd.ipa_enabled=0; + + result=qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE); + return result; +} + +static int qeth_send_startlan(qeth_card_t *card,__u16 ip_vers) +{ + int result; + char dbf_text[15]; + + sprintf(dbf_text,"stln%4x",card->irq0); + QETH_DBF_TEXT4(0,trace,dbf_text); + + result=qeth_send_startstoplan(card,IPA_CMD_STARTLAN,ip_vers); + if (!result) atomic_set(&card->is_startlaned,1); + + if (result) { + QETH_DBF_TEXT2(0,trace,"STRTLNFL"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + } + + return result; +} + +static int qeth_send_stoplan(qeth_card_t *card) +{ +#ifdef QETH_SEND_STOPLAN_ON_SHUTDOWN + int result; + char dbf_text[15]; + + atomic_set(&card->is_startlaned,0); + + sprintf(dbf_text,"spln%4x",card->irq0); + QETH_DBF_TEXT4(0,trace,dbf_text); + + result=qeth_send_startstoplan(card,IPA_CMD_STOPLAN,4); + + if (result) { + QETH_DBF_TEXT2(0,trace,"STPLNFLD"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + } + + return result; +#else /* QETH_SEND_STOPLAN_ON_SHUTDOWN */ + return 0; +#endif /* QETH_SEND_STOPLAN_ON_SHUTDOWN */ +} + +static int qeth_send_qipassist(qeth_card_t *card,short ip_vers) +{ + ipa_cmd_t cmd; + int result; + + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_QIPASSIST,ip_vers); + + result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE); + + if (!result) { + if (ip_vers==4) { + card->ipa_supported=cmd.ipa_supported; + card->ipa_enabled=cmd.ipa_enabled; + } else { + card->ipa6_supported=cmd.ipa_supported; + card->ipa6_enabled=cmd.ipa_enabled; + } + } + + return result; +} + +static int qeth_send_ipa_arpcmd(qeth_card_t *card,arp_cmd_t *cmd, + int update_cmd,int ipatype,__u32 req_size) +{ + unsigned char *buffer; + int ipa_cmd; + int result; + __u16 s1,s2; + + /* don't muck around with ipv6 if there's no use to do so */ + if ( (cmd->prot_version==6) && + (!qeth_is_supported(IPA_IPv6)) ) return 0; + result = 0; + ipa_cmd=cmd->command; + + memcpy(card->send_buf,IPA_PDU_HEADER, + IPA_PDU_HEADER_SIZE); + memcpy(QETH_IPA_CMD_DEST_ADDR(card->send_buf), + &card->token.ulp_connection_r,QETH_MPC_TOKEN_LENGTH); + memcpy(card->send_buf+IPA_PDU_HEADER_SIZE, + cmd,sizeof(arp_cmd_t)); + + if (req_size) { + /* adjust sizes for big requests */ + s1=(__u32)IPA_PDU_HEADER_SIZE+SNMP_BASE_CMDLENGTH+req_size; + s2=(__u32)SNMP_BASE_CMDLENGTH+req_size; + memcpy(QETH_IPA_PDU_LEN_TOTAL(card->send_buf),&s1,2); + memcpy(QETH_IPA_PDU_LEN_PDU1(card->send_buf),&s2,2); + memcpy(QETH_IPA_PDU_LEN_PDU2(card->send_buf),&s2,2); + memcpy(QETH_IPA_PDU_LEN_PDU3(card->send_buf),&s2,2); + } + + buffer=qeth_send_control_data(card,card->send_buf, + IPA_PDU_HEADER_SIZE+sizeof(arp_cmd_t), + ipatype); + if (!buffer) + result = -ENODATA; + else + result = card->ioctl_returncode; + return result; +} + +static int qeth_ioctl_handle_snmp_data(qeth_card_t *card,arp_cmd_t *reply) +{ + __u16 data_len; + +#define SNMP_HEADER_SIZE_WITH_TOKEN 36 + + data_len = *((__u16*)QETH_IPA_PDU_LEN_PDU1(card->dma_stuff->recbuf)); + + if (reply->data.setadapterparms.frame_seq_no == 1) { + data_len = data_len - + (__u16)((char*)reply->data.setadapterparms. + data.snmp_subcommand. + snmp_data - (char*)reply); + } else { + data_len = data_len - + (__u16)((char*)&reply->data.setadapterparms.data. + snmp_subcommand. + snmp_request - (char*)reply); + } + if (reply->data.setadapterparms.frame_seq_no == 1) { + if (card->ioctl_buffersize <= (SNMP_HEADER_SIZE_WITH_TOKEN + + reply->data.setadapterparms.frames_used_total * + ARP_DATA_SIZE)) { + card->ioctl_returncode = ARP_RETURNCODE_ERROR; + reply->data.setadapterparms.data. + snmp_subcommand.snmp_returncode = -ENOMEM; + } else { + card->ioctl_returncode = ARP_RETURNCODE_SUCCESS; + card->number_of_entries = 0; + memcpy(((char *)card->ioctl_data_buffer), + reply->data.setadapterparms.snmp_token, + SNMP_HEADER_SIZE_WITH_TOKEN); + card->ioctl_buffer_pointer = card->ioctl_data_buffer+ + SNMP_HEADER_SIZE_WITH_TOKEN; + } + } + + if (card->ioctl_returncode != ARP_RETURNCODE_ERROR && + reply->data.setadapterparms.frame_seq_no <= + reply->data.setadapterparms.frames_used_total) { + if (reply->data.setadapterparms.return_code== + IPA_REPLY_SUCCESS) { + if (reply->data.setadapterparms.frame_seq_no == 1) { + memcpy(card->ioctl_buffer_pointer, + reply->data.setadapterparms.data. + snmp_subcommand.snmp_data,data_len); + } else { + memcpy(card->ioctl_buffer_pointer, + (char*)&reply->data.setadapterparms. + data.snmp_subcommand. + snmp_request,data_len); + } + card->ioctl_buffer_pointer = + card->ioctl_buffer_pointer + data_len; + card->ioctl_returncode = ARP_RETURNCODE_SUCCESS; + + if (reply->data.setadapterparms.frame_seq_no == + reply->data.setadapterparms.frames_used_total) { + card->ioctl_returncode = + ARP_RETURNCODE_LASTREPLY; + } + } else { + card->ioctl_returncode = ARP_RETURNCODE_ERROR; + memset(card->ioctl_data_buffer,0, + card->ioctl_buffersize); + reply->data.setadapterparms.data. + snmp_subcommand.snmp_returncode = + reply->data.setadapterparms.return_code; + } + } +#undef SNMP_HEADER_SIZE_WITH_TOKEN + + return card->ioctl_returncode; +} + +static int qeth_ioctl_handle_arp_data(qeth_card_t *card, arp_cmd_t *reply) +{ + if (reply->data.setassparms.seq_no == 1) { + if (card->ioctl_buffersize <= + (sizeof(__u16) + sizeof(int) + reply->data. + setassparms.number_of_replies * ARP_DATA_SIZE)) { + card->ioctl_returncode = ARP_RETURNCODE_ERROR; + } else { + card->ioctl_returncode = ARP_RETURNCODE_SUCCESS; + card->number_of_entries = 0; + card->ioctl_buffer_pointer = card->ioctl_data_buffer+ + sizeof(__u16) + sizeof(int); + } + } + + if (card->ioctl_returncode != ARP_RETURNCODE_ERROR && + reply->data.setassparms.seq_no <= + reply->data.setassparms.number_of_replies) { + + if (reply->data.setassparms.return_code==IPA_REPLY_SUCCESS) { + + card->number_of_entries = card->number_of_entries + + reply->data.setassparms. + data.queryarp_data. + number_of_entries; + memcpy(card->ioctl_buffer_pointer, + reply->data.setassparms.data.queryarp_data. + arp_data,ARP_DATA_SIZE); + card->ioctl_buffer_pointer = card-> + ioctl_buffer_pointer + ARP_DATA_SIZE; + card->ioctl_returncode = ARP_RETURNCODE_SUCCESS; + if (reply->data.setassparms.seq_no == + reply->data.setassparms.number_of_replies) { + memcpy(card->ioctl_data_buffer, + &reply->data.setassparms.data. + queryarp_data.osa_setbitmask, + sizeof(__u16)); + card->ioctl_returncode= + ARP_RETURNCODE_LASTREPLY; + } + } else { + card->ioctl_returncode = ARP_RETURNCODE_ERROR; + memset(card->ioctl_data_buffer,0, + card->ioctl_buffersize); + } + } + return card->ioctl_returncode; +} + +static int qeth_look_for_arp_data(qeth_card_t *card) +{ + arp_cmd_t *reply; + int result; + + + reply=(arp_cmd_t*)PDU_ENCAPSULATION(card->dma_stuff->recbuf); + + if ( (reply->command==IPA_CMD_SETASSPARMS) && + (reply->data.setassparms.assist_no==IPA_ARP_PROCESSING) && + (reply->data.setassparms.command_code== + IPA_CMD_ASS_ARP_FLUSH_CACHE) ) { + result=ARP_FLUSH; + } else if ( (reply->command == IPA_CMD_SETASSPARMS) && + (reply->data.setassparms.assist_no == IPA_ARP_PROCESSING) && + (reply->data.setassparms.command_code == + IPA_CMD_ASS_ARP_QUERY_INFO) && + (card->ioctl_returncode == ARP_RETURNCODE_SUCCESS)) { + result = qeth_ioctl_handle_arp_data(card,reply); + } else if ( (reply->command == IPA_CMD_SETADAPTERPARMS) && + (reply->data.setadapterparms.command_code == + IPA_SETADP_SET_SNMP_CONTROL) && + (card->ioctl_returncode == ARP_RETURNCODE_SUCCESS) ){ + result = qeth_ioctl_handle_snmp_data(card,reply); + } else + result = ARP_RETURNCODE_NOARPDATA; + + return result; +} + + + +static int qeth_queryarp(qeth_card_t *card,struct ifreq *req,int version, + __u32 assist_no, __u16 command_code,char *c_data, + __u16 len) +{ + int data_size; + arp_cmd_t *cmd; + int result; + + + cmd = (arp_cmd_t *) kmalloc(sizeof(arp_cmd_t),GFP_KERNEL); + if (!cmd) { + return IPA_REPLY_FAILED; + } + + memcpy(&data_size,c_data,sizeof(int)); + + qeth_fill_ipa_cmd(card,(ipa_cmd_t*)cmd,IPA_CMD_SETASSPARMS,version); + + cmd->data.setassparms.assist_no=assist_no; + cmd->data.setassparms.length=8+len; + cmd->data.setassparms.command_code=command_code; + cmd->data.setassparms.return_code=0; + cmd->data.setassparms.seq_no=0; + + card->ioctl_buffersize = data_size; + card->ioctl_data_buffer = (char *) vmalloc(data_size); + if (!card->ioctl_data_buffer) { + kfree(cmd); + return IPA_REPLY_FAILED; + } + + card->ioctl_returncode = ARP_RETURNCODE_SUCCESS; + + result=qeth_send_ipa_arpcmd(card,cmd,1,IPA_IOCTL_STATE,0); + + if ((result == ARP_RETURNCODE_ERROR) || + (result == -ENODATA)) { + result = IPA_REPLY_FAILED; + } + else { + result = IPA_REPLY_SUCCESS; + memcpy(((char *)(card->ioctl_data_buffer)) + sizeof(__u16), + &(card->number_of_entries),sizeof(int)); + copy_to_user(req->ifr_ifru.ifru_data, + card->ioctl_data_buffer,data_size); + } + card->ioctl_buffer_pointer = NULL; + vfree(card->ioctl_data_buffer); + kfree(cmd); + card->number_of_entries = 0; + card->ioctl_buffersize = 0; + + return result; +} + +static int snmp_set_setadapterparms_command(qeth_card_t *card, + arp_cmd_t *cmd,struct ifreq *req, + char *data,__u16 len, + __u16 command_code,int req_size) +{ + __u32 data_size; + + memcpy(&data_size,data,sizeof(__u32)); + + card->ioctl_buffersize = data_size; + card->ioctl_data_buffer = (char *) vmalloc(data_size); + if (!card->ioctl_data_buffer) { + return -ENOMEM; + } + card->ioctl_returncode = ARP_RETURNCODE_SUCCESS; + + memcpy(cmd->data.setadapterparms.snmp_token, + data+SNMP_REQUEST_DATA_OFFSET,req_size); + + cmd->data.setadapterparms.cmdlength=SNMP_SETADP_CMDLENGTH+req_size; + cmd->data.setadapterparms.command_code = command_code; + cmd->data.setadapterparms.frames_used_total=1; + cmd->data.setadapterparms.frame_seq_no=1; + + return 0; +} + +static int qeth_send_snmp_control(qeth_card_t *card,struct ifreq *req, + __u32 command,__u16 command_code, + char *c_data,__u16 len) +{ + arp_cmd_t *cmd; + __u32 result,req_size; + + cmd = (arp_cmd_t *) kmalloc(sizeof(arp_cmd_t),GFP_KERNEL); + if (!cmd) { + return IPA_REPLY_FAILED; + } + + qeth_fill_ipa_cmd(card,(ipa_cmd_t*)cmd,command,4); + + memcpy(&req_size,((char*)c_data)+sizeof(__u32),sizeof(__u32)); + + if (snmp_set_setadapterparms_command(card,cmd,req,c_data, + len,command_code,req_size)) + { + kfree(cmd); + return IPA_REPLY_FAILED; + } + + result=qeth_send_ipa_arpcmd(card,cmd,1,IPA_IOCTL_STATE,req_size); + + if (result == -ENODATA) { + result = IPA_REPLY_FAILED; + goto snmp_out; + } + if (result == ARP_RETURNCODE_ERROR ) { + copy_to_user(req->ifr_ifru.ifru_data+SNMP_REQUEST_DATA_OFFSET, + card->ioctl_data_buffer,card->ioctl_buffersize); + result = IPA_REPLY_FAILED; + } + else { + copy_to_user(req->ifr_ifru.ifru_data+SNMP_REQUEST_DATA_OFFSET, + card->ioctl_data_buffer,card->ioctl_buffersize); + result = IPA_REPLY_SUCCESS; + } +snmp_out: + card->number_of_entries = 0; + card->ioctl_buffersize = 0; + card->ioctl_buffer_pointer = NULL; + vfree(card->ioctl_data_buffer); + kfree(cmd); + + return result; +} + +static int qeth_send_setassparms(qeth_card_t *card,int version, + __u32 assist_no,__u16 command_code, + long data,__u16 len) +{ + ipa_cmd_t cmd; + int result; + + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETASSPARMS,version); + + cmd.data.setassparms.assist_no=assist_no; + cmd.data.setassparms.length=8+len; + cmd.data.setassparms.command_code=command_code; + cmd.data.setassparms.return_code=0; + cmd.data.setassparms.seq_no=0; + + if (len<=sizeof(__u32)) + cmd.data.setassparms.data.flags_32bit=(__u32)data; + else if (len>sizeof(__u32)) + memcpy(&cmd.data.setassparms.data,(void*)data, + /* limit here to a page or so */ + qeth_min(len,PAGE_SIZE)); + if (command_code != IPA_CMD_ASS_START) { + result=qeth_send_ipa_cmd(card,&cmd,0, + ((assist_no==IPA_ARP_PROCESSING)&& + (command_code!=IPA_CMD_ASS_ARP_FLUSH_CACHE))? + IPA_IOCTL_STATE:IPA_CMD_STATE); + + } else + result=qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE); + + return result; +} + +static int qeth_send_setadapterparms_query(qeth_card_t *card) +{ + ipa_cmd_t cmd; + int result; + + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETADAPTERPARMS, + IPA_SETADAPTERPARMS_IP_VERSION); + cmd.data.setadapterparms.cmdlength=sizeof(struct ipa_setadp_cmd); + cmd.data.setadapterparms.command_code= + IPA_SETADP_QUERY_COMMANDS_SUPPORTED; + cmd.data.setadapterparms.frames_used_total=1; + cmd.data.setadapterparms.frame_seq_no=1; + result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE); + + if (cmd.data.setadapterparms.data.query_cmds_supp.lan_type&0x7f) + card->link_type=cmd.data.setadapterparms.data. + query_cmds_supp.lan_type; + + card->adp_supported= + cmd.data.setadapterparms.data.query_cmds_supp.supported_cmds; + + return result; +} + +static int qeth_send_setadapterparms_mode(qeth_card_t *card,__u32 command, + __u32 mode) +{ + ipa_cmd_t cmd; + int result; + + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETADAPTERPARMS, + IPA_SETADAPTERPARMS_IP_VERSION); + cmd.data.setadapterparms.cmdlength=sizeof(struct ipa_setadp_cmd); + cmd.data.setadapterparms.command_code=command; + cmd.data.setadapterparms.frames_used_total=1; + cmd.data.setadapterparms.frame_seq_no=1; + cmd.data.setadapterparms.data.mode=mode; + result=qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE); + + return result; +} + +static int qeth_send_setadapterparms_change_addr(qeth_card_t *card, + __u32 command, + __u32 subcmd,__u8 *mac_addr, + int addr_len) +{ + ipa_cmd_t cmd; + int result; + + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETADAPTERPARMS, + IPA_SETADAPTERPARMS_IP_VERSION); + cmd.data.setadapterparms.cmdlength=sizeof(struct ipa_setadp_cmd); + cmd.data.setadapterparms.command_code=command; + cmd.data.setadapterparms.frames_used_total=1; + cmd.data.setadapterparms.frame_seq_no=1; + cmd.data.setadapterparms.data.change_addr.cmd=subcmd; + cmd.data.setadapterparms.data.change_addr.addr_size=addr_len; + memcpy(&cmd.data.setadapterparms.data.change_addr.addr, + mac_addr,addr_len); + + result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE); + + memcpy(mac_addr,&cmd.data.setadapterparms.data.change_addr.addr, + addr_len); + + return result; +} + +static int qeth_send_setassparms_simple_with_data(qeth_card_t *card, + __u32 assist_no, + __u16 command_code, + long data) +{ + return qeth_send_setassparms(card,4,assist_no,command_code,data,4); +} + +static int qeth_send_setassparms_simple_without_data(qeth_card_t *card, + __u32 assist_no, + __u16 command_code) +{ + return qeth_send_setassparms(card,4,assist_no,command_code,0,0); +} + +static int qeth_send_setassparms_simple_without_data6(qeth_card_t *card, + __u32 assist_no, + __u16 command_code) +{ + return qeth_send_setassparms(card,6,assist_no,command_code,0,0); +} + +static int qeth_send_setdelip(qeth_card_t *card,__u8 *ip,__u8 *netmask, + int ipacmd,short ip_vers,unsigned int flags) +{ + ipa_cmd_t cmd; + int ip_len=(ip_vers==6)?16:4; + + qeth_fill_ipa_cmd(card,&cmd,ipacmd,ip_vers); + if (ip_vers==6) { + memcpy(&cmd.data.setdelip6.ip,ip,ip_len); + memcpy(&cmd.data.setdelip6.netmask,netmask,ip_len); + cmd.data.setdelip6.flags=flags; + } else { + memcpy(&cmd.data.setdelip4.ip,ip,ip_len); + memcpy(&cmd.data.setdelip4.netmask,netmask,ip_len); + cmd.data.setdelip4.flags=flags; + } + + return qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE| + ((ipacmd==IPA_CMD_SETIP)?IPA_SETIP_FLAG:0)); +} + +static int qeth_send_setdelipm(qeth_card_t *card,__u8 *ip,__u8 *mac, + int ipacmd,short ip_vers) +{ + ipa_cmd_t cmd; + int ip_len=(ip_vers==6)?16:4; + + qeth_fill_ipa_cmd(card,&cmd,ipacmd,ip_vers); + memcpy(&cmd.data.setdelipm.mac,mac,6); + if (ip_vers==6) { + memcpy(&cmd.data.setdelipm.ip6,ip,ip_len); + } else { + memcpy(&cmd.data.setdelipm.ip4_6,ip,ip_len); + } + + return qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE| + ((ipacmd==IPA_CMD_SETIPM)?IPA_SETIP_FLAG:0)); +} + +#define PRINT_SETIP_ERROR(x) \ + if (result) \ + PRINT_ERR("setip%c: return code 0x%x (%s)\n",x,result, \ + (result==0xe002)?"invalid mtu size": \ + (result==0xe005)?"duplicate ip address": \ + (result==0xe0a5)?"duplicate ip address": \ + (result==0xe006)?"ip table full": \ + (result==0xe008)?"startlan not received": \ + (result==0xe009)?"setip already received": \ + (result==0xe00a)?"dup network ip address": \ + (result==0xe00b)?"mblk no free main task entry": \ + (result==0xe00d)?"invalid ip version": \ + (result==0xe00e)?"unsupported arp assist cmd": \ + (result==0xe00f)?"arp assist not enabled": \ + (result==0xe080)?"startlan disabled": \ + (result==-1)?"IPA communication timeout": \ + "unknown return code") + +static inline int qeth_send_setip(qeth_card_t *card,__u8 *ip, + __u8 *netmask,short ip_vers,int use_retries) +{ + int result; + int retries; + char dbf_text[15]; + int takeover=0; + + retries=(use_retries)?QETH_SETIP_RETRIES:1; + if (qeth_is_ipa_covered_by_ipato_entries(ip_vers,ip,card)) { + sprintf(dbf_text,"ipto%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + if (ip_vers==4) { + *((__u32*)(&dbf_text[0]))=*((__u32*)ip); + *((__u32*)(&dbf_text[4]))=*((__u32*)netmask); + QETH_DBF_HEX2(0,trace,dbf_text,QETH_DBF_TRACE_LEN); + } else { + QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,netmask,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,netmask+QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + } + takeover=1; + } +retry: + result=qeth_send_setdelip(card,ip,netmask,IPA_CMD_SETIP,ip_vers, + (takeover)?IPA_SETIP_TAKEOVER_FLAGS: + IPA_SETIP_FLAGS); + PRINT_SETIP_ERROR(' '); + + if (result) { + QETH_DBF_TEXT2(0,trace,"SETIPFLD"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + } + + if (((result==-1)||(result==0xe080))&&(retries--)) { + sprintf(dbf_text,"sipr%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + if (ip_vers==4) { + *((__u32*)(&dbf_text[0]))=*((__u32*)ip); + *((__u32*)(&dbf_text[4]))=*((__u32*)netmask); + QETH_DBF_HEX2(0,trace,dbf_text,QETH_DBF_TRACE_LEN); + } else { + QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,netmask,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,netmask+QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + } + PRINT_WARN("trying again...\n"); + goto retry; + } + + return result; +} + +static inline int qeth_send_delip(qeth_card_t *card,__u8 *ip, + __u8 *netmask,short ip_vers) +{ + return qeth_send_setdelip(card,ip,netmask,IPA_CMD_DELIP,ip_vers, + IPA_DELIP_FLAGS); +} + +static inline int qeth_send_setipm(qeth_card_t *card,__u8 *ip, + __u8 *mac,short ip_vers,int use_retries) +{ + int result; + int retries; + char dbf_text[15]; + + retries=(use_retries)?QETH_SETIP_RETRIES:1; + if (qeth_is_ipa_covered_by_ipato_entries(ip_vers,ip,card)) { + sprintf(dbf_text,"imto%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + if (ip_vers==4) { + *((__u32*)(&dbf_text[0]))=*((__u32*)ip); + QETH_DBF_HEX2(0,trace,dbf_text,QETH_DBF_TRACE_LEN); + } else { + QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + } + } + +retry: + result=qeth_send_setdelipm(card,ip,mac,IPA_CMD_SETIPM,ip_vers); + PRINT_SETIP_ERROR('m'); + + if (result) { + QETH_DBF_TEXT2(0,trace,"SETIMFLD"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + } + + if ((result==-1)&&(retries--)) { + sprintf(dbf_text,"simr%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + if (ip_vers==4) { + sprintf(dbf_text,"%08x",*((__u32*)ip)); + QETH_DBF_TEXT2(0,trace,dbf_text); + } else { + QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + } + QETH_DBF_HEX2(0,trace,mac,OSA_ADDR_LEN); + PRINT_WARN("trying again...\n"); + goto retry; + } + + return result; +} + +static inline int qeth_send_delipm(qeth_card_t *card,__u8 *ip, + __u8 *mac,short ip_vers) +{ + return qeth_send_setdelipm(card,ip,mac,IPA_CMD_DELIPM,ip_vers); +} + +static int qeth_add_vipa_entry(qeth_card_t *card,int version,__u8 *addr, + int flag) +{ + qeth_vipa_entry_t *entry,*e; + int result=0; + + entry=(qeth_vipa_entry_t*)kmalloc(sizeof(qeth_vipa_entry_t), + GFP_KERNEL); + if (!entry) { + PRINT_ERR("not enough memory for vipa handling\n"); + return -ENOMEM; + } + entry->version=version; + entry->flag=flag; + memcpy(entry->ip,addr,16); + entry->state=VIPA_2_B_ADDED; + + my_write_lock(&card->vipa_list_lock); + e=card->vipa_list; + while (e) { + if (e->version!=version) goto next; + if (memcmp(e->ip,addr,(version==4)?4:16)) goto next; + if (flag==IPA_SETIP_VIPA_FLAGS) { + PRINT_ERR("vipa already set\n"); + } else { + PRINT_ERR("rxip already set\n"); + } + kfree(entry); + result=-EALREADY; + goto out; +next: + e=e->next; + } + entry->next=card->vipa_list; + card->vipa_list=entry; +out: + my_write_unlock(&card->vipa_list_lock); + return result; +} + +static int qeth_del_vipa_entry(qeth_card_t *card,int version,__u8 *addr, + int flag) +{ + qeth_vipa_entry_t *e; + int result=0; + + my_write_lock(&card->vipa_list_lock); + e=card->vipa_list; + while (e) { + if (e->version!=version) goto next; + if (e->flag!=flag) goto next; + if (memcmp(e->ip,addr,(version==4)?4:16)) goto next; + e->state=VIPA_2_B_REMOVED; + goto out; +next: + e=e->next; + } + if (flag==IPA_SETIP_VIPA_FLAGS) { + PRINT_ERR("vipa not found\n"); + } else { + PRINT_ERR("rxip not found\n"); + } + result=-ENOENT; +out: + my_write_unlock(&card->vipa_list_lock); + return result; +} + +static void qeth_set_vipas(qeth_card_t *card,int set_only) +{ + qeth_vipa_entry_t *e,*le=NULL,*ne; /* ne stands for new entry, + le is last entry */ + char dbf_text[15]; + int result; + __u8 netmask[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; + qeth_vipa_entry_t *priv_add_list=NULL; + qeth_vipa_entry_t *priv_del_list=NULL; + + my_write_lock(&card->vipa_list_lock); + e=card->vipa_list; + while (e) { + switch (e->state) { + case VIPA_2_B_ADDED: + if (!set_only) break; + if (!atomic_read(&card->is_open)) break; + /* we don't want to hold the lock for a long time... + * so we clone the entry */ + ne=(qeth_vipa_entry_t*) + kmalloc(sizeof(qeth_vipa_entry_t), + GFP_KERNEL); + if (ne) { + ne->version=e->version; + memcpy(ne->ip,e->ip,16); + ne->next=priv_add_list; + priv_add_list=ne; + + e->state=VIPA_ESTABLISHED; + } else { + PRINT_ERR("not enough for internal vipa " \ + "handling... trying to set " \ + "vipa next time.\n"); + qeth_start_softsetup_thread(card); + } + break; + case VIPA_2_B_REMOVED: + if (set_only) break; + if (le) + le->next=e->next; + else card->vipa_list=e->next; + ne=e->next; + e->next=priv_del_list; + priv_del_list=e; + e=ne; + continue; + case VIPA_ESTABLISHED: + if (atomic_read(&card->is_open)) break; + /* we don't want to hold the lock for a long time... + * so we clone the entry */ + ne=(qeth_vipa_entry_t*) + kmalloc(sizeof(qeth_vipa_entry_t), + GFP_KERNEL); + if (ne) { + ne->version=e->version; + memcpy(ne->ip,e->ip,16); + ne->next=priv_del_list; + priv_del_list=ne; + + e->state=VIPA_2_B_ADDED; + } else { + PRINT_ERR("not enough for internal vipa " \ + "handling... VIPA/RXIP remains set " \ + "although device is stopped.\n"); + qeth_start_softsetup_thread(card); + } + break; + default: + break; + } + le=e; + e=e->next; + } + my_write_unlock(&card->vipa_list_lock); + + while (priv_add_list) { + result=qeth_send_setdelip(card,priv_add_list->ip,netmask, + IPA_CMD_SETIP,priv_add_list->version, + priv_add_list->flag); + PRINT_SETIP_ERROR('s'); + + if (result) { + QETH_DBF_TEXT2(0,trace,"SETSVFLD"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + if (priv_add_list->version==4) { + PRINT_ERR("going to leave vipa/rxip %08x" \ + "unset...\n", + *((__u32*)&priv_add_list->ip[0])); + sprintf(dbf_text,"%08x", + *((__u32*)&priv_add_list->ip[0])); + QETH_DBF_TEXT2(0,trace,dbf_text); + } else { + PRINT_ERR("going to leave vipa/rxip " \ + "%08x%08x%08x%08x unset...\n", + *((__u32*)&priv_add_list->ip[0]), + *((__u32*)&priv_add_list->ip[4]), + *((__u32*)&priv_add_list->ip[8]), + *((__u32*)&priv_add_list->ip[12])); + QETH_DBF_HEX2(0,trace,&priv_add_list->ip[0], + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,&priv_add_list->ip[8], + QETH_DBF_TRACE_LEN); + } + } + e=priv_add_list; + priv_add_list=priv_add_list->next; + kfree(e); + } + + while (priv_del_list) { + result=qeth_send_setdelip(card,priv_del_list->ip,netmask, + IPA_CMD_DELIP,priv_del_list->version, + priv_del_list->flag); + if (result) { + QETH_DBF_TEXT2(0,trace,"DELSVFLD"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + if (priv_del_list->version==4) { + PRINT_ERR("could not delete vipa/rxip " \ + "%08x...\n", + *((__u32*)&priv_del_list->ip[0])); + sprintf(dbf_text,"%08x", + *((__u32*)&priv_del_list->ip[0])); + QETH_DBF_TEXT2(0,trace,dbf_text); + } else { + PRINT_ERR("could not delete vipa/rxip " \ + "%08x%08x%08x%08x...\n", + *((__u32*)&priv_del_list->ip[0]), + *((__u32*)&priv_del_list->ip[4]), + *((__u32*)&priv_del_list->ip[8]), + *((__u32*)&priv_del_list->ip[12])); + QETH_DBF_HEX2(0,trace,&priv_del_list->ip[0], + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX2(0,trace,&priv_del_list->ip[8], + QETH_DBF_TRACE_LEN); + } + } + e=priv_del_list; + priv_del_list=priv_del_list->next; + kfree(e); + } +} + +static void qeth_refresh_vipa_states(qeth_card_t *card) +{ + qeth_vipa_entry_t *e; + + my_write_lock(&card->vipa_list_lock); + e=card->vipa_list; + while (e) { + if (e->state==VIPA_ESTABLISHED) e->state=VIPA_2_B_ADDED; + e=e->next; + } + my_write_unlock(&card->vipa_list_lock); +} + +static inline int qeth_send_setrtg(qeth_card_t *card,int routing_type, + short ip_vers) +{ + ipa_cmd_t cmd; + + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETRTG,ip_vers); + /* strip off RESET_ROUTING_FLAG */ + cmd.data.setrtg.type=(routing_type)&(ROUTER_MASK); + + return qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE); +} + +static int qeth_is_ipa_in_list(struct in_ifaddr *ip,struct in_ifaddr *list) +{ + while (list) { + if (ip->ifa_address==list->ifa_address) return 1; + list=list->ifa_next; + } + return 0; +} + +#ifdef QETH_IPV6 +static int qeth_is_ipa_in_list6(struct inet6_ifaddr *ip, + struct inet6_ifaddr *list) +{ + while (list) { + if (!memcmp(&ip->addr.s6_addr,&list->addr.s6_addr,16)) + return 1; + list=list->if_next; + } + return 0; +} + +static int qeth_add_ifa6_to_list(struct inet6_ifaddr **list, + struct inet6_ifaddr *ifa) +{ + struct inet6_ifaddr *i; + + if (*list==NULL) { + *list=ifa; + } else { + if (qeth_is_ipa_in_list6(ifa,*list)) + return -EALREADY; + i=*list; + while (i->if_next) { + i=i->if_next; + } + i->if_next=ifa; + } + ifa->if_next=NULL; + return 0; +} +#endif /* QETH_IPV6 */ + +static int qeth_add_ifa_to_list(struct in_ifaddr **list,struct in_ifaddr *ifa) +{ + struct in_ifaddr *i; + + if (*list==NULL) { + *list=ifa; + } else { + if (qeth_is_ipa_in_list(ifa,*list)) + return -EALREADY; + i=*list; + while (i->ifa_next) { + i=i->ifa_next; + } + i->ifa_next=ifa; + } + ifa->ifa_next=NULL; + return 0; +} + +static int qeth_setips(qeth_card_t *card,int use_setip_retries) +{ + struct in_ifaddr *addr; + int result; + char dbf_text[15]; +#ifdef QETH_IPV6 + struct inet6_ifaddr *addr6; + __u8 netmask[16]; +#endif /* QETH_IPV6 */ + + sprintf(dbf_text,"stip%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + addr=card->ip_current_state.ip_ifa; + while (addr) { + if (!qeth_is_ipa_in_list(addr,card->ip_new_state.ip_ifa)) { + QETH_DBF_TEXT3(0,trace,"setipdel"); + *((__u32*)(&dbf_text[0]))=*((__u32*)&addr->ifa_address); + *((__u32*)(&dbf_text[4]))=*((__u32*)&addr->ifa_mask); + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); + result=qeth_send_delip(card,(__u8*)&addr->ifa_address, + (__u8*)&addr->ifa_mask,4); + if (result) { + PRINT_ERR("was not able to delete ip " \ + "%08x/%08x on irq x%x " \ + "(result: 0x%x), " \ + "trying to continue\n", + addr->ifa_address, + addr->ifa_mask,card->irq0,result); + sprintf(dbf_text,"stdl%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + } + addr=addr->ifa_next; + } + + addr=card->ip_new_state.ip_ifa; + while (addr) { + if (!qeth_is_ipa_in_list(addr, + card->ip_current_state.ip_ifa)) { + QETH_DBF_TEXT3(0,trace,"setipset"); + *((__u32*)(&dbf_text[0]))= + *((__u32*)&addr->ifa_address); + *((__u32*)(&dbf_text[4]))= + *((__u32*)&addr->ifa_mask); + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); + result=qeth_send_setip(card,(__u8*)&addr->ifa_address, + (__u8*)&addr->ifa_mask,4, + use_setip_retries); + if (result) { + PRINT_ERR("was not able to set ip " \ + "%08x/%08x on irq x%x, trying to " \ + "continue\n", + addr->ifa_address, + addr->ifa_mask,card->irq0); + sprintf(dbf_text,"stst%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + } + addr=addr->ifa_next; + } + +#ifdef QETH_IPV6 +#define FILL_NETMASK(len) { \ + int i,j; \ + for (i=0;i<16;i++) { \ + j=(len)-(i*8); \ + if (j>=8) netmask[i]=0xff; else \ + if (j<=0) netmask[i]=0x0; else \ + netmask[i]=(__u8)(0xFF00>>j); \ + } \ +} + /* here we go with IPv6 */ + addr6=card->ip_current_state.ip6_ifa; + while (addr6) { + if (!qeth_is_ipa_in_list6(addr6,card->ip_new_state.ip6_ifa)) { + QETH_DBF_TEXT3(0,trace,"setipdl6"); + QETH_DBF_HEX3(0,trace,&addr6->addr.s6_addr, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX3(0,trace, + ((char *)(&addr6->addr.s6_addr))+ + QETH_DBF_TRACE_LEN,QETH_DBF_TRACE_LEN); + sprintf(dbf_text,"nmsk%4u",addr6->prefix_len); + QETH_DBF_TEXT3(0,trace,dbf_text); + FILL_NETMASK(addr6->prefix_len); + result=qeth_send_delip(card, + (__u8*)&addr6->addr.s6_addr, + (__u8*)&netmask,6); + if (result) { + PRINT_ERR("was not able to delete ip " \ + "%04x:%04x:%04x:%04x:%04x:%04x:" \ + "%04x:%04x/%u on irq x%x " \ + "(result: 0x%x), " \ + "trying to continue\n", + addr6->addr.s6_addr16[0], + addr6->addr.s6_addr16[1], + addr6->addr.s6_addr16[2], + addr6->addr.s6_addr16[3], + addr6->addr.s6_addr16[4], + addr6->addr.s6_addr16[5], + addr6->addr.s6_addr16[6], + addr6->addr.s6_addr16[7], + addr6->prefix_len, + card->irq0,result); + sprintf(dbf_text,"std6%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + } + addr6=addr6->if_next; + } + + addr6=card->ip_new_state.ip6_ifa; + while (addr6) { + if (!qeth_is_ipa_in_list6(addr6, + card->ip_current_state.ip6_ifa)) { + QETH_DBF_TEXT3(0,trace,"setipst6"); + QETH_DBF_HEX3(0,trace,&addr6->addr.s6_addr, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX3(0,trace, + ((char *)(&addr6->addr.s6_addr))+ + QETH_DBF_TRACE_LEN,QETH_DBF_TRACE_LEN); + sprintf(dbf_text,"nmsk%4u",addr6->prefix_len); + QETH_DBF_TEXT3(0,trace,dbf_text); + FILL_NETMASK(addr6->prefix_len); + result=qeth_send_setip(card, + (__u8*)&addr6->addr.s6_addr, + (__u8*)&netmask,6, + use_setip_retries); + if (result) { + PRINT_ERR("was not able to set ip " \ + "%04x:%04x:%04x:%04x:%04x:%04x:" \ + "%04x:%04x/%u on irq x%x " \ + "(result: 0x%x), " \ + "trying to continue\n", + addr6->addr.s6_addr16[0], + addr6->addr.s6_addr16[1], + addr6->addr.s6_addr16[2], + addr6->addr.s6_addr16[3], + addr6->addr.s6_addr16[4], + addr6->addr.s6_addr16[5], + addr6->addr.s6_addr16[6], + addr6->addr.s6_addr16[7], + addr6->prefix_len, + card->irq0,result); + sprintf(dbf_text,"sts6%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + } + addr6=addr6->if_next; + } +#endif /* QETH_IPV6 */ + + return 0; +} + +static int qeth_is_ipma_in_list(struct qeth_ipm_mac *ipma, + struct qeth_ipm_mac *list) +{ + while (list) { + if ( (!memcmp(ipma->ip,list->ip,16)) && + (!memcmp(ipma->mac,list->mac,6)) ) return 1; + list=list->next; + } + return 0; +} + +static void qeth_remove_mc_ifa_from_list(struct qeth_ipm_mac **list, + struct qeth_ipm_mac *ipma) +{ + struct qeth_ipm_mac *i,*li=NULL; + + if ((!(*list)) || (!ipma)) return; + + if (*list==ipma) { + *list=ipma->next; + } else { + i=*list; + while (i) { + if (i==ipma) { + li->next=i->next; + } else { + li=i; + } + i=i->next; + } + } +} + +static int qeth_add_mc_ifa_to_list(struct qeth_ipm_mac **list, + struct qeth_ipm_mac *ipma) +{ + struct qeth_ipm_mac *i; + + if (qeth_is_ipma_in_list(ipma,*list)) + return -EALREADY; + + if (*list==NULL) { + *list=ipma; + } else { + i=*list; + while (i->next) { + i=i->next; + } + i->next=ipma; + } + ipma->next=NULL; + return 0; +} + +static int qeth_setipms(qeth_card_t *card,int use_setipm_retries) +{ + struct qeth_ipm_mac *addr; + int result; + char dbf_text[15]; + + sprintf(dbf_text,"stim%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + if (qeth_is_supported(IPA_MULTICASTING)) { + addr=card->ip_mc_current_state.ipm_ifa; + while (addr) { + if (!qeth_is_ipma_in_list(addr,card-> + ip_mc_new_state.ipm_ifa)) { + QETH_DBF_TEXT3(0,trace,"setimdel"); + sprintf(dbf_text,"%08x", + *((__u32*)&addr->ip[0])); + QETH_DBF_TEXT3(0,trace,dbf_text); + *((__u32*)(&dbf_text[0]))= + *((__u32*)&addr->mac); + *((__u32*)(&dbf_text[4]))= + *(((__u32*)&addr->mac)+1); + QETH_DBF_HEX3(0,trace,dbf_text, + QETH_DBF_TRACE_LEN); + result=qeth_send_delipm( + card,(__u8*)&addr->ip[0], + (__u8*)addr->mac,4); + if (result) { + PRINT_ERR("was not able to delete " \ + "multicast ip %08x/" \ + "%02x%02x%02x%02x%02x%02x " \ + "on irq x%x " \ + "(result: 0x%x), " \ + "trying to continue\n", + *((__u32*)&addr->ip[0]), + addr->mac[0],addr->mac[1], + addr->mac[2],addr->mac[3], + addr->mac[4],addr->mac[5], + card->irq0,result); + sprintf(dbf_text,"smdl%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + } + addr=addr->next; + } + + addr=card->ip_mc_new_state.ipm_ifa; + while (addr) { + if (!qeth_is_ipma_in_list(addr,card-> + ip_mc_current_state. + ipm_ifa)) { + QETH_DBF_TEXT3(0,trace,"setimset"); + sprintf(dbf_text,"%08x", + *((__u32*)&addr->ip[0])); + QETH_DBF_TEXT3(0,trace,dbf_text); + *((__u32*)(&dbf_text[0]))= + *((__u32*)&addr->mac); + *((__u32*)(&dbf_text[4]))= + *(((__u32*)&addr->mac)+1); + QETH_DBF_HEX3(0,trace,dbf_text, + QETH_DBF_TRACE_LEN); + result=qeth_send_setipm( + card,(__u8*)&addr->ip[0], + (__u8*)addr->mac,4, + use_setipm_retries); + if (result) { + PRINT_ERR("was not able to set " \ + "multicast ip %08x/" \ + "%02x%02x%02x%02x%02x%02x " \ + "on irq x%x " \ + "(result: 0x%x), " \ + "trying to continue\n", + *((__u32*)&addr->ip[0]), + addr->mac[0],addr->mac[1], + addr->mac[2],addr->mac[3], + addr->mac[4],addr->mac[5], + card->irq0,result); + sprintf(dbf_text,"smst%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + qeth_remove_mc_ifa_from_list( + &card->ip_mc_current_state. + ipm_ifa,addr); + } + } + addr=addr->next; + } + +#ifdef QETH_IPV6 + /* here we go with IPv6 */ + addr=card->ip_mc_current_state.ipm6_ifa; + while (addr) { + if (!qeth_is_ipma_in_list(addr,card-> + ip_mc_new_state.ipm6_ifa)) { + QETH_DBF_TEXT3(0,trace,"setimdl6"); + QETH_DBF_HEX3(0,trace,&addr->ip[0], + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX3(0,trace,(&addr->ip[0])+ + QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX3(0,trace,&addr->mac, + QETH_DBF_TRACE_LEN); + result=qeth_send_delipm( + card,(__u8*)&addr->ip[0], + (__u8*)addr->mac,6); + if (result) { + PRINT_ERR("was not able to delete " \ + "multicast ip %04x:%04x:" \ + "%04x:%04x:%04x:%04x:" \ + "%04x:%04x/" \ + "%02x%02x%02x%02x%02x%02x " \ + "on irq x%x " \ + "(result: 0x%x), " \ + "trying to continue\n", + *((__u16*)&addr->ip[0]), + *((__u16*)&addr->ip[2]), + *((__u16*)&addr->ip[4]), + *((__u16*)&addr->ip[6]), + *((__u16*)&addr->ip[8]), + *((__u16*)&addr->ip[10]), + *((__u16*)&addr->ip[12]), + *((__u16*)&addr->ip[14]), + addr->mac[0],addr->mac[1], + addr->mac[2],addr->mac[3], + addr->mac[4],addr->mac[5], + card->irq0,result); + sprintf(dbf_text,"smd6%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + } + } + addr=addr->next; + } + + addr=card->ip_mc_new_state.ipm6_ifa; + while (addr) { + if (!qeth_is_ipma_in_list(addr,card-> + ip_mc_current_state. + ipm6_ifa)) { + QETH_DBF_TEXT3(0,trace,"setimst6"); + QETH_DBF_HEX3(0,trace,&addr->ip[0], + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX3(0,trace,(&addr->ip[0])+ + QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX3(0,trace,&addr->mac, + QETH_DBF_TRACE_LEN); + result=qeth_send_setipm( + card,(__u8*)&addr->ip[0], + (__u8*)addr->mac,6, + use_setipm_retries); + if (result) { + PRINT_ERR("was not able to set " \ + "multicast ip %04x:%04x:" \ + "%04x:%04x:%04x:%04x:" \ + "%04x:%04x/" \ + "%02x%02x%02x%02x%02x%02x " \ + "on irq x%x " \ + "(result: 0x%x), " \ + "trying to continue\n", + *((__u16*)&addr->ip[0]), + *((__u16*)&addr->ip[2]), + *((__u16*)&addr->ip[4]), + *((__u16*)&addr->ip[6]), + *((__u16*)&addr->ip[8]), + *((__u16*)&addr->ip[10]), + *((__u16*)&addr->ip[12]), + *((__u16*)&addr->ip[14]), + addr->mac[0],addr->mac[1], + addr->mac[2],addr->mac[3], + addr->mac[4],addr->mac[5], + card->irq0,result); + sprintf(dbf_text,"sms6%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + qeth_remove_mc_ifa_from_list( + &card->ip_mc_current_state. + ipm6_ifa,addr); + } + } + addr=addr->next; + } +#endif /* QETH_IPV6 */ + return 0; + } else return 0; +} + +static void qeth_clone_ifa(struct in_ifaddr *src,struct in_ifaddr *dest) +{ + memcpy(dest,src,sizeof(struct in_ifaddr)); + dest->ifa_next=NULL; +} + +#ifdef QETH_IPV6 +static void qeth_clone_ifa6(struct inet6_ifaddr *src, + struct inet6_ifaddr *dest) +{ + memcpy(dest,src,sizeof(struct inet6_ifaddr)); + dest->if_next=NULL; +} +#endif /* QETH_IPV6 */ + +#define QETH_STANDARD_RETVALS \ + ret_val=-EIO; \ + if (result==IPA_REPLY_SUCCESS) ret_val=0; \ + if (result==IPA_REPLY_FAILED) ret_val=-EIO; \ + if (result==IPA_REPLY_OPNOTSUPP) ret_val=-EOPNOTSUPP + +static int qeth_do_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) +{ + char *data; + int result,i,ret_val; + int version=4; + qeth_card_t *card; + char dbf_text[15]; + char buff[100]; + + card=(qeth_card_t*)dev->priv; + + sprintf(dbf_text,"ioct%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"cmd=%4x",cmd); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_HEX2(0,trace,&rq,sizeof(void*)); + + if ((cmdSIOCDEVPRIVATE+5)) + return -EOPNOTSUPP; + copy_from_user(buff,rq->ifr_ifru.ifru_data,sizeof(buff)); + data=buff; + + if ( (!atomic_read(&card->is_registered))|| + (!atomic_read(&card->is_hardsetup))|| + (atomic_read(&card->is_gone)) ) return -ENODEV; + + if (atomic_read(&card->shutdown_phase)) return -ENODEV; + + my_spin_lock(&card->ioctl_lock); + + if (atomic_read(&card->shutdown_phase)) return -ENODEV; + if ( (!atomic_read(&card->is_registered))|| + (!atomic_read(&card->is_hardsetup))|| + (atomic_read(&card->is_gone)) ) { + ret_val=-ENODEV; + goto out; + } + + switch (cmd) { + case SIOCDEVPRIVATE+0: + if (!capable(CAP_NET_ADMIN)) { + ret_val=-EPERM; + break; + } + result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING, + IPA_CMD_ASS_ARP_SET_NO_ENTRIES, + rq->ifr_ifru.ifru_ivalue,4); + QETH_STANDARD_RETVALS; + if (result==3) ret_val=-EINVAL; + break; + case SIOCDEVPRIVATE+1: + if (!capable(CAP_NET_ADMIN)) { + ret_val=-EPERM; + break; + } + result = qeth_queryarp(card,rq,version,IPA_ARP_PROCESSING, + IPA_CMD_ASS_ARP_QUERY_INFO,data,4); + + QETH_STANDARD_RETVALS; + break; + case SIOCDEVPRIVATE+2: + if (!capable(CAP_NET_ADMIN)) { + ret_val=-EPERM; + break; + } + for (i=12;i<24;i++) if (data[i]) version=6; + result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING, + IPA_CMD_ASS_ARP_ADD_ENTRY, + (long)data,56); + QETH_STANDARD_RETVALS; + break; + case SIOCDEVPRIVATE+3: + if (!capable(CAP_NET_ADMIN)) { + ret_val=-EPERM; + break; + } + for (i=4;i<12;i++) if (data[i]) version=6; + result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING, + IPA_CMD_ASS_ARP_REMOVE_ENTRY, + (long)data,16); + QETH_STANDARD_RETVALS; + break; + case SIOCDEVPRIVATE+4: + if (!capable(CAP_NET_ADMIN)) { + ret_val=-EPERM; + break; + } + result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING, + IPA_CMD_ASS_ARP_FLUSH_CACHE, + 0,0); + QETH_STANDARD_RETVALS; + break; + case SIOCDEVPRIVATE+5: + result=qeth_send_snmp_control(card,rq,IPA_CMD_SETADAPTERPARMS, + IPA_SETADP_SET_SNMP_CONTROL, + data,4); + QETH_STANDARD_RETVALS; + break; + + default: + return -EOPNOTSUPP; + } +out: + my_spin_unlock(&card->ioctl_lock); + + sprintf(dbf_text,"ret=%4x",ret_val); + QETH_DBF_TEXT2(0,trace,dbf_text); + + return ret_val; +} + +static void qeth_clear_ifamc_list(struct qeth_ipm_mac **ifa_list) +{ + struct qeth_ipm_mac *ifa; + while (*ifa_list) { + ifa=*ifa_list; + *ifa_list=ifa->next; + kfree(ifa); + } +} + +#ifdef QETH_IPV6 +static void qeth_clear_ifa6_list(struct inet6_ifaddr **ifa_list) +{ + struct inet6_ifaddr *ifa; + while (*ifa_list) { + ifa=*ifa_list; + *ifa_list=ifa->if_next; + kfree(ifa); + } +} + +static void qeth_takeover_ip_ipms6(qeth_card_t *card) +{ + struct inet6_ifaddr *ifa,*ifanew; + char dbf_text[15]; + int remove; +#ifdef QETH_VLAN + struct vlan_group *card_group; + int i; +#endif + + struct qeth_ipm_mac *ipmanew; + struct ifmcaddr6 *im6; + struct inet6_dev *in6_dev; +#ifdef QETH_VLAN + struct inet6_dev *in6_vdev; +#endif + char buf[MAX_ADDR_LEN]; + + sprintf(dbf_text,"tip6%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + /* unicast */ + /* clear ip_current_state */ + qeth_clear_ifa6_list(&card->ip_current_state.ip6_ifa); + /* take it over */ + card->ip_current_state.ip6_ifa=card->ip_new_state.ip6_ifa; + card->ip_new_state.ip6_ifa=NULL; + + /* multicast */ + /* clear ip_mc_current_state */ + qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm6_ifa); + /* take it over */ + card->ip_mc_current_state.ipm6_ifa=card->ip_mc_new_state.ipm6_ifa; + /* get new one, we try to have the same order as ifa_list in device + structure, for what reason ever*/ + card->ip_mc_new_state.ipm6_ifa=NULL; + + if((in6_dev=in6_dev_get(card->dev))==NULL) { + sprintf(dbf_text,"id16%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + goto out; + } + read_lock(&in6_dev->lock); + + /* get new one, we try to have the same order as ifa_list in device + structure, for what reason ever*/ + QETH_DBF_TEXT4(0,trace,"to-ip6s"); + if ( (atomic_read(&card->is_open)) && (card->dev->ip6_ptr) && + (((struct inet6_dev*)card->dev->ip6_ptr)->addr_list) ) { + ifa=((struct inet6_dev*)card->dev->ip6_ptr)->addr_list; + + while (ifa) { + ifanew=kmalloc(sizeof(struct inet6_ifaddr),GFP_KERNEL); + if (!ifanew) { + PRINT_WARN("No memory for IP address " \ + "handling. Some of the IPs " \ + "will not be set on %s.\n", + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPNMEM"); + } else { + qeth_clone_ifa6(ifa,ifanew); + remove=qeth_add_ifa6_to_list( + &card->ip_new_state.ip6_ifa,ifanew); + QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr+ + QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + sprintf(dbf_text,"pref%4u",ifanew->prefix_len); + QETH_DBF_TEXT4(0,trace,dbf_text); + if (remove) { + kfree(ifanew); + QETH_DBF_TEXT4(0,trace,"alrdy6rm"); + } + } + ifa=ifa->if_next; + } + } +#ifdef QETH_VLAN +/*append all known VLAN IP Addresses corresponding + to the real device card->dev->ifindex +*/ + QETH_DBF_TEXT4(0,trace,"to-vip6s"); + if ( (qeth_is_supported(IPA_FULL_VLAN)) && + (atomic_read(&card->is_open)) ) { + card_group = (struct vlan_group *) card->vlangrp; + if (card_group) for (i=0;ivlan_devices[i]) && + (card_group->vlan_devices[i]->flags&IFF_UP)&& + ((struct inet6_dev *) card_group-> + vlan_devices[i]->ip6_ptr) ) { + ifa=((struct inet6_dev *) + card_group->vlan_devices[i]->ip6_ptr)-> + addr_list; + + while (ifa) { + ifanew=kmalloc(sizeof(struct inet6_ifaddr),GFP_KERNEL); + if (!ifanew) { + PRINT_WARN("No memory for IP address " \ + "handling. Some of the IPs " \ + "will not be set on %s.\n", + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPNMEM"); + } else { + qeth_clone_ifa6(ifa,ifanew); + remove=qeth_add_ifa6_to_list + (&card->ip_new_state.ip6_ifa,ifanew); + QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr+ + QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + sprintf(dbf_text,"pref%4u",ifanew->prefix_len); + QETH_DBF_TEXT4(0,trace,dbf_text); + if (remove) { + kfree(ifanew); + QETH_DBF_TEXT4(0,trace,"alrdv6rm"); + } + } + ifa=ifa->if_next; + } + } + } + } +#endif + + QETH_DBF_TEXT4(0,trace,"to-ipm6s"); + if (atomic_read(&card->is_open)) + for (im6=in6_dev->mc_list;im6;im6=im6->next) { + ndisc_mc_map(&im6->mca_addr,buf,card->dev,0); + ipmanew=(struct qeth_ipm_mac*)kmalloc( + sizeof(struct qeth_ipm_mac),GFP_KERNEL); + if (!ipmanew) { + PRINT_WARN("No memory for IPM address " \ + "handling. Multicast IP " \ + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" \ + "will not be set on %s.\n", + im6->mca_addr.s6_addr16[0], + im6->mca_addr.s6_addr16[1], + im6->mca_addr.s6_addr16[2], + im6->mca_addr.s6_addr16[3], + im6->mca_addr.s6_addr16[4], + im6->mca_addr.s6_addr16[5], + im6->mca_addr.s6_addr16[6], + im6->mca_addr.s6_addr16[7], + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPMNMM"); + } else { + memset(ipmanew,0,sizeof(struct qeth_ipm_mac)); + memcpy(ipmanew->mac,buf,OSA_ADDR_LEN); + memcpy(ipmanew->ip,im6->mca_addr.s6_addr,16); + ipmanew->next=NULL; + remove=qeth_add_mc_ifa_to_list( + &card->ip_mc_new_state.ipm6_ifa,ipmanew); + QETH_DBF_HEX4(0,trace,&ipmanew->ip, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX4(0,trace,&ipmanew->ip+ + QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX4(0,trace,&ipmanew->mac, + QETH_DBF_TRACE_LEN); + if (remove) { + QETH_DBF_TEXT4(0,trace,"mlrdy6rm"); + kfree(ipmanew); + } + } + } +#ifdef QETH_VLAN + QETH_DBF_TEXT4(0,trace,"tovipm6s"); + if ( (qeth_is_supported(IPA_FULL_VLAN)) && + (atomic_read(&card->is_open)) ) { + card_group = (struct vlan_group *) card->vlangrp; + if (card_group) for (i=0;ivlan_devices[i])&& + (card_group->vlan_devices[i]->flags&IFF_UP)) { + in6_vdev=in6_dev_get(card_group-> + vlan_devices[i]); + if(!(in6_vdev==NULL)) { + read_lock(&in6_vdev->lock); + for (im6=in6_vdev->mc_list; + im6;im6=im6->next) { + ndisc_mc_map(&im6->mca_addr, + buf,card_group->vlan_devices[i], + 0); + ipmanew=(struct qeth_ipm_mac*) + kmalloc(sizeof(struct qeth_ipm_mac), + GFP_KERNEL); + if (!ipmanew) { + PRINT_WARN("No memory for IPM address " \ + "handling. Multicast IP " \ + "%04x:%04x:%04x:%04x:" \ + "%04x:%04x:%04x:%04x" \ + "will not be set on %s.\n", + im6->mca_addr.s6_addr16[0], + im6->mca_addr.s6_addr16[1], + im6->mca_addr.s6_addr16[2], + im6->mca_addr.s6_addr16[3], + im6->mca_addr.s6_addr16[4], + im6->mca_addr.s6_addr16[5], + im6->mca_addr.s6_addr16[6], + im6->mca_addr.s6_addr16[7], + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPMNMM"); + } else { + memset(ipmanew,0, + sizeof(struct qeth_ipm_mac)); + memcpy(ipmanew->mac,buf,OSA_ADDR_LEN); + memcpy(ipmanew->ip, + im6->mca_addr.s6_addr,16); + ipmanew->next=NULL; + remove=qeth_add_mc_ifa_to_list + (&card->ip_mc_new_state.ipm6_ifa, + ipmanew); + QETH_DBF_HEX4(0,trace,&ipmanew->ip, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX4(0,trace,&ipmanew->ip+ + QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + QETH_DBF_HEX4(0,trace,&ipmanew->mac, + QETH_DBF_TRACE_LEN); + + if (remove) { + QETH_DBF_TEXT4(0,trace,"mlrdv6rm"); + kfree(ipmanew); + } + } + } + read_unlock(&in6_vdev->lock); + in6_dev_put(in6_vdev); + } else { + sprintf(dbf_text,"id26%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + } + } + } + } +#endif + read_unlock(&in6_dev->lock); + in6_dev_put(in6_dev); + out: + ; +} +#endif /* QETH_IPV6 */ + +static void qeth_clear_ifa4_list(struct in_ifaddr **ifa_list) +{ + struct in_ifaddr *ifa; + while (*ifa_list) { + ifa=*ifa_list; + *ifa_list=ifa->ifa_next; + kfree(ifa); + } +} + +static void qeth_takeover_ip_ipms(qeth_card_t *card) +{ + struct in_ifaddr *ifa,*ifanew; + char dbf_text[15]; + int remove; +#ifdef QETH_VLAN + struct vlan_group *card_group; + int i; + struct in_device *vin4_dev; +#endif + + struct qeth_ipm_mac *ipmanew; + struct ip_mc_list *im4; + struct in_device *in4_dev; + char buf[MAX_ADDR_LEN]; + __u32 maddr; + + sprintf(dbf_text,"tips%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + /* unicast */ + /* clear ip_current_state */ + qeth_clear_ifa4_list(&card->ip_current_state.ip_ifa); + /* take it over */ + card->ip_current_state.ip_ifa=card->ip_new_state.ip_ifa; + card->ip_new_state.ip_ifa=NULL; + + /* multicast */ + /* clear ip_mc_current_state */ + qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm_ifa); + /* take it over */ + card->ip_mc_current_state.ipm_ifa=card->ip_mc_new_state.ipm_ifa; + /* get new one, we try to have the same order as ifa_list in device + structure, for what reason ever*/ + card->ip_mc_new_state.ipm_ifa=NULL; + + if((in4_dev=in_dev_get(card->dev))==NULL) { + QETH_DBF_TEXT2(0,trace,"nodvhol1"); + QETH_DBF_TEXT2(0,trace,card->dev_name); + return; + } + read_lock(&in4_dev->lock); + + /* get new one, we try to have the same order as ifa_list in device + structure, for what reason ever*/ + QETH_DBF_TEXT4(0,trace,"to-ips"); + if ( (atomic_read(&card->is_open)) && (card->dev->ip_ptr) && + (((struct in_device*)card->dev->ip_ptr)->ifa_list) ) { + ifa=((struct in_device*)card->dev->ip_ptr)->ifa_list; + + while (ifa) { + ifanew=kmalloc(sizeof(struct in_ifaddr),GFP_KERNEL); + if (!ifanew) { + PRINT_WARN("No memory for IP address " \ + "handling. Some of the IPs " \ + "will not be set on %s.\n", + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPNMEM"); + } else { + qeth_clone_ifa(ifa,ifanew); + remove=qeth_add_ifa_to_list( + &card->ip_new_state.ip_ifa,ifanew); + *((__u32*)(&dbf_text[0]))= + *((__u32*)&ifanew->ifa_address); + *((__u32*)(&dbf_text[4]))= + *((__u32*)&ifanew->ifa_mask); + QETH_DBF_TEXT4(0,trace,dbf_text); + if (remove) { + kfree(ifanew); + QETH_DBF_TEXT4(0,trace,"alrdy4rm"); + } + } + + ifa=ifa->ifa_next; + } + } + +#ifdef QETH_VLAN + /* append all known VLAN IP Addresses corresponding to the + * real device card->dev->ifindex */ + QETH_DBF_TEXT4(0,trace,"to-vips"); + if ( (qeth_is_supported(IPA_FULL_VLAN)) && + (atomic_read(&card->is_open)) ) { + card_group = (struct vlan_group *) card->vlangrp; + if (card_group) { + for (i=0;idev))) { + read_lock(&vin4_dev->lock); + if ((card_group->vlan_devices[i])&& + (card_group->vlan_devices[i]->flags&IFF_UP)) { + ifa=((struct in_device*) + card_group->vlan_devices[i]->ip_ptr)-> + ifa_list; + while (ifa) { + ifanew=kmalloc(sizeof(struct in_ifaddr), + GFP_KERNEL); + if (!ifanew) { + PRINT_WARN("No memory for IP address " \ + "handling. Some of the IPs " \ + "will not be set on %s.\n", + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPNMEM"); + } else { + qeth_clone_ifa(ifa,ifanew); + remove=qeth_add_ifa_to_list( + &card->ip_new_state.ip_ifa, + ifanew); + *((__u32*)(&dbf_text[0]))= + *((__u32*)&ifanew-> + ifa_address); + *((__u32*)(&dbf_text[4]))= + *((__u32*)&ifanew->ifa_mask); + QETH_DBF_TEXT4(0,trace,dbf_text); + if (remove) { + kfree(ifanew); + QETH_DBF_TEXT4(0,trace, + "alrdv4rm"); + } + } + ifa=ifa->ifa_next; + } + } + read_unlock(&vin4_dev->lock); + in_dev_put(vin4_dev); + } else { + QETH_DBF_TEXT2(0,trace,"nodvhol2"); + QETH_DBF_TEXT2(0,trace,card->dev_name); + } + } + } + } +#endif /* QETH_VLAN */ + + QETH_DBF_TEXT4(0,trace,"to-ipms"); + if (atomic_read(&card->is_open)) + for (im4=in4_dev->mc_list;im4;im4=im4->next) { + qeth_get_mac_for_ipm(im4->multiaddr,buf,in4_dev->dev); + ipmanew=(struct qeth_ipm_mac*)kmalloc( + sizeof(struct qeth_ipm_mac),GFP_KERNEL); + if (!ipmanew) { + PRINT_WARN("No memory for IPM address " \ + "handling. Multicast IP %08x" \ + "will not be set on %s.\n", + (__u32)im4->multiaddr, + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPMNMM"); + } else { + memset(ipmanew,0,sizeof(struct qeth_ipm_mac)); + memcpy(ipmanew->mac,buf,OSA_ADDR_LEN); + maddr=im4->multiaddr; + memcpy(&(ipmanew->ip[0]),&maddr,4); + memset(&(ipmanew->ip[4]),0xff,12); + ipmanew->next=NULL; + remove=qeth_add_mc_ifa_to_list( + &card->ip_mc_new_state.ipm_ifa,ipmanew); + sprintf(dbf_text,"%08x",*((__u32*)&ipmanew->ip)); + QETH_DBF_TEXT4(0,trace,dbf_text); + QETH_DBF_HEX4(0,trace,&ipmanew->mac, + QETH_DBF_TRACE_LEN); + if (remove) { + QETH_DBF_TEXT4(0,trace,"mlrdy4rm"); + kfree(ipmanew); + } + } + } + +#ifdef QETH_VLAN + QETH_DBF_TEXT4(0,trace,"to-vipms"); + if ( (qeth_is_supported(IPA_FULL_VLAN)) && + (atomic_read(&card->is_open)) ) { + card_group = (struct vlan_group *) card->vlangrp; + if (card_group) for (i=0;ivlan_devices[i])&& + (card_group->vlan_devices[i]->flags&IFF_UP)) { + if ((vin4_dev=in_dev_get(card_group-> + vlan_devices[i]))) { + read_lock(&vin4_dev->lock); + for (im4=vin4_dev->mc_list;im4;im4=im4->next) { + qeth_get_mac_for_ipm(im4->multiaddr,buf,vin4_dev->dev); + ipmanew=(struct qeth_ipm_mac*)kmalloc( + sizeof(struct qeth_ipm_mac),GFP_KERNEL); + if (!ipmanew) { + PRINT_WARN("No memory for IPM address " \ + "handling. Multicast VLAN IP %08x" \ + "will not be set on %s.\n", + (__u32)im4->multiaddr, + card->dev_name); + QETH_DBF_TEXT2(0,trace,"TOIPMNMM"); + } else { + memset(ipmanew,0,sizeof(struct qeth_ipm_mac)); + memcpy(ipmanew->mac,buf,OSA_ADDR_LEN); + maddr=im4->multiaddr; + memcpy(&(ipmanew->ip[0]),&maddr,4); + memset(&(ipmanew->ip[4]),0xff,12); + ipmanew->next=NULL; + remove=qeth_add_mc_ifa_to_list( + &card->ip_mc_new_state.ipm_ifa, + ipmanew); + sprintf(dbf_text,"%08x", + *((__u32*)&ipmanew->ip)); + QETH_DBF_TEXT4(0,trace,dbf_text); + QETH_DBF_HEX4(0,trace,&ipmanew->mac, + QETH_DBF_TRACE_LEN); + if (remove) { + QETH_DBF_TEXT4(0,trace,"mlrdv4rm"); + kfree(ipmanew); + } + } + } + read_unlock(&vin4_dev->lock); + in_dev_put(vin4_dev); + } else { + QETH_DBF_TEXT2(0,trace,"novdhol3"); + QETH_DBF_TEXT2(0,trace,card->dev_name); + QETH_DBF_TEXT2(0,trace,card_group-> + vlan_devices[i]->name); + } + } + } + } +#endif /* QETH_VLAN */ + + read_unlock(&in4_dev->lock); + in_dev_put(in4_dev); +} + +static void qeth_get_unique_id(qeth_card_t *card) +{ +#ifdef QETH_IPV6 +#ifdef CONFIG_SHARED_IPV6_CARDS + ipa_cmd_t cmd; + int result; + char dbf_text[15]; + + if (!qeth_is_supported(IPA_IPv6)) { + card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED| + UNIQUE_ID_NOT_BY_CARD; + return; + } + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_CREATE_ADDR,6); + + *((__u16*)&cmd.data.create_destroy_addr.unique_id[6])=card->unique_id; + + result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE); + + if (result) { + card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED| + UNIQUE_ID_NOT_BY_CARD; + PRINT_WARN("couldn't get a unique id from the card on irq " \ + "x%x (result=x%x), using default id. ipv6 " \ + "autoconfig on other lpars may lead to duplicate " \ + "ip addresses. please use manually " \ + "configured ones.\n",card->irq0,result); + QETH_DBF_TEXT2(0,trace,"unid fld"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + } else { + card->unique_id= + *((__u16*)&cmd.data.create_destroy_addr.unique_id[6]); + QETH_DBF_TEXT2(0,setup,"uniqueid"); + sprintf(dbf_text,"%4x%4x",card->irq0,card->unique_id); + QETH_DBF_TEXT2(0,setup,dbf_text); + } +#else /* CONFIG_SHARED_IPV6_CARDS */ + card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD; +#endif /* CONFIG_SHARED_IPV6_CARDS */ +#else /* QETH_IPV6 */ + card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD; +#endif /* QETH_IPV6 */ +} + +static void qeth_put_unique_id(qeth_card_t *card) +{ +#ifdef QETH_IPV6 +#ifdef CONFIG_SHARED_IPV6_CARDS + ipa_cmd_t cmd; + int result; + char dbf_text[15]; + + /* is also true, if ipv6 is not supported on the card */ + if ((card->unique_id&UNIQUE_ID_NOT_BY_CARD)==UNIQUE_ID_NOT_BY_CARD) + return; + + qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_DESTROY_ADDR,6); + *((__u16*)&cmd.data.create_destroy_addr.unique_id[6])=card->unique_id; + memcpy(&cmd.data.create_destroy_addr.unique_id[0], + card->dev->dev_addr,OSA_ADDR_LEN); + + result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE); + + if (result) { + QETH_DBF_TEXT2(0,trace,"unibkfld"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT2(0,trace,dbf_text); + } +#else /* CONFIG_SHARED_IPV6_CARDS */ + card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD; +#endif /* CONFIG_SHARED_IPV6_CARDS */ +#else /* QETH_IPV6 */ + card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD; +#endif /* QETH_IPV6 */ +} + +static void qeth_do_setadapterparms_stuff(qeth_card_t *card) +{ + int result; + char dbf_text[15]; + + if (!qeth_is_supported(IPA_SETADAPTERPARMS)) { + return; + } + + sprintf(dbf_text,"stap%4x",card->irq0); + QETH_DBF_TEXT4(0,trace,dbf_text); + + result=qeth_send_setadapterparms_query(card); + + if (result) { + PRINT_WARN("couldn't set adapter parameters on irq 0x%x: " \ + "x%x\n",card->irq0,result); + QETH_DBF_TEXT1(0,trace,"SETADPFL"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT1(1,trace,dbf_text); + return; + } + + sprintf(dbf_text,"spap%4x",card->adp_supported); + QETH_DBF_TEXT2(0,trace,dbf_text); + + if (qeth_is_adp_supported(IPA_SETADP_ALTER_MAC_ADDRESS)) { + sprintf(dbf_text,"rdmc%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_TEXT2(0,setup,dbf_text); + + result=qeth_send_setadapterparms_change_addr(card, + IPA_SETADP_ALTER_MAC_ADDRESS, + CHANGE_ADDR_READ_MAC,card->dev->dev_addr, + OSA_ADDR_LEN); + if (result) { + PRINT_WARN("couldn't get MAC address on " \ + "irq 0x%x: x%x\n",card->irq0,result); + QETH_DBF_TEXT1(0,trace,"NOMACADD"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT1(1,trace,dbf_text); + } else { + QETH_DBF_HEX2(0,setup,card->dev->dev_addr, + __max(OSA_ADDR_LEN,QETH_DBF_SETUP_LEN)); + QETH_DBF_HEX3(0,trace,card->dev->dev_addr, + __max(OSA_ADDR_LEN,QETH_DBF_TRACE_LEN)); + } + } + + if ( (card->link_type==QETH_MPC_LINK_TYPE_HSTR) || + (card->link_type==QETH_MPC_LINK_TYPE_LANE_TR) ) { + sprintf(dbf_text,"hstr%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + if (qeth_is_adp_supported(IPA_SETADP_SET_BROADCAST_MODE)) { + result=qeth_send_setadapterparms_mode(card, + IPA_SETADP_SET_BROADCAST_MODE, + card->options.broadcast_mode); + if (result) { + PRINT_WARN("couldn't set broadcast mode on " \ + "irq 0x%x: x%x\n", + card->irq0,result); + QETH_DBF_TEXT1(0,trace,"STBRDCST"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT1(1,trace,dbf_text); + } + } else if (card->options.broadcast_mode) { + PRINT_WARN("set adapter parameters not available " \ + "to set broadcast mode, using ALLRINGS " \ + "on irq 0x%x:\n",card->irq0); + sprintf(dbf_text,"NOBC%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + } + + if (qeth_is_adp_supported(IPA_SETADP_SET_BROADCAST_MODE)) { + result=qeth_send_setadapterparms_mode(card, + IPA_SETADP_ALTER_MAC_ADDRESS, + card->options.macaddr_mode); + if (result) { + PRINT_WARN("couldn't set macaddr mode on " \ + "irq 0x%x: x%x\n", + card->irq0,result); + QETH_DBF_TEXT1(0,trace,"STMACMOD"); + sprintf(dbf_text,"%4x%4x",card->irq0,result); + QETH_DBF_TEXT1(1,trace,dbf_text); + } + } else if (card->options.macaddr_mode) { + PRINT_WARN("set adapter parameters not available " \ + "to set macaddr mode, using NONCANONICAL " \ + "on irq 0x%x:\n",card->irq0); + sprintf(dbf_text,"NOMA%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + } + } +} + +static int qeth_softsetup_card(qeth_card_t *card,int wait_for_lock) +{ + int result; + int use_setip_retries=1; + char dbf_text[15]; + int do_a_startlan6=0; + + if (wait_for_lock==QETH_WAIT_FOR_LOCK) { + my_spin_lock(&card->softsetup_lock); + } else if (wait_for_lock==QETH_DONT_WAIT_FOR_LOCK) { + if (!spin_trylock(&card->softsetup_lock)) { + return -EAGAIN; + } + } else if (wait_for_lock==QETH_LOCK_ALREADY_HELD) { + use_setip_retries=0; /* we are in recovery and don't want + to repeat setting ips on and on */ + } else { + return -EINVAL; + } + + qeth_save_dev_flag_state(card); + + sprintf(dbf_text,"ssc%c%4x",wait_for_lock?'w':'n',card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + + if (!atomic_read(&card->is_softsetup)) { + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); +#endif /* QETH_IPV6 */ + if ( (!atomic_read(&card->is_startlaned)) && + (atomic_read(&card->startlan_attempts)) ) { + atomic_dec(&card->startlan_attempts); + QETH_DBF_TEXT2(0,trace,"startlan"); + netif_stop_queue(card->dev); + result=qeth_send_startlan(card,4); + if (result) { + PRINT_WARN("couldn't send STARTLAN on %s " \ + "(CHPID 0x%X): 0x%x (%s)\n", + card->dev_name,card->chpid,result, + (result==0xe080)? + "startlan disabled (link " \ + "failure -- please check the " \ + "network, plug in the cable or " \ + "enable the OSA port": + "unknown return code"); + sprintf(dbf_text,"stln%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->is_softsetup,0); + atomic_set(&card->is_startlaned,0); + /* do not return an error */ + if (result==0xe080) { + result=0; + } + goto out; + } + do_a_startlan6=1; + } + netif_wake_queue(card->dev); + + qeth_do_setadapterparms_stuff(card); + + if (!qeth_is_supported(IPA_ARP_PROCESSING)) { + PRINT_WARN("oops... ARP processing not supported " \ + "on %s!\n",card->dev_name); + QETH_DBF_TEXT1(0,trace,"NOarpPRC"); + } else { + QETH_DBF_TEXT2(0,trace,"enaARPpr"); + result=qeth_send_setassparms_simple_without_data( + card,IPA_ARP_PROCESSING,IPA_CMD_ASS_START); + if (result) { + PRINT_WARN("Could not start ARP processing " \ + "assist on %s: 0x%x\n", + card->dev_name,result); + sprintf(dbf_text,"ARPp%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->is_softsetup,0); + goto out; + } + } + + if (qeth_is_supported(IPA_IP_FRAGMENTATION)) { + PRINT_INFO("IP fragmentation supported on " \ + "%s... :-)\n",card->dev_name); + QETH_DBF_TEXT2(0,trace,"enaipfrg"); + result=qeth_send_setassparms_simple_without_data( + card,IPA_IP_FRAGMENTATION,IPA_CMD_ASS_START); + if (result) { + PRINT_WARN("Could not start IP fragmenting " \ + "assist on %s: 0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"IFRG%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + /* go on */ + } + } + + if (card->options.fake_ll==FAKE_LL) { + if (qeth_is_supported(IPA_SOURCE_MAC_AVAIL)) { + QETH_DBF_TEXT2(0,trace,"enainsrc"); + result=qeth_send_setassparms_simple_without_data( + card,IPA_SOURCE_MAC_AVAIL,IPA_CMD_ASS_START); + if (result) { + PRINT_WARN("Could not start " \ + "inbound source " \ + "assist on %s: 0x%x, " \ + "continuing\n", + card->dev_name,result); + sprintf(dbf_text,"INSR%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + /* go on */ + } + } else { + PRINT_INFO("Inbound source addresses not " \ + "supported on %s\n",card->dev_name); + } + } +#ifdef QETH_VLAN + if (!qeth_is_supported(IPA_FULL_VLAN)) { + PRINT_WARN("VLAN not supported on %s\n", + card->dev_name); + QETH_DBF_TEXT2(0,trace,"vlnotsup"); + } else { + result=qeth_send_setassparms_simple_without_data( + card,IPA_VLAN_PRIO,IPA_CMD_ASS_START); + QETH_DBF_TEXT2(0,trace,"enavlan"); + if (result) { + PRINT_WARN("Could not start vlan " + "assist on %s: 0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"VLAN%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + /* go on*/ + } + else { + card->dev->features |= + NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX; + + } + } +#endif /* QETH_VLAN */ + + if (!qeth_is_supported(IPA_MULTICASTING)) { + PRINT_WARN("multicasting not supported on %s\n", + card->dev_name); + QETH_DBF_TEXT2(0,trace,"mcnotsup"); + } else { + result=qeth_send_setassparms_simple_without_data( + card,IPA_MULTICASTING,IPA_CMD_ASS_START); + QETH_DBF_TEXT2(0,trace,"enamcass"); + if (result) { + PRINT_WARN("Could not start multicast " + "assist on %s: 0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"MCAS%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + /* go on*/ + } else { + card->dev->flags|=IFF_MULTICAST; + } + } + + if (!qeth_is_supported(IPA_IPv6)) { + QETH_DBF_TEXT2(0,trace,"ipv6ntsp"); + PRINT_WARN("IPv6 not supported on %s\n", + card->dev_name); + } else { + if (do_a_startlan6) { + QETH_DBF_TEXT2(0,trace,"startln6"); + netif_stop_queue(card->dev); + result=qeth_send_startlan(card,6); + if (result) { + sprintf(dbf_text,"stl6%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->is_softsetup,0); + /* do not return an error */ + if (result==0xe080) { + result=0; + } + goto out; + } + } + netif_wake_queue(card->dev); + QETH_DBF_TEXT2(0,trace,"qipassi6"); + result=qeth_send_qipassist(card,6); + if (result) { + PRINT_WARN("couldn't send QIPASSIST6 on %s: " \ + "0x%x\n",card->dev_name,result); + sprintf(dbf_text,"QIP6%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->is_softsetup,0); + goto out; + } + + sprintf(dbf_text,"%4x%4x",card->ipa6_supported, + card->ipa6_enabled); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_TEXT2(0,trace,"enaipv46"); + result=qeth_send_setassparms_simple_with_data( + card,IPA_IPv6,IPA_CMD_ASS_START,3); + if (result) { + PRINT_WARN("Could not enable IPv4&6 assist " \ + "on %s: " \ + "0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"I46A%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + /* go on */ + } + QETH_DBF_TEXT2(0,trace,"enaipv6"); + result=qeth_send_setassparms_simple_without_data6( + card,IPA_IPv6,IPA_CMD_ASS_START); + if (result) { + PRINT_WARN("Could not start IPv6 assist " \ + "on %s: " \ + "0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"I6AS%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + /* go on */ + } + QETH_DBF_TEXT2(0,trace,"enapstr6"); + result=qeth_send_setassparms_simple_without_data6( + card,IPA_PASSTHRU,IPA_CMD_ASS_START); + if (result) { + PRINT_WARN("Could not enable passthrough " \ + "on %s: " \ + "0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"PSTR%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + /* go on */ + } + } + + card->broadcast_capable=0; + if (!qeth_is_supported(IPA_FILTERING)) { + QETH_DBF_TEXT2(0,trace,"filtntsp"); + PRINT_WARN("Broadcasting not supported on %s\n", + card->dev_name); + } else { + QETH_DBF_TEXT2(0,trace,"enafiltr"); + result=qeth_send_setassparms_simple_without_data( + card,IPA_FILTERING,IPA_CMD_ASS_START); + if (result) { + PRINT_WARN("Could not enable broadcast " \ + "filtering on %s: " \ + "0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"FLT1%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + goto go_on_filt; + } + result=qeth_send_setassparms_simple_with_data( + card,IPA_FILTERING,IPA_CMD_ASS_CONFIGURE,1); + if (result) { + PRINT_WARN("Could not set up broadcast " \ + "filtering on %s: " \ + "0x%x, continuing\n", + card->dev_name,result); + sprintf(dbf_text,"FLT2%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + goto go_on_filt; + } + card->dev->flags|=IFF_BROADCAST; + card->broadcast_capable=1; + + } +go_on_filt: + if (card->options.checksum_type==HW_CHECKSUMMING) { + if (!qeth_is_supported(IPA_INBOUND_CHECKSUM)) { + PRINT_WARN("Inbound HW checksumming not " \ + "supported on %s, continuing " \ + "using inbound sw checksumming\n", + card->dev_name); + QETH_DBF_TEXT2(0,trace,"ibckntsp"); + card->options.checksum_type=SW_CHECKSUMMING; + } else { + QETH_DBF_TEXT2(0,trace,"ibcksupp"); + result=qeth_send_setassparms_simple_without_data( + card,IPA_INBOUND_CHECKSUM, + IPA_CMD_ASS_START); + if (result) { + PRINT_WARN("Could not start inbound " \ + "checksumming on %s: " \ + "0x%x, " \ + "continuing using " \ + "inbound sw checksumming\n", + card->dev_name,result); + sprintf(dbf_text,"SIBC%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + card->options.checksum_type= + SW_CHECKSUMMING; + goto go_on_checksum; + } + result=qeth_send_setassparms_simple_with_data( + card,IPA_INBOUND_CHECKSUM, + IPA_CMD_ASS_ENABLE, + IPA_CHECKSUM_ENABLE_MASK); + if (result) { + PRINT_WARN("Could not enable inbound " \ + "checksumming on %s: " \ + "0x%x, " \ + "continuing using " \ + "inbound sw checksumming\n", + card->dev_name,result); + sprintf(dbf_text,"EIBC%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + card->options.checksum_type= + SW_CHECKSUMMING; + goto go_on_checksum; + } + } + } +go_on_checksum: + + atomic_set(&card->is_softsetup,1); + } + + if (atomic_read(&card->enable_routing_attempts4)) { + if (card->options.routing_type4) { + sprintf(dbf_text,"strtg4%2x", + card->options.routing_type4); + QETH_DBF_TEXT2(0,trace,dbf_text); + result=qeth_send_setrtg(card,card->options. + routing_type4,4); + if (result) { + if (atomic_dec_return(&card-> + enable_routing_attempts4)) { + PRINT_WARN("couldn't set up v4 routing type " \ + "on %s: 0x%x (%s).\nWill try " \ + "next time again.\n", + card->dev_name,result, + ((result==0xe010)|| + (result==0xe008))? + "primary already defined": + ((result==0xe011)|| + (result==0xe009))? + "secondary already defined": + (result==0xe012)? + "invalid indicator": + "unknown return code"); + sprintf(dbf_text,"sRT4%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->rt4fld,1); + } else { + PRINT_WARN("couldn't set up v4 routing type " \ + "on %s: 0x%x (%s).\nTrying to " \ + "continue without routing.\n", + card->dev_name,result, + ((result==0xe010)|| + (result==0xe008))? + "primary already defined": + ((result==0xe011)|| + (result==0xe009))? + "secondary already defined": + (result==0xe012)? + "invalid indicator": + "unknown return code"); + sprintf(dbf_text,"SRT4%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->rt4fld,1); + } + } else { /* routing set correctly */ + atomic_set(&card->enable_routing_attempts4,0); + atomic_set(&card->rt4fld,0); + } + } else { + atomic_set(&card->enable_routing_attempts4,0); + atomic_set(&card->rt4fld,0); + } + } + +#ifdef QETH_IPV6 + if (atomic_read(&card->enable_routing_attempts6)) { + if (card->options.routing_type6) { + sprintf(dbf_text,"strtg6%2x", + card->options.routing_type6); + QETH_DBF_TEXT2(0,trace,dbf_text); + result=qeth_send_setrtg(card,card->options. + routing_type6,6); + if (result) { + if (atomic_dec_return(&card-> + enable_routing_attempts6)) { + PRINT_WARN("couldn't set up v6 routing type " \ + "on %s: 0x%x (%s).\nWill try " \ + "next time again.\n", + card->dev_name,result, + ((result==0xe010)|| + (result==0xe008))? + "primary already defined": + ((result==0xe011)|| + (result==0xe009))? + "secondary already defined": + (result==0xe012)? + "invalid indicator": + "unknown return code"); + sprintf(dbf_text,"sRT6%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->rt6fld,1); + } else { + PRINT_WARN("couldn't set up v6 routing type " \ + "on %s: 0x%x (%s).\nTrying to " \ + "continue without routing.\n", + card->dev_name,result, + ((result==0xe010)|| + (result==0xe008))? + "primary already defined": + ((result==0xe011)|| + (result==0xe009))? + "secondary already defined": + (result==0xe012)? + "invalid indicator": + "unknown return code"); + sprintf(dbf_text,"SRT6%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->rt6fld,1); + } + } else { /* routing set correctly */ + atomic_set(&card->enable_routing_attempts6,0); + atomic_set(&card->rt6fld,0); + } + } else { + atomic_set(&card->enable_routing_attempts6,0); + atomic_set(&card->rt6fld,0); + } + } +#endif /* QETH_IPV6 */ + + QETH_DBF_TEXT2(0,trace,"delvipa"); + qeth_set_vipas(card,0); + QETH_DBF_TEXT2(0,trace,"toip/ms"); + qeth_takeover_ip_ipms(card); +#ifdef QETH_IPV6 + qeth_takeover_ip_ipms6(card); +#endif /* QETH_IPV6 */ + QETH_DBF_TEXT2(0,trace,"setvipa"); + qeth_set_vipas(card,1); + + result=qeth_setips(card,use_setip_retries); + if (result) { /* by now, qeth_setips does not return errors */ + PRINT_WARN("couldn't set up IPs on %s: 0x%x\n", + card->dev_name,result); + sprintf(dbf_text,"SSIP%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->is_softsetup,0); + goto out; + } + + result=qeth_setipms(card,use_setip_retries); + if (result) { /* by now, qeth_setipms does not return errors */ + PRINT_WARN("couldn't set up multicast IPs on %s: 0x%x\n", + card->dev_name,result); + sprintf(dbf_text,"ssim%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->is_softsetup,0); + goto out; + } + out: + if (!result) { + netif_wake_queue(card->dev); + } + if (wait_for_lock!=QETH_LOCK_ALREADY_HELD) + my_spin_unlock(&card->softsetup_lock); + return result; +} + +static int qeth_softsetup_thread(void *param) +{ + char dbf_text[15]; + char name[15]; + qeth_card_t *card=(qeth_card_t*)param; + + daemonize(); + + /* set a nice name ... */ + sprintf(name, "qethsoftd%04x", card->irq0); + strcpy(current->comm, name); + + sprintf(dbf_text,"ssth%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + atomic_set(&card->softsetup_thread_is_running,1); + for (;;) { + if (atomic_read(&card->shutdown_phase)) goto out; + down_interruptible(&card->softsetup_thread_sem); + sprintf(dbf_text,"ssst%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + if (atomic_read(&card->shutdown_phase)) goto out; + while (qeth_softsetup_card(card,QETH_DONT_WAIT_FOR_LOCK) + ==-EAGAIN) { + if (atomic_read(&card->shutdown_phase)) goto out; + qeth_wait_nonbusy(QETH_IDLE_WAIT_TIME); + } + sprintf(dbf_text,"sstd%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + netif_wake_queue(card->dev); + } + out: + atomic_set(&card->softsetup_thread_is_running,0); + + sprintf(dbf_text,"lsst%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + return 0; +} + +static void qeth_softsetup_thread_starter(void *data) +{ + char dbf_text[15]; + qeth_card_t *card=(qeth_card_t *)data; + + sprintf(dbf_text,"ssts%4x",card->irq0); + QETH_DBF_TEXT4(0,trace,dbf_text); + sema_init(&card->softsetup_thread_sem,0); + kernel_thread(qeth_softsetup_thread,card,SIGCHLD); +} + +static void qeth_start_reinit_thread(qeth_card_t *card) +{ + char dbf_text[15]; + + /* we allow max 2 reinit threads, one could be just about to + * finish and the next would be waiting. another waiting + * reinit_thread is not necessary. */ + if (atomic_read(&card->reinit_counter)<2) { + atomic_inc(&card->reinit_counter); + if (atomic_read(&card->shutdown_phase)) { + atomic_dec(&card->reinit_counter); + return; + } + sprintf(dbf_text,"stri%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + PRINT_STUPID("starting reinit-thread\n"); + kernel_thread(qeth_reinit_thread,card,SIGCHLD); + } +} + +static void qeth_recover(void *data) +{ + qeth_card_t *card; + int i; + char dbf_text[15]; + + card=(qeth_card_t*)data; + + sprintf(dbf_text,"recv%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + if (atomic_compare_and_swap(0,1,&card->in_recovery)) + return; + + i=atomic_read(&card->problem); + + sprintf(dbf_text,"PROB%4x",i); + QETH_DBF_TEXT2(0,trace,dbf_text); + + PRINT_WARN("recovery was scheduled on irq 0x%x (%s) with " \ + "problem 0x%x\n", + card->irq0,card->dev_name,i); + switch (i) { + case PROBLEM_RECEIVED_IDX_TERMINATE: + if (atomic_read(&card->in_recovery)) + atomic_set(&card->break_out,QETH_BREAKOUT_AGAIN); + break; + case PROBLEM_CARD_HAS_STARTLANED: + PRINT_WARN("You are lucky! Somebody either fixed the " \ + "network problem, plugged the cable back in " \ + "or enabled the OSA port on %s (CHPID 0x%X). " \ + "The link has come up.\n", + card->dev_name,card->chpid); + sprintf(dbf_text,"CBIN%4x",i); + QETH_DBF_TEXT1(0,trace,dbf_text); + atomic_set(&card->is_softsetup,0); + qeth_set_dev_flag_running(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); + qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); + qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa); +#endif /* QETH_IPV6 */ + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa); +#ifdef QETH_IPV6 + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa); +#endif /* QETH_IPV6 */ + qeth_refresh_vipa_states(card); + qeth_start_softsetup_thread(card); + atomic_set(&card->in_recovery,0); + break; + case PROBLEM_RESETTING_EVENT_INDICATOR: + /* we do nothing here */ + break; + case PROBLEM_ACTIVATE_CHECK_CONDITION: + case PROBLEM_GENERAL_CHECK: + case PROBLEM_USER_TRIGGERED_RECOVERY: + case PROBLEM_AFFE: + case PROBLEM_MACHINE_CHECK: + case PROBLEM_BAD_SIGA_RESULT: + case PROBLEM_TX_TIMEOUT: + qeth_start_reinit_thread(card); + break; + } +} + +static void qeth_schedule_recovery(qeth_card_t *card) +{ + if (card) { + INIT_LIST_HEAD(&card->tqueue.list); + card->tqueue.routine=qeth_recover; + card->tqueue.data=card; + card->tqueue.sync=0; + schedule_task(&card->tqueue); + } else { + QETH_DBF_TEXT2(1,trace,"scdnocrd"); + PRINT_WARN("recovery requested to be scheduled " \ + "with no card!\n"); + } +} + +static void qeth_qdio_input_handler(int irq,unsigned int status, + unsigned int qdio_error,unsigned int siga_error, + unsigned int queue, + int first_element,int count, + unsigned long card_ptr) +{ + struct net_device *dev; + qeth_card_t *card; + int problem; + int sbalf15; + char dbf_text[15]="qinbhnXX"; + + *((__u16*)(&dbf_text[6]))=(__u16)irq; + QETH_DBF_HEX6(0,trace,dbf_text,QETH_DBF_TRACE_LEN); + + card=(qeth_card_t *)card_ptr; + +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.inbound_start_time=NOW; +#endif /* QETH_PERFORMANCE_STATS */ + dev=card->dev; + + if (status&QDIO_STATUS_LOOK_FOR_ERROR) { + if (status&QDIO_STATUS_ACTIVATE_CHECK_CONDITION) { + problem=PROBLEM_ACTIVATE_CHECK_CONDITION; + PRINT_WARN("activate queues on irq 0x%x: " \ + "dstat=0x%x, cstat=0x%x\n",irq, + card->devstat2->dstat, + card->devstat2->cstat); + atomic_set(&card->problem,problem); + QETH_DBF_TEXT1(0,trace,"IHACTQCK"); + sprintf(dbf_text,"%4x%4x",first_element,count); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",queue,status); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"qscd%4x",card->irq0); + QETH_DBF_TEXT1(1,trace,dbf_text); + qeth_schedule_recovery(card); + return; + } + sbalf15=(card->inbound_qdio_buffers[(first_element+count-1)& + QDIO_MAX_BUFFERS_PER_Q]. + element[15].flags)&&0xff; + PRINT_STUPID("inbound qdio transfer error on irq 0x%04x. " \ + "qdio_error=0x%x (more than one: %c), " \ + "siga_error=0x%x (more than one: %c), " \ + "sbalf15=x%x, bufno=x%x\n", + irq,qdio_error, + (status&QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR)? + 'y':'n',siga_error, + (status&QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR)? + 'y':'n', + sbalf15,first_element); + sprintf(dbf_text,"IQTI%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + sprintf(dbf_text,"%4x%4x",first_element,count); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + sprintf(dbf_text,"%2x%4x%2x",queue,status,sbalf15); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + sprintf(dbf_text,"%4x%4x",qdio_error,siga_error); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + /* we inform about error more detailed in + * qeth_read_in_buffer() */ + } + + for (;;) { + qeth_get_linux_addrs_for_buffer(card,first_element); + qeth_read_in_buffer(card,first_element); + qeth_queue_input_buffer(card,first_element, + QDIO_FLAG_UNDER_INTERRUPT); + count--; + if (count) + first_element=(first_element+1)& + (QDIO_MAX_BUFFERS_PER_Q-1); + else break; + } +} + +static void qeth_qdio_output_handler(int irq,unsigned int status, + unsigned int qdio_error,unsigned int siga_error, + unsigned int queue, + int first_element,int count, + unsigned long card_ptr) +{ + qeth_card_t *card; + int mycnt,problem,buffers_used; + int sbalf15; + char dbf_text[15]="qouthnXX"; + char dbf_text2[15]="stchdwXX"; + int last_pci_hit=0,switch_state; + int last_pci; + + *((__u16*)(&dbf_text[6]))=(__u16)irq; + QETH_DBF_HEX6(0,trace,dbf_text,QETH_DBF_TRACE_LEN); + + mycnt=count; + card=(qeth_card_t *)card_ptr; + + if (status&QDIO_STATUS_LOOK_FOR_ERROR) { + if (status&QDIO_STATUS_ACTIVATE_CHECK_CONDITION) { + problem=PROBLEM_ACTIVATE_CHECK_CONDITION; + PRINT_WARN("activate queues on irq 0x%x: " \ + "dstat=0x%x, cstat=0x%x\n",irq, + card->devstat2->dstat, + card->devstat2->cstat); + atomic_set(&card->problem,problem); + QETH_DBF_TEXT1(0,trace,"OHACTQCK"); + sprintf(dbf_text,"%4x%4x",first_element,count); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",queue,status); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"qscd%4x",card->irq0); + QETH_DBF_TEXT1(1,trace,dbf_text); + qeth_schedule_recovery(card); + goto out; + } + sbalf15=(card->outbound_ringbuffer[queue]->buffer[ + (first_element+count-1)& + QDIO_MAX_BUFFERS_PER_Q].element[15].flags)&0xff; + PRINT_STUPID("outbound qdio transfer error on irq %04x, " \ + "queue=%i. qdio_error=0x%x (more than one: %c)," \ + " siga_error=0x%x (more than one: %c), " \ + "sbalf15=x%x, bufno=x%x\n", + irq,queue,qdio_error,status& + QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR?'y':'n', + siga_error,status& + QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR?'y':'n', + sbalf15,first_element); + sprintf(dbf_text,"IQTO%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + sprintf(dbf_text,"%4x%4x",first_element,count); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + sprintf(dbf_text,"%2x%4x%2x",queue,status,sbalf15); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + sprintf(dbf_text,"%4x%4x",qdio_error,siga_error); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_TEXT1(0,qerr,dbf_text); + /* we maybe do recovery or dst_link_failures + * in qeth_free_buffer */ + } + + if (mycnt) { + last_pci=atomic_read(&card->last_pci_pos[queue]); + for (;;) { + qeth_free_buffer(card,queue,first_element, + qdio_error,siga_error); + if (first_element==last_pci) last_pci_hit=1; + mycnt--; + if (mycnt>0) + first_element=(first_element+1)& + (QDIO_MAX_BUFFERS_PER_Q-1); + else break; + } + } + + buffers_used=atomic_return_sub(count, + &card->outbound_used_buffers[queue]); + + switch (card->send_state[queue]) { + case SEND_STATE_PACK: + switch_state=(atomic_read + (&card->outbound_used_buffers[queue])<= + LOW_WATERMARK_PACK); + /* first_element is the last buffer that we got back + * from hydra */ + if (switch_state||last_pci_hit) { + *((__u16*)(&dbf_text2[6]))=card->irq0; + QETH_DBF_HEX3(0,trace,dbf_text2,QETH_DBF_TRACE_LEN); + if (atomic_swap(&card->outbound_ringbuffer_lock + [queue],QETH_LOCK_FLUSH) + ==QETH_LOCK_UNLOCKED) { + /* we stop the queue as we try to not run + * onto the outbound_ringbuffer_lock -- + * this will not prevent it totally, but + * reduce it. in high traffic situations, + * it saves around 20us per second, hopefully + * this is amortized by calling netif_... */ + netif_stop_queue(card->dev); + qeth_flush_packed_packets + (card,queue, + QDIO_FLAG_UNDER_INTERRUPT); + /* only switch state to non-packing, if + * the amount of used buffers decreased */ + if (switch_state) + card->send_state[queue]= + SEND_STATE_DONT_PACK; + netif_wake_queue(card->dev); + atomic_set(&card->outbound_ringbuffer_lock[ + queue],QETH_LOCK_UNLOCKED); + } /* if the lock was UNLOCKED, we flush ourselves, + otherwise this is done in do_send_packet when + the lock is released */ +#ifdef QETH_PERFORMANCE_STATS + card->perf_stats.sc_p_dp++; +#endif /* QETH_PERFORMANCE_STATS */ + } + break; + default: break; + } + + /* we don't have to start the queue, if it was started already */ + if (buffers_useddev); +} + +static void qeth_interrupt_handler_read(int irq,void *devstat, + struct pt_regs *p) +{ + devstat_t *stat; + int cstat,dstat; + int problem; + qeth_card_t *card; + int rqparam; + char dbf_text[15]; + int result; + + stat=(devstat_t *)devstat; + cstat=stat->cstat; + dstat=stat->dstat; + rqparam=stat->intparm; + + sprintf(dbf_text,"rint%4x",irq); + QETH_DBF_TEXT4(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",cstat,dstat); + QETH_DBF_TEXT4(0,trace,dbf_text); + sprintf(dbf_text,"%4x",rqparam); + QETH_DBF_TEXT4(0,trace,dbf_text); + + if (!rqparam) { + PRINT_STUPID("got unsolicited interrupt in read handler, " \ + "irq 0x%x\n",irq); + return; + } + + card=qeth_get_card_by_irq(irq); + if (!card) return; + + if ((rqparam==CLEAR_STATE) || (stat->flag&DEVSTAT_CLEAR_FUNCTION)) { + atomic_set(&card->clear_succeeded0,1); + return; + } + + if ((dstat==0)&&(cstat==0)) return; + + if (card->devstat0->flag&DEVSTAT_FLAG_SENSE_AVAIL) { + PRINT_WARN("sense data available on read channel.\n"); + HEXDUMP16(WARN,"irb: ",&card->devstat0->ii.irb); + HEXDUMP16(WARN,"sense data: ",&card->devstat0->ii. + sense.data[0]); + sprintf(dbf_text,"RSNS%4x",irq); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_HEX0(0,sense,&card->devstat0->ii.irb, + QETH_DBF_SENSE_LEN); + } + + if (cstat!=0) { + PRINT_WARN("got nonzero-nonpci channel status in read_" \ + "handler (irq 0x%x, devstat 0x%02x, schstat " \ + "0x%02x, rqparam 0x%x)\n",irq,dstat,cstat,rqparam); + } + + problem=qeth_get_cards_problem(card,card->dma_stuff->recbuf, + irq,dstat,cstat,rqparam, + (char*)&card->devstat0->ii.irb, + (char*)&card->devstat0-> + ii.sense.data[0]); + + /* detect errors in dstat here */ + if ( (dstat&DEV_STAT_UNIT_EXCEP) || (dstat&DEV_STAT_UNIT_CHECK) ) { + PRINT_WARN("unit check/exception in read_handler " \ + "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \ + "rqparam 0x%x)\n",irq,dstat,cstat,rqparam); + if (!atomic_read(&card->is_hardsetup)) { + if ((problem)&&(qeth_is_to_recover(card,problem))) + atomic_set(&card->break_out, + QETH_BREAKOUT_AGAIN); + else + atomic_set(&card->break_out, + QETH_BREAKOUT_LEAVE); + goto wakeup_out; + } else goto recover; + } + + if (!(dstat&DEV_STAT_CHN_END)) { + PRINT_WARN("didn't get device end in read_handler " \ + "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \ + "rqparam 0x%x)\n",irq,dstat,cstat,rqparam); + goto wakeup_out; + } + + if ( (rqparam==IDX_ACTIVATE_WRITE_STATE) || + (rqparam==NOP_STATE) ) { + goto wakeup_out; + } + + /* at this point, (maybe channel end and) device end has appeared */ + + /* we don't start the next read until we have examined the buffer. */ + if ( (rqparam!=IDX_ACTIVATE_READ_STATE) && + (rqparam!=IDX_ACTIVATE_WRITE_STATE) ) + qeth_issue_next_read(card); + +recover: + if (qeth_is_to_recover(card,problem)) { + sprintf(dbf_text,"rscd%4x",card->irq0); + QETH_DBF_TEXT2(1,trace,dbf_text); + qeth_schedule_recovery(card); + goto wakeup_out; + } + + if (!IS_IPA(card->dma_stuff->recbuf)|| + IS_IPA_REPLY(card->dma_stuff->recbuf)) { + /* setup or unknown data */ + result = qeth_look_for_arp_data(card); + switch (result) { + case ARP_RETURNCODE_ERROR: + case ARP_RETURNCODE_LASTREPLY: + qeth_wakeup_ioctl(card); + return; + default: + break; + } + } + + wakeup_out: + memcpy(card->ipa_buf,card->dma_stuff->recbuf,QETH_BUFSIZE); + qeth_wakeup(card); +} + +static void qeth_interrupt_handler_write(int irq,void *devstat, + struct pt_regs *p) +{ + devstat_t *stat; + int cstat,dstat,rqparam; + qeth_card_t *card; + int problem; + char dbf_text[15]; + + stat = (devstat_t *)devstat; + cstat = stat->cstat; + dstat = stat->dstat; + rqparam=stat->intparm; + + sprintf(dbf_text,"wint%4x",irq); + QETH_DBF_TEXT4(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",cstat,dstat); + QETH_DBF_TEXT4(0,trace,dbf_text); + sprintf(dbf_text,"%4x",rqparam); + QETH_DBF_TEXT4(0,trace,dbf_text); + + if (!rqparam) { + PRINT_STUPID("got unsolicited interrupt in write handler, " \ + "irq 0x%x\n",irq); + return; + } + + card=qeth_get_card_by_irq(irq); + if (!card) return; + + if ((rqparam==CLEAR_STATE) || (stat->flag&DEVSTAT_CLEAR_FUNCTION)) { + atomic_set(&card->clear_succeeded1,1); + goto out; + } + + if ((dstat==0)&&(cstat==0)) goto out; + + if (card->devstat1->flag&DEVSTAT_FLAG_SENSE_AVAIL) { + PRINT_WARN("sense data available on write channel.\n"); + HEXDUMP16(WARN,"irb: ",&card->devstat1->ii.irb); + HEXDUMP16(WARN,"sense data: ",&card->devstat1->ii. + sense.data[0]); + sprintf(dbf_text,"WSNS%4x",irq); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_HEX0(0,sense,&card->devstat1->ii.irb, + QETH_DBF_SENSE_LEN); + } + + if (cstat != 0) { + PRINT_WARN("got nonzero channel status in write_handler " \ + "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \ + "rqparam 0x%x)\n",irq,dstat,cstat,rqparam); + } + + problem=qeth_get_cards_problem(card,NULL, + irq,dstat,cstat,rqparam, + (char*)&card->devstat1->ii.irb, + (char*)&card->devstat1-> + ii.sense.data[0]); + + /* detect errors in dstat here */ + if ( (dstat&DEV_STAT_UNIT_EXCEP) || (dstat&DEV_STAT_UNIT_CHECK) ) { + PRINT_WARN("unit check/exception in write_handler " \ + "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \ + "rqparam 0x%x)\n",irq,dstat,cstat,rqparam); + if (!atomic_read(&card->is_hardsetup)) { + if (problem==PROBLEM_RESETTING_EVENT_INDICATOR) { + atomic_set(&card->break_out, + QETH_BREAKOUT_AGAIN); + qeth_wakeup(card); + goto out; + } + atomic_set(&card->break_out,QETH_BREAKOUT_LEAVE); + goto out; + } else goto recover; + } + + if (dstat==DEV_STAT_DEV_END) goto out; + + if (!(dstat&DEV_STAT_CHN_END)) { + PRINT_WARN("didn't get device end in write_handler " \ + "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \ + "rqparam 0x%x)\n",irq,dstat,cstat,rqparam); + goto out; + } + +recover: + if (qeth_is_to_recover(card,problem)) { + sprintf(dbf_text,"wscd%4x",card->irq1); + QETH_DBF_TEXT2(1,trace,dbf_text); + qeth_schedule_recovery(card); + goto out; + } + + /* at this point, (maybe channel end and) device end has appeared */ + if ( (rqparam==IDX_ACTIVATE_READ_STATE) || + (rqparam==IDX_ACTIVATE_WRITE_STATE) || + (rqparam==NOP_STATE) ) { + qeth_wakeup(card); + goto out; + } + + /* well, a write has been done successfully. */ + + out: + /* all statuses are final statuses on the write channel */ + atomic_set(&card->write_busy,0); +} + +static void qeth_interrupt_handler_qdio(int irq,void *devstat, + struct pt_regs *p) +{ + devstat_t *stat; + int cstat,dstat,rqparam; + char dbf_text[15]; + + qeth_card_t *card; + + stat = (devstat_t *)devstat; + cstat = stat->cstat; + dstat = stat->dstat; + rqparam=stat->intparm; + + sprintf(dbf_text,"qint%4x",irq); + QETH_DBF_TEXT4(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",cstat,dstat); + QETH_DBF_TEXT4(0,trace,dbf_text); + sprintf(dbf_text,"%4x",rqparam); + QETH_DBF_TEXT4(0,trace,dbf_text); + + + if (!rqparam) { + PRINT_STUPID("got unsolicited interrupt in qdio handler, " \ + "irq 0x%x\n",irq); + return; + } + + card=qeth_get_card_by_irq(irq); + if (!card) return; + + if ((rqparam==CLEAR_STATE) || (stat->flag&DEVSTAT_CLEAR_FUNCTION)) { + atomic_set(&card->clear_succeeded2,1); + return; + } + + if ((dstat==0)&&(cstat==0)) return; + + if (card->devstat2->flag&DEVSTAT_FLAG_SENSE_AVAIL) { + PRINT_WARN("sense data available on qdio channel.\n"); + HEXDUMP16(WARN,"irb: ",&card->devstat2->ii.irb); + HEXDUMP16(WARN,"sense data: ",&card->devstat2->ii. + sense.data[0]); + sprintf(dbf_text,"QSNS%4x",irq); + QETH_DBF_TEXT1(0,trace,dbf_text); + QETH_DBF_HEX0(0,sense,&card->devstat2->ii.irb, + QETH_DBF_SENSE_LEN); + } + + if ( (rqparam==READ_CONF_DATA_STATE) || + (rqparam==NOP_STATE) ) { + qeth_wakeup(card); + return; + } + + if (cstat != 0) { + sprintf(dbf_text,"qchk%4x",irq); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",cstat,dstat); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"%4x",rqparam); + QETH_DBF_TEXT2(0,trace,dbf_text); + PRINT_WARN("got nonzero channel status in qdio_handler " \ + "(irq 0x%x, devstat 0x%02x, schstat 0x%02x)\n", + irq,dstat,cstat); + } + + if (dstat&~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) { + PRINT_WARN("got the following dstat on the qdio channel: " \ + "irq 0x%x, dstat 0x%02x, cstat 0x%02x, " \ + "rqparam=%i\n", + irq,dstat,cstat,rqparam); + } + +} + +static int qeth_register_netdev(qeth_card_t *card) +{ + int result; + char dbf_text[15]; + + sprintf(dbf_text,"rgnd%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + result=register_netdev(card->dev); + + return result; +} + +static void qeth_unregister_netdev(qeth_card_t *card) +{ + char dbf_text[15]; + + sprintf(dbf_text,"nrgn%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + unregister_netdev(card->dev); +} + +static int qeth_stop(struct net_device *dev) +{ + char dbf_text[15]; + qeth_card_t *card; + + card=(qeth_card_t *)dev->priv; + sprintf(dbf_text,"stop%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_TEXT2(0,setup,dbf_text); + + qeth_save_dev_flag_state(card); + + netif_stop_queue(dev); + if (atomic_swap(&((qeth_card_t*)dev->priv)->is_open,0)) { + MOD_DEC_USE_COUNT; + } + + return 0; +} + +static void qeth_softshutdown(qeth_card_t *card) +{ + char dbf_text[15]; + + sprintf(dbf_text,"ssht%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + qeth_send_stoplan(card); +} + +static void qeth_clear_card(qeth_card_t *card,int qdio_clean,int use_halt) +{ + unsigned long flags0,flags1,flags2; + char dbf_text[15]; + + sprintf(dbf_text,"clr%c%4x",(qdio_clean)?'q':' ',card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_TEXT1(0,setup,dbf_text); + + atomic_set(&card->write_busy,0); + if (qdio_clean) + qdio_cleanup(card->irq2, + (card->type==QETH_CARD_TYPE_IQD)? + QDIO_FLAG_CLEANUP_USING_HALT: + QDIO_FLAG_CLEANUP_USING_CLEAR); + + if (use_halt) { + atomic_set(&card->clear_succeeded0,0); + atomic_set(&card->clear_succeeded1,0); + atomic_set(&card->clear_succeeded2,0); + + s390irq_spin_lock_irqsave(card->irq0,flags0); + halt_IO(card->irq0,CLEAR_STATE,0); + s390irq_spin_unlock_irqrestore(card->irq0,flags0); + + s390irq_spin_lock_irqsave(card->irq1,flags1); + halt_IO(card->irq1,CLEAR_STATE,0); + s390irq_spin_unlock_irqrestore(card->irq1,flags1); + + s390irq_spin_lock_irqsave(card->irq2,flags2); + halt_IO(card->irq2,CLEAR_STATE,0); + s390irq_spin_unlock_irqrestore(card->irq2,flags2); + + if (qeth_wait_for_event(&card->clear_succeeded0, + QETH_CLEAR_TIMEOUT)==-ETIME) { + if (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK) { + PRINT_ERR("Did not get interrupt on halt_IO " \ + "on irq 0x%x.\n",card->irq0); + } + } + if (qeth_wait_for_event(&card->clear_succeeded1, + QETH_CLEAR_TIMEOUT)==-ETIME) { + if (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK) { + PRINT_ERR("Did not get interrupt on halt_IO " \ + "on irq 0x%x.\n",card->irq1); + } + } + if (qeth_wait_for_event(&card->clear_succeeded2, + QETH_CLEAR_TIMEOUT)==-ETIME) { + if (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK) { + PRINT_ERR("Did not get interrupt on halt_IO " \ + "on irq 0x%x.\n",card->irq2); + } + } + } + + atomic_set(&card->clear_succeeded0,0); + atomic_set(&card->clear_succeeded1,0); + atomic_set(&card->clear_succeeded2,0); + + s390irq_spin_lock_irqsave(card->irq0,flags0); + clear_IO(card->irq0,CLEAR_STATE,0); + s390irq_spin_unlock_irqrestore(card->irq0,flags0); + + s390irq_spin_lock_irqsave(card->irq1,flags1); + clear_IO(card->irq1,CLEAR_STATE,0); + s390irq_spin_unlock_irqrestore(card->irq1,flags1); + + s390irq_spin_lock_irqsave(card->irq2,flags2); + clear_IO(card->irq2,CLEAR_STATE,0); + s390irq_spin_unlock_irqrestore(card->irq2,flags2); + + if (qeth_wait_for_event(&card->clear_succeeded0, + QETH_CLEAR_TIMEOUT)==-ETIME) { + if (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK) { + PRINT_ERR("Did not get interrupt on clear_IO on " \ + "irq 0x%x.\n",card->irq0); + } + } + if (qeth_wait_for_event(&card->clear_succeeded1, + QETH_CLEAR_TIMEOUT)==-ETIME) { + if (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK) { + PRINT_ERR("Did not get interrupt on clear_IO on " \ + "irq 0x%x.\n",card->irq1); + } + } + if (qeth_wait_for_event(&card->clear_succeeded2, + QETH_CLEAR_TIMEOUT)==-ETIME) { + if (atomic_read(&card->shutdown_phase)!= + QETH_REMOVE_CARD_QUICK) { + PRINT_ERR("Did not get interrupt on clear_IO on " \ + "irq 0x%x.\n",card->irq2); + } + } +} + +static void qeth_free_card(qeth_card_t *card) +{ + int i,j; + char dbf_text[15]; + int element_count; + qeth_vipa_entry_t *e,*e2; + + if (!card) return; + + sprintf(dbf_text,"free%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_TEXT1(0,setup,dbf_text); + + my_write_lock(&card->vipa_list_lock); + e=card->vipa_list; + while (e) { + e2=e->next; + kfree(e); + e=e2; + } + my_write_unlock(&card->vipa_list_lock); + + element_count=(card->options.memusage==MEMUSAGE_DISCONTIG)? + BUFFER_MAX_ELEMENTS:1; + for (i=0;ioptions.inbound_buffer_count;i++) { + for (j=0;jinbound_buffer_pool_entry[i][j]) { + kfree(card->inbound_buffer_pool_entry[i][j]); + card->inbound_buffer_pool_entry[i][j]=NULL; + } + } + } + for (i=0;ino_queues;i++) + if (card->outbound_ringbuffer[i]) + vfree(card->outbound_ringbuffer[i]); + + if (card->stats) kfree(card->stats); + if (card->dma_stuff) kfree(card->dma_stuff); + if (card->dev) kfree(card->dev); + if (card->devstat2) kfree(card->devstat2); + if (card->devstat1) kfree(card->devstat1); + if (card->devstat0) kfree(card->devstat0); + vfree(card); /* we checked against NULL already */ +} + +/* also locked from outside (setup_lock) */ +static void qeth_remove_card_from_list(qeth_card_t *card) +{ + qeth_card_t *cn; + unsigned long flags0,flags1,flags2; + char dbf_text[15]; + + my_write_lock(&list_lock); + if (!card) { + QETH_DBF_TEXT2(0,trace,"RMCWNOCD"); + PRINT_WARN("qeth_remove_card_from_list call with no card!\n"); + return; + } + + sprintf(dbf_text,"rmcl%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + /* check first, if card is in list */ + if (!firstcard) { + QETH_DBF_TEXT2(0,trace,"NOCRDINL"); + PRINT_WARN("qeth_remove_card_from_list called on " \ + "empty card list!!\n"); + return; + } + + s390irq_spin_lock_irqsave(card->irq0,flags0); + s390irq_spin_lock_irqsave(card->irq1,flags1); + s390irq_spin_lock_irqsave(card->irq2,flags2); + + if (firstcard==card) + firstcard=card->next; + else { + cn=firstcard; + while (cn->next) { + if (cn->next==card) { + cn->next=card->next; + card->next=NULL; + break; + } + cn = cn->next; + } + } + + s390irq_spin_unlock_irqrestore(card->irq2,flags2); + s390irq_spin_unlock_irqrestore(card->irq1,flags1); + s390irq_spin_unlock_irqrestore(card->irq0,flags0); + + + my_write_unlock(&list_lock); + +} + +static void qeth_delete_all_ips(qeth_card_t *card) +{ + qeth_vipa_entry_t *e; + + if (atomic_read(&card->is_softsetup)) { + qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa); + +#ifdef QETH_IPV6 + qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa); +#endif /* QETH_IPV6 */ + + my_write_lock(&card->vipa_list_lock); + e=card->vipa_list; + while (e) { + e->state=VIPA_2_B_REMOVED; + e=e->next; + } + my_write_unlock(&card->vipa_list_lock); + qeth_start_softsetup_thread(card); + } +} + +static void qeth_remove_card(qeth_card_t *card,int method) +{ + char dbf_text[15]; + + if (!card) { + return; + } + sprintf(dbf_text,"rmcd%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_TEXT1(0,setup,dbf_text); + + if (method==QETH_REMOVE_CARD_PROPER) { + atomic_set(&card->shutdown_phase,QETH_REMOVE_CARD_PROPER); + if (atomic_read(&card->is_open)) { + qeth_stop(card->dev); + qeth_wait_nonbusy(QETH_REMOVE_WAIT_TIME); + } + qeth_delete_all_ips(card); + } else { + atomic_set(&card->shutdown_phase,QETH_REMOVE_CARD_QUICK); + } + atomic_set(&card->write_busy,0); + + QETH_DBF_TEXT4(0,trace,"freeskbs"); + qeth_free_all_skbs(card); + + QETH_DBF_TEXT2(0,trace,"upthrsem"); + + up(&card->softsetup_thread_sem); + up(&card->reinit_thread_sem); + while ( (atomic_read(&card->softsetup_thread_is_running)) || + (atomic_read(&card->reinit_counter)) ) { + qeth_wait_nonbusy(QETH_WAIT_FOR_THREAD_TIME); + } + + if (method==QETH_REMOVE_CARD_PROPER) { + QETH_DBF_TEXT4(0,trace,"softshut"); + qeth_softshutdown(card); + qeth_wait_nonbusy(QETH_REMOVE_WAIT_TIME); + } + + atomic_set(&card->is_startlaned,0); /* paranoia, qeth_stop + should prevent + further calls of + hard_start_xmit */ + + if (atomic_read(&card->is_registered)) { + QETH_DBF_TEXT2(0,trace,"unregdev"); + qeth_unregister_netdev(card); + qeth_wait_nonbusy(QETH_REMOVE_WAIT_TIME); + atomic_set(&card->is_registered,0); + } + + qeth_put_unique_id(card); + + QETH_DBF_TEXT2(0,trace,"clrcard"); + if (atomic_read(&card->is_hardsetup)) { + PRINT_STUPID("clearing card %s\n",card->dev_name); + qeth_clear_card(card,1,0); + } + + atomic_set(&card->is_hardsetup,0); + atomic_set(&card->is_softsetup,0); + + + if (card->has_irq>=3) { + QETH_DBF_TEXT2(0,trace,"freeirq2"); + chandev_free_irq(card->irq2,card->devstat2); + } + if (card->has_irq>=2) { + QETH_DBF_TEXT2(0,trace,"freeirq1"); + chandev_free_irq(card->irq1,card->devstat1); + } + if (card->has_irq>=1) { + QETH_DBF_TEXT2(0,trace,"freeirq0"); + chandev_free_irq(card->irq0,card->devstat0); + } +} + +static void qeth_destructor(struct net_device *dev) +{ + char dbf_text[15]; + qeth_card_t *card; + + card=(qeth_card_t *)(dev->priv); + sprintf(dbf_text,"dstr%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); +} + +static void qeth_set_multicast_list(struct net_device *dev) +{ + char dbf_text[15]; + qeth_card_t *card=dev->priv; + + sprintf(dbf_text,"smcl%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + qeth_start_softsetup_thread(card); +} + +static int qeth_set_mac_address(struct net_device *dev,void *addr) +{ + char dbf_text[15]; + + sprintf(dbf_text,"stmc%4x",((qeth_card_t *)dev->priv)->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + return -EOPNOTSUPP; +} + +static int qeth_neigh_setup(struct net_device *dev,struct neigh_parms *np) +{ + char dbf_text[15]; + + sprintf(dbf_text,"ngst%4x",((qeth_card_t *)dev->priv)->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + return 0; +} + +static void qeth_generate_tokens(qeth_card_t *card) +{ + card->token.issuer_rm_w=0x00010103UL; + card->token.cm_filter_w=0x00010108UL; + card->token.cm_connection_w=0x0001010aUL; + card->token.ulp_filter_w=0x0001010bUL; + card->token.ulp_connection_w=0x0001010dUL; +} + +static int qeth_peer_func_level(int level) +{ + if ((level&0xff)==8) return (level&0xff)+0x400; + if ( ((level>>8)&3)==1) return (level&0xff)+0x200; + return level; /* hmmm... don't know what to do with that level. */ +} + +static int qeth_idx_activate_read(qeth_card_t *card) +{ + int result,result2; + __u16 temp; + unsigned long flags; + char dbf_text[15]; + + result=result2=0; + + memcpy(&card->dma_stuff->write_ccw,WRITE_CCW,sizeof(ccw1_t)); + card->dma_stuff->write_ccw.count=IDX_ACTIVATE_SIZE; + card->dma_stuff->write_ccw.cda= + QETH_GET_ADDR(card->dma_stuff->sendbuf); + + memcpy(card->dma_stuff->sendbuf,IDX_ACTIVATE_READ, + IDX_ACTIVATE_SIZE); + memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(card->dma_stuff->sendbuf), + &card->seqno.trans_hdr,QETH_SEQ_NO_LENGTH); + + memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(card->dma_stuff->sendbuf), + &card->token.issuer_rm_w,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->sendbuf), + &card->func_level,2); + + temp=card->devno2; + memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(card->dma_stuff->sendbuf), + &temp,2); + temp=(card->cula<<8)+card->unit_addr2; + memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(card->dma_stuff->sendbuf), + &temp,2); + + sprintf(dbf_text,"iarw%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_HEX2(0,control,card->dma_stuff->sendbuf, + QETH_DBF_CONTROL_LEN); + + s390irq_spin_lock_irqsave(card->irq0,flags); + result=do_IO(card->irq0,&card->dma_stuff->write_ccw, + IDX_ACTIVATE_WRITE_STATE,0,0); + if (result) { + qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); + result2=do_IO(card->irq0,&card->dma_stuff->write_ccw, + IDX_ACTIVATE_WRITE_STATE,0,0); + sprintf(dbf_text,"IRW1%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"IRW2%4x",result2); + QETH_DBF_TEXT2(0,trace,dbf_text); + PRINT_WARN("qeth_idx_activate_read (write): do_IO returned " \ + "%i, next try returns %i\n",result,result2); + } + s390irq_spin_unlock_irqrestore(card->irq0,flags); + + if (atomic_read(&card->break_out)) { + QETH_DBF_TEXT3(0,trace,"IARWBRKO"); + result=-EIO; + goto exit; + } + + if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) { + sprintf(dbf_text,"IRWT%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_ERR("IDX_ACTIVATE(wr) on read channel irq 0x%x: " \ + "timeout\n",card->irq0); + result=-EIO; + goto exit; + } + + /* start reading on read channel, card->read_ccw is not yet used */ + memcpy(&card->dma_stuff->read_ccw,READ_CCW,sizeof(ccw1_t)); + card->dma_stuff->read_ccw.count=QETH_BUFSIZE; + card->dma_stuff->read_ccw.cda=QETH_GET_ADDR(card->dma_stuff->recbuf); + + s390irq_spin_lock_irqsave(card->irq0,flags); + result2=0; + result=do_IO(card->irq0,&card->dma_stuff->read_ccw, + IDX_ACTIVATE_READ_STATE,0,0); + if (result) { + qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); + result2=do_IO(card->irq0,&card->dma_stuff->read_ccw, + IDX_ACTIVATE_READ_STATE,0,0); + sprintf(dbf_text,"IRR1%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"IRR2%4x",result2); + QETH_DBF_TEXT2(0,trace,dbf_text); + PRINT_WARN("qeth_idx_activate_read (read): do_IO " \ + "returned %i, next try returns %i\n", + result,result2); + } + s390irq_spin_unlock_irqrestore(card->irq0,flags); + + if (result2) { + result=result2; + if (result) goto exit; + } + + if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) { + sprintf(dbf_text,"IRRT%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_ERR("IDX_ACTIVATE(rd) on read channel irq 0x%x: " \ + "timeout\n",card->irq0); + result=-EIO; + goto exit; + } + sprintf(dbf_text,"iarr%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_HEX2(0,control,card->dma_stuff->recbuf, + QETH_DBF_CONTROL_LEN); + + if (!(QETH_IS_IDX_ACT_POS_REPLY(card->dma_stuff->recbuf))) { + sprintf(dbf_text,"IRNR%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_ERR("IDX_ACTIVATE on read channel irq 0x%x: negative " \ + "reply\n",card->irq0); + result=-EIO; + goto exit; + } + + card->portname_required= + ((!QETH_IDX_NO_PORTNAME_REQUIRED(card->dma_stuff->recbuf))&& + (card->type==QETH_CARD_TYPE_OSAE)); + + memcpy(&temp,QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->recbuf),2); + if (temp!=qeth_peer_func_level(card->func_level)) { + sprintf(dbf_text,"IRFL%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",card->func_level,temp); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_WARN("IDX_ACTIVATE on read channel irq 0x%x: " \ + "function level mismatch (sent: 0x%x, " \ + "received: 0x%x)\n", + card->irq0,card->func_level,temp); + result=-EIO; + } + + memcpy(&card->token.issuer_rm_r, + QETH_IDX_ACT_ISSUER_RM_TOKEN(card->dma_stuff->recbuf), + QETH_MPC_TOKEN_LENGTH); + + memcpy(&card->level[0], + QETH_IDX_REPLY_LEVEL(card->dma_stuff->recbuf), + QETH_MCL_LENGTH); + exit: + return result; +} + +static int qeth_idx_activate_write(qeth_card_t *card) +{ + int result,result2; + __u16 temp; + unsigned long flags; + char dbf_text[15]; + + result=result2=0; + + memcpy(&card->dma_stuff->write_ccw,WRITE_CCW,sizeof(ccw1_t)); + card->dma_stuff->write_ccw.count=IDX_ACTIVATE_SIZE; + card->dma_stuff->write_ccw.cda= + QETH_GET_ADDR(card->dma_stuff->sendbuf); + + memcpy(card->dma_stuff->sendbuf,IDX_ACTIVATE_WRITE, + IDX_ACTIVATE_SIZE); + memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(card->dma_stuff->sendbuf), + &card->seqno.trans_hdr,QETH_SEQ_NO_LENGTH); + card->seqno.trans_hdr++; + + memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(card->dma_stuff->sendbuf), + &card->token.issuer_rm_w,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->sendbuf), + &card->func_level,2); + + temp=card->devno2; + memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(card->dma_stuff->sendbuf), + &temp,2); + temp=(card->cula<<8)+card->unit_addr2; + memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(card->dma_stuff->sendbuf), + &temp,2); + + sprintf(dbf_text,"iaww%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_HEX2(0,control,card->dma_stuff->sendbuf, + QETH_DBF_CONTROL_LEN); + + s390irq_spin_lock_irqsave(card->irq1,flags); + result=do_IO(card->irq1,&card->dma_stuff->write_ccw, + IDX_ACTIVATE_WRITE_STATE,0,0); + if (result) { + qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); + result2=do_IO(card->irq1,&card->dma_stuff->write_ccw, + IDX_ACTIVATE_WRITE_STATE,0,0); + sprintf(dbf_text,"IWW1%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"IWW2%4x",result2); + QETH_DBF_TEXT2(0,trace,dbf_text); + PRINT_WARN("qeth_idx_activate_write (write): do_IO " \ + "returned %i, next try returns %i\n", + result,result2); + } + s390irq_spin_unlock_irqrestore(card->irq1,flags); + + if (atomic_read(&card->break_out)) { + QETH_DBF_TEXT3(0,trace,"IAWWBRKO"); + result=-EIO; + goto exit; + } + + if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) { + sprintf(dbf_text,"IWWT%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_ERR("IDX_ACTIVATE(wr) on write channel irq 0x%x: " \ + "timeout\n",card->irq1); + result=-EIO; + goto exit; + } + + QETH_DBF_TEXT3(0,trace,"idxawrrd"); + + /* start one read on write channel */ + memcpy(&card->dma_stuff->read_ccw,READ_CCW,sizeof(ccw1_t)); + card->dma_stuff->read_ccw.count=QETH_BUFSIZE; + + /* recbuf and card->read_ccw is not yet used by any other + read channel program */ + card->dma_stuff->read_ccw.cda=QETH_GET_ADDR(card->dma_stuff->recbuf); + + s390irq_spin_lock_irqsave(card->irq1,flags); + result2=0; + result=do_IO(card->irq1,&card->dma_stuff->read_ccw, + IDX_ACTIVATE_READ_STATE,0,0); + if (result) { + qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); + result2=do_IO(card->irq1,&card->dma_stuff->read_ccw, + IDX_ACTIVATE_READ_STATE,0,0); + sprintf(dbf_text,"IWR1%4x",result); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"IWR2%4x",result2); + QETH_DBF_TEXT2(0,trace,dbf_text); + PRINT_WARN("qeth_idx_activate_write (read): do_IO returned " \ + "%i, next try returns %i\n",result,result2); + } + + s390irq_spin_unlock_irqrestore(card->irq1,flags); + + if (result2) { + result=result2; + if (result) goto exit; + } + + if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) { + sprintf(dbf_text,"IWRT%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_ERR("IDX_ACTIVATE(rd) on write channel irq 0x%x: " \ + "timeout\n",card->irq1); + result=-EIO; + goto exit; + } + sprintf(dbf_text,"iawr%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + QETH_DBF_HEX2(0,control,card->dma_stuff->recbuf, + QETH_DBF_CONTROL_LEN); + + if (!(QETH_IS_IDX_ACT_POS_REPLY(card->dma_stuff->recbuf))) { + sprintf(dbf_text,"IWNR%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_ERR("IDX_ACTIVATE on write channel irq 0x%x: " \ + "negative reply\n",card->irq1); + result=-EIO; + goto exit; + } + + memcpy(&temp,QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->recbuf),2); + if ((temp&~0x0100)!=qeth_peer_func_level(card->func_level)) { + sprintf(dbf_text,"IWFM%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + sprintf(dbf_text,"%4x%4x",card->func_level,temp); + QETH_DBF_TEXT1(0,trace,dbf_text); + PRINT_WARN("IDX_ACTIVATE on write channel irq 0x%x: " \ + "function level mismatch (sent: 0x%x, " \ + "received: 0x%x)\n", + card->irq1,card->func_level,temp); + result=-EIO; + } + + exit: + return result; +} + +static int qeth_cm_enable(qeth_card_t *card) +{ + unsigned char *buffer; + int result; + char dbf_text[15]; + + memcpy(card->send_buf,CM_ENABLE,CM_ENABLE_SIZE); + + memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(card->send_buf), + &card->token.issuer_rm_r,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_CM_ENABLE_FILTER_TOKEN(card->send_buf), + &card->token.cm_filter_w,QETH_MPC_TOKEN_LENGTH); + + buffer=qeth_send_control_data(card,card->send_buf, + CM_ENABLE_SIZE,MPC_SETUP_STATE); + + if (!buffer) { + QETH_DBF_TEXT2(0,trace,"CME:NOBF"); + return -EIO; + } + + memcpy(&card->token.cm_filter_r, + QETH_CM_ENABLE_RESP_FILTER_TOKEN(buffer), + QETH_MPC_TOKEN_LENGTH); + + result=qeth_check_idx_response(buffer); + + sprintf(dbf_text,"cme=%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return result; +} + +static int qeth_cm_setup(qeth_card_t *card) +{ + unsigned char *buffer; + int result; + char dbf_text[15]; + + memcpy(card->send_buf,CM_SETUP,CM_SETUP_SIZE); + + memcpy(QETH_CM_SETUP_DEST_ADDR(card->send_buf), + &card->token.issuer_rm_r,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(card->send_buf), + &card->token.cm_connection_w,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_CM_SETUP_FILTER_TOKEN(card->send_buf), + &card->token.cm_filter_r,QETH_MPC_TOKEN_LENGTH); + + buffer=qeth_send_control_data(card,card->send_buf, + CM_SETUP_SIZE,MPC_SETUP_STATE); + + if (!buffer) { + QETH_DBF_TEXT2(0,trace,"CMS:NOBF"); + return -EIO; + } + + memcpy(&card->token.cm_connection_r, + QETH_CM_SETUP_RESP_DEST_ADDR(buffer), + QETH_MPC_TOKEN_LENGTH); + + result=qeth_check_idx_response(buffer); + + sprintf(dbf_text,"cms=%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return result; +} + +static int qeth_ulp_enable(qeth_card_t *card) +{ + unsigned char *buffer; + __u16 mtu,framesize; + __u16 len; + __u8 link_type; + int result; + char dbf_text[15]; + + memcpy(card->send_buf,ULP_ENABLE,ULP_ENABLE_SIZE); + + *(QETH_ULP_ENABLE_LINKNUM(card->send_buf))=(__u8)card->options.portno; + + memcpy(QETH_ULP_ENABLE_DEST_ADDR(card->send_buf), + &card->token.cm_connection_r,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(card->send_buf), + &card->token.ulp_filter_w,QETH_MPC_TOKEN_LENGTH); + + memcpy(QETH_ULP_ENABLE_PORTNAME_AND_LL(card->send_buf), + card->options.portname,9); + + buffer=qeth_send_control_data(card,card->send_buf, + ULP_ENABLE_SIZE,MPC_SETUP_STATE); + + if (!buffer) { + QETH_DBF_TEXT2(0,trace,"ULE:NOBF"); + return -EIO; + } + + memcpy(&card->token.ulp_filter_r, + QETH_ULP_ENABLE_RESP_FILTER_TOKEN(buffer), + QETH_MPC_TOKEN_LENGTH); + + /* to be done before qeth_init_ringbuffers and qeth_init_dev */ + if (qeth_get_mtu_out_of_mpc(card->type)) { + memcpy(&framesize,QETH_ULP_ENABLE_RESP_MAX_MTU(buffer),2); + mtu=qeth_get_mtu_outof_framesize(framesize); + + sprintf(dbf_text,"ule:%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"mtu=%4x",mtu); + QETH_DBF_TEXT2(0,trace,dbf_text); + + if (!mtu) return -EINVAL; + + card->max_mtu=mtu; + card->initial_mtu=mtu; + card->inbound_buffer_size=mtu+2*PAGE_SIZE; + } else { + card->initial_mtu=qeth_get_initial_mtu_for_card(card); + card->max_mtu=qeth_get_max_mtu_for_card(card->type); + card->inbound_buffer_size=DEFAULT_BUFFER_SIZE; + } + + memcpy(&len,QETH_ULP_ENABLE_RESP_DIFINFO_LEN(buffer),2); + if (len>=QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) { + memcpy(&link_type,QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer),1); + card->link_type=link_type; + sprintf(dbf_text,"link=%2x",link_type); + QETH_DBF_TEXT2(0,trace,dbf_text); + } else card->link_type=0; + + result=qeth_check_idx_response(buffer); + + sprintf(dbf_text,"ule=%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return result; +} + +static int qeth_ulp_setup(qeth_card_t *card) +{ + unsigned char *buffer; + __u16 temp; + int result; + char dbf_text[15]; + + memcpy(card->send_buf,ULP_SETUP,ULP_SETUP_SIZE); + + memcpy(QETH_ULP_SETUP_DEST_ADDR(card->send_buf), + &card->token.cm_connection_r,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(card->send_buf), + &card->token.ulp_connection_w,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_ULP_SETUP_FILTER_TOKEN(card->send_buf), + &card->token.ulp_filter_r,QETH_MPC_TOKEN_LENGTH); + + temp=card->devno2; + memcpy(QETH_ULP_SETUP_CUA(card->send_buf), + &temp,2); + temp=(card->cula<<8)+card->unit_addr2; + memcpy(QETH_ULP_SETUP_REAL_DEVADDR(card->send_buf), + &temp,2); + + buffer=qeth_send_control_data(card,card->send_buf, + ULP_SETUP_SIZE,MPC_SETUP_STATE); + + if (!buffer) { + QETH_DBF_TEXT2(0,trace,"ULS:NOBF"); + return -EIO; + } + + memcpy(&card->token.ulp_connection_r, + QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(buffer), + QETH_MPC_TOKEN_LENGTH); + + result=qeth_check_idx_response(buffer); + + sprintf(dbf_text,"uls=%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return result; +} + +static int qeth_qdio_establish(qeth_card_t *card) +{ + int result; + char adapter_area[15]; + char dbf_text[15]; + void **input_array,**output_array,**ptr; + int i,j; + qdio_initialize_t init_data; + + adapter_area[0]=_ascebc['P']; + adapter_area[1]=_ascebc['C']; + adapter_area[2]=_ascebc['I']; + adapter_area[3]=_ascebc['T']; + *((unsigned int*)(&adapter_area[4]))=PCI_THRESHOLD_A; + *((unsigned int*)(&adapter_area[8]))=PCI_THRESHOLD_B; + *((unsigned int*)(&adapter_area[12]))=PCI_TIMER_VALUE; + + input_array=vmalloc(QDIO_MAX_BUFFERS_PER_Q*sizeof(void*)); + if (!input_array) return -ENOMEM; + ptr=input_array; + for (j=0;jinbound_qdio_buffers[j]); + ptr++; + } + + output_array=vmalloc(QDIO_MAX_BUFFERS_PER_Q*sizeof(void*)* + card->no_queues); + if (!output_array) { + vfree(input_array); + return -ENOMEM; + } + ptr=output_array; + for (i=0;ino_queues;i++) + for (j=0;joutbound_ringbuffer[i]-> + buffer[j]); + ptr++; + } + + init_data.irq=card->irq2; + init_data.q_format=qeth_get_q_format(card->type); + init_data.qib_param_field_format=0; + init_data.qib_param_field=adapter_area; + init_data.input_slib_elements=NULL; + init_data.output_slib_elements=NULL; + init_data.min_input_threshold=card->options.polltime; + init_data.max_input_threshold=card->options.polltime; + init_data.min_output_threshold=QETH_MIN_OUTPUT_THRESHOLD; + init_data.max_output_threshold=QETH_MAX_OUTPUT_THRESHOLD; + init_data.no_input_qs=1; + init_data.no_output_qs=card->no_queues; + init_data.input_handler=qeth_qdio_input_handler; + init_data.output_handler=qeth_qdio_output_handler; + init_data.int_parm=(unsigned long)card; + init_data.flags=QDIO_INBOUND_0COPY_SBALS| + QDIO_OUTBOUND_0COPY_SBALS| + QDIO_USE_OUTBOUND_PCIS; + if (card->do_pfix) + init_data.flags |= QDIO_PFIX; + init_data.input_sbal_addr_array=input_array; + init_data.output_sbal_addr_array=output_array; + + result=qdio_initialize(&init_data); + + vfree(input_array); + vfree(output_array); + + sprintf(dbf_text,"qde=%4i",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return result; +} + +static int qeth_qdio_activate(qeth_card_t *card) +{ + int result; + char dbf_text[15]; + + result=qdio_activate(card->irq2,0); + + sprintf(dbf_text,"qda=%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return result; +} + +static int qeth_dm_act(qeth_card_t *card) +{ + unsigned char *buffer; + int result; + char dbf_text[15]; + + memcpy(card->send_buf,DM_ACT,DM_ACT_SIZE); + + memcpy(QETH_DM_ACT_DEST_ADDR(card->send_buf), + &card->token.cm_connection_r,QETH_MPC_TOKEN_LENGTH); + memcpy(QETH_DM_ACT_CONNECTION_TOKEN(card->send_buf), + &card->token.ulp_connection_r,QETH_MPC_TOKEN_LENGTH); + + buffer=qeth_send_control_data(card,card->send_buf, + DM_ACT_SIZE,MPC_SETUP_STATE); + + if (!buffer) { + QETH_DBF_TEXT2(0,trace,"DMA:NOBF"); + return -EIO; + } + + result=qeth_check_idx_response(buffer); + + sprintf(dbf_text,"dma=%4x",result); + QETH_DBF_TEXT3(0,trace,dbf_text); + + return result; +} + +#if defined(QETH_VLAN)||defined(QETH_IPV6) +static int qeth_verify_dev(struct net_device *dev) +{ + qeth_card_t *tmp; + int result=0; +#ifdef QETH_VLAN + struct vlan_group *vlan_grp; + int i; +#endif + + my_read_lock(&list_lock); + tmp=firstcard; + for (;tmp&&(!result);tmp=tmp->next) { + if (atomic_read(&tmp->shutdown_phase)) + continue; + if (dev==tmp->dev) { + result=QETH_VERIFY_IS_REAL_DEV; + } +#ifdef QETH_VLAN + /* check all vlan devices */ + vlan_grp = (struct vlan_group *) tmp->vlangrp; + if (vlan_grp) { + for (i=0;ivlan_devices[i]==dev) { + result=QETH_VERIFY_IS_VLAN_DEV; + } + } + } + +#endif + } + my_read_unlock(&list_lock); + return result; +} +#endif /* defined(QETH_VLAN)||defined(QETH_IPV6) */ + +static int qeth_verify_card(qeth_card_t *card) +{ + qeth_card_t *tmp; + int result=0; + + my_read_lock(&list_lock); + tmp=firstcard; + while (tmp) { + if ((card==tmp) && (!atomic_read(&card->shutdown_phase))) { + result=1; + break; + } + tmp=tmp->next; + } + my_read_unlock(&list_lock); + return result; +} + +#ifdef QETH_IPV6 +extern struct neigh_table arp_tbl; +int (*qeth_old_arp_constructor)(struct neighbour *); +static struct neigh_ops arp_direct_ops_template = +{ + family: AF_INET, + destructor: NULL, + solicit: NULL, + error_report: NULL, + output: dev_queue_xmit, + connected_output: dev_queue_xmit, + hh_output: dev_queue_xmit, + queue_xmit: dev_queue_xmit +}; +/* as we have neighbour structures point to this structure, even + * after our life time, this will stay in memory as a leak */ +static struct neigh_ops *arp_direct_ops; + +static int qeth_arp_constructor(struct neighbour *neigh) +{ + char dbf_text[15]; + struct net_device *dev = neigh->dev; + struct in_device *in_dev = in_dev_get(dev); + + if (in_dev == NULL) + return -EINVAL; + + QETH_DBF_TEXT4(0,trace,"arpconst"); + if (!qeth_verify_dev(dev)) { + + in_dev_put(in_dev); + return qeth_old_arp_constructor(neigh); + } + + neigh->type = inet_addr_type(*(u32*)neigh->primary_key); + if (in_dev->arp_parms) + neigh->parms = in_dev->arp_parms; + + in_dev_put(in_dev); + + sprintf(dbf_text,"%08x",ntohl(*((__u32*)(neigh->primary_key)))); + QETH_DBF_TEXT4(0,trace,dbf_text); + QETH_DBF_HEX4(0,trace,&neigh,sizeof(void*)); + + neigh->nud_state = NUD_NOARP; + neigh->ops = arp_direct_ops; + neigh->output = neigh->ops->queue_xmit; + return 0; +} + +static int qeth_hard_header(struct sk_buff *skb,struct net_device *dev, + unsigned short type,void *daddr,void *saddr, + unsigned len) +{ + qeth_card_t *card; + + QETH_DBF_TEXT5(0,trace,"hardhdr"); + +#ifdef QETH_VLAN + if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) + card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv; + else +#endif + card=(qeth_card_t*)dev->priv; + + return card->hard_header(skb,dev,type,daddr,saddr,len); +} + +static void qeth_header_cache_update(struct hh_cache *hh, + struct net_device *dev, + unsigned char *haddr) +{ + qeth_card_t *card; + + card=(qeth_card_t*)dev->priv; + QETH_DBF_TEXT5(0,trace,"hdrcheup"); + return card->header_cache_update(hh,dev,haddr); +} + +static int qeth_rebuild_header(struct sk_buff *skb) +{ + qeth_card_t *card; + QETH_DBF_TEXT5(0,trace,"rebldhdr"); + if (skb->protocol==__constant_htons(ETH_P_IP)) return 0; + +#ifdef QETH_VLAN + if (qeth_verify_dev(skb->dev)==QETH_VERIFY_IS_VLAN_DEV) + card = (qeth_card_t *)VLAN_DEV_INFO(skb->dev)->real_dev->priv; + else +#endif + card=(qeth_card_t*)skb->dev->priv; + + return card->rebuild_header(skb); +} + +static void qeth_ipv6_init_card(qeth_card_t *card) +{ + card->hard_header=qeth_get_hard_header(card->link_type); + card->rebuild_header=qeth_get_rebuild_header(card->link_type); + card->hard_header_cache=qeth_get_hard_header_cache(card->link_type); + card->header_cache_update= + qeth_get_header_cache_update(card->link_type); + card->type_trans=qeth_get_type_trans(card->link_type); +} +#endif /* QETH_IPV6 */ + +#ifdef QETH_VLAN +static void qeth_vlan_rx_register(struct net_device *dev, + struct vlan_group *grp) +{ + qeth_card_t *card; + card = (qeth_card_t *)dev->priv; + spin_lock_irq(&card->vlan_lock); + card->vlangrp = grp; + spin_unlock_irq(&card->vlan_lock); +} +static void qeth_vlan_rx_kill_vid(struct net_device *dev, + unsigned short vid) +{ + qeth_card_t *card; + card = (qeth_card_t *)dev->priv; + spin_lock_irq(&card->vlan_lock); + if (card->vlangrp) + card->vlangrp->vlan_devices[vid] = NULL; + spin_unlock_irq(&card->vlan_lock); +} + +#endif /*QETH_VLAN*/ + + +static void qeth_tx_timeout(struct net_device *dev) +{ + char dbf_text[15]; + qeth_card_t *card; + + card=(qeth_card_t *)dev->priv; + sprintf(dbf_text,"XMTO%4x",card->irq0); + QETH_DBF_TEXT2(1,trace,dbf_text); + card->stats->tx_errors++; + atomic_set(&card->problem,PROBLEM_TX_TIMEOUT); + qeth_schedule_recovery(card); +} + +static int qeth_init_dev(struct net_device *dev) +{ + qeth_card_t *card; + char dbf_text[15]; + + card=(qeth_card_t *)dev->priv; + + sprintf(dbf_text,"inid%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + dev->tx_timeout=&qeth_tx_timeout; + dev->watchdog_timeo=QETH_TX_TIMEOUT; + dev->open=qeth_open; + dev->stop=qeth_stop; + dev->set_config=qeth_set_config; + dev->hard_start_xmit=qeth_hard_start_xmit; + dev->do_ioctl=qeth_do_ioctl; + dev->get_stats=qeth_get_stats; + dev->change_mtu=qeth_change_mtu; +#ifdef QETH_VLAN + dev->vlan_rx_register = qeth_vlan_rx_register; + dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid; +#endif + + dev->rebuild_header= +#ifdef QETH_IPV6 + (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))? + (qeth_get_rebuild_header(card->link_type)? + qeth_rebuild_header:NULL): +#endif /* QETH_IPV6 */ + NULL; + dev->hard_header= +#ifdef QETH_IPV6 + (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))? + (qeth_get_hard_header(card->link_type)? + qeth_hard_header:NULL): +#endif /* QETH_IPV6 */ + NULL; + dev->header_cache_update= +#ifdef QETH_IPV6 + (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))? + (qeth_get_header_cache_update(card->link_type)? + qeth_header_cache_update:NULL): +#endif /* QETH_IPV6 */ + NULL; + dev->hard_header_cache= +#ifdef QETH_IPV6 + (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))? + qeth_get_hard_header_cache(card->link_type): +#endif /* QETH_IPV6 */ + NULL; + dev->hard_header_parse=NULL; + dev->destructor=qeth_destructor; + dev->set_multicast_list=qeth_set_multicast_list; + dev->set_mac_address=qeth_set_mac_address; + dev->neigh_setup=qeth_neigh_setup; + + dev->flags|=qeth_get_additional_dev_flags(card->type); + + dev->flags|=( + (card->options.fake_broadcast==FAKE_BROADCAST)|| + (card->broadcast_capable) + )? + IFF_BROADCAST:0; + + /* is done in hardsetup_card... see comment below + qeth_send_qipassist(card,4);*/ + + /* that was the old place. one id. we need to make sure, that + * hydra knows about us going to use the same id again, so we + * do that in hardsetup_card every time + qeth_get_unique_id(card);*/ + +#ifdef CONFIG_SHARED_IPV6_CARDS + dev->features=(card->unique_id&UNIQUE_ID_NOT_BY_CARD)? + 0:NETIF_F_SHARED_IPV6; + dev->dev_id=card->unique_id&0xffff; +#endif /* CONFIG_SHARED_IPV6_CARDS */ + + dev->tx_queue_len=qeth_get_device_tx_q_len(card->type); + dev->hard_header_len=qeth_get_hlen(card->link_type)+ + card->options.add_hhlen; + dev->addr_len=OSA_ADDR_LEN; /* is ok for eth, tr, atm lane */ + netif_start_queue(dev); + + dev->mtu=card->initial_mtu; + +#ifdef QETH_IPV6 + qeth_ipv6_init_card(card); +#endif /* QETH_IPV6 */ + + dev_init_buffers(dev); + + return 0; +} + +static int qeth_get_unitaddr(qeth_card_t *card) +{ + char *prcd; + int result=0; + char dbf_text[15]; + int length; + + sprintf(dbf_text,"gtua%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + result = read_conf_data(card->irq2, (void **)&prcd, &length, 0); + if (result) { + sprintf(dbf_text, "rcd%4x", result); + QETH_DBF_TEXT3(0, trace, dbf_text); + PRINT_ERR("read_conf_data for sch %x returned %i\n", + card->irq2, result); + goto exit; + } + + card->chpid = prcd[30]; + card->unit_addr2 = prcd[31]; + card->cula = prcd[63]; + /* Don't build queues with diag98 for VM guest lan. */ + card->do_pfix = (MACHINE_HAS_PFIX) ? ((prcd[0x10]!=_ascebc['V']) || + (prcd[0x11]!=_ascebc['M'])):0; + + sprintf(dbf_text,"chpid:%02x",card->chpid); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"unad2:%02x",card->unit_addr2); + QETH_DBF_TEXT2(0,trace,dbf_text); + sprintf(dbf_text,"cula:%02x",card->cula); + QETH_DBF_TEXT2(0,trace,dbf_text); + + result=0; + + exit: + return result; +} + +static int qeth_send_nops(qeth_card_t *card) +{ + int result,result2; + char dbf_text[15]; + int irq; + unsigned long saveflags; + + card->dma_stuff->write_ccw.cmd_code=CCW_NOP_CMD; + card->dma_stuff->write_ccw.flags=CCW_FLAG_SLI; + card->dma_stuff->write_ccw.count=CCW_NOP_COUNT; + card->dma_stuff->write_ccw.cda=(unsigned long)NULL; + +#define DO_SEND_NOP(subchannel) \ +do { \ + irq=subchannel; \ + sprintf(dbf_text,"snnp%4x",irq); \ + QETH_DBF_TEXT3(0,trace,dbf_text); \ +\ + s390irq_spin_lock_irqsave(irq,saveflags); \ + result=do_IO(irq,&card->dma_stuff->write_ccw,NOP_STATE,0,0); \ + if (result) { \ + qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); \ + result2=do_IO(irq,&card->dma_stuff->write_ccw, \ + NOP_STATE,0,0); \ + PRINT_WARN("qeth_send_nops on irq 0x%x: do_IO returned %i, " \ + "next try returns %i\n", \ + irq,result,result2); \ + result=result2; \ + } \ + s390irq_spin_unlock_irqrestore(irq,saveflags); \ +\ + if (result) goto exit; \ +\ + if (qeth_sleepon(card,QETH_NOP_TIMEOUT)) { \ + QETH_DBF_TEXT2(0,trace,"snnp:tme"); \ + result=-EIO; \ + goto exit; \ + } \ +} while (0) + + DO_SEND_NOP(card->irq0); + DO_SEND_NOP(card->irq1); + DO_SEND_NOP(card->irq2); + +exit: + return result; +} + +static void qeth_clear_card_structures(qeth_card_t *card) +{ + int i,j; + char dbf_text[15]; + + if (!card) { + QETH_DBF_TEXT2(0,trace,"clrCRDnc"); + return; + } + + sprintf(dbf_text,"clcs%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + atomic_set(&card->is_startlaned,0); + + for (i=0;isend_state[i]=SEND_STATE_DONT_PACK; + card->outbound_first_free_buffer[i]=0; + atomic_set(&card->outbound_used_buffers[i],0); + atomic_set(&card->outbound_ringbuffer_lock[i],0); + + for (j=0;joutbound_buffer_send_state[i][j]= + SEND_STATE_DONT_PACK; + card->send_retries[i][j]=0; + + if (ino_queues) { + card->outbound_ringbuffer[i]-> + ringbuf_element[j]. + next_element_to_fill=0; + card->outbound_bytes_in_buffer[i]=0; + skb_queue_head_init(&card-> + outbound_ringbuffer[i]-> + ringbuf_element[j]. + skb_list); + } + } + } + + for (i=0;ioptions.inbound_buffer_count;i++) { + xchg((int*)&card->inbound_buffer_pool_entry_used[i], + BUFFER_UNUSED); + } + + spin_lock_init(&card->requeue_input_lock); + atomic_set(&card->requeue_position,0); + atomic_set(&card->requeue_counter,0); + + card->seqno.trans_hdr=0; + card->seqno.pdu_hdr=0; + card->seqno.pdu_hdr_ack=0; + card->seqno.ipa=0; + + qeth_clear_ifa4_list(&card->ip_current_state.ip_ifa); + qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa); + qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa); + +#ifdef QETH_IPV6 + qeth_clear_ifa6_list(&card->ip_current_state.ip6_ifa); + qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa); + qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm6_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa); +#endif /* QETH_IPV6 */ +} + +static void qeth_init_input_buffers(qeth_card_t *card) +{ + int i; + + /* slowly, slowly (we don't want to enqueue all buffers + * at one time) */ + for (i=0;iinbound_buffer_refcnt[i],1); + } + for (i=0;iinbound_buffer_refcnt[i],0); + /* only try to queue as many buffers as we have at all */ + if (ioptions.inbound_buffer_count) { + qeth_queue_input_buffer(card,i,0); + } + } + qdio_synchronize(card->irq2,QDIO_FLAG_SYNC_INPUT,0); +} + +/* initializes all the structures for a card */ +static int qeth_hardsetup_card(qeth_card_t *card,int in_recovery) +{ + int result,q,breakout; + unsigned long flags; + int laps=QETH_HARDSETUP_LAPS; + int clear_laps; + int cleanup_qdio; + char dbf_text[15]; + int i,r; + + /* setup name and so on */ + atomic_set(&card->shutdown_phase,0); + + if (atomic_read(&card->is_hardsetup)) { + sprintf(dbf_text,"hscd%4x",card->irq0); + QETH_DBF_TEXT2(1,trace,dbf_text); + PRINT_ALL("card is already hardsetup.\n"); + return 0; + } + + cleanup_qdio=in_recovery; /* if we are in recovery, we clean + the qdio stuff up */ + + my_spin_lock(&card->hardsetup_lock); + atomic_set(&card->write_busy,0); + + do { + if (in_recovery) { + PRINT_STUPID("qeth: recovery: quiescing %s...\n", + card->dev_name); + sprintf(dbf_text,"Rqsc%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + qeth_wait_nonbusy(QETH_QUIESCE_WAIT_BEFORE_CLEAR); + } + clear_laps=QETH_HARDSETUP_CLEAR_LAPS; + do { + if (in_recovery) + PRINT_STUPID("clearing card %s\n", + card->dev_name); + qeth_clear_card(card,cleanup_qdio, + (card->type==QETH_CARD_TYPE_OSAE)); + result=qeth_send_nops(card); + breakout=atomic_read(&card->break_out); + } while ( (--clear_laps) && (result) ); + if (result) { + goto exit; + } + + if (in_recovery) { + PRINT_STUPID("qeth: recovery: still quiescing %s...\n", + card->dev_name); + sprintf(dbf_text,"RQsc%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + qeth_wait_nonbusy(QETH_QUIESCE_WAIT_AFTER_CLEAR); + } else { + atomic_set(&card->shutdown_phase,0); + } + + cleanup_qdio=0; /* qdio was cleaned now, if necessary */ + + result=qeth_get_unitaddr(card); + if (result) goto exit; + + qeth_generate_tokens(card); + +#define PRINT_TOKENS do { \ + sprintf(dbf_text,"stra "); \ + memcpy(&dbf_text[4],&card->seqno.trans_hdr,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"spdu "); \ + memcpy(&dbf_text[4],&card->seqno.pdu_hdr,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"spda "); \ + memcpy(&dbf_text[4],&card->seqno.pdu_hdr_ack,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"sipa "); \ + memcpy(&dbf_text[4],&card->seqno.ipa,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tisw "); \ + memcpy(&dbf_text[4],&card->token.issuer_rm_w,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tisr "); \ + memcpy(&dbf_text[4],&card->token.issuer_rm_r,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tcfw "); \ + memcpy(&dbf_text[4],&card->token.cm_filter_w,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tcfr "); \ + memcpy(&dbf_text[4],&card->token.cm_filter_r,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tccw "); \ + memcpy(&dbf_text[4],&card->token.cm_connection_w,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tccr "); \ + memcpy(&dbf_text[4],&card->token.cm_connection_r,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tufw "); \ + memcpy(&dbf_text[4],&card->token.ulp_filter_w,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tufr "); \ + memcpy(&dbf_text[4],&card->token.ulp_filter_r,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tucw "); \ + memcpy(&dbf_text[4],&card->token.ulp_connection_w,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + sprintf(dbf_text,"tucr "); \ + memcpy(&dbf_text[4],&card->token.ulp_connection_r,4); \ + QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \ + } while (0) + PRINT_TOKENS; + + /* card->break_out and problem will be set here to 0 + * (in each lap) (there can't be a problem at this + * early time) */ + atomic_set(&card->problem,0); + atomic_set(&card->break_out,0); + +#define CHECK_ERRORS \ + breakout=atomic_read(&card->break_out); \ + if (breakout==QETH_BREAKOUT_AGAIN) \ + continue; \ + else if (breakout==QETH_BREAKOUT_LEAVE) { \ + result=-EIO; \ + goto exit; \ + } \ + if (result) goto exit + + QETH_DBF_TEXT2(0,trace,"hsidxard"); + result=qeth_idx_activate_read(card); + CHECK_ERRORS; + + PRINT_TOKENS; + QETH_DBF_TEXT2(0,trace,"hsidxawr"); + result=qeth_idx_activate_write(card); + CHECK_ERRORS; + + QETH_DBF_TEXT2(0,trace,"hsissurd"); + /* from here, there will always be an outstanding read */ + s390irq_spin_lock_irqsave(card->irq0,flags); + qeth_issue_next_read(card); + s390irq_spin_unlock_irqrestore(card->irq0,flags); + + PRINT_TOKENS; + QETH_DBF_TEXT2(0,trace,"hscmenab"); + result=qeth_cm_enable(card); + CHECK_ERRORS; + + PRINT_TOKENS; + QETH_DBF_TEXT2(0,trace,"hscmsetu"); + result=qeth_cm_setup(card); + CHECK_ERRORS; + + PRINT_TOKENS; + QETH_DBF_TEXT2(0,trace,"hsulpena"); + result=qeth_ulp_enable(card); + CHECK_ERRORS; + + PRINT_TOKENS; + QETH_DBF_TEXT2(0,trace,"hsulpset"); + result=qeth_ulp_setup(card); + CHECK_ERRORS; + + cleanup_qdio=1; + + QETH_DBF_TEXT2(0,trace,"hsqdioes"); + result=qeth_qdio_establish(card); + CHECK_ERRORS; + + PRINT_TOKENS; + QETH_DBF_TEXT2(0,trace,"hsqdioac"); + result=qeth_qdio_activate(card); + CHECK_ERRORS; + + PRINT_TOKENS; + QETH_DBF_TEXT2(0,trace,"hsdmact"); + result=qeth_dm_act(card); + CHECK_ERRORS; + } while ( (laps--) && (breakout==QETH_BREAKOUT_AGAIN) ); + if (breakout==QETH_BREAKOUT_AGAIN) { + sprintf(dbf_text,"hsnr%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + printk("qeth: recovery not successful on device " \ + "0x%X/0x%X/0x%X; giving up.\n", + card->devno0,card->devno1,card->devno2); + result=-EIO; + goto exit; + } + + qeth_clear_ifa4_list(&card->ip_current_state.ip_ifa); + qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa); + qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa); + +#ifdef QETH_IPV6 + qeth_clear_ifa6_list(&card->ip_current_state.ip6_ifa); + qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa); + qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm6_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa); +#endif /* QETH_IPV6 */ + + if (!atomic_read(&card->is_registered)) { + card->dev->dev_addr[0]=0; /* we don't know the mac addr yet */ + card->dev->dev_addr[1]=0; + card->dev->dev_addr[2]=0; + card->dev->dev_addr[3]=0; + card->dev->dev_addr[4]=0; + card->dev->dev_addr[5]=0; + card->dev->broadcast[0]=card->dev->broadcast[1]=0xff; + card->dev->broadcast[2]=card->dev->broadcast[3]=0xff; + card->dev->broadcast[4]=card->dev->broadcast[5]=0xff; + + card->dev->type=qeth_get_arphrd_type(card->type, + card->link_type); + + card->dev->init=qeth_init_dev; + + if (card->options.memusage==MEMUSAGE_CONTIG) { + card->easy_copy_cap= + qeth_determine_easy_copy_cap(card->type); + } else card->easy_copy_cap=0; + card->ipa_timeout=qeth_get_ipa_timeout(card->type); + } + + atomic_set(&card->is_hardsetup,1); + atomic_set(&card->is_softsetup,0); + atomic_set(&card->startlan_attempts,1); + + for (q=0;qno_queues;q++) + card->send_state[q]=SEND_STATE_DONT_PACK; + + /* here we need to know, whether we should include a value + * into eui-64 address generation */ + QETH_DBF_TEXT2(0,trace,"qipassi4"); + r=qeth_send_qipassist(card,4); + if (r) { + PRINT_WARN("couldn't send QIPASSIST4 on %s: " \ + "0x%x\n",card->dev_name,r); + sprintf(dbf_text,"QIP4%4x",r); + QETH_DBF_TEXT2(0,trace,dbf_text); + } + + sprintf(dbf_text,"%4x%4x",card->ipa_supported,card->ipa_enabled); + QETH_DBF_TEXT2(0,trace,dbf_text); + + qeth_get_unique_id(card); + + /* print out status */ + if (in_recovery) { + qeth_clear_card_structures(card); + qeth_init_input_buffers(card); + QETH_DBF_TEXT1(0,trace,"RECOVSUC"); + printk("qeth: recovered device 0x%X/0x%X/0x%X (%s) " \ + "successfully.\n", + card->devno0,card->devno1,card->devno2, + card->dev_name); + } else { + QETH_DBF_TEXT2(0,trace,"hrdsetok"); + + switch (card->type) { + case QETH_CARD_TYPE_OSAE: + /* VM will use a non-zero first character to indicate + * a HiperSockets like reporting of the level + * OSA sets the first character to zero */ + if (!card->level[0]) { + sprintf(card->level,"%02x%02x",card->level[2], + card->level[3]); + card->level[QETH_MCL_LENGTH]=0; + break; + } else { + /* fallthrough */ + } + case QETH_CARD_TYPE_IQD: + card->level[0]=(char)_ebcasc[(__u8)card->level[0]]; + card->level[1]=(char)_ebcasc[(__u8)card->level[1]]; + card->level[2]=(char)_ebcasc[(__u8)card->level[2]]; + card->level[3]=(char)_ebcasc[(__u8)card->level[3]]; + card->level[QETH_MCL_LENGTH]=0; + break; + default: + memset(&card->level[0],0,QETH_MCL_LENGTH+1); + } + + sprintf(dbf_text,"lvl:%s",card->level); + QETH_DBF_TEXT2(0,setup,dbf_text); + + if (card->portname_required) { + sprintf(dbf_text,"%s",card->options.portname+1); + for (i=0;i<8;i++) + dbf_text[i]=(char)_ebcasc[(__u8)dbf_text[i]]; + dbf_text[8]=0; + printk("qeth: Device 0x%X/0x%X/0x%X is a%s " \ + "card%s%s%s\n" \ + "with link type %s (portname: %s)\n", + card->devno0,card->devno1,card->devno2, + qeth_get_cardname(card->type), + (card->level[0])?" (level: ":"", + (card->level[0])?card->level:"", + (card->level[0])?")":"", + qeth_get_link_type_name(card->type, + card->link_type), + dbf_text); + } else { + printk("qeth: Device 0x%X/0x%X/0x%X is a%s " \ + "card%s%s%s\nwith link type %s " \ + "(no portname needed by interface)\n", + card->devno0,card->devno1,card->devno2, + qeth_get_cardname(card->type), + (card->level[0])?" (level: ":"", + (card->level[0])?card->level:"", + (card->level[0])?")":"", + qeth_get_link_type_name(card->type, + card->link_type)); + } + } + + exit: + my_spin_unlock(&card->hardsetup_lock); + return result; +} + +static int qeth_reinit_thread(void *param) +{ + qeth_card_t *card=(qeth_card_t*)param; + int already_registered; + int already_hardsetup; + int retry=QETH_RECOVERY_HARDSETUP_RETRY; + int result; + char dbf_text[15]; + char name[15]; + + sprintf(dbf_text,"RINI%4x",card->irq0); + QETH_DBF_TEXT1(0,trace,dbf_text); + + daemonize(); + + /* set a nice name ... */ + sprintf(name, "qethrinid%04x", card->irq0); + strcpy(current->comm, name); + + if (atomic_read(&card->shutdown_phase)) goto out_wakeup; + down_interruptible(&card->reinit_thread_sem); + if (atomic_read(&card->shutdown_phase)) goto out_wakeup; + + QETH_DBF_TEXT1(0,trace,"ri-gotin"); + PRINT_STUPID("entering recovery (reinit) thread for device %s\n", + card->dev_name); + + atomic_set(&card->is_startlaned,0); + atomic_set(&card->is_softsetup,0); + + my_read_lock(&list_lock); + if (!qeth_verify_card(card)) goto out; + QETH_DBF_TEXT1(0,trace,"ri-vrfd"); + + atomic_set(&card->write_busy,0); + qeth_set_dev_flag_norunning(card); + already_hardsetup=atomic_read(&card->is_hardsetup); + already_registered=atomic_read(&card->is_registered); + if (already_hardsetup) { + atomic_set(&card->is_hardsetup,0); + + if (-1==my_spin_lock_nonbusy(card,&setup_lock)) goto out; + if (atomic_read(&card->shutdown_phase)) goto out_wakeup; + + atomic_set(&card->escape_softsetup,1); + if (-1==my_spin_lock_nonbusy(card,&card->softsetup_lock)) { + atomic_set(&card->escape_softsetup,0); + goto out; + } + atomic_set(&card->escape_softsetup,0); + if (atomic_read(&card->shutdown_phase)) { + my_spin_unlock(&card->softsetup_lock); + goto out_wakeup; + } + if (!qeth_verify_card(card)) goto out; + + if (already_registered) + netif_stop_queue(card->dev); + + qeth_wait_nonbusy(QETH_QUIESCE_NETDEV_TIME); + + atomic_set(&card->is_startlaned,0); + + QETH_DBF_TEXT1(0,trace,"ri-frskb"); + qeth_free_all_skbs(card); + do { + QETH_DBF_TEXT1(0,trace,"ri-hrdst"); + result=qeth_hardsetup_card(card,1); + } while (result&&(retry--)); + + /* tries to remove old ips, that's paranoid, but ok */ + qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa); + +#ifdef QETH_IPV6 + qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa); + qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa); +#endif /* QETH_IPV6 */ + + if (result) { + QETH_DBF_TEXT1(0,trace,"ri-nosuc"); + printk("qeth: RECOVERY WAS NOT SUCCESSFUL ON %s " \ + "(devnos 0x%X/0x%X/0x%X), GIVING UP, " \ + "OUTGOING PACKETS WILL BE DISCARDED!\n", + card->dev_name,card->devno0, + card->devno1,card->devno2); + /* early leave hard_start_xmit! */ + atomic_set(&card->is_startlaned,0); + /* show status in /proc/qeth */ + atomic_set(&card->is_gone,1); + qeth_wakeup_procfile(); + } else { + QETH_DBF_TEXT1(0,trace,"ri-sftst"); + qeth_softsetup_card(card,QETH_LOCK_ALREADY_HELD); + my_spin_unlock(&card->softsetup_lock); + + if (!already_registered) { + QETH_DBF_TEXT1(0,trace,"ri-regcd"); + qeth_register_netdev(card); + } + qeth_restore_dev_flag_state(card); + atomic_set(&card->is_gone,0); + netif_wake_queue(card->dev); + qeth_wakeup_procfile(); + } + my_spin_unlock(&setup_lock); + } +out: + atomic_set(&card->in_recovery,0); + my_read_unlock(&list_lock); + QETH_DBF_TEXT1(0,trace,"ri-leave"); +out_wakeup: + up(&card->reinit_thread_sem); + atomic_dec(&card->reinit_counter); + + return 0; +} + +static void qeth_fill_qeth_card_options(qeth_card_t *card) +{ + int i; + + card->options.portname[0]=0; + for (i=1;i<9;i++) + card->options.portname[i]=_ascebc[' ']; + strcpy(card->options.devname," "); + card->options.routing_type4=NO_ROUTER; +#ifdef QETH_IPV6 + card->options.routing_type6=NO_ROUTER; +#endif /* QETH_IPV6 */ + card->options.portno=0; + card->options.checksum_type=QETH_CHECKSUM_DEFAULT; + card->options.do_prio_queueing=0; + card->options.default_queue=QETH_DEFAULT_QUEUE; + card->options.inbound_buffer_count=DEFAULT_BUFFER_COUNT; + card->options.polltime=QETH_MAX_INPUT_THRESHOLD; + card->options.memusage=MEMUSAGE_DISCONTIG; + card->options.macaddr_mode=MACADDR_NONCANONICAL; + card->options.broadcast_mode=BROADCAST_ALLRINGS; + card->options.fake_broadcast=DONT_FAKE_BROADCAST; + card->options.ena_ipat=ENABLE_TAKEOVER; + card->options.add_hhlen=DEFAULT_ADD_HHLEN; + card->options.fake_ll=DONT_FAKE_LL; + card->options.async_iqd=SYNC_IQD; +} + +static qeth_card_t *qeth_alloc_card(void) +{ + qeth_card_t *card; + + QETH_DBF_TEXT3(0,trace,"alloccrd"); + card=(qeth_card_t *)vmalloc(sizeof(qeth_card_t)); + if (!card) goto exit_card; + memset(card,0,sizeof(qeth_card_t)); + init_waitqueue_head(&card->wait_q); + init_waitqueue_head(&card->ioctl_wait_q); + + qeth_fill_qeth_card_options(card); + + card->dma_stuff=(qeth_dma_stuff_t*)kmalloc(sizeof(qeth_dma_stuff_t), + GFP_DMA); + if (!card->dma_stuff) goto exit_dma; + memset(card->dma_stuff,0,sizeof(qeth_dma_stuff_t)); + + card->dma_stuff->recbuf=(char*)kmalloc(QETH_BUFSIZE,GFP_DMA); + if (!card->dma_stuff->recbuf) goto exit_dma1; + memset(card->dma_stuff->recbuf,0,QETH_BUFSIZE); + + card->dma_stuff->sendbuf=(char*)kmalloc(QETH_BUFSIZE,GFP_DMA); + if (!card->dma_stuff->sendbuf) goto exit_dma2; + memset(card->dma_stuff->sendbuf,0,QETH_BUFSIZE); + + card->dev=(struct net_device *)kmalloc(sizeof(struct net_device), + GFP_KERNEL); + if (!card->dev) goto exit_dev; + memset(card->dev,0,sizeof(struct net_device)); + + card->stats=(struct net_device_stats *)kmalloc( + sizeof(struct net_device_stats),GFP_KERNEL); + if (!card->stats) goto exit_stats; + memset(card->stats,0,sizeof(struct net_device_stats)); + + card->devstat0=(devstat_t *)kmalloc(sizeof(devstat_t),GFP_KERNEL); + if (!card->devstat0) goto exit_stats; + memset(card->devstat0,0,sizeof(devstat_t)); + + card->devstat1=(devstat_t *)kmalloc(sizeof(devstat_t),GFP_KERNEL); + if (!card->devstat1) { + kfree(card->devstat0); + goto exit_stats; + } + memset(card->devstat1,0,sizeof(devstat_t)); + + card->devstat2=(devstat_t *)kmalloc(sizeof(devstat_t),GFP_KERNEL); + if (!card->devstat2) { + kfree(card->devstat1); + kfree(card->devstat0); + goto exit_stats; + } + memset(card->devstat2,0,sizeof(devstat_t)); + + spin_lock_init(&card->wait_q_lock); + spin_lock_init(&card->softsetup_lock); + spin_lock_init(&card->hardsetup_lock); + spin_lock_init(&card->ioctl_lock); +#ifdef QETH_VLAN + spin_lock_init(&card->vlan_lock); + card->vlangrp = NULL; +#endif + card->unique_id=0; + sema_init(&card->reinit_thread_sem,0); + up(&card->reinit_thread_sem); + + /* setup card stuff */ + card->ip_current_state.ip_ifa=NULL; + card->ip_new_state.ip_ifa=NULL; + card->ip_mc_current_state.ipm_ifa=NULL; + card->ip_mc_new_state.ipm_ifa=NULL; + +#ifdef QETH_IPV6 + card->ip_current_state.ip6_ifa=NULL; + card->ip_new_state.ip6_ifa=NULL; + card->ip_mc_current_state.ipm6_ifa=NULL; + card->ip_mc_new_state.ipm6_ifa=NULL; +#endif /* QETH_IPV6 */ + + /* setup net_device stuff */ + card->dev->priv=card; + + strncpy(card->dev->name,card->dev_name,IFNAMSIZ); + + /* setup net_device_stats stuff */ + /* =nothing yet */ + + /* and return to the sender */ + return card; + + /* these are quick exits in case of failures of the kmallocs */ +exit_stats: + kfree(card->dev); +exit_dev: + kfree(card->dma_stuff->sendbuf); +exit_dma2: + kfree(card->dma_stuff->recbuf); +exit_dma1: + kfree(card->dma_stuff); +exit_dma: + kfree(card); +exit_card: + return NULL; +} + +static int qeth_init_ringbuffers1(qeth_card_t *card) +{ + int i,j; + char dbf_text[15]; + + sprintf(dbf_text,"irb1%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + for (i=0;ino_queues;i++) { + card->outbound_ringbuffer[i]= + vmalloc(sizeof(qeth_ringbuffer_t)); + if (!card->outbound_ringbuffer[i]) { + for (j=i-1;j>=0;j--) { + vfree(card->outbound_ringbuffer[j]); + card->outbound_ringbuffer[j]=NULL; + } + return -ENOMEM; + } + memset(card->outbound_ringbuffer[i],0, + sizeof(qeth_ringbuffer_t)); + for (j=0;joutbound_ringbuffer[i]-> + ringbuf_element[j].skb_list); + } + + return 0; +} + +static int qeth_init_ringbuffers2(qeth_card_t *card) +{ + int i,j; + int failed=0; + char dbf_text[15]; + int discont_mem,element_count; + long alloc_size; + + sprintf(dbf_text,"irb2%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + discont_mem=(card->options.memusage==MEMUSAGE_DISCONTIG); + element_count=(discont_mem)?BUFFER_MAX_ELEMENTS:1; + alloc_size=(discont_mem)?PAGE_SIZE:BUFFER_SIZE; + if (discont_mem) { + for (i=0;ioptions.inbound_buffer_count;i++) { + for (j=0;jinbound_buffer_pool_entry[i][j]= + kmalloc(alloc_size,GFP_KERNEL); + if (!card->inbound_buffer_pool_entry[i][j]) { + failed=1; + goto out; + } + } + card->inbound_buffer_pool_entry_used[i]=BUFFER_UNUSED; + } + } else { + for (i=0;ioptions.inbound_buffer_count;i++) { + card->inbound_buffer_pool_entry[i][0]= + kmalloc(alloc_size,GFP_KERNEL); + if (!card->inbound_buffer_pool_entry[i][0]) failed=1; + for (j=1;jinbound_buffer_pool_entry[i][j]= + card->inbound_buffer_pool_entry[i][0]+ + PAGE_SIZE*j; + card->inbound_buffer_pool_entry_used[i]=BUFFER_UNUSED; + } + } + +out: + if (failed) { + for (i=0;ioptions.inbound_buffer_count;i++) { + for (j=0;jinbound_buffer_pool_entry[i][j]) { + if (j + inbound_buffer_pool_entry + [i][j]); + card->inbound_buffer_pool_entry + [i][j]=NULL; + } + } + } + for (i=0;ino_queues;i++) { + vfree(card->outbound_ringbuffer[i]); + card->outbound_ringbuffer[i]=NULL; + } + return -ENOMEM; + } + + spin_lock_init(&card->requeue_input_lock); + + return 0; +} + +/* also locked from outside (setup_lock) */ +static void qeth_insert_card_into_list(qeth_card_t *card) +{ + char dbf_text[15]; + + sprintf(dbf_text,"icil%4x",card->irq0); + QETH_DBF_TEXT3(0,trace,dbf_text); + + my_write_lock(&list_lock); + card->next=firstcard; + firstcard=card; + my_write_unlock(&list_lock); +} + +static int qeth_determine_card_type(qeth_card_t *card) +{ + int i=0; + char dbf_text[15]; + + while (known_devices[i][4]) { + if ( (card->dev_type==known_devices[i][2]) && + (card->dev_model==known_devices[i][3]) ) { + card->type=known_devices[i][4]; + if (card->options.ena_ipat==ENABLE_TAKEOVER) + card->func_level=known_devices[i][6]; + else + card->func_level=known_devices[i][7]; + card->no_queues=known_devices[i][8]; + card->is_multicast_different=known_devices[i][9]; + sprintf(dbf_text,"irq %4x",card->irq0); + QETH_DBF_TEXT2(0,setup,dbf_text); + sprintf(dbf_text,"ctyp%4x",card->type); + QETH_DBF_TEXT2(0,setup,dbf_text); + return 0; + } + i++; + } + card->type=QETH_CARD_TYPE_UNKNOWN; + sprintf(dbf_text,"irq %4x",card->irq0); + QETH_DBF_TEXT2(0,setup,dbf_text); + sprintf(dbf_text,"ctypUNKN"); + QETH_DBF_TEXT2(0,setup,dbf_text); + PRINT_ERR("unknown card type on irq x%x\n",card->irq0); + return -ENOENT; +} + +static int qeth_getint(char *s,int longint) +{ + int cnt; + int hex; + int result; + char c; + + if (!s) return -1; + hex=((s[0]=='0')&&( (s[1]=='x') || (s[1]=='X') ))?1:0; + cnt=(hex)?2:0; /* start from the first real digit */ + if (!(s[cnt])) return -1; + result=0; + while ((c=s[cnt++])) { + if (hex) { + if (isxdigit(c)) result=result*16+qeth_getxdigit(c); + else return -1; + } else { + if (isdigit(c)) result=result*10+c-'0'; + else return -1; + } + /* prevent overflow, 0xffff is enough for us */ + if (longint) { + if (result>0xfffffff) return -1; + } else { + if (result>0xffff) return -1; + } + } + return result; +} + +static int qeth_setvalue_if_possible(qeth_card_t *card,char *option, + int parse_category, + int *variable,int value) +{ + int *a_p=0; /* to shut the compiler up */ + int routing_already_set_conflict=0; + + a_p= &card->options.already_parsed[parse_category]; + + /* reject a general router statement, if router4 or router6 + * have already been set */ + if (parse_category==PARSE_ROUTING_TYPE) { + if ( (card->options.already_parsed[PARSE_ROUTING_TYPE4]) || + (card->options.already_parsed[PARSE_ROUTING_TYPE6]) ) + routing_already_set_conflict=1; + } + + /* reject a router4 statement, if a general router statement + * has already been set */ + if (parse_category==PARSE_ROUTING_TYPE4) { + if ( (card->options.already_parsed[PARSE_ROUTING_TYPE4]) && + (card->options.already_parsed[PARSE_ROUTING_TYPE6]) ) + routing_already_set_conflict=1; + } + + /* reject a router6 statement, if a general router statement + * has already been set */ + if (parse_category==PARSE_ROUTING_TYPE6) { + if ( (card->options.already_parsed[PARSE_ROUTING_TYPE4]) && + (card->options.already_parsed[PARSE_ROUTING_TYPE6]) ) + routing_already_set_conflict=1; + } + + if ( (routing_already_set_conflict) || + ((parse_category!=-1) && (*a_p)) ) { + PRINT_ERR("parameter %s does not fit to previous " \ + "parameters\n",option); + return 0; + } + *a_p=1; + *variable=value; + return 1; +} + +/* um... */ +#define doit1(a,b,c,d) \ + if (!strcmp(option,a)) \ + return qeth_setvalue_if_possible(card,option,b,((int*)&c),d) + +#define doit2(a,b,c,d,e,f) \ + doit1(a,b,c,d) | qeth_setvalue_if_possible(card,option,-1,((int*)&e),f) + +/* returns 0, if option could notr be parsed alright */ +static int qeth_parse_option(qeth_card_t *card,char *option) +{ + int i; + int *a_p; + +#ifdef QETH_IPV6 + doit2("no_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,NO_ROUTER, + card->options.routing_type6,NO_ROUTER); + doit2("primary_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,PRIMARY_ROUTER, + card->options.routing_type6,PRIMARY_ROUTER); + doit2("secondary_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,SECONDARY_ROUTER, + card->options.routing_type6,SECONDARY_ROUTER); + doit2("multicast_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,MULTICAST_ROUTER, + card->options.routing_type6,MULTICAST_ROUTER); + doit2("primary_connector",PARSE_ROUTING_TYPE, + card->options.routing_type4,PRIMARY_CONNECTOR, + card->options.routing_type6,PRIMARY_CONNECTOR); + doit2("secondary_connector",PARSE_ROUTING_TYPE, + card->options.routing_type4,SECONDARY_CONNECTOR, + card->options.routing_type6,SECONDARY_CONNECTOR); +#else /* QETH_IPV6 */ + doit1("no_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,NO_ROUTER); + doit1("primary_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,PRIMARY_ROUTER); + doit1("secondary_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,SECONDARY_ROUTER); + doit1("multicast_router",PARSE_ROUTING_TYPE, + card->options.routing_type4,MULTICAST_ROUTER); + doit1("primary_connector",PARSE_ROUTING_TYPE, + card->options.routing_type4,PRIMARY_CONNECTOR); + doit1("secondary_connector",PARSE_ROUTING_TYPE, + card->options.routing_type4,SECONDARY_CONNECTOR); +#endif /* QETH_IPV6 */ + + doit1("no_router4",PARSE_ROUTING_TYPE4, + card->options.routing_type4,NO_ROUTER); + doit1("primary_router4",PARSE_ROUTING_TYPE4, + card->options.routing_type4,PRIMARY_ROUTER); + doit1("secondary_router4",PARSE_ROUTING_TYPE4, + card->options.routing_type4,SECONDARY_ROUTER); + doit1("multicast_router4",PARSE_ROUTING_TYPE4, + card->options.routing_type4,MULTICAST_ROUTER); + doit1("primary_connector4",PARSE_ROUTING_TYPE4, + card->options.routing_type4,PRIMARY_CONNECTOR); + doit1("secondary_connector4",PARSE_ROUTING_TYPE4, + card->options.routing_type4,SECONDARY_CONNECTOR); + +#ifdef QETH_IPV6 + doit1("no_router6",PARSE_ROUTING_TYPE6, + card->options.routing_type6,NO_ROUTER); + doit1("primary_router6",PARSE_ROUTING_TYPE6, + card->options.routing_type6,PRIMARY_ROUTER); + doit1("secondary_router6",PARSE_ROUTING_TYPE6, + card->options.routing_type6,SECONDARY_ROUTER); + doit1("multicast_router6",PARSE_ROUTING_TYPE6, + card->options.routing_type6,MULTICAST_ROUTER); + doit1("primary_connector6",PARSE_ROUTING_TYPE6, + card->options.routing_type6,PRIMARY_CONNECTOR); + doit1("secondary_connector6",PARSE_ROUTING_TYPE6, + card->options.routing_type6,SECONDARY_CONNECTOR); +#endif /* QETH_IPV6 */ + + doit1("sw_checksumming",PARSE_CHECKSUMMING, + card->options.checksum_type,SW_CHECKSUMMING); + doit1("hw_checksumming",PARSE_CHECKSUMMING, + card->options.checksum_type,HW_CHECKSUMMING); + doit1("no_checksumming",PARSE_CHECKSUMMING, + card->options.checksum_type,NO_CHECKSUMMING); + + doit1("prio_queueing_prec",PARSE_PRIO_QUEUEING, + card->options.do_prio_queueing,PRIO_QUEUEING_PREC); + doit1("prio_queueing_tos",PARSE_PRIO_QUEUEING, + card->options.do_prio_queueing,PRIO_QUEUEING_TOS); + + doit1("mem_discontig",PARSE_MEMUSAGE, + card->options.memusage,MEMUSAGE_DISCONTIG); + doit1("mem_contig",PARSE_MEMUSAGE, + card->options.memusage,MEMUSAGE_CONTIG); + + doit1("broadcast_allrings",PARSE_BROADCAST_MODE, + card->options.broadcast_mode,BROADCAST_ALLRINGS); + doit1("broadcast_local",PARSE_BROADCAST_MODE, + card->options.broadcast_mode,BROADCAST_LOCAL); + + doit1("macaddr_noncanon",PARSE_MACADDR_MODE, + card->options.macaddr_mode,MACADDR_NONCANONICAL); + doit1("macaddr_canon",PARSE_MACADDR_MODE, + card->options.macaddr_mode,MACADDR_CANONICAL); + + doit1("enable_takeover",PARSE_ENA_IPAT, + card->options.ena_ipat,ENABLE_TAKEOVER); + doit1("disable_takeover",PARSE_ENA_IPAT, + card->options.ena_ipat,DISABLE_TAKEOVER); + + doit1("fake_broadcast",PARSE_FAKE_BROADCAST, + card->options.fake_broadcast,FAKE_BROADCAST); + doit1("dont_fake_broadcast",PARSE_FAKE_BROADCAST, + card->options.fake_broadcast,DONT_FAKE_BROADCAST); + + doit1("fake_ll",PARSE_FAKE_LL, + card->options.fake_ll,FAKE_LL); + doit1("dont_fake_ll",PARSE_FAKE_LL, + card->options.fake_ll,DONT_FAKE_LL); + + doit1("sync_hsi",PARSE_ASYNC_IQD, + card->options.async_iqd,SYNC_IQD); + doit1("async_hsi",PARSE_ASYNC_IQD, + card->options.async_iqd,ASYNC_IQD); + + doit2("no_prio_queueing:0",PARSE_PRIO_QUEUEING, + card->options.do_prio_queueing,NO_PRIO_QUEUEING, + card->options.default_queue,0); + doit2("no_prio_queueing:1",PARSE_PRIO_QUEUEING, + card->options.do_prio_queueing,NO_PRIO_QUEUEING, + card->options.default_queue,1); + doit2("no_prio_queueing:2",PARSE_PRIO_QUEUEING, + card->options.do_prio_queueing,NO_PRIO_QUEUEING, + card->options.default_queue,2); + doit2("no_prio_queueing:3",PARSE_PRIO_QUEUEING, + card->options.do_prio_queueing,NO_PRIO_QUEUEING, + card->options.default_queue,3); + doit2("no_prio_queueing",PARSE_PRIO_QUEUEING, + card->options.do_prio_queueing,NO_PRIO_QUEUEING, + card->options.default_queue,QETH_DEFAULT_QUEUE); + + if (!strncmp(option,"polltime:",9)) { + i=qeth_getint(option+9,1); + if (i==-1) { + PRINT_ERR("parameter %s -- does not contain " \ + "a valid number.\n",option); + return 0; + } + return qeth_setvalue_if_possible(card,option,PARSE_POLLTIME, + &card->options.polltime,i); + } + + if (!strncmp(option,"port:",5)) { + i=qeth_getint(option+5,0); + if (i==-1) { + PRINT_ERR("parameter %s -- does not contain " \ + "a valid number.\n",option); + return 0; + } + if ( (i<0) || (i>MAX_PORTNO) ) { + PRINT_ERR("parameter %s -- out of range\n", + option); + return 0; + } + return qeth_setvalue_if_possible(card,option,PARSE_PORTNO, + &card->options.portno,i); + } + + if (!strncmp(option,"add_hhlen:",10)) { + i=qeth_getint(option+10,0); + if (i==-1) { + PRINT_ERR("parameter %s -- does not contain " \ + "a valid number.\n",option); + return 0; + } + if ( (i<0) || (i>MAX_ADD_HHLEN) ) { + PRINT_ERR("parameter %s -- out of range\n", + option); + return 0; + } + return qeth_setvalue_if_possible(card,option,PARSE_ADD_HHLEN, + &card->options.add_hhlen,i); + } + + if (!strncmp(option,"portname:",9)) { + a_p=&card->options.already_parsed[PARSE_PORTNAME]; + if (*a_p) { + PRINT_ERR("parameter %s does not fit to " \ + "previous parameters\n",option); + return 0; + } + if ((strlen(option)-9)>8) { + PRINT_ERR("parameter %s -- too long\n",option); + return 0; + } + *a_p=1; + card->options.portname[0]=strlen(option)-9; + /* for beauty reasons: */ + for (i=1;i<9;i++) + card->options.portname[i]=' '; + strcpy(card->options.portname+1,option+9); + for (i=1;i<9;i++) + card->options.portname[i]= + _ascebc[(unsigned char) + card->options.portname[i]]; + return 1; + } + + PRINT_ERR("unknown parameter: %s\n",option); + + return 0; +} + +static void qeth_detach_handler(int irq,int status) +{ + qeth_card_t *card; + int remove_method; + char dbf_text[15]; + + if (irq>=NR_IRQS) { + irq-=NR_IRQS; + remove_method=QETH_REMOVE_CARD_PROPER; + } else { + remove_method=QETH_REMOVE_CARD_QUICK; + } + + QETH_DBF_TEXT1(0,trace,"detchhnd"); + sprintf(dbf_text,"%4x%4x",irq,status); + QETH_DBF_TEXT1(0,trace,dbf_text); + + /* try to get the lock, if we didn't get it (hold by recovery), + * give up initiative to enable others to release the lock */ + my_spin_lock_nonbusy(NULL,&setup_lock); + + if ((card=qeth_get_card_by_irq(irq))) { + qeth_remove_card(card,remove_method); + } + qeth_wakeup_procfile(); + my_spin_unlock(&setup_lock); +} + +static void qeth_chandev_do_unregister_device(struct net_device *dev, + int quick) +{ + qeth_card_t *card; + + card=(qeth_card_t *)dev->priv; + + if (quick) { + qeth_detach_handler(card->irq0,0x1234); + } else { + qeth_detach_handler(NR_IRQS+card->irq0,0x1234); + } +} + +static void qeth_chandev_unregister_device(struct net_device *dev) +{ + qeth_chandev_do_unregister_device(dev, 0); +} + +static void qeth_chandev_parse_options(qeth_card_t *card,char *parmstring) +{ + /* parse options coming from the chandev layer */ + char *optionstr; + char *tmp; + + QETH_DBF_HEX2(0,misc,parmstring, + qeth_min(QETH_DBF_MISC_LEN,strlen(parmstring))); + tmp = kmalloc ((strlen(parmstring) + 1) * sizeof (char), GFP_KERNEL); + if (tmp) { + memset (tmp, 0, strlen(parmstring) + 1); + memcpy (tmp, parmstring, strlen(parmstring) + 1); + do { + char *end; + int len; + end = strchr (tmp, ','); + if (end == NULL) { + len = strlen (tmp) + 1; + } else { + len = (long) end - (long) tmp + 1; + *end = '\0'; + end++; + } + + if (len>1) { + optionstr = kmalloc (len * sizeof (char), + GFP_KERNEL); + if (optionstr) { + memset(optionstr,0,len*sizeof(char)); + memcpy(optionstr,tmp,len*sizeof(char)); + + qeth_parse_option(card,optionstr); + kfree(optionstr); + tmp = end; + } else { + PRINT_ERR("Cannot allocate memory " \ + "for option parsing!\n"); + break; + } + } + } while (tmp != NULL && *tmp != '\0'); + } else { + PRINT_ERR("Cannot allocate memory " \ + "for option parsing!\n"); + } +} + +static int qeth_get_bufcnt_from_memamnt(qeth_card_t *card,__s32 *memamnt) +{ + int cnt = 0; + int bufsize = BUFFER_SIZE; + + if (bufsize == 24576) + bufsize = 32768; + if (bufsize == 40960) + bufsize = 65536; + cnt = (*memamnt)*1024 / bufsize; + cnt = (cntBUFCNT_MAX)?BUFCNT_MAX:cnt); + (*memamnt) = cnt * bufsize/1024; + + return cnt; +} + +static void qeth_correct_routing_status(qeth_card_t *card) +{ + if (card->type==QETH_CARD_TYPE_IQD) { + /* if it's not a mc router, it's no router */ + if ( (card->options.routing_type4 == PRIMARY_ROUTER) || + (card->options.routing_type4 == SECONDARY_ROUTER) +#ifdef QETH_IPV6 + || + (card->options.routing_type6 == PRIMARY_ROUTER) || + (card->options.routing_type6 == SECONDARY_ROUTER) +#endif /* QETH_IPV6 */ + ) { + PRINT_WARN("routing not applicable, reset " \ + "routing status.\n"); + card->options.routing_type4=NO_ROUTER; +#ifdef QETH_IPV6 + card->options.routing_type6=NO_ROUTER; +#endif /* QETH_IPV6 */ + } + card->options.do_prio_queueing=NO_PRIO_QUEUEING; + } else { + /* if it's a mc router, it's no router */ + if ( (card->options.routing_type4 == MULTICAST_ROUTER) || + (card->options.routing_type4 == PRIMARY_CONNECTOR) || + (card->options.routing_type4 == SECONDARY_CONNECTOR) +#ifdef QETH_IPV6 + || + (card->options.routing_type6 == MULTICAST_ROUTER) || + (card->options.routing_type6 == PRIMARY_CONNECTOR) || + (card->options.routing_type6 == SECONDARY_CONNECTOR) +#endif /* QETH_IPV6 */ + ) { + PRINT_WARN("routing not applicable, reset " \ + "routing status. (Did you mean " \ + "primary_router or secondary_router?)\n"); + card->options.routing_type4=NO_ROUTER; +#ifdef QETH_IPV6 + card->options.routing_type6=NO_ROUTER; +#endif /* QETH_IPV6 */ + } + } +} + +static int qeth_attach_handler(int irq_to_scan,chandev_probeinfo *probeinfo) +{ + int result = 0; + int irq1,irq2; + unsigned int irq; + int nr; + __u8 mask; + int read_chpid=-1,write_chpid=-2,data_chpid=-3; /* so that it will + fail, if getting + the chpids fails */ + qeth_card_t *card; + int success = 0; + char dbf_text[15]; + chandev_subchannel_info temp; + + QETH_DBF_TEXT2(0,trace,"athandlr"); + sprintf(dbf_text,"irq:%4x",irq_to_scan); + QETH_DBF_TEXT2(0,trace,dbf_text); + + my_spin_lock_nonbusy(NULL,&setup_lock); + + for (nr=0; nr<8; nr++) { + mask = 0x80 >> nr; + if (probeinfo->read.pim & mask) { + read_chpid=probeinfo->read.chpid[nr]; + /* we take the first chpid -- well, there's + * usually only one... */ + break; + } + } + for (nr=0; nr<8; nr++) { + mask = 0x80 >> nr; + if (probeinfo->write.pim & mask) { + write_chpid=probeinfo->write.chpid[nr]; + /* we take the first chpid -- well, there's + * usually only one... */ + break; + } + } + for (nr=0; nr<8; nr++) { + mask = 0x80 >> nr; + if (probeinfo->data.pim & mask) { + data_chpid=probeinfo->data.chpid[nr]; + /* we take the first chpid -- well, there's + * usually only one... */ + break; + } + } + if ((read_chpid!=write_chpid)||(read_chpid!=data_chpid)) { + PRINT_ERR("devices are not on the same CHPID!\n"); + goto endloop; + } + + /* Try to reorder the devices, if neccessary */ + if (probeinfo->read.dev_model == 0x05) + /* No odd/even restr. for IQD */ + goto correct_order; + if ((probeinfo->read.devno %2 == 0) && + (probeinfo->write.devno == probeinfo->read.devno + 1)) + goto correct_order; + if ((probeinfo->write.devno %2 == 0) && + (probeinfo->data.devno == probeinfo->write.devno + 1)) { + temp = probeinfo->read; + probeinfo->read = probeinfo->write; + probeinfo->write = probeinfo->data; + probeinfo->data = temp; + goto correct_order; + } + if ((probeinfo->write.devno %2 == 0) && + (probeinfo->read.devno == probeinfo->write.devno + 1)) { + temp = probeinfo->read; + probeinfo->read = probeinfo->write; + probeinfo->write = temp; + goto correct_order; + } + if ((probeinfo->read.devno %2 == 0) && + (probeinfo->data.devno == probeinfo->read.devno + 1)) { + temp = probeinfo->write; + probeinfo->write = probeinfo->data; + probeinfo->data = temp; + goto correct_order; + } + if ((probeinfo->data.devno %2 == 0) && + (probeinfo->write.devno == probeinfo->data.devno + 1)) { + temp = probeinfo->read; + probeinfo->read = probeinfo->data; + probeinfo->data = temp; + goto correct_order; + } + if ((probeinfo->data.devno %2 == 0) && + (probeinfo->read.devno == probeinfo->data.devno + 1)) { + temp = probeinfo->read; + probeinfo->read = probeinfo->data; + probeinfo->data = probeinfo->write; + probeinfo->write = temp; + goto correct_order; + } + PRINT_ERR("Failed to reorder devices %04x,%04x,%04x; " + "please check your configuration\n", + probeinfo->read.devno, probeinfo->write.devno, + probeinfo->data.devno); + goto endloop; + +correct_order: + irq = probeinfo->read.irq; + irq1 = probeinfo->write.irq; + irq2 = probeinfo->data.irq; + + card=qeth_alloc_card(); + if (card==NULL) { + QETH_DBF_TEXT2(0,trace,"nocrdmem"); + PRINT_ERR("memory structures could not be allocated\n"); + goto endloop; + } + card->chpid=read_chpid; + + if (probeinfo->port_protocol_no != -1 ) + card->options.portno = probeinfo->port_protocol_no; + else + card->options.portno = 0; + + qeth_chandev_parse_options(card,probeinfo->parmstr); + + card->has_irq=0; + card->irq0=irq; + card->irq1=irq1; + card->irq2=irq2; + card->devno0=probeinfo->read.devno; + card->devno1=probeinfo->write.devno; + card->devno2=probeinfo->data.devno; + card->dev_type=probeinfo->read.dev_type; + card->dev_model=probeinfo->read.dev_model; + atomic_set(&card->is_gone,0); + atomic_set(&card->rt4fld,0); +#ifdef QETH_IPV6 + atomic_set(&card->rt6fld,0); +#endif /* QETH_IPV6 */ + + sprintf(dbf_text,"atch%4x",card->irq0); + QETH_DBF_TEXT1(0,setup,dbf_text); + QETH_DBF_HEX1(0,setup,&card,sizeof(void*)); + QETH_DBF_HEX1(0,setup,&card->dev,sizeof(void*)); + QETH_DBF_HEX1(0,setup,&card->stats,sizeof(void*)); + QETH_DBF_HEX1(0,setup,&card->devstat0,sizeof(void*)); + QETH_DBF_HEX1(0,setup,&card->devstat1,sizeof(void*)); + QETH_DBF_HEX1(0,setup,&card->devstat2,sizeof(void*)); + + QETH_DBF_HEX2(0,misc,&card->options,QETH_DBF_MISC_LEN); + + if (qeth_determine_card_type(card)) { + qeth_free_card(card); + goto endloop; + } + + qeth_correct_routing_status(card); + qeth_insert_card_into_list(card); + + QETH_DBF_TEXT3(0,trace,"request0"); + /* 0 is irqflags. what is SA_SAMPLE_RANDOM? */ + result=chandev_request_irq(irq,(void*) + qeth_interrupt_handler_read, + 0,QETH_NAME,card->devstat0); + if (result) goto attach_error; + card->has_irq++; + + QETH_DBF_TEXT3(0,trace,"request1"); + result=chandev_request_irq(irq1,(void*) + qeth_interrupt_handler_write, + 0,QETH_NAME,card->devstat1); + if (result) goto attach_error; + card->has_irq++; + + QETH_DBF_TEXT3(0,trace,"request2"); + result=chandev_request_irq(irq2,(void*) + qeth_interrupt_handler_qdio, + 0,QETH_NAME,card->devstat2); + if (result) goto attach_error; + card->has_irq++; + + printk("qeth: Trying to use card with devnos 0x%X/0x%X/0x%X\n", + card->devno0,card->devno1,card->devno2); + + result=qeth_init_ringbuffers1(card); + if (result) goto attach_error; + + result=qeth_hardsetup_card(card,0); + if (result) goto attach_error; + if (probeinfo->memory_usage_in_k != 0) { + card->options.inbound_buffer_count= + qeth_get_bufcnt_from_memamnt + (card,&probeinfo->memory_usage_in_k); + card->options.memory_usage_in_k= + probeinfo->memory_usage_in_k; + } else { + /* sick... */ + probeinfo->memory_usage_in_k= + -card->options.inbound_buffer_count* + BUFFER_SIZE/1024; + } + result=qeth_init_ringbuffers2(card); + if (result) goto attach_error; + + success = 1; + goto endloop; + + attach_error: + sprintf(dbf_text,"ATER%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + switch (result) { + case 0: + break; + case -EINVAL: + PRINT_ERR("oops... invalid parameter.\n"); + break; + case -EBUSY: + PRINT_WARN("Device is busy!\n"); + break; + case -ENODEV: + PRINT_WARN("Device became not operational.\n"); + break; + case -ENOMEM: + PRINT_ERR("Not enough kernel memory for operation.\n"); + break; + case -EIO: + PRINT_ERR("There were problems in hard-setting up " \ + "the card.\n"); + break; + case -ETIME: + PRINT_WARN("Timeout on initializing the card.\n"); + break; + default: + PRINT_ERR("Unknown error %d in attach_handler.\n", + result); + } + if (result) { + qeth_remove_card(card,QETH_REMOVE_CARD_PROPER); + + qeth_remove_card_from_list(card); + QETH_DBF_TEXT4(0,trace,"freecard"); + qeth_free_card(card); + } + endloop: + + QETH_DBF_TEXT3(0,trace,"leftloop"); + + if (!success) { + QETH_DBF_TEXT2(0,trace,"noaddcrd"); + + /* we want to return which problem we had */ + result=result?result:-ENODEV; + goto exit; + } + + + exit: + my_spin_unlock(&setup_lock); + + return result; +} + +static void qeth_chandev_msck_notfunc(struct net_device *device, + int msck_irq, + chandev_msck_status prevstatus, + chandev_msck_status newstatus ) +{ + + if (!(device->priv)) + return; + + if ((prevstatus != chandev_status_good) || + (prevstatus != chandev_status_all_chans_good)) { + if ((newstatus == chandev_status_good) || + (newstatus == chandev_status_all_chans_good)) { + qeth_card_t *card = (qeth_card_t *)device->priv; + + atomic_set(&card->problem,PROBLEM_MACHINE_CHECK); + atomic_set(&card->write_busy,0); + qeth_schedule_recovery(card); + } + } + if ((newstatus == chandev_status_gone) || + (newstatus == chandev_status_no_path) || + (newstatus == chandev_status_not_oper)) { + qeth_card_t *card = (qeth_card_t *)device->priv; + + my_read_lock(&list_lock); + if (qeth_verify_card(card)) { + atomic_set(&card->is_startlaned,0); + qeth_set_dev_flag_norunning(card); + /* + * Unfortunately, the chandev layer does not provide + * a possibility to unregister a single device. So + * we mark the card as "gone" to avoid internal + * mishandling. + */ + atomic_set(&card->is_gone,1); + /* means, we prevent looping in + * qeth_send_control_data */ + atomic_set(&card->write_busy,0); + qeth_wakeup_procfile(); + } + my_read_unlock(&list_lock); + } +} + +struct net_device *qeth_chandev_init_netdev(struct net_device *dev, + int sizeof_priv) +{ + + qeth_card_t *card = NULL; + int result; + char dbf_text[15]; + + if (!dev) { + PRINT_ERR("qeth_chandev_init_netdev called with no device!\n"); + goto out; + } + + card = (qeth_card_t *)dev->priv; + strcpy(card->dev_name,dev->name); + result=qeth_register_netdev(card); + if (result) { + PRINT_ALL(" register_netdev %s -- rc=%i\n", + ((qeth_card_t*)firstcard->dev->priv)-> + dev_name,result); + sprintf(dbf_text,"rgnd%4x",(__u16)result); + QETH_DBF_TEXT2(1,trace,dbf_text); + atomic_set(&card->is_registered,0); + goto out; + } + strcpy(card->dev_name,dev->name); + atomic_set(&card->write_busy,0); + atomic_set(&card->is_registered,1); + + result=qeth_softsetup_card(card,QETH_WAIT_FOR_LOCK); + + if (!result) { + qeth_init_input_buffers(card); + } else { + QETH_DBF_TEXT2(0,trace,"SSFAILED"); + PRINT_WARN("soft-setup of card failed!\n"); + } + + INIT_LIST_HEAD(&card->tqueue_sst.list); + card->tqueue_sst.routine=qeth_softsetup_thread_starter; + card->tqueue_sst.data=card; + card->tqueue_sst.sync=0; + schedule_task(&card->tqueue_sst); + out: + qeth_wakeup_procfile(); + return dev; + +} + +static int qeth_probe(chandev_probeinfo *probeinfo) +{ + int result; + struct net_device *pdevice = NULL; + int sizeof_priv; + qeth_card_t *card; + char *basename = NULL; + + result = qeth_attach_handler(probeinfo->read.irq, probeinfo); + if (result) + return result; + + sizeof_priv = sizeof(qeth_card_t); + card = qeth_get_card_by_irq(probeinfo->read.irq); + + pdevice = card->dev; + basename = (char *)qeth_get_dev_basename(card->type, card->link_type); + + pdevice->irq=card->irq0; + + if (probeinfo->memory_usage_in_k>=0) + probeinfo->memory_usage_in_k= + -card->options.memory_usage_in_k; + pdevice = chandev_initnetdevice(probeinfo, + card->options.portno, + pdevice, + sizeof_priv, + basename, + qeth_chandev_init_netdev, + qeth_chandev_unregister_device); + if (pdevice) { + return 0; + } else { + qeth_remove_card(card,QETH_REMOVE_CARD_PROPER); + qeth_remove_card_from_list(card); + QETH_DBF_TEXT4(0,trace,"freecard"); + qeth_free_card(card); + return -ENODEV; + } + +} + +static int qeth_dev_event(struct notifier_block *this, + unsigned long event,void *ptr) +{ + qeth_card_t *card; + struct net_device *dev = (struct net_device *)ptr; + char dbf_text[15]; + + sprintf(dbf_text,"devevent"); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long)); + QETH_DBF_HEX3(0,trace,&dev,sizeof(void*)); + +#ifdef QETH_VLAN + if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) + card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv; + else +#endif + card=(qeth_card_t *)dev->priv; + if (qeth_does_card_exist(card)) { + qeth_save_dev_flag_state(card); + switch (event) { + default: + qeth_start_softsetup_thread(card); + break; + } + } + + return NOTIFY_DONE; +} + +static int qeth_ip_event(struct notifier_block *this, + unsigned long event,void *ptr) +{ + qeth_card_t *card; + struct in_ifaddr *ifa=(struct in_ifaddr *)ptr; + struct net_device *dev = ifa->ifa_dev->dev; + char dbf_text[15]; + + sprintf(dbf_text,"ipevent"); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long)); + QETH_DBF_HEX3(0,trace,&dev,sizeof(void*)); + sprintf(dbf_text,"%08x",ifa->ifa_address); + QETH_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"%08x",ifa->ifa_mask); + QETH_DBF_TEXT3(0,trace,dbf_text); + +#ifdef QETH_VLAN + if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) + card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv; + else +#endif + card=(qeth_card_t *)dev->priv; + if (qeth_does_card_exist(card)) { + QETH_DBF_HEX3(0,trace,&card,sizeof(void*)); + qeth_save_dev_flag_state(card); + qeth_start_softsetup_thread(card); + } + + return NOTIFY_DONE; +} + +#ifdef QETH_IPV6 +static int qeth_ip6_event(struct notifier_block *this, + unsigned long event,void *ptr) +{ + qeth_card_t *card; + struct inet6_ifaddr *ifa=(struct inet6_ifaddr *)ptr; + struct net_device *dev = ifa->idev->dev; + char dbf_text[15]; + + sprintf(dbf_text,"ip6event"); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long)); + QETH_DBF_HEX3(0,trace,&dev,sizeof(void*)); + QETH_DBF_HEX3(0,trace,ifa->addr.s6_addr,QETH_DBF_TRACE_LEN); + QETH_DBF_HEX3(0,trace,ifa->addr.s6_addr+QETH_DBF_TRACE_LEN, + QETH_DBF_TRACE_LEN); + +#ifdef QETH_VLAN + if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) + card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv; + else +#endif + card=(qeth_card_t *)dev->priv; + + if (qeth_does_card_exist(card)) { + QETH_DBF_HEX3(0,trace,&card,sizeof(void*)); + qeth_save_dev_flag_state(card); + qeth_start_softsetup_thread(card); + } + + return NOTIFY_DONE; +} +#endif /* QETH_IPV6 */ + +static int qeth_reboot_event(struct notifier_block *this, + unsigned long event,void *ptr) +{ + qeth_card_t *card; + + my_read_lock(&list_lock); + if (firstcard) { + card = firstcard; +clear_another_one: + if (card->has_irq) { + if (card->type==QETH_CARD_TYPE_IQD) { + halt_IO(card->irq2,0,0); + clear_IO(card->irq0,0,0); + clear_IO(card->irq1,0,0); + clear_IO(card->irq2,0,0); + } else { + clear_IO(card->irq2,0,0); + clear_IO(card->irq0,0,0); + clear_IO(card->irq1,0,0); + } + } + if (card->next) { + card = card->next; + goto clear_another_one; + } + } + my_read_unlock(&list_lock); + + return 0; +} + +static struct notifier_block qeth_dev_notifier = { + qeth_dev_event, + 0 +}; + +static struct notifier_block qeth_ip_notifier = { + qeth_ip_event, + 0 +}; + +#ifdef QETH_IPV6 +static struct notifier_block qeth_ip6_notifier = { + qeth_ip6_event, + 0 +}; +#endif /* QETH_IPV6 */ + +static struct notifier_block qeth_reboot_notifier = { + qeth_reboot_event, + 0 +}; + +static void qeth_register_notifiers(void) +{ + int r; + + QETH_DBF_TEXT5(0,trace,"regnotif"); + /* register to be notified on events */ + r=register_netdevice_notifier(&qeth_dev_notifier); + + r=register_inetaddr_notifier(&qeth_ip_notifier); +#ifdef QETH_IPV6 + r=register_inet6addr_notifier(&qeth_ip6_notifier); +#endif /* QETH_IPV6 */ + r=register_reboot_notifier(&qeth_reboot_notifier); +} + +#ifdef MODULE +static void qeth_unregister_notifiers(void) +{ + int r; + + QETH_DBF_TEXT5(0,trace,"unregnot"); + r=unregister_netdevice_notifier(&qeth_dev_notifier); + r=unregister_inetaddr_notifier(&qeth_ip_notifier); +#ifdef QETH_IPV6 + r=unregister_inet6addr_notifier(&qeth_ip6_notifier); +#endif /* QETH_IPV6 */ + r=unregister_reboot_notifier(&qeth_reboot_notifier); +} +#endif /* MODULE */ + +static int qeth_procfile_open(struct inode *inode, struct file *file) +{ + int length=0; + qeth_card_t *card; + char checksum_str[5],queueing_str[14],router_str[8],bufsize_str[4]; + char *buffer; + int rc=0; + int size; + tempinfo_t *info; + + info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t)); + if (info == NULL) { + PRINT_WARN("No memory available for data\n"); + return -ENOMEM; + } else { + file->private_data = (void *) info; + } + + /* lock all the stuff */ + my_read_lock(&list_lock); + card=firstcard; + size=200; /* 2 lines plus some sanity space */ + while (card) { + size+=90; /* if device name is > 10 chars, (should never + happen...), we'll need that */ + card=card->next; + } + + buffer=info->data = (char *) vmalloc (size); + if (info->data == NULL) { + PRINT_WARN("No memory available for data\n"); + vfree (info); + rc=-ENOMEM; + goto out; + } + + QETH_DBF_TEXT2(0,trace,"procread"); + length+=sprintf(buffer+length, + "devnos (hex) CHPID " \ + "device cardtype port chksum prio-q'ing " \ + "rtr fsz C cnt\n"); + length+=sprintf(buffer+length, + "-------------- --- ----" \ + "------ -------------- -- -- ---------- " \ + "--- --- - ---\n"); + card=firstcard; + while (card) { + strcpy(checksum_str, + (card->options.checksum_type==SW_CHECKSUMMING)?"SW": + (card->options.checksum_type==HW_CHECKSUMMING)?"HW": + "no"); + if (card->options.do_prio_queueing==NO_PRIO_QUEUEING) { + sprintf(queueing_str,"always_q_%i", + card->options.default_queue); + } else { + strcpy(queueing_str,(card->options.do_prio_queueing + ==PRIO_QUEUEING_PREC)?"by_prec.": + "by_ToS"); + } + +#ifdef QETH_IPV6 + if (atomic_read(&card->rt4fld) && + atomic_read(&card->rt6fld)) + strcpy(router_str, "no"); + else if (atomic_read(&card->rt4fld) || + atomic_read(&card->rt6fld)) + strcpy(router_str, "mix"); +#else /* QETH_IPV6 */ + if (atomic_read(&card->rt4fld)) + strcpy(router_str, "no"); +#endif /* QETH_IPV6 */ + else if ( ((card->options.routing_type4&ROUTER_MASK)== + PRIMARY_ROUTER) +#ifdef QETH_IPV6 + && + ((card->options.routing_type6&ROUTER_MASK)== + PRIMARY_ROUTER) +#endif /* QETH_IPV6 */ + ) { + strcpy(router_str,"pri"); + } else + if ( ((card->options.routing_type4&ROUTER_MASK)== + SECONDARY_ROUTER) +#ifdef QETH_IPV6 + && + ((card->options.routing_type6&ROUTER_MASK)== + SECONDARY_ROUTER) +#endif /* QETH_IPV6 */ + ) { + strcpy(router_str,"sec"); + } else + if ( ((card->options.routing_type4&ROUTER_MASK)== + MULTICAST_ROUTER) +#ifdef QETH_IPV6 + && + ((card->options.routing_type6&ROUTER_MASK)== + MULTICAST_ROUTER) +#endif /* QETH_IPV6 */ + ) { + strcpy(router_str,"mc"); + } else + if ( ((card->options.routing_type4&ROUTER_MASK)== + PRIMARY_CONNECTOR) +#ifdef QETH_IPV6 + && + ((card->options.routing_type6&ROUTER_MASK)== + PRIMARY_CONNECTOR) +#endif /* QETH_IPV6 */ + ) { + strcpy(router_str,"p.c"); + } else + if ( ((card->options.routing_type4&ROUTER_MASK)== + SECONDARY_CONNECTOR) +#ifdef QETH_IPV6 + && + ((card->options.routing_type6&ROUTER_MASK)== + SECONDARY_CONNECTOR) +#endif /* QETH_IPV6 */ + ) { + strcpy(router_str,"s.c"); + } else + if ( ((card->options.routing_type4&ROUTER_MASK)== + NO_ROUTER) +#ifdef QETH_IPV6 + && + ((card->options.routing_type6&ROUTER_MASK)== + NO_ROUTER) +#endif /* QETH_IPV6 */ + ) { + strcpy(router_str,"no"); + } else { + strcpy(router_str,"mix"); + } + strcpy(bufsize_str, + (BUFFER_SIZE==16384)?"16k": + (BUFFER_SIZE==24576)?"24k": + (BUFFER_SIZE==32768)?"32k": + (BUFFER_SIZE==40960)?"40k": + "64k"); + if (atomic_read(&card->is_gone)) { + length+=sprintf(buffer+length, + "%04X/%04X/%04X x%02X %10s %14s %2i" + " +++ CARD IS GONE +++\n", + card->devno0,card->devno1,card->devno2, + card->chpid, + card->dev_name, + qeth_get_cardname_short + (card->type,card->link_type), + card->options.portno); + } else if (!atomic_read(&card->is_startlaned)) { + length+=sprintf(buffer+length, + "%04X/%04X/%04X x%02X %10s %14s %2i" + " +++ CABLE PULLED +++\n", + card->devno0,card->devno1,card->devno2, + card->chpid, + card->dev_name, + qeth_get_cardname_short + (card->type,card->link_type), + card->options.portno); + } else { + length+=sprintf(buffer+length, + "%04X/%04X/%04X x%02X %10s %14s %2i" \ + " %2s %10s %3s %3s %c %3i\n", + card->devno0,card->devno1,card->devno2, + card->chpid,card->dev_name, + qeth_get_cardname_short + (card->type,card->link_type), + card->options.portno, + checksum_str, + queueing_str,router_str,bufsize_str, + (card->options.memusage== + MEMUSAGE_CONTIG)?'c':' ', + card->options.inbound_buffer_count); + } + card=card->next; + } + +out: + info->len=length; + /* unlock all the stuff */ + my_read_unlock(&list_lock); + return rc; +} + +static qeth_card_t *qeth_find_card(char *buffer,int len) +{ + qeth_card_t *card; + int devnamelen; + + my_read_lock(&list_lock); + card=firstcard; + while (card) { + devnamelen=0; + while ( (devnamelendev_name[devnamelen]!=' ') && + (card->dev_name[devnamelen]!=0) && + (card->dev_name[devnamelen]!='\n') ) ) { + devnamelen++; + } + if ((!strncmp(card->dev_name,buffer, + qeth_min(len,DEV_NAME_LEN)))&& + (devnamelen==len) && + (!atomic_read(&card->shutdown_phase))) break; + card=card->next; + } + my_read_unlock(&list_lock); + + return card; +} + +static int qeth_get_next_token(char *buffer,int *token_len, + int *pos,int *end_pos,int count) +{ + *token_len=0; + *end_pos=*pos; + if (*end_pos>=count) return 0; + if (!buffer[*end_pos]) return 0; + for (;;) { + if ( (buffer[*end_pos]!=' ') && + (buffer[*end_pos]!='\t') && + (buffer[*end_pos]!='\n') && + (buffer[*end_pos]!='\r') && + (buffer[*end_pos]!=0) && + (*end_pos=count) return; + if ((buffer[*pos]==' ')|| + (buffer[*pos]=='\t')|| + (buffer[*pos]=='\n')|| + (buffer[*pos]=='\r')) *pos=(*pos)+1; + else return; + } +} + +#define CHECK_MISSING_PARAMETER do { \ + pos=end_pos; \ + if (!qeth_get_next_token(buffer,&token_len,&pos,&end_pos,user_len)) { \ + PRINT_WARN("paramter missing on procfile input, " \ + "ignoring input!\n"); \ + goto out; \ + } \ + card=qeth_find_card(buffer+pos,token_len); \ + if (!card) { \ + PRINT_WARN("paramter invalid on procfile input, " \ + "ignoring input!\n"); \ + goto out; \ + } \ +} while (0) + +static ssize_t qeth_procfile_write(struct file *file, + const char *user_buffer, + size_t user_len,loff_t *offset) +{ + qeth_card_t *card; + char *buffer; + int token_len; + int pos=0,end_pos; + char dbf_text[15]; + + if (*offset>0) return user_len; + buffer=vmalloc(__max(user_len+1,QETH_DBF_MISC_LEN)); + if (buffer == NULL) + return -ENOMEM; + memset(buffer,0,user_len+1); + + if (copy_from_user(buffer, user_buffer, user_len)) { + vfree (buffer); + return -EFAULT; + } + + QETH_DBF_TEXT2(0,trace,"procwrit"); + QETH_DBF_TEXT2(0,misc,buffer); + + if (!qeth_get_next_token(buffer,&token_len,&pos,&end_pos,user_len)) + goto out; + qeth_skip_whitespace(buffer,&end_pos,user_len); + + if (!strncmp(buffer+pos,"recover",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"UTRC%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + atomic_set(&card->problem, + PROBLEM_USER_TRIGGERED_RECOVERY); + qeth_schedule_recovery(card); + + } else if (!strncmp(buffer+pos,"remember",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"remb%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + card->save_state_flag=1; + + } else if (!strncmp(buffer+pos,"forget",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"forg%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + card->save_state_flag=0; + } else if (!strncmp(buffer+pos,"primary_router",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"prir%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=PRIMARY_ROUTER| + RESET_ROUTING_FLAG; +#ifdef QETH_IPV6 + card->options.routing_type6=PRIMARY_ROUTER| + RESET_ROUTING_FLAG; +#endif /* QETH_IPV6 */ + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); +#endif /* QETH_IPV6 */ + qeth_start_softsetup_thread(card); + } else if (!strncmp(buffer+pos,"primary_router4",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"pri4%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=PRIMARY_ROUTER| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#ifdef QETH_IPV6 + } else if (!strncmp(buffer+pos,"primary_router6",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"pri6%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type6=PRIMARY_ROUTER| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#endif /* QETH_IPV6 */ + } else if (!strncmp(buffer+pos,"secondary_router",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"secr%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=SECONDARY_ROUTER| + RESET_ROUTING_FLAG; +#ifdef QETH_IPV6 + card->options.routing_type6=SECONDARY_ROUTER| + RESET_ROUTING_FLAG; +#endif /* QETH_IPV6 */ + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); +#endif /* QETH_IPV6 */ + qeth_start_softsetup_thread(card); + } else if (!strncmp(buffer+pos,"secondary_router4",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"sec4%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=SECONDARY_ROUTER| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#ifdef QETH_IPV6 + } else if (!strncmp(buffer+pos,"secondary_router6",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"sec6%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type6=SECONDARY_ROUTER| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#endif /* QETH_IPV6 */ + } else if (!strncmp(buffer+pos,"multicast_router",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"mcr %4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=MULTICAST_ROUTER| + RESET_ROUTING_FLAG; +#ifdef QETH_IPV6 + card->options.routing_type6=MULTICAST_ROUTER| + RESET_ROUTING_FLAG; +#endif /* QETH_IPV6 */ + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); +#endif /* QETH_IPV6 */ + qeth_start_softsetup_thread(card); + } else if (!strncmp(buffer+pos,"multicast_router4",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"mcr4%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=MULTICAST_ROUTER| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#ifdef QETH_IPV6 + } else if (!strncmp(buffer+pos,"multicast_router6",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"mcr6%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type6=MULTICAST_ROUTER| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#endif /* QETH_IPV6 */ + } else if (!strncmp(buffer+pos,"primary_connector",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"prc %4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=PRIMARY_CONNECTOR| + RESET_ROUTING_FLAG; +#ifdef QETH_IPV6 + card->options.routing_type6=PRIMARY_CONNECTOR| + RESET_ROUTING_FLAG; +#endif /* QETH_IPV6 */ + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); +#endif /* QETH_IPV6 */ + qeth_start_softsetup_thread(card); + } else if (!strncmp(buffer+pos,"primary_connector4",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"prc4%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=PRIMARY_CONNECTOR| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#ifdef QETH_IPV6 + } else if (!strncmp(buffer+pos,"primary_connector6",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"prc6%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type6=PRIMARY_CONNECTOR| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#endif /* QETH_IPV6 */ + } else if (!strncmp(buffer+pos,"secondary_connector",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"scc %4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=SECONDARY_CONNECTOR| + RESET_ROUTING_FLAG; +#ifdef QETH_IPV6 + card->options.routing_type6=SECONDARY_CONNECTOR| + RESET_ROUTING_FLAG; +#endif /* QETH_IPV6 */ + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); +#endif /* QETH_IPV6 */ + qeth_start_softsetup_thread(card); + } else if (!strncmp(buffer+pos,"secondary_connector4",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"scc4%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=SECONDARY_CONNECTOR| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#ifdef QETH_IPV6 + } else if (!strncmp(buffer+pos,"secondary_connector6",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"scc6%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type6=SECONDARY_CONNECTOR| + RESET_ROUTING_FLAG; + qeth_correct_routing_status(card); + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#endif /* QETH_IPV6 */ + } else if (!strncmp(buffer+pos,"no_router",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"nor %4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=NO_ROUTER| + RESET_ROUTING_FLAG; +#ifdef QETH_IPV6 + card->options.routing_type6=NO_ROUTER| + RESET_ROUTING_FLAG; +#endif /* QETH_IPV6 */ + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); +#ifdef QETH_IPV6 + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); +#endif /* QETH_IPV6 */ + qeth_start_softsetup_thread(card); + } else if (!strncmp(buffer+pos,"no_router4",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"nor4%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type4=NO_ROUTER| + RESET_ROUTING_FLAG; + atomic_set(&card->enable_routing_attempts4, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#ifdef QETH_IPV6 + } else if (!strncmp(buffer+pos,"no_router6",token_len)) { + CHECK_MISSING_PARAMETER; + sprintf(dbf_text,"nor6%4x",card->irq0); + QETH_DBF_TEXT2(0,trace,dbf_text); + + card->options.routing_type6=NO_ROUTER| + RESET_ROUTING_FLAG; + atomic_set(&card->enable_routing_attempts6, + QETH_ROUTING_ATTEMPTS); + qeth_start_softsetup_thread(card); +#endif /* QETH_IPV6 */ + } else { + PRINT_WARN("unknown command input in procfile\n"); + } +#undef CHECK_MISSING_PARAMETER +out: + + *offset = *offset + user_len; + vfree(buffer); + + return user_len; +} + +#define _OUTP_IT(x...) c+=sprintf(buffer+c,x) + +#ifdef QETH_PERFORMANCE_STATS +static int qeth_perf_procfile_read(char *buffer,char **buffer_location, + off_t offset,int buffer_length,int *eof, + void *data) +{ + int c=0; + qeth_card_t *card; + /* we are always called with buffer_length=4k, so we all + deliver on the first read */ + if (offset>0) return 0; + + QETH_DBF_TEXT2(0,trace,"perfpfrd"); + + card=firstcard; + + while (card) { + _OUTP_IT("For card with devnos 0x%X/0x%X/0x%X (%s):\n", + card->devno0,card->devno1,card->devno2, + card->dev_name); + _OUTP_IT(" Skb's/buffers received : %i/%i\n", + card->perf_stats.skbs_rec, + card->perf_stats.bufs_rec); + _OUTP_IT(" Skb's/buffers sent : %i/%i\n", + card->perf_stats.skbs_sent, + card->perf_stats.bufs_sent); + _OUTP_IT("\n"); + _OUTP_IT(" Skb's/buffers sent without packing : %i/%i\n", + card->perf_stats.skbs_sent_dont_pack, + card->perf_stats.bufs_sent_dont_pack); + _OUTP_IT(" Skb's/buffers sent with packing : %i/%i\n", + card->perf_stats.skbs_sent_pack, + card->perf_stats.bufs_sent_pack); + _OUTP_IT("\n"); + _OUTP_IT(" Packing state changes no pkg.->packing : %i/%i\n", + card->perf_stats.sc_dp_p, + card->perf_stats.sc_p_dp); + _OUTP_IT(" Current buffer usage (outbound q's) : " \ + "%i/%i/%i/%i\n", + atomic_read(&card->outbound_used_buffers[0]), + atomic_read(&card->outbound_used_buffers[1]), + atomic_read(&card->outbound_used_buffers[2]), + atomic_read(&card->outbound_used_buffers[3])); + _OUTP_IT("\n"); + _OUTP_IT(" Inbound time (in us) : %i\n", + card->perf_stats.inbound_time); + _OUTP_IT(" Inbound cnt : %i\n", + card->perf_stats.inbound_cnt); + _OUTP_IT(" Outbound time (in us, incl QDIO) : %i\n", + card->perf_stats.outbound_time); + _OUTP_IT(" Outbound cnt : %i\n", + card->perf_stats.outbound_cnt); + _OUTP_IT(" Watermarks: L/H=%i/%i\n", + LOW_WATERMARK_PACK,HIGH_WATERMARK_PACK); + _OUTP_IT("\n"); + + card=card->next; + } + + return c; +} + +static struct proc_dir_entry *qeth_perf_proc_file; + +#endif /* QETH_PERFORMANCE_STATS */ + +static int qeth_ipato_procfile_open(struct inode *inode, struct file *file) +{ + char text[33]; + ipato_entry_t *ipato_entry; + qeth_card_t *card; + qeth_vipa_entry_t *vipa_entry; + int rc=0; + tempinfo_t *info; + int size; + char entry_type[5]; + + info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t)); + if (info == NULL) { + PRINT_WARN("No memory available for data\n"); + return -ENOMEM; + } else { + file->private_data = (void *) info; + } + info->len=0; + + QETH_DBF_TEXT2(0,trace,"ipatorea"); + /* lock all the stuff */ + my_spin_lock(&ipato_list_lock); + my_read_lock(&list_lock); + + size=64; /* for inv4/6 etc. */ + + ipato_entry=ipato_entries; + while (ipato_entry) { + ipato_entry=ipato_entry->next; + size+=64; + } + card=firstcard; + while (card) { + my_read_lock(&card->vipa_list_lock); + vipa_entry=card->vipa_list; + while (vipa_entry) { + vipa_entry=vipa_entry->next; + size+=64; + } + /*my_read_unlock(&card->vipa_list_lock); don't unlock it here*/ + card=card->next; + } + info->data = (char *) vmalloc (size); + if (info->data == NULL) { + PRINT_WARN("No memory available for data\n"); + vfree (info); + rc=-ENOMEM; + goto out; + } + +#define _IOUTP_IT(x...) info->len+=sprintf(info->data+info->len,x) + if (ipato_inv4) + _IOUTP_IT("inv4\n"); + ipato_entry=ipato_entries; + text[8]=0; + while (ipato_entry) { + if (ipato_entry->version==4) { + qeth_convert_addr_to_text(4,ipato_entry->addr,text); + _IOUTP_IT("add4 %s/%i%s%s\n",text, + ipato_entry->mask_bits, + ipato_entry->dev_name[0]?":":"", + ipato_entry->dev_name[0]? + ipato_entry->dev_name:""); + } + ipato_entry=ipato_entry->next; + } + + if (ipato_inv6) + _IOUTP_IT("inv6\n"); + ipato_entry=ipato_entries; + text[32]=0; + while (ipato_entry) { + if (ipato_entry->version==6) { + qeth_convert_addr_to_text(6,ipato_entry->addr,text); + _IOUTP_IT("add6 %s/%i%s%s\n",text, + ipato_entry->mask_bits, + ipato_entry->dev_name[0]?":":"", + ipato_entry->dev_name[0]? + ipato_entry->dev_name:""); + } + ipato_entry=ipato_entry->next; + } + card=firstcard; + while (card) { + vipa_entry=card->vipa_list; + while (vipa_entry) { + strcpy(entry_type,(vipa_entry->flag== + IPA_SETIP_VIPA_FLAGS)? + "vipa":"rxip"); + if (vipa_entry->version==4) { + _IOUTP_IT("add_%s4 %02x%02x%02x%02x:%s\n", + entry_type, + vipa_entry->ip[0], + vipa_entry->ip[1], + vipa_entry->ip[2], + vipa_entry->ip[3], + card->dev_name); + } else { + _IOUTP_IT("add_%s6 %02x%02x%02x%02x" \ + "%02x%02x%02x%02x" \ + "%02x%02x%02x%02x" \ + "%02x%02x%02x%02x:%s\n", + entry_type, + vipa_entry->ip[0], + vipa_entry->ip[1], + vipa_entry->ip[2], + vipa_entry->ip[3], + vipa_entry->ip[4], + vipa_entry->ip[5], + vipa_entry->ip[6], + vipa_entry->ip[7], + vipa_entry->ip[8], + vipa_entry->ip[9], + vipa_entry->ip[10], + vipa_entry->ip[11], + vipa_entry->ip[12], + vipa_entry->ip[13], + vipa_entry->ip[14], + vipa_entry->ip[15], + card->dev_name); + } + vipa_entry=vipa_entry->next; + } + card=card->next; + } +out: + /* unlock all the stuff */ + card=firstcard; + while (card) { + /*my_read_lock(&card->vipa_list_lock); don't lock it here */ + my_read_unlock(&card->vipa_list_lock); + card=card->next; + } + my_read_unlock(&list_lock); + my_spin_unlock(&ipato_list_lock); + + return rc; +} + +static ssize_t qeth_procfile_read(struct file *file,char *user_buf, + size_t user_len,loff_t * offset) +{ + loff_t len; + tempinfo_t *p_info = (tempinfo_t *) file->private_data; + + if (*offset >= p_info->len) { + return 0; + } else { + len = __min(user_len, (p_info->len - *offset)); + if (copy_to_user (user_buf, &(p_info->data[*offset]), len)) + return -EFAULT; + (*offset) += len; + return len; + } +} + +/* ATT: this is also the procfile release function for the ipato + * procfs entry */ +static int qeth_procfile_release(struct inode *inode,struct file *file) +{ + tempinfo_t *p_info = (tempinfo_t *) file->private_data; + + if (p_info) { + if (p_info->data) + vfree (p_info->data); + vfree (p_info); + } + + return 0; +} + +static ssize_t qeth_ipato_procfile_write(struct file *file, + const char *user_buffer, + size_t user_len,loff_t *offset) +{ + int add,version; + char text[33]; + __u8 addr[16]; + int len,i,flag; + int mask_bits; + char *buffer; + int dev_name_there; + char *dev_name_ptr; + qeth_card_t *card; +#define BUFFER_LEN (10+32+1+5+1+DEV_NAME_LEN+1) + + if (*offset>0) return user_len; + buffer=vmalloc(__max(__max(user_len+1,BUFFER_LEN),QETH_DBF_MISC_LEN)); + + if (buffer == NULL) + return -ENOMEM; + /* BUFFER_LEN=command incl. blank+addr+slash+mask_bits+ + * colon+DEV_NAME_LEN+zero */ + memset(buffer,0,BUFFER_LEN); + + if (copy_from_user(buffer, user_buffer, user_len)) { + vfree (buffer); + return -EFAULT; + } + + QETH_DBF_TEXT2(0,trace,"ipatowri"); + QETH_DBF_TEXT2(0,misc,buffer); + if (!strncmp(buffer,"inv4",4)) { + ipato_inv4=1-ipato_inv4; + goto out; + } + if (!strncmp(buffer,"inv6",4)) { + ipato_inv6=1-ipato_inv6; + goto out; + } + if ( (!strncmp(buffer,"add4 ",5)) || + (!strncmp(buffer,"add6 ",5)) || + (!strncmp(buffer,"del4 ",5)) || + (!strncmp(buffer,"del6 ",5)) ) { + text[8]=0; + text[32]=0; + add=!strncmp(buffer,"add",3); + version=(buffer[3]=='4')?4:6; + len=(version==4)?8:32; + strncpy(text,buffer+5,len); + if (qeth_convert_text_to_addr(version,text,addr)) { + PRINT_ERR("error in parsing ipato information " \ + "(addr)\n"); + goto out; + } + strncpy(text,buffer+5+len+1,10); + /* we prepare mask_bits for qeth_getints */ + dev_name_there=0; + for (i=5+len+1;i((version==4)?32:128))) { + PRINT_ERR("error in parsing ipato information " \ + "(mask bits)\n"); + goto out; + } + if (dev_name_there) { + dev_name_ptr=buffer+dev_name_there+1; + /* wipe out the linefeed */ + for (i=dev_name_there+1; + i 0) ) + return -EFAULT; + if ( data_size > IOCTL_MAX_TRANSFER_SIZE ) + return -EFAULT; + if ( !access_ok(VERIFY_WRITE, (void *)arg, data_size) ) + return -EFAULT; + + my_read_lock(&list_lock); + card = firstcard; +#define IOCTL_USER_STRUCT_SIZE (DEV_NAME_LEN*sizeof(char)) + \ + sizeof(__u32) + sizeof(__u32) + while (card) { + if (card->type == QETH_CARD_TYPE_OSAE) + number_of_devices=number_of_devices + IOCTL_USER_STRUCT_SIZE; + card = card->next; + } +#undef IOCTL_USER_STRUCT_SIZE + if ((number_of_devices + 4*sizeof(__u32)) >= data_size) { + result=-ENOMEM; + goto out; + } + + number_of_devices=0; + card = firstcard; + buffer = (char *)vmalloc(data_size); + if (!buffer) { + result=-EFAULT; + goto out; + } + buffer_pointer = ((char *)(buffer)) + (4*sizeof(__u32)) ; + while (card) { + if ((card->type == QETH_CARD_TYPE_OSAE)&& + (!atomic_read(&card->is_gone))&& + (atomic_read(&card->is_hardsetup))&& + (atomic_read(&card->is_registered))) { + + memcpy(buffer_pointer,card->dev_name,DEV_NAME_LEN); + buffer_pointer = buffer_pointer + DEV_NAME_LEN; + if_index=card->dev->ifindex; + memcpy(buffer_pointer,&if_index,sizeof(__u32)); + buffer_pointer = buffer_pointer + sizeof(__u32); + memcpy(buffer_pointer,&ioctl_flags,sizeof(__u32)); + buffer_pointer = buffer_pointer + sizeof(__u32); + number_of_devices=number_of_devices+1; + } + card = card->next; + } + + /* we copy the real size */ + data_len=buffer_pointer-buffer; + + buffer_pointer = buffer; + /* copy the header information at the beginning of the buffer */ + memcpy(buffer_pointer,&version,sizeof(__u32)); + memcpy(((char *)buffer_pointer)+sizeof(__u32),&valid_fields, + sizeof(__u32)); + memcpy(((char *)buffer_pointer)+(2*sizeof(__u32)),&qeth_version, + sizeof(__u32)); + memcpy(((char *)buffer_pointer)+(3*sizeof(__u32)),&number_of_devices, + sizeof(__u32)); + copy_to_user((char *)arg,buffer,data_len); + vfree(buffer); +out: + my_read_unlock(&list_lock); + return result; + +#undef PARMS_BUFFERLENGTH + +}; + +static int qeth_procfile_interfacechanges(unsigned long arg) +{ + return qeth_sleepon_procfile(); + +} + +static int qeth_procfile_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + + int result; + down_interruptible(&qeth_procfile_ioctl_lock); + switch (cmd) { + + case QETH_IOCPROC_OSAEINTERFACES: + result = qeth_procfile_getinterfaces(arg); + break; + case QETH_IOCPROC_INTERFACECHANGES: + result = qeth_procfile_interfacechanges(arg); + break; + default: + result = -EOPNOTSUPP; + } + up(&qeth_procfile_ioctl_lock); + return result; +}; + +static struct file_operations qeth_procfile_fops = +{ + ioctl:qeth_procfile_ioctl, + read:qeth_procfile_read, + write:qeth_procfile_write, + open:qeth_procfile_open, + release:qeth_procfile_release, +}; + +static struct proc_dir_entry *qeth_proc_file; + +static struct file_operations qeth_ipato_procfile_fops = +{ + read:qeth_procfile_read, /* same as above! */ + write:qeth_ipato_procfile_write, + open:qeth_ipato_procfile_open, + release:qeth_procfile_release /* same as above! */ +}; + +static struct proc_dir_entry *qeth_ipato_proc_file; + +static void qeth_add_procfs_entries(void) +{ + proc_file_registration=0; + qeth_proc_file=create_proc_entry(QETH_PROCFILE_NAME, + S_IFREG|0644,&proc_root); + if (qeth_proc_file) { + qeth_proc_file->proc_fops = &qeth_procfile_fops; + sema_init(&qeth_procfile_ioctl_sem, + PROCFILE_SLEEP_SEM_MAX_VALUE); + sema_init(&qeth_procfile_ioctl_lock, + PROCFILE_IOCTL_SEM_MAX_VALUE); + } else proc_file_registration=-1; + + if (proc_file_registration) + PRINT_WARN("was not able to register proc-file (%i).\n", + proc_file_registration); + proc_ipato_file_registration=0; + qeth_ipato_proc_file=create_proc_entry(QETH_IPA_PROCFILE_NAME, + S_IFREG|0644,&proc_root); + if (qeth_ipato_proc_file) { + qeth_ipato_proc_file->proc_fops = &qeth_ipato_procfile_fops; + } else proc_ipato_file_registration=-1; + + if (proc_ipato_file_registration) + PRINT_WARN("was not able to register ipato-proc-file (%i).\n", + proc_ipato_file_registration); + +#ifdef QETH_PERFORMANCE_STATS + proc_perf_file_registration=0; + qeth_perf_proc_file=create_proc_entry(QETH_PERF_PROCFILE_NAME, + S_IFREG|0444,&proc_root); + if (qeth_perf_proc_file) { + qeth_perf_proc_file->read_proc=&qeth_perf_procfile_read; + } else proc_perf_file_registration=-1; + + if (proc_perf_file_registration) + PRINT_WARN("was not able to register perf. proc-file (%i).\n", + proc_perf_file_registration); +#endif /* QETH_PERFORMANCE_STATS */ +} + +#ifdef MODULE +static void qeth_remove_procfs_entries(void) +{ + if (!proc_file_registration) /* means if it went ok earlier */ + remove_proc_entry(QETH_PROCFILE_NAME,&proc_root); + + if (!proc_ipato_file_registration) /* means if it went ok earlier */ + remove_proc_entry(QETH_IPA_PROCFILE_NAME,&proc_root); + +#ifdef QETH_PERFORMANCE_STATS + if (!proc_perf_file_registration) /* means if it went ok earlier */ + remove_proc_entry(QETH_PERF_PROCFILE_NAME,&proc_root); +#endif /* QETH_PERFORMANCE_STATS */ +} +#endif /* MODULE */ + +static void qeth_unregister_dbf_views(void) +{ + if (qeth_dbf_setup) + debug_unregister(qeth_dbf_setup); + if (qeth_dbf_qerr) + debug_unregister(qeth_dbf_qerr); + if (qeth_dbf_sense) + debug_unregister(qeth_dbf_sense); + if (qeth_dbf_misc) + debug_unregister(qeth_dbf_misc); + if (qeth_dbf_data) + debug_unregister(qeth_dbf_data); + if (qeth_dbf_control) + debug_unregister(qeth_dbf_control); + if (qeth_dbf_trace) + debug_unregister(qeth_dbf_trace); +} + +static int qeth_chandev_shutdown(struct net_device *dev) +{ + + qeth_card_t* card; + + card = (qeth_card_t *)dev->priv; + + my_spin_lock(&setup_lock); + + qeth_remove_card_from_list(card); + QETH_DBF_TEXT4(0,trace,"freecard"); + qeth_free_card(card); + + my_spin_unlock(&setup_lock); + + return 0; + +} + +#ifdef QETH_IPV6 +static int qeth_ipv6_init(void) +{ + qeth_old_arp_constructor=arp_tbl.constructor; + write_lock(&arp_tbl.lock); + arp_tbl.constructor=qeth_arp_constructor; + write_unlock(&arp_tbl.lock); + + /* generate the memory leak here */ + arp_direct_ops=(struct neigh_ops*) + kmalloc(sizeof(struct neigh_ops),GFP_KERNEL); + if (!arp_direct_ops) + return -ENOMEM; + + memcpy(arp_direct_ops,&arp_direct_ops_template, + sizeof(struct neigh_ops)); + return 0; +} + +static void qeth_ipv6_uninit(void) +{ + write_lock(&arp_tbl.lock); + arp_tbl.constructor=qeth_old_arp_constructor; + write_unlock(&arp_tbl.lock); +} +#endif /* QETH_IPV6 */ + +static void qeth_get_internal_functions(void) +{ + struct net_device dev; + ether_setup(&dev); + qeth_my_eth_header=dev.hard_header; + qeth_my_eth_rebuild_header=dev.rebuild_header; + qeth_my_eth_header_cache=dev.hard_header_cache; + qeth_my_eth_header_cache_update=dev.header_cache_update; + qeth_my_eth_header=dev.hard_header; +#ifdef CONFIG_TR + tr_setup(&dev); + qeth_my_tr_header=dev.hard_header; + qeth_my_tr_rebuild_header=dev.rebuild_header; +#endif /* CONFIG_TR */ +} + +#ifdef MODULE +int init_module(void) +#else /* MODULE */ +static int __init qeth_init(void) +#endif /* MODULE */ +{ + int result; +#ifdef MODULE + void *ptr; +#endif /* MODULE */ + + int unregister_from_chandev=0; + int cards_found; + + qeth_eyecatcher(); + + printk("qeth: loading %s\n",version); + +#ifdef MODULE + global_stay_in_mem = chandev_persist(chandev_type_qeth); +#endif /* MODULE */ + + spin_lock_init(&setup_lock); + + spin_lock_init(&ipato_list_lock); + + qeth_get_internal_functions(); + + qeth_alloc_spare_bufs(); + +#ifdef QETH_IPV6 + if (qeth_ipv6_init()) goto oom; +#endif /* QETH_IPV6 */ + + qeth_dbf_setup=debug_register(QETH_DBF_SETUP_NAME, + QETH_DBF_SETUP_INDEX, + QETH_DBF_SETUP_NR_AREAS, + QETH_DBF_SETUP_LEN); + if (!qeth_dbf_setup) goto oom; + + debug_register_view(qeth_dbf_setup,&debug_hex_ascii_view); + debug_set_level(qeth_dbf_setup,QETH_DBF_SETUP_LEVEL); + + qeth_dbf_misc=debug_register(QETH_DBF_MISC_NAME, + QETH_DBF_MISC_INDEX, + QETH_DBF_MISC_NR_AREAS, + QETH_DBF_MISC_LEN); + if (!qeth_dbf_misc) goto oom; + + debug_register_view(qeth_dbf_misc,&debug_hex_ascii_view); + debug_set_level(qeth_dbf_misc,QETH_DBF_MISC_LEVEL); + + qeth_dbf_data=debug_register(QETH_DBF_DATA_NAME, + QETH_DBF_DATA_INDEX, + QETH_DBF_DATA_NR_AREAS, + QETH_DBF_DATA_LEN); + if (!qeth_dbf_data) goto oom; + + debug_register_view(qeth_dbf_data,&debug_hex_ascii_view); + debug_set_level(qeth_dbf_data,QETH_DBF_DATA_LEVEL); + + qeth_dbf_control=debug_register(QETH_DBF_CONTROL_NAME, + QETH_DBF_CONTROL_INDEX, + QETH_DBF_CONTROL_NR_AREAS, + QETH_DBF_CONTROL_LEN); + if (!qeth_dbf_control) goto oom; + + debug_register_view(qeth_dbf_control,&debug_hex_ascii_view); + debug_set_level(qeth_dbf_control,QETH_DBF_CONTROL_LEVEL); + + qeth_dbf_sense=debug_register(QETH_DBF_SENSE_NAME, + QETH_DBF_SENSE_INDEX, + QETH_DBF_SENSE_NR_AREAS, + QETH_DBF_SENSE_LEN); + if (!qeth_dbf_sense) goto oom; + + debug_register_view(qeth_dbf_sense,&debug_hex_ascii_view); + debug_set_level(qeth_dbf_sense,QETH_DBF_SENSE_LEVEL); + + qeth_dbf_qerr=debug_register(QETH_DBF_QERR_NAME, + QETH_DBF_QERR_INDEX, + QETH_DBF_QERR_NR_AREAS, + QETH_DBF_QERR_LEN); + if (!qeth_dbf_qerr) goto oom; + + debug_register_view(qeth_dbf_qerr,&debug_hex_ascii_view); + debug_set_level(qeth_dbf_qerr,QETH_DBF_QERR_LEVEL); + + qeth_dbf_trace=debug_register(QETH_DBF_TRACE_NAME, + QETH_DBF_TRACE_INDEX, + QETH_DBF_TRACE_NR_AREAS, + QETH_DBF_TRACE_LEN); + if (!qeth_dbf_trace) goto oom; + + debug_register_view(qeth_dbf_trace,&debug_hex_ascii_view); + debug_set_level(qeth_dbf_trace,QETH_DBF_TRACE_LEVEL); + + cards_found = chandev_register_and_probe + (qeth_probe,(chandev_shutdownfunc)qeth_chandev_shutdown, + (chandev_msck_notification_func)qeth_chandev_msck_notfunc, + chandev_type_qeth); + if (cards_found>0) + result=0; + else if (cards_found<0) { + result=cards_found; + global_stay_in_mem=0; + } else result=-ENODEV; + + unregister_from_chandev=(cards_found>=0); + if ((result)&&(global_stay_in_mem)) { + result=0; + } + +#ifdef MODULE + QETH_DBF_TEXT0(0,setup,"initmodl"); + ptr=&init_module; + QETH_DBF_HEX0(0,setup,&ptr,sizeof(void*)); +#endif /* MODULE */ + + if (!result) { + qeth_register_notifiers(); + qeth_add_procfs_entries(); + } else { + /* don't call it with shutdown -- there was not device + * initialized or an internal problem in chandev, better + * have him not try to call us */ + if (unregister_from_chandev) + chandev_unregister(qeth_probe,0); + qeth_unregister_dbf_views(); +#ifdef QETH_IPV6 + qeth_ipv6_uninit(); +#endif /* QETH_IPV6 */ + qeth_free_all_spare_bufs(); + } + + return result; +oom: + PRINT_ERR("not enough memory for dbf. Will not load module.\n"); + result=-ENOMEM; +#ifdef QETH_IPV6 + qeth_ipv6_uninit(); +#endif /* QETH_IPV6 */ + qeth_unregister_dbf_views(); + qeth_free_all_spare_bufs(); + return result; +} + +#ifdef MODULE +void cleanup_module(void) +{ +#ifdef QETH_IPV6 + qeth_ipv6_uninit(); +#endif /* QETH_IPV6 */ + qeth_unregister_notifiers(); + + qeth_remove_procfs_entries(); + + QETH_DBF_TEXT1(0,trace,"cleanup."); + + chandev_unregister(qeth_probe, 1 ); + + qeth_free_all_spare_bufs(); + + qeth_unregister_dbf_views(); + + printk("qeth: %s: module removed\n",version); +} +EXPORT_SYMBOL(qeth_eyecatcher); /* yeah, i know, could be outside of + the ifdef */ +#else /* MODULE */ +__initcall(qeth_init); +#endif /* MODULE */ diff -urN linux-2.4.21/drivers/s390/net/qeth.h linux-2.4.22/drivers/s390/net/qeth.h --- linux-2.4.21/drivers/s390/net/qeth.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/s390/net/qeth.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1235 @@ +/* + * linux/drivers/s390/net/qeth.h + * + * Linux on zSeries OSA Express and HiperSockets support + * + * Copyright 2000,2003 IBM Corporation + * Author(s): Utz Bacher + * + */ + +#ifndef __QETH_H__ +#define __QETH_H__ + +#include + +#define QETH_NAME " qeth" + +#define VERSION_QETH_H "$Revision: 1.113 $" + +/******************** CONFIG STUFF ***********************/ +//#define QETH_DBF_LIKE_HELL + +#ifdef CONFIG_QETH_IPV6 +#define QETH_IPV6 +#define QETH_VERSION_IPV6 ":IPv6" +#else +#define QETH_VERSION_IPV6 "" +#endif /* CONFIG_QETH_IPV6 */ + +#ifdef CONFIG_QETH_VLAN +#define QETH_VLAN +#define QETH_VERSION_VLAN ":VLAN" +#else +#define QETH_VERSION_VLAN "" +#endif /* CONFIG_QETH_VLAN */ + +/* these values match CHECKSUM_* in include/linux/skbuff.h */ +#define SW_CHECKSUMMING 0 +#define HW_CHECKSUMMING 1 +#define NO_CHECKSUMMING 2 + +#define QETH_CHECKSUM_DEFAULT NO_CHECKSUMMING + +#define QETH_DEFAULT_QUEUE 2 + +/******************** CONFIG STUFF END ***********************/ +/********************* TUNING STUFF **************************/ +#define HIGH_WATERMARK_PACK 5 +#define LOW_WATERMARK_PACK 2 +#define WATERMARK_FUZZ 2 + +#define QETH_MAX_INPUT_THRESHOLD 500 +#define QETH_MAX_OUTPUT_THRESHOLD 300 /* ? */ + +/* only the MAX values are used */ +#define QETH_MIN_INPUT_THRESHOLD 1 +#define QETH_MIN_OUTPUT_THRESHOLD 1 + +#define QETH_REQUEUE_THRESHOLD (card->options.inbound_buffer_count/4) + +#ifdef CONFIG_QETH_PERF_STATS +#define QETH_PERFORMANCE_STATS +#endif /* CONFIG_QETH_PERF_STATS */ + +#define QETH_VERBOSE_LEVEL 7 + +#define PCI_THRESHOLD_A (card->options.inbound_buffer_count+1) /* buffers we have to be behind + before we get a PCI */ +#define PCI_THRESHOLD_B 0 /* enqueued free buffers left before we get a PCI */ +#define PCI_TIMER_VALUE 3 /* not used, unless the microcode gets patched */ + +#define DEFAULT_SPARE_BUFFERS 0 +#define MAX_SPARE_BUFFERS 1024 +#define SPAREBUF_MASK 65536 +#define MAX_PORTNO 15 + +#define QETH_PROCFILE_NAME "qeth" +#define QETH_PERF_PROCFILE_NAME "qeth_perf" +#define QETH_IPA_PROCFILE_NAME "qeth_ipa_takeover" + +#define SEND_RETRIES_ALLOWED 5 +#define QETH_ROUTING_ATTEMPTS 2 + +#define QETH_HARDSETUP_LAPS 5 +#define QETH_HARDSETUP_CLEAR_LAPS 3 +#define QETH_RECOVERY_HARDSETUP_RETRY 2 + +/************************* DEBUG FACILITY STUFF *********************/ + +#define QETH_DBF_HEX(ex,name,level,addr,len) \ + do { \ + if (ex) \ + debug_exception(qeth_dbf_##name,level,(void*)addr,len); \ + else \ + debug_event(qeth_dbf_##name,level,(void*)addr,len); \ + } while (0) +#define QETH_DBF_TEXT(ex,name,level,text) \ + do { \ + if (ex) \ + debug_text_exception(qeth_dbf_##name,level,text); \ + else \ + debug_text_event(qeth_dbf_##name,level,text); \ + } while (0) + +#define QETH_DBF_HEX0(ex,name,addr,len) QETH_DBF_HEX(ex,name,0,addr,len) +#define QETH_DBF_HEX1(ex,name,addr,len) QETH_DBF_HEX(ex,name,1,addr,len) +#define QETH_DBF_HEX2(ex,name,addr,len) QETH_DBF_HEX(ex,name,2,addr,len) +#define QETH_DBF_HEX3(ex,name,addr,len) QETH_DBF_HEX(ex,name,3,addr,len) +#define QETH_DBF_HEX4(ex,name,addr,len) QETH_DBF_HEX(ex,name,4,addr,len) +#define QETH_DBF_HEX5(ex,name,addr,len) QETH_DBF_HEX(ex,name,5,addr,len) +#define QETH_DBF_HEX6(ex,name,addr,len) QETH_DBF_HEX(ex,name,6,addr,len) +#ifdef QETH_DBF_LIKE_HELL +#endif /* QETH_DBF_LIKE_HELL */ + +#define QETH_DBF_TEXT0(ex,name,text) QETH_DBF_TEXT(ex,name,0,text) +#define QETH_DBF_TEXT1(ex,name,text) QETH_DBF_TEXT(ex,name,1,text) +#define QETH_DBF_TEXT2(ex,name,text) QETH_DBF_TEXT(ex,name,2,text) +#define QETH_DBF_TEXT3(ex,name,text) QETH_DBF_TEXT(ex,name,3,text) +#define QETH_DBF_TEXT4(ex,name,text) QETH_DBF_TEXT(ex,name,4,text) +#define QETH_DBF_TEXT5(ex,name,text) QETH_DBF_TEXT(ex,name,5,text) +#define QETH_DBF_TEXT6(ex,name,text) QETH_DBF_TEXT(ex,name,6,text) +#ifdef QETH_DBF_LIKE_HELL +#endif /* QETH_DBF_LIKE_HELL */ + +#define QETH_DBF_SETUP_NAME "qeth_setup" +#define QETH_DBF_SETUP_LEN 8 +#define QETH_DBF_SETUP_INDEX 3 +#define QETH_DBF_SETUP_NR_AREAS 1 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_SETUP_LEVEL 6 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_SETUP_LEVEL 3 +#endif /* QETH_DBF_LIKE_HELL */ + +#define QETH_DBF_MISC_NAME "qeth_misc" +#define QETH_DBF_MISC_LEN 128 +#define QETH_DBF_MISC_INDEX 1 +#define QETH_DBF_MISC_NR_AREAS 1 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_MISC_LEVEL 6 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_MISC_LEVEL 2 +#endif /* QETH_DBF_LIKE_HELL */ + +#define QETH_DBF_DATA_NAME "qeth_data" +#define QETH_DBF_DATA_LEN 96 +#define QETH_DBF_DATA_INDEX 3 +#define QETH_DBF_DATA_NR_AREAS 1 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_DATA_LEVEL 6 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_DATA_LEVEL 2 +#endif /* QETH_DBF_LIKE_HELL */ + +#define QETH_DBF_CONTROL_NAME "qeth_control" +/* buffers are 255 bytes long, but no prob */ +#define QETH_DBF_CONTROL_LEN 256 +#define QETH_DBF_CONTROL_INDEX 3 +#define QETH_DBF_CONTROL_NR_AREAS 2 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_CONTROL_LEVEL 6 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_CONTROL_LEVEL 2 +#endif /* QETH_DBF_LIKE_HELL */ + +#define QETH_DBF_TRACE_NAME "qeth_trace" +#define QETH_DBF_TRACE_LEN 8 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_TRACE_INDEX 3 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_TRACE_INDEX 2 +#endif /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_TRACE_NR_AREAS 2 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_TRACE_LEVEL 6 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_TRACE_LEVEL 2 +#endif /* QETH_DBF_LIKE_HELL */ + +#define QETH_DBF_SENSE_NAME "qeth_sense" +#define QETH_DBF_SENSE_LEN 64 +#define QETH_DBF_SENSE_INDEX 1 +#define QETH_DBF_SENSE_NR_AREAS 1 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_SENSE_LEVEL 6 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_SENSE_LEVEL 2 +#endif /* QETH_DBF_LIKE_HELL */ + + +#define QETH_DBF_QERR_NAME "qeth_qerr" +#define QETH_DBF_QERR_LEN 8 +#define QETH_DBF_QERR_INDEX 1 +#define QETH_DBF_QERR_NR_AREAS 2 +#ifdef QETH_DBF_LIKE_HELL +#define QETH_DBF_QERR_LEVEL 6 +#else /* QETH_DBF_LIKE_HELL */ +#define QETH_DBF_QERR_LEVEL 2 +#endif /* QETH_DBF_LIKE_HELL */ +/****************** END OF DEBUG FACILITY STUFF *********************/ + +/********************* CARD DATA STUFF **************************/ + +#define QETH_MAX_PARAMS 150 + +#define QETH_CARD_TYPE_UNKNOWN 0 +#define QETH_CARD_TYPE_OSAE 10 +#define QETH_CARD_TYPE_IQD 1234 + +#define QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT 0x0101 +#define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x0101 +/* as soon as steve is ready: +#define QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT 0x4101 +#define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x5101 +*/ +#define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108 +#define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 + +#define QETH_MAX_QUEUES 4 + +#define UNIQUE_ID_IF_CREATE_ADDR_FAILED 0xfffe +#define UNIQUE_ID_NOT_BY_CARD 0x10000 + +/* CU type & model, Dev type & model, card_type, odd_even_restriction, func level, no of queues, multicast is different (multicast-queue_no + 0x100) */ +#define QETH_MODELLIST_ARRAY \ + {{0x1731,0x01,0x1732,0x01,QETH_CARD_TYPE_OSAE,1, \ + QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \ + QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \ + QETH_MAX_QUEUES,0}, \ + {0x1731,0x05,0x1732,0x05,QETH_CARD_TYPE_IQD,0, \ + QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \ + QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \ + QETH_MAX_QUEUES,0x103}, \ + {0,0,0,0,0,0,0,0,0}} + +#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18 + /* only the first two bytes are looked at in qeth_get_cardname_short */ +#define QETH_MPC_LINK_TYPE_FAST_ETHERNET 0x01 +#define QETH_MPC_LINK_TYPE_HSTR 0x02 +#define QETH_MPC_LINK_TYPE_GIGABIT_ETHERNET 0x03 +#define QETH_MPC_LINK_TYPE_LANE_ETH100 0x81 +#define QETH_MPC_LINK_TYPE_LANE_TR 0x82 +#define QETH_MPC_LINK_TYPE_LANE_ETH1000 0x83 +#define QETH_MPC_LINK_TYPE_LANE 0x88 + +#define DEFAULT_ADD_HHLEN 0 +#define MAX_ADD_HHLEN 1024 + +#define QETH_HEADER_SIZE 32 +#define QETH_IP_HEADER_SIZE 40 +#define QETH_HEADER_LEN_POS 8 +/* flags for the header: */ +#define QETH_HEADER_PASSTHRU 0x10 +#define QETH_HEADER_IPV6 0x80 + +#define QETH_CAST_FLAGS 0x07 +#define QETH_CAST_UNICAST 6 +#define QETH_CAST_MULTICAST 4 +#define QETH_CAST_BROADCAST 5 +#define QETH_CAST_ANYCAST 7 +#define QETH_CAST_NOCAST 0 + +/* VLAN defines */ +#define QETH_EXT_HEADER_VLAN_FRAME 0x01 +#define QETH_EXT_HEADER_TOKEN_ID 0x02 +#define QETH_EXT_HEADER_INCLUDE_VLAN_TAG 0x04 + +#define QETH_EXT_HEADER_SRC_MAC_ADDRESS 0x08 +#define QETH_EXT_HEADER_CSUM_HDR_REQ 0x10 +#define QETH_EXT_HEADER_CSUM_TRANSP_REQ 0x20 +#define QETH_EXT_HEADER_CSUM_TRANSP_FRAME_TYPE 0x40 + +#define QETH_UDP_CSUM_OFFSET 6 +#define QETH_TCP_CSUM_OFFSET 16 + +#define QETH_VERIFY_IS_REAL_DEV 1 +#define QETH_VERIFY_IS_VLAN_DEV 2 + +inline static unsigned int qeth_get_ipa_timeout(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_IQD: return 2000; + default: return 20000; + } +} + +inline static unsigned short qeth_get_additional_dev_flags(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_IQD: return IFF_NOARP; +#ifdef QETH_IPV6 + default: return 0; +#else /* QETH_IPV6 */ + default: return IFF_NOARP; +#endif /* QETH_IPV6 */ + } +} + +inline static int qeth_get_hlen(__u8 link_type) +{ +#ifdef QETH_IPV6 + switch (link_type) { + case QETH_MPC_LINK_TYPE_HSTR: + case QETH_MPC_LINK_TYPE_LANE_TR: + return QETH_HEADER_SIZE+TR_HLEN; + default: +#ifdef QETH_VLAN + return QETH_HEADER_SIZE+VLAN_ETH_HLEN; +#else + return QETH_HEADER_SIZE+ETH_HLEN; +#endif + } +#else /* QETH_IPV6 */ +#ifdef QETH_VLAN + return QETH_HEADER_SIZE+VLAN_HLEN; +#else + return QETH_HEADER_SIZE; +#endif + +#endif /* QETH_IPV6 */ +} + +int (*qeth_my_eth_header)(struct sk_buff *,struct net_device *, + unsigned short,void *,void *,unsigned); +int (*qeth_my_tr_header)(struct sk_buff *,struct net_device *, + unsigned short,void *,void *,unsigned); +int (*qeth_my_eth_rebuild_header)(struct sk_buff *); +int (*qeth_my_tr_rebuild_header)(struct sk_buff *); +int (*qeth_my_eth_header_cache)(struct neighbour *,struct hh_cache *); +void (*qeth_my_eth_header_cache_update)(struct hh_cache *,struct net_device *, + unsigned char *); + +#ifdef QETH_IPV6 +typedef int (*__qeth_temp1)(struct sk_buff *,struct net_device *, + unsigned short,void *,void *,unsigned); +inline static __qeth_temp1 qeth_get_hard_header(__u8 link_type) +{ + switch (link_type) { +#ifdef CONFIG_TR + case QETH_MPC_LINK_TYPE_HSTR: + case QETH_MPC_LINK_TYPE_LANE_TR: + return qeth_my_tr_header; +#endif /* CONFIG_TR */ + default: + return qeth_my_eth_header; + } +} + +typedef int (*__qeth_temp2)(struct sk_buff *); +inline static __qeth_temp2 qeth_get_rebuild_header(__u8 link_type) +{ + switch (link_type) { +#ifdef CONFIG_TR + case QETH_MPC_LINK_TYPE_HSTR: + case QETH_MPC_LINK_TYPE_LANE_TR: + return qeth_my_tr_rebuild_header; +#endif /* CONFIG_TR */ + default: + return qeth_my_eth_rebuild_header; + } +} + +typedef int (*__qeth_temp3)(struct neighbour *,struct hh_cache *); +inline static __qeth_temp3 qeth_get_hard_header_cache(__u8 link_type) +{ + switch (link_type) { + case QETH_MPC_LINK_TYPE_HSTR: + case QETH_MPC_LINK_TYPE_LANE_TR: + return NULL; + default: + return qeth_my_eth_header_cache; + } +} + +typedef void (*__qeth_temp4)(struct hh_cache *,struct net_device *, + unsigned char *); +inline static __qeth_temp4 qeth_get_header_cache_update(__u8 link_type) +{ + switch (link_type) { + case QETH_MPC_LINK_TYPE_HSTR: + case QETH_MPC_LINK_TYPE_LANE_TR: + return NULL; + default: + return qeth_my_eth_header_cache_update; + } +} + +static unsigned short qeth_eth_type_trans(struct sk_buff *skb, + struct net_device *dev) +{ + struct ethhdr *eth; + + skb->mac.raw=skb->data; + skb_pull(skb,ETH_ALEN*2+sizeof(short)); + 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 { + skb->pkt_type=PACKET_OTHERHOST; + } + if (ntohs(eth->h_proto)>=1536) return eth->h_proto; + if (*(unsigned short *)(skb->data) == 0xFFFF) + return htons(ETH_P_802_3); + return htons(ETH_P_802_2); +} + +typedef unsigned short (*__qeth_temp5)(struct sk_buff *,struct net_device *); +inline static __qeth_temp5 qeth_get_type_trans(__u8 link_type) +{ + switch (link_type) { + case QETH_MPC_LINK_TYPE_HSTR: + case QETH_MPC_LINK_TYPE_LANE_TR: + return tr_type_trans; + default: + return qeth_eth_type_trans; + } +} +#endif /* QETH_IPV6 */ + +inline static const char *qeth_get_link_type_name(int cardtype,__u8 linktype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return "unknown"; + case QETH_CARD_TYPE_OSAE: + switch (linktype) { + case QETH_MPC_LINK_TYPE_FAST_ETHERNET: return "Fast Eth"; + case QETH_MPC_LINK_TYPE_HSTR: return "HSTR"; + case QETH_MPC_LINK_TYPE_GIGABIT_ETHERNET: return "Gigabit Eth"; + case QETH_MPC_LINK_TYPE_LANE_ETH100: return "LANE Eth100"; + case QETH_MPC_LINK_TYPE_LANE_TR: return "LANE TR"; + case QETH_MPC_LINK_TYPE_LANE_ETH1000: return "LANE Eth1000"; + default: return "unknown"; + } + case QETH_CARD_TYPE_IQD: return "magic"; + default: return "unknown"; + } +} + +inline static const char* qeth_get_dev_basename(int cardtype,__u8 link_type) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return "eth"; + case QETH_CARD_TYPE_OSAE: switch (link_type) { + case QETH_MPC_LINK_TYPE_LANE_TR: + /* fallthrough */ + case QETH_MPC_LINK_TYPE_HSTR: return "tr"; + default: return "eth"; + } + case QETH_CARD_TYPE_IQD: return "hsi"; + default: return "eth"; + } +} + +/* inbound: */ +#define DEFAULT_BUFFER_SIZE 65536 +#define DEFAULT_BUFFER_COUNT 128 +#define BUFCNT_MIN 8 +#define BUFCNT_MAX 128 +#define BUFFER_SIZE (card->inbound_buffer_size) +#define BUFFER_MAX_ELEMENTS (BUFFER_SIZE>>12) + /* 8k for each pair header-buffer: */ + +inline static int qeth_sbal_packing_on_card(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_IQD: return 0; + default: return 1; + } +} + +/* do it this way round -> __MODULE_STRING needs with */ +/* QETH_PRIO_NICE_LEVELS a single number */ +#define QETH_MAX_PRIO_QUEUES QETH_PRIO_NICE_LEVELS+1 + +static inline int qeth_sbalf15_in_retrieable_range(int sbalf15) +{ + return ( (sbalf15>=15) && (sbalf15<=31) ); +} + +#define INBOUND_BUFFER_POS(card,bufno,sbale) \ + ( (bufno&SPAREBUF_MASK)? \ + ( \ + (sparebufs[bufno&(~SPAREBUF_MASK)].buf+ \ + PAGE_SIZE*sbale) \ + ):( \ + (card->inbound_buffer_pool_entry[card-> \ + inbound_buffer_entry_no[bufno]][sbale]) \ + ) ) + +#define SPAREBUF_UNAVAIL 0 +#define SPAREBUF_FREE 1 +#define SPAREBUF_USED 2 + +typedef struct sparebufs_t { + char *buf; + atomic_t status; +} sparebufs_t; + +#define SEND_STATE_INACTIVE 0 +#define SEND_STATE_DONT_PACK 1 +#define SEND_STATE_PACK 2 + +#define QETH_LOCK_UNLOCKED 0 +#define QETH_LOCK_NORMAL 1 +#define QETH_LOCK_FLUSH 2 + +#define QETH_MAX_DEVICES 16 + /* DEPENDENCY ON QETH_MAX_DEVICES. + *__MOUDLE_STRING expects simple literals */ +#define QETH_MAX_DEVICES_TIMES_4 64 +#define QETH_MAX_DEVNAMES 16 +#define QETH_DEVNAME "eth" + +#define QETH_TX_TIMEOUT 100*HZ /* 100 seconds */ + +#define QETH_REMOVE_WAIT_TIME 200 +#define QETH_WAIT_FOR_THREAD_TIME 20 +#define QETH_IDLE_WAIT_TIME 10 +#define QETH_WAIT_BEFORE_2ND_DOIO 1000 + +#define QETH_MAX_PARM_LEN 128 + +#define QETH_FAKE_LL_LEN ETH_HLEN /* 14 */ +#define QETH_FAKE_LL_PROT_LEN 2 +#define QETH_FAKE_LL_ADDR_LEN ETH_ALEN /* 6 */ +#define QETH_FAKE_LL_DEST_MAC_POS 0 +#define QETH_FAKE_LL_SRC_MAC_POS 6 +#define QETH_FAKE_LL_SRC_MAC_POS_IN_QDIO_HDR 6 +#define QETH_FAKE_LL_PROT_POS 12 +#define QETH_FAKE_LL_V4_ADDR_POS 16 +#define QETH_FAKE_LL_V6_ADDR_POS 24 + +#define DEV_NAME_LEN 16 +#define IOCTL_MAX_TRANSFER_SIZE 65535 + +#define IP_TOS_LOWDELAY 0x10 +#define IP_TOS_HIGHTHROUGHPUT 0x08 +#define IP_TOS_HIGHRELIABILITY 0x04 +#define IP_TOS_NOTIMPORTANT 0x02 + +#define QETH_RCD_LENGTH 128 + +#define __max(a,b) ( ((a)>(b))?(a):(b) ) +#define __min(a,b) ( ((a)<(b))?(a):(b) ) +#define QETH_BUFSIZE __max(__max(IPA_PDU_HEADER_SIZE+ \ + sizeof(arp_cmd_t),IPA_PDU_HEADER_SIZE+ \ + sizeof(ipa_cmd_t)),QETH_RCD_LENGTH) + +#define QETH_FINAL_STATUS_TIMEOUT 1500 +#define QETH_CLEAR_TIMEOUT 1500 +#define QETH_RCD_TIMEOUT 1500 +#define QETH_NOP_TIMEOUT 1500 +#define QETH_QUIESCE_NETDEV_TIME 300 +#define QETH_QUIESCE_WAIT_BEFORE_CLEAR 4000 +#define QETH_QUIESCE_WAIT_AFTER_CLEAR 4000 + +#define NOP_STATE 0x1001 +#define READ_CONF_DATA_STATE 0x1002 +#define IDX_ACTIVATE_READ_STATE 0x1003 +#define IDX_ACTIVATE_WRITE_STATE 0x1004 +#define MPC_SETUP_STATE 0x1005 +#define CLEAR_STATE 0x1006 +#define IPA_CMD_STATE 0x1007 +#define IPA_IOCTL_STATE 0x1009 +#define IPA_SETIP_FLAG 0x100000 + +#define QETH_REMOVE_CARD_PROPER 1 +#define QETH_REMOVE_CARD_QUICK 2 + +#define PARSE_AUTO 0 +#define PARSE_ROUTING_TYPE 1 +#define PARSE_CHECKSUMMING 2 +#define PARSE_PRIO_QUEUEING 3 +#define PARSE_STAYINMEM 4 +#define PARSE_BUFFERCOUNT 5 +#define PARSE_PORTNAME 6 +#define PARSE_POLLTIME 7 +#define PARSE_SPARE_BUFFERCOUNT 8 +#define PARSE_PORTNO 9 +#define PARSE_BROADCAST_MODE 10 +#define PARSE_MACADDR_MODE 11 +#define PARSE_MEMUSAGE 12 +#define PARSE_ENA_IPAT 13 +#define PARSE_FAKE_BROADCAST 14 +#define PARSE_ADD_HHLEN 15 +#define PARSE_ROUTING_TYPE4 16 +#define PARSE_ROUTING_TYPE6 17 +#define PARSE_FAKE_LL 18 +#define PARSE_ASYNC_IQD 19 + +#define PARSE_COUNT 20 + +#define NO_PRIO_QUEUEING 0 +#define PRIO_QUEUEING_PREC 1 +#define PRIO_QUEUEING_TOS 2 +#define NO_ROUTER 0 +#define PRIMARY_ROUTER 1 +#define SECONDARY_ROUTER 2 +#define MULTICAST_ROUTER 3 +#define PRIMARY_CONNECTOR 4 +#define SECONDARY_CONNECTOR 5 +#define ROUTER_MASK 0xf /* used to remove SET_ROUTING_FLAG + from routing_type */ +#define RESET_ROUTING_FLAG 0x10 /* used to indicate, that setting + the routing type is desired */ +#define BROADCAST_ALLRINGS 0 +#define BROADCAST_LOCAL 1 +#define MACADDR_NONCANONICAL 0 +#define MACADDR_CANONICAL 1 +#define MEMUSAGE_DISCONTIG 0 +#define MEMUSAGE_CONTIG 1 +#define ENABLE_TAKEOVER 0 +#define DISABLE_TAKEOVER 1 +#define FAKE_BROADCAST 0 +#define DONT_FAKE_BROADCAST 1 +#define FAKE_LL 0 +#define DONT_FAKE_LL 1 +#define SYNC_IQD 0 +#define ASYNC_IQD 1 + +#define QETH_BREAKOUT_LEAVE 1 +#define QETH_BREAKOUT_AGAIN 2 + +#define QETH_WAIT_FOR_LOCK 0 +#define QETH_DONT_WAIT_FOR_LOCK 1 +#define QETH_LOCK_ALREADY_HELD 2 + +#define PROBLEM_CARD_HAS_STARTLANED 1 +#define PROBLEM_RECEIVED_IDX_TERMINATE 2 +#define PROBLEM_ACTIVATE_CHECK_CONDITION 3 +#define PROBLEM_RESETTING_EVENT_INDICATOR 4 +#define PROBLEM_COMMAND_REJECT 5 +#define PROBLEM_ZERO_SENSE_DATA 6 +#define PROBLEM_GENERAL_CHECK 7 +#define PROBLEM_BAD_SIGA_RESULT 8 +#define PROBLEM_USER_TRIGGERED_RECOVERY 9 +#define PROBLEM_AFFE 10 +#define PROBLEM_MACHINE_CHECK 11 +#define PROBLEM_TX_TIMEOUT 12 + +#define SENSE_COMMAND_REJECT_BYTE 0 +#define SENSE_COMMAND_REJECT_FLAG 0x80 +#define SENSE_RESETTING_EVENT_BYTE 1 +#define SENSE_RESETTING_EVENT_FLAG 0x80 + +#define DEFAULT_RCD_CMD 0x72 +#define DEFAULT_RCD_COUNT 0x80 + +#define BUFFER_USED 1 +#define BUFFER_UNUSED -1 + +/*typedef struct wait_queue* wait_queue_head_t; already typedefed in qdio.h */ + +typedef int (*reg_notifier_t)(struct notifier_block*); + +typedef struct ipato_entry_t { + int version; + __u8 addr[16]; + int mask_bits; + char dev_name[DEV_NAME_LEN]; + struct ipato_entry_t *next; +} ipato_entry_t; + +typedef struct qeth_vipa_entry_t { + int version; + __u8 ip[16]; + int flag; + volatile int state; + struct qeth_vipa_entry_t *next; +} qeth_vipa_entry_t; + +typedef struct ip_state_t { + struct in_ifaddr *ip_ifa; /* pointer to IPv4 adresses */ + struct inet6_ifaddr *ip6_ifa; +} ip_state_t; + +struct qeth_ipm_mac { + __u8 mac[ETH_ALEN]; + __u8 ip[16]; + struct qeth_ipm_mac *next; +}; + +typedef struct ip_mc_state_t { + struct qeth_ipm_mac *ipm_ifa; + struct qeth_ipm_mac *ipm6_ifa; +} ip_mc_state_t; + +struct qeth_card_options { + char devname[DEV_NAME_LEN]; + volatile int routing_type4; +#ifdef QETH_IPV6 + volatile int routing_type6; +#endif /* QETH_IPV6 */ + int checksum_type; + int do_prio_queueing; + int default_queue; + int already_parsed[PARSE_COUNT]; + int inbound_buffer_count; + __s32 memory_usage_in_k; + int polltime; + char portname[9]; + int portno; + int memusage; + int broadcast_mode; + int macaddr_mode; + int ena_ipat; + int fake_broadcast; + int add_hhlen; + int fake_ll; + int async_iqd; +}; + +typedef struct qeth_hdr_t { + __u8 id; + __u8 flags; + __u16 inbound_checksum; + __u32 token; + __u16 length; + __u8 vlan_prio; + __u8 ext_flags; + __u16 vlan_id; + __u16 frame_offset; + __u8 dest_addr[16]; +} qeth_hdr_t; + +typedef struct qeth_ringbuffer_element_t { + struct sk_buff_head skb_list; + int next_element_to_fill; +} __attribute__ ((packed)) qeth_ringbuffer_element_t; + +typedef struct qeth_ringbuffer_t { + qdio_buffer_t buffer[QDIO_MAX_BUFFERS_PER_Q]; + qeth_ringbuffer_element_t ringbuf_element[QDIO_MAX_BUFFERS_PER_Q]; +} qeth_ringbuffer_t __attribute__ ((packed,aligned(PAGE_SIZE))); + +typedef struct qeth_dma_stuff_t { + unsigned char *sendbuf; + unsigned char *recbuf; + ccw1_t read_ccw; + ccw1_t write_ccw; +} qeth_dma_stuff_t __attribute__ ((packed,aligned(PAGE_SIZE))); + +typedef struct qeth_perf_stats_t { + unsigned int skbs_rec; + unsigned int bufs_rec; + + unsigned int skbs_sent; + unsigned int bufs_sent; + + unsigned int skbs_sent_dont_pack; + unsigned int bufs_sent_dont_pack; + unsigned int skbs_sent_pack; + unsigned int bufs_sent_pack; + unsigned int skbs_sent_pack_better; + unsigned int bufs_sent_pack_better; + + unsigned int sc_dp_p; + unsigned int sc_p_dp; + + __u64 inbound_start_time; + unsigned int inbound_cnt; + unsigned int inbound_time; + __u64 outbound_start_time; + unsigned int outbound_cnt; + unsigned int outbound_time; +} qeth_perf_stats_t; + +/* ugly. I know. */ +typedef struct qeth_card_t { /* pointed to by dev->priv */ + int easy_copy_cap; + + /* pointer to options (defaults + parameters) */ + struct qeth_card_options options; + + atomic_t is_startlaned; /* card did not get a stoplan */ + /* also 0 when card is gone after a + machine check */ + + __u8 link_type; + + int do_pfix; /* to avoid doing diag98 for vm guest lan devices */ + + /* inbound buffer management */ + atomic_t inbound_buffer_refcnt[QDIO_MAX_BUFFERS_PER_Q]; + qdio_buffer_t inbound_qdio_buffers[QDIO_MAX_BUFFERS_PER_Q]; + void *real_inb_buffer_addr[QDIO_MAX_BUFFERS_PER_Q] + [QDIO_MAX_ELEMENTS_PER_BUFFER]; + + /* inbound data area */ + void *inbound_buffer_pool_entry[QDIO_MAX_BUFFERS_PER_Q] + [QDIO_MAX_ELEMENTS_PER_BUFFER]; + volatile int inbound_buffer_pool_entry_used[QDIO_MAX_BUFFERS_PER_Q]; + int inbound_buffer_entry_no[QDIO_MAX_BUFFERS_PER_Q]; + + /* for requeueing of buffers */ + spinlock_t requeue_input_lock; + atomic_t requeue_position; + atomic_t requeue_counter; + + /* outbound QDIO stuff */ + volatile int send_state[QETH_MAX_QUEUES]; + volatile int outbound_first_free_buffer[QETH_MAX_QUEUES]; + atomic_t outbound_used_buffers[QETH_MAX_QUEUES]; + int outbound_buffer_send_state[QETH_MAX_QUEUES] + [QDIO_MAX_BUFFERS_PER_Q]; + int send_retries[QETH_MAX_QUEUES][QDIO_MAX_BUFFERS_PER_Q]; + volatile int outbound_bytes_in_buffer[QETH_MAX_QUEUES]; + qeth_ringbuffer_t *outbound_ringbuffer[QETH_MAX_QUEUES]; + atomic_t outbound_ringbuffer_lock[QETH_MAX_QUEUES]; + atomic_t last_pci_pos[QETH_MAX_QUEUES]; + +#ifdef QETH_IPV6 + int (*hard_header)(struct sk_buff *,struct net_device *, + unsigned short,void *,void *,unsigned); + int (*rebuild_header)(struct sk_buff *); + int (*hard_header_cache)(struct neighbour *,struct hh_cache *); + void (*header_cache_update)(struct hh_cache *,struct net_device *, + unsigned char *); + unsigned short (*type_trans)(struct sk_buff *,struct net_device *); + int type_trans_correction; +#endif /* QETH_IPV6 */ + +#ifdef QETH_VLAN + struct vlan_group *vlangrp; + spinlock_t vlan_lock; + +#endif + char dev_name[DEV_NAME_LEN]; /* pointed to by dev->name */ + char dev_basename[DEV_NAME_LEN]; + struct net_device *dev; + struct net_device_stats *stats; + + int no_queues; + +#ifdef QETH_PERFORMANCE_STATS + qeth_perf_stats_t perf_stats; +#endif /* QETH_PERFORMANCE_STATS */ + + /* our state */ + atomic_t is_registered; /* card registered as netdev? */ + atomic_t is_hardsetup; /* card has gone through hardsetup */ + atomic_t is_softsetup; /* card is setup by softsetup */ + atomic_t is_open; /* card is in use */ + atomic_t is_gone; /* after a msck */ + + int has_irq; /* once a request_irq was successful */ + + /* prevents deadlocks :-O */ + spinlock_t softsetup_lock; + spinlock_t hardsetup_lock; + spinlock_t ioctl_lock; + atomic_t softsetup_thread_is_running; + struct semaphore softsetup_thread_sem; + struct tq_struct tqueue_sst; + + atomic_t escape_softsetup; /* active, when recovery has to + wait for softsetup */ + struct semaphore reinit_thread_sem; + atomic_t in_recovery; + atomic_t reinit_counter; + + /* problem management */ + atomic_t break_out; + atomic_t problem; + struct tq_struct tqueue; + + struct { + __u32 trans_hdr; + __u32 pdu_hdr; + __u32 pdu_hdr_ack; + __u32 ipa; + } seqno; + + struct { + __u32 issuer_rm_w; + __u32 issuer_rm_r; + __u32 cm_filter_w; + __u32 cm_filter_r; + __u32 cm_connection_w; + __u32 cm_connection_r; + __u32 ulp_filter_w; + __u32 ulp_filter_r; + __u32 ulp_connection_w; + __u32 ulp_connection_r; + } token; + + /* this is card-related */ + int type; + __u16 func_level; + int initial_mtu; + int max_mtu; + int inbound_buffer_size; + + int is_multicast_different; /* if multicast traffic is to be sent + on a different queue, this is the + queue+no_queues */ + int can_do_async_iqd; /* 1 only on IQD that provides async + unicast sigas */ + + __u32 ipa_supported; + __u32 ipa_enabled; + __u32 ipa6_supported; + __u32 ipa6_enabled; + __u32 adp_supported; + + atomic_t startlan_attempts; + atomic_t enable_routing_attempts4; + atomic_t rt4fld; +#ifdef QETH_IPV6 + atomic_t enable_routing_attempts6; + atomic_t rt6fld; +#endif /* QETH_IPV6 */ + int unique_id; + + /* device and I/O data */ + int devno0; + int devno1; + int devno2; + int irq0; + int irq1; + int irq2; + unsigned short unit_addr2; + unsigned short cula; + unsigned short dev_type; + unsigned char dev_model; + unsigned short chpid; + devstat_t *devstat0; + devstat_t *devstat1; + devstat_t *devstat2; + + unsigned char ipa_buf[QETH_BUFSIZE]; + unsigned char send_buf[QETH_BUFSIZE]; + +/* IOCTL Stuff */ + unsigned char *ioctl_data_buffer; + unsigned char *ioctl_buffer_pointer; + int ioctl_returncode; + int ioctl_buffersize; + int number_of_entries; + + + atomic_t ioctl_data_has_arrived; + wait_queue_head_t ioctl_wait_q; + atomic_t ioctl_wait_q_active; + spinlock_t ioctl_wait_q_lock; + +/* stuff under 2 gb */ + qeth_dma_stuff_t *dma_stuff; + + unsigned int ipa_timeout; + + atomic_t write_busy; + + int read_state; /* only modified and read in the int handler */ + + /* vipa stuff */ + rwlock_t vipa_list_lock; + qeth_vipa_entry_t *vipa_list; + + /* state information when doing I/O */ + atomic_t shutdown_phase; + volatile int save_state_flag; + atomic_t data_has_arrived; + wait_queue_head_t wait_q; + atomic_t wait_q_active; + spinlock_t wait_q_lock; /* for wait_q_active and wait_q */ + + atomic_t final_status0; + atomic_t final_status1; + atomic_t final_status2; + atomic_t clear_succeeded0; + atomic_t clear_succeeded1; + atomic_t clear_succeeded2; + + /* bookkeeping of IP and multicast addresses */ + ip_state_t ip_current_state; + ip_state_t ip_new_state; + +#ifdef CONFIG_IP_MULTICAST + ip_mc_state_t ip_mc_current_state; + ip_mc_state_t ip_mc_new_state; +#endif /* CONFIG_IF_MULTICAST */ + + int broadcast_capable; + int portname_required; + + int realloc_message; + + char level[QETH_MCL_LENGTH+1]; + + volatile int saved_dev_flags; + + /* for our linked list */ + struct qeth_card_t *next; +} qeth_card_t; + +typedef struct mydevreg_t { + devreg_t devreg; + struct mydevreg_t *next; + struct mydevreg_t *prev; +} mydevreg_t; + +inline static int qeth_get_arphrd_type(int cardtype,int linktype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_OSAE: switch (linktype) { + case QETH_MPC_LINK_TYPE_LANE_TR: + /* fallthrough */ + case QETH_MPC_LINK_TYPE_HSTR: + return ARPHRD_IEEE802; + default: return ARPHRD_ETHER; + } + case QETH_CARD_TYPE_IQD: return ARPHRD_ETHER; + default: return ARPHRD_ETHER; + } +} + +inline static int qeth_determine_easy_copy_cap(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return 0; /* better be cautious */ + case QETH_CARD_TYPE_OSAE: return 1; + case QETH_CARD_TYPE_IQD: return 0; + default: return 0; /* ?? */ + } +} +inline static __u8 qeth_get_adapter_type_for_ipa(int link_type) +{ + switch (link_type) { + case QETH_MPC_LINK_TYPE_HSTR: return 2; + default: return 1; + } +} + +inline static const char *qeth_get_cardname(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return "n unknown"; + case QETH_CARD_TYPE_OSAE: return "n OSD Express"; + case QETH_CARD_TYPE_IQD: return " HiperSockets"; + default: return " strange"; + } +} + +/* max length to be returned: 14 */ +inline static const char *qeth_get_cardname_short(int cardtype,__u8 link_type) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return "unknown"; + case QETH_CARD_TYPE_OSAE: switch (link_type) { + case QETH_MPC_LINK_TYPE_FAST_ETHERNET: + return "OSD_100"; + case QETH_MPC_LINK_TYPE_HSTR: + return "HSTR"; + case QETH_MPC_LINK_TYPE_GIGABIT_ETHERNET: + return "OSD_1000"; + case QETH_MPC_LINK_TYPE_LANE_ETH100: + return "OSD_FE_LANE"; + case QETH_MPC_LINK_TYPE_LANE_TR: + return "OSD_TR_LANE"; + case QETH_MPC_LINK_TYPE_LANE_ETH1000: + return "OSD_GbE_LANE"; + case QETH_MPC_LINK_TYPE_LANE: + return "OSD_ATM_LANE"; + default: return "OSD_Express"; + } + case QETH_CARD_TYPE_IQD: return "HiperSockets"; + default: return " strange"; + } +} + +inline static int qeth_mtu_is_valid(qeth_card_t *card,int mtu) +{ + switch (card->type) { + case QETH_CARD_TYPE_UNKNOWN: return 1; + case QETH_CARD_TYPE_OSAE: return ( (mtu>=576) && (mtu<=61440) ); + case QETH_CARD_TYPE_IQD: return ( (mtu>=576) && + (mtu<=card->max_mtu+4096-32) ); + default: return 1; + } +} + +inline static int qeth_get_initial_mtu_for_card(qeth_card_t *card) +{ + switch (card->type) { + case QETH_CARD_TYPE_UNKNOWN: return 1500; + case QETH_CARD_TYPE_IQD: return card->max_mtu; + case QETH_CARD_TYPE_OSAE: + switch (card->link_type) { + case QETH_MPC_LINK_TYPE_HSTR: + case QETH_MPC_LINK_TYPE_LANE_TR: + return 2000; + default: + return 1492; + } + default: return 1500; + } +} + +inline static int qeth_get_max_mtu_for_card(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return 61440; + case QETH_CARD_TYPE_OSAE: return 61440; + case QETH_CARD_TYPE_IQD: return 57344; + default: return 1500; + } +} + +inline static int qeth_get_mtu_out_of_mpc(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_IQD: return 1; + default: return 0; + } +} + +inline static int qeth_get_mtu_outof_framesize(int framesize) +{ + switch (framesize) { + case 0x4000: return 8192; + case 0x6000: return 16384; + case 0xa000: return 32768; + case 0xffff: return 57344; + default: return 0; + } +} + +inline static int qeth_get_buffersize_for_card(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return 65536; + case QETH_CARD_TYPE_OSAE: return 65536; + case QETH_CARD_TYPE_IQD: return 16384; + default: return 65536; + } +} + +inline static int qeth_get_min_number_of_buffers(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_UNKNOWN: return 32; + case QETH_CARD_TYPE_OSAE: return 32; + case QETH_CARD_TYPE_IQD: return 64; + default: return 64; + } +} + +inline static int qeth_get_q_format(int cardtype) +{ + switch (cardtype) { + case QETH_CARD_TYPE_IQD: return 2; + default: return 0; + } +} + +inline static int qeth_get_device_tx_q_len(int cardtype) +{ + return 100; +} + +inline static int qeth_get_max_number_of_buffers(int cardtype) +{ + return 127; +} + +/******************** OUTPUT FACILITIES **************************/ + +#ifdef PRINT_INFO +#undef PRINTK_HEADER +#undef PRINT_STUPID +#undef PRINT_ALL +#undef PRINT_INFO +#undef PRINT_WARN +#undef PRINT_ERR +#undef PRINT_CRIT +#undef PRINT_ALERT +#undef PRINT_EMERG +#endif /* PRINT_INFO */ + +#define PRINTK_HEADER QETH_NAME ": " + +#if QETH_VERBOSE_LEVEL>8 +#define PRINT_STUPID(x...) printk( KERN_DEBUG PRINTK_HEADER x) +#else +#define PRINT_STUPID(x...) +#endif + +#if QETH_VERBOSE_LEVEL>7 +#define PRINT_ALL(x...) printk( KERN_DEBUG PRINTK_HEADER x) +#else +#define PRINT_ALL(x...) +#endif + +#if QETH_VERBOSE_LEVEL>6 +#define PRINT_INFO(x...) printk( KERN_INFO PRINTK_HEADER x) +#else +#define PRINT_INFO(x...) +#endif + +#if QETH_VERBOSE_LEVEL>5 +#define PRINT_WARN(x...) printk( KERN_WARNING PRINTK_HEADER x) +#else +#define PRINT_WARN(x...) +#endif + +#if QETH_VERBOSE_LEVEL>4 +#define PRINT_ERR(x...) printk( KERN_ERR PRINTK_HEADER x) +#else +#define PRINT_ERR(x...) +#endif + +#if QETH_VERBOSE_LEVEL>3 +#define PRINT_CRIT(x...) printk( KERN_CRIT PRINTK_HEADER x) +#else +#define PRINT_CRIT(x...) +#endif + +#if QETH_VERBOSE_LEVEL>2 +#define PRINT_ALERT(x...) printk( KERN_ALERT PRINTK_HEADER x) +#else +#define PRINT_ALERT(x...) +#endif + +#if QETH_VERBOSE_LEVEL>1 +#define PRINT_EMERG(x...) printk( KERN_EMERG PRINTK_HEADER x) +#else +#define PRINT_EMERG(x...) +#endif + +#endif /* __QETH_H__ */ diff -urN linux-2.4.21/drivers/s390/net/qeth_mpc.h linux-2.4.22/drivers/s390/net/qeth_mpc.h --- linux-2.4.21/drivers/s390/net/qeth_mpc.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/s390/net/qeth_mpc.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,611 @@ +/* + * linux/drivers/s390/net/qeth_mpc.h + * + * Linux on zSeries OSA Express and HiperSockets support + * + * Copyright 2000,2003 IBM Corporation + * Author(s): Utz Bacher + * + */ + +#ifndef __QETH_MPC_H__ +#define __QETH_MPC_H__ + +#define VERSION_QETH_MPC_H "$Revision: 1.42 $" + +#define QETH_IPA_TIMEOUT (card->ipa_timeout) +#define QETH_MPC_TIMEOUT 2000 +#define QETH_ADDR_TIMEOUT 1000 + +#define QETH_SETIP_RETRIES 2 + +#define IDX_ACTIVATE_SIZE 0x22 +#define CM_ENABLE_SIZE 0x63 +#define CM_SETUP_SIZE 0x64 +#define ULP_ENABLE_SIZE 0x6b +#define ULP_SETUP_SIZE 0x6c +#define DM_ACT_SIZE 0x55 + +#define QETH_MPC_TOKEN_LENGTH 4 +#define QETH_SEQ_NO_LENGTH 4 +#define QETH_IPA_SEQ_NO_LENGTH 2 + +#define QETH_TRANSPORT_HEADER_SEQ_NO(buffer) (buffer+4) +#define QETH_PDU_HEADER_SEQ_NO(buffer) (buffer+0x1c) +#define QETH_PDU_HEADER_ACK_SEQ_NO(buffer) (buffer+0x20) + +static unsigned char IDX_ACTIVATE_READ[]={ + 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00, + + 0x19,0x01,0x01,0x80, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0xc8,0xc1, + 0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00, + 0x00,0x00 +}; + +static unsigned char IDX_ACTIVATE_WRITE[]={ + 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00, + + 0x15,0x01,0x01,0x80, 0x00,0x00,0x00,0x00, + 0xff,0xff,0x00,0x00, 0x00,0x00,0xc8,0xc1, + 0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00, + 0x00,0x00 +}; + +#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c) +#define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80) +#define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10) +#define QETH_IDX_ACT_DATASET_NAME(buffer) (buffer+0x16) +#define QETH_IDX_ACT_QDIO_DEV_CUA(buffer) (buffer+0x1e) +#define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer+0x20) + +#define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08]&3)==2) + +#define QETH_IDX_REPLY_LEVEL(buffer) (buffer+0x12) +#define QETH_MCL_LENGTH 4 + +static unsigned char CM_ENABLE[]={ + 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x01, + 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x63, + 0x10,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00, + 0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x23, + 0x00,0x00,0x23,0x05, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + + 0x01,0x00,0x00,0x23, 0x00,0x00,0x00,0x40, + + 0x00,0x0c,0x41,0x02, 0x00,0x17,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x0b,0x04,0x01, + + 0x7e,0x04,0x05,0x00, 0x01,0x01,0x0f, + + 0x00, + + 0x0c,0x04,0x02,0xff, 0xff,0xff,0xff,0xff, + + 0xff,0xff,0xff +}; + +#define QETH_CM_ENABLE_ISSUER_RM_TOKEN(buffer) (buffer+0x2c) +#define QETH_CM_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53) +#define QETH_CM_ENABLE_USER_DATA(buffer) (buffer+0x5b) + +#define QETH_CM_ENABLE_RESP_FILTER_TOKEN(buffer) (PDU_ENCAPSULATION(buffer)+ \ + 0x13) + +static unsigned char CM_SETUP[]={ + 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x02, + 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x64, + 0x10,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00, + 0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x24, + 0x00,0x00,0x24,0x05, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + + 0x01,0x00,0x00,0x24, 0x00,0x00,0x00,0x40, + + 0x00,0x0c,0x41,0x04, 0x00,0x18,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x09,0x04,0x04, + + 0x05,0x00,0x01,0x01, 0x11, + + 0x00,0x09,0x04, + + 0x05,0x05,0x00,0x00, 0x00,0x00, + + 0x00,0x06, + + 0x04,0x06,0xc8,0x00 +}; + +#define QETH_CM_SETUP_DEST_ADDR(buffer) (buffer+0x2c) +#define QETH_CM_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51) +#define QETH_CM_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a) + +#define QETH_CM_SETUP_RESP_DEST_ADDR(buffer) (PDU_ENCAPSULATION(buffer)+ \ + 0x1a) + +static unsigned char ULP_ENABLE[]={ + 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x03, + 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6b, + 0x10,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00, + 0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x01, + 0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x2b, + 0x00,0x00,0x2b,0x05, 0x20,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + + 0x01,0x00,0x00,0x2b, 0x00,0x00,0x00,0x40, + + 0x00,0x0c,0x41,0x02, 0x00,0x1f,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x0b,0x04,0x01, + + 0x03,0x04,0x05,0x00, 0x01,0x01,0x12, + + 0x00, + + 0x14,0x04,0x0a,0x00, 0x20,0x00,0x00,0xff, + 0xff,0x00,0x08,0xc8, 0xe8,0xc4,0xf1,0xc7, + + 0xf1,0x00,0x00 +}; + +#define QETH_ULP_ENABLE_LINKNUM(buffer) (buffer+0x61) +#define QETH_ULP_ENABLE_DEST_ADDR(buffer) (buffer+0x2c) +#define QETH_ULP_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53) +#define QETH_ULP_ENABLE_PORTNAME_AND_LL(buffer) (buffer+0x62) + +#define QETH_ULP_ENABLE_RESP_FILTER_TOKEN(buffer) (PDU_ENCAPSULATION(buffer)+ \ + 0x13) +#define QETH_ULP_ENABLE_RESP_MAX_MTU(buffer) (PDU_ENCAPSULATION(buffer)+ \ + 0x1f) +#define QETH_ULP_ENABLE_RESP_DIFINFO_LEN(buffer) (PDU_ENCAPSULATION(buffer)+ \ + 0x17) +#define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) (PDU_ENCAPSULATION(buffer)+ \ + 0x2b) + +static unsigned char ULP_SETUP[]={ + 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6c, + 0x10,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00, + 0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x02, + 0x00,0x00,0x00,0x01, 0x00,0x24,0x00,0x2c, + 0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + + 0x01,0x00,0x00,0x2c, 0x00,0x00,0x00,0x40, + + 0x00,0x0c,0x41,0x04, 0x00,0x20,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x09,0x04,0x04, + + 0x05,0x00,0x01,0x01, 0x14, + 0x00,0x09,0x04, + + 0x05,0x05,0x30,0x01, 0x00,0x00, + + 0x00,0x06, + + 0x04,0x06,0x40,0x00, + + 0x00,0x08,0x04,0x0b, + + 0x00,0x00,0x00,0x00 +}; + +#define QETH_ULP_SETUP_DEST_ADDR(buffer) (buffer+0x2c) +#define QETH_ULP_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51) +#define QETH_ULP_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a) +#define QETH_ULP_SETUP_CUA(buffer) (buffer+0x68) +#define QETH_ULP_SETUP_REAL_DEVADDR(buffer) (buffer+0x6a) + +#define QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(buffer) (PDU_ENCAPSULATION \ + (buffer)+0x1a) + + +static unsigned char DM_ACT[]={ + 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x05, + 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x55, + 0x10,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00, + 0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x03, + 0x00,0x00,0x00,0x02, 0x00,0x24,0x00,0x15, + 0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + + 0x01,0x00,0x00,0x15, 0x00,0x00,0x00,0x40, + + 0x00,0x0c,0x43,0x60, 0x00,0x09,0x00,0x00, + + 0x00,0x00,0x00,0x00, + + 0x00,0x09,0x04,0x04, + + 0x05,0x40,0x01,0x01, 0x00 +}; + +#define QETH_DM_ACT_DEST_ADDR(buffer) (buffer+0x2c) +#define QETH_DM_ACT_CONNECTION_TOKEN(buffer) (buffer+0x51) + +#define IPA_CMD_STARTLAN 0x01 +#define IPA_CMD_STOPLAN 0x02 +#define IPA_CMD_SETIP 0xb1 +#define IPA_CMD_DELIP 0xb7 +#define IPA_CMD_QIPASSIST 0xb2 +#define IPA_CMD_SETASSPARMS 0xb3 +#define IPA_CMD_SETIPM 0xb4 +#define IPA_CMD_DELIPM 0xb5 +#define IPA_CMD_SETRTG 0xb6 +#define IPA_CMD_SETADAPTERPARMS 0xb8 +#define IPA_CMD_ADD_ADDR_ENTRY 0xc1 +#define IPA_CMD_DELETE_ADDR_ENTRY 0xc2 +#define IPA_CMD_CREATE_ADDR 0xc3 +#define IPA_CMD_DESTROY_ADDR 0xc4 +#define IPA_CMD_REGISTER_LOCAL_ADDR 0xd1 +#define IPA_CMD_UNREGISTER_LOCAL_ADDR 0xd2 + +#define INITIATOR_HOST 0 +#define INITIATOR_HYDRA 1 + +#define PRIM_VERSION_IPA 1 + +#define PROT_VERSION_SNA 1 +#define PROT_VERSION_IPv4 4 +#define PROT_VERSION_IPv6 6 + +#define OSA_ADDR_LEN 6 +#define IPA_SETADAPTERPARMS_IP_VERSION PROT_VERSION_IPv4 +#define SR_INFO_LEN 16 + +#define IPA_ARP_PROCESSING 0x00000001L +#define IPA_INBOUND_CHECKSUM 0x00000002L +#define IPA_OUTBOUND_CHECKSUM 0x00000004L +#define IPA_IP_FRAGMENTATION 0x00000008L +#define IPA_FILTERING 0x00000010L +#define IPA_IPv6 0x00000020L +#define IPA_MULTICASTING 0x00000040L +#define IPA_IP_REASSEMBLY 0x00000080L +#define IPA_QUERY_ARP_COUNTERS 0x00000100L +#define IPA_QUERY_ARP_ADDR_INFO 0x00000200L +#define IPA_SETADAPTERPARMS 0x00000400L +#define IPA_VLAN_PRIO 0x00000800L +#define IPA_PASSTHRU 0x00001000L +#define IPA_FULL_VLAN 0x00004000L +#define IPA_SOURCE_MAC_AVAIL 0x00010000L + +#define IPA_SETADP_QUERY_COMMANDS_SUPPORTED 0x01 +#define IPA_SETADP_ALTER_MAC_ADDRESS 0x02 +#define IPA_SETADP_ADD_DELETE_GROUP_ADDRESS 0x04 +#define IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR 0x08 +#define IPA_SETADP_SET_ADDRESSING_MODE 0x10 +#define IPA_SETADP_SET_CONFIG_PARMS 0x20 +#define IPA_SETADP_SET_CONFIG_PARMS_EXTENDED 0x40 +#define IPA_SETADP_SET_BROADCAST_MODE 0x80 +#define IPA_SETADP_SEND_OSA_MESSAGE 0x0100 +#define IPA_SETADP_SET_SNMP_CONTROL 0x0200 +#define IPA_SETADP_READ_SNMP_PARMS 0x0400 +#define IPA_SETADP_WRITE_SNMP_PARMS 0x0800 +#define IPA_SETADP_QUERY_CARD_INFO 0x1000 + +#define CHANGE_ADDR_READ_MAC 0 +#define CHANGE_ADDR_REPLACE_MAC 1 +#define CHANGE_ADDR_ADD_MAC 2 +#define CHANGE_ADDR_DEL_MAC 4 +#define CHANGE_ADDR_RESET_MAC 8 +#define CHANGE_ADDR_READ_ADDR 0 +#define CHANGE_ADDR_ADD_ADDR 1 +#define CHANGE_ADDR_DEL_ADDR 2 +#define CHANGE_ADDR_FLUSH_ADDR_TABLE 4 + +#define qeth_is_supported(str) (card->ipa_supported&str) +#define qeth_is_supported6(str) (card->ipa6_supported&str) +#define qeth_is_adp_supported(str) (card->adp_supported&str) + +#define IPA_CMD_ASS_START 0x0001 +#define IPA_CMD_ASS_STOP 0x0002 + +#define IPA_CMD_ASS_CONFIGURE 0x0003 +#define IPA_CMD_ASS_ENABLE 0x0004 + +#define IPA_CMD_ASS_ARP_SET_NO_ENTRIES 0x0003 +#define IPA_CMD_ASS_ARP_QUERY_CACHE 0x0004 +#define IPA_CMD_ASS_ARP_ADD_ENTRY 0x0005 +#define IPA_CMD_ASS_ARP_REMOVE_ENTRY 0x0006 +#define IPA_CMD_ASS_ARP_FLUSH_CACHE 0x0007 +#define IPA_CMD_ASS_ARP_QUERY_INFO 0x0104 +#define IPA_CMD_ASS_ARP_QUERY_STATS 0x0204 + +#define IPA_CHECKSUM_ENABLE_MASK 0x001f + +#define IPA_CMD_ASS_FILTER_SET_TYPES 0x0003 + +#define IPA_CMD_ASS_IPv6_SET_FUNCTIONS 0x0003 + +#define IPA_REPLY_SUCCESS 0 +#define IPA_REPLY_FAILED 1 +#define IPA_REPLY_OPNOTSUPP 2 +#define IPA_REPLY_OPNOTSUPP2 4 +#define IPA_REPLY_NOINFO 8 + +#define IPA_SETIP_FLAGS 0 +#define IPA_SETIP_VIPA_FLAGS 1 +#define IPA_SETIP_TAKEOVER_FLAGS 2 + +#define VIPA_2_B_ADDED 0 +#define VIPA_ESTABLISHED 1 +#define VIPA_2_B_REMOVED 2 + +#define IPA_DELIP_FLAGS 0 + +#define IPA_SETADP_CMDSIZE 40 + +struct ipa_setadp_cmd { + __u32 supp_hw_cmds; + __u32 reserved1; + __u16 cmdlength; + __u16 reserved2; + __u32 command_code; + __u16 return_code; + __u8 frames_used_total; + __u8 frame_seq_no; + __u32 reserved3; + union { + struct { + __u32 no_lantypes_supp; + __u8 lan_type; + __u8 reserved1[3]; + __u32 supported_cmds; + __u8 reserved2[8]; + } query_cmds_supp; + struct { + __u32 cmd; + __u32 addr_size; + __u32 no_macs; + __u8 addr[OSA_ADDR_LEN]; + } change_addr; + __u32 mode; + } data; +}; + +typedef struct ipa_cmd_t { + __u8 command; + __u8 initiator; + __u16 seq_no; + __u16 return_code; + __u8 adapter_type; + __u8 rel_adapter_no; + __u8 prim_version_no; + __u8 param_count; + __u16 prot_version; + __u32 ipa_supported; + __u32 ipa_enabled; + union { + struct { + __u8 ip[4]; + __u8 netmask[4]; + __u32 flags; + } setdelip4; + struct { + __u8 ip[16]; + __u8 netmask[16]; + __u32 flags; + } setdelip6; + struct { + __u32 assist_no; + __u16 length; + __u16 command_code; + __u16 return_code; + __u8 number_of_replies; + __u8 seq_no; + union { + __u32 flags_32bit; + struct { + __u8 mac[6]; + __u8 reserved[2]; + __u8 ip[16]; + __u8 reserved2[32]; + } add_arp_entry; + __u8 ip[16]; + } data; + } setassparms; + struct { + __u8 mac[6]; + __u8 padding[2]; + __u8 ip6[12]; + __u8 ip4_6[4]; + } setdelipm; + struct { + __u8 type; + } setrtg; + struct ipa_setadp_cmd setadapterparms; + struct { + __u32 command; +#define ADDR_FRAME_TYPE_DIX 1 +#define ADDR_FRAME_TYPE_802_3 2 +#define ADDR_FRAME_TYPE_TR_WITHOUT_SR 0x10 +#define ADDR_FRAME_TYPE_TR_WITH_SR 0x20 + __u32 frame_type; + __u32 cmd_flags; + __u8 ip_addr[16]; + __u32 tag_field; + __u8 mac_addr[6]; + __u8 reserved[10]; + __u32 sr_len; + __u8 sr_info[SR_INFO_LEN]; + } add_addr_entry; + struct { + __u32 command; + __u32 cmd_flags; + __u8 ip_addr[16]; + __u32 tag_field; + } delete_addr_entry; + struct { + __u8 unique_id[8]; + } create_destroy_addr; + } data; +} ipa_cmd_t __attribute__ ((packed)); + +#define QETH_IOC_MAGIC 0x22 +#define QETH_IOCPROC_OSAEINTERFACES _IOWR(QETH_IOC_MAGIC, 1, arg) +#define QETH_IOCPROC_INTERFACECHANGES _IOWR(QETH_IOC_MAGIC, 2, arg) + +#define SNMP_QUERY_CARD_INFO 0x00000002L +#define SNMP_REGISETER_MIB 0x00000004L +#define SNMP_GET_OID 0x00000010L +#define SNMP_SET_OID 0x00000011L +#define SNMP_GET_NEXT_OID 0x00000012L +#define SNMP_QUERY_ALERTS 0x00000020L +#define SNMP_SET_TRAP 0x00000021L + + +#define ARP_DATA_SIZE 3968 +#define ARP_FLUSH -3 +#define ARP_RETURNCODE_NOARPDATA -2 +#define ARP_RETURNCODE_ERROR -1 +#define ARP_RETURNCODE_SUCCESS 0 +#define ARP_RETURNCODE_LASTREPLY 1 + +#define SNMP_BASE_CMDLENGTH 44 +#define SNMP_SETADP_CMDLENGTH 16 +#define SNMP_REQUEST_DATA_OFFSET 16 + +typedef struct snmp_ipa_setadp_cmd_t { + __u32 supp_hw_cmds; + __u32 reserved1; + __u16 cmdlength; + __u16 reserved2; + __u32 command_code; + __u16 return_code; + __u8 frames_used_total; + __u8 frame_seq_no; + __u32 reserved3; + __u8 snmp_token[16]; + union { + struct { + __u32 snmp_request; + __u32 snmp_interface; + __u32 snmp_returncode; + __u32 snmp_firmwarelevel; + __u32 snmp_seqno; + __u8 snmp_data[ARP_DATA_SIZE]; + } snmp_subcommand; + } data; +} snmp_ipa_setadp_cmd_t __attribute__ ((packed)); + +typedef struct arp_cmd_t { + __u8 command; + __u8 initiator; + __u16 seq_no; + __u16 return_code; + __u8 adapter_type; + __u8 rel_adapter_no; + __u8 prim_version_no; + __u8 param_count; + __u16 prot_version; + __u32 ipa_supported; + __u32 ipa_enabled; + union { + struct { + __u32 assist_no; + __u16 length; + __u16 command_code; + __u16 return_code; + __u8 number_of_replies; + __u8 seq_no; + union { + struct { + __u16 tcpip_requestbitmask; + __u16 osa_setbitmask; + __u32 number_of_entries; + __u8 arp_data[ARP_DATA_SIZE]; + } queryarp_data; + } data; + } setassparms; + snmp_ipa_setadp_cmd_t setadapterparms; + } data; +} arp_cmd_t __attribute__ ((packed)); + + + +#define IPA_PDU_HEADER_SIZE 0x40 +#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e) +#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26) +#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x2a) +#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a) + +static unsigned char IPA_PDU_HEADER[]={ + 0x00,0xe0,0x00,0x00, 0x77,0x77,0x77,0x77, + 0x00,0x00,0x00,0x14, 0x00,0x00, + (IPA_PDU_HEADER_SIZE+sizeof(ipa_cmd_t))/256, + (IPA_PDU_HEADER_SIZE+sizeof(ipa_cmd_t))%256, + 0x10,0x00,0x00,0x01, + + 0x00,0x00,0x00,0x00, + 0xc1,0x03,0x00,0x01, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x24,0x00,sizeof(ipa_cmd_t), + 0x00,0x00,sizeof(ipa_cmd_t),0x05, 0x77,0x77,0x77,0x77, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x01,0x00,sizeof(ipa_cmd_t)/256,sizeof(ipa_cmd_t)%256, + 0x00,0x00,0x00,0x40, +}; + +#define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer+0x2c) + +#define PDU_ENCAPSULATION(buffer) \ + (buffer+ \ + *(buffer+ (*(buffer+0x0b))+ *(buffer+*(buffer+0x0b)+0x11) +0x07)) + +#define IS_IPA(buffer) ((buffer) && ( *(buffer+ ((*(buffer+0x0b))+4) )==0xc1) ) + +#define IS_IPA_REPLY(buffer) ( (buffer) && ( (*(PDU_ENCAPSULATION(buffer)+1)) \ + ==INITIATOR_HOST ) ) + +#define IS_ADDR_IPA(buffer) ( (buffer) && ( \ + ( ((ipa_cmd_t*)PDU_ENCAPSULATION(buffer))->command== \ + IPA_CMD_ADD_ADDR_ENTRY ) || \ + ( ((ipa_cmd_t*)PDU_ENCAPSULATION(buffer))->command== \ + IPA_CMD_DELETE_ADDR_ENTRY ) ) ) + +#define CCW_NOP_CMD 0x03 +#define CCW_NOP_COUNT 1 + +static unsigned char WRITE_CCW[]={ + 0x01,CCW_FLAG_SLI,0,0, + 0,0,0,0 +}; + +static unsigned char READ_CCW[]={ + 0x02,CCW_FLAG_SLI,0,0, + 0,0,0,0 +}; + +#endif /* __QETH_MPC_H__ */ + + + + + + + + + + + + + diff -urN linux-2.4.21/drivers/s390/qdio.c linux-2.4.22/drivers/s390/qdio.c --- linux-2.4.21/drivers/s390/qdio.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/s390/qdio.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,3625 @@ +/* + * + * linux/drivers/s390/qdio.c + * + * Linux for S/390 QDIO base support, Hipersocket base support + * version 2 + * + * Copyright 2000,2002 IBM Corporation + * Author(s): Utz Bacher + * + * Restriction: only 63 iqdio subchannels would have its own indicator, + * after that, subsequent subchannels share one indicator + * + * + * + * + * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* we want the eyecatcher to be at the top of the code */ +void volatile qdio_eyecatcher(void) +{ + return; +} + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#define VERSION_QDIO_C "$Revision: 1.145 $" + +/****************** MODULE PARAMETER VARIABLES ********************/ +MODULE_AUTHOR("Utz Bacher "); +MODULE_DESCRIPTION("QDIO base support version 2, " \ + "Copyright 2000 IBM Corporation"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)) +MODULE_LICENSE("GPL"); +#endif + +/******************** HERE WE GO ***********************************/ + +static const char *version="QDIO base support version 2 (" + VERSION_QDIO_C "/" VERSION_QDIO_H ")"; + +#ifdef QDIO_PERFORMANCE_STATS +static int proc_perf_file_registration; +unsigned long i_p_c=0,i_p_nc=0,o_p_c=0,o_p_nc=0,ii_p_c=0,ii_p_nc=0; + +static struct { + unsigned int tl_runs; + + unsigned int siga_outs; + unsigned int siga_ins; + unsigned int siga_syncs; + unsigned int pcis; + unsigned int thinints; + unsigned int fast_reqs; + + __u64 start_time_outbound; + unsigned int outbound_cnt; + unsigned int outbound_time; + __u64 start_time_inbound; + unsigned int inbound_cnt; + unsigned int inbound_time; +} perf_stats; + +#endif /* QDIO_PERFORMANCE_STATS */ + +static int hydra_thinints=0; + +static int indicator_used[INDICATORS_PER_CACHELINE]; +static __u32 * volatile indicators; +static __u32 volatile spare_indicator; + +static debug_info_t *qdio_dbf_setup=NULL; +static debug_info_t *qdio_dbf_sbal=NULL; +static debug_info_t *qdio_dbf_trace=NULL; +static debug_info_t *qdio_dbf_sense=NULL; +#ifdef QDIO_DBF_LIKE_HELL +static debug_info_t *qdio_dbf_slsb_out=NULL; +static debug_info_t *qdio_dbf_slsb_in=NULL; +#endif /* QDIO_DBF_LIKE_HELL */ + +static qdio_irq_t *first_irq[QDIO_IRQ_BUCKETS]={ + [0 ... (QDIO_IRQ_BUCKETS-1)] = NULL +}; +static rwlock_t irq_list_lock[QDIO_IRQ_BUCKETS]={ + [0 ... (QDIO_IRQ_BUCKETS-1)] = RW_LOCK_UNLOCKED +}; + +static struct semaphore init_sema; + +static qdio_chsc_area_t *chsc_area; +/* iQDIO stuff: */ +static volatile qdio_q_t *tiq_list=NULL; /* volatile as it could change + during a while loop */ +static spinlock_t ttiq_list_lock=SPIN_LOCK_UNLOCKED; +static int register_thinint_result; +static void tiqdio_tl(unsigned long); +static DECLARE_TASKLET(tiqdio_tasklet,tiqdio_tl,0); + +#define HEXDUMP16(importance,header,ptr) \ +QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x\n",*(((char*)ptr)), \ + *(((char*)ptr)+1),*(((char*)ptr)+2), \ + *(((char*)ptr)+3),*(((char*)ptr)+4), \ + *(((char*)ptr)+5),*(((char*)ptr)+6), \ + *(((char*)ptr)+7),*(((char*)ptr)+8), \ + *(((char*)ptr)+9),*(((char*)ptr)+10), \ + *(((char*)ptr)+11),*(((char*)ptr)+12), \ + *(((char*)ptr)+13),*(((char*)ptr)+14), \ + *(((char*)ptr)+15)); \ +QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ + *(((char*)ptr)+16),*(((char*)ptr)+17), \ + *(((char*)ptr)+18),*(((char*)ptr)+19), \ + *(((char*)ptr)+20),*(((char*)ptr)+21), \ + *(((char*)ptr)+22),*(((char*)ptr)+23), \ + *(((char*)ptr)+24),*(((char*)ptr)+25), \ + *(((char*)ptr)+26),*(((char*)ptr)+27), \ + *(((char*)ptr)+28),*(((char*)ptr)+29), \ + *(((char*)ptr)+30),*(((char*)ptr)+31)); + +#define atomic_swap(a,b) xchg((int*)a.counter,b) + +/* not a macro, as one of the arguments is atomic_read */ +static inline int qdio_min(int a,int b) +{ + if (asiga_sync)) qdio_siga_sync_q(q) +#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \ + qdio_siga_sync(q,~0U,~0U) +#define SYNC_MEMORY_ALL_OUTB if (unlikely(q->siga_sync)) \ + qdio_siga_sync(q,~0U,0) + +#define NOW qdio_get_micros() +#define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW +#define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time) +#define SAVE_FRONTIER(q,val) q->last_move_ftc=val +#define GET_SAVED_FRONTIER(q) (q->last_move_ftc) + +#define MY_MODULE_STRING(x) #x + +#ifdef QDIO_32_BIT +#define QDIO_GET_32BIT_ADDR(x) ((__u32)(long)x) +#else /* QDIO_32_BIT */ +#define QDIO_GET_32BIT_ADDR(x) ((__u32)(unsigned long)x) +#endif /* QDIO_32_BIT */ + +#define QDIO_PFIX_GET_ADDR(x) ((flags&QDIO_PFIX) ? \ + pfix_get_addr(x):((unsigned long)x)) + +/***************** SCRUBBER HELPER ROUTINES **********************/ + +static inline volatile __u64 qdio_get_micros(void) +{ + __u64 time; + + asm volatile ("STCK %0" : "=m" (time)); + return time>>12; /* time>>12 is microseconds*/ +} +static inline unsigned long qdio_get_millis(void) +{ + return (unsigned long)(qdio_get_micros()>>12); +} + +static __inline__ int atomic_return_add (int i, atomic_t *v) +{ + int old, new; + __CS_LOOP(old, new, v, i, "ar"); + return old; +} + +static void qdio_wait_nonbusy(unsigned int timeout) +{ + unsigned int start; + char dbf_text[15]; + + sprintf(dbf_text,"wtnb%4x",timeout); + QDIO_DBF_TEXT3(0,trace,dbf_text); + + start=qdio_get_millis(); + for (;;) { + set_task_state(current,TASK_INTERRUPTIBLE); + if (qdio_get_millis()-start>timeout) { + goto out; + } + schedule_timeout(((start+timeout-qdio_get_millis())>>10)*HZ); + } +out: + set_task_state(current,TASK_RUNNING); +} + +static int qdio_wait_for_no_use_count(atomic_t *use_count) +{ + unsigned long start; + + QDIO_DBF_TEXT3(0,trace,"wtnousec"); + start=qdio_get_millis(); + for (;;) { + if (qdio_get_millis()-start>QDIO_NO_USE_COUNT_TIMEOUT) { + QDIO_DBF_TEXT1(1,trace,"WTNOUSTO"); + return -ETIME; + } + if (!atomic_read(use_count)) { + QDIO_DBF_TEXT3(0,trace,"wtnoused"); + return 0; + } + qdio_wait_nonbusy(QDIO_NO_USE_COUNT_TIME); + } +} + +/* unfortunately, we can't just xchg the values; in do_QDIO we want to reserve + * the q in any case, so that we'll not be interrupted when we are in + * qdio_mark_tiq... shouldn't have a really bad impact, as reserving almost + * ever works (last famous words) */ +static inline int qdio_reserve_q(qdio_q_t *q) +{ + return atomic_return_add(1,&q->use_count); +} + +static inline void qdio_release_q(qdio_q_t *q) +{ + atomic_dec(&q->use_count); +} +#ifdef QDIO_DBF_LIKE_HELL +#define set_slsb(x,y) \ + if(q->queue_type==QDIO_TRACE_QTYPE) { \ + if(q->is_input_q) { \ + QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ + } else { \ + QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ + } \ + } \ + qdio_set_slsb(x,y); \ + if(q->queue_type==QDIO_TRACE_QTYPE) { \ + if(q->is_input_q) { \ + QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ + } else { \ + QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ + } \ + } +#else /* QDIO_DBF_LIKE_HELL */ +#define set_slsb(x,y) qdio_set_slsb(x,y) +#endif /* QDIO_DBF_LIKE_HELL */ +static volatile inline void qdio_set_slsb(volatile char *slsb, + unsigned char value) +{ + xchg((char*)slsb,value); +} + +static inline int qdio_siga_sync(qdio_q_t *q, + unsigned int gpr2, + unsigned int gpr3) +{ + int cc; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"sigasync"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(int)); + QDIO_DBF_HEX4(0,trace,&gpr2,sizeof(int)); + QDIO_DBF_HEX4(0,trace,&gpr3,sizeof(int)); +#endif /* QDIO_DBF_LIKE_HELL */ + +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.siga_syncs++; +#endif /* QDIO_PERFORMANCE_STATS */ + +#ifdef QDIO_32_BIT + asm volatile ( + "lhi 0,2 \n\t" + "lr 1,%1 \n\t" + "lr 2,%2 \n\t" + "lr 3,%3 \n\t" + "siga 0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) + : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3) + : "cc", "0", "1", "2", "3" + ); +#else /* QDIO_32_BIT */ + asm volatile ( + "lghi 0,2 \n\t" + "llgfr 1,%1 \n\t" + "llgfr 2,%2 \n\t" + "llgfr 3,%3 \n\t" + "siga 0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) + : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3) + : "cc", "0", "1", "2", "3" + ); +#endif /* QDIO_32_BIT */ + + if (cc) { +#ifndef QDIO_DBF_LIKE_HELL + /* when QDIO_DBF_LIKE_HELL, we put that already out */ + QDIO_DBF_TEXT3(0,trace,"sigasync"); + QDIO_DBF_HEX3(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); + } + + return cc; +} + +static inline int qdio_siga_sync_q(qdio_q_t *q) +{ + if (q->is_input_q) { + return qdio_siga_sync(q,0,q->mask); + } else { + return qdio_siga_sync(q,q->mask,0); + } +} + +/* returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns + an access exception */ +static inline int qdio_siga_output(qdio_q_t *q) +{ + int cc; + __u32 busy_bit; + __u64 start_time=0; + +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.siga_outs++; +#endif /* QDIO_PERFORMANCE_STATS */ + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"sigaout"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + for (;;) { + +#ifdef QDIO_32_BIT + asm volatile ( + "lhi 0,0 \n\t" + "lr 1,%2 \n\t" + "lr 2,%3 \n\t" + "siga 0 \n\t" + "0:" + "ipm %0 \n\t" + "srl %0,28 \n\t" + "srl 0,31 \n\t" + "lr %1,0 \n\t" + "1: \n\t" + ".section .fixup,\"ax\"\n\t" + "2: \n\t" + "lhi %0,%4 \n\t" + "bras 1,3f \n\t" + ".long 1b \n\t" + "3: \n\t" + "l 1,0(1) \n\t" + "br 1 \n\t" + ".previous \n\t" + ".section __ex_table,\"a\"\n\t" + ".align 4 \n\t" + ".long 0b,2b \n\t" + ".previous \n\t" + : "=d" (cc), "=d" (busy_bit) + : "d" (0x10000|q->irq), "d" (q->mask), + "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) + : "cc", "0", "1", "2", "memory" + ); +#else /* QDIO_32_BIT */ + asm volatile ( + "lghi 0,0 \n\t" + "llgfr 1,%2 \n\t" + "llgfr 2,%3 \n\t" + "siga 0 \n\t" + "0:" + "ipm %0 \n\t" + "srl %0,28 \n\t" + "srl 0,31 \n\t" + "llgfr %1,0 \n\t" + "1: \n\t" + ".section .fixup,\"ax\"\n\t" + "lghi %0,%4 \n\t" + "jg 1b \n\t" + ".previous\n\t" + ".section __ex_table,\"a\"\n\t" + ".align 8 \n\t" + ".quad 0b,1b \n\t" + ".previous \n\t" + : "=d" (cc), "=d" (busy_bit) + : "d" (0x10000|q->irq), "d" (q->mask), + "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) + : "cc", "0", "1", "2", "memory" + ); +#endif /* QDIO_32_BIT */ + +//QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit); + if ( (cc==2) && (busy_bit) && + (q->is_iqdio_q) ) { + if (!start_time) start_time=NOW; + if ((NOW-start_time)>QDIO_BUSY_BIT_PATIENCE) + break; + } else + break; + } + + if ((cc==2) && (busy_bit)) cc|=QDIO_SIGA_ERROR_B_BIT_SET; + + if (cc) { +#ifndef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT3(0,trace,"sigaout"); + QDIO_DBF_HEX3(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); + } + + return cc; +} + +static inline int qdio_siga_input(qdio_q_t *q) +{ + int cc; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"sigain"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.siga_ins++; +#endif /* QDIO_PERFORMANCE_STATS */ + +#ifdef QDIO_32_BIT + asm volatile ( + "lhi 0,1 \n\t" + "lr 1,%1 \n\t" + "lr 2,%2 \n\t" + "siga 0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) + : "d" (0x10000|q->irq), "d" (q->mask) + : "cc", "0", "1", "2", "memory" + ); +#else /* QDIO_32_BIT */ + asm volatile ( + "lghi 0,1 \n\t" + "llgfr 1,%1 \n\t" + "llgfr 2,%2 \n\t" + "siga 0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) + : "d" (0x10000|q->irq), "d" (q->mask) + : "cc", "0", "1", "2", "memory" + ); +#endif /* QDIO_32_BIT */ + + if (cc) { +#ifndef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT3(0,trace,"sigain"); + QDIO_DBF_HEX3(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); + } + + return cc; +} + +/* locked by the locks in qdio_activate and qdio_cleanup */ +static __u32 * volatile qdio_get_indicator(void) +{ + int i=1; + int found=0; + + while (iis_in_shutdown))) goto out_unlock; + + if (q->is_input_q) { + if ((q->list_prev) || (q->list_next)) goto out_unlock; + + if (!tiq_list) { + tiq_list=q; + q->list_prev=q; + q->list_next=q; + } else { + q->list_next=tiq_list; + q->list_prev=tiq_list->list_prev; + tiq_list->list_prev->list_next=q; + tiq_list->list_prev=q; + } + spin_unlock_irqrestore(&ttiq_list_lock,flags); + + tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); + tiqdio_sched_tl(); + } + return; +out_unlock: + spin_unlock_irqrestore(&ttiq_list_lock,flags); + return; +} + +static inline void qdio_mark_q(qdio_q_t *q) +{ +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"mark q"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (unlikely(atomic_read(&q->is_in_shutdown))) return; + + tasklet_schedule(&q->tasklet); +} + +static inline int qdio_stop_polling(qdio_q_t *q) +{ +#ifdef QDIO_USE_PROCESSING_STATE + int gsf; + + if (!atomic_swap(&q->polling,0)) return 1; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"stoppoll"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + /* show the card that we are not polling anymore */ + if (q->is_input_q) { + gsf=GET_SAVED_FRONTIER(q); + set_slsb(&q->slsb.acc.val[(gsf+QDIO_MAX_BUFFERS_PER_Q-1)& + (QDIO_MAX_BUFFERS_PER_Q-1)],SLSB_P_INPUT_NOT_INIT); + /* we don't issue this SYNC_MEMORY, as we trust Rick T and + * moreover will not use the PROCESSING state, so q->polling + * was 0 + SYNC_MEMORY;*/ + if (q->slsb.acc.val[gsf]==SLSB_P_INPUT_PRIMED) { + /* set our summary bit again, as otherwise there is a + * small window we can miss between resetting it and + * checking for PRIMED state */ + if (q->is_thinint_q) + tiqdio_set_summary_bit + ((__u32*)q->dev_st_chg_ind); + return 0; + } + } +#endif /* QDIO_USE_PROCESSING_STATE */ + return 1; +} + +/* see the comment in do_QDIO and before qdio_reserve_q about the + * sophisticated locking outside of unmark_q, so that we don't need to + * disable the interrupts :-) */ +static inline void qdio_unmark_q(qdio_q_t *q) +{ + unsigned long flags; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"unmark q"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + if ((!q->list_prev)||(!q->list_next)) return; + + if ((q->is_thinint_q)&&(q->is_input_q)) { + /* iQDIO */ + spin_lock_irqsave(&ttiq_list_lock,flags); + if (q->list_next==q) { + /* q was the only interesting q */ + tiq_list=NULL; + q->list_next=NULL; + q->list_prev=NULL; + } else { + q->list_next->list_prev=q->list_prev; + q->list_prev->list_next=q->list_next; + tiq_list=q->list_next; + q->list_next=NULL; + q->list_prev=NULL; + } + spin_unlock_irqrestore(&ttiq_list_lock,flags); + } +} + +static inline volatile unsigned long tiqdio_clear_global_summary(void) +{ + unsigned long time; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT5(0,trace,"clrglobl"); +#endif /* QDIO_DBF_LIKE_HELL */ + +#ifdef QDIO_32_BIT + asm volatile ( + "lhi 1,3 \n\t" + ".insn rre,0xb2650000,2,0 \n\t" + "lr %0,3 \n\t" + : "=d" (time) : : "cc", "1", "2", "3" + ); +#else /* QDIO_32_BIT */ + asm volatile ( + "lghi 1,3 \n\t" + ".insn rre,0xb2650000,2,0 \n\t" + "lgr %0,3 \n\t" + : "=d" (time) : : "cc", "1", "2", "3" + ); +#endif /* QDIO_32_BIT */ + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_HEX5(0,trace,&time,sizeof(unsigned long)); +#endif /* QDIO_DBF_LIKE_HELL */ + return time; +} + +/************************* OUTBOUND ROUTINES *******************************/ + +static inline void qdio_translate_buffer_back(qdio_q_t *q,int bufno) +{ + if (unlikely(!q->is_0copy_sbals_q)) + memcpy(q->qdio_buffers[bufno], + (void*)q->sbal[bufno],SBAL_SIZE); +} + +inline static int qdio_get_outbound_buffer_frontier(qdio_q_t *q) +{ + int f,f_mod_no; + volatile char *slsb; + int first_not_to_check; + char dbf_text[15]; + char slsbyte; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"getobfro"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + slsb=&q->slsb.acc.val[0]; + f_mod_no=f=q->first_to_check; + /* f point to already processed elements, so f+no_used is correct... + * ... but: we don't check 128 buffers, as otherwise + * qdio_has_outbound_q_moved would return 0 */ + first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), + (QDIO_MAX_BUFFERS_PER_Q-1)); + + if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) { + SYNC_MEMORY; + } + +check_next: + if (f==first_not_to_check) goto out; + slsbyte=slsb[f_mod_no]; + + /* the hydra has not fetched the output yet */ + if (slsbyte==SLSB_CU_OUTPUT_PRIMED) { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT5(0,trace,"outpprim"); +#endif /* QDIO_DBF_LIKE_HELL */ + goto out; + } + + /* the hydra got it */ + if (slsbyte==SLSB_P_OUTPUT_EMPTY) { + atomic_dec(&q->number_of_buffers_used); + f++; + f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1); +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT5(0,trace,"outpempt"); +#endif /* QDIO_DBF_LIKE_HELL */ + goto check_next; + } + + if (slsbyte==SLSB_P_OUTPUT_ERROR) { + QDIO_DBF_TEXT3(0,trace,"outperr"); + sprintf(dbf_text,"%x-%x-%x",f_mod_no, + q->sbal[f_mod_no]->element[14].sbalf.value, + q->sbal[f_mod_no]->element[15].sbalf.value); + QDIO_DBF_TEXT3(1,trace,dbf_text); + QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); + + /* kind of process the buffer */ + set_slsb(&q->slsb.acc.val[f_mod_no], + SLSB_P_OUTPUT_NOT_INIT); + + qdio_translate_buffer_back(q,f_mod_no); + + /* we increment the frontier, as this buffer + * was processed obviously */ + atomic_dec(&q->number_of_buffers_used); + f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1); + + if (q->qdio_error) + q->error_status_flags|= + QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; + q->qdio_error=SLSB_P_OUTPUT_ERROR; + q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR; + + goto out; + } + + /* no new buffers */ +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT5(0,trace,"outpni"); +#endif /* QDIO_DBF_LIKE_HELL */ + goto out; + +out: + return (q->first_to_check=f_mod_no); +} + +/* all buffers are processed */ +inline static int qdio_is_outbound_q_done(qdio_q_t *q) +{ + int no_used; +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[15]; +#endif /* QDIO_DBF_LIKE_HELL */ + + no_used=atomic_read(&q->number_of_buffers_used); + +#ifdef QDIO_DBF_LIKE_HELL + if (no_used) { + sprintf(dbf_text,"oqisnt%02x",no_used); + QDIO_DBF_TEXT4(0,trace,dbf_text); + } else { + QDIO_DBF_TEXT4(0,trace,"oqisdone"); + } + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + return (no_used==0); +} + +inline static int qdio_has_outbound_q_moved(qdio_q_t *q) +{ + int i; + + i=qdio_get_outbound_buffer_frontier(q); + + if ( (i!=GET_SAVED_FRONTIER(q)) || + (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) { + SAVE_FRONTIER(q,i); + SAVE_TIMESTAMP(q); +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"oqhasmvd"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + return 1; + } else { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"oqhsntmv"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + return 0; + } +} + +inline static void qdio_kick_outbound_q(qdio_q_t *q) +{ + int result; +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"kickoutq"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (!q->siga_out) return; + + result=qdio_siga_output(q); + + if (result) { + if (q->siga_error) + q->error_status_flags|= + QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR; + q->error_status_flags|= + QDIO_STATUS_LOOK_FOR_ERROR; + q->siga_error=result; + } +} + +inline static void qdio_kick_outbound_handler(qdio_q_t *q) +{ +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[15]; +#endif /* QDIO_DBF_LIKE_HELL */ + + int start=q->first_element_to_kick; + /* last_move_ftc was just updated */ + int real_end=GET_SAVED_FRONTIER(q); + int end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)& + (QDIO_MAX_BUFFERS_PER_Q-1); + int count=(end+QDIO_MAX_BUFFERS_PER_Q+1-start)& + (QDIO_MAX_BUFFERS_PER_Q-1); + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"kickouth"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + +#ifdef QDIO_DBF_LIKE_HELL + sprintf(dbf_text,"s=%2xc=%2x",start,count); + QDIO_DBF_TEXT4(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (q->state==QDIO_IRQ_STATE_ACTIVE) + q->handler(q->irq,QDIO_STATUS_OUTBOUND_INT| + q->error_status_flags, + q->qdio_error,q->siga_error,q->q_no,start,count, + q->int_parm); + + /* for the next time: */ + q->first_element_to_kick=real_end; + q->qdio_error=0; + q->siga_error=0; + q->error_status_flags=0; +} + +static void qdio_outbound_processing(qdio_q_t *q) +{ +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"qoutproc"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (unlikely(qdio_reserve_q(q))) { + qdio_release_q(q); +#ifdef QDIO_PERFORMANCE_STATS + o_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ + /* as we're sissies, we'll check next time */ + if (likely(!atomic_read(&q->is_in_shutdown))) { + qdio_mark_q(q); +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"busy,agn"); +#endif /* QDIO_DBF_LIKE_HELL */ + } + return; + } +#ifdef QDIO_PERFORMANCE_STATS + o_p_nc++; +#endif /* QDIO_PERFORMANCE_STATS */ + +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs++; +#endif /* QDIO_PERFORMANCE_STATS */ + + if (qdio_has_outbound_q_moved(q)) { + qdio_kick_outbound_handler(q); + } + + if (q->is_iqdio_q) { + /* for asynchronous queues, we better check, if the fill + * level is too high */ + if (atomic_read(&q->number_of_buffers_used)> + IQDIO_FILL_LEVEL_TO_POLL) { + qdio_mark_q(q); + } + } else if (!q->hydra_gives_outbound_pcis) { + if (!qdio_is_outbound_q_done(q)) { + qdio_mark_q(q); + } + } + + qdio_release_q(q); +} + +/************************* INBOUND ROUTINES *******************************/ + + +inline static int qdio_get_inbound_buffer_frontier(qdio_q_t *q) +{ + int f,f_mod_no; + volatile char *slsb; + char slsbyte; + int first_not_to_check; + char dbf_text[15]; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"getibfro"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + slsb=&q->slsb.acc.val[0]; + f_mod_no=f=q->first_to_check; + /* we don't check 128 buffers, as otherwise qdio_has_inbound_q_moved + * would return 0 */ + first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), + (QDIO_MAX_BUFFERS_PER_Q-1)); + + /* we don't use this one, as a PCI or we after a thin interrupt + * will sync the queues + SYNC_MEMORY;*/ + +check_next: + f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1); + if (f==first_not_to_check) goto out; + slsbyte=slsb[f_mod_no]; + + /* CU_EMPTY means frontier is reached */ + if (slsbyte==SLSB_CU_INPUT_EMPTY) { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT5(0,trace,"inptempt"); +#endif /* QDIO_DBF_LIKE_HELL */ + goto out; + } + + /* P_PRIMED means set slsb to P_PROCESSING and move on */ + if (slsbyte==SLSB_P_INPUT_PRIMED) { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT5(0,trace,"inptprim"); +#endif /* QDIO_DBF_LIKE_HELL */ + +#ifdef QDIO_USE_PROCESSING_STATE + /* as soon as running under VM, polling the input queues will + * kill VM in terms of CP overhead */ + if (q->siga_sync) { + set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); + } else { + set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_PROCESSING); + atomic_set(&q->polling,1); + } +#else /* QDIO_USE_PROCESSING_STATE */ + set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); +#endif /* QDIO_USE_PROCESSING_STATE */ + /* not needed, as the inbound queue will be synced on the next + * siga-r + SYNC_MEMORY;*/ + f++; + atomic_dec(&q->number_of_buffers_used); + goto check_next; + } + + if ( (slsbyte==SLSB_P_INPUT_NOT_INIT) || + (slsbyte==SLSB_P_INPUT_PROCESSING) ) { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT5(0,trace,"inpnipro"); +#endif /* QDIO_DBF_LIKE_HELL */ + goto out; + } + + /* P_ERROR means frontier is reached, break and report error */ + if (slsbyte==SLSB_P_INPUT_ERROR) { + sprintf(dbf_text,"inperr%2x",f_mod_no); + QDIO_DBF_TEXT3(1,trace,dbf_text); + QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); + + /* kind of process the buffer */ + set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); + + if (q->qdio_error) + q->error_status_flags|= + QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; + q->qdio_error=SLSB_P_INPUT_ERROR; + q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR; + + /* we increment the frontier, as this buffer + * was processed obviously */ + f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1); + atomic_dec(&q->number_of_buffers_used); + + goto out; + } + + /* everything else means frontier not changed (HALTED or so) */ +out: + q->first_to_check=f_mod_no; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); +#endif /* QDIO_DBF_LIKE_HELL */ + + return q->first_to_check; +} + +inline static int qdio_has_inbound_q_moved(qdio_q_t *q) +{ + int i; + +#ifdef QDIO_PERFORMANCE_STATS + static int old_pcis=0; + static int old_thinints=0; + + if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints)) + perf_stats.start_time_inbound=NOW; + else + old_pcis=perf_stats.pcis; +#endif /* QDIO_PERFORMANCE_STATS */ + + i=qdio_get_inbound_buffer_frontier(q); + if ( (i!=GET_SAVED_FRONTIER(q)) || + (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) { + SAVE_FRONTIER(q,i); + if ((!q->siga_sync)&&(!q->hydra_gives_outbound_pcis)) { + SAVE_TIMESTAMP(q); + } + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"inhasmvd"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + return 1; + } else { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"inhsntmv"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + return 0; + } +} + +/* means, no more buffers to be filled */ +inline static int iqdio_is_inbound_q_done(qdio_q_t *q) +{ + int no_used; +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[15]; +#endif /* QDIO_DBF_LIKE_HELL */ + + no_used=atomic_read(&q->number_of_buffers_used); + + /* propagate the change from 82 to 80 through VM */ + SYNC_MEMORY; + +#ifdef QDIO_DBF_LIKE_HELL + if (no_used) { + sprintf(dbf_text,"iqisnt%02x",no_used); + QDIO_DBF_TEXT4(0,trace,dbf_text); + } else { + QDIO_DBF_TEXT4(0,trace,"iniqisdo"); + } + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (!no_used) { + return 1; + } + + if (q->siga_sync) { + if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) { + /* ok, the next input buffer is primed. that means, + * that device state change indicator and adapter + * local summary are set, so we will find it next + * time. + * we will return 0 below, as there is nothing to + * do, except of scheduling ourselves for the next + * time. */ + tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); + tiqdio_sched_tl(); + } else { + /* nothing more to do, if next buffer is not PRIMED. + * note that we did a SYNC_MEMORY before, that there + * has been a sychnronization. + * we will return 0 below, as there is nothing to do + * (stop_polling not necessary, as we have not been + * using the PROCESSING state */ + } + } else { + /* we'll check for more primed buffers + * in qeth_stop_polling */ + } + + return 0; +} + +inline static int qdio_is_inbound_q_done(qdio_q_t *q) +{ + int no_used; +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[15]; +#endif /* QDIO_DBF_LIKE_HELL */ + + no_used=atomic_read(&q->number_of_buffers_used); + + /* we need that one for synchronization with Hydra, as Hydra + * does a kind of PCI avoidance */ + SYNC_MEMORY; + + if (!no_used) { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"inqisdnA"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); + QDIO_DBF_TEXT4(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + return 1; + } + + if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) { + /* we got something to do */ +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"inqisntA"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + return 0; + } + + /* on VM, we don't poll, so the q is always done here */ + if (q->siga_sync) return 1; + if (q->hydra_gives_outbound_pcis) return 1; + + /* at this point we know, that inbound first_to_check + has (probably) not moved (see qdio_inbound_processing) */ + if (NOW>GET_SAVED_TIMESTAMP(q)+q->timing.threshold) { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"inqisdon"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); + sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used); + QDIO_DBF_TEXT4(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + return 1; + } else { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"inqisntd"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); + sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used); + QDIO_DBF_TEXT4(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + return 0; + } +} + +inline static void qdio_kick_inbound_handler(qdio_q_t *q) +{ + int count=0; + int start,end,real_end,i; +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[15]; + + QDIO_DBF_TEXT4(0,trace,"kickinh"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + start=q->first_element_to_kick; + real_end=q->first_to_check; + end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)&(QDIO_MAX_BUFFERS_PER_Q-1); + + i=start; + while (1) { + count++; + qdio_translate_buffer_back(q,i); + if (i==end) break; + i=(i+1)&(QDIO_MAX_BUFFERS_PER_Q-1); + } + +#ifdef QDIO_DBF_LIKE_HELL + sprintf(dbf_text,"s=%2xc=%2x",start,count); + QDIO_DBF_TEXT4(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (likely(q->state==QDIO_IRQ_STATE_ACTIVE)) + q->handler(q->irq, + QDIO_STATUS_INBOUND_INT|q->error_status_flags, + q->qdio_error,q->siga_error,q->q_no,start,count, + q->int_parm); + + /* for the next time: */ + q->first_element_to_kick=real_end; + q->qdio_error=0; + q->siga_error=0; + q->error_status_flags=0; + +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; + perf_stats.inbound_cnt++; +#endif /* QDIO_PERFORMANCE_STATS */ +} + +static inline void tiqdio_inbound_processing(qdio_q_t *q) +{ + qdio_irq_t *irq_ptr; + qdio_q_t *oq; + int i; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"iqinproc"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + /* we first want to reserve the q, so that we know, that we don't + * interrupt ourselves and call qdio_unmark_q, as is_in_shutdown might + * be set */ + if (unlikely(qdio_reserve_q(q))) { + qdio_release_q(q); +#ifdef QDIO_PERFORMANCE_STATS + ii_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ + /* as we might just be about to stop polling, we make + * sure that we check again at least once more */ + tiqdio_sched_tl(); + return; + } +#ifdef QDIO_PERFORMANCE_STATS + ii_p_nc++; +#endif /* QDIO_PERFORMANCE_STATS */ + if (unlikely(atomic_read(&q->is_in_shutdown))) { + qdio_unmark_q(q); + goto out; + } + + if (*(q->dev_st_chg_ind)) { + tiqdio_clear_summary_bit((__u32*)q->dev_st_chg_ind); + + if (q->hydra_gives_outbound_pcis) { + if (!q->siga_sync_done_on_thinints) { + SYNC_MEMORY_ALL; + } else if ((!q->siga_sync_done_on_outb_tis)&& + (q->hydra_gives_outbound_pcis)) { + SYNC_MEMORY_ALL_OUTB; + } + } else { + SYNC_MEMORY; + } + + /* maybe we have to do work on our outbound queues... at least + * we have to check Hydra outbound-int-capable thinint-capable + * queues */ + if (q->hydra_gives_outbound_pcis) { + irq_ptr=(qdio_irq_t*)q->irq_ptr; + for (i=0;ino_output_qs;i++) { + oq=irq_ptr->output_qs[i]; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs--; +#endif /* QDIO_PERFORMANCE_STATS */ + if (!qdio_is_outbound_q_done(oq)) { + qdio_outbound_processing(oq); + } + } + } + + if (qdio_has_inbound_q_moved(q)) { + qdio_kick_inbound_handler(q); + if (iqdio_is_inbound_q_done(q)) { + if (!qdio_stop_polling(q)) { + /* we set the flags to get into + * the stuff next time, see also + * comment in qdio_stop_polling */ + tiqdio_set_summary_bit + ((__u32*)q->dev_st_chg_ind); + tiqdio_sched_tl(); + } + } + } + } +out: + qdio_release_q(q); +} + +static void qdio_inbound_processing(qdio_q_t *q) +{ + int q_laps=0; + +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"qinproc"); + QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (unlikely(qdio_reserve_q(q))) { + qdio_release_q(q); +#ifdef QDIO_PERFORMANCE_STATS + i_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ + /* as we're sissies, we'll check next time */ + if (likely(!atomic_read(&q->is_in_shutdown))) { + qdio_mark_q(q); +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"busy,agn"); +#endif /* QDIO_DBF_LIKE_HELL */ + } + return; + } +#ifdef QDIO_PERFORMANCE_STATS + i_p_nc++; + perf_stats.tl_runs++; +#endif /* QDIO_PERFORMANCE_STATS */ + +again: + if (qdio_has_inbound_q_moved(q)) { + qdio_kick_inbound_handler(q); + if (!qdio_stop_polling(q)) { + q_laps++; + if (q_lapslist_next; + } while (q!=(qdio_q_t*)tiq_list); + + /* switch off all queues' processing state */ +#ifdef QDIO_USE_PROCESSING_STATE + q=(qdio_q_t*)tiq_list; + do { + if (!q) { + tiqdio_sched_tl(); + break; + } + /* under VM, we have not used the PROCESSING state, so no + * need to stop polling */ + if (q->siga_sync) { + q=(qdio_q_t*)q->list_next; + continue; + } + + if (unlikely(qdio_reserve_q(q))) { + qdio_release_q(q); +#ifdef QDIO_PERFORMANCE_STATS + ii_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ + /* as we might just be about to stop polling, we make + * sure that we check again at least once more */ + + /* sanity -- we'd get here without setting the + * dev st chg ind */ + tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); + tiqdio_sched_tl(); + break; + } + if (!qdio_stop_polling(q)) { + q_laps++; + if (q_lapsdev_st_chg_ind); + tiqdio_sched_tl(); + } + } + qdio_release_q(q); + q=(qdio_q_t*)q->list_next; + } while (q!=(qdio_q_t*)tiq_list); +#endif /* QDIO_USE_PROCESSING_STATE */ +} + +static void tiqdio_tl(unsigned long data) +{ +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"tiqdio_tl"); +#endif /* QDIO_DBF_LIKE_HELL */ +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs++; +#endif /* QDIO_PERFORMANCE_STATS */ + + tiqdio_inbound_checks(); +} + +/********************* GENERAL HELPER_ROUTINES ***********************/ + +static qdio_irq_t *qdio_get_irq_ptr(int irq) +{ + qdio_irq_t *irq_ptr; + int bucket=irq&(QDIO_IRQ_BUCKETS-1); + + read_lock(&irq_list_lock[bucket]); + irq_ptr=first_irq[bucket]; + while (irq_ptr) { + if (irq_ptr->irq==irq) break; + irq_ptr=irq_ptr->next; + } + read_unlock(&irq_list_lock[bucket]); + return irq_ptr; +} + +static qdio_irq_t *qdio_get_irq_ptr_wolock(int irq) +{ + qdio_irq_t *irq_ptr=first_irq[irq&(QDIO_IRQ_BUCKETS-1)]; + + while (irq_ptr) { + if (irq_ptr->irq==irq) break; + irq_ptr=irq_ptr->next; + } + return irq_ptr; +} + +/* irq_ptr->irq should be set already! */ +static void qdio_insert_irq_ptr(qdio_irq_t *irq_ptr) +{ + qdio_irq_t *i_p; + int irq,bucket; + + if (!irq_ptr) return; + + irq=irq_ptr->irq; + bucket=irq&(QDIO_IRQ_BUCKETS-1); + + write_lock(&irq_list_lock[bucket]); + + if (irq_ptr==qdio_get_irq_ptr_wolock(irq)) goto out; + + if (!first_irq[bucket]) { + first_irq[bucket]=irq_ptr; + } else { + i_p=first_irq[bucket]; + while (i_p->next) + i_p=i_p->next; + i_p->next=irq_ptr; + } + irq_ptr->next=NULL; +out: + write_unlock(&irq_list_lock[bucket]); +} + +static void qdio_remove_irq_ptr(qdio_irq_t *irq_ptr) +{ + qdio_irq_t *i_p; + int irq,bucket; + + if (!irq_ptr) return; + + irq=irq_ptr->irq; + bucket=irq&(QDIO_IRQ_BUCKETS-1); + + write_lock(&irq_list_lock[bucket]); + + if (!qdio_get_irq_ptr_wolock(irq)) goto out; + + if (first_irq[irq&(QDIO_IRQ_BUCKETS-1)]==irq_ptr) { + first_irq[irq&(QDIO_IRQ_BUCKETS-1)]=irq_ptr->next; + } else { + for (i_p=first_irq[irq&(QDIO_IRQ_BUCKETS-1)]; + i_p->next!=irq_ptr;i_p=i_p->next); + i_p->next=irq_ptr->next; + } + irq_ptr->next=NULL; +out: + write_unlock(&irq_list_lock[bucket]); +} + +static void qdio_release_irq_memory(qdio_irq_t *irq_ptr) +{ + int i,j; + int available; + + for (i=0;iinput_qs[i]) goto next; + available=0; + if (!irq_ptr->input_qs[i]->is_0copy_sbals_q) + for (j=0;jinput_qs[i]->sbal[j]) + kfree((void*)irq_ptr-> + input_qs[i]->sbal[j]); + available=PAGE_SIZE; + } + available-=sizeof(sbal_t); + } + if (irq_ptr->input_qs[i]->slib) + kfree(irq_ptr->input_qs[i]->slib); + kfree(irq_ptr->input_qs[i]); + +next: + if (!irq_ptr->output_qs[i]) continue; + available=0; + if (!irq_ptr->output_qs[i]->is_0copy_sbals_q) + for (j=0;joutput_qs[i]->sbal[j]) + kfree((void*)irq_ptr-> + output_qs[i]->sbal[j]); + available=PAGE_SIZE; + } + available-=sizeof(sbal_t); + } + if (irq_ptr->output_qs[i]->slib) + kfree(irq_ptr->output_qs[i]->slib); + kfree(irq_ptr->output_qs[i]); + + } + if (irq_ptr->qdr) kfree(irq_ptr->qdr); + kfree(irq_ptr); +} + +static inline void qdio_wakeup(atomic_t *var,qdio_irq_t *irq_ptr) +{ + wait_queue_head_t *wait_q; + +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[20]; + sprintf(dbf_text,"qwkp%4x",irq_ptr->irq); + QDIO_DBF_TEXT3(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + + atomic_set(var,1); + if ((wait_q=&irq_ptr->wait_q)) + wake_up(wait_q); +} + +static int qdio_sleepon(atomic_t *var,int timeout,qdio_irq_t *irq_ptr) +{ + __u64 stop; + int retval; + DECLARE_WAITQUEUE (current_wait_q,current); + +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[20]; + sprintf(dbf_text,"qslp%4x",irq_ptr->irq); + QDIO_DBF_TEXT3(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + + add_wait_queue(&irq_ptr->wait_q,¤t_wait_q); + stop=(qdio_get_micros()>>10)+timeout; + for (;;) { + set_task_state(current,TASK_INTERRUPTIBLE); + if (atomic_read(var)) { + atomic_set(var,0); + retval=0; + goto out; + } + if (qdio_get_micros()>>10>stop) { +#ifdef QDIO_DBF_LIKE_HELL + sprintf(dbf_text,"%xtime",irq_ptr->irq); + QDIO_DBF_TEXT3(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + retval=-ETIME; + goto out; + } + schedule_timeout(((stop-(qdio_get_micros()>>10))>>10)*HZ); + } + out: + set_task_state(current,TASK_RUNNING); + remove_wait_queue(&irq_ptr->wait_q,¤t_wait_q); + return retval; +} + +static void qdio_set_impl_params(qdio_irq_t *irq_ptr, + unsigned int qib_param_field_format, + /* pointer to 128 bytes or NULL, if no param field */ + unsigned char *qib_param_field, + unsigned int no_input_qs, + unsigned int no_output_qs, + /* pointer to no_queues*128 words of data or NULL */ + unsigned long *input_slib_elements, + unsigned long *output_slib_elements) +{ + int i,j; + + if (!irq_ptr) return; + + irq_ptr->qib.pfmt=qib_param_field_format; + if (qib_param_field) + memcpy(irq_ptr->qib.parm,qib_param_field, + QDIO_MAX_BUFFERS_PER_Q); + + if (input_slib_elements) + for (i=0;iinput_qs[i]->slib->slibe[j].parms= + input_slib_elements[ + i*QDIO_MAX_BUFFERS_PER_Q+j]; + } + if (output_slib_elements) + for (i=0;ioutput_qs[i]->slib->slibe[j].parms= + output_slib_elements[ + i*QDIO_MAX_BUFFERS_PER_Q+j]; + } +} + + + +static int qdio_alloc_qs(qdio_irq_t *irq_ptr,int no_input_qs,int no_output_qs, + qdio_handler_t *input_handler, + qdio_handler_t *output_handler, + unsigned long int_parm,int q_format, + unsigned long flags, + void **inbound_sbals_array, + void **outbound_sbals_array) +{ + qdio_q_t *q; + int i,j,result=0; + char dbf_text[20]; /* see qdio_initialize */ + void *ptr; + int available; + + for (i=0;islib=kmalloc(PAGE_SIZE,GFP_KERNEL); + if (!q->slib) { + QDIO_PRINT_ERR("kmalloc of slib failed!\n"); + goto out; + } + memset(q->slib,0,PAGE_SIZE); + q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2); + + available=0; + if (flags&QDIO_INBOUND_0COPY_SBALS) { + for (j=0;jsbal[j]=*(inbound_sbals_array++); + } + } else for (j=0;jsbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL); + if (!q->sbal[j]) { + goto out; + } + available=PAGE_SIZE; + memset((void*)q->sbal[j],0,PAGE_SIZE); + } else { + q->sbal[j]=(volatile sbal_t *) + (((char*)q->sbal[j-1])+sizeof(sbal_t)); + } + available-=sizeof(sbal_t); + } + + q->queue_type=q_format; + q->int_parm=int_parm; + irq_ptr->input_qs[i]=q; + q->irq=irq_ptr->irq; + q->irq_ptr=irq_ptr; + q->mask=1<<(31-i); + q->q_no=i; + q->is_input_q=1; + q->is_0copy_sbals_q=flags&QDIO_INBOUND_0COPY_SBALS; + q->first_to_check=0; + q->last_move_ftc=0; + q->handler=input_handler; + q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind; + + q->tasklet.data=(unsigned long)q; + /* q->is_thinint_q isn't valid at this time, but + * irq_ptr->is_thinint_irq is */ + q->tasklet.func=(void(*)(unsigned long)) + ((irq_ptr->is_thinint_irq)?&tiqdio_inbound_processing: + &qdio_inbound_processing); + +/* for (j=0;jtiming.last_transfer_times[j]=(qdio_get_micros()/ + QDIO_STATS_NUMBER)*j; + q->timing.last_transfer_index=QDIO_STATS_NUMBER-1; +*/ + + /* fill in slib */ + if (i>0) irq_ptr->input_qs[i-1]->slib->nsliba= + QDIO_PFIX_GET_ADDR(q->slib); + q->slib->sla=QDIO_PFIX_GET_ADDR(q->sl); + q->slib->slsba=QDIO_PFIX_GET_ADDR((void *)&q->slsb.acc.val[0]); + + /* fill in sl */ + for (j=0;jsl->element[j].sbal= + QDIO_PFIX_GET_ADDR((void *)q->sbal[j]); + + QDIO_DBF_TEXT2(0,setup,"sl-sb-b0"); + ptr=(void*)q->sl; + QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); + ptr=(void*)&q->slsb; + QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); + ptr=(void*)q->sbal[0]; + QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); + + /* fill in slsb */ + for (j=0;jslsb.acc.val[j], + SLSB_P_INPUT_NOT_INIT); + q->sbal[j]->element[1].sbalf.i1.key= + QDIO_STORAGE_ACC_KEY; + } + } + + for (i=0;islib=kmalloc(PAGE_SIZE,GFP_KERNEL); + if (!q->slib) { + QDIO_PRINT_ERR("kmalloc of slib failed!\n"); + goto out; + } + memset(q->slib,0,PAGE_SIZE); + q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2); + + available=0; + if (flags&QDIO_OUTBOUND_0COPY_SBALS) { + for (j=0;jsbal[j]=*(outbound_sbals_array++); + } + } else for (j=0;jsbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL); + if (!q->sbal[j]) { + goto out; + } + available=PAGE_SIZE; + memset((void*)q->sbal[j],0,PAGE_SIZE); + } else { + q->sbal[j]=(volatile sbal_t *) + (((char*)q->sbal[j-1])+sizeof(sbal_t)); + } + available-=sizeof(sbal_t); + } + + q->queue_type=q_format; + q->int_parm=int_parm; + irq_ptr->output_qs[i]=q; + q->is_input_q=0; + q->is_0copy_sbals_q=flags&QDIO_OUTBOUND_0COPY_SBALS; + q->irq=irq_ptr->irq; + q->irq_ptr=irq_ptr; + q->mask=1<<(31-i); + q->q_no=i; + q->first_to_check=0; + q->last_move_ftc=0; + q->handler=output_handler; + + q->tasklet.data=(unsigned long)q; + q->tasklet.func=(void(*)(unsigned long)) + &qdio_outbound_processing; + + /* fill in slib */ + if (i>0) irq_ptr->output_qs[i-1]->slib->nsliba= + QDIO_PFIX_GET_ADDR(q->slib); + q->slib->sla=QDIO_PFIX_GET_ADDR(q->sl); + q->slib->slsba=QDIO_PFIX_GET_ADDR((void *)&q->slsb.acc.val[0]); + + /* fill in sl */ + for (j=0;jsl->element[j].sbal= + QDIO_PFIX_GET_ADDR((void *)q->sbal[j]); + + QDIO_DBF_TEXT2(0,setup,"sl-sb-b0"); + ptr=(void*)q->sl; + QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); + ptr=(void*)&q->slsb; + QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); + ptr=(void*)q->sbal[0]; + QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); + + /* fill in slsb */ + for (j=0;jslsb.acc.val[j], + SLSB_P_OUTPUT_NOT_INIT); + q->sbal[j]->element[1].sbalf.i1.key= + QDIO_STORAGE_ACC_KEY; + } + } + + result=1; +out: + return result; +} + +static void qdio_fill_thresholds(qdio_irq_t *irq_ptr, + unsigned int no_input_qs, + unsigned int no_output_qs, + unsigned int min_input_threshold, + unsigned int max_input_threshold, + unsigned int min_output_threshold, + unsigned int max_output_threshold) +{ + int i; + qdio_q_t *q; + + for (i=0;iinput_qs[i]; + q->timing.threshold=max_input_threshold; +/* for (j=0;jthreshold_classes[j].threshold= + min_input_threshold+ + (max_input_threshold-min_input_threshold)/ + QDIO_STATS_CLASSES; + } + qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/ + } + for (i=0;ioutput_qs[i]; + q->timing.threshold=max_output_threshold; +/* for (j=0;jthreshold_classes[j].threshold= + min_output_threshold+ + (max_output_threshold-min_output_threshold)/ + QDIO_STATS_CLASSES; + } + qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/ + } +} + +static int tiqdio_thinint_handler(__u32 intparm) +{ +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT4(0,trace,"thin_int"); +#endif /* QDIO_DBF_LIKE_HELL */ + +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.thinints++; + perf_stats.start_time_inbound=NOW; +#endif /* QDIO_PERFORMANCE_STATS */ + + /* VM will do the SVS for us + * issue SVS to benefit from iqdio interrupt avoidance (SVS clears AISOI)*/ + if (!MACHINE_IS_VM) { + tiqdio_clear_global_summary(); + } + + tiqdio_inbound_checks(); + return 0; +} + +static void qdio_set_state(qdio_irq_t *irq_ptr,int state) +{ + int i; + char dbf_text[15]; + + QDIO_DBF_TEXT5(0,trace,"newstate"); + sprintf(dbf_text,"%4x%4x",irq_ptr->irq,state); + QDIO_DBF_TEXT5(0,trace,dbf_text); + + irq_ptr->state=state; + for (i=0;ino_input_qs;i++) + irq_ptr->input_qs[i]->state=state; + for (i=0;ino_output_qs;i++) + irq_ptr->output_qs[i]->state=state; + mb(); +} + +static void qdio_handler(int irq,devstat_t *devstat,struct pt_regs *p) +{ + qdio_irq_t *irq_ptr; + qdio_q_t *q; + int i; + int cstat,dstat; + int rqparam; + char dbf_text[15]="qintXXXX"; + + cstat = devstat->cstat; + dstat = devstat->dstat; + rqparam=devstat->intparm; + + *((int*)(&dbf_text[4]))=irq; + QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); + + if (!rqparam) { + QDIO_PRINT_STUPID("got unsolicited interrupt in qdio " \ + "handler, irq 0x%x\n",irq); + return; + } + + irq_ptr=qdio_get_irq_ptr(irq); + if (!irq_ptr) { + sprintf(dbf_text,"uint%4x",irq); + QDIO_DBF_TEXT2(1,trace,dbf_text); + QDIO_PRINT_ERR("received interrupt on unused irq 0x%04x!\n", + irq); + return; + } + + if (devstat->flag&DEVSTAT_FLAG_SENSE_AVAIL) { + sprintf(dbf_text,"sens%4x",irq); + QDIO_DBF_TEXT2(1,trace,dbf_text); + QDIO_DBF_HEX0(0,sense,&devstat->ii.irb,QDIO_DBF_SENSE_LEN); + + QDIO_PRINT_WARN("sense data available on qdio channel.\n"); + HEXDUMP16(WARN,"irb: ",&devstat->ii.irb); + HEXDUMP16(WARN,"sense data: ",&devstat->ii.sense.data[0]); + } + + irq_ptr->io_result_cstat=ioinfo[irq]->devstat.cstat; + irq_ptr->io_result_dstat=ioinfo[irq]->devstat.dstat; + irq_ptr->io_result_flags=ioinfo[irq]->devstat.flag; + + if ( (rqparam==QDIO_DOING_ACTIVATE) && + (cstat & SCHN_STAT_PCI) ) { +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.pcis++; + perf_stats.start_time_inbound=NOW; +#endif /* QDIO_PERFORMANCE_STATS */ + for (i=0;ino_input_qs;i++) { + q=irq_ptr->input_qs[i]; + if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) + qdio_mark_q(q); + else { +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs--; +#endif /* QDIO_PERFORMANCE_STATS */ + qdio_inbound_processing(q); + } + } + if (irq_ptr->hydra_gives_outbound_pcis) { + for (i=0;ino_output_qs;i++) { + q=irq_ptr->output_qs[i]; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs--; +#endif /* QDIO_PERFORMANCE_STATS */ + if (!qdio_is_outbound_q_done(q)) { + if (!irq_ptr->sync_done_on_outb_pcis) { + SYNC_MEMORY; + } + qdio_outbound_processing(q); + } + } + } + return; + } + + if ( (rqparam==QDIO_DOING_ACTIVATE) && + (!cstat) && + (!dstat) ) { + rqparam=QDIO_DOING_CLEANUP; + } + + if ( (rqparam==QDIO_DOING_ESTABLISH) && + ( (cstat) || + (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ) ) { + sprintf(dbf_text,"ick1%4x",irq); + QDIO_DBF_TEXT2(1,trace,dbf_text); + QDIO_DBF_HEX2(0,trace,&rqparam,sizeof(int)); + QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int)); + QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int)); + QDIO_PRINT_ERR("received check condition on establish " \ + "queues on irq 0x%x (cs=x%x, ds=x%x).\n", + irq,cstat,dstat); + qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED); + return; + } + + if ( ( (rqparam==QDIO_DOING_ACTIVATE) && + (dstat==(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ) || + ( (rqparam==QDIO_DOING_CLEANUP) || (!rqparam) ) ) { + qdio_wakeup(&irq_ptr->interrupt_has_been_cleaned,irq_ptr); + return; + } + + if ( (rqparam==QDIO_DOING_ACTIVATE) && + ( (cstat & ~SCHN_STAT_PCI) || + (dstat) ) ) { + sprintf(dbf_text,"ick2%4x",irq); + QDIO_DBF_TEXT2(1,trace,dbf_text); + QDIO_DBF_HEX2(0,trace,&rqparam,sizeof(int)); + QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int)); + QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int)); + QDIO_PRINT_ERR("received check condition on activate " \ + "queues on irq 0x%x (cs=x%x, ds=x%x).\n", + irq,cstat,dstat); + if (irq_ptr->no_input_qs) { + q=irq_ptr->input_qs[0]; + } else if (irq_ptr->no_output_qs) { + q=irq_ptr->output_qs[0]; + } else { + QDIO_PRINT_ERR("oops... no queue registered on irq " \ + "0x%x!?\n",irq); + goto omit_handler_call; + } + q->handler(q->irq,QDIO_STATUS_ACTIVATE_CHECK_CONDITION| + QDIO_STATUS_LOOK_FOR_ERROR, + 0,0,0,-1,-1,q->int_parm); + omit_handler_call: + qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED); + return; + } + + qdio_wakeup(&irq_ptr->interrupt_has_arrived,irq_ptr); +} + +/* this is for mp3 */ +int qdio_synchronize(int irq,unsigned int flags, + unsigned int queue_number) +{ + unsigned int gpr2,gpr3; + int cc; + qdio_q_t *q; + qdio_irq_t *irq_ptr; + char dbf_text[15]="SyncXXXX"; + void *ptr; + + *((int*)(&dbf_text[4]))=irq; + QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); + *((int*)(&dbf_text[0]))=flags; + *((int*)(&dbf_text[4]))=queue_number; + QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); + + irq_ptr=qdio_get_irq_ptr(irq); + if (!irq_ptr) return -ENODEV; + + if (flags&QDIO_FLAG_SYNC_INPUT) { + q=irq_ptr->input_qs[queue_number]; + if (!q) return -EINVAL; + + gpr2=0; + gpr3=q->mask; + } else if (flags&QDIO_FLAG_SYNC_OUTPUT) { + q=irq_ptr->output_qs[queue_number]; + if (!q) return -EINVAL; + + gpr2=q->mask; + gpr3=0; + } else return -EINVAL; + +#ifdef QDIO_32_BIT + asm volatile ( + "lhi 0,2 \n\t" + "lr 1,%1 \n\t" + "lr 2,%2 \n\t" + "lr 3,%3 \n\t" + "siga 0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) + : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3) + : "cc", "0", "1", "2", "3" + ); +#else /* QDIO_32_BIT */ + asm volatile ( + "lghi 0,2 \n\t" + "llgfr 1,%1 \n\t" + "llgfr 2,%2 \n\t" + "llgfr 3,%3 \n\t" + "siga 0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) + : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3) + : "cc", "0", "1", "2", "3" + ); +#endif /* QDIO_32_BIT */ + + ptr=&cc; + if (cc) QDIO_DBF_HEX3(0,trace,&ptr,sizeof(int)); + + return cc; +} + +unsigned char qdio_get_slsb_state(int irq,unsigned int flag, + unsigned int queue_number, + unsigned int qidx) +{ + qdio_irq_t *irq_ptr; + qdio_q_t *q; + + irq_ptr=qdio_get_irq_ptr(irq); + if (!irq_ptr) return SLSB_ERROR_DURING_LOOKUP; + + if (flag&QDIO_FLAG_SYNC_INPUT) { + q=irq_ptr->input_qs[queue_number]; + } else if (flag&QDIO_FLAG_SYNC_OUTPUT) { + q=irq_ptr->output_qs[queue_number]; + } else return SLSB_ERROR_DURING_LOOKUP; + + return q->slsb.acc.val[qidx&(QDIO_MAX_BUFFERS_PER_Q-1)]; +} + +static int qdio_chsc(qdio_chsc_area_t *chsc_area) +{ + int cc; + +#ifdef QDIO_32_BIT + asm volatile ( + ".insn rre,0xb25f0000,%1,0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) : "d" (chsc_area) : "cc" + ); +#else /* QDIO_32_BIT */ + asm volatile ( + ".insn rre,0xb25f0000,%1,0 \n\t" + "ipm %0 \n\t" + "srl %0,28 \n\t" + : "=d" (cc) : "d" (chsc_area) : "cc" + ); +#endif /* QDIO_32_BIT */ + + return cc; +} + +static unsigned char qdio_check_siga_needs(int sch) +{ + int resp_code,result; + + memset(chsc_area,0,sizeof(qdio_chsc_area_t)); + chsc_area->request_block.command_code1=0x0010; /* length */ + chsc_area->request_block.command_code2=0x0024; /* op code */ + chsc_area->request_block.first_sch=sch; + chsc_area->request_block.last_sch=sch; + + result=qdio_chsc(chsc_area); + + if (result) { + QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \ + "SIGAs for sch x%x.\n", + result,sch); + return -1; /* all flags set */ + } + + resp_code=chsc_area->request_block.operation_data_area. + store_qdio_data_response.response_code; + if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) { + QDIO_PRINT_WARN("response upon checking SIGA needs " \ + "is 0x%x. Using all SIGAs for sch x%x.\n", + resp_code,sch); + return -1; /* all flags set */ + } + if ( + (!(chsc_area->request_block.operation_data_area. + store_qdio_data_response.flags&CHSC_FLAG_QDIO_CAPABILITY)) || + (!(chsc_area->request_block.operation_data_area. + store_qdio_data_response.flags&CHSC_FLAG_VALIDITY)) || + (chsc_area->request_block.operation_data_area. + store_qdio_data_response.sch!=sch) + ) { + QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \ + "using all SIGAs.\n",sch); + return CHSC_FLAG_SIGA_INPUT_NECESSARY | + CHSC_FLAG_SIGA_OUTPUT_NECESSARY | + CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */ + } + + return chsc_area->request_block.operation_data_area. + store_qdio_data_response.qdioac; +} + +static int qdio_check_for_hydra_thinints(void) +{ + int i,result; + + memset(chsc_area,0,sizeof(qdio_chsc_area_t)); + chsc_area->request_block.command_code1=0x0010; + chsc_area->request_block.command_code2=0x0010; + result=qdio_chsc(chsc_area); + + if (result) { + QDIO_PRINT_WARN("CHSC returned cc %i. Won't use adapter " \ + "interrupts for any Hydra.\n",result); + return 0; + } + + i=chsc_area->request_block.operation_data_area. + store_qdio_data_response.response_code; + if (i!=1) { + QDIO_PRINT_WARN("Was not able to determine general " \ + "characteristics of all Hydras aboard.\n"); + return 0; + } + + /* 4: request block + * 2: general char + * 512: chsc char */ + /* check for bit 67 */ + if ( (*(((unsigned int*)(chsc_area))+4+2+2)&0x10000000)!=0x10000000) { + return 0; + } else { + return 1; + } +} + +/* the chsc_area is locked by the lock in qdio_activate */ +static unsigned int tiqdio_check_chsc_availability(void) { + int result; + int i; + + memset(chsc_area,0,sizeof(qdio_chsc_area_t)); + chsc_area->request_block.command_code1=0x0010; + chsc_area->request_block.command_code2=0x0010; + result=qdio_chsc(chsc_area); + if (result) { + QDIO_PRINT_WARN("Was not able to determine " \ + "available CHSCs, cc=%i.\n", + result); + result=-EIO; + goto exit; + } + result=0; + i=chsc_area->request_block.operation_data_area. + store_qdio_data_response.response_code; + if (i!=1) { + QDIO_PRINT_WARN("Was not able to determine " \ + "available CHSCs.\n"); + result=-EIO; + goto exit; + } + /* 4: request block + * 2: general char + * 512: chsc char */ + /* check for bit 41 */ + if ( (*(((unsigned int*)(chsc_area))+4+2+1)&0x00400000)!=0x00400000) { + QDIO_PRINT_WARN("Adapter interruption facility not " \ + "installed.\n"); + result=-ENOENT; + goto exit; + } + /* check for bits 107 and 108 */ + if ( (*(((unsigned int*)(chsc_area))+4+512+3)&0x00180000)!= + 0x00180000 ) { + QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \ + "not available.\n"); + result=-ENOENT; + goto exit; + } +exit: + return result; +} + +/* the chsc_area is locked by the lock in qdio_activate */ +static unsigned int tiqdio_set_subchannel_ind(qdio_irq_t *irq_ptr, + int reset_to_zero) +{ + unsigned long real_addr_local_summary_bit; + unsigned long real_addr_dev_st_chg_ind; + void *ptr; + char dbf_text[15]; + + unsigned int resp_code; + int result; + + if (!irq_ptr->is_thinint_irq) return -ENODEV; + + if (reset_to_zero) { + real_addr_local_summary_bit=0; + real_addr_dev_st_chg_ind=0; + } else { + real_addr_local_summary_bit= + virt_to_phys((volatile void *)indicators); + real_addr_dev_st_chg_ind= + virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind); + } + + memset(chsc_area,0,sizeof(qdio_chsc_area_t)); + chsc_area->request_block.command_code1=0x0fe0; + chsc_area->request_block.command_code2=0x0021; + chsc_area->request_block.operation_code=0; + chsc_area->request_block.image_id=0; + + chsc_area->request_block.operation_data_area.set_chsc. + summary_indicator_addr=real_addr_local_summary_bit; + chsc_area->request_block.operation_data_area.set_chsc. + subchannel_indicator_addr=real_addr_dev_st_chg_ind; + chsc_area->request_block.operation_data_area.set_chsc. + ks=QDIO_STORAGE_ACC_KEY; + chsc_area->request_block.operation_data_area.set_chsc. + kc=QDIO_STORAGE_ACC_KEY; + chsc_area->request_block.operation_data_area.set_chsc. + isc=TIQDIO_THININT_ISC; + chsc_area->request_block.operation_data_area.set_chsc. + subsystem_id=(1<<16)+irq_ptr->irq; + + result=qdio_chsc(chsc_area); + if (result) { + QDIO_PRINT_WARN("could not set indicators on irq x%x, " \ + "cc=%i.\n",irq_ptr->irq,result); + return -EIO; + } + + resp_code=chsc_area->response_block.response_code; + if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) { + QDIO_PRINT_WARN("response upon setting indicators " \ + "is 0x%x.\n",resp_code); + sprintf(dbf_text,"sidR%4x",resp_code); + QDIO_DBF_TEXT1(0,trace,dbf_text); + QDIO_DBF_TEXT1(0,setup,dbf_text); + ptr=&chsc_area->response_block; + QDIO_DBF_HEX2(1,setup,&ptr,QDIO_DBF_SETUP_LEN); + return -EIO; + } + + QDIO_DBF_TEXT2(0,setup,"setscind"); + QDIO_DBF_HEX2(0,setup,&real_addr_local_summary_bit, + sizeof(unsigned long)); + QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long)); + return 0; +} + +/* chsc_area would have to be locked if called from outside qdio_activate */ +static unsigned int tiqdio_set_delay_target(qdio_irq_t *irq_ptr, + unsigned long delay_target) +{ + unsigned int resp_code; + int result; + void *ptr; + char dbf_text[15]; + + if (!irq_ptr->is_thinint_irq) return -ENODEV; + + memset(chsc_area,0,sizeof(qdio_chsc_area_t)); + chsc_area->request_block.command_code1=0x0fe0; + chsc_area->request_block.command_code2=0x1027; + chsc_area->request_block.operation_data_area.set_chsc_fast. + delay_target=delay_target<<16; + + result=qdio_chsc(chsc_area); + if (result) { + QDIO_PRINT_WARN("could not set delay target on irq x%x, " \ + "cc=%i. Continuing.\n",irq_ptr->irq,result); + return -EIO; + } + + resp_code=chsc_area->response_block.response_code; + if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) { + QDIO_PRINT_WARN("response upon setting delay target " \ + "is 0x%x. Continuing.\n",resp_code); + sprintf(dbf_text,"sdtR%4x",resp_code); + QDIO_DBF_TEXT1(0,trace,dbf_text); + QDIO_DBF_TEXT1(0,setup,dbf_text); + ptr=&chsc_area->response_block; + QDIO_DBF_HEX2(1,trace,&ptr,QDIO_DBF_TRACE_LEN); + } + QDIO_DBF_TEXT2(0,trace,"delytrgt"); + QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long)); + return 0; +} + +int qdio_cleanup(int irq,int how) +{ + qdio_irq_t *irq_ptr; + int i,result; + int do_an_irqrestore=0; + unsigned long flags; + int timeout; + char dbf_text[15]="12345678"; + + result=0; + sprintf(dbf_text,"qcln%4x",irq); + QDIO_DBF_TEXT1(0,trace,dbf_text); + QDIO_DBF_TEXT0(0,setup,dbf_text); + + irq_ptr=qdio_get_irq_ptr(irq); + if (!irq_ptr) return -ENODEV; + + spin_lock(&irq_ptr->setting_up_lock); + + /* mark all qs as uninteresting */ + for (i=0;ino_input_qs;i++) { + atomic_set(&irq_ptr->input_qs[i]->is_in_shutdown,1); + } + for (i=0;ino_output_qs;i++) { + atomic_set(&irq_ptr->output_qs[i]->is_in_shutdown,1); + } + + tasklet_kill(&tiqdio_tasklet); + + for (i=0;ino_input_qs;i++) { + qdio_unmark_q(irq_ptr->input_qs[i]); + tasklet_kill(&irq_ptr->input_qs[i]->tasklet); + if (qdio_wait_for_no_use_count(&irq_ptr->input_qs[i]-> + use_count)) + result=-EINPROGRESS; + } + + for (i=0;ino_output_qs;i++) { + tasklet_kill(&irq_ptr->output_qs[i]->tasklet); + if (qdio_wait_for_no_use_count(&irq_ptr->output_qs[i]-> + use_count)) + result=-EINPROGRESS; + } + + atomic_set(&irq_ptr->interrupt_has_been_cleaned,0); + + /* cleanup subchannel */ + s390irq_spin_lock_irqsave(irq,flags); + if (how&QDIO_FLAG_CLEANUP_USING_CLEAR) { + clear_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0); + timeout=QDIO_CLEANUP_CLEAR_TIMEOUT; + } else if (how&QDIO_FLAG_CLEANUP_USING_HALT) { + halt_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0); + timeout=QDIO_CLEANUP_HALT_TIMEOUT; + } else { /* default behaviour */ + halt_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0); + timeout=QDIO_CLEANUP_HALT_TIMEOUT; + } + s390irq_spin_unlock_irqrestore(irq,flags); + + if (qdio_sleepon(&irq_ptr->interrupt_has_been_cleaned, + timeout,irq_ptr)==-ETIME) { + s390irq_spin_lock_irqsave(irq,flags); + QDIO_PRINT_INFO("Did not get interrupt on %s_IO, " \ + "irq=0x%x.\n", + (how==QDIO_FLAG_CLEANUP_USING_CLEAR)? + "clear":"halt",irq); + do_an_irqrestore=1; + } + + if (irq_ptr->is_thinint_irq) { + qdio_put_indicator((__u32*)irq_ptr->dev_st_chg_ind); + tiqdio_set_subchannel_ind(irq_ptr,1); /* reset adapter + interrupt indicators */ + } + + /* exchange int handlers, if necessary */ + if ((void*)ioinfo[irq]->irq_desc.handler + ==(void*)qdio_handler) { + ioinfo[irq]->irq_desc.handler= + irq_ptr->original_int_handler; +/* irq_ptr->original_int_handler=NULL; */ + } + + qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE); + + if (do_an_irqrestore) + s390irq_spin_unlock_irqrestore(irq,flags); + + spin_unlock(&irq_ptr->setting_up_lock); + + qdio_remove_irq_ptr(irq_ptr); + qdio_release_irq_memory(irq_ptr); + + QDIO_DBF_TEXT3(0,setup,"MOD_DEC_"); + MOD_DEC_USE_COUNT; + + return result; +} + +unsigned long qdio_get_characteristics(int irq) +{ + qdio_irq_t *irq_ptr; + int result=0; + + irq_ptr=qdio_get_irq_ptr(irq); + if (!irq_ptr) return -ENODEV; + + if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) { + return -EBUSY; + } + + if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) { + result|=QDIO_STATE_INACTIVE; + } else if (irq_ptr->state==QDIO_IRQ_STATE_ESTABLISHED) { + result|=QDIO_STATE_ESTABLISHED; + } else if (irq_ptr->state==QDIO_IRQ_STATE_ACTIVE) { + result|=QDIO_STATE_ACTIVE; + } else if (irq_ptr->state==QDIO_IRQ_STATE_STOPPED) { + result|=QDIO_STATE_STOPPED; + } + + if (irq_ptr->hydra_gives_outbound_pcis) + result|=QDIO_STATE_MUST_USE_OUTB_PCI; + + return result; +} + +int qdio_initialize(qdio_initialize_t *init_data) +{ + int i,ciw_cnt; + unsigned long saveflags; + qdio_irq_t *irq_ptr=NULL; + int result,result2; + int found; + unsigned long flags; + char dbf_text[20]; /* if a printf would print out more than 8 chars */ + + down_interruptible(&init_sema); + + sprintf(dbf_text,"qini%4x",init_data->irq); + QDIO_DBF_TEXT0(0,setup,dbf_text); + QDIO_DBF_TEXT0(0,trace,dbf_text); + sprintf(dbf_text,"qfmt:%x",init_data->q_format); + QDIO_DBF_TEXT0(0,setup,dbf_text); + QDIO_DBF_TEXT0(0,setup,init_data->adapter_name); + QDIO_DBF_HEX0(0,setup,init_data->adapter_name,8); + sprintf(dbf_text,"qpff%4x",init_data->qib_param_field_format); + QDIO_DBF_TEXT0(0,setup,dbf_text); + QDIO_DBF_HEX0(0,setup,&init_data->qib_param_field,sizeof(char*)); + QDIO_DBF_HEX0(0,setup,&init_data->input_slib_elements,sizeof(long*)); + QDIO_DBF_HEX0(0,setup,&init_data->output_slib_elements,sizeof(long*)); + sprintf(dbf_text,"miit%4x",init_data->min_input_threshold); + QDIO_DBF_TEXT0(0,setup,dbf_text); + sprintf(dbf_text,"mait%4x",init_data->min_input_threshold); + QDIO_DBF_TEXT0(0,setup,dbf_text); + sprintf(dbf_text,"miot%4x",init_data->max_output_threshold); + QDIO_DBF_TEXT0(0,setup,dbf_text); + sprintf(dbf_text,"maot%4x",init_data->max_output_threshold); + QDIO_DBF_TEXT0(0,setup,dbf_text); + sprintf(dbf_text,"niq:%4x",init_data->no_input_qs); + QDIO_DBF_TEXT0(0,setup,dbf_text); + sprintf(dbf_text,"noq:%4x",init_data->no_output_qs); + QDIO_DBF_TEXT0(0,setup,dbf_text); + QDIO_DBF_HEX0(0,setup,&init_data->input_handler,sizeof(void*)); + QDIO_DBF_HEX0(0,setup,&init_data->output_handler,sizeof(void*)); + QDIO_DBF_HEX0(0,setup,&init_data->int_parm,sizeof(long)); + QDIO_DBF_HEX0(0,setup,&init_data->flags,sizeof(long)); + QDIO_DBF_HEX0(0,setup,&init_data->input_sbal_addr_array,sizeof(void*)); + QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*)); + flags=init_data->flags; + + /* sanity checks */ + if (qdio_get_irq_ptr(init_data->irq)) { + result=-EBUSY; + goto out; + } + + if (ioinfo[init_data->irq]==INVALID_STORAGE_AREA) { + result=-ENODEV; + goto out; + } + + if (!ioinfo[init_data->irq]) { + QDIO_PRINT_WARN("ioinfo[%i] is NULL!\n",init_data->irq); + result=-ENODEV; + goto out; + } + +#define DEVSTAT_FLAG_IRQ_QDIO ~0UL + if (!(ioinfo[init_data->irq]->devstat.flag&DEVSTAT_FLAG_IRQ_QDIO)) { + QDIO_PRINT_WARN("ioinfo[%i]->devstat.flag=0x%08x\n", + init_data->irq, + ioinfo[init_data->irq]->devstat.flag); + result=-ENODEV; + goto out; + } + + if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || + (init_data->no_output_qs>QDIO_MAX_QUEUES_PER_IRQ) || + ((init_data->no_input_qs) && (!init_data->input_handler)) || + ((init_data->no_output_qs) && (!init_data->output_handler)) ) { + result=-EINVAL; + goto out; + } + + if ( (init_data->flags&QDIO_INBOUND_0COPY_SBALS)&& + (!init_data->input_sbal_addr_array) ) { + result=-EINVAL; + goto out; + } + if ( (init_data->flags&QDIO_OUTBOUND_0COPY_SBALS)&& + (!init_data->output_sbal_addr_array) ) { + result=-EINVAL; + goto out; + } + + /* create irq */ + irq_ptr=kmalloc(sizeof(qdio_irq_t),GFP_DMA); + + QDIO_DBF_TEXT0(0,setup,"irq_ptr:"); + QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*)); + + if (!irq_ptr) { + QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n"); + result=-ENOMEM; + goto out; + } + + memset(irq_ptr,0,sizeof(qdio_irq_t)); /* wipes qib.ac, + required by ar7063 */ + + irq_ptr->qdr=kmalloc(sizeof(qdr_t),GFP_DMA); + if (!(irq_ptr->qdr)) { + kfree(irq_ptr->qdr); + kfree(irq_ptr); + QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n"); + result=-ENOMEM; + goto out; + } + memset(irq_ptr->qdr,0,sizeof(qdr_t)); + QDIO_DBF_TEXT0(0,setup,"qdr:"); + QDIO_DBF_HEX0(0,setup,&irq_ptr->qdr,sizeof(void*)); + + init_waitqueue_head(&irq_ptr->wait_q); + + irq_ptr->int_parm=init_data->int_parm; + + irq_ptr->irq=init_data->irq; + irq_ptr->no_input_qs=init_data->no_input_qs; + irq_ptr->no_output_qs=init_data->no_output_qs; + + if (init_data->q_format==QDIO_IQDIO_QFMT) { + irq_ptr->is_iqdio_irq=1; + irq_ptr->is_thinint_irq=1; + } else { + irq_ptr->is_iqdio_irq=0; + irq_ptr->is_thinint_irq=hydra_thinints; + } + sprintf(dbf_text,"is_i_t%1x%1x", + irq_ptr->is_iqdio_irq,irq_ptr->is_thinint_irq); + QDIO_DBF_TEXT2(0,setup,dbf_text); + + if (irq_ptr->is_thinint_irq) { + irq_ptr->dev_st_chg_ind=qdio_get_indicator(); + QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*)); + if (!irq_ptr->dev_st_chg_ind) { + QDIO_PRINT_WARN("no indicator location available " \ + "for irq 0x%x\n",irq_ptr->irq); + qdio_release_irq_memory(irq_ptr); + result=-ENOBUFS; + goto out; + } + } + + if (flags&QDIO_PFIX) + irq_ptr->other_flags |= QDIO_PFIX; + + /* defaults */ + irq_ptr->commands.eq=DEFAULT_ESTABLISH_QS_CMD; + irq_ptr->commands.count_eq=DEFAULT_ESTABLISH_QS_COUNT; + irq_ptr->commands.aq=DEFAULT_ACTIVATE_QS_CMD; + irq_ptr->commands.count_aq=DEFAULT_ACTIVATE_QS_COUNT; + + if (!qdio_alloc_qs(irq_ptr,init_data->no_input_qs, + init_data->no_output_qs, + init_data->input_handler, + init_data->output_handler,init_data->int_parm, + init_data->q_format,init_data->flags, + init_data->input_sbal_addr_array, + init_data->output_sbal_addr_array)) { + qdio_release_irq_memory(irq_ptr); + result=-ENOMEM; + goto out; + } + + qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE); + + irq_ptr->setting_up_lock=SPIN_LOCK_UNLOCKED; + + MOD_INC_USE_COUNT; + QDIO_DBF_TEXT3(0,setup,"MOD_INC_"); + + spin_lock(&irq_ptr->setting_up_lock); + + qdio_insert_irq_ptr(irq_ptr); + + qdio_fill_thresholds(irq_ptr,init_data->no_input_qs, + init_data->no_output_qs, + init_data->min_input_threshold, + init_data->max_input_threshold, + init_data->min_output_threshold, + init_data->max_output_threshold); + + /* fill in qdr */ + irq_ptr->qdr->qfmt=init_data->q_format; + irq_ptr->qdr->iqdcnt=init_data->no_input_qs; + irq_ptr->qdr->oqdcnt=init_data->no_output_qs; + irq_ptr->qdr->iqdsz=sizeof(qdesfmt0_t)/4; /* size in words */ + irq_ptr->qdr->oqdsz=sizeof(qdesfmt0_t)/4; + + irq_ptr->qdr->qiba=QDIO_PFIX_GET_ADDR(&irq_ptr->qib); + irq_ptr->qdr->qkey=QDIO_STORAGE_ACC_KEY; + + /* fill in qib */ + irq_ptr->qib.qfmt=init_data->q_format; + if (init_data->no_input_qs) irq_ptr->qib.isliba= + QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[0]->slib); + if (init_data->no_output_qs) irq_ptr->qib.osliba=(unsigned long) + QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[0]->slib); + memcpy(irq_ptr->qib.ebcnam,init_data->adapter_name,8); + + qdio_set_impl_params(irq_ptr,init_data->qib_param_field_format, + init_data->qib_param_field, + init_data->no_input_qs, + init_data->no_output_qs, + init_data->input_slib_elements, + init_data->output_slib_elements); + + /* first input descriptors, then output descriptors */ + for (i=0;ino_input_qs;i++) { + irq_ptr->input_qs[i]->is_iqdio_q= + (init_data->q_format==QDIO_IQDIO_QFMT)?1:0; + irq_ptr->input_qs[i]->is_thinint_q=irq_ptr->is_thinint_irq; + + irq_ptr->qdr->qdf0[i].sliba= + QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[i]->slib); + + irq_ptr->qdr->qdf0[i].sla= + QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[i]->sl); + + irq_ptr->qdr->qdf0[i].slsba= + QDIO_PFIX_GET_ADDR + ((void *)&irq_ptr->input_qs[i]->slsb.acc.val[0]); + + irq_ptr->qdr->qdf0[i].akey=QDIO_STORAGE_ACC_KEY; + irq_ptr->qdr->qdf0[i].bkey=QDIO_STORAGE_ACC_KEY; + irq_ptr->qdr->qdf0[i].ckey=QDIO_STORAGE_ACC_KEY; + irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_ACC_KEY; + } + + for (i=0;ino_output_qs;i++) { + irq_ptr->output_qs[i]->is_iqdio_q= + (init_data->q_format==QDIO_IQDIO_QFMT)?1:0; + irq_ptr->output_qs[i]->is_thinint_q=irq_ptr->is_thinint_irq; + + irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sliba= + QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[i]->slib); + + irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sla= + QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[i]->sl); + + irq_ptr->qdr->qdf0[i+init_data->no_input_qs].slsba= + QDIO_PFIX_GET_ADDR + ((void *)&irq_ptr->output_qs[i]->slsb.acc.val[0]); + + irq_ptr->qdr->qdf0[i+init_data->no_input_qs].akey= + QDIO_STORAGE_ACC_KEY; + irq_ptr->qdr->qdf0[i+init_data->no_input_qs].bkey= + QDIO_STORAGE_ACC_KEY; + irq_ptr->qdr->qdf0[i+init_data->no_input_qs].ckey= + QDIO_STORAGE_ACC_KEY; + irq_ptr->qdr->qdf0[i+init_data->no_input_qs].dkey= + QDIO_STORAGE_ACC_KEY; + } + /* qdr, qib, sls, slsbs, slibs, sbales filled. */ + + s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags); + /* keep track of original int handler */ + irq_ptr->original_int_handler=ioinfo[irq_ptr->irq]->irq_desc.handler; + + /* insert qdio int handler */ + ioinfo[irq_ptr->irq]->irq_desc.handler=(void*)qdio_handler; + + s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags); + +#define TAKEOVER_CIW(x) irq_ptr->commands.x=ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].cmd; irq_ptr->commands.count_##x=ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].count + /* get qdio commands */ + found=0; + for (ciw_cnt=0;ciw_cntirq]->senseid.ciw[ciw_cnt].ct) { + case CIW_TYPE_RCD: TAKEOVER_CIW(rcd); break; + case CIW_TYPE_SII: TAKEOVER_CIW(sii); break; + case CIW_TYPE_RNI: TAKEOVER_CIW(rni); break; + case CIW_TYPE_EQUEUE: TAKEOVER_CIW(eq); found++; break; + case CIW_TYPE_AQUEUE: TAKEOVER_CIW(aq); found++; break; + } + if ( (ciw_cnt>0) && + (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].ct==0) && + (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].cmd==0) && + (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].count) ) + break; + } + if (found<2) { + QDIO_DBF_TEXT2(1,setup,"no ciws"); + QDIO_PRINT_INFO("No CIWs found for QDIO commands. Trying to " \ + "use defaults.\n"); + } + + /* the thinint CHSC stuff */ + if (irq_ptr->is_thinint_irq) { +/* iqdio_enable_adapter_int_facility(irq_ptr);*/ + + if (tiqdio_check_chsc_availability()) { + QDIO_PRINT_ERR("Not all CHSCs supported. " \ + "Continuing.\n"); + } + result=tiqdio_set_subchannel_ind(irq_ptr,0); + if (result) { + spin_unlock(&irq_ptr->setting_up_lock); + qdio_cleanup(irq_ptr->irq, + QDIO_FLAG_CLEANUP_USING_CLEAR); + goto out2; + } + tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); + } + + /* establish q */ + irq_ptr->ccw.cmd_code=irq_ptr->commands.eq; + irq_ptr->ccw.flags=CCW_FLAG_SLI; + irq_ptr->ccw.count=irq_ptr->commands.count_eq; + irq_ptr->ccw.cda=QDIO_GET_32BIT_ADDR(QDIO_PFIX_GET_ADDR(irq_ptr->qdr)); + + s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags); + atomic_set(&irq_ptr->interrupt_has_arrived,0); + + result=do_IO(irq_ptr->irq,&irq_ptr->ccw,QDIO_DOING_ESTABLISH,0, + ((irq_ptr->other_flags&QDIO_PFIX)?DOIO_USE_DIAG98:0)); + if (result) { + result2=do_IO(irq_ptr->irq,&irq_ptr->ccw, + QDIO_DOING_ESTABLISH,0, + ((irq_ptr->other_flags&QDIO_PFIX)? + DOIO_USE_DIAG98:0)); + sprintf(dbf_text,"eq:io%4x",result); + QDIO_DBF_TEXT2(1,setup,dbf_text); + if (result2) { + sprintf(dbf_text,"eq:io%4x",result); + QDIO_DBF_TEXT2(1,setup,dbf_text); + } + QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \ + "returned %i, next try returned %i\n", + irq_ptr->irq,result,result2); + result=result2; + } + + s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags); + + if (result) { + spin_unlock(&irq_ptr->setting_up_lock); + qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR); + goto out2; + } + + result=qdio_sleepon(&irq_ptr->interrupt_has_arrived, + QDIO_ESTABLISH_TIMEOUT,irq_ptr); + + if (result) { + QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n", + irq_ptr->irq); + QDIO_DBF_TEXT2(1,setup,"eq:timeo"); + spin_unlock(&irq_ptr->setting_up_lock); + qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR); + goto out2; + } + + if (!(irq_ptr->io_result_dstat & DEV_STAT_DEV_END)) { + QDIO_DBF_TEXT2(1,setup,"eq:no de"); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat, + sizeof(irq_ptr->io_result_dstat)); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat, + sizeof(irq_ptr->io_result_cstat)); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags, + sizeof(irq_ptr->io_result_flags)); + QDIO_PRINT_ERR("establish queues on irq %04x: didn't get " \ + "device end: dstat=%02x, cstat=%02x, " \ + "flags=%02x\n", + irq_ptr->irq,irq_ptr->io_result_dstat, + irq_ptr->io_result_cstat, + irq_ptr->io_result_flags); + spin_unlock(&irq_ptr->setting_up_lock); + qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR); + result=-EIO; + goto out2; + } + + if (irq_ptr->io_result_dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) { + QDIO_DBF_TEXT2(1,setup,"eq:badio"); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat, + sizeof(irq_ptr->io_result_dstat)); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat, + sizeof(irq_ptr->io_result_cstat)); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags, + sizeof(irq_ptr->io_result_flags)); + QDIO_PRINT_ERR("establish queues on irq %04x: got " \ + "the following devstat: dstat=%02x, " \ + "cstat=%02x, flags=%02x\n", + irq_ptr->irq,irq_ptr->io_result_dstat, + irq_ptr->io_result_cstat, + irq_ptr->io_result_flags); + result=-EIO; + goto out; + } + + if (MACHINE_IS_VM) + irq_ptr->qdioac=qdio_check_siga_needs(irq_ptr->irq); + else { + irq_ptr->qdioac=CHSC_FLAG_SIGA_INPUT_NECESSARY + | CHSC_FLAG_SIGA_OUTPUT_NECESSARY; + } + sprintf(dbf_text,"qdioac%2x",irq_ptr->qdioac); + QDIO_DBF_TEXT2(0,setup,dbf_text); + + sprintf(dbf_text,"qib ac%2x",irq_ptr->qib.ac); + QDIO_DBF_TEXT2(0,setup,dbf_text); + + if (init_data->flags&QDIO_USE_OUTBOUND_PCIS) { + irq_ptr->hydra_gives_outbound_pcis= + irq_ptr->qib.ac&QIB_AC_OUTBOUND_PCI_SUPPORTED; + } else { + irq_ptr->hydra_gives_outbound_pcis=0; + } + irq_ptr->sync_done_on_outb_pcis= + irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS; + + for (i=0;ino_input_qs;i++) { + irq_ptr->input_qs[i]->siga_sync= + irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY; + irq_ptr->input_qs[i]->siga_in= + irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY; + irq_ptr->input_qs[i]->siga_out= + irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY; + irq_ptr->input_qs[i]->siga_sync_done_on_thinints= + irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS; + irq_ptr->input_qs[i]->hydra_gives_outbound_pcis= + irq_ptr->hydra_gives_outbound_pcis; + irq_ptr->input_qs[i]->siga_sync_done_on_outb_tis= + ( (irq_ptr->qdioac& + (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| + CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS))== + (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| + CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS) ); + } + + for (i=0;ino_output_qs;i++) { + irq_ptr->output_qs[i]->siga_sync= + irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY; + irq_ptr->output_qs[i]->siga_in= + irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY; + irq_ptr->output_qs[i]->siga_out= + irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY; + irq_ptr->output_qs[i]->siga_sync_done_on_thinints= + irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS; + irq_ptr->output_qs[i]->hydra_gives_outbound_pcis= + irq_ptr->hydra_gives_outbound_pcis; + irq_ptr->output_qs[i]->siga_sync_done_on_outb_tis= + ( (irq_ptr->qdioac& + (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| + CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS))== + (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| + CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS) ); + } + + if (init_data->qib_param_field) + memcpy(init_data->qib_param_field,irq_ptr->qib.parm, + QDIO_MAX_BUFFERS_PER_Q); + + qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED); + + out: + if (irq_ptr) { + spin_unlock(&irq_ptr->setting_up_lock); + } + out2: + up(&init_sema); + + return result; +} + +int qdio_activate(int irq,int flags) +{ + qdio_irq_t *irq_ptr; + int i,result=0,result2; + unsigned long saveflags; + char dbf_text[20]; /* see qdio_initialize */ + + irq_ptr=qdio_get_irq_ptr(irq); + if (!irq_ptr) return -ENODEV; + + spin_lock(&irq_ptr->setting_up_lock); + if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) { + result=-EBUSY; + goto out; + } + + sprintf(dbf_text,"qact%4x",irq); + QDIO_DBF_TEXT2(0,setup,dbf_text); + QDIO_DBF_TEXT2(0,trace,dbf_text); + + /* activate q */ + irq_ptr->ccw.cmd_code=irq_ptr->commands.aq; + irq_ptr->ccw.flags=CCW_FLAG_SLI; + irq_ptr->ccw.count=irq_ptr->commands.count_aq; + irq_ptr->ccw.cda=QDIO_GET_32BIT_ADDR(0); /* no QDIO_PFIX_GET_ADDR here, + not needed */ + + s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags); + atomic_set(&irq_ptr->interrupt_has_arrived,0); + + result=do_IO(irq_ptr->irq,&irq_ptr->ccw,QDIO_DOING_ACTIVATE, + 0,DOIO_REPORT_ALL|DOIO_DENY_PREFETCH| + ((irq_ptr->other_flags&QDIO_PFIX)?DOIO_USE_DIAG98:0)); + if (result) { + result2=do_IO(irq_ptr->irq,&irq_ptr->ccw, + QDIO_DOING_ACTIVATE,0,DOIO_REPORT_ALL| + ((irq_ptr->other_flags&QDIO_PFIX) ? + DOIO_USE_DIAG98:0)); + sprintf(dbf_text,"aq:io%4x",result); + QDIO_DBF_TEXT2(1,setup,dbf_text); + if (result2) { + sprintf(dbf_text,"aq:io%4x",result); + QDIO_DBF_TEXT2(1,setup,dbf_text); + } + QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \ + "returned %i, next try returned %i\n", + irq_ptr->irq,result,result2); + result=result2; + } + + s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags); + if (result) { + goto out; + } + + if (!(flags&QDIO_FLAG_UNDER_INTERRUPT)) { + result=qdio_sleepon(&irq_ptr->interrupt_has_arrived, + QDIO_ACTIVATE_TIMEOUT,irq_ptr); + + if (result!=-ETIME) { + QDIO_DBF_TEXT2(1,setup,"aq:badio"); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat, + sizeof(irq_ptr->io_result_dstat)); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat, + sizeof(irq_ptr->io_result_cstat)); + QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags, + sizeof(irq_ptr->io_result_flags)); + QDIO_PRINT_ERR("activate queues on irq %04x: got " \ + "the following devstat: dstat=%02x, " \ + "cstat=%02x, flags=%02x\n", + irq_ptr->irq,irq_ptr->io_result_dstat, + irq_ptr->io_result_cstat, + irq_ptr->io_result_flags); + result=-EIO; + goto out; + } else { /* result is -ETIME, but timeout is ok for us */ + result=0; + } + } else result=0; + + for (i=0;ino_input_qs;i++) { + if (irq_ptr->is_thinint_irq) { + /* that way we know, that, if we will + * get interrupted + * by tiqdio_inbound_processing, + * qdio_unmark_q will + * not be called */ + qdio_reserve_q(irq_ptr->input_qs[i]); + qdio_mark_tiq(irq_ptr->input_qs[i]); + qdio_release_q(irq_ptr->input_qs[i]); + } + } + + if (flags&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) { + for (i=0;ino_input_qs;i++) { + irq_ptr->input_qs[i]->is_input_q|= + QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT; + } + } + + qdio_wait_nonbusy(QDIO_ACTIVATE_DELAY); + + qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ACTIVE); + + out: + spin_unlock(&irq_ptr->setting_up_lock); + + return result; +} + +/* buffers filled forwards again to make Rick happy */ +static void qdio_do_qdio_fill_input(qdio_q_t *q,unsigned int qidx, + unsigned int count,qdio_buffer_t *buffers) +{ + for (;;) { + if (!q->is_0copy_sbals_q) { + memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE); + q->qdio_buffers[qidx]=buffers; + buffers++; + } + set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY); + count--; + if (!count) break; + qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1); + } + + /* not necessary, as the queues are synced during the SIGA read + SYNC_MEMORY;*/ +} + +static inline void qdio_do_qdio_fill_output(qdio_q_t *q,unsigned int qidx, + unsigned int count, + qdio_buffer_t *buffers) +{ + for (;;) { + if (!q->is_0copy_sbals_q) { + memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE); + q->qdio_buffers[qidx]=buffers; + buffers++; + } + set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED); + count--; + if (!count) break; + qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1); + } + + /* SIGA write will sync the queues + SYNC_MEMORY;*/ +} + +/* count must be 1 in iqdio */ +int do_QDIO(int irq,unsigned int callflags,unsigned int queue_number, + unsigned int qidx,unsigned int count,qdio_buffer_t *buffers) +{ + qdio_q_t *q; + qdio_irq_t *irq_ptr; + int result; + int used_elements; + +#ifdef QDIO_DBF_LIKE_HELL + char dbf_text[20]; + + sprintf(dbf_text,"doQD%04x",irq); + QDIO_DBF_TEXT3(0,trace,dbf_text); +#endif /* QDIO_DBF_LIKE_HELL */ + + if ( (qidx>QDIO_MAX_BUFFERS_PER_Q) || + (count>QDIO_MAX_BUFFERS_PER_Q) || + (queue_number>QDIO_MAX_QUEUES_PER_IRQ) ) + return -EINVAL; + + if (count==0) return 0; + + irq_ptr=qdio_get_irq_ptr(irq); + if (!irq_ptr) return -ENODEV; + +#ifdef QDIO_DBF_LIKE_HELL + if (callflags&QDIO_FLAG_SYNC_INPUT) + QDIO_DBF_HEX3(0,trace,&irq_ptr->input_qs[queue_number], + sizeof(void*)); + else + QDIO_DBF_HEX3(0,trace,&irq_ptr->output_qs[queue_number], + sizeof(void*)); + sprintf(dbf_text,"flag%04x",callflags); + QDIO_DBF_TEXT3(0,trace,dbf_text); + sprintf(dbf_text,"qi%02xct%02x",qidx,count); + QDIO_DBF_TEXT3(0,trace,dbf_text); + if ( ((callflags&QDIO_FLAG_SYNC_INPUT)&& + (!irq_ptr->input_qs[queue_number]->is_0copy_sbals_q)) || + ((callflags&QDIO_FLAG_SYNC_OUTPUT)&& + (!irq_ptr->output_qs[queue_number]->is_0copy_sbals_q)) ) + QDIO_DBF_HEX5(0,sbal,buffers,256); +#endif /* QDIO_DBF_LIKE_HELL */ + + if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) { + return -EBUSY; + } + + if (callflags&QDIO_FLAG_SYNC_INPUT) { + /* This is the inbound handling of queues */ + q=irq_ptr->input_qs[queue_number]; + + used_elements=atomic_return_add(count, + &q->number_of_buffers_used); + + qdio_do_qdio_fill_input(q,qidx,count,buffers); + + if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&& + (callflags&QDIO_FLAG_UNDER_INTERRUPT)) + atomic_swap(&q->polling,0); + + if (!used_elements) if (!(callflags&QDIO_FLAG_DONT_SIGA)) { + if (q->siga_in) { + result=qdio_siga_input(q); + if (result) { + if (q->siga_error) + q->error_status_flags|= + QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR; + q->error_status_flags|= + QDIO_STATUS_LOOK_FOR_ERROR; + q->siga_error=result; + } + } + + qdio_mark_q(q); + } + } else if (callflags&QDIO_FLAG_SYNC_OUTPUT) { + /* This is the outbound handling of queues */ +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.start_time_outbound=NOW; +#endif /* QDIO_PERFORMANCE_STATS */ + q=irq_ptr->output_qs[queue_number]; + + qdio_do_qdio_fill_output(q,qidx,count,buffers); + + used_elements=atomic_return_add(count, + &q->number_of_buffers_used); + + if (!(callflags&QDIO_FLAG_DONT_SIGA)) { + if (q->is_iqdio_q) { + /* one siga for every sbal */ + while (count--) { + qdio_kick_outbound_q(q); + } + + qdio_outbound_processing(q); + } else { + /* under VM, we do a SIGA sync + * unconditionally */ + SYNC_MEMORY; + else { + /* w/o shadow queues (else branch of + * SYNC_MEMORY :-/ ), we try to + * fast-requeue buffers */ + if (q->slsb.acc.val + [(qidx+QDIO_MAX_BUFFERS_PER_Q-1) + &(QDIO_MAX_BUFFERS_PER_Q-1)]!= + SLSB_CU_OUTPUT_PRIMED) { + qdio_kick_outbound_q(q); + } else { +#ifdef QDIO_DBF_LIKE_HELL + QDIO_DBF_TEXT3(0,trace, + "fast-req"); +#endif /* QDIO_DBF_LIKE_HELL */ +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.fast_reqs++; +#endif /* QDIO_PERFORMANCE_STATS */ + } + } + /* only marking the q could take + * too long, the upper layer + * module could do a lot of + * traffic in that time */ + qdio_outbound_processing(q); + } + } + +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; + perf_stats.outbound_cnt++; +#endif /* QDIO_PERFORMANCE_STATS */ + } else { + QDIO_DBF_TEXT3(1,trace,"doQD:inv"); + return -EINVAL; + } + return 0; +} + +#ifdef QDIO_PERFORMANCE_STATS +static int qdio_perf_procfile_read(char *buffer,char **buffer_location, + off_t offset,int buffer_length,int *eof, + void *data) +{ + int c=0,bucket; + qdio_irq_t *irq_ptr; + + /* we are always called with buffer_length=4k, so we all + deliver on the first read */ + if (offset>0) return 0; + +#define _OUTP_IT(x...) c+=sprintf(buffer+c,x) + _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); + _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); + _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); + _OUTP_IT("Number of tasklet runs (total) : %u\n", + perf_stats.tl_runs); + _OUTP_IT("\n"); + _OUTP_IT("Number of SIGA sync's issued : %u\n", + perf_stats.siga_syncs); + _OUTP_IT("Number of SIGA in's issued : %u\n", + perf_stats.siga_ins); + _OUTP_IT("Number of SIGA out's issued : %u\n", + perf_stats.siga_outs); + _OUTP_IT("Number of PCI's caught : %u\n", + perf_stats.pcis); + _OUTP_IT("Number of adapter interrupts caught : %u\n", + perf_stats.thinints); + _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %u\n", + perf_stats.fast_reqs); + _OUTP_IT("\n"); + _OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n", + perf_stats.inbound_time); + _OUTP_IT("Number of inbound transfers : %u\n", + perf_stats.inbound_cnt); + _OUTP_IT("Total time of all outbound do_QDIOs (us) : %u\n", + perf_stats.outbound_time); + _OUTP_IT("Number of do_QDIOs outbound : %u\n", + perf_stats.outbound_cnt); + _OUTP_IT("\n"); + + for (bucket=0;bucketirq,irq_ptr->input_qs[0]-> + timing.threshold); + irq_ptr=irq_ptr->next; + } + } + + return c; +} + +static struct proc_dir_entry *qdio_perf_proc_file; +#endif /* QDIO_PERFORMANCE_STATS */ + +static void qdio_add_procfs_entry(void) +{ +#ifdef QDIO_PERFORMANCE_STATS + proc_perf_file_registration=0; + qdio_perf_proc_file=create_proc_entry(QDIO_PERF, + S_IFREG|0444,&proc_root); + if (qdio_perf_proc_file) { + qdio_perf_proc_file->read_proc=&qdio_perf_procfile_read; + } else proc_perf_file_registration=-1; + + if (proc_perf_file_registration) + QDIO_PRINT_WARN("was not able to register perf. " \ + "proc-file (%i).\n", + proc_perf_file_registration); +#endif /* QDIO_PERFORMANCE_STATS */ +} +#ifdef MODULE +static void qdio_remove_procfs_entry(void) +{ +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs=0; + + if (!proc_perf_file_registration) /* means if it went ok earlier */ + remove_proc_entry(QDIO_PERF,&proc_root); +#endif /* QDIO_PERFORMANCE_STATS */ +} +#endif /* MODULE */ + +static void tiqdio_register_thinints(void) +{ + char dbf_text[20]; + register_thinint_result= + s390_register_adapter_interrupt(&tiqdio_thinint_handler); + if (register_thinint_result) { + sprintf(dbf_text,"regthn%x",(register_thinint_result&0xff)); + QDIO_DBF_TEXT0(0,setup,dbf_text); + QDIO_PRINT_ERR("failed to register adapter handler " \ + "(rc=%i).\nAdapter interrupts might " \ + "not work. Continuing.\n", + register_thinint_result); + } +} + +#ifdef MODULE +static void tiqdio_unregister_thinints(void) +{ + if (!register_thinint_result) + s390_unregister_adapter_interrupt(&tiqdio_thinint_handler); +} +#endif /* MODULE */ + +static int qdio_get_qdio_memory(void) +{ + int i; + indicator_used[0]=1; + + for (i=1;i #include #include +#include #ifdef CONFIG_PROC_FS #include #endif @@ -116,6 +117,11 @@ ##args); \ } while (0) +#define CIO_HEX_EVENT(imp, args...) do { \ + if (cio_debug_initialized) \ + debug_event(cio_debug_trace_id, imp, ##args); \ + } while (0) + #undef CONFIG_DEBUG_IO #define CONFIG_DEBUG_CRW #define CONFIG_DEBUG_CHSC @@ -175,14 +181,13 @@ int s390_start_IO (int irq, ccw1_t * cpa, unsigned long user_intparm, __u8 lpm, unsigned long flag); -static int s390_send_nop(int irq, __u8 lpm); - #ifdef CONFIG_PROC_FS static int chan_proc_init (void); #endif static inline void do_adapter_IO (__u32 intparm); +static void s390_schedule_path_verification(unsigned long irq); int s390_DevicePathVerification (int irq, __u8 domask); int s390_register_adapter_interrupt (adapter_int_handler_t handler); int s390_unregister_adapter_interrupt (adapter_int_handler_t handler); @@ -251,20 +256,17 @@ if ((to && (from > to)) || (to<0) || (to > 0xffff) - || (from<0) || (from > 0xffff)) { - printk (KERN_WARNING - "Invalid blacklist range %x to %x, skipping\n", from, - to); + || (from<0) || (from > 0xffff)) return; - } + if (!locked) spin_lock_irqsave (&blacklist_lock, flags); if (!to) to = from; for (i = from; i <= to; i++) { - set_bit (i, &bl_dev); - nr_ignored++; + if (!test_and_set_bit (i, &bl_dev)) + nr_ignored++; } if (to >= highest_ignored) @@ -285,20 +287,16 @@ long flags; int i; - if ((to<0) || (to > 0xffff) - || (from<0) || (from > 0xffff)) { - printk (KERN_WARNING - "Invalid blacklist range %x to %x, " - "not freeing\n", - from, to); + if ((to && (from > to)) + || (to<0) || (to > 0xffff) + || (from<0) || (from > 0xffff)) return; - } spin_lock_irqsave (&blacklist_lock, flags); for (i = from; i <= to; i++) { - clear_bit (i, &bl_dev); - nr_ignored--; + if (test_and_clear_bit (i, &bl_dev)) + nr_ignored--; } if (to == highest_ignored) @@ -364,16 +362,12 @@ static inline int blacklist_strtoul (char *str, char **stra) { - char *temp = str; - int val; - if (*temp == '0') { - temp++; /* strip leading zero */ - if (*temp == 'x') - temp++; /* strip leading x */ - } - val = simple_strtoul (temp, &temp, 16); /* interpret anything as hex */ - *stra = temp; - return val; + if (*str == '0') { + str++; /* strip leading zero */ + if (*str == 'x') + str++; /* strip leading x */ + } + return simple_strtoul (str, stra, 16); /* interpret anything as hex */ } /* @@ -507,85 +501,62 @@ void blacklist_parse_proc_parameters (char *buf) { - char *tmp; int i; - char *end; - int len = -1; - char *param; int from = 0; int to = 0; long flags; int err = 0; - tmp = buf; - if (strstr (tmp, "free ")) { + if (strstr (buf, "free ")) { for (i = 0; i < 5; i++) { - tmp++; + buf++; } - if (strstr (tmp, "all")) { + if (strstr (buf, "all")) { blacklist_free_all_ranges (); s390_redo_validation (); } else { - while (tmp != NULL) { - end = strchr (tmp, ','); - if (end == NULL) { - len = strlen (tmp) + 1; - } else { - len = (long) end - (long) tmp + 1; - *end = '\0'; - end++; - } - param = - (char *) kmalloc (len * sizeof (char) + 1, - GFP_KERNEL); - strncpy (param, (const char *) tmp, len); - tmp = end; - from = blacklist_strtoul (param, ¶m); - if (*param == '-') { - param++; - to = blacklist_strtoul (param, ¶m); - } else { - to = from; + while (*buf != 0 && *buf != '\n') { + if (!isxdigit(*buf)) { + printk(KERN_WARNING "%s: error parsing " + "\"%s\"\n", __FUNCTION__, buf); + return; } + + from = blacklist_strtoul (buf, &buf); + to = (*buf == '-') ? + blacklist_strtoul (buf+1, &buf) : from; + blacklist_range_remove (from, to); - kfree (param); + + if (*buf == ',') + buf++; } - s390_redo_validation (); + s390_redo_validation(); } - } else if (strstr (tmp, "add ")) { + } else if (strstr (buf, "add ")) { for (i = 0; i < 4; i++) { - tmp++; + buf++; } - while (tmp != NULL) { - end = strchr (tmp, ','); - if (end == NULL) { - len = strlen (tmp) + 1; - } else { - len = (long) end - (long) tmp + 1; - *end = '\0'; - end++; - } - param = - (char *) kmalloc (len * sizeof (char) + 1, - GFP_KERNEL); - strncpy (param, (const char *) tmp, len); - tmp = end; - from = blacklist_strtoul (param, ¶m); - if (*param == '-') { - param++; - to = blacklist_strtoul (param, ¶m); - } else { - to = from; + while (*buf != 0 && *buf != '\n') { + if (!isxdigit(*buf)) { + printk(KERN_WARNING "%s: error parsing " + "\"%s\"\n", __FUNCTION__, buf); + return; } + + from = blacklist_strtoul (buf, &buf); + to = (*buf == '-') ? + blacklist_strtoul (buf+1, &buf) : from; + spin_lock_irqsave (&blacklist_lock, flags); - + /* * Don't allow for already known devices to be * blacklisted * The criterion is a bit dumb, devices which once were * there but are already gone are also caught... */ - + err = 0; for (i = 0; i <= highest_subchannel; i++) { if (ioinfo[i] != INVALID_STORAGE_AREA) { @@ -603,12 +574,13 @@ } } } - + if (!err) blacklist_range_add (from, to, 1); - + spin_unlock_irqrestore (&blacklist_lock, flags); - kfree (param); + if (*buf == ',') + buf++; } } else { @@ -623,7 +595,6 @@ /* End of blacklist handling */ void s390_displayhex (char *str, void *ptr, s32 cnt); -void s390_displayhex2 (char *str, void *ptr, s32 cnt, int level); void s390_displayhex (char *str, void *ptr, s32 cnt) @@ -644,26 +615,6 @@ } } -void -s390_displayhex2 (char *str, void *ptr, s32 cnt, int level) -{ - s32 cnt1, cnt2, maxcnt2; - u32 *currptr = (__u32 *) ptr; - char buffer[cnt * 12]; - - debug_text_event (cio_debug_msg_id, level, str); - - for (cnt1 = 0; cnt1 < cnt; cnt1 += 16) { - sprintf (buffer, "%08lX ", (unsigned long) currptr); - maxcnt2 = cnt - cnt1; - if (maxcnt2 > 16) - maxcnt2 = 16; - for (cnt2 = 0; cnt2 < maxcnt2; cnt2 += 4) - sprintf (buffer, "%08X ", *currptr++); - } - debug_text_event (cio_debug_msg_id, level, buffer); -} - static int __init cio_setup (char *parm) { @@ -815,93 +766,6 @@ return; } - -/* - * Function: s390_send_nop - * - * sends a nop CCW to the specified subchannel down the given path(s) - */ -static int -s390_send_nop(int irq, __u8 lpm) -{ - char dbf_txt[15]; - ccw1_t *nop_ccw; - devstat_t devstat; - devstat_t *pdevstat = &devstat; - unsigned long flags; - - int irq_ret = 0; - int inlreq = 0; - - SANITY_CHECK(irq); - - if (!ioinfo[irq]->ui.flags.oper) - /* no sense in trying */ - return -ENODEV; - - sprintf(dbf_txt, "snop%x", irq); - CIO_TRACE_EVENT(5, dbf_txt); - - if (!ioinfo[irq]->ui.flags.ready) { - /* - * If there's no handler, use our dummy handler. - */ - irq_ret = request_irq (irq, - init_IRQ_handler, - SA_PROBE, - "SNOP", - pdevstat); - if (!irq_ret) - inlreq = 1; - } else { - pdevstat = ioinfo[irq]->irq_desc.dev_id; - } - - if (irq_ret) - return irq_ret; - - s390irq_spin_lock_irqsave (irq, flags); - - if (init_IRQ_complete) - nop_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA); - else - nop_ccw = alloc_bootmem_low (sizeof (ccw1_t)); - - nop_ccw->cmd_code = CCW_CMD_NOOP; - nop_ccw->cda = 0; - nop_ccw->count = 0; - nop_ccw->flags = CCW_FLAG_SLI; - - memset (pdevstat, '\0', sizeof (devstat_t)); - - irq_ret = s390_start_IO (irq, nop_ccw, 0xE2D5D6D7, lpm, - DOIO_WAIT_FOR_INTERRUPT - | DOIO_TIMEOUT - | DOIO_DONT_CALL_INTHDLR - | DOIO_VALID_LPM); - - if (irq_ret == -ETIMEDOUT) { - - /* better cancel... */ - cancel_IO(irq); - } - - if (init_IRQ_complete) - kfree (nop_ccw); - else - free_bootmem ((unsigned long) nop_ccw, sizeof (ccw1_t)); - - s390irq_spin_unlock_irqrestore (irq, flags); - - if (inlreq) - free_irq (irq, pdevstat); - - return irq_ret; - -} - - - /* * Note : internal use of irqflags SA_PROBE for NOT path grouping * @@ -930,7 +794,7 @@ if (ioinfo[irq]->st) return -ENODEV; - sprintf (dbf_txt, "reqs%x", irq); + sprintf (dbf_txt, "reqsp%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -1054,6 +918,7 @@ s390irq_spin_unlock_irqrestore (irq, flags); udelay (200000); /* 200 ms */ s390irq_spin_lock_irqsave (irq, flags); + ret = disable_subchannel (irq); if (ret == -EBUSY) { @@ -1130,7 +995,7 @@ if (!ioinfo[irq]->ui.flags.ready) return -ENODEV; - sprintf (dbf_txt, "dirq%x", irq); + sprintf (dbf_txt, "disirq%x", irq); CIO_TRACE_EVENT (4, dbf_txt); s390irq_spin_lock_irqsave (irq, flags); @@ -1157,7 +1022,7 @@ if (!ioinfo[irq]->ui.flags.ready) return -ENODEV; - sprintf (dbf_txt, "eirq%x", irq); + sprintf (dbf_txt, "enirq%x", irq); CIO_TRACE_EVENT (4, dbf_txt); s390irq_spin_lock_irqsave (irq, flags); @@ -1183,7 +1048,7 @@ SANITY_CHECK (irq); - sprintf (dbf_txt, "esch%x", irq); + sprintf (dbf_txt, "ensch%x", irq); CIO_TRACE_EVENT (2, dbf_txt); /* @@ -1268,7 +1133,7 @@ SANITY_CHECK (irq); - sprintf (dbf_txt, "dsch%x", irq); + sprintf (dbf_txt, "dissch%x", irq); CIO_TRACE_EVENT (2, dbf_txt); if (ioinfo[irq]->ui.flags.busy) { @@ -1367,6 +1232,7 @@ { unsigned long flags; /* PSW flags */ long cr6 __attribute__ ((aligned (8))); + cpuid_t cpuid; asm volatile ("STCK %0":"=m" (irq_IPL_TOD)); @@ -1406,8 +1272,18 @@ global_pgid = (pgid_t *)alloc_bootmem(sizeof(pgid_t)); - global_pgid->cpu_addr = *(__u16 *) __LC_CPUADDR; - global_pgid->cpu_id = ((cpuid_t *) __LC_CPUID)->ident; + cpuid = *(cpuid_t*) __LC_CPUID; + + if (MACHINE_NEW_STIDP) + global_pgid->cpu_addr = 0x8000; + else { +#ifdef CONFIG_SMP + global_pgid->cpu_addr = hard_smp_processor_id(); +#else + global_pgid->cpu_addr = 0; +#endif + } + global_pgid->cpu_id = cpuid.ident; global_pgid->cpu_model = ((cpuid_t *) __LC_CPUID)->machine; global_pgid->tod_high = *(__u32 *) & irq_IPL_TOD; @@ -1445,7 +1321,6 @@ { /* flags */ int ccode; int ret = 0; - char buffer[80]; char dbf_txt[15]; SANITY_CHECK (irq); @@ -1512,7 +1387,14 @@ /* * Issue "Start subchannel" and process condition code */ - ccode = ssch (irq, &(ioinfo[irq]->orb)); + if (flag & DOIO_USE_DIAG98) { + ioinfo[irq]->orb.key = get_storage_key() >> 4; + ioinfo[irq]->orb.cpa = + (__u32) pfix_get_addr((void *)ioinfo[irq]->orb.cpa); + ccode = diag98 (irq, &(ioinfo[irq]->orb)); + } else { + ccode = ssch (irq, &(ioinfo[irq]->orb)); + } sprintf (dbf_txt, "ccode:%d", ccode); CIO_TRACE_EVENT (4, dbf_txt); @@ -1674,6 +1556,16 @@ break; case 1: /* status pending */ + + /* + * Don't do an inline processing of pending interrupt conditions + * while doing async. I/O. The interrupt will pop up when we are + * enabled again and the I/O can be retried. + */ + if (!ioinfo[irq]->ui.flags.syncio) { + ret = -EBUSY; + break; + } ioinfo[irq]->devstat.flag = DEVSTAT_START_FUNCTION | DEVSTAT_STATUS_PENDING; @@ -1715,14 +1607,6 @@ * than the one used (i.e. path available mask is non-zero). */ if (ioinfo[irq]->devstat.ii.irb.scsw.cc == 3) { - if (flag & DOIO_VALID_LPM) { - ioinfo[irq]->opm &= - ~(ioinfo[irq]->devstat.ii.irb.esw.esw1. - lpum); - } else { - ioinfo[irq]->opm = 0; - - } if (ioinfo[irq]->opm == 0) { ret = -ENODEV; @@ -1736,6 +1620,7 @@ #ifdef CONFIG_DEBUG_IO { + char buffer[80]; stsch (irq, &(ioinfo[irq]->schib)); @@ -1777,39 +1662,23 @@ #endif if (cio_debug_initialized) { stsch (irq, &(ioinfo[irq]->schib)); - - sprintf (buffer, - "s390_start_IO(%04X) - irb for " - "device %04X, after status pending\n", - irq, ioinfo[irq]->devstat.devno); - - s390_displayhex2 (buffer, - &(ioinfo[irq]->devstat.ii. - irb), sizeof (irb_t), 2); - - sprintf (buffer, - "s390_start_IO(%04X) - schib for " - "device %04X, after status pending\n", - irq, ioinfo[irq]->devstat.devno); - - s390_displayhex2 (buffer, - &(ioinfo[irq]->schib), - sizeof (schib_t), 2); + + sprintf(dbf_txt, "sp%x", irq); + CIO_TRACE_EVENT(2, dbf_txt); + CIO_TRACE_EVENT(2, "irb:"); + CIO_HEX_EVENT(2, &(ioinfo[irq]->devstat.ii.irb), + sizeof (irb_t)); + CIO_TRACE_EVENT(2, "schib:"); + CIO_HEX_EVENT(2, &(ioinfo[irq]->schib), + sizeof (schib_t)); if (ioinfo[irq]->devstat. flag & DEVSTAT_FLAG_SENSE_AVAIL) { - sprintf (buffer, - "s390_start_IO(%04X) " - "- sense data for device %04X," - " after status pending\n", - irq, - ioinfo[irq]->devstat.devno); - - s390_displayhex2 (buffer, - ioinfo[irq]->irq_desc. - dev_id->ii.sense.data, - ioinfo[irq]->irq_desc. - dev_id->rescnt, 2); + CIO_TRACE_EVENT(2, "sense:"); + CIO_HEX_EVENT(2, ioinfo[irq]->irq_desc. + dev_id->ii.sense.data, + ioinfo[irq]->irq_desc. + dev_id->rescnt); } } @@ -1860,14 +1729,10 @@ #endif if (cio_debug_initialized) { stsch (irq, &(ioinfo[irq]->schib)); - - sprintf (buffer, "s390_start_IO(%04X) - schib for " - "device %04X, after 'not oper' status\n", - irq, ioinfo[irq]->devstat.devno); - - s390_displayhex2 (buffer, - &(ioinfo[irq]->schib), - sizeof (schib_t), 2); + sprintf(dbf_txt, "no%x", irq); + CIO_TRACE_EVENT(2, dbf_txt); + CIO_HEX_EVENT(2, &(ioinfo[irq]->schib), + sizeof (schib_t)); } break; @@ -1908,6 +1773,9 @@ sprintf (dbf_txt, "doIO%x", irq); CIO_TRACE_EVENT (4, dbf_txt); + if (ioinfo[irq]->ui.flags.noio) + return -EBUSY; + /* * Note: We ignore the device operational status - if not operational, * the SSCH will lead to an -ENODEV condition ... @@ -1963,7 +1831,7 @@ SANITY_CHECK (irq); - sprintf (dbf_txt, "rsIO%x", irq); + sprintf (dbf_txt, "resIO%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -1982,7 +1850,6 @@ break; case 1: - s390_process_IRQ (irq); ret = -EBUSY; break; @@ -2025,6 +1892,9 @@ SANITY_CHECK (irq); + if (ioinfo[irq]->ui.flags.noio) + return -EBUSY; + /* * we only allow for halt_IO if the device has an I/O handler associated */ @@ -2038,8 +1908,7 @@ if (ioinfo[irq]->ui.flags.w4sense) { return 0; } - CIO_TRACE_EVENT (2, "haltIO"); - sprintf (dbf_txt, "%x", irq); + sprintf (dbf_txt, "haltIO%x", irq); CIO_TRACE_EVENT (2, dbf_txt); /* @@ -2158,6 +2027,16 @@ case 1: /* status pending */ + /* + * Don't do an inline processing of pending interrupt conditions + * while doing async. I/O. The interrupt will pop up when we are + * enabled again and the I/O can be retried. + */ + if (!ioinfo[irq]->ui.flags.syncio) { + ret = -EBUSY; + break; + } + ioinfo[irq]->devstat.flag |= DEVSTAT_STATUS_PENDING; /* @@ -2248,6 +2127,8 @@ if (ioinfo[irq] == INVALID_STORAGE_AREA) return (-ENODEV); + if (ioinfo[irq]->ui.flags.noio) + return -EBUSY; /* * we only allow for clear_IO if the device has an I/O handler associated */ @@ -2260,8 +2141,7 @@ if (ioinfo[irq]->ui.flags.w4sense) return 0; - CIO_TRACE_EVENT (2, "clearIO"); - sprintf (dbf_txt, "%x", irq); + sprintf (dbf_txt, "clearIO%x", irq); CIO_TRACE_EVENT (2, dbf_txt); /* @@ -2418,8 +2298,7 @@ SANITY_CHECK (irq); - CIO_TRACE_EVENT (2, "cancelIO"); - sprintf (dbf_txt, "%x", irq); + sprintf (dbf_txt, "cancelIO%x", irq); CIO_TRACE_EVENT (2, dbf_txt); ccode = xsch (irq); @@ -2435,8 +2314,6 @@ case 1: /* status pending */ - /* process the pending irq... */ - s390_process_IRQ (irq); ret = -EBUSY; break; @@ -2595,7 +2472,7 @@ dp = &ioinfo[irq]->devstat; udp = ioinfo[irq]->irq_desc.dev_id; - + /* * It might be possible that a device was not-oper. at the time * of free_irq() processing. This means the handler is no longer @@ -2719,7 +2596,7 @@ } dp->cpa = dp->ii.irb.scsw.cpa; - + } irb_cc = dp->ii.irb.scsw.cc; @@ -2806,18 +2683,9 @@ irq, dp->devno); s390_displayhex (buffer, &(dp->ii.irb), sizeof (irb_t)); - if (cio_debug_initialized) { - - sprintf (buffer, - "s390_process_IRQ(%04X) - irb for " - "device %04X after channel check " - "or interface control check\n", - irq, dp->devno); - - s390_displayhex2 (buffer, - &(dp->ii.irb), - sizeof (irb_t), 0); - } + sprintf(dbf_txt, "chk%x", irq); + CIO_TRACE_EVENT(0, dbf_txt); + CIO_HEX_EVENT(0, &(dp->ii.irb), sizeof (irb_t)); } ioinfo[irq]->stctl |= stctl; @@ -2840,6 +2708,7 @@ */ if (!(stctl & SCSW_STCTL_ALERT_STATUS) && (ioinfo[irq]->ui.flags.busy == 0)) { + #ifdef CONFIG_DEBUG_IO if (irq != cons_dev) printk (KERN_INFO @@ -2863,16 +2732,9 @@ "subchannel status : %02X\n", dp->devno, irq, dp->dstat, dp->cstat); - if (cio_debug_initialized) { - sprintf (buffer, - "s390_process_IRQ(%04X) - irb for " - "device %04X, ending_status %d\n", irq, - dp->devno, ending_status); - - s390_displayhex2 (buffer, - &(dp->ii.irb), - sizeof (irb_t), 2); - } + sprintf(dbf_txt, "uint%x", irq); + CIO_TRACE_EVENT(2, dbf_txt); + CIO_HEX_EVENT(2, &(dp->ii.irb), sizeof (irb_t)); } /* @@ -2899,13 +2761,25 @@ unsigned long s_flag = 0; if (ending_status) { + /* there is a chance that the command + * that gave us the unit check actually + * was a basic sense, so we must not + * overwrite *udp in that case + */ + if (ioinfo[irq]->ui.flags.w4sense && + (dp->ii.irb.scsw.dstat & DEV_STAT_UNIT_CHECK)) { + CIO_MSG_EVENT(4,"double unit check irq %04x, dstat %02x," + "flags %8x\n", irq, dp->ii.irb.scsw.dstat, + ioinfo[irq]->ui.info, ending_status); + } else { /* * We copy the current status information into the device driver * status area. Then we can use the local devstat area for device * sensing. When finally calling the IRQ handler we must not overlay * the original device status but copy the sense data only. */ - memcpy (udp, dp, sizeof (devstat_t)); + memcpy (udp, dp, sizeof (devstat_t)); + } s_ccw->cmd_code = CCW_CMD_BASIC_SENSE; s_ccw->cda = @@ -2919,10 +2793,13 @@ * process we have to sense synchronously */ if (ioinfo[irq]->ui.flags.unready - || ioinfo[irq]->ui.flags.syncio) { - s_flag = DOIO_WAIT_FOR_INTERRUPT; + || ioinfo[irq]->ui.flags.syncio) + s_flag = DOIO_WAIT_FOR_INTERRUPT + | DOIO_TIMEOUT + | DOIO_VALID_LPM; - } + else + s_flag = DOIO_VALID_LPM; /* * Reset status info @@ -2950,8 +2827,34 @@ ioinfo[irq]->ui.flags.w4sense = 1; ret_io = s390_start_IO (irq, s_ccw, 0xE2C5D5E2, /* = SENSe */ - 0, /* n/a */ + 0xff, s_flag); + switch (ret_io) { + case 0: /* OK */ + break; + case -ENODEV: + /* + * The device is no longer operational. + * We won't get any sense data. + */ + ioinfo[irq]->ui.flags.w4sense = 0; + ioinfo[irq]->ui.flags.oper = 0; + allow4handler = 1; /* to notify the driver */ + break; + case -EBUSY: + /* + * The channel subsystem is either busy, or we have + * a status pending. Retry later. + */ + ioinfo[irq]->ui.flags.w4sense = 0; + ioinfo[irq]->ui.flags.delsense = 1; + break; + default: + printk(KERN_ERR"irq %04X: Unexpected rc %d " + "for BASIC SENSE!\n", irq, ret_io); + ioinfo[irq]->ui.flags.w4sense = 0; + allow4handler = 1; + } } else { /* * we received an Unit Check but we have no final @@ -3024,10 +2927,12 @@ udp->flag |= DEVSTAT_FLAG_SENSE_AVAIL; udp->scnt = sense_count; - if (sense_count >= 0) { + if (sense_count > 0) { memcpy (udp->ii.sense.data, ioinfo[irq]->sense_data, sense_count); + } else if (sense_count == 0) { + udp->flag &= ~DEVSTAT_FLAG_SENSE_AVAIL; } else { panic ("s390_process_IRQ(%04x) encountered " @@ -3090,7 +2995,8 @@ dp->flag |= DEVSTAT_FINAL_STATUS; udp->flag |= DEVSTAT_FINAL_STATUS; - ioinfo[irq]->irq_desc.handler (irq, udp, NULL); + if (!ioinfo[irq]->ui.flags.killio) + ioinfo[irq]->irq_desc.handler (irq, udp, NULL); /* * reset intparm after final status or we will badly present unsolicited @@ -3156,7 +3062,7 @@ udp->flag |= DEVSTAT_SUSPENDED; } - + ioinfo[irq]->irq_desc.handler (irq, udp, NULL); } @@ -3174,16 +3080,15 @@ dp->cstat = 0; dp->dstat = 0; - if (ioinfo[irq]->ulpm != ioinfo[irq]->opm) { - /* - * either it was the only path or it was restricted ... - */ - ioinfo[irq]->opm &= - ~(ioinfo[irq]->devstat.ii.irb.esw.esw1.lpum); - } else { - ioinfo[irq]->opm = 0; - - } + if ((dp->ii.irb.scsw.fctl != 0) && + ((dp->ii.irb.scsw.stctl & SCSW_STCTL_STATUS_PEND) != 0) && + (((dp->ii.irb.scsw.stctl & SCSW_STCTL_INTER_STATUS) == 0) || + ((dp->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED) != 0))) + if (dp->ii.irb.scsw.pno) { + stsch(irq, &ioinfo[irq]->schib); + ioinfo[irq]->opm &= + ~ioinfo[irq]->schib.pmcw.pnom; + } if (ioinfo[irq]->opm == 0) { ioinfo[irq]->ui.flags.oper = 0; @@ -3234,9 +3139,10 @@ ioinfo[irq]->devstat.intparm = 0; if (!ioinfo[irq]->ui.flags.s_pend - && !ioinfo[irq]->ui.flags.repnone) { - ioinfo[irq]->irq_desc.handler (irq, udp, NULL); + && !ioinfo[irq]->ui.flags.repnone + && !ioinfo[irq]->ui.flags.killio) { + ioinfo[irq]->irq_desc.handler (irq, udp, NULL); } ending_status = 1; @@ -3245,6 +3151,18 @@ } + if (ending_status && + ioinfo[irq]->ui.flags.noio && + !ioinfo[irq]->ui.flags.syncio && + !ioinfo[irq]->ui.flags.w4sense) { + if(ioinfo[irq]->ui.flags.ready) { + s390_schedule_path_verification(irq); + } else { + ioinfo[irq]->ui.flags.killio = 0; + ioinfo[irq]->ui.flags.noio = 0; + } + } + return (ending_status); } @@ -3277,7 +3195,7 @@ if (cons_dev != -1) return -EBUSY; - sprintf (dbf_txt, "scd%x", irq); + sprintf (dbf_txt, "scons%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -3322,7 +3240,7 @@ if (cons_dev != -1) return -EBUSY; - sprintf (dbf_txt, "rscd%x", irq); + sprintf (dbf_txt, "rcons%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -3366,7 +3284,7 @@ if (irq != cons_dev) return -EINVAL; - sprintf (dbf_txt, "wcd%x", irq); + sprintf (dbf_txt, "wcons%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -3417,7 +3335,7 @@ int rc = 0; char dbf_txt[15]; - sprintf (dbf_txt, "eisc%x", irq); + sprintf (dbf_txt, "enisc%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* This one spins until it can get the sync_isc lock for irq# irq */ @@ -3438,7 +3356,6 @@ * we only run the STSCH/MSCH path for the first enablement */ else if (sync_isc_cnt == 1) { - ioinfo[irq]->ui.flags.syncio = 1; ccode = stsch (irq, &(ioinfo[irq]->schib)); @@ -3463,6 +3380,7 @@ * if neccessary */ if (cons_dev != -1) cr6 &= 0xFEFFFFFF; + ioinfo[irq]->ui.flags.syncio = 1; __ctl_load (cr6, 6, 6); rc = 0; retry = 0; @@ -3505,6 +3423,15 @@ if (rc) { /* can only happen if stsch/msch fails */ sync_isc_cnt = 0; atomic_set (&sync_isc, -1); + } else if (sync_isc_cnt == 1) { + int ccode; + + ccode = stsch(irq, &ioinfo[irq]->schib); + if (!ccode && ioinfo[irq]->schib.pmcw.isc != 5) { + ioinfo[irq]->ui.flags.syncio = 0; + sync_isc_cnt = 0; + atomic_set (&sync_isc, -1); + } } } else { #ifdef CONFIG_SYNC_ISC_PARANOIA @@ -3531,7 +3458,7 @@ char dbf_txt[15]; - sprintf (dbf_txt, "disc%x", irq); + sprintf (dbf_txt, "disisc%x", irq); CIO_TRACE_EVENT (4, dbf_txt); if ((irq <= highest_subchannel) && @@ -3621,7 +3548,7 @@ sync_isc_cnt = 0; atomic_set (&sync_isc, -1); - + } else { sync_isc_cnt--; @@ -3641,6 +3568,26 @@ return (rc); } +int diag210 (diag210_t *addr) +{ + int ccode; + + __asm__ __volatile__( +#ifdef CONFIG_ARCH_S390X + " sam31\n" + " diag %1,0,0x210\n" + " sam64\n" +#else + " diag %1,0,0x210\n" +#endif + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "a" (addr) + : "cc" ); + return ccode; +} + /* * Input : * devno - device number @@ -3658,11 +3605,13 @@ CIO_TRACE_EVENT (4, "VMvdinf"); if (init_IRQ_complete) { - p_diag_data = kmalloc (sizeof (diag210_t), GFP_DMA); + p_diag_data = kmalloc (sizeof (diag210_t), GFP_DMA | GFP_ATOMIC); } else { p_diag_data = alloc_bootmem_low (sizeof (diag210_t)); } + if (!p_diag_data) + return; p_diag_data->vrdcdvno = devno; p_diag_data->vrdclen = sizeof (diag210_t); @@ -3980,7 +3929,7 @@ int read_dev_chars (int irq, void **buffer, int length) { - unsigned int flags; + unsigned long flags; ccw1_t *rdc_ccw; devstat_t devstat; char *rdc_buf; @@ -4009,7 +3958,7 @@ return -EUSERS; } - sprintf (dbf_txt, "rdc%x", irq); + sprintf (dbf_txt, "rddevch%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -4052,8 +4001,7 @@ rdc_ccw->count = length; rdc_ccw->flags = CCW_FLAG_SLI; ret = - set_normalized_cda (rdc_ccw, (unsigned long) - rdc_buf); + set_normalized_cda (rdc_ccw, rdc_buf); if (!ret) { memset (ioinfo[irq]->irq_desc.dev_id, @@ -4139,7 +4087,7 @@ return -EUSERS; } - sprintf (dbf_txt, "rcd%x", irq); + sprintf (dbf_txt, "rdconf%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -4194,7 +4142,7 @@ if (init_IRQ_complete) { rcd_buf = kmalloc (ioinfo[irq]->senseid.ciw[ciw_cnt]. - count, GFP_DMA); + count, GFP_DMA | GFP_ATOMIC); } else { rcd_buf = alloc_bootmem_low (ioinfo[irq]->senseid. @@ -4553,7 +4501,7 @@ int ret; char dbf_txt[15]; - sprintf (dbf_txt, "dri%x", irq); + sprintf (dbf_txt, "devrec%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -4576,6 +4524,7 @@ if (!ret) { pgid_t pgid; + int i, mask; /* * First thing we should do is a sensePGID in * order to find out how we can proceed with @@ -4586,13 +4535,24 @@ */ memcpy(&pgid, global_pgid, sizeof(pgid_t)); - ret = s390_SensePGID(irq, 0xff, &pgid); - if (ret == -EOPNOTSUPP) - /* - * Doesn't prevent us from proceeding - */ - ret = 0; + ret = -EAGAIN; + for (i=0; i<8 && ret==-EAGAIN; i++) { + + mask = (0x80 >> i) & ioinfo[irq]->opm; + + if (!mask) + continue; + + ret = s390_SensePGID(irq, mask, &pgid); + + if (ret == -EOPNOTSUPP) + /* + * Doesn't prevent us from proceeding + */ + ret = 0; + + } if (!ret && !ioinfo[irq]->ui.flags.unfriendly) { @@ -4645,18 +4605,9 @@ s390_displayhex (buffer, prcd, lrcd); #endif - if (cio_debug_initialized) { - sprintf (buffer, - "RCD for device(%04X)/" - "subchannel(%04X) returns :\n", - ioinfo[irq]-> - schib.pmcw.dev, - irq); - - s390_displayhex2 - (buffer, prcd, lrcd, - 2); - } + CIO_TRACE_EVENT(2, "rcddata:"); + CIO_HEX_EVENT(2, prcd, lrcd); + if (init_IRQ_complete) { kfree (prcd); } else { @@ -4756,14 +4707,9 @@ int s390_trigger_resense(int irq) { - char dbf_txt[8]; SANITY_CHECK(irq); - CIO_TRACE_EVENT (2, "tsns"); - sprintf(dbf_txt, "%x", irq); - CIO_TRACE_EVENT (2, dbf_txt); - if (ioinfo[irq]->ui.flags.ready) { printk (KERN_WARNING "s390_trigger_resense(%04X): " "Device is in use!\n", irq); @@ -4826,7 +4772,7 @@ char dbf_txt[15]; - sprintf (dbf_txt, "vals%x", irq); + sprintf (dbf_txt, "valsch%x", irq); CIO_TRACE_EVENT (4, dbf_txt); /* @@ -4901,9 +4847,12 @@ alloc_bootmem_low (sizeof (ioinfo_t)); } else { ioinfo[irq] = (ioinfo_t *) - kmalloc (sizeof (ioinfo_t), GFP_DMA); + kmalloc (sizeof (ioinfo_t), GFP_DMA | GFP_ATOMIC); } + if (!ioinfo[irq]) + return -ENOMEM; + memset (ioinfo[irq], '\0', sizeof (ioinfo_t)); memcpy (&ioinfo[irq]->schib, p_init_schib, sizeof (schib_t)); @@ -4964,6 +4913,10 @@ /* disable using this path */ ioinfo[irq]->opm &= ~mask; } + } else { + /* This chpid is not available to us */ + clear_bit(ioinfo[irq]->schib.pmcw.chpid[chp], + &chpids); } } } @@ -5209,8 +5162,7 @@ return -EUSERS; } - CIO_TRACE_EVENT (4, "senseID"); - sprintf (dbf_txt, "%x", irq); + sprintf (dbf_txt, "snsID%x", irq); CIO_TRACE_EVENT (4, dbf_txt); inlreq = 0; /* to make the compiler quiet... */ @@ -5245,11 +5197,17 @@ s390irq_spin_lock (irq); if (init_IRQ_complete) { - sense_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA); + sense_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA | GFP_ATOMIC); } else { sense_ccw = alloc_bootmem_low (2 * sizeof (ccw1_t)); } + if (!sense_ccw) { + s390irq_spin_unlock (irq); + if (inlreq) + free_irq (irq, &devstat); + return -ENOMEM; + } /* more than one path installed ? */ if (ioinfo[irq]->schib.pmcw.pim != 0x80) { @@ -5642,56 +5600,237 @@ return (cc); } -/* - * Device Path Verification - * - * Path verification is accomplished by checking which paths (CHPIDs) are - * available. Further, a path group ID is set, if possible in multipath - * mode, otherwise in single path mode. - * - * Note : This function must not be called during normal device recognition, - * but during device driver initiated request_irq() processing only. - */ -int -s390_DevicePathVerification (int irq, __u8 usermask) +static int +s390_do_path_verification(int irq, __u8 usermask) { - int ccode; - __u8 pathmask; __u8 domask; -#ifdef CONFIG_CHSC - int chp; - int mask; - int old_opm = 0; -#endif /* CONFIG_CHSC */ - - int ret = 0; int i; pgid_t pgid; __u8 dev_path; int first = 1; - + int ret = 0; char dbf_txt[15]; - sprintf (dbf_txt, "dpvf%x", irq); - CIO_TRACE_EVENT (4, dbf_txt); + sprintf(dbf_txt, "dopv%x", irq); + CIO_TRACE_EVENT(2, dbf_txt); - if (ioinfo[irq]->st) - return -ENODEV; + dev_path = usermask ? usermask : ioinfo[irq]->opm; -#ifdef CONFIG_CHSC - old_opm = ioinfo[irq]->opm; + if (ioinfo[irq]->ui.flags.pgid == 0) { + memcpy (&ioinfo[irq]->pgid, global_pgid, sizeof (pgid_t)); + ioinfo[irq]->ui.flags.pgid = 1; + } + + for (i = 0; i < 8 && !ret; i++) { + + domask = dev_path & (0x80>>i); + + if (!domask) + continue; + + if (!test_bit(ioinfo[irq]->schib.pmcw.chpid[i], + &chpids_logical)) + /* Chpid is logically offline, don't do io */ + continue; + + ret = s390_SetPGID (irq, domask); + + /* + * For the *first* path we are prepared for recovery + * + * - If we fail setting the PGID we assume its + * using a different PGID already (VM) we + * try to sense. + */ + if (ret == -EOPNOTSUPP && first) { + *(int *) &pgid = 0; + + ret = s390_SensePGID (irq, domask, &pgid); + first = 0; + + if (ret == 0) { + /* + * Check whether we retrieved + * a reasonable PGID ... + */ + if (pgid.inf.ps.state1 == SNID_STATE1_GROUPED) + memcpy (&ioinfo[irq]->pgid, + &pgid, sizeof (pgid_t)); + else /* ungrouped or garbage ... */ + ret = -EOPNOTSUPP; + + } else { + ioinfo[irq]->ui.flags.pgid_supp = 0; + +#ifdef CONFIG_DEBUG_IO + printk (KERN_WARNING + "PathVerification(%04X) - Device %04X " + "doesn't support path grouping\n", + irq, ioinfo[irq]->schib.pmcw.dev); +#endif + CIO_MSG_EVENT(2, "PathVerification(%04X) " + "- Device %04X doesn't " + " support path grouping\n", + irq, + ioinfo[irq]->schib.pmcw.dev); + + } + } else if (ret == -EIO) { +#ifdef CONFIG_DEBUG_IO + printk (KERN_ERR "PathVerification(%04X) - I/O error " + "on device %04X\n", irq, + ioinfo[irq]->schib.pmcw.dev); +#endif + + CIO_MSG_EVENT(2, "PathVerification(%04X) - I/O error " + "on device %04X\n", irq, + ioinfo[irq]->schib.pmcw.dev); + + ioinfo[irq]->ui.flags.pgid_supp = 0; + + } else if (ret == -ETIMEDOUT) { +#ifdef CONFIG_DEBUG_IO + printk (KERN_ERR "PathVerification(%04X) - I/O timed " + "out on device %04X\n", irq, + ioinfo[irq]->schib.pmcw.dev); +#endif + CIO_MSG_EVENT(2, "PathVerification(%04X) - I/O timed " + "out on device %04X\n", irq, + ioinfo[irq]->schib.pmcw.dev); + + ioinfo[irq]->ui.flags.pgid_supp = 0; + + } else if (ret == -EAGAIN) { + + ret = 0; + } else if (ret == -EUSERS) { + +#ifdef CONFIG_DEBUG_IO + printk (KERN_ERR "PathVerification(%04X) " + "- Device is locked by someone else!\n", + irq); +#endif + CIO_MSG_EVENT(2, "PathVerification(%04X) " + "- Device is locked by someone else!\n", + irq); + } else if (ret == -ENODEV) { +#ifdef CONFIG_DEBUG_IO + printk (KERN_ERR "PathVerification(%04X) " + "- Device %04X is no longer there?!?\n", + irq, ioinfo[irq]->schib.pmcw.dev); +#endif + CIO_MSG_EVENT(2, "PathVerification(%04X) " + "- Device %04X is no longer there?!?\n", + irq, ioinfo[irq]->schib.pmcw.dev); + + } else if (ret == -EBUSY) { + /* + * The device is busy. Schedule the path verification + * bottom half and we'll hopefully get in next time. + */ + if (!ioinfo[irq]->ui.flags.noio) { + s390_schedule_path_verification(irq); + } + return -EINPROGRESS; + } else if (ret) { +#ifdef CONFIG_DEBUG_IO + printk (KERN_ERR "PathVerification(%04X) " + "- Unexpected error %d on device %04X\n", + irq, ret, ioinfo[irq]->schib.pmcw.dev); +#endif + CIO_MSG_EVENT(2, "PathVerification(%04X) - " + "Unexpected error %d on device %04X\n", + irq, ret, ioinfo[irq]->schib.pmcw.dev); + + ioinfo[irq]->ui.flags.pgid_supp = 0; + } + } + if (stsch(irq, &ioinfo[irq]->schib) != 0) + /* FIXME: tell driver device is dead. */ + return -ENODEV; + + /* + * stsch() doesn't always yield the correct pim, pam, and pom + * values, if no device selection has been performed yet. + * However, after complete path verification they are up to date. + */ + ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim & + ioinfo[irq]->schib.pmcw.pam & + ioinfo[irq]->schib.pmcw.pom; + +#ifdef CONFIG_CHSC + if (ioinfo[irq]->opm) { + for (i=0;i<=7;i++) { + int mask = 0x80 >> i; + if ((ioinfo[irq]->opm & mask) && + (!test_bit(ioinfo[irq]->schib.pmcw.chpid[i], + &chpids_logical))) + /* disable using this path */ + ioinfo[irq]->opm &= ~mask; + } + } +#endif /* CONFIG_CHSC */ + + ioinfo[irq]->ui.flags.noio = 0; + + /* Eventually wake up the device driver. */ + if (ioinfo[irq]->opm != 0) { + devreg_t *pdevreg; + pdevreg = s390_search_devreg(ioinfo[irq]); + + if (pdevreg && pdevreg->oper_func) + pdevreg->oper_func(irq, pdevreg); + } + return ret; + +} + +/* + * Device Path Verification + * + * Path verification is accomplished by checking which paths (CHPIDs) are + * available. Further, a path group ID is set, if possible in multipath + * mode, otherwise in single path mode. + * + * Note : This function must not be called during normal device recognition, + * but during device driver initiated request_irq() processing only. + */ +int +s390_DevicePathVerification (int irq, __u8 usermask) +{ + int ccode; +#ifdef CONFIG_CHSC + int chp; + int mask; + int old_opm = 0; +#endif /* CONFIG_CHSC */ + + int ret = 0; + + char dbf_txt[15]; + devreg_t *pdevreg; + + sprintf (dbf_txt, "dpver%x", irq); + CIO_TRACE_EVENT (4, dbf_txt); + + if (ioinfo[irq]->st) + return -ENODEV; + +#ifdef CONFIG_CHSC + old_opm = ioinfo[irq]->opm; #endif /* CONFIG_CHSC */ ccode = stsch (irq, &(ioinfo[irq]->schib)); - if (ccode) { + if (ccode) return -ENODEV; - } + if (ioinfo[irq]->schib.pmcw.pim == 0x80) { /* * no error, just not required for single path only devices */ ioinfo[irq]->ui.flags.pgid_supp = 0; ret = 0; + ioinfo[irq]->ui.flags.noio = 0; #ifdef CONFIG_CHSC /* @@ -5699,58 +5838,35 @@ */ if (!test_bit(ioinfo[irq]->schib.pmcw.chpid[0], &chpids_logical)) { - not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc; - int was_oper = ioinfo[irq]->ui.flags.oper; ioinfo[irq]->opm = 0; ioinfo[irq]->ui.flags.oper = 0; printk(KERN_WARNING "No logical path for sch %d...\n", irq); - if (old_opm && - was_oper && - ioinfo[irq]->ui.flags.ready) { -#ifdef CONFIG_PROC_FS - if (cio_proc_devinfo) - cio_procfs_device_remove - (ioinfo[irq]->devno); -#endif /* CONFIG_PROC_FS */ - free_irq( irq, ioinfo[irq]->irq_desc.dev_id); - if (nopfunc) - nopfunc( irq, DEVSTAT_DEVICE_GONE); - } - ret = -ENODEV; - } else if (!old_opm) { - /* - * check for opm... - */ + if (ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + + return -ENODEV; + } + if (!old_opm) { + ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom; - + if (ioinfo[irq]->opm) { - devreg_t *pdevreg; ioinfo[irq]->ui.flags.oper = 1; - pdevreg = s390_search_devreg( ioinfo[irq] ); - - if (pdevreg) - if (pdevreg->oper_func) - pdevreg->oper_func - ( irq, pdevreg); -#ifdef CONFIG_PROC_FS - if (cio_proc_devinfo) - if (highest_subchannel - < MAX_CIO_PROCFS_ENTRIES) { - cio_procfs_device_create - (ioinfo[irq]->devno); - } -#endif /* CONFIG_PROC_FS */ + pdevreg = s390_search_devreg(ioinfo[irq]); + + if (pdevreg && pdevreg->oper_func) + pdevreg->oper_func(irq, pdevreg); + ret = 0; + } else { + ret = -ENODEV; } - ret = 0; - } else { - ret = 0; } #endif /* CONFIG_CHSC */ return ret; @@ -5763,199 +5879,72 @@ if (ioinfo[irq]->opm) { for (chp=0;chp<=7;chp++) { mask = 0x80 >> chp; - if (ioinfo[irq]->opm & mask) { - if (!test_bit - (ioinfo[irq]->schib.pmcw.chpid[chp], - &chpids_logical)) { - /* disable using this path */ - ioinfo[irq]->opm &= ~mask; - } - } + if ((ioinfo[irq]->opm & mask) + &&(!test_bit(ioinfo[irq]->schib.pmcw.chpid[chp], + &chpids_logical))) + /* disable using this path */ + ioinfo[irq]->opm &= ~mask; } } - if ((ioinfo[irq]->opm == 0) && (old_opm)) { - not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc; - int was_oper = ioinfo[irq]->ui.flags.ready; - - ioinfo[irq]->ui.flags.oper = 0; - printk(KERN_WARNING "No logical path for sch %d...\n",irq); - if (was_oper && ioinfo[irq]->ui.flags.oper) { -#ifdef CONFIG_PROC_FS - if (cio_proc_devinfo) - cio_procfs_device_remove(ioinfo[irq]->devno); -#endif /* CONFIG_PROC_FS */ - free_irq( irq, ioinfo[irq]->irq_desc.dev_id); - if (nopfunc) - nopfunc( irq, DEVSTAT_DEVICE_GONE); - } - return -ENODEV; - } - - if (!old_opm) { - /* Hey, we have a new logical path... */ - devreg_t *pdevreg; - - ioinfo[irq]->ui.flags.oper = 1; - pdevreg = s390_search_devreg( ioinfo[irq] ); - - if (pdevreg) - if (pdevreg->oper_func) - pdevreg->oper_func( irq, pdevreg); -#ifdef CONFIG_PROC_FS - if (cio_proc_devinfo) - if (highest_subchannel < MAX_CIO_PROCFS_ENTRIES) { - cio_procfs_device_create(ioinfo[irq]->devno); - } -#endif /* CONFIG_PROC_FS */ - } #endif /* CONFIG_CHSC */ - if ( ioinfo[irq]->ui.flags.pgid_supp == 0 ) - return( 0); /* just exit ... */ + if (ioinfo[irq]->ui.flags.pgid_supp == 0) { - if (usermask) { - dev_path = usermask; - } else { - dev_path = ioinfo[irq]->opm; + if (ioinfo[irq]->opm == 0) + return -ENODEV; + + ioinfo[irq]->ui.flags.oper = 1; + ioinfo[irq]->ui.flags.noio = 0; - } + pdevreg = s390_search_devreg(ioinfo[irq]); + + if (pdevreg && pdevreg->oper_func) + pdevreg->oper_func(irq, pdevreg); - if (ioinfo[irq]->ui.flags.pgid == 0) { - memcpy (&ioinfo[irq]->pgid, global_pgid, sizeof (pgid_t)); - ioinfo[irq]->ui.flags.pgid = 1; + return 0; } - for (i = 0; i < 8 && !ret; i++) { - pathmask = 0x80 >> i; - - domask = dev_path & pathmask; - - if (domask) { - ret = s390_SetPGID (irq, domask); - - /* - * For the *first* path we are prepared - * for recovery - * - * - If we fail setting the PGID we assume its - * using a different PGID already (VM) we - * try to sense. - */ - if (ret == -EOPNOTSUPP && first) { - *(int *) &pgid = 0; - - ret = s390_SensePGID (irq, domask, &pgid); - first = 0; - - if (ret == 0) { - /* - * Check whether we retrieved - * a reasonable PGID ... - */ - if (pgid.inf.ps.state1 == - SNID_STATE1_GROUPED) { - memcpy (&ioinfo[irq]->pgid, - &pgid, sizeof (pgid_t)); - } else { /* ungrouped or garbage ... */ - ret = -EOPNOTSUPP; - - } - } else { - ioinfo[irq]->ui.flags.pgid_supp = 0; - -#ifdef CONFIG_DEBUG_IO - printk (KERN_WARNING - "PathVerification(%04X) " - "- Device %04X doesn't " - " support path grouping\n", - irq, - ioinfo[irq]->schib.pmcw.dev); -#endif - CIO_MSG_EVENT(2, - "PathVerification(%04X) " - "- Device %04X doesn't " - " support path grouping\n", - irq, - ioinfo[irq]->schib. - pmcw.dev); - - } - } else if (ret == -EIO) { -#ifdef CONFIG_DEBUG_IO - printk (KERN_ERR - "PathVerification(%04X) - I/O error " - "on device %04X\n", irq, - ioinfo[irq]->schib.pmcw.dev); -#endif + return s390_do_path_verification (irq, usermask); - CIO_MSG_EVENT(2, - "PathVerification(%04X) - I/O error " - "on device %04X\n", irq, - ioinfo[irq]->schib.pmcw.dev); - - ioinfo[irq]->ui.flags.pgid_supp = 0; +} - } else if (ret == -ETIMEDOUT) { -#ifdef CONFIG_DEBUG_IO - printk (KERN_ERR - "PathVerification(%04X) - I/O timed " - "out on device %04X\n", - irq, - ioinfo[irq]->schib.pmcw.dev); -#endif - CIO_MSG_EVENT(2, - "PathVerification(%04X) - I/O timed " - "out on device %04X\n", irq, - ioinfo[irq]->schib.pmcw.dev); - - ioinfo[irq]->ui.flags.pgid_supp = 0; +void +s390_kick_path_verification (unsigned long irq) +{ + long cr6 __attribute__ ((aligned (8))); - } else if (ret == -EAGAIN) { + atomic_set (&ioinfo[irq]->pver_pending, 0); + /* Do not enter path verification if sync_isc is enabled. */ + __ctl_store (cr6, 6, 6); + if (cr6 & 0x04000000) { + s390_schedule_path_verification (irq); + return; + } + ioinfo[irq]->ui.flags.killio = 0; + s390_DevicePathVerification(irq, 0xff); - ret = 0; +} - } else if (ret == -EUSERS) { - -#ifdef CONFIG_DEBUG_IO - printk (KERN_ERR - "PathVerification(%04X) " - "- Device is locked by someone else!\n", - irq); -#endif - CIO_MSG_EVENT(2, - "PathVerification(%04X) " - "- Device is locked by someone else!\n", - irq); - } else if (ret == -ENODEV) { -#ifdef CONFIG_DEBUG_IO - printk (KERN_ERR - "PathVerification(%04X) " - "- Device %04X is no longer there?!?\n", - irq, ioinfo[irq]->schib.pmcw.dev); -#endif - CIO_MSG_EVENT(2, - "PathVerification(%04X) " - "- Device %04X is no longer there?!?\n", - irq, ioinfo[irq]->schib.pmcw.dev); - } else if (ret) { -#ifdef CONFIG_DEBUG_IO - printk (KERN_ERR - "PathVerification(%04X) " - "- Unexpected error %d on device %04X\n", - irq, ret, ioinfo[irq]->schib.pmcw.dev); -#endif - CIO_MSG_EVENT(2, - "PathVerification(%04X) - " - "Unexpected error %d on device %04X\n", - irq, ret, ioinfo[irq]->schib.pmcw.dev); - - ioinfo[irq]->ui.flags.pgid_supp = 0; - } - } +static void +s390_schedule_path_verification(unsigned long irq) +{ + /* Protect against rescheduling, when already running */ + if (atomic_compare_and_swap (0, 1, &ioinfo[irq]->pver_pending)) { + return; } - return ret; + /* + * Call path verification. + * Note this is always called from inside the i/o layer, so we don't + * need to care about the usermask. + */ + INIT_LIST_HEAD (&ioinfo[irq]->pver_bh.list); + ioinfo[irq]->pver_bh.sync = 0; + ioinfo[irq]->pver_bh.routine = (void*) (void*) s390_kick_path_verification; + ioinfo[irq]->pver_bh.data = (void*) irq; + queue_task (&ioinfo[irq]->pver_bh, &tq_immediate); + mark_bh (IMMEDIATE_BH); } /* @@ -6018,10 +6007,15 @@ s390irq_spin_lock_irqsave (irq, flags); if (init_IRQ_complete) { - spid_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA); + spid_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA | GFP_ATOMIC); } else { spid_ccw = alloc_bootmem_low (2 * sizeof (ccw1_t)); - + } + if (!spid_ccw) { + s390irq_spin_unlock_irqrestore(irq, flags); + if (inlreq) + free_irq(irq, pdevstat); + return -ENOMEM; } spid_ccw[0].cmd_code = CCW_CMD_SUSPEND_RECONN; @@ -6056,17 +6050,19 @@ printk (KERN_DEBUG "SPID - Device %04X " "on Subchannel %04X " "reports pending status, " + "lpm = %x, " "retry : %d\n", ioinfo[irq]->schib.pmcw.dev, - irq, retry); + irq, lpm, retry); #endif CIO_MSG_EVENT(2, "SPID - Device %04X " "on Subchannel %04X " "reports pending status, " + "lpm = %x, " "retry : %d\n", ioinfo[irq]->schib.pmcw. - dev, irq, retry); + dev, irq, lpm, retry); retry--; irq_ret = -EIO; } @@ -6117,11 +6113,12 @@ "SPID - device %04X," " unit check," " retry %d, cnt %02d," - " sns :" + " lpm %x, sns :" " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", ioinfo[irq]->schib.pmcw. dev, retry, pdevstat->scnt, + lpm, pdevstat->ii.sense. data[0], pdevstat->ii.sense. @@ -6143,11 +6140,12 @@ "SPID - device %04X," " unit check," " retry %d, cnt %02d," - " sns :" + " lpm %x, sns :" " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", ioinfo[irq]->schib. pmcw.dev, retry, pdevstat->scnt, + lpm, pdevstat->ii.sense. data[0], pdevstat->ii.sense. @@ -6174,7 +6172,7 @@ /* don't issue warnings during startup unless requested */ if (init_IRQ_complete || cio_notoper_msg) { - printk (KERN_WARNING + printk (KERN_INFO "SPID - Device %04X " "on Subchannel %04X, " "lpm %02X, " @@ -6214,12 +6212,52 @@ irq); retry--; + } else if (irq_ret == -EBUSY) { +#ifdef CONFIG_DEBUG_IO + printk(KERN_WARNING + "SPID - device %x, irq %x is busy!\n", + ioinfo[irq]->schib.pmcw.dev, irq); +#endif /* CONFIG_DEBUG_IO */ + CIO_MSG_EVENT(2, + "SPID - device %x, irq %x is busy!\n", + ioinfo[irq]->schib.pmcw.dev, irq); + retry = 0; + } else if (irq_ret != -ENODEV) { retry--; irq_ret = -EIO; - } else { + } else if (!pdevstat->flag & DEVSTAT_NOT_OPER) { retry = 0; irq_ret = -ENODEV; + } else { + /* don't issue warnings during startup unless requested */ + if (init_IRQ_complete || cio_notoper_msg) { + + printk (KERN_INFO + "SPID - Device %04X " + "on Subchannel %04X, " + "lpm %02X, " + "became 'not operational'\n", + ioinfo[irq]->schib.pmcw. + dev, irq, + lpm); + CIO_MSG_EVENT(2, + "SPID - Device %04X " + "on Subchannel %04X, " + "lpm %02X, " + "became 'not operational'\n", + ioinfo[irq]->schib. + pmcw.dev, irq, + lpm); + } + + retry = 0; + ioinfo[irq]->opm &= ~lpm; + + if (ioinfo[irq]->opm != 0) + irq_ret = -EAGAIN; + else + irq_ret = -ENODEV; } @@ -6302,13 +6340,32 @@ ioinfo[irq]->ui.flags.unfriendly = 0; /* assume it's friendly... */ if (init_IRQ_complete) { - snid_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA); - tmp_pgid = kmalloc (sizeof (pgid_t), GFP_DMA); + snid_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA | GFP_ATOMIC); + tmp_pgid = kmalloc (sizeof (pgid_t), GFP_DMA | GFP_ATOMIC); } else { snid_ccw = alloc_bootmem_low (sizeof (ccw1_t)); tmp_pgid = alloc_bootmem_low (sizeof (pgid_t)); } + if (!snid_ccw || !tmp_pgid) { + if (snid_ccw) { + if (init_IRQ_complete) + kfree(snid_ccw); + else + free_bootmem((unsigned long) snid_ccw, sizeof(ccw1_t)); + } + if (tmp_pgid) { + if (init_IRQ_complete) + kfree(tmp_pgid); + else + free_bootmem((unsigned long) tmp_pgid, sizeof(pgid_t)); + } + s390irq_spin_unlock_irqrestore(irq, flags); + if (inlreq) + free_irq (irq, pdevstat); + return -ENOMEM; + } + snid_ccw->cmd_code = CCW_CMD_SENSE_PGID; snid_ccw->cda = (__u32) virt_to_phys (tmp_pgid); snid_ccw->count = sizeof (pgid_t); @@ -6335,8 +6392,8 @@ * Sense Path Group ID command * further retries wouldn't help ... */ - if (pdevstat->ii.sense.data[0] & - (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) { + if (pdevstat->ii.sense.data[0] + & (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) { retry = 0; irq_ret = -EOPNOTSUPP; } else { @@ -6403,7 +6460,7 @@ } else if (pdevstat->flag & DEVSTAT_NOT_OPER) { /* don't issue warnings during startup unless requested */ if (init_IRQ_complete || cio_notoper_msg) { - printk (KERN_WARNING + printk (KERN_INFO "SNID - Device %04X " "on Subchannel %04X, " "lpm %02X, " @@ -6422,7 +6479,8 @@ } retry = 0; - irq_ret = -EIO; + ioinfo[irq]->opm &= ~lpm; + irq_ret = -EAGAIN; } else { retry = 0; /* success ... */ @@ -6432,7 +6490,7 @@ * -- we'll fail other commands if that is * the case */ - if (pgid->inf.ps.state2 == + if (tmp_pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { printk (KERN_WARNING "SNID - Device %04X " @@ -6507,10 +6565,38 @@ ioinfo[irq]->schib.pmcw.dev, irq_ret); retry--; irq_ret = -EIO; - } else { /* -ENODEV ... */ - + } else if (!pdevstat->flag & DEVSTAT_NOT_OPER) { retry = 0; irq_ret = -ENODEV; + } else { + /* don't issue warnings during startup unless requested */ + if (init_IRQ_complete || cio_notoper_msg) { + + printk (KERN_INFO + "SNID - Device %04X " + "on Subchannel %04X, " + "lpm %02X, " + "became 'not operational'\n", + ioinfo[irq]->schib.pmcw. + dev, irq, + lpm); + CIO_MSG_EVENT(2, + "SNID - Device %04X " + "on Subchannel %04X, " + "lpm %02X, " + "became 'not operational'\n", + ioinfo[irq]->schib. + pmcw.dev, irq, + lpm); + } + + retry = 0; + ioinfo[irq]->opm &= ~lpm; + + if (ioinfo[irq]->opm != 0) + irq_ret = -EAGAIN; + else + irq_ret = -ENODEV; } @@ -6650,12 +6736,9 @@ pdevreg = s390_search_devreg (ioinfo[irq]); - if (pdevreg != NULL) { - if (pdevreg->oper_func != NULL) - pdevreg-> - oper_func (irq, pdevreg); + if (pdevreg && pdevreg->oper_func) + pdevreg->oper_func(irq, pdevreg); - } #ifdef CONFIG_PROC_FS /* add new procfs entry */ if (cio_proc_devinfo) @@ -6995,19 +7078,120 @@ __initcall(chsc_get_sch_descriptions); +static int +__check_for_io_and_kill(int irq, __u8 mask, int fatal) +{ + schib_t *schib = &ioinfo[irq]->schib; + int ret = 0; + + if (schib->scsw.actl & SCSW_ACTL_DEVACT) { + if ((ioinfo[irq]->opm != mask) || + (fatal == 0)) { + ret = CIO_PATHGONE_WAIT4INT; + } + if ((schib->scsw.actl & SCSW_ACTL_SCHACT) && + (schib->pmcw.lpum == mask) && + (fatal != 0)) { + int cc; + /* Kill the IO. It won't complete. */ + ioinfo[irq]->ui.flags.noio = 0; + ioinfo[irq]->ui.flags.killio = 1; + cc = clear_IO(irq, 0xD2C9D3D3, 0); + if (cc != 0) { + /* Eek, can't kill io. */ + CIO_CRW_EVENT(0, + "Can't kill io on " + "sch %x, clear_IO " + "returned %d!\n", + irq, cc); + ioinfo[irq]->ui.flags.killio = 0; + s390irq_spin_unlock(irq); + if ((cc == -ENODEV) && + (ioinfo[irq]->nopfunc)) { + ioinfo[irq]->ui.flags.oper = 0; + ioinfo[irq]->nopfunc(irq, + DEVSTAT_DEVICE_GONE); + } + ret = CIO_PATHGONE_DEVGONE; + } else { + ret |= CIO_PATHGONE_WAIT4INT; + } + ioinfo[irq]->ui.flags.noio = 1; + ret |= CIO_PATHGONE_IOERR; + } + + } else if (schib->scsw.actl & (SCSW_ACTL_CLEAR_PEND | + SCSW_ACTL_HALT_PEND | + SCSW_ACTL_START_PEND | + SCSW_ACTL_RESUME_PEND)) { + if ((schib->pmcw.lpum != mask) || + (fatal == 0)) { + ret = CIO_PATHGONE_WAIT4INT; + } else { + int cc; + /* Cancel the i/o. */ + cc = cancel_IO(irq); + switch (cc) { + case 0: + /* i/o cancelled; we can do path verif. */ + ret = CIO_PATHGONE_IOERR; + break; + case -EBUSY: + /* Status pending, we'll get an interrupt */ + ret = CIO_PATHGONE_WAIT4INT; + break; + case -EINVAL: + /* + * There is either not only the start function + * specified or we are subchannel active. + * Do a clear sch. + */ + ioinfo[irq]->ui.flags.noio = 0; + ioinfo[irq]->ui.flags.killio = 1; + cc = clear_IO(irq, 0xD2C9D3D3, 0); + if (cc != 0) { + /* Eek, can't kill io. */ + CIO_CRW_EVENT(0, + "Can't kill io on " + "sch %x, clear_IO " + "returned %d!\n", + irq, cc); + ioinfo[irq]->ui.flags.killio = 0; + s390irq_spin_unlock(irq); + if ((cc == -ENODEV) && + (ioinfo[irq]->nopfunc)) { + ioinfo[irq]->nopfunc(irq, + DEVSTAT_DEVICE_GONE); + ioinfo[irq]->ui.flags.oper = 0; + } + ret = CIO_PATHGONE_DEVGONE; + } else { + ret = CIO_PATHGONE_WAIT4INT + | CIO_PATHGONE_IOERR; + ioinfo[irq]->ui.flags.noio = 1; + } + break; + default: /* -ENODEV */ + s390irq_spin_unlock(irq); + if (ioinfo[irq]->nopfunc) { + ioinfo[irq]->ui.flags.oper = 0; + ioinfo[irq]->nopfunc(irq, + DEVSTAT_DEVICE_GONE); + } + ret = CIO_PATHGONE_DEVGONE; + } + } + } + return ret; +} + void s390_do_chpid_processing( __u8 chpid) { int irq; int j; - int mask; char dbf_txt[15]; - int ccode; - int was_oper; - int chp = 0; - int mask2; - int ret = 0; sprintf(dbf_txt, "chpr%x", chpid); CIO_TRACE_EVENT( 2, dbf_txt); @@ -7017,141 +7201,82 @@ * but the chpid the report came in through. How to handle??? */ clear_bit(chpid, &chpids); - if (!test_and_clear_bit(chpid, &chpids_known)) + if (!test_and_clear_bit(chpid, &chpids_known)) { +#ifdef CONFIG_DEBUG_CHSC + pr_debug(KERN_DEBUG"Got link incident for unknown chpid %x\n", + chpid); +#endif /* CONFIG_DEBUG_CHSC */ return; /* we didn't know the chpid anyway */ + } for (irq=0;irq<=highest_subchannel;irq++) { + schib_t *schib; + if (ioinfo[irq] == INVALID_STORAGE_AREA) continue; /* we don't know the device anyway */ if (ioinfo[irq]->st) continue; /* non-io subchannel */ + schib = &ioinfo[irq]->schib; for (j=0; j<8;j++) { - if (ioinfo[irq]->schib.pmcw.chpid[j] == chpid) { - - /* - * Send nops down each path to find out - * which path is gone (ssch will yield cc=3 - * and the path will be switched off in the opm) - */ - - /* - * Note: irq spinlock is grabbed several times - * in here - */ - for (chp=0;chp<=7;chp++) { - mask2 = 0x80 >> chp; - if (mask2 & ioinfo[irq]->opm) - ret = s390_send_nop (irq, mask2); - } - - s390irq_spin_lock(irq); - - /* - * FIXME: is this neccessary? - */ - ccode = stsch(irq, &ioinfo[irq]->schib); - if (ccode) { -#ifdef CONFIG_DEBUG_CRW - printk( KERN_WARNING - "do_crw_pending: device on " - "sch %x is not operational\n", - irq); -#endif /* CONFIG_DEBUG_CRW */ - CIO_CRW_EVENT( 2, - "device on sch %x is " - "not operational\n", - irq); - ioinfo[irq]->ui.flags.oper = 0; + int mask = 0x80 >> j; + int out = 0; + int err = 0; + + if (schib->pmcw.chpid[j] != chpid) + continue; + + if (stsch(irq, schib) != 0) { + ioinfo[irq]->ui.flags.oper = 0; + if (ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_DEVICE_GONE); + break; + } + + s390irq_spin_lock(irq); + + ioinfo[irq]->ui.flags.noio = 1; + + /* Do we still expect an interrupt for outstanding io? */ + if (ioinfo[irq]->ui.flags.busy) { + int rck = __check_for_io_and_kill(irq, mask, 1); + if (rck & CIO_PATHGONE_WAIT4INT) + out=1; + if (rck & CIO_PATHGONE_IOERR) + err=1; + if (rck & CIO_PATHGONE_DEVGONE) break; - } - - ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim & - ioinfo[irq]->schib.pmcw.pam & - ioinfo[irq]->schib.pmcw.pom; - - if (ioinfo[irq]->opm) { - for (chp=0;chp<=7;chp++) { - mask2 = 0x80 >> chp; - if (ioinfo[irq]->opm & mask2) { - if (!test_bit - (ioinfo[irq]-> - schib.pmcw.chpid[chp], - &chpids_logical)) { - /* disable using this path */ - ioinfo[irq]->opm - &= ~mask2; - } - } - } - } + } + + s390irq_spin_unlock(irq); + + /* Tell the device driver not to disturb us. */ + if (ioinfo[irq]->ui.flags.ready && + schib->pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc) { + if (err) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC_ERR); + else + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + } - if (!ioinfo[irq]->opm) { - /* - * sh*t, our last path has gone... - * Set the device status to not operational - * and eventually notify the device driver - */ -#ifdef CONFIG_DEBUG_CRW - printk( KERN_WARNING - "do_crw_pending: Last path gone for " - "device %x, sch %x\n", - ioinfo[irq]->devno, irq); -#endif /* CONFIG_DEBUG_CRW */ - CIO_CRW_EVENT( 2, - "Last path gone for " - "device %x, sch %x\n", - ioinfo[irq]->devno, - irq); - - was_oper = ioinfo[irq]->ui.flags.oper; - - ioinfo[irq]->ui.flags.oper = 0; - - if (was_oper && ioinfo[irq]->ui.flags.ready) { - - not_oper_handler_func_t nopfunc = - ioinfo[irq]->nopfunc; -#ifdef CONFIG_PROC_FS - if (cio_proc_devinfo) - cio_procfs_device_remove - (ioinfo[irq]->devno); -#endif /* CONFIG_PROC_FS */ - free_irq(irq, - ioinfo[irq]->irq_desc.dev_id); - if (nopfunc) - nopfunc(irq, - DEVSTAT_DEVICE_GONE); - } - - } else if (ioinfo[irq]->ui.flags.ready) { - /* - * Re-do path verification for the chpid in question - * FIXME: is this neccessary? - */ - mask = 0x80 >> j; + ioinfo[irq]->opm &= ~mask; + + if (out) + break; - if (!s390_DevicePathVerification(irq,mask)) { -#ifdef CONFIG_DEBUG_CRW - printk( KERN_DEBUG - "DevicePathVerification " - "successful for" - " Subchannel %x, " - "chpid %x\n", - irq, chpid); -#endif /* CONFIG_DEBUG_CRW */ - CIO_CRW_EVENT( 2, - "DevicePathVerification " - "successful for" - " Subchannel %x, " - "chpid %x\n", - irq, chpid); - } - } - - j=8; - s390irq_spin_unlock(irq); + /* + * Always schedule the path verification, even if opm=0. + * Reason: We can't rely on stsch() to return latest&greatest + * values, if a device selections hasn't been performed, and + * we might miss a path we didn't get a mchk for. + */ + if (ioinfo[irq]->ui.flags.ready) + s390_schedule_path_verification(irq); + else { + ioinfo[irq]->ui.flags.noio = 0; + ioinfo[irq]->ui.flags.killio = 0; } - + break; } } } @@ -7163,13 +7288,11 @@ char dbf_txt[15]; int irq = 0; - int ccode; __u32 fla_mask = 0xffff; int chp; - int mask, mask2; - int ret; + int mask; - sprintf(dbf_txt, "accp%x", chpid); + sprintf(dbf_txt, "accpr%x", chpid); CIO_TRACE_EVENT( 2, dbf_txt); if (info != CHSC_SEI_ACC_CHPID) { sprintf(dbf_txt, "fla%x", fla); @@ -7204,8 +7327,13 @@ return; } - if (!test_bit(chpid, &chpids_logical)) + if (!test_bit(chpid, &chpids_logical)) { +#ifdef CONFIG_DEBUG_CHSC + printk(KERN_DEBUG"chpid %x is logically offline, " + "skipping res acc processing\n", chpid); +#endif /* CONFIG_DEBUG_CHSC */ return; /* no need to do the rest */ + } switch (info) { case CHSC_SEI_ACC_CHPID: /* @@ -7216,62 +7344,13 @@ printk( KERN_DEBUG "Looking at chpid %x...\n", chpid); #endif /* CONFIG_DEBUG_CHSC */ - for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) { + for (irq=0; irq<__MAX_SUBCHANNELS; irq++) { if((ioinfo[irq] != INVALID_STORAGE_AREA) - && (!ioinfo[irq]->st)) { + && (ioinfo[irq]->st != 0)) + continue; - /* - * Send nops down each path to find out - * which path is there - */ - - for (chp=0;chp<=7;chp++) { - mask = 0x80 >> chp; - - /* - * check if chpid is in information - * updated by ssd - */ - if ((ioinfo[irq]->ssd_info.valid) && - (ioinfo[irq]->ssd_info.chpid[chp] - == chpid)) - ret = s390_send_nop (irq, mask); - } - - ccode = stsch(irq, &ioinfo[irq]->schib); - if (!ccode) { - - ioinfo[irq]->opm = - ioinfo[irq]->schib.pmcw.pim & - ioinfo[irq]->schib.pmcw.pam & - ioinfo[irq]->schib.pmcw.pom; - - if (ioinfo[irq]->opm) { - for (chp=0;chp<=7;chp++) { - mask = 0x80 >> chp; - if (ioinfo[irq]->opm - & mask) { - if (!test_bit - (ioinfo[irq]-> - schib.pmcw.chpid[chp], - &chpids_logical)) { - /* disable using this path */ - ioinfo[irq]->opm - &= ~mask; - } - } - } - } - - if ((ioinfo[irq]->ui.flags.ready) - && (chpid & ioinfo[irq]->opm)) - s390_DevicePathVerification(irq, chpid); - - } else { - ioinfo[irq]->ui.flags.oper = 0; - } - } else if (ioinfo[irq] == INVALID_STORAGE_AREA) { + if (ioinfo[irq] == INVALID_STORAGE_AREA) { /* * We don't know the device yet, but since a path * may be available now to the device we'll have @@ -7291,9 +7370,41 @@ highest_subchannel = irq; if (valret == 0) s390_device_recognition_irq(irq); + continue; } - } + for (chp=0;chp<=7;chp++) { + mask = 0x80 >> chp; + + /* + * check if chpid is in information + * updated by ssd + */ + if ((!ioinfo[irq]->ssd_info.valid) || + (ioinfo[irq]->ssd_info.chpid[chp] != chpid)) + continue; + + /* Tell the device driver not to disturb us. */ + if (ioinfo[irq]->ui.flags.ready && + ioinfo[irq]->schib.pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + + ioinfo[irq]->ui.flags.noio = 1; + + /* Do we still expect an interrupt for outstanding io? */ + if (ioinfo[irq]->ui.flags.busy) + /* Wait for interrupt. */ + break; + + if (ioinfo[irq]->ui.flags.ready) { + s390_schedule_path_verification(irq); + } else + ioinfo[irq]->ui.flags.noio = 0; + + break; + } + } break; case CHSC_SEI_ACC_LINKADDR: /* @@ -7313,8 +7424,8 @@ chpid, fla); #endif /* CONFIG_DEBUG_CHSC */ - for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) { - + for (irq=0; irq<__MAX_SUBCHANNELS; irq++) { + int j; /* * Walk through all subchannels and * look if our chpid and our (masked) link @@ -7322,52 +7433,7 @@ * Do a stsch for the found subchannels and * perform path grouping */ - if ((ioinfo[irq] != INVALID_STORAGE_AREA) - && (!ioinfo[irq]->st)) { - int j; - - /* Update our ssd_info */ - if (chsc_get_sch_desc_irq(irq)) - break; - - for (j=0;j<8;j++) { - if ((ioinfo[irq]->ssd_info.chpid[j] == chpid) && - ((ioinfo[irq]->ssd_info.fla[j]&fla_mask) == fla)) { - - mask2 = 0x80 >> j; - ret = s390_send_nop (irq, mask2); - - ccode = stsch(irq,&ioinfo[irq]->schib); - if (!ccode) { - ioinfo[irq]->opm = - ioinfo[irq]->schib.pmcw.pim & - ioinfo[irq]->schib.pmcw.pam & - ioinfo[irq]->schib.pmcw.pom; - - if (ioinfo[irq]->opm) { - for (chp=0;chp<=7;chp++) { - mask = 0x80 >> chp; - if (ioinfo[irq]->opm - & mask) { - if (!test_bit - (ioinfo[irq]-> - schib.pmcw.chpid[chp], - &chpids_logical)) { - /* disable using this path */ - ioinfo[irq]->opm - &= ~mask; - } - } - } - } - - if (ioinfo[irq]->ui.flags.ready) - s390_DevicePathVerification(irq, chpid); - } - break; - } - } - } else if (ioinfo[irq] == INVALID_STORAGE_AREA) { + if (ioinfo[irq] == INVALID_STORAGE_AREA) { /* The full program again (see above), grr... */ int valret = 0; @@ -7380,10 +7446,43 @@ highest_subchannel = irq; if (valret == 0) s390_device_recognition_irq(irq); + continue; + } + if (ioinfo[irq]->st != 0) + continue; + + /* Update our ssd_info */ + if (chsc_get_sch_desc_irq(irq)) + break; + + for (j=0;j<8;j++) { + if ((ioinfo[irq]->ssd_info.chpid[j] != chpid) || + ((ioinfo[irq]->ssd_info.fla[j]&fla_mask) != fla)) + continue; + + /* Tell the device driver not to disturb us. */ + if (ioinfo[irq]->ui.flags.ready && + ioinfo[irq]->schib.pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + + ioinfo[irq]->ui.flags.noio = 1; + + /* Do we still expect an interrupt for outstanding io? */ + if (ioinfo[irq]->ui.flags.busy) + /* Wait for interrupt. */ + break; + + if (ioinfo[irq]->ui.flags.ready) { + s390_schedule_path_verification(irq); + } else + ioinfo[irq]->ui.flags.noio = 0; + break; } + break; + } - break; default: BUG(); @@ -7394,7 +7493,7 @@ s390_process_css( void ) { - int ccode; + int ccode, do_sei; CIO_TRACE_EVENT( 2, "prcss"); @@ -7414,18 +7513,26 @@ return; } - /* - * build the chsc request block for store event information - * and do the call - */ - memset(chsc_area_sei,0,sizeof(chsc_area_t)); - chsc_area_sei->request_block.command_code1=0x0010; - chsc_area_sei->request_block.command_code2=0x000E; + do_sei = 1; - ccode = chsc(chsc_area_sei); + while (do_sei) { + + do_sei = 0; + /* + * build the chsc request block for store event information + * and do the call + */ + memset(chsc_area_sei,0,sizeof(chsc_area_t)); + chsc_area_sei->request_block.command_code1=0x0010; + chsc_area_sei->request_block.command_code2=0x000E; + + ccode = chsc(chsc_area_sei); + + + if (ccode) + break; - if (!ccode) { /* for debug purposes, check for problems */ if (chsc_area_sei->response_block.response_code == 0x0003) { #ifdef CONFIG_DEBUG_CHSC @@ -7435,8 +7542,9 @@ CIO_CRW_EVENT( 2, "s390_process_css: " "error in chsc request block!\n"); - - } else if (chsc_area_sei->response_block.response_code == 0x0005) { + break; + } + if (chsc_area_sei->response_block.response_code == 0x0005) { #ifdef CONFIG_DEBUG_CHSC printk( KERN_WARNING "s390_process_css: no event information stored\n"); @@ -7444,8 +7552,9 @@ CIO_CRW_EVENT( 2, "s390_process_css: " "no event information stored\n"); - - } else if (chsc_area_sei->response_block.response_code == 0x0002) { + break; + } + if (chsc_area_sei->response_block.response_code == 0x0002) { #ifdef CONFIG_DEBUG_CHSC printk( KERN_WARNING "s390_process_css: invalid command!\n"); @@ -7453,157 +7562,350 @@ CIO_CRW_EVENT( 2, "s390_process_css: " "invalid command!\n"); + break; + } + if (chsc_area_sei->response_block.response_code != 0x0001) { +#ifdef CONFIG_DEBUG_CHSC + printk( KERN_WARNING + "s390_process_css: unknown response code %d\n", + chsc_area_sei->response_block.response_code); +#endif /* CONFIG_DEBUG_CHSC */ + CIO_CRW_EVENT( 2, + "s390_process_css: unknown response " + "code %d\n", + chsc_area_sei->response_block.response_code); + break; + } + /* everything ok */ +#ifdef CONFIG_DEBUG_CHSC + printk( KERN_DEBUG + "s390_process_css: " + "event information successfully stored\n"); +#endif /* CONFIG_DEBUG_CHSC */ + CIO_CRW_EVENT( 4, + "s390_process_css: " + "event information successfully stored\n"); + + /* Check if there is more event information pending. */ + if (chsc_area_sei->response_block.response_block_data. + sei_res.flags & 0x80) { +#ifdef CONFIG_DEBUG_CHSC + printk(KERN_INFO"s390_process_css: further event " + "information pending...\n"); +#endif /* CONFIG_DEBUG_CHSC */ + CIO_CRW_EVENT( 2, "further event information pending\n"); - } else if (chsc_area_sei->response_block.response_code == 0x0001) { - /* everything ok */ + do_sei = 1; + } + + /* Check if we might have lost some information. */ + if (chsc_area_sei->response_block.response_block_data. + sei_res.flags & 0x40) { #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG + printk(KERN_ERR"s390_process_css: Event information has " + "been lost due to overflow!\n"); +#endif /* CONFIG_DEBUG_CHSC */ + CIO_CRW_EVENT( 2, "Event information has " + "been lost due to overflow!\n"); + } + + if (chsc_area_sei->response_block. + response_block_data.sei_res.rs != 4) { +#ifdef CONFIG_DEBUG_CHSC + printk( KERN_ERR "s390_process_css: " - "event information successfully stored\n"); + "reporting source (%04X) isn't a chpid!\n", + chsc_area_sei->response_block. + response_block_data.sei_res.rsid); #endif /* CONFIG_DEBUG_CHSC */ - CIO_CRW_EVENT( 4, + CIO_CRW_EVENT( 2, "s390_process_css: " - "event information successfully stored\n"); + "reporting source (%04X) isn't a chpid!\n", + chsc_area_sei->response_block. + response_block_data.sei_res.rsid); + continue; + } - if (chsc_area_sei->response_block. - response_block_data.sei_res.rs != 4) { + /* which kind of information was stored? */ + switch (chsc_area_sei->response_block. + response_block_data.sei_res.cc) { + case 1: /* link incident*/ #ifdef CONFIG_DEBUG_CHSC - printk( KERN_ERR - "s390_process_css: " - "reporting source (%04X) isn't a chpid!" - "Aborting processing of machine check...\n", - chsc_area_sei->response_block. - response_block_data.sei_res.rsid); + printk( KERN_DEBUG + "s390_process_css: " + "channel subsystem reports link incident," + " source is chpid %x\n", + chsc_area_sei->response_block. + response_block_data.sei_res.rsid); #endif /* CONFIG_DEBUG_CHSC */ - CIO_CRW_EVENT( 2, - "s390_process_css: " - "reporting source (%04X) isn't a chpid!" - "Aborting processing of machine check...\n", - chsc_area_sei->response_block. - response_block_data.sei_res.rsid); - return; - } + CIO_CRW_EVENT( 4, + "s390_process_css: " + "channel subsystem reports " + "link incident, " + "source is chpid %x\n", + chsc_area_sei->response_block. + response_block_data.sei_res.rsid); + + s390_do_chpid_processing(chsc_area_sei->response_block. + response_block_data.sei_res.rsid); - /* which kind of information was stored? */ - switch (chsc_area_sei->response_block. - response_block_data.sei_res.cc) { - case 1: /* link incident*/ + break; + + case 2: /* i/o resource accessibiliy */ #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG - "s390_process_css: " - "channel subsystem reports link incident," - " source is chpid %x\n", - chsc_area_sei->response_block. - response_block_data.sei_res.rsid); + printk( KERN_DEBUG + "s390_process_css: channel subsystem " + "reports some I/O devices " + "may have become accessible\n"); #endif /* CONFIG_DEBUG_CHSC */ - CIO_CRW_EVENT( 4, - "s390_process_css: " - "channel subsystem reports " - "link incident, " - "source is chpid %x\n", - chsc_area_sei->response_block. - response_block_data.sei_res.rsid); - - s390_do_chpid_processing(chsc_area_sei->response_block. - response_block_data.sei_res.rsid); - - break; - - case 2: /* i/o resource accessibiliy */ + CIO_CRW_EVENT( 4, + "s390_process_css: " + "channel subsystem reports " + "some I/O devices " + "may have become accessible\n"); #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG - "s390_process_css: channel subsystem " - "reports some I/O devices " - "may have become accessable\n"); + printk( KERN_DEBUG + "Data received after sei: \n"); + printk( KERN_DEBUG + "Validity flags: %x\n", + chsc_area_sei->response_block. + response_block_data.sei_res.vf); #endif /* CONFIG_DEBUG_CHSC */ - CIO_CRW_EVENT( 4, - "s390_process_css: " - "channel subsystem reports " - "some I/O devices " - "may have become accessable\n"); + if ((chsc_area_sei->response_block. + response_block_data.sei_res.vf&0x80) + == 0) { #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG - "Data received after sei: \n"); - printk( KERN_DEBUG - "Validity flags: %x\n", - chsc_area_sei->response_block. - response_block_data.sei_res.vf); + printk( KERN_DEBUG "chpid: %x\n", + chsc_area_sei->response_block. + response_block_data.sei_res.rsid); #endif /* CONFIG_DEBUG_CHSC */ - if ((chsc_area_sei->response_block. - response_block_data.sei_res.vf&0x80) - == 0) { + s390_do_res_acc_processing + (chsc_area_sei->response_block. + response_block_data.sei_res.rsid, + 0, + CHSC_SEI_ACC_CHPID); + } else if ((chsc_area_sei->response_block. + response_block_data.sei_res.vf&0xc0) + == 0x80) { #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG "chpid: %x\n", - chsc_area_sei->response_block. - response_block_data.sei_res.rsid); + printk( KERN_DEBUG + "chpid: %x link addr: %x\n", + chsc_area_sei->response_block. + response_block_data.sei_res.rsid, + chsc_area_sei->response_block. + response_block_data.sei_res.fla); #endif /* CONFIG_DEBUG_CHSC */ - s390_do_res_acc_processing - (chsc_area_sei->response_block. - response_block_data.sei_res.rsid, - 0, - CHSC_SEI_ACC_CHPID); - } else if ((chsc_area_sei->response_block. - response_block_data.sei_res.vf&0xc0) - == 0x80) { + s390_do_res_acc_processing + (chsc_area_sei->response_block. + response_block_data.sei_res.rsid, + chsc_area_sei->response_block. + response_block_data.sei_res.fla, + CHSC_SEI_ACC_LINKADDR); + } else if ((chsc_area_sei->response_block. + response_block_data.sei_res.vf & 0xc0) + == 0xc0) { #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG - "chpid: %x link addr: %x\n", - chsc_area_sei->response_block. - response_block_data.sei_res.rsid, - chsc_area_sei->response_block. - response_block_data.sei_res.fla); + printk( KERN_DEBUG + "chpid: %x " + "full link addr: %x\n", + chsc_area_sei->response_block. + response_block_data.sei_res.rsid, + chsc_area_sei->response_block. + response_block_data.sei_res.fla); #endif /* CONFIG_DEBUG_CHSC */ - s390_do_res_acc_processing - (chsc_area_sei->response_block. - response_block_data.sei_res.rsid, - chsc_area_sei->response_block. - response_block_data.sei_res.fla, - CHSC_SEI_ACC_LINKADDR); - } else if ((chsc_area_sei->response_block. - response_block_data.sei_res.vf & 0xc0) - == 0xc0) { + s390_do_res_acc_processing + (chsc_area_sei->response_block. + response_block_data.sei_res.rsid, + chsc_area_sei->response_block. + response_block_data.sei_res.fla, + CHSC_SEI_ACC_FULLLINKADDR); + } #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG - "chpid: %x " - "full link addr: %x\n", - chsc_area_sei->response_block. - response_block_data.sei_res.rsid, - chsc_area_sei->response_block. - response_block_data.sei_res.fla); + printk( KERN_DEBUG "\n"); #endif /* CONFIG_DEBUG_CHSC */ - s390_do_res_acc_processing - (chsc_area_sei->response_block. - response_block_data.sei_res.rsid, - chsc_area_sei->response_block. - response_block_data.sei_res.fla, - CHSC_SEI_ACC_FULLLINKADDR); - } + + break; + + default: /* other stuff */ #ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG "\n"); + printk( KERN_DEBUG + "s390_process_css: event %d\n", + chsc_area_sei->response_block. + response_block_data.sei_res.cc); #endif /* CONFIG_DEBUG_CHSC */ + CIO_CRW_EVENT( 4, + "s390_process_css: event %d\n", + chsc_area_sei->response_block. + response_block_data.sei_res.cc); + + break; + + } + } + + spin_unlock(&chsc_lock_sei); +} +#endif +static void +__process_chp_gone(int irq, int chpid) +{ + schib_t *schib = &ioinfo[irq]->schib; + int i; + + for (i=0;i<8;i++) { + int mask = 0x80>>i; + int out = 0; + int err = 0; + + if (schib->pmcw.chpid[i] != chpid) + continue; + + if (stsch(irq, schib) != 0) { + ioinfo[irq]->ui.flags.oper = 0; + if (ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_DEVICE_GONE); + break; + } + + s390irq_spin_lock(irq); + + ioinfo[irq]->ui.flags.noio = 1; + + /* Do we still expect an interrupt for outstanding io? */ + if (ioinfo[irq]->ui.flags.busy) { + int rck = __check_for_io_and_kill(irq, mask, 1); + if (rck & CIO_PATHGONE_WAIT4INT) + out=1; + if (rck & CIO_PATHGONE_IOERR) + err=1; + if (rck & CIO_PATHGONE_DEVGONE) break; + } + + s390irq_spin_unlock(irq); - default: /* other stuff */ -#ifdef CONFIG_DEBUG_CHSC - printk( KERN_DEBUG - "s390_process_css: event %d\n", - chsc_area_sei->response_block. - response_block_data.sei_res.cc); -#endif /* CONFIG_DEBUG_CHSC */ - CIO_CRW_EVENT( 4, - "s390_process_css: event %d\n", - chsc_area_sei->response_block. - response_block_data.sei_res.cc); + /* Tell the device driver not to disturb us. */ + if (ioinfo[irq]->ui.flags.ready && + schib->pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc) { + if (err) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC_ERR); + else + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + } + + if (out) + break; + + if (ioinfo[irq]->ui.flags.ready) { + s390_schedule_path_verification(irq); + } else { + ioinfo[irq]->ui.flags.noio = 0; + ioinfo[irq]->ui.flags.killio = 0; + } + break; + } - break; +} - } +static void +__process_chp_come(int irq, int chpid) +{ + schib_t *schib = &ioinfo[irq]->schib; + int i; + + for (i=0;i<8;i++) { + + if (schib->pmcw.chpid[i] != chpid) + continue; + + /* Tell the device driver not to disturb us. */ + if (ioinfo[irq]->ui.flags.ready && + schib->pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + + ioinfo[irq]->ui.flags.noio = 1; + + /* Do we still expect an interrupt for outstanding io? */ + if (ioinfo[irq]->ui.flags.busy) + /* Wait for interrupt. */ + break; + + if (ioinfo[irq]->ui.flags.ready) + s390_schedule_path_verification(irq); + else + ioinfo[irq]->ui.flags.noio = 0; + + break; + } +} + +static void +s390_process_chp_source(int chpid, int onoff) +{ + int irq; + int ret; + char dbf_txt[15]; + + sprintf(dbf_txt, "prchp%x", chpid); + CIO_TRACE_EVENT(2, dbf_txt); + +#ifdef CONFIG_CHSC + if (onoff == 0) { + clear_bit(chpid, &chpids); + } else { + set_bit(chpid, &chpids); + set_bit(chpid, &chpids_known); + } +#endif /* CONFIG_CHSC */ + + if (onoff == 0) { + for (irq=0;irq<=highest_subchannel;irq++) { + + if ((ioinfo[irq] == INVALID_STORAGE_AREA) + || (ioinfo[irq]->st != 0)) + continue; + + __process_chp_gone(irq, chpid); } + return; } - spin_unlock(&chsc_lock_sei); + + for (irq=0;irq<__MAX_SUBCHANNELS;irq++) { + + if (ioinfo[irq] == INVALID_STORAGE_AREA) { + ret = s390_validate_subchannel(irq,0); + if (ret == 0) { + if (irq > highest_subchannel) + highest_subchannel = irq; +#ifdef CONFIG_DEBUG_CRW + printk(KERN_DEBUG"process_chp_source: Found " + "device on irq %x\n", irq); +#endif /* CONFIG_DEBUG_CRW */ + CIO_CRW_EVENT(4, "Found device on irq %x\n", + irq); + s390_device_recognition_irq(irq); + } + } else if (ioinfo[irq]->st == 0) { + ret = stsch(irq, &ioinfo[irq]->schib); + if (ret != 0) + ret = -ENXIO; + } else + continue; + + if (ret == -ENXIO) + /* We're through. */ + return; + + if (ret != 0) + continue; + + __process_chp_come(irq, chpid); + } + } -#endif /* * s390_do_crw_pending @@ -7657,7 +7959,24 @@ printk (KERN_NOTICE "do_crw_pending : source is " "channel path %02X\n", chpid); #endif - CIO_CRW_EVENT(2, "source is channel path %02X\n"); + CIO_CRW_EVENT(2, "source is channel path %02X\n", + chpid); + switch (pcrwe->crw.erc) { + case CRW_ERC_IPARM: /* Path has come. */ + s390_process_chp_source(chpid, 1); + break; + case CRW_ERC_PERRI: /* Path has gone. */ + s390_process_chp_source(chpid, 0); + break; + default: +#ifdef CONFIG_DEBUG_CRW + printk(KERN_WARNING"do_crw_pending: don't " + "know how to handle erc=%x\n", + pcrwe->crw.erc); +#endif /* CONFIG_DEBUG_CRW */ + CIO_CRW_EVENT(0, "don't know how to handle " + "erc=%x\n", pcrwe->crw.erc); + } break; case CRW_RSC_CONFIG: @@ -7850,6 +8169,84 @@ } } +static void +__vary_chpid_offline(int irq, int chpid) +{ + schib_t *schib = &ioinfo[irq]->schib; + int i; + + for (i=0;i<8;i++) { + int mask = 0x80>>i; + int out = 0; + unsigned long flags; + + if (ioinfo[irq]->ssd_info.chpid[i] != chpid) + continue; + + s390irq_spin_lock_irqsave(irq, flags); + + ioinfo[irq]->ui.flags.noio = 1; + + /* Hmm, the path is not really gone... */ + if (ioinfo[irq]->ui.flags.busy) { + if (__check_for_io_and_kill(irq, mask, 0) != 0) + out=1; + } + + s390irq_spin_unlock_irqrestore(irq, flags); + + /* Tell the device driver not to disturb us. */ + if (ioinfo[irq]->ui.flags.ready && + schib->pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + + if (out) + break; + + if (ioinfo[irq]->ui.flags.ready) + s390_schedule_path_verification(irq); + else + ioinfo[irq]->ui.flags.noio = 0; + + break; + } + +} + +static void +__vary_chpid_online(int irq, int chpid) +{ + schib_t *schib = &ioinfo[irq]->schib; + int i; + + for (i=0;i<8;i++) { + + if (schib->pmcw.chpid[i] != chpid) + continue; + + /* Tell the device driver not to disturb us. */ + if (ioinfo[irq]->ui.flags.ready && + schib->pmcw.pim != 0x80 && + ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); + + ioinfo[irq]->ui.flags.noio = 1; + + /* Do we still expect an interrupt for outstanding io? */ + if (ioinfo[irq]->ui.flags.busy) + /* Wait for interrupt. */ + break; + + if (ioinfo[irq]->ui.flags.ready) + s390_schedule_path_verification(irq); + else + ioinfo[irq]->ui.flags.noio = 0; + + break; + } +} + /* * Function: s390_vary_chpid @@ -7899,34 +8296,20 @@ for (irq=0;irq<=highest_subchannel;irq++) { - /* - * We don't need to adjust the opm, as this will be done in - * DevicePathVerification... - */ - if (ioinfo[irq] == INVALID_STORAGE_AREA) continue; if (ioinfo[irq]->st) continue; + + if (!ioinfo[irq]->ssd_info.valid) + continue; + + if (on) + __vary_chpid_online(irq, chpid); + else + __vary_chpid_offline(irq, chpid); - if (ioinfo[irq]->ssd_info.valid) { - if ((ioinfo[irq]->ssd_info.chpid[0] == chpid) || - (ioinfo[irq]->ssd_info.chpid[1] == chpid) || - (ioinfo[irq]->ssd_info.chpid[2] == chpid) || - (ioinfo[irq]->ssd_info.chpid[3] == chpid) || - (ioinfo[irq]->ssd_info.chpid[4] == chpid) || - (ioinfo[irq]->ssd_info.chpid[5] == chpid) || - (ioinfo[irq]->ssd_info.chpid[6] == chpid) || - (ioinfo[irq]->ssd_info.chpid[7] == chpid)) { -#ifdef CONFIG_DEBUG_CHSC - printk(KERN_DEBUG "Calling " - "DevicePathVerification for irq %d\n", - irq); -#endif /* CONFIG_DEBUG_CHSC */ - s390_DevicePathVerification(irq, 0); - } - } } return 0; @@ -8613,7 +8996,7 @@ user_len = 65536; buffer = vmalloc (user_len + 1); - + if (buffer == NULL) return -ENOMEM; if (copy_from_user (buffer, user_buf, user_len)) { @@ -8624,9 +9007,6 @@ #ifdef CONFIG_DEBUG_IO printk (KERN_DEBUG "/proc/cio_ignore: '%s'\n", buffer); #endif /* CONFIG_DEBUG_IO */ - if (cio_debug_initialized) - debug_sprintf_event (cio_debug_msg_id, 2, - "/proc/cio_ignore: '%s'\n", buffer); blacklist_parse_proc_parameters (buffer); @@ -8795,19 +9175,28 @@ chsc_get_sch_descriptions(); if (!cio_chsc_desc_avail) { len += sprintf(info->data+len, "no info available\n"); - } else { - for (i=0;idata+len, + "%02X n/a\n", + i); + else if (test_bit(i, &chpids_logical)) len += sprintf(info->data+len, "%02X online\n", i); - else if (test_bit(i, &chpids_known)) + else len += sprintf(info->data+len, - "%02X logically offline\n", + "%02X logically " + "offline\n", i); } + } + cont: info->len = len; } } @@ -8940,6 +9329,7 @@ EXPORT_SYMBOL (do_IO); EXPORT_SYMBOL (resume_IO); EXPORT_SYMBOL (ioinfo); +EXPORT_SYMBOL (diag210); EXPORT_SYMBOL (get_dev_info_by_irq); EXPORT_SYMBOL (get_dev_info_by_devno); EXPORT_SYMBOL (get_irq_by_devno); diff -urN linux-2.4.21/drivers/s390/s390mach.c linux-2.4.22/drivers/s390/s390mach.c --- linux-2.4.21/drivers/s390/s390mach.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/s390/s390mach.c 2003-08-25 04:44:42.000000000 -0700 @@ -121,7 +121,7 @@ #if 1 ctl_set_bit( 14, 28 ); // enable channel report MCH #endif -#ifdef CONFIG_MACHCK_WARNING +#ifdef CONFIG_MACHCHK_WARNING ctl_set_bit( 14, 24); /* enable warning MCH */ #endif @@ -152,7 +152,6 @@ return; } - /* * s390_do_machine_check * @@ -327,6 +326,16 @@ } /* endif */ #endif +#ifdef CONFIG_MACHCHK_WARNING + if ( pmache->mcic.mcc.mcd.w ) + { + ctrl_alt_del(); // shutdown NOW! +#ifdef S390_MACHCHK_DEBUG + printk( KERN_DEBUG "mach_handler : kill -SIGPWR init\n"); +#endif + } /* endif */ +#endif + s390_enqueue_free_mchchk( pmache ); } else @@ -655,4 +664,3 @@ return ( 1 ); } #endif - diff -urN linux-2.4.21/drivers/sbus/sbus.c linux-2.4.22/drivers/sbus/sbus.c --- linux-2.4.21/drivers/sbus/sbus.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/sbus/sbus.c 2003-08-25 04:44:42.000000000 -0700 @@ -20,6 +20,13 @@ struct sbus_bus *sbus_root = NULL; static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } }; +#ifdef CONFIG_SPARC32 +static int interrupts[PROMINTR_MAX] __initdata = { 0 }; +#endif + +#ifdef CONFIG_PCI +extern int pcic_present(void); +#endif /* Perhaps when I figure out more about the iommu we'll put a * device registration routine here that probe_sbus() calls to @@ -122,20 +129,37 @@ #else len = prom_getproperty(prom_node, "intr", (char *)irqs, sizeof(irqs)); - if (len == -1) - len = 0; - sdev->num_irqs = len / 8; - if (sdev->num_irqs == 0) { - sdev->irqs[0] = 0; - } else if (sparc_cpu_model == sun4d) { - extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq); + if (len != -1) { + sdev->num_irqs = len / 8; + if (sdev->num_irqs == 0) { + sdev->irqs[0] = 0; + } else if (sparc_cpu_model == sun4d) { + extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq); - for (len = 0; len < sdev->num_irqs; len++) - sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri); + for (len = 0; len < sdev->num_irqs; len++) + sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri); + } else { + for (len = 0; len < sdev->num_irqs; len++) + sdev->irqs[len] = irqs[len].pri; + } } else { - for (len = 0; len < sdev->num_irqs; len++) - sdev->irqs[len] = irqs[len].pri; - } + /* No "intr" node found-- check for "interrupts" node. + * This node contains SBus interrupt levels, not IPLs + * as in "intr", and no vector values. We convert + * SBus interrupt levels to PILs (platform specific). + */ + len = prom_getproperty(prom_node, "interrupts", + (char *)interrupts, sizeof(interrupts)); + if (len == -1) { + sdev->irqs[0] = 0; + sdev->num_irqs = 0; + } else { + sdev->num_irqs = len / sizeof(int); + for (len = 0; len < sdev->num_irqs; len++) { + sdev->irqs[len] = sbint_to_irq(sdev, interrupts[len]); + } + } + } #endif /* !__sparc_v9__ */ } @@ -308,7 +332,7 @@ nd = prom_searchsiblings(topnd, "sbus"); if(nd == 0) { #ifdef CONFIG_PCI - if (!pcibios_present()) { + if (!pcic_present()) { prom_printf("Neither SBUS nor PCI found.\n"); prom_halt(); } else { @@ -333,7 +357,7 @@ (nd = prom_getchild(iommund)) == 0 || (nd = prom_searchsiblings(nd, "sbus")) == 0) { #ifdef CONFIG_PCI - if (!pcibios_present()) { + if (!pcic_present()) { prom_printf("Neither SBUS nor PCI found.\n"); prom_halt(); } diff -urN linux-2.4.21/drivers/scsi/3w-xxxx.c linux-2.4.22/drivers/scsi/3w-xxxx.c --- linux-2.4.21/drivers/scsi/3w-xxxx.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/3w-xxxx.c 2003-08-25 04:44:42.000000000 -0700 @@ -165,6 +165,14 @@ Add support for "twe" character device for ioctls. Clean up request_id queueing code. Fix tw_scsi_queue() spinlocks. + 1.02.00.033 - Fix tw_aen_complete() to not queue 'queue empty' AEN's. + Initialize queues correctly when loading with no valid units. + 1.02.00.034 - Fix tw_decode_bits() to handle multiple errors. + Add support for user configurable cmd_per_lun. + Add support for sht->select_queue_depths. + 1.02.00.035 - Improve tw_allocate_memory() memory allocation. + Fix tw_chrdev_ioctl() to sleep correctly. + 1.02.00.036 - Increase character ioctl timeout to 60 seconds. */ #include @@ -232,7 +240,7 @@ }; /* Globals */ -char *tw_driver_version="1.02.00.032"; +char *tw_driver_version="1.02.00.036"; TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; int tw_device_extension_count = 0; static int twe_major = -1; @@ -271,25 +279,24 @@ printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen); } } - if (aen != 0x0) + if (aen != TW_AEN_QUEUE_EMPTY) { tw_dev->aen_count++; - /* Now queue the code */ - tw_dev->aen_queue[tw_dev->aen_tail] = aen; - if (tw_dev->aen_tail == TW_Q_LENGTH - 1) { - tw_dev->aen_tail = TW_Q_START; - } else { - tw_dev->aen_tail = tw_dev->aen_tail + 1; - } - if (tw_dev->aen_head == tw_dev->aen_tail) { - if (tw_dev->aen_head == TW_Q_LENGTH - 1) { - tw_dev->aen_head = TW_Q_START; + /* Now queue the code */ + tw_dev->aen_queue[tw_dev->aen_tail] = aen; + if (tw_dev->aen_tail == TW_Q_LENGTH - 1) { + tw_dev->aen_tail = TW_Q_START; } else { - tw_dev->aen_head = tw_dev->aen_head + 1; + tw_dev->aen_tail = tw_dev->aen_tail + 1; + } + if (tw_dev->aen_head == tw_dev->aen_tail) { + if (tw_dev->aen_head == TW_Q_LENGTH - 1) { + tw_dev->aen_head = TW_Q_START; + } else { + tw_dev->aen_head = tw_dev->aen_head + 1; + } } - } - if (aen != TW_AEN_QUEUE_EMPTY) { error = tw_aen_read_queue(tw_dev, request_id); if (error) { printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no); @@ -556,34 +563,33 @@ else imax = TW_Q_LENGTH; - for (i=0;itw_pci_dev, size, &dma_handle); - if (cpu_addr == NULL) { - printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n"); - return 1; - } + cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*imax, &dma_handle); + if (cpu_addr == NULL) { + printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n"); + return 1; + } - if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) { - printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n"); - pci_free_consistent(tw_dev->tw_pci_dev, size, cpu_addr, dma_handle); - return 1; - } + if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) { + printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n"); + pci_free_consistent(tw_dev->tw_pci_dev, size*imax, cpu_addr, dma_handle); + return 1; + } + + memset(cpu_addr, 0, size*imax); + for (i=0;icommand_packet_virtual_address[i] = cpu_addr; - tw_dev->command_packet_physical_address[i] = dma_handle; - memset(tw_dev->command_packet_virtual_address[i], 0, size); + tw_dev->command_packet_physical_address[i] = dma_handle+(i*size); + tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size)); break; case 1: - tw_dev->alignment_virtual_address[i] = cpu_addr; - tw_dev->alignment_physical_address[i] = dma_handle; - memset(tw_dev->alignment_virtual_address[i], 0, size); + tw_dev->alignment_physical_address[i] = dma_handle+(i*size); + tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size)); break; case 2: - tw_dev->bounce_buffer[i] = cpu_addr; - tw_dev->bounce_buffer_phys[i] = dma_handle; - memset(tw_dev->bounce_buffer[i], 0, size); + tw_dev->bounce_buffer_phys[i] = dma_handle+(i*size); + tw_dev->bounce_buffer[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size)); break; default: printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n"); @@ -631,11 +637,11 @@ int error, request_id; dma_addr_t dma_handle; unsigned short tw_aen_code; - unsigned long before; unsigned long flags; unsigned int data_buffer_length = 0; unsigned long data_buffer_length_adjusted = 0; unsigned long *cpu_addr; + long timeout; TW_New_Ioctl *tw_ioctl; TW_Passthru *passthru; TW_Device_Extension *tw_dev = tw_device_extension_list[MINOR(inode->i_rdev)]; @@ -735,30 +741,30 @@ tw_post_command_packet(tw_dev, request_id); spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ; + /* Now wait for the command to complete */ - before = jiffies; + tw_wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); - while (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { - /* FIXME: we need to sleep here */ - udelay(10); - if (time_after(jiffies, before + HZ *TW_IOCTL_CHRDEV_TIMEOUT)) { - /* Now we need to reset the board */ + /* Check if we timed out, got a signal, or didn't get + an interrupt */ + if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) { + /* Now we need to reset the board */ + if (timeout == -ERESTARTSYS) { + retval = timeout; + } else { printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd); - spin_lock_irqsave(&tw_dev->tw_lock, flags); - tw_dev->state[request_id] = TW_S_COMPLETED; - tw_state_request_finish(tw_dev, request_id); - pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); - tw_dev->posted_request_count--; - if (tw_reset_device_extension(tw_dev)) { - printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no); - } - spin_unlock_irqrestore(&tw_dev->tw_lock, flags); - if (signal_pending(current)) - retval = -EINTR; - else - retval = -EIO; - goto out2; + retval = -EIO; + } + spin_lock_irqsave(&tw_dev->tw_lock, flags); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->posted_request_count--; + if (tw_reset_device_extension(tw_dev)) { + printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no); } + spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + goto out2; } /* Now copy in the command packet response */ @@ -886,30 +892,33 @@ else host[0] = '\0'; - switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) { - case TW_STATUS_PCI_PARITY_ERROR: + if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) { printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host); outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr); - break; - case TW_STATUS_MICROCONTROLLER_ERROR: - if (tw_dev->reset_print == 0) { - printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host); - tw_dev->reset_print = 1; - } - return 1; - case TW_STATUS_PCI_ABORT: + } + + if (status_reg_value & TW_STATUS_PCI_ABORT) { printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host); outl(TW_CONTROL_CLEAR_PCI_ABORT, tw_dev->registers.control_reg_addr); pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT); - break; - case TW_STATUS_QUEUE_ERROR: + } + + if (status_reg_value & TW_STATUS_QUEUE_ERROR) { printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host); outl(TW_CONTROL_CLEAR_QUEUE_ERROR, tw_dev->registers.control_reg_addr); - break; - case TW_STATUS_SBUF_WRITE_ERROR: + } + + if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) { printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host); outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, tw_dev->registers.control_reg_addr); - break; + } + + if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) { + if (tw_dev->reset_print == 0) { + printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host); + tw_dev->reset_print = 1; + } + return 1; } return 0; @@ -1143,19 +1152,24 @@ tw_dev->online = 1; /* Calculate max cmds per lun, and setup queues */ - if (tw_dev->num_units > 0) { - if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) { - tw_host->cmd_per_lun = (TW_MAX_BOUNCEBUF-2)/tw_dev->num_units; - tw_dev->free_head = TW_Q_START; - tw_dev->free_tail = TW_Q_START; - tw_dev->free_wrap = TW_MAX_BOUNCEBUF - 1; - } else { - /* Use SHT cmd_per_lun here */ + if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) { + tw_host->cmd_per_lun = (TW_MAX_BOUNCEBUF-2)/tw_dev->num_units; + tw_dev->free_head = TW_Q_START; + tw_dev->free_tail = TW_Q_START; + tw_dev->free_wrap = TW_MAX_BOUNCEBUF - 1; + } else { + /* Check for user configured cmd_per_lun */ +#ifdef CONFIG_3W_XXXX_CMD_PER_LUN + tw_host->cmd_per_lun = CONFIG_3W_XXXX_CMD_PER_LUN; + if (tw_host->cmd_per_lun > TW_MAX_CMDS_PER_LUN) tw_host->cmd_per_lun = TW_MAX_CMDS_PER_LUN; - tw_dev->free_head = TW_Q_START; - tw_dev->free_tail = TW_Q_START; - tw_dev->free_wrap = TW_Q_LENGTH - 1; - } +#else + /* Use SHT cmd_per_lun default */ + tw_host->cmd_per_lun = TW_MAX_CMDS_PER_LUN; +#endif + tw_dev->free_head = TW_Q_START; + tw_dev->free_tail = TW_Q_START; + tw_dev->free_wrap = TW_Q_LENGTH - 1; } /* Register the card with the kernel SCSI layer */ @@ -1184,6 +1198,8 @@ host->max_sectors = TW_MAX_SECTORS; #endif + host->select_queue_depths = tw_select_queue_depths; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) scsi_set_pci_device(host, tw_pci_dev); #endif @@ -1198,6 +1214,10 @@ if (host->hostdata) { tw_dev2 = (TW_Device_Extension *)host->hostdata; memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension)); + /* Need to init the sem/wqueue after the copy */ + init_MUTEX(&tw_dev2->ioctl_sem); + init_waitqueue_head(&tw_dev2->ioctl_wqueue); + tw_device_extension_list[tw_device_extension_count] = tw_dev2; numcards++; tw_device_extension_count = numcards; @@ -1254,22 +1274,17 @@ /* This function will free up device extension resources */ void tw_free_device_extension(TW_Device_Extension *tw_dev) { - int i; - dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n"); + /* Free command packet and generic buffer memory */ - for (i=0;icommand_packet_virtual_address[i]) - pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector), tw_dev->command_packet_virtual_address[i], tw_dev->command_packet_physical_address[i]); + if (tw_dev->command_packet_physical_address[0]) + pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Command)*TW_Q_LENGTH, tw_dev->command_packet_virtual_address[0], tw_dev->command_packet_physical_address[0]); - if (tw_dev->alignment_virtual_address[i]) - pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector), tw_dev->alignment_virtual_address[i], tw_dev->alignment_physical_address[i]); + if (tw_dev->alignment_physical_address[0]) + pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_Q_LENGTH, tw_dev->alignment_virtual_address[0], tw_dev->alignment_physical_address[0]); - } - for (i=0;ibounce_buffer[i]) - pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_MAX_BOUNCE_SECTORS, tw_dev->bounce_buffer[i], tw_dev->bounce_buffer_phys[i]); - } + if (tw_dev->bounce_buffer[0]) + pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_MAX_BOUNCE_SECTORS*TW_MAX_BOUNCEBUF, tw_dev->bounce_buffer[0], tw_dev->bounce_buffer_phys[0]); } /* End tw_free_device_extension() */ /* Clean shutdown routine */ @@ -1379,8 +1394,6 @@ tw_dev->pending_tail = TW_Q_START; spin_lock_init(&tw_dev->tw_lock); tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; - init_waitqueue_head(&tw_dev->ioctl_wqueue); - init_MUTEX(&tw_dev->ioctl_sem); return 0; } /* End tw_initialize_device_extension() */ @@ -1720,6 +1733,7 @@ } } else { tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; + wake_up(&tw_dev->ioctl_wqueue); } } else { switch (tw_dev->srb[request_id]->cmnd[0]) { @@ -3395,6 +3409,31 @@ return 0; } /* End tw_scsiop_test_unit_ready_complete() */ +/* This function will select queue depths for a target */ +void tw_select_queue_depths(struct Scsi_Host *host, Scsi_Device *dev) +{ + Scsi_Device *ptr; + TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; + + dprintk(KERN_WARNING "3w-xxxx: tw_select_queue_depths()\n"); + + for (ptr = dev; ptr != NULL; ptr = ptr->next) { + if (ptr->host == host) { + if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) { + ptr->queue_depth = (TW_MAX_BOUNCEBUF-2)/tw_dev->num_units; + } else { +#ifdef CONFIG_3W_XXXX_CMD_PER_LUN + ptr->queue_depth = CONFIG_3W_XXXX_CMD_PER_LUN; + if (ptr->queue_depth > TW_MAX_CMDS_PER_LUN) + ptr->queue_depth = TW_MAX_CMDS_PER_LUN; +#else + ptr->queue_depth = TW_MAX_CMDS_PER_LUN; +#endif + } + } + } +} /* End tw_select_queue_depths() */ + /* Set a value in the features table */ int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, unsigned char *val) diff -urN linux-2.4.21/drivers/scsi/3w-xxxx.h linux-2.4.22/drivers/scsi/3w-xxxx.h --- linux-2.4.21/drivers/scsi/3w-xxxx.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/3w-xxxx.h 2003-08-25 04:44:42.000000000 -0700 @@ -115,10 +115,10 @@ {0xd0, 0x0b, 0x00, 0x00}, // Device busy Aborted command {0xd1, 0x0b, 0x00, 0x00}, // Device busy Aborted command {0x37, 0x02, 0x04, 0x00}, // Unit offline Not ready + {0x09, 0x02, 0x04, 0x00}, // Unrecovered disk error Not ready /* Codes for older firmware */ // 3ware Error SCSI Error - {0x09, 0x0b, 0x00, 0x00}, // Unrecovered disk error Aborted command {0x51, 0x0b, 0x00, 0x00} // Unspecified Aborted command }; @@ -238,7 +238,7 @@ #define TW_ISR_DONT_COMPLETE 2 #define TW_ISR_DONT_RESULT 3 #define TW_IOCTL_TIMEOUT 25 /* 25 seconds */ -#define TW_IOCTL_CHRDEV_TIMEOUT 25 /* 25 seconds */ +#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */ #define TW_IOCTL_CHRDEV_FREE -1 /* Macros */ @@ -249,6 +249,30 @@ (x & TW_STATUS_MICROCONTROLLER_ERROR)) && \ (x & TW_STATUS_MICROCONTROLLER_READY)) +/* This was taken from 2.5 kernel */ +#define tw_wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + #ifdef TW_DEBUG #define dprintk(msg...) printk(msg) #else @@ -498,6 +522,7 @@ int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id); int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id); int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id); +void tw_select_queue_depths(struct Scsi_Host *host, Scsi_Device *dev); int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, unsigned char *val); int tw_setup_irq(TW_Device_Extension *tw_dev); diff -urN linux-2.4.21/drivers/scsi/Config.in linux-2.4.22/drivers/scsi/Config.in --- linux-2.4.21/drivers/scsi/Config.in 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/Config.in 2003-08-25 04:44:42.000000000 -0700 @@ -37,7 +37,7 @@ fi if [ "$CONFIG_DECSTATION" = "y" ]; then dep_tristate 'DEC NCR53C94 Scsi Driver' CONFIG_SCSI_DECNCR $CONFIG_SCSI $CONFIG_TC - dep_tristate 'DEC SII Scsi Driver' CONFIG_SCSI_DECSII $CONFIG_SCSI + dep_tristate 'DEC SII Scsi Driver' CONFIG_SCSI_DECSII $CONFIG_SCSI $CONFIG_MIPS32 fi if [ "$CONFIG_PCI" = "y" ]; then @@ -52,7 +52,6 @@ dep_tristate 'Adaptec AACRAID support (EXPERIMENTAL)' CONFIG_SCSI_AACRAID $CONFIG_SCSI $CONFIG_PCI fi source drivers/scsi/aic7xxx/Config.in -source drivers/scsi/aic79xx/Config.in if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI if [ "$CONFIG_SCSI_AIC7XXX_OLD" != "n" ]; then @@ -61,7 +60,9 @@ bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_OLD_PROC_STATS fi fi -dep_tristate 'Adaptec I2O RAID support ' CONFIG_SCSI_DPT_I2O $CONFIG_SCSI +if [ "$CONFIG_X86_64" != "y" ]; then + dep_tristate 'Adaptec I2O RAID support ' CONFIG_SCSI_DPT_I2O $CONFIG_SCSI +fi dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI $CONFIG_PCI diff -urN linux-2.4.21/drivers/scsi/Makefile linux-2.4.22/drivers/scsi/Makefile --- linux-2.4.21/drivers/scsi/Makefile 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -27,7 +27,7 @@ subdir-$(CONFIG_SCSI_AACRAID) += aacraid subdir-$(CONFIG_SCSI_AIC7XXX) += aic7xxx -subdir-$(CONFIG_SCSI_AIC79XX) += aic79xx +subdir-$(CONFIG_SCSI_AIC79XX) += aic7xxx subdir-$(CONFIG_PCMCIA) += pcmcia @@ -73,7 +73,7 @@ obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx.o endif ifeq ($(CONFIG_SCSI_AIC79XX),y) - obj-$(CONFIG_SCSI_AIC79XX) += aic79xx/aic79xx.o + obj-$(CONFIG_SCSI_AIC79XX) += aic7xxx/aic79xx.o endif obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o obj-$(CONFIG_SCSI_IPS) += ips.o diff -urN linux-2.4.21/drivers/scsi/README.st linux-2.4.22/drivers/scsi/README.st --- linux-2.4.21/drivers/scsi/README.st 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/README.st 2003-08-25 04:44:42.000000000 -0700 @@ -1,8 +1,8 @@ This file contains brief information about the SCSI tape driver. The driver is currently maintained by Kai Mäkisara (email -Kai.Makisara@metla.fi) +Kai.Makisara@kolumbus.fi) -Last modified: Tue Apr 16 22:32:10 2002 by makisara +Last modified: Sun Apr 6 22:44:55 2003 by makisara BASICS @@ -112,7 +112,7 @@ Asynchronous writing. Writing the buffer contents to the tape is started and the write call returns immediately. The status is checked -at the next tape operation. +at the next tape operation. Applies only to variable block mode. Buffered writes and asynchronous writes may in some rare cases cause problems in multivolume operations if there is not enough space on the @@ -147,11 +147,6 @@ supports scatter/gather (the allocation is not limited to "DMA memory" and the buffer can be composed of several fragments). -The threshold for triggering asynchronous write in fixed block mode -is defined by ST_WRITE_THRESHOLD. This may be optimized for each -use pattern. The default triggers asynchronous write after three -default sized writes (10 kB) from tar. - Scatter/gather buffers (buffers that consist of chunks non-contiguous in the physical memory) are used if contiguous buffers can't be allocated. To support all SCSI adapters (including those not @@ -184,7 +179,6 @@ are configurable when the driver is loaded as a module. The keywords are: buffer_kbs=xxx the buffer size in kilobytes is set to xxx -write_threshold_kbs=xxx the write threshold in kilobytes set to xxx max_buffers=xxx the maximum number of tape buffer set to xxx max_sg_segs=xxx the maximum number of scatter/gather segments @@ -213,7 +207,7 @@ where aa is the buffer size in 1024 byte units - bb is the write threshold in 1024 byte units + bb is the write threshold in 1024 byte units (not used any more) cc is the maximum number of tape buffers to allocate (the number of buffers is bounded also by the number of drives detected) dd is the maximum number of scatter/gather segments @@ -321,9 +315,6 @@ MT_ST_SETBOOLEANS MT_ST_CLEARBOOLEANS Sets or clears the option bits. - MT_ST_WRITE_THRESHOLD - Sets the write threshold for this device to kilobytes - specified by the lowest bits. MT_ST_DEF_BLKSIZE Defines the default block size set automatically. Value 0xffffff means that the default is not used any more. diff -urN linux-2.4.21/drivers/scsi/aacraid/README linux-2.4.22/drivers/scsi/aacraid/README --- linux-2.4.21/drivers/scsi/aacraid/README 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/README 2003-08-25 04:44:42.000000000 -0700 @@ -18,6 +18,12 @@ ADAPTEC 2120S ADAPTEC 2200S ADAPTEC 5400S + Legend S220 + Legend S230 + Adaptec 3230S + Adaptec 3240S + ASR-2020S PCI-X + AAR-2410SA SATA People ------------------------- @@ -28,15 +34,22 @@ added new ioctls, changed scsi interface to use new error handler, increased the number of fibs and outstanding commands to a container) + (fixed 64bit and 64G memory model, changed confusing naming convention + where fibs that go to the hardware are consistently called hw_fibs and + not just fibs like the name of the driver tracking structure) +Mark Salyzyn Fixed panic issues and added some new product ids for upcoming hbas. + Original Driver ------------------------- Adaptec Unix OEM Product Group Mailing List ------------------------- -None currently. Also note this is very different to Brian's original driver +linux-aacraid-devel@dell.com (Interested parties troll here) +http://mbserver.adaptec.com/ (Currently more Community Support than Devel Support) +Also note this is very different to Brian's original driver so don't expect him to support it. -Adaptec does support this driver. Contact either tech support or deanna bonds. +Adaptec does support this driver. Contact either tech support or Mark Salyzyn. Original by Brian Boerner February 2001 Rewritten by Alan Cox, November 2001 diff -urN linux-2.4.21/drivers/scsi/aacraid/TODO linux-2.4.22/drivers/scsi/aacraid/TODO --- linux-2.4.21/drivers/scsi/aacraid/TODO 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/TODO 2003-08-25 04:44:42.000000000 -0700 @@ -2,3 +2,4 @@ o More testing o Feature request: display the firmware/bios/etc revisions in the /proc info +o 2.5.0 and beyond. diff -urN linux-2.4.21/drivers/scsi/aacraid/aachba.c linux-2.4.22/drivers/scsi/aacraid/aachba.c --- linux-2.4.21/drivers/scsi/aacraid/aachba.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aacraid/aachba.c 2003-08-25 04:44:42.000000000 -0700 @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -224,6 +225,15 @@ static char *aac_get_status_string(u32 status); #endif +/* + * Non dasd selection is handled entirely in aachba now + */ + +MODULE_PARM(nondasd, "i"); +MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); + +static int nondasd = -1; + /** * aac_get_containers - list containers * @common: adapter to probe @@ -261,13 +271,14 @@ 1, 1, NULL, NULL); if (status < 0 ) { - printk(KERN_WARNING "ProbeContainers: SendFIB failed.\n"); + printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n"); break; } dresp = (struct aac_mount *)fib_data(fibptr); if ((le32_to_cpu(dresp->status) == ST_OK) && - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) { + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && + (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { fsa_dev_ptr->valid[index] = 1; fsa_dev_ptr->type[index] = le32_to_cpu(dresp->mnt[0].vol); fsa_dev_ptr->size[index] = le32_to_cpu(dresp->mnt[0].capacity); @@ -332,7 +343,8 @@ dresp = (struct aac_mount *) fib_data(fibptr); if ((le32_to_cpu(dresp->status) == ST_OK) && - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) { + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && + (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { fsa_dev_ptr->valid[cid] = 1; fsa_dev_ptr->type[cid] = le32_to_cpu(dresp->mnt[0].vol); fsa_dev_ptr->size[cid] = le32_to_cpu(dresp->mnt[0].capacity); @@ -520,22 +532,54 @@ dev->name, dev->id, dev->adapter_info.serial[0], dev->adapter_info.serial[1]); - dev->pae_support = 0; + dev->nondasd_support = 0; - if( BITS_PER_LONG >= 64 && - (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ - printk(KERN_INFO "%s%d: 64 Bit PAE enabled\n", dev->name, dev->id); + dev->raid_scsi_mode = 0; + if(dev->adapter_info.options & AAC_OPT_NONDASD){ + dev->nondasd_support = 1; + } + + /* + * If the firmware supports ROMB RAID/SCSI mode and we are currently + * in RAID/SCSI mode, set the flag. For now if in this mode we will + * force nondasd support on. If we decide to allow the non-dasd flag + * additional changes changes will have to be made to support + * RAID/SCSI. the function aac_scsi_cmd in this module will have to be + * changed to support the new dev->raid_scsi_mode flag instead of + * leaching off of the dev->nondasd_support flag. Also in linit.c the + * function aac_detect will have to be modified where it sets up the + * max number of channels based on the aac->nondasd_support flag only. + */ + if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) + && (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) + { + dev->nondasd_support = 1; + dev->raid_scsi_mode = 1; + } + if (dev->raid_scsi_mode != 0) + printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n",dev->name, dev->id); + + if (nondasd != -1) + dev->nondasd_support = (nondasd!=0); + + if(dev->nondasd_support != 0) + printk(KERN_INFO "%s%d: Non-DASD support enabled\n",dev->name, dev->id); + + dev->pae_support = 0; + if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ dev->pae_support = 1; } /* TODO - dmb temporary until fw can set this bit */ dev->pae_support = (BITS_PER_LONG >= 64); - if(dev->pae_support != 0) { + if(dev->pae_support != 0) + { printk(KERN_INFO "%s%d: 64 Bit PAE enabled\n", dev->name, dev->id); + pci_set_dma_mask(dev->pdev, (dma_addr_t)0xFFFFFFFFFFFFFFFFULL); } - if(dev->adapter_info.options & AAC_OPT_NONDASD){ - dev->nondasd_support = 1; - } + fib_complete(fibptr); + fib_free(fibptr); + return rcode; } @@ -554,7 +598,7 @@ cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; - dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies)); + dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); if (fibptr == NULL) BUG(); @@ -599,7 +643,7 @@ cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; - dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies)); + dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); if (fibptr == NULL) BUG(); @@ -765,7 +809,7 @@ lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; } - dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %lu, t = %ld.\n", smp_processor_id(), lba, jiffies)); + dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); /* * Allocate and initialize a Fib then setup a BlockWrite command */ @@ -1261,17 +1305,29 @@ /* * Next check the srb status */ - switch(le32_to_cpu(srbreply->srb_status)){ + switch( (le32_to_cpu(srbreply->srb_status))&0x3f){ case SRB_STATUS_ERROR_RECOVERY: case SRB_STATUS_PENDING: case SRB_STATUS_SUCCESS: if(scsicmd->cmnd[0] == INQUIRY ){ u8 b; + u8 b1; /* We can't expose disk devices because we can't tell whether they - * are the raw container drives or stand alone drives + * are the raw container drives or stand alone drives. If they have + * the removable bit set then we should expose them though. */ - b = *(u8*)scsicmd->buffer; - if( (b & 0x0f) == TYPE_DISK ){ + b = (*(u8*)scsicmd->buffer)&0x1f; + b1 = ((u8*)scsicmd->buffer)[1]; + if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER + || (b==TYPE_DISK && (b1&0x80)) ){ + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; + /* + * We will allow disk devices if in RAID/SCSI mode and + * the channel is 2 + */ + } else if((dev->raid_scsi_mode)&&(scsicmd->channel == 2)){ + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; + } else { scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8; } } else { @@ -1293,6 +1349,28 @@ } scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8; break; + case INQUIRY: { + u8 b; + u8 b1; + /* We can't expose disk devices because we can't tell whether they + * are the raw container drives or stand alone drives + */ + b = (*(u8*)scsicmd->buffer)&0x0f; + b1 = ((u8*)scsicmd->buffer)[1]; + if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER + || (b==TYPE_DISK && (b1&0x80)) ){ + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; + /* + * We will allow disk devices if in RAID/SCSI mode and + * the channel is 2 + */ + } else if((dev->raid_scsi_mode)&&(scsicmd->channel == 2)){ + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; + } else { + scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8; + } + break; + } default: scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; break; @@ -1348,13 +1426,14 @@ case SRB_STATUS_DOMAIN_VALIDATION_FAIL: default: #ifdef AAC_DETAILED_STATUS_INFO - printk("aacraid: SRB ERROR (%s)\n",aac_get_status_string(le32_to_cpu(srbreply->srb_status))); + printk("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n",le32_to_cpu(srbreply->srb_status&0x3f),aac_get_status_string(le32_to_cpu(srbreply->srb_status)), scsicmd->cmnd[0], le32_to_cpu(srbreply->scsi_status) ); #endif scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8; break; } if (le32_to_cpu(srbreply->scsi_status) == 0x02 ){ // Check Condition int len; + scsicmd->result |= CHECK_CONDITION; len = (srbreply->sense_data_size > sizeof(scsicmd->sense_buffer))? sizeof(scsicmd->sense_buffer):srbreply->sense_data_size; printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n", le32_to_cpu(srbreply->status), len); @@ -1387,6 +1466,7 @@ struct aac_srb *srbcmd; u16 fibsize; u32 flag; + u32 timeout; if( scsicmd->target > 15 || scsicmd->lun > 7) { scsicmd->result = DID_NO_CONNECT << 16; @@ -1428,7 +1508,11 @@ srbcmd->target = cpu_to_le32(scsicmd->target); srbcmd->lun = cpu_to_le32(scsicmd->lun); srbcmd->flags = cpu_to_le32(flag); - srbcmd->timeout = cpu_to_le32(0); // timeout not used + timeout = (scsicmd->timeout-jiffies)/HZ; + if(timeout == 0){ + timeout = 1; + } + srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter srbcmd->cdb_size = cpu_to_le32(scsicmd->cmd_len); @@ -1533,6 +1617,7 @@ psg->count = cpu_to_le32(1); psg->sg[0].addr = cpu_to_le32(addr); psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen); + /* Cast to pointer from integer of different size */ scsicmd->SCp.ptr = (void *)addr; byte_count = scsicmd->request_bufflen; } @@ -1594,6 +1679,7 @@ psg->sg[0].addr[1] = (u32)(le_addr>>32); psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff); psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen); + /* Cast to pointer from integer of different size */ scsicmd->SCp.ptr = (void *)addr; byte_count = scsicmd->request_bufflen; } diff -urN linux-2.4.21/drivers/scsi/aacraid/aacraid.h linux-2.4.22/drivers/scsi/aacraid/aacraid.h --- linux-2.4.21/drivers/scsi/aacraid/aacraid.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/aacraid.h 2003-08-25 04:44:42.000000000 -0700 @@ -1,5 +1,7 @@ -#define dprintk(x) -/*#define dprintk(x) printk x */ +//#define dprintk(x) printk x +#if (!defined(dprintk)) +# define dprintk(x) +#endif /*------------------------------------------------------------------------------ * D E F I N E S @@ -8,12 +10,13 @@ #define MAXIMUM_NUM_CONTAINERS 31 #define MAXIMUM_NUM_ADAPTERS 8 -#define AAC_NUM_FIB 578 -#define AAC_NUM_IO_FIB 512 +#define AAC_NUM_FIB 578 +//#define AAC_NUM_IO_FIB 512 +#define AAC_NUM_IO_FIB 100 -#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1) +#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1) //#define AAC_MAX_TARGET (16) -#define AAC_MAX_LUN (8) +#define AAC_MAX_LUN (8) /* * These macros convert from physical channels to virtual channels @@ -269,11 +272,11 @@ u32 _ReceiverTimeStart; // Timestamp for receipt of fib u32 _ReceiverTimeDone; // Timestamp for completion of fib } _s; - struct list_head _FibLinks; // Used to link Adapter Initiated Fibs on the host +// struct aac_list_head _FibLinks; // Used to link Adapter Initiated Fibs on the host } _u; }; -#define FibLinks _u._FibLinks +//#define FibLinks _u._FibLinks #define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr)) @@ -438,6 +441,8 @@ char * vname; char * model; u16 channels; + int quirks; +#define AAC_QUIRK_31BIT 1 }; /* @@ -629,7 +634,7 @@ struct semaphore wait_sem; // this is used to wait for the next fib to arrive. int wait; // Set to true when thread is in WaitForSingleObject unsigned long count; // total number of FIBs on FibList - struct list_head fibs; + struct list_head fib_list; // this holds fibs which should be 32 bit addresses }; struct fsa_scsi_hba { @@ -639,7 +644,7 @@ u8 ro[MAXIMUM_NUM_CONTAINERS]; u8 locked[MAXIMUM_NUM_CONTAINERS]; u8 deleted[MAXIMUM_NUM_CONTAINERS]; - u32 devno[MAXIMUM_NUM_CONTAINERS]; + s32 devno[MAXIMUM_NUM_CONTAINERS]; }; struct fib { @@ -650,7 +655,6 @@ * The Adapter that this I/O is destined for. */ struct aac_dev *dev; - u64 logicaladdr; /* 64 bit */ /* * This is the event the sendfib routine will wait on if the * caller did not pass one and this is synch io. @@ -667,9 +671,14 @@ * Outstanding I/O queue. */ struct list_head queue; - + /* + * And for the internal issue/reply queues (we may be able + * to merge these two) + */ + struct list_head fiblink; void *data; - struct hw_fib *fib; /* Actual shared object */ + struct hw_fib *hw_fib; /* Actual shared object */ + dma_addr_t hw_fib_pa; /* physical address of hw_fib*/ }; /* @@ -696,6 +705,7 @@ u32 biosrev; u32 biosbuild; u32 cluster; + u32 clusterchannelmask; u32 serial[2]; u32 battery; u32 options; @@ -720,19 +730,22 @@ /* * Supported Options */ -#define AAC_OPT_SNAPSHOT cpu_to_le32(1) -#define AAC_OPT_CLUSTERS cpu_to_le32(1<<1) -#define AAC_OPT_WRITE_CACHE cpu_to_le32(1<<2) -#define AAC_OPT_64BIT_DATA cpu_to_le32(1<<3) -#define AAC_OPT_HOST_TIME_FIB cpu_to_le32(1<<4) -#define AAC_OPT_RAID50 cpu_to_le32(1<<5) -#define AAC_OPT_4GB_WINDOW cpu_to_le32(1<<6) -#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7) -#define AAC_OPT_SOFT_ERR_REPORT cpu_to_le32(1<<8) -#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9) -#define AAC_OPT_SGMAP_HOST64 cpu_to_le32(1<<10) -#define AAC_OPT_ALARM cpu_to_le32(1<<11) -#define AAC_OPT_NONDASD cpu_to_le32(1<<12) +#define AAC_OPT_SNAPSHOT cpu_to_le32(1) +#define AAC_OPT_CLUSTERS cpu_to_le32(1<<1) +#define AAC_OPT_WRITE_CACHE cpu_to_le32(1<<2) +#define AAC_OPT_64BIT_DATA cpu_to_le32(1<<3) +#define AAC_OPT_HOST_TIME_FIB cpu_to_le32(1<<4) +#define AAC_OPT_RAID50 cpu_to_le32(1<<5) +#define AAC_OPT_4GB_WINDOW cpu_to_le32(1<<6) +#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7) +#define AAC_OPT_SOFT_ERR_REPORT cpu_to_le32(1<<8) +#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9) +#define AAC_OPT_SGMAP_HOST64 cpu_to_le32(1<<10) +#define AAC_OPT_ALARM cpu_to_le32(1<<11) +#define AAC_OPT_NONDASD cpu_to_le32(1<<12) +#define AAC_OPT_SCSI_MANAGED cpu_to_le32(1<<13) +#define AAC_OPT_RAID_SCSI_MODE cpu_to_le32(1<<14) +#define AAC_OPT_SUPPLEMENT_ADAPTER_INFO cpu_to_le32(1<<15) struct aac_dev { @@ -746,13 +759,12 @@ */ dma_addr_t hw_fib_pa; struct hw_fib *hw_fib_va; -#if BITS_PER_LONG >= 64 ulong fib_base_va; -#endif /* * Fib Headers */ - struct fib fibs[AAC_NUM_FIB]; + struct fib *fibs; + struct fib *free_fib; struct fib *timeout_fib; spinlock_t fib_lock; @@ -781,7 +793,7 @@ struct Scsi_Host *scsi_host_ptr; struct fsa_scsi_hba fsa_dev; - int thread_pid; + pid_t thread_pid; int cardtype; /* @@ -804,8 +816,15 @@ */ u8 nondasd_support; u8 pae_support; + u8 raid_scsi_mode; }; +#define AllocateAndMapFibSpace(dev, MapFibContext) \ + dev->a_ops.AllocateAndMapFibSpace(dev, MapFibContext) + +#define UnmapAndFreeFibSpace(dev, MapFibContext) \ + dev->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext) + #define aac_adapter_interrupt(dev) \ dev->a_ops.adapter_interrupt(dev) @@ -1142,7 +1161,9 @@ u32 altoid; // != oid <==> snapshot or broken mirror exists }; -#define FSCS_READONLY 0x0002 /* possible result of broken mirror */ +#define FSCS_NOTCLEAN 0x0001 /* fsck is neccessary before mounting */ +#define FSCS_READONLY 0x0002 /* possible result of broken mirror */ +#define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */ struct aac_query_mount { u32 command; @@ -1326,9 +1347,12 @@ */ #define AifCmdEventNotify 1 /* Notify of event */ +#define AifEnContainerChange 4 /* Container configuration change */ #define AifCmdJobProgress 2 /* Progress report */ #define AifCmdAPIReport 3 /* Report from other user of API */ #define AifCmdDriverNotify 4 /* Notify host driver of event */ +#define AifDenMorphComplete 200 /* A morph operation completed */ +#define AifDenVolumeExtendComplete 201 /* A volume expand operation completed */ #define AifReqJobList 100 /* Gets back complete job list */ #define AifReqJobsForCtr 101 /* Gets back jobs for specific container */ #define AifReqJobsForScsi 102 /* Gets back jobs for specific SCSI device */ @@ -1353,16 +1377,6 @@ u8 data[1]; /* Undefined length (from kernel viewpoint) */ }; -static inline u32 fib2addr(struct hw_fib *hw) -{ - return (u32)hw; -} - -static inline struct hw_fib *addr2fib(u32 addr) -{ - return (struct hw_fib *)addr; -} - const char *aac_driverinfo(struct Scsi_Host *); struct fib *fib_alloc(struct aac_dev *dev); int fib_setup(struct aac_dev *dev); @@ -1376,7 +1390,7 @@ int aac_consumer_avail(struct aac_dev * dev, struct aac_queue * q); void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); int fib_complete(struct fib * context); -#define fib_data(fibctx) ((void *)(fibctx)->fib->data) +#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) int aac_detach(struct aac_dev *dev); struct aac_dev *aac_init_adapter(struct aac_dev *dev); int aac_get_containers(struct aac_dev *dev); diff -urN linux-2.4.21/drivers/scsi/aacraid/commctrl.c linux-2.4.22/drivers/scsi/aacraid/commctrl.c --- linux-2.4.21/drivers/scsi/aacraid/commctrl.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/commctrl.c 2003-08-25 04:44:42.000000000 -0700 @@ -63,7 +63,7 @@ if(fibptr == NULL) return -ENOMEM; - kfib = fibptr->fib; + kfib = fibptr->hw_fib; /* * First copy in the header so that we can check the size field. */ @@ -150,7 +150,7 @@ * the list to 0. */ fibctx->count = 0; - INIT_LIST_HEAD(&fibctx->fibs); + INIT_LIST_HEAD(&fibctx->fib_list); fibctx->jiffies = jiffies/HZ; /* * Now add this context onto the adapter's @@ -181,7 +181,7 @@ { struct fib_ioctl f; struct aac_fib_context *fibctx, *aifcp; - struct hw_fib * fib; + struct fib * fib; int status; struct list_head * entry; int found; @@ -211,12 +211,16 @@ } entry = entry->next; } - if (found == 0) + if (found == 0) { + dprintk ((KERN_INFO "Fib not found\n")); return -EINVAL; + } if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || - (fibctx->size != sizeof(struct aac_fib_context))) + (fibctx->size != sizeof(struct aac_fib_context))) { + dprintk ((KERN_INFO "Fib Context corrupt?\n")); return -EINVAL; + } status = 0; spin_lock_irqsave(&dev->fib_lock, flags); /* @@ -224,27 +228,28 @@ * -EAGAIN */ return_fib: - if (!list_empty(&fibctx->fibs)) { + if (!list_empty(&fibctx->fib_list)) { struct list_head * entry; /* * Pull the next fib from the fibs */ - entry = fibctx->fibs.next; + entry = fibctx->fib_list.next; list_del(entry); - fib = list_entry(entry, struct hw_fib, header.FibLinks); + fib = list_entry(entry, struct fib, fiblink); fibctx->count--; spin_unlock_irqrestore(&dev->fib_lock, flags); - if (copy_to_user(f.fib, fib, sizeof(struct hw_fib))) { + if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) { + kfree(fib->hw_fib); kfree(fib); return -EFAULT; } /* * Free the space occupied by this copy of the fib. */ + kfree(fib->hw_fib); kfree(fib); status = 0; - fibctx->jiffies = jiffies/HZ; } else { spin_unlock_irqrestore(&dev->fib_lock, flags); if (f.wait) { @@ -259,28 +264,30 @@ status = -EAGAIN; } } + fibctx->jiffies = jiffies/HZ; return status; } int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx) { - struct hw_fib *fib; + struct fib *fib; /* * First free any FIBs that have not been consumed. */ - while (!list_empty(&fibctx->fibs)) { + while (!list_empty(&fibctx->fib_list)) { struct list_head * entry; /* * Pull the next fib from the fibs */ - entry = fibctx->fibs.next; + entry = fibctx->fib_list.next; list_del(entry); - fib = list_entry(entry, struct hw_fib, header.FibLinks); + fib = list_entry(entry, struct fib, fiblink); fibctx->count--; /* * Free the space occupied by this copy of the fib. */ + kfree(fib->hw_fib); kfree(fib); } /* diff -urN linux-2.4.21/drivers/scsi/aacraid/comminit.c linux-2.4.22/drivers/scsi/aacraid/comminit.c --- linux-2.4.21/drivers/scsi/aacraid/comminit.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/comminit.c 2003-08-25 04:44:42.000000000 -0700 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "scsi.h" #include "hosts.h" @@ -58,7 +59,6 @@ struct aac_init *init; dma_addr_t phys; - /* FIXME: Adaptec add 128 bytes to this value - WHY ?? */ size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz; base = pci_alloc_consistent(dev->pdev, size, &phys); @@ -74,14 +74,6 @@ dev->init = (struct aac_init *)(base + fibsize); dev->init_pa = phys + fibsize; - /* - * Cache the upper bits of the virtual mapping for 64bit boxes - * FIXME: this crap should be rewritten - */ -#if BITS_PER_LONG >= 64 - dev->fib_base_va = ((ulong)base & 0xffffffff00000000); -#endif - init = dev->init; init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION); @@ -92,16 +84,20 @@ * Adapter Fibs are the first thing allocated so that they * start page aligned */ - init->AdapterFibsVirtualAddress = cpu_to_le32((u32)base); - init->AdapterFibsPhysicalAddress = cpu_to_le32(phys); + dev->fib_base_va = (ulong)base; + + /* We submit the physical address for AIF tags to limit to 32 bits */ + init->AdapterFibsVirtualAddress = cpu_to_le32((u32)phys); + init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); init->AdapterFibsSize = cpu_to_le32(fibsize); init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); + init->HostPhysMemPages = cpu_to_le32(num_physpages); // number of 4k pages of host physical memory /* * Increment the base address by the amount already used */ base = base + fibsize + sizeof(struct aac_init); - phys = phys + fibsize + sizeof(struct aac_init); + phys = (dma_addr_t)((ulong)phys + fibsize + sizeof(struct aac_init)); /* * Align the beginning of Headers to commalign */ @@ -111,8 +107,8 @@ /* * Fill in addresses of the Comm Area Headers and Queues */ - *commaddr = (unsigned long *)base; - init->CommHeaderAddress = cpu_to_le32(phys); + *commaddr = base; + init->CommHeaderAddress = cpu_to_le32((u32)phys); /* * Increment the base address by the size of the CommArea */ @@ -140,8 +136,8 @@ q->lock = &q->lockdata; q->headers.producer = mem; q->headers.consumer = mem+1; - *q->headers.producer = cpu_to_le32(qsize); - *q->headers.consumer = cpu_to_le32(qsize); + *(q->headers.producer) = cpu_to_le32(qsize); + *(q->headers.consumer) = cpu_to_le32(qsize); q->entries = qsize; } @@ -246,9 +242,9 @@ if (!aac_alloc_comm(dev, (void * *)&headers, size, QUEUE_ALIGNMENT)) return -ENOMEM; - queues = (struct aac_entry *)((unsigned char *)headers + hdrsize); + queues = (struct aac_entry *)(((ulong)headers) + hdrsize); - /* Adapter to Host normal proirity Command queue */ + /* Adapter to Host normal priority Command queue */ comm->queue[HostNormCmdQueue].base = queues; aac_queue_init(dev, &comm->queue[HostNormCmdQueue], headers, HOST_NORM_CMD_ENTRIES); queues += HOST_NORM_CMD_ENTRIES; @@ -320,14 +316,18 @@ } memset(dev->queues, 0, sizeof(struct aac_queue_block)); - if (aac_comm_init(dev)<0) + if (aac_comm_init(dev)<0){ + kfree(dev->queues); return NULL; + } /* * Initialize the list of fibs */ - if(fib_setup(dev)<0) + if(fib_setup(dev)<0){ + kfree(dev->queues); return NULL; - + } + INIT_LIST_HEAD(&dev->fib_list); init_completion(&dev->aif_completion); /* diff -urN linux-2.4.21/drivers/scsi/aacraid/commsup.c linux-2.4.22/drivers/scsi/aacraid/commsup.c --- linux-2.4.21/drivers/scsi/aacraid/commsup.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/commsup.c 2003-08-25 04:44:42.000000000 -0700 @@ -42,6 +42,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -86,32 +87,32 @@ int fib_setup(struct aac_dev * dev) { struct fib *fibptr; - struct hw_fib *fib; - dma_addr_t fibpa; + struct hw_fib *hw_fib_va; + dma_addr_t hw_fib_pa; int i; if(fib_map_alloc(dev)<0) return -ENOMEM; - fib = dev->hw_fib_va; - fibpa = dev->hw_fib_pa; - memset(fib, 0, sizeof(struct hw_fib) * AAC_NUM_FIB); + hw_fib_va = dev->hw_fib_va; + hw_fib_pa = dev->hw_fib_pa; + memset(hw_fib_va, 0, sizeof(struct hw_fib) * AAC_NUM_FIB); /* * Initialise the fibs */ for (i = 0, fibptr = &dev->fibs[i]; i < AAC_NUM_FIB; i++, fibptr++) { fibptr->dev = dev; - fibptr->fib = fib; - fibptr->data = (void *) fibptr->fib->data; + fibptr->hw_fib = hw_fib_va; + fibptr->data = (void *) fibptr->hw_fib->data; fibptr->next = fibptr+1; /* Forward chain the fibs */ init_MUTEX_LOCKED(&fibptr->event_wait); spin_lock_init(&fibptr->event_lock); - fib->header.XferState = cpu_to_le32(0xffffffff); - fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); - fibptr->logicaladdr = (unsigned long) fibpa; - fib = (struct hw_fib *)((unsigned char *)fib + sizeof(struct hw_fib)); - fibpa = fibpa + sizeof(struct hw_fib); + hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); + hw_fib_va->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); + fibptr->hw_fib_pa = hw_fib_pa; + hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + sizeof(struct hw_fib)); + hw_fib_pa = hw_fib_pa + sizeof(struct hw_fib); } /* * Add the fib chain to the free list @@ -152,7 +153,7 @@ * Null out fields that depend on being zero at the start of * each I/O */ - fibptr->fib->header.XferState = cpu_to_le32(0); + fibptr->hw_fib->header.XferState = cpu_to_le32(0); fibptr->callback = NULL; fibptr->callback_data = NULL; @@ -178,9 +179,9 @@ fibptr->next = fibptr->dev->timeout_fib; fibptr->dev->timeout_fib = fibptr; } else { - if (fibptr->fib->header.XferState != 0) { + if (fibptr->hw_fib->header.XferState != 0) { printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", - (void *)fibptr, fibptr->fib->header.XferState); + (void*)fibptr, fibptr->hw_fib->header.XferState); } fibptr->next = fibptr->dev->free_fib; fibptr->dev->free_fib = fibptr; @@ -197,14 +198,14 @@ void fib_init(struct fib *fibptr) { - struct hw_fib *fib = fibptr->fib; + struct hw_fib *hw_fib = fibptr->hw_fib; - fib->header.StructType = FIB_MAGIC; - fib->header.Size = cpu_to_le16(sizeof(struct hw_fib)); - fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); - fib->header.SenderFibAddress = cpu_to_le32(0); - fib->header.ReceiverFibAddress = cpu_to_le32(0); - fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); + hw_fib->header.StructType = FIB_MAGIC; + hw_fib->header.Size = cpu_to_le16(sizeof(struct hw_fib)); + hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); + hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa); + hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); + hw_fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); } /** @@ -217,10 +218,10 @@ void fib_dealloc(struct fib * fibptr) { - struct hw_fib *fib = fibptr->fib; - if(fib->header.StructType != FIB_MAGIC) + struct hw_fib *hw_fib = fibptr->hw_fib; + if(hw_fib->header.StructType != FIB_MAGIC) BUG(); - fib->header.XferState = cpu_to_le32(0); + hw_fib->header.XferState = cpu_to_le32(0); } /* @@ -257,7 +258,7 @@ q = &dev->queues->queue[qid]; *index = le32_to_cpu(*(q->headers.producer)); - if (*index - 2 == le32_to_cpu(*(q->headers.consumer))) + if ((*index - 2) == le32_to_cpu(*(q->headers.consumer))) *nonotify = 1; if (qid == AdapHighCmdQueue) { @@ -304,7 +305,7 @@ * success. */ -static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * fib, int wait, struct fib * fibptr, unsigned long *nonotify) +static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify) { struct aac_entry * entry = NULL; int map = 0; @@ -322,7 +323,7 @@ /* * Setup queue entry with a command, status and fib mapped */ - entry->size = cpu_to_le32(le16_to_cpu(fib->header.Size)); + entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); map = 1; } else if (qid == AdapHighRespQueue || qid == AdapNormRespQueue) @@ -334,9 +335,10 @@ /* * Setup queue entry with command, status and fib mapped */ - entry->size = cpu_to_le32(le16_to_cpu(fib->header.Size)); - entry->addr = cpu_to_le32(fib->header.SenderFibAddress); /* Restore adapters pointer to the FIB */ - fib->header.ReceiverFibAddress = fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ + entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); + entry->addr = hw_fib->header.SenderFibAddress; + /* Restore adapters pointer to the FIB */ + hw_fib->header.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ map = 0; } /* @@ -344,7 +346,7 @@ * in the queue entry. */ if (map) - entry->addr = cpu_to_le32((unsigned long)(fibptr->logicaladdr)); + entry->addr = fibptr->hw_fib_pa; return 0; } @@ -415,11 +417,11 @@ u32 qid; struct aac_dev * dev = fibptr->dev; unsigned long nointr = 0; - struct hw_fib * fib = fibptr->fib; + struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_queue * q; unsigned long flags = 0; - if (!(le32_to_cpu(fib->header.XferState) & HostOwned)) + if (!(le32_to_cpu(hw_fib->header.XferState) & HostOwned)) return -EBUSY; /* * There are 5 cases with the wait and reponse requested flags. @@ -435,19 +437,22 @@ if (wait && !reply) { return -EINVAL; } else if (!wait && reply) { - fib->header.XferState |= cpu_to_le32(Async | ResponseExpected); + hw_fib->header.XferState |= cpu_to_le32(Async | ResponseExpected); FIB_COUNTER_INCREMENT(aac_config.AsyncSent); } else if (!wait && !reply) { - fib->header.XferState |= cpu_to_le32(NoResponseExpected); + hw_fib->header.XferState |= cpu_to_le32(NoResponseExpected); FIB_COUNTER_INCREMENT(aac_config.NoResponseSent); } else if (wait && reply) { - fib->header.XferState |= cpu_to_le32(ResponseExpected); + hw_fib->header.XferState |= cpu_to_le32(ResponseExpected); FIB_COUNTER_INCREMENT(aac_config.NormalSent); } /* * Map the fib into 32bits by using the fib number */ - fib->header.SenderData = fibptr-&dev->fibs[0]; /* for callback */ + +// hw_fib->header.SenderFibAddress = ((u32)(fibptr-dev->fibs)) << 1; + hw_fib->header.SenderFibAddress = cpu_to_le32((u32)(ulong)fibptr->hw_fib_pa); + hw_fib->header.SenderData = (u32)(fibptr - dev->fibs); /* * Set FIB state to indicate where it came from and if we want a * response from the adapter. Also load the command from the @@ -455,15 +460,14 @@ * * Map the hw fib pointer as a 32bit value */ - fib->header.SenderFibAddress = fib2addr(fib); - fib->header.Command = cpu_to_le16(command); - fib->header.XferState |= cpu_to_le32(SentFromHost); - fibptr->fib->header.Flags = 0; /* Zero the flags field - its internal only... */ + hw_fib->header.Command = cpu_to_le16(command); + hw_fib->header.XferState |= cpu_to_le32(SentFromHost); + fibptr->hw_fib->header.Flags = 0; /* 0 the flags field - internal only*/ /* * Set the size of the Fib we want to send to the adapter */ - fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size); - if (le16_to_cpu(fib->header.Size) > le16_to_cpu(fib->header.SenderSize)) { + hw_fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size); + if (le16_to_cpu(hw_fib->header.Size) > le16_to_cpu(hw_fib->header.SenderSize)) { return -EMSGSIZE; } /* @@ -471,22 +475,25 @@ * the adapter a command is ready. */ if (priority == FsaHigh) { - fib->header.XferState |= cpu_to_le32(HighPriority); + hw_fib->header.XferState |= cpu_to_le32(HighPriority); qid = AdapHighCmdQueue; } else { - fib->header.XferState |= cpu_to_le32(NormalPriority); + hw_fib->header.XferState |= cpu_to_le32(NormalPriority); qid = AdapNormCmdQueue; } q = &dev->queues->queue[qid]; if(wait) spin_lock_irqsave(&fibptr->event_lock, flags); - if(aac_queue_get( dev, &index, qid, fib, 1, fibptr, &nointr)<0) + if(aac_queue_get( dev, &index, qid, hw_fib, 1, fibptr, &nointr)<0) return -EWOULDBLOCK; dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index)); dprintk((KERN_DEBUG "Fib contents:.\n")); - dprintk((KERN_DEBUG " Command = %d.\n", fib->header.Command)); - dprintk((KERN_DEBUG " XferState = %x.\n", fib->header.XferState)); + dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command)); + dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState)); + dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib)); + dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); + dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); /* * Fill in the Callback and CallbackContext if we are not * going to wait. @@ -500,6 +507,7 @@ q->numpending++; fibptr->done = 0; + fibptr->flags = 0; if(aac_insert_entry(dev, index, qid, (nointr & aac_config.irq_mod)) < 0) return -EWOULDBLOCK; @@ -543,8 +551,7 @@ { u32 index; int status; - - if (*q->headers.producer == *q->headers.consumer) { + if (le32_to_cpu(*q->headers.producer) == le32_to_cpu(*q->headers.consumer)) { status = 0; } else { /* @@ -564,7 +571,7 @@ int aac_consumer_avail(struct aac_dev *dev, struct aac_queue * q) { - return (*q->headers.producer != *q->headers.consumer); + return (le32_to_cpu(*q->headers.producer) != le32_to_cpu(*q->headers.consumer)); } @@ -583,7 +590,7 @@ int wasfull = 0; u32 notify; - if (*q->headers.producer+1 == *q->headers.consumer) + if ((le32_to_cpu(*q->headers.producer)+1) == le32_to_cpu(*q->headers.consumer)) wasfull = 1; if (le32_to_cpu(*q->headers.consumer) >= q->entries) @@ -625,16 +632,15 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size) { - struct hw_fib * fib = fibptr->fib; + struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_dev * dev = fibptr->dev; unsigned long nointr = 0; - - if (le32_to_cpu(fib->header.XferState) == 0) + if (le32_to_cpu(hw_fib->header.XferState) == 0) return 0; /* * If we plan to do anything check the structure type first. */ - if ( fib->header.StructType != FIB_MAGIC ) { + if ( hw_fib->header.StructType != FIB_MAGIC ) { return -EINVAL; } /* @@ -644,34 +650,34 @@ * and want to send a response back to the adapter. This will * send the completed cdb to the adapter. */ - if (fib->header.XferState & cpu_to_le32(SentFromAdapter)) { - fib->header.XferState |= cpu_to_le32(HostProcessed); - if (fib->header.XferState & cpu_to_le32(HighPriority)) { + if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { + hw_fib->header.XferState |= cpu_to_le32(HostProcessed); + if (hw_fib->header.XferState & cpu_to_le32(HighPriority)) { u32 index; if (size) { size += sizeof(struct aac_fibhdr); - if (size > le16_to_cpu(fib->header.SenderSize)) + if (size > le16_to_cpu(hw_fib->header.SenderSize)) return -EMSGSIZE; - fib->header.Size = cpu_to_le16(size); + hw_fib->header.Size = cpu_to_le16(size); } - if(aac_queue_get(dev, &index, AdapHighRespQueue, fib, 1, NULL, &nointr) < 0) { + if(aac_queue_get(dev, &index, AdapHighRespQueue, hw_fib, 1, NULL, &nointr) < 0) { return -EWOULDBLOCK; } if (aac_insert_entry(dev, index, AdapHighRespQueue, (nointr & (int)aac_config.irq_mod)) != 0) { } } - else if (fib->header.XferState & NormalPriority) + else if (hw_fib->header.XferState & NormalPriority) { u32 index; if (size) { size += sizeof(struct aac_fibhdr); - if (size > le16_to_cpu(fib->header.SenderSize)) + if (size > le16_to_cpu(hw_fib->header.SenderSize)) return -EMSGSIZE; - fib->header.Size = cpu_to_le16(size); + hw_fib->header.Size = cpu_to_le16(size); } - if (aac_queue_get(dev, &index, AdapNormRespQueue, fib, 1, NULL, &nointr) < 0) + if (aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr) < 0) return -EWOULDBLOCK; if (aac_insert_entry(dev, index, AdapNormRespQueue, (nointr & (int)aac_config.irq_mod)) != 0) @@ -696,19 +702,19 @@ int fib_complete(struct fib * fibptr) { - struct hw_fib * fib = fibptr->fib; + struct hw_fib * hw_fib = fibptr->hw_fib; /* * Check for a fib which has already been completed */ - if (fib->header.XferState == cpu_to_le32(0)) + if (hw_fib->header.XferState == cpu_to_le32(0)) return 0; /* * If we plan to do anything check the structure type first. */ - if (fib->header.StructType != FIB_MAGIC) + if (hw_fib->header.StructType != FIB_MAGIC) return -EINVAL; /* * This block completes a cdb which orginated on the host and we @@ -716,19 +722,19 @@ * command is complete that we had sent to the adapter and this * cdb could be reused. */ - if((fib->header.XferState & cpu_to_le32(SentFromHost)) && - (fib->header.XferState & cpu_to_le32(AdapterProcessed))) + if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) && + (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) { fib_dealloc(fibptr); } - else if(fib->header.XferState & cpu_to_le32(SentFromHost)) + else if(hw_fib->header.XferState & cpu_to_le32(SentFromHost)) { /* * This handles the case when the host has aborted the I/O * to the adapter because the adapter is not responding */ fib_dealloc(fibptr); - } else if(fib->header.XferState & cpu_to_le32(HostOwned)) { + } else if(hw_fib->header.XferState & cpu_to_le32(HostOwned)) { fib_dealloc(fibptr); } else { BUG(); @@ -776,16 +782,115 @@ * dispatches it to the appropriate routine for handling. */ +#define CONTAINER_TO_BUS(cont) (0) +#define CONTAINER_TO_TARGET(cont) ((cont)) +#define CONTAINER_TO_LUN(cont) (0) + static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) { - struct hw_fib * fib = fibptr->fib; - /* - * Set the status of this FIB to be Invalid parameter. - * - * *(u32 *)fib->data = ST_INVAL; - */ - *(u32 *)fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(fibptr, sizeof(u32)); + struct hw_fib * hw_fib = fibptr->hw_fib; + struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; + int busy; + u32 container; + mm_segment_t fs; + + /* Sniff for container changes */ + dprintk ((KERN_INFO "AifCmdDriverNotify=%x\n", le32_to_cpu(*(u32 *)aifcmd->data))); + switch (le32_to_cpu(*(u32 *)aifcmd->data)) { + case AifDenMorphComplete: + case AifDenVolumeExtendComplete: + case AifEnContainerChange: /* Not really a driver notify Event */ + + busy = 0; + container = le32_to_cpu(((u32 *)aifcmd->data)[1]); + dprintk ((KERN_INFO "container=%d(%d,%d,%d,%d) ", + container, + (dev && dev->scsi_host_ptr) + ? dev->scsi_host_ptr->host_no + : -1, + CONTAINER_TO_BUS(container), + CONTAINER_TO_TARGET(container), + CONTAINER_TO_LUN(container))); + + /* + * Find the Scsi_Device associated with the SCSI address, + * and mark it as changed, invalidating the cache. This deals + * with changes to existing device IDs. + */ + + if ((dev != (struct aac_dev *)NULL) + && (dev->scsi_host_ptr != (struct Scsi_Host *)NULL)) { + Scsi_Device * device; + + for (device = dev->scsi_host_ptr->host_queue; + device != (Scsi_Device *)NULL; + device = device->next) { + dprintk((KERN_INFO + "aifd: device (%d,%d,%d,%d)?\n", + dev->scsi_host_ptr->host_no, + device->channel, + device->id, + device->lun)); + if ((device->channel == CONTAINER_TO_BUS(container)) + && (device->id == CONTAINER_TO_TARGET(container)) + && (device->lun == CONTAINER_TO_LUN(container))) { + busy |= (device->access_count != 0); + if (busy == 0) { + device->removable = TRUE; + } + } + } + } + dprintk (("busy=%d\n", busy)); + + /* + * if (busy == 0) { + * scan_scsis(dev->scsi_host_ptr, 1, + * CONTAINER_TO_BUS(container), + * CONTAINER_TO_TARGET(container), + * CONTAINER_TO_LUN(container)); + * } + * is not exported as accessible, so we need to go around it + * another way. So, we look for the "proc/scsi/scsi" entry in + * the proc filesystem (using proc_scsi as a shortcut) and send + * it a message. This deals with new devices that have + * appeared. If the device has gone offline, scan_scsis will + * also discover this, but we do not want the device to + * go away. We need to check the access_count for the + * device since we are not wanting the devices to go away. + */ + if (busy == 0 && proc_scsi != NULL) { + struct proc_dir_entry * entry; + + dprintk((KERN_INFO "proc_scsi=%p ", proc_scsi)); + for (entry = proc_scsi->subdir; entry != (struct proc_dir_entry *)NULL; entry = entry->next) { + dprintk(("\"%.*s\"[%d]=%x ", entry->namelen, + entry->name, entry->namelen, entry->low_ino)); + if ((entry->low_ino != 0) && (entry->namelen == 4) && (memcmp ("scsi", entry->name, 4) == 0)) { + dprintk(("%p->write_proc=%p ", entry, entry->write_proc)); + if (entry->write_proc != (int (*)(struct file *, const char *, unsigned long, void *))NULL) { + char buffer[80]; + int length; + + sprintf (buffer, + "scsi add-single-device %d %d %d %d\n", + dev->scsi_host_ptr->host_no, + CONTAINER_TO_BUS(container), + CONTAINER_TO_TARGET(container), + CONTAINER_TO_LUN(container)); + length = strlen (buffer); + dprintk((KERN_INFO "echo %.*s > /proc/scsi/scsi\n", length-1, buffer)); + fs = get_fs(); + set_fs(get_ds()); + length = entry->write_proc(NULL, buffer, length, NULL); + set_fs(fs); + dprintk((KERN_INFO "returns %d\n", length)); + } + break; + } + } + } + } } /** @@ -800,8 +905,8 @@ int aac_command_thread(struct aac_dev * dev) { - struct hw_fib *fib, *newfib; - struct fib fibptr; /* for error logging */ + struct hw_fib *hw_fib, *hw_newfib; + struct fib *fib, *newfib; struct aac_queue_block *queues = dev->queues; struct aac_fib_context *fibctx; unsigned long flags; @@ -822,9 +927,9 @@ * Let the DPC know it has a place to send the AIF's to. */ dev->aif_thread = 1; - memset(&fibptr, 0, sizeof(struct fib)); add_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait); set_current_state(TASK_INTERRUPTIBLE); + dprintk ((KERN_INFO "aac_command_thread start\n")); while(1) { spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags); @@ -833,37 +938,47 @@ struct aac_aifcmd * aifcmd; set_current_state(TASK_RUNNING); - + entry = queues->queue[HostNormCmdQueue].cmdq.next; list_del(entry); - + spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags); - fib = list_entry(entry, struct hw_fib, header.FibLinks); + fib = list_entry(entry, struct fib, fiblink); /* * We will process the FIB here or pass it to a * worker thread that is TBD. We Really can't * do anything at this point since we don't have * anything defined for this thread to do. */ - memset(&fibptr, 0, sizeof(struct fib)); - fibptr.type = FSAFS_NTC_FIB_CONTEXT; - fibptr.size = sizeof( struct fib ); - fibptr.fib = fib; - fibptr.data = fib->data; - fibptr.dev = dev; + hw_fib = fib->hw_fib; + + memset(fib, 0, sizeof(struct fib)); + fib->type = FSAFS_NTC_FIB_CONTEXT; + fib->size = sizeof( struct fib ); + fib->hw_fib = hw_fib; + fib->data = hw_fib->data; + fib->dev = dev; /* * We only handle AifRequest fibs from the adapter. */ - aifcmd = (struct aac_aifcmd *) fib->data; - if (aifcmd->command == le16_to_cpu(AifCmdDriverNotify)) { - aac_handle_aif(dev, &fibptr); + aifcmd = (struct aac_aifcmd *) hw_fib->data; + if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) { + /* Handle Driver Notify Events */ + aac_handle_aif(dev, fib); + *(u32 *)hw_fib->data = cpu_to_le32(ST_OK); + fib_adapter_complete(fib, sizeof(u32)); } else { + struct list_head *entry; /* The u32 here is important and intended. We are using 32bit wrapping time to fit the adapter field */ u32 time_now, time_last; unsigned long flagv; + /* Sniff events */ + if (aifcmd->command == cpu_to_le32(AifCmdEventNotify)) + aac_handle_aif(dev, fib); + time_now = jiffies/HZ; spin_lock_irqsave(&dev->fib_lock, flagv); @@ -885,6 +1000,11 @@ */ if (fibctx->count > 20) { + /* + * It's *not* jiffies folks, + * but jiffies / HZ, so do not + * panic ... + */ time_last = fibctx->jiffies; /* * Has it been > 2 minutes @@ -901,17 +1021,21 @@ * Warning: no sleep allowed while * holding spinlock */ - newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC); - if (newfib) { + hw_newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC); + newfib = kmalloc(sizeof(struct fib), GFP_ATOMIC); + if (newfib && hw_newfib) { /* * Make the copy of the FIB + * FIXME: check if we need to fix other fields up */ - memcpy(newfib, fib, sizeof(struct hw_fib)); + memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib)); + memcpy(newfib, fib, sizeof(struct fib)); + newfib->hw_fib = hw_newfib; /* * Put the FIB onto the * fibctx's fibs */ - list_add_tail(&newfib->header.FibLinks, &fibctx->fibs); + list_add_tail(&newfib->fiblink, &fibctx->fib_list); fibctx->count++; /* * Set the event to wake up the @@ -920,17 +1044,22 @@ up(&fibctx->wait_sem); } else { printk(KERN_WARNING "aifd: didn't allocate NewFib.\n"); + if(newfib) + kfree(newfib); + if(hw_newfib) + kfree(hw_newfib); } entry = entry->next; } /* * Set the status of this FIB */ - *(u32 *)fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(&fibptr, sizeof(u32)); + *(u32 *)hw_fib->data = cpu_to_le32(ST_OK); + fib_adapter_complete(fib, sizeof(u32)); spin_unlock_irqrestore(&dev->fib_lock, flagv); } spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags); + kfree(fib); } /* * There are no more AIF's diff -urN linux-2.4.21/drivers/scsi/aacraid/dpcsup.c linux-2.4.22/drivers/scsi/aacraid/dpcsup.c --- linux-2.4.21/drivers/scsi/aacraid/dpcsup.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/dpcsup.c 2003-08-25 04:44:42.000000000 -0700 @@ -74,12 +74,14 @@ */ while(aac_consumer_get(dev, q, &entry)) { - int fast; + u32 fast ; + fast = (entry->addr & cpu_to_le32(0x01)); +// fib = &dev->fibs[(entry->addr >> 1)]; +// hwfib = fib->hw_fib; + hwfib = bus_to_virt(le32_to_cpu(entry->addr & cpu_to_le32(~0x01))); + fib = &dev->fibs[hwfib->header.SenderData]; - fast = (int) (entry->addr & 0x01); - hwfib = addr2fib(entry->addr & ~0x01); aac_consumer_free(dev, q, HostNormRespQueue); - fib = &dev->fibs[hwfib->header.SenderData]; /* * Remove this fib from the Outstanding I/O queue. * But only if it has not already been timed out. @@ -169,30 +171,51 @@ * up the waiters until there are no more QEs. We then return * back to the system. */ + dprintk((KERN_INFO + "dev=%p, dev->comm_phys=%x, dev->comm_addr=%p, dev->comm_size=%u\n", + dev, (u32)dev->comm_phys, dev->comm_addr, (unsigned)dev->comm_size)); + while(aac_consumer_get(dev, q, &entry)) { - struct hw_fib * fib; - fib = addr2fib(entry->addr); + struct fib fibctx; + struct fib *fib = &fibctx; + u32 hw_fib_pa = le32_to_cpu(entry->addr & cpu_to_le32(~0x01)); + struct hw_fib * hw_fib_va = ((dev->comm_phys <= hw_fib_pa) + && (hw_fib_pa < (dev->comm_phys + dev->comm_size))) + ? dev->comm_addr + (hw_fib_pa - dev->comm_phys) + : /* inconceivable */ bus_to_virt(hw_fib_pa); + dprintk((KERN_INFO "hw_fib_pa=%x hw_fib_va=%p\n", hw_fib_pa, hw_fib_va)); - if (dev->aif_thread) { - list_add_tail(&fib->header.FibLinks, &q->cmdq); + /* + * Allocate a FIB at all costs. For non queued stuff + * we can just use the stack so we are happy. We need + * a fib object in order to manage the linked lists + */ + if (dev->aif_thread) + if((fib = kmalloc(sizeof(struct fib), GFP_ATOMIC))==NULL) + fib = &fibctx; + + memset(fib, 0, sizeof(struct fib)); + INIT_LIST_HEAD(&fib->fiblink); + fib->type = FSAFS_NTC_FIB_CONTEXT; + fib->size = sizeof(struct fib); + fib->hw_fib = hw_fib_va; + fib->data = hw_fib_va->data; + fib->dev = dev; + + if (dev->aif_thread && fib != &fibctx) + { + list_add_tail(&fib->fiblink, &q->cmdq); aac_consumer_free(dev, q, HostNormCmdQueue); wake_up_interruptible(&q->cmdready); } else { - struct fib fibctx; aac_consumer_free(dev, q, HostNormCmdQueue); spin_unlock_irqrestore(q->lock, flags); - memset(&fibctx, 0, sizeof(struct fib)); - fibctx.type = FSAFS_NTC_FIB_CONTEXT; - fibctx.size = sizeof(struct fib); - fibctx.fib = fib; - fibctx.data = fib->data; - fibctx.dev = dev; /* * Set the status of this FIB */ - *(u32 *)fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(&fibctx, sizeof(u32)); + *(u32 *)hw_fib_va->data = cpu_to_le32(ST_OK); + fib_adapter_complete(fib, sizeof(u32)); spin_lock_irqsave(q->lock, flags); } } diff -urN linux-2.4.21/drivers/scsi/aacraid/linit.c linux-2.4.22/drivers/scsi/aacraid/linit.c --- linux-2.4.21/drivers/scsi/aacraid/linit.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aacraid/linit.c 2003-08-25 04:44:42.000000000 -0700 @@ -35,8 +35,8 @@ * */ -#define AAC_DRIVER_VERSION "0.9.9ac6-TEST" -#define AAC_DRIVER_BUILD_DATE __DATE__ +#define AAC_DRIVER_VERSION "1.1.2" +#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__ #include #include @@ -59,12 +59,12 @@ #define AAC_DRIVERNAME "aacraid" MODULE_AUTHOR("Red Hat Inc and Adaptec"); -MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, PERC 320/DC, Adaptec 2120S, 2200S, 5400S, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com"); +MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, Adaptec Advanced Raid Products, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com"); MODULE_LICENSE("GPL"); -MODULE_PARM(nondasd, "i"); -MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); +MODULE_PARM(paemode, "i"); +MODULE_PARM_DESC(paemode, "Control whether dma addressing is using PAE. 0=off, 1=on"); -static int nondasd=-1; +static int paemode = -1; struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS]; @@ -81,25 +81,41 @@ */ static struct aac_driver_ident aac_drivers[] = { - { 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 2/Si */ - { 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */ - { 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Si */ - { 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Si */ - { 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */ - { 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */ - { 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */ - { 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */ - { 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */ - { 0x9005, 0x0283, 0x9005, 0x0283, aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2 }, /* catapult*/ - { 0x9005, 0x0284, 0x9005, 0x0284, aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2 }, /* tomcat*/ - { 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1 }, /* Adaptec 2120S (Crusader)*/ - { 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2 }, /* Adaptec 2200S (Vulcan)*/ - { 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2 }, /* Adaptec 2200S (Vulcan-2m)*/ - { 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* Dell PERC 320/DC */ - { 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4 }, /* Adaptec 5400S (Mustang)*/ - { 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4 }, /* Adaptec 5400S (Mustang)*/ - { 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4 }, /* Dell PERC2 "Quad Channel" */ - { 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid", "HP ", "NetRAID-4M ", 4 } /* HP NetRAID-4M */ + { 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 2/Si (Iguana/PERC2Si) */ + { 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Opal/PERC3Di) */ + { 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Si (SlimFast/PERC3Si */ + { 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */ + { 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Viper/PERC3DiV) */ + { 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Lexus/PERC3DiL) */ + { 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Jaguar/PERC3DiJ) */ + { 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Dagger/PERC3DiD) */ + { 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Boxster/PERC3DiB) */ + { 0x9005, 0x0283, 0x9005, 0x0283, aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2 }, /* catapult */ + { 0x9005, 0x0284, 0x9005, 0x0284, aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2 }, /* tomcat */ + { 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT },/* Adaptec 2120S (Crusader) */ + { 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan) */ + { 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan-2m) */ + { 0x9005, 0x0285, 0x17aa, 0x0286, aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1 }, /* Legend S220 (Legend Crusader) */ + { 0x9005, 0x0285, 0x17aa, 0x0287, aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2 }, /* Legend S230 (Legend Vulcan) */ + + { 0x9005, 0x0285, 0x9005, 0x0288, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3230S ", 2 }, /* Adaptec 3230S (Harrier) */ + { 0x9005, 0x0285, 0x9005, 0x0289, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3240S ", 2 }, /* Adaptec 3240S (Tornado) */ + { 0x9005, 0x0285, 0x9005, 0x028a, aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S PCI-X ZCR (Skyhawk) */ + { 0x9005, 0x0285, 0x9005, 0x028b, aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S SO-DIMM PCI-X ZCR (Terminator) */ + { 0x9005, 0x0285, 0x9005, 0x0290, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2410SA SATA ", 2 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */ + { 0x9005, 0x0285, 0x1028, 0x0291, aac_rx_init, "aacraid", "DELL ", "CERC SATA RAID 2 ", 2 }, /* CERC SATA RAID 2 PCI SATA 8ch (DellCorsair) */ + { 0x9005, 0x0285, 0x9005, 0x0292, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2810SA SATA ", 2 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */ + { 0x9005, 0x0285, 0x9005, 0x0293, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-21610SA SATA ", 2 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */ + { 0x9005, 0x0285, 0x9005, 0x0294, aac_rx_init, "aacraid", "ADAPTEC ", "SO-DIMM SATA ZCR ", 2 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ + /* ServeRAID */ +/* { 0x9005, 0x0250, 0x1014, 0x0279, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, */ /* (Marco) */ +/* { 0x9005, 0x0250, 0x1014, 0x028c, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, */ /* (Sebring)*/ + + { 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2 }, /* Perc 320/DC*/ + { 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4 }, /* Adaptec 5400S (Mustang)*/ + { 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4 }, /* Adaptec 5400S (Mustang)*/ + { 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4 }, /* Dell PERC2 "Quad Channel" */ + { 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4 } /* HP NetRAID-4M */ }; #define NUM_AACTYPES (sizeof(aac_drivers) / sizeof(struct aac_driver_ident)) @@ -159,10 +175,11 @@ struct fsa_scsi_hba *fsa_dev_ptr; char *name = NULL; - printk(KERN_INFO "Red Hat/Adaptec aacraid driver, %s\n", AAC_DRIVER_BUILD_DATE); + printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n", AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE); /* setting up the proc directory structure */ template->proc_name = "aacraid"; + spin_unlock_irq(&io_request_lock); for( index = 0; index != num_aacdrivers; index++ ) { @@ -179,7 +196,11 @@ if (pci_enable_device(dev)) continue; pci_set_master(dev); - pci_set_dma_mask(dev, 0xFFFFFFFFULL); + + if(aac_drivers[index].quirks & AAC_QUIRK_31BIT) + pci_set_dma_mask(dev, 0x7FFFFFFFULL); + else + pci_set_dma_mask(dev, 0xFFFFFFFFULL); if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) || (dev->subsystem_device != aac_drivers[index].subsystem_device)) @@ -188,8 +209,6 @@ dprintk((KERN_DEBUG "%s device detected.\n", name)); dprintk((KERN_DEBUG "%x/%x/%x/%x.\n", vendor_id, device_id, aac_drivers[index].subsystem_vendor, aac_drivers[index].subsystem_device)); - /* Increment the host adapter count */ - aac_count++; /* * scsi_register() allocates memory for a Scsi_Hosts structure and * links it into the linked list of host adapters. This linked list @@ -203,13 +222,14 @@ * specific information. */ host_ptr = scsi_register( template, sizeof(struct aac_dev) ); + if(host_ptr == NULL) + continue; + /* Increment the host adapter count */ + aac_count++; /* * These three parameters can be used to allow for wide SCSI * and for host adapters that support multiple buses. */ - host_ptr->max_id = 17; - host_ptr->max_lun = 8; - host_ptr->max_channel = 1; host_ptr->irq = dev->irq; /* Adapter IRQ number */ /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */ host_ptr->base = dev->resource[0].start; @@ -236,9 +256,13 @@ /* attach a pointer back to Scsi_Host */ aac->scsi_host_ptr = host_ptr; aac->pdev = dev; - aac->cardtype = index; aac->name = aac->scsi_host_ptr->hostt->name; aac->id = aac->scsi_host_ptr->unique_id; + aac->cardtype = index; + + aac->fibs = (struct fib*) kmalloc(sizeof(struct fib)*AAC_NUM_FIB, GFP_KERNEL); + spin_lock_init(&aac->fib_lock); + /* Initialize the ordinal number of the device to -1 */ fsa_dev_ptr = &(aac->fsa_dev); for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ ) @@ -255,15 +279,6 @@ } dprintk((KERN_DEBUG "%s:%d device initialization successful.\n", name, host_ptr->unique_id)); aac_get_adapter_info(aac); - if(nondasd != -1) - { - /* someone told us how to set this on the cmdline */ - aac->nondasd_support = (nondasd!=0); - } - if(aac->nondasd_support != 0){ - printk(KERN_INFO "%s%d: Non-DASD support enabled\n", aac->name, aac->id); - } - dprintk((KERN_DEBUG "%s:%d options flag %04x.\n",name, host_ptr->unique_id,aac->adapter_info.options)); if(aac->nondasd_support == 1) { /* @@ -280,21 +295,11 @@ aac_devices[aac_count-1] = aac; /* - * dmb - we may need to move these 3 parms somewhere else once + * dmb - we may need to move the setting of these parms somewhere else once * we get a fib that can report the actual numbers */ host_ptr->max_id = AAC_MAX_TARGET; host_ptr->max_lun = AAC_MAX_LUN; - - /* - * If we are PAE capable then our future DMA mappings - * (for read/write commands) are 64bit clean and don't - * need bouncing. This assumes we do no other 32bit only - * allocations (eg fib table expands) after this point. - */ - - if(aac->pae_support) - pci_set_dma_mask(dev, 0xFFFFFFFFFFFFFFFFUL); } } @@ -302,6 +307,7 @@ if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0) printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n"); } + spin_lock_irq(&io_request_lock); template->present = aac_count; /* # of cards of this type found */ return aac_count; @@ -738,7 +744,10 @@ if(write || offset > 0) return 0; *start_ptr = proc_buffer; - return sprintf(proc_buffer, "%s %d\n", "Raid Controller, scsi hba number", host_no); + return sprintf(proc_buffer, + "Adaptec Raid Controller %s %s, scsi hba number %d\n", + AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE, + host_no); } EXPORT_NO_SYMBOLS; diff -urN linux-2.4.21/drivers/scsi/aacraid/rx.c linux-2.4.22/drivers/scsi/aacraid/rx.c --- linux-2.4.21/drivers/scsi/aacraid/rx.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/rx.c 2003-08-25 04:44:42.000000000 -0700 @@ -400,6 +400,11 @@ * Start any kernel threads needed */ dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); + if(dev->thread_pid < 0) + { + printk(KERN_ERR "aacraid: Unable to create rx thread.\n"); + return -1; + } /* * Tell the adapter that all is configured, and it can start * accepting requests diff -urN linux-2.4.21/drivers/scsi/aacraid/sa.c linux-2.4.22/drivers/scsi/aacraid/sa.c --- linux-2.4.21/drivers/scsi/aacraid/sa.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aacraid/sa.c 2003-08-25 04:44:42.000000000 -0700 @@ -349,7 +349,7 @@ * Wait for the adapter to be up and running. Wait up to 3 minutes. */ while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) { - if (time_after(start+180*HZ, jiffies)) { + if (time_after(jiffies, start+180*HZ)) { status = sa_readl(dev, Mailbox7) >> 16; printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %d.\n", name, instance, le32_to_cpu(status)); return -1; @@ -384,6 +384,11 @@ * Start any kernel threads needed */ dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); + if (dev->thread_pid < 0) { + printk(KERN_ERR "aacraid: Unable to create command thread.\n"); + return -1; + } + /* * Tell the adapter that all is configure, and it can start * accepting requests diff -urN linux-2.4.21/drivers/scsi/aha152x.c linux-2.4.22/drivers/scsi/aha152x.c --- linux-2.4.21/drivers/scsi/aha152x.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aha152x.c 2003-08-25 04:44:42.000000000 -0700 @@ -1930,12 +1930,30 @@ static void intr(int irqno, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *shpnt = lookup_irq(irqno); + unsigned char rev, dmacntrl0; if (!shpnt) { printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno); return; } + /* + * Read a couple of registers that are known to not be all 1's. If + * we read all 1's (-1), that means that either: + * a. The host adapter chip has gone bad, and we cannot control it, + * OR + * b. The host adapter is a PCMCIA card that has been ejected + * In either case, we cannot do anything with the host adapter at + * this point in time. So just ignore the interrupt and return. + * In the latter case, the interrupt might actually be meant for + * someone else sharing this IRQ, and that driver will handle it + */ + rev = GETPORT(REV); + dmacntrl0 = GETPORT(DMACNTRL0); + if ((rev == 0xFF) && (dmacntrl0 == 0xFF)) { + return; + } + /* no more interrupts from the controller, while we're busy. INTEN is restored by the BH handler */ CLRBITS(DMACNTRL0, INTEN); diff -urN linux-2.4.21/drivers/scsi/aic79xx/CHANGELOG linux-2.4.22/drivers/scsi/aic79xx/CHANGELOG --- linux-2.4.21/drivers/scsi/aic79xx/CHANGELOG 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/CHANGELOG 1969-12-31 16:00:00.000000000 -0800 @@ -1,23260 +0,0 @@ -Change 1861 by scottl@scottl-template on 2003/01/21 18:26:00 - - Update driver version to 1.3.0 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#108 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#25 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#28 edit - -Change 1859 by scottl@scottl-template on 2003/01/21 15:27:08 - - readme.txt: - README.aic7xxx: - Convert tabs to spaces. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#4 edit -... //depot/linux_mod_devel/scsi.aic7xxx/readme.txt#4 edit - -Change 1858 by scottl@scottl-template on 2003/01/21 14:43:42 - - readme.txt: - README.aic79xx: - Fix the wording of the 1.3.0 version history line - Replace tabs with spaces. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#6 edit -... //depot/linux_mod_devel/scsi.aic79xx/readme.txt#18 edit - -Change 1856 by gibbs@bitkeeper-linux-2.5 on 2003/01/21 12:37:08 - - Update the embedded aic7xxx driver README. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#3 edit - -Change 1854 by gibbs@bitkeeper-linux-2.5 on 2003/01/21 12:12:27 - - Update aic79xx README used for embedding. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#5 edit - -Change 1851 by gibbs@bitkeeper-linux-2.5 on 2003/01/20 16:45:59 - - Bump aic7xxx driver to version 6.2.28. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#123 edit - -Change 1850 by scottl@scottl-template on 2003/01/20 16:29:28 - - Update driver version to 1.3.0.RC2 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#107 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#24 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#27 edit - -Change 1849 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 16:23:35 - - aic79xx_osm.c: - Correct the BUILD_SCSIID macro to take into account the - future removal of target, lun and channel from the - scsi_cmnd structure. - - Clean up ahd_linux_initialize_scsi_bus(). The indirection - was left over from the port from aic7xxx where twin - channel adapters come into play. The result in the aic79xx - driver just looked silly. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#115 edit - -Change 1848 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 16:20:47 - - aic79xx.c: - Fix a missed goal.period -> goal.offset change. In - this case, the bug resulted in comparing a period - against an offset. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#156 edit - -Change 1847 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 10:14:37 - - aic79xx.c: - aic7xxx.c: - Indicate the features, bugs, and flags set in the softc - that are used to control firmware patch download when - booting verbose. - - aic7xxx.c: - Fix an ifdef bug that caused sequencer debugging to - be enabled always. - - Clear the ultraenb flag in our tstate during startup. - The ultraenbled'ness of a device is recorded in the user - transfer settings. tstate->ultraenb bitmask indicates - which devices we have negotiated an ultra speed with. - Just after initialization, we are async. Setting the - ultraenb flag while async seems to be harmless, but it - was confusing to see the ULTRAENB flag set in the SCB. - - Allow ahc_dump_card_state() to be called when the sequencer - is not paused. Add dump card state markers as in the U320 - driver. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#155 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#112 edit - -Change 1846 by gibbs@bitkeeper-linux-2.4 on 2003/01/20 09:53:07 - - aic79xx_osm.c: - aic7xxx_osm.c: - Dump card state on DV timeouts when SHOW_DV debug - option is set. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#114 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#179 edit - -Change 1845 by gibbs@bitkeeper-linux-2.4 on 2003/01/17 14:46:30 - - aic79xx.c: - aic7xxx.c: - Force an SDTR after a rejected WDTR if the - syncrate is unkonwn. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#154 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#111 edit - -Change 1844 by gibbs@bitkeeper-linux-2.5 on 2003/01/17 13:20:26 - - aic7xxx_osm.h: - Bump driver version to 6.2.27. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#122 edit - -Change 1843 by gibbs@overdrive on 2003/01/17 13:06:51 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#22 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#23 edit - -Change 1842 by scottl@scottl-template on 2003/01/17 12:39:50 - - Update driver version to 1.3.0.RC1 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#106 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#23 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#26 edit - -Change 1841 by gibbs@bitkeeper-linux-2.4 on 2003/01/17 12:39:21 - - aic7xxx.c: - aic7xxx.h: - aic7xxx_pci.c: - Take another stab at disabling PCI errors in the aic7xxx - driver. We now just clear the PERRRESEN bit in the command - register. This option is now enabled via a new flag in - ahc->flags: AHC_DISABLE_PCI_PERR. - - aic7xxx_osm.c: - Hook the already existing pci_parity option. Parity - defaults to off since so many Linux users have clunky - VIA chipsets that cause spurious warnings. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#110 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#70 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#178 edit - -Change 1840 by scottl@scottl-template on 2003/01/16 18:53:11 - - aic7xxx_osm.c: - Fix missed AHD->AHC substitutions from last commit. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#177 edit - -Change 1839 by scottl@scottl-template on 2003/01/16 18:51:20 - - aic7xxx_osm.c: - Traverse the array of targets and devices in - ahc_platform_free() and remove each device. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#176 edit - -Change 1838 by scottl@scottl-template on 2003/01/16 18:46:46 - - aic79xx_osm.c: - Traverse the arrays of targets and devices to free each - device when ahd_platform_free() is called. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#113 edit - -Change 1837 by gibbs@bitkeeper-linux-2.4 on 2003/01/16 16:24:58 - - aic79xx_osm.c: - aic79xx_osm.h: - aic7xxx_osm.c: - aic7xxx_osm.h: - Adapt to upcoming 2.5.X change. The host, target, channel, - and lun fields are disappearing from the scsi_cmnd structure. - We must instead get this data from the scsi_device structure - hung off the command. The only trick in this is an update - to how we fake up DV commands. We now need to fake up a - scsi_device too. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#112 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#105 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#175 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#121 edit - -Change 1836 by gibbs@bitkeeper-linux-2.4 on 2003/01/16 14:39:58 - - aic79xx.c: - Only send an async update to the luns affected by - the device reset now that ahd_handle_devreset is - called for lun resets too. - - aic79xx_osm.c: - Only bother dumping card state after we've determined - that the command to be aborted is still active on the - controller. - - aic79xx_osm.c: - aic7xxx_osm.c: - Have the AC_SENT_BDR handler manually set the was_reset - and expecting_cc_ua flags in all devices that are - affected by the target/lun reset. - - Never allow cmd->retries to go below zero. cmd->retries - is not incremented when a command goes through recovery. - This could allow the retry count to suddenly become a - very large number. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#153 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#111 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#174 edit - -Change 1834 by gibbs@aslan on 2003/01/15 21:32:22 - - aic7xxx.seq: - Correct a target mode regression that prevented the - driver from properly handling unexpected - messages (negotiation, etc). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 edit - -Change 1833 by gibbs@bitkeeper-linux-2.4 on 2003/01/15 21:27:13 - - aic79xx_osm.c: - Split out the abort handler from the dev reset handler. - The dev reset handler will now use a new SCB to issue - the dev reset. This avoids a potential problem with - SCB race issues for dev resets. - - Manually set the task management function now that - ahd_queue_scb() doesn't do this for us. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#110 edit - -Change 1832 by gibbs@bitkeeper-linux-2.4 on 2003/01/15 21:20:59 - - aic79xx.c: - Update copyright for 2003. - - Modify ahd_handle_devreset so that it can handle - lun resets in addition to target resets. - - Correct a bug in the illegal phase handler that - caused us to drop down to narrow when handling the - unexpected command phase case after 3rd party - reset of a packetized device. - - Add some diagnostics to the task management function code. - - Use ahd_handle_devreset for lun and target reset task - management functions. - - Handle the abort task TMF race case better. We now - wait until any current selections are over and then - set the TMF back to zero. This should cause the sequencer - to ignore the abort TMF completion should it occur. - - Correct a regression in ahd_sent_msg that caused it to fail - to recognize any 1byte messages other than identify. - - aic79xx_inline.h: - Allow callers to ahd_send_scb() to set the task management - function. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#152 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#41 edit - -Change 1831 by scottl@scottl-template on 2003/01/15 17:37:56 - - Move aic_error_action and aic_calc_speed out of the osm's and - into aiclib. Do slight header adjustment to make it work. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#69 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#109 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#104 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#173 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#120 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#6 edit - -Change 1830 by gibbs@bitkeeper-linux-2.4 on 2003/01/15 15:33:45 - - aic79xx_osm.c: - aic79xx_osm.h: - aic7xxx_osm.c: - aic7xxx_osm.h: - Correct use of AHD_EH_UP_SEMAPHORE. This should - unbreak the recovery handler. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#108 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#103 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#172 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#119 edit - -Change 1829 by gibbs@overdrive on 2003/01/15 11:18:20 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#54 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#35 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#55 edit - -Change 1828 by gibbs@bitkeeper-linux-2.5 on 2003/01/15 10:19:07 - - aic79xx_osm.c: - Continue to dump the card state on timeouts for the - time being. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#107 edit - -Change 1827 by gibbs@bitkeeper-linux-2.5 on 2003/01/15 10:18:44 - - aic7xxx.h: - Reformat a few comments to follow driver style. - - Add a controller flag that indicates that a controller - has not been initialized by the BIOS. - - aic7xxx.c: - Disable PCI error interrupts on PCI adapters prior - to the Ultra2 controllers. This brings us in line - with what the other Adaptec drivers do, but it is - still not clear exactly why this status reporting - might be broken. - - Don't set our width to unknown when forcing negotiation - on narrow controllers. This will confuse the negotiation - code into negotiating with a wide message on narrow - controllers. - - In ahc_reset(), record whether or not we found the - controller in a reset state. If the controller was - already reset, assume that no BIOS has initialized - the controller and ignore left over scratch ram - settings. - - In ahc_dump_card_state() fix a logic reversal. The - SCSIPHASE register only exists on U160 controllers. - The SCSISIGI register exists on all controllers. Not - the other way around. - - aic7xxx_osm.c: - Format sense diagnostic in 16 byte rows. - - Remove a superfluous diagnostic printf. - - aic7xxx_pci.c: - Ensure that the PCIERRGENDIS bit is set in the - PCIERRGEN config space register. Perhaps this - is a reason for the spurios parity errors reported - on U160 controllers. - - Honor the AHC_NO_BIOS_INIT flag. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#109 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#68 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#56 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#171 edit - -Change 1826 by gibbs@bitkeeper-linux-2.5 on 2003/01/15 10:10:47 - - aic79xx.reg: - Add SEQINT codes for handling task management - completions. - - aic79xx.seq: - Add notifications to the host of task management - completions as well as the completions for commands - that have a task management function pending but - not yet sent. - - Hold a critical section during select-out processing - until we have a fully identified connection. This - removes a race condition with the legacy abort handler. - - Correct a few spelling errors in some comments. - - aic79xx_core.c - Flush the good status FIFO in ahd_flush_qoutfifo. - This routine should now catch all completed commands - in their various locations and states. - - Add support for task management function completions. - - If we are a narrow controller, don't set the current - width to unknown when forcing a future negotiation. - This just confuses the code into attempting a wide - negotiation on a narrow bus. - - aic79xx_osm.c: - Enable recovery code. Behavior should be similar to - that of the aic7xxx driver for legacy devices. For - packetized devices, we will now queue the appropriate - task management function. - - When printing out sense information, format in 16 - byte rows. - - scsi_iu.h: - Add definitions for the task management codes sent - in SPI4 command information units. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#151 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#60 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#78 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#106 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#4 edit - -Change 1825 by gibbs@bitkeeper-linux-2.5 on 2003/01/10 16:42:54 - - aic79xx_osm.c: - aic7xxx_osm.c: - Short cicuit domain validation if the inquiry - data for the device shows that it does not support - sync or wide transfers. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#105 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#170 edit - -Change 1820 by gibbs@bitkeeper-linux-2.5 on 2003/01/07 19:47:06 - - aic79xx_osm_pci.c: - Always set the pci_dma_mask. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#20 edit - -Change 1819 by gibbs@bitkeeper-linux-2.5 on 2003/01/07 19:44:50 - - aic7xxx_osm_pci.c: - Always initialize the pci_dma_mask. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#43 edit - -Change 1818 by gibbs@overdrive on 2003/01/07 19:11:29 - - aic79xx_osm.h: - aic7xxx_osm.h: - Correct version numbers. We are now at aic7xxx 6.2.26, - and aic79xx 1.3.0_BETA2. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#102 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#118 edit - -Change 1817 by scottl@scottl-template on 2003/01/07 19:03:54 - - Update driver version to 6.2.24 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#117 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#10 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#14 edit - -Change 1815 by scottl@scottl-belfalas-template on 2003/01/07 18:58:15 - - Forward declare and static-ize aic7xxx_setup(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#169 edit - -Change 1814 by gibbs@bitkeeper-linux-2.5 on 2003/01/07 18:35:16 - - aic7xxx_osm.h: - Add PCIM_CMD_SERRESPEN definition. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#116 edit - -Change 1813 by gibbs@overdrive on 2003/01/07 18:32:44 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#22 edit - -Change 1812 by gibbs@aslan on 2003/01/07 17:38:33 - - aic79xx_pci.c: - aic7xxx_pci.c: - Disable SERR and pause the controller prior to performing - our mmapped I/O test. This should handle the case of - controllers that do not "auto-access pause". For legacy - controllers, use SCB ram instead of scratch ram since - the latter may contain settings left over from the BIOS - that we will use if an seeprom is not found. - - aic7xxx.h: - aic7xxx.c: - Remove the probe_stack code. The stack is always - 4 deep on legacy controllers, so probing is pointless. - This also avoids an issue where probing the stack would - upset the aic7770. - - aic7xxx.c: - Print out the ERROR register in ahc_dump_card_state(). - - aic7xxx.reg: - Add a constant for the controller's stack size. - - aic7xxx.seq: - Style nit. The source is implied to be the destination - unless overridden in an "and" instruction. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#61 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#108 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#67 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#55 edit - -Change 1811 by gibbs@aslan on 2003/01/07 14:20:42 - - aicasm_gram.y: - Remove the numerical_value portion of the grammer - which is no longer referenced. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 edit - -Change 1810 by scottl@scottl-template on 2003/01/07 09:29:00 - - Update driver version to 1.3.0.BETA1 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#101 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#21 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#24 edit - -Change 1808 by gibbs@bitkeeper-linux-2.5 on 2003/01/06 14:21:46 - - aic7xxx_osm.c: - Correctly account for twin channel adapters in - pre-allocating target devices for initial DV scan. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#168 edit - -Change 1807 by gibbs@bitkeeper-linux-2.5 on 2003/01/06 11:58:41 - - aic79xx.c: - Correct ahd_find_syncrate() so that the actual - syncrate and not the "maximum syncrate" is modified - by tests that limit syncrate based on PPR options. - - aic7xxx.c: - aic79xx.c: - Enhance residual diagnostic to indicate if the residual - if for sense information or normal data transfers. - - aic79xx_osm.c: - aic7xxx_osm.c: - For the initial DV scan, only instantiate target objects - for IDs that can exist (i.e. only up to ID 7 on narrow - - Record the maximum bus width for fallback in the target - structure and use this to ensure we never fallback to - wide on a narrow target. - channels). - - Add DV diagnostic for failed inquiry verification. - - aic79xx_osm.h: - aic7xxx_osm.h: - Add dv_max_width to target structures and shrink several - fields to 8bits. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#150 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#107 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#104 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#100 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#167 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#115 edit -... //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#5 edit - -Change 1805 by scottl@scottl-junior-freebsd on 2002/12/30 21:13:11 - - Convert the use of MAXBSIZE in the dma tag to more appropriate values. - Use BUS_SPACE_MAXSIZE_32BIT for the parent dma tags, and - (NSEGS - 1) * PAGE_SIZE for the data buffer tags. FreeBSD/sparc64 is - more strick about checking these values that other arches. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#149 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#106 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#10 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#12 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#12 edit - -Change 1804 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 18:59:49 - - aic79xx_osm.h: - Bump version number to 1.3.0_ALPHA6 - - aic7xxx_osm.h: - Bump version number to 6.2.25. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#99 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#114 edit - -Change 1803 by gibbs@bitkeeper-linux-2.4 on 2002/12/30 16:54:09 - - aic79xx_osm.c: - aic7xxx_osm.c: - Reorganize DV state machine so that full inquiry data - is retrieved prior to testing to see if the unit is ready. - We now use this full inquiry data to assume defaults if - for some reason the DV state machine fails to configure - the device. This failsafe mechanism should ensure that - these devices are at least configured in the same fashion - as they were before the addition of DV to these drivers. - - aic79xx_osm.h: - aic7xxx_osm.h: - Re-arrange DV state enum to reflect current state machine - transitions. - - Add additional target flags used to implement the DV - failsafe mechanism. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#103 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#98 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#166 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#113 edit - -Change 1802 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 14:59:22 - - aic7770_osm.c: - aic79xx_osm_pci.c: - aic7xxx_osm_pci.c: - Clean up check_region() usage. It is deprecated in 2.5.X - and 2.4.X, but is still required in earlier kernels. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#42 edit - -Change 1801 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 13:50:25 - - aiclib.c: - Ignore media not-present errors during DV. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#5 edit - -Change 1800 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 13:50:10 - - aic79xx_osm.c: - aic7xxx_osm.c: - Use down_interruptable() rather than down() to avoid - having our thread counted toward the load average. - We disable all signal sources to that the down_interruptable() - is not really interruptable(). Singals are not required for - the drivers to terminate the DV threads on unload. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#102 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#165 edit - -Change 1799 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:19:23 - - aicasm_symbol.c: - Fix the last reference to the reg_print.c file handle - in symtable_dump. This allows the assembler to operate - without generating this file. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 edit - -Change 1798 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:18:05 - - aiclib.h: - Restore driver style. All functions are declared prior - to being defined. The original bug was that the 2.4.X - declaration was used unconditionally. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#5 edit - -Change 1797 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:17:23 - - aic79xx_osm.c: - aic7xxx_osm.c: - Enable highmem_io on 2.5.X kernels. It turns out that - the CONFIG_HIGHIO option does not exist there. - - Call daemonize() on and provide a name for our dv threads. - - aic79xx_osm.h: - aic7xxx_osm.h: - Include smp_lock.h for (un)lock_kernel(). - - aic7xxx_osm.c: - Add a diagnostic, similar to that in the aic79xx driver, - for printing out sense information. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#101 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#97 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#164 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#112 edit - -Change 1796 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:14:42 - - aic7xxx.c: - Preface the "asserting atn" diagnostic with controller/target - information. - - Restore a call to ahc_assert_atn() that was inadvertantly - lost when the asserting atn diagnostic was added. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#105 edit - -Change 1795 by gibbs@bitkeeper-linux-2.5 on 2002/12/30 12:13:06 - - aic79xx_core.c: - Print out target information to preface the asserting - attention diagnostic. - - Correct a compilation warning. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#148 edit - -Change 1792 by gibbs@bitkeeper-linux-2.5 on 2002/12/20 17:52:04 - - Bump to version 6.2.24. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#111 edit - -Change 1788 by gibbs@aslan on 2002/12/20 16:39:14 - - aic79xx.c: - Remove stray debugging code. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#147 edit - -Change 1787 by scottl@scottl-template on 2002/12/20 16:04:59 - - Update driver version to 1.3.0.ALPHA5 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#96 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#20 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#23 edit - -Change 1786 by gibbs@overdrive on 2002/12/19 16:10:05 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#53 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#34 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#54 edit - -Change 1785 by gibbs@aslan on 2002/12/19 16:08:47 - - aic79xx.c: - Add a statistics timer that decides when to enable - or disable interrupt coalessing based on load. - - Add ahd_flush_qoutfifo() which will run the qoutfifo - as well as complete any commands sitting on the - sequencer's COMPLETE_SCB lists. Use this routine in - several places that did similar things in an add-hoc, - but incomplete, fashion. A call to this routine was - also added to ahd_abort_scbs() to close a race. - - Add a routine, ahd_reset_cmds_pending() which is used - to update the CMDS_PENDING sequencer variable whenever - error recovery compeltes SCBs without notifying the - sequencer. Since ahd_reset_cmds_pending is called - during ahd_unpause() only if we've aborted SCBs, its - call to ahd_flush_qoutfifo should not cause recursion - through ahd_run_qoutfifo(). A panic has been added to - ensure that this recursion does not occur. - - In ahd_search_qinfifo, update the CMDS_PENDING sequencer - variable directly. ahd_search_qinififo can be called - in situations where using ahd_reset_cmds_pending() might - cause recursion. Since we can safely determine the - exact number to reduce CMDS_PENDING by in this scenario - without running the qoutfifo, the manual update is more - than adequate. - - Clean up diagnostics. - - aic79xx.h: - Update per-softc variables for the stats "daemon". - The defaults for interrupt coalessing have been updated - slightly, but these need additional tuning. A new - tunable paramter "minimum commands still outstanding - required to attempt coalessing" has been added. - - Add a debug option for interrupt coalessing activities. - - Add two new softc flags: - o AHD_UPDATE_PEND_CMDS - Run ahd_reset_cmds_pending() on the next unpause. - - o AHD_RUNNING_QOUTFIFO - Used to catch recursion through ahd_run_qoutfifo(). - - aic79xx.reg: - Break INTMASK in SEQITNCTL out into INTMASK1 and INTMASK2. - In at least the REV A, these are writable bits. We make - use of that for a swtimer workaround in the sequencer. - - Add sequencer variables to recovery the min-commands - still outstanding for coalessing and the current number - of commands outstanding. - - Since HS_MAILBOX autoclears, provide a sequencer variable - to store its contents. - - aic79xx.seq: - In idle_loop_cchan, update LOCAL_HS_MAILBOX everytime - we are notified of an HS_MAILBOX update via the - HS_MAILBOX_ACT bit in QOFF_CTLSTA. - - Enhance our coalessing algorithm. If we have more - SCBs to complete to the host (sitting in COMPLETE_SCB - lists), always try to coaless them up to our coalessing - limit. If coalessing is enabled, but we have fewer - commands oustantind than the hosts limit, complete the - command immediately. - - Since we cannot disable the swtimer's countdown, simply - mask its interrupt once we no longer care about it firing. - - Add code to track the number of commands outstanding. - Commands are outstanding from the time they are placed - into the execution queue until the DMA to post completion - is setup. - - Add a workaround for intvec_2 interrupts on the H2A4. - In H2A4, the mode pointer is not saved for intvec2, but - is restored on iret. This can lead to the restoration - of a bogus mode ptr. Manually clear the intmask bits and - do a normal return to compensate. - - aic79xx_inline.h: - Call ahd_reset_cmds_pending() in ahd_unpause if required. - - Update cmdcmplt interrupt statistics in our interrupt - handler. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#146 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#78 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#59 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#77 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#40 edit - -Change 1784 by gibbs@bitkeeper-linux-2.5 on 2002/12/18 10:33:25 - - aic79xx_osm.c: - Remove a stray ';' that was short cicuiting an if statement. - - aic79xx_osm.c: - aic7xxx_osm.c: - aic79xx_osm.h: - aic7xxx_osm.h: - Only allow slave_destroy() to destroy a real device - if that device has had slave_configure() called on it. - This prevents "silly deletions" caused by bogons in - the scsi_scan code from deleting DV state for devices - that are still attached and will have a slave_alloc() - called for them as soon as the slave_destroy() returns. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#100 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#95 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#163 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#110 edit - -Change 1783 by gibbs@bitkeeper-linux-2.5 on 2002/12/18 10:29:46 - - aic7xxx.c: - Don't clobber ppr_options when forcing a renegotiation. - The current ppr_options may be referenced while queuing - new commands. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#104 edit - -Change 1782 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:27:05 - - aic79xx_osm.c: - Add a prototype for ahd_linux_dv_fallback(). - - aic7xxx_osm.c: - Complete the merge of the new biosparam API from - Christoph Hellwig. - - aic79xx_osm.c: - aic7xxx_osm.c: - Move the setting of max_sectors to the host template - to quiet a warning in 2.5.X. - - Add slave_alloc calls and "bootverbose" diagnostics - for help in sorting out exactly how this slave_* - API functions. - - Move call to ahd_linux_device_queue_depth to within - the test to see if dev is NULL. - - Add code to actually destroy our data structures to - the slave_destroy routine instead of waiting for a - command that may not come to do so. - - Initialize the name field of the host structure. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#99 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#162 edit - -Change 1781 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:20:16 - - aic79xx.c: - Remove "Now packetized" diagnostic now that this - information is incorperated into the actual negotiation - messages that are displayed. - - When forcing renegotiation, don't clober the current - ppr_options. Much of the driver uses this information - to determine if we are currently packetized or not. - - Remove some stray spaces at column 1 and ahd_set_tags. - - When complaining about getting a host message loop - request with no pending messages, print out the - SCB_CONTROL register down on the card. - - Modify the ahd_sent_msg() routine to handle a search - for an outgoing identify message. Use this to detect - a msg reject on an identify message which typically - indicates that the target thought we were packetized. - Force a renegotiation in this case. - - In ahd_search_qinfifo(), wait more effectively for SCB - DMA activities to cease. We also clear out the state - that tells the sequencer that a DMA was in progress for - SCB fetch operations since we are about to change the - qinfifo. - - In ahd_pause_and_flush_work(), actually itterate through - the two Complete SCB lists. Ooops. - - In ahd_qinfifo_count(), fix the qinfifo empty case. - - In ahd_dump_card_state(), print out CCSCBCTL in the - correct mode. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#145 edit - -Change 1780 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:11:25 - - aic79xx.seq: - Add a missing ret to the last instruction in - load_overrun_buf. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#76 edit - -Change 1779 by gibbs@bitkeeper-linux-2.5 on 2002/12/17 19:10:42 - - aic79xx.reg: - Correct address for the DFDBCTL register. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#58 edit - -Change 1774 by scottl@scottl-template on 2002/12/16 03:08:08 - - Update driver version to 1.3.0.ALPHA4 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#94 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#19 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#22 edit - -Change 1772 by scottl@scottl-belfalas-template on 2002/12/16 02:43:36 - - ahd_linux_fallback can't aquire the ahd lock since it might be - called from the completion handler. Create a wrapper called - ahd_linux_dv_fallback that aquires and releases the ahd lock so - that is can be called from the DV code and still satisfy it's locking - needs. - Move the error stat code into ahd_linux_queue_cmd_complete so it - can catch more error conditions. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#98 edit - -Change 1771 by scottl@scottl-belfalas-template on 2002/12/16 02:39:22 - - aic79xx_proc.c: - Add a newline when printing the renegotiation pending message. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#11 edit - -Change 1770 by scottl@scottl-belfalas-template on 2002/12/15 23:38:06 - - aic79xx_osm.c: - Don't grab the ahd lock when updating error stats since - it's already held. - When deciding to do a fallback because of an error, don't - alias the existing devinfo struct with a new one. Why - the compiler didn't catch this is beyond me. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#97 edit - -Change 1769 by scottl@scottl-hobbiton-0b47 on 2002/12/15 22:24:16 - - Regen firmware - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#52 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#33 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#53 edit - -Change 1768 by scottl@scottl-hobbiton-0b47 on 2002/12/15 22:24:02 - - aic79xx_osm.c: - aic79xx_osm.h: - Switch to a bucket-based method of counting the number off - good commands in between bad ones. Use only a single bucket - right now for simplicity, though this can grow in the future. - This also removes the stats timer. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#96 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#93 edit - -Change 1767 by scottl@scottl-hobbiton-0b47 on 2002/12/15 21:23:38 - - aic79xx_osm.h: - Move the errors_detected field to the target structure, and - add new_errors_detected field for doing stats decay. - - aic79xx_osm.c: - If a transmission error is detected, increment the - new_errors_detected counter. If it's passed the threshold, - call for a speed fallback. - Update the errors_detected field with new_errors_detected and - reset new_errors_detected on every stats timeout call. - - aic79xx_proc.c: - Display the per-target errors detected field. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#95 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#92 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#10 edit - -Change 1766 by gibbs@aslan on 2002/12/15 19:32:13 - - Add interrupt coalessing hooks. - - aic79xx.c: - Keep a copy of the hs_mailbox in our softc so that - we can perform read/modify/write operations on the - hs_mailbox without having to pause the sequencer to - read the last written value. Use the ENINT_COALESS - flag in the hs_mailbox to toggle interrupt coalessing. - - Add entrypoints for enabling interrupt coalessing and - setting both a timeout (how long to wait for commands - to be coalessed) and a maximum commands to coaless value. - - In ahd_pause_and_flushwork() only return one selections - are safely disabled. We now also flush the two sequencer - lists of completed commands. - - aic79xx.h: - Add coalessing and HS_MAILBOX fields. - - aic79xx.reg: - Correct register addresses related to the software timer. - - Add constants paramaterizing the software timer. - - Add scratch ram locations for storing interrupt coalessing - tunables. - - aic79xx.seq: - Use the software timer and a commands completed count to - implement interrupt coalessing. The command complete is - deferred until either the maximum command threshold or a - timer since the first command completed since the last - completion expires. - - Move the test for the cfg4istat interrupt up an instruction - to hopefully close a race between the next outgoing selection - and our disabling of selections. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#144 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#77 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#57 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#75 edit - -Change 1765 by gibbs@aslan on 2002/12/15 17:48:29 - - aicasm_gram.y: - Allow constants to be complex expressions so long - as those expressions can be fully evaluated during - assembly. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#28 edit - -Change 1764 by scottl@scottl-hobbiton-0b47 on 2002/12/13 18:09:34 - - aic79xx_osm.c: - aic79xx_osm.h: - Start of runtime fallback and interrupt caolescing stat - gathering. Run ahd_linux_stats_update() every - AHD_LINUX_STATS_INTERVAL period. Consense the packetized - and non-packetized autosense code and start some logic to - figure out what to do with the sense information. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#94 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#91 edit - -Change 1762 by gibbs@bitkeeper-linux-2.5 on 2002/12/13 13:08:43 - - aic79xx_osm.c: - aic7xxx_osm.c: - Remove *slave_alloc declarations as we don't need or - export this entry point. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#93 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#161 edit - -Change 1761 by gibbs@bitkeeper-linux-2.4 on 2002/12/12 14:31:11 - - aiclib.h: - Add aic_sector_div macro. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#4 edit - -Change 1760 by gibbs@bitkeeper-linux-2.4 on 2002/12/12 14:30:40 - - aic79xx_osm.h: - aic7xxx_osm.h: - Complete adjustment for host template changes. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#90 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#109 edit - -Change 1759 by gibbs@bitkeeper-linux-2.5 on 2002/12/12 14:25:19 - - aic79xx_osm.h: - Remove a stray reference to aic79xx_host.h. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#89 edit - -Change 1754 by gibbs@bitkeeper-linux-2.4 on 2002/12/12 11:45:59 - - aic79xx_host.h: - aic7xxx_host.h: - aic79xx_osm.c: - aic7xxx_osm.c: - Eliminate separate Linux host template files and move - all host template entry ponts to one section of the Linux - osm.c file. - - aic79xx_osm.c: - aic7xxx_osm.c: - Add support for larger disks under 2.5.X. - - Changes prodded by: Christoph Hellwig - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#14 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#92 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#18 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#16 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#160 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#41 edit - -Change 1751 by scottl@scottl-template on 2002/12/10 21:41:30 - - Update driver version to 6.2.23 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#108 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#9 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#12 edit - -Change 1750 by gibbs@bitkeeper-linux-2.4 on 2002/12/10 20:51:23 - - aic79xx_host.h: - aic7xxx_host.h: - Set single_sg_okay for RH AS 2.1 too. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#15 edit - -Change 1749 by gibbs@bitkeeper-linux-2.4 on 2002/12/10 20:45:35 - - aic79xx_host.h: - aic7xxx_host.h: - Use CONFIG_HIGHIO as the gating define for whether - the highmem_io host template field is present. Also - assume that if the kernel version is less than 2.4.18, - then we must be under RedHat and need to call this field - can_dma_32. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#14 edit - -Change 1748 by scottl@scottl-template on 2002/12/10 19:54:55 - - Update driver version to 1.3.0.ALPHA3 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#88 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#18 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#20 edit - -Change 1747 by gibbs@bitkeeper-linux-2.4 on 2002/12/10 18:49:21 - - aic79xx_host.h: - aic7xxx_host.h: - Enable the highmem_io option on kernels with the - new highmem bouncing code. - - aic79xx_osm.c: - aic7xxx_osm.c: - Fix compilation error in the non-debug enabled case. - - aic7xxx_osm.c: - Remove leftover #if 0'd code from DV merge. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#91 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#159 edit - -Change 1746 by gibbs@bitkeeper-linux-2.5 on 2002/12/10 12:05:15 - - aic79xx_osm.c: - aic7xxx_osm.c: - Disable the shutdown hook for 2.5.X since it is called - to early to be useful. Some other strategy will need to - be found. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#90 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#158 edit - -Change 1745 by gibbs@bitkeeper-linux-2.5 on 2002/12/09 16:29:02 - - aic79xx_host.h: - aic79xx_osm.c: - aic79xx_osm_pci.c - aic7xxx_host.h: - aic7xxx_osm.c: - aic7xxx_osm_pci.c: - Conform to latest 2.5.X API changes. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#89 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#157 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#40 edit - -Change 1743 by gibbs@bitkeeper-linux-2.4 on 2002/12/09 15:16:31 - - aic79xx.c: - Limit the syncrate after all option conformance - changes have taken place in ahd_devlimited_syncrate. - Changes in options may change the final syncrate we - accept. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#143 edit - -Change 1741 by gibbs@bitkeeper-linux-2.4 on 2002/12/09 14:11:44 - - Makefile: - Turn off -g. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#10 edit - -Change 1740 by scottl@scottl-template on 2002/12/09 10:15:50 - - Update driver version to 6.2.22 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#107 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#8 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#11 edit - -Change 1737 by scottl@scottl-template on 2002/12/06 16:14:24 - - Update driver version to 1.3.0.ALPHA2 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#87 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#17 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#19 edit - -Change 1736 by gibbs@overdrive on 2002/12/06 16:04:51 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#51 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#32 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#52 edit - -Change 1735 by gibbs@bitkeeper-linux-2.4 on 2002/12/06 16:03:54 - - aic79xx.h: - Use consistent names for AH?_ASYNC_XFER_PERIOD. - - aic79xx.c: - aic79xx_proc.c: - Print out IU, QAS, and RTI features when showing - transfer options. - - aic79xx.c: - Save and restore the NEGOADDR address when setting - new transfer settings. The sequencer performs lookups - in the negotiation table too and it expects NEGOADDR - to remain consistent across pause/unpause sessions. - - Consistently use "offset" instead of "period" to determine - if we are running sync or not. - - Add a SHOW_MESSAGES diagnostic for when we assert ATN - during message processing. - - aic79xx_osm.c: - aic7xxx_osm.c: - In ah?_devlimited_syncrate enforce that we can never - attempt DT transfers if we are narrow. - - Remove the ALLOW_MEMIO config option. - - Modify ah?_linux_filter_inquiry to assume that the - inquiry buffer is large enough and has been setup - correctly (i.e. memset to 0 prior to command issue) - so that range checks are unecessary. - - Remove comments about the need to perform short inquiry - requests. The code does this now. - - Split out the bottom half handling of DV inquiry results - to make the code clearer. - - Re-arrange the DV state machine so that: - - o REB descriptor fetching is performed ASYNC so we - don't confuse a failure with the need to fallback. - o Devices using Level 2 DV don't bother with Level 1 - DV. - o REB collisions are retried after a delay randomized - by our ID on the bus. - o Level 2 DV is only attempted on devices that support - DT transfers. - - Fix ah?_linux_fallback to always favor the fastest - speed during fallback and to favor sync over async speeds. - - Don't let a target reponding to a PPR message with 0 - options set fool us into falling back to far. We still - must try to negotiate without using PPR to get by some - expanders. - - Use the SCB_SILENT flag on DV commands. - with 0 PPR options set - - Fix large inquiry size calculation. It was off by one. - We need to add 5 and not 4. - - aic79xx_osm_pci.c: - Tell the user that our failure of the MMAP test is non - fatal. We're just dropping back to PIO. - - aiclib.c: - aiclib.h: - Add flags for a randomized delay in response to an error. - - Include table entries for REB collisions. - - Add the proper response codes for sense codes indicating - inquiry data has changed. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#142 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#76 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#103 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#66 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#88 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#86 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#16 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#156 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#106 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#39 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#3 edit - -Change 1734 by gibbs@bitkeeper-linux-2.4 on 2002/12/06 15:49:37 - - Config.in: - With the advent of our command line option and the - new memory mapped register test, there is no need - for a kernel compile time option to allow memory - mapped I/O. Remove it. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#10 edit - -Change 1733 by gibbs@bitkeeper-linux-2.4 on 2002/12/06 15:31:31 - - aic79xx.seq: - Correct ignore wide residue processing check for - a wide negotiation being in effect. We must be - in the SCSI register window in order to access the - negotiation table. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#74 edit - -Change 1732 by gibbs@aslan on 2002/12/06 15:14:01 - - aicasm_gram.y: - Add two missing ';'s that for some reason yacc/bison - never complained about as a syntax error. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#27 edit - -Change 1730 by cde@haywire on 2002/12/05 17:55:31 - - Add AHD_DV_STATE_INQ_SHORT_ASYNC to probe inquiry buff len - - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#87 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#85 edit - -Change 1729 by gibbs@aslan on 2002/12/05 17:23:45 - - aic7xxx.h: - AHD -> AHC. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#65 edit - -Change 1728 by gibbs@aslan on 2002/12/05 17:21:45 - - aic79xx.c: - aic79xx.h: - aic7xxx.c: - aic7xxx.h: - Cleanup usage of the SCB_SILENT flag by using - a new macro SCB_IS_SILENT(scb). - - Apply the silent treatment to outgoing LQ CRC - errors. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#141 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#75 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#102 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#64 edit - -Change 1727 by gibbs@aslan on 2002/12/05 17:01:15 - - aic79xx.c - aic7xxx.c: - aic79xx.h: - aic7xxx.h: - Implement the SCB_SILENT flag. This is useful for - hushing up the driver during DV or other operations - that we expect to cause transmission errors. The - messages will still print if the SHOW_MASKED_ERRORS - debug option is enabled. - - aic7xxx_inline.h: - aic7xxx_pci.c: - Implement ahc_[in|out][w|l|q]. This removes the need - for manual 'or and shift" type operations through out - the driver. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#140 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#74 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#101 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#63 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#39 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#54 edit - -Change 1726 by gibbs@overdrive on 2002/12/04 17:33:18 - - Regenerate Linux firmware - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#20 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#21 edit - -Change 1725 by gibbs@aslan on 2002/12/04 17:32:26 - - aic7xxx.reg: - Add a definition for MAX_OFFSET. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#36 edit - -Change 1724 by gibbs@overdrive on 2002/12/04 16:35:11 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#50 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#31 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#51 edit - -Change 1723 by gibbs@aslan on 2002/12/04 16:34:34 - - aic79xx.seq: - The sequencer downloading code assumes that all jump - labels are acurate in relation to a fully compiled - sequencer program (all patches downloaded). Correct - a few occurances of a relative jump across a macro - that ended up jumping us into the last instruction - of the macro. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#73 edit - -Change 1722 by scottl@scottl-via-freebsd on 2002/12/04 15:40:08 - - ahd_pci.c: - Add a newline to the MEMIO printf. - - aic79xx_pci.c: - Set the mode correctly for writing to SRAM_BASE in the MEMIO - test. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#60 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#11 edit - -Change 1721 by scottl@scottl-junior-freebsd on 2002/12/04 14:49:34 - - aic79xx_pci.c: - Use SRAM and the 0xaa55 pattern for the MEMIO test. - - ahd_pci.c: - Go along with ahc_pci.c and retrieve the allow_memio hint - from the resource manager and act on it. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#59 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#10 edit - -Change 1719 by gibbs@bitkeeper-linux-2.4 on 2002/12/03 17:04:22 - - aic79xx_pci.c: - Don't attempt to set reserved bits in memio test. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#58 edit - -Change 1718 by gibbs@overdrive on 2002/12/03 16:16:46 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#49 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#30 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#50 edit - -Change 1717 by gibbs@scottl-via-freebsd on 2002/12/03 15:29:57 - - aic79xx_pci.c: - Use the TYPEPTR register as a base for our - memory mapped I/O test. The Rev B. will allow - multi-byte access to Scratch Ram, so it is not - a good test of write-combining or other bad - behavior. - - User CLRPCIINT and CLRSPLTINT in their respective - handlers. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#57 edit - -Change 1716 by gibbs@scottl-via-freebsd on 2002/12/03 15:27:24 - - aic79xx.reg: - Correct the location of the TARGPCISTAT register. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#56 edit - -Change 1715 by gibbs@aslan on 2002/12/03 10:34:23 - - aic79xx_pci.c: - Revamp memory mapped I/O test to match the algorithm - used in the aic7xxx driver. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#56 edit - -Change 1714 by scottl@scottl-via-freebsd on 2002/12/02 19:12:42 - - aic7xxx_pci.c: - In the memio test, clear the FAILDIS bit of the SEQCTL - before running the tests so that PCI errors will be - flagged. - - Write only 4 bytes to the SRAM to prevent VIA chipsets - from generating a burst transaction on the bus. - - Clear the PCIR_STATUS register and restore the SEQCTL - register before exiting. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#53 edit - -Change 1713 by gibbs@aslan on 2002/12/02 13:04:29 - - aic79xx_pci.c: - Properly report the aic7901A as an aic7901A. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#55 edit - -Change 1710 by scottl@scottl-junior-freebsd on 2002/11/27 02:05:18 - - Fix a spelling mistake and a whitespace goof. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#52 edit - -Change 1709 by scottl@scottl-junior-freebsd on 2002/11/26 22:12:00 - - Strip down the $FreeBSD$ - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 edit - -Change 1708 by scottl@scottl-junior-freebsd on 2002/11/26 21:56:03 - - Revert whitespace changes in ahc_syncrates[] to reduce diffs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#100 edit - -Change 1699 by gibbs@bitkeeper-linux-2.4 on 2002/11/20 14:14:13 - - aic79xx_osm_pci.c: - aic7xxx_osm_pci.c: - Make use of the new Core PCI routine for testing memory - mapped register access. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#15 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#38 edit - -Change 1698 by gibbs@bitkeeper-linux-2.4 on 2002/11/20 14:13:40 - - aic79xx_osm.c: - aic7xxx_osm.c: - Make the "ALLOW_MEMIO" config option actually work for - the "disabled" case. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#86 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#155 edit - -Change 1697 by gibbs@bitkeeper-linux-2.4 on 2002/11/20 14:12:43 - - aic79xx.h: - aic79xx_pci.c: - aic7xxx.h: - aic7xxx_pci.c: - Add a routine for testing memory mapped register access. - This will hopefully detect things like buggy via chipsets - so that the OSM can fallback to using I/O mapped access - when memory mapped I/O simply will not work. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#73 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#54 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#62 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#51 edit - -Change 1696 by gibbs@bitkeeper-linux-2.5 on 2002/11/19 11:43:33 - - aiclib.h: - Don't include the definition for REPORT_LUNS. It conflicts - with the native Linux definition. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#2 edit - -Change 1695 by scottl@scottl-template on 2002/11/18 16:45:04 - - Update driver version to 1.3.0.ALPHA1 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#84 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#16 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#18 edit - -Change 1690 by scottl@scottl-template on 2002/11/14 18:31:41 - - Fix type from previous commit - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#154 edit - -Change 1689 by scottl@scottl-template on 2002/11/14 18:26:58 - - Update driver version to 6.2.21 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#105 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#7 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#10 edit - -Change 1688 by scottl@scottl-template on 2002/11/14 17:38:10 - - Update driver version to 1.2.0 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#83 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#14 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#17 edit - -Change 1687 by scottl@scottl-template on 2002/11/14 17:36:51 - - Remove the previous change for falling back in narrow. It doesn't - seem to work. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#85 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#153 edit - -Change 1686 by scottl@scottl-template on 2002/11/14 12:40:42 - - Update driver version to 1.1.14 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#82 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#13 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#16 edit - -Change 1685 by scottl@scottl-template on 2002/11/14 12:40:17 - - aic79xx_osm.c - aic7xxx_osm.c - Add a minimum bus settle delay after doing a bus reset from - the DV timeout handler. - - Limit the max period allowed for narrow when figuring out - the narrow fallback speed. - - aic7xxx.h - Add AHD_ULTRA2_XFER_PERIOD for narrow fallback calculations - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#61 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#84 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#152 edit - -Change 1683 by scottl@scottl-template on 2002/11/13 20:49:54 - - Update driver version to 1.1.13 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#81 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#12 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#15 edit - -Change 1680 by gibbs@vas2209a on 2002/11/13 19:08:38 - - aic7xxx_osm.c: - Use ahc_set_tags rather than ahc_platform_set_tags so - that the core can be appraised of any tag type or depth - changes. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#151 edit - -Change 1679 by gibbs@vas2209a on 2002/11/13 19:03:23 - - aic7xxx_osm.c: - Add a back in a missing ahc_done_unlock() that was - lost in the last change. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#150 edit - -Change 1678 by gibbs@bitkeeper-linux-2.5 on 2002/11/13 18:26:28 - - aic79xx_osm.c: - aic7xxx_osm.c: - Requeue deferred command completions so that when the - timer does expire the entries are actually sent. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#83 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#149 edit - -Change 1676 by gibbs@bitkeeper-linux-2.5 on 2002/11/13 16:26:07 - - aic79xx_osm.c: - aic7xxx_osm.c: - Move a FALLTHROUGH label to the correct - location in the code. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#82 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#148 edit - -Change 1675 by gibbs@vas2209a on 2002/11/13 15:43:19 - - aic79xx.c: - Set WIDERESEN for Rev B which ensures that an - expected wide residue does not prevent the - FIFO from reporting FIFOEMP. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#139 edit - -Change 1674 by gibbs@vas2209a on 2002/11/13 14:27:15 - - aic79xx_host.h: - aic79xx_osm.c: - aic7xxx_osm.c: - Correct a few minor compile issues that fell out of - the port to 2.5.X. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#81 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#147 edit - -Change 1673 by gibbs@bitkeeper-linux-2.5 on 2002/11/13 13:43:15 - - aic79xx_host.h: - aic79xx_osm.c: - aic79xx_osm.h: - aic7xxx_host.h: - aic7xxx_osm.c: - aic7xxx_osm.h: - Complete the port to Linux 2.5.X. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#80 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#80 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#146 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#104 edit - -Change 1672 by gibbs@bitkeeper-linux-2.4 on 2002/11/13 13:02:15 - - aic79xx_osm.c: - aic7xxx_osm.c: - Remove fallback from the Read Echo Buffer Descriptor - DV state. This avoids issues with tape drives that - just hang if you issue the command. We should really - be issuing the command async, but that is too complicated - a fix for PH1.2. Defer that fix to PH1.3. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#79 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#145 edit - -Change 1671 by gibbs@aslan on 2002/11/13 12:10:23 - - aic79xx.c: - Correct code that restore the STACK. It was - always placing a 0 in the high byte of the stack - address. - - aic7xxx.c: - Remove unecessary restoration of the STACK for older - chips. - - aic7xxx.h: - aic79xx.h: - Collapse SCB flag entries so they are bit contiguous. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#138 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#72 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#99 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#60 edit - -Change 1670 by gibbs@bitkeeper-linux-2.4 on 2002/11/13 11:46:51 - - aic79xx_osm.c: - aic7xxx_osm.c: - To avoid stack explosion in the mid-layer, only complete - AH?_LINUX_MAX_RETURNED_ERRORS commands that have errors - at a time. Any deferred entries will be returned via - a timer that runs the queue. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#78 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#144 edit - -Change 1669 by gibbs@vas2209a on 2002/11/13 00:14:42 - - aic79xx_osm.c: - aic79xx_osm.h: - aic7xxx_osm.c: - aic7xxx_osm.h: - Don't allow the eh_sem to be up'ed twice in the - case of the eh timer expiring and the command completing - due to a future recovery action such as a bus reset. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#77 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#79 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#143 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#103 edit - -Change 1668 by gibbs@vas2209a on 2002/11/13 00:01:03 - - aic79xx.c: - Add DFFSTAT in mode 3 to ahd_dump_card_state(). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#137 edit - -Change 1667 by gibbs@overdrive on 2002/11/12 23:57:48 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#48 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#29 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#49 edit - -Change 1666 by gibbs@aslan on 2002/11/12 23:55:24 - - aic79xx.reg: - aic79xx.seq: - Workaround Rev B issue with CURRFIFO_0 having the - same value in "enhanced mode" as "standard mode" - for "writes". Reads of the register behave as - expected. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#55 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#72 edit - -Change 1662 by gibbs@overdrive on 2002/11/12 14:59:39 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#47 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#28 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#48 edit - -Change 1661 by gibbs@vas2209a on 2002/11/12 14:58:23 - - aicasm_gram.y: - Use a direct move from allzeros to emulate a - mvi of 0. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#26 edit - -Change 1660 by gibbs@vas2209a on 2002/11/12 10:33:25 - - aic7xxx.h: - Add a missing typedef. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#59 edit - -Change 1659 by gibbs@overdrive on 2002/11/11 23:37:31 - - Regenerate Linux Firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#46 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#27 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#47 edit - -Change 1658 by gibbs@overdrive on 2002/11/11 23:35:30 - - aic79xx_pci.c: - Set the PREQDIS bit in DEVCONFIG1 for the B. The - bit is misnamed, but seems to disable a work-around - that breaks on the B on PCI busses. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#53 edit - -Change 1657 by gibbs@overdrive on 2002/11/11 23:34:43 - - aic79xx.seq: - Return to the SCSI mode prior to re-allocating a FIFO. - The alloc-FIFO routine assume we are in the SCSI mode. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#71 edit - -Change 1656 by gibbs@bitkeeper-linux-2.4 on 2002/11/11 15:37:54 - - aic79xx.c: - Printout the SAVED_MODE scratch ram location in ahd_dump_card_state. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#136 edit - -Change 1655 by gibbs@bitkeeper-linux-2.4 on 2002/11/11 14:22:01 - - aic79xx_osm.c: - aic79xx_osm.h - aic7xxx_osm.c: - aic7xxx_osm.h - Add a timer for deferred running of the completion - queue. We use this to return commands back to the OS - when our queue is frozen that happen to arrive before - Linux sees that our host queue is blocked. This avoids - a deadlock issue that occurs should we attempt to simply - scsi_done the command immediately. This strategy also - guarantees that the commands are returned almost imediately - instead of having to wait for either a DV command or simq - release to occur. - - Add the ability to reset a command's timeout from within - the core. We use this to give RequestSense operations - a new timer. - - Always perform DV thread operations while our ah?_lock - is held. - - aic79xx.c: - aic7xxx.c: - Make use of the new ah?_scb_timer_reset() api. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#135 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#98 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#76 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#78 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#142 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#102 edit - -Change 1654 by scottl@scottl-belfalas-rh72as on 2002/11/08 19:15:45 - - aic79xx_osm.c: - Remove unused variable. - - Move ahd_linux_thread_run_complete_queue() to its - proper location in the file. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#75 edit - -Change 1653 by scottl@scottl-belfalas-rh72as on 2002/11/08 19:10:04 - - aic79xx_osm.c: - Fix deadlock in ahd_linux_queue() when we want to - return a command immediately to the system because - our queue is blocked. We now defer the return of - the command until either the simq is released or - the dv thread has an oportunity to flush the queue. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#74 edit - -Change 1652 by scottl@scottl-template on 2002/11/07 23:34:47 - - Update driver version to 6.2.20 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#101 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#6 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#8 edit - -Change 1650 by gibbs@aslan on 2002/11/07 13:55:31 - - aic79xx.c: - Avoid infinite loop in restoration of STACK contents - in ahd_dump_card_state(). Our interrator must be - signed. - - aic79xx.c: - aic7xxx.c: - Remove a diagnostic printf. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#134 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#97 edit - -Change 1649 by gibbs@bitkeeper-linux-2.4 on 2002/11/07 13:33:07 - - aic79xx.c: - Workaround printf format and integer sizing issues. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#133 edit - -Change 1648 by gibbs@bitkeeper-linux-2.4 on 2002/11/07 13:23:23 - - aic79xx.c: - Remove extraineous include of stdint.h. The OSM - header file should be doing this. - - Remove unused variable warnings for debuging code. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#132 edit - -Change 1647 by gibbs@bitkeeper-linux-2.4 on 2002/11/07 13:19:35 - - aic79xx_osm.c: - aic7xxx_osm.c: - Mark devices as "configured" once the OS calls - select queue_depths. This is required now that we - are no longer sniffing all inquiry cmds that the - OS performs. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#73 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#141 edit - -Change 1646 by scottl@scottl-template on 2002/11/06 23:07:03 - - Update driver version to 1.1.12 - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#131 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#77 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#11 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#12 edit - -Change 1645 by scottl@scottl-template on 2002/11/06 23:05:33 - - Follow the aic79xx driver and extend the timeout amount when - debug printing is enabled. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#140 edit - -Change 1644 by gibbs@bitkeeper-linux-2.4 on 2002/11/06 11:03:48 - - aic79xx_osm.c: - Be even more pessimistic about how long negotiation - messages take by bumping up the DV timeout a whole - 1 second should negotiation debugging be enabled. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#72 edit - -Change 1643 by scottl@scottl-template on 2002/11/05 23:40:18 - - Update driver version to 6.2.19 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#100 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#5 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#7 edit - -Change 1642 by scottl@scottl-template on 2002/11/05 17:58:47 - - Update driver version to 1.1.11 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#76 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#10 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#11 edit - -Change 1641 by gibbs@bitkeeper-linux-2.4 on 2002/11/05 16:33:24 - - aic79xx_osm.c: - aic7xxx_osm.c: - Not all Linux kernel versions honor the return value - from the queue_command driver entry point. To deal with - these older kernels, always return "rejected" commands - via the scsi_done handler. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#71 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#139 edit - -Change 1640 by gibbs@bitkeeper-linux-2.4 on 2002/11/05 15:33:08 - - aic79xx_osm.c: - aic7xxx_osm.c: - Avoid taking the io_request lock twice. This is a - regression from our port to 2.5.X. - - aic79xx_osm.c: - Put some more diagnostics under AHD_SHOW_RECOVERY. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#70 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#138 edit - -Change 1639 by gibbs@aslan on 2002/11/05 13:13:20 - - aic79xx.c: - aic79xx.h: - aic7xxx.c: - aic7xxx.h: - Save and restore stack contents during diagnostics. - Some chip variants overwrite stale entries on a - stack "pop". - - Don't use 0 to probe the stack depth. 0 is the typical - value used to backfill the stack if entries are overwritten - on a "pop". - - aic79xx.c: - aic79xx.h: - Add the AHD_SHOW_RECOVERY debug option and use it to - control some diagnostic messages related to error recovery. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#130 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#71 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#96 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#58 edit - -Change 1638 by scottl@scottl-template on 2002/11/01 18:16:08 - - Update driver version to 1.1.10 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#75 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#9 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#10 edit - -Change 1637 by gibbs@overdrive on 2002/11/01 17:17:04 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#45 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#26 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#46 edit - -Change 1636 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:14:53 - - cam.h: - Add CAM_DEVQ_FROZEN to the cam_status enum. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#15 edit - -Change 1635 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:14:34 - - Make "empty_string" static so it can be included in both the - aic7xxx and the aic79xx drivers. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#3 edit - -Change 1634 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:14:08 - - aic7xxx.c: - aic7xxx.h: - Just for safety, have the aic7xxx driver probe - the stack depth too. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#95 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#57 edit - -Change 1633 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:13:33 - - aic79xx_osm.c: - Correct a compile error. The updated handling of - CAM_CMD_TIMEOUT was placed in the wrong routine. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#69 edit - -Change 1632 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:12:22 - - aic79xx.seq: - Revert de-optimization in the fifo polling loop. - Our problem was caused by the larger stack size on - Rev B. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#70 edit - -Change 1631 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 17:11:33 - - aic79xx.c: - Move ahd_probe_stack_size() so it matches the location - of its declaration. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#129 edit - -Change 1630 by gibbs@bitkeeper-linux-2.4 on 2002/11/01 16:19:58 - - aic79xx_osm.c: - aic79xx_osm.h: - aic7xxx_osm.c: - aic7xxx_osm.h: - Actually freeze the device queue in response to a request - to do so from the Core. This closes a race in the case - of things like QUEUE FULL or BUSY handling where the - OSM may be able to queue additional commands prior to - seeing the SCB that should have frozen or otherwise altered - the execution queue. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#68 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#74 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#137 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#99 edit - -Change 1629 by gibbs@overdrive on 2002/11/01 16:17:55 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#44 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#25 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#45 edit - -Change 1628 by gibbs@aslan on 2002/11/01 16:11:16 - - aic79xx.c: - aic79xx.h: - aic79xx.reg: - Add a routine to dynamically determine the size - of the sequencer stack. It turns out that RevB - has a 9 entry stack rather than the 8 entry stack - of the A4. Determining the stack depth programatically - should protect us from any future changes in this area. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#128 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#70 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#54 edit - -Change 1626 by scottl@scottl-template on 2002/10/31 16:38:49 - - Update driver version to 1.1.9 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#73 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#8 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#9 edit - -Change 1625 by scottl@scottl-template on 2002/10/31 15:47:57 - - Update driver version to 6.2.18 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#98 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#4 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#6 edit - -Change 1623 by scottl@scottl-template on 2002/10/31 14:47:46 - - Define SCSI_NOSENSE_STRINGS to elimiate the asc/ascq description - strings. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#2 edit - -Change 1622 by scottl@scottl-template on 2002/10/31 14:44:19 - - Don't lock the io_request_lock until after calling - ahd_linux_register_host(). - Release the ahd lock when calling kernel_thread() - - This fixes a deadlock when launching the DV thread in - older 2.4 SMP kernels. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#136 edit - -Change 1621 by scottl@scottl-template on 2002/10/31 14:17:54 - - Don't lock the io_request_lock until after calling - ahd_linux_register_host(). - Release the ahd lock when calling kernel_thread() - - This fixes a deadlock when launching the DV thread in - older 2.4 kernels. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#67 edit - -Change 1618 by scottl@scottl-template on 2002/10/30 19:48:52 - - Update driver version to 1.1.8 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#72 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/aic79xx.spec#7 edit -... //depot/linux_mod_devel/scsi.aic79xx/rpm/install.sh#8 edit - -Change 1616 by scottl@scottl-template on 2002/10/30 19:05:51 - - Update driver version to 6.2.17 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#97 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/aic7xxx.spec#3 edit -... //depot/linux_mod_devel/scsi.aic7xxx/rpm/install.sh#3 edit - -Change 1615 by gibbs@overdrive on 2002/10/30 18:35:23 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#43 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#44 edit - -Change 1614 by gibbs@aslan on 2002/10/30 18:34:26 - - aic79xx.seq: - Rearrange idle_loop_service_fifo: I have a hunch - that the sequencer does not like the optimized version - of this routine should we be paused at the start of - a longjmp handler. We now change this to look just - as it did in PH 1.1. - - Clear the longjmp address of the p_data handler just - after we call disable_ccsgen. Otherwise the longjmp - handler may not be deregistered until an extra call - into the handler or a new handler is installed. The - first behavior might be dangerous if the FIFO is not - active. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#69 edit - -Change 1613 by gibbs@overdrive on 2002/10/30 16:52:10 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#42 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#23 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#43 edit - -Change 1612 by gibbs@aslan on 2002/10/30 16:50:11 - - aic79xx.seq: - Test for SCSIPERR instead of relying on SCSIPHASE - not setting on a SCSI parity error. It seems that - this is not the case and that we occassionally coast - out of routines like phase_lock when a parity error - is pending. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#68 edit - -Change 1611 by gibbs@aslan on 2002/10/30 12:55:46 - - aic7770.c: - Add IDs for some Olivetti OEM aic7770 based cards. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#27 edit - -Change 1610 by gibbs@bitkeeper-linux-2.4 on 2002/10/30 12:27:14 - - aic7xxx.c: - Don't disable ENBUSFREE when single stepping on - a DT capable controller. We cannot re-enable unexpected - busfree detection, so we must clear BUSFREE on each - step instead. - - Correct the lookup of the SCB ID in ahc_handle_proto_error. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#94 edit - -Change 1609 by gibbs@aslan on 2002/10/30 12:25:51 - - aic79xx.h: - Remove redundant declaration of ahd_print_devinfo(). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#69 edit - -Change 1608 by gibbs@bitkeeper-linux-2.4 on 2002/10/30 11:38:28 - - aic7xxx_osm.c: - Bring in DV state machine enhancements from the U320 - driver. - - aic79xx_osm.c: - Remove a left over diagnostic. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#66 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#135 edit - -Change 1607 by gibbs@bitkeeper-linux-2.4 on 2002/10/30 10:13:52 - - Pull DV branch into the mainline. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#127 integrate -... //depot/aic7xxx/aic7xxx/aic79xx.h#68 integrate -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#39 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx.c#93 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx.h#56 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#65 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#71 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#8 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#134 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#96 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#23 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.c#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aiclib.h#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#14 integrate - -Change 1604 by gibbs@overdrive on 2002/10/29 18:59:13 - - aic79xx_osm.c: - Correct module description to properly identify the - driver as AIC79XX. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#64 edit - -Change 1597 by gibbs@overdrive on 2002/10/29 14:09:41 - - aic79xx_osm_pci.c: - Remove redundant check for PCI-X controller. The bug - flag should be enough. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#14 edit - -Change 1596 by gibbs@overdrive on 2002/10/29 14:09:13 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#41 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#22 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#42 edit - -Change 1592 by gibbs@aslan on 2002/10/29 11:05:58 - - Implement work around for the Interrupt collission problem - on the 7902B. - - aic79xx.c: - When a sequencer interrupt occurs on the B, unpause - the sequencer and allow it to clear SEQINTCODE with - a second SEQINT prior to processing the "real" seqint. - This clears SEQINTCODE without requiring an extra - interrupt. - - Convert the SAW_HWERR sequencer interrupt into a - call to ahd_handle_hwerrint(). - - aic79xx.h: - Add AHD_INTCOLLISION_BUG. - - Add NO_SEQINT, which is the special value that we - use to initialize SEQINTCODE so that the host can - tell if there is a real SEQINT pending. - - aic79xx.reg: - Add SET_SEQINTCODE() macro to special case sequencer - interrupt processing based on AHD_INTCOLLISION_BUG. - - aic79xx.seq - Whenever the sequencer is restarted, insure that - SEQINTCODE is properly initialized. - - Convert a non-zero ERROR status to a SAW_HWERR - sequencer interrupt. - - Add set_seqint_work_around which will clear SEQINTCODE - after every SEQINT. - - Use SET_SEQINTCODE throughout the firmware. - - aic79xx_inline.h: - Use a read of HCNTRL to flush our write to CLRCMDCMPLT - on the RevB. This allows us to check to see if the sequencer - is paused and to initiate the interrupt collision workaround - without incuring an extra read. - - aic79xx_pci_c: - Set AHD_INTCOLLISIONT_BUG for the Rev B. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#126 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#67 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#53 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#67 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#38 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#52 edit - -Change 1590 by gibbs@overdrive on 2002/10/28 18:12:32 - - Regernerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#40 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#41 edit - -Change 1588 by gibbs@aslan on 2002/10/28 14:39:15 - - aic79xx_inline.h: - Add our controller name to the front of our - diagnostic "Setting Mode" messages. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#37 edit - -Change 1587 by gibbs@aslan on 2002/10/28 14:38:45 - - aic79xx.c: - aic79xx.reg: - Some 160 devices incorrectly accept 0xfe as a - sync offset, but will overrun this value. Limit - to 0x7f for speeds lower than U320 which will - avoid the persistent sync offset overruns. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#125 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#52 edit - -Change 1574 by gibbs@overdrive on 2002/10/26 20:42:36 - - aic7xxx_osm.c: - Add "paused = TRUE" in ahc_queue_recovery_cmd which - was lost in the conversion to use ahc_pause_and_flush_work(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#133 edit - -Change 1572 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/26 01:10:28 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#70 edit - -Change 1570 by gibbs@aslan on 2002/10/25 23:53:19 - - aic79xx_pci.c: - Remove stray/random extra 7901A generic PCI - table entry. Also switch the correct 7901A - generic entry to use ID_ALL_MASK since we - can only differentiate the 7901A from the - 7902 by checking for a "type field" of 0xE. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#51 edit - -Change 1565 by gibbs@overdrive on 2002/10/25 20:45:29 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#39 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#20 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#40 edit - -Change 1564 by gibbs@aslan on 2002/10/25 20:44:25 - - aic79xx.h: - Add "feature" AHD_NEW_DFCNTRL_OPTS for SCSIENWRDIS. - - aic79xx.reg: - Add the SCSNENWRDIS field and the PLLDELAY register - definitions. - - aic79xx.seq: - Use SCSIENWRDIS when setting PRELOADEN on all - SG element writes save the first one on chips - that support this feature so that SCSIEN does - not get corrupted. - - Correct a bug in the legacy bitbucket handler. - We must save and restore our mode pointer now - that we can be using both FIFOs. - - aic79xx_pci.c: - PREQDIS in DEVCONFIG1 went away after the A2. - Remove all code that references this bit. This - is especially important since this bit was reused - in the B for a different HW fix workaround. - - Properly set the AHD_NEW_IOCELL_OPTS and - AHD_NEW_DFCNTRL_OPTS features for the B. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#66 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#51 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#66 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#50 edit - -Change 1540 by gibbs@bitkeeper-linux-2.4 on 2002/10/23 12:53:14 - - Make it possible for both the aic7xxx and the aic79xx driver - to rely on scsi_all.c yet still be built into the same kernel. - Since we can't use a module dependency to have a "library module", - symbols are renamed and the code included in each driver. - -Affected files ... - -... //depot/aic7xxx-dv/aic7xxx/aic79xx.c#8 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#9 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#8 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#3 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#30 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#13 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#3 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/cam.c#2 delete -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/cam.h#4 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/scsi_all.c#2 edit -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/scsi_all.h#2 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#9 edit - -Change 1538 by gibbs@aslan on 2002/10/22 21:45:34 - - aic79xx.c: - Modify use_ppr handling in ahd_build_transfer_message - to match the aic7xxx driver. - - aic7xxx.c: - Move a comment and remove a useless clearing of use_ppr. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#124 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#92 edit - -Change 1537 by gibbs@aslan on 2002/10/22 21:38:02 - - aic7xxx.c: - Bring back "use_ppr". We need to use_ppr anytime - doppr is true or we have non-zero protocol options. - The later case was not handled in the recent removal - of use_ppr. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#91 edit - -Change 1528 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/22 12:00:33 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#69 edit - -Change 1526 by gibbs@bitkeeper-linux-2.4 on 2002/10/22 11:54:03 - - Integrate from Head into aic7xxx-dv. - -Affected files ... - -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#6 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#6 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#6 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#3 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#3 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#8 edit - -Change 1525 by gibbs@overdrive on 2002/10/22 11:53:24 - - Regerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#38 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#39 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#20 edit - -Change 1520 by gibbs@aslan on 2002/10/21 20:40:11 - - aic7xxx.c: - Add a newline to ahc_dump_card_state() output. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#90 edit - -Change 1519 by gibbs@aslan on 2002/10/21 20:39:23 - - aic7xxx.c: - Update ahc_reg_print() to handle a NULL cur_col. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#89 edit - -Change 1518 by gibbs@aslan on 2002/10/21 20:37:24 - - aic7xxx.c: - Add additional diagnostic output to ahc_dump_card_state(), - and have it use the register pretty printing functions. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#88 edit - -Change 1517 by gibbs@aslan on 2002/10/21 16:30:21 - - aic7xxx.seq: - Move data fifo CLRCHN to mesgin_rdptrs which is a safer - location for doing this operation. This also saves a - sequencer instruction. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#52 edit - -Change 1516 by gibbs@aslan on 2002/10/21 16:18:49 - - aic79xx.seq: - Clarify a comment in the mesgin_rdptrs handler. - We need to clear the data fifo for CMD retries too. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#65 edit - -Change 1515 by gibbs@overdrive on 2002/10/21 16:06:12 - - aic7xxx_osm.c: - Adapt to conversion from IDENTIFY_SEEN to NO_IDENTIFIED. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#132 edit - -Change 1514 by gibbs@aslan on 2002/10/21 15:58:42 - - aic79xx.c: - Move "false parity error due to REQ release glitch" - workaround to the packetized busfree handler. We - now only look to see if this is the potential cause - of the error if we have ruled out all other causes. - Before, it might be possible for this workaround - to trigger on "real" busfrees. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#123 edit - -Change 1513 by gibbs@overdrive on 2002/10/21 15:53:19 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#37 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#18 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#38 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#18 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#19 edit - -Change 1512 by gibbs@aslan on 2002/10/21 15:51:41 - - aic79xx.c: - aic79xx.seq: - Handle unexpected command phases in the protocol violation - handler. Right now we treat these just like data phase - protocol violations. - - aic79xx.seq: - Optimize out a few instructions by using a common label - for protocol violations in mesgin and status phases. One - more instruction was removed by factoring out the status - received check in the mesgin_complete handler. - - aic7xxx.c: - aic7xxx.h: - aic7xxx.reg: - aic7xxx.seq: - Bring in the protocol violation handler from the U320 - driver and replace the NO_IDENT sequencer interrupt code - with the PROTO_VIOLATION code. Support for this code - required the following changes: - - SEQ_FLAGS: - IDENTIFY_SEEN -> NOT_IDENTIFIED - Added NO_CDB_SENT - - SCB_CONTROL: - TARGET_SCB == STATUS_RCVD for initiator mode - - scb->flags: - Added SCB_TARGET_SCB since we cannot rely on - TARGET_SCB as a target/initiator differentiator - due to it being overloaded in initiator mode to - indicate that status has been received. - - aic7xxx.seq: - Reset the FIFO whenever a short CDB transfer occurs - so that the FIFO contents do not corrupt a future CDB - transfer retry. - - Add support for catching the various protocol violations - handled by ahc_handle_protocol_violation. - - Reformat some comments. - - aic7xxx_osm.c: - Handle changes to SCB_CONTROL, scb->flags and SEQ_FLAGS. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#122 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#64 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#87 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#55 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#35 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#51 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#12 edit - -Change 1511 by gibbs@overdrive on 2002/10/18 17:37:10 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#36 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#37 edit - -Change 1509 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/18 17:33:40 - - Remove the DV framework from aic79xx. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#63 edit - -Change 1508 by scottl@scottl-template on 2002/10/18 15:27:23 - - Update to 6.2.13 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#95 edit - -Change 1505 by scottl@scottl-template on 2002/10/17 18:48:26 - - Integrate from aic7xxx-dv branch. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#86 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx.h#54 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#62 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#131 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#94 integrate - -Change 1491 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:51:15 - - aic79xx.reg: - Remove duplicate field. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#50 edit - -Change 1490 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:44:45 - - aic79xx.reg: - Bring in Rev B SNAPSHOT and SLOWCRC bit fields from - the DV branch. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#49 integrate - -Change 1488 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:38:54 - - README.aic79xx: - Correct rd_strm section to match correct syntax. - - Add amplitude, precomp, and slewrate options. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#4 edit - -Change 1487 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:30:42 - - aic79xx_osm.c: - aic79xx_osm.h: - Add code to set precomp, slewrate, and amplitude on - a per-controller basis. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#61 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#68 edit - -Change 1486 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 18:30:16 - - aic79xx.h: - aic79xx_pci.c: - SLEW -> SLEWRATE - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#65 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#49 edit - -Change 1484 by gibbs@overdrive on 2002/10/15 17:00:52 - - Regenerate Linux firmware and register definitions. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#35 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#16 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#36 edit - -Change 1483 by gibbs@aslan on 2002/10/15 14:53:35 - - Move IOCell paramters into softc and add a hook for the - OSM to modify these as well as other settings prior to - committing them to the chip. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#121 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#64 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#48 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#48 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#15 edit - -Change 1482 by gibbs@bitkeeper-linux-2.5 on 2002/10/15 10:05:36 - - aic79xx_osm.c: - aic7xxx_osm.c: - Promote si.memsize to 64 bits pefore shifting by - PAGE_SIZE so that the returned value is not truncated - to 64GB. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#60 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#130 edit - -Change 1481 by scottl@scottl-template on 2002/10/15 00:59:37 - - Integrate debugging info nit from aic7xxx-dv - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#129 integrate - -Change 1480 by scottl@scottl-template on 2002/10/15 00:57:33 - - Update to version 6.2.12 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#93 edit - -Change 1478 by scottl@scottl-template on 2002/10/15 00:22:14 - - Integrate from the aic7xxx-dv branch - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#53 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#128 integrate - -Change 1474 by scottl@scottl-template on 2002/10/14 10:57:29 - - Integrate the aic7xxx dv work into head - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#85 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#127 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#92 edit - -Change 1465 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/10 16:11:43 - - Add three new insmod tunables for the IO Cell. They let you control - the slewrate, precomp, and amplitude. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#120 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#59 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#67 edit - -Change 1462 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/09 21:49:56 - - Add updated H2B identifiers - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#47 edit -... //depot/linux_mod_devel/scsi.aic79xx/dud/redhat/pcitable#2 edit - -Change 1457 by gibbs@bitkeeper-linux-2.4 on 2002/10/09 15:56:51 - - Integrate from aic7xxx -> aic7xxx_dv. - -Affected files ... - -... //depot/aic7xxx-dv/aic7xxx/aic79xx.c#3 integrate -... //depot/aic7xxx-dv/aic7xxx/aic79xx.reg#3 integrate -... //depot/aic7xxx-dv/aic7xxx/aic79xx.seq#3 integrate -... //depot/aic7xxx-dv/aic7xxx/aic79xx_pci.c#3 integrate -... //depot/aic7xxx-dv/aic7xxx/aic7xxx.c#2 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#2 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#3 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#3 integrate -... //depot/aic7xxx-dv/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#7 edit - -Change 1455 by gibbs@bitkeeper-linux-2.4 on 2002/10/09 15:08:23 - - aic7xxx.c: - Only force a renegotiation on a selection timeout - if the SCB was valid. Doing otherwise may be dangerous - as the connection was not valid for an unknown reason. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#84 edit - -Change 1454 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/10/09 14:45:23 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#66 edit - -Change 1453 by gibbs@overdrive on 2002/10/09 14:44:21 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#34 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#15 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#35 edit - -Change 1452 by gibbs@aslan on 2002/10/09 14:43:31 - - The double write workaround for CURRSCB is only required if - abort pending is set. Remove this work around and set the - abort pending bug bit on the B at least until we have better - confirmation that the double write is always safe. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#63 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#46 edit - -Change 1450 by gibbs@overdrive on 2002/10/09 00:32:41 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#33 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#14 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#34 edit - -Change 1449 by gibbs@aslan on 2002/10/09 00:31:44 - - aic79xx.c: - Enhance the packetized overrun handler to cover the - case of a data phase for an SCB that is not active. - - Update the comment on how CRC errors should be handled - in Harpoon2A and B. The comment is still not fully - accurate. We'll need more input from the hardware developers - before we can make the CRC handling really robust. - - Add diagnostics for unexpected busfrees that we take to - mean a negotiation message has been rejected. - - Fix several bugs in the iocell option setting code. For - starters, the amplitude setting is in ANNEXCOL 6. The - amplitude should also be set regardless of connection - speed. The negotiation table is now updated in the - chip reset code which occurs after the profile information - is stored in our softc. This avoids the problem of having - the chip reset code clear the neg table after the profile - code has written to it. Lastly, only clear the negtable - manually on chip reset if we are on rev A. - - Remove the redundant setting of the ABORTPENDING bit. - I have yet to verify that aborts actually work on the B. - - Have ahd_qinfifo_requeue_tail() save and restore the - current mode and operate in the command channel mode. - ahd_qinfifo_count requires this mode and some of the - latest callers to ahd_qinfifo_requeue_tail() are not - already in the command channel mode. - - Allow register pretty printing with a NULL cur_column. - - Add a space in a register diagnostic and print out SIMODE0 - in ahd_dump_card_state(). - - aic79xx.reg: - Add a macro RESTORE_MODE that sets the current mode to - the value stored in the register passed to it. - - Add the DFFBITBUCKET bit for packetized bitbucket. - - Correct the definition of AHD_ANNEXCOL_IOCELL_OPT1. - - aic79xx.seq: - Clean up the structure of our idle loop. This adds - a few instructions since the idle loop has been broken - into the following sub-routines that can be assembled - into customized idle loops: - - idle_loop_gsfifo - Service the Good Status FIFO - idle_loop_service_fifos - Run any LONGJMP handlers - idle_loop_cchan - Run command channel operations - - One or more of these routines are now called from the - main idle loop, the legacy idle loop, and the allocate_fifo - routine. This removes a bunch of duplicated code and hopefully - clarifies the code flow. - - Optimize out a few instructions. - - Write to CURRSCB twice in a row since it seems that these - writes are sometimes flakey. - - Use the MK_MESSAGE bit in SCB_CONTROL as our abort bit. - We now set MK_MESSAGE on every SCB completion so that - reselections to idle SCBs trigger an automatic abort. - - Now that the other FIFO may be active doing packetized - things during a legacy connection, have the legacy - idle loop use a LONGJMP handler and process LONGJMP - handlers for both FIFOs. - - Have the CFG4OVERRUN handler use packetized bitbucket - if it is available. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#119 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#47 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#62 edit - -Change 1445 by gibbs@overdrive on 2002/10/05 00:10:28 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#32 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#33 edit - -Change 1444 by gibbs@aslan on 2002/10/05 00:07:22 - - aic79xx.c: - Add 4 TRACEPOINT sequencer interrupts useful for debugging. - - Record busfree time prior to clearing any critical sections - since we now clear any busfree interrupts while stepping. - - Add support for supressing unexpected busfree warnings - when we reject a QAS request after delivering a CRC - related message. - - Rev B hardware will not step with pending, pausing, - sequencer interrupts. Turn off the interrupt enables - for all pausing interrupts save ENBUSFREE. ENBUSFREE - must not be disabled or we will lose the ability to - detect unexpected busfree events until the start of - the next connection. Diagnostics have also been added - to track the stepping process under the MISC debug category. - - Add CLROVERRUN to the list of interrupts cleared by - ahd_clear_intstat(). - - Update PPR message conformance rules. RTI must be - disabled for non-paced transfers. - - Don't apply RevA negtable corrections to the B. - - First pass at supporting RevB IOCELL settings. Currently - the settings for precomp are the same for Rev A and B, - so they share code. This will have to change if these - numbers are adjusted further. It may be possible to remove - the RevA HP_BOARD options, but I still need to verify that - with Brandon Aubrey. - - If a device rejects a PPR message after the full PPR - message has been sent, assume it does not understand - SPI-4 PPR options and negotiate without them. This - allows us to negotiate U160 with certain Fujitsu - U160 drives. - - Use enhanced DFFSTAT CURRFIFO status and adjust code - appropriately. - - CPQ->HP - - Set LQONOCHKOVER in LQOSCSCTL to avoid spurious LQO - overrun conditions. - - Negotiate RTI if it is available. - - aic79xx.h: - Add RTI and NEW_IOCELL_OPTS as AHD options enabled on - the B. - - Document each ahd_bug entry in the enumeration for quick - reference and add the AHD_LQOOVERRUN_BUG and - AHD_PACED_NEGTABLE_BUG entries. - - CPQ-HP - - Add the expect QAS reject busfree flag in ahd_msg_flags. - - aic79xx.reg: - Add four tracepoint sequencer interrupts. - - Modify CURRFIFO definition for Rev A backwards compatibility - while using Rev B enhanced mode. - - Add the LQOSCSCTL register. - - Correct spelling of CURRFIFODEF in SCSCHKN. - - Add new IOCELL option ANNEX column definitions. - - Update CCSGCTL to move of CCSGEN in Rev B. This - definition allows backwards compatibility, but may - change should we decide to optimize code due to this - change. - - Align QOUTFIFO_NEXT_ADDR on a 4 byte boundary since on - the B, this is required of any location that will be used - as the source for a block move to SCB/SGHADDR. - - aic79xx.seq: - Hit CCSCBRESET after setting the target address in - SCBHADDR to mirror what the CHIM sequencer does. I - don't believe this has any real effect but was a holdover - from debugging command channel DMA operations up to - the host on the B. - - Simplify the run down of the qoutfifo loop by rearranging - it a bit. We no longer special case loading first element. - - Allow non-pack transactions to use either FIFO without - waiting for the other FIFO to clear on Rev B. - - Remove an unecessary clear of SHCNT[1] and SHCNT[2] in - the embedded cdb transmission case. - - Do not rely on SCSIENACK being visible until at least one - sequencer instruction after it is written. While this - is safe on RevA, the wait is required on RevB. - - Adapt to changes in the definition of CCSGCTL. - - Always perform aligned, 4byte block moves to SCB/SGHADDR. - Single RMW operations are still okay too. - - aic79xx_pci.c: - HP -> CPQ - - Rearrange IDs to better match which chips they use. - - Convert to uniform product description strings. - - Simplify 7901A setup function. - - Add the NONPACKFIFO_BUG and PACED_NEGTABLE_BUG entries - for the A. - - Add rev B bugs and features. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#118 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#63 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#46 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#61 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#45 edit - -Change 1441 by gibbs@overdrive on 2002/10/04 16:29:18 - - Add missing "{}"s around diagnostic code so that status packet - information is not printed unless the SHOW_SENSE debug flag is - set. The message is only printed if the driver is compiled with - debug code enabled. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#117 edit - -Change 1432 by gibbs@overdrive on 2002/10/02 15:12:35 - - oder -> order. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#2 edit - -Change 1427 by gibbs@bitkeeper-linux-2.4 on 2002/10/01 18:56:39 - - Have the Makefile do all the relative path including instead of - putting this in all of the include directives in the Linux OSMs. - This will make the module building framework happy on 8.0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#58 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#65 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#126 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#91 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#6 edit - -Change 1425 by gibbs@aslan on 2002/10/01 14:45:04 - - Add a space to the end of the ahc/ahd_print_devinfo routines - so that it behaves as expected by the code that uses it. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#116 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#83 edit - -Change 1424 by gibbs@bitkeeper-linux-2.4 on 2002/10/01 13:20:47 - - If the initial bus reset is diabled, attempt to negotiate async - rather than the fastest non-ppr rate below the user setting. We - will negotiate up to the user setting once inquiry information is - available. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#57 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#125 edit - -Change 1423 by gibbs@aslan on 2002/10/01 13:13:22 - - aic79xx.c: - Fix a style nit. - - Attempt to recover from a selection timeout that - occurs with an invalid SCB. This should never - happen, but its best to try and keep the machine - going. - - Force a renegotiation to a particular target after - a selection timeout. This handles the case of a - temporary interruption in the cable that the target - might notice and switch back to async without creating - a unit attention condition. - - Add code to ignore busfree interrupts which are in - fact parity errors resulting from a glitchy REQ - release of the free running clock by a target transitioning - to the bus free phase. This code needs to be tested by - FTL. A diagnostic will be printed if the debugging code - is enabled with the AHD_SHOW_MASKED_ERRORS bit set in - the debugging bitmask. - - Remove a redundant setting of the mode in the busfree - handler. - - aic79xx.c: - aic79xx.h: - aic7xxx.c: - aic7xxx.h: - Change ahc/ahd_upate_neg_request() to take a "negotiation - type" enum that allows us to negotiate: - o only if the goal and current parameters differ. - o only if the goal is non-async - o always - even if the negotiation will be for async. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#115 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#62 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#82 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#52 edit - -Change 1422 by gibbs@aslan on 2002/09/30 17:09:13 - - Don't panic (as a diagnostic to catch bugs) if we decided to - force the renegotiation of async even if we believe we are - already async. This should allow us to negotiate async instead - of the full user goal rate during startup if bus resets are disabled. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#114 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#81 edit - -Change 1420 by gibbs@aslan on 2002/09/30 13:49:47 - - Remove a left over '&' from the conversion to using our - softc referenced seeprom store. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#26 edit - -Change 1419 by gibbs@bitkeeper-linux-2.5 on 2002/09/27 16:44:04 - - Add a missing pair of curly braces to a conditional debug - statement. This ensures that debug code doesn't trigger if - it isn't enabled. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#80 edit - -Change 1418 by gibbs@bitkeeper-linux-2.5 on 2002/09/27 14:46:02 - - Reset commands_since_idle_or_otag in the mid-layer induced otag - case. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#56 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#124 edit - -Change 1417 by gibbs@bitkeeper-linux-2.5 on 2002/09/27 14:36:27 - - Honor ordered tagged requests from the mid-layer. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#55 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#123 edit - -Change 1416 by gibbs@aslan on 2002/09/26 21:19:05 - - Remove redundant inclusion of inttypes.h in aicasm_gram.y - and properly sort inttypes.h into list of includes. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#25 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#7 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#23 edit - -Change 1415 by gibbs@aslan on 2002/09/26 16:02:22 - - Correct another BE issue in a printf. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#113 edit - -Change 1404 by gibbs@overdrive on 2002/09/24 17:27:07 - - Correct a spelling error. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#54 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#122 edit - -Change 1403 by gibbs@aslan on 2002/09/24 17:06:41 - - Correct a spelling mistake. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#79 edit - -Change 1400 by gibbs@overdrive on 2002/09/24 14:29:16 - - Make version numbers match what the driver prints on startup. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#2 edit - -Change 1399 by gibbs@overdrive on 2002/09/24 13:54:33 - - Add README files for embedded Linux drivers. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic79xx#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/README.aic7xxx#1 add - -Change 1398 by gibbs@bitkeeper-linux-2.5 on 2002/09/24 12:50:32 - - Bump Linux driver versions: - aic7xxx = 6.2.10 - aic79xx = 1.1.1 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#64 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#90 edit - -Change 1397 by gibbs@bitkeeper-linux-2.4 on 2002/09/23 12:02:16 - - Add memory mapped I/O compile time option. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#9 edit - -Change 1396 by gibbs@bitkeeper-linux-2.4 on 2002/09/23 12:01:01 - - Add memory mapped I/O option to both the aic7xxx and aic79xx drivers. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#53 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#63 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#121 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#89 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#37 edit - -Change 1395 by gibbs@overdrive on 2002/09/23 11:19:47 - - aic79xx_osm.c: - aic7xxx_osm.c: - Remove two spurious but benign if statements that - probably appeared due to an editing botch. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#52 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#120 edit - -Change 1393 by gibbs@bitkeeper-linux-2.5 on 2002/09/20 14:58:43 - - aic7xxx_host.h: - Port to 2.5.X. - - Adapt to "biosparam" driver method specification - - aic7xxx_osm.c: - Port to 2.5.X. - - Include scsicam.h for disk partition functions. - - Switch from strtok to strsep. Strtok is no longer - available in 2.5.X. - - Adapt to the removal of the io_request lock and the - mid-layer acquiring our own lock prior to calling us. - This comes in the form of a new inline, - ahc_midlayer_entrypoint_lock(). For 2.5.X, this is - no-op since our lock is already held prior to entry - into the driver. - - Make use of scsi_assign_lock so that we can have our - lock held before we have our host structure. If we - used the host lock in the host structure, we would - not be able to acquire our lock in our interrupt handler - should a shared interrupt occur before we allocated - our host structure. - - Added comments indicating why it is that we don't do - the same ahc_unlock()/ahd_done_lock() dance in 2.5.X. - Since the done lock and the ahc_lock are one and the - same, it doesn't make sense to release and reacquire - the same lock. For older kernels, this dance is required - to avoid lock order reversals. - - In our error recovery entry points, move unlock_irq() - calls down to where we sleep so it is more obvious why - they are required. Add some comments about this too. - - Adapt to changes in the biosparam method specification. - - Turn runq scheduling into an inline to remove lots of - #ifdef clutter. - - aic7xxx_osm.h: - Make register pretty printing and option. - - Add ahc_midlayer_entrypoint_lock() inlines to help - manage the latest Linux mid-layer locking fiasco. - - ahc_done_lock/unlock are no-ops for 2.5.X. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#119 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#88 edit - -Change 1392 by gibbs@bitkeeper-linux-2.5 on 2002/09/20 14:47:28 - - Config.in: - Bring both the aic7xxx and aic79xx sections of this - file up to date in regards to the latest options. - aic79xx_host.h: - Port to 2.5.X. - - Adapt to "biosparam" driver method specification - - Modify driver template to be 2.5.X compatible - - aic79xx_osm.c: - Port to 2.5.X. - - Include scsicam.h for disk partition functions. - - Switch from strtok to strsep. Strtok is no longer - available in 2.5.X. - - Adapt to the removal of the io_request lock and the - mid-layer acquiring our own lock prior to calling us. - This comes in the form of a new inline, - ahd_midlayer_entrypoint_lock(). For 2.5.X, this is - no-op since our lock is already held prior to entry - into the driver. - - Make use of scsi_assign_lock so that we can have our - lock held before we have our host structure. If we - used the host lock in the host structure, we would - not be able to acquire our lock in our interrupt handler - should a shared interrupt occur before we allocated - our host structure. - - Added comments indicating why it is that we don't do - the same ahd_unlock()/ahd_done_lock() dance in 2.5.X. - Since the done lock and the ahd_lock are one and the - same, it doesn't make sense to release and reacquire - the same lock. For older kernels, this dance is required - to avoid lock order reversals. - - In our error recovery entry points, move unlock_irq() - calls down to where we sleep so it is more obvious why - they are required. Add some comments about this too. - - Adapt to changes in the biosparam method specification. - - Turn runq scheduling into an inline to remove lots of - #ifdef clutter. - - aic79xx_osm.h: - Make register pretty printing and option. - - Add ahd_midlayer_entrypoint_lock() inlines to help - manage the latest Linux mid-layer locking fiasco. - - ahd_done_lock/unlock are no-ops for 2.5.X. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#51 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#62 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#8 edit - -Change 1386 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/17 19:10:33 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#61 edit - -Change 1385 by gibbs@overdrive on 2002/09/17 18:48:09 - - aic79xx_osm.c: - Correct a case in the aic79xx_rd_strm_info code where - it was referencing the tag_info array by mistake. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#50 edit - -Change 1380 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/16 14:46:03 - - Include to get uint8_t definitions - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#24 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#6 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#17 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#22 edit - -Change 1378 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/16 12:49:34 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#60 edit - -Change 1377 by gibbs@aslan on 2002/09/16 12:47:19 - - Print out LQOSTAT* registers in ahd_dump_card_state. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#112 edit - -Change 1373 by gibbs@aslan on 2002/09/12 12:33:53 - - aic79xx.c: - Cover the ENBUSFREE case for bus resets too. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#111 edit - -Change 1372 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/12 11:26:37 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#59 edit - -Change 1371 by gibbs@aslan on 2002/09/12 11:24:42 - - aic79xx.c: - With the BUSFREEREV bug in effect, we must - muck with the ENBUSFREE toggle if the busfree - occurred in a non-pack connection. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#110 edit - -Change 1370 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/11 18:39:38 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#58 edit - -Change 1369 by gibbs@overdrive on 2002/09/11 18:38:24 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#31 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#32 edit - -Change 1368 by gibbs@aslan on 2002/09/11 18:37:30 - - Implement workaround for broken busfree-rev in the A4. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#109 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#61 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#60 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#44 edit - -Change 1364 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/11 10:02:19 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#57 edit - -Change 1363 by gibbs@overdrive on 2002/09/11 10:01:38 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#30 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#31 edit - -Change 1362 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/10 19:43:30 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#56 edit - -Change 1361 by gibbs@aslan on 2002/09/10 18:57:05 - - aic79xx.c: - Aesthetic changes to the dump_sglist routine. - We now indicate that the LAST flag was set in - the last SG element. - - aic79xx_inline.h: - Don't use ahd_htole64 on a variable that may not - be 64bits wide. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#108 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#36 edit - -Change 1360 by gibbs@aslan on 2002/09/10 18:52:55 - - aicasm_gram.y: - Adjust support for mvi with immediate of 0 to - handle the downloaded constant case. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#23 edit - -Change 1354 by gibbs@aslan on 2002/09/10 15:09:50 - - aic79xx.h: - Add two new bug defines that only apply to the A: - - o AHD_REG_SLOW_SETTLE_BUG - - Some Host registers take a few clocks to settle. - - o AHD_SET_MODE_BUG - - Interrupts must be disabled when changing the mode - - aic79xx.reg: - Modify SET_MODE and add a new TOGGLE_DFF_MODE macro - to optimize out the AHD_SET_MODE_BUG workaround. - - Make P_BUSFREE a field instead of a member of an - enum with a mask that doesn't apply to its bit location. - - aic79xx.seq: - Optimize code based on the two new bug defines. We - also iimplement, for the first time, the SLOW_REG - bug workaround. - - SET_MODE and TOGGLE_DFF_MODE can't have ';'s after - them now due to if/else clauses. - - Correct a ';' -> ':' syntax error. - - aic79xx_pci.c: - Add the two new bug defines to the list of bugs - that apply to the A4. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#60 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#45 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#59 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#43 edit - -Change 1352 by gibbs@aslan on 2002/09/10 14:44:31 - - aicasm_gram.y: - Allow mvi immediates of zero and have the assembler - convert these to the equivalent of a clr instruction. - This allows macros that do not know the value of the - immediate they are given DTRT. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#22 edit - -Change 1349 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/09 15:09:57 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#55 edit - -Change 1347 by gibbs@aslan on 2002/09/09 15:08:20 - - aic79xx.seq: - In pkt_saveptrs, wait for FIFOEMP before issuing - the clearchn. This seems to be the easiest way - to ensure that we don't complete the command to - the host prior to all data draining. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#58 edit - -Change 1346 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/08 17:46:07 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#54 edit - -Change 1345 by gibbs@overdrive on 2002/09/08 17:41:10 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#29 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#30 edit - -Change 1344 by gibbs@aslan on 2002/09/08 17:40:23 - - aic79xx.seq: - Correct a comment. - - In pkt_saveptrs, only clear the saveptrs interrupt - status once the pointers are saved. Otherwise we - may allow a cfg4data in the other FIFO to proceed - with incorrect data pointers. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#57 edit - -Change 1343 by gibbs@aslan on 2002/09/08 17:13:36 - - aic79xx.c: - Add diagnostic messages for DSPDATACTL workarounds. - - Negotiate HOLD_MCS for U320 transfers. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#107 edit - -Change 1342 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/06 17:46:11 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#53 edit - -Change 1341 by gibbs@overdrive on 2002/09/06 17:45:16 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#28 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#29 edit - -Change 1340 by gibbs@aslan on 2002/09/06 17:44:20 - - aic79xx.seq: - Fix syntax error. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#56 edit - -Change 1339 by gibbs@aslan on 2002/09/06 17:42:26 - - aic79xx.seq: - aic79xx.reg: - Fix SCBPTR corruption during mixed pack/non-pack - processing. When allocating a FIFO, an SCB can - complete using MODE3's SCBPTR. Save the SCBID - requesting the allocation into a new scratch ram - location that is unused by any other code prior - to running any FIFO threads and restore it once - allocation is complete. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#44 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#55 edit - -Change 1338 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/05 22:06:27 - - Update driver version - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#52 edit - -Change 1337 by gibbs@overdrive on 2002/09/05 21:48:01 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#27 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#28 edit - -Change 1336 by gibbs@overdrive on 2002/09/05 20:58:55 - - aic79xx.c: - Restart the sequencer prior to scheduling our - reset polling timer. We want to be sure the - sequencer is reset prior to the timer firing. - - In ahd_reset_poll(), put us in the SCSI mode - prior to tweaking registers. - - aic79xx.reg: - Use consistent case in defining register addresses. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#106 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#43 edit - -Change 1335 by gibbs@overdrive on 2002/09/05 20:19:00 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#26 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#27 edit - -Change 1334 by gibbs@aslan on 2002/09/05 18:26:26 - - aic79xx.h: - Give AHD_SHOW_SG it's own value. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#59 edit - -Change 1333 by gibbs@aslan on 2002/09/05 18:25:32 - - aic79xx.c: - Remove a redundant ahd_update_modes(); - - Only print scb path information in our SELTO handler - once we've verified that the SCB is not NULL. - - Fix formatting nits. - - Convert transmission error diagnostic code to ahd_reg_print(). - - Correct the comment for ahd_handle_pkt_busfree(). We - can enter this routine in any of modes 0, 1 and 3. - - In ahd_handle_pkt_busfree(), ensure we are in mode 3 - for dealing with LQOBUSFREE events, save and restore - the current SCBPTR in that mode, and use CURRSCB to - determine the SCB affected by the busfree rather than - the quite bogus SCBPTR. - - In ahd_abort_scbs(), operate in the SCSI mode so that - busy and clear TCL functions use that mode. It is - the only safe mode to use for temporary changes to - the SCBPTR register unless you have guaranteed that - no SCB fetches are inprogress in which case the command - channel mode is safe. - - Add assertions in the busy_tcl code to ensure we are - in the SCSI mode. - - Save and restore the SCBPTR in ahd_dump_card_state(). - We were always leaving SCBPTR pointing to the last - SCB traversed in our debug output. - - Use ahd_get_scbptr() in all cases. - - Cleanup some nits in ahd_dump_cardstate() output. - - Save and restore the scbptr in ahd_dump_scbs(). - - aic79xx.reg: - Remove the SCB_DMA field in SEQ_FLAGS2. It is not - needed for Harpoon's SCB dma fetch abort algorithm. - - aic79xx.seq: - Add a critical section around the SCB dma complete - code. It was possible for the host driver to "abort" - this SCB fetch while the sequencer was in the process - of handling the completion. The critical section - ensures that the SCB fetch is either aborted, or on - the waiting queue once we are outside of the critical - section. - - Complete the removal of the SCB_DMA flag. - - Fix the PDATA_REINIT case. We neglected to jump - to the dma_loop once the kernel had completed the - reinitialization. - - Fix the non-packetized bitbucket handler. We were not - properly waiting until the data phase was over. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#105 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#42 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#54 edit - -Change 1332 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/04 23:44:52 - - Version 1.0.12 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#51 edit - -Change 1331 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/04 23:43:46 - - Regen aic79xx firmware - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#25 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#26 edit - -Change 1330 by gibbs@aslan on 2002/09/04 18:04:26 - - aic79xx.c: - Don't call ahd_clear_intstat from our busfree handler. - The bus may well have moved on and we don't want to - clear state that pertains to the current connection. - If we get stray PERR status, it will now be handled - by the "catch-all" case in the SCSIINT handler. - - In ahd_clear_intstat(), deal with the AHD_CLRLQO_AUTOCLR_BUG. - This may have been the cause for the really strange - problems with mixed pack/non-pack configuratons. - - When clearing ENSELO in SCSISEQ0, make sure we are - in a known and safe mode. - - Remove "nonpkt_tag" from the "task_attribute_nonpkt_tag" - HSCB field. We no longer need nonpkt_tag information - in the SCB. - - Another update from Gordon for the bus reset quiet - the controller algorithm. - - Print the current byte on the bus in ahd_dump_card_state(). - - Remove spurious ','s from the printing of the pending list. - - Include SCB_TAG in pending list dumps. - - aic79xx.h: - Put SCB_TAG on a 4 byte boundary just to be paranoid. - - task_attribute_nonpkt_tag -> task_attribute - - aic79xx.reg: - Put SCB_TAG on a 4 byte boundary just to be paranoid. - - aic79xx.seq: - Remove extra AHD_MDFF_WSCBPTR_BUG code. The failure - can never occur since, in the A, only the non-pack - FIFO can ever be active during non-pack processing. - - Clear the busfree status when entering non-pack processing - so we can rely on it in await_busfree. - - aic79xx_inline.h: - Remove what is hopefully the last chunk of untagged queue - code from the driver. - - Don't bother setting the nonpack_tag since it is always - the same as the low byte of SCBPTR. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#104 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#58 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#41 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#53 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#35 edit - -Change 1328 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/09/03 17:30:10 - - Version 1.0.11 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#50 edit - -Change 1327 by gibbs@overdrive on 2002/09/03 17:21:56 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#25 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#18 edit - -Change 1326 by gibbs@aslan on 2002/09/03 17:20:25 - - Remove a spuriously expanded $FreeBSD$. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#5 edit - -Change 1325 by gibbs@aslan on 2002/09/03 17:14:43 - - aic79xx.c: - Add a missing space in the pending list - debug output code. - - aic79xx.h: - Add AHD_MDFF_WSCBPTR_BUG. - - aic79xx.reg: - Reserve mode specific scratch location - REG2 for interrupt handler use only. - This avoids any potential races between - normal and interrupt contexts. - - Put target mode bits after initiator bits - so that the initiator mode ones are printed - during diagnostics. We don't currently - support target mode. - - aic79xx.seq: - Add duplicate writes to SCBPTR when in modes - 0 and 1. - - Switch one section of ISR code over to using - REG_ISR. - - Perform clear target state after releasing the - FIFO so the FIFO is free as soon as possible. - - aic79xx_pci.c: - Turn on AHD_MDFF_WSCBPTR_BUG. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#103 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#57 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#40 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#52 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#42 edit - -Change 1323 by gibbs@aslan on 2002/08/30 23:06:40 - - Strip back down to $FreeBSD$. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#25 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#78 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#51 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#34 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#17 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#12 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#38 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#50 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#8 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#8 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#22 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#10 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#10 edit - -Change 1322 by gibbs@aslan on 2002/08/30 23:06:24 - - aic7xxx.seq: - Correct a bug in target mode handling of non-disconnected - transactions. The host would indicate the correct SCB to - DMA by setting the SCB id in the currently selected hardware - SCB. Unfortunately, we would then immediated allocate a - hardware SCB which, depending on the access patern might not - be the same hardware SCB that the host setup for us. Avoid - this by having the host put the SCBID into scratch ram. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#50 edit - -Change 1321 by gibbs@aslan on 2002/08/30 23:00:30 - - Strip back down to $FreeBSD$ - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#14 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#21 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#16 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#21 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#17 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aicasm/Makefile#1 add - -Change 1320 by gibbs@aslan on 2002/08/30 20:47:28 - - Expands revision tags. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#21 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#13 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#20 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#10 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#4 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#4 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#15 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#20 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#16 edit - -Change 1317 by gibbs@aslan on 2002/08/30 20:18:37 - - aic7xxx.c: - Make use of ahc_print_devinfo in the non-AHC_DEBUG case - to quiet GCC. We'll be adding more non-debug uses later - anyway. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#77 edit - -Change 1316 by gibbs@aslan on 2002/08/30 17:37:39 - - Expand Ids. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#24 edit -... //depot/aic7xxx/aic7xxx/aic79xx.c#102 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#56 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#39 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#51 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#34 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#41 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#76 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#50 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#33 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#49 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#16 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#11 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#37 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#49 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#6 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#6 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#6 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#21 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#13 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#9 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#8 edit - -Change 1313 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/29 16:44:35 - - Version 1.0.10 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#49 edit - -Change 1312 by gibbs@overdrive on 2002/08/29 16:17:01 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#23 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#16 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#17 edit - -Change 1311 by gibbs@aslan on 2002/08/29 16:08:39 - - aic79xx.c: - Correct negotiation regression in 1.0.9. We need to - cancel the negotiations for any unstarted SCBs to avoid - the "AWAITING MSG with no waiting message" assertion. - In the packetized world, it is safe to cancel negotiations - so long as we are active on the bus preventing the execution - queue from being run. Restore ahd_update_pending_scbs() to - update SCBs on the controller and have all callers only call - it for negotiation changes when the transaction is active. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#101 edit - -Change 1310 by gibbs@aslan on 2002/08/29 14:34:09 - - aic79xx.c: - aic7xxx.c: - Print pathing information with some diagnostics. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#100 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#75 edit - -Change 1309 by gibbs@aslan on 2002/08/29 14:01:21 - - aic7xxx.c: - aic7xxx.h: - Add support for AHC_SHOW_MESSAGES. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#74 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#49 edit - -Change 1308 by gibbs@aslan on 2002/08/29 14:00:48 - - aicasm.c: - aicasm.h: - aicasm_gram.y: - aicasm_scan.l: - aicasm_symbol.h: - Update copyrights. - - aicasm_symbol.c: - Update cpyright. - - Allow print reg functions for registers with - no fields. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#20 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#12 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#19 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#14 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#19 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#15 edit - -Change 1307 by gibbs@aslan on 2002/08/29 13:57:31 - - Update copyrights. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#50 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#33 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#40 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#20 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#11 edit - -Change 1306 by gibbs@aslan on 2002/08/29 13:56:41 - - aic79xx.c: - Use ahd_print_path() for selection timeout messages. - - Clear all interrupt sources, via ahd_clear_intstat(), - if we get an expected or unexpected busfree. It turns - out that the hardware clears some of them, but not all - of them when a busfree occurs which can confuse our SCSIINT - handler down the road. - - Update ahd_clear_intstat() to clear LQO/LQI type interrupts. - - Remove duplicate phase printing in the AHD_SHOW_MESSAGES - code. - - Update ahd_dump_card_state to use more of the "reg print" - functions. - - Conditionalize SG list printing under AHD_SHOW_SG. - - aic79xx.h: - Add AHD_SHOW_SG. - - aic79xx.reg: - Add several changes for Rev. B. These still need - to be verified. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#99 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#55 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#38 edit - -Change 1305 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/29 10:27:03 - - limit per-drive tags to 32 - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#7 edit - -Change 1304 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/29 10:26:10 - - Sync up with the linux-aic79xx-2.4.18_rc4 version of this in order to - get the new aic79xx_reg_print.o dependency. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#5 integrate - -Change 1302 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/28 10:55:57 - - Version 1.0.9 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#48 edit - -Change 1301 by gibbs@overdrive on 2002/08/27 16:50:51 - - Regen Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#22 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#23 edit - -Change 1300 by gibbs@aslan on 2002/08/27 16:49:33 - - aic79xx.c: - Print out both bytes of SINDEX in a diagnostic. - - Remove redundant pausing of the sequencer prior - to calls to ahd_update_pending_scbs(). It performs - its own pause management. - - In ahd_update_pending_scbs(), don't mess with SCBs - already DMA'ed down to the card. Fields in the - SCB control byte are referenced by the select out - code to determine queue state, so it is best to - leave them alone. The U320 cards don't embed - negotiation information in the SCBs anyway, so - the update was of little use. - - Protect against freezing the SIM Q multiple times - should a second bus reset be initiate prior to the - completed processing of a previous bus reset event. - - Print out some additional registers in ahd_dump_card_state(). - - Don't rely on the flexport seeprom type detection to - determine if an seeprom is present. The logic is not - present on all board types (e.g. mule boards). - - aic79xx.h: - Add bit for AHD_RESET_POLL_ACTIVE. - - aic79xx.seq: - Correct a few comments about how the sequencer operates. - - Always clear SG_STATE in disable_ccsgen. Leaving stale - info in there was confusing the non-packetized path. - - Inline the effect of a call to disable_ccsgen in the - S/G fetch code path. - - aic79xx_pci.c: - If bootverbose, indicate STPWLEVEL. - - aic79xx_osm.c: - Properly drop to a sync rate that does not require - information unit transfers if tagged queuing or the - disconnect privledge are not available. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#98 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#54 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#49 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#39 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#19 edit - -Change 1296 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/22 17:40:40 - - 1.0.8 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#47 edit - -Change 1295 by gibbs@overdrive on 2002/08/22 17:35:03 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#22 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#15 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#16 edit - -Change 1293 by gibbs@aslan on 2002/08/22 15:14:44 - - aic79xx.c - Style nits. - - Print out REG0 in the NO_MATCH case. It is more - interesting than ARG_1. - - Use AHD_NUM_LUNS_NONPKT for loops over the busy - target table. Packetized luns don't use the table. - - Use BUILD_TCL_RAW rather than rolling our own in - combination with BUILD_TCL in a few places. - - aic79xx.h: - Allow TCLs to store all lun bits. - - Lower bus reset hold time to 25us. - - aic79xx.seq: - Correct grammer in a comment. - - Simplify busy table operatins in mesgin_identify. - - Remove a commented-out diagnostic. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#97 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#53 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#48 edit - -Change 1292 by gibbs@aslan on 2002/08/22 15:10:03 - - aic7xxx.h: - Drop reset hold duration to 25us. - - aic7xxx.seq: - Correct the grammer in a comment. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#48 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#48 edit - -Change 1291 by gibbs@aslan on 2002/08/22 14:04:12 - - aicasm_symbol.c: - aicasm_symbol.h: - Fix symbol sorting logic. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#18 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#14 edit - -Change 1289 by gibbs@aslan on 2002/08/21 18:45:16 - - aic79xx.c: - aic7xxx.c: - Handle field values that can be 0 in ahd_print_register(). - The code would get into an infinite loop before. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#96 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#73 edit - -Change 1288 by gibbs@aslan on 2002/08/21 16:30:00 - - aic79xx.reg: - Remove unused SEQINTCODEs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#37 edit - -Change 1287 by gibbs@aslan on 2002/08/21 16:29:36 - - aic79xx.c: - It turns out that we can single step even if a - SCSIINT is pending. Remove clearing/restoring of - SCSIINT interrupt enables. This fixes an issue - with busfree detection getting turned off without - the possibility of re-enabling it. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#95 edit - -Change 1286 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/20 18:32:08 - - Update to 1.0.7, add required makefile changes - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#46 edit -... //depot/linux_mod_devel/scsi.aic79xx/Makefile#2 edit - -Change 1285 by gibbs@aslan on 2002/08/20 18:30:47 - - aic79xx.c: - Implement the latest bus reset card shutdown procedure. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#94 edit - -Change 1282 by gibbs@overdrive on 2002/08/20 17:18:57 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#45 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#20 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg_print.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#87 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#14 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg_print.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#15 edit - -Change 1280 by gibbs@aslan on 2002/08/20 14:15:29 - - aic79xx.seq: - Add a PREFIX for ahd generated definitions. - - Clean up more code related to the now defunct - disconnected lists. - - Use *stable* references to the current scsiid - and lun (SAVED_SCSIID/SAVED_LUN) for indexing - into the busy targets table. We were referring - to the possibly uninitialzied SCB_LUN of the - SCB we had indexed into. Bad. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#47 edit - -Change 1279 by gibbs@aslan on 2002/08/20 14:13:20 - - aic7xxx.c: - aic7xxx.h: - Fix a few typos. - - Implement ahc_print_register. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#72 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#47 edit - -Change 1278 by gibbs@aslan on 2002/08/20 14:12:23 - - aic79xx.c: - aic79xx.h: - More work on the ahd_print_register routine. - - Use the pretty print register routines in a few places. - - Fix a few typos. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#93 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#52 edit - -Change 1277 by gibbs@aslan on 2002/08/20 14:10:38 - - aic7xxx.seq: - Add a PREFIX designator for use in making assembler - generated definitions, unique. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#47 edit - -Change 1276 by gibbs@aslan on 2002/08/20 14:09:03 - - aic79xx.reg: - aic7xxx.reg: - Adapt to new assembler syntax. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#36 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#32 edit - -Change 1275 by gibbs@aslan on 2002/08/20 14:06:35 - - aicasm.c: - aicasm_gram.y: - aicasm_scan.l: - aicasm_symbol.c: - aicasm_symbol.h: - Add support for generating register field tables for - use in pretty-printing register values. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#19 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#18 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#13 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#17 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#13 edit - -Change 1272 by gibbs@overdrive on 2002/08/14 14:16:46 - - aic79xx_osm_pci.c: - Move warning about failures to memory map our controller - under bootverbose. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#12 edit - -Change 1271 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/14 08:02:15 - - Version 1.0.6 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#44 edit - -Change 1270 by gibbs@overdrive on 2002/08/13 16:02:05 - - aic79xx_osm.c: - aic7xxx_osm.c: - Use MSG_EXT_PPR_QAS_REQ rather than SID_SPI_QAS - when dealing with PPR options. The latter is used - when looking at inquiry information. Ooops. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#49 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#118 edit - -Change 1269 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/09 13:09:26 - - veriosn 1.0.5 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#43 edit - -Change 1264 by gibbs@aslan on 2002/08/08 15:19:58 - - aic79xx.c: - Use CAM_SEQUENCE_FAIL for protocol violations. - - Add first cut at a register printing function. - - Use better markers for the beginning and end - of ahd_dump_card_state. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#92 edit - -Change 1263 by gibbs@aslan on 2002/08/08 15:18:52 - - aicasm.c: - aicasm.h: - aicasm_gram.y: - aicasm_scan.l: - aicasm_symbol.c: - aicasm_symbol.h: - First cut at outputing register printing tables. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#18 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#11 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#17 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#12 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#16 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#12 edit - -Change 1262 by gibbs@overdrive on 2002/08/08 14:21:43 - - cam.h: - Add a mapping for CAM_SEQUENCE_FAIL. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#13 edit - -Change 1261 by gibbs@overdrive on 2002/08/08 10:56:31 - - aic79xx_osm.c: - aic7xxx_osm.c: - If QAS is not supported by a target, be sure to clear - the QAS flag in the ppr_options. Otherwise we may - attempt a PPR on a device that does not support it. - - Use prot_version rather than the protocol version in - the tstate as the latter is not initialized until later - in the routine and will be 0 the first time an inquiry - is sent to a device. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#48 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#117 edit - -Change 1259 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/07 09:36:00 - - Version 1.0.4 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#42 edit - -Change 1258 by gibbs@aslan on 2002/08/06 16:58:52 - - aic79xx.c: - Move expected bus free handling code to ahd_set_syncrate() - so that it will work for message types other than PPR. - - Test for expected bus frees if the last phase was either - MESGIN or MESGOUT. SPI4 dictates that the bus free will - occur once message phases are over, so we must handle the - case of other messages occuring prior to the bus going free. - We filter out other causes for the bus free (abort tag, etc.) - prior to treating this as an expected busfree. - - Wait a bus reset delay prior to performing the chip reset - for outgoing bus resets *just in case* this helps with the - stray arb issue. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#91 edit - -Change 1250 by gibbs@overdrive on 2002/08/05 14:23:13 - - aic7xxx_osm.c: - aic79xx_osm.c: - Fix off-by-one errors in calculations using the inquiry - data's additional_length field. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#47 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#116 edit - -Change 1248 by gibbs@overdrive on 2002/08/03 12:26:50 - - aic7xxx_proc.c: - Explicitly test for VLB and PCI cards in seeprom_write() - so we don't try this on EISA cards. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#22 edit - -Change 1246 by gibbs@overdrive on 2002/08/03 12:06:45 - - aic7xxx_proc.c: - AHC_PCI_CONFIG is always defined. Test for > 0 instead. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#21 edit - -Change 1244 by gibbs@overdrive on 2002/08/03 12:01:55 - - aic7xxx_osm.c: - ahc_pause_and_flush_work() -> ahc_pause_and_flushwork(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#115 edit - -Change 1243 by gibbs@overdrive on 2002/08/03 11:57:55 - - aic7xxx_proc.c: - Allow this to compile if PCI support is not - configured into the system. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#20 edit - -Change 1242 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/08/02 19:43:45 - - Version 1.0.3 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#41 edit - -Change 1240 by gibbs@aslan on 2002/08/02 17:47:26 - - aic79xx.c: - Force scb to be NULL if we have not been fully identified - in ahd_handle_protocol_violation(). - - Use MSG_ABORT_TASK for invalid reselections as per the - SPI4 spec. - - Push the waiting for the bus transceivers to setting into - ahc_chip_init(). This makes the wait occur for bus reset - operations too. Perform this wait prior to setting up - any of our iocell workarounds just in case the chip clobbers - them when the bus settles. - - Don't rely on the chip remaining paused while we wait for - the bus reset line to fall. We simply perform most of - the reconfiguration of the chip prior to starting to poll - for the reset line to fall. - - Fix a bug in ahd_reset_poll() in the case of the reset - line not falling. We would not exit the function to wait - again for the reset line to fall. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#90 edit - -Change 1228 by gibbs@overdrive on 2002/07/31 16:33:59 - - aic79xx_osm.c: - aic79xx_osm.h: - aic7xxx_osm.c: - aic7xxx_osm.h: - cam.h: - Emulate CAM_REQUEUE_REQ by returning check condition - status with the ABORTED COMMAND sense key. This works - even if we happen to be requesting an error recovery - command to be unconditionally requeued. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#46 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#40 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#114 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#86 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#12 edit - -Change 1227 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/31 12:12:00 - - version 1.0.2 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#39 edit - -Change 1226 by gibbs@overdrive on 2002/07/30 17:12:07 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#20 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#14 edit - -Change 1225 by gibbs@aslan on 2002/07/30 17:10:40 - - aic79xx.c: - When a selection timout occurs, we need not play with - ENBUSFREE. The busfree interrupt is a pulse so simply - clearing that interrupt source is sufficient. - - Fixup some curly braces. - - LASTPHASE -> PREVPHASE. LASTPHASE is a register - in scratch ram and not the bit in the PERRDIAG register - that indicates if the error has occurred before the - current phase. - - When setting the SCSI reset line, clear ENSELO and - ENARBO just in case they are set. We don't want the - chip to decide it need to perform a select out as - soon as the reset is over. - - Add a line of '='s prior to dumping card state. It - makes traces easier to follow. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#89 edit - -Change 1224 by gibbs@aslan on 2002/07/29 17:06:54 - - aic79xx.c: - When auto-sense fails due to non-0 scsi status, - we still need to release the selection queue. - Rearrange the code so that we do this step prior - to checking to see if this was an auto-sense - command. - - aic79xx.seq: - Be more careful about detection of protocol violations - flagged on command complete messages. The command complete - is valid even if the CDB was never fully sent if the - target has given us non-zero status. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#88 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#46 edit - -Change 1223 by gibbs@aslan on 2002/07/29 12:00:22 - - aic79xx.c: - Move handler for protocol violations to its own funciton. - Make another attempt to handle protocol violations that - occur before we have a fully identified connection. - - Add ahd_print_devinfo() to simplify diagnostics for - scenarios without a fully identified connection. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#87 edit - -Change 1221 by gibbs@overdrive on 2002/07/26 13:54:57 - - aic79xx_osm.c: - aic7xxx_osm.c: - When we get a QUEUE_FULL with only the transaction - returning QUEUE FULL outstanding, tell Linux that - the transaction received BUSY status. Linux doesn't - understand how to deal with QUEUE FULL correctly in - this situation and will leave the device frozen forever. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#45 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#113 edit - -Change 1217 by gibbs@overdrive on 2002/07/25 13:35:10 - - aic7xxx_osm.c: - Rely on ahc_pause_and_flushwork() instead of rolling our own. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#112 edit - -Change 1216 by gibbs@aslan on 2002/07/25 13:34:21 - - aic7770.c: - Remove an unused variable. - - aic7xxx.c: - Mask qoutfifonext in printf to avoid promotion - issues when printing its value. - - When we experience a dual edge error, send an - initiator detected error message regardless of - data direction. This is an error we can detect - either way. - - Cast the return from malloc. - - Use the SCSI offset as an indication that we have - a sync negotiation setup, not the period. - - In ahc_fetch_devinfo(), test for a few more bits - in SEQ_FLAGS to determine if we are acting as a - target that has been selected. Depending on how - far we are along in the transaction one or all - of them may be set. - - Align our S/G data structures on an 8byte boundary. - This already was occuring by luck, but using the - correct parameter to bus_dma_tag_create formalizes - this requirement. - - Guard against pending (re)selections in - ahc_pause_and_flushwork(). - - If SEARCH_REMOVE removes an SCB from an untagged queue, - clear its SCB_UNTAGGEDQ flag. - - When enabling a lun for target mode on a controller without - MULTARGID support, complain when an attempt is made to - enable another ID. - - aic7xxx.h: - Remove external declaration of the syncrate table. It - is no longer accessed directly by the OSM. - - aic7xxx.reg: - Add a definition for SXFRCTL2. This is just to serve - as documentation since we don't currently use this - register. - - Alias MWI_RESIDUAL with TARG_IMMEDIATE_SCB. This new - field is used for a more robust immediate target mode - SCB delivery scheme. - - aic7xxx.seq: - Adapt to TARG_IMMEDIATE_SCB scheme. - - Correct a problem with immediate target mode SCBs on - controllers without a command channel. We neglected - to CLRCHN before continuing the connection. - - Grammer nits. - - aic7xxx_pci.c: - Remove an unused variables. - - Simplify the code to read the SCB2 data. - - When checking termination on 785X cards, force - the wide termination to be off since these chips - do not support wide SCSI. - - aic7xxx_osm.c: - Use offset not period for sync rate negotiation decissions. - - Adapt to TARG_IMMDEDIATE_SCB scheme. - - Properly cast our softc in ahc_poll(). - - Remove test for P_BUSFREE when trying to determine if - an active SCB is valid. The SCB may be valid long - before we see the first phase. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#23 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#71 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#46 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#31 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#46 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#48 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#8 edit - -Change 1209 by gibbs@overdrive on 2002/07/24 16:53:31 - - aic79xx_osm.c: - Remove one last multi-line string constant. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#44 edit - -Change 1208 by scottl@scottl-hobbiton-mod_devel_aic7xxx on 2002/07/24 16:00:02 - - Fix compiliation errors - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#111 edit - -Change 1207 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/24 15:57:30 - - remove hard printf's - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#38 edit - -Change 1206 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/24 14:17:12 - - Driver is now at version 1.0.1 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#38 edit - -Change 1205 by gibbs@overdrive on 2002/07/24 14:09:02 - - aic79xx_osm.c: - Allow MODULE_LICENSE to work on 7.2AS. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#43 edit - -Change 1203 by scottl@scottl-linux-ia64 on 2002/07/23 11:18:20 - - Clear any bogus bus reset flags while the transceivers are settling - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#86 edit - -Change 1202 by scottl@scottl-linux-ia64 on 2002/07/22 19:10:49 - - Move the debugging printf in ahd_alloc to the end, avoiding a junk - pointer reference. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#85 edit - -Change 1201 by gibbs@aslan on 2002/07/22 17:53:37 - - aic7xxx_inline.h: - If chip interrupts are disabled, just return from our - interupt handler. In these cases, the interrupts are - likely disabled because we don't want any entry into - our interrupt handler, even those caused by a shared - interrupt handler. - - aic7770.c: - aic7xxx_pci.c: - aic7xxx_osm.c: - Allow the OSM to decide when to initially enable interrups. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#22 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#36 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#47 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#7 edit - -Change 1200 by gibbs@overdrive on 2002/07/22 17:51:33 - - aic7xxx_osm.c: - Allow the OSM to decide when to initially enable - interrupts. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#110 edit - -Change 1199 by gibbs@overdrive on 2002/07/22 17:46:04 - - aic79xx_osm.c: - Add a missing \n" - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#42 edit - -Change 1198 by gibbs@aslan on 2002/07/22 17:40:37 - - aic79xx_inline.h - If interrupts are not enabled, just return - from the interrupt handler. Interrupts are - usually disabled on the chip when we *don't* - want our interrupt handler entered which can - happen if the interrupt is shared. - - aic79xx_pci.c: - aic79xx_osm.c: - Let the OSM decide when to initially enable interrupts. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#32 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#37 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#18 edit - -Change 1197 by gibbs@overdrive on 2002/07/22 17:38:44 - - aic79xx_osm.c: - Use explicit newlines in multi-line string constants to - quiet GCC. - - Let the OSM enable interrupts once it is ready to - receive them. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#41 edit - -Change 1196 by gibbs@aslan on 2002/07/22 16:39:46 - - aic79xx.c: - Don't mask off the OVERRUN bit in sstat0 since - we do enable it. - - Assert that we are in a know mode other than MODE_CFG - when calling clear_intstat. - - To simplify logic, set the collision index in all - SCBs of a collision chain. - - AHD_BUILD_SCB_COL_IDX -> AHD_GET_SCB_COL_IDX - - CLRSCSIINT immediately after clearing any NTRAMPERRs - that occur during ahd_chip_init(). - - aic79xx.h: - aic79xx_inline.h: - Move COL_IDX macros to aic79xx.h. - - Optimize collision chain head table for multiple - targets, not multiple luns. The chain heads should - fit in 1 or 2 cache lines instead of an almost guaranteed - 1 per target. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#84 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#51 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#31 edit - -Change 1195 by gibbs@overdrive on 2002/07/22 11:00:46 - - aicasm_gram.y: - Remove an extranious break; - - The syntax for a C label is: identifier ':' statement - label: } is not valid syntax even though GCC has allowed - it for years. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#16 edit - -Change 1194 by gibbs@overdrive on 2002/07/22 10:57:44 - - aic7xxx_osm.c: - Quiet GCC 3.X warnings by using explicit newlines in - long string constants. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#109 edit - -Change 1192 by gibbs@overdrive on 2002/07/19 19:51:02 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#18 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#13 edit - -Change 1191 by gibbs@overdrive on 2002/07/19 19:50:13 - - aic79xx_osm.c: - Remove references to the untagged queues. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#40 edit - -Change 1190 by gibbs@aslan on 2002/07/19 19:48:44 - - aic79xx.c: - Remove untagged queue support code. - - Set SCB_ACTIVE when it is allocated rather than - let the OSM set it some time later. This closes - a race condition with collision list code that looks - for the active flag. - - aic79xx.h: - Move untagged queue cleanup. - - aic79xx.seq: - Remove the last reference to the SCB_NONPACKET_TAG - field. This field will be removed shortly. - - aic79xx_osm.c: - Remove untagged queue support code. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#83 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#50 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#45 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#17 edit - -Change 1189 by gibbs@aslan on 2002/07/19 19:18:20 - - aic79xx.c: - Pause the sequencer prior to updating the negotiation - tables if "paused" is false. - - Add the collision scb to the collision list, not - the just allocated scb, in ahd_get_scb(). - - Use the correct collision index when adding a just freed - scb back into a collision list. - - aic79xx.seq: - Simplify the mesgin_identify path now that we will - never have full disconnection lists. This also removes - a bug where we could select the wrong SCB as the - valid SCB for the connection. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#82 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#44 edit - -Change 1187 by gibbs@overdrive on 2002/07/19 17:27:05 - - aic79xx_osm.c: - Correct typo: simple_strltoul -> simple_strtoul. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#39 edit - -Change 1186 by gibbs@overdrive on 2002/07/19 17:19:45 - - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#18 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#12 edit - -Change 1185 by gibbs@overdrive on 2002/07/19 17:19:24 - - aic7xxx.seq: - Revert attempt to improve stuck PCI retry workaround - code. This was only generated as a test and should - never have been committed in the first place. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#45 edit - -Change 1184 by gibbs@overdrive on 2002/07/19 17:14:13 - - aic79xx_osm.c: - Get a collision index prior to getting an SCB to use. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#38 edit - -Change 1183 by gibbs@aslan on 2002/07/19 17:04:52 - - aic79xx.c: - Add string for the aic7901A. - - Implement new SCB free list management so that - all 512 scbs can be used in non-packetized - environments. - - Implement new command completion mechanism that - uses a toggling bit 15 to indicate that a new - entry has arrived. This avoids the kludgy writes - to the qoutfifo that may not work on processors - with certain types of cache retirement policies. - - Print out data structure sizes if AHD_DEBUG and - AHD_SHOW_MEMORY. - - Allocate the "sentinal" hardware SCB used for - queuing commands to the card separately so - that one of the 512 valid SCBs is not consumed - for this function. - - Add a space so we report "Wide Channel" instead of - "WideChannel". - - Cleanup allocation of the shared data area so that - the qoutfifo is always first. - - Add a fix for the RevA packetized Lun bug. The driver - will now setup a full 8byte lun in the previously - "spare" portion of the SCB and the SCB transfer size - is incremented if the bug is present. This required a - change in the layout of the disconnected SCB table to - make room for the larger lun field. - - aic79xx.h: - Add constants for the new qoutfifo scheme. - - Bump AHD_MAX_QUEUE up to 512 now that we have removed - all of the issues that previously restricted it to - a much lower value. - - Add a chip entry for the 7901A. - - Add the pkt_long_lun field to the hardware scb. - - SCB and ahc_softc updates for our new free scb - management algorithm. - - Stop inlining ahd_get_scb() and ahd_free_scb(). - The get routine also take a collision index so - as t make an optimum choice in which free SCB to - pick. - - aic79xx.reg: - Add QOUTFIFO_ENTRY_VALID_TAG which is or'd into the - top byte of each completed SCB's tag id to effect - the new completion scheme. - - Define the SCB_PKT_LUN field and new SCB transfer - sizes required to use this field.. - - aic79xx.seq: - Implement the new command completion scheme. - - Effect disconnected SCB table format change. - - aic79xx_inline.h: - When queuing a packetized SCB, update pkt_long_lun - in case we need it for the PKT_LUN workaround. - - Uninline ahd_get_scb() && ahd_free_scb(). - - Adjust for the change from storing an SCB to an HSCB - as the next "SCB" in the softc. - - Update for changes in the command completion scheme. - - aic79xx_pci.c: - Fix a few issues with detecting the 7901A. - - aic79xx_osm.c: - Determine the type of transaction prior and the - necessary collision index prior to allocating - an SCB. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#81 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#49 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#35 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#43 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#30 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#36 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#16 edit - -Change 1182 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/19 16:34:50 - - Add the global_tag_depth variable to the aic79xx driver - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#37 edit - -Change 1181 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/07/19 13:45:22 - - Update PCI tables for the 29320 and 7901 variants. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#48 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#35 edit - -Change 1180 by gibbs@aslan on 2002/07/18 17:08:50 - - aic79xx_pci.c: - Remove A3 support. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#34 edit - -Change 1179 by scottl@scottl-hobbiton-mod_devel_aic7xxx on 2002/07/18 15:46:45 - - Version 6.2.9: - Add new command-line argument global_tag_depth:, which - allows you to set the tag depth for every target on every - channel. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#108 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#85 edit - -Change 1172 by gibbs@overdrive on 2002/06/12 12:32:49 - - aic7xxx_osm.c: - Define use MODULE_LICENSE should it be defined instead - of testing against a specific kernel version. This - should allow 7.2AS driver diskettes to work. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#107 edit - -Change 1171 by gibbs@overdrive on 2002/06/06 17:40:00 - - aic79xx_osm.h: - Try two. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#37 edit - -Change 1170 by gibbs@overdrive on 2002/06/06 17:38:12 - - aic79xx_osm.h: - Convert to using AHD_DEBUG_OPTS. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#36 edit - -Change 1166 by gibbs@aslan on 2002/06/06 10:18:11 - - Cleanup AHD_DEBUG. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#80 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#47 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#29 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#33 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#14 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#8 edit - -Change 1164 by gibbs@aslan on 2002/06/06 10:05:23 - - aicasm_symbol.c: - Remove another multi-line string literal. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#15 edit - -Change 1163 by gibbs@aslan on 2002/06/05 16:49:30 - - aicasm.c: - Remove wrapping strings. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#17 edit - -Change 1159 by gibbs@bitkeeper-linux-2.4 on 2002/05/30 23:23:01 - - Config.in: - Makefile: - Cleanup our config data and makefiles. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#6 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#4 edit - -Change 1157 by gibbs@overdrive on 2002/05/30 22:15:02 - - aic79xx_osm.h: - Bump to version 1.0.0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#35 edit - -Change 1156 by gibbs@overdrive on 2002/05/30 22:14:09 - - aic79xx_inline.h: - Rearrange code to setup hscb->dataptr so our operations - are not truncated to 32bits. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#28 edit - -Change 1154 by gibbs@aslan on 2002/05/30 21:53:39 - - aic79xx_inline.h: - Include the top 7 bits of address when setting up - hscb->dataptr for the 39BIT addressing mode. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#27 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#44 edit - -Change 1153 by gibbs@aslan on 2002/05/30 20:09:22 - - aic79xx.h: - union -> struct for the cdb_plus_sense structure. - This was missed in the re-arrangement of the hscb - declaration. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#46 edit - -Change 1151 by gibbs@overdrive on 2002/05/30 18:24:34 - - aic79xx_reg.h: - aic79xx_seq.h: - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#16 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#17 edit - -Change 1150 by gibbs@aslan on 2002/05/30 14:26:20 - - aic79xx_inline.h: - aic79xx_inline.h: - Break dataptr into u_int sized chucks for - printing to avoid compiler errors. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#26 edit - -Change 1149 by gibbs@aslan on 2002/05/30 14:25:13 - - aic79xx.c: - Panic if our hardware scb definition is not 64 bytes. - Hopefully this will catch agressive compiler padding - in the future. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#79 edit - -Change 1145 by gibbs@overdrive on 2002/05/30 13:51:24 - - aic79xx_osm.c: - Upate for change in hardware SCB definition. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#36 edit - -Change 1144 by gibbs@aslan on 2002/05/30 13:50:02 - - aic79xx.c: - aic79xx.h: - aic79xx_inline.h: - aic79xx_osm.c: - Rearrange hardware SCB definition to avoid - 64bit alignment/packing problems on native - 64bit platforms. Everything was aligned - correctly, but the compiler was not smart - enough to see this with how the structures - were previously defined. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#78 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#45 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#25 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#12 edit - -Change 1143 by gibbs@aslan on 2002/05/29 20:55:06 - - aic79xx.c: - aic79xx.h: - aic79xx_pci.c: - aic7xxx.c: - Convert a few straglers to inttypes. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#77 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#44 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#32 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#70 edit - -Change 1141 by gibbs@overdrive on 2002/05/29 20:27:14 - - aic79xx_osm.c: - Bring back an "int i;" that was removed to fix a - compile warning. It is used in debug code, so move - it to where it is used. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#35 edit - -Change 1139 by gibbs@overdrive on 2002/05/29 20:23:18 - - aic79xx_osm.c: - aic79xx_osm.h: - aic79xx_osm_pci.c: - aic7xxx_osm.c: - aic7xxx_osm.h: - aic7xxx_osm_pci.c: - Bring back the hack to force consistent memory to - be below 4GB. The IA64 platform only enforces this - if your PCI device's dma mask is set to 4GB. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#34 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#34 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#106 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#84 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#36 edit - -Change 1138 by gibbs@overdrive on 2002/05/28 14:19:38 - - aic79xx_osm.c: - And another. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#33 edit - -Change 1137 by gibbs@overdrive on 2002/05/28 14:17:46 - - aic79xx_osm.c: - Kill a few compile warnings. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#32 edit - -Change 1135 by gibbs@aslan on 2002/05/28 13:35:41 - - aic79xx.c: - aic79xx.h: - Enable ahd_fini_scbdata(). - - Change some #if 0's to AHD_DEBUG logs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#76 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#43 edit - -Change 1133 by gibbs@overdrive on 2002/05/28 12:58:11 - - aic79xx_osm.c: - Clean up some 'XXX' and #if 0 stuff. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#31 edit - -Change 1132 by gibbs@overdrive on 2002/05/28 12:51:44 - - aic79xx_osm_pci.c: - More typos. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#10 edit - -Change 1130 by gibbs@overdrive on 2002/05/28 12:45:53 - - aic7xxx_osm_pci.c: - Remove stray '{' - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#35 edit - -Change 1129 by gibbs@overdrive on 2002/05/28 12:43:47 - - aic79xx_osm_pci.c: - aic7xxx_osm_pci.c: - Restore inadvertantly removed #endif. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#34 edit - -Change 1128 by gibbs@overdrive on 2002/05/28 12:39:12 - - aic7xxx_osm.c: - Remove one more stray use of hw_dma_mask. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#105 edit - -Change 1127 by gibbs@overdrive on 2002/05/28 12:37:22 - - aic7xxx_osm.c: - aic7xxx_osm.h: - aic7xxx_osm_pci.c: - Don't bother messing with the dma mask during - alloc consistent calls. Linux guarantees that - the mappings will be below 4GB. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#104 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#83 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#33 edit - -Change 1126 by gibbs@overdrive on 2002/05/28 12:32:23 - - aic79xx_osm.c: - aic79xx_osm.h: - aic79xx_osm_pci.c: - Hook up 64BIT S/G support for Linux. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#30 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#33 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#8 edit - -Change 1125 by gibbs@aslan on 2002/05/24 17:11:19 - - aic79xx.h: - Pad ahd_dma64_seg to 16 bytes so we can still use - the ODD_SEG bit in the SG_CACHE. Otherwise we'd - be able to shrink the SG element down to 12 bytes. - - aic79xx.seq: - Complete 64bit S/G data address support and inline - sg advance. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#42 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#42 edit - -Change 1121 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/24 14:01:42 - - Beta 6 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#32 edit - -Change 1120 by gibbs@aslan on 2002/05/24 13:58:41 - - aic79xx.c: - Fix some big endian bugs. - - Set SPLTSTADIS in PCIXCTL so we don't issue a target - abort when we abort an SG element fetch. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#75 edit - -Change 1117 by gibbs@overdrive on 2002/05/23 16:44:08 - - aic79xx_osm.h: - Bump version number to 0.5.0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#31 edit - -Change 1115 by gibbs@overdrive on 2002/05/23 16:41:47 - - aic79xx_osm.h: - Add PCIX configuration space definitions. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#30 edit - -Change 1114 by gibbs@aslan on 2002/05/23 16:39:32 - - aic79xx_pci.c: - First shot at PCI-X error reporting. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#31 edit - -Change 1113 by gibbs@aslan on 2002/05/23 16:36:13 - - aic79xx_inline.h: - We always need to run the qoutfifo even if only - doing target mode. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#24 edit - -Change 1112 by gibbs@aslan on 2002/05/22 13:38:33 - - aic7xxx_pci.c: - Allow autoterm if we have SCB based config data. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#46 edit - -Change 1110 by gibbs@overdrive on 2002/05/22 11:41:08 - - aic7xxx_reg.h: - aic7xxx_seq.h: - Regenerate firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#11 edit - -Change 1109 by gibbs@aslan on 2002/05/22 11:40:28 - - aic7xxx.c: - Remove some unecessary ahc_flush_device_writes(). - - aic7xxx.reg: - Remove redundant definition for SOFTCMDEN. - - aic7xxx_pci.c: - Only attempt auto-term if we have seeprom (or like) - data. - - For SPIOCAP based controllers, be sure that external - board control logic is enabled for termination control. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#69 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#45 edit - -Change 1108 by gibbs@aslan on 2002/05/21 16:51:16 - - aic79xx_pci.c: - SRAM_BASE -> SCB_BASE for reading SCB configuration - options. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#30 edit - -Change 1106 by gibbs@overdrive on 2002/05/21 15:03:07 - - Regenerate Linux aic79xx firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#15 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#16 edit - -Change 1105 by gibbs@overdrive on 2002/05/21 15:01:39 - - aic79xx_osm.c: - AHC -> AHD. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#29 edit - -Change 1103 by gibbs@overdrive on 2002/05/21 14:57:59 - - aic79xx_osm.c: - aic79xx_osm.h: - Add queue full and busy status timer to the aic79xx driver. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#28 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#29 edit - -Change 1102 by gibbs@overdrive on 2002/05/21 14:48:16 - - aic7xxx_osm.c: - Fix a few more compile errors. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#103 edit - -Change 1101 by gibbs@overdrive on 2002/05/21 14:45:36 - - aic7xxx_osm.c: - Really get the right timer. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#102 edit - -Change 1100 by gibbs@overdrive on 2002/05/21 14:39:27 - - aic7xxx_osm.c: - Use the correct timer for busy and queue full handling. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#101 edit - -Change 1099 by gibbs@overdrive on 2002/05/21 14:36:05 - - aic7xxx_osm.h: - aic7xxx_osm.c: - Perform a 500ms delay for single command queue full status - and busy status since Linux does not delay in this case. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#100 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 edit - -Change 1098 by gibbs@aslan on 2002/05/21 13:37:36 - - aic79xx.c: - aic79xx.reg: - aic79xx.seq: - Switch over to a more generic "protocol violation" - handler. Use this to now catch cases where a - disconnect or command complete message is not - valid. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#74 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#34 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#41 edit - -Change 1091 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/17 14:35:15 - - Put a blank line before the Serial EEPROM text - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#7 edit - -Change 1090 by gibbs@overdrive on 2002/05/17 14:19:14 - - aic79xx_osm.h: - Bump to Beta 4. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#28 edit - -Change 1089 by gibbs@overdrive on 2002/05/17 14:18:47 - - aic79xx_seq.h: - aic79xx_reg.h: - Regenerate firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#14 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#15 edit - -Change 1088 by gibbs@aslan on 2002/05/17 14:16:58 - - aic79xx.c: - aic79xx.reg: - aic79xx.seq: - aic79xx_osm.c: - IDENTIFY_SEEN -> NOT_IDENTIFIED. - - Add NO_CDB_SENT flag to SEQ_FLAGS. Use this - to protect against DATA phases prior to having - a completed cdb transfer. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#73 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#33 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#40 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#11 edit - -Change 1087 by gibbs@aslan on 2002/05/17 13:32:27 - - aic79xx.c: - aic79xx.h: - aic79xx.reg: - aic79xx_pci.c: - Add Compaq special write bias and slewrate. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#72 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#41 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#32 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#29 edit - -Change 1086 by gibbs@overdrive on 2002/05/17 12:30:27 - - aic79xx_proc.c: - Adapt to ahd interface changes for seeprom routines. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#6 edit - -Change 1085 by gibbs@overdrive on 2002/05/17 12:28:21 - - aic79xx_reg.h: - aic79xx_seq.h: - Regenerate Linux firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#14 edit - -Change 1083 by gibbs@overdrive on 2002/05/17 12:25:01 - - aic7xxx_proc.c: - Add a prototype. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#19 edit - -Change 1082 by gibbs@overdrive on 2002/05/17 12:24:49 - - aic79xx_proc.c: - Add write seeprom support. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#5 edit - -Change 1081 by gibbs@aslan on 2002/05/17 12:22:15 - - aic79xx.c: - aic79xx.h: - aic79xx.reg: - aic79xx_pci.c: - Add logic for writing to serial eeproms. - - Move all flexport logic into the core. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#71 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#40 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#31 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#28 edit - -Change 1080 by gibbs@aslan on 2002/05/17 11:43:50 - - aic79xx.c: - aic79xx.h: - aic79xx_pci.c: - Switch over to using a buffer to store seeprom contents. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#70 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#39 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#27 edit - -Change 1078 by gibbs@overdrive on 2002/05/17 11:31:05 - - aic79xx_proc.c: - Protect the aic79xx proc code with the ahd_list_lock. - - aic7xxx_proc.c: - Release the ahc_list_lock when errors are encountered. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#18 edit - -Change 1077 by gibbs@overdrive on 2002/05/17 11:16:59 - - aic79xx_osm.c: - ':' -> ';' - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#27 edit - -Change 1076 by gibbs@overdrive on 2002/05/17 11:14:48 - - aic79xx_osm.c: - aic79xx_osm.h: - Kill a few stray ahcs. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#26 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#27 edit - -Change 1074 by gibbs@overdrive on 2002/05/17 11:08:38 - - aic79xx_osm.c: - aic79xx_osm.h: - aic79xx_osm_pci.c: - Linux implementation of the ahd_list_lock. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#25 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#26 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#7 edit - -Change 1073 by gibbs@aslan on 2002/05/17 10:57:35 - - Implement and use the ahd_list_lock. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#69 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#26 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#10 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#6 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#6 edit - -Change 1071 by gibbs@overdrive on 2002/05/17 10:23:20 - - aic7xxx_reg.h: - aic7xxx_seq.h: - Regenerate firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#10 edit - -Change 1070 by gibbs@overdrive on 2002/05/17 10:22:28 - - aic7xxx.seq: - Defer clearing SELDO until we have set IDENTIFY_SEEN. - This closes another race in the abort code. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 edit - -Change 1069 by gibbs@overdrive on 2002/05/17 10:21:50 - - aic7xxx_osm.c: - Treat IDENTIFY_SEEN flag as an indication that we - are still on the bus but still waiting for the first - REQ. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#99 edit - -Change 1068 by gibbs@overdrive on 2002/05/17 09:42:25 - - aic7xxx_osm.c: - aic7xxx_osm_pci.c: - Guard the two avenues for detach with the ahc_list_lock. - - Disable card interrupts prior to attempting detach. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#98 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#32 edit - -Change 1067 by gibbs@aslan on 2002/05/17 09:36:18 - - aic7770.c: - aic7xxx_pci.c: - Guarantee that the ahc_list_lock is not required - across the calls to the different config calls by - only putting the softc into the list if the config - is successful. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#21 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#44 edit - -Change 1066 by gibbs@aslan on 2002/05/17 09:30:44 - - aic7770.c: - aic7xxx.c: - aic7xxx_pci.c: - aic7xxx_osm.c: - Make sure that the ahc_list_lock is always aquired - ahead of the ahc_lock to prevent lock order reversals. - - Protect insertions of the ahc_softc into the ahc_list - with the ahc_list_lock. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#20 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#68 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#43 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#5 edit - -Change 1064 by gibbs@overdrive on 2002/05/16 22:36:00 - - aic7xxx_osm.c: - Don't register our reboot notifier twice. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#97 edit - -Change 1062 by gibbs@aslan on 2002/05/16 17:36:58 - - aic79xx.c: - Set HOST_MSG in the command complete with no status - case so that when we go to message out, the sequencer - will notify the host. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#68 edit - -Change 1061 by gibbs@overdrive on 2002/05/16 14:55:36 - - aic7xxx.c: - Freeze the untagged queues from within - ahc_search_untaggd_queues() in addition to - ahc_search_qinfifo(). There are other callers - to ahc_search_untagged_queues(). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#67 edit - -Change 1059 by gibbs@overdrive on 2002/05/16 14:18:12 - - aic7xxx_osm.h: - Bump version number to 6.2.8. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#81 edit - -Change 1058 by gibbs@overdrive on 2002/05/16 14:17:45 - - aic7xxx_reg.h: - aic7xxx_seq.h: - Regenerate firmware for Linux. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#9 edit - -Change 1057 by gibbs@overdrive on 2002/05/16 14:16:41 - - aic7xxx_proc.c: - Perform a read after the write to the serial eeprom - to refresh our eeprom buffer. This allows the user - to verify that the write was good. - - Only acquire and release the seeprom if we are not - a VLB card. - - Be less strick in allowing writes. We want the user to - be able to overwrite an EEPROM that was previously corrupted. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#17 edit - -Change 1056 by gibbs@overdrive on 2002/05/16 14:13:32 - - aic7xxx_pci.c: - Set seep_config to NULL after freeing the seep buffer. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#42 edit - -Change 1055 by gibbs@aslan on 2002/05/16 13:59:01 - - aic7770.c: - aic7xxx.reg: - Add support for configuration extended translation - on the 274X. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#19 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#29 edit - -Change 1054 by gibbs@aslan on 2002/05/16 12:57:59 - - aic7xxx.h: - aic7xxx_pci.c: - Record if the BIOS config left over in SCB2 is used. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#45 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#41 edit - -Change 1053 by gibbs@aslan on 2002/05/16 12:57:24 - - aic79xx.h: - Reduce AHD_MAX_QUEUE to 255 until support for using - all SCBs is added. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#38 edit - -Change 1052 by gibbs@overdrive on 2002/05/16 11:23:12 - - aic79xx_reg.h: - aic79xx_seq.h: - Regenerate firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#13 edit - -Change 1051 by gibbs@aslan on 2002/05/16 11:06:00 - - aic79xx.c: - Correct some #if AHD_TARGET_MODE code. - - aic79xx.seq: - If we do not find a matching SCB when snooping - the bus, don't "double ack" the last byte. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#67 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#39 edit - -Change 1050 by gibbs@aslan on 2002/05/16 10:55:25 - - aic7xxx.c: - aic7xxx.h: - aic7xxx_pci.c: - Record if we are in large SCB mode and use this - to fully initialize all SCBs so that reads in - our debuging routines don't cause inadvertent - parity errors. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#66 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#44 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#40 edit - -Change 1049 by gibbs@aslan on 2002/05/16 10:41:35 - - aic7xxx.c: - Flush device writes after doing any CLRREQINITs. - - Protect ahc frees via the list lock. - - aic7xxx_osm.h: - FreeBSD implementation of the list lock. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#65 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#5 edit - -Change 1048 by gibbs@overdrive on 2002/05/16 10:29:21 - - aic7xxx_osm.c: - Set "paused" from within the "get the controller in - a consistent state" loop in ahc_queue_recovery_cmd(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#96 edit - -Change 1046 by gibbs@overdrive on 2002/05/15 17:53:13 - - aic7xxx_reg.h: - aic7xxx_seq.h: - Regenerate firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#8 edit - -Change 1045 by gibbs@aslan on 2002/05/15 17:51:20 - - aic7xxx.seq: - Only clear SELDO after we have removed the - active SCB from the waiting list. This allows - the host to use this as a confirmation that - the WAITING_SCB list is free of a just selected - SCB. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#42 edit - -Change 1044 by gibbs@overdrive on 2002/05/15 17:48:42 - - aic7xxx_osm.c: - aic7xxx_osm.h: - Add ahd_list_lock implementation for Linux. - - Protect against a pending selection in our recovery - queuing routine. - - aic7xxx_proc.c: - Use the buffer in the softc for seeprom access. Add - preliminary write support for VLB cards. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#95 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#80 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#16 edit - -Change 1043 by gibbs@overdrive on 2002/05/15 17:07:06 - - aic7xxx.c: - Clear out SCB_SCSIID and SCB_LUN when setting up - the SCB free list. We don't want a parity error - if we dump these out in ahc_dump_card_state(). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#64 edit - -Change 1042 by gibbs@aslan on 2002/05/15 15:39:00 - - aic7770.c: - Seeprom config is now a pointer. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#18 edit - -Change 1040 by gibbs@aslan on 2002/05/15 14:47:38 - - aic7770.c: - aic7xxx.c: - aic7xxx.h: - aic7xxx_pci.c: - Store seeprom information in a buffer hung - off the softc. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#17 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#63 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#43 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#39 edit - -Change 1039 by gibbs@overdrive on 2002/05/15 13:05:07 - - Merge latest aic79xx driver into linux-aic79xx-2.4.0. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/Makefile#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd640.c#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/Makefile#2 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#5 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#3 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.reg#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.seq#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_core.c#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_host.h#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_inline.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.c#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.h#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_pci.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_proc.c#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_reg.h#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_seq.h#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.reg#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.seq#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_core.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_host.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.c#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.h#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_pci.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_proc.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_reg.h#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_seq.h#4 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/Makefile#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/scsi_iu.h#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sd.c#3 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr.c#3 integrate - -Change 1038 by gibbs@overdrive on 2002/05/15 12:50:49 - - aic79xx_osm.c: - aic79xx_osm.h: - Next pass at timer support in the Linux OSM. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#25 edit - -Change 1037 by gibbs@overdrive on 2002/05/15 12:48:28 - - aic79xx.c: - Move two variables into #ifdef AHD_TARGET_ROLE. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#66 edit - -Change 1036 by gibbs@overdrive on 2002/05/14 17:16:57 - - Regenerate firmware. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#7 edit - -Change 1035 by gibbs@overdrive on 2002/05/14 17:15:44 - - aic79xx_osm.c: - Register our reboot notifier on the first allocation - of a platform softc rather than in our module parameter - parsing routine. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#23 edit - -Change 1034 by gibbs@overdrive on 2002/05/14 17:08:01 - - aic79xx_osm.h: - First cut at ahd timer facility for linux. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#24 edit - -Change 1033 by gibbs@aslan on 2002/05/14 15:54:32 - - aic79xx.c: - aic79xx.h: - aic79xx.seq: - aic79xx_osm.h: - Poll for SCSI bus reset going away from a timer - context rather than deferring the re-enabling - of the SCSIRSTI interrupt to the sequencer. We - have to catch *every* bus reset due to the reset - behavior of the negotiation table. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#65 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#37 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#38 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#5 edit - -Change 1032 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/13 17:21:47 - - Regenerate firmware - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#11 edit - -Change 1031 by gibbs@overdrive on 2002/05/13 17:14:19 - - aic79xx_osm.h - Bump version to 0.3.0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#23 edit - -Change 1030 by gibbs@aslan on 2002/05/13 17:11:08 - - aic79xx.c: - aic79xx.seq: - Have the sequencer re-enable incoming scsi reset - interrupts if, prior to starting an outgoing selection, - this interrupt is disabled. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#64 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#37 edit - -Change 1029 by gibbs@aslan on 2002/05/13 16:47:29 - - aic79xx.c: - Handle non-packetized phase unexpected busfree - events via the non-packetized handler regardless - of the packetized negotiation agreement in effect. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#63 edit - -Change 1028 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/11 22:55:03 - - Bump the version to 0.2.1. We missed 0.2.0, and the driver is - about to be re-released to address yet another script bug. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#22 edit - -Change 1026 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/10 22:38:10 - - Regenerate firmware - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#10 edit - -Change 1024 by gibbs@aslan on 2002/05/10 20:19:25 - - aic79xx.c: - Add an error handler for receiving a command complete - message without having received status. We will attempt - to abort the command. - - Enable the OVERRUN interrup and add a handler for it. - - Include lun information when compiling devinfo for the - unexpected bus free handler. - - Mask off the correct number of length bits when printing - S/G elements. - - Always update the neg table when setting bus width. - - Don't bother clearing the last three bytes of the annex - table on every update of the neg table. These are cleared - explicitly on chip reset and will, in the B, contain training - info. - - Reset the chip on third party resets. It is hoped that this - is the cause of some of the host basher issues related to - transferring into and out of emulation mode. - - Factor out more S/G printing code. - - aic79xx.reg: - Add a new sequencer interrupt code for a command complete - message with no status phase. - - aic79xx.seq: - Add checking for whether status has been delivered or not - in the command complete handler. - - Correct a test for a necessary bitbucket prior to having - the host reinitialize our data pointers. - - aic79xx_osm.h: - Change the AHD_DEBUG value for FreeBSD to 0x3FF. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#62 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#30 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#36 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#4 edit - -Change 1018 by gibbs@bitkeeper-linux-2.4 on 2002/05/08 17:21:24 - - aic7xxx_osm.c: - Replace SEARCH_REMOVE with SEARCH_COMPLETE in the search - of the untagged queue. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#94 edit - -Change 1017 by gibbs@overdrive on 2002/05/07 17:45:57 - - aic7xxx_osm.c: - Remove entries from the untagged queue prior to - doing a more general abort in ahd_linux_queue_recovery_cmd(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#93 edit - -Change 1016 by gibbs@aslan on 2002/05/07 17:34:02 - - aic7xxx.c: - aic7xxx.h: - Break out the search for entries in the untagged - queue into its own routine. Allow the user to - search based on io_ctxt too. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#62 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#42 edit - -Change 1015 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/07 14:54:52 - - Beta 1 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#21 edit - -Change 1014 by gibbs@aslan on 2002/05/07 14:53:39 - - aic79xx.h: - Limit max queue to 256 until nonpacketized tag - management is added to the driver. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#36 edit - -Change 1013 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/07 14:26:20 - - Add semicolon, initialize a variable before use. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#22 edit - -Change 1012 by gibbs@overdrive on 2002/05/07 14:25:46 - - aic79xx.h: - Change ahd_debug to be a uint32_t. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#35 edit - -Change 1011 by gibbs@overdrive on 2002/05/07 14:01:41 - - aic79xx.c: - Make ahd_debug a uint32_t. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#61 edit - -Change 1010 by gibbs@overdrive on 2002/05/07 13:59:31 - - aic79xx_osm.c: - Ignore short inquiry information for devices that - are already configured and seem to allow spi3/4 - ppr options. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#21 edit - -Change 1009 by gibbs@aslan on 2002/05/07 13:07:06 - - aic79xx.c: - Expand on our unexpected busfree handling. - We now have a better chance of getting the - packetized vs. non-packetized status correct. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#60 edit - -Change 1008 by gibbs@aslan on 2002/05/07 11:22:51 - - aic79xx.h: - Add a debug option for QFull messages. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#34 edit - -Change 1007 by gibbs@overdrive on 2002/05/07 11:22:04 - - aic79xx_osm.c: - Add a loging option for displaying Queue Full info. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#20 edit - -Change 1005 by gibbs@aslan on 2002/05/06 17:20:00 - - aic79xx.c: - Complete port of the ignore wide residue and - data pointers reinitialization routines. - - Create ahd_dump_sglist() and use it to factor out - some code. - - Use SCB_GET_TAG to access hscb->tag. This fixes - the first of many big endian issues in the driver. - - In the busfree handler, busfree time is valid even - for non-packetized phases. We now assume that a - packetized phase is active if lastphase is P_BUSFREE. - - If a parity error occurred in the current phase, - ack the current byte so long as it is not currently - a data phase. - - Print out the number of SCBs aborted during - non-packetized busfree handling. - - aic79xx.h: - Add definition for SCB_GET_TAG. - - Add a new debug entry for AHD_SHOW_QUEUE. - - Add prototype for ahd_dump_sglist. - - aic79xx.seq: - In our restore data pointers handler, release - and reacquire our FIFO to flush out any state - info before a possible return to data phase. - - When coming back to the data phase handler after - having already handled at least one data phase, - only bother with the PDATA_REINIT sequencer - interrupt if we think more data needs to be sent. - - aic79xx_inline.h: - More SCB_GET_TAG() cleanup. - - Add SHOW queue code. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#59 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#33 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#35 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#23 edit - -Change 1004 by gibbs@aslan on 2002/05/06 17:07:11 - - Sync FreeBSD Ids. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#61 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#41 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#28 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#41 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#15 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#10 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#35 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#38 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#16 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#10 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#15 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#9 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#11 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#14 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#11 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#5 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#5 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#9 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#4 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#4 edit - -Change 1002 by gibbs@overdrive on 2002/05/02 19:05:23 - - aic79xx_osm.c: - aic7xxx_osm.c: - Release the io_request lock in our detect routines - to avoid deadlock with other portions of the system - (possibly PCI) that may try to acquire a spin lock. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#92 edit - -Change 1001 by gibbs@overdrive on 2002/05/02 17:24:12 - - aic79xx_osm.c: - Put sense printing behind AHD_DEBUG. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#18 edit - -Change 1000 by gibbs@aslan on 2002/05/02 17:22:05 - - aic79xx.c: - Put even more messages behind AHD_DEBUG type stuff. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#58 edit - -Change 999 by gibbs@overdrive on 2002/05/02 16:59:43 - - aic79xx_osm.h: - Bump version to Alpha 8. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#20 edit - -Change 998 by gibbs@overdrive on 2002/05/02 16:59:16 - - aic79xx_osm.c: - aic79xx_osm.h: - Add options for enabling debugging code. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#19 edit - -Change 997 by gibbs@overdrive on 2002/05/02 16:58:22 - - Config.in: - Add compile time options to control AHD_DEBUG. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#4 edit - -Change 996 by gibbs@aslan on 2002/05/02 16:42:23 - - aic79xx.c: - Put sense and S/G mapping printfs under AHD_DEBUG. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#57 edit - -Change 995 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/02 15:37:38 - - Remove HD_DEBUG block that doesn't compile on Linux and doesn't - make much sense anyways. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#56 edit - -Change 994 by gibbs@overdrive on 2002/05/02 15:34:00 - - scsi_iu.h: - Pull in the latest from FreeBSD. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#3 edit - -Change 993 by gibbs@overdrive on 2002/05/02 15:19:13 - - aic79xx_reg.h: - aic79xx_seq.h: - aic7xxx_reg.h: - aic7xxx_seq.h: - Regenerate firmware for Linux. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#6 edit - -Change 992 by gibbs@aslan on 2002/05/02 15:03:26 - - aic79xx.c: - Save and restore modes in ahd_clear_fifo. - Also reset our long jump address. - - At the beginning of every message loop, - reset LQIPHASE_OUTPKT via LQIRETRY if - this condition is set. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#55 edit - -Change 991 by scottl@scottl-hobbiton-mod_devel_aic79xx on 2002/05/02 12:55:04 - - Document the read streaming config switch - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/Documentation/Configure.help#4 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#3 edit - -Change 990 by gibbs@overdrive on 2002/05/01 22:03:06 - - aic79xx_osm.c: - First pass at read stream user tunables. Still - needs an update to the config file. - - Bump limited tag count to 64. Maxtor drives - still have issues with higher tag counts. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#16 edit - -Change 989 by gibbs@aslan on 2002/05/01 21:29:56 - - aic79xx.seq: - Restore an END_CRITICAL that was lost in the last - revision. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#34 edit - -Change 988 by gibbs@overdrive on 2002/05/01 21:23:18 - - aic79xx.seq: - Remove workarounds that only apply to chips <= A3. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#33 edit - -Change 987 by gibbs@aslan on 2002/05/01 21:19:06 - - aic79xx.c: - Split DFF reseting out of ahd_restart() and into - the routine ahd_clear_fifo(). This allows us to - safely restart the sequencer even if a FIFO has - been allocated to a new transaction. - - Add ahd_clear_fifo() calls as appropriate. - - Don't set PERRORDIS in SEQCTL0. - - Clean out sequencer interrupt codes that - are no longer in use. - - Add a handler for the ENTERING_NONPACK sequencer - interrupt. This is used to handle the message - phases usually related to CRC errors in packetized - connections. - - Clean up saved mode handling. The driver now - keeps the mode state as of when the interrupt - handler was entered in the softc as a separate - variable. ahd_unpause() will now restore these - values whenever it is called. This allows us to - remove several layers of saves and restores of - the mode register. - - Ensure we are in the SCSI mode when cleaning SCSI - interrupts. Some of these clear bits are only - available in that mode. - - Port a few more non-pack sequencer interrupt code - handlers. - - Remove a few non-pack sequencer interrupt code - handlers that don't apply in a non-SCB paging - world. - - Complete framework for handling CRC errors. - - In our busfree handler, clear whichever fifo - was active at the time of the busfree. - - Only force a renegotiation for busfrees in a - non-packetized connection. - - In ahd_clear_critical_sections(), turn off all - of the interrupt enables that might prevent stepping. - Make sure that we unpause the sequencer in its - original mode during the stepping process. - - Rely on ATNO instead of ATNI. - - Handle "expected" busfrees after delivering an - INITIATOR_DET_ERROR message. - - Remove pausing code in the ahd_alloc_scbs() since - we no longer touch the hardware in this routine. - - Add additional AHD_DEBUG logging. - - Correct ahd_index_busy_tcl. The target mask used - to set the SCBPTR was not correct. This broke - non-packetized operations. - - Add code to print out the value of the packetized - failures field in status packets should it be set. - - Have ahd_dump_card_state() report the sequencer's - saved mode, not the current mode. - - aic79xx.h: - Add message handler flags for packetized CRC error - handling. - - Add fields for storing the sequencer's mode pointer - as found before setting any modes in host code. - - Add additional AHD_DEBUG values. - - aic79xx.reg: - Clean up SEQINTCODEs. - - Fix typo in BUSFREE_DFF0: O -> 0 - - aic79xx.seq: - Remove a redundant test for SELDO. - - Workaround missing NONPACKREQ cases by looking - for ATNO and a message phase. - - Move the clearing of SELDO to outside of our - select_out handler's critical section. This - ensures that we don't clear this status while - stepping through a critical section. - - Remove a jmp to await_busfree by moving the - await busfree handler. - - Clear the LONGJMP_ADDR prior to entering the - NONPACK handler. - - aic79xx_inline.h: - Revamp mode pointer routines to allow automatic - restoration of the sequencer's mode pointer when - the sequencer is unpaused. - - Add debug logging for all mode pointer accesses. - aic79xx_pci.c: - Correct the logging of PCI target errors. - - aic79xx_osm.c: - Add DDB hooks for looking at AHD registers. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#54 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#32 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#29 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#32 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#22 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#25 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#8 edit - -Change 986 by gibbs@aslan on 2002/05/01 20:51:55 - - aic7xxx.c: - Force renegotiation if we have an unexpected - busfree with a target just in case the busfree - is due to a negotiation mismatch. - - If the target goes on to a message that should - be handled by the sequencer during a host message - loop, terminate our message loop. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#60 edit - -Change 980 by gibbs@overdrive on 2002/04/25 12:54:54 - - aic79xx_osm.c: - If a device does not support information units as - per its inquiry data, don't attempt to set IUs or - IU related bits in our PPR requests. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#15 edit - -Change 979 by gibbs@aslan on 2002/04/25 11:32:11 - - aic79xx.c: - Force renegotiation on a non-packetized busfree. - - Commonize some devinfo setup in the non-packetized - busfree handler. - - Modify ahd_fetch_devinfo to pull IOWNID and TOWNID - from mode 3. These registers are not valid in - modes 0 and 1. - - Add support for terminating an initiator message - loop early. This is used to return to sequencer - based processing for those messages that the - sequencer usually handles. - - When parsing configuration parameters, manually - disable IU negotiation if the disconnect privledge - is disabled. - - Print out IOWNID, TOWNID and SCSISEQ1 in - ahd_dump_card_state. - - aic79xx_osm.c: - Disable IU_REQs if disconnects are disabled. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#53 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#7 edit - -Change 977 by gibbs@aslan on 2002/04/24 14:54:33 - - aicasm/aicasm.c: - Style nit. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#15 edit - -Change 976 by gibbs@aslan on 2002/04/24 12:43:24 - - aic79xx_inline.h: - Don't attempt to run the TQINFIFO if we are - out of ATIOs with which to service it. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#21 edit - -Change 975 by gibbs@aslan on 2002/04/24 12:42:39 - - ahc_eisa.c: - ahc_pci.c: - Remove DEVINTERFACE stuff that crept in from - my private trees. - - aic7xxx_inline.h: - Correct a big endian issue with large (> 12 byte) - cdb support. - - aic7xxx_osm.c: - Correct another big endian bug having to do with - sense data copying. - - And another big endian bug in the initialization - of SCBs that do not transfer data. - - aic7xxx_osm.h: - Enable byte swapping macros for FreeBSD. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#34 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#4 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_pci.c#3 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#3 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#3 edit - -Change 974 by gibbs@aslan on 2002/04/23 11:14:43 - - aic7xxx.c: - When clearing interrupts, perform a few - ahc_flush_device_writes() calls to ensure - status bits are cleared before any dependent - interrupt status bits. - - Add a comment about proper cleanup of the tqinfifo - under target mode. Special care has to be taken - if we are a twin channel controller. - - Clean up the bus reset logic as it pertains to - target mode. We still need a timer to wait for - the bus reset to fall so as to be completely immune - from "bus reset storms". - - Add a printf indicating that all ATIO resources - have been exhausted if this condition occurs and - we are running in bootverbose mode. - - aic7xxx.seq: - Properly set the synchronous transfer settings upon - resumption of a transaction with the disconnect privledge - disabled in target mode. These connections were always - run in async mode irrespective of the negotiated transfer - rate. - - aic7xxx_inline.h: - Only attempt to run the TQINFIFO if we have ATIOs available - to service any entries that are found. - - aic7xxx_osm.c: - Put target mode diagnostics for transactions without the - disconnect privledge under bootverbose. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#59 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#40 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#33 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#2 edit - -Change 969 by gibbs@overdrive on 2002/04/22 16:46:42 - - aic7xxx_osm.h: - Bump Linux driver to 6.2.7 for chip reset delay. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#79 edit - -Change 967 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/22 11:50:17 - - Note Alpha 7 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#18 edit - -Change 966 by gibbs@overdrive on 2002/04/22 11:46:47 - - aic79xx_reg.h: - aic79xx_seq.h: - Regenerate firmware for Linux. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#5 edit - -Change 965 by gibbs@aslan on 2002/04/22 11:45:24 - - aic79xx.c: - Simplify LQO busfree handling. We now rely on - critical sections in the sequencer to make sure - that the sequencer is outside of the SELDO handler. - This allows us to clean up after the busfree with - one interrupt instead of two. - - Don't muck with the ENBUSFREE bit. The set of the - BUSFREE interrupt is a pulse, so simply clearing - the BUSFREE status is enough to kill the interrupt. - This allows busfree protection for any packetized - connections that might be in progress during the - BUSFREE handler. - - aic79xx.h: - Fix duplicate entries in AHD_BUG definitions. - - aic79xx.reg: - Kill the LQOBUSFREE_TRAP sequencer interrupt. - It is no longer needed. - - aic79xx.seq: - Add critical sections to protect against jumping - to the SELDO handler at the same time the kernel - clears SELDO. - - If an LQOBUSFREE is detected in our SELDO handler, - jmp back to the idle loop so that we exit the - critical section and the kernel can handle the - error. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#52 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#31 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#28 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#31 edit - -Change 964 by gibbs@overdrive on 2002/04/22 00:00:09 - - aic79xx_reg.h: - aic79xx_seq.h: - Regenerate firmware for Linux. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#7 edit - -Change 963 by gibbs@aslan on 2002/04/21 23:58:57 - - aic79xx.seq: - Or in HDMAEN along with PRELOADEN just in - case HDMAENACK is not true at the time we - load a segment. This avoids accidentally - shutting off host transfers. This seems - to avoid the IBM drive issue and doesn't - require extra instructions or busy loops. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#30 edit - -Change 962 by gibbs@overdrive on 2002/04/21 23:24:21 - - aic79xx.c: - occured -> occurred. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#51 edit - -Change 961 by gibbs@overdrive on 2002/04/21 22:19:31 - - aic79xx_reg.h: - aic79xx_seq.h: - Regenerate to latest. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#6 edit - -Change 960 by gibbs@aslan on 2002/04/21 19:49:06 - - aic79xx_pci.c: - Update PCI bus modes to better reflect reality. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#24 edit - -Change 959 by gibbs@overdrive on 2002/04/21 18:44:49 - - aic79xx.seq: - Do not clear ENSELO if there is a pending SELDO - already. We have not yet seen the SELDO, and - we rely on ENSELO set/clear sematics to distinguish - between packetized and non-packetized selections. - - or in IRET rather then use mvi in case some of - the bits in SEQINTCTL matter during interrupt - return. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#29 edit - -Change 958 by gibbs@overdrive on 2002/04/21 17:26:16 - - scsi_iu.h: - Correct off by 1 error. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#2 edit - -Change 957 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/21 00:23:33 - - Indicate Alpha 6 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#17 edit - -Change 956 by gibbs@overdrive on 2002/04/20 23:36:53 - - aic79xx_inline.h: - In ahd_lookup_scb(), guard against tag values - larger than AHD_SCB_MAX. Our array of indexes - in only that large. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#20 edit - -Change 955 by gibbs@overdrive on 2002/04/20 23:28:30 - - aic79xx.c: - Fix logic bug in ahd_abort_scbs(). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#50 edit - -Change 954 by gibbs@overdrive on 2002/04/20 23:27:01 - - aic79xx.c: - Add missing '}'. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#49 edit - -Change 953 by gibbs@overdrive on 2002/04/20 23:25:00 - - aic79xx.c: - Limit abort processing of the busy targets table - to LUNS that are addressable when not packetized. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#48 edit - -Change 951 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/20 21:16:27 - - Add definition for PCIM_SERRESPEN - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#16 edit - -Change 950 by gibbs@overdrive on 2002/04/20 21:06:07 - - aic79xx_osm.c: - Remove call to ahd_search_disc_list() which is no - longer required. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#14 edit - -Change 949 by gibbs@overdrive on 2002/04/20 21:04:55 - - aic79xx_reg.h: - aic79xx_seq.h: - Regenerate firmware for Linux releases. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#5 edit - -Change 948 by gibbs@aslan on 2002/04/20 21:03:26 - - aic79xx.c: - Remove disconnected list handling code as this - product does not use this algorithm. - - Add a routine to determine if we are currently - in a connection that has a packetized agreement. - - Add a routine to switch to the currently active - FIFO's mode. - - Modify unexpected busfree handling for outgoing - packets. LQOBUSFREE is now a pollable status - rather than an interrupt. When the unexpected - busfree interrupt occurs, we simply clear it - if LQOBUSFREE is set. The sequencer will - eventually handle the SELDO and issue a sequencer - interrupt to the host. The host then cleans up - the execution queue and restarts the sequencer. - This avoids the problem of determining just where - the sequencer is executing at the time of the - BUSFREE since the sequencer can drift into the - SELDO handler while the BUSFREE interrupt is working - to pause it. - - Finish the port of the busy target table routines. - This are used during error recovery. - - Start documenting our strategies for handling - CRC errors. The code for this is only partially - completed. - - Tighten up the host message loop. We now have - the sequencer perform the actual reads and writes - to drive our ACK, to reduce the possibility of the - sequencer missing a short lived phase. - - Print out the HADDR and HCNT for both FIFOs - in ahd_dump_card_state(). - - aic79xx.h: - Add better documentation for the TCL format. - - Add a macro for building a TCL from target, - channel and lun, rather than SCSIID and lun. - - Add a bug entry for the issue on the A about - the packetized status bit being flakey. - - Add an SCB flag for recording transmission - errors. This flag should save us if the - target does not properly return status - in response to our initiator detected - error message. - - aic79xx.reg: - Add a new sequencer interrupt for the busfree trap. - - Add bit definition for LQIPHASE_OUTPKT. - - Target message loop definitions. - - aic79xx.seq: - Use ENSELO auto-clearing as the key to determining - if the connection is packetized or not. - - Add support for handling unexpected busfree - events in outgoing command packets. - - If we have already allocated a FIFO when entering - the command phase, this must be a retry. Free - the FIFO and reallocate it to make sure no - state from the previous transfer prevents the - retry from occurring properly. - - Host message loop changes. - - Add a possible workaround for hardware failing - to record the write to HDMAEN. We simply loop - setting this bit until the hardware finally - acknowledges that it is set. The seems to - only be required on SCSI writes to IBM Daytona - drives. More investigation is needed. - - aic79xx_osm.c: - Update for changes in host message loop - handling. - - Remove call to ahd_search_disc_list() that - is nolonger required. - - aic79xx_pci.c: - Add in new bug definitions. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#47 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#30 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#27 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#28 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#23 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#6 edit - -Change 935 by gibbs@aslan on 2002/04/17 10:28:58 - - aic79xx.c: - Perform a 1000us delay after asserting CHIPRST - and prior to touching an card registers. The - delay is not exact due to PCI write buffering - semantics, but it should still be sufficient to - avoid touching chip registers prior to the chip - becoming ready for such accesses. - - Modify ahd_chip_init() to leave the chip in a - paused state in AHD_MODE_SCSI. - - Modify ahd_loadseq() to leave the sequencer paused. - Code that follows such a call must call ahd_restart(). - - Perform a chip reset on every outgoing bus reset - on rev A hardware. - - aic79xx.h: - Add AHD_SCSIRST_BUG. - - aic79xx_inline.h: - Don't reset the channel just prior to panicing due - to a mode assertion. This could cause an infinite - recursion loop if the mode assertion is in - ahd_reset_channel or something it calls. - - aic79xx_pci.c: - Add in scsi bus reset requires chiprst bug to ahd->bugs. - - aic7xxx.c: - Perform a 1000us delay after asserting CHIPRST - and prior to touching an card registers. The - delay is not exact due to PCI write buffering - semantics, but it should still be sufficient to - avoid touching chip registers prior to the chip - becoming ready for such accesses. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#46 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#29 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#19 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#22 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#58 edit - -Change 931 by gibbs@aslan on 2002/04/16 19:19:23 - - aic79xx.c: - Break out post CHIPRST initialization from ahc_init() - so that we can reset the chip for workarounds. - - aic79xx.h: - AHD_PCIX_RST_BUG -> AHD_PCIX_CHIPRST_BUG. - - aic79xx.reg: - Move CMDSIZE_TABLE to the end of our current scratch - ram definitions and initialize it in ahd_chip_init(). - - aic79xx_pci.c: - Pull some PCI initialization code that needs to be - performed after every CHIPRST into aic79xx.c:ahd_chip_init(). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#45 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#28 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#26 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#21 edit - -Change 930 by gibbs@overdrive on 2002/04/15 19:22:04 - - aic79xx_osm.h: - Turn on all debugging code. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#15 edit - -Change 929 by scottl@scottl-hobbiton-linux on 2002/04/15 15:45:29 - - Bump the driver version to ALPHA 5 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#14 edit - -Change 912 by gibbs@aslan on 2002/04/15 13:30:23 - - aic79xx.c: - Style fix. - - Move chip bug bitmap setup into the "chip personality" - handlers. - - Include a bus description in ahd_controller_info(). - - aic79xx.h: - Add a mask for bug workarounds that can be disabled - if we are not in PCI-X mode. - - Add bus_description to our softc. - - aic79xx_pci.c: - Initialize ahd->bus_description. - - Disable PCI-X specitific workarounds when operating - in PCI mode. - - Remove a few workarounds if we are an A4 chip. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#44 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#27 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#20 edit - -Change 905 by gibbs@overdrive on 2002/04/11 22:00:57 - - aic7xxx_osm.h: - Bump to version 6.2.6. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#78 edit - -Change 902 by scottl@scottl-hobbiton-mod_devel1 on 2002/04/10 23:30:00 - - aic79xx.c: - Dump our card state should we encounter an unhandled - SCSIINT. Make the panic message for this case more - explicit too. - - Add a diagnostic for a new PPR Negotiation that should - end in a Busfree. This is the case of a pre-existing - IU_REQ agreement at the time of a Negotiation. - - Dump the card state when we encounter an unexpected busfree. - - Always refresh the neg-table when calling ahd_set_syncrate() - to handle the case of the sequencer setting the ENATNO bit - for a MK_MESSAGE request. We will always renegotiate in that - case if this is a packetized request. - - Correct the logic for setting MSG_FLAG_EXPECT_PPR_BUSFREE. - This should be set in the case of a pre-existing IU_REQ - agreement as well as if the IU_REQ agreement has changed. - - Kill a redundant call to ahd_update_neg_table. - - When dumping card state, also dump platform card state. - - aic79xx_osm.c: - user uint16_t rather than uint8_t for the array of user - settable tag limits. We will eventually allow 512 as - the max. - - Properly propogate sense data in status packets back - to the user. - - Dump card state in the abort and target reset handlers. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#43 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#13 edit - -Change 899 by scottl@scottl-hobbiton-linux on 2002/04/09 16:25:34 - - Remove seeprom_erase - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#14 integrate - -Change 895 by gibbs@overdrive on 2002/04/09 15:17:06 - - aic79xx_host.h: - aic79xx_osm.c: - aic7xxx_host.h: - aic7xxx_osm.c: - Move max_sectors initialization back into osm.c so - that it can be conditionalized on Linux kernel verison. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#91 edit - -Change 894 by scottl@scottl-hobbiton-linux on 2002/04/09 15:16:00 - - Add support for reading and writing the SEEPROM through the - /proc interface. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#40 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#13 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#9 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#37 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#15 integrate - -Change 891 by gibbs@overdrive on 2002/04/09 13:35:39 - - aic79xx_seq.h: - aic79xx_reg.h: - aic7xxx_seq.h: - aic7xxx_reg.h: - Start generating firmware at the toplevel only. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#4 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#4 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#4 edit - -Change 886 by gibbs@overdrive on 2002/04/07 23:42:22 - - aic79xx.c: - Kill debugger calls that are unsupported by Linux. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#42 edit - -Change 884 by gibbs@overdrive on 2002/04/07 21:46:23 - - aicasm/Makefile: - Reverse integration. - Kill .NOTPARALLEL. Use flex's -o. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#12 integrate - -Change 883 by gibbs@aslan on 2002/04/07 21:40:53 - - aic79xx.c: - When handling the "expected" unexpected busfree - after a negotiation, freeze the scb and the device - queue so that ordering is preserved. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#41 edit - -Change 882 by gibbs@aslan on 2002/04/07 21:21:53 - - aic79xx.c: - aic79xx.h: - aic79xx.seq: - Add a workaround for the outstanding split bug. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#40 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#26 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#27 edit - -Change 881 by gibbs@overdrive on 2002/04/07 21:10:53 - - aic79xx.c: - aic7xxx.c: - Kill return argument. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#39 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#57 edit - -Change 880 by gibbs@overdrive on 2002/04/07 21:09:54 - - aic79xx.h: - aic7xxx.h: - Kill return argument. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#25 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#39 edit - -Change 879 by gibbs@overdrive on 2002/04/07 21:06:29 - - aic79xx.c: - aic79xx.h: - aic7xxx.c: - aic7xxx.h: - Add a routine to verify that a softc is still - on our list and configured. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#38 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#24 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#56 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#38 edit - -Change 878 by gibbs@overdrive on 2002/04/07 21:04:35 - - aic79xx_host.h: - aic7xxx_host.h: - Add a missing comma. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#8 edit - -Change 875 by gibbs@overdrive on 2002/04/07 18:16:42 - - aic79xx_host.h: - aic7xxx_host.h: - aic79xx_osm.c - aic7xxx_osm.c - Set "max_sectors" in our host template so that the Linux - SCSI layer doesn't foolishly limit our I/O size. - - Set a few additional static fields into the template - initialization macro. - - aic7xxx_osm_pci.c: - aic79xx_osm_pci.c: - Use ah[dc]_find_softc rather than do a brute force lookup - in multiple places. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#90 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#31 edit - -Change 873 by gibbs@aslan on 2002/04/05 12:29:11 - - aic79xx.c: - Handle a few more sequencer interrupts. - - Monitor sstat3 during SCSIINT handling. - - Remove a duplicate comment. - - Enable checking of negotiation table and output - sync FIFO parity errors. - - When traversing the execution queue, only complain - of list corruption after itterating over max SCB - entries. Since elements can be queued outside of - the per-target lists, the num target limit coult - unintentionally fire. - - Correct a bug in the stitching of the TID lists in - the execution queue. We could lose a whole TID - list in certain scenarios. - - When handling status errors, save and restore the - current mode as well as clear any critical sections - in the firmware. We might otherwise corrupt sequencer - state. - - Add some more information to the ahd_dump_card_state() - output. - - Add a routine to dump out the state of all SCBs. This - might be useful from the debugger. - - aic79xx.h: - Prototype ahd_dump_scbs(). - - aic79xx.seq: - Stop using MK_MESSAGE as a flag for "dead" SCBs. - We should come up with another mechanism, but this - might confuse the cleanup of the execution queue - for SCBs that selected out with atn asserted. - - Use HDMAEN as a definitive test to see if a - saveptr interrupt is for a snapshot or not. - - aic79xx_pci.c: - Add a comma to the table of pci_status_strigs, so we - don't attempt to printf garbage. Oops. - - Clear latched pci status at the end of our PCI error - handler so that the pci error interrupt is de-asserted. - More logic is needed here to handle PCI-X errors. - - aic7xxx.c: - If we have an overrun on an auto-request sense, report - autosense fail, not data-run-error. - - Use AHC_NUM_TARGETS rather than a hard coded 16. - - Fix a typo. - - aic7xxx.reg: - Add a comment to the DIRECTION bit so I can stop - looking it up its polarity in the data book all the time. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#37 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#23 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#25 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#26 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#19 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#55 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#27 edit - -Change 840 by gibbs@overdrive on 2002/03/26 23:33:12 - - p4 integrate -r -b redhat-aic7xxx-2.4.7_10_i386. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#26 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#39 integrate -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#36 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#14 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#9 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#14 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#8 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#2 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#2 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#10 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#13 integrate -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#10 integrate - -Change 839 by gibbs@overdrive on 2002/03/26 23:32:40 - - Integrate -r -b redhat-aic7xxx-2.4.7_10_i386 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#89 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#14 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#3 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#3 branch - -Change 813 by gibbs@overdrive on 2002/03/13 20:18:34 - - aic79xx_osm.h: - Bump version number to 0.0.4 for Alpha 4 release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#13 edit - -Change 800 by gibbs@overdrive on 2002/03/13 14:56:13 - - aic79xx.c: - Remove TRACEPOINT6 code which is no longer used. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#36 edit - -Change 795 by gibbs@overdrive on 2002/03/13 14:39:50 - - aic79xx_osm.h: - Add an implementation for scsi_4btoul(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#12 edit - -Change 791 by gibbs@aslan on 2002/03/13 14:02:50 - - aic79xx.c: - Reset the bus if we encounter an overrun on a - status packet. - - Implement the AHD_CLRLQO_ATUTOCLR_BUG workaround. - We just need to manually clear the CLRLQO registers - when we use them. - - Roll LQISTAT1 handling into the - ahd_handle_transmission_errror(), handler. - - Don't qualify the BUSFREE status with ENBUSFREE. The - chip may well have moved on to an handled another - transaction on the bus, so we simply cannot rely on - ENBUSFREE giving us an acuate sense of whether this - is a true BUSFREE interrupt. Right now we defer - looking at BUSFREE interrupts until last in the hope - that we'll ignore spurious values of this bit by handling - the conditions we are sure of first. - - In handling busfree conditions allow the handler for that - condition to either unpause the sequencer or to force a - sequencer reset. - - Don't rely on the PACKETIZED status bit. It corresponds - to the *last* connection on the bus, not the current one. - Instead rely on LQISTAT1 giving us acurate information - about transmission errors that correspond to packetized - transfers. - - Handle unexpected busfrees that indicate the target - saw a bad CRC in one of our outgoing LQs. - - Add optional debugging information for kernel handled - message phases. - - Fix a spelling error. - - Add loging for QAS messages that occur when they shouldn't. - We will reject the message which should force a busfree. - - Add more bug entries. - - When cleaning up entries from the waiting for selection - queue, handle MK_MESSAGE SCBs specially as they are not - now placed into the per-target-id queues. - - Add more logging for sense packets. - - Link completed SCBs using a different set of link - pointers. This allows us to put the SCBs on the - complete queue without fear of corrupting the waiting - for selection queue if we have yet to see a pending - SELDO. - - Log the contents of the SCSIPHASE register in - ahd_dump_card_state(). - - aic79xx.h: - Add more bug entries. - - Add a debugging flag for printing information during - kernel handled message phases. - - aic79xx.reg: - LQOBUSFREE1 -> LQOBUSFREE - LQOPHACHG1 -> LQOPHACHGINPKT - - CLRLQOBUSFREE1 -> CLRLQOBUSFREE - CLRLQOPHACH1 -> CLRLQOPHCHGINPKT - - ENLQOBUSFREE1 -> ENLQOBUSFREE - ENLQOPHACHG1 -> ENLQOPHACHGINPKT - - LQOPHACHG0 -> LQOPHACHGOUTPKT - - Add SCB_NEXT_COMPLETE link in the CDB pad - area. - - aic79xx.seq: - Queue incoming MK_MESSAGE SCBs separately so as - to ensure we see the MK_MESSAGE bit on the outgoing - selection that will send this SCB. - - Convert all complete queue operations to use the - SCB_NEXT_COMPLETE link. - - Start adding more critical section wrappers. This - work still needs to be augmented and reviewed. - - When selecting out with a SCB that has MK_MESSAGE - set, don't bother clearing NEGPPROPTS. We now - look for the MK_MESSAGE flag in our SELDO handler - and can thus determine that this is actually a - "nonpackreq" selection. - - Add in the workaround for AHD_AUTOFLUSH_BUG. - - Correctly set the transfer size for status packets - so we don't think we've had an overrun. - - Enhance, I hope, the workaround for the PCIX arbiter - hang. We also now install the hang detection for - legacy. - - aic79xx_pci.c: - Take a first shot at handling PCI/PCI-X errors. More - work is required here. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#35 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#22 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#24 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#25 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#18 edit - -Change 779 by gibbs@overdrive on 2002/03/11 17:55:24 - - aic79xx_osm.c: - Disable ABORT and BDR attempts until error recovery - is better fleshed out. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#10 edit - -Change 778 by gibbs@overdrive on 2002/03/11 17:55:02 - - aic79xx_osm.h: - Remove EISA/VL defines that don't apply to the - hardware supported by this driver. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#11 edit - -Change 767 by gibbs@aslan on 2002/03/06 15:10:06 - - aic79xx_pci.c: - Add a #define for the A4 revision number. - - Add a placeholder for the B0 revision number. - - Disable pending PCI REQ assertion on anything - younger than the B0. It doesn't work if both - channels are active. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#17 edit - -Change 765 by gibbs@overdrive on 2002/03/04 21:59:30 - - aic79xx_osm.h: - Bump version number to 0.0.3. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#10 edit - -Change 764 by gibbs@overdrive on 2002/03/04 21:59:14 - - Handle integrate -r from redhat-aic79xx-2.4.7_10_i386 - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#3 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#5 integrate -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#3 integrate - -Change 761 by gibbs@overdrive on 2002/03/04 21:49:07 - - aic79xx.c: - Remove critical section clearing printfs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#34 edit - -Change 759 by gibbs@moria on 2002/03/04 21:36:11 - - aic79xx.c: - In ahd_devlimited_syncrate(), treat the precomp enable - bit specially. This is bit should be acted on regardless - of our goal for having the target precomp for us. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#33 edit - -Change 755 by gibbs@aslan on 2002/03/04 12:59:48 - - aic79xx_pci.c: - Only attach to A3 or newer H2A2 parts. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#16 edit - -Change 754 by gibbs@aslan on 2002/03/04 10:43:45 - - aic79xx.c: - Convert ahd_assert_atn to an inline. - - Add a comment indicating that blindly clearing out the - DMA channels in ahd_restart() is probably a bad thing. - Perhaps the best place to do this is in ahd_abort_scbs() - which should be able to match the SCB owning the FIFO - with the SCB pattern to kill off, but that is not completely - clear yet. - - Add the beginnings of an "illegal non-packetized phase" - handler. This interrupt will be invoked should a target, - with whom we've negotiated packetized, take us to a non-pkt - and non-message phase. The only situation we currently - handle is the case of a target taking us to the command - phase on the first REQ of what should be a packetized - connection. Our response to that condition is: - o Downgrade our current negotiation to async/narrow. - o Embed a TUR into the SCB to replace whatever, - possibly media altering, command was originally - in the SCB. - o Clear any tag information in the SCB and set - MK_MESSAGE. - o Set MSG_OUT to HOST_MSG, SAVED_SCSIID to the - scb's SCSIID, and SAVED_LUN to 0 (no identify - message, so target believes lun is 0). - o Clear the packetized flag in the SCB and set - SCB_ABORT and SCB_CMDPHASE_ABORT. - o assert ATN. - o Prepare the transaction to complete with - CAM_REQUEUE_REQ. - o When the Abort completes, we only abort the - SCB that encountered the error. This behavior - and the actual error code we return should be - reviewed. - - Convert some manual traversals of the phase table to calls - to ahd_lookup_phase_entry(). - - Port the MKMSG_FAILED sequencer interrupt handler. - - If busfreetime is non-zero, but we were performing nonpackreq - recovery, use the ahd_handle-nonpkt_busfree() handler. - - Handle the case of a new PPR negotiation to a target that - we have already negotiated packetized to. We should get - a busfree in this case. The remainder of the handling of - this situation is in the sequencer. - - Correct a bug in the critical section stepping code. We - were in the wrong register window when trying to clear - SIMODE0. - - If we are currently packetized with a target, the only - valid messages we can send at the beginning of the connection - are PPR or TUR. Therefore, supress the identify messages. - - Create a msg_flags field in ahd_softc. This replaces - msg_expect_ppr_busfree since we need to also record - whether the state of IU_REQ changed. - - Fix a grammer bug. - - Clear all message flags in the SCB during a request sense - that only intends to renegotiate with the device. - - Kill a debugging printf. - - Display the contents of SIMODE1, OPTIONMODE and MAXCMDCNT - during ahd_dump_card_state(). - - aic79xx.h: - Make AHD_SENSE_BUFSIZE a sequencer visible value. - - Redefine our Hardware SCB format so we can embed a - sense address in the case of cdbs <= 12 bytes or using - a pointer. - - Add the SCB_CMDPHASE_ABORT flag. - - Add ahd_msg_flags. - - aic79xx.reg: - Document the DIRECTION bit in DFCNTRL. - - Redefine our Hardware SCB format so we can embed a - sense address in the case of cdbs <= 12 bytes or using - a pointer. - - Make AHD_SENSE_BUFSIZE a sequencer visible value. - aic79xx.seq: - When we are about to select a device and the first SCB - has MK_MESSAGE set, make sure to enable ENAUTOATNO. - - Treat LQOPHACHG1 as an unexpected_nonpkt_phase. - - Make the PCI-X workaround for the hung arbiter even - more selective in the legacy case. We only need to - check for the hang condition if we are disconnecting - in the middle of a transfer. - - Enhance a comment about BITBUCKET handling in the - non-pack case. - - Correct a lable jump that should have been changed in - the last commit to this file. The previous lable has - been removed. - - Add support for handling a status packet without host - intervention if the sense address is embedded in the - SCB. - - aic79xx_inline.h: - Embed the sense address in the SCB if there is room. - - aic79xx_pci.c: - Be more careful about endianess when printing out - serial eeprom contents. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#32 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#21 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#23 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#24 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#18 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#15 edit - -Change 697 by gibbs@overdrive on 2002/02/26 17:49:44 - - aic79xx.c: - aic79xx.h: - aic79xx.reg: - aic79xx.seq: - aic79xx_pci.c: - Integrate changes from redhat-aic7xxx-2.4.7_10_i386 - back into the core files. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#31 integrate -... //depot/aic7xxx/aic7xxx/aic79xx.h#20 integrate -... //depot/aic7xxx/aic7xxx/aic79xx.reg#22 integrate -... //depot/aic7xxx/aic7xxx/aic79xx.seq#23 integrate -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#14 integrate - -Change 673 by gibbs@overdrive on 2002/02/11 16:36:16 - - aic79xx_osm.h: - Bump driver version to 0.0.2. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#9 edit - -Change 671 by gibbs@overdrive on 2002/02/11 16:28:09 - - aic7xxx_pci.c: - Pretend that there are no cables if we have - an illegal cable configuration. This may fix - problems on certain HP Kayak systems. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#35 edit - -Change 668 by gibbs@overdrive on 2002/02/11 15:13:10 - - aic79xx.reg: - aic79xx.seq: - Convert to text+ko - - aic79xx_pci.c: - Avoid endian issues when dumping the seeprom. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.reg#21 integrate -... //depot/aic7xxx/aic7xxx/aic79xx.seq#22 integrate -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#13 edit - -Change 667 by gibbs@aslan on 2002/02/11 15:09:27 - - aic79xx.c: - Add additional bug entries for Rev A errata. - - Don't attempt to perform current sensing on a - board unless we know that it is supported. Doing - current sensing when it is not support messes up - our external termination. - - Leave the force U160 stuff in place, but allow - U320 transfers now. - - Don't attempt QAS or read streaming on A2 hardware. - - aic79xx.h: - Add more bug entries. - - aic79xx.seq: - Add comment about why we have to check SEDO when - ENSELO is clear but prior to starting a new selection. - - Add critical sections around some of the places they - are needed. - - Add a first cut workaround for one of the PCI-X bugs. - This particular bug is fixed in A3. - - Conditionalize the last bit of the CURRSCB workaround. - - Set the SCB_DMA flag when we initiate an SCB dma. This - is the beginning of work to handle cancled DMAs from - the qinfifo. - - aic79xx_pci.c: - Only do current sensing if the card supports it. - - Truely initialize termctl if auto-term sensing fails. - - Set the low primary termination prior to setting any - external termination. This mirrors what CHIM does. - - Add a mode assert to ahd_write_flexport. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#30 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#19 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#21 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#12 edit - -Change 663 by gibbs@overdrive on 2002/02/11 13:13:52 - - aic7xxx_osm.h: - Bump Linux aic7xxx driver version number to 6.2.5. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#77 edit - -Change 661 by gibbs@overdrive on 2002/02/11 13:11:36 - - aicasm/Makfile: - Bring .NOTPARALLEL change into the top level. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#11 integrate - -Change 657 by scottl@scottl-linux on 2002/02/06 19:17:16 - - Serialize Makefiles. Use CONFIG_AIC79XX_BUILD_FIRMWARE flag. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#2 edit -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/Makefile#2 edit - -Change 650 by gibbs@overdrive on 2002/01/28 17:35:10 - - aic79xx_osm.c: - Limit tag depth to 16 under Linux to avoid QUEUE_FULL - issues with Maxtor drives. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#9 edit - -Change 648 by gibbs@overdrive on 2002/01/28 17:29:46 - - aic79xx.c: - Correct typo. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#29 edit - -Change 647 by gibbs@overdrive on 2002/01/28 17:22:18 - - aic79xx.c: - Move more diagnostic printfs under AHD_DEBUG. - - Force 160 as the maximum sync speed until 320 - issues are ironed out. - - aic79xx_pci.c: - Kill some diagnostic printfs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#28 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#11 edit - -Change 646 by gibbs@overdrive on 2002/01/28 17:18:52 - - aic79xx_osm.h: - Bump Linux version number to for 0.0.1 release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#8 edit - -Change 644 by gibbs@overdrive on 2002/01/28 16:43:03 - - aic79xx_osm.c: - Remove reference to ahc->seltime_b. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#8 edit - -Change 643 by gibbs@aslan on 2002/01/28 15:18:56 - - aic79xx.c: - aic79xx.h: - aic79xx.reg: - aic79xx.seq: - aic79xx_inline.h: - aic79xx_pci.c: - First pass at NONPACKREQ and CRC error handling. - - Turn on digital filtering and some additional IOCELL - workarounds. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#27 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#18 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#20 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#20 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#17 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#10 edit - -Change 640 by gibbs@aslan on 2002/01/27 14:15:43 - - aic79xx.c: - aic79xx.h: - aic79xx.reg: - Correct the selection timeout period on Rev A - parts where it is twice as long as the set value. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#26 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#17 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#19 edit - -Change 639 by gibbs@aslan on 2002/01/26 19:39:29 - - aic79xx.c: - Remove debugging printfs and place others inside - AHD_DEBUG statements. - aic79xx.h: - aic79xx_pci.c: - Complete support for termination current sensing. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#25 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#16 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#9 edit - -Change 637 by gibbs@overdrive on 2002/01/25 14:07:51 - - Firmware is generated in the leaf branch nodes. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#3 delete - -Change 626 by gibbs@overdrive on 2002/01/25 12:55:44 - - Remove extra blank line. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#76 edit - -Change 623 by gibbs@overdrive on 2002/01/25 12:48:59 - - Add text+ko and finish cleanup of no_probe. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#2 edit - -Change 621 by gibbs@overdrive on 2002/01/25 12:39:17 - - aic79xx_osm.h: - aic7xxx_osm.h: - linux/malloc.h has been deprecated in 2.4.15. Use - linux/slab.h instead which has been available since 2.4.0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#75 edit - -Change 615 by gibbs@overdrive on 2002/01/24 17:27:58 - - aic79xx_osm.c: - Lose references to EISA and VLB inherited from - aic7xxx driver. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#6 edit - -Change 608 by gibbs@overdrive on 2002/01/24 13:32:31 - - To keep IDs coherent, we'll generate these in each branch we - ship to customers. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#2 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#2 delete - -Change 603 by gibbs@overdrive on 2002/01/24 13:00:46 - - Add assembled aic79xx firmware to revision control. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_reg.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_seq.h#1 add - -Change 601 by gibbs@overdrive on 2002/01/24 12:57:18 - - Add assembled firmware to revision control. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_reg.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_seq.h#1 add - -Change 587 by gibbs@overdrive on 2002/01/23 14:36:02 - - aic7xxx_osm.c: - Integrate PROBE_VL config changes back into Linux - driver mainline. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#88 integrate - -Change 580 by gibbs@overdrive on 2002/01/22 22:13:15 - - Integrate from linux-aic7xxx-2.4.0 -> linux-aic79xx-2.4.0 - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd640.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7770_osm.c#2 integrate -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.c#2 integrate - -Change 578 by gibbs@overdrive on 2002/01/22 21:48:24 - - aic7xxx_osm.c: - Protect against config not defining CONFIG_AIC7XXX_PROBE_EISA_VL - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#87 edit - -Change 576 by gibbs@overdrive on 2002/01/22 21:42:02 - - aic7770_osm.c: - Don't refer to aic7xxx_no_probe. The check for - whether to perform EISA/VL probes was made prior - to the call to the EISA/VL probe. - - aic7xxx_osm.c: - Add a configuration option for EISA/VL probing. - It will default to off to avoid clobbering PCI - devices that frequest those I/O ranges. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#86 edit - -Change 575 by gibbs@overdrive on 2002/01/22 21:34:25 - - aic7xxx_osm.c: - Default to not scanning for EISA/VL adapters. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#85 edit - -Change 569 by gibbs@aslan on 2002/01/22 13:56:22 - - aic79xx.c: - Clean up warnings related to currently disabled code. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#24 edit - -Change 568 by gibbs@overdrive on 2002/01/22 13:49:27 - - aic79xx_osm.h: - Include scsi_iu.h. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#5 edit - -Change 567 by gibbs@aslan on 2002/01/22 13:46:00 - - aic79xx.c: - Remove call to Debugger() which is not supported - under Linux. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#23 edit - -Change 566 by gibbs@overdrive on 2002/01/22 13:43:07 - - Initial aic79xx port to 2.4.0. - -Affected files ... - -... //depot/linux-aic79xx-2.4.0/COPYING#1 branch -... //depot/linux-aic79xx-2.4.0/CREDITS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/BUG-HUNTING#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/Changes#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/CodingStyle#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/Configure.help#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DMA-mapping.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/kernel-api.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/kernel-hacking.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/kernel-locking.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/mcabook.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/mousedrivers.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parport-multi.fig#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parport-share.fig#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parport-structure.fig#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/parportbook.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/sis900.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/via-audio.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/videobook.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/wanbook.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/DocBook/z8530book.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/IO-mapping.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/IRQ-affinity.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/LVM-HOWTO#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/README.DAC960#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/README.moxa#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/SubmittingDrivers#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/SubmittingPatches#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/VGA-softcursor.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/Netwinder#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Assabet#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Brutus#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/CERF#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/GraphicsClient#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Itsy#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/LART#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/PLEB#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Pangolin#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Tifon#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/Victor#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/empeg#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/nanoEngine#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/SA1100/serial_UART#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/Setup#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/empeg/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/empeg/ir.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/empeg/mkdevs#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/NOTES#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/README.FPE#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/arm/nwfpe/TODO#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/binfmt_misc.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cachetlb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cciss.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/aztcd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/cdrom-standard.tex#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/cdu31a#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/cm206#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/gscd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/ide-cd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/isp16#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/mcd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/mcdx#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/optcd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/sbpcd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/sjcd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cdrom/sonycd535#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/computone.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/cpqarray.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/devices.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/digiboard.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/digiepca.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/dnotify.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/exception.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/aty128fb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/clgenfb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/framebuffer.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/internals.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/matroxfb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/modedb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/sa1100fb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/tgafb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/fb/vesafb.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/Locking#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/adfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/affs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/bfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/coda.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/cramfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/ToDo#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/boot-options#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/devfs/rc.devfs#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ext2.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/fat_cvf.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/hpfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/isofs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ncpfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ntfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/proc.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/romfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/smbfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/sysv-fs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/udf.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/ufs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/umsdos.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/vfat.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/filesystems/vfs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/floppy.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/ftape.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/hayes-esp.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/highuid.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/dev-interface#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/functionality#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/i2c-protocol#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/proc-interface#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/smbus-protocol#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/summary#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/ten-bit-addresses#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i2c/writing-clients#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i386/IO-APIC.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i386/boot.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/i386/zero-page.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/ia64/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/ia64/efirtc.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/ide.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/initrd.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/ioctl-number.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isapnp.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/CREDITS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/HiSax.cert#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/INTERFACE#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/INTERFACE.fax#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.FAQ#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.HiSax#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.act2000#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.audio#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.avmb1#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.concap#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.diversion#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.eicon#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.fax#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.hfc-pci#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.hysdn#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.icn#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.pcbit#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.sc#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.syncppp#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/README.x25#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/isdn/syncPPP.FAQ#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/java.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/joystick-api.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/joystick-parport.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/joystick.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/bug-list.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/commands.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/config-language.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kbuild/makefiles.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kernel-doc-nano-HOWTO.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kernel-docs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kernel-parameters.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/kmod.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/locks.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/logo.gif#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/logo.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/m68k/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/m68k/README.buddha#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/m68k/kernel-options.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/magic-number.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/mandatory.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/mca.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/md.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/memory.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/mkdev.cciss#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/mkdev.ida#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/modules.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/moxa-smartio#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/mtrr.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/nbd.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/3c505.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/6pack.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/8139too.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/Configurable#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/DLINK.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/PLIP.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/README.sb1000#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/alias.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/arcnet-hardware.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/arcnet.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/atm.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ax25.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/baycom.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/bridge.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/comx.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/cops.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/cs89x0.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/de4x5.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/decnet.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/depca.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/dgrs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/dmfe.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/eql.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ethertap.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ewrk3.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/filter.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/fore200e.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/framerelay.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ip-sysctl.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ip_dynaddr.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ipddp.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/iphase.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/irda.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/lapb-module.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ltpc.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/multicast.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ncsa-telnet#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/net-modules.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/netdevices.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/olympic.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/policy-routing.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/pt.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/ray_cs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/routing.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/shaper.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/sis900.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/sk98lin.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/skfp.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/smc9.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/smctr.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/soundmodem.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/tcp.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/tlan.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/tms380tr.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/tulip.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/tuntap.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/vortex.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/wan-router.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/wanpipe.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/wavelan.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/x25-iface.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/x25.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/networking/z8530drv.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/nfsroot.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/nmi_watchdog.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/oops-tracing.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/paride.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/parisc/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/parisc/IODC.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/parisc/debugging#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/parisc/mm#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/parisc/registers#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/parport-lowlevel.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/parport.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/pci.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/pcwd-watchdog.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/pm.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/00-INDEX#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/SBC8260_memory_mapping.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/ppc_htab.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/smp.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/sound.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/powerpc/zImage_layout.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/ramdisk.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/riscom8.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/rtc.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/s390/DASD#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/s390/cds.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/scsi-generic.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/scsi.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/serial-console.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sgi-visws.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/smart-config.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/smp.tex#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/smp.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/AD1816#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/ALS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/AWE32#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/AudioExcelDSP16#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/CMI8330#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/CMI8338#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/CS4232#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/ChangeLog.awe#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/ChangeLog.multisound#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/ESS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/ESS1868#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/INSTALL.awe#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/Introduction#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/MAD16#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/Maestro#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/MultiSound#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/NEWS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/NM256#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/OPL3#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/OPL3-SA#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/OPL3-SA2#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/Opti#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/PAS16#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/PCM1-pro#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/PSS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/PSS-updates#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.OSS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.awe#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.modules#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/README.ymfsb#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/SoundPro#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/Soundblaster#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/Tropez+#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/VIA-chipset#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/VIBRA16#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/Wavefront#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/es1370#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/es1371#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/mwave#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/solo1#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/sonicvibes#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/ultrasound#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/via82cxxx.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sound/vwsnd#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sparc/sbus_drivers.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/specialix.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/spinlocks.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/stallion.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/svga.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sx.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/fs.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/kernel.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/sunrpc.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sysctl/vm.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/sysrq.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/telephony/ixj.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/unicode.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/CREDITS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/URB.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/acm.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/bluetooth.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/dc2xx.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/error-codes.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/hotplug.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/ibmcam.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/input.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/ohci.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/ov511.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/proc_usb_info.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/rio.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/scanner-hp-sane.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/scanner.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/uhci.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/usb-help.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/usb/usb-serial.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/API.html#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/CQcam.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/README.buz#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/README.cpia#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/CARDLIST#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/CONTRIBUTORS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/ICs#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Insmod-options#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/MAKEDEV#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Modules.conf#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/PROBLEMS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/README#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/README.WINVIEW#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Sound-FAQ#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/Specs#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/bttv/THANKS#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/radiotrack.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/video4linux/zr36120.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/vm/balance#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/vm/locking#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/vm/numa#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/watchdog.txt#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/xterm-linux.xpm#1 branch -... //depot/linux-aic79xx-2.4.0/Documentation/zorro.txt#1 branch -... //depot/linux-aic79xx-2.4.0/MAINTAINERS#1 branch -... //depot/linux-aic79xx-2.4.0/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/README#1 branch -... //depot/linux-aic79xx-2.4.0/REPORTING-BUGS#1 branch -... //depot/linux-aic79xx-2.4.0/Rules.make#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/bootloader.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/bootp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/tools/mkbb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/boot/tools/objstrip.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/alpha_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/check_asm.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_apecs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_cia.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_irongate.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_lca.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_mcpcia.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_polaris.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_t2.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_titan.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_tsunami.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/core_wildfire.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/es1888.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_alpha.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_i8259.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_impl.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_pyxis.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/irq_srm.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/machvec_impl.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/ns87312.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/osf_sys.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/pci_impl.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/pci_iommu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/proto.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/smc37c669.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/smc37c93x.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_alcor.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_cabriolet.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_dp264.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_eb64p.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_eiger.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_jensen.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_miata.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_mikasa.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_nautilus.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_noritake.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_rawhide.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_ruffian.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_rx164.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_sable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_sio.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_sx164.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_takara.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_titan.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/sys_wildfire.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/callback_srm.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/checksum.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/clear_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/copy_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/csum_ipv6_magic.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/csum_partial_copy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/divide.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-clear_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-copy_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-csum_ipv6_magic.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-divide.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-memchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-strncpy_from_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-stxcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev6-stxncpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strcat.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strlen.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strncat.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/ev67-strrchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/fpreg.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memcpy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memmove.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/srm_printk.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/srm_puts.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stackcheck.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stackkill.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stacktrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strcasecmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strcat.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strlen.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strncat.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strncpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strncpy_from_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/strrchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stxcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/lib/stxncpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/math.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/qrnnd.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/math-emu/sfp-util.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/alpha/vmlinux.lds.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/bootp/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/bootp/bootp.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/bootp/init.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/Makefile.debug#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-ftvpci.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-l7200.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-netwinder.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head-sa1100.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/hw-bse.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/ll_char_wr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/setup-sa1100.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/compressed/vmlinux.lds.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/boot/install.sh#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/a5k#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/assabet#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/brutus#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/cerf#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/clps7500#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/ebsa110#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/empeg#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/footbridge#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/graphicsclient#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/integrator#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/lart#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/lusl7200#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/neponset#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/pangolin#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/rpc#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/shark#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/sherman#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/def-configs/victor#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/arch.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/armksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/arthur.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/bios32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/calls.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/debug-armo.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/debug-armv.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dec21285.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-arc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-footbridge.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-isa.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma-rpc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ecard.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/entry-armo.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/entry-armv.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/entry-common.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/fiq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ftv-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/head-armo.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/head-armv.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/isa.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/leds-ebsa110.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/leds-ftvpci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/oldlatches.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/plx90x0.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/sys_arm.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/time-acorn.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/kernel/via82c505.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/backtrace.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/changebit.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/clearbit.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/copy_page.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumipv6.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumpartial.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumpartialcopy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/csumpartialcopyuser.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/delay.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/ecard.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/extractconstants.pl#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/findbit.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/floppydma.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/getconsdata.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-acorn.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-pcio.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsb.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsl.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsw-armv3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-readsw-armv4.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-shark.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesb.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesl.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesw-armv3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io-writesw-armv4.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/memzero.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/setbit.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strncpy_from_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strnlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/strrchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/testchangebit.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/testclearbit.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/testsetbit.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/uaccess-armo.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/lib/uaccess.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/arch.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/cats-hw.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/cats-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/ebsa285-leds.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/ebsa285-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/netwinder-hw.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/netwinder-leds.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/netwinder-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-footbridge/personal-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/arch.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/hw.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-sa1100/leds.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/arch.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/mm.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mach-shark/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/consistent.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/fault-armo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/fault-armv.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/fault-common.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/ioremap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-armo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-armv.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-clps7500.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-ebsa110.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-footbridge.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-l7200.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-nexuspci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-rpc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-sa1100.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/mm-tbox.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm2,3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm6,7.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm720.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-arm920.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-sa110.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/proc-syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/mm/small_page.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/ARM-gcc.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/config.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/double_cpdo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/entry26.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/extended_cpdo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11.inl#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11_cpdo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11_cpdt.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpa11_cprt.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpmodule.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpmodule.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpmodule.inl#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpopcode.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpopcode.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/fpsr.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/milieu.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/single_cpdo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat-macros#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat-specialize#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/nwfpe/softfloat.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/tools/gen-mach-types#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/tools/mach-types#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/vmlinux-armo.lds.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/arm/vmlinux-armv.lds.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/bootsect.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/compressed/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/compressed/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/compressed/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/install.sh#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/setup.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/tools/build.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/boot/video.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/apic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/apm.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/bluesmoke.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/cpuid.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/dmi_scan.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/i386_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/i387.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/i8259.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/io_apic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/ioport.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/ldt.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/mca.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/microcode.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/mpparse.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/msr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/mtrr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-i386.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-i386.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-pc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/pci-visws.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/smpboot.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/sys_i386.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/trampoline.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/visws_apic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/kernel/vm86.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/checksum.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/dec_and_lock.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/delay.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/getuser.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/iodebug.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/memcpy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/mmx.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/old-checksum.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/putuser.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/lib/usercopy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/README#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/control_w.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/div_Xsig.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/div_small.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/errors.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/exception.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_arith.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_asm.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_aux.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_emu.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_entry.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_etc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_proto.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_system.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_tags.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/fpu_trig.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/get_address.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/load_store.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/mul_Xsig.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_2xm1.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_atan.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_l2.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_sin.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/poly_tan.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/polynom_Xsig.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_add_sub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_compare.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_constant.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_constant.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_convert.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_divide.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_ld_str.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_mul.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_norm.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_round.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_add.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_div.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_mul.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/reg_u_sub.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/round_Xsig.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/shr_Xsig.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/status_w.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/version.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/wm_shrx.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/math-emu/wm_sqrt.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/mm/ioremap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/i386/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/boot/bootloader.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/boot/bootloader.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/dig/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/dig/machvec.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/dig/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_machvec.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/hp/hpsim_ssc.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/binfmt_elf32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_support.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/ia32_traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/ia32/sys_ia32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/acpi.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/brl_emu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/efi.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/efi_stub.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/entry.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/fw-emu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/gate.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/ia64_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/iosapic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/irq_ia64.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/irq_sapic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/ivt.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/machvec.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/mca.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/mca_asm.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/minstate.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/pal.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/palinfo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/perfmon.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/sal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/smpboot.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/sys_ia64.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unaligned.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unwind.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unwind_decoder.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/kernel/unwind_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/checksum.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/clear_page.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/clear_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/copy_page.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/copy_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/csum_partial_copy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/do_csum.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/flush.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/idiv32.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/idiv64.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strlen.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strncpy_from_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/strnlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/lib/swiotlb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/mm/tlb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/README#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fpmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fpmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fprom.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fpromasm.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/fw-emu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/fprom/runsim#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/alenlist.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/cdl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/devsupport.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/eeprom.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hcl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hcl_util.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hubdev.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/hubspc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/invent.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ip37.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/klconflib.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/klgraph.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/klgraph_hack.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/l1.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/l1_command.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/labelcl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/mem_refcnt.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ml_SN_init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ml_SN_intr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/ml_iograph.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/module.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pci_bus_cvlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pci_dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pcibr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/pciio.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/sgi_if.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/sgi_io_init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/sgi_io_sim.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/stubs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/xbow.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/xswitch.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/io/xtalk.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/discontig.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/iomv.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/llsc4.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/llsc4.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/machvec.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/mm.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/sn1_asm.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/sn1/synergy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/sn/tools/make_textsym#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/tools/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/tools/print_offsets.awk#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/tools/print_offsets.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ia64/vmlinux.lds.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/amiga_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/amiints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/amisound.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/chipram.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/cia.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/amiga/pcmcia.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/dn_debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/apollo/dn_ints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/ataints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atakeyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atari_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atasound.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/atasound.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/hades-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/joystick.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/stdma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/stram.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/atari/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/bvmeints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/bvme6000/rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/README#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/bindec.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/binstr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/bugfix.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/decbin.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/do_func.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/fpsp.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/gen_except.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/get_op.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/kernel_ex.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/res_func.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/round.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sacos.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sasin.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/satan.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/satanh.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/scale.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/scosh.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/setox.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sgetem.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sint.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/skeleton.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/slog2.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/slogn.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/smovecr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/srem_mod.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/ssin.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/ssinh.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/stan.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/stanh.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/sto_res.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/stwotox.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/tbldo.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/util.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_bsun.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_fline.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_operr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_ovfl.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_snan.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_store.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_unfl.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_unimp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/fpsp040/x_unsupp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/README.hp300#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/hil.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/hp300map.map#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/ints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/ints.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/reboot.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/hp300/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/CHANGES#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/MISC#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/README#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/TEST.DOC#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fplsp.doc#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fplsp.sa#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fpsp.doc#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fpsp.sa#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/fskeleton.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/ftest.sa#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/ilsp.doc#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/ilsp.sa#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/iskeleton.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/isp.doc#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/isp.sa#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/itest.sa#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/os.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/pfpsp.sa#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/README-SRC#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/fplsp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/fpsp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/ftest.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/ilsp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/isp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/itest.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/ifpsp060/src/pfpsp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/bios32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/ints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/m68k_defs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/m68k_defs.head#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/m68k_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/sun3-head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/sys_m68k.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/ashldi3.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/ashrdi3.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/checksum.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/lshrdi3.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/memcmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/memcpy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/memset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/muldi3.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/lib/semaphore.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/baboon.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/bootparse.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/iop.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/mac_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/mac_penguin.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/macboing.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/macints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/oss.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/psc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mac/via.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_arith.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_arith.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_cond.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_decode.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_emu.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_log.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_move.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_movem.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_scan.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_trig.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_trig.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/fp_util.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/math-emu/multi_arith.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/hwtest.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/kmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/motorola.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mm/sun3mmu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme147/147ints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme147/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme147/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/16xints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/mvme16x_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/mvme16x/rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/README#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/q40/q40ints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/dvma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/idprom.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/intersil.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/leds.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/mmu_emu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/prom/printf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/sbus.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/sun3_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3/sun3ints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/dvma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/sbus.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/sun3x/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/tools/amiga/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/tools/amiga/dmesg.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/vmlinux-sun3.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/m68k/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/.gdbinit#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/algor/README#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/cmdline.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/env.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/identify.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/printf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/salone.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/arc/tree.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/baget.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/bagetIRQ.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/balo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/balo_supp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/ld.script.balo#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/print.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/prom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/prom/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/vacserial.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/baget/wbflush.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/boot/addinitrd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/boot/ecoff.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/boot/elf2ecoff.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/boot/mkboot.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/cobaltscc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/diagdefs.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/hw-access.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/int-handler.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/via.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/cobalt/z8530.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/int-handler.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/nile4.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/pci-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/prom.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ddb5074/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/boot/decstation.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/boot/ld.ecoff#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/int-handler.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/cmdline.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/dectypes.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/identify.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/locore.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/prom/prom.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/promcon.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/rtc-dec.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/serial.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/dec/wbflush.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-cobalt#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-decstation#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-ip22#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-orion#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/defconfig-rm200#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/floppy-jazz.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/int-handler.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/jazzdma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/kbd-jazz.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/rtc-jazz.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/jazz/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/branch.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/fpe.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/gdb-low.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/gdb-stub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/ioport.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/ipc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irix5sys.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixelf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixinv.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irixsig.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/mips_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r2300_fpu.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r2300_misc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r2300_switch.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r4k_fpu.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r4k_misc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r4k_switch.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/r6000_fpu.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/scall_o32.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/softfp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/syscall.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/syscalls.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/sysirix.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/sysmips.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/unaligned.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/kernel/vm86.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ld.script.big#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/ld.script.little#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/csum_partial.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/csum_partial_copy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/dump_tlb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/floppy-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/floppy-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/ide-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/ide-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/kbd-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/kbd-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/r3k_dump_tlb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/rtc-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/rtc-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/strlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/strncpy_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/strnlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/tinycon.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/lib/watch.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/andes.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/loadmmu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/r2300.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/r4xx0.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/mm/umap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/int-handler.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/ld.script.orion#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/no_initrd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/piggyback.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/promcon.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/orion/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indyIRQ.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_hpc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_int.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_mc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_sc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/indy_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/promcon.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/system.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sgi/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/int-handler.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/pcimt_scache.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/sni/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/tools/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips/tools/offset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/cmdline.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/env.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/identify.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/printf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/salone.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/arc/tree.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/defconfig-ip22#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/defconfig-ip27#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/binfmt_elf32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/branch.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/ioctl32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/linux32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/mips64_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_cache.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_fpu.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_genex.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_switch.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_tlb.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_tlb_debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/r4k_tlb_glue.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/scall_64.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/scall_o32.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/signal32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/softfp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/syscall.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/kernel/unaligned.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/ld.script.elf32.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/ld.script.elf64#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/csum_partial.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/csum_partial_copy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/dump_tlb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/floppy-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/floppy-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/ide-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/ide-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/kbd-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/kbd-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/rtc-no.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/rtc-std.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/strlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/strncpy_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/strnlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/lib/watch.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/andes.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/loadmmu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/r4xx0.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/mm/umap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-berr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-hpc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-int.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-irq.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-mc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-sc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/ip22-timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/system.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip22/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/TODO#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-berr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-irq-glue.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-klconfig.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-klnuma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-nmi.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-pci-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-reset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/sgi-ip27/ip27-timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/tools/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/mips64/tools/offset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/entry_hpux.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/fs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/gate.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/sys_hpux.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/hpux/wrappers.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/cache.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/ccio-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/ccio-rm-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/drivers.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/hardware.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/hpmc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/inventory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/iosapic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/iosapic_private.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/keyboard.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/lasimap.map#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/lba_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/led.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pa7300lc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/parisc_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pci-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pdc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/pdc_cons.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/real1.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/real2.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/sba_iommu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/sys_parisc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/syscall.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/bitops.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/checksum.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/lib/lusercopy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/kmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/pa11.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/mm/pa20.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/tools/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/tools/offset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/parisc/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/commproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/enet.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/fcc_enet.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8260_io/uart.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/commproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/commproc.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/enet.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/fec.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/8xx_io/uart.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/amiga_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/amiints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/amisound.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/bootinfo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/chipram.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/cia.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/ints.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/pcmcia.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/amiga/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/iso_font.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/kbd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/mkprep.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/ns16550.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/ns16550.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/of1275.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/of1275.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/offset#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/size#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/boot/vreset.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/addnote.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/crt0.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/misc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/mknote.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/no_initrd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/piggyback.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/chrpboot/start.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/chrpmain.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/coffcrt0.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/coffmain.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/crt0.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/dummy.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/hack-coff.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/ld.script#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/misc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/mknote.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/no_initrd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/nonstdio.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/piggyback.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/rs6000.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/start.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/string.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/zlib.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/coffboot/zlib.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/apus_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/bseip_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/common_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/est8260_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/gemini_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/mbx_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/oak_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/rpxcllf_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/rpxlite_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/configs/walnut_defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/align.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/apus_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/bitops.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/checks.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/chrp_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/chrp_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/chrp_time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/feature.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/find_name.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/galaxy_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/gemini_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/gemini_prom.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/gemini_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/hashtable.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/head_4xx.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/head_8xx.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/i8259.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/i8259.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/idle.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/indirect_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/local_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/m8260_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/m8xx_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/misc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/mk_defs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/mol.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/oak_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/oak_setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/open_pic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/open_pic.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pci-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_backlight.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_nvram.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_pic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_pic.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/pmac_time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc-stub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc4xx_pic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc4xx_pic.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8260_pic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8260_pic.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8xx_pic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc8xx_pic.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_asm.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_asm.tmpl#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_defs.head#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_htab.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ppc_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_nvram.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prep_time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/prom.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/qspan_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/residual.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/sleep.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/softemu8xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/syscalls.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/walnut_setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/walnut_setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/xics.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/kernel/xics.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/checksum.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/locks.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/strcase.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/lib/string.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/double.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fabs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fadd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fadds.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fcmpo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fcmpu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fctiw.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fctiwz.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fdiv.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fdivs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmadd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmadds.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmsub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmsubs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmul.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fmuls.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnabs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fneg.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmadd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmadds.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmsub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fnmsubs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fres.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/frsp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/frsqrte.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsel.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsqrt.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsqrts.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/fsubs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/lfd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/lfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/math.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mcrfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mffs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsb0.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsb1.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/mtfsfi.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-1.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-2.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-4.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/op-common.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/sfp-machine.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/single.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/soft-fp.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/stfd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/stfiwx.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/stfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/types.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/math-emu/udivmodti4.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/embed_config.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/gzimage.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/head_8260.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/iic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/m8260_tty.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/m8xx_tty.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/offset#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/qspan_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/rdimage.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/size#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mbxboot/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/4xx_tlb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/4xx_tlb.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/mem_pieces.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/mm/mem_pieces.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/crt0.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/elf.pl#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/irSect.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/irSect.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/ld.script#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/misc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/mkevimg#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/treeboot/mkirimg#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/adb.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ansidecl.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/nonstdio.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ppc-dis.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ppc-opc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/ppc.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/privinst.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/setjmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/start.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/start_8xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/subr_prf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/ppc/xmon/xmon.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/boot/ipldump.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/boot/ipleckd.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/boot/iplfba.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/bitmap.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/cpcmd.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/cpcmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/ebcdic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/floatlib.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/gdb-stub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/ieee.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/irqextras390.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/lowcore.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/mathemu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/reipl.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390dyn.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390fpu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/s390mach.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/sys_s390.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/lib/checksum.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/lib/delay.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/lib/strcmp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/lib/strncpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/mm/ioremap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/dasdfmt/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/dasdfmt/dasdfmt.8#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/dasdfmt/dasdfmt.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/cfg.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/cfg.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/silo.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/tools/silo/silo.conf#1 branch -... //depot/linux-aic79xx-2.4.0/arch/s390/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/install.sh#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/boot/compressed/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/cf-enabler.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/fpu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_generic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_hd64461.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_se.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/io_unknown.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/irq_imask.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/irq_ipr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/led_se.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/mach_hp600.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/mach_se.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/mach_unknown.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/pci-sh.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_cqreek.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_hd64461.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_od.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/setup_se.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/sh_bios.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/sh_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/sys_sh.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/checksum.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/delay.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memchr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memmove.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/old-checksum.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/lib/strcasecmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/mm/cache.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/mm/ioremap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sh/vmlinux.lds.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/boot/btfixupprep.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/boot/piggyback.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/auxio.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/check_asm.sh#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/cpu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/devices.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/ebus.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/errtbls.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/etrap.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/idprom.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/ioport.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/muldiv.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/pcic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/rtrap.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sclow.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sparc-stub.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sparc_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4c_irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4d_irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4d_smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4m_irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4m_smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sun4setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sunos_asm.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sunos_ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sys_solaris.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sys_sparc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/sys_sunos.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/systbls.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/tadpole.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/tick14.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/trampoline.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/unaligned.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/windows.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/wof.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/kernel/wuf.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/COPYING.LIB#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/ashldi3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/ashrdi3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/atomic.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/bitops.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/blockops.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/checksum.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/copy_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/debuglocks.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/divdi3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/locks.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/lshrdi3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memcmp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memscan.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/memset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/mul.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/muldi3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/rem.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/rwsem.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/sdiv.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strlen.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strncmp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/strncpy_from_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/udiv.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/udivdi3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/umul.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/lib/urem.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/ashldi3.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/math.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/math-emu/sfp-util.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/btfixup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/generic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/hypersparc.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/io-unit.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/iommu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/loadmmu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/nosrmmu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/nosun4c.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/srmmu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/sun4c.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/swift.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/tsunami.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/mm/viking.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/bootstr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/devmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/devops.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/mp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/palloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/printf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/ranges.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/segment.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/sun4prom.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/prom/tree.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/boot/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/boot/piggyback.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/config.in#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/defconfig#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/auxio.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/binfmt_aout32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/binfmt_elf32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/central.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/check_asm.sh#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/cpu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/devices.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/dtlb_backend.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/dtlb_base.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/dtlb_prot.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ebus.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/entry.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/etrap.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/head.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/idprom.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/init_task.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ioctl32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/iommu_common.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/iommu_common.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/itlb_base.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_common.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_impl.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_iommu.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_psycho.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/pci_sabre.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/power.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/process.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/rtrap.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sbus.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/semaphore.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/signal32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/smp.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sparc64_ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/starfire.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sunos_ioctl32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys32.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys_sparc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys_sparc32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/sys_sunos32.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/systbls.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/trampoline.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/traps.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/ttable.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/unaligned.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/kernel/winfixup.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/PeeCeeI.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3copy_from_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3copy_in_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3copy_to_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/U3memcpy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIS.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VISbzero.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScopy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScsum.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScsumcopy.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VIScsumcopyusr.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VISmemset.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/VISsave.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/atomic.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/bitops.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/blockops.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/checksum.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/debuglocks.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/dec_and_lock.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/memcmp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/memscan.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/rwlock.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strlen.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strlen_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strncmp.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/lib/strncpy_from_user.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/math-emu/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/math-emu/math.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/math-emu/sfp-util.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/extable.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/fault.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/generic.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/modutil.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/mm/ultra.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/bootstr.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/console.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/devops.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/map.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/p1275.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/printf.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/prom/tree.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/conv.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/entry64.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/fs.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/ipc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/socket.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/socksys.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/socksys.h#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/systbl.S#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/solaris/timod.c#1 branch -... //depot/linux-aic79xx-2.4.0/arch/sparc64/vmlinux.lds#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/README#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/fd1772.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/fd1772dma.S#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/mfm.S#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/block/mfmhd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/defkeymap-acorn.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/i2c.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/keyb_arc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/keyb_ps2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/mouse_rpc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/pcf8583.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/pcf8583.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/serial-atomwide.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/serial-card.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/char/serial-dualsp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/ether3.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/net/etherh.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/acornscsi-io.S#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/acornscsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/acornscsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/arxescsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/arxescsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/cumana_2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/ecoscsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/ecoscsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/eesox.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/eesox.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/fas216.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/fas216.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/msgqueue.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/msgqueue.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/oak.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/oak.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/powertec.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/powertec.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/queue.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acorn/scsi/queue.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/cmbatt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmalloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmclib.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmcopy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmdebug.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmdelete.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmeval.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmglobal.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cminit.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmobject.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmutils.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/common/cmxface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/cpu.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsfield.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsmethod.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsmthdat.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsobject.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsopcode.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dsutils.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswexec.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswload.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswscope.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/dispatcher/dswstate.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/driver.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/driver.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/ec.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/ec.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evevent.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evmisc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evregion.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evrgnini.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evsci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evxface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evxfevnt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/events/evxfregn.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwacpi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwcpu32.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwgpe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwregs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/hardware/hwxface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/accommon.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acconfig.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acdebug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acdispat.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acenv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acevents.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acexcep.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acgcc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acglobal.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/achware.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acinterp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/aclinux.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/aclocal.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acmacros.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acnamesp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acobject.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acoutput.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acparser.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acpi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acpiosxf.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acpixf.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/acresrc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actables.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actbl71.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/actypes.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/include/amlcode.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amconfig.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amcreate.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amdyadic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amfield.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amfldio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/ammisc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/ammonad.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amnames.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amprep.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amregion.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amresnte.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amresolv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amresop.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amstore.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amstoren.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amstorob.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amsystem.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amutils.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/interpreter/amxface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsaccess.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsalloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nseval.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsinit.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsload.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsnames.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsobject.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nssearch.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsutils.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nswalk.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsxfname.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/namespace/nsxfobj.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/os.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psargs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psopcode.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psparse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psscope.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/pstree.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psutils.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/pswalk.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/parser/psxface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/power.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsaddr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rscalc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rscreate.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsdump.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsirq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rslist.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsmemory.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsmisc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsutils.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/resources/rsxface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/sys.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/table.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbconvrt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbget.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbinstal.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbutils.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbxface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/acpi/tables/tbxfroot.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/ambassador.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/ambassador.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/atmdev_init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/atmsar11.data#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/atmsar11.regions#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/atmsar11.start#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/atmtcp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/eni.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/eni.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/firestream.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/firestream.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e_firmware_copyright#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/fore200e_mkfirm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/horizon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/horizon.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/idt77105.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/idt77105.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/iphase.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/iphase.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/midway.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstar.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstar.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstarmac.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstarmac.copyright#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/nicstarmac.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/pca200e.data#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/pca200e_ecd.data#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/sba200e_ecd.data#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/suni.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/suni.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/tonga.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/uPD98401.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/uPD98402.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/uPD98402.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/zatm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/zatm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/atm/zeprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/DAC960.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/DAC960.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/acsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/acsi_slm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/amiflop.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/ataflop.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/blkpg.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/cciss.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/cciss.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/cciss_cmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/cpqarray.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/cpqarray.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/elevator.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/floppy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/genhd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/ida_cmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/ida_ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/ll_rw_blk.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/loop.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/nbd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/aten.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/bpck.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/comm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/dstr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/epat.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/epia.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/fit2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/fit3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/friq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/frpw.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/jumbo#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/kbic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/ktti.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/mkd#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/on20.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/on26.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/paride.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/paride.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pcd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pg.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pseudo.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/pt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/paride/setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/ps2esdi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/rd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/smart1,2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/swim3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/swim_iop.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/xd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/xd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/block/z2ram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/aztcd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/aztcd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cdrom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cdu31a.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cdu31a.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cm206.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/cm206.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/gscd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/gscd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/isp16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/isp16.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcdx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/mcdx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/optcd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/optcd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sbpcd4.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sjcd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sjcd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sonycd535.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/cdrom/sonycd535.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/README.computone#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/README.cycladesZ#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/README.cyclomY#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/README.epca#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/README.scc#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/acquirewdt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/adbmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/agp/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/agp/agp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/agp/agpgart_be.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/agp/agpgart_fe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/amigamouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/amikeyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/amiserial.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/applicom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/applicom.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/atarimouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/atixlmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/busmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/busmouse.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/cd1865.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/conmakehash.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/console.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/console_macros.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/consolemap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/cp437.uni#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/cyclades.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/defkeymap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/defkeymap.map#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/digi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/digi1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/digiFep1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/digiPCI.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/digi_bios.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/digi_fep.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/dn_keyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/README.drm#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/agpsupport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/auth.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/bufs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/context.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ctxbitmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/drawable.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/drm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/drmP.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ffb_context.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ffb_drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ffb_drv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/fops.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/gamma_dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/gamma_drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/gamma_drv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_bufs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_context.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_drm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/i810_drv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/lists.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/lock.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_bufs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_context.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_drm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_drv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/mga_state.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_bufs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_cce.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_context.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_drm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_drv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/r128_state.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/tdfx_context.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/tdfx_drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/tdfx_drv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/drm/vm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ds1620.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/dsp56k.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/dtlk.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/dz.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/dz.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/efirtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/epca.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/epca.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/epcaconfig.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/esp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/fep.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/README.PCI#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/RELEASE-NOTES#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/lzrw3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/lzrw3.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/zftape-compress.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/compressor/zftape-compress.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fc-10.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fc-10.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-io.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-io.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-isr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/fdc-isr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-bsm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-bsm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-buffer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-buffer.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-calibr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-calibr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ecc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-ecc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-format.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-format.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-init.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-io.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-io.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-proc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-read.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-read.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-rw.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-rw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-tracing.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-tracing.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-write.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape-write.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/lowlevel/ftape_syms.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-buffers.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-buffers.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-ctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-ctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-eof.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-eof.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-init.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-read.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-read.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-rw.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-rw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-vtbl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-vtbl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-write.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape-write.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ftape/zftape/zftape_syms.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/generic_serial.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/h8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/h8.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/hp600_keyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/i810-tco.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/i810-tco.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/i810_rng.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/fip_firm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2cmd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2cmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2ellis.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2ellis.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2lib.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2lib.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2os.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/i2pack.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2mkdev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2stat.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2trace.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2trace.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2/ip2types.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ip2main.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/isicom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/istallion.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/a3d.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/adi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/amijoy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/analog.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/cobra.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/db9.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/gamecon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/gameport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/gf2k.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/grip.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/iforce.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/interact.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/lightning.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/magellan.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/ns558.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/pcigame.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/serio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/serport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/sidewinder.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/spaceball.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/spaceorb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/tmdc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/turbografx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/joystick/warrior.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/keyboard.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/logibusmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/lp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/mem.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/mixcomwd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/moxa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/msbusmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/mxser.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/n_hdlc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/n_r3964.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/n_tty.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/nvram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/nwbutton.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/nwbutton.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/nwflash.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pc110pad.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pc110pad.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pc_keyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/serial_cb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pcmcia/serial_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pcwd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pcxx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pcxx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/ppdev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/pty.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/q40_keyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/qpmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/random.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/raw.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/board.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/bootpkt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/brates.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cdproto.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/chan.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cirrus.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cmdblk.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/cmdpkt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/control.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/daemon.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/data.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/defaults.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/eisa.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/enable.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/error.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/errors.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/formpkt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/func.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/host.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/hosthw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/link.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/linux_compat.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/list.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/lrt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/ltt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/lttwake.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/map.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/mca.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/mesg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/parmmap.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/phb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/pkt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/port.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/proto.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/protsts.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/qbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rio_linux.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rio_linux.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioboot.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riocmd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioctrl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riodrvr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioinit.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riointr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riolocks.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioparam.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riopcicopy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rioroute.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riospace.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotable.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotime.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotty.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riotypes.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riowinif.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/riscos.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rom.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/route.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rtahw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rup.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/rupstat.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/sam.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/selftest.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/space.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/sysmap.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/timeouts.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/top.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/typdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rio/unixrup.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/riscom8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/riscom8.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/riscom8_reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rocket.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rocket_int.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rsf16fmi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sbc60xxwdt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/scan_keyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/scan_keyb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/scc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/selection.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/serial.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/serial167.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/serial_21285.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/serial_amba.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sh-sci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sh-sci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/softdog.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/specialix.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/specialix_io8.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/stallion.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sxboards.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sxwindow.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/synclink.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/sysrq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/toshiba.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/tpqic02.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/tty_io.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/tty_ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/vc_screen.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/vino.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/vme_scc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/vt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/wd501p.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/wdt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/wdt285.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/wdt977.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/char/wdt_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/dio/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/dio/dio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc-al.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/fc_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/fcp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/fcp_impl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/soc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/soc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/socal.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/fc4/socal.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-algo-bit.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-algo-pcf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-elektor.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-elv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-pcf8584.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-philips-par.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2c/i2c-velleman.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/README#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/README.ioctl#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_block.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_config.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_lan.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_lan.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_scsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/i2o/i2o_scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/aec62xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ali14xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/alim15x3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/amd7409.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/buddha.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd640.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/cmd64x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/cs5530.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/cy82c693.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/dtc2278.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/falconide.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/gayle.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/hd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/hpt34x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/hpt366.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ht6560b.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/icside.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-cd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-cd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-disk.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-features.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-floppy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-geometry.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-pmac.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-pnp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-probe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide-tape.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ide_modes.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/macide.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/ns87415.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/opti621.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/osb4.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/pdc202xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/pdc4030.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/pdc4030.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/piix.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/q40ide.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/qd6580.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/rapide.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/rz1000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/sis5513.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/sl82c105.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/slc90e66.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/trm290.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/umc8672.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ide/via82cxxx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/aic5800.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/aic5800.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/csr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/csr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/guid.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/guid.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/highlevel.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/highlevel.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/hosts.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/hosts.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_core.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_transactions.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_transactions.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ieee1394_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ohci1394.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/ohci1394.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/pcilynx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/pcilynx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/raw1394.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/raw1394.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/video1394.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/ieee1394/video1394.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/input/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/input/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/input/evdev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/input/input.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/input/joydev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/input/keybdev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/input/mousedev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/act2000.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/act2000_isa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/act2000_isa.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/capi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/capi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/act2000/module.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/avm_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/avmcard.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1isa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/b1pcmcia.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/c4.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capicmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capidev.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capidrv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capidrv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capifs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capifs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capilli.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capiutil.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/capiutil.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/kcapi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/t1isa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/avmb1/t1pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/divert_init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/divert_procfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/isdn_divert.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/divert/isdn_divert.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/Divas_mod.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/adapter.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/bri.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/common.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/constant.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/divalog.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/divas.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/dsp_defs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/dspdids.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_dsp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_idi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_idi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_io.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_isa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_isa.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_mod.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/eicon_pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/fcheck.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/fourbri.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/fpga.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/idi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/idi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/kprintf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/lincfg.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/linchr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/linio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/linsys.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/log.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/md5sums.asc#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pc_maint.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pr_pc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/pri.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/sys.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/uxio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/eicon/xlog.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/amd7930.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/arcofi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/arcofi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/asuscom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/avm_a1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/avm_a1p.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/avm_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/bkm_a4t.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/bkm_a8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/bkm_ax.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/callc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/cert.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/config.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/diva.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/elsa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/elsa_ser.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/fsm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/gazel.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bds0.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bds0.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bs0.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_2bs0.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_sx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfc_sx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hfcscard.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hisax.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hscx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hscx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/hscx_irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/icc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/icc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/ipac.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isac.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isac.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isar.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isar.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isdnl3.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/isurf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/ix1_micro.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/jade.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/jade.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/jade_irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3_1tr6.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3_1tr6.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3dss1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3dss1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3ni1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/l3ni1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/lmgr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/md5sums.asc#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/mic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/netjet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/netjet.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/niccy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/nj_s.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/nj_u.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/q931.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/rawhdlc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/rawhdlc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/s0box.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/saphir.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/sedlbauer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/sportster.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/tei.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/teleint.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/teles0.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/teles3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/telespci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/w6692.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hisax/w6692.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/boardergo.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/boardergo.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hycapi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_boot.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_defs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_net.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_pof.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_procconf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_procfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_proclog.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/hysdn_sched.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/hysdn/ince1pc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/icn/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/icn/icn.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/icn/icn.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_audio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_bsdcomp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_cards.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_cards.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_common.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_common.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_concap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_concap.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_net.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_net.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ppp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ppp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_tty.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_tty.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ttyfax.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_ttyfax.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_v110.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_v110.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_x25iface.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdn_x25iface.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdnloop/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdnloop/isdnloop.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/isdnloop/isdnloop.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/callbacks.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/callbacks.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/capi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/capi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/edss1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/edss1.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/layer2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/layer2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/module.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/pcbit/pcbit.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/card.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/command.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/event.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/includes.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/interrupt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/message.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/message.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/packet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/scioc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/shmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/isdn/sc/timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/adb-iop.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/adb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/adbhid.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mac_hid.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mac_keyb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/macio-adb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mackeymap.map#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/macserial.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/macserial.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/mediabay.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/nvram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-cuda.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-macii.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-maciisi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-pmu.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/macintosh/via-pmu68k.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/linear.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/lvm-snap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/lvm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/md.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/raid0.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/raid1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/raid5.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/md/xor.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-aimslab.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-aztech.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-cadet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-gemtek.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-maestro.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-miropcm20.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-rtrack2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-sf16fmi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-terratec.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-trust.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-typhoon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/radio/radio-zoltrix.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/audiochip.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bt848.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv-cards.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv-driver.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv-if.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bttvp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/buz.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/buz.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bw-qcam.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/bw-qcam.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/c-qcam.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia_pp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/cpia_usb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/cs8420.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/i2c-old.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/i2c-parport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/ibmmpeg2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/id.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/msp3400.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/planb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/planb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/pms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa5249.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7110.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7111.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7121.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7146.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7146reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7185.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/saa7196.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/stradis.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tda7432.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tda9875.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tuner-3036.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tuner.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tuner.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tvaudio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tvaudio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/tvmixer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/videodev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/vino.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36057.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36060.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120_i2c.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120_mem.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/media/video/zr36120_mem.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/misc/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/misc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/cfi_cmdset_0001.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/cfi_cmdset_0002.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/cfi_probe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/doc1000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/doc2000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/doc2001.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/docecc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/docprobe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/ftl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/jedec.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/map_ram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/map_rom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/mapped.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/mixmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdblock.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdchar.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdcore.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdpart.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/mtdram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/nftl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/nftlmount.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/nora.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/octagon-5066.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/physmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/pmc551.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/pnc2000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/rpxlite.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/slram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/mtd/vmax301.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c501.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c503.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c503.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c505.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c505.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c507.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c509.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c515.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c523.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c523.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c527.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c527.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/3c59x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/7990.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/7990.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/8139too.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/82596.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/8390.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/8390.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/LICENSE.SRC#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/Space.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/a2065.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/a2065.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ac3200.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/acenic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/acenic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/acenic_firmware.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_card.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/aironet4500_rid.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/am79c961a.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/am79c961a.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/apne.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops_ffdrv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/cops_ltdrv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ipddp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ipddp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ltpc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/appletalk/ltpc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/arc-rawmode.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/arc-rimi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/arcnet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com20020-isa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com20020-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com20020.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com90io.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/com90xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/rfc1051.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arcnet/rfc1201.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ariadne.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ariadne.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ariadne2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arlan-proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arlan.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/arlan.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/at1700.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/atari_bionet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/atari_pamsnet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/atarilance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/atp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/atp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/auto_irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/bagetlance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/bmac.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/bmac.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/bonding.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/bsd_comp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/cs89x0.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/cs89x0.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/daynaport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/de4x5.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/de4x5.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/de600.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/de620.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/de620.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/declance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/defxx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/defxx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/depca.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/depca.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_asstruct.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_bcomm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_es4h.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_ether.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_firmware.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_i82596.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dgrs_plx9060.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dmfe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/dummy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/e2100.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/eepro.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/eepro100.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/eexpress.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/eexpress.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/epic100.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/eql.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/es3210.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/eth16i.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ethertap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ewrk3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ewrk3.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526_ip.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526_novram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fc/iph5526_scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fc/tach.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fc/tach_structs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/fmv18x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/gmac.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/gmac.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamachi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/6pack.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_epp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_par.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_ser_fdx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/baycom_ser_hdx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/bpqether.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/dmascc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/hdlcdrv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/mkiss.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/mkiss.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/scc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/gentbl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk1200.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_afsk2666.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_fsk9600.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_hapn4800.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_psk4800.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_sbc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/sm_wss.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/soundmodem/smdma.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/yam.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/yam1200.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/yam9600.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hamradio/z8530.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hp-plus.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hp100.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hp100.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hplance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hplance.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hydra.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/hydra.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/i82586.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ibmlana.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ibmlana.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ioc3-eth.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/actisys.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/esi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/girbil.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/irport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/irtty.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/litelink.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/nsc-ircc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/old_belkin.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/smc-ircc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/tekram.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/toshoboe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/irda/w83977af_ir.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/isa-skeleton.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/jazzsonic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/lance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/lasi_82596.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/lne390.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/loopback.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/mac89x0.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/mace.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/mace.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/macmace.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/macsonic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/mvme147.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/myri_code.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/myri_sbus.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/myri_sbus.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/natsemi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ncr885_debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ncr885e.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ncr885e.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ne.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ne2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ne2k-pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ne3210.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/net_init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ni5010.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ni5010.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ni52.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ni52.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ni65.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ni65.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/oaknet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/3c574_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/3c589_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/aironet4500_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/com20020_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/fmvj18x_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/i82593.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ibmtr_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/netwave_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/nmclan_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ositech.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/pcnet_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ray_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/ray_cs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/rayctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/smc91c92_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/wavelan.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/wavelan_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/wavelan_cs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/xirc2ps_cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcmcia/xircom_tulip_cb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pcnet32.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/plip.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_async.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_deflate.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_generic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ppp_synctty.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pppoe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/pppox.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ptifddi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ptifddi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/ptifddi_asm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/rcif.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/rclanmtl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/rclanmtl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/rcpci45.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/rrunner.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/rrunner.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/rtl8129.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sb1000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/seeq8005.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/seeq8005.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/setup.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sgiseeq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sgiseeq.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/shaper.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sis900.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sis900.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/lm80.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skaddr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skcsum.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skdebug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skdrv1st.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skdrv2nd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skerror.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgedrv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgehw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgehwt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgei2c.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgeinit.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgepnm2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgepnmi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skgesirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/ski2c.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skqueue.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skrlmt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/sktimer.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/sktypes.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/skvpd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/h/xmac_ii.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skaddr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skcsum.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skge.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgehwt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgeinit.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgepnmi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skgesirq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/ski2c.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/sklm80.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skqueue.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skrlmt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/sktimer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skvpd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk98lin/skxmac2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk_g16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk_g16.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk_mca.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sk_mca.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/can.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/cfm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/drvfbi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/ecm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/ess.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/fplustm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/cmtdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/fddi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/fddimib.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/fplustm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/hwmtm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/lnkstat.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/mbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/osdef1st.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/sba.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/sba_def.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/skfbi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/skfbiinc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smt.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smt_p.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/smtstate.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/supern_2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/targethw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/targetos.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/h/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/hwmtm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/hwt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/lnkstat.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/pcmplc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/pmf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/queue.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/rmt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/skfddi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smtdef.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smtinit.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smtparse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/smttimer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/skfp/srf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/slhc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/slip.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/slip.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/smc-mca.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/smc-mca.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/smc-ultra.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/smc-ultra32.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/smc9194.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/smc9194.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sonic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sonic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/starfire.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/stnic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/strip.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sun3lance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sunbmac.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sunbmac.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sundance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sunhme.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sunhme.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sunlance.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sunqe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/sunqe.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tlan.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tlan.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/abyss.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/abyss.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/ibmtr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/ibmtr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/lanstreamer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/lanstreamer.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/madgemc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/madgemc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/olympic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/olympic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/smctr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/smctr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/smctr_firmware.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tms380tr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tms380tr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tms380tr_microcode.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tokenring/tmspci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/21142.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/eeprom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/interrupt.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/media.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/pnic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/tulip.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tulip/tulip_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/tun.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/via-rhine.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-hw-comx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-hw-locomx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-hw-mixcom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-proto-fr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-proto-lapb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx-proto-ppp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/comxhw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cosa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cosa.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cycx_drv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cycx_main.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/cycx_x25.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/dlci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/hostess_sv11.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/hscx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lapbether.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_main.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_media.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_media.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_prot.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_proto.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_proto.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_proto_raw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_var.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/lmc/lmc_ver.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/mixcom.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sbni.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sbni.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_chdlc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_fr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_ppp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdla_x25.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdladrv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sdlamain.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/sealevel.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/syncppp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/syncppp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/x25_asy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/x25_asy.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/z85230.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wan/z85230.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wavelan.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wavelan.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wavelan.p.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/wd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/winbond-840.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/yellowfin.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/zlib.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/zlib.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/net/znet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/nubus/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/nubus/nubus.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/nubus/nubus_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/nubus/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/BUGS-parport#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/TODO-parport#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/daisy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/ieee1284.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/ieee1284_ops.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/multiface.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_amiga.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_arc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_atari.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_gsc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_mfc3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_pc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/parport_sunbpp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/probe.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/procfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/parport/share.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/compat.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/gen-devlist.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/names.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/pci.ids#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/quirks.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/setup-bus.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/setup-irq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/setup-res.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pci/syscall.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/bulkmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cardbus.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cb_enabler.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cirrus.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cistpl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/cs_internal.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/ds.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/i82365.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/i82365.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/o2micro.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/old-yenta.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/pci_socket.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/pci_socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/ricoh.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/rsrc_mgr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/rsrc_mgr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/smc34c90.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/tcic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/tcic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/ti113x.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/topic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/vg468.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/yenta.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pcmcia/yenta.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pnp/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pnp/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pnp/isapnp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pnp/isapnp_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/pnp/quirks.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_ccwstuff.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_ccwstuff.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_eckd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_erp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_erp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_mdsk.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_profile.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/dasd_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/mdisk.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/block/mdisk.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/char/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/char/con3215.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_con.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_rw.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_rw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/char/hwc_tty.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/misc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/misc/chandev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/net/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/net/ctc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/net/iucv.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/s390/net/iucv.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/amd7930.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/amd7930.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/cs4215.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/cs4231.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/cs4231.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dbri.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dbri.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dmy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/audio/dummy.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/aurora.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/aurora.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/bpp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/cd180.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/display7seg.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/envctrl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/flash.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/jsflash.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/openprom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/pcikbd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/pcikbd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/rtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sab82532.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/su.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkbd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkbd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkbdmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkeymap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunkeymap.map#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunmouse.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunserial.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/sunserial.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/uctrl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc_i2c.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/vfc_i2c.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/zs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/char/zs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/dvma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sbus/sbus.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/3w-xxxx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/3w-xxxx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7,8xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7,8xx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7,8xx.scr#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7xx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c7xx.scr#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c8xx_d.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/53c8xx_u.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/AM53C974.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/AM53C974.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/BusLogic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/BusLogic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.ips#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.ncr53c8xx#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.serverraid#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ChangeLog.sym53c8xx#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/FlashPoint.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/LICENSE.FlashPoint#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR5380.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR5380.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53C9x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53C9x.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53c406a.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/NCR53c406a.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.AM53C974#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.BusLogic#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.FlashPoint#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.Mylex#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.aha152x#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.dtc3x80#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.g_NCR5380#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ibmmca#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.in2000#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ncr53c7xx#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ncr53c8xx#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.osst#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.ppa#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.qlogicfas#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.qlogicisp#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.st#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/README.tmscsim#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/a2091.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/a2091.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/a3000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/a3000.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/advansys.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/advansys.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha152x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha152x.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1542.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1542.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1740.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aha1740.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7770.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7770_osm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.reg#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx.seq#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_host.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_inline.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic79xx_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.reg#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx.seq#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_host.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_inline.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_pci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aic7xxx_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/cam.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/queue.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/scsi_iu.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx/scsi_message.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/README.aic7xxx#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx.reg#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx.seq#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx_reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/aic7xxx_seq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/scsi_message.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/aic7xxx_old/sequencer.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/amiga7xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/amiga7xx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_NCR5380.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_dma_emul.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_scsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/atari_scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/atp870u.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/atp870u.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz1230.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz1230.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz2060.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/blz2060.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/bvme6000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/bvme6000.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/constants.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/constants.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfc.Readme#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTS.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSchip.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTScontrol.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSi2c.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSinit.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSstructs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTStrigger.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqfcTSworker.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cpqioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstorm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstorm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstormII.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/cyberstormII.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/dc390.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/dec_esp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/dec_esp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/dmx3191d.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/dmx3191d.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/dtc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/dtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_dma_proc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_generic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_pio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_pio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/eata_pio_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/esp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/esp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fastlane.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fastlane.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fcal.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fcal.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fd_mcs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fd_mcs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fdomain.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/fdomain.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/g_NCR5380.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/g_NCR5380.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth_ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/gdth_proc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/gvp11.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/gvp11.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/hosts.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/hosts.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/i60uscsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/i60uscsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/i91uscsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/i91uscsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ibmmca.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ibmmca.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ide-scsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ide-scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/imm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/imm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/in2000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/in2000.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ini9100u.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ini9100u.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/inia100.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/inia100.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ips.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ips.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/jazz_esp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/jazz_esp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac53c94.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac53c94.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_NCR5380.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_esp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_esp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_scsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mac_scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mca_53c9x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mca_53c9x.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/megaraid.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/megaraid.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mesh.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mesh.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme147.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme147.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme16x.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/mvme16x.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ncr53c8xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ncr53c8xx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/oktagon_esp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/oktagon_esp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/oktagon_io.S#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst_detect.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/osst_options.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pas16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pas16.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2000.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2220i.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pci2220i.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/aha152x_stub.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/fdomain_stub.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pcmcia/qlogic_stub.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pluto.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/pluto.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ppa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ppa.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi240i.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi240i.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi_chip.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi_dale.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/psi_roy.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ql12160_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ql1280_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qla1280.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qla1280.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfas.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfas.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicfc_asm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicisp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicisp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicisp_asm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicpti.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicpti.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/qlogicpti_asm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/script_asm.pl#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_error.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_lib.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_merge.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_module.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_obsolete.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_obsolete.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_queue.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_scan.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsi_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsicam.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/scsiiom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/seagate.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/seagate.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sg.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sgiwd93.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sgiwd93.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710.scr#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710_d.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sim710_u.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr_ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sr_vendor.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/st.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/st.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/st_options.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3_NCR5380.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3_scsi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3_scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3x_esp.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sun3x_esp.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c416.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c416.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx_comm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/sym53c8xx_defs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/t128.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/t128.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/tmscsim.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/tmscsim.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/u14-34f.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/u14-34f.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ultrastor.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/ultrastor.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd33c93.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd33c93.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd7000.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/scsi/wd7000.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/ds1286.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/gconsole.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/graphics.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/graphics.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/graphics_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/newport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/rrm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/sgicons.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/sgiserial.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/sgiserial.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/shmiq.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/streamable.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/usema.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sgi/char/usema.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/.indent.pro#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/.version#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/724hwmcode.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/CHANGELOG#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/COPYING#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/Hwmcode.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/README.FIRST#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ac97.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ac97.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ac97_codec.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/aci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1816.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1848.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1848.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ad1848_mixer.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/adlib_card.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/aedsp16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/audio_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/awe_hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/awe_wave.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/awe_wave.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/bin2hex.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cmpci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/coproc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4232.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4232.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4281.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cs4281_hwdefs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cs461x.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cs461x_image.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/cs46xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dev_table.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dev_table.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmabuf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/awacs_defs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_atari.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_awacs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_paula.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/dmasound/dmasound_q40.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/8010.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/audio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmo.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardmo.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwo.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/cardwo.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/ecard.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/ecard.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/efxmgr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/emu_wrapper.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/emuadxmg.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/hwaccess.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/hwaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/icardmid.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/icardwav.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/irqmgr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/irqmgr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/midi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/midi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/mixer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/recmgr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/recmgr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/timer.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/voicemgr.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/emu10k1/voicemgr.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/es1370.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/es1371.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/esssolo1.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/gus.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_card.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_linearvol.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_midi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_vol.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/gus_wave.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/hex2hex.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/i810_audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ics2101.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/iwmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/mad16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/maestro.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/maestro.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/maestro_tables.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/maui.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_ctrl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_synth.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/midi_synth.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/midibuf.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/miroaci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/mpu401.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/mpu401.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_classic.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_classic.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_pinnacle.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/msnd_pinnacle.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/nm256.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/nm256_audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/nm256_coeff.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3_hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3sa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/opl3sa2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/os.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_card.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_midi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_mixer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/pas2_pcm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/pss.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_card.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_common.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_ess.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_ess.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_midi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_mixer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sb_mixer.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sequencer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sequencer_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sgalaxy.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/skeleton.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sonicvibes.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_calls.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_config.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_firmware.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_firmware.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sound_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/soundcard.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/soundvers.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sscape.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/sys_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/trident.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/trident.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/trix.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/tuning.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/uart401.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/uart6850.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ulaw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/v_midi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/v_midi.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/via82cxxx_audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/vidc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/vidc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/vidc_fill.S#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/vwsnd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/waveartist.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/waveartist.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/wavfront.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/wf_midi.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ymf_sb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ymfpci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ymfpci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/ymfpci_image.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/yss225.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/sound/yss225.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/tc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/tc/tc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/tc/tcsyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/tc/zs.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/tc/zs.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/telephony/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/telephony/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/telephony/ixj.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/telephony/ixj.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/telephony/phonedev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/acm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/audio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/audio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/bluetooth.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/dabfirmware.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/dabusb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/dabusb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/dc2xx.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/devices.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/devio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/drivers.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/dsbr100.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/hid-debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/hid.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/hid.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/hub.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/hub.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/ibmcam.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/ibmcam.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/mdc800.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/microtek.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/microtek.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/net1080.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/ov511.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/ov511.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/pegasus.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/pegasus.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/plusb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/printer.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/rio500.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/rio500_usb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/scanner.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/scanner.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/Makefile-keyspan_pda_fw#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/belkin_sa.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/belkin_sa.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/digi_acceleport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/empeg.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/ezusb_convert.pl#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/ftdi_sio.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/ftdi_sio.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_pda.S#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_pda.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_pda_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa18x_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa19_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa19w_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa26msg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa28_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa28msg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa28x_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa49msg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/keyspan_usa49w_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/mct_u232.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/mct_u232.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/omninet.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/usb-serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/usbserial.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/visor.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/visor.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/whiteheat.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/whiteheat.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/serial/whiteheat_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/dpcm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/dpcm.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/freecom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/freecom.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/initializers.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/initializers.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/protocol.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/protocol.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/scsiglue.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/scsiglue.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/sddr09.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/sddr09.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/shuttle_usbat.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/shuttle_usbat.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/transport.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/transport.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/usb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/storage/usb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/uhci-debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/uhci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/uhci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-debug.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-ohci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-ohci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-uhci-debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-uhci.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usb-uhci.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usbkbd.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/usbmouse.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/uss720.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/usb/wacom.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/S3triofb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/acornfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/acornfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/amifb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/atafb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/aty.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/aty128.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/aty128fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/atyfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/bwtwofb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cgfourteenfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cgsixfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cgthreefb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/chipsfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/clgenfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/clgenfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/controlfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/controlfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/creatorfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cvisionppc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cyber2000fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cyber2000fb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cyberfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/cyberfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/dn_accel.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/dn_cfb4.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/dn_cfb8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/dnfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/dummycon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-afb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb24.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb32.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb4.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-cfb8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-hga.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-ilbm.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-iplan2p2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-iplan2p4.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-iplan2p8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-mac.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-mfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-sti.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-vga-planes.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon-vga.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbcon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbgen.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fbmon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fm2fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/font_6x11.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/font_8x16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/font_8x8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/font_acorn_8x8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/font_pearl_8x8.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/font_sun12x22.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/font_sun8x16.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/fonts.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/g364fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/hgafb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/hitfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/hpfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/iga.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/igafb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/imsttfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/leofb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/macfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/macmodes.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/i2c-matroxfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_DAC1064.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_DAC1064.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_Ti3026.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_Ti3026.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_accel.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_accel.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_base.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_base.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_crtc2.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_crtc2.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_g450.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_g450.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_maven.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_maven.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/matrox/matroxfb_misc.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/mdacon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/modedb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/newport_con.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/offb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/p9100.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/p9100fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/platinumfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/platinumfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/pm2fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/pm2fb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/prom.uni#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/promcon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/q40fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/retz3fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/retz3fb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/riva/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/riva/fbdev.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/riva/nv4ref.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/riva/nvreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/riva/riva_hw.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/riva/riva_hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/riva/riva_tbl.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sa1100fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sbusfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sgivwfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sgivwfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/initdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_300.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_300.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_301.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_301.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sis/sis_main.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/skeletonfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sti-bmode.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sti.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sticon-bmode.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sticon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sticore.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/stifb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/sun3fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/tcxfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/tdfxfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/tgafb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/tgafb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/valkyriefb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/valkyriefb.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/vesafb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/vfb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/vga16fb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/vgacon.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/video/virgefb.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/zorro/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/zorro/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/zorro/gen-devlist.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/zorro/names.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/zorro/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/zorro/zorro.c#1 branch -... //depot/linux-aic79xx-2.4.0/drivers/zorro/zorro.ids#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/fs/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/fs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/adfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_f.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_f.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_fplus.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/dir_fplus.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/map.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/adfs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/Changes#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/amigaffs.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/bitmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/affs/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/attr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/autofs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/dirhash.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/root.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs/waitq.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/autofs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/expire.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/init.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/root.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/autofs4/waitq.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/bad_inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/bfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/bfs/bfs_defs.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/bfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/bfs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/bfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/binfmt_aout.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/binfmt_elf.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/binfmt_em86.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/binfmt_misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/binfmt_script.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/block_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/buffer.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/cache.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/cnode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/coda_linux.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/pioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/psdev.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/sysctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/coda/upcall.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/README#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/cramfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/adler32.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infblock.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infblock.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infcodes.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infcodes.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inffast.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inffast.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inffixed.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inflate.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inftrees.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/inftrees.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infutil.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/infutil.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/uncompr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/zconf.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/zlib.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inflate/zutil.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/cramfs/uncompress.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/dcache.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devfs/base.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devfs/util.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devices.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devpts/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devpts/devpts_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devpts/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/devpts/root.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/dnotify.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/dquot.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/efs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/efs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/efs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/efs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/efs/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/efs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/efs/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/exec.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/CHANGES#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/acl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/balloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/bitmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/fsync.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/ialloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ext2/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/buffer.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/cache.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/cvf.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/fatfs_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/msbuffer.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/tables.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fat/tables.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fcntl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/fifo.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/file_table.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/filesystems.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/COPYING#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/FAQ.txt#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/HFS.txt#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/INSTALL.txt#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/TODO#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/balloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/bdelete.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/bfind.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/bins_del.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/binsert.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/bitmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/bitops.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/bnode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/brec.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/btree.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/catalog.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/dir_cap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/dir_dbl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/dir_nat.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/extent.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/file_cap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/file_hdr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/hfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/hfs_btree.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/mdb.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/part_tbl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/string.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/sysdep.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/trans.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hfs/version.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/alloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/anode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/buffer.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/dentry.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/dnode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/ea.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/hpfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/hpfs_fn.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/map.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/name.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/hpfs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/iobuf.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/joliet.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/rock.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/rock.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/isofs/util.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/jffs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/jffs/inode-v23.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/jffs/intrep.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/jffs/intrep.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/jffs/jffs_fm.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/jffs/jffs_fm.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/clntlock.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/clntproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/host.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/lockd_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/mon.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/svc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/svc4proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/svclock.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/svcproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/svcshare.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/svcsubs.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/xdr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/lockd/xdr4.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/locks.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/bitmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/itree_common.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/itree_v1.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/itree_v2.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/minix/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/msdos/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/msdos/msdosfs_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/msdos/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/mmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncplib_kernel.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncplib_kernel.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncpsign_kernel.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/ncpsign_kernel.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/sock.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ncpfs/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/flushd.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/mount_clnt.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/nfs2xdr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/nfs3proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/nfs3xdr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/nfsroot.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/read.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/unlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfs/write.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/auth.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/export.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/lockd.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfs3proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfs3xdr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfscache.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsfh.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfssvc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/nfsxdr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/stats.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nfsd/vfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_base.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_big5.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp437.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp737.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp775.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp850.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp852.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp855.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp857.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp860.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp861.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp862.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp863.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp864.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp865.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp866.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp869.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp874.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp932.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp936.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp949.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_cp950.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_euc-jp.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_euc-kr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_gb2312.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-1.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-14.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-15.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-2.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-3.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-4.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-5.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-6.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-7.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-8.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_iso8859-9.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_koi8-r.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_sjis.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/nls/nls_utf8.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/noquot.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/attr.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/attr.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/dir.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/fs.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/inode.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/macros.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/ntfsendian.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/ntfstypes.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/struct.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/super.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/support.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/support.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/sysctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/sysctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/util.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ntfs/util.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/open.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/openpromfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/openpromfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/acorn.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/acorn.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/amiga.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/amiga.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/atari.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/atari.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/check.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/check.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/ibm.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/ibm.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/mac.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/mac.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/msdos.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/msdos.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/osf.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/osf.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/sgi.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/sgi.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/sun.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/sun.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/ultrix.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/partitions/ultrix.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/pipe.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/array.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/base.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/generic.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/inode-alloc.txt#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/kcore.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/kmsg.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/proc_devtree.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/proc_misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/proc_tty.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/procfs_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/proc/root.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/BUGS#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/README#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/TODO#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/bitmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/fsync.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/qnx4/truncate.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ramfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ramfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/read_write.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/readdir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/romfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/romfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/select.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/ChangeLog#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/cache.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/getopt.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/getopt.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/smb_debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/smbfs/sock.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/stat.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/CHANGES#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/INTRO#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/balloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/fsync.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/ialloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/sysv/truncate.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/balloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/crc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/directory.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/fsync.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/ialloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/lowlevel.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/partition.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/truncate.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/udf_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/udf_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/udfdecl.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/udfend.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/udftime.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/udf/unicode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/balloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/cylinder.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/file.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/ialloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/super.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/swab.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/symlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/truncate.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/util.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/ufs/util.h#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/README-WIP.txt#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/dir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/emd.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/inode.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/mangle.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/notes#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/rdir.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/umsdos/specs#1 branch -... //depot/linux-aic79xx-2.4.0/fs/vfat/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/fs/vfat/namei.c#1 branch -... //depot/linux-aic79xx-2.4.0/fs/vfat/vfatfs_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/asm_offsets.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/compiler.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/console.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_apecs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_cia.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_irongate.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_lca.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_mcpcia.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_polaris.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_t2.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_titan.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_tsunami.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/core_wildfire.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/fpu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/gentrap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/hwrpb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/jensen.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/machvec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/md.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sfp-machine.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/sysinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-alpha/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/oldlatches.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-arc/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/acornfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-cl7500/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa110/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-ebsa285/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/serial_l7200.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-l7200/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-nexuspci/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/acornfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-rpc/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/SA-1100.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/SA-1101.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/SA-1111.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/assabet.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/bitfield.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/bitsy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/cerf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/mmzone.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/serial_reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/thinclient.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-sa1100/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-shark/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/irqs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/arch-tbox/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/assembler.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/cpu-multi26.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/cpu-multi32.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/cpu-single.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ecard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/fiq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/dec21285.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/ioc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/iomd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/memc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/pci_v3.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hardware/serial_amba.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/leds.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/limits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/arch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/map.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mach/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/mmzone.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/nwflash.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/assembler.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/locks.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armo/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/assembler.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/domain.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/locks.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-armv/uncompress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/proc-fns.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/procinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/therm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/vt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-arm/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-generic/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-generic/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-generic/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-generic/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-generic/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/apic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/apicdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/boot.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/cobalt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/cpufeature.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/debugreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/desc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/e820.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/fixmap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/highmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/i387.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/io_apic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/kmap_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ldt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/lithium.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/locks.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/math_emu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mca_dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mmx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mpspec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/msr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/mtrr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgalloc-2level.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgalloc-3level.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgtable-2level.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgtable-3level.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/rwlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/string-486.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/vm86.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-i386/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/acpi-ext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/acpikcfg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/asmmacro.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/break.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/efi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/fpswa.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/fpu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ia32.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/iosapic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_dig.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_hpsim.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/machvec_sn1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mca.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mca_asm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/offsets.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/ptrace_offsets.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/rse.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/addrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/agent.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/alenlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/arc/hinv.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/arc/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/arch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/cdl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/clksupport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/cmn_err.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/dmamap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/driver.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/eeprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/gda.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hack.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hcl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hcl_util.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hubspc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/hwcntrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/intr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/intr_public.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/invent.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/iobus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ioc3.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ioerror.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ioerror_handling.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/iograph.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/klconfig.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/kldir.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ksys/elsc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ksys/i2c.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/ksys/l1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/labelcl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mem_refcnt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mmzone.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mmzone_default.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/mmzone_sn1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/nic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/nodemask.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/nodepda.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/bridge.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pci_bus_cvlink.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pci_defs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pcibr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pcibr_private.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pciio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pci/pciio_private.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/pio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/prio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/router.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sgi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/slotnum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/addrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/arch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/bedrock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubdev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubio_next.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hublb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hublb_next.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubmd_next.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubni.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubni_next.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubpi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubpi_next.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubxb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/hubxb_next.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/ip27config.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/kldir.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/leds.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/promlog.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/router.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/slotnum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/sn1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/uart16550.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn1/war.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn_cpuid.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn_fru.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/sn_private.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/synergy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/systeminfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/vector.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/war.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xbow.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xbow_info.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xswitch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xtalk.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xtalk_private.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xtalkaddrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sn/xtalk/xwidget.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/unwind.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ia64/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/adb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/adb_iop.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/adb_mouse.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amigahw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amigaints.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amigayle.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/amipcmcia.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/apollodma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/apollohw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atafd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atafdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_SCCserial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_SLM.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_acsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_joystick.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_stdma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atari_stram.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atarihw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atariints.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atarikb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/blinken.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bootinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/bvme6000hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/cachectl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/contregs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/dsp56k.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/dvma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/entry.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/fbio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/fpu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/hwtest.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/idprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/intersil.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/kbio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_asc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_baboon.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_iop.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_mouse.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_oss.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_psc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mac_via.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/machdep.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/machines.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/machw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/macintosh.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/macints.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/math-emu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/md.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/motorola_pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/motorola_pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/movs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mvme147hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/mvme16xhw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/openprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/oplib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/page_offset.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/q40_keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/q40_master.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/q40ints.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sbus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/shm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3-head.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3_pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3_pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3ints.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/sun3x.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/swim_iop.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/traps.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/virtconvert.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/vuid_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-m68k/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/addrspace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/arc/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/asm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/asmmacro.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/baget/baget.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/baget/vac.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/baget/vic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/bcache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/bootinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/branch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/cachectl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/cacheops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/cpu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ddb5074.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/interrupts.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/ioasic_addrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/ioasic_ints.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn01.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn02.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn02xa.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/kn03.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/machtype.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/tc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/tcinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dec/tcmodule.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ds1286.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/fp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/fpregdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/gdb-stub.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/gfx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/inst.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/inventory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/isadep.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/jazz.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/jazzdma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/mipsprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/mipsregs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ng1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ng1hw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/nile4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/orion.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/paccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/prctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/r4kcache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/reboot.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/regdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/rrm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sfp-machine.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgihpc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgimc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgi/sgint23.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgialib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgiarcs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sgidefs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/shmiq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sni.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/stackframe.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/sysmips.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/umap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/usioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/watch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/wbflush.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/addrspace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/arc/hinv.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/arc/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/asm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/asmmacro.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bcache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bootinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/branch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/cachectl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/cpu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ds1286.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/fpregdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/gfx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/inst.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/m48t35.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mipsregs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/mmzone.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ng1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/paccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pci/bridge.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r10kcache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r10kcacheops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r4kcache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/r4kcacheops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/regdef.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/riscos-syscall.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sfp-machine.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgihpc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgimc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgi/sgint23.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgialib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgiarcs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sgidefs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/shmiq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/addrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/agent.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/arch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/gda.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/intr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/intr_public.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/ioc3.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/klconfig.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/kldir.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/klkernvars.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/launch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/mapped_kernel.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/nmi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/addrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/arch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hub.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubmd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubni.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/hubpi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/ip27.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn0/sn0_fru.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/sn_private.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sn/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/stackframe.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/sysmips.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/usioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/watch.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/xtalk/xtalk.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-mips64/xtalk/xwidget.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/asmregs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/assembly.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/bootdata.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/fixmap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/gsc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hardware.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hil.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/iosapic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/led.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/machdep.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/md.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/parport_gsc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pdc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pdcpat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/psw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/real.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/runway.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/som.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/traps.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-parisc/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/8xx_immap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigahw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigaints.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigappc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amigayle.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/amipcmcia.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/backlight.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/board.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bootinfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bootx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bseip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/cpm_8260.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/dbdma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/est8260.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/fads.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/feature.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/gemini.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/gemini_serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/gg2.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/heathrow.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/highmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/hydra.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/immap_8260.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/keylargo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/kgdb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/kmap_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/m48t35.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/machdep.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mbx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/md.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mediabay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mk48t59.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mpc8260.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/mpc8xx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/nvram.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/oak.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ohare.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pci-bridge.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/pnp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/prep_nvram.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/prom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/raven.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/residual.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/rpxclassic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/rpxlite.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/tqm860.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/tqm8xxL.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/traps.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/uninorth.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/vc_ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/walnut.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-ppc/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/chandev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ebcdic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/gdb-stub.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/irqextras390.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/lowcore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/major.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/mathemu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/misc390.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/queue.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390-gdbregs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390-regs-common.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390dyn.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/s390mach.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/setup.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/sigp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-s390/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/addrspace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/hd64461.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/hitachi_se.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/hw_irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_generic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_hd64461.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_od.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_se.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/io_unknown.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/machvec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/machvec_init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgalloc-2level.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgtable-2level.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/sh_bios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/smc37c93x.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/ucontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sh/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/asi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/asmmacro.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/audioio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/auxio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bpp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bsderrno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/btfixup.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/clock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/contregs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/cprefix.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/cypress.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ebus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ecc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/eeprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/fbio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/head.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/highmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/idprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/io-unit.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/iommu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/jsflash.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kbio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kdebug.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kgdb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/kmap_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/machines.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mbus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/memreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mostek.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mpmbox.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/msi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/mxcc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/obio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/openprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/openpromio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/oplib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pbm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pcic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pconf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/perfctr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtsrmmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtsun4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/pgtsun4c.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/psr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ross.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sbi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sbus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sfp-machine.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/smpprim.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/solerrno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sun4paddr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sun4prom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sunbpp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/svr4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/swift.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/sysen.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/timer.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/traps.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/tsunami.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/turbosparc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/ultra.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vac-ops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vaddrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vfc_ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/viking.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/vuid_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/winmacro.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/apb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/asi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/atomic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/audioio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/auxio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bpp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bsderrno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/bugs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/byteorder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/current.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/display7seg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/div64.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/dma.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ebus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/envctrl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fbio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fhc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/floppy.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/fpumacro.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/hardirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/head.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/idprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/io.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ioctls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/iommu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ipcbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/kbio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/kdebug.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/lsu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mmu_context.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/mostek.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/msgbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/namei.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ns87303.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/openprom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/openpromio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/oplib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pbm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pconf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/perfctr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pgalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pgtable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/processor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/psrcompat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/pstate.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sab82532.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sbus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/scatterlist.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/semaphore-helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/semaphore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sembuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sfp-machine.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/shmbuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/shmparam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sigcontext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/siginfo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/smplock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/softirq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/solerrno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/spitfire.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/starfire.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/statfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/sunbpp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/svr4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/system.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/termbits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/timer.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/ttable.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/uaccess.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/uctx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/unaligned.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/upa.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/utrap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/vaddrs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/visasm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/vuid_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/asm-sparc64/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/802_11.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/a.out.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ac97_codec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/acct.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/acpi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/adb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/adb_mouse.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/adfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/adfs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/adfs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/affs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/affs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/affs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/affs_hardblocks.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/agp_backend.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/agpgart.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/amifd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/amifdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/amigaffs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/apm_bios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/arcdevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atalk.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atari_rootsec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atm_eni.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atm_idt77105.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atm_nicstar.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atm_suni.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atm_tcp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atm_zatm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmapi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmarp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmclip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmdev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmioc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmlec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmmpc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmsap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/atmsvc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/auto_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/auto_fs4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/awe_voice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ax25.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/b1lli.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/b1pcmcia.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/baycom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/bfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/bfs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/bfs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/binfmts.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/bitops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/blk.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/blkdev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/blkpg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/bootmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/bpqether.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/brlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/big_endian.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/generic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/little_endian.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/pdp_endian.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/swab.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/byteorder/swabb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/capability.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/capi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cciss_ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cd1400.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cdk.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cdrom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/circ_buf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/coda.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/coda_cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/coda_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/coda_linux.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/coda_proc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/coda_psdev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/coff.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/com20020.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/compatmac.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/comstats.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/concap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/config.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/console.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/console_struct.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/consolemap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ctype.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cuda.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cyclades.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cyclomx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cycx_cfm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cycx_drv.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/cycx_x25.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/dasd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/dcache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/delay.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/devfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/devfs_fs_kernel.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/devpts_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/dio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/dirent.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/divert.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/dn.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/dnotify.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/dtlk.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/efs_dir.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/efs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/efs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/efs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/efs_vh.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/elevator.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/elf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/elfcore.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/errno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/errqueue.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/etherdevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ethtool.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ext2_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ext2_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ext2_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fat_cvf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fcdevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fcntl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fd1772.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fddidevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/file.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/filter.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/fs_struct.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ftape-header-segment.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ftape-vendors.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ftape.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/gameport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/generic_serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/genhd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ghash.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hayesesp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hdlcdrv.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hdreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hdsmart.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hfs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hfs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hfs_sysdep.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/highmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/highuid.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hippidevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hpfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hpfs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hpfs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/hysdn_if.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2c-algo-bit.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2c-algo-pcf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2c-dev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2c-elektor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2c-id.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2c-old.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2c.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2o-dev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/i2o.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ibmtr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/icmp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/icmpv6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ide.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_arcnet.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_arp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_bonding.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_bridge.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_cablemodem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_ec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_eql.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_ether.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_fc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_fddi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_frad.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_hippi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_ltalk.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_packet.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_plip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_ppp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_pppox.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_pppvar.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_shaper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_slip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_strip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_tr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_tun.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/if_tunnel.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/igmp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/in.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/in6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/in_route.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/in_systm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/inet.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/inetdevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/init.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/input.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/interrupt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/iobuf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ioport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ipc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ipsec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ipv6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ipv6_route.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ipx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/irda.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/irq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/irq_cpustat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/isapnp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/isdn.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/isdn_divertif.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/isdn_lzscomp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/isdn_ppp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/isdnif.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/isicom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/iso_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/iso_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/iso_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/istallion.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ixjuser.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/jffs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/joystick.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kbd_diacr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kbd_kern.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kbd_ll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kdev_t.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kernel.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kernel_stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kernelcapi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/keyboard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/kmod.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lapb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/limits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/linkage.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/linux_logo.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/list.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/bind.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/lockd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/nlm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/share.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/sm_inter.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/xdr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lockd/xdr4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/locks.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/logibusmouse.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/loop.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/lvm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/major.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/malloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/matroxfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mc146818rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mc6821.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mca.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/minix_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/minix_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/minix_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/miscdevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mman.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mmzone.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/modsetver.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/module.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mount.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mpp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mroute.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/msdos_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/msdos_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/msdos_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/msg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/cfi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/compatmac.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/doc2000.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/flashchip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/ftl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/iflash.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/jedec.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/map.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/mapped.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/mtd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/nand.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/nand_ids.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/nftl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/partitions.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtd/pmc551.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/mtio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/n_r3964.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nbd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ncp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ncp_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ncp_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ncp_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ncp_mount.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ncp_no.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/net.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netbeui.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netdevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ddp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_decnet.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/compat_firewall.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_core.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_ftp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_protocol.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_tcp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_conntrack_tuple.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_core.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_ftp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_helper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_protocol.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_nat_rule.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_queue.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ip_tables.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipchains_core.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipfwadm_core.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_LOG.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_MARK.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_REJECT.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_TOS.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_limit.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_mac.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_mark.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_multiport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_owner.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_state.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/ipt_tos.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/listhelp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv4/lockhelp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6_tables.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_LOG.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_MARK.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_REJECT.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_limit.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_mac.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_mark.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_multiport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipv6/ip6t_owner.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_ipx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netfilter_x25.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netlink.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/netrom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs2.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs3.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs_flushd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs_mount.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs_page.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfs_xdr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/auth.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/cache.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/const.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/export.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/interface.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/nfsd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/nfsfh.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/stats.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/syscall.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/xdr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsd/xdr3.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nfsiod.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/notifier.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ntfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ntfs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ntfs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nubus.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/nvram.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/openpic.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/openprom_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pagemap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/parport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/parport_pc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pc_keyb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pci_ids.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/personality.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/phonedev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pipe_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pkt_cls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pkt_sched.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/pmu.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/poll.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/posix_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ppdev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ppp-comp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ppp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ppp_channel.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ppp_defs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/prctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/proc_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/proc_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ps2esdi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ptrace.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/qic117.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/qnx4_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/qnx4_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/qnx4_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/qnxtypes.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/quota.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/quotaops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/linear.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/md.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_compatible.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_k.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_p.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/md_u.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/raid0.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/raid1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/raid5.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raid/xor.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/random.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/raw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/reboot.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/resource.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/rocket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/romfs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/romfs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/romfs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/rose.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/route.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/rpcsock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/rtc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/rtnetlink.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sc26198.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/scc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sched.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdla.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdla_chdlc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdla_fr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdla_ppp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdla_x25.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdladrv.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdlapci.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sdlasfm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/securebits.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/selection.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/serial.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/serial167.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/serialP.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/serial_reg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/serio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/shm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/shmem_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/signal.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sisfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/skbuff.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/slab.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smb_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smb_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smb_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smb_mount.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smbno.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/smp_lock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/socket.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sockios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sonet.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sound.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/soundcard.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/soundmodem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/spinlock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/stallion.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/stat.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/stddef.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/string.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/auth.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/clnt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/debug.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/msg_prot.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/sched.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/stats.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/svc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/svcauth.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/svcsock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/xdr.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sunrpc/xprt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/swap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/swapctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/synclink.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sys.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sysctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sysrq.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sysv_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sysv_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/sysv_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/tcp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/telephony.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/termios.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/threads.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/time.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/timer.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/times.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/timex.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/toshiba.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/tpqic02.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/tqueue.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/trdevice.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/tty.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/tty_driver.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/tty_flip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/tty_ldisc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/udf_167.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/udf_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/udf_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/udf_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/udf_udf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/udp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ufs_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ufs_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ufs_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/uio.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/ultrasound.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/umsdos_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/umsdos_fs.p#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/umsdos_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/un.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/unistd.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/usb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/usbdev_fs_i.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/usbdev_fs_sb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/usbdevice_fs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/user.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/utime.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/uts.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/utsname.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/vfs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/video_decoder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/video_encoder.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/videodev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/videotext.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/vmalloc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/vt.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/vt_buffer.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/vt_kern.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/wait.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/wanpipe.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/wanrouter.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/watchdog.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/wavefront.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/wireless.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/wrapper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/x25.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/yam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/zftape.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/zorro.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/linux/zorro_ids.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/double.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/extended.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/op-1.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/op-2.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/op-4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/op-8.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/op-common.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/quad.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/single.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/math-emu/soft-fp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/addrconf.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/af_unix.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/arp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/atmclip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ax25.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/checksum.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/datalink.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dn.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dn_dev.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dn_fib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dn_neigh.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dn_nsp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dn_route.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dsfield.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/dst.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/flow.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/icmp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/if_inet6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/inet_common.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/inet_ecn.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/inetpeer.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ip6_fib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ip6_fw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ip6_route.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ip_fib.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ipconfig.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ipip.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ipv6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ipx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/crc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/discovery.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_core.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_lmp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_param.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_ttp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_tty.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/ircomm_tty_attach.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irda.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irda_device.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irdacall.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/iriap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/iriap_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irias_object.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_client.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_common.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_eth.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_filter.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlan_provider.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap_comp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlap_frame.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlmp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlmp_event.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irlmp_frame.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irmod.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irqueue.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irttp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/irtty.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/nsc-ircc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/parameters.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/qos.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/smc-ircc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/timer.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/toshoboe.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/w83977af.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/w83977af_ir.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/irda/wrapper.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/lapb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/llc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/llc_frame.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/llc_name.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/llc_state.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/ndisc.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/neighbour.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/netrom.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/p8022.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/pkt_cls.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/pkt_sched.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/profile.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/protocol.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/psnap.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/raw.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/rawv6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/rose.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/route.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/scm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/slhc_vj.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/snmp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/sock.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/spx.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/tcp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/tcp_ecn.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/transp_v6.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/udp.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/net/x25.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/bulkmem.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/bus_ops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/ciscode.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/cisreg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/cistpl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/cs.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/cs_types.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/driver_ops.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/ds.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/ftl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/mem_op.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/memory.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/ss.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/pcmcia/version.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/scsi/scsi.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/scsi/scsi_ioctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/scsi/scsicam.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/scsi/sg.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-afb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb16.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb2.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb24.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb32.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-cfb8.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-hga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-ilbm.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-iplan2p2.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-iplan2p4.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-iplan2p8.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-mac.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-mfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-vga-planes.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon-vga.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/fbcon.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/font.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/macmodes.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/newport.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/s3blit.h#1 branch -... //depot/linux-aic79xx-2.4.0/include/video/sbusfb.h#1 branch -... //depot/linux-aic79xx-2.4.0/init/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/init/version.c#1 branch -... //depot/linux-aic79xx-2.4.0/ipc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/ipc/msg.c#1 branch -... //depot/linux-aic79xx-2.4.0/ipc/sem.c#1 branch -... //depot/linux-aic79xx-2.4.0/ipc/shm.c#1 branch -... //depot/linux-aic79xx-2.4.0/ipc/util.c#1 branch -... //depot/linux-aic79xx-2.4.0/ipc/util.h#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/acct.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/capability.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/context.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/dma.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/exec_domain.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/exit.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/fork.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/info.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/itimer.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/kmod.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/ksyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/module.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/panic.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/pm.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/printk.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/ptrace.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/resource.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/sched.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/signal.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/softirq.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/sys.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/sysctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/time.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/uid16.c#1 branch -... //depot/linux-aic79xx-2.4.0/kernel/user.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/lib/brlock.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/cmdline.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/ctype.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/dec_and_lock.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/errno.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/inflate.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/string.c#1 branch -... //depot/linux-aic79xx-2.4.0/lib/vsprintf.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/mm/bootmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/filemap.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/highmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/memory.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/mlock.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/mmap.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/mmap_avl.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/mprotect.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/mremap.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/numa.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/oom_kill.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/page_alloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/page_io.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/shmem.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/slab.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/swap.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/swap_state.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/swapfile.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/vmalloc.c#1 branch -... //depot/linux-aic79xx-2.4.0/mm/vmscan.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/TODO#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/cl2llc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/cl2llc.pre#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/fc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/fddi.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/hippi.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/llc_macinit.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/llc_sendpdu.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/llc_utility.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/p8022.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/p8023.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/actionnm.awk#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/actionnm.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/compile.awk#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/opcd2num.sed#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/opcodes#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/opcodesnm.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/pseudocode#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/pseudo/pseudocode.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/psnap.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/sysctl_net_802.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/tr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/transit/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/transit/compile.awk#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/transit/pdutr.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/transit/pdutr.pre#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/transit/timertr.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/802/transit/timertr.pre#1 branch -... //depot/linux-aic79xx-2.4.0/net/Changes#1 branch -... //depot/linux-aic79xx-2.4.0/net/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/README#1 branch -... //depot/linux-aic79xx-2.4.0/net/TUNABLE#1 branch -... //depot/linux-aic79xx-2.4.0/net/appletalk/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/appletalk/aarp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/appletalk/ddp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/appletalk/sysctl_net_atalk.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/addr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/addr.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/atm_misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/clip.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/common.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/common.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/ipcommon.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/ipcommon.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/lec.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/lec.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/lec_arpc.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/mpc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/mpc.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/mpoa_caches.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/mpoa_caches.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/mpoa_proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/protocols.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/pvc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/raw.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/resources.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/resources.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/signaling.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/signaling.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/atm/svc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/af_ax25.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_addr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ds_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ds_subr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ds_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_iface.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_ip.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_out.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_std_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_std_subr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_std_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_subr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/ax25_uid.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ax25/sysctl_net_ax25.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_device.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_fdb.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_forward.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_if.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_input.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_notify.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_private.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_private_stp.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_private_timer.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp_bpdu.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp_if.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/bridge/br_stp_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/datagram.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/dev_mcast.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/dst.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/dv.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/filter.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/iovec.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/neighbour.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/netfilter.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/profile.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/rtnetlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/scm.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/skbuff.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/sock.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/sysctl_net_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/core/utils.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/README#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/TODO#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/af_decnet.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_fib.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_neigh.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_nsp_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_nsp_out.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_rules.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_table.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/dn_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/decnet/sysctl_net_decnet.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/econet/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/econet/af_econet.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/econet/sysctl_net_ec.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ethernet/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/ethernet/eth.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ethernet/pe2.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ethernet/sysctl_net_ether.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/af_inet.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/arp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/devinet.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_frontend.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_hash.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_rules.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/fib_semantics.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/icmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/igmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/inetpeer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_forward.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_fragment.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_gre.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_input.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_nat_dumb.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_options.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_output.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ip_sockglue.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ipconfig.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ipip.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/ipmr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_ftp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_generic.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_icmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_tcp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_proto_udp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_conntrack_standalone.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_fw_compat.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_fw_compat_masq.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_fw_compat_redir.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_ftp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_icmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_tcp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_udp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_proto_unknown.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_rule.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_nat_standalone.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_queue.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ip_tables.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipchains_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipfwadm_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_LOG.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_MARK.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_MASQUERADE.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_MIRROR.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_REDIRECT.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_REJECT.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_TOS.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_limit.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_mac.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_mark.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_multiport.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_owner.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_state.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_tos.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/ipt_unclean.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/iptable_filter.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/netfilter/iptable_mangle.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/protocol.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/raw.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/syncookies.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/sysctl_net_ipv4.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_input.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_ipv4.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_minisocks.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_output.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/tcp_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/udp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv4/utils.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/README#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/addrconf.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/af_inet6.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/datagram.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/exthdrs.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/icmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_fib.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_flowlabel.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_fw.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_input.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/ip6_output.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/ipv6_sockglue.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/mcast.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/ndisc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6_tables.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_MARK.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_limit.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_mac.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_mark.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6t_multiport.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/netfilter/ip6table_filter.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/proc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/protocol.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/raw.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/reassembly.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/sit.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/sysctl_net_ipv6.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/tcp_ipv6.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipv6/udp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipx/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipx/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipx/af_ipx.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipx/af_spx.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/ipx/sysctl_net_ipx.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/af_irda.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/compressors/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/compressors/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/compressors/irda_deflate.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/crc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/discovery.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_core.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_event.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_lmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_param.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_ttp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_tty.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_tty_attach.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/ircomm/ircomm_tty_ioctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irda_device.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/iriap.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/iriap_event.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irias_object.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_client.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_client_event.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_common.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_eth.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_event.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_filter.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_provider.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlan/irlan_provider_event.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlap.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlap_comp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlap_event.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlap_frame.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlmp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlmp_event.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irlmp_frame.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irnet/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irnet/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_irda.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_irda.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_ppp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irnet/irnet_ppp.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irqueue.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irsyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irsysctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/irttp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/parameters.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/qos.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/irda/wrapper.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/README#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/accept.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/datasending.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/logging.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/main.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/make_times_h.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/misc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/prototypes.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/rfc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/rfc_time.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/security.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/security.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/sockets.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/structure.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/sysctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/sysctl.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/userspace.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/khttpd/waitheaders.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/lapb/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_iface.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_out.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_subr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/lapb/lapb_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netlink/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/netlink/af_netlink.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netlink/netlink_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/af_netrom.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/nr_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/nr_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/nr_loopback.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/nr_out.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/nr_route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/nr_subr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/nr_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netrom/sysctl_net_netrom.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/netsyms.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/packet/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/packet/af_packet.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/af_rose.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_link.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_loopback.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_out.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_subr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/rose_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/rose/sysctl_net_rose.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/Config.in#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_api.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_fw.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_rsvp.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_rsvp.h#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_rsvp6.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_tcindex.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/cls_u32.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/estimator.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/police.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_api.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_atm.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_cbq.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_csz.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_dsmark.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_fifo.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_generic.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_gred.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_ingress.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_prio.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_red.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_sfq.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_tbf.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sched/sch_teql.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/socket.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/auth.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/auth_null.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/auth_unix.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/clnt.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/pmap_clnt.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/sched.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/stats.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/sunrpc_syms.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/svc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/svcauth.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/svcauth_des.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/svcsock.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/sysctl.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/xdr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sunrpc/xprt.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/sysctl_net.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/unix/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/unix/af_unix.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/unix/garbage.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/unix/sysctl_net_unix.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/wanrouter/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/wanrouter/patchlevel#1 branch -... //depot/linux-aic79xx-2.4.0/net/wanrouter/wanmain.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/wanrouter/wanproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/af_x25.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/sysctl_net_x25.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_dev.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_facilities.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_in.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_link.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_out.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_route.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_subr.c#1 branch -... //depot/linux-aic79xx-2.4.0/net/x25/x25_timer.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/Configure#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/MAKEDEV.ide#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/Menuconfig#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/README.Menuconfig#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/checkconfig.pl#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/checkhelp.pl#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/checkincludes.pl#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/cramfs/GNUmakefile#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/cramfs/mkcramfs.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/docgen#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/docproc.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/gen-all-syms#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/header.tk#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/kernel-doc#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/ksymoops/README#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/BIG.FAT.WARNING#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/Makefile#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/checklist.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/colors.h#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/dialog.h#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/inputbox.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/lxdialog.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/menubox.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/msgbox.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/textbox.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/util.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/lxdialog/yesno.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/makelst#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/mkdep.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/patch-kernel#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/pathdown.sh#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/split-include.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/tail.tk#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/tkcond.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/tkgen.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/tkparse.c#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/tkparse.h#1 branch -... //depot/linux-aic79xx-2.4.0/scripts/ver_linux#1 branch - -Change 563 by gibbs@aslan on 2002/01/22 11:00:23 - - aic79xx.c: - Add initial AHD_PKT_BITBUCKET_BUG and overrun handling. - In the cases where the hardware will allow such a - situation, we will transfer data into on overrun - buffer in host memory to simulate a bitbucket. - - aic79xx.h: - AHD_PKT_BITBUCKET_BUG definition. - - aic79xx.reg: - Add per-mode location for saving the accumulator during - interrupt handlers. - - Add bits describing an overrun condition. - - Add a downloadable constant for defining the - overrun buffer location. - - aic79xx.seq: - Turn freeze_queue into a subroutine and have it - save and restore the accumulator around using it. - - Add preliminary support for handling overruns. - - aicasm/aicasm.c: - Formatting nits. - - aicasm/aicasm_gram.y: - aicasm/aicasm_symbol.h: - Allow constants to be larger than 8bits. The sequencer - will still complain if an expression doesn't manipulate - the constant into a form that fits in 8bits during an - assignment. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#22 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#15 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#18 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#19 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#13 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#13 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#9 edit - -Change 554 by gibbs@overdrive on 2002/01/22 00:14:54 - - scsi_iu.h: - Add a header file describing datastructures of - SCSI Information Units. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_iu.h#1 add - -Change 552 by gibbs@overdrive on 2002/01/21 23:50:24 - - aic7xxx_osm.c: - block_size() is only available in very recent - kernels. Use 1024 for anything earlier than 2.4.17. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#84 edit - -Change 529 by gibbs@overdrive on 2002/01/21 14:19:18 - - aic7xxx_host.h: - Correct idempotency ifdefs. - - aic7xxx_osm.c: - Use "block_size" rather than a hard coded 1024 to - access the underlying device in search of an fdisk table. - - aic7xxx_osm.c: - Protect code unreferenced if MMAPIO is flase. - - Use pci_set_drvdata(), rather than touching the - PCI device structure manually. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#83 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#30 edit - -Change 504 by gibbs@aslan on 2002/01/15 13:23:22 - - aic79xx.c: - Set SAVED_SCSIID and SAVED_LUN to invalid values - everytime we restart the sequencer. - - Panic() after dumping card state should we complete - an SCB twice. This will be removed prior to release. - - Add panics after most calls to ahd_dump_card_state(). - This guarantees that we can capture any diagnostic - output. - - Implement status packet fetching. In the future we - may embed the sense data location into the SCB so - a sequencer interrupt is not necessary, but for now - we let the kernel fill in the sense address. - - Add sequencer interrupt codes for failures of diagnostics - performed by the sequencer. - - Properly set the bug variable to include all bugs we - have workarounds for. - - Add support for using the abort feature (once it works) - to catch references by a target to tag identifiers that - are not allocated. - - Protect the routines parsing the execution list from - infinite transaction loops. - - Enahance ahd_dump_card_state to include more information. - - aic79xx.h: - Move derivative register access routines to aic79xx_inline.h. - Using inline functions allows type promotion which aids in - gracefully handling quads. - - aic79xx.reg: - Add additional sequencer interrupt codes. - - Fix a typo in the definition of LQIABORT. - - Define the sequencer stack size. - - aic79xx.seq: - Revert to non-inlined version of load_first_seg. The - bug that this "worked around" has been addressed. - - Use calls to setjmp in our interrupt handler rather than - manually setting the longjmp address. - - aic79xx_inline.h: - Add routines for syncing sense buffers. - - Add inline versions of the derivative register - access methods (inw, inq, etc.). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#21 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#14 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#17 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#18 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#16 edit - -Change 503 by gibbs@aslan on 2002/01/13 20:57:51 - - Packetized checkpoint. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#17 edit - -Change 495 by gibbs@aslan on 2002/01/09 09:29:03 - - aic7xxx.c: - Set both SAVED_LUN and SAVED_SCSIID to impossible values - in ahc_restart(). We can't trust these fields until the - sequencer trusts them again and since we didn't initialize - them explicitly during startup, a rogue interrupt could - have caused us to access them, generating a parity error. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#54 edit - -Change 493 by gibbs@aslan on 2002/01/08 12:39:10 - - Setup task attributes (tag type) for packetized transactions. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#15 edit - -Change 492 by gibbs@aslan on 2002/01/08 11:20:40 - - aic79xx.c: - Add additional trace sequencer interrupt codes. - - Make a fist pass at handling unexpected bus frees. We - now expect a busfree at the end of any PPR negotiation - that results in a change in the IU_REQ agreement. - - Don't set PACED transfers for async speeds. This bug - didn't seem to upset the chip, but who knows. - - Fix a bug in initialization of the per-device annex - data. Start at the PRECOMP column and allow - auto-increment to do the rest. - - Enable IU/QAS/RD_STRM/WR_FLOW negotiation. - - Enable searching through the pending list for SCBs to - abort in ahd_abort_scbs(). - - Print out FIFO status in ahd_dump_card_state(). - - aic79xx.reg: - Add more debugging SEQINTCODEs. - - Add definitions for the BUSFREETIME status bits. - - Correct definition of the PRECOMP annex column. - - Add FETCH_INPROG to SG_STATE for workaround of - SG_CACHE_AVAIL coming true soon than expected. - - Change DRAINING_SCB to LONGJMP_SCB as the SCBID - is now set for many different longjmp routines. - - aic79xx.seq: - Add code to drain the good status fifo. - - Service longjmp routines in order to clear FIFOs - for a non-packetized transaction. - - Complete the workaround for Razor #494. - - SG_CACHE_AVAIL will come true in the other FIFO as - soon as the FIFO using the SG_CACHE has provided - enough segments to satify it's transfer or has seen - saveptrs status. Use FETCH_INPROG state to guard against - this early switch confusing the other FIFO into believing - it has valid SG data. - - Clear SG_FULL_RESID from both the SCB_SGPTR and the - RESIDUAL_SGPTR by clearing the flag in SCB_SGPTR prior - to the copy to the residual field. - - Update the calc_resid subroutine to include the setting - of the residual datacnt. - - Remove the monitor_drain handler. We rely on the data - FIFO's high priority to handle this case. - - Only defer completions if a longjmp routine for the - SCB of interrest is still active. This simplifies - the check_fifo routine. - - Inline the good_status_IU handler to lose a stack level. - - aic79xx_inline.h: - Clear the task_management field if we are packetized. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#20 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#13 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#16 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#16 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#14 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#53 edit - -Change 485 by gibbs@overdrive on 2001/12/17 23:07:26 - - aic79xx_osm.c: - Correct typos and style nits. - - Properly track the transfer length in - scb->platform_data->xfer_len. We failed to - update this variable during the conversion to - use the Core ahd_sg_setup() routine. - - Increment cur_seg instead of using the first - segment for every segment in the transfer. - - Remove target_offset. Since single function - twin chips don't exist in the 79XX class, target_offset - and target are synonymous. - - If we don't have a "linux target" structure for for - a device pertaining to an async event, don't service - the event. - - aic79xx_osm_pci.c: - Linux counts every 4 bytes of config space as a bar - regardless of whether the BAR is 64bit or not. Update - use of pci_resource_start() to reflect this strange - method of indexing. - - Correct check of retrieved ioport bases. base and - base2 are pointers. - - Correct think-o in mapping regsiters. We only want to - attempt IO space if maddr is NULL indicating that - memory mapped space is not available. - - aic7xxx_osm.c: - Style nit. - - If we don't have a "linux target" structure for for - a device pertaining to an async event, don't service - the event. - - aic7xxx_osm_pci.c: - Correct check of retrieved ioport base. - base is a pointer. - - Correct think-o in mapping regsiters. We only want to - attempt IO space if maddr is NULL indicating that - memory mapped space is not available. - - aicasm/Makefile: - yacc in some distributions does not support the -o - output option. Modify the Makefile to avoid using - this feature. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#82 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#29 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#10 edit - -Change 484 by gibbs@overdrive on 2001/12/17 21:32:02 - - Disable information unit transfers for now. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#19 edit - -Change 483 by gibbs@overdrive on 2001/12/17 15:23:19 - - aic79xx_osm.c: - Remove vestigial call to aic7770_linux_probe(). This driver - does not support that chip. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#4 edit - -Change 482 by gibbs@overdrive on 2001/12/17 13:43:35 - - Include SPI4 PPR options. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#4 edit - -Change 481 by gibbs@overdrive on 2001/12/17 13:43:25 - - Set SCB_PACKETIZED on all packetized SCBs. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#3 edit - -Change 480 by gibbs@overdrive on 2001/12/17 13:43:06 - - Prepare for release 0.0.0 of the aic79xx driver. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#4 edit - -Change 479 by gibbs@aslan on 2001/12/17 13:27:15 - - aic79xx.c: - aic79xx.seq: - Initialize SG_STATE to 0 for sanity on card initialization - and anytime a new transfer is started where additional - segments are not needed. - - aic79xx.reg: - SG_SENSE is no longer needed. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#18 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#15 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#15 edit - -Change 478 by gibbs@overdrive on 2001/12/17 11:44:16 - - aic7xxx.h: - Remove alternate bus space tag handles. We don't bother - holding the unused regions any more. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#37 edit - -Change 477 by gibbs@aslan on 2001/12/17 11:43:03 - - aic79xx.c: - Break out the computation of "post patch" sequencer - addresses so we can use it to compute the location - of the sequencer's interrupt handler. - - Start the process of marking Rev A bugs with the - AHD_SENT_SCB_UPDATE_BUG. - - Expand PPR option rules to include all supported - options. - - Correct the setting of precompensation values to - reflect fixes in the A2. - - Begin the process of handling PPR negotiations that - end in a bus free due to a change in IU_REQ. - - Enhance DFF mode specific initialization to include - the LongJmp address and the interrupts we want enabled. - - We must be in the SCSI mode to initialize the - negotiation table. - - Enable write flow control, read streaming and - information units if the SEEPROM tells us to enable - packetized. - - aic79xx.h: - Add AHD_SENT_SCB_UPDATE_BUG definition. - - Add SCB flags indicating packetized transaction and - a PPR that should result in a busfree. - - aic79xx.reg: - Add additional sequencer interrupt codes for packetized - failure modes. - - Allow the STACK and LASTSCB to be written two. The - STACK needs to be written for longjump operations. - LASTSCB needs to be written for the AHD_SENT_SCB_UPDATE_BUG. - - Add PRECOMP constants. - - Move DATA_COUNT_ODD to per-mode scratch. - - Add STATUS_RCVD field to SCB_CONTROL. - - A status code of STATUS_PKT_SENSE indicates sense - data was recieved for this packetized transaction. - - Set the high bit of LONGJMP_ADDR to indicate that - it is no longer valid. - - aic79xx.seq: - Add setjmp/longjmp support. - - Implement AHD_SENT_SCB_UPDATE_BUG workaround. - - Break out first segment load, SCB completion, - residual calculation and save pointers so they - can be used for packetized operations. - - Make a first cut at sequencer interrupt services - for packetized operations. - - aic79xx_inline.h: - aic79xx_osm.c: - Use an SCB flag to indicate that a transaction is - packetized freeing up a bit in SCB_CONTROL for - STATUS_RCVD. - - aic79xx_pci.c: - Add compaq IDs. - - aicasm/aicasm_gram.y: - aicasm/aicasm_scan.l: - aicasm/aicasm_symbol.c: - aicasm/aicasm_symbol.h: - Add the ability to export a sequencer label to - the host driver. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#17 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#12 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#14 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#14 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#13 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#8 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#12 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#9 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#12 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#8 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#3 edit - -Change 475 by gibbs@overdrive on 2001/12/13 14:45:21 - - aic79xx_osm.h: - Put definition of KERNEL_VERSION into a more - appropriate place. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#3 edit - -Change 474 by gibbs@overdrive on 2001/12/13 14:43:24 - - Makefile: - Delete common makefile. Each version of Linux is - so different that having one Makefile isn't practical. - Our build process has not referenced this version for - some time. - - aic7770_osm.c: - Pass port information into aic7770_config rather than - using a back door through the bus tag and handle to - get it. This allows us to properly clean up mappings - should our attach fail. - - Port is now passed into aic7770_map_registers. - - Don't set platform data irq field until allocation is - successful. This avoids freeing attempting to free - an IRQ we don't own during teardown of a failed attach. - - aic79xx_osm.c: - Clean up unmapping of SCB data. In the single buffer case, - we now store the bus address for the buffer in the SCB - platform data so we don't need to recreate it from the - S/G list. The S/G list may be changed by and auto request - sense operation, so it cannot be trusted. - - Formatting nits. - - Allow DT transfers to devices that only claim SCSI_2 if they - have the DT_REQ bit set in thier inquiry data. This fixes - slow transfers on certain IBM drivers. - - aic79xx_osm.h: - Add powerof2 #define. - - Add buf_busaddr into the SCB platform data. - - aic79xx_osm_pci.c: - Correct comments to reflect reality. - - aic7xxx_osm.c: - Only define modversion info in this file. This should fix - builds on 2.2.X kernels. - - Clean up unmapping of SCB data. In the single buffer case, - we now store the bus address for the buffer in the SCB - platform data so we don't need to recreate it from the - S/G list. The S/G list may be changed by and auto request - sense operation, so it cannot be trusted. - - Initialize platform IRQ field to unallocated value so we - don't inadvertantly free an IRQ we don't own in ahc_free(). - - Use AHC_NUM_LUNS rather than hard coded value. - - Properly initialize sg_count prior to mapping any segments. - - Allow DT transfers to devices that only claim SCSI_2 if they - have the DT_REQ bit set in thier inquiry data. This fixes - slow transfers on certain IBM drivers. - - aic7xxx_osm.h: - Add tasklet include and adjust for movement of files. - - Add buf_busaddr to scb_platform_data. - - Add define for AHC_LINUX_NOIRQ. - - Adjust for new prototype for aic7770_map_registers. - - aic7xxx_osm_pci.c: - Properly release memory regions if we fail to ioremap them. - In general clean up how we allocate memory regions. - - Don't set platform data irq field until allocation is - successful. This avoids freeing attempting to free - an IRQ we don't own during teardown of a failed attach. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#9 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#81 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#74 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#28 edit - -Change 473 by gibbs@aslan on 2001/12/07 17:48:46 - - aic79xx.c: - Initialize new SG_STATE, per DFF, scratch ram variable. - - Display SG_STATE information when dumping card state - while in a DFF mode. - - aic79xx.reg: - Add SG_STATE and SAVED_MODE scratch ram variables. - - aic79xx.seq: - Move the return label to a location where there is - already a solicatry return instruction. - - Add code to service FIFOS for packetized transactions - to the main idle loop. - - We can't rely on ARRDONE after ARREN is disabled. The - chip clears that bit at the same time ARREN is cleared. - Remove a comment about an optimization we could perform - if ARRDONE stayed set. - - Add a comment explaining why we must disable interrupts - when setting the mode pointer register. - - Have allocate FIFO service FIFOs so it can free them - up. We still require both FIFOs to be free for a - non-packetized request. - - Optimize the delivery of an unpacketized cdb. If we - are using SCB internal storage, we can bypass the - SG FIFO and set SHCNT directly. This shaves ~12 clocks - of the start of the cdb transfer. - - Start using CLRCHN instead of RSTCHN. There is still - more optimization that can occur in the non-packetized - path in terms of deferring DFIFO teardown. - - Modify data_group_idle_loop to service the other FIFO - as well as perform SCB prefetch/completion type - activities. - - Use SG_STATE to track S/G prefetch and FIFO servicing - requirements. - - Clear SG_STATE when the last segment is loaded or we - have completed this data group transfer (last segment - done or phasechange). - - If we go into an overrun condition, release the FIFO - by performing a reset channel if a FIFO is still - allocated. - - Change ultra2 -> data_group in all labels. - - Rely exclusively on SCSIEN going away to signal end - of a data transfer. SCSIEN transitions on last segment - done, so testing for it in the loop too is superfluous. - - aic79xx_inline.h: - Add a better comment for why we read from the MODE_PTR - register after every SCB ram read. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#16 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#13 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#13 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#12 edit - -Change 470 by gibbs@aslan on 2001/12/04 17:09:19 - - aic79xx.seq: - Convert ccsg idle loop into a proceedure so it can - be used in places other than the main idle loop. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.seq#12 edit - -Change 469 by gibbs@aslan on 2001/12/02 14:30:08 - - aic79xx.c: - Add a trace point for printing out saved pointer and residual - data from an SCB. - - Remove a hardware workaround that is no longer needed for - H2A2 and beyond. - - Quite some diagnostic code. - - Trim our downloaded constants down to only those needed. - - Add a #error if the number of downloaded constants grows - or shrinks from the number we currently initialize. - - Perform more robust calculations to determine the constants - used for S/G element prefetch. - - aic79xx.reg: - Add the saved/residual tracepoint to SEQINTCODE. - - Trim unused downloaded constants. - - aic79xx.seq: - Make use of SG_PREFETCH_CNT_LIMIT constant in handling - S/G fetch. This ensures that a complete segment is - still left in the buffer prior to attempting to use it. - - Assume the kernel will start the DMA after a PDATA_REINIT - call. - - Correct some comments. - - Don't clear the data channel after a data group phase. - Defer this to await busfree. This guarantees that SHADDR - is still valid should a saved data pointers occur. - - aic79xx_inline.h: - Add "ahd_inl_scbram()". - - aic79xx_osm.c: - Correct another case where we were still using an - ahd_syncrate. - - aicasm/aicasm_gram.y: - Don't complain about an immediate aliasing the accumulator - if the immediate is a downloaded constant. - - aicasm/aicasm_symbol.c: - Output a #define for the number of downloaded constants - the sequencer program is expecting. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#15 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#12 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#11 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#11 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#11 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#11 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#2 edit - -Change 468 by gibbs@overdrive on 2001/11/28 15:47:30 - - aic79xx_host.h: - aic79xx_osm.c: - aic79xx_osm.h: - aic79xx_osm_pci.c: - aic79xx_proc.c: - First cut at Linux U320 OSM layer. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#1 add - -Change 467 by gibbs@aslan on 2001/11/28 15:45:19 - - aic79xx_pci.c: - Correct include location under Linux. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#7 edit - -Change 466 by gibbs@aslan on 2001/11/28 15:43:12 - - aic79xx.c: - aic79xx.reg: - Linux's kernel ffs() implementation doesn't handle - constants properly on x86. Compensate by using - a constant for the bit offset as well. Grrrr! - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#14 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#11 edit - -Change 465 by gibbs@aslan on 2001/11/28 14:55:16 - - aic79xx.c: - Remove debugging printfs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#13 edit - -Change 464 by gibbs@aslan on 2001/11/28 14:46:07 - - aic79xx.c: - Remove Debugger() statements that Linux doesn't understand. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#12 edit - -Change 463 by gibbs@overdrive on 2001/11/28 14:43:42 - - aic79xx_inline.h: - Avoid code bloat by only including 64bit S/G format - code if sizeof(bus_addr_t) > 4. The compiler should - optimize out this code if this check against a constant - fails. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#10 edit - -Change 462 by gibbs@aslan on 2001/11/28 14:41:51 - - aic79xx.h: - aic79xx_pci.c: - Put PCI BAR offsets into a header where - all OSMs can see them. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#11 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#6 edit - -Change 461 by gibbs@aslan on 2001/11/27 17:52:25 - - aic79xx.h: - Pull ahd_inw/l/q and ahd_outw/l/q into Core header file. - - aic79xx_osm.h: - Mask off top port bit when doing I/O. - - ahd_pci.c: - Map a subregion for bshs[1], offset by 256 bytes, when we are - doing memory mapped I/O. This compensates for the masking - of the port performed above. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#10 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#2 edit -... //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#2 edit - -Change 459 by gibbs@overdrive on 2001/11/27 13:32:05 - - Enable ID expansion. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#11 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#9 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#10 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#10 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#9 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#5 edit - -Change 458 by gibbs@overdrive on 2001/11/27 13:29:05 - - Allow FreeBSD and Linux to fully share core files. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#16 edit -... //depot/aic7xxx/aic7xxx/aic79xx.c#10 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#52 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#36 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#12 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#34 edit - -Change 454 by gibbs@overdrive on 2001/11/25 17:22:22 - - Complete the update of the assembler. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#1 add -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#1 add - -Change 453 by gibbs@overdrive on 2001/11/25 15:46:40 - - aic7xxx_osm.c: - Add a function to pull out user tag depth information. - Use it to limit the per-device tag depth. The kernel - will never send us more commands than this limit anyway - since we honor this limit in select queue depths, but - this will make the information in /proc jibe with the - users settings and prevent some confusion. - - On kernels that support them (>= 2.4.0), use a tasklet - to flush any queued commands pent up in our per-device - queues - - Use an inline function, ahc_linux_next_device_to_run(), - to factor out some common code. - - aic7xxx_osm.h: - Add structures for our tasklet to the linux platform - softc. - - aicasm/Makefile: - Update for second parser/scanner in the assembler. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#80 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#73 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#9 edit - -Change 452 by gibbs@overdrive on 2001/11/25 15:32:58 - - aic7770.c: - Disable chip interrupts early in chip attach. - We poke a few registers on the chip prior to - resetting it so this narrows the window where - an unexpected interrupt could hang us. - - Convert all exported symbols to use an "ahc" - prefix to avoid conflicts with other drivers. - - Use a common SEEPROM checksum. - - aic7xxx.c: - Clear any pending message state in ahc_restart(); - - Pass the ahc softc to ahc_update_residual. - ahc_update_residual calls ahc_calc_residual which - requires the softc to print path information if - debugging is enabled. - - Don't bother clearing message state just prior - to calling ahc_restart(); - - Always perform a bus read prior to waiting in - a delay loop waiting for a bus write to take - effect. This ensures that the first time - through the loop the delay occurs after the - write has taken effect. - - Style cleanup. - - Remove some initialization code left over from - a previous way of probing SCBs. - - Always clear parity error status after reading - any SCB or scratch locations that might be - uninitialized. The debugging code that dumps - scratch ram contents could trigger such an - event. - - Initialize any scratch ram locations that might - be read (by our interrupt handler most likely) - prior to being initialized by our first transaction. - SAVED_SCSIID falls into this category, but there - may be others. - - Remove some unecessary code. In this case, the - varaible "next" was initialized unecessarily which - could hide "use before initialization" bugs. - - Add some more information to ahc_dump_card_state(); - - aic7xxx.h: - Update ahc_update_residual() declaration. - - Move AHC_DEBUG definitions to this header. - - aic7xxx.reg: - aic7xxx.seq: - Update for changes in the assembler. - - aic7xxx_93cx6.c: - aic7xxx_93cx6.h: - Prefix exported symbols with "ahc". - - aic7xxx_inline.h: - Update ahc_update_residual() definition. - - Target mode command completions come in through - the qinfifo, so we must read it even if we are - only executing the target role. - - Change to power state D0 prior to mapping our - registers. BARs are usually cleared by a power - state change. - - Disable chip interrupts early in chip attach. - We poke a few registers on the chip prior to - resetting it so this narrows the window where - an unexpected interrupt could hang us. - - Use symbols prefixed by "ahc". - - Clear any parity errors that might occur while - trying to pull uninitialized SCB2 information. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#15 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#51 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#35 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#25 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#38 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#11 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#8 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#32 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#33 edit - -Change 451 by gibbs@overdrive on 2001/11/25 15:05:14 - - Teach the assembler about simple 'C' macros. - - Add a second parser/scanner to handle macro expansions. - - The arguments to patch functions are now specified in the - source file rather than be hard coded. - - Use the "driver neutral" "aic_patch_#_func() to denote the - static functions used to patch sequencer code. - - staticize all generated code to avoid conflicts when mutliple - drivers are compiled together. - - Teach the driver about register window modes. Have the assembler - complain if a register is accessed in a window that is not supported - by the register. - - Allow '<<' and '>>' expressions. They are evaluated during assembly. - - Complain if an expression used as an "immediate or the accumulator" - argument evaluates to 0. 0 is an alias for the accumulator in these - instruction formats and referencing the accumulator in these - situations is likely not the desired effect. - - BUGS: Line numbers get screwed up on program listing when macros are - used. The assembler should output the expanded code into the - listing file so line numbers and instruction lines make sense. - Line numbers in error messages may also be wrong for macros, - but I haven't verified this. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#12 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#8 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#10 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#8 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#10 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#7 edit - -Change 448 by gibbs@aslan on 2001/11/19 21:22:51 - - Checkpoint. Tagged queuing now works. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#9 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#8 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#9 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#9 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#8 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#4 edit - -Change 447 by gibbs@aslan on 2001/11/17 21:06:51 - - Checkpoint: U160 now operational. - - Deal with the NEG table. And NEG table bugs. - - Implement IOCELL workarounds. - - Deal with missing DIS_MSGIN_DUAL in OPTIONMODE register. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#8 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#7 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#8 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#8 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#7 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#3 edit - -Change 445 by gibbs@aslan on 2001/11/14 16:49:32 - - Checkpoint. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#7 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#6 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#7 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#7 edit - -Change 444 by gibbs@aslan on 2001/11/13 21:49:20 - - Checkpoint. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#6 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#5 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#6 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#6 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#6 edit - -Change 442 by gibbs@aslan on 2001/11/13 14:07:10 - - Checkpoint. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#5 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#4 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#5 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#5 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#5 edit - -Change 440 by gibbs@aslan on 2001/11/08 21:14:12 - - Checkpoint. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#4 edit -... //depot/aic7xxx/aic7xxx/aic79xx.h#3 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#4 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#4 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#4 edit - -Change 439 by gibbs@aslan on 2001/11/07 18:54:07 - - Checkpoint. Selection Timeout path now operates. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#3 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#3 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#3 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#3 edit - -Change 438 by gibbs@aslan on 2001/11/07 17:28:10 - - Checkpoint. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#2 edit - -Change 437 by gibbs@aslan on 2001/11/07 15:41:15 - - Checkpoint. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.h#2 edit -... //depot/aic7xxx/aic7xxx/aic79xx.reg#2 edit -... //depot/aic7xxx/aic7xxx/aic79xx.seq#2 edit -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#2 edit -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#2 edit - -Change 435 by gibbs@aslan on 2001/10/25 13:28:33 - - Initial 790X Core driver import. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic79xx.c#1 add -... //depot/aic7xxx/aic7xxx/aic79xx.h#1 add -... //depot/aic7xxx/aic7xxx/aic79xx.reg#1 add -... //depot/aic7xxx/aic7xxx/aic79xx.seq#1 add -... //depot/aic7xxx/aic7xxx/aic79xx_inline.h#1 add -... //depot/aic7xxx/aic7xxx/aic79xx_pci.c#1 add - -Change 421 by gibbs@overdrive on 2001/10/11 15:33:59 - - Bump version to 6.2.4. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#72 edit - -Change 420 by gibbs@overdrive on 2001/10/11 15:33:30 - - aic7xxx_osm.c: - Move the include of linux/module.h to our osm header file. - - Add a MODULE_LICENSE entry. - - Don't forget to include the high address bits in - calls to pci_unmap_single(). - - Fix a typo in a comment. - - Use hex instead of decimal when reporting return codes - to our exception handling routines. - - aic7xxx_osm.h: - Include, unconditionally, linux/module.h. - - aic7xxx_osm_pci.c: - Add a MODULE_DEVICE_TABLE entry for our PCI ids. - - Formatting cleanup. - - Use a simpler way of expressing "all bits set in something - the size of a bus_addr_t" without getting compiler warnings - on some platforms. - - Kill an unused variable. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#79 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#71 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#27 edit - -Change 419 by gibbs@overdrive on 2001/10/11 15:21:15 - - aic7xxx.c: - Force renegotatiation of transfer parameters on the - next command to a device after a selection timeout or - a parity error. - - Fix a typo in a comment. - - Put SCBs that aren't in the scbindex table and not already - in the free list, back into the free list. This can happen - in certain "SCB queued twice for abort processing" cases. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#50 edit - -Change 408 by gibbs@overdrive on 2001/09/13 17:49:29 - - Still part of the 6.2.3 release... - - aic7xxx.c: - Export ahc_abort_scbs() for use by OSMs. - - In ahc_abort_scbs(), only remove entries from - the busy target table that match the abort - criteria. In the past, we might take out any - entry for a particular target. - - In ahc_abort_scbs() only search the disconnected - list and busy target table if the role is not - ROLE_TARGET. - - aic7xxx.h: - Export ahc_abort_scbs() for use by OSMs. - - aic7xxx.reg: - Add a definition for the SCSI offset count in - SSTAT3 for U2+ adapters. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#49 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#34 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#24 edit - -Change 391 by gibbs@overdrive on 2001/09/12 13:14:51 - - Update version for 6.2.3 driver release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#70 edit - -Change 390 by gibbs@overdrive on 2001/09/12 13:14:00 - - Update copyright to reflect new binary distribution disclaimer - clause (if you choose BSD license terms) and Adaptec copyright. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#78 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#69 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#26 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#13 edit - -Change 389 by gibbs@overdrive on 2001/09/12 13:07:18 - - Update copyright to reflect new binary distribution disclaimer - clause and Adaptec copyright. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#14 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#48 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#33 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#23 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#37 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#10 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#7 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#31 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#32 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#11 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#7 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#9 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#7 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#7 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#9 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#6 edit - -Change 387 by gibbs@overdrive on 2001/09/11 15:31:45 - - aic7xxx_inline.h: - Remove spurious '{' that only came into effect if - target mode was compiled in. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#30 edit - -Change 386 by gibbs@overdrive on 2001/09/11 14:19:51 - - aic7xxx_osm.c: - Only run our shutdown hook for the SYS_DOWN and - SYS_HALT events. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#77 edit - -Change 385 by gibbs@overdrive on 2001/09/11 14:18:38 - - aic7xxx.h: - Add residual information to struct target_data to - allow residual information to be handled in the - same way as for the initiator role. Prior to this - fix, the status byte field was overwritten when the - residual count was saved to the SCB assuming the - residual was non-zero. - - aic7xxx.reg: - Adjust for change in SCB layout for target mode. - - aic7xxx.seq: - Adjust for change in SCB layout for target mode. - - Send an ignore wide residue message if we are acting - as a target in wide mode and complete a data-in phase - with an odd data count. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#32 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#22 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#36 edit - -Change 382 by gibbs@overdrive on 2001/09/10 17:31:46 - - aic7xxx_osm.c: - Initialize our host template's "max_lun" field. This may - correct an issue with probing big, multi-lun, devices in - Linux post 2.4.3. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#76 edit - -Change 381 by gibbs@overdrive on 2001/09/10 16:29:53 - - aic7xxx.c: - aic7xxx.h: - Add a new constant, AHC_SCB_MAX_ALLOC, which indicates - how many of the AHC_SCB_MAX scbs available on the card - we can actually allocate. This can be at most - AHC_MAX_QUEUE+1. The FreeBSD OSM, by virtue of CAM, already - enforced this limit. This change ensures that all OSMs - are restricted to this limit. - - aic7xxx_inline.h: - If CMDCMPLT is active in intstat, check all completion queues. - This corrects a race condition when target mode is enabled - that could allow us to miss running a queue that just received - a new command. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#47 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#31 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#29 edit - -Change 357 by gibbs@overdrive on 2001/09/06 13:25:10 - - aic7xxx_osm.h: - Add constants related to the "periodic_otag" feature. - - Increase the ordered tag threshold to 500 commands. - - Issue an mb() even when using PIO to talk to the card. - This may be necessary on platforms other than intel. - - Bump driver version to 6.2.2. - - aic7xxx_osm.c: - Remove comments/globals referencing unused driver options. - - Hook up the following driver options: - no_probe Disable EISA/VLB controller probing - no_reset Supress initial bus resets - extended Enable extended geometry on - all controllers - periodic_otag Send an ordered tagged transaction - periodically to prevent tag starvation. - This may be required by some older disk - drives/RAID arrays. - reverse_scan Sort PCI devices highest Bus/Slot to - lowest - - Don't attempt to set the PCI dma mask if we're an EISA/VLB - controller. - - Dump controller state on any abort/bdr instead of only when - the user has turned on the "verbose" option. This should - facilitate the generation of user bug reports. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#75 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#68 edit - -Change 356 by gibbs@overdrive on 2001/09/06 13:16:05 - - Only trust sub-device information on Adaptec cards. It seems - that many motherboard implementations do not follow the Adaptec - sub-device id spec. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#31 edit - -Change 340 by gibbs@overdrive on 2001/08/24 11:24:25 - - aic7xxx_osm.c: - Remove a no-longer relevant comment. - - Add information about our module parameters that - can be displayed by modinfo. - - Use the channel letter, rather than the number, as - we do in all other displays of this information. - - Never attempt PPR messages on a device that claims - to be SCSI2. Jaz drives hang, rather than reject - the message, and sending these messages to SCSI2 - devices is just too dangerous. - - Whitespace cleanup. - - aic7xxx_osm.h: - Include endian information for use by aicasm_insformat.h. - - aic7xxx_osm_pci.c: - Always reserve both our memory and I/O port range to guard - against other devices attaching to these same addresses. - We still only use one of the two regions for accessing the - card. - - aicasm/Makefile: - Add explicit dependencies on y.tab.h so it is rebuilt - prior to any files, even generated ones, that need it. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#74 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#67 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#25 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#8 edit - -Change 339 by gibbs@overdrive on 2001/08/24 11:17:35 - - aic7xxx.c: - Re-intialize LASTPHASE everytime we restart the sequencer. - This should make the value of LASTPHASE fully deterministic. - - Correct target mode handling of Abort and Abort Tag messages. - The sequencer now sets TARGET_MSG_PENDING whenever it runs - into an unexpected message while parsing "ident" messages - during a selection. We have to clear this flag whenever we - stop processing messages. We also need to restart the sequencer - for any abort message so that we return to busfree. - - Send the tag number along with the abort tag message immediate - notification message. - - The construct "foo(i++, i++, i++);" is not guaranteed to - give "expected" results by the C standard. Change some - diagnostic code to avoid this. - - Correctly set ahc->unpause to include the IRQMS bit on - non-PCI platforms. - - aic7xxx.reg: - Add TARGET_MSG_PENDING bit to the SEQ_FLAGS2 register. - - aic7xxx.seq: - During identify message processing, setup SAVED_LUN. We - may need it to handle certain types of messages. - - Handle unexpected messages that have already been REQ'ed - as well as those that have not been REQ'ed but should be - handled due to ATNI being active. - - Postpone the "queue full" determination until we are about - to transition to command phase. This should give the - initiator the ability to abort transactions even if our - queue would otherwise be full. - - aic7xxx_pci.c: - Take another stab at validating the 9005 subdevice information - prior to using it. We now ensure that the device type stated - in the device field is compatible with the one expressed in - the subdevice field. This should allow the latest report - of a "missing channel" to be probed again. - - aicasm/aicasm.c - Pull the platform endian file for userland operations from - here, so that the insformat header, which is shared with the - kernel, never gets the wrong file. The kernel driver will - deal with getting the correct endian values in its platform - specific file. - - aicasm/aicasm_insformat.h: - String #include of endian header files. This is now handled - by the client of this file. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#46 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#21 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#35 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#30 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#10 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#6 edit - -Change 330 by gibbs@overdrive on 2001/08/16 15:16:36 - - "GNU Public License" -> "GNU General Public License" - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#73 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#66 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#11 edit - -Change 329 by gibbs@overdrive on 2001/08/16 15:12:51 - - "Gnu Public License" -> "Gnu General Public License" - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#13 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#45 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#30 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#20 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#34 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#9 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#6 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#28 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#29 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#9 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#6 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#8 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#5 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#6 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#8 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#5 edit - -Change 323 by gibbs@overdrive on 2001/08/05 15:00:59 - - aic7xxx_linxu.c: - aic7xxx_osm_pci.c: - pci_set_dma_mask() became available in 2.4.3, not 2.4.0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#72 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#23 edit - -Change 322 by gibbs@overdrive on 2001/08/05 14:58:46 - - aic7xxx.c: - Correct an off by one in our critical section handling. - SEQADDR always reads the next instruction to execute, - so we must subtract one from its value before making - comparisons with entries in the critical section table. - - Kill a "too verbose" bootverbose printf. - - Print a few additional registers whenever we dump - card state. - - Show the SCB_CONTROL and SCB_TAG values for all pending - SCBs in card SCB ram when dumping card state. - - aic7xxx.seq: - Fix a bug introduced while optimizing the SDPTR path. - We would ack the SDPTR message twice on Ultra2 or better - chips if it occurred after all data had been transferred - for a transaction. - - Change our workaround for the PCI2.1 retry bug on some - chips. Although the previous workaround was logically - correct, its faster method of draining the FIFO seemed - to occassionally confuse the FIFO state. We now drain - the FIFO at half the speed which avoids the problem. - - aic7xxx_pci.c: - Chips with the PCI 2.1 retry bug can't handle a 16byte - cachesize. If the cachesize is set to 16bytes, drop - it to 0. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#44 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#33 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#28 edit - -Change 317 by gibbs@overdrive on 2001/07/18 16:19:54 - - Bump version to 6.2.0 Release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#65 edit - -Change 314 by gibbs@overdrive on 2001/07/18 14:17:17 - - Remove a stray '{' after a #endif. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#27 edit - -Change 311 by gibbs@overdrive on 2001/07/18 14:14:39 - - Only set AHC_RUN_TQINFIFO if we are performing the target role. - Otherwise there is no guarantee that the tqinfifo is even allocated. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#26 edit - -Change 309 by gibbs@overdrive on 2001/07/17 18:10:35 - - aic7xxx_osm.h: - Add definition for BUS_SPACE_MAXADDR_32BIT. This - is now used in our bus_dma_tag_create() operations. - - Remove a spurious return(0) I mistakenly added when - "fixing" compiler warnings for NOTREACHED code. - - aic7xxx_osm_pci.c: - Quite a compiler warning for code that cannot be reached - unless sizeof(dma_addr_t) > 4. We now mask our 39bit - mask with a mask based on the size of dma_addr_t so - we cannot have an overflowing assignment the compiler - will complain about. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#64 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#22 edit - -Change 308 by gibbs@overdrive on 2001/07/17 18:06:31 - - aic7xxx.c: - Enforce a 4GB boundary on all DMA transactions. Due - to 32bit DAC restrictions, 64bit addressed operations - cannot cross a 4GB boundary. This is enforced manually - in the Linux driver as bus tag boundaries are not honored, - but for FreeBSD, the tags are used by the OS dma map - routines to enforce the limits. - - Bus resets (initiated or incoming) clear the ENSELI bit - in the SCSISEQ register. For this reason, we cannot - defer the re-enabling of bus reset interrupts in target - mode - select-ins might get disabled and we'd never - know. - - aic7xxx.seq: - Remove sequencer code to re-enable bus reset interrupts - when we are selected as a target. - - aic7xxx_inline.h: - Correct calls to ahc_dmamap_sync. In Linux these are - no-ops, so the fact that we didn't reference our maps - correctly didn't show up. - - aicasm/aicasm.c: - aicasm/aicasm_symbol.c: - Use queue macros instead of groveling through queue - data structures manually. - - Fix a few style bugs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#43 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#32 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#25 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#8 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#7 edit - -Change 307 by gibbs@overdrive on 2001/07/16 17:31:46 - - aic7xxx.c: - style(9) fix. - - aic7xxx.seq: - Correct high address support for non-Ultra2 chips. - - Bring back a fix for flaky external SRAM support - on the aic7895. - - aic7xxx_inline.h: - In ahc_update_residual(), don't bother setting - a 0 length residual. The residual is cleared - prior to starting the command. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#42 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#31 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#24 edit - -Change 306 by gibbs@overdrive on 2001/07/16 17:26:24 - - aic7xxx_osm.c: - Clean out PCMCIA defines. This driver does not - require any special compile environment to serve - cardbus cards. - - Clear residual data prior to starting a new SCB. - The calculate residual code now only sets residual - information should a residual exist. - - Remove a redundant assignment to platform_data->xfer_len. - Our map_seg routine already updates this field. - - Manually set the DRIVER_SENSE bit in the result word - of commands that have had auto-sense. - - aic7xxx_osm.h: - Kill silly compiler warnings for no return with value - from functions that panic. - - aic7xxx_osm_pci.c: - Use more formal "ULL" designation on some constants. - - cam.h: - Remove unused, at least in Linux, definition of - CAM_SIM_QUEUED. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#71 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#63 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#10 edit - -Change 303 by gibbs@overdrive on 2001/07/11 17:51:28 - - Bump version to 6.2.0-BETA1. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#62 edit - -Change 302 by gibbs@overdrive on 2001/07/11 17:47:06 - - Remove another diagnostic printf. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#20 edit - -Change 301 by gibbs@overdrive on 2001/07/11 17:35:55 - - Place a diagnostic behind bootverbose. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#27 edit - -Change 300 by gibbs@overdrive on 2001/07/11 17:35:34 - - Add VERSION statements. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#19 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#30 edit - -Change 299 by gibbs@overdrive on 2001/07/11 17:34:54 - - Remove debugging printfs. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#70 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#19 edit - -Change 297 by gibbs@overdrive on 2001/07/10 18:23:07 - - Add support for the "VERSION" keyword. - - Print out all version information in generated files. - - Fix a bug in the handling of "include" statements. - For some reason this didn't show up until the version - changes were added. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#7 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#5 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#7 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#5 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#6 edit - -Change 295 by gibbs@overdrive on 2001/07/10 15:27:47 - - aic7xxx_osm.c: - Don't panic if the system decides to have us select - the queue depth for a non-existant device. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#69 edit - -Change 293 by gibbs@overdrive on 2001/07/10 14:23:44 - - aic7xxx_osm.c: - Properly ignore inquiry responses for VPD data or where - the amount of data that is actually transferred is not - enough for us to pull transfer negotiation information. - - Add synchronization of datastructures we share with - the hardware. - - Add a per-segment mapping helper function that deals - with 39bit addressing issues and complete 39bit - support. - - Fool the OS into always allocating our shared device/kernel - memory below the 4GB mark by changing our dma mask on - the fly. - - Add a method for determining the amount of memory in - the system. - - Run devices in a Round Robin fashion to ensure fairness. - - Correct code that handles temporary SCB resource shortages. - - Don't report bus resets until we have successfully registered - our host structure. - - aic7xxx_osm.h: - Add synchronization primatives. - - Add definition for the inquiry command for use in - our filtering function. - - Use system defined mb() macro rather than rolling our - own. Allow memory mapped I/O on the ia64. - - aic7xxx_osm_pci.c: - Enable 39Bit addressing if the system supports large - addresses on the platform and we have more than 2GB - of memory installed. Some systems move memory to - after the 4GB mark, reserving the 2-4GB range for - device memory mapping. - - Clean up a compile error when memory mapped I/O is - not enabled. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#68 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#61 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#18 edit - -Change 291 by gibbs@overdrive on 2001/07/10 13:43:58 - - aic7770.c: - Set fields directly in the softc rather than indirect - through the probe config structure. - - aic7xxx.c: - Add synchronization calls for data structures in - system memory that are shared between the kernel - driver and the controller. - - Several corrections to 39bit address support: - o 39bit support is a flag not a feature - in the ahc softc. - - o Perform endian conversions for high - address bits. - - Prevent PPR messages from being issued when acting - as a target. - - Add diagnostics in ahc_search_qinfifo() for tracking - down qinfifo corruption issues. - - aic7xxx.h: - Store a pointer to the sg_map_node in the scb to - allow scatter gather lists to be synced. - - aic7xxx.seq: - 39bit support is a flag not a feature in the ahc softc. - - aic7xxx_inline.h: - Add inlines to facilitate synchronization operations. - - Synchronize SCBs anytime we perform a lookup from - SCB ID to pending SCB and prior to queuing SCBs to - the adapter. - - Synchronize the first qoutfifo and tqinfifo when - checking for newly completed transactions. - - Fix several bugs in the spurious interrupt handling - in our interrupt handler. Hopefully this will stop - the reports of spurious PCI errors. - - aic7xxx_pci.c: - Add pci 64bit bus status bit definition for the - DEVCONFIG register. - - Be even more careful in checking that a 9005 subdevice - ID is valid prior to processing it. This should prevent - us from dropping the second channel on some MB controllers. - - Set fields directly in the softc rather than indirect - through the probe config structure. - - Set the DAC enable bit when in 39bit addressing mode. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#12 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#41 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#29 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#29 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#23 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#26 edit - -Change 277 by gibbs@overdrive on 2001/06/18 14:52:58 - - Switch to round-robin scheduling of devices to ensure fairness - during resource contention. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#67 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#60 edit - -Change 276 by gibbs@overdrive on 2001/06/18 14:47:51 - - aic7xxx.c: - Spelling fixes. - - Handling data pointers reinitialization requests - from the sequencer. This only occurs should the - target take us into the data phase twice with - an interviening non-data phase. - - On a data overrun, clear the channel of all preloaded - S/G segments if we are an Ultra2 controller. This - error path does not go through the normal dma shutdown - path, so we have to clear the S/G fifo while the kernel - is recording the overrun event. - - Clear AHC_ULTRA rather than deal with the AHC_ULTRA_DISABLED - flag. - - Fixup a few cases where we were not properly byte swapping - S/G element data in the ignore wide residue handler. Update - this routine for 39bit addressing support. Remove the - reload of the explicit HADDR registers. We now do this at - the time we re-enter the dataphase, which, in 90% of the - cases, will never happen. - - Add the ahc_reinitialize_dataptrs() routine. This is called - to fixup the dma engine's data pointers should we re-enter - a data phase with some interveining phase. This used to - be handled in the sequencer, but is so rare (i.e. almost - never happens), that there is little reason to waste - sequencer space on it. - - aic7xxx.h: - Remove AHC_ULTRA_DISABLED ahc_flag. - - Add AHC_39BIT_ADRESSING ahc_flag. - - aic7xxx.reg: - Add the DSCOMMAND1 register which holds the high - address load select bits. - - Add the PDATA_REINIT sequencer interrupt code. - This is hit should we re-enter a data phase and - need help from the kernel to restore the data ptrs. - - Remove the RESIDUAL sequencer interrupt code. - It has not been used for some time. - - aic7xxx.seq: - Spelling fixes. - - Streamline the ULTRA2 idle loop. The HADDR register - is not directly shaddowed, so we can read the contents - placed there by the bmov out of CCSGRAM. - - Remove data_phase_reinit. This is now handled by a - sequencer interrupt request to the kernel. - - Remove the assert method. We now do the test inline - which saves two instructions per call. - - Add 39bit addressing support. - - Add shortcuts for updating our residual pointers and - handling SDPTR messages when we are at the end of - a transfer. - - aic7xxx_inline.h: - Change the way that unsolicited interrupts are counted. - We now only increment and/or test the unsolicited interrupt - count if we see that we don't have any conventional - interrupts pending. More importantly, everytime we do - unsolicited interrupt processing, we clear the count. - This prevents us from constantly performing unsolicited - interrupt handling. - - aic7xxx_pci.c: - Set CLRPARERR in CLRINT for all PCI error status. The - manuals are not sufficiently clear on which status code - cause parity errors to be set, so we play it safe. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#40 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#28 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#18 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#28 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#8 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#22 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#25 edit - -Change 207 by gibbs@overdrive on 2001/05/01 16:18:08 - - Bump driver version to 6.1.13. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#59 edit - -Change 206 by gibbs@overdrive on 2001/05/01 16:16:11 - - aic7xxx.seq: - For chips without S/G pipelining, we can only ack the - SDPTR message after SHADDR has been saved. On these - chips, SHADDR increments with every bus transaction, - even PIO. This corrects a data corruption bug in the - last version of the sequencer for non-ULTRA2 chips. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#27 edit - -Change 205 by gibbs@overdrive on 2001/05/01 15:04:36 - - aic7xxx_osm.c: - Add support for the 2.4.4 scsi_set_pci_device API. - - aic7xxx_osm.h: - Move the conditional declaration of KERNEL_VERSION to - the top of aic7xxx_osm.h so it is defined before - its first usage. - - Remove late conditional include of linux/version.h. We - already include it unconditionally at the top of this file. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#66 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#58 edit - -Change 203 by gibbs@overdrive on 2001/05/01 13:07:13 - - Makefile: - Add the current directory to the include path. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#7 edit - -Change 202 by gibbs@overdrive on 2001/05/01 13:02:15 - - aic7xxx_osm.c: - Don't unregister from the reboot notification chain - from within our handler. The routine that calls down - the chain does not guard against removals. - - Create a simq_freeze method as a compliment to the - simq_release method. This method assumes that the - ahc lock is held prior to call. The release method - requires a lock as it is only called from a timeout - handler. The release method now guards (other than - for a small race that cannot be avoided without a - mid-layer change) unblocking and blocking multiple times. - Blocking is either on or off; the mid-layer does not - have semaphore type semantics for this feature. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#65 edit - -Change 196 by gibbs@overdrive on 2001/04/27 14:24:13 - - Bump version number to 6.1.12 for next release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#57 edit - -Change 195 by gibbs@overdrive on 2001/04/27 14:23:37 - - aic7xxx_osm.c: - current -> curr - - Implement a kludge to deal with inquiry requests that - are not large enough for us to pull the spi3 bits. - In this case, we assume that a device that tells us - they can provide inquiry data that spans the SPI3 - bits can handle a PPR request. If the inquiry - request has sufficient buffer space to cover these - bits, we check them to see if any ppr options are - available. This corrects the drop to async narrow - for U160 devices during a cdrecord bus scan. - - aic7xxx_osm.h: - Remove the kludge to undefine "current". We've renamed - any effected fields in the driver to avoid a conflict. - - dma_addr_t appeared in 2.2.18, not 2.2.17. - - aic7xxx_proc.c: - current -> curr - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#64 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#56 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#11 edit - -Change 194 by gibbs@overdrive on 2001/04/27 14:19:04 - - aic7xxx.c: - current->curr to avoid Linux's use of current as a - #define for the current task on some architectures. - - Add a helper function, ahc_assert_atn(), for use in - message phases we handle manually. This hides the fact - that U160 chips with the expected phase matching disabled - need to have SCSISIGO updated differently. - - if (ahc_check_residual(scb) != 0) - ahc_calc_residual(scb); - else - ahc_set_residual(scb, 0); - - becomes: - - ahc_update_residual(scb); - - Modify scsi parity error (or CRC error) handling to - reflect expected phase being disabled on U160 chips. - - Move SELTO handling above BUSFREE handling so we can - use the new busfree interrupt behavior on U160 chips. - - Correct a long standing but latent bug in - ahc_find_syncrate(). We could choose a DT only - rate even though DT transfers were disabled. - - When displaing controller characteristics, include the - speed of the chip. This way we can modify the transfer - speed based on optional features that are enabled/disabled - in a particular application. - - aic7xxx.h: - The real 7850 does not support Ultra modes, but there are - several cards that use the generic 7850 PCI ID even though - they are using an Ultra capable chip (7859/7860). We start - out with the AHC_ULTRA feature set and then check the - DEVSTATUS register to determine if the capability is really - present. - - current -> curr - - ahc_calc_residual() is no longer static allowing it to - be called from ahc_update_residual() in aic7xxx_inline.h. - - aic7xxx.reg: - Add a combined DATA_PHASE mask to the SCSIPHASE register - definition to simplify some sequencer code. - - aic7xxx.seq: - Take advantage of some performance features available only - on the U160 chips. The auto-ack feature allows us to ack - data-in phases up to the data-fifo size while the sequencer - is still setting up the DMA engine. This greatly reduces - read transfer latency and simplifies testing for transfer - complete (check SCSIEN only). We also disable the expected - phase feature, and enable the new bus free interrupt behavior, - to avoid a few instructions. - - Re-arrange the Ultra2+ data phase handling to allow us to - do more work in parallel with the data fifo flushing on a - read. - - On an SDTR, ack the message immediately so the target can - prepare the next phase or message byte in parallel with - our work to honor the message. - - aic7xxx_inline.h: - ahc_update_residual() now looks at the residual valid - flag in an endian safe way. This fixes a residual bug - on the PPC. - - aic7xxx_pci.c: - Correct a few product strings. - - Enable several U160 performance enhancing features. - - Modify Ultra capability determination so we will enable - Ultra speeds on devices with a 7850 PCI id that happen - to really be 7859 or 7860s. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#39 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#27 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#17 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#26 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#21 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#24 edit - -Change 189 by gibbs@overdrive on 2001/04/09 14:52:16 - - Bump version number to 6.1.11 for latest release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#55 edit - -Change 188 by gibbs@overdrive on 2001/04/06 16:38:18 - - aic7xxx.c: - In ahc_build_transfer_msg() filter the period and - ppr_options prior to deciding whether a PPR message - is required. ppr_options may be forced to zero - which will affect our decision. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#38 edit - -Change 187 by gibbs@overdrive on 2001/04/06 15:54:25 - - aic7xxx_osm.c: - Don't try negotiations that require PPR messages - if bus reset is enabled. We'll wait until we - successfully retrieve Inquiry data so we can make - an informed decision. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#63 edit - -Change 186 by gibbs@overdrive on 2001/04/05 16:29:33 - - aic7xxx_osm.h: - Bump version number to 6.1.10. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#54 edit - -Change 185 by gibbs@overdrive on 2001/04/05 16:29:00 - - aic7xxx_osm.c - Use scsi_(un)block_requests() to effect a freeze of the - entire controller queue. Scsi_unblock_requests() has been - modified to actually run any stalled queues in the 2.4.X - kernel sources. For 2.2.X, scsi_(un)block_requests() was - implemented. Since we now rely on this functionality, - only patch updates to the driver will be provided from - here on out. - - With this change, our bus settle delay can be of any - length and still avoid triggering command timeouts from - the midlayer. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#62 edit - -Change 182 by gibbs@overdrive on 2001/04/04 16:32:27 - - Bump version number to 6.1.9 for latest release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#53 edit - -Change 181 by gibbs@overdrive on 2001/04/04 16:31:50 - - aic7xxx_osm.c: - Correct a bug in ahc_done() that prevented us from running - the in-core device queue anytime the physical device was - idle. This caused problems anytime the driver received - more than one transaction for a device that does not - support tagged transactions. Unless another transaction - was queued to us to kick the queue, the transaction would - never get run. Zip drives are the most commonly found - device that was affected by this bug. - - CONFIG_AIC7XXX_RESET_DELAY -> CONFIG_AIC7XXX_RESET_DELAY_MS - Too many people have stale settings under the old config - option name for us to use it with a different meaning. - The setting is now in milli-seconds to allow more granular - control so stale values resulted in an extremely short bus - settle delay. - - Add a shutdown hook that resets all of the controllers - to a safe state. - - Update for changes in the way negotiation prameters are - communicated with the Core. - - Correct a function name in a printf. - - tmode_tstate -> ahc_tmode_tstate. - - aic7xxx_proc.c: - tmode_tstate -> ahc_tmode_tstate. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#61 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#10 edit - -Change 180 by gibbs@overdrive on 2001/04/04 16:22:29 - - aic7770.c: - Register our interrupt driver prior to enabling our - Bus drivers. This is just added paranoia. - - aic7xxx.c: - Namespace cleanup continues: - tmode_tstate -> ahc_tmode_tstate - tmode_lstate -> ahc_tmode_lstate - - Clean up the check condition path by branching early rather - than indenting a giant block of code. - - Add support for target mode initiated sync negotiation. - The code has been tested by forcing the feature on for - all devices, but for the moment is left inaccesible until - a decent mechanism for controlling the behavior is complete. - Implementing this feature required the removal of the - old "target message request" mechanism. The old method - required setting one of the 16 bit fields to initiate - negotiation with a particular target. This had the nice - feature of being easy to change the request and have it - effect the next command. We now set the MK_MESSAGE bit - on any new command when negotiation is required. When - the negotiation is successful, we walk through and clean - up the bit on any pending commands. We have to walk - the commands to reset the SCSI syncrate values already, - so no additional work is required. The only drawback of - this approach is that the negotiation is deferred until - the next command is queued to the controller. On the plus - side, we regain two bytes of sequencer scratch ram and 6 - sequencer instructions. - - When cleaning up a target mode instance, never remove the - "master" target mode state object. The master contains - all of the saved SEEPROM settings that control things like - transfer negotiations. This data will be cloned as the - defaults if a target mode instance is re-instantiated. - - Correct a bug in ahc_set_width(). We neglected to update - the pending scbs to reflect the new parameters. Since - wide negotiation is almost always followed by sync - negotiation it is doubtful that this had any real - effect. - - When in the target role, don't complain about - "Target Initiated" negotiation requests when an initiator - negotiates with us. - - Pull all info that used to be in ahc_timeout for the FreeBSD - OSM into ahc_dump_card_state(). This info should be printed - out on all platforms. - - aic7xxx.h: - Add the SCB_AUTO_NEGOITATE scb flag. This allows us to - discern the reason the MK_MESSAGE flag is set in the hscb - control byte. We only want to clear MK_MESSAGE in - ahc_update_pending_scbs() if the MK_MESSAGE was set due - to an auto transfer negotiation. - - Add the auto_negotiate bitfield for each tstate so that - behavior can be controlled for each of our enabled SCSI - IDs. - - Use a bus interrupt handler vector in our softc rather - than hard coding the PCI interrupt handler. This makes - it easier to build the different bus attachments to - the aic7xxx driver as modules. - - Update seeprom definitions for the latest formats. - - aic7xxx.reg: - Remove the TARGET_MSG_REQUEST definition for sequencer ram. - - aic7xxx.seq: - Fix a few target mode bugs: - - o If MK_MESSAGE is set in an SCB, transition to - message in phase and notify the kernel so that - message delivery can occur. This is currently - only used for target mode initiated transfer - negotiation. - - o Allow a continue target I/O to compile without - executing a status phase or disconnecting. If - we have not been granted the disconnect privledge - but this transfer is larger than MAXPHYS, it may - take several CTIOs to get the job done. - - Remove the tests of the TARGET_MSG_REQUEST field - in scratch ram. - - aic7xxx_inline.h: - Use ahc->bus_intr rather than ahc_pci_intr. - - aic7xxx_pci.c: - Move a comment to the correct location. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#11 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#37 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#26 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#16 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#25 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#20 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#23 edit - -Change 172 by gibbs@overdrive on 2001/03/22 17:47:51 - - Bump version to 6.1.8. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#52 edit - -Change 169 by gibbs@overdrive on 2001/03/22 15:56:41 - - aic7xxx_osm.c: - aic7xxx_osm.h: - Add support for switching to from full to basic - command queuing. Flags in the ahc_linux_device - structure indicate what kind of queuing to perform. - - In the past, we issued an ordered tag every 250 - transactions. We now issue an ordered tag every - 250 transactions issued without the device queue - going empty. - - aic7xxx_proc.c: - Use an unsigned long for total number of commands - sent to a device. %q and %lld don't seem to work - under Linux or I'd have used a quad. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#60 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#51 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#9 edit - -Change 167 by gibbs@overdrive on 2001/03/22 15:45:33 - - aic7770.c: - aic7xxx_pci.c: - Don't map our interrupt until after we are fully setup to - handle interrupts. Our interrupt line may be shared so - an interrupt could occur at any time. - - aic7xxx.h: - aic7xxx.c: - Add support for switching from fully blown tagged queing - to just using simple queue tags should the device reject - an ordered tag. - - Remove per-target "current" disconnect and tag queuing - enable flags. These should be per-device and are not - referenced internally be the driver, so we let the OSM - track this state if it needs to. - - Use SCSI-3 message terminology. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#10 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#36 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#25 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#22 edit - -Change 165 by gibbs@overdrive on 2001/03/19 17:58:07 - - aic7770.c: - ahc_reset() leaves the card in a paused state. - Re-arrange the code so we reset the chip earlier - so we can avoid a manual pause during setup. - - Setup the controller without enabling card interrupts. - - aic7xxx.c: - Fix a bug in ahc_lookup_phase_entry(). We never traversed - past the first entry. This routine is only used in - diagnostics so this had only a limited effect. - - Start out life with card interrupts disabled. The bus - code will enable the interrupts once setup is complete - and our handler is in place. - - Initialize our softc unit to -1 so that code such as - ahc_linux_next_unit() can traverse the list looking for - coliding unit numbers without tripping over entries that - have not yet had their unit number set. - - Enhance ahc_dump_card_state(). OSMs should be able to - rely on this to dump any controller specific data of - interest. Most of the additional registers printed - used to be printed in the FreeBSD timeout handler. - - Add a function pointer in our softc for a bus specific - interrupt handler. This removes some dependencies on - the PCI code so that bus attachments can be compiled - as modules separate from the core. - - aic7xxx.reg: - Use the naming for bit 5 of DFSTATUS in the data book, - FIFOQWDEMP. - - aic7xxx.seq: - In our idle loop, use an or instruction to set PRELOADEN - rather than rewriting the contents of DMAPARAMS to - DFCNTRL. The later may re-enable the DMA engine if - the idle loop is called to complete the preload of at - least one segment when a target disconnects on an S/G - segment boundary but before we have completed fetching - the next segment. This correts a hang, usually in - message out phase, when this situation occurs. This - bug has been here for a long time, so the situation - is rare, but not impossible to reproduce. - - Wait for at least 8 bytes in the FIFO before testing to - see if the DMA fetch of an SCB has stalled. The old - code used FIFOEMP, which goes false on a single byte. - Since we drain the FIFO 8 bytes at a time, using FIFOQWDEMP - is safer. - - If a device happens to be exceptionally slow in asserting - HDONE, our workaround for a stalled SCB dma can be triggered. - Make this situation non-fatal by terminating our FIFO - emptying should we complete the transfer. - - aic7xxx_inline.h: - ahc_pci_intr() -> ahc->bus_intr() - - aic7xxx_pci.c: - Setup ahc->bus_intr(). - - Enable board interrupts at the appropriate time. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#9 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#35 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#24 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#15 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#24 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#19 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#21 edit - -Change 164 by gibbs@overdrive on 2001/03/19 17:44:04 - - aic7xxx_osm.c: - Format to 80 columns. - - Break after finding a matching entry in the token - table during aic7xxx_setup. - - print the correct name of a function in a diagnostic. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#59 edit - -Change 163 by gibbs@overdrive on 2001/03/10 23:51:53 - - Bump version to 6.1.7. The too leanient interpretation - of the seeprom signature could result in improper - termination settings on some MBs, and this is a big - enough bug to warant a new release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#50 edit - -Change 162 by gibbs@overdrive on 2001/03/10 23:50:09 - - Handle cross builds. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#6 edit - -Change 161 by gibbs@overdrive on 2001/03/10 23:41:16 - - We now generate a header file for the db include - under linux to handle the build on more distribution - types. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#5 edit - -Change 160 by gibbs@overdrive on 2001/03/10 23:40:38 - - aic7xxx.h: - Add a definition for the 3.X BIOS signature. - - aic7xxx_inline.h: - We must setup queuestat before processing - command complete interrupts in case target - mode is enabled. - - aic7xxx_pci.c: - Be more selective in the BIOS signatures we - support. Some seeproms have a signature of - 0xFFFF, so testing greater than 0x250 resulted - in false positives. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.h#23 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#18 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#20 edit - -Change 159 by gibbs@overdrive on 2001/03/09 18:37:25 - - To be compatible with older kernels, our setup routine - must be called aic7xxx_setup(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#58 edit - -Change 158 by gibbs@overdrive on 2001/03/09 18:00:41 - - Play some games so we have a better chance of actually - building on more systems. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#5 edit - -Change 157 by gibbs@overdrive on 2001/03/09 17:04:49 - - aic7770_osm.c: - aic7xxx_osm.h: - Adjust aic7770_map_int() to not rely on a passed in "shared" - argument. We can now look at ahc->flags to see whether the - interrupt source is edge or level. - - aic7xxx_osm.c: - Only adjust our goal negotiation settings if the device - is actually present. This prevents a disconnected lun - that does not claim to support negotiations from messing - up the settings for a successfully probed lun whose inquiry - data properly reflects the abilities of the device. - - Set the device structure as releasable should the inquiry - come back with anything other than lun connected. We - should also do this if the device goes away as evidenced - by a selection timeout, but as we can't know if this - condition is persistant and there is no guarantee that - the mid-layer will reissue the inquiry command we use - to validate the device, I've simply added a comment - this effect. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#57 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#49 edit - -Change 156 by gibbs@overdrive on 2001/03/09 16:58:41 - - Adjust our interrupt handler so it will work in the edge - interrupt case. We must process all interrupt sources - when the interrupt fires or risk not ever getting an - interrupt from them. This involves marking the fact - that we are relying on an edge interrupt in ahc->flags - and checking for this condition in addition to the - AHC_ALL_INTERRUPTS flag. - - This will make it into the 6.1.6 Linux driver release. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#8 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#22 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#17 edit - -Change 155 by gibbs@overdrive on 2001/03/08 17:00:32 - - Bump version number for new release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#48 edit - -Change 154 by gibbs@overdrive on 2001/03/08 16:59:57 - - Convert to ahc_* and ahc_linux_* function names. - - aic7770_osm.c: - Drop the SA_INTERRUPT flag. According to Linus, - it should not be set. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#56 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#47 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#8 edit - -Change 153 by gibbs@overdrive on 2001/03/08 16:58:20 - - Cleanup exported symbol names. We now use ahc_* exclusively - to reduce the chance of conflicts with other modules. - - Staticize symbols that should have always been static. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#34 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#21 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#16 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#19 edit - -Change 152 by gibbs@overdrive on 2001/03/07 18:54:38 - - aic7xxx_osm.c: - Correct our softc comparison routine so that, regardless - of which function is seen first, the primary channel of - a multi-function chip is probed first. - - Note that the host structure only records a single scsi - ID. This means that multi-channel controllers, such as - the 2742T, cannot inform the SCSI layer of the IDs used - by channels other than the first. - - There is also no way to communicate the probe order of - channels on a multi-channel adapter. We could swap the - channels internally, but that would probably be more - confusing than just not supporting the option. - - Add a crude hack to make modunload/modload cycles work - now that we are using the new PCI methods. We must - detach our driver from each PCI device referenced by - a call to our release method. The PCI code doesn't have - a method to do this, so we muck with the pci_dev ourselves. - - Deregister our PCI driver when aic7xxx_release releases - the last host instance. - - Fix a bug in the inquiry sniffing code. It was possible - to set our period to a non-zero value even though the - offset was zero. This might have confused some async - devices. - - aic7xxx_osm.h: - ahc_power_state_change() is now an OSM routine. - - aic7xxx_osm_pci.c - Make our pci_driver non-static so that aic7xxx_osm.c - can reference it during module unload. - - Add an implementation to change the power state for - kernel versions that don't have a PCI method to do - this. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#55 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#46 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#16 edit - -Change 151 by gibbs@overdrive on 2001/03/07 18:45:53 - - aic7770.c: - Store a 2 bit channel number in ahc->flags. - - aic7xxx.c: - AHC_SUPPORT_PCI has never been defined. Use - AHC_PCI_CONFIG instead. - - Modify multi-function option merging to work - regardless of the order the functions are presented - to the driver. - - Adjust for the primary channel being a 2 bit integer - rather than a flag for 'B' channel being the primary. - - aic7xxx.h: - Adjust for the primary channel being represented as - a 2 bit integer in the flags member of the ahc softc. - - Cleanup the flags definitions so that comment blocks are - not cramped. - - Update seeprom definitions to correctly reflect the fact - that the primary channel is represented as a 2 bit - integer. - - aic7xxx.reg: - Add DFCACHETH to the definition of DFSTATUS for - completness sake. - - aic7xxx.seq: - On some chips, at least the aic7856, the transition from - MREQPEND to HDONE can take a full 4 clock cycles. Test - HDONE one more time to avoid this race. We only want our - FIFO hung recovery code to execute when the engine is - really hung. - - aic7xxx_pci.c: - Move the powerstate manipulation code into the OSM. Several - OSes now provide this functionality natively. - - Take another shot at using the data stored in scratch ram - if the SCB2 signature is correct and no SEEPROM data is - available. In the past this failed if external SCB ram - was configured because the memory port was locked. We - now release the memory port prior to testing the values - in SCB2 and re-acquire it prior to doing termination control. - - Adjust for new 2 bit primary channel setting. - - Trust the STPWLEVEL setting on any BIOS v 2.5X and above. - 3.X bioses have started to ship. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#7 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#33 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#20 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#14 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#23 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#18 edit - -Change 150 by gibbs@overdrive on 2001/02/28 17:44:09 - - aic7xxx_osm.c: - Fix the setup for the selection timeout setting. - - During exception processing dump the card state if - we are in verbose mode. - - Keep "driver_template" static so as not to conflict - with other files in the system. Instead, export a - pointer to the driver template with a more unique - symbol name. - - aic7xxx.h: - Export our pointer to the driver template. - - Bump driver version number to 6.1.5. - - aic7xxx_osm_pci.c: - Use the newly exported pointer to the driver template. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#54 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#45 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#15 edit - -Change 149 by gibbs@overdrive on 2001/02/28 17:36:26 - - aic7xxx.c: - Take advantage of a new flag managed by the sequencer - that indicates if an SCB fetch is in progress. If so, - the currently selected SCB needs to be returned to the - free list to prevent an SCB leak. This leak is a rarity - and would only occur if a bus reset or timeout resulting - in a bus reset occurred in the middle of an SCB fetch. - - Don't attempt to perform ULTRA transfers on ultra capable - adapters missing the external precision resistor required - for ultra speeds. I've never encountered an adapter - configured this way, but better safe than sorry. - - aic7xxx.h: - Add AHC_ULTRA_DIASABLED softc flag to denote controllers - missing the external precision resistor. - - aic7xxx.reg: - Add SEQ_FLAGS2 which currently only contains the SCB_DMA - (SCB DMA in progress) flag. - - aic7xxx.seq: - Manage the SCB_DMA flag of SEQ_FLAGS2. - - More carefully shutdown the S/G dma engine in - all cases by using a subroutine. Supposedly not - doing this can cause an arbiter hang on some ULTRA2 - chips. - - Formatting cleanup. - - aic7xxx_pci.c: - Configure any 785X ID in the same fashion and assume - that any device with a rev id of 1 or higher has the - PCI 2.1 retry bug. It seems that at least some revisions - of the 7856 have this bug. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#32 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#19 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#13 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#22 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#17 edit - -Change 148 by gibbs@overdrive on 2001/02/27 17:39:56 - - Correct a problem when one lun has a disconnected untagged - transaction and another lun has disconnected tagged transactions. - Just because an entry is found in the untagged table doesn't - mean that it will match. If the match on the lun fails, cleanup - the SCB (return it to the disconnected list or free it), and snoop - for a tag message. Before this change, we reported an unsolicited - reselection. This bug was introduced about a month ago during an - overly aggressive optimization pass on the reselection code. - - When cleaning up an SCB, we can't just blindly free the SCB. In - the paging case, if the SCB came off of the disconnected list, its - state may never have been updated in host memory. So, check the - disconnected bit in SCB_CONTROL and return the SCB to the disconnected - list if appropriate. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#21 edit - -Change 147 by gibbs@overdrive on 2001/02/26 17:05:34 - - Handle the case of 5MHz user sync rate set as "0" instead of 0x1c - in scratch ram. - - If we lookup a period of 0 in our table (async), clear the scsi offset. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#31 edit - -Change 146 by gibbs@overdrive on 2001/02/21 20:48:22 - - Put our exception handling semaphore into the softc rather - than as a global. I don't know what I was thinking when - I wrote this code, but having two different controllers sleeping - on the same mutex for error recovery is a recipe for disaster. - - Implement a controller global queue freeze function. We use this - feature to handle the initial reset bus settle delay. The queue - is unfrozen by a timer so all bus settle delays occur in parallel - and without stopping other kernel tasks from running. My only - remaining concern is that the specification of too long of a - reset delay might trigger a mid-layer timeout. The default - under linux is 5 seconds which is substantially less than the - timeouts used during probe. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#53 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#44 edit - -Change 145 by gibbs@overdrive on 2001/02/21 13:26:52 - - Bump version for 6.1.3 release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#43 edit - -Change 144 by gibbs@overdrive on 2001/02/21 13:26:21 - - Properly use the target offset rather than the target id - for choosing the correct untagged Q to manipulate. This - should correct problems with the 2742T. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#52 edit - -Change 143 by gibbs@overdrive on 2001/02/21 13:25:10 - - Identify adapters in ARO mode as such. - - Ensure that not only the subvendor ID is correct (9005) - but also that the controller type field is valid before - looking at other information in the subdevice id. Intel - seems to have decided that their subdevice id of 8086 - is more appropriate than Adaptec's sanctioned scheme. - - Add an exclusion entry for SISL (AAC on MB based adapters). - Adapters in SISL mode are owned by the RAID controller, so - even if a driver for the RAID controller is not present, - it isn't safe for us to touch them. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#16 edit - -Change 142 by gibbs@overdrive on 2001/02/21 13:21:47 - - Use the target offset rather than the target Id to reference - the untagged SCB array. The offset and id are identical save - in the twin channel case. This should correct several issues - with the 2742T. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#30 edit - -Change 141 by gibbs@overdrive on 2001/02/21 13:21:00 - - Correct an issue with the aic7770 in twin channel mode. - We could continually attempt to start a selection even - though a selection was already occurring on one channel. - This might have the side effect of hanging our selection - or causing us to select the wrong device. - - While here, create a separate polling loop for when we - have already started a selection. This should reduce - the latency of our response to a (re)selection. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#20 edit - -Change 140 by gibbs@overdrive on 2001/02/17 14:44:19 - - Bump version number to 6.1.2. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#42 edit - -Change 139 by gibbs@overdrive on 2001/02/16 16:15:57 - - Don't require iospace or mem space to be enabled in order to - attach to a PCI device. We only require that one of the mapping - registers is properly setup. - - This fix allows us to run on a G3 PowerMac. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#14 edit - -Change 138 by gibbs@overdrive on 2001/02/15 10:43:52 - - Use dma_addr_t as the Linux equivalent to bus_addr_t. uint32_t - works for only some platforms. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#41 edit - -Change 137 by gibbs@overdrive on 2001/02/15 10:42:44 - - Set the goal and user settings for sync and wide negotiation - prior to setting the current. This makes it easier for some - code in the Linux OSM to know when is an oportune time to - display a user message about transfer negotiation status. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#29 edit - -Change 136 by gibbs@overdrive on 2001/02/09 20:09:59 - - On second thought, don't test for ATN just before a - command complete message is processed. We probably - want to test for SCSIPERR, but this needs more thought. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#19 edit - -Change 135 by gibbs@overdrive on 2001/02/09 20:06:02 - - aic7xxx.c: - Style nits. - - Make sure that our selection hardware is disabled - as soon as possible after detecting a busfree and - even go so far as to disable the selection hardware - in advance of an event that will cause a busfree - (ABORT or BUS DEVICE RESET message). The concern - is that the selection hardware will select a target - for which, after processing the bus free, there - will be no commands pending. The sequencer idle - loop will re-enable the selection should still be - necessary. - - In ahc_handle_scsiint(), clear SSTAT0 events several - PCI transactions (most notably reads) prior to clearing - SCSIINT. The newer chips seem to take a bit of time - see the change which can make the clearing of SCSIINT - ineffective. - - Don't bother panicing at the end of ahc_handle_scsiint(). - Getting to the final else just means we lost the race - with clearing SCSIINT. - - In ahc_free(), handle case 0. This can happen when we fail - the attach for RAID devices. While I'm here, also kill - the parent dma tag. - - In ahc_match_scb(), consider initiator ccbs to be any - that are not from the target mode group. This fixes - a bug where an external reset CCB was not getting cleaned - up by the reset code. - - Don't bother freezing a ccb in any of our "abort" routines - when the status is set to CAM_REQ_CMP. - - aic7xxx.reg: - Reserve space for a completion queue. This will be used - to enhance performance in the near future. - - Remove an optimization for the 7890 autoflush bug that - turned out to allow, in rare cases, some data to get - lost. - - Even though we need a critical section to fully close - the command complete loophole, test for ATN anyway in - the command complete handler. Its better than nothing. - - Implement a simpler, faster, fix for the PCI_2_1 retry - bug that hangs the sequencer on an SCB dma. - - aic7xxx_pci.c - Use the correct mask for checking the generic aic7892 - entry. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#28 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#12 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#18 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#15 edit - -Change 134 by gibbs@overdrive on 2001/02/09 19:29:14 - - aic7xxx_osm.c: - Pull the host_no out of the host structure rather - than storing a copy of the field in our own platform - softc. - - Use the host_no rather than our unit nuber for any - "scsi%d" type printfs. In this case, the result is - a corrected printf for tagged queue depth. - - Anytime we run the complete queue, we must clear it. - We missed the clearing part when running the device - queue after queuing a new command. - - Use the same format for reporting transfer rates as the - /proc code. Only print transfer info if no further - negotiations are pending and the value is different from - the last one reported. - - Correctly format a printf used during error recovery. - - Don't forget to set the result before returning from - one case in ahc_queue_recovery_scb. - - Fix inverted test for the non-paging case. The result of - this bug was that we would set the MK_MESSAGE bit in an - SCB unrelated to the SCB we were trying to abort. - - Add a missing add_timer() call. It's hard to timeout - on a recovery action when no timer is running. This - also explains why I had to invert the test of the status - returned by del_timer() in the past. We always thought - the timer had expired because it was no longer active. - - Don't forget to run the device queue after error recovery - is complete. We don't want to leave any stray commands - stuck in our queues. - - aic7xxx_osm.h - Bump version for next release. - - Add a "last_tinfo" field to the ahc_linux_target to track - what negotiation settings have been announced. - - Kill unneeded host_no field in the platform softc. - - Bring the info_str structure into this header file so - we can export ahc_format_transinfo() outside of the - /proc code. - - aic7xxx_proc.c: - Export ahc_format_transinfo(). - - Use the host_no in the host structure rather than - removed field in the platform softc. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#51 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#40 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#7 edit - -Change 133 by gibbs@overdrive on 2001/01/28 15:49:09 - - aic7770_osm.c: - Convert to "aic7xxx_osm.h". - - On newer kernels, check the return of request_region. - - aic7xxx_osm.c: - Cleanup comment blocks for consistent style. - - Convert to "aic7xxx_osm.h". - - Add support for attachment of devices found after - the initial probe during "aic7xxx_detect". We do - this by setting a global, aic7xxx_detect_complete, - which tells the pci probe code to do its own registration - call if initial detection has already occurred. This way, - we maintain the "sane ordering" of devices that the - old driver had for statically configured devices. - - Split out the host registration code into its own function - so that hot-plug devices can call this code after - aic7xxx_detect has already completed. - - Use request/release_mem_region on 2.4.0 or higher kernels. - - Restore SCBPTR after setting up an abort for a - disconnected SCB. The sequencer will become confused - if this is not done. - - Always look for the SCB that timedout first and result to - a more generic search only if that fails. The timedout SCB - is more likely to be the one on the bus. - - Don't bother to drop and reaquire our mutex at the tail - of the recovery handler unless we are going to sleep. - - aic7xxx_osm.h: - Comment cleanup. - - Export our SCSI host template so the hot-plug PCI stuff - can use it. - - Bump revision to 6.1.0... our first release. - - aic7xxx_osm_pci.c: - Add support for new PCI probe mechanism in 2.4.0 while - maintaining compatibility with older kernels. - - aic7xxx_proc.c: - Fix several bugs in Gerard's proc code. We would never - properly deal with reads at offsets other than 0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#50 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#39 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#6 edit - -Change 132 by gibbs@overdrive on 2001/01/28 15:32:59 - - aic7770.c: - aic7xxx.c: - aic7xxx_93cx6.c: - Convert to "aic7xxx_osm.h" setup rather than ifdef hell. - - aic7xxx_pci.c: - Document the layout of the DEVID for cards with the 9005 - Adaptec vendor ID. Use a more generic mask for the generic - 9005 product tests. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#6 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#27 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#7 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#14 edit - -Change 131 by gibbs@overdrive on 2001/01/23 15:29:46 - - When flipping the first entry in the qinfifo with the - "next queued SCB", we must also inform the card of this - change. Otherwise the sequencer will traverse a corrupt - list of SCBS. The side effects of this problem were unknown - SCBs completing in the qoutfifo or worse yet, panics due - to sequencer interrupts that referenced what, to the kernel, - were invalid SCB ids. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#26 edit - -Change 130 by gibbs@overdrive on 2001/01/22 17:44:12 - - Update copyrights. - - aic7xxx.seq: - Handle busfree early in selection correctly. We - must clear ENSELO so that we will make future attempts - at selection. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#5 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#25 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#18 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#11 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#17 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#6 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#15 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#13 edit - -Change 129 by gibbs@overdrive on 2001/01/22 17:03:07 - - Bump revision level. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#38 edit - -Change 128 by gibbs@overdrive on 2001/01/19 16:09:10 - - Bump version number. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#37 edit - -Change 127 by gibbs@overdrive on 2001/01/19 15:57:40 - - It's Adaptec Inc., not just Adaptec. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#2 edit - -Change 126 by gibbs@overdrive on 2001/01/19 15:57:16 - - Correct a typo. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#4 edit - -Change 125 by gibbs@overdrive on 2001/01/19 10:35:11 - - aic7xxx.c: - Remove aic7895 stack corruption work-around. - This seems to only apply if you are mucking - with the stack register to effect a "long-jump". - We don't do this and don't plan to either. - - Add additional diagnostic output for when things - go wrong. - - AHC_SCB_BTT is set in the flags area of the softc, - not features. - - Don't loop forever if the INTSTAT register gets - locked up when flushing work. This can happen if - we are a removable device (register goes away) or - the card dies. - - aic7xxx.h: - Add a removable feature designation to ahc_features. - This is currently only used for the apa1480 and the 29160C. - - aic7xxx.reg: - Don't use the sequencer intcode 0xF0. It makes it possible - for the kernel to see INTSTAT as 0xFF and believe a hot-eject - has occurred. - - Align the busy target table on a 16byte boundary. This - appears to correct a sequencer execution issue for the - 7895. - - aic7xxx.seq: - Don't bother performing a "diagnostic" sequencer interupt - should an abort collision occur. - - Have the bus-free after selection code apply to - reselections too. - - Always follow the clearing of SELDI with a jmp instruction. - This corrects a sequencer execution issue on the 7895. - - In the target mode command loop, don't bother re-enabling - SPIOEN for each byte. It only needs to be enabled once. - - Fix AHC_SCB_BTT tests to test the correct field in the softc. - - Correctly clean up resources should an incoming reselection - reference a transaction we don't believe is pending. Add - some additional sequencer diagnostics for the SCB_BTT case - too. - - aic7xxx_inline.h: - Fix AHC_SCB_BTT tests to test the correct field in the softc. - - Only believe a hot eject to have occurred if the device - is removable. - - aic7xxx_pci.c: - Set the removable feature for the apa1480 and 29160C. - - Don't print information about high byte termination on - narrow adapters. - - Use a pci bus read instead of a questionable read for - safety when manipulating external termination logic. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#24 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#17 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#10 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#16 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#14 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#12 edit - -Change 124 by gibbs@overdrive on 2001/01/15 05:12:30 - - aic7770_osm.c: - Whitespace cleanup. - - Don't reference a NULL pointer. - - aic7xxx_osm.c: - Honor kernel configuration settings for bus - settle delay and max tagged commands. - - Correct accuracy of tagged command setup comments. - - Limit linux to 253 total commands due to command - complete FIFO cleanup restrictions. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#49 edit - -Change 123 by gibbs@overdrive on 2001/01/12 09:08:27 - - aic7770.c: - Add softcs for new EISA instances into the global list - of aic7xxx controllers as they are found. Leaving the - softcs out of the list prevented these controller instances - from being attached. - - aic7xxx.c: - Remove code that corrected for a state that cannot occur. - The sequencer now increments its position in the qinfifo - only once it has successfully DMAed the SCB from that queue - position down to the controller. In the past the sequencer - incremented before attempting the DMA. - - To ensure that the sequencer always notices an abort - collision, swap the first entry in the qinfifo with - the held, next to dma, hscb only after we have completed - our pass through the array. In the past, we did this - before clearing out the queue, and this did not provide - the same guarantee since the queue could be cleared leaving - the next pointer to be the same as it was originally. - - Print out the next queued SCB as seen by both the kernel - and the sequencer in ahc_dump_card_state(). - - aic7xxx.h: - Introduce a new constant, AHC_MAX_QUEUE. This is now set - to 253 to make sure that our 32bit writes to clear the - qoutfifo can never clobber a valid entry in the queue. - All OSMs should use this new define to throttle their - controller wide queue depth. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#4 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#23 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#16 edit - -Change 122 by gibbs@overdrive on 2001/01/08 11:32:55 - - Kill old insqueue interface. It will not be used by the - aic7xxx driver. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#4 edit - -Change 121 by gibbs@overdrive on 2001/01/08 11:30:36 - - Reduce the university's copyright per Kirk. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#3 edit - -Change 120 by gibbs@overdrive on 2001/01/08 11:27:30 - - Bump version number for next release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#36 edit - -Change 119 by gibbs@overdrive on 2001/01/08 11:20:17 - - Turn on ID expansion. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#3 edit - -Change 118 by gibbs@overdrive on 2001/01/08 08:10:19 - - aic7xxx_osm.c: - Honor selection timeout settings set by the user. - - Style cleanup of initial setup routine. - - Use sense buffer access inlines. - - Check for critical underflow only if there are no - other errors reported at the time the command is ahc_done()'d. - In the past, we might have marked the command as critically - failed before retrieving sense. Sense data should take - priority. - - aic7xxx_osm.h: - Second part of underflow cleanup. Just store the residual - in ahc_set_residual(). Leave policy decision to ahc_done(). - - aic7xxx_proc.c: - Add per-device statistics to proc output. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#48 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#35 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#5 edit - -Change 117 by gibbs@overdrive on 2001/01/08 08:03:54 - - aic7xxx.c: - Use inline accessors to get to the sense buffer associated - with a particular auto-sense transaction. This buffer is - now indexed by scb offset, not hscb offset, so any qinfifo - manipulations will not effect the buffer referenced. - - Honor the selection timeout setting in ahc_softc. The - OSM is responsible for setting this to any non-default - value. - - Modify our suspend and resume routines to take into account - twin channel adapters. - - aic7xxx.h: - Add fields for twin channel suspend state storage and - selection timeout timer to ahc_softc. - - aic7xxx_inline.h: - Inline accessors for sense buffer bus address and buffer. - - aic7xxx_pci.c: - Correct subdevice id data extraction routines to work - correctly on motherboard devices. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#22 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#15 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#13 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#11 edit - -Change 116 by gibbs@overdrive on 2000/12/21 09:22:20 - - Makefile: - Generate module in SCSI directory so it can be - named just like its predecessor. - - aic7xxx_osm.c: - Fix semaphore declarations for newer kernels. - - Use new ahc_* byte order functions. - - Cleanup some unused code. - - Implement platform_flush_work. - - aic7xxx_osm.hosts.h: - Split out our host template definition so we don't - muck up the namespace when our template is included - in hosts.c - - aic7xxx_inline.h: - Define ahc_endian functions. - - Bump version number. - - aic7xxx_proc.c: - First stab at /proc support. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#47 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#34 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#4 edit - -Change 115 by gibbs@overdrive on 2000/12/21 08:59:37 - - Add untested support for big endian machines. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#21 edit - -Change 114 by gibbs@overdrive on 2000/12/13 08:00:07 - - Bring in the optimized interrupts handler. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#12 edit - -Change 113 by gibbs@overdrive on 2000/12/13 07:57:15 - - aic7xxx_osm.c: - Use a semaphore and a timer to cause our exception - handler to sleep while recovery actions are in progress. - - Mark the correct recovery type in the SCB instead of - always marking DEVICE_RESET. - - aic7xxx_osm.h: - We are now at 6.0.6 BETA. - - Use a simple "do/while" construct to serve as a - memory barier on ia32. lock instructions are - expensive and all we need is something to prevent - the compiler from reordering our store order. - - aic7xxx_pci.c: - Turn off either I/O or Mem access depending on which - mapping type is not in use. This prevents our EISA - probe from kicking one of our cards. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#46 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#33 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#12 edit - -Change 112 by gibbs@overdrive on 2000/12/13 07:39:03 - - Complete preliminary resume support. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#20 edit - -Change 111 by gibbs@overdrive on 2000/12/12 12:09:54 - - aic7xxx.c: - During initialization, be sure to initialize all scratch - ram locations before they are read to avoid parity errors. - In this case, we use a new function, ahc_unbusy_tcl() to - initialize the scratch ram busy target table. - - Replace instances of ahc_index_busy_tcl() used to unbusy - a tcl without looking at the old value with ahc_unbusy_tcl(). - - Modify ahc_sent_msg so that it can find single byte messages. - ahc_sent_msg is now used to determine if a transfer negotiation - attempt resulted in a bus free. - - Be more careful in filtering out only the SCSI interrupts - of interest in ahc_handle_scsiint. - - Rearrange interrupt clearing code to ensure that at least - one PCI transaction occurrs after hitting CLRSINT1 and - writting to CLRINT. CLRSINT1 writes take a bit to - take effect, and the re-arrangement provides sufficient - delay to ensure the write to CLRINT is effective. - - export ahc-update_target_msg_request for use by OSM code. - - If a target does not respond to our ATN request, clear - it once we move to a non-message phase. This avoids - sending a MSG_NOOP in some later message out phase. - - Use max lun and max target constants instead of - hard-coded values. - - Use softc storage built into our device_t under FreeBSD. - - Fix a bug in ahc_free() that caused us to delete - resources that were not allocated. - - Clean up any tstate/lstate info in ahc_free(). - - Clear the powerdown state in ahc_reset() so that - registers can be accessed. - - Add a preliminary function for pausing the chip and - processing any posted work. - - Add a preliminary suspend and resume functions. - - aic7xxx.h: - Limit the number of supported luns to 64. We don't - support information unit transfers, so this is the - maximum that makes sense for these chips. - - Add a new flag AHC_ALL_INTERRUPTS that forces the - processing of all interrupt state in a single invokation - of ahc_intr(). When the flag is not set, we use the - lazy interrupt handling scheme. - - Add data structures to store controller state while - we are suspended. - - Use constants instead of hard coded values where appropriate. - - Correct some harmless "unsigned/signed" conflicts. - - aic7xxx.seq: - Only perform the SCSIBUSL fix on ULTRA2 or newer controllers. - Older controllers seem to be confused by this. - - In target mode, ignore PHASEMIS during data phases. - This bit seems to be flakey on U160 controllers acting - in target mode. - - aic7xxx_pci.c: - Add support for the 29160C CPCI adapter. - - Add definitions for subvendor ID information - available for devices with the "9005" vendor id. - We currently use this information to determine - if a multi-function device doesn't have the second - channel hooked up on a board. - - Add rudimentary power mode code so we can put the - controller into the D0 state. - - Only capture "left over BIOS state" if the POWRDN - setting is not set in HCNTRL. - - In target mode, don't bother sending incremental - CRC data. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#19 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#14 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#15 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#10 edit - -Change 110 by gibbs@overdrive on 2000/12/01 09:43:59 - - When bus resets are disabled, call update_target_msgreq after - setting initial transfer settings so that negotiation takes place - on the first command to the target. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#45 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#32 edit - -Change 109 by gibbs@overdrive on 2000/11/10 09:37:15 - - Add IOMODE support. - - Remove recurring interrupts during scsi bus resets by - disabling scsi bus reset notifications until we start - sending or receiving transactions again. - - Issue a missed busfree sequencer interrupt instead of - overloading bad phase. The code was getting confused - before because last phase was not set in all cases - to distinguish the two cases. - - Don't assume the SCB tag is valid unless SEEN_IDENTIFY - is set in SEQ_FLAGS during timeout handling. - - Add critical sections to protect the sequencer from list - corruption during timeout handling. - - Sync with FreeBSD IDs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#18 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#13 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#9 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#14 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#5 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#5 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#11 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#9 edit - -Change 108 by gibbs@overdrive on 2000/11/10 09:33:33 - - Bump version for next release. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#31 edit - -Change 107 by gibbs@overdrive on 2000/11/06 09:36:35 - - The core driver takes care to clean up any doubly queued SCBs - now, so don't call ahc_search_qinfifo from ahc_done(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#44 edit - -Change 106 by gibbs@overdrive on 2000/11/06 09:35:50 - - Fix 8bit math errors when tweaking the qinfifo. - - Don't allow ahc_search_qinfifo to be called recursively. - - Use a subroutine to make sure we don't coast into any - important sequencer instructions when issuing a pausing - interrupt. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#17 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#8 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#13 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#10 edit - -Change 105 by gibbs@overdrive on 2000/11/01 12:01:08 - - Linux EISA support, support for 2.4.X kernels, and updates to - match changes in the core aic7xxx code. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#43 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#30 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#11 edit - -Change 104 by gibbs@overdrive on 2000/11/01 11:59:42 - - Too many changes to mention. Lots of bug fixes. Filtering of - incoming transfer negotiation messages based on user settings, - bmov instruction for all moves, additional debugging code, etc. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.c#16 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#12 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#7 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#12 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#9 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#8 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#6 edit - -Change 103 by gibbs@overdrive on 2000/10/13 10:01:42 - - aic7xxx.c: - Limit our sync period correctly based on tinfo data. - We now send a period of 0 if we want async. - - Fix problem with DMA'ed CDBs. The pointer to the - physical cdb was not being setup properly during - the HSCB swap. We now compute this value in - ahc_setup_scb(). - - aic7xxx.seq: - Make sure that DFON stays on in SXFRCTL0. - - Fix DMA'ed cdbs for adapters without a command channel. - The length in HCNT was not properly set. - - Clear STCNT on U2 controllers when we exit command - phase. This is an attempt to clear the preload circuit. - It is not yet clear that this works. - - aic7xxx_inline.h: - Copy the whole 64 bytes of the hscb when queuing it. - If we need to recalculate the cdb physical pointer for - a large cdb, do so at this time as well. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#15 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#11 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#11 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#8 edit - -Change 102 by gibbs@overdrive on 2000/10/12 11:12:41 - - Make the no_reset option work and also honor the seeprom/nvram - reset options at boot time. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#42 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#29 edit - -Change 101 by gibbs@overdrive on 2000/10/12 10:00:34 - - Update for changes in aic7xxx core files: UNTAGGED_Q flag, - ahc_validate*() now take a tinfo. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#41 edit - -Change 100 by gibbs@overdrive on 2000/10/12 09:59:11 - - Limit transfer settings to that of our goal at all times. This - ensures that a target initiated sync/wide negotiation never goes - above the limits specified by the user. - - When switching to non-tagged queuing, be sure to set the - SCB_UNTAGGEDQ flag when inserting the SCB onto the untagged q. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#14 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#10 edit - -Change 99 by gibbs@overdrive on 2000/10/09 11:21:46 - - Remove AIC7XXX_STRICT_PCI_SETUP. We don't currently honor it - and don't have a reason to honor it in the future. - - Handle temporary resource shortages such as an attempt to allocate - additional SCBs failing. - - Complete the first pass at Linux error recovery code. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#40 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#28 edit - -Change 98 by gibbs@overdrive on 2000/10/09 11:17:46 - - Export ahc_match_scb() to OSMs. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#13 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#9 edit - -Change 97 by gibbs@overdrive on 2000/10/09 07:49:38 - - aic7xxx.c: - export ahc_qinfifo_requeue and a new routine - ahc_qinfifo_count for use by OSM error recovery - routines. - - Resync the tqinfifo position during every restart of - the sequencer. In the past, we would do this only - for bus resets but there are other situations where - restarting the sequencer might cause a discrepency. - - Print the scb's path information before running an - abort command that will include that scb. There is - no guarantee that the path information will be valid - after an SCB is freed. - - In ahc_clear_critical_sections(), disable all SCSIINT - interrupt sources and clear SCSIINT. SCSIINT is a pausing - interrupt and the sequencer will not step if it is paused - by an interrupt condition. Any SCSIINT sourc that is - active prior to or becomes active during the stepping - process will cause SCSIINT to be re-asserted when we - re-enable these interrupt sources at the tail of - ahc_clear_critical_sections(). - - Send the correct async notifications for BDR and bus reset. - - Fix an error in ahc_search_qinfifo() that would update - QINFIFO at the wrong time. - - In ahc_loadseq, properly calculate the critical section - regions for the current firmware load. The old code was - confused if a critical sections boundary occurred on - an instruction not downloaded to the chip. - - aic7xxx.h: - Remove an unused SCB_FLAG. - - Export ahc_qinfifo_requeue() and ahc_qinfifo_count(). - - aic7xxx.seq: - The MK_MESSAGE flag is cleared by the kernel. Don't - bother duplicating that effort in the sequencer. - - aic7xxx_pci.c: - 7880's prior to rev B have the MWI boundary bug. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#12 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#8 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#10 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#7 edit - -Change 96 by gibbs@overdrive on 2000/10/06 06:40:57 - - Convert to keeping a queue of Scsi_Cmnd structures instead of SCBs. - This will allow us to queue domain validation and other requests - internally to the driver without fear of an SCB shortage related - deadlock. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#39 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#27 edit - -Change 95 by gibbs@overdrive on 2000/10/06 06:39:42 - - Simplify ahc_update_pending_syncrates(). - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#11 edit - -Change 94 by gibbs@overdrive on 2000/10/06 06:19:23 - - Update FreeBSD ids. - - Move verbose logging of negotiation into the *construct* methods - so that logging occurs in all cases. - - Correct ahc_search_qinfifo to properly deal with an SCB out of - the qinfifo but mid-dma in the SEARCH_REMOVE case. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#10 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#7 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#6 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#9 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#4 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#4 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#7 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#6 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#6 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#4 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#5 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#4 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#4 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#4 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#4 edit - -Change 93 by gibbs@overdrive on 2000/10/03 11:11:11 - - Fix non-module build on 2.2.14. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#38 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#26 edit - -Change 92 by gibbs@overdrive on 2000/10/03 11:10:45 - - aic7xxx.c: - panic with a reasonable message if we do not have a valid - SCB when handling a HOST_MSG_LOOP event. - - Clear any critical sections when a bus reset or any unexpected - SCSI event occurs. - - Fix an off by one in testing whether we are inside a - critical section. - - Set the step bit in the correct register. - - Also check whether the PPR options have changed when - deciding to update our syncrate. - - Add some bootverbose logging about transfer negotiations. - - If we are going to reject a PPR, explicitly set all options - to async/narrow. It may be that only one of the many options - was filtered to an unacceptable value. - - Have the ahc_search_qinfifo routing properly handle the - case where an SCB has left the qinfifo but has not yet - been added to the waiting list. - - aic7xxx.seq: - Correct critical sections for input queue handling. - - Fix a bug in input queue handling that caused us to - smash the next scb to download value as we were putting - the new SCB onto the waiting list. - - If the qinfifo changes to not include the just DMAed - SCB, throw it away... it has been aborted by the kernel. - - aic7xxx_inline.h: - Simplify a statement. No fucntional change. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#9 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#8 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#6 edit - -Change 91 by gibbs@overdrive on 2000/09/28 10:59:15 - - Limit prefetch to a PCI cacheline amount instead of pulling - a full (and expensive) 128 bytes. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#8 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#5 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#7 edit - -Change 90 by gibbs@overdrive on 2000/09/28 10:31:17 - - Make sure we tell the OS that we can only take 254 or - AHC_SCB_MAX - 1 requests at a time due to the new QINFIFO - scheme. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#37 edit - -Change 89 by gibbs@overdrive on 2000/09/28 10:30:48 - - Correct ahc_search_qinfifo by reading and resetting the - SNSCB_QOFF register. A read of this register increments it, - requiring the reset. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#7 edit - -Change 88 by gibbs@overdrive on 2000/09/28 09:24:14 - - Use an array of scb pointers to map from HSCB tag to - SCB. - - Take a first shot at correcting ahc_search_qinfifo for the - new qinfifo mechanism. We don't currently handle the case - of an SCB in transit to the card after it has been removed - from the QINFIFO. - - There still appears to be a problem with the QINFIFO handling - that I have yet to address. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#6 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#6 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#6 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#5 edit - -Change 87 by gibbs@overdrive on 2000/09/27 09:03:56 - - Put the Linux aic7770 support into its final location. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_eisa.c#3 delete - -Change 86 by gibbs@overdrive on 2000/09/27 09:03:16 - - Implement new, single DMA, strategy for getting commands to - the controller. - - Still need to implement qinfifo cleanup routine. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#5 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#5 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#4 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#5 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#4 edit - -Change 85 by gibbs@overdrive on 2000/09/27 09:02:01 - - Clean up code formating so extraineous commas are not - generated. - - Output a constant indicating the size of the critical - section table. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#5 edit - -Change 84 by gibbs@overdrive on 2000/09/27 08:58:38 - - Switch to only allowing 254 commands outstanding in preparation - for new input queue handling. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#36 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#25 edit - -Change 83 by gibbs@overdrive on 2000/09/25 08:40:23 - - aic7xxx_osm.c: - Correct a KERNEL_VERSION test. - - Reset the bus only after we've finished setting - up the controller fully. - - Update for new ahc_send_async() API. - - Only attempt to report bus resets if the kernel - we're building for supports it. - - aic7xxx_osm.h: - Bump driver version in preparation for next release. - - Fix compilation on older kernels. The Scsi_Cmnd is now - available through the scb->io_ctx. - - Update for new ahc_send_async() API. - - aic7xxx_osm_pci.c: - Correctly handle the I/O mapped case. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#35 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#10 edit - -Change 82 by gibbs@overdrive on 2000/09/25 08:35:25 - - Rely on CACHETHEN bug entries to limit its use. Otherwise, - default to turning it on. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#5 edit - -Change 81 by gibbs@overdrive on 2000/09/22 07:55:30 - - aic7xxx.c: - Clear scsi interrupts via the CLRINT register if we - see a spurios SCSI interrupt. - - Modify the ahc_send_async interface so that the client - can directly specify which devices (through the use of - wildcards) are affected. - - When sending a PPR message we need to filter the syncrate - we attempt to negotiate with the target just as when using - the older SDTR message. Combine these two cases so we can - share the code that does this. - - Correct a panic message. - - Handle a MSG_MESSAGE_REJ for a PPR request. Simplify the - ahc_handle_msg_reject routine by calling - ahc_build_transfer_msg in cases where further negotiation - is required rather than doing this manually. - - In ahc_controller_info(), don't bother updating len and - buf for the last sprintf since no-one will look at them - again. - - aic7xxx.h: - Increase the size of both msgout_buf and msgin_buf[]. - The PPR message is 8 bytes in length and we might - (on some platforms) combine the PPR with inquiry and - tag data. We now allocate 12 bytes in each. - - aic7xxx.seq: - Use quoted includes in the sequencer file and make up - for the lack of path information in some OS dependent - manner (sys/conf/files for FreeBSD, placement of files - in Linux). The assembler doesn't understand #ifdef - directives and this allows the files to be completely - shared between platforms. - - Remove an unnecessary nop instruction. - - aic7xxx_pci.c: - In ahc_pci_intr(), look at the error register to - determine whether a PCI error has occurred before - rushing into a configuration cycle to read the error. - Configuration cycles are more expensive than a single - memory read transaction and we may end up thinking - we have a PCI interrupt waiting just because we share - an IRQ with other devices. - - unpause the sequencer after clearing any PCI status. - For some errors (such as received Master Abort), the - error had nothing to do with this controller, but the - chip was automatically paused. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#4 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#4 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#4 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#4 edit - -Change 80 by gibbs@overdrive on 2000/09/19 09:20:44 - - Add ahc_send_async() for Linux and have it report bus resets. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#34 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#23 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#9 edit - -Change 79 by gibbs@overdrive on 2000/09/19 09:06:42 - - include inttypes.h. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#4 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#4 edit - -Change 78 by gibbs@overdrive on 2000/09/19 08:43:13 - - Bring back the Linux Makefile for the assembler. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#4 add - -Change 77 by gibbs@overdrive on 2000/09/19 08:15:07 - - Bring in latest FreeBSD port changes. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7770.c#1 add -... //depot/aic7xxx/aic7xxx/aic7xxx.c#3 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#3 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#3 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#3 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#3 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#3 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#3 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#3 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#3 edit - -Change 76 by gibbs@overdrive on 2000/09/19 07:24:37 - - Make sure these all have RCS ID expansion enabled. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.h#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#2 edit -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#2 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#2 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#2 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#2 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#2 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#2 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#2 edit -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#2 edit - -Change 75 by gibbs@overdrive on 2000/09/19 07:21:44 - - Move core files to core location in the repository. - -Affected files ... - -... //depot/aic7xxx/aic7xxx/aic7xxx.c#1 branch -... //depot/aic7xxx/aic7xxx/aic7xxx.h#1 branch -... //depot/aic7xxx/aic7xxx/aic7xxx.reg#1 branch -... //depot/aic7xxx/aic7xxx/aic7xxx.seq#1 branch -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#1 branch -... //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#1 branch -... //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#1 branch -... //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#1 branch -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#1 branch -... //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#1 branch -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#1 branch -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#1 branch -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#1 branch -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#1 branch -... //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#25 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#12 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.reg#5 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#12 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#4 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_eisa.c#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#10 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#7 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.c#5 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.h#4 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#7 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#2 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#5 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#4 delete - -Change 74 by gibbs@overdrive on 2000/09/12 11:57:59 - - Cleanup and changes to support FreeBSD - - aic7xxx.c: - FreeBSD includes. FreeBSD uses -nostdinc so - we must explicitly state the path to any referenced - files. - - staticize - - Inline ahc_intr(). It is only referenced once by - the OSM. - - Call ahc_notify_xfer_settings_change() in all locations - where settings change. - - Simplify ahc_platform_set_tags. Don't bother calling - it if the tags setting has not changed. - - Don't leak ahc->name() in ahc_free(). - - Add functions used only for target mode. - - pci_softc -> dev_softc. - - Move FreeBSD specific calls into aic7xxx_freebsd.c. - - Add marker to cleanup tstate info in ahc_free(). - - Bring back SEARCH_REMOVE to ahc_search_qinfifo(). - The FreeBSD error recovery code uses it. - - aic7xxx.h: - Add the io_ctx field into the scb. This represents a - pointer to the ccb or Scsi_Cmnd or whatever a platform - uses to keep track of the OSes io context. This is - faster and simpler than rooting around in the scb_platform - data object. - - Bring back in more target mode stuff. - - ahc_pci_softc_t -> ahc_dev_softc_t. - - inline ahc_intr. - - export functions referenced by FreeBSD's error recovery code. - - aic7xxx_93cx6.c: - FreeBSD inludes. - - aic7xxx_inline.h: - Inline ahc_intr. - - aic7xxx_osm.c: - Cleanup unused and #if 0'd code. - - platform_data->cmd -> io_ctx. - - ahc->pci_softc -> ahc->dev_softc. - - Cleanup unused (or should have been unused) fields - in ahc_platform_softc. - - ahc_platform_set_tags() simplification. Changed argument - goes away and the function is only called when the - tags setting changes. - - aic7xxx_osm.h: - Cleanup unused and #if 0'd code. - - Add ahc_insb() for use by ahc_dump_seq(). - - pci_softc -> dev_softc. - - platform_data->cmd -> io_ctx. - - aic7xxx_osm_pci.c: - pci_softc -> dev_softc. - - aic7xxx_pci.c: - FreeBSD includes - - pci_softc -> dev_softc. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#33 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#22 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#6 edit - -Change 72 by gibbs@overdrive on 2000/09/07 10:47:56 - - aic7xxx.c: - TAILQ_FOREACH is not safe to use when the list you - are traversing is modified in the body of the loop. - Manually traverse the list instead. - - aic7xxx_osm.h: - aic7xxx_osm.c: - Avoid re-entry issues during abort processing by - deferring the run of any device queues until after - ahc_intr() has completed. Just as in the case of - running the complete queue, the device queues will - need to be run from any abort processing performed - outside the interrupt handler as well. - - Bump our version number in preparation for another release. - - cam.h: - Make get and set transaction status work the same way as - in FreeBSD. Notably, mask with CAM_STATUS_MASK. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#23 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#32 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#8 edit - -Change 68 by gibbs@overdrive on 2000/09/06 10:25:15 - - aic7xxx.c: - Start the port back to FreeBSD.... - o Include FreeBSD header on FreeBSD - - o ahc_freeze_ccb -> ahc_freeze_scb() and unifdef. - - o Change XXX to __FreeBSD__ on sections of code - we still need additional special accessors for. - - o Bring in the rest of the target mode code. - - Move the pci_softc from platform_data into its own - field in ahc_softc. This makes it less cumbersome - to perform PCI operations. - - Add a routine, ahc_dump_card_state, that dumps the - state of all of our queues. This can be called when - something unexpected occurs to aid in debugging problems. - It is currently only called when we see an inactive - SCB come through ahc_done(). - - aic7xxx.h: - struct ahc_pci_softc -> ahc_pci_softc_t. - On both Linux and FreeBSD, the pci_softc need only - be a pointer to the platform provided PCI instance - object, so we let the OSM define this type to be - whatever is convenient. - - Add bug definition for SCB corruption on upload - with aic7899s on 66MHz PCI. - - Use bus space tag/handle pair for accessing the - card on all platforms. This removes an extra - pointer dereference and matches what FreeBSD - has been doing for some time. - - Move the platform_softc lower in the ahc_softc. - Since it no-longer includes the fields required - to access card registers, it is accessed less often - than the fields that now appear before it. - - aic7xxx.seq: - Implement a workaround for the 66MHz PCI SCB upload - corruption problem. By transferring first from the - SCB into SCBRAM and then performing the DMA, we - avoid the corruption. - - aic7xxx_osm.c: - ahc_pci_softc_t fallout. - - bus space fallout. - - Implement the platform dependant portions of - ahc_dump_card_state(). - - Fix a nasty bug in ahc_run_device_queue(). We - cannot send any SCB that does not have CAM_SIM_QUEUED - set to the card or it will get sent twice. Once - by the queue run routine and again by aic7xxx_queue(). - - aic7xxx_osm.h: - Implement bus space fields for PIO/MEMIO. - - struct ahc_pci_softc -> ahc_pci_softc_t - - Implement ahc_freeze_scb() which is a no-op on Linux. - - aic7xxx_osm_pci.c: - ahc_pci_softc_t fallout. - - bus space fallout. - - aic7xxx_pci.c: - ahc_pci_softc_t fallout. - - aicasm_symbol.c: - Pick up the correct db header on non-linux platforms. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#11 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#31 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#20 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#2 edit - -Change 64 by gibbs@overdrive on 2000/09/02 12:46:16 - - aic7xxx.c: - Add a chip name for the aic7895 Rev C. We differentiate - between the C and all other revs, so it is best to report - explicitly to the user when we find this chip. - - Export ahc_print_scb(); - - In restart_sequencer() do all of the things that the - sequencer used to do at startup. This shaves quite - a few instructions and there is no reason to "optimize" - these steps as they happen very rarely. - - Add some useful TRACEPOINT code. - - Use SCB_BASE instead of SCB_CONTROL to reference the - start of SCB ram. SCB_CONTROL is no longer the first - element in the SCB and this show why using a variable - location instead of a fixed constant is unwise. - - Explictily export controller information - (width, scsiid, number of SCBS, etc) via - ahc_controller_info() instead of spraying this - data out from all through ahc_init(). This - allows OSMs to display the data in any way - they see fit. - - Correct some SCB_BTT bugs. - - Size the downloaded constants table correctly. - - aic7xxx.h: - Give the aic7895C isn't own chip identifier. - - Note which controllers have the AUTOPAUSE feature. - - Add a bug entry for controllers that fail to handle - residual transfers after a PCI MWI transaction correctly. - - Move the status packet up to the top of the SCB in - preparation for shortening the number of bytes uploaded - during check condition and other errors. - - Store in our softc information about the pci cacheline size. - - aic7xxx.reg: - Move the SCB status packet up to the top of the SCB. - - Add a different download size for external SCB memory. - This appears to avoid a download corruption problem. - - Add the MWI_RESIDUAL field for the MWI sequencer workaround. - - Add a downloaded constants describing the PCI cachline size. - - aic7xxx.seq: - Move reset code into kernel space. - - Add MWI bug workaround. Essentially we save off the - portion of the current S/G segment that goes beyond the - last cacheline and transfer this separately. - - Use SCB_BASE instead of SCB_CONTROL for referencing the - start of SCB space. - - Add a workaround for transferring an embedded CDB from - external scratch ram on the aic7895. We must wait to - enable the DMA engine until after we have filled the - FIFO. - - Fix index_busy_target in the SCB_BTT case. - - Factor out some more code that is not needed when - we don't page SCBs. - - Replace explicit test against aic7895 in command channel - code with != ULTRA2. This gives the same effect and - doesn't require us to also check to see if this is an aic7895C. - - If we have large external SCBs, download 48 bytes of - SCB instead of 32. This appears to avoid an SCB - corruption problem. - - Solidify the PCI 2.1 retry problem on SCB dma operations - bug. We now wait until we are sure the chip is hung - before touching the FIFO. The old system seemed to - sometimes pull out data too soon or corrupt the - data. - - aic7xxx_inline.h: - Only explicitly pause the sequencer on command enqueue - operations if the chip does not have the auto-pause - feature or the queue registers feature. - - aic7xxx_osm.c: - Fix the number of trasactions we report as supporting - to the mid layer. Also fix our max opening count. - It was possible to overrun the FIFOs if we were using - the SCB busy target table. - - Provide more controller information through aic7xxx_info() - via the ahc_controller_info() routine. - - aic7xxx_osm.h: - More "number of transactions" cleanups. - - Our per-device active and openings count must be - signed so we can properly reduce our opening count - when downgrading from tagged to untagged. - - Add a bit definition for the memory write and invalidate - enable PCI space bit. - - Provide more information to the user on underflow conditions. - - aic7xxx_pci.c: - Clean up the way that large SCBs are enabled. This is - now only done in the ahc_probe_extscbs() routine. - - Fetch PCI cache line size information and put it in the - softc. - - Correct the seletion of large SCBs for Ultra2+ controllers - in the SCB config routine. - - If external SCBs are not present, run through the SCB - config routine with the default settings. This avoids - having to put code to attain the defaults somewhere - else. - - Correct SCB_BTT feature enable logic. We must have - external 64byte SCBs for this to work. - - If bootverbose, mention whether large SCBs are being - used. - - SCB_CONTROL->SCB_BASE. - - Output the Sequencer program address if we get a PCI - error. Useful in debugging. - - Note which controllers require MWI workarounds. - - Differentiate even more between the aic7895 and aic7895C. - Add code to deal the the spurious DAC cycle problem, - but don't enable it just yet. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#20 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.reg#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#30 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#4 edit - -Change 62 by gibbs@overdrive on 2000/08/29 05:51:37 - - Move to just a single driver version stored in aic7xxx_osm.h. - Cleanup information printed out at driver load time. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#29 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#18 edit - -Change 61 by gibbs@overdrive on 2000/08/29 05:46:33 - - aic7xxx.seq: - Be a little more careful in how we empty the FIFO - on PCI 2.1 compliant aic78XX chips. After pulling - out 8 bytes, wait for the FIFO to get some data - before testing to see if we are hung. - - aic7xxx_osm.c: - Fix the abort collision case in the device queue by - setting CAM_SIM_QUEUED only once aic7xxx_queue() has - released ownership of the SCB. The old code was somewhat - confused in how it flagged transactions as still being - owned by aic7xxx_queue(). - - Revert ahc_queue_busy_scb() and instead implement a - roll_back function ahc_free_busy_scb(). This makes - it much clearer who is aborting which scbs and how. - This required implementing ahc_unmap_scb() for use - by both ahc_done() and ahc_free_busy_scb(). - - Correct ahc_platform_abort_scbs to abort the correct - device. It was not checking wide/twin controller - properties and also suffered from a cut 'n paste error - that corrupted how the luns to traverse were determined. - - aic7xxx_osm.h: - Only return the low byte of the transaction status to - the rest of the world, but allow the high byte to be - set. This simplifies handling of the CAM_SIM_QUEUED - flag. - - cam.h: - Add the CAM_SIM_QUEUED flag. This flag is only used - in the device busy queue and indicates that the transaction - in the queue is no longer being operated on by aic7xxx_queue(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#28 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#7 edit - -Change 60 by gibbs@overdrive on 2000/08/24 12:12:57 - - Turn on ktext expansion for all files. - - Add $Id$ where appropriate. - - Add PCI 2.1 Retry bug workaround. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#19 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_eisa.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#27 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#16 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_eisa.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#3 edit - -Change 59 by gibbs@overdrive on 2000/08/22 08:26:27 - - Change the name of our controller to scsi%d once we know the host - number. Until that time, use a bus specific name. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#18 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#26 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#6 edit - -Change 58 by gibbs@overdrive on 2000/08/22 07:29:04 - - Remove old, #ifdef'd out, abort/reset implementations. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#25 edit - -Change 57 by gibbs@overdrive on 2000/08/22 07:20:46 - - Remove debugging printfs. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#5 edit - -Change 56 by gibbs@overdrive on 2000/08/22 06:53:44 - - aic7xxx.c: - For no, leave all locking to OSM layer. - - aic7xxx_osm.c: - Correct Adaptec copyright. - - Conditionalize inclusion of linux/init.h - - Add proc_dir_entry for older kernels. - - Don't declare static, entry points that may be - called externally in a static kernel linkage - configuration. - - Fixup abort processing for entries in the dev - queue. We first bring these transactions up - to a state where ahc_done() will work on them, - and then call ahc_done(). This ensures that - all mapped memory for the transaction, etc. is - released. - - Becareful not to overwrite the sense data buffer - in Scsi_Cmnd's. - - Guard against null host structures in aic7xxx_release. - - aic7xxx_osm.h: - Remove bogus status checking in ahc_set_transaction_status(). - - aic7xxx_osm_pci.c: - Use pci_find_class() to enumerate PCI devices. This should - work acceptably in all kernel versions we support. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#24 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#15 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#4 edit - -Change 54 by gibbs@overdrive on 2000/08/21 12:30:49 - - When aborting commands in our per-device queues, queue them - to the complete queue, thus avoiding the dead-lock of a direct - completion. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#23 edit - -Change 53 by gibbs@overdrive on 2000/08/21 09:50:38 - - Use DID_BUS_BUSY for CAM_REQUEUE_REQ. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#22 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#5 edit - -Change 52 by gibbs@overdrive on 2000/08/21 09:37:53 - - Implement aic7xxx_biosparam, finish tagged queuing implementation, - and complete the port to 2.2.14. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#21 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#14 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#4 edit - -Change 51 by gibbs@overdrive on 2000/08/12 10:40:14 - - aic7xxx.c: - Add a platform callback to notify the system when - tag settings change. We use this to freeze the - device queue until all oustanding transaction complete - when the tag type changes. - - aic7xxx_osm.c: - Add support for releasing the queue when the active - count goes to 0 for a particular device. - - Implement ahc_platform_set_tags() which will freeze - the queue when tag types change. - - In ahc_filter_cmd(), enable tags if the device supports them. - - aic7xxx_osm.h: - Prototype for ahc_platform_set_tags(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#16 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#20 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#13 edit - -Change 50 by gibbs@overdrive on 2000/08/12 10:10:26 - - Kill a diagnostic printf. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#19 edit - -Change 49 by gibbs@overdrive on 2000/08/12 10:06:51 - - Switch to queing SCBs not Linux scsi commands in our busy - queues. This avoids a locking and latency issues when we - have to run the queues from interrupt context. - - Run the busyq at the end of ahc_done. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#18 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#12 edit - -Change 48 by gibbs@overdrive on 2000/08/12 09:25:34 - - aic7xxx.c: - Add a platform callbacks for aborting transactions - sitting in OSM queues. - - aic7xxx_inline.h: - Don't lock in ahc_get_scb. Let the OSM do this - as it may need to lock other data structures (using - the same lock) around the time it aquires the SCB. - - aic7xxx_osm.c: - Implement Linux version of the transaction abort - callbacks. - - Modify ahc_get_device() to only allocate device - entries if asked. This allows this routine to - be used to see if a device exists at that location. - - Modify aic7xxx_queue() so that incoming commands - are placed into the device busy queue and that - transactions are only run if the device has - openings available and is not frozen. - - Check to see if a command has been aborted after - re-acquiring the ahc lock at the tail end of - aic7xxx_queue(). - - Modify ahc_alloc_device() to initialize the openings - and maxtags fields. - - aic7xxx_osm.h: - Add Adaptec Copyright. - - Add device fields required to handle tagged queuing. - - Add function prototypes for ahc_platform abort routines. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#15 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#17 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#11 edit - -Change 47 by gibbs@overdrive on 2000/08/12 07:00:10 - - Swith to using a union in ahc_cmd so we can avoid excessive - casting. - - Sort entries as they are inserted onto the completeq so that - transaction ordering for retried transactions is maintained. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#16 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#10 edit - -Change 46 by gibbs@overdrive on 2000/08/12 06:25:07 - - aic7xxx.c: - Remove some debugging printfs. - - Correctly deal with TWIN channel adapters when - dealing with the busy target table or busy target - queues. - - aic7xxx_osm.c: - Correct memset call in ahc_alloc_device() to - zero the correct nuber of bytes. - - aic7xxx_osm_pci.c: - Remove some debugging printfs. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#14 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#15 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#2 edit - -Change 45 by gibbs@overdrive on 2000/08/11 09:20:01 - - Set scb->platform_data->dev in aic7xxx_queue(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#14 edit - -Change 44 by gibbs@overdrive on 2000/08/11 08:47:10 - - Correct addressing for per-device data-structures for - twin channel devices. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#9 edit - -Change 43 by gibbs@overdrive on 2000/08/11 08:40:12 - - aic7xxx.c: - Remove the "SEARCH_REMOVE" case from ahc_search_action. - It is never used and it would be hard to create sane - semantics for its use. - - scbp->scb to match most of the rest of the driver. - - In ahc_search_qinfifo(), handle the untagged queues - as well. To the rest of the system, these are just - another part of the input fifo. - - aic7xxx_osm.c: - Add Adaptec Inc. copyright. - - Add a mechanism for allocating and freeing a per-device - data-structure for queue and other management. The - data structure is persistent so long as commands for - that device are outstanding and/or we've seen a proper - inquiry response from that device that makes us believe - there is a persistent device at that location (target/lun). - - aic7xxx_osm.h: - Per-device data structure definitions. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#13 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#12 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#8 edit - -Change 42 by gibbs@overdrive on 2000/08/11 04:43:03 - - Initialize the completeq with STAILQ_INIT now that it is an - STAILQ. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#11 edit - -Change 41 by gibbs@overdrive on 2000/08/11 04:37:07 - - Use a shaddow structure of scsi_cmnd so we can name fields - "reserved" for HBA use however we wish. This lets us use - the queue macros for queuing these structures. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#10 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#7 edit - -Change 37 by gibbs@overdrive on 2000/08/10 08:07:55 - - aic7xxx.c: - aic7xxx.h: - Move more function declarations to global scope. - - aic7xxx_osm.c: - Implement a mechanism to sniff completed commands - that complete with good status. We use this to - sniff completed inquiry responses for targets to - determine there transfer capabilities. - - aic7xxx_osm.h: - Add a definition for the inquiry response format - for use by our transaction sniffer. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#9 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#6 edit - -Change 36 by gibbs@overdrive on 2000/08/10 06:34:34 - - Spaces to tabs. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#8 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#8 edit - -Change 35 by gibbs@overdrive on 2000/08/10 05:33:22 - - aic7xxx.c: - Add ahc_busy_tcl(). This routine is used to add - an SCBID to the busy target's table. Right now this - is only used when transitioning a transaction from - tagged to untagged when a tag message is rejected. - - Move some function prototypes to aic7xxx.h for use - by other modules. - - Re-enable code that sets transaction status now that - we have an OSM method for doing this. - - Kill some debugging printfs. - - aic7xxx.h: - Added function prototypes for methods in aic7xxx.c - - aic7xxx.seq: - For added safety, when handling a data overrun, - clear STCNT before going into bit-bucket mode. - clearing STCNT should ensure that the data channel - will not resume a previous transfer setup via - PRELOADEN. - - aic7xxx_inline.h: - The controller lock is always held when a transaction is - freed. Don't bother re-acquiring it is ahc_free_scb(). - - Kill more diagnostic printfs. - - aic7xxx_osm.c: - Inline completion queue routines. - - Reset the bus on startup for now. Later we will honor - non-volatile card setting and if no reset is requested, - we will negotiate on the first transaction. - - Store a pointer to a scsi command's scb in the host_scribble - area while the command is outstanding. This allows us - to get back to the SCB from within the abort/reset routines. - - Check cmd->use_sg consistently. Even if only one SG is - provided, we must still treat the request_buffer pointer - as a pointer to a list of SG structures, not a contiguous - buffer. - - Fixup some bugs in how were were initializing SCBs in the - aic7xxx_queue routine. - - Keep track of pending SCBs in the pending_scb list. The - core routines in aic7xxx.c expect to find pending SCBS - here. - - Properly remove untagged transactions from the untagged - queue when they complete. - - Set transaction status to DID_OK (CAM_REQ_CMP) if, at - ahc_done time, the status is still CAM_REQ_INPROG. - - Add some diagnostic code to the abort routine so we - can determine why the mid-layer decided an abort was - necessary. - - aic7xxx_osm.h: - Make the ahc_done_lock a no-op on systems that use - interrupt blocking for locks. The softc lock is always - while the done lock is held, so no additional protection - is required. - - Add accessers for both the transaction and scsi status - fields. These are used by core code. - - cam.h: - Switch CAM_SEL_TIMEOUT from "DID_TIME_OUT" to - "DID_NO_CONNECT". This seems more correct based - on a quick look at scsi_error.c of the mid-layer. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.h#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#7 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#5 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#3 edit - -Change 32 by gibbs@overdrive on 2000/08/09 07:31:45 - - aic7xxx.c: - Remove duplicate OSM function ahc_scb_set_residual(). - We already had ahc_set_residual(). - - Use platform independent method for storing retrieved - sense data. - - aic7xxx_osm.c: - Add a deferred completion queue. The queue is filled - by ahc_done() and run from either our interrupt handler, - or error recovery routines after all commands are queued - for completion. - - Keep track of the size of our transfer. This is later - used in residual handling. - - Implement basic ahc_done() routine. This will need to - be enhanced to deal with things like queue full. - - aic7xxx_osm.h: - Implement the completeq. Due to the nature of the - scsi_cmnd structure, we cannot use a - style queue for this, so create a simple LIFO. - - Flesh out the inline accessors to OSM dependent - per transaction data fields. - - cam.h: - Map CAM status to Linux SCSI status codes. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#6 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#2 edit - -Change 31 by gibbs@overdrive on 2000/08/08 13:11:38 - - Debug adapter queue command path. We can now queue a command, - have the sequencer complete it, and route the compelted - command to ahc_done(). - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#5 edit - -Change 30 by gibbs@overdrive on 2000/08/08 10:01:08 - - First pass at the aic7xxx_queue routine. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#4 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#3 edit - -Change 29 by gibbs@overdrive on 2000/08/08 07:41:45 - - Missed in prior checkin. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_pci.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#2 edit - -Change 27 by gibbs@overdrive on 2000/08/08 07:10:41 - - Add definitions to properly lock the system when returning - commands back to the OS. - - Hook up our interrupt handler. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.c#2 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#3 edit -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#2 edit - -Change 26 by gibbs@overdrive on 2000/08/08 05:59:33 - - Get us to the point where we can successfully register - PCI adapters. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#2 edit - -Change 25 by gibbs@overdrive on 2000/08/08 05:58:36 - - More infrastructure - mostly from FreeBSD. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_eisa.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_eisa.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/queue.h#1 add - -Change 19 by gibbs@overdrive on 2000/07/28 03:12:09 - - Move into our sub-directory. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx_proc.c#4 delete - -Change 18 by gibbs@overdrive on 2000/07/27 12:00:48 - - Use the old Linux driver as the foundation for the Linux - specific core file. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#1 branch - -Change 7 by gibbs@overdrive on 2000/07/13 07:09:24 - - Latest SCSI message file from FreeBSD. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#2 edit - -Change 5 by gibbs@overdrive on 2000/07/13 07:07:29 - - Move the assembler to its own subdirectory. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/Makefile#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm.c#2 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm.h#2 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/Makefile#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.c#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm.h#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h#1 branch -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_gram.y#2 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_insformat.h#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_scan.l#2 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_symbol.c#3 delete -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aicasm_symbol.h#2 delete - -Change 1 by gibbs@overdrive on 2000/07/12 11:01:33 - - Initial import of Doug Ledford's aic7xxx driver v5.2.0. - -Affected files ... - -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx.c#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.reg#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx.seq#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/scsi_message.h#1 add -... //depot/aic7xxx/linux/drivers/scsi/aic7xxx/sequencer.h#1 add - diff -urN linux-2.4.21/drivers/scsi/aic79xx/Config.in linux-2.4.22/drivers/scsi/aic79xx/Config.in --- linux-2.4.21/drivers/scsi/aic79xx/Config.in 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/Config.in 1969-12-31 16:00:00.000000000 -0800 @@ -1,17 +0,0 @@ -dep_tristate 'Adaptec AIC79xx support' CONFIG_SCSI_AIC79XX $CONFIG_SCSI -if [ "$CONFIG_SCSI_AIC79XX" != "n" ]; then - int ' Maximum number of TCQ commands per device' \ - CONFIG_AIC79XX_CMDS_PER_DEVICE 32 - int ' Initial bus reset delay in milli-seconds' \ - CONFIG_AIC79XX_RESET_DELAY_MS 15000 - bool ' Build Adapter Firmware with Kernel Build' \ - CONFIG_AIC79XX_BUILD_FIRMWARE - bool ' Enable Read Streaming for All Targets' \ - CONFIG_AIC79XX_ENABLE_RD_STRM - bool ' Compile in Debugging Code' \ - CONFIG_AIC79XX_DEBUG_ENABLE - int ' Debug code enable mask (16384 for all debugging)' \ - CONFIG_AIC79XX_DEBUG_MASK 0 - bool ' Decode registers during diagnostics' \ - CONFIG_AIC79XX_REG_PRETTY_PRINT -fi diff -urN linux-2.4.21/drivers/scsi/aic79xx/Makefile linux-2.4.22/drivers/scsi/aic79xx/Makefile --- linux-2.4.21/drivers/scsi/aic79xx/Makefile 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,50 +0,0 @@ -# -# drivers/scsi/aic79xx/Makefile -# -# Makefile for the Linux aic79xx SCSI driver. -# - -O_TARGET := aic79xx_drv.o - -list-multi := aic79xx.o - -obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o - -EXTRA_CFLAGS += -I.. -#EXTRA_CFLAGS += -g - -# Platform Specific U320 Files -obj-aic79xx = aic79xx_osm.o aic79xx_proc.o aic79xx_osm_pci.o -# Core Files -obj-aic79xx += aic79xx_core.o aic79xx_pci.o -ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y) -obj-aic79xx += aic79xx_reg_print.o -endif - -# Override our module desitnation -MOD_DESTDIR = $(shell cd .. && $(CONFIG_SHELL) $(TOPDIR)/scripts/pathdown.sh) - -include $(TOPDIR)/Rules.make - -aic79xx_core.o: aic79xx_seq.h -$(obj-aic79xx): aic79xx_reg.h -aic79xx.o: aic79xx_seq.h aic79xx_reg.h $(obj-aic79xx) - $(LD) $(LD_RFLAG) -r -o $@ $(obj-aic79xx) - -ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y) -aic79xx_gen = aic79xx_seq.h aic79xx_reg.h -ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y) -aic79xx_gen += aic79xx_reg_print.c -aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \ - -p aic79xx_reg_print.c -i aic79xx_osm.h \ - -o aic79xx_seq.h aic79xx.seq -else -aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \ - -o aic79xx_seq.h aic79xx.seq -endif -$(aic79xx_gen): aic79xx.seq aic79xx.reg aicasm/aicasm - $(aic79xx_asm_cmd) -endif - -aicasm/aicasm: aicasm/*.[chyl] - $(MAKE) -C aicasm diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx.h linux-2.4.22/drivers/scsi/aic79xx/aic79xx.h --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,1480 +0,0 @@ -/* - * Core definitions and data structures shareable across OS platforms. - * - * Copyright (c) 1994-2002 Justin T. Gibbs. - * Copyright (c) 2000-2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#78 $ - * - * $FreeBSD$ - */ - -#ifndef _AIC79XX_H_ -#define _AIC79XX_H_ - -/* Register Definitions */ -#include "aic79xx_reg.h" - -/************************* Forward Declarations *******************************/ -struct ahd_platform_data; -struct scb_platform_data; - -/****************************** Useful Macros *********************************/ -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) - -#define ALL_CHANNELS '\0' -#define ALL_TARGETS_MASK 0xFFFF -#define INITIATOR_WILDCARD (~0) -#define SCB_LIST_NULL 0xFF00 -#define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL)) -#define QOUTFIFO_ENTRY_VALID 0x8000 -#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000)) -#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL) - -#define SCSIID_TARGET(ahd, scsiid) \ - (((scsiid) & TID) >> TID_SHIFT) -#define SCSIID_OUR_ID(scsiid) \ - ((scsiid) & OID) -#define SCSIID_CHANNEL(ahd, scsiid) ('A') -#define SCB_IS_SCSIBUS_B(ahd, scb) (0) -#define SCB_GET_OUR_ID(scb) \ - SCSIID_OUR_ID((scb)->hscb->scsiid) -#define SCB_GET_TARGET(ahd, scb) \ - SCSIID_TARGET((ahd), (scb)->hscb->scsiid) -#define SCB_GET_CHANNEL(ahd, scb) \ - SCSIID_CHANNEL(ahd, (scb)->hscb->scsiid) -#define SCB_GET_LUN(scb) \ - ((scb)->hscb->lun) -#define SCB_GET_TARGET_OFFSET(ahd, scb) \ - SCB_GET_TARGET(ahd, scb) -#define SCB_GET_TARGET_MASK(ahd, scb) \ - (0x01 << (SCB_GET_TARGET_OFFSET(ahd, scb))) -#ifdef AHD_DEBUG -#define SCB_IS_SILENT(scb) \ - ((ahd_debug & AHD_SHOW_MASKED_ERRORS) == 0 \ - && (((scb)->flags & SCB_SILENT) != 0)) -#else -#define SCB_IS_SILENT(scb) \ - (((scb)->flags & SCB_SILENT) != 0) -#endif -/* - * TCLs have the following format: TTTTLLLLLLLL - */ -#define TCL_TARGET_OFFSET(tcl) \ - ((((tcl) >> 4) & TID) >> 4) -#define TCL_LUN(tcl) \ - (tcl & (AHD_NUM_LUNS - 1)) -#define BUILD_TCL(scsiid, lun) \ - ((lun) | (((scsiid) & TID) << 4)) -#define BUILD_TCL_RAW(target, channel, lun) \ - ((lun) | ((target) << 8)) - -#define SCB_GET_TAG(scb) \ - ahd_le16toh(scb->hscb->tag) - -#ifndef AHD_TARGET_MODE -#undef AHD_TMODE_ENABLE -#define AHD_TMODE_ENABLE 0 -#endif - -#define AHD_BUILD_COL_IDX(target, lun) \ - (((lun) << 4) | target) - -#define AHD_GET_SCB_COL_IDX(ahd, scb) \ - ((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb)) - -#define AHD_SET_SCB_COL_IDX(scb, col_idx) \ -do { \ - (scb)->hscb->scsiid = ((col_idx) << TID_SHIFT) & TID; \ - (scb)->hscb->lun = ((col_idx) >> 4) & (AHD_NUM_LUNS_NONPKT-1); \ -} while (0) - -#define AHD_COPY_SCB_COL_IDX(dst, src) \ -do { \ - dst->hscb->scsiid = src->hscb->scsiid; \ - dst->hscb->lun = src->hscb->lun; \ -} while (0) - -#define AHD_NEVER_COL_IDX 0xFFFF - -/**************************** Driver Constants ********************************/ -/* - * The maximum number of supported targets. - */ -#define AHD_NUM_TARGETS 16 - -/* - * The maximum number of supported luns. - * The identify message only supports 64 luns in non-packetized transfers. - * You can have 2^64 luns when information unit transfers are enabled, - * but until we see a need to support that many, we support 256. - */ -#define AHD_NUM_LUNS_NONPKT 64 -#define AHD_NUM_LUNS 256 - -/* - * The maximum transfer per S/G segment. - */ -#define AHD_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */ - -/* - * The maximum amount of SCB storage in hardware on a controller. - * This value represents an upper bound. Due to software design, - * we may not be able to use this number. - */ -#define AHD_SCB_MAX 512 - -/* - * The maximum number of concurrent transactions supported per driver instance. - * Sequencer Control Blocks (SCBs) store per-transaction information. - */ -#define AHD_MAX_QUEUE AHD_SCB_MAX - -/* - * Define the size of our QIN and QOUT FIFOs. They must be a power of 2 - * in size and accomodate as many transactions as can be queued concurrently. - */ -#define AHD_QIN_SIZE AHD_MAX_QUEUE -#define AHD_QOUT_SIZE AHD_MAX_QUEUE - -#define AHD_QIN_WRAP(x) ((x) & (AHD_QIN_SIZE-1)) -/* - * The maximum amount of SCB storage we allocate in host memory. - */ -#define AHD_SCB_MAX_ALLOC AHD_MAX_QUEUE - -/* - * Ring Buffer of incoming target commands. - * We allocate 256 to simplify the logic in the sequencer - * by using the natural wrap point of an 8bit counter. - */ -#define AHD_TMODE_CMDS 256 - -/* Reset line assertion time in us */ -#define AHD_BUSRESET_DELAY 25 - -/******************* Chip Characteristics/Operating Settings *****************/ -/* - * Chip Type - * The chip order is from least sophisticated to most sophisticated. - */ -typedef enum { - AHD_NONE = 0x0000, - AHD_CHIPID_MASK = 0x00FF, - AHD_AIC7901 = 0x0001, - AHD_AIC7902 = 0x0002, - AHD_AIC7901A = 0x0003, - AHD_PCI = 0x0100, /* Bus type PCI */ - AHD_PCIX = 0x0200, /* Bus type PCIX */ - AHD_BUS_MASK = 0x0F00 -} ahd_chip; - -/* - * Features available in each chip type. - */ -typedef enum { - AHD_FENONE = 0x00000, - AHD_WIDE = 0x00001,/* Wide Channel */ - AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */ - AHD_TARGETMODE = 0x01000,/* Has tested target mode support */ - AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */ - AHD_RTI = 0x04000,/* Retained Training Support */ - AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */ - AHD_NEW_DFCNTRL_OPTS = 0x10000,/* SCSIENWRDIS bit */ - AHD_REMOVABLE = 0x00000,/* Hot-Swap supported - None so far*/ - AHD_AIC7901_FE = AHD_FENONE, - AHD_AIC7902_FE = AHD_MULTI_FUNC -} ahd_feature; - -/* - * Bugs in the silicon that we work around in software. - */ -typedef enum { - AHD_BUGNONE = 0x0000, - /* - * Rev A hardware fails to update LAST/CURR/NEXTSCB - * correctly in certain packetized selection cases. - */ - AHD_SENT_SCB_UPDATE_BUG = 0x0001, - /* The wrong SCB is accessed to check the abort pending bit. */ - AHD_ABORT_LQI_BUG = 0x0002, - /* Packetized bitbucket crosses packet boundaries. */ - AHD_PKT_BITBUCKET_BUG = 0x0004, - /* The selection timer runs twice as long as its setting. */ - AHD_LONG_SETIMO_BUG = 0x0008, - /* The Non-LQ CRC error status is delayed until phase change. */ - AHD_NLQICRC_DELAYED_BUG = 0x0010, - /* The chip must be reset for all outgoing bus resets. */ - AHD_SCSIRST_BUG = 0x0020, - /* Some PCIX fields must be saved and restored across chip reset. */ - AHD_PCIX_CHIPRST_BUG = 0x0040, - /* MMAPIO is not functional in PCI-X mode. */ - AHD_PCIX_MMAPIO_BUG = 0x0080, - /* Bug workarounds that can be disabled on non-PCIX busses. */ - AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG - | AHD_PCIX_MMAPIO_BUG, - /* - * LQOSTOP0 status set even for forced selections with ATN - * to perform non-packetized message delivery. - */ - AHD_LQO_ATNO_BUG = 0x0100, - /* FIFO auto-flush does not always trigger. */ - AHD_AUTOFLUSH_BUG = 0x0200, - /* The CLRLQO registers are not self-clearing. */ - AHD_CLRLQO_AUTOCLR_BUG = 0x0400, - /* The PACKETIZED status bit refers to the previous connection. */ - AHD_PKTIZED_STATUS_BUG = 0x0800, - /* "Short Luns" are not placed into outgoing LQ packets correctly. */ - AHD_PKT_LUN_BUG = 0x1000, - /* - * Only the FIFO allocated to the non-packetized connection may - * be in use during a non-packetzied connection. - */ - AHD_NONPACKFIFO_BUG = 0x2000, - /* - * Writing to a DFF SCBPTR register may fail if concurent with - * a hardware write to the other DFF SCBPTR register. This is - * not currently a concern in our sequencer since all chips with - * this bug have the AHD_NONPACKFIFO_BUG and all writes of concern - * occur in non-packetized connections. - */ - AHD_MDFF_WSCBPTR_BUG = 0x4000, - /* SGHADDR updates are slow. */ - AHD_REG_SLOW_SETTLE_BUG = 0x8000, - /* - * Changing the MODE_PTR coincident with an interrupt that - * switches to a different mode will cause the interrupt to - * be in the mode written outside of interrupt context. - */ - AHD_SET_MODE_BUG = 0x10000, - /* Non-packetized busfree revision does not work. */ - AHD_BUSFREEREV_BUG = 0x20000, - /* - * Paced transfers are indicated with a non-standard PPR - * option bit in the neg table, 160MHz is indicated by - * sync factor 0x7, and the offset if off by a factor of 2. - */ - AHD_PACED_NEGTABLE_BUG = 0x40000, - /* LQOOVERRUN false positives. */ - AHD_LQOOVERRUN_BUG = 0x80000, - /* - * Controller write to INTSTAT will lose to a host - * write to CLRINT. - */ - AHD_INTCOLLISION_BUG = 0x100000 -} ahd_bug; - -/* - * Configuration specific settings. - * The driver determines these settings by probing the - * chip/controller's configuration. - */ -typedef enum { - AHD_FNONE = 0x00000, - AHD_PRIMARY_CHANNEL = 0x00003,/* - * The channel that should - * be probed first. - */ - AHD_USEDEFAULTS = 0x00004,/* - * For cards without an seeprom - * or a BIOS to initialize the chip's - * SRAM, we use the default target - * settings. - */ - AHD_SEQUENCER_DEBUG = 0x00008, - AHD_RESET_BUS_A = 0x00010, - AHD_EXTENDED_TRANS_A = 0x00020, - AHD_TERM_ENB_A = 0x00040, - AHD_SPCHK_ENB_A = 0x00080, - AHD_STPWLEVEL_A = 0x00100, - AHD_INITIATORROLE = 0x00200,/* - * Allow initiator operations on - * this controller. - */ - AHD_TARGETROLE = 0x00400,/* - * Allow target operations on this - * controller. - */ - AHD_RESOURCE_SHORTAGE = 0x00800, - AHD_TQINFIFO_BLOCKED = 0x01000,/* Blocked waiting for ATIOs */ - AHD_INT50_SPEEDFLEX = 0x02000,/* - * Internal 50pin connector - * sits behind an aic3860 - */ - AHD_BIOS_ENABLED = 0x04000, - AHD_ALL_INTERRUPTS = 0x08000, - AHD_39BIT_ADDRESSING = 0x10000,/* Use 39 bit addressing scheme. */ - AHD_64BIT_ADDRESSING = 0x20000,/* Use 64 bit addressing scheme. */ - AHD_CURRENT_SENSING = 0x40000, - AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */ - AHD_HP_BOARD = 0x100000, - AHD_RESET_POLL_ACTIVE = 0x200000, - AHD_UPDATE_PEND_CMDS = 0x400000, - AHD_RUNNING_QOUTFIFO = 0x800000 -} ahd_flag; - -/************************* Hardware SCB Definition ***************************/ - -/* - * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB - * consists of a "hardware SCB" mirroring the fields availible on the card - * and additional information the kernel stores for each transaction. - * - * To minimize space utilization, a portion of the hardware scb stores - * different data during different portions of a SCSI transaction. - * As initialized by the host driver for the initiator role, this area - * contains the SCSI cdb (or a pointer to the cdb) to be executed. After - * the cdb has been presented to the target, this area serves to store - * residual transfer information and the SCSI status byte. - * For the target role, the contents of this area do not change, but - * still serve a different purpose than for the initiator role. See - * struct target_data for details. - */ - -/* - * Status information embedded in the shared poriton of - * an SCB after passing the cdb to the target. The kernel - * driver will only read this data for transactions that - * complete abnormally. - */ -struct initiator_status { - uint32_t residual_datacnt; /* Residual in the current S/G seg */ - uint32_t residual_sgptr; /* The next S/G for this transfer */ - uint8_t scsi_status; /* Standard SCSI status byte */ -}; - -struct target_status { - uint32_t residual_datacnt; /* Residual in the current S/G seg */ - uint32_t residual_sgptr; /* The next S/G for this transfer */ - uint8_t scsi_status; /* SCSI status to give to initiator */ - uint8_t target_phases; /* Bitmap of phases to execute */ - uint8_t data_phase; /* Data-In or Data-Out */ - uint8_t initiator_tag; /* Initiator's transaction tag */ -}; - -/* - * Initiator mode SCB shared data area. - * If the embedded CDB is 12 bytes or less, we embed - * the sense buffer address in the SCB. This allows - * us to retrieve sense information without interupting - * the host in packetized mode. - */ -typedef uint32_t sense_addr_t; -#define MAX_CDB_LEN 16 -#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t)) -union initiator_data { - uint64_t cdbptr; - uint8_t cdb[MAX_CDB_LEN]; - struct { - uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR]; - sense_addr_t sense_addr; - } cdb_plus_saddr; -}; - -/* - * Target mode version of the shared data SCB segment. - */ -struct target_data { - uint32_t spare[2]; - uint8_t scsi_status; /* SCSI status to give to initiator */ - uint8_t target_phases; /* Bitmap of phases to execute */ - uint8_t data_phase; /* Data-In or Data-Out */ - uint8_t initiator_tag; /* Initiator's transaction tag */ -}; - -struct hardware_scb { -/*0*/ union { - union initiator_data idata; - struct target_data tdata; - struct initiator_status istatus; - struct target_status tstatus; - } shared_data; -/* - * A word about residuals. - * The scb is presented to the sequencer with the dataptr and datacnt - * fields initialized to the contents of the first S/G element to - * transfer. The sgptr field is initialized to the bus address for - * the S/G element that follows the first in the in core S/G array - * or'ed with the SG_FULL_RESID flag. Sgptr may point to an invalid - * S/G entry for this transfer (single S/G element transfer with the - * first elements address and length preloaded in the dataptr/datacnt - * fields). If no transfer is to occur, sgptr is set to SG_LIST_NULL. - * The SG_FULL_RESID flag ensures that the residual will be correctly - * noted even if no data transfers occur. Once the data phase is entered, - * the residual sgptr and datacnt are loaded from the sgptr and the - * datacnt fields. After each S/G element's dataptr and length are - * loaded into the hardware, the residual sgptr is advanced. After - * each S/G element is expired, its datacnt field is checked to see - * if the LAST_SEG flag is set. If so, SG_LIST_NULL is set in the - * residual sg ptr and the transfer is considered complete. If the - * sequencer determines that there is a residual in the tranfer, or - * there is non-zero status, it will set the SG_STATUS_VALID flag in - * sgptr and dma the scb back into host memory. To sumarize: - * - * Sequencer: - * o A residual has occurred if SG_FULL_RESID is set in sgptr, - * or residual_sgptr does not have SG_LIST_NULL set. - * - * o We are transfering the last segment if residual_datacnt has - * the SG_LAST_SEG flag set. - * - * Host: - * o A residual can only have occurred if a completed scb has the - * SG_STATUS_VALID flag set. Inspection of the SCSI status field, - * the residual_datacnt, and the residual_sgptr field will tell - * for sure. - * - * o residual_sgptr and sgptr refer to the "next" sg entry - * and so may point beyond the last valid sg entry for the - * transfer. - */ -#define SG_PTR_MASK 0xFFFFFFF8 -/*16*/ uint16_t tag; -/*18*/ uint8_t cdb_len; -/*19*/ uint8_t task_management; -/*20*/ uint32_t next_hscb_busaddr; -/*24*/ uint64_t dataptr; -/*32*/ uint32_t datacnt; /* Byte 3 is spare. */ -/*36*/ uint32_t sgptr; -/*40*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */ -/*41*/ uint8_t scsiid; /* - * Selection out Id - * Our Id (bits 0-3) Their ID (bits 4-7) - */ -/*42*/ uint8_t lun; -/*43*/ uint8_t task_attribute; -/*44*/ uint32_t hscb_busaddr; -/******* Long lun field only downloaded for full 8 byte lun support *******/ -/*48*/ uint8_t pkt_long_lun[8]; -/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/ -/*56*/ uint8_t spare[8]; -}; - -/************************ Kernel SCB Definitions ******************************/ -/* - * Some fields of the SCB are OS dependent. Here we collect the - * definitions for elements that all OS platforms need to include - * in there SCB definition. - */ - -/* - * Definition of a scatter/gather element as transfered to the controller. - * The aic7xxx chips only support a 24bit length. We use the top byte of - * the length to store additional address bits and a flag to indicate - * that a given segment terminates the transfer. This gives us an - * addressable range of 512GB on machines with 64bit PCI or with chips - * that can support dual address cycles on 32bit PCI busses. - */ -struct ahd_dma_seg { - uint32_t addr; - uint32_t len; -#define AHD_DMA_LAST_SEG 0x80000000 -#define AHD_SG_HIGH_ADDR_MASK 0x7F000000 -#define AHD_SG_LEN_MASK 0x00FFFFFF -}; - -struct ahd_dma64_seg { - uint64_t addr; - uint32_t len; - uint32_t pad; -}; - -struct map_node { - bus_dmamap_t dmamap; - bus_addr_t physaddr; - uint8_t *vaddr; - SLIST_ENTRY(map_node) links; -}; - -/* - * The current state of this SCB. - */ -typedef enum { - SCB_FLAG_NONE = 0x00000, - SCB_TRANSMISSION_ERROR = 0x00001,/* - * We detected a parity or CRC - * error that has effected the - * payload of the command. This - * flag is checked when normal - * status is returned to catch - * the case of a target not - * responding to our attempt - * to report the error. - */ - SCB_OTHERTCL_TIMEOUT = 0x00002,/* - * Another device was active - * during the first timeout for - * this SCB so we gave ourselves - * an additional timeout period - * in case it was hogging the - * bus. - */ - SCB_DEVICE_RESET = 0x00004, - SCB_SENSE = 0x00008, - SCB_CDB32_PTR = 0x00010, - SCB_RECOVERY_SCB = 0x00020, - SCB_AUTO_NEGOTIATE = 0x00040,/* Negotiate to achieve goal. */ - SCB_NEGOTIATE = 0x00080,/* Negotiation forced for command. */ - SCB_ABORT = 0x00100, - SCB_ACTIVE = 0x00200, - SCB_TARGET_IMMEDIATE = 0x00400, - SCB_PACKETIZED = 0x00800, - SCB_EXPECT_PPR_BUSFREE = 0x01000, - SCB_PKT_SENSE = 0x02000, - SCB_CMDPHASE_ABORT = 0x04000, - SCB_ON_COL_LIST = 0x08000, - SCB_SILENT = 0x10000 /* - * Be quiet about transmission type - * errors. They are expected and we - * don't want to upset the user. This - * flag is typically used during DV. - */ -} scb_flag; - -struct scb { - struct hardware_scb *hscb; - union { - SLIST_ENTRY(scb) sle; - LIST_ENTRY(scb) le; - TAILQ_ENTRY(scb) tqe; - } links; - union { - SLIST_ENTRY(scb) sle; - LIST_ENTRY(scb) le; - TAILQ_ENTRY(scb) tqe; - } links2; -#define pending_links links2.le -#define collision_links links2.le - struct scb *col_scb; - ahd_io_ctx_t io_ctx; - struct ahd_softc *ahd_softc; - scb_flag flags; -#ifndef __linux__ - bus_dmamap_t dmamap; -#endif - struct scb_platform_data *platform_data; - struct map_node *hscb_map; - struct map_node *sg_map; - struct map_node *sense_map; - void *sg_list; - uint8_t *sense_data; - bus_addr_t sg_list_busaddr; - bus_addr_t sense_busaddr; - u_int sg_count;/* How full ahd_dma_seg is */ -#define AHD_MAX_LQ_CRC_ERRORS 5 - u_int crc_retry_count; -}; - -TAILQ_HEAD(scb_tailq, scb); -LIST_HEAD(scb_list, scb); - -struct scb_data { - /* - * TAILQ of lists of free SCBs grouped by device - * collision domains. - */ - struct scb_tailq free_scbs; - - /* - * Per-device lists of SCBs whose tag ID would collide - * with an already active tag on the device. - */ - struct scb_list free_scb_lists[AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT]; - - /* - * SCBs that will not collide with any active device. - */ - struct scb_list any_dev_free_scb_list; - - /* - * Mapping from tag to SCB. - */ - struct scb *scbindex[AHD_SCB_MAX]; - - /* - * "Bus" addresses of our data structures. - */ - bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */ - bus_dma_tag_t sg_dmat; /* dmat for our sg segments */ - bus_dma_tag_t sense_dmat; /* dmat for our sense buffers */ - SLIST_HEAD(, map_node) hscb_maps; - SLIST_HEAD(, map_node) sg_maps; - SLIST_HEAD(, map_node) sense_maps; - int scbs_left; /* unallocated scbs in head map_node */ - int sgs_left; /* unallocated sgs in head map_node */ - int sense_left; /* unallocated sense in head map_node */ - uint16_t numscbs; - uint16_t maxhscbs; /* Number of SCBs on the card */ - uint8_t init_level; /* - * How far we've initialized - * this structure. - */ -}; - -/************************ Target Mode Definitions *****************************/ - -/* - * Connection desciptor for select-in requests in target mode. - */ -struct target_cmd { - uint8_t scsiid; /* Our ID and the initiator's ID */ - uint8_t identify; /* Identify message */ - uint8_t bytes[22]; /* - * Bytes contains any additional message - * bytes terminated by 0xFF. The remainder - * is the cdb to execute. - */ - uint8_t cmd_valid; /* - * When a command is complete, the firmware - * will set cmd_valid to all bits set. - * After the host has seen the command, - * the bits are cleared. This allows us - * to just peek at host memory to determine - * if more work is complete. cmd_valid is on - * an 8 byte boundary to simplify setting - * it on aic7880 hardware which only has - * limited direct access to the DMA FIFO. - */ - uint8_t pad[7]; -}; - -/* - * Number of events we can buffer up if we run out - * of immediate notify ccbs. - */ -#define AHD_TMODE_EVENT_BUFFER_SIZE 8 -struct ahd_tmode_event { - uint8_t initiator_id; - uint8_t event_type; /* MSG type or EVENT_TYPE_BUS_RESET */ -#define EVENT_TYPE_BUS_RESET 0xFF - uint8_t event_arg; -}; - -/* - * Per enabled lun target mode state. - * As this state is directly influenced by the host OS'es target mode - * environment, we let the OS module define it. Forward declare the - * structure here so we can store arrays of them, etc. in OS neutral - * data structures. - */ -#ifdef AHD_TARGET_MODE -struct ahd_tmode_lstate { - struct cam_path *path; - struct ccb_hdr_slist accept_tios; - struct ccb_hdr_slist immed_notifies; - struct ahd_tmode_event event_buffer[AHD_TMODE_EVENT_BUFFER_SIZE]; - uint8_t event_r_idx; - uint8_t event_w_idx; -}; -#else -struct ahd_tmode_lstate; -#endif - -/******************** Transfer Negotiation Datastructures *********************/ -#define AHD_TRANS_CUR 0x01 /* Modify current neogtiation status */ -#define AHD_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */ -#define AHD_TRANS_GOAL 0x04 /* Modify negotiation goal */ -#define AHD_TRANS_USER 0x08 /* Modify user negotiation settings */ -#define AHD_PERIOD_10MHz 0x19 - -#define AHD_WIDTH_UNKNOWN 0xFF -#define AHD_PERIOD_UNKNOWN 0xFF -#define AHD_OFFSET_UNKNOWN 0x0 -#define AHD_PPR_OPTS_UNKNOWN 0xFF - -/* - * Transfer Negotiation Information. - */ -struct ahd_transinfo { - uint8_t protocol_version; /* SCSI Revision level */ - uint8_t transport_version; /* SPI Revision level */ - uint8_t width; /* Bus width */ - uint8_t period; /* Sync rate factor */ - uint8_t offset; /* Sync offset */ - uint8_t ppr_options; /* Parallel Protocol Request options */ -}; - -/* - * Per-initiator current, goal and user transfer negotiation information. */ -struct ahd_initiator_tinfo { - struct ahd_transinfo curr; - struct ahd_transinfo goal; - struct ahd_transinfo user; -}; - -/* - * Per enabled target ID state. - * Pointers to lun target state as well as sync/wide negotiation information - * for each initiator<->target mapping. For the initiator role we pretend - * that we are the target and the targets are the initiators since the - * negotiation is the same regardless of role. - */ -struct ahd_tmode_tstate { - struct ahd_tmode_lstate* enabled_luns[AHD_NUM_LUNS]; - struct ahd_initiator_tinfo transinfo[AHD_NUM_TARGETS]; - - /* - * Per initiator state bitmasks. - */ - uint16_t auto_negotiate;/* Auto Negotiation Required */ - uint16_t discenable; /* Disconnection allowed */ - uint16_t tagenable; /* Tagged Queuing allowed */ -}; - -/* - * Points of interest along the negotiated transfer scale. - */ -#define AHD_SYNCRATE_160 0x8 -#define AHD_SYNCRATE_PACED 0x8 -#define AHD_SYNCRATE_DT 0x9 -#define AHD_SYNCRATE_ULTRA2 0xa -#define AHD_SYNCRATE_ULTRA 0xc -#define AHD_SYNCRATE_FAST 0x19 -#define AHD_SYNCRATE_MIN_DT AHD_SYNCRATE_FAST -#define AHD_SYNCRATE_SYNC 0x32 -#define AHD_SYNCRATE_MIN 0x60 -#define AHD_SYNCRATE_ASYNC 0xFF -#define AHD_SYNCRATE_MAX AHD_SYNCRATE_160 - -/* Safe and valid period for async negotiations. */ -#define AHD_ASYNC_XFER_PERIOD 0x44 - -/* - * In RevA, the synctable uses a 120MHz rate for the period - * factor 8 and 160MHz for the period factor 7. The 120MHz - * rate never made it into the official SCSI spec, so we must - * compensate when setting the negotiation table for Rev A - * parts. - */ -#define AHD_SYNCRATE_REVA_120 0x8 -#define AHD_SYNCRATE_REVA_160 0x7 - -/***************************** Lookup Tables **********************************/ -/* - * Phase -> name and message out response - * to parity errors in each phase table. - */ -struct ahd_phase_table_entry { - uint8_t phase; - uint8_t mesg_out; /* Message response to parity errors */ - char *phasemsg; -}; - -/************************** Serial EEPROM Format ******************************/ - -struct seeprom_config { -/* - * Per SCSI ID Configuration Flags - */ - uint16_t device_flags[16]; /* words 0-15 */ -#define CFXFER 0x003F /* synchronous transfer rate */ -#define CFXFER_ASYNC 0x3F -#define CFQAS 0x0040 /* Negotiate QAS */ -#define CFPACKETIZED 0x0080 /* Negotiate Packetized Transfers */ -#define CFSTART 0x0100 /* send start unit SCSI command */ -#define CFINCBIOS 0x0200 /* include in BIOS scan */ -#define CFDISC 0x0400 /* enable disconnection */ -#define CFMULTILUNDEV 0x0800 /* Probe multiple luns in BIOS scan */ -#define CFWIDEB 0x1000 /* wide bus device */ -#define CFHOSTMANAGED 0x8000 /* Managed by a RAID controller */ - -/* - * BIOS Control Bits - */ - uint16_t bios_control; /* word 16 */ -#define CFSUPREM 0x0001 /* support all removeable drives */ -#define CFSUPREMB 0x0002 /* support removeable boot drives */ -#define CFBIOSSTATE 0x000C /* BIOS Action State */ -#define CFBS_DISABLED 0x00 -#define CFBS_ENABLED 0x04 -#define CFBS_DISABLED_SCAN 0x08 -#define CFENABLEDV 0x0010 /* Perform Domain Validation */ -#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */ -#define CFSPARITY 0x0040 /* SCSI parity */ -#define CFEXTEND 0x0080 /* extended translation enabled */ -#define CFBOOTCD 0x0100 /* Support Bootable CD-ROM */ -#define CFMSG_LEVEL 0x0600 /* BIOS Message Level */ -#define CFMSG_VERBOSE 0x0000 -#define CFMSG_SILENT 0x0200 -#define CFMSG_DIAG 0x0400 -#define CFRESETB 0x0800 /* reset SCSI bus at boot */ -/* UNUSED 0xf000 */ - -/* - * Host Adapter Control Bits - */ - uint16_t adapter_control; /* word 17 */ -#define CFAUTOTERM 0x0001 /* Perform Auto termination */ -#define CFSTERM 0x0002 /* SCSI low byte termination */ -#define CFWSTERM 0x0004 /* SCSI high byte termination */ -#define CFSEAUTOTERM 0x0008 /* Ultra2 Perform secondary Auto Term*/ -#define CFSELOWTERM 0x0010 /* Ultra2 secondary low term */ -#define CFSEHIGHTERM 0x0020 /* Ultra2 secondary high term */ -#define CFSTPWLEVEL 0x0040 /* Termination level control */ -#define CFBIOSAUTOTERM 0x0080 /* Perform Auto termination */ -#define CFTERM_MENU 0x0100 /* BIOS displays termination menu */ -#define CFCLUSTERENB 0x8000 /* Cluster Enable */ - -/* - * Bus Release Time, Host Adapter ID - */ - uint16_t brtime_id; /* word 18 */ -#define CFSCSIID 0x000f /* host adapter SCSI ID */ -/* UNUSED 0x00f0 */ -#define CFBRTIME 0xff00 /* bus release time/PCI Latency Time */ - -/* - * Maximum targets - */ - uint16_t max_targets; /* word 19 */ -#define CFMAXTARG 0x00ff /* maximum targets */ -#define CFBOOTLUN 0x0f00 /* Lun to boot from */ -#define CFBOOTID 0xf000 /* Target to boot from */ - uint16_t res_1[10]; /* words 20-29 */ - uint16_t signature; /* BIOS Signature */ -#define CFSIGNATURE 0x400 - uint16_t checksum; /* word 31 */ -}; - -/****************************** Flexport Logic ********************************/ -#define FLXADDR_TERMCTL 0x0 -#define FLX_TERMCTL_ENSECHIGH 0x8 -#define FLX_TERMCTL_ENSECLOW 0x4 -#define FLX_TERMCTL_ENPRIHIGH 0x2 -#define FLX_TERMCTL_ENPRILOW 0x1 -#define FLXADDR_ROMSTAT_CURSENSECTL 0x1 -#define FLX_ROMSTAT_SEECFG 0xF0 -#define FLX_ROMSTAT_EECFG 0x0F -#define FLX_ROMSTAT_SEE_93C66 0x00 -#define FLX_ROMSTAT_SEE_NONE 0xF0 -#define FLX_ROMSTAT_EE_512x8 0x0 -#define FLX_ROMSTAT_EE_1MBx8 0x1 -#define FLX_ROMSTAT_EE_2MBx8 0x2 -#define FLX_ROMSTAT_EE_4MBx8 0x3 -#define FLX_ROMSTAT_EE_16MBx8 0x4 -#define CURSENSE_ENB 0x1 -#define FLXADDR_FLEXSTAT 0x2 -#define FLX_FSTAT_BUSY 0x1 -#define FLXADDR_CURRENT_STAT 0x4 -#define FLX_CSTAT_SEC_HIGH 0xC0 -#define FLX_CSTAT_SEC_LOW 0x30 -#define FLX_CSTAT_PRI_HIGH 0x0C -#define FLX_CSTAT_PRI_LOW 0x03 -#define FLX_CSTAT_MASK 0x03 -#define FLX_CSTAT_SHIFT 2 -#define FLX_CSTAT_OKAY 0x0 -#define FLX_CSTAT_OVER 0x1 -#define FLX_CSTAT_UNDER 0x2 -#define FLX_CSTAT_INVALID 0x3 - -int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, - u_int start_addr, u_int count); - -int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, - u_int start_addr, u_int count); -int ahd_wait_seeprom(struct ahd_softc *ahd); -int ahd_verify_cksum(struct seeprom_config *sc); -int ahd_acquire_seeprom(struct ahd_softc *ahd); -void ahd_release_seeprom(struct ahd_softc *ahd); - -/**************************** Message Buffer *********************************/ -typedef enum { - MSG_FLAG_NONE = 0x00, - MSG_FLAG_EXPECT_PPR_BUSFREE = 0x01, - MSG_FLAG_IU_REQ_CHANGED = 0x02, - MSG_FLAG_EXPECT_IDE_BUSFREE = 0x04, - MSG_FLAG_EXPECT_QASREJ_BUSFREE = 0x08, - MSG_FLAG_PACKETIZED = 0x10 -} ahd_msg_flags; - -typedef enum { - MSG_TYPE_NONE = 0x00, - MSG_TYPE_INITIATOR_MSGOUT = 0x01, - MSG_TYPE_INITIATOR_MSGIN = 0x02, - MSG_TYPE_TARGET_MSGOUT = 0x03, - MSG_TYPE_TARGET_MSGIN = 0x04 -} ahd_msg_type; - -typedef enum { - MSGLOOP_IN_PROG, - MSGLOOP_MSGCOMPLETE, - MSGLOOP_TERMINATED -} msg_loop_stat; - -/*********************** Software Configuration Structure *********************/ -struct ahd_suspend_channel_state { - uint8_t scsiseq; - uint8_t sxfrctl0; - uint8_t sxfrctl1; - uint8_t simode0; - uint8_t simode1; - uint8_t seltimer; - uint8_t seqctl; -}; - -struct ahd_suspend_state { - struct ahd_suspend_channel_state channel[2]; - uint8_t optionmode; - uint8_t dscommand0; - uint8_t dspcistatus; - /* hsmailbox */ - uint8_t crccontrol1; - uint8_t scbbaddr; - /* Host and sequencer SCB counts */ - uint8_t dff_thrsh; - uint8_t *scratch_ram; - uint8_t *btt; -}; - -typedef void (*ahd_bus_intr_t)(struct ahd_softc *); - -typedef enum { - AHD_MODE_DFF0, - AHD_MODE_DFF1, - AHD_MODE_CCHAN, - AHD_MODE_SCSI, - AHD_MODE_CFG, - AHD_MODE_UNKNOWN -} ahd_mode; - -#define AHD_MK_MSK(x) (0x01 << (x)) -#define AHD_MODE_DFF0_MSK AHD_MK_MSK(AHD_MODE_DFF0) -#define AHD_MODE_DFF1_MSK AHD_MK_MSK(AHD_MODE_DFF1) -#define AHD_MODE_CCHAN_MSK AHD_MK_MSK(AHD_MODE_CCHAN) -#define AHD_MODE_SCSI_MSK AHD_MK_MSK(AHD_MODE_SCSI) -#define AHD_MODE_CFG_MSK AHD_MK_MSK(AHD_MODE_CFG) -#define AHD_MODE_UNKNOWN_MSK AHD_MK_MSK(AHD_MODE_UNKNOWN) -#define AHD_MODE_ANY_MSK (~0) - -typedef uint8_t ahd_mode_state; - -typedef void ahd_callback_t (void *); - -struct ahd_softc { - bus_space_tag_t tags[2]; - bus_space_handle_t bshs[2]; -#ifndef __linux__ - bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ -#endif - struct scb_data scb_data; - - struct hardware_scb *next_queued_hscb; - - /* - * SCBs that have been sent to the controller - */ - LIST_HEAD(, scb) pending_scbs; - - /* - * Current register window mode information. - */ - ahd_mode dst_mode; - ahd_mode src_mode; - - /* - * Saved register window mode information - * used for restore on next unpause. - */ - ahd_mode saved_dst_mode; - ahd_mode saved_src_mode; - - /* - * Platform specific data. - */ - struct ahd_platform_data *platform_data; - - /* - * Platform specific device information. - */ - ahd_dev_softc_t dev_softc; - - /* - * Bus specific device information. - */ - ahd_bus_intr_t bus_intr; - - /* - * Target mode related state kept on a per enabled lun basis. - * Targets that are not enabled will have null entries. - * As an initiator, we keep one target entry for our initiator - * ID to store our sync/wide transfer settings. - */ - struct ahd_tmode_tstate *enabled_targets[AHD_NUM_TARGETS]; - - /* - * The black hole device responsible for handling requests for - * disabled luns on enabled targets. - */ - struct ahd_tmode_lstate *black_hole; - - /* - * Device instance currently on the bus awaiting a continue TIO - * for a command that was not given the disconnect priveledge. - */ - struct ahd_tmode_lstate *pending_device; - - /* - * Timer handles for timer driven callbacks. - */ - ahd_timer_t reset_timer; - ahd_timer_t stat_timer; - - /* - * Statistics. - */ -#define AHD_STAT_UPDATE_US 250000 /* 250ms */ -#define AHD_STAT_BUCKETS 4 - u_int cmdcmplt_bucket; - uint32_t cmdcmplt_counts[AHD_STAT_BUCKETS]; - uint32_t cmdcmplt_total; - - /* - * Card characteristics - */ - ahd_chip chip; - ahd_feature features; - ahd_bug bugs; - ahd_flag flags; - struct seeprom_config *seep_config; - - /* Values to store in the SEQCTL register for pause and unpause */ - uint8_t unpause; - uint8_t pause; - - /* Command Queues */ - uint16_t qoutfifonext; - uint16_t qoutfifonext_valid_tag; - uint16_t qinfifonext; - uint16_t qinfifo[AHD_SCB_MAX]; - uint16_t *qoutfifo; - - /* Critical Section Data */ - struct cs *critical_sections; - u_int num_critical_sections; - - /* Buffer for handling packetized bitbucket. */ - uint8_t *overrun_buf; - - /* Links for chaining softcs */ - TAILQ_ENTRY(ahd_softc) links; - - /* Channel Names ('A', 'B', etc.) */ - char channel; - - /* Initiator Bus ID */ - uint8_t our_id; - - /* - * Target incoming command FIFO. - */ - struct target_cmd *targetcmds; - uint8_t tqinfifonext; - - /* - * Cached verson of the hs_mailbox so we can avoid - * pausing the sequencer during mailbox updates. - */ - uint8_t hs_mailbox; - - /* - * Incoming and outgoing message handling. - */ - uint8_t send_msg_perror; - ahd_msg_flags msg_flags; - ahd_msg_type msg_type; - uint8_t msgout_buf[12];/* Message we are sending */ - uint8_t msgin_buf[12];/* Message we are receiving */ - u_int msgout_len; /* Length of message to send */ - u_int msgout_index; /* Current index in msgout */ - u_int msgin_index; /* Current index in msgin */ - - /* - * Mapping information for data structures shared - * between the sequencer and kernel. - */ - bus_dma_tag_t parent_dmat; - bus_dma_tag_t shared_data_dmat; - bus_dmamap_t shared_data_dmamap; - bus_addr_t shared_data_busaddr; - - /* Information saved through suspend/resume cycles */ - struct ahd_suspend_state suspend_state; - - /* Number of enabled target mode device on this card */ - u_int enabled_luns; - - /* Initialization level of this data structure */ - u_int init_level; - - /* PCI cacheline size. */ - u_int pci_cachesize; - - /* IO Cell Parameters */ - uint8_t iocell_opts[AHD_NUM_PER_DEV_ANNEXCOLS]; - - u_int stack_size; - uint16_t *saved_stack; - - /* Per-Unit descriptive information */ - const char *description; - const char *bus_description; - char *name; - int unit; - - /* Selection Timer settings */ - int seltime; - - /* - * Interrupt coalessing settings. - */ -#define AHD_INT_COALESSING_TIMER_DEFAULT 250 /*us*/ -#define AHD_INT_COALESSING_MAXCMDS_DEFAULT 10 -#define AHD_INT_COALESSING_MAXCMDS_MAX 127 -#define AHD_INT_COALESSING_MINCMDS_DEFAULT 5 -#define AHD_INT_COALESSING_MINCMDS_MAX 127 -#define AHD_INT_COALESSING_THRESHOLD_DEFAULT 2000 -#define AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT 1000 - u_int int_coalessing_timer; - u_int int_coalessing_maxcmds; - u_int int_coalessing_mincmds; - u_int int_coalessing_threshold; - u_int int_coalessing_stop_threshold; - - uint16_t user_discenable;/* Disconnection allowed */ - uint16_t user_tagenable;/* Tagged Queuing allowed */ -}; - -TAILQ_HEAD(ahd_softc_tailq, ahd_softc); -extern struct ahd_softc_tailq ahd_tailq; - -/*************************** IO Cell Configuration ****************************/ -#define AHD_PRECOMP_SLEW_INDEX \ - (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0) - -#define AHD_AMPLITUDE_INDEX \ - (AHD_ANNEXCOL_AMPLITUDE - AHD_ANNEXCOL_PER_DEV0) - -#define AHD_SET_SLEWRATE(ahd, new_slew) \ -do { \ - (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_SLEWRATE_MASK; \ - (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ - (((new_slew) << AHD_SLEWRATE_SHIFT) & AHD_SLEWRATE_MASK); \ -} while (0) - -#define AHD_SET_PRECOMP(ahd, new_pcomp) \ -do { \ - (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; \ - (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ - (((new_pcomp) << AHD_PRECOMP_SHIFT) & AHD_PRECOMP_MASK); \ -} while (0) - -#define AHD_SET_AMPLITUDE(ahd, new_amp) \ -do { \ - (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] &= ~AHD_AMPLITUDE_MASK; \ - (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] |= \ - (((new_amp) << AHD_AMPLITUDE_SHIFT) & AHD_AMPLITUDE_MASK); \ -} while (0) - -/************************ Active Device Information ***************************/ -typedef enum { - ROLE_UNKNOWN, - ROLE_INITIATOR, - ROLE_TARGET -} role_t; - -struct ahd_devinfo { - int our_scsiid; - int target_offset; - uint16_t target_mask; - u_int target; - u_int lun; - char channel; - role_t role; /* - * Only guaranteed to be correct if not - * in the busfree state. - */ -}; - -/****************************** PCI Structures ********************************/ -#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/ -#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */ -#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */ - -typedef int (ahd_device_setup_t)(struct ahd_softc *); - -struct ahd_pci_identity { - uint64_t full_id; - uint64_t id_mask; - char *name; - ahd_device_setup_t *setup; -}; -extern struct ahd_pci_identity ahd_pci_ident_table []; -extern const u_int ahd_num_pci_devs; - -/***************************** VL/EISA Declarations ***************************/ -struct aic7770_identity { - uint32_t full_id; - uint32_t id_mask; - char *name; - ahd_device_setup_t *setup; -}; -extern struct aic7770_identity aic7770_ident_table []; -extern const int ahd_num_aic7770_devs; - -#define AHD_EISA_SLOT_OFFSET 0xc00 -#define AHD_EISA_IOSIZE 0x100 - -/*************************** Function Declarations ****************************/ -/******************************************************************************/ -void ahd_reset_cmds_pending(struct ahd_softc *ahd); -u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); -void ahd_busy_tcl(struct ahd_softc *ahd, - u_int tcl, u_int busyid); -static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl); -static __inline void -ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) -{ - ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); -} - -/***************************** PCI Front End *********************************/ -struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); -int ahd_pci_config(struct ahd_softc *, - struct ahd_pci_identity *); -int ahd_pci_test_register_access(struct ahd_softc *); - -/************************** SCB and SCB queue management **********************/ -int ahd_probe_scbs(struct ahd_softc *); -void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, - struct scb *scb); -int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, - int target, char channel, int lun, - u_int tag, role_t role); - -/****************************** Initialization ********************************/ -struct ahd_softc *ahd_alloc(void *platform_arg, char *name); -int ahd_softc_init(struct ahd_softc *); -void ahd_controller_info(struct ahd_softc *ahd, char *buf); -int ahd_init(struct ahd_softc *ahd); -int ahd_default_config(struct ahd_softc *ahd); -int ahd_parse_cfgdata(struct ahd_softc *ahd, - struct seeprom_config *sc); -void ahd_intr_enable(struct ahd_softc *ahd, int enable); -void ahd_update_coalessing_values(struct ahd_softc *ahd, - u_int timer, - u_int maxcmds, - u_int mincmds); -void ahd_enable_coalessing(struct ahd_softc *ahd, - int enable); -void ahd_pause_and_flushwork(struct ahd_softc *ahd); -int ahd_suspend(struct ahd_softc *ahd); -int ahd_resume(struct ahd_softc *ahd); -void ahd_softc_insert(struct ahd_softc *); -struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd); -void ahd_set_unit(struct ahd_softc *, int); -void ahd_set_name(struct ahd_softc *, char *); -struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); -void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); -void ahd_alloc_scbs(struct ahd_softc *ahd); -void ahd_free(struct ahd_softc *ahd); -int ahd_reset(struct ahd_softc *ahd); -void ahd_shutdown(void *arg); -int ahd_write_flexport(struct ahd_softc *ahd, - u_int addr, u_int value); -int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, - uint8_t *value); -int ahd_wait_flexport(struct ahd_softc *ahd); - -/*************************** Interrupt Services *******************************/ -void ahd_pci_intr(struct ahd_softc *ahd); -void ahd_clear_intstat(struct ahd_softc *ahd); -void ahd_flush_qoutfifo(struct ahd_softc *ahd); -void ahd_run_qoutfifo(struct ahd_softc *ahd); -#ifdef AHD_TARGET_MODE -void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); -#endif -void ahd_handle_hwerrint(struct ahd_softc *ahd); -void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); -void ahd_handle_scsiint(struct ahd_softc *ahd, - u_int intstat); -void ahd_clear_critical_section(struct ahd_softc *ahd); - -/***************************** Error Recovery *********************************/ -typedef enum { - SEARCH_COMPLETE, - SEARCH_COUNT, - SEARCH_REMOVE, - SEARCH_PRINT -} ahd_search_action; -int ahd_search_qinfifo(struct ahd_softc *ahd, int target, - char channel, int lun, u_int tag, - role_t role, uint32_t status, - ahd_search_action action); -int ahd_search_disc_list(struct ahd_softc *ahd, int target, - char channel, int lun, u_int tag, - int stop_on_first, int remove, - int save_state); -void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb); -int ahd_reset_channel(struct ahd_softc *ahd, char channel, - int initiate_reset); -int ahd_abort_scbs(struct ahd_softc *ahd, int target, - char channel, int lun, u_int tag, - role_t role, uint32_t status); -void ahd_restart(struct ahd_softc *ahd); -void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo); -void ahd_handle_scb_status(struct ahd_softc *ahd, - struct scb *scb); -void ahd_handle_scsi_status(struct ahd_softc *ahd, - struct scb *scb); -void ahd_calc_residual(struct ahd_softc *ahd, - struct scb *scb); -/*************************** Utility Functions ********************************/ -struct ahd_phase_table_entry* - ahd_lookup_phase_entry(int phase); -void ahd_compile_devinfo(struct ahd_devinfo *devinfo, - u_int our_id, u_int target, - u_int lun, char channel, - role_t role); -/************************** Transfer Negotiation ******************************/ -void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, - u_int *ppr_options, u_int maxsync); -void ahd_validate_offset(struct ahd_softc *ahd, - struct ahd_initiator_tinfo *tinfo, - u_int period, u_int *offset, - int wide, role_t role); -void ahd_validate_width(struct ahd_softc *ahd, - struct ahd_initiator_tinfo *tinfo, - u_int *bus_width, - role_t role); -/* - * Negotiation types. These are used to qualify if we should renegotiate - * even if our goal and current transport parameters are identical. - */ -typedef enum { - AHD_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */ - AHD_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */ - AHD_NEG_ALWAYS /* Renegotiat even if goal is async. */ -} ahd_neg_type; -int ahd_update_neg_request(struct ahd_softc*, - struct ahd_devinfo*, - struct ahd_tmode_tstate*, - struct ahd_initiator_tinfo*, - ahd_neg_type); -void ahd_set_width(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - u_int width, u_int type, int paused); -void ahd_set_syncrate(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - u_int period, u_int offset, - u_int ppr_options, - u_int type, int paused); -typedef enum { - AHD_QUEUE_NONE, - AHD_QUEUE_BASIC, - AHD_QUEUE_TAGGED -} ahd_queue_alg; - -void ahd_set_tags(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - ahd_queue_alg alg); - -/**************************** Target Mode *************************************/ -#ifdef AHD_TARGET_MODE -void ahd_send_lstate_events(struct ahd_softc *, - struct ahd_tmode_lstate *); -void ahd_handle_en_lun(struct ahd_softc *ahd, - struct cam_sim *sim, union ccb *ccb); -cam_status ahd_find_tmode_devs(struct ahd_softc *ahd, - struct cam_sim *sim, union ccb *ccb, - struct ahd_tmode_tstate **tstate, - struct ahd_tmode_lstate **lstate, - int notfound_failure); -#ifndef AHD_TMODE_ENABLE -#define AHD_TMODE_ENABLE 0 -#endif -#endif -/******************************* Debug ***************************************/ -#ifdef AHD_DEBUG -extern uint32_t ahd_debug; -#define AHD_SHOW_MISC 0x00001 -#define AHD_SHOW_SENSE 0x00002 -#define AHD_SHOW_RECOVERY 0x00004 -#define AHD_DUMP_SEEPROM 0x00008 -#define AHD_SHOW_TERMCTL 0x00010 -#define AHD_SHOW_MEMORY 0x00020 -#define AHD_SHOW_MESSAGES 0x00040 -#define AHD_SHOW_MODEPTR 0x00080 -#define AHD_SHOW_SELTO 0x00100 -#define AHD_SHOW_FIFOS 0x00200 -#define AHD_SHOW_QFULL 0x00400 -#define AHD_SHOW_DV 0x00800 -#define AHD_SHOW_MASKED_ERRORS 0x01000 -#define AHD_SHOW_QUEUE 0x02000 -#define AHD_SHOW_TQIN 0x04000 -#define AHD_SHOW_SG 0x08000 -#define AHD_SHOW_INT_COALESSING 0x10000 -#define AHD_DEBUG_SEQUENCER 0x20000 -#endif -void ahd_print_scb(struct scb *scb); -void ahd_print_devinfo(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -void ahd_dump_sglist(struct scb *scb); -void ahd_dump_all_cards_state(void); -void ahd_dump_card_state(struct ahd_softc *ahd); -int ahd_print_register(ahd_reg_parse_entry_t *table, - u_int num_entries, - const char *name, - u_int address, - u_int value, - u_int *cur_column, - u_int wrap_point); -void ahd_dump_scbs(struct ahd_softc *ahd); -#endif /* _AIC79XX_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx.reg linux-2.4.22/drivers/scsi/aic79xx/aic79xx.reg --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx.reg 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx.reg 1969-12-31 16:00:00.000000000 -0800 @@ -1,3950 +0,0 @@ -/* - * Aic79xx register and scratch ram definitions. - * - * Copyright (c) 1994-2001 Justin T. Gibbs. - * Copyright (c) 2000-2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD$ - */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $" - -/* - * This file is processed by the aic7xxx_asm utility for use in assembling - * firmware for the aic79xx family of SCSI host adapters as well as to generate - * a C header file for use in the kernel portion of the Aic79xx driver. - */ - -/* Register window Modes */ -#define M_DFF0 0 -#define M_DFF1 1 -#define M_CCHAN 2 -#define M_SCSI 3 -#define M_CFG 4 -#define M_DST_SHIFT 4 - -#define MK_MODE(src, dst) ((src) | ((dst) << M_DST_SHIFT)) -#define SET_MODE(src, dst) \ - SET_SRC_MODE src; \ - SET_DST_MODE dst; \ - if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ - mvi MK_MODE(src, dst) call set_mode_work_around; \ - } else { \ - mvi MODE_PTR, MK_MODE(src, dst); \ - } - -#define TOGGLE_DFF_MODE \ - if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ - call toggle_dff_mode_work_around; \ - } else { \ - xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); \ - } - -#define RESTORE_MODE(mode) \ - if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ - mov mode call set_mode_work_around; \ - } else { \ - mov MODE_PTR, mode; \ - } - -#define SET_SEQINTCODE(code) \ - if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { \ - mvi code call set_seqint_work_around; \ - } else { \ - mvi SEQINTCODE, code; \ - } - -/* - * Mode Pointer - * Controls which of the 5, 512byte, address spaces should be used - * as the source and destination of any register accesses in our - * register window. - */ -register MODE_PTR { - address 0x000 - access_mode RW - field DST_MODE 0x70 - field SRC_MODE 0x07 - mode_pointer -} - -const SRC_MODE_SHIFT 0 -const DST_MODE_SHIFT 4 - -/* - * Host Interrupt Status - */ -register INTSTAT { - address 0x001 - access_mode RW - field HWERRINT 0x80 - field BRKADRINT 0x40 - field SWTMINT 0x20 - field PCIINT 0x10 - field SCSIINT 0x08 - field SEQINT 0x04 - field CMDCMPLT 0x02 - field SPLTINT 0x01 - mask INT_PEND 0xFF -} - -/* - * Sequencer Interrupt Code - */ -register SEQINTCODE { - address 0x002 - access_mode RW - field { - NO_SEQINT, /* No seqint pending. */ - BAD_PHASE, /* unknown scsi bus phase */ - SEND_REJECT, /* sending a message reject */ - PROTO_VIOLATION, /* Protocol Violation */ - NO_MATCH, /* no cmd match for reconnect */ - IGN_WIDE_RES, /* Complex IGN Wide Res Msg */ - PDATA_REINIT, /* - * Returned to data phase - * that requires data - * transfer pointers to be - * recalculated from the - * transfer residual. - */ - HOST_MSG_LOOP, /* - * The bus is ready for the - * host to perform another - * message transaction. This - * mechanism is used for things - * like sync/wide negotiation - * that require a kernel based - * message state engine. - */ - BAD_STATUS, /* Bad status from target */ - DATA_OVERRUN, /* - * Target attempted to write - * beyond the bounds of its - * command. - */ - MKMSG_FAILED, /* - * Target completed command - * without honoring our ATN - * request to issue a message. - */ - MISSED_BUSFREE, /* - * The sequencer never saw - * the bus go free after - * either a command complete - * or disconnect message. - */ - DUMP_CARD_STATE, - ILLEGAL_PHASE, - INVALID_SEQINT, - CFG4ISTAT_INTR, - STATUS_OVERRUN, - CFG4OVERRUN, - ENTERING_NONPACK, - TASKMGMT_FUNC_COMPLETE, /* - * Task management function - * request completed with - * an expected busfree. - */ - TASKMGMT_CMD_CMPLT_OKAY, /* - * A command with a non-zero - * task management function - * has completed via the normal - * command completion method - * for commands with a zero - * task management function. - * This happens when an attempt - * to abort a command loses - * the race for the command to - * complete normally. - */ - TRACEPOINT0, - TRACEPOINT1, - TRACEPOINT2, - TRACEPOINT3, - SAW_HWERR - } -} - -/* - * Clear Host Interrupt - */ -register CLRINT { - address 0x003 - access_mode WO - field CLRHWERRINT 0x80 /* Rev B or greater */ - field CLRBRKADRINT 0x40 - field CLRSWTMINT 0x20 - field CLRPCIINT 0x10 - field CLRSCSIINT 0x08 - field CLRSEQINT 0x04 - field CLRCMDINT 0x02 - field CLRSPLTINT 0x01 -} - -/* - * Error Register - */ -register ERROR { - address 0x004 - access_mode RO - field CIOPARERR 0x80 - field CIOACCESFAIL 0x40 /* Rev B or greater */ - field MPARERR 0x20 - field DPARERR 0x10 - field SQPARERR 0x08 - field ILLOPCODE 0x04 - field DSCTMOUT 0x02 -} - -/* - * Clear Error - */ -register CLRERR { - address 0x004 - access_mode WO - field CLRCIOPARERR 0x80 - field CLRCIOACCESFAIL 0x40 /* Rev B or greater */ - field CLRMPARERR 0x20 - field CLRDPARERR 0x10 - field CLRSQPARERR 0x08 - field CLRILLOPCODE 0x04 - field CLRDSCTMOUT 0x02 -} - -/* - * Host Control Register - * Overall host control of the device. - */ -register HCNTRL { - address 0x005 - access_mode RW - field SEQ_RESET 0x80 /* Rev B or greater */ - field POWRDN 0x40 - field SWINT 0x10 - field SWTIMER_START_B 0x08 /* Rev B or greater */ - field PAUSE 0x04 - field INTEN 0x02 - field CHIPRST 0x01 - field CHIPRSTACK 0x01 -} - -/* - * Host New SCB Queue Offset - */ -register HNSCB_QOFF { - address 0x006 - access_mode RW - size 2 -} - -/* - * Host Empty SCB Queue Offset - */ -register HESCB_QOFF { - address 0x008 - access_mode RW -} - -/* - * Host Mailbox - */ -register HS_MAILBOX { - address 0x00B - access_mode RW - mask HOST_TQINPOS 0x80 /* Boundary at either 0 or 128 */ - mask ENINT_COALESS 0x40 /* Perform interrupt coalessing */ -} - -/* - * Sequencer Interupt Status - */ -register SEQINTSTAT { - address 0x00C - access_mode RO - field SEQ_SWTMRTO 0x10 - field SEQ_SEQINT 0x08 - field SEQ_SCSIINT 0x04 - field SEQ_PCIINT 0x02 - field SEQ_SPLTINT 0x01 -} - -/* - * Clear SEQ Interrupt - */ -register CLRSEQINTSTAT { - address 0x00C - access_mode WO - field CLRSEQ_SWTMRTO 0x10 - field CLRSEQ_SEQINT 0x08 - field CLRSEQ_SCSIINT 0x04 - field CLRSEQ_PCIINT 0x02 - field CLRSEQ_SPLTINT 0x01 -} - -/* - * Software Timer - */ -register SWTIMER { - address 0x00E - access_mode RW - size 2 -} - -/* - * SEQ New SCB Queue Offset - */ -register SNSCB_QOFF { - address 0x010 - access_mode RW - size 2 - modes M_CCHAN -} - -/* - * SEQ Empty SCB Queue Offset - */ -register SESCB_QOFF { - address 0x012 - access_mode RW - modes M_CCHAN -} - -/* - * SEQ Done SCB Queue Offset - */ -register SDSCB_QOFF { - address 0x014 - access_mode RW - modes M_CCHAN - size 2 -} - -/* - * Queue Offset Control & Status - */ -register QOFF_CTLSTA { - address 0x016 - access_mode RW - modes M_CCHAN - field EMPTY_SCB_AVAIL 0x80 - field NEW_SCB_AVAIL 0x40 - field SDSCB_ROLLOVR 0x20 - field HS_MAILBOX_ACT 0x10 - field SCB_QSIZE 0x0F { - SCB_QSIZE_4, - SCB_QSIZE_8, - SCB_QSIZE_16, - SCB_QSIZE_32, - SCB_QSIZE_64, - SCB_QSIZE_128, - SCB_QSIZE_256, - SCB_QSIZE_512, - SCB_QSIZE_1024, - SCB_QSIZE_2048, - SCB_QSIZE_4096, - SCB_QSIZE_8192, - SCB_QSIZE_16384 - } -} - -/* - * Interrupt Control - */ -register INTCTL { - address 0x018 - access_mode RW - field SWTMINTMASK 0x80 - field SWTMINTEN 0x40 - field SWTIMER_START 0x20 - field AUTOCLRCMDINT 0x10 - field PCIINTEN 0x08 - field SCSIINTEN 0x04 - field SEQINTEN 0x02 - field SPLTINTEN 0x01 -} - -/* - * Data FIFO Control - */ -register DFCNTRL { - address 0x019 - access_mode RW - modes M_DFF0, M_DFF1 - field PRELOADEN 0x80 - field SCSIENWRDIS 0x40 /* Rev B only. */ - field SCSIEN 0x20 - field SCSIENACK 0x20 - field HDMAEN 0x08 - field HDMAENACK 0x08 - field DIRECTION 0x04 - field DIRECTIONACK 0x04 - field FIFOFLUSH 0x02 - field FIFOFLUSHACK 0x02 - field DIRECTIONEN 0x01 -} - -/* - * Device Space Command 0 - */ -register DSCOMMAND0 { - address 0x019 - access_mode RW - modes M_CFG - field CACHETHEN 0x80 /* Cache Threshold enable */ - field DPARCKEN 0x40 /* Data Parity Check Enable */ - field MPARCKEN 0x20 /* Memory Parity Check Enable */ - field EXTREQLCK 0x10 /* External Request Lock */ - field DISABLE_TWATE 0x02 /* Rev B or greater */ - field CIOPARCKEN 0x01 /* Internal bus parity error enable */ -} - -/* - * Data FIFO Status - */ -register DFSTATUS { - address 0x01A - access_mode RO - modes M_DFF0, M_DFF1 - field PRELOAD_AVAIL 0x80 - field PKT_PRELOAD_AVAIL 0x40 - field MREQPEND 0x10 - field HDONE 0x08 - field DFTHRESH 0x04 - field FIFOFULL 0x02 - field FIFOEMP 0x01 -} - -/* - * S/G Cache Pointer - */ -register SG_CACHE_PRE { - address 0x01B - access_mode WO - modes M_DFF0, M_DFF1 - field SG_ADDR_MASK 0xf8 - field ODD_SEG 0x04 - field LAST_SEG 0x02 -} - -register SG_CACHE_SHADOW { - address 0x01B - access_mode RO - modes M_DFF0, M_DFF1 - field SG_ADDR_MASK 0xf8 - field ODD_SEG 0x04 - field LAST_SEG 0x02 - field LAST_SEG_DONE 0x01 -} - -/* - * Arbiter Control - */ -register ARBCTL { - address 0x01B - access_mode RW - modes M_CFG - field RESET_HARB 0x80 - field RETRY_SWEN 0x08 - field USE_TIME 0x07 -} - -/* - * Data Channel Host Address - */ -register HADDR { - address 0x070 - access_mode RW - size 8 - modes M_DFF0, M_DFF1 -} - -/* - * Host Overlay DMA Address - */ -register HODMAADR { - address 0x070 - access_mode RW - size 8 - modes M_SCSI -} - -/* - * PCI PLL Delay. - */ -register PLLDELAY { - address 0x070 - access_mode RW - size 1 - modes M_CFG - field SPLIT_DROP_REQ 0x80 -} - -/* - * Data Channel Host Count - */ -register HCNT { - address 0x078 - access_mode RW - size 3 - modes M_DFF0, M_DFF1 -} - -/* - * Host Overlay DMA Count - */ -register HODMACNT { - address 0x078 - access_mode RW - size 2 - modes M_SCSI -} - -/* - * Host Overlay DMA Enable - */ -register HODMAEN { - address 0x07A - access_mode RW - modes M_SCSI -} - -/* - * Scatter/Gather Host Address - */ -register SGHADDR { - address 0x07C - access_mode RW - size 8 - modes M_DFF0, M_DFF1 -} - -/* - * SCB Host Address - */ -register SCBHADDR { - address 0x07C - access_mode RW - size 8 - modes M_CCHAN -} - -/* - * Scatter/Gather Host Count - */ -register SGHCNT { - address 0x084 - access_mode RW - modes M_DFF0, M_DFF1 -} - -/* - * SCB Host Count - */ -register SCBHCNT { - address 0x084 - access_mode RW - modes M_CCHAN -} - -/* - * Data FIFO Threshold - */ -register DFF_THRSH { - address 0x088 - access_mode RW - modes M_CFG - field WR_DFTHRSH 0x70 { - WR_DFTHRSH_MIN, - WR_DFTHRSH_25, - WR_DFTHRSH_50, - WR_DFTHRSH_63, - WR_DFTHRSH_75, - WR_DFTHRSH_85, - WR_DFTHRSH_90, - WR_DFTHRSH_MAX - } - field RD_DFTHRSH 0x07 { - RD_DFTHRSH_MIN, - RD_DFTHRSH_25, - RD_DFTHRSH_50, - RD_DFTHRSH_63, - RD_DFTHRSH_75, - RD_DFTHRSH_85, - RD_DFTHRSH_90, - RD_DFTHRSH_MAX - } -} - -/* - * ROM Address - */ -register ROMADDR { - address 0x08A - access_mode RW - size 3 -} - -/* - * ROM Control - */ -register ROMCNTRL { - address 0x08D - access_mode RW - field ROMOP 0xE0 - field ROMSPD 0x18 - field REPEAT 0x02 - field RDY 0x01 -} - -/* - * ROM Data - */ -register ROMDATA { - address 0x08E - access_mode RW -} - -/* - * Data Channel Receive Message 0 - */ -register DCHRXMSG0 { - address 0x090 - access_mode RO - modes M_DFF0, M_DFF1 - field CDNUM 0xF8 - field CFNUM 0x07 -} - -/* - * CMC Recieve Message 0 - */ -register CMCRXMSG0 { - address 0x090 - access_mode RO - modes M_CCHAN - field CDNUM 0xF8 - field CFNUM 0x07 -} - -/* - * Overlay Recieve Message 0 - */ -register OVLYRXMSG0 { - address 0x090 - access_mode RO - modes M_SCSI - field CDNUM 0xF8 - field CFNUM 0x07 -} - -/* - * Relaxed Order Enable - */ -register ROENABLE { - address 0x090 - access_mode RW - modes M_CFG - field MSIROEN 0x20 - field OVLYROEN 0x10 - field CMCROEN 0x08 - field SGROEN 0x04 - field DCH1ROEN 0x02 - field DCH0ROEN 0x01 -} - -/* - * Data Channel Receive Message 1 - */ -register DCHRXMSG1 { - address 0x091 - access_mode RO - modes M_DFF0, M_DFF1 - field CBNUM 0xFF -} - -/* - * CMC Recieve Message 1 - */ -register CMCRXMSG1 { - address 0x091 - access_mode RO - modes M_CCHAN - field CBNUM 0xFF -} - -/* - * Overlay Recieve Message 1 - */ -register OVLYRXMSG1 { - address 0x091 - access_mode RO - modes M_SCSI - field CBNUM 0xFF -} - -/* - * No Snoop Enable - */ -register NSENABLE { - address 0x091 - access_mode RW - modes M_CFG - field MSINSEN 0x20 - field OVLYNSEN 0x10 - field CMCNSEN 0x08 - field SGNSEN 0x04 - field DCH1NSEN 0x02 - field DCH0NSEN 0x01 -} - -/* - * Data Channel Receive Message 2 - */ -register DCHRXMSG2 { - address 0x092 - access_mode RO - modes M_DFF0, M_DFF1 - field MINDEX 0xFF -} - -/* - * CMC Recieve Message 2 - */ -register CMCRXMSG2 { - address 0x092 - access_mode RO - modes M_CCHAN - field MINDEX 0xFF -} - -/* - * Overlay Recieve Message 2 - */ -register OVLYRXMSG2 { - address 0x092 - access_mode RO - modes M_SCSI - field MINDEX 0xFF -} - -/* - * Outstanding Split Transactions - */ -register OST { - address 0x092 - access_mode RW - modes M_CFG -} - -/* - * Data Channel Receive Message 3 - */ -register DCHRXMSG3 { - address 0x093 - access_mode RO - modes M_DFF0, M_DFF1 - field MCLASS 0x0F -} - -/* - * CMC Recieve Message 3 - */ -register CMCRXMSG3 { - address 0x093 - access_mode RO - modes M_CCHAN - field MCLASS 0x0F -} - -/* - * Overlay Recieve Message 3 - */ -register OVLYRXMSG3 { - address 0x093 - access_mode RO - modes M_SCSI - field MCLASS 0x0F -} - -/* - * PCI-X Control - */ -register PCIXCTL { - address 0x093 - access_mode RW - modes M_CFG - field SERRPULSE 0x80 - field UNEXPSCIEN 0x20 - field SPLTSMADIS 0x10 - field SPLTSTADIS 0x08 - field SRSPDPEEN 0x04 - field TSCSERREN 0x02 - field CMPABCDIS 0x01 -} - -/* - * CMC Sequencer Byte Count - */ -register CMCSEQBCNT { - address 0x094 - access_mode RO - modes M_CCHAN -} - -/* - * Overlay Sequencer Byte Count - */ -register OVLYSEQBCNT { - address 0x094 - access_mode RO - modes M_SCSI -} - -/* - * Data Channel Sequencer Byte Count - */ -register DCHSEQBCNT { - address 0x094 - access_mode RO - size 2 - modes M_DFF0, M_DFF1 -} - -/* - * Data Channel Split Status 0 - */ -register DCHSPLTSTAT0 { - address 0x096 - access_mode RW - modes M_DFF0, M_DFF1 - field STAETERM 0x80 - field SCBCERR 0x40 - field SCADERR 0x20 - field SCDATBUCKET 0x10 - field CNTNOTCMPLT 0x08 - field RXOVRUN 0x04 - field RXSCEMSG 0x02 - field RXSPLTRSP 0x01 -} - -/* - * CMC Split Status 0 - */ -register CMCSPLTSTAT0 { - address 0x096 - access_mode RW - modes M_CCHAN - field STAETERM 0x80 - field SCBCERR 0x40 - field SCADERR 0x20 - field SCDATBUCKET 0x10 - field CNTNOTCMPLT 0x08 - field RXOVRUN 0x04 - field RXSCEMSG 0x02 - field RXSPLTRSP 0x01 -} - -/* - * Overlay Split Status 0 - */ -register OVLYSPLTSTAT0 { - address 0x096 - access_mode RW - modes M_SCSI - field STAETERM 0x80 - field SCBCERR 0x40 - field SCADERR 0x20 - field SCDATBUCKET 0x10 - field CNTNOTCMPLT 0x08 - field RXOVRUN 0x04 - field RXSCEMSG 0x02 - field RXSPLTRSP 0x01 -} - -/* - * Data Channel Split Status 1 - */ -register DCHSPLTSTAT1 { - address 0x097 - access_mode RW - modes M_DFF0, M_DFF1 - field RXDATABUCKET 0x01 -} - -/* - * CMC Split Status 1 - */ -register CMCSPLTSTAT1 { - address 0x097 - access_mode RW - modes M_CCHAN - field RXDATABUCKET 0x01 -} - -/* - * Overlay Split Status 1 - */ -register OVLYSPLTSTAT1 { - address 0x097 - access_mode RW - modes M_SCSI - field RXDATABUCKET 0x01 -} - -/* - * S/G Receive Message 0 - */ -register SGRXMSG0 { - address 0x098 - access_mode RO - modes M_DFF0, M_DFF1 - field CDNUM 0xF8 - field CFNUM 0x07 -} - -/* - * S/G Receive Message 1 - */ -register SGRXMSG1 { - address 0x099 - access_mode RO - modes M_DFF0, M_DFF1 - field CBNUM 0xFF -} - -/* - * S/G Receive Message 2 - */ -register SGRXMSG2 { - address 0x09A - access_mode RO - modes M_DFF0, M_DFF1 - field MINDEX 0xFF -} - -/* - * S/G Receive Message 3 - */ -register SGRXMSG3 { - address 0x09B - access_mode RO - modes M_DFF0, M_DFF1 - field MCLASS 0x0F -} - -/* - * Slave Split Out Address 0 - */ -register SLVSPLTOUTADR0 { - address 0x098 - access_mode RO - modes M_SCSI - field LOWER_ADDR 0x7F -} - -/* - * Slave Split Out Address 1 - */ -register SLVSPLTOUTADR1 { - address 0x099 - access_mode RO - modes M_SCSI - field REQ_DNUM 0xF8 - field REQ_FNUM 0x07 -} - -/* - * Slave Split Out Address 2 - */ -register SLVSPLTOUTADR2 { - address 0x09A - access_mode RO - modes M_SCSI - field REQ_BNUM 0xFF -} - -/* - * Slave Split Out Address 3 - */ -register SLVSPLTOUTADR3 { - address 0x09B - access_mode RO - modes M_SCSI - field RLXORD 020 - field TAG_NUM 0x1F -} - -/* - * SG Sequencer Byte Count - */ -register SGSEQBCNT { - address 0x09C - access_mode RO - modes M_DFF0, M_DFF1 -} - -/* - * Slave Split Out Attribute 0 - */ -register SLVSPLTOUTATTR0 { - address 0x09C - access_mode RO - modes M_SCSI - field LOWER_BCNT 0xFF -} - -/* - * Slave Split Out Attribute 1 - */ -register SLVSPLTOUTATTR1 { - address 0x09D - access_mode RO - modes M_SCSI - field CMPLT_DNUM 0xF8 - field CMPLT_FNUM 0x07 -} - -/* - * Slave Split Out Attribute 2 - */ -register SLVSPLTOUTATTR2 { - address 0x09E - access_mode RO - size 2 - modes M_SCSI - field CMPLT_BNUM 0xFF -} -/* - * S/G Split Status 0 - */ -register SGSPLTSTAT0 { - address 0x09E - access_mode RW - modes M_DFF0, M_DFF1 - field STAETERM 0x80 - field SCBCERR 0x40 - field SCADERR 0x20 - field SCDATBUCKET 0x10 - field CNTNOTCMPLT 0x08 - field RXOVRUN 0x04 - field RXSCEMSG 0x02 - field RXSPLTRSP 0x01 -} - -/* - * S/G Split Status 1 - */ -register SGSPLTSTAT1 { - address 0x09F - access_mode RW - modes M_DFF0, M_DFF1 - field RXDATABUCKET 0x01 -} - -/* - * Special Function - */ -register SFUNCT { - address 0x09f - access_mode RW - modes M_CFG - field TEST_GROUP 0xF0 - field TEST_NUM 0x0F -} - -/* - * Data FIFO 0 PCI Status - */ -register DF0PCISTAT { - address 0x0A0 - access_mode RW - modes M_CFG - field DPE 0x80 - field SSE 0x40 - field RMA 0x20 - field RTA 0x10 - field SCAAPERR 0x08 - field RDPERR 0x04 - field TWATERR 0x02 - field DPR 0x01 -} - -/* - * Data FIFO 1 PCI Status - */ -register DF1PCISTAT { - address 0x0A1 - access_mode RW - modes M_CFG - field DPE 0x80 - field SSE 0x40 - field RMA 0x20 - field RTA 0x10 - field SCAAPERR 0x08 - field RDPERR 0x04 - field TWATERR 0x02 - field DPR 0x01 -} - -/* - * S/G PCI Status - */ -register SGPCISTAT { - address 0x0A2 - access_mode RW - modes M_CFG - field DPE 0x80 - field SSE 0x40 - field RMA 0x20 - field RTA 0x10 - field SCAAPERR 0x08 - field RDPERR 0x04 - field DPR 0x01 -} - -/* - * CMC PCI Status - */ -register CMCPCISTAT { - address 0x0A3 - access_mode RW - modes M_CFG - field DPE 0x80 - field SSE 0x40 - field RMA 0x20 - field RTA 0x10 - field SCAAPERR 0x08 - field RDPERR 0x04 - field TWATERR 0x02 - field DPR 0x01 -} - -/* - * Overlay PCI Status - */ -register OVLYPCISTAT { - address 0x0A4 - access_mode RW - modes M_CFG - field DPE 0x80 - field SSE 0x40 - field RMA 0x20 - field RTA 0x10 - field SCAAPERR 0x08 - field RDPERR 0x04 - field DPR 0x01 -} - -/* - * PCI Status for MSI Master DMA Transfer - */ -register MSIPCISTAT { - address 0x0A6 - access_mode RW - modes M_CFG - field SSE 0x40 - field RMA 0x20 - field RTA 0x10 - field CLRPENDMSI 0x08 - field TWATERR 0x02 - field DPR 0x01 -} - -/* - * PCI Status for Target - */ -register TARGPCISTAT { - address 0x0A7 - access_mode RW - modes M_CFG - field DPE 0x80 - field SSE 0x40 - field STA 0x08 - field TWATERR 0x02 -} - -/* - * LQ Packet In - * The last LQ Packet recieved - */ -register LQIN { - address 0x020 - access_mode RW - size 20 - modes M_DFF0, M_DFF1, M_SCSI -} - -/* - * SCB Type Pointer - * SCB offset for Target Mode SCB type information - */ -register TYPEPTR { - address 0x020 - access_mode RW - modes M_CFG -} - -/* - * Queue Tag Pointer - * SCB offset to the Two Byte tag identifier used for target mode. - */ -register TAGPTR { - address 0x021 - access_mode RW - modes M_CFG -} - -/* - * Logical Unit Number Pointer - * SCB offset to the LSB (little endian) of the lun field. - */ -register LUNPTR { - address 0x022 - access_mode RW - modes M_CFG -} - -/* - * Data Length Pointer - * SCB offset for the 4 byte data length field in target mode. - */ -register DATALENPTR { - address 0x023 - access_mode RW - modes M_CFG -} - -/* - * Status Length Pointer - * SCB offset to the two byte status field in target SCBs. - */ -register STATLENPTR { - address 0x024 - access_mode RW - modes M_CFG -} - -/* - * Command Length Pointer - * Scb offset for the CDB length field in initiator SCBs. - */ -register CMDLENPTR { - address 0x025 - access_mode RW - modes M_CFG -} - -/* - * Task Attribute Pointer - * Scb offset for the byte field specifying the attribute byte - * to be used in command packets. - */ -register ATTRPTR { - address 0x026 - access_mode RW - modes M_CFG -} - -/* - * Task Management Flags Pointer - * Scb offset for the byte field specifying the attribute flags - * byte to be used in command packets. - */ -register FLAGPTR { - address 0x027 - access_mode RW - modes M_CFG -} - -/* - * Command Pointer - * Scb offset for the first byte in the CDB for initiator SCBs. - */ -register CMDPTR { - address 0x028 - access_mode RW - modes M_CFG -} - -/* - * Queue Next Pointer - * Scb offset for the 2 byte "next scb link". - */ -register QNEXTPTR { - address 0x029 - access_mode RW - modes M_CFG -} - -/* - * SCSI ID Pointer - * Scb offset to the value to place in the SCSIID register - * during target mode connections. - */ -register IDPTR { - address 0x02A - access_mode RW - modes M_CFG -} - -/* - * Command Aborted Byte Pointer - * Offset to the SCB flags field that includes the - * "SCB aborted" status bit. - */ -register ABRTBYTEPTR { - address 0x02B - access_mode RW - modes M_CFG -} - -/* - * Command Aborted Bit Pointer - * Bit offset in the SCB flags field for "SCB aborted" status. - */ -register ABRTBITPTR { - address 0x02C - access_mode RW - modes M_CFG -} - -/* - * Rev B or greater. - */ -register MAXCMDBYTES { - address 0x02D - access_mode RW - modes M_CFG -} - -/* - * Rev B or greater. - */ -register MAXCMD2RCV { - address 0x02E - access_mode RW - modes M_CFG -} - -/* - * Rev B or greater. - */ -register SHORTTHRESH { - address 0x02F - access_mode RW - modes M_CFG -} - -/* - * Logical Unit Number Length - * The length, in bytes, of the SCB lun field. - */ -register LUNLEN { - address 0x030 - access_mode RW - modes M_CFG -} - -/* - * CDB Limit - * The size, in bytes, of the embedded CDB field in initator SCBs. - */ -register CDBLIMIT { - address 0x031 - access_mode RW - modes M_CFG -} - -/* - * Maximum Commands - * The maximum number of commands to issue during a - * single packetized connection. - */ -register MAXCMD { - address 0x032 - access_mode RW - modes M_CFG -} - -/* - * Maximum Command Counter - * The number of commands already sent during this connection - */ -register MAXCMDCNT { - address 0x033 - access_mode RW - modes M_CFG -} - -/* - * LQ Packet Reserved Bytes - * The bytes to be sent in the currently reserved fileds - * of all LQ packets. - */ -register LQRSVD01 { - address 0x034 - access_mode RW - modes M_SCSI -} -register LQRSVD16 { - address 0x035 - access_mode RW - modes M_SCSI -} -register LQRSVD17 { - address 0x036 - access_mode RW - modes M_SCSI -} - -/* - * Command Reserved 0 - * The byte to be sent for the reserved byte 0 of - * outgoing command packets. - */ -register CMDRSVD0 { - address 0x037 - access_mode RW - modes M_CFG -} - -/* - * LQ Manager Control 0 - */ -register LQCTL0 { - address 0x038 - access_mode RW - modes M_CFG - field LQITARGCLT 0xC0 - field LQIINITGCLT 0x30 - field LQ0TARGCLT 0x0C - field LQ0INITGCLT 0x03 -} - -/* - * LQ Manager Control 1 - */ -register LQCTL1 { - address 0x038 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field PCI2PCI 0x04 - field SINGLECMD 0x02 - field ABORTPENDING 0x01 -} - -/* - * LQ Manager Control 2 - */ -register LQCTL2 { - address 0x039 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field LQIRETRY 0x80 - field LQICONTINUE 0x40 - field LQITOIDLE 0x20 - field LQIPAUSE 0x10 - field LQORETRY 0x08 - field LQOCONTINUE 0x04 - field LQOTOIDLE 0x02 - field LQOPAUSE 0x01 -} - -/* - * SCSI RAM BIST0 - */ -register SCSBIST0 { - address 0x039 - access_mode RW - modes M_CFG - field GSBISTERR 0x40 - field GSBISTDONE 0x20 - field GSBISTRUN 0x10 - field OSBISTERR 0x04 - field OSBISTDONE 0x02 - field OSBISTRUN 0x01 -} - -/* - * SCSI Sequence Control0 - */ -register SCSISEQ0 { - address 0x03A - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field TEMODEO 0x80 - field ENSELO 0x40 - field ENARBO 0x20 - field FORCEBUSFREE 0x10 - field SCSIRSTO 0x01 -} - -/* - * SCSI RAM BIST 1 - */ -register SCSBIST1 { - address 0x03A - access_mode RW - modes M_CFG - field NTBISTERR 0x04 - field NTBISTDONE 0x02 - field NTBISTRUN 0x01 -} - -/* - * SCSI Sequence Control 1 - */ -register SCSISEQ1 { - address 0x03B - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field MANUALCTL 0x40 - field ENSELI 0x20 - field ENRSELI 0x10 - field MANUALP 0x0C - field ENAUTOATNP 0x02 - field ALTSTIM 0x01 -} - -/* - * SCSI Transfer Control 0 - */ -register SXFRCTL0 { - address 0x03C - access_mode RW - modes M_SCSI - field DFON 0x80 - field DFPEXP 0x40 - field BIOSCANCELEN 0x10 - field SPIOEN 0x08 -} - -/* - * SCSI Transfer Control 1 - */ -register SXFRCTL1 { - address 0x03D - access_mode RW - modes M_SCSI - field BITBUCKET 0x80 - field ENSACHK 0x40 - field ENSPCHK 0x20 - field STIMESEL 0x18 - field ENSTIMER 0x04 - field ACTNEGEN 0x02 - field STPWEN 0x01 -} - -/* - * SCSI Transfer Control 2 - */ -register SXFRCTL2 { - address 0x03E - access_mode RW - modes M_SCSI - field AUTORSTDIS 0x10 - field CMDDMAEN 0x08 - field ASU 0x07 -} - -/* - * SCSI Bus Initiator IDs - * Bitmask of observed initiators on the bus. - */ -register BUSINITID { - address 0x03C - access_mode RW - modes M_CFG - size 2 -} - -/* - * Data Length Counters - * Packet byte counter. - */ -register DLCOUNT { - address 0x03C - access_mode RW - modes M_DFF0, M_DFF1 - size 3 -} - -/* - * Data FIFO Status - */ -register DFFSTAT { - address 0x03F - access_mode RW - modes M_SCSI - field FIFO1FREE 0x20 - field FIFO0FREE 0x10 - /* - * On the B, this enum only works - * in the read direction. For writes, - * you must use the B version of the - * CURRFIFO_0 definition which is defined - * as a constant outside of this register - * definition to avoid confusing the - * register pretty printing code. - */ - enum CURRFIFO 0x03 { - CURRFIFO_0, - CURRFIFO_1, - CURRFIFO_NONE 0x3 - } -} - -const B_CURRFIFO_0 0x2 - -/* - * SCSI Bus Target IDs - * Bitmask of observed targets on the bus. - */ -register BUSTARGID { - address 0x03E - access_mode RW - modes M_CFG - size 2 -} - -/* - * SCSI Control Signal Out - */ -register SCSISIGO { - address 0x040 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field CDO 0x80 - field IOO 0x40 - field MSGO 0x20 - field ATNO 0x10 - field SELO 0x08 - field BSYO 0x04 - field REQO 0x02 - field ACKO 0x01 -/* - * Possible phases to write into SCSISIG0 - */ - enum PHASE_MASK CDO|IOO|MSGO { - P_DATAOUT 0x0, - P_DATAIN IOO, - P_DATAOUT_DT P_DATAOUT|MSGO, - P_DATAIN_DT P_DATAIN|MSGO, - P_COMMAND CDO, - P_MESGOUT CDO|MSGO, - P_STATUS CDO|IOO, - P_MESGIN CDO|IOO|MSGO - } -} - -register SCSISIGI { - address 0x041 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field CDI 0x80 - field IOI 0x40 - field MSGI 0x20 - field ATNI 0x10 - field SELI 0x08 - field BSYI 0x04 - field REQI 0x02 - field ACKI 0x01 -/* - * Possible phases in SCSISIGI - */ - enum PHASE_MASK CDO|IOO|MSGO { - P_DATAOUT 0x0, - P_DATAIN IOO, - P_DATAOUT_DT P_DATAOUT|MSGO, - P_DATAIN_DT P_DATAIN|MSGO, - P_COMMAND CDO, - P_MESGOUT CDO|MSGO, - P_STATUS CDO|IOO, - P_MESGIN CDO|IOO|MSGO - } -} - -/* - * Multiple Target IDs - * Bitmask of ids to respond as a target. - */ -register MULTARGID { - address 0x040 - access_mode RW - modes M_CFG - size 2 -} - -/* - * SCSI Phase - */ -register SCSIPHASE { - address 0x042 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field STATUS_PHASE 0x20 - field COMMAND_PHASE 0x10 - field MSG_IN_PHASE 0x08 - field MSG_OUT_PHASE 0x04 - field DATA_PHASE_MASK 0x03 { - DATA_OUT_PHASE 0x01, - DATA_IN_PHASE 0x02 - } -} - -/* - * SCSI Data 0 Image - */ -register SCSIDAT0_IMG { - address 0x043 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI -} - -/* - * SCSI Latched Data - */ -register SCSIDAT { - address 0x044 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - size 2 -} - -/* - * SCSI Data Bus - */ -register SCSIBUS { - address 0x046 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - size 2 -} - -/* - * Target ID In - */ -register TARGIDIN { - address 0x048 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field CLKOUT 0x80 - field TARGID 0x0F -} - -/* - * Selection/Reselection ID - * Upper four bits are the device id. The ONEBIT is set when the re/selecting - * device did not set its own ID. - */ -register SELID { - address 0x049 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field SELID_MASK 0xf0 - field ONEBIT 0x08 -} - -/* - * SCSI Block Control - * Controls Bus type and channel selection. SELWIDE allows for the - * coexistence of 8bit and 16bit devices on a wide bus. - */ -register SBLKCTL { - address 0x04A - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field DIAGLEDEN 0x80 - field DIAGLEDON 0x40 - field ENAB40 0x08 /* LVD transceiver active */ - field ENAB20 0x04 /* SE/HVD transceiver active */ - field SELWIDE 0x02 -} - -/* - * Option Mode - */ -register OPTIONMODE { - address 0x04A - access_mode RW - modes M_CFG - field BIOSCANCTL 0x80 - field AUTOACKEN 0x40 - field BIASCANCTL 0x20 - field BUSFREEREV 0x10 - field ENDGFORMCHK 0x04 - field AUTO_MSGOUT_DE 0x02 - mask OPTIONMODE_DEFAULTS AUTO_MSGOUT_DE -} - -/* - * SCSI Status 0 - */ -register SSTAT0 { - address 0x04B - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field TARGET 0x80 /* Board acting as target */ - field SELDO 0x40 /* Selection Done */ - field SELDI 0x20 /* Board has been selected */ - field SELINGO 0x10 /* Selection In Progress */ - field IOERR 0x08 /* LVD Tranceiver mode changed */ - field OVERRUN 0x04 /* SCSI Offset overrun detected */ - field SPIORDY 0x02 /* SCSI PIO Ready */ - field ARBDO 0x01 /* Arbitration Done Out */ -} - -/* - * Clear SCSI Interrupt 0 - * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT0. - */ -register CLRSINT0 { - address 0x04B - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRSELDO 0x40 - field CLRSELDI 0x20 - field CLRSELINGO 0x10 - field CLRIOERR 0x08 - field CLROVERRUN 0x04 - field CLRSPIORDY 0x02 - field CLRARBDO 0x01 -} - -/* - * SCSI Interrupt Mode 0 - * Setting any bit will enable the corresponding function - * in SIMODE0 to interrupt via the IRQ pin. - */ -register SIMODE0 { - address 0x04B - access_mode RW - modes M_CFG - field ENSELDO 0x40 - field ENSELDI 0x20 - field ENSELINGO 0x10 - field ENIOERR 0x08 - field ENOVERRUN 0x04 - field ENSPIORDY 0x02 - field ENARBDO 0x01 -} - -/* - * SCSI Status 1 - */ -register SSTAT1 { - address 0x04C - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field SELTO 0x80 - field ATNTARG 0x40 - field SCSIRSTI 0x20 - field PHASEMIS 0x10 - field BUSFREE 0x08 - field SCSIPERR 0x04 - field STRB2FAST 0x02 - field REQINIT 0x01 -} - -/* - * Clear SCSI Interrupt 1 - * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1. - */ -register CLRSINT1 { - address 0x04C - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRSELTIMEO 0x80 - field CLRATNO 0x40 - field CLRSCSIRSTI 0x20 - field CLRBUSFREE 0x08 - field CLRSCSIPERR 0x04 - field CLRSTRB2FAST 0x02 - field CLRREQINIT 0x01 -} - -/* - * SCSI Status 2 - */ -register SSTAT2 { - address 0x04d - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field BUSFREETIME 0xc0 { - BUSFREE_LQO 0x40, - BUSFREE_DFF0 0x80, - BUSFREE_DFF1 0xC0 - } - field NONPACKREQ 0x20 - field EXP_ACTIVE 0x10 /* SCSI Expander Active */ - field BSYX 0x08 /* Busy Expander */ - field WIDE_RES 0x04 /* Modes 0 and 1 only */ - field SDONE 0x02 /* Modes 0 and 1 only */ - field DMADONE 0x01 /* Modes 0 and 1 only */ -} - -/* - * Clear SCSI Interrupt 2 - */ -register CLRSINT2 { - address 0x04D - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRNONPACKREQ 0x20 - field CLRWIDE_RES 0x04 /* Modes 0 and 1 only */ - field CLRSDONE 0x02 /* Modes 0 and 1 only */ - field CLRDMADONE 0x01 /* Modes 0 and 1 only */ -} - -/* - * SCSI Interrupt Mode 2 - */ -register SIMODE2 { - address 0x04D - access_mode RW - modes M_CFG - field ENWIDE_RES 0x04 - field ENSDONE 0x02 - field ENDMADONE 0x01 -} - -/* - * Physical Error Diagnosis - */ -register PERRDIAG { - address 0x04E - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field HIZERO 0x80 - field HIPERR 0x40 - field PREVPHASE 0x20 - field PARITYERR 0x10 - field AIPERR 0x08 - field CRCERR 0x04 - field DGFORMERR 0x02 - field DTERR 0x01 -} - -/* - * LQI Manager Current State - */ -register LQISTATE { - address 0x04E - access_mode RO - modes M_CFG -} - -/* - * SCSI Offset Count - */ -register SOFFCNT { - address 0x04F - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI -} - -/* - * LQO Manager Current State - */ -register LQOSTATE { - address 0x04F - access_mode RO - modes M_CFG -} - -/* - * LQI Manager Status - */ -register LQISTAT0 { - address 0x050 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field LQIATNQAS 0x20 - field LQICRCT1 0x10 - field LQICRCT2 0x08 - field LQIBADLQT 0x04 - field LQIATNLQ 0x02 - field LQIATNCMD 0x01 -} - -/* - * Clear LQI Interrupts 0 - */ -register CLRLQIINT0 { - address 0x050 - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRLQIATNQAS 0x20 - field CLRLQICRCT1 0x10 - field CLRLQICRCT2 0x08 - field CLRLQIBADLQT 0x04 - field CLRLQIATNLQ 0x02 - field CLRLQIATNCMD 0x01 -} - -/* - * LQI Manager Interrupt Mode 0 - */ -register LQIMODE0 { - address 0x050 - access_mode RW - modes M_CFG - field ENLQIATNQASK 0x20 - field ENLQICRCT1 0x10 - field ENLQICRCT2 0x08 - field ENLQIBADLQT 0x04 - field ENLQIATNLQ 0x02 - field ENLQIATNCMD 0x01 -} - -/* - * LQI Manager Status 1 - */ -register LQISTAT1 { - address 0x051 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field LQIPHASE_LQ 0x80 - field LQIPHASE_NLQ 0x40 - field LQIABORT 0x20 - field LQICRCI_LQ 0x10 - field LQICRCI_NLQ 0x08 - field LQIBADLQI 0x04 - field LQIOVERI_LQ 0x02 - field LQIOVERI_NLQ 0x01 -} - -/* - * Clear LQI Manager Interrupts1 - */ -register CLRLQIINT1 { - address 0x051 - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRLQIPHASE_LQ 0x80 - field CLRLQIPHASE_NLQ 0x40 - field CLRLIQABORT 0x20 - field CLRLQICRCI_LQ 0x10 - field CLRLQICRCI_NLQ 0x08 - field CLRLQIBADLQI 0x04 - field CLRLQIOVERI_LQ 0x02 - field CLRLQIOVERI_NLQ 0x01 -} - -/* - * LQI Manager Interrupt Mode 1 - */ -register LQIMODE1 { - address 0x051 - access_mode RW - modes M_CFG - field ENLQIPHASE_LQ 0x80 - field ENLQIPHASE_NLQ 0x40 - field ENLIQABORT 0x20 - field ENLQICRCI_LQ 0x10 - field ENLQICRCI_NLQ 0x08 - field ENLQIBADLQI 0x04 - field ENLQIOVERI_LQ 0x02 - field ENLQIOVERI_NLQ 0x01 -} - -/* - * LQI Manager Status 2 - */ -register LQISTAT2 { - address 0x052 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field PACKETIZED 0x80 - field LQIPHASE_OUTPKT 0x40 - field LQIWORKONLQ 0x20 - field LQIWAITFIFO 0x10 - field LQISTOPPKT 0x08 - field LQISTOPLQ 0x04 - field LQISTOPCMD 0x02 - field LQIGSAVAIL 0x01 -} - -/* - * SCSI Status 3 - */ -register SSTAT3 { - address 0x053 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field NTRAMPERR 0x02 - field OSRAMPERR 0x01 -} - -/* - * Clear SCSI Status 3 - */ -register CLRSINT3 { - address 0x053 - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRNTRAMPERR 0x02 - field CLROSRAMPERR 0x01 -} - -/* - * SCSI Interrupt Mode 3 - */ -register SIMODE3 { - address 0x053 - access_mode RW - modes M_CFG - field ENNTRAMPERR 0x02 - field ENOSRAMPERR 0x01 -} - -/* - * LQO Manager Status 0 - */ -register LQOSTAT0 { - address 0x054 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field LQOTARGSCBPERR 0x10 - field LQOSTOPT2 0x08 - field LQOATNLQ 0x04 - field LQOATNPKT 0x02 - field LQOTCRC 0x01 -} - -/* - * Clear LQO Manager interrupt 0 - */ -register CLRLQOINT0 { - address 0x054 - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRLQOTARGSCBPERR 0x10 - field CLRLQOSTOPT2 0x08 - field CLRLQOATNLQ 0x04 - field CLRLQOATNPKT 0x02 - field CLRLQOTCRC 0x01 -} - -/* - * LQO Manager Interrupt Mode 0 - */ -register LQOMODE0 { - address 0x054 - access_mode RW - modes M_CFG - field ENLQOTARGSCBPERR 0x10 - field ENLQOSTOPT2 0x08 - field ENLQOATNLQ 0x04 - field ENLQOATNPKT 0x02 - field ENLQOTCRC 0x01 -} - -/* - * LQO Manager Status 1 - */ -register LQOSTAT1 { - address 0x055 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field LQOINITSCBPERR 0x10 - field LQOSTOPI2 0x08 - field LQOBADQAS 0x04 - field LQOBUSFREE 0x02 - field LQOPHACHGINPKT 0x01 -} - -/* - * Clear LOQ Interrupt 1 - */ -register CLRLQOINT1 { - address 0x055 - access_mode WO - modes M_DFF0, M_DFF1, M_SCSI - field CLRLQOINITSCBPERR 0x10 - field CLRLQOSTOPI2 0x08 - field CLRLQOBADQAS 0x04 - field CLRLQOBUSFREE 0x02 - field CLRLQOPHACHGINPKT 0x01 -} - -/* - * LQO Manager Interrupt Mode 1 - */ -register LQOMODE1 { - address 0x055 - access_mode RW - modes M_CFG - field ENLQOINITSCBPERR 0x10 - field ENLQOSTOPI2 0x08 - field ENLQOBADQAS 0x04 - field ENLQOBUSFREE 0x02 - field ENLQOPHACHGINPKT 0x01 -} - -/* - * LQO Manager Status 2 - */ -register LQOSTAT2 { - address 0x056 - access_mode RO - modes M_DFF0, M_DFF1, M_SCSI - field LQOPKT 0xE0 - field LQOWAITFIFO 0x10 - field LQOPHACHGOUTPKT 0x02 /* outside of packet boundaries. */ - field LQOSTOP0 0x01 /* Stopped after sending all packets */ -} - -/* - * Output Synchronizer Space Count - */ -register OS_SPACE_CNT { - address 0x056 - access_mode RO - modes M_CFG -} - -/* - * SCSI Interrupt Mode 1 - * Setting any bit will enable the corresponding function - * in SIMODE1 to interrupt via the IRQ pin. - */ -register SIMODE1 { - address 0x057 - access_mode RW - modes M_DFF0, M_DFF1, M_SCSI - field ENSELTIMO 0x80 - field ENATNTARG 0x40 - field ENSCSIRST 0x20 - field ENPHASEMIS 0x10 - field ENBUSFREE 0x08 - field ENSCSIPERR 0x04 - field ENSTRB2FAST 0x02 - field ENREQINIT 0x01 -} - -/* - * Good Status FIFO - */ -register GSFIFO { - address 0x058 - access_mode RO - size 2 - modes M_DFF0, M_DFF1, M_SCSI -} - -/* - * Data FIFO SCSI Transfer Control - */ -register DFFSXFRCTL { - address 0x05A - access_mode RW - modes M_DFF0, M_DFF1 - field DFFBITBUCKET 0x08 - field CLRSHCNT 0x04 - field CLRCHN 0x02 - field RSTCHN 0x01 -} - -/* - * Next SCSI Control Block - */ -register NEXTSCB { - address 0x05A - access_mode RW - size 2 - modes M_SCSI -} - -/* Rev B only. */ -register LQOSCSCTL { - address 0x05A - access_mode RW - size 1 - modes M_CFG - field LQOH2A_VERSION 0x80 - field LQONOCHKOVER 0x01 -} - -/* - * SEQ Interrupts - */ -register SEQINTSRC { - address 0x05B - access_mode RO - modes M_DFF0, M_DFF1 - field CTXTDONE 0x40 - field SAVEPTRS 0x20 - field CFG4DATA 0x10 - field CFG4ISTAT 0x08 - field CFG4TSTAT 0x04 - field CFG4ICMD 0x02 - field CFG4TCMD 0x01 -} - -/* - * Clear Arp Interrupts - */ -register CLRSEQINTSRC { - address 0x05B - access_mode WO - modes M_DFF0, M_DFF1 - field CLRCTXTDONE 0x40 - field CLRSAVEPTRS 0x20 - field CLRCFG4DATA 0x10 - field CLRCFG4ISTAT 0x08 - field CLRCFG4TSTAT 0x04 - field CLRCFG4ICMD 0x02 - field CLRCFG4TCMD 0x01 -} - -/* - * SEQ Interrupt Enabled (Shared) - */ -register SEQIMODE { - address 0x05C - access_mode RW - modes M_DFF0, M_DFF1 - field ENCTXTDONE 0x40 - field ENSAVEPTRS 0x20 - field ENCFG4DATA 0x10 - field ENCFG4ISTAT 0x08 - field ENCFG4TSTAT 0x04 - field ENCFG4ICMD 0x02 - field ENCFG4TCMD 0x01 -} - -/* - * Current SCSI Control Block - */ -register CURRSCB { - address 0x05C - access_mode RW - size 2 - modes M_SCSI -} - -/* - * Data FIFO Status - */ -register MDFFSTAT { - address 0x05D - access_mode RO - modes M_DFF0, M_DFF1 - field SHCNTNEGATIVE 0x40 /* Rev B or higher */ - field SHCNTMINUS1 0x20 /* Rev B or higher */ - field LASTSDONE 0x10 - field SHVALID 0x08 - field DLZERO 0x04 /* FIFO data ends on packet boundary. */ - field DATAINFIFO 0x02 - field FIFOFREE 0x01 -} - -/* - * CRC Control - */ -register CRCCONTROL { - address 0x05d - access_mode RW - modes M_CFG - field CRCVALCHKEN 0x40 -} - -/* - * SCSI Test Control - */ -register SCSITEST { - address 0x05E - access_mode RW - modes M_CFG - field CNTRTEST 0x08 - field SEL_TXPLL_DEBUG 0x04 -} - -/* - * Data FIFO Queue Tag - */ -register DFFTAG { - address 0x05E - access_mode RW - size 2 - modes M_DFF0, M_DFF1 -} - -/* - * Last SCSI Control Block - */ -register LASTSCB { - address 0x05E - access_mode RW - size 2 - modes M_SCSI -} - -/* - * SCSI I/O Cell Power-down Control - */ -register IOPDNCTL { - address 0x05F - access_mode RW - modes M_CFG - field DISABLE_OE 0x80 - field PDN_IDIST 0x04 - field PDN_DIFFSENSE 0x01 -} - -/* - * Shaddow Host Address. - */ -register SHADDR { - address 0x060 - access_mode RO - size 8 - modes M_DFF0, M_DFF1 -} - -/* - * Data Group CRC Interval. - */ -register DGRPCRCI { - address 0x060 - access_mode RW - size 2 - modes M_CFG -} - -/* - * Data Transfer Negotiation Address - */ -register NEGOADDR { - address 0x060 - access_mode RW - modes M_SCSI -} - -/* - * Data Transfer Negotiation Data - Period Byte - */ -register NEGPERIOD { - address 0x061 - access_mode RW - modes M_SCSI -} - -/* - * Packetized CRC Interval - */ -register PACKCRCI { - address 0x062 - access_mode RW - size 2 - modes M_CFG -} - -/* - * Data Transfer Negotiation Data - Offset Byte - */ -register NEGOFFSET { - address 0x062 - access_mode RW - modes M_SCSI -} - -/* - * Data Transfer Negotiation Data - PPR Options - */ -register NEGPPROPTS { - address 0x063 - access_mode RW - modes M_SCSI - field PPROPT_PACE 0x08 - field PPROPT_QAS 0x04 - field PPROPT_DT 0x02 - field PPROPT_IUT 0x01 -} - -/* - * Data Transfer Negotiation Data - Connection Options - */ -register NEGCONOPTS { - address 0x064 - access_mode RW - modes M_SCSI - field ENSNAPSHOT 0x40 - field RTI_WRTDIS 0x20 - field RTI_OVRDTRN 0x10 - field ENSLOWCRC 0x08 - field ENAUTOATNI 0x04 - field ENAUTOATNO 0x02 - field WIDEXFER 0x01 -} - -/* - * Negotiation Table Annex Column Index. - */ -register ANNEXCOL { - address 0x065 - access_mode RW - modes M_SCSI -} - -register SCSCHKN { - address 0x066 - access_mode RW - modes M_CFG - field STSELSKIDDIS 0x40 - field CURRFIFODEF 0x20 - field WIDERESEN 0x10 - field SDONEMSKDIS 0x08 - field DFFACTCLR 0x04 - field SHVALIDSTDIS 0x02 - field LSTSGCLRDIS 0x01 -} - -const AHD_ANNEXCOL_PER_DEV0 4 -const AHD_NUM_PER_DEV_ANNEXCOLS 4 -const AHD_ANNEXCOL_PRECOMP_SLEW 4 -const AHD_PRECOMP_MASK 0x07 -const AHD_PRECOMP_SHIFT 0 -const AHD_PRECOMP_CUTBACK_17 0x04 -const AHD_PRECOMP_CUTBACK_29 0x06 -const AHD_PRECOMP_CUTBACK_37 0x07 -const AHD_SLEWRATE_MASK 0x78 -const AHD_SLEWRATE_SHIFT 3 -/* - * Rev A has only a single bit of slew adjustment. - * Rev B has 4 bits. - */ -const AHD_SLEWRATE_DEF_REVA 0x01 -const AHD_SLEWRATE_DEF_REVB 0x08 - -/* Rev A does not have any amplitude setting. */ -const AHD_ANNEXCOL_AMPLITUDE 6 -const AHD_AMPLITUDE_MASK 0x7 -const AHD_AMPLITUDE_SHIFT 0 -const AHD_AMPLITUDE_DEF 0x7 - -/* - * Negotiation Table Annex Data Port. - */ -register ANNEXDAT { - address 0x066 - access_mode RW - modes M_SCSI -} - -/* - * Initiator's Own Id. - * The SCSI ID to use for Selection Out and seen during a reselection.. - */ -register IOWNID { - address 0x067 - access_mode RW - modes M_SCSI -} - -/* - * 960MHz Phase-Locked Loop Control 0 - */ -register PLL960CTL0 { - address 0x068 - access_mode RW - modes M_CFG - field PLL_VCOSEL 0x80 - field PLL_PWDN 0x40 - field PLL_NS 0x30 - field PLL_ENLUD 0x08 - field PLL_ENLPF 0x04 - field PLL_DLPF 0x02 - field PLL_ENFBM 0x01 -} - -/* - * Target Own Id - */ -register TOWNID { - address 0x069 - access_mode RW - modes M_SCSI -} - -/* - * 960MHz Phase-Locked Loop Control 1 - */ -register PLL960CTL1 { - address 0x069 - access_mode RW - modes M_CFG - field PLL_CNTEN 0x80 - field PLL_CNTCLR 0x40 - field PLL_RST 0x01 -} - -/* - * Expander Signature - */ -register XSIG { - address 0x06A - access_mode RW - modes M_SCSI -} - -/* - * Shadow Byte Count - */ -register SHCNT { - address 0x068 - access_mode RW - size 3 - modes M_DFF0, M_DFF1 -} - -/* - * Selection Out ID - */ -register SELOID { - address 0x06B - access_mode RW - modes M_SCSI -} - -/* - * 960-MHz Phase-Locked Loop Test Count - */ -register PLL960CNT0 { - address 0x06A - access_mode RO - size 2 - modes M_CFG -} - -/* - * 400-MHz Phase-Locked Loop Control 0 - */ -register PLL400CTL0 { - address 0x06C - access_mode RW - modes M_CFG - field PLL_VCOSEL 0x80 - field PLL_PWDN 0x40 - field PLL_NS 0x30 - field PLL_ENLUD 0x08 - field PLL_ENLPF 0x04 - field PLL_DLPF 0x02 - field PLL_ENFBM 0x01 -} - -/* - * Arbitration Fairness - */ -register FAIRNESS { - address 0x06C - access_mode RW - size 2 - modes M_SCSI -} - -/* - * 400-MHz Phase-Locked Loop Control 1 - */ -register PLL400CTL1 { - address 0x06D - access_mode RW - modes M_CFG - field PLL_CNTEN 0x80 - field PLL_CNTCLR 0x40 - field PLL_RST 0x01 -} - -/* - * Arbitration Unfairness - */ -register UNFAIRNESS { - address 0x06E - access_mode RW - size 2 - modes M_SCSI -} - -/* - * 400-MHz Phase-Locked Loop Test Count - */ -register PLL400CNT0 { - address 0x06E - access_mode RO - size 2 - modes M_CFG -} - -/* - * SCB Page Pointer - */ -register SCBPTR { - address 0x0A8 - access_mode RW - size 2 - modes M_DFF0, M_DFF1, M_CCHAN, M_SCSI -} - -/* - * CMC SCB Array Count - * Number of bytes to transfer between CMC SCB memory and SCBRAM. - * Transfers must be 8byte aligned and sized. - */ -register CCSCBACNT { - address 0x0AB - access_mode RW - modes M_CCHAN -} - -/* - * SCB Autopointer - * SCB-Next Address Snooping logic. When an SCB is transferred to - * the card, the next SCB address to be used by the CMC array can - * be autoloaded from that transfer. - */ -register SCBAUTOPTR { - address 0x0AB - access_mode RW - modes M_CFG - field AUSCBPTR_EN 0x80 - field SCBPTR_ADDR 0x38 - field SCBPTR_OFF 0x07 -} - -/* - * CMC SG Ram Address Pointer - */ -register CCSGADDR { - address 0x0AC - access_mode RW - modes M_DFF0, M_DFF1 -} - -/* - * CMC SCB RAM Address Pointer - */ -register CCSCBADDR { - address 0x0AC - access_mode RW - modes M_CCHAN -} - -/* - * CMC SCB Ram Back-up Address Pointer - * Indicates the true stop location of transfers halted prior - * to SCBHCNT going to 0. - */ -register CCSCBADR_BK { - address 0x0AC - access_mode RO - modes M_CFG -} - -/* - * CMC SG Control - */ -register CCSGCTL { - address 0x0AD - access_mode RW - modes M_DFF0, M_DFF1 - field CCSGDONE 0x80 - field SG_CACHE_AVAIL 0x10 - field CCSGENACK 0x08 - mask CCSGEN 0x0C - field SG_FETCH_REQ 0x02 - field CCSGRESET 0x01 -} - -/* - * CMD SCB Control - */ -register CCSCBCTL { - address 0x0AD - access_mode RW - modes M_CCHAN - field CCSCBDONE 0x80 - field ARRDONE 0x40 - field CCARREN 0x10 - field CCSCBEN 0x08 - field CCSCBDIR 0x04 - field CCSCBRESET 0x01 -} - -/* - * CMC Ram BIST - */ -register CMC_RAMBIST { - address 0x0AD - access_mode RW - modes M_CFG - field SG_ELEMENT_SIZE 0x80 - field SCBRAMBIST_FAIL 0x40 - field SG_BIST_FAIL 0x20 - field SG_BIST_EN 0x10 - field CMC_BUFFER_BIST_FAIL 0x02 - field CMC_BUFFER_BIST_EN 0x01 -} - -/* - * CMC SG RAM Data Port - */ -register CCSGRAM { - address 0x0B0 - access_mode RW - modes M_DFF0, M_DFF1 -} - -/* - * CMC SCB RAM Data Port - */ -register CCSCBRAM { - address 0x0B0 - access_mode RW - modes M_CCHAN -} - -/* - * Flex DMA Address. - */ -register FLEXADR { - address 0x0B0 - access_mode RW - size 3 - modes M_SCSI -} - -/* - * Flex DMA Byte Count - */ -register FLEXCNT { - address 0x0B3 - access_mode RW - size 2 - modes M_SCSI -} - -/* - * Flex DMA Status - */ -register FLEXDMASTAT { - address 0x0B5 - access_mode RW - modes M_SCSI - field FLEXDMAERR 0x02 - field FLEXDMADONE 0x01 -} - -/* - * Flex DMA Data Port - */ -register FLEXDATA { - address 0x0B6 - access_mode RW - modes M_SCSI -} - -/* - * Board Data - */ -register BRDDAT { - address 0x0B8 - access_mode RW - modes M_SCSI -} - -/* - * Board Control - */ -register BRDCTL { - address 0x0B9 - access_mode RW - modes M_SCSI - field FLXARBACK 0x80 - field FLXARBREQ 0x40 - field BRDADDR 0x38 - field BRDEN 0x04 - field BRDRW 0x02 - field BRDSTB 0x01 -} - -/* - * Serial EEPROM Address - */ -register SEEADR { - address 0x0BA - access_mode RW - modes M_SCSI -} - -/* - * Serial EEPROM Data - */ -register SEEDAT { - address 0x0BC - access_mode RW - size 2 - modes M_SCSI -} - -/* - * Serial EEPROM Status - */ -register SEESTAT { - address 0x0BE - access_mode RO - modes M_SCSI - field INIT_DONE 0x80 - field SEEOPCODE 0x70 - field LDALTID_L 0x08 - field SEEARBACK 0x04 - field SEEBUSY 0x02 - field SEESTART 0x01 -} - -/* - * Serial EEPROM Control - */ -register SEECTL { - address 0x0BE - access_mode RW - modes M_SCSI - field SEEOPCODE 0x70 { - SEEOP_ERASE 0x70, - SEEOP_READ 0x60, - SEEOP_WRITE 0x50, - /* - * The following four commands use special - * addresses for differentiation. - */ - SEEOP_ERAL 0x40 - } - mask SEEOP_EWEN 0x40 - mask SEEOP_WALL 0x40 - mask SEEOP_EWDS 0x40 - field SEERST 0x02 - field SEESTART 0x01 -} - -const SEEOP_ERAL_ADDR 0x80 -const SEEOP_EWEN_ADDR 0xC0 -const SEEOP_WRAL_ADDR 0x40 -const SEEOP_EWDS_ADDR 0x00 - -/* - * SCB Counter - */ -register SCBCNT { - address 0x0BF - access_mode RW - modes M_SCSI -} - -/* - * Data FIFO Write Address - * Pointer to the next QWD location to be written to the data FIFO. - */ -register DFWADDR { - address 0x0C0 - access_mode RW - size 2 - modes M_DFF0, M_DFF1 -} - -/* - * DSP Filter Control - */ -register DSPFLTRCTL { - address 0x0C0 - access_mode RW - modes M_CFG - field FLTRDISABLE 0x20 - field EDGESENSE 0x10 - field DSPFCNTSEL 0x0F -} - -/* - * DSP Data Channel Control - */ -register DSPDATACTL { - address 0x0C1 - access_mode RW - modes M_CFG - field BYPASSENAB 0x80 - field DESQDIS 0x10 - field RCVROFFSTDIS 0x04 - field XMITOFFSTDIS 0x02 -} - -/* - * Data FIFO Read Address - * Pointer to the next QWD location to be read from the data FIFO. - */ -register DFRADDR { - address 0x0C2 - access_mode RW - size 2 - modes M_DFF0, M_DFF1 -} - -/* - * DSP REQ Control - */ -register DSPREQCTL { - address 0x0C2 - access_mode RW - modes M_CFG - field MANREQCTL 0xC0 - field MANREQDLY 0x3F -} - -/* - * DSP ACK Control - */ -register DSPACKCTL { - address 0x0C3 - access_mode RW - modes M_CFG - field MANACKCTL 0xC0 - field MANACKDLY 0x3F -} - -/* - * Data FIFO Data - * Read/Write byte port into the data FIFO. The read and write - * FIFO pointers increment with each read and write respectively - * to this port. - */ -register DFDAT { - address 0x0C4 - access_mode RW - modes M_DFF0, M_DFF1 -} - -/* - * DSP Channel Select - */ -register DSPSELECT { - address 0x0C4 - access_mode RW - modes M_CFG - field AUTOINCEN 0x80 - field DSPSEL 0x1F -} - -const NUMDSPS 0x14 - -/* - * Write Bias Control - */ -register WRTBIASCTL { - address 0x0C5 - access_mode WO - modes M_CFG - field AUTOXBCDIS 0x80 - field XMITMANVAL 0x3F -} - -/* - * Currently the WRTBIASCTL is the same as the default. - */ -const WRTBIASCTL_HP_DEFAULT 0x0 - -/* - * Receiver Bias Control - */ -register RCVRBIOSCTL { - address 0x0C6 - access_mode WO - modes M_CFG - field AUTORBCDIS 0x80 - field RCVRMANVAL 0x3F -} - -/* - * Write Bias Calculator - */ -register WRTBIASCALC { - address 0x0C7 - access_mode RO - modes M_CFG -} - -/* - * Data FIFO Pointers - * Contains the byte offset from DFWADDR and DWRADDR to the current - * FIFO write/read locations. - */ -register DFPTRS { - address 0x0C8 - access_mode RW - modes M_DFF0, M_DFF1 -} - -/* - * Receiver Bias Calculator - */ -register RCVRBIASCALC { - address 0x0C8 - access_mode RO - modes M_CFG -} - -/* - * Data FIFO Backup Read Pointer - * Contains the data FIFO address to be restored if the last - * data accessed from the data FIFO was not transferred successfully. - */ -register DFBKPTR { - address 0x0C9 - access_mode RW - size 2 - modes M_DFF0, M_DFF1 -} - -/* - * Skew Calculator - */ -register SKEWCALC { - address 0x0C9 - access_mode RO - modes M_CFG -} - -/* - * Data FIFO Debug Control - */ -register DFDBCTL { - address 0x0CB - access_mode RW - modes M_DFF0, M_DFF1 - field DFF_CIO_WR_RDY 0x20 - field DFF_CIO_RD_RDY 0x10 - field DFF_DIR_ERR 0x08 - field DFF_RAMBIST_FAIL 0x04 - field DFF_RAMBIST_DONE 0x02 - field DFF_RAMBIST_EN 0x01 -} - -/* - * Data FIFO Space Count - * Number of FIFO locations that are free. - */ -register DFSCNT { - address 0x0CC - access_mode RO - size 2 - modes M_DFF0, M_DFF1 -} - -/* - * Data FIFO Byte Count - * Number of filled FIFO locations. - */ -register DFBCNT { - address 0x0CE - access_mode RO - size 2 - modes M_DFF0, M_DFF1 -} - -/* - * Sequencer Program Overlay Address. - * Low address must be written prior to high address. - */ -register OVLYADDR { - address 0x0D4 - modes M_SCSI - size 2 - access_mode RW -} - -/* - * Sequencer Control 0 - * Error detection mode, speed configuration, - * single step, breakpoints and program load. - */ -register SEQCTL0 { - address 0x0D6 - access_mode RW - field PERRORDIS 0x80 - field PAUSEDIS 0x40 - field FAILDIS 0x20 - field FASTMODE 0x10 - field BRKADRINTEN 0x08 - field STEP 0x04 - field SEQRESET 0x02 - field LOADRAM 0x01 -} - -/* - * Sequencer Control 1 - * Instruction RAM Diagnostics - */ -register SEQCTL1 { - address 0x0D7 - access_mode RW - field OVRLAY_DATA_CHK 0x08 - field RAMBIST_DONE 0x04 - field RAMBIST_FAIL 0x02 - field RAMBIST_EN 0x01 -} - -/* - * Sequencer Flags - * Zero and Carry state of the ALU. - */ -register FLAGS { - address 0x0D8 - access_mode RO - field ZERO 0x02 - field CARRY 0x01 -} - -/* - * Sequencer Interrupt Control - */ -register SEQINTCTL { - address 0x0D9 - access_mode RW - field INTVEC1DSL 0x80 - field INT1_CONTEXT 0x20 - field SCS_SEQ_INT1M1 0x10 - field SCS_SEQ_INT1M0 0x08 - field INTMASK2 0x04 - field INTMASK1 0x02 - field IRET 0x01 -} - -/* - * Sequencer RAM Data Port - * Single byte window into the Sequencer Instruction Ram area starting - * at the address specified by OVLYADDR. To write a full instruction word, - * simply write four bytes in succession. OVLYADDR will increment after the - * most significant instrution byte (the byte with the parity bit) is written. - */ -register SEQRAM { - address 0x0DA - access_mode RW -} - -/* - * Sequencer Program Counter - * Low byte must be written prior to high byte. - */ -register PRGMCNT { - address 0x0DE - access_mode RW - size 2 -} - -/* - * Accumulator - */ -register ACCUM { - address 0x0E0 - access_mode RW - accumulator -} - -/* - * Source Index Register - * Incrementing index for reads of SINDIR and the destination (low byte only) - * for any immediate operands passed in jmp, jc, jnc, call instructions. - * Example: - * mvi 0xFF call some_routine; - * - * Will set SINDEX[0] to 0xFF and call the routine "some_routine. - */ -register SINDEX { - address 0x0E2 - access_mode RW - size 2 - sindex -} - -/* - * Destination Index Register - * Incrementing index for writes to DINDIR. Can be used as a scratch register. - */ -register DINDEX { - address 0x0E4 - access_mode RW - size 2 -} - -/* - * Break Address - * Sequencer instruction breakpoint address address. - */ -register BRKADDR0 { - address 0x0E6 - access_mode RW -} - -register BRKADDR1 { - address 0x0E6 - access_mode RW - field BRKDIS 0x80 /* Disable Breakpoint */ -} - -/* - * All Ones - * All reads to this register return the value 0xFF. - */ -register ALLONES { - address 0x0E8 - access_mode RO - allones -} - -/* - * All Zeros - * All reads to this register return the value 0. - */ -register ALLZEROS { - address 0x0EA - access_mode RO - allzeros -} - -/* - * No Destination - * Writes to this register have no effect. - */ -register NONE { - address 0x0EA - access_mode WO - none -} - -/* - * Source Index Indirect - * Reading this register is equivalent to reading (register_base + SINDEX) and - * incrementing SINDEX by 1. - */ -register SINDIR { - address 0x0EC - access_mode RO -} - -/* - * Destination Index Indirect - * Writing this register is equivalent to writing to (register_base + DINDEX) - * and incrementing DINDEX by 1. - */ -register DINDIR { - address 0x0ED - access_mode WO -} - -/* - * Function One - * 2's complement to bit value conversion. Write the 2's complement value - * (0-7 only) to the top nibble and retrieve the bit indexed by that value - * on the next read of this register. - * Example: - * Write 0x60 - * Read 0x40 - */ -register FUNCTION1 { - address 0x0F0 - access_mode RW -} - -/* - * Stack - * Window into the stack. Each stack location is 10 bits wide reported - * low byte followed by high byte. There are 8 stack locations. - */ -register STACK { - address 0x0F2 - access_mode RW -} - -/* - * Interrupt Vector 1 Address - * Interrupt branch address for SCS SEQ_INT1 mode 0 and 1 interrupts. - */ -register INTVEC1_ADDR { - address 0x0F4 - access_mode RW - size 2 - modes M_CFG -} - -/* - * Current Address - * Address of the SEQRAM instruction currently executing instruction. - */ -register CURADDR { - address 0x0F4 - access_mode RW - size 2 - modes M_SCSI -} - -/* - * Interrupt Vector 2 Address - * Interrupt branch address for HST_SEQ_INT2 interrupts. - */ -register INTVEC2_ADDR { - address 0x0F6 - access_mode RW - size 2 - modes M_CFG -} - -/* - * Last Address - * Address of the SEQRAM instruction executed prior to the current instruction. - */ -register LASTADDR { - address 0x0F6 - access_mode RW - size 2 - modes M_SCSI -} - -register AHD_PCI_CONFIG_BASE { - address 0x100 - access_mode RW - size 256 - modes M_CFG -} - -/* ---------------------- Scratch RAM Offsets ------------------------- */ -scratch_ram { - /* Mode Specific */ - address 0x0A0 - size 8 - modes 0, 1, 2, 3 - REG0 { - size 2 - } - REG1 { - size 2 - } - REG_ISR { - size 2 - } - SG_STATE { - size 1 - field SEGS_AVAIL 0x01 - field LOADING_NEEDED 0x02 - field FETCH_INPROG 0x04 - } - /* - * Track whether the transfer byte count for - * the current data phase is odd. - */ - DATA_COUNT_ODD { - size 1 - } -} - -scratch_ram { - /* Mode Specific */ - address 0x0F8 - size 8 - modes 0, 1, 2, 3 - LONGJMP_ADDR { - size 2 - } - LONGJMP_SCB { - size 2 - } - ACCUM_SAVE { - size 1 - } -} - - -scratch_ram { - address 0x100 - size 128 - modes 0, 1, 2, 3 - /* - * Per "other-id" execution queues. We use an array of - * tail pointers into lists of SCBs sorted by "other-id". - * The execution head pointer threads the head SCBs for - * each list. - */ - WAITING_SCB_TAILS { - size 32 - } - WAITING_TID_HEAD { - size 2 - } - WAITING_TID_TAIL { - size 2 - } - /* - * SCBID of the next SCB in the new SCB queue. - */ - NEXT_QUEUED_SCB_ADDR { - size 4 - } - /* - * head of list of SCBs that have - * completed but have not been - * put into the qoutfifo. - */ - COMPLETE_SCB_HEAD { - size 2 - } - /* - * The list of completed SCBs in - * the active DMA. - */ - COMPLETE_SCB_DMAINPROG_HEAD { - size 2 - } - /* - * head of list of SCBs that have - * completed but need to be uploaded - * to the host prior to being completed. - */ - COMPLETE_DMA_SCB_HEAD { - size 2 - } - /* Counting semaphore to prevent new select-outs */ - QFREEZE_COUNT { - size 2 - } - /* - * Mode to restore on legacy idle loop exit. - */ - SAVED_MODE { - size 1 - } - /* - * Single byte buffer used to designate the type or message - * to send to a target. - */ - MSG_OUT { - size 1 - } - /* Parameters for DMA Logic */ - DMAPARAMS { - size 1 - field PRELOADEN 0x80 - field WIDEODD 0x40 - field SCSIEN 0x20 - field SDMAEN 0x10 - field SDMAENACK 0x10 - field HDMAEN 0x08 - field HDMAENACK 0x08 - field DIRECTION 0x04 /* Set indicates PCI->SCSI */ - field FIFOFLUSH 0x02 - field FIFORESET 0x01 - } - SEQ_FLAGS { - size 1 - field NOT_IDENTIFIED 0x80 - field NO_CDB_SENT 0x40 - field TARGET_CMD_IS_TAGGED 0x40 - field DPHASE 0x20 - /* Target flags */ - field TARG_CMD_PENDING 0x10 - field CMDPHASE_PENDING 0x08 - field DPHASE_PENDING 0x04 - field SPHASE_PENDING 0x02 - field NO_DISCONNECT 0x01 - } - /* - * Temporary storage for the - * target/channel/lun of a - * reconnecting target - */ - SAVED_SCSIID { - size 1 - } - SAVED_LUN { - size 1 - } - /* - * The last bus phase as seen by the sequencer. - */ - LASTPHASE { - size 1 - field CDI 0x80 - field IOI 0x40 - field MSGI 0x20 - field P_BUSFREE 0x01 - enum PHASE_MASK CDO|IOO|MSGO { - P_DATAOUT 0x0, - P_DATAIN IOO, - P_DATAOUT_DT P_DATAOUT|MSGO, - P_DATAIN_DT P_DATAIN|MSGO, - P_COMMAND CDO, - P_MESGOUT CDO|MSGO, - P_STATUS CDO|IOO, - P_MESGIN CDO|IOO|MSGO - } - } - /* - * Value to "or" into the SCBPTR[1] value to - * indicate that an entry in the QINFIFO is valid. - */ - QOUTFIFO_ENTRY_VALID_TAG { - size 1 - } - /* - * Base address of our shared data with the kernel driver in host - * memory. This includes the qoutfifo and target mode - * incoming command queue. - */ - SHARED_DATA_ADDR { - size 4 - } - /* - * Pointer to location in host memory for next - * position in the qoutfifo. - */ - QOUTFIFO_NEXT_ADDR { - size 4 - } - /* - * Kernel and sequencer offsets into the queue of - * incoming target mode command descriptors. The - * queue is full when the KERNEL_TQINPOS == TQINPOS. - */ - KERNEL_TQINPOS { - size 1 - } - TQINPOS { - size 1 - } - ARG_1 { - size 1 - mask SEND_MSG 0x80 - mask SEND_SENSE 0x40 - mask SEND_REJ 0x20 - mask MSGOUT_PHASEMIS 0x10 - mask EXIT_MSG_LOOP 0x08 - mask CONT_MSG_LOOP_WRITE 0x04 - mask CONT_MSG_LOOP_READ 0x03 - mask CONT_MSG_LOOP_TARG 0x02 - alias RETURN_1 - } - ARG_2 { - size 1 - alias RETURN_2 - } - - /* - * Snapshot of MSG_OUT taken after each message is sent. - */ - LAST_MSG { - size 1 - } - - /* - * Sequences the kernel driver has okayed for us. This allows - * the driver to do things like prevent initiator or target - * operations. - */ - SCSISEQ_TEMPLATE { - size 1 - field MANUALCTL 0x40 - field ENSELI 0x20 - field ENRSELI 0x10 - field MANUALP 0x0C - field ENAUTOATNP 0x02 - field ALTSTIM 0x01 - } - - /* - * The initiator specified tag for this target mode transaction. - */ - INITIATOR_TAG { - size 1 - } - - SEQ_FLAGS2 { - size 1 - field TARGET_MSG_PENDING 0x02 - field SELECTOUT_QFROZEN 0x04 - } - - ALLOCFIFO_SCBPTR { - size 2 - } - - /* - * The maximum amount of time to wait, when interrupt coalessing - * is enabled, before issueing a CMDCMPLT interrupt for a completed - * command. - */ - INT_COALESSING_TIMER { - size 2 - } - - /* - * The maximum number of commands to coaless into a single interrupt. - * Actually the 2's complement of that value to simplify sequencer - * code. - */ - INT_COALESSING_MAXCMDS { - size 1 - } - - /* - * The minimum number of commands still outstanding required - * to continue coalessing (2's compliment of value). - */ - INT_COALESSING_MINCMDS { - size 1 - } - - /* - * Number of commands "in-flight". - */ - CMDS_PENDING { - size 2 - } - - /* - * The count of commands that have been coalessed. - */ - INT_COALESSING_CMDCOUNT { - size 1 - } - - /* - * Since the HS_MAIBOX is self clearing, copy its contents to - * this position in scratch ram every time it changes. - */ - LOCAL_HS_MAILBOX { - size 1 - } - /* - * Target-mode CDB type to CDB length table used - * in non-packetized operation. - */ - CMDSIZE_TABLE { - size 8 - } -} - -/************************* Hardware SCB Definition ****************************/ -scb { - address 0x180 - size 64 - modes 0, 1, 2, 3 - SCB_RESIDUAL_DATACNT { - size 4 - alias SCB_CDB_STORE - } - SCB_RESIDUAL_SGPTR { - size 4 - alias SCB_CDB_PTR - field SG_ADDR_MASK 0xf8 /* In the last byte */ - field SG_OVERRUN_RESID 0x02 /* In the first byte */ - field SG_LIST_NULL 0x01 /* In the first byte */ - } - SCB_SCSI_STATUS { - size 1 - } - SCB_TARGET_PHASES { - size 1 - } - SCB_TARGET_DATA_DIR { - size 1 - } - SCB_TARGET_ITAG { - size 1 - } - SCB_SENSE_BUSADDR { - /* - * Only valid if CDB length is less than 13 bytes or - * we are using a CDB pointer. Otherwise contains - * the last 4 bytes of embedded cdb information. - */ - size 4 - alias SCB_NEXT_COMPLETE - } - SCB_TAG { - size 2 - } - SCB_CDB_LEN { - size 1 - field SCB_CDB_LEN_PTR 0x80 /* CDB in host memory */ - } - SCB_TASK_MANAGEMENT { - size 1 - } - SCB_NEXT { - alias SCB_NEXT_SCB_BUSADDR - size 2 - } - SCB_NEXT2 { - size 2 - } - SCB_DATAPTR { - size 8 - } - SCB_DATACNT { - /* - * The last byte is really the high address bits for - * the data address. - */ - size 4 - field SG_LAST_SEG 0x80 /* In the fourth byte */ - field SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */ - } - SCB_SGPTR { - size 4 - field SG_STATUS_VALID 0x04 /* In the first byte */ - field SG_FULL_RESID 0x02 /* In the first byte */ - field SG_LIST_NULL 0x01 /* In the first byte */ - } - SCB_CONTROL { - size 1 - field TARGET_SCB 0x80 - field DISCENB 0x40 - field TAG_ENB 0x20 - field MK_MESSAGE 0x10 - field STATUS_RCVD 0x08 - field DISCONNECTED 0x04 - field SCB_TAG_TYPE 0x03 - } - SCB_SCSIID { - size 1 - field TID 0xF0 - field OID 0x0F - } - SCB_LUN { - size 1 - field LID 0xff - } - SCB_TASK_ATTRIBUTE { - size 1 - } - SCB_BUSADDR { - size 4 - } - SCB_SPARE { - size 8 - alias SCB_PKT_LUN - } - SCB_DISCONNECTED_LISTS { - size 8 - } -} - -/*********************************** Constants ********************************/ -const MK_MESSAGE_BIT_OFFSET 4 -const TID_SHIFT 4 -const TARGET_CMD_CMPLT 0xfe -const INVALID_ADDR 0x80 -#define SCB_LIST_NULL 0xff -#define QOUTFIFO_ENTRY_VALID_TOGGLE 0x80 - -const CCSGADDR_MAX 0x80 -const CCSCBADDR_MAX 0x80 -const CCSGRAM_MAXSEGS 16 - -/* Selection Timeout Timer Constants */ -const STIMESEL_SHIFT 3 -const STIMESEL_MIN 0x18 -const STIMESEL_BUG_ADJ 0x8 - -/* WDTR Message values */ -const BUS_8_BIT 0x00 -const BUS_16_BIT 0x01 -const BUS_32_BIT 0x02 - -/* Offset maximums */ -const MAX_OFFSET 0xfe -const MAX_OFFSET_PACED 0xfe -const MAX_OFFSET_PACED_BUG 0x7f -/* - * Some 160 devices incorrectly accept 0xfe as a - * sync offset, but will overrun this value. Limit - * to 0x7f for speed lower than U320 which will - * avoid the persistent sync offset overruns. - */ -const MAX_OFFSET_NON_PACED 0x7f -const HOST_MSG 0xff - -/* - * The size of our sense buffers. - * Sense buffer mapping can be handled in either of two ways. - * The first is to allocate a dmamap for each transaction. - * Depending on the architecture, dmamaps can be costly. The - * alternative is to statically map the buffers in much the same - * way we handle our scatter gather lists. The driver implements - * the later. - */ -const AHD_SENSE_BUFSIZE 256 - -/* Target mode command processing constants */ -const CMD_GROUP_CODE_SHIFT 0x05 - -const STATUS_BUSY 0x08 -const STATUS_QUEUE_FULL 0x28 -const STATUS_PKT_SENSE 0xFF -const TARGET_DATA_IN 1 - -const SCB_TRANSFER_SIZE_FULL_LUN 56 -const SCB_TRANSFER_SIZE_1BYTE_LUN 48 -/* PKT_OVERRUN_BUFSIZE must be a multiple of 256 less than 64K */ -const PKT_OVERRUN_BUFSIZE 512 - -/* - * Timer parameters. - */ -const AHD_TIMER_US_PER_TICK 25 -const AHD_TIMER_MAX_TICKS 0xFFFF -const AHD_TIMER_MAX_US (AHD_TIMER_MAX_TICKS * AHD_TIMER_US_PER_TICK) - -/* - * Downloaded (kernel inserted) constants - */ -const SG_PREFETCH_CNT download -const SG_PREFETCH_CNT_LIMIT download -const SG_PREFETCH_ALIGN_MASK download -const SG_PREFETCH_ADDR_MASK download -const SG_SIZEOF download -const PKT_OVERRUN_BUFOFFSET download -const SCB_TRANSFER_SIZE download - -/* - * BIOS SCB offsets - */ -const NVRAM_SCB_OFFSET 0x2C diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx.seq linux-2.4.22/drivers/scsi/aic79xx/aic79xx.seq --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx.seq 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx.seq 1969-12-31 16:00:00.000000000 -0800 @@ -1,1889 +0,0 @@ -/* - * Adaptec U320 device driver firmware for Linux and FreeBSD. - * - * Copyright (c) 1994-2001 Justin T. Gibbs. - * Copyright (c) 2000-2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD$ - */ - -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $" -PATCH_ARG_LIST = "struct ahd_softc *ahd" -PREFIX = "ahd_" - -#include "aic79xx.reg" -#include "scsi_message.h" - -restart: -if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { - test SEQINTCODE, 0xFF jz idle_loop; - SET_SEQINTCODE(NO_SEQINT) -} - -idle_loop: - - if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { - /* - * Convert ERROR status into a sequencer - * interrupt to handle the case of an - * interrupt collision on the hardware - * setting of HWERR. - */ - test ERROR, 0xFF jz no_error_set; - SET_SEQINTCODE(SAW_HWERR) -no_error_set: - } - SET_MODE(M_SCSI, M_SCSI) - test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus; - test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus; - cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus; - /* - * ENSELO is cleared by a SELDO, so we must test for SELDO - * one last time. - */ -BEGIN_CRITICAL; - test SSTAT0, SELDO jnz select_out; -END_CRITICAL; - call start_selection; -idle_loop_checkbus: -BEGIN_CRITICAL; - test SSTAT0, SELDO jnz select_out; -END_CRITICAL; - test SSTAT0, SELDI jnz select_in; - test SCSIPHASE, ~DATA_PHASE_MASK jz idle_loop_check_nonpackreq; - test SCSISIGO, ATNO jz idle_loop_check_nonpackreq; - call unexpected_nonpkt_phase_find_ctxt; -idle_loop_check_nonpackreq: - test SSTAT2, NONPACKREQ jz . + 2; - call unexpected_nonpkt_phase_find_ctxt; - call idle_loop_gsfifo_in_scsi_mode; - call idle_loop_service_fifos; - call idle_loop_cchan; - jmp idle_loop; - -BEGIN_CRITICAL; -idle_loop_gsfifo: - SET_MODE(M_SCSI, M_SCSI) -idle_loop_gsfifo_in_scsi_mode: - test LQISTAT2, LQIGSAVAIL jz return; - /* - * We have received good status for this transaction. There may - * still be data in our FIFOs draining to the host. Setup - * monitoring of the draining process or complete the SCB. - */ -good_status_IU_done: - bmov SCBPTR, GSFIFO, 2; - clr SCB_SCSI_STATUS; - /* - * If a command completed before an attempted task management - * function completed, notify the host after disabling any - * pending select-outs. - */ - test SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally; - test SSTAT0, SELDO|SELINGO jnz . + 2; - and SCSISEQ0, ~ENSELO; - SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) -gsfifo_complete_normally: - or SCB_CONTROL, STATUS_RCVD; - - /* - * Since this status did not consume a FIFO, we have to - * be a bit more dilligent in how we check for FIFOs pertaining - * to this transaction. There are three states that a FIFO still - * transferring data may be in. - * - * 1) Configured and draining to the host, with a pending CLRCHN. - * 2) Configured and draining to the host, no pending CLRCHN. - * 3) Pending cfg4data, fifo not empty. - * - * Cases 1 and 2 can be detected by noticing that a longjmp is - * active for the FIFO and LONGJMP_SCB matches our SCB. In this - * case, we allow the routine servicing the FIFO to complete the SCB. - * - * Case 3 implies either a pending or yet to occur save data - * pointers for this same context in the other FIFO. So, if - * we detect case 2, we will properly defer the post of the SCB - * and achieve the desired result. The pending cfg4data will - * notice that status has been received and complete the SCB. - */ - test SCB_SGPTR, SG_LIST_NULL jz good_status_check_fifos; - /* - * All segments have been loaded (or no data transfer), so - * it is safe to complete the command. Since this was a - * cheap command to check for completion, loop to see if - * more entries can be removed from the GSFIFO. - */ - call complete; -END_CRITICAL; - jmp idle_loop_gsfifo_in_scsi_mode; -BEGIN_CRITICAL; -good_status_check_fifos: - clc; - bmov ARG_1, SCBPTR, 2; - SET_MODE(M_DFF0, M_DFF0) - call check_fifo; - jc return; - SET_MODE(M_DFF1, M_DFF1) - call check_fifo; - jc return; - SET_MODE(M_SCSI, M_SCSI) - jmp queue_scb_completion; -END_CRITICAL; - -idle_loop_service_fifos: - SET_MODE(M_DFF0, M_DFF0) - test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo; - call longjmp; -idle_loop_next_fifo: - SET_MODE(M_DFF1, M_DFF1) - test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp; - ret; - -idle_loop_cchan: - SET_MODE(M_CCHAN, M_CCHAN) - test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty; - mov LOCAL_HS_MAILBOX, HS_MAILBOX; - or QOFF_CTLSTA, HS_MAILBOX_ACT; -hs_mailbox_empty: -BEGIN_CRITICAL; - test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle; - test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog; - test CCSCBCTL, CCSCBDONE jz return; -END_CRITICAL; - /* FALLTHROUGH */ -scbdma_tohost_done: - test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone; - /* - * A complete SCB upload requires no intervention. - * The SCB is already on the COMPLETE_SCB list - * and its completion notification will now be - * handled just like any other SCB. - */ - and CCSCBCTL, ~(CCARREN|CCSCBEN) ret; -fill_qoutfifo_dmadone: - and CCSCBCTL, ~(CCARREN|CCSCBEN); - call qoutfifo_updated; - mvi COMPLETE_SCB_DMAINPROG_HEAD[1], SCB_LIST_NULL; - bmov QOUTFIFO_NEXT_ADDR, SCBHADDR, 4; - test QOFF_CTLSTA, SDSCB_ROLLOVR jz return; - bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4; - xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret; - -qoutfifo_updated: - /* - * If there are more commands waiting to be dma'ed - * to the host, always coaless. Otherwise honor the - * host's wishes. - */ - cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count; - cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count; - test LOCAL_HS_MAILBOX, ENINT_COALESS jz issue_cmdcmplt; - - /* - * If we have relatively few commands outstanding, don't - * bother waiting for another command to complete. - */ - test CMDS_PENDING[1], 0xFF jnz coaless_by_count; - /* Add -1 so that jnc means <= not just < */ - add A, -1, INT_COALESSING_MINCMDS; - add NONE, A, CMDS_PENDING; - jnc issue_cmdcmplt; - - /* - * If coalessing, only coaless up to the limit - * provided by the host driver. - */ -coaless_by_count: - mov A, INT_COALESSING_MAXCMDS; - add NONE, A, INT_COALESSING_CMDCOUNT; - jc issue_cmdcmplt; - /* - * If the timer is not currently active, - * fire it up. - */ - test INTCTL, SWTMINTMASK jz return; - bmov SWTIMER, INT_COALESSING_TIMER, 2; - mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; - or INTCTL, SWTMINTEN|SWTIMER_START; - and INTCTL, ~SWTMINTMASK ret; - -issue_cmdcmplt: - mvi INTSTAT, CMDCMPLT; - clr INT_COALESSING_CMDCOUNT; - or INTCTL, SWTMINTMASK ret; - -BEGIN_CRITICAL; -fetch_new_scb_inprog: - test CCSCBCTL, ARRDONE jz return; -fetch_new_scb_done: - and CCSCBCTL, ~(CCARREN|CCSCBEN); - bmov REG0, SCBPTR, 2; - clr A; - add CMDS_PENDING, 1; - adc CMDS_PENDING[1], A; - /* Update the next SCB address to download. */ - bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4; - mvi SCB_NEXT[1], SCB_LIST_NULL; - mvi SCB_NEXT2[1], SCB_LIST_NULL; - /* Increment our position in the QINFIFO. */ - mov NONE, SNSCB_QOFF; - /* - * SCBs that want to send messages are always - * queued independently. This ensures that they - * are at the head of the SCB list to select out - * to a target and we will see the MK_MESSAGE flag. - */ - test SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb; - shr SINDEX, 3, SCB_SCSIID; - and SINDEX, ~0x1; - mvi SINDEX[1], (WAITING_SCB_TAILS >> 8); - bmov DINDEX, SINDEX, 2; - bmov SCBPTR, SINDIR, 2; - bmov DINDIR, REG0, 2; - cmp SCBPTR[1], SCB_LIST_NULL je first_new_target_scb; - bmov SCB_NEXT, REG0, 2 ret; -first_new_target_scb: - cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb; - bmov SCBPTR, WAITING_TID_TAIL, 2; - bmov SCB_NEXT2, REG0, 2; - bmov WAITING_TID_TAIL, REG0, 2 ret; -first_new_scb: - bmov WAITING_TID_HEAD, REG0, 2; - bmov WAITING_TID_TAIL, REG0, 2 ret; -END_CRITICAL; - -scbdma_idle: - /* - * Give precedence to downloading new SCBs to execute - * unless select-outs are currently frozen. - */ - test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2; -BEGIN_CRITICAL; - test QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb; - cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb; - cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return; - /* FALLTHROUGH */ -fill_qoutfifo: - /* - * Keep track of the SCBs we are dmaing just - * in case the DMA fails or is aborted. - */ - mov A, QOUTFIFO_ENTRY_VALID_TAG; - bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2; - mvi CCSCBCTL, CCSCBRESET; - bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4; - bmov SCBPTR, COMPLETE_SCB_HEAD, 2; -fill_qoutfifo_loop: - mov CCSCBRAM, SCBPTR; - or CCSCBRAM, A, SCBPTR[1]; - mov NONE, SDSCB_QOFF; - inc INT_COALESSING_CMDCOUNT; - add CMDS_PENDING, -1; - adc CMDS_PENDING[1], -1; - cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done; - cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done; - test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done; - bmov SCBPTR, SCB_NEXT_COMPLETE, 2; - jmp fill_qoutfifo_loop; -fill_qoutfifo_done: - mov SCBHCNT, CCSCBADDR; - mvi CCSCBCTL, CCSCBEN|CCSCBRESET; - bmov COMPLETE_SCB_HEAD, SCB_NEXT_COMPLETE, 2; - mvi SCB_NEXT_COMPLETE[1], SCB_LIST_NULL ret; - -fetch_new_scb: - bmov SCBHADDR, NEXT_QUEUED_SCB_ADDR, 4; - mvi CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET jmp dma_scb; -dma_complete_scb: - bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2; - bmov SCBHADDR, SCB_BUSADDR, 4; - mvi CCARREN|CCSCBEN|CCSCBRESET call dma_scb; - /* - * Now that we've started the DMA, push us onto - * the normal completion queue to have our SCBID - * posted to the kernel. - */ - bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2; - bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; - bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; -END_CRITICAL; - -/* - * Either post or fetch an SCB from host memory. The caller - * is responsible for polling for transfer completion. - * - * Prerequisits: Mode == M_CCHAN - * SINDEX contains CCSCBCTL flags - * SCBHADDR set to Host SCB address - * SCBPTR set to SCB src location on "push" operations - */ -SET_SRC_MODE M_CCHAN; -SET_DST_MODE M_CCHAN; -dma_scb: - mvi SCBHCNT, SCB_TRANSFER_SIZE; - mov CCSCBCTL, SINDEX ret; - -BEGIN_CRITICAL; -setjmp_setscb: - bmov LONGJMP_SCB, SCBPTR, 2; -setjmp: - bmov LONGJMP_ADDR, STACK, 2 ret; -setjmp_inline: - bmov LONGJMP_ADDR, STACK, 2; -longjmp: - bmov STACK, LONGJMP_ADDR, 2 ret; -END_CRITICAL; - -/*************************** Chip Bug Work Arounds ****************************/ -/* - * Must disable interrupts when setting the mode pointer - * register as an interrupt occurring mid update will - * fail to store the new mode value for restoration on - * an iret. - */ -if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { -set_mode_work_around: - mvi SEQINTCTL, INTVEC1DSL; - mov MODE_PTR, SINDEX; - clr SEQINTCTL ret; - -toggle_dff_mode_work_around: - mvi SEQINTCTL, INTVEC1DSL; - xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); - clr SEQINTCTL ret; -} - - -if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { -set_seqint_work_around: - mov SEQINTCODE, SINDEX; - mvi SEQINTCODE, NO_SEQINT ret; -} - -/************************ Packetized LongJmp Routines *************************/ -SET_SRC_MODE M_SCSI; -SET_DST_MODE M_SCSI; -start_selection: -BEGIN_CRITICAL; - if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { - /* - * Razor #494 - * Rev A hardware fails to update LAST/CURR/NEXTSCB - * correctly after a packetized selection in several - * situations: - * - * 1) If only one command existed in the queue, the - * LAST/CURR/NEXTSCB are unchanged. - * - * 2) In a non QAS, protocol allowed phase change, - * the queue is shifted 1 too far. LASTSCB is - * the last SCB that was correctly processed. - * - * 3) In the QAS case, if the full list of commands - * was successfully sent, NEXTSCB is NULL and neither - * CURRSCB nor LASTSCB can be trusted. We must - * manually walk the list counting MAXCMDCNT elements - * to find the last SCB that was sent correctly. - * - * To simplify the workaround for this bug in SELDO - * handling, we initialize LASTSCB prior to enabling - * selection so we can rely on it even for case #1 above. - */ - bmov LASTSCB, WAITING_TID_HEAD, 2; - } - bmov CURRSCB, WAITING_TID_HEAD, 2; - bmov SCBPTR, WAITING_TID_HEAD, 2; - shr SELOID, 4, SCB_SCSIID; - /* - * If we want to send a message to the device, ensure - * we are selecting with atn irregardless of our packetized - * agreement. Since SPI4 only allows target reset or PPR - * messages if this is a packetized connection, the change - * to our negotiation table entry for this selection will - * be cleared when the message is acted on. - */ - test SCB_CONTROL, MK_MESSAGE jz . + 3; - mov NEGOADDR, SELOID; - or NEGCONOPTS, ENAUTOATNO; - or SCSISEQ0, ENSELO ret; -END_CRITICAL; - -/* - * Allocate a FIFO for a non-packetized transaction. - * In RevA hardware, both FIFOs must be free before we - * can allocate a FIFO for a non-packetized transaction. - */ -allocate_fifo_loop: - /* - * Do whatever work is required to free a FIFO. - */ - call idle_loop_service_fifos; - SET_MODE(M_SCSI, M_SCSI) -allocate_fifo: - if ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0) { - and A, FIFO0FREE|FIFO1FREE, DFFSTAT; - cmp A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop; - } else { - test DFFSTAT, FIFO1FREE jnz allocate_fifo1; - test DFFSTAT, FIFO0FREE jz allocate_fifo_loop; - mvi DFFSTAT, B_CURRFIFO_0; - SET_MODE(M_DFF0, M_DFF0) - bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; - } -SET_SRC_MODE M_SCSI; -SET_DST_MODE M_SCSI; -allocate_fifo1: - mvi DFFSTAT, CURRFIFO_1; - SET_MODE(M_DFF1, M_DFF1) - bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; - -/* - * We have been reselected as an initiator - * or selected as a target. - */ -SET_SRC_MODE M_SCSI; -SET_DST_MODE M_SCSI; -select_in: - if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { - /* - * This exposes a window whereby a - * busfree just after a selection will - * be missed, but there is no other safe - * way to enable busfree detection if - * the busfreerev function is broken. - */ - mvi CLRSINT1,CLRBUSFREE; - or SIMODE1, ENBUSFREE; - } - or SXFRCTL0, SPIOEN; - and SAVED_SCSIID, SELID_MASK, SELID; - and A, OID, IOWNID; - or SAVED_SCSIID, A; - mvi CLRSINT0, CLRSELDI; - jmp ITloop; - -/* - * We have successfully selected out. - * - * Clear SELDO. - * Dequeue all SCBs sent from the waiting queue - * Requeue all SCBs *not* sent to the tail of the waiting queue - * Take Razor #494 into account for above. - * - * In Packetized Mode: - * Return to the idle loop. Our interrupt handler will take - * care of any incoming L_Qs. - * - * In Non-Packetize Mode: - * Continue to our normal state machine. - */ -SET_SRC_MODE M_SCSI; -SET_DST_MODE M_SCSI; -select_out: -BEGIN_CRITICAL; - /* Clear out all SCBs that have been successfully sent. */ - if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { - /* - * For packetized, the LQO manager clears ENSELO on - * the assertion of SELDO. If we are non-packetized, - * LASTSCB and CURRSCB are acuate. - */ - test SCSISEQ0, ENSELO jnz use_lastscb; - - /* - * The update is correct for LQOSTAT1 errors. All - * but LQOBUSFREE are handled by kernel interrupts. - * If we see LQOBUSFREE, return to the idle loop. - * Once we are out of the select_out critical section, - * the kernel will cleanup the LQOBUSFREE and we will - * eventually restart the selection if appropriate. - */ - test LQOSTAT1, LQOBUSFREE jnz idle_loop; - - /* - * On a phase change oustside of packet boundaries, - * LASTSCB points to the currently active SCB context - * on the bus. - */ - test LQOSTAT2, LQOPHACHGOUTPKT jnz use_lastscb; - - /* - * If the hardware has traversed the whole list, NEXTSCB - * will be NULL, CURRSCB and LASTSCB cannot be trusted, - * but MAXCMDCNT is accurate. If we stop part way through - * the list or only had one command to issue, NEXTSCB[1] is - * not NULL and LASTSCB is the last command to go out. - */ - cmp NEXTSCB[1], SCB_LIST_NULL jne use_lastscb; - - /* - * Brute force walk. - */ - bmov SCBPTR, WAITING_TID_HEAD, 2; - mvi SEQINTCTL, INTVEC1DSL; - mvi MODE_PTR, MK_MODE(M_CFG, M_CFG); - mov A, MAXCMDCNT; - mvi MODE_PTR, MK_MODE(M_SCSI, M_SCSI); - clr SEQINTCTL; -find_lastscb_loop: - dec A; - test A, 0xFF jz found_last_sent_scb; - bmov SCBPTR, SCB_NEXT, 2; - jmp find_lastscb_loop; -use_lastscb: - bmov SCBPTR, LASTSCB, 2; -found_last_sent_scb: - bmov CURRSCB, SCBPTR, 2; -curscb_ww_done: - } else { - /* - * Untested - Verify with Rev B. - */ - bmov SCBPTR, CURRSCB, 2; - } - - /* - * Requeue any SCBs not sent, to the tail of the waiting Q. - */ - cmp SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done; - - /* - * We know that neither the per-TID list nor the list of - * TIDs is empty. Use this knowledge to our advantage. - */ - bmov REG0, SCB_NEXT, 2; - bmov SCBPTR, WAITING_TID_TAIL, 2; - bmov SCB_NEXT2, REG0, 2; - bmov WAITING_TID_TAIL, REG0, 2; - jmp select_out_inc_tid_q; - -select_out_list_done: - /* - * The whole list made it. Just clear our TID's tail pointer - * unless we were queued independently due to our need to - * send a message. - */ - test SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q; - shr DINDEX, 3, SCB_SCSIID; - or DINDEX, 1; /* Want only the second byte */ - mvi DINDEX[1], ((WAITING_SCB_TAILS) >> 8); - mvi DINDIR, SCB_LIST_NULL; -select_out_inc_tid_q: - bmov SCBPTR, WAITING_TID_HEAD, 2; - bmov WAITING_TID_HEAD, SCB_NEXT2, 2; - cmp WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2; - mvi WAITING_TID_TAIL[1], SCB_LIST_NULL; - bmov SCBPTR, CURRSCB, 2; - mvi CLRSINT0, CLRSELDO; - test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase; - test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase; - - /* - * If this is a packetized connection, return to our - * idle_loop and let our interrupt handler deal with - * any connection setup/teardown issues. The only - * exceptions are the case of MK_MESSAGE and task management - * SCBs. - */ - if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) { - /* - * In the A, the LQO manager transitions to LQOSTOP0 even if - * we have selected out with ATN asserted and the target - * REQs in a non-packet phase. - */ - test SCB_CONTROL, MK_MESSAGE jz select_out_no_message; - test SCSISIGO, ATNO jnz select_out_non_packetized; -select_out_no_message: - } - test LQOSTAT2, LQOSTOP0 jz select_out_non_packetized; - test SCB_TASK_MANAGEMENT, 0xFF jz idle_loop; - SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE) - jmp idle_loop; - -select_out_non_packetized: - /* Non packetized request. */ - and SCSISEQ0, ~ENSELO; - if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { - /* - * This exposes a window whereby a - * busfree just after a selection will - * be missed, but there is no other safe - * way to enable busfree detection if - * the busfreerev function is broken. - */ - mvi CLRSINT1,CLRBUSFREE; - or SIMODE1, ENBUSFREE; - } - mov SAVED_SCSIID, SCB_SCSIID; - mov SAVED_LUN, SCB_LUN; - mvi SEQ_FLAGS, NO_CDB_SENT; -END_CRITICAL; - or SXFRCTL0, SPIOEN; - - /* - * As soon as we get a successful selection, the target - * should go into the message out phase since we have ATN - * asserted. - */ - mvi MSG_OUT, MSG_IDENTIFYFLAG; - - /* - * Main loop for information transfer phases. Wait for the - * target to assert REQ before checking MSG, C/D and I/O for - * the bus phase. - */ -mesgin_phasemis: -ITloop: - call phase_lock; - - mov A, LASTPHASE; - - test A, ~P_DATAIN_DT jz p_data; - cmp A,P_COMMAND je p_command; - cmp A,P_MESGOUT je p_mesgout; - cmp A,P_STATUS je p_status; - cmp A,P_MESGIN je p_mesgin; - - SET_SEQINTCODE(BAD_PHASE) - jmp ITloop; /* Try reading the bus again. */ - -/* - * Command phase. Set up the DMA registers and let 'er rip. - */ -p_command: - test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay; - SET_SEQINTCODE(PROTO_VIOLATION) -p_command_okay: - test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) - jnz p_command_allocate_fifo; - /* - * Command retry. Free our current FIFO and - * re-allocate a FIFO so transfer state is - * reset. - */ -SET_SRC_MODE M_DFF1; -SET_DST_MODE M_DFF1; - mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; - SET_MODE(M_SCSI, M_SCSI) -p_command_allocate_fifo: - bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; - call allocate_fifo; -SET_SRC_MODE M_DFF1; -SET_DST_MODE M_DFF1; - add NONE, -17, SCB_CDB_LEN; - jnc p_command_embedded; -p_command_from_host: - bmov HADDR[0], SCB_CDB_PTR, 11; - mvi SG_CACHE_PRE, LAST_SEG; - mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); - jmp p_command_xfer; -p_command_embedded: - bmov SHCNT[0], SCB_CDB_LEN, 1; - bmov DFDAT, SCB_CDB_STORE, 16; - mvi DFCNTRL, SCSIEN; -p_command_xfer: - and SEQ_FLAGS, ~NO_CDB_SENT; - test DFCNTRL, SCSIEN jnz .; - /* - * DMA Channel automatically disabled. - * Don't allow a data phase if the command - * was not fully transferred. - */ - test SSTAT2, SDONE jnz ITloop; - or SEQ_FLAGS, NO_CDB_SENT; - jmp ITloop; - - -/* - * Status phase. Wait for the data byte to appear, then read it - * and store it into the SCB. - */ -SET_SRC_MODE M_SCSI; -SET_DST_MODE M_SCSI; -p_status: - test SEQ_FLAGS,NOT_IDENTIFIED jnz mesgin_proto_violation; -p_status_okay: - mov SCB_SCSI_STATUS, SCSIDAT; - or SCB_CONTROL, STATUS_RCVD; - jmp ITloop; - -/* - * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full - * indentify message sequence and send it to the target. The host may - * override this behavior by setting the MK_MESSAGE bit in the SCB - * control byte. This will cause us to interrupt the host and allow - * it to handle the message phase completely on its own. If the bit - * associated with this target is set, we will also interrupt the host, - * thereby allowing it to send a message on the next selection regardless - * of the transaction being sent. - * - * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. - * This is done to allow the host to send messages outside of an identify - * sequence while protecting the seqencer from testing the MK_MESSAGE bit - * on an SCB that might not be for the current nexus. (For example, a - * BDR message in responce to a bad reselection would leave us pointed to - * an SCB that doesn't have anything to do with the current target). - * - * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, - * bus device reset). - * - * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, - * in case the target decides to put us in this phase for some strange - * reason. - */ -p_mesgout_retry: - /* Turn on ATN for the retry */ - mvi SCSISIGO, ATNO; -p_mesgout: - mov SINDEX, MSG_OUT; - cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; - test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; -p_mesgout_identify: - or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN; - test SCB_CONTROL, DISCENB jnz . + 2; - and SINDEX, ~DISCENB; -/* - * Send a tag message if TAG_ENB is set in the SCB control block. - * Use SCB_NONPACKET_TAG as the tag value. - */ -p_mesgout_tag: - test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; - mov SCSIDAT, SINDEX; /* Send the identify message */ - call phase_lock; - cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; - and SCSIDAT,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; - call phase_lock; - cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; - mov SCBPTR jmp p_mesgout_onebyte; -/* - * Interrupt the driver, and allow it to handle this message - * phase and any required retries. - */ -p_mesgout_from_host: - cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; - jmp host_message_loop; - -p_mesgout_onebyte: - mvi CLRSINT1, CLRATNO; - mov SCSIDAT, SINDEX; - -/* - * If the next bus phase after ATN drops is message out, it means - * that the target is requesting that the last message(s) be resent. - */ - call phase_lock; - cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; - -p_mesgout_done: - mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ - mov LAST_MSG, MSG_OUT; - mvi MSG_OUT, MSG_NOOP; /* No message left */ - jmp ITloop; - -/* - * Message in phase. Bytes are read using Automatic PIO mode. - */ -p_mesgin: - /* read the 1st message byte */ - mvi ACCUM call inb_first; - - test A,MSG_IDENTIFYFLAG jnz mesgin_identify; - cmp A,MSG_DISCONNECT je mesgin_disconnect; - cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; - cmp ALLZEROS,A je mesgin_complete; - cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; - cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue; - cmp A,MSG_NOOP je mesgin_done; - -/* - * Pushed message loop to allow the kernel to - * run it's own message state engine. To avoid an - * extra nop instruction after signaling the kernel, - * we perform the phase_lock before checking to see - * if we should exit the loop and skip the phase_lock - * in the ITloop. Performing back to back phase_locks - * shouldn't hurt, but why do it twice... - */ -host_message_loop: - call phase_lock; /* Benign the first time through. */ - SET_SEQINTCODE(HOST_MSG_LOOP) - cmp RETURN_1, EXIT_MSG_LOOP je ITloop; - cmp RETURN_1, CONT_MSG_LOOP_WRITE jne . + 3; - mov SCSIDAT, RETURN_2; - jmp host_message_loop; - /* Must be CONT_MSG_LOOP_READ */ - mov NONE, SCSIDAT; /* ACK Byte */ - jmp host_message_loop; - -mesgin_ign_wide_residue: - mov SAVED_MODE, MODE_PTR; - SET_MODE(M_SCSI, M_SCSI) - shr NEGOADDR, 4, SAVED_SCSIID; - mov A, NEGCONOPTS; - RESTORE_MODE(SAVED_MODE) - test A, WIDEXFER jz mesgin_reject; - /* Pull the residue byte */ - mvi REG0 call inb_next; - cmp REG0, 0x01 jne mesgin_reject; - test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; - test DATA_COUNT_ODD, 0x1 jz mesgin_done; - jmp mesgin_done; - -mesgin_proto_violation: - SET_SEQINTCODE(PROTO_VIOLATION) - jmp mesgin_done; -mesgin_reject: - mvi MSG_MESSAGE_REJECT call mk_mesg; -mesgin_done: - mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ - jmp ITloop; - -#define INDEX_DISC_LIST(scsiid, lun) \ - and A, 0xC0, scsiid; \ - or SCBPTR, A, lun; \ - clr SCBPTR[1]; \ - and SINDEX, 0x30, scsiid; \ - shr SINDEX, 3; /* Multiply by 2 */ \ - add SINDEX, (SCB_DISCONNECTED_LISTS & 0xFF); \ - mvi SINDEX[1], ((SCB_DISCONNECTED_LISTS >> 8) & 0xFF) - -mesgin_identify: - /* - * Determine whether a target is using tagged or non-tagged - * transactions by first looking at the transaction stored in - * the per-device, disconnected array. If there is no untagged - * transaction for this target, this must be a tagged transaction. - */ - and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; - INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); - bmov DINDEX, SINDEX, 2; - bmov REG0, SINDIR, 2; - cmp REG0[1], SCB_LIST_NULL je snoop_tag; - /* Untagged. Clear the busy table entry and setup the SCB. */ - bmov DINDIR, ALLONES, 2; - bmov SCBPTR, REG0, 2; - jmp setup_SCB; - -/* - * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. - * If we get one, we use the tag returned to find the proper - * SCB. After receiving the tag, look for the SCB at SCB locations tag and - * tag + 256. - */ -snoop_tag: - if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { - or SEQ_FLAGS, 0x80; - } - mov NONE, SCSIDAT; /* ACK Identify MSG */ - call phase_lock; - if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { - or SEQ_FLAGS, 0x1; - } - cmp LASTPHASE, P_MESGIN jne not_found_ITloop; - if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { - or SEQ_FLAGS, 0x2; - } - cmp SCSIBUS, MSG_SIMPLE_Q_TAG jne not_found; -get_tag: - clr SCBPTR[1]; - mvi SCBPTR call inb_next; /* tag value */ -verify_scb: - test SCB_CONTROL,DISCONNECTED jz verify_other_scb; - mov A, SAVED_SCSIID; - cmp SCB_SCSIID, A jne verify_other_scb; - mov A, SAVED_LUN; - cmp SCB_LUN, A je setup_SCB_disconnected; -verify_other_scb: - xor SCBPTR[1], 1; - test SCBPTR[1], 0xFF jnz verify_scb; - jmp not_found; - -/* - * Ensure that the SCB the tag points to is for - * an SCB transaction to the reconnecting target. - */ -setup_SCB: - if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { - or SEQ_FLAGS, 0x10; - } - test SCB_CONTROL,DISCONNECTED jz not_found; -setup_SCB_disconnected: - and SCB_CONTROL,~DISCONNECTED; - clr SEQ_FLAGS; /* make note of IDENTIFY */ - test SCB_SGPTR, SG_LIST_NULL jnz . + 3; - bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; - call allocate_fifo; - /* See if the host wants to send a message upon reconnection */ - test SCB_CONTROL, MK_MESSAGE jz mesgin_done; - mvi HOST_MSG call mk_mesg; - jmp mesgin_done; - -not_found: - SET_SEQINTCODE(NO_MATCH) - jmp mesgin_done; - -not_found_ITloop: - SET_SEQINTCODE(NO_MATCH) - jmp ITloop; - -/* - * We received a "command complete" message. Put the SCB on the complete - * queue and trigger a completion interrupt via the idle loop. Before doing - * so, check to see if there - * is a residual or the status byte is something other than STATUS_GOOD (0). - * In either of these conditions, we upload the SCB back to the host so it can - * process this information. In the case of a non zero status byte, we - * additionally interrupt the kernel driver synchronously, allowing it to - * decide if sense should be retrieved. If the kernel driver wishes to request - * sense, it will fill the kernel SCB with a request sense command, requeue - * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting - * RETURN_1 to SEND_SENSE. - */ -mesgin_complete: - - /* - * If ATN is raised, we still want to give the target a message. - * Perhaps there was a parity error on this last message byte. - * Either way, the target should take us to message out phase - * and then attempt to complete the command again. We should use a - * critical section here to guard against a timeout triggering - * for this command and setting ATN while we are still processing - * the completion. - test SCSISIGI, ATNI jnz mesgin_done; - */ - - /* - * If we are identified and have successfully sent the CDB, - * any status will do. Optimize this fast path. - */ - test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation; - test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; - - /* - * If the target never sent an identify message but instead went - * to mesgin to give an invalid message, let the host abort us. - */ - test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; - - /* - * If we recevied good status but never successfully sent the - * cdb, abort the command. - */ - test SCB_SCSI_STATUS,0xff jnz complete_accepted; - test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation; -complete_accepted: - - /* - * See if we attempted to deliver a message but the target ingnored us. - */ - test SCB_CONTROL, MK_MESSAGE jz complete_nomsg; - SET_SEQINTCODE(MKMSG_FAILED) -complete_nomsg: - call queue_scb_completion; - jmp await_busfree; - -freeze_queue: - /* Cancel any pending select-out. */ - test SSTAT0, SELDO|SELINGO jnz . + 2; - and SCSISEQ0, ~ENSELO; - mov ACCUM_SAVE, A; - clr A; - add QFREEZE_COUNT, 1; - adc QFREEZE_COUNT[1], A; - or SEQ_FLAGS2, SELECTOUT_QFROZEN; - mov A, ACCUM_SAVE ret; - -queue_arg1_scb_completion: - SET_MODE(M_SCSI, M_SCSI) - bmov SCBPTR, ARG_1, 2; -queue_scb_completion: - if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0) { - /* - * Set MK_MESSAGE to trigger an abort should this SCB - * be referenced by a target even though it is not currently - * active. - */ - or SCB_CONTROL, MK_MESSAGE; - } - test SCB_SCSI_STATUS,0xff jnz bad_status; - /* - * Check for residuals - */ - test SCB_SGPTR, SG_LIST_NULL jnz complete; /* No xfer */ - test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ - test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; -complete: - bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; - bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; -bad_status: - cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb; - call freeze_queue; -upload_scb: - bmov SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2; - bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2; - or SCB_SGPTR, SG_STATUS_VALID ret; - -/* - * Is it a disconnect message? Set a flag in the SCB to remind us - * and await the bus going free. If this is an untagged transaction - * store the SCB id for it in our untagged target table for lookup on - * a reselction. - */ -mesgin_disconnect: - /* - * If ATN is raised, we still want to give the target a message. - * Perhaps there was a parity error on this last message byte - * or we want to abort this command. Either way, the target - * should take us to message out phase and then attempt to - * disconnect again. - * XXX - Wait for more testing. - test SCSISIGI, ATNI jnz mesgin_done; - */ - test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT - jnz mesgin_proto_violation; - or SCB_CONTROL,DISCONNECTED; - test SCB_CONTROL, TAG_ENB jnz await_busfree; -queue_disc_scb: - bmov REG0, SCBPTR, 2; - INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); - bmov DINDEX, SINDEX, 2; - bmov DINDIR, REG0, 2; - bmov SCBPTR, REG0, 2; - /* FALLTHROUGH */ -await_busfree: - and SIMODE1, ~ENBUSFREE; - if ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0) { - /* - * In the BUSFREEREV_BUG case, the - * busfree status was cleared at the - * beginning of the connection. - */ - mvi CLRSINT1,CLRBUSFREE; - } - mov NONE, SCSIDAT; /* Ack the last byte */ - test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) - jnz await_busfree_not_m_dff; -SET_SRC_MODE M_DFF1; -SET_DST_MODE M_DFF1; -await_busfree_clrchn: - mvi DFFSXFRCTL, CLRCHN; -await_busfree_not_m_dff: - call clear_target_state; - test SSTAT1,REQINIT|BUSFREE jz .; - test SSTAT1, BUSFREE jnz idle_loop; - SET_SEQINTCODE(MISSED_BUSFREE) - - -/* - * Save data pointers message: - * Copying RAM values back to SCB, for Save Data Pointers message, but - * only if we've actually been into a data phase to change them. This - * protects against bogus data in scratch ram and the residual counts - * since they are only initialized when we go into data_in or data_out. - * Ack the message as soon as possible. - */ -SET_SRC_MODE M_DFF1; -SET_DST_MODE M_DFF1; -mesgin_sdptrs: - mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ - test SEQ_FLAGS, DPHASE jz ITloop; - call save_pointers; - jmp ITloop; - -save_pointers: - /* - * If we are asked to save our position at the end of the - * transfer, just mark us at the end rather than perform a - * full save. - */ - test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz save_pointers_full; - or SCB_SGPTR, SG_LIST_NULL ret; - -save_pointers_full: - /* - * The SCB_DATAPTR becomes the current SHADDR. - * All other information comes directly from our residual - * state. - */ - bmov SCB_DATAPTR, SHADDR, 8; - bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8 ret; - -/* - * Restore pointers message? Data pointers are recopied from the - * SCB anytime we enter a data phase for the first time, so all - * we need to do is clear the DPHASE flag and let the data phase - * code do the rest. We also reset/reallocate the FIFO to make - * sure we have a clean start for the next data or command phase. - */ -mesgin_rdptrs: - and SEQ_FLAGS, ~DPHASE; - test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz msgin_rdptrs_get_fifo; - mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; - SET_MODE(M_SCSI, M_SCSI) -msgin_rdptrs_get_fifo: - call allocate_fifo; - jmp mesgin_done; - -clear_target_state: - mvi LASTPHASE, P_BUSFREE; - /* clear target specific flags */ - mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret; - -phase_lock: - test SCSIPHASE, 0xFF jz .; - test SSTAT1, SCSIPERR jnz phase_lock; -phase_lock_latch_phase: - and LASTPHASE, PHASE_MASK, SCSISIGI ret; - -/* - * Functions to read data in Automatic PIO mode. - * - * An ACK is not sent on input from the target until SCSIDATL is read from. - * So we wait until SCSIDATL is latched (the usual way), then read the data - * byte directly off the bus using SCSIBUSL. When we have pulled the ATN - * line, or we just want to acknowledge the byte, then we do a dummy read - * from SCISDATL. The SCSI spec guarantees that the target will hold the - * data byte on the bus until we send our ACK. - * - * The assumption here is that these are called in a particular sequence, - * and that REQ is already set when inb_first is called. inb_{first,next} - * use the same calling convention as inb. - */ -inb_next: - mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ -inb_next_wait: - /* - * If there is a parity error, wait for the kernel to - * see the interrupt and prepare our message response - * before continuing. - */ - test SCSIPHASE, 0xFF jz .; - test SSTAT1, SCSIPERR jnz inb_next_wait; -inb_next_check_phase: - and LASTPHASE, PHASE_MASK, SCSISIGI; - cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; -inb_first: - clr DINDEX[1]; - mov DINDEX,SINDEX; - mov DINDIR,SCSIBUS ret; /*read byte directly from bus*/ -inb_last: - mov NONE,SCSIDAT ret; /*dummy read from latch to ACK*/ - -mk_mesg: - mvi SCSISIGO, ATNO; - mov MSG_OUT,SINDEX ret; - -SET_SRC_MODE M_DFF1; -SET_DST_MODE M_DFF1; -disable_ccsgen: - test SG_STATE, FETCH_INPROG jz disable_ccsgen_fetch_done; - clr CCSGCTL; -disable_ccsgen_fetch_done: - clr SG_STATE ret; - -service_fifo: - /* - * Do we have any prefetch left??? - */ - test SG_STATE, SEGS_AVAIL jnz idle_sg_avail; - - /* - * Can this FIFO have access to the S/G cache yet? - */ - test CCSGCTL, SG_CACHE_AVAIL jz return; - - /* Did we just finish fetching segs? */ - test CCSGCTL, CCSGDONE jnz idle_sgfetch_complete; - - /* Are we actively fetching segments? */ - test CCSGCTL, CCSGENACK jnz return; - - /* - * We fetch a "cacheline aligned" and sized amount of data - * so we don't end up referencing a non-existant page. - * Cacheline aligned is in quotes because the kernel will - * set the prefetch amount to a reasonable level if the - * cacheline size is unknown. - */ - bmov SGHADDR, SCB_RESIDUAL_SGPTR, 4; - mvi SGHCNT, SG_PREFETCH_CNT; - if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) { - /* - * Need two instruction between "touches" of SGHADDR. - */ - nop; - } - and SGHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR; - mvi CCSGCTL, CCSGEN|SG_CACHE_AVAIL|CCSGRESET; - or SG_STATE, FETCH_INPROG ret; -idle_sgfetch_complete: - /* - * Guard against SG_CACHE_AVAIL activating during sg fetch - * request in the other FIFO. - */ - test SG_STATE, FETCH_INPROG jz return; - clr CCSGCTL; - and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR; - mvi SG_STATE, SEGS_AVAIL|LOADING_NEEDED; -idle_sg_avail: - /* Does the hardware have space for another SG entry? */ - test DFSTATUS, PRELOAD_AVAIL jz return; - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { - bmov HADDR, CCSGRAM, 8; - } else { - bmov HADDR, CCSGRAM, 4; - } - bmov HCNT, CCSGRAM, 3; - test HCNT[0], 0x1 jz . + 2; - xor DATA_COUNT_ODD, 0x1; - bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; - if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { - and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3]; - } - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { - /* Skip 4 bytes of pad. */ - add CCSGADDR, 4; - } -sg_advance: - clr A; /* add sizeof(struct scatter) */ - add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF; - adc SCB_RESIDUAL_SGPTR[1],A; - adc SCB_RESIDUAL_SGPTR[2],A; - adc SCB_RESIDUAL_SGPTR[3],A; - mov SINDEX, SCB_RESIDUAL_SGPTR[0]; - test DATA_COUNT_ODD, 0x1 jz . + 2; - or SINDEX, ODD_SEG; - test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3; - or SINDEX, LAST_SEG; - clr SG_STATE; - mov SG_CACHE_PRE, SINDEX; - /* - * Load the segment. Or in HDMAEN here too - * just in case HDMAENACK has not come true - * by the time this segment is loaded. If - * HDMAENACK is not true, this or will disable - * HDMAEN mid-transfer. We do not want to simply - * mvi our original settings as SCSIEN automatically - * de-asserts and we don't want to accidentally - * re-enable it. - */ - if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) { - /* - * Use SCSIENWRDIS so that SCSIEN is never - * modified by this operation. - */ - or DFCNTRL, PRELOADEN|SCSIENWRDIS|HDMAEN; - } else { - or DFCNTRL, PRELOADEN|HDMAEN; - } - /* - * Do we have another segment in the cache? - */ - add NONE, SG_PREFETCH_CNT_LIMIT, CCSGADDR; - jnc return; - and SG_STATE, ~SEGS_AVAIL ret; - -/* - * Initialize the DMA address and counter from the SCB. - */ -load_first_seg: - bmov HADDR, SCB_DATAPTR, 11; - and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0]; - and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0]; - test SCB_DATACNT[3], SG_LAST_SEG jz . + 2; - or REG_ISR, LAST_SEG; - test DATA_COUNT_ODD, 0x1 jz . + 2; - or REG_ISR, ODD_SEG; - mov SG_CACHE_PRE, REG_ISR; - mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); - /* - * Since we've are entering a data phase, we will - * rely on the SCB_RESID* fields. Initialize the - * residual and clear the full residual flag. - */ - and SCB_SGPTR[0], ~SG_FULL_RESID; - bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5; - /* If we need more S/G elements, tell the idle loop */ - test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz . + 2; - mvi SG_STATE, LOADING_NEEDED ret; - clr SG_STATE ret; - -p_data_handle_xfer: - call setjmp_setscb; - test SG_STATE, LOADING_NEEDED jnz service_fifo; -p_data_clear_handler: - or LONGJMP_ADDR[1], INVALID_ADDR ret; - -p_data: - test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed; - SET_SEQINTCODE(PROTO_VIOLATION) -p_data_allowed: - - test SEQ_FLAGS, DPHASE jz data_phase_initialize; - - /* - * If we re-enter the data phase after going through another - * phase, our transfer location has almost certainly been - * corrupted by the interveining, non-data, transfers. Ask - * the host driver to fix us up based on the transfer residual - * unless we already know that we should be bitbucketing. - */ - test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; - SET_SEQINTCODE(PDATA_REINIT) - jmp data_phase_inbounds; - -p_data_bitbucket: - /* - * Turn on `Bit Bucket' mode, wait until the target takes - * us to another phase, and then notify the host. - */ - mov SAVED_MODE, MODE_PTR; - test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) - jnz bitbucket_not_m_dff; - /* - * Ensure that any FIFO contents are cleared out and the - * FIFO free'd prior to starting the BITBUCKET. BITBUCKET - * doesn't discard data already in the FIFO. - */ - mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; - SET_MODE(M_SCSI, M_SCSI) -bitbucket_not_m_dff: - or SXFRCTL1,BITBUCKET; - /* Wait for non-data phase. */ - test SCSIPHASE, ~DATA_PHASE_MASK jz .; - and SXFRCTL1, ~BITBUCKET; - RESTORE_MODE(SAVED_MODE) -SET_SRC_MODE M_DFF1; -SET_DST_MODE M_DFF1; - SET_SEQINTCODE(DATA_OVERRUN) - jmp ITloop; - -data_phase_initialize: - test SCB_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; - call load_first_seg; -data_phase_inbounds: - /* We have seen a data phase at least once. */ - or SEQ_FLAGS, DPHASE; - mov SAVED_MODE, MODE_PTR; - test SG_STATE, LOADING_NEEDED jz data_group_dma_loop; - call p_data_handle_xfer; -data_group_dma_loop: - /* - * The transfer is complete if either the last segment - * completes or the target changes phase. Both conditions - * will clear SCSIEN. - */ - call idle_loop_service_fifos; - call idle_loop_cchan; - call idle_loop_gsfifo; - RESTORE_MODE(SAVED_MODE) - test DFCNTRL, SCSIEN jnz data_group_dma_loop; - -data_group_dmafinish: - /* - * The transfer has terminated either due to a phase - * change, and/or the completion of the last segment. - * We have two goals here. Do as much other work - * as possible while the data fifo drains on a read - * and respond as quickly as possible to the standard - * messages (save data pointers/disconnect and command - * complete) that usually follow a data phase. - */ - call calc_residual; - - /* - * Go ahead and shut down the DMA engine now. - */ - test DFCNTRL, DIRECTION jnz data_phase_finish; -data_group_fifoflush: - if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { - or DFCNTRL, FIFOFLUSH; - } - /* - * We have enabled the auto-ack feature. This means - * that the controller may have already transferred - * some overrun bytes into the data FIFO and acked them - * on the bus. The only way to detect this situation is - * to wait for LAST_SEG_DONE to come true on a completed - * transfer and then test to see if the data FIFO is - * non-empty. We know there is more data yet to transfer - * if SG_LIST_NULL is not yet set, thus there cannot be - * an overrun. - */ - test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_finish; - test SG_CACHE_SHADOW, LAST_SEG_DONE jz .; - test DFSTATUS, FIFOEMP jnz data_phase_finish; - /* Overrun */ - jmp p_data; -data_phase_finish: - /* - * If the target has left us in data phase, loop through - * the dma code again. We will only loop if there is a - * data overrun. - */ - if ((ahd->flags & AHD_TARGETROLE) != 0) { - test SSTAT0, TARGET jnz data_phase_done; - } - if ((ahd->flags & AHD_INITIATORROLE) != 0) { - test SSTAT1, REQINIT jz .; - test SCSIPHASE, DATA_PHASE_MASK jnz p_data; - } - -data_phase_done: - /* Kill off any pending prefetch */ - call disable_ccsgen; - or LONGJMP_ADDR[1], INVALID_ADDR; - - if ((ahd->flags & AHD_TARGETROLE) != 0) { - test SEQ_FLAGS, DPHASE_PENDING jz ITloop; - /* - and SEQ_FLAGS, ~DPHASE_PENDING; - * For data-in phases, wait for any pending acks from the - * initiator before changing phase. We only need to - * send Ignore Wide Residue messages for data-in phases. - test DFCNTRL, DIRECTION jz target_ITloop; - test SSTAT1, REQINIT jnz .; - test DATA_COUNT_ODD, 0x1 jz target_ITloop; - SET_MODE(M_SCSI, M_SCSI) - test NEGCONOPTS, WIDEXFER jz target_ITloop; - */ - /* - * Issue an Ignore Wide Residue Message. - mvi P_MESGIN|BSYO call change_phase; - mvi MSG_IGN_WIDE_RESIDUE call target_outb; - mvi 1 call target_outb; - jmp target_ITloop; - */ - } else { - jmp ITloop; - } - -/* - * We assume that, even though data may still be - * transferring to the host, that the SCSI side of - * the DMA engine is now in a static state. This - * allows us to update our notion of where we are - * in this transfer. - * - * If, by chance, we stopped before being able - * to fetch additional segments for this transfer, - * yet the last S/G was completely exhausted, - * call our idle loop until it is able to load - * another segment. This will allow us to immediately - * pickup on the next segment on the next data phase. - * - * If we happened to stop on the last segment, then - * our residual information is still correct from - * the idle loop and there is no need to perform - * any fixups. - */ -calc_residual: - test SG_CACHE_SHADOW, LAST_SEG jz residual_before_last_seg; - /* Record if we've consumed all S/G entries */ - test MDFFSTAT, SHVALID jz . + 2; - bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; - or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL ret; -residual_before_last_seg: - test MDFFSTAT, SHVALID jnz sgptr_fixup; - /* - * Can never happen from an interrupt as the packetized - * hardware will only interrupt us once SHVALID or - * LAST_SEG_DONE. - */ - call idle_loop_service_fifos; - RESTORE_MODE(SAVED_MODE) - jmp calc_residual; - -sgptr_fixup: - /* - * Fixup the residual next S/G pointer. The S/G preload - * feature of the chip allows us to load two elements - * in addition to the currently active element. We - * store the bottom byte of the next S/G pointer in - * the SG_CACHE_PTR register so we can restore the - * correct value when the DMA completes. If the next - * sg ptr value has advanced to the point where higher - * bytes in the address have been affected, fix them - * too. - */ - test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done; - test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done; - add SCB_RESIDUAL_SGPTR[1], -1; - adc SCB_RESIDUAL_SGPTR[2], -1; - adc SCB_RESIDUAL_SGPTR[3], -1; -sgptr_fixup_done: - and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; - clr DATA_COUNT_ODD; - test SG_CACHE_SHADOW, ODD_SEG jz . + 2; - or DATA_COUNT_ODD, 0x1; - clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */ - bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; - -export timer_isr: - call issue_cmdcmplt; - mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; - if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { - /* - * In H2A4, the mode pointer is not saved - * for intvec2, but is restored on iret. - * This can lead to the restoration of a - * bogus mode ptr. Manually clear the - * intmask bits and do a normal return - * to compensate. - */ - and SEQINTCTL, ~(INTMASK2|INTMASK1) ret; - } else { - or SEQINTCTL, IRET ret; - } - -export seq_isr: - nop; /* Jumps in the first ISR instruction fail on Rev A. */ - test SEQINTSRC, CFG4DATA jnz cfg4data_intr; - test SEQINTSRC, CFG4ISTAT jnz cfg4istat_intr; - test SEQINTSRC, SAVEPTRS jnz saveptr_intr; - test SEQINTSRC, CFG4ICMD jnz cfg4icmd_intr; - SET_SEQINTCODE(INVALID_SEQINT) - -/* - * There are two types of save pointers interrupts: - * The first is a snapshot save pointers where the current FIFO is not - * active and contains a snapshot of the current poniter information. - * This happens between packets in a stream for a single L_Q. Since we - * are not performing a pointer save, we can safely clear the channel - * so it can be used for other transactions. - * - * The second case is a save pointers on an active FIFO which occurs - * if the target changes to a new L_Q or busfrees/QAS' and the transfer - * has a residual. This should occur coincident with a ctxtdone. We - * disable the interrupt and allow our active routine to handle the - * save. - */ -saveptr_intr: - test DFCNTRL, HDMAENACK jz snapshot_saveptr; - and SEQIMODE, ~ENSAVEPTRS; - or SEQINTCTL, IRET ret; -snapshot_saveptr: - mvi DFFSXFRCTL, CLRCHN; - or SEQINTCTL, IRET ret; - -cfg4data_intr: - test SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun; - call load_first_seg; - call pkt_handle_xfer; - or SEQINTCTL, IRET ret; - -cfg4istat_intr: - call freeze_queue; - add NONE, -13, SCB_CDB_LEN; - jnc cfg4istat_have_sense_addr; - test SCB_CDB_LEN, SCB_CDB_LEN_PTR jnz cfg4istat_have_sense_addr; - /* - * Host sets up address/count and enables transfer. - */ - SET_SEQINTCODE(CFG4ISTAT_INTR) - jmp cfg4istat_setup_handler; -cfg4istat_have_sense_addr: - bmov HADDR, SCB_SENSE_BUSADDR, 4; - mvi HCNT[1], (AHD_SENSE_BUFSIZE >> 8); - mvi SG_CACHE_PRE, LAST_SEG; - mvi DFCNTRL, PRELOADEN|SCSIEN|HDMAEN; -cfg4istat_setup_handler: - /* - * Status pkt is transferring to host. - * Wait in idle loop for transfer to complete. - * If a command completed before an attempted - * task management function completed, notify the host. - */ - test SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func; - SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) -cfg4istat_no_taskmgmt_func: - call pkt_handle_status; - or SEQINTCTL, IRET ret; - -/* - * See if the target has gone on in this context creating an - * overrun condition. For the write case, the hardware cannot - * ack bytes until data are provided. So, if the target begins - * another packet without changing contexts, implying we are - * not sitting on a packet boundary, we are in an overrun - * situation. For the read case, the hardware will continue to - * ack bytes into the FIFO, and may even ack the last overrun packet - * into the FIFO. If the FIFO should become non-empty, we are in - * a read overrun case. - */ -#define check_overrun \ - /* Not on a packet boundary. */ \ - test MDFFSTAT, DLZERO jz pkt_handle_overrun; \ - test DFSTATUS, FIFOEMP jz pkt_handle_overrun - -pkt_handle_xfer: - bmov LONGJMP_SCB, SCBPTR, 2; - test SG_STATE, LOADING_NEEDED jz pkt_last_seg; - call setjmp; - test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; - test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; - test SCSISIGO, ATNO jnz . + 2; - test SSTAT2, NONPACKREQ jz pkt_service_fifo; - /* - * Defer handling of this NONPACKREQ until we - * can be sure it pertains to this FIFO. SAVEPTRS - * will not be asserted if the NONPACKREQ is for us, - * so we must simulate it if shaddow is valid. If - * shaddow is not valid, keep running this FIFO until we - * have satisfied the transfer by loading segments and - * waiting for either shaddow valid or last_seg_done. - */ - test MDFFSTAT, SHVALID jnz pkt_saveptrs; -pkt_service_fifo: - test SG_STATE, LOADING_NEEDED jnz service_fifo; -pkt_last_seg: - call setjmp; - test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; - test SG_CACHE_SHADOW, LAST_SEG_DONE jnz last_pkt_done; - test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; - test SCSISIGO, ATNO jnz . + 2; - test SSTAT2, NONPACKREQ jz return; - test MDFFSTAT, SHVALID jz return; - /* FALLTHROUGH */ - -/* - * Either a SAVEPTRS interrupt condition is pending for this FIFO - * or we have a pending nonpackreq for this FIFO. We differentiate - * between the two by capturing the state of the SAVEPTRS interrupt - * prior to clearing this status and executing the common code for - * these two cases. - */ -pkt_saveptrs: -BEGIN_CRITICAL; - if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { - or DFCNTRL, FIFOFLUSH; - } - mov REG0, SEQINTSRC; - call calc_residual; - call save_pointers; - mvi CLRSEQINTSRC, CLRSAVEPTRS; - call disable_ccsgen; - or SEQIMODE, ENSAVEPTRS; - test DFCNTRL, DIRECTION jnz pkt_saveptrs_check_status; - test DFSTATUS, FIFOEMP jnz pkt_saveptrs_check_status; - /* - * Keep a handler around for this FIFO until it drains - * to the host to guarantee that we don't complete the - * command to the host before the data arrives. - */ -pkt_saveptrs_wait_fifoemp: - call setjmp; - test DFSTATUS, FIFOEMP jz return; -pkt_saveptrs_check_status: - or LONGJMP_ADDR[1], INVALID_ADDR; - test REG0, SAVEPTRS jz unexpected_nonpkt_phase; - test SCB_CONTROL, STATUS_RCVD jz pkt_saveptrs_clrchn; - jmp last_pkt_complete; -pkt_saveptrs_clrchn: - mvi DFFSXFRCTL, CLRCHN ret; -END_CRITICAL; - -last_pkt_done: -BEGIN_CRITICAL; - if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { - or DFCNTRL, FIFOFLUSH; - } - test SCB_CONTROL, STATUS_RCVD jz wait_pkt_end; - check_overrun; - or SCB_SGPTR, SG_LIST_NULL; - /* - * It is safe to skip the other FIFO check since - * we defer CLRCHN on SAVEPTRS until all data in - * the FIFO are seen by the host and a CFG4DATA - * in this FIFO for the same context is held off - * by hardware. - */ -last_pkt_queue_scb: - or LONGJMP_ADDR[1], INVALID_ADDR; - bmov ARG_1, SCBPTR, 2; - mvi DFFSXFRCTL, CLRCHN; - jmp queue_arg1_scb_completion; - -last_pkt_complete: - bmov ARG_1, SCBPTR, 2; - mvi DFFSXFRCTL, CLRCHN; -check_other_fifo: - clc; - TOGGLE_DFF_MODE - call check_fifo; - jnc queue_arg1_scb_completion; -return: - ret; - -wait_pkt_end: - call setjmp; -END_CRITICAL; -wait_pkt_end_loop: - test SEQINTSRC, CTXTDONE jnz pkt_end; - check_overrun; - test SSTAT2, NONPACKREQ jz return; - test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; -pkt_end: -BEGIN_CRITICAL; - check_overrun; - or LONGJMP_ADDR[1], INVALID_ADDR; - or SCB_SGPTR, SG_LIST_NULL; - test SCB_CONTROL, STATUS_RCVD jnz last_pkt_complete; - mvi DFFSXFRCTL, CLRCHN ret; -END_CRITICAL; - -check_status_overrun: - test SHCNT[2], 0xFF jz status_IU_done; - SET_SEQINTCODE(STATUS_OVERRUN) - jmp status_IU_done; -pkt_handle_status: - call setjmp_setscb; - test MDFFSTAT, LASTSDONE jnz check_status_overrun; - test SEQINTSRC, CTXTDONE jz return; -status_IU_done: -BEGIN_CRITICAL; - if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { - or DFCNTRL, FIFOFLUSH; - } - or LONGJMP_ADDR[1], INVALID_ADDR; - mvi SCB_SCSI_STATUS, STATUS_PKT_SENSE; - or SCB_CONTROL, STATUS_RCVD; - jmp last_pkt_complete; -END_CRITICAL; - -SET_SRC_MODE M_DFF0; -SET_DST_MODE M_DFF0; -BEGIN_CRITICAL; -check_fifo: - test LONGJMP_ADDR[1], INVALID_ADDR jnz return; - mov A, ARG_2; - cmp LONGJMP_SCB[1], A jne return; - mov A, ARG_1; - cmp LONGJMP_SCB[0], A jne return; - stc ret; -END_CRITICAL; - -/* - * Nonpackreq is a polled status. It can come true in three situations: - * we have received an L_Q, we have sent one or more L_Qs, or there is no - * L_Q context associated with this REQ (REQ occurs immediately after a - * (re)selection). Routines that know that the context responsible for this - * nonpackreq call directly into unexpected_nonpkt_phase. In the case of the - * top level idle loop, we exhaust all active contexts prior to determining that - * we simply do not have the full I_T_L_Q for this phase. - */ -unexpected_nonpkt_phase_find_ctxt: - /* - * This nonpackreq is most likely associated with one of the tags - * in a FIFO or an outgoing LQ. Only treat it as an I_T only - * nonpackreq if we've cleared out the FIFOs and handled any - * pending SELDO. - */ -SET_SRC_MODE M_SCSI; -SET_DST_MODE M_SCSI; - and A, FIFO1FREE|FIFO0FREE, DFFSTAT; - cmp A, FIFO1FREE|FIFO0FREE jne return; - test SSTAT0, SELDO jnz return; - mvi SCBPTR[1], SCB_LIST_NULL; -unexpected_nonpkt_phase: - test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz . + 3; -SET_SRC_MODE M_DFF0; -SET_DST_MODE M_DFF0; - or LONGJMP_ADDR[1], INVALID_ADDR; - mvi DFFSXFRCTL, CLRCHN; - mvi CLRSINT2, CLRNONPACKREQ; - test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase; - SET_SEQINTCODE(ENTERING_NONPACK) - jmp ITloop; - -illegal_phase: - SET_SEQINTCODE(ILLEGAL_PHASE) - jmp ITloop; - -/* - * We have entered an overrun situation. If we have working - * BITBUCKET, flip that on and let the hardware eat any overrun - * data. Otherwise use an overrun buffer in the host to simulate - * BITBUCKET. - */ -pkt_handle_overrun: - SET_SEQINTCODE(CFG4OVERRUN) - call freeze_queue; - if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) { - or DFFSXFRCTL, DFFBITBUCKET; -SET_SRC_MODE M_DFF1; -SET_DST_MODE M_DFF1; - } else { - call load_overrun_buf; - mvi DFCNTRL, (HDMAEN|SCSIEN|PRELOADEN); - } - call setjmp; - if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { - test DFSTATUS, PRELOAD_AVAIL jz overrun_load_done; - call load_overrun_buf; - or DFCNTRL, PRELOADEN; -overrun_load_done: - test SEQINTSRC, CTXTDONE jnz pkt_overrun_end; - } else { - test DFFSXFRCTL, DFFBITBUCKET jz pkt_overrun_end; - } - test SSTAT2, NONPACKREQ jz return; -pkt_overrun_end: - or SCB_RESIDUAL_SGPTR, SG_OVERRUN_RESID; - test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; - test SCB_CONTROL, STATUS_RCVD jnz last_pkt_queue_scb; - mvi DFFSXFRCTL, CLRCHN ret; - -if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { -load_overrun_buf: - /* - * Load a dummy segment if preload space is available. - */ - mov HADDR[0], SHARED_DATA_ADDR; - add HADDR[1], PKT_OVERRUN_BUFOFFSET, SHARED_DATA_ADDR[1]; - mov ACCUM_SAVE, A; - clr A; - adc HADDR[2], A, SHARED_DATA_ADDR[2]; - adc HADDR[3], A, SHARED_DATA_ADDR[3]; - mov A, ACCUM_SAVE; - bmov HADDR[4], ALLZEROS, 4; - /* PKT_OVERRUN_BUFSIZE is a multiple of 256 */ - clr HCNT[0]; - mvi HCNT[1], ((PKT_OVERRUN_BUFSIZE >> 8) & 0xFF); - clr HCNT[2] ret; -} - -cfg4icmd_intr: diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_core.c linux-2.4.22/drivers/scsi/aic79xx/aic79xx_core.c --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_core.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_core.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,9505 +0,0 @@ -/* - * Core routines and tables shareable across OS platforms. - * - * Copyright (c) 1994-2002 Justin T. Gibbs. - * Copyright (c) 2000-2003 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#156 $ - * - * $FreeBSD$ - */ - -#ifdef __linux__ -#include "aic79xx_osm.h" -#include "aic79xx_inline.h" -#include "aicasm/aicasm_insformat.h" -#else -#include -#include -#include -#endif - -/******************************** Globals *************************************/ -struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq); - -/***************************** Lookup Tables **********************************/ -char *ahd_chip_names[] = -{ - "NONE", - "aic7901", - "aic7902", - "aic7901A" -}; -static const u_int num_chip_names = NUM_ELEMENTS(ahd_chip_names); - -/* - * Hardware error codes. - */ -struct ahd_hard_error_entry { - uint8_t errno; - char *errmesg; -}; - -static struct ahd_hard_error_entry ahd_hard_errors[] = { - { DSCTMOUT, "Discard Timer has timed out" }, - { ILLOPCODE, "Illegal Opcode in sequencer program" }, - { SQPARERR, "Sequencer Parity Error" }, - { DPARERR, "Data-path Parity Error" }, - { MPARERR, "Scratch or SCB Memory Parity Error" }, - { CIOPARERR, "CIOBUS Parity Error" }, -}; -static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors); - -static struct ahd_phase_table_entry ahd_phase_table[] = -{ - { P_DATAOUT, MSG_NOOP, "in Data-out phase" }, - { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" }, - { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" }, - { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" }, - { P_COMMAND, MSG_NOOP, "in Command phase" }, - { P_MESGOUT, MSG_NOOP, "in Message-out phase" }, - { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" }, - { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" }, - { P_BUSFREE, MSG_NOOP, "while idle" }, - { 0, MSG_NOOP, "in unknown phase" } -}; - -/* - * In most cases we only wish to itterate over real phases, so - * exclude the last element from the count. - */ -static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1; - -/* Our Sequencer Program */ -#include "aic79xx_seq.h" - -/**************************** Function Declarations ***************************/ -static void ahd_handle_transmission_error(struct ahd_softc *ahd); -static void ahd_handle_lqiphase_error(struct ahd_softc *ahd, - u_int lqistat1); -static int ahd_handle_pkt_busfree(struct ahd_softc *ahd, - u_int busfreetime); -static int ahd_handle_nonpkt_busfree(struct ahd_softc *ahd); -static void ahd_handle_proto_violation(struct ahd_softc *ahd); -static void ahd_force_renegotiation(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); - -static struct ahd_tmode_tstate* - ahd_alloc_tstate(struct ahd_softc *ahd, - u_int scsi_id, char channel); -#ifdef AHD_TARGET_MODE -static void ahd_free_tstate(struct ahd_softc *ahd, - u_int scsi_id, char channel, int force); -#endif -static void ahd_devlimited_syncrate(struct ahd_softc *ahd, - struct ahd_initiator_tinfo *, - u_int *period, - u_int *ppr_options, - role_t role); -static void ahd_update_neg_table(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - struct ahd_transinfo *tinfo); -static void ahd_update_pending_scbs(struct ahd_softc *ahd); -static void ahd_fetch_devinfo(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static void ahd_scb_devinfo(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - struct scb *scb); -static void ahd_setup_initiator_msgout(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - struct scb *scb); -static void ahd_build_transfer_msg(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static void ahd_construct_sdtr(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - u_int period, u_int offset); -static void ahd_construct_wdtr(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - u_int bus_width); -static void ahd_construct_ppr(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - u_int period, u_int offset, - u_int bus_width, u_int ppr_options); -static void ahd_clear_msg_state(struct ahd_softc *ahd); -static void ahd_handle_message_phase(struct ahd_softc *ahd); -typedef enum { - AHDMSG_1B, - AHDMSG_2B, - AHDMSG_EXT -} ahd_msgtype; -static int ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, - u_int msgval, int full); -static int ahd_parse_msg(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static int ahd_handle_msg_reject(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static void ahd_handle_ign_wide_residue(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static void ahd_reinitialize_dataptrs(struct ahd_softc *ahd); -static void ahd_handle_devreset(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - u_int lun, cam_status status, - char *message, int verbose_level); -#if AHD_TARGET_MODE -static void ahd_setup_target_msgin(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, - struct scb *scb); -#endif - -static u_int ahd_sglist_size(struct ahd_softc *ahd); -static u_int ahd_sglist_allocsize(struct ahd_softc *ahd); -static bus_dmamap_callback_t - ahd_dmamap_cb; -static void ahd_initialize_hscbs(struct ahd_softc *ahd); -static int ahd_init_scbdata(struct ahd_softc *ahd); -static void ahd_fini_scbdata(struct ahd_softc *ahd); -static void ahd_setup_iocell_workaround(struct ahd_softc *ahd); -static void ahd_iocell_first_selection(struct ahd_softc *ahd); -static void ahd_add_col_list(struct ahd_softc *ahd, - struct scb *scb, u_int col_idx); -static void ahd_rem_col_list(struct ahd_softc *ahd, - struct scb *scb); -static void ahd_chip_init(struct ahd_softc *ahd); -static void ahd_qinfifo_requeue(struct ahd_softc *ahd, - struct scb *prev_scb, - struct scb *scb); -static int ahd_qinfifo_count(struct ahd_softc *ahd); -static int ahd_search_scb_list(struct ahd_softc *ahd, int target, - char channel, int lun, u_int tag, - role_t role, uint32_t status, - ahd_search_action action, - u_int *list_head, u_int tid); -static void ahd_stitch_tid_list(struct ahd_softc *ahd, - u_int tid_prev, u_int tid_cur, - u_int tid_next); -static void ahd_add_scb_to_free_list(struct ahd_softc *ahd, - u_int scbid); -static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, - u_int prev, u_int next, u_int tid); -static void ahd_reset_current_bus(struct ahd_softc *ahd); -static ahd_callback_t ahd_reset_poll; -static ahd_callback_t ahd_stat_timer; -#ifdef AHD_DUMP_SEQ -static void ahd_dumpseq(struct ahd_softc *ahd); -#endif -static void ahd_loadseq(struct ahd_softc *ahd); -static int ahd_check_patch(struct ahd_softc *ahd, - struct patch **start_patch, - u_int start_instr, u_int *skip_addr); -static u_int ahd_resolve_seqaddr(struct ahd_softc *ahd, - u_int address); -static void ahd_download_instr(struct ahd_softc *ahd, - u_int instrptr, uint8_t *dconsts); -static int ahd_probe_stack_size(struct ahd_softc *ahd); -#ifdef AHD_TARGET_MODE -static void ahd_queue_lstate_event(struct ahd_softc *ahd, - struct ahd_tmode_lstate *lstate, - u_int initiator_id, - u_int event_type, - u_int event_arg); -static void ahd_update_scsiid(struct ahd_softc *ahd, - u_int targid_mask); -static int ahd_handle_target_cmd(struct ahd_softc *ahd, - struct target_cmd *cmd); -#endif - -/******************************** Private Inlines *****************************/ -static __inline void ahd_assert_atn(struct ahd_softc *ahd); -static __inline int ahd_currently_packetized(struct ahd_softc *ahd); -static __inline int ahd_set_active_fifo(struct ahd_softc *ahd); - -static __inline void -ahd_assert_atn(struct ahd_softc *ahd) -{ - ahd_outb(ahd, SCSISIGO, ATNO); -} - -/* - * Determine if the current connection has a packetized - * agreement. This does not necessarily mean that we - * are currently in a packetized transfer. We could - * just as easily be sending or receiving a message. - */ -static __inline int -ahd_currently_packetized(struct ahd_softc *ahd) -{ - ahd_mode_state saved_modes; - int packetized; - - saved_modes = ahd_save_modes(ahd); - if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) { - /* - * The packetized bit refers to the last - * connection, not the current one. Check - * for non-zero LQISTATE instead. - */ - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - packetized = ahd_inb(ahd, LQISTATE) != 0; - } else { - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED; - } - ahd_restore_modes(ahd, saved_modes); - return (packetized); -} - -static __inline int -ahd_set_active_fifo(struct ahd_softc *ahd) -{ - u_int active_fifo; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO; - switch (active_fifo) { - case 0: - case 1: - ahd_set_modes(ahd, active_fifo, active_fifo); - return (1); - default: - return (0); - } -} - -/************************* Sequencer Execution Control ************************/ -/* - * Restart the sequencer program from address zero - */ -void -ahd_restart(struct ahd_softc *ahd) -{ - - ahd_pause(ahd); - - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - - /* No more pending messages */ - ahd_clear_msg_state(ahd); - ahd_outb(ahd, SCSISIGO, 0); /* De-assert BSY */ - ahd_outb(ahd, MSG_OUT, MSG_NOOP); /* No message to send */ - ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET); - ahd_outb(ahd, SEQINTCTL, 0); - ahd_outb(ahd, LASTPHASE, P_BUSFREE); - ahd_outb(ahd, SEQ_FLAGS, 0); - ahd_outb(ahd, SAVED_SCSIID, 0xFF); - ahd_outb(ahd, SAVED_LUN, 0xFF); - - /* - * Ensure that the sequencer's idea of TQINPOS - * matches our own. The sequencer increments TQINPOS - * only after it sees a DMA complete and a reset could - * occur before the increment leaving the kernel to believe - * the command arrived but the sequencer to not. - */ - ahd_outb(ahd, TQINPOS, ahd->tqinfifonext); - - /* Always allow reselection */ - ahd_outb(ahd, SCSISEQ1, - ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP)); - /* Ensure that no DMA operations are in progress */ - ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); - ahd_outb(ahd, SCBHCNT, 0); - ahd_outb(ahd, CCSCBCTL, CCSCBRESET); - ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); - ahd_unpause(ahd); -} - -void -ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) -{ - ahd_mode_state saved_modes; - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_FIFOS) != 0) - printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo); -#endif - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, fifo, fifo); - ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT); - if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) - ahd_outb(ahd, CCSGCTL, CCSGRESET); - ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); - ahd_outb(ahd, SG_STATE, 0); - ahd_restore_modes(ahd, saved_modes); -} - -/************************* Input/Output Queues ********************************/ -/* - * Flush and completed commands that are sitting in the command - * complete queues down on the chip but have yet to be dma'ed back up. - */ -void -ahd_flush_qoutfifo(struct ahd_softc *ahd) -{ - struct scb *scb; - ahd_mode_state saved_modes; - u_int saved_scbptr; - u_int ccscbctl; - u_int scbid; - u_int next_scbid; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); - saved_scbptr = ahd_get_scbptr(ahd); - - /* - * Wait for any inprogress DMA to complete and clear DMA state - * if this if for an SCB in the qinfifo. - */ - while ((ccscbctl = ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) { - - if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) { - if ((ccscbctl & ARRDONE) != 0) - break; - } else if ((ccscbctl & CCSCBDONE) != 0) - break; - ahd_delay(200); - } - if ((ccscbctl & CCSCBDIR) != 0) - ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN)); - - /* - * Complete any SCBs that just finished being - * DMA'ed into the qoutfifo. - */ - ahd_run_qoutfifo(ahd); - - /* - * Manually update/complete any completed SCBs that are waiting to be - * DMA'ed back up to the host. - */ - scbid = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); - while (!SCBID_IS_NULL(scbid)) { - uint8_t *hscb_ptr; - u_int i; - - ahd_set_scbptr(ahd, scbid); - next_scbid = ahd_inw(ahd, SCB_NEXT_COMPLETE); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("%s: Warning - DMA-up and complete " - "SCB %d invalid\n", ahd_name(ahd), scbid); - continue; - } - hscb_ptr = (uint8_t *)scb->hscb; - for (i = 0; i < sizeof(struct hardware_scb); i++) - *hscb_ptr++ = ahd_inb(ahd, SCB_BASE + i); - - ahd_complete_scb(ahd, scb); - scbid = next_scbid; - } - ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); - - scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD); - while (!SCBID_IS_NULL(scbid)) { - - ahd_set_scbptr(ahd, scbid); - next_scbid = ahd_inw(ahd, SCB_NEXT_COMPLETE); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("%s: Warning - Complete SCB %d invalid\n", - ahd_name(ahd), scbid); - continue; - } - - ahd_complete_scb(ahd, scb); - scbid = next_scbid; - } - ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); - ahd_set_scbptr(ahd, saved_scbptr); - - /* - * Flush the good status FIFO for compelted packetized commands. - */ - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) { - scbid = (ahd_inb(ahd, GSFIFO+1) << 8) - | ahd_inb(ahd, GSFIFO); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("%s: Warning - GSFIFO SCB %d invalid\n", - ahd_name(ahd), scbid); - continue; - } - ahd_complete_scb(ahd, scb); - } - - /* - * Restore state. - */ - ahd_restore_modes(ahd, saved_modes); - ahd->flags |= AHD_UPDATE_PEND_CMDS; -} - -void -ahd_run_qoutfifo(struct ahd_softc *ahd) -{ - struct scb *scb; - u_int scb_index; - - if ((ahd->flags & AHD_RUNNING_QOUTFIFO) != 0) - panic("ahd_run_qoutfifo recursion"); - ahd->flags |= AHD_RUNNING_QOUTFIFO; - ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD); - while ((ahd->qoutfifo[ahd->qoutfifonext] - & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) { - - scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext] - & ~QOUTFIFO_ENTRY_VALID_LE); - scb = ahd_lookup_scb(ahd, scb_index); - if (scb == NULL) { - printf("%s: WARNING no command for scb %d " - "(cmdcmplt)\nQOUTPOS = %d\n", - ahd_name(ahd), scb_index, - ahd->qoutfifonext); - ahd_dump_card_state(ahd); - } else - ahd_complete_scb(ahd, scb); - - ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1); - if (ahd->qoutfifonext == 0) - ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE; - } - ahd->flags &= ~AHD_RUNNING_QOUTFIFO; -} - -/************************* Interrupt Handling *********************************/ -void -ahd_handle_hwerrint(struct ahd_softc *ahd) -{ - /* - * Some catastrophic hardware error has occurred. - * Print it for the user and disable the controller. - */ - int i; - int error; - - error = ahd_inb(ahd, ERROR); - for (i = 0; i < num_errors; i++) { - if ((error & ahd_hard_errors[i].errno) != 0) - printf("%s: hwerrint, %s\n", - ahd_name(ahd), ahd_hard_errors[i].errmesg); - } - - ahd_dump_card_state(ahd); - panic("BRKADRINT"); - - /* Tell everyone that this HBA is no longer availible */ - ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, - CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN, - CAM_NO_HBA); - - /* Tell the system that this controller has gone away. */ - ahd_free(ahd); -} - -void -ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) -{ - u_int seqintcode; - - /* - * Save the sequencer interrupt code and clear the SEQINT - * bit. We will unpause the sequencer, if appropriate, - * after servicing the request. - */ - seqintcode = ahd_inb(ahd, SEQINTCODE); - ahd_outb(ahd, CLRINT, CLRSEQINT); - if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { - /* - * Unpause the sequencer and let it clear - * SEQINT by writing NO_SEQINT to it. This - * will cause the sequencer to be paused again, - * which is the expected state of this routine. - */ - ahd_unpause(ahd); - while (!ahd_is_paused(ahd)) - ; - ahd_outb(ahd, CLRINT, CLRSEQINT); - } - ahd_update_modes(ahd); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("%s: Handle Seqint Called for code %d\n", - ahd_name(ahd), seqintcode); -#endif - switch (seqintcode) { - case ENTERING_NONPACK: - { - struct scb *scb; - u_int scbid; - - AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), - ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - /* - * Somehow need to know if this - * is from a selection or reselection. - * From that, we can termine target - * ID so we at least have an I_T nexus. - */ - } else { - ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); - ahd_outb(ahd, SAVED_LUN, scb->hscb->lun); - ahd_outb(ahd, SEQ_FLAGS, 0x0); - } - if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0 - && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) { - /* - * Phase change after read stream with - * CRC error with P0 asserted on last - * packet. - */ -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) - printf("%s: Assuming LQIPHASE_NLQ with " - "P0 assertion\n", ahd_name(ahd)); -#endif - } -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) - printf("%s: Entering NONPACK\n", ahd_name(ahd)); -#endif - break; - } - case INVALID_SEQINT: - printf("%s: Invalid Sequencer interrupt occurred.\n", - ahd_name(ahd)); - ahd_dump_card_state(ahd); - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - break; - case STATUS_OVERRUN: - { - printf("%s: Status Overrun", ahd_name(ahd)); - ahd_dump_card_state(ahd); - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - break; - } - case CFG4ISTAT_INTR: - { - struct scb *scb; - u_int scbid; - - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - ahd_dump_card_state(ahd); - printf("CFG4ISTAT: Free SCB %d referenced", scbid); - panic("For safety"); - } - ahd_outq(ahd, HADDR, scb->sense_busaddr); - ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE); - ahd_outb(ahd, HCNT + 2, 0); - ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG); - ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN); - break; - } - case ILLEGAL_PHASE: - { - u_int bus_phase; - - bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; - printf("%s: ILLEGAL_PHASE 0x%x\n", - ahd_name(ahd), bus_phase); - - switch (bus_phase) { - case P_DATAOUT: - case P_DATAIN: - case P_DATAOUT_DT: - case P_DATAIN_DT: - case P_MESGOUT: - case P_STATUS: - case P_MESGIN: - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - printf("%s: Issued Bus Reset.\n", ahd_name(ahd)); - break; - case P_COMMAND: - { - struct ahd_devinfo devinfo; - struct scb *scb; - struct ahd_initiator_tinfo *targ_info; - struct ahd_tmode_tstate *tstate; - struct ahd_transinfo *tinfo; - u_int scbid; - - /* - * If a target takes us into the command phase - * assume that it has been externally reset and - * has thus lost our previous packetized negotiation - * agreement. Since we have not sent an identify - * message and may not have fully qualified the - * connection, we change our command to TUR, assert - * ATN and ABORT the task when we go to message in - * phase. The OSM will see the REQUEUE_REQUEST - * status and retry the command. - */ - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("Invalid phase with no valid SCB. " - "Resetting bus.\n"); - ahd_reset_channel(ahd, 'A', - /*Initiate Reset*/TRUE); - break; - } - ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb), - SCB_GET_TARGET(ahd, scb), - SCB_GET_LUN(scb), - SCB_GET_CHANNEL(ahd, scb), - ROLE_INITIATOR); - targ_info = ahd_fetch_transinfo(ahd, - devinfo.channel, - devinfo.our_scsiid, - devinfo.target, - &tstate); - tinfo = &targ_info->curr; - ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_ACTIVE, /*paused*/TRUE); - ahd_set_syncrate(ahd, &devinfo, /*period*/0, - /*offset*/0, /*ppr_options*/0, - AHD_TRANS_ACTIVE, /*paused*/TRUE); - ahd_outb(ahd, SCB_CDB_STORE, 0); - ahd_outb(ahd, SCB_CDB_STORE+1, 0); - ahd_outb(ahd, SCB_CDB_STORE+2, 0); - ahd_outb(ahd, SCB_CDB_STORE+3, 0); - ahd_outb(ahd, SCB_CDB_STORE+4, 0); - ahd_outb(ahd, SCB_CDB_STORE+5, 0); - ahd_outb(ahd, SCB_CDB_LEN, 6); - scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); - scb->hscb->control |= MK_MESSAGE; - ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); - /* - * The lun is 0, regardless of the SCB's lun - * as we have not sent an identify message. - */ - ahd_outb(ahd, SAVED_LUN, 0); - ahd_outb(ahd, SEQ_FLAGS, 0); - ahd_assert_atn(ahd); - scb->flags &= ~(SCB_PACKETIZED); - scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT; - ahd_freeze_devq(ahd, scb); - ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); - ahd_freeze_scb(scb); - - /* - * Allow the sequencer to continue with - * non-pack processing. - */ - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT); - if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { - ahd_outb(ahd, CLRLQOINT1, 0); - } -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { - ahd_print_path(ahd, scb); - printf("Unexpected command phase from " - "packetized target\n"); - } -#endif - break; - } - } - break; - } - case CFG4OVERRUN: - { - struct scb *scb; - u_int scb_index; - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { - printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd), - ahd_inb(ahd, MODE_PTR)); - } -#endif - scb_index = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scb_index); - if (scb == NULL) { - /* - * Attempt to transfer to an SCB that is - * not outstanding. - */ - ahd_assert_atn(ahd); - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd->msgout_buf[0] = MSG_ABORT_TASK; - ahd->msgout_len = 1; - ahd->msgout_index = 0; - ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; - /* - * Clear status received flag to prevent any - * attempt to complete this bogus SCB. - */ - ahd_outb(ahd, SCB_CONTROL, - ahd_inb(ahd, SCB_CONTROL) & ~STATUS_RCVD); - } - break; - } - case DUMP_CARD_STATE: - { - ahd_dump_card_state(ahd); - break; - } - case PDATA_REINIT: - { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { - printf("%s: PDATA_REINIT - DFCNTRL = 0x%x " - "SG_CACHE_SHADOW = 0x%x\n", - ahd_name(ahd), ahd_inb(ahd, DFCNTRL), - ahd_inb(ahd, SG_CACHE_SHADOW)); - } -#endif - ahd_reinitialize_dataptrs(ahd); - break; - } - case HOST_MSG_LOOP: - { - struct ahd_devinfo devinfo; - - /* - * The sequencer has encountered a message phase - * that requires host assistance for completion. - * While handling the message phase(s), we will be - * notified by the sequencer after each byte is - * transfered so we can track bus phase changes. - * - * If this is the first time we've seen a HOST_MSG_LOOP - * interrupt, initialize the state of the host message - * loop. - */ - ahd_fetch_devinfo(ahd, &devinfo); - if (ahd->msg_type == MSG_TYPE_NONE) { - struct scb *scb; - u_int scb_index; - u_int bus_phase; - - bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; - if (bus_phase != P_MESGIN - && bus_phase != P_MESGOUT) { - printf("ahd_intr: HOST_MSG_LOOP bad " - "phase 0x%x\n", bus_phase); - /* - * Probably transitioned to bus free before - * we got here. Just punt the message. - */ - ahd_dump_card_state(ahd); - ahd_clear_intstat(ahd); - ahd_restart(ahd); - return; - } - - scb_index = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scb_index); - if (devinfo.role == ROLE_INITIATOR) { - if (bus_phase == P_MESGOUT) - ahd_setup_initiator_msgout(ahd, - &devinfo, - scb); - else { - ahd->msg_type = - MSG_TYPE_INITIATOR_MSGIN; - ahd->msgin_index = 0; - } - } -#if AHD_TARGET_MODE - else { - if (bus_phase == P_MESGOUT) { - ahd->msg_type = - MSG_TYPE_TARGET_MSGOUT; - ahd->msgin_index = 0; - } - else - ahd_setup_target_msgin(ahd, - &devinfo, - scb); - } -#endif - } - - ahd_handle_message_phase(ahd); - break; - } - case NO_MATCH: - { - /* Ensure we don't leave the selection hardware on */ - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); - - printf("%s:%c:%d: no active SCB for reconnecting " - "target - issuing BUS DEVICE RESET\n", - ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4); - printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, " - "REG0 == 0x%x ACCUM = 0x%x\n", - ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN), - ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM)); - printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, " - "SINDEX == 0x%x\n", - ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd), - ahd_find_busy_tcl(ahd, - BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID), - ahd_inb(ahd, SAVED_LUN))), - ahd_inw(ahd, SINDEX)); - printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, " - "SCB_CONTROL == 0x%x\n", - ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID), - ahd_inb_scbram(ahd, SCB_LUN), - ahd_inb_scbram(ahd, SCB_CONTROL)); - printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n", - ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI)); - printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0)); - printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0)); - ahd_dump_card_state(ahd); - ahd->msgout_buf[0] = MSG_BUS_DEV_RESET; - ahd->msgout_len = 1; - ahd->msgout_index = 0; - ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd_assert_atn(ahd); - break; - } - case PROTO_VIOLATION: - { - ahd_handle_proto_violation(ahd); - break; - } - case IGN_WIDE_RES: - { - struct ahd_devinfo devinfo; - - ahd_fetch_devinfo(ahd, &devinfo); - ahd_handle_ign_wide_residue(ahd, &devinfo); - break; - } - case BAD_PHASE: - { - u_int lastphase; - - lastphase = ahd_inb(ahd, LASTPHASE); - printf("%s:%c:%d: unknown scsi bus phase %x, " - "lastphase = 0x%x. Attempting to continue\n", - ahd_name(ahd), 'A', - SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), - lastphase, ahd_inb(ahd, SCSISIGI)); - break; - } - case MISSED_BUSFREE: - { - u_int lastphase; - - lastphase = ahd_inb(ahd, LASTPHASE); - printf("%s:%c:%d: Missed busfree. " - "Lastphase = 0x%x, Curphase = 0x%x\n", - ahd_name(ahd), 'A', - SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), - lastphase, ahd_inb(ahd, SCSISIGI)); - ahd_restart(ahd); - return; - } - case DATA_OVERRUN: - { - /* - * When the sequencer detects an overrun, it - * places the controller in "BITBUCKET" mode - * and allows the target to complete its transfer. - * Unfortunately, none of the counters get updated - * when the controller is in this mode, so we have - * no way of knowing how large the overrun was. - */ - struct scb *scb; - u_int scbindex; -#ifdef AHD_DEBUG - u_int lastphase; -#endif - - scbindex = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbindex); -#ifdef AHD_DEBUG - lastphase = ahd_inb(ahd, LASTPHASE); - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { - ahd_print_path(ahd, scb); - printf("data overrun detected %s. Tag == 0x%x.\n", - ahd_lookup_phase_entry(lastphase)->phasemsg, - SCB_GET_TAG(scb)); - ahd_print_path(ahd, scb); - printf("%s seen Data Phase. Length = %ld. " - "NumSGs = %d.\n", - ahd_inb(ahd, SEQ_FLAGS) & DPHASE - ? "Have" : "Haven't", - ahd_get_transfer_length(scb), scb->sg_count); - ahd_dump_sglist(scb); - } -#endif - - /* - * Set this and it will take effect when the - * target does a command complete. - */ - ahd_freeze_devq(ahd, scb); - ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); - ahd_freeze_scb(scb); - break; - } - case MKMSG_FAILED: - { - struct ahd_devinfo devinfo; - struct scb *scb; - u_int scbid; - - ahd_fetch_devinfo(ahd, &devinfo); - printf("%s:%c:%d:%d: Attempt to issue message failed\n", - ahd_name(ahd), devinfo.channel, devinfo.target, - devinfo.lun); - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb != NULL - && (scb->flags & SCB_RECOVERY_SCB) != 0) - /* - * Ensure that we didn't put a second instance of this - * SCB into the QINFIFO. - */ - ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), - SCB_GET_CHANNEL(ahd, scb), - SCB_GET_LUN(scb), SCB_GET_TAG(scb), - ROLE_INITIATOR, /*status*/0, - SEARCH_REMOVE); - ahd_outb(ahd, SCB_CONTROL, - ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE); - break; - } - case TASKMGMT_FUNC_COMPLETE: - { - u_int scbid; - struct scb *scb; - - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb != NULL) { - u_int lun; - u_int tag; - cam_status error; - - ahd_print_path(ahd, scb); - printf("Task Management Func 0x%x Complete\n", - scb->hscb->task_management); - lun = CAM_LUN_WILDCARD; - tag = SCB_LIST_NULL; - - switch (scb->hscb->task_management) { - case SIU_TASKMGMT_ABORT_TASK: - tag = scb->hscb->tag; - case SIU_TASKMGMT_ABORT_TASK_SET: - case SIU_TASKMGMT_CLEAR_TASK_SET: - lun = scb->hscb->lun; - error = CAM_REQ_ABORTED; - ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), - 'A', lun, tag, ROLE_INITIATOR, - error); - break; - case SIU_TASKMGMT_LUN_RESET: - lun = scb->hscb->lun; - case SIU_TASKMGMT_TARGET_RESET: - { - struct ahd_devinfo devinfo; - - ahd_scb_devinfo(ahd, &devinfo, scb); - error = CAM_BDR_SENT; - ahd_handle_devreset(ahd, &devinfo, lun, - CAM_BDR_SENT, - lun != CAM_LUN_WILDCARD - ? "Lun Reset" - : "Target Reset", - /*verbose_level*/0); - break; - } - default: - panic("Unexpected TaskMgmt Func\n"); - break; - } - } - break; - } - case TASKMGMT_CMD_CMPLT_OKAY: - { - u_int scbid; - struct scb *scb; - - /* - * An ABORT TASK TMF failed to be delivered before - * the targeted command completed normally. - */ - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb != NULL) { - /* - * Remove the second instance of this SCB from - * the QINFIFO if it is still there. - */ - ahd_print_path(ahd, scb); - printf("SCB completes before TMF\n"); - /* - * Handle losing the race. Wait until any - * current selection completes. We will then - * set the TMF back to zero in this SCB so that - * the sequencer doesn't bother to issue another - * sequencer interrupt for its completion. - */ - while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0 - && (ahd_inb(ahd, SSTAT0) & SELDO) == 0 - && (ahd_inb(ahd, SSTAT1) & SELTO) == 0) - ; - ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0); - ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), - SCB_GET_CHANNEL(ahd, scb), - SCB_GET_LUN(scb), scb->hscb->tag, - ROLE_INITIATOR, /*status*/0, - SEARCH_REMOVE); - } - break; - } - case TRACEPOINT0: - case TRACEPOINT1: - case TRACEPOINT2: - case TRACEPOINT3: - printf("%s: Tracepoint %d\n", ahd_name(ahd), - seqintcode - TRACEPOINT0); - break; - case NO_SEQINT: - break; - case SAW_HWERR: - ahd_handle_hwerrint(ahd); - break; - default: - printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd), - seqintcode); - break; - } - /* - * The sequencer is paused immediately on - * a SEQINT, so we should restart it when - * we're done. - */ - ahd_unpause(ahd); -} - -void -ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) -{ - struct scb *scb; - u_int status0; - u_int status3; - u_int status; - u_int lqistat1; - u_int lqostat0; - u_int scbid; - u_int busfreetime; - - ahd_update_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - - status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR); - status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO); - status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR); - lqistat1 = ahd_inb(ahd, LQISTAT1); - lqostat0 = ahd_inb(ahd, LQOSTAT0); - busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; - if ((status0 & (SELDI|SELDO)) != 0) { - u_int simode0; - - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - simode0 = ahd_inb(ahd, SIMODE0); - status0 &= simode0 & (IOERR|OVERRUN|SELDI|SELDO); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - } - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb != NULL - && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) - scb = NULL; - - /* Make sure the sequencer is in a safe location. */ - ahd_clear_critical_section(ahd); - - if ((status0 & IOERR) != 0) { - u_int now_lvd; - - now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40; - printf("%s: Transceiver State Has Changed to %s mode\n", - ahd_name(ahd), now_lvd ? "LVD" : "SE"); - ahd_outb(ahd, CLRSINT0, CLRIOERR); - /* - * A change in I/O mode is equivalent to a bus reset. - */ - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); - ahd_pause(ahd); - ahd_setup_iocell_workaround(ahd); - ahd_unpause(ahd); - } else if ((status0 & OVERRUN) != 0) { - printf("%s: SCSI offset overrun detected. Resetting bus.\n", - ahd_name(ahd)); - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - } else if ((status & SCSIRSTI) != 0) { - printf("%s: Someone reset channel A\n", ahd_name(ahd)); - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); - } else if ((status & SCSIPERR) != 0) { - ahd_handle_transmission_error(ahd); - } else if (lqostat0 != 0) { - printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0); - ahd_outb(ahd, CLRLQOINT0, lqostat0); - if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { - ahd_outb(ahd, CLRLQOINT1, 0); - } - } else if ((status & SELTO) != 0) { - u_int scbid; - - /* Stop the selection */ - ahd_outb(ahd, SCSISEQ0, 0); - - /* No more pending messages */ - ahd_clear_msg_state(ahd); - - /* Clear interrupt state */ - ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR); - - /* - * Although the driver does not care about the - * 'Selection in Progress' status bit, the busy - * LED does. SELINGO is only cleared by a sucessfull - * selection, so we must manually clear it to insure - * the LED turns off just incase no future successful - * selections occur (e.g. no devices on the bus). - */ - ahd_outb(ahd, CLRSINT0, CLRSELINGO); - - scbid = ahd_inw(ahd, WAITING_TID_HEAD); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("%s: ahd_intr - referenced scb not " - "valid during SELTO scb(0x%x)\n", - ahd_name(ahd), scbid); - ahd_dump_card_state(ahd); - } else { - struct ahd_devinfo devinfo; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_SELTO) != 0) { - ahd_print_path(ahd, scb); - printf("Saw Selection Timeout for SCB 0x%x\n", - scbid); - } -#endif - /* - * Force a renegotiation with this target just in - * case the cable was pulled and will later be - * re-attached. The target may forget its negotiation - * settings with us should it attempt to reselect - * during the interruption. The target will not issue - * a unit attention in this case, so we must always - * renegotiate. - */ - ahd_scb_devinfo(ahd, &devinfo, scb); - ahd_force_renegotiation(ahd, &devinfo); - ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT); - ahd_freeze_devq(ahd, scb); - } - ahd_outb(ahd, CLRINT, CLRSCSIINT); - ahd_iocell_first_selection(ahd); - ahd_unpause(ahd); - } else if ((status0 & (SELDI|SELDO)) != 0) { - ahd_iocell_first_selection(ahd); - ahd_unpause(ahd); - } else if (status3 != 0) { - printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n", - ahd_name(ahd), status3); - ahd_outb(ahd, CLRSINT3, status3); - } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) { - ahd_handle_lqiphase_error(ahd, lqistat1); - } else if ((status & BUSFREE) != 0) { - u_int lqostat1; - int restart; - int clear_fifo; - int packetized; - u_int mode; - - /* - * Clear our selection hardware as soon as possible. - * We may have an entry in the waiting Q for this target, - * that is affected by this busfree and we don't want to - * go about selecting the target while we handle the event. - */ - ahd_outb(ahd, SCSISEQ0, 0); - - /* - * Determine what we were up to at the time of - * the busfree. - */ - mode = AHD_MODE_SCSI; - busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; - lqostat1 = ahd_inb(ahd, LQOSTAT1); - switch (busfreetime) { - case BUSFREE_DFF0: - case BUSFREE_DFF1: - { - u_int scbid; - struct scb *scb; - - mode = busfreetime == BUSFREE_DFF0 - ? AHD_MODE_DFF0 : AHD_MODE_DFF1; - ahd_set_modes(ahd, mode, mode); - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("%s: Invalid SCB in DFF%d " - "during unexpected busfree\n", - ahd_name(ahd), mode); - packetized = 0; - } else - packetized = (scb->flags & SCB_PACKETIZED) != 0; - clear_fifo = 1; - break; - } - case BUSFREE_LQO: - clear_fifo = 0; - packetized = 1; - break; - default: - clear_fifo = 0; - packetized = (lqostat1 & LQOBUSFREE) != 0; - if (!packetized - && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) - packetized = 1; - break; - } - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("Saw Busfree. Busfreetime = 0x%x.\n", - busfreetime); -#endif - /* - * Busfrees that occur in non-packetized phases are - * handled by the nonpkt_busfree handler. - */ - if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) { - restart = ahd_handle_pkt_busfree(ahd, busfreetime); - } else { - packetized = 0; - restart = ahd_handle_nonpkt_busfree(ahd); - } - /* - * Clear the busfree interrupt status. The setting of - * the interrupt is a pulse, so in a perfect world, we - * would not need to muck with the ENBUSFREE logic. This - * would ensure that if the bus moves on to another - * connection, busfree protection is still in force. If - * BUSFREEREV is broken, however, we must manually clear - * the ENBUSFREE if the busfree occurred during a non-pack - * connection so that we don't get false positives during - * future, packetized, connections. - */ - ahd_outb(ahd, CLRSINT1, CLRBUSFREE); - if (packetized == 0 - && (ahd->bugs & AHD_BUSFREEREV_BUG) != 0) - ahd_outb(ahd, SIMODE1, - ahd_inb(ahd, SIMODE1) & ~ENBUSFREE); - - if (clear_fifo) - ahd_clear_fifo(ahd, mode); - - ahd_clear_msg_state(ahd); - ahd_outb(ahd, CLRINT, CLRSCSIINT); - if (restart) { - ahd_restart(ahd); - } else { - ahd_unpause(ahd); - } - } else { - printf("%s: Missing case in ahd_handle_scsiint. status = %x\n", - ahd_name(ahd), status); - ahd_dump_card_state(ahd); - ahd_clear_intstat(ahd); - ahd_unpause(ahd); - } -} - -static void -ahd_handle_transmission_error(struct ahd_softc *ahd) -{ - struct scb *scb; - u_int scbid; - u_int lqistat1; - u_int lqistat2; - u_int msg_out; - u_int curphase; - u_int lastphase; - u_int perrdiag; - u_int cur_col; - int silent; - - scb = NULL; - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ); - lqistat2 = ahd_inb(ahd, LQISTAT2); - if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0 - && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) { - u_int lqistate; - - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - lqistate = ahd_inb(ahd, LQISTATE); - if ((lqistate >= 0x1E && lqistate <= 0x24) - || (lqistate == 0x29)) { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { - printf("%s: NLQCRC found via LQISTATE\n", - ahd_name(ahd)); - } -#endif - lqistat1 |= LQICRCI_NLQ; - } - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - } - - ahd_outb(ahd, CLRLQIINT1, lqistat1); - lastphase = ahd_inb(ahd, LASTPHASE); - curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; - perrdiag = ahd_inb(ahd, PERRDIAG); - msg_out = MSG_INITIATOR_DET_ERR; - ahd_outb(ahd, CLRSINT1, CLRSCSIPERR); - - /* - * Try to find the SCB associated with this error. - */ - silent = FALSE; - if (lqistat1 == 0 - || (lqistat1 & LQICRCI_NLQ) != 0) { - if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0) - ahd_set_active_fifo(ahd); - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb != NULL && SCB_IS_SILENT(scb)) - silent = TRUE; - } - - cur_col = 0; - if (silent == FALSE) { - printf("%s: Transmission error detected\n", ahd_name(ahd)); - ahd_lqistat1_print(lqistat1, &cur_col, 50); - ahd_lastphase_print(lastphase, &cur_col, 50); - ahd_scsisigi_print(curphase, &cur_col, 50); - ahd_perrdiag_print(perrdiag, &cur_col, 50); - printf("\n"); - ahd_dump_card_state(ahd); - } - - if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) { - if (silent == FALSE) { - printf("%s: Gross protocol error during incoming " - "packet. lqistat1 == 0x%x. Resetting bus.\n", - ahd_name(ahd), lqistat1); - } - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - return; - } else if ((lqistat1 & LQICRCI_LQ) != 0) { - /* - * A CRC error has been detected on an incoming LQ. - * The bus is currently hung on the last ACK. - * Hit LQIRETRY to release the last ack, and - * wait for the sequencer to determine that ATNO - * is asserted while in message out to take us - * to our host message loop. No NONPACKREQ or - * LQIPHASE type errors will occur in this - * scenario. After this first LQIRETRY, the LQI - * manager will be in ISELO where it will - * happily sit until another packet phase begins. - * Unexpected bus free detection is enabled - * through any phases that occur after we release - * this last ack until the LQI manager sees a - * packet phase. This implies we may have to - * ignore a perfectly valid "unexected busfree" - * after our "initiator detected error" message is - * sent. A busfree is the expected response after - * we tell the target that it's L_Q was corrupted. - * (SPI4R09 10.7.3.3.3) - */ - ahd_outb(ahd, LQCTL2, LQIRETRY); - printf("LQIRetry for LQICRCI_LQ to release ACK\n"); - } else if ((lqistat1 & LQICRCI_NLQ) != 0) { - /* - * We detected a CRC error in a NON-LQ packet. - * The hardware has varying behavior in this situation - * depending on whether this packet was part of a - * stream or not. - * - * PKT by PKT mode: - * The hardware has already acked the complete packet. - * If the target honors our outstanding ATN condition, - * we should be (or soon will be) in MSGOUT phase. - * This will trigger the LQIPHASE_LQ status bit as the - * hardware was expecting another LQ. Unexpected - * busfree detection is enabled. Once LQIPHASE_LQ is - * true (first entry into host message loop is much - * the same), we must clear LQIPHASE_LQ and hit - * LQIRETRY so the hardware is ready to handle - * a future LQ. NONPACKREQ will not be asserted again - * once we hit LQIRETRY until another packet is - * processed. The target may either go busfree - * or start another packet in response to our message. - * - * Read Streaming P0 asserted: - * If we raise ATN and the target completes the entire - * stream (P0 asserted during the last packet), the - * hardware will ack all data and return to the ISTART - * state. When the target reponds to our ATN condition, - * LQIPHASE_LQ will be asserted. We should respond to - * this with an LQIRETRY to prepare for any future - * packets. NONPACKREQ will not be asserted again - * once we hit LQIRETRY until another packet is - * processed. The target may either go busfree or - * start another packet in response to our message. - * Busfree detection is enabled. - * - * Read Streaming P0 not asserted: - * If we raise ATN and the target transitions to - * MSGOUT in or after a packet where P0 is not - * asserted, the hardware will assert LQIPHASE_NLQ. - * We should respond to the LQIPHASE_NLQ with an - * LQIRETRY. Should the target stay in a non-pkt - * phase after we send our message, the hardware - * will assert LQIPHASE_LQ. Recovery is then just as - * listed above for the read streaming with P0 asserted. - * Busfree detection is enabled. - */ - if (silent == FALSE) - printf("LQICRC_NLQ\n"); - if (scb == NULL) { - printf("%s: No SCB valid for LQICRC_NLQ. " - "Resetting bus\n", ahd_name(ahd)); - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - return; - } - } else if ((lqistat1 & LQIBADLQI) != 0) { - printf("Need to handle BADLQI!\n"); - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - return; - } else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) { - if ((curphase & ~P_DATAIN_DT) != 0) { - /* Ack the byte. So we can continue. */ - if (silent == FALSE) - printf("Acking %s to clear perror\n", - ahd_lookup_phase_entry(curphase)->phasemsg); - ahd_inb(ahd, SCSIDAT); - } - - if (curphase == P_MESGIN) - msg_out = MSG_PARITY_ERROR; - } - - /* - * We've set the hardware to assert ATN if we - * get a parity error on "in" phases, so all we - * need to do is stuff the message buffer with - * the appropriate message. "In" phases have set - * mesg_out to something other than MSG_NOP. - */ - ahd->send_msg_perror = msg_out; - if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR) - scb->flags |= SCB_TRANSMISSION_ERROR; - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd_outb(ahd, CLRINT, CLRSCSIINT); - ahd_unpause(ahd); -} - -static void -ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1) -{ - /* - * Clear the sources of the interrupts. - */ - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_outb(ahd, CLRLQIINT1, lqistat1); - - /* - * If the "illegal" phase changes were in response - * to our ATN to flag a CRC error, AND we ended up - * on packet boundaries, clear the error, restart the - * LQI manager as appropriate, and go on our merry - * way toward sending the message. Otherwise, reset - * the bus to clear the error. - */ - ahd_set_active_fifo(ahd); - if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0 - && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) { - if ((lqistat1 & LQIPHASE_LQ) != 0) { - printf("LQIRETRY for LQIPHASE_LQ\n"); - ahd_outb(ahd, LQCTL2, LQIRETRY); - } else if ((lqistat1 & LQIPHASE_NLQ) != 0) { - printf("LQIRETRY for LQIPHASE_NLQ\n"); - ahd_outb(ahd, LQCTL2, LQIRETRY); - } else - panic("ahd_handle_lqiphase_error: No phase errors\n"); - ahd_dump_card_state(ahd); - ahd_outb(ahd, CLRINT, CLRSCSIINT); - ahd_unpause(ahd); - } else { - printf("Reseting Channel for LQI Phase error\n"); - ahd_dump_card_state(ahd); - ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); - } -} - -/* - * Packetized unexpected or expected busfree. - * Entered in mode based on busfreetime. - */ -static int -ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime) -{ - u_int lqostat1; - - AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), - ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); - lqostat1 = ahd_inb(ahd, LQOSTAT1); - if ((lqostat1 & LQOBUSFREE) != 0) { - struct scb *scb; - u_int scbid; - u_int saved_scbptr; - u_int waiting_h; - u_int waiting_t; - u_int next; - - if ((busfreetime & BUSFREE_LQO) == 0) - printf("%s: Warning, BUSFREE time is 0x%x. " - "Expected BUSFREE_LQO.\n", - ahd_name(ahd), busfreetime); - /* - * The LQO manager detected an unexpected busfree - * either: - * - * 1) During an outgoing LQ. - * 2) After an outgoing LQ but before the first - * REQ of the command packet. - * 3) During an outgoing command packet. - * - * In all cases, CURRSCB is pointing to the - * SCB that encountered the failure. Clean - * up the queue, clear SELDO and LQOBUSFREE, - * and allow the sequencer to restart the select - * out at its lesure. - */ - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - scbid = ahd_inw(ahd, CURRSCB); - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) - panic("SCB not valid during LQOBUSFREE"); - /* - * Return the LQO manager to its idle loop. It will - * not do this automatically if the busfree occurs - * after the first REQ of either the LQ or command - * packet or between the LQ and command packet. - */ - ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE); - - /* - * Clear the status. - */ - ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE); - if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) - ahd_outb(ahd, CLRLQOINT1, 0); - ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); - ahd_outb(ahd, CLRSINT0, CLRSELDO); - - /* - * Update the waiting for selection queue so - * we restart on the correct SCB. - */ - waiting_h = ahd_inw(ahd, WAITING_TID_HEAD); - saved_scbptr = ahd_get_scbptr(ahd); - if (waiting_h != scbid) { - - ahd_outw(ahd, WAITING_TID_HEAD, scbid); - waiting_t = ahd_inw(ahd, WAITING_TID_TAIL); - next = SCB_LIST_NULL; - if (waiting_t == waiting_h) { - ahd_outw(ahd, WAITING_TID_TAIL, scbid); - } else { - ahd_set_scbptr(ahd, waiting_h); - next = ahd_inw(ahd, SCB_NEXT2); - } - ahd_set_scbptr(ahd, scbid); - ahd_outw(ahd, SCB_NEXT2, next); - } - ahd_set_scbptr(ahd, saved_scbptr); - if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) { - if (SCB_IS_SILENT(scb) == FALSE) { - ahd_print_path(ahd, scb); - printf("Probable outgoing LQ CRC error. " - "Retrying command\n"); - } - scb->crc_retry_count++; - } else { - ahd_set_transaction_status(scb, CAM_UNCOR_PARITY); - ahd_freeze_scb(scb); - ahd_freeze_devq(ahd, scb); - } - /* Return unpausing the sequencer. */ - return (0); - } else if ((ahd_inb(ahd, PERRDIAG) & PARITYERR) != 0) { - /* - * Ignore what are really parity errors that - * occur on the last REQ of a free running - * clock prior to going busfree. Some drives - * do not properly active negate just before - * going busfree resulting in a parity glitch. - */ - ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0) - printf("%s: Parity on last REQ detected " - "during busfree phase.\n", - ahd_name(ahd)); -#endif - /* Return unpausing the sequencer. */ - return (0); - } - if (ahd->src_mode != AHD_MODE_SCSI) { - u_int scbid; - struct scb *scb; - - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - ahd_print_path(ahd, scb); - printf("Unexpected PKT busfree condition\n"); - ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A', - SCB_GET_LUN(scb), SCB_GET_TAG(scb), - ROLE_INITIATOR, CAM_UNEXP_BUSFREE); - - /* Return restarting the sequencer. */ - return (1); - } - printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd)); - ahd_dump_card_state(ahd); - /* Restart the sequencer. */ - return (1); -} - -/* - * Non-packetized unexpected or expected busfree. - */ -static int -ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) -{ - struct ahd_devinfo devinfo; - struct scb *scb; - u_int lastphase; - u_int saved_scsiid; - u_int saved_lun; - u_int target; - u_int initiator_role_id; - u_int scbid; - u_int ppr_busfree; - int printerror; - - /* - * Look at what phase we were last in. If its message out, - * chances are pretty good that the busfree was in response - * to one of our abort requests. - */ - lastphase = ahd_inb(ahd, LASTPHASE); - saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); - saved_lun = ahd_inb(ahd, SAVED_LUN); - target = SCSIID_TARGET(ahd, saved_scsiid); - initiator_role_id = SCSIID_OUR_ID(saved_scsiid); - ahd_compile_devinfo(&devinfo, initiator_role_id, - target, saved_lun, 'A', ROLE_INITIATOR); - printerror = 1; - - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - if (scb != NULL - && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) - scb = NULL; - - ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0; - if (lastphase == P_MESGOUT) { - u_int tag; - - tag = SCB_LIST_NULL; - if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE) - || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) { - int found; - int sent_msg; - - if (scb == NULL) { - ahd_print_devinfo(ahd, &devinfo); - printf("Abort for unidentified " - "connection completed.\n"); - /* restart the sequencer. */ - return (1); - } - sent_msg = ahd->msgout_buf[ahd->msgout_index - 1]; - ahd_print_path(ahd, scb); - printf("SCB %d - Abort%s Completed.\n", - SCB_GET_TAG(scb), - sent_msg == MSG_ABORT_TAG ? "" : " Tag"); - - if (sent_msg == MSG_ABORT_TAG) - tag = SCB_GET_TAG(scb); - - if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) { - /* - * This abort is in response to an - * unexpected switch to command phase - * for a packetized connection. Since - * the identify message was never sent, - * "saved lun" is 0. We really want to - * abort only the SCB that encountered - * this error, which could have a different - * lun. The SCB will be retried so the OS - * will see the UA after renegotiating to - * packetized. - */ - tag = SCB_GET_TAG(scb); - saved_lun = scb->hscb->lun; - } - found = ahd_abort_scbs(ahd, target, 'A', saved_lun, - tag, ROLE_INITIATOR, - CAM_REQ_ABORTED); - printf("found == 0x%x\n", found); - printerror = 0; - } else if (ahd_sent_msg(ahd, AHDMSG_1B, - MSG_BUS_DEV_RESET, TRUE)) { -#ifdef __FreeBSD__ - /* - * Don't mark the user's request for this BDR - * as completing with CAM_BDR_SENT. CAM3 - * specifies CAM_REQ_CMP. - */ - if (scb != NULL - && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV - && ahd_match_scb(ahd, scb, target, 'A', - CAM_LUN_WILDCARD, SCB_LIST_NULL, - ROLE_INITIATOR)) - ahd_set_transaction_status(scb, CAM_REQ_CMP); -#endif - ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD, - CAM_BDR_SENT, "Bus Device Reset", - /*verbose_level*/0); - printerror = 0; - } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE) - && ppr_busfree == 0) { - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - - /* - * PPR Rejected. Try non-ppr negotiation - * and retry command. - */ -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("PPR negotiation rejected busfree.\n"); -#endif - tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, - devinfo.our_scsiid, - devinfo.target, &tstate); - tinfo->curr.transport_version = 2; - tinfo->goal.transport_version = 2; - tinfo->goal.ppr_options = 0; - ahd_qinfifo_requeue_tail(ahd, scb); - printerror = 0; - } else if ((ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) - || ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)) - && ppr_busfree == 0) { - /* - * Negotiation Rejected. Go-async and - * retry command. - */ -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("Negotiation rejected busfree.\n"); -#endif - ahd_set_width(ahd, &devinfo, - MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_CUR|AHD_TRANS_GOAL, - /*paused*/TRUE); - ahd_set_syncrate(ahd, &devinfo, - /*period*/0, /*offset*/0, - /*ppr_options*/0, - AHD_TRANS_CUR|AHD_TRANS_GOAL, - /*paused*/TRUE); - ahd_qinfifo_requeue_tail(ahd, scb); - printerror = 0; - } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 - && ahd_sent_msg(ahd, AHDMSG_1B, - MSG_INITIATOR_DET_ERR, TRUE)) { - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("Expected IDE Busfree\n"); -#endif - printerror = 0; - } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE) - && ahd_sent_msg(ahd, AHDMSG_1B, - MSG_MESSAGE_REJECT, TRUE)) { - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("Expected QAS Reject Busfree\n"); -#endif - printerror = 0; - } - } - - /* - * The busfree required flag is honored at the end of - * the message phases. We check it last in case we - * had to send some other message that caused a busfree. - */ - if (printerror != 0 - && (lastphase == P_MESGIN || lastphase == P_MESGOUT) - && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { - - ahd_freeze_devq(ahd, scb); - ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); - ahd_freeze_scb(scb); - if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) { - ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), - SCB_GET_CHANNEL(ahd, scb), - SCB_GET_LUN(scb), SCB_LIST_NULL, - ROLE_INITIATOR, CAM_REQ_ABORTED); - } else { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("PPR Negotiation Busfree.\n"); -#endif - ahd_done(ahd, scb); - } - printerror = 0; - } - if (printerror != 0) { - int aborted; - - aborted = 0; - if (scb != NULL) { - u_int tag; - - if ((scb->hscb->control & TAG_ENB) != 0) - tag = SCB_GET_TAG(scb); - else - tag = SCB_LIST_NULL; - ahd_print_path(ahd, scb); - aborted = ahd_abort_scbs(ahd, target, 'A', - SCB_GET_LUN(scb), tag, - ROLE_INITIATOR, - CAM_UNEXP_BUSFREE); - } else { - /* - * We had not fully identified this connection, - * so we cannot abort anything. - */ - printf("%s: ", ahd_name(ahd)); - } - if (lastphase != P_BUSFREE) - ahd_force_renegotiation(ahd, &devinfo); - printf("Unexpected busfree %s, %d SCBs aborted, " - "PRGMCNT == 0x%x\n", - ahd_lookup_phase_entry(lastphase)->phasemsg, - aborted, - ahd_inb(ahd, PRGMCNT) - | (ahd_inb(ahd, PRGMCNT+1) << 8)); - ahd_dump_card_state(ahd); - } - /* Always restart the sequencer. */ - return (1); -} - -static void -ahd_handle_proto_violation(struct ahd_softc *ahd) -{ - struct ahd_devinfo devinfo; - struct scb *scb; - u_int scbid; - u_int seq_flags; - u_int curphase; - u_int lastphase; - int found; - - ahd_fetch_devinfo(ahd, &devinfo); - scbid = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scbid); - seq_flags = ahd_inb(ahd, SEQ_FLAGS); - curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; - lastphase = ahd_inb(ahd, LASTPHASE); - if ((seq_flags & NOT_IDENTIFIED) != 0) { - - /* - * The reconnecting target either did not send an - * identify message, or did, but we didn't find an SCB - * to match. - */ - ahd_print_devinfo(ahd, &devinfo); - printf("Target did not send an IDENTIFY message. " - "LASTPHASE = 0x%x.\n", lastphase); - scb = NULL; - } else if (scb == NULL) { - /* - * We don't seem to have an SCB active for this - * transaction. Print an error and reset the bus. - */ - ahd_print_devinfo(ahd, &devinfo); - printf("No SCB found during protocol violation\n"); - goto proto_violation_reset; - } else { - ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL); - if ((seq_flags & NO_CDB_SENT) != 0) { - ahd_print_path(ahd, scb); - printf("No or incomplete CDB sent to device.\n"); - } else if ((ahd_inb(ahd, SCB_CONTROL) & STATUS_RCVD) == 0) { - /* - * The target never bothered to provide status to - * us prior to completing the command. Since we don't - * know the disposition of this command, we must attempt - * to abort it. Assert ATN and prepare to send an abort - * message. - */ - ahd_print_path(ahd, scb); - printf("Completed command without status.\n"); - } else { - ahd_print_path(ahd, scb); - printf("Unknown protocol violation.\n"); - ahd_dump_card_state(ahd); - } - } - if ((lastphase & ~P_DATAIN_DT) == 0 - || lastphase == P_COMMAND) { -proto_violation_reset: - /* - * Target either went directly to data - * phase or didn't respond to our ATN. - * The only safe thing to do is to blow - * it away with a bus reset. - */ - found = ahd_reset_channel(ahd, 'A', TRUE); - printf("%s: Issued Channel %c Bus Reset. " - "%d SCBs aborted\n", ahd_name(ahd), 'A', found); - } else { - /* - * Leave the selection hardware off in case - * this abort attempt will affect yet to - * be sent commands. - */ - ahd_outb(ahd, SCSISEQ0, - ahd_inb(ahd, SCSISEQ0) & ~ENSELO); - ahd_assert_atn(ahd); - ahd_outb(ahd, MSG_OUT, HOST_MSG); - if (scb == NULL) { - ahd_print_devinfo(ahd, &devinfo); - ahd->msgout_buf[0] = MSG_ABORT_TASK; - ahd->msgout_len = 1; - ahd->msgout_index = 0; - ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; - } else { - ahd_print_path(ahd, scb); - scb->flags |= SCB_ABORT; - } - printf("Protocol violation %s. Attempting to abort.\n", - ahd_lookup_phase_entry(curphase)->phasemsg); - } -} - -/* - * Force renegotiation to occur the next time we initiate - * a command to the current device. - */ -static void -ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - struct ahd_initiator_tinfo *targ_info; - struct ahd_tmode_tstate *tstate; - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { - ahd_print_devinfo(ahd, devinfo); - printf("Forcing renegotiation\n"); - } -#endif - targ_info = ahd_fetch_transinfo(ahd, - devinfo->channel, - devinfo->our_scsiid, - devinfo->target, - &tstate); - ahd_update_neg_request(ahd, devinfo, tstate, - targ_info, AHD_NEG_IF_NON_ASYNC); -} - -#define AHD_MAX_STEPS 2000 -void -ahd_clear_critical_section(struct ahd_softc *ahd) -{ - ahd_mode_state saved_modes; - int stepping; - int steps; - int first_instr; - u_int simode0; - u_int simode1; - u_int simode3; - u_int lqimode0; - u_int lqimode1; - u_int lqomode0; - u_int lqomode1; - - if (ahd->num_critical_sections == 0) - return; - - stepping = FALSE; - steps = 0; - first_instr = 0; - simode0 = 0; - simode1 = 0; - simode3 = 0; - lqimode0 = 0; - lqimode1 = 0; - lqomode0 = 0; - lqomode1 = 0; - saved_modes = ahd_save_modes(ahd); - for (;;) { - struct cs *cs; - u_int seqaddr; - u_int i; - - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - seqaddr = ahd_inb(ahd, CURADDR) - | (ahd_inb(ahd, CURADDR+1) << 8); - - cs = ahd->critical_sections; - for (i = 0; i < ahd->num_critical_sections; i++, cs++) { - - if (cs->begin < seqaddr && cs->end >= seqaddr) - break; - } - - if (i == ahd->num_critical_sections) - break; - - if (steps > AHD_MAX_STEPS) { - printf("%s: Infinite loop in critical section\n" - "%s: First Instruction 0x%x now 0x%x\n", - ahd_name(ahd), ahd_name(ahd), first_instr, - seqaddr); - ahd_dump_card_state(ahd); - panic("critical section loop"); - } - - steps++; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("%s: Single stepping at 0x%x\n", ahd_name(ahd), - seqaddr); -#endif - if (stepping == FALSE) { - - first_instr = seqaddr; - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - simode0 = ahd_inb(ahd, SIMODE0); - simode3 = ahd_inb(ahd, SIMODE3); - lqimode0 = ahd_inb(ahd, LQIMODE0); - lqimode1 = ahd_inb(ahd, LQIMODE1); - lqomode0 = ahd_inb(ahd, LQOMODE0); - lqomode1 = ahd_inb(ahd, LQOMODE1); - ahd_outb(ahd, SIMODE0, 0); - ahd_outb(ahd, SIMODE3, 0); - ahd_outb(ahd, LQIMODE0, 0); - ahd_outb(ahd, LQIMODE1, 0); - ahd_outb(ahd, LQOMODE0, 0); - ahd_outb(ahd, LQOMODE1, 0); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - simode1 = ahd_inb(ahd, SIMODE1); - ahd_outb(ahd, SIMODE1, ENBUSFREE); - ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP); - stepping = TRUE; - } - ahd_outb(ahd, CLRSINT1, CLRBUSFREE); - ahd_outb(ahd, CLRINT, CLRSCSIINT); - ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); - ahd_outb(ahd, HCNTRL, ahd->unpause); - do { - ahd_delay(200); - } while (!ahd_is_paused(ahd)); - ahd_update_modes(ahd); - } - if (stepping) { - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - ahd_outb(ahd, SIMODE0, simode0); - ahd_outb(ahd, SIMODE3, simode3); - ahd_outb(ahd, LQIMODE0, lqimode0); - ahd_outb(ahd, LQIMODE1, lqimode1); - ahd_outb(ahd, LQOMODE0, lqomode0); - ahd_outb(ahd, LQOMODE1, lqomode1); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP); - ahd_outb(ahd, SIMODE1, simode1); - } - ahd_restore_modes(ahd, saved_modes); -} - -/* - * Clear any pending interrupt status. - */ -void -ahd_clear_intstat(struct ahd_softc *ahd) -{ - AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), - ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); - /* Clear any interrupt conditions this may have caused */ - ahd_outb(ahd, CLRLQIINT0, CLRLQIATNQAS|CLRLQICRCT1|CLRLQICRCT2 - |CLRLQIBADLQT|CLRLQIATNLQ|CLRLQIATNCMD); - ahd_outb(ahd, CLRLQIINT1, CLRLQIPHASE_LQ|CLRLQIPHASE_NLQ|CLRLIQABORT - |CLRLQICRCI_LQ|CLRLQICRCI_NLQ|CLRLQIBADLQI - |CLRLQIOVERI_LQ|CLRLQIOVERI_NLQ|CLRNONPACKREQ); - ahd_outb(ahd, CLRLQOINT0, CLRLQOTARGSCBPERR|CLRLQOSTOPT2|CLRLQOATNLQ - |CLRLQOATNPKT|CLRLQOTCRC); - ahd_outb(ahd, CLRLQOINT1, CLRLQOINITSCBPERR|CLRLQOSTOPI2|CLRLQOBADQAS - |CLRLQOBUSFREE|CLRLQOPHACHGINPKT); - if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { - ahd_outb(ahd, CLRLQOINT0, 0); - ahd_outb(ahd, CLRLQOINT1, 0); - } - ahd_outb(ahd, CLRSINT3, CLRNTRAMPERR|CLROSRAMPERR); - ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI - |CLRBUSFREE|CLRSCSIPERR|CLRREQINIT); - ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO - |CLRIOERR|CLROVERRUN); - ahd_outb(ahd, CLRINT, CLRSCSIINT); -} - -/**************************** Debugging Routines ******************************/ -#ifdef AHD_DEBUG -uint32_t ahd_debug = AHD_DEBUG_OPTS; -#endif -void -ahd_print_scb(struct scb *scb) -{ - struct hardware_scb *hscb; - int i; - - hscb = scb->hscb; - printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n", - (void *)scb, - hscb->control, - hscb->scsiid, - hscb->lun, - hscb->cdb_len); - printf("Shared Data: "); - for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++) - printf("%#02x", hscb->shared_data.idata.cdb[i]); - printf(" dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n", - (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF), - (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF), - ahd_le32toh(hscb->datacnt), - ahd_le32toh(hscb->sgptr), - SCB_GET_TAG(scb)); - ahd_dump_sglist(scb); -} - -void -ahd_dump_sglist(struct scb *scb) -{ - int i; - - if (scb->sg_count > 0) { - if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { - struct ahd_dma64_seg *sg_list; - - sg_list = (struct ahd_dma64_seg*)scb->sg_list; - for (i = 0; i < scb->sg_count; i++) { - uint64_t addr; - uint32_t len; - - addr = ahd_le64toh(sg_list[i].addr); - len = ahd_le32toh(sg_list[i].len); - printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", - i, - (uint32_t)((addr >> 32) & 0xFFFFFFFF), - (uint32_t)(addr & 0xFFFFFFFF), - sg_list[i].len & AHD_SG_LEN_MASK, - (sg_list[i].len & AHD_DMA_LAST_SEG) - ? " Last" : ""); - } - } else { - struct ahd_dma_seg *sg_list; - - sg_list = (struct ahd_dma_seg*)scb->sg_list; - for (i = 0; i < scb->sg_count; i++) { - uint32_t len; - - len = ahd_le32toh(sg_list[i].len); - printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", - i, - (len >> 24) & SG_HIGH_ADDR_BITS, - ahd_le32toh(sg_list[i].addr), - len & AHD_SG_LEN_MASK, - len & AHD_DMA_LAST_SEG ? " Last" : ""); - } - } - } -} - -/************************* Transfer Negotiation *******************************/ -/* - * Allocate per target mode instance (ID we respond to as a target) - * transfer negotiation data structures. - */ -static struct ahd_tmode_tstate * -ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel) -{ - struct ahd_tmode_tstate *master_tstate; - struct ahd_tmode_tstate *tstate; - int i; - - master_tstate = ahd->enabled_targets[ahd->our_id]; - if (ahd->enabled_targets[scsi_id] != NULL - && ahd->enabled_targets[scsi_id] != master_tstate) - panic("%s: ahd_alloc_tstate - Target already allocated", - ahd_name(ahd)); - tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT); - if (tstate == NULL) - return (NULL); - - /* - * If we have allocated a master tstate, copy user settings from - * the master tstate (taken from SRAM or the EEPROM) for this - * channel, but reset our current and goal settings to async/narrow - * until an initiator talks to us. - */ - if (master_tstate != NULL) { - memcpy(tstate, master_tstate, sizeof(*tstate)); - memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns)); - for (i = 0; i < 16; i++) { - memset(&tstate->transinfo[i].curr, 0, - sizeof(tstate->transinfo[i].curr)); - memset(&tstate->transinfo[i].goal, 0, - sizeof(tstate->transinfo[i].goal)); - } - } else - memset(tstate, 0, sizeof(*tstate)); - ahd->enabled_targets[scsi_id] = tstate; - return (tstate); -} - -#ifdef AHD_TARGET_MODE -/* - * Free per target mode instance (ID we respond to as a target) - * transfer negotiation data structures. - */ -static void -ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force) -{ - struct ahd_tmode_tstate *tstate; - - /* - * Don't clean up our "master" tstate. - * It has our default user settings. - */ - if (scsi_id == ahd->our_id - && force == FALSE) - return; - - tstate = ahd->enabled_targets[scsi_id]; - if (tstate != NULL) - free(tstate, M_DEVBUF); - ahd->enabled_targets[scsi_id] = NULL; -} -#endif - -/* - * Called when we have an active connection to a target on the bus, - * this function finds the nearest period to the input period limited - * by the capabilities of the bus connectivity of and sync settings for - * the target. - */ -void -ahd_devlimited_syncrate(struct ahd_softc *ahd, - struct ahd_initiator_tinfo *tinfo, - u_int *period, u_int *ppr_options, role_t role) -{ - struct ahd_transinfo *transinfo; - u_int maxsync; - - if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0 - && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) { - maxsync = AHD_SYNCRATE_PACED; - } else { - maxsync = AHD_SYNCRATE_ULTRA; - /* Can't do DT related options on an SE bus */ - *ppr_options &= MSG_EXT_PPR_QAS_REQ; - } - /* - * Never allow a value higher than our current goal - * period otherwise we may allow a target initiated - * negotiation to go above the limit as set by the - * user. In the case of an initiator initiated - * sync negotiation, we limit based on the user - * setting. This allows the system to still accept - * incoming negotiations even if target initiated - * negotiation is not performed. - */ - if (role == ROLE_TARGET) - transinfo = &tinfo->user; - else - transinfo = &tinfo->goal; - *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN); - if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { - maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2); - *ppr_options &= ~MSG_EXT_PPR_DT_REQ; - } - if (transinfo->period == 0) { - *period = 0; - *ppr_options = 0; - } else { - *period = MAX(*period, transinfo->period); - ahd_find_syncrate(ahd, period, ppr_options, maxsync); - } -} - -/* - * Look up the valid period to SCSIRATE conversion in our table. - * Return the period and offset that should be sent to the target - * if this was the beginning of an SDTR. - */ -void -ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, - u_int *ppr_options, u_int maxsync) -{ - if (*period < maxsync) - *period = maxsync; - - if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0 - && *period > AHD_SYNCRATE_MIN_DT) - *ppr_options &= ~MSG_EXT_PPR_DT_REQ; - - if (*period > AHD_SYNCRATE_MIN) - *period = 0; - - /* Honor PPR option conformance rules. */ - if (*period > AHD_SYNCRATE_PACED) - *ppr_options &= ~MSG_EXT_PPR_RTI; - - if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0) - *ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ); - - if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0) - *ppr_options &= MSG_EXT_PPR_QAS_REQ; - - /* Skip all PACED only entries if IU is not available */ - if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0 - && *period < AHD_SYNCRATE_DT) - *period = AHD_SYNCRATE_DT; - - /* Skip all DT only entries if DT is not available */ - if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0 - && *period < AHD_SYNCRATE_ULTRA2) - *period = AHD_SYNCRATE_ULTRA2; -} - -/* - * Truncate the given synchronous offset to a value the - * current adapter type and syncrate are capable of. - */ -void -ahd_validate_offset(struct ahd_softc *ahd, - struct ahd_initiator_tinfo *tinfo, - u_int period, u_int *offset, int wide, - role_t role) -{ - u_int maxoffset; - - /* Limit offset to what we can do */ - if (period == 0) - maxoffset = 0; - else if (period <= AHD_SYNCRATE_PACED) { - if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) - maxoffset = MAX_OFFSET_PACED_BUG; - else - maxoffset = MAX_OFFSET_PACED; - } else - maxoffset = MAX_OFFSET_NON_PACED; - *offset = MIN(*offset, maxoffset); - if (tinfo != NULL) { - if (role == ROLE_TARGET) - *offset = MIN(*offset, tinfo->user.offset); - else - *offset = MIN(*offset, tinfo->goal.offset); - } -} - -/* - * Truncate the given transfer width parameter to a value the - * current adapter type is capable of. - */ -void -ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, - u_int *bus_width, role_t role) -{ - switch (*bus_width) { - default: - if (ahd->features & AHD_WIDE) { - /* Respond Wide */ - *bus_width = MSG_EXT_WDTR_BUS_16_BIT; - break; - } - /* FALLTHROUGH */ - case MSG_EXT_WDTR_BUS_8_BIT: - *bus_width = MSG_EXT_WDTR_BUS_8_BIT; - break; - } - if (tinfo != NULL) { - if (role == ROLE_TARGET) - *bus_width = MIN(tinfo->user.width, *bus_width); - else - *bus_width = MIN(tinfo->goal.width, *bus_width); - } -} - -/* - * Update the bitmask of targets for which the controller should - * negotiate with at the next convenient oportunity. This currently - * means the next time we send the initial identify messages for - * a new transaction. - */ -int -ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - struct ahd_tmode_tstate *tstate, - struct ahd_initiator_tinfo *tinfo, ahd_neg_type neg_type) -{ - u_int auto_negotiate_orig; - - auto_negotiate_orig = tstate->auto_negotiate; - if (neg_type == AHD_NEG_ALWAYS) { - /* - * Force our "current" settings to be - * unknown so that unless a bus reset - * occurs the need to renegotiate is - * recorded persistently. - */ - if ((ahd->features & AHD_WIDE) != 0) - tinfo->curr.width = AHD_WIDTH_UNKNOWN; - tinfo->curr.period = AHD_PERIOD_UNKNOWN; - tinfo->curr.offset = AHD_OFFSET_UNKNOWN; - } - if (tinfo->curr.period != tinfo->goal.period - || tinfo->curr.width != tinfo->goal.width - || tinfo->curr.offset != tinfo->goal.offset - || tinfo->curr.ppr_options != tinfo->goal.ppr_options - || (neg_type == AHD_NEG_IF_NON_ASYNC - && (tinfo->goal.offset != 0 - || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT - || tinfo->goal.ppr_options != 0))) - tstate->auto_negotiate |= devinfo->target_mask; - else - tstate->auto_negotiate &= ~devinfo->target_mask; - - return (auto_negotiate_orig != tstate->auto_negotiate); -} - -/* - * Update the user/goal/curr tables of synchronous negotiation - * parameters as well as, in the case of a current or active update, - * any data structures on the host controller. In the case of an - * active update, the specified target is currently talking to us on - * the bus, so the transfer parameter update must take effect - * immediately. - */ -void -ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - u_int period, u_int offset, u_int ppr_options, - u_int type, int paused) -{ - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - u_int old_period; - u_int old_offset; - u_int old_ppr; - int active; - int update_needed; - - active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE; - update_needed = 0; - - if (period == 0 || offset == 0) { - period = 0; - offset = 0; - } - - tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, - devinfo->target, &tstate); - - if ((type & AHD_TRANS_USER) != 0) { - tinfo->user.period = period; - tinfo->user.offset = offset; - tinfo->user.ppr_options = ppr_options; - } - - if ((type & AHD_TRANS_GOAL) != 0) { - tinfo->goal.period = period; - tinfo->goal.offset = offset; - tinfo->goal.ppr_options = ppr_options; - } - - old_period = tinfo->curr.period; - old_offset = tinfo->curr.offset; - old_ppr = tinfo->curr.ppr_options; - - if ((type & AHD_TRANS_CUR) != 0 - && (old_period != period - || old_offset != offset - || old_ppr != ppr_options)) { - - update_needed++; - - tinfo->curr.period = period; - tinfo->curr.offset = offset; - tinfo->curr.ppr_options = ppr_options; - - ahd_send_async(ahd, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); - if (bootverbose) { - if (offset != 0) { - int options; - - printf("%s: target %d synchronous with " - "period = 0x%x, offset = 0x%x", - ahd_name(ahd), devinfo->target, - period, offset); - options = 0; - if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { - printf("(DT"); - options++; - } - if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - printf("%s", options ? "|IU" : "(IU"); - options++; - } - if ((ppr_options & MSG_EXT_PPR_RTI) != 0) { - printf("%s", options ? "|RTI" : "(RTI"); - options++; - } - if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) { - printf("%s", options ? "|QAS" : "(QAS"); - options++; - } - if (options != 0) - printf(")\n"); - else - printf("\n"); - } else { - printf("%s: target %d using " - "asynchronous transfers%s\n", - ahd_name(ahd), devinfo->target, - (ppr_options & MSG_EXT_PPR_QAS_REQ) != 0 - ? "(QAS)" : ""); - } - } - } - /* - * Always refresh the neg-table to handle the case of the - * sequencer setting the ENATNO bit for a MK_MESSAGE request. - * We will always renegotiate in that case if this is a - * packetized request. Also manage the busfree expected flag - * from this common routine so that we catch changes due to - * WDTR or SDTR messages. - */ - if ((type & AHD_TRANS_CUR) != 0) { - if (!paused) - ahd_pause(ahd); - ahd_update_neg_table(ahd, devinfo, &tinfo->curr); - if (!paused) - ahd_unpause(ahd); - if (ahd->msg_type != MSG_TYPE_NONE) { - if ((old_ppr & MSG_EXT_PPR_IU_REQ) - != (ppr_options & MSG_EXT_PPR_IU_REQ)) { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { - ahd_print_devinfo(ahd, devinfo); - printf("Expecting IU Change busfree\n"); - } -#endif - ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE - | MSG_FLAG_IU_REQ_CHANGED; - } - if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("PPR with IU_REQ outstanding\n"); -#endif - ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE; - } - } - } - - update_needed += ahd_update_neg_request(ahd, devinfo, tstate, - tinfo, AHD_NEG_TO_GOAL); - - if (update_needed && active) - ahd_update_pending_scbs(ahd); -} - -/* - * Update the user/goal/curr tables of wide negotiation - * parameters as well as, in the case of a current or active update, - * any data structures on the host controller. In the case of an - * active update, the specified target is currently talking to us on - * the bus, so the transfer parameter update must take effect - * immediately. - */ -void -ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - u_int width, u_int type, int paused) -{ - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - u_int oldwidth; - int active; - int update_needed; - - active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE; - update_needed = 0; - tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, - devinfo->target, &tstate); - - if ((type & AHD_TRANS_USER) != 0) - tinfo->user.width = width; - - if ((type & AHD_TRANS_GOAL) != 0) - tinfo->goal.width = width; - - oldwidth = tinfo->curr.width; - if ((type & AHD_TRANS_CUR) != 0 && oldwidth != width) { - - update_needed++; - - tinfo->curr.width = width; - ahd_send_async(ahd, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); - if (bootverbose) { - printf("%s: target %d using %dbit transfers\n", - ahd_name(ahd), devinfo->target, - 8 * (0x01 << width)); - } - } - - if ((type & AHD_TRANS_CUR) != 0) { - if (!paused) - ahd_pause(ahd); - ahd_update_neg_table(ahd, devinfo, &tinfo->curr); - if (!paused) - ahd_unpause(ahd); - } - - update_needed += ahd_update_neg_request(ahd, devinfo, tstate, - tinfo, AHD_NEG_TO_GOAL); - if (update_needed && active) - ahd_update_pending_scbs(ahd); - -} - -/* - * Update the current state of tagged queuing for a given target. - */ -void -ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - ahd_queue_alg alg) -{ - ahd_platform_set_tags(ahd, devinfo, alg); - ahd_send_async(ahd, devinfo->channel, devinfo->target, - devinfo->lun, AC_TRANSFER_NEG, &alg); -} - -static void -ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - struct ahd_transinfo *tinfo) -{ - ahd_mode_state saved_modes; - u_int period; - u_int ppr_opts; - u_int con_opts; - u_int offset; - u_int saved_negoaddr; - uint8_t iocell_opts[sizeof(ahd->iocell_opts)]; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - - saved_negoaddr = ahd_inb(ahd, NEGOADDR); - ahd_outb(ahd, NEGOADDR, devinfo->target); - period = tinfo->period; - offset = tinfo->offset; - memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts)); - ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ - |MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI); - con_opts = 0; - if (period == 0) - period = AHD_SYNCRATE_ASYNC; - if (period == AHD_SYNCRATE_160) { - - if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) { - /* - * When the SPI4 spec was finalized, PACE transfers - * was not made a configurable option in the PPR - * message. Instead it is assumed to be enabled for - * any syncrate faster than 80MHz. Nevertheless, - * Harpoon2A4 allows this to be configurable. - * - * Harpoon2A4 also assumes at most 2 data bytes per - * negotiated REQ/ACK offset. Paced transfers take - * 4, so we must adjust our offset. - */ - ppr_opts |= PPROPT_PACE; - offset *= 2; - - /* - * Harpoon2A assumed that there would be a - * fallback rate between 160MHz and 80Mhz, - * so 7 is used as the period factor rather - * than 8 for 160MHz. - */ - period = AHD_SYNCRATE_REVA_160; - } - if ((tinfo->ppr_options & MSG_EXT_PPR_PCOMP_EN) == 0) - iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= - ~AHD_PRECOMP_MASK; - } else { - /* - * Precomp should be disabled for non-paced transfers. - */ - iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; - - if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0 - && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) { - /* - * Slow down our CRC interval to be - * compatible with devices that can't - * handle a CRC at full speed. - */ - con_opts |= ENSLOWCRC; - } - } - - ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW); - ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_PRECOMP_SLEW_INDEX]); - ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_AMPLITUDE); - ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_AMPLITUDE_INDEX]); - - ahd_outb(ahd, NEGPERIOD, period); - ahd_outb(ahd, NEGPPROPTS, ppr_opts); - ahd_outb(ahd, NEGOFFSET, offset); - - if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT) - con_opts |= WIDEXFER; - - /* - * During packetized transfers, the target will - * give us the oportunity to send command packets - * without us asserting attention. - */ - if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0) - con_opts |= ENAUTOATNO; - ahd_outb(ahd, NEGCONOPTS, con_opts); - ahd_outb(ahd, NEGOADDR, saved_negoaddr); - ahd_restore_modes(ahd, saved_modes); -} - -/* - * When the transfer settings for a connection change, setup for - * negotiation in pending SCBs to effect the change as quickly as - * possible. We also cancel any negotiations that are scheduled - * for inflight SCBs that have not been started yet. - */ -static void -ahd_update_pending_scbs(struct ahd_softc *ahd) -{ - struct scb *pending_scb; - int pending_scb_count; - int i; - int paused; - u_int saved_scbptr; - ahd_mode_state saved_modes; - - /* - * Traverse the pending SCB list and ensure that all of the - * SCBs there have the proper settings. We can only safely - * clear the negotiation required flag (setting requires the - * execution queue to be modified) and this is only possible - * if we are not already attempting to select out for this - * SCB. For this reason, all callers only call this routine - * if we are changing the negotiation settings for the currently - * active transaction on the bus. - */ - pending_scb_count = 0; - LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { - struct ahd_devinfo devinfo; - struct hardware_scb *pending_hscb; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - - ahd_scb_devinfo(ahd, &devinfo, pending_scb); - tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, - devinfo.our_scsiid, - devinfo.target, &tstate); - pending_hscb = pending_scb->hscb; - if ((tstate->auto_negotiate & devinfo.target_mask) == 0 - && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) { - pending_scb->flags &= ~SCB_AUTO_NEGOTIATE; - pending_hscb->control &= ~MK_MESSAGE; - } - ahd_sync_scb(ahd, pending_scb, - BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - pending_scb_count++; - } - - if (pending_scb_count == 0) - return; - - if (ahd_is_paused(ahd)) { - paused = 1; - } else { - paused = 0; - ahd_pause(ahd); - } - - /* - * Force the sequencer to reinitialize the selection for - * the command at the head of the execution queue if it - * has already been setup. The negotiation changes may - * effect whether we select-out with ATN. - */ - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); - saved_scbptr = ahd_get_scbptr(ahd); - /* Ensure that the hscbs down on the card match the new information */ - for (i = 0; i < ahd->scb_data.maxhscbs; i++) { - struct hardware_scb *pending_hscb; - u_int control; - u_int scb_tag; - - ahd_set_scbptr(ahd, i); - scb_tag = i; - pending_scb = ahd_lookup_scb(ahd, scb_tag); - if (pending_scb == NULL) - continue; - - pending_hscb = pending_scb->hscb; - control = ahd_inb_scbram(ahd, SCB_CONTROL); - control &= ~MK_MESSAGE; - control |= pending_hscb->control & MK_MESSAGE; - ahd_outb(ahd, SCB_CONTROL, control); - } - ahd_set_scbptr(ahd, saved_scbptr); - ahd_restore_modes(ahd, saved_modes); - - if (paused == 0) - ahd_unpause(ahd); -} - -/**************************** Pathing Information *****************************/ -static void -ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - ahd_mode_state saved_modes; - u_int saved_scsiid; - role_t role; - int our_id; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - - if (ahd_inb(ahd, SSTAT0) & TARGET) - role = ROLE_TARGET; - else - role = ROLE_INITIATOR; - - if (role == ROLE_TARGET - && (ahd_inb(ahd, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) { - /* We were selected, so pull our id from TARGIDIN */ - our_id = ahd_inb(ahd, TARGIDIN) & OID; - } else if (role == ROLE_TARGET) - our_id = ahd_inb(ahd, TOWNID); - else - our_id = ahd_inb(ahd, IOWNID); - - saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); - ahd_compile_devinfo(devinfo, - our_id, - SCSIID_TARGET(ahd, saved_scsiid), - ahd_inb(ahd, SAVED_LUN), - SCSIID_CHANNEL(ahd, saved_scsiid), - role); - ahd_restore_modes(ahd, saved_modes); -} - -void -ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - printf("%s:%c:%d:%d: ", ahd_name(ahd), 'A', - devinfo->target, devinfo->lun); -} - -struct ahd_phase_table_entry* -ahd_lookup_phase_entry(int phase) -{ - struct ahd_phase_table_entry *entry; - struct ahd_phase_table_entry *last_entry; - - /* - * num_phases doesn't include the default entry which - * will be returned if the phase doesn't match. - */ - last_entry = &ahd_phase_table[num_phases]; - for (entry = ahd_phase_table; entry < last_entry; entry++) { - if (phase == entry->phase) - break; - } - return (entry); -} - -void -ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target, - u_int lun, char channel, role_t role) -{ - devinfo->our_scsiid = our_id; - devinfo->target = target; - devinfo->lun = lun; - devinfo->target_offset = target; - devinfo->channel = channel; - devinfo->role = role; - if (channel == 'B') - devinfo->target_offset += 8; - devinfo->target_mask = (0x01 << devinfo->target_offset); -} - -static void -ahd_scb_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - struct scb *scb) -{ - role_t role; - int our_id; - - our_id = SCSIID_OUR_ID(scb->hscb->scsiid); - role = ROLE_INITIATOR; - if ((scb->hscb->control & TARGET_SCB) != 0) - role = ROLE_TARGET; - ahd_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahd, scb), - SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahd, scb), role); -} - - -/************************ Message Phase Processing ****************************/ -/* - * When an initiator transaction with the MK_MESSAGE flag either reconnects - * or enters the initial message out phase, we are interrupted. Fill our - * outgoing message buffer with the appropriate message and beging handing - * the message phase(s) manually. - */ -static void -ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - struct scb *scb) -{ - /* - * To facilitate adding multiple messages together, - * each routine should increment the index and len - * variables instead of setting them explicitly. - */ - ahd->msgout_index = 0; - ahd->msgout_len = 0; - - if (ahd_currently_packetized(ahd)) - ahd->msg_flags |= MSG_FLAG_PACKETIZED; - - if (ahd->send_msg_perror - && ahd_inb(ahd, MSG_OUT) == HOST_MSG) { - ahd->msgout_buf[ahd->msgout_index++] = ahd->send_msg_perror; - ahd->msgout_len++; - ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("Setting up for Parity Error delivery\n"); -#endif - return; - } else if (scb == NULL) { - printf("%s: WARNING. No pending message for " - "I_T msgin. Issuing NO-OP\n", ahd_name(ahd)); - ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP; - ahd->msgout_len++; - ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; - return; - } - - if ((scb->flags & SCB_DEVICE_RESET) == 0 - && (scb->flags & SCB_PACKETIZED) == 0 - && ahd_inb(ahd, MSG_OUT) == MSG_IDENTIFYFLAG) { - u_int identify_msg; - - identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb); - if ((scb->hscb->control & DISCENB) != 0) - identify_msg |= MSG_IDENTIFY_DISCFLAG; - ahd->msgout_buf[ahd->msgout_index++] = identify_msg; - ahd->msgout_len++; - - if ((scb->hscb->control & TAG_ENB) != 0) { - ahd->msgout_buf[ahd->msgout_index++] = - scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE); - ahd->msgout_buf[ahd->msgout_index++] = SCB_GET_TAG(scb); - ahd->msgout_len += 2; - } - } - - if (scb->flags & SCB_DEVICE_RESET) { - ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET; - ahd->msgout_len++; - ahd_print_path(ahd, scb); - printf("Bus Device Reset Message Sent\n"); - /* - * Clear our selection hardware in advance of - * the busfree. We may have an entry in the waiting - * Q for this target, and we don't want to go about - * selecting while we handle the busfree and blow it - * away. - */ - ahd_outb(ahd, SCSISEQ0, 0); - } else if ((scb->flags & SCB_ABORT) != 0) { - - if ((scb->hscb->control & TAG_ENB) != 0) { - ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG; - } else { - ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT; - } - ahd->msgout_len++; - ahd_print_path(ahd, scb); - printf("Abort%s Message Sent\n", - (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : ""); - /* - * Clear our selection hardware in advance of - * the busfree. We may have an entry in the waiting - * Q for this target, and we don't want to go about - * selecting while we handle the busfree and blow it - * away. - */ - ahd_outb(ahd, SCSISEQ0, 0); - } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) { - ahd_build_transfer_msg(ahd, devinfo); - /* - * Clear our selection hardware in advance of potential - * PPR IU status change busfree. We may have an entry in - * the waiting Q for this target, and we don't want to go - * about selecting while we handle the busfree and blow - * it away. - */ - ahd_outb(ahd, SCSISEQ0, 0); - } else { - printf("ahd_intr: AWAITING_MSG for an SCB that " - "does not have a waiting message\n"); - printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid, - devinfo->target_mask); - panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x " - "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control, - ahd_inb(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT), - scb->flags); - } - - /* - * Clear the MK_MESSAGE flag from the SCB so we aren't - * asked to send this message again. - */ - ahd_outb(ahd, SCB_CONTROL, - ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE); - scb->hscb->control &= ~MK_MESSAGE; - ahd->msgout_index = 0; - ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; -} - -/* - * Build an appropriate transfer negotiation message for the - * currently active target. - */ -static void -ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - /* - * We need to initiate transfer negotiations. - * If our current and goal settings are identical, - * we want to renegotiate due to a check condition. - */ - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - int dowide; - int dosync; - int doppr; - u_int period; - u_int ppr_options; - u_int offset; - - tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, - devinfo->target, &tstate); - /* - * Filter our period based on the current connection. - * If we can't perform DT transfers on this segment (not in LVD - * mode for instance), then our decision to issue a PPR message - * may change. - */ - period = tinfo->goal.period; - ppr_options = tinfo->goal.ppr_options; - /* Target initiated PPR is not allowed in the SCSI spec */ - if (devinfo->role == ROLE_TARGET) - ppr_options = 0; - ahd_devlimited_syncrate(ahd, tinfo, &period, - &ppr_options, devinfo->role); - dowide = tinfo->curr.width != tinfo->goal.width; - dosync = tinfo->curr.period != period; - /* - * Only use PPR if we have options that need it, even if the device - * claims to support it. There might be an expander in the way - * that doesn't. - */ - doppr = ppr_options != 0; - - if (!dowide && !dosync && !doppr) { - dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT; - dosync = tinfo->goal.period != 0; - } - - if (!dowide && !dosync && !doppr) { - /* - * Force async with a WDTR message if we have a wide bus, - * or just issue an SDTR with a 0 offset. - */ - if ((ahd->features & AHD_WIDE) != 0) - dowide = 1; - else - dosync = 1; - - if (bootverbose) { - ahd_print_devinfo(ahd, devinfo); - printf("Ensuring async\n"); - } - } - /* Target initiated PPR is not allowed in the SCSI spec */ - if (devinfo->role == ROLE_TARGET) - doppr = 0; - - /* - * Both the PPR message and SDTR message require the - * goal syncrate to be limited to what the target device - * is capable of handling (based on whether an LVD->SE - * expander is on the bus), so combine these two cases. - * Regardless, guarantee that if we are using WDTR and SDTR - * messages that WDTR comes first. - */ - if (doppr || (dosync && !dowide)) { - - offset = tinfo->goal.offset; - ahd_validate_offset(ahd, tinfo, period, &offset, - doppr ? tinfo->goal.width - : tinfo->curr.width, - devinfo->role); - if (doppr) { - ahd_construct_ppr(ahd, devinfo, period, offset, - tinfo->goal.width, ppr_options); - } else { - ahd_construct_sdtr(ahd, devinfo, period, offset); - } - } else { - ahd_construct_wdtr(ahd, devinfo, tinfo->goal.width); - } -} - -/* - * Build a synchronous negotiation message in our message - * buffer based on the input parameters. - */ -static void -ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - u_int period, u_int offset) -{ - if (offset == 0) - period = AHD_ASYNC_XFER_PERIOD; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR; - ahd->msgout_buf[ahd->msgout_index++] = period; - ahd->msgout_buf[ahd->msgout_index++] = offset; - ahd->msgout_len += 5; - if (bootverbose) { - printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n", - ahd_name(ahd), devinfo->channel, devinfo->target, - devinfo->lun, period, offset); - } -} - -/* - * Build a wide negotiateion message in our message - * buffer based on the input parameters. - */ -static void -ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - u_int bus_width) -{ - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR; - ahd->msgout_buf[ahd->msgout_index++] = bus_width; - ahd->msgout_len += 4; - if (bootverbose) { - printf("(%s:%c:%d:%d): Sending WDTR %x\n", - ahd_name(ahd), devinfo->channel, devinfo->target, - devinfo->lun, bus_width); - } -} - -/* - * Build a parallel protocol request message in our message - * buffer based on the input parameters. - */ -static void -ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - u_int period, u_int offset, u_int bus_width, - u_int ppr_options) -{ - /* - * Always request precompensation from - * the other target if we are running - * at paced syncrates. - */ - if (period <= AHD_SYNCRATE_PACED) - ppr_options |= MSG_EXT_PPR_PCOMP_EN; - if (offset == 0) - period = AHD_ASYNC_XFER_PERIOD; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN; - ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR; - ahd->msgout_buf[ahd->msgout_index++] = period; - ahd->msgout_buf[ahd->msgout_index++] = 0; - ahd->msgout_buf[ahd->msgout_index++] = offset; - ahd->msgout_buf[ahd->msgout_index++] = bus_width; - ahd->msgout_buf[ahd->msgout_index++] = ppr_options; - ahd->msgout_len += 8; - if (bootverbose) { - printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, " - "offset %x, ppr_options %x\n", ahd_name(ahd), - devinfo->channel, devinfo->target, devinfo->lun, - bus_width, period, offset, ppr_options); - } -} - -/* - * Clear any active message state. - */ -static void -ahd_clear_msg_state(struct ahd_softc *ahd) -{ - ahd_mode_state saved_modes; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd->send_msg_perror = 0; - ahd->msg_flags = MSG_FLAG_NONE; - ahd->msgout_len = 0; - ahd->msgin_index = 0; - ahd->msg_type = MSG_TYPE_NONE; - if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0) { - /* - * The target didn't care to respond to our - * message request, so clear ATN. - */ - ahd_outb(ahd, CLRSINT1, CLRATNO); - } - ahd_outb(ahd, MSG_OUT, MSG_NOOP); - ahd_outb(ahd, SEQ_FLAGS2, - ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING); - ahd_restore_modes(ahd, saved_modes); -} - -/* - * Manual message loop handler. - */ -static void -ahd_handle_message_phase(struct ahd_softc *ahd) -{ - struct ahd_devinfo devinfo; - u_int bus_phase; - int end_session; - - ahd_fetch_devinfo(ahd, &devinfo); - end_session = FALSE; - bus_phase = ahd_inb(ahd, LASTPHASE); - - if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) { - printf("LQIRETRY for LQIPHASE_OUTPKT\n"); - ahd_outb(ahd, LQCTL2, LQIRETRY); - } -reswitch: - switch (ahd->msg_type) { - case MSG_TYPE_INITIATOR_MSGOUT: - { - int lastbyte; - int phasemis; - int msgdone; - - if (ahd->msgout_len == 0 && ahd->send_msg_perror == 0) - panic("HOST_MSG_LOOP interrupt with no active message"); - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { - ahd_print_devinfo(ahd, &devinfo); - printf("INITIATOR_MSG_OUT"); - } -#endif - phasemis = bus_phase != P_MESGOUT; - if (phasemis) { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { - printf(" PHASEMIS %s\n", - ahd_lookup_phase_entry(bus_phase) - ->phasemsg); - } -#endif - if (bus_phase == P_MESGIN) { - /* - * Change gears and see if - * this messages is of interest to - * us or should be passed back to - * the sequencer. - */ - ahd_outb(ahd, CLRSINT1, CLRATNO); - ahd->send_msg_perror = 0; - ahd->msg_type = MSG_TYPE_INITIATOR_MSGIN; - ahd->msgin_index = 0; - goto reswitch; - } - end_session = TRUE; - break; - } - - if (ahd->send_msg_perror) { - ahd_outb(ahd, CLRSINT1, CLRATNO); - ahd_outb(ahd, CLRSINT1, CLRREQINIT); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf(" byte 0x%x\n", ahd->send_msg_perror); -#endif - /* - * If we are notifying the target of a CRC error - * during packetized operations, the target is - * within its rights to acknowledge our message - * with a busfree. - */ - if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0 - && ahd->send_msg_perror == MSG_INITIATOR_DET_ERR) - ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE; - - ahd_outb(ahd, RETURN_2, ahd->send_msg_perror); - ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE); - break; - } - - msgdone = ahd->msgout_index == ahd->msgout_len; - if (msgdone) { - /* - * The target has requested a retry. - * Re-assert ATN, reset our message index to - * 0, and try again. - */ - ahd->msgout_index = 0; - ahd_assert_atn(ahd); - } - - lastbyte = ahd->msgout_index == (ahd->msgout_len - 1); - if (lastbyte) { - /* Last byte is signified by dropping ATN */ - ahd_outb(ahd, CLRSINT1, CLRATNO); - } - - /* - * Clear our interrupt status and present - * the next byte on the bus. - */ - ahd_outb(ahd, CLRSINT1, CLRREQINIT); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf(" byte 0x%x\n", - ahd->msgout_buf[ahd->msgout_index]); -#endif - ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]); - ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE); - break; - } - case MSG_TYPE_INITIATOR_MSGIN: - { - int phasemis; - int message_done; - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { - ahd_print_devinfo(ahd, &devinfo); - printf("INITIATOR_MSG_IN"); - } -#endif - phasemis = bus_phase != P_MESGIN; - if (phasemis) { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { - printf(" PHASEMIS %s\n", - ahd_lookup_phase_entry(bus_phase) - ->phasemsg); - } -#endif - ahd->msgin_index = 0; - if (bus_phase == P_MESGOUT - && (ahd->send_msg_perror != 0 - || (ahd->msgout_len != 0 - && ahd->msgout_index == 0))) { - ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; - goto reswitch; - } - end_session = TRUE; - break; - } - - /* Pull the byte in without acking it */ - ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf(" byte 0x%x\n", - ahd->msgin_buf[ahd->msgin_index]); -#endif - - message_done = ahd_parse_msg(ahd, &devinfo); - - if (message_done) { - /* - * Clear our incoming message buffer in case there - * is another message following this one. - */ - ahd->msgin_index = 0; - - /* - * If this message illicited a response, - * assert ATN so the target takes us to the - * message out phase. - */ - if (ahd->msgout_len != 0) { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { - ahd_print_devinfo(ahd, &devinfo); - printf("Asserting ATN for response\n"); - } -#endif - ahd_assert_atn(ahd); - } - } else - ahd->msgin_index++; - - if (message_done == MSGLOOP_TERMINATED) { - end_session = TRUE; - } else { - /* Ack the byte */ - ahd_outb(ahd, CLRSINT1, CLRREQINIT); - ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_READ); - } - break; - } - case MSG_TYPE_TARGET_MSGIN: - { - int msgdone; - int msgout_request; - - /* - * By default, the message loop will continue. - */ - ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG); - - if (ahd->msgout_len == 0) - panic("Target MSGIN with no active message"); - - /* - * If we interrupted a mesgout session, the initiator - * will not know this until our first REQ. So, we - * only honor mesgout requests after we've sent our - * first byte. - */ - if ((ahd_inb(ahd, SCSISIGI) & ATNI) != 0 - && ahd->msgout_index > 0) - msgout_request = TRUE; - else - msgout_request = FALSE; - - if (msgout_request) { - - /* - * Change gears and see if - * this messages is of interest to - * us or should be passed back to - * the sequencer. - */ - ahd->msg_type = MSG_TYPE_TARGET_MSGOUT; - ahd_outb(ahd, SCSISIGO, P_MESGOUT | BSYO); - ahd->msgin_index = 0; - /* Dummy read to REQ for first byte */ - ahd_inb(ahd, SCSIDAT); - ahd_outb(ahd, SXFRCTL0, - ahd_inb(ahd, SXFRCTL0) | SPIOEN); - break; - } - - msgdone = ahd->msgout_index == ahd->msgout_len; - if (msgdone) { - ahd_outb(ahd, SXFRCTL0, - ahd_inb(ahd, SXFRCTL0) & ~SPIOEN); - end_session = TRUE; - break; - } - - /* - * Present the next byte on the bus. - */ - ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) | SPIOEN); - ahd_outb(ahd, SCSIDAT, ahd->msgout_buf[ahd->msgout_index++]); - break; - } - case MSG_TYPE_TARGET_MSGOUT: - { - int lastbyte; - int msgdone; - - /* - * By default, the message loop will continue. - */ - ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG); - - /* - * The initiator signals that this is - * the last byte by dropping ATN. - */ - lastbyte = (ahd_inb(ahd, SCSISIGI) & ATNI) == 0; - - /* - * Read the latched byte, but turn off SPIOEN first - * so that we don't inadvertently cause a REQ for the - * next byte. - */ - ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) & ~SPIOEN); - ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIDAT); - msgdone = ahd_parse_msg(ahd, &devinfo); - if (msgdone == MSGLOOP_TERMINATED) { - /* - * The message is *really* done in that it caused - * us to go to bus free. The sequencer has already - * been reset at this point, so pull the ejection - * handle. - */ - return; - } - - ahd->msgin_index++; - - /* - * XXX Read spec about initiator dropping ATN too soon - * and use msgdone to detect it. - */ - if (msgdone == MSGLOOP_MSGCOMPLETE) { - ahd->msgin_index = 0; - - /* - * If this message illicited a response, transition - * to the Message in phase and send it. - */ - if (ahd->msgout_len != 0) { - ahd_outb(ahd, SCSISIGO, P_MESGIN | BSYO); - ahd_outb(ahd, SXFRCTL0, - ahd_inb(ahd, SXFRCTL0) | SPIOEN); - ahd->msg_type = MSG_TYPE_TARGET_MSGIN; - ahd->msgin_index = 0; - break; - } - } - - if (lastbyte) - end_session = TRUE; - else { - /* Ask for the next byte. */ - ahd_outb(ahd, SXFRCTL0, - ahd_inb(ahd, SXFRCTL0) | SPIOEN); - } - - break; - } - default: - panic("Unknown REQINIT message type"); - } - - if (end_session) { - if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) { - printf("%s: Returning to Idle Loop\n", - ahd_name(ahd)); - ahd_outb(ahd, LASTPHASE, P_BUSFREE); - ahd_clear_msg_state(ahd); - ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); - } else { - ahd_clear_msg_state(ahd); - ahd_outb(ahd, RETURN_1, EXIT_MSG_LOOP); - } - } -} - -/* - * See if we sent a particular extended message to the target. - * If "full" is true, return true only if the target saw the full - * message. If "full" is false, return true if the target saw at - * least the first byte of the message. - */ -static int -ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full) -{ - int found; - u_int index; - - found = FALSE; - index = 0; - - while (index < ahd->msgout_len) { - if (ahd->msgout_buf[index] == MSG_EXTENDED) { - u_int end_index; - - end_index = index + 1 + ahd->msgout_buf[index + 1]; - if (ahd->msgout_buf[index+2] == msgval - && type == AHDMSG_EXT) { - - if (full) { - if (ahd->msgout_index > end_index) - found = TRUE; - } else if (ahd->msgout_index > index) - found = TRUE; - } - index = end_index; - } else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK - && ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) { - - /* Skip tag type and tag id or residue param*/ - index += 2; - } else { - /* Single byte message */ - if (type == AHDMSG_1B - && ahd->msgout_index > index - && (ahd->msgout_buf[index] == msgval - || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0 - && msgval == MSG_IDENTIFYFLAG))) - found = TRUE; - index++; - } - - if (found) - break; - } - return (found); -} - -/* - * Wait for a complete incoming message, parse it, and respond accordingly. - */ -static int -ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - int reject; - int done; - int response; - - done = MSGLOOP_IN_PROG; - response = FALSE; - reject = FALSE; - tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, - devinfo->target, &tstate); - - /* - * Parse as much of the message as is availible, - * rejecting it if we don't support it. When - * the entire message is availible and has been - * handled, return MSGLOOP_MSGCOMPLETE, indicating - * that we have parsed an entire message. - * - * In the case of extended messages, we accept the length - * byte outright and perform more checking once we know the - * extended message type. - */ - switch (ahd->msgin_buf[0]) { - case MSG_DISCONNECT: - case MSG_SAVEDATAPOINTER: - case MSG_CMDCOMPLETE: - case MSG_RESTOREPOINTERS: - case MSG_IGN_WIDE_RESIDUE: - /* - * End our message loop as these are messages - * the sequencer handles on its own. - */ - done = MSGLOOP_TERMINATED; - break; - case MSG_MESSAGE_REJECT: - response = ahd_handle_msg_reject(ahd, devinfo); - /* FALLTHROUGH */ - case MSG_NOOP: - done = MSGLOOP_MSGCOMPLETE; - break; - case MSG_EXTENDED: - { - /* Wait for enough of the message to begin validation */ - if (ahd->msgin_index < 2) - break; - switch (ahd->msgin_buf[2]) { - case MSG_EXT_SDTR: - { - u_int period; - u_int ppr_options; - u_int offset; - u_int saved_offset; - - if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) { - reject = TRUE; - break; - } - - /* - * Wait until we have both args before validating - * and acting on this message. - * - * Add one to MSG_EXT_SDTR_LEN to account for - * the extended message preamble. - */ - if (ahd->msgin_index < (MSG_EXT_SDTR_LEN + 1)) - break; - - period = ahd->msgin_buf[3]; - ppr_options = 0; - saved_offset = offset = ahd->msgin_buf[4]; - ahd_devlimited_syncrate(ahd, tinfo, &period, - &ppr_options, devinfo->role); - ahd_validate_offset(ahd, tinfo, period, &offset, - tinfo->curr.width, devinfo->role); - if (bootverbose) { - printf("(%s:%c:%d:%d): Received " - "SDTR period %x, offset %x\n\t" - "Filtered to period %x, offset %x\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun, - ahd->msgin_buf[3], saved_offset, - period, offset); - } - ahd_set_syncrate(ahd, devinfo, period, - offset, ppr_options, - AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, - /*paused*/TRUE); - - /* - * See if we initiated Sync Negotiation - * and didn't have to fall down to async - * transfers. - */ - if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) { - /* We started it */ - if (saved_offset != offset) { - /* Went too low - force async */ - reject = TRUE; - } - } else { - /* - * Send our own SDTR in reply - */ - if (bootverbose - && devinfo->role == ROLE_INITIATOR) { - printf("(%s:%c:%d:%d): Target " - "Initiated SDTR\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun); - } - ahd->msgout_index = 0; - ahd->msgout_len = 0; - ahd_construct_sdtr(ahd, devinfo, - period, offset); - ahd->msgout_index = 0; - response = TRUE; - } - done = MSGLOOP_MSGCOMPLETE; - break; - } - case MSG_EXT_WDTR: - { - u_int bus_width; - u_int saved_width; - u_int sending_reply; - - sending_reply = FALSE; - if (ahd->msgin_buf[1] != MSG_EXT_WDTR_LEN) { - reject = TRUE; - break; - } - - /* - * Wait until we have our arg before validating - * and acting on this message. - * - * Add one to MSG_EXT_WDTR_LEN to account for - * the extended message preamble. - */ - if (ahd->msgin_index < (MSG_EXT_WDTR_LEN + 1)) - break; - - bus_width = ahd->msgin_buf[3]; - saved_width = bus_width; - ahd_validate_width(ahd, tinfo, &bus_width, - devinfo->role); - if (bootverbose) { - printf("(%s:%c:%d:%d): Received WDTR " - "%x filtered to %x\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun, - saved_width, bus_width); - } - - if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) { - /* - * Don't send a WDTR back to the - * target, since we asked first. - * If the width went higher than our - * request, reject it. - */ - if (saved_width > bus_width) { - reject = TRUE; - printf("(%s:%c:%d:%d): requested %dBit " - "transfers. Rejecting...\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun, - 8 * (0x01 << bus_width)); - bus_width = 0; - } - } else { - /* - * Send our own WDTR in reply - */ - if (bootverbose - && devinfo->role == ROLE_INITIATOR) { - printf("(%s:%c:%d:%d): Target " - "Initiated WDTR\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun); - } - ahd->msgout_index = 0; - ahd->msgout_len = 0; - ahd_construct_wdtr(ahd, devinfo, bus_width); - ahd->msgout_index = 0; - response = TRUE; - sending_reply = TRUE; - } - ahd_set_width(ahd, devinfo, bus_width, - AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, - /*paused*/TRUE); - /* After a wide message, we are async */ - ahd_set_syncrate(ahd, devinfo, /*period*/0, - /*offset*/0, /*ppr_options*/0, - AHD_TRANS_ACTIVE, /*paused*/TRUE); - if (sending_reply == FALSE && reject == FALSE) { - - if (tinfo->goal.offset) { - ahd->msgout_index = 0; - ahd->msgout_len = 0; - ahd_build_transfer_msg(ahd, devinfo); - ahd->msgout_index = 0; - response = TRUE; - } - } - done = MSGLOOP_MSGCOMPLETE; - break; - } - case MSG_EXT_PPR: - { - u_int period; - u_int offset; - u_int bus_width; - u_int ppr_options; - u_int saved_width; - u_int saved_offset; - u_int saved_ppr_options; - - if (ahd->msgin_buf[1] != MSG_EXT_PPR_LEN) { - reject = TRUE; - break; - } - - /* - * Wait until we have all args before validating - * and acting on this message. - * - * Add one to MSG_EXT_PPR_LEN to account for - * the extended message preamble. - */ - if (ahd->msgin_index < (MSG_EXT_PPR_LEN + 1)) - break; - - period = ahd->msgin_buf[3]; - offset = ahd->msgin_buf[5]; - bus_width = ahd->msgin_buf[6]; - saved_width = bus_width; - ppr_options = ahd->msgin_buf[7]; - /* - * According to the spec, a DT only - * period factor with no DT option - * set implies async. - */ - if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0 - && period <= 9) - offset = 0; - saved_ppr_options = ppr_options; - saved_offset = offset; - - /* - * Transfer options are only available if we - * are negotiating wide. - */ - if (bus_width == 0) - ppr_options &= MSG_EXT_PPR_QAS_REQ; - - ahd_validate_width(ahd, tinfo, &bus_width, - devinfo->role); - ahd_devlimited_syncrate(ahd, tinfo, &period, - &ppr_options, devinfo->role); - ahd_validate_offset(ahd, tinfo, period, &offset, - bus_width, devinfo->role); - - if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) { - /* - * If we are unable to do any of the - * requested options (we went too low), - * then we'll have to reject the message. - */ - if (saved_width > bus_width - || saved_offset != offset - || saved_ppr_options != ppr_options) { - reject = TRUE; - period = 0; - offset = 0; - bus_width = 0; - ppr_options = 0; - } - } else { - if (devinfo->role != ROLE_TARGET) - printf("(%s:%c:%d:%d): Target " - "Initiated PPR\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun); - else - printf("(%s:%c:%d:%d): Initiator " - "Initiated PPR\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun); - ahd->msgout_index = 0; - ahd->msgout_len = 0; - ahd_construct_ppr(ahd, devinfo, period, offset, - bus_width, ppr_options); - ahd->msgout_index = 0; - response = TRUE; - } - if (bootverbose) { - printf("(%s:%c:%d:%d): Received PPR width %x, " - "period %x, offset %x,options %x\n" - "\tFiltered to width %x, period %x, " - "offset %x, options %x\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun, - saved_width, ahd->msgin_buf[3], - saved_offset, saved_ppr_options, - bus_width, period, offset, ppr_options); - } - ahd_set_width(ahd, devinfo, bus_width, - AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, - /*paused*/TRUE); - ahd_set_syncrate(ahd, devinfo, period, - offset, ppr_options, - AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, - /*paused*/TRUE); - - done = MSGLOOP_MSGCOMPLETE; - break; - } - default: - /* Unknown extended message. Reject it. */ - reject = TRUE; - break; - } - break; - } -#ifdef AHD_TARGET_MODE - case MSG_BUS_DEV_RESET: - ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD, - CAM_BDR_SENT, - "Bus Device Reset Received", - /*verbose_level*/0); - ahd_restart(ahd); - done = MSGLOOP_TERMINATED; - break; - case MSG_ABORT_TAG: - case MSG_ABORT: - case MSG_CLEAR_QUEUE: - { - int tag; - - /* Target mode messages */ - if (devinfo->role != ROLE_TARGET) { - reject = TRUE; - break; - } - tag = SCB_LIST_NULL; - if (ahd->msgin_buf[0] == MSG_ABORT_TAG) - tag = ahd_inb(ahd, INITIATOR_TAG); - ahd_abort_scbs(ahd, devinfo->target, devinfo->channel, - devinfo->lun, tag, ROLE_TARGET, - CAM_REQ_ABORTED); - - tstate = ahd->enabled_targets[devinfo->our_scsiid]; - if (tstate != NULL) { - struct ahd_tmode_lstate* lstate; - - lstate = tstate->enabled_luns[devinfo->lun]; - if (lstate != NULL) { - ahd_queue_lstate_event(ahd, lstate, - devinfo->our_scsiid, - ahd->msgin_buf[0], - /*arg*/tag); - ahd_send_lstate_events(ahd, lstate); - } - } - ahd_restart(ahd); - done = MSGLOOP_TERMINATED; - break; - } -#endif - case MSG_QAS_REQUEST: -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - printf("%s: QAS request. SCSISIGI == 0x%x\n", - ahd_name(ahd), ahd_inb(ahd, SCSISIGI)); -#endif - ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE; - /* FALLTHROUGH */ - case MSG_TERM_IO_PROC: - default: - reject = TRUE; - break; - } - - if (reject) { - /* - * Setup to reject the message. - */ - ahd->msgout_index = 0; - ahd->msgout_len = 1; - ahd->msgout_buf[0] = MSG_MESSAGE_REJECT; - done = MSGLOOP_MSGCOMPLETE; - response = TRUE; - } - - if (done != MSGLOOP_IN_PROG && !response) - /* Clear the outgoing message buffer */ - ahd->msgout_len = 0; - - return (done); -} - -/* - * Process a message reject message. - */ -static int -ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - /* - * What we care about here is if we had an - * outstanding SDTR or WDTR message for this - * target. If we did, this is a signal that - * the target is refusing negotiation. - */ - struct scb *scb; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - u_int scb_index; - u_int last_msg; - int response = 0; - - scb_index = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scb_index); - tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, - devinfo->our_scsiid, - devinfo->target, &tstate); - /* Might be necessary */ - last_msg = ahd_inb(ahd, LAST_MSG); - - if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) { - if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/TRUE) - && tinfo->goal.period <= AHD_SYNCRATE_PACED) { - /* - * Target may not like our SPI-4 PPR Options. - * Attempt to negotiate 80MHz which will turn - * off these options. - */ - if (bootverbose) { - printf("(%s:%c:%d:%d): PPR Rejected. " - "Trying simple U160 PPR\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun); - } - tinfo->goal.period = AHD_SYNCRATE_DT; - tinfo->goal.ppr_options &= MSG_EXT_PPR_IU_REQ - | MSG_EXT_PPR_QAS_REQ - | MSG_EXT_PPR_DT_REQ; - } else { - /* - * Target does not support the PPR message. - * Attempt to negotiate SPI-2 style. - */ - if (bootverbose) { - printf("(%s:%c:%d:%d): PPR Rejected. " - "Trying WDTR/SDTR\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun); - } - tinfo->goal.ppr_options = 0; - tinfo->curr.transport_version = 2; - tinfo->goal.transport_version = 2; - } - ahd->msgout_index = 0; - ahd->msgout_len = 0; - ahd_build_transfer_msg(ahd, devinfo); - ahd->msgout_index = 0; - response = 1; - } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) { - - /* note 8bit xfers */ - printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using " - "8bit transfers\n", ahd_name(ahd), - devinfo->channel, devinfo->target, devinfo->lun); - ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, - /*paused*/TRUE); - /* - * No need to clear the sync rate. If the target - * did not accept the command, our syncrate is - * unaffected. If the target started the negotiation, - * but rejected our response, we already cleared the - * sync rate before sending our WDTR. - */ - if (tinfo->goal.offset != tinfo->curr.offset) { - - /* Start the sync negotiation */ - ahd->msgout_index = 0; - ahd->msgout_len = 0; - ahd_build_transfer_msg(ahd, devinfo); - ahd->msgout_index = 0; - response = 1; - } - } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) { - /* note asynch xfers and clear flag */ - ahd_set_syncrate(ahd, devinfo, /*period*/0, - /*offset*/0, /*ppr_options*/0, - AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, - /*paused*/TRUE); - printf("(%s:%c:%d:%d): refuses synchronous negotiation. " - "Using asynchronous transfers\n", - ahd_name(ahd), devinfo->channel, - devinfo->target, devinfo->lun); - } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) { - int tag_type; - int mask; - - tag_type = (scb->hscb->control & MSG_SIMPLE_TASK); - - if (tag_type == MSG_SIMPLE_TASK) { - printf("(%s:%c:%d:%d): refuses tagged commands. " - "Performing non-tagged I/O\n", ahd_name(ahd), - devinfo->channel, devinfo->target, devinfo->lun); - ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE); - mask = ~0x23; - } else { - printf("(%s:%c:%d:%d): refuses %s tagged commands. " - "Performing simple queue tagged I/O only\n", - ahd_name(ahd), devinfo->channel, devinfo->target, - devinfo->lun, tag_type == MSG_ORDERED_TASK - ? "ordered" : "head of queue"); - ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC); - mask = ~0x03; - } - - /* - * Resend the identify for this CCB as the target - * may believe that the selection is invalid otherwise. - */ - ahd_outb(ahd, SCB_CONTROL, - ahd_inb_scbram(ahd, SCB_CONTROL) & mask); - scb->hscb->control &= mask; - ahd_set_transaction_tag(scb, /*enabled*/FALSE, - /*type*/MSG_SIMPLE_TASK); - ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG); - ahd_assert_atn(ahd); - ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun), - SCB_GET_TAG(scb)); - - /* - * Requeue all tagged commands for this target - * currently in our posession so they can be - * converted to untagged commands. - */ - ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), - SCB_GET_CHANNEL(ahd, scb), - SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL, - ROLE_INITIATOR, CAM_REQUEUE_REQ, - SEARCH_COMPLETE); - } else if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_IDENTIFYFLAG, TRUE)) { - /* - * Most likely the device believes that we had - * previously negotiated packetized. - */ - ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE - | MSG_FLAG_IU_REQ_CHANGED; - - ahd_force_renegotiation(ahd, devinfo); - ahd->msgout_index = 0; - ahd->msgout_len = 0; - ahd_build_transfer_msg(ahd, devinfo); - ahd->msgout_index = 0; - response = 1; - } else { - /* - * Otherwise, we ignore it. - */ - printf("%s:%c:%d: Message reject for %x -- ignored\n", - ahd_name(ahd), devinfo->channel, devinfo->target, - last_msg); - } - return (response); -} - -/* - * Process an ingnore wide residue message. - */ -static void -ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - u_int scb_index; - struct scb *scb; - - scb_index = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scb_index); - /* - * XXX Actually check data direction in the sequencer? - * Perhaps add datadir to some spare bits in the hscb? - */ - if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0 - || ahd_get_transfer_dir(scb) != CAM_DIR_IN) { - /* - * Ignore the message if we haven't - * seen an appropriate data phase yet. - */ - } else { - /* - * If the residual occurred on the last - * transfer and the transfer request was - * expected to end on an odd count, do - * nothing. Otherwise, subtract a byte - * and update the residual count accordingly. - */ - uint32_t sgptr; - - sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); - if ((sgptr & SG_LIST_NULL) != 0 - && ahd_inb(ahd, DATA_COUNT_ODD) == 1) { - /* - * If the residual occurred on the last - * transfer and the transfer request was - * expected to end on an odd count, do - * nothing. - */ - } else { - uint32_t data_cnt; - uint64_t data_addr; - uint32_t sglen; - - /* Pull in the rest of the sgptr */ - sgptr |= - (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8); - sgptr &= SG_PTR_MASK; - data_cnt = - (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+2) << 16) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+1) << 8) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT)); - - data_addr = (((uint64_t)ahd_inb(ahd, SHADDR + 7)) << 56) - | (((uint64_t)ahd_inb(ahd, SHADDR + 6)) << 48) - | (((uint64_t)ahd_inb(ahd, SHADDR + 5)) << 40) - | (((uint64_t)ahd_inb(ahd, SHADDR + 4)) << 32) - | (ahd_inb(ahd, SHADDR + 3) << 24) - | (ahd_inb(ahd, SHADDR + 2) << 16) - | (ahd_inb(ahd, SHADDR + 1) << 8) - | (ahd_inb(ahd, SHADDR)); - - data_cnt += 1; - data_addr -= 1; - - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { - struct ahd_dma64_seg *sg; - - sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); - - /* - * The residual sg ptr points to the next S/G - * to load so we must go back one. - */ - sg--; - sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; - if (sg != scb->sg_list - && sglen < (data_cnt & AHD_SG_LEN_MASK)) { - - sg--; - sglen = ahd_le32toh(sg->len); - /* - * Preserve High Address and SG_LIST - * bits while setting the count to 1. - */ - data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK)); - data_addr = ahd_le64toh(sg->addr) - + (sglen & AHD_SG_LEN_MASK) - - 1; - - /* - * Increment sg so it points to the - * "next" sg. - */ - sg++; - sgptr = ahd_sg_virt_to_bus(ahd, scb, - sg); - } - } else { - struct ahd_dma_seg *sg; - - sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); - - /* - * The residual sg ptr points to the next S/G - * to load so we must go back one. - */ - sg--; - sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; - if (sg != scb->sg_list - && sglen < (data_cnt & AHD_SG_LEN_MASK)) { - - sg--; - sglen = ahd_le32toh(sg->len); - /* - * Preserve High Address and SG_LIST - * bits while setting the count to 1. - */ - data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK)); - data_addr = ahd_le32toh(sg->addr) - + (sglen & AHD_SG_LEN_MASK) - - 1; - - /* - * Increment sg so it points to the - * "next" sg. - */ - sg++; - sgptr = ahd_sg_virt_to_bus(ahd, scb, - sg); - } - } - ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 3, sgptr >> 24); - ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 2, sgptr >> 16); - ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 1, sgptr >> 8); - ahd_outb(ahd, SCB_RESIDUAL_SGPTR, sgptr); - - ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24); - ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16); - ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8); - ahd_outb(ahd, SCB_RESIDUAL_DATACNT, data_cnt); - - /* - * The FIFO's pointers will be updated if/when the - * sequencer re-enters a data phase. - */ - } - } -} - - -/* - * Reinitialize the data pointers for the active transfer - * based on its current residual. - */ -static void -ahd_reinitialize_dataptrs(struct ahd_softc *ahd) -{ - struct scb *scb; - ahd_mode_state saved_modes; - u_int scb_index; - u_int wait; - uint32_t sgptr; - uint32_t resid; - uint64_t dataptr; - - AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK, - AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK); - - scb_index = ahd_get_scbptr(ahd); - scb = ahd_lookup_scb(ahd, scb_index); - - /* - * Release and reacquire the FIFO so we - * have a clean slate. - */ - ahd_outb(ahd, DFFSXFRCTL, CLRCHN); - wait = 1000; - do { - ahd_delay(100); - } while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE)); - if (wait == 0) { - ahd_print_path(ahd, scb); - printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n"); - ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT); - } - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_outb(ahd, DFFSTAT, - ahd_inb(ahd, DFFSTAT) - | (saved_modes == 0x11 ? CURRFIFO_1 : CURRFIFO_0)); - - /* - * Determine initial values for data_addr and data_cnt - * for resuming the data phase. - */ - sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8) - | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); - sgptr &= SG_PTR_MASK; - - resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16) - | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 1) << 8) - | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT); - - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { - struct ahd_dma64_seg *sg; - - sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); - - /* The residual sg_ptr always points to the next sg */ - sg--; - - dataptr = ahd_le64toh(sg->addr) - + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) - - resid; - ahd_outb(ahd, HADDR + 7, dataptr >> 56); - ahd_outb(ahd, HADDR + 6, dataptr >> 48); - ahd_outb(ahd, HADDR + 5, dataptr >> 40); - ahd_outb(ahd, HADDR + 4, dataptr >> 32); - } else { - struct ahd_dma_seg *sg; - - sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); - - /* The residual sg_ptr always points to the next sg */ - sg--; - - dataptr = ahd_le32toh(sg->addr) - + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) - - resid; - ahd_outb(ahd, HADDR + 4, - (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24); - } - ahd_outb(ahd, HADDR + 3, dataptr >> 24); - ahd_outb(ahd, HADDR + 2, dataptr >> 16); - ahd_outb(ahd, HADDR + 1, dataptr >> 8); - ahd_outb(ahd, HADDR, dataptr); - ahd_outb(ahd, HCNT + 2, resid >> 16); - ahd_outb(ahd, HCNT + 1, resid >> 8); - ahd_outb(ahd, HCNT, resid); -} - -/* - * Handle the effects of issuing a bus device reset message. - */ -static void -ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - u_int lun, cam_status status, char *message, - int verbose_level) -{ -#ifdef AHD_TARGET_MODE - struct ahd_tmode_tstate* tstate; -#endif - int found; - - found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel, - lun, SCB_LIST_NULL, devinfo->role, - status); - -#ifdef AHD_TARGET_MODE - /* - * Send an immediate notify ccb to all target mord peripheral - * drivers affected by this action. - */ - tstate = ahd->enabled_targets[devinfo->our_scsiid]; - if (tstate != NULL) { - u_int cur_lun; - u_int max_lun; - - if (lun != CAM_LUN_WILDCARD) { - cur_lun = 0; - max_lun = AHD_NUM_LUNS - 1; - } else { - cur_lun = lun; - max_lun = lun; - } - for (cur_lun <= max_lun; cur_lun++) { - struct ahd_tmode_lstate* lstate; - - lstate = tstate->enabled_luns[cur_lun]; - if (lstate == NULL) - continue; - - ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid, - MSG_BUS_DEV_RESET, /*arg*/0); - ahd_send_lstate_events(ahd, lstate); - } - } -#endif - - /* - * Go back to async/narrow transfers and renegotiate. - */ - ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_CUR, /*paused*/TRUE); - ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0, - /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE); - - ahd_send_async(ahd, devinfo->channel, devinfo->target, - lun, AC_SENT_BDR, NULL); - - if (message != NULL - && (verbose_level <= bootverbose)) - printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), - message, devinfo->channel, devinfo->target, found); -} - -#ifdef AHD_TARGET_MODE -static void -ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - struct scb *scb) -{ - - /* - * To facilitate adding multiple messages together, - * each routine should increment the index and len - * variables instead of setting them explicitly. - */ - ahd->msgout_index = 0; - ahd->msgout_len = 0; - - if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0) - ahd_build_transfer_msg(ahd, devinfo); - else - panic("ahd_intr: AWAITING target message with no message"); - - ahd->msgout_index = 0; - ahd->msg_type = MSG_TYPE_TARGET_MSGIN; -} -#endif -/**************************** Initialization **********************************/ -static u_int -ahd_sglist_size(struct ahd_softc *ahd) -{ - bus_size_t list_size; - - list_size = sizeof(struct ahd_dma_seg) * AHD_NSEG; - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) - list_size = sizeof(struct ahd_dma64_seg) * AHD_NSEG; - return (list_size); -} - -/* - * Calculate the optimum S/G List allocation size. S/G elements used - * for a given transaction must be physically contiguous. Assume the - * OS will allocate full pages to us, so it doesn't make sense to request - * less than a page. - */ -static u_int -ahd_sglist_allocsize(struct ahd_softc *ahd) -{ - bus_size_t sg_list_increment; - bus_size_t sg_list_size; - bus_size_t max_list_size; - bus_size_t best_list_size; - - /* Start out with the minimum required for AHD_NSEG. */ - sg_list_increment = ahd_sglist_size(ahd); - sg_list_size = sg_list_increment; - - /* Get us as close as possible to a page in size. */ - while ((sg_list_size + sg_list_increment) <= PAGE_SIZE) - sg_list_size += sg_list_increment; - - /* - * Try to reduce the amount of wastage by allocating - * multiple pages. - */ - best_list_size = sg_list_size; - max_list_size = roundup(sg_list_increment, PAGE_SIZE); - if (max_list_size < 4 * PAGE_SIZE) - max_list_size = 4 * PAGE_SIZE; - if (max_list_size > (AHD_SCB_MAX_ALLOC * sg_list_increment)) - max_list_size = (AHD_SCB_MAX_ALLOC * sg_list_increment); - while ((sg_list_size + sg_list_increment) <= max_list_size - && (sg_list_size % PAGE_SIZE) != 0) { - bus_size_t new_mod; - bus_size_t best_mod; - - sg_list_size += sg_list_increment; - new_mod = sg_list_size % PAGE_SIZE; - best_mod = best_list_size % PAGE_SIZE; - if (new_mod > best_mod || new_mod == 0) { - best_list_size = sg_list_size; - } - } - return (best_list_size); -} - -/* - * Allocate a controller structure for a new device - * and perform initial initializion. - */ -struct ahd_softc * -ahd_alloc(void *platform_arg, char *name) -{ - struct ahd_softc *ahd; - -#ifndef __FreeBSD__ - ahd = malloc(sizeof(*ahd), M_DEVBUF, M_NOWAIT); - if (!ahd) { - printf("aic7xxx: cannot malloc softc!\n"); - free(name, M_DEVBUF); - return NULL; - } -#else - ahd = device_get_softc((device_t)platform_arg); -#endif - memset(ahd, 0, sizeof(*ahd)); - ahd->seep_config = malloc(sizeof(*ahd->seep_config), - M_DEVBUF, M_NOWAIT); - if (ahd->seep_config == NULL) { -#ifndef __FreeBSD__ - free(ahd, M_DEVBUF); -#endif - free(name, M_DEVBUF); - return (NULL); - } - LIST_INIT(&ahd->pending_scbs); - /* We don't know our unit number until the OSM sets it */ - ahd->name = name; - ahd->unit = -1; - ahd->description = NULL; - ahd->bus_description = NULL; - ahd->channel = 'A'; - ahd->chip = AHD_NONE; - ahd->features = AHD_FENONE; - ahd->bugs = AHD_BUGNONE; - ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A - | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A; - ahd_timer_init(&ahd->reset_timer); - ahd_timer_init(&ahd->stat_timer); - ahd->int_coalessing_timer = AHD_INT_COALESSING_TIMER_DEFAULT; - ahd->int_coalessing_maxcmds = AHD_INT_COALESSING_MAXCMDS_DEFAULT; - ahd->int_coalessing_mincmds = AHD_INT_COALESSING_MINCMDS_DEFAULT; - ahd->int_coalessing_threshold = AHD_INT_COALESSING_THRESHOLD_DEFAULT; - ahd->int_coalessing_stop_threshold = - AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT; - - if (ahd_platform_alloc(ahd, platform_arg) != 0) { - ahd_free(ahd); - ahd = NULL; - } -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MEMORY) != 0) { - printf("%s: scb size = 0x%x, hscb size = 0x%x\n", - ahd_name(ahd), (u_int)sizeof(struct scb), - (u_int)sizeof(struct hardware_scb)); - } -#endif - return (ahd); -} - -int -ahd_softc_init(struct ahd_softc *ahd) -{ - - ahd->unpause = 0; - ahd->pause = PAUSE; - return (0); -} - -void -ahd_softc_insert(struct ahd_softc *ahd) -{ - struct ahd_softc *list_ahd; - -#if AHD_PCI_CONFIG > 0 - /* - * Second Function PCI devices need to inherit some - * settings from function 0. - */ - if ((ahd->features & AHD_MULTI_FUNC) != 0) { - TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { - ahd_dev_softc_t list_pci; - ahd_dev_softc_t pci; - - list_pci = list_ahd->dev_softc; - pci = ahd->dev_softc; - if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci) - && ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) { - struct ahd_softc *master; - struct ahd_softc *slave; - - if (ahd_get_pci_function(list_pci) == 0) { - master = list_ahd; - slave = ahd; - } else { - master = ahd; - slave = list_ahd; - } - slave->flags &= ~AHD_BIOS_ENABLED; - slave->flags |= - master->flags & AHD_BIOS_ENABLED; - slave->flags &= ~AHD_PRIMARY_CHANNEL; - slave->flags |= - master->flags & AHD_PRIMARY_CHANNEL; - break; - } - } - } -#endif - - /* - * Insertion sort into our list of softcs. - */ - list_ahd = TAILQ_FIRST(&ahd_tailq); - while (list_ahd != NULL - && ahd_softc_comp(list_ahd, ahd) <= 0) - list_ahd = TAILQ_NEXT(list_ahd, links); - if (list_ahd != NULL) - TAILQ_INSERT_BEFORE(list_ahd, ahd, links); - else - TAILQ_INSERT_TAIL(&ahd_tailq, ahd, links); - ahd->init_level++; -} - -/* - * Verify that the passed in softc pointer is for a - * controller that is still configured. - */ -struct ahd_softc * -ahd_find_softc(struct ahd_softc *ahd) -{ - struct ahd_softc *list_ahd; - - TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { - if (list_ahd == ahd) - return (ahd); - } - return (NULL); -} - -void -ahd_set_unit(struct ahd_softc *ahd, int unit) -{ - ahd->unit = unit; -} - -void -ahd_set_name(struct ahd_softc *ahd, char *name) -{ - if (ahd->name != NULL) - free(ahd->name, M_DEVBUF); - ahd->name = name; -} - -void -ahd_free(struct ahd_softc *ahd) -{ - int i; - - ahd_fini_scbdata(ahd); - switch (ahd->init_level) { - default: - case 5: - ahd_shutdown(ahd); - TAILQ_REMOVE(&ahd_tailq, ahd, links); - /* FALLTHROUGH */ - case 4: - ahd_dmamap_unload(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap); - /* FALLTHROUGH */ - case 3: - ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, - ahd->shared_data_dmamap); - ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap); - /* FALLTHROUGH */ - case 2: - ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); - case 1: -#ifndef __linux__ - ahd_dma_tag_destroy(ahd, ahd->buffer_dmat); -#endif - break; - case 0: - break; - } - -#ifndef __linux__ - ahd_dma_tag_destroy(ahd, ahd->parent_dmat); -#endif - ahd_platform_free(ahd); - for (i = 0; i < AHD_NUM_TARGETS; i++) { - struct ahd_tmode_tstate *tstate; - - tstate = ahd->enabled_targets[i]; - if (tstate != NULL) { -#if AHD_TARGET_MODE - int j; - - for (j = 0; j < AHD_NUM_LUNS; j++) { - struct ahd_tmode_lstate *lstate; - - lstate = tstate->enabled_luns[j]; - if (lstate != NULL) { - xpt_free_path(lstate->path); - free(lstate, M_DEVBUF); - } - } -#endif - free(tstate, M_DEVBUF); - } - } -#if AHD_TARGET_MODE - if (ahd->black_hole != NULL) { - xpt_free_path(ahd->black_hole->path); - free(ahd->black_hole, M_DEVBUF); - } -#endif - if (ahd->name != NULL) - free(ahd->name, M_DEVBUF); - if (ahd->seep_config != NULL) - free(ahd->seep_config, M_DEVBUF); - if (ahd->saved_stack != NULL) - free(ahd->saved_stack, M_DEVBUF); -#ifndef __FreeBSD__ - free(ahd, M_DEVBUF); -#endif - return; -} - -void -ahd_shutdown(void *arg) -{ - struct ahd_softc *ahd; - - ahd = (struct ahd_softc *)arg; - - /* - * Stop periodic timer callbacks. - */ - ahd_timer_stop(&ahd->reset_timer); - ahd_timer_stop(&ahd->stat_timer); - - /* This will reset most registers to 0, but not all */ - ahd_reset(ahd); -} - -/* - * Reset the controller and record some information about it - * that is only available just after a reset. - */ -int -ahd_reset(struct ahd_softc *ahd) -{ - u_int sxfrctl1; - int wait; - uint32_t cmd; - - /* - * Preserve the value of the SXFRCTL1 register for all channels. - * It contains settings that affect termination and we don't want - * to disturb the integrity of the bus. - */ - ahd_pause(ahd); - sxfrctl1 = ahd_inb(ahd, SXFRCTL1); - - cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2); - if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) { - uint32_t mod_cmd; - - /* - * A4 Razor #632 - * During the assertion of CHIPRST, the chip - * does not disable its parity logic prior to - * the start of the reset. This may cause a - * parity error to be detected and thus a - * spurious SERR or PERR assertion. Disble - * PERR and SERR responses during the CHIPRST. - */ - mod_cmd = cmd & ~(PCIM_CMD_PERRESPEN|PCIM_CMD_SERRESPEN); - ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, - mod_cmd, /*bytes*/2); - } - ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause); - - /* - * Ensure that the reset has finished. We delay 1000us - * prior to reading the register to make sure the chip - * has sufficiently completed its reset to handle register - * accesses. - */ - wait = 1000; - do { - ahd_delay(1000); - } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK)); - - if (wait == 0) { - printf("%s: WARNING - Failed chip reset! " - "Trying to initialize anyway.\n", ahd_name(ahd)); - } - ahd_outb(ahd, HCNTRL, ahd->pause); - - if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) { - /* - * Clear any latched PCI error status and restore - * previous SERR and PERR response enables. - */ - ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, - 0xFF, /*bytes*/1); - ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, - cmd, /*bytes*/2); - } - /* After a reset, we know the state of the mode register. */ - ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - - /* Determine chip configuration */ - ahd->features &= ~AHD_WIDE; - if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0) - ahd->features |= AHD_WIDE; - - /* - * Restore SXFRCTL1. - * - * We must always initialize STPWEN to 1 before we - * restore the saved values. STPWEN is initialized - * to a tri-state condition which can only be cleared - * by turning it on. - */ - ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN); - ahd_outb(ahd, SXFRCTL1, sxfrctl1); - - /* - * If a recovery action has forced a chip reset, - * re-initialize the chip to our likeing. - */ - if (ahd->init_level > 0) - ahd_chip_init(ahd); - - return (0); -} - -/* - * Determine the number of SCBs available on the controller - */ -int -ahd_probe_scbs(struct ahd_softc *ahd) { - int i; - - AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), - ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); - for (i = 0; i < AHD_SCB_MAX; i++) { - int j; - - ahd_set_scbptr(ahd, i); - ahd_outw(ahd, SCB_BASE, i); - for (j = 2; j < 64; j++) - ahd_outb(ahd, SCB_BASE+j, 0); - /* Start out life as unallocated (needing an abort) */ - ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE); - if (ahd_inw_scbram(ahd, SCB_BASE) != i) - break; - ahd_set_scbptr(ahd, 0); - if (ahd_inw_scbram(ahd, SCB_BASE) != 0) - break; - } - return (i); -} - -static void -ahd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - bus_addr_t *baddr; - - baddr = (bus_addr_t *)arg; - *baddr = segs->ds_addr; -} - -static void -ahd_initialize_hscbs(struct ahd_softc *ahd) -{ - int i; - - for (i = 0; i < ahd->scb_data.maxhscbs; i++) { - ahd_set_scbptr(ahd, i); - - /* Clear the control byte. */ - ahd_outb(ahd, SCB_CONTROL, 0); - - /* Set the next pointer */ - ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL); - } -} - -static int -ahd_init_scbdata(struct ahd_softc *ahd) -{ - struct scb_data *scb_data; - int i; - - scb_data = &ahd->scb_data; - TAILQ_INIT(&scb_data->free_scbs); - for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++) - LIST_INIT(&scb_data->free_scb_lists[i]); - LIST_INIT(&scb_data->any_dev_free_scb_list); - SLIST_INIT(&scb_data->hscb_maps); - SLIST_INIT(&scb_data->sg_maps); - SLIST_INIT(&scb_data->sense_maps); - - /* Determine the number of hardware SCBs and initialize them */ - scb_data->maxhscbs = ahd_probe_scbs(ahd); - if (scb_data->maxhscbs == 0) { - printf("%s: No SCB space found\n", ahd_name(ahd)); - return (ENXIO); - } - - ahd_initialize_hscbs(ahd); - - /* - * Create our DMA tags. These tags define the kinds of device - * accessible memory allocations and memory mappings we will - * need to perform during normal operation. - * - * Unless we need to further restrict the allocation, we rely - * on the restrictions of the parent dmat, hence the common - * use of MAXADDR and MAXSIZE. - */ - - /* DMA tag for our hardware scb structures */ - if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, - /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - PAGE_SIZE, /*nsegments*/1, - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, &scb_data->hscb_dmat) != 0) { - goto error_exit; - } - - scb_data->init_level++; - - /* DMA tag for our S/G structures. */ - if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, - /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - ahd_sglist_allocsize(ahd), /*nsegments*/1, - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, &scb_data->sg_dmat) != 0) { - goto error_exit; - } -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MEMORY) != 0) - printf("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd), - ahd_sglist_allocsize(ahd)); -#endif - - scb_data->init_level++; - - /* DMA tag for our sense buffers. We allocate in page sized chunks */ - if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, - /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - PAGE_SIZE, /*nsegments*/1, - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, &scb_data->sense_dmat) != 0) { - goto error_exit; - } - - scb_data->init_level++; - - /* Perform initial CCB allocation */ - ahd_alloc_scbs(ahd); - - if (scb_data->numscbs == 0) { - printf("%s: ahd_init_scbdata - " - "Unable to allocate initial scbs\n", - ahd_name(ahd)); - goto error_exit; - } - - /* - * Note that we were successfull - */ - return (0); - -error_exit: - - return (ENOMEM); -} - -static struct scb * -ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag) -{ - struct scb *scb; - - /* - * Look on the pending list. - */ - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { - if (SCB_GET_TAG(scb) == tag) - return (scb); - } - - /* - * Then on all of the collision free lists. - */ - TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { - struct scb *list_scb; - - list_scb = scb; - do { - if (SCB_GET_TAG(list_scb) == tag) - return (list_scb); - list_scb = LIST_NEXT(list_scb, collision_links); - } while (list_scb); - } - - /* - * And finally on the generic free list. - */ - LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { - if (SCB_GET_TAG(scb) == tag) - return (scb); - } - - return (NULL); -} - -static void -ahd_fini_scbdata(struct ahd_softc *ahd) -{ - struct scb_data *scb_data; - - scb_data = &ahd->scb_data; - if (scb_data == NULL) - return; - - switch (scb_data->init_level) { - default: - case 7: - { - struct map_node *sns_map; - - while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) { - SLIST_REMOVE_HEAD(&scb_data->sense_maps, links); - ahd_dmamap_unload(ahd, scb_data->sense_dmat, - sns_map->dmamap); - ahd_dmamem_free(ahd, scb_data->sense_dmat, - sns_map->vaddr, sns_map->dmamap); - free(sns_map, M_DEVBUF); - } - ahd_dma_tag_destroy(ahd, scb_data->sense_dmat); - /* FALLTHROUGH */ - } - case 6: - { - struct map_node *sg_map; - - while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) { - SLIST_REMOVE_HEAD(&scb_data->sg_maps, links); - ahd_dmamap_unload(ahd, scb_data->sg_dmat, - sg_map->dmamap); - ahd_dmamem_free(ahd, scb_data->sg_dmat, - sg_map->vaddr, sg_map->dmamap); - free(sg_map, M_DEVBUF); - } - ahd_dma_tag_destroy(ahd, scb_data->sg_dmat); - /* FALLTHROUGH */ - } - case 5: - { - struct map_node *hscb_map; - - while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) { - SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links); - ahd_dmamap_unload(ahd, scb_data->hscb_dmat, - hscb_map->dmamap); - ahd_dmamem_free(ahd, scb_data->hscb_dmat, - hscb_map->vaddr, hscb_map->dmamap); - free(hscb_map, M_DEVBUF); - } - ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat); - /* FALLTHROUGH */ - } - case 4: - case 3: - case 2: - case 1: - case 0: - break; - } -} - -/* - * DSP filter Bypass must be enabled until the first selection - * after a change in bus mode (Razor #491 and #493). - */ -static void -ahd_setup_iocell_workaround(struct ahd_softc *ahd) -{ - ahd_mode_state saved_modes; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL) - | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS); - ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI)); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("%s: Setting up iocell workaround\n", ahd_name(ahd)); -#endif - ahd_restore_modes(ahd, saved_modes); -} - -static void -ahd_iocell_first_selection(struct ahd_softc *ahd) -{ - ahd_mode_state saved_modes; - u_int sblkctl; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - sblkctl = ahd_inb(ahd, SBLKCTL); - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("%s: iocell first selection\n", ahd_name(ahd)); -#endif - if ((sblkctl & ENAB40) != 0) { - ahd_outb(ahd, DSPDATACTL, - ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("%s: BYPASS now disabled\n", ahd_name(ahd)); -#endif - } - ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI)); - ahd_outb(ahd, CLRINT, CLRSCSIINT); - ahd_restore_modes(ahd, saved_modes); -} - -/*************************** SCB Management ***********************************/ -static void -ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx) -{ - struct scb_list *free_list; - struct scb_tailq *free_tailq; - struct scb *first_scb; - - scb->flags |= SCB_ON_COL_LIST; - AHD_SET_SCB_COL_IDX(scb, col_idx); - free_list = &ahd->scb_data.free_scb_lists[col_idx]; - free_tailq = &ahd->scb_data.free_scbs; - first_scb = LIST_FIRST(free_list); - if (first_scb != NULL) { - LIST_INSERT_AFTER(first_scb, scb, collision_links); - } else { - LIST_INSERT_HEAD(free_list, scb, collision_links); - TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe); - } -} - -static void -ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb) -{ - struct scb_list *free_list; - struct scb_tailq *free_tailq; - struct scb *first_scb; - u_int col_idx; - - scb->flags &= ~SCB_ON_COL_LIST; - col_idx = AHD_GET_SCB_COL_IDX(ahd, scb); - free_list = &ahd->scb_data.free_scb_lists[col_idx]; - free_tailq = &ahd->scb_data.free_scbs; - first_scb = LIST_FIRST(free_list); - if (first_scb == scb) { - struct scb *next_scb; - - /* - * Maintain order in the collision free - * lists for fairness if this device has - * other colliding tags active. - */ - next_scb = LIST_NEXT(scb, collision_links); - if (next_scb != NULL) { - TAILQ_INSERT_AFTER(free_tailq, scb, - next_scb, links.tqe); - } - TAILQ_REMOVE(free_tailq, scb, links.tqe); - } - LIST_REMOVE(scb, collision_links); -} - -/* - * Get a free scb. If there are none, see if we can allocate a new SCB. - */ -struct scb * -ahd_get_scb(struct ahd_softc *ahd, u_int col_idx) -{ - struct scb *scb; - int tries; - - tries = 0; -look_again: - TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { - if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) { - ahd_rem_col_list(ahd, scb); - goto found; - } - } - if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL) { - - if (tries++ != 0) - return (NULL); - ahd_alloc_scbs(ahd); - goto look_again; - } - LIST_REMOVE(scb, links.le); - if (col_idx != AHD_NEVER_COL_IDX - && (scb->col_scb != NULL) - && (scb->col_scb->flags & SCB_ACTIVE) == 0) { - LIST_REMOVE(scb->col_scb, links.le); - ahd_add_col_list(ahd, scb->col_scb, col_idx); - } -found: - scb->flags |= SCB_ACTIVE; - return (scb); -} - -/* - * Return an SCB resource to the free list. - */ -void -ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) -{ - - /* Clean up for the next user */ - scb->flags = SCB_FLAG_NONE; - scb->hscb->control = 0; - ahd->scb_data.scbindex[scb->hscb->tag] = NULL; - - if (scb->col_scb == NULL) { - - /* - * No collision possible. Just free normally. - */ - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb, links.le); - } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) { - - /* - * The SCB we might have collided with is on - * a free collision list. Put both SCBs on - * the generic list. - */ - ahd_rem_col_list(ahd, scb->col_scb); - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb, links.le); - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb->col_scb, links.le); - } else if ((scb->col_scb->flags - & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE - && (scb->col_scb->hscb->control & TAG_ENB) != 0) { - - /* - * The SCB we might collide with on the next allocation - * is still active in a non-packetized, tagged, context. - * Put us on the SCB collision list. - */ - ahd_add_col_list(ahd, scb, - AHD_GET_SCB_COL_IDX(ahd, scb->col_scb)); - } else { - /* - * The SCB we might collide with on the next allocation - * is either active in a packetized context, or free. - * Since we can't collide, put this SCB on the generic - * free list. - */ - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb, links.le); - } - - ahd_platform_scb_free(ahd, scb); -} - -void -ahd_alloc_scbs(struct ahd_softc *ahd) -{ - struct scb_data *scb_data; - struct scb *next_scb; - struct hardware_scb *hscb; - struct map_node *hscb_map; - struct map_node *sg_map; - struct map_node *sense_map; - uint8_t *segs; - uint8_t *sense_data; - bus_addr_t hscb_busaddr; - bus_addr_t sg_busaddr; - bus_addr_t sense_busaddr; - int newcount; - int i; - - scb_data = &ahd->scb_data; - if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC) - /* Can't allocate any more */ - return; - - if (scb_data->scbs_left != 0) { - int offset; - - offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left; - hscb_map = SLIST_FIRST(&scb_data->hscb_maps); - hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset]; - hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb)); - } else { - hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_NOWAIT); - - if (hscb_map == NULL) - return; - - /* Allocate the next batch of hardware SCBs */ - if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat, - (void **)&hscb_map->vaddr, - BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) { - free(hscb_map, M_DEVBUF); - return; - } - - SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links); - - ahd_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap, - hscb_map->vaddr, PAGE_SIZE, ahd_dmamap_cb, - &hscb_map->physaddr, /*flags*/0); - - hscb = (struct hardware_scb *)hscb_map->vaddr; - hscb_busaddr = hscb_map->physaddr; - scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb); - } - - if (scb_data->sgs_left != 0) { - int offset; - - offset = ahd_sglist_allocsize(ahd) - - (scb_data->sgs_left * ahd_sglist_size(ahd)); - sg_map = SLIST_FIRST(&scb_data->sg_maps); - segs = sg_map->vaddr + offset; - sg_busaddr = sg_map->physaddr + offset; - } else { - sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); - - if (sg_map == NULL) - return; - - /* Allocate the next batch of S/G lists */ - if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat, - (void **)&sg_map->vaddr, - BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) { - free(sg_map, M_DEVBUF); - return; - } - - SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links); - - ahd_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap, - sg_map->vaddr, ahd_sglist_allocsize(ahd), - ahd_dmamap_cb, &sg_map->physaddr, /*flags*/0); - - segs = sg_map->vaddr; - sg_busaddr = sg_map->physaddr; - scb_data->sgs_left = - ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd); -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_MEMORY) - printf("Mapped SG data\n"); -#endif - } - - if (scb_data->sense_left != 0) { - int offset; - - offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left); - sense_map = SLIST_FIRST(&scb_data->sense_maps); - sense_data = sense_map->vaddr + offset; - sense_busaddr = sense_map->physaddr + offset; - } else { - sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_NOWAIT); - - if (sense_map == NULL) - return; - - /* Allocate the next batch of sense buffers */ - if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat, - (void **)&sense_map->vaddr, - BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) { - free(sense_map, M_DEVBUF); - return; - } - - SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links); - - ahd_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap, - sense_map->vaddr, PAGE_SIZE, ahd_dmamap_cb, - &sense_map->physaddr, /*flags*/0); - - sense_data = sense_map->vaddr; - sense_busaddr = sense_map->physaddr; - scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE; -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_MEMORY) - printf("Mapped sense data\n"); -#endif - } - - newcount = MIN(scb_data->sense_left, scb_data->scbs_left); - newcount = MIN(newcount, scb_data->sgs_left); - newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); - scb_data->sense_left -= newcount; - scb_data->scbs_left -= newcount; - scb_data->sgs_left -= newcount; - for (i = 0; i < newcount; i++) { - u_int col_tag; - - struct scb_platform_data *pdata; -#ifndef __linux__ - int error; -#endif - next_scb = (struct scb *)malloc(sizeof(*next_scb), - M_DEVBUF, M_NOWAIT); - if (next_scb == NULL) - break; - - pdata = (struct scb_platform_data *)malloc(sizeof(*pdata), - M_DEVBUF, M_NOWAIT); - if (pdata == NULL) { - free(next_scb, M_DEVBUF); - break; - } - next_scb->platform_data = pdata; - next_scb->hscb_map = hscb_map; - next_scb->sg_map = sg_map; - next_scb->sense_map = sense_map; - next_scb->sg_list = segs; - next_scb->sense_data = sense_data; - next_scb->sense_busaddr = sense_busaddr; - next_scb->hscb = hscb; - hscb->hscb_busaddr = ahd_htole32(hscb_busaddr); - - /* - * The sequencer always starts with the second entry. - * The first entry is embedded in the scb. - */ - next_scb->sg_list_busaddr = sg_busaddr; - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) - next_scb->sg_list_busaddr - += sizeof(struct ahd_dma64_seg); - else - next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg); - next_scb->ahd_softc = ahd; - next_scb->flags = SCB_FLAG_NONE; -#ifndef __linux__ - error = ahd_dmamap_create(ahd, ahd->buffer_dmat, /*flags*/0, - &next_scb->dmamap); - if (error != 0) { - free(next_scb, M_DEVBUF); - free(pdata, M_DEVBUF); - break; - } -#endif - next_scb->hscb->tag = ahd_htole16(scb_data->numscbs); - col_tag = scb_data->numscbs ^ 0x100; - next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag); - if (next_scb->col_scb != NULL) - next_scb->col_scb->col_scb = next_scb; - ahd_free_scb(ahd, next_scb); - hscb++; - hscb_busaddr += sizeof(*hscb); - segs += ahd_sglist_size(ahd); - sg_busaddr += ahd_sglist_size(ahd); - sense_data += AHD_SENSE_BUFSIZE; - sense_busaddr += AHD_SENSE_BUFSIZE; - scb_data->numscbs++; - } -} - -void -ahd_controller_info(struct ahd_softc *ahd, char *buf) -{ - const char *speed; - const char *type; - int len; - - len = sprintf(buf, "%s: ", ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]); - buf += len; - - speed = "Ultra320 "; - if ((ahd->features & AHD_WIDE) != 0) { - type = "Wide "; - } else { - type = "Single "; - } - len = sprintf(buf, "%s%sChannel %c, SCSI Id=%d, ", - speed, type, ahd->channel, ahd->our_id); - buf += len; - - sprintf(buf, "%s, %d SCBs", ahd->bus_description, - ahd->scb_data.maxhscbs); -} - -static const char *channel_strings[] = { - "Primary Low", - "Primary High", - "Secondary Low", - "Secondary High" -}; - -static const char *termstat_strings[] = { - "Terminated Correctly", - "Over Terminated", - "Under Terminated", - "Not Configured" -}; - -/* - * Start the board, ready for normal operation - */ -int -ahd_init(struct ahd_softc *ahd) -{ - uint8_t *base_vaddr; - uint8_t *next_vaddr; - bus_addr_t next_baddr; - size_t driver_data_size; - int i; - int error; - u_int warn_user; - uint8_t current_sensing; - uint8_t fstat; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - - ahd->stack_size = ahd_probe_stack_size(ahd); - ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t), - M_DEVBUF, M_NOWAIT); - if (ahd->saved_stack == NULL) - return (ENOMEM); - - /* - * Verify that the compiler hasn't over-agressively - * padded important structures. - */ - if (sizeof(struct hardware_scb) != 64) - panic("Hardware SCB size is incorrect"); - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0) - ahd->flags |= AHD_SEQUENCER_DEBUG; -#endif - - /* - * Default to allowing initiator operations. - */ - ahd->flags |= AHD_INITIATORROLE; - - /* - * Only allow target mode features if this unit has them enabled. - */ - if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0) - ahd->features &= ~AHD_TARGETMODE; - -#ifndef __linux__ - /* DMA tag for mapping buffers into device visible space. */ - if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, - /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, - /*lowaddr*/BUS_SPACE_MAXADDR, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/(AHD_NSEG - 1) * PAGE_SIZE, - /*nsegments*/AHD_NSEG, - /*maxsegsz*/AHD_MAXTRANSFER_SIZE, - /*flags*/BUS_DMA_ALLOCNOW, - &ahd->buffer_dmat) != 0) { - return (ENOMEM); - } -#endif - - ahd->init_level++; - - /* - * DMA tag for our command fifos and other data in system memory - * the card's sequencer must be able to access. For initiator - * roles, we need to allocate space for the qoutfifo. When providing - * for the target mode role, we must additionally provide space for - * the incoming target command fifo. - */ - driver_data_size = AHD_SCB_MAX * sizeof(uint16_t) - + sizeof(struct hardware_scb); - if ((ahd->features & AHD_TARGETMODE) != 0) - driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd); - if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) - driver_data_size += PKT_OVERRUN_BUFSIZE; - if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, - /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - driver_data_size, - /*nsegments*/1, - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, &ahd->shared_data_dmat) != 0) { - return (ENOMEM); - } - - ahd->init_level++; - - /* Allocation of driver data */ - if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, - (void **)&base_vaddr, - BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) { - return (ENOMEM); - } - - ahd->init_level++; - - /* And permanently map it in */ - ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, - base_vaddr, driver_data_size, ahd_dmamap_cb, - &ahd->shared_data_busaddr, /*flags*/0); - ahd->qoutfifo = (uint16_t *)base_vaddr; - next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; - next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t); - if ((ahd->features & AHD_TARGETMODE) != 0) { - ahd->targetcmds = (struct target_cmd *)next_vaddr; - next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); - next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); - } - - if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { - ahd->overrun_buf = next_vaddr; - next_vaddr += PKT_OVERRUN_BUFSIZE; - next_baddr += PKT_OVERRUN_BUFSIZE; - } - - /* - * We need one SCB to serve as the "next SCB". Since the - * tag identifier in this SCB will never be used, there is - * no point in using a valid HSCB tag from an SCB pulled from - * the standard free pool. So, we allocate this "sentinel" - * specially from the DMA safe memory chunk used for the QOUTFIFO. - */ - ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; - ahd->next_queued_hscb->hscb_busaddr = next_baddr; - - ahd->init_level++; - - /* Allocate SCB data now that buffer_dmat is initialized */ - if (ahd_init_scbdata(ahd) != 0) - return (ENOMEM); - - if ((ahd->flags & AHD_INITIATORROLE) == 0) - ahd->flags &= ~AHD_RESET_BUS_A; - - /* - * Before committing these settings to the chip, give - * the OSM one last chance to modify our configuration. - */ - ahd_platform_init(ahd); - - /* Bring up the chip. */ - ahd_chip_init(ahd); - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - - if ((ahd->flags & AHD_CURRENT_SENSING) == 0) - goto init_done; - - /* - * Verify termination based on current draw and - * warn user if the bus is over/under terminated. - */ - error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, - CURSENSE_ENB); - if (error != 0) { - printf("%s: current sensing timeout 1\n", ahd_name(ahd)); - goto init_done; - } - for (i = 20, fstat = FLX_FSTAT_BUSY; - (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) { - error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat); - if (error != 0) { - printf("%s: current sensing timeout 2\n", - ahd_name(ahd)); - goto init_done; - } - } - if (i == 0) { - printf("%s: Timedout during current-sensing test\n", - ahd_name(ahd)); - goto init_done; - } - - /* Latch Current Sensing status. */ - error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, ¤t_sensing); - if (error != 0) { - printf("%s: current sensing timeout 3\n", ahd_name(ahd)); - goto init_done; - } - - /* Diable current sensing. */ - ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0); - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) { - printf("%s: current_sensing == 0x%x\n", - ahd_name(ahd), current_sensing); - } -#endif - warn_user = 0; - for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) { - u_int term_stat; - - term_stat = (current_sensing & FLX_CSTAT_MASK); - switch (term_stat) { - case FLX_CSTAT_OVER: - case FLX_CSTAT_UNDER: - warn_user++; - case FLX_CSTAT_INVALID: - case FLX_CSTAT_OKAY: - if (warn_user == 0 && bootverbose == 0) - break; - printf("%s: %s Channel %s\n", ahd_name(ahd), - channel_strings[i], termstat_strings[term_stat]); - break; - } - } - if (warn_user) { - printf("%s: WARNING. Termination is not configured correctly.\n" - "%s: WARNING. SCSI bus operations may FAIL.\n", - ahd_name(ahd), ahd_name(ahd)); - } -init_done: - ahd_restart(ahd); - ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, - ahd_stat_timer, ahd); - return (0); -} - -/* - * (Re)initialize chip state after a chip reset. - */ -static void -ahd_chip_init(struct ahd_softc *ahd) -{ - uint32_t busaddr; - u_int sxfrctl1; - u_int scsiseq_template; - u_int wait; - u_int i; - u_int target; - - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - /* - * Take the LED out of diagnostic mode - */ - ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON)); - - /* - * Return HS_MAILBOX to its default value. - */ - ahd->hs_mailbox = 0; - ahd_outb(ahd, HS_MAILBOX, 0); - - /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1. */ - ahd_outb(ahd, IOWNID, ahd->our_id); - ahd_outb(ahd, TOWNID, ahd->our_id); - sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0; - sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0; - if ((ahd->bugs & AHD_LONG_SETIMO_BUG) - && (ahd->seltime != STIMESEL_MIN)) { - /* - * The selection timer duration is twice as long - * as it should be. Halve it by adding "1" to - * the user specified setting. - */ - sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ; - } else { - sxfrctl1 |= ahd->seltime; - } - - ahd_outb(ahd, SXFRCTL0, DFON); - ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN); - ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR); - - /* - * Now that termination is set, wait for up - * to 500ms for our transceivers to settle. If - * the adapter does not have a cable attached, - * the tranceivers may never settle, so don't - * complain if we fail here. - */ - for (wait = 10000; - (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait; - wait--) - ahd_delay(100); - - /* Clear any false bus resets due to the transceivers settling */ - ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); - ahd_outb(ahd, CLRINT, CLRSCSIINT); - - /* Initialize mode specific S/G state. */ - for (i = 0; i < 2; i++) { - ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); - ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); - ahd_outw(ahd, LONGJMP_SCB, SCB_LIST_NULL); - ahd_outb(ahd, SG_STATE, 0); - ahd_outb(ahd, CLRSEQINTSRC, 0xFF); - ahd_outb(ahd, SEQIMODE, - ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT - |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD); - } - - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN); - ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75); - ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN); - ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR); - if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { - ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE); - } else { - ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE); - } - ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN); - if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX) - /* - * Do not issue a target abort when a split completion - * error occurs. Let our PCIX interrupt handler deal - * with it instead. H2A4 Razor #625 - */ - ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS); - - if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0) - ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER); - - /* - * Tweak IOCELL settings. - */ - if ((ahd->flags & AHD_HP_BOARD) != 0) { - for (i = 0; i < NUMDSPS; i++) { - ahd_outb(ahd, DSPSELECT, i); - ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT); - } -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd), - WRTBIASCTL_HP_DEFAULT); -#endif - } - ahd_setup_iocell_workaround(ahd); - - /* - * Enable LQI Manager interrupts. - */ - ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT - | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI - | ENLQIOVERI_LQ|ENLQIOVERI_NLQ); - ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC); - /* - * An interrupt from LQOBUSFREE is made redundant by the - * BUSFREE interrupt. We choose to have the sequencer catch - * LQOPHCHGINPKT errors manually for the command phase at the - * start of a packetized selection case. - ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT); - */ - ahd_outb(ahd, LQOMODE1, 0); - - /* - * Setup sequencer interrupt handlers. - */ - ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr)); - ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr)); - - /* - * Setup SCB Offset registers. - */ - if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { - ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, - pkt_long_lun)); - } else { - ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun)); - } - ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len)); - ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute)); - ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management)); - ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb, - shared_data.idata.cdb)); - ahd_outb(ahd, QNEXTPTR, - offsetof(struct hardware_scb, next_hscb_busaddr)); - ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET); - ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control)); - if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { - ahd_outb(ahd, LUNLEN, - sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1); - } else { - ahd_outb(ahd, LUNLEN, sizeof(ahd->next_queued_hscb->lun) - 1); - } - ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1); - ahd_outb(ahd, MAXCMD, 0xFF); - ahd_outb(ahd, SCBAUTOPTR, - AUSCBPTR_EN | offsetof(struct hardware_scb, tag)); - - /* We haven't been enabled for target mode yet. */ - ahd_outb(ahd, MULTARGID, 0); - ahd_outb(ahd, MULTARGID + 1, 0); - - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - /* Initialize the negotiation table. */ - if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) { - /* - * Clear the spare bytes in the neg table to avoid - * spurious parity errors. - */ - for (target = 0; target < AHD_NUM_TARGETS; target++) { - ahd_outb(ahd, NEGOADDR, target); - ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0); - for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++) - ahd_outb(ahd, ANNEXDAT, 0); - } - } - for (target = 0; target < AHD_NUM_TARGETS; target++) { - struct ahd_devinfo devinfo; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - - tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - target, &tstate); - ahd_compile_devinfo(&devinfo, ahd->our_id, - target, CAM_LUN_WILDCARD, - 'A', ROLE_INITIATOR); - ahd_update_neg_table(ahd, &devinfo, &tinfo->curr); - } - - ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR); - ahd_outb(ahd, CLRINT, CLRSCSIINT); - - /* - * Always enable abort on incoming L_Qs if this feature is - * supported. We use this to catch invalid SCB references. - */ - if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0) - ahd_outb(ahd, LQCTL1, ABORTPENDING); - else - ahd_outb(ahd, LQCTL1, 0); - - /* All of our queues are empty */ - ahd->qoutfifonext = 0; - ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE; - ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8); - for (i = 0; i < AHD_QOUT_SIZE; i++) - ahd->qoutfifo[i] = 0; - ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD); - - ahd->qinfifonext = 0; - for (i = 0; i < AHD_QIN_SIZE; i++) - ahd->qinfifo[i] = SCB_LIST_NULL; - - if ((ahd->features & AHD_TARGETMODE) != 0) { - /* All target command blocks start out invalid. */ - for (i = 0; i < AHD_TMODE_CMDS; i++) - ahd->targetcmds[i].cmd_valid = 0; - ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD); - ahd->tqinfifonext = 1; - ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1); - ahd_outb(ahd, TQINPOS, ahd->tqinfifonext); - } - - /* Initialize Scratch Ram. */ - ahd_outb(ahd, SEQ_FLAGS, 0); - ahd_outb(ahd, SEQ_FLAGS2, 0); - - /* We don't have any waiting selections */ - ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL); - ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL); - for (i = 0; i < AHD_NUM_TARGETS; i++) - ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL); - - /* - * Nobody is waiting to be DMAed into the QOUTFIFO. - */ - ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); - ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL); - ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); - - /* - * The Freeze Count is 0. - */ - ahd_outw(ahd, QFREEZE_COUNT, 0); - - /* - * Tell the sequencer where it can find our arrays in memory. - */ - busaddr = ahd->shared_data_busaddr; - ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF); - ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF); - ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF); - ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF); - ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF); - ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF); - ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF); - ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF); - - /* - * Setup the allowed SCSI Sequences based on operational mode. - * If we are a target, we'll enable select in operations once - * we've had a lun enabled. - */ - scsiseq_template = ENAUTOATNP; - if ((ahd->flags & AHD_INITIATORROLE) != 0) - scsiseq_template |= ENRSELI; - ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template); - - /* There are no busy SCBs yet. */ - for (target = 0; target < AHD_NUM_TARGETS; target++) { - int lun; - - for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++) - ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun)); - } - - /* - * Initialize the group code to command length table. - * Vendor Unique codes are set to 0 so we only capture - * the first byte of the cdb. These can be overridden - * when target mode is enabled. - */ - ahd_outb(ahd, CMDSIZE_TABLE, 5); - ahd_outb(ahd, CMDSIZE_TABLE + 1, 9); - ahd_outb(ahd, CMDSIZE_TABLE + 2, 9); - ahd_outb(ahd, CMDSIZE_TABLE + 3, 0); - ahd_outb(ahd, CMDSIZE_TABLE + 4, 15); - ahd_outb(ahd, CMDSIZE_TABLE + 5, 11); - ahd_outb(ahd, CMDSIZE_TABLE + 6, 0); - ahd_outb(ahd, CMDSIZE_TABLE + 7, 0); - - /* Tell the sequencer of our initial queue positions */ - ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); - ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512); - ahd->qinfifonext = 0; - ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); - ahd_set_hescb_qoff(ahd, 0); - ahd_set_snscb_qoff(ahd, 0); - ahd_set_sescb_qoff(ahd, 0); - ahd_set_sdscb_qoff(ahd, 0); - - /* - * Tell the sequencer which SCB will be the next one it receives. - */ - busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); - - /* - * Default to coalessing disabled. - */ - ahd_outw(ahd, INT_COALESSING_CMDCOUNT, 0); - ahd_outw(ahd, CMDS_PENDING, 0); - ahd_update_coalessing_values(ahd, ahd->int_coalessing_timer, - ahd->int_coalessing_maxcmds, - ahd->int_coalessing_mincmds); - ahd_enable_coalessing(ahd, FALSE); - - ahd_loadseq(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); -} - -/* - * Setup default device and controller settings. - * This should only be called if our probe has - * determined that no configuration data is available. - */ -int -ahd_default_config(struct ahd_softc *ahd) -{ - int targ; - - ahd->our_id = 7; - - /* - * Allocate a tstate to house information for our - * initiator presence on the bus as well as the user - * data for any target mode initiator. - */ - if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { - printf("%s: unable to allocate ahd_tmode_tstate. " - "Failing attach\n", ahd_name(ahd)); - return (ENOMEM); - } - - for (targ = 0; targ < AHD_NUM_TARGETS; targ++) { - struct ahd_devinfo devinfo; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - uint16_t target_mask; - - tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - targ, &tstate); - /* - * We support SPC2 and SPI4. - */ - tinfo->user.protocol_version = 4; - tinfo->user.transport_version = 4; - - target_mask = 0x01 << targ; - ahd->user_discenable |= target_mask; - tstate->discenable |= target_mask; - ahd->user_tagenable |= target_mask; -#ifdef AHD_FORCE_160 - tinfo->user.period = AHD_SYNCRATE_DT; -#else - tinfo->user.period = AHD_SYNCRATE_160; -#endif - tinfo->user.offset= ~0; - tinfo->user.ppr_options = MSG_EXT_PPR_RD_STRM - | MSG_EXT_PPR_WR_FLOW - | MSG_EXT_PPR_HOLD_MCS - | MSG_EXT_PPR_IU_REQ - | MSG_EXT_PPR_QAS_REQ - | MSG_EXT_PPR_DT_REQ; - if ((ahd->features & AHD_RTI) != 0) - tinfo->user.ppr_options |= MSG_EXT_PPR_RTI; - - tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT; - - /* - * Start out Async/Narrow/Untagged and with - * conservative protocol support. - */ - tinfo->goal.protocol_version = 2; - tinfo->goal.transport_version = 2; - tinfo->curr.protocol_version = 2; - tinfo->curr.transport_version = 2; - ahd_compile_devinfo(&devinfo, ahd->our_id, - targ, CAM_LUN_WILDCARD, - 'A', ROLE_INITIATOR); - tstate->tagenable &= ~target_mask; - ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); - ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, - /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, - /*paused*/TRUE); - } - return (0); -} - -/* - * Parse device configuration information. - */ -int -ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc) -{ - int targ; - int max_targ; - - max_targ = sc->max_targets & CFMAXTARG; - ahd->our_id = sc->brtime_id & CFSCSIID; - - /* - * Allocate a tstate to house information for our - * initiator presence on the bus as well as the user - * data for any target mode initiator. - */ - if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { - printf("%s: unable to allocate ahd_tmode_tstate. " - "Failing attach\n", ahd_name(ahd)); - return (ENOMEM); - } - - for (targ = 0; targ < max_targ; targ++) { - struct ahd_devinfo devinfo; - struct ahd_initiator_tinfo *tinfo; - struct ahd_transinfo *user_tinfo; - struct ahd_tmode_tstate *tstate; - uint16_t target_mask; - - tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - targ, &tstate); - user_tinfo = &tinfo->user; - - /* - * We support SPC2 and SPI4. - */ - tinfo->user.protocol_version = 4; - tinfo->user.transport_version = 4; - - target_mask = 0x01 << targ; - ahd->user_discenable &= ~target_mask; - tstate->discenable &= ~target_mask; - ahd->user_tagenable &= ~target_mask; - if (sc->device_flags[targ] & CFDISC) { - tstate->discenable |= target_mask; - ahd->user_discenable |= target_mask; - ahd->user_tagenable |= target_mask; - } else { - /* - * Cannot be packetized without disconnection. - */ - sc->device_flags[targ] &= ~CFPACKETIZED; - } - - user_tinfo->ppr_options = 0; - user_tinfo->period = (sc->device_flags[targ] & CFXFER); - if (user_tinfo->period < CFXFER_ASYNC) { - if (user_tinfo->period <= AHD_PERIOD_10MHz) - user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ; - user_tinfo->offset = MAX_OFFSET; - } else { - user_tinfo->offset = 0; - user_tinfo->period = AHD_ASYNC_XFER_PERIOD; - } -#ifdef AHD_FORCE_160 - if (user_tinfo->period <= AHD_SYNCRATE_160) - user_tinfo->period = AHD_SYNCRATE_DT; -#endif - - if ((sc->device_flags[targ] & CFPACKETIZED) != 0) { - user_tinfo->ppr_options |= MSG_EXT_PPR_RD_STRM - | MSG_EXT_PPR_WR_FLOW - | MSG_EXT_PPR_HOLD_MCS - | MSG_EXT_PPR_IU_REQ; - if ((ahd->features & AHD_RTI) != 0) - user_tinfo->ppr_options |= MSG_EXT_PPR_RTI; - } - - if ((sc->device_flags[targ] & CFQAS) != 0) - user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ; - - if ((sc->device_flags[targ] & CFWIDEB) != 0) - user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT; - else - user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) - printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width, - user_tinfo->period, user_tinfo->offset, - user_tinfo->ppr_options); -#endif - /* - * Start out Async/Narrow/Untagged and with - * conservative protocol support. - */ - tstate->tagenable &= ~target_mask; - tinfo->goal.protocol_version = 2; - tinfo->goal.transport_version = 2; - tinfo->curr.protocol_version = 2; - tinfo->curr.transport_version = 2; - ahd_compile_devinfo(&devinfo, ahd->our_id, - targ, CAM_LUN_WILDCARD, - 'A', ROLE_INITIATOR); - ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); - ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, - /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, - /*paused*/TRUE); - } - - ahd->flags &= ~AHD_SPCHK_ENB_A; - if (sc->bios_control & CFSPARITY) - ahd->flags |= AHD_SPCHK_ENB_A; - - ahd->flags &= ~AHD_RESET_BUS_A; - if (sc->bios_control & CFRESETB) - ahd->flags |= AHD_RESET_BUS_A; - - ahd->flags &= ~AHD_EXTENDED_TRANS_A; - if (sc->bios_control & CFEXTEND) - ahd->flags |= AHD_EXTENDED_TRANS_A; - - ahd->flags &= ~AHD_BIOS_ENABLED; - if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED) - ahd->flags |= AHD_BIOS_ENABLED; - - ahd->flags &= ~AHD_STPWLEVEL_A; - if ((sc->adapter_control & CFSTPWLEVEL) != 0) - ahd->flags |= AHD_STPWLEVEL_A; - - return (0); -} - -void -ahd_intr_enable(struct ahd_softc *ahd, int enable) -{ - u_int hcntrl; - - hcntrl = ahd_inb(ahd, HCNTRL); - hcntrl &= ~INTEN; - ahd->pause &= ~INTEN; - ahd->unpause &= ~INTEN; - if (enable) { - hcntrl |= INTEN; - ahd->pause |= INTEN; - ahd->unpause |= INTEN; - } - ahd_outb(ahd, HCNTRL, hcntrl); -} - -void -ahd_update_coalessing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, - u_int mincmds) -{ - if (timer > AHD_TIMER_MAX_US) - timer = AHD_TIMER_MAX_US; - ahd->int_coalessing_timer = timer; - - if (maxcmds > AHD_INT_COALESSING_MAXCMDS_MAX) - maxcmds = AHD_INT_COALESSING_MAXCMDS_MAX; - if (mincmds > AHD_INT_COALESSING_MINCMDS_MAX) - mincmds = AHD_INT_COALESSING_MINCMDS_MAX; - ahd->int_coalessing_maxcmds = maxcmds; - ahd_outw(ahd, INT_COALESSING_TIMER, timer / AHD_TIMER_US_PER_TICK); - ahd_outb(ahd, INT_COALESSING_MAXCMDS, -maxcmds); - ahd_outb(ahd, INT_COALESSING_MINCMDS, -mincmds); -} - -void -ahd_enable_coalessing(struct ahd_softc *ahd, int enable) -{ - - ahd->hs_mailbox &= ~ENINT_COALESS; - if (enable) - ahd->hs_mailbox |= ENINT_COALESS; - ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox); - ahd_flush_device_writes(ahd); - ahd_run_qoutfifo(ahd); -} - -/* - * Ensure that the card is paused in a location - * outside of all critical sections and that all - * pending work is completed prior to returning. - * This routine should only be called from outside - * an interrupt context. - */ -void -ahd_pause_and_flushwork(struct ahd_softc *ahd) -{ - u_int intstat; - u_int maxloops; - int paused; - - maxloops = 1000; - ahd->flags |= AHD_ALL_INTERRUPTS; - intstat = 0; - paused = FALSE; - do { - struct scb *waiting_scb; - - if (paused) - ahd_unpause(ahd); - ahd_intr(ahd); - ahd_pause(ahd); - paused = TRUE; - ahd_clear_critical_section(ahd); - if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0) - ahd_outb(ahd, SCSISEQ0, - ahd_inb(ahd, SCSISEQ0) & ~ENSELO); - /* - * In the non-packetized case, the sequencer (for Rev A), - * relies on ENSELO remaining set after SELDO. The hardware - * auto-clears ENSELO in the packetized case. - */ - waiting_scb = ahd_lookup_scb(ahd, - ahd_inw(ahd, WAITING_TID_HEAD)); - if (waiting_scb != NULL - && (waiting_scb->flags & SCB_PACKETIZED) == 0 - && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0) - ahd_outb(ahd, SCSISEQ0, - ahd_inb(ahd, SCSISEQ0) | ENSELO); - - if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) - break; - } while (--maxloops - && (((intstat = ahd_inb(ahd, INTSTAT)) & INT_PEND) != 0 - || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)))); - if (maxloops == 0) { - printf("Infinite interrupt loop, INTSTAT = %x", - ahd_inb(ahd, INTSTAT)); - } - - ahd_flush_qoutfifo(ahd); - - ahd_platform_flushwork(ahd); - ahd->flags &= ~AHD_ALL_INTERRUPTS; -} - -int -ahd_suspend(struct ahd_softc *ahd) -{ -#if 0 - uint8_t *ptr; - int i; - - ahd_pause_and_flushwork(ahd); - - if (LIST_FIRST(&ahd->pending_scbs) != NULL) - return (EBUSY); - -#if AHD_TARGET_MODE - /* - * XXX What about ATIOs that have not yet been serviced? - * Perhaps we should just refuse to be suspended if we - * are acting in a target role. - */ - if (ahd->pending_device != NULL) - return (EBUSY); -#endif - - /* Save volatile registers */ - ahd->suspend_state.channel[0].scsiseq = ahd_inb(ahd, SCSISEQ0); - ahd->suspend_state.channel[0].sxfrctl0 = ahd_inb(ahd, SXFRCTL0); - ahd->suspend_state.channel[0].sxfrctl1 = ahd_inb(ahd, SXFRCTL1); - ahd->suspend_state.channel[0].simode0 = ahd_inb(ahd, SIMODE0); - ahd->suspend_state.channel[0].simode1 = ahd_inb(ahd, SIMODE1); - ahd->suspend_state.channel[0].seltimer = ahd_inb(ahd, SELTIMER); - ahd->suspend_state.channel[0].seqctl = ahd_inb(ahd, SEQCTL0); - ahd->suspend_state.dscommand0 = ahd_inb(ahd, DSCOMMAND0); - ahd->suspend_state.dspcistatus = ahd_inb(ahd, DSPCISTATUS); - - if ((ahd->features & AHD_DT) != 0) { - u_int sfunct; - - sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE; - ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE); - ahd->suspend_state.optionmode = ahd_inb(ahd, OPTIONMODE); - ahd_outb(ahd, SFUNCT, sfunct); - ahd->suspend_state.crccontrol1 = ahd_inb(ahd, CRCCONTROL1); - } - - if ((ahd->features & AHD_MULTI_FUNC) != 0) - ahd->suspend_state.scbbaddr = ahd_inb(ahd, SCBBADDR); - - if ((ahd->features & AHD_ULTRA2) != 0) - ahd->suspend_state.dff_thrsh = ahd_inb(ahd, DFF_THRSH); - - ptr = ahd->suspend_state.scratch_ram; - for (i = 0; i < 64; i++) - *ptr++ = ahd_inb(ahd, SRAM_BASE + i); - - if ((ahd->features & AHD_MORE_SRAM) != 0) { - for (i = 0; i < 16; i++) - *ptr++ = ahd_inb(ahd, TARG_OFFSET + i); - } - - ptr = ahd->suspend_state.btt; - for (i = 0;i < AHD_NUM_TARGETS; i++) { - int j; - - for (j = 0;j < AHD_NUM_LUNS_NONPKT; j++) { - u_int tcl; - - tcl = BUILD_TCL_RAW(i, 'A', j); - *ptr = ahd_find_busy_tcl(ahd, tcl); - } - } - ahd_shutdown(ahd); -#endif - return (0); -} - -int -ahd_resume(struct ahd_softc *ahd) -{ -#if 0 - uint8_t *ptr; - int i; - - ahd_reset(ahd); - - ahd_build_free_scb_list(ahd); - - /* Restore volatile registers */ - ahd_outb(ahd, SCSISEQ0, ahd->suspend_state.channel[0].scsiseq); - ahd_outb(ahd, SXFRCTL0, ahd->suspend_state.channel[0].sxfrctl0); - ahd_outb(ahd, SXFRCTL1, ahd->suspend_state.channel[0].sxfrctl1); - ahd_outb(ahd, SIMODE0, ahd->suspend_state.channel[0].simode0); - ahd_outb(ahd, SIMODE1, ahd->suspend_state.channel[0].simode1); - ahd_outb(ahd, SELTIMER, ahd->suspend_state.channel[0].seltimer); - ahd_outb(ahd, SEQCTL0, ahd->suspend_state.channel[0].seqctl); - if ((ahd->features & AHD_ULTRA2) != 0) - ahd_outb(ahd, SCSIID_ULTRA2, ahd->our_id); - else - ahd_outb(ahd, SCSIID, ahd->our_id); - - ahd_outb(ahd, DSCOMMAND0, ahd->suspend_state.dscommand0); - ahd_outb(ahd, DSPCISTATUS, ahd->suspend_state.dspcistatus); - - if ((ahd->features & AHD_DT) != 0) { - u_int sfunct; - - sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE; - ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE); - ahd_outb(ahd, OPTIONMODE, ahd->suspend_state.optionmode); - ahd_outb(ahd, SFUNCT, sfunct); - ahd_outb(ahd, CRCCONTROL1, ahd->suspend_state.crccontrol1); - } - - if ((ahd->features & AHD_MULTI_FUNC) != 0) - ahd_outb(ahd, SCBBADDR, ahd->suspend_state.scbbaddr); - - if ((ahd->features & AHD_ULTRA2) != 0) - ahd_outb(ahd, DFF_THRSH, ahd->suspend_state.dff_thrsh); - - ptr = ahd->suspend_state.scratch_ram; - for (i = 0; i < 64; i++) - ahd_outb(ahd, SRAM_BASE + i, *ptr++); - - if ((ahd->features & AHD_MORE_SRAM) != 0) { - for (i = 0; i < 16; i++) - ahd_outb(ahd, TARG_OFFSET + i, *ptr++); - } - - ptr = ahd->suspend_state.btt; - for (i = 0;i < AHD_NUM_TARGETS; i++) { - int j; - - for (j = 0;j < AHD_NUM_LUNS; j++) { - u_int tcl; - - tcl = BUILD_TCL(i << 4, j); - ahd_busy_tcl(ahd, tcl, *ptr); - } - } -#endif - return (0); -} - -/************************** Busy Target Table *********************************/ -/* - * Set SCBPTR to the SCB that contains the busy - * table entry for TCL. Return the offset into - * the SCB that contains the entry for TCL. - * saved_scbid is dereferenced and set to the - * scbid that should be restored once manipualtion - * of the TCL entry is complete. - */ -static __inline u_int -ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl) -{ - /* - * Index to the SCB that contains the busy entry. - */ - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - *saved_scbid = ahd_get_scbptr(ahd); - ahd_set_scbptr(ahd, TCL_LUN(tcl) - | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4)); - - /* - * And now calculate the SCB offset to the entry. - * Each entry is 2 bytes wide, hence the - * multiplication by 2. - */ - return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS); -} - -/* - * Return the untagged transaction id for a given target/channel lun. - * Optionally, clear the entry. - */ -u_int -ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) -{ - u_int scbid; - u_int scb_offset; - u_int saved_scbptr; - - scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl); - scbid = ahd_inw_scbram(ahd, scb_offset); - ahd_set_scbptr(ahd, saved_scbptr); - return (scbid); -} - -void -ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) -{ - u_int scb_offset; - u_int saved_scbptr; - - scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl); - ahd_outw(ahd, scb_offset, scbid); - ahd_set_scbptr(ahd, saved_scbptr); -} - -/************************** SCB and SCB queue management **********************/ -int -ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, - char channel, int lun, u_int tag, role_t role) -{ - int targ = SCB_GET_TARGET(ahd, scb); - char chan = SCB_GET_CHANNEL(ahd, scb); - int slun = SCB_GET_LUN(scb); - int match; - - match = ((chan == channel) || (channel == ALL_CHANNELS)); - if (match != 0) - match = ((targ == target) || (target == CAM_TARGET_WILDCARD)); - if (match != 0) - match = ((lun == slun) || (lun == CAM_LUN_WILDCARD)); - if (match != 0) { -#if AHD_TARGET_MODE - int group; - - group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code); - if (role == ROLE_INITIATOR) { - match = (group != XPT_FC_GROUP_TMODE) - && ((tag == SCB_GET_TAG(scb)) - || (tag == SCB_LIST_NULL)); - } else if (role == ROLE_TARGET) { - match = (group == XPT_FC_GROUP_TMODE) - && ((tag == scb->io_ctx->csio.tag_id) - || (tag == SCB_LIST_NULL)); - } -#else /* !AHD_TARGET_MODE */ - match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL)); -#endif /* AHD_TARGET_MODE */ - } - - return match; -} - -void -ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb) -{ - int target; - char channel; - int lun; - - target = SCB_GET_TARGET(ahd, scb); - lun = SCB_GET_LUN(scb); - channel = SCB_GET_CHANNEL(ahd, scb); - - ahd_search_qinfifo(ahd, target, channel, lun, - /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN, - CAM_REQUEUE_REQ, SEARCH_COMPLETE); - - ahd_platform_freeze_devq(ahd, scb); -} - -void -ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb) -{ - struct scb *prev_scb; - ahd_mode_state saved_modes; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); - prev_scb = NULL; - if (ahd_qinfifo_count(ahd) != 0) { - u_int prev_tag; - u_int prev_pos; - - prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1); - prev_tag = ahd->qinfifo[prev_pos]; - prev_scb = ahd_lookup_scb(ahd, prev_tag); - } - ahd_qinfifo_requeue(ahd, prev_scb, scb); - ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); - ahd_restore_modes(ahd, saved_modes); -} - -static void -ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb, - struct scb *scb) -{ - if (prev_scb == NULL) { - uint32_t busaddr; - - busaddr = ahd_le32toh(scb->hscb->hscb_busaddr); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); - } else { - prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; - ahd_sync_scb(ahd, prev_scb, - BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - } - ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); - ahd->qinfifonext++; - scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr; - ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); -} - -static int -ahd_qinfifo_count(struct ahd_softc *ahd) -{ - u_int qinpos; - u_int wrap_qinpos; - u_int wrap_qinfifonext; - - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - qinpos = ahd_get_snscb_qoff(ahd); - wrap_qinpos = AHD_QIN_WRAP(qinpos); - wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext); - if (wrap_qinfifonext >= wrap_qinpos) - return (wrap_qinfifonext - wrap_qinpos); - else - return (wrap_qinfifonext - + NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos); -} - -void -ahd_reset_cmds_pending(struct ahd_softc *ahd) -{ - struct scb *scb; - ahd_mode_state saved_modes; - u_int pending_cmds; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); - - /* - * Don't count any commands as outstanding that the - * sequencer has already marked for completion. - */ - ahd_flush_qoutfifo(ahd); - - pending_cmds = 0; - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { - pending_cmds++; - } - ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd)); - ahd_restore_modes(ahd, saved_modes); - ahd->flags &= ~AHD_UPDATE_PEND_CMDS; -} - -int -ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, - int lun, u_int tag, role_t role, uint32_t status, - ahd_search_action action) -{ - struct scb *scb; - struct scb *prev_scb; - ahd_mode_state saved_modes; - u_int qinstart; - u_int qinpos; - u_int qintail; - u_int tid_next; - u_int tid_prev; - u_int scbid; - u_int savedscbptr; - uint32_t busaddr; - int found; - int targets; - - /* Must be in CCHAN mode */ - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); - - /* - * Halt any pending SCB DMA. The sequencer will reinitiate - * this dma if the qinfifo is not empty once we unpause. - */ - if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR)) - == (CCARREN|CCSCBEN|CCSCBDIR)) { - ahd_outb(ahd, CCSCBCTL, - ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN)); - while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) - ; - } - /* Determine sequencer's position in the qinfifo. */ - qintail = AHD_QIN_WRAP(ahd->qinfifonext); - qinstart = ahd_get_snscb_qoff(ahd); - qinpos = AHD_QIN_WRAP(qinstart); - found = 0; - prev_scb = NULL; - - if (action == SEARCH_PRINT) { - printf("qinstart = %d qinfifonext = %d\nQINFIFO:", - qinstart, ahd->qinfifonext); - } - - /* - * Start with an empty queue. Entries that are not chosen - * for removal will be re-added to the queue as we go. - */ - ahd->qinfifonext = qinstart; - busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); - ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); - - while (qinpos != qintail) { - scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]); - if (scb == NULL) { - printf("qinpos = %d, SCB index = %d\n", - qinpos, ahd->qinfifo[qinpos]); - panic("Loop 1\n"); - } - - if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) { - /* - * We found an scb that needs to be acted on. - */ - found++; - switch (action) { - case SEARCH_COMPLETE: - { - cam_status ostat; - cam_status cstat; - - ostat = ahd_get_transaction_status(scb); - if (ostat == CAM_REQ_INPROG) - ahd_set_transaction_status(scb, - status); - cstat = ahd_get_transaction_status(scb); - if (cstat != CAM_REQ_CMP) - ahd_freeze_scb(scb); - if ((scb->flags & SCB_ACTIVE) == 0) - printf("Inactive SCB in qinfifo\n"); - ahd_done(ahd, scb); - - /* FALLTHROUGH */ - } - case SEARCH_REMOVE: - break; - case SEARCH_PRINT: - printf(" 0x%x", ahd->qinfifo[qinpos]); - /* FALLTHROUGH */ - case SEARCH_COUNT: - ahd_qinfifo_requeue(ahd, prev_scb, scb); - prev_scb = scb; - break; - } - } else { - ahd_qinfifo_requeue(ahd, prev_scb, scb); - prev_scb = scb; - } - qinpos = AHD_QIN_WRAP(qinpos+1); - } - - ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); - - if (action == SEARCH_PRINT) - printf("\nWAITING_TID_QUEUES:\n"); - - /* - * Search waiting for selection lists. We traverse the - * list of "their ids" waiting for selection and, if - * appropriate, traverse the SCBs of each "their id" - * looking for matches. - */ - savedscbptr = ahd_get_scbptr(ahd); - tid_next = ahd_inw(ahd, WAITING_TID_HEAD); - tid_prev = SCB_LIST_NULL; - targets = 0; - for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) { - u_int tid_head; - - /* - * We limit based on the number of SCBs since - * MK_MESSAGE SCBs are not in the per-tid lists. - */ - targets++; - if (targets > AHD_SCB_MAX) { - panic("TID LIST LOOP"); - } - if (scbid >= ahd->scb_data.numscbs) { - printf("%s: Waiting TID List inconsistency. " - "SCB index == 0x%x, yet numscbs == 0x%x.", - ahd_name(ahd), scbid, ahd->scb_data.numscbs); - ahd_dump_card_state(ahd); - panic("for safety"); - } - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("%s: SCB = 0x%x Not Active!\n", - ahd_name(ahd), scbid); - panic("Waiting TID List traversal\n"); - } - ahd_set_scbptr(ahd, scbid); - tid_next = ahd_inw_scbram(ahd, SCB_NEXT2); - if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD, - SCB_LIST_NULL, ROLE_UNKNOWN) == 0) { - tid_prev = scbid; - continue; - } - - /* - * We found a list of scbs that needs to be searched. - */ - if (action == SEARCH_PRINT) - printf(" %d ( ", SCB_GET_TARGET(ahd, scb)); - tid_head = scbid; - found += ahd_search_scb_list(ahd, target, channel, - lun, tag, role, status, - action, &tid_head, - SCB_GET_TARGET(ahd, scb)); - if (tid_head != scbid) - ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next); - if (!SCBID_IS_NULL(tid_head)) - tid_prev = tid_head; - if (action == SEARCH_PRINT) - printf(")\n"); - } - ahd_set_scbptr(ahd, savedscbptr); - ahd_restore_modes(ahd, saved_modes); - return (found); -} - -static int -ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, - int lun, u_int tag, role_t role, uint32_t status, - ahd_search_action action, u_int *list_head, u_int tid) -{ - struct scb *scb; - u_int scbid; - u_int next; - u_int prev; - int found; - - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - found = 0; - prev = SCB_LIST_NULL; - next = *list_head; - for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) { - if (scbid >= ahd->scb_data.numscbs) { - printf("%s:SCB List inconsistency. " - "SCB == 0x%x, yet numscbs == 0x%x.", - ahd_name(ahd), scbid, ahd->scb_data.numscbs); - ahd_dump_card_state(ahd); - panic("for safety"); - } - scb = ahd_lookup_scb(ahd, scbid); - if (scb == NULL) { - printf("%s: SCB = %d Not Active!\n", - ahd_name(ahd), scbid); - panic("Waiting List traversal\n"); - } - ahd_set_scbptr(ahd, scbid); - next = ahd_inw_scbram(ahd, SCB_NEXT); - if (ahd_match_scb(ahd, scb, target, channel, - lun, SCB_LIST_NULL, role) == 0) { - prev = scbid; - continue; - } - found++; - switch (action) { - case SEARCH_COMPLETE: - { - cam_status ostat; - cam_status cstat; - - ostat = ahd_get_transaction_status(scb); - if (ostat == CAM_REQ_INPROG) - ahd_set_transaction_status(scb, status); - cstat = ahd_get_transaction_status(scb); - if (cstat != CAM_REQ_CMP) - ahd_freeze_scb(scb); - if ((scb->flags & SCB_ACTIVE) == 0) - printf("Inactive SCB in Waiting List\n"); - ahd_done(ahd, scb); - /* FALLTHROUGH */ - } - case SEARCH_REMOVE: - ahd_rem_wscb(ahd, scbid, prev, next, tid); - if (prev == SCB_LIST_NULL) - *list_head = next; - break; - case SEARCH_PRINT: - printf("0x%x ", scbid); - case SEARCH_COUNT: - prev = scbid; - break; - } - if (found > AHD_SCB_MAX) - panic("SCB LIST LOOP"); - } - if (action == SEARCH_COMPLETE - || action == SEARCH_REMOVE) - ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found); - return (found); -} - -static void -ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev, - u_int tid_cur, u_int tid_next) -{ - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - - if (SCBID_IS_NULL(tid_cur)) { - - /* Bypass current TID list */ - if (SCBID_IS_NULL(tid_prev)) { - ahd_outw(ahd, WAITING_TID_HEAD, tid_next); - } else { - ahd_set_scbptr(ahd, tid_prev); - ahd_outw(ahd, SCB_NEXT2, tid_next); - } - if (SCBID_IS_NULL(tid_next)) - ahd_outw(ahd, WAITING_TID_TAIL, tid_prev); - } else { - - /* Stitch through tid_cur */ - if (SCBID_IS_NULL(tid_prev)) { - ahd_outw(ahd, WAITING_TID_HEAD, tid_cur); - } else { - ahd_set_scbptr(ahd, tid_prev); - ahd_outw(ahd, SCB_NEXT2, tid_cur); - } - ahd_set_scbptr(ahd, tid_cur); - ahd_outw(ahd, SCB_NEXT2, tid_next); - - if (SCBID_IS_NULL(tid_next)) - ahd_outw(ahd, WAITING_TID_TAIL, tid_cur); - } -} - -/* - * Manipulate the waiting for selection list and return the - * scb that follows the one that we remove. - */ -static u_int -ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, - u_int prev, u_int next, u_int tid) -{ - u_int tail_offset; - - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - if (!SCBID_IS_NULL(prev)) { - ahd_set_scbptr(ahd, prev); - ahd_outw(ahd, SCB_NEXT, next); - } - - /* - * SCBs that had MK_MESSAGE set in them will not - * be queued to the per-target lists, so don't - * blindly clear the tail pointer. - */ - tail_offset = WAITING_SCB_TAILS + (2 * tid); - if (SCBID_IS_NULL(next) - && ahd_inw(ahd, tail_offset) == scbid) - ahd_outw(ahd, tail_offset, prev); - ahd_add_scb_to_free_list(ahd, scbid); - return (next); -} - -/* - * Add the SCB as selected by SCBPTR onto the on chip list of - * free hardware SCBs. This list is empty/unused if we are not - * performing SCB paging. - */ -static void -ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid) -{ -/* XXX Need some other mechanism to designate "free". */ - /* - * Invalidate the tag so that our abort - * routines don't think it's active. - ahd_outb(ahd, SCB_TAG, SCB_LIST_NULL); - */ -} - -/******************************** Error Handling ******************************/ -/* - * Abort all SCBs that match the given description (target/channel/lun/tag), - * setting their status to the passed in status if the status has not already - * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer - * is paused before it is called. - */ -int -ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, - int lun, u_int tag, role_t role, uint32_t status) -{ - struct scb *scbp; - struct scb *scbp_next; - u_int active_scb; - u_int i, j; - u_int maxtarget; - u_int minlun; - u_int maxlun; - int found; - ahd_mode_state saved_modes; - - /* restore these when we're done */ - active_scb = ahd_get_scbptr(ahd); - saved_modes = ahd_save_modes(ahd); - - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL, - role, CAM_REQUEUE_REQ, SEARCH_COMPLETE); - - /* - * Clean out the busy target table for any untagged commands. - */ - i = 0; - maxtarget = 16; - if (target != CAM_TARGET_WILDCARD) { - i = target; - if (channel == 'B') - i += 8; - maxtarget = i + 1; - } - - if (lun == CAM_LUN_WILDCARD) { - minlun = 0; - maxlun = AHD_NUM_LUNS_NONPKT; - } else if (lun >= AHD_NUM_LUNS_NONPKT) { - minlun = maxlun = 0; - } else { - minlun = lun; - maxlun = lun + 1; - } - - if (role != ROLE_TARGET) { - for (;i < maxtarget; i++) { - for (j = minlun;j < maxlun; j++) { - u_int scbid; - u_int tcl; - - tcl = BUILD_TCL_RAW(i, 'A', j); - scbid = ahd_find_busy_tcl(ahd, tcl); - scbp = ahd_lookup_scb(ahd, scbid); - if (scbp == NULL - || ahd_match_scb(ahd, scbp, target, channel, - lun, tag, role) == 0) - continue; - ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j)); - } - } - } - - /* - * Don't abort commands that have already completed, - * but haven't quite made it up to the host yet. - */ - ahd_flush_qoutfifo(ahd); - - /* - * Go through the pending CCB list and look for - * commands for this target that are still active. - * These are other tagged commands that were - * disconnected when the reset occurred. - */ - scbp_next = LIST_FIRST(&ahd->pending_scbs); - while (scbp_next != NULL) { - scbp = scbp_next; - scbp_next = LIST_NEXT(scbp, pending_links); - if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) { - cam_status ostat; - - ostat = ahd_get_transaction_status(scbp); - if (ostat == CAM_REQ_INPROG) - ahd_set_transaction_status(scbp, status); - if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP) - ahd_freeze_scb(scbp); - if ((scbp->flags & SCB_ACTIVE) == 0) - printf("Inactive SCB on pending list\n"); - ahd_done(ahd, scbp); - found++; - } - } - ahd_set_scbptr(ahd, active_scb); - ahd_restore_modes(ahd, saved_modes); - ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status); - ahd->flags |= AHD_UPDATE_PEND_CMDS; - return found; -} - -static void -ahd_reset_current_bus(struct ahd_softc *ahd) -{ - uint8_t scsiseq; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST); - scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO); - ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO); - ahd_delay(AHD_BUSRESET_DELAY); - /* Turn off the bus reset */ - ahd_outb(ahd, SCSISEQ0, scsiseq); - if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) { - /* - * 2A Razor #474 - * Certain chip state is not cleared for - * SCSI bus resets that we initiate, so - * we must reset the chip. - */ - ahd_delay(AHD_BUSRESET_DELAY); - ahd_reset(ahd); - ahd_intr_enable(ahd, /*enable*/TRUE); - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - } - - ahd_clear_intstat(ahd); -} - -int -ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) -{ - struct ahd_devinfo devinfo; - u_int initiator; - u_int target; - u_int max_scsiid; - int found; - u_int fifo; - u_int next_fifo; - - ahd->pending_device = NULL; - - ahd_compile_devinfo(&devinfo, - CAM_TARGET_WILDCARD, - CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD, - channel, ROLE_UNKNOWN); - ahd_pause(ahd); - - /* Make sure the sequencer is in a safe location. */ - ahd_clear_critical_section(ahd); - -#if AHD_TARGET_MODE - if ((ahd->flags & AHD_TARGETROLE) != 0) { - ahd_run_tqinfifo(ahd, /*paused*/TRUE); - } -#endif - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - - /* - * Disable selections so no automatic hardware - * functions will modify chip state. - */ - ahd_outb(ahd, SCSISEQ0, 0); - ahd_outb(ahd, SCSISEQ1, 0); - - /* - * Safely shut down our DMA engines. Always start with - * the FIFO that is not currently active (if any are - * actively connected). - */ - next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO; - if (next_fifo > CURRFIFO_1) - /* If disconneced, arbitrarily start with FIFO1. */ - next_fifo = fifo = 0; - do { - next_fifo ^= CURRFIFO_1; - ahd_set_modes(ahd, next_fifo, next_fifo); - ahd_outb(ahd, DFCNTRL, - ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN)); - while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0) - ahd_delay(10); - /* - * Set CURRFIFO to the now inactive channel. - */ - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_outb(ahd, DFFSTAT, next_fifo); - } while (next_fifo != fifo); - /* - * Reset the bus if we are initiating this reset - */ - ahd_clear_msg_state(ahd); - ahd_outb(ahd, SIMODE1, - ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE)); - if (initiate_reset) - ahd_reset_current_bus(ahd); - ahd_clear_intstat(ahd); - - /* - * Clean up all the state information for the - * pending transactions on this bus. - */ - found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel, - CAM_LUN_WILDCARD, SCB_LIST_NULL, - ROLE_UNKNOWN, CAM_SCSI_BUS_RESET); - - /* - * Cleanup anything left in the FIFOs. - */ - ahd_clear_fifo(ahd, 0); - ahd_clear_fifo(ahd, 1); - - /* - * Revert to async/narrow transfers until we renegotiate. - */ - max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; - for (target = 0; target <= max_scsiid; target++) { - - if (ahd->enabled_targets[target] == NULL) - continue; - for (initiator = 0; initiator <= max_scsiid; initiator++) { - struct ahd_devinfo devinfo; - - ahd_compile_devinfo(&devinfo, target, initiator, - CAM_LUN_WILDCARD, - 'A', ROLE_UNKNOWN); - ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_CUR, /*paused*/TRUE); - ahd_set_syncrate(ahd, &devinfo, /*period*/0, - /*offset*/0, /*ppr_options*/0, - AHD_TRANS_CUR, /*paused*/TRUE); - } - } - -#ifdef AHD_TARGET_MODE - max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; - - /* - * Send an immediate notify ccb to all target more peripheral - * drivers affected by this action. - */ - for (target = 0; target <= max_scsiid; target++) { - struct ahd_tmode_tstate* tstate; - u_int lun; - - tstate = ahd->enabled_targets[target]; - if (tstate == NULL) - continue; - for (lun = 0; lun < AHD_NUM_LUNS; lun++) { - struct ahd_tmode_lstate* lstate; - - lstate = tstate->enabled_luns[lun]; - if (lstate == NULL) - continue; - - ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD, - EVENT_TYPE_BUS_RESET, /*arg*/0); - ahd_send_lstate_events(ahd, lstate); - } - } -#endif - /* Notify the XPT that a bus reset occurred */ - ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); - ahd_restart(ahd); - /* - * Freeze the SIMQ until our poller can determine that - * the bus reset has really gone away. We set the initial - * timer to 0 to have the check performed as soon as possible - * from the timer context. - */ - if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) { - ahd->flags |= AHD_RESET_POLL_ACTIVE; - ahd_freeze_simq(ahd); - ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd); - } - return (found); -} - - -#define AHD_RESET_POLL_US 1000 -static void -ahd_reset_poll(void *arg) -{ - struct ahd_softc *ahd; - u_int scsiseq1; - u_long l; - u_long s; - - ahd_list_lock(&l); - ahd = ahd_find_softc((struct ahd_softc *)arg); - if (ahd == NULL) { - printf("ahd_reset_poll: Instance %p no longer exists\n", arg); - ahd_list_unlock(&l); - return; - } - ahd_lock(ahd, &s); - ahd_pause(ahd); - ahd_update_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); - if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) { - ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US, - ahd_reset_poll, ahd); - ahd_unpause(ahd); - ahd_unlock(ahd, &s); - ahd_list_unlock(&l); - return; - } - - /* Reset is now low. Complete chip reinitialization. */ - ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); - scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); - ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP)); - ahd_unpause(ahd); - ahd->flags &= ~AHD_RESET_POLL_ACTIVE; - ahd_unlock(ahd, &s); - ahd_release_simq(ahd); - ahd_list_unlock(&l); -} - -/**************************** Statistics Processing ***************************/ -static void -ahd_stat_timer(void *arg) -{ - struct ahd_softc *ahd; - u_long l; - u_long s; - int enint_coal; - - ahd_list_lock(&l); - ahd = ahd_find_softc((struct ahd_softc *)arg); - if (ahd == NULL) { - printf("ahd_stat_timer: Instance %p no longer exists\n", arg); - ahd_list_unlock(&l); - return; - } - ahd_lock(ahd, &s); - - enint_coal = ahd->hs_mailbox & ENINT_COALESS; - if (ahd->cmdcmplt_total > ahd->int_coalessing_threshold) - enint_coal |= ENINT_COALESS; - else if (ahd->cmdcmplt_total < ahd->int_coalessing_stop_threshold) - enint_coal &= ~ENINT_COALESS; - - if (enint_coal != (ahd->hs_mailbox & ENINT_COALESS)) { - ahd_enable_coalessing(ahd, enint_coal); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_INT_COALESSING) != 0) - printf("%s: Interrupt coalessing " - "now %sabled. Cmds %d\n", - ahd_name(ahd), - (enint_coal & ENINT_COALESS) ? "en" : "dis", - ahd->cmdcmplt_total); -#endif - } - - ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1); - ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]; - ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0; - ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, - ahd_stat_timer, ahd); - ahd_unlock(ahd, &s); - ahd_list_unlock(&l); -} - -/****************************** Status Processing *****************************/ -void -ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) -{ - if (scb->hscb->shared_data.istatus.scsi_status != 0) { - ahd_handle_scsi_status(ahd, scb); - } else { - ahd_calc_residual(ahd, scb); - ahd_done(ahd, scb); - } -} - -void -ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) -{ - struct hardware_scb *hscb; - u_int qfreeze_cnt; - ahd_mode_state saved_modes; - - /* - * The sequencer freezes its select-out queue - * anytime a SCSI status error occurs. We must - * handle the error and decrement the QFREEZE count - * to allow the sequencer to continue. - */ - hscb = scb->hscb; - - /* Freeze the queue until the client sees the error. */ - ahd_pause(ahd); - saved_modes = ahd_save_modes(ahd); - ahd_clear_critical_section(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - ahd_freeze_devq(ahd, scb); - ahd_freeze_scb(scb); - qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT); - if (qfreeze_cnt == 0) { - printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd)); - } else { - qfreeze_cnt--; - ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt); - } - if (qfreeze_cnt == 0) - ahd_outb(ahd, SEQ_FLAGS2, - ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN); - ahd_unpause(ahd); - /* Don't want to clobber the original sense code */ - if ((scb->flags & SCB_SENSE) != 0) { - /* - * Clear the SCB_SENSE Flag and perform - * a normal command completion. - */ - scb->flags &= ~SCB_SENSE; - ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); - ahd_done(ahd, scb); - return; - } - ahd_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR); - ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status); - switch (hscb->shared_data.istatus.scsi_status) { - case STATUS_PKT_SENSE: - { - struct scsi_status_iu_header *siu; - - ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD); - siu = (struct scsi_status_iu_header *)scb->sense_data; - ahd_set_scsi_status(scb, siu->status); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_SENSE) != 0) { - ahd_print_path(ahd, scb); - printf("SCB 0x%x Received PKT Status of 0x%x\n", - SCB_GET_TAG(scb), siu->status); - printf("\tflags = 0x%x, sense len = 0x%x, " - "pktfail = 0x%x\n", - siu->flags, scsi_4btoul(siu->sense_length), - scsi_4btoul(siu->pkt_failures_length)); - } -#endif - if ((siu->flags & SIU_RSPVALID) != 0) { - ahd_print_path(ahd, scb); - if (scsi_4btoul(siu->pkt_failures_length) < 4) { - printf("Unable to parse pkt_failures\n"); - } else { - - switch (SIU_PKTFAIL_CODE(siu)) { - case SIU_PFC_NONE: - printf("No packet failure found\n"); - break; - case SIU_PFC_CIU_FIELDS_INVALID: - printf("Invalid Command IU Field\n"); - break; - case SIU_PFC_TMF_NOT_SUPPORTED: - printf("TMF not supportd\n"); - break; - case SIU_PFC_TMF_FAILED: - printf("TMF failed\n"); - break; - case SIU_PFC_INVALID_TYPE_CODE: - printf("Invalid L_Q Type code\n"); - break; - case SIU_PFC_ILLEGAL_REQUEST: - printf("Illegal request\n"); - default: - break; - } - } - if (siu->status == SCSI_STATUS_OK) - ahd_set_transaction_status(scb, - CAM_REQ_CMP_ERR); - } - if ((siu->flags & SIU_SNSVALID) != 0) { - scb->flags |= SCB_PKT_SENSE; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_SENSE) != 0) - printf("Sense data available\n"); -#endif - } - ahd_done(ahd, scb); - break; - } - case SCSI_STATUS_CMD_TERMINATED: - case SCSI_STATUS_CHECK_COND: - { - struct ahd_devinfo devinfo; - struct ahd_dma_seg *sg; - struct scsi_sense *sc; - struct ahd_initiator_tinfo *targ_info; - struct ahd_tmode_tstate *tstate; - struct ahd_transinfo *tinfo; -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_SENSE) { - ahd_print_path(ahd, scb); - printf("SCB %d: requests Check Status\n", - SCB_GET_TAG(scb)); - } -#endif - - if (ahd_perform_autosense(scb) == 0) - break; - - ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb), - SCB_GET_TARGET(ahd, scb), - SCB_GET_LUN(scb), - SCB_GET_CHANNEL(ahd, scb), - ROLE_INITIATOR); - targ_info = ahd_fetch_transinfo(ahd, - devinfo.channel, - devinfo.our_scsiid, - devinfo.target, - &tstate); - tinfo = &targ_info->curr; - sg = scb->sg_list; - sc = (struct scsi_sense *)hscb->shared_data.idata.cdb; - /* - * Save off the residual if there is one. - */ - ahd_update_residual(ahd, scb); -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_SENSE) { - ahd_print_path(ahd, scb); - printf("Sending Sense\n"); - } -#endif - scb->sg_count = 0; - sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb), - ahd_get_sense_bufsize(ahd, scb), - /*last*/TRUE); - sc->opcode = REQUEST_SENSE; - sc->byte2 = 0; - if (tinfo->protocol_version <= SCSI_REV_2 - && SCB_GET_LUN(scb) < 8) - sc->byte2 = SCB_GET_LUN(scb) << 5; - sc->unused[0] = 0; - sc->unused[1] = 0; - sc->length = ahd_get_sense_bufsize(ahd, scb); - sc->control = 0; - - /* - * We can't allow the target to disconnect. - * This will be an untagged transaction and - * having the target disconnect will make this - * transaction indestinguishable from outstanding - * tagged transactions. - */ - hscb->control = 0; - - /* - * This request sense could be because the - * the device lost power or in some other - * way has lost our transfer negotiations. - * Renegotiate if appropriate. Unit attention - * errors will be reported before any data - * phases occur. - */ - if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) { - ahd_update_neg_request(ahd, &devinfo, - tstate, targ_info, - AHD_NEG_IF_NON_ASYNC); - } - if (tstate->auto_negotiate & devinfo.target_mask) { - hscb->control |= MK_MESSAGE; - scb->flags &= - ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET); - scb->flags |= SCB_AUTO_NEGOTIATE; - } - hscb->cdb_len = sizeof(*sc); - ahd_setup_data_scb(ahd, scb); - scb->flags |= SCB_SENSE; - ahd_queue_scb(ahd, scb); - /* - * Ensure we have enough time to actually - * retrieve the sense. - */ - ahd_scb_timer_reset(scb, 5 * 1000000); - break; - } - case SCSI_STATUS_OK: - printf("%s: Interrupted for staus of 0???\n", - ahd_name(ahd)); - /* FALLTHROUGH */ - default: - ahd_done(ahd, scb); - break; - } -} - -/* - * Calculate the residual for a just completed SCB. - */ -void -ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb) -{ - struct hardware_scb *hscb; - struct initiator_status *spkt; - uint32_t sgptr; - uint32_t resid_sgptr; - uint32_t resid; - - /* - * 5 cases. - * 1) No residual. - * SG_STATUS_VALID clear in sgptr. - * 2) Transferless command - * 3) Never performed any transfers. - * sgptr has SG_FULL_RESID set. - * 4) No residual but target did not - * save data pointers after the - * last transfer, so sgptr was - * never updated. - * 5) We have a partial residual. - * Use residual_sgptr to determine - * where we are. - */ - - hscb = scb->hscb; - sgptr = ahd_le32toh(hscb->sgptr); - if ((sgptr & SG_STATUS_VALID) == 0) - /* Case 1 */ - return; - sgptr &= ~SG_STATUS_VALID; - - if ((sgptr & SG_LIST_NULL) != 0) - /* Case 2 */ - return; - - /* - * Residual fields are the same in both - * target and initiator status packets, - * so we can always use the initiator fields - * regardless of the role for this SCB. - */ - spkt = &hscb->shared_data.istatus; - resid_sgptr = ahd_le32toh(spkt->residual_sgptr); - if ((sgptr & SG_FULL_RESID) != 0) { - /* Case 3 */ - resid = ahd_get_transfer_length(scb); - } else if ((resid_sgptr & SG_LIST_NULL) != 0) { - /* Case 4 */ - return; - } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) { - ahd_print_path(ahd, scb); - printf("data overrun detected Tag == 0x%x.\n", - SCB_GET_TAG(scb)); - ahd_freeze_devq(ahd, scb); - ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); - ahd_freeze_scb(scb); - return; - } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) { - panic("Bogus resid sgptr value 0x%x\n", resid_sgptr); - /* NOTREACHED */ - } else { - struct ahd_dma_seg *sg; - - /* - * Remainder of the SG where the transfer - * stopped. - */ - resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK; - sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK); - - /* The residual sg_ptr always points to the next sg */ - sg--; - - /* - * Add up the contents of all residual - * SG segments that are after the SG where - * the transfer stopped. - */ - while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) { - sg++; - resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; - } - } - if ((scb->flags & SCB_SENSE) == 0) - ahd_set_residual(scb, resid); - else - ahd_set_sense_residual(scb, resid); - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) { - ahd_print_path(ahd, scb); - printf("Handled %sResidual of %d bytes\n", - (scb->flags & SCB_SENSE) ? "Sense " : "", resid); - } -#endif -} - -/******************************* Target Mode **********************************/ -#ifdef AHD_TARGET_MODE -/* - * Add a target mode event to this lun's queue - */ -static void -ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate, - u_int initiator_id, u_int event_type, u_int event_arg) -{ - struct ahd_tmode_event *event; - int pending; - - xpt_freeze_devq(lstate->path, /*count*/1); - if (lstate->event_w_idx >= lstate->event_r_idx) - pending = lstate->event_w_idx - lstate->event_r_idx; - else - pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1 - - (lstate->event_r_idx - lstate->event_w_idx); - - if (event_type == EVENT_TYPE_BUS_RESET - || event_type == MSG_BUS_DEV_RESET) { - /* - * Any earlier events are irrelevant, so reset our buffer. - * This has the effect of allowing us to deal with reset - * floods (an external device holding down the reset line) - * without losing the event that is really interesting. - */ - lstate->event_r_idx = 0; - lstate->event_w_idx = 0; - xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE); - } - - if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) { - xpt_print_path(lstate->path); - printf("immediate event %x:%x lost\n", - lstate->event_buffer[lstate->event_r_idx].event_type, - lstate->event_buffer[lstate->event_r_idx].event_arg); - lstate->event_r_idx++; - if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE) - lstate->event_r_idx = 0; - xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE); - } - - event = &lstate->event_buffer[lstate->event_w_idx]; - event->initiator_id = initiator_id; - event->event_type = event_type; - event->event_arg = event_arg; - lstate->event_w_idx++; - if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE) - lstate->event_w_idx = 0; -} - -/* - * Send any target mode events queued up waiting - * for immediate notify resources. - */ -void -ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate) -{ - struct ccb_hdr *ccbh; - struct ccb_immed_notify *inot; - - while (lstate->event_r_idx != lstate->event_w_idx - && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) { - struct ahd_tmode_event *event; - - event = &lstate->event_buffer[lstate->event_r_idx]; - SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle); - inot = (struct ccb_immed_notify *)ccbh; - switch (event->event_type) { - case EVENT_TYPE_BUS_RESET: - ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN; - break; - default: - ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN; - inot->message_args[0] = event->event_type; - inot->message_args[1] = event->event_arg; - break; - } - inot->initiator_id = event->initiator_id; - inot->sense_len = 0; - xpt_done((union ccb *)inot); - lstate->event_r_idx++; - if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE) - lstate->event_r_idx = 0; - } -} -#endif - -/******************** Sequencer Program Patching/Download *********************/ - -#ifdef AHD_DUMP_SEQ -void -ahd_dumpseq(struct ahd_softc* ahd) -{ - int i; - int max_prog; - - max_prog = 2048; - - ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); - ahd_outb(ahd, PRGMCNT, 0); - ahd_outb(ahd, PRGMCNT+1, 0); - for (i = 0; i < max_prog; i++) { - uint8_t ins_bytes[4]; - - ahd_insb(ahd, SEQRAM, ins_bytes, 4); - printf("0x%08x\n", ins_bytes[0] << 24 - | ins_bytes[1] << 16 - | ins_bytes[2] << 8 - | ins_bytes[3]); - } -} -#endif - -static void -ahd_loadseq(struct ahd_softc *ahd) -{ - struct cs cs_table[num_critical_sections]; - u_int begin_set[num_critical_sections]; - u_int end_set[num_critical_sections]; - struct patch *cur_patch; - u_int cs_count; - u_int cur_cs; - u_int i; - int downloaded; - u_int skip_addr; - u_int sg_prefetch_cnt; - u_int sg_prefetch_cnt_limit; - u_int sg_prefetch_align; - u_int sg_size; - uint8_t download_consts[DOWNLOAD_CONST_COUNT]; - - if (bootverbose) - printf("%s: Downloading Sequencer Program...", - ahd_name(ahd)); - -#if DOWNLOAD_CONST_COUNT != 7 -#error "Download Const Mismatch" -#endif - /* - * Start out with 0 critical sections - * that apply to this firmware load. - */ - cs_count = 0; - cur_cs = 0; - memset(begin_set, 0, sizeof(begin_set)); - memset(end_set, 0, sizeof(end_set)); - - /* - * Setup downloadable constant table. - * - * The computation for the S/G prefetch variables is - * a bit complicated. We would like to always fetch - * in terms of cachelined sized increments. However, - * if the cacheline is not an even multiple of the - * SG element size or is larger than our SG RAM, using - * just the cache size might leave us with only a portion - * of an SG element at the tail of a prefetch. If the - * cacheline is larger than our S/G prefetch buffer less - * the size of an SG element, we may round down to a cacheline - * that doesn't contain any or all of the S/G of interest - * within the bounds of our S/G ram. Provide variables to - * the sequencer that will allow it to handle these edge - * cases. - */ - /* Start by aligning to the nearest cacheline. */ - sg_prefetch_align = ahd->pci_cachesize; - if (sg_prefetch_align == 0) - sg_prefetch_cnt = 8; - /* Round down to the nearest power of 2. */ - while (powerof2(sg_prefetch_align) == 0) - sg_prefetch_align--; - /* - * If the cacheline boundary is greater than half our prefetch RAM - * we risk not being able to fetch even a single complete S/G - * segment if we align to that boundary. - */ - if (sg_prefetch_align > CCSGADDR_MAX/2) - sg_prefetch_align = CCSGADDR_MAX/2; - /* Start by fetching a single cacheline. */ - sg_prefetch_cnt = sg_prefetch_align; - /* - * Increment the prefetch count by cachelines until - * at least one S/G element will fit. - */ - sg_size = sizeof(struct ahd_dma_seg); - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) - sg_size = sizeof(struct ahd_dma64_seg); - while (sg_prefetch_cnt < sg_size) - sg_prefetch_cnt += sg_prefetch_align; - /* - * If the cacheline is not an even multiple of - * the S/G size, we may only get a partial S/G when - * we align. Add a cacheline if this is the case. - */ - if ((sg_prefetch_align % sg_size) != 0 - && (sg_prefetch_cnt < CCSGADDR_MAX)) - sg_prefetch_cnt += sg_prefetch_align; - /* - * Lastly, compute a value that the sequencer can use - * to determine if the remainder of the CCSGRAM buffer - * has a full S/G element in it. - */ - sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1); - download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt; - download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit; - download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1); - download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1); - download_consts[SG_SIZEOF] = sg_size; - download_consts[PKT_OVERRUN_BUFOFFSET] = - (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256; - download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN; - if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) - download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_FULL_LUN; - cur_patch = patches; - downloaded = 0; - skip_addr = 0; - ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); - ahd_outb(ahd, PRGMCNT, 0); - ahd_outb(ahd, PRGMCNT+1, 0); - - for (i = 0; i < sizeof(seqprog)/4; i++) { - if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) { - /* - * Don't download this instruction as it - * is in a patch that was removed. - */ - continue; - } - /* - * Move through the CS table until we find a CS - * that might apply to this instruction. - */ - for (; cur_cs < num_critical_sections; cur_cs++) { - if (critical_sections[cur_cs].end <= i) { - if (begin_set[cs_count] == TRUE - && end_set[cs_count] == FALSE) { - cs_table[cs_count].end = downloaded; - end_set[cs_count] = TRUE; - cs_count++; - } - continue; - } - if (critical_sections[cur_cs].begin <= i - && begin_set[cs_count] == FALSE) { - cs_table[cs_count].begin = downloaded; - begin_set[cs_count] = TRUE; - } - break; - } - ahd_download_instr(ahd, i, download_consts); - downloaded++; - } - - ahd->num_critical_sections = cs_count; - if (cs_count != 0) { - - cs_count *= sizeof(struct cs); - ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT); - if (ahd->critical_sections == NULL) - panic("ahd_loadseq: Could not malloc"); - memcpy(ahd->critical_sections, cs_table, cs_count); - } - ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE); - - if (bootverbose) { - printf(" %d instructions downloaded\n", downloaded); - printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n", - ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags); - } -} - -static int -ahd_check_patch(struct ahd_softc *ahd, struct patch **start_patch, - u_int start_instr, u_int *skip_addr) -{ - struct patch *cur_patch; - struct patch *last_patch; - u_int num_patches; - - num_patches = sizeof(patches)/sizeof(struct patch); - last_patch = &patches[num_patches]; - cur_patch = *start_patch; - - while (cur_patch < last_patch && start_instr == cur_patch->begin) { - - if (cur_patch->patch_func(ahd) == 0) { - - /* Start rejecting code */ - *skip_addr = start_instr + cur_patch->skip_instr; - cur_patch += cur_patch->skip_patch; - } else { - /* Accepted this patch. Advance to the next - * one and wait for our intruction pointer to - * hit this point. - */ - cur_patch++; - } - } - - *start_patch = cur_patch; - if (start_instr < *skip_addr) - /* Still skipping */ - return (0); - - return (1); -} - -static u_int -ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address) -{ - struct patch *cur_patch; - int address_offset; - u_int skip_addr; - u_int i; - - address_offset = 0; - cur_patch = patches; - skip_addr = 0; - - for (i = 0; i < address;) { - - ahd_check_patch(ahd, &cur_patch, i, &skip_addr); - - if (skip_addr > i) { - int end_addr; - - end_addr = MIN(address, skip_addr); - address_offset += end_addr - i; - i = skip_addr; - } else { - i++; - } - } - return (address - address_offset); -} - -static void -ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts) -{ - union ins_formats instr; - struct ins_format1 *fmt1_ins; - struct ins_format3 *fmt3_ins; - u_int opcode; - - /* - * The firmware is always compiled into a little endian format. - */ - instr.integer = ahd_le32toh(*(uint32_t*)&seqprog[instrptr * 4]); - - fmt1_ins = &instr.format1; - fmt3_ins = NULL; - - /* Pull the opcode */ - opcode = instr.format1.opcode; - switch (opcode) { - case AIC_OP_JMP: - case AIC_OP_JC: - case AIC_OP_JNC: - case AIC_OP_CALL: - case AIC_OP_JNE: - case AIC_OP_JNZ: - case AIC_OP_JE: - case AIC_OP_JZ: - { - fmt3_ins = &instr.format3; - fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address); - /* FALLTHROUGH */ - } - case AIC_OP_OR: - case AIC_OP_AND: - case AIC_OP_XOR: - case AIC_OP_ADD: - case AIC_OP_ADC: - case AIC_OP_BMOV: - if (fmt1_ins->parity != 0) { - fmt1_ins->immediate = dconsts[fmt1_ins->immediate]; - } - fmt1_ins->parity = 0; - /* FALLTHROUGH */ - case AIC_OP_ROL: - { - int i, count; - - /* Calculate odd parity for the instruction */ - for (i = 0, count = 0; i < 31; i++) { - uint32_t mask; - - mask = 0x01 << i; - if ((instr.integer & mask) != 0) - count++; - } - if ((count & 0x01) == 0) - instr.format1.parity = 1; - - /* The sequencer is a little endian cpu */ - instr.integer = ahd_htole32(instr.integer); - ahd_outsb(ahd, SEQRAM, instr.bytes, 4); - break; - } - default: - panic("Unknown opcode encountered in seq program"); - break; - } -} - -static int -ahd_probe_stack_size(struct ahd_softc *ahd) -{ - int last_probe; - - last_probe = 0; - while (1) { - int i; - - /* - * We avoid using 0 as a pattern to avoid - * confusion if the stack implementation - * "back-fills" with zeros when "poping' - * entries. - */ - for (i = 1; i <= last_probe+1; i++) { - ahd_outb(ahd, STACK, i & 0xFF); - ahd_outb(ahd, STACK, (i >> 8) & 0xFF); - } - - /* Verify */ - for (i = last_probe+1; i > 0; i--) { - u_int stack_entry; - - stack_entry = ahd_inb(ahd, STACK) - |(ahd_inb(ahd, STACK) << 8); - if (stack_entry != i) - goto sized; - } - last_probe++; - } -sized: - return (last_probe); -} - -void -ahd_dump_all_cards_state() -{ - struct ahd_softc *list_ahd; - - TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { - ahd_dump_card_state(list_ahd); - } -} - -int -ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries, - const char *name, u_int address, u_int value, - u_int *cur_column, u_int wrap_point) -{ - int printed; - u_int printed_mask; - - if (cur_column != NULL && *cur_column >= wrap_point) { - printf("\n"); - *cur_column = 0; - } - printed = printf("%s[0x%x]", name, value); - if (table == NULL) { - printed += printf(" "); - *cur_column += printed; - return (printed); - } - printed_mask = 0; - while (printed_mask != 0xFF) { - int entry; - - for (entry = 0; entry < num_entries; entry++) { - if (((value & table[entry].mask) - != table[entry].value) - || ((printed_mask & table[entry].mask) - == table[entry].mask)) - continue; - - printed += printf("%s%s", - printed_mask == 0 ? ":(" : "|", - table[entry].name); - printed_mask |= table[entry].mask; - - break; - } - if (entry >= num_entries) - break; - } - if (printed_mask != 0) - printed += printf(") "); - else - printed += printf(" "); - if (cur_column != NULL) - *cur_column += printed; - return (printed); -} - -void -ahd_dump_card_state(struct ahd_softc *ahd) -{ - struct scb *scb; - ahd_mode_state saved_modes; - u_int dffstat; - int paused; - u_int scb_index; - u_int saved_scb_index; - u_int cur_col; - int i; - - if (ahd_is_paused(ahd)) { - paused = 1; - } else { - paused = 0; - ahd_pause(ahd); - } - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" - "%s: Dumping Card State at program address 0x%x Mode 0x%x\n", - ahd_name(ahd), - ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8), - ahd_build_mode_state(ahd, ahd->saved_src_mode, - ahd->saved_dst_mode)); - if (paused) - printf("Card was paused\n"); - /* - * Mode independent registers. - */ - cur_col = 0; - ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50); - ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50); - ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50); - ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50); - ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50); - ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50); - ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50); - ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50); - ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50); - ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50); - ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50); - ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50); - ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50); - ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50); - ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50); - ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50); - ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50); - ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50); - ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50); - ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50); - ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50); - ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50); - ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50); - ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50); - ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50); - ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50); - ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50); - printf("\n"); - printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x " - "CURRSCB 0x%x NEXTSCB 0x%x\n", - ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING), - ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB), - ahd_inw(ahd, NEXTSCB)); - cur_col = 0; - /* QINFIFO */ - ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, - CAM_LUN_WILDCARD, SCB_LIST_NULL, - ROLE_UNKNOWN, /*status*/0, SEARCH_PRINT); - saved_scb_index = ahd_get_scbptr(ahd); - printf("Pending list:"); - i = 0; - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { - if (i++ > AHD_SCB_MAX) - break; - cur_col = printf("\n%3d ", SCB_GET_TAG(scb)); - ahd_set_scbptr(ahd, SCB_GET_TAG(scb)); - ahd_scb_control_print(ahd_inb(ahd, SCB_CONTROL), &cur_col, 60); - ahd_scb_scsiid_print(ahd_inb(ahd, SCB_SCSIID), &cur_col, 60); - ahd_scb_tag_print(ahd_inb(ahd, SCB_TAG), &cur_col, 60); - } - printf("\nTotal %d\n", i); - - printf("Kernel Free SCB list: "); - i = 0; - TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { - struct scb *list_scb; - - list_scb = scb; - do { - printf("%d ", SCB_GET_TAG(list_scb)); - list_scb = LIST_NEXT(list_scb, collision_links); - } while (list_scb && i++ < AHD_SCB_MAX); - } - - LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { - if (i++ > AHD_SCB_MAX) - break; - printf("%d ", SCB_GET_TAG(scb)); - } - printf("\n"); - - printf("Sequencer Complete DMA-inprog list: "); - scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD); - i = 0; - while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { - ahd_set_scbptr(ahd, scb_index); - printf("%d ", scb_index); - scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); - } - printf("\n"); - - printf("Sequencer Complete list: "); - scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD); - i = 0; - while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { - ahd_set_scbptr(ahd, scb_index); - printf("%d ", scb_index); - scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); - } - printf("\n"); - - - printf("Sequencer DMA-Up and Complete list: "); - scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); - i = 0; - while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { - ahd_set_scbptr(ahd, scb_index); - printf("%d ", scb_index); - scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); - } - printf("\n"); - ahd_set_scbptr(ahd, saved_scb_index); - dffstat = ahd_inb(ahd, DFFSTAT); - for (i = 0; i < 2; i++) { -#ifdef AHD_DEBUG - struct scb *fifo_scb; -#endif - u_int fifo_scbptr; - - ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); - fifo_scbptr = ahd_get_scbptr(ahd); - printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, " - "SCB 0x%x, LJSCB 0x%x\n", - ahd_name(ahd), i, - (dffstat & (FIFO0FREE << i)) ? "Free" : "Active", - ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr, - ahd_inw(ahd, LONGJMP_SCB)); - cur_col = 0; - ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50); - ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50); - ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50); - ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50); - ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW), - &cur_col, 50); - ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50); - ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50); - ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50); - ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50); - if (cur_col > 50) { - printf("\n"); - cur_col = 0; - } - cur_col += printf("SHADDR = 0x%x%x, SHCNT = 0x%x ", - ahd_inl(ahd, SHADDR+4), - ahd_inl(ahd, SHADDR), - (ahd_inb(ahd, SHCNT) - | (ahd_inb(ahd, SHCNT + 1) << 8) - | (ahd_inb(ahd, SHCNT + 2) << 16))); - if (cur_col > 50) { - printf("\n"); - cur_col = 0; - } - cur_col += printf("HADDR = 0x%x%x, HCNT = 0x%x ", - ahd_inl(ahd, HADDR+4), - ahd_inl(ahd, HADDR), - (ahd_inb(ahd, HCNT) - | (ahd_inb(ahd, HCNT + 1) << 8) - | (ahd_inb(ahd, HCNT + 2) << 16))); - ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_SG) != 0) { - fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr); - if (fifo_scb != NULL) - ahd_dump_sglist(fifo_scb); - } -#endif - } - printf("\nLQIN: "); - for (i = 0; i < 20; i++) - printf("0x%x ", ahd_inb(ahd, LQIN + i)); - printf("\n"); - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n", - ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE), - ahd_inb(ahd, OPTIONMODE)); - printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n", - ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT), - ahd_inb(ahd, MAXCMDCNT)); - ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50); - printf("\n"); - ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); - cur_col = 0; - ahd_ccscbctl_print(ahd_inb(ahd, CCSCBCTL), &cur_col, 50); - printf("\n"); - ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); - printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n", - ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX), - ahd_inw(ahd, DINDEX)); - printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n", - ahd_name(ahd), ahd_get_scbptr(ahd), ahd_inw(ahd, SCB_NEXT), - ahd_inw(ahd, SCB_NEXT2)); - printf("CDB %x %x %x %x %x %x\n", - ahd_inb(ahd, SCB_CDB_STORE), - ahd_inb(ahd, SCB_CDB_STORE+1), - ahd_inb(ahd, SCB_CDB_STORE+2), - ahd_inb(ahd, SCB_CDB_STORE+3), - ahd_inb(ahd, SCB_CDB_STORE+4), - ahd_inb(ahd, SCB_CDB_STORE+5)); - printf("STACK:"); - for (i = 0; i < ahd->stack_size; i++) { - ahd->saved_stack[i] = - ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8); - printf(" 0x%x", ahd->saved_stack[i]); - } - for (i = ahd->stack_size-1; i >= 0; i--) { - ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF); - ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF); - } - printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); - ahd_platform_dump_card_state(ahd); - ahd_restore_modes(ahd, saved_modes); - if (paused == 0) - ahd_unpause(ahd); -} - -void -ahd_dump_scbs(struct ahd_softc *ahd) -{ - ahd_mode_state saved_modes; - u_int saved_scb_index; - int i; - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - saved_scb_index = ahd_get_scbptr(ahd); - for (i = 0; i < AHD_SCB_MAX; i++) { - ahd_set_scbptr(ahd, i); - printf("%3d", i); - printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n", - ahd_inb(ahd, SCB_CONTROL), - ahd_inb(ahd, SCB_SCSIID), ahd_inw(ahd, SCB_NEXT), - ahd_inw(ahd, SCB_NEXT2), ahd_inl(ahd, SCB_SGPTR), - ahd_inl(ahd, SCB_RESIDUAL_SGPTR)); - } - printf("\n"); - ahd_set_scbptr(ahd, saved_scb_index); - ahd_restore_modes(ahd, saved_modes); -} - -/**************************** Flexport Logic **********************************/ -/* - * Read count 16bit words from 16bit word address start_addr from the - * SEEPROM attached to the controller, into buf, using the controller's - * SEEPROM reading state machine. - */ -int -ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, - u_int start_addr, u_int count) -{ - u_int cur_addr; - u_int end_addr; - int error; - - /* - * If we never make it through the loop even once, - * we were passed invalid arguments. - */ - error = EINVAL; - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - end_addr = start_addr + count; - for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) { - ahd_outb(ahd, SEEADR, cur_addr); - ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART); - - error = ahd_wait_seeprom(ahd); - if (error) - break; - *buf++ = ahd_inw(ahd, SEEDAT); - } - return (error); -} - -/* - * Write count 16bit words from buf, into SEEPROM attache to the - * controller starting at 16bit word address start_addr, using the - * controller's SEEPROM writing state machine. - */ -int -ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, - u_int start_addr, u_int count) -{ - u_int cur_addr; - u_int end_addr; - int error; - int retval; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - error = ENOENT; - - /* Place the chip into write-enable mode */ - ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR); - ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART); - error = ahd_wait_seeprom(ahd); - if (error) - return (error); - - /* - * Write the data. If we don't get throught the loop at - * least once, the arguments were invalid. - */ - retval = EINVAL; - end_addr = start_addr + count; - for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) { - ahd_outw(ahd, SEEDAT, *buf++); - ahd_outb(ahd, SEEADR, cur_addr); - ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART); - - retval = ahd_wait_seeprom(ahd); - if (retval) - break; - } - - /* - * Disable writes. - */ - ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR); - ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART); - error = ahd_wait_seeprom(ahd); - if (error) - return (error); - return (retval); -} - -/* - * Wait ~100us for the serial eeprom to satisfy our request. - */ -int -ahd_wait_seeprom(struct ahd_softc *ahd) -{ - int cnt; - - cnt = 20; - while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt) - ahd_delay(5); - - if (cnt == 0) - return (ETIMEDOUT); - return (0); -} - -int -ahd_verify_cksum(struct seeprom_config *sc) -{ - int i; - int maxaddr; - uint32_t checksum; - uint16_t *scarray; - - maxaddr = (sizeof(*sc)/2) - 1; - checksum = 0; - scarray = (uint16_t *)sc; - - for (i = 0; i < maxaddr; i++) - checksum = checksum + scarray[i]; - if (checksum == 0 - || (checksum & 0xFFFF) != sc->checksum) { - return (0); - } else { - return (1); - } -} - -int -ahd_acquire_seeprom(struct ahd_softc *ahd) -{ - /* - * We should be able to determine the SEEPROM type - * from the flexport logic, but unfortunately not - * all implementations have this logic and there is - * no programatic method for determining if the logic - * is present. - */ - return (1); -#if 0 - uint8_t seetype; - int error; - - error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype); - if (error != 0 - || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE)) - return (0); - return (1); -#endif -} - -void -ahd_release_seeprom(struct ahd_softc *ahd) -{ - /* Currently a no-op */ -} - -int -ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value) -{ - int error; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - if (addr > 7) - panic("ahd_write_flexport: address out of range"); - ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3)); - error = ahd_wait_flexport(ahd); - if (error != 0) - return (error); - ahd_outb(ahd, BRDDAT, value); - ahd_flush_device_writes(ahd); - ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3)); - ahd_flush_device_writes(ahd); - ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3)); - ahd_flush_device_writes(ahd); - ahd_outb(ahd, BRDCTL, 0); - ahd_flush_device_writes(ahd); - return (0); -} - -int -ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value) -{ - int error; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - if (addr > 7) - panic("ahd_read_flexport: address out of range"); - ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3)); - error = ahd_wait_flexport(ahd); - if (error != 0) - return (error); - *value = ahd_inb(ahd, BRDDAT); - ahd_outb(ahd, BRDCTL, 0); - ahd_flush_device_writes(ahd); - return (0); -} - -/* - * Wait at most 2 seconds for flexport arbitration to succeed. - */ -int -ahd_wait_flexport(struct ahd_softc *ahd) -{ - int cnt; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - cnt = 1000000 * 2 / 5; - while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) - ahd_delay(5); - - if (cnt == 0) - return (ETIMEDOUT); - return (0); -} - -/************************* Target Mode ****************************************/ -#ifdef AHD_TARGET_MODE -cam_status -ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb, - struct ahd_tmode_tstate **tstate, - struct ahd_tmode_lstate **lstate, - int notfound_failure) -{ - - if ((ahd->features & AHD_TARGETMODE) == 0) - return (CAM_REQ_INVALID); - - /* - * Handle the 'black hole' device that sucks up - * requests to unattached luns on enabled targets. - */ - if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD - && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) { - *tstate = NULL; - *lstate = ahd->black_hole; - } else { - u_int max_id; - - max_id = (ahd->features & AHD_WIDE) ? 15 : 7; - if (ccb->ccb_h.target_id > max_id) - return (CAM_TID_INVALID); - - if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS) - return (CAM_LUN_INVALID); - - *tstate = ahd->enabled_targets[ccb->ccb_h.target_id]; - *lstate = NULL; - if (*tstate != NULL) - *lstate = - (*tstate)->enabled_luns[ccb->ccb_h.target_lun]; - } - - if (notfound_failure != 0 && *lstate == NULL) - return (CAM_PATH_INVALID); - - return (CAM_REQ_CMP); -} - -void -ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) -{ -#if NOT_YET - struct ahd_tmode_tstate *tstate; - struct ahd_tmode_lstate *lstate; - struct ccb_en_lun *cel; - cam_status status; - u_int target; - u_int lun; - u_int target_mask; - u_long s; - char channel; - - status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate, - /*notfound_failure*/FALSE); - - if (status != CAM_REQ_CMP) { - ccb->ccb_h.status = status; - return; - } - - if ((ahd->features & AHD_MULTIROLE) != 0) { - u_int our_id; - - our_id = ahd->our_id; - if (ccb->ccb_h.target_id != our_id) { - if ((ahd->features & AHD_MULTI_TID) != 0 - && (ahd->flags & AHD_INITIATORROLE) != 0) { - /* - * Only allow additional targets if - * the initiator role is disabled. - * The hardware cannot handle a re-select-in - * on the initiator id during a re-select-out - * on a different target id. - */ - status = CAM_TID_INVALID; - } else if ((ahd->flags & AHD_INITIATORROLE) != 0 - || ahd->enabled_luns > 0) { - /* - * Only allow our target id to change - * if the initiator role is not configured - * and there are no enabled luns which - * are attached to the currently registered - * scsi id. - */ - status = CAM_TID_INVALID; - } - } - } - - if (status != CAM_REQ_CMP) { - ccb->ccb_h.status = status; - return; - } - - /* - * We now have an id that is valid. - * If we aren't in target mode, switch modes. - */ - if ((ahd->flags & AHD_TARGETROLE) == 0 - && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { - u_long s; - - printf("Configuring Target Mode\n"); - ahd_lock(ahd, &s); - if (LIST_FIRST(&ahd->pending_scbs) != NULL) { - ccb->ccb_h.status = CAM_BUSY; - ahd_unlock(ahd, &s); - return; - } - ahd->flags |= AHD_TARGETROLE; - if ((ahd->features & AHD_MULTIROLE) == 0) - ahd->flags &= ~AHD_INITIATORROLE; - ahd_pause(ahd); - ahd_loadseq(ahd); - ahd_unlock(ahd, &s); - } - cel = &ccb->cel; - target = ccb->ccb_h.target_id; - lun = ccb->ccb_h.target_lun; - channel = SIM_CHANNEL(ahd, sim); - target_mask = 0x01 << target; - if (channel == 'B') - target_mask <<= 8; - - if (cel->enable != 0) { - u_int scsiseq1; - - /* Are we already enabled?? */ - if (lstate != NULL) { - xpt_print_path(ccb->ccb_h.path); - printf("Lun already enabled\n"); - ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; - return; - } - - if (cel->grp6_len != 0 - || cel->grp7_len != 0) { - /* - * Don't (yet?) support vendor - * specific commands. - */ - ccb->ccb_h.status = CAM_REQ_INVALID; - printf("Non-zero Group Codes\n"); - return; - } - - /* - * Seems to be okay. - * Setup our data structures. - */ - if (target != CAM_TARGET_WILDCARD && tstate == NULL) { - tstate = ahd_alloc_tstate(ahd, target, channel); - if (tstate == NULL) { - xpt_print_path(ccb->ccb_h.path); - printf("Couldn't allocate tstate\n"); - ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - return; - } - } - lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT); - if (lstate == NULL) { - xpt_print_path(ccb->ccb_h.path); - printf("Couldn't allocate lstate\n"); - ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - return; - } - memset(lstate, 0, sizeof(*lstate)); - status = xpt_create_path(&lstate->path, /*periph*/NULL, - xpt_path_path_id(ccb->ccb_h.path), - xpt_path_target_id(ccb->ccb_h.path), - xpt_path_lun_id(ccb->ccb_h.path)); - if (status != CAM_REQ_CMP) { - free(lstate, M_DEVBUF); - xpt_print_path(ccb->ccb_h.path); - printf("Couldn't allocate path\n"); - ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - return; - } - SLIST_INIT(&lstate->accept_tios); - SLIST_INIT(&lstate->immed_notifies); - ahd_lock(ahd, &s); - ahd_pause(ahd); - if (target != CAM_TARGET_WILDCARD) { - tstate->enabled_luns[lun] = lstate; - ahd->enabled_luns++; - - if ((ahd->features & AHD_MULTI_TID) != 0) { - u_int targid_mask; - - targid_mask = ahd_inb(ahd, TARGID) - | (ahd_inb(ahd, TARGID + 1) << 8); - - targid_mask |= target_mask; - ahd_outb(ahd, TARGID, targid_mask); - ahd_outb(ahd, TARGID+1, (targid_mask >> 8)); - - ahd_update_scsiid(ahd, targid_mask); - } else { - u_int our_id; - char channel; - - channel = SIM_CHANNEL(ahd, sim); - our_id = SIM_SCSI_ID(ahd, sim); - - /* - * This can only happen if selections - * are not enabled - */ - if (target != our_id) { - u_int sblkctl; - char cur_channel; - int swap; - - sblkctl = ahd_inb(ahd, SBLKCTL); - cur_channel = (sblkctl & SELBUSB) - ? 'B' : 'A'; - if ((ahd->features & AHD_TWIN) == 0) - cur_channel = 'A'; - swap = cur_channel != channel; - ahd->our_id = target; - - if (swap) - ahd_outb(ahd, SBLKCTL, - sblkctl ^ SELBUSB); - - ahd_outb(ahd, SCSIID, target); - - if (swap) - ahd_outb(ahd, SBLKCTL, sblkctl); - } - } - } else - ahd->black_hole = lstate; - /* Allow select-in operations */ - if (ahd->black_hole != NULL && ahd->enabled_luns > 0) { - scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); - scsiseq1 |= ENSELI; - ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1); - scsiseq1 = ahd_inb(ahd, SCSISEQ1); - scsiseq1 |= ENSELI; - ahd_outb(ahd, SCSISEQ1, scsiseq1); - } - ahd_unpause(ahd); - ahd_unlock(ahd, &s); - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_print_path(ccb->ccb_h.path); - printf("Lun now enabled for target mode\n"); - } else { - struct scb *scb; - int i, empty; - - if (lstate == NULL) { - ccb->ccb_h.status = CAM_LUN_INVALID; - return; - } - - ahd_lock(ahd, &s); - - ccb->ccb_h.status = CAM_REQ_CMP; - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { - struct ccb_hdr *ccbh; - - ccbh = &scb->io_ctx->ccb_h; - if (ccbh->func_code == XPT_CONT_TARGET_IO - && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){ - printf("CTIO pending\n"); - ccb->ccb_h.status = CAM_REQ_INVALID; - ahd_unlock(ahd, &s); - return; - } - } - - if (SLIST_FIRST(&lstate->accept_tios) != NULL) { - printf("ATIOs pending\n"); - ccb->ccb_h.status = CAM_REQ_INVALID; - } - - if (SLIST_FIRST(&lstate->immed_notifies) != NULL) { - printf("INOTs pending\n"); - ccb->ccb_h.status = CAM_REQ_INVALID; - } - - if (ccb->ccb_h.status != CAM_REQ_CMP) { - ahd_unlock(ahd, &s); - return; - } - - xpt_print_path(ccb->ccb_h.path); - printf("Target mode disabled\n"); - xpt_free_path(lstate->path); - free(lstate, M_DEVBUF); - - ahd_pause(ahd); - /* Can we clean up the target too? */ - if (target != CAM_TARGET_WILDCARD) { - tstate->enabled_luns[lun] = NULL; - ahd->enabled_luns--; - for (empty = 1, i = 0; i < 8; i++) - if (tstate->enabled_luns[i] != NULL) { - empty = 0; - break; - } - - if (empty) { - ahd_free_tstate(ahd, target, channel, - /*force*/FALSE); - if (ahd->features & AHD_MULTI_TID) { - u_int targid_mask; - - targid_mask = ahd_inb(ahd, TARGID) - | (ahd_inb(ahd, TARGID + 1) - << 8); - - targid_mask &= ~target_mask; - ahd_outb(ahd, TARGID, targid_mask); - ahd_outb(ahd, TARGID+1, - (targid_mask >> 8)); - ahd_update_scsiid(ahd, targid_mask); - } - } - } else { - - ahd->black_hole = NULL; - - /* - * We can't allow selections without - * our black hole device. - */ - empty = TRUE; - } - if (ahd->enabled_luns == 0) { - /* Disallow select-in */ - u_int scsiseq1; - - scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); - scsiseq1 &= ~ENSELI; - ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1); - scsiseq1 = ahd_inb(ahd, SCSISEQ1); - scsiseq1 &= ~ENSELI; - ahd_outb(ahd, SCSISEQ1, scsiseq1); - - if ((ahd->features & AHD_MULTIROLE) == 0) { - printf("Configuring Initiator Mode\n"); - ahd->flags &= ~AHD_TARGETROLE; - ahd->flags |= AHD_INITIATORROLE; - ahd_pause(ahd); - ahd_loadseq(ahd); - } - } - ahd_unpause(ahd); - ahd_unlock(ahd, &s); - } -#endif -} - -static void -ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask) -{ -#if NOT_YET - u_int scsiid_mask; - u_int scsiid; - - if ((ahd->features & AHD_MULTI_TID) == 0) - panic("ahd_update_scsiid called on non-multitid unit\n"); - - /* - * Since we will rely on the TARGID mask - * for selection enables, ensure that OID - * in SCSIID is not set to some other ID - * that we don't want to allow selections on. - */ - if ((ahd->features & AHD_ULTRA2) != 0) - scsiid = ahd_inb(ahd, SCSIID_ULTRA2); - else - scsiid = ahd_inb(ahd, SCSIID); - scsiid_mask = 0x1 << (scsiid & OID); - if ((targid_mask & scsiid_mask) == 0) { - u_int our_id; - - /* ffs counts from 1 */ - our_id = ffs(targid_mask); - if (our_id == 0) - our_id = ahd->our_id; - else - our_id--; - scsiid &= TID; - scsiid |= our_id; - } - if ((ahd->features & AHD_ULTRA2) != 0) - ahd_outb(ahd, SCSIID_ULTRA2, scsiid); - else - ahd_outb(ahd, SCSIID, scsiid); -#endif -} - -void -ahd_run_tqinfifo(struct ahd_softc *ahd, int paused) -{ - struct target_cmd *cmd; - - ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD); - while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) { - - /* - * Only advance through the queue if we - * have the resources to process the command. - */ - if (ahd_handle_target_cmd(ahd, cmd) != 0) - break; - - cmd->cmd_valid = 0; - ahd_dmamap_sync(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap, - ahd_targetcmd_offset(ahd, ahd->tqinfifonext), - sizeof(struct target_cmd), - BUS_DMASYNC_PREREAD); - ahd->tqinfifonext++; - - /* - * Lazily update our position in the target mode incoming - * command queue as seen by the sequencer. - */ - if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) { - u_int hs_mailbox; - - hs_mailbox = ahd_inb(ahd, HS_MAILBOX); - hs_mailbox &= ~HOST_TQINPOS; - hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS; - ahd_outb(ahd, HS_MAILBOX, hs_mailbox); - } - } -} - -static int -ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd) -{ - struct ahd_tmode_tstate *tstate; - struct ahd_tmode_lstate *lstate; - struct ccb_accept_tio *atio; - uint8_t *byte; - int initiator; - int target; - int lun; - - initiator = SCSIID_TARGET(ahd, cmd->scsiid); - target = SCSIID_OUR_ID(cmd->scsiid); - lun = (cmd->identify & MSG_IDENTIFY_LUNMASK); - - byte = cmd->bytes; - tstate = ahd->enabled_targets[target]; - lstate = NULL; - if (tstate != NULL) - lstate = tstate->enabled_luns[lun]; - - /* - * Commands for disabled luns go to the black hole driver. - */ - if (lstate == NULL) - lstate = ahd->black_hole; - - atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios); - if (atio == NULL) { - ahd->flags |= AHD_TQINFIFO_BLOCKED; - /* - * Wait for more ATIOs from the peripheral driver for this lun. - */ - return (1); - } else - ahd->flags &= ~AHD_TQINFIFO_BLOCKED; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_TQIN) != 0) - printf("Incoming command from %d for %d:%d%s\n", - initiator, target, lun, - lstate == ahd->black_hole ? "(Black Holed)" : ""); -#endif - SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle); - - if (lstate == ahd->black_hole) { - /* Fill in the wildcards */ - atio->ccb_h.target_id = target; - atio->ccb_h.target_lun = lun; - } - - /* - * Package it up and send it off to - * whomever has this lun enabled. - */ - atio->sense_len = 0; - atio->init_id = initiator; - if (byte[0] != 0xFF) { - /* Tag was included */ - atio->tag_action = *byte++; - atio->tag_id = *byte++; - atio->ccb_h.flags = CAM_TAG_ACTION_VALID; - } else { - atio->ccb_h.flags = 0; - } - byte++; - - /* Okay. Now determine the cdb size based on the command code */ - switch (*byte >> CMD_GROUP_CODE_SHIFT) { - case 0: - atio->cdb_len = 6; - break; - case 1: - case 2: - atio->cdb_len = 10; - break; - case 4: - atio->cdb_len = 16; - break; - case 5: - atio->cdb_len = 12; - break; - case 3: - default: - /* Only copy the opcode. */ - atio->cdb_len = 1; - printf("Reserved or VU command code type encountered\n"); - break; - } - - memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len); - - atio->ccb_h.status |= CAM_CDB_RECVD; - - if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) { - /* - * We weren't allowed to disconnect. - * We're hanging on the bus until a - * continue target I/O comes in response - * to this accept tio. - */ -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_TQIN) != 0) - printf("Received Immediate Command %d:%d:%d - %p\n", - initiator, target, lun, ahd->pending_device); -#endif - ahd->pending_device = lstate; - ahd_freeze_ccb((union ccb *)atio); - atio->ccb_h.flags |= CAM_DIS_DISCONNECT; - } - xpt_done((union ccb*)atio); - return (0); -} - -#endif diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_inline.h linux-2.4.22/drivers/scsi/aic79xx/aic79xx_inline.h --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_inline.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_inline.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,950 +0,0 @@ -/* - * Inline routines shareable across OS platforms. - * - * Copyright (c) 1994-2001 Justin T. Gibbs. - * Copyright (c) 2000-2003 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#41 $ - * - * $FreeBSD$ - */ - -#ifndef _AIC79XX_INLINE_H_ -#define _AIC79XX_INLINE_H_ - -/******************************** Debugging ***********************************/ -static __inline char *ahd_name(struct ahd_softc *ahd); - -static __inline char * -ahd_name(struct ahd_softc *ahd) -{ - return (ahd->name); -} - -/************************ Sequencer Execution Control *************************/ -static __inline void ahd_known_modes(struct ahd_softc *ahd, - ahd_mode src, ahd_mode dst); -static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd, - ahd_mode src, - ahd_mode dst); -static __inline void ahd_extract_mode_state(struct ahd_softc *ahd, - ahd_mode_state state, - ahd_mode *src, ahd_mode *dst); -static __inline void ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, - ahd_mode dst); -static __inline void ahd_update_modes(struct ahd_softc *ahd); -static __inline void ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, - ahd_mode dstmode, const char *file, - int line); -static __inline ahd_mode_state ahd_save_modes(struct ahd_softc *ahd); -static __inline void ahd_restore_modes(struct ahd_softc *ahd, - ahd_mode_state state); -static __inline int ahd_is_paused(struct ahd_softc *ahd); -static __inline void ahd_pause(struct ahd_softc *ahd); -static __inline void ahd_unpause(struct ahd_softc *ahd); - -static __inline void -ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) -{ - ahd->src_mode = src; - ahd->dst_mode = dst; - ahd->saved_src_mode = src; - ahd->saved_dst_mode = dst; -} - -static __inline ahd_mode_state -ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) -{ - return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT)); -} - -static __inline void -ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state, - ahd_mode *src, ahd_mode *dst) -{ - *src = (state & SRC_MODE) >> SRC_MODE_SHIFT; - *dst = (state & DST_MODE) >> DST_MODE_SHIFT; -} - -static __inline void -ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) -{ - if (ahd->src_mode == src && ahd->dst_mode == dst) - return; -#ifdef AHD_DEBUG - if (ahd->src_mode == AHD_MODE_UNKNOWN - || ahd->dst_mode == AHD_MODE_UNKNOWN) - panic("Setting mode prior to saving it.\n"); - if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) - printf("%s: Setting mode 0x%x\n", ahd_name(ahd), - ahd_build_mode_state(ahd, src, dst)); -#endif - ahd_outb(ahd, MODE_PTR, ahd_build_mode_state(ahd, src, dst)); - ahd->src_mode = src; - ahd->dst_mode = dst; -} - -static __inline void -ahd_update_modes(struct ahd_softc *ahd) -{ - ahd_mode_state mode_ptr; - ahd_mode src; - ahd_mode dst; - - mode_ptr = ahd_inb(ahd, MODE_PTR); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) - printf("Reading mode 0x%x\n", mode_ptr); -#endif - ahd_extract_mode_state(ahd, mode_ptr, &src, &dst); - ahd_known_modes(ahd, src, dst); -} - -static __inline void -ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, - ahd_mode dstmode, const char *file, int line) -{ -#ifdef AHD_DEBUG - if ((srcmode & AHD_MK_MSK(ahd->src_mode)) == 0 - || (dstmode & AHD_MK_MSK(ahd->dst_mode)) == 0) { - panic("%s:%s:%d: Mode assertion failed.\n", - ahd_name(ahd), file, line); - } -#endif -} - -static __inline ahd_mode_state -ahd_save_modes(struct ahd_softc *ahd) -{ - if (ahd->src_mode == AHD_MODE_UNKNOWN - || ahd->dst_mode == AHD_MODE_UNKNOWN) - ahd_update_modes(ahd); - - return (ahd_build_mode_state(ahd, ahd->src_mode, ahd->dst_mode)); -} - -static __inline void -ahd_restore_modes(struct ahd_softc *ahd, ahd_mode_state state) -{ - ahd_mode src; - ahd_mode dst; - - ahd_extract_mode_state(ahd, state, &src, &dst); - ahd_set_modes(ahd, src, dst); -} - -#define AHD_ASSERT_MODES(ahd, source, dest) \ - ahd_assert_modes(ahd, source, dest, __FILE__, __LINE__); - -/* - * Determine whether the sequencer has halted code execution. - * Returns non-zero status if the sequencer is stopped. - */ -static __inline int -ahd_is_paused(struct ahd_softc *ahd) -{ - return ((ahd_inb(ahd, HCNTRL) & PAUSE) != 0); -} - -/* - * Request that the sequencer stop and wait, indefinitely, for it - * to stop. The sequencer will only acknowledge that it is paused - * once it has reached an instruction boundary and PAUSEDIS is - * cleared in the SEQCTL register. The sequencer may use PAUSEDIS - * for critical sections. - */ -static __inline void -ahd_pause(struct ahd_softc *ahd) -{ - ahd_outb(ahd, HCNTRL, ahd->pause); - - /* - * Since the sequencer can disable pausing in a critical section, we - * must loop until it actually stops. - */ - while (ahd_is_paused(ahd) == 0) - ; -} - -/* - * Allow the sequencer to continue program execution. - * We check here to ensure that no additional interrupt - * sources that would cause the sequencer to halt have been - * asserted. If, for example, a SCSI bus reset is detected - * while we are fielding a different, pausing, interrupt type, - * we don't want to release the sequencer before going back - * into our interrupt handler and dealing with this new - * condition. - */ -static __inline void -ahd_unpause(struct ahd_softc *ahd) -{ - /* - * Automatically restore our modes to those saved - * prior to the first change of the mode. - */ - if (ahd->saved_src_mode != AHD_MODE_UNKNOWN - && ahd->saved_dst_mode != AHD_MODE_UNKNOWN) { - if ((ahd->flags & AHD_UPDATE_PEND_CMDS) != 0) - ahd_reset_cmds_pending(ahd); - ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); - } - - if ((ahd_inb(ahd, INTSTAT) & ~(SWTMINT | CMDCMPLT)) == 0) - ahd_outb(ahd, HCNTRL, ahd->unpause); - - ahd_known_modes(ahd, AHD_MODE_UNKNOWN, AHD_MODE_UNKNOWN); -} - -/*********************** Scatter Gather List Handling *************************/ -static __inline void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, - void *sgptr, bus_addr_t addr, - bus_size_t len, int last); -static __inline void ahd_setup_scb_common(struct ahd_softc *ahd, - struct scb *scb); -static __inline void ahd_setup_data_scb(struct ahd_softc *ahd, - struct scb *scb); -static __inline void ahd_setup_noxfer_scb(struct ahd_softc *ahd, - struct scb *scb); - -static __inline void * -ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, - void *sgptr, bus_addr_t addr, bus_size_t len, int last) -{ - scb->sg_count++; - if (sizeof(bus_addr_t) > 4 - && (ahd->flags & AHD_64BIT_ADDRESSING) != 0) { - struct ahd_dma64_seg *sg; - - sg = (struct ahd_dma64_seg *)sgptr; - sg->addr = ahd_htole64(addr); - sg->len = ahd_htole32(len | (last ? AHD_DMA_LAST_SEG : 0)); - return (sg + 1); - } else { - struct ahd_dma_seg *sg; - - sg = (struct ahd_dma_seg *)sgptr; - sg->addr = ahd_htole32(addr & 0xFFFFFFFF); - sg->len = ahd_htole32(len | ((addr >> 8) & 0x7F000000) - | (last ? AHD_DMA_LAST_SEG : 0)); - return (sg + 1); - } -} - -static __inline void -ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb) -{ - /* XXX Handle target mode SCBs. */ - scb->crc_retry_count = 0; - if ((scb->flags & SCB_PACKETIZED) != 0) { - /* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */ - scb->hscb->task_attribute= scb->hscb->control & SCB_TAG_TYPE; - /* - * For Rev A short lun workaround. - */ - scb->hscb->pkt_long_lun[6] = scb->hscb->lun; - } - - if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR - || (scb->hscb->cdb_len & SCB_CDB_LEN_PTR) != 0) - scb->hscb->shared_data.idata.cdb_plus_saddr.sense_addr = - ahd_htole32(scb->sense_busaddr); -} - -static __inline void -ahd_setup_data_scb(struct ahd_softc *ahd, struct scb *scb) -{ - /* - * Copy the first SG into the "current" data ponter area. - */ - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { - struct ahd_dma64_seg *sg; - - sg = (struct ahd_dma64_seg *)scb->sg_list; - scb->hscb->dataptr = sg->addr; - scb->hscb->datacnt = sg->len; - } else { - struct ahd_dma_seg *sg; - - sg = (struct ahd_dma_seg *)scb->sg_list; - scb->hscb->dataptr = sg->addr; - if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { - uint64_t high_addr; - - high_addr = ahd_le32toh(sg->len) & 0x7F000000; - scb->hscb->dataptr |= ahd_htole64(high_addr << 8); - } - scb->hscb->datacnt = sg->len; - } - /* - * Note where to find the SG entries in bus space. - * We also set the full residual flag which the - * sequencer will clear as soon as a data transfer - * occurs. - */ - scb->hscb->sgptr = ahd_htole32(scb->sg_list_busaddr|SG_FULL_RESID); -} - -static __inline void -ahd_setup_noxfer_scb(struct ahd_softc *ahd, struct scb *scb) -{ - scb->hscb->sgptr = ahd_htole32(SG_LIST_NULL); - scb->hscb->dataptr = 0; - scb->hscb->datacnt = 0; -} - -/************************** Memory mapping routines ***************************/ -static __inline size_t ahd_sg_size(struct ahd_softc *ahd); -static __inline void * - ahd_sg_bus_to_virt(struct ahd_softc *ahd, - struct scb *scb, - uint32_t sg_busaddr); -static __inline uint32_t - ahd_sg_virt_to_bus(struct ahd_softc *ahd, - struct scb *scb, - void *sg); -static __inline void ahd_sync_scb(struct ahd_softc *ahd, - struct scb *scb, int op); -static __inline void ahd_sync_sglist(struct ahd_softc *ahd, - struct scb *scb, int op); -static __inline void ahd_sync_sense(struct ahd_softc *ahd, - struct scb *scb, int op); -static __inline uint32_t - ahd_targetcmd_offset(struct ahd_softc *ahd, - u_int index); - -static __inline size_t -ahd_sg_size(struct ahd_softc *ahd) -{ - if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) - return (sizeof(struct ahd_dma64_seg)); - return (sizeof(struct ahd_dma_seg)); -} - -static __inline void * -ahd_sg_bus_to_virt(struct ahd_softc *ahd, struct scb *scb, uint32_t sg_busaddr) -{ - bus_addr_t sg_offset; - - /* sg_list_phys points to entry 1, not 0 */ - sg_offset = sg_busaddr - (scb->sg_list_busaddr - ahd_sg_size(ahd)); - return ((uint8_t *)scb->sg_list + sg_offset); -} - -static __inline uint32_t -ahd_sg_virt_to_bus(struct ahd_softc *ahd, struct scb *scb, void *sg) -{ - bus_addr_t sg_offset; - - /* sg_list_phys points to entry 1, not 0 */ - sg_offset = ((uint8_t *)sg - (uint8_t *)scb->sg_list) - - ahd_sg_size(ahd); - - return (scb->sg_list_busaddr + sg_offset); -} - -static __inline void -ahd_sync_scb(struct ahd_softc *ahd, struct scb *scb, int op) -{ - ahd_dmamap_sync(ahd, ahd->scb_data.hscb_dmat, - scb->hscb_map->dmamap, - /*offset*/(uint8_t*)scb->hscb - scb->hscb_map->vaddr, - /*len*/sizeof(*scb->hscb), op); -} - -static __inline void -ahd_sync_sglist(struct ahd_softc *ahd, struct scb *scb, int op) -{ - if (scb->sg_count == 0) - return; - - ahd_dmamap_sync(ahd, ahd->scb_data.sg_dmat, - scb->sg_map->dmamap, - /*offset*/scb->sg_list_busaddr - ahd_sg_size(ahd), - /*len*/ahd_sg_size(ahd) * scb->sg_count, op); -} - -static __inline void -ahd_sync_sense(struct ahd_softc *ahd, struct scb *scb, int op) -{ - ahd_dmamap_sync(ahd, ahd->scb_data.sense_dmat, - scb->sense_map->dmamap, - /*offset*/scb->sense_busaddr, - /*len*/AHD_SENSE_BUFSIZE, op); -} - -static __inline uint32_t -ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) -{ - return (((uint8_t *)&ahd->targetcmds[index]) - - (uint8_t *)ahd->qoutfifo); -} - -/*********************** Miscelaneous Support Functions ***********************/ -static __inline void ahd_complete_scb(struct ahd_softc *ahd, - struct scb *scb); -static __inline void ahd_update_residual(struct ahd_softc *ahd, - struct scb *scb); -static __inline struct ahd_initiator_tinfo * - ahd_fetch_transinfo(struct ahd_softc *ahd, - char channel, u_int our_id, - u_int remote_id, - struct ahd_tmode_tstate **tstate); -static __inline uint16_t - ahd_inw(struct ahd_softc *ahd, u_int port); -static __inline void ahd_outw(struct ahd_softc *ahd, u_int port, - u_int value); -static __inline uint32_t - ahd_inl(struct ahd_softc *ahd, u_int port); -static __inline void ahd_outl(struct ahd_softc *ahd, u_int port, - uint32_t value); -static __inline uint64_t - ahd_inq(struct ahd_softc *ahd, u_int port); -static __inline void ahd_outq(struct ahd_softc *ahd, u_int port, - uint64_t value); -static __inline u_int ahd_get_scbptr(struct ahd_softc *ahd); -static __inline void ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr); -static __inline u_int ahd_get_hnscb_qoff(struct ahd_softc *ahd); -static __inline void ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value); -static __inline u_int ahd_get_hescb_qoff(struct ahd_softc *ahd); -static __inline void ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value); -static __inline u_int ahd_get_snscb_qoff(struct ahd_softc *ahd); -static __inline void ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value); -static __inline u_int ahd_get_sescb_qoff(struct ahd_softc *ahd); -static __inline void ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value); -static __inline u_int ahd_get_sdscb_qoff(struct ahd_softc *ahd); -static __inline void ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value); -static __inline u_int ahd_inb_scbram(struct ahd_softc *ahd, u_int offset); -static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset); -static __inline uint32_t - ahd_inl_scbram(struct ahd_softc *ahd, u_int offset); -static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd, - struct scb *scb); -static __inline void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb); -static __inline uint8_t * - ahd_get_sense_buf(struct ahd_softc *ahd, - struct scb *scb); -static __inline uint32_t - ahd_get_sense_bufaddr(struct ahd_softc *ahd, - struct scb *scb); - -static __inline void -ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) -{ - uint32_t sgptr; - - sgptr = ahd_le32toh(scb->hscb->sgptr); - if ((sgptr & SG_STATUS_VALID) != 0) - ahd_handle_scb_status(ahd, scb); - else - ahd_done(ahd, scb); -} - -/* - * Determine whether the sequencer reported a residual - * for this SCB/transaction. - */ -static __inline void -ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) -{ - uint32_t sgptr; - - sgptr = ahd_le32toh(scb->hscb->sgptr); - if ((sgptr & SG_STATUS_VALID) != 0) - ahd_calc_residual(ahd, scb); -} - -/* - * Return pointers to the transfer negotiation information - * for the specified our_id/remote_id pair. - */ -static __inline struct ahd_initiator_tinfo * -ahd_fetch_transinfo(struct ahd_softc *ahd, char channel, u_int our_id, - u_int remote_id, struct ahd_tmode_tstate **tstate) -{ - /* - * Transfer data structures are stored from the perspective - * of the target role. Since the parameters for a connection - * in the initiator role to a given target are the same as - * when the roles are reversed, we pretend we are the target. - */ - if (channel == 'B') - our_id += 8; - *tstate = ahd->enabled_targets[our_id]; - return (&(*tstate)->transinfo[remote_id]); -} - -#define AHD_COPY_COL_IDX(dst, src) \ -do { \ - dst->hscb->scsiid = src->hscb->scsiid; \ - dst->hscb->lun = src->hscb->lun; \ -} while (0) - -static __inline uint16_t -ahd_inw(struct ahd_softc *ahd, u_int port) -{ - return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); -} - -static __inline void -ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) -{ - ahd_outb(ahd, port, value & 0xFF); - ahd_outb(ahd, port+1, (value >> 8) & 0xFF); -} - -static __inline uint32_t -ahd_inl(struct ahd_softc *ahd, u_int port) -{ - return ((ahd_inb(ahd, port)) - | (ahd_inb(ahd, port+1) << 8) - | (ahd_inb(ahd, port+2) << 16) - | (ahd_inb(ahd, port+3) << 24)); -} - -static __inline void -ahd_outl(struct ahd_softc *ahd, u_int port, uint32_t value) -{ - ahd_outb(ahd, port, (value) & 0xFF); - ahd_outb(ahd, port+1, ((value) >> 8) & 0xFF); - ahd_outb(ahd, port+2, ((value) >> 16) & 0xFF); - ahd_outb(ahd, port+3, ((value) >> 24) & 0xFF); -} - -static __inline uint64_t -ahd_inq(struct ahd_softc *ahd, u_int port) -{ - return ((ahd_inb(ahd, port)) - | (ahd_inb(ahd, port+1) << 8) - | (ahd_inb(ahd, port+2) << 16) - | (ahd_inb(ahd, port+3) << 24) - | (((uint64_t)ahd_inb(ahd, port+4)) << 32) - | (((uint64_t)ahd_inb(ahd, port+5)) << 40) - | (((uint64_t)ahd_inb(ahd, port+6)) << 48) - | (((uint64_t)ahd_inb(ahd, port+7)) << 56)); -} - -static __inline void -ahd_outq(struct ahd_softc *ahd, u_int port, uint64_t value) -{ - ahd_outb(ahd, port, value & 0xFF); - ahd_outb(ahd, port+1, (value >> 8) & 0xFF); - ahd_outb(ahd, port+2, (value >> 16) & 0xFF); - ahd_outb(ahd, port+3, (value >> 24) & 0xFF); - ahd_outb(ahd, port+4, (value >> 32) & 0xFF); - ahd_outb(ahd, port+5, (value >> 40) & 0xFF); - ahd_outb(ahd, port+6, (value >> 48) & 0xFF); - ahd_outb(ahd, port+7, (value >> 56) & 0xFF); -} - -static __inline u_int -ahd_get_scbptr(struct ahd_softc *ahd) -{ - AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), - ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); - return (ahd_inb(ahd, SCBPTR) | (ahd_inb(ahd, SCBPTR + 1) << 8)); -} - -static __inline void -ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr) -{ - AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), - ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); - ahd_outb(ahd, SCBPTR, scbptr & 0xFF); - ahd_outb(ahd, SCBPTR+1, (scbptr >> 8) & 0xFF); -} - -static __inline u_int -ahd_get_hnscb_qoff(struct ahd_softc *ahd) -{ - return (ahd_inw_atomic(ahd, HNSCB_QOFF)); -} - -static __inline void -ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value) -{ - ahd_outw_atomic(ahd, HNSCB_QOFF, value); -} - -static __inline u_int -ahd_get_hescb_qoff(struct ahd_softc *ahd) -{ - return (ahd_inb(ahd, HESCB_QOFF)); -} - -static __inline void -ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value) -{ - ahd_outb(ahd, HESCB_QOFF, value); -} - -static __inline u_int -ahd_get_snscb_qoff(struct ahd_softc *ahd) -{ - u_int oldvalue; - - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - oldvalue = ahd_inw(ahd, SNSCB_QOFF); - ahd_outw(ahd, SNSCB_QOFF, oldvalue); - return (oldvalue); -} - -static __inline void -ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value) -{ - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - ahd_outw(ahd, SNSCB_QOFF, value); -} - -static __inline u_int -ahd_get_sescb_qoff(struct ahd_softc *ahd) -{ - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - return (ahd_inb(ahd, SESCB_QOFF)); -} - -static __inline void -ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value) -{ - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - ahd_outb(ahd, SESCB_QOFF, value); -} - -static __inline u_int -ahd_get_sdscb_qoff(struct ahd_softc *ahd) -{ - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - return (ahd_inb(ahd, SDSCB_QOFF) | (ahd_inb(ahd, SDSCB_QOFF + 1) << 8)); -} - -static __inline void -ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value) -{ - AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); - ahd_outb(ahd, SDSCB_QOFF, value & 0xFF); - ahd_outb(ahd, SDSCB_QOFF+1, (value >> 8) & 0xFF); -} - -static __inline u_int -ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) -{ - u_int value; - - /* - * Workaround PCI-X Rev A. hardware bug. - * After a host read of SCB memory, the chip - * may become confused into thinking prefetch - * was required. This starts the discard timer - * running and can cause an unexpected discard - * timer interrupt. The work around is to read - * a normal register prior to the exhaustion of - * the discard timer. The mode pointer register - * has no side effects and so serves well for - * this purpose. - * - * Razor #528 - */ - value = ahd_inb(ahd, offset); - ahd_inb(ahd, MODE_PTR); - return (value); -} - -static __inline u_int -ahd_inw_scbram(struct ahd_softc *ahd, u_int offset) -{ - return (ahd_inb_scbram(ahd, offset) - | (ahd_inb_scbram(ahd, offset+1) << 8)); -} - -static __inline uint32_t -ahd_inl_scbram(struct ahd_softc *ahd, u_int offset) -{ - return (ahd_inb_scbram(ahd, offset) - | (ahd_inb_scbram(ahd, offset+1) << 8) - | (ahd_inb_scbram(ahd, offset+2) << 16) - | (ahd_inb_scbram(ahd, offset+3) << 24)); -} - -static __inline struct scb * -ahd_lookup_scb(struct ahd_softc *ahd, u_int tag) -{ - struct scb* scb; - - if (tag >= AHD_SCB_MAX) - return (NULL); - scb = ahd->scb_data.scbindex[tag]; - if (scb != NULL) - ahd_sync_scb(ahd, scb, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - return (scb); -} - -static __inline void -ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) -{ - struct hardware_scb *q_hscb; - uint32_t saved_hscb_busaddr; - - /* - * Our queuing method is a bit tricky. The card - * knows in advance which HSCB (by address) to download, - * and we can't disappoint it. To achieve this, the next - * HSCB to download is saved off in ahd->next_queued_hscb. - * When we are called to queue "an arbitrary scb", - * we copy the contents of the incoming HSCB to the one - * the sequencer knows about, swap HSCB pointers and - * finally assign the SCB to the tag indexed location - * in the scb_array. This makes sure that we can still - * locate the correct SCB by SCB_TAG. - */ - q_hscb = ahd->next_queued_hscb; - saved_hscb_busaddr = q_hscb->hscb_busaddr; - memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); - q_hscb->hscb_busaddr = saved_hscb_busaddr; - q_hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; - - /* Now swap HSCB pointers. */ - ahd->next_queued_hscb = scb->hscb; - scb->hscb = q_hscb; - - /* Now define the mapping from tag to SCB in the scbindex */ - ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; -} - -/* - * Tell the sequencer about a new transaction to execute. - */ -static __inline void -ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb) -{ - ahd_swap_with_next_hscb(ahd, scb); - - if (SCBID_IS_NULL(SCB_GET_TAG(scb))) - panic("Attempt to queue invalid SCB tag %x\n", - SCB_GET_TAG(scb)); - - /* - * Keep a history of SCBs we've downloaded in the qinfifo. - */ - ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); - ahd->qinfifonext++; - - if (scb->sg_count != 0) - ahd_setup_data_scb(ahd, scb); - else - ahd_setup_noxfer_scb(ahd, scb); - ahd_setup_scb_common(ahd, scb); - - /* - * Make sure our data is consistant from the - * perspective of the adapter. - */ - ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_QUEUE) != 0) { - printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n", - ahd_name(ahd), - SCB_GET_TAG(scb), scb->hscb->hscb_busaddr, - (u_int)((scb->hscb->dataptr >> 32) & 0xFFFFFFFF), - (u_int)(scb->hscb->dataptr & 0xFFFFFFFF), - scb->hscb->datacnt); - } -#endif - /* Tell the adapter about the newly queued SCB */ - ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); -} - -static __inline uint8_t * -ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb) -{ - return (scb->sense_data); -} - -static __inline uint32_t -ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb) -{ - return (scb->sense_busaddr); -} - -/************************** Interrupt Processing ******************************/ -static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op); -static __inline void ahd_sync_tqinfifo(struct ahd_softc *ahd, int op); -static __inline u_int ahd_check_cmdcmpltqueues(struct ahd_softc *ahd); -static __inline void ahd_intr(struct ahd_softc *ahd); - -static __inline void -ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) -{ - ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, - /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op); -} - -static __inline void -ahd_sync_tqinfifo(struct ahd_softc *ahd, int op) -{ -#ifdef AHD_TARGET_MODE - if ((ahd->flags & AHD_TARGETROLE) != 0) { - ahd_dmamap_sync(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap, - ahd_targetcmd_offset(ahd, 0), - sizeof(struct target_cmd) * AHD_TMODE_CMDS, - op); - } -#endif -} - -/* - * See if the firmware has posted any completed commands - * into our in-core command complete fifos. - */ -#define AHD_RUN_QOUTFIFO 0x1 -#define AHD_RUN_TQINFIFO 0x2 -static __inline u_int -ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) -{ - u_int retval; - - retval = 0; - ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, - /*offset*/ahd->qoutfifonext, /*len*/2, - BUS_DMASYNC_POSTREAD); - if ((ahd->qoutfifo[ahd->qoutfifonext] - & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) - retval |= AHD_RUN_QOUTFIFO; -#ifdef AHD_TARGET_MODE - if ((ahd->flags & AHD_TARGETROLE) != 0 - && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { - ahd_dmamap_sync(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap, - ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), - /*len*/sizeof(struct target_cmd), - BUS_DMASYNC_POSTREAD); - if (ahd->targetcmds[ahd->tqinfifonext].cmd_valid != 0) - retval |= AHD_RUN_TQINFIFO; - } -#endif - return (retval); -} - -/* - * Catch an interrupt from the adapter - */ -static __inline void -ahd_intr(struct ahd_softc *ahd) -{ - u_int intstat; - - if ((ahd->pause & INTEN) == 0) { - /* - * Our interrupt is not enabled on the chip - * and may be disabled for re-entrancy reasons, - * so just return. This is likely just a shared - * interrupt. - */ - return; - } - - /* - * Instead of directly reading the interrupt status register, - * infer the cause of the interrupt by checking our in-core - * completion queues. This avoids a costly PCI bus read in - * most cases. - */ - if ((ahd->flags & AHD_ALL_INTERRUPTS) == 0 - && (ahd_check_cmdcmpltqueues(ahd) != 0)) - intstat = CMDCMPLT; - else - intstat = ahd_inb(ahd, INTSTAT); - - if (intstat & CMDCMPLT) { - ahd_outb(ahd, CLRINT, CLRCMDINT); - - /* - * Ensure that the chip sees that we've cleared - * this interrupt before we walk the output fifo. - * Otherwise, we may, due to posted bus writes, - * clear the interrupt after we finish the scan, - * and after the sequencer has added new entries - * and asserted the interrupt again. - */ - if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { - if (ahd_is_paused(ahd)) { - /* - * Potentially lost SEQINT. - * If SEQINTCODE is non-zero, - * simulate the SEQINT. - */ - if (ahd_inb(ahd, SEQINTCODE) != NO_SEQINT) - intstat |= SEQINT; - } - } else { - ahd_flush_device_writes(ahd); - } - ahd_run_qoutfifo(ahd); - ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]++; - ahd->cmdcmplt_total++; -#ifdef AHD_TARGET_MODE - if ((ahd->flags & AHD_TARGETROLE) != 0) - ahd_run_tqinfifo(ahd, /*paused*/FALSE); -#endif - } - - if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) - /* Hot eject */ - return; - - if ((intstat & INT_PEND) == 0) - return; - - if (intstat & HWERRINT) { - ahd_handle_hwerrint(ahd); - return; - } - - if ((intstat & (PCIINT|SPLTINT)) != 0) { - ahd->bus_intr(ahd); - return; - } - - if ((intstat & SEQINT) != 0) - ahd_handle_seqint(ahd, intstat); - - if ((intstat & SCSIINT) != 0) - ahd_handle_scsiint(ahd, intstat); -} - -#endif /* _AIC79XX_INLINE_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_osm.c linux-2.4.22/drivers/scsi/aic79xx/aic79xx_osm.c --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_osm.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_osm.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,5322 +0,0 @@ -/* - * Adaptec AIC79xx device driver for Linux. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#115 $ - * - * -------------------------------------------------------------------------- - * Copyright (c) 1994-2000 Justin T. Gibbs. - * Copyright (c) 1997-1999 Doug Ledford - * Copyright (c) 2000-2003 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHD_MODVERSION_FILE - -#include "aic79xx_osm.h" -#include "aic79xx_inline.h" -#include - -/* - * Include aiclib.c as part of our - * "module dependencies are hard" work around. - */ -#include "aiclib.c" - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) -#include /* __setup */ -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "sd.h" /* For geometry detection */ -#endif - -#include /* For fetching system memory size */ - -#define __KERNEL_SYSCALLS__ - -#include -static int errno; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -/* - * Lock protecting manipulation of the ahd softc list. - */ -spinlock_t ahd_list_spinlock; -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -struct proc_dir_entry proc_scsi_aic79xx = { - PROC_SCSI_AIC79XX, 7, "aic79xx", - S_IFDIR | S_IRUGO | S_IXUGO, 2, - 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; -#endif - -/* - * Bucket size for counting good commands in between bad ones. - */ -#define AHD_LINUX_ERR_THRESH 1000 - -/* - * Set this to the delay in seconds after SCSI bus reset. - * Note, we honor this only for the initial bus reset. - * The scsi error recovery code performs its own bus settle - * delay handling for error recovery actions. - */ -#ifdef CONFIG_AIC79XX_RESET_DELAY_MS -#define AIC79XX_RESET_DELAY CONFIG_AIC79XX_RESET_DELAY_MS -#else -#define AIC79XX_RESET_DELAY 5000 -#endif - -/* - * To change the default number of tagged transactions allowed per-device, - * add a line to the lilo.conf file like: - * append="aic79xx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}" - * which will result in the first four devices on the first two - * controllers being set to a tagged queue depth of 32. - * - * The tag_commands is an array of 16 to allow for wide and twin adapters. - * Twin adapters will use indexes 0-7 for channel 0, and indexes 8-15 - * for channel 1. - */ -typedef struct { - uint16_t tag_commands[16]; /* Allow for wide/twin adapters. */ -} adapter_tag_info_t; - -/* - * Modify this as you see fit for your system. - * - * 0 tagged queuing disabled - * 1 <= n <= 253 n == max tags ever dispatched. - * - * The driver will throttle the number of commands dispatched to a - * device if it returns queue full. For devices with a fixed maximum - * queue depth, the driver will eventually determine this depth and - * lock it in (a console message is printed to indicate that a lock - * has occurred). On some devices, queue full is returned for a temporary - * resource shortage. These devices will return queue full at varying - * depths. The driver will throttle back when the queue fulls occur and - * attempt to slowly increase the depth over time as the device recovers - * from the resource shortage. - * - * In this example, the first line will disable tagged queueing for all - * the devices on the first probed aic79xx adapter. - * - * The second line enables tagged queueing with 4 commands/LUN for IDs - * (0, 2-11, 13-15), disables tagged queueing for ID 12, and tells the - * driver to attempt to use up to 64 tags for ID 1. - * - * The third line is the same as the first line. - * - * The fourth line disables tagged queueing for devices 0 and 3. It - * enables tagged queueing for the other IDs, with 16 commands/LUN - * for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for - * IDs 2, 5-7, and 9-15. - */ - -/* - * NOTE: The below structure is for reference only, the actual structure - * to modify in order to change things is just below this comment block. -adapter_tag_info_t aic79xx_tag_info[] = -{ - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, - {{4, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4}}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, - {{0, 16, 4, 0, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}} -}; -*/ - -#ifdef CONFIG_AIC79XX_CMDS_PER_DEVICE -#define AIC79XX_CMDS_PER_DEVICE CONFIG_AIC79XX_CMDS_PER_DEVICE -#else -#define AIC79XX_CMDS_PER_DEVICE AHD_MAX_QUEUE -#endif - -#define AIC79XX_CONFIGED_TAG_COMMANDS { \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ - AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE \ -} - -/* - * By default, use the number of commands specified by - * the users kernel configuration. - */ -static adapter_tag_info_t aic79xx_tag_info[] = -{ - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS}, - {AIC79XX_CONFIGED_TAG_COMMANDS} -}; - -/* - * By default, read streaming is disabled. In theory, - * read streaming should enhance performance, but early - * U320 drive firmware actually performs slower with - * read streaming enabled. - */ -#ifdef CONFIG_AIC79XX_ENABLE_RD_STRM -#define AIC79XX_CONFIGED_RD_STRM 0xFFFF -#else -#define AIC79XX_CONFIGED_RD_STRM 0 -#endif - -static uint16_t aic79xx_rd_strm_info[] = -{ - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM, - AIC79XX_CONFIGED_RD_STRM -}; - -/* - * DV option: - * - * positive value = DV Enabled - * zero = DV Disabled - * negative value = DV Default for adapter type/seeprom - */ -#ifdef CONFIG_AIC79XX_DV_SETTING -#define AIC79XX_CONFIGED_DV CONFIG_AIC79XX_DV_SETTING -#else -#define AIC79XX_CONFIGED_DV -1 -#endif - -static int8_t aic79xx_dv_settings[] = -{ - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV, - AIC79XX_CONFIGED_DV -}; - -/* - * The I/O cell on the chip is very configurable in respect to its analog - * characteristics. Set the defaults here; they can be overriden with - * the proper insmod parameters. - */ -struct ahd_linux_iocell_opts -{ - uint8_t precomp; - uint8_t slewrate; - uint8_t amplitude; -}; -#define AIC79XX_DEFAULT_PRECOMP 0xFF -#define AIC79XX_DEFAULT_SLEWRATE 0xFF -#define AIC79XX_DEFAULT_AMPLITUDE 0xFF -#define AIC79XX_DEFAULT_IOOPTS \ -{ \ - AIC79XX_DEFAULT_PRECOMP, \ - AIC79XX_DEFAULT_SLEWRATE, \ - AIC79XX_DEFAULT_AMPLITUDE \ -} -#define AIC79XX_PRECOMP_INDEX 0 -#define AIC79XX_SLEWRATE_INDEX 1 -#define AIC79XX_AMPLITUDE_INDEX 2 -static struct ahd_linux_iocell_opts aic79xx_iocell_info[] = -{ - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS, - AIC79XX_DEFAULT_IOOPTS -}; - -/* - * There should be a specific return value for this in scsi.h, but - * it seems that most drivers ignore it. - */ -#define DID_UNDERFLOW DID_ERROR - -void -ahd_print_path(struct ahd_softc *ahd, struct scb *scb) -{ - printk("(scsi%d:%c:%d:%d): ", - ahd->platform_data->host->host_no, - scb != NULL ? SCB_GET_CHANNEL(ahd, scb) : 'X', - scb != NULL ? SCB_GET_TARGET(ahd, scb) : -1, - scb != NULL ? SCB_GET_LUN(scb) : -1); -} - -/* - * XXX - these options apply unilaterally to _all_ adapters - * cards in the system. This should be fixed. Exceptions to this - * rule are noted in the comments. - */ - -/* - * Skip the scsi bus reset. Non 0 make us skip the reset at startup. This - * has no effect on any later resets that might occur due to things like - * SCSI bus timeouts. - */ -static uint32_t aic79xx_no_reset; - -/* - * Certain PCI motherboards will scan PCI devices from highest to lowest, - * others scan from lowest to highest, and they tend to do all kinds of - * strange things when they come into contact with PCI bridge chips. The - * net result of all this is that the PCI card that is actually used to boot - * the machine is very hard to detect. Most motherboards go from lowest - * PCI slot number to highest, and the first SCSI controller found is the - * one you boot from. The only exceptions to this are when a controller - * has its BIOS disabled. So, we by default sort all of our SCSI controllers - * from lowest PCI slot number to highest PCI slot number. We also force - * all controllers with their BIOS disabled to the end of the list. This - * works on *almost* all computers. Where it doesn't work, we have this - * option. Setting this option to non-0 will reverse the order of the sort - * to highest first, then lowest, but will still leave cards with their BIOS - * disabled at the very end. That should fix everyone up unless there are - * really strange cirumstances. - */ -static int aic79xx_reverse_scan = 0; - -/* - * Should we force EXTENDED translation on a controller. - * 0 == Use whatever is in the SEEPROM or default to off - * 1 == Use whatever is in the SEEPROM or default to on - */ -static uint32_t aic79xx_extended = 0; - -/* - * PCI bus parity checking of the Adaptec controllers. This is somewhat - * dubious at best. To my knowledge, this option has never actually - * solved a PCI parity problem, but on certain machines with broken PCI - * chipset configurations, it can generate tons of false error messages. - * It's included in the driver for completeness. - * 0 = Shut off PCI parity check - * -1 = Normal polarity pci parity checking - * 1 = reverse polarity pci parity checking - * - * NOTE: you can't actually pass -1 on the lilo prompt. So, to set this - * variable to -1 you would actually want to simply pass the variable - * name without a number. That will invert the 0 which will result in - * -1. - */ -static int aic79xx_pci_parity = 0; - -/* - * There are lots of broken chipsets in the world. Some of them will - * violate the PCI spec when we issue byte sized memory writes to our - * controller. I/O mapped register access, if allowed by the given - * platform, will work in almost all cases. - */ -int aic79xx_allow_memio = 1; - -/* - * aic79xx_detect() has been run, so register all device arrivals - * immediately with the system rather than deferring to the sorted - * attachment performed by aic79xx_detect(). - */ -int aic79xx_detect_complete; - -/* - * So that we can set how long each device is given as a selection timeout. - * The table of values goes like this: - * 0 - 256ms - * 1 - 128ms - * 2 - 64ms - * 3 - 32ms - * We default to 256ms because some older devices need a longer time - * to respond to initial selection. - */ -static int aic79xx_seltime = 0x00; - -/* - * Certain devices do not perform any aging on commands. Should the - * device be saturated by commands in one portion of the disk, it is - * possible for transactions on far away sectors to never be serviced. - * To handle these devices, we can periodically send an ordered tag to - * force all outstanding transactions to be serviced prior to a new - * transaction. - */ -int aic79xx_periodic_otag; - -/* - * Module information and settable options. - */ -#ifdef MODULE -static char *aic79xx = NULL; -/* - * Just in case someone uses commas to separate items on the insmod - * command line, we define a dummy buffer here to avoid having insmod - * write wild stuff into our code segment - */ -static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n"; - -MODULE_AUTHOR("Maintainer: Justin T. Gibbs "); -MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver"); -#ifdef MODULE_LICENSE -MODULE_LICENSE("Dual BSD/GPL"); -#endif -MODULE_PARM(aic79xx, "s"); -MODULE_PARM_DESC(aic79xx, -"period delimited, options string.\n" -" verbose Enable verbose/diagnostic logging\n" -" allow_memio Allow device registers to be memory mapped\n" -" debug Bitmask of debug values to enable\n" -" no_reset Supress initial bus resets\n" -" extended Enable extended geometry on all controllers\n" -" periodic_otag Send an ordered tagged transaction\n" -" periodically to prevent tag starvation.\n" -" This may be required by some older disk\n" -" or drives/RAID arrays.\n" -" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" -" tag_info: Set per-target tag depth\n" -" global_tag_depth: Global tag depth for all targets on all buses\n" -" rd_strm: Set per-target read streaming setting.\n" -" dv: Set per-controller Domain Validation Setting.\n" -" slewrate:Set the signal slew rate (0-15).\n" -" precomp: Set the signal precompensation (0-7).\n" -" amplitude: Set the signal amplitude (0-7).\n" -" seltime: Selection Timeout:\n" -" (0/256ms,1/128ms,2/64ms,3/32ms)\n" -"\n" -" Sample /etc/modules.conf line:\n" -" Enable verbose logging\n" -" Set tag depth on Controller 2/Target 2 to 10 tags\n" -" Shorten the selection timeout to 128ms\n" -"\n" -" options aic79xx='\"verbose.tag_info:{{}.{}.{..10}}.seltime:1\"'\n" -"\n" -" Sample /etc/modules.conf line:\n" -" Change Read Streaming for Controller's 2 and 3\n" -"\n" -" options aic79xx='\"rd_strm:{..0xFFF0.0xC0F0}\"'"); -#endif - -static void ahd_linux_handle_scsi_status(struct ahd_softc *, - struct ahd_linux_device *, - struct scb *); -static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, - Scsi_Cmnd *cmd); -static void ahd_linux_filter_inquiry(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static void ahd_linux_dev_timed_unfreeze(u_long arg); -static void ahd_linux_sem_timeout(u_long arg); -static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); -static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd); -static void ahd_linux_start_dv(struct ahd_softc *ahd); -static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd); -static int ahd_linux_dv_thread(void *data); -static void ahd_linux_dv_target(struct ahd_softc *ahd, u_int target); -static void ahd_linux_dv_transition(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ); -static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo); -static void ahd_linux_dv_inq(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ, - u_int request_length); -static void ahd_linux_dv_tur(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo); -static void ahd_linux_dv_rebd(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ); -static void ahd_linux_dv_web(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ); -static void ahd_linux_dv_reb(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ); -static void ahd_linux_dv_su(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ); -static __inline int - ahd_linux_dv_fallback(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static int ahd_linux_fallback(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static __inline int ahd_linux_dv_fallback(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static void ahd_linux_dv_complete(Scsi_Cmnd *cmd); -static void ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ); -static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo); -static u_int ahd_linux_user_dv_setting(struct ahd_softc *ahd); -static void ahd_linux_device_queue_depth(struct ahd_softc *ahd, - struct ahd_linux_device *dev); -static struct ahd_linux_target* ahd_linux_alloc_target(struct ahd_softc*, - u_int, u_int); -static void ahd_linux_free_target(struct ahd_softc*, - struct ahd_linux_target*); -static struct ahd_linux_device* ahd_linux_alloc_device(struct ahd_softc*, - struct ahd_linux_target*, - u_int); -static void ahd_linux_free_device(struct ahd_softc*, - struct ahd_linux_device*); -static void ahd_linux_run_device_queue(struct ahd_softc*, - struct ahd_linux_device*); -static void ahd_linux_setup_tag_info(char *p, char *end, char *s); -static void ahd_linux_setup_tag_info_global(char *p); -static void ahd_linux_setup_rd_strm_info(char *p, char *end, char *s); -static void ahd_linux_setup_dv(char *p, char *end, char *s); -static void ahd_linux_setup_iocell_info(char *p, char *end, char *s, int index); -static int ahd_linux_next_unit(void); -static void ahd_runq_tasklet(unsigned long data); -static int ahd_linux_halt(struct notifier_block *nb, u_long event, void *buf); -static int aic79xx_setup(char *c); - -/****************************** Inlines ***************************************/ -static __inline void ahd_schedule_completeq(struct ahd_softc *ahd, - struct ahd_cmd *acmd); -static __inline void ahd_schedule_runq(struct ahd_softc *ahd); -static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd); -static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd); -static __inline struct ahd_linux_device* - ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, - u_int target, u_int lun, int alloc); -static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd, - struct ahd_cmd *acmd); -static __inline void ahd_linux_check_device_queue(struct ahd_softc *ahd, - struct ahd_linux_device *dev); -static __inline struct ahd_linux_device * - ahd_linux_next_device_to_run(struct ahd_softc *ahd); -static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd); -static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); - -static __inline int ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, - struct ahd_dma_seg *sg, - bus_addr_t addr, bus_size_t len); - -static __inline void -ahd_schedule_completeq(struct ahd_softc *ahd, struct ahd_cmd *acmd) -{ - while (acmd != NULL) { - struct ahd_completeq *completeq; - struct ahd_cmd *list_cmd; - struct ahd_cmd *next_cmd; - - next_cmd = TAILQ_NEXT(acmd, acmd_links.tqe); - completeq = &ahd->platform_data->completeq; - list_cmd = TAILQ_FIRST(completeq); - while (list_cmd != NULL - && acmd_scsi_cmd(list_cmd).serial_number - < acmd_scsi_cmd(acmd).serial_number) - list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); - if (list_cmd != NULL) - TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); - else - TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); - acmd = next_cmd; - } - if ((ahd->platform_data->flags & AHD_RUN_CMPLT_Q_TIMER) == 0) { - ahd->platform_data->flags |= AHD_RUN_CMPLT_Q_TIMER; - ahd->platform_data->completeq_timer.expires = jiffies; - add_timer(&ahd->platform_data->completeq_timer); - } -} - -static __inline void -ahd_schedule_runq(struct ahd_softc *ahd) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_schedule(&ahd->platform_data->runq_tasklet); -#else - /* - * Tasklets are not available, so run inline. - */ - ahd_runq_tasklet((unsigned long)ahd); -#endif -} - -static __inline -void ahd_setup_runq_tasklet(struct ahd_softc *ahd) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_init(&ahd->platform_data->runq_tasklet, ahd_runq_tasklet, - (unsigned long)ahd); -#endif -} - -static __inline void -ahd_teardown_runq_tasklet(struct ahd_softc *ahd) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_kill(&ahd->platform_data->runq_tasklet); -#endif -} - -static __inline struct ahd_linux_device* -ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target, - u_int lun, int alloc) -{ - struct ahd_linux_target *targ; - struct ahd_linux_device *dev; - u_int target_offset; - - target_offset = target; - if (channel != 0) - target_offset += 8; - targ = ahd->platform_data->targets[target_offset]; - if (targ == NULL) { - if (alloc != 0) { - targ = ahd_linux_alloc_target(ahd, channel, target); - if (targ == NULL) - return (NULL); - } else - return (NULL); - } - dev = targ->devices[lun]; - if (dev == NULL && alloc != 0) - dev = ahd_linux_alloc_device(ahd, targ, lun); - return (dev); -} - -#define AHD_LINUX_MAX_RETURNED_ERRORS 4 -static struct ahd_cmd * -ahd_linux_run_complete_queue(struct ahd_softc *ahd, struct ahd_cmd *acmd) -{ - u_long done_flags; - int with_errors; - - ahd_done_lock(ahd, &done_flags); - with_errors = 0; - while (acmd != NULL) { - Scsi_Cmnd *cmd; - - cmd = &acmd_scsi_cmd(acmd); - acmd = TAILQ_NEXT(acmd, acmd_links.tqe); - cmd->host_scribble = NULL; - if (ahd_cmd_get_transaction_status(cmd) != DID_OK - || (cmd->result & 0xFF) != SCSI_STATUS_OK) - with_errors++; - - cmd->scsi_done(cmd); - - if (with_errors > AHD_LINUX_MAX_RETURNED_ERRORS) { - /* - * Linux uses stack recursion to requeue - * commands that need to be retried. Avoid - * blowing out the stack by "spoon feeding" - * commands that completed with error back - * the operating system in case they are going - * to be retried. "ick" - */ - break; - } - } - ahd_done_unlock(ahd, &done_flags); - return (acmd); -} - -static __inline void -ahd_linux_check_device_queue(struct ahd_softc *ahd, - struct ahd_linux_device *dev) -{ - if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) != 0 - && dev->active == 0) { - dev->flags &= ~AHD_DEV_FREEZE_TIL_EMPTY; - dev->qfrozen--; - } - - if (TAILQ_FIRST(&dev->busyq) == NULL - || dev->openings == 0 || dev->qfrozen != 0) - return; - - ahd_linux_run_device_queue(ahd, dev); -} - -static __inline struct ahd_linux_device * -ahd_linux_next_device_to_run(struct ahd_softc *ahd) -{ - - if ((ahd->flags & AHD_RESOURCE_SHORTAGE) != 0 - || (ahd->platform_data->qfrozen != 0 - && AHD_DV_SIMQ_FROZEN(ahd) == 0)) - return (NULL); - return (TAILQ_FIRST(&ahd->platform_data->device_runq)); -} - -static __inline void -ahd_linux_run_device_queues(struct ahd_softc *ahd) -{ - struct ahd_linux_device *dev; - - while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { - TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); - dev->flags &= ~AHD_DEV_ON_RUN_LIST; - ahd_linux_check_device_queue(ahd, dev); - } -} - -static __inline void -ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) -{ - Scsi_Cmnd *cmd; - int direction; - - cmd = scb->io_ctx; - direction = scsi_to_pci_dma_dir(cmd->sc_data_direction); - ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE); - if (cmd->use_sg != 0) { - struct scatterlist *sg; - - sg = (struct scatterlist *)cmd->request_buffer; - pci_unmap_sg(ahd->dev_softc, sg, cmd->use_sg, direction); - } else if (cmd->request_bufflen != 0) { - pci_unmap_single(ahd->dev_softc, - scb->platform_data->buf_busaddr, - cmd->request_bufflen, direction); - } -} - -static __inline int -ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, - struct ahd_dma_seg *sg, bus_addr_t addr, bus_size_t len) -{ - int consumed; - - if ((scb->sg_count + 1) > AHD_NSEG) - panic("Too few segs for dma mapping. " - "Increase AHD_NSEG\n"); - - consumed = 1; - sg->addr = ahd_htole32(addr & 0xFFFFFFFF); - scb->platform_data->xfer_len += len; - if (sizeof(bus_addr_t) > 4 - && (ahd->flags & AHD_39BIT_ADDRESSING) != 0) { - /* - * Due to DAC restrictions, we can't - * cross a 4GB boundary. - */ - if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) { - struct ahd_dma_seg *next_sg; - uint32_t next_len; - - printf("Crossed Seg\n"); - if ((scb->sg_count + 2) > AHD_NSEG) - panic("Too few segs for dma mapping. " - "Increase AHD_NSEG\n"); - - consumed++; - next_sg = sg + 1; - next_sg->addr = 0; - next_len = 0x100000000 - (addr & 0xFFFFFFFF); - len -= next_len; - next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000; - next_sg->len = ahd_htole32(next_len); - } - len |= (addr >> 8) & 0x7F000000; - } - sg->len = ahd_htole32(len); - return (consumed); -} - -/******************************** Macros **************************************/ -#define BUILD_SCSIID(ahd, cmd) \ - ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id) - -/************************ Host template entry points *************************/ -static int ahd_linux_detect(Scsi_Host_Template *); -static int ahd_linux_release(struct Scsi_Host *); -static const char *ahd_linux_info(struct Scsi_Host *); -static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -static int ahd_linux_slave_alloc(Scsi_Device *); -static int ahd_linux_slave_configure(Scsi_Device *); -static void ahd_linux_slave_destroy(Scsi_Device *); -static int ahd_linux_biosparam(struct scsi_device*, - struct block_device*, sector_t, int[]); -#else -static void ahd_linux_select_queue_depth(struct Scsi_Host *host, - Scsi_Device *scsi_devs); -static int ahd_linux_biosparam(Disk *, kdev_t, int[]); -#endif -static int ahd_linux_bus_reset(Scsi_Cmnd *); -static int ahd_linux_dev_reset(Scsi_Cmnd *); -static int ahd_linux_abort(Scsi_Cmnd *); - -/* - * Try to detect an Adaptec 79XX controller. - */ -static int -ahd_linux_detect(Scsi_Host_Template *template) -{ - struct ahd_softc *ahd; - int found; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); -#endif - - /* - * Sanity checking of Linux SCSI data structures so - * that some of our hacks^H^H^H^H^Hassumptions aren't - * violated. - */ - if (offsetof(struct ahd_cmd_internal, end) - > offsetof(struct scsi_cmnd, host_scribble)) { - printf("ahd_linux_detect: SCSI data structures changed.\n"); - printf("ahd_linux_detect: Unable to attach\n"); - return (0); - } -#ifdef MODULE - /* - * If we've been passed any parameters, process them now. - */ - if (aic79xx) - aic79xx_setup(aic79xx); - if (dummy_buffer[0] != 'P') - printk(KERN_WARNING -"aic79xx: Please read the file /usr/src/linux/drivers/scsi/README.aic79xx\n" -"aic79xx: to see the proper way to specify options to the aic79xx module\n" -"aic79xx: Specifically, don't use any commas when passing arguments to\n" -"aic79xx: insmod or else it might trash certain memory areas.\n"); -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) - template->proc_name = "aic79xx"; -#else - template->proc_dir = &proc_scsi_aic79xx; -#endif - - /* - * Initialize our softc list lock prior to - * probing for any adapters. - */ - ahd_list_lockinit(); - -#ifdef CONFIG_PCI - ahd_linux_pci_probe(template); -#endif - - /* - * Register with the SCSI layer all - * controllers we've found. - */ - found = 0; - TAILQ_FOREACH(ahd, &ahd_tailq, links) { - - if (ahd_linux_register_host(ahd, template) == 0) - found++; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - aic79xx_detect_complete++; - return (found); -} - -/* - * Free the passed in Scsi_Host memory structures prior to unloading the - * module. - */ -static int -ahd_linux_release(struct Scsi_Host * host) -{ - struct ahd_softc *ahd; - u_long l; - - ahd_list_lock(&l); - if (host != NULL) { - - /* - * We should be able to just perform - * the free directly, but check our - * list for extra sanity. - */ - ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata); - if (ahd != NULL) { - u_long s; - - ahd_lock(ahd, &s); - ahd_intr_enable(ahd, FALSE); - ahd_unlock(ahd, &s); - ahd_free(ahd); - } - } - ahd_list_unlock(&l); - return (0); -} - -/* - * Return a string describing the driver. - */ -static const char * -ahd_linux_info(struct Scsi_Host *host) -{ - static char buffer[512]; - char ahd_info[256]; - char *bp; - struct ahd_softc *ahd; - - bp = &buffer[0]; - ahd = *(struct ahd_softc **)host->hostdata; - memset(bp, 0, sizeof(buffer)); - strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev "); - strcat(bp, AIC79XX_DRIVER_VERSION); - strcat(bp, "\n"); - strcat(bp, " <"); - strcat(bp, ahd->description); - strcat(bp, ">\n"); - strcat(bp, " "); - ahd_controller_info(ahd, ahd_info); - strcat(bp, ahd_info); - strcat(bp, "\n"); - - return (bp); -} - -/* - * Queue an SCB to the controller. - */ -static int -ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) -{ - struct ahd_softc *ahd; - struct ahd_linux_device *dev; - u_long flags; - - ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - - /* - * Save the callback on completion function. - */ - cmd->scsi_done = scsi_done; - - ahd_midlayer_entrypoint_lock(ahd, &flags); - - /* - * Close the race of a command that was in the process of - * being queued to us just as our simq was frozen. Let - * DV commands through so long as we are only frozen to - * perform DV. - */ - if (ahd->platform_data->qfrozen != 0 - && AHD_DV_CMD(cmd) == 0) { - - ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); - ahd_linux_queue_cmd_complete(ahd, cmd); - ahd_schedule_completeq(ahd, NULL); - ahd_midlayer_entrypoint_unlock(ahd, &flags); - return (0); - } - dev = ahd_linux_get_device(ahd, cmd->device->channel, - cmd->device->id, cmd->device->lun, - /*alloc*/TRUE); - if (dev == NULL) { - ahd_midlayer_entrypoint_unlock(ahd, &flags); - printf("aic79xx_linux_queue: Unable to allocate device!\n"); - return (-ENOMEM); - } - if (cmd->cmd_len > MAX_CDB_LEN) - return (-EINVAL); - cmd->result = CAM_REQ_INPROG << 16; - TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe); - if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); - dev->flags |= AHD_DEV_ON_RUN_LIST; - ahd_linux_run_device_queues(ahd); - } - ahd_midlayer_entrypoint_unlock(ahd, &flags); - return (0); -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -static int -ahd_linux_slave_alloc(Scsi_Device *device) -{ - struct ahd_softc *ahd; - - ahd = *((struct ahd_softc **)device->host->hostdata); - if (bootverbose) - printf("%s: Slave Alloc %d\n", ahd_name(ahd), device->id); - return (0); -} - -static int -ahd_linux_slave_configure(Scsi_Device *device) -{ - struct ahd_softc *ahd; - struct ahd_linux_device *dev; - u_long flags; - - ahd = *((struct ahd_softc **)device->host->hostdata); - if (bootverbose) - printf("%s: Slave Configure %d\n", ahd_name(ahd), device->id); - ahd_midlayer_entrypoint_lock(ahd, &flags); - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahd_linux_get_device(ahd, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHD_DEV_UNCONFIGURED; - dev->flags |= AHD_DEV_SLAVE_CONFIGURED; - dev->scsi_device = device; - ahd_linux_device_queue_depth(ahd, dev); - } - ahd_midlayer_entrypoint_unlock(ahd, &flags); - return (0); -} - -static void -ahd_linux_slave_destroy(Scsi_Device *device) -{ - struct ahd_softc *ahd; - struct ahd_linux_device *dev; - u_long flags; - - ahd = *((struct ahd_softc **)device->host->hostdata); - if (bootverbose) - printf("%s: Slave Destroy %d\n", ahd_name(ahd), device->id); - ahd_midlayer_entrypoint_lock(ahd, &flags); - dev = ahd_linux_get_device(ahd, device->channel, - device->id, device->lun, - /*alloc*/FALSE); - - /* - * Filter out "silly" deletions of real devices by only - * deleting devices that have had slave_configure() - * called on them. All other devices that have not - * been configured will automatically be deleted by - * the refcounting process. - */ - if (dev != NULL - && (dev->flags & AHD_DEV_SLAVE_CONFIGURED) != 0) { - dev->flags |= AHD_DEV_UNCONFIGURED; - if (TAILQ_EMPTY(&dev->busyq) - && dev->active == 0) - ahd_linux_free_device(ahd, dev); - } - ahd_midlayer_entrypoint_unlock(ahd, &flags); -} -#else -/* - * Sets the queue depth for each SCSI device hanging - * off the input host adapter. - */ -static void -ahd_linux_select_queue_depth(struct Scsi_Host * host, - Scsi_Device * scsi_devs) -{ - Scsi_Device *device; - struct ahd_softc *ahd; - u_long flags; - int scbnum; - - ahd = *((struct ahd_softc **)host->hostdata); - ahd_midlayer_entrypoint_lock(ahd, &flags); - scbnum = 0; - for (device = scsi_devs; device != NULL; device = device->next) { - - if (device->host == host) { - struct ahd_linux_device *dev; - - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahd_linux_get_device(ahd, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHD_DEV_UNCONFIGURED; - dev->scsi_device = device; - ahd_linux_device_queue_depth(ahd, dev); - device->queue_depth = dev->openings - + dev->active; - if ((dev->flags & (AHD_DEV_Q_BASIC - | AHD_DEV_Q_TAGGED)) == 0) { - /* - * We allow the OS to queue 2 untagged - * transactions to us at any time even - * though we can only execute them - * serially on the controller/device. - * This should remove some latency. - */ - device->queue_depth = 2; - } - } - } - } - ahd_midlayer_entrypoint_unlock(ahd, &flags); -} -#endif - -/* - * Return the disk geometry for the given SCSI device. - */ -static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int geom[]) -{ - uint8_t *bh; -#else -ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) -{ - struct scsi_device *sdev = disk->device; - u_long capacity = disk->capacity; - struct buffer_head *bh; -#endif - int heads; - int sectors; - int cylinders; - int ret; - int extended; - struct ahd_softc *ahd; - - ahd = *((struct ahd_softc **)sdev->host->hostdata); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - bh = scsi_bios_ptable(bdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); -#else - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); -#endif - - if (bh) { - ret = scsi_partsize(bh, capacity, - &geom[2], &geom[0], &geom[1]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - kfree(bh); -#else - brelse(bh); -#endif - if (ret != -1) - return (ret); - } - heads = 64; - sectors = 32; - cylinders = aic_sector_div(capacity, heads, sectors); - - if (aic79xx_extended != 0) - extended = 1; - else - extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0; - if (extended && cylinders >= 1024) { - heads = 255; - sectors = 63; - cylinders = aic_sector_div(capacity, heads, sectors); - } - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; - return (0); -} - -/* - * Abort the current SCSI command(s). - */ -static int -ahd_linux_abort(Scsi_Cmnd *cmd) -{ - struct ahd_softc *ahd; - struct ahd_cmd *acmd; - struct ahd_cmd *list_acmd; - struct ahd_linux_device *dev; - struct scb *pending_scb; - u_long s; - u_int saved_scbptr; - u_int active_scbptr; - u_int last_phase; - int retval; - int paused; - int wait; - int disconnected; - ahd_mode_state saved_modes; - - pending_scb = NULL; - paused = FALSE; - wait = FALSE; - ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - acmd = (struct ahd_cmd *)cmd; - - printf("%s:%d:%d:%d: Attempting to abort cmd %p\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun, cmd); - - /* - * In all versions of Linux, we have to work around - * a major flaw in how the mid-layer is locked down - * if we are to sleep successfully in our error handler - * while allowing our interrupt handler to run. Since - * the midlayer acquires either the io_request_lock or - * our lock prior to calling us, we must use the - * spin_unlock_irq() method for unlocking our lock. - * This will force interrupts to be enabled on the - * current CPU. Since the EH thread should not have - * been running with CPU interrupts disabled other than - * by acquiring either the io_request_lock or our own - * lock, this *should* be safe. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irq(&io_request_lock); -#endif - ahd_midlayer_entrypoint_lock(ahd, &s); - - /* - * First determine if we currently own this command. - * Start by searching the device queue. If not found - * there, check the pending_scb list. If not found - * at all, and the system wanted us to just abort the - * command return success. - */ - dev = ahd_linux_get_device(ahd, cmd->device->channel, - cmd->device->id, cmd->device->lun, - /*alloc*/FALSE); - - if (dev == NULL) { - /* - * No target device for this command exists, - * so we must not still own the command. - */ - printf("%s:%d:%d:%d: Is not an active device\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); - retval = SUCCESS; - goto no_cmd; - } - - TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { - if (list_acmd == acmd) - break; - } - - if (list_acmd != NULL) { - printf("%s:%d:%d:%d: Command found on device queue\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); - TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); - cmd->result = DID_ABORT << 16; - ahd_linux_queue_cmd_complete(ahd, cmd); - retval = SUCCESS; - goto done; - } - - /* - * See if we can find a matching cmd in the pending list. - */ - LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { - if (pending_scb->io_ctx == cmd) - break; - } - - if (pending_scb == NULL) { - printf("%s:%d:%d:%d: Command not found\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); - goto no_cmd; - } - - if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) { - /* - * We can't queue two recovery actions using the same SCB - */ - retval = FAILED; - goto done; - } - - /* - * Ensure that the card doesn't do anything - * behind our back. Also make sure that we - * didn't "just" miss an interrupt that would - * affect this cmd. - */ - ahd_pause_and_flushwork(ahd); - paused = TRUE; - - if ((pending_scb->flags & SCB_ACTIVE) == 0) { - printf("%s:%d:%d:%d: Command already completed\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); - goto no_cmd; - } - - ahd_dump_card_state(ahd); - - disconnected = TRUE; - if (ahd_search_qinfifo(ahd, cmd->device->id, cmd->device->channel + 'A', - cmd->device->lun, pending_scb->hscb->tag, - ROLE_INITIATOR, CAM_REQ_ABORTED, - SEARCH_COMPLETE) > 0) { - printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun); - retval = SUCCESS; - goto done; - } - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - last_phase = ahd_inb(ahd, LASTPHASE); - saved_scbptr = ahd_get_scbptr(ahd); - active_scbptr = saved_scbptr; - if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { - struct scb *bus_scb; - - bus_scb = ahd_lookup_scb(ahd, active_scbptr); - if (bus_scb == pending_scb) - disconnected = FALSE; - } - - /* - * At this point, pending_scb is the scb associated with the - * passed in command. That command is currently active on the - * bus or is in the disconnected state. - */ - if (last_phase != P_BUSFREE - && pending_scb->hscb->tag == active_scbptr) { - - /* - * We're active on the bus, so assert ATN - * and hope that the target responds. - */ - pending_scb = ahd_lookup_scb(ahd, active_scbptr); - pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd_outb(ahd, SCSISIGO, last_phase|ATNO); - printf("%s:%d:%d:%d: Device is active, asserting ATN\n", - ahd_name(ahd), cmd->device->channel, - cmd->device->id, cmd->device->lun); - wait = TRUE; - } else if (disconnected) { - - /* - * Actually re-queue this SCB in an attempt - * to select the device before it reconnects. - */ - pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; - ahd_set_scbptr(ahd, pending_scb->hscb->tag); - pending_scb->hscb->cdb_len = 0; - pending_scb->hscb->task_attribute = 0; - pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK; - - if ((pending_scb->flags & SCB_PACKETIZED) != 0) { - /* - * Mark the SCB has having an outstanding - * task management function. Should the command - * complete normally before the task management - * function can be sent, the host will be notified - * to abort our requeued SCB. - */ - ahd_outb(ahd, SCB_TASK_MANAGEMENT, - pending_scb->hscb->task_management); - } else { - /* - * If non-packetized, set the MK_MESSAGE control - * bit indicating that we desire to send a message. - * We also set the disconnected flag since there is - * no guarantee that our SCB control byte matches - * the version on the card. We don't want the - * sequencer to abort the command thinking an - * unsolicited reselection occurred. - */ - pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED; - - /* - * The sequencer will never re-reference the - * in-core SCB. To make sure we are notified - * during reslection, set the MK_MESSAGE flag in - * the card's copy of the SCB. - */ - ahd_outb(ahd, SCB_CONTROL, - ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE); - } - - /* - * Clear out any entries in the QINFIFO first - * so we are the next SCB for this target - * to run. - */ - ahd_search_qinfifo(ahd, cmd->device->id, - cmd->device->channel + 'A', cmd->device->lun, - SCB_LIST_NULL, ROLE_INITIATOR, - CAM_REQUEUE_REQ, SEARCH_COMPLETE); - ahd_qinfifo_requeue_tail(ahd, pending_scb); - ahd_set_scbptr(ahd, saved_scbptr); - ahd_print_path(ahd, pending_scb); - printf("Device is disconnected, re-queuing SCB\n"); - wait = TRUE; - } else { - printf("%s:%d:%d:%d: Unable to deliver message\n", - ahd_name(ahd), cmd->device->channel, - cmd->device->id, cmd->device->lun); - retval = FAILED; - goto done; - } - -no_cmd: - /* - * Our assumption is that if we don't have the command, no - * recovery action was required, so we return success. Again, - * the semantics of the mid-layer recovery engine are not - * well defined, so this may change in time. - */ - retval = SUCCESS; -done: - if (paused) - ahd_unpause(ahd); - if (wait) { - struct timer_list timer; - int ret; - - ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &s); -#else - spin_unlock_irq(ahd->platform_data->host->host_lock); -#endif - init_timer(&timer); - timer.data = (u_long)ahd; - timer.expires = jiffies + (5 * HZ); - timer.function = ahd_linux_sem_timeout; - add_timer(&timer); - printf("Recovery code sleeping\n"); - down(&ahd->platform_data->eh_sem); - printf("Recovery code awake\n"); - ret = del_timer(&timer); - if (ret == 0) { - printf("Timer Expired\n"); - retval = FAILED; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_lock(ahd, &s); -#else - spin_lock_irq(ahd->platform_data->host->host_lock); -#endif - } - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - ahd_midlayer_entrypoint_unlock(ahd, &s); - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { - ahd_midlayer_entrypoint_lock(ahd, &s); - ahd_schedule_completeq(ahd, acmd); - ahd_midlayer_entrypoint_unlock(ahd, &s); - } - } - ahd_schedule_runq(ahd); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - return (retval); -} - - -static void -ahd_linux_dev_reset_complete(Scsi_Cmnd *cmd) -{ - free(cmd, M_DEVBUF); -} - -/* - * Attempt to send a target reset message to the device that timed out. - */ -static int -ahd_linux_dev_reset(Scsi_Cmnd *cmd) -{ - struct ahd_softc *ahd; - struct scsi_cmnd *recovery_cmd; - struct ahd_linux_device *dev; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - struct scb *scb; - struct hardware_scb *hscb; - struct ahd_cmd *acmd; - u_long s; - struct timer_list timer; - int retval; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irq(&io_request_lock); -#endif - ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - recovery_cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); - memset(recovery_cmd, 0, sizeof(struct scsi_cmnd)); - recovery_cmd->device = cmd->device; - recovery_cmd->scsi_done = ahd_linux_dev_reset_complete; -#if AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) - printf("%s:%d:%d:%d: Device reset called for cmd %p\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->device->lun, cmd); -#endif - ahd_midlayer_entrypoint_lock(ahd, &s); - - dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id, - cmd->device->lun, /*alloc*/FALSE); - if (dev == NULL) { - ahd_midlayer_entrypoint_unlock(ahd, &s); - return (FAILED); - } - if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) { - ahd_midlayer_entrypoint_unlock(ahd, &s); - return (FAILED); - } - tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - cmd->device->id, &tstate); - recovery_cmd->result = CAM_REQ_INPROG << 16; - recovery_cmd->host_scribble = (char *)scb; - scb->io_ctx = recovery_cmd; - scb->platform_data->dev = dev; - scb->sg_count = 0; - ahd_set_residual(scb, 0); - ahd_set_sense_residual(scb, 0); - hscb = scb->hscb; - hscb->control = 0; - hscb->scsiid = BUILD_SCSIID(ahd, cmd); - hscb->lun = cmd->lun; - hscb->cdb_len = 0; - hscb->task_management = SIU_TASKMGMT_LUN_RESET; - scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE; - if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - scb->flags |= SCB_PACKETIZED; - } else { - hscb->control |= MK_MESSAGE; - } - dev->openings--; - dev->active++; - dev->commands_issued++; - LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); - ahd_queue_scb(ahd, scb); - - ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &s); -#else - spin_unlock_irq(ahd->platform_data->host->host_lock); -#endif - init_timer(&timer); - timer.data = (u_long)ahd; - timer.expires = jiffies + (5 * HZ); - timer.function = ahd_linux_sem_timeout; - add_timer(&timer); - printf("Recovery code sleeping\n"); - down(&ahd->platform_data->eh_sem); - printf("Recovery code awake\n"); - retval = SUCCESS; - if (del_timer(&timer) == 0) { - printf("Timer Expired\n"); - retval = FAILED; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_lock(ahd, &s); -#else - spin_lock_irq(ahd->platform_data->host->host_lock); -#endif - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - ahd_midlayer_entrypoint_unlock(ahd, &s); - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { - ahd_midlayer_entrypoint_lock(ahd, &s); - ahd_schedule_completeq(ahd, acmd); - ahd_midlayer_entrypoint_unlock(ahd, &s); - } - } - ahd_schedule_runq(ahd); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval); - return (retval); -} - -/* - * Reset the SCSI bus. - */ -static int -ahd_linux_bus_reset(Scsi_Cmnd *cmd) -{ - struct ahd_softc *ahd; - struct ahd_cmd *acmd; - u_long s; - int found; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irq(&io_request_lock); -#endif - ahd = *(struct ahd_softc **)cmd->device->host->hostdata; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) - printf("%s: Bus reset called for cmd %p\n", - ahd_name(ahd), cmd); -#endif - ahd_midlayer_entrypoint_lock(ahd, &s); - found = ahd_reset_channel(ahd, cmd->channel + 'A', - /*initiate reset*/TRUE); - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - ahd_midlayer_entrypoint_unlock(ahd, &s); - if (bootverbose) - printf("%s: SCSI bus reset delivered. " - "%d SCBs aborted.\n", ahd_name(ahd), found); - - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { - ahd_midlayer_entrypoint_lock(ahd, &s); - ahd_schedule_completeq(ahd, acmd); - ahd_midlayer_entrypoint_unlock(ahd, &s); - } - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - return (SUCCESS); -} - -Scsi_Host_Template aic79xx_driver_template = { - .proc_info = ahd_linux_proc_info, - .detect = ahd_linux_detect, - .release = ahd_linux_release, - .info = ahd_linux_info, - .queuecommand = ahd_linux_queue, - .eh_abort_handler = ahd_linux_abort, - .eh_device_reset_handler = ahd_linux_dev_reset, - .eh_bus_reset_handler = ahd_linux_bus_reset, -#if defined(__i386__) - .bios_param = ahd_linux_biosparam, -#endif - .can_queue = AHD_MAX_QUEUE, - .this_id = -1, - .sg_tablesize = AHD_NSEG, - .cmd_per_lun = 2, - .use_clustering = ENABLE_CLUSTERING, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) - /* - * We can only map 16MB per-SG - * so create a sector limit of - * "16MB" in 2K sectors. - */ - .max_sectors = 8192, -#endif -#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) -/* Assume RedHat Distribution with its different HIGHIO conventions. */ - .can_dma_32 = 1, - .single_sg_okay = 1, -#else - .highmem_io = 1, -#endif -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - .name = "aic79xx", - .slave_alloc = ahd_linux_slave_alloc, - .slave_configure = ahd_linux_slave_configure, - .slave_destroy = ahd_linux_slave_destroy, -#else - .select_queue_depths = ahd_linux_select_queue_depth, - .use_new_eh_code = 1, -#endif -}; - -#define driver_template aic79xx_driver_template -#include "scsi_module.c" -/**************************** Tasklet Handler *********************************/ - -static void -ahd_runq_tasklet(unsigned long data) -{ - struct ahd_softc* ahd; - struct ahd_linux_device *dev; - u_long flags; - - ahd = (struct ahd_softc *)data; - ahd_lock(ahd, &flags); - while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { - - TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); - dev->flags &= ~AHD_DEV_ON_RUN_LIST; - ahd_linux_check_device_queue(ahd, dev); - /* Yeild to our interrupt handler */ - ahd_unlock(ahd, &flags); - ahd_lock(ahd, &flags); - } - ahd_unlock(ahd, &flags); -} - -/************************ Shutdown/halt/reboot hook ***************************/ -#include -#include - -static struct notifier_block ahd_linux_notifier = { - ahd_linux_halt, NULL, 0 -}; - -static int ahd_linux_halt(struct notifier_block *nb, u_long event, void *buf) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - struct ahd_softc *ahd; - - /* - * In 2.5.X, this is called prior to the filesystems - * being synced and the SCSI layer being properly - * shutdown. A different API is required there, - * but the device hooks for this don't quite look - * right. - */ - if (event == SYS_DOWN || event == SYS_HALT) { - TAILQ_FOREACH(ahd, &ahd_tailq, links) { - ahd_shutdown(ahd); - } - } -#endif - return (NOTIFY_OK); -} - -/******************************** Bus DMA *************************************/ -int -ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, - bus_size_t alignment, bus_size_t boundary, - bus_addr_t lowaddr, bus_addr_t highaddr, - bus_dma_filter_t *filter, void *filterarg, - bus_size_t maxsize, int nsegments, - bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) -{ - bus_dma_tag_t dmat; - - dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT); - if (dmat == NULL) - return (ENOMEM); - - /* - * Linux is very simplistic about DMA memory. For now don't - * maintain all specification information. Once Linux supplies - * better facilities for doing these operations, or the - * needs of this particular driver change, we might need to do - * more here. - */ - dmat->alignment = alignment; - dmat->boundary = boundary; - dmat->maxsize = maxsize; - *ret_tag = dmat; - return (0); -} - -void -ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat) -{ - free(dmat, M_DEVBUF); -} - -int -ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr, - int flags, bus_dmamap_t *mapp) -{ - bus_dmamap_t map; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); - if (map == NULL) - return (ENOMEM); - /* - * Although we can dma data above 4GB, our - * "consistent" memory is below 4GB for - * space efficiency reasons (only need a 4byte - * address). For this reason, we have to reset - * our dma mask when doing allocations. - */ - if (ahd->dev_softc != NULL) - ahd_pci_set_dma_mask(ahd->dev_softc, 0xFFFFFFFF); - *vaddr = pci_alloc_consistent(ahd->dev_softc, - dmat->maxsize, &map->bus_addr); - if (ahd->dev_softc != NULL) - ahd_pci_set_dma_mask(ahd->dev_softc, - ahd->platform_data->hw_dma_mask); -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ - /* - * At least in 2.2.14, malloc is a slab allocator so all - * allocations are aligned. We assume for these kernel versions - * that all allocations will be bellow 4Gig, physically contiguous, - * and accessable via DMA by the controller. - */ - map = NULL; /* No additional information to store */ - *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); -#endif - if (*vaddr == NULL) - return (ENOMEM); - *mapp = map; - return(0); -} - -void -ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat, - void* vaddr, bus_dmamap_t map) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - pci_free_consistent(ahd->dev_softc, dmat->maxsize, - vaddr, map->bus_addr); -#else - free(vaddr, M_DEVBUF); -#endif -} - -int -ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map, - void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, - void *cb_arg, int flags) -{ - /* - * Assume for now that this will only be used during - * initialization and not for per-transaction buffer mapping. - */ - bus_dma_segment_t stack_sg; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - stack_sg.ds_addr = map->bus_addr; -#else -#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a)) - stack_sg.ds_addr = VIRT_TO_BUS(buf); -#endif - stack_sg.ds_len = dmat->maxsize; - cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); - return (0); -} - -void -ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map) -{ - /* - * The map may is NULL in our < 2.3.X implementation. - */ - if (map != NULL) - free(map, M_DEVBUF); -} - -int -ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map) -{ - /* Nothing to do */ - return (0); -} - -/********************* Platform Dependent Functions ***************************/ -int -ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd) -{ - int value; - char primary_channel; - - /* - * Under Linux, cards are ordered as follows: - * 1) PCI devices with BIOS enabled sorted by bus/slot/func. - * 2) All remaining PCI devices sorted by bus/slot/func. - */ - value = (lahd->flags & AHD_BIOS_ENABLED) - - (rahd->flags & AHD_BIOS_ENABLED); - if (value != 0) - /* Controllers with BIOS enabled have a *higher* priority */ - return (-value); - - /* Still equal. Sort by bus/slot/func. */ - if (aic79xx_reverse_scan != 0) - value = ahd_get_pci_bus(rahd->dev_softc) - - ahd_get_pci_bus(lahd->dev_softc); - else - value = ahd_get_pci_bus(lahd->dev_softc) - - ahd_get_pci_bus(rahd->dev_softc); - if (value != 0) - return (value); - if (aic79xx_reverse_scan != 0) - value = ahd_get_pci_slot(rahd->dev_softc) - - ahd_get_pci_slot(lahd->dev_softc); - else - value = ahd_get_pci_slot(lahd->dev_softc) - - ahd_get_pci_slot(rahd->dev_softc); - if (value != 0) - return (value); - - /* - * On multi-function devices, the user can choose - * to have function 1 probed before function 0. - * Give whichever channel is the primary channel - * the lowest priority. - */ - primary_channel = (lahd->flags & AHD_PRIMARY_CHANNEL) + 'A'; - value = 1; - if (lahd->channel == primary_channel) - value = -1; - return (value); -} - -static void -ahd_linux_setup_tag_info(char *p, char *end, char *s) -{ - char *base; - char *tok; - char *tok_end; - char *tok_end2; - int i; - int instance; - int targ; - int done; - char tok_list[] = {'.', ',', '{', '}', '\0'}; - - if (*p != ':') - return; - - instance = -1; - targ = -1; - done = FALSE; - base = p; - /* Forward us just past the ':' */ - tok = base + 1; - tok_end = strchr(tok, '\0'); - if (tok_end < end) - *tok_end = ','; - while (!done) { - switch (*tok) { - case '{': - if (instance == -1) - instance = 0; - else if (targ == -1) - targ = 0; - tok++; - break; - case '}': - if (targ != -1) - targ = -1; - else if (instance != -1) - instance = -1; - tok++; - break; - case ',': - case '.': - if (instance == -1) - done = TRUE; - else if (targ >= 0) - targ++; - else if (instance >= 0) - instance++; - if ((targ >= AHD_NUM_TARGETS) || - (instance >= NUM_ELEMENTS(aic79xx_tag_info))) - done = TRUE; - tok++; - if (!done) { - base = tok; - } - break; - case '\0': - done = TRUE; - break; - default: - done = TRUE; - tok_end = strchr(tok, '\0'); - for (i = 0; tok_list[i]; i++) { - tok_end2 = strchr(tok, tok_list[i]); - if ((tok_end2) && (tok_end2 < tok_end)) { - tok_end = tok_end2; - done = FALSE; - } - } - if ((instance >= 0) && (targ >= 0) - && (instance < NUM_ELEMENTS(aic79xx_tag_info)) - && (targ < AHD_NUM_TARGETS)) { - aic79xx_tag_info[instance].tag_commands[targ] = - simple_strtoul(tok, NULL, 0) & 0xff; - } - tok = tok_end; - break; - } - } - while ((p != base) && (p != NULL)) - p = strsep(&s, ",."); -} - -static void -ahd_linux_setup_rd_strm_info(char *p, char *end, char *s) -{ - char *base; - char *tok; - char *tok_end; - char *tok_end2; - int i; - int instance; - int done; - char tok_list[] = {'.', ',', '{', '}', '\0'}; - - if (*p != ':') - return; - - instance = -1; - done = FALSE; - base = p; - /* Forward us just past the ':' */ - tok = base + 1; - tok_end = strchr(tok, '\0'); - if (tok_end < end) - *tok_end = ','; - while (!done) { - switch (*tok) { - case '{': - if (instance == -1) - instance = 0; - tok++; - break; - case '}': - if (instance != -1) - instance = -1; - tok++; - break; - case ',': - case '.': - if (instance == -1) - done = TRUE; - else if (instance >= 0) - instance++; - if (instance >= NUM_ELEMENTS(aic79xx_rd_strm_info)) - done = TRUE; - tok++; - if (!done) { - base = tok; - } - break; - case '\0': - done = TRUE; - break; - default: - done = TRUE; - tok_end = strchr(tok, '\0'); - for (i = 0; tok_list[i]; i++) { - tok_end2 = strchr(tok, tok_list[i]); - if ((tok_end2) && (tok_end2 < tok_end)) { - tok_end = tok_end2; - done = FALSE; - } - } - if ((instance >= 0) - && (instance < NUM_ELEMENTS(aic79xx_rd_strm_info))) { - aic79xx_rd_strm_info[instance] = - simple_strtoul(tok, NULL, 0) & 0xffff; - } - tok = tok_end; - break; - } - } - while ((p != base) && (p != NULL)) - p = strsep(&s, ",."); -} - -static void -ahd_linux_setup_dv(char *p, char *end, char *s) -{ - char *base; - char *tok; - char *tok_end; - char *tok_end2; - int i; - int instance; - int done; - char tok_list[] = {'.', ',', '{', '}', '\0'}; - - if (*p != ':') - return; - - instance = -1; - done = FALSE; - base = p; - /* Forward us just past the ':' */ - tok = base + 1; - tok_end = strchr(tok, '\0'); - if (tok_end < end) - *tok_end = ','; - while (!done) { - switch (*tok) { - case '{': - if (instance == -1) - instance = 0; - tok++; - break; - case '}': - if (instance != -1) - instance = -1; - tok++; - break; - case ',': - case '.': - if (instance == -1) - done = TRUE; - else if (instance >= 0) - instance++; - if (instance >= NUM_ELEMENTS(aic79xx_dv_settings)) - done = TRUE; - tok++; - if (!done) { - base = tok; - } - break; - case '\0': - done = TRUE; - break; - default: - done = TRUE; - tok_end = strchr(tok, '\0'); - for (i = 0; tok_list[i]; i++) { - tok_end2 = strchr(tok, tok_list[i]); - if ((tok_end2) && (tok_end2 < tok_end)) { - tok_end = tok_end2; - done = FALSE; - } - } - if ((instance >= 0) - && (instance < NUM_ELEMENTS(aic79xx_dv_settings))) { - aic79xx_dv_settings[instance] = - simple_strtol(tok, NULL, 0); - } - tok = tok_end; - break; - } - } - while ((p != base) && (p != NULL)) - p = strsep(&s, ",."); -} - -static void -ahd_linux_setup_iocell_info(char *p, char *end, char *s, int index) -{ - char *base; - char *tok; - char *tok_end; - char *tok_end2; - uint8_t *iocell_info; - int i; - int instance; - int done; - char tok_list[] = {'.', ',', '{', '}', '\0'}; - - if (*p != ':') - return; - - instance = -1; - done = FALSE; - base = p; - /* Forward us just past the ':' */ - tok = base + 1; - tok_end = strchr(tok, '\0'); - if (tok_end < end) - *tok_end = ','; - while (!done) { - switch (*tok) { - case '{': - if (instance == -1) - instance = 0; - tok++; - break; - case '}': - if (instance != -1) - instance = -1; - tok++; - break; - case ',': - case '.': - if (instance == -1) - done = TRUE; - else if (instance >= 0) - instance++; - if (instance >= NUM_ELEMENTS(aic79xx_iocell_info)) - done = TRUE; - tok++; - if (!done) { - base = tok; - } - break; - case '\0': - done = TRUE; - break; - default: - done = TRUE; - tok_end = strchr(tok, '\0'); - for (i = 0; tok_list[i]; i++) { - tok_end2 = strchr(tok, tok_list[i]); - if ((tok_end2) && (tok_end2 < tok_end)) { - tok_end = tok_end2; - done = FALSE; - } - } - if ((instance >= 0) - && (instance < NUM_ELEMENTS(aic79xx_iocell_info))) { - iocell_info = - (uint8_t*)&aic79xx_iocell_info[instance]; - iocell_info[index] = - simple_strtoul(tok, NULL, 0) & 0xffff; - } - tok = tok_end; - break; - } - } - while ((p != base) && (p != NULL)) - p = strsep(&s, ",."); -} - -static void -ahd_linux_setup_tag_info_global(char *p) -{ - int tags, i, j; - - tags = simple_strtoul(p + 1, NULL, 0) & 0xff; - printf("Setting Global Tags= %d\n", tags); - - for (i = 0; i < NUM_ELEMENTS(aic79xx_tag_info); i++) { - for (j = 0; j < AHD_NUM_TARGETS; j++) { - aic79xx_tag_info[i].tag_commands[j] = tags; - } - } -} - -/* - * Handle Linux boot parameters. This routine allows for assigning a value - * to a parameter with a ':' between the parameter and the value. - * ie. aic79xx=stpwlev:1,extended - */ -static int -aic79xx_setup(char *s) -{ - int i, n; - char *p; - char *end; - - static struct { - const char *name; - uint32_t *flag; - } options[] = { - { "extended", &aic79xx_extended }, - { "no_reset", &aic79xx_no_reset }, - { "verbose", &aic79xx_verbose }, - { "allow_memio", &aic79xx_allow_memio}, -#ifdef AHD_DEBUG - { "debug", &ahd_debug }, -#endif - { "reverse_scan", &aic79xx_reverse_scan }, - { "periodic_otag", &aic79xx_periodic_otag }, - { "pci_parity", &aic79xx_pci_parity }, - { "seltime", &aic79xx_seltime }, - { "tag_info", NULL }, - { "global_tag_depth", NULL}, - { "rd_strm", NULL }, - { "dv", NULL }, - { "slewrate", NULL }, - { "precomp", NULL }, - { "amplitude", NULL }, - }; - - end = strchr(s, '\0'); - - while ((p = strsep(&s, ",.")) != NULL) { - if (*p == '\0') - continue; - for (i = 0; i < NUM_ELEMENTS(options); i++) { - n = strlen(options[i].name); - - if (strncmp(options[i].name, p, n) != 0) - continue; - - if (!strncmp(p, "global_tag_depth", n)) { - ahd_linux_setup_tag_info_global(p + n); - } else if (!strncmp(p, "tag_info", n)) { - ahd_linux_setup_tag_info(p + n, end, s); - } else if (strncmp(p, "rd_strm", n) == 0) { - ahd_linux_setup_rd_strm_info(p + n, end, s); - } else if (strncmp(p, "dv", n) == 0) { - ahd_linux_setup_dv(p + n, end, s); - } else if (strncmp(p, "slewrate", n) == 0) { - ahd_linux_setup_iocell_info(p + n, end, s, - AIC79XX_SLEWRATE_INDEX); - } else if (strncmp(p, "precomp", n) == 0) { - ahd_linux_setup_iocell_info(p + n, end, s, - AIC79XX_PRECOMP_INDEX); - } else if (strncmp(p, "amplitude", n) == 0) { - ahd_linux_setup_iocell_info(p + n, end, s, - AIC79XX_AMPLITUDE_INDEX); - } else if (p[n] == ':') { - *(options[i].flag) = - simple_strtoul(p + n + 1, NULL, 0); - } else if (!strncmp(p, "verbose", n)) { - *(options[i].flag) = 1; - } else { - *(options[i].flag) = ~(*(options[i].flag)); - } - break; - } - } - return 1; -} - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) -__setup("aic79xx=", aic79xx_setup); -#endif - -int aic79xx_verbose; - -int -ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) -{ - char buf[80]; - struct Scsi_Host *host; - char *new_name; - u_long s; - u_long target; - - template->name = ahd->description; - host = scsi_register(template, sizeof(struct ahd_softc *)); - if (host == NULL) - return (ENOMEM); - - *((struct ahd_softc **)host->hostdata) = ahd; - ahd_lock(ahd, &s); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - scsi_assign_lock(host, &ahd->platform_data->spin_lock); -#endif - ahd->platform_data->host = host; - host->can_queue = AHD_MAX_QUEUE; - host->cmd_per_lun = 2; - host->sg_tablesize = AHD_NSEG; - host->this_id = ahd->our_id; - host->irq = ahd->platform_data->irq; - host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8; - host->max_lun = AHD_NUM_LUNS; - host->max_channel = 0; - ahd_set_unit(ahd, ahd_linux_next_unit()); - sprintf(buf, "scsi%d", host->host_no); - new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); - if (new_name != NULL) { - strcpy(new_name, buf); - ahd_set_name(ahd, new_name); - } - host->unique_id = ahd->unit; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) - scsi_set_pci_device(host, ahd->dev_softc); -#endif - ahd_linux_initialize_scsi_bus(ahd); - ahd_unlock(ahd, &s); - ahd->platform_data->dv_pid = kernel_thread(ahd_linux_dv_thread, ahd, 0); - ahd_lock(ahd, &s); - if (ahd->platform_data->dv_pid < 0) { - printf("%s: Failed to create DV thread, error= %d\n", - ahd_name(ahd), ahd->platform_data->dv_pid); - return (-ahd->platform_data->dv_pid); - } - /* - * Initially allocate *all* of our linux target objects - * so that the DV thread will scan them all in parallel - * just after driver initialization. Any device that - * does not exist will have its target object destroyed - * by the selection timeout handler. In the case of a - * device that appears after the initial DV scan, async - * negotiation will occur for the first command, and DV - * will comence should that first command be successful. - */ - for (target = 0; target < host->max_id; target++) - ahd_linux_alloc_target(ahd, 0, target); - ahd_intr_enable(ahd, TRUE); - ahd_linux_start_dv(ahd); - ahd_unlock(ahd, &s); - return (0); -} - -uint64_t -ahd_linux_get_memsize() -{ - struct sysinfo si; - - si_meminfo(&si); - return ((uint64_t)si.totalram << PAGE_SHIFT); -} - -/* - * Find the smallest available unit number to use - * for a new device. We don't just use a static - * count to handle the "repeated hot-(un)plug" - * scenario. - */ -static int -ahd_linux_next_unit() -{ - struct ahd_softc *ahd; - int unit; - - unit = 0; -retry: - TAILQ_FOREACH(ahd, &ahd_tailq, links) { - if (ahd->unit == unit) { - unit++; - goto retry; - } - } - return (unit); -} - -/* - * Place the SCSI bus into a known state by either resetting it, - * or forcing transfer negotiations on the next command to any - * target. - */ -static void -ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd) -{ - u_int target_id; - u_int numtarg; - - target_id = 0; - numtarg = 0; - - if (aic79xx_no_reset != 0) - ahd->flags &= ~AHD_RESET_BUS_A; - - if ((ahd->flags & AHD_RESET_BUS_A) != 0) - ahd_reset_channel(ahd, 'A', /*initiate_reset*/TRUE); - else - numtarg = (ahd->features & AHD_WIDE) ? 16 : 8; - - /* - * Force negotiation to async for all targets that - * will not see an initial bus reset. - */ - for (; target_id < numtarg; target_id++) { - struct ahd_devinfo devinfo; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - - tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - target_id, &tstate); - ahd_compile_devinfo(&devinfo, ahd->our_id, target_id, - CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR); - ahd_update_neg_request(ahd, &devinfo, tstate, - tinfo, AHD_NEG_ALWAYS); - } - /* Give the bus some time to recover */ - if ((ahd->flags & AHD_RESET_BUS_A) != 0) { - ahd_freeze_simq(ahd); - init_timer(&ahd->platform_data->reset_timer); - ahd->platform_data->reset_timer.data = (u_long)ahd; - ahd->platform_data->reset_timer.expires = - jiffies + (AIC79XX_RESET_DELAY * HZ)/1000; - ahd->platform_data->reset_timer.function = - (ahd_linux_callback_t *)ahd_release_simq; - add_timer(&ahd->platform_data->reset_timer); - } -} - -int -ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) -{ - ahd->platform_data = - malloc(sizeof(struct ahd_platform_data), M_DEVBUF, M_NOWAIT); - if (ahd->platform_data == NULL) - return (ENOMEM); - memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); - TAILQ_INIT(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->device_runq); - ahd->platform_data->irq = AHD_LINUX_NOIRQ; - ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; - ahd_lockinit(ahd); - ahd_done_lockinit(ahd); - init_timer(&ahd->platform_data->completeq_timer); - ahd->platform_data->completeq_timer.data = (u_long)ahd; - ahd->platform_data->completeq_timer.function = - (ahd_linux_callback_t *)ahd_linux_thread_run_complete_queue; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - init_MUTEX_LOCKED(&ahd->platform_data->eh_sem); - init_MUTEX_LOCKED(&ahd->platform_data->dv_sem); - init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem); -#else - ahd->platform_data->eh_sem = MUTEX_LOCKED; - ahd->platform_data->dv_sem = MUTEX_LOCKED; - ahd->platform_data->dv_cmd_sem = MUTEX_LOCKED; -#endif - ahd_setup_runq_tasklet(ahd); - ahd->seltime = (aic79xx_seltime & 0x3) << 4; - if (TAILQ_EMPTY(&ahd_tailq)) - register_reboot_notifier(&ahd_linux_notifier); - return (0); -} - -void -ahd_platform_free(struct ahd_softc *ahd) -{ - struct ahd_linux_target *targ; - struct ahd_linux_device *dev; - u_long s; - int i, j; - - if (ahd->platform_data != NULL) { - /* Kill the DV kthread */ - if (ahd->platform_data->dv_pid != 0) { - ahd_lock(ahd, &s); - ahd->platform_data->flags |= AHD_DV_SHUTDOWN; - ahd_unlock(ahd, &s); - up(&ahd->platform_data->dv_sem); - do { -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - printf("%s: Waiting for DV thread to " - "exit\n", ahd_name(ahd)); - } -#endif - } while (waitpid(ahd->platform_data->dv_pid, NULL, - __WCLONE) == -ERESTARTSYS); - } - ahd_teardown_runq_tasklet(ahd); - if (ahd->platform_data->host != NULL) - scsi_unregister(ahd->platform_data->host); - - /* destroy all of the device and target objects */ - for (i = 0; i < AHD_NUM_TARGETS; i++) { - targ = ahd->platform_data->targets[i]; - if (targ != NULL) { - for (j = 0; j < AHD_NUM_LUNS; j++) { - if (targ->devices[j] != NULL) { - dev = targ->devices[j]; - ahd_linux_free_device(ahd, dev); - } - if (ahd->platform_data->targets[i] == - NULL) - break; - } - } - } - - if (ahd->platform_data->irq != AHD_LINUX_NOIRQ) - free_irq(ahd->platform_data->irq, ahd); - if (ahd->tags[0] == BUS_SPACE_PIO - && ahd->bshs[0].ioport != 0) - release_region(ahd->bshs[0].ioport, 256); - if (ahd->tags[1] == BUS_SPACE_PIO - && ahd->bshs[1].ioport != 0) - release_region(ahd->bshs[1].ioport, 256); - if (ahd->tags[0] == BUS_SPACE_MEMIO - && ahd->bshs[0].maddr != NULL) { - u_long base_addr; - - base_addr = (u_long)ahd->bshs[0].maddr; - base_addr &= PAGE_MASK; - iounmap((void *)base_addr); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - release_mem_region(ahd->platform_data->mem_busaddr, - 0x1000); -#endif - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - /* XXX Need an instance detach in the PCI code */ - if (ahd->dev_softc != NULL) - ahd->dev_softc->driver = NULL; -#endif - free(ahd->platform_data, M_DEVBUF); - } - if (TAILQ_EMPTY(&ahd_tailq)) { - unregister_reboot_notifier(&ahd_linux_notifier); -#ifdef CONFIG_PCI -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - pci_unregister_driver(&aic79xx_pci_driver); -#endif -#endif - } -} - -void -ahd_platform_init(struct ahd_softc *ahd) -{ - /* - * Lookup and commit any modified IO Cell options. - */ - if (ahd->unit < NUM_ELEMENTS(aic79xx_iocell_info)) { - struct ahd_linux_iocell_opts *iocell_opts; - - iocell_opts = &aic79xx_iocell_info[ahd->unit]; - if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP) - AHD_SET_PRECOMP(ahd, iocell_opts->precomp); - if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE) - AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate); - if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE) - AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude); - } - -} - -void -ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb) -{ - ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), - SCB_GET_CHANNEL(ahd, scb), - SCB_GET_LUN(scb), SCB_LIST_NULL, - ROLE_UNKNOWN, CAM_REQUEUE_REQ); -} - -void -ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - ahd_queue_alg alg) -{ - struct ahd_linux_device *dev; - int was_queuing; - int now_queuing; - - dev = ahd_linux_get_device(ahd, devinfo->channel - 'A', - devinfo->target, - devinfo->lun, /*alloc*/FALSE); - if (dev == NULL) - return; - was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED); - now_queuing = alg != AHD_QUEUE_NONE; - if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0 - && (was_queuing != now_queuing) - && (dev->active != 0)) { - dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY; - dev->qfrozen++; - } - - dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG); - if (now_queuing) { - u_int usertags; - - usertags = ahd_linux_user_tagdepth(ahd, devinfo); - if (!was_queuing) { - /* - * Start out agressively and allow our - * dynamic queue depth algorithm to take - * care of the rest. - */ - dev->maxtags = usertags; - dev->openings = dev->maxtags - dev->active; - } - if (dev->maxtags == 0) { - /* - * Queueing is disabled by the user. - */ - dev->openings = 1; - } else if (alg == AHD_QUEUE_TAGGED) { - dev->flags |= AHD_DEV_Q_TAGGED; - if (aic79xx_periodic_otag != 0) - dev->flags |= AHD_DEV_PERIODIC_OTAG; - } else - dev->flags |= AHD_DEV_Q_BASIC; - } else { - /* We can only have one opening. */ - dev->maxtags = 0; - dev->openings = 1 - dev->active; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - if (dev->scsi_device != NULL) { - switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { - case AHD_DEV_Q_BASIC: - scsi_adjust_queue_depth(dev->scsi_device, - MSG_SIMPLE_TASK, - dev->openings + dev->active); - break; - case AHD_DEV_Q_TAGGED: - scsi_adjust_queue_depth(dev->scsi_device, - MSG_ORDERED_TASK, - dev->openings + dev->active); - break; - default: - /* - * We allow the OS to queue 2 untagged transactions to - * us at any time even though we can only execute them - * serially on the controller/device. This should - * remove some latency. - */ - scsi_adjust_queue_depth(dev->scsi_device, - /*NON-TAGGED*/0, - /*queue depth*/2); - break; - } - } -#endif -} - -int -ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel, - int lun, u_int tag, role_t role, uint32_t status) -{ - int targ; - int maxtarg; - int maxlun; - int clun; - int count; - - if (tag != SCB_LIST_NULL) - return (0); - - targ = 0; - if (target != CAM_TARGET_WILDCARD) { - targ = target; - maxtarg = targ + 1; - } else { - maxtarg = (ahd->features & AHD_WIDE) ? 16 : 8; - } - clun = 0; - if (lun != CAM_LUN_WILDCARD) { - clun = lun; - maxlun = clun + 1; - } else { - maxlun = AHD_NUM_LUNS; - } - - count = 0; - for (; targ < maxtarg; targ++) { - - for (; clun < maxlun; clun++) { - struct ahd_linux_device *dev; - struct ahd_busyq *busyq; - struct ahd_cmd *acmd; - - dev = ahd_linux_get_device(ahd, /*chan*/0, targ, - clun, /*alloc*/FALSE); - if (dev == NULL) - continue; - - busyq = &dev->busyq; - while ((acmd = TAILQ_FIRST(busyq)) != NULL) { - Scsi_Cmnd *cmd; - - cmd = &acmd_scsi_cmd(acmd); - TAILQ_REMOVE(busyq, acmd, - acmd_links.tqe); - count++; - cmd->result = status << 16; - ahd_linux_queue_cmd_complete(ahd, cmd); - } - } - } - - return (count); -} - -static void -ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd) -{ - struct ahd_cmd *acmd; - u_long flags; - - ahd_lock(ahd, &flags); - del_timer(&ahd->platform_data->completeq_timer); - ahd->platform_data->flags &= ~AHD_RUN_CMPLT_Q_TIMER; - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_lock(ahd, &flags); -#endif - ahd_schedule_completeq(ahd, acmd); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif - } - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif -} - -static void -ahd_linux_start_dv(struct ahd_softc *ahd) -{ - - /* - * Freeze the simq and signal ahd_linux_queue to not let any - * more commands through - */ - if ((ahd->platform_data->flags & AHD_DV_ACTIVE) == 0) { -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) - printf("%s: Starting DV\n", ahd_name(ahd)); -#endif - - ahd->platform_data->flags |= AHD_DV_ACTIVE; - ahd_freeze_simq(ahd); - - /* Wake up the DV kthread */ - up(&ahd->platform_data->dv_sem); - } -} - -static int -ahd_linux_dv_thread(void *data) -{ - struct ahd_softc *ahd; - int target; - u_long s; - - ahd = (struct ahd_softc *)data; - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) - printf("In DV Thread\n"); -#endif - - /* - * Don't care about any signals. - */ - siginitsetinv(¤t->blocked, 0); - - /* - * Complete thread creation. - */ - lock_kernel(); - daemonize(); - sprintf(current->comm, "ahd_dv_%d", ahd->unit); - unlock_kernel(); - - while (1) { - /* - * Use down_interruptible() rather than down() to - * avoid inclusion in the load average. - */ - down_interruptible(&ahd->platform_data->dv_sem); - - /* Check to see if we've been signaled to exit */ - ahd_lock(ahd, &s); - if ((ahd->platform_data->flags & AHD_DV_SHUTDOWN) != 0) { - ahd_unlock(ahd, &s); - return (0); - } - ahd_unlock(ahd, &s); - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) - printf("%s: Beginning Domain Validation\n", - ahd_name(ahd)); -#endif - - /* - * Wait for any pending commands to drain before proceeding. - */ - ahd_lock(ahd, &s); - while (LIST_FIRST(&ahd->pending_scbs) != NULL) { - ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_EMPTY; - ahd_unlock(ahd, &s); - down_interruptible(&ahd->platform_data->dv_sem); - ahd_lock(ahd, &s); - } - - /* - * Wait for the SIMQ to be released so that DV is the - * only reason the queue is frozen. - */ - while (AHD_DV_SIMQ_FROZEN(ahd) == 0) { - ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE; - ahd_unlock(ahd, &s); - down_interruptible(&ahd->platform_data->dv_sem); - ahd_lock(ahd, &s); - } - ahd_unlock(ahd, &s); - - for (target = 0; target < AHD_NUM_TARGETS; target++) - ahd_linux_dv_target(ahd, target); - - ahd_lock(ahd, &s); - ahd->platform_data->flags &= ~AHD_DV_ACTIVE; - ahd_unlock(ahd, &s); - - /* - * Release the SIMQ so that normal commands are - * allowed to continue on the bus. - */ - ahd_release_simq(ahd); - } - - return (0); -} - -#define AHD_LINUX_DV_INQ_SHORT_LEN 36 -#define AHD_LINUX_DV_INQ_LEN 256 -#define AHD_LINUX_DV_TIMEOUT (HZ / 4) - -#define AHD_SET_DV_STATE(ahd, targ, newstate) \ - ahd_set_dv_state(ahd, targ, newstate, __LINE__) - -static __inline void -ahd_set_dv_state(struct ahd_softc *ahd, struct ahd_linux_target *targ, - ahd_dv_state newstate, u_int line) -{ - ahd_dv_state oldstate; - - oldstate = targ->dv_state; -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) - printf("%s:%d: Going from state %d to state %d\n", - ahd_name(ahd), line, oldstate, newstate); -#endif - - if (oldstate == newstate) - targ->dv_state_retry++; - else - targ->dv_state_retry = 0; - targ->dv_state = newstate; -} - -static void -ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset) -{ - struct ahd_devinfo devinfo; - struct ahd_linux_target *targ; - struct scsi_cmnd *cmd; - struct scsi_device *scsi_dev; - struct scsi_sense_data *sense; - uint8_t *buffer; - u_long s; - u_int timeout; - int echo_size; - - sense = NULL; - buffer = NULL; - echo_size = 0; - ahd_lock(ahd, &s); - targ = ahd->platform_data->targets[target_offset]; - if (targ == NULL || (targ->flags & AHD_DV_REQUIRED) == 0) { - ahd_unlock(ahd, &s); - return; - } - ahd_compile_devinfo(&devinfo, ahd->our_id, targ->target, /*lun*/0, - targ->channel + 'A', ROLE_INITIATOR); -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, &devinfo); - printf("Performing DV\n"); - } -#endif - - ahd_unlock(ahd, &s); - - cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); - scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK); - scsi_dev->host = ahd->platform_data->host; - scsi_dev->id = devinfo.target; - scsi_dev->lun = devinfo.lun; - scsi_dev->channel = devinfo.channel - 'A'; - ahd->platform_data->dv_scsi_dev = scsi_dev; - - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_SHORT_ASYNC); - - while (targ->dv_state != AHD_DV_STATE_EXIT) { - timeout = AHD_LINUX_DV_TIMEOUT; - switch (targ->dv_state) { - case AHD_DV_STATE_INQ_SHORT_ASYNC: - case AHD_DV_STATE_INQ_ASYNC: - case AHD_DV_STATE_INQ_ASYNC_VERIFY: - /* - * Set things to async narrow to reduce the - * chance that the INQ will fail. - */ - ahd_lock(ahd, &s); - ahd_set_syncrate(ahd, &devinfo, 0, 0, 0, - AHD_TRANS_GOAL, /*paused*/FALSE); - ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_GOAL, /*paused*/FALSE); - ahd_unlock(ahd, &s); - timeout = 10 * HZ; - targ->flags &= ~AHD_INQ_VALID; - /* FALLTHROUGH */ - case AHD_DV_STATE_INQ_VERIFY: - { - u_int inq_len; - - if (targ->dv_state == AHD_DV_STATE_INQ_SHORT_ASYNC) - inq_len = AHD_LINUX_DV_INQ_SHORT_LEN; - else - inq_len = targ->inq_data->additional_length + 5; - ahd_linux_dv_inq(ahd, cmd, &devinfo, targ, inq_len); - break; - } - case AHD_DV_STATE_TUR: - case AHD_DV_STATE_BUSY: - ahd_linux_dv_tur(ahd, cmd, &devinfo); - break; - case AHD_DV_STATE_REBD: - ahd_linux_dv_rebd(ahd, cmd, &devinfo, targ); - break; - case AHD_DV_STATE_WEB: - ahd_linux_dv_web(ahd, cmd, &devinfo, targ); - break; - - case AHD_DV_STATE_REB: - ahd_linux_dv_reb(ahd, cmd, &devinfo, targ); - break; - - case AHD_DV_STATE_SU: - ahd_linux_dv_su(ahd, cmd, &devinfo, targ); - timeout = 50 * HZ; - break; - - default: - ahd_print_devinfo(ahd, &devinfo); - printf("Unknown DV state %d\n", targ->dv_state); - goto out; - } - - /* Queue the command and wait for it to complete */ - /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */ - init_timer(&cmd->eh_timeout); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) - /* - * All of the printfs during negotiation - * really slow down the negotiation. - * Add a bit of time just to be safe. - */ - timeout += HZ; -#endif - scsi_add_timer(cmd, timeout, ahd_linux_dv_timeout); - /* - * In 2.5.X, it is assumed that all calls from the - * "midlayer" (which we are emulating) will have the - * ahd host lock held. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - ahd_lock(ahd, &s); -#endif - ahd_linux_queue(cmd, ahd_linux_dv_complete); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &s); -#endif - down_interruptible(&ahd->platform_data->dv_cmd_sem); - /* - * Wait for the SIMQ to be released so that DV is the - * only reason the queue is frozen. - */ - ahd_lock(ahd, &s); - while (AHD_DV_SIMQ_FROZEN(ahd) == 0) { - ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE; - ahd_unlock(ahd, &s); - down_interruptible(&ahd->platform_data->dv_sem); - ahd_lock(ahd, &s); - } - ahd_unlock(ahd, &s); - - ahd_linux_dv_transition(ahd, cmd, &devinfo, targ); - } - -out: - if ((targ->flags & AHD_INQ_VALID) != 0 - && ahd_linux_get_device(ahd, devinfo.channel - 'A', - devinfo.target, devinfo.lun, - /*alloc*/FALSE) == NULL) { - /* - * The DV state machine failed to configure this device. - * This is normal if DV is disabled. Since we have inquiry - * data, filter it and use the "optimistic" negotiation - * parameters found in the inquiry string. - */ - ahd_linux_filter_inquiry(ahd, &devinfo); - if ((targ->flags & (AHD_BASIC_DV|AHD_ENHANCED_DV)) != 0) { - ahd_print_devinfo(ahd, &devinfo); - printf("DV failed to configure device. " - "Please file a bug report against " - "this driver.\n"); - } - } - - if (cmd != NULL) - free(cmd, M_DEVBUF); - - if (ahd->platform_data->dv_scsi_dev != NULL) { - free(ahd->platform_data->dv_scsi_dev, M_DEVBUF); - ahd->platform_data->dv_scsi_dev = NULL; - } - - ahd_lock(ahd, &s); - if (targ->dv_buffer != NULL) - free(targ->dv_buffer, M_DEVBUF); - if (targ->dv_buffer1 != NULL) - free(targ->dv_buffer1, M_DEVBUF); - targ->flags &= ~AHD_DV_REQUIRED; - if (targ->refcount == 0) - ahd_linux_free_target(ahd, targ); - ahd_unlock(ahd, &s); -} - -static void -ahd_linux_dv_transition(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ) -{ - cam_status cam_status; - u_int32_t status; - u_int scsi_status; - - scsi_status = ahd_cmd_get_scsi_status(cmd); - cam_status = ahd_cmd_get_transaction_status(cmd); - status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status); - - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Entering ahd_linux_dv_transition, state= %d, " - "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state, - status, cmd->result); - } -#endif - - switch (targ->dv_state) { - case AHD_DV_STATE_INQ_SHORT_ASYNC: - case AHD_DV_STATE_INQ_ASYNC: - switch (status & SS_MASK) { - case SS_NOP: - { - AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1); - break; - } - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - case SS_TUR: - case SS_RETRY: - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) - targ->dv_state_retry--; - if ((status & SS_ERRMASK) == EBUSY) - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); - if (targ->dv_state_retry < 10) - break; - /* FALLTHROUGH */ - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Failed DV inquiry, skipping\n"); - } -#endif - break; - } - break; - case AHD_DV_STATE_INQ_ASYNC_VERIFY: - switch (status & SS_MASK) { - case SS_NOP: - { - u_int xportflags; - u_int spi3data; - - if (memcmp(targ->inq_data, targ->dv_buffer, - AHD_LINUX_DV_INQ_LEN) != 0) { - /* - * Inquiry data must have changed. - * Try from the top again. - */ - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - } - - AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1); - targ->flags |= AHD_INQ_VALID; - if (ahd_linux_user_dv_setting(ahd) == 0) - break; - - xportflags = targ->inq_data->flags; - if ((xportflags & (SID_Sync|SID_WBus16)) == 0) - break; - - spi3data = targ->inq_data->spi3data; - switch (spi3data & SID_SPI_CLOCK_DT_ST) { - default: - case SID_SPI_CLOCK_ST: - /* Assume only basic DV is supported. */ - targ->flags |= AHD_BASIC_DV; - break; - case SID_SPI_CLOCK_DT: - case SID_SPI_CLOCK_DT_ST: - targ->flags |= AHD_ENHANCED_DV; - break; - } - break; - } - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - case SS_TUR: - case SS_RETRY: - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) - targ->dv_state_retry--; - - if ((status & SS_ERRMASK) == EBUSY) - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); - if (targ->dv_state_retry < 10) - break; - /* FALLTHROUGH */ - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Failed DV inquiry, skipping\n"); - } -#endif - break; - } - break; - case AHD_DV_STATE_INQ_VERIFY: - switch (status & SS_MASK) { - case SS_NOP: - { - - if (memcmp(targ->inq_data, targ->dv_buffer, - AHD_LINUX_DV_INQ_LEN) == 0) { - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - int i; - - ahd_print_devinfo(ahd, devinfo); - printf("Inquiry buffer mismatch:"); - for (i = 0; i < AHD_LINUX_DV_INQ_LEN; i++) { - if ((i & 0xF) == 0) - printf("\n "); - printf("0x%x:0x0%x ", - ((uint8_t *)targ->inq_data)[i], - targ->dv_buffer[i]); - } - printf("\n"); - } -#endif - - if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - /* - * Do not count "falling back" - * against our retries. - */ - targ->dv_state_retry = 0; - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - break; - } - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - case SS_TUR: - case SS_RETRY: - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) { - targ->dv_state_retry--; - } else if ((status & SSQ_FALLBACK) != 0) { - if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_EXIT); - break; - } - /* - * Do not count "falling back" - * against our retries. - */ - targ->dv_state_retry = 0; - } else if ((status & SS_ERRMASK) == EBUSY) - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); - if (targ->dv_state_retry < 10) - break; - /* FALLTHROUGH */ - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Failed DV inquiry, skipping\n"); - } -#endif - break; - } - break; - - case AHD_DV_STATE_TUR: - switch (status & SS_MASK) { - case SS_NOP: - if ((targ->flags & AHD_BASIC_DV) != 0) { - ahd_linux_filter_inquiry(ahd, devinfo); - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_VERIFY); - } else if ((targ->flags & AHD_ENHANCED_DV) != 0) { - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REBD); - } else { - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - } - break; - case SS_RETRY: - case SS_TUR: - if ((status & SS_ERRMASK) == EBUSY) { - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); - break; - } - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) { - targ->dv_state_retry--; - } else if ((status & SSQ_FALLBACK) != 0) { - if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_EXIT); - break; - } - /* - * Do not count "falling back" - * against our retries. - */ - targ->dv_state_retry = 0; - } - if (targ->dv_state_retry >= 10) { -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("DV TUR reties exhausted\n"); - } -#endif - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - if (status & SSQ_DELAY) - scsi_sleep(1 * HZ); - - break; - case SS_START: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_SU); - break; - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - break; - - case AHD_DV_STATE_REBD: - switch (status & SS_MASK) { - case SS_NOP: - { - uint32_t echo_size; - - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB); - echo_size = scsi_3btoul(&targ->dv_buffer[1]); - echo_size &= 0x1FFF; -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Echo buffer size= %d\n", echo_size); - } -#endif - if (echo_size == 0) { - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - - /* Generate the buffer pattern */ - targ->dv_echo_size = echo_size; - ahd_linux_generate_dv_pattern(targ); - /* - * Setup initial negotiation values. - */ - ahd_linux_filter_inquiry(ahd, devinfo); - break; - } - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - case SS_RETRY: - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) - targ->dv_state_retry--; - if (targ->dv_state_retry <= 10) - break; -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("DV REBD reties exhausted\n"); - } -#endif - /* FALLTHROUGH */ - case SS_FATAL: - default: - /* - * Setup initial negotiation values - * and try level 1 DV. - */ - ahd_linux_filter_inquiry(ahd, devinfo); - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_VERIFY); - targ->dv_echo_size = 0; - break; - } - break; - - case AHD_DV_STATE_WEB: - switch (status & SS_MASK) { - case SS_NOP: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REB); - break; - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - case SS_RETRY: - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) { - targ->dv_state_retry--; - } else if ((status & SSQ_FALLBACK) != 0) { - if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_EXIT); - break; - } - /* - * Do not count "falling back" - * against our retries. - */ - targ->dv_state_retry = 0; - } - if (targ->dv_state_retry <= 10) - break; - /* FALLTHROUGH */ -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("DV WEB reties exhausted\n"); - } -#endif - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - break; - - case AHD_DV_STATE_REB: - switch (status & SS_MASK) { - case SS_NOP: - if (memcmp(targ->dv_buffer, targ->dv_buffer1, - targ->dv_echo_size) != 0) { - if (ahd_linux_dv_fallback(ahd, devinfo) != 0) - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_EXIT); - else - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_WEB); - break; - } - - if (targ->dv_buffer != NULL) { - free(targ->dv_buffer, M_DEVBUF); - targ->dv_buffer = NULL; - } - if (targ->dv_buffer1 != NULL) { - free(targ->dv_buffer1, M_DEVBUF); - targ->dv_buffer1 = NULL; - } - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - case SS_RETRY: - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) { - targ->dv_state_retry--; - } else if ((status & SSQ_FALLBACK) != 0) { - if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_EXIT); - break; - } - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB); - } - if (targ->dv_state_retry <= 10) { - if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0) - scsi_sleep(ahd->our_id*HZ/10); - break; - } -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("DV REB reties exhausted\n"); - } -#endif - /* FALLTHROUGH */ - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - break; - - case AHD_DV_STATE_SU: - switch (status & SS_MASK) { - case SS_NOP: - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - break; - - case AHD_DV_STATE_BUSY: - switch (status & SS_MASK) { - case SS_NOP: - case SS_INQ_REFRESH: - AHD_SET_DV_STATE(ahd, targ, - AHD_DV_STATE_INQ_SHORT_ASYNC); - break; - case SS_TUR: - case SS_RETRY: - AHD_SET_DV_STATE(ahd, targ, targ->dv_state); - if (ahd_cmd_get_transaction_status(cmd) - == CAM_REQUEUE_REQ) { - targ->dv_state_retry--; - } else if (targ->dv_state_retry < 60) { - if ((status & SSQ_DELAY) != 0) - scsi_sleep(1 * HZ); - } else { -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("DV BUSY reties exhausted\n"); - } -#endif - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - } - break; - default: - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } - break; - - default: - printf("%s: Invalid DV completion state %d\n", ahd_name(ahd), - targ->dv_state); - AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); - break; - } -} - -static void -ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo) -{ - memset(cmd, 0, sizeof(struct scsi_cmnd)); - cmd->device = ahd->platform_data->dv_scsi_dev; - cmd->scsi_done = ahd_linux_dv_complete; -} - -/* - * Synthesize an inquiry command. On the return trip, it'll be - * sniffed and the device transfer settings set for us. - */ -static void -ahd_linux_dv_inq(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, struct ahd_linux_target *targ, - u_int request_length) -{ - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Sending INQ\n"); - } -#endif - if (targ->inq_data == NULL) - targ->inq_data = malloc(AHD_LINUX_DV_INQ_LEN, - M_DEVBUF, M_WAITOK); - if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) { - if (targ->dv_buffer != NULL) - free(targ->dv_buffer, M_DEVBUF); - targ->dv_buffer = malloc(AHD_LINUX_DV_INQ_LEN, - M_DEVBUF, M_WAITOK); - } - - ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); - cmd->sc_data_direction = SCSI_DATA_READ; - cmd->cmd_len = 6; - cmd->cmnd[0] = INQUIRY; - cmd->cmnd[4] = request_length; - cmd->request_bufflen = request_length; - if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) - cmd->request_buffer = targ->dv_buffer; - else - cmd->request_buffer = targ->inq_data; - memset(cmd->request_buffer, 0, AHD_LINUX_DV_INQ_LEN); -} - -static void -ahd_linux_dv_tur(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo) -{ - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Sending TUR\n"); - } -#endif - /* Do a TUR to clear out any non-fatal transitional state */ - ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); - cmd->sc_data_direction = SCSI_DATA_NONE; - cmd->cmd_len = 6; - cmd->cmnd[0] = TEST_UNIT_READY; -} - -#define AHD_REBD_LEN 4 - -static void -ahd_linux_dv_rebd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) -{ - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Sending REBD\n"); - } -#endif - if (targ->dv_buffer != NULL) - free(targ->dv_buffer, M_DEVBUF); - targ->dv_buffer = malloc(AHD_REBD_LEN, M_DEVBUF, M_WAITOK); - ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); - cmd->sc_data_direction = SCSI_DATA_READ; - cmd->cmd_len = 10; - cmd->cmnd[0] = READ_BUFFER; - cmd->cmnd[1] = 0x0b; - scsi_ulto3b(AHD_REBD_LEN, &cmd->cmnd[6]); - cmd->request_bufflen = AHD_REBD_LEN; - cmd->underflow = cmd->request_bufflen; - cmd->request_buffer = targ->dv_buffer; -} - -static void -ahd_linux_dv_web(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) -{ - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Sending WEB\n"); - } -#endif - ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); - cmd->sc_data_direction = SCSI_DATA_WRITE; - cmd->cmd_len = 10; - cmd->cmnd[0] = WRITE_BUFFER; - cmd->cmnd[1] = 0x0a; - scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); - cmd->request_bufflen = targ->dv_echo_size; - cmd->underflow = cmd->request_bufflen; - cmd->request_buffer = targ->dv_buffer; -} - -static void -ahd_linux_dv_reb(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) -{ - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Sending REB\n"); - } -#endif - ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); - cmd->sc_data_direction = SCSI_DATA_READ; - cmd->cmd_len = 10; - cmd->cmnd[0] = READ_BUFFER; - cmd->cmnd[1] = 0x0a; - scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); - cmd->request_bufflen = targ->dv_echo_size; - cmd->underflow = cmd->request_bufflen; - cmd->request_buffer = targ->dv_buffer1; -} - -static void -ahd_linux_dv_su(struct ahd_softc *ahd, struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - struct ahd_linux_target *targ) -{ - u_int le; - - le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0; - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Sending SU\n"); - } -#endif - ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); - cmd->sc_data_direction = SCSI_DATA_NONE; - cmd->cmd_len = 6; - cmd->cmnd[0] = START_STOP_UNIT; - cmd->cmnd[4] = le | SSS_START; -} - -static __inline int -ahd_linux_dv_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - u_long s; - int retval; - - ahd_lock(ahd, &s); - retval = ahd_linux_fallback(ahd, devinfo); - ahd_unlock(ahd, &s); - - return (retval); -} - -static int -ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - struct ahd_linux_target *targ; - struct ahd_initiator_tinfo *tinfo; - struct ahd_transinfo *goal; - struct ahd_tmode_tstate *tstate; - u_int width; - u_int period; - u_int offset; - u_int ppr_options; - u_int cur_speed; - u_int wide_speed; - u_int narrow_speed; - u_int fallback_speed; - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - ahd_print_devinfo(ahd, devinfo); - printf("Trying to fallback\n"); - } -#endif - targ = ahd->platform_data->targets[devinfo->target_offset]; - tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, - devinfo->our_scsiid, - devinfo->target, &tstate); - goal = &tinfo->goal; - width = goal->width; - period = goal->period; - offset = goal->offset; - ppr_options = goal->ppr_options; - if (offset == 0) - period = AHD_ASYNC_XFER_PERIOD; - if (targ->dv_next_narrow_period == 0) - targ->dv_next_narrow_period = MAX(period, AHD_SYNCRATE_ULTRA2); - if (targ->dv_next_wide_period == 0) - targ->dv_next_wide_period = period; - if (targ->dv_max_width == 0) - targ->dv_max_width = width; - if (targ->dv_max_ppr_options == 0) - targ->dv_max_ppr_options = ppr_options; - if (targ->dv_last_ppr_options == 0) - targ->dv_last_ppr_options = ppr_options; - - cur_speed = aic_calc_speed(width, period, offset, AHD_SYNCRATE_MIN); - wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, - targ->dv_next_wide_period, - MAX_OFFSET, AHD_SYNCRATE_MIN); - narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, - targ->dv_next_narrow_period, - MAX_OFFSET, AHD_SYNCRATE_MIN); - fallback_speed = aic_calc_speed(width, period+1, offset, - AHD_SYNCRATE_MIN); -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, " - "fallback_speed= %d\n", cur_speed, wide_speed, - narrow_speed, fallback_speed); - } -#endif - - if (cur_speed > 160000) { - /* - * Paced/DT/IU_REQ only transfer speeds. All we - * can do is fallback in terms of syncrate. - */ - period++; - } else if (cur_speed > 80000) { - if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - /* - * Try without IU_REQ as it may be confusing - * an expander. - */ - ppr_options &= ~MSG_EXT_PPR_IU_REQ; - } else { - /* - * Paced/DT only transfer speeds. All we - * can do is fallback in terms of syncrate. - */ - period++; - ppr_options = targ->dv_max_ppr_options; - } - } else if (cur_speed > 3300) { - - /* - * In this range we the following - * options ordered from highest to - * lowest desireability: - * - * o Wide/DT - * o Wide/non-DT - * o Narrow at a potentally higher sync rate. - * - * All modes are tested with and without IU_REQ - * set since using IUs may confuse an expander. - */ - if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - - ppr_options &= ~MSG_EXT_PPR_IU_REQ; - } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { - /* - * Try going non-DT. - */ - ppr_options = targ->dv_max_ppr_options; - ppr_options &= ~MSG_EXT_PPR_DT_REQ; - } else if (targ->dv_last_ppr_options != 0) { - /* - * Try without QAS or any other PPR options. - * We may need a non-PPR message to work with - * an expander. We look at the "last PPR options" - * so we will perform this fallback even if the - * target responded to our PPR negotiation with - * no option bits set. - */ - ppr_options = 0; - } else if (width == MSG_EXT_WDTR_BUS_16_BIT) { - /* - * If the next narrow speed is greater than - * the next wide speed, fallback to narrow. - * Otherwise fallback to the next DT/Wide setting. - * The narrow async speed will always be smaller - * than the wide async speed, so handle this case - * specifically. - */ - ppr_options = targ->dv_max_ppr_options; - if (narrow_speed > fallback_speed - || period >= AHD_ASYNC_XFER_PERIOD) { - targ->dv_next_wide_period = period+1; - width = MSG_EXT_WDTR_BUS_8_BIT; - period = targ->dv_next_narrow_period; - } else { - period++; - } - } else if ((ahd->features & AHD_WIDE) != 0 - && targ->dv_max_width != 0 - && wide_speed >= fallback_speed - && (targ->dv_next_wide_period <= AHD_ASYNC_XFER_PERIOD - || period >= AHD_ASYNC_XFER_PERIOD)) { - - /* - * We are narrow. Try falling back - * to the next wide speed with - * all supported ppr options set. - */ - targ->dv_next_narrow_period = period+1; - width = MSG_EXT_WDTR_BUS_16_BIT; - period = targ->dv_next_wide_period; - ppr_options = targ->dv_max_ppr_options; - } else { - /* Only narrow fallback is allowed. */ - period++; - ppr_options = targ->dv_max_ppr_options; - } - } else { - return (-1); - } - offset = MAX_OFFSET; - ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_PACED); - ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, FALSE); - if (period == 0) { - period = 0; - offset = 0; - ppr_options = 0; - if (width == MSG_EXT_WDTR_BUS_8_BIT) - targ->dv_next_narrow_period = AHD_ASYNC_XFER_PERIOD; - else - targ->dv_next_wide_period = AHD_ASYNC_XFER_PERIOD; - } - ahd_set_syncrate(ahd, devinfo, period, offset, - ppr_options, AHD_TRANS_GOAL, FALSE); - targ->dv_last_ppr_options = ppr_options; - return (0); -} - -static void -ahd_linux_dv_timeout(struct scsi_cmnd *cmd) -{ - struct ahd_softc *ahd; - struct ahd_cmd *acmd; - struct ahd_linux_device *next_dev; - struct scb *scb; - u_long flags; - - ahd = *((struct ahd_softc **)cmd->device->host->hostdata); - ahd_lock(ahd, &flags); - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) { - printf("%s: Timeout while doing DV command %x.\n", - ahd_name(ahd), cmd->cmnd[0]); - ahd_dump_card_state(ahd); - } -#endif - - /* - * Guard against "done race". No action is - * required if we just completed. - */ - if ((scb = (struct scb *)cmd->host_scribble) == NULL) { - ahd_unlock(ahd, &flags); - return; - } - - /* - * Command has not completed. Mark this - * SCB as having failing status prior to - * resetting the bus, so we get the correct - * error code. - */ - if ((scb->flags & SCB_SENSE) != 0) - ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); - else - ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); - ahd_reset_channel(ahd, cmd->channel + 'A', /*initiate*/TRUE); - - /* - * Add a minimal bus settle delay for devices that are slow to - * respond after bus resets. - */ - ahd_freeze_simq(ahd); - init_timer(&ahd->platform_data->reset_timer); - ahd->platform_data->reset_timer.data = (u_long)ahd; - ahd->platform_data->reset_timer.expires = jiffies + HZ / 2; - ahd->platform_data->reset_timer.function = - (ahd_linux_callback_t *)ahd_release_simq; - add_timer(&ahd->platform_data->reset_timer); - /* - * In 2.5.X, the "done lock" is the ahd_lock. - * Instead of dropping and re-acquiring the same - * lock in the 2.5.X case, just hold our ahd_lock - * the whole time. ahd_done_lock() has been - * made a no-op for 2.5.X too. - */ - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - next_dev = ahd_linux_next_device_to_run(ahd); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif - if (next_dev) - ahd_schedule_runq(ahd); - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_lock(ahd, &flags); -#endif - ahd_schedule_completeq(ahd, acmd); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif - } - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif -} - -static void -ahd_linux_dv_complete(struct scsi_cmnd *cmd) -{ - struct ahd_softc *ahd; - - ahd = *((struct ahd_softc **)cmd->device->host->hostdata); - - /* Delete the DV timer before it goes off! */ - scsi_delete_timer(cmd); - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) - printf("%s:%c:%d: Command completed, status= 0x%x\n", - ahd_name(ahd), cmd->device->channel, cmd->device->id, - cmd->result); -#endif - - /* Wake up the state machine */ - up(&ahd->platform_data->dv_cmd_sem); -} - -static void -ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ) -{ - uint16_t b; - u_int i; - u_int j; - - if (targ->dv_buffer != NULL) - free(targ->dv_buffer, M_DEVBUF); - targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); - if (targ->dv_buffer1 != NULL) - free(targ->dv_buffer1, M_DEVBUF); - targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); - - i = 0; - - b = 0x0001; - for (j = 0 ; i < targ->dv_echo_size; j++) { - if (j < 32) { - /* - * 32bytes of sequential numbers. - */ - targ->dv_buffer[i++] = j & 0xff; - } else if (j < 48) { - /* - * 32bytes of repeating 0x0000, 0xffff. - */ - targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00; - } else if (j < 64) { - /* - * 32bytes of repeating 0x5555, 0xaaaa. - */ - targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55; - } else { - /* - * Remaining buffer is filled with a repeating - * patter of: - * - * 0xffff - * ~0x0001 << shifted once in each loop. - */ - if (j & 0x02) { - if (j & 0x01) { - targ->dv_buffer[i++] = ~(b >> 8) & 0xff; - b <<= 1; - if (b == 0x0000) - b = 0x0001; - } else { - targ->dv_buffer[i++] = (~b & 0xff); - } - } else { - targ->dv_buffer[i++] = 0xff; - } - } - } -} - -static u_int -ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - static int warned_user; - u_int tags; - - tags = 0; - if ((ahd->user_discenable & devinfo->target_mask) != 0) { - if (warned_user == 0 - && ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) { - - printf("aic79xx: WARNING, insufficient " - "tag_info instances for installed " - "controllers. Using defaults\n"); - printf("aic79xx: Please update the " - "aic79xx_tag_info array in the " - "aic79xx.c source file.\n"); - tags = AHD_MAX_QUEUE; - warned_user++; - } else { - adapter_tag_info_t *tag_info; - - tag_info = &aic79xx_tag_info[ahd->unit]; - tags = tag_info->tag_commands[devinfo->target_offset]; - if (tags > AHD_MAX_QUEUE) - tags = AHD_MAX_QUEUE; - } - } - return (tags); -} - -static u_int -ahd_linux_user_dv_setting(struct ahd_softc *ahd) -{ - static int warned_user; - int dv; - - if (warned_user == 0 - && ahd->unit >= NUM_ELEMENTS(aic79xx_dv_settings)) { - - printf("aic79xx: WARNING, insufficient " - "dv settings instances for installed " - "controllers. Using defaults\n"); - printf("aic79xx: Please update the " - "aic79xx_dv_settings array in the " - "aic79xx.c source file.\n"); - dv = -1; - warned_user++; - } else { - - dv = aic79xx_dv_settings[ahd->unit]; - } - - if (dv < 0) { - /* - * Apply the default. - */ - dv = 1; - if (ahd->seep_config != 0) - dv = (ahd->seep_config->bios_control & CFENABLEDV); - } - return (dv); -} - -/* - * Determines the queue depth for a given device. - */ -static void -ahd_linux_device_queue_depth(struct ahd_softc *ahd, - struct ahd_linux_device *dev) -{ - struct ahd_devinfo devinfo; - u_int tags; - - ahd_compile_devinfo(&devinfo, - ahd->our_id, - dev->target->target, dev->lun, - dev->target->channel == 0 ? 'A' : 'B', - ROLE_INITIATOR); - tags = ahd_linux_user_tagdepth(ahd, &devinfo); - if (tags != 0 - && dev->scsi_device != NULL - && dev->scsi_device->tagged_supported != 0) { - - ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED); - printf("scsi%d:%c:%d:%d: Tagged Queuing enabled. Depth %d\n", - ahd->platform_data->host->host_no, devinfo.channel, - devinfo.target, devinfo.lun, tags); - } else { - ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE); - } -} - -static void -ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev) -{ - struct ahd_cmd *acmd; - struct scsi_cmnd *cmd; - struct scb *scb; - struct hardware_scb *hscb; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - u_int col_idx; - uint16_t mask; - - if ((dev->flags & AHD_DEV_ON_RUN_LIST) != 0) - panic("running device on run list"); - - while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL - && dev->openings > 0 && dev->qfrozen == 0) { - - /* - * Schedule us to run later. The only reason we are not - * running is because the whole controller Q is frozen. - */ - if (ahd->platform_data->qfrozen != 0 - && AHD_DV_SIMQ_FROZEN(ahd) == 0) { - - TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, - dev, links); - dev->flags |= AHD_DEV_ON_RUN_LIST; - return; - } - - cmd = &acmd_scsi_cmd(acmd); - - /* - * Get an scb to use. - */ - tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - cmd->device->id, &tstate); - if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0 - || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - col_idx = AHD_NEVER_COL_IDX; - } else { - col_idx = AHD_BUILD_COL_IDX(cmd->device->id, - cmd->device->lun); - } - if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { - TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, - dev, links); - dev->flags |= AHD_DEV_ON_RUN_LIST; - ahd->flags |= AHD_RESOURCE_SHORTAGE; - return; - } - TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe); - scb->io_ctx = cmd; - scb->platform_data->dev = dev; - hscb = scb->hscb; - cmd->host_scribble = (char *)scb; - - /* - * Fill out basics of the HSCB. - */ - hscb->control = 0; - hscb->scsiid = BUILD_SCSIID(ahd, cmd); - hscb->lun = cmd->lun; - scb->hscb->task_management = 0; - mask = SCB_GET_TARGET_MASK(ahd, scb); - - if ((ahd->user_discenable & mask) != 0) - hscb->control |= DISCENB; - - if (AHD_DV_CMD(cmd) != 0) - scb->flags |= SCB_SILENT; - - if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) - scb->flags |= SCB_PACKETIZED; - - if ((tstate->auto_negotiate & mask) != 0) { - scb->flags |= SCB_AUTO_NEGOTIATE; - scb->hscb->control |= MK_MESSAGE; - } - - if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - int msg_bytes; - uint8_t tag_msgs[2]; - - msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); - if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { - hscb->control |= tag_msgs[0]; - if (tag_msgs[0] == MSG_ORDERED_TASK) - dev->commands_since_idle_or_otag = 0; - } else -#endif - if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH - && (dev->flags & AHD_DEV_Q_TAGGED) != 0) { - hscb->control |= MSG_ORDERED_TASK; - dev->commands_since_idle_or_otag = 0; - } else { - hscb->control |= MSG_SIMPLE_TASK; - } - } - - hscb->cdb_len = cmd->cmd_len; - memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len); - - scb->sg_count = 0; - ahd_set_residual(scb, 0); - ahd_set_sense_residual(scb, 0); - if (cmd->use_sg != 0) { - void *sg; - struct scatterlist *cur_seg; - u_int nseg; - int dir; - - cur_seg = (struct scatterlist *)cmd->request_buffer; - dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); - nseg = pci_map_sg(ahd->dev_softc, cur_seg, - cmd->use_sg, dir); - scb->platform_data->xfer_len = 0; - for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) { - bus_addr_t addr; - bus_size_t len; - - addr = sg_dma_address(cur_seg); - len = sg_dma_len(cur_seg); - scb->platform_data->xfer_len += len; - sg = ahd_sg_setup(ahd, scb, sg, addr, len, - /*last*/nseg == 1); - } - } else if (cmd->request_bufflen != 0) { - void *sg; - bus_addr_t addr; - int dir; - - sg = scb->sg_list; - dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); - addr = pci_map_single(ahd->dev_softc, - cmd->request_buffer, - cmd->request_bufflen, dir); - scb->platform_data->xfer_len = cmd->request_bufflen; - scb->platform_data->buf_busaddr = addr; - sg = ahd_sg_setup(ahd, scb, sg, addr, - cmd->request_bufflen, /*last*/TRUE); - } - - LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); - dev->openings--; - dev->active++; - dev->commands_issued++; - - /* Update the error counting bucket and dump if needed */ - if (dev->target->cmds_since_error) { - dev->target->cmds_since_error++; - if (dev->target->cmds_since_error > - AHD_LINUX_ERR_THRESH) - dev->target->cmds_since_error = 0; - } - - if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0) - dev->commands_since_idle_or_otag++; - scb->flags |= SCB_ACTIVE; - ahd_queue_scb(ahd, scb); - } -} - -/* - * SCSI controller interrupt handler. - */ -void -ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) -{ - struct ahd_softc *ahd; - struct ahd_cmd *acmd; - u_long flags; - struct ahd_linux_device *next_dev; - - ahd = (struct ahd_softc *) dev_id; - ahd_lock(ahd, &flags); - ahd_intr(ahd); - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - next_dev = ahd_linux_next_device_to_run(ahd); - /* - * In 2.5.X, the "done lock" is the ahd_lock. - * Instead of dropping and re-acquiring the same - * lock in the 2.5.X case, just hold our ahd_lock - * the whole time. ahd_done_lock() has been - * made a no-op for 2.5.X too. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif - if (next_dev) - ahd_schedule_runq(ahd); - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_lock(ahd, &flags); -#endif - ahd_schedule_completeq(ahd, acmd); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif - } - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &flags); -#endif -} - -void -ahd_platform_flushwork(struct ahd_softc *ahd) -{ - struct ahd_cmd *acmd; - - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - while (acmd != NULL) - acmd = ahd_linux_run_complete_queue(ahd, acmd); -} - -static struct ahd_linux_target* -ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target) -{ - struct ahd_linux_target *targ; - u_int target_offset; - - target_offset = target; - /* - * Never allow allocation of a target object for - * our own SCSIID. - */ - if (target == ahd->our_id) { - ahd->platform_data->targets[target_offset] = NULL; - return (NULL); - } - - targ = malloc(sizeof(*targ), M_DEVBUF, M_NOWAIT); - if (targ == NULL) - return (NULL); - memset(targ, 0, sizeof(*targ)); - targ->channel = channel; - targ->target = target; - targ->ahd = ahd; - targ->flags = AHD_DV_REQUIRED; - ahd->platform_data->targets[target_offset] = targ; - return (targ); -} - -static void -ahd_linux_free_target(struct ahd_softc *ahd, struct ahd_linux_target *targ) -{ - struct ahd_devinfo devinfo; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - u_int our_id; - u_int target_offset; - char channel; - - /* - * Force a negotiation to async/narrow on any - * future command to this device unless a bus - * reset occurs between now and that command. - */ - channel = 'A' + targ->channel; - our_id = ahd->our_id; - target_offset = targ->target; - tinfo = ahd_fetch_transinfo(ahd, channel, our_id, - targ->target, &tstate); - ahd_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD, - channel, ROLE_INITIATOR); - ahd_set_syncrate(ahd, &devinfo, 0, 0, 0, - AHD_TRANS_GOAL, /*paused*/FALSE); - ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_GOAL, /*paused*/FALSE); - ahd_update_neg_request(ahd, &devinfo, tstate, tinfo, AHD_NEG_ALWAYS); - ahd->platform_data->targets[target_offset] = NULL; - if (targ->inq_data != NULL) - free(targ->inq_data, M_DEVBUF); - if (targ->dv_buffer != NULL) - free(targ->dv_buffer, M_DEVBUF); - if (targ->dv_buffer1 != NULL) - free(targ->dv_buffer1, M_DEVBUF); - free(targ, M_DEVBUF); -} - -static struct ahd_linux_device* -ahd_linux_alloc_device(struct ahd_softc *ahd, - struct ahd_linux_target *targ, u_int lun) -{ - struct ahd_linux_device *dev; - - dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT); - if (dev == NULL) - return (NULL); - memset(dev, 0, sizeof(*dev)); - init_timer(&dev->timer); - TAILQ_INIT(&dev->busyq); - dev->flags = AHD_DEV_UNCONFIGURED; - dev->lun = lun; - dev->target = targ; - - /* - * We start out life using untagged - * transactions of which we allow one. - */ - dev->openings = 1; - - /* - * Set maxtags to 0. This will be changed if we - * later determine that we are dealing with - * a tagged queuing capable device. - */ - dev->maxtags = 0; - - targ->refcount++; - targ->devices[lun] = dev; - return (dev); -} - -static void -ahd_linux_free_device(struct ahd_softc *ahd, struct ahd_linux_device *dev) -{ - struct ahd_linux_target *targ; - - del_timer(&dev->timer); - targ = dev->target; - targ->devices[dev->lun] = NULL; - free(dev, M_DEVBUF); - targ->refcount--; - if (targ->refcount == 0 - && (targ->flags & AHD_DV_REQUIRED) == 0) - ahd_linux_free_target(ahd, targ); -} - -void -ahd_send_async(struct ahd_softc *ahd, char channel, - u_int target, u_int lun, ac_code code, void *arg) -{ - switch (code) { - case AC_TRANSFER_NEG: - { - char buf[80]; - struct ahd_linux_target *targ; - struct info_str info; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - - info.buffer = buf; - info.length = sizeof(buf); - info.offset = 0; - info.pos = 0; - tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id, - target, &tstate); - - /* - * Don't bother reporting results while - * negotiations are still pending. - */ - if (tinfo->curr.period != tinfo->goal.period - || tinfo->curr.width != tinfo->goal.width - || tinfo->curr.offset != tinfo->goal.offset - || tinfo->curr.ppr_options != tinfo->goal.ppr_options) - if (bootverbose == 0) - break; - - /* - * Don't bother reporting results that - * are identical to those last reported. - */ - targ = ahd->platform_data->targets[target]; - if (targ == NULL) - break; - if (tinfo->curr.period == targ->last_tinfo.period - && tinfo->curr.width == targ->last_tinfo.width - && tinfo->curr.offset == targ->last_tinfo.offset - && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options) - if (bootverbose == 0) - break; - - targ->last_tinfo.period = tinfo->curr.period; - targ->last_tinfo.width = tinfo->curr.width; - targ->last_tinfo.offset = tinfo->curr.offset; - targ->last_tinfo.ppr_options = tinfo->curr.ppr_options; - - printf("(%s:%c:", ahd_name(ahd), channel); - if (target == CAM_TARGET_WILDCARD) - printf("*): "); - else - printf("%d): ", target); - ahd_format_transinfo(&info, &tinfo->curr); - if (info.pos < info.length) - *info.buffer = '\0'; - else - buf[info.length - 1] = '\0'; - printf("%s", buf); - break; - } - case AC_SENT_BDR: - { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - Scsi_Device *scsi_dev; - - /* - * Find the SCSI device associated with this - * request and indicate that a UA is expected. - * XXX This should really be handled by the mid-layer. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - list_for_each_entry(scsi_dev, - &ahd->platform_data->host->my_devices, - siblings) { -#else - for (scsi_dev = ahd->platform_data->host->host_queue; - scsi_dev != NULL; scsi_dev = scsi_dev->next) { -#endif - if (channel - 'A' == scsi_dev->channel - && target == scsi_dev->id - && (lun == CAM_LUN_WILDCARD - || lun == scsi_dev->lun)) { - scsi_dev->was_reset = 1; - scsi_dev->expecting_cc_ua = 1; - } - } -#endif - break; - } - case AC_BUS_RESET: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - if (ahd->platform_data->host != NULL) { - scsi_report_bus_reset(ahd->platform_data->host, - channel - 'A'); - } -#endif - break; - default: - panic("ahd_send_async: Unexpected async event"); - } -} - -/* - * Calls the higher level scsi done function and frees the scb. - */ -void -ahd_done(struct ahd_softc *ahd, struct scb *scb) -{ - Scsi_Cmnd *cmd; - struct ahd_linux_device *dev; - - LIST_REMOVE(scb, pending_links); - - if ((scb->flags & SCB_ACTIVE) == 0) { - printf("SCB %d done'd twice\n", scb->hscb->tag); - ahd_dump_card_state(ahd); - panic("Stopping for safety"); - } - cmd = scb->io_ctx; - dev = scb->platform_data->dev; - dev->active--; - dev->openings++; - if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) { - cmd->result &= ~(CAM_DEV_QFRZN << 16); - dev->qfrozen--; - } - ahd_linux_unmap_scb(ahd, scb); - - /* - * Guard against stale sense data. - * The Linux mid-layer assumes that sense - * was retrieved anytime the first byte of - * the sense buffer looks "sane". - */ - cmd->sense_buffer[0] = 0; - if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) { - uint32_t amount_xferred; - - amount_xferred = - ahd_get_transfer_length(scb) - ahd_get_residual(scb); - if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) { -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_MISC) != 0) { - ahd_print_path(ahd, scb); - printf("Set CAM_UNCOR_PARITY\n"); - } -#endif - ahd_set_transaction_status(scb, CAM_UNCOR_PARITY); - } else if (amount_xferred < scb->io_ctx->underflow) { - printf("Saw underflow (%ld of %ld bytes). " - "Treated as error\n", - ahd_get_residual(scb), - ahd_get_transfer_length(scb)); - ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); - } else { - ahd_set_transaction_status(scb, CAM_REQ_CMP); - } - } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { - ahd_linux_handle_scsi_status(ahd, dev, scb); - } else if (ahd_get_transaction_status(scb) == CAM_SEL_TIMEOUT) { - dev->flags |= AHD_DEV_UNCONFIGURED; - if (AHD_DV_CMD(cmd) == FALSE) - dev->target->flags &= ~AHD_DV_REQUIRED; - } - /* - * Start DV for devices that require it assuming the first command - * sent does not result in a selection timeout. - */ - if (ahd_get_transaction_status(scb) != CAM_SEL_TIMEOUT - && (dev->target->flags & AHD_DV_REQUIRED) != 0) - ahd_linux_start_dv(ahd); - - if (dev->openings == 1 - && ahd_get_transaction_status(scb) == CAM_REQ_CMP - && ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL) - dev->tag_success_count++; - /* - * Some devices deal with temporary internal resource - * shortages by returning queue full. When the queue - * full occurrs, we throttle back. Slowly try to get - * back to our previous queue depth. - */ - if ((dev->openings + dev->active) < dev->maxtags - && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) { - dev->tag_success_count = 0; - dev->openings++; - } - - if (dev->active == 0) - dev->commands_since_idle_or_otag = 0; - - if (TAILQ_EMPTY(&dev->busyq)) { - if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 - && dev->active == 0) - ahd_linux_free_device(ahd, dev); - } else if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); - dev->flags |= AHD_DEV_ON_RUN_LIST; - } - - if ((scb->flags & SCB_RECOVERY_SCB) != 0) { - printf("Recovery SCB completes\n"); - if (ahd_get_transaction_status(scb) == CAM_BDR_SENT - || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) - ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); - if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { - ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; - up(&ahd->platform_data->eh_sem); - } - } - - ahd_free_scb(ahd, scb); - ahd_linux_queue_cmd_complete(ahd, cmd); - - if ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_EMPTY) != 0 - && LIST_FIRST(&ahd->pending_scbs) == NULL) { - ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_EMPTY; - up(&ahd->platform_data->dv_sem); - } -} - -static void -ahd_linux_handle_scsi_status(struct ahd_softc *ahd, - struct ahd_linux_device *dev, struct scb *scb) -{ - struct ahd_devinfo devinfo; - - ahd_compile_devinfo(&devinfo, - ahd->our_id, - dev->target->target, dev->lun, - dev->target->channel == 0 ? 'A' : 'B', - ROLE_INITIATOR); - - /* - * We don't currently trust the mid-layer to - * properly deal with queue full or busy. So, - * when one occurs, we tell the mid-layer to - * unconditionally requeue the command to us - * so that we can retry it ourselves. We also - * implement our own throttling mechanism so - * we don't clobber the device with too many - * commands. - */ - switch (ahd_get_scsi_status(scb)) { - default: - break; - case SCSI_STATUS_CHECK_COND: - case SCSI_STATUS_CMD_TERMINATED: - { - Scsi_Cmnd *cmd; - - /* - * Copy sense information to the OS's cmd - * structure if it is available. - */ - cmd = scb->io_ctx; - if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) { - struct scsi_status_iu_header *siu; - u_int sense_size; - u_int sense_offset; - - if (scb->flags & SCB_SENSE) { - sense_size = MIN(sizeof(struct scsi_sense_data) - - ahd_get_sense_residual(scb), - sizeof(cmd->sense_buffer)); - sense_offset = 0; - } else { - /* - * Copy only the sense data into the provided - * buffer. - */ - siu = (struct scsi_status_iu_header *) - scb->sense_data; - sense_size = MIN(scsi_4btoul(siu->sense_length), - sizeof(cmd->sense_buffer)); - sense_offset = SIU_SENSE_OFFSET(siu); - } - - memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); - memcpy(cmd->sense_buffer, - ahd_get_sense_buf(ahd, scb) - + sense_offset, sense_size); - cmd->result |= (DRIVER_SENSE << 24); - -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_SENSE) { - int i; - - printf("Copied %d bytes of sense data at %d:", - sense_size, sense_offset); - for (i = 0; i < sense_size; i++) { - if ((i & 0xF) == 0) - printf("\n"); - printf("0x%x ", cmd->sense_buffer[i]); - } - printf("\n"); - } -#endif - } - break; - } - case SCSI_STATUS_QUEUE_FULL: - { - /* - * By the time the core driver has returned this - * command, all other commands that were queued - * to us but not the device have been returned. - * This ensures that dev->active is equal to - * the number of commands actually queued to - * the device. - */ - dev->tag_success_count = 0; - if (dev->active != 0) { - /* - * Drop our opening count to the number - * of commands currently outstanding. - */ - dev->openings = 0; -#ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_QFULL) { - ahd_print_path(ahd, scb); - printf("Dropping tag count to %d\n", - dev->active); - } -#endif - if (dev->active == dev->tags_on_last_queuefull) { - - dev->last_queuefull_same_count++; - /* - * If we repeatedly see a queue full - * at the same queue depth, this - * device has a fixed number of tag - * slots. Lock in this tag depth - * so we stop seeing queue fulls from - * this device. - */ - if (dev->last_queuefull_same_count - == AHD_LOCK_TAGS_COUNT) { - dev->maxtags = dev->active; - ahd_print_path(ahd, scb); - printf("Locking max tag count at %d\n", - dev->active); - } - } else { - dev->tags_on_last_queuefull = dev->active; - dev->last_queuefull_same_count = 0; - } - ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); - ahd_set_scsi_status(scb, SCSI_STATUS_OK); - ahd_set_tags(ahd, &devinfo, - (dev->flags & AHD_DEV_Q_BASIC) - ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); - break; - } - /* - * Drop down to a single opening, and treat this - * as if the target returned BUSY SCSI status. - */ - dev->openings = 1; - ahd_set_tags(ahd, &devinfo, - (dev->flags & AHD_DEV_Q_BASIC) - ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); - ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); - /* FALLTHROUGH */ - } - case SCSI_STATUS_BUSY: - /* - * Set a short timer to defer sending commands for - * a bit since Linux will not delay in this case. - */ - if ((dev->flags & AHD_DEV_TIMER_ACTIVE) != 0) { - printf("%s:%c:%d: Device Timer still active during " - "busy processing\n", ahd_name(ahd), - dev->target->channel, dev->target->target); - break; - } - dev->flags |= AHD_DEV_TIMER_ACTIVE; - dev->qfrozen++; - init_timer(&dev->timer); - dev->timer.data = (u_long)dev; - dev->timer.expires = jiffies + (HZ/2); - dev->timer.function = ahd_linux_dev_timed_unfreeze; - add_timer(&dev->timer); - break; - } -} - -static void -ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, Scsi_Cmnd *cmd) -{ - /* - * Typically, the complete queue has very few entries - * queued to it before the queue is emptied by - * ahd_linux_run_complete_queue, so sorting the entries - * by generation number should be inexpensive. - * We perform the sort so that commands that complete - * with an error are retuned in the order origionally - * queued to the controller so that any subsequent retries - * are performed in order. The underlying ahd routines do - * not guarantee the order that aborted commands will be - * returned to us. - */ - struct ahd_completeq *completeq; - struct ahd_cmd *list_cmd; - struct ahd_cmd *acmd; - - /* - * Map CAM error codes into Linux Error codes. We - * avoid the conversion so that the DV code has the - * full error information available when making - * state change decisions. - */ - if (AHD_DV_CMD(cmd) == FALSE) { - uint32_t status; - u_int new_status; - - status = ahd_cmd_get_transaction_status(cmd); - if (status != CAM_REQ_CMP) { - struct ahd_linux_device *dev; - struct ahd_devinfo devinfo; - cam_status cam_status; - uint32_t action; - u_int scsi_status; - - dev = ahd_linux_get_device(ahd, cmd->channel, - cmd->device->id, - cmd->device->lun, - /*alloc*/FALSE); - - if (dev == NULL) - goto no_fallback; - - ahd_compile_devinfo(&devinfo, - ahd->our_id, - dev->target->target, dev->lun, - dev->target->channel == 0 ? 'A':'B', - ROLE_INITIATOR); - - scsi_status = ahd_cmd_get_scsi_status(cmd); - cam_status = ahd_cmd_get_transaction_status(cmd); - action = aic_error_action(cmd, dev->target->inq_data, - cam_status, scsi_status); - if ((action & SSQ_FALLBACK) != 0) { - - /* Update stats */ - dev->target->errors_detected++; - if (dev->target->cmds_since_error == 0) - dev->target->cmds_since_error++; - else { - dev->target->cmds_since_error = 0; - ahd_linux_fallback(ahd, &devinfo); - } - } - } -no_fallback: - switch (status) { - case CAM_REQ_INPROG: - case CAM_REQ_CMP: - case CAM_SCSI_STATUS_ERROR: - new_status = DID_OK; - break; - case CAM_REQ_ABORTED: - new_status = DID_ABORT; - break; - case CAM_BUSY: - new_status = DID_BUS_BUSY; - break; - case CAM_REQ_INVALID: - case CAM_PATH_INVALID: - new_status = DID_BAD_TARGET; - break; - case CAM_SEL_TIMEOUT: - new_status = DID_NO_CONNECT; - break; - case CAM_SCSI_BUS_RESET: - case CAM_BDR_SENT: - new_status = DID_RESET; - break; - case CAM_UNCOR_PARITY: - new_status = DID_PARITY; - break; - case CAM_CMD_TIMEOUT: - new_status = DID_TIME_OUT; - break; - case CAM_UA_ABORT: - case CAM_REQ_CMP_ERR: - case CAM_AUTOSENSE_FAIL: - case CAM_NO_HBA: - case CAM_DATA_RUN_ERR: - case CAM_UNEXP_BUSFREE: - case CAM_SEQUENCE_FAIL: - case CAM_CCB_LEN_ERR: - case CAM_PROVIDE_FAIL: - case CAM_REQ_TERMIO: - case CAM_UNREC_HBA_ERROR: - case CAM_REQ_TOO_BIG: - new_status = DID_ERROR; - break; - case CAM_REQUEUE_REQ: - /* - * If we want the request requeued, make sure there - * are sufficent retries. In the old scsi error code, - * we used to be able to specify a result code that - * bypassed the retry count. Now we must use this - * hack. We also "fake" a check condition with - * a sense code of ABORTED COMMAND. This seems to - * evoke a retry even if this command is being sent - * via the eh thread. Ick! Ick! Ick! - */ - if (cmd->retries > 0) - cmd->retries--; - new_status = DID_OK; - ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); - cmd->result |= (DRIVER_SENSE << 24); - memset(cmd->sense_buffer, 0, - sizeof(cmd->sense_buffer)); - cmd->sense_buffer[0] = SSD_ERRCODE_VALID - | SSD_CURRENT_ERROR; - cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND; - break; - default: - /* We should never get here */ - new_status = DID_ERROR; - break; - } - - ahd_cmd_set_transaction_status(cmd, new_status); - } - - completeq = &ahd->platform_data->completeq; - list_cmd = TAILQ_FIRST(completeq); - acmd = (struct ahd_cmd *)cmd; - while (list_cmd != NULL - && acmd_scsi_cmd(list_cmd).serial_number - < acmd_scsi_cmd(acmd).serial_number) - list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); - if (list_cmd != NULL) - TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); - else - TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); -} - -static void -ahd_linux_filter_inquiry(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) -{ - struct scsi_inquiry_data *sid; - struct ahd_initiator_tinfo *tinfo; - struct ahd_transinfo *user; - struct ahd_transinfo *goal; - struct ahd_transinfo *curr; - struct ahd_tmode_tstate *tstate; - struct ahd_linux_device *dev; - u_int width; - u_int period; - u_int offset; - u_int ppr_options; - u_int trans_version; - u_int prot_version; - static int warned_user; - - /* - * Determine if this lun actually exists. If so, - * hold on to its corresponding device structure. - * If not, make sure we release the device and - * don't bother processing the rest of this inquiry - * command. - */ - dev = ahd_linux_get_device(ahd, devinfo->channel - 'A', - devinfo->target, devinfo->lun, - /*alloc*/TRUE); - - sid = (struct scsi_inquiry_data *)dev->target->inq_data; - if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) { - - dev->flags &= ~AHD_DEV_UNCONFIGURED; - } else { - dev->flags |= AHD_DEV_UNCONFIGURED; - return; - } - - /* - * Update our notion of this device's transfer - * negotiation capabilities. - */ - tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, - devinfo->our_scsiid, - devinfo->target, &tstate); - user = &tinfo->user; - goal = &tinfo->goal; - curr = &tinfo->curr; - width = user->width; - period = user->period; - offset = user->offset; - ppr_options = user->ppr_options; - trans_version = user->transport_version; - prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid)); - - /* - * If we have read streaming info for this controller, - * apply it to this target. - */ - if (warned_user == 0 - && ahd->unit >= NUM_ELEMENTS(aic79xx_rd_strm_info)) { - - printf("aic79xx: WARNING, insufficient rd_strm instances " - "for installed controllers. Using defaults\n"); - printf("aic79xx: Please update the aic79xx_rd_strm_info " - "array in the aic79xx_osm.c source file.\n"); - warned_user++; - } else { - uint16_t rd_strm_mask; - - rd_strm_mask = aic79xx_rd_strm_info[ahd->unit]; - if ((rd_strm_mask & devinfo->target_mask) == 0) - ppr_options &= ~MSG_EXT_PPR_RD_STRM; - } - - /* - * Only attempt SPI3/4 once we've verified that - * the device claims to support SPI3/4 features. - */ - if (prot_version < SCSI_REV_2) - trans_version = SID_ANSI_REV(sid); - else - trans_version = SCSI_REV_2; - - if ((sid->flags & SID_WBus16) == 0) - width = MSG_EXT_WDTR_BUS_8_BIT; - if ((sid->flags & SID_Sync) == 0) { - period = 0; - offset = 0; - ppr_options = 0; - } - if ((sid->spi3data & SID_SPI_QAS) == 0) - ppr_options &= ~MSG_EXT_PPR_QAS_REQ; - if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0) - ppr_options &= MSG_EXT_PPR_QAS_REQ; - if ((sid->spi3data & SID_SPI_IUS) == 0) - ppr_options &= (MSG_EXT_PPR_DT_REQ - | MSG_EXT_PPR_QAS_REQ); - - if (prot_version > SCSI_REV_2 - && ppr_options != 0) - trans_version = user->transport_version; - - ahd_validate_width(ahd, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN); - ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_MAX); - ahd_validate_offset(ahd, /*tinfo limit*/NULL, period, - &offset, width, ROLE_UNKNOWN); - if (offset == 0 || period == 0) { - period = 0; - offset = 0; - ppr_options = 0; - } - /* Apply our filtered user settings. */ - curr->transport_version = trans_version; - curr->protocol_version = prot_version; - ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, /*paused*/FALSE); - ahd_set_syncrate(ahd, devinfo, period, offset, ppr_options, - AHD_TRANS_GOAL, /*paused*/FALSE); -} - -void -ahd_freeze_simq(struct ahd_softc *ahd) -{ - ahd->platform_data->qfrozen++; - if (ahd->platform_data->qfrozen == 1) { - scsi_block_requests(ahd->platform_data->host); - ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, - CAM_LUN_WILDCARD, SCB_LIST_NULL, - ROLE_INITIATOR, CAM_REQUEUE_REQ); - } -} - -void -ahd_release_simq(struct ahd_softc *ahd) -{ - u_long s; - int unblock_reqs; - - unblock_reqs = 0; - ahd_lock(ahd, &s); - if (ahd->platform_data->qfrozen > 0) - ahd->platform_data->qfrozen--; - if (ahd->platform_data->qfrozen == 0) { - unblock_reqs = 1; - } - if (AHD_DV_SIMQ_FROZEN(ahd) - && ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_RELEASE) != 0)) { - ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE; - up(&ahd->platform_data->dv_sem); - } - ahd_unlock(ahd, &s); - /* - * There is still a race here. The mid-layer - * should keep its own freeze count and use - * a bottom half handler to run the queues - * so we can unblock with our own lock held. - */ - if (unblock_reqs) - scsi_unblock_requests(ahd->platform_data->host); - - ahd_schedule_runq(ahd); -} - -static void -ahd_linux_sem_timeout(u_long arg) -{ - struct ahd_softc *ahd; - u_long s; - - ahd = (struct ahd_softc *)arg; - ahd_lock(ahd, &s); - if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { - ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; - up(&ahd->platform_data->eh_sem); - } - ahd_unlock(ahd, &s); -} - -static void -ahd_linux_dev_timed_unfreeze(u_long arg) -{ - struct ahd_linux_device *dev; - struct ahd_softc *ahd; - u_long s; - - dev = (struct ahd_linux_device *)arg; - ahd = dev->target->ahd; - ahd_lock(ahd, &s); - dev->flags &= ~AHD_DEV_TIMER_ACTIVE; - if (dev->qfrozen > 0) - dev->qfrozen--; - if (dev->qfrozen == 0 - && (dev->flags & AHD_DEV_ON_RUN_LIST) == 0) - ahd_linux_run_device_queue(ahd, dev); - ahd_unlock(ahd, &s); -} - -void -ahd_platform_dump_card_state(struct ahd_softc *ahd) -{ - struct ahd_linux_device *dev; - int target; - int maxtarget; - int lun; - int i; - - maxtarget = (ahd->features & AHD_WIDE) ? 15 : 7; - for (target = 0; target <=maxtarget; target++) { - - for (lun = 0; lun < AHD_NUM_LUNS; lun++) { - struct ahd_cmd *acmd; - - dev = ahd_linux_get_device(ahd, 0, target, - lun, /*alloc*/FALSE); - if (dev == NULL) - continue; - - printf("DevQ(%d:%d:%d): ", 0, target, lun); - i = 0; - TAILQ_FOREACH(acmd, &dev->busyq, acmd_links.tqe) { - if (i++ > AHD_SCB_MAX) - break; - } - printf("%d waiting\n", i); - } - } -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_osm.h linux-2.4.22/drivers/scsi/aic79xx/aic79xx_osm.h --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_osm.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_osm.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,1288 +0,0 @@ -/* - * Adaptec AIC79xx device driver for Linux. - * - * Copyright (c) 2000-2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#108 $ - * - */ -#ifndef _AIC79XX_LINUX_H_ -#define _AIC79XX_LINUX_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef AHD_MODVERSION_FILE -#define __NO_VERSION__ -#endif -#include -#include -#include - -#ifndef KERNEL_VERSION -#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -#include /* For tasklet support. */ -#include -#include -#else -#include -#endif - -/* Core SCSI definitions */ -#define AIC_LIB_PREFIX ahd -#include "scsi.h" -#include "hosts.h" - -/* Name space conflict with BSD queue macros */ -#ifdef LIST_HEAD -#undef LIST_HEAD -#endif - -#include "cam.h" -#include "queue.h" -#include "scsi_message.h" -#include "scsi_iu.h" -#include "aiclib.h" - -/*********************************** Debugging ********************************/ -#ifdef CONFIG_AIC79XX_DEBUG_ENABLE -#ifdef CONFIG_AIC79XX_DEBUG_MASK -#define AHD_DEBUG 1 -#define AHD_DEBUG_OPTS CONFIG_AIC79XX_DEBUG_MASK -#else -/* - * Compile in debugging code, but do not enable any printfs. - */ -#define AHD_DEBUG 1 -#endif -/* No debugging code. */ -#endif - -/********************************** Misc Macros *******************************/ -#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) -#define powerof2(x) ((((x)-1)&(x))==0) - -/************************* Forward Declarations *******************************/ -struct ahd_softc; -typedef struct pci_dev *ahd_dev_softc_t; -typedef Scsi_Cmnd *ahd_io_ctx_t; - -/******************************* Byte Order ***********************************/ -#define ahd_htobe16(x) cpu_to_be16(x) -#define ahd_htobe32(x) cpu_to_be32(x) -#define ahd_htobe64(x) cpu_to_be64(x) -#define ahd_htole16(x) cpu_to_le16(x) -#define ahd_htole32(x) cpu_to_le32(x) -#define ahd_htole64(x) cpu_to_le64(x) - -#define ahd_be16toh(x) be16_to_cpu(x) -#define ahd_be32toh(x) be32_to_cpu(x) -#define ahd_be64toh(x) be64_to_cpu(x) -#define ahd_le16toh(x) le16_to_cpu(x) -#define ahd_le32toh(x) le32_to_cpu(x) -#define ahd_le64toh(x) le64_to_cpu(x) - -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif - -#ifndef BYTE_ORDER -#if defined(__BIG_ENDIAN) -#define BYTE_ORDER BIG_ENDIAN -#endif -#if defined(__LITTLE_ENDIAN) -#define BYTE_ORDER LITTLE_ENDIAN -#endif -#endif /* BYTE_ORDER */ - -/************************* Configuration Data *********************************/ -extern int aic79xx_allow_memio; -extern int aic79xx_detect_complete; -extern Scsi_Host_Template aic79xx_driver_template; - -/***************************** Bus Space/DMA **********************************/ - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17) -typedef dma_addr_t bus_addr_t; -#else -typedef uint32_t bus_addr_t; -#endif -typedef uint32_t bus_size_t; - -typedef enum { - BUS_SPACE_MEMIO, - BUS_SPACE_PIO -} bus_space_tag_t; - -typedef union { - u_long ioport; - volatile uint8_t *maddr; -} bus_space_handle_t; - -typedef struct bus_dma_segment -{ - bus_addr_t ds_addr; - bus_size_t ds_len; -} bus_dma_segment_t; - -struct ahd_linux_dma_tag -{ - bus_size_t alignment; - bus_size_t boundary; - bus_size_t maxsize; -}; -typedef struct ahd_linux_dma_tag* bus_dma_tag_t; - -struct ahd_linux_dmamap -{ - bus_addr_t bus_addr; -}; -typedef struct ahd_linux_dmamap* bus_dmamap_t; - -typedef int bus_dma_filter_t(void*, bus_addr_t); -typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); - -#define BUS_DMA_WAITOK 0x0 -#define BUS_DMA_NOWAIT 0x1 -#define BUS_DMA_ALLOCNOW 0x2 -#define BUS_DMA_LOAD_SEGS 0x4 /* - * Argument is an S/G list not - * a single buffer. - */ - -#define BUS_SPACE_MAXADDR 0xFFFFFFFF -#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF -#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF - -int ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/, - bus_size_t /*alignment*/, bus_size_t /*boundary*/, - bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/, - bus_dma_filter_t*/*filter*/, void */*filterarg*/, - bus_size_t /*maxsize*/, int /*nsegments*/, - bus_size_t /*maxsegsz*/, int /*flags*/, - bus_dma_tag_t */*dma_tagp*/); - -void ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/); - -int ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t /*dmat*/, - void** /*vaddr*/, int /*flags*/, - bus_dmamap_t* /*mapp*/); - -void ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t /*dmat*/, - void* /*vaddr*/, bus_dmamap_t /*map*/); - -void ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/, - bus_dmamap_t /*map*/); - -int ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t /*dmat*/, - bus_dmamap_t /*map*/, void * /*buf*/, - bus_size_t /*buflen*/, bus_dmamap_callback_t *, - void */*callback_arg*/, int /*flags*/); - -int ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t); - -/* - * Operations performed by ahd_dmamap_sync(). - */ -#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ -#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ -#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ -#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ - -/* - * XXX - * ahd_dmamap_sync is only used on buffers allocated with - * the pci_alloc_consistent() API. Although I'm not sure how - * this works on architectures with a write buffer, Linux does - * not have an API to sync "coherent" memory. Perhaps we need - * to do an mb()? - */ -#define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op) - -/************************** Timer DataStructures ******************************/ -typedef struct timer_list ahd_timer_t; - -/********************************** Includes **********************************/ -#if CONFIG_AIC79XX_REG_PRETTY_PRINT -#define AIC_DEBUG_REGISTERS 1 -#else -#define AIC_DEBUG_REGISTERS 0 -#endif -#include "aic79xx.h" - -/***************************** Timer Facilities *******************************/ -#define ahd_timer_init init_timer -#define ahd_timer_stop del_timer -typedef void ahd_linux_callback_t (u_long); -static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec, - ahd_callback_t *func, void *arg); -static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec); - -static __inline void -ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg) -{ - struct ahd_softc *ahd; - - ahd = (struct ahd_softc *)arg; - del_timer(timer); - timer->data = (u_long)arg; - timer->expires = jiffies + (usec * HZ)/1000000; - timer->function = (ahd_linux_callback_t*)func; - add_timer(timer); -} - -static __inline void -ahd_scb_timer_reset(struct scb *scb, u_int usec) -{ - mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); -} - -/***************************** SMP support ************************************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17) -#include -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) -#include -#endif - -#define AIC79XX_DRIVER_VERSION "1.3.0" - -/**************************** Front End Queues ********************************/ -/* - * Data structure used to cast the Linux struct scsi_cmnd to something - * that allows us to use the queue macros. The linux structure has - * plenty of space to hold the links fields as required by the queue - * macros, but the queue macors require them to have the correct type. - */ -struct ahd_cmd_internal { - /* Area owned by the Linux scsi layer. */ - uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)]; - union { - STAILQ_ENTRY(ahd_cmd) ste; - LIST_ENTRY(ahd_cmd) le; - TAILQ_ENTRY(ahd_cmd) tqe; - } links; - uint32_t end; -}; - -struct ahd_cmd { - union { - struct ahd_cmd_internal icmd; - struct scsi_cmnd scsi_cmd; - } un; -}; - -#define acmd_icmd(cmd) ((cmd)->un.icmd) -#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd) -#define acmd_links un.icmd.links - -/*************************** Device Data Structures ***************************/ -/* - * A per probed device structure used to deal with some error recovery - * scenarios that the Linux mid-layer code just doesn't know how to - * handle. The structure allocated for a device only becomes persistant - * after a successfully completed inquiry command to the target when - * that inquiry data indicates a lun is present. - */ -TAILQ_HEAD(ahd_busyq, ahd_cmd); -typedef enum { - AHD_DEV_UNCONFIGURED = 0x01, - AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ - AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ - AHD_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ - AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ - AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ - AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ - AHD_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ -} ahd_linux_dev_flags; - -struct ahd_linux_target; -struct ahd_linux_device { - TAILQ_ENTRY(ahd_linux_device) links; - struct ahd_busyq busyq; - - /* - * The number of transactions currently - * queued to the device. - */ - int active; - - /* - * The currently allowed number of - * transactions that can be queued to - * the device. Must be signed for - * conversion from tagged to untagged - * mode where the device may have more - * than one outstanding active transaction. - */ - int openings; - - /* - * A positive count indicates that this - * device's queue is halted. - */ - u_int qfrozen; - - /* - * Cumulative command counter. - */ - u_long commands_issued; - - /* - * The number of tagged transactions when - * running at our current opening level - * that have been successfully received by - * this device since the last QUEUE FULL. - */ - u_int tag_success_count; -#define AHD_TAG_SUCCESS_INTERVAL 50 - - ahd_linux_dev_flags flags; - - /* - * Per device timer. - */ - struct timer_list timer; - - /* - * The high limit for the tags variable. - */ - u_int maxtags; - - /* - * The computed number of tags outstanding - * at the time of the last QUEUE FULL event. - */ - u_int tags_on_last_queuefull; - - /* - * How many times we have seen a queue full - * with the same number of tags. This is used - * to stop our adaptive queue depth algorithm - * on devices with a fixed number of tags. - */ - u_int last_queuefull_same_count; -#define AHD_LOCK_TAGS_COUNT 50 - - /* - * How many transactions have been queued - * without the device going idle. We use - * this statistic to determine when to issue - * an ordered tag to prevent transaction - * starvation. This statistic is only updated - * if the AHD_DEV_PERIODIC_OTAG flag is set - * on this device. - */ - u_int commands_since_idle_or_otag; -#define AHD_OTAG_THRESH 500 - - int lun; - Scsi_Device *scsi_device; - struct ahd_linux_target *target; -}; - -typedef enum { - AHD_DV_REQUIRED = 0x01, - AHD_INQ_VALID = 0x02, - AHD_BASIC_DV = 0x04, - AHD_ENHANCED_DV = 0x08 -} ahd_linux_targ_flags; - -/* DV States */ -typedef enum { - AHD_DV_STATE_EXIT = 0, - AHD_DV_STATE_INQ_SHORT_ASYNC, - AHD_DV_STATE_INQ_ASYNC, - AHD_DV_STATE_INQ_ASYNC_VERIFY, - AHD_DV_STATE_TUR, - AHD_DV_STATE_REBD, - AHD_DV_STATE_INQ_VERIFY, - AHD_DV_STATE_WEB, - AHD_DV_STATE_REB, - AHD_DV_STATE_SU, - AHD_DV_STATE_BUSY -} ahd_dv_state; - -struct ahd_linux_target { - struct ahd_linux_device *devices[AHD_NUM_LUNS]; - int channel; - int target; - int refcount; - struct ahd_transinfo last_tinfo; - struct ahd_softc *ahd; - ahd_linux_targ_flags flags; - struct scsi_inquiry_data *inq_data; - /* - * The next "fallback" period to use for narrow/wide transfers. - */ - uint8_t dv_next_narrow_period; - uint8_t dv_next_wide_period; - uint8_t dv_max_width; - uint8_t dv_max_ppr_options; - uint8_t dv_last_ppr_options; - u_int dv_echo_size; - ahd_dv_state dv_state; - u_int dv_state_retry; - uint8_t *dv_buffer; - uint8_t *dv_buffer1; - - /* - * Cumulative counter of errors. - */ - u_long errors_detected; - u_long cmds_since_error; -}; - -/********************* Definitions Required by the Core ***********************/ -/* - * Number of SG segments we require. So long as the S/G segments for - * a particular transaction are allocated in a physically contiguous - * manner and are allocated below 4GB, the number of S/G segments is - * unrestricted. - */ -#define AHD_NSEG 128 - -/* - * Per-SCB OSM storage. - */ -typedef enum { - AHD_UP_EH_SEMAPHORE = 0x1 -} ahd_linux_scb_flags; - -struct scb_platform_data { - struct ahd_linux_device *dev; - bus_addr_t buf_busaddr; - uint32_t xfer_len; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) - uint32_t resid; /* Transfer residual */ -#endif - uint32_t sense_resid; /* Auto-Sense residual */ - ahd_linux_scb_flags flags; -}; - -/* - * Define a structure used for each host adapter. All members are - * aligned on a boundary >= the size of the member to honor the - * alignment restrictions of the various platforms supported by - * this driver. - */ -typedef enum { - AHD_DV_WAIT_SIMQ_EMPTY = 0x01, - AHD_DV_WAIT_SIMQ_RELEASE = 0x02, - AHD_DV_ACTIVE = 0x04, - AHD_DV_SHUTDOWN = 0x08, - AHD_RUN_CMPLT_Q_TIMER = 0x10 -} ahd_linux_softc_flags; - -TAILQ_HEAD(ahd_completeq, ahd_cmd); - -struct ahd_platform_data { - /* - * Fields accessed from interrupt context. - */ - struct ahd_linux_target *targets[AHD_NUM_TARGETS]; - TAILQ_HEAD(, ahd_linux_device) device_runq; - struct ahd_completeq completeq; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) - spinlock_t spin_lock; -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - struct tasklet_struct runq_tasklet; -#endif - u_int qfrozen; - pid_t dv_pid; - struct timer_list completeq_timer; - struct timer_list reset_timer; - struct timer_list stats_timer; - struct semaphore eh_sem; - struct semaphore dv_sem; - struct semaphore dv_cmd_sem; /* XXX This needs to be in - * the target struct - */ - struct scsi_device *dv_scsi_dev; - struct Scsi_Host *host; /* pointer to scsi host */ -#define AHD_LINUX_NOIRQ ((uint32_t)~0) - uint32_t irq; /* IRQ for this adapter */ - uint32_t bios_address; - uint32_t mem_busaddr; /* Mem Base Addr */ - bus_addr_t hw_dma_mask; - ahd_linux_softc_flags flags; -}; - -/************************** OS Utility Wrappers *******************************/ -#define printf printk -#define M_NOWAIT GFP_ATOMIC -#define M_WAITOK 0 -#define malloc(size, type, flags) kmalloc(size, flags) -#define free(ptr, type) kfree(ptr) - -static __inline void ahd_delay(long); -static __inline void -ahd_delay(long usec) -{ - /* - * udelay on Linux can have problems for - * multi-millisecond waits. Wait at most - * 1024us per call. - */ - while (usec > 0) { - udelay(usec % 1024); - usec -= 1024; - } -} - - -/***************************** Low Level I/O **********************************/ -#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__) -#define MMAPIO -#endif - -static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port); -static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port); -static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val); -static __inline void ahd_outw_atomic(struct ahd_softc * ahd, - long port, uint16_t val); -static __inline void ahd_outsb(struct ahd_softc * ahd, long port, - uint8_t *, int count); -static __inline void ahd_insb(struct ahd_softc * ahd, long port, - uint8_t *, int count); - -static __inline uint8_t -ahd_inb(struct ahd_softc * ahd, long port) -{ - uint8_t x; -#ifdef MMAPIO - - if (ahd->tags[0] == BUS_SPACE_MEMIO) { - x = readb(ahd->bshs[0].maddr + port); - } else { - x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); - } -#else - x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); -#endif - mb(); - return (x); -} - -static __inline uint16_t -ahd_inw_atomic(struct ahd_softc * ahd, long port) -{ - uint8_t x; -#ifdef MMAPIO - - if (ahd->tags[0] == BUS_SPACE_MEMIO) { - x = readw(ahd->bshs[0].maddr + port); - } else { - x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); - } -#else - x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); -#endif - mb(); - return (x); -} - -static __inline void -ahd_outb(struct ahd_softc * ahd, long port, uint8_t val) -{ -#ifdef MMAPIO - if (ahd->tags[0] == BUS_SPACE_MEMIO) { - writeb(val, ahd->bshs[0].maddr + port); - } else { - outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); - } -#else - outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); -#endif - mb(); -} - -static __inline void -ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val) -{ -#ifdef MMAPIO - if (ahd->tags[0] == BUS_SPACE_MEMIO) { - writew(val, ahd->bshs[0].maddr + port); - } else { - outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); - } -#else - outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); -#endif - mb(); -} - -static __inline void -ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count) -{ - int i; - - /* - * There is probably a more efficient way to do this on Linux - * but we don't use this for anything speed critical and this - * should work. - */ - for (i = 0; i < count; i++) - ahd_outb(ahd, port, *array++); -} - -static __inline void -ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count) -{ - int i; - - /* - * There is probably a more efficient way to do this on Linux - * but we don't use this for anything speed critical and this - * should work. - */ - for (i = 0; i < count; i++) - *array++ = ahd_inb(ahd, port); -} - -/**************************** Initialization **********************************/ -int ahd_linux_register_host(struct ahd_softc *, - Scsi_Host_Template *); - -uint64_t ahd_linux_get_memsize(void); - -/*************************** Pretty Printing **********************************/ -struct info_str { - char *buffer; - int length; - off_t offset; - int pos; -}; - -void ahd_format_transinfo(struct info_str *info, - struct ahd_transinfo *tinfo); - -/******************************** Locking *************************************/ -/* Lock protecting internal data structures */ -static __inline void ahd_lockinit(struct ahd_softc *); -static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags); -static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags); - -/* Lock acquisition and release of the above lock in midlayer entry points. */ -static __inline void ahd_midlayer_entrypoint_lock(struct ahd_softc *, - unsigned long *flags); -static __inline void ahd_midlayer_entrypoint_unlock(struct ahd_softc *, - unsigned long *flags); - -/* Lock held during command compeletion to the upper layer */ -static __inline void ahd_done_lockinit(struct ahd_softc *); -static __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags); -static __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags); - -/* Lock held during ahd_list manipulation and ahd softc frees */ -extern spinlock_t ahd_list_spinlock; -static __inline void ahd_list_lockinit(void); -static __inline void ahd_list_lock(unsigned long *flags); -static __inline void ahd_list_unlock(unsigned long *flags); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) -static __inline void -ahd_lockinit(struct ahd_softc *ahd) -{ - spin_lock_init(&ahd->platform_data->spin_lock); -} - -static __inline void -ahd_lock(struct ahd_softc *ahd, unsigned long *flags) -{ - *flags = 0; - spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags); -} - -static __inline void -ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) -{ - spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags); -} - -static __inline void -ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags) -{ - /* - * In 2.5.X, the midlayer takes our lock just before - * calling us, so avoid locking again. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_lock(ahd, flags); -#endif -} - -static __inline void -ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags) -{ - /* - * In 2.5.X, the midlayer takes our lock just before - * calling us and unlocks when we return, so let it do the unlock. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, flags); -#endif -} - -static __inline void -ahd_done_lockinit(struct ahd_softc *ahd) -{ - /* - * In 2.5.X, our own lock is held during completions. - * In previous versions, the io_request_lock is used. - * In either case, we can't initialize this lock again. - */ -} - -static __inline void -ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - *flags = 0; - spin_lock_irqsave(&io_request_lock, *flags); -#endif -} - -static __inline void -ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irqrestore(&io_request_lock, *flags); -#endif -} - -static __inline void -ahd_list_lockinit() -{ - spin_lock_init(&ahd_list_spinlock); -} - -static __inline void -ahd_list_lock(unsigned long *flags) -{ - *flags = 0; - spin_lock_irqsave(&ahd_list_spinlock, *flags); -} - -static __inline void -ahd_list_unlock(unsigned long *flags) -{ - spin_unlock_irqrestore(&ahd_list_spinlock, *flags); -} - -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ - -ahd_lockinit(struct ahd_softc *ahd) -{ -} - -static __inline void -ahd_lock(struct ahd_softc *ahd, unsigned long *flags) -{ - *flags = 0; - save_flags(*flags); - cli(); -} - -static __inline void -ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) -{ - restore_flags(*flags); -} - -ahd_done_lockinit(struct ahd_softc *ahd) -{ -} - -static __inline void -ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) -{ - /* - * The done lock is always held while - * the ahd lock is held so blocking - * interrupts again would have no effect. - */ -} - -static __inline void -ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) -{ -} - -static __inline void -ahd_list_lockinit() -{ -} - -static __inline void -ahd_list_lock(unsigned long *flags) -{ - *flags = 0; - save_flags(*flags); - cli(); -} - -static __inline void -ahd_list_unlock(unsigned long *flags) -{ - restore_flags(*flags); -} -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ - -/******************************* PCI Definitions ******************************/ -/* - * PCIM_xxx: mask to locate subfield in register - * PCIR_xxx: config register offset - * PCIC_xxx: device class - * PCIS_xxx: device subclass - * PCIP_xxx: device programming interface - * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) - * PCID_xxx: device ID - */ -#define PCIR_DEVVENDOR 0x00 -#define PCIR_VENDOR 0x00 -#define PCIR_DEVICE 0x02 -#define PCIR_COMMAND 0x04 -#define PCIM_CMD_PORTEN 0x0001 -#define PCIM_CMD_MEMEN 0x0002 -#define PCIM_CMD_BUSMASTEREN 0x0004 -#define PCIM_CMD_MWRICEN 0x0010 -#define PCIM_CMD_PERRESPEN 0x0040 -#define PCIM_CMD_SERRESPEN 0x0100 -#define PCIR_STATUS 0x06 -#define PCIR_REVID 0x08 -#define PCIR_PROGIF 0x09 -#define PCIR_SUBCLASS 0x0a -#define PCIR_CLASS 0x0b -#define PCIR_CACHELNSZ 0x0c -#define PCIR_LATTIMER 0x0d -#define PCIR_HEADERTYPE 0x0e -#define PCIM_MFDEV 0x80 -#define PCIR_BIST 0x0f -#define PCIR_CAP_PTR 0x34 - -/* config registers for header type 0 devices */ -#define PCIR_MAPS 0x10 -#define PCIR_SUBVEND_0 0x2c -#define PCIR_SUBDEV_0 0x2e - -/****************************** PCI-X definitions *****************************/ -#define PCIXR_COMMAND 0x96 -#define PCIXR_DEVADDR 0x98 -#define PCIXM_DEVADDR_FNUM 0x0003 /* Function Number */ -#define PCIXM_DEVADDR_DNUM 0x00F8 /* Device Number */ -#define PCIXM_DEVADDR_BNUM 0xFF00 /* Bus Number */ -#define PCIXR_STATUS 0x9A -#define PCIXM_STATUS_64BIT 0x0001 /* Active 64bit connection to device. */ -#define PCIXM_STATUS_133CAP 0x0002 /* Device is 133MHz capable */ -#define PCIXM_STATUS_SCDISC 0x0004 /* Split Completion Discarded */ -#define PCIXM_STATUS_UNEXPSC 0x0008 /* Unexpected Split Completion */ -#define PCIXM_STATUS_CMPLEXDEV 0x0010 /* Device Complexity (set == bridge) */ -#define PCIXM_STATUS_MAXMRDBC 0x0060 /* Maximum Burst Read Count */ -#define PCIXM_STATUS_MAXSPLITS 0x0380 /* Maximum Split Transactions */ -#define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ -#define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -extern struct pci_driver aic79xx_pci_driver; -#endif - -typedef enum -{ - AHD_POWER_STATE_D0, - AHD_POWER_STATE_D1, - AHD_POWER_STATE_D2, - AHD_POWER_STATE_D3 -} ahd_power_state; - -void ahd_power_state_change(struct ahd_softc *ahd, - ahd_power_state new_state); - -/******************************* PCI Routines *********************************/ -/* - * We need to use the bios32.h routines if we are kernel version 2.1.92 or less. - */ -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92) -#if defined(__sparc_v9__) || defined(__powerpc__) -#error "PPC and Sparc platforms are only support under 2.1.92 and above" -#endif -#include -#endif - -int ahd_linux_pci_probe(Scsi_Host_Template *); -int ahd_pci_map_registers(struct ahd_softc *ahd); -int ahd_pci_map_int(struct ahd_softc *ahd); - -static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci, - int reg, int width); - -static __inline uint32_t -ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width) -{ - switch (width) { - case 1: - { - uint8_t retval; - - pci_read_config_byte(pci, reg, &retval); - return (retval); - } - case 2: - { - uint16_t retval; - pci_read_config_word(pci, reg, &retval); - return (retval); - } - case 4: - { - uint32_t retval; - pci_read_config_dword(pci, reg, &retval); - return (retval); - } - default: - panic("ahd_pci_read_config: Read size too big"); - /* NOTREACHED */ - return (0); - } -} - -static __inline void ahd_pci_write_config(ahd_dev_softc_t pci, - int reg, uint32_t value, - int width); - -static __inline void -ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width) -{ - switch (width) { - case 1: - pci_write_config_byte(pci, reg, value); - break; - case 2: - pci_write_config_word(pci, reg, value); - break; - case 4: - pci_write_config_dword(pci, reg, value); - break; - default: - panic("ahd_pci_write_config: Write size too big"); - /* NOTREACHED */ - } -} - -static __inline int ahd_get_pci_function(ahd_dev_softc_t); -static __inline int -ahd_get_pci_function(ahd_dev_softc_t pci) -{ - return (PCI_FUNC(pci->devfn)); -} - -static __inline int ahd_get_pci_slot(ahd_dev_softc_t); -static __inline int -ahd_get_pci_slot(ahd_dev_softc_t pci) -{ - return (PCI_SLOT(pci->devfn)); -} - -static __inline int ahd_get_pci_bus(ahd_dev_softc_t); -static __inline int -ahd_get_pci_bus(ahd_dev_softc_t pci) -{ - return (pci->bus->number); -} - -static __inline void ahd_flush_device_writes(struct ahd_softc *); -static __inline void -ahd_flush_device_writes(struct ahd_softc *ahd) -{ - /* XXX Is this sufficient for all architectures??? */ - ahd_inb(ahd, INTSTAT); -} - -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0) -#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg) -#define pci_unmap_sg(pdev, sg_list, nseg, direction) -#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address)) -#define sg_dma_len(sg) ((sg)->length) -#define pci_map_single(pdev, buffer, bufflen, direction) \ - (VIRT_TO_BUS(buffer)) -#define pci_unmap_single(pdev, buffer, buflen, direction) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) -#define ahd_pci_set_dma_mask pci_set_dma_mask -#else -/* - * Always "return" 0 for success. - */ -#define ahd_pci_set_dma_mask(dev_softc, mask) \ - (((dev_softc)->dma_mask = mask) && 0) -#endif -/**************************** Proc FS Support *********************************/ -int ahd_linux_proc_info(char *, char **, off_t, int, int, int); - -/*************************** Domain Validation ********************************/ -#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete) -#define AHD_DV_SIMQ_FROZEN(ahd) \ - ((((ahd)->platform_data->flags & AHD_DV_ACTIVE) != 0) \ - && (ahd)->platform_data->qfrozen == 1) - -/*********************** Transaction Access Wrappers **************************/ -static __inline void ahd_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); -static __inline void ahd_set_transaction_status(struct scb *, uint32_t); -static __inline void ahd_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); -static __inline void ahd_set_scsi_status(struct scb *, uint32_t); -static __inline uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd); -static __inline uint32_t ahd_get_transaction_status(struct scb *); -static __inline uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd); -static __inline uint32_t ahd_get_scsi_status(struct scb *); -static __inline void ahd_set_transaction_tag(struct scb *, int, u_int); -static __inline u_long ahd_get_transfer_length(struct scb *); -static __inline int ahd_get_transfer_dir(struct scb *); -static __inline void ahd_set_residual(struct scb *, u_long); -static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid); -static __inline u_long ahd_get_residual(struct scb *); -static __inline u_long ahd_get_sense_residual(struct scb *); -static __inline int ahd_perform_autosense(struct scb *); -static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *, - struct scb *); -static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *, - struct ahd_devinfo *); -static __inline void ahd_platform_scb_free(struct ahd_softc *ahd, - struct scb *scb); -static __inline void ahd_freeze_scb(struct scb *scb); - -static __inline -void ahd_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) -{ - cmd->result &= ~(CAM_STATUS_MASK << 16); - cmd->result |= status << 16; -} - -static __inline -void ahd_set_transaction_status(struct scb *scb, uint32_t status) -{ - ahd_cmd_set_transaction_status(scb->io_ctx,status); -} - -static __inline -void ahd_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) -{ - cmd->result &= ~0xFFFF; - cmd->result |= status; -} - -static __inline -void ahd_set_scsi_status(struct scb *scb, uint32_t status) -{ - ahd_cmd_set_scsi_status(scb->io_ctx, status); -} - -static __inline -uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd) -{ - return ((cmd->result >> 16) & CAM_STATUS_MASK); -} - -static __inline -uint32_t ahd_get_transaction_status(struct scb *scb) -{ - return (ahd_cmd_get_transaction_status(scb->io_ctx)); -} - -static __inline -uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd) -{ - return (cmd->result & 0xFFFF); -} - -static __inline -uint32_t ahd_get_scsi_status(struct scb *scb) -{ - return (ahd_cmd_get_scsi_status(scb->io_ctx)); -} - -static __inline -void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type) -{ - /* - * Nothing to do for linux as the incoming transaction - * has no concept of tag/non tagged, etc. - */ -} - -static __inline -u_long ahd_get_transfer_length(struct scb *scb) -{ - return (scb->platform_data->xfer_len); -} - -static __inline -int ahd_get_transfer_dir(struct scb *scb) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40) - return (scb->io_ctx->sc_data_direction); -#else - if (scb->io_ctx->bufflen == 0) - return (CAM_DIR_NONE); - - switch(scb->io_ctx->cmnd[0]) { - case 0x08: /* READ(6) */ - case 0x28: /* READ(10) */ - case 0xA8: /* READ(12) */ - return (CAM_DIR_IN); - case 0x0A: /* WRITE(6) */ - case 0x2A: /* WRITE(10) */ - case 0xAA: /* WRITE(12) */ - return (CAM_DIR_OUT); - default: - return (CAM_DIR_NONE); - } -#endif -} - -static __inline -void ahd_set_residual(struct scb *scb, u_long resid) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - scb->io_ctx->resid = resid; -#else - scb->platform_data->resid = resid; -#endif -} - -static __inline -void ahd_set_sense_residual(struct scb *scb, u_long resid) -{ - scb->platform_data->sense_resid = resid; -} - -static __inline -u_long ahd_get_residual(struct scb *scb) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - return (scb->io_ctx->resid); -#else - return (scb->platform_data->resid); -#endif -} - -static __inline -u_long ahd_get_sense_residual(struct scb *scb) -{ - return (scb->platform_data->sense_resid); -} - -static __inline -int ahd_perform_autosense(struct scb *scb) -{ - /* - * We always perform autosense in Linux. - * On other platforms this is set on a - * per-transaction basis. - */ - return (1); -} - -static __inline uint32_t -ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb) -{ - return (sizeof(struct scsi_sense_data)); -} - -static __inline void -ahd_notify_xfer_settings_change(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo) -{ - /* Nothing to do here for linux */ -} - -static __inline void -ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb) -{ - ahd->flags &= ~AHD_RESOURCE_SHORTAGE; -} - -int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); -void ahd_platform_free(struct ahd_softc *ahd); -void ahd_platform_init(struct ahd_softc *ahd); -void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb); -void ahd_freeze_simq(struct ahd_softc *ahd); -void ahd_release_simq(struct ahd_softc *ahd); - -static __inline void -ahd_freeze_scb(struct scb *scb) -{ - if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) { - scb->io_ctx->result |= CAM_DEV_QFRZN << 16; - scb->platform_data->dev->qfrozen++; - } -} - -void ahd_platform_set_tags(struct ahd_softc *ahd, - struct ahd_devinfo *devinfo, ahd_queue_alg); -int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, - char channel, int lun, u_int tag, - role_t role, uint32_t status); -void ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); -void ahd_platform_flushwork(struct ahd_softc *ahd); -int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *); -void ahd_done(struct ahd_softc*, struct scb*); -void ahd_send_async(struct ahd_softc *, char channel, - u_int target, u_int lun, ac_code, void *); -void ahd_print_path(struct ahd_softc *, struct scb *); -void ahd_platform_dump_card_state(struct ahd_softc *ahd); - -#ifdef CONFIG_PCI -#define AHD_PCI_CONFIG 1 -#else -#define AHD_PCI_CONFIG 0 -#endif -#define bootverbose aic79xx_verbose -extern int aic79xx_verbose; -#endif /* _AIC79XX_LINUX_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_osm_pci.c linux-2.4.22/drivers/scsi/aic79xx/aic79xx_osm_pci.c --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_osm_pci.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_osm_pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,432 +0,0 @@ -/* - * Linux driver attachment glue for PCI based U320 controllers. - * - * Copyright (c) 2000-2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#20 $ - */ - -#include "aic79xx_osm.h" -#include "aic79xx_inline.h" - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -struct pci_device_id -{ -}; -#endif - -static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, - const struct pci_device_id *ent); -static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, - u_long *base, u_long *base2); -static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, - u_long *bus_addr, - uint8_t **maddr); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); - -/* We do our own ID filtering. So, grab all SCSI storage class devices. */ -static struct pci_device_id ahd_linux_pci_id_table[] = { - { - 0x9005, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0 - }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); - -struct pci_driver aic79xx_pci_driver = { - name: "aic79xx", - probe: ahd_linux_pci_dev_probe, - remove: ahd_linux_pci_dev_remove, - id_table: ahd_linux_pci_id_table -}; - -static void -ahd_linux_pci_dev_remove(struct pci_dev *pdev) -{ - struct ahd_softc *ahd; - u_long l; - - /* - * We should be able to just perform - * the free directly, but check our - * list for extra sanity. - */ - ahd_list_lock(&l); - ahd = ahd_find_softc((struct ahd_softc *)pci_get_drvdata(pdev)); - if (ahd != NULL) { - u_long s; - - ahd_lock(ahd, &s); - ahd_intr_enable(ahd, FALSE); - ahd_unlock(ahd, &s); - ahd_free(ahd); - } - ahd_list_unlock(&l); -} -#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */ - -static int -ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - char buf[80]; - struct ahd_softc *ahd; - ahd_dev_softc_t pci; - struct ahd_pci_identity *entry; - char *name; - int error; - - /* - * Some BIOSen report the same device multiple times. - */ - TAILQ_FOREACH(ahd, &ahd_tailq, links) { - struct pci_dev *probed_pdev; - - probed_pdev = ahd->dev_softc; - if (probed_pdev->bus->number == pdev->bus->number - && probed_pdev->devfn == pdev->devfn) - break; - } - if (ahd != NULL) { - /* Skip duplicate. */ - return (-ENODEV); - } - - pci = pdev; - entry = ahd_find_pci_device(pci); - if (entry == NULL) - return (-ENODEV); - - /* - * Allocate a softc for this card and - * set it up for attachment by our - * common detect routine. - */ - sprintf(buf, "ahd_pci:%d:%d:%d", - ahd_get_pci_bus(pci), - ahd_get_pci_slot(pci), - ahd_get_pci_function(pci)); - name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); - if (name == NULL) - return (-ENOMEM); - strcpy(name, buf); - ahd = ahd_alloc(NULL, name); - if (ahd == NULL) - return (-ENOMEM); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - if (pci_enable_device(pdev)) { - ahd_free(ahd); - return (-ENODEV); - } - pci_set_master(pdev); - - if (sizeof(bus_addr_t) > 4) { - uint64_t memsize; - - memsize = ahd_linux_get_memsize(); - if (memsize >= 0x8000000000 - && ahd_pci_set_dma_mask(pdev, 0xFFFFFFFFFFFFFFFFULL) == 0) { - ahd->flags |= AHD_64BIT_ADDRESSING; - ahd->platform_data->hw_dma_mask = - (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0); - } else if (memsize > 0x80000000 - && ahd_pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) { - ahd->flags |= AHD_39BIT_ADDRESSING; - ahd->platform_data->hw_dma_mask = - (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0); - } - } else { - ahd_pci_set_dma_mask(pdev, 0xFFFFFFFF); - ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; - } -#endif - ahd->dev_softc = pci; - error = ahd_pci_config(ahd, entry); - if (error != 0) { - ahd_free(ahd); - return (-error); - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - pci_set_drvdata(pdev, ahd); - if (aic79xx_detect_complete) - ahd_linux_register_host(ahd, &aic79xx_driver_template); -#endif - return (0); -} - -int -ahd_linux_pci_probe(Scsi_Host_Template *template) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - return (pci_module_init(&aic79xx_pci_driver)); -#else - struct pci_dev *pdev; - u_int class; - int found; - - /* If we don't have a PCI bus, we can't find any adapters. */ - if (pci_present() == 0) - return (0); - - found = 0; - pdev = NULL; - class = PCI_CLASS_STORAGE_SCSI << 8; - while ((pdev = pci_find_class(class, pdev)) != NULL) { - ahd_dev_softc_t pci; - int error; - - pci = pdev; - error = ahd_linux_pci_dev_probe(pdev, /*pci_devid*/NULL); - if (error == 0) - found++; - } - return (found); -#endif -} - -static int -ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base, - u_long *base2) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - *base = pci_resource_start(ahd->dev_softc, 0); - /* - * This is really the 3rd bar and should be at index 2, - * but the Linux PCI code doesn't know how to "count" 64bit - * bars. - */ - *base2 = pci_resource_start(ahd->dev_softc, 3); -#else - *base = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR0, 4); - *base2 = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR1, 4); - *base &= PCI_BASE_ADDRESS_IO_MASK; - *base2 &= PCI_BASE_ADDRESS_IO_MASK; -#endif - if (*base == 0 || *base2 == 0) - return (ENOMEM); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) - if (check_region(*base, 256) != 0 - || check_region(*base2, 256) != 0) - return (ENOMEM); - request_region(*base, 256, "aic79xx"); - request_region(*base2, 256, "aic79xx"); -#else - if (request_region(*base, 256, "aic79xx") == 0) - return (ENOMEM); - if (request_region(*base2, 256, "aic79xx") == 0) { - release_region(*base2, 256); - return (ENOMEM); - } -#endif - return (0); -} - -static int -ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, - u_long *bus_addr, - uint8_t **maddr) -{ - u_long start; - u_long base_page; - u_long base_offset; - int error; - - if (aic79xx_allow_memio == 0) - return (ENOMEM); - - if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0) - return (ENOMEM); - - error = 0; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - start = pci_resource_start(ahd->dev_softc, 1); - base_page = start & PAGE_MASK; - base_offset = start - base_page; -#else - start = ahd_pci_read_config(ahd->dev_softc, PCIR_MAPS+4, 4); - base_offset = start & PCI_BASE_ADDRESS_MEM_MASK; - base_page = base_offset & PAGE_MASK; - base_offset -= base_page; -#endif - if (start != 0) { - *bus_addr = start; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - if (request_mem_region(start, 0x1000, "aic79xx") == 0) - error = ENOMEM; -#endif - if (error == 0) { - *maddr = ioremap_nocache(base_page, base_offset + 256); - if (*maddr == NULL) { - error = ENOMEM; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - release_mem_region(start, 0x1000); -#endif - } else - *maddr += base_offset; - } - } else - error = ENOMEM; - return (error); -} - -int -ahd_pci_map_registers(struct ahd_softc *ahd) -{ - uint32_t command; - u_long base; - uint8_t *maddr; - int error; - - /* - * If its allowed, we prefer memory mapped access. - */ - command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4); - command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); - base = 0; - maddr = NULL; -#ifdef MMAPIO - error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr); - if (error == 0) { - ahd->platform_data->mem_busaddr = base; - ahd->tags[0] = BUS_SPACE_MEMIO; - ahd->bshs[0].maddr = maddr; - ahd->tags[1] = BUS_SPACE_MEMIO; - ahd->bshs[1].maddr = maddr + 0x100; - ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, - command | PCIM_CMD_MEMEN, 4); - - if (ahd_pci_test_register_access(ahd) != 0) { - - printf("aic79xx: PCI Device %d:%d:%d " - "failed memory mapped test. Using PIO.\n", - ahd_get_pci_bus(ahd->dev_softc), - ahd_get_pci_slot(ahd->dev_softc), - ahd_get_pci_function(ahd->dev_softc)); - iounmap((void *)((u_long)maddr & PAGE_MASK)); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - release_mem_region(ahd->platform_data->mem_busaddr, - 0x1000); -#endif - ahd->bshs[0].maddr = NULL; - maddr = NULL; - } else - command |= PCIM_CMD_MEMEN; - } else if (bootverbose) { - printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx " - "unavailable. Cannot memory map device.\n", - ahd_get_pci_bus(ahd->dev_softc), - ahd_get_pci_slot(ahd->dev_softc), - ahd_get_pci_function(ahd->dev_softc), - base); - } -#endif - - if (maddr == NULL) { - u_long base2; - - error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2); - if (error == 0) { - ahd->tags[0] = BUS_SPACE_PIO; - ahd->tags[1] = BUS_SPACE_PIO; - ahd->bshs[0].ioport = base; - ahd->bshs[1].ioport = base2; - command |= PCIM_CMD_PORTEN; - } else { - printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx" - "unavailable. Cannot map device.\n", - ahd_get_pci_bus(ahd->dev_softc), - ahd_get_pci_slot(ahd->dev_softc), - ahd_get_pci_function(ahd->dev_softc), - base, base2); - } - } - ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4); - return (error); -} - -int -ahd_pci_map_int(struct ahd_softc *ahd) -{ - int error; - - error = request_irq(ahd->dev_softc->irq, ahd_linux_isr, - SA_SHIRQ, "aic79xx", ahd); - if (error == 0) - ahd->platform_data->irq = ahd->dev_softc->irq; - - return (-error); -} - -void -ahd_power_state_change(struct ahd_softc *ahd, ahd_power_state new_state) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - pci_set_power_state(ahd->dev_softc, new_state); -#else - uint32_t cap; - u_int cap_offset; - - /* - * Traverse the capability list looking for - * the power management capability. - */ - cap = 0; - cap_offset = ahd_pci_read_config(ahd->dev_softc, - PCIR_CAP_PTR, /*bytes*/1); - while (cap_offset != 0) { - - cap = ahd_pci_read_config(ahd->dev_softc, - cap_offset, /*bytes*/4); - if ((cap & 0xFF) == 1 - && ((cap >> 16) & 0x3) > 0) { - uint32_t pm_control; - - pm_control = ahd_pci_read_config(ahd->dev_softc, - cap_offset + 4, - /*bytes*/4); - pm_control &= ~0x3; - pm_control |= new_state; - ahd_pci_write_config(ahd->dev_softc, - cap_offset + 4, - pm_control, /*bytes*/2); - break; - } - cap_offset = (cap >> 8) & 0xFF; - } -#endif -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_pci.c linux-2.4.22/drivers/scsi/aic79xx/aic79xx_pci.c --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_pci.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,923 +0,0 @@ -/* - * Product specific probe and attach routines for: - * aic7901 and aic7902 SCSI controllers - * - * Copyright (c) 1994-2001 Justin T. Gibbs. - * Copyright (c) 2000-2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#61 $ - * - * $FreeBSD$ - */ - -#ifdef __linux__ -#include "aic79xx_osm.h" -#include "aic79xx_inline.h" -#else -#include -#include -#endif - -static __inline uint64_t -ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) -{ - uint64_t id; - - id = subvendor - | (subdevice << 16) - | ((uint64_t)vendor << 32) - | ((uint64_t)device << 48); - - return (id); -} - -#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull -#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull -#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull - -#define ID_AIC7901 0x800F9005FFFF9005ull -#define ID_AIC7901A 0x801E9005FFFF9005ull -#define ID_AIC7901A_IROC 0x809E9005FFFF9005ull -#define ID_AHA_29320A 0x8000900500609005ull -#define ID_AHA_29320LP 0x8014900500449005ull -#define ID_AHA_29320LP_IROC 0x8094900500449005ull - -#define ID_AIC7902 0x801F9005FFFF9005ull -#define ID_AIC7902_IROC 0x809F9005FFFF9005ull -#define ID_AIC7902_B 0x801D9005FFFF9005ull -#define ID_AIC7902_B_IROC 0x809D9005FFFF9005ull -#define ID_AHA_39320 0x8010900500409005ull -#define ID_AHA_39320D 0x8011900500419005ull -#define ID_AHA_39320D_B 0x801C900500419005ull -#define ID_AHA_39320D_HP 0x8011900500AC0E11ull -#define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull -#define ID_AHA_29320 0x8012900500429005ull -#define ID_AHA_29320B 0x8013900500439005ull -#define ID_AIC7902_PCI_REV_A4 0x3 -#define ID_AIC7902_PCI_REV_B0 0x10 -#define SUBID_HP 0x0E11 - -#define DEVID_9005_TYPE(id) ((id) & 0xF) -#define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */ -#define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */ -#define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */ -#define DEVID_9005_TYPE_MB 0xF /* On Motherboard */ - -#define DEVID_9005_MFUNC(id) ((id) & 0x10) - -#define DEVID_9005_PACKETIZED(id) ((id) & 0x8000) - -#define SUBID_9005_TYPE(id) ((id) & 0xF) -#define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */ -#define SUBID_9005_TYPE_MB 0xF /* On Motherboard */ - -#define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0) - -#define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20) - -#define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6) -#define SUBID_9005_SEEPTYPE_NONE 0x0 -#define SUBID_9005_SEEPTYPE_4K 0x1 - -static ahd_device_setup_t ahd_aic7901A_setup; -static ahd_device_setup_t ahd_aic7902_setup; - -struct ahd_pci_identity ahd_pci_ident_table [] = -{ - /* aic7901A based controllers */ - { - ID_AHA_29320LP, - ID_ALL_MASK, - "Adaptec 29320LP Ultra320 SCSI adapter", - ahd_aic7901A_setup - }, - { - ID_AHA_29320A, - ID_ALL_MASK, - "Adaptec 29320A Ultra320 SCSI adapter", - ahd_aic7901A_setup - }, - /* aic7902 based controllers */ - { - ID_AHA_39320, - ID_ALL_MASK, - "Adaptec 39320 Ultra320 SCSI adapter", - ahd_aic7902_setup - }, - { - ID_AHA_39320D, - ID_ALL_MASK, - "Adaptec 39320D Ultra320 SCSI adapter", - ahd_aic7902_setup - }, - { - ID_AHA_39320D_HP, - ID_ALL_MASK, - "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter", - ahd_aic7902_setup - }, - { - ID_AHA_39320D_B, - ID_ALL_MASK, - "Adaptec 39320D Ultra320 SCSI adapter", - ahd_aic7902_setup - }, - { - ID_AHA_39320D_B_HP, - ID_ALL_MASK, - "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter", - ahd_aic7902_setup - }, - { - ID_AHA_29320, - ID_ALL_MASK, - "Adaptec 29320 Ultra320 SCSI adapter", - ahd_aic7902_setup - }, - { - ID_AHA_29320B, - ID_ALL_MASK, - "Adaptec 29320B Ultra320 SCSI adapter", - ahd_aic7902_setup - }, - /* Generic chip probes for devices we don't know 'exactly' */ - { - ID_AIC7901A & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec AIC7901A Ultra320 SCSI adapter", - ahd_aic7901A_setup - }, - { - ID_AIC7902 & ID_9005_GENERIC_MASK, - ID_9005_GENERIC_MASK, - "Adaptec AIC7902 Ultra320 SCSI adapter", - ahd_aic7902_setup - } -}; - -const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table); - -#define DEVCONFIG 0x40 -#define PCIXINITPAT 0x0000E000ul -#define PCIXINIT_PCI33_66 0x0000E000ul -#define PCIXINIT_PCIX50_66 0x0000C000ul -#define PCIXINIT_PCIX66_100 0x0000A000ul -#define PCIXINIT_PCIX100_133 0x00008000ul -#define PCI_BUS_MODES_INDEX(devconfig) \ - (((devconfig) & PCIXINITPAT) >> 13) -static const char *pci_bus_modes[] = -{ - "PCI bus mode unknown", - "PCI bus mode unknown", - "PCI bus mode unknown", - "PCI bus mode unknown", - "PCI-X 101-133Mhz", - "PCI-X 67-100Mhz", - "PCI-X 50-66Mhz", - "PCI 33 or 66Mhz" -}; - -#define TESTMODE 0x00000800ul -#define IRDY_RST 0x00000200ul -#define FRAME_RST 0x00000100ul -#define PCI64BIT 0x00000080ul -#define MRDCEN 0x00000040ul -#define ENDIANSEL 0x00000020ul -#define MIXQWENDIANEN 0x00000008ul -#define DACEN 0x00000004ul -#define STPWLEVEL 0x00000002ul -#define QWENDIANSEL 0x00000001ul - -#define DEVCONFIG1 0x44 -#define PREQDIS 0x01 - -#define CSIZE_LATTIME 0x0c -#define CACHESIZE 0x000000fful -#define LATTIME 0x0000ff00ul - -static int ahd_check_extport(struct ahd_softc *ahd); -static void ahd_configure_termination(struct ahd_softc *ahd, - u_int adapter_control); -static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); - -struct ahd_pci_identity * -ahd_find_pci_device(ahd_dev_softc_t pci) -{ - uint64_t full_id; - uint16_t device; - uint16_t vendor; - uint16_t subdevice; - uint16_t subvendor; - struct ahd_pci_identity *entry; - u_int i; - - vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2); - device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2); - subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2); - subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2); - full_id = ahd_compose_id(device, - vendor, - subdevice, - subvendor); - - for (i = 0; i < ahd_num_pci_devs; i++) { - entry = &ahd_pci_ident_table[i]; - if (entry->full_id == (full_id & entry->id_mask)) { - /* Honor exclusion entries. */ - if (entry->name == NULL) - return (NULL); - return (entry); - } - } - return (NULL); -} - -int -ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) -{ - struct scb_data *shared_scb_data; - u_long l; - u_int command; - uint32_t devconfig; - uint16_t subvendor; - int error; - - shared_scb_data = NULL; - ahd->description = entry->name; - /* - * Record if this is an HP board. - */ - subvendor = ahd_pci_read_config(ahd->dev_softc, - PCIR_SUBVEND_0, /*bytes*/2); - if (subvendor == SUBID_HP) - ahd->flags |= AHD_HP_BOARD; - - error = entry->setup(ahd); - if (error != 0) - return (error); - - devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4); - if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) { - ahd->chip |= AHD_PCI; - /* Disable PCIX workarounds when running in PCI mode. */ - ahd->bugs &= ~AHD_PCIX_BUG_MASK; - } else { - ahd->chip |= AHD_PCIX; - } - ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)]; - - ahd_power_state_change(ahd, AHD_POWER_STATE_D0); - - error = ahd_pci_map_registers(ahd); - if (error != 0) - return (error); - - /* - * If we need to support high memory, enable dual - * address cycles. This bit must be set to enable - * high address bit generation even if we are on a - * 64bit bus (PCI64BIT set in devconfig). - */ - if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) { - uint32_t devconfig; - - if (bootverbose) - printf("%s: Enabling 39Bit Addressing\n", - ahd_name(ahd)); - devconfig = ahd_pci_read_config(ahd->dev_softc, - DEVCONFIG, /*bytes*/4); - devconfig |= DACEN; - ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, - devconfig, /*bytes*/4); - } - - /* Ensure busmastering is enabled */ - command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1); - command |= PCIM_CMD_BUSMASTEREN; - ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/1); - - error = ahd_softc_init(ahd); - if (error != 0) - return (error); - - ahd->bus_intr = ahd_pci_intr; - - error = ahd_reset(ahd); - if (error != 0) - return (ENXIO); - - ahd->pci_cachesize = - ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, - /*bytes*/1) & CACHESIZE; - ahd->pci_cachesize *= 4; - - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - /* See if we have a SEEPROM and perform auto-term */ - error = ahd_check_extport(ahd); - if (error != 0) - return (error); - - /* Core initialization */ - error = ahd_init(ahd); - if (error != 0) - return (error); - - /* - * Allow interrupts now that we are completely setup. - */ - error = ahd_pci_map_int(ahd); - if (error != 0) - return (error); - - ahd_list_lock(&l); - /* - * Link this softc in with all other ahd instances. - */ - ahd_softc_insert(ahd); - ahd_list_unlock(&l); - return (0); -} - -/* - * Perform some simple tests that should catch situations where - * our registers are invalidly mapped. - */ -int -ahd_pci_test_register_access(struct ahd_softc *ahd) -{ - ahd_mode_state saved_modes; - uint32_t cmd; - int error; - uint8_t hcntrl; - - saved_modes = ahd_save_modes(ahd); - error = EIO; - - /* - * Enable PCI error interrupt status, but suppress NMIs - * generated by SERR raised due to target aborts. - */ - cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2); - ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, - cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); - - /* - * First a simple test to see if any - * registers can be read. Reading - * HCNTRL has no side effects and has - * at least one bit that is guaranteed to - * be zero so it is a good register to - * use for this test. - */ - hcntrl = ahd_inb(ahd, HCNTRL); - if (hcntrl == 0xFF) - goto fail; - - /* - * Next create a situation where write combining - * or read prefetching could be initiated by the - * CPU or host bridge. Our device does not support - * either, so look for data corruption and/or flaged - * PCI errors. - */ - ahd_outb(ahd, HCNTRL, hcntrl|PAUSE); - while (ahd_is_paused(ahd) == 0) - ; - ahd_outb(ahd, SEQCTL0, PERRORDIS); - ahd_outl(ahd, SRAM_BASE, 0x5aa555aa); - if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa) - goto fail; - - if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { - u_int targpcistat; - - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - targpcistat = ahd_inb(ahd, TARGPCISTAT); - if ((targpcistat & STA) != 0) - goto fail; - } - - error = 0; - -fail: - if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { - u_int targpcistat; - u_int pci_status1; - - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - targpcistat = ahd_inb(ahd, TARGPCISTAT); - - /* Silently clear any latched errors. */ - ahd_outb(ahd, TARGPCISTAT, targpcistat); - pci_status1 = ahd_pci_read_config(ahd->dev_softc, - PCIR_STATUS + 1, /*bytes*/1); - ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, - pci_status1, /*bytes*/1); - ahd_outb(ahd, CLRINT, CLRPCIINT); - } - - ahd_restore_modes(ahd, saved_modes); - ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS); - ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); - return (error); -} - -/* - * Check the external port logic for a serial eeprom - * and termination/cable detection contrls. - */ -static int -ahd_check_extport(struct ahd_softc *ahd) -{ - struct seeprom_config *sc; - u_int adapter_control; - int have_seeprom; - int error; - - sc = ahd->seep_config; - have_seeprom = ahd_acquire_seeprom(ahd); - if (have_seeprom) { - u_int start_addr; - - if (bootverbose) - printf("%s: Reading SEEPROM...", ahd_name(ahd)); - - /* Address is always in units of 16bit words */ - start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A'); - - error = ahd_read_seeprom(ahd, (uint16_t *)sc, - start_addr, sizeof(*sc)/2); - - if (error != 0) { - printf("Unable to read SEEPROM\n"); - have_seeprom = 0; - } else { - have_seeprom = ahd_verify_cksum(sc); - - if (bootverbose) { - if (have_seeprom == 0) - printf ("checksum error\n"); - else - printf ("done.\n"); - } - } - ahd_release_seeprom(ahd); - } - - if (!have_seeprom) { - u_int nvram_scb; - - /* - * Pull scratch ram settings and treat them as - * if they are the contents of an seeprom if - * the 'ADPT', 'BIOS', or 'ASPI' signature is found - * in SCB 0xFF. We manually compose the data as 16bit - * values to avoid endian issues. - */ - ahd_set_scbptr(ahd, 0xFF); - nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET); - if (nvram_scb != 0xFF - && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' - && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D' - && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' - && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T') - || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B' - && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I' - && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O' - && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S') - || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' - && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S' - && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' - && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) { - uint16_t *sc_data; - int i; - - ahd_set_scbptr(ahd, nvram_scb); - sc_data = (uint16_t *)sc; - for (i = 0; i < 64; i += 2) - *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i); - have_seeprom = ahd_verify_cksum(sc); - if (have_seeprom) - ahd->flags |= AHD_SCB_CONFIG_USED; - } - } - -#if AHD_DEBUG - if (have_seeprom != 0 - && (ahd_debug & AHD_DUMP_SEEPROM) != 0) { - uint8_t *sc_data; - int i; - - printf("%s: Seeprom Contents:", ahd_name(ahd)); - sc_data = (uint8_t *)sc; - for (i = 0; i < (sizeof(*sc)); i += 2) - printf("\n\t0x%.4x", - sc_data[i] | (sc_data[i+1] << 8)); - printf("\n"); - } -#endif - - if (!have_seeprom) { - if (bootverbose) - printf("%s: No SEEPROM available.\n", ahd_name(ahd)); - ahd->flags |= AHD_USEDEFAULTS; - error = ahd_default_config(ahd); - adapter_control = CFAUTOTERM|CFSEAUTOTERM; - free(ahd->seep_config, M_DEVBUF); - ahd->seep_config = NULL; - } else { - error = ahd_parse_cfgdata(ahd, sc); - adapter_control = sc->adapter_control; - } - if (error != 0) - return (error); - - ahd_configure_termination(ahd, adapter_control); - - return (0); -} - -static void -ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control) -{ - int error; - u_int sxfrctl1; - uint8_t termctl; - uint32_t devconfig; - - devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4); - devconfig &= ~STPWLEVEL; - if ((ahd->flags & AHD_STPWLEVEL_A) != 0) - devconfig |= STPWLEVEL; - if (bootverbose) - printf("%s: STPWLEVEL is %s\n", - ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off"); - ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); - - /* Make sure current sensing is off. */ - if ((ahd->flags & AHD_CURRENT_SENSING) != 0) { - (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0); - } - - /* - * Read to sense. Write to set. - */ - error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl); - if ((adapter_control & CFAUTOTERM) == 0) { - if (bootverbose) - printf("%s: Manual Primary Termination\n", - ahd_name(ahd)); - termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH); - if ((adapter_control & CFSTERM) != 0) - termctl |= FLX_TERMCTL_ENPRILOW; - if ((adapter_control & CFWSTERM) != 0) - termctl |= FLX_TERMCTL_ENPRIHIGH; - } else if (error != 0) { - printf("%s: Primary Auto-Term Sensing failed! " - "Using Defaults.\n", ahd_name(ahd)); - termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH; - } - - if ((adapter_control & CFSEAUTOTERM) == 0) { - if (bootverbose) - printf("%s: Manual Secondary Termination\n", - ahd_name(ahd)); - termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH); - if ((adapter_control & CFSELOWTERM) != 0) - termctl |= FLX_TERMCTL_ENSECLOW; - if ((adapter_control & CFSEHIGHTERM) != 0) - termctl |= FLX_TERMCTL_ENSECHIGH; - } else if (error != 0) { - printf("%s: Secondary Auto-Term Sensing failed! " - "Using Defaults.\n", ahd_name(ahd)); - termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH; - } - - /* - * Now set the termination based on what we found. - */ - sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN; - if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) { - ahd->flags |= AHD_TERM_ENB_A; - sxfrctl1 |= STPWEN; - } - /* Must set the latch once in order to be effective. */ - ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN); - ahd_outb(ahd, SXFRCTL1, sxfrctl1); - - error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl); - if (error != 0) { - printf("%s: Unable to set termination settings!\n", - ahd_name(ahd)); - } else if (bootverbose) { - printf("%s: Primary High byte termination %sabled\n", - ahd_name(ahd), - (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis"); - - printf("%s: Primary Low byte termination %sabled\n", - ahd_name(ahd), - (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis"); - - printf("%s: Secondary High byte termination %sabled\n", - ahd_name(ahd), - (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis"); - - printf("%s: Secondary Low byte termination %sabled\n", - ahd_name(ahd), - (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis"); - } - return; -} - -#define DPE 0x80 -#define SSE 0x40 -#define RMA 0x20 -#define RTA 0x10 -#define STA 0x08 -#define DPR 0x01 - -static const char *split_status_source[] = -{ - "DFF0", - "DFF1", - "OVLY", - "CMC", -}; - -static const char *pci_status_source[] = -{ - "DFF0", - "DFF1", - "SG", - "CMC", - "OVLY", - "NONE", - "MSI", - "TARG" -}; - -static const char *split_status_strings[] = -{ - "%s: Received split response in %s.\n" - "%s: Received split completion error message in %s\n", - "%s: Receive overrun in %s\n", - "%s: Count not complete in %s\n", - "%s: Split completion data bucket in %s\n", - "%s: Split completion address error in %s\n", - "%s: Split completion byte count error in %s\n", - "%s: Signaled Target-abort to early terminate a split in %s\n", -}; - -static const char *pci_status_strings[] = -{ - "%s: Data Parity Error has been reported via PERR# in %s\n", - "%s: Target initial wait state error in %s\n", - "%s: Split completion read data parity error in %s\n", - "%s: Split completion address attribute parity error in %s\n", - "%s: Received a Target Abort in %s\n", - "%s: Received a Master Abort in %s\n", - "%s: Signal System Error Detected in %s\n", - "%s: Address or Write Phase Parity Error Detected in %s.\n" -}; - -void -ahd_pci_intr(struct ahd_softc *ahd) -{ - uint8_t pci_status[8]; - ahd_mode_state saved_modes; - u_int pci_status1; - u_int intstat; - u_int i; - u_int reg; - - intstat = ahd_inb(ahd, INTSTAT); - - if ((intstat & SPLTINT) != 0) - ahd_pci_split_intr(ahd, intstat); - - if ((intstat & PCIINT) == 0) - return; - - printf("%s: PCI error Interrupt\n", ahd_name(ahd)); - saved_modes = ahd_save_modes(ahd); - ahd_dump_card_state(ahd); - ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); - for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) { - - if (i == 5) - continue; - pci_status[i] = ahd_inb(ahd, reg); - /* Clear latched errors. So our interupt deasserts. */ - ahd_outb(ahd, reg, pci_status[i]); - } - - for (i = 0; i < 8; i++) { - u_int bit; - - if (i == 5) - continue; - - for (bit = 0; bit < 8; bit++) { - - if ((pci_status[i] & (0x1 << bit)) != 0) { - static const char *s; - - s = pci_status_strings[bit]; - if (i == 7/*TARG*/ && bit == 3) - s = "%s: Signaled Target Abort\n"; - printf(s, ahd_name(ahd), pci_status_source[i]); - } - } - } - pci_status1 = ahd_pci_read_config(ahd->dev_softc, - PCIR_STATUS + 1, /*bytes*/1); - ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, - pci_status1, /*bytes*/1); - ahd_restore_modes(ahd, saved_modes); - ahd_outb(ahd, CLRINT, CLRPCIINT); - ahd_unpause(ahd); -} - -static void -ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) -{ - uint8_t split_status[4]; - uint8_t split_status1[4]; - uint8_t sg_split_status[2]; - uint8_t sg_split_status1[2]; - ahd_mode_state saved_modes; - u_int i; - uint16_t pcix_status; - - /* - * Check for splits in all modes. Modes 0 and 1 - * additionally have SG engine splits to look at. - */ - pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS, - /*bytes*/2); - printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n", - ahd_name(ahd), pcix_status); - saved_modes = ahd_save_modes(ahd); - for (i = 0; i < 4; i++) { - ahd_set_modes(ahd, i, i); - - split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0); - split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1); - /* Clear latched errors. So our interupt deasserts. */ - ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]); - ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]); - if (i != 0) - continue; - sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0); - sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1); - /* Clear latched errors. So our interupt deasserts. */ - ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]); - ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]); - } - - for (i = 0; i < 4; i++) { - u_int bit; - - for (bit = 0; bit < 8; bit++) { - - if ((split_status[i] & (0x1 << bit)) != 0) { - static const char *s; - - s = split_status_strings[bit]; - printf(s, ahd_name(ahd), - split_status_source[i]); - } - - if (i != 0) - continue; - - if ((sg_split_status[i] & (0x1 << bit)) != 0) { - static const char *s; - - s = split_status_strings[bit]; - printf(s, ahd_name(ahd), "SG"); - } - } - } - /* - * Clear PCI-X status bits. - */ - ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS, - pcix_status, /*bytes*/2); - ahd_outb(ahd, CLRINT, CLRSPLTINT); - ahd_restore_modes(ahd, saved_modes); -} - -static int -ahd_aic7901A_setup(struct ahd_softc *ahd) -{ - int error; - - error = ahd_aic7902_setup(ahd); - if (error != 0) - return (error); - ahd->chip = AHD_AIC7901A; - return (0); -} - -static int -ahd_aic7902_setup(struct ahd_softc *ahd) -{ - ahd_dev_softc_t pci; - u_int rev; - - pci = ahd->dev_softc; - rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1); - if (rev < ID_AIC7902_PCI_REV_A4) { - printf("%s: Unable to attach to unsupported chip revision %d\n", - ahd_name(ahd), rev); - ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/1); - return (ENXIO); - } - ahd->channel = ahd_get_pci_function(pci) + 'A'; - ahd->chip = AHD_AIC7902; - ahd->features = AHD_AIC7902_FE; - if (rev < ID_AIC7902_PCI_REV_B0) { - /* - * Enable A series workarounds. - */ - ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG - | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG - | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG - | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG - | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG - | AHD_PCIX_CHIPRST_BUG|AHD_PKTIZED_STATUS_BUG - | AHD_PKT_LUN_BUG|AHD_MDFF_WSCBPTR_BUG - | AHD_REG_SLOW_SETTLE_BUG|AHD_SET_MODE_BUG - | AHD_BUSFREEREV_BUG|AHD_NONPACKFIFO_BUG - | AHD_PACED_NEGTABLE_BUG; - - /* - * IO Cell paramter setup. - */ - AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); - - if ((ahd->flags & AHD_HP_BOARD) == 0) - AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA); - } else { - u_int devconfig1; - - ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS - | AHD_NEW_DFCNTRL_OPTS; - ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG - | AHD_INTCOLLISION_BUG; - - /* - * IO Cell paramter setup. - */ - AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); - AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB); - AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF); - - /* - * Set the PREQDIS bit for H2B which disables some workaround - * that doesn't work on regular PCI busses. - * XXX - Find out exactly what this does from the hardware - * folks! - */ - devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1); - ahd_pci_write_config(pci, DEVCONFIG1, - devconfig1|PREQDIS, /*bytes*/1); - devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1); - } - - return (0); -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_proc.c linux-2.4.22/drivers/scsi/aic79xx/aic79xx_proc.c --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_proc.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_proc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2000-2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * String handling code courtesy of Gerard Roudier's - * sym driver. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#11 $ - */ -#include "aic79xx_osm.h" -#include "aic79xx_inline.h" - -static void copy_mem_info(struct info_str *info, char *data, int len); -static int copy_info(struct info_str *info, char *fmt, ...); -static void ahd_dump_target_state(struct ahd_softc *ahd, - struct info_str *info, - u_int our_id, char channel, - u_int target_id, u_int target_offset); -static void ahd_dump_device_state(struct info_str *info, - struct ahd_linux_device *dev); -static int ahd_proc_write_seeprom(struct ahd_softc *ahd, - char *buffer, int length); - -static void -copy_mem_info(struct info_str *info, char *data, int len) -{ - if (info->pos + len > info->offset + info->length) - len = info->offset + info->length - info->pos; - - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - - if (info->pos < info->offset) { - off_t partial; - - partial = info->offset - info->pos; - data += partial; - info->pos += partial; - len -= partial; - } - - if (len > 0) { - memcpy(info->buffer, data, len); - info->pos += len; - info->buffer += len; - } -} - -static int -copy_info(struct info_str *info, char *fmt, ...) -{ - va_list args; - char buf[256]; - int len; - - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); - - copy_mem_info(info, buf, len); - return (len); -} - -void -ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) -{ - u_int speed; - u_int freq; - u_int mb; - - if (tinfo->period == AHD_PERIOD_UNKNOWN) { - copy_info(info, "Renegotiation Pending\n"); - return; - } - speed = 3300; - freq = 0; - if (tinfo->offset != 0) { - freq = aic_calc_syncsrate(tinfo->period); - speed = freq; - } - speed *= (0x01 << tinfo->width); - mb = speed / 1000; - if (mb > 0) - copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000); - else - copy_info(info, "%dKB/s transfers", speed); - - if (freq != 0) { - int printed_options; - - printed_options = 0; - copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000); - if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { - copy_info(info, " DT"); - printed_options++; - } - if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - copy_info(info, "%s", printed_options ? "|IU" : " IU"); - printed_options++; - } - if ((tinfo->ppr_options & MSG_EXT_PPR_RTI) != 0) { - copy_info(info, "%s", - printed_options ? "|RTI" : " RTI"); - printed_options++; - } - if ((tinfo->ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) { - copy_info(info, "%s", - printed_options ? "|QAS" : " QAS"); - printed_options++; - } - } - - if (tinfo->width > 0) { - if (freq != 0) { - copy_info(info, ", "); - } else { - copy_info(info, " ("); - } - copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width)); - } else if (freq != 0) { - copy_info(info, ")"); - } - copy_info(info, "\n"); -} - -static void -ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, - u_int our_id, char channel, u_int target_id, - u_int target_offset) -{ - struct ahd_linux_target *targ; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - int lun; - - tinfo = ahd_fetch_transinfo(ahd, channel, our_id, - target_id, &tstate); - copy_info(info, "Channel %c Target %d Negotiation Settings\n", - channel, target_id); - copy_info(info, "\tUser: "); - ahd_format_transinfo(info, &tinfo->user); - targ = ahd->platform_data->targets[target_offset]; - if (targ == NULL) - return; - - copy_info(info, "\tGoal: "); - ahd_format_transinfo(info, &tinfo->goal); - copy_info(info, "\tCurr: "); - ahd_format_transinfo(info, &tinfo->curr); - copy_info(info, "\tTransmission Errors %ld\n", targ->errors_detected); - - for (lun = 0; lun < AHD_NUM_LUNS; lun++) { - struct ahd_linux_device *dev; - - dev = targ->devices[lun]; - - if (dev == NULL) - continue; - - ahd_dump_device_state(info, dev); - } -} - -static void -ahd_dump_device_state(struct info_str *info, struct ahd_linux_device *dev) -{ - copy_info(info, "\tChannel %c Target %d Lun %d Settings\n", - dev->target->channel + 'A', dev->target->target, dev->lun); - - copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued); - copy_info(info, "\t\tCommands Active %d\n", dev->active); - copy_info(info, "\t\tCommand Openings %d\n", dev->openings); - copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags); - copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen); -} - -static int -ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length) -{ - ahd_mode_state saved_modes; - int have_seeprom; - u_long s; - int paused; - int written; - - /* Default to failure. */ - written = -EINVAL; - ahd_lock(ahd, &s); - paused = ahd_is_paused(ahd); - if (!paused) - ahd_pause(ahd); - - saved_modes = ahd_save_modes(ahd); - ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); - if (length != sizeof(struct seeprom_config)) { - printf("ahd_proc_write_seeprom: incorrect buffer size\n"); - goto done; - } - - have_seeprom = ahd_verify_cksum((struct seeprom_config*)buffer); - if (have_seeprom == 0) { - printf("ahd_proc_write_seeprom: cksum verification failed\n"); - goto done; - } - - have_seeprom = ahd_acquire_seeprom(ahd); - if (!have_seeprom) { - printf("ahd_proc_write_seeprom: No Serial EEPROM\n"); - goto done; - } else { - u_int start_addr; - - if (ahd->seep_config == NULL) { - ahd->seep_config = malloc(sizeof(*ahd->seep_config), - M_DEVBUF, M_NOWAIT); - if (ahd->seep_config == NULL) { - printf("aic79xx: Unable to allocate serial " - "eeprom buffer. Write failing\n"); - goto done; - } - } - printf("aic79xx: Writing Serial EEPROM\n"); - start_addr = 32 * (ahd->channel - 'A'); - ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr, - sizeof(struct seeprom_config)/2); - ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config, - start_addr, sizeof(struct seeprom_config)/2); - ahd_release_seeprom(ahd); - written = length; - } - -done: - ahd_restore_modes(ahd, saved_modes); - if (!paused) - ahd_unpause(ahd); - ahd_unlock(ahd, &s); - return (written); -} -/* - * Return information to handle /proc support for the driver. - */ -int -ahd_linux_proc_info(char *buffer, char **start, off_t offset, - int length, int hostno, int inout) -{ - struct ahd_softc *ahd; - struct info_str info; - char ahd_info[256]; - u_long l; - u_int max_targ; - u_int i; - int retval; - - retval = -EINVAL; - ahd_list_lock(&l); - TAILQ_FOREACH(ahd, &ahd_tailq, links) { - if (ahd->platform_data->host->host_no == hostno) - break; - } - - if (ahd == NULL) - goto done; - - /* Has data been written to the file? */ - if (inout == TRUE) { - retval = ahd_proc_write_seeprom(ahd, buffer, length); - goto done; - } - - if (start) - *start = buffer; - - info.buffer = buffer; - info.length = length; - info.offset = offset; - info.pos = 0; - - copy_info(&info, "Adaptec AIC79xx driver version: %s\n", - AIC79XX_DRIVER_VERSION); - ahd_controller_info(ahd, ahd_info); - copy_info(&info, "%s\n\n", ahd_info); - - if (ahd->seep_config == NULL) - copy_info(&info, "No Serial EEPROM\n"); - else { - copy_info(&info, "Serial EEPROM:\n"); - for (i = 0; i < sizeof(*ahd->seep_config)/2; i++) { - if (((i % 8) == 0) && (i != 0)) { - copy_info(&info, "\n"); - } - copy_info(&info, "0x%.4x ", - ((uint16_t*)ahd->seep_config)[i]); - } - copy_info(&info, "\n"); - } - copy_info(&info, "\n"); - - max_targ = 15; - if ((ahd->features & AHD_WIDE) == 0) - max_targ = 7; - - for (i = 0; i <= max_targ; i++) { - - ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', - /*target_id*/i, /*target_offset*/i); - } - retval = info.pos > info.offset ? info.pos - info.offset : 0; -done: - ahd_list_unlock(&l); - return (retval); -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_reg.h linux-2.4.22/drivers/scsi/aic79xx/aic79xx_reg.h --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_reg.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_reg.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,3778 +0,0 @@ -/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ - */ -typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); -typedef struct ahd_reg_parse_entry { - char *name; - uint8_t value; - uint8_t mask; -} ahd_reg_parse_entry_t; - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_mode_ptr_print; -#else -#define ahd_mode_ptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MODE_PTR", 0x00, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_intstat_print; -#else -#define ahd_intstat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INTSTAT", 0x01, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqintcode_print; -#else -#define ahd_seqintcode_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQINTCODE", 0x02, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrint_print; -#else -#define ahd_clrint_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRINT", 0x03, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_error_print; -#else -#define ahd_error_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ERROR", 0x04, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrerr_print; -#else -#define ahd_clrerr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRERR", 0x04, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hcntrl_print; -#else -#define ahd_hcntrl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HCNTRL", 0x05, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hnscb_qoff_print; -#else -#define ahd_hnscb_qoff_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HNSCB_QOFF", 0x06, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hescb_qoff_print; -#else -#define ahd_hescb_qoff_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HESCB_QOFF", 0x08, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hs_mailbox_print; -#else -#define ahd_hs_mailbox_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HS_MAILBOX", 0x0b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrseqintstat_print; -#else -#define ahd_clrseqintstat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRSEQINTSTAT", 0x0c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqintstat_print; -#else -#define ahd_seqintstat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQINTSTAT", 0x0c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_swtimer_print; -#else -#define ahd_swtimer_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SWTIMER", 0x0e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_snscb_qoff_print; -#else -#define ahd_snscb_qoff_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SNSCB_QOFF", 0x10, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sescb_qoff_print; -#else -#define ahd_sescb_qoff_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SESCB_QOFF", 0x12, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sdscb_qoff_print; -#else -#define ahd_sdscb_qoff_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SDSCB_QOFF", 0x14, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_qoff_ctlsta_print; -#else -#define ahd_qoff_ctlsta_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "QOFF_CTLSTA", 0x16, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_intctl_print; -#else -#define ahd_intctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INTCTL", 0x18, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfcntrl_print; -#else -#define ahd_dfcntrl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFCNTRL", 0x19, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dscommand0_print; -#else -#define ahd_dscommand0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DSCOMMAND0", 0x19, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfstatus_print; -#else -#define ahd_dfstatus_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFSTATUS", 0x1a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sg_cache_shadow_print; -#else -#define ahd_sg_cache_shadow_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SG_CACHE_SHADOW", 0x1b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_arbctl_print; -#else -#define ahd_arbctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ARBCTL", 0x1b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sg_cache_pre_print; -#else -#define ahd_sg_cache_pre_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SG_CACHE_PRE", 0x1b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqin_print; -#else -#define ahd_lqin_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQIN", 0x20, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_typeptr_print; -#else -#define ahd_typeptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "TYPEPTR", 0x20, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_tagptr_print; -#else -#define ahd_tagptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "TAGPTR", 0x21, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lunptr_print; -#else -#define ahd_lunptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LUNPTR", 0x22, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_datalenptr_print; -#else -#define ahd_datalenptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DATALENPTR", 0x23, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_statlenptr_print; -#else -#define ahd_statlenptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "STATLENPTR", 0x24, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmdlenptr_print; -#else -#define ahd_cmdlenptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMDLENPTR", 0x25, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_attrptr_print; -#else -#define ahd_attrptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ATTRPTR", 0x26, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_flagptr_print; -#else -#define ahd_flagptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FLAGPTR", 0x27, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmdptr_print; -#else -#define ahd_cmdptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMDPTR", 0x28, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_qnextptr_print; -#else -#define ahd_qnextptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "QNEXTPTR", 0x29, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_idptr_print; -#else -#define ahd_idptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "IDPTR", 0x2a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_abrtbyteptr_print; -#else -#define ahd_abrtbyteptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ABRTBYTEPTR", 0x2b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_abrtbitptr_print; -#else -#define ahd_abrtbitptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ABRTBITPTR", 0x2c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_maxcmdbytes_print; -#else -#define ahd_maxcmdbytes_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MAXCMDBYTES", 0x2d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_maxcmd2rcv_print; -#else -#define ahd_maxcmd2rcv_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MAXCMD2RCV", 0x2e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_shortthresh_print; -#else -#define ahd_shortthresh_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SHORTTHRESH", 0x2f, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lunlen_print; -#else -#define ahd_lunlen_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LUNLEN", 0x30, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cdblimit_print; -#else -#define ahd_cdblimit_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CDBLIMIT", 0x31, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_maxcmd_print; -#else -#define ahd_maxcmd_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MAXCMD", 0x32, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_maxcmdcnt_print; -#else -#define ahd_maxcmdcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MAXCMDCNT", 0x33, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqrsvd01_print; -#else -#define ahd_lqrsvd01_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQRSVD01", 0x34, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqrsvd16_print; -#else -#define ahd_lqrsvd16_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQRSVD16", 0x35, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqrsvd17_print; -#else -#define ahd_lqrsvd17_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQRSVD17", 0x36, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmdrsvd0_print; -#else -#define ahd_cmdrsvd0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMDRSVD0", 0x37, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqctl0_print; -#else -#define ahd_lqctl0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQCTL0", 0x38, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqctl1_print; -#else -#define ahd_lqctl1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQCTL1", 0x38, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsbist0_print; -#else -#define ahd_scsbist0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSBIST0", 0x39, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqctl2_print; -#else -#define ahd_lqctl2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQCTL2", 0x39, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsbist1_print; -#else -#define ahd_scsbist1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSBIST1", 0x3a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsiseq0_print; -#else -#define ahd_scsiseq0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSISEQ0", 0x3a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsiseq1_print; -#else -#define ahd_scsiseq1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSISEQ1", 0x3b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sxfrctl0_print; -#else -#define ahd_sxfrctl0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SXFRCTL0", 0x3c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_businitid_print; -#else -#define ahd_businitid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "BUSINITID", 0x3c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dlcount_print; -#else -#define ahd_dlcount_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DLCOUNT", 0x3c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sxfrctl1_print; -#else -#define ahd_sxfrctl1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SXFRCTL1", 0x3d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_bustargid_print; -#else -#define ahd_bustargid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "BUSTARGID", 0x3e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sxfrctl2_print; -#else -#define ahd_sxfrctl2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SXFRCTL2", 0x3e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dffstat_print; -#else -#define ahd_dffstat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFFSTAT", 0x3f, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsisigo_print; -#else -#define ahd_scsisigo_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSISIGO", 0x40, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_multargid_print; -#else -#define ahd_multargid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MULTARGID", 0x40, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsisigi_print; -#else -#define ahd_scsisigi_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSISIGI", 0x41, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsiphase_print; -#else -#define ahd_scsiphase_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSIPHASE", 0x42, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsidat0_img_print; -#else -#define ahd_scsidat0_img_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSIDAT0_IMG", 0x43, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsidat_print; -#else -#define ahd_scsidat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSIDAT", 0x44, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsibus_print; -#else -#define ahd_scsibus_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSIBUS", 0x46, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_targidin_print; -#else -#define ahd_targidin_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "TARGIDIN", 0x48, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_selid_print; -#else -#define ahd_selid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SELID", 0x49, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sblkctl_print; -#else -#define ahd_sblkctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SBLKCTL", 0x4a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_optionmode_print; -#else -#define ahd_optionmode_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OPTIONMODE", 0x4a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sstat0_print; -#else -#define ahd_sstat0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SSTAT0", 0x4b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrsint0_print; -#else -#define ahd_clrsint0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRSINT0", 0x4b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_simode0_print; -#else -#define ahd_simode0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SIMODE0", 0x4b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrsint1_print; -#else -#define ahd_clrsint1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRSINT1", 0x4c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sstat1_print; -#else -#define ahd_sstat1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SSTAT1", 0x4c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sstat2_print; -#else -#define ahd_sstat2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SSTAT2", 0x4d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrsint2_print; -#else -#define ahd_clrsint2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRSINT2", 0x4d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_simode2_print; -#else -#define ahd_simode2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SIMODE2", 0x4d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_perrdiag_print; -#else -#define ahd_perrdiag_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PERRDIAG", 0x4e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqistate_print; -#else -#define ahd_lqistate_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQISTATE", 0x4e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_soffcnt_print; -#else -#define ahd_soffcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SOFFCNT", 0x4f, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqostate_print; -#else -#define ahd_lqostate_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQOSTATE", 0x4f, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqistat0_print; -#else -#define ahd_lqistat0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQISTAT0", 0x50, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrlqiint0_print; -#else -#define ahd_clrlqiint0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRLQIINT0", 0x50, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqimode0_print; -#else -#define ahd_lqimode0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQIMODE0", 0x50, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqimode1_print; -#else -#define ahd_lqimode1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQIMODE1", 0x51, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqistat1_print; -#else -#define ahd_lqistat1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQISTAT1", 0x51, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrlqiint1_print; -#else -#define ahd_clrlqiint1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRLQIINT1", 0x51, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqistat2_print; -#else -#define ahd_lqistat2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQISTAT2", 0x52, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sstat3_print; -#else -#define ahd_sstat3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SSTAT3", 0x53, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_simode3_print; -#else -#define ahd_simode3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SIMODE3", 0x53, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrsint3_print; -#else -#define ahd_clrsint3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRSINT3", 0x53, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqomode0_print; -#else -#define ahd_lqomode0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQOMODE0", 0x54, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqostat0_print; -#else -#define ahd_lqostat0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQOSTAT0", 0x54, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrlqoint0_print; -#else -#define ahd_clrlqoint0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRLQOINT0", 0x54, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqostat1_print; -#else -#define ahd_lqostat1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQOSTAT1", 0x55, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrlqoint1_print; -#else -#define ahd_clrlqoint1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRLQOINT1", 0x55, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqomode1_print; -#else -#define ahd_lqomode1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQOMODE1", 0x55, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqostat2_print; -#else -#define ahd_lqostat2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQOSTAT2", 0x56, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_os_space_cnt_print; -#else -#define ahd_os_space_cnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OS_SPACE_CNT", 0x56, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_simode1_print; -#else -#define ahd_simode1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SIMODE1", 0x57, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_gsfifo_print; -#else -#define ahd_gsfifo_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "GSFIFO", 0x58, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dffsxfrctl_print; -#else -#define ahd_dffsxfrctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFFSXFRCTL", 0x5a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lqoscsctl_print; -#else -#define ahd_lqoscsctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LQOSCSCTL", 0x5a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_nextscb_print; -#else -#define ahd_nextscb_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NEXTSCB", 0x5a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_clrseqintsrc_print; -#else -#define ahd_clrseqintsrc_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CLRSEQINTSRC", 0x5b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqintsrc_print; -#else -#define ahd_seqintsrc_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQINTSRC", 0x5b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_currscb_print; -#else -#define ahd_currscb_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CURRSCB", 0x5c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqimode_print; -#else -#define ahd_seqimode_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQIMODE", 0x5c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_mdffstat_print; -#else -#define ahd_mdffstat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MDFFSTAT", 0x5d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_crccontrol_print; -#else -#define ahd_crccontrol_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CRCCONTROL", 0x5d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfftag_print; -#else -#define ahd_dfftag_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFFTAG", 0x5e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lastscb_print; -#else -#define ahd_lastscb_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LASTSCB", 0x5e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsitest_print; -#else -#define ahd_scsitest_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSITEST", 0x5e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_iopdnctl_print; -#else -#define ahd_iopdnctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "IOPDNCTL", 0x5f, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_shaddr_print; -#else -#define ahd_shaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SHADDR", 0x60, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_negoaddr_print; -#else -#define ahd_negoaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NEGOADDR", 0x60, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dgrpcrci_print; -#else -#define ahd_dgrpcrci_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DGRPCRCI", 0x60, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_negperiod_print; -#else -#define ahd_negperiod_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NEGPERIOD", 0x61, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_packcrci_print; -#else -#define ahd_packcrci_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PACKCRCI", 0x62, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_negoffset_print; -#else -#define ahd_negoffset_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NEGOFFSET", 0x62, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_negppropts_print; -#else -#define ahd_negppropts_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NEGPPROPTS", 0x63, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_negconopts_print; -#else -#define ahd_negconopts_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NEGCONOPTS", 0x64, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_annexcol_print; -#else -#define ahd_annexcol_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ANNEXCOL", 0x65, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scschkn_print; -#else -#define ahd_scschkn_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSCHKN", 0x66, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_annexdat_print; -#else -#define ahd_annexdat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ANNEXDAT", 0x66, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_iownid_print; -#else -#define ahd_iownid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "IOWNID", 0x67, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_pll960ctl0_print; -#else -#define ahd_pll960ctl0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PLL960CTL0", 0x68, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_shcnt_print; -#else -#define ahd_shcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SHCNT", 0x68, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_townid_print; -#else -#define ahd_townid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "TOWNID", 0x69, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_pll960ctl1_print; -#else -#define ahd_pll960ctl1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PLL960CTL1", 0x69, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_pll960cnt0_print; -#else -#define ahd_pll960cnt0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PLL960CNT0", 0x6a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_xsig_print; -#else -#define ahd_xsig_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "XSIG", 0x6a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seloid_print; -#else -#define ahd_seloid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SELOID", 0x6b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_pll400ctl0_print; -#else -#define ahd_pll400ctl0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PLL400CTL0", 0x6c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_fairness_print; -#else -#define ahd_fairness_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FAIRNESS", 0x6c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_pll400ctl1_print; -#else -#define ahd_pll400ctl1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PLL400CTL1", 0x6d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_pll400cnt0_print; -#else -#define ahd_pll400cnt0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PLL400CNT0", 0x6e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_unfairness_print; -#else -#define ahd_unfairness_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "UNFAIRNESS", 0x6e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_haddr_print; -#else -#define ahd_haddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HADDR", 0x70, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_plldelay_print; -#else -#define ahd_plldelay_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PLLDELAY", 0x70, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hodmaadr_print; -#else -#define ahd_hodmaadr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HODMAADR", 0x70, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hodmacnt_print; -#else -#define ahd_hodmacnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HODMACNT", 0x78, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hcnt_print; -#else -#define ahd_hcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HCNT", 0x78, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_hodmaen_print; -#else -#define ahd_hodmaen_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "HODMAEN", 0x7a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sghaddr_print; -#else -#define ahd_sghaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGHADDR", 0x7c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scbhaddr_print; -#else -#define ahd_scbhaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCBHADDR", 0x7c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sghcnt_print; -#else -#define ahd_sghcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGHCNT", 0x84, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scbhcnt_print; -#else -#define ahd_scbhcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCBHCNT", 0x84, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dff_thrsh_print; -#else -#define ahd_dff_thrsh_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFF_THRSH", 0x88, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_romaddr_print; -#else -#define ahd_romaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ROMADDR", 0x8a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_romcntrl_print; -#else -#define ahd_romcntrl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ROMCNTRL", 0x8d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_romdata_print; -#else -#define ahd_romdata_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ROMDATA", 0x8e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcrxmsg0_print; -#else -#define ahd_cmcrxmsg0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCRXMSG0", 0x90, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_roenable_print; -#else -#define ahd_roenable_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ROENABLE", 0x90, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyrxmsg0_print; -#else -#define ahd_ovlyrxmsg0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYRXMSG0", 0x90, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dchrxmsg0_print; -#else -#define ahd_dchrxmsg0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DCHRXMSG0", 0x90, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyrxmsg1_print; -#else -#define ahd_ovlyrxmsg1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYRXMSG1", 0x91, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_nsenable_print; -#else -#define ahd_nsenable_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NSENABLE", 0x91, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dchrxmsg1_print; -#else -#define ahd_dchrxmsg1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DCHRXMSG1", 0x91, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcrxmsg1_print; -#else -#define ahd_cmcrxmsg1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCRXMSG1", 0x91, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dchrxmsg2_print; -#else -#define ahd_dchrxmsg2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DCHRXMSG2", 0x92, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyrxmsg2_print; -#else -#define ahd_ovlyrxmsg2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYRXMSG2", 0x92, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcrxmsg2_print; -#else -#define ahd_cmcrxmsg2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCRXMSG2", 0x92, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ost_print; -#else -#define ahd_ost_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OST", 0x92, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dchrxmsg3_print; -#else -#define ahd_dchrxmsg3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DCHRXMSG3", 0x93, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcrxmsg3_print; -#else -#define ahd_cmcrxmsg3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCRXMSG3", 0x93, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_pcixctl_print; -#else -#define ahd_pcixctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PCIXCTL", 0x93, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyrxmsg3_print; -#else -#define ahd_ovlyrxmsg3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYRXMSG3", 0x93, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyseqbcnt_print; -#else -#define ahd_ovlyseqbcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYSEQBCNT", 0x94, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcseqbcnt_print; -#else -#define ahd_cmcseqbcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCSEQBCNT", 0x94, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dchseqbcnt_print; -#else -#define ahd_dchseqbcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DCHSEQBCNT", 0x94, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcspltstat0_print; -#else -#define ahd_cmcspltstat0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCSPLTSTAT0", 0x96, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyspltstat0_print; -#else -#define ahd_ovlyspltstat0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYSPLTSTAT0", 0x96, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dchspltstat0_print; -#else -#define ahd_dchspltstat0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DCHSPLTSTAT0", 0x96, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dchspltstat1_print; -#else -#define ahd_dchspltstat1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DCHSPLTSTAT1", 0x97, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcspltstat1_print; -#else -#define ahd_cmcspltstat1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCSPLTSTAT1", 0x97, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyspltstat1_print; -#else -#define ahd_ovlyspltstat1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYSPLTSTAT1", 0x97, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgrxmsg0_print; -#else -#define ahd_sgrxmsg0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGRXMSG0", 0x98, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_slvspltoutadr0_print; -#else -#define ahd_slvspltoutadr0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SLVSPLTOUTADR0", 0x98, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgrxmsg1_print; -#else -#define ahd_sgrxmsg1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGRXMSG1", 0x99, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_slvspltoutadr1_print; -#else -#define ahd_slvspltoutadr1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SLVSPLTOUTADR1", 0x99, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgrxmsg2_print; -#else -#define ahd_sgrxmsg2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGRXMSG2", 0x9a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_slvspltoutadr2_print; -#else -#define ahd_slvspltoutadr2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SLVSPLTOUTADR2", 0x9a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgrxmsg3_print; -#else -#define ahd_sgrxmsg3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGRXMSG3", 0x9b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_slvspltoutadr3_print; -#else -#define ahd_slvspltoutadr3_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SLVSPLTOUTADR3", 0x9b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgseqbcnt_print; -#else -#define ahd_sgseqbcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGSEQBCNT", 0x9c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_slvspltoutattr0_print; -#else -#define ahd_slvspltoutattr0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SLVSPLTOUTATTR0", 0x9c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_slvspltoutattr1_print; -#else -#define ahd_slvspltoutattr1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SLVSPLTOUTATTR1", 0x9d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_slvspltoutattr2_print; -#else -#define ahd_slvspltoutattr2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SLVSPLTOUTATTR2", 0x9e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgspltstat0_print; -#else -#define ahd_sgspltstat0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGSPLTSTAT0", 0x9e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sfunct_print; -#else -#define ahd_sfunct_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgspltstat1_print; -#else -#define ahd_sgspltstat1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGSPLTSTAT1", 0x9f, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_df0pcistat_print; -#else -#define ahd_df0pcistat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DF0PCISTAT", 0xa0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_reg0_print; -#else -#define ahd_reg0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "REG0", 0xa0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_df1pcistat_print; -#else -#define ahd_df1pcistat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DF1PCISTAT", 0xa1, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sgpcistat_print; -#else -#define ahd_sgpcistat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SGPCISTAT", 0xa2, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_reg1_print; -#else -#define ahd_reg1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "REG1", 0xa2, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmcpcistat_print; -#else -#define ahd_cmcpcistat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMCPCISTAT", 0xa3, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlypcistat_print; -#else -#define ahd_ovlypcistat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYPCISTAT", 0xa4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_reg_isr_print; -#else -#define ahd_reg_isr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "REG_ISR", 0xa4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sg_state_print; -#else -#define ahd_sg_state_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SG_STATE", 0xa6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_msipcistat_print; -#else -#define ahd_msipcistat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MSIPCISTAT", 0xa6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_targpcistat_print; -#else -#define ahd_targpcistat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "TARGPCISTAT", 0xa7, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_data_count_odd_print; -#else -#define ahd_data_count_odd_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DATA_COUNT_ODD", 0xa7, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scbptr_print; -#else -#define ahd_scbptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCBPTR", 0xa8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccscbacnt_print; -#else -#define ahd_ccscbacnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSCBACNT", 0xab, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scbautoptr_print; -#else -#define ahd_scbautoptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCBAUTOPTR", 0xab, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccsgaddr_print; -#else -#define ahd_ccsgaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSGADDR", 0xac, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccscbaddr_print; -#else -#define ahd_ccscbaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSCBADDR", 0xac, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccscbadr_bk_print; -#else -#define ahd_ccscbadr_bk_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSCBADR_BK", 0xac, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmc_rambist_print; -#else -#define ahd_cmc_rambist_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMC_RAMBIST", 0xad, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccsgctl_print; -#else -#define ahd_ccsgctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSGCTL", 0xad, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccscbctl_print; -#else -#define ahd_ccscbctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSCBCTL", 0xad, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccsgram_print; -#else -#define ahd_ccsgram_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSGRAM", 0xb0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_flexadr_print; -#else -#define ahd_flexadr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FLEXADR", 0xb0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ccscbram_print; -#else -#define ahd_ccscbram_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CCSCBRAM", 0xb0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_flexcnt_print; -#else -#define ahd_flexcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FLEXCNT", 0xb3, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_flexdmastat_print; -#else -#define ahd_flexdmastat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FLEXDMASTAT", 0xb5, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_flexdata_print; -#else -#define ahd_flexdata_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FLEXDATA", 0xb6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_brddat_print; -#else -#define ahd_brddat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "BRDDAT", 0xb8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_brdctl_print; -#else -#define ahd_brdctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "BRDCTL", 0xb9, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seeadr_print; -#else -#define ahd_seeadr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEEADR", 0xba, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seedat_print; -#else -#define ahd_seedat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEEDAT", 0xbc, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seectl_print; -#else -#define ahd_seectl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEECTL", 0xbe, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seestat_print; -#else -#define ahd_seestat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEESTAT", 0xbe, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scbcnt_print; -#else -#define ahd_scbcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCBCNT", 0xbf, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfwaddr_print; -#else -#define ahd_dfwaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFWADDR", 0xc0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dspfltrctl_print; -#else -#define ahd_dspfltrctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DSPFLTRCTL", 0xc0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dspdatactl_print; -#else -#define ahd_dspdatactl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DSPDATACTL", 0xc1, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfraddr_print; -#else -#define ahd_dfraddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFRADDR", 0xc2, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dspreqctl_print; -#else -#define ahd_dspreqctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DSPREQCTL", 0xc2, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dspackctl_print; -#else -#define ahd_dspackctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DSPACKCTL", 0xc3, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfdat_print; -#else -#define ahd_dfdat_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFDAT", 0xc4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dspselect_print; -#else -#define ahd_dspselect_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DSPSELECT", 0xc4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_wrtbiasctl_print; -#else -#define ahd_wrtbiasctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "WRTBIASCTL", 0xc5, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_rcvrbiosctl_print; -#else -#define ahd_rcvrbiosctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "RCVRBIOSCTL", 0xc6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_wrtbiascalc_print; -#else -#define ahd_wrtbiascalc_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "WRTBIASCALC", 0xc7, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfptrs_print; -#else -#define ahd_dfptrs_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFPTRS", 0xc8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_rcvrbiascalc_print; -#else -#define ahd_rcvrbiascalc_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "RCVRBIASCALC", 0xc8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfbkptr_print; -#else -#define ahd_dfbkptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFBKPTR", 0xc9, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_skewcalc_print; -#else -#define ahd_skewcalc_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SKEWCALC", 0xc9, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfdbctl_print; -#else -#define ahd_dfdbctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFDBCTL", 0xcb, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfscnt_print; -#else -#define ahd_dfscnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFSCNT", 0xcc, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dfbcnt_print; -#else -#define ahd_dfbcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DFBCNT", 0xce, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ovlyaddr_print; -#else -#define ahd_ovlyaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "OVLYADDR", 0xd4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqctl0_print; -#else -#define ahd_seqctl0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQCTL0", 0xd6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqctl1_print; -#else -#define ahd_seqctl1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQCTL1", 0xd7, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_flags_print; -#else -#define ahd_flags_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FLAGS", 0xd8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqintctl_print; -#else -#define ahd_seqintctl_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQINTCTL", 0xd9, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seqram_print; -#else -#define ahd_seqram_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQRAM", 0xda, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_prgmcnt_print; -#else -#define ahd_prgmcnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "PRGMCNT", 0xde, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_accum_print; -#else -#define ahd_accum_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ACCUM", 0xe0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sindex_print; -#else -#define ahd_sindex_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SINDEX", 0xe2, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dindex_print; -#else -#define ahd_dindex_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DINDEX", 0xe4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_brkaddr1_print; -#else -#define ahd_brkaddr1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "BRKADDR1", 0xe6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_brkaddr0_print; -#else -#define ahd_brkaddr0_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "BRKADDR0", 0xe6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_allones_print; -#else -#define ahd_allones_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ALLONES", 0xe8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_allzeros_print; -#else -#define ahd_allzeros_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ALLZEROS", 0xea, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_none_print; -#else -#define ahd_none_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NONE", 0xea, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sindir_print; -#else -#define ahd_sindir_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SINDIR", 0xec, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dindir_print; -#else -#define ahd_dindir_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DINDIR", 0xed, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_function1_print; -#else -#define ahd_function1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "FUNCTION1", 0xf0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_stack_print; -#else -#define ahd_stack_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "STACK", 0xf2, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_curaddr_print; -#else -#define ahd_curaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CURADDR", 0xf4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_intvec1_addr_print; -#else -#define ahd_intvec1_addr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INTVEC1_ADDR", 0xf4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_intvec2_addr_print; -#else -#define ahd_intvec2_addr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INTVEC2_ADDR", 0xf6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lastaddr_print; -#else -#define ahd_lastaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LASTADDR", 0xf6, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_longjmp_addr_print; -#else -#define ahd_longjmp_addr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LONGJMP_ADDR", 0xf8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_longjmp_scb_print; -#else -#define ahd_longjmp_scb_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LONGJMP_SCB", 0xfa, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_accum_save_print; -#else -#define ahd_accum_save_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ACCUM_SAVE", 0xfc, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_waiting_scb_tails_print; -#else -#define ahd_waiting_scb_tails_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", 0x100, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_ahd_pci_config_base_print; -#else -#define ahd_ahd_pci_config_base_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE", 0x100, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_sram_base_print; -#else -#define ahd_sram_base_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SRAM_BASE", 0x100, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_waiting_tid_head_print; -#else -#define ahd_waiting_tid_head_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "WAITING_TID_HEAD", 0x120, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_waiting_tid_tail_print; -#else -#define ahd_waiting_tid_tail_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "WAITING_TID_TAIL", 0x122, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_next_queued_scb_addr_print; -#else -#define ahd_next_queued_scb_addr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR", 0x124, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_complete_scb_head_print; -#else -#define ahd_complete_scb_head_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD", 0x128, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_complete_scb_dmainprog_head_print; -#else -#define ahd_complete_scb_dmainprog_head_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD", 0x12a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_complete_dma_scb_head_print; -#else -#define ahd_complete_dma_scb_head_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD", 0x12c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_qfreeze_count_print; -#else -#define ahd_qfreeze_count_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "QFREEZE_COUNT", 0x12e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_saved_mode_print; -#else -#define ahd_saved_mode_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SAVED_MODE", 0x130, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_msg_out_print; -#else -#define ahd_msg_out_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "MSG_OUT", 0x131, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_dmaparams_print; -#else -#define ahd_dmaparams_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "DMAPARAMS", 0x132, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seq_flags_print; -#else -#define ahd_seq_flags_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQ_FLAGS", 0x133, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_saved_scsiid_print; -#else -#define ahd_saved_scsiid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SAVED_SCSIID", 0x134, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_saved_lun_print; -#else -#define ahd_saved_lun_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SAVED_LUN", 0x135, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_lastphase_print; -#else -#define ahd_lastphase_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LASTPHASE", 0x136, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_qoutfifo_entry_valid_tag_print; -#else -#define ahd_qoutfifo_entry_valid_tag_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG", 0x137, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_shared_data_addr_print; -#else -#define ahd_shared_data_addr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x138, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_qoutfifo_next_addr_print; -#else -#define ahd_qoutfifo_next_addr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", 0x13c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_kernel_tqinpos_print; -#else -#define ahd_kernel_tqinpos_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "KERNEL_TQINPOS", 0x140, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_tqinpos_print; -#else -#define ahd_tqinpos_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "TQINPOS", 0x141, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_arg_1_print; -#else -#define ahd_arg_1_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ARG_1", 0x142, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_arg_2_print; -#else -#define ahd_arg_2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ARG_2", 0x143, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_last_msg_print; -#else -#define ahd_last_msg_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LAST_MSG", 0x144, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scsiseq_template_print; -#else -#define ahd_scsiseq_template_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x145, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_initiator_tag_print; -#else -#define ahd_initiator_tag_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INITIATOR_TAG", 0x146, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_seq_flags2_print; -#else -#define ahd_seq_flags2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SEQ_FLAGS2", 0x147, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_allocfifo_scbptr_print; -#else -#define ahd_allocfifo_scbptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR", 0x148, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_int_coalessing_timer_print; -#else -#define ahd_int_coalessing_timer_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INT_COALESSING_TIMER", 0x14a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_int_coalessing_maxcmds_print; -#else -#define ahd_int_coalessing_maxcmds_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS", 0x14c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_int_coalessing_mincmds_print; -#else -#define ahd_int_coalessing_mincmds_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS", 0x14d, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmds_pending_print; -#else -#define ahd_cmds_pending_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMDS_PENDING", 0x14e, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_int_coalessing_cmdcount_print; -#else -#define ahd_int_coalessing_cmdcount_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT", 0x150, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_local_hs_mailbox_print; -#else -#define ahd_local_hs_mailbox_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX", 0x151, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_cmdsize_table_print; -#else -#define ahd_cmdsize_table_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "CMDSIZE_TABLE", 0x152, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_base_print; -#else -#define ahd_scb_base_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_BASE", 0x180, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_residual_datacnt_print; -#else -#define ahd_scb_residual_datacnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", 0x180, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_residual_sgptr_print; -#else -#define ahd_scb_residual_sgptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0x184, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_scsi_status_print; -#else -#define ahd_scb_scsi_status_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", 0x188, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_target_phases_print; -#else -#define ahd_scb_target_phases_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_TARGET_PHASES", 0x189, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_target_data_dir_print; -#else -#define ahd_scb_target_data_dir_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0x18a, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_target_itag_print; -#else -#define ahd_scb_target_itag_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_TARGET_ITAG", 0x18b, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_sense_busaddr_print; -#else -#define ahd_scb_sense_busaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR", 0x18c, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_tag_print; -#else -#define ahd_scb_tag_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_cdb_len_print; -#else -#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x192, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_task_management_print; -#else -#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x193, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_next_print; -#else -#define ahd_scb_next_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_NEXT", 0x194, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_next2_print; -#else -#define ahd_scb_next2_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_NEXT2", 0x196, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_dataptr_print; -#else -#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_datacnt_print; -#else -#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_sgptr_print; -#else -#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_control_print; -#else -#define ahd_scb_control_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_CONTROL", 0x1a8, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_scsiid_print; -#else -#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_SCSIID", 0x1a9, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_lun_print; -#else -#define ahd_scb_lun_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_LUN", 0x1aa, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_task_attribute_print; -#else -#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x1ab, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_busaddr_print; -#else -#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1ac, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_spare_print; -#else -#define ahd_scb_spare_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_SPARE", 0x1b0, regvalue, cur_col, wrap) -#endif - -#if AIC_DEBUG_REGISTERS -ahd_reg_print_t ahd_scb_disconnected_lists_print; -#else -#define ahd_scb_disconnected_lists_print(regvalue, cur_col, wrap) \ - ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS", 0x1b8, regvalue, cur_col, wrap) -#endif - - -#define MODE_PTR 0x00 -#define DST_MODE 0x70 -#define SRC_MODE 0x07 - -#define INTSTAT 0x01 -#define INT_PEND 0xff -#define HWERRINT 0x80 -#define BRKADRINT 0x40 -#define SWTMINT 0x20 -#define PCIINT 0x10 -#define SCSIINT 0x08 -#define SEQINT 0x04 -#define CMDCMPLT 0x02 -#define SPLTINT 0x01 - -#define SEQINTCODE 0x02 -#define SAW_HWERR 0x19 -#define TRACEPOINT3 0x18 -#define TRACEPOINT2 0x17 -#define TRACEPOINT1 0x16 -#define TRACEPOINT0 0x15 -#define TASKMGMT_CMD_CMPLT_OKAY 0x14 -#define TASKMGMT_FUNC_COMPLETE 0x13 -#define ENTERING_NONPACK 0x12 -#define CFG4OVERRUN 0x11 -#define STATUS_OVERRUN 0x10 -#define CFG4ISTAT_INTR 0x0f -#define INVALID_SEQINT 0x0e -#define ILLEGAL_PHASE 0x0d -#define DUMP_CARD_STATE 0x0c -#define MISSED_BUSFREE 0x0b -#define MKMSG_FAILED 0x0a -#define DATA_OVERRUN 0x09 -#define BAD_STATUS 0x08 -#define HOST_MSG_LOOP 0x07 -#define PDATA_REINIT 0x06 -#define IGN_WIDE_RES 0x05 -#define NO_MATCH 0x04 -#define PROTO_VIOLATION 0x03 -#define SEND_REJECT 0x02 -#define BAD_PHASE 0x01 -#define NO_SEQINT 0x00 - -#define CLRINT 0x03 -#define CLRHWERRINT 0x80 -#define CLRBRKADRINT 0x40 -#define CLRSWTMINT 0x20 -#define CLRPCIINT 0x10 -#define CLRSCSIINT 0x08 -#define CLRSEQINT 0x04 -#define CLRCMDINT 0x02 -#define CLRSPLTINT 0x01 - -#define ERROR 0x04 -#define CIOPARERR 0x80 -#define CIOACCESFAIL 0x40 -#define MPARERR 0x20 -#define DPARERR 0x10 -#define SQPARERR 0x08 -#define ILLOPCODE 0x04 -#define DSCTMOUT 0x02 - -#define CLRERR 0x04 -#define CLRCIOPARERR 0x80 -#define CLRCIOACCESFAIL 0x40 -#define CLRMPARERR 0x20 -#define CLRDPARERR 0x10 -#define CLRSQPARERR 0x08 -#define CLRILLOPCODE 0x04 -#define CLRDSCTMOUT 0x02 - -#define HCNTRL 0x05 -#define SEQ_RESET 0x80 -#define POWRDN 0x40 -#define SWINT 0x10 -#define SWTIMER_START_B 0x08 -#define PAUSE 0x04 -#define INTEN 0x02 -#define CHIPRST 0x01 -#define CHIPRSTACK 0x01 - -#define HNSCB_QOFF 0x06 - -#define HESCB_QOFF 0x08 - -#define HS_MAILBOX 0x0b -#define HOST_TQINPOS 0x80 -#define ENINT_COALESS 0x40 - -#define CLRSEQINTSTAT 0x0c -#define CLRSEQ_SWTMRTO 0x10 -#define CLRSEQ_SEQINT 0x08 -#define CLRSEQ_SCSIINT 0x04 -#define CLRSEQ_PCIINT 0x02 -#define CLRSEQ_SPLTINT 0x01 - -#define SEQINTSTAT 0x0c -#define SEQ_SWTMRTO 0x10 -#define SEQ_SEQINT 0x08 -#define SEQ_SCSIINT 0x04 -#define SEQ_PCIINT 0x02 -#define SEQ_SPLTINT 0x01 - -#define SWTIMER 0x0e - -#define SNSCB_QOFF 0x10 - -#define SESCB_QOFF 0x12 - -#define SDSCB_QOFF 0x14 - -#define QOFF_CTLSTA 0x16 -#define EMPTY_SCB_AVAIL 0x80 -#define NEW_SCB_AVAIL 0x40 -#define SDSCB_ROLLOVR 0x20 -#define HS_MAILBOX_ACT 0x10 -#define SCB_QSIZE 0x0f -#define SCB_QSIZE_16384 0x0c -#define SCB_QSIZE_8192 0x0b -#define SCB_QSIZE_4096 0x0a -#define SCB_QSIZE_2048 0x09 -#define SCB_QSIZE_1024 0x08 -#define SCB_QSIZE_512 0x07 -#define SCB_QSIZE_256 0x06 -#define SCB_QSIZE_128 0x05 -#define SCB_QSIZE_64 0x04 -#define SCB_QSIZE_32 0x03 -#define SCB_QSIZE_16 0x02 -#define SCB_QSIZE_8 0x01 -#define SCB_QSIZE_4 0x00 - -#define INTCTL 0x18 -#define SWTMINTMASK 0x80 -#define SWTMINTEN 0x40 -#define SWTIMER_START 0x20 -#define AUTOCLRCMDINT 0x10 -#define PCIINTEN 0x08 -#define SCSIINTEN 0x04 -#define SEQINTEN 0x02 -#define SPLTINTEN 0x01 - -#define DFCNTRL 0x19 -#define SCSIENWRDIS 0x40 -#define SCSIENACK 0x20 -#define DIRECTIONACK 0x04 -#define FIFOFLUSHACK 0x02 -#define DIRECTIONEN 0x01 - -#define DSCOMMAND0 0x19 -#define CACHETHEN 0x80 -#define DPARCKEN 0x40 -#define MPARCKEN 0x20 -#define EXTREQLCK 0x10 -#define DISABLE_TWATE 0x02 -#define CIOPARCKEN 0x01 - -#define DFSTATUS 0x1a -#define PRELOAD_AVAIL 0x80 -#define PKT_PRELOAD_AVAIL 0x40 -#define MREQPEND 0x10 -#define HDONE 0x08 -#define DFTHRESH 0x04 -#define FIFOFULL 0x02 -#define FIFOEMP 0x01 - -#define SG_CACHE_SHADOW 0x1b -#define ODD_SEG 0x04 -#define LAST_SEG 0x02 -#define LAST_SEG_DONE 0x01 - -#define ARBCTL 0x1b -#define RESET_HARB 0x80 -#define RETRY_SWEN 0x08 -#define USE_TIME 0x07 - -#define SG_CACHE_PRE 0x1b - -#define LQIN 0x20 - -#define TYPEPTR 0x20 - -#define TAGPTR 0x21 - -#define LUNPTR 0x22 - -#define DATALENPTR 0x23 - -#define STATLENPTR 0x24 - -#define CMDLENPTR 0x25 - -#define ATTRPTR 0x26 - -#define FLAGPTR 0x27 - -#define CMDPTR 0x28 - -#define QNEXTPTR 0x29 - -#define IDPTR 0x2a - -#define ABRTBYTEPTR 0x2b - -#define ABRTBITPTR 0x2c - -#define MAXCMDBYTES 0x2d - -#define MAXCMD2RCV 0x2e - -#define SHORTTHRESH 0x2f - -#define LUNLEN 0x30 - -#define CDBLIMIT 0x31 - -#define MAXCMD 0x32 - -#define MAXCMDCNT 0x33 - -#define LQRSVD01 0x34 - -#define LQRSVD16 0x35 - -#define LQRSVD17 0x36 - -#define CMDRSVD0 0x37 - -#define LQCTL0 0x38 -#define LQITARGCLT 0xc0 -#define LQIINITGCLT 0x30 -#define LQ0TARGCLT 0x0c -#define LQ0INITGCLT 0x03 - -#define LQCTL1 0x38 -#define PCI2PCI 0x04 -#define SINGLECMD 0x02 -#define ABORTPENDING 0x01 - -#define SCSBIST0 0x39 -#define GSBISTERR 0x40 -#define GSBISTDONE 0x20 -#define GSBISTRUN 0x10 -#define OSBISTERR 0x04 -#define OSBISTDONE 0x02 -#define OSBISTRUN 0x01 - -#define LQCTL2 0x39 -#define LQIRETRY 0x80 -#define LQICONTINUE 0x40 -#define LQITOIDLE 0x20 -#define LQIPAUSE 0x10 -#define LQORETRY 0x08 -#define LQOCONTINUE 0x04 -#define LQOTOIDLE 0x02 -#define LQOPAUSE 0x01 - -#define SCSBIST1 0x3a -#define NTBISTERR 0x04 -#define NTBISTDONE 0x02 -#define NTBISTRUN 0x01 - -#define SCSISEQ0 0x3a -#define TEMODEO 0x80 -#define ENSELO 0x40 -#define ENARBO 0x20 -#define FORCEBUSFREE 0x10 -#define SCSIRSTO 0x01 - -#define SCSISEQ1 0x3b - -#define SXFRCTL0 0x3c -#define DFON 0x80 -#define DFPEXP 0x40 -#define BIOSCANCELEN 0x10 -#define SPIOEN 0x08 - -#define BUSINITID 0x3c - -#define DLCOUNT 0x3c - -#define SXFRCTL1 0x3d -#define BITBUCKET 0x80 -#define ENSACHK 0x40 -#define ENSPCHK 0x20 -#define STIMESEL 0x18 -#define ENSTIMER 0x04 -#define ACTNEGEN 0x02 -#define STPWEN 0x01 - -#define BUSTARGID 0x3e - -#define SXFRCTL2 0x3e -#define AUTORSTDIS 0x10 -#define CMDDMAEN 0x08 -#define ASU 0x07 - -#define DFFSTAT 0x3f -#define CURRFIFO 0x03 -#define FIFO1FREE 0x20 -#define FIFO0FREE 0x10 -#define CURRFIFO_NONE 0x03 -#define CURRFIFO_1 0x01 -#define CURRFIFO_0 0x00 - -#define SCSISIGO 0x40 -#define CDO 0x80 -#define IOO 0x40 -#define MSGO 0x20 -#define ATNO 0x10 -#define SELO 0x08 -#define BSYO 0x04 -#define REQO 0x02 -#define ACKO 0x01 - -#define MULTARGID 0x40 - -#define SCSISIGI 0x41 -#define ATNI 0x10 -#define SELI 0x08 -#define BSYI 0x04 -#define REQI 0x02 -#define ACKI 0x01 - -#define SCSIPHASE 0x42 -#define STATUS_PHASE 0x20 -#define COMMAND_PHASE 0x10 -#define MSG_IN_PHASE 0x08 -#define MSG_OUT_PHASE 0x04 -#define DATA_PHASE_MASK 0x03 -#define DATA_IN_PHASE 0x02 -#define DATA_OUT_PHASE 0x01 - -#define SCSIDAT0_IMG 0x43 - -#define SCSIDAT 0x44 - -#define SCSIBUS 0x46 - -#define TARGIDIN 0x48 -#define CLKOUT 0x80 -#define TARGID 0x0f - -#define SELID 0x49 -#define SELID_MASK 0xf0 -#define ONEBIT 0x08 - -#define SBLKCTL 0x4a -#define DIAGLEDEN 0x80 -#define DIAGLEDON 0x40 -#define ENAB40 0x08 -#define ENAB20 0x04 -#define SELWIDE 0x02 - -#define OPTIONMODE 0x4a -#define OPTIONMODE_DEFAULTS 0x02 -#define BIOSCANCTL 0x80 -#define AUTOACKEN 0x40 -#define BIASCANCTL 0x20 -#define BUSFREEREV 0x10 -#define ENDGFORMCHK 0x04 -#define AUTO_MSGOUT_DE 0x02 - -#define SSTAT0 0x4b -#define TARGET 0x80 -#define SELDO 0x40 -#define SELDI 0x20 -#define SELINGO 0x10 -#define IOERR 0x08 -#define OVERRUN 0x04 -#define SPIORDY 0x02 -#define ARBDO 0x01 - -#define CLRSINT0 0x4b -#define CLRSELDO 0x40 -#define CLRSELDI 0x20 -#define CLRSELINGO 0x10 -#define CLRIOERR 0x08 -#define CLROVERRUN 0x04 -#define CLRSPIORDY 0x02 -#define CLRARBDO 0x01 - -#define SIMODE0 0x4b -#define ENSELDO 0x40 -#define ENSELDI 0x20 -#define ENSELINGO 0x10 -#define ENIOERR 0x08 -#define ENOVERRUN 0x04 -#define ENSPIORDY 0x02 -#define ENARBDO 0x01 - -#define CLRSINT1 0x4c -#define CLRSELTIMEO 0x80 -#define CLRATNO 0x40 -#define CLRSCSIRSTI 0x20 -#define CLRBUSFREE 0x08 -#define CLRSCSIPERR 0x04 -#define CLRSTRB2FAST 0x02 -#define CLRREQINIT 0x01 - -#define SSTAT1 0x4c -#define SELTO 0x80 -#define ATNTARG 0x40 -#define SCSIRSTI 0x20 -#define PHASEMIS 0x10 -#define BUSFREE 0x08 -#define SCSIPERR 0x04 -#define STRB2FAST 0x02 -#define REQINIT 0x01 - -#define SSTAT2 0x4d -#define BUSFREETIME 0xc0 -#define NONPACKREQ 0x20 -#define EXP_ACTIVE 0x10 -#define BSYX 0x08 -#define WIDE_RES 0x04 -#define SDONE 0x02 -#define DMADONE 0x01 -#define BUSFREE_DFF1 0xc0 -#define BUSFREE_DFF0 0x80 -#define BUSFREE_LQO 0x40 - -#define CLRSINT2 0x4d -#define CLRNONPACKREQ 0x20 -#define CLRWIDE_RES 0x04 -#define CLRSDONE 0x02 -#define CLRDMADONE 0x01 - -#define SIMODE2 0x4d -#define ENWIDE_RES 0x04 -#define ENSDONE 0x02 -#define ENDMADONE 0x01 - -#define PERRDIAG 0x4e -#define HIZERO 0x80 -#define HIPERR 0x40 -#define PREVPHASE 0x20 -#define PARITYERR 0x10 -#define AIPERR 0x08 -#define CRCERR 0x04 -#define DGFORMERR 0x02 -#define DTERR 0x01 - -#define LQISTATE 0x4e - -#define SOFFCNT 0x4f - -#define LQOSTATE 0x4f - -#define LQISTAT0 0x50 -#define LQIATNQAS 0x20 -#define LQICRCT1 0x10 -#define LQICRCT2 0x08 -#define LQIBADLQT 0x04 -#define LQIATNLQ 0x02 -#define LQIATNCMD 0x01 - -#define CLRLQIINT0 0x50 -#define CLRLQIATNQAS 0x20 -#define CLRLQICRCT1 0x10 -#define CLRLQICRCT2 0x08 -#define CLRLQIBADLQT 0x04 -#define CLRLQIATNLQ 0x02 -#define CLRLQIATNCMD 0x01 - -#define LQIMODE0 0x50 -#define ENLQIATNQASK 0x20 -#define ENLQICRCT1 0x10 -#define ENLQICRCT2 0x08 -#define ENLQIBADLQT 0x04 -#define ENLQIATNLQ 0x02 -#define ENLQIATNCMD 0x01 - -#define LQIMODE1 0x51 -#define ENLQIPHASE_LQ 0x80 -#define ENLQIPHASE_NLQ 0x40 -#define ENLIQABORT 0x20 -#define ENLQICRCI_LQ 0x10 -#define ENLQICRCI_NLQ 0x08 -#define ENLQIBADLQI 0x04 -#define ENLQIOVERI_LQ 0x02 -#define ENLQIOVERI_NLQ 0x01 - -#define LQISTAT1 0x51 -#define LQIPHASE_LQ 0x80 -#define LQIPHASE_NLQ 0x40 -#define LQIABORT 0x20 -#define LQICRCI_LQ 0x10 -#define LQICRCI_NLQ 0x08 -#define LQIBADLQI 0x04 -#define LQIOVERI_LQ 0x02 -#define LQIOVERI_NLQ 0x01 - -#define CLRLQIINT1 0x51 -#define CLRLQIPHASE_LQ 0x80 -#define CLRLQIPHASE_NLQ 0x40 -#define CLRLIQABORT 0x20 -#define CLRLQICRCI_LQ 0x10 -#define CLRLQICRCI_NLQ 0x08 -#define CLRLQIBADLQI 0x04 -#define CLRLQIOVERI_LQ 0x02 -#define CLRLQIOVERI_NLQ 0x01 - -#define LQISTAT2 0x52 -#define PACKETIZED 0x80 -#define LQIPHASE_OUTPKT 0x40 -#define LQIWORKONLQ 0x20 -#define LQIWAITFIFO 0x10 -#define LQISTOPPKT 0x08 -#define LQISTOPLQ 0x04 -#define LQISTOPCMD 0x02 -#define LQIGSAVAIL 0x01 - -#define SSTAT3 0x53 -#define NTRAMPERR 0x02 -#define OSRAMPERR 0x01 - -#define SIMODE3 0x53 -#define ENNTRAMPERR 0x02 -#define ENOSRAMPERR 0x01 - -#define CLRSINT3 0x53 -#define CLRNTRAMPERR 0x02 -#define CLROSRAMPERR 0x01 - -#define LQOMODE0 0x54 -#define ENLQOTARGSCBPERR 0x10 -#define ENLQOSTOPT2 0x08 -#define ENLQOATNLQ 0x04 -#define ENLQOATNPKT 0x02 -#define ENLQOTCRC 0x01 - -#define LQOSTAT0 0x54 -#define LQOTARGSCBPERR 0x10 -#define LQOSTOPT2 0x08 -#define LQOATNLQ 0x04 -#define LQOATNPKT 0x02 -#define LQOTCRC 0x01 - -#define CLRLQOINT0 0x54 -#define CLRLQOTARGSCBPERR 0x10 -#define CLRLQOSTOPT2 0x08 -#define CLRLQOATNLQ 0x04 -#define CLRLQOATNPKT 0x02 -#define CLRLQOTCRC 0x01 - -#define LQOSTAT1 0x55 -#define LQOINITSCBPERR 0x10 -#define LQOSTOPI2 0x08 -#define LQOBADQAS 0x04 -#define LQOBUSFREE 0x02 -#define LQOPHACHGINPKT 0x01 - -#define CLRLQOINT1 0x55 -#define CLRLQOINITSCBPERR 0x10 -#define CLRLQOSTOPI2 0x08 -#define CLRLQOBADQAS 0x04 -#define CLRLQOBUSFREE 0x02 -#define CLRLQOPHACHGINPKT 0x01 - -#define LQOMODE1 0x55 -#define ENLQOINITSCBPERR 0x10 -#define ENLQOSTOPI2 0x08 -#define ENLQOBADQAS 0x04 -#define ENLQOBUSFREE 0x02 -#define ENLQOPHACHGINPKT 0x01 - -#define LQOSTAT2 0x56 -#define LQOPKT 0xe0 -#define LQOWAITFIFO 0x10 -#define LQOPHACHGOUTPKT 0x02 -#define LQOSTOP0 0x01 - -#define OS_SPACE_CNT 0x56 - -#define SIMODE1 0x57 -#define ENSELTIMO 0x80 -#define ENATNTARG 0x40 -#define ENSCSIRST 0x20 -#define ENPHASEMIS 0x10 -#define ENBUSFREE 0x08 -#define ENSCSIPERR 0x04 -#define ENSTRB2FAST 0x02 -#define ENREQINIT 0x01 - -#define GSFIFO 0x58 - -#define DFFSXFRCTL 0x5a -#define DFFBITBUCKET 0x08 -#define CLRSHCNT 0x04 -#define CLRCHN 0x02 -#define RSTCHN 0x01 - -#define LQOSCSCTL 0x5a -#define LQOH2A_VERSION 0x80 -#define LQONOCHKOVER 0x01 - -#define NEXTSCB 0x5a - -#define CLRSEQINTSRC 0x5b -#define CLRCTXTDONE 0x40 -#define CLRSAVEPTRS 0x20 -#define CLRCFG4DATA 0x10 -#define CLRCFG4ISTAT 0x08 -#define CLRCFG4TSTAT 0x04 -#define CLRCFG4ICMD 0x02 -#define CLRCFG4TCMD 0x01 - -#define SEQINTSRC 0x5b -#define CTXTDONE 0x40 -#define SAVEPTRS 0x20 -#define CFG4DATA 0x10 -#define CFG4ISTAT 0x08 -#define CFG4TSTAT 0x04 -#define CFG4ICMD 0x02 -#define CFG4TCMD 0x01 - -#define CURRSCB 0x5c - -#define SEQIMODE 0x5c -#define ENCTXTDONE 0x40 -#define ENSAVEPTRS 0x20 -#define ENCFG4DATA 0x10 -#define ENCFG4ISTAT 0x08 -#define ENCFG4TSTAT 0x04 -#define ENCFG4ICMD 0x02 -#define ENCFG4TCMD 0x01 - -#define MDFFSTAT 0x5d -#define SHCNTNEGATIVE 0x40 -#define SHCNTMINUS1 0x20 -#define LASTSDONE 0x10 -#define SHVALID 0x08 -#define DLZERO 0x04 -#define DATAINFIFO 0x02 -#define FIFOFREE 0x01 - -#define CRCCONTROL 0x5d -#define CRCVALCHKEN 0x40 - -#define DFFTAG 0x5e - -#define LASTSCB 0x5e - -#define SCSITEST 0x5e -#define CNTRTEST 0x08 -#define SEL_TXPLL_DEBUG 0x04 - -#define IOPDNCTL 0x5f -#define DISABLE_OE 0x80 -#define PDN_IDIST 0x04 -#define PDN_DIFFSENSE 0x01 - -#define SHADDR 0x60 - -#define NEGOADDR 0x60 - -#define DGRPCRCI 0x60 - -#define NEGPERIOD 0x61 - -#define PACKCRCI 0x62 - -#define NEGOFFSET 0x62 - -#define NEGPPROPTS 0x63 -#define PPROPT_PACE 0x08 -#define PPROPT_QAS 0x04 -#define PPROPT_DT 0x02 -#define PPROPT_IUT 0x01 - -#define NEGCONOPTS 0x64 -#define ENSNAPSHOT 0x40 -#define RTI_WRTDIS 0x20 -#define RTI_OVRDTRN 0x10 -#define ENSLOWCRC 0x08 -#define ENAUTOATNI 0x04 -#define ENAUTOATNO 0x02 -#define WIDEXFER 0x01 - -#define ANNEXCOL 0x65 - -#define SCSCHKN 0x66 -#define STSELSKIDDIS 0x40 -#define CURRFIFODEF 0x20 -#define WIDERESEN 0x10 -#define SDONEMSKDIS 0x08 -#define DFFACTCLR 0x04 -#define SHVALIDSTDIS 0x02 -#define LSTSGCLRDIS 0x01 - -#define ANNEXDAT 0x66 - -#define IOWNID 0x67 - -#define PLL960CTL0 0x68 - -#define SHCNT 0x68 - -#define TOWNID 0x69 - -#define PLL960CTL1 0x69 - -#define PLL960CNT0 0x6a - -#define XSIG 0x6a - -#define SELOID 0x6b - -#define PLL400CTL0 0x6c -#define PLL_VCOSEL 0x80 -#define PLL_PWDN 0x40 -#define PLL_NS 0x30 -#define PLL_ENLUD 0x08 -#define PLL_ENLPF 0x04 -#define PLL_DLPF 0x02 -#define PLL_ENFBM 0x01 - -#define FAIRNESS 0x6c - -#define PLL400CTL1 0x6d -#define PLL_CNTEN 0x80 -#define PLL_CNTCLR 0x40 -#define PLL_RST 0x01 - -#define PLL400CNT0 0x6e - -#define UNFAIRNESS 0x6e - -#define HADDR 0x70 - -#define PLLDELAY 0x70 -#define SPLIT_DROP_REQ 0x80 - -#define HODMAADR 0x70 - -#define HODMACNT 0x78 - -#define HCNT 0x78 - -#define HODMAEN 0x7a - -#define SGHADDR 0x7c - -#define SCBHADDR 0x7c - -#define SGHCNT 0x84 - -#define SCBHCNT 0x84 - -#define DFF_THRSH 0x88 -#define WR_DFTHRSH 0x70 -#define RD_DFTHRSH 0x07 -#define WR_DFTHRSH_MAX 0x70 -#define WR_DFTHRSH_90 0x60 -#define WR_DFTHRSH_85 0x50 -#define WR_DFTHRSH_75 0x40 -#define WR_DFTHRSH_63 0x30 -#define WR_DFTHRSH_50 0x20 -#define WR_DFTHRSH_25 0x10 -#define RD_DFTHRSH_MAX 0x07 -#define RD_DFTHRSH_90 0x06 -#define RD_DFTHRSH_85 0x05 -#define RD_DFTHRSH_75 0x04 -#define RD_DFTHRSH_63 0x03 -#define RD_DFTHRSH_50 0x02 -#define RD_DFTHRSH_25 0x01 -#define WR_DFTHRSH_MIN 0x00 -#define RD_DFTHRSH_MIN 0x00 - -#define ROMADDR 0x8a - -#define ROMCNTRL 0x8d -#define ROMOP 0xe0 -#define ROMSPD 0x18 -#define REPEAT 0x02 -#define RDY 0x01 - -#define ROMDATA 0x8e - -#define CMCRXMSG0 0x90 - -#define ROENABLE 0x90 -#define MSIROEN 0x20 -#define OVLYROEN 0x10 -#define CMCROEN 0x08 -#define SGROEN 0x04 -#define DCH1ROEN 0x02 -#define DCH0ROEN 0x01 - -#define OVLYRXMSG0 0x90 - -#define DCHRXMSG0 0x90 - -#define OVLYRXMSG1 0x91 - -#define NSENABLE 0x91 -#define MSINSEN 0x20 -#define OVLYNSEN 0x10 -#define CMCNSEN 0x08 -#define SGNSEN 0x04 -#define DCH1NSEN 0x02 -#define DCH0NSEN 0x01 - -#define DCHRXMSG1 0x91 - -#define CMCRXMSG1 0x91 - -#define DCHRXMSG2 0x92 - -#define OVLYRXMSG2 0x92 - -#define CMCRXMSG2 0x92 - -#define OST 0x92 - -#define DCHRXMSG3 0x93 - -#define CMCRXMSG3 0x93 - -#define PCIXCTL 0x93 -#define SERRPULSE 0x80 -#define UNEXPSCIEN 0x20 -#define SPLTSMADIS 0x10 -#define SPLTSTADIS 0x08 -#define SRSPDPEEN 0x04 -#define TSCSERREN 0x02 -#define CMPABCDIS 0x01 - -#define OVLYRXMSG3 0x93 - -#define OVLYSEQBCNT 0x94 - -#define CMCSEQBCNT 0x94 - -#define DCHSEQBCNT 0x94 - -#define CMCSPLTSTAT0 0x96 - -#define OVLYSPLTSTAT0 0x96 - -#define DCHSPLTSTAT0 0x96 - -#define DCHSPLTSTAT1 0x97 - -#define CMCSPLTSTAT1 0x97 - -#define OVLYSPLTSTAT1 0x97 - -#define SGRXMSG0 0x98 -#define CDNUM 0xf8 -#define CFNUM 0x07 - -#define SLVSPLTOUTADR0 0x98 -#define LOWER_ADDR 0x7f - -#define SGRXMSG1 0x99 -#define CBNUM 0xff - -#define SLVSPLTOUTADR1 0x99 -#define REQ_DNUM 0xf8 -#define REQ_FNUM 0x07 - -#define SGRXMSG2 0x9a -#define MINDEX 0xff - -#define SLVSPLTOUTADR2 0x9a -#define REQ_BNUM 0xff - -#define SGRXMSG3 0x9b -#define MCLASS 0x0f - -#define SLVSPLTOUTADR3 0x9b -#define TAG_NUM 0x1f -#define RLXORD 0x10 - -#define SGSEQBCNT 0x9c - -#define SLVSPLTOUTATTR0 0x9c -#define LOWER_BCNT 0xff - -#define SLVSPLTOUTATTR1 0x9d -#define CMPLT_DNUM 0xf8 -#define CMPLT_FNUM 0x07 - -#define SLVSPLTOUTATTR2 0x9e -#define CMPLT_BNUM 0xff - -#define SGSPLTSTAT0 0x9e -#define STAETERM 0x80 -#define SCBCERR 0x40 -#define SCADERR 0x20 -#define SCDATBUCKET 0x10 -#define CNTNOTCMPLT 0x08 -#define RXOVRUN 0x04 -#define RXSCEMSG 0x02 -#define RXSPLTRSP 0x01 - -#define SFUNCT 0x9f -#define TEST_GROUP 0xf0 -#define TEST_NUM 0x0f - -#define SGSPLTSTAT1 0x9f -#define RXDATABUCKET 0x01 - -#define DF0PCISTAT 0xa0 - -#define REG0 0xa0 - -#define DF1PCISTAT 0xa1 - -#define SGPCISTAT 0xa2 - -#define REG1 0xa2 - -#define CMCPCISTAT 0xa3 - -#define OVLYPCISTAT 0xa4 -#define SCAAPERR 0x08 -#define RDPERR 0x04 - -#define REG_ISR 0xa4 - -#define SG_STATE 0xa6 -#define FETCH_INPROG 0x04 -#define LOADING_NEEDED 0x02 -#define SEGS_AVAIL 0x01 - -#define MSIPCISTAT 0xa6 -#define RMA 0x20 -#define RTA 0x10 -#define CLRPENDMSI 0x08 -#define DPR 0x01 - -#define TARGPCISTAT 0xa7 -#define DPE 0x80 -#define SSE 0x40 -#define STA 0x08 -#define TWATERR 0x02 - -#define DATA_COUNT_ODD 0xa7 - -#define SCBPTR 0xa8 - -#define CCSCBACNT 0xab - -#define SCBAUTOPTR 0xab -#define AUSCBPTR_EN 0x80 -#define SCBPTR_ADDR 0x38 -#define SCBPTR_OFF 0x07 - -#define CCSGADDR 0xac - -#define CCSCBADDR 0xac - -#define CCSCBADR_BK 0xac - -#define CMC_RAMBIST 0xad -#define SG_ELEMENT_SIZE 0x80 -#define SCBRAMBIST_FAIL 0x40 -#define SG_BIST_FAIL 0x20 -#define SG_BIST_EN 0x10 -#define CMC_BUFFER_BIST_FAIL 0x02 -#define CMC_BUFFER_BIST_EN 0x01 - -#define CCSGCTL 0xad -#define CCSGEN 0x0c -#define CCSGDONE 0x80 -#define SG_CACHE_AVAIL 0x10 -#define CCSGENACK 0x08 -#define SG_FETCH_REQ 0x02 -#define CCSGRESET 0x01 - -#define CCSCBCTL 0xad -#define CCSCBDONE 0x80 -#define ARRDONE 0x40 -#define CCARREN 0x10 -#define CCSCBEN 0x08 -#define CCSCBDIR 0x04 -#define CCSCBRESET 0x01 - -#define CCSGRAM 0xb0 - -#define FLEXADR 0xb0 - -#define CCSCBRAM 0xb0 - -#define FLEXCNT 0xb3 - -#define FLEXDMASTAT 0xb5 -#define FLEXDMAERR 0x02 -#define FLEXDMADONE 0x01 - -#define FLEXDATA 0xb6 - -#define BRDDAT 0xb8 - -#define BRDCTL 0xb9 -#define FLXARBACK 0x80 -#define FLXARBREQ 0x40 -#define BRDADDR 0x38 -#define BRDEN 0x04 -#define BRDRW 0x02 -#define BRDSTB 0x01 - -#define SEEADR 0xba - -#define SEEDAT 0xbc - -#define SEECTL 0xbe -#define SEEOP_EWEN 0x40 -#define SEEOP_WALL 0x40 -#define SEEOP_EWDS 0x40 -#define SEEOPCODE 0x70 -#define SEERST 0x02 -#define SEESTART 0x01 -#define SEEOP_ERASE 0x70 -#define SEEOP_READ 0x60 -#define SEEOP_WRITE 0x50 -#define SEEOP_ERAL 0x40 - -#define SEESTAT 0xbe -#define INIT_DONE 0x80 -#define LDALTID_L 0x08 -#define SEEARBACK 0x04 -#define SEEBUSY 0x02 - -#define SCBCNT 0xbf - -#define DFWADDR 0xc0 - -#define DSPFLTRCTL 0xc0 -#define FLTRDISABLE 0x20 -#define EDGESENSE 0x10 -#define DSPFCNTSEL 0x0f - -#define DSPDATACTL 0xc1 -#define BYPASSENAB 0x80 -#define DESQDIS 0x10 -#define RCVROFFSTDIS 0x04 -#define XMITOFFSTDIS 0x02 - -#define DFRADDR 0xc2 - -#define DSPREQCTL 0xc2 -#define MANREQCTL 0xc0 -#define MANREQDLY 0x3f - -#define DSPACKCTL 0xc3 -#define MANACKCTL 0xc0 -#define MANACKDLY 0x3f - -#define DFDAT 0xc4 - -#define DSPSELECT 0xc4 -#define AUTOINCEN 0x80 -#define DSPSEL 0x1f - -#define WRTBIASCTL 0xc5 -#define AUTOXBCDIS 0x80 -#define XMITMANVAL 0x3f - -#define RCVRBIOSCTL 0xc6 -#define AUTORBCDIS 0x80 -#define RCVRMANVAL 0x3f - -#define WRTBIASCALC 0xc7 - -#define DFPTRS 0xc8 - -#define RCVRBIASCALC 0xc8 - -#define DFBKPTR 0xc9 - -#define SKEWCALC 0xc9 - -#define DFDBCTL 0xcb -#define DFF_CIO_WR_RDY 0x20 -#define DFF_CIO_RD_RDY 0x10 -#define DFF_DIR_ERR 0x08 -#define DFF_RAMBIST_FAIL 0x04 -#define DFF_RAMBIST_DONE 0x02 -#define DFF_RAMBIST_EN 0x01 - -#define DFSCNT 0xcc - -#define DFBCNT 0xce - -#define OVLYADDR 0xd4 - -#define SEQCTL0 0xd6 -#define PERRORDIS 0x80 -#define PAUSEDIS 0x40 -#define FAILDIS 0x20 -#define FASTMODE 0x10 -#define BRKADRINTEN 0x08 -#define STEP 0x04 -#define SEQRESET 0x02 -#define LOADRAM 0x01 - -#define SEQCTL1 0xd7 -#define OVRLAY_DATA_CHK 0x08 -#define RAMBIST_DONE 0x04 -#define RAMBIST_FAIL 0x02 -#define RAMBIST_EN 0x01 - -#define FLAGS 0xd8 -#define ZERO 0x02 -#define CARRY 0x01 - -#define SEQINTCTL 0xd9 -#define INTVEC1DSL 0x80 -#define INT1_CONTEXT 0x20 -#define SCS_SEQ_INT1M1 0x10 -#define SCS_SEQ_INT1M0 0x08 -#define INTMASK2 0x04 -#define INTMASK1 0x02 -#define IRET 0x01 - -#define SEQRAM 0xda - -#define PRGMCNT 0xde - -#define ACCUM 0xe0 - -#define SINDEX 0xe2 - -#define DINDEX 0xe4 - -#define BRKADDR1 0xe6 -#define BRKDIS 0x80 - -#define BRKADDR0 0xe6 - -#define ALLONES 0xe8 - -#define ALLZEROS 0xea - -#define NONE 0xea - -#define SINDIR 0xec - -#define DINDIR 0xed - -#define FUNCTION1 0xf0 - -#define STACK 0xf2 - -#define CURADDR 0xf4 - -#define INTVEC1_ADDR 0xf4 - -#define INTVEC2_ADDR 0xf6 - -#define LASTADDR 0xf6 - -#define LONGJMP_ADDR 0xf8 - -#define LONGJMP_SCB 0xfa - -#define ACCUM_SAVE 0xfc - -#define WAITING_SCB_TAILS 0x100 - -#define AHD_PCI_CONFIG_BASE 0x100 - -#define SRAM_BASE 0x100 - -#define WAITING_TID_HEAD 0x120 - -#define WAITING_TID_TAIL 0x122 - -#define NEXT_QUEUED_SCB_ADDR 0x124 - -#define COMPLETE_SCB_HEAD 0x128 - -#define COMPLETE_SCB_DMAINPROG_HEAD 0x12a - -#define COMPLETE_DMA_SCB_HEAD 0x12c - -#define QFREEZE_COUNT 0x12e - -#define SAVED_MODE 0x130 - -#define MSG_OUT 0x131 - -#define DMAPARAMS 0x132 -#define PRELOADEN 0x80 -#define WIDEODD 0x40 -#define SCSIEN 0x20 -#define SDMAEN 0x10 -#define SDMAENACK 0x10 -#define HDMAENACK 0x08 -#define HDMAEN 0x08 -#define DIRECTION 0x04 -#define FIFOFLUSH 0x02 -#define FIFORESET 0x01 - -#define SEQ_FLAGS 0x133 -#define NOT_IDENTIFIED 0x80 -#define NO_CDB_SENT 0x40 -#define TARGET_CMD_IS_TAGGED 0x40 -#define DPHASE 0x20 -#define TARG_CMD_PENDING 0x10 -#define CMDPHASE_PENDING 0x08 -#define DPHASE_PENDING 0x04 -#define SPHASE_PENDING 0x02 -#define NO_DISCONNECT 0x01 - -#define SAVED_SCSIID 0x134 - -#define SAVED_LUN 0x135 - -#define LASTPHASE 0x136 -#define PHASE_MASK 0xe0 -#define CDI 0x80 -#define IOI 0x40 -#define MSGI 0x20 -#define P_BUSFREE 0x01 -#define P_MESGIN 0xe0 -#define P_STATUS 0xc0 -#define P_MESGOUT 0xa0 -#define P_COMMAND 0x80 -#define P_DATAIN_DT 0x60 -#define P_DATAIN 0x40 -#define P_DATAOUT_DT 0x20 -#define P_DATAOUT 0x00 - -#define QOUTFIFO_ENTRY_VALID_TAG 0x137 - -#define SHARED_DATA_ADDR 0x138 - -#define QOUTFIFO_NEXT_ADDR 0x13c - -#define KERNEL_TQINPOS 0x140 - -#define TQINPOS 0x141 - -#define ARG_1 0x142 -#define RETURN_1 0x142 -#define SEND_MSG 0x80 -#define SEND_SENSE 0x40 -#define SEND_REJ 0x20 -#define MSGOUT_PHASEMIS 0x10 -#define EXIT_MSG_LOOP 0x08 -#define CONT_MSG_LOOP_WRITE 0x04 -#define CONT_MSG_LOOP_READ 0x03 -#define CONT_MSG_LOOP_TARG 0x02 - -#define ARG_2 0x143 -#define RETURN_2 0x143 - -#define LAST_MSG 0x144 - -#define SCSISEQ_TEMPLATE 0x145 -#define MANUALCTL 0x40 -#define ENSELI 0x20 -#define ENRSELI 0x10 -#define MANUALP 0x0c -#define ENAUTOATNP 0x02 -#define ALTSTIM 0x01 - -#define INITIATOR_TAG 0x146 - -#define SEQ_FLAGS2 0x147 -#define SELECTOUT_QFROZEN 0x04 -#define TARGET_MSG_PENDING 0x02 - -#define ALLOCFIFO_SCBPTR 0x148 - -#define INT_COALESSING_TIMER 0x14a - -#define INT_COALESSING_MAXCMDS 0x14c - -#define INT_COALESSING_MINCMDS 0x14d - -#define CMDS_PENDING 0x14e - -#define INT_COALESSING_CMDCOUNT 0x150 - -#define LOCAL_HS_MAILBOX 0x151 - -#define CMDSIZE_TABLE 0x152 - -#define SCB_BASE 0x180 - -#define SCB_RESIDUAL_DATACNT 0x180 -#define SCB_CDB_STORE 0x180 - -#define SCB_RESIDUAL_SGPTR 0x184 -#define SCB_CDB_PTR 0x184 -#define SG_ADDR_MASK 0xf8 -#define SG_OVERRUN_RESID 0x02 - -#define SCB_SCSI_STATUS 0x188 - -#define SCB_TARGET_PHASES 0x189 - -#define SCB_TARGET_DATA_DIR 0x18a - -#define SCB_TARGET_ITAG 0x18b - -#define SCB_SENSE_BUSADDR 0x18c -#define SCB_NEXT_COMPLETE 0x18c - -#define SCB_TAG 0x190 - -#define SCB_CDB_LEN 0x192 -#define SCB_CDB_LEN_PTR 0x80 - -#define SCB_TASK_MANAGEMENT 0x193 - -#define SCB_NEXT 0x194 -#define SCB_NEXT_SCB_BUSADDR 0x194 - -#define SCB_NEXT2 0x196 - -#define SCB_DATAPTR 0x198 - -#define SCB_DATACNT 0x1a0 -#define SG_LAST_SEG 0x80 -#define SG_HIGH_ADDR_BITS 0x7f - -#define SCB_SGPTR 0x1a4 -#define SG_STATUS_VALID 0x04 -#define SG_FULL_RESID 0x02 -#define SG_LIST_NULL 0x01 - -#define SCB_CONTROL 0x1a8 -#define TARGET_SCB 0x80 -#define DISCENB 0x40 -#define TAG_ENB 0x20 -#define MK_MESSAGE 0x10 -#define STATUS_RCVD 0x08 -#define DISCONNECTED 0x04 -#define SCB_TAG_TYPE 0x03 - -#define SCB_SCSIID 0x1a9 -#define TID 0xf0 -#define OID 0x0f - -#define SCB_LUN 0x1aa -#define LID 0xff - -#define SCB_TASK_ATTRIBUTE 0x1ab - -#define SCB_BUSADDR 0x1ac - -#define SCB_SPARE 0x1b0 -#define SCB_PKT_LUN 0x1b0 - -#define SCB_DISCONNECTED_LISTS 0x1b8 - - -#define AHD_TIMER_US_PER_TICK 0x19 -#define SCB_TRANSFER_SIZE_FULL_LUN 0x38 -#define STATUS_QUEUE_FULL 0x28 -#define STATUS_BUSY 0x08 -#define MAX_OFFSET_NON_PACED 0x7f -#define MAX_OFFSET_PACED 0xfe -#define BUS_32_BIT 0x02 -#define CCSGADDR_MAX 0x80 -#define TID_SHIFT 0x04 -#define MK_MESSAGE_BIT_OFFSET 0x04 -#define WRTBIASCTL_HP_DEFAULT 0x00 -#define SEEOP_EWDS_ADDR 0x00 -#define AHD_AMPLITUDE_SHIFT 0x00 -#define AHD_AMPLITUDE_MASK 0x07 -#define AHD_ANNEXCOL_AMPLITUDE 0x06 -#define AHD_SLEWRATE_DEF_REVA 0x01 -#define AHD_SLEWRATE_SHIFT 0x03 -#define AHD_SLEWRATE_MASK 0x78 -#define AHD_PRECOMP_CUTBACK_29 0x06 -#define AHD_NUM_PER_DEV_ANNEXCOLS 0x04 -#define B_CURRFIFO_0 0x02 -#define NVRAM_SCB_OFFSET 0x2c -#define AHD_TIMER_MAX_US 0x18ffe7 -#define AHD_TIMER_MAX_TICKS 0xffff -#define STATUS_PKT_SENSE 0xff -#define CMD_GROUP_CODE_SHIFT 0x05 -#define AHD_SENSE_BUFSIZE 0x100 -#define MAX_OFFSET_PACED_BUG 0x7f -#define BUS_8_BIT 0x00 -#define STIMESEL_BUG_ADJ 0x08 -#define STIMESEL_MIN 0x18 -#define STIMESEL_SHIFT 0x03 -#define CCSGRAM_MAXSEGS 0x10 -#define INVALID_ADDR 0x80 -#define TARGET_CMD_CMPLT 0xfe -#define SEEOP_WRAL_ADDR 0x40 -#define SEEOP_ERAL_ADDR 0x80 -#define AHD_AMPLITUDE_DEF 0x07 -#define AHD_SLEWRATE_DEF_REVB 0x08 -#define AHD_PRECOMP_CUTBACK_37 0x07 -#define AHD_PRECOMP_CUTBACK_17 0x04 -#define AHD_PRECOMP_SHIFT 0x00 -#define AHD_PRECOMP_MASK 0x07 -#define AHD_ANNEXCOL_PRECOMP_SLEW 0x04 -#define SRC_MODE_SHIFT 0x00 -#define PKT_OVERRUN_BUFSIZE 0x200 -#define SCB_TRANSFER_SIZE_1BYTE_LUN 0x30 -#define TARGET_DATA_IN 0x01 -#define HOST_MSG 0xff -#define MAX_OFFSET 0xfe -#define BUS_16_BIT 0x01 -#define CCSCBADDR_MAX 0x80 -#define NUMDSPS 0x14 -#define SEEOP_EWEN_ADDR 0xc0 -#define AHD_ANNEXCOL_PER_DEV0 0x04 -#define DST_MODE_SHIFT 0x04 - - -/* Downloaded Constant Definitions */ -#define SCB_TRANSFER_SIZE 0x06 -#define PKT_OVERRUN_BUFOFFSET 0x05 -#define SG_SIZEOF 0x04 -#define SG_PREFETCH_ADDR_MASK 0x03 -#define SG_PREFETCH_ALIGN_MASK 0x02 -#define SG_PREFETCH_CNT_LIMIT 0x01 -#define SG_PREFETCH_CNT 0x00 -#define DOWNLOAD_CONST_COUNT 0x07 - - -/* Exported Labels */ -#define LABEL_seq_isr 0x263 -#define LABEL_timer_isr 0x25f diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_reg_print.c linux-2.4.22/drivers/scsi/aic79xx/aic79xx_reg_print.c --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_reg_print.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_reg_print.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,3632 +0,0 @@ -/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ - */ - -#include "aic79xx_osm.h" - -static ahd_reg_parse_entry_t MODE_PTR_parse_table[] = { - { "SRC_MODE", 0x07, 0x07 }, - { "DST_MODE", 0x70, 0x70 } -}; - -int -ahd_mode_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(MODE_PTR_parse_table, 2, "MODE_PTR", - 0x00, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t INTSTAT_parse_table[] = { - { "SPLTINT", 0x01, 0x01 }, - { "CMDCMPLT", 0x02, 0x02 }, - { "SEQINT", 0x04, 0x04 }, - { "SCSIINT", 0x08, 0x08 }, - { "PCIINT", 0x10, 0x10 }, - { "SWTMINT", 0x20, 0x20 }, - { "BRKADRINT", 0x40, 0x40 }, - { "HWERRINT", 0x80, 0x80 }, - { "INT_PEND", 0xff, 0xff } -}; - -int -ahd_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(INTSTAT_parse_table, 9, "INTSTAT", - 0x01, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = { - { "NO_SEQINT", 0x00, 0xff }, - { "BAD_PHASE", 0x01, 0xff }, - { "SEND_REJECT", 0x02, 0xff }, - { "PROTO_VIOLATION", 0x03, 0xff }, - { "NO_MATCH", 0x04, 0xff }, - { "IGN_WIDE_RES", 0x05, 0xff }, - { "PDATA_REINIT", 0x06, 0xff }, - { "HOST_MSG_LOOP", 0x07, 0xff }, - { "BAD_STATUS", 0x08, 0xff }, - { "DATA_OVERRUN", 0x09, 0xff }, - { "MKMSG_FAILED", 0x0a, 0xff }, - { "MISSED_BUSFREE", 0x0b, 0xff }, - { "DUMP_CARD_STATE", 0x0c, 0xff }, - { "ILLEGAL_PHASE", 0x0d, 0xff }, - { "INVALID_SEQINT", 0x0e, 0xff }, - { "CFG4ISTAT_INTR", 0x0f, 0xff }, - { "STATUS_OVERRUN", 0x10, 0xff }, - { "CFG4OVERRUN", 0x11, 0xff }, - { "ENTERING_NONPACK", 0x12, 0xff }, - { "TASKMGMT_FUNC_COMPLETE",0x13, 0xff }, - { "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff }, - { "TRACEPOINT0", 0x15, 0xff }, - { "TRACEPOINT1", 0x16, 0xff }, - { "TRACEPOINT2", 0x17, 0xff }, - { "TRACEPOINT3", 0x18, 0xff }, - { "SAW_HWERR", 0x19, 0xff } -}; - -int -ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQINTCODE_parse_table, 26, "SEQINTCODE", - 0x02, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRINT_parse_table[] = { - { "CLRSPLTINT", 0x01, 0x01 }, - { "CLRCMDINT", 0x02, 0x02 }, - { "CLRSEQINT", 0x04, 0x04 }, - { "CLRSCSIINT", 0x08, 0x08 }, - { "CLRPCIINT", 0x10, 0x10 }, - { "CLRSWTMINT", 0x20, 0x20 }, - { "CLRBRKADRINT", 0x40, 0x40 }, - { "CLRHWERRINT", 0x80, 0x80 } -}; - -int -ahd_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRINT_parse_table, 8, "CLRINT", - 0x03, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t ERROR_parse_table[] = { - { "DSCTMOUT", 0x02, 0x02 }, - { "ILLOPCODE", 0x04, 0x04 }, - { "SQPARERR", 0x08, 0x08 }, - { "DPARERR", 0x10, 0x10 }, - { "MPARERR", 0x20, 0x20 }, - { "CIOACCESFAIL", 0x40, 0x40 }, - { "CIOPARERR", 0x80, 0x80 } -}; - -int -ahd_error_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(ERROR_parse_table, 7, "ERROR", - 0x04, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRERR_parse_table[] = { - { "CLRDSCTMOUT", 0x02, 0x02 }, - { "CLRILLOPCODE", 0x04, 0x04 }, - { "CLRSQPARERR", 0x08, 0x08 }, - { "CLRDPARERR", 0x10, 0x10 }, - { "CLRMPARERR", 0x20, 0x20 }, - { "CLRCIOACCESFAIL", 0x40, 0x40 }, - { "CLRCIOPARERR", 0x80, 0x80 } -}; - -int -ahd_clrerr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRERR_parse_table, 7, "CLRERR", - 0x04, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t HCNTRL_parse_table[] = { - { "CHIPRST", 0x01, 0x01 }, - { "CHIPRSTACK", 0x01, 0x01 }, - { "INTEN", 0x02, 0x02 }, - { "PAUSE", 0x04, 0x04 }, - { "SWTIMER_START_B", 0x08, 0x08 }, - { "SWINT", 0x10, 0x10 }, - { "POWRDN", 0x40, 0x40 }, - { "SEQ_RESET", 0x80, 0x80 } -}; - -int -ahd_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(HCNTRL_parse_table, 8, "HCNTRL", - 0x05, regvalue, cur_col, wrap)); -} - -int -ahd_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "HNSCB_QOFF", - 0x06, regvalue, cur_col, wrap)); -} - -int -ahd_hescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "HESCB_QOFF", - 0x08, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t HS_MAILBOX_parse_table[] = { - { "ENINT_COALESS", 0x40, 0x40 }, - { "HOST_TQINPOS", 0x80, 0x80 } -}; - -int -ahd_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(HS_MAILBOX_parse_table, 2, "HS_MAILBOX", - 0x0b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRSEQINTSTAT_parse_table[] = { - { "CLRSEQ_SPLTINT", 0x01, 0x01 }, - { "CLRSEQ_PCIINT", 0x02, 0x02 }, - { "CLRSEQ_SCSIINT", 0x04, 0x04 }, - { "CLRSEQ_SEQINT", 0x08, 0x08 }, - { "CLRSEQ_SWTMRTO", 0x10, 0x10 } -}; - -int -ahd_clrseqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRSEQINTSTAT_parse_table, 5, "CLRSEQINTSTAT", - 0x0c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQINTSTAT_parse_table[] = { - { "SEQ_SPLTINT", 0x01, 0x01 }, - { "SEQ_PCIINT", 0x02, 0x02 }, - { "SEQ_SCSIINT", 0x04, 0x04 }, - { "SEQ_SEQINT", 0x08, 0x08 }, - { "SEQ_SWTMRTO", 0x10, 0x10 } -}; - -int -ahd_seqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQINTSTAT_parse_table, 5, "SEQINTSTAT", - 0x0c, regvalue, cur_col, wrap)); -} - -int -ahd_swtimer_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SWTIMER", - 0x0e, regvalue, cur_col, wrap)); -} - -int -ahd_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SNSCB_QOFF", - 0x10, regvalue, cur_col, wrap)); -} - -int -ahd_sescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SESCB_QOFF", - 0x12, regvalue, cur_col, wrap)); -} - -int -ahd_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SDSCB_QOFF", - 0x14, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = { - { "SCB_QSIZE_4", 0x00, 0x0f }, - { "SCB_QSIZE_8", 0x01, 0x0f }, - { "SCB_QSIZE_16", 0x02, 0x0f }, - { "SCB_QSIZE_32", 0x03, 0x0f }, - { "SCB_QSIZE_64", 0x04, 0x0f }, - { "SCB_QSIZE_128", 0x05, 0x0f }, - { "SCB_QSIZE_256", 0x06, 0x0f }, - { "SCB_QSIZE_512", 0x07, 0x0f }, - { "SCB_QSIZE_1024", 0x08, 0x0f }, - { "SCB_QSIZE_2048", 0x09, 0x0f }, - { "SCB_QSIZE_4096", 0x0a, 0x0f }, - { "SCB_QSIZE_8192", 0x0b, 0x0f }, - { "SCB_QSIZE_16384", 0x0c, 0x0f }, - { "SCB_QSIZE", 0x0f, 0x0f }, - { "HS_MAILBOX_ACT", 0x10, 0x10 }, - { "SDSCB_ROLLOVR", 0x20, 0x20 }, - { "NEW_SCB_AVAIL", 0x40, 0x40 }, - { "EMPTY_SCB_AVAIL", 0x80, 0x80 } -}; - -int -ahd_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(QOFF_CTLSTA_parse_table, 18, "QOFF_CTLSTA", - 0x16, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t INTCTL_parse_table[] = { - { "SPLTINTEN", 0x01, 0x01 }, - { "SEQINTEN", 0x02, 0x02 }, - { "SCSIINTEN", 0x04, 0x04 }, - { "PCIINTEN", 0x08, 0x08 }, - { "AUTOCLRCMDINT", 0x10, 0x10 }, - { "SWTIMER_START", 0x20, 0x20 }, - { "SWTMINTEN", 0x40, 0x40 }, - { "SWTMINTMASK", 0x80, 0x80 } -}; - -int -ahd_intctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(INTCTL_parse_table, 8, "INTCTL", - 0x18, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DFCNTRL_parse_table[] = { - { "DIRECTIONEN", 0x01, 0x01 }, - { "FIFOFLUSH", 0x02, 0x02 }, - { "FIFOFLUSHACK", 0x02, 0x02 }, - { "DIRECTION", 0x04, 0x04 }, - { "DIRECTIONACK", 0x04, 0x04 }, - { "HDMAEN", 0x08, 0x08 }, - { "HDMAENACK", 0x08, 0x08 }, - { "SCSIEN", 0x20, 0x20 }, - { "SCSIENACK", 0x20, 0x20 }, - { "SCSIENWRDIS", 0x40, 0x40 }, - { "PRELOADEN", 0x80, 0x80 } -}; - -int -ahd_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DFCNTRL_parse_table, 11, "DFCNTRL", - 0x19, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DSCOMMAND0_parse_table[] = { - { "CIOPARCKEN", 0x01, 0x01 }, - { "DISABLE_TWATE", 0x02, 0x02 }, - { "EXTREQLCK", 0x10, 0x10 }, - { "MPARCKEN", 0x20, 0x20 }, - { "DPARCKEN", 0x40, 0x40 }, - { "CACHETHEN", 0x80, 0x80 } -}; - -int -ahd_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DSCOMMAND0_parse_table, 6, "DSCOMMAND0", - 0x19, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DFSTATUS_parse_table[] = { - { "FIFOEMP", 0x01, 0x01 }, - { "FIFOFULL", 0x02, 0x02 }, - { "DFTHRESH", 0x04, 0x04 }, - { "HDONE", 0x08, 0x08 }, - { "MREQPEND", 0x10, 0x10 }, - { "PKT_PRELOAD_AVAIL", 0x40, 0x40 }, - { "PRELOAD_AVAIL", 0x80, 0x80 } -}; - -int -ahd_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DFSTATUS_parse_table, 7, "DFSTATUS", - 0x1a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = { - { "LAST_SEG_DONE", 0x01, 0x01 }, - { "LAST_SEG", 0x02, 0x02 }, - { "ODD_SEG", 0x04, 0x04 }, - { "SG_ADDR_MASK", 0xf8, 0xf8 } -}; - -int -ahd_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SG_CACHE_SHADOW_parse_table, 4, "SG_CACHE_SHADOW", - 0x1b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t ARBCTL_parse_table[] = { - { "USE_TIME", 0x07, 0x07 }, - { "RETRY_SWEN", 0x08, 0x08 }, - { "RESET_HARB", 0x80, 0x80 } -}; - -int -ahd_arbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(ARBCTL_parse_table, 3, "ARBCTL", - 0x1b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = { - { "LAST_SEG", 0x02, 0x02 }, - { "ODD_SEG", 0x04, 0x04 }, - { "SG_ADDR_MASK", 0xf8, 0xf8 } -}; - -int -ahd_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE", - 0x1b, regvalue, cur_col, wrap)); -} - -int -ahd_lqin_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LQIN", - 0x20, regvalue, cur_col, wrap)); -} - -int -ahd_typeptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "TYPEPTR", - 0x20, regvalue, cur_col, wrap)); -} - -int -ahd_tagptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "TAGPTR", - 0x21, regvalue, cur_col, wrap)); -} - -int -ahd_lunptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LUNPTR", - 0x22, regvalue, cur_col, wrap)); -} - -int -ahd_datalenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DATALENPTR", - 0x23, regvalue, cur_col, wrap)); -} - -int -ahd_statlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "STATLENPTR", - 0x24, regvalue, cur_col, wrap)); -} - -int -ahd_cmdlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CMDLENPTR", - 0x25, regvalue, cur_col, wrap)); -} - -int -ahd_attrptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ATTRPTR", - 0x26, regvalue, cur_col, wrap)); -} - -int -ahd_flagptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "FLAGPTR", - 0x27, regvalue, cur_col, wrap)); -} - -int -ahd_cmdptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CMDPTR", - 0x28, regvalue, cur_col, wrap)); -} - -int -ahd_qnextptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "QNEXTPTR", - 0x29, regvalue, cur_col, wrap)); -} - -int -ahd_idptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "IDPTR", - 0x2a, regvalue, cur_col, wrap)); -} - -int -ahd_abrtbyteptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ABRTBYTEPTR", - 0x2b, regvalue, cur_col, wrap)); -} - -int -ahd_abrtbitptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ABRTBITPTR", - 0x2c, regvalue, cur_col, wrap)); -} - -int -ahd_maxcmdbytes_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "MAXCMDBYTES", - 0x2d, regvalue, cur_col, wrap)); -} - -int -ahd_maxcmd2rcv_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "MAXCMD2RCV", - 0x2e, regvalue, cur_col, wrap)); -} - -int -ahd_shortthresh_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SHORTTHRESH", - 0x2f, regvalue, cur_col, wrap)); -} - -int -ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LUNLEN", - 0x30, regvalue, cur_col, wrap)); -} - -int -ahd_cdblimit_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CDBLIMIT", - 0x31, regvalue, cur_col, wrap)); -} - -int -ahd_maxcmd_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "MAXCMD", - 0x32, regvalue, cur_col, wrap)); -} - -int -ahd_maxcmdcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "MAXCMDCNT", - 0x33, regvalue, cur_col, wrap)); -} - -int -ahd_lqrsvd01_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LQRSVD01", - 0x34, regvalue, cur_col, wrap)); -} - -int -ahd_lqrsvd16_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LQRSVD16", - 0x35, regvalue, cur_col, wrap)); -} - -int -ahd_lqrsvd17_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LQRSVD17", - 0x36, regvalue, cur_col, wrap)); -} - -int -ahd_cmdrsvd0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CMDRSVD0", - 0x37, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQCTL0_parse_table[] = { - { "LQ0INITGCLT", 0x03, 0x03 }, - { "LQ0TARGCLT", 0x0c, 0x0c }, - { "LQIINITGCLT", 0x30, 0x30 }, - { "LQITARGCLT", 0xc0, 0xc0 } -}; - -int -ahd_lqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQCTL0_parse_table, 4, "LQCTL0", - 0x38, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQCTL1_parse_table[] = { - { "ABORTPENDING", 0x01, 0x01 }, - { "SINGLECMD", 0x02, 0x02 }, - { "PCI2PCI", 0x04, 0x04 } -}; - -int -ahd_lqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQCTL1_parse_table, 3, "LQCTL1", - 0x38, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSBIST0_parse_table[] = { - { "OSBISTRUN", 0x01, 0x01 }, - { "OSBISTDONE", 0x02, 0x02 }, - { "OSBISTERR", 0x04, 0x04 }, - { "GSBISTRUN", 0x10, 0x10 }, - { "GSBISTDONE", 0x20, 0x20 }, - { "GSBISTERR", 0x40, 0x40 } -}; - -int -ahd_scsbist0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSBIST0_parse_table, 6, "SCSBIST0", - 0x39, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQCTL2_parse_table[] = { - { "LQOPAUSE", 0x01, 0x01 }, - { "LQOTOIDLE", 0x02, 0x02 }, - { "LQOCONTINUE", 0x04, 0x04 }, - { "LQORETRY", 0x08, 0x08 }, - { "LQIPAUSE", 0x10, 0x10 }, - { "LQITOIDLE", 0x20, 0x20 }, - { "LQICONTINUE", 0x40, 0x40 }, - { "LQIRETRY", 0x80, 0x80 } -}; - -int -ahd_lqctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQCTL2_parse_table, 8, "LQCTL2", - 0x39, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSBIST1_parse_table[] = { - { "NTBISTRUN", 0x01, 0x01 }, - { "NTBISTDONE", 0x02, 0x02 }, - { "NTBISTERR", 0x04, 0x04 } -}; - -int -ahd_scsbist1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSBIST1_parse_table, 3, "SCSBIST1", - 0x3a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSISEQ0_parse_table[] = { - { "SCSIRSTO", 0x01, 0x01 }, - { "FORCEBUSFREE", 0x10, 0x10 }, - { "ENARBO", 0x20, 0x20 }, - { "ENSELO", 0x40, 0x40 }, - { "TEMODEO", 0x80, 0x80 } -}; - -int -ahd_scsiseq0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSISEQ0_parse_table, 5, "SCSISEQ0", - 0x3a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSISEQ1_parse_table[] = { - { "ALTSTIM", 0x01, 0x01 }, - { "ENAUTOATNP", 0x02, 0x02 }, - { "MANUALP", 0x0c, 0x0c }, - { "ENRSELI", 0x10, 0x10 }, - { "ENSELI", 0x20, 0x20 }, - { "MANUALCTL", 0x40, 0x40 } -}; - -int -ahd_scsiseq1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSISEQ1_parse_table, 6, "SCSISEQ1", - 0x3b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SXFRCTL0_parse_table[] = { - { "SPIOEN", 0x08, 0x08 }, - { "BIOSCANCELEN", 0x10, 0x10 }, - { "DFPEXP", 0x40, 0x40 }, - { "DFON", 0x80, 0x80 } -}; - -int -ahd_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SXFRCTL0_parse_table, 4, "SXFRCTL0", - 0x3c, regvalue, cur_col, wrap)); -} - -int -ahd_businitid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "BUSINITID", - 0x3c, regvalue, cur_col, wrap)); -} - -int -ahd_dlcount_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DLCOUNT", - 0x3c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SXFRCTL1_parse_table[] = { - { "STPWEN", 0x01, 0x01 }, - { "ACTNEGEN", 0x02, 0x02 }, - { "ENSTIMER", 0x04, 0x04 }, - { "STIMESEL", 0x18, 0x18 }, - { "ENSPCHK", 0x20, 0x20 }, - { "ENSACHK", 0x40, 0x40 }, - { "BITBUCKET", 0x80, 0x80 } -}; - -int -ahd_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1", - 0x3d, regvalue, cur_col, wrap)); -} - -int -ahd_bustargid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "BUSTARGID", - 0x3e, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SXFRCTL2_parse_table[] = { - { "ASU", 0x07, 0x07 }, - { "CMDDMAEN", 0x08, 0x08 }, - { "AUTORSTDIS", 0x10, 0x10 } -}; - -int -ahd_sxfrctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SXFRCTL2_parse_table, 3, "SXFRCTL2", - 0x3e, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DFFSTAT_parse_table[] = { - { "CURRFIFO_0", 0x00, 0x03 }, - { "CURRFIFO_1", 0x01, 0x03 }, - { "CURRFIFO_NONE", 0x03, 0x03 }, - { "FIFO0FREE", 0x10, 0x10 }, - { "FIFO1FREE", 0x20, 0x20 }, - { "CURRFIFO", 0x03, 0x03 } -}; - -int -ahd_dffstat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DFFSTAT_parse_table, 6, "DFFSTAT", - 0x3f, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSISIGO_parse_table[] = { - { "P_DATAOUT", 0x00, 0xe0 }, - { "P_DATAOUT_DT", 0x20, 0xe0 }, - { "P_DATAIN", 0x40, 0xe0 }, - { "P_DATAIN_DT", 0x60, 0xe0 }, - { "P_COMMAND", 0x80, 0xe0 }, - { "P_MESGOUT", 0xa0, 0xe0 }, - { "P_STATUS", 0xc0, 0xe0 }, - { "P_MESGIN", 0xe0, 0xe0 }, - { "ACKO", 0x01, 0x01 }, - { "REQO", 0x02, 0x02 }, - { "BSYO", 0x04, 0x04 }, - { "SELO", 0x08, 0x08 }, - { "ATNO", 0x10, 0x10 }, - { "MSGO", 0x20, 0x20 }, - { "IOO", 0x40, 0x40 }, - { "CDO", 0x80, 0x80 }, - { "PHASE_MASK", 0xe0, 0xe0 } -}; - -int -ahd_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSISIGO_parse_table, 17, "SCSISIGO", - 0x40, regvalue, cur_col, wrap)); -} - -int -ahd_multargid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "MULTARGID", - 0x40, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSISIGI_parse_table[] = { - { "P_DATAOUT", 0x00, 0xe0 }, - { "P_DATAOUT_DT", 0x20, 0xe0 }, - { "P_DATAIN", 0x40, 0xe0 }, - { "P_DATAIN_DT", 0x60, 0xe0 }, - { "P_COMMAND", 0x80, 0xe0 }, - { "P_MESGOUT", 0xa0, 0xe0 }, - { "P_STATUS", 0xc0, 0xe0 }, - { "P_MESGIN", 0xe0, 0xe0 }, - { "ACKI", 0x01, 0x01 }, - { "REQI", 0x02, 0x02 }, - { "BSYI", 0x04, 0x04 }, - { "SELI", 0x08, 0x08 }, - { "ATNI", 0x10, 0x10 }, - { "MSGI", 0x20, 0x20 }, - { "IOI", 0x40, 0x40 }, - { "CDI", 0x80, 0x80 }, - { "PHASE_MASK", 0xe0, 0xe0 } -}; - -int -ahd_scsisigi_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSISIGI_parse_table, 17, "SCSISIGI", - 0x41, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSIPHASE_parse_table[] = { - { "DATA_OUT_PHASE", 0x01, 0x03 }, - { "DATA_IN_PHASE", 0x02, 0x03 }, - { "DATA_PHASE_MASK", 0x03, 0x03 }, - { "MSG_OUT_PHASE", 0x04, 0x04 }, - { "MSG_IN_PHASE", 0x08, 0x08 }, - { "COMMAND_PHASE", 0x10, 0x10 }, - { "STATUS_PHASE", 0x20, 0x20 } -}; - -int -ahd_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE", - 0x42, regvalue, cur_col, wrap)); -} - -int -ahd_scsidat0_img_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCSIDAT0_IMG", - 0x43, regvalue, cur_col, wrap)); -} - -int -ahd_scsidat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCSIDAT", - 0x44, regvalue, cur_col, wrap)); -} - -int -ahd_scsibus_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCSIBUS", - 0x46, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t TARGIDIN_parse_table[] = { - { "TARGID", 0x0f, 0x0f }, - { "CLKOUT", 0x80, 0x80 } -}; - -int -ahd_targidin_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(TARGIDIN_parse_table, 2, "TARGIDIN", - 0x48, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SELID_parse_table[] = { - { "ONEBIT", 0x08, 0x08 }, - { "SELID_MASK", 0xf0, 0xf0 } -}; - -int -ahd_selid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SELID_parse_table, 2, "SELID", - 0x49, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SBLKCTL_parse_table[] = { - { "SELWIDE", 0x02, 0x02 }, - { "ENAB20", 0x04, 0x04 }, - { "ENAB40", 0x08, 0x08 }, - { "DIAGLEDON", 0x40, 0x40 }, - { "DIAGLEDEN", 0x80, 0x80 } -}; - -int -ahd_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL", - 0x4a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OPTIONMODE_parse_table[] = { - { "AUTO_MSGOUT_DE", 0x02, 0x02 }, - { "ENDGFORMCHK", 0x04, 0x04 }, - { "BUSFREEREV", 0x10, 0x10 }, - { "BIASCANCTL", 0x20, 0x20 }, - { "AUTOACKEN", 0x40, 0x40 }, - { "BIOSCANCTL", 0x80, 0x80 }, - { "OPTIONMODE_DEFAULTS",0x02, 0x02 } -}; - -int -ahd_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OPTIONMODE_parse_table, 7, "OPTIONMODE", - 0x4a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SSTAT0_parse_table[] = { - { "ARBDO", 0x01, 0x01 }, - { "SPIORDY", 0x02, 0x02 }, - { "OVERRUN", 0x04, 0x04 }, - { "IOERR", 0x08, 0x08 }, - { "SELINGO", 0x10, 0x10 }, - { "SELDI", 0x20, 0x20 }, - { "SELDO", 0x40, 0x40 }, - { "TARGET", 0x80, 0x80 } -}; - -int -ahd_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SSTAT0_parse_table, 8, "SSTAT0", - 0x4b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRSINT0_parse_table[] = { - { "CLRARBDO", 0x01, 0x01 }, - { "CLRSPIORDY", 0x02, 0x02 }, - { "CLROVERRUN", 0x04, 0x04 }, - { "CLRIOERR", 0x08, 0x08 }, - { "CLRSELINGO", 0x10, 0x10 }, - { "CLRSELDI", 0x20, 0x20 }, - { "CLRSELDO", 0x40, 0x40 } -}; - -int -ahd_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRSINT0_parse_table, 7, "CLRSINT0", - 0x4b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SIMODE0_parse_table[] = { - { "ENARBDO", 0x01, 0x01 }, - { "ENSPIORDY", 0x02, 0x02 }, - { "ENOVERRUN", 0x04, 0x04 }, - { "ENIOERR", 0x08, 0x08 }, - { "ENSELINGO", 0x10, 0x10 }, - { "ENSELDI", 0x20, 0x20 }, - { "ENSELDO", 0x40, 0x40 } -}; - -int -ahd_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SIMODE0_parse_table, 7, "SIMODE0", - 0x4b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRSINT1_parse_table[] = { - { "CLRREQINIT", 0x01, 0x01 }, - { "CLRSTRB2FAST", 0x02, 0x02 }, - { "CLRSCSIPERR", 0x04, 0x04 }, - { "CLRBUSFREE", 0x08, 0x08 }, - { "CLRSCSIRSTI", 0x20, 0x20 }, - { "CLRATNO", 0x40, 0x40 }, - { "CLRSELTIMEO", 0x80, 0x80 } -}; - -int -ahd_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRSINT1_parse_table, 7, "CLRSINT1", - 0x4c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SSTAT1_parse_table[] = { - { "REQINIT", 0x01, 0x01 }, - { "STRB2FAST", 0x02, 0x02 }, - { "SCSIPERR", 0x04, 0x04 }, - { "BUSFREE", 0x08, 0x08 }, - { "PHASEMIS", 0x10, 0x10 }, - { "SCSIRSTI", 0x20, 0x20 }, - { "ATNTARG", 0x40, 0x40 }, - { "SELTO", 0x80, 0x80 } -}; - -int -ahd_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SSTAT1_parse_table, 8, "SSTAT1", - 0x4c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SSTAT2_parse_table[] = { - { "BUSFREE_LQO", 0x40, 0xc0 }, - { "BUSFREE_DFF0", 0x80, 0xc0 }, - { "BUSFREE_DFF1", 0xc0, 0xc0 }, - { "DMADONE", 0x01, 0x01 }, - { "SDONE", 0x02, 0x02 }, - { "WIDE_RES", 0x04, 0x04 }, - { "BSYX", 0x08, 0x08 }, - { "EXP_ACTIVE", 0x10, 0x10 }, - { "NONPACKREQ", 0x20, 0x20 }, - { "BUSFREETIME", 0xc0, 0xc0 } -}; - -int -ahd_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SSTAT2_parse_table, 10, "SSTAT2", - 0x4d, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRSINT2_parse_table[] = { - { "CLRDMADONE", 0x01, 0x01 }, - { "CLRSDONE", 0x02, 0x02 }, - { "CLRWIDE_RES", 0x04, 0x04 }, - { "CLRNONPACKREQ", 0x20, 0x20 } -}; - -int -ahd_clrsint2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRSINT2_parse_table, 4, "CLRSINT2", - 0x4d, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SIMODE2_parse_table[] = { - { "ENDMADONE", 0x01, 0x01 }, - { "ENSDONE", 0x02, 0x02 }, - { "ENWIDE_RES", 0x04, 0x04 } -}; - -int -ahd_simode2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SIMODE2_parse_table, 3, "SIMODE2", - 0x4d, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t PERRDIAG_parse_table[] = { - { "DTERR", 0x01, 0x01 }, - { "DGFORMERR", 0x02, 0x02 }, - { "CRCERR", 0x04, 0x04 }, - { "AIPERR", 0x08, 0x08 }, - { "PARITYERR", 0x10, 0x10 }, - { "PREVPHASE", 0x20, 0x20 }, - { "HIPERR", 0x40, 0x40 }, - { "HIZERO", 0x80, 0x80 } -}; - -int -ahd_perrdiag_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(PERRDIAG_parse_table, 8, "PERRDIAG", - 0x4e, regvalue, cur_col, wrap)); -} - -int -ahd_lqistate_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LQISTATE", - 0x4e, regvalue, cur_col, wrap)); -} - -int -ahd_soffcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SOFFCNT", - 0x4f, regvalue, cur_col, wrap)); -} - -int -ahd_lqostate_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LQOSTATE", - 0x4f, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQISTAT0_parse_table[] = { - { "LQIATNCMD", 0x01, 0x01 }, - { "LQIATNLQ", 0x02, 0x02 }, - { "LQIBADLQT", 0x04, 0x04 }, - { "LQICRCT2", 0x08, 0x08 }, - { "LQICRCT1", 0x10, 0x10 }, - { "LQIATNQAS", 0x20, 0x20 } -}; - -int -ahd_lqistat0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQISTAT0_parse_table, 6, "LQISTAT0", - 0x50, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRLQIINT0_parse_table[] = { - { "CLRLQIATNCMD", 0x01, 0x01 }, - { "CLRLQIATNLQ", 0x02, 0x02 }, - { "CLRLQIBADLQT", 0x04, 0x04 }, - { "CLRLQICRCT2", 0x08, 0x08 }, - { "CLRLQICRCT1", 0x10, 0x10 }, - { "CLRLQIATNQAS", 0x20, 0x20 } -}; - -int -ahd_clrlqiint0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRLQIINT0_parse_table, 6, "CLRLQIINT0", - 0x50, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQIMODE0_parse_table[] = { - { "ENLQIATNCMD", 0x01, 0x01 }, - { "ENLQIATNLQ", 0x02, 0x02 }, - { "ENLQIBADLQT", 0x04, 0x04 }, - { "ENLQICRCT2", 0x08, 0x08 }, - { "ENLQICRCT1", 0x10, 0x10 }, - { "ENLQIATNQASK", 0x20, 0x20 } -}; - -int -ahd_lqimode0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQIMODE0_parse_table, 6, "LQIMODE0", - 0x50, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQIMODE1_parse_table[] = { - { "ENLQIOVERI_NLQ", 0x01, 0x01 }, - { "ENLQIOVERI_LQ", 0x02, 0x02 }, - { "ENLQIBADLQI", 0x04, 0x04 }, - { "ENLQICRCI_NLQ", 0x08, 0x08 }, - { "ENLQICRCI_LQ", 0x10, 0x10 }, - { "ENLIQABORT", 0x20, 0x20 }, - { "ENLQIPHASE_NLQ", 0x40, 0x40 }, - { "ENLQIPHASE_LQ", 0x80, 0x80 } -}; - -int -ahd_lqimode1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQIMODE1_parse_table, 8, "LQIMODE1", - 0x51, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQISTAT1_parse_table[] = { - { "LQIOVERI_NLQ", 0x01, 0x01 }, - { "LQIOVERI_LQ", 0x02, 0x02 }, - { "LQIBADLQI", 0x04, 0x04 }, - { "LQICRCI_NLQ", 0x08, 0x08 }, - { "LQICRCI_LQ", 0x10, 0x10 }, - { "LQIABORT", 0x20, 0x20 }, - { "LQIPHASE_NLQ", 0x40, 0x40 }, - { "LQIPHASE_LQ", 0x80, 0x80 } -}; - -int -ahd_lqistat1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQISTAT1_parse_table, 8, "LQISTAT1", - 0x51, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRLQIINT1_parse_table[] = { - { "CLRLQIOVERI_NLQ", 0x01, 0x01 }, - { "CLRLQIOVERI_LQ", 0x02, 0x02 }, - { "CLRLQIBADLQI", 0x04, 0x04 }, - { "CLRLQICRCI_NLQ", 0x08, 0x08 }, - { "CLRLQICRCI_LQ", 0x10, 0x10 }, - { "CLRLIQABORT", 0x20, 0x20 }, - { "CLRLQIPHASE_NLQ", 0x40, 0x40 }, - { "CLRLQIPHASE_LQ", 0x80, 0x80 } -}; - -int -ahd_clrlqiint1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRLQIINT1_parse_table, 8, "CLRLQIINT1", - 0x51, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQISTAT2_parse_table[] = { - { "LQIGSAVAIL", 0x01, 0x01 }, - { "LQISTOPCMD", 0x02, 0x02 }, - { "LQISTOPLQ", 0x04, 0x04 }, - { "LQISTOPPKT", 0x08, 0x08 }, - { "LQIWAITFIFO", 0x10, 0x10 }, - { "LQIWORKONLQ", 0x20, 0x20 }, - { "LQIPHASE_OUTPKT", 0x40, 0x40 }, - { "PACKETIZED", 0x80, 0x80 } -}; - -int -ahd_lqistat2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQISTAT2_parse_table, 8, "LQISTAT2", - 0x52, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SSTAT3_parse_table[] = { - { "OSRAMPERR", 0x01, 0x01 }, - { "NTRAMPERR", 0x02, 0x02 } -}; - -int -ahd_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SSTAT3_parse_table, 2, "SSTAT3", - 0x53, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SIMODE3_parse_table[] = { - { "ENOSRAMPERR", 0x01, 0x01 }, - { "ENNTRAMPERR", 0x02, 0x02 } -}; - -int -ahd_simode3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SIMODE3_parse_table, 2, "SIMODE3", - 0x53, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRSINT3_parse_table[] = { - { "CLROSRAMPERR", 0x01, 0x01 }, - { "CLRNTRAMPERR", 0x02, 0x02 } -}; - -int -ahd_clrsint3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRSINT3_parse_table, 2, "CLRSINT3", - 0x53, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQOMODE0_parse_table[] = { - { "ENLQOTCRC", 0x01, 0x01 }, - { "ENLQOATNPKT", 0x02, 0x02 }, - { "ENLQOATNLQ", 0x04, 0x04 }, - { "ENLQOSTOPT2", 0x08, 0x08 }, - { "ENLQOTARGSCBPERR", 0x10, 0x10 } -}; - -int -ahd_lqomode0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQOMODE0_parse_table, 5, "LQOMODE0", - 0x54, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQOSTAT0_parse_table[] = { - { "LQOTCRC", 0x01, 0x01 }, - { "LQOATNPKT", 0x02, 0x02 }, - { "LQOATNLQ", 0x04, 0x04 }, - { "LQOSTOPT2", 0x08, 0x08 }, - { "LQOTARGSCBPERR", 0x10, 0x10 } -}; - -int -ahd_lqostat0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQOSTAT0_parse_table, 5, "LQOSTAT0", - 0x54, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRLQOINT0_parse_table[] = { - { "CLRLQOTCRC", 0x01, 0x01 }, - { "CLRLQOATNPKT", 0x02, 0x02 }, - { "CLRLQOATNLQ", 0x04, 0x04 }, - { "CLRLQOSTOPT2", 0x08, 0x08 }, - { "CLRLQOTARGSCBPERR", 0x10, 0x10 } -}; - -int -ahd_clrlqoint0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRLQOINT0_parse_table, 5, "CLRLQOINT0", - 0x54, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQOSTAT1_parse_table[] = { - { "LQOPHACHGINPKT", 0x01, 0x01 }, - { "LQOBUSFREE", 0x02, 0x02 }, - { "LQOBADQAS", 0x04, 0x04 }, - { "LQOSTOPI2", 0x08, 0x08 }, - { "LQOINITSCBPERR", 0x10, 0x10 } -}; - -int -ahd_lqostat1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQOSTAT1_parse_table, 5, "LQOSTAT1", - 0x55, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRLQOINT1_parse_table[] = { - { "CLRLQOPHACHGINPKT", 0x01, 0x01 }, - { "CLRLQOBUSFREE", 0x02, 0x02 }, - { "CLRLQOBADQAS", 0x04, 0x04 }, - { "CLRLQOSTOPI2", 0x08, 0x08 }, - { "CLRLQOINITSCBPERR", 0x10, 0x10 } -}; - -int -ahd_clrlqoint1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRLQOINT1_parse_table, 5, "CLRLQOINT1", - 0x55, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQOMODE1_parse_table[] = { - { "ENLQOPHACHGINPKT", 0x01, 0x01 }, - { "ENLQOBUSFREE", 0x02, 0x02 }, - { "ENLQOBADQAS", 0x04, 0x04 }, - { "ENLQOSTOPI2", 0x08, 0x08 }, - { "ENLQOINITSCBPERR", 0x10, 0x10 } -}; - -int -ahd_lqomode1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQOMODE1_parse_table, 5, "LQOMODE1", - 0x55, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQOSTAT2_parse_table[] = { - { "LQOSTOP0", 0x01, 0x01 }, - { "LQOPHACHGOUTPKT", 0x02, 0x02 }, - { "LQOWAITFIFO", 0x10, 0x10 }, - { "LQOPKT", 0xe0, 0xe0 } -}; - -int -ahd_lqostat2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQOSTAT2_parse_table, 4, "LQOSTAT2", - 0x56, regvalue, cur_col, wrap)); -} - -int -ahd_os_space_cnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "OS_SPACE_CNT", - 0x56, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SIMODE1_parse_table[] = { - { "ENREQINIT", 0x01, 0x01 }, - { "ENSTRB2FAST", 0x02, 0x02 }, - { "ENSCSIPERR", 0x04, 0x04 }, - { "ENBUSFREE", 0x08, 0x08 }, - { "ENPHASEMIS", 0x10, 0x10 }, - { "ENSCSIRST", 0x20, 0x20 }, - { "ENATNTARG", 0x40, 0x40 }, - { "ENSELTIMO", 0x80, 0x80 } -}; - -int -ahd_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SIMODE1_parse_table, 8, "SIMODE1", - 0x57, regvalue, cur_col, wrap)); -} - -int -ahd_gsfifo_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "GSFIFO", - 0x58, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DFFSXFRCTL_parse_table[] = { - { "RSTCHN", 0x01, 0x01 }, - { "CLRCHN", 0x02, 0x02 }, - { "CLRSHCNT", 0x04, 0x04 }, - { "DFFBITBUCKET", 0x08, 0x08 } -}; - -int -ahd_dffsxfrctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DFFSXFRCTL_parse_table, 4, "DFFSXFRCTL", - 0x5a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LQOSCSCTL_parse_table[] = { - { "LQONOCHKOVER", 0x01, 0x01 }, - { "LQOH2A_VERSION", 0x80, 0x80 } -}; - -int -ahd_lqoscsctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LQOSCSCTL_parse_table, 2, "LQOSCSCTL", - 0x5a, regvalue, cur_col, wrap)); -} - -int -ahd_nextscb_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "NEXTSCB", - 0x5a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CLRSEQINTSRC_parse_table[] = { - { "CLRCFG4TCMD", 0x01, 0x01 }, - { "CLRCFG4ICMD", 0x02, 0x02 }, - { "CLRCFG4TSTAT", 0x04, 0x04 }, - { "CLRCFG4ISTAT", 0x08, 0x08 }, - { "CLRCFG4DATA", 0x10, 0x10 }, - { "CLRSAVEPTRS", 0x20, 0x20 }, - { "CLRCTXTDONE", 0x40, 0x40 } -}; - -int -ahd_clrseqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CLRSEQINTSRC_parse_table, 7, "CLRSEQINTSRC", - 0x5b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQINTSRC_parse_table[] = { - { "CFG4TCMD", 0x01, 0x01 }, - { "CFG4ICMD", 0x02, 0x02 }, - { "CFG4TSTAT", 0x04, 0x04 }, - { "CFG4ISTAT", 0x08, 0x08 }, - { "CFG4DATA", 0x10, 0x10 }, - { "SAVEPTRS", 0x20, 0x20 }, - { "CTXTDONE", 0x40, 0x40 } -}; - -int -ahd_seqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQINTSRC_parse_table, 7, "SEQINTSRC", - 0x5b, regvalue, cur_col, wrap)); -} - -int -ahd_currscb_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CURRSCB", - 0x5c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQIMODE_parse_table[] = { - { "ENCFG4TCMD", 0x01, 0x01 }, - { "ENCFG4ICMD", 0x02, 0x02 }, - { "ENCFG4TSTAT", 0x04, 0x04 }, - { "ENCFG4ISTAT", 0x08, 0x08 }, - { "ENCFG4DATA", 0x10, 0x10 }, - { "ENSAVEPTRS", 0x20, 0x20 }, - { "ENCTXTDONE", 0x40, 0x40 } -}; - -int -ahd_seqimode_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQIMODE_parse_table, 7, "SEQIMODE", - 0x5c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t MDFFSTAT_parse_table[] = { - { "FIFOFREE", 0x01, 0x01 }, - { "DATAINFIFO", 0x02, 0x02 }, - { "DLZERO", 0x04, 0x04 }, - { "SHVALID", 0x08, 0x08 }, - { "LASTSDONE", 0x10, 0x10 }, - { "SHCNTMINUS1", 0x20, 0x20 }, - { "SHCNTNEGATIVE", 0x40, 0x40 } -}; - -int -ahd_mdffstat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(MDFFSTAT_parse_table, 7, "MDFFSTAT", - 0x5d, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CRCCONTROL_parse_table[] = { - { "CRCVALCHKEN", 0x40, 0x40 } -}; - -int -ahd_crccontrol_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CRCCONTROL_parse_table, 1, "CRCCONTROL", - 0x5d, regvalue, cur_col, wrap)); -} - -int -ahd_dfftag_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFFTAG", - 0x5e, regvalue, cur_col, wrap)); -} - -int -ahd_lastscb_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LASTSCB", - 0x5e, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSITEST_parse_table[] = { - { "SEL_TXPLL_DEBUG", 0x04, 0x04 }, - { "CNTRTEST", 0x08, 0x08 } -}; - -int -ahd_scsitest_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSITEST_parse_table, 2, "SCSITEST", - 0x5e, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t IOPDNCTL_parse_table[] = { - { "PDN_DIFFSENSE", 0x01, 0x01 }, - { "PDN_IDIST", 0x04, 0x04 }, - { "DISABLE_OE", 0x80, 0x80 } -}; - -int -ahd_iopdnctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(IOPDNCTL_parse_table, 3, "IOPDNCTL", - 0x5f, regvalue, cur_col, wrap)); -} - -int -ahd_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SHADDR", - 0x60, regvalue, cur_col, wrap)); -} - -int -ahd_negoaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "NEGOADDR", - 0x60, regvalue, cur_col, wrap)); -} - -int -ahd_dgrpcrci_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DGRPCRCI", - 0x60, regvalue, cur_col, wrap)); -} - -int -ahd_negperiod_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "NEGPERIOD", - 0x61, regvalue, cur_col, wrap)); -} - -int -ahd_packcrci_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "PACKCRCI", - 0x62, regvalue, cur_col, wrap)); -} - -int -ahd_negoffset_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "NEGOFFSET", - 0x62, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t NEGPPROPTS_parse_table[] = { - { "PPROPT_IUT", 0x01, 0x01 }, - { "PPROPT_DT", 0x02, 0x02 }, - { "PPROPT_QAS", 0x04, 0x04 }, - { "PPROPT_PACE", 0x08, 0x08 } -}; - -int -ahd_negppropts_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NEGPPROPTS_parse_table, 4, "NEGPPROPTS", - 0x63, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t NEGCONOPTS_parse_table[] = { - { "WIDEXFER", 0x01, 0x01 }, - { "ENAUTOATNO", 0x02, 0x02 }, - { "ENAUTOATNI", 0x04, 0x04 }, - { "ENSLOWCRC", 0x08, 0x08 }, - { "RTI_OVRDTRN", 0x10, 0x10 }, - { "RTI_WRTDIS", 0x20, 0x20 }, - { "ENSNAPSHOT", 0x40, 0x40 } -}; - -int -ahd_negconopts_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NEGCONOPTS_parse_table, 7, "NEGCONOPTS", - 0x64, regvalue, cur_col, wrap)); -} - -int -ahd_annexcol_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ANNEXCOL", - 0x65, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSCHKN_parse_table[] = { - { "LSTSGCLRDIS", 0x01, 0x01 }, - { "SHVALIDSTDIS", 0x02, 0x02 }, - { "DFFACTCLR", 0x04, 0x04 }, - { "SDONEMSKDIS", 0x08, 0x08 }, - { "WIDERESEN", 0x10, 0x10 }, - { "CURRFIFODEF", 0x20, 0x20 }, - { "STSELSKIDDIS", 0x40, 0x40 } -}; - -int -ahd_scschkn_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSCHKN_parse_table, 7, "SCSCHKN", - 0x66, regvalue, cur_col, wrap)); -} - -int -ahd_annexdat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ANNEXDAT", - 0x66, regvalue, cur_col, wrap)); -} - -int -ahd_iownid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "IOWNID", - 0x67, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t PLL960CTL0_parse_table[] = { - { "PLL_ENFBM", 0x01, 0x01 }, - { "PLL_DLPF", 0x02, 0x02 }, - { "PLL_ENLPF", 0x04, 0x04 }, - { "PLL_ENLUD", 0x08, 0x08 }, - { "PLL_NS", 0x30, 0x30 }, - { "PLL_PWDN", 0x40, 0x40 }, - { "PLL_VCOSEL", 0x80, 0x80 } -}; - -int -ahd_pll960ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(PLL960CTL0_parse_table, 7, "PLL960CTL0", - 0x68, regvalue, cur_col, wrap)); -} - -int -ahd_shcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SHCNT", - 0x68, regvalue, cur_col, wrap)); -} - -int -ahd_townid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "TOWNID", - 0x69, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t PLL960CTL1_parse_table[] = { - { "PLL_RST", 0x01, 0x01 }, - { "PLL_CNTCLR", 0x40, 0x40 }, - { "PLL_CNTEN", 0x80, 0x80 } -}; - -int -ahd_pll960ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(PLL960CTL1_parse_table, 3, "PLL960CTL1", - 0x69, regvalue, cur_col, wrap)); -} - -int -ahd_pll960cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "PLL960CNT0", - 0x6a, regvalue, cur_col, wrap)); -} - -int -ahd_xsig_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "XSIG", - 0x6a, regvalue, cur_col, wrap)); -} - -int -ahd_seloid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SELOID", - 0x6b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t PLL400CTL0_parse_table[] = { - { "PLL_ENFBM", 0x01, 0x01 }, - { "PLL_DLPF", 0x02, 0x02 }, - { "PLL_ENLPF", 0x04, 0x04 }, - { "PLL_ENLUD", 0x08, 0x08 }, - { "PLL_NS", 0x30, 0x30 }, - { "PLL_PWDN", 0x40, 0x40 }, - { "PLL_VCOSEL", 0x80, 0x80 } -}; - -int -ahd_pll400ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(PLL400CTL0_parse_table, 7, "PLL400CTL0", - 0x6c, regvalue, cur_col, wrap)); -} - -int -ahd_fairness_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "FAIRNESS", - 0x6c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t PLL400CTL1_parse_table[] = { - { "PLL_RST", 0x01, 0x01 }, - { "PLL_CNTCLR", 0x40, 0x40 }, - { "PLL_CNTEN", 0x80, 0x80 } -}; - -int -ahd_pll400ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(PLL400CTL1_parse_table, 3, "PLL400CTL1", - 0x6d, regvalue, cur_col, wrap)); -} - -int -ahd_pll400cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "PLL400CNT0", - 0x6e, regvalue, cur_col, wrap)); -} - -int -ahd_unfairness_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "UNFAIRNESS", - 0x6e, regvalue, cur_col, wrap)); -} - -int -ahd_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "HADDR", - 0x70, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t PLLDELAY_parse_table[] = { - { "SPLIT_DROP_REQ", 0x80, 0x80 } -}; - -int -ahd_plldelay_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(PLLDELAY_parse_table, 1, "PLLDELAY", - 0x70, regvalue, cur_col, wrap)); -} - -int -ahd_hodmaadr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "HODMAADR", - 0x70, regvalue, cur_col, wrap)); -} - -int -ahd_hodmacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "HODMACNT", - 0x78, regvalue, cur_col, wrap)); -} - -int -ahd_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "HCNT", - 0x78, regvalue, cur_col, wrap)); -} - -int -ahd_hodmaen_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "HODMAEN", - 0x7a, regvalue, cur_col, wrap)); -} - -int -ahd_sghaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SGHADDR", - 0x7c, regvalue, cur_col, wrap)); -} - -int -ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCBHADDR", - 0x7c, regvalue, cur_col, wrap)); -} - -int -ahd_sghcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SGHCNT", - 0x84, regvalue, cur_col, wrap)); -} - -int -ahd_scbhcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCBHCNT", - 0x84, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DFF_THRSH_parse_table[] = { - { "WR_DFTHRSH_MIN", 0x00, 0x70 }, - { "RD_DFTHRSH_MIN", 0x00, 0x07 }, - { "RD_DFTHRSH_25", 0x01, 0x07 }, - { "RD_DFTHRSH_50", 0x02, 0x07 }, - { "RD_DFTHRSH_63", 0x03, 0x07 }, - { "RD_DFTHRSH_75", 0x04, 0x07 }, - { "RD_DFTHRSH_85", 0x05, 0x07 }, - { "RD_DFTHRSH_90", 0x06, 0x07 }, - { "RD_DFTHRSH_MAX", 0x07, 0x07 }, - { "WR_DFTHRSH_25", 0x10, 0x70 }, - { "WR_DFTHRSH_50", 0x20, 0x70 }, - { "WR_DFTHRSH_63", 0x30, 0x70 }, - { "WR_DFTHRSH_75", 0x40, 0x70 }, - { "WR_DFTHRSH_85", 0x50, 0x70 }, - { "WR_DFTHRSH_90", 0x60, 0x70 }, - { "WR_DFTHRSH_MAX", 0x70, 0x70 }, - { "RD_DFTHRSH", 0x07, 0x07 }, - { "WR_DFTHRSH", 0x70, 0x70 } -}; - -int -ahd_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH", - 0x88, regvalue, cur_col, wrap)); -} - -int -ahd_romaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ROMADDR", - 0x8a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t ROMCNTRL_parse_table[] = { - { "RDY", 0x01, 0x01 }, - { "REPEAT", 0x02, 0x02 }, - { "ROMSPD", 0x18, 0x18 }, - { "ROMOP", 0xe0, 0xe0 } -}; - -int -ahd_romcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(ROMCNTRL_parse_table, 4, "ROMCNTRL", - 0x8d, regvalue, cur_col, wrap)); -} - -int -ahd_romdata_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ROMDATA", - 0x8e, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMCRXMSG0_parse_table[] = { - { "CFNUM", 0x07, 0x07 }, - { "CDNUM", 0xf8, 0xf8 } -}; - -int -ahd_cmcrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMCRXMSG0_parse_table, 2, "CMCRXMSG0", - 0x90, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t ROENABLE_parse_table[] = { - { "DCH0ROEN", 0x01, 0x01 }, - { "DCH1ROEN", 0x02, 0x02 }, - { "SGROEN", 0x04, 0x04 }, - { "CMCROEN", 0x08, 0x08 }, - { "OVLYROEN", 0x10, 0x10 }, - { "MSIROEN", 0x20, 0x20 } -}; - -int -ahd_roenable_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(ROENABLE_parse_table, 6, "ROENABLE", - 0x90, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OVLYRXMSG0_parse_table[] = { - { "CFNUM", 0x07, 0x07 }, - { "CDNUM", 0xf8, 0xf8 } -}; - -int -ahd_ovlyrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OVLYRXMSG0_parse_table, 2, "OVLYRXMSG0", - 0x90, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DCHRXMSG0_parse_table[] = { - { "CFNUM", 0x07, 0x07 }, - { "CDNUM", 0xf8, 0xf8 } -}; - -int -ahd_dchrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DCHRXMSG0_parse_table, 2, "DCHRXMSG0", - 0x90, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OVLYRXMSG1_parse_table[] = { - { "CBNUM", 0xff, 0xff } -}; - -int -ahd_ovlyrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OVLYRXMSG1_parse_table, 1, "OVLYRXMSG1", - 0x91, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t NSENABLE_parse_table[] = { - { "DCH0NSEN", 0x01, 0x01 }, - { "DCH1NSEN", 0x02, 0x02 }, - { "SGNSEN", 0x04, 0x04 }, - { "CMCNSEN", 0x08, 0x08 }, - { "OVLYNSEN", 0x10, 0x10 }, - { "MSINSEN", 0x20, 0x20 } -}; - -int -ahd_nsenable_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NSENABLE_parse_table, 6, "NSENABLE", - 0x91, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DCHRXMSG1_parse_table[] = { - { "CBNUM", 0xff, 0xff } -}; - -int -ahd_dchrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DCHRXMSG1_parse_table, 1, "DCHRXMSG1", - 0x91, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMCRXMSG1_parse_table[] = { - { "CBNUM", 0xff, 0xff } -}; - -int -ahd_cmcrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMCRXMSG1_parse_table, 1, "CMCRXMSG1", - 0x91, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DCHRXMSG2_parse_table[] = { - { "MINDEX", 0xff, 0xff } -}; - -int -ahd_dchrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DCHRXMSG2_parse_table, 1, "DCHRXMSG2", - 0x92, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OVLYRXMSG2_parse_table[] = { - { "MINDEX", 0xff, 0xff } -}; - -int -ahd_ovlyrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OVLYRXMSG2_parse_table, 1, "OVLYRXMSG2", - 0x92, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMCRXMSG2_parse_table[] = { - { "MINDEX", 0xff, 0xff } -}; - -int -ahd_cmcrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMCRXMSG2_parse_table, 1, "CMCRXMSG2", - 0x92, regvalue, cur_col, wrap)); -} - -int -ahd_ost_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "OST", - 0x92, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DCHRXMSG3_parse_table[] = { - { "MCLASS", 0x0f, 0x0f } -}; - -int -ahd_dchrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DCHRXMSG3_parse_table, 1, "DCHRXMSG3", - 0x93, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMCRXMSG3_parse_table[] = { - { "MCLASS", 0x0f, 0x0f } -}; - -int -ahd_cmcrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMCRXMSG3_parse_table, 1, "CMCRXMSG3", - 0x93, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t PCIXCTL_parse_table[] = { - { "CMPABCDIS", 0x01, 0x01 }, - { "TSCSERREN", 0x02, 0x02 }, - { "SRSPDPEEN", 0x04, 0x04 }, - { "SPLTSTADIS", 0x08, 0x08 }, - { "SPLTSMADIS", 0x10, 0x10 }, - { "UNEXPSCIEN", 0x20, 0x20 }, - { "SERRPULSE", 0x80, 0x80 } -}; - -int -ahd_pcixctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(PCIXCTL_parse_table, 7, "PCIXCTL", - 0x93, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OVLYRXMSG3_parse_table[] = { - { "MCLASS", 0x0f, 0x0f } -}; - -int -ahd_ovlyrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OVLYRXMSG3_parse_table, 1, "OVLYRXMSG3", - 0x93, regvalue, cur_col, wrap)); -} - -int -ahd_ovlyseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "OVLYSEQBCNT", - 0x94, regvalue, cur_col, wrap)); -} - -int -ahd_cmcseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CMCSEQBCNT", - 0x94, regvalue, cur_col, wrap)); -} - -int -ahd_dchseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DCHSEQBCNT", - 0x94, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMCSPLTSTAT0_parse_table[] = { - { "RXSPLTRSP", 0x01, 0x01 }, - { "RXSCEMSG", 0x02, 0x02 }, - { "RXOVRUN", 0x04, 0x04 }, - { "CNTNOTCMPLT", 0x08, 0x08 }, - { "SCDATBUCKET", 0x10, 0x10 }, - { "SCADERR", 0x20, 0x20 }, - { "SCBCERR", 0x40, 0x40 }, - { "STAETERM", 0x80, 0x80 } -}; - -int -ahd_cmcspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMCSPLTSTAT0_parse_table, 8, "CMCSPLTSTAT0", - 0x96, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OVLYSPLTSTAT0_parse_table[] = { - { "RXSPLTRSP", 0x01, 0x01 }, - { "RXSCEMSG", 0x02, 0x02 }, - { "RXOVRUN", 0x04, 0x04 }, - { "CNTNOTCMPLT", 0x08, 0x08 }, - { "SCDATBUCKET", 0x10, 0x10 }, - { "SCADERR", 0x20, 0x20 }, - { "SCBCERR", 0x40, 0x40 }, - { "STAETERM", 0x80, 0x80 } -}; - -int -ahd_ovlyspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OVLYSPLTSTAT0_parse_table, 8, "OVLYSPLTSTAT0", - 0x96, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DCHSPLTSTAT0_parse_table[] = { - { "RXSPLTRSP", 0x01, 0x01 }, - { "RXSCEMSG", 0x02, 0x02 }, - { "RXOVRUN", 0x04, 0x04 }, - { "CNTNOTCMPLT", 0x08, 0x08 }, - { "SCDATBUCKET", 0x10, 0x10 }, - { "SCADERR", 0x20, 0x20 }, - { "SCBCERR", 0x40, 0x40 }, - { "STAETERM", 0x80, 0x80 } -}; - -int -ahd_dchspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DCHSPLTSTAT0_parse_table, 8, "DCHSPLTSTAT0", - 0x96, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = { - { "RXDATABUCKET", 0x01, 0x01 } -}; - -int -ahd_dchspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DCHSPLTSTAT1_parse_table, 1, "DCHSPLTSTAT1", - 0x97, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMCSPLTSTAT1_parse_table[] = { - { "RXDATABUCKET", 0x01, 0x01 } -}; - -int -ahd_cmcspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMCSPLTSTAT1_parse_table, 1, "CMCSPLTSTAT1", - 0x97, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OVLYSPLTSTAT1_parse_table[] = { - { "RXDATABUCKET", 0x01, 0x01 } -}; - -int -ahd_ovlyspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OVLYSPLTSTAT1_parse_table, 1, "OVLYSPLTSTAT1", - 0x97, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SGRXMSG0_parse_table[] = { - { "CFNUM", 0x07, 0x07 }, - { "CDNUM", 0xf8, 0xf8 } -}; - -int -ahd_sgrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SGRXMSG0_parse_table, 2, "SGRXMSG0", - 0x98, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SLVSPLTOUTADR0_parse_table[] = { - { "LOWER_ADDR", 0x7f, 0x7f } -}; - -int -ahd_slvspltoutadr0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SLVSPLTOUTADR0_parse_table, 1, "SLVSPLTOUTADR0", - 0x98, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SGRXMSG1_parse_table[] = { - { "CBNUM", 0xff, 0xff } -}; - -int -ahd_sgrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SGRXMSG1_parse_table, 1, "SGRXMSG1", - 0x99, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SLVSPLTOUTADR1_parse_table[] = { - { "REQ_FNUM", 0x07, 0x07 }, - { "REQ_DNUM", 0xf8, 0xf8 } -}; - -int -ahd_slvspltoutadr1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SLVSPLTOUTADR1_parse_table, 2, "SLVSPLTOUTADR1", - 0x99, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SGRXMSG2_parse_table[] = { - { "MINDEX", 0xff, 0xff } -}; - -int -ahd_sgrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SGRXMSG2_parse_table, 1, "SGRXMSG2", - 0x9a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SLVSPLTOUTADR2_parse_table[] = { - { "REQ_BNUM", 0xff, 0xff } -}; - -int -ahd_slvspltoutadr2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SLVSPLTOUTADR2_parse_table, 1, "SLVSPLTOUTADR2", - 0x9a, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SGRXMSG3_parse_table[] = { - { "MCLASS", 0x0f, 0x0f } -}; - -int -ahd_sgrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SGRXMSG3_parse_table, 1, "SGRXMSG3", - 0x9b, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SLVSPLTOUTADR3_parse_table[] = { - { "RLXORD", 0x10, 0x10 }, - { "TAG_NUM", 0x1f, 0x1f } -}; - -int -ahd_slvspltoutadr3_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SLVSPLTOUTADR3_parse_table, 2, "SLVSPLTOUTADR3", - 0x9b, regvalue, cur_col, wrap)); -} - -int -ahd_sgseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SGSEQBCNT", - 0x9c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SLVSPLTOUTATTR0_parse_table[] = { - { "LOWER_BCNT", 0xff, 0xff } -}; - -int -ahd_slvspltoutattr0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SLVSPLTOUTATTR0_parse_table, 1, "SLVSPLTOUTATTR0", - 0x9c, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SLVSPLTOUTATTR1_parse_table[] = { - { "CMPLT_FNUM", 0x07, 0x07 }, - { "CMPLT_DNUM", 0xf8, 0xf8 } -}; - -int -ahd_slvspltoutattr1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SLVSPLTOUTATTR1_parse_table, 2, "SLVSPLTOUTATTR1", - 0x9d, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SLVSPLTOUTATTR2_parse_table[] = { - { "CMPLT_BNUM", 0xff, 0xff } -}; - -int -ahd_slvspltoutattr2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SLVSPLTOUTATTR2_parse_table, 1, "SLVSPLTOUTATTR2", - 0x9e, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SGSPLTSTAT0_parse_table[] = { - { "RXSPLTRSP", 0x01, 0x01 }, - { "RXSCEMSG", 0x02, 0x02 }, - { "RXOVRUN", 0x04, 0x04 }, - { "CNTNOTCMPLT", 0x08, 0x08 }, - { "SCDATBUCKET", 0x10, 0x10 }, - { "SCADERR", 0x20, 0x20 }, - { "SCBCERR", 0x40, 0x40 }, - { "STAETERM", 0x80, 0x80 } -}; - -int -ahd_sgspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SGSPLTSTAT0_parse_table, 8, "SGSPLTSTAT0", - 0x9e, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SFUNCT_parse_table[] = { - { "TEST_NUM", 0x0f, 0x0f }, - { "TEST_GROUP", 0xf0, 0xf0 } -}; - -int -ahd_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SFUNCT_parse_table, 2, "SFUNCT", - 0x9f, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SGSPLTSTAT1_parse_table[] = { - { "RXDATABUCKET", 0x01, 0x01 } -}; - -int -ahd_sgspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SGSPLTSTAT1_parse_table, 1, "SGSPLTSTAT1", - 0x9f, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DF0PCISTAT_parse_table[] = { - { "DPR", 0x01, 0x01 }, - { "TWATERR", 0x02, 0x02 }, - { "RDPERR", 0x04, 0x04 }, - { "SCAAPERR", 0x08, 0x08 }, - { "RTA", 0x10, 0x10 }, - { "RMA", 0x20, 0x20 }, - { "SSE", 0x40, 0x40 }, - { "DPE", 0x80, 0x80 } -}; - -int -ahd_df0pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DF0PCISTAT_parse_table, 8, "DF0PCISTAT", - 0xa0, regvalue, cur_col, wrap)); -} - -int -ahd_reg0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "REG0", - 0xa0, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DF1PCISTAT_parse_table[] = { - { "DPR", 0x01, 0x01 }, - { "TWATERR", 0x02, 0x02 }, - { "RDPERR", 0x04, 0x04 }, - { "SCAAPERR", 0x08, 0x08 }, - { "RTA", 0x10, 0x10 }, - { "RMA", 0x20, 0x20 }, - { "SSE", 0x40, 0x40 }, - { "DPE", 0x80, 0x80 } -}; - -int -ahd_df1pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DF1PCISTAT_parse_table, 8, "DF1PCISTAT", - 0xa1, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SGPCISTAT_parse_table[] = { - { "DPR", 0x01, 0x01 }, - { "RDPERR", 0x04, 0x04 }, - { "SCAAPERR", 0x08, 0x08 }, - { "RTA", 0x10, 0x10 }, - { "RMA", 0x20, 0x20 }, - { "SSE", 0x40, 0x40 }, - { "DPE", 0x80, 0x80 } -}; - -int -ahd_sgpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SGPCISTAT_parse_table, 7, "SGPCISTAT", - 0xa2, regvalue, cur_col, wrap)); -} - -int -ahd_reg1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "REG1", - 0xa2, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMCPCISTAT_parse_table[] = { - { "DPR", 0x01, 0x01 }, - { "TWATERR", 0x02, 0x02 }, - { "RDPERR", 0x04, 0x04 }, - { "SCAAPERR", 0x08, 0x08 }, - { "RTA", 0x10, 0x10 }, - { "RMA", 0x20, 0x20 }, - { "SSE", 0x40, 0x40 }, - { "DPE", 0x80, 0x80 } -}; - -int -ahd_cmcpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMCPCISTAT_parse_table, 8, "CMCPCISTAT", - 0xa3, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t OVLYPCISTAT_parse_table[] = { - { "DPR", 0x01, 0x01 }, - { "RDPERR", 0x04, 0x04 }, - { "SCAAPERR", 0x08, 0x08 }, - { "RTA", 0x10, 0x10 }, - { "RMA", 0x20, 0x20 }, - { "SSE", 0x40, 0x40 }, - { "DPE", 0x80, 0x80 } -}; - -int -ahd_ovlypcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(OVLYPCISTAT_parse_table, 7, "OVLYPCISTAT", - 0xa4, regvalue, cur_col, wrap)); -} - -int -ahd_reg_isr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "REG_ISR", - 0xa4, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SG_STATE_parse_table[] = { - { "SEGS_AVAIL", 0x01, 0x01 }, - { "LOADING_NEEDED", 0x02, 0x02 }, - { "FETCH_INPROG", 0x04, 0x04 } -}; - -int -ahd_sg_state_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SG_STATE_parse_table, 3, "SG_STATE", - 0xa6, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t MSIPCISTAT_parse_table[] = { - { "DPR", 0x01, 0x01 }, - { "TWATERR", 0x02, 0x02 }, - { "CLRPENDMSI", 0x08, 0x08 }, - { "RTA", 0x10, 0x10 }, - { "RMA", 0x20, 0x20 }, - { "SSE", 0x40, 0x40 } -}; - -int -ahd_msipcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(MSIPCISTAT_parse_table, 6, "MSIPCISTAT", - 0xa6, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t TARGPCISTAT_parse_table[] = { - { "TWATERR", 0x02, 0x02 }, - { "STA", 0x08, 0x08 }, - { "SSE", 0x40, 0x40 }, - { "DPE", 0x80, 0x80 } -}; - -int -ahd_targpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(TARGPCISTAT_parse_table, 4, "TARGPCISTAT", - 0xa7, regvalue, cur_col, wrap)); -} - -int -ahd_data_count_odd_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DATA_COUNT_ODD", - 0xa7, regvalue, cur_col, wrap)); -} - -int -ahd_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCBPTR", - 0xa8, regvalue, cur_col, wrap)); -} - -int -ahd_ccscbacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CCSCBACNT", - 0xab, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCBAUTOPTR_parse_table[] = { - { "SCBPTR_OFF", 0x07, 0x07 }, - { "SCBPTR_ADDR", 0x38, 0x38 }, - { "AUSCBPTR_EN", 0x80, 0x80 } -}; - -int -ahd_scbautoptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCBAUTOPTR_parse_table, 3, "SCBAUTOPTR", - 0xab, regvalue, cur_col, wrap)); -} - -int -ahd_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CCSGADDR", - 0xac, regvalue, cur_col, wrap)); -} - -int -ahd_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CCSCBADDR", - 0xac, regvalue, cur_col, wrap)); -} - -int -ahd_ccscbadr_bk_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CCSCBADR_BK", - 0xac, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CMC_RAMBIST_parse_table[] = { - { "CMC_BUFFER_BIST_EN", 0x01, 0x01 }, - { "CMC_BUFFER_BIST_FAIL",0x02, 0x02 }, - { "SG_BIST_EN", 0x10, 0x10 }, - { "SG_BIST_FAIL", 0x20, 0x20 }, - { "SCBRAMBIST_FAIL", 0x40, 0x40 }, - { "SG_ELEMENT_SIZE", 0x80, 0x80 } -}; - -int -ahd_cmc_rambist_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CMC_RAMBIST_parse_table, 6, "CMC_RAMBIST", - 0xad, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CCSGCTL_parse_table[] = { - { "CCSGRESET", 0x01, 0x01 }, - { "SG_FETCH_REQ", 0x02, 0x02 }, - { "CCSGENACK", 0x08, 0x08 }, - { "SG_CACHE_AVAIL", 0x10, 0x10 }, - { "CCSGDONE", 0x80, 0x80 }, - { "CCSGEN", 0x0c, 0x0c } -}; - -int -ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL", - 0xad, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = { - { "CCSCBRESET", 0x01, 0x01 }, - { "CCSCBDIR", 0x04, 0x04 }, - { "CCSCBEN", 0x08, 0x08 }, - { "CCARREN", 0x10, 0x10 }, - { "ARRDONE", 0x40, 0x40 }, - { "CCSCBDONE", 0x80, 0x80 } -}; - -int -ahd_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL", - 0xad, regvalue, cur_col, wrap)); -} - -int -ahd_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CCSGRAM", - 0xb0, regvalue, cur_col, wrap)); -} - -int -ahd_flexadr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "FLEXADR", - 0xb0, regvalue, cur_col, wrap)); -} - -int -ahd_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CCSCBRAM", - 0xb0, regvalue, cur_col, wrap)); -} - -int -ahd_flexcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "FLEXCNT", - 0xb3, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t FLEXDMASTAT_parse_table[] = { - { "FLEXDMADONE", 0x01, 0x01 }, - { "FLEXDMAERR", 0x02, 0x02 } -}; - -int -ahd_flexdmastat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(FLEXDMASTAT_parse_table, 2, "FLEXDMASTAT", - 0xb5, regvalue, cur_col, wrap)); -} - -int -ahd_flexdata_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "FLEXDATA", - 0xb6, regvalue, cur_col, wrap)); -} - -int -ahd_brddat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "BRDDAT", - 0xb8, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t BRDCTL_parse_table[] = { - { "BRDSTB", 0x01, 0x01 }, - { "BRDRW", 0x02, 0x02 }, - { "BRDEN", 0x04, 0x04 }, - { "BRDADDR", 0x38, 0x38 }, - { "FLXARBREQ", 0x40, 0x40 }, - { "FLXARBACK", 0x80, 0x80 } -}; - -int -ahd_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(BRDCTL_parse_table, 6, "BRDCTL", - 0xb9, regvalue, cur_col, wrap)); -} - -int -ahd_seeadr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SEEADR", - 0xba, regvalue, cur_col, wrap)); -} - -int -ahd_seedat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SEEDAT", - 0xbc, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEECTL_parse_table[] = { - { "SEEOP_ERAL", 0x40, 0x70 }, - { "SEEOP_WRITE", 0x50, 0x70 }, - { "SEEOP_READ", 0x60, 0x70 }, - { "SEEOP_ERASE", 0x70, 0x70 }, - { "SEESTART", 0x01, 0x01 }, - { "SEERST", 0x02, 0x02 }, - { "SEEOPCODE", 0x70, 0x70 }, - { "SEEOP_EWEN", 0x40, 0x40 }, - { "SEEOP_WALL", 0x40, 0x40 }, - { "SEEOP_EWDS", 0x40, 0x40 } -}; - -int -ahd_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEECTL_parse_table, 10, "SEECTL", - 0xbe, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEESTAT_parse_table[] = { - { "SEESTART", 0x01, 0x01 }, - { "SEEBUSY", 0x02, 0x02 }, - { "SEEARBACK", 0x04, 0x04 }, - { "LDALTID_L", 0x08, 0x08 }, - { "SEEOPCODE", 0x70, 0x70 }, - { "INIT_DONE", 0x80, 0x80 } -}; - -int -ahd_seestat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEESTAT_parse_table, 6, "SEESTAT", - 0xbe, regvalue, cur_col, wrap)); -} - -int -ahd_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCBCNT", - 0xbf, regvalue, cur_col, wrap)); -} - -int -ahd_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFWADDR", - 0xc0, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DSPFLTRCTL_parse_table[] = { - { "DSPFCNTSEL", 0x0f, 0x0f }, - { "EDGESENSE", 0x10, 0x10 }, - { "FLTRDISABLE", 0x20, 0x20 } -}; - -int -ahd_dspfltrctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DSPFLTRCTL_parse_table, 3, "DSPFLTRCTL", - 0xc0, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DSPDATACTL_parse_table[] = { - { "XMITOFFSTDIS", 0x02, 0x02 }, - { "RCVROFFSTDIS", 0x04, 0x04 }, - { "DESQDIS", 0x10, 0x10 }, - { "BYPASSENAB", 0x80, 0x80 } -}; - -int -ahd_dspdatactl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DSPDATACTL_parse_table, 4, "DSPDATACTL", - 0xc1, regvalue, cur_col, wrap)); -} - -int -ahd_dfraddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFRADDR", - 0xc2, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DSPREQCTL_parse_table[] = { - { "MANREQDLY", 0x3f, 0x3f }, - { "MANREQCTL", 0xc0, 0xc0 } -}; - -int -ahd_dspreqctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DSPREQCTL_parse_table, 2, "DSPREQCTL", - 0xc2, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DSPACKCTL_parse_table[] = { - { "MANACKDLY", 0x3f, 0x3f }, - { "MANACKCTL", 0xc0, 0xc0 } -}; - -int -ahd_dspackctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DSPACKCTL_parse_table, 2, "DSPACKCTL", - 0xc3, regvalue, cur_col, wrap)); -} - -int -ahd_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFDAT", - 0xc4, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DSPSELECT_parse_table[] = { - { "DSPSEL", 0x1f, 0x1f }, - { "AUTOINCEN", 0x80, 0x80 } -}; - -int -ahd_dspselect_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DSPSELECT_parse_table, 2, "DSPSELECT", - 0xc4, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t WRTBIASCTL_parse_table[] = { - { "XMITMANVAL", 0x3f, 0x3f }, - { "AUTOXBCDIS", 0x80, 0x80 } -}; - -int -ahd_wrtbiasctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(WRTBIASCTL_parse_table, 2, "WRTBIASCTL", - 0xc5, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t RCVRBIOSCTL_parse_table[] = { - { "RCVRMANVAL", 0x3f, 0x3f }, - { "AUTORBCDIS", 0x80, 0x80 } -}; - -int -ahd_rcvrbiosctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(RCVRBIOSCTL_parse_table, 2, "RCVRBIOSCTL", - 0xc6, regvalue, cur_col, wrap)); -} - -int -ahd_wrtbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "WRTBIASCALC", - 0xc7, regvalue, cur_col, wrap)); -} - -int -ahd_dfptrs_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFPTRS", - 0xc8, regvalue, cur_col, wrap)); -} - -int -ahd_rcvrbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "RCVRBIASCALC", - 0xc8, regvalue, cur_col, wrap)); -} - -int -ahd_dfbkptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFBKPTR", - 0xc9, regvalue, cur_col, wrap)); -} - -int -ahd_skewcalc_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SKEWCALC", - 0xc9, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DFDBCTL_parse_table[] = { - { "DFF_RAMBIST_EN", 0x01, 0x01 }, - { "DFF_RAMBIST_DONE", 0x02, 0x02 }, - { "DFF_RAMBIST_FAIL", 0x04, 0x04 }, - { "DFF_DIR_ERR", 0x08, 0x08 }, - { "DFF_CIO_RD_RDY", 0x10, 0x10 }, - { "DFF_CIO_WR_RDY", 0x20, 0x20 } -}; - -int -ahd_dfdbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DFDBCTL_parse_table, 6, "DFDBCTL", - 0xcb, regvalue, cur_col, wrap)); -} - -int -ahd_dfscnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFSCNT", - 0xcc, regvalue, cur_col, wrap)); -} - -int -ahd_dfbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DFBCNT", - 0xce, regvalue, cur_col, wrap)); -} - -int -ahd_ovlyaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "OVLYADDR", - 0xd4, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQCTL0_parse_table[] = { - { "LOADRAM", 0x01, 0x01 }, - { "SEQRESET", 0x02, 0x02 }, - { "STEP", 0x04, 0x04 }, - { "BRKADRINTEN", 0x08, 0x08 }, - { "FASTMODE", 0x10, 0x10 }, - { "FAILDIS", 0x20, 0x20 }, - { "PAUSEDIS", 0x40, 0x40 }, - { "PERRORDIS", 0x80, 0x80 } -}; - -int -ahd_seqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQCTL0_parse_table, 8, "SEQCTL0", - 0xd6, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQCTL1_parse_table[] = { - { "RAMBIST_EN", 0x01, 0x01 }, - { "RAMBIST_FAIL", 0x02, 0x02 }, - { "RAMBIST_DONE", 0x04, 0x04 }, - { "OVRLAY_DATA_CHK", 0x08, 0x08 } -}; - -int -ahd_seqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQCTL1_parse_table, 4, "SEQCTL1", - 0xd7, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t FLAGS_parse_table[] = { - { "CARRY", 0x01, 0x01 }, - { "ZERO", 0x02, 0x02 } -}; - -int -ahd_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(FLAGS_parse_table, 2, "FLAGS", - 0xd8, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQINTCTL_parse_table[] = { - { "IRET", 0x01, 0x01 }, - { "INTMASK1", 0x02, 0x02 }, - { "INTMASK2", 0x04, 0x04 }, - { "SCS_SEQ_INT1M0", 0x08, 0x08 }, - { "SCS_SEQ_INT1M1", 0x10, 0x10 }, - { "INT1_CONTEXT", 0x20, 0x20 }, - { "INTVEC1DSL", 0x80, 0x80 } -}; - -int -ahd_seqintctl_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQINTCTL_parse_table, 7, "SEQINTCTL", - 0xd9, regvalue, cur_col, wrap)); -} - -int -ahd_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SEQRAM", - 0xda, regvalue, cur_col, wrap)); -} - -int -ahd_prgmcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "PRGMCNT", - 0xde, regvalue, cur_col, wrap)); -} - -int -ahd_accum_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ACCUM", - 0xe0, regvalue, cur_col, wrap)); -} - -int -ahd_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SINDEX", - 0xe2, regvalue, cur_col, wrap)); -} - -int -ahd_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DINDEX", - 0xe4, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t BRKADDR1_parse_table[] = { - { "BRKDIS", 0x80, 0x80 } -}; - -int -ahd_brkaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(BRKADDR1_parse_table, 1, "BRKADDR1", - 0xe6, regvalue, cur_col, wrap)); -} - -int -ahd_brkaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "BRKADDR0", - 0xe6, regvalue, cur_col, wrap)); -} - -int -ahd_allones_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ALLONES", - 0xe8, regvalue, cur_col, wrap)); -} - -int -ahd_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ALLZEROS", - 0xea, regvalue, cur_col, wrap)); -} - -int -ahd_none_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "NONE", - 0xea, regvalue, cur_col, wrap)); -} - -int -ahd_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SINDIR", - 0xec, regvalue, cur_col, wrap)); -} - -int -ahd_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "DINDIR", - 0xed, regvalue, cur_col, wrap)); -} - -int -ahd_function1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "FUNCTION1", - 0xf0, regvalue, cur_col, wrap)); -} - -int -ahd_stack_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "STACK", - 0xf2, regvalue, cur_col, wrap)); -} - -int -ahd_curaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CURADDR", - 0xf4, regvalue, cur_col, wrap)); -} - -int -ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "INTVEC1_ADDR", - 0xf4, regvalue, cur_col, wrap)); -} - -int -ahd_intvec2_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "INTVEC2_ADDR", - 0xf6, regvalue, cur_col, wrap)); -} - -int -ahd_lastaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LASTADDR", - 0xf6, regvalue, cur_col, wrap)); -} - -int -ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LONGJMP_ADDR", - 0xf8, regvalue, cur_col, wrap)); -} - -int -ahd_longjmp_scb_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LONGJMP_SCB", - 0xfa, regvalue, cur_col, wrap)); -} - -int -ahd_accum_save_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ACCUM_SAVE", - 0xfc, regvalue, cur_col, wrap)); -} - -int -ahd_waiting_scb_tails_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", - 0x100, regvalue, cur_col, wrap)); -} - -int -ahd_ahd_pci_config_base_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE", - 0x100, regvalue, cur_col, wrap)); -} - -int -ahd_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SRAM_BASE", - 0x100, regvalue, cur_col, wrap)); -} - -int -ahd_waiting_tid_head_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "WAITING_TID_HEAD", - 0x120, regvalue, cur_col, wrap)); -} - -int -ahd_waiting_tid_tail_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "WAITING_TID_TAIL", - 0x122, regvalue, cur_col, wrap)); -} - -int -ahd_next_queued_scb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR", - 0x124, regvalue, cur_col, wrap)); -} - -int -ahd_complete_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD", - 0x128, regvalue, cur_col, wrap)); -} - -int -ahd_complete_scb_dmainprog_head_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD", - 0x12a, regvalue, cur_col, wrap)); -} - -int -ahd_complete_dma_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD", - 0x12c, regvalue, cur_col, wrap)); -} - -int -ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "QFREEZE_COUNT", - 0x12e, regvalue, cur_col, wrap)); -} - -int -ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SAVED_MODE", - 0x130, regvalue, cur_col, wrap)); -} - -int -ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "MSG_OUT", - 0x131, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t DMAPARAMS_parse_table[] = { - { "FIFORESET", 0x01, 0x01 }, - { "FIFOFLUSH", 0x02, 0x02 }, - { "DIRECTION", 0x04, 0x04 }, - { "HDMAEN", 0x08, 0x08 }, - { "HDMAENACK", 0x08, 0x08 }, - { "SDMAEN", 0x10, 0x10 }, - { "SDMAENACK", 0x10, 0x10 }, - { "SCSIEN", 0x20, 0x20 }, - { "WIDEODD", 0x40, 0x40 }, - { "PRELOADEN", 0x80, 0x80 } -}; - -int -ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS", - 0x132, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = { - { "NO_DISCONNECT", 0x01, 0x01 }, - { "SPHASE_PENDING", 0x02, 0x02 }, - { "DPHASE_PENDING", 0x04, 0x04 }, - { "CMDPHASE_PENDING", 0x08, 0x08 }, - { "TARG_CMD_PENDING", 0x10, 0x10 }, - { "DPHASE", 0x20, 0x20 }, - { "NO_CDB_SENT", 0x40, 0x40 }, - { "TARGET_CMD_IS_TAGGED",0x40, 0x40 }, - { "NOT_IDENTIFIED", 0x80, 0x80 } -}; - -int -ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS", - 0x133, regvalue, cur_col, wrap)); -} - -int -ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SAVED_SCSIID", - 0x134, regvalue, cur_col, wrap)); -} - -int -ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SAVED_LUN", - 0x135, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t LASTPHASE_parse_table[] = { - { "P_DATAOUT", 0x00, 0xe0 }, - { "P_DATAOUT_DT", 0x20, 0xe0 }, - { "P_DATAIN", 0x40, 0xe0 }, - { "P_DATAIN_DT", 0x60, 0xe0 }, - { "P_COMMAND", 0x80, 0xe0 }, - { "P_MESGOUT", 0xa0, 0xe0 }, - { "P_STATUS", 0xc0, 0xe0 }, - { "P_MESGIN", 0xe0, 0xe0 }, - { "P_BUSFREE", 0x01, 0x01 }, - { "MSGI", 0x20, 0x20 }, - { "IOI", 0x40, 0x40 }, - { "CDI", 0x80, 0x80 }, - { "PHASE_MASK", 0xe0, 0xe0 } -}; - -int -ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE", - 0x136, regvalue, cur_col, wrap)); -} - -int -ahd_qoutfifo_entry_valid_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG", - 0x137, regvalue, cur_col, wrap)); -} - -int -ahd_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", - 0x138, regvalue, cur_col, wrap)); -} - -int -ahd_qoutfifo_next_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", - 0x13c, regvalue, cur_col, wrap)); -} - -int -ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS", - 0x140, regvalue, cur_col, wrap)); -} - -int -ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "TQINPOS", - 0x141, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t ARG_1_parse_table[] = { - { "CONT_MSG_LOOP_TARG", 0x02, 0x02 }, - { "CONT_MSG_LOOP_READ", 0x03, 0x03 }, - { "CONT_MSG_LOOP_WRITE",0x04, 0x04 }, - { "EXIT_MSG_LOOP", 0x08, 0x08 }, - { "MSGOUT_PHASEMIS", 0x10, 0x10 }, - { "SEND_REJ", 0x20, 0x20 }, - { "SEND_SENSE", 0x40, 0x40 }, - { "SEND_MSG", 0x80, 0x80 } -}; - -int -ahd_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(ARG_1_parse_table, 8, "ARG_1", - 0x142, regvalue, cur_col, wrap)); -} - -int -ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ARG_2", - 0x143, regvalue, cur_col, wrap)); -} - -int -ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LAST_MSG", - 0x144, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = { - { "ALTSTIM", 0x01, 0x01 }, - { "ENAUTOATNP", 0x02, 0x02 }, - { "MANUALP", 0x0c, 0x0c }, - { "ENRSELI", 0x10, 0x10 }, - { "ENSELI", 0x20, 0x20 }, - { "MANUALCTL", 0x40, 0x40 } -}; - -int -ahd_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE", - 0x145, regvalue, cur_col, wrap)); -} - -int -ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "INITIATOR_TAG", - 0x146, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = { - { "TARGET_MSG_PENDING", 0x02, 0x02 }, - { "SELECTOUT_QFROZEN", 0x04, 0x04 } -}; - -int -ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2", - 0x147, regvalue, cur_col, wrap)); -} - -int -ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR", - 0x148, regvalue, cur_col, wrap)); -} - -int -ahd_int_coalessing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "INT_COALESSING_TIMER", - 0x14a, regvalue, cur_col, wrap)); -} - -int -ahd_int_coalessing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS", - 0x14c, regvalue, cur_col, wrap)); -} - -int -ahd_int_coalessing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS", - 0x14d, regvalue, cur_col, wrap)); -} - -int -ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CMDS_PENDING", - 0x14e, regvalue, cur_col, wrap)); -} - -int -ahd_int_coalessing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT", - 0x150, regvalue, cur_col, wrap)); -} - -int -ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX", - 0x151, regvalue, cur_col, wrap)); -} - -int -ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE", - 0x152, regvalue, cur_col, wrap)); -} - -int -ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_BASE", - 0x180, regvalue, cur_col, wrap)); -} - -int -ahd_scb_residual_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", - 0x180, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCB_RESIDUAL_SGPTR_parse_table[] = { - { "SG_LIST_NULL", 0x01, 0x01 }, - { "SG_OVERRUN_RESID", 0x02, 0x02 }, - { "SG_ADDR_MASK", 0xf8, 0xf8 } -}; - -int -ahd_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCB_RESIDUAL_SGPTR_parse_table, 3, "SCB_RESIDUAL_SGPTR", - 0x184, regvalue, cur_col, wrap)); -} - -int -ahd_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", - 0x188, regvalue, cur_col, wrap)); -} - -int -ahd_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_TARGET_PHASES", - 0x189, regvalue, cur_col, wrap)); -} - -int -ahd_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", - 0x18a, regvalue, cur_col, wrap)); -} - -int -ahd_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_TARGET_ITAG", - 0x18b, regvalue, cur_col, wrap)); -} - -int -ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR", - 0x18c, regvalue, cur_col, wrap)); -} - -int -ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_TAG", - 0x190, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = { - { "SCB_CDB_LEN_PTR", 0x80, 0x80 } -}; - -int -ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN", - 0x192, regvalue, cur_col, wrap)); -} - -int -ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", - 0x193, regvalue, cur_col, wrap)); -} - -int -ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_NEXT", - 0x194, regvalue, cur_col, wrap)); -} - -int -ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_NEXT2", - 0x196, regvalue, cur_col, wrap)); -} - -int -ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_DATAPTR", - 0x198, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = { - { "SG_HIGH_ADDR_BITS", 0x7f, 0x7f }, - { "SG_LAST_SEG", 0x80, 0x80 } -}; - -int -ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT", - 0x1a0, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = { - { "SG_LIST_NULL", 0x01, 0x01 }, - { "SG_FULL_RESID", 0x02, 0x02 }, - { "SG_STATUS_VALID", 0x04, 0x04 } -}; - -int -ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR", - 0x1a4, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = { - { "SCB_TAG_TYPE", 0x03, 0x03 }, - { "DISCONNECTED", 0x04, 0x04 }, - { "STATUS_RCVD", 0x08, 0x08 }, - { "MK_MESSAGE", 0x10, 0x10 }, - { "TAG_ENB", 0x20, 0x20 }, - { "DISCENB", 0x40, 0x40 }, - { "TARGET_SCB", 0x80, 0x80 } -}; - -int -ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL", - 0x1a8, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = { - { "OID", 0x0f, 0x0f }, - { "TID", 0xf0, 0xf0 } -}; - -int -ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID", - 0x1a9, regvalue, cur_col, wrap)); -} - -static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = { - { "LID", 0xff, 0xff } -}; - -int -ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN", - 0x1aa, regvalue, cur_col, wrap)); -} - -int -ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", - 0x1ab, regvalue, cur_col, wrap)); -} - -int -ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_BUSADDR", - 0x1ac, regvalue, cur_col, wrap)); -} - -int -ahd_scb_spare_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_SPARE", - 0x1b0, regvalue, cur_col, wrap)); -} - -int -ahd_scb_disconnected_lists_print(u_int regvalue, u_int *cur_col, u_int wrap) -{ - return (ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS", - 0x1b8, regvalue, cur_col, wrap)); -} - diff -urN linux-2.4.21/drivers/scsi/aic79xx/aic79xx_seq.h linux-2.4.22/drivers/scsi/aic79xx/aic79xx_seq.h --- linux-2.4.21/drivers/scsi/aic79xx/aic79xx_seq.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aic79xx_seq.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,1085 +0,0 @@ -/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ - */ -static uint8_t seqprog[] = { - 0xff, 0x02, 0x06, 0x78, - 0x00, 0xea, 0x46, 0x59, - 0x01, 0xea, 0x04, 0x30, - 0xff, 0x04, 0x0c, 0x78, - 0x19, 0xea, 0x46, 0x59, - 0x19, 0xea, 0x04, 0x00, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x60, 0x3a, 0x1a, 0x68, - 0x04, 0x47, 0x1b, 0x68, - 0xff, 0x21, 0x1b, 0x70, - 0x40, 0x4b, 0x88, 0x69, - 0x00, 0xe2, 0x4a, 0x59, - 0x40, 0x4b, 0x88, 0x69, - 0x20, 0x4b, 0x78, 0x69, - 0xfc, 0x42, 0x24, 0x78, - 0x10, 0x40, 0x24, 0x78, - 0x00, 0xe2, 0xa4, 0x5d, - 0x20, 0x4d, 0x28, 0x78, - 0x00, 0xe2, 0xa4, 0x5d, - 0x00, 0xe2, 0x34, 0x58, - 0x00, 0xe2, 0x66, 0x58, - 0x00, 0xe2, 0x76, 0x58, - 0x00, 0xe2, 0x06, 0x40, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x01, 0x52, 0x66, 0x7d, - 0x02, 0x58, 0x50, 0x31, - 0xff, 0xea, 0x10, 0x0b, - 0xff, 0x93, 0x45, 0x78, - 0x50, 0x4b, 0x40, 0x68, - 0xbf, 0x3a, 0x74, 0x08, - 0x14, 0xea, 0x46, 0x59, - 0x14, 0xea, 0x04, 0x00, - 0x08, 0xa8, 0x51, 0x03, - 0x01, 0xa4, 0x4d, 0x78, - 0x00, 0xe2, 0x44, 0x5b, - 0x00, 0xe2, 0x34, 0x40, - 0xff, 0xea, 0xd4, 0x19, - 0x02, 0xa8, 0x84, 0x32, - 0x00, 0xea, 0x3a, 0x59, - 0x01, 0xea, 0x00, 0x30, - 0x00, 0xe2, 0x98, 0x5d, - 0x00, 0xe2, 0x66, 0x4d, - 0x11, 0xea, 0x3a, 0x59, - 0x11, 0xea, 0x00, 0x00, - 0x00, 0xe2, 0x98, 0x5d, - 0x00, 0xe2, 0x66, 0x4d, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x00, 0xe2, 0x3a, 0x43, - 0x00, 0xea, 0x3a, 0x59, - 0x01, 0xea, 0x00, 0x30, - 0x80, 0xf9, 0x6e, 0x68, - 0x00, 0xe2, 0x38, 0x59, - 0x11, 0xea, 0x3a, 0x59, - 0x11, 0xea, 0x00, 0x00, - 0x80, 0xf9, 0x38, 0x79, - 0xff, 0xea, 0xd4, 0x0d, - 0x22, 0xea, 0x3a, 0x59, - 0x22, 0xea, 0x00, 0x00, - 0x10, 0x16, 0x80, 0x78, - 0x01, 0x0b, 0xa2, 0x32, - 0x10, 0x16, 0x2c, 0x00, - 0x18, 0xad, 0xee, 0x78, - 0x04, 0xad, 0xbc, 0x68, - 0x80, 0xad, 0x66, 0x7d, - 0x10, 0xad, 0x8a, 0x78, - 0xe7, 0xad, 0x5a, 0x0d, - 0xe7, 0xad, 0x5a, 0x09, - 0x00, 0xe2, 0x98, 0x58, - 0xff, 0xea, 0x56, 0x02, - 0x04, 0x7c, 0x78, 0x32, - 0x20, 0x16, 0x66, 0x7d, - 0x04, 0x38, 0x79, 0x32, - 0x80, 0x37, 0x6f, 0x16, - 0xff, 0x2d, 0xa7, 0x60, - 0xff, 0x29, 0xa7, 0x60, - 0x40, 0x51, 0xb7, 0x78, - 0xff, 0x4f, 0xa7, 0x68, - 0xff, 0x4d, 0xc1, 0x19, - 0x00, 0x4e, 0xd5, 0x19, - 0x00, 0xe2, 0xb6, 0x50, - 0x01, 0x4c, 0xc1, 0x31, - 0x00, 0x50, 0xd5, 0x19, - 0x00, 0xe2, 0xb6, 0x48, - 0x80, 0x18, 0x66, 0x7d, - 0x02, 0x4a, 0x1d, 0x30, - 0x10, 0xea, 0x18, 0x00, - 0x60, 0x18, 0x30, 0x00, - 0x7f, 0x18, 0x30, 0x0c, - 0x02, 0xea, 0x02, 0x00, - 0xff, 0xea, 0xa0, 0x0a, - 0x80, 0x18, 0x30, 0x04, - 0x40, 0xad, 0x66, 0x7d, - 0xe7, 0xad, 0x5a, 0x09, - 0x02, 0xa8, 0x40, 0x31, - 0xff, 0xea, 0xc0, 0x09, - 0x01, 0x4e, 0x9d, 0x1a, - 0x00, 0x4f, 0x9f, 0x22, - 0x04, 0x94, 0x49, 0x32, - 0xff, 0xea, 0x2a, 0x03, - 0xff, 0xea, 0x2e, 0x03, - 0x01, 0x10, 0xd4, 0x31, - 0x10, 0xa8, 0xe3, 0x68, - 0x3d, 0xa9, 0xc5, 0x29, - 0xfe, 0xe2, 0xc4, 0x09, - 0x01, 0xea, 0xc6, 0x01, - 0x02, 0xe2, 0xc8, 0x31, - 0x02, 0xec, 0x50, 0x31, - 0x02, 0xa0, 0xda, 0x31, - 0xff, 0xa9, 0xe2, 0x70, - 0x02, 0xa0, 0x28, 0x37, - 0xff, 0x21, 0xeb, 0x70, - 0x02, 0x22, 0x51, 0x31, - 0x02, 0xa0, 0x2c, 0x33, - 0x02, 0xa0, 0x44, 0x36, - 0x02, 0xa0, 0x40, 0x32, - 0x02, 0xa0, 0x44, 0x36, - 0x04, 0x47, 0xf3, 0x68, - 0x40, 0x16, 0x1e, 0x69, - 0xff, 0x2d, 0x23, 0x61, - 0xff, 0x29, 0x67, 0x75, - 0x01, 0x37, 0xc1, 0x31, - 0x02, 0x28, 0x55, 0x32, - 0x01, 0xea, 0x5a, 0x01, - 0x04, 0x3c, 0xf9, 0x30, - 0x02, 0x28, 0x51, 0x31, - 0x01, 0xa8, 0x60, 0x31, - 0x00, 0xa9, 0x60, 0x01, - 0x01, 0x14, 0xd4, 0x31, - 0x01, 0x50, 0xa1, 0x1a, - 0xff, 0x4e, 0x9d, 0x1a, - 0xff, 0x4f, 0x9f, 0x22, - 0xff, 0x8d, 0x17, 0x71, - 0x80, 0xac, 0x16, 0x71, - 0x20, 0x16, 0x16, 0x69, - 0x02, 0x8c, 0x51, 0x31, - 0x00, 0xe2, 0x00, 0x41, - 0x01, 0xac, 0x08, 0x31, - 0x09, 0xea, 0x5a, 0x01, - 0x02, 0x8c, 0x51, 0x32, - 0xff, 0xea, 0x1a, 0x07, - 0x04, 0x24, 0xf9, 0x30, - 0x1d, 0xea, 0x2e, 0x41, - 0x02, 0x2c, 0x51, 0x31, - 0x04, 0xac, 0xf9, 0x30, - 0x19, 0xea, 0x2e, 0x59, - 0x02, 0x8c, 0x59, 0x32, - 0x02, 0x28, 0x19, 0x33, - 0x02, 0xa8, 0x50, 0x36, - 0x06, 0xea, 0x08, 0x81, - 0x01, 0xe2, 0x5a, 0x35, - 0x02, 0xa8, 0xf4, 0x31, - 0x02, 0xf2, 0xf0, 0x35, - 0x02, 0xf2, 0xf0, 0x31, - 0x02, 0xf8, 0xe4, 0x35, - 0x80, 0xea, 0xb2, 0x01, - 0x01, 0xe2, 0x00, 0x30, - 0xff, 0xea, 0xb2, 0x0d, - 0x80, 0xea, 0xb2, 0x01, - 0x11, 0x00, 0x00, 0x10, - 0xff, 0xea, 0xb2, 0x0d, - 0x01, 0xe2, 0x04, 0x30, - 0x01, 0xea, 0x04, 0x34, - 0x02, 0x20, 0xbd, 0x30, - 0x02, 0x20, 0xb9, 0x30, - 0x02, 0x20, 0x51, 0x31, - 0x4c, 0xa9, 0xd7, 0x28, - 0x10, 0xa8, 0x59, 0x79, - 0x01, 0x6b, 0xc0, 0x30, - 0x02, 0x64, 0xc8, 0x00, - 0x40, 0x3a, 0x74, 0x04, - 0x00, 0xe2, 0x66, 0x58, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x30, 0x3f, 0xc0, 0x09, - 0x30, 0xe0, 0x5a, 0x61, - 0x20, 0x3f, 0x70, 0x69, - 0x10, 0x3f, 0x5a, 0x79, - 0x02, 0xea, 0x7e, 0x00, - 0x00, 0xea, 0x3a, 0x59, - 0x01, 0xea, 0x00, 0x30, - 0x02, 0x48, 0x51, 0x35, - 0x01, 0xea, 0x7e, 0x00, - 0x11, 0xea, 0x3a, 0x59, - 0x11, 0xea, 0x00, 0x00, - 0x02, 0x48, 0x51, 0x35, - 0x08, 0xea, 0x98, 0x00, - 0x08, 0x57, 0xae, 0x00, - 0x08, 0x3c, 0x78, 0x00, - 0xf0, 0x49, 0x68, 0x0a, - 0x0f, 0x67, 0xc0, 0x09, - 0x00, 0x34, 0x69, 0x02, - 0x20, 0xea, 0x96, 0x00, - 0x00, 0xe2, 0xee, 0x41, - 0x40, 0x3a, 0xa4, 0x69, - 0x02, 0x55, 0x06, 0x68, - 0x02, 0x56, 0xa4, 0x69, - 0xff, 0x5b, 0xa4, 0x61, - 0x02, 0x20, 0x51, 0x31, - 0x80, 0xea, 0xb2, 0x01, - 0x44, 0xea, 0x00, 0x00, - 0x01, 0x33, 0xc0, 0x31, - 0x33, 0xea, 0x00, 0x00, - 0xff, 0xea, 0xb2, 0x09, - 0xff, 0xe0, 0xc0, 0x19, - 0xff, 0xe0, 0xa6, 0x79, - 0x02, 0x94, 0x51, 0x31, - 0x00, 0xe2, 0x9c, 0x41, - 0x02, 0x5e, 0x50, 0x31, - 0x02, 0xa8, 0xb8, 0x30, - 0x02, 0x5c, 0x50, 0x31, - 0xff, 0x95, 0xb7, 0x71, - 0x02, 0x94, 0x41, 0x31, - 0x02, 0x22, 0x51, 0x31, - 0x02, 0xa0, 0x2c, 0x33, - 0x02, 0xa0, 0x44, 0x32, - 0x00, 0xe2, 0xc0, 0x41, - 0x10, 0xa8, 0xc1, 0x69, - 0x3d, 0xa9, 0xc9, 0x29, - 0x01, 0xe4, 0xc8, 0x01, - 0x01, 0xea, 0xca, 0x01, - 0xff, 0xea, 0xda, 0x01, - 0x02, 0x20, 0x51, 0x31, - 0x02, 0x96, 0x41, 0x32, - 0xff, 0x21, 0xc9, 0x61, - 0xff, 0xea, 0x46, 0x02, - 0x02, 0x5c, 0x50, 0x31, - 0x40, 0xea, 0x96, 0x00, - 0x02, 0x56, 0xac, 0x6d, - 0x01, 0x55, 0xac, 0x6d, - 0x10, 0xa8, 0xd5, 0x79, - 0x10, 0x40, 0xde, 0x69, - 0x01, 0x56, 0xde, 0x79, - 0xff, 0x93, 0x07, 0x78, - 0x13, 0xea, 0x46, 0x59, - 0x13, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x06, 0x40, - 0xbf, 0x3a, 0x74, 0x08, - 0x08, 0xea, 0x98, 0x00, - 0x08, 0x57, 0xae, 0x00, - 0x01, 0xa9, 0x69, 0x32, - 0x01, 0xaa, 0x6b, 0x32, - 0x40, 0xea, 0x66, 0x02, - 0x08, 0x3c, 0x78, 0x00, - 0x80, 0xea, 0x62, 0x02, - 0x00, 0xe2, 0xa4, 0x5b, - 0x01, 0x36, 0xc1, 0x31, - 0x9f, 0xe0, 0x38, 0x7c, - 0x80, 0xe0, 0x02, 0x72, - 0xa0, 0xe0, 0x3a, 0x72, - 0xc0, 0xe0, 0x30, 0x72, - 0xe0, 0xe0, 0x6a, 0x72, - 0x01, 0xea, 0x46, 0x59, - 0x01, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xee, 0x41, - 0x80, 0x33, 0x09, 0x7a, - 0x03, 0xea, 0x46, 0x59, - 0x03, 0xea, 0x04, 0x00, - 0xee, 0x00, 0x10, 0x6a, - 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x02, 0xa8, 0x90, 0x32, - 0x00, 0xe2, 0x60, 0x59, - 0xef, 0x92, 0xd5, 0x19, - 0x00, 0xe2, 0x20, 0x52, - 0x0b, 0x84, 0xe1, 0x30, - 0x02, 0xea, 0x36, 0x00, - 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0x26, 0x42, - 0x01, 0x92, 0xd1, 0x30, - 0x10, 0x80, 0x89, 0x31, - 0x20, 0xea, 0x32, 0x00, - 0xbf, 0x33, 0x67, 0x0a, - 0x20, 0x19, 0x28, 0x6a, - 0x02, 0x4d, 0xee, 0x69, - 0x40, 0x33, 0x67, 0x02, - 0x00, 0xe2, 0xee, 0x41, - 0x80, 0x33, 0xa7, 0x6a, - 0x01, 0x44, 0x10, 0x33, - 0x08, 0xa8, 0x51, 0x03, - 0x00, 0xe2, 0xee, 0x41, - 0x10, 0xea, 0x80, 0x00, - 0x01, 0x31, 0xc5, 0x31, - 0x80, 0xe2, 0x56, 0x62, - 0x10, 0xa8, 0x7b, 0x6a, - 0xc0, 0xaa, 0xc5, 0x01, - 0x40, 0xa8, 0x47, 0x6a, - 0xbf, 0xe2, 0xc4, 0x09, - 0x20, 0xa8, 0x5b, 0x7a, - 0x01, 0xe2, 0x88, 0x30, - 0x00, 0xe2, 0xa4, 0x5b, - 0xa0, 0x36, 0x63, 0x62, - 0x23, 0xa8, 0x89, 0x08, - 0x00, 0xe2, 0xa4, 0x5b, - 0xa0, 0x36, 0x63, 0x62, - 0x00, 0xa8, 0x5a, 0x42, - 0xff, 0xe2, 0x5a, 0x62, - 0x00, 0xe2, 0x7a, 0x42, - 0x40, 0xea, 0x98, 0x00, - 0x01, 0xe2, 0x88, 0x30, - 0x00, 0xe2, 0xa4, 0x5b, - 0xa0, 0x36, 0x39, 0x72, - 0x40, 0xea, 0x98, 0x00, - 0x01, 0x31, 0x89, 0x32, - 0x08, 0xea, 0x62, 0x02, - 0x00, 0xe2, 0xee, 0x41, - 0xe0, 0xea, 0xb4, 0x5b, - 0x80, 0xe0, 0xb2, 0x6a, - 0x04, 0xe0, 0x52, 0x73, - 0x02, 0xe0, 0x82, 0x73, - 0x00, 0xea, 0x10, 0x73, - 0x03, 0xe0, 0x92, 0x73, - 0x23, 0xe0, 0x8c, 0x72, - 0x08, 0xe0, 0xae, 0x72, - 0x00, 0xe2, 0xa4, 0x5b, - 0x07, 0xea, 0x46, 0x59, - 0x07, 0xea, 0x04, 0x00, - 0x08, 0x42, 0xef, 0x71, - 0x04, 0x42, 0x89, 0x62, - 0x01, 0x43, 0x89, 0x30, - 0x00, 0xe2, 0x7a, 0x42, - 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0x7a, 0x42, - 0x01, 0x00, 0x60, 0x32, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x4c, 0x34, 0xc1, 0x28, - 0x01, 0x64, 0xc0, 0x31, - 0x00, 0x30, 0x3b, 0x59, - 0x01, 0x30, 0x01, 0x30, - 0x01, 0xe0, 0xac, 0x7a, - 0xa0, 0xea, 0xaa, 0x5b, - 0x01, 0xa0, 0xac, 0x62, - 0x01, 0x84, 0xa5, 0x7a, - 0x01, 0xa7, 0xae, 0x7a, - 0x00, 0xe2, 0xae, 0x42, - 0x03, 0xea, 0x46, 0x59, - 0x03, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xae, 0x42, - 0x07, 0xea, 0xbc, 0x5b, - 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0xee, 0x41, - 0x3f, 0xe0, 0x6a, 0x0a, - 0xc0, 0x34, 0xc1, 0x09, - 0x00, 0x35, 0x51, 0x01, - 0xff, 0xea, 0x52, 0x09, - 0x30, 0x34, 0xc5, 0x09, - 0x3d, 0xe2, 0xc4, 0x29, - 0xb8, 0xe2, 0xc4, 0x19, - 0x01, 0xea, 0xc6, 0x01, - 0x02, 0xe2, 0xc8, 0x31, - 0x02, 0xec, 0x40, 0x31, - 0xff, 0xa1, 0xce, 0x72, - 0x02, 0xe8, 0xda, 0x31, - 0x02, 0xa0, 0x50, 0x31, - 0x00, 0xe2, 0xf0, 0x42, - 0x80, 0x33, 0x67, 0x02, - 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0xa4, 0x5b, - 0x01, 0x33, 0x67, 0x02, - 0xe0, 0x36, 0x0b, 0x63, - 0x02, 0x33, 0x67, 0x02, - 0x20, 0x46, 0x04, 0x63, - 0xff, 0xea, 0x52, 0x09, - 0xa8, 0xea, 0xaa, 0x5b, - 0x04, 0xa8, 0xeb, 0x7a, - 0x01, 0x34, 0xc1, 0x31, - 0x00, 0xa9, 0xeb, 0x62, - 0x01, 0x35, 0xc1, 0x31, - 0x00, 0xaa, 0xf5, 0x72, - 0x01, 0xa9, 0x52, 0x11, - 0xff, 0xa9, 0xe0, 0x6a, - 0x00, 0xe2, 0x04, 0x43, - 0x10, 0x33, 0x67, 0x02, - 0x04, 0xa8, 0x05, 0x7b, - 0xfb, 0xa8, 0x51, 0x0b, - 0xff, 0xea, 0x66, 0x0a, - 0x01, 0xa4, 0xff, 0x6a, - 0x02, 0xa8, 0x90, 0x32, - 0x00, 0xe2, 0x60, 0x59, - 0x10, 0xa8, 0xaf, 0x7a, - 0xff, 0xea, 0xbc, 0x5b, - 0x00, 0xe2, 0xae, 0x42, - 0x04, 0xea, 0x46, 0x59, - 0x04, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xae, 0x42, - 0x04, 0xea, 0x46, 0x59, - 0x04, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xee, 0x41, - 0x08, 0xa8, 0xa7, 0x7a, - 0xc0, 0x33, 0x1b, 0x7b, - 0x80, 0x33, 0xa7, 0x6a, - 0xff, 0x88, 0x1b, 0x6b, - 0x40, 0x33, 0xa7, 0x6a, - 0x10, 0xa8, 0x21, 0x7b, - 0x0a, 0xea, 0x46, 0x59, - 0x0a, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x3a, 0x5b, - 0x00, 0xe2, 0x6e, 0x43, - 0x50, 0x4b, 0x28, 0x6b, - 0xbf, 0x3a, 0x74, 0x08, - 0x01, 0xe0, 0xf8, 0x31, - 0xff, 0xea, 0xc0, 0x09, - 0x01, 0x2e, 0x5d, 0x1a, - 0x00, 0x2f, 0x5f, 0x22, - 0x04, 0x47, 0x8f, 0x02, - 0x01, 0xfc, 0xc0, 0x35, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x02, 0x42, 0x51, 0x31, - 0x10, 0xa8, 0x51, 0x03, - 0xff, 0x88, 0x49, 0x6b, - 0x01, 0xa4, 0x45, 0x6b, - 0x02, 0xa4, 0x4d, 0x6b, - 0x01, 0x84, 0x4d, 0x7b, - 0x02, 0x28, 0x19, 0x33, - 0x02, 0xa8, 0x50, 0x36, - 0xff, 0x88, 0x4d, 0x73, - 0x00, 0xe2, 0x24, 0x5b, - 0x02, 0x2c, 0x19, 0x33, - 0x02, 0xa8, 0x58, 0x32, - 0x04, 0xa4, 0x49, 0x07, - 0xc0, 0x33, 0xa7, 0x6a, - 0x04, 0xa8, 0x51, 0x03, - 0x20, 0xa8, 0x6f, 0x6b, - 0x02, 0xa8, 0x40, 0x31, - 0xc0, 0x34, 0xc1, 0x09, - 0x00, 0x35, 0x51, 0x01, - 0xff, 0xea, 0x52, 0x09, - 0x30, 0x34, 0xc5, 0x09, - 0x3d, 0xe2, 0xc4, 0x29, - 0xb8, 0xe2, 0xc4, 0x19, - 0x01, 0xea, 0xc6, 0x01, - 0x02, 0xe2, 0xc8, 0x31, - 0x02, 0xa0, 0xda, 0x31, - 0x02, 0xa0, 0x50, 0x31, - 0xf7, 0x57, 0xae, 0x08, - 0x08, 0xea, 0x98, 0x00, - 0x01, 0x44, 0xd4, 0x31, - 0xee, 0x00, 0x78, 0x6b, - 0x02, 0xea, 0xb4, 0x00, - 0x00, 0xe2, 0xa0, 0x5b, - 0x09, 0x4c, 0x7a, 0x7b, - 0x08, 0x4c, 0x06, 0x68, - 0x0b, 0xea, 0x46, 0x59, - 0x0b, 0xea, 0x04, 0x00, - 0x01, 0x44, 0xd4, 0x31, - 0x20, 0x33, 0xef, 0x79, - 0x00, 0xe2, 0x8a, 0x5b, - 0x00, 0xe2, 0xee, 0x41, - 0x01, 0x84, 0x8f, 0x7b, - 0x01, 0xa4, 0x49, 0x07, - 0x08, 0x60, 0x30, 0x33, - 0x08, 0x80, 0x41, 0x37, - 0xdf, 0x33, 0x67, 0x0a, - 0xee, 0x00, 0x9c, 0x6b, - 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x00, 0xe2, 0x60, 0x59, - 0x00, 0xe2, 0xae, 0x42, - 0x01, 0xea, 0x6c, 0x02, - 0xc0, 0xea, 0x66, 0x06, - 0xff, 0x42, 0xa4, 0x7b, - 0x04, 0x4c, 0xa4, 0x6b, - 0xe0, 0x41, 0x6c, 0x0e, - 0x01, 0x44, 0xd4, 0x31, - 0xff, 0x42, 0xac, 0x7b, - 0x04, 0x4c, 0xac, 0x6b, - 0xe0, 0x41, 0x6c, 0x0a, - 0xe0, 0x36, 0xef, 0x61, - 0xff, 0xea, 0xca, 0x09, - 0x01, 0xe2, 0xc8, 0x31, - 0x01, 0x46, 0xda, 0x35, - 0x01, 0x44, 0xd4, 0x35, - 0x10, 0xea, 0x80, 0x00, - 0x01, 0xe2, 0x62, 0x36, - 0x04, 0xa6, 0xc4, 0x7b, - 0xff, 0xea, 0x5a, 0x09, - 0xff, 0xea, 0x4c, 0x0d, - 0x01, 0xa6, 0xe2, 0x6b, - 0x10, 0xad, 0x66, 0x7d, - 0x80, 0xad, 0xda, 0x6b, - 0x08, 0xad, 0x66, 0x6d, - 0x04, 0x84, 0xf9, 0x30, - 0x00, 0xea, 0x08, 0x81, - 0xff, 0xea, 0xd4, 0x09, - 0x02, 0x84, 0xf9, 0x88, - 0x1d, 0xea, 0x5a, 0x01, - 0x04, 0xa6, 0x4c, 0x05, - 0x04, 0xa6, 0x66, 0x7d, - 0xff, 0xea, 0x5a, 0x09, - 0x03, 0x84, 0x59, 0x89, - 0x03, 0xea, 0x4c, 0x01, - 0x80, 0x1a, 0x66, 0x7d, - 0x08, 0xb0, 0xe0, 0x30, - 0x04, 0xb0, 0xe0, 0x30, - 0x03, 0xb0, 0xf0, 0x30, - 0x01, 0x78, 0xee, 0x7b, - 0x01, 0xa7, 0x4e, 0x11, - 0x01, 0xb0, 0x06, 0x33, - 0x7f, 0x83, 0xe9, 0x08, - 0x04, 0xac, 0x58, 0x19, - 0xff, 0xea, 0xc0, 0x09, - 0x04, 0x84, 0x09, 0x9b, - 0x00, 0x85, 0x0b, 0x23, - 0x00, 0x86, 0x0d, 0x23, - 0x00, 0x87, 0x0f, 0x23, - 0x01, 0x84, 0xc5, 0x31, - 0x01, 0xa7, 0x04, 0x7c, - 0x04, 0xe2, 0xc4, 0x01, - 0x80, 0x83, 0x0b, 0x7c, - 0x02, 0xe2, 0xc4, 0x01, - 0xff, 0xea, 0x4c, 0x09, - 0x01, 0xe2, 0x36, 0x30, - 0xc8, 0x19, 0x32, 0x00, - 0x88, 0x19, 0x32, 0x00, - 0x01, 0xac, 0xd4, 0x99, - 0x00, 0xe2, 0x66, 0x55, - 0xfe, 0xa6, 0x4c, 0x0d, - 0x0b, 0x98, 0xe1, 0x30, - 0x01, 0xa0, 0x4f, 0x09, - 0xfd, 0xa4, 0x49, 0x09, - 0x80, 0xa3, 0x21, 0x7c, - 0x02, 0xa4, 0x48, 0x01, - 0x01, 0xa7, 0x24, 0x7c, - 0x04, 0xa4, 0x48, 0x01, - 0x01, 0xa4, 0x36, 0x30, - 0xa8, 0xea, 0x32, 0x00, - 0xfd, 0xa4, 0x49, 0x0b, - 0x05, 0xa3, 0x07, 0x33, - 0x80, 0x83, 0x31, 0x6c, - 0x02, 0xea, 0x4c, 0x05, - 0xff, 0xea, 0x4c, 0x0d, - 0x00, 0xe2, 0x32, 0x59, - 0x02, 0xa6, 0xc6, 0x6b, - 0x80, 0xf9, 0xf2, 0x05, - 0xc0, 0x33, 0x3f, 0x7c, - 0x03, 0xea, 0x46, 0x59, - 0x03, 0xea, 0x04, 0x00, - 0x20, 0x33, 0x63, 0x7c, - 0x01, 0x84, 0x49, 0x6c, - 0x06, 0xea, 0x46, 0x59, - 0x06, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x66, 0x44, - 0x01, 0x00, 0x60, 0x32, - 0xee, 0x00, 0x52, 0x6c, - 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x3a, 0x59, - 0x33, 0xea, 0x00, 0x00, - 0x80, 0x3d, 0x7a, 0x00, - 0xfc, 0x42, 0x54, 0x7c, - 0x7f, 0x3d, 0x7a, 0x08, - 0x00, 0x30, 0x3b, 0x59, - 0x01, 0x30, 0x01, 0x30, - 0x09, 0xea, 0x46, 0x59, - 0x09, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xee, 0x41, - 0x01, 0xa4, 0x49, 0x6c, - 0x00, 0xe2, 0x16, 0x5c, - 0x20, 0x33, 0x67, 0x02, - 0x01, 0x00, 0x60, 0x32, - 0x02, 0xa6, 0x6e, 0x7c, - 0x00, 0xe2, 0x32, 0x5c, - 0x00, 0xe2, 0x66, 0x58, - 0x00, 0xe2, 0x76, 0x58, - 0x00, 0xe2, 0x30, 0x58, - 0x00, 0x30, 0x3b, 0x59, - 0x01, 0x30, 0x01, 0x30, - 0x20, 0x19, 0x6e, 0x6c, - 0x00, 0xe2, 0x96, 0x5c, - 0x04, 0x19, 0x88, 0x6c, - 0x02, 0x19, 0x32, 0x00, - 0x01, 0x84, 0x89, 0x7c, - 0x01, 0x1b, 0x82, 0x7c, - 0x01, 0x1a, 0x88, 0x6c, - 0x00, 0xe2, 0x38, 0x44, - 0x80, 0x4b, 0x8e, 0x6c, - 0x01, 0x4c, 0x8a, 0x7c, - 0x03, 0x42, 0x38, 0x6c, - 0x00, 0xe2, 0xc0, 0x5b, - 0x80, 0xf9, 0xf2, 0x01, - 0x04, 0x33, 0xef, 0x79, - 0x00, 0xe2, 0xee, 0x41, - 0x02, 0x1b, 0x9e, 0x7c, - 0x08, 0x5d, 0x9c, 0x7c, - 0x03, 0x68, 0x00, 0x37, - 0x01, 0x84, 0x09, 0x07, - 0x08, 0x5d, 0xa8, 0x6c, - 0x00, 0xe2, 0x66, 0x58, - 0x00, 0x30, 0x3b, 0x59, - 0x01, 0x30, 0x01, 0x30, - 0x00, 0xe2, 0x96, 0x44, - 0x80, 0x1b, 0xb2, 0x7c, - 0x80, 0x84, 0xb3, 0x6c, - 0xff, 0x85, 0x0b, 0x1b, - 0xff, 0x86, 0x0d, 0x23, - 0xff, 0x87, 0x0f, 0x23, - 0xf8, 0x1b, 0x08, 0x0b, - 0xff, 0xea, 0x4e, 0x09, - 0x04, 0x1b, 0xba, 0x7c, - 0x01, 0xa7, 0x4e, 0x01, - 0xff, 0xea, 0x06, 0x0b, - 0x03, 0x68, 0x00, 0x37, - 0x00, 0xe2, 0xb6, 0x58, - 0x10, 0xea, 0x18, 0x00, - 0xf9, 0xd9, 0xb2, 0x0d, - 0x01, 0xd9, 0xb2, 0x05, - 0xff, 0xea, 0xd4, 0x09, - 0x10, 0x5b, 0xde, 0x6c, - 0x08, 0x5b, 0xe6, 0x6c, - 0x20, 0x5b, 0xd4, 0x6c, - 0x02, 0x5b, 0xfa, 0x6d, - 0x0e, 0xea, 0x46, 0x59, - 0x0e, 0xea, 0x04, 0x00, - 0x08, 0x19, 0xda, 0x7c, - 0xdf, 0x5c, 0xb8, 0x08, - 0x01, 0xd9, 0xb2, 0x05, - 0x02, 0xea, 0xb4, 0x00, - 0x01, 0xd9, 0xb2, 0x05, - 0x01, 0xa4, 0xc3, 0x6d, - 0x00, 0xe2, 0x16, 0x5c, - 0x00, 0xe2, 0x06, 0x5d, - 0x01, 0xd9, 0xb2, 0x05, - 0x00, 0xe2, 0x24, 0x5b, - 0xf3, 0x92, 0xd5, 0x19, - 0x00, 0xe2, 0xf4, 0x54, - 0x80, 0x92, 0xf5, 0x6c, - 0x0f, 0xea, 0x46, 0x59, - 0x0f, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xfc, 0x44, - 0x04, 0x8c, 0xe1, 0x30, - 0x01, 0xea, 0xf2, 0x00, - 0x02, 0xea, 0x36, 0x00, - 0xa8, 0xea, 0x32, 0x00, - 0xff, 0x93, 0x03, 0x7d, - 0x14, 0xea, 0x46, 0x59, - 0x14, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x88, 0x5d, - 0x01, 0xd9, 0xb2, 0x05, - 0x02, 0xa8, 0xf4, 0x31, - 0x02, 0xa6, 0x18, 0x7d, - 0x00, 0xe2, 0x34, 0x59, - 0x20, 0x5b, 0x26, 0x6d, - 0xfc, 0x42, 0x12, 0x7d, - 0x10, 0x40, 0x14, 0x6d, - 0x20, 0x4d, 0x16, 0x7d, - 0x08, 0x5d, 0x26, 0x6d, - 0x02, 0xa6, 0xc6, 0x6b, - 0x00, 0xe2, 0x34, 0x59, - 0x20, 0x5b, 0x26, 0x6d, - 0x01, 0x1b, 0x46, 0x6d, - 0xfc, 0x42, 0x22, 0x7d, - 0x10, 0x40, 0x24, 0x6d, - 0x20, 0x4d, 0x66, 0x7d, - 0x08, 0x5d, 0x66, 0x7d, - 0x02, 0x19, 0x32, 0x00, - 0x01, 0x5b, 0x40, 0x31, - 0x00, 0xe2, 0x96, 0x5c, - 0x00, 0xe2, 0x8a, 0x5b, - 0x20, 0xea, 0xb6, 0x00, - 0x00, 0xe2, 0xc0, 0x5b, - 0x20, 0x5c, 0xb8, 0x00, - 0x04, 0x19, 0x3c, 0x6d, - 0x01, 0x1a, 0x3c, 0x6d, - 0x00, 0xe2, 0x34, 0x59, - 0x01, 0x1a, 0x66, 0x7d, - 0x80, 0xf9, 0xf2, 0x01, - 0x20, 0xa0, 0xac, 0x7d, - 0x08, 0xa8, 0x45, 0x7d, - 0x00, 0xe2, 0x58, 0x45, - 0x02, 0xea, 0xb4, 0x04, - 0x02, 0x19, 0x32, 0x00, - 0x08, 0xa8, 0x69, 0x7d, - 0x04, 0x5d, 0xc2, 0x7d, - 0x01, 0x1a, 0xc2, 0x7d, - 0x01, 0xa4, 0x49, 0x03, - 0x80, 0xf9, 0xf2, 0x01, - 0x02, 0xa8, 0x84, 0x32, - 0x02, 0xea, 0xb4, 0x00, - 0x00, 0xe2, 0x34, 0x43, - 0x02, 0xa8, 0x84, 0x32, - 0x02, 0xea, 0xb4, 0x00, - 0xff, 0xea, 0xd4, 0x19, - 0x00, 0xe2, 0x40, 0x59, - 0x11, 0x00, 0x00, 0x10, - 0x00, 0xe2, 0x98, 0x5d, - 0x00, 0xe2, 0x34, 0x53, - 0xff, 0xea, 0xd4, 0x0d, - 0x00, 0xe2, 0x34, 0x59, - 0x40, 0x5b, 0x74, 0x6d, - 0x04, 0x5d, 0xc2, 0x7d, - 0x01, 0x1a, 0xc2, 0x7d, - 0x20, 0x4d, 0x66, 0x7d, - 0x40, 0x5b, 0xac, 0x7d, - 0x04, 0x5d, 0xc2, 0x7d, - 0x01, 0x1a, 0xc2, 0x7d, - 0x80, 0xf9, 0xf2, 0x01, - 0x01, 0xa4, 0x49, 0x03, - 0x08, 0xa8, 0x59, 0x6d, - 0x02, 0xea, 0xb4, 0x04, - 0xff, 0x6a, 0x8e, 0x7d, - 0x10, 0xea, 0x46, 0x59, - 0x10, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x8e, 0x45, - 0x00, 0xe2, 0x32, 0x59, - 0x10, 0x5d, 0x80, 0x6d, - 0x40, 0x5b, 0x66, 0x7d, - 0x02, 0x19, 0x32, 0x00, - 0x80, 0xf9, 0xf2, 0x01, - 0xff, 0xea, 0x10, 0x03, - 0x08, 0xa8, 0x51, 0x03, - 0x00, 0xe2, 0x58, 0x45, - 0x80, 0xf9, 0x66, 0x6d, - 0x01, 0x43, 0xc1, 0x31, - 0x00, 0xfb, 0x66, 0x65, - 0x01, 0x42, 0xc1, 0x31, - 0x00, 0xfa, 0x66, 0x65, - 0x01, 0xe8, 0xd4, 0x1d, - 0x30, 0x3f, 0xc0, 0x09, - 0x30, 0xe0, 0x66, 0x65, - 0x40, 0x4b, 0x66, 0x6d, - 0xff, 0xea, 0x52, 0x01, - 0xee, 0x00, 0xb2, 0x6d, - 0x80, 0xf9, 0xf2, 0x01, - 0x02, 0xea, 0xb4, 0x00, - 0x20, 0xea, 0x9a, 0x00, - 0xf3, 0x42, 0xbc, 0x6d, - 0x12, 0xea, 0x46, 0x59, - 0x12, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xee, 0x41, - 0x0d, 0xea, 0x46, 0x59, - 0x0d, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xee, 0x41, - 0x11, 0xea, 0x46, 0x59, - 0x11, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x24, 0x5b, - 0x08, 0x5a, 0xb4, 0x00, - 0x00, 0xe2, 0xe4, 0x5d, - 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0x34, 0x59, - 0x80, 0x1a, 0xd6, 0x7d, - 0x00, 0xe2, 0xe4, 0x5d, - 0x80, 0x19, 0x32, 0x00, - 0x40, 0x5b, 0xdc, 0x6d, - 0x08, 0x5a, 0xdc, 0x7d, - 0x20, 0x4d, 0x66, 0x7d, - 0x02, 0x84, 0x09, 0x03, - 0x40, 0x5b, 0xac, 0x7d, - 0x08, 0xa8, 0x51, 0x6d, - 0x02, 0xea, 0xb4, 0x04, - 0x01, 0x38, 0xe1, 0x30, - 0x05, 0x39, 0xe3, 0x98, - 0x01, 0xe0, 0xf8, 0x31, - 0xff, 0xea, 0xc0, 0x09, - 0x00, 0x3a, 0xe5, 0x20, - 0x00, 0x3b, 0xe7, 0x20, - 0x01, 0xfc, 0xc0, 0x31, - 0x04, 0xea, 0xe8, 0x30, - 0xff, 0xea, 0xf0, 0x08, - 0x02, 0xea, 0xf2, 0x00, - 0xff, 0xea, 0xf4, 0x0c -}; - -typedef int ahd_patch_func_t (struct ahd_softc *ahd); -static ahd_patch_func_t ahd_patch18_func; - -static int -ahd_patch18_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch17_func; - -static int -ahd_patch17_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0); -} - -static ahd_patch_func_t ahd_patch16_func; - -static int -ahd_patch16_func(struct ahd_softc *ahd) -{ - return ((ahd->flags & AHD_INITIATORROLE) != 0); -} - -static ahd_patch_func_t ahd_patch15_func; - -static int -ahd_patch15_func(struct ahd_softc *ahd) -{ - return ((ahd->flags & AHD_TARGETROLE) != 0); -} - -static ahd_patch_func_t ahd_patch14_func; - -static int -ahd_patch14_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch13_func; - -static int -ahd_patch13_func(struct ahd_softc *ahd) -{ - return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0); -} - -static ahd_patch_func_t ahd_patch12_func; - -static int -ahd_patch12_func(struct ahd_softc *ahd) -{ - return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0); -} - -static ahd_patch_func_t ahd_patch11_func; - -static int -ahd_patch11_func(struct ahd_softc *ahd) -{ - return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0); -} - -static ahd_patch_func_t ahd_patch10_func; - -static int -ahd_patch10_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch9_func; - -static int -ahd_patch9_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0); -} - -static ahd_patch_func_t ahd_patch8_func; - -static int -ahd_patch8_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0); -} - -static ahd_patch_func_t ahd_patch7_func; - -static int -ahd_patch7_func(struct ahd_softc *ahd) -{ - return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0); -} - -static ahd_patch_func_t ahd_patch6_func; - -static int -ahd_patch6_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch5_func; - -static int -ahd_patch5_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch4_func; - -static int -ahd_patch4_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch3_func; - -static int -ahd_patch3_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch2_func; - -static int -ahd_patch2_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_SET_MODE_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch1_func; - -static int -ahd_patch1_func(struct ahd_softc *ahd) -{ - return ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0); -} - -static ahd_patch_func_t ahd_patch0_func; - -static int -ahd_patch0_func(struct ahd_softc *ahd) -{ - return (0); -} - -static struct patch { - ahd_patch_func_t *patch_func; - uint32_t begin :10, - skip_instr :10, - skip_patch :12; -} patches[] = { - { ahd_patch1_func, 0, 3, 3 }, - { ahd_patch1_func, 1, 1, 2 }, - { ahd_patch0_func, 2, 1, 1 }, - { ahd_patch1_func, 3, 3, 3 }, - { ahd_patch1_func, 4, 1, 2 }, - { ahd_patch0_func, 5, 1, 1 }, - { ahd_patch2_func, 6, 1, 2 }, - { ahd_patch0_func, 7, 1, 1 }, - { ahd_patch2_func, 24, 1, 2 }, - { ahd_patch0_func, 25, 1, 1 }, - { ahd_patch1_func, 32, 1, 2 }, - { ahd_patch0_func, 33, 1, 1 }, - { ahd_patch2_func, 40, 1, 2 }, - { ahd_patch0_func, 41, 1, 1 }, - { ahd_patch2_func, 44, 1, 2 }, - { ahd_patch0_func, 45, 1, 1 }, - { ahd_patch2_func, 48, 1, 2 }, - { ahd_patch0_func, 49, 1, 1 }, - { ahd_patch2_func, 51, 1, 2 }, - { ahd_patch0_func, 52, 1, 1 }, - { ahd_patch2_func, 55, 1, 2 }, - { ahd_patch0_func, 56, 1, 1 }, - { ahd_patch2_func, 59, 1, 2 }, - { ahd_patch0_func, 60, 1, 1 }, - { ahd_patch2_func, 157, 6, 1 }, - { ahd_patch1_func, 163, 2, 1 }, - { ahd_patch3_func, 165, 1, 1 }, - { ahd_patch2_func, 174, 1, 2 }, - { ahd_patch0_func, 175, 1, 1 }, - { ahd_patch4_func, 176, 2, 2 }, - { ahd_patch0_func, 178, 6, 3 }, - { ahd_patch2_func, 181, 1, 2 }, - { ahd_patch0_func, 182, 1, 1 }, - { ahd_patch2_func, 185, 1, 2 }, - { ahd_patch0_func, 186, 1, 1 }, - { ahd_patch5_func, 188, 2, 1 }, - { ahd_patch3_func, 196, 16, 2 }, - { ahd_patch0_func, 212, 1, 1 }, - { ahd_patch6_func, 232, 2, 1 }, - { ahd_patch1_func, 236, 1, 2 }, - { ahd_patch0_func, 237, 1, 1 }, - { ahd_patch5_func, 240, 2, 1 }, - { ahd_patch1_func, 254, 1, 2 }, - { ahd_patch0_func, 255, 1, 1 }, - { ahd_patch1_func, 258, 1, 2 }, - { ahd_patch0_func, 259, 1, 1 }, - { ahd_patch2_func, 262, 1, 2 }, - { ahd_patch0_func, 263, 1, 1 }, - { ahd_patch1_func, 318, 1, 2 }, - { ahd_patch0_func, 319, 1, 1 }, - { ahd_patch2_func, 327, 1, 2 }, - { ahd_patch0_func, 328, 1, 1 }, - { ahd_patch2_func, 331, 1, 2 }, - { ahd_patch0_func, 332, 1, 1 }, - { ahd_patch1_func, 339, 1, 2 }, - { ahd_patch0_func, 340, 1, 1 }, - { ahd_patch7_func, 359, 1, 1 }, - { ahd_patch7_func, 362, 1, 1 }, - { ahd_patch7_func, 364, 1, 1 }, - { ahd_patch7_func, 376, 1, 1 }, - { ahd_patch1_func, 386, 1, 2 }, - { ahd_patch0_func, 387, 1, 1 }, - { ahd_patch1_func, 389, 1, 2 }, - { ahd_patch0_func, 390, 1, 1 }, - { ahd_patch1_func, 398, 1, 2 }, - { ahd_patch0_func, 399, 1, 1 }, - { ahd_patch2_func, 410, 1, 2 }, - { ahd_patch0_func, 411, 1, 1 }, - { ahd_patch8_func, 413, 1, 1 }, - { ahd_patch9_func, 440, 1, 1 }, - { ahd_patch1_func, 447, 1, 2 }, - { ahd_patch0_func, 448, 1, 1 }, - { ahd_patch2_func, 460, 1, 2 }, - { ahd_patch0_func, 461, 1, 1 }, - { ahd_patch10_func, 489, 1, 1 }, - { ahd_patch11_func, 498, 1, 2 }, - { ahd_patch0_func, 499, 1, 1 }, - { ahd_patch12_func, 504, 1, 1 }, - { ahd_patch11_func, 505, 1, 1 }, - { ahd_patch13_func, 518, 1, 2 }, - { ahd_patch0_func, 519, 1, 1 }, - { ahd_patch1_func, 541, 1, 2 }, - { ahd_patch0_func, 542, 1, 1 }, - { ahd_patch1_func, 545, 1, 2 }, - { ahd_patch0_func, 546, 1, 1 }, - { ahd_patch2_func, 551, 1, 2 }, - { ahd_patch0_func, 552, 1, 1 }, - { ahd_patch2_func, 556, 1, 2 }, - { ahd_patch0_func, 557, 1, 1 }, - { ahd_patch1_func, 558, 1, 2 }, - { ahd_patch0_func, 559, 1, 1 }, - { ahd_patch2_func, 570, 1, 2 }, - { ahd_patch0_func, 571, 1, 1 }, - { ahd_patch14_func, 575, 1, 1 }, - { ahd_patch15_func, 580, 1, 1 }, - { ahd_patch16_func, 581, 2, 1 }, - { ahd_patch15_func, 585, 1, 2 }, - { ahd_patch0_func, 586, 1, 1 }, - { ahd_patch2_func, 593, 1, 2 }, - { ahd_patch0_func, 594, 1, 1 }, - { ahd_patch2_func, 609, 1, 2 }, - { ahd_patch0_func, 610, 1, 1 }, - { ahd_patch1_func, 616, 1, 2 }, - { ahd_patch0_func, 617, 1, 1 }, - { ahd_patch1_func, 631, 1, 2 }, - { ahd_patch0_func, 632, 1, 1 }, - { ahd_patch1_func, 639, 1, 2 }, - { ahd_patch0_func, 640, 1, 1 }, - { ahd_patch14_func, 659, 1, 1 }, - { ahd_patch14_func, 675, 1, 1 }, - { ahd_patch2_func, 687, 1, 2 }, - { ahd_patch0_func, 688, 1, 1 }, - { ahd_patch1_func, 705, 1, 2 }, - { ahd_patch0_func, 706, 1, 1 }, - { ahd_patch14_func, 711, 1, 1 }, - { ahd_patch1_func, 731, 1, 2 }, - { ahd_patch0_func, 732, 1, 1 }, - { ahd_patch1_func, 734, 1, 2 }, - { ahd_patch0_func, 735, 1, 1 }, - { ahd_patch1_func, 737, 1, 2 }, - { ahd_patch0_func, 738, 1, 1 }, - { ahd_patch17_func, 740, 1, 2 }, - { ahd_patch0_func, 741, 2, 1 }, - { ahd_patch18_func, 744, 4, 2 }, - { ahd_patch0_func, 748, 1, 1 }, - { ahd_patch18_func, 754, 11, 1 } -}; - -static struct cs { - uint16_t begin; - uint16_t end; -} critical_sections[] = { - { 11, 12 }, - { 13, 14 }, - { 24, 37 }, - { 38, 51 }, - { 64, 67 }, - { 94, 119 }, - { 120, 151 }, - { 153, 157 }, - { 165, 173 }, - { 196, 245 }, - { 659, 675 }, - { 675, 693 }, - { 698, 704 }, - { 711, 716 }, - { 716, 722 } -}; - -static const int num_critical_sections = sizeof(critical_sections) - / sizeof(*critical_sections); diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/Makefile linux-2.4.22/drivers/scsi/aic79xx/aicasm/Makefile --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/Makefile 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,65 +0,0 @@ -PROG= aicasm - -.SUFFIXES= .l .y .c .h - -CSRCS= aicasm.c aicasm_symbol.c -YSRCS= aicasm_gram.y aicasm_macro_gram.y -LSRCS= aicasm_scan.l aicasm_macro_scan.l - -GENHDRS= aicdb.h $(YSRCS:.y=.h) -GENSRCS= $(YSRCS:.y=.c) $(LSRCS:.l=.c) - -SRCS= ${CSRCS} ${GENSRCS} -CLEANFILES= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) -# Override default kernel CFLAGS. This is a userland app. -AICASM_CFLAGS:= -I/usr/include -I. -ldb -YFLAGS= -d - -NOMAN= noman - -ifneq ($(HOSTCC),) -AICASM_CC= $(HOSTCC) -else -AICASM_CC= $(CC) -endif - -ifdef DEBUG -CFLAGS+= -DDEBUG -g -YFLAGS+= -t -v -LFLAGS= -d -endif - -$(PROG): ${GENHDRS} $(SRCS) - $(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) - -aicdb.h: - @if [ -e "/usr/include/db3/db_185.h" ]; then \ - echo "#include " > aicdb.h; \ - elif [ -e "/usr/include/db2/db_185.h" ]; then \ - echo "#include " > aicdb.h; \ - elif [ -e "/usr/include/db/db_185.h" ]; then \ - echo "#include " > aicdb.h; \ - elif [ -e "/usr/include/db_185.h" ]; then \ - echo "#include " > aicdb.h; \ - else \ - echo "*** Install db development libraries"; \ - fi - -clean: - rm -f $(CLEANFILES) $(PROG) - -aicasm_gram.c aicasm_gram.h: aicasm_gram.y - $(YACC) $(YFLAGS) -b $(<:.y=) $< - mv $(<:.y=).tab.c $(<:.y=.c) - mv $(<:.y=).tab.h $(<:.y=.h) - -aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y - $(YACC) $(YFLAGS) -b $(<:.y=) -p mm $< - mv $(<:.y=).tab.c $(<:.y=.c) - mv $(<:.y=).tab.h $(<:.y=.h) - -aicasm_scan.c: aicasm_scan.l - $(LEX) $(LFLAGS) -o$@ $< - -aicasm_macro_scan.c: aicasm_macro_scan.l - $(LEX) $(LFLAGS) -Pmm -o$@ $< diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm.c linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm.c --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,835 +0,0 @@ -/* - * Aic7xxx SCSI host adapter firmware asssembler - * - * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs. - * Copyright (c) 2001, 2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 $ - * - * $FreeBSD$ - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if linux -#include -#else -#include -#endif - -#include "aicasm.h" -#include "aicasm_symbol.h" -#include "aicasm_insformat.h" - -typedef struct patch { - STAILQ_ENTRY(patch) links; - int patch_func; - u_int begin; - u_int skip_instr; - u_int skip_patch; -} patch_t; - -STAILQ_HEAD(patch_list, patch) patches; - -static void usage(void); -static void back_patch(void); -static void output_code(void); -static void output_listing(char *ifilename); -static void dump_scope(scope_t *scope); -static void emit_patch(scope_t *scope, int patch); -static int check_patch(patch_t **start_patch, int start_instr, - int *skip_addr, int *func_vals); - -struct path_list search_path; -int includes_search_curdir; -char *appname; -char *stock_include_file; -FILE *ofile; -char *ofilename; -char *regfilename; -FILE *regfile; -char *listfilename; -FILE *listfile; -char *regdiagfilename; -FILE *regdiagfile; -int src_mode; -int dst_mode; - -static STAILQ_HEAD(,instruction) seq_program; -struct cs_tailq cs_tailq; -struct scope_list scope_stack; -symlist_t patch_functions; - -#if DEBUG -extern int yy_flex_debug; -extern int mm_flex_debug; -extern int yydebug; -extern int mmdebug; -#endif -extern FILE *yyin; -extern int yyparse(void); - -int main(int argc, char *argv[]); - -int -main(int argc, char *argv[]) -{ - extern char *optarg; - extern int optind; - int ch; - int retval; - char *inputfilename; - scope_t *sentinal; - - STAILQ_INIT(&patches); - SLIST_INIT(&search_path); - STAILQ_INIT(&seq_program); - TAILQ_INIT(&cs_tailq); - SLIST_INIT(&scope_stack); - - /* Set Sentinal scope node */ - sentinal = scope_alloc(); - sentinal->type = SCOPE_ROOT; - - includes_search_curdir = 1; - appname = *argv; - regfile = NULL; - listfile = NULL; -#if DEBUG - yy_flex_debug = 0; - mm_flex_debug = 0; - yydebug = 0; - mmdebug = 0; -#endif - while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) { - switch(ch) { - case 'd': -#if DEBUG - if (strcmp(optarg, "s") == 0) { - yy_flex_debug = 1; - mm_flex_debug = 1; - } else if (strcmp(optarg, "p") == 0) { - yydebug = 1; - mmdebug = 1; - } else { - fprintf(stderr, "%s: -d Requires either an " - "'s' or 'p' argument\n", appname); - usage(); - } -#else - stop("-d: Assembler not built with debugging " - "information", EX_SOFTWARE); -#endif - break; - case 'i': - stock_include_file = optarg; - break; - case 'l': - /* Create a program listing */ - if ((listfile = fopen(optarg, "w")) == NULL) { - perror(optarg); - stop(NULL, EX_CANTCREAT); - } - listfilename = optarg; - break; - case 'n': - /* Don't complain about the -nostdinc directrive */ - if (strcmp(optarg, "ostdinc")) { - fprintf(stderr, "%s: Unknown option -%c%s\n", - appname, ch, optarg); - usage(); - /* NOTREACHED */ - } - break; - case 'o': - if ((ofile = fopen(optarg, "w")) == NULL) { - perror(optarg); - stop(NULL, EX_CANTCREAT); - } - ofilename = optarg; - break; - case 'p': - /* Create Register Diagnostic "printing" Functions */ - if ((regdiagfile = fopen(optarg, "w")) == NULL) { - perror(optarg); - stop(NULL, EX_CANTCREAT); - } - regdiagfilename = optarg; - break; - case 'r': - if ((regfile = fopen(optarg, "w")) == NULL) { - perror(optarg); - stop(NULL, EX_CANTCREAT); - } - regfilename = optarg; - break; - case 'I': - { - path_entry_t include_dir; - - if (strcmp(optarg, "-") == 0) { - if (includes_search_curdir == 0) { - fprintf(stderr, "%s: Warning - '-I-' " - "specified multiple " - "times\n", appname); - } - includes_search_curdir = 0; - for (include_dir = SLIST_FIRST(&search_path); - include_dir != NULL; - include_dir = SLIST_NEXT(include_dir, - links)) - /* - * All entries before a '-I-' only - * apply to includes specified with - * quotes instead of "<>". - */ - include_dir->quoted_includes_only = 1; - } else { - include_dir = - (path_entry_t)malloc(sizeof(*include_dir)); - if (include_dir == NULL) { - perror(optarg); - stop(NULL, EX_OSERR); - } - include_dir->directory = strdup(optarg); - if (include_dir->directory == NULL) { - perror(optarg); - stop(NULL, EX_OSERR); - } - include_dir->quoted_includes_only = 0; - SLIST_INSERT_HEAD(&search_path, include_dir, - links); - } - break; - } - case '?': - default: - usage(); - /* NOTREACHED */ - } - } - argc -= optind; - argv += optind; - - if (argc != 1) { - fprintf(stderr, "%s: No input file specifiled\n", appname); - usage(); - /* NOTREACHED */ - } - - if (regdiagfile != NULL - && (regfile == NULL || stock_include_file == NULL)) { - fprintf(stderr, - "%s: The -p option requires the -r and -i options.\n", - appname); - usage(); - /* NOTREACHED */ - } - symtable_open(); - inputfilename = *argv; - include_file(*argv, SOURCE_FILE); - retval = yyparse(); - if (retval == 0) { - if (SLIST_FIRST(&scope_stack) == NULL - || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) { - stop("Unterminated conditional expression", EX_DATAERR); - /* NOTREACHED */ - } - - /* Process outmost scope */ - process_scope(SLIST_FIRST(&scope_stack)); - /* - * Decend the tree of scopes and insert/emit - * patches as appropriate. We perform a depth first - * tranversal, recursively handling each scope. - */ - /* start at the root scope */ - dump_scope(SLIST_FIRST(&scope_stack)); - - /* Patch up forward jump addresses */ - back_patch(); - - if (ofile != NULL) - output_code(); - if (regfile != NULL) - symtable_dump(regfile, regdiagfile); - if (listfile != NULL) - output_listing(inputfilename); - } - - stop(NULL, 0); - /* NOTREACHED */ - return (0); -} - -static void -usage() -{ - - (void)fprintf(stderr, -"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n" -" [-r register_output_file [-p register_diag_file -i includefile]]\n" -" [-l program_list_file]\n" -" input_file\n", appname); - exit(EX_USAGE); -} - -static void -back_patch() -{ - struct instruction *cur_instr; - - for (cur_instr = STAILQ_FIRST(&seq_program); - cur_instr != NULL; - cur_instr = STAILQ_NEXT(cur_instr, links)) { - if (cur_instr->patch_label != NULL) { - struct ins_format3 *f3_instr; - u_int address; - - if (cur_instr->patch_label->type != LABEL) { - char buf[255]; - - snprintf(buf, sizeof(buf), - "Undefined label %s", - cur_instr->patch_label->name); - stop(buf, EX_DATAERR); - /* NOTREACHED */ - } - f3_instr = &cur_instr->format.format3; - address = f3_instr->address; - address += cur_instr->patch_label->info.linfo->address; - f3_instr->address = address; - } - } -} - -static void -output_code() -{ - struct instruction *cur_instr; - patch_t *cur_patch; - critical_section_t *cs; - symbol_node_t *cur_node; - int instrcount; - - instrcount = 0; - fprintf(ofile, -"/*\n" -" * DO NOT EDIT - This file is automatically generated\n" -" * from the following source files:\n" -" *\n" -"%s */\n", versions); - - fprintf(ofile, "static uint8_t seqprog[] = {\n"); - for (cur_instr = STAILQ_FIRST(&seq_program); - cur_instr != NULL; - cur_instr = STAILQ_NEXT(cur_instr, links)) { - - fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x", - cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n", -#if BYTE_ORDER == LITTLE_ENDIAN - cur_instr->format.bytes[0], - cur_instr->format.bytes[1], - cur_instr->format.bytes[2], - cur_instr->format.bytes[3]); -#else - cur_instr->format.bytes[3], - cur_instr->format.bytes[2], - cur_instr->format.bytes[1], - cur_instr->format.bytes[0]); -#endif - instrcount++; - } - fprintf(ofile, "\n};\n\n"); - - if (patch_arg_list == NULL) - stop("Patch argument list not defined", - EX_DATAERR); - - /* - * Output patch information. Patch functions first. - */ - fprintf(ofile, -"typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list); - - for (cur_node = SLIST_FIRST(&patch_functions); - cur_node != NULL; - cur_node = SLIST_NEXT(cur_node,links)) { - fprintf(ofile, -"static %spatch_func_t %spatch%d_func;\n" -"\n" -"static int\n" -"%spatch%d_func(%s)\n" -"{\n" -" return (%s);\n" -"}\n\n", - prefix, - prefix, - cur_node->symbol->info.condinfo->func_num, - prefix, - cur_node->symbol->info.condinfo->func_num, - patch_arg_list, - cur_node->symbol->name); - } - - fprintf(ofile, -"static struct patch {\n" -" %spatch_func_t *patch_func;\n" -" uint32_t begin :10,\n" -" skip_instr :10,\n" -" skip_patch :12;\n" -"} patches[] = {\n", prefix); - - for (cur_patch = STAILQ_FIRST(&patches); - cur_patch != NULL; - cur_patch = STAILQ_NEXT(cur_patch,links)) { - fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }", - cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n", - prefix, - cur_patch->patch_func, cur_patch->begin, - cur_patch->skip_instr, cur_patch->skip_patch); - } - - fprintf(ofile, "\n};\n\n"); - - fprintf(ofile, -"static struct cs {\n" -" uint16_t begin;\n" -" uint16_t end;\n" -"} critical_sections[] = {\n"); - - for (cs = TAILQ_FIRST(&cs_tailq); - cs != NULL; - cs = TAILQ_NEXT(cs, links)) { - fprintf(ofile, "%s\t{ %d, %d }", - cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n", - cs->begin_addr, cs->end_addr); - } - - fprintf(ofile, "\n};\n\n"); - - fprintf(ofile, -"static const int num_critical_sections = sizeof(critical_sections)\n" -" / sizeof(*critical_sections);\n"); - - fprintf(stderr, "%s: %d instructions used\n", appname, instrcount); -} - -static void -dump_scope(scope_t *scope) -{ - scope_t *cur_scope; - - /* - * Emit the first patch for this scope - */ - emit_patch(scope, 0); - - /* - * Dump each scope within this one. - */ - cur_scope = TAILQ_FIRST(&scope->inner_scope); - - while (cur_scope != NULL) { - - dump_scope(cur_scope); - - cur_scope = TAILQ_NEXT(cur_scope, scope_links); - } - - /* - * Emit the second, closing, patch for this scope - */ - emit_patch(scope, 1); -} - -void -emit_patch(scope_t *scope, int patch) -{ - patch_info_t *pinfo; - patch_t *new_patch; - - pinfo = &scope->patches[patch]; - - if (pinfo->skip_instr == 0) - /* No-Op patch */ - return; - - new_patch = (patch_t *)malloc(sizeof(*new_patch)); - - if (new_patch == NULL) - stop("Could not malloc patch structure", EX_OSERR); - - memset(new_patch, 0, sizeof(*new_patch)); - - if (patch == 0) { - new_patch->patch_func = scope->func_num; - new_patch->begin = scope->begin_addr; - } else { - new_patch->patch_func = 0; - new_patch->begin = scope->end_addr; - } - new_patch->skip_instr = pinfo->skip_instr; - new_patch->skip_patch = pinfo->skip_patch; - STAILQ_INSERT_TAIL(&patches, new_patch, links); -} - -void -output_listing(char *ifilename) -{ - char buf[1024]; - FILE *ifile; - struct instruction *cur_instr; - patch_t *cur_patch; - symbol_node_t *cur_func; - int *func_values; - int instrcount; - int instrptr; - int line; - int func_count; - int skip_addr; - - instrcount = 0; - instrptr = 0; - line = 1; - skip_addr = 0; - if ((ifile = fopen(ifilename, "r")) == NULL) { - perror(ifilename); - stop(NULL, EX_DATAERR); - } - - /* - * Determine which options to apply to this listing. - */ - for (func_count = 0, cur_func = SLIST_FIRST(&patch_functions); - cur_func != NULL; - cur_func = SLIST_NEXT(cur_func, links)) - func_count++; - - func_values = NULL; - if (func_count != 0) { - func_values = (int *)malloc(func_count * sizeof(int)); - - if (func_values == NULL) - stop("Could not malloc", EX_OSERR); - - func_values[0] = 0; /* FALSE func */ - func_count--; - - /* - * Ask the user to fill in the return values for - * the rest of the functions. - */ - - - for (cur_func = SLIST_FIRST(&patch_functions); - cur_func != NULL && SLIST_NEXT(cur_func, links) != NULL; - cur_func = SLIST_NEXT(cur_func, links), func_count--) { - int input; - - fprintf(stdout, "\n(%s)\n", cur_func->symbol->name); - fprintf(stdout, - "Enter the return value for " - "this expression[T/F]:"); - - while (1) { - - input = getchar(); - input = toupper(input); - - if (input == 'T') { - func_values[func_count] = 1; - break; - } else if (input == 'F') { - func_values[func_count] = 0; - break; - } - } - if (isatty(fileno(stdin)) == 0) - putchar(input); - } - fprintf(stdout, "\nThanks!\n"); - } - - /* Now output the listing */ - cur_patch = STAILQ_FIRST(&patches); - for (cur_instr = STAILQ_FIRST(&seq_program); - cur_instr != NULL; - cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) { - - if (check_patch(&cur_patch, instrcount, - &skip_addr, func_values) == 0) { - /* Don't count this instruction as it is in a patch - * that was removed. - */ - continue; - } - - while (line < cur_instr->srcline) { - fgets(buf, sizeof(buf), ifile); - fprintf(listfile, "\t\t%s", buf); - line++; - } - fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr, -#if BYTE_ORDER == LITTLE_ENDIAN - cur_instr->format.bytes[0], - cur_instr->format.bytes[1], - cur_instr->format.bytes[2], - cur_instr->format.bytes[3]); -#else - cur_instr->format.bytes[3], - cur_instr->format.bytes[2], - cur_instr->format.bytes[1], - cur_instr->format.bytes[0]); -#endif - fgets(buf, sizeof(buf), ifile); - fprintf(listfile, "\t%s", buf); - line++; - instrptr++; - } - /* Dump the remainder of the file */ - while(fgets(buf, sizeof(buf), ifile) != NULL) - fprintf(listfile, "\t\t%s", buf); - - fclose(ifile); -} - -static int -check_patch(patch_t **start_patch, int start_instr, - int *skip_addr, int *func_vals) -{ - patch_t *cur_patch; - - cur_patch = *start_patch; - - while (cur_patch != NULL && start_instr == cur_patch->begin) { - if (func_vals[cur_patch->patch_func] == 0) { - int skip; - - /* Start rejecting code */ - *skip_addr = start_instr + cur_patch->skip_instr; - for (skip = cur_patch->skip_patch; - skip > 0 && cur_patch != NULL; - skip--) - cur_patch = STAILQ_NEXT(cur_patch, links); - } else { - /* Accepted this patch. Advance to the next - * one and wait for our intruction pointer to - * hit this point. - */ - cur_patch = STAILQ_NEXT(cur_patch, links); - } - } - - *start_patch = cur_patch; - if (start_instr < *skip_addr) - /* Still skipping */ - return (0); - - return (1); -} - -/* - * Print out error information if appropriate, and clean up before - * terminating the program. - */ -void -stop(const char *string, int err_code) -{ - if (string != NULL) { - fprintf(stderr, "%s: ", appname); - if (yyfilename != NULL) { - fprintf(stderr, "Stopped at file %s, line %d - ", - yyfilename, yylineno); - } - fprintf(stderr, "%s\n", string); - } - - if (ofile != NULL) { - fclose(ofile); - if (err_code != 0) { - fprintf(stderr, "%s: Removing %s due to error\n", - appname, ofilename); - unlink(ofilename); - } - } - - if (regfile != NULL) { - fclose(regfile); - if (err_code != 0) { - fprintf(stderr, "%s: Removing %s due to error\n", - appname, regfilename); - unlink(regfilename); - } - } - - if (listfile != NULL) { - fclose(listfile); - if (err_code != 0) { - fprintf(stderr, "%s: Removing %s due to error\n", - appname, listfilename); - unlink(listfilename); - } - } - - symlist_free(&patch_functions); - symtable_close(); - - exit(err_code); -} - -struct instruction * -seq_alloc() -{ - struct instruction *new_instr; - - new_instr = (struct instruction *)malloc(sizeof(struct instruction)); - if (new_instr == NULL) - stop("Unable to malloc instruction object", EX_SOFTWARE); - memset(new_instr, 0, sizeof(*new_instr)); - STAILQ_INSERT_TAIL(&seq_program, new_instr, links); - new_instr->srcline = yylineno; - return new_instr; -} - -critical_section_t * -cs_alloc() -{ - critical_section_t *new_cs; - - new_cs= (critical_section_t *)malloc(sizeof(critical_section_t)); - if (new_cs == NULL) - stop("Unable to malloc critical_section object", EX_SOFTWARE); - memset(new_cs, 0, sizeof(*new_cs)); - - TAILQ_INSERT_TAIL(&cs_tailq, new_cs, links); - return new_cs; -} - -scope_t * -scope_alloc() -{ - scope_t *new_scope; - - new_scope = (scope_t *)malloc(sizeof(scope_t)); - if (new_scope == NULL) - stop("Unable to malloc scope object", EX_SOFTWARE); - memset(new_scope, 0, sizeof(*new_scope)); - TAILQ_INIT(&new_scope->inner_scope); - - if (SLIST_FIRST(&scope_stack) != NULL) { - TAILQ_INSERT_TAIL(&SLIST_FIRST(&scope_stack)->inner_scope, - new_scope, scope_links); - } - /* This patch is now the current scope */ - SLIST_INSERT_HEAD(&scope_stack, new_scope, scope_stack_links); - return new_scope; -} - -void -process_scope(scope_t *scope) -{ - /* - * We are "leaving" this scope. We should now have - * enough information to process the lists of scopes - * we encapsulate. - */ - scope_t *cur_scope; - u_int skip_patch_count; - u_int skip_instr_count; - - cur_scope = TAILQ_LAST(&scope->inner_scope, scope_tailq); - skip_patch_count = 0; - skip_instr_count = 0; - while (cur_scope != NULL) { - u_int patch0_patch_skip; - - patch0_patch_skip = 0; - switch (cur_scope->type) { - case SCOPE_IF: - case SCOPE_ELSE_IF: - if (skip_instr_count != 0) { - /* Create a tail patch */ - patch0_patch_skip++; - cur_scope->patches[1].skip_patch = - skip_patch_count + 1; - cur_scope->patches[1].skip_instr = - skip_instr_count; - } - - /* Count Head patch */ - patch0_patch_skip++; - - /* Count any patches contained in our inner scope */ - patch0_patch_skip += cur_scope->inner_scope_patches; - - cur_scope->patches[0].skip_patch = patch0_patch_skip; - cur_scope->patches[0].skip_instr = - cur_scope->end_addr - cur_scope->begin_addr; - - skip_instr_count += cur_scope->patches[0].skip_instr; - - skip_patch_count += patch0_patch_skip; - if (cur_scope->type == SCOPE_IF) { - scope->inner_scope_patches += skip_patch_count; - skip_patch_count = 0; - skip_instr_count = 0; - } - break; - case SCOPE_ELSE: - /* Count any patches contained in our innter scope */ - skip_patch_count += cur_scope->inner_scope_patches; - - skip_instr_count += cur_scope->end_addr - - cur_scope->begin_addr; - break; - case SCOPE_ROOT: - stop("Unexpected scope type encountered", EX_SOFTWARE); - /* NOTREACHED */ - } - - cur_scope = TAILQ_PREV(cur_scope, scope_tailq, scope_links); - } -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm.h linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm.h --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,95 +0,0 @@ -/* - * Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters - * - * Copyright (c) 1997 Justin T. Gibbs. - * Copyright (c) 2001, 2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#14 $ - * - * $FreeBSD$ - */ - -#ifdef __linux__ -#include "../queue.h" -#else -#include -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -typedef struct path_entry { - char *directory; - int quoted_includes_only; - SLIST_ENTRY(path_entry) links; -} *path_entry_t; - -typedef enum { - QUOTED_INCLUDE, - BRACKETED_INCLUDE, - SOURCE_FILE -} include_type; - -SLIST_HEAD(path_list, path_entry); - -extern struct path_list search_path; -extern struct cs_tailq cs_tailq; -extern struct scope_list scope_stack; -extern struct symlist patch_functions; -extern int includes_search_curdir; /* False if we've seen -I- */ -extern char *appname; -extern char *stock_include_file; -extern int yylineno; -extern char *yyfilename; -extern char *prefix; -extern char *patch_arg_list; -extern char *versions; -extern int src_mode; -extern int dst_mode; -struct symbol; - -void stop(const char *errstring, int err_code); -void include_file(char *file_name, include_type type); -void expand_macro(struct symbol *macro_symbol); -struct instruction *seq_alloc(void); -struct critical_section *cs_alloc(void); -struct scope *scope_alloc(void); -void process_scope(struct scope *); diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_gram.y linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_gram.y --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_gram.y 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_gram.y 1969-12-31 16:00:00.000000000 -0800 @@ -1,1945 +0,0 @@ -%{ -/* - * Parser for the Aic7xxx SCSI Host adapter sequencer assembler. - * - * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. - * Copyright (c) 2001, 2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 $ - * - * $FreeBSD$ - */ - -#include - -#include -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include "../queue.h" -#else -#include -#endif - -#include "aicasm.h" -#include "aicasm_symbol.h" -#include "aicasm_insformat.h" - -int yylineno; -char *yyfilename; -char stock_prefix[] = "aic_"; -char *prefix = stock_prefix; -char *patch_arg_list; -char *versions; -static char errbuf[255]; -static char regex_pattern[255]; -static symbol_t *cur_symbol; -static symbol_t *field_symbol; -static symbol_t *scb_or_sram_symbol; -static symtype cur_symtype; -static symbol_ref_t accumulator; -static symbol_ref_t mode_ptr; -static symbol_ref_t allones; -static symbol_ref_t allzeros; -static symbol_ref_t none; -static symbol_ref_t sindex; -static int instruction_ptr; -static int num_srams; -static int sram_or_scb_offset; -static int download_constant_count; -static int in_critical_section; -static u_int enum_increment; -static u_int enum_next_value; - -static void process_field(int field_type, symbol_t *sym, int mask); -static void initialize_symbol(symbol_t *symbol); -static void add_macro_arg(const char *argtext, int position); -static void add_macro_body(const char *bodytext); -static void process_register(symbol_t **p_symbol); -static void format_1_instr(int opcode, symbol_ref_t *dest, - expression_t *immed, symbol_ref_t *src, int ret); -static void format_2_instr(int opcode, symbol_ref_t *dest, - expression_t *places, symbol_ref_t *src, int ret); -static void format_3_instr(int opcode, symbol_ref_t *src, - expression_t *immed, symbol_ref_t *address); -static void test_readable_symbol(symbol_t *symbol); -static void test_writable_symbol(symbol_t *symbol); -static void type_check(symbol_t *symbol, expression_t *expression, int and_op); -static void make_expression(expression_t *immed, int value); -static void add_conditional(symbol_t *symbol); -static void add_version(const char *verstring); -static int is_download_const(expression_t *immed); - -#define SRAM_SYMNAME "SRAM_BASE" -#define SCB_SYMNAME "SCB_BASE" -%} - -%union { - u_int value; - char *str; - symbol_t *sym; - symbol_ref_t sym_ref; - expression_t expression; -} - -%token T_REGISTER - -%token T_CONST - -%token T_EXPORT - -%token T_DOWNLOAD - -%token T_SCB - -%token T_SRAM - -%token T_ALIAS - -%token T_SIZE - -%token T_EXPR_LSHIFT - -%token T_EXPR_RSHIFT - -%token T_ADDRESS - -%token T_ACCESS_MODE - -%token T_MODES - -%token T_DEFINE - -%token T_SET_SRC_MODE - -%token T_SET_DST_MODE - -%token T_MODE - -%token T_BEGIN_CS - -%token T_END_CS - -%token T_FIELD - -%token T_ENUM - -%token T_MASK - -%token T_NUMBER - -%token T_PATH T_STRING T_ARG T_MACROBODY - -%token T_CEXPR - -%token T_EOF T_INCLUDE T_VERSION T_PREFIX T_PATCH_ARG_LIST - -%token T_SHR T_SHL T_ROR T_ROL - -%token T_MVI T_MOV T_CLR T_BMOV - -%token T_JMP T_JC T_JNC T_JE T_JNE T_JNZ T_JZ T_CALL - -%token T_ADD T_ADC - -%token T_INC T_DEC - -%token T_STC T_CLC - -%token T_CMP T_NOT T_XOR - -%token T_TEST T_AND - -%token T_OR - -%token T_RET - -%token T_NOP - -%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX T_MODE_PTR - -%token T_A - -%token T_SYMBOL - -%token T_NL - -%token T_IF T_ELSE T_ELSE_IF T_ENDIF - -%type reg_symbol address destination source opt_source - -%type expression immediate immediate_or_a - -%type export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne - -%type mode_value mode_list macro_arglist - -%left '|' -%left '&' -%left T_EXPR_LSHIFT T_EXPR_RSHIFT -%left '+' '-' -%left '*' '/' -%right '~' -%nonassoc UMINUS -%% - -program: - include -| program include -| prefix -| program prefix -| patch_arg_list -| program patch_arg_list -| version -| program version -| register -| program register -| constant -| program constant -| macrodefn -| program macrodefn -| scratch_ram -| program scratch_ram -| scb -| program scb -| label -| program label -| set_src_mode -| program set_src_mode -| set_dst_mode -| program set_dst_mode -| critical_section_start -| program critical_section_start -| critical_section_end -| program critical_section_end -| conditional -| program conditional -| code -| program code -; - -include: - T_INCLUDE '<' T_PATH '>' - { - include_file($3, BRACKETED_INCLUDE); - } -| T_INCLUDE '"' T_PATH '"' - { - include_file($3, QUOTED_INCLUDE); - } -; - -prefix: - T_PREFIX '=' T_STRING - { - if (prefix != stock_prefix) - stop("Prefix multiply defined", - EX_DATAERR); - prefix = strdup($3); - if (prefix == NULL) - stop("Unable to record prefix", EX_SOFTWARE); - } -; - -patch_arg_list: - T_PATCH_ARG_LIST '=' T_STRING - { - if (patch_arg_list != NULL) - stop("Patch argument list multiply defined", - EX_DATAERR); - patch_arg_list = strdup($3); - if (patch_arg_list == NULL) - stop("Unable to record patch arg list", EX_SOFTWARE); - } -; - -version: - T_VERSION '=' T_STRING - { add_version($3); } -; - -register: - T_REGISTER { cur_symtype = REGISTER; } reg_definition -; - -reg_definition: - T_SYMBOL '{' - { - if ($1->type != UNINITIALIZED) { - stop("Register multiply defined", EX_DATAERR); - /* NOTREACHED */ - } - cur_symbol = $1; - cur_symbol->type = cur_symtype; - initialize_symbol(cur_symbol); - } - reg_attribute_list - '}' - { - /* - * Default to allowing everything in for registers - * with no bit or mask definitions. - */ - if (cur_symbol->info.rinfo->valid_bitmask == 0) - cur_symbol->info.rinfo->valid_bitmask = 0xFF; - - if (cur_symbol->info.rinfo->size == 0) - cur_symbol->info.rinfo->size = 1; - - /* - * This might be useful for registers too. - */ - if (cur_symbol->type != REGISTER) { - if (cur_symbol->info.rinfo->address == 0) - cur_symbol->info.rinfo->address = - sram_or_scb_offset; - sram_or_scb_offset += - cur_symbol->info.rinfo->size; - } - cur_symbol = NULL; - } -; - -reg_attribute_list: - reg_attribute -| reg_attribute_list reg_attribute -; - -reg_attribute: - reg_address -| size -| access_mode -| modes -| field_defn -| enum_defn -| mask_defn -| alias -| accumulator -| mode_pointer -| allones -| allzeros -| none -| sindex -; - -reg_address: - T_ADDRESS T_NUMBER - { - cur_symbol->info.rinfo->address = $2; - } -; - -size: - T_SIZE T_NUMBER - { - cur_symbol->info.rinfo->size = $2; - if (scb_or_sram_symbol != NULL) { - u_int max_addr; - u_int sym_max_addr; - - max_addr = scb_or_sram_symbol->info.rinfo->address - + scb_or_sram_symbol->info.rinfo->size; - sym_max_addr = cur_symbol->info.rinfo->address - + cur_symbol->info.rinfo->size; - - if (sym_max_addr > max_addr) - stop("SCB or SRAM space exhausted", EX_DATAERR); - } - } -; - -access_mode: - T_ACCESS_MODE T_MODE - { - cur_symbol->info.rinfo->mode = $2; - } -; - -modes: - T_MODES mode_list - { - cur_symbol->info.rinfo->modes = $2; - } -; - -mode_list: - mode_value - { - $$ = $1; - } -| mode_list ',' mode_value - { - $$ = $1 | $3; - } -; - -mode_value: - T_NUMBER - { - if ($1 > 4) { - stop("Valid register modes range between 0 and 4.", - EX_DATAERR); - /* NOTREACHED */ - } - - $$ = (0x1 << $1); - } -| T_SYMBOL - { - symbol_t *symbol; - - symbol = $1; - if (symbol->type != CONST) { - stop("Only \"const\" symbols allowed in " - "mode definitions.", EX_DATAERR); - /* NOTREACHED */ - } - if (symbol->info.cinfo->value > 4) { - stop("Valid register modes range between 0 and 4.", - EX_DATAERR); - /* NOTREACHED */ - } - $$ = (0x1 << symbol->info.cinfo->value); - } -; - -field_defn: - T_FIELD - { - field_symbol = NULL; - enum_next_value = 0; - enum_increment = 1; - } - '{' enum_entry_list '}' -| T_FIELD T_SYMBOL expression - { - process_field(FIELD, $2, $3.value); - field_symbol = $2; - enum_next_value = 0; - enum_increment = 0x01 << (ffs($3.value) - 1); - } - '{' enum_entry_list '}' -| T_FIELD T_SYMBOL expression - { - process_field(FIELD, $2, $3.value); - } -; - -enum_defn: - T_ENUM - { - field_symbol = NULL; - enum_next_value = 0; - enum_increment = 1; - } - '{' enum_entry_list '}' -| T_ENUM T_SYMBOL expression - { - process_field(ENUM, $2, $3.value); - field_symbol = $2; - enum_next_value = 0; - enum_increment = 0x01 << (ffs($3.value) - 1); - } - '{' enum_entry_list '}' -; - -enum_entry_list: - enum_entry -| enum_entry_list ',' enum_entry -; - -enum_entry: - T_SYMBOL - { - process_field(ENUM_ENTRY, $1, enum_next_value); - enum_next_value += enum_increment; - } -| T_SYMBOL expression - { - process_field(ENUM_ENTRY, $1, $2.value); - enum_next_value = $2.value + enum_increment; - } -; - -mask_defn: - T_MASK T_SYMBOL expression - { - process_field(MASK, $2, $3.value); - } -; - -alias: - T_ALIAS T_SYMBOL - { - if ($2->type != UNINITIALIZED) { - stop("Re-definition of register alias", - EX_DATAERR); - /* NOTREACHED */ - } - $2->type = ALIAS; - initialize_symbol($2); - $2->info.ainfo->parent = cur_symbol; - } -; - -accumulator: - T_ACCUM - { - if (accumulator.symbol != NULL) { - stop("Only one accumulator definition allowed", - EX_DATAERR); - /* NOTREACHED */ - } - accumulator.symbol = cur_symbol; - } -; - -mode_pointer: - T_MODE_PTR - { - if (mode_ptr.symbol != NULL) { - stop("Only one mode pointer definition allowed", - EX_DATAERR); - /* NOTREACHED */ - } - mode_ptr.symbol = cur_symbol; - } -; - -allones: - T_ALLONES - { - if (allones.symbol != NULL) { - stop("Only one definition of allones allowed", - EX_DATAERR); - /* NOTREACHED */ - } - allones.symbol = cur_symbol; - } -; - -allzeros: - T_ALLZEROS - { - if (allzeros.symbol != NULL) { - stop("Only one definition of allzeros allowed", - EX_DATAERR); - /* NOTREACHED */ - } - allzeros.symbol = cur_symbol; - } -; - -none: - T_NONE - { - if (none.symbol != NULL) { - stop("Only one definition of none allowed", - EX_DATAERR); - /* NOTREACHED */ - } - none.symbol = cur_symbol; - } -; - -sindex: - T_SINDEX - { - if (sindex.symbol != NULL) { - stop("Only one definition of sindex allowed", - EX_DATAERR); - /* NOTREACHED */ - } - sindex.symbol = cur_symbol; - } -; - -expression: - expression '|' expression - { - $$.value = $1.value | $3.value; - symlist_merge(&$$.referenced_syms, - &$1.referenced_syms, - &$3.referenced_syms); - } -| expression '&' expression - { - $$.value = $1.value & $3.value; - symlist_merge(&$$.referenced_syms, - &$1.referenced_syms, - &$3.referenced_syms); - } -| expression '+' expression - { - $$.value = $1.value + $3.value; - symlist_merge(&$$.referenced_syms, - &$1.referenced_syms, - &$3.referenced_syms); - } -| expression '-' expression - { - $$.value = $1.value - $3.value; - symlist_merge(&($$.referenced_syms), - &($1.referenced_syms), - &($3.referenced_syms)); - } -| expression '*' expression - { - $$.value = $1.value * $3.value; - symlist_merge(&($$.referenced_syms), - &($1.referenced_syms), - &($3.referenced_syms)); - } -| expression '/' expression - { - $$.value = $1.value / $3.value; - symlist_merge(&($$.referenced_syms), - &($1.referenced_syms), - &($3.referenced_syms)); - } -| expression T_EXPR_LSHIFT expression - { - $$.value = $1.value << $3.value; - symlist_merge(&$$.referenced_syms, - &$1.referenced_syms, - &$3.referenced_syms); - } -| expression T_EXPR_RSHIFT expression - { - $$.value = $1.value >> $3.value; - symlist_merge(&$$.referenced_syms, - &$1.referenced_syms, - &$3.referenced_syms); - } -| '(' expression ')' - { - $$ = $2; - } -| '~' expression - { - $$ = $2; - $$.value = (~$$.value) & 0xFF; - } -| '-' expression %prec UMINUS - { - $$ = $2; - $$.value = -$$.value; - } -| T_NUMBER - { - $$.value = $1; - SLIST_INIT(&$$.referenced_syms); - } -| T_SYMBOL - { - symbol_t *symbol; - - symbol = $1; - switch (symbol->type) { - case ALIAS: - symbol = $1->info.ainfo->parent; - case REGISTER: - case SCBLOC: - case SRAMLOC: - $$.value = symbol->info.rinfo->address; - break; - case MASK: - case FIELD: - case ENUM: - case ENUM_ENTRY: - $$.value = symbol->info.finfo->value; - break; - case DOWNLOAD_CONST: - case CONST: - $$.value = symbol->info.cinfo->value; - break; - case UNINITIALIZED: - default: - { - snprintf(errbuf, sizeof(errbuf), - "Undefined symbol %s referenced", - symbol->name); - stop(errbuf, EX_DATAERR); - /* NOTREACHED */ - break; - } - } - SLIST_INIT(&$$.referenced_syms); - symlist_add(&$$.referenced_syms, symbol, SYMLIST_INSERT_HEAD); - } -; - -constant: - T_CONST T_SYMBOL expression - { - if ($2->type != UNINITIALIZED) { - stop("Re-definition of symbol as a constant", - EX_DATAERR); - /* NOTREACHED */ - } - $2->type = CONST; - initialize_symbol($2); - $2->info.cinfo->value = $3.value; - } -| T_CONST T_SYMBOL T_DOWNLOAD - { - if ($1) { - stop("Invalid downloaded constant declaration", - EX_DATAERR); - /* NOTREACHED */ - } - if ($2->type != UNINITIALIZED) { - stop("Re-definition of symbol as a downloaded constant", - EX_DATAERR); - /* NOTREACHED */ - } - $2->type = DOWNLOAD_CONST; - initialize_symbol($2); - $2->info.cinfo->value = download_constant_count++; - } -; - -macrodefn_prologue: - T_DEFINE T_SYMBOL - { - if ($2->type != UNINITIALIZED) { - stop("Re-definition of symbol as a macro", - EX_DATAERR); - /* NOTREACHED */ - } - cur_symbol = $2; - cur_symbol->type = MACRO; - initialize_symbol(cur_symbol); - } -; - -macrodefn: - macrodefn_prologue T_MACROBODY - { - add_macro_body($2); - } -| macrodefn_prologue '(' macro_arglist ')' T_MACROBODY - { - add_macro_body($5); - cur_symbol->info.macroinfo->narg = $3; - } -; - -macro_arglist: - { - /* Macros can take no arguments */ - $$ = 0; - } -| T_ARG - { - $$ = 1; - add_macro_arg($1, 0); - } -| macro_arglist ',' T_ARG - { - if ($1 == 0) { - stop("Comma without preceeding argument in arg list", - EX_DATAERR); - /* NOTREACHED */ - } - $$ = $1 + 1; - add_macro_arg($3, $1); - } -; - -scratch_ram: - T_SRAM '{' - { - snprintf(errbuf, sizeof(errbuf), "%s%d", SRAM_SYMNAME, - num_srams); - cur_symbol = symtable_get(SRAM_SYMNAME); - cur_symtype = SRAMLOC; - cur_symbol->type = SRAMLOC; - initialize_symbol(cur_symbol); - } - reg_address - { - sram_or_scb_offset = cur_symbol->info.rinfo->address; - } - size - { - scb_or_sram_symbol = cur_symbol; - } - scb_or_sram_attributes - '}' - { - cur_symbol = NULL; - scb_or_sram_symbol = NULL; - } -; - -scb: - T_SCB '{' - { - cur_symbol = symtable_get(SCB_SYMNAME); - cur_symtype = SCBLOC; - if (cur_symbol->type != UNINITIALIZED) { - stop("Only one SRAM definition allowed", - EX_SOFTWARE); - /* NOTREACHED */ - } - cur_symbol->type = SCBLOC; - initialize_symbol(cur_symbol); - /* 64 bytes of SCB space */ - cur_symbol->info.rinfo->size = 64; - } - reg_address - { - sram_or_scb_offset = cur_symbol->info.rinfo->address; - } - size - { - scb_or_sram_symbol = cur_symbol; - } - scb_or_sram_attributes - '}' - { - cur_symbol = NULL; - scb_or_sram_symbol = NULL; - } -; - -scb_or_sram_attributes: - /* NULL definition is okay */ -| modes -| scb_or_sram_reg_list -| modes scb_or_sram_reg_list -; - -scb_or_sram_reg_list: - reg_definition -| scb_or_sram_reg_list reg_definition -; - -reg_symbol: - T_SYMBOL - { - process_register(&$1); - $$.symbol = $1; - $$.offset = 0; - } -| T_SYMBOL '[' T_SYMBOL ']' - { - process_register(&$1); - if ($3->type != CONST) { - stop("register offset must be a constant", EX_DATAERR); - /* NOTREACHED */ - } - if (($3->info.cinfo->value + 1) > $1->info.rinfo->size) { - stop("Accessing offset beyond range of register", - EX_DATAERR); - /* NOTREACHED */ - } - $$.symbol = $1; - $$.offset = $3->info.cinfo->value; - } -| T_SYMBOL '[' T_NUMBER ']' - { - process_register(&$1); - if (($3 + 1) > $1->info.rinfo->size) { - stop("Accessing offset beyond range of register", - EX_DATAERR); - /* NOTREACHED */ - } - $$.symbol = $1; - $$.offset = $3; - } -| T_A - { - if (accumulator.symbol == NULL) { - stop("No accumulator has been defined", EX_DATAERR); - /* NOTREACHED */ - } - $$.symbol = accumulator.symbol; - $$.offset = 0; - } -; - -destination: - reg_symbol - { - test_writable_symbol($1.symbol); - $$ = $1; - } -; - -immediate: - expression - { $$ = $1; } -; - -immediate_or_a: - expression - { - if ($1.value == 0 && is_download_const(&$1) == 0) { - snprintf(errbuf, sizeof(errbuf), - "\nExpression evaluates to 0 and thus " - "references the accumulator.\n " - "If this is the desired effect, use 'A' " - "instead.\n"); - stop(errbuf, EX_DATAERR); - } - $$ = $1; - } -| T_A - { - SLIST_INIT(&$$.referenced_syms); - symlist_add(&$$.referenced_syms, accumulator.symbol, - SYMLIST_INSERT_HEAD); - $$.value = 0; - } -; - -source: - reg_symbol - { - test_readable_symbol($1.symbol); - $$ = $1; - } -; - -opt_source: - { - $$.symbol = NULL; - $$.offset = 0; - } -| ',' source - { $$ = $2; } -; - -ret: - { $$ = 0; } -| T_RET - { $$ = 1; } -; - -set_src_mode: - T_SET_SRC_MODE T_NUMBER ';' - { - src_mode = $2; - } -; - -set_dst_mode: - T_SET_DST_MODE T_NUMBER ';' - { - dst_mode = $2; - } -; - -critical_section_start: - T_BEGIN_CS ';' - { - critical_section_t *cs; - - if (in_critical_section != FALSE) { - stop("Critical Section within Critical Section", - EX_DATAERR); - /* NOTREACHED */ - } - cs = cs_alloc(); - cs->begin_addr = instruction_ptr; - in_critical_section = TRUE; - } -; - -critical_section_end: - T_END_CS ';' - { - critical_section_t *cs; - - if (in_critical_section == FALSE) { - stop("Unballanced 'end_cs'", EX_DATAERR); - /* NOTREACHED */ - } - cs = TAILQ_LAST(&cs_tailq, cs_tailq); - cs->end_addr = instruction_ptr; - in_critical_section = FALSE; - } -; - -export: - { $$ = 0; } -| T_EXPORT - { $$ = 1; } -; - -label: - export T_SYMBOL ':' - { - if ($2->type != UNINITIALIZED) { - stop("Program label multiply defined", EX_DATAERR); - /* NOTREACHED */ - } - $2->type = LABEL; - initialize_symbol($2); - $2->info.linfo->address = instruction_ptr; - $2->info.linfo->exported = $1; - } -; - -address: - T_SYMBOL - { - $$.symbol = $1; - $$.offset = 0; - } -| T_SYMBOL '+' T_NUMBER - { - $$.symbol = $1; - $$.offset = $3; - } -| T_SYMBOL '-' T_NUMBER - { - $$.symbol = $1; - $$.offset = -$3; - } -| '.' - { - $$.symbol = NULL; - $$.offset = 0; - } -| '.' '+' T_NUMBER - { - $$.symbol = NULL; - $$.offset = $3; - } -| '.' '-' T_NUMBER - { - $$.symbol = NULL; - $$.offset = -$3; - } -; - -conditional: - T_IF T_CEXPR '{' - { - scope_t *new_scope; - - add_conditional($2); - new_scope = scope_alloc(); - new_scope->type = SCOPE_IF; - new_scope->begin_addr = instruction_ptr; - new_scope->func_num = $2->info.condinfo->func_num; - } -| T_ELSE T_IF T_CEXPR '{' - { - scope_t *new_scope; - scope_t *scope_context; - scope_t *last_scope; - - /* - * Ensure that the previous scope is either an - * if or and else if. - */ - scope_context = SLIST_FIRST(&scope_stack); - last_scope = TAILQ_LAST(&scope_context->inner_scope, - scope_tailq); - if (last_scope == NULL - || last_scope->type == T_ELSE) { - - stop("'else if' without leading 'if'", EX_DATAERR); - /* NOTREACHED */ - } - add_conditional($3); - new_scope = scope_alloc(); - new_scope->type = SCOPE_ELSE_IF; - new_scope->begin_addr = instruction_ptr; - new_scope->func_num = $3->info.condinfo->func_num; - } -| T_ELSE '{' - { - scope_t *new_scope; - scope_t *scope_context; - scope_t *last_scope; - - /* - * Ensure that the previous scope is either an - * if or and else if. - */ - scope_context = SLIST_FIRST(&scope_stack); - last_scope = TAILQ_LAST(&scope_context->inner_scope, - scope_tailq); - if (last_scope == NULL - || last_scope->type == SCOPE_ELSE) { - - stop("'else' without leading 'if'", EX_DATAERR); - /* NOTREACHED */ - } - new_scope = scope_alloc(); - new_scope->type = SCOPE_ELSE; - new_scope->begin_addr = instruction_ptr; - } -; - -conditional: - '}' - { - scope_t *scope_context; - - scope_context = SLIST_FIRST(&scope_stack); - if (scope_context->type == SCOPE_ROOT) { - stop("Unexpected '}' encountered", EX_DATAERR); - /* NOTREACHED */ - } - - scope_context->end_addr = instruction_ptr; - - /* Pop the scope */ - SLIST_REMOVE_HEAD(&scope_stack, scope_stack_links); - - process_scope(scope_context); - - if (SLIST_FIRST(&scope_stack) == NULL) { - stop("Unexpected '}' encountered", EX_DATAERR); - /* NOTREACHED */ - } - } -; - -f1_opcode: - T_AND { $$ = AIC_OP_AND; } -| T_XOR { $$ = AIC_OP_XOR; } -| T_ADD { $$ = AIC_OP_ADD; } -| T_ADC { $$ = AIC_OP_ADC; } -; - -code: - f1_opcode destination ',' immediate_or_a opt_source ret ';' - { - format_1_instr($1, &$2, &$4, &$5, $6); - } -; - -code: - T_OR reg_symbol ',' immediate_or_a opt_source ret ';' - { - format_1_instr(AIC_OP_OR, &$2, &$4, &$5, $6); - } -; - -code: - T_INC destination opt_source ret ';' - { - expression_t immed; - - make_expression(&immed, 1); - format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4); - } -; - -code: - T_DEC destination opt_source ret ';' - { - expression_t immed; - - make_expression(&immed, -1); - format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4); - } -; - -code: - T_CLC ret ';' - { - expression_t immed; - - make_expression(&immed, -1); - format_1_instr(AIC_OP_ADD, &none, &immed, &allzeros, $2); - } -| T_CLC T_MVI destination ',' immediate_or_a ret ';' - { - format_1_instr(AIC_OP_ADD, &$3, &$5, &allzeros, $6); - } -; - -code: - T_STC ret ';' - { - expression_t immed; - - make_expression(&immed, 1); - format_1_instr(AIC_OP_ADD, &none, &immed, &allones, $2); - } -| T_STC destination ret ';' - { - expression_t immed; - - make_expression(&immed, 1); - format_1_instr(AIC_OP_ADD, &$2, &immed, &allones, $3); - } -; - -code: - T_BMOV destination ',' source ',' immediate ret ';' - { - format_1_instr(AIC_OP_BMOV, &$2, &$6, &$4, $7); - } -; - -code: - T_MOV destination ',' source ret ';' - { - expression_t immed; - - make_expression(&immed, 1); - format_1_instr(AIC_OP_BMOV, &$2, &immed, &$4, $5); - } -; - -code: - T_MVI destination ',' immediate ret ';' - { - if ($4.value == 0 - && is_download_const(&$4) == 0) { - expression_t immed; - - /* - * Allow move immediates of 0 so that macros, - * that can't know the immediate's value and - * otherwise compensate, still work. - */ - make_expression(&immed, 1); - format_1_instr(AIC_OP_BMOV, &$2, &immed, &allzeros, $5); - } else { - format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); - } - } -; - -code: - T_NOT destination opt_source ret ';' - { - expression_t immed; - - make_expression(&immed, 0xff); - format_1_instr(AIC_OP_XOR, &$2, &immed, &$3, $4); - } -; - -code: - T_CLR destination ret ';' - { - expression_t immed; - - make_expression(&immed, 0xff); - format_1_instr(AIC_OP_AND, &$2, &immed, &allzeros, $3); - } -; - -code: - T_NOP ret ';' - { - expression_t immed; - - make_expression(&immed, 0xff); - format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, $2); - } -; - -code: - T_RET ';' - { - expression_t immed; - - make_expression(&immed, 0xff); - format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, TRUE); - } -; - - /* - * This grammer differs from the one in the aic7xxx - * reference manual since the grammer listed there is - * ambiguous and causes a shift/reduce conflict. - * It also seems more logical as the "immediate" - * argument is listed as the second arg like the - * other formats. - */ - -f2_opcode: - T_SHL { $$ = AIC_OP_SHL; } -| T_SHR { $$ = AIC_OP_SHR; } -| T_ROL { $$ = AIC_OP_ROL; } -| T_ROR { $$ = AIC_OP_ROR; } -; - -code: - f2_opcode destination ',' expression opt_source ret ';' - { - format_2_instr($1, &$2, &$4, &$5, $6); - } -; - -jmp_jc_jnc_call: - T_JMP { $$ = AIC_OP_JMP; } -| T_JC { $$ = AIC_OP_JC; } -| T_JNC { $$ = AIC_OP_JNC; } -| T_CALL { $$ = AIC_OP_CALL; } -; - -jz_jnz: - T_JZ { $$ = AIC_OP_JZ; } -| T_JNZ { $$ = AIC_OP_JNZ; } -; - -je_jne: - T_JE { $$ = AIC_OP_JE; } -| T_JNE { $$ = AIC_OP_JNE; } -; - -code: - jmp_jc_jnc_call address ';' - { - expression_t immed; - - make_expression(&immed, 0); - format_3_instr($1, &sindex, &immed, &$2); - } -; - -code: - T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';' - { - format_3_instr($5, &$2, &$4, &$6); - } -; - -code: - T_TEST source ',' immediate_or_a jz_jnz address ';' - { - format_3_instr($5, &$2, &$4, &$6); - } -; - -code: - T_CMP source ',' immediate_or_a je_jne address ';' - { - format_3_instr($5, &$2, &$4, &$6); - } -; - -code: - T_MOV source jmp_jc_jnc_call address ';' - { - expression_t immed; - - make_expression(&immed, 0); - format_3_instr($3, &$2, &immed, &$4); - } -; - -code: - T_MVI immediate jmp_jc_jnc_call address ';' - { - format_3_instr($3, &allzeros, &$2, &$4); - } -; - -%% - -static void -process_field(int field_type, symbol_t *sym, int value) -{ - /* - * Add the current register to its - * symbol list, if it already exists, - * warn if we are setting it to a - * different value, or in the bit to - * the "allowed bits" of this register. - */ - if (sym->type == UNINITIALIZED) { - sym->type = field_type; - initialize_symbol(sym); - sym->info.finfo->value = value; - if (field_type != ENUM_ENTRY) { - if (field_type != MASK && value == 0) { - stop("Empty Field, or Enum", EX_DATAERR); - /* NOTREACHED */ - } - sym->info.finfo->value = value; - sym->info.finfo->mask = value; - } else if (field_symbol != NULL) { - sym->info.finfo->mask = field_symbol->info.finfo->value; - } else { - sym->info.finfo->mask = 0xFF; - } - } else if (sym->type != field_type) { - stop("Field definition mirrors a definition of the same " - " name, but a different type", EX_DATAERR); - /* NOTREACHED */ - } else if (value != sym->info.finfo->value) { - stop("Field redefined with a conflicting value", EX_DATAERR); - /* NOTREACHED */ - } - /* Fail if this symbol is already listed */ - if (symlist_search(&(sym->info.finfo->symrefs), - cur_symbol->name) != NULL) { - stop("Field defined multiple times for register", EX_DATAERR); - /* NOTREACHED */ - } - symlist_add(&(sym->info.finfo->symrefs), cur_symbol, - SYMLIST_INSERT_HEAD); - cur_symbol->info.rinfo->valid_bitmask |= sym->info.finfo->mask; - cur_symbol->info.rinfo->typecheck_masks = TRUE; - symlist_add(&(cur_symbol->info.rinfo->fields), sym, SYMLIST_SORT); -} - -static void -initialize_symbol(symbol_t *symbol) -{ - switch (symbol->type) { - case UNINITIALIZED: - stop("Call to initialize_symbol with type field unset", - EX_SOFTWARE); - /* NOTREACHED */ - break; - case REGISTER: - case SRAMLOC: - case SCBLOC: - symbol->info.rinfo = - (struct reg_info *)malloc(sizeof(struct reg_info)); - if (symbol->info.rinfo == NULL) { - stop("Can't create register info", EX_SOFTWARE); - /* NOTREACHED */ - } - memset(symbol->info.rinfo, 0, - sizeof(struct reg_info)); - SLIST_INIT(&(symbol->info.rinfo->fields)); - /* - * Default to allowing access in all register modes - * or to the mode specified by the SCB or SRAM space - * we are in. - */ - if (scb_or_sram_symbol != NULL) - symbol->info.rinfo->modes = - scb_or_sram_symbol->info.rinfo->modes; - else - symbol->info.rinfo->modes = ~0; - break; - case ALIAS: - symbol->info.ainfo = - (struct alias_info *)malloc(sizeof(struct alias_info)); - if (symbol->info.ainfo == NULL) { - stop("Can't create alias info", EX_SOFTWARE); - /* NOTREACHED */ - } - memset(symbol->info.ainfo, 0, - sizeof(struct alias_info)); - break; - case MASK: - case FIELD: - case ENUM: - case ENUM_ENTRY: - symbol->info.finfo = - (struct field_info *)malloc(sizeof(struct field_info)); - if (symbol->info.finfo == NULL) { - stop("Can't create field info", EX_SOFTWARE); - /* NOTREACHED */ - } - memset(symbol->info.finfo, 0, sizeof(struct field_info)); - SLIST_INIT(&(symbol->info.finfo->symrefs)); - break; - case CONST: - case DOWNLOAD_CONST: - symbol->info.cinfo = - (struct const_info *)malloc(sizeof(struct const_info)); - if (symbol->info.cinfo == NULL) { - stop("Can't create alias info", EX_SOFTWARE); - /* NOTREACHED */ - } - memset(symbol->info.cinfo, 0, - sizeof(struct const_info)); - break; - case LABEL: - symbol->info.linfo = - (struct label_info *)malloc(sizeof(struct label_info)); - if (symbol->info.linfo == NULL) { - stop("Can't create label info", EX_SOFTWARE); - /* NOTREACHED */ - } - memset(symbol->info.linfo, 0, - sizeof(struct label_info)); - break; - case CONDITIONAL: - symbol->info.condinfo = - (struct cond_info *)malloc(sizeof(struct cond_info)); - if (symbol->info.condinfo == NULL) { - stop("Can't create conditional info", EX_SOFTWARE); - /* NOTREACHED */ - } - memset(symbol->info.condinfo, 0, - sizeof(struct cond_info)); - break; - case MACRO: - symbol->info.macroinfo = - (struct macro_info *)malloc(sizeof(struct macro_info)); - if (symbol->info.macroinfo == NULL) { - stop("Can't create macro info", EX_SOFTWARE); - /* NOTREACHED */ - } - memset(symbol->info.macroinfo, 0, - sizeof(struct macro_info)); - STAILQ_INIT(&symbol->info.macroinfo->args); - break; - default: - stop("Call to initialize_symbol with invalid symbol type", - EX_SOFTWARE); - /* NOTREACHED */ - break; - } -} - -static void -add_macro_arg(const char *argtext, int argnum) -{ - struct macro_arg *marg; - int i; - int retval; - - - if (cur_symbol == NULL || cur_symbol->type != MACRO) { - stop("Invalid current symbol for adding macro arg", - EX_SOFTWARE); - /* NOTREACHED */ - } - - marg = (struct macro_arg *)malloc(sizeof(*marg)); - if (marg == NULL) { - stop("Can't create macro_arg structure", EX_SOFTWARE); - /* NOTREACHED */ - } - marg->replacement_text = NULL; - retval = snprintf(regex_pattern, sizeof(regex_pattern), - "[^-/A-Za-z0-9_](%s)([^-/A-Za-z0-9_]|$)", - argtext); - if (retval >= sizeof(regex_pattern)) { - stop("Regex text buffer too small for arg", - EX_SOFTWARE); - /* NOTREACHED */ - } - retval = regcomp(&marg->arg_regex, regex_pattern, REG_EXTENDED); - if (retval != 0) { - stop("Regex compilation failed", EX_SOFTWARE); - /* NOTREACHED */ - } - STAILQ_INSERT_TAIL(&cur_symbol->info.macroinfo->args, marg, links); -} - -static void -add_macro_body(const char *bodytext) -{ - if (cur_symbol == NULL || cur_symbol->type != MACRO) { - stop("Invalid current symbol for adding macro arg", - EX_SOFTWARE); - /* NOTREACHED */ - } - cur_symbol->info.macroinfo->body = strdup(bodytext); - if (cur_symbol->info.macroinfo->body == NULL) { - stop("Can't duplicate macro body text", EX_SOFTWARE); - /* NOTREACHED */ - } -} - -static void -process_register(symbol_t **p_symbol) -{ - symbol_t *symbol = *p_symbol; - - if (symbol->type == UNINITIALIZED) { - snprintf(errbuf, sizeof(errbuf), "Undefined register %s", - symbol->name); - stop(errbuf, EX_DATAERR); - /* NOTREACHED */ - } else if (symbol->type == ALIAS) { - *p_symbol = symbol->info.ainfo->parent; - } else if ((symbol->type != REGISTER) - && (symbol->type != SCBLOC) - && (symbol->type != SRAMLOC)) { - snprintf(errbuf, sizeof(errbuf), - "Specified symbol %s is not a register", - symbol->name); - stop(errbuf, EX_DATAERR); - } -} - -static void -format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed, - symbol_ref_t *src, int ret) -{ - struct instruction *instr; - struct ins_format1 *f1_instr; - - if (src->symbol == NULL) - src = dest; - - /* Test register permissions */ - test_writable_symbol(dest->symbol); - test_readable_symbol(src->symbol); - - /* Ensure that immediate makes sense for this destination */ - type_check(dest->symbol, immed, opcode); - - /* Allocate sequencer space for the instruction and fill it out */ - instr = seq_alloc(); - f1_instr = &instr->format.format1; - f1_instr->ret = ret ? 1 : 0; - f1_instr->opcode = opcode; - f1_instr->destination = dest->symbol->info.rinfo->address - + dest->offset; - f1_instr->source = src->symbol->info.rinfo->address - + src->offset; - f1_instr->immediate = immed->value; - - if (is_download_const(immed)) - f1_instr->parity = 1; - else if (dest->symbol == mode_ptr.symbol) { - u_int src_value; - u_int dst_value; - - /* - * Attempt to update mode information if - * we are operating on the mode register. - */ - if (src->symbol == allones.symbol) - src_value = 0xFF; - else if (src->symbol == allzeros.symbol) - src_value = 0; - else if (src->symbol == mode_ptr.symbol) - src_value = (dst_mode << 4) | src_mode; - else - goto cant_update; - - switch (opcode) { - case AIC_OP_AND: - dst_value = src_value & immed->value; - break; - case AIC_OP_XOR: - dst_value = src_value ^ immed->value; - break; - case AIC_OP_ADD: - dst_value = (src_value + immed->value) & 0xFF; - break; - case AIC_OP_OR: - dst_value = src_value | immed->value; - break; - case AIC_OP_BMOV: - dst_value = src_value; - break; - default: - goto cant_update; - } - src_mode = dst_value & 0xF; - dst_mode = (dst_value >> 4) & 0xF; - } - -cant_update: - symlist_free(&immed->referenced_syms); - instruction_ptr++; -} - -static void -format_2_instr(int opcode, symbol_ref_t *dest, expression_t *places, - symbol_ref_t *src, int ret) -{ - struct instruction *instr; - struct ins_format2 *f2_instr; - uint8_t shift_control; - - if (src->symbol == NULL) - src = dest; - - /* Test register permissions */ - test_writable_symbol(dest->symbol); - test_readable_symbol(src->symbol); - - /* Allocate sequencer space for the instruction and fill it out */ - instr = seq_alloc(); - f2_instr = &instr->format.format2; - f2_instr->ret = ret ? 1 : 0; - f2_instr->opcode = AIC_OP_ROL; - f2_instr->destination = dest->symbol->info.rinfo->address - + dest->offset; - f2_instr->source = src->symbol->info.rinfo->address - + src->offset; - if (places->value > 8 || places->value <= 0) { - stop("illegal shift value", EX_DATAERR); - /* NOTREACHED */ - } - switch (opcode) { - case AIC_OP_SHL: - if (places->value == 8) - shift_control = 0xf0; - else - shift_control = (places->value << 4) | places->value; - break; - case AIC_OP_SHR: - if (places->value == 8) { - shift_control = 0xf8; - } else { - shift_control = (places->value << 4) - | (8 - places->value) - | 0x08; - } - break; - case AIC_OP_ROL: - shift_control = places->value & 0x7; - break; - case AIC_OP_ROR: - shift_control = (8 - places->value) | 0x08; - break; - default: - shift_control = 0; /* Quiet Compiler */ - stop("Invalid shift operation specified", EX_SOFTWARE); - /* NOTREACHED */ - break; - }; - f2_instr->shift_control = shift_control; - symlist_free(&places->referenced_syms); - instruction_ptr++; -} - -static void -format_3_instr(int opcode, symbol_ref_t *src, - expression_t *immed, symbol_ref_t *address) -{ - struct instruction *instr; - struct ins_format3 *f3_instr; - int addr; - - /* Test register permissions */ - test_readable_symbol(src->symbol); - - /* Ensure that immediate makes sense for this source */ - type_check(src->symbol, immed, opcode); - - /* Allocate sequencer space for the instruction and fill it out */ - instr = seq_alloc(); - f3_instr = &instr->format.format3; - if (address->symbol == NULL) { - /* 'dot' referrence. Use the current instruction pointer */ - addr = instruction_ptr + address->offset; - } else if (address->symbol->type == UNINITIALIZED) { - /* forward reference */ - addr = address->offset; - instr->patch_label = address->symbol; - } else - addr = address->symbol->info.linfo->address + address->offset; - f3_instr->opcode = opcode; - f3_instr->address = addr; - f3_instr->source = src->symbol->info.rinfo->address - + src->offset; - f3_instr->immediate = immed->value; - - if (is_download_const(immed)) - f3_instr->parity = 1; - - symlist_free(&immed->referenced_syms); - instruction_ptr++; -} - -static void -test_readable_symbol(symbol_t *symbol) -{ - - if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) { - snprintf(errbuf, sizeof(errbuf), - "Register %s unavailable in source reg mode %d", - symbol->name, src_mode); - stop(errbuf, EX_DATAERR); - } - - if (symbol->info.rinfo->mode == WO) { - stop("Write Only register specified as source", - EX_DATAERR); - /* NOTREACHED */ - } -} - -static void -test_writable_symbol(symbol_t *symbol) -{ - - if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) { - snprintf(errbuf, sizeof(errbuf), - "Register %s unavailable in destination reg mode %d", - symbol->name, dst_mode); - stop(errbuf, EX_DATAERR); - } - - if (symbol->info.rinfo->mode == RO) { - stop("Read Only register specified as destination", - EX_DATAERR); - /* NOTREACHED */ - } -} - -static void -type_check(symbol_t *symbol, expression_t *expression, int opcode) -{ - symbol_node_t *node; - int and_op; - - and_op = FALSE; - if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ) - and_op = TRUE; - - /* - * Make sure that we aren't attempting to write something - * that hasn't been defined. If this is an and operation, - * this is a mask, so "undefined" bits are okay. - */ - if (and_op == FALSE - && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) { - snprintf(errbuf, sizeof(errbuf), - "Invalid bit(s) 0x%x in immediate written to %s", - expression->value & ~symbol->info.rinfo->valid_bitmask, - symbol->name); - stop(errbuf, EX_DATAERR); - /* NOTREACHED */ - } - - /* - * Now make sure that all of the symbols referenced by the - * expression are defined for this register. - */ - if (symbol->info.rinfo->typecheck_masks != FALSE) { - for(node = expression->referenced_syms.slh_first; - node != NULL; - node = node->links.sle_next) { - if ((node->symbol->type == MASK - || node->symbol->type == FIELD - || node->symbol->type == ENUM - || node->symbol->type == ENUM_ENTRY) - && symlist_search(&node->symbol->info.finfo->symrefs, - symbol->name) == NULL) { - snprintf(errbuf, sizeof(errbuf), - "Invalid field or mask %s " - "for register %s", - node->symbol->name, symbol->name); - stop(errbuf, EX_DATAERR); - /* NOTREACHED */ - } - } - } -} - -static void -make_expression(expression_t *immed, int value) -{ - SLIST_INIT(&immed->referenced_syms); - immed->value = value & 0xff; -} - -static void -add_conditional(symbol_t *symbol) -{ - static int numfuncs; - - if (numfuncs == 0) { - /* add a special conditional, "0" */ - symbol_t *false_func; - - false_func = symtable_get("0"); - if (false_func->type != UNINITIALIZED) { - stop("Conditional expression '0' " - "conflicts with a symbol", EX_DATAERR); - /* NOTREACHED */ - } - false_func->type = CONDITIONAL; - initialize_symbol(false_func); - false_func->info.condinfo->func_num = numfuncs++; - symlist_add(&patch_functions, false_func, SYMLIST_INSERT_HEAD); - } - - /* This condition has occurred before */ - if (symbol->type == CONDITIONAL) - return; - - if (symbol->type != UNINITIALIZED) { - stop("Conditional expression conflicts with a symbol", - EX_DATAERR); - /* NOTREACHED */ - } - - symbol->type = CONDITIONAL; - initialize_symbol(symbol); - symbol->info.condinfo->func_num = numfuncs++; - symlist_add(&patch_functions, symbol, SYMLIST_INSERT_HEAD); -} - -static void -add_version(const char *verstring) -{ - const char prefix[] = " * "; - int newlen; - int oldlen; - - newlen = strlen(verstring) + strlen(prefix); - oldlen = 0; - if (versions != NULL) - oldlen = strlen(versions); - versions = realloc(versions, newlen + oldlen + 2); - if (versions == NULL) - stop("Can't allocate version string", EX_SOFTWARE); - strcpy(&versions[oldlen], prefix); - strcpy(&versions[oldlen + strlen(prefix)], verstring); - versions[newlen + oldlen] = '\n'; - versions[newlen + oldlen + 1] = '\0'; -} - -void -yyerror(const char *string) -{ - stop(string, EX_DATAERR); -} - -static int -is_download_const(expression_t *immed) -{ - if ((immed->referenced_syms.slh_first != NULL) - && (immed->referenced_syms.slh_first->symbol->type == DOWNLOAD_CONST)) - return (TRUE); - - return (FALSE); -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_insformat.h linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_insformat.h --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_insformat.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_insformat.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,131 +0,0 @@ -/* - * Instruction formats for the sequencer program downloaded to - * Aic7xxx SCSI host adapters - * - * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 $ - * - * $FreeBSD$ - */ - -struct ins_format1 { -#if BYTE_ORDER == LITTLE_ENDIAN - uint32_t immediate : 8, - source : 9, - destination : 9, - ret : 1, - opcode : 4, - parity : 1; -#else - uint32_t parity : 1, - opcode : 4, - ret : 1, - destination : 9, - source : 9, - immediate : 8; -#endif -}; - -struct ins_format2 { -#if BYTE_ORDER == LITTLE_ENDIAN - uint32_t shift_control : 8, - source : 9, - destination : 9, - ret : 1, - opcode : 4, - parity : 1; -#else - uint32_t parity : 1, - opcode : 4, - ret : 1, - destination : 9, - source : 9, - shift_control : 8; -#endif -}; - -struct ins_format3 { -#if BYTE_ORDER == LITTLE_ENDIAN - uint32_t immediate : 8, - source : 9, - address : 10, - opcode : 4, - parity : 1; -#else - uint32_t parity : 1, - opcode : 4, - address : 10, - source : 9, - immediate : 8; -#endif -}; - -union ins_formats { - struct ins_format1 format1; - struct ins_format2 format2; - struct ins_format3 format3; - uint8_t bytes[4]; - uint32_t integer; -}; -struct instruction { - union ins_formats format; - u_int srcline; - struct symbol *patch_label; - STAILQ_ENTRY(instruction) links; -}; - -#define AIC_OP_OR 0x0 -#define AIC_OP_AND 0x1 -#define AIC_OP_XOR 0x2 -#define AIC_OP_ADD 0x3 -#define AIC_OP_ADC 0x4 -#define AIC_OP_ROL 0x5 -#define AIC_OP_BMOV 0x6 - -#define AIC_OP_JMP 0x8 -#define AIC_OP_JC 0x9 -#define AIC_OP_JNC 0xa -#define AIC_OP_CALL 0xb -#define AIC_OP_JNE 0xc -#define AIC_OP_JNZ 0xd -#define AIC_OP_JE 0xe -#define AIC_OP_JZ 0xf - -/* Pseudo Ops */ -#define AIC_OP_SHL 0x10 -#define AIC_OP_SHR 0x20 -#define AIC_OP_ROR 0x30 diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_macro_gram.y 1969-12-31 16:00:00.000000000 -0800 @@ -1,164 +0,0 @@ -%{ -/* - * Sub-parser for macro invocation in the Aic7xxx SCSI - * Host adapter sequencer assembler. - * - * Copyright (c) 2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $ - * - * $FreeBSD$ - */ - -#include - -#include -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include "../queue.h" -#else -#include -#endif - -#include "aicasm.h" -#include "aicasm_symbol.h" -#include "aicasm_insformat.h" - -static symbol_t *macro_symbol; - -static void add_macro_arg(const char *argtext, int position); - -%} - -%union { - int value; - char *str; - symbol_t *sym; -} - - -%token T_ARG - -%token T_SYMBOL - -%type macro_arglist - -%% - -macrocall: - T_SYMBOL '(' - { - macro_symbol = $1; - } - macro_arglist ')' - { - if (macro_symbol->info.macroinfo->narg != $4) { - printf("Narg == %d", macro_symbol->info.macroinfo->narg); - stop("Too few arguments for macro invocation", - EX_DATAERR); - /* NOTREACHED */ - } - macro_symbol = NULL; - YYACCEPT; - } -; - -macro_arglist: - { - /* Macros can take 0 arguments */ - $$ = 0; - } -| T_ARG - { - $$ = 1; - add_macro_arg($1, 1); - } -| macro_arglist ',' T_ARG - { - if ($1 == 0) { - stop("Comma without preceeding argument in arg list", - EX_DATAERR); - /* NOTREACHED */ - } - $$ = $1 + 1; - add_macro_arg($3, $$); - } -; - -%% - -static void -add_macro_arg(const char *argtext, int argnum) -{ - struct macro_arg *marg; - int i; - - if (macro_symbol == NULL || macro_symbol->type != MACRO) { - stop("Invalid current symbol for adding macro arg", - EX_SOFTWARE); - /* NOTREACHED */ - } - /* - * Macro Invocation. Find the appropriate argument and fill - * in the replace ment text for this call. - */ - i = 0; - STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { - i++; - if (i == argnum) - break; - } - if (marg == NULL) { - stop("Too many arguments for macro invocation", EX_DATAERR); - /* NOTREACHED */ - } - marg->replacement_text = strdup(argtext); - if (marg->replacement_text == NULL) { - stop("Unable to replicate replacement text", EX_SOFTWARE); - /* NOTREACHED */ - } -} - -void -mmerror(const char *string) -{ - stop(string, EX_DATAERR); -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_macro_scan.l 1969-12-31 16:00:00.000000000 -0800 @@ -1,155 +0,0 @@ -%{ -/* - * Sub-Lexical Analyzer for macro invokation in - * the Aic7xxx SCSI Host adapter sequencer assembler. - * - * Copyright (c) 2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#7 $ - * - * $FreeBSD$ - */ - -#include - -#include -#include -#include -#include -#include -#include -#ifdef __linux__ -#include "../queue.h" -#else -#include -#endif - -#include "aicasm.h" -#include "aicasm_symbol.h" -#include "aicasm_macro_gram.h" - -#define MAX_STR_CONST 4096 -static char string_buf[MAX_STR_CONST]; -static char *string_buf_ptr; -static int parren_count; -static char buf[255]; -%} - -WORD [A-Za-z_][-A-Za-z_0-9]* -SPACE [ \t]+ -MCARG [^(), \t]+ - -%x ARGLIST - -%% -\n { - ++yylineno; - } -{SPACE} ; -\( { - parren_count++; - if (parren_count == 1) { - string_buf_ptr = string_buf; - return ('('); - } - *string_buf_ptr++ = '('; - } -\) { - if (parren_count == 1) { - if (string_buf_ptr != string_buf) { - /* - * Return an argument and - * rescan this parren so we - * can return it as well. - */ - *string_buf_ptr = '\0'; - mmlval.str = string_buf; - string_buf_ptr = string_buf; - unput(')'); - return T_ARG; - } - BEGIN INITIAL; - return (')'); - } - parren_count--; - *string_buf_ptr++ = ')'; - } -{MCARG} { - char *yptr; - - yptr = mmtext; - while (*yptr) - *string_buf_ptr++ = *yptr++; - } -\, { - if (string_buf_ptr != string_buf) { - /* - * Return an argument and - * rescan this comma so we - * can return it as well. - */ - *string_buf_ptr = '\0'; - mmlval.str = string_buf; - string_buf_ptr = string_buf; - unput(','); - return T_ARG; - } - return ','; - } -{WORD}[(] { - /* May be a symbol or a macro invocation. */ - mmlval.sym = symtable_get(mmtext); - if (mmlval.sym->type != MACRO) { - stop("Expecting Macro Name", - EX_DATAERR); - } - unput('('); - parren_count = 0; - BEGIN ARGLIST; - return T_SYMBOL; - } -. { - snprintf(buf, sizeof(buf), "Invalid character " - "'%c'", mmtext[0]); - stop(buf, EX_DATAERR); - } -%% - -int -mmwrap() -{ - stop("EOF encountered in macro call", EX_DATAERR); -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_scan.l linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_scan.l --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_scan.l 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_scan.l 1969-12-31 16:00:00.000000000 -0800 @@ -1,597 +0,0 @@ -%{ -/* - * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. - * - * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. - * Copyright (c) 2001, 2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 $ - * - * $FreeBSD$ - */ - -#include - -#include -#include -#include -#include -#include -#include -#ifdef __linux__ -#include "../queue.h" -#else -#include -#endif - -#include "aicasm.h" -#include "aicasm_symbol.h" -#include "aicasm_gram.h" - -/* This is used for macro body capture too, so err on the large size. */ -#define MAX_STR_CONST 4096 -static char string_buf[MAX_STR_CONST]; -static char *string_buf_ptr; -static int parren_count; -static int quote_count; -static char buf[255]; -%} - -PATH ([/]*[-A-Za-z0-9_.])+ -WORD [A-Za-z_][-A-Za-z_0-9]* -SPACE [ \t]+ -MCARG [^(), \t]+ -MBODY ((\\[^\n])*[^\n\\]*)+ - -%x COMMENT -%x CEXPR -%x INCLUDE -%x STRING -%x MACRODEF -%x MACROARGLIST -%x MACROCALLARGS -%x MACROBODY - -%% -\n { ++yylineno; } -"/*" { BEGIN COMMENT; /* Enter comment eating state */ } -"/*" { fprintf(stderr, "Warning! Comment within comment."); } -\n { ++yylineno; } -[^*/\n]* ; -"*"+[^*/\n]* ; -"/"+[^*/\n]* ; -"*"+"/" { BEGIN INITIAL; } -if[ \t]*\( { - string_buf_ptr = string_buf; - parren_count = 1; - BEGIN CEXPR; - return T_IF; - } -\( { *string_buf_ptr++ = '('; parren_count++; } -\) { - parren_count--; - if (parren_count == 0) { - /* All done */ - BEGIN INITIAL; - *string_buf_ptr = '\0'; - yylval.sym = symtable_get(string_buf); - return T_CEXPR; - } else { - *string_buf_ptr++ = ')'; - } - } -\n { ++yylineno; } -[^()\n]+ { - char *yptr; - - yptr = yytext; - while (*yptr != '\0') { - /* Remove duplicate spaces */ - if (*yptr == '\t') - *yptr = ' '; - if (*yptr == ' ' - && string_buf_ptr != string_buf - && string_buf_ptr[-1] == ' ') - yptr++; - else - *string_buf_ptr++ = *yptr++; - } - } - -VERSION { return T_VERSION; } -PREFIX { return T_PREFIX; } -PATCH_ARG_LIST { return T_PATCH_ARG_LIST; } -\" { - string_buf_ptr = string_buf; - BEGIN STRING; - } -[^"]+ { - char *yptr; - - yptr = yytext; - while (*yptr) - *string_buf_ptr++ = *yptr++; - } -\" { - /* All done */ - BEGIN INITIAL; - *string_buf_ptr = '\0'; - yylval.str = string_buf; - return T_STRING; - } -{SPACE} ; - - /* Register/SCB/SRAM definition keywords */ -export { return T_EXPORT; } -register { return T_REGISTER; } -const { yylval.value = FALSE; return T_CONST; } -download { return T_DOWNLOAD; } -address { return T_ADDRESS; } -access_mode { return T_ACCESS_MODE; } -modes { return T_MODES; } -RW|RO|WO { - if (strcmp(yytext, "RW") == 0) - yylval.value = RW; - else if (strcmp(yytext, "RO") == 0) - yylval.value = RO; - else - yylval.value = WO; - return T_MODE; - } -BEGIN_CRITICAL { return T_BEGIN_CS; } -END_CRITICAL { return T_END_CS; } -SET_SRC_MODE { return T_SET_SRC_MODE; } -SET_DST_MODE { return T_SET_DST_MODE; } -field { return T_FIELD; } -enum { return T_ENUM; } -mask { return T_MASK; } -alias { return T_ALIAS; } -size { return T_SIZE; } -scb { return T_SCB; } -scratch_ram { return T_SRAM; } -accumulator { return T_ACCUM; } -mode_pointer { return T_MODE_PTR; } -allones { return T_ALLONES; } -allzeros { return T_ALLZEROS; } -none { return T_NONE; } -sindex { return T_SINDEX; } -A { return T_A; } - - /* Opcodes */ -shl { return T_SHL; } -shr { return T_SHR; } -ror { return T_ROR; } -rol { return T_ROL; } -mvi { return T_MVI; } -mov { return T_MOV; } -clr { return T_CLR; } -jmp { return T_JMP; } -jc { return T_JC; } -jnc { return T_JNC; } -je { return T_JE; } -jne { return T_JNE; } -jz { return T_JZ; } -jnz { return T_JNZ; } -call { return T_CALL; } -add { return T_ADD; } -adc { return T_ADC; } -bmov { return T_BMOV; } -inc { return T_INC; } -dec { return T_DEC; } -stc { return T_STC; } -clc { return T_CLC; } -cmp { return T_CMP; } -not { return T_NOT; } -xor { return T_XOR; } -test { return T_TEST;} -and { return T_AND; } -or { return T_OR; } -ret { return T_RET; } -nop { return T_NOP; } -else { return T_ELSE; } - - /* Allowed Symbols */ -\<\< { return T_EXPR_LSHIFT; } -\>\> { return T_EXPR_RSHIFT; } -[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; } - - /* Number processing */ -0[0-7]* { - yylval.value = strtol(yytext, NULL, 8); - return T_NUMBER; - } - -0[xX][0-9a-fA-F]+ { - yylval.value = strtoul(yytext + 2, NULL, 16); - return T_NUMBER; - } - -[1-9][0-9]* { - yylval.value = strtol(yytext, NULL, 10); - return T_NUMBER; - } - /* Include Files */ -#include{SPACE} { - BEGIN INCLUDE; - quote_count = 0; - return T_INCLUDE; - } -[<] { return yytext[0]; } -[>] { BEGIN INITIAL; return yytext[0]; } -[\"] { - if (quote_count != 0) - BEGIN INITIAL; - quote_count++; - return yytext[0]; - } -{PATH} { - char *yptr; - - yptr = yytext; - string_buf_ptr = string_buf; - while (*yptr) - *string_buf_ptr++ = *yptr++; - yylval.str = string_buf; - *string_buf_ptr = '\0'; - return T_PATH; - } -. { stop("Invalid include line", EX_DATAERR); } -#define{SPACE} { - BEGIN MACRODEF; - return T_DEFINE; - } -{WORD}{SPACE} { - char *yptr; - - /* Strip space and return as a normal symbol */ - yptr = yytext; - while (*yptr != ' ' && *yptr != '\t') - yptr++; - *yptr = '\0'; - yylval.sym = symtable_get(yytext); - string_buf_ptr = string_buf; - BEGIN MACROBODY; - return T_SYMBOL; - } -{WORD}\( { - /* - * We store the symbol with its opening - * parren so we can differentiate macros - * that take args from macros with the - * same name that do not take args as - * is allowed in C. - */ - BEGIN MACROARGLIST; - yylval.sym = symtable_get(yytext); - unput('('); - return T_SYMBOL; - } -{WORD} { - yylval.str = yytext; - return T_ARG; - } -{SPACE} ; -[(,] { - return yytext[0]; - } -[)] { - string_buf_ptr = string_buf; - BEGIN MACROBODY; - return ')'; - } -. { - snprintf(buf, sizeof(buf), "Invalid character " - "'%c' in macro argument list", - yytext[0]); - stop(buf, EX_DATAERR); - } -{SPACE} ; -\( { - parren_count++; - if (parren_count == 1) - return ('('); - *string_buf_ptr++ = '('; - } -\) { - parren_count--; - if (parren_count == 0) { - BEGIN INITIAL; - return (')'); - } - *string_buf_ptr++ = ')'; - } -{MCARG} { - char *yptr; - - yptr = yytext; - while (*yptr) - *string_buf_ptr++ = *yptr++; - } -\, { - if (string_buf_ptr != string_buf) { - /* - * Return an argument and - * rescan this comma so we - * can return it as well. - */ - *string_buf_ptr = '\0'; - yylval.str = string_buf; - string_buf_ptr = string_buf; - unput(','); - return T_ARG; - } - return ','; - } -\\\n { - /* Eat escaped newlines. */ - ++yylineno; - } -\n { - /* Macros end on the first unescaped newline. */ - BEGIN INITIAL; - *string_buf_ptr = '\0'; - yylval.str = string_buf; - ++yylineno; - return T_MACROBODY; - } -{MBODY} { - char *yptr; - - yptr = yytext; - while (*yptr) - *string_buf_ptr++ = *yptr++; - } -{WORD}\( { - char *yptr; - char *ycopy; - - /* May be a symbol or a macro invocation. */ - yylval.sym = symtable_get(yytext); - if (yylval.sym->type == MACRO) { - YY_BUFFER_STATE old_state; - YY_BUFFER_STATE temp_state; - - ycopy = strdup(yytext); - yptr = ycopy + yyleng; - while (yptr > ycopy) - unput(*--yptr); - old_state = YY_CURRENT_BUFFER; - temp_state = - yy_create_buffer(stdin, - YY_BUF_SIZE); - yy_switch_to_buffer(temp_state); - mm_switch_to_buffer(old_state); - mmparse(); - mm_switch_to_buffer(temp_state); - yy_switch_to_buffer(old_state); - mm_delete_buffer(temp_state); - expand_macro(yylval.sym); - } else { - if (yylval.sym->type == UNINITIALIZED) { - /* Try without the '(' */ - symbol_delete(yylval.sym); - yytext[yyleng-1] = '\0'; - yylval.sym = - symtable_get(yytext); - } - unput('('); - return T_SYMBOL; - } - } -{WORD} { - yylval.sym = symtable_get(yytext); - if (yylval.sym->type == MACRO) { - expand_macro(yylval.sym); - } else { - return T_SYMBOL; - } - } -. { - snprintf(buf, sizeof(buf), "Invalid character " - "'%c'", yytext[0]); - stop(buf, EX_DATAERR); - } -%% - -typedef struct include { - YY_BUFFER_STATE buffer; - int lineno; - char *filename; - SLIST_ENTRY(include) links; -}include_t; - -SLIST_HEAD(, include) include_stack; - -void -include_file(char *file_name, include_type type) -{ - FILE *newfile; - include_t *include; - - newfile = NULL; - /* Try the current directory first */ - if (includes_search_curdir != 0 || type == SOURCE_FILE) - newfile = fopen(file_name, "r"); - - if (newfile == NULL && type != SOURCE_FILE) { - path_entry_t include_dir; - for (include_dir = search_path.slh_first; - include_dir != NULL; - include_dir = include_dir->links.sle_next) { - char fullname[PATH_MAX]; - - if ((include_dir->quoted_includes_only == TRUE) - && (type != QUOTED_INCLUDE)) - continue; - - snprintf(fullname, sizeof(fullname), - "%s/%s", include_dir->directory, file_name); - - if ((newfile = fopen(fullname, "r")) != NULL) - break; - } - } - - if (newfile == NULL) { - perror(file_name); - stop("Unable to open input file", EX_SOFTWARE); - /* NOTREACHED */ - } - - if (type != SOURCE_FILE) { - include = (include_t *)malloc(sizeof(include_t)); - if (include == NULL) { - stop("Unable to allocate include stack entry", - EX_SOFTWARE); - /* NOTREACHED */ - } - include->buffer = YY_CURRENT_BUFFER; - include->lineno = yylineno; - include->filename = yyfilename; - SLIST_INSERT_HEAD(&include_stack, include, links); - } - yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); - yylineno = 1; - yyfilename = strdup(file_name); -} - -static void next_substitution(struct symbol *mac_symbol, const char *body_pos, - const char **next_match, - struct macro_arg **match_marg, regmatch_t *match); - -void -expand_macro(struct symbol *macro_symbol) -{ - struct macro_arg *marg; - struct macro_arg *match_marg; - const char *body_head; - const char *body_pos; - const char *next_match; - - /* - * Due to the nature of unput, we must work - * backwards through the macro body performing - * any expansions. - */ - body_head = macro_symbol->info.macroinfo->body; - body_pos = body_head + strlen(body_head); - while (body_pos > body_head) { - regmatch_t match; - - next_match = body_head; - match_marg = NULL; - next_substitution(macro_symbol, body_pos, &next_match, - &match_marg, &match); - - /* Put back everything up until the replacement. */ - while (body_pos > next_match) - unput(*--body_pos); - - /* Perform the replacement. */ - if (match_marg != NULL) { - const char *strp; - - next_match = match_marg->replacement_text; - strp = next_match + strlen(next_match); - while (strp > next_match) - unput(*--strp); - - /* Skip past the unexpanded macro arg. */ - body_pos -= match.rm_eo - match.rm_so; - } - } - - /* Cleanup replacement text. */ - STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { - free(marg->replacement_text); - } -} - -/* - * Find the next substitution in the macro working backwards from - * body_pos until the beginning of the macro buffer. next_match - * should be initialized to the beginning of the macro buffer prior - * to calling this routine. - */ -static void -next_substitution(struct symbol *mac_symbol, const char *body_pos, - const char **next_match, struct macro_arg **match_marg, - regmatch_t *match) -{ - regmatch_t matches[2]; - struct macro_arg *marg; - const char *search_pos; - int retval; - - do { - search_pos = *next_match; - - STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) { - - retval = regexec(&marg->arg_regex, search_pos, 2, - matches, 0); - if (retval == 0 - && (matches[1].rm_eo + search_pos) <= body_pos - && (matches[1].rm_eo + search_pos) > *next_match) { - *match = matches[1]; - *next_match = match->rm_eo + search_pos; - *match_marg = marg; - } - } - } while (search_pos != *next_match); -} - -int -yywrap() -{ - include_t *include; - - yy_delete_buffer(YY_CURRENT_BUFFER); - (void)fclose(yyin); - if (yyfilename != NULL) - free(yyfilename); - yyfilename = NULL; - include = include_stack.slh_first; - if (include != NULL) { - yy_switch_to_buffer(include->buffer); - yylineno = include->lineno; - yyfilename = include->filename; - SLIST_REMOVE_HEAD(&include_stack, links); - free(include); - return (0); - } - return (1); -} diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_symbol.c linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_symbol.c --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_symbol.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_symbol.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,677 +0,0 @@ -/* - * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation - * - * Copyright (c) 1997 Justin T. Gibbs. - * Copyright (c) 2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $ - * - * $FreeBSD$ - */ - -#include - -#ifdef __linux__ -#include "aicdb.h" -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -#include "aicasm_symbol.h" -#include "aicasm.h" - -static DB *symtable; - -symbol_t * -symbol_create(char *name) -{ - symbol_t *new_symbol; - - new_symbol = (symbol_t *)malloc(sizeof(symbol_t)); - if (new_symbol == NULL) { - perror("Unable to create new symbol"); - exit(EX_SOFTWARE); - } - memset(new_symbol, 0, sizeof(*new_symbol)); - new_symbol->name = strdup(name); - if (new_symbol->name == NULL) - stop("Unable to strdup symbol name", EX_SOFTWARE); - new_symbol->type = UNINITIALIZED; - return (new_symbol); -} - -void -symbol_delete(symbol_t *symbol) -{ - if (symtable != NULL) { - DBT key; - - key.data = symbol->name; - key.size = strlen(symbol->name); - symtable->del(symtable, &key, /*flags*/0); - } - switch(symbol->type) { - case SCBLOC: - case SRAMLOC: - case REGISTER: - if (symbol->info.rinfo != NULL) - free(symbol->info.rinfo); - break; - case ALIAS: - if (symbol->info.ainfo != NULL) - free(symbol->info.ainfo); - break; - case MASK: - case FIELD: - case ENUM: - case ENUM_ENTRY: - if (symbol->info.finfo != NULL) { - symlist_free(&symbol->info.finfo->symrefs); - free(symbol->info.finfo); - } - break; - case DOWNLOAD_CONST: - case CONST: - if (symbol->info.cinfo != NULL) - free(symbol->info.cinfo); - break; - case LABEL: - if (symbol->info.linfo != NULL) - free(symbol->info.linfo); - break; - case UNINITIALIZED: - default: - break; - } - free(symbol->name); - free(symbol); -} - -void -symtable_open() -{ - symtable = dbopen(/*filename*/NULL, - O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH, - /*openinfo*/NULL); - - if (symtable == NULL) { - perror("Symbol table creation failed"); - exit(EX_SOFTWARE); - /* NOTREACHED */ - } -} - -void -symtable_close() -{ - if (symtable != NULL) { - DBT key; - DBT data; - - while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) { - symbol_t *stored_ptr; - - memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); - symbol_delete(stored_ptr); - } - symtable->close(symtable); - } -} - -/* - * The semantics of get is to return an uninitialized symbol entry - * if a lookup fails. - */ -symbol_t * -symtable_get(char *name) -{ - symbol_t *stored_ptr; - DBT key; - DBT data; - int retval; - - key.data = (void *)name; - key.size = strlen(name); - - if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) { - if (retval == -1) { - perror("Symbol table get operation failed"); - exit(EX_SOFTWARE); - /* NOTREACHED */ - } else if (retval == 1) { - /* Symbol wasn't found, so create a new one */ - symbol_t *new_symbol; - - new_symbol = symbol_create(name); - data.data = &new_symbol; - data.size = sizeof(new_symbol); - if (symtable->put(symtable, &key, &data, - /*flags*/0) !=0) { - perror("Symtable put failed"); - exit(EX_SOFTWARE); - } - return (new_symbol); - } else { - perror("Unexpected return value from db get routine"); - exit(EX_SOFTWARE); - /* NOTREACHED */ - } - } - memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); - return (stored_ptr); -} - -symbol_node_t * -symlist_search(symlist_t *symlist, char *symname) -{ - symbol_node_t *curnode; - - curnode = SLIST_FIRST(symlist); - while(curnode != NULL) { - if (strcmp(symname, curnode->symbol->name) == 0) - break; - curnode = SLIST_NEXT(curnode, links); - } - return (curnode); -} - -void -symlist_add(symlist_t *symlist, symbol_t *symbol, int how) -{ - symbol_node_t *newnode; - - newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t)); - if (newnode == NULL) { - stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE); - /* NOTREACHED */ - } - newnode->symbol = symbol; - if (how == SYMLIST_SORT) { - symbol_node_t *curnode; - int field; - - field = FALSE; - switch(symbol->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - break; - case FIELD: - case MASK: - case ENUM: - case ENUM_ENTRY: - field = TRUE; - break; - default: - stop("symlist_add: Invalid symbol type for sorting", - EX_SOFTWARE); - /* NOTREACHED */ - } - - curnode = SLIST_FIRST(symlist); - if (curnode == NULL - || (field - && (curnode->symbol->type > newnode->symbol->type - || (curnode->symbol->type == newnode->symbol->type - && (curnode->symbol->info.finfo->value > - newnode->symbol->info.finfo->value)))) - || (!field && (curnode->symbol->info.rinfo->address > - newnode->symbol->info.rinfo->address))) { - SLIST_INSERT_HEAD(symlist, newnode, links); - return; - } - - while (1) { - if (SLIST_NEXT(curnode, links) == NULL) { - SLIST_INSERT_AFTER(curnode, newnode, - links); - break; - } else { - symbol_t *cursymbol; - - cursymbol = SLIST_NEXT(curnode, links)->symbol; - if ((field - && (cursymbol->type > symbol->type - || (cursymbol->type == symbol->type - && (cursymbol->info.finfo->value > - symbol->info.finfo->value)))) - || (!field - && (cursymbol->info.rinfo->address > - symbol->info.rinfo->address))) { - SLIST_INSERT_AFTER(curnode, newnode, - links); - break; - } - } - curnode = SLIST_NEXT(curnode, links); - } - } else { - SLIST_INSERT_HEAD(symlist, newnode, links); - } -} - -void -symlist_free(symlist_t *symlist) -{ - symbol_node_t *node1, *node2; - - node1 = SLIST_FIRST(symlist); - while (node1 != NULL) { - node2 = SLIST_NEXT(node1, links); - free(node1); - node1 = node2; - } - SLIST_INIT(symlist); -} - -void -symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, - symlist_t *symlist_src2) -{ - symbol_node_t *node; - - *symlist_dest = *symlist_src1; - while((node = SLIST_FIRST(symlist_src2)) != NULL) { - SLIST_REMOVE_HEAD(symlist_src2, links); - SLIST_INSERT_HEAD(symlist_dest, node, links); - } - - /* These are now empty */ - SLIST_INIT(symlist_src1); - SLIST_INIT(symlist_src2); -} - -void -aic_print_file_prologue(FILE *ofile) -{ - - if (ofile == NULL) - return; - - fprintf(ofile, -"/*\n" -" * DO NOT EDIT - This file is automatically generated\n" -" * from the following source files:\n" -" *\n" -"%s */\n", - versions); -} - -void -aic_print_include(FILE *dfile, char *include_file) -{ - - if (dfile == NULL) - return; - fprintf(dfile, "\n#include \"%s\"\n\n", include_file); -} - -void -aic_print_reg_dump_types(FILE *ofile) -{ - if (ofile == NULL) - return; - - fprintf(ofile, -"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n" -"typedef struct %sreg_parse_entry {\n" -" char *name;\n" -" uint8_t value;\n" -" uint8_t mask;\n" -"} %sreg_parse_entry_t;\n" -"\n", - prefix, prefix, prefix); -} - -static void -aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode) -{ - if (dfile == NULL) - return; - - fprintf(dfile, -"static %sreg_parse_entry_t %s_parse_table[] = {\n", - prefix, - regnode->symbol->name); -} - -static void -aic_print_reg_dump_end(FILE *ofile, FILE *dfile, - symbol_node_t *regnode, u_int num_entries) -{ - char *lower_name; - char *letter; - - lower_name = strdup(regnode->symbol->name); - if (lower_name == NULL) - stop("Unable to strdup symbol name", EX_SOFTWARE); - - for (letter = lower_name; *letter != '\0'; letter++) - *letter = tolower(*letter); - - if (dfile != NULL) { - if (num_entries != 0) - fprintf(dfile, -"\n" -"};\n" -"\n"); - - fprintf(dfile, -"int\n" -"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n" -"{\n" -" return (%sprint_register(%s%s, %d, \"%s\",\n" -" 0x%02x, regvalue, cur_col, wrap));\n" -"}\n" -"\n", - prefix, - lower_name, - prefix, - num_entries != 0 ? regnode->symbol->name : "NULL", - num_entries != 0 ? "_parse_table" : "", - num_entries, - regnode->symbol->name, - regnode->symbol->info.rinfo->address); - } - - fprintf(ofile, -"#if AIC_DEBUG_REGISTERS\n" -"%sreg_print_t %s%s_print;\n" -"#else\n" -"#define %s%s_print(regvalue, cur_col, wrap) \\\n" -" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n" -"#endif\n" -"\n", - prefix, - prefix, - lower_name, - prefix, - lower_name, - prefix, - regnode->symbol->name, - regnode->symbol->info.rinfo->address); -} - -static void -aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode) -{ - int num_tabs; - - if (dfile == NULL) - return; - - fprintf(dfile, -" { \"%s\",", - curnode->symbol->name); - - num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8; - - while (num_tabs-- > 0) - fputc('\t', dfile); - fprintf(dfile, "0x%02x, 0x%02x }", - curnode->symbol->info.finfo->value, - curnode->symbol->info.finfo->mask); -} - -void -symtable_dump(FILE *ofile, FILE *dfile) -{ - /* - * Sort the registers by address with a simple insertion sort. - * Put bitmasks next to the first register that defines them. - * Put constants at the end. - */ - symlist_t registers; - symlist_t masks; - symlist_t constants; - symlist_t download_constants; - symlist_t aliases; - symlist_t exported_labels; - symbol_node_t *curnode; - symbol_node_t *regnode; - DBT key; - DBT data; - int flag; - u_int i; - - if (symtable == NULL) - return; - - SLIST_INIT(®isters); - SLIST_INIT(&masks); - SLIST_INIT(&constants); - SLIST_INIT(&download_constants); - SLIST_INIT(&aliases); - SLIST_INIT(&exported_labels); - flag = R_FIRST; - while (symtable->seq(symtable, &key, &data, flag) == 0) { - symbol_t *cursym; - - memcpy(&cursym, data.data, sizeof(cursym)); - switch(cursym->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - symlist_add(®isters, cursym, SYMLIST_SORT); - break; - case MASK: - case FIELD: - case ENUM: - case ENUM_ENTRY: - symlist_add(&masks, cursym, SYMLIST_SORT); - break; - case CONST: - symlist_add(&constants, cursym, - SYMLIST_INSERT_HEAD); - break; - case DOWNLOAD_CONST: - symlist_add(&download_constants, cursym, - SYMLIST_INSERT_HEAD); - break; - case ALIAS: - symlist_add(&aliases, cursym, - SYMLIST_INSERT_HEAD); - break; - case LABEL: - if (cursym->info.linfo->exported == 0) - break; - symlist_add(&exported_labels, cursym, - SYMLIST_INSERT_HEAD); - break; - default: - break; - } - flag = R_NEXT; - } - - /* Register dianostic functions/declarations first. */ - aic_print_file_prologue(ofile); - aic_print_reg_dump_types(ofile); - aic_print_file_prologue(dfile); - aic_print_include(dfile, stock_include_file); - SLIST_FOREACH(curnode, ®isters, links) { - - switch(curnode->symbol->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - { - symlist_t *fields; - symbol_node_t *fieldnode; - int num_entries; - - num_entries = 0; - fields = &curnode->symbol->info.rinfo->fields; - SLIST_FOREACH(fieldnode, fields, links) { - if (num_entries == 0) - aic_print_reg_dump_start(dfile, - curnode); - else if (dfile != NULL) - fputs(",\n", dfile); - num_entries++; - aic_print_reg_dump_entry(dfile, fieldnode); - } - aic_print_reg_dump_end(ofile, dfile, - curnode, num_entries); - } - default: - break; - } - } - - /* Fold in the masks and bits */ - while (SLIST_FIRST(&masks) != NULL) { - char *regname; - - curnode = SLIST_FIRST(&masks); - SLIST_REMOVE_HEAD(&masks, links); - - regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs); - regname = regnode->symbol->name; - regnode = symlist_search(®isters, regname); - SLIST_INSERT_AFTER(regnode, curnode, links); - } - - /* Add the aliases */ - while (SLIST_FIRST(&aliases) != NULL) { - char *regname; - - curnode = SLIST_FIRST(&aliases); - SLIST_REMOVE_HEAD(&aliases, links); - - regname = curnode->symbol->info.ainfo->parent->name; - regnode = symlist_search(®isters, regname); - SLIST_INSERT_AFTER(regnode, curnode, links); - } - - /* Output generated #defines. */ - while (SLIST_FIRST(®isters) != NULL) { - symbol_node_t *curnode; - u_int value; - char *tab_str; - char *tab_str2; - - curnode = SLIST_FIRST(®isters); - SLIST_REMOVE_HEAD(®isters, links); - switch(curnode->symbol->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - fprintf(ofile, "\n"); - value = curnode->symbol->info.rinfo->address; - tab_str = "\t"; - tab_str2 = "\t\t"; - break; - case ALIAS: - { - symbol_t *parent; - - parent = curnode->symbol->info.ainfo->parent; - value = parent->info.rinfo->address; - tab_str = "\t"; - tab_str2 = "\t\t"; - break; - } - case MASK: - case FIELD: - case ENUM: - case ENUM_ENTRY: - value = curnode->symbol->info.finfo->value; - tab_str = "\t\t"; - tab_str2 = "\t"; - break; - default: - value = 0; /* Quiet compiler */ - tab_str = NULL; - tab_str2 = NULL; - stop("symtable_dump: Invalid symbol type " - "encountered", EX_SOFTWARE); - break; - } - fprintf(ofile, "#define%s%-16s%s0x%02x\n", - tab_str, curnode->symbol->name, tab_str2, - value); - free(curnode); - } - fprintf(ofile, "\n\n"); - - while (SLIST_FIRST(&constants) != NULL) { - symbol_node_t *curnode; - - curnode = SLIST_FIRST(&constants); - SLIST_REMOVE_HEAD(&constants, links); - fprintf(ofile, "#define\t%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.cinfo->value); - free(curnode); - } - - - fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); - - for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { - symbol_node_t *curnode; - - curnode = SLIST_FIRST(&download_constants); - SLIST_REMOVE_HEAD(&download_constants, links); - fprintf(ofile, "#define\t%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.cinfo->value); - free(curnode); - } - fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); - - fprintf(ofile, "\n\n/* Exported Labels */\n"); - - while (SLIST_FIRST(&exported_labels) != NULL) { - symbol_node_t *curnode; - - curnode = SLIST_FIRST(&exported_labels); - SLIST_REMOVE_HEAD(&exported_labels, links); - fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.linfo->address); - free(curnode); - } -} - diff -urN linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_symbol.h linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_symbol.h --- linux-2.4.21/drivers/scsi/aic79xx/aicasm/aicasm_symbol.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aicasm/aicasm_symbol.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,207 +0,0 @@ -/* - * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions - * - * Copyright (c) 1997 Justin T. Gibbs. - * Copyright (c) 2002 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#17 $ - * - * $FreeBSD$ - */ - -#ifdef __linux__ -#include "../queue.h" -#else -#include -#endif - -typedef enum { - UNINITIALIZED, - REGISTER, - ALIAS, - SCBLOC, - SRAMLOC, - ENUM_ENTRY, - FIELD, - MASK, - ENUM, - CONST, - DOWNLOAD_CONST, - LABEL, - CONDITIONAL, - MACRO -} symtype; - -typedef enum { - RO = 0x01, - WO = 0x02, - RW = 0x03 -}amode_t; - -typedef SLIST_HEAD(symlist, symbol_node) symlist_t; - -struct reg_info { - u_int address; - int size; - amode_t mode; - symlist_t fields; - uint8_t valid_bitmask; - uint8_t modes; - int typecheck_masks; -}; - -struct field_info { - symlist_t symrefs; - uint8_t value; - uint8_t mask; -}; - -struct const_info { - u_int value; - int define; -}; - -struct alias_info { - struct symbol *parent; -}; - -struct label_info { - int address; - int exported; -}; - -struct cond_info { - int func_num; -}; - -struct macro_arg { - STAILQ_ENTRY(macro_arg) links; - regex_t arg_regex; - char *replacement_text; -}; -STAILQ_HEAD(macro_arg_list, macro_arg) args; - -struct macro_info { - struct macro_arg_list args; - int narg; - const char* body; -}; - -typedef struct expression_info { - symlist_t referenced_syms; - int value; -} expression_t; - -typedef struct symbol { - char *name; - symtype type; - union { - struct reg_info *rinfo; - struct field_info *finfo; - struct const_info *cinfo; - struct alias_info *ainfo; - struct label_info *linfo; - struct cond_info *condinfo; - struct macro_info *macroinfo; - }info; -} symbol_t; - -typedef struct symbol_ref { - symbol_t *symbol; - int offset; -} symbol_ref_t; - -typedef struct symbol_node { - SLIST_ENTRY(symbol_node) links; - symbol_t *symbol; -} symbol_node_t; - -typedef struct critical_section { - TAILQ_ENTRY(critical_section) links; - int begin_addr; - int end_addr; -} critical_section_t; - -typedef enum { - SCOPE_ROOT, - SCOPE_IF, - SCOPE_ELSE_IF, - SCOPE_ELSE -} scope_type; - -typedef struct patch_info { - int skip_patch; - int skip_instr; -} patch_info_t; - -typedef struct scope { - SLIST_ENTRY(scope) scope_stack_links; - TAILQ_ENTRY(scope) scope_links; - TAILQ_HEAD(, scope) inner_scope; - scope_type type; - int inner_scope_patches; - int begin_addr; - int end_addr; - patch_info_t patches[2]; - int func_num; -} scope_t; - -TAILQ_HEAD(cs_tailq, critical_section); -SLIST_HEAD(scope_list, scope); -TAILQ_HEAD(scope_tailq, scope); - -void symbol_delete(symbol_t *symbol); - -void symtable_open(void); - -void symtable_close(void); - -symbol_t * - symtable_get(char *name); - -symbol_node_t * - symlist_search(symlist_t *symlist, char *symname); - -void - symlist_add(symlist_t *symlist, symbol_t *symbol, int how); -#define SYMLIST_INSERT_HEAD 0x00 -#define SYMLIST_SORT 0x01 - -void symlist_free(symlist_t *symlist); - -void symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, - symlist_t *symlist_src2); -void symtable_dump(FILE *ofile, FILE *dfile); diff -urN linux-2.4.21/drivers/scsi/aic79xx/aiclib.c linux-2.4.22/drivers/scsi/aic79xx/aiclib.c --- linux-2.4.21/drivers/scsi/aic79xx/aiclib.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aiclib.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1335 +0,0 @@ -/* - * Implementation of Utility functions for all SCSI device types. - * - * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. - * Copyright (c) 1997, 1998 Kenneth D. Merry. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $ - * $Id$ - */ - -#include -#include -#include -#include - -/* Core SCSI definitions */ -#include "scsi.h" -#include "hosts.h" -#include "aiclib.h" -#include "cam.h" - -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef ERESTART -#define ERESTART -1 /* restart syscall */ -#endif -#ifndef EJUSTRETURN -#define EJUSTRETURN -2 /* don't modify regs, just return */ -#endif - -static int ascentrycomp(const void *key, const void *member); -static int senseentrycomp(const void *key, const void *member); -static void fetchtableentries(int sense_key, int asc, int ascq, - struct scsi_inquiry_data *, - const struct sense_key_table_entry **, - const struct asc_table_entry **); -static void * scsibsearch(const void *key, const void *base, size_t nmemb, - size_t size, - int (*compar)(const void *, const void *)); -typedef int (cam_quirkmatch_t)(caddr_t, caddr_t); -static int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, - int str_len); -static caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, - int num_entries, int entry_size, - cam_quirkmatch_t *comp_func); - -#define SCSI_NO_SENSE_STRINGS 1 -#if !defined(SCSI_NO_SENSE_STRINGS) -#define SST(asc, ascq, action, desc) \ - asc, ascq, action, desc -#else -static const char empty_string[] = ""; - -#define SST(asc, ascq, action, desc) \ - asc, ascq, action, empty_string -#endif - -static const struct sense_key_table_entry sense_key_table[] = -{ - { SSD_KEY_NO_SENSE, SS_NOP, "NO SENSE" }, - { SSD_KEY_RECOVERED_ERROR, SS_NOP|SSQ_PRINT_SENSE, "RECOVERED ERROR" }, - { - SSD_KEY_NOT_READY, SS_TUR|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, - "NOT READY" - }, - { SSD_KEY_MEDIUM_ERROR, SS_RDEF, "MEDIUM ERROR" }, - { SSD_KEY_HARDWARE_ERROR, SS_RDEF, "HARDWARE FAILURE" }, - { SSD_KEY_ILLEGAL_REQUEST, SS_FATAL|EINVAL, "ILLEGAL REQUEST" }, - { SSD_KEY_UNIT_ATTENTION, SS_FATAL|ENXIO, "UNIT ATTENTION" }, - { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" }, - { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" }, - { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" }, - { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" }, - { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" }, - { SSD_KEY_EQUAL, SS_NOP, "EQUAL" }, - { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" }, - { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" }, - { SSD_KEY_RESERVED, SS_FATAL|EIO, "RESERVED" } -}; - -static const int sense_key_table_size = - sizeof(sense_key_table)/sizeof(sense_key_table[0]); - -static struct asc_table_entry quantum_fireball_entries[] = { - {SST(0x04, 0x0b, SS_START|SSQ_DECREMENT_COUNT|ENXIO, - "Logical unit not ready, initializing cmd. required")} -}; - -static struct asc_table_entry sony_mo_entries[] = { - {SST(0x04, 0x00, SS_START|SSQ_DECREMENT_COUNT|ENXIO, - "Logical unit not ready, cause not reportable")} -}; - -static struct scsi_sense_quirk_entry sense_quirk_table[] = { - { - /* - * The Quantum Fireball ST and SE like to return 0x04 0x0b when - * they really should return 0x04 0x02. 0x04,0x0b isn't - * defined in any SCSI spec, and it isn't mentioned in the - * hardware manual for these drives. - */ - {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"}, - /*num_sense_keys*/0, - sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry), - /*sense key entries*/NULL, - quantum_fireball_entries - }, - { - /* - * This Sony MO drive likes to return 0x04, 0x00 when it - * isn't spun up. - */ - {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"}, - /*num_sense_keys*/0, - sizeof(sony_mo_entries)/sizeof(struct asc_table_entry), - /*sense key entries*/NULL, - sony_mo_entries - } -}; - -static const int sense_quirk_table_size = - sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]); - -static struct asc_table_entry asc_table[] = { -/* - * From File: ASC-NUM.TXT - * SCSI ASC/ASCQ Assignments - * Numeric Sorted Listing - * as of 5/12/97 - * - * D - DIRECT ACCESS DEVICE (SBC) device column key - * .T - SEQUENTIAL ACCESS DEVICE (SSC) ------------------- - * . L - PRINTER DEVICE (SSC) blank = reserved - * . P - PROCESSOR DEVICE (SPC) not blank = allowed - * . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC) - * . . R - CD DEVICE (MMC) - * . . S - SCANNER DEVICE (SGC) - * . . .O - OPTICAL MEMORY DEVICE (SBC) - * . . . M - MEDIA CHANGER DEVICE (SMC) - * . . . C - COMMUNICATION DEVICE (SSC) - * . . . .A - STORAGE ARRAY DEVICE (SCC) - * . . . . E - ENCLOSURE SERVICES DEVICE (SES) - * DTLPWRSOMCAE ASC ASCQ Action Description - * ------------ ---- ---- ------ -----------------------------------*/ -/* DTLPWRSOMCAE */{SST(0x00, 0x00, SS_NOP, - "No additional sense information") }, -/* T S */{SST(0x00, 0x01, SS_RDEF, - "Filemark detected") }, -/* T S */{SST(0x00, 0x02, SS_RDEF, - "End-of-partition/medium detected") }, -/* T */{SST(0x00, 0x03, SS_RDEF, - "Setmark detected") }, -/* T S */{SST(0x00, 0x04, SS_RDEF, - "Beginning-of-partition/medium detected") }, -/* T S */{SST(0x00, 0x05, SS_RDEF, - "End-of-data detected") }, -/* DTLPWRSOMCAE */{SST(0x00, 0x06, SS_RDEF, - "I/O process terminated") }, -/* R */{SST(0x00, 0x11, SS_FATAL|EBUSY, - "Audio play operation in progress") }, -/* R */{SST(0x00, 0x12, SS_NOP, - "Audio play operation paused") }, -/* R */{SST(0x00, 0x13, SS_NOP, - "Audio play operation successfully completed") }, -/* R */{SST(0x00, 0x14, SS_RDEF, - "Audio play operation stopped due to error") }, -/* R */{SST(0x00, 0x15, SS_NOP, - "No current audio status to return") }, -/* DTLPWRSOMCAE */{SST(0x00, 0x16, SS_FATAL|EBUSY, - "Operation in progress") }, -/* DTL WRSOM AE */{SST(0x00, 0x17, SS_RDEF, - "Cleaning requested") }, -/* D W O */{SST(0x01, 0x00, SS_RDEF, - "No index/sector signal") }, -/* D WR OM */{SST(0x02, 0x00, SS_RDEF, - "No seek complete") }, -/* DTL W SO */{SST(0x03, 0x00, SS_RDEF, - "Peripheral device write fault") }, -/* T */{SST(0x03, 0x01, SS_RDEF, - "No write current") }, -/* T */{SST(0x03, 0x02, SS_RDEF, - "Excessive write errors") }, -/* DTLPWRSOMCAE */{SST(0x04, 0x00, - SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EIO, - "Logical unit not ready, cause not reportable") }, -/* DTLPWRSOMCAE */{SST(0x04, 0x01, - SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, - "Logical unit is in process of becoming ready") }, -/* DTLPWRSOMCAE */{SST(0x04, 0x02, SS_START|SSQ_DECREMENT_COUNT|ENXIO, - "Logical unit not ready, initializing cmd. required") }, -/* DTLPWRSOMCAE */{SST(0x04, 0x03, SS_FATAL|ENXIO, - "Logical unit not ready, manual intervention required")}, -/* DTL O */{SST(0x04, 0x04, SS_FATAL|EBUSY, - "Logical unit not ready, format in progress") }, -/* DT W OMCA */{SST(0x04, 0x05, SS_FATAL|EBUSY, - "Logical unit not ready, rebuild in progress") }, -/* DT W OMCA */{SST(0x04, 0x06, SS_FATAL|EBUSY, - "Logical unit not ready, recalculation in progress") }, -/* DTLPWRSOMCAE */{SST(0x04, 0x07, SS_FATAL|EBUSY, - "Logical unit not ready, operation in progress") }, -/* R */{SST(0x04, 0x08, SS_FATAL|EBUSY, - "Logical unit not ready, long write in progress") }, -/* DTL WRSOMCAE */{SST(0x05, 0x00, SS_RDEF, - "Logical unit does not respond to selection") }, -/* D WR OM */{SST(0x06, 0x00, SS_RDEF, - "No reference position found") }, -/* DTL WRSOM */{SST(0x07, 0x00, SS_RDEF, - "Multiple peripheral devices selected") }, -/* DTL WRSOMCAE */{SST(0x08, 0x00, SS_RDEF, - "Logical unit communication failure") }, -/* DTL WRSOMCAE */{SST(0x08, 0x01, SS_RDEF, - "Logical unit communication time-out") }, -/* DTL WRSOMCAE */{SST(0x08, 0x02, SS_RDEF, - "Logical unit communication parity error") }, -/* DT R OM */{SST(0x08, 0x03, SS_RDEF, - "Logical unit communication crc error (ultra-dma/32)")}, -/* DT WR O */{SST(0x09, 0x00, SS_RDEF, - "Track following error") }, -/* WR O */{SST(0x09, 0x01, SS_RDEF, - "Tracking servo failure") }, -/* WR O */{SST(0x09, 0x02, SS_RDEF, - "Focus servo failure") }, -/* WR O */{SST(0x09, 0x03, SS_RDEF, - "Spindle servo failure") }, -/* DT WR O */{SST(0x09, 0x04, SS_RDEF, - "Head select fault") }, -/* DTLPWRSOMCAE */{SST(0x0A, 0x00, SS_FATAL|ENOSPC, - "Error log overflow") }, -/* DTLPWRSOMCAE */{SST(0x0B, 0x00, SS_RDEF, - "Warning") }, -/* DTLPWRSOMCAE */{SST(0x0B, 0x01, SS_RDEF, - "Specified temperature exceeded") }, -/* DTLPWRSOMCAE */{SST(0x0B, 0x02, SS_RDEF, - "Enclosure degraded") }, -/* T RS */{SST(0x0C, 0x00, SS_RDEF, - "Write error") }, -/* D W O */{SST(0x0C, 0x01, SS_NOP|SSQ_PRINT_SENSE, - "Write error - recovered with auto reallocation") }, -/* D W O */{SST(0x0C, 0x02, SS_RDEF, - "Write error - auto reallocation failed") }, -/* D W O */{SST(0x0C, 0x03, SS_RDEF, - "Write error - recommend reassignment") }, -/* DT W O */{SST(0x0C, 0x04, SS_RDEF, - "Compression check miscompare error") }, -/* DT W O */{SST(0x0C, 0x05, SS_RDEF, - "Data expansion occurred during compression") }, -/* DT W O */{SST(0x0C, 0x06, SS_RDEF, - "Block not compressible") }, -/* R */{SST(0x0C, 0x07, SS_RDEF, - "Write error - recovery needed") }, -/* R */{SST(0x0C, 0x08, SS_RDEF, - "Write error - recovery failed") }, -/* R */{SST(0x0C, 0x09, SS_RDEF, - "Write error - loss of streaming") }, -/* R */{SST(0x0C, 0x0A, SS_RDEF, - "Write error - padding blocks added") }, -/* D W O */{SST(0x10, 0x00, SS_RDEF, - "ID CRC or ECC error") }, -/* DT WRSO */{SST(0x11, 0x00, SS_RDEF, - "Unrecovered read error") }, -/* DT W SO */{SST(0x11, 0x01, SS_RDEF, - "Read retries exhausted") }, -/* DT W SO */{SST(0x11, 0x02, SS_RDEF, - "Error too long to correct") }, -/* DT W SO */{SST(0x11, 0x03, SS_RDEF, - "Multiple read errors") }, -/* D W O */{SST(0x11, 0x04, SS_RDEF, - "Unrecovered read error - auto reallocate failed") }, -/* WR O */{SST(0x11, 0x05, SS_RDEF, - "L-EC uncorrectable error") }, -/* WR O */{SST(0x11, 0x06, SS_RDEF, - "CIRC unrecovered error") }, -/* W O */{SST(0x11, 0x07, SS_RDEF, - "Data re-synchronization error") }, -/* T */{SST(0x11, 0x08, SS_RDEF, - "Incomplete block read") }, -/* T */{SST(0x11, 0x09, SS_RDEF, - "No gap found") }, -/* DT O */{SST(0x11, 0x0A, SS_RDEF, - "Miscorrected error") }, -/* D W O */{SST(0x11, 0x0B, SS_RDEF, - "Unrecovered read error - recommend reassignment") }, -/* D W O */{SST(0x11, 0x0C, SS_RDEF, - "Unrecovered read error - recommend rewrite the data")}, -/* DT WR O */{SST(0x11, 0x0D, SS_RDEF, - "De-compression CRC error") }, -/* DT WR O */{SST(0x11, 0x0E, SS_RDEF, - "Cannot decompress using declared algorithm") }, -/* R */{SST(0x11, 0x0F, SS_RDEF, - "Error reading UPC/EAN number") }, -/* R */{SST(0x11, 0x10, SS_RDEF, - "Error reading ISRC number") }, -/* R */{SST(0x11, 0x11, SS_RDEF, - "Read error - loss of streaming") }, -/* D W O */{SST(0x12, 0x00, SS_RDEF, - "Address mark not found for id field") }, -/* D W O */{SST(0x13, 0x00, SS_RDEF, - "Address mark not found for data field") }, -/* DTL WRSO */{SST(0x14, 0x00, SS_RDEF, - "Recorded entity not found") }, -/* DT WR O */{SST(0x14, 0x01, SS_RDEF, - "Record not found") }, -/* T */{SST(0x14, 0x02, SS_RDEF, - "Filemark or setmark not found") }, -/* T */{SST(0x14, 0x03, SS_RDEF, - "End-of-data not found") }, -/* T */{SST(0x14, 0x04, SS_RDEF, - "Block sequence error") }, -/* DT W O */{SST(0x14, 0x05, SS_RDEF, - "Record not found - recommend reassignment") }, -/* DT W O */{SST(0x14, 0x06, SS_RDEF, - "Record not found - data auto-reallocated") }, -/* DTL WRSOM */{SST(0x15, 0x00, SS_RDEF, - "Random positioning error") }, -/* DTL WRSOM */{SST(0x15, 0x01, SS_RDEF, - "Mechanical positioning error") }, -/* DT WR O */{SST(0x15, 0x02, SS_RDEF, - "Positioning error detected by read of medium") }, -/* D W O */{SST(0x16, 0x00, SS_RDEF, - "Data synchronization mark error") }, -/* D W O */{SST(0x16, 0x01, SS_RDEF, - "Data sync error - data rewritten") }, -/* D W O */{SST(0x16, 0x02, SS_RDEF, - "Data sync error - recommend rewrite") }, -/* D W O */{SST(0x16, 0x03, SS_NOP|SSQ_PRINT_SENSE, - "Data sync error - data auto-reallocated") }, -/* D W O */{SST(0x16, 0x04, SS_RDEF, - "Data sync error - recommend reassignment") }, -/* DT WRSO */{SST(0x17, 0x00, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with no error correction applied") }, -/* DT WRSO */{SST(0x17, 0x01, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with retries") }, -/* DT WR O */{SST(0x17, 0x02, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with positive head offset") }, -/* DT WR O */{SST(0x17, 0x03, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with negative head offset") }, -/* WR O */{SST(0x17, 0x04, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with retries and/or CIRC applied") }, -/* D WR O */{SST(0x17, 0x05, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data using previous sector id") }, -/* D W O */{SST(0x17, 0x06, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data without ECC - data auto-reallocated") }, -/* D W O */{SST(0x17, 0x07, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data without ECC - recommend reassignment")}, -/* D W O */{SST(0x17, 0x08, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data without ECC - recommend rewrite") }, -/* D W O */{SST(0x17, 0x09, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data without ECC - data rewritten") }, -/* D W O */{SST(0x18, 0x00, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with error correction applied") }, -/* D WR O */{SST(0x18, 0x01, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with error corr. & retries applied") }, -/* D WR O */{SST(0x18, 0x02, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data - data auto-reallocated") }, -/* R */{SST(0x18, 0x03, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with CIRC") }, -/* R */{SST(0x18, 0x04, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with L-EC") }, -/* D WR O */{SST(0x18, 0x05, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data - recommend reassignment") }, -/* D WR O */{SST(0x18, 0x06, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data - recommend rewrite") }, -/* D W O */{SST(0x18, 0x07, SS_NOP|SSQ_PRINT_SENSE, - "Recovered data with ECC - data rewritten") }, -/* D O */{SST(0x19, 0x00, SS_RDEF, - "Defect list error") }, -/* D O */{SST(0x19, 0x01, SS_RDEF, - "Defect list not available") }, -/* D O */{SST(0x19, 0x02, SS_RDEF, - "Defect list error in primary list") }, -/* D O */{SST(0x19, 0x03, SS_RDEF, - "Defect list error in grown list") }, -/* DTLPWRSOMCAE */{SST(0x1A, 0x00, SS_RDEF, - "Parameter list length error") }, -/* DTLPWRSOMCAE */{SST(0x1B, 0x00, SS_RDEF, - "Synchronous data transfer error") }, -/* D O */{SST(0x1C, 0x00, SS_RDEF, - "Defect list not found") }, -/* D O */{SST(0x1C, 0x01, SS_RDEF, - "Primary defect list not found") }, -/* D O */{SST(0x1C, 0x02, SS_RDEF, - "Grown defect list not found") }, -/* D W O */{SST(0x1D, 0x00, SS_FATAL, - "Miscompare during verify operation" )}, -/* D W O */{SST(0x1E, 0x00, SS_NOP|SSQ_PRINT_SENSE, - "Recovered id with ecc correction") }, -/* D O */{SST(0x1F, 0x00, SS_RDEF, - "Partial defect list transfer") }, -/* DTLPWRSOMCAE */{SST(0x20, 0x00, SS_FATAL|EINVAL, - "Invalid command operation code") }, -/* DT WR OM */{SST(0x21, 0x00, SS_FATAL|EINVAL, - "Logical block address out of range" )}, -/* DT WR OM */{SST(0x21, 0x01, SS_FATAL|EINVAL, - "Invalid element address") }, -/* D */{SST(0x22, 0x00, SS_FATAL|EINVAL, - "Illegal function") }, /* Deprecated. Use 20 00, 24 00, or 26 00 instead */ -/* DTLPWRSOMCAE */{SST(0x24, 0x00, SS_FATAL|EINVAL, - "Invalid field in CDB") }, -/* DTLPWRSOMCAE */{SST(0x25, 0x00, SS_FATAL|ENXIO, - "Logical unit not supported") }, -/* DTLPWRSOMCAE */{SST(0x26, 0x00, SS_FATAL|EINVAL, - "Invalid field in parameter list") }, -/* DTLPWRSOMCAE */{SST(0x26, 0x01, SS_FATAL|EINVAL, - "Parameter not supported") }, -/* DTLPWRSOMCAE */{SST(0x26, 0x02, SS_FATAL|EINVAL, - "Parameter value invalid") }, -/* DTLPWRSOMCAE */{SST(0x26, 0x03, SS_FATAL|EINVAL, - "Threshold parameters not supported") }, -/* DTLPWRSOMCAE */{SST(0x26, 0x04, SS_FATAL|EINVAL, - "Invalid release of active persistent reservation") }, -/* DT W O */{SST(0x27, 0x00, SS_FATAL|EACCES, - "Write protected") }, -/* DT W O */{SST(0x27, 0x01, SS_FATAL|EACCES, - "Hardware write protected") }, -/* DT W O */{SST(0x27, 0x02, SS_FATAL|EACCES, - "Logical unit software write protected") }, -/* T */{SST(0x27, 0x03, SS_FATAL|EACCES, - "Associated write protect") }, -/* T */{SST(0x27, 0x04, SS_FATAL|EACCES, - "Persistent write protect") }, -/* T */{SST(0x27, 0x05, SS_FATAL|EACCES, - "Permanent write protect") }, -/* DTLPWRSOMCAE */{SST(0x28, 0x00, SS_RDEF, - "Not ready to ready change, medium may have changed") }, -/* DTLPWRSOMCAE */{SST(0x28, 0x01, SS_FATAL|ENXIO, - "Import or export element accessed") }, -/* - * XXX JGibbs - All of these should use the same errno, but I don't think - * ENXIO is the correct choice. Should we borrow from the networking - * errnos? ECONNRESET anyone? - */ -/* DTLPWRSOMCAE */{SST(0x29, 0x00, SS_RDEF, - "Power on, reset, or bus device reset occurred") }, -/* DTLPWRSOMCAE */{SST(0x29, 0x01, SS_RDEF, - "Power on occurred") }, -/* DTLPWRSOMCAE */{SST(0x29, 0x02, SS_RDEF, - "Scsi bus reset occurred") }, -/* DTLPWRSOMCAE */{SST(0x29, 0x03, SS_RDEF, - "Bus device reset function occurred") }, -/* DTLPWRSOMCAE */{SST(0x29, 0x04, SS_RDEF, - "Device internal reset") }, -/* DTLPWRSOMCAE */{SST(0x29, 0x05, SS_RDEF, - "Transceiver mode changed to single-ended") }, -/* DTLPWRSOMCAE */{SST(0x29, 0x06, SS_RDEF, - "Transceiver mode changed to LVD") }, -/* DTL WRSOMCAE */{SST(0x2A, 0x00, SS_RDEF, - "Parameters changed") }, -/* DTL WRSOMCAE */{SST(0x2A, 0x01, SS_RDEF, - "Mode parameters changed") }, -/* DTL WRSOMCAE */{SST(0x2A, 0x02, SS_RDEF, - "Log parameters changed") }, -/* DTLPWRSOMCAE */{SST(0x2A, 0x03, SS_RDEF, - "Reservations preempted") }, -/* DTLPWRSO C */{SST(0x2B, 0x00, SS_RDEF, - "Copy cannot execute since host cannot disconnect") }, -/* DTLPWRSOMCAE */{SST(0x2C, 0x00, SS_RDEF, - "Command sequence error") }, -/* S */{SST(0x2C, 0x01, SS_RDEF, - "Too many windows specified") }, -/* S */{SST(0x2C, 0x02, SS_RDEF, - "Invalid combination of windows specified") }, -/* R */{SST(0x2C, 0x03, SS_RDEF, - "Current program area is not empty") }, -/* R */{SST(0x2C, 0x04, SS_RDEF, - "Current program area is empty") }, -/* T */{SST(0x2D, 0x00, SS_RDEF, - "Overwrite error on update in place") }, -/* DTLPWRSOMCAE */{SST(0x2F, 0x00, SS_RDEF, - "Commands cleared by another initiator") }, -/* DT WR OM */{SST(0x30, 0x00, SS_RDEF, - "Incompatible medium installed") }, -/* DT WR O */{SST(0x30, 0x01, SS_RDEF, - "Cannot read medium - unknown format") }, -/* DT WR O */{SST(0x30, 0x02, SS_RDEF, - "Cannot read medium - incompatible format") }, -/* DT */{SST(0x30, 0x03, SS_RDEF, - "Cleaning cartridge installed") }, -/* DT WR O */{SST(0x30, 0x04, SS_RDEF, - "Cannot write medium - unknown format") }, -/* DT WR O */{SST(0x30, 0x05, SS_RDEF, - "Cannot write medium - incompatible format") }, -/* DT W O */{SST(0x30, 0x06, SS_RDEF, - "Cannot format medium - incompatible medium") }, -/* DTL WRSOM AE */{SST(0x30, 0x07, SS_RDEF, - "Cleaning failure") }, -/* R */{SST(0x30, 0x08, SS_RDEF, - "Cannot write - application code mismatch") }, -/* R */{SST(0x30, 0x09, SS_RDEF, - "Current session not fixated for append") }, -/* DT WR O */{SST(0x31, 0x00, SS_RDEF, - "Medium format corrupted") }, -/* D L R O */{SST(0x31, 0x01, SS_RDEF, - "Format command failed") }, -/* D W O */{SST(0x32, 0x00, SS_RDEF, - "No defect spare location available") }, -/* D W O */{SST(0x32, 0x01, SS_RDEF, - "Defect list update failure") }, -/* T */{SST(0x33, 0x00, SS_RDEF, - "Tape length error") }, -/* DTLPWRSOMCAE */{SST(0x34, 0x00, SS_RDEF, - "Enclosure failure") }, -/* DTLPWRSOMCAE */{SST(0x35, 0x00, SS_RDEF, - "Enclosure services failure") }, -/* DTLPWRSOMCAE */{SST(0x35, 0x01, SS_RDEF, - "Unsupported enclosure function") }, -/* DTLPWRSOMCAE */{SST(0x35, 0x02, SS_RDEF, - "Enclosure services unavailable") }, -/* DTLPWRSOMCAE */{SST(0x35, 0x03, SS_RDEF, - "Enclosure services transfer failure") }, -/* DTLPWRSOMCAE */{SST(0x35, 0x04, SS_RDEF, - "Enclosure services transfer refused") }, -/* L */{SST(0x36, 0x00, SS_RDEF, - "Ribbon, ink, or toner failure") }, -/* DTL WRSOMCAE */{SST(0x37, 0x00, SS_RDEF, - "Rounded parameter") }, -/* DTL WRSOMCAE */{SST(0x39, 0x00, SS_RDEF, - "Saving parameters not supported") }, -/* DTL WRSOM */{SST(0x3A, 0x00, SS_NOP, - "Medium not present") }, -/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, - "Medium not present - tray closed") }, -/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, - "Medium not present - tray open") }, -/* DT WR OM */{SST(0x3A, 0x03, SS_NOP, - "Medium not present - Loadable") }, -/* DT WR OM */{SST(0x3A, 0x04, SS_NOP, - "Medium not present - medium auxiliary " - "memory accessible") }, -/* DT WR OM */{SST(0x3A, 0xFF, SS_NOP, NULL) },/* Range 0x05->0xFF */ -/* TL */{SST(0x3B, 0x00, SS_RDEF, - "Sequential positioning error") }, -/* T */{SST(0x3B, 0x01, SS_RDEF, - "Tape position error at beginning-of-medium") }, -/* T */{SST(0x3B, 0x02, SS_RDEF, - "Tape position error at end-of-medium") }, -/* L */{SST(0x3B, 0x03, SS_RDEF, - "Tape or electronic vertical forms unit not ready") }, -/* L */{SST(0x3B, 0x04, SS_RDEF, - "Slew failure") }, -/* L */{SST(0x3B, 0x05, SS_RDEF, - "Paper jam") }, -/* L */{SST(0x3B, 0x06, SS_RDEF, - "Failed to sense top-of-form") }, -/* L */{SST(0x3B, 0x07, SS_RDEF, - "Failed to sense bottom-of-form") }, -/* T */{SST(0x3B, 0x08, SS_RDEF, - "Reposition error") }, -/* S */{SST(0x3B, 0x09, SS_RDEF, - "Read past end of medium") }, -/* S */{SST(0x3B, 0x0A, SS_RDEF, - "Read past beginning of medium") }, -/* S */{SST(0x3B, 0x0B, SS_RDEF, - "Position past end of medium") }, -/* T S */{SST(0x3B, 0x0C, SS_RDEF, - "Position past beginning of medium") }, -/* DT WR OM */{SST(0x3B, 0x0D, SS_FATAL|ENOSPC, - "Medium destination element full") }, -/* DT WR OM */{SST(0x3B, 0x0E, SS_RDEF, - "Medium source element empty") }, -/* R */{SST(0x3B, 0x0F, SS_RDEF, - "End of medium reached") }, -/* DT WR OM */{SST(0x3B, 0x11, SS_RDEF, - "Medium magazine not accessible") }, -/* DT WR OM */{SST(0x3B, 0x12, SS_RDEF, - "Medium magazine removed") }, -/* DT WR OM */{SST(0x3B, 0x13, SS_RDEF, - "Medium magazine inserted") }, -/* DT WR OM */{SST(0x3B, 0x14, SS_RDEF, - "Medium magazine locked") }, -/* DT WR OM */{SST(0x3B, 0x15, SS_RDEF, - "Medium magazine unlocked") }, -/* DTLPWRSOMCAE */{SST(0x3D, 0x00, SS_RDEF, - "Invalid bits in identify message") }, -/* DTLPWRSOMCAE */{SST(0x3E, 0x00, SS_RDEF, - "Logical unit has not self-configured yet") }, -/* DTLPWRSOMCAE */{SST(0x3E, 0x01, SS_RDEF, - "Logical unit failure") }, -/* DTLPWRSOMCAE */{SST(0x3E, 0x02, SS_RDEF, - "Timeout on logical unit") }, -/* DTLPWRSOMCAE */{SST(0x3F, 0x00, SS_RDEF, - "Target operating conditions have changed") }, -/* DTLPWRSOMCAE */{SST(0x3F, 0x01, SS_RDEF, - "Microcode has been changed") }, -/* DTLPWRSOMC */{SST(0x3F, 0x02, SS_RDEF, - "Changed operating definition") }, -/* DTLPWRSOMCAE */{SST(0x3F, 0x03, SS_INQ_REFRESH|SSQ_DECREMENT_COUNT, - "Inquiry data has changed") }, -/* DT WR OMCAE */{SST(0x3F, 0x04, SS_RDEF, - "Component device attached") }, -/* DT WR OMCAE */{SST(0x3F, 0x05, SS_RDEF, - "Device identifier changed") }, -/* DT WR OMCAE */{SST(0x3F, 0x06, SS_RDEF, - "Redundancy group created or modified") }, -/* DT WR OMCAE */{SST(0x3F, 0x07, SS_RDEF, - "Redundancy group deleted") }, -/* DT WR OMCAE */{SST(0x3F, 0x08, SS_RDEF, - "Spare created or modified") }, -/* DT WR OMCAE */{SST(0x3F, 0x09, SS_RDEF, - "Spare deleted") }, -/* DT WR OMCAE */{SST(0x3F, 0x0A, SS_RDEF, - "Volume set created or modified") }, -/* DT WR OMCAE */{SST(0x3F, 0x0B, SS_RDEF, - "Volume set deleted") }, -/* DT WR OMCAE */{SST(0x3F, 0x0C, SS_RDEF, - "Volume set deassigned") }, -/* DT WR OMCAE */{SST(0x3F, 0x0D, SS_RDEF, - "Volume set reassigned") }, -/* DTLPWRSOMCAE */{SST(0x3F, 0x0E, SS_RDEF, - "Reported luns data has changed") }, -/* DTLPWRSOMCAE */{SST(0x3F, 0x0F, SS_RETRY|SSQ_DECREMENT_COUNT - | SSQ_DELAY_RANDOM|EBUSY, - "Echo buffer overwritten") }, -/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, "Medium Loadable") }, -/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, - "Medium auxiliary memory accessible") }, -/* D */{SST(0x40, 0x00, SS_RDEF, - "Ram failure") }, /* deprecated - use 40 NN instead */ -/* DTLPWRSOMCAE */{SST(0x40, 0x80, SS_RDEF, - "Diagnostic failure: ASCQ = Component ID") }, -/* DTLPWRSOMCAE */{SST(0x40, 0xFF, SS_RDEF|SSQ_RANGE, - NULL) },/* Range 0x80->0xFF */ -/* D */{SST(0x41, 0x00, SS_RDEF, - "Data path failure") }, /* deprecated - use 40 NN instead */ -/* D */{SST(0x42, 0x00, SS_RDEF, - "Power-on or self-test failure") }, /* deprecated - use 40 NN instead */ -/* DTLPWRSOMCAE */{SST(0x43, 0x00, SS_RDEF, - "Message error") }, -/* DTLPWRSOMCAE */{SST(0x44, 0x00, SS_RDEF, - "Internal target failure") }, -/* DTLPWRSOMCAE */{SST(0x45, 0x00, SS_RDEF, - "Select or reselect failure") }, -/* DTLPWRSOMC */{SST(0x46, 0x00, SS_RDEF, - "Unsuccessful soft reset") }, -/* DTLPWRSOMCAE */{SST(0x47, 0x00, SS_RDEF|SSQ_FALLBACK, - "SCSI parity error") }, -/* DTLPWRSOMCAE */{SST(0x47, 0x01, SS_RDEF|SSQ_FALLBACK, - "Data Phase CRC error detected") }, -/* DTLPWRSOMCAE */{SST(0x47, 0x02, SS_RDEF|SSQ_FALLBACK, - "SCSI parity error detected during ST data phase") }, -/* DTLPWRSOMCAE */{SST(0x47, 0x03, SS_RDEF|SSQ_FALLBACK, - "Information Unit iuCRC error") }, -/* DTLPWRSOMCAE */{SST(0x47, 0x04, SS_RDEF|SSQ_FALLBACK, - "Asynchronous information protection error detected") }, -/* DTLPWRSOMCAE */{SST(0x47, 0x05, SS_RDEF|SSQ_FALLBACK, - "Protocol server CRC error") }, -/* DTLPWRSOMCAE */{SST(0x48, 0x00, SS_RDEF|SSQ_FALLBACK, - "Initiator detected error message received") }, -/* DTLPWRSOMCAE */{SST(0x49, 0x00, SS_RDEF, - "Invalid message error") }, -/* DTLPWRSOMCAE */{SST(0x4A, 0x00, SS_RDEF, - "Command phase error") }, -/* DTLPWRSOMCAE */{SST(0x4B, 0x00, SS_RDEF, - "Data phase error") }, -/* DTLPWRSOMCAE */{SST(0x4C, 0x00, SS_RDEF, - "Logical unit failed self-configuration") }, -/* DTLPWRSOMCAE */{SST(0x4D, 0x00, SS_RDEF, - "Tagged overlapped commands: ASCQ = Queue tag ID") }, -/* DTLPWRSOMCAE */{SST(0x4D, 0xFF, SS_RDEF|SSQ_RANGE, - NULL)}, /* Range 0x00->0xFF */ -/* DTLPWRSOMCAE */{SST(0x4E, 0x00, SS_RDEF, - "Overlapped commands attempted") }, -/* T */{SST(0x50, 0x00, SS_RDEF, - "Write append error") }, -/* T */{SST(0x50, 0x01, SS_RDEF, - "Write append position error") }, -/* T */{SST(0x50, 0x02, SS_RDEF, - "Position error related to timing") }, -/* T O */{SST(0x51, 0x00, SS_RDEF, - "Erase failure") }, -/* T */{SST(0x52, 0x00, SS_RDEF, - "Cartridge fault") }, -/* DTL WRSOM */{SST(0x53, 0x00, SS_RDEF, - "Media load or eject failed") }, -/* T */{SST(0x53, 0x01, SS_RDEF, - "Unload tape failure") }, -/* DT WR OM */{SST(0x53, 0x02, SS_RDEF, - "Medium removal prevented") }, -/* P */{SST(0x54, 0x00, SS_RDEF, - "Scsi to host system interface failure") }, -/* P */{SST(0x55, 0x00, SS_RDEF, - "System resource failure") }, -/* D O */{SST(0x55, 0x01, SS_FATAL|ENOSPC, - "System buffer full") }, -/* R */{SST(0x57, 0x00, SS_RDEF, - "Unable to recover table-of-contents") }, -/* O */{SST(0x58, 0x00, SS_RDEF, - "Generation does not exist") }, -/* O */{SST(0x59, 0x00, SS_RDEF, - "Updated block read") }, -/* DTLPWRSOM */{SST(0x5A, 0x00, SS_RDEF, - "Operator request or state change input") }, -/* DT WR OM */{SST(0x5A, 0x01, SS_RDEF, - "Operator medium removal request") }, -/* DT W O */{SST(0x5A, 0x02, SS_RDEF, - "Operator selected write protect") }, -/* DT W O */{SST(0x5A, 0x03, SS_RDEF, - "Operator selected write permit") }, -/* DTLPWRSOM */{SST(0x5B, 0x00, SS_RDEF, - "Log exception") }, -/* DTLPWRSOM */{SST(0x5B, 0x01, SS_RDEF, - "Threshold condition met") }, -/* DTLPWRSOM */{SST(0x5B, 0x02, SS_RDEF, - "Log counter at maximum") }, -/* DTLPWRSOM */{SST(0x5B, 0x03, SS_RDEF, - "Log list codes exhausted") }, -/* D O */{SST(0x5C, 0x00, SS_RDEF, - "RPL status change") }, -/* D O */{SST(0x5C, 0x01, SS_NOP|SSQ_PRINT_SENSE, - "Spindles synchronized") }, -/* D O */{SST(0x5C, 0x02, SS_RDEF, - "Spindles not synchronized") }, -/* DTLPWRSOMCAE */{SST(0x5D, 0x00, SS_RDEF, - "Failure prediction threshold exceeded") }, -/* DTLPWRSOMCAE */{SST(0x5D, 0xFF, SS_RDEF, - "Failure prediction threshold exceeded (false)") }, -/* DTLPWRSO CA */{SST(0x5E, 0x00, SS_RDEF, - "Low power condition on") }, -/* DTLPWRSO CA */{SST(0x5E, 0x01, SS_RDEF, - "Idle condition activated by timer") }, -/* DTLPWRSO CA */{SST(0x5E, 0x02, SS_RDEF, - "Standby condition activated by timer") }, -/* DTLPWRSO CA */{SST(0x5E, 0x03, SS_RDEF, - "Idle condition activated by command") }, -/* DTLPWRSO CA */{SST(0x5E, 0x04, SS_RDEF, - "Standby condition activated by command") }, -/* S */{SST(0x60, 0x00, SS_RDEF, - "Lamp failure") }, -/* S */{SST(0x61, 0x00, SS_RDEF, - "Video acquisition error") }, -/* S */{SST(0x61, 0x01, SS_RDEF, - "Unable to acquire video") }, -/* S */{SST(0x61, 0x02, SS_RDEF, - "Out of focus") }, -/* S */{SST(0x62, 0x00, SS_RDEF, - "Scan head positioning error") }, -/* R */{SST(0x63, 0x00, SS_RDEF, - "End of user area encountered on this track") }, -/* R */{SST(0x63, 0x01, SS_FATAL|ENOSPC, - "Packet does not fit in available space") }, -/* R */{SST(0x64, 0x00, SS_RDEF, - "Illegal mode for this track") }, -/* R */{SST(0x64, 0x01, SS_RDEF, - "Invalid packet size") }, -/* DTLPWRSOMCAE */{SST(0x65, 0x00, SS_RDEF, - "Voltage fault") }, -/* S */{SST(0x66, 0x00, SS_RDEF, - "Automatic document feeder cover up") }, -/* S */{SST(0x66, 0x01, SS_RDEF, - "Automatic document feeder lift up") }, -/* S */{SST(0x66, 0x02, SS_RDEF, - "Document jam in automatic document feeder") }, -/* S */{SST(0x66, 0x03, SS_RDEF, - "Document miss feed automatic in document feeder") }, -/* A */{SST(0x67, 0x00, SS_RDEF, - "Configuration failure") }, -/* A */{SST(0x67, 0x01, SS_RDEF, - "Configuration of incapable logical units failed") }, -/* A */{SST(0x67, 0x02, SS_RDEF, - "Add logical unit failed") }, -/* A */{SST(0x67, 0x03, SS_RDEF, - "Modification of logical unit failed") }, -/* A */{SST(0x67, 0x04, SS_RDEF, - "Exchange of logical unit failed") }, -/* A */{SST(0x67, 0x05, SS_RDEF, - "Remove of logical unit failed") }, -/* A */{SST(0x67, 0x06, SS_RDEF, - "Attachment of logical unit failed") }, -/* A */{SST(0x67, 0x07, SS_RDEF, - "Creation of logical unit failed") }, -/* A */{SST(0x68, 0x00, SS_RDEF, - "Logical unit not configured") }, -/* A */{SST(0x69, 0x00, SS_RDEF, - "Data loss on logical unit") }, -/* A */{SST(0x69, 0x01, SS_RDEF, - "Multiple logical unit failures") }, -/* A */{SST(0x69, 0x02, SS_RDEF, - "Parity/data mismatch") }, -/* A */{SST(0x6A, 0x00, SS_RDEF, - "Informational, refer to log") }, -/* A */{SST(0x6B, 0x00, SS_RDEF, - "State change has occurred") }, -/* A */{SST(0x6B, 0x01, SS_RDEF, - "Redundancy level got better") }, -/* A */{SST(0x6B, 0x02, SS_RDEF, - "Redundancy level got worse") }, -/* A */{SST(0x6C, 0x00, SS_RDEF, - "Rebuild failure occurred") }, -/* A */{SST(0x6D, 0x00, SS_RDEF, - "Recalculate failure occurred") }, -/* A */{SST(0x6E, 0x00, SS_RDEF, - "Command to logical unit failed") }, -/* T */{SST(0x70, 0x00, SS_RDEF, - "Decompression exception short: ASCQ = Algorithm ID") }, -/* T */{SST(0x70, 0xFF, SS_RDEF|SSQ_RANGE, - NULL) }, /* Range 0x00 -> 0xFF */ -/* T */{SST(0x71, 0x00, SS_RDEF, - "Decompression exception long: ASCQ = Algorithm ID") }, -/* T */{SST(0x71, 0xFF, SS_RDEF|SSQ_RANGE, - NULL) }, /* Range 0x00 -> 0xFF */ -/* R */{SST(0x72, 0x00, SS_RDEF, - "Session fixation error") }, -/* R */{SST(0x72, 0x01, SS_RDEF, - "Session fixation error writing lead-in") }, -/* R */{SST(0x72, 0x02, SS_RDEF, - "Session fixation error writing lead-out") }, -/* R */{SST(0x72, 0x03, SS_RDEF, - "Session fixation error - incomplete track in session") }, -/* R */{SST(0x72, 0x04, SS_RDEF, - "Empty or partially written reserved track") }, -/* R */{SST(0x73, 0x00, SS_RDEF, - "CD control error") }, -/* R */{SST(0x73, 0x01, SS_RDEF, - "Power calibration area almost full") }, -/* R */{SST(0x73, 0x02, SS_FATAL|ENOSPC, - "Power calibration area is full") }, -/* R */{SST(0x73, 0x03, SS_RDEF, - "Power calibration area error") }, -/* R */{SST(0x73, 0x04, SS_RDEF, - "Program memory area update failure") }, -/* R */{SST(0x73, 0x05, SS_RDEF, - "program memory area is full") } -}; - -static const int asc_table_size = sizeof(asc_table)/sizeof(asc_table[0]); - -struct asc_key -{ - int asc; - int ascq; -}; - -static int -ascentrycomp(const void *key, const void *member) -{ - int asc; - int ascq; - const struct asc_table_entry *table_entry; - - asc = ((const struct asc_key *)key)->asc; - ascq = ((const struct asc_key *)key)->ascq; - table_entry = (const struct asc_table_entry *)member; - - if (asc >= table_entry->asc) { - - if (asc > table_entry->asc) - return (1); - - if (ascq <= table_entry->ascq) { - /* Check for ranges */ - if (ascq == table_entry->ascq - || ((table_entry->action & SSQ_RANGE) != 0 - && ascq >= (table_entry - 1)->ascq)) - return (0); - return (-1); - } - return (1); - } - return (-1); -} - -static int -senseentrycomp(const void *key, const void *member) -{ - int sense_key; - const struct sense_key_table_entry *table_entry; - - sense_key = *((const int *)key); - table_entry = (const struct sense_key_table_entry *)member; - - if (sense_key >= table_entry->sense_key) { - if (sense_key == table_entry->sense_key) - return (0); - return (1); - } - return (-1); -} - -static void -fetchtableentries(int sense_key, int asc, int ascq, - struct scsi_inquiry_data *inq_data, - const struct sense_key_table_entry **sense_entry, - const struct asc_table_entry **asc_entry) -{ - void *match; - const struct asc_table_entry *asc_tables[2]; - const struct sense_key_table_entry *sense_tables[2]; - struct asc_key asc_ascq; - size_t asc_tables_size[2]; - size_t sense_tables_size[2]; - int num_asc_tables; - int num_sense_tables; - int i; - - /* Default to failure */ - *sense_entry = NULL; - *asc_entry = NULL; - match = NULL; - if (inq_data != NULL) - match = cam_quirkmatch((void *)inq_data, - (void *)sense_quirk_table, - sense_quirk_table_size, - sizeof(*sense_quirk_table), - aic_inquiry_match); - - if (match != NULL) { - struct scsi_sense_quirk_entry *quirk; - - quirk = (struct scsi_sense_quirk_entry *)match; - asc_tables[0] = quirk->asc_info; - asc_tables_size[0] = quirk->num_ascs; - asc_tables[1] = asc_table; - asc_tables_size[1] = asc_table_size; - num_asc_tables = 2; - sense_tables[0] = quirk->sense_key_info; - sense_tables_size[0] = quirk->num_sense_keys; - sense_tables[1] = sense_key_table; - sense_tables_size[1] = sense_key_table_size; - num_sense_tables = 2; - } else { - asc_tables[0] = asc_table; - asc_tables_size[0] = asc_table_size; - num_asc_tables = 1; - sense_tables[0] = sense_key_table; - sense_tables_size[0] = sense_key_table_size; - num_sense_tables = 1; - } - - asc_ascq.asc = asc; - asc_ascq.ascq = ascq; - for (i = 0; i < num_asc_tables; i++) { - void *found_entry; - - found_entry = scsibsearch(&asc_ascq, asc_tables[i], - asc_tables_size[i], - sizeof(**asc_tables), - ascentrycomp); - - if (found_entry) { - *asc_entry = (struct asc_table_entry *)found_entry; - break; - } - } - - for (i = 0; i < num_sense_tables; i++) { - void *found_entry; - - found_entry = scsibsearch(&sense_key, sense_tables[i], - sense_tables_size[i], - sizeof(**sense_tables), - senseentrycomp); - - if (found_entry) { - *sense_entry = - (struct sense_key_table_entry *)found_entry; - break; - } - } -} - -static void * -scsibsearch(const void *key, const void *base, size_t nmemb, size_t size, - int (*compar)(const void *, const void *)) -{ - const void *entry; - u_int l; - u_int u; - u_int m; - - l = -1; - u = nmemb; - while (l + 1 != u) { - m = (l + u) / 2; - entry = base + m * size; - if (compar(key, entry) > 0) - l = m; - else - u = m; - } - - entry = base + u * size; - if (u == nmemb - || compar(key, entry) != 0) - return (NULL); - - return ((void *)entry); -} - -/* - * Compare string with pattern, returning 0 on match. - * Short pattern matches trailing blanks in name, - * wildcard '*' in pattern matches rest of name, - * wildcard '?' matches a single non-space character. - */ -static int -cam_strmatch(const uint8_t *str, const uint8_t *pattern, int str_len) -{ - - while (*pattern != '\0'&& str_len > 0) { - - if (*pattern == '*') { - return (0); - } - if ((*pattern != *str) - && (*pattern != '?' || *str == ' ')) { - return (1); - } - pattern++; - str++; - str_len--; - } - while (str_len > 0 && *str++ == ' ') - str_len--; - - return (str_len); -} - -static caddr_t -cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries, - int entry_size, cam_quirkmatch_t *comp_func) -{ - for (; num_entries > 0; num_entries--, quirk_table += entry_size) { - if ((*comp_func)(target, quirk_table) == 0) - return (quirk_table); - } - return (NULL); -} - -void -aic_sense_desc(int sense_key, int asc, int ascq, - struct scsi_inquiry_data *inq_data, - const char **sense_key_desc, const char **asc_desc) -{ - const struct asc_table_entry *asc_entry; - const struct sense_key_table_entry *sense_entry; - - fetchtableentries(sense_key, asc, ascq, - inq_data, - &sense_entry, - &asc_entry); - - *sense_key_desc = sense_entry->desc; - - if (asc_entry != NULL) - *asc_desc = asc_entry->desc; - else if (asc >= 0x80 && asc <= 0xff) - *asc_desc = "Vendor Specific ASC"; - else if (ascq >= 0x80 && ascq <= 0xff) - *asc_desc = "Vendor Specific ASCQ"; - else - *asc_desc = "Reserved ASC/ASCQ pair"; -} - -/* - * Given sense and device type information, return the appropriate action. - * If we do not understand the specific error as identified by the ASC/ASCQ - * pair, fall back on the more generic actions derived from the sense key. - */ -aic_sense_action -aic_sense_error_action(struct scsi_sense_data *sense_data, - struct scsi_inquiry_data *inq_data, uint32_t sense_flags) -{ - const struct asc_table_entry *asc_entry; - const struct sense_key_table_entry *sense_entry; - int error_code, sense_key, asc, ascq; - aic_sense_action action; - - scsi_extract_sense(sense_data, &error_code, &sense_key, &asc, &ascq); - - if (error_code == SSD_DEFERRED_ERROR) { - /* - * XXX dufault@FreeBSD.org - * This error doesn't relate to the command associated - * with this request sense. A deferred error is an error - * for a command that has already returned GOOD status - * (see SCSI2 8.2.14.2). - * - * By my reading of that section, it looks like the current - * command has been cancelled, we should now clean things up - * (hopefully recovering any lost data) and then retry the - * current command. There are two easy choices, both wrong: - * - * 1. Drop through (like we had been doing), thus treating - * this as if the error were for the current command and - * return and stop the current command. - * - * 2. Issue a retry (like I made it do) thus hopefully - * recovering the current transfer, and ignoring the - * fact that we've dropped a command. - * - * These should probably be handled in a device specific - * sense handler or punted back up to a user mode daemon - */ - action = SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE; - } else { - fetchtableentries(sense_key, asc, ascq, - inq_data, - &sense_entry, - &asc_entry); - - /* - * Override the 'No additional Sense' entry (0,0) - * with the error action of the sense key. - */ - if (asc_entry != NULL - && (asc != 0 || ascq != 0)) - action = asc_entry->action; - else - action = sense_entry->action; - - if (sense_key == SSD_KEY_RECOVERED_ERROR) { - /* - * The action succeeded but the device wants - * the user to know that some recovery action - * was required. - */ - action &= ~(SS_MASK|SSQ_MASK|SS_ERRMASK); - action |= SS_NOP|SSQ_PRINT_SENSE; - } else if (sense_key == SSD_KEY_ILLEGAL_REQUEST) { - if ((sense_flags & SF_QUIET_IR) != 0) - action &= ~SSQ_PRINT_SENSE; - } else if (sense_key == SSD_KEY_UNIT_ATTENTION) { - if ((sense_flags & SF_RETRY_UA) != 0 - && (action & SS_MASK) == SS_FAIL) { - action &= ~(SS_MASK|SSQ_MASK); - action |= SS_RETRY|SSQ_DECREMENT_COUNT| - SSQ_PRINT_SENSE; - } - } - } - - if ((sense_flags & SF_PRINT_ALWAYS) != 0) - action |= SSQ_PRINT_SENSE; - else if ((sense_flags & SF_NO_PRINT) != 0) - action &= ~SSQ_PRINT_SENSE; - - return (action); -} - -/* - * Try make as good a match as possible with - * available sub drivers - */ -int -aic_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) -{ - struct scsi_inquiry_pattern *entry; - struct scsi_inquiry_data *inq; - - entry = (struct scsi_inquiry_pattern *)table_entry; - inq = (struct scsi_inquiry_data *)inqbuffer; - - if (((SID_TYPE(inq) == entry->type) - || (entry->type == T_ANY)) - && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE - : entry->media_type & SIP_MEDIA_FIXED) - && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) - && (cam_strmatch(inq->product, entry->product, - sizeof(inq->product)) == 0) - && (cam_strmatch(inq->revision, entry->revision, - sizeof(inq->revision)) == 0)) { - return (0); - } - return (-1); -} - -/* - * Table of syncrates that don't follow the "divisible by 4" - * rule. This table will be expanded in future SCSI specs. - */ -static struct { - u_int period_factor; - u_int period; /* in 100ths of ns */ -} scsi_syncrates[] = { - { 0x08, 625 }, /* FAST-160 */ - { 0x09, 1250 }, /* FAST-80 */ - { 0x0a, 2500 }, /* FAST-40 40MHz */ - { 0x0b, 3030 }, /* FAST-40 33MHz */ - { 0x0c, 5000 } /* FAST-20 */ -}; - -/* - * Return the frequency in kHz corresponding to the given - * sync period factor. - */ -u_int -aic_calc_syncsrate(u_int period_factor) -{ - int i; - int num_syncrates; - - num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); - /* See if the period is in the "exception" table */ - for (i = 0; i < num_syncrates; i++) { - - if (period_factor == scsi_syncrates[i].period_factor) { - /* Period in kHz */ - return (100000000 / scsi_syncrates[i].period); - } - } - - /* - * Wasn't in the table, so use the standard - * 4 times conversion. - */ - return (10000000 / (period_factor * 4 * 10)); -} - -/* - * Return speed in KB/s. - */ -u_int -aic_calc_speed(u_int width, u_int period, u_int offset, u_int min_rate) -{ - u_int freq; - - if (offset != 0 && period < min_rate) - freq = aic_calc_syncsrate(period); - else - /* Roughly 3.3MB/s for async */ - freq = 3300; - freq <<= width; - return (freq); -} - -uint32_t -aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data, - cam_status status, u_int scsi_status) -{ - aic_sense_action err_action; - int sense; - - sense = (cmd->result >> 24) == DRIVER_SENSE; - - switch (status) { - case CAM_REQ_CMP: - err_action = SS_NOP; - break; - case CAM_AUTOSENSE_FAIL: - case CAM_SCSI_STATUS_ERROR: - - switch (scsi_status) { - case SCSI_STATUS_OK: - case SCSI_STATUS_COND_MET: - case SCSI_STATUS_INTERMED: - case SCSI_STATUS_INTERMED_COND_MET: - err_action = SS_NOP; - break; - case SCSI_STATUS_CMD_TERMINATED: - case SCSI_STATUS_CHECK_COND: - if (sense != 0) { - struct scsi_sense_data *sense; - - sense = (struct scsi_sense_data *) - &cmd->sense_buffer; - err_action = - aic_sense_error_action(sense, inq_data, 0); - - } else { - err_action = SS_RETRY|SSQ_FALLBACK - | SSQ_DECREMENT_COUNT|EIO; - } - break; - case SCSI_STATUS_QUEUE_FULL: - case SCSI_STATUS_BUSY: - err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY - | SSQ_DECREMENT_COUNT|EBUSY; - break; - case SCSI_STATUS_RESERV_CONFLICT: - default: - err_action = SS_FAIL|EBUSY; - break; - } - break; - case CAM_CMD_TIMEOUT: - case CAM_REQ_CMP_ERR: - case CAM_UNEXP_BUSFREE: - case CAM_UNCOR_PARITY: - case CAM_DATA_RUN_ERR: - err_action = SS_RETRY|SSQ_FALLBACK|EIO; - break; - case CAM_UA_ABORT: - case CAM_UA_TERMIO: - case CAM_MSG_REJECT_REC: - case CAM_SEL_TIMEOUT: - err_action = SS_FAIL|EIO; - break; - case CAM_REQ_INVALID: - case CAM_PATH_INVALID: - case CAM_DEV_NOT_THERE: - case CAM_NO_HBA: - case CAM_PROVIDE_FAIL: - case CAM_REQ_TOO_BIG: - case CAM_RESRC_UNAVAIL: - case CAM_BUSY: - default: - /* panic?? These should never occur in our application. */ - err_action = SS_FAIL|EIO; - break; - case CAM_SCSI_BUS_RESET: - case CAM_BDR_SENT: - case CAM_REQUEUE_REQ: - /* Unconditional requeue */ - err_action = SS_RETRY; - break; - } - - return (err_action); -} - diff -urN linux-2.4.21/drivers/scsi/aic79xx/aiclib.h linux-2.4.22/drivers/scsi/aic79xx/aiclib.h --- linux-2.4.21/drivers/scsi/aic79xx/aiclib.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/aiclib.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,1001 +0,0 @@ -/* - * Largely written by Julian Elischer (julian@tfs.com) - * for TRW Financial Systems. - * - * TRW Financial Systems, in accordance with their agreement with Carnegie - * Mellon University, makes this software available to CMU to distribute - * or use in any manner that they see fit as long as this message is kept with - * the software. For this reason TFS also grants any other persons or - * organisations permission to use or modify this software. - * - * TFS supplies this software to be publicly redistributed - * on the understanding that TFS is not responsible for the correct - * functioning of this software in any circumstances. - * - * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 - * - * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.21 2002/10/08 17:12:44 ken Exp $ - * $Id$ - */ - -/* - * SCSI general interface description - */ - -#ifndef _SCSI_SCSI_ALL_H -#define _SCSI_SCSI_ALL_H 1 - -/* - * SCSI command format - */ - -/* - * Define dome bits that are in ALL (or a lot of) scsi commands - */ -#define SCSI_CTL_LINK 0x01 -#define SCSI_CTL_FLAG 0x02 -#define SCSI_CTL_VENDOR 0xC0 -#define SCSI_CMD_LUN 0xA0 /* these two should not be needed */ -#define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */ - -#define SCSI_MAX_CDBLEN 16 /* - * 16 byte commands are in the - * SCSI-3 spec - */ -/* 6byte CDBs special case 0 length to be 256 */ -#define SCSI_CDB6_LEN(len) ((len) == 0 ? 256 : len) - -/* - * This type defines actions to be taken when a particular sense code is - * received. Right now, these flags are only defined to take up 16 bits, - * but can be expanded in the future if necessary. - */ -typedef enum { - SS_NOP = 0x000000, /* Do nothing */ - SS_RETRY = 0x010000, /* Retry the command */ - SS_FAIL = 0x020000, /* Bail out */ - SS_START = 0x030000, /* Send a Start Unit command to the device, - * then retry the original command. - */ - SS_TUR = 0x040000, /* Send a Test Unit Ready command to the - * device, then retry the original command. - */ - SS_REQSENSE = 0x050000, /* Send a RequestSense command to the - * device, then retry the original command. - */ - SS_INQ_REFRESH = 0x060000, - SS_MASK = 0xff0000 -} aic_sense_action; - -typedef enum { - SSQ_NONE = 0x0000, - SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */ - SSQ_MANY = 0x0200, /* send lots of recovery commands */ - SSQ_RANGE = 0x0400, /* - * This table entry represents the - * end of a range of ASCQs that - * have identical error actions - * and text. - */ - SSQ_PRINT_SENSE = 0x0800, - SSQ_DELAY = 0x1000, /* Delay before retry. */ - SSQ_DELAY_RANDOM = 0x2000, /* Randomized delay before retry. */ - SSQ_FALLBACK = 0x4000, /* Do a speed fallback to recover */ - SSQ_MASK = 0xff00 -} aic_sense_action_qualifier; - -/* Mask for error status values */ -#define SS_ERRMASK 0xff - -/* The default, retyable, error action */ -#define SS_RDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO - -/* The retyable, error action, with table specified error code */ -#define SS_RET SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE - -/* Fatal error action, with table specified error code */ -#define SS_FATAL SS_FAIL|SSQ_PRINT_SENSE - -struct scsi_generic -{ - uint8_t opcode; - uint8_t bytes[11]; -}; - -struct scsi_request_sense -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[2]; - uint8_t length; - uint8_t control; -}; - -struct scsi_test_unit_ready -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[3]; - uint8_t control; -}; - -struct scsi_send_diag -{ - uint8_t opcode; - uint8_t byte2; -#define SSD_UOL 0x01 -#define SSD_DOL 0x02 -#define SSD_SELFTEST 0x04 -#define SSD_PF 0x10 - uint8_t unused[1]; - uint8_t paramlen[2]; - uint8_t control; -}; - -struct scsi_sense -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[2]; - uint8_t length; - uint8_t control; -}; - -struct scsi_inquiry -{ - uint8_t opcode; - uint8_t byte2; -#define SI_EVPD 0x01 - uint8_t page_code; - uint8_t reserved; - uint8_t length; - uint8_t control; -}; - -struct scsi_mode_sense_6 -{ - uint8_t opcode; - uint8_t byte2; -#define SMS_DBD 0x08 - uint8_t page; -#define SMS_PAGE_CODE 0x3F -#define SMS_VENDOR_SPECIFIC_PAGE 0x00 -#define SMS_DISCONNECT_RECONNECT_PAGE 0x02 -#define SMS_PERIPHERAL_DEVICE_PAGE 0x09 -#define SMS_CONTROL_MODE_PAGE 0x0A -#define SMS_ALL_PAGES_PAGE 0x3F -#define SMS_PAGE_CTRL_MASK 0xC0 -#define SMS_PAGE_CTRL_CURRENT 0x00 -#define SMS_PAGE_CTRL_CHANGEABLE 0x40 -#define SMS_PAGE_CTRL_DEFAULT 0x80 -#define SMS_PAGE_CTRL_SAVED 0xC0 - uint8_t unused; - uint8_t length; - uint8_t control; -}; - -struct scsi_mode_sense_10 -{ - uint8_t opcode; - uint8_t byte2; /* same bits as small version */ - uint8_t page; /* same bits as small version */ - uint8_t unused[4]; - uint8_t length[2]; - uint8_t control; -}; - -struct scsi_mode_select_6 -{ - uint8_t opcode; - uint8_t byte2; -#define SMS_SP 0x01 -#define SMS_PF 0x10 - uint8_t unused[2]; - uint8_t length; - uint8_t control; -}; - -struct scsi_mode_select_10 -{ - uint8_t opcode; - uint8_t byte2; /* same bits as small version */ - uint8_t unused[5]; - uint8_t length[2]; - uint8_t control; -}; - -/* - * When sending a mode select to a tape drive, the medium type must be 0. - */ -struct scsi_mode_hdr_6 -{ - uint8_t datalen; - uint8_t medium_type; - uint8_t dev_specific; - uint8_t block_descr_len; -}; - -struct scsi_mode_hdr_10 -{ - uint8_t datalen[2]; - uint8_t medium_type; - uint8_t dev_specific; - uint8_t reserved[2]; - uint8_t block_descr_len[2]; -}; - -struct scsi_mode_block_descr -{ - uint8_t density_code; - uint8_t num_blocks[3]; - uint8_t reserved; - uint8_t block_len[3]; -}; - -struct scsi_log_sense -{ - uint8_t opcode; - uint8_t byte2; -#define SLS_SP 0x01 -#define SLS_PPC 0x02 - uint8_t page; -#define SLS_PAGE_CODE 0x3F -#define SLS_ALL_PAGES_PAGE 0x00 -#define SLS_OVERRUN_PAGE 0x01 -#define SLS_ERROR_WRITE_PAGE 0x02 -#define SLS_ERROR_READ_PAGE 0x03 -#define SLS_ERROR_READREVERSE_PAGE 0x04 -#define SLS_ERROR_VERIFY_PAGE 0x05 -#define SLS_ERROR_NONMEDIUM_PAGE 0x06 -#define SLS_ERROR_LASTN_PAGE 0x07 -#define SLS_PAGE_CTRL_MASK 0xC0 -#define SLS_PAGE_CTRL_THRESHOLD 0x00 -#define SLS_PAGE_CTRL_CUMULATIVE 0x40 -#define SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 -#define SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 - uint8_t reserved[2]; - uint8_t paramptr[2]; - uint8_t length[2]; - uint8_t control; -}; - -struct scsi_log_select -{ - uint8_t opcode; - uint8_t byte2; -/* SLS_SP 0x01 */ -#define SLS_PCR 0x02 - uint8_t page; -/* SLS_PAGE_CTRL_MASK 0xC0 */ -/* SLS_PAGE_CTRL_THRESHOLD 0x00 */ -/* SLS_PAGE_CTRL_CUMULATIVE 0x40 */ -/* SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 */ -/* SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 */ - uint8_t reserved[4]; - uint8_t length[2]; - uint8_t control; -}; - -struct scsi_log_header -{ - uint8_t page; - uint8_t reserved; - uint8_t datalen[2]; -}; - -struct scsi_log_param_header { - uint8_t param_code[2]; - uint8_t param_control; -#define SLP_LP 0x01 -#define SLP_LBIN 0x02 -#define SLP_TMC_MASK 0x0C -#define SLP_TMC_ALWAYS 0x00 -#define SLP_TMC_EQUAL 0x04 -#define SLP_TMC_NOTEQUAL 0x08 -#define SLP_TMC_GREATER 0x0C -#define SLP_ETC 0x10 -#define SLP_TSD 0x20 -#define SLP_DS 0x40 -#define SLP_DU 0x80 - uint8_t param_len; -}; - -struct scsi_control_page { - uint8_t page_code; - uint8_t page_length; - uint8_t rlec; -#define SCB_RLEC 0x01 /*Report Log Exception Cond*/ - uint8_t queue_flags; -#define SCP_QUEUE_ALG_MASK 0xF0 -#define SCP_QUEUE_ALG_RESTRICTED 0x00 -#define SCP_QUEUE_ALG_UNRESTRICTED 0x10 -#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/ -#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/ - uint8_t eca_and_aen; -#define SCP_EECA 0x80 /*Enable Extended CA*/ -#define SCP_RAENP 0x04 /*Ready AEN Permission*/ -#define SCP_UAAENP 0x02 /*UA AEN Permission*/ -#define SCP_EAENP 0x01 /*Error AEN Permission*/ - uint8_t reserved; - uint8_t aen_holdoff_period[2]; -}; - -struct scsi_reserve -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[2]; - uint8_t length; - uint8_t control; -}; - -struct scsi_release -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[2]; - uint8_t length; - uint8_t control; -}; - -struct scsi_prevent -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[2]; - uint8_t how; - uint8_t control; -}; -#define PR_PREVENT 0x01 -#define PR_ALLOW 0x00 - -struct scsi_sync_cache -{ - uint8_t opcode; - uint8_t byte2; - uint8_t begin_lba[4]; - uint8_t reserved; - uint8_t lb_count[2]; - uint8_t control; -}; - - -struct scsi_changedef -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused1; - uint8_t how; - uint8_t unused[4]; - uint8_t datalen; - uint8_t control; -}; - -struct scsi_read_buffer -{ - uint8_t opcode; - uint8_t byte2; -#define RWB_MODE 0x07 -#define RWB_MODE_HDR_DATA 0x00 -#define RWB_MODE_DATA 0x02 -#define RWB_MODE_DOWNLOAD 0x04 -#define RWB_MODE_DOWNLOAD_SAVE 0x05 - uint8_t buffer_id; - uint8_t offset[3]; - uint8_t length[3]; - uint8_t control; -}; - -struct scsi_write_buffer -{ - uint8_t opcode; - uint8_t byte2; - uint8_t buffer_id; - uint8_t offset[3]; - uint8_t length[3]; - uint8_t control; -}; - -struct scsi_rw_6 -{ - uint8_t opcode; - uint8_t addr[3]; -/* only 5 bits are valid in the MSB address byte */ -#define SRW_TOPADDR 0x1F - uint8_t length; - uint8_t control; -}; - -struct scsi_rw_10 -{ - uint8_t opcode; -#define SRW10_RELADDR 0x01 -#define SRW10_FUA 0x08 -#define SRW10_DPO 0x10 - uint8_t byte2; - uint8_t addr[4]; - uint8_t reserved; - uint8_t length[2]; - uint8_t control; -}; - -struct scsi_rw_12 -{ - uint8_t opcode; -#define SRW12_RELADDR 0x01 -#define SRW12_FUA 0x08 -#define SRW12_DPO 0x10 - uint8_t byte2; - uint8_t addr[4]; - uint8_t length[4]; - uint8_t reserved; - uint8_t control; -}; - -struct scsi_start_stop_unit -{ - uint8_t opcode; - uint8_t byte2; -#define SSS_IMMED 0x01 - uint8_t reserved[2]; - uint8_t how; -#define SSS_START 0x01 -#define SSS_LOEJ 0x02 - uint8_t control; -}; - -#define SC_SCSI_1 0x01 -#define SC_SCSI_2 0x03 - -/* - * Opcodes - */ - -#define TEST_UNIT_READY 0x00 -#define REQUEST_SENSE 0x03 -#define READ_6 0x08 -#define WRITE_6 0x0a -#define INQUIRY 0x12 -#define MODE_SELECT_6 0x15 -#define MODE_SENSE_6 0x1a -#define START_STOP_UNIT 0x1b -#define START_STOP 0x1b -#define RESERVE 0x16 -#define RELEASE 0x17 -#define RECEIVE_DIAGNOSTIC 0x1c -#define SEND_DIAGNOSTIC 0x1d -#define PREVENT_ALLOW 0x1e -#define READ_CAPACITY 0x25 -#define READ_10 0x28 -#define WRITE_10 0x2a -#define POSITION_TO_ELEMENT 0x2b -#define SYNCHRONIZE_CACHE 0x35 -#define WRITE_BUFFER 0x3b -#define READ_BUFFER 0x3c -#define CHANGE_DEFINITION 0x40 -#define LOG_SELECT 0x4c -#define LOG_SENSE 0x4d -#ifdef XXXCAM -#define MODE_SENSE_10 0x5A -#endif -#define MODE_SELECT_10 0x55 -#define MOVE_MEDIUM 0xa5 -#define READ_12 0xa8 -#define WRITE_12 0xaa -#define READ_ELEMENT_STATUS 0xb8 - - -/* - * Device Types - */ -#define T_DIRECT 0x00 -#define T_SEQUENTIAL 0x01 -#define T_PRINTER 0x02 -#define T_PROCESSOR 0x03 -#define T_WORM 0x04 -#define T_CDROM 0x05 -#define T_SCANNER 0x06 -#define T_OPTICAL 0x07 -#define T_CHANGER 0x08 -#define T_COMM 0x09 -#define T_ASC0 0x0a -#define T_ASC1 0x0b -#define T_STORARRAY 0x0c -#define T_ENCLOSURE 0x0d -#define T_RBC 0x0e -#define T_OCRW 0x0f -#define T_NODEVICE 0x1F -#define T_ANY 0xFF /* Used in Quirk table matches */ - -#define T_REMOV 1 -#define T_FIXED 0 - -/* - * This length is the initial inquiry length used by the probe code, as - * well as the legnth necessary for aic_print_inquiry() to function - * correctly. If either use requires a different length in the future, - * the two values should be de-coupled. - */ -#define SHORT_INQUIRY_LENGTH 36 - -struct scsi_inquiry_data -{ - uint8_t device; -#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f) -#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5) -#define SID_QUAL_LU_CONNECTED 0x00 /* - * The specified peripheral device - * type is currently connected to - * logical unit. If the target cannot - * determine whether or not a physical - * device is currently connected, it - * shall also use this peripheral - * qualifier when returning the INQUIRY - * data. This peripheral qualifier - * does not mean that the device is - * ready for access by the initiator. - */ -#define SID_QUAL_LU_OFFLINE 0x01 /* - * The target is capable of supporting - * the specified peripheral device type - * on this logical unit; however, the - * physical device is not currently - * connected to this logical unit. - */ -#define SID_QUAL_RSVD 0x02 -#define SID_QUAL_BAD_LU 0x03 /* - * The target is not capable of - * supporting a physical device on - * this logical unit. For this - * peripheral qualifier the peripheral - * device type shall be set to 1Fh to - * provide compatibility with previous - * versions of SCSI. All other - * peripheral device type values are - * reserved for this peripheral - * qualifier. - */ -#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) - uint8_t dev_qual2; -#define SID_QUAL2 0x7F -#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0) - uint8_t version; -#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07) -#define SCSI_REV_0 0 -#define SCSI_REV_CCS 1 -#define SCSI_REV_2 2 -#define SCSI_REV_SPC 3 -#define SCSI_REV_SPC2 4 - -#define SID_ECMA 0x38 -#define SID_ISO 0xC0 - uint8_t response_format; -#define SID_AENC 0x80 -#define SID_TrmIOP 0x40 - uint8_t additional_length; - uint8_t reserved[2]; - uint8_t flags; -#define SID_SftRe 0x01 -#define SID_CmdQue 0x02 -#define SID_Linked 0x08 -#define SID_Sync 0x10 -#define SID_WBus16 0x20 -#define SID_WBus32 0x40 -#define SID_RelAdr 0x80 -#define SID_VENDOR_SIZE 8 - char vendor[SID_VENDOR_SIZE]; -#define SID_PRODUCT_SIZE 16 - char product[SID_PRODUCT_SIZE]; -#define SID_REVISION_SIZE 4 - char revision[SID_REVISION_SIZE]; - /* - * The following fields were taken from SCSI Primary Commands - 2 - * (SPC-2) Revision 14, Dated 11 November 1999 - */ -#define SID_VENDOR_SPECIFIC_0_SIZE 20 - uint8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE]; - /* - * An extension of SCSI Parallel Specific Values - */ -#define SID_SPI_IUS 0x01 -#define SID_SPI_QAS 0x02 -#define SID_SPI_CLOCK_ST 0x00 -#define SID_SPI_CLOCK_DT 0x04 -#define SID_SPI_CLOCK_DT_ST 0x0C -#define SID_SPI_MASK 0x0F - uint8_t spi3data; - uint8_t reserved2; - /* - * Version Descriptors, stored 2 byte values. - */ - uint8_t version1[2]; - uint8_t version2[2]; - uint8_t version3[2]; - uint8_t version4[2]; - uint8_t version5[2]; - uint8_t version6[2]; - uint8_t version7[2]; - uint8_t version8[2]; - - uint8_t reserved3[22]; - -#define SID_VENDOR_SPECIFIC_1_SIZE 160 - uint8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE]; -}; - -struct scsi_vpd_unit_serial_number -{ - uint8_t device; - uint8_t page_code; -#define SVPD_UNIT_SERIAL_NUMBER 0x80 - uint8_t reserved; - uint8_t length; /* serial number length */ -#define SVPD_SERIAL_NUM_SIZE 251 - uint8_t serial_num[SVPD_SERIAL_NUM_SIZE]; -}; - -struct scsi_read_capacity -{ - uint8_t opcode; - uint8_t byte2; - uint8_t addr[4]; - uint8_t unused[3]; - uint8_t control; -}; - -struct scsi_read_capacity_data -{ - uint8_t addr[4]; - uint8_t length[4]; -}; - -struct scsi_report_luns -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[3]; - uint8_t addr[4]; - uint8_t control; -}; - -struct scsi_report_luns_data { - uint8_t length[4]; /* length of LUN inventory, in bytes */ - uint8_t reserved[4]; /* unused */ - /* - * LUN inventory- we only support the type zero form for now. - */ - struct { - uint8_t lundata[8]; - } luns[1]; -}; -#define RPL_LUNDATA_ATYP_MASK 0xc0 /* MBZ for type 0 lun */ -#define RPL_LUNDATA_T0LUN 1 /* @ lundata[1] */ - - -struct scsi_sense_data -{ - uint8_t error_code; -#define SSD_ERRCODE 0x7F -#define SSD_CURRENT_ERROR 0x70 -#define SSD_DEFERRED_ERROR 0x71 -#define SSD_ERRCODE_VALID 0x80 - uint8_t segment; - uint8_t flags; -#define SSD_KEY 0x0F -#define SSD_KEY_NO_SENSE 0x00 -#define SSD_KEY_RECOVERED_ERROR 0x01 -#define SSD_KEY_NOT_READY 0x02 -#define SSD_KEY_MEDIUM_ERROR 0x03 -#define SSD_KEY_HARDWARE_ERROR 0x04 -#define SSD_KEY_ILLEGAL_REQUEST 0x05 -#define SSD_KEY_UNIT_ATTENTION 0x06 -#define SSD_KEY_DATA_PROTECT 0x07 -#define SSD_KEY_BLANK_CHECK 0x08 -#define SSD_KEY_Vendor_Specific 0x09 -#define SSD_KEY_COPY_ABORTED 0x0a -#define SSD_KEY_ABORTED_COMMAND 0x0b -#define SSD_KEY_EQUAL 0x0c -#define SSD_KEY_VOLUME_OVERFLOW 0x0d -#define SSD_KEY_MISCOMPARE 0x0e -#define SSD_KEY_RESERVED 0x0f -#define SSD_ILI 0x20 -#define SSD_EOM 0x40 -#define SSD_FILEMARK 0x80 - uint8_t info[4]; - uint8_t extra_len; - uint8_t cmd_spec_info[4]; - uint8_t add_sense_code; - uint8_t add_sense_code_qual; - uint8_t fru; - uint8_t sense_key_spec[3]; -#define SSD_SCS_VALID 0x80 -#define SSD_FIELDPTR_CMD 0x40 -#define SSD_BITPTR_VALID 0x08 -#define SSD_BITPTR_VALUE 0x07 -#define SSD_MIN_SIZE 18 - uint8_t extra_bytes[14]; -#define SSD_FULL_SIZE sizeof(struct scsi_sense_data) -}; - -struct scsi_mode_header_6 -{ - uint8_t data_length; /* Sense data length */ - uint8_t medium_type; - uint8_t dev_spec; - uint8_t blk_desc_len; -}; - -struct scsi_mode_header_10 -{ - uint8_t data_length[2];/* Sense data length */ - uint8_t medium_type; - uint8_t dev_spec; - uint8_t unused[2]; - uint8_t blk_desc_len[2]; -}; - -struct scsi_mode_page_header -{ - uint8_t page_code; - uint8_t page_length; -}; - -struct scsi_mode_blk_desc -{ - uint8_t density; - uint8_t nblocks[3]; - uint8_t reserved; - uint8_t blklen[3]; -}; - -#define SCSI_DEFAULT_DENSITY 0x00 /* use 'default' density */ -#define SCSI_SAME_DENSITY 0x7f /* use 'same' density- >= SCSI-2 only */ - - -/* - * Status Byte - */ -#define SCSI_STATUS_OK 0x00 -#define SCSI_STATUS_CHECK_COND 0x02 -#define SCSI_STATUS_COND_MET 0x04 -#define SCSI_STATUS_BUSY 0x08 -#define SCSI_STATUS_INTERMED 0x10 -#define SCSI_STATUS_INTERMED_COND_MET 0x14 -#define SCSI_STATUS_RESERV_CONFLICT 0x18 -#define SCSI_STATUS_CMD_TERMINATED 0x22 /* Obsolete in SAM-2 */ -#define SCSI_STATUS_QUEUE_FULL 0x28 -#define SCSI_STATUS_ACA_ACTIVE 0x30 -#define SCSI_STATUS_TASK_ABORTED 0x40 - -struct scsi_inquiry_pattern { - uint8_t type; - uint8_t media_type; -#define SIP_MEDIA_REMOVABLE 0x01 -#define SIP_MEDIA_FIXED 0x02 - const char *vendor; - const char *product; - const char *revision; -}; - -struct scsi_static_inquiry_pattern { - uint8_t type; - uint8_t media_type; - char vendor[SID_VENDOR_SIZE+1]; - char product[SID_PRODUCT_SIZE+1]; - char revision[SID_REVISION_SIZE+1]; -}; - -struct scsi_sense_quirk_entry { - struct scsi_inquiry_pattern inq_pat; - int num_sense_keys; - int num_ascs; - struct sense_key_table_entry *sense_key_info; - struct asc_table_entry *asc_info; -}; - -struct sense_key_table_entry { - uint8_t sense_key; - uint32_t action; - const char *desc; -}; - -struct asc_table_entry { - uint8_t asc; - uint8_t ascq; - uint32_t action; - const char *desc; -}; - -struct op_table_entry { - uint8_t opcode; - uint16_t opmask; - const char *desc; -}; - -struct scsi_op_quirk_entry { - struct scsi_inquiry_pattern inq_pat; - int num_ops; - struct op_table_entry *op_table; -}; - -typedef enum { - SSS_FLAG_NONE = 0x00, - SSS_FLAG_PRINT_COMMAND = 0x01 -} scsi_sense_string_flags; - -extern const char *scsi_sense_key_text[]; - -/************************* Large Disk Handling ********************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -static __inline int aic_sector_div(u_long capacity, int heads, int sectors); - -static __inline int -aic_sector_div(u_long capacity, int heads, int sectors) -{ - return (capacity / (heads * sectors)); -} -#else -static __inline int aic_sector_div(sector_t capacity, int heads, int sectors); - -static __inline int -aic_sector_div(sector_t capacity, int heads, int sectors) -{ - /* ugly, ugly sector_div calling convention.. */ - sector_div(capacity, (heads * sectors)); - return (int)capacity; -} -#endif - -/**************************** Module Library Hack *****************************/ -/* - * What we'd like to do is have a single "scsi library" module that both the - * aic7xxx and aic79xx drivers could load and depend on. A cursory examination - * of implementing module dependencies in Linux (handling the install and - * initrd cases) does not look promissing. For now, we just duplicate this - * code in both drivers using a simple symbol renaming scheme that hides this - * hack from the drivers. - */ -#define AIC_LIB_ENTRY_CONCAT(x, prefix) prefix ## x -#define AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix) -#define AIC_LIB_ENTRY(x) AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX) - -#define aic_sense_desc AIC_LIB_ENTRY(_sense_desc) -#define aic_sense_error_action AIC_LIB_ENTRY(_sense_error_action) -#define aic_error_action AIC_LIB_ENTRY(_error_action) -#define aic_op_desc AIC_LIB_ENTRY(_op_desc) -#define aic_cdb_string AIC_LIB_ENTRY(_cdb_string) -#define aic_print_inquiry AIC_LIB_ENTRY(_print_inquiry) -#define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate) -#define aic_calc_syncparam AIC_LIB_ENTRY(_calc_syncparam) -#define aic_calc_speed AIC_LIB_ENTRY(_calc_speed) -#define aic_inquiry_match AIC_LIB_ENTRY(_inquiry_match) -#define aic_static_inquiry_match AIC_LIB_ENTRY(_static_inquiry_match) - -/******************************************************************************/ - -void aic_sense_desc(int /*sense_key*/, int /*asc*/, - int /*ascq*/, struct scsi_inquiry_data*, - const char** /*sense_key_desc*/, - const char** /*asc_desc*/); -aic_sense_action aic_sense_error_action(struct scsi_sense_data*, - struct scsi_inquiry_data*, - uint32_t /*sense_flags*/); -uint32_t aic_error_action(struct scsi_cmnd *, - struct scsi_inquiry_data *, - cam_status, u_int); - -#define SF_RETRY_UA 0x01 -#define SF_NO_PRINT 0x02 -#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */ -#define SF_PRINT_ALWAYS 0x08 - - -const char * aic_op_desc(uint16_t /*opcode*/, struct scsi_inquiry_data*); -char * aic_cdb_string(uint8_t* /*cdb_ptr*/, char* /*cdb_string*/, - size_t /*len*/); -void aic_print_inquiry(struct scsi_inquiry_data*); - -u_int aic_calc_syncsrate(u_int /*period_factor*/); -u_int aic_calc_syncparam(u_int /*period*/); -u_int aic_calc_speed(u_int width, u_int period, u_int offset, - u_int min_rate); - -int aic_inquiry_match(caddr_t /*inqbuffer*/, - caddr_t /*table_entry*/); -int aic_static_inquiry_match(caddr_t /*inqbuffer*/, - caddr_t /*table_entry*/); - - -static __inline void scsi_extract_sense(struct scsi_sense_data *sense, - int *error_code, int *sense_key, - int *asc, int *ascq); -static __inline void scsi_ulto2b(uint32_t val, uint8_t *bytes); -static __inline void scsi_ulto3b(uint32_t val, uint8_t *bytes); -static __inline void scsi_ulto4b(uint32_t val, uint8_t *bytes); -static __inline uint32_t scsi_2btoul(uint8_t *bytes); -static __inline uint32_t scsi_3btoul(uint8_t *bytes); -static __inline int32_t scsi_3btol(uint8_t *bytes); -static __inline uint32_t scsi_4btoul(uint8_t *bytes); - -static __inline void scsi_extract_sense(struct scsi_sense_data *sense, - int *error_code, int *sense_key, - int *asc, int *ascq) -{ - *error_code = sense->error_code & SSD_ERRCODE; - *sense_key = sense->flags & SSD_KEY; - *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; - *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; -} - -static __inline void -scsi_ulto2b(uint32_t val, uint8_t *bytes) -{ - - bytes[0] = (val >> 8) & 0xff; - bytes[1] = val & 0xff; -} - -static __inline void -scsi_ulto3b(uint32_t val, uint8_t *bytes) -{ - - bytes[0] = (val >> 16) & 0xff; - bytes[1] = (val >> 8) & 0xff; - bytes[2] = val & 0xff; -} - -static __inline void -scsi_ulto4b(uint32_t val, uint8_t *bytes) -{ - - bytes[0] = (val >> 24) & 0xff; - bytes[1] = (val >> 16) & 0xff; - bytes[2] = (val >> 8) & 0xff; - bytes[3] = val & 0xff; -} - -static __inline uint32_t -scsi_2btoul(uint8_t *bytes) -{ - uint32_t rv; - - rv = (bytes[0] << 8) | - bytes[1]; - return (rv); -} - -static __inline uint32_t -scsi_3btoul(uint8_t *bytes) -{ - uint32_t rv; - - rv = (bytes[0] << 16) | - (bytes[1] << 8) | - bytes[2]; - return (rv); -} - -static __inline int32_t -scsi_3btol(uint8_t *bytes) -{ - uint32_t rc = scsi_3btoul(bytes); - - if (rc & 0x00800000) - rc |= 0xff000000; - - return (int32_t) rc; -} - -static __inline uint32_t -scsi_4btoul(uint8_t *bytes) -{ - uint32_t rv; - - rv = (bytes[0] << 24) | - (bytes[1] << 16) | - (bytes[2] << 8) | - bytes[3]; - return (rv); -} - -#endif /*_SCSI_SCSI_ALL_H*/ diff -urN linux-2.4.21/drivers/scsi/aic79xx/cam.h linux-2.4.22/drivers/scsi/aic79xx/cam.h --- linux-2.4.21/drivers/scsi/aic79xx/cam.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/cam.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,117 +0,0 @@ -/* - * Data structures and definitions for the CAM system. - * - * Copyright (c) 1997 Justin T. Gibbs. - * Copyright (c) 2000 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL"). - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#15 $ - */ - -#ifndef _AIC7XXX_CAM_H -#define _AIC7XXX_CAM_H 1 - -#include - -#define CAM_BUS_WILDCARD ((u_int)~0) -#define CAM_TARGET_WILDCARD ((u_int)~0) -#define CAM_LUN_WILDCARD ((u_int)~0) - -/* CAM Status field values */ -typedef enum { - CAM_REQ_INPROG, /* CCB request is in progress */ - CAM_REQ_CMP, /* CCB request completed without error */ - CAM_REQ_ABORTED, /* CCB request aborted by the host */ - CAM_UA_ABORT, /* Unable to abort CCB request */ - CAM_REQ_CMP_ERR, /* CCB request completed with an error */ - CAM_BUSY, /* CAM subsytem is busy */ - CAM_REQ_INVALID, /* CCB request was invalid */ - CAM_PATH_INVALID, /* Supplied Path ID is invalid */ - CAM_SEL_TIMEOUT, /* Target Selection Timeout */ - CAM_CMD_TIMEOUT, /* Command timeout */ - CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */ - CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */ - CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */ - CAM_AUTOSENSE_FAIL, /* Autosense: request sense cmd fail */ - CAM_NO_HBA, /* No HBA Detected Error */ - CAM_DATA_RUN_ERR, /* Data Overrun error */ - CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */ - CAM_SEQUENCE_FAIL, /* Protocol Violation */ - CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */ - CAM_PROVIDE_FAIL, /* Unable to provide requested capability */ - CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */ - CAM_REQ_TERMIO, /* CCB request terminated by the host */ - CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */ - CAM_REQ_TOO_BIG, /* The request was too large for this host */ - CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */ - CAM_MSG_REJECT_REC, /* Message Reject Received */ - CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */ - CAM_RESRC_UNAVAIL, /* Resource Unavailable */ - /* - * This request should be requeued to preserve - * transaction ordering. This typically occurs - * when the SIM recognizes an error that should - * freeze the queue and must place additional - * requests for the target at the sim level - * back into the XPT queue. - */ - CAM_REQUEUE_REQ, - CAM_DEV_QFRZN = 0x40, - - CAM_STATUS_MASK = 0x3F -} cam_status; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -#define SCSI_DATA_READ 1 -#define SCSI_DATA_WRITE 2 -#define SCSI_DATA_NONE 3 -#endif - -/* - * Definitions for the asynchronous callback CCB fields. - */ -typedef enum { - AC_GETDEV_CHANGED = 0x800,/* Getdev info might have changed */ - AC_INQ_CHANGED = 0x400,/* Inquiry info might have changed */ - AC_TRANSFER_NEG = 0x200,/* New transfer settings in effect */ - AC_LOST_DEVICE = 0x100,/* A device went away */ - AC_FOUND_DEVICE = 0x080,/* A new device was found */ - AC_PATH_DEREGISTERED = 0x040,/* A path has de-registered */ - AC_PATH_REGISTERED = 0x020,/* A new path has been registered */ - AC_SENT_BDR = 0x010,/* A BDR message was sent to target */ - AC_SCSI_AEN = 0x008,/* A SCSI AEN has been received */ - AC_UNSOL_RESEL = 0x002,/* Unsolicited reselection occurred */ - AC_BUS_RESET = 0x001 /* A SCSI bus reset occurred */ -} ac_code; - -typedef enum { - CAM_DIR_IN = SCSI_DATA_READ, - CAM_DIR_OUT = SCSI_DATA_WRITE, - CAM_DIR_NONE = SCSI_DATA_NONE -} ccb_flags; - -#endif /* _AIC7XXX_CAM_H */ diff -urN linux-2.4.21/drivers/scsi/aic79xx/queue.h linux-2.4.22/drivers/scsi/aic79xx/queue.h --- linux-2.4.21/drivers/scsi/aic79xx/queue.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/queue.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,501 +0,0 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.38 2000/05/26 02:06:56 jake Exp $ - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * singly-linked tail queues, lists, tail queues, and circular queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * - * SLIST LIST STAILQ TAILQ CIRCLEQ - * _HEAD + + + + + - * _HEAD_INITIALIZER + + + + + - * _ENTRY + + + + + - * _INIT + + + + + - * _EMPTY + + + + + - * _FIRST + + + + + - * _NEXT + + + + + - * _PREV - - - + + - * _LAST - - + + + - * _FOREACH + + + + + - * _FOREACH_REVERSE - - - + + - * _INSERT_HEAD + + + + + - * _INSERT_BEFORE - + - + + - * _INSERT_AFTER + + + + + - * _INSERT_TAIL - - + + + - * _REMOVE_HEAD + - + - - - * _REMOVE + + + + + - * - */ - -/* - * Singly-linked List declarations. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ -} while (0) - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = \ - SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ - } \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ -} while (0) - -/* - * Singly-linked Tail queue declarations. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_FIRST(head) ((head)->stqh_first) - -#define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ -} while (0) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - STAILQ_LAST((head)) = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) - -#define STAILQ_LAST(head) (*(head)->stqh_last) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD(head, field); \ - } \ - else { \ - struct type *curelm = STAILQ_FIRST((head)); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - if ((STAILQ_NEXT(curelm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ - } \ -} while (0) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -/* - * List declarations. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ -} while (0) - -/* - * Tail queue declarations. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = NULL; \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - TAILQ_NEXT((elm), field) = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ -} while (0) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ -} while (0) - -/* - * Circular queue declarations. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { (void *)&(head), (void *)&(head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue functions. - */ -#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) - -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for ((var) = CIRCLEQ_FIRST((head)); \ - (var) != (void *)(head); \ - (var) = CIRCLEQ_NEXT((var), field)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for ((var) = CIRCLEQ_LAST((head)); \ - (var) != (void *)(head); \ - (var) = CIRCLEQ_PREV((var), field)) - -#define CIRCLEQ_INIT(head) do { \ - CIRCLEQ_FIRST((head)) = (void *)(head); \ - CIRCLEQ_LAST((head)) = (void *)(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \ - CIRCLEQ_PREV((elm), field) = (listelm); \ - if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \ - CIRCLEQ_LAST((head)) = (elm); \ - else \ - CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\ - CIRCLEQ_NEXT((listelm), field) = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = (listelm); \ - CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \ - if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \ - CIRCLEQ_FIRST((head)) = (elm); \ - else \ - CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\ - CIRCLEQ_PREV((listelm), field) = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \ - CIRCLEQ_PREV((elm), field) = (void *)(head); \ - if (CIRCLEQ_LAST((head)) == (void *)(head)) \ - CIRCLEQ_LAST((head)) = (elm); \ - else \ - CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \ - CIRCLEQ_FIRST((head)) = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = (void *)(head); \ - CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \ - if (CIRCLEQ_FIRST((head)) == (void *)(head)) \ - CIRCLEQ_FIRST((head)) = (elm); \ - else \ - CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \ - CIRCLEQ_LAST((head)) = (elm); \ -} while (0) - -#define CIRCLEQ_LAST(head) ((head)->cqh_last) - -#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) - -#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \ - CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \ - else \ - CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \ - CIRCLEQ_PREV((elm), field); \ - if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \ - CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \ - else \ - CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \ - CIRCLEQ_NEXT((elm), field); \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic79xx/scsi_iu.h linux-2.4.22/drivers/scsi/aic79xx/scsi_iu.h --- linux-2.4.21/drivers/scsi/aic79xx/scsi_iu.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/scsi_iu.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,39 +0,0 @@ -/* - * This file is in the public domain. - */ -#ifndef _SCSI_SCSI_IU_H -#define _SCSI_SCSI_IU_H 1 - -struct scsi_status_iu_header -{ - u_int8_t reserved[2]; - u_int8_t flags; -#define SIU_SNSVALID 0x2 -#define SIU_RSPVALID 0x1 - u_int8_t status; - u_int8_t sense_length[4]; - u_int8_t pkt_failures_length[4]; - u_int8_t pkt_failures[1]; -}; - -#define SIU_PKTFAIL_OFFSET(siu) 12 -#define SIU_PKTFAIL_CODE(siu) (scsi_4btoul((siu)->pkt_failures) & 0xFF) -#define SIU_PFC_NONE 0 -#define SIU_PFC_CIU_FIELDS_INVALID 2 -#define SIU_PFC_TMF_NOT_SUPPORTED 4 -#define SIU_PFC_TMF_FAILED 5 -#define SIU_PFC_INVALID_TYPE_CODE 6 -#define SIU_PFC_ILLEGAL_REQUEST 7 -#define SIU_SENSE_OFFSET(siu) \ - (12 + (((siu)->flags & SIU_RSPVALID) \ - ? scsi_4btoul((siu)->pkt_failures_length) \ - : 0)) - -#define SIU_TASKMGMT_NONE 0x00 -#define SIU_TASKMGMT_ABORT_TASK 0x01 -#define SIU_TASKMGMT_ABORT_TASK_SET 0x02 -#define SIU_TASKMGMT_CLEAR_TASK_SET 0x04 -#define SIU_TASKMGMT_LUN_RESET 0x08 -#define SIU_TASKMGMT_TARGET_RESET 0x20 -#define SIU_TASKMGMT_CLEAR_ACA 0x40 -#endif /*_SCSI_SCSI_IU_H*/ diff -urN linux-2.4.21/drivers/scsi/aic79xx/scsi_message.h linux-2.4.22/drivers/scsi/aic79xx/scsi_message.h --- linux-2.4.21/drivers/scsi/aic79xx/scsi_message.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic79xx/scsi_message.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,70 +0,0 @@ -/* - * This file is in the public domain. - * $FreeBSD: src/sys/cam/scsi/scsi_message.h,v 1.2 2000/05/01 20:21:29 peter Exp $ - */ - -/* Messages (1 byte) */ /* I/T (M)andatory or (O)ptional */ -#define MSG_CMDCOMPLETE 0x00 /* M/M */ -#define MSG_TASK_COMPLETE 0x00 /* M/M */ /* SPI3 Terminology */ -#define MSG_EXTENDED 0x01 /* O/O */ -#define MSG_SAVEDATAPOINTER 0x02 /* O/O */ -#define MSG_RESTOREPOINTERS 0x03 /* O/O */ -#define MSG_DISCONNECT 0x04 /* O/O */ -#define MSG_INITIATOR_DET_ERR 0x05 /* M/M */ -#define MSG_ABORT 0x06 /* O/M */ -#define MSG_ABORT_TASK_SET 0x06 /* O/M */ /* SPI3 Terminology */ -#define MSG_MESSAGE_REJECT 0x07 /* M/M */ -#define MSG_NOOP 0x08 /* M/M */ -#define MSG_PARITY_ERROR 0x09 /* M/M */ -#define MSG_LINK_CMD_COMPLETE 0x0a /* O/O */ -#define MSG_LINK_CMD_COMPLETEF 0x0b /* O/O */ -#define MSG_BUS_DEV_RESET 0x0c /* O/M */ -#define MSG_TARGET_RESET 0x0c /* O/M */ /* SPI3 Terminology */ -#define MSG_ABORT_TAG 0x0d /* O/O */ -#define MSG_ABORT_TASK 0x0d /* O/O */ /* SPI3 Terminology */ -#define MSG_CLEAR_QUEUE 0x0e /* O/O */ -#define MSG_CLEAR_TASK_SET 0x0e /* O/O */ /* SPI3 Terminology */ -#define MSG_INIT_RECOVERY 0x0f /* O/O */ /* Deprecated in SPI3 */ -#define MSG_REL_RECOVERY 0x10 /* O/O */ /* Deprecated in SPI3 */ -#define MSG_TERM_IO_PROC 0x11 /* O/O */ /* Deprecated in SPI3 */ -#define MSG_CLEAR_ACA 0x16 /* O/O */ /* SPI3 */ -#define MSG_LOGICAL_UNIT_RESET 0x17 /* O/O */ /* SPI3 */ -#define MSG_QAS_REQUEST 0x55 /* O/O */ /* SPI3 */ - -/* Messages (2 byte) */ -#define MSG_SIMPLE_Q_TAG 0x20 /* O/O */ -#define MSG_SIMPLE_TASK 0x20 /* O/O */ /* SPI3 Terminology */ -#define MSG_HEAD_OF_Q_TAG 0x21 /* O/O */ -#define MSG_HEAD_OF_QUEUE_TASK 0x21 /* O/O */ /* SPI3 Terminology */ -#define MSG_ORDERED_Q_TAG 0x22 /* O/O */ -#define MSG_ORDERED_TASK 0x22 /* O/O */ /* SPI3 Terminology */ -#define MSG_IGN_WIDE_RESIDUE 0x23 /* O/O */ -#define MSG_ACA_TASK 0x24 /* 0/0 */ /* SPI3 */ - -/* Identify message */ /* M/M */ -#define MSG_IDENTIFYFLAG 0x80 -#define MSG_IDENTIFY_DISCFLAG 0x40 -#define MSG_IDENTIFY(lun, disc) (((disc) ? 0xc0 : MSG_IDENTIFYFLAG) | (lun)) -#define MSG_ISIDENTIFY(m) ((m) & MSG_IDENTIFYFLAG) -#define MSG_IDENTIFY_LUNMASK 0x3F - -/* Extended messages (opcode and length) */ -#define MSG_EXT_SDTR 0x01 -#define MSG_EXT_SDTR_LEN 0x03 - -#define MSG_EXT_WDTR 0x03 -#define MSG_EXT_WDTR_LEN 0x02 -#define MSG_EXT_WDTR_BUS_8_BIT 0x00 -#define MSG_EXT_WDTR_BUS_16_BIT 0x01 -#define MSG_EXT_WDTR_BUS_32_BIT 0x02 /* Deprecated in SPI3 */ - -#define MSG_EXT_PPR 0x04 /* SPI3 */ -#define MSG_EXT_PPR_LEN 0x06 -#define MSG_EXT_PPR_PCOMP_EN 0x80 -#define MSG_EXT_PPR_RTI 0x40 -#define MSG_EXT_PPR_RD_STRM 0x20 -#define MSG_EXT_PPR_WR_FLOW 0x10 -#define MSG_EXT_PPR_HOLD_MCS 0x08 -#define MSG_EXT_PPR_QAS_REQ 0x04 -#define MSG_EXT_PPR_DT_REQ 0x02 -#define MSG_EXT_PPR_IU_REQ 0x01 diff -urN linux-2.4.21/drivers/scsi/aic7xxx/Config.in linux-2.4.22/drivers/scsi/aic7xxx/Config.in --- linux-2.4.21/drivers/scsi/aic7xxx/Config.in 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/Config.in 2003-08-25 04:44:42.000000000 -0700 @@ -2,12 +2,35 @@ dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then int ' Maximum number of TCQ commands per device' \ - CONFIG_AIC7XXX_CMDS_PER_DEVICE 253 + CONFIG_AIC7XXX_CMDS_PER_DEVICE 32 int ' Initial bus reset delay in milli-seconds' \ CONFIG_AIC7XXX_RESET_DELAY_MS 15000 bool ' Probe for EISA and VL AIC7XXX Adapters' \ CONFIG_AIC7XXX_PROBE_EISA_VL bool ' Build Adapter Firmware with Kernel Build' \ CONFIG_AIC7XXX_BUILD_FIRMWARE + bool ' Compile in Debugging Code' \ + CONFIG_AIC7XXX_DEBUG_ENABLE + int ' Debug code enable mask (2048 for all debugging)' \ + CONFIG_AIC7XXX_DEBUG_MASK 0 + bool ' Decode registers during diagnostics' \ + CONFIG_AIC7XXX_REG_PRETTY_PRINT fi fi +dep_tristate 'Adaptec AIC79xx support' CONFIG_SCSI_AIC79XX $CONFIG_SCSI +if [ "$CONFIG_SCSI_AIC79XX" != "n" ]; then + int ' Maximum number of TCQ commands per device' \ + CONFIG_AIC79XX_CMDS_PER_DEVICE 32 + int ' Initial bus reset delay in milli-seconds' \ + CONFIG_AIC79XX_RESET_DELAY_MS 15000 + bool ' Build Adapter Firmware with Kernel Build' \ + CONFIG_AIC79XX_BUILD_FIRMWARE + bool ' Enable Read Streaming for All Targets' \ + CONFIG_AIC79XX_ENABLE_RD_STRM + bool ' Compile in Debugging Code' \ + CONFIG_AIC79XX_DEBUG_ENABLE + int ' Debug code enable mask (16384 for all debugging)' \ + CONFIG_AIC79XX_DEBUG_MASK 0 + bool ' Decode registers during diagnostics' \ + CONFIG_AIC79XX_REG_PRETTY_PRINT +fi diff -urN linux-2.4.21/drivers/scsi/aic7xxx/Makefile linux-2.4.22/drivers/scsi/aic7xxx/Makefile --- linux-2.4.21/drivers/scsi/aic7xxx/Makefile 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -6,23 +6,46 @@ O_TARGET := aic7xxx_drv.o -list-multi := aic7xxx.o +list-multi := aic7xxx.o aic79xx.o obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o +endif +EXTRA_CFLAGS += -I$(TOPDIR)/drivers/scsi -Werror #EXTRA_CFLAGS += -g # Platform Specific Files -obj-aic7xxx = aic7xxx_osm.o aic7xxx_proc.o aic7770_osm.o -#PCI Specific Platform Files +obj-aic7xxx = aic7xxx_osm.o aic7xxx_proc.o + +# Core Files +obj-aic7xxx += aic7xxx_core.o aic7xxx_93cx6.o +ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y) +obj-aic7xxx += aic7xxx_reg_print.o +endif + +#EISA Specific Files +AIC7XXX_EISA_ARCH = $(filter i386 alpha,$(ARCH)) +ifneq ($(AIC7XXX_EISA_ARCH),) +obj-aic7xxx += aic7770.o +# Platform Specific EISA Files +obj-aic7xxx += aic7770_osm.o +endif + +#PCI Specific Files ifeq ($(CONFIG_PCI),y) +obj-aic7xxx += aic7xxx_pci.o +# Platform Specific PCI Files obj-aic7xxx += aic7xxx_osm_pci.o endif + +# Platform Specific U320 Files +obj-aic79xx = aic79xx_osm.o aic79xx_proc.o aic79xx_osm_pci.o # Core Files -obj-aic7xxx += aic7xxx_core.o aic7xxx_93cx6.o aic7770.o -#PCI Specific Core Files -ifeq ($(CONFIG_PCI),y) -obj-aic7xxx += aic7xxx_pci.o +obj-aic79xx += aic79xx_core.o aic79xx_pci.o +ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y) +obj-aic79xx += aic79xx_reg_print.o endif # Override our module desitnation @@ -35,9 +58,39 @@ aic7xxx.o: aic7xxx_seq.h aic7xxx_reg.h $(obj-aic7xxx) $(LD) $(LD_RFLAG) -r -o $@ $(obj-aic7xxx) +aic79xx_core.o: aic79xx_seq.h +$(obj-aic79xx): aic79xx_reg.h +aic79xx.o: aic79xx_seq.h aic79xx_reg.h $(obj-aic79xx) + $(LD) $(LD_RFLAG) -r -o $@ $(obj-aic79xx) + ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y) -aic7xxx_seq.h aic7xxx_reg.h: aic7xxx.seq aic7xxx.reg aicasm/aicasm - aicasm/aicasm -I. -r aic7xxx_reg.h -o aic7xxx_seq.h aic7xxx.seq +aic7xxx_gen = aic7xxx_seq.h aic7xxx_reg.h +ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y) +aic7xxx_gen += aic7xxx_reg_print.c +aic7xxx_asm_cmd = aicasm/aicasm -I. -r aic7xxx_reg.h \ + -p aic7xxx_reg_print.c -i aic7xxx_osm.h \ + -o aic7xxx_seq.h aic7xxx.seq +else +aic7xxx_asm_cmd = aicasm/aicasm -I. -r aic7xxx_reg.h \ + -o aic7xxx_seq.h aic7xxx.seq +endif +$(aic7xxx_gen): aic7xxx.seq aic7xxx.reg aicasm/aicasm + $(aic7xxx_asm_cmd) +endif + +ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y) +aic79xx_gen = aic79xx_seq.h aic79xx_reg.h +ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y) +aic79xx_gen += aic79xx_reg_print.c +aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \ + -p aic79xx_reg_print.c -i aic79xx_osm.h \ + -o aic79xx_seq.h aic79xx.seq +else +aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \ + -o aic79xx_seq.h aic79xx.seq +endif +$(aic79xx_gen): aic79xx.seq aic79xx.reg aicasm/aicasm + $(aic79xx_asm_cmd) endif aicasm/aicasm: aicasm/*.[chyl] diff -urN linux-2.4.21/drivers/scsi/aic7xxx/README.aic79xx linux-2.4.22/drivers/scsi/aic7xxx/README.aic79xx --- linux-2.4.21/drivers/scsi/aic7xxx/README.aic79xx 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/README.aic79xx 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,496 @@ +==================================================================== += Adaptec Ultra320 Family Manager Set v1.3.0 = += = += README for = += The Linux Operating System = +==================================================================== + +The following information is available in this file: + + 1. Supported Hardware + 2. Version History + 3. Command Line Options + 4. Additional Notes + 5. Contacting Adaptec + + +1. Supported Hardware + + The following Adaptec SCSI Host Adapters are supported by this + driver set. + + Ultra320 Adapters Description + ---------------------------------------------------------------- + Adaptec SCSI Card 39320 Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI Card (one external + 68-pin, two internal 68-pin) + Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI Card (two external VHDC + and one internal 68-pin) + Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI Card (two external VHDC + and one internal 68-pin) based on the + AIC-7902B ASIC + Adaptec SCSI Card 29320 Single Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI Card (one external + 68-pin, two internal 68-pin, one + internal 50-pin) + Adaptec SCSI Card 29320LP Single Channel 64-bit Low Profile + PCI-X 133MHz to Ultra320 SCSI Card + (One external VHDC, one internal + 68-pin) + AIC-7901A Single Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC + AIC-7902A4 Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC + AIC-7902B Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC + +2. Version History + 1.3.10 (June 3rd, 2003) + - Align the SCB_TAG field on a 16byte boundary. This avoids + SCB corruption on some PCI-33 busses. + - Correct non-zero luns on Rev B. hardware. + - Update for change in 2.5.X SCSI proc FS interface. + - When negotiation async via an 8bit WDTR message, send + an SDTR with an offset of 0 to be sure the target + knows we are async. This works around a firmware defect + in the Quantum Atlas 10K. + - Implement controller susupend and resume. + - Clear PCI error state during driver attach so that we + don't disable memory mapped I/O due to a stray write + by some other driver probe that occurred before we + claimed the controller. + + 1.3.9 (May 22nd, 2003) + - Fix compiler errors. + - Remove S/G splitting for segments that cross a 4GB boundary. + This is guaranteed not to happen in Linux. + - Add support for scsi_report_device_reset() found in + 2.5.X kernels. + - Add 7901B support. + - Simplify handling of the packtized lun Rev A workaround. + - Correct and simplify handling of the ignore wide residue + message. The previous code would fail to report a residual + if the transaction data length was even and we received + an IWR message. + + 1.3.8 (April 29th, 2003) + - Fix types accessed via the command line interface code. + - Perform a few firmware optimizations. + - Fix "Unexpected PKT busfree" errors. + - Use a sequencer interrupt to notify the host of + commands with bad status. We defer the notification + until there are no outstanding selections to ensure + that the host is interrupted for as short a time as + possible. + - Remove pre-2.2.X support. + - Add support for new 2.5.X interrupt API. + - Correct big-endian architecture support. + + 1.3.7 (April 16th, 2003) + - Use del_timer_sync() to ensure that no timeouts + are pending during controller shutdown. + - For pre-2.5.X kernels, carefully adjust our segment + list size to avoid SCSI malloc pool fragmentation. + - Cleanup channel display in our /proc output. + - Workaround duplicate device entries in the mid-layer + devlice list during add-single-device. + + 1.3.6 (March 28th, 2003) + - Correct a double free in the Domain Validation code. + - Correct a reference to free'ed memory during controller + shutdown. + - Reset the bus on an SE->LVD change. This is required + to reset our transcievers. + + 1.3.5 (March 24th, 2003) + - Fix a few register window mode bugs. + - Include read streaming in the PPR flags we display in + diagnostics as well as /proc. + - Add PCI hot plug support for 2.5.X kernels. + - Correct default precompensation value for RevA hardware. + - Fix Domain Validation thread shutdown. + - Add a firmware workaround to make the LED blink + brighter during packetized operations on the H2A4. + - Correct /proc display of user read streaming settings. + - Simplify driver locking by releasing the io_request_lock + upon driver entry from the mid-layer. + - Cleanup command line parsing and move much of this code + to aiclib. + + 1.3.4 (February 28th, 2003) + - Correct a race condition in our error recovery handler. + - Allow Test Unit Ready commands to take a full 5 seconds + during Domain Validation. + + 1.3.2 (February 19th, 2003) + - Correct a Rev B. regression due to the GEM318 + compatibility fix included in 1.3.1. + + 1.3.1 (February 11th, 2003) + - Add support for the 39320A. + - Improve recovery for certain PCI-X errors. + - Fix handling of LQ/DATA/LQ/DATA for the + same write transaction that can occur without + interveining training. + - Correct compatibility issues with the GEM318 + enclosure services device. + - Correct data corruption issue that occurred under + high tag depth write loads. + - Adapt to a change in the 2.5.X daemonize() API. + - Correct a "Missing case in ahd_handle_scsiint" panic. + + 1.3.0 (January 21st, 2003) + - Full regression testing for all U320 products completed. + - Added abort and target/lun reset error recovery handler and + interrupt coalessing. + + 1.2.0 (November 14th, 2002) + - Added support for Domain Validation + - Add support for the Hewlett-Packard version of the 39320D + and AIC-7902 adapters. + Support for previous adapters has not been fully tested and should + only be used at the customer's own risk. + + 1.1.1 (September 24th, 2002) + - Added support for the Linux 2.5.X kernel series + + 1.1.0 (September 17th, 2002) + - Added support for four additional SCSI products: + ASC-39320, ASC-29320, ASC-29320LP, AIC-7901. + + 1.0.0 (May 30th, 2002) + - Initial driver release. + + 2.1. Software/Hardware Features + - Support for the SPI-4 "Ultra320" standard: + - 320MB/s transfer rates + - Packetized SCSI Protocol at 160MB/s and 320MB/s + - Quick Arbitration Selection (QAS) + - Retained Training Information (Rev B. ASIC only) + - Interrupt Coalessing + - Initiator Mode (target mode not currently + supported) + - Support for the PCI-X standard up to 133MHz + - Support for the PCI v2.2 standard + - Domain Validation + + 2.2. Operating System Support: + - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1 + - SuSE Linux 7.3, 8.0, 8.1, Enterprise Server 7 + - only Intel and AMD x86 supported at this time + - >4GB memory configurations supported. + + Refer to the User's Guide for more details on this. + +3. Command Line Options + + WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS + INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE. + USE THEM WITH CAUTION. + + Edit the file "modules.conf" in the directory /etc and add/edit a + line containing 'options aic79xx aic79xx=[command[,command...]]' where + 'command' is one or more of the following: + ----------------------------------------------------------------- + Option: verbose + Definition: enable additional informative messages during + driver operation. + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: debug:[value] + Definition: Enables various levels of debugging information + The bit definitions for the debugging mask can + be found in drivers/scsi/aic7xxx/aic79xx.h under + the "Debug" heading. + Possible Values: 0x0000 = no debugging, 0xffff = full debugging + Default Value: 0x0000 + ----------------------------------------------------------------- + Option: no_reset + Definition: Do not reset the bus during the initial probe + phase + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: extended + Definition: Force extended translation on the controller + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: periodic_otag + Definition: Send an ordered tag periodically to prevent + tag starvation. Needed for some older devices + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: reverse_scan + Definition: Probe the scsi bus in reverse order, starting + with target 15 + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: global_tag_depth + Definition: Global tag depth for all targets on all busses. + This option sets the default tag depth which + may be selectively overridden vi the tag_info + option. + Possible Values: 1 - 253 + Default Value: 32 + ----------------------------------------------------------------- + Option: tag_info:{{value[,value...]}[,{value[,value...]}...]} + Definition: Set the per-target tagged queue depth on a + per controller basis. Both controllers and targets + may be ommitted indicating that they should retain + the default tag depth. + Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32} + On Controller 0 + specifies a tag depth of 16 for target 0 + specifies a tag depth of 64 for target 3 + specifies a tag depth of 8 for targets 4 and 5 + leaves target 6 at the default + specifies a tag depth of 32 for targets 1,2,7-15 + All other targets retain the default depth. + + tag_info:{{},{32,,32}} + On Controller 1 + specifies a tag depth of 32 for targets 0 and 2 + All other targets retain the default depth. + + Possible Values: 1 - 253 + Default Value: 32 + ----------------------------------------------------------------- + Option: rd_strm: {rd_strm_bitmask[,rd_strm_bitmask...]} + Definition: Enable read streaming on a per target basis. + The rd_strm_bitmask is a 16 bit hex value in which + each bit represents a target. Setting the target's + bit to '1' enables read streaming for that + target. Controllers may be ommitted indicating that + they should retain the default read streaming setting. + Example: rd_strm:{0x0041} + On Controller 0 + enables read streaming for targets 0 and 6. + disables read streaming for targets 1-5,7-15. + All other targets retain the default read + streaming setting. + Example: rd_strm:{0x0023,,0xFFFF} + On Controller 0 + enables read streaming for targets 1,2, and 5. + disables read streaming for targets 3,4,6-15. + On Controller 2 + enables read streaming for all targets. + All other targets retain the default read + streaming setting. + + Possible Values: 0x0000 - 0xffff + Default Value: 0x0000 + ----------------------------------------------------------------- + Option: dv: {value[,value...]} + Definition: Set Domain Validation Policy on a per-controller basis. + Controllers may be ommitted indicating that + they should retain the default read streaming setting. + Example: dv:{-1,0,,1,1,0} + On Controller 0 leave DV at its default setting. + On Controller 1 disable DV. + Skip configuration on Controller 2. + On Controllers 3 and 4 enable DV. + On Controller 5 disable DV. + + Possible Values: < 0 Use setting from serial EEPROM. + 0 Disable DV + > 0 Enable DV + Default Value: DV Serial EEPROM configuration setting. + ----------------------------------------------------------------- + Option: seltime:[value] + Definition: Specifies the selection timeout value + Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms + Default Value: 0 + ----------------------------------------------------------------- + + *** The following three options should only be changed at *** + *** the direction of a technical support representative. *** + + ----------------------------------------------------------------- + Option: precomp: {value[,value...]} + Definition: Set IO Cell precompensation value on a per-controller + basis. + Controllers may be ommitted indicating that + they should retain the default precompensation setting. + Example: precomp:{0x1} + On Controller 0 set precompensation to 1. + Example: precomp:{1,,7} + On Controller 0 set precompensation to 1. + On Controller 2 set precompensation to 8. + + Possible Values: 0 - 7 + Default Value: Varies based on chip revision + ----------------------------------------------------------------- + Option: slewrate: {value[,value...]} + Definition: Set IO Cell slew rate on a per-controller basis. + Controllers may be ommitted indicating that + they should retain the default slew rate setting. + Example: slewrate:{0x1} + On Controller 0 set slew rate to 1. + Example: slewrate :{1,,8} + On Controller 0 set slew rate to 1. + On Controller 2 set slew rate to 8. + + Possible Values: 0 - 15 + Default Value: Varies based on chip revision + ----------------------------------------------------------------- + Option: amplitude: {value[,value...]} + Definition: Set IO Cell signal amplitude on a per-controller basis. + Controllers may be ommitted indicating that + they should retain the default read streaming setting. + Example: amplitude:{0x1} + On Controller 0 set amplitude to 1. + Example: amplitude :{1,,7} + On Controller 0 set amplitude to 1. + On Controller 2 set amplitude to 7. + + Possible Values: 1 - 7 + Default Value: Varies based on chip revision + ----------------------------------------------------------------- + + Example: 'options aic79xx aic79xx=verbose,rd_strm:{{0x0041}}' + enables verbose output in the driver and turns read streaming on + for targets 0 and 6 of Controller 0. + +4. Additional Notes + + 4.1. Known/Unresolved or FYI Issues + + * Under SuSE Linux Enterprise 7, the driver may fail to operate + correctly due to a problem with PCI interrupt routing in the + Linux kernel. Please contact SuSE for an updated Linux + kernel. + + 4.2. Third-Party Compatibility Issues + + * Adaptec only supports Ultra320 hard drives running + the latest firmware available. Please check with + your hard drive manufacturer to ensure you have the + latest version. + + 4.3. Operating System or Technology Limitations + + * PCI Hot Plug is untested and may cause the operating system + to stop responding. + * Luns that are not numbered contiguously starting with 0 might not + be automatically probed during system startup. This is a limitation + of the OS. Please contact your Linux vendor for instructions on + manually probing non-contiguous luns. + * Using the Driver Update Disk version of this package during OS + installation under RedHat might result in two versions of this + driver being installed into the system module directory. This + might cause problems with the /sbin/mkinitrd program and/or + other RPM packages that try to install system modules. The best + way to correct this once the system is running is to install + the latest RPM package version of this driver, available from + http://www.adaptec.com. + + +5. Contacting Adaptec + + A Technical Support Identification (TSID) Number is required for + Adaptec technical support. + - The 12-digit TSID can be found on the white barcode-type label + included inside the box with your product. The TSID helps us + provide more efficient service by accurately identifying your + product and support status. + Support Options + - Search the Adaptec Support Knowledgebase (ASK) at + http://ask.adaptec.com for articles, troubleshooting tips, and + frequently asked questions for your product. + - For support via Email, submit your question to Adaptec's + Technical Support Specialists at http://ask.adaptec.com. + + North America + - Visit our Web site at http://www.adaptec.com. + - To speak with a Fibre Channel/RAID/External Storage Technical + Support Specialist, call 1-321-207-2000, + Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST. + (Not open on holidays) + - For Technical Support in all other technologies including + SCSI, call 1-408-934-7274, + Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST. + (Not open on holidays) + - For after hours support, call 1-800-416-8066 ($99/call, + $149/call on holidays) + - To order Adaptec products including software and cables, call + 1-800-442-7274 or 1-408-957-7274. You can also visit our + online store at http://www.adaptecstore.com + + Europe + - Visit our Web site at http://www.adaptec-europe.com. + - English and French: To speak with a Technical Support + Specialist, call one of the following numbers: + - English: +32-2-352-3470 + - French: +32-2-352-3460 + Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET + Friday, 10:00 to 12:30, 13:30 to 16:30 CET + - German: To speak with a Technical Support Specialist, + call +49-89-456-40660 + Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET + Friday, 09:30 to 12:30, 13:30 to 15:00 CET + - To order Adaptec products, including accessories and cables: + - UK: +0800-96-65-26 or fax +0800-731-02-95 + - Other European countries: +32-11-300-379 + + Australia and New Zealand + - Visit our Web site at http://www.adaptec.com.au. + - To speak with a Technical Support Specialist, call + +612-9416-0698 + Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT + (Not open on holidays) + + Japan + - To speak with a Technical Support Specialist, call + +81-3-5308-6120 + Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to + 6:00 p.m. TSC + + Hong Kong and China + - To speak with a Technical Support Specialist, call + +852-2869-7200 + Hours: Monday-Friday, 10:00 to 17:00. + - Fax Technical Support at +852-2869-7100. + + Singapore + - To speak with a Technical Support Specialist, call + +65-245-7470 + Hours: Monday-Friday, 10:00 to 17:00. + - Fax Technical Support at +852-2869-7100 + +------------------------------------------------------------------- +/* + * Copyright (c) 2003 Adaptec Inc. 691 S. Milpitas Blvd., Milpitas CA 95035 USA. + * All rights reserved. + * + * You are permitted to redistribute, use and modify this README file in whole + * or in part in conjunction with redistribution of software governed by the + * General Public License, provided that the following conditions are met: + * 1. Redistributions of README file must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 3. Modifications or new contributions must be attributed in a copyright + * notice identifying the author ("Contributor") and added below the + * original copyright notice. The copyright notice is for purposes of + * identifying contributors and should not be deemed as permission to alter + * the permissions given by Adaptec. + * + * THIS README FILE IS PROVIDED BY ADAPTEC AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ANY + * WARRANTIES OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * ADAPTEC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS README + * FILE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/README.aic7xxx linux-2.4.22/drivers/scsi/aic7xxx/README.aic7xxx --- linux-2.4.21/drivers/scsi/aic7xxx/README.aic7xxx 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/README.aic7xxx 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,414 @@ +==================================================================== += Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.28 = += README for = += The Linux Operating System = +==================================================================== + +The following information is available in this file: + + 1. Supported Hardware + 2. Version History + 3. Command Line Options + 4. Contacting Adaptec + +1. Supported Hardware + + The following Adaptec SCSI Chips and Host Adapters are supported by + the aic7xxx driver. + + Chip MIPS Host Bus MaxSync MaxWidth SCBs Notes + --------------------------------------------------------------- + aic7770 10 EISA/VL 10MHz 16Bit 4 1 + aic7850 10 PCI/32 10MHz 8Bit 3 + aic7855 10 PCI/32 10MHz 8Bit 3 + aic7856 10 PCI/32 10MHz 8Bit 3 + aic7859 10 PCI/32 20MHz 8Bit 3 + aic7860 10 PCI/32 20MHz 8Bit 3 + aic7870 10 PCI/32 10MHz 16Bit 16 + aic7880 10 PCI/32 20MHz 16Bit 16 + aic7890 20 PCI/32 40MHz 16Bit 16 3 4 5 6 7 8 + aic7891 20 PCI/64 40MHz 16Bit 16 3 4 5 6 7 8 + aic7892 20 PCI/64-66 80MHz 16Bit 16 3 4 5 6 7 8 + aic7895 15 PCI/32 20MHz 16Bit 16 2 3 4 5 + aic7895C 15 PCI/32 20MHz 16Bit 16 2 3 4 5 8 + aic7896 20 PCI/32 40MHz 16Bit 16 2 3 4 5 6 7 8 + aic7897 20 PCI/64 40MHz 16Bit 16 2 3 4 5 6 7 8 + aic7899 20 PCI/64-66 80MHz 16Bit 16 2 3 4 5 6 7 8 + + 1. Multiplexed Twin Channel Device - One controller servicing two + busses. + 2. Multi-function Twin Channel Device - Two controllers on one chip. + 3. Command Channel Secondary DMA Engine - Allows scatter gather list + and SCB prefetch. + 4. 64 Byte SCB Support - Allows disconnected, unttagged request table + for all possible target/lun combinations. + 5. Block Move Instruction Support - Doubles the speed of certain + sequencer operations. + 6. `Bayonet' style Scatter Gather Engine - Improves S/G prefetch + performance. + 7. Queuing Registers - Allows queuing of new transactions without + pausing the sequencer. + 8. Multiple Target IDs - Allows the controller to respond to selection + as a target on multiple SCSI IDs. + + Controller Chip Host-Bus Int-Connectors Ext-Connectors Notes + -------------------------------------------------------------------------- + AHA-274X[A] aic7770 EISA SE-50M SE-HD50F + AHA-274X[A]W aic7770 EISA SE-HD68F SE-HD68F + SE-50M + AHA-274X[A]T aic7770 EISA 2 X SE-50M SE-HD50F + AHA-2842 aic7770 VL SE-50M SE-HD50F + AHA-2940AU aic7860 PCI/32 SE-50M SE-HD50F + AVA-2902I aic7860 PCI/32 SE-50M + AVA-2902E aic7860 PCI/32 SE-50M + AVA-2906 aic7856 PCI/32 SE-50M SE-DB25F + APC-7850 aic7850 PCI/32 SE-50M 1 + AVA-2940 aic7860 PCI/32 SE-50M + AHA-2920B aic7860 PCI/32 SE-50M + AHA-2930B aic7860 PCI/32 SE-50M + AHA-2920C aic7856 PCI/32 SE-50M SE-HD50F + AHA-2930C aic7860 PCI/32 SE-50M + AHA-2930C aic7860 PCI/32 SE-50M + AHA-2910C aic7860 PCI/32 SE-50M + AHA-2915C aic7860 PCI/32 SE-50M + AHA-2940AU/CN aic7860 PCI/32 SE-50M SE-HD50F + AHA-2944W aic7870 PCI/32 HVD-HD68F HVD-HD68F + HVD-50M + AHA-3940W aic7870 PCI/32 2 X SE-HD68F SE-HD68F 2 + AHA-2940UW aic7880 PCI/32 SE-HD68F + SE-50M SE-HD68F + AHA-2940U aic7880 PCI/32 SE-50M SE-HD50F + AHA-2940D aic7880 PCI/32 + aHA-2940 A/T aic7880 PCI/32 + AHA-2940D A/T aic7880 PCI/32 + AHA-3940UW aic7880 PCI/32 2 X SE-HD68F SE-HD68F 3 + AHA-3940UWD aic7880 PCI/32 2 X SE-HD68F 2 X SE-VHD68F 3 + AHA-3940U aic7880 PCI/32 2 X SE-50M SE-HD50F 3 + AHA-2944UW aic7880 PCI/32 HVD-HD68F HVD-HD68F + HVD-50M + AHA-3944UWD aic7880 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F 3 + AHA-4944UW aic7880 PCI/32 + AHA-2930UW aic7880 PCI/32 + AHA-2940UW Pro aic7880 PCI/32 SE-HD68F SE-HD68F 4 + SE-50M + AHA-2940UW/CN aic7880 PCI/32 + AHA-2940UDual aic7895 PCI/32 + AHA-2940UWDual aic7895 PCI/32 + AHA-3940UWD aic7895 PCI/32 + AHA-3940AUW aic7895 PCI/32 + AHA-3940AUWD aic7895 PCI/32 + AHA-3940AU aic7895 PCI/32 + AHA-3944AUWD aic7895 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F + AHA-2940U2B aic7890 PCI/32 LVD-HD68F LVD-HD68F + AHA-2940U2 OEM aic7891 PCI/64 + AHA-2940U2W aic7890 PCI/32 LVD-HD68F LVD-HD68F + SE-HD68F + SE-50M + AHA-2950U2B aic7891 PCI/64 LVD-HD68F LVD-HD68F + AHA-2930U2 aic7890 PCI/32 LVD-HD68F SE-HD50F + SE-50M + AHA-3950U2B aic7897 PCI/64 + AHA-3950U2D aic7897 PCI/64 + AHA-29160 aic7892 PCI/64-66 + AHA-29160 CPQ aic7892 PCI/64-66 + AHA-29160N aic7892 PCI/32 LVD-HD68F SE-HD50F + SE-50M + AHA-29160LP aic7892 PCI/64-66 + AHA-19160 aic7892 PCI/64-66 + AHA-29150LP aic7892 PCI/64-66 + AHA-29130LP aic7892 PCI/64-66 + AHA-3960D aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F + LVD-50M + AHA-3960D CPQ aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F + LVD-50M + AHA-39160 aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F + LVD-50M + + 1. No BIOS support + 2. DEC21050 PCI-PCI bridge with multiple controller chips on secondary bus + 3. DEC2115X PCI-PCI bridge with multiple controller chips on secondary bus + 4. All three SCSI connectors may be used simultaneously without + SCSI "stub" effects. + +2. Version History + 6.2.36 (June 3rd, 2003) + - Correct code that disables PCI parity error checking. + - Correct and simplify handling of the ignore wide residue + message. The previous code would fail to report a residual + if the transaction data length was even and we received + an IWR message. + - Add support for the 2.5.X EISA framework. + - Update for change in 2.5.X SCSI proc FS interface. + - Correct Domain Validation command-line option parsing. + - When negotiation async via an 8bit WDTR message, send + an SDTR with an offset of 0 to be sure the target + knows we are async. This works around a firmware defect + in the Quantum Atlas 10K. + - Clear PCI error state during driver attach so that we + don't disable memory mapped I/O due to a stray write + by some other driver probe that occurred before we + claimed the controller. + + 6.2.35 (May 14th, 2003) + - Fix a few GCC 3.3 compiler warnings. + - Correct operation on EISA Twin Channel controller. + - Add support for 2.5.X's scsi_report_device_reset(). + + 6.2.34 (May 5th, 2003) + - Fix locking regression instroduced in 6.2.29 that + could cuase a lock order reversal between the io_request_lock + and our per-softc lock. This was only possible on RH9, + SuSE, and kernel.org 2.4.X kernels. + + 6.2.33 (April 30th, 2003) + - Dynamically disable PCI parity error reporting after + 10 errors are reported to the user. These errors are + the result of some other device issuing PCI transactions + with bad parity. Once the user has been informed of the + problem, continuing to report the errors just degrades + our performance. + + 6.2.32 (March 28th, 2003) + - Dynamically sized S/G lists to avoid SCSI malloc + pool fragmentation and SCSI mid-layer deadlock. + + 6.2.28 (January 20th, 2003) + - Domain Validation Fixes + - Add ability to disable PCI parity error checking. + - Enhanced Memory Mapped I/O probe + + 6.2.20 (November 7th, 2002) + - Added Domain Validation. + +3. Command Line Options + + WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS + INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE. + USE THEM WITH CAUTION. + + Edit the file "modules.conf" in the directory /etc and add/edit a + line containing 'options aic7xxx aic7xxx=[command[,command...]]' where + 'command' is one or more of the following: + ----------------------------------------------------------------- + Option: verbose + Definition: enable additional informative messages during + driver operation. + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: debug:[value] + Definition: Enables various levels of debugging information + Possible Values: 0x0000 = no debugging, 0xffff = full debugging + Default Value: 0x0000 + ----------------------------------------------------------------- + Option: no_probe + Option: probe_eisa_vl + Definition: Do not probe for EISA/VLB controllers. + This is a toggle. If the driver is compiled + to not probe EISA/VLB controllers by default, + specifying "no_probe" will enable this probing. + If the driver is compiled to probe EISA/VLB + controllers by default, specifying "no_probe" + will disable this probing. + Possible Values: This option is a toggle + Default Value: EISA/VLB probing is disabled by default. + ----------------------------------------------------------------- + Option: pci_parity + Definition: Toggles the detection of PCI parity errors. + On many motherboards with VIA chipsets, + PCI parity is not generated correctly on the + PCI bus. It is impossible for the hardware to + differentiate between these "spurious" parity + errors and real parity errors. The symptom of + this problem is a stream of the message: + "scsi0: Data Parity Error Detected during address or write data phase" + output by the driver. + Possible Values: This option is a toggle + Default Value: PCI Parity Error reporting is disabled + ----------------------------------------------------------------- + Option: no_reset + Definition: Do not reset the bus during the initial probe + phase + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: extended + Definition: Force extended translation on the controller + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: periodic_otag + Definition: Send an ordered tag periodically to prevent + tag starvation. Needed for some older devices + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: reverse_scan + Definition: Probe the scsi bus in reverse order, starting + with target 15 + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: global_tag_depth:[value] + Definition: Global tag depth for all targets on all busses. + This option sets the default tag depth which + may be selectively overridden vi the tag_info + option. + Possible Values: 1 - 253 + Default Value: 32 + ----------------------------------------------------------------- + Option: tag_info:{{value[,value...]}[,{value[,value...]}...]} + Definition: Set the per-target tagged queue depth on a + per controller basis. Both controllers and targets + may be ommitted indicating that they should retain + the default tag depth. + Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32} + On Controller 0 + specifies a tag depth of 16 for target 0 + specifies a tag depth of 64 for target 3 + specifies a tag depth of 8 for targets 4 and 5 + leaves target 6 at the default + specifies a tag depth of 32 for targets 1,2,7-15 + All other targets retain the default depth. + + tag_info:{{},{32,,32}} + On Controller 1 + specifies a tag depth of 32 for targets 0 and 2 + All other targets retain the default depth. + + Possible Values: 1 - 253 + Default Value: 32 + ----------------------------------------------------------------- + Option: seltime:[value] + Definition: Specifies the selection timeout value + Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms + Default Value: 0 + ----------------------------------------------------------------- + Option: dv: {value[,value...]} + Definition: Set Domain Validation Policy on a per-controller basis. + Controllers may be ommitted indicating that + they should retain the default read streaming setting. + Example: dv:{-1,0,,1,1,0} + On Controller 0 leave DV at its default setting. + On Controller 1 disable DV. + Skip configuration on Controller 2. + On Controllers 3 and 4 enable DV. + On Controller 5 disable DV. + + Possible Values: < 0 Use setting from serial EEPROM. + 0 Disable DV + > 0 Enable DV + + Default Value: SCSI-Select setting on controllers with a SCSI Select + option for DV. Otherwise, on for controllers supporting + U160 speeds and off for all other controller types. + ----------------------------------------------------------------- + + Example: + 'options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1" + enables verbose logging, Disable EISA/VLB probing, + and set tag depth on Controller 1/Target 2 to 10 tags. + +3. Contacting Adaptec + + A Technical Support Identification (TSID) Number is required for + Adaptec technical support. + - The 12-digit TSID can be found on the white barcode-type label + included inside the box with your product. The TSID helps us + provide more efficient service by accurately identifying your + product and support status. + Support Options + - Search the Adaptec Support Knowledgebase (ASK) at + http://ask.adaptec.com for articles, troubleshooting tips, and + frequently asked questions for your product. + - For support via Email, submit your question to Adaptec's + Technical Support Specialists at http://ask.adaptec.com. + + North America + - Visit our Web site at http://www.adaptec.com. + - To speak with a Fibre Channel/RAID/External Storage Technical + Support Specialist, call 1-321-207-2000, + Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST. + (Not open on holidays) + - For Technical Support in all other technologies including + SCSI, call 1-408-934-7274, + Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST. + (Not open on holidays) + - For after hours support, call 1-800-416-8066 ($99/call, + $149/call on holidays) + - To order Adaptec products including software and cables, call + 1-800-442-7274 or 1-408-957-7274. You can also visit our + online store at http://www.adaptecstore.com + + Europe + - Visit our Web site at http://www.adaptec-europe.com. + - English and French: To speak with a Technical Support + Specialist, call one of the following numbers: + - English: +32-2-352-3470 + - French: +32-2-352-3460 + Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET + Friday, 10:00 to 12:30, 13:30 to 16:30 CET + - German: To speak with a Technical Support Specialist, + call +49-89-456-40660 + Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET + Friday, 09:30 to 12:30, 13:30 to 15:00 CET + - To order Adaptec products, including accessories and cables: + - UK: +0800-96-65-26 or fax +0800-731-02-95 + - Other European countries: +32-11-300-379 + + Australia and New Zealand + - Visit our Web site at http://www.adaptec.com.au. + - To speak with a Technical Support Specialist, call + +612-9416-0698 + Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT + (Not open on holidays) + + Japan + - To speak with a Technical Support Specialist, call + +81-3-5308-6120 + Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to + 6:00 p.m. TSC + + Hong Kong and China + - To speak with a Technical Support Specialist, call + +852-2869-7200 + Hours: Monday-Friday, 10:00 to 17:00. + - Fax Technical Support at +852-2869-7100. + + Singapore + - To speak with a Technical Support Specialist, call + +65-245-7470 + Hours: Monday-Friday, 10:00 to 17:00. + - Fax Technical Support at +852-2869-7100 + +------------------------------------------------------------------- +/* + * Copyright (c) 2003 Adaptec Inc. 691 S. Milpitas Blvd., Milpitas CA 95035 USA. + * All rights reserved. + * + * You are permitted to redistribute, use and modify this README file in whole + * or in part in conjunction with redistribution of software governed by the + * General Public License, provided that the following conditions are met: + * 1. Redistributions of README file must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 3. Modifications or new contributions must be attributed in a copyright + * notice identifying the author ("Contributor") and added below the + * original copyright notice. The copyright notice is for purposes of + * identifying contributors and should not be deemed as permission to alter + * the permissions given by Adaptec. + * + * THIS README FILE IS PROVIDED BY ADAPTEC AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ANY + * WARRANTIES OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * ADAPTEC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS README + * FILE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7770.c linux-2.4.22/drivers/scsi/aic7xxx/aic7770.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7770.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7770.c 2003-08-25 04:44:42.000000000 -0700 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#21 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#32 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1 2000/09/16 20:02:27 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -56,14 +56,18 @@ #define ID_AHA_274x 0x04907771 #define ID_AHA_284xB 0x04907756 /* BIOS enabled */ #define ID_AHA_284x 0x04907757 /* BIOS disabled*/ +#define ID_OLV_274x 0x04907782 /* Olivetti OEM */ +#define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ +static int aic7770_chip_init(struct ahc_softc *ahc); +static int aic7770_suspend(struct ahc_softc *ahc); +static int aic7770_resume(struct ahc_softc *ahc); static int aha2840_load_seeprom(struct ahc_softc *ahc); static ahc_device_setup_t ahc_aic7770_VL_setup; static ahc_device_setup_t ahc_aic7770_EISA_setup;; static ahc_device_setup_t ahc_aic7770_setup; - -struct aic7770_identity aic7770_ident_table [] = +struct aic7770_identity aic7770_ident_table[] = { { ID_AHA_274x, @@ -77,6 +81,24 @@ "Adaptec 284X SCSI adapter", ahc_aic7770_VL_setup }, + { + ID_AHA_284x, + 0xFFFFFFFE, + "Adaptec 284X SCSI adapter (BIOS Disabled)", + ahc_aic7770_VL_setup + }, + { + ID_OLV_274x, + 0xFFFFFFFF, + "Adaptec (Olivetti OEM) 274X SCSI adapter", + ahc_aic7770_EISA_setup + }, + { + ID_OLV_274xD, + 0xFFFFFFFF, + "Adaptec (Olivetti OEM) 274X Differential SCSI adapter", + ahc_aic7770_EISA_setup + }, /* Generic chip probes for devices we don't know 'exactly' */ { ID_AIC7770, @@ -105,7 +127,6 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) { u_long l; - u_long s; int error; int have_seeprom; u_int hostconf; @@ -131,8 +152,14 @@ ahc->description = entry->name; error = ahc_softc_init(ahc); + if (error != 0) + return (error); - error = ahc_reset(ahc); + ahc->bus_chip_init = aic7770_chip_init; + ahc->bus_suspend = aic7770_suspend; + ahc->bus_resume = aic7770_resume; + + error = ahc_reset(ahc, /*reinit*/FALSE); if (error != 0) return (error); @@ -213,6 +240,9 @@ ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH); ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF); + ahc->bus_softc.aic7770_softc.busspd = hostconf & DFTHRSH; + ahc->bus_softc.aic7770_softc.bustime = (hostconf << 2) & BOFF; + /* * Generic aic7xxx initialization. */ @@ -235,18 +265,33 @@ */ ahc_outb(ahc, BCTL, ENABLE); - /* - * Allow interrupts. - */ - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, TRUE); - ahc_unlock(ahc, &s); - ahc_list_unlock(&l); return (0); } +static int +aic7770_chip_init(struct ahc_softc *ahc) +{ + ahc_outb(ahc, BUSSPD, ahc->bus_softc.aic7770_softc.busspd); + ahc_outb(ahc, BUSTIME, ahc->bus_softc.aic7770_softc.bustime); + ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); + ahc_outb(ahc, BCTL, ENABLE); + return (ahc_chip_init(ahc)); +} + +static int +aic7770_suspend(struct ahc_softc *ahc) +{ + return (ahc_suspend(ahc)); +} + +static int +aic7770_resume(struct ahc_softc *ahc) +{ + return (ahc_resume(ahc)); +} + /* * Read the 284x SEEPROM. */ @@ -365,5 +410,6 @@ ahc->features = AHC_AIC7770_FE; ahc->bugs |= AHC_TMODE_WIDEODD_BUG; ahc->flags |= AHC_PAGESCBS; + ahc->instruction_ram_size = 448; return (0); } diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7770_osm.c linux-2.4.22/drivers/scsi/aic7xxx/aic7770_osm.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7770_osm.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7770_osm.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,7 +1,7 @@ /* * Linux driver attachment glue for aic7770 based controllers. * - * Copyright (c) 2000-2001 Adaptec Inc. + * Copyright (c) 2000-2003 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,33 +36,102 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#11 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#14 $ */ #include "aic7xxx_osm.h" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#include +#include + +#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */ +#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */ +#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@') /* Bits 16-20 */ +#define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */ +#define EISA_REVISION_ID(ID) (uint8_t)(ID & 0x0F) /* Bits 0-3 */ + +static int aic7770_eisa_dev_probe(struct device *dev); +static int aic7770_eisa_dev_remove(struct device *dev); +static struct eisa_driver aic7770_driver = { + .driver = { + .name = "aic7xxx", + .probe = aic7770_eisa_dev_probe, + .remove = aic7770_eisa_dev_remove, + } +}; + +typedef struct device *aic7770_dev_t; +#else #define MINSLOT 1 #define NUMSLOTS 16 #define IDOFFSET 0x80 -int -aic7770_linux_probe(Scsi_Host_Template *template) +typedef void *aic7770_dev_t; +#endif + +static int aic7770_linux_config(struct aic7770_identity *entry, + aic7770_dev_t dev, u_int eisaBase); + +void +ahc_linux_eisa_init(void) { -#if defined(__i386__) || defined(__alpha__) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + struct eisa_device_id *eid; + struct aic7770_identity *id; + int i; + + if (aic7xxx_probe_eisa_vl == 0) + return; + + /* + * Linux requires the EISA IDs to be specified in + * the EISA ID string format. Perform the conversion + * and setup a table with a NUL terminal entry. + */ + aic7770_driver.id_table = malloc(sizeof(struct eisa_device_id) * + (ahc_num_aic7770_devs + 1), + M_DEVBUF, M_NOWAIT); + if (aic7770_driver.id_table == NULL) + return; + + for (eid = (struct eisa_device_id *)aic7770_driver.id_table, + id = aic7770_ident_table, i = 0; + i < ahc_num_aic7770_devs; eid++, id++, i++) { + + sprintf(eid->sig, "%c%c%c%03X%01X", + EISA_MFCTR_CHAR0(id->full_id), + EISA_MFCTR_CHAR1(id->full_id), + EISA_MFCTR_CHAR2(id->full_id), + EISA_PRODUCT_ID(id->full_id), + EISA_REVISION_ID(id->full_id)); + eid->driver_data = i; + } + eid->sig[0] = 0; + + eisa_driver_register(&aic7770_driver); +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */ struct aic7770_identity *entry; - struct ahc_softc *ahc; - int i, slot; - int eisaBase; - int found; + u_int slot; + u_int eisaBase; + u_int i; + + if (aic7xxx_probe_eisa_vl == 0) + return; eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET; - found = 0; for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) { uint32_t eisa_id; size_t id_size; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0) continue; + request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx"); +#else + if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0) + continue; +#endif eisa_id = 0; id_size = sizeof(eisa_id); @@ -72,49 +141,69 @@ eisa_id |= inb(eisaBase + IDOFFSET + i) << ((id_size-i-1) * 8); } + release_region(eisaBase, AHC_EISA_IOSIZE); if (eisa_id & 0x80000000) continue; /* no EISA card in slot */ entry = aic7770_find_device(eisa_id); - if (entry != NULL) { - char buf[80]; - char *name; - int error; - - /* - * Allocate a softc for this card and - * set it up for attachment by our - * common detect routine. - */ - sprintf(buf, "ahc_eisa:%d", slot); - name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); - if (name == NULL) - break; - strcpy(name, buf); - ahc = ahc_alloc(template, name); - if (ahc == NULL) { - /* - * If we can't allocate this one, - * chances are we won't be able to - * allocate future card structures. - */ - break; - } - error = aic7770_config(ahc, entry, eisaBase); - if (error != 0) { - ahc->bsh.ioport = 0; - ahc_free(ahc); - continue; - } - found++; - } + if (entry != NULL) + aic7770_linux_config(entry, NULL, eisaBase); + } +#endif +} + +void +ahc_linux_eisa_exit(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (aic7xxx_probe_eisa_vl == 0) + return; + + if (aic7770_driver.id_table != NULL) { + eisa_driver_unregister(&aic7770_driver); + free(aic7770_driver.id_table, M_DEVBUF); } - return (found); -#else - return (0); #endif } +static int +aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev, + u_int eisaBase) +{ + struct ahc_softc *ahc; + char buf[80]; + char *name; + int error; + + /* + * Allocate a softc for this card and + * set it up for attachment by our + * common detect routine. + */ + sprintf(buf, "ahc_eisa:%d", eisaBase >> 12); + name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); + if (name == NULL) + return (ENOMEM); + strcpy(name, buf); + ahc = ahc_alloc(&aic7xxx_driver_template, name); + if (ahc == NULL) { + free(name, M_DEVBUF); + return (ENOMEM); + } + error = aic7770_config(ahc, entry, eisaBase); + if (error != 0) { + ahc->bsh.ioport = 0; + ahc_free(ahc); + return (error); + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + dev->driver_data = (void *)ahc; + if (aic7xxx_detect_complete) + error = ahc_linux_register_host(ahc, &aic7xxx_driver_template); +#endif + return (error); +} + int aic7770_map_registers(struct ahc_softc *ahc, u_int port) { @@ -122,6 +211,8 @@ * Lock out other contenders for our i/o space. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + if (check_region(port, AHC_EISA_IOSIZE) != 0) + return (ENOMEM); request_region(port, AHC_EISA_IOSIZE, "aic7xxx"); #else if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0) @@ -148,3 +239,41 @@ return (-error); } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int +aic7770_eisa_dev_probe(struct device *dev) +{ + struct eisa_device *edev; + + edev = to_eisa_device(dev); + return (aic7770_linux_config(aic7770_ident_table + edev->id.driver_data, + dev, edev->base_addr+AHC_EISA_SLOT_OFFSET)); +} + +static int +aic7770_eisa_dev_remove(struct device *dev) +{ + struct ahc_softc *ahc; + u_long l; + + /* + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. + */ + ahc_list_lock(&l); + ahc = ahc_find_softc((struct ahc_softc *)dev->driver_data); + if (ahc != NULL) { + u_long s; + + ahc_lock(ahc, &s); + ahc_intr_enable(ahc, FALSE); + ahc_unlock(ahc, &s); + ahc_free(ahc); + } + ahc_list_unlock(&l); + + return (0); +} +#endif diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx.h linux-2.4.22/drivers/scsi/aic7xxx/aic79xx.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1534 @@ +/* + * Core definitions and data structures shareable across OS platforms. + * + * Copyright (c) 1994-2002 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#92 $ + * + * $FreeBSD$ + */ + +#ifndef _AIC79XX_H_ +#define _AIC79XX_H_ + +/* Register Definitions */ +#include "aic79xx_reg.h" + +/************************* Forward Declarations *******************************/ +struct ahd_platform_data; +struct scb_platform_data; + +/****************************** Useful Macros *********************************/ +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) + +#define ALL_CHANNELS '\0' +#define ALL_TARGETS_MASK 0xFFFF +#define INITIATOR_WILDCARD (~0) +#define SCB_LIST_NULL 0xFF00 +#define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL)) +#define QOUTFIFO_ENTRY_VALID 0x8000 +#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000)) +#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL) + +#define SCSIID_TARGET(ahd, scsiid) \ + (((scsiid) & TID) >> TID_SHIFT) +#define SCSIID_OUR_ID(scsiid) \ + ((scsiid) & OID) +#define SCSIID_CHANNEL(ahd, scsiid) ('A') +#define SCB_IS_SCSIBUS_B(ahd, scb) (0) +#define SCB_GET_OUR_ID(scb) \ + SCSIID_OUR_ID((scb)->hscb->scsiid) +#define SCB_GET_TARGET(ahd, scb) \ + SCSIID_TARGET((ahd), (scb)->hscb->scsiid) +#define SCB_GET_CHANNEL(ahd, scb) \ + SCSIID_CHANNEL(ahd, (scb)->hscb->scsiid) +#define SCB_GET_LUN(scb) \ + ((scb)->hscb->lun) +#define SCB_GET_TARGET_OFFSET(ahd, scb) \ + SCB_GET_TARGET(ahd, scb) +#define SCB_GET_TARGET_MASK(ahd, scb) \ + (0x01 << (SCB_GET_TARGET_OFFSET(ahd, scb))) +#ifdef AHD_DEBUG +#define SCB_IS_SILENT(scb) \ + ((ahd_debug & AHD_SHOW_MASKED_ERRORS) == 0 \ + && (((scb)->flags & SCB_SILENT) != 0)) +#else +#define SCB_IS_SILENT(scb) \ + (((scb)->flags & SCB_SILENT) != 0) +#endif +/* + * TCLs have the following format: TTTTLLLLLLLL + */ +#define TCL_TARGET_OFFSET(tcl) \ + ((((tcl) >> 4) & TID) >> 4) +#define TCL_LUN(tcl) \ + (tcl & (AHD_NUM_LUNS - 1)) +#define BUILD_TCL(scsiid, lun) \ + ((lun) | (((scsiid) & TID) << 4)) +#define BUILD_TCL_RAW(target, channel, lun) \ + ((lun) | ((target) << 8)) + +#define SCB_GET_TAG(scb) \ + ahd_le16toh(scb->hscb->tag) + +#ifndef AHD_TARGET_MODE +#undef AHD_TMODE_ENABLE +#define AHD_TMODE_ENABLE 0 +#endif + +#define AHD_BUILD_COL_IDX(target, lun) \ + (((lun) << 4) | target) + +#define AHD_GET_SCB_COL_IDX(ahd, scb) \ + ((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb)) + +#define AHD_SET_SCB_COL_IDX(scb, col_idx) \ +do { \ + (scb)->hscb->scsiid = ((col_idx) << TID_SHIFT) & TID; \ + (scb)->hscb->lun = ((col_idx) >> 4) & (AHD_NUM_LUNS_NONPKT-1); \ +} while (0) + +#define AHD_COPY_SCB_COL_IDX(dst, src) \ +do { \ + dst->hscb->scsiid = src->hscb->scsiid; \ + dst->hscb->lun = src->hscb->lun; \ +} while (0) + +#define AHD_NEVER_COL_IDX 0xFFFF + +/**************************** Driver Constants ********************************/ +/* + * The maximum number of supported targets. + */ +#define AHD_NUM_TARGETS 16 + +/* + * The maximum number of supported luns. + * The identify message only supports 64 luns in non-packetized transfers. + * You can have 2^64 luns when information unit transfers are enabled, + * but until we see a need to support that many, we support 256. + */ +#define AHD_NUM_LUNS_NONPKT 64 +#define AHD_NUM_LUNS 256 + +/* + * The maximum transfer per S/G segment. + */ +#define AHD_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */ + +/* + * The maximum amount of SCB storage in hardware on a controller. + * This value represents an upper bound. Due to software design, + * we may not be able to use this number. + */ +#define AHD_SCB_MAX 512 + +/* + * The maximum number of concurrent transactions supported per driver instance. + * Sequencer Control Blocks (SCBs) store per-transaction information. + */ +#define AHD_MAX_QUEUE AHD_SCB_MAX + +/* + * Define the size of our QIN and QOUT FIFOs. They must be a power of 2 + * in size and accommodate as many transactions as can be queued concurrently. + */ +#define AHD_QIN_SIZE AHD_MAX_QUEUE +#define AHD_QOUT_SIZE AHD_MAX_QUEUE + +#define AHD_QIN_WRAP(x) ((x) & (AHD_QIN_SIZE-1)) +/* + * The maximum amount of SCB storage we allocate in host memory. + */ +#define AHD_SCB_MAX_ALLOC AHD_MAX_QUEUE + +/* + * Ring Buffer of incoming target commands. + * We allocate 256 to simplify the logic in the sequencer + * by using the natural wrap point of an 8bit counter. + */ +#define AHD_TMODE_CMDS 256 + +/* Reset line assertion time in us */ +#define AHD_BUSRESET_DELAY 25 + +/******************* Chip Characteristics/Operating Settings *****************/ +/* + * Chip Type + * The chip order is from least sophisticated to most sophisticated. + */ +typedef enum { + AHD_NONE = 0x0000, + AHD_CHIPID_MASK = 0x00FF, + AHD_AIC7901 = 0x0001, + AHD_AIC7902 = 0x0002, + AHD_AIC7901A = 0x0003, + AHD_PCI = 0x0100, /* Bus type PCI */ + AHD_PCIX = 0x0200, /* Bus type PCIX */ + AHD_BUS_MASK = 0x0F00 +} ahd_chip; + +/* + * Features available in each chip type. + */ +typedef enum { + AHD_FENONE = 0x00000, + AHD_WIDE = 0x00001,/* Wide Channel */ + AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */ + AHD_TARGETMODE = 0x01000,/* Has tested target mode support */ + AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */ + AHD_RTI = 0x04000,/* Retained Training Support */ + AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */ + AHD_NEW_DFCNTRL_OPTS = 0x10000,/* SCSIENWRDIS bit */ + AHD_REMOVABLE = 0x00000,/* Hot-Swap supported - None so far*/ + AHD_AIC7901_FE = AHD_FENONE, + AHD_AIC7902_FE = AHD_MULTI_FUNC +} ahd_feature; + +/* + * Bugs in the silicon that we work around in software. + */ +typedef enum { + AHD_BUGNONE = 0x0000, + /* + * Rev A hardware fails to update LAST/CURR/NEXTSCB + * correctly in certain packetized selection cases. + */ + AHD_SENT_SCB_UPDATE_BUG = 0x0001, + /* The wrong SCB is accessed to check the abort pending bit. */ + AHD_ABORT_LQI_BUG = 0x0002, + /* Packetized bitbucket crosses packet boundaries. */ + AHD_PKT_BITBUCKET_BUG = 0x0004, + /* The selection timer runs twice as long as its setting. */ + AHD_LONG_SETIMO_BUG = 0x0008, + /* The Non-LQ CRC error status is delayed until phase change. */ + AHD_NLQICRC_DELAYED_BUG = 0x0010, + /* The chip must be reset for all outgoing bus resets. */ + AHD_SCSIRST_BUG = 0x0020, + /* Some PCIX fields must be saved and restored across chip reset. */ + AHD_PCIX_CHIPRST_BUG = 0x0040, + /* MMAPIO is not functional in PCI-X mode. */ + AHD_PCIX_MMAPIO_BUG = 0x0080, + /* Reads to SCBRAM fail to reset the discard timer. */ + AHD_PCIX_SCBRAM_RD_BUG = 0x0100, + /* Bug workarounds that can be disabled on non-PCIX busses. */ + AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG + | AHD_PCIX_MMAPIO_BUG + | AHD_PCIX_SCBRAM_RD_BUG, + /* + * LQOSTOP0 status set even for forced selections with ATN + * to perform non-packetized message delivery. + */ + AHD_LQO_ATNO_BUG = 0x0200, + /* FIFO auto-flush does not always trigger. */ + AHD_AUTOFLUSH_BUG = 0x0400, + /* The CLRLQO registers are not self-clearing. */ + AHD_CLRLQO_AUTOCLR_BUG = 0x0800, + /* The PACKETIZED status bit refers to the previous connection. */ + AHD_PKTIZED_STATUS_BUG = 0x1000, + /* "Short Luns" are not placed into outgoing LQ packets correctly. */ + AHD_PKT_LUN_BUG = 0x2000, + /* + * Only the FIFO allocated to the non-packetized connection may + * be in use during a non-packetzied connection. + */ + AHD_NONPACKFIFO_BUG = 0x4000, + /* + * Writing to a DFF SCBPTR register may fail if concurent with + * a hardware write to the other DFF SCBPTR register. This is + * not currently a concern in our sequencer since all chips with + * this bug have the AHD_NONPACKFIFO_BUG and all writes of concern + * occur in non-packetized connections. + */ + AHD_MDFF_WSCBPTR_BUG = 0x8000, + /* SGHADDR updates are slow. */ + AHD_REG_SLOW_SETTLE_BUG = 0x10000, + /* + * Changing the MODE_PTR coincident with an interrupt that + * switches to a different mode will cause the interrupt to + * be in the mode written outside of interrupt context. + */ + AHD_SET_MODE_BUG = 0x20000, + /* Non-packetized busfree revision does not work. */ + AHD_BUSFREEREV_BUG = 0x40000, + /* + * Paced transfers are indicated with a non-standard PPR + * option bit in the neg table, 160MHz is indicated by + * sync factor 0x7, and the offset if off by a factor of 2. + */ + AHD_PACED_NEGTABLE_BUG = 0x80000, + /* LQOOVERRUN false positives. */ + AHD_LQOOVERRUN_BUG = 0x100000, + /* + * Controller write to INTSTAT will lose to a host + * write to CLRINT. + */ + AHD_INTCOLLISION_BUG = 0x200000, + /* + * The GEM318 violates the SCSI spec by not waiting + * the mandated bus settle delay between phase changes + * in some situations. Some aic79xx chip revs. are more + * strict in this regard and will treat REQ assertions + * that fall within the bus settle delay window as + * glitches. This flag tells the firmware to tolerate + * early REQ assertions. + */ + AHD_EARLY_REQ_BUG = 0x400000, + /* + * The LED does not stay on long enough in packetized modes. + */ + AHD_FAINT_LED_BUG = 0x800000 +} ahd_bug; + +/* + * Configuration specific settings. + * The driver determines these settings by probing the + * chip/controller's configuration. + */ +typedef enum { + AHD_FNONE = 0x00000, + AHD_BOOT_CHANNEL = 0x00001,/* We were set as the boot channel. */ + AHD_USEDEFAULTS = 0x00004,/* + * For cards without an seeprom + * or a BIOS to initialize the chip's + * SRAM, we use the default target + * settings. + */ + AHD_SEQUENCER_DEBUG = 0x00008, + AHD_RESET_BUS_A = 0x00010, + AHD_EXTENDED_TRANS_A = 0x00020, + AHD_TERM_ENB_A = 0x00040, + AHD_SPCHK_ENB_A = 0x00080, + AHD_STPWLEVEL_A = 0x00100, + AHD_INITIATORROLE = 0x00200,/* + * Allow initiator operations on + * this controller. + */ + AHD_TARGETROLE = 0x00400,/* + * Allow target operations on this + * controller. + */ + AHD_RESOURCE_SHORTAGE = 0x00800, + AHD_TQINFIFO_BLOCKED = 0x01000,/* Blocked waiting for ATIOs */ + AHD_INT50_SPEEDFLEX = 0x02000,/* + * Internal 50pin connector + * sits behind an aic3860 + */ + AHD_BIOS_ENABLED = 0x04000, + AHD_ALL_INTERRUPTS = 0x08000, + AHD_39BIT_ADDRESSING = 0x10000,/* Use 39 bit addressing scheme. */ + AHD_64BIT_ADDRESSING = 0x20000,/* Use 64 bit addressing scheme. */ + AHD_CURRENT_SENSING = 0x40000, + AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */ + AHD_HP_BOARD = 0x100000, + AHD_RESET_POLL_ACTIVE = 0x200000, + AHD_UPDATE_PEND_CMDS = 0x400000, + AHD_RUNNING_QOUTFIFO = 0x800000 +} ahd_flag; + +/************************* Hardware SCB Definition ***************************/ + +/* + * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB + * consists of a "hardware SCB" mirroring the fields available on the card + * and additional information the kernel stores for each transaction. + * + * To minimize space utilization, a portion of the hardware scb stores + * different data during different portions of a SCSI transaction. + * As initialized by the host driver for the initiator role, this area + * contains the SCSI cdb (or a pointer to the cdb) to be executed. After + * the cdb has been presented to the target, this area serves to store + * residual transfer information and the SCSI status byte. + * For the target role, the contents of this area do not change, but + * still serve a different purpose than for the initiator role. See + * struct target_data for details. + */ + +/* + * Status information embedded in the shared poriton of + * an SCB after passing the cdb to the target. The kernel + * driver will only read this data for transactions that + * complete abnormally. + */ +struct initiator_status { + uint32_t residual_datacnt; /* Residual in the current S/G seg */ + uint32_t residual_sgptr; /* The next S/G for this transfer */ + uint8_t scsi_status; /* Standard SCSI status byte */ +}; + +struct target_status { + uint32_t residual_datacnt; /* Residual in the current S/G seg */ + uint32_t residual_sgptr; /* The next S/G for this transfer */ + uint8_t scsi_status; /* SCSI status to give to initiator */ + uint8_t target_phases; /* Bitmap of phases to execute */ + uint8_t data_phase; /* Data-In or Data-Out */ + uint8_t initiator_tag; /* Initiator's transaction tag */ +}; + +/* + * Initiator mode SCB shared data area. + * If the embedded CDB is 12 bytes or less, we embed + * the sense buffer address in the SCB. This allows + * us to retrieve sense information without interrupting + * the host in packetized mode. + */ +typedef uint32_t sense_addr_t; +#define MAX_CDB_LEN 16 +#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t)) +union initiator_data { + struct { + uint64_t cdbptr; + uint8_t cdblen; + } cdb_from_host; + uint8_t cdb[MAX_CDB_LEN]; + struct { + uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR]; + sense_addr_t sense_addr; + } cdb_plus_saddr; +}; + +/* + * Target mode version of the shared data SCB segment. + */ +struct target_data { + uint32_t spare[2]; + uint8_t scsi_status; /* SCSI status to give to initiator */ + uint8_t target_phases; /* Bitmap of phases to execute */ + uint8_t data_phase; /* Data-In or Data-Out */ + uint8_t initiator_tag; /* Initiator's transaction tag */ +}; + +struct hardware_scb { +/*0*/ union { + union initiator_data idata; + struct target_data tdata; + struct initiator_status istatus; + struct target_status tstatus; + } shared_data; +/* + * A word about residuals. + * The scb is presented to the sequencer with the dataptr and datacnt + * fields initialized to the contents of the first S/G element to + * transfer. The sgptr field is initialized to the bus address for + * the S/G element that follows the first in the in core S/G array + * or'ed with the SG_FULL_RESID flag. Sgptr may point to an invalid + * S/G entry for this transfer (single S/G element transfer with the + * first elements address and length preloaded in the dataptr/datacnt + * fields). If no transfer is to occur, sgptr is set to SG_LIST_NULL. + * The SG_FULL_RESID flag ensures that the residual will be correctly + * noted even if no data transfers occur. Once the data phase is entered, + * the residual sgptr and datacnt are loaded from the sgptr and the + * datacnt fields. After each S/G element's dataptr and length are + * loaded into the hardware, the residual sgptr is advanced. After + * each S/G element is expired, its datacnt field is checked to see + * if the LAST_SEG flag is set. If so, SG_LIST_NULL is set in the + * residual sg ptr and the transfer is considered complete. If the + * sequencer determines that there is a residual in the tranfer, or + * there is non-zero status, it will set the SG_STATUS_VALID flag in + * sgptr and dma the scb back into host memory. To sumarize: + * + * Sequencer: + * o A residual has occurred if SG_FULL_RESID is set in sgptr, + * or residual_sgptr does not have SG_LIST_NULL set. + * + * o We are transfering the last segment if residual_datacnt has + * the SG_LAST_SEG flag set. + * + * Host: + * o A residual can only have occurred if a completed scb has the + * SG_STATUS_VALID flag set. Inspection of the SCSI status field, + * the residual_datacnt, and the residual_sgptr field will tell + * for sure. + * + * o residual_sgptr and sgptr refer to the "next" sg entry + * and so may point beyond the last valid sg entry for the + * transfer. + */ +#define SG_PTR_MASK 0xFFFFFFF8 +/*16*/ uint16_t tag; /* Reused by Sequencer. */ +/*18*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */ +/*19*/ uint8_t scsiid; /* + * Selection out Id + * Our Id (bits 0-3) Their ID (bits 4-7) + */ +/*20*/ uint8_t lun; +/*21*/ uint8_t task_attribute; +/*22*/ uint8_t cdb_len; +/*23*/ uint8_t task_management; +/*24*/ uint64_t dataptr; +/*32*/ uint32_t datacnt; /* Byte 3 is spare. */ +/*36*/ uint32_t sgptr; +/*40*/ uint32_t hscb_busaddr; +/*44*/ uint32_t next_hscb_busaddr; +/********** Long lun field only downloaded for full 8 byte lun support ********/ +/*48*/ uint8_t pkt_long_lun[8]; +/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/ +/*56*/ uint8_t spare[8]; +}; + +/************************ Kernel SCB Definitions ******************************/ +/* + * Some fields of the SCB are OS dependent. Here we collect the + * definitions for elements that all OS platforms need to include + * in there SCB definition. + */ + +/* + * Definition of a scatter/gather element as transfered to the controller. + * The aic7xxx chips only support a 24bit length. We use the top byte of + * the length to store additional address bits and a flag to indicate + * that a given segment terminates the transfer. This gives us an + * addressable range of 512GB on machines with 64bit PCI or with chips + * that can support dual address cycles on 32bit PCI busses. + */ +struct ahd_dma_seg { + uint32_t addr; + uint32_t len; +#define AHD_DMA_LAST_SEG 0x80000000 +#define AHD_SG_HIGH_ADDR_MASK 0x7F000000 +#define AHD_SG_LEN_MASK 0x00FFFFFF +}; + +struct ahd_dma64_seg { + uint64_t addr; + uint32_t len; + uint32_t pad; +}; + +struct map_node { + bus_dmamap_t dmamap; + bus_addr_t physaddr; + uint8_t *vaddr; + SLIST_ENTRY(map_node) links; +}; + +/* + * The current state of this SCB. + */ +typedef enum { + SCB_FLAG_NONE = 0x00000, + SCB_TRANSMISSION_ERROR = 0x00001,/* + * We detected a parity or CRC + * error that has effected the + * payload of the command. This + * flag is checked when normal + * status is returned to catch + * the case of a target not + * responding to our attempt + * to report the error. + */ + SCB_OTHERTCL_TIMEOUT = 0x00002,/* + * Another device was active + * during the first timeout for + * this SCB so we gave ourselves + * an additional timeout period + * in case it was hogging the + * bus. + */ + SCB_DEVICE_RESET = 0x00004, + SCB_SENSE = 0x00008, + SCB_CDB32_PTR = 0x00010, + SCB_RECOVERY_SCB = 0x00020, + SCB_AUTO_NEGOTIATE = 0x00040,/* Negotiate to achieve goal. */ + SCB_NEGOTIATE = 0x00080,/* Negotiation forced for command. */ + SCB_ABORT = 0x00100, + SCB_ACTIVE = 0x00200, + SCB_TARGET_IMMEDIATE = 0x00400, + SCB_PACKETIZED = 0x00800, + SCB_EXPECT_PPR_BUSFREE = 0x01000, + SCB_PKT_SENSE = 0x02000, + SCB_CMDPHASE_ABORT = 0x04000, + SCB_ON_COL_LIST = 0x08000, + SCB_SILENT = 0x10000 /* + * Be quiet about transmission type + * errors. They are expected and we + * don't want to upset the user. This + * flag is typically used during DV. + */ +} scb_flag; + +struct scb { + struct hardware_scb *hscb; + union { + SLIST_ENTRY(scb) sle; + LIST_ENTRY(scb) le; + TAILQ_ENTRY(scb) tqe; + } links; + union { + SLIST_ENTRY(scb) sle; + LIST_ENTRY(scb) le; + TAILQ_ENTRY(scb) tqe; + } links2; +#define pending_links links2.le +#define collision_links links2.le + struct scb *col_scb; + ahd_io_ctx_t io_ctx; + struct ahd_softc *ahd_softc; + scb_flag flags; +#ifndef __linux__ + bus_dmamap_t dmamap; +#endif + struct scb_platform_data *platform_data; + struct map_node *hscb_map; + struct map_node *sg_map; + struct map_node *sense_map; + void *sg_list; + uint8_t *sense_data; + bus_addr_t sg_list_busaddr; + bus_addr_t sense_busaddr; + u_int sg_count;/* How full ahd_dma_seg is */ +#define AHD_MAX_LQ_CRC_ERRORS 5 + u_int crc_retry_count; +}; + +TAILQ_HEAD(scb_tailq, scb); +LIST_HEAD(scb_list, scb); + +struct scb_data { + /* + * TAILQ of lists of free SCBs grouped by device + * collision domains. + */ + struct scb_tailq free_scbs; + + /* + * Per-device lists of SCBs whose tag ID would collide + * with an already active tag on the device. + */ + struct scb_list free_scb_lists[AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT]; + + /* + * SCBs that will not collide with any active device. + */ + struct scb_list any_dev_free_scb_list; + + /* + * Mapping from tag to SCB. + */ + struct scb *scbindex[AHD_SCB_MAX]; + + /* + * "Bus" addresses of our data structures. + */ + bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */ + bus_dma_tag_t sg_dmat; /* dmat for our sg segments */ + bus_dma_tag_t sense_dmat; /* dmat for our sense buffers */ + SLIST_HEAD(, map_node) hscb_maps; + SLIST_HEAD(, map_node) sg_maps; + SLIST_HEAD(, map_node) sense_maps; + int scbs_left; /* unallocated scbs in head map_node */ + int sgs_left; /* unallocated sgs in head map_node */ + int sense_left; /* unallocated sense in head map_node */ + uint16_t numscbs; + uint16_t maxhscbs; /* Number of SCBs on the card */ + uint8_t init_level; /* + * How far we've initialized + * this structure. + */ +}; + +/************************ Target Mode Definitions *****************************/ + +/* + * Connection desciptor for select-in requests in target mode. + */ +struct target_cmd { + uint8_t scsiid; /* Our ID and the initiator's ID */ + uint8_t identify; /* Identify message */ + uint8_t bytes[22]; /* + * Bytes contains any additional message + * bytes terminated by 0xFF. The remainder + * is the cdb to execute. + */ + uint8_t cmd_valid; /* + * When a command is complete, the firmware + * will set cmd_valid to all bits set. + * After the host has seen the command, + * the bits are cleared. This allows us + * to just peek at host memory to determine + * if more work is complete. cmd_valid is on + * an 8 byte boundary to simplify setting + * it on aic7880 hardware which only has + * limited direct access to the DMA FIFO. + */ + uint8_t pad[7]; +}; + +/* + * Number of events we can buffer up if we run out + * of immediate notify ccbs. + */ +#define AHD_TMODE_EVENT_BUFFER_SIZE 8 +struct ahd_tmode_event { + uint8_t initiator_id; + uint8_t event_type; /* MSG type or EVENT_TYPE_BUS_RESET */ +#define EVENT_TYPE_BUS_RESET 0xFF + uint8_t event_arg; +}; + +/* + * Per enabled lun target mode state. + * As this state is directly influenced by the host OS'es target mode + * environment, we let the OS module define it. Forward declare the + * structure here so we can store arrays of them, etc. in OS neutral + * data structures. + */ +#ifdef AHD_TARGET_MODE +struct ahd_tmode_lstate { + struct cam_path *path; + struct ccb_hdr_slist accept_tios; + struct ccb_hdr_slist immed_notifies; + struct ahd_tmode_event event_buffer[AHD_TMODE_EVENT_BUFFER_SIZE]; + uint8_t event_r_idx; + uint8_t event_w_idx; +}; +#else +struct ahd_tmode_lstate; +#endif + +/******************** Transfer Negotiation Datastructures *********************/ +#define AHD_TRANS_CUR 0x01 /* Modify current neogtiation status */ +#define AHD_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */ +#define AHD_TRANS_GOAL 0x04 /* Modify negotiation goal */ +#define AHD_TRANS_USER 0x08 /* Modify user negotiation settings */ +#define AHD_PERIOD_10MHz 0x19 + +#define AHD_WIDTH_UNKNOWN 0xFF +#define AHD_PERIOD_UNKNOWN 0xFF +#define AHD_OFFSET_UNKNOWN 0xFF +#define AHD_PPR_OPTS_UNKNOWN 0xFF + +/* + * Transfer Negotiation Information. + */ +struct ahd_transinfo { + uint8_t protocol_version; /* SCSI Revision level */ + uint8_t transport_version; /* SPI Revision level */ + uint8_t width; /* Bus width */ + uint8_t period; /* Sync rate factor */ + uint8_t offset; /* Sync offset */ + uint8_t ppr_options; /* Parallel Protocol Request options */ +}; + +/* + * Per-initiator current, goal and user transfer negotiation information. */ +struct ahd_initiator_tinfo { + struct ahd_transinfo curr; + struct ahd_transinfo goal; + struct ahd_transinfo user; +}; + +/* + * Per enabled target ID state. + * Pointers to lun target state as well as sync/wide negotiation information + * for each initiator<->target mapping. For the initiator role we pretend + * that we are the target and the targets are the initiators since the + * negotiation is the same regardless of role. + */ +struct ahd_tmode_tstate { + struct ahd_tmode_lstate* enabled_luns[AHD_NUM_LUNS]; + struct ahd_initiator_tinfo transinfo[AHD_NUM_TARGETS]; + + /* + * Per initiator state bitmasks. + */ + uint16_t auto_negotiate;/* Auto Negotiation Required */ + uint16_t discenable; /* Disconnection allowed */ + uint16_t tagenable; /* Tagged Queuing allowed */ +}; + +/* + * Points of interest along the negotiated transfer scale. + */ +#define AHD_SYNCRATE_160 0x8 +#define AHD_SYNCRATE_PACED 0x8 +#define AHD_SYNCRATE_DT 0x9 +#define AHD_SYNCRATE_ULTRA2 0xa +#define AHD_SYNCRATE_ULTRA 0xc +#define AHD_SYNCRATE_FAST 0x19 +#define AHD_SYNCRATE_MIN_DT AHD_SYNCRATE_FAST +#define AHD_SYNCRATE_SYNC 0x32 +#define AHD_SYNCRATE_MIN 0x60 +#define AHD_SYNCRATE_ASYNC 0xFF +#define AHD_SYNCRATE_MAX AHD_SYNCRATE_160 + +/* Safe and valid period for async negotiations. */ +#define AHD_ASYNC_XFER_PERIOD 0x44 + +/* + * In RevA, the synctable uses a 120MHz rate for the period + * factor 8 and 160MHz for the period factor 7. The 120MHz + * rate never made it into the official SCSI spec, so we must + * compensate when setting the negotiation table for Rev A + * parts. + */ +#define AHD_SYNCRATE_REVA_120 0x8 +#define AHD_SYNCRATE_REVA_160 0x7 + +/***************************** Lookup Tables **********************************/ +/* + * Phase -> name and message out response + * to parity errors in each phase table. + */ +struct ahd_phase_table_entry { + uint8_t phase; + uint8_t mesg_out; /* Message response to parity errors */ + char *phasemsg; +}; + +/************************** Serial EEPROM Format ******************************/ + +struct seeprom_config { +/* + * Per SCSI ID Configuration Flags + */ + uint16_t device_flags[16]; /* words 0-15 */ +#define CFXFER 0x003F /* synchronous transfer rate */ +#define CFXFER_ASYNC 0x3F +#define CFQAS 0x0040 /* Negotiate QAS */ +#define CFPACKETIZED 0x0080 /* Negotiate Packetized Transfers */ +#define CFSTART 0x0100 /* send start unit SCSI command */ +#define CFINCBIOS 0x0200 /* include in BIOS scan */ +#define CFDISC 0x0400 /* enable disconnection */ +#define CFMULTILUNDEV 0x0800 /* Probe multiple luns in BIOS scan */ +#define CFWIDEB 0x1000 /* wide bus device */ +#define CFHOSTMANAGED 0x8000 /* Managed by a RAID controller */ + +/* + * BIOS Control Bits + */ + uint16_t bios_control; /* word 16 */ +#define CFSUPREM 0x0001 /* support all removeable drives */ +#define CFSUPREMB 0x0002 /* support removeable boot drives */ +#define CFBIOSSTATE 0x000C /* BIOS Action State */ +#define CFBS_DISABLED 0x00 +#define CFBS_ENABLED 0x04 +#define CFBS_DISABLED_SCAN 0x08 +#define CFENABLEDV 0x0010 /* Perform Domain Validation */ +#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */ +#define CFSPARITY 0x0040 /* SCSI parity */ +#define CFEXTEND 0x0080 /* extended translation enabled */ +#define CFBOOTCD 0x0100 /* Support Bootable CD-ROM */ +#define CFMSG_LEVEL 0x0600 /* BIOS Message Level */ +#define CFMSG_VERBOSE 0x0000 +#define CFMSG_SILENT 0x0200 +#define CFMSG_DIAG 0x0400 +#define CFRESETB 0x0800 /* reset SCSI bus at boot */ +/* UNUSED 0xf000 */ + +/* + * Host Adapter Control Bits + */ + uint16_t adapter_control; /* word 17 */ +#define CFAUTOTERM 0x0001 /* Perform Auto termination */ +#define CFSTERM 0x0002 /* SCSI low byte termination */ +#define CFWSTERM 0x0004 /* SCSI high byte termination */ +#define CFSEAUTOTERM 0x0008 /* Ultra2 Perform secondary Auto Term*/ +#define CFSELOWTERM 0x0010 /* Ultra2 secondary low term */ +#define CFSEHIGHTERM 0x0020 /* Ultra2 secondary high term */ +#define CFSTPWLEVEL 0x0040 /* Termination level control */ +#define CFBIOSAUTOTERM 0x0080 /* Perform Auto termination */ +#define CFTERM_MENU 0x0100 /* BIOS displays termination menu */ +#define CFCLUSTERENB 0x8000 /* Cluster Enable */ + +/* + * Bus Release Time, Host Adapter ID + */ + uint16_t brtime_id; /* word 18 */ +#define CFSCSIID 0x000f /* host adapter SCSI ID */ +/* UNUSED 0x00f0 */ +#define CFBRTIME 0xff00 /* bus release time/PCI Latency Time */ + +/* + * Maximum targets + */ + uint16_t max_targets; /* word 19 */ +#define CFMAXTARG 0x00ff /* maximum targets */ +#define CFBOOTLUN 0x0f00 /* Lun to boot from */ +#define CFBOOTID 0xf000 /* Target to boot from */ + uint16_t res_1[10]; /* words 20-29 */ + uint16_t signature; /* BIOS Signature */ +#define CFSIGNATURE 0x400 + uint16_t checksum; /* word 31 */ +}; + +/* + * Vital Product Data used during POST and by the BIOS. + */ +struct vpd_config { + uint8_t bios_flags; +#define VPDMASTERBIOS 0x0001 +#define VPDBOOTHOST 0x0002 + uint8_t reserved_1[21]; + uint8_t resource_type; + uint8_t resource_len[2]; + uint8_t resource_data[8]; + uint8_t vpd_tag; + uint16_t vpd_len; + uint8_t vpd_keyword[2]; + uint8_t length; + uint8_t revision; + uint8_t device_flags; + uint8_t termnation_menus[2]; + uint8_t fifo_threshold; + uint8_t end_tag; + uint8_t vpd_checksum; + uint16_t default_target_flags; + uint16_t default_bios_flags; + uint16_t default_ctrl_flags; + uint8_t default_irq; + uint8_t pci_lattime; + uint8_t max_target; + uint8_t boot_lun; + uint16_t signature; + uint8_t reserved_2; + uint8_t checksum; + uint8_t reserved_3[4]; +}; + +/****************************** Flexport Logic ********************************/ +#define FLXADDR_TERMCTL 0x0 +#define FLX_TERMCTL_ENSECHIGH 0x8 +#define FLX_TERMCTL_ENSECLOW 0x4 +#define FLX_TERMCTL_ENPRIHIGH 0x2 +#define FLX_TERMCTL_ENPRILOW 0x1 +#define FLXADDR_ROMSTAT_CURSENSECTL 0x1 +#define FLX_ROMSTAT_SEECFG 0xF0 +#define FLX_ROMSTAT_EECFG 0x0F +#define FLX_ROMSTAT_SEE_93C66 0x00 +#define FLX_ROMSTAT_SEE_NONE 0xF0 +#define FLX_ROMSTAT_EE_512x8 0x0 +#define FLX_ROMSTAT_EE_1MBx8 0x1 +#define FLX_ROMSTAT_EE_2MBx8 0x2 +#define FLX_ROMSTAT_EE_4MBx8 0x3 +#define FLX_ROMSTAT_EE_16MBx8 0x4 +#define CURSENSE_ENB 0x1 +#define FLXADDR_FLEXSTAT 0x2 +#define FLX_FSTAT_BUSY 0x1 +#define FLXADDR_CURRENT_STAT 0x4 +#define FLX_CSTAT_SEC_HIGH 0xC0 +#define FLX_CSTAT_SEC_LOW 0x30 +#define FLX_CSTAT_PRI_HIGH 0x0C +#define FLX_CSTAT_PRI_LOW 0x03 +#define FLX_CSTAT_MASK 0x03 +#define FLX_CSTAT_SHIFT 2 +#define FLX_CSTAT_OKAY 0x0 +#define FLX_CSTAT_OVER 0x1 +#define FLX_CSTAT_UNDER 0x2 +#define FLX_CSTAT_INVALID 0x3 + +int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count, int bstream); + +int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count); +int ahd_wait_seeprom(struct ahd_softc *ahd); +int ahd_verify_vpd_cksum(struct vpd_config *vpd); +int ahd_verify_cksum(struct seeprom_config *sc); +int ahd_acquire_seeprom(struct ahd_softc *ahd); +void ahd_release_seeprom(struct ahd_softc *ahd); + +/**************************** Message Buffer *********************************/ +typedef enum { + MSG_FLAG_NONE = 0x00, + MSG_FLAG_EXPECT_PPR_BUSFREE = 0x01, + MSG_FLAG_IU_REQ_CHANGED = 0x02, + MSG_FLAG_EXPECT_IDE_BUSFREE = 0x04, + MSG_FLAG_EXPECT_QASREJ_BUSFREE = 0x08, + MSG_FLAG_PACKETIZED = 0x10 +} ahd_msg_flags; + +typedef enum { + MSG_TYPE_NONE = 0x00, + MSG_TYPE_INITIATOR_MSGOUT = 0x01, + MSG_TYPE_INITIATOR_MSGIN = 0x02, + MSG_TYPE_TARGET_MSGOUT = 0x03, + MSG_TYPE_TARGET_MSGIN = 0x04 +} ahd_msg_type; + +typedef enum { + MSGLOOP_IN_PROG, + MSGLOOP_MSGCOMPLETE, + MSGLOOP_TERMINATED +} msg_loop_stat; + +/*********************** Software Configuration Structure *********************/ +struct ahd_suspend_channel_state { + uint8_t scsiseq; + uint8_t sxfrctl0; + uint8_t sxfrctl1; + uint8_t simode0; + uint8_t simode1; + uint8_t seltimer; + uint8_t seqctl; +}; + +struct ahd_suspend_state { + struct ahd_suspend_channel_state channel[2]; + uint8_t optionmode; + uint8_t dscommand0; + uint8_t dspcistatus; + /* hsmailbox */ + uint8_t crccontrol1; + uint8_t scbbaddr; + /* Host and sequencer SCB counts */ + uint8_t dff_thrsh; + uint8_t *scratch_ram; + uint8_t *btt; +}; + +typedef void (*ahd_bus_intr_t)(struct ahd_softc *); + +typedef enum { + AHD_MODE_DFF0, + AHD_MODE_DFF1, + AHD_MODE_CCHAN, + AHD_MODE_SCSI, + AHD_MODE_CFG, + AHD_MODE_UNKNOWN +} ahd_mode; + +#define AHD_MK_MSK(x) (0x01 << (x)) +#define AHD_MODE_DFF0_MSK AHD_MK_MSK(AHD_MODE_DFF0) +#define AHD_MODE_DFF1_MSK AHD_MK_MSK(AHD_MODE_DFF1) +#define AHD_MODE_CCHAN_MSK AHD_MK_MSK(AHD_MODE_CCHAN) +#define AHD_MODE_SCSI_MSK AHD_MK_MSK(AHD_MODE_SCSI) +#define AHD_MODE_CFG_MSK AHD_MK_MSK(AHD_MODE_CFG) +#define AHD_MODE_UNKNOWN_MSK AHD_MK_MSK(AHD_MODE_UNKNOWN) +#define AHD_MODE_ANY_MSK (~0) + +typedef uint8_t ahd_mode_state; + +typedef void ahd_callback_t (void *); + +struct ahd_softc { + bus_space_tag_t tags[2]; + bus_space_handle_t bshs[2]; +#ifndef __linux__ + bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ +#endif + struct scb_data scb_data; + + struct hardware_scb *next_queued_hscb; + + /* + * SCBs that have been sent to the controller + */ + LIST_HEAD(, scb) pending_scbs; + + /* + * Current register window mode information. + */ + ahd_mode dst_mode; + ahd_mode src_mode; + + /* + * Saved register window mode information + * used for restore on next unpause. + */ + ahd_mode saved_dst_mode; + ahd_mode saved_src_mode; + + /* + * Platform specific data. + */ + struct ahd_platform_data *platform_data; + + /* + * Platform specific device information. + */ + ahd_dev_softc_t dev_softc; + + /* + * Bus specific device information. + */ + ahd_bus_intr_t bus_intr; + + /* + * Target mode related state kept on a per enabled lun basis. + * Targets that are not enabled will have null entries. + * As an initiator, we keep one target entry for our initiator + * ID to store our sync/wide transfer settings. + */ + struct ahd_tmode_tstate *enabled_targets[AHD_NUM_TARGETS]; + + /* + * The black hole device responsible for handling requests for + * disabled luns on enabled targets. + */ + struct ahd_tmode_lstate *black_hole; + + /* + * Device instance currently on the bus awaiting a continue TIO + * for a command that was not given the disconnect priveledge. + */ + struct ahd_tmode_lstate *pending_device; + + /* + * Timer handles for timer driven callbacks. + */ + ahd_timer_t reset_timer; + ahd_timer_t stat_timer; + + /* + * Statistics. + */ +#define AHD_STAT_UPDATE_US 250000 /* 250ms */ +#define AHD_STAT_BUCKETS 4 + u_int cmdcmplt_bucket; + uint32_t cmdcmplt_counts[AHD_STAT_BUCKETS]; + uint32_t cmdcmplt_total; + + /* + * Card characteristics + */ + ahd_chip chip; + ahd_feature features; + ahd_bug bugs; + ahd_flag flags; + struct seeprom_config *seep_config; + + /* Values to store in the SEQCTL register for pause and unpause */ + uint8_t unpause; + uint8_t pause; + + /* Command Queues */ + uint16_t qoutfifonext; + uint16_t qoutfifonext_valid_tag; + uint16_t qinfifonext; + uint16_t qinfifo[AHD_SCB_MAX]; + uint16_t *qoutfifo; + + /* Critical Section Data */ + struct cs *critical_sections; + u_int num_critical_sections; + + /* Buffer for handling packetized bitbucket. */ + uint8_t *overrun_buf; + + /* Links for chaining softcs */ + TAILQ_ENTRY(ahd_softc) links; + + /* Channel Names ('A', 'B', etc.) */ + char channel; + + /* Initiator Bus ID */ + uint8_t our_id; + + /* + * Target incoming command FIFO. + */ + struct target_cmd *targetcmds; + uint8_t tqinfifonext; + + /* + * Cached verson of the hs_mailbox so we can avoid + * pausing the sequencer during mailbox updates. + */ + uint8_t hs_mailbox; + + /* + * Incoming and outgoing message handling. + */ + uint8_t send_msg_perror; + ahd_msg_flags msg_flags; + ahd_msg_type msg_type; + uint8_t msgout_buf[12];/* Message we are sending */ + uint8_t msgin_buf[12];/* Message we are receiving */ + u_int msgout_len; /* Length of message to send */ + u_int msgout_index; /* Current index in msgout */ + u_int msgin_index; /* Current index in msgin */ + + /* + * Mapping information for data structures shared + * between the sequencer and kernel. + */ + bus_dma_tag_t parent_dmat; + bus_dma_tag_t shared_data_dmat; + bus_dmamap_t shared_data_dmamap; + bus_addr_t shared_data_busaddr; + + /* Information saved through suspend/resume cycles */ + struct ahd_suspend_state suspend_state; + + /* Number of enabled target mode device on this card */ + u_int enabled_luns; + + /* Initialization level of this data structure */ + u_int init_level; + + /* PCI cacheline size. */ + u_int pci_cachesize; + + /* IO Cell Parameters */ + uint8_t iocell_opts[AHD_NUM_PER_DEV_ANNEXCOLS]; + + u_int stack_size; + uint16_t *saved_stack; + + /* Per-Unit descriptive information */ + const char *description; + const char *bus_description; + char *name; + int unit; + + /* Selection Timer settings */ + int seltime; + + /* + * Interrupt coalescing settings. + */ +#define AHD_INT_COALESCING_TIMER_DEFAULT 250 /*us*/ +#define AHD_INT_COALESCING_MAXCMDS_DEFAULT 10 +#define AHD_INT_COALESCING_MAXCMDS_MAX 127 +#define AHD_INT_COALESCING_MINCMDS_DEFAULT 5 +#define AHD_INT_COALESCING_MINCMDS_MAX 127 +#define AHD_INT_COALESCING_THRESHOLD_DEFAULT 2000 +#define AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT 1000 + u_int int_coalescing_timer; + u_int int_coalescing_maxcmds; + u_int int_coalescing_mincmds; + u_int int_coalescing_threshold; + u_int int_coalescing_stop_threshold; + + uint16_t user_discenable;/* Disconnection allowed */ + uint16_t user_tagenable;/* Tagged Queuing allowed */ +}; + +TAILQ_HEAD(ahd_softc_tailq, ahd_softc); +extern struct ahd_softc_tailq ahd_tailq; + +/*************************** IO Cell Configuration ****************************/ +#define AHD_PRECOMP_SLEW_INDEX \ + (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0) + +#define AHD_AMPLITUDE_INDEX \ + (AHD_ANNEXCOL_AMPLITUDE - AHD_ANNEXCOL_PER_DEV0) + +#define AHD_SET_SLEWRATE(ahd, new_slew) \ +do { \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_SLEWRATE_MASK; \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ + (((new_slew) << AHD_SLEWRATE_SHIFT) & AHD_SLEWRATE_MASK); \ +} while (0) + +#define AHD_SET_PRECOMP(ahd, new_pcomp) \ +do { \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; \ + (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ + (((new_pcomp) << AHD_PRECOMP_SHIFT) & AHD_PRECOMP_MASK); \ +} while (0) + +#define AHD_SET_AMPLITUDE(ahd, new_amp) \ +do { \ + (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] &= ~AHD_AMPLITUDE_MASK; \ + (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] |= \ + (((new_amp) << AHD_AMPLITUDE_SHIFT) & AHD_AMPLITUDE_MASK); \ +} while (0) + +/************************ Active Device Information ***************************/ +typedef enum { + ROLE_UNKNOWN, + ROLE_INITIATOR, + ROLE_TARGET +} role_t; + +struct ahd_devinfo { + int our_scsiid; + int target_offset; + uint16_t target_mask; + u_int target; + u_int lun; + char channel; + role_t role; /* + * Only guaranteed to be correct if not + * in the busfree state. + */ +}; + +/****************************** PCI Structures ********************************/ +#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/ +#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */ +#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */ + +typedef int (ahd_device_setup_t)(struct ahd_softc *); + +struct ahd_pci_identity { + uint64_t full_id; + uint64_t id_mask; + char *name; + ahd_device_setup_t *setup; +}; +extern struct ahd_pci_identity ahd_pci_ident_table []; +extern const u_int ahd_num_pci_devs; + +/***************************** VL/EISA Declarations ***************************/ +struct aic7770_identity { + uint32_t full_id; + uint32_t id_mask; + char *name; + ahd_device_setup_t *setup; +}; +extern struct aic7770_identity aic7770_ident_table []; +extern const int ahd_num_aic7770_devs; + +#define AHD_EISA_SLOT_OFFSET 0xc00 +#define AHD_EISA_IOSIZE 0x100 + +/*************************** Function Declarations ****************************/ +/******************************************************************************/ +void ahd_reset_cmds_pending(struct ahd_softc *ahd); +u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); +void ahd_busy_tcl(struct ahd_softc *ahd, + u_int tcl, u_int busyid); +static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl); +static __inline void +ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) +{ + ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); +} + +/***************************** PCI Front End *********************************/ +struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); +int ahd_pci_config(struct ahd_softc *, + struct ahd_pci_identity *); +int ahd_pci_test_register_access(struct ahd_softc *); + +/************************** SCB and SCB queue management **********************/ +int ahd_probe_scbs(struct ahd_softc *); +void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, + struct scb *scb); +int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, + int target, char channel, int lun, + u_int tag, role_t role); + +/****************************** Initialization ********************************/ +struct ahd_softc *ahd_alloc(void *platform_arg, char *name); +int ahd_softc_init(struct ahd_softc *); +void ahd_controller_info(struct ahd_softc *ahd, char *buf); +int ahd_init(struct ahd_softc *ahd); +int ahd_default_config(struct ahd_softc *ahd); +int ahd_parse_vpddata(struct ahd_softc *ahd, + struct vpd_config *vpd); +int ahd_parse_cfgdata(struct ahd_softc *ahd, + struct seeprom_config *sc); +void ahd_intr_enable(struct ahd_softc *ahd, int enable); +void ahd_update_coalescing_values(struct ahd_softc *ahd, + u_int timer, + u_int maxcmds, + u_int mincmds); +void ahd_enable_coalescing(struct ahd_softc *ahd, + int enable); +void ahd_pause_and_flushwork(struct ahd_softc *ahd); +int ahd_suspend(struct ahd_softc *ahd); +int ahd_resume(struct ahd_softc *ahd); +void ahd_softc_insert(struct ahd_softc *); +struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd); +void ahd_set_unit(struct ahd_softc *, int); +void ahd_set_name(struct ahd_softc *, char *); +struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); +void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); +void ahd_alloc_scbs(struct ahd_softc *ahd); +void ahd_free(struct ahd_softc *ahd); +int ahd_reset(struct ahd_softc *ahd, int reinit); +void ahd_shutdown(void *arg); +int ahd_write_flexport(struct ahd_softc *ahd, + u_int addr, u_int value); +int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, + uint8_t *value); +int ahd_wait_flexport(struct ahd_softc *ahd); + +/*************************** Interrupt Services *******************************/ +void ahd_pci_intr(struct ahd_softc *ahd); +void ahd_clear_intstat(struct ahd_softc *ahd); +void ahd_flush_qoutfifo(struct ahd_softc *ahd); +void ahd_run_qoutfifo(struct ahd_softc *ahd); +#ifdef AHD_TARGET_MODE +void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); +#endif +void ahd_handle_hwerrint(struct ahd_softc *ahd); +void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); +void ahd_handle_scsiint(struct ahd_softc *ahd, + u_int intstat); +void ahd_clear_critical_section(struct ahd_softc *ahd); + +/***************************** Error Recovery *********************************/ +typedef enum { + SEARCH_COMPLETE, + SEARCH_COUNT, + SEARCH_REMOVE, + SEARCH_PRINT +} ahd_search_action; +int ahd_search_qinfifo(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status, + ahd_search_action action); +int ahd_search_disc_list(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + int stop_on_first, int remove, + int save_state); +void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb); +int ahd_reset_channel(struct ahd_softc *ahd, char channel, + int initiate_reset); +int ahd_abort_scbs(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status); +void ahd_restart(struct ahd_softc *ahd); +void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo); +void ahd_handle_scb_status(struct ahd_softc *ahd, + struct scb *scb); +void ahd_handle_scsi_status(struct ahd_softc *ahd, + struct scb *scb); +void ahd_calc_residual(struct ahd_softc *ahd, + struct scb *scb); +/*************************** Utility Functions ********************************/ +struct ahd_phase_table_entry* + ahd_lookup_phase_entry(int phase); +void ahd_compile_devinfo(struct ahd_devinfo *devinfo, + u_int our_id, u_int target, + u_int lun, char channel, + role_t role); +/************************** Transfer Negotiation ******************************/ +void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, + u_int *ppr_options, u_int maxsync); +void ahd_validate_offset(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int period, u_int *offset, + int wide, role_t role); +void ahd_validate_width(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int *bus_width, + role_t role); +/* + * Negotiation types. These are used to qualify if we should renegotiate + * even if our goal and current transport parameters are identical. + */ +typedef enum { + AHD_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */ + AHD_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */ + AHD_NEG_ALWAYS /* Renegotiat even if goal is async. */ +} ahd_neg_type; +int ahd_update_neg_request(struct ahd_softc*, + struct ahd_devinfo*, + struct ahd_tmode_tstate*, + struct ahd_initiator_tinfo*, + ahd_neg_type); +void ahd_set_width(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int width, u_int type, int paused); +void ahd_set_syncrate(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int period, u_int offset, + u_int ppr_options, + u_int type, int paused); +typedef enum { + AHD_QUEUE_NONE, + AHD_QUEUE_BASIC, + AHD_QUEUE_TAGGED +} ahd_queue_alg; + +void ahd_set_tags(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + ahd_queue_alg alg); + +/**************************** Target Mode *************************************/ +#ifdef AHD_TARGET_MODE +void ahd_send_lstate_events(struct ahd_softc *, + struct ahd_tmode_lstate *); +void ahd_handle_en_lun(struct ahd_softc *ahd, + struct cam_sim *sim, union ccb *ccb); +cam_status ahd_find_tmode_devs(struct ahd_softc *ahd, + struct cam_sim *sim, union ccb *ccb, + struct ahd_tmode_tstate **tstate, + struct ahd_tmode_lstate **lstate, + int notfound_failure); +#ifndef AHD_TMODE_ENABLE +#define AHD_TMODE_ENABLE 0 +#endif +#endif +/******************************* Debug ***************************************/ +#ifdef AHD_DEBUG +extern uint32_t ahd_debug; +#define AHD_SHOW_MISC 0x00001 +#define AHD_SHOW_SENSE 0x00002 +#define AHD_SHOW_RECOVERY 0x00004 +#define AHD_DUMP_SEEPROM 0x00008 +#define AHD_SHOW_TERMCTL 0x00010 +#define AHD_SHOW_MEMORY 0x00020 +#define AHD_SHOW_MESSAGES 0x00040 +#define AHD_SHOW_MODEPTR 0x00080 +#define AHD_SHOW_SELTO 0x00100 +#define AHD_SHOW_FIFOS 0x00200 +#define AHD_SHOW_QFULL 0x00400 +#define AHD_SHOW_DV 0x00800 +#define AHD_SHOW_MASKED_ERRORS 0x01000 +#define AHD_SHOW_QUEUE 0x02000 +#define AHD_SHOW_TQIN 0x04000 +#define AHD_SHOW_SG 0x08000 +#define AHD_SHOW_INT_COALESCING 0x10000 +#define AHD_DEBUG_SEQUENCER 0x20000 +#endif +void ahd_print_scb(struct scb *scb); +void ahd_print_devinfo(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +void ahd_dump_sglist(struct scb *scb); +void ahd_dump_all_cards_state(void); +void ahd_dump_card_state(struct ahd_softc *ahd); +int ahd_print_register(ahd_reg_parse_entry_t *table, + u_int num_entries, + const char *name, + u_int address, + u_int value, + u_int *cur_column, + u_int wrap_point); +void ahd_dump_scbs(struct ahd_softc *ahd); +#endif /* _AIC79XX_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx.reg linux-2.4.22/drivers/scsi/aic7xxx/aic79xx.reg --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx.reg 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx.reg 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,3958 @@ +/* + * Aic79xx register and scratch ram definitions. + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $" + +/* + * This file is processed by the aic7xxx_asm utility for use in assembling + * firmware for the aic79xx family of SCSI host adapters as well as to generate + * a C header file for use in the kernel portion of the Aic79xx driver. + */ + +/* Register window Modes */ +#define M_DFF0 0 +#define M_DFF1 1 +#define M_CCHAN 2 +#define M_SCSI 3 +#define M_CFG 4 +#define M_DST_SHIFT 4 + +#define MK_MODE(src, dst) ((src) | ((dst) << M_DST_SHIFT)) +#define SET_MODE(src, dst) \ + SET_SRC_MODE src; \ + SET_DST_MODE dst; \ + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ + mvi MK_MODE(src, dst) call set_mode_work_around; \ + } else { \ + mvi MODE_PTR, MK_MODE(src, dst); \ + } + +#define TOGGLE_DFF_MODE \ + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ + call toggle_dff_mode_work_around; \ + } else { \ + xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); \ + } + +#define RESTORE_MODE(mode) \ + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ + mov mode call set_mode_work_around; \ + } else { \ + mov MODE_PTR, mode; \ + } + +#define SET_SEQINTCODE(code) \ + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { \ + mvi code call set_seqint_work_around; \ + } else { \ + mvi SEQINTCODE, code; \ + } + +/* + * Mode Pointer + * Controls which of the 5, 512byte, address spaces should be used + * as the source and destination of any register accesses in our + * register window. + */ +register MODE_PTR { + address 0x000 + access_mode RW + field DST_MODE 0x70 + field SRC_MODE 0x07 + mode_pointer +} + +const SRC_MODE_SHIFT 0 +const DST_MODE_SHIFT 4 + +/* + * Host Interrupt Status + */ +register INTSTAT { + address 0x001 + access_mode RW + field HWERRINT 0x80 + field BRKADRINT 0x40 + field SWTMINT 0x20 + field PCIINT 0x10 + field SCSIINT 0x08 + field SEQINT 0x04 + field CMDCMPLT 0x02 + field SPLTINT 0x01 + mask INT_PEND 0xFF +} + +/* + * Sequencer Interrupt Code + */ +register SEQINTCODE { + address 0x002 + access_mode RW + field { + NO_SEQINT, /* No seqint pending. */ + BAD_PHASE, /* unknown scsi bus phase */ + SEND_REJECT, /* sending a message reject */ + PROTO_VIOLATION, /* Protocol Violation */ + NO_MATCH, /* no cmd match for reconnect */ + IGN_WIDE_RES, /* Complex IGN Wide Res Msg */ + PDATA_REINIT, /* + * Returned to data phase + * that requires data + * transfer pointers to be + * recalculated from the + * transfer residual. + */ + HOST_MSG_LOOP, /* + * The bus is ready for the + * host to perform another + * message transaction. This + * mechanism is used for things + * like sync/wide negotiation + * that require a kernel based + * message state engine. + */ + BAD_STATUS, /* Bad status from target */ + DATA_OVERRUN, /* + * Target attempted to write + * beyond the bounds of its + * command. + */ + MKMSG_FAILED, /* + * Target completed command + * without honoring our ATN + * request to issue a message. + */ + MISSED_BUSFREE, /* + * The sequencer never saw + * the bus go free after + * either a command complete + * or disconnect message. + */ + DUMP_CARD_STATE, + ILLEGAL_PHASE, + INVALID_SEQINT, + CFG4ISTAT_INTR, + STATUS_OVERRUN, + CFG4OVERRUN, + ENTERING_NONPACK, + TASKMGMT_FUNC_COMPLETE, /* + * Task management function + * request completed with + * an expected busfree. + */ + TASKMGMT_CMD_CMPLT_OKAY, /* + * A command with a non-zero + * task management function + * has completed via the normal + * command completion method + * for commands with a zero + * task management function. + * This happens when an attempt + * to abort a command loses + * the race for the command to + * complete normally. + */ + TRACEPOINT0, + TRACEPOINT1, + TRACEPOINT2, + TRACEPOINT3, + SAW_HWERR, + BAD_SCB_STATUS + } +} + +/* + * Clear Host Interrupt + */ +register CLRINT { + address 0x003 + access_mode WO + field CLRHWERRINT 0x80 /* Rev B or greater */ + field CLRBRKADRINT 0x40 + field CLRSWTMINT 0x20 + field CLRPCIINT 0x10 + field CLRSCSIINT 0x08 + field CLRSEQINT 0x04 + field CLRCMDINT 0x02 + field CLRSPLTINT 0x01 +} + +/* + * Error Register + */ +register ERROR { + address 0x004 + access_mode RO + field CIOPARERR 0x80 + field CIOACCESFAIL 0x40 /* Rev B or greater */ + field MPARERR 0x20 + field DPARERR 0x10 + field SQPARERR 0x08 + field ILLOPCODE 0x04 + field DSCTMOUT 0x02 +} + +/* + * Clear Error + */ +register CLRERR { + address 0x004 + access_mode WO + field CLRCIOPARERR 0x80 + field CLRCIOACCESFAIL 0x40 /* Rev B or greater */ + field CLRMPARERR 0x20 + field CLRDPARERR 0x10 + field CLRSQPARERR 0x08 + field CLRILLOPCODE 0x04 + field CLRDSCTMOUT 0x02 +} + +/* + * Host Control Register + * Overall host control of the device. + */ +register HCNTRL { + address 0x005 + access_mode RW + field SEQ_RESET 0x80 /* Rev B or greater */ + field POWRDN 0x40 + field SWINT 0x10 + field SWTIMER_START_B 0x08 /* Rev B or greater */ + field PAUSE 0x04 + field INTEN 0x02 + field CHIPRST 0x01 + field CHIPRSTACK 0x01 +} + +/* + * Host New SCB Queue Offset + */ +register HNSCB_QOFF { + address 0x006 + access_mode RW + size 2 +} + +/* + * Host Empty SCB Queue Offset + */ +register HESCB_QOFF { + address 0x008 + access_mode RW +} + +/* + * Host Mailbox + */ +register HS_MAILBOX { + address 0x00B + access_mode RW + mask HOST_TQINPOS 0x80 /* Boundary at either 0 or 128 */ + mask ENINT_COALESCE 0x40 /* Perform interrupt coalescing */ +} + +/* + * Sequencer Interupt Status + */ +register SEQINTSTAT { + address 0x00C + access_mode RO + field SEQ_SWTMRTO 0x10 + field SEQ_SEQINT 0x08 + field SEQ_SCSIINT 0x04 + field SEQ_PCIINT 0x02 + field SEQ_SPLTINT 0x01 +} + +/* + * Clear SEQ Interrupt + */ +register CLRSEQINTSTAT { + address 0x00C + access_mode WO + field CLRSEQ_SWTMRTO 0x10 + field CLRSEQ_SEQINT 0x08 + field CLRSEQ_SCSIINT 0x04 + field CLRSEQ_PCIINT 0x02 + field CLRSEQ_SPLTINT 0x01 +} + +/* + * Software Timer + */ +register SWTIMER { + address 0x00E + access_mode RW + size 2 +} + +/* + * SEQ New SCB Queue Offset + */ +register SNSCB_QOFF { + address 0x010 + access_mode RW + size 2 + modes M_CCHAN +} + +/* + * SEQ Empty SCB Queue Offset + */ +register SESCB_QOFF { + address 0x012 + access_mode RW + modes M_CCHAN +} + +/* + * SEQ Done SCB Queue Offset + */ +register SDSCB_QOFF { + address 0x014 + access_mode RW + modes M_CCHAN + size 2 +} + +/* + * Queue Offset Control & Status + */ +register QOFF_CTLSTA { + address 0x016 + access_mode RW + modes M_CCHAN + field EMPTY_SCB_AVAIL 0x80 + field NEW_SCB_AVAIL 0x40 + field SDSCB_ROLLOVR 0x20 + field HS_MAILBOX_ACT 0x10 + field SCB_QSIZE 0x0F { + SCB_QSIZE_4, + SCB_QSIZE_8, + SCB_QSIZE_16, + SCB_QSIZE_32, + SCB_QSIZE_64, + SCB_QSIZE_128, + SCB_QSIZE_256, + SCB_QSIZE_512, + SCB_QSIZE_1024, + SCB_QSIZE_2048, + SCB_QSIZE_4096, + SCB_QSIZE_8192, + SCB_QSIZE_16384 + } +} + +/* + * Interrupt Control + */ +register INTCTL { + address 0x018 + access_mode RW + field SWTMINTMASK 0x80 + field SWTMINTEN 0x40 + field SWTIMER_START 0x20 + field AUTOCLRCMDINT 0x10 + field PCIINTEN 0x08 + field SCSIINTEN 0x04 + field SEQINTEN 0x02 + field SPLTINTEN 0x01 +} + +/* + * Data FIFO Control + */ +register DFCNTRL { + address 0x019 + access_mode RW + modes M_DFF0, M_DFF1 + field PRELOADEN 0x80 + field SCSIENWRDIS 0x40 /* Rev B only. */ + field SCSIEN 0x20 + field SCSIENACK 0x20 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 + field DIRECTIONACK 0x04 + field FIFOFLUSH 0x02 + field FIFOFLUSHACK 0x02 + field DIRECTIONEN 0x01 +} + +/* + * Device Space Command 0 + */ +register DSCOMMAND0 { + address 0x019 + access_mode RW + modes M_CFG + field CACHETHEN 0x80 /* Cache Threshold enable */ + field DPARCKEN 0x40 /* Data Parity Check Enable */ + field MPARCKEN 0x20 /* Memory Parity Check Enable */ + field EXTREQLCK 0x10 /* External Request Lock */ + field DISABLE_TWATE 0x02 /* Rev B or greater */ + field CIOPARCKEN 0x01 /* Internal bus parity error enable */ +} + +/* + * Data FIFO Status + */ +register DFSTATUS { + address 0x01A + access_mode RO + modes M_DFF0, M_DFF1 + field PRELOAD_AVAIL 0x80 + field PKT_PRELOAD_AVAIL 0x40 + field MREQPEND 0x10 + field HDONE 0x08 + field DFTHRESH 0x04 + field FIFOFULL 0x02 + field FIFOEMP 0x01 +} + +/* + * S/G Cache Pointer + */ +register SG_CACHE_PRE { + address 0x01B + access_mode WO + modes M_DFF0, M_DFF1 + field SG_ADDR_MASK 0xf8 + field ODD_SEG 0x04 + field LAST_SEG 0x02 +} + +register SG_CACHE_SHADOW { + address 0x01B + access_mode RO + modes M_DFF0, M_DFF1 + field SG_ADDR_MASK 0xf8 + field ODD_SEG 0x04 + field LAST_SEG 0x02 + field LAST_SEG_DONE 0x01 +} + +/* + * Arbiter Control + */ +register ARBCTL { + address 0x01B + access_mode RW + modes M_CFG + field RESET_HARB 0x80 + field RETRY_SWEN 0x08 + field USE_TIME 0x07 +} + +/* + * Data Channel Host Address + */ +register HADDR { + address 0x070 + access_mode RW + size 8 + modes M_DFF0, M_DFF1 +} + +/* + * Host Overlay DMA Address + */ +register HODMAADR { + address 0x070 + access_mode RW + size 8 + modes M_SCSI +} + +/* + * PCI PLL Delay. + */ +register PLLDELAY { + address 0x070 + access_mode RW + size 1 + modes M_CFG + field SPLIT_DROP_REQ 0x80 +} + +/* + * Data Channel Host Count + */ +register HCNT { + address 0x078 + access_mode RW + size 3 + modes M_DFF0, M_DFF1 +} + +/* + * Host Overlay DMA Count + */ +register HODMACNT { + address 0x078 + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Host Overlay DMA Enable + */ +register HODMAEN { + address 0x07A + access_mode RW + modes M_SCSI +} + +/* + * Scatter/Gather Host Address + */ +register SGHADDR { + address 0x07C + access_mode RW + size 8 + modes M_DFF0, M_DFF1 +} + +/* + * SCB Host Address + */ +register SCBHADDR { + address 0x07C + access_mode RW + size 8 + modes M_CCHAN +} + +/* + * Scatter/Gather Host Count + */ +register SGHCNT { + address 0x084 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * SCB Host Count + */ +register SCBHCNT { + address 0x084 + access_mode RW + modes M_CCHAN +} + +/* + * Data FIFO Threshold + */ +register DFF_THRSH { + address 0x088 + access_mode RW + modes M_CFG + field WR_DFTHRSH 0x70 { + WR_DFTHRSH_MIN, + WR_DFTHRSH_25, + WR_DFTHRSH_50, + WR_DFTHRSH_63, + WR_DFTHRSH_75, + WR_DFTHRSH_85, + WR_DFTHRSH_90, + WR_DFTHRSH_MAX + } + field RD_DFTHRSH 0x07 { + RD_DFTHRSH_MIN, + RD_DFTHRSH_25, + RD_DFTHRSH_50, + RD_DFTHRSH_63, + RD_DFTHRSH_75, + RD_DFTHRSH_85, + RD_DFTHRSH_90, + RD_DFTHRSH_MAX + } +} + +/* + * ROM Address + */ +register ROMADDR { + address 0x08A + access_mode RW + size 3 +} + +/* + * ROM Control + */ +register ROMCNTRL { + address 0x08D + access_mode RW + field ROMOP 0xE0 + field ROMSPD 0x18 + field REPEAT 0x02 + field RDY 0x01 +} + +/* + * ROM Data + */ +register ROMDATA { + address 0x08E + access_mode RW +} + +/* + * Data Channel Receive Message 0 + */ +register DCHRXMSG0 { + address 0x090 + access_mode RO + modes M_DFF0, M_DFF1 + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * CMC Recieve Message 0 + */ +register CMCRXMSG0 { + address 0x090 + access_mode RO + modes M_CCHAN + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * Overlay Recieve Message 0 + */ +register OVLYRXMSG0 { + address 0x090 + access_mode RO + modes M_SCSI + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * Relaxed Order Enable + */ +register ROENABLE { + address 0x090 + access_mode RW + modes M_CFG + field MSIROEN 0x20 + field OVLYROEN 0x10 + field CMCROEN 0x08 + field SGROEN 0x04 + field DCH1ROEN 0x02 + field DCH0ROEN 0x01 +} + +/* + * Data Channel Receive Message 1 + */ +register DCHRXMSG1 { + address 0x091 + access_mode RO + modes M_DFF0, M_DFF1 + field CBNUM 0xFF +} + +/* + * CMC Recieve Message 1 + */ +register CMCRXMSG1 { + address 0x091 + access_mode RO + modes M_CCHAN + field CBNUM 0xFF +} + +/* + * Overlay Recieve Message 1 + */ +register OVLYRXMSG1 { + address 0x091 + access_mode RO + modes M_SCSI + field CBNUM 0xFF +} + +/* + * No Snoop Enable + */ +register NSENABLE { + address 0x091 + access_mode RW + modes M_CFG + field MSINSEN 0x20 + field OVLYNSEN 0x10 + field CMCNSEN 0x08 + field SGNSEN 0x04 + field DCH1NSEN 0x02 + field DCH0NSEN 0x01 +} + +/* + * Data Channel Receive Message 2 + */ +register DCHRXMSG2 { + address 0x092 + access_mode RO + modes M_DFF0, M_DFF1 + field MINDEX 0xFF +} + +/* + * CMC Recieve Message 2 + */ +register CMCRXMSG2 { + address 0x092 + access_mode RO + modes M_CCHAN + field MINDEX 0xFF +} + +/* + * Overlay Recieve Message 2 + */ +register OVLYRXMSG2 { + address 0x092 + access_mode RO + modes M_SCSI + field MINDEX 0xFF +} + +/* + * Outstanding Split Transactions + */ +register OST { + address 0x092 + access_mode RW + modes M_CFG +} + +/* + * Data Channel Receive Message 3 + */ +register DCHRXMSG3 { + address 0x093 + access_mode RO + modes M_DFF0, M_DFF1 + field MCLASS 0x0F +} + +/* + * CMC Recieve Message 3 + */ +register CMCRXMSG3 { + address 0x093 + access_mode RO + modes M_CCHAN + field MCLASS 0x0F +} + +/* + * Overlay Recieve Message 3 + */ +register OVLYRXMSG3 { + address 0x093 + access_mode RO + modes M_SCSI + field MCLASS 0x0F +} + +/* + * PCI-X Control + */ +register PCIXCTL { + address 0x093 + access_mode RW + modes M_CFG + field SERRPULSE 0x80 + field UNEXPSCIEN 0x20 + field SPLTSMADIS 0x10 + field SPLTSTADIS 0x08 + field SRSPDPEEN 0x04 + field TSCSERREN 0x02 + field CMPABCDIS 0x01 +} + +/* + * CMC Sequencer Byte Count + */ +register CMCSEQBCNT { + address 0x094 + access_mode RO + modes M_CCHAN +} + +/* + * Overlay Sequencer Byte Count + */ +register OVLYSEQBCNT { + address 0x094 + access_mode RO + modes M_SCSI +} + +/* + * Data Channel Sequencer Byte Count + */ +register DCHSEQBCNT { + address 0x094 + access_mode RO + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Data Channel Split Status 0 + */ +register DCHSPLTSTAT0 { + address 0x096 + access_mode RW + modes M_DFF0, M_DFF1 + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * CMC Split Status 0 + */ +register CMCSPLTSTAT0 { + address 0x096 + access_mode RW + modes M_CCHAN + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * Overlay Split Status 0 + */ +register OVLYSPLTSTAT0 { + address 0x096 + access_mode RW + modes M_SCSI + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * Data Channel Split Status 1 + */ +register DCHSPLTSTAT1 { + address 0x097 + access_mode RW + modes M_DFF0, M_DFF1 + field RXDATABUCKET 0x01 +} + +/* + * CMC Split Status 1 + */ +register CMCSPLTSTAT1 { + address 0x097 + access_mode RW + modes M_CCHAN + field RXDATABUCKET 0x01 +} + +/* + * Overlay Split Status 1 + */ +register OVLYSPLTSTAT1 { + address 0x097 + access_mode RW + modes M_SCSI + field RXDATABUCKET 0x01 +} + +/* + * S/G Receive Message 0 + */ +register SGRXMSG0 { + address 0x098 + access_mode RO + modes M_DFF0, M_DFF1 + field CDNUM 0xF8 + field CFNUM 0x07 +} + +/* + * S/G Receive Message 1 + */ +register SGRXMSG1 { + address 0x099 + access_mode RO + modes M_DFF0, M_DFF1 + field CBNUM 0xFF +} + +/* + * S/G Receive Message 2 + */ +register SGRXMSG2 { + address 0x09A + access_mode RO + modes M_DFF0, M_DFF1 + field MINDEX 0xFF +} + +/* + * S/G Receive Message 3 + */ +register SGRXMSG3 { + address 0x09B + access_mode RO + modes M_DFF0, M_DFF1 + field MCLASS 0x0F +} + +/* + * Slave Split Out Address 0 + */ +register SLVSPLTOUTADR0 { + address 0x098 + access_mode RO + modes M_SCSI + field LOWER_ADDR 0x7F +} + +/* + * Slave Split Out Address 1 + */ +register SLVSPLTOUTADR1 { + address 0x099 + access_mode RO + modes M_SCSI + field REQ_DNUM 0xF8 + field REQ_FNUM 0x07 +} + +/* + * Slave Split Out Address 2 + */ +register SLVSPLTOUTADR2 { + address 0x09A + access_mode RO + modes M_SCSI + field REQ_BNUM 0xFF +} + +/* + * Slave Split Out Address 3 + */ +register SLVSPLTOUTADR3 { + address 0x09B + access_mode RO + modes M_SCSI + field RLXORD 020 + field TAG_NUM 0x1F +} + +/* + * SG Sequencer Byte Count + */ +register SGSEQBCNT { + address 0x09C + access_mode RO + modes M_DFF0, M_DFF1 +} + +/* + * Slave Split Out Attribute 0 + */ +register SLVSPLTOUTATTR0 { + address 0x09C + access_mode RO + modes M_SCSI + field LOWER_BCNT 0xFF +} + +/* + * Slave Split Out Attribute 1 + */ +register SLVSPLTOUTATTR1 { + address 0x09D + access_mode RO + modes M_SCSI + field CMPLT_DNUM 0xF8 + field CMPLT_FNUM 0x07 +} + +/* + * Slave Split Out Attribute 2 + */ +register SLVSPLTOUTATTR2 { + address 0x09E + access_mode RO + size 2 + modes M_SCSI + field CMPLT_BNUM 0xFF +} +/* + * S/G Split Status 0 + */ +register SGSPLTSTAT0 { + address 0x09E + access_mode RW + modes M_DFF0, M_DFF1 + field STAETERM 0x80 + field SCBCERR 0x40 + field SCADERR 0x20 + field SCDATBUCKET 0x10 + field CNTNOTCMPLT 0x08 + field RXOVRUN 0x04 + field RXSCEMSG 0x02 + field RXSPLTRSP 0x01 +} + +/* + * S/G Split Status 1 + */ +register SGSPLTSTAT1 { + address 0x09F + access_mode RW + modes M_DFF0, M_DFF1 + field RXDATABUCKET 0x01 +} + +/* + * Special Function + */ +register SFUNCT { + address 0x09f + access_mode RW + modes M_CFG + field TEST_GROUP 0xF0 + field TEST_NUM 0x0F +} + +/* + * Data FIFO 0 PCI Status + */ +register DF0PCISTAT { + address 0x0A0 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * Data FIFO 1 PCI Status + */ +register DF1PCISTAT { + address 0x0A1 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * S/G PCI Status + */ +register SGPCISTAT { + address 0x0A2 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field DPR 0x01 +} + +/* + * CMC PCI Status + */ +register CMCPCISTAT { + address 0x0A3 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * Overlay PCI Status + */ +register OVLYPCISTAT { + address 0x0A4 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field SCAAPERR 0x08 + field RDPERR 0x04 + field DPR 0x01 +} + +/* + * PCI Status for MSI Master DMA Transfer + */ +register MSIPCISTAT { + address 0x0A6 + access_mode RW + modes M_CFG + field SSE 0x40 + field RMA 0x20 + field RTA 0x10 + field CLRPENDMSI 0x08 + field TWATERR 0x02 + field DPR 0x01 +} + +/* + * PCI Status for Target + */ +register TARGPCISTAT { + address 0x0A7 + access_mode RW + modes M_CFG + field DPE 0x80 + field SSE 0x40 + field STA 0x08 + field TWATERR 0x02 +} + +/* + * LQ Packet In + * The last LQ Packet recieved + */ +register LQIN { + address 0x020 + access_mode RW + size 20 + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * SCB Type Pointer + * SCB offset for Target Mode SCB type information + */ +register TYPEPTR { + address 0x020 + access_mode RW + modes M_CFG +} + +/* + * Queue Tag Pointer + * SCB offset to the Two Byte tag identifier used for target mode. + */ +register TAGPTR { + address 0x021 + access_mode RW + modes M_CFG +} + +/* + * Logical Unit Number Pointer + * SCB offset to the LSB (little endian) of the lun field. + */ +register LUNPTR { + address 0x022 + access_mode RW + modes M_CFG +} + +/* + * Data Length Pointer + * SCB offset for the 4 byte data length field in target mode. + */ +register DATALENPTR { + address 0x023 + access_mode RW + modes M_CFG +} + +/* + * Status Length Pointer + * SCB offset to the two byte status field in target SCBs. + */ +register STATLENPTR { + address 0x024 + access_mode RW + modes M_CFG +} + +/* + * Command Length Pointer + * Scb offset for the CDB length field in initiator SCBs. + */ +register CMDLENPTR { + address 0x025 + access_mode RW + modes M_CFG +} + +/* + * Task Attribute Pointer + * Scb offset for the byte field specifying the attribute byte + * to be used in command packets. + */ +register ATTRPTR { + address 0x026 + access_mode RW + modes M_CFG +} + +/* + * Task Management Flags Pointer + * Scb offset for the byte field specifying the attribute flags + * byte to be used in command packets. + */ +register FLAGPTR { + address 0x027 + access_mode RW + modes M_CFG +} + +/* + * Command Pointer + * Scb offset for the first byte in the CDB for initiator SCBs. + */ +register CMDPTR { + address 0x028 + access_mode RW + modes M_CFG +} + +/* + * Queue Next Pointer + * Scb offset for the 2 byte "next scb link". + */ +register QNEXTPTR { + address 0x029 + access_mode RW + modes M_CFG +} + +/* + * SCSI ID Pointer + * Scb offset to the value to place in the SCSIID register + * during target mode connections. + */ +register IDPTR { + address 0x02A + access_mode RW + modes M_CFG +} + +/* + * Command Aborted Byte Pointer + * Offset to the SCB flags field that includes the + * "SCB aborted" status bit. + */ +register ABRTBYTEPTR { + address 0x02B + access_mode RW + modes M_CFG +} + +/* + * Command Aborted Bit Pointer + * Bit offset in the SCB flags field for "SCB aborted" status. + */ +register ABRTBITPTR { + address 0x02C + access_mode RW + modes M_CFG +} + +/* + * Rev B or greater. + */ +register MAXCMDBYTES { + address 0x02D + access_mode RW + modes M_CFG +} + +/* + * Rev B or greater. + */ +register MAXCMD2RCV { + address 0x02E + access_mode RW + modes M_CFG +} + +/* + * Rev B or greater. + */ +register SHORTTHRESH { + address 0x02F + access_mode RW + modes M_CFG +} + +/* + * Logical Unit Number Length + * The length, in bytes, of the SCB lun field. + */ +register LUNLEN { + address 0x030 + access_mode RW + modes M_CFG + mask ILUNLEN 0x0F + mask TLUNLEN 0xF0 +} +const LUNLEN_SINGLE_LEVEL_LUN 0xF + +/* + * CDB Limit + * The size, in bytes, of the embedded CDB field in initator SCBs. + */ +register CDBLIMIT { + address 0x031 + access_mode RW + modes M_CFG +} + +/* + * Maximum Commands + * The maximum number of commands to issue during a + * single packetized connection. + */ +register MAXCMD { + address 0x032 + access_mode RW + modes M_CFG +} + +/* + * Maximum Command Counter + * The number of commands already sent during this connection + */ +register MAXCMDCNT { + address 0x033 + access_mode RW + modes M_CFG +} + +/* + * LQ Packet Reserved Bytes + * The bytes to be sent in the currently reserved fileds + * of all LQ packets. + */ +register LQRSVD01 { + address 0x034 + access_mode RW + modes M_SCSI +} +register LQRSVD16 { + address 0x035 + access_mode RW + modes M_SCSI +} +register LQRSVD17 { + address 0x036 + access_mode RW + modes M_SCSI +} + +/* + * Command Reserved 0 + * The byte to be sent for the reserved byte 0 of + * outgoing command packets. + */ +register CMDRSVD0 { + address 0x037 + access_mode RW + modes M_CFG +} + +/* + * LQ Manager Control 0 + */ +register LQCTL0 { + address 0x038 + access_mode RW + modes M_CFG + field LQITARGCLT 0xC0 + field LQIINITGCLT 0x30 + field LQ0TARGCLT 0x0C + field LQ0INITGCLT 0x03 +} + +/* + * LQ Manager Control 1 + */ +register LQCTL1 { + address 0x038 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field PCI2PCI 0x04 + field SINGLECMD 0x02 + field ABORTPENDING 0x01 +} + +/* + * LQ Manager Control 2 + */ +register LQCTL2 { + address 0x039 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field LQIRETRY 0x80 + field LQICONTINUE 0x40 + field LQITOIDLE 0x20 + field LQIPAUSE 0x10 + field LQORETRY 0x08 + field LQOCONTINUE 0x04 + field LQOTOIDLE 0x02 + field LQOPAUSE 0x01 +} + +/* + * SCSI RAM BIST0 + */ +register SCSBIST0 { + address 0x039 + access_mode RW + modes M_CFG + field GSBISTERR 0x40 + field GSBISTDONE 0x20 + field GSBISTRUN 0x10 + field OSBISTERR 0x04 + field OSBISTDONE 0x02 + field OSBISTRUN 0x01 +} + +/* + * SCSI Sequence Control0 + */ +register SCSISEQ0 { + address 0x03A + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field TEMODEO 0x80 + field ENSELO 0x40 + field ENARBO 0x20 + field FORCEBUSFREE 0x10 + field SCSIRSTO 0x01 +} + +/* + * SCSI RAM BIST 1 + */ +register SCSBIST1 { + address 0x03A + access_mode RW + modes M_CFG + field NTBISTERR 0x04 + field NTBISTDONE 0x02 + field NTBISTRUN 0x01 +} + +/* + * SCSI Sequence Control 1 + */ +register SCSISEQ1 { + address 0x03B + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field MANUALCTL 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field MANUALP 0x0C + field ENAUTOATNP 0x02 + field ALTSTIM 0x01 +} + +/* + * SCSI Transfer Control 0 + */ +register SXFRCTL0 { + address 0x03C + access_mode RW + modes M_SCSI + field DFON 0x80 + field DFPEXP 0x40 + field BIOSCANCELEN 0x10 + field SPIOEN 0x08 +} + +/* + * SCSI Transfer Control 1 + */ +register SXFRCTL1 { + address 0x03D + access_mode RW + modes M_SCSI + field BITBUCKET 0x80 + field ENSACHK 0x40 + field ENSPCHK 0x20 + field STIMESEL 0x18 + field ENSTIMER 0x04 + field ACTNEGEN 0x02 + field STPWEN 0x01 +} + +/* + * SCSI Transfer Control 2 + */ +register SXFRCTL2 { + address 0x03E + access_mode RW + modes M_SCSI + field AUTORSTDIS 0x10 + field CMDDMAEN 0x08 + field ASU 0x07 +} + +/* + * SCSI Bus Initiator IDs + * Bitmask of observed initiators on the bus. + */ +register BUSINITID { + address 0x03C + access_mode RW + modes M_CFG + size 2 +} + +/* + * Data Length Counters + * Packet byte counter. + */ +register DLCOUNT { + address 0x03C + access_mode RW + modes M_DFF0, M_DFF1 + size 3 +} + +/* + * Data FIFO Status + */ +register DFFSTAT { + address 0x03F + access_mode RW + modes M_SCSI + field FIFO1FREE 0x20 + field FIFO0FREE 0x10 + /* + * On the B, this enum only works + * in the read direction. For writes, + * you must use the B version of the + * CURRFIFO_0 definition which is defined + * as a constant outside of this register + * definition to avoid confusing the + * register pretty printing code. + */ + enum CURRFIFO 0x03 { + CURRFIFO_0, + CURRFIFO_1, + CURRFIFO_NONE 0x3 + } +} + +const B_CURRFIFO_0 0x2 + +/* + * SCSI Bus Target IDs + * Bitmask of observed targets on the bus. + */ +register BUSTARGID { + address 0x03E + access_mode RW + modes M_CFG + size 2 +} + +/* + * SCSI Control Signal Out + */ +register SCSISIGO { + address 0x040 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field CDO 0x80 + field IOO 0x40 + field MSGO 0x20 + field ATNO 0x10 + field SELO 0x08 + field BSYO 0x04 + field REQO 0x02 + field ACKO 0x01 +/* + * Possible phases to write into SCSISIG0 + */ + enum PHASE_MASK CDO|IOO|MSGO { + P_DATAOUT 0x0, + P_DATAIN IOO, + P_DATAOUT_DT P_DATAOUT|MSGO, + P_DATAIN_DT P_DATAIN|MSGO, + P_COMMAND CDO, + P_MESGOUT CDO|MSGO, + P_STATUS CDO|IOO, + P_MESGIN CDO|IOO|MSGO + } +} + +register SCSISIGI { + address 0x041 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 + field ATNI 0x10 + field SELI 0x08 + field BSYI 0x04 + field REQI 0x02 + field ACKI 0x01 +/* + * Possible phases in SCSISIGI + */ + enum PHASE_MASK CDO|IOO|MSGO { + P_DATAOUT 0x0, + P_DATAIN IOO, + P_DATAOUT_DT P_DATAOUT|MSGO, + P_DATAIN_DT P_DATAIN|MSGO, + P_COMMAND CDO, + P_MESGOUT CDO|MSGO, + P_STATUS CDO|IOO, + P_MESGIN CDO|IOO|MSGO + } +} + +/* + * Multiple Target IDs + * Bitmask of ids to respond as a target. + */ +register MULTARGID { + address 0x040 + access_mode RW + modes M_CFG + size 2 +} + +/* + * SCSI Phase + */ +register SCSIPHASE { + address 0x042 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field STATUS_PHASE 0x20 + field COMMAND_PHASE 0x10 + field MSG_IN_PHASE 0x08 + field MSG_OUT_PHASE 0x04 + field DATA_PHASE_MASK 0x03 { + DATA_OUT_PHASE 0x01, + DATA_IN_PHASE 0x02 + } +} + +/* + * SCSI Data 0 Image + */ +register SCSIDAT0_IMG { + address 0x043 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * SCSI Latched Data + */ +register SCSIDAT { + address 0x044 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + size 2 +} + +/* + * SCSI Data Bus + */ +register SCSIBUS { + address 0x046 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + size 2 +} + +/* + * Target ID In + */ +register TARGIDIN { + address 0x048 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field CLKOUT 0x80 + field TARGID 0x0F +} + +/* + * Selection/Reselection ID + * Upper four bits are the device id. The ONEBIT is set when the re/selecting + * device did not set its own ID. + */ +register SELID { + address 0x049 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field SELID_MASK 0xf0 + field ONEBIT 0x08 +} + +/* + * SCSI Block Control + * Controls Bus type and channel selection. SELWIDE allows for the + * coexistence of 8bit and 16bit devices on a wide bus. + */ +register SBLKCTL { + address 0x04A + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field DIAGLEDEN 0x80 + field DIAGLEDON 0x40 + field ENAB40 0x08 /* LVD transceiver active */ + field ENAB20 0x04 /* SE/HVD transceiver active */ + field SELWIDE 0x02 +} + +/* + * Option Mode + */ +register OPTIONMODE { + address 0x04A + access_mode RW + modes M_CFG + field BIOSCANCTL 0x80 + field AUTOACKEN 0x40 + field BIASCANCTL 0x20 + field BUSFREEREV 0x10 + field ENDGFORMCHK 0x04 + field AUTO_MSGOUT_DE 0x02 + mask OPTIONMODE_DEFAULTS AUTO_MSGOUT_DE +} + +/* + * SCSI Status 0 + */ +register SSTAT0 { + address 0x04B + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field TARGET 0x80 /* Board acting as target */ + field SELDO 0x40 /* Selection Done */ + field SELDI 0x20 /* Board has been selected */ + field SELINGO 0x10 /* Selection In Progress */ + field IOERR 0x08 /* LVD Tranceiver mode changed */ + field OVERRUN 0x04 /* SCSI Offset overrun detected */ + field SPIORDY 0x02 /* SCSI PIO Ready */ + field ARBDO 0x01 /* Arbitration Done Out */ +} + +/* + * Clear SCSI Interrupt 0 + * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT0. + */ +register CLRSINT0 { + address 0x04B + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRSELDO 0x40 + field CLRSELDI 0x20 + field CLRSELINGO 0x10 + field CLRIOERR 0x08 + field CLROVERRUN 0x04 + field CLRSPIORDY 0x02 + field CLRARBDO 0x01 +} + +/* + * SCSI Interrupt Mode 0 + * Setting any bit will enable the corresponding function + * in SIMODE0 to interrupt via the IRQ pin. + */ +register SIMODE0 { + address 0x04B + access_mode RW + modes M_CFG + field ENSELDO 0x40 + field ENSELDI 0x20 + field ENSELINGO 0x10 + field ENIOERR 0x08 + field ENOVERRUN 0x04 + field ENSPIORDY 0x02 + field ENARBDO 0x01 +} + +/* + * SCSI Status 1 + */ +register SSTAT1 { + address 0x04C + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field SELTO 0x80 + field ATNTARG 0x40 + field SCSIRSTI 0x20 + field PHASEMIS 0x10 + field BUSFREE 0x08 + field SCSIPERR 0x04 + field STRB2FAST 0x02 + field REQINIT 0x01 +} + +/* + * Clear SCSI Interrupt 1 + * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1. + */ +register CLRSINT1 { + address 0x04C + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRSELTIMEO 0x80 + field CLRATNO 0x40 + field CLRSCSIRSTI 0x20 + field CLRBUSFREE 0x08 + field CLRSCSIPERR 0x04 + field CLRSTRB2FAST 0x02 + field CLRREQINIT 0x01 +} + +/* + * SCSI Status 2 + */ +register SSTAT2 { + address 0x04d + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field BUSFREETIME 0xc0 { + BUSFREE_LQO 0x40, + BUSFREE_DFF0 0x80, + BUSFREE_DFF1 0xC0 + } + field NONPACKREQ 0x20 + field EXP_ACTIVE 0x10 /* SCSI Expander Active */ + field BSYX 0x08 /* Busy Expander */ + field WIDE_RES 0x04 /* Modes 0 and 1 only */ + field SDONE 0x02 /* Modes 0 and 1 only */ + field DMADONE 0x01 /* Modes 0 and 1 only */ +} + +/* + * Clear SCSI Interrupt 2 + */ +register CLRSINT2 { + address 0x04D + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRNONPACKREQ 0x20 + field CLRWIDE_RES 0x04 /* Modes 0 and 1 only */ + field CLRSDONE 0x02 /* Modes 0 and 1 only */ + field CLRDMADONE 0x01 /* Modes 0 and 1 only */ +} + +/* + * SCSI Interrupt Mode 2 + */ +register SIMODE2 { + address 0x04D + access_mode RW + modes M_CFG + field ENWIDE_RES 0x04 + field ENSDONE 0x02 + field ENDMADONE 0x01 +} + +/* + * Physical Error Diagnosis + */ +register PERRDIAG { + address 0x04E + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field HIZERO 0x80 + field HIPERR 0x40 + field PREVPHASE 0x20 + field PARITYERR 0x10 + field AIPERR 0x08 + field CRCERR 0x04 + field DGFORMERR 0x02 + field DTERR 0x01 +} + +/* + * LQI Manager Current State + */ +register LQISTATE { + address 0x04E + access_mode RO + modes M_CFG +} + +/* + * SCSI Offset Count + */ +register SOFFCNT { + address 0x04F + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * LQO Manager Current State + */ +register LQOSTATE { + address 0x04F + access_mode RO + modes M_CFG +} + +/* + * LQI Manager Status + */ +register LQISTAT0 { + address 0x050 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQIATNQAS 0x20 + field LQICRCT1 0x10 + field LQICRCT2 0x08 + field LQIBADLQT 0x04 + field LQIATNLQ 0x02 + field LQIATNCMD 0x01 +} + +/* + * Clear LQI Interrupts 0 + */ +register CLRLQIINT0 { + address 0x050 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQIATNQAS 0x20 + field CLRLQICRCT1 0x10 + field CLRLQICRCT2 0x08 + field CLRLQIBADLQT 0x04 + field CLRLQIATNLQ 0x02 + field CLRLQIATNCMD 0x01 +} + +/* + * LQI Manager Interrupt Mode 0 + */ +register LQIMODE0 { + address 0x050 + access_mode RW + modes M_CFG + field ENLQIATNQASK 0x20 + field ENLQICRCT1 0x10 + field ENLQICRCT2 0x08 + field ENLQIBADLQT 0x04 + field ENLQIATNLQ 0x02 + field ENLQIATNCMD 0x01 +} + +/* + * LQI Manager Status 1 + */ +register LQISTAT1 { + address 0x051 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQIPHASE_LQ 0x80 + field LQIPHASE_NLQ 0x40 + field LQIABORT 0x20 + field LQICRCI_LQ 0x10 + field LQICRCI_NLQ 0x08 + field LQIBADLQI 0x04 + field LQIOVERI_LQ 0x02 + field LQIOVERI_NLQ 0x01 +} + +/* + * Clear LQI Manager Interrupts1 + */ +register CLRLQIINT1 { + address 0x051 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQIPHASE_LQ 0x80 + field CLRLQIPHASE_NLQ 0x40 + field CLRLIQABORT 0x20 + field CLRLQICRCI_LQ 0x10 + field CLRLQICRCI_NLQ 0x08 + field CLRLQIBADLQI 0x04 + field CLRLQIOVERI_LQ 0x02 + field CLRLQIOVERI_NLQ 0x01 +} + +/* + * LQI Manager Interrupt Mode 1 + */ +register LQIMODE1 { + address 0x051 + access_mode RW + modes M_CFG + field ENLQIPHASE_LQ 0x80 /* LQIPHASE1 */ + field ENLQIPHASE_NLQ 0x40 /* LQIPHASE2 */ + field ENLIQABORT 0x20 + field ENLQICRCI_LQ 0x10 /* LQICRCI1 */ + field ENLQICRCI_NLQ 0x08 /* LQICRCI2 */ + field ENLQIBADLQI 0x04 + field ENLQIOVERI_LQ 0x02 /* LQIOVERI1 */ + field ENLQIOVERI_NLQ 0x01 /* LQIOVERI2 */ +} + +/* + * LQI Manager Status 2 + */ +register LQISTAT2 { + address 0x052 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field PACKETIZED 0x80 + field LQIPHASE_OUTPKT 0x40 + field LQIWORKONLQ 0x20 + field LQIWAITFIFO 0x10 + field LQISTOPPKT 0x08 + field LQISTOPLQ 0x04 + field LQISTOPCMD 0x02 + field LQIGSAVAIL 0x01 +} + +/* + * SCSI Status 3 + */ +register SSTAT3 { + address 0x053 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field NTRAMPERR 0x02 + field OSRAMPERR 0x01 +} + +/* + * Clear SCSI Status 3 + */ +register CLRSINT3 { + address 0x053 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRNTRAMPERR 0x02 + field CLROSRAMPERR 0x01 +} + +/* + * SCSI Interrupt Mode 3 + */ +register SIMODE3 { + address 0x053 + access_mode RW + modes M_CFG + field ENNTRAMPERR 0x02 + field ENOSRAMPERR 0x01 +} + +/* + * LQO Manager Status 0 + */ +register LQOSTAT0 { + address 0x054 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQOTARGSCBPERR 0x10 + field LQOSTOPT2 0x08 + field LQOATNLQ 0x04 + field LQOATNPKT 0x02 + field LQOTCRC 0x01 +} + +/* + * Clear LQO Manager interrupt 0 + */ +register CLRLQOINT0 { + address 0x054 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQOTARGSCBPERR 0x10 + field CLRLQOSTOPT2 0x08 + field CLRLQOATNLQ 0x04 + field CLRLQOATNPKT 0x02 + field CLRLQOTCRC 0x01 +} + +/* + * LQO Manager Interrupt Mode 0 + */ +register LQOMODE0 { + address 0x054 + access_mode RW + modes M_CFG + field ENLQOTARGSCBPERR 0x10 + field ENLQOSTOPT2 0x08 + field ENLQOATNLQ 0x04 + field ENLQOATNPKT 0x02 + field ENLQOTCRC 0x01 +} + +/* + * LQO Manager Status 1 + */ +register LQOSTAT1 { + address 0x055 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQOINITSCBPERR 0x10 + field LQOSTOPI2 0x08 + field LQOBADQAS 0x04 + field LQOBUSFREE 0x02 + field LQOPHACHGINPKT 0x01 +} + +/* + * Clear LOQ Interrupt 1 + */ +register CLRLQOINT1 { + address 0x055 + access_mode WO + modes M_DFF0, M_DFF1, M_SCSI + field CLRLQOINITSCBPERR 0x10 + field CLRLQOSTOPI2 0x08 + field CLRLQOBADQAS 0x04 + field CLRLQOBUSFREE 0x02 + field CLRLQOPHACHGINPKT 0x01 +} + +/* + * LQO Manager Interrupt Mode 1 + */ +register LQOMODE1 { + address 0x055 + access_mode RW + modes M_CFG + field ENLQOINITSCBPERR 0x10 + field ENLQOSTOPI2 0x08 + field ENLQOBADQAS 0x04 + field ENLQOBUSFREE 0x02 + field ENLQOPHACHGINPKT 0x01 +} + +/* + * LQO Manager Status 2 + */ +register LQOSTAT2 { + address 0x056 + access_mode RO + modes M_DFF0, M_DFF1, M_SCSI + field LQOPKT 0xE0 + field LQOWAITFIFO 0x10 + field LQOPHACHGOUTPKT 0x02 /* outside of packet boundaries. */ + field LQOSTOP0 0x01 /* Stopped after sending all packets */ +} + +/* + * Output Synchronizer Space Count + */ +register OS_SPACE_CNT { + address 0x056 + access_mode RO + modes M_CFG +} + +/* + * SCSI Interrupt Mode 1 + * Setting any bit will enable the corresponding function + * in SIMODE1 to interrupt via the IRQ pin. + */ +register SIMODE1 { + address 0x057 + access_mode RW + modes M_DFF0, M_DFF1, M_SCSI + field ENSELTIMO 0x80 + field ENATNTARG 0x40 + field ENSCSIRST 0x20 + field ENPHASEMIS 0x10 + field ENBUSFREE 0x08 + field ENSCSIPERR 0x04 + field ENSTRB2FAST 0x02 + field ENREQINIT 0x01 +} + +/* + * Good Status FIFO + */ +register GSFIFO { + address 0x058 + access_mode RO + size 2 + modes M_DFF0, M_DFF1, M_SCSI +} + +/* + * Data FIFO SCSI Transfer Control + */ +register DFFSXFRCTL { + address 0x05A + access_mode RW + modes M_DFF0, M_DFF1 + field DFFBITBUCKET 0x08 + field CLRSHCNT 0x04 + field CLRCHN 0x02 + field RSTCHN 0x01 +} + +/* + * Next SCSI Control Block + */ +register NEXTSCB { + address 0x05A + access_mode RW + size 2 + modes M_SCSI +} + +/* Rev B only. */ +register LQOSCSCTL { + address 0x05A + access_mode RW + size 1 + modes M_CFG + field LQOH2A_VERSION 0x80 + field LQONOCHKOVER 0x01 +} + +/* + * SEQ Interrupts + */ +register SEQINTSRC { + address 0x05B + access_mode RO + modes M_DFF0, M_DFF1 + field CTXTDONE 0x40 + field SAVEPTRS 0x20 + field CFG4DATA 0x10 + field CFG4ISTAT 0x08 + field CFG4TSTAT 0x04 + field CFG4ICMD 0x02 + field CFG4TCMD 0x01 +} + +/* + * Clear Arp Interrupts + */ +register CLRSEQINTSRC { + address 0x05B + access_mode WO + modes M_DFF0, M_DFF1 + field CLRCTXTDONE 0x40 + field CLRSAVEPTRS 0x20 + field CLRCFG4DATA 0x10 + field CLRCFG4ISTAT 0x08 + field CLRCFG4TSTAT 0x04 + field CLRCFG4ICMD 0x02 + field CLRCFG4TCMD 0x01 +} + +/* + * SEQ Interrupt Enabled (Shared) + */ +register SEQIMODE { + address 0x05C + access_mode RW + modes M_DFF0, M_DFF1 + field ENCTXTDONE 0x40 + field ENSAVEPTRS 0x20 + field ENCFG4DATA 0x10 + field ENCFG4ISTAT 0x08 + field ENCFG4TSTAT 0x04 + field ENCFG4ICMD 0x02 + field ENCFG4TCMD 0x01 +} + +/* + * Current SCSI Control Block + */ +register CURRSCB { + address 0x05C + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Data FIFO Status + */ +register MDFFSTAT { + address 0x05D + access_mode RO + modes M_DFF0, M_DFF1 + field SHCNTNEGATIVE 0x40 /* Rev B or higher */ + field SHCNTMINUS1 0x20 /* Rev B or higher */ + field LASTSDONE 0x10 + field SHVALID 0x08 + field DLZERO 0x04 /* FIFO data ends on packet boundary. */ + field DATAINFIFO 0x02 + field FIFOFREE 0x01 +} + +/* + * CRC Control + */ +register CRCCONTROL { + address 0x05d + access_mode RW + modes M_CFG + field CRCVALCHKEN 0x40 +} + +/* + * SCSI Test Control + */ +register SCSITEST { + address 0x05E + access_mode RW + modes M_CFG + field CNTRTEST 0x08 + field SEL_TXPLL_DEBUG 0x04 +} + +/* + * Data FIFO Queue Tag + */ +register DFFTAG { + address 0x05E + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Last SCSI Control Block + */ +register LASTSCB { + address 0x05E + access_mode RW + size 2 + modes M_SCSI +} + +/* + * SCSI I/O Cell Power-down Control + */ +register IOPDNCTL { + address 0x05F + access_mode RW + modes M_CFG + field DISABLE_OE 0x80 + field PDN_IDIST 0x04 + field PDN_DIFFSENSE 0x01 +} + +/* + * Shaddow Host Address. + */ +register SHADDR { + address 0x060 + access_mode RO + size 8 + modes M_DFF0, M_DFF1 +} + +/* + * Data Group CRC Interval. + */ +register DGRPCRCI { + address 0x060 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Data Transfer Negotiation Address + */ +register NEGOADDR { + address 0x060 + access_mode RW + modes M_SCSI +} + +/* + * Data Transfer Negotiation Data - Period Byte + */ +register NEGPERIOD { + address 0x061 + access_mode RW + modes M_SCSI +} + +/* + * Packetized CRC Interval + */ +register PACKCRCI { + address 0x062 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Data Transfer Negotiation Data - Offset Byte + */ +register NEGOFFSET { + address 0x062 + access_mode RW + modes M_SCSI +} + +/* + * Data Transfer Negotiation Data - PPR Options + */ +register NEGPPROPTS { + address 0x063 + access_mode RW + modes M_SCSI + field PPROPT_PACE 0x08 + field PPROPT_QAS 0x04 + field PPROPT_DT 0x02 + field PPROPT_IUT 0x01 +} + +/* + * Data Transfer Negotiation Data - Connection Options + */ +register NEGCONOPTS { + address 0x064 + access_mode RW + modes M_SCSI + field ENSNAPSHOT 0x40 + field RTI_WRTDIS 0x20 + field RTI_OVRDTRN 0x10 + field ENSLOWCRC 0x08 + field ENAUTOATNI 0x04 + field ENAUTOATNO 0x02 + field WIDEXFER 0x01 +} + +/* + * Negotiation Table Annex Column Index. + */ +register ANNEXCOL { + address 0x065 + access_mode RW + modes M_SCSI +} + +register SCSCHKN { + address 0x066 + access_mode RW + modes M_CFG + field STSELSKIDDIS 0x40 + field CURRFIFODEF 0x20 + field WIDERESEN 0x10 + field SDONEMSKDIS 0x08 + field DFFACTCLR 0x04 + field SHVALIDSTDIS 0x02 + field LSTSGCLRDIS 0x01 +} + +const AHD_ANNEXCOL_PER_DEV0 4 +const AHD_NUM_PER_DEV_ANNEXCOLS 4 +const AHD_ANNEXCOL_PRECOMP_SLEW 4 +const AHD_PRECOMP_MASK 0x07 +const AHD_PRECOMP_SHIFT 0 +const AHD_PRECOMP_CUTBACK_17 0x04 +const AHD_PRECOMP_CUTBACK_29 0x06 +const AHD_PRECOMP_CUTBACK_37 0x07 +const AHD_SLEWRATE_MASK 0x78 +const AHD_SLEWRATE_SHIFT 3 +/* + * Rev A has only a single bit (high bit of field) of slew adjustment. + * Rev B has 4 bits. The current default happens to be the same for both. + */ +const AHD_SLEWRATE_DEF_REVA 0x08 +const AHD_SLEWRATE_DEF_REVB 0x08 + +/* Rev A does not have any amplitude setting. */ +const AHD_ANNEXCOL_AMPLITUDE 6 +const AHD_AMPLITUDE_MASK 0x7 +const AHD_AMPLITUDE_SHIFT 0 +const AHD_AMPLITUDE_DEF 0x7 + +/* + * Negotiation Table Annex Data Port. + */ +register ANNEXDAT { + address 0x066 + access_mode RW + modes M_SCSI +} + +/* + * Initiator's Own Id. + * The SCSI ID to use for Selection Out and seen during a reselection.. + */ +register IOWNID { + address 0x067 + access_mode RW + modes M_SCSI +} + +/* + * 960MHz Phase-Locked Loop Control 0 + */ +register PLL960CTL0 { + address 0x068 + access_mode RW + modes M_CFG + field PLL_VCOSEL 0x80 + field PLL_PWDN 0x40 + field PLL_NS 0x30 + field PLL_ENLUD 0x08 + field PLL_ENLPF 0x04 + field PLL_DLPF 0x02 + field PLL_ENFBM 0x01 +} + +/* + * Target Own Id + */ +register TOWNID { + address 0x069 + access_mode RW + modes M_SCSI +} + +/* + * 960MHz Phase-Locked Loop Control 1 + */ +register PLL960CTL1 { + address 0x069 + access_mode RW + modes M_CFG + field PLL_CNTEN 0x80 + field PLL_CNTCLR 0x40 + field PLL_RST 0x01 +} + +/* + * Expander Signature + */ +register XSIG { + address 0x06A + access_mode RW + modes M_SCSI +} + +/* + * Shadow Byte Count + */ +register SHCNT { + address 0x068 + access_mode RW + size 3 + modes M_DFF0, M_DFF1 +} + +/* + * Selection Out ID + */ +register SELOID { + address 0x06B + access_mode RW + modes M_SCSI +} + +/* + * 960-MHz Phase-Locked Loop Test Count + */ +register PLL960CNT0 { + address 0x06A + access_mode RO + size 2 + modes M_CFG +} + +/* + * 400-MHz Phase-Locked Loop Control 0 + */ +register PLL400CTL0 { + address 0x06C + access_mode RW + modes M_CFG + field PLL_VCOSEL 0x80 + field PLL_PWDN 0x40 + field PLL_NS 0x30 + field PLL_ENLUD 0x08 + field PLL_ENLPF 0x04 + field PLL_DLPF 0x02 + field PLL_ENFBM 0x01 +} + +/* + * Arbitration Fairness + */ +register FAIRNESS { + address 0x06C + access_mode RW + size 2 + modes M_SCSI +} + +/* + * 400-MHz Phase-Locked Loop Control 1 + */ +register PLL400CTL1 { + address 0x06D + access_mode RW + modes M_CFG + field PLL_CNTEN 0x80 + field PLL_CNTCLR 0x40 + field PLL_RST 0x01 +} + +/* + * Arbitration Unfairness + */ +register UNFAIRNESS { + address 0x06E + access_mode RW + size 2 + modes M_SCSI +} + +/* + * 400-MHz Phase-Locked Loop Test Count + */ +register PLL400CNT0 { + address 0x06E + access_mode RO + size 2 + modes M_CFG +} + +/* + * SCB Page Pointer + */ +register SCBPTR { + address 0x0A8 + access_mode RW + size 2 + modes M_DFF0, M_DFF1, M_CCHAN, M_SCSI +} + +/* + * CMC SCB Array Count + * Number of bytes to transfer between CMC SCB memory and SCBRAM. + * Transfers must be 8byte aligned and sized. + */ +register CCSCBACNT { + address 0x0AB + access_mode RW + modes M_CCHAN +} + +/* + * SCB Autopointer + * SCB-Next Address Snooping logic. When an SCB is transferred to + * the card, the next SCB address to be used by the CMC array can + * be autoloaded from that transfer. + */ +register SCBAUTOPTR { + address 0x0AB + access_mode RW + modes M_CFG + field AUSCBPTR_EN 0x80 + field SCBPTR_ADDR 0x38 + field SCBPTR_OFF 0x07 +} + +/* + * CMC SG Ram Address Pointer + */ +register CCSGADDR { + address 0x0AC + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * CMC SCB RAM Address Pointer + */ +register CCSCBADDR { + address 0x0AC + access_mode RW + modes M_CCHAN +} + +/* + * CMC SCB Ram Back-up Address Pointer + * Indicates the true stop location of transfers halted prior + * to SCBHCNT going to 0. + */ +register CCSCBADR_BK { + address 0x0AC + access_mode RO + modes M_CFG +} + +/* + * CMC SG Control + */ +register CCSGCTL { + address 0x0AD + access_mode RW + modes M_DFF0, M_DFF1 + field CCSGDONE 0x80 + field SG_CACHE_AVAIL 0x10 + field CCSGENACK 0x08 + mask CCSGEN 0x0C + field SG_FETCH_REQ 0x02 + field CCSGRESET 0x01 +} + +/* + * CMD SCB Control + */ +register CCSCBCTL { + address 0x0AD + access_mode RW + modes M_CCHAN + field CCSCBDONE 0x80 + field ARRDONE 0x40 + field CCARREN 0x10 + field CCSCBEN 0x08 + field CCSCBDIR 0x04 + field CCSCBRESET 0x01 +} + +/* + * CMC Ram BIST + */ +register CMC_RAMBIST { + address 0x0AD + access_mode RW + modes M_CFG + field SG_ELEMENT_SIZE 0x80 + field SCBRAMBIST_FAIL 0x40 + field SG_BIST_FAIL 0x20 + field SG_BIST_EN 0x10 + field CMC_BUFFER_BIST_FAIL 0x02 + field CMC_BUFFER_BIST_EN 0x01 +} + +/* + * CMC SG RAM Data Port + */ +register CCSGRAM { + address 0x0B0 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * CMC SCB RAM Data Port + */ +register CCSCBRAM { + address 0x0B0 + access_mode RW + modes M_CCHAN +} + +/* + * Flex DMA Address. + */ +register FLEXADR { + address 0x0B0 + access_mode RW + size 3 + modes M_SCSI +} + +/* + * Flex DMA Byte Count + */ +register FLEXCNT { + address 0x0B3 + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Flex DMA Status + */ +register FLEXDMASTAT { + address 0x0B5 + access_mode RW + modes M_SCSI + field FLEXDMAERR 0x02 + field FLEXDMADONE 0x01 +} + +/* + * Flex DMA Data Port + */ +register FLEXDATA { + address 0x0B6 + access_mode RW + modes M_SCSI +} + +/* + * Board Data + */ +register BRDDAT { + address 0x0B8 + access_mode RW + modes M_SCSI +} + +/* + * Board Control + */ +register BRDCTL { + address 0x0B9 + access_mode RW + modes M_SCSI + field FLXARBACK 0x80 + field FLXARBREQ 0x40 + field BRDADDR 0x38 + field BRDEN 0x04 + field BRDRW 0x02 + field BRDSTB 0x01 +} + +/* + * Serial EEPROM Address + */ +register SEEADR { + address 0x0BA + access_mode RW + modes M_SCSI +} + +/* + * Serial EEPROM Data + */ +register SEEDAT { + address 0x0BC + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Serial EEPROM Status + */ +register SEESTAT { + address 0x0BE + access_mode RO + modes M_SCSI + field INIT_DONE 0x80 + field SEEOPCODE 0x70 + field LDALTID_L 0x08 + field SEEARBACK 0x04 + field SEEBUSY 0x02 + field SEESTART 0x01 +} + +/* + * Serial EEPROM Control + */ +register SEECTL { + address 0x0BE + access_mode RW + modes M_SCSI + field SEEOPCODE 0x70 { + SEEOP_ERASE 0x70, + SEEOP_READ 0x60, + SEEOP_WRITE 0x50, + /* + * The following four commands use special + * addresses for differentiation. + */ + SEEOP_ERAL 0x40 + } + mask SEEOP_EWEN 0x40 + mask SEEOP_WALL 0x40 + mask SEEOP_EWDS 0x40 + field SEERST 0x02 + field SEESTART 0x01 +} + +const SEEOP_ERAL_ADDR 0x80 +const SEEOP_EWEN_ADDR 0xC0 +const SEEOP_WRAL_ADDR 0x40 +const SEEOP_EWDS_ADDR 0x00 + +/* + * SCB Counter + */ +register SCBCNT { + address 0x0BF + access_mode RW + modes M_SCSI +} + +/* + * Data FIFO Write Address + * Pointer to the next QWD location to be written to the data FIFO. + */ +register DFWADDR { + address 0x0C0 + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * DSP Filter Control + */ +register DSPFLTRCTL { + address 0x0C0 + access_mode RW + modes M_CFG + field FLTRDISABLE 0x20 + field EDGESENSE 0x10 + field DSPFCNTSEL 0x0F +} + +/* + * DSP Data Channel Control + */ +register DSPDATACTL { + address 0x0C1 + access_mode RW + modes M_CFG + field BYPASSENAB 0x80 + field DESQDIS 0x10 + field RCVROFFSTDIS 0x04 + field XMITOFFSTDIS 0x02 +} + +/* + * Data FIFO Read Address + * Pointer to the next QWD location to be read from the data FIFO. + */ +register DFRADDR { + address 0x0C2 + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * DSP REQ Control + */ +register DSPREQCTL { + address 0x0C2 + access_mode RW + modes M_CFG + field MANREQCTL 0xC0 + field MANREQDLY 0x3F +} + +/* + * DSP ACK Control + */ +register DSPACKCTL { + address 0x0C3 + access_mode RW + modes M_CFG + field MANACKCTL 0xC0 + field MANACKDLY 0x3F +} + +/* + * Data FIFO Data + * Read/Write byte port into the data FIFO. The read and write + * FIFO pointers increment with each read and write respectively + * to this port. + */ +register DFDAT { + address 0x0C4 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * DSP Channel Select + */ +register DSPSELECT { + address 0x0C4 + access_mode RW + modes M_CFG + field AUTOINCEN 0x80 + field DSPSEL 0x1F +} + +const NUMDSPS 0x14 + +/* + * Write Bias Control + */ +register WRTBIASCTL { + address 0x0C5 + access_mode WO + modes M_CFG + field AUTOXBCDIS 0x80 + field XMITMANVAL 0x3F +} + +/* + * Currently the WRTBIASCTL is the same as the default. + */ +const WRTBIASCTL_HP_DEFAULT 0x0 + +/* + * Receiver Bias Control + */ +register RCVRBIOSCTL { + address 0x0C6 + access_mode WO + modes M_CFG + field AUTORBCDIS 0x80 + field RCVRMANVAL 0x3F +} + +/* + * Write Bias Calculator + */ +register WRTBIASCALC { + address 0x0C7 + access_mode RO + modes M_CFG +} + +/* + * Data FIFO Pointers + * Contains the byte offset from DFWADDR and DWRADDR to the current + * FIFO write/read locations. + */ +register DFPTRS { + address 0x0C8 + access_mode RW + modes M_DFF0, M_DFF1 +} + +/* + * Receiver Bias Calculator + */ +register RCVRBIASCALC { + address 0x0C8 + access_mode RO + modes M_CFG +} + +/* + * Data FIFO Backup Read Pointer + * Contains the data FIFO address to be restored if the last + * data accessed from the data FIFO was not transferred successfully. + */ +register DFBKPTR { + address 0x0C9 + access_mode RW + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Skew Calculator + */ +register SKEWCALC { + address 0x0C9 + access_mode RO + modes M_CFG +} + +/* + * Data FIFO Debug Control + */ +register DFDBCTL { + address 0x0CB + access_mode RW + modes M_DFF0, M_DFF1 + field DFF_CIO_WR_RDY 0x20 + field DFF_CIO_RD_RDY 0x10 + field DFF_DIR_ERR 0x08 + field DFF_RAMBIST_FAIL 0x04 + field DFF_RAMBIST_DONE 0x02 + field DFF_RAMBIST_EN 0x01 +} + +/* + * Data FIFO Space Count + * Number of FIFO locations that are free. + */ +register DFSCNT { + address 0x0CC + access_mode RO + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Data FIFO Byte Count + * Number of filled FIFO locations. + */ +register DFBCNT { + address 0x0CE + access_mode RO + size 2 + modes M_DFF0, M_DFF1 +} + +/* + * Sequencer Program Overlay Address. + * Low address must be written prior to high address. + */ +register OVLYADDR { + address 0x0D4 + modes M_SCSI + size 2 + access_mode RW +} + +/* + * Sequencer Control 0 + * Error detection mode, speed configuration, + * single step, breakpoints and program load. + */ +register SEQCTL0 { + address 0x0D6 + access_mode RW + field PERRORDIS 0x80 + field PAUSEDIS 0x40 + field FAILDIS 0x20 + field FASTMODE 0x10 + field BRKADRINTEN 0x08 + field STEP 0x04 + field SEQRESET 0x02 + field LOADRAM 0x01 +} + +/* + * Sequencer Control 1 + * Instruction RAM Diagnostics + */ +register SEQCTL1 { + address 0x0D7 + access_mode RW + field OVRLAY_DATA_CHK 0x08 + field RAMBIST_DONE 0x04 + field RAMBIST_FAIL 0x02 + field RAMBIST_EN 0x01 +} + +/* + * Sequencer Flags + * Zero and Carry state of the ALU. + */ +register FLAGS { + address 0x0D8 + access_mode RO + field ZERO 0x02 + field CARRY 0x01 +} + +/* + * Sequencer Interrupt Control + */ +register SEQINTCTL { + address 0x0D9 + access_mode RW + field INTVEC1DSL 0x80 + field INT1_CONTEXT 0x20 + field SCS_SEQ_INT1M1 0x10 + field SCS_SEQ_INT1M0 0x08 + field INTMASK2 0x04 + field INTMASK1 0x02 + field IRET 0x01 +} + +/* + * Sequencer RAM Data Port + * Single byte window into the Sequencer Instruction Ram area starting + * at the address specified by OVLYADDR. To write a full instruction word, + * simply write four bytes in succession. OVLYADDR will increment after the + * most significant instrution byte (the byte with the parity bit) is written. + */ +register SEQRAM { + address 0x0DA + access_mode RW +} + +/* + * Sequencer Program Counter + * Low byte must be written prior to high byte. + */ +register PRGMCNT { + address 0x0DE + access_mode RW + size 2 +} + +/* + * Accumulator + */ +register ACCUM { + address 0x0E0 + access_mode RW + accumulator +} + +/* + * Source Index Register + * Incrementing index for reads of SINDIR and the destination (low byte only) + * for any immediate operands passed in jmp, jc, jnc, call instructions. + * Example: + * mvi 0xFF call some_routine; + * + * Will set SINDEX[0] to 0xFF and call the routine "some_routine. + */ +register SINDEX { + address 0x0E2 + access_mode RW + size 2 + sindex +} + +/* + * Destination Index Register + * Incrementing index for writes to DINDIR. Can be used as a scratch register. + */ +register DINDEX { + address 0x0E4 + access_mode RW + size 2 +} + +/* + * Break Address + * Sequencer instruction breakpoint address address. + */ +register BRKADDR0 { + address 0x0E6 + access_mode RW +} + +register BRKADDR1 { + address 0x0E6 + access_mode RW + field BRKDIS 0x80 /* Disable Breakpoint */ +} + +/* + * All Ones + * All reads to this register return the value 0xFF. + */ +register ALLONES { + address 0x0E8 + access_mode RO + allones +} + +/* + * All Zeros + * All reads to this register return the value 0. + */ +register ALLZEROS { + address 0x0EA + access_mode RO + allzeros +} + +/* + * No Destination + * Writes to this register have no effect. + */ +register NONE { + address 0x0EA + access_mode WO + none +} + +/* + * Source Index Indirect + * Reading this register is equivalent to reading (register_base + SINDEX) and + * incrementing SINDEX by 1. + */ +register SINDIR { + address 0x0EC + access_mode RO +} + +/* + * Destination Index Indirect + * Writing this register is equivalent to writing to (register_base + DINDEX) + * and incrementing DINDEX by 1. + */ +register DINDIR { + address 0x0ED + access_mode WO +} + +/* + * Function One + * 2's complement to bit value conversion. Write the 2's complement value + * (0-7 only) to the top nibble and retrieve the bit indexed by that value + * on the next read of this register. + * Example: + * Write 0x60 + * Read 0x40 + */ +register FUNCTION1 { + address 0x0F0 + access_mode RW +} + +/* + * Stack + * Window into the stack. Each stack location is 10 bits wide reported + * low byte followed by high byte. There are 8 stack locations. + */ +register STACK { + address 0x0F2 + access_mode RW +} + +/* + * Interrupt Vector 1 Address + * Interrupt branch address for SCS SEQ_INT1 mode 0 and 1 interrupts. + */ +register INTVEC1_ADDR { + address 0x0F4 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Current Address + * Address of the SEQRAM instruction currently executing instruction. + */ +register CURADDR { + address 0x0F4 + access_mode RW + size 2 + modes M_SCSI +} + +/* + * Interrupt Vector 2 Address + * Interrupt branch address for HST_SEQ_INT2 interrupts. + */ +register INTVEC2_ADDR { + address 0x0F6 + access_mode RW + size 2 + modes M_CFG +} + +/* + * Last Address + * Address of the SEQRAM instruction executed prior to the current instruction. + */ +register LASTADDR { + address 0x0F6 + access_mode RW + size 2 + modes M_SCSI +} + +register AHD_PCI_CONFIG_BASE { + address 0x100 + access_mode RW + size 256 + modes M_CFG +} + +/* ---------------------- Scratch RAM Offsets ------------------------- */ +scratch_ram { + /* Mode Specific */ + address 0x0A0 + size 8 + modes 0, 1, 2, 3 + REG0 { + size 2 + } + REG1 { + size 2 + } + REG_ISR { + size 2 + } + SG_STATE { + size 1 + field SEGS_AVAIL 0x01 + field LOADING_NEEDED 0x02 + field FETCH_INPROG 0x04 + } + /* + * Track whether the transfer byte count for + * the current data phase is odd. + */ + DATA_COUNT_ODD { + size 1 + } +} + +scratch_ram { + /* Mode Specific */ + address 0x0F8 + size 8 + modes 0, 1, 2, 3 + LONGJMP_ADDR { + size 2 + } + ACCUM_SAVE { + size 1 + } +} + + +scratch_ram { + address 0x100 + size 128 + modes 0, 1, 2, 3 + /* + * Per "other-id" execution queues. We use an array of + * tail pointers into lists of SCBs sorted by "other-id". + * The execution head pointer threads the head SCBs for + * each list. + */ + WAITING_SCB_TAILS { + size 32 + } + WAITING_TID_HEAD { + size 2 + } + WAITING_TID_TAIL { + size 2 + } + /* + * SCBID of the next SCB in the new SCB queue. + */ + NEXT_QUEUED_SCB_ADDR { + size 4 + } + /* + * head of list of SCBs that have + * completed but have not been + * put into the qoutfifo. + */ + COMPLETE_SCB_HEAD { + size 2 + } + /* + * The list of completed SCBs in + * the active DMA. + */ + COMPLETE_SCB_DMAINPROG_HEAD { + size 2 + } + /* + * head of list of SCBs that have + * completed but need to be uploaded + * to the host prior to being completed. + */ + COMPLETE_DMA_SCB_HEAD { + size 2 + } + /* Counting semaphore to prevent new select-outs */ + QFREEZE_COUNT { + size 2 + } + /* + * Mode to restore on legacy idle loop exit. + */ + SAVED_MODE { + size 1 + } + /* + * Single byte buffer used to designate the type or message + * to send to a target. + */ + MSG_OUT { + size 1 + } + /* Parameters for DMA Logic */ + DMAPARAMS { + size 1 + field PRELOADEN 0x80 + field WIDEODD 0x40 + field SCSIEN 0x20 + field SDMAEN 0x10 + field SDMAENACK 0x10 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 /* Set indicates PCI->SCSI */ + field FIFOFLUSH 0x02 + field FIFORESET 0x01 + } + SEQ_FLAGS { + size 1 + field NOT_IDENTIFIED 0x80 + field NO_CDB_SENT 0x40 + field TARGET_CMD_IS_TAGGED 0x40 + field DPHASE 0x20 + /* Target flags */ + field TARG_CMD_PENDING 0x10 + field CMDPHASE_PENDING 0x08 + field DPHASE_PENDING 0x04 + field SPHASE_PENDING 0x02 + field NO_DISCONNECT 0x01 + } + /* + * Temporary storage for the + * target/channel/lun of a + * reconnecting target + */ + SAVED_SCSIID { + size 1 + } + SAVED_LUN { + size 1 + } + /* + * The last bus phase as seen by the sequencer. + */ + LASTPHASE { + size 1 + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 + field P_BUSFREE 0x01 + enum PHASE_MASK CDO|IOO|MSGO { + P_DATAOUT 0x0, + P_DATAIN IOO, + P_DATAOUT_DT P_DATAOUT|MSGO, + P_DATAIN_DT P_DATAIN|MSGO, + P_COMMAND CDO, + P_MESGOUT CDO|MSGO, + P_STATUS CDO|IOO, + P_MESGIN CDO|IOO|MSGO + } + } + /* + * Value to "or" into the SCBPTR[1] value to + * indicate that an entry in the QINFIFO is valid. + */ + QOUTFIFO_ENTRY_VALID_TAG { + size 1 + } + /* + * Base address of our shared data with the kernel driver in host + * memory. This includes the qoutfifo and target mode + * incoming command queue. + */ + SHARED_DATA_ADDR { + size 4 + } + /* + * Pointer to location in host memory for next + * position in the qoutfifo. + */ + QOUTFIFO_NEXT_ADDR { + size 4 + } + /* + * Kernel and sequencer offsets into the queue of + * incoming target mode command descriptors. The + * queue is full when the KERNEL_TQINPOS == TQINPOS. + */ + KERNEL_TQINPOS { + size 1 + } + TQINPOS { + size 1 + } + ARG_1 { + size 1 + mask SEND_MSG 0x80 + mask SEND_SENSE 0x40 + mask SEND_REJ 0x20 + mask MSGOUT_PHASEMIS 0x10 + mask EXIT_MSG_LOOP 0x08 + mask CONT_MSG_LOOP_WRITE 0x04 + mask CONT_MSG_LOOP_READ 0x03 + mask CONT_MSG_LOOP_TARG 0x02 + alias RETURN_1 + } + ARG_2 { + size 1 + alias RETURN_2 + } + + /* + * Snapshot of MSG_OUT taken after each message is sent. + */ + LAST_MSG { + size 1 + } + + /* + * Sequences the kernel driver has okayed for us. This allows + * the driver to do things like prevent initiator or target + * operations. + */ + SCSISEQ_TEMPLATE { + size 1 + field MANUALCTL 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field MANUALP 0x0C + field ENAUTOATNP 0x02 + field ALTSTIM 0x01 + } + + /* + * The initiator specified tag for this target mode transaction. + */ + INITIATOR_TAG { + size 1 + } + + SEQ_FLAGS2 { + size 1 + field TARGET_MSG_PENDING 0x02 + field SELECTOUT_QFROZEN 0x04 + } + + ALLOCFIFO_SCBPTR { + size 2 + } + + /* + * The maximum amount of time to wait, when interrupt coalescing + * is enabled, before issueing a CMDCMPLT interrupt for a completed + * command. + */ + INT_COALESCING_TIMER { + size 2 + } + + /* + * The maximum number of commands to coalesce into a single interrupt. + * Actually the 2's complement of that value to simplify sequencer + * code. + */ + INT_COALESCING_MAXCMDS { + size 1 + } + + /* + * The minimum number of commands still outstanding required + * to continue coalescing (2's complement of value). + */ + INT_COALESCING_MINCMDS { + size 1 + } + + /* + * Number of commands "in-flight". + */ + CMDS_PENDING { + size 2 + } + + /* + * The count of commands that have been coalesced. + */ + INT_COALESCING_CMDCOUNT { + size 1 + } + + /* + * Since the HS_MAIBOX is self clearing, copy its contents to + * this position in scratch ram every time it changes. + */ + LOCAL_HS_MAILBOX { + size 1 + } + /* + * Target-mode CDB type to CDB length table used + * in non-packetized operation. + */ + CMDSIZE_TABLE { + size 8 + } +} + +/************************* Hardware SCB Definition ****************************/ +scb { + address 0x180 + size 64 + modes 0, 1, 2, 3 + SCB_RESIDUAL_DATACNT { + size 4 + alias SCB_CDB_STORE + alias SCB_HOST_CDB_PTR + } + SCB_RESIDUAL_SGPTR { + size 4 + field SG_ADDR_MASK 0xf8 /* In the last byte */ + field SG_OVERRUN_RESID 0x02 /* In the first byte */ + field SG_LIST_NULL 0x01 /* In the first byte */ + } + SCB_SCSI_STATUS { + size 1 + alias SCB_HOST_CDB_LEN + } + SCB_TARGET_PHASES { + size 1 + } + SCB_TARGET_DATA_DIR { + size 1 + } + SCB_TARGET_ITAG { + size 1 + } + SCB_SENSE_BUSADDR { + /* + * Only valid if CDB length is less than 13 bytes or + * we are using a CDB pointer. Otherwise contains + * the last 4 bytes of embedded cdb information. + */ + size 4 + alias SCB_NEXT_COMPLETE + } + SCB_TAG { + alias SCB_FIFO_USE_COUNT + size 2 + } + SCB_CONTROL { + size 1 + field TARGET_SCB 0x80 + field DISCENB 0x40 + field TAG_ENB 0x20 + field MK_MESSAGE 0x10 + field STATUS_RCVD 0x08 + field DISCONNECTED 0x04 + field SCB_TAG_TYPE 0x03 + } + SCB_SCSIID { + size 1 + field TID 0xF0 + field OID 0x0F + } + SCB_LUN { + size 1 + field LID 0xff + } + SCB_TASK_ATTRIBUTE { + size 1 + /* + * Overloaded field for non-packetized + * ignore wide residue message handling. + */ + field SCB_XFERLEN_ODD 0x01 + } + SCB_CDB_LEN { + size 1 + field SCB_CDB_LEN_PTR 0x80 /* CDB in host memory */ + } + SCB_TASK_MANAGEMENT { + size 1 + } + SCB_DATAPTR { + size 8 + } + SCB_DATACNT { + /* + * The last byte is really the high address bits for + * the data address. + */ + size 4 + field SG_LAST_SEG 0x80 /* In the fourth byte */ + field SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */ + } + SCB_SGPTR { + size 4 + field SG_STATUS_VALID 0x04 /* In the first byte */ + field SG_FULL_RESID 0x02 /* In the first byte */ + field SG_LIST_NULL 0x01 /* In the first byte */ + } + SCB_BUSADDR { + size 4 + } + SCB_NEXT { + alias SCB_NEXT_SCB_BUSADDR + size 2 + } + SCB_NEXT2 { + size 2 + } + SCB_SPARE { + size 8 + alias SCB_PKT_LUN + } + SCB_DISCONNECTED_LISTS { + size 8 + } +} + +/*********************************** Constants ********************************/ +const MK_MESSAGE_BIT_OFFSET 4 +const TID_SHIFT 4 +const TARGET_CMD_CMPLT 0xfe +const INVALID_ADDR 0x80 +#define SCB_LIST_NULL 0xff +#define QOUTFIFO_ENTRY_VALID_TOGGLE 0x80 + +const CCSGADDR_MAX 0x80 +const CCSCBADDR_MAX 0x80 +const CCSGRAM_MAXSEGS 16 + +/* Selection Timeout Timer Constants */ +const STIMESEL_SHIFT 3 +const STIMESEL_MIN 0x18 +const STIMESEL_BUG_ADJ 0x8 + +/* WDTR Message values */ +const BUS_8_BIT 0x00 +const BUS_16_BIT 0x01 +const BUS_32_BIT 0x02 + +/* Offset maximums */ +const MAX_OFFSET 0xfe +const MAX_OFFSET_PACED 0xfe +const MAX_OFFSET_PACED_BUG 0x7f +/* + * Some 160 devices incorrectly accept 0xfe as a + * sync offset, but will overrun this value. Limit + * to 0x7f for speed lower than U320 which will + * avoid the persistent sync offset overruns. + */ +const MAX_OFFSET_NON_PACED 0x7f +const HOST_MSG 0xff + +/* + * The size of our sense buffers. + * Sense buffer mapping can be handled in either of two ways. + * The first is to allocate a dmamap for each transaction. + * Depending on the architecture, dmamaps can be costly. The + * alternative is to statically map the buffers in much the same + * way we handle our scatter gather lists. The driver implements + * the later. + */ +const AHD_SENSE_BUFSIZE 256 + +/* Target mode command processing constants */ +const CMD_GROUP_CODE_SHIFT 0x05 + +const STATUS_BUSY 0x08 +const STATUS_QUEUE_FULL 0x28 +const STATUS_PKT_SENSE 0xFF +const TARGET_DATA_IN 1 + +const SCB_TRANSFER_SIZE_FULL_LUN 56 +const SCB_TRANSFER_SIZE_1BYTE_LUN 48 +/* PKT_OVERRUN_BUFSIZE must be a multiple of 256 less than 64K */ +const PKT_OVERRUN_BUFSIZE 512 + +/* + * Timer parameters. + */ +const AHD_TIMER_US_PER_TICK 25 +const AHD_TIMER_MAX_TICKS 0xFFFF +const AHD_TIMER_MAX_US (AHD_TIMER_MAX_TICKS * AHD_TIMER_US_PER_TICK) + +/* + * Downloaded (kernel inserted) constants + */ +const SG_PREFETCH_CNT download +const SG_PREFETCH_CNT_LIMIT download +const SG_PREFETCH_ALIGN_MASK download +const SG_PREFETCH_ADDR_MASK download +const SG_SIZEOF download +const PKT_OVERRUN_BUFOFFSET download +const SCB_TRANSFER_SIZE download + +/* + * BIOS SCB offsets + */ +const NVRAM_SCB_OFFSET 0x2C diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx.seq linux-2.4.22/drivers/scsi/aic7xxx/aic79xx.seq --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx.seq 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx.seq 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,2032 @@ +/* + * Adaptec U320 device driver firmware for Linux and FreeBSD. + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $" +PATCH_ARG_LIST = "struct ahd_softc *ahd" +PREFIX = "ahd_" + +#include "aic79xx.reg" +#include "scsi_message.h" + +restart: +if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + test SEQINTCODE, 0xFF jz idle_loop; + SET_SEQINTCODE(NO_SEQINT) +} + +idle_loop: + + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + /* + * Convert ERROR status into a sequencer + * interrupt to handle the case of an + * interrupt collision on the hardware + * setting of HWERR. + */ + test ERROR, 0xFF jz no_error_set; + SET_SEQINTCODE(SAW_HWERR) +no_error_set: + } + SET_MODE(M_SCSI, M_SCSI) + test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus; + test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus; + cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus; + /* + * ENSELO is cleared by a SELDO, so we must test for SELDO + * one last time. + */ +BEGIN_CRITICAL; + test SSTAT0, SELDO jnz select_out; +END_CRITICAL; + call start_selection; +idle_loop_checkbus: +BEGIN_CRITICAL; + test SSTAT0, SELDO jnz select_out; +END_CRITICAL; + test SSTAT0, SELDI jnz select_in; + test SCSIPHASE, ~DATA_PHASE_MASK jz idle_loop_check_nonpackreq; + test SCSISIGO, ATNO jz idle_loop_check_nonpackreq; + call unexpected_nonpkt_phase_find_ctxt; +idle_loop_check_nonpackreq: + test SSTAT2, NONPACKREQ jz . + 2; + call unexpected_nonpkt_phase_find_ctxt; + if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) { + and A, FIFO0FREE|FIFO1FREE, DFFSTAT; + cmp A, FIFO0FREE|FIFO1FREE jne . + 3; + and SBLKCTL, ~DIAGLEDEN|DIAGLEDON; + jmp . + 2; + or SBLKCTL, DIAGLEDEN|DIAGLEDON; + } + call idle_loop_gsfifo_in_scsi_mode; + call idle_loop_service_fifos; + call idle_loop_cchan; + jmp idle_loop; + +BEGIN_CRITICAL; +idle_loop_gsfifo: + SET_MODE(M_SCSI, M_SCSI) +idle_loop_gsfifo_in_scsi_mode: + test LQISTAT2, LQIGSAVAIL jz return; + /* + * We have received good status for this transaction. There may + * still be data in our FIFOs draining to the host. Complete + * the SCB only if all data has transferred to the host. + */ +good_status_IU_done: + bmov SCBPTR, GSFIFO, 2; + clr SCB_SCSI_STATUS; + /* + * If a command completed before an attempted task management + * function completed, notify the host after disabling any + * pending select-outs. + */ + test SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally; + test SSTAT0, SELDO|SELINGO jnz . + 2; + and SCSISEQ0, ~ENSELO; + SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) +gsfifo_complete_normally: + or SCB_CONTROL, STATUS_RCVD; + + /* + * Since this status did not consume a FIFO, we have to + * be a bit more dilligent in how we check for FIFOs pertaining + * to this transaction. There are two states that a FIFO still + * transferring data may be in. + * + * 1) Configured and draining to the host, with a FIFO handler. + * 2) Pending cfg4data, fifo not empty. + * + * Case 1 can be detected by noticing a non-zero FIFO active + * count in the SCB. In this case, we allow the routine servicing + * the FIFO to complete the SCB. + * + * Case 2 implies either a pending or yet to occur save data + * pointers for this same context in the other FIFO. So, if + * we detect case 1, we will properly defer the post of the SCB + * and achieve the desired result. The pending cfg4data will + * notice that status has been received and complete the SCB. + */ + test SCB_FIFO_USE_COUNT, 0xFF jnz idle_loop_gsfifo_in_scsi_mode; + call complete; +END_CRITICAL; + jmp idle_loop_gsfifo_in_scsi_mode; + +idle_loop_service_fifos: + SET_MODE(M_DFF0, M_DFF0) + test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo; + call longjmp; +idle_loop_next_fifo: + SET_MODE(M_DFF1, M_DFF1) + test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp; +return: + ret; + +idle_loop_cchan: + SET_MODE(M_CCHAN, M_CCHAN) + test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty; + mov LOCAL_HS_MAILBOX, HS_MAILBOX; + or QOFF_CTLSTA, HS_MAILBOX_ACT; +hs_mailbox_empty: +BEGIN_CRITICAL; + test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle; + test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog; + test CCSCBCTL, CCSCBDONE jz return; +END_CRITICAL; + /* FALLTHROUGH */ +scbdma_tohost_done: + test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone; + /* + * An SCB has been succesfully uploaded to the host. + * If the SCB was uploaded for some reason other than + * bad SCSI status (currently only for underruns), we + * queue the SCB for normal completion. Otherwise, we + * wait until any select-out activity has halted, and + * then notify the host so that the transaction can be + * dealt with. + */ + test SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host; + and CCSCBCTL, ~(CCARREN|CCSCBEN); + bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2; + bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; + bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; +scbdma_notify_host: + SET_MODE(M_SCSI, M_SCSI) + test SCSISEQ0, ENSELO jnz return; + test SSTAT0, (SELDO|SELINGO) jnz return; + SET_MODE(M_CCHAN, M_CCHAN) + /* + * Remove SCB and notify host. + */ + and CCSCBCTL, ~(CCARREN|CCSCBEN); + bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2; + SET_SEQINTCODE(BAD_SCB_STATUS) + ret; +fill_qoutfifo_dmadone: + and CCSCBCTL, ~(CCARREN|CCSCBEN); + call qoutfifo_updated; + mvi COMPLETE_SCB_DMAINPROG_HEAD[1], SCB_LIST_NULL; + bmov QOUTFIFO_NEXT_ADDR, SCBHADDR, 4; + test QOFF_CTLSTA, SDSCB_ROLLOVR jz return; + bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4; + xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret; + +qoutfifo_updated: + /* + * If there are more commands waiting to be dma'ed + * to the host, always coalesce. Otherwise honor the + * host's wishes. + */ + cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count; + cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count; + test LOCAL_HS_MAILBOX, ENINT_COALESCE jz issue_cmdcmplt; + + /* + * If we have relatively few commands outstanding, don't + * bother waiting for another command to complete. + */ + test CMDS_PENDING[1], 0xFF jnz coalesce_by_count; + /* Add -1 so that jnc means <= not just < */ + add A, -1, INT_COALESCING_MINCMDS; + add NONE, A, CMDS_PENDING; + jnc issue_cmdcmplt; + + /* + * If coalescing, only coalesce up to the limit + * provided by the host driver. + */ +coalesce_by_count: + mov A, INT_COALESCING_MAXCMDS; + add NONE, A, INT_COALESCING_CMDCOUNT; + jc issue_cmdcmplt; + /* + * If the timer is not currently active, + * fire it up. + */ + test INTCTL, SWTMINTMASK jz return; + bmov SWTIMER, INT_COALESCING_TIMER, 2; + mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; + or INTCTL, SWTMINTEN|SWTIMER_START; + and INTCTL, ~SWTMINTMASK ret; + +issue_cmdcmplt: + mvi INTSTAT, CMDCMPLT; + clr INT_COALESCING_CMDCOUNT; + or INTCTL, SWTMINTMASK ret; + +BEGIN_CRITICAL; +fetch_new_scb_inprog: + test CCSCBCTL, ARRDONE jz return; +fetch_new_scb_done: + and CCSCBCTL, ~(CCARREN|CCSCBEN); + bmov REG0, SCBPTR, 2; + clr A; + add CMDS_PENDING, 1; + adc CMDS_PENDING[1], A; + if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { + /* + * "Short Luns" are not placed into outgoing LQ + * packets in the correct byte order. Use a full + * sized lun field instead and fill it with the + * one byte of lun information we support. + */ + mov SCB_PKT_LUN[6], SCB_LUN; + } + /* + * The FIFO use count field is shared with the + * tag set by the host so that our SCB dma engine + * knows the correct location to store the SCB. + * Set it to zero before processing the SCB. + */ + mov SCB_FIFO_USE_COUNT, ALLZEROS; + /* Update the next SCB address to download. */ + bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4; + mvi SCB_NEXT[1], SCB_LIST_NULL; + mvi SCB_NEXT2[1], SCB_LIST_NULL; + /* Increment our position in the QINFIFO. */ + mov NONE, SNSCB_QOFF; + /* + * SCBs that want to send messages are always + * queued independently. This ensures that they + * are at the head of the SCB list to select out + * to a target and we will see the MK_MESSAGE flag. + */ + test SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb; + shr SINDEX, 3, SCB_SCSIID; + and SINDEX, ~0x1; + mvi SINDEX[1], (WAITING_SCB_TAILS >> 8); + bmov DINDEX, SINDEX, 2; + bmov SCBPTR, SINDIR, 2; + bmov DINDIR, REG0, 2; + cmp SCBPTR[1], SCB_LIST_NULL je first_new_target_scb; + bmov SCB_NEXT, REG0, 2 ret; +first_new_target_scb: + cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb; + bmov SCBPTR, WAITING_TID_TAIL, 2; + bmov SCB_NEXT2, REG0, 2; + bmov WAITING_TID_TAIL, REG0, 2 ret; +first_new_scb: + bmov WAITING_TID_HEAD, REG0, 2; + bmov WAITING_TID_TAIL, REG0, 2 ret; +END_CRITICAL; + +scbdma_idle: + /* + * Give precedence to downloading new SCBs to execute + * unless select-outs are currently frozen. + */ + test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2; +BEGIN_CRITICAL; + test QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb; + cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb; + cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return; + /* FALLTHROUGH */ +fill_qoutfifo: + /* + * Keep track of the SCBs we are dmaing just + * in case the DMA fails or is aborted. + */ + mov A, QOUTFIFO_ENTRY_VALID_TAG; + bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2; + mvi CCSCBCTL, CCSCBRESET; + bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4; + bmov SCBPTR, COMPLETE_SCB_HEAD, 2; +fill_qoutfifo_loop: + mov CCSCBRAM, SCBPTR; + or CCSCBRAM, A, SCBPTR[1]; + mov NONE, SDSCB_QOFF; + inc INT_COALESCING_CMDCOUNT; + add CMDS_PENDING, -1; + adc CMDS_PENDING[1], -1; + cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done; + cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done; + test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done; + bmov SCBPTR, SCB_NEXT_COMPLETE, 2; + jmp fill_qoutfifo_loop; +fill_qoutfifo_done: + mov SCBHCNT, CCSCBADDR; + mvi CCSCBCTL, CCSCBEN|CCSCBRESET; + bmov COMPLETE_SCB_HEAD, SCB_NEXT_COMPLETE, 2; + mvi SCB_NEXT_COMPLETE[1], SCB_LIST_NULL ret; + +fetch_new_scb: + bmov SCBHADDR, NEXT_QUEUED_SCB_ADDR, 4; + mvi CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET jmp dma_scb; +dma_complete_scb: + bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2; + bmov SCBHADDR, SCB_BUSADDR, 4; + mvi CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb; +END_CRITICAL; + +/* + * Either post or fetch an SCB from host memory. The caller + * is responsible for polling for transfer completion. + * + * Prerequisits: Mode == M_CCHAN + * SINDEX contains CCSCBCTL flags + * SCBHADDR set to Host SCB address + * SCBPTR set to SCB src location on "push" operations + */ +SET_SRC_MODE M_CCHAN; +SET_DST_MODE M_CCHAN; +dma_scb: + mvi SCBHCNT, SCB_TRANSFER_SIZE; + mov CCSCBCTL, SINDEX ret; + +BEGIN_CRITICAL; +setjmp: + bmov LONGJMP_ADDR, STACK, 2 ret; +setjmp_inline: + bmov LONGJMP_ADDR, STACK, 2; +longjmp: + bmov STACK, LONGJMP_ADDR, 2 ret; +END_CRITICAL; + +/*************************** Chip Bug Work Arounds ****************************/ +/* + * Must disable interrupts when setting the mode pointer + * register as an interrupt occurring mid update will + * fail to store the new mode value for restoration on + * an iret. + */ +if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { +set_mode_work_around: + mvi SEQINTCTL, INTVEC1DSL; + mov MODE_PTR, SINDEX; + clr SEQINTCTL ret; + +toggle_dff_mode_work_around: + mvi SEQINTCTL, INTVEC1DSL; + xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); + clr SEQINTCTL ret; +} + + +if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { +set_seqint_work_around: + mov SEQINTCODE, SINDEX; + mvi SEQINTCODE, NO_SEQINT ret; +} + +/************************ Packetized LongJmp Routines *************************/ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +start_selection: +BEGIN_CRITICAL; + if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { + /* + * Razor #494 + * Rev A hardware fails to update LAST/CURR/NEXTSCB + * correctly after a packetized selection in several + * situations: + * + * 1) If only one command existed in the queue, the + * LAST/CURR/NEXTSCB are unchanged. + * + * 2) In a non QAS, protocol allowed phase change, + * the queue is shifted 1 too far. LASTSCB is + * the last SCB that was correctly processed. + * + * 3) In the QAS case, if the full list of commands + * was successfully sent, NEXTSCB is NULL and neither + * CURRSCB nor LASTSCB can be trusted. We must + * manually walk the list counting MAXCMDCNT elements + * to find the last SCB that was sent correctly. + * + * To simplify the workaround for this bug in SELDO + * handling, we initialize LASTSCB prior to enabling + * selection so we can rely on it even for case #1 above. + */ + bmov LASTSCB, WAITING_TID_HEAD, 2; + } + bmov CURRSCB, WAITING_TID_HEAD, 2; + bmov SCBPTR, WAITING_TID_HEAD, 2; + shr SELOID, 4, SCB_SCSIID; + /* + * If we want to send a message to the device, ensure + * we are selecting with atn irregardless of our packetized + * agreement. Since SPI4 only allows target reset or PPR + * messages if this is a packetized connection, the change + * to our negotiation table entry for this selection will + * be cleared when the message is acted on. + */ + test SCB_CONTROL, MK_MESSAGE jz . + 3; + mov NEGOADDR, SELOID; + or NEGCONOPTS, ENAUTOATNO; + or SCSISEQ0, ENSELO ret; +END_CRITICAL; + +/* + * Allocate a FIFO for a non-packetized transaction. + * In RevA hardware, both FIFOs must be free before we + * can allocate a FIFO for a non-packetized transaction. + */ +allocate_fifo_loop: + /* + * Do whatever work is required to free a FIFO. + */ + call idle_loop_service_fifos; + SET_MODE(M_SCSI, M_SCSI) +allocate_fifo: + if ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0) { + and A, FIFO0FREE|FIFO1FREE, DFFSTAT; + cmp A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop; + } else { + test DFFSTAT, FIFO1FREE jnz allocate_fifo1; + test DFFSTAT, FIFO0FREE jz allocate_fifo_loop; + mvi DFFSTAT, B_CURRFIFO_0; + SET_MODE(M_DFF0, M_DFF0) + bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; + } +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +allocate_fifo1: + mvi DFFSTAT, CURRFIFO_1; + SET_MODE(M_DFF1, M_DFF1) + bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret; + +/* + * We have been reselected as an initiator + * or selected as a target. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +select_in: + if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { + /* + * This exposes a window whereby a + * busfree just after a selection will + * be missed, but there is no other safe + * way to enable busfree detection if + * the busfreerev function is broken. + */ + mvi CLRSINT1,CLRBUSFREE; + or SIMODE1, ENBUSFREE; + } + or SXFRCTL0, SPIOEN; + and SAVED_SCSIID, SELID_MASK, SELID; + and A, OID, IOWNID; + or SAVED_SCSIID, A; + mvi CLRSINT0, CLRSELDI; + jmp ITloop; + +/* + * We have successfully selected out. + * + * Clear SELDO. + * Dequeue all SCBs sent from the waiting queue + * Requeue all SCBs *not* sent to the tail of the waiting queue + * Take Razor #494 into account for above. + * + * In Packetized Mode: + * Return to the idle loop. Our interrupt handler will take + * care of any incoming L_Qs. + * + * In Non-Packetize Mode: + * Continue to our normal state machine. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +select_out: +BEGIN_CRITICAL; + /* Clear out all SCBs that have been successfully sent. */ + if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { + /* + * For packetized, the LQO manager clears ENSELO on + * the assertion of SELDO. If we are non-packetized, + * LASTSCB and CURRSCB are accurate. + */ + test SCSISEQ0, ENSELO jnz use_lastscb; + + /* + * The update is correct for LQOSTAT1 errors. All + * but LQOBUSFREE are handled by kernel interrupts. + * If we see LQOBUSFREE, return to the idle loop. + * Once we are out of the select_out critical section, + * the kernel will cleanup the LQOBUSFREE and we will + * eventually restart the selection if appropriate. + */ + test LQOSTAT1, LQOBUSFREE jnz idle_loop; + + /* + * On a phase change oustside of packet boundaries, + * LASTSCB points to the currently active SCB context + * on the bus. + */ + test LQOSTAT2, LQOPHACHGOUTPKT jnz use_lastscb; + + /* + * If the hardware has traversed the whole list, NEXTSCB + * will be NULL, CURRSCB and LASTSCB cannot be trusted, + * but MAXCMDCNT is accurate. If we stop part way through + * the list or only had one command to issue, NEXTSCB[1] is + * not NULL and LASTSCB is the last command to go out. + */ + cmp NEXTSCB[1], SCB_LIST_NULL jne use_lastscb; + + /* + * Brute force walk. + */ + bmov SCBPTR, WAITING_TID_HEAD, 2; + mvi SEQINTCTL, INTVEC1DSL; + mvi MODE_PTR, MK_MODE(M_CFG, M_CFG); + mov A, MAXCMDCNT; + mvi MODE_PTR, MK_MODE(M_SCSI, M_SCSI); + clr SEQINTCTL; +find_lastscb_loop: + dec A; + test A, 0xFF jz found_last_sent_scb; + bmov SCBPTR, SCB_NEXT, 2; + jmp find_lastscb_loop; +use_lastscb: + bmov SCBPTR, LASTSCB, 2; +found_last_sent_scb: + bmov CURRSCB, SCBPTR, 2; +curscb_ww_done: + } else { + /* + * Untested - Verify with Rev B. + */ + bmov SCBPTR, CURRSCB, 2; + } + + /* + * Requeue any SCBs not sent, to the tail of the waiting Q. + */ + cmp SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done; + + /* + * We know that neither the per-TID list nor the list of + * TIDs is empty. Use this knowledge to our advantage. + */ + bmov REG0, SCB_NEXT, 2; + bmov SCBPTR, WAITING_TID_TAIL, 2; + bmov SCB_NEXT2, REG0, 2; + bmov WAITING_TID_TAIL, REG0, 2; + jmp select_out_inc_tid_q; + +select_out_list_done: + /* + * The whole list made it. Just clear our TID's tail pointer + * unless we were queued independently due to our need to + * send a message. + */ + test SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q; + shr DINDEX, 3, SCB_SCSIID; + or DINDEX, 1; /* Want only the second byte */ + mvi DINDEX[1], ((WAITING_SCB_TAILS) >> 8); + mvi DINDIR, SCB_LIST_NULL; +select_out_inc_tid_q: + bmov SCBPTR, WAITING_TID_HEAD, 2; + bmov WAITING_TID_HEAD, SCB_NEXT2, 2; + cmp WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2; + mvi WAITING_TID_TAIL[1], SCB_LIST_NULL; + bmov SCBPTR, CURRSCB, 2; + mvi CLRSINT0, CLRSELDO; + test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase; + test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase; + + /* + * If this is a packetized connection, return to our + * idle_loop and let our interrupt handler deal with + * any connection setup/teardown issues. The only + * exceptions are the case of MK_MESSAGE and task management + * SCBs. + */ + if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) { + /* + * In the A, the LQO manager transitions to LQOSTOP0 even if + * we have selected out with ATN asserted and the target + * REQs in a non-packet phase. + */ + test SCB_CONTROL, MK_MESSAGE jz select_out_no_message; + test SCSISIGO, ATNO jnz select_out_non_packetized; +select_out_no_message: + } + test LQOSTAT2, LQOSTOP0 jz select_out_non_packetized; + test SCB_TASK_MANAGEMENT, 0xFF jz idle_loop; + SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE) + jmp idle_loop; + +select_out_non_packetized: + /* Non packetized request. */ + and SCSISEQ0, ~ENSELO; + if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { + /* + * This exposes a window whereby a + * busfree just after a selection will + * be missed, but there is no other safe + * way to enable busfree detection if + * the busfreerev function is broken. + */ + mvi CLRSINT1,CLRBUSFREE; + or SIMODE1, ENBUSFREE; + } + mov SAVED_SCSIID, SCB_SCSIID; + mov SAVED_LUN, SCB_LUN; + mvi SEQ_FLAGS, NO_CDB_SENT; +END_CRITICAL; + or SXFRCTL0, SPIOEN; + + /* + * As soon as we get a successful selection, the target + * should go into the message out phase since we have ATN + * asserted. + */ + mvi MSG_OUT, MSG_IDENTIFYFLAG; + + /* + * Main loop for information transfer phases. Wait for the + * target to assert REQ before checking MSG, C/D and I/O for + * the bus phase. + */ +mesgin_phasemis: +ITloop: + call phase_lock; + + mov A, LASTPHASE; + + test A, ~P_DATAIN_DT jz p_data; + cmp A,P_COMMAND je p_command; + cmp A,P_MESGOUT je p_mesgout; + cmp A,P_STATUS je p_status; + cmp A,P_MESGIN je p_mesgin; + + SET_SEQINTCODE(BAD_PHASE) + jmp ITloop; /* Try reading the bus again. */ + +/* + * Command phase. Set up the DMA registers and let 'er rip. + */ +p_command: + test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay; + SET_SEQINTCODE(PROTO_VIOLATION) +p_command_okay: + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) + jnz p_command_allocate_fifo; + /* + * Command retry. Free our current FIFO and + * re-allocate a FIFO so transfer state is + * reset. + */ +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; + SET_MODE(M_SCSI, M_SCSI) +p_command_allocate_fifo: + bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; + call allocate_fifo; +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + add NONE, -17, SCB_CDB_LEN; + jnc p_command_embedded; +p_command_from_host: + bmov HADDR[0], SCB_HOST_CDB_PTR, 9; + mvi SG_CACHE_PRE, LAST_SEG; + mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); + jmp p_command_xfer; +p_command_embedded: + bmov SHCNT[0], SCB_CDB_LEN, 1; + bmov DFDAT, SCB_CDB_STORE, 16; + mvi DFCNTRL, SCSIEN; +p_command_xfer: + and SEQ_FLAGS, ~NO_CDB_SENT; + test DFCNTRL, SCSIEN jnz .; + /* + * DMA Channel automatically disabled. + * Don't allow a data phase if the command + * was not fully transferred. + */ + test SSTAT2, SDONE jnz ITloop; + or SEQ_FLAGS, NO_CDB_SENT; + jmp ITloop; + + +/* + * Status phase. Wait for the data byte to appear, then read it + * and store it into the SCB. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; +p_status: + test SEQ_FLAGS,NOT_IDENTIFIED jnz mesgin_proto_violation; +p_status_okay: + mov SCB_SCSI_STATUS, SCSIDAT; + or SCB_CONTROL, STATUS_RCVD; + jmp ITloop; + +/* + * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full + * indentify message sequence and send it to the target. The host may + * override this behavior by setting the MK_MESSAGE bit in the SCB + * control byte. This will cause us to interrupt the host and allow + * it to handle the message phase completely on its own. If the bit + * associated with this target is set, we will also interrupt the host, + * thereby allowing it to send a message on the next selection regardless + * of the transaction being sent. + * + * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. + * This is done to allow the host to send messages outside of an identify + * sequence while protecting the seqencer from testing the MK_MESSAGE bit + * on an SCB that might not be for the current nexus. (For example, a + * BDR message in responce to a bad reselection would leave us pointed to + * an SCB that doesn't have anything to do with the current target). + * + * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, + * bus device reset). + * + * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, + * in case the target decides to put us in this phase for some strange + * reason. + */ +p_mesgout_retry: + /* Turn on ATN for the retry */ + mvi SCSISIGO, ATNO; +p_mesgout: + mov SINDEX, MSG_OUT; + cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; + test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; +p_mesgout_identify: + or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN; + test SCB_CONTROL, DISCENB jnz . + 2; + and SINDEX, ~DISCENB; +/* + * Send a tag message if TAG_ENB is set in the SCB control block. + * Use SCB_NONPACKET_TAG as the tag value. + */ +p_mesgout_tag: + test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; + mov SCSIDAT, SINDEX; /* Send the identify message */ + call phase_lock; + cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; + and SCSIDAT,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; + call phase_lock; + cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; + mov SCBPTR jmp p_mesgout_onebyte; +/* + * Interrupt the driver, and allow it to handle this message + * phase and any required retries. + */ +p_mesgout_from_host: + cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; + jmp host_message_loop; + +p_mesgout_onebyte: + mvi CLRSINT1, CLRATNO; + mov SCSIDAT, SINDEX; + +/* + * If the next bus phase after ATN drops is message out, it means + * that the target is requesting that the last message(s) be resent. + */ + call phase_lock; + cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; + +p_mesgout_done: + mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ + mov LAST_MSG, MSG_OUT; + mvi MSG_OUT, MSG_NOOP; /* No message left */ + jmp ITloop; + +/* + * Message in phase. Bytes are read using Automatic PIO mode. + */ +p_mesgin: + /* read the 1st message byte */ + mvi ACCUM call inb_first; + + test A,MSG_IDENTIFYFLAG jnz mesgin_identify; + cmp A,MSG_DISCONNECT je mesgin_disconnect; + cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; + cmp ALLZEROS,A je mesgin_complete; + cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; + cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue; + cmp A,MSG_NOOP je mesgin_done; + +/* + * Pushed message loop to allow the kernel to + * run it's own message state engine. To avoid an + * extra nop instruction after signaling the kernel, + * we perform the phase_lock before checking to see + * if we should exit the loop and skip the phase_lock + * in the ITloop. Performing back to back phase_locks + * shouldn't hurt, but why do it twice... + */ +host_message_loop: + call phase_lock; /* Benign the first time through. */ + SET_SEQINTCODE(HOST_MSG_LOOP) + cmp RETURN_1, EXIT_MSG_LOOP je ITloop; + cmp RETURN_1, CONT_MSG_LOOP_WRITE jne . + 3; + mov SCSIDAT, RETURN_2; + jmp host_message_loop; + /* Must be CONT_MSG_LOOP_READ */ + mov NONE, SCSIDAT; /* ACK Byte */ + jmp host_message_loop; + +mesgin_ign_wide_residue: + mov SAVED_MODE, MODE_PTR; + SET_MODE(M_SCSI, M_SCSI) + shr NEGOADDR, 4, SAVED_SCSIID; + mov A, NEGCONOPTS; + RESTORE_MODE(SAVED_MODE) + test A, WIDEXFER jz mesgin_reject; + /* Pull the residue byte */ + mvi REG0 call inb_next; + cmp REG0, 0x01 jne mesgin_reject; + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; + test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jnz mesgin_done; + SET_SEQINTCODE(IGN_WIDE_RES) + jmp mesgin_done; + +mesgin_proto_violation: + SET_SEQINTCODE(PROTO_VIOLATION) + jmp mesgin_done; +mesgin_reject: + mvi MSG_MESSAGE_REJECT call mk_mesg; +mesgin_done: + mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ + jmp ITloop; + +#define INDEX_DISC_LIST(scsiid, lun) \ + and A, 0xC0, scsiid; \ + or SCBPTR, A, lun; \ + clr SCBPTR[1]; \ + and SINDEX, 0x30, scsiid; \ + shr SINDEX, 3; /* Multiply by 2 */ \ + add SINDEX, (SCB_DISCONNECTED_LISTS & 0xFF); \ + mvi SINDEX[1], ((SCB_DISCONNECTED_LISTS >> 8) & 0xFF) + +mesgin_identify: + /* + * Determine whether a target is using tagged or non-tagged + * transactions by first looking at the transaction stored in + * the per-device, disconnected array. If there is no untagged + * transaction for this target, this must be a tagged transaction. + */ + and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; + INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); + bmov DINDEX, SINDEX, 2; + bmov REG0, SINDIR, 2; + cmp REG0[1], SCB_LIST_NULL je snoop_tag; + /* Untagged. Clear the busy table entry and setup the SCB. */ + bmov DINDIR, ALLONES, 2; + bmov SCBPTR, REG0, 2; + jmp setup_SCB; + +/* + * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. + * If we get one, we use the tag returned to find the proper + * SCB. After receiving the tag, look for the SCB at SCB locations tag and + * tag + 256. + */ +snoop_tag: + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x80; + } + mov NONE, SCSIDAT; /* ACK Identify MSG */ + call phase_lock; + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x1; + } + cmp LASTPHASE, P_MESGIN jne not_found_ITloop; + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x2; + } + cmp SCSIBUS, MSG_SIMPLE_Q_TAG jne not_found; +get_tag: + clr SCBPTR[1]; + mvi SCBPTR call inb_next; /* tag value */ +verify_scb: + test SCB_CONTROL,DISCONNECTED jz verify_other_scb; + mov A, SAVED_SCSIID; + cmp SCB_SCSIID, A jne verify_other_scb; + mov A, SAVED_LUN; + cmp SCB_LUN, A je setup_SCB_disconnected; +verify_other_scb: + xor SCBPTR[1], 1; + test SCBPTR[1], 0xFF jnz verify_scb; + jmp not_found; + +/* + * Ensure that the SCB the tag points to is for + * an SCB transaction to the reconnecting target. + */ +setup_SCB: + if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x10; + } + test SCB_CONTROL,DISCONNECTED jz not_found; +setup_SCB_disconnected: + and SCB_CONTROL,~DISCONNECTED; + clr SEQ_FLAGS; /* make note of IDENTIFY */ + test SCB_SGPTR, SG_LIST_NULL jnz . + 3; + bmov ALLOCFIFO_SCBPTR, SCBPTR, 2; + call allocate_fifo; + /* See if the host wants to send a message upon reconnection */ + test SCB_CONTROL, MK_MESSAGE jz mesgin_done; + mvi HOST_MSG call mk_mesg; + jmp mesgin_done; + +not_found: + SET_SEQINTCODE(NO_MATCH) + jmp mesgin_done; + +not_found_ITloop: + SET_SEQINTCODE(NO_MATCH) + jmp ITloop; + +/* + * We received a "command complete" message. Put the SCB on the complete + * queue and trigger a completion interrupt via the idle loop. Before doing + * so, check to see if there + * is a residual or the status byte is something other than STATUS_GOOD (0). + * In either of these conditions, we upload the SCB back to the host so it can + * process this information. In the case of a non zero status byte, we + * additionally interrupt the kernel driver synchronously, allowing it to + * decide if sense should be retrieved. If the kernel driver wishes to request + * sense, it will fill the kernel SCB with a request sense command, requeue + * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting + * RETURN_1 to SEND_SENSE. + */ +mesgin_complete: + + /* + * If ATN is raised, we still want to give the target a message. + * Perhaps there was a parity error on this last message byte. + * Either way, the target should take us to message out phase + * and then attempt to complete the command again. We should use a + * critical section here to guard against a timeout triggering + * for this command and setting ATN while we are still processing + * the completion. + test SCSISIGI, ATNI jnz mesgin_done; + */ + + /* + * If we are identified and have successfully sent the CDB, + * any status will do. Optimize this fast path. + */ + test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation; + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; + + /* + * If the target never sent an identify message but instead went + * to mesgin to give an invalid message, let the host abort us. + */ + test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; + + /* + * If we recevied good status but never successfully sent the + * cdb, abort the command. + */ + test SCB_SCSI_STATUS,0xff jnz complete_accepted; + test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation; +complete_accepted: + + /* + * See if we attempted to deliver a message but the target ingnored us. + */ + test SCB_CONTROL, MK_MESSAGE jz complete_nomsg; + SET_SEQINTCODE(MKMSG_FAILED) +complete_nomsg: + call queue_scb_completion; + jmp await_busfree; + +freeze_queue: + /* Cancel any pending select-out. */ + test SSTAT0, SELDO|SELINGO jnz . + 2; + and SCSISEQ0, ~ENSELO; + mov ACCUM_SAVE, A; + clr A; + add QFREEZE_COUNT, 1; + adc QFREEZE_COUNT[1], A; + or SEQ_FLAGS2, SELECTOUT_QFROZEN; + mov A, ACCUM_SAVE ret; + +/* + * Complete the current FIFO's SCB if data for this same + * SCB is not transferring in the other FIFO. + */ +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; +pkt_complete_scb_if_fifos_idle: + bmov ARG_1, SCBPTR, 2; + mvi DFFSXFRCTL, CLRCHN; + SET_MODE(M_SCSI, M_SCSI) + bmov SCBPTR, ARG_1, 2; + test SCB_FIFO_USE_COUNT, 0xFF jnz return; +queue_scb_completion: + test SCB_SCSI_STATUS,0xff jnz bad_status; + /* + * Check for residuals + */ + test SCB_SGPTR, SG_LIST_NULL jnz complete; /* No xfer */ + test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ + test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; +complete: + bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; + bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; +bad_status: + cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb; + call freeze_queue; +upload_scb: + /* + * Restore SCB TAG since we reuse this field + * in the sequencer. We don't want to corrupt + * it on the host. + */ + bmov SCB_TAG, SCBPTR, 2; + bmov SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2; + bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2; + or SCB_SGPTR, SG_STATUS_VALID ret; + +/* + * Is it a disconnect message? Set a flag in the SCB to remind us + * and await the bus going free. If this is an untagged transaction + * store the SCB id for it in our untagged target table for lookup on + * a reselction. + */ +mesgin_disconnect: + /* + * If ATN is raised, we still want to give the target a message. + * Perhaps there was a parity error on this last message byte + * or we want to abort this command. Either way, the target + * should take us to message out phase and then attempt to + * disconnect again. + * XXX - Wait for more testing. + test SCSISIGI, ATNI jnz mesgin_done; + */ + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT + jnz mesgin_proto_violation; + or SCB_CONTROL,DISCONNECTED; + test SCB_CONTROL, TAG_ENB jnz await_busfree; +queue_disc_scb: + bmov REG0, SCBPTR, 2; + INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN); + bmov DINDEX, SINDEX, 2; + bmov DINDIR, REG0, 2; + bmov SCBPTR, REG0, 2; + /* FALLTHROUGH */ +await_busfree: + and SIMODE1, ~ENBUSFREE; + if ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0) { + /* + * In the BUSFREEREV_BUG case, the + * busfree status was cleared at the + * beginning of the connection. + */ + mvi CLRSINT1,CLRBUSFREE; + } + mov NONE, SCSIDAT; /* Ack the last byte */ + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) + jnz await_busfree_not_m_dff; +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; +await_busfree_clrchn: + mvi DFFSXFRCTL, CLRCHN; +await_busfree_not_m_dff: + call clear_target_state; + test SSTAT1,REQINIT|BUSFREE jz .; + test SSTAT1, BUSFREE jnz idle_loop; + SET_SEQINTCODE(MISSED_BUSFREE) + + +/* + * Save data pointers message: + * Copying RAM values back to SCB, for Save Data Pointers message, but + * only if we've actually been into a data phase to change them. This + * protects against bogus data in scratch ram and the residual counts + * since they are only initialized when we go into data_in or data_out. + * Ack the message as soon as possible. + */ +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; +mesgin_sdptrs: + mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ + test SEQ_FLAGS, DPHASE jz ITloop; + call save_pointers; + jmp ITloop; + +save_pointers: + /* + * If we are asked to save our position at the end of the + * transfer, just mark us at the end rather than perform a + * full save. + */ + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz save_pointers_full; + or SCB_SGPTR, SG_LIST_NULL ret; + +save_pointers_full: + /* + * The SCB_DATAPTR becomes the current SHADDR. + * All other information comes directly from our residual + * state. + */ + bmov SCB_DATAPTR, SHADDR, 8; + bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8 ret; + +/* + * Restore pointers message? Data pointers are recopied from the + * SCB anytime we enter a data phase for the first time, so all + * we need to do is clear the DPHASE flag and let the data phase + * code do the rest. We also reset/reallocate the FIFO to make + * sure we have a clean start for the next data or command phase. + */ +mesgin_rdptrs: + and SEQ_FLAGS, ~DPHASE; + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz msgin_rdptrs_get_fifo; + mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; + SET_MODE(M_SCSI, M_SCSI) +msgin_rdptrs_get_fifo: + call allocate_fifo; + jmp mesgin_done; + +clear_target_state: + mvi LASTPHASE, P_BUSFREE; + /* clear target specific flags */ + mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret; + +phase_lock: + if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) { + /* + * Don't ignore persistent REQ assertions just because + * they were asserted within the bus settle delay window. + * This allows us to tolerate devices like the GEM318 + * that violate the SCSI spec. We are careful not to + * count REQ while we are waiting for it to fall during + * an async phase due to our asserted ACK. Each + * sequencer instruction takes ~25ns, so the REQ must + * last at least 100ns in order to be counted as a true + * REQ. + */ + test SCSIPHASE, 0xFF jnz phase_locked; + test SCSISIGI, ACKI jnz phase_lock; + test SCSISIGI, REQI jz phase_lock; + test SCSIPHASE, 0xFF jnz phase_locked; + test SCSISIGI, ACKI jnz phase_lock; + test SCSISIGI, REQI jz phase_lock; +phase_locked: + } else { + test SCSIPHASE, 0xFF jz .; + } + test SSTAT1, SCSIPERR jnz phase_lock; +phase_lock_latch_phase: + and LASTPHASE, PHASE_MASK, SCSISIGI ret; + +/* + * Functions to read data in Automatic PIO mode. + * + * An ACK is not sent on input from the target until SCSIDATL is read from. + * So we wait until SCSIDATL is latched (the usual way), then read the data + * byte directly off the bus using SCSIBUSL. When we have pulled the ATN + * line, or we just want to acknowledge the byte, then we do a dummy read + * from SCISDATL. The SCSI spec guarantees that the target will hold the + * data byte on the bus until we send our ACK. + * + * The assumption here is that these are called in a particular sequence, + * and that REQ is already set when inb_first is called. inb_{first,next} + * use the same calling convention as inb. + */ +inb_next: + mov NONE,SCSIDAT; /*dummy read from latch to ACK*/ +inb_next_wait: + /* + * If there is a parity error, wait for the kernel to + * see the interrupt and prepare our message response + * before continuing. + */ + test SCSIPHASE, 0xFF jz .; + test SSTAT1, SCSIPERR jnz inb_next_wait; +inb_next_check_phase: + and LASTPHASE, PHASE_MASK, SCSISIGI; + cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; +inb_first: + clr DINDEX[1]; + mov DINDEX,SINDEX; + mov DINDIR,SCSIBUS ret; /*read byte directly from bus*/ +inb_last: + mov NONE,SCSIDAT ret; /*dummy read from latch to ACK*/ + +mk_mesg: + mvi SCSISIGO, ATNO; + mov MSG_OUT,SINDEX ret; + +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; +disable_ccsgen: + test SG_STATE, FETCH_INPROG jz disable_ccsgen_fetch_done; + clr CCSGCTL; +disable_ccsgen_fetch_done: + clr SG_STATE ret; + +service_fifo: + /* + * Do we have any prefetch left??? + */ + test SG_STATE, SEGS_AVAIL jnz idle_sg_avail; + + /* + * Can this FIFO have access to the S/G cache yet? + */ + test CCSGCTL, SG_CACHE_AVAIL jz return; + + /* Did we just finish fetching segs? */ + test CCSGCTL, CCSGDONE jnz idle_sgfetch_complete; + + /* Are we actively fetching segments? */ + test CCSGCTL, CCSGENACK jnz return; + + /* + * We fetch a "cacheline aligned" and sized amount of data + * so we don't end up referencing a non-existant page. + * Cacheline aligned is in quotes because the kernel will + * set the prefetch amount to a reasonable level if the + * cacheline size is unknown. + */ + bmov SGHADDR, SCB_RESIDUAL_SGPTR, 4; + mvi SGHCNT, SG_PREFETCH_CNT; + if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) { + /* + * Need two instruction between "touches" of SGHADDR. + */ + nop; + } + and SGHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR; + mvi CCSGCTL, CCSGEN|CCSGRESET; + or SG_STATE, FETCH_INPROG ret; +idle_sgfetch_complete: + /* + * Guard against SG_CACHE_AVAIL activating during sg fetch + * request in the other FIFO. + */ + test SG_STATE, FETCH_INPROG jz return; + clr CCSGCTL; + and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR; + mvi SG_STATE, SEGS_AVAIL|LOADING_NEEDED; +idle_sg_avail: + /* Does the hardware have space for another SG entry? */ + test DFSTATUS, PRELOAD_AVAIL jz return; + /* + * On the A, preloading a segment before HDMAENACK + * comes true can clobber the shaddow address of the + * first segment in the S/G FIFO. Wait until it is + * safe to proceed. + */ + if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0) { + test DFCNTRL, HDMAENACK jz return; + } + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + bmov HADDR, CCSGRAM, 8; + } else { + bmov HADDR, CCSGRAM, 4; + } + bmov HCNT, CCSGRAM, 3; + bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; + if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { + and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3]; + } + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + /* Skip 4 bytes of pad. */ + add CCSGADDR, 4; + } +sg_advance: + clr A; /* add sizeof(struct scatter) */ + add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF; + adc SCB_RESIDUAL_SGPTR[1],A; + adc SCB_RESIDUAL_SGPTR[2],A; + adc SCB_RESIDUAL_SGPTR[3],A; + mov SINDEX, SCB_RESIDUAL_SGPTR[0]; + test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3; + or SINDEX, LAST_SEG; + clr SG_STATE; + mov SG_CACHE_PRE, SINDEX; + if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) { + /* + * Use SCSIENWRDIS so that SCSIEN is never + * modified by this operation. + */ + or DFCNTRL, PRELOADEN|HDMAEN|SCSIENWRDIS; + } else { + or DFCNTRL, PRELOADEN|HDMAEN; + } + /* + * Do we have another segment in the cache? + */ + add NONE, SG_PREFETCH_CNT_LIMIT, CCSGADDR; + jnc return; + and SG_STATE, ~SEGS_AVAIL ret; + +/* + * Initialize the DMA address and counter from the SCB. + */ +load_first_seg: + bmov HADDR, SCB_DATAPTR, 11; + and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0]; + test SCB_DATACNT[3], SG_LAST_SEG jz . + 2; + or REG_ISR, LAST_SEG; + mov SG_CACHE_PRE, REG_ISR; + mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); + /* + * Since we've are entering a data phase, we will + * rely on the SCB_RESID* fields. Initialize the + * residual and clear the full residual flag. + */ + and SCB_SGPTR[0], ~SG_FULL_RESID; + bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5; + /* If we need more S/G elements, tell the idle loop */ + test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz . + 2; + mvi SG_STATE, LOADING_NEEDED ret; + clr SG_STATE ret; + +p_data_handle_xfer: + call setjmp; + test SG_STATE, LOADING_NEEDED jnz service_fifo; +p_data_clear_handler: + or LONGJMP_ADDR[1], INVALID_ADDR ret; + +p_data: + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed; + SET_SEQINTCODE(PROTO_VIOLATION) +p_data_allowed: + + test SEQ_FLAGS, DPHASE jz data_phase_initialize; + + /* + * If we re-enter the data phase after going through another + * phase, our transfer location has almost certainly been + * corrupted by the interveining, non-data, transfers. Ask + * the host driver to fix us up based on the transfer residual + * unless we already know that we should be bitbucketing. + */ + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; + SET_SEQINTCODE(PDATA_REINIT) + jmp data_phase_inbounds; + +p_data_bitbucket: + /* + * Turn on `Bit Bucket' mode, wait until the target takes + * us to another phase, and then notify the host. + */ + mov SAVED_MODE, MODE_PTR; + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) + jnz bitbucket_not_m_dff; + /* + * Ensure that any FIFO contents are cleared out and the + * FIFO free'd prior to starting the BITBUCKET. BITBUCKET + * doesn't discard data already in the FIFO. + */ + mvi DFFSXFRCTL, RSTCHN|CLRSHCNT; + SET_MODE(M_SCSI, M_SCSI) +bitbucket_not_m_dff: + or SXFRCTL1,BITBUCKET; + /* Wait for non-data phase. */ + test SCSIPHASE, ~DATA_PHASE_MASK jz .; + and SXFRCTL1, ~BITBUCKET; + RESTORE_MODE(SAVED_MODE) +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + SET_SEQINTCODE(DATA_OVERRUN) + jmp ITloop; + +data_phase_initialize: + test SCB_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket; + call load_first_seg; +data_phase_inbounds: + /* We have seen a data phase at least once. */ + or SEQ_FLAGS, DPHASE; + mov SAVED_MODE, MODE_PTR; + test SG_STATE, LOADING_NEEDED jz data_group_dma_loop; + call p_data_handle_xfer; +data_group_dma_loop: + /* + * The transfer is complete if either the last segment + * completes or the target changes phase. Both conditions + * will clear SCSIEN. + */ + call idle_loop_service_fifos; + call idle_loop_cchan; + call idle_loop_gsfifo; + RESTORE_MODE(SAVED_MODE) + test DFCNTRL, SCSIEN jnz data_group_dma_loop; + +data_group_dmafinish: + /* + * The transfer has terminated either due to a phase + * change, and/or the completion of the last segment. + * We have two goals here. Do as much other work + * as possible while the data fifo drains on a read + * and respond as quickly as possible to the standard + * messages (save data pointers/disconnect and command + * complete) that usually follow a data phase. + */ + call calc_residual; + + /* + * Go ahead and shut down the DMA engine now. + */ + test DFCNTRL, DIRECTION jnz data_phase_finish; +data_group_fifoflush: + if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { + or DFCNTRL, FIFOFLUSH; + } + /* + * We have enabled the auto-ack feature. This means + * that the controller may have already transferred + * some overrun bytes into the data FIFO and acked them + * on the bus. The only way to detect this situation is + * to wait for LAST_SEG_DONE to come true on a completed + * transfer and then test to see if the data FIFO is + * non-empty. We know there is more data yet to transfer + * if SG_LIST_NULL is not yet set, thus there cannot be + * an overrun. + */ + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_finish; + test SG_CACHE_SHADOW, LAST_SEG_DONE jz .; + test DFSTATUS, FIFOEMP jnz data_phase_finish; + /* Overrun */ + jmp p_data; +data_phase_finish: + /* + * If the target has left us in data phase, loop through + * the dma code again. We will only loop if there is a + * data overrun. + */ + if ((ahd->flags & AHD_TARGETROLE) != 0) { + test SSTAT0, TARGET jnz data_phase_done; + } + if ((ahd->flags & AHD_INITIATORROLE) != 0) { + test SSTAT1, REQINIT jz .; + test SCSIPHASE, DATA_PHASE_MASK jnz p_data; + } + +data_phase_done: + /* Kill off any pending prefetch */ + call disable_ccsgen; + or LONGJMP_ADDR[1], INVALID_ADDR; + + if ((ahd->flags & AHD_TARGETROLE) != 0) { + test SEQ_FLAGS, DPHASE_PENDING jz ITloop; + /* + and SEQ_FLAGS, ~DPHASE_PENDING; + * For data-in phases, wait for any pending acks from the + * initiator before changing phase. We only need to + * send Ignore Wide Residue messages for data-in phases. + test DFCNTRL, DIRECTION jz target_ITloop; + test SSTAT1, REQINIT jnz .; + test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jz target_ITloop; + SET_MODE(M_SCSI, M_SCSI) + test NEGCONOPTS, WIDEXFER jz target_ITloop; + */ + /* + * Issue an Ignore Wide Residue Message. + mvi P_MESGIN|BSYO call change_phase; + mvi MSG_IGN_WIDE_RESIDUE call target_outb; + mvi 1 call target_outb; + jmp target_ITloop; + */ + } else { + jmp ITloop; + } + +/* + * We assume that, even though data may still be + * transferring to the host, that the SCSI side of + * the DMA engine is now in a static state. This + * allows us to update our notion of where we are + * in this transfer. + * + * If, by chance, we stopped before being able + * to fetch additional segments for this transfer, + * yet the last S/G was completely exhausted, + * call our idle loop until it is able to load + * another segment. This will allow us to immediately + * pickup on the next segment on the next data phase. + * + * If we happened to stop on the last segment, then + * our residual information is still correct from + * the idle loop and there is no need to perform + * any fixups. + */ +residual_before_last_seg: + test MDFFSTAT, SHVALID jnz sgptr_fixup; + /* + * Can never happen from an interrupt as the packetized + * hardware will only interrupt us once SHVALID or + * LAST_SEG_DONE. + */ + call idle_loop_service_fifos; + RESTORE_MODE(SAVED_MODE) + /* FALLTHROUGH */ +calc_residual: + test SG_CACHE_SHADOW, LAST_SEG jz residual_before_last_seg; + /* Record if we've consumed all S/G entries */ + test MDFFSTAT, SHVALID jz . + 2; + bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; + or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL ret; + +sgptr_fixup: + /* + * Fixup the residual next S/G pointer. The S/G preload + * feature of the chip allows us to load two elements + * in addition to the currently active element. We + * store the bottom byte of the next S/G pointer in + * the SG_CACHE_PTR register so we can restore the + * correct value when the DMA completes. If the next + * sg ptr value has advanced to the point where higher + * bytes in the address have been affected, fix them + * too. + */ + test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done; + test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done; + add SCB_RESIDUAL_SGPTR[1], -1; + adc SCB_RESIDUAL_SGPTR[2], -1; + adc SCB_RESIDUAL_SGPTR[3], -1; +sgptr_fixup_done: + and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; + clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */ + bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret; + +export timer_isr: + call issue_cmdcmplt; + mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO; + if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { + /* + * In H2A4, the mode pointer is not saved + * for intvec2, but is restored on iret. + * This can lead to the restoration of a + * bogus mode ptr. Manually clear the + * intmask bits and do a normal return + * to compensate. + */ + and SEQINTCTL, ~(INTMASK2|INTMASK1) ret; + } else { + or SEQINTCTL, IRET ret; + } + +export seq_isr: + if ((ahd->features & AHD_RTI) == 0) { + /* + * On RevA Silicon, if the target returns us to data-out + * after we have already trained for data-out, it is + * possible for us to transition the free running clock to + * data-valid before the required 100ns P1 setup time (8 P1 + * assertions in fast-160 mode). This will only happen if + * this L-Q is a continuation of a data transfer for which + * we have already prefetched data into our FIFO (LQ/Data + * followed by LQ/Data for the same write transaction). + * This can cause some target implementations to miss the + * first few data transfers on the bus. We detect this + * situation by noticing that this is the first data transfer + * after an LQ (LQIWORKONLQ true), that the data transfer is + * a continuation of a transfer already setup in our FIFO + * (SAVEPTRS interrupt), and that the transaction is a write + * (DIRECTION set in DFCNTRL). The delay is performed by + * disabling SCSIEN until we see the first REQ from the + * target. + * + * First instruction in an ISR cannot be a branch on + * Rev A. Snapshot LQISTAT2 so the status is not missed + * and deffer the test by one instruction. + */ + mov REG_ISR, LQISTAT2; + test REG_ISR, LQIWORKONLQ jz main_isr; + test SEQINTSRC, SAVEPTRS jz main_isr; + test LONGJMP_ADDR[1], INVALID_ADDR jz saveptr_active_fifo; + /* + * Switch to the active FIFO after clearing the snapshot + * savepointer in the current FIFO. We do this so that + * a pending CTXTDONE or SAVEPTR is visible in the active + * FIFO. This status is the only way we can detect if we + * have lost the race (e.g. host paused us) and our attepts + * to disable the channel occurred after all REQs were + * already seen and acked (REQINIT never comes true). + */ + mvi DFFSXFRCTL, CLRCHN; + xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); + test DFCNTRL, DIRECTION jz interrupt_return; + and DFCNTRL, ~SCSIEN; +snapshot_wait_data_valid: + test SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz snapshot_data_valid; + test SSTAT1, REQINIT jz snapshot_wait_data_valid; +snapshot_data_valid: + or DFCNTRL, SCSIEN; + or SEQINTCTL, IRET ret; +snapshot_saveptr: + mvi DFFSXFRCTL, CLRCHN; + or SEQINTCTL, IRET ret; +main_isr: + } + test SEQINTSRC, CFG4DATA jnz cfg4data_intr; + test SEQINTSRC, CFG4ISTAT jnz cfg4istat_intr; + test SEQINTSRC, SAVEPTRS jnz saveptr_intr; + test SEQINTSRC, CFG4ICMD jnz cfg4icmd_intr; + SET_SEQINTCODE(INVALID_SEQINT) + +/* + * There are two types of save pointers interrupts: + * The first is a snapshot save pointers where the current FIFO is not + * active and contains a snapshot of the current poniter information. + * This happens between packets in a stream for a single L_Q. Since we + * are not performing a pointer save, we can safely clear the channel + * so it can be used for other transactions. On RTI capable controllers, + * where snapshots can, and are, disabled, the code to handle this type + * of snapshot is not active. + * + * The second case is a save pointers on an active FIFO which occurs + * if the target changes to a new L_Q or busfrees/QASes and the transfer + * has a residual. This should occur coincident with a ctxtdone. We + * disable the interrupt and allow our active routine to handle the + * save. + */ +saveptr_intr: + if ((ahd->features & AHD_RTI) == 0) { + test LONGJMP_ADDR[1], INVALID_ADDR jnz snapshot_saveptr; + } +saveptr_active_fifo: + and SEQIMODE, ~ENSAVEPTRS; + or SEQINTCTL, IRET ret; + +cfg4data_intr: + test SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun_inc_use_count; + call load_first_seg; + call pkt_handle_xfer; + inc SCB_FIFO_USE_COUNT; +interrupt_return: + or SEQINTCTL, IRET ret; + +cfg4istat_intr: + call freeze_queue; + add NONE, -13, SCB_CDB_LEN; + jnc cfg4istat_have_sense_addr; + test SCB_CDB_LEN, SCB_CDB_LEN_PTR jnz cfg4istat_have_sense_addr; + /* + * Host sets up address/count and enables transfer. + */ + SET_SEQINTCODE(CFG4ISTAT_INTR) + jmp cfg4istat_setup_handler; +cfg4istat_have_sense_addr: + bmov HADDR, SCB_SENSE_BUSADDR, 4; + mvi HCNT[1], (AHD_SENSE_BUFSIZE >> 8); + mvi SG_CACHE_PRE, LAST_SEG; + mvi DFCNTRL, PRELOADEN|SCSIEN|HDMAEN; +cfg4istat_setup_handler: + /* + * Status pkt is transferring to host. + * Wait in idle loop for transfer to complete. + * If a command completed before an attempted + * task management function completed, notify the host. + */ + test SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func; + SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) +cfg4istat_no_taskmgmt_func: + call pkt_handle_status; + or SEQINTCTL, IRET ret; + +cfg4icmd_intr: + /* + * In the case of DMAing a CDB from the host, the normal + * CDB buffer is formatted with an 8 byte address followed + * by a 1 byte count. + */ + bmov HADDR[0], SCB_HOST_CDB_PTR, 9; + mvi SG_CACHE_PRE, LAST_SEG; + mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN); + call pkt_handle_cdb; + or SEQINTCTL, IRET ret; + +/* + * See if the target has gone on in this context creating an + * overrun condition. For the write case, the hardware cannot + * ack bytes until data are provided. So, if the target begins + * another packet without changing contexts, implying we are + * not sitting on a packet boundary, we are in an overrun + * situation. For the read case, the hardware will continue to + * ack bytes into the FIFO, and may even ack the last overrun packet + * into the FIFO. If the FIFO should become non-empty, we are in + * a read overrun case. + */ +#define check_overrun \ + /* Not on a packet boundary. */ \ + test MDFFSTAT, DLZERO jz pkt_handle_overrun; \ + test DFSTATUS, FIFOEMP jz pkt_handle_overrun + +pkt_handle_xfer: + test SG_STATE, LOADING_NEEDED jz pkt_last_seg; + call setjmp; + test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; + test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; + test SCSISIGO, ATNO jnz . + 2; + test SSTAT2, NONPACKREQ jz pkt_service_fifo; + /* + * Defer handling of this NONPACKREQ until we + * can be sure it pertains to this FIFO. SAVEPTRS + * will not be asserted if the NONPACKREQ is for us, + * so we must simulate it if shaddow is valid. If + * shaddow is not valid, keep running this FIFO until we + * have satisfied the transfer by loading segments and + * waiting for either shaddow valid or last_seg_done. + */ + test MDFFSTAT, SHVALID jnz pkt_saveptrs; +pkt_service_fifo: + test SG_STATE, LOADING_NEEDED jnz service_fifo; +pkt_last_seg: + call setjmp; + test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs; + test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_last_seg_done; + test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2; + test SCSISIGO, ATNO jnz . + 2; + test SSTAT2, NONPACKREQ jz return; + test MDFFSTAT, SHVALID jz return; + /* FALLTHROUGH */ + +/* + * Either a SAVEPTRS interrupt condition is pending for this FIFO + * or we have a pending NONPACKREQ for this FIFO. We differentiate + * between the two by capturing the state of the SAVEPTRS interrupt + * prior to clearing this status and executing the common code for + * these two cases. + */ +pkt_saveptrs: +BEGIN_CRITICAL; + if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { + or DFCNTRL, FIFOFLUSH; + } + mov REG0, SEQINTSRC; + call calc_residual; + call save_pointers; + mvi CLRSEQINTSRC, CLRSAVEPTRS; + call disable_ccsgen; + or SEQIMODE, ENSAVEPTRS; + test DFCNTRL, DIRECTION jnz pkt_saveptrs_check_status; + test DFSTATUS, FIFOEMP jnz pkt_saveptrs_check_status; + /* + * Keep a handler around for this FIFO until it drains + * to the host to guarantee that we don't complete the + * command to the host before the data arrives. + */ +pkt_saveptrs_wait_fifoemp: + call setjmp; + test DFSTATUS, FIFOEMP jz return; +pkt_saveptrs_check_status: + or LONGJMP_ADDR[1], INVALID_ADDR; + test REG0, SAVEPTRS jz unexpected_nonpkt_phase; + dec SCB_FIFO_USE_COUNT; + test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle; + mvi DFFSXFRCTL, CLRCHN ret; +END_CRITICAL; + +/* + * LAST_SEG_DONE status has been seen in the current FIFO. + * This indicates that all of the allowed data for this + * command has transferred across the SCSI and host buses. + * Check for overrun and see if we can complete this command. + */ +pkt_last_seg_done: +BEGIN_CRITICAL; + /* + * Mark transfer as completed. + */ + or SCB_SGPTR, SG_LIST_NULL; + + /* + * Wait for the current context to finish to verify that + * no overrun condition has occurred. + */ + test SEQINTSRC, CTXTDONE jnz pkt_ctxt_done; + call setjmp; +pkt_wait_ctxt_done_loop: + test SEQINTSRC, CTXTDONE jnz pkt_ctxt_done; + /* + * A sufficiently large overrun or a NONPACKREQ may + * prevent CTXTDONE from ever asserting, so we must + * poll for these statuses too. + */ + check_overrun; + test SSTAT2, NONPACKREQ jz return; + test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; + /* FALLTHROUGH */ + +pkt_ctxt_done: + check_overrun; + or LONGJMP_ADDR[1], INVALID_ADDR; + /* + * If status has been received, it is safe to skip + * the check to see if another FIFO is active because + * LAST_SEG_DONE has been observed. However, we check + * the FIFO anyway since it costs us only one extra + * instruction to leverage common code to perform the + * SCB completion. + */ + dec SCB_FIFO_USE_COUNT; + test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle; + mvi DFFSXFRCTL, CLRCHN ret; +END_CRITICAL; + +/* + * Must wait until CDB xfer is over before issuing the + * clear channel. + */ +pkt_handle_cdb: + call setjmp; + test SG_CACHE_SHADOW, LAST_SEG_DONE jz return; + or LONGJMP_ADDR[1], INVALID_ADDR; + mvi DFFSXFRCTL, CLRCHN ret; + +/* + * Watch over the status transfer. Our host sense buffer is + * large enough to take the maximum allowed status packet. + * None-the-less, we must still catch and report overruns to + * the host. Additionally, properly catch unexpected non-packet + * phases that are typically caused by CRC errors in status packet + * transmission. + */ +pkt_handle_status: + call setjmp; + test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun; + test SEQINTSRC, CTXTDONE jz pkt_status_check_nonpackreq; + test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun; +pkt_status_IU_done: + if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) { + or DFCNTRL, FIFOFLUSH; + } + test DFSTATUS, FIFOEMP jz return; +BEGIN_CRITICAL; + or LONGJMP_ADDR[1], INVALID_ADDR; + mvi SCB_SCSI_STATUS, STATUS_PKT_SENSE; + or SCB_CONTROL, STATUS_RCVD; + jmp pkt_complete_scb_if_fifos_idle; +END_CRITICAL; +pkt_status_check_overrun: + /* + * Status PKT overruns are uncerimoniously recovered with a + * bus reset. If we've overrun, let the host know so that + * recovery can be performed. + * + * LAST_SEG_DONE has been observed. If either CTXTDONE or + * a NONPACKREQ phase change have occurred and the FIFO is + * empty, there is no overrun. + */ + test DFSTATUS, FIFOEMP jz pkt_status_report_overrun; + test SEQINTSRC, CTXTDONE jz . + 2; + test DFSTATUS, FIFOEMP jnz pkt_status_IU_done; + test SCSIPHASE, ~DATA_PHASE_MASK jz return; + test DFSTATUS, FIFOEMP jnz pkt_status_check_nonpackreq; +pkt_status_report_overrun: + SET_SEQINTCODE(STATUS_OVERRUN) + /* SEQUENCER RESTARTED */ +pkt_status_check_nonpackreq: + /* + * CTXTDONE may be held off if a NONPACKREQ is associated with + * the current context. If a NONPACKREQ is observed, decide + * if it is for the current context. If it is for the current + * context, we must defer NONPACKREQ processing until all data + * has transferred to the host. + */ + test SCSIPHASE, ~DATA_PHASE_MASK jz return; + test SCSISIGO, ATNO jnz . + 2; + test SSTAT2, NONPACKREQ jz return; + test SEQINTSRC, CTXTDONE jnz pkt_status_IU_done; + test DFSTATUS, FIFOEMP jz return; + /* + * The unexpected nonpkt phase handler assumes that any + * data channel use will have a FIFO reference count. It + * turns out that the status handler doesn't need a refernce + * count since the status received flag, and thus completion + * processing, cannot be set until the handler is finished. + * We increment the count here to make the nonpkt handler + * happy. + */ + inc SCB_FIFO_USE_COUNT; + /* FALLTHROUGH */ + +/* + * Nonpackreq is a polled status. It can come true in three situations: + * we have received an L_Q, we have sent one or more L_Qs, or there is no + * L_Q context associated with this REQ (REQ occurs immediately after a + * (re)selection). Routines that know that the context responsible for this + * nonpackreq call directly into unexpected_nonpkt_phase. In the case of the + * top level idle loop, we exhaust all active contexts prior to determining that + * we simply do not have the full I_T_L_Q for this phase. + */ +unexpected_nonpkt_phase_find_ctxt: + /* + * This nonpackreq is most likely associated with one of the tags + * in a FIFO or an outgoing LQ. Only treat it as an I_T only + * nonpackreq if we've cleared out the FIFOs and handled any + * pending SELDO. + */ +SET_SRC_MODE M_SCSI; +SET_DST_MODE M_SCSI; + and A, FIFO1FREE|FIFO0FREE, DFFSTAT; + cmp A, FIFO1FREE|FIFO0FREE jne return; + test SSTAT0, SELDO jnz return; + mvi SCBPTR[1], SCB_LIST_NULL; +unexpected_nonpkt_phase: + test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz . + 3; +SET_SRC_MODE M_DFF0; +SET_DST_MODE M_DFF0; + or LONGJMP_ADDR[1], INVALID_ADDR; + dec SCB_FIFO_USE_COUNT; + mvi DFFSXFRCTL, CLRCHN; + mvi CLRSINT2, CLRNONPACKREQ; + test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase; + SET_SEQINTCODE(ENTERING_NONPACK) + jmp ITloop; + +illegal_phase: + SET_SEQINTCODE(ILLEGAL_PHASE) + jmp ITloop; + +/* + * We have entered an overrun situation. If we have working + * BITBUCKET, flip that on and let the hardware eat any overrun + * data. Otherwise use an overrun buffer in the host to simulate + * BITBUCKET. + */ +pkt_handle_overrun_inc_use_count: + inc SCB_FIFO_USE_COUNT; +pkt_handle_overrun: + SET_SEQINTCODE(CFG4OVERRUN) + call freeze_queue; + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) { + or DFFSXFRCTL, DFFBITBUCKET; +SET_SRC_MODE M_DFF1; +SET_DST_MODE M_DFF1; + } else { + call load_overrun_buf; + mvi DFCNTRL, (HDMAEN|SCSIEN|PRELOADEN); + } + call setjmp; + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { + test DFSTATUS, PRELOAD_AVAIL jz overrun_load_done; + call load_overrun_buf; + or DFCNTRL, PRELOADEN; +overrun_load_done: + test SEQINTSRC, CTXTDONE jnz pkt_overrun_end; + } else { + test DFFSXFRCTL, DFFBITBUCKET jz pkt_overrun_end; + } + test SSTAT2, NONPACKREQ jz return; +pkt_overrun_end: + or SCB_RESIDUAL_SGPTR, SG_OVERRUN_RESID; + test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase; + dec SCB_FIFO_USE_COUNT; + or LONGJMP_ADDR[1], INVALID_ADDR; + test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle; + mvi DFFSXFRCTL, CLRCHN ret; + +if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { +load_overrun_buf: + /* + * Load a dummy segment if preload space is available. + */ + mov HADDR[0], SHARED_DATA_ADDR; + add HADDR[1], PKT_OVERRUN_BUFOFFSET, SHARED_DATA_ADDR[1]; + mov ACCUM_SAVE, A; + clr A; + adc HADDR[2], A, SHARED_DATA_ADDR[2]; + adc HADDR[3], A, SHARED_DATA_ADDR[3]; + mov A, ACCUM_SAVE; + bmov HADDR[4], ALLZEROS, 4; + /* PKT_OVERRUN_BUFSIZE is a multiple of 256 */ + clr HCNT[0]; + mvi HCNT[1], ((PKT_OVERRUN_BUFSIZE >> 8) & 0xFF); + clr HCNT[2] ret; +} diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_core.c linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_core.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_core.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_core.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,9541 @@ +/* + * Core routines and tables shareable across OS platforms. + * + * Copyright (c) 1994-2002 Justin T. Gibbs. + * Copyright (c) 2000-2003 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#197 $ + * + * $FreeBSD$ + */ + +#ifdef __linux__ +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" +#include "aicasm/aicasm_insformat.h" +#else +#include +#include +#include +#endif + +/******************************** Globals *************************************/ +struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq); + +/***************************** Lookup Tables **********************************/ +char *ahd_chip_names[] = +{ + "NONE", + "aic7901", + "aic7902", + "aic7901A" +}; +static const u_int num_chip_names = NUM_ELEMENTS(ahd_chip_names); + +/* + * Hardware error codes. + */ +struct ahd_hard_error_entry { + uint8_t errno; + char *errmesg; +}; + +static struct ahd_hard_error_entry ahd_hard_errors[] = { + { DSCTMOUT, "Discard Timer has timed out" }, + { ILLOPCODE, "Illegal Opcode in sequencer program" }, + { SQPARERR, "Sequencer Parity Error" }, + { DPARERR, "Data-path Parity Error" }, + { MPARERR, "Scratch or SCB Memory Parity Error" }, + { CIOPARERR, "CIOBUS Parity Error" }, +}; +static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors); + +static struct ahd_phase_table_entry ahd_phase_table[] = +{ + { P_DATAOUT, MSG_NOOP, "in Data-out phase" }, + { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" }, + { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" }, + { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" }, + { P_COMMAND, MSG_NOOP, "in Command phase" }, + { P_MESGOUT, MSG_NOOP, "in Message-out phase" }, + { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" }, + { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" }, + { P_BUSFREE, MSG_NOOP, "while idle" }, + { 0, MSG_NOOP, "in unknown phase" } +}; + +/* + * In most cases we only wish to itterate over real phases, so + * exclude the last element from the count. + */ +static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1; + +/* Our Sequencer Program */ +#include "aic79xx_seq.h" + +/**************************** Function Declarations ***************************/ +static void ahd_handle_transmission_error(struct ahd_softc *ahd); +static void ahd_handle_lqiphase_error(struct ahd_softc *ahd, + u_int lqistat1); +static int ahd_handle_pkt_busfree(struct ahd_softc *ahd, + u_int busfreetime); +static int ahd_handle_nonpkt_busfree(struct ahd_softc *ahd); +static void ahd_handle_proto_violation(struct ahd_softc *ahd); +static void ahd_force_renegotiation(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); + +static struct ahd_tmode_tstate* + ahd_alloc_tstate(struct ahd_softc *ahd, + u_int scsi_id, char channel); +#ifdef AHD_TARGET_MODE +static void ahd_free_tstate(struct ahd_softc *ahd, + u_int scsi_id, char channel, int force); +#endif +static void ahd_devlimited_syncrate(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *, + u_int *period, + u_int *ppr_options, + role_t role); +static void ahd_update_neg_table(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct ahd_transinfo *tinfo); +static void ahd_update_pending_scbs(struct ahd_softc *ahd); +static void ahd_fetch_devinfo(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_scb_devinfo(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct scb *scb); +static void ahd_setup_initiator_msgout(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct scb *scb); +static void ahd_build_transfer_msg(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_construct_sdtr(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int period, u_int offset); +static void ahd_construct_wdtr(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int bus_width); +static void ahd_construct_ppr(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int period, u_int offset, + u_int bus_width, u_int ppr_options); +static void ahd_clear_msg_state(struct ahd_softc *ahd); +static void ahd_handle_message_phase(struct ahd_softc *ahd); +typedef enum { + AHDMSG_1B, + AHDMSG_2B, + AHDMSG_EXT +} ahd_msgtype; +static int ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, + u_int msgval, int full); +static int ahd_parse_msg(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static int ahd_handle_msg_reject(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_handle_ign_wide_residue(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_reinitialize_dataptrs(struct ahd_softc *ahd); +static void ahd_handle_devreset(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + u_int lun, cam_status status, + char *message, int verbose_level); +#if AHD_TARGET_MODE +static void ahd_setup_target_msgin(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, + struct scb *scb); +#endif + +static u_int ahd_sglist_size(struct ahd_softc *ahd); +static u_int ahd_sglist_allocsize(struct ahd_softc *ahd); +static bus_dmamap_callback_t + ahd_dmamap_cb; +static void ahd_initialize_hscbs(struct ahd_softc *ahd); +static int ahd_init_scbdata(struct ahd_softc *ahd); +static void ahd_fini_scbdata(struct ahd_softc *ahd); +static void ahd_setup_iocell_workaround(struct ahd_softc *ahd); +static void ahd_iocell_first_selection(struct ahd_softc *ahd); +static void ahd_add_col_list(struct ahd_softc *ahd, + struct scb *scb, u_int col_idx); +static void ahd_rem_col_list(struct ahd_softc *ahd, + struct scb *scb); +static void ahd_chip_init(struct ahd_softc *ahd); +static void ahd_qinfifo_requeue(struct ahd_softc *ahd, + struct scb *prev_scb, + struct scb *scb); +static int ahd_qinfifo_count(struct ahd_softc *ahd); +static int ahd_search_scb_list(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status, + ahd_search_action action, + u_int *list_head, u_int tid); +static void ahd_stitch_tid_list(struct ahd_softc *ahd, + u_int tid_prev, u_int tid_cur, + u_int tid_next); +static void ahd_add_scb_to_free_list(struct ahd_softc *ahd, + u_int scbid); +static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, + u_int prev, u_int next, u_int tid); +static void ahd_reset_current_bus(struct ahd_softc *ahd); +static ahd_callback_t ahd_reset_poll; +static ahd_callback_t ahd_stat_timer; +#ifdef AHD_DUMP_SEQ +static void ahd_dumpseq(struct ahd_softc *ahd); +#endif +static void ahd_loadseq(struct ahd_softc *ahd); +static int ahd_check_patch(struct ahd_softc *ahd, + struct patch **start_patch, + u_int start_instr, u_int *skip_addr); +static u_int ahd_resolve_seqaddr(struct ahd_softc *ahd, + u_int address); +static void ahd_download_instr(struct ahd_softc *ahd, + u_int instrptr, uint8_t *dconsts); +static int ahd_probe_stack_size(struct ahd_softc *ahd); +#ifdef AHD_TARGET_MODE +static void ahd_queue_lstate_event(struct ahd_softc *ahd, + struct ahd_tmode_lstate *lstate, + u_int initiator_id, + u_int event_type, + u_int event_arg); +static void ahd_update_scsiid(struct ahd_softc *ahd, + u_int targid_mask); +static int ahd_handle_target_cmd(struct ahd_softc *ahd, + struct target_cmd *cmd); +#endif + +/******************************** Private Inlines *****************************/ +static __inline void ahd_assert_atn(struct ahd_softc *ahd); +static __inline int ahd_currently_packetized(struct ahd_softc *ahd); +static __inline int ahd_set_active_fifo(struct ahd_softc *ahd); + +static __inline void +ahd_assert_atn(struct ahd_softc *ahd) +{ + ahd_outb(ahd, SCSISIGO, ATNO); +} + +/* + * Determine if the current connection has a packetized + * agreement. This does not necessarily mean that we + * are currently in a packetized transfer. We could + * just as easily be sending or receiving a message. + */ +static __inline int +ahd_currently_packetized(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + int packetized; + + saved_modes = ahd_save_modes(ahd); + if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) { + /* + * The packetized bit refers to the last + * connection, not the current one. Check + * for non-zero LQISTATE instead. + */ + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + packetized = ahd_inb(ahd, LQISTATE) != 0; + } else { + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED; + } + ahd_restore_modes(ahd, saved_modes); + return (packetized); +} + +static __inline int +ahd_set_active_fifo(struct ahd_softc *ahd) +{ + u_int active_fifo; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO; + switch (active_fifo) { + case 0: + case 1: + ahd_set_modes(ahd, active_fifo, active_fifo); + return (1); + default: + return (0); + } +} + +/************************* Sequencer Execution Control ************************/ +/* + * Restart the sequencer program from address zero + */ +void +ahd_restart(struct ahd_softc *ahd) +{ + + ahd_pause(ahd); + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + /* No more pending messages */ + ahd_clear_msg_state(ahd); + ahd_outb(ahd, SCSISIGO, 0); /* De-assert BSY */ + ahd_outb(ahd, MSG_OUT, MSG_NOOP); /* No message to send */ + ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET); + ahd_outb(ahd, SEQINTCTL, 0); + ahd_outb(ahd, LASTPHASE, P_BUSFREE); + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_outb(ahd, SAVED_SCSIID, 0xFF); + ahd_outb(ahd, SAVED_LUN, 0xFF); + + /* + * Ensure that the sequencer's idea of TQINPOS + * matches our own. The sequencer increments TQINPOS + * only after it sees a DMA complete and a reset could + * occur before the increment leaving the kernel to believe + * the command arrived but the sequencer to not. + */ + ahd_outb(ahd, TQINPOS, ahd->tqinfifonext); + + /* Always allow reselection */ + ahd_outb(ahd, SCSISEQ1, + ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP)); + /* Ensure that no DMA operations are in progress */ + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + ahd_outb(ahd, SCBHCNT, 0); + ahd_outb(ahd, CCSCBCTL, CCSCBRESET); + ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); + ahd_unpause(ahd); +} + +void +ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) +{ + ahd_mode_state saved_modes; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_FIFOS) != 0) + printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo); +#endif + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, fifo, fifo); + ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT); + if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) + ahd_outb(ahd, CCSGCTL, CCSGRESET); + ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); + ahd_outb(ahd, SG_STATE, 0); + ahd_restore_modes(ahd, saved_modes); +} + +/************************* Input/Output Queues ********************************/ +/* + * Flush and completed commands that are sitting in the command + * complete queues down on the chip but have yet to be dma'ed back up. + */ +void +ahd_flush_qoutfifo(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int saved_scbptr; + u_int ccscbctl; + u_int scbid; + u_int next_scbid; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + saved_scbptr = ahd_get_scbptr(ahd); + + /* + * Wait for any inprogress DMA to complete and clear DMA state + * if this if for an SCB in the qinfifo. + */ + while ((ccscbctl = ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) { + + if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) { + if ((ccscbctl & ARRDONE) != 0) + break; + } else if ((ccscbctl & CCSCBDONE) != 0) + break; + ahd_delay(200); + } + if ((ccscbctl & CCSCBDIR) != 0) + ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN)); + + /* + * Complete any SCBs that just finished being + * DMA'ed into the qoutfifo. + */ + ahd_run_qoutfifo(ahd); + + /* + * Manually update/complete any completed SCBs that are waiting to be + * DMA'ed back up to the host. + */ + scbid = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); + while (!SCBID_IS_NULL(scbid)) { + uint8_t *hscb_ptr; + u_int i; + + ahd_set_scbptr(ahd, scbid); + next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Warning - DMA-up and complete " + "SCB %d invalid\n", ahd_name(ahd), scbid); + continue; + } + hscb_ptr = (uint8_t *)scb->hscb; + for (i = 0; i < sizeof(struct hardware_scb); i++) + *hscb_ptr++ = ahd_inb_scbram(ahd, SCB_BASE + i); + + ahd_complete_scb(ahd, scb); + scbid = next_scbid; + } + ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); + + scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD); + while (!SCBID_IS_NULL(scbid)) { + + ahd_set_scbptr(ahd, scbid); + next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Warning - Complete SCB %d invalid\n", + ahd_name(ahd), scbid); + continue; + } + + ahd_complete_scb(ahd, scb); + scbid = next_scbid; + } + ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); + ahd_set_scbptr(ahd, saved_scbptr); + + /* + * Flush the good status FIFO for compelted packetized commands. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) { + scbid = (ahd_inb(ahd, GSFIFO+1) << 8) + | ahd_inb(ahd, GSFIFO); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Warning - GSFIFO SCB %d invalid\n", + ahd_name(ahd), scbid); + continue; + } + ahd_complete_scb(ahd, scb); + } + + /* + * Restore state. + */ + ahd_restore_modes(ahd, saved_modes); + ahd->flags |= AHD_UPDATE_PEND_CMDS; +} + +void +ahd_run_qoutfifo(struct ahd_softc *ahd) +{ + struct scb *scb; + u_int scb_index; + + if ((ahd->flags & AHD_RUNNING_QOUTFIFO) != 0) + panic("ahd_run_qoutfifo recursion"); + ahd->flags |= AHD_RUNNING_QOUTFIFO; + ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD); + while ((ahd->qoutfifo[ahd->qoutfifonext] + & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) { + + scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext] + & ~QOUTFIFO_ENTRY_VALID_LE); + scb = ahd_lookup_scb(ahd, scb_index); + if (scb == NULL) { + printf("%s: WARNING no command for scb %d " + "(cmdcmplt)\nQOUTPOS = %d\n", + ahd_name(ahd), scb_index, + ahd->qoutfifonext); + ahd_dump_card_state(ahd); + } else + ahd_complete_scb(ahd, scb); + + ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1); + if (ahd->qoutfifonext == 0) + ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE; + } + ahd->flags &= ~AHD_RUNNING_QOUTFIFO; +} + +/************************* Interrupt Handling *********************************/ +void +ahd_handle_hwerrint(struct ahd_softc *ahd) +{ + /* + * Some catastrophic hardware error has occurred. + * Print it for the user and disable the controller. + */ + int i; + int error; + + error = ahd_inb(ahd, ERROR); + for (i = 0; i < num_errors; i++) { + if ((error & ahd_hard_errors[i].errno) != 0) + printf("%s: hwerrint, %s\n", + ahd_name(ahd), ahd_hard_errors[i].errmesg); + } + + ahd_dump_card_state(ahd); + panic("BRKADRINT"); + + /* Tell everyone that this HBA is no longer available */ + ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN, + CAM_NO_HBA); + + /* Tell the system that this controller has gone away. */ + ahd_free(ahd); +} + +void +ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) +{ + u_int seqintcode; + + /* + * Save the sequencer interrupt code and clear the SEQINT + * bit. We will unpause the sequencer, if appropriate, + * after servicing the request. + */ + seqintcode = ahd_inb(ahd, SEQINTCODE); + ahd_outb(ahd, CLRINT, CLRSEQINT); + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + /* + * Unpause the sequencer and let it clear + * SEQINT by writing NO_SEQINT to it. This + * will cause the sequencer to be paused again, + * which is the expected state of this routine. + */ + ahd_unpause(ahd); + while (!ahd_is_paused(ahd)) + ; + ahd_outb(ahd, CLRINT, CLRSEQINT); + } + ahd_update_modes(ahd); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: Handle Seqint Called for code %d\n", + ahd_name(ahd), seqintcode); +#endif + switch (seqintcode) { + case BAD_SCB_STATUS: + { + struct scb *scb; + u_int scbid; + int cmds_pending; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) { + ahd_complete_scb(ahd, scb); + } else { + printf("%s: WARNING no command for scb %d " + "(bad status)\n", ahd_name(ahd), scbid); + ahd_dump_card_state(ahd); + } + cmds_pending = ahd_inw(ahd, CMDS_PENDING); + if (cmds_pending > 0) + ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1); + break; + } + case ENTERING_NONPACK: + { + struct scb *scb; + u_int scbid; + + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + /* + * Somehow need to know if this + * is from a selection or reselection. + * From that, we can termine target + * ID so we at least have an I_T nexus. + */ + } else { + ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); + ahd_outb(ahd, SAVED_LUN, scb->hscb->lun); + ahd_outb(ahd, SEQ_FLAGS, 0x0); + } + if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0 + && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) { + /* + * Phase change after read stream with + * CRC error with P0 asserted on last + * packet. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s: Assuming LQIPHASE_NLQ with " + "P0 assertion\n", ahd_name(ahd)); +#endif + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s: Entering NONPACK\n", ahd_name(ahd)); +#endif + break; + } + case INVALID_SEQINT: + printf("%s: Invalid Sequencer interrupt occurred.\n", + ahd_name(ahd)); + ahd_dump_card_state(ahd); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + break; + case STATUS_OVERRUN: + { + struct scb *scb; + u_int scbid; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) + ahd_print_path(ahd, scb); + else + printf("%s: ", ahd_name(ahd)); + printf("SCB %d Packetized Status Overrun", scbid); + ahd_dump_card_state(ahd); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + break; + } + case CFG4ISTAT_INTR: + { + struct scb *scb; + u_int scbid; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + ahd_dump_card_state(ahd); + printf("CFG4ISTAT: Free SCB %d referenced", scbid); + panic("For safety"); + } + ahd_outq(ahd, HADDR, scb->sense_busaddr); + ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE); + ahd_outb(ahd, HCNT + 2, 0); + ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG); + ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN); + break; + } + case ILLEGAL_PHASE: + { + u_int bus_phase; + + bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + printf("%s: ILLEGAL_PHASE 0x%x\n", + ahd_name(ahd), bus_phase); + + switch (bus_phase) { + case P_DATAOUT: + case P_DATAIN: + case P_DATAOUT_DT: + case P_DATAIN_DT: + case P_MESGOUT: + case P_STATUS: + case P_MESGIN: + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + printf("%s: Issued Bus Reset.\n", ahd_name(ahd)); + break; + case P_COMMAND: + { + struct ahd_devinfo devinfo; + struct scb *scb; + struct ahd_initiator_tinfo *targ_info; + struct ahd_tmode_tstate *tstate; + struct ahd_transinfo *tinfo; + u_int scbid; + + /* + * If a target takes us into the command phase + * assume that it has been externally reset and + * has thus lost our previous packetized negotiation + * agreement. Since we have not sent an identify + * message and may not have fully qualified the + * connection, we change our command to TUR, assert + * ATN and ABORT the task when we go to message in + * phase. The OSM will see the REQUEUE_REQUEST + * status and retry the command. + */ + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("Invalid phase with no valid SCB. " + "Resetting bus.\n"); + ahd_reset_channel(ahd, 'A', + /*Initiate Reset*/TRUE); + break; + } + ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb), + SCB_GET_TARGET(ahd, scb), + SCB_GET_LUN(scb), + SCB_GET_CHANNEL(ahd, scb), + ROLE_INITIATOR); + targ_info = ahd_fetch_transinfo(ahd, + devinfo.channel, + devinfo.our_scsiid, + devinfo.target, + &tstate); + tinfo = &targ_info->curr; + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_ACTIVE, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_ACTIVE, /*paused*/TRUE); + ahd_outb(ahd, SCB_CDB_STORE, 0); + ahd_outb(ahd, SCB_CDB_STORE+1, 0); + ahd_outb(ahd, SCB_CDB_STORE+2, 0); + ahd_outb(ahd, SCB_CDB_STORE+3, 0); + ahd_outb(ahd, SCB_CDB_STORE+4, 0); + ahd_outb(ahd, SCB_CDB_STORE+5, 0); + ahd_outb(ahd, SCB_CDB_LEN, 6); + scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); + scb->hscb->control |= MK_MESSAGE; + ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); + /* + * The lun is 0, regardless of the SCB's lun + * as we have not sent an identify message. + */ + ahd_outb(ahd, SAVED_LUN, 0); + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_assert_atn(ahd); + scb->flags &= ~(SCB_PACKETIZED); + scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT; + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); + ahd_freeze_scb(scb); + + /* + * Allow the sequencer to continue with + * non-pack processing. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { + ahd_outb(ahd, CLRLQOINT1, 0); + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + ahd_print_path(ahd, scb); + printf("Unexpected command phase from " + "packetized target\n"); + } +#endif + break; + } + } + break; + } + case CFG4OVERRUN: + { + struct scb *scb; + u_int scb_index; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd), + ahd_inb(ahd, MODE_PTR)); + } +#endif + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + if (scb == NULL) { + /* + * Attempt to transfer to an SCB that is + * not outstanding. + */ + ahd_assert_atn(ahd); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd->msgout_buf[0] = MSG_ABORT_TASK; + ahd->msgout_len = 1; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + /* + * Clear status received flag to prevent any + * attempt to complete this bogus SCB. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb(ahd, SCB_CONTROL) & ~STATUS_RCVD); + } + break; + } + case DUMP_CARD_STATE: + { + ahd_dump_card_state(ahd); + break; + } + case PDATA_REINIT: + { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + printf("%s: PDATA_REINIT - DFCNTRL = 0x%x " + "SG_CACHE_SHADOW = 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, DFCNTRL), + ahd_inb(ahd, SG_CACHE_SHADOW)); + } +#endif + ahd_reinitialize_dataptrs(ahd); + break; + } + case HOST_MSG_LOOP: + { + struct ahd_devinfo devinfo; + + /* + * The sequencer has encountered a message phase + * that requires host assistance for completion. + * While handling the message phase(s), we will be + * notified by the sequencer after each byte is + * transfered so we can track bus phase changes. + * + * If this is the first time we've seen a HOST_MSG_LOOP + * interrupt, initialize the state of the host message + * loop. + */ + ahd_fetch_devinfo(ahd, &devinfo); + if (ahd->msg_type == MSG_TYPE_NONE) { + struct scb *scb; + u_int scb_index; + u_int bus_phase; + + bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + if (bus_phase != P_MESGIN + && bus_phase != P_MESGOUT) { + printf("ahd_intr: HOST_MSG_LOOP bad " + "phase 0x%x\n", bus_phase); + /* + * Probably transitioned to bus free before + * we got here. Just punt the message. + */ + ahd_dump_card_state(ahd); + ahd_clear_intstat(ahd); + ahd_restart(ahd); + return; + } + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + if (devinfo.role == ROLE_INITIATOR) { + if (bus_phase == P_MESGOUT) + ahd_setup_initiator_msgout(ahd, + &devinfo, + scb); + else { + ahd->msg_type = + MSG_TYPE_INITIATOR_MSGIN; + ahd->msgin_index = 0; + } + } +#if AHD_TARGET_MODE + else { + if (bus_phase == P_MESGOUT) { + ahd->msg_type = + MSG_TYPE_TARGET_MSGOUT; + ahd->msgin_index = 0; + } + else + ahd_setup_target_msgin(ahd, + &devinfo, + scb); + } +#endif + } + + ahd_handle_message_phase(ahd); + break; + } + case NO_MATCH: + { + /* Ensure we don't leave the selection hardware on */ + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + + printf("%s:%c:%d: no active SCB for reconnecting " + "target - issuing BUS DEVICE RESET\n", + ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4); + printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, " + "REG0 == 0x%x ACCUM = 0x%x\n", + ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN), + ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM)); + printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, " + "SINDEX == 0x%x\n", + ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd), + ahd_find_busy_tcl(ahd, + BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID), + ahd_inb(ahd, SAVED_LUN))), + ahd_inw(ahd, SINDEX)); + printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, " + "SCB_CONTROL == 0x%x\n", + ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID), + ahd_inb_scbram(ahd, SCB_LUN), + ahd_inb_scbram(ahd, SCB_CONTROL)); + printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n", + ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI)); + printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0)); + printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0)); + ahd_dump_card_state(ahd); + ahd->msgout_buf[0] = MSG_BUS_DEV_RESET; + ahd->msgout_len = 1; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_assert_atn(ahd); + break; + } + case PROTO_VIOLATION: + { + ahd_handle_proto_violation(ahd); + break; + } + case IGN_WIDE_RES: + { + struct ahd_devinfo devinfo; + + ahd_fetch_devinfo(ahd, &devinfo); + ahd_handle_ign_wide_residue(ahd, &devinfo); + break; + } + case BAD_PHASE: + { + u_int lastphase; + + lastphase = ahd_inb(ahd, LASTPHASE); + printf("%s:%c:%d: unknown scsi bus phase %x, " + "lastphase = 0x%x. Attempting to continue\n", + ahd_name(ahd), 'A', + SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), + lastphase, ahd_inb(ahd, SCSISIGI)); + break; + } + case MISSED_BUSFREE: + { + u_int lastphase; + + lastphase = ahd_inb(ahd, LASTPHASE); + printf("%s:%c:%d: Missed busfree. " + "Lastphase = 0x%x, Curphase = 0x%x\n", + ahd_name(ahd), 'A', + SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), + lastphase, ahd_inb(ahd, SCSISIGI)); + ahd_restart(ahd); + return; + } + case DATA_OVERRUN: + { + /* + * When the sequencer detects an overrun, it + * places the controller in "BITBUCKET" mode + * and allows the target to complete its transfer. + * Unfortunately, none of the counters get updated + * when the controller is in this mode, so we have + * no way of knowing how large the overrun was. + */ + struct scb *scb; + u_int scbindex; +#ifdef AHD_DEBUG + u_int lastphase; +#endif + + scbindex = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbindex); +#ifdef AHD_DEBUG + lastphase = ahd_inb(ahd, LASTPHASE); + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + ahd_print_path(ahd, scb); + printf("data overrun detected %s. Tag == 0x%x.\n", + ahd_lookup_phase_entry(lastphase)->phasemsg, + SCB_GET_TAG(scb)); + ahd_print_path(ahd, scb); + printf("%s seen Data Phase. Length = %ld. " + "NumSGs = %d.\n", + ahd_inb(ahd, SEQ_FLAGS) & DPHASE + ? "Have" : "Haven't", + ahd_get_transfer_length(scb), scb->sg_count); + ahd_dump_sglist(scb); + } +#endif + + /* + * Set this and it will take effect when the + * target does a command complete. + */ + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); + ahd_freeze_scb(scb); + break; + } + case MKMSG_FAILED: + { + struct ahd_devinfo devinfo; + struct scb *scb; + u_int scbid; + + ahd_fetch_devinfo(ahd, &devinfo); + printf("%s:%c:%d:%d: Attempt to issue message failed\n", + ahd_name(ahd), devinfo.channel, devinfo.target, + devinfo.lun); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL + && (scb->flags & SCB_RECOVERY_SCB) != 0) + /* + * Ensure that we didn't put a second instance of this + * SCB into the QINFIFO. + */ + ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), SCB_GET_TAG(scb), + ROLE_INITIATOR, /*status*/0, + SEARCH_REMOVE); + ahd_outb(ahd, SCB_CONTROL, + ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE); + break; + } + case TASKMGMT_FUNC_COMPLETE: + { + u_int scbid; + struct scb *scb; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) { + u_int lun; + u_int tag; + cam_status error; + + ahd_print_path(ahd, scb); + printf("Task Management Func 0x%x Complete\n", + scb->hscb->task_management); + lun = CAM_LUN_WILDCARD; + tag = SCB_LIST_NULL; + + switch (scb->hscb->task_management) { + case SIU_TASKMGMT_ABORT_TASK: + tag = SCB_GET_TAG(scb); + case SIU_TASKMGMT_ABORT_TASK_SET: + case SIU_TASKMGMT_CLEAR_TASK_SET: + lun = scb->hscb->lun; + error = CAM_REQ_ABORTED; + ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), + 'A', lun, tag, ROLE_INITIATOR, + error); + break; + case SIU_TASKMGMT_LUN_RESET: + lun = scb->hscb->lun; + case SIU_TASKMGMT_TARGET_RESET: + { + struct ahd_devinfo devinfo; + + ahd_scb_devinfo(ahd, &devinfo, scb); + error = CAM_BDR_SENT; + ahd_handle_devreset(ahd, &devinfo, lun, + CAM_BDR_SENT, + lun != CAM_LUN_WILDCARD + ? "Lun Reset" + : "Target Reset", + /*verbose_level*/0); + break; + } + default: + panic("Unexpected TaskMgmt Func\n"); + break; + } + } + break; + } + case TASKMGMT_CMD_CMPLT_OKAY: + { + u_int scbid; + struct scb *scb; + + /* + * An ABORT TASK TMF failed to be delivered before + * the targeted command completed normally. + */ + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) { + /* + * Remove the second instance of this SCB from + * the QINFIFO if it is still there. + */ + ahd_print_path(ahd, scb); + printf("SCB completes before TMF\n"); + /* + * Handle losing the race. Wait until any + * current selection completes. We will then + * set the TMF back to zero in this SCB so that + * the sequencer doesn't bother to issue another + * sequencer interrupt for its completion. + */ + while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0 + && (ahd_inb(ahd, SSTAT0) & SELDO) == 0 + && (ahd_inb(ahd, SSTAT1) & SELTO) == 0) + ; + ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0); + ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), SCB_GET_TAG(scb), + ROLE_INITIATOR, /*status*/0, + SEARCH_REMOVE); + } + break; + } + case TRACEPOINT0: + case TRACEPOINT1: + case TRACEPOINT2: + case TRACEPOINT3: + printf("%s: Tracepoint %d\n", ahd_name(ahd), + seqintcode - TRACEPOINT0); + break; + case NO_SEQINT: + break; + case SAW_HWERR: + ahd_handle_hwerrint(ahd); + break; + default: + printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd), + seqintcode); + break; + } + /* + * The sequencer is paused immediately on + * a SEQINT, so we should restart it when + * we're done. + */ + ahd_unpause(ahd); +} + +void +ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) +{ + struct scb *scb; + u_int status0; + u_int status3; + u_int status; + u_int lqistat1; + u_int lqostat0; + u_int scbid; + u_int busfreetime; + + ahd_update_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR); + status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO); + status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR); + lqistat1 = ahd_inb(ahd, LQISTAT1); + lqostat0 = ahd_inb(ahd, LQOSTAT0); + busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; + if ((status0 & (SELDI|SELDO)) != 0) { + u_int simode0; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + simode0 = ahd_inb(ahd, SIMODE0); + status0 &= simode0 & (IOERR|OVERRUN|SELDI|SELDO); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + } + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL + && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) + scb = NULL; + + /* Make sure the sequencer is in a safe location. */ + ahd_clear_critical_section(ahd); + + if ((status0 & IOERR) != 0) { + u_int now_lvd; + + now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40; + printf("%s: Transceiver State Has Changed to %s mode\n", + ahd_name(ahd), now_lvd ? "LVD" : "SE"); + ahd_outb(ahd, CLRSINT0, CLRIOERR); + /* + * A change in I/O mode is equivalent to a bus reset. + */ + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + ahd_pause(ahd); + ahd_setup_iocell_workaround(ahd); + ahd_unpause(ahd); + } else if ((status0 & OVERRUN) != 0) { + printf("%s: SCSI offset overrun detected. Resetting bus.\n", + ahd_name(ahd)); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + } else if ((status & SCSIRSTI) != 0) { + printf("%s: Someone reset channel A\n", ahd_name(ahd)); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); + } else if ((status & SCSIPERR) != 0) { + ahd_handle_transmission_error(ahd); + } else if (lqostat0 != 0) { + printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0); + ahd_outb(ahd, CLRLQOINT0, lqostat0); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { + ahd_outb(ahd, CLRLQOINT1, 0); + } + } else if ((status & SELTO) != 0) { + u_int scbid; + + /* Stop the selection */ + ahd_outb(ahd, SCSISEQ0, 0); + + /* No more pending messages */ + ahd_clear_msg_state(ahd); + + /* Clear interrupt state */ + ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR); + + /* + * Although the driver does not care about the + * 'Selection in Progress' status bit, the busy + * LED does. SELINGO is only cleared by a sucessfull + * selection, so we must manually clear it to insure + * the LED turns off just incase no future successful + * selections occur (e.g. no devices on the bus). + */ + ahd_outb(ahd, CLRSINT0, CLRSELINGO); + + scbid = ahd_inw(ahd, WAITING_TID_HEAD); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: ahd_intr - referenced scb not " + "valid during SELTO scb(0x%x)\n", + ahd_name(ahd), scbid); + ahd_dump_card_state(ahd); + } else { + struct ahd_devinfo devinfo; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SELTO) != 0) { + ahd_print_path(ahd, scb); + printf("Saw Selection Timeout for SCB 0x%x\n", + scbid); + } +#endif + /* + * Force a renegotiation with this target just in + * case the cable was pulled and will later be + * re-attached. The target may forget its negotiation + * settings with us should it attempt to reselect + * during the interruption. The target will not issue + * a unit attention in this case, so we must always + * renegotiate. + */ + ahd_scb_devinfo(ahd, &devinfo, scb); + ahd_force_renegotiation(ahd, &devinfo); + ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT); + ahd_freeze_devq(ahd, scb); + } + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_iocell_first_selection(ahd); + ahd_unpause(ahd); + } else if ((status0 & (SELDI|SELDO)) != 0) { + ahd_iocell_first_selection(ahd); + ahd_unpause(ahd); + } else if (status3 != 0) { + printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n", + ahd_name(ahd), status3); + ahd_outb(ahd, CLRSINT3, status3); + } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) { + ahd_handle_lqiphase_error(ahd, lqistat1); + } else if ((lqistat1 & LQICRCI_NLQ) != 0) { + /* + * This status can be delayed during some + * streaming operations. The SCSIPHASE + * handler has already dealt with this case + * so just clear the error. + */ + ahd_outb(ahd, CLRLQIINT1, CLRLQICRCI_NLQ); + } else if ((status & BUSFREE) != 0) { + u_int lqostat1; + int restart; + int clear_fifo; + int packetized; + u_int mode; + + /* + * Clear our selection hardware as soon as possible. + * We may have an entry in the waiting Q for this target, + * that is affected by this busfree and we don't want to + * go about selecting the target while we handle the event. + */ + ahd_outb(ahd, SCSISEQ0, 0); + + /* + * Determine what we were up to at the time of + * the busfree. + */ + mode = AHD_MODE_SCSI; + busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; + lqostat1 = ahd_inb(ahd, LQOSTAT1); + switch (busfreetime) { + case BUSFREE_DFF0: + case BUSFREE_DFF1: + { + u_int scbid; + struct scb *scb; + + mode = busfreetime == BUSFREE_DFF0 + ? AHD_MODE_DFF0 : AHD_MODE_DFF1; + ahd_set_modes(ahd, mode, mode); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Invalid SCB %d in DFF%d " + "during unexpected busfree\n", + ahd_name(ahd), scbid, mode); + packetized = 0; + } else + packetized = (scb->flags & SCB_PACKETIZED) != 0; + clear_fifo = 1; + break; + } + case BUSFREE_LQO: + clear_fifo = 0; + packetized = 1; + break; + default: + clear_fifo = 0; + packetized = (lqostat1 & LQOBUSFREE) != 0; + if (!packetized + && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) + packetized = 1; + break; + } + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("Saw Busfree. Busfreetime = 0x%x.\n", + busfreetime); +#endif + /* + * Busfrees that occur in non-packetized phases are + * handled by the nonpkt_busfree handler. + */ + if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) { + restart = ahd_handle_pkt_busfree(ahd, busfreetime); + } else { + packetized = 0; + restart = ahd_handle_nonpkt_busfree(ahd); + } + /* + * Clear the busfree interrupt status. The setting of + * the interrupt is a pulse, so in a perfect world, we + * would not need to muck with the ENBUSFREE logic. This + * would ensure that if the bus moves on to another + * connection, busfree protection is still in force. If + * BUSFREEREV is broken, however, we must manually clear + * the ENBUSFREE if the busfree occurred during a non-pack + * connection so that we don't get false positives during + * future, packetized, connections. + */ + ahd_outb(ahd, CLRSINT1, CLRBUSFREE); + if (packetized == 0 + && (ahd->bugs & AHD_BUSFREEREV_BUG) != 0) + ahd_outb(ahd, SIMODE1, + ahd_inb(ahd, SIMODE1) & ~ENBUSFREE); + + if (clear_fifo) + ahd_clear_fifo(ahd, mode); + + ahd_clear_msg_state(ahd); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + if (restart) { + ahd_restart(ahd); + } else { + ahd_unpause(ahd); + } + } else { + printf("%s: Missing case in ahd_handle_scsiint. status = %x\n", + ahd_name(ahd), status); + ahd_dump_card_state(ahd); + ahd_clear_intstat(ahd); + ahd_unpause(ahd); + } +} + +static void +ahd_handle_transmission_error(struct ahd_softc *ahd) +{ + struct scb *scb; + u_int scbid; + u_int lqistat1; + u_int lqistat2; + u_int msg_out; + u_int curphase; + u_int lastphase; + u_int perrdiag; + u_int cur_col; + int silent; + + scb = NULL; + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ); + lqistat2 = ahd_inb(ahd, LQISTAT2); + if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0 + && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) { + u_int lqistate; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + lqistate = ahd_inb(ahd, LQISTATE); + if ((lqistate >= 0x1E && lqistate <= 0x24) + || (lqistate == 0x29)) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + printf("%s: NLQCRC found via LQISTATE\n", + ahd_name(ahd)); + } +#endif + lqistat1 |= LQICRCI_NLQ; + } + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + } + + ahd_outb(ahd, CLRLQIINT1, lqistat1); + lastphase = ahd_inb(ahd, LASTPHASE); + curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + perrdiag = ahd_inb(ahd, PERRDIAG); + msg_out = MSG_INITIATOR_DET_ERR; + ahd_outb(ahd, CLRSINT1, CLRSCSIPERR); + + /* + * Try to find the SCB associated with this error. + */ + silent = FALSE; + if (lqistat1 == 0 + || (lqistat1 & LQICRCI_NLQ) != 0) { + if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0) + ahd_set_active_fifo(ahd); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL && SCB_IS_SILENT(scb)) + silent = TRUE; + } + + cur_col = 0; + if (silent == FALSE) { + printf("%s: Transmission error detected\n", ahd_name(ahd)); + ahd_lqistat1_print(lqistat1, &cur_col, 50); + ahd_lastphase_print(lastphase, &cur_col, 50); + ahd_scsisigi_print(curphase, &cur_col, 50); + ahd_perrdiag_print(perrdiag, &cur_col, 50); + printf("\n"); + ahd_dump_card_state(ahd); + } + + if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) { + if (silent == FALSE) { + printf("%s: Gross protocol error during incoming " + "packet. lqistat1 == 0x%x. Resetting bus.\n", + ahd_name(ahd), lqistat1); + } + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + return; + } else if ((lqistat1 & LQICRCI_LQ) != 0) { + /* + * A CRC error has been detected on an incoming LQ. + * The bus is currently hung on the last ACK. + * Hit LQIRETRY to release the last ack, and + * wait for the sequencer to determine that ATNO + * is asserted while in message out to take us + * to our host message loop. No NONPACKREQ or + * LQIPHASE type errors will occur in this + * scenario. After this first LQIRETRY, the LQI + * manager will be in ISELO where it will + * happily sit until another packet phase begins. + * Unexpected bus free detection is enabled + * through any phases that occur after we release + * this last ack until the LQI manager sees a + * packet phase. This implies we may have to + * ignore a perfectly valid "unexected busfree" + * after our "initiator detected error" message is + * sent. A busfree is the expected response after + * we tell the target that it's L_Q was corrupted. + * (SPI4R09 10.7.3.3.3) + */ + ahd_outb(ahd, LQCTL2, LQIRETRY); + printf("LQIRetry for LQICRCI_LQ to release ACK\n"); + } else if ((lqistat1 & LQICRCI_NLQ) != 0) { + /* + * We detected a CRC error in a NON-LQ packet. + * The hardware has varying behavior in this situation + * depending on whether this packet was part of a + * stream or not. + * + * PKT by PKT mode: + * The hardware has already acked the complete packet. + * If the target honors our outstanding ATN condition, + * we should be (or soon will be) in MSGOUT phase. + * This will trigger the LQIPHASE_LQ status bit as the + * hardware was expecting another LQ. Unexpected + * busfree detection is enabled. Once LQIPHASE_LQ is + * true (first entry into host message loop is much + * the same), we must clear LQIPHASE_LQ and hit + * LQIRETRY so the hardware is ready to handle + * a future LQ. NONPACKREQ will not be asserted again + * once we hit LQIRETRY until another packet is + * processed. The target may either go busfree + * or start another packet in response to our message. + * + * Read Streaming P0 asserted: + * If we raise ATN and the target completes the entire + * stream (P0 asserted during the last packet), the + * hardware will ack all data and return to the ISTART + * state. When the target reponds to our ATN condition, + * LQIPHASE_LQ will be asserted. We should respond to + * this with an LQIRETRY to prepare for any future + * packets. NONPACKREQ will not be asserted again + * once we hit LQIRETRY until another packet is + * processed. The target may either go busfree or + * start another packet in response to our message. + * Busfree detection is enabled. + * + * Read Streaming P0 not asserted: + * If we raise ATN and the target transitions to + * MSGOUT in or after a packet where P0 is not + * asserted, the hardware will assert LQIPHASE_NLQ. + * We should respond to the LQIPHASE_NLQ with an + * LQIRETRY. Should the target stay in a non-pkt + * phase after we send our message, the hardware + * will assert LQIPHASE_LQ. Recovery is then just as + * listed above for the read streaming with P0 asserted. + * Busfree detection is enabled. + */ + if (silent == FALSE) + printf("LQICRC_NLQ\n"); + if (scb == NULL) { + printf("%s: No SCB valid for LQICRC_NLQ. " + "Resetting bus\n", ahd_name(ahd)); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + return; + } + } else if ((lqistat1 & LQIBADLQI) != 0) { + printf("Need to handle BADLQI!\n"); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + return; + } else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) { + if ((curphase & ~P_DATAIN_DT) != 0) { + /* Ack the byte. So we can continue. */ + if (silent == FALSE) + printf("Acking %s to clear perror\n", + ahd_lookup_phase_entry(curphase)->phasemsg); + ahd_inb(ahd, SCSIDAT); + } + + if (curphase == P_MESGIN) + msg_out = MSG_PARITY_ERROR; + } + + /* + * We've set the hardware to assert ATN if we + * get a parity error on "in" phases, so all we + * need to do is stuff the message buffer with + * the appropriate message. "In" phases have set + * mesg_out to something other than MSG_NOP. + */ + ahd->send_msg_perror = msg_out; + if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR) + scb->flags |= SCB_TRANSMISSION_ERROR; + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_unpause(ahd); +} + +static void +ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1) +{ + /* + * Clear the sources of the interrupts. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRLQIINT1, lqistat1); + + /* + * If the "illegal" phase changes were in response + * to our ATN to flag a CRC error, AND we ended up + * on packet boundaries, clear the error, restart the + * LQI manager as appropriate, and go on our merry + * way toward sending the message. Otherwise, reset + * the bus to clear the error. + */ + ahd_set_active_fifo(ahd); + if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0 + && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) { + if ((lqistat1 & LQIPHASE_LQ) != 0) { + printf("LQIRETRY for LQIPHASE_LQ\n"); + ahd_outb(ahd, LQCTL2, LQIRETRY); + } else if ((lqistat1 & LQIPHASE_NLQ) != 0) { + printf("LQIRETRY for LQIPHASE_NLQ\n"); + ahd_outb(ahd, LQCTL2, LQIRETRY); + } else + panic("ahd_handle_lqiphase_error: No phase errors\n"); + ahd_dump_card_state(ahd); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_unpause(ahd); + } else { + printf("Reseting Channel for LQI Phase error\n"); + ahd_dump_card_state(ahd); + ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + } +} + +/* + * Packetized unexpected or expected busfree. + * Entered in mode based on busfreetime. + */ +static int +ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime) +{ + u_int lqostat1; + + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + lqostat1 = ahd_inb(ahd, LQOSTAT1); + if ((lqostat1 & LQOBUSFREE) != 0) { + struct scb *scb; + u_int scbid; + u_int saved_scbptr; + u_int waiting_h; + u_int waiting_t; + u_int next; + + if ((busfreetime & BUSFREE_LQO) == 0) + printf("%s: Warning, BUSFREE time is 0x%x. " + "Expected BUSFREE_LQO.\n", + ahd_name(ahd), busfreetime); + /* + * The LQO manager detected an unexpected busfree + * either: + * + * 1) During an outgoing LQ. + * 2) After an outgoing LQ but before the first + * REQ of the command packet. + * 3) During an outgoing command packet. + * + * In all cases, CURRSCB is pointing to the + * SCB that encountered the failure. Clean + * up the queue, clear SELDO and LQOBUSFREE, + * and allow the sequencer to restart the select + * out at its lesure. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + scbid = ahd_inw(ahd, CURRSCB); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) + panic("SCB not valid during LQOBUSFREE"); + /* + * Clear the status. + */ + ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) + ahd_outb(ahd, CLRLQOINT1, 0); + ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + ahd_flush_device_writes(ahd); + ahd_outb(ahd, CLRSINT0, CLRSELDO); + + /* + * Return the LQO manager to its idle loop. It will + * not do this automatically if the busfree occurs + * after the first REQ of either the LQ or command + * packet or between the LQ and command packet. + */ + ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE); + + /* + * Update the waiting for selection queue so + * we restart on the correct SCB. + */ + waiting_h = ahd_inw(ahd, WAITING_TID_HEAD); + saved_scbptr = ahd_get_scbptr(ahd); + if (waiting_h != scbid) { + + ahd_outw(ahd, WAITING_TID_HEAD, scbid); + waiting_t = ahd_inw(ahd, WAITING_TID_TAIL); + if (waiting_t == waiting_h) { + ahd_outw(ahd, WAITING_TID_TAIL, scbid); + next = SCB_LIST_NULL; + } else { + ahd_set_scbptr(ahd, waiting_h); + next = ahd_inw_scbram(ahd, SCB_NEXT2); + } + ahd_set_scbptr(ahd, scbid); + ahd_outw(ahd, SCB_NEXT2, next); + } + ahd_set_scbptr(ahd, saved_scbptr); + if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) { + if (SCB_IS_SILENT(scb) == FALSE) { + ahd_print_path(ahd, scb); + printf("Probable outgoing LQ CRC error. " + "Retrying command\n"); + } + scb->crc_retry_count++; + } else { + ahd_set_transaction_status(scb, CAM_UNCOR_PARITY); + ahd_freeze_scb(scb); + ahd_freeze_devq(ahd, scb); + } + /* Return unpausing the sequencer. */ + return (0); + } else if ((ahd_inb(ahd, PERRDIAG) & PARITYERR) != 0) { + /* + * Ignore what are really parity errors that + * occur on the last REQ of a free running + * clock prior to going busfree. Some drives + * do not properly active negate just before + * going busfree resulting in a parity glitch. + */ + ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0) + printf("%s: Parity on last REQ detected " + "during busfree phase.\n", + ahd_name(ahd)); +#endif + /* Return unpausing the sequencer. */ + return (0); + } + if (ahd->src_mode != AHD_MODE_SCSI) { + u_int scbid; + struct scb *scb; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + ahd_print_path(ahd, scb); + printf("Unexpected PKT busfree condition\n"); + ahd_dump_card_state(ahd); + ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A', + SCB_GET_LUN(scb), SCB_GET_TAG(scb), + ROLE_INITIATOR, CAM_UNEXP_BUSFREE); + + /* Return restarting the sequencer. */ + return (1); + } + printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd)); + ahd_dump_card_state(ahd); + /* Restart the sequencer. */ + return (1); +} + +/* + * Non-packetized unexpected or expected busfree. + */ +static int +ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) +{ + struct ahd_devinfo devinfo; + struct scb *scb; + u_int lastphase; + u_int saved_scsiid; + u_int saved_lun; + u_int target; + u_int initiator_role_id; + u_int scbid; + u_int ppr_busfree; + int printerror; + + /* + * Look at what phase we were last in. If its message out, + * chances are pretty good that the busfree was in response + * to one of our abort requests. + */ + lastphase = ahd_inb(ahd, LASTPHASE); + saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); + saved_lun = ahd_inb(ahd, SAVED_LUN); + target = SCSIID_TARGET(ahd, saved_scsiid); + initiator_role_id = SCSIID_OUR_ID(saved_scsiid); + ahd_compile_devinfo(&devinfo, initiator_role_id, + target, saved_lun, 'A', ROLE_INITIATOR); + printerror = 1; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL + && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) + scb = NULL; + + ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0; + if (lastphase == P_MESGOUT) { + u_int tag; + + tag = SCB_LIST_NULL; + if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE) + || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) { + int found; + int sent_msg; + + if (scb == NULL) { + ahd_print_devinfo(ahd, &devinfo); + printf("Abort for unidentified " + "connection completed.\n"); + /* restart the sequencer. */ + return (1); + } + sent_msg = ahd->msgout_buf[ahd->msgout_index - 1]; + ahd_print_path(ahd, scb); + printf("SCB %d - Abort%s Completed.\n", + SCB_GET_TAG(scb), + sent_msg == MSG_ABORT_TAG ? "" : " Tag"); + + if (sent_msg == MSG_ABORT_TAG) + tag = SCB_GET_TAG(scb); + + if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) { + /* + * This abort is in response to an + * unexpected switch to command phase + * for a packetized connection. Since + * the identify message was never sent, + * "saved lun" is 0. We really want to + * abort only the SCB that encountered + * this error, which could have a different + * lun. The SCB will be retried so the OS + * will see the UA after renegotiating to + * packetized. + */ + tag = SCB_GET_TAG(scb); + saved_lun = scb->hscb->lun; + } + found = ahd_abort_scbs(ahd, target, 'A', saved_lun, + tag, ROLE_INITIATOR, + CAM_REQ_ABORTED); + printf("found == 0x%x\n", found); + printerror = 0; + } else if (ahd_sent_msg(ahd, AHDMSG_1B, + MSG_BUS_DEV_RESET, TRUE)) { +#ifdef __FreeBSD__ + /* + * Don't mark the user's request for this BDR + * as completing with CAM_BDR_SENT. CAM3 + * specifies CAM_REQ_CMP. + */ + if (scb != NULL + && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV + && ahd_match_scb(ahd, scb, target, 'A', + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_INITIATOR)) + ahd_set_transaction_status(scb, CAM_REQ_CMP); +#endif + ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD, + CAM_BDR_SENT, "Bus Device Reset", + /*verbose_level*/0); + printerror = 0; + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE) + && ppr_busfree == 0) { + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + /* + * PPR Rejected. Try non-ppr negotiation + * and retry command. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("PPR negotiation rejected busfree.\n"); +#endif + tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, + devinfo.our_scsiid, + devinfo.target, &tstate); + tinfo->curr.transport_version = 2; + tinfo->goal.transport_version = 2; + tinfo->goal.ppr_options = 0; + ahd_qinfifo_requeue_tail(ahd, scb); + printerror = 0; + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) + && ppr_busfree == 0) { + /* + * Negotiation Rejected. Go-narrow and + * retry command. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("WDTR negotiation rejected busfree.\n"); +#endif + ahd_set_width(ahd, &devinfo, + MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + ahd_qinfifo_requeue_tail(ahd, scb); + printerror = 0; + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) + && ppr_busfree == 0) { + /* + * Negotiation Rejected. Go-async and + * retry command. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("SDTR negotiation rejected busfree.\n"); +#endif + ahd_set_syncrate(ahd, &devinfo, + /*period*/0, /*offset*/0, + /*ppr_options*/0, + AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + ahd_qinfifo_requeue_tail(ahd, scb); + printerror = 0; + } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 + && ahd_sent_msg(ahd, AHDMSG_1B, + MSG_INITIATOR_DET_ERR, TRUE)) { + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("Expected IDE Busfree\n"); +#endif + printerror = 0; + } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE) + && ahd_sent_msg(ahd, AHDMSG_1B, + MSG_MESSAGE_REJECT, TRUE)) { + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("Expected QAS Reject Busfree\n"); +#endif + printerror = 0; + } + } + + /* + * The busfree required flag is honored at the end of + * the message phases. We check it last in case we + * had to send some other message that caused a busfree. + */ + if (printerror != 0 + && (lastphase == P_MESGIN || lastphase == P_MESGOUT) + && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { + + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); + ahd_freeze_scb(scb); + if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) { + ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQ_ABORTED); + } else { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("PPR Negotiation Busfree.\n"); +#endif + ahd_done(ahd, scb); + } + printerror = 0; + } + if (printerror != 0) { + int aborted; + + aborted = 0; + if (scb != NULL) { + u_int tag; + + if ((scb->hscb->control & TAG_ENB) != 0) + tag = SCB_GET_TAG(scb); + else + tag = SCB_LIST_NULL; + ahd_print_path(ahd, scb); + aborted = ahd_abort_scbs(ahd, target, 'A', + SCB_GET_LUN(scb), tag, + ROLE_INITIATOR, + CAM_UNEXP_BUSFREE); + } else { + /* + * We had not fully identified this connection, + * so we cannot abort anything. + */ + printf("%s: ", ahd_name(ahd)); + } + if (lastphase != P_BUSFREE) + ahd_force_renegotiation(ahd, &devinfo); + printf("Unexpected busfree %s, %d SCBs aborted, " + "PRGMCNT == 0x%x\n", + ahd_lookup_phase_entry(lastphase)->phasemsg, + aborted, + ahd_inb(ahd, PRGMCNT) + | (ahd_inb(ahd, PRGMCNT+1) << 8)); + ahd_dump_card_state(ahd); + } + /* Always restart the sequencer. */ + return (1); +} + +static void +ahd_handle_proto_violation(struct ahd_softc *ahd) +{ + struct ahd_devinfo devinfo; + struct scb *scb; + u_int scbid; + u_int seq_flags; + u_int curphase; + u_int lastphase; + int found; + + ahd_fetch_devinfo(ahd, &devinfo); + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + seq_flags = ahd_inb(ahd, SEQ_FLAGS); + curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK; + lastphase = ahd_inb(ahd, LASTPHASE); + if ((seq_flags & NOT_IDENTIFIED) != 0) { + + /* + * The reconnecting target either did not send an + * identify message, or did, but we didn't find an SCB + * to match. + */ + ahd_print_devinfo(ahd, &devinfo); + printf("Target did not send an IDENTIFY message. " + "LASTPHASE = 0x%x.\n", lastphase); + scb = NULL; + } else if (scb == NULL) { + /* + * We don't seem to have an SCB active for this + * transaction. Print an error and reset the bus. + */ + ahd_print_devinfo(ahd, &devinfo); + printf("No SCB found during protocol violation\n"); + goto proto_violation_reset; + } else { + ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL); + if ((seq_flags & NO_CDB_SENT) != 0) { + ahd_print_path(ahd, scb); + printf("No or incomplete CDB sent to device.\n"); + } else if ((ahd_inb_scbram(ahd, SCB_CONTROL) + & STATUS_RCVD) == 0) { + /* + * The target never bothered to provide status to + * us prior to completing the command. Since we don't + * know the disposition of this command, we must attempt + * to abort it. Assert ATN and prepare to send an abort + * message. + */ + ahd_print_path(ahd, scb); + printf("Completed command without status.\n"); + } else { + ahd_print_path(ahd, scb); + printf("Unknown protocol violation.\n"); + ahd_dump_card_state(ahd); + } + } + if ((lastphase & ~P_DATAIN_DT) == 0 + || lastphase == P_COMMAND) { +proto_violation_reset: + /* + * Target either went directly to data + * phase or didn't respond to our ATN. + * The only safe thing to do is to blow + * it away with a bus reset. + */ + found = ahd_reset_channel(ahd, 'A', TRUE); + printf("%s: Issued Channel %c Bus Reset. " + "%d SCBs aborted\n", ahd_name(ahd), 'A', found); + } else { + /* + * Leave the selection hardware off in case + * this abort attempt will affect yet to + * be sent commands. + */ + ahd_outb(ahd, SCSISEQ0, + ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + ahd_assert_atn(ahd); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + if (scb == NULL) { + ahd_print_devinfo(ahd, &devinfo); + ahd->msgout_buf[0] = MSG_ABORT_TASK; + ahd->msgout_len = 1; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + } else { + ahd_print_path(ahd, scb); + scb->flags |= SCB_ABORT; + } + printf("Protocol violation %s. Attempting to abort.\n", + ahd_lookup_phase_entry(curphase)->phasemsg); + } +} + +/* + * Force renegotiation to occur the next time we initiate + * a command to the current device. + */ +static void +ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct ahd_initiator_tinfo *targ_info; + struct ahd_tmode_tstate *tstate; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, devinfo); + printf("Forcing renegotiation\n"); + } +#endif + targ_info = ahd_fetch_transinfo(ahd, + devinfo->channel, + devinfo->our_scsiid, + devinfo->target, + &tstate); + ahd_update_neg_request(ahd, devinfo, tstate, + targ_info, AHD_NEG_IF_NON_ASYNC); +} + +#define AHD_MAX_STEPS 2000 +void +ahd_clear_critical_section(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + int stepping; + int steps; + int first_instr; + u_int simode0; + u_int simode1; + u_int simode3; + u_int lqimode0; + u_int lqimode1; + u_int lqomode0; + u_int lqomode1; + + if (ahd->num_critical_sections == 0) + return; + + stepping = FALSE; + steps = 0; + first_instr = 0; + simode0 = 0; + simode1 = 0; + simode3 = 0; + lqimode0 = 0; + lqimode1 = 0; + lqomode0 = 0; + lqomode1 = 0; + saved_modes = ahd_save_modes(ahd); + for (;;) { + struct cs *cs; + u_int seqaddr; + u_int i; + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + seqaddr = ahd_inb(ahd, CURADDR) + | (ahd_inb(ahd, CURADDR+1) << 8); + + cs = ahd->critical_sections; + for (i = 0; i < ahd->num_critical_sections; i++, cs++) { + + if (cs->begin < seqaddr && cs->end >= seqaddr) + break; + } + + if (i == ahd->num_critical_sections) + break; + + if (steps > AHD_MAX_STEPS) { + printf("%s: Infinite loop in critical section\n" + "%s: First Instruction 0x%x now 0x%x\n", + ahd_name(ahd), ahd_name(ahd), first_instr, + seqaddr); + ahd_dump_card_state(ahd); + panic("critical section loop"); + } + + steps++; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: Single stepping at 0x%x\n", ahd_name(ahd), + seqaddr); +#endif + if (stepping == FALSE) { + + first_instr = seqaddr; + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + simode0 = ahd_inb(ahd, SIMODE0); + simode3 = ahd_inb(ahd, SIMODE3); + lqimode0 = ahd_inb(ahd, LQIMODE0); + lqimode1 = ahd_inb(ahd, LQIMODE1); + lqomode0 = ahd_inb(ahd, LQOMODE0); + lqomode1 = ahd_inb(ahd, LQOMODE1); + ahd_outb(ahd, SIMODE0, 0); + ahd_outb(ahd, SIMODE3, 0); + ahd_outb(ahd, LQIMODE0, 0); + ahd_outb(ahd, LQIMODE1, 0); + ahd_outb(ahd, LQOMODE0, 0); + ahd_outb(ahd, LQOMODE1, 0); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + simode1 = ahd_inb(ahd, SIMODE1); + ahd_outb(ahd, SIMODE1, ENBUSFREE); + ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP); + stepping = TRUE; + } + ahd_outb(ahd, CLRSINT1, CLRBUSFREE); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); + ahd_outb(ahd, HCNTRL, ahd->unpause); + do { + ahd_delay(200); + } while (!ahd_is_paused(ahd)); + ahd_update_modes(ahd); + } + if (stepping) { + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + ahd_outb(ahd, SIMODE0, simode0); + ahd_outb(ahd, SIMODE3, simode3); + ahd_outb(ahd, LQIMODE0, lqimode0); + ahd_outb(ahd, LQIMODE1, lqimode1); + ahd_outb(ahd, LQOMODE0, lqomode0); + ahd_outb(ahd, LQOMODE1, lqomode1); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP); + ahd_outb(ahd, SIMODE1, simode1); + /* + * SCSIINT seems to glitch occassionally when + * the interrupt masks are restored. Clear SCSIINT + * one more time so that only persistent errors + * are seen as a real interrupt. + */ + ahd_outb(ahd, CLRINT, CLRSCSIINT); + } + ahd_restore_modes(ahd, saved_modes); +} + +/* + * Clear any pending interrupt status. + */ +void +ahd_clear_intstat(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + /* Clear any interrupt conditions this may have caused */ + ahd_outb(ahd, CLRLQIINT0, CLRLQIATNQAS|CLRLQICRCT1|CLRLQICRCT2 + |CLRLQIBADLQT|CLRLQIATNLQ|CLRLQIATNCMD); + ahd_outb(ahd, CLRLQIINT1, CLRLQIPHASE_LQ|CLRLQIPHASE_NLQ|CLRLIQABORT + |CLRLQICRCI_LQ|CLRLQICRCI_NLQ|CLRLQIBADLQI + |CLRLQIOVERI_LQ|CLRLQIOVERI_NLQ|CLRNONPACKREQ); + ahd_outb(ahd, CLRLQOINT0, CLRLQOTARGSCBPERR|CLRLQOSTOPT2|CLRLQOATNLQ + |CLRLQOATNPKT|CLRLQOTCRC); + ahd_outb(ahd, CLRLQOINT1, CLRLQOINITSCBPERR|CLRLQOSTOPI2|CLRLQOBADQAS + |CLRLQOBUSFREE|CLRLQOPHACHGINPKT); + if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { + ahd_outb(ahd, CLRLQOINT0, 0); + ahd_outb(ahd, CLRLQOINT1, 0); + } + ahd_outb(ahd, CLRSINT3, CLRNTRAMPERR|CLROSRAMPERR); + ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI + |CLRBUSFREE|CLRSCSIPERR|CLRREQINIT); + ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO + |CLRIOERR|CLROVERRUN); + ahd_outb(ahd, CLRINT, CLRSCSIINT); +} + +/**************************** Debugging Routines ******************************/ +#ifdef AHD_DEBUG +uint32_t ahd_debug = AHD_DEBUG_OPTS; +#endif +void +ahd_print_scb(struct scb *scb) +{ + struct hardware_scb *hscb; + int i; + + hscb = scb->hscb; + printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n", + (void *)scb, + hscb->control, + hscb->scsiid, + hscb->lun, + hscb->cdb_len); + printf("Shared Data: "); + for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++) + printf("%#02x", hscb->shared_data.idata.cdb[i]); + printf(" dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n", + (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF), + (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF), + ahd_le32toh(hscb->datacnt), + ahd_le32toh(hscb->sgptr), + SCB_GET_TAG(scb)); + ahd_dump_sglist(scb); +} + +void +ahd_dump_sglist(struct scb *scb) +{ + int i; + + if (scb->sg_count > 0) { + if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg_list; + + sg_list = (struct ahd_dma64_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint64_t addr; + uint32_t len; + + addr = ahd_le64toh(sg_list[i].addr); + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (uint32_t)((addr >> 32) & 0xFFFFFFFF), + (uint32_t)(addr & 0xFFFFFFFF), + sg_list[i].len & AHD_SG_LEN_MASK, + (sg_list[i].len & AHD_DMA_LAST_SEG) + ? " Last" : ""); + } + } else { + struct ahd_dma_seg *sg_list; + + sg_list = (struct ahd_dma_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint32_t len; + + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (len >> 24) & SG_HIGH_ADDR_BITS, + ahd_le32toh(sg_list[i].addr), + len & AHD_SG_LEN_MASK, + len & AHD_DMA_LAST_SEG ? " Last" : ""); + } + } + } +} + +/************************* Transfer Negotiation *******************************/ +/* + * Allocate per target mode instance (ID we respond to as a target) + * transfer negotiation data structures. + */ +static struct ahd_tmode_tstate * +ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel) +{ + struct ahd_tmode_tstate *master_tstate; + struct ahd_tmode_tstate *tstate; + int i; + + master_tstate = ahd->enabled_targets[ahd->our_id]; + if (ahd->enabled_targets[scsi_id] != NULL + && ahd->enabled_targets[scsi_id] != master_tstate) + panic("%s: ahd_alloc_tstate - Target already allocated", + ahd_name(ahd)); + tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT); + if (tstate == NULL) + return (NULL); + + /* + * If we have allocated a master tstate, copy user settings from + * the master tstate (taken from SRAM or the EEPROM) for this + * channel, but reset our current and goal settings to async/narrow + * until an initiator talks to us. + */ + if (master_tstate != NULL) { + memcpy(tstate, master_tstate, sizeof(*tstate)); + memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns)); + for (i = 0; i < 16; i++) { + memset(&tstate->transinfo[i].curr, 0, + sizeof(tstate->transinfo[i].curr)); + memset(&tstate->transinfo[i].goal, 0, + sizeof(tstate->transinfo[i].goal)); + } + } else + memset(tstate, 0, sizeof(*tstate)); + ahd->enabled_targets[scsi_id] = tstate; + return (tstate); +} + +#ifdef AHD_TARGET_MODE +/* + * Free per target mode instance (ID we respond to as a target) + * transfer negotiation data structures. + */ +static void +ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force) +{ + struct ahd_tmode_tstate *tstate; + + /* + * Don't clean up our "master" tstate. + * It has our default user settings. + */ + if (scsi_id == ahd->our_id + && force == FALSE) + return; + + tstate = ahd->enabled_targets[scsi_id]; + if (tstate != NULL) + free(tstate, M_DEVBUF); + ahd->enabled_targets[scsi_id] = NULL; +} +#endif + +/* + * Called when we have an active connection to a target on the bus, + * this function finds the nearest period to the input period limited + * by the capabilities of the bus connectivity of and sync settings for + * the target. + */ +void +ahd_devlimited_syncrate(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int *period, u_int *ppr_options, role_t role) +{ + struct ahd_transinfo *transinfo; + u_int maxsync; + + if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0 + && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) { + maxsync = AHD_SYNCRATE_PACED; + } else { + maxsync = AHD_SYNCRATE_ULTRA; + /* Can't do DT related options on an SE bus */ + *ppr_options &= MSG_EXT_PPR_QAS_REQ; + } + /* + * Never allow a value higher than our current goal + * period otherwise we may allow a target initiated + * negotiation to go above the limit as set by the + * user. In the case of an initiator initiated + * sync negotiation, we limit based on the user + * setting. This allows the system to still accept + * incoming negotiations even if target initiated + * negotiation is not performed. + */ + if (role == ROLE_TARGET) + transinfo = &tinfo->user; + else + transinfo = &tinfo->goal; + *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN); + if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { + maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2); + *ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } + if (transinfo->period == 0) { + *period = 0; + *ppr_options = 0; + } else { + *period = MAX(*period, transinfo->period); + ahd_find_syncrate(ahd, period, ppr_options, maxsync); + } +} + +/* + * Look up the valid period to SCSIRATE conversion in our table. + * Return the period and offset that should be sent to the target + * if this was the beginning of an SDTR. + */ +void +ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, + u_int *ppr_options, u_int maxsync) +{ + if (*period < maxsync) + *period = maxsync; + + if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0 + && *period > AHD_SYNCRATE_MIN_DT) + *ppr_options &= ~MSG_EXT_PPR_DT_REQ; + + if (*period > AHD_SYNCRATE_MIN) + *period = 0; + + /* Honor PPR option conformance rules. */ + if (*period > AHD_SYNCRATE_PACED) + *ppr_options &= ~MSG_EXT_PPR_RTI; + + if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0) + *ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ); + + if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0) + *ppr_options &= MSG_EXT_PPR_QAS_REQ; + + /* Skip all PACED only entries if IU is not available */ + if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0 + && *period < AHD_SYNCRATE_DT) + *period = AHD_SYNCRATE_DT; + + /* Skip all DT only entries if DT is not available */ + if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0 + && *period < AHD_SYNCRATE_ULTRA2) + *period = AHD_SYNCRATE_ULTRA2; +} + +/* + * Truncate the given synchronous offset to a value the + * current adapter type and syncrate are capable of. + */ +void +ahd_validate_offset(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int period, u_int *offset, int wide, + role_t role) +{ + u_int maxoffset; + + /* Limit offset to what we can do */ + if (period == 0) + maxoffset = 0; + else if (period <= AHD_SYNCRATE_PACED) { + if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) + maxoffset = MAX_OFFSET_PACED_BUG; + else + maxoffset = MAX_OFFSET_PACED; + } else + maxoffset = MAX_OFFSET_NON_PACED; + *offset = MIN(*offset, maxoffset); + if (tinfo != NULL) { + if (role == ROLE_TARGET) + *offset = MIN(*offset, tinfo->user.offset); + else + *offset = MIN(*offset, tinfo->goal.offset); + } +} + +/* + * Truncate the given transfer width parameter to a value the + * current adapter type is capable of. + */ +void +ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, + u_int *bus_width, role_t role) +{ + switch (*bus_width) { + default: + if (ahd->features & AHD_WIDE) { + /* Respond Wide */ + *bus_width = MSG_EXT_WDTR_BUS_16_BIT; + break; + } + /* FALLTHROUGH */ + case MSG_EXT_WDTR_BUS_8_BIT: + *bus_width = MSG_EXT_WDTR_BUS_8_BIT; + break; + } + if (tinfo != NULL) { + if (role == ROLE_TARGET) + *bus_width = MIN(tinfo->user.width, *bus_width); + else + *bus_width = MIN(tinfo->goal.width, *bus_width); + } +} + +/* + * Update the bitmask of targets for which the controller should + * negotiate with at the next convenient oportunity. This currently + * means the next time we send the initial identify messages for + * a new transaction. + */ +int +ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct ahd_tmode_tstate *tstate, + struct ahd_initiator_tinfo *tinfo, ahd_neg_type neg_type) +{ + u_int auto_negotiate_orig; + + auto_negotiate_orig = tstate->auto_negotiate; + if (neg_type == AHD_NEG_ALWAYS) { + /* + * Force our "current" settings to be + * unknown so that unless a bus reset + * occurs the need to renegotiate is + * recorded persistently. + */ + if ((ahd->features & AHD_WIDE) != 0) + tinfo->curr.width = AHD_WIDTH_UNKNOWN; + tinfo->curr.period = AHD_PERIOD_UNKNOWN; + tinfo->curr.offset = AHD_OFFSET_UNKNOWN; + } + if (tinfo->curr.period != tinfo->goal.period + || tinfo->curr.width != tinfo->goal.width + || tinfo->curr.offset != tinfo->goal.offset + || tinfo->curr.ppr_options != tinfo->goal.ppr_options + || (neg_type == AHD_NEG_IF_NON_ASYNC + && (tinfo->goal.offset != 0 + || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT + || tinfo->goal.ppr_options != 0))) + tstate->auto_negotiate |= devinfo->target_mask; + else + tstate->auto_negotiate &= ~devinfo->target_mask; + + return (auto_negotiate_orig != tstate->auto_negotiate); +} + +/* + * Update the user/goal/curr tables of synchronous negotiation + * parameters as well as, in the case of a current or active update, + * any data structures on the host controller. In the case of an + * active update, the specified target is currently talking to us on + * the bus, so the transfer parameter update must take effect + * immediately. + */ +void +ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int period, u_int offset, u_int ppr_options, + u_int type, int paused) +{ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int old_period; + u_int old_offset; + u_int old_ppr; + int active; + int update_needed; + + active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE; + update_needed = 0; + + if (period == 0 || offset == 0) { + period = 0; + offset = 0; + } + + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + + if ((type & AHD_TRANS_USER) != 0) { + tinfo->user.period = period; + tinfo->user.offset = offset; + tinfo->user.ppr_options = ppr_options; + } + + if ((type & AHD_TRANS_GOAL) != 0) { + tinfo->goal.period = period; + tinfo->goal.offset = offset; + tinfo->goal.ppr_options = ppr_options; + } + + old_period = tinfo->curr.period; + old_offset = tinfo->curr.offset; + old_ppr = tinfo->curr.ppr_options; + + if ((type & AHD_TRANS_CUR) != 0 + && (old_period != period + || old_offset != offset + || old_ppr != ppr_options)) { + + update_needed++; + + tinfo->curr.period = period; + tinfo->curr.offset = offset; + tinfo->curr.ppr_options = ppr_options; + + ahd_send_async(ahd, devinfo->channel, devinfo->target, + CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); + if (bootverbose) { + if (offset != 0) { + int options; + + printf("%s: target %d synchronous with " + "period = 0x%x, offset = 0x%x", + ahd_name(ahd), devinfo->target, + period, offset); + options = 0; + if ((ppr_options & MSG_EXT_PPR_RD_STRM) != 0) { + printf("(RDSTRM"); + options++; + } + if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { + printf("%s", options ? "|DT" : "(DT"); + options++; + } + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + printf("%s", options ? "|IU" : "(IU"); + options++; + } + if ((ppr_options & MSG_EXT_PPR_RTI) != 0) { + printf("%s", options ? "|RTI" : "(RTI"); + options++; + } + if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) { + printf("%s", options ? "|QAS" : "(QAS"); + options++; + } + if (options != 0) + printf(")\n"); + else + printf("\n"); + } else { + printf("%s: target %d using " + "asynchronous transfers%s\n", + ahd_name(ahd), devinfo->target, + (ppr_options & MSG_EXT_PPR_QAS_REQ) != 0 + ? "(QAS)" : ""); + } + } + } + /* + * Always refresh the neg-table to handle the case of the + * sequencer setting the ENATNO bit for a MK_MESSAGE request. + * We will always renegotiate in that case if this is a + * packetized request. Also manage the busfree expected flag + * from this common routine so that we catch changes due to + * WDTR or SDTR messages. + */ + if ((type & AHD_TRANS_CUR) != 0) { + if (!paused) + ahd_pause(ahd); + ahd_update_neg_table(ahd, devinfo, &tinfo->curr); + if (!paused) + ahd_unpause(ahd); + if (ahd->msg_type != MSG_TYPE_NONE) { + if ((old_ppr & MSG_EXT_PPR_IU_REQ) + != (ppr_options & MSG_EXT_PPR_IU_REQ)) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, devinfo); + printf("Expecting IU Change busfree\n"); + } +#endif + ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE + | MSG_FLAG_IU_REQ_CHANGED; + } + if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("PPR with IU_REQ outstanding\n"); +#endif + ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE; + } + } + } + + update_needed += ahd_update_neg_request(ahd, devinfo, tstate, + tinfo, AHD_NEG_TO_GOAL); + + if (update_needed && active) + ahd_update_pending_scbs(ahd); +} + +/* + * Update the user/goal/curr tables of wide negotiation + * parameters as well as, in the case of a current or active update, + * any data structures on the host controller. In the case of an + * active update, the specified target is currently talking to us on + * the bus, so the transfer parameter update must take effect + * immediately. + */ +void +ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int width, u_int type, int paused) +{ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int oldwidth; + int active; + int update_needed; + + active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE; + update_needed = 0; + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + + if ((type & AHD_TRANS_USER) != 0) + tinfo->user.width = width; + + if ((type & AHD_TRANS_GOAL) != 0) + tinfo->goal.width = width; + + oldwidth = tinfo->curr.width; + if ((type & AHD_TRANS_CUR) != 0 && oldwidth != width) { + + update_needed++; + + tinfo->curr.width = width; + ahd_send_async(ahd, devinfo->channel, devinfo->target, + CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); + if (bootverbose) { + printf("%s: target %d using %dbit transfers\n", + ahd_name(ahd), devinfo->target, + 8 * (0x01 << width)); + } + } + + if ((type & AHD_TRANS_CUR) != 0) { + if (!paused) + ahd_pause(ahd); + ahd_update_neg_table(ahd, devinfo, &tinfo->curr); + if (!paused) + ahd_unpause(ahd); + } + + update_needed += ahd_update_neg_request(ahd, devinfo, tstate, + tinfo, AHD_NEG_TO_GOAL); + if (update_needed && active) + ahd_update_pending_scbs(ahd); + +} + +/* + * Update the current state of tagged queuing for a given target. + */ +void +ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + ahd_queue_alg alg) +{ + ahd_platform_set_tags(ahd, devinfo, alg); + ahd_send_async(ahd, devinfo->channel, devinfo->target, + devinfo->lun, AC_TRANSFER_NEG, &alg); +} + +static void +ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct ahd_transinfo *tinfo) +{ + ahd_mode_state saved_modes; + u_int period; + u_int ppr_opts; + u_int con_opts; + u_int offset; + u_int saved_negoaddr; + uint8_t iocell_opts[sizeof(ahd->iocell_opts)]; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + saved_negoaddr = ahd_inb(ahd, NEGOADDR); + ahd_outb(ahd, NEGOADDR, devinfo->target); + period = tinfo->period; + offset = tinfo->offset; + memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts)); + ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ + |MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI); + con_opts = 0; + if (period == 0) + period = AHD_SYNCRATE_ASYNC; + if (period == AHD_SYNCRATE_160) { + + if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) { + /* + * When the SPI4 spec was finalized, PACE transfers + * was not made a configurable option in the PPR + * message. Instead it is assumed to be enabled for + * any syncrate faster than 80MHz. Nevertheless, + * Harpoon2A4 allows this to be configurable. + * + * Harpoon2A4 also assumes at most 2 data bytes per + * negotiated REQ/ACK offset. Paced transfers take + * 4, so we must adjust our offset. + */ + ppr_opts |= PPROPT_PACE; + offset *= 2; + + /* + * Harpoon2A assumed that there would be a + * fallback rate between 160MHz and 80Mhz, + * so 7 is used as the period factor rather + * than 8 for 160MHz. + */ + period = AHD_SYNCRATE_REVA_160; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_PCOMP_EN) == 0) + iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= + ~AHD_PRECOMP_MASK; + } else { + /* + * Precomp should be disabled for non-paced transfers. + */ + iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; + + if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0 + && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) { + /* + * Slow down our CRC interval to be + * compatible with devices that can't + * handle a CRC at full speed. + */ + con_opts |= ENSLOWCRC; + } + } + + ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW); + ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_PRECOMP_SLEW_INDEX]); + ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_AMPLITUDE); + ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_AMPLITUDE_INDEX]); + + ahd_outb(ahd, NEGPERIOD, period); + ahd_outb(ahd, NEGPPROPTS, ppr_opts); + ahd_outb(ahd, NEGOFFSET, offset); + + if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT) + con_opts |= WIDEXFER; + + /* + * During packetized transfers, the target will + * give us the oportunity to send command packets + * without us asserting attention. + */ + if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0) + con_opts |= ENAUTOATNO; + ahd_outb(ahd, NEGCONOPTS, con_opts); + ahd_outb(ahd, NEGOADDR, saved_negoaddr); + ahd_restore_modes(ahd, saved_modes); +} + +/* + * When the transfer settings for a connection change, setup for + * negotiation in pending SCBs to effect the change as quickly as + * possible. We also cancel any negotiations that are scheduled + * for inflight SCBs that have not been started yet. + */ +static void +ahd_update_pending_scbs(struct ahd_softc *ahd) +{ + struct scb *pending_scb; + int pending_scb_count; + int i; + int paused; + u_int saved_scbptr; + ahd_mode_state saved_modes; + + /* + * Traverse the pending SCB list and ensure that all of the + * SCBs there have the proper settings. We can only safely + * clear the negotiation required flag (setting requires the + * execution queue to be modified) and this is only possible + * if we are not already attempting to select out for this + * SCB. For this reason, all callers only call this routine + * if we are changing the negotiation settings for the currently + * active transaction on the bus. + */ + pending_scb_count = 0; + LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + struct ahd_devinfo devinfo; + struct hardware_scb *pending_hscb; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + ahd_scb_devinfo(ahd, &devinfo, pending_scb); + tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, + devinfo.our_scsiid, + devinfo.target, &tstate); + pending_hscb = pending_scb->hscb; + if ((tstate->auto_negotiate & devinfo.target_mask) == 0 + && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) { + pending_scb->flags &= ~SCB_AUTO_NEGOTIATE; + pending_hscb->control &= ~MK_MESSAGE; + } + ahd_sync_scb(ahd, pending_scb, + BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + pending_scb_count++; + } + + if (pending_scb_count == 0) + return; + + if (ahd_is_paused(ahd)) { + paused = 1; + } else { + paused = 0; + ahd_pause(ahd); + } + + /* + * Force the sequencer to reinitialize the selection for + * the command at the head of the execution queue if it + * has already been setup. The negotiation changes may + * effect whether we select-out with ATN. + */ + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + saved_scbptr = ahd_get_scbptr(ahd); + /* Ensure that the hscbs down on the card match the new information */ + for (i = 0; i < ahd->scb_data.maxhscbs; i++) { + struct hardware_scb *pending_hscb; + u_int control; + u_int scb_tag; + + ahd_set_scbptr(ahd, i); + scb_tag = i; + pending_scb = ahd_lookup_scb(ahd, scb_tag); + if (pending_scb == NULL) + continue; + + pending_hscb = pending_scb->hscb; + control = ahd_inb_scbram(ahd, SCB_CONTROL); + control &= ~MK_MESSAGE; + control |= pending_hscb->control & MK_MESSAGE; + ahd_outb(ahd, SCB_CONTROL, control); + } + ahd_set_scbptr(ahd, saved_scbptr); + ahd_restore_modes(ahd, saved_modes); + + if (paused == 0) + ahd_unpause(ahd); +} + +/**************************** Pathing Information *****************************/ +static void +ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + ahd_mode_state saved_modes; + u_int saved_scsiid; + role_t role; + int our_id; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + if (ahd_inb(ahd, SSTAT0) & TARGET) + role = ROLE_TARGET; + else + role = ROLE_INITIATOR; + + if (role == ROLE_TARGET + && (ahd_inb(ahd, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) { + /* We were selected, so pull our id from TARGIDIN */ + our_id = ahd_inb(ahd, TARGIDIN) & OID; + } else if (role == ROLE_TARGET) + our_id = ahd_inb(ahd, TOWNID); + else + our_id = ahd_inb(ahd, IOWNID); + + saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); + ahd_compile_devinfo(devinfo, + our_id, + SCSIID_TARGET(ahd, saved_scsiid), + ahd_inb(ahd, SAVED_LUN), + SCSIID_CHANNEL(ahd, saved_scsiid), + role); + ahd_restore_modes(ahd, saved_modes); +} + +void +ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + printf("%s:%c:%d:%d: ", ahd_name(ahd), 'A', + devinfo->target, devinfo->lun); +} + +struct ahd_phase_table_entry* +ahd_lookup_phase_entry(int phase) +{ + struct ahd_phase_table_entry *entry; + struct ahd_phase_table_entry *last_entry; + + /* + * num_phases doesn't include the default entry which + * will be returned if the phase doesn't match. + */ + last_entry = &ahd_phase_table[num_phases]; + for (entry = ahd_phase_table; entry < last_entry; entry++) { + if (phase == entry->phase) + break; + } + return (entry); +} + +void +ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target, + u_int lun, char channel, role_t role) +{ + devinfo->our_scsiid = our_id; + devinfo->target = target; + devinfo->lun = lun; + devinfo->target_offset = target; + devinfo->channel = channel; + devinfo->role = role; + if (channel == 'B') + devinfo->target_offset += 8; + devinfo->target_mask = (0x01 << devinfo->target_offset); +} + +static void +ahd_scb_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct scb *scb) +{ + role_t role; + int our_id; + + our_id = SCSIID_OUR_ID(scb->hscb->scsiid); + role = ROLE_INITIATOR; + if ((scb->hscb->control & TARGET_SCB) != 0) + role = ROLE_TARGET; + ahd_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahd, scb), + SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahd, scb), role); +} + + +/************************ Message Phase Processing ****************************/ +/* + * When an initiator transaction with the MK_MESSAGE flag either reconnects + * or enters the initial message out phase, we are interrupted. Fill our + * outgoing message buffer with the appropriate message and beging handing + * the message phase(s) manually. + */ +static void +ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct scb *scb) +{ + /* + * To facilitate adding multiple messages together, + * each routine should increment the index and len + * variables instead of setting them explicitly. + */ + ahd->msgout_index = 0; + ahd->msgout_len = 0; + + if (ahd_currently_packetized(ahd)) + ahd->msg_flags |= MSG_FLAG_PACKETIZED; + + if (ahd->send_msg_perror + && ahd_inb(ahd, MSG_OUT) == HOST_MSG) { + ahd->msgout_buf[ahd->msgout_index++] = ahd->send_msg_perror; + ahd->msgout_len++; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("Setting up for Parity Error delivery\n"); +#endif + return; + } else if (scb == NULL) { + printf("%s: WARNING. No pending message for " + "I_T msgin. Issuing NO-OP\n", ahd_name(ahd)); + ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP; + ahd->msgout_len++; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + return; + } + + if ((scb->flags & SCB_DEVICE_RESET) == 0 + && (scb->flags & SCB_PACKETIZED) == 0 + && ahd_inb(ahd, MSG_OUT) == MSG_IDENTIFYFLAG) { + u_int identify_msg; + + identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb); + if ((scb->hscb->control & DISCENB) != 0) + identify_msg |= MSG_IDENTIFY_DISCFLAG; + ahd->msgout_buf[ahd->msgout_index++] = identify_msg; + ahd->msgout_len++; + + if ((scb->hscb->control & TAG_ENB) != 0) { + ahd->msgout_buf[ahd->msgout_index++] = + scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE); + ahd->msgout_buf[ahd->msgout_index++] = SCB_GET_TAG(scb); + ahd->msgout_len += 2; + } + } + + if (scb->flags & SCB_DEVICE_RESET) { + ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET; + ahd->msgout_len++; + ahd_print_path(ahd, scb); + printf("Bus Device Reset Message Sent\n"); + /* + * Clear our selection hardware in advance of + * the busfree. We may have an entry in the waiting + * Q for this target, and we don't want to go about + * selecting while we handle the busfree and blow it + * away. + */ + ahd_outb(ahd, SCSISEQ0, 0); + } else if ((scb->flags & SCB_ABORT) != 0) { + + if ((scb->hscb->control & TAG_ENB) != 0) { + ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG; + } else { + ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT; + } + ahd->msgout_len++; + ahd_print_path(ahd, scb); + printf("Abort%s Message Sent\n", + (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : ""); + /* + * Clear our selection hardware in advance of + * the busfree. We may have an entry in the waiting + * Q for this target, and we don't want to go about + * selecting while we handle the busfree and blow it + * away. + */ + ahd_outb(ahd, SCSISEQ0, 0); + } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) { + ahd_build_transfer_msg(ahd, devinfo); + /* + * Clear our selection hardware in advance of potential + * PPR IU status change busfree. We may have an entry in + * the waiting Q for this target, and we don't want to go + * about selecting while we handle the busfree and blow + * it away. + */ + ahd_outb(ahd, SCSISEQ0, 0); + } else { + printf("ahd_intr: AWAITING_MSG for an SCB that " + "does not have a waiting message\n"); + printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid, + devinfo->target_mask); + panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x " + "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control, + ahd_inb(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT), + scb->flags); + } + + /* + * Clear the MK_MESSAGE flag from the SCB so we aren't + * asked to send this message again. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE); + scb->hscb->control &= ~MK_MESSAGE; + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; +} + +/* + * Build an appropriate transfer negotiation message for the + * currently active target. + */ +static void +ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + /* + * We need to initiate transfer negotiations. + * If our current and goal settings are identical, + * we want to renegotiate due to a check condition. + */ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + int dowide; + int dosync; + int doppr; + u_int period; + u_int ppr_options; + u_int offset; + + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + /* + * Filter our period based on the current connection. + * If we can't perform DT transfers on this segment (not in LVD + * mode for instance), then our decision to issue a PPR message + * may change. + */ + period = tinfo->goal.period; + offset = tinfo->goal.offset; + ppr_options = tinfo->goal.ppr_options; + /* Target initiated PPR is not allowed in the SCSI spec */ + if (devinfo->role == ROLE_TARGET) + ppr_options = 0; + ahd_devlimited_syncrate(ahd, tinfo, &period, + &ppr_options, devinfo->role); + dowide = tinfo->curr.width != tinfo->goal.width; + dosync = tinfo->curr.offset != offset || tinfo->curr.period != period; + /* + * Only use PPR if we have options that need it, even if the device + * claims to support it. There might be an expander in the way + * that doesn't. + */ + doppr = ppr_options != 0; + + if (!dowide && !dosync && !doppr) { + dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT; + dosync = tinfo->goal.offset != 0; + } + + if (!dowide && !dosync && !doppr) { + /* + * Force async with a WDTR message if we have a wide bus, + * or just issue an SDTR with a 0 offset. + */ + if ((ahd->features & AHD_WIDE) != 0) + dowide = 1; + else + dosync = 1; + + if (bootverbose) { + ahd_print_devinfo(ahd, devinfo); + printf("Ensuring async\n"); + } + } + /* Target initiated PPR is not allowed in the SCSI spec */ + if (devinfo->role == ROLE_TARGET) + doppr = 0; + + /* + * Both the PPR message and SDTR message require the + * goal syncrate to be limited to what the target device + * is capable of handling (based on whether an LVD->SE + * expander is on the bus), so combine these two cases. + * Regardless, guarantee that if we are using WDTR and SDTR + * messages that WDTR comes first. + */ + if (doppr || (dosync && !dowide)) { + + offset = tinfo->goal.offset; + ahd_validate_offset(ahd, tinfo, period, &offset, + doppr ? tinfo->goal.width + : tinfo->curr.width, + devinfo->role); + if (doppr) { + ahd_construct_ppr(ahd, devinfo, period, offset, + tinfo->goal.width, ppr_options); + } else { + ahd_construct_sdtr(ahd, devinfo, period, offset); + } + } else { + ahd_construct_wdtr(ahd, devinfo, tinfo->goal.width); + } +} + +/* + * Build a synchronous negotiation message in our message + * buffer based on the input parameters. + */ +static void +ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int period, u_int offset) +{ + if (offset == 0) + period = AHD_ASYNC_XFER_PERIOD; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR; + ahd->msgout_buf[ahd->msgout_index++] = period; + ahd->msgout_buf[ahd->msgout_index++] = offset; + ahd->msgout_len += 5; + if (bootverbose) { + printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + devinfo->lun, period, offset); + } +} + +/* + * Build a wide negotiateion message in our message + * buffer based on the input parameters. + */ +static void +ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int bus_width) +{ + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR; + ahd->msgout_buf[ahd->msgout_index++] = bus_width; + ahd->msgout_len += 4; + if (bootverbose) { + printf("(%s:%c:%d:%d): Sending WDTR %x\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + devinfo->lun, bus_width); + } +} + +/* + * Build a parallel protocol request message in our message + * buffer based on the input parameters. + */ +static void +ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int period, u_int offset, u_int bus_width, + u_int ppr_options) +{ + /* + * Always request precompensation from + * the other target if we are running + * at paced syncrates. + */ + if (period <= AHD_SYNCRATE_PACED) + ppr_options |= MSG_EXT_PPR_PCOMP_EN; + if (offset == 0) + period = AHD_ASYNC_XFER_PERIOD; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR; + ahd->msgout_buf[ahd->msgout_index++] = period; + ahd->msgout_buf[ahd->msgout_index++] = 0; + ahd->msgout_buf[ahd->msgout_index++] = offset; + ahd->msgout_buf[ahd->msgout_index++] = bus_width; + ahd->msgout_buf[ahd->msgout_index++] = ppr_options; + ahd->msgout_len += 8; + if (bootverbose) { + printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, " + "offset %x, ppr_options %x\n", ahd_name(ahd), + devinfo->channel, devinfo->target, devinfo->lun, + bus_width, period, offset, ppr_options); + } +} + +/* + * Clear any active message state. + */ +static void +ahd_clear_msg_state(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd->send_msg_perror = 0; + ahd->msg_flags = MSG_FLAG_NONE; + ahd->msgout_len = 0; + ahd->msgin_index = 0; + ahd->msg_type = MSG_TYPE_NONE; + if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0) { + /* + * The target didn't care to respond to our + * message request, so clear ATN. + */ + ahd_outb(ahd, CLRSINT1, CLRATNO); + } + ahd_outb(ahd, MSG_OUT, MSG_NOOP); + ahd_outb(ahd, SEQ_FLAGS2, + ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING); + ahd_restore_modes(ahd, saved_modes); +} + +/* + * Manual message loop handler. + */ +static void +ahd_handle_message_phase(struct ahd_softc *ahd) +{ + struct ahd_devinfo devinfo; + u_int bus_phase; + int end_session; + + ahd_fetch_devinfo(ahd, &devinfo); + end_session = FALSE; + bus_phase = ahd_inb(ahd, LASTPHASE); + + if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) { + printf("LQIRETRY for LQIPHASE_OUTPKT\n"); + ahd_outb(ahd, LQCTL2, LQIRETRY); + } +reswitch: + switch (ahd->msg_type) { + case MSG_TYPE_INITIATOR_MSGOUT: + { + int lastbyte; + int phasemis; + int msgdone; + + if (ahd->msgout_len == 0 && ahd->send_msg_perror == 0) + panic("HOST_MSG_LOOP interrupt with no active message"); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("INITIATOR_MSG_OUT"); + } +#endif + phasemis = bus_phase != P_MESGOUT; + if (phasemis) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahd_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif + if (bus_phase == P_MESGIN) { + /* + * Change gears and see if + * this messages is of interest to + * us or should be passed back to + * the sequencer. + */ + ahd_outb(ahd, CLRSINT1, CLRATNO); + ahd->send_msg_perror = 0; + ahd->msg_type = MSG_TYPE_INITIATOR_MSGIN; + ahd->msgin_index = 0; + goto reswitch; + } + end_session = TRUE; + break; + } + + if (ahd->send_msg_perror) { + ahd_outb(ahd, CLRSINT1, CLRATNO); + ahd_outb(ahd, CLRSINT1, CLRREQINIT); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", ahd->send_msg_perror); +#endif + /* + * If we are notifying the target of a CRC error + * during packetized operations, the target is + * within its rights to acknowledge our message + * with a busfree. + */ + if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0 + && ahd->send_msg_perror == MSG_INITIATOR_DET_ERR) + ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE; + + ahd_outb(ahd, RETURN_2, ahd->send_msg_perror); + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE); + break; + } + + msgdone = ahd->msgout_index == ahd->msgout_len; + if (msgdone) { + /* + * The target has requested a retry. + * Re-assert ATN, reset our message index to + * 0, and try again. + */ + ahd->msgout_index = 0; + ahd_assert_atn(ahd); + } + + lastbyte = ahd->msgout_index == (ahd->msgout_len - 1); + if (lastbyte) { + /* Last byte is signified by dropping ATN */ + ahd_outb(ahd, CLRSINT1, CLRATNO); + } + + /* + * Clear our interrupt status and present + * the next byte on the bus. + */ + ahd_outb(ahd, CLRSINT1, CLRREQINIT); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahd->msgout_buf[ahd->msgout_index]); +#endif + ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]); + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE); + break; + } + case MSG_TYPE_INITIATOR_MSGIN: + { + int phasemis; + int message_done; + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("INITIATOR_MSG_IN"); + } +#endif + phasemis = bus_phase != P_MESGIN; + if (phasemis) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahd_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif + ahd->msgin_index = 0; + if (bus_phase == P_MESGOUT + && (ahd->send_msg_perror != 0 + || (ahd->msgout_len != 0 + && ahd->msgout_index == 0))) { + ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + goto reswitch; + } + end_session = TRUE; + break; + } + + /* Pull the byte in without acking it */ + ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahd->msgin_buf[ahd->msgin_index]); +#endif + + message_done = ahd_parse_msg(ahd, &devinfo); + + if (message_done) { + /* + * Clear our incoming message buffer in case there + * is another message following this one. + */ + ahd->msgin_index = 0; + + /* + * If this message illicited a response, + * assert ATN so the target takes us to the + * message out phase. + */ + if (ahd->msgout_len != 0) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("Asserting ATN for response\n"); + } +#endif + ahd_assert_atn(ahd); + } + } else + ahd->msgin_index++; + + if (message_done == MSGLOOP_TERMINATED) { + end_session = TRUE; + } else { + /* Ack the byte */ + ahd_outb(ahd, CLRSINT1, CLRREQINIT); + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_READ); + } + break; + } + case MSG_TYPE_TARGET_MSGIN: + { + int msgdone; + int msgout_request; + + /* + * By default, the message loop will continue. + */ + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG); + + if (ahd->msgout_len == 0) + panic("Target MSGIN with no active message"); + + /* + * If we interrupted a mesgout session, the initiator + * will not know this until our first REQ. So, we + * only honor mesgout requests after we've sent our + * first byte. + */ + if ((ahd_inb(ahd, SCSISIGI) & ATNI) != 0 + && ahd->msgout_index > 0) + msgout_request = TRUE; + else + msgout_request = FALSE; + + if (msgout_request) { + + /* + * Change gears and see if + * this messages is of interest to + * us or should be passed back to + * the sequencer. + */ + ahd->msg_type = MSG_TYPE_TARGET_MSGOUT; + ahd_outb(ahd, SCSISIGO, P_MESGOUT | BSYO); + ahd->msgin_index = 0; + /* Dummy read to REQ for first byte */ + ahd_inb(ahd, SCSIDAT); + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) | SPIOEN); + break; + } + + msgdone = ahd->msgout_index == ahd->msgout_len; + if (msgdone) { + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) & ~SPIOEN); + end_session = TRUE; + break; + } + + /* + * Present the next byte on the bus. + */ + ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) | SPIOEN); + ahd_outb(ahd, SCSIDAT, ahd->msgout_buf[ahd->msgout_index++]); + break; + } + case MSG_TYPE_TARGET_MSGOUT: + { + int lastbyte; + int msgdone; + + /* + * By default, the message loop will continue. + */ + ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG); + + /* + * The initiator signals that this is + * the last byte by dropping ATN. + */ + lastbyte = (ahd_inb(ahd, SCSISIGI) & ATNI) == 0; + + /* + * Read the latched byte, but turn off SPIOEN first + * so that we don't inadvertently cause a REQ for the + * next byte. + */ + ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) & ~SPIOEN); + ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIDAT); + msgdone = ahd_parse_msg(ahd, &devinfo); + if (msgdone == MSGLOOP_TERMINATED) { + /* + * The message is *really* done in that it caused + * us to go to bus free. The sequencer has already + * been reset at this point, so pull the ejection + * handle. + */ + return; + } + + ahd->msgin_index++; + + /* + * XXX Read spec about initiator dropping ATN too soon + * and use msgdone to detect it. + */ + if (msgdone == MSGLOOP_MSGCOMPLETE) { + ahd->msgin_index = 0; + + /* + * If this message illicited a response, transition + * to the Message in phase and send it. + */ + if (ahd->msgout_len != 0) { + ahd_outb(ahd, SCSISIGO, P_MESGIN | BSYO); + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) | SPIOEN); + ahd->msg_type = MSG_TYPE_TARGET_MSGIN; + ahd->msgin_index = 0; + break; + } + } + + if (lastbyte) + end_session = TRUE; + else { + /* Ask for the next byte. */ + ahd_outb(ahd, SXFRCTL0, + ahd_inb(ahd, SXFRCTL0) | SPIOEN); + } + + break; + } + default: + panic("Unknown REQINIT message type"); + } + + if (end_session) { + if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) { + printf("%s: Returning to Idle Loop\n", + ahd_name(ahd)); + ahd_outb(ahd, LASTPHASE, P_BUSFREE); + ahd_clear_msg_state(ahd); + ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); + } else { + ahd_clear_msg_state(ahd); + ahd_outb(ahd, RETURN_1, EXIT_MSG_LOOP); + } + } +} + +/* + * See if we sent a particular extended message to the target. + * If "full" is true, return true only if the target saw the full + * message. If "full" is false, return true if the target saw at + * least the first byte of the message. + */ +static int +ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full) +{ + int found; + u_int index; + + found = FALSE; + index = 0; + + while (index < ahd->msgout_len) { + if (ahd->msgout_buf[index] == MSG_EXTENDED) { + u_int end_index; + + end_index = index + 1 + ahd->msgout_buf[index + 1]; + if (ahd->msgout_buf[index+2] == msgval + && type == AHDMSG_EXT) { + + if (full) { + if (ahd->msgout_index > end_index) + found = TRUE; + } else if (ahd->msgout_index > index) + found = TRUE; + } + index = end_index; + } else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK + && ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) { + + /* Skip tag type and tag id or residue param*/ + index += 2; + } else { + /* Single byte message */ + if (type == AHDMSG_1B + && ahd->msgout_index > index + && (ahd->msgout_buf[index] == msgval + || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0 + && msgval == MSG_IDENTIFYFLAG))) + found = TRUE; + index++; + } + + if (found) + break; + } + return (found); +} + +/* + * Wait for a complete incoming message, parse it, and respond accordingly. + */ +static int +ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + int reject; + int done; + int response; + + done = MSGLOOP_IN_PROG; + response = FALSE; + reject = FALSE; + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid, + devinfo->target, &tstate); + + /* + * Parse as much of the message as is available, + * rejecting it if we don't support it. When + * the entire message is available and has been + * handled, return MSGLOOP_MSGCOMPLETE, indicating + * that we have parsed an entire message. + * + * In the case of extended messages, we accept the length + * byte outright and perform more checking once we know the + * extended message type. + */ + switch (ahd->msgin_buf[0]) { + case MSG_DISCONNECT: + case MSG_SAVEDATAPOINTER: + case MSG_CMDCOMPLETE: + case MSG_RESTOREPOINTERS: + case MSG_IGN_WIDE_RESIDUE: + /* + * End our message loop as these are messages + * the sequencer handles on its own. + */ + done = MSGLOOP_TERMINATED; + break; + case MSG_MESSAGE_REJECT: + response = ahd_handle_msg_reject(ahd, devinfo); + /* FALLTHROUGH */ + case MSG_NOOP: + done = MSGLOOP_MSGCOMPLETE; + break; + case MSG_EXTENDED: + { + /* Wait for enough of the message to begin validation */ + if (ahd->msgin_index < 2) + break; + switch (ahd->msgin_buf[2]) { + case MSG_EXT_SDTR: + { + u_int period; + u_int ppr_options; + u_int offset; + u_int saved_offset; + + if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) { + reject = TRUE; + break; + } + + /* + * Wait until we have both args before validating + * and acting on this message. + * + * Add one to MSG_EXT_SDTR_LEN to account for + * the extended message preamble. + */ + if (ahd->msgin_index < (MSG_EXT_SDTR_LEN + 1)) + break; + + period = ahd->msgin_buf[3]; + ppr_options = 0; + saved_offset = offset = ahd->msgin_buf[4]; + ahd_devlimited_syncrate(ahd, tinfo, &period, + &ppr_options, devinfo->role); + ahd_validate_offset(ahd, tinfo, period, &offset, + tinfo->curr.width, devinfo->role); + if (bootverbose) { + printf("(%s:%c:%d:%d): Received " + "SDTR period %x, offset %x\n\t" + "Filtered to period %x, offset %x\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + ahd->msgin_buf[3], saved_offset, + period, offset); + } + ahd_set_syncrate(ahd, devinfo, period, + offset, ppr_options, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + + /* + * See if we initiated Sync Negotiation + * and didn't have to fall down to async + * transfers. + */ + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) { + /* We started it */ + if (saved_offset != offset) { + /* Went too low - force async */ + reject = TRUE; + } + } else { + /* + * Send our own SDTR in reply + */ + if (bootverbose + && devinfo->role == ROLE_INITIATOR) { + printf("(%s:%c:%d:%d): Target " + "Initiated SDTR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_construct_sdtr(ahd, devinfo, + period, offset); + ahd->msgout_index = 0; + response = TRUE; + } + done = MSGLOOP_MSGCOMPLETE; + break; + } + case MSG_EXT_WDTR: + { + u_int bus_width; + u_int saved_width; + u_int sending_reply; + + sending_reply = FALSE; + if (ahd->msgin_buf[1] != MSG_EXT_WDTR_LEN) { + reject = TRUE; + break; + } + + /* + * Wait until we have our arg before validating + * and acting on this message. + * + * Add one to MSG_EXT_WDTR_LEN to account for + * the extended message preamble. + */ + if (ahd->msgin_index < (MSG_EXT_WDTR_LEN + 1)) + break; + + bus_width = ahd->msgin_buf[3]; + saved_width = bus_width; + ahd_validate_width(ahd, tinfo, &bus_width, + devinfo->role); + if (bootverbose) { + printf("(%s:%c:%d:%d): Received WDTR " + "%x filtered to %x\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + saved_width, bus_width); + } + + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) { + /* + * Don't send a WDTR back to the + * target, since we asked first. + * If the width went higher than our + * request, reject it. + */ + if (saved_width > bus_width) { + reject = TRUE; + printf("(%s:%c:%d:%d): requested %dBit " + "transfers. Rejecting...\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + 8 * (0x01 << bus_width)); + bus_width = 0; + } + } else { + /* + * Send our own WDTR in reply + */ + if (bootverbose + && devinfo->role == ROLE_INITIATOR) { + printf("(%s:%c:%d:%d): Target " + "Initiated WDTR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_construct_wdtr(ahd, devinfo, bus_width); + ahd->msgout_index = 0; + response = TRUE; + sending_reply = TRUE; + } + /* + * After a wide message, we are async, but + * some devices don't seem to honor this portion + * of the spec. Force a renegotiation of the + * sync component of our transfer agreement even + * if our goal is async. By updating our width + * after forcing the negotiation, we avoid + * renegotiating for width. + */ + ahd_update_neg_request(ahd, devinfo, tstate, + tinfo, AHD_NEG_ALWAYS); + ahd_set_width(ahd, devinfo, bus_width, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + if (sending_reply == FALSE && reject == FALSE) { + + /* + * We will always have an SDTR to send. + */ + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = TRUE; + } + done = MSGLOOP_MSGCOMPLETE; + break; + } + case MSG_EXT_PPR: + { + u_int period; + u_int offset; + u_int bus_width; + u_int ppr_options; + u_int saved_width; + u_int saved_offset; + u_int saved_ppr_options; + + if (ahd->msgin_buf[1] != MSG_EXT_PPR_LEN) { + reject = TRUE; + break; + } + + /* + * Wait until we have all args before validating + * and acting on this message. + * + * Add one to MSG_EXT_PPR_LEN to account for + * the extended message preamble. + */ + if (ahd->msgin_index < (MSG_EXT_PPR_LEN + 1)) + break; + + period = ahd->msgin_buf[3]; + offset = ahd->msgin_buf[5]; + bus_width = ahd->msgin_buf[6]; + saved_width = bus_width; + ppr_options = ahd->msgin_buf[7]; + /* + * According to the spec, a DT only + * period factor with no DT option + * set implies async. + */ + if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0 + && period <= 9) + offset = 0; + saved_ppr_options = ppr_options; + saved_offset = offset; + + /* + * Transfer options are only available if we + * are negotiating wide. + */ + if (bus_width == 0) + ppr_options &= MSG_EXT_PPR_QAS_REQ; + + ahd_validate_width(ahd, tinfo, &bus_width, + devinfo->role); + ahd_devlimited_syncrate(ahd, tinfo, &period, + &ppr_options, devinfo->role); + ahd_validate_offset(ahd, tinfo, period, &offset, + bus_width, devinfo->role); + + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) { + /* + * If we are unable to do any of the + * requested options (we went too low), + * then we'll have to reject the message. + */ + if (saved_width > bus_width + || saved_offset != offset + || saved_ppr_options != ppr_options) { + reject = TRUE; + period = 0; + offset = 0; + bus_width = 0; + ppr_options = 0; + } + } else { + if (devinfo->role != ROLE_TARGET) + printf("(%s:%c:%d:%d): Target " + "Initiated PPR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + else + printf("(%s:%c:%d:%d): Initiator " + "Initiated PPR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_construct_ppr(ahd, devinfo, period, offset, + bus_width, ppr_options); + ahd->msgout_index = 0; + response = TRUE; + } + if (bootverbose) { + printf("(%s:%c:%d:%d): Received PPR width %x, " + "period %x, offset %x,options %x\n" + "\tFiltered to width %x, period %x, " + "offset %x, options %x\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun, + saved_width, ahd->msgin_buf[3], + saved_offset, saved_ppr_options, + bus_width, period, offset, ppr_options); + } + ahd_set_width(ahd, devinfo, bus_width, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + ahd_set_syncrate(ahd, devinfo, period, + offset, ppr_options, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + + done = MSGLOOP_MSGCOMPLETE; + break; + } + default: + /* Unknown extended message. Reject it. */ + reject = TRUE; + break; + } + break; + } +#ifdef AHD_TARGET_MODE + case MSG_BUS_DEV_RESET: + ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD, + CAM_BDR_SENT, + "Bus Device Reset Received", + /*verbose_level*/0); + ahd_restart(ahd); + done = MSGLOOP_TERMINATED; + break; + case MSG_ABORT_TAG: + case MSG_ABORT: + case MSG_CLEAR_QUEUE: + { + int tag; + + /* Target mode messages */ + if (devinfo->role != ROLE_TARGET) { + reject = TRUE; + break; + } + tag = SCB_LIST_NULL; + if (ahd->msgin_buf[0] == MSG_ABORT_TAG) + tag = ahd_inb(ahd, INITIATOR_TAG); + ahd_abort_scbs(ahd, devinfo->target, devinfo->channel, + devinfo->lun, tag, ROLE_TARGET, + CAM_REQ_ABORTED); + + tstate = ahd->enabled_targets[devinfo->our_scsiid]; + if (tstate != NULL) { + struct ahd_tmode_lstate* lstate; + + lstate = tstate->enabled_luns[devinfo->lun]; + if (lstate != NULL) { + ahd_queue_lstate_event(ahd, lstate, + devinfo->our_scsiid, + ahd->msgin_buf[0], + /*arg*/tag); + ahd_send_lstate_events(ahd, lstate); + } + } + ahd_restart(ahd); + done = MSGLOOP_TERMINATED; + break; + } +#endif + case MSG_QAS_REQUEST: +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + printf("%s: QAS request. SCSISIGI == 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, SCSISIGI)); +#endif + ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE; + /* FALLTHROUGH */ + case MSG_TERM_IO_PROC: + default: + reject = TRUE; + break; + } + + if (reject) { + /* + * Setup to reject the message. + */ + ahd->msgout_index = 0; + ahd->msgout_len = 1; + ahd->msgout_buf[0] = MSG_MESSAGE_REJECT; + done = MSGLOOP_MSGCOMPLETE; + response = TRUE; + } + + if (done != MSGLOOP_IN_PROG && !response) + /* Clear the outgoing message buffer */ + ahd->msgout_len = 0; + + return (done); +} + +/* + * Process a message reject message. + */ +static int +ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + /* + * What we care about here is if we had an + * outstanding SDTR or WDTR message for this + * target. If we did, this is a signal that + * the target is refusing negotiation. + */ + struct scb *scb; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int scb_index; + u_int last_msg; + int response = 0; + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + /* Might be necessary */ + last_msg = ahd_inb(ahd, LAST_MSG); + + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) { + if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/TRUE) + && tinfo->goal.period <= AHD_SYNCRATE_PACED) { + /* + * Target may not like our SPI-4 PPR Options. + * Attempt to negotiate 80MHz which will turn + * off these options. + */ + if (bootverbose) { + printf("(%s:%c:%d:%d): PPR Rejected. " + "Trying simple U160 PPR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + tinfo->goal.period = AHD_SYNCRATE_DT; + tinfo->goal.ppr_options &= MSG_EXT_PPR_IU_REQ + | MSG_EXT_PPR_QAS_REQ + | MSG_EXT_PPR_DT_REQ; + } else { + /* + * Target does not support the PPR message. + * Attempt to negotiate SPI-2 style. + */ + if (bootverbose) { + printf("(%s:%c:%d:%d): PPR Rejected. " + "Trying WDTR/SDTR\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } + tinfo->goal.ppr_options = 0; + tinfo->curr.transport_version = 2; + tinfo->goal.transport_version = 2; + } + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = 1; + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) { + + /* note 8bit xfers */ + printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using " + "8bit transfers\n", ahd_name(ahd), + devinfo->channel, devinfo->target, devinfo->lun); + ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + /* + * No need to clear the sync rate. If the target + * did not accept the command, our syncrate is + * unaffected. If the target started the negotiation, + * but rejected our response, we already cleared the + * sync rate before sending our WDTR. + */ + if (tinfo->goal.offset != tinfo->curr.offset) { + + /* Start the sync negotiation */ + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = 1; + } + } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) { + /* note asynch xfers and clear flag */ + ahd_set_syncrate(ahd, devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, + /*paused*/TRUE); + printf("(%s:%c:%d:%d): refuses synchronous negotiation. " + "Using asynchronous transfers\n", + ahd_name(ahd), devinfo->channel, + devinfo->target, devinfo->lun); + } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) { + int tag_type; + int mask; + + tag_type = (scb->hscb->control & MSG_SIMPLE_TASK); + + if (tag_type == MSG_SIMPLE_TASK) { + printf("(%s:%c:%d:%d): refuses tagged commands. " + "Performing non-tagged I/O\n", ahd_name(ahd), + devinfo->channel, devinfo->target, devinfo->lun); + ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE); + mask = ~0x23; + } else { + printf("(%s:%c:%d:%d): refuses %s tagged commands. " + "Performing simple queue tagged I/O only\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + devinfo->lun, tag_type == MSG_ORDERED_TASK + ? "ordered" : "head of queue"); + ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC); + mask = ~0x03; + } + + /* + * Resend the identify for this CCB as the target + * may believe that the selection is invalid otherwise. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb_scbram(ahd, SCB_CONTROL) & mask); + scb->hscb->control &= mask; + ahd_set_transaction_tag(scb, /*enabled*/FALSE, + /*type*/MSG_SIMPLE_TASK); + ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG); + ahd_assert_atn(ahd); + ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun), + SCB_GET_TAG(scb)); + + /* + * Requeue all tagged commands for this target + * currently in our posession so they can be + * converted to untagged commands. + */ + ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ, + SEARCH_COMPLETE); + } else if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_IDENTIFYFLAG, TRUE)) { + /* + * Most likely the device believes that we had + * previously negotiated packetized. + */ + ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE + | MSG_FLAG_IU_REQ_CHANGED; + + ahd_force_renegotiation(ahd, devinfo); + ahd->msgout_index = 0; + ahd->msgout_len = 0; + ahd_build_transfer_msg(ahd, devinfo); + ahd->msgout_index = 0; + response = 1; + } else { + /* + * Otherwise, we ignore it. + */ + printf("%s:%c:%d: Message reject for %x -- ignored\n", + ahd_name(ahd), devinfo->channel, devinfo->target, + last_msg); + } + return (response); +} + +/* + * Process an ingnore wide residue message. + */ +static void +ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + u_int scb_index; + struct scb *scb; + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + /* + * XXX Actually check data direction in the sequencer? + * Perhaps add datadir to some spare bits in the hscb? + */ + if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0 + || ahd_get_transfer_dir(scb) != CAM_DIR_IN) { + /* + * Ignore the message if we haven't + * seen an appropriate data phase yet. + */ + } else { + /* + * If the residual occurred on the last + * transfer and the transfer request was + * expected to end on an odd count, do + * nothing. Otherwise, subtract a byte + * and update the residual count accordingly. + */ + uint32_t sgptr; + + sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); + if ((sgptr & SG_LIST_NULL) != 0 + && (ahd_inb(ahd, SCB_TASK_ATTRIBUTE) & SCB_XFERLEN_ODD) != 0) { + /* + * If the residual occurred on the last + * transfer and the transfer request was + * expected to end on an odd count, do + * nothing. + */ + } else { + uint32_t data_cnt; + uint64_t data_addr; + uint32_t sglen; + + /* Pull in the rest of the sgptr */ + sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR); + data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT); + if ((sgptr & SG_LIST_NULL) != 0) { + /* + * The residual data count is not updated + * for the command run to completion case. + * Explicitly zero the count. + */ + data_cnt &= ~AHD_SG_LEN_MASK; + } + data_addr = ahd_inq(ahd, SHADDR); + data_cnt += 1; + data_addr -= 1; + sgptr &= SG_PTR_MASK; + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* + * The residual sg ptr points to the next S/G + * to load so we must go back one. + */ + sg--; + sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; + if (sg != scb->sg_list + && sglen < (data_cnt & AHD_SG_LEN_MASK)) { + + sg--; + sglen = ahd_le32toh(sg->len); + /* + * Preserve High Address and SG_LIST + * bits while setting the count to 1. + */ + data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK)); + data_addr = ahd_le64toh(sg->addr) + + (sglen & AHD_SG_LEN_MASK) + - 1; + + /* + * Increment sg so it points to the + * "next" sg. + */ + sg++; + sgptr = ahd_sg_virt_to_bus(ahd, scb, + sg); + } + } else { + struct ahd_dma_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* + * The residual sg ptr points to the next S/G + * to load so we must go back one. + */ + sg--; + sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; + if (sg != scb->sg_list + && sglen < (data_cnt & AHD_SG_LEN_MASK)) { + + sg--; + sglen = ahd_le32toh(sg->len); + /* + * Preserve High Address and SG_LIST + * bits while setting the count to 1. + */ + data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK)); + data_addr = ahd_le32toh(sg->addr) + + (sglen & AHD_SG_LEN_MASK) + - 1; + + /* + * Increment sg so it points to the + * "next" sg. + */ + sg++; + sgptr = ahd_sg_virt_to_bus(ahd, scb, + sg); + } + } + /* + * Toggle the "oddness" of the transfer length + * to handle this mid-transfer ignore wide + * residue. This ensures that the oddness is + * correct for subsequent data transfers. + */ + ahd_outb(ahd, SCB_TASK_ATTRIBUTE, + ahd_inb(ahd, SCB_TASK_ATTRIBUTE) ^ SCB_XFERLEN_ODD); + + ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr); + ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt); + /* + * The FIFO's pointers will be updated if/when the + * sequencer re-enters a data phase. + */ + } + } +} + + +/* + * Reinitialize the data pointers for the active transfer + * based on its current residual. + */ +static void +ahd_reinitialize_dataptrs(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int scb_index; + u_int wait; + uint32_t sgptr; + uint32_t resid; + uint64_t dataptr; + + AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK, + AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK); + + scb_index = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scb_index); + + /* + * Release and reacquire the FIFO so we + * have a clean slate. + */ + ahd_outb(ahd, DFFSXFRCTL, CLRCHN); + wait = 1000; + do { + ahd_delay(100); + } while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE)); + if (wait == 0) { + ahd_print_path(ahd, scb); + printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n"); + ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT); + } + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, DFFSTAT, + ahd_inb(ahd, DFFSTAT) + | (saved_modes == 0x11 ? CURRFIFO_1 : CURRFIFO_0)); + + /* + * Determine initial values for data_addr and data_cnt + * for resuming the data phase. + */ + sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8) + | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); + sgptr &= SG_PTR_MASK; + + resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16) + | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 1) << 8) + | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT); + + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* The residual sg_ptr always points to the next sg */ + sg--; + + dataptr = ahd_le64toh(sg->addr) + + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) + - resid; + ahd_outb(ahd, HADDR + 7, dataptr >> 56); + ahd_outb(ahd, HADDR + 6, dataptr >> 48); + ahd_outb(ahd, HADDR + 5, dataptr >> 40); + ahd_outb(ahd, HADDR + 4, dataptr >> 32); + } else { + struct ahd_dma_seg *sg; + + sg = ahd_sg_bus_to_virt(ahd, scb, sgptr); + + /* The residual sg_ptr always points to the next sg */ + sg--; + + dataptr = ahd_le32toh(sg->addr) + + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) + - resid; + ahd_outb(ahd, HADDR + 4, + (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24); + } + ahd_outb(ahd, HADDR + 3, dataptr >> 24); + ahd_outb(ahd, HADDR + 2, dataptr >> 16); + ahd_outb(ahd, HADDR + 1, dataptr >> 8); + ahd_outb(ahd, HADDR, dataptr); + ahd_outb(ahd, HCNT + 2, resid >> 16); + ahd_outb(ahd, HCNT + 1, resid >> 8); + ahd_outb(ahd, HCNT, resid); +} + +/* + * Handle the effects of issuing a bus device reset message. + */ +static void +ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + u_int lun, cam_status status, char *message, + int verbose_level) +{ +#ifdef AHD_TARGET_MODE + struct ahd_tmode_tstate* tstate; +#endif + int found; + + found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel, + lun, SCB_LIST_NULL, devinfo->role, + status); + +#ifdef AHD_TARGET_MODE + /* + * Send an immediate notify ccb to all target mord peripheral + * drivers affected by this action. + */ + tstate = ahd->enabled_targets[devinfo->our_scsiid]; + if (tstate != NULL) { + u_int cur_lun; + u_int max_lun; + + if (lun != CAM_LUN_WILDCARD) { + cur_lun = 0; + max_lun = AHD_NUM_LUNS - 1; + } else { + cur_lun = lun; + max_lun = lun; + } + for (cur_lun <= max_lun; cur_lun++) { + struct ahd_tmode_lstate* lstate; + + lstate = tstate->enabled_luns[cur_lun]; + if (lstate == NULL) + continue; + + ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid, + MSG_BUS_DEV_RESET, /*arg*/0); + ahd_send_lstate_events(ahd, lstate); + } + } +#endif + + /* + * Go back to async/narrow transfers and renegotiate. + */ + ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR, /*paused*/TRUE); + ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0, + /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE); + + ahd_send_async(ahd, devinfo->channel, devinfo->target, + lun, AC_SENT_BDR, NULL); + + if (message != NULL + && (verbose_level <= bootverbose)) + printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), + message, devinfo->channel, devinfo->target, found); +} + +#ifdef AHD_TARGET_MODE +static void +ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + struct scb *scb) +{ + + /* + * To facilitate adding multiple messages together, + * each routine should increment the index and len + * variables instead of setting them explicitly. + */ + ahd->msgout_index = 0; + ahd->msgout_len = 0; + + if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0) + ahd_build_transfer_msg(ahd, devinfo); + else + panic("ahd_intr: AWAITING target message with no message"); + + ahd->msgout_index = 0; + ahd->msg_type = MSG_TYPE_TARGET_MSGIN; +} +#endif +/**************************** Initialization **********************************/ +static u_int +ahd_sglist_size(struct ahd_softc *ahd) +{ + bus_size_t list_size; + + list_size = sizeof(struct ahd_dma_seg) * AHD_NSEG; + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + list_size = sizeof(struct ahd_dma64_seg) * AHD_NSEG; + return (list_size); +} + +/* + * Calculate the optimum S/G List allocation size. S/G elements used + * for a given transaction must be physically contiguous. Assume the + * OS will allocate full pages to us, so it doesn't make sense to request + * less than a page. + */ +static u_int +ahd_sglist_allocsize(struct ahd_softc *ahd) +{ + bus_size_t sg_list_increment; + bus_size_t sg_list_size; + bus_size_t max_list_size; + bus_size_t best_list_size; + + /* Start out with the minimum required for AHD_NSEG. */ + sg_list_increment = ahd_sglist_size(ahd); + sg_list_size = sg_list_increment; + + /* Get us as close as possible to a page in size. */ + while ((sg_list_size + sg_list_increment) <= PAGE_SIZE) + sg_list_size += sg_list_increment; + + /* + * Try to reduce the amount of wastage by allocating + * multiple pages. + */ + best_list_size = sg_list_size; + max_list_size = roundup(sg_list_increment, PAGE_SIZE); + if (max_list_size < 4 * PAGE_SIZE) + max_list_size = 4 * PAGE_SIZE; + if (max_list_size > (AHD_SCB_MAX_ALLOC * sg_list_increment)) + max_list_size = (AHD_SCB_MAX_ALLOC * sg_list_increment); + while ((sg_list_size + sg_list_increment) <= max_list_size + && (sg_list_size % PAGE_SIZE) != 0) { + bus_size_t new_mod; + bus_size_t best_mod; + + sg_list_size += sg_list_increment; + new_mod = sg_list_size % PAGE_SIZE; + best_mod = best_list_size % PAGE_SIZE; + if (new_mod > best_mod || new_mod == 0) { + best_list_size = sg_list_size; + } + } + return (best_list_size); +} + +/* + * Allocate a controller structure for a new device + * and perform initial initializion. + */ +struct ahd_softc * +ahd_alloc(void *platform_arg, char *name) +{ + struct ahd_softc *ahd; + +#ifndef __FreeBSD__ + ahd = malloc(sizeof(*ahd), M_DEVBUF, M_NOWAIT); + if (!ahd) { + printf("aic7xxx: cannot malloc softc!\n"); + free(name, M_DEVBUF); + return NULL; + } +#else + ahd = device_get_softc((device_t)platform_arg); +#endif + memset(ahd, 0, sizeof(*ahd)); + ahd->seep_config = malloc(sizeof(*ahd->seep_config), + M_DEVBUF, M_NOWAIT); + if (ahd->seep_config == NULL) { +#ifndef __FreeBSD__ + free(ahd, M_DEVBUF); +#endif + free(name, M_DEVBUF); + return (NULL); + } + LIST_INIT(&ahd->pending_scbs); + /* We don't know our unit number until the OSM sets it */ + ahd->name = name; + ahd->unit = -1; + ahd->description = NULL; + ahd->bus_description = NULL; + ahd->channel = 'A'; + ahd->chip = AHD_NONE; + ahd->features = AHD_FENONE; + ahd->bugs = AHD_BUGNONE; + ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A + | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A; + ahd_timer_init(&ahd->reset_timer); + ahd_timer_init(&ahd->stat_timer); + ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT; + ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT; + ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT; + ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT; + ahd->int_coalescing_stop_threshold = + AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT; + + if (ahd_platform_alloc(ahd, platform_arg) != 0) { + ahd_free(ahd); + ahd = NULL; + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MEMORY) != 0) { + printf("%s: scb size = 0x%x, hscb size = 0x%x\n", + ahd_name(ahd), (u_int)sizeof(struct scb), + (u_int)sizeof(struct hardware_scb)); + } +#endif + return (ahd); +} + +int +ahd_softc_init(struct ahd_softc *ahd) +{ + + ahd->unpause = 0; + ahd->pause = PAUSE; + return (0); +} + +void +ahd_softc_insert(struct ahd_softc *ahd) +{ + struct ahd_softc *list_ahd; + +#if AHD_PCI_CONFIG > 0 + /* + * Second Function PCI devices need to inherit some + * settings from function 0. + */ + if ((ahd->features & AHD_MULTI_FUNC) != 0) { + TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { + ahd_dev_softc_t list_pci; + ahd_dev_softc_t pci; + + list_pci = list_ahd->dev_softc; + pci = ahd->dev_softc; + if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci) + && ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) { + struct ahd_softc *master; + struct ahd_softc *slave; + + if (ahd_get_pci_function(list_pci) == 0) { + master = list_ahd; + slave = ahd; + } else { + master = ahd; + slave = list_ahd; + } + slave->flags &= ~AHD_BIOS_ENABLED; + slave->flags |= + master->flags & AHD_BIOS_ENABLED; + break; + } + } + } +#endif + + /* + * Insertion sort into our list of softcs. + */ + list_ahd = TAILQ_FIRST(&ahd_tailq); + while (list_ahd != NULL + && ahd_softc_comp(ahd, list_ahd) <= 0) + list_ahd = TAILQ_NEXT(list_ahd, links); + if (list_ahd != NULL) + TAILQ_INSERT_BEFORE(list_ahd, ahd, links); + else + TAILQ_INSERT_TAIL(&ahd_tailq, ahd, links); + ahd->init_level++; +} + +/* + * Verify that the passed in softc pointer is for a + * controller that is still configured. + */ +struct ahd_softc * +ahd_find_softc(struct ahd_softc *ahd) +{ + struct ahd_softc *list_ahd; + + TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { + if (list_ahd == ahd) + return (ahd); + } + return (NULL); +} + +void +ahd_set_unit(struct ahd_softc *ahd, int unit) +{ + ahd->unit = unit; +} + +void +ahd_set_name(struct ahd_softc *ahd, char *name) +{ + if (ahd->name != NULL) + free(ahd->name, M_DEVBUF); + ahd->name = name; +} + +void +ahd_free(struct ahd_softc *ahd) +{ + int i; + + switch (ahd->init_level) { + default: + case 5: + ahd_shutdown(ahd); + TAILQ_REMOVE(&ahd_tailq, ahd, links); + /* FALLTHROUGH */ + case 4: + ahd_dmamap_unload(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap); + /* FALLTHROUGH */ + case 3: + ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, + ahd->shared_data_dmamap); + ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap); + /* FALLTHROUGH */ + case 2: + ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); + case 1: +#ifndef __linux__ + ahd_dma_tag_destroy(ahd, ahd->buffer_dmat); +#endif + break; + case 0: + break; + } + +#ifndef __linux__ + ahd_dma_tag_destroy(ahd, ahd->parent_dmat); +#endif + ahd_platform_free(ahd); + ahd_fini_scbdata(ahd); + for (i = 0; i < AHD_NUM_TARGETS; i++) { + struct ahd_tmode_tstate *tstate; + + tstate = ahd->enabled_targets[i]; + if (tstate != NULL) { +#if AHD_TARGET_MODE + int j; + + for (j = 0; j < AHD_NUM_LUNS; j++) { + struct ahd_tmode_lstate *lstate; + + lstate = tstate->enabled_luns[j]; + if (lstate != NULL) { + xpt_free_path(lstate->path); + free(lstate, M_DEVBUF); + } + } +#endif + free(tstate, M_DEVBUF); + } + } +#if AHD_TARGET_MODE + if (ahd->black_hole != NULL) { + xpt_free_path(ahd->black_hole->path); + free(ahd->black_hole, M_DEVBUF); + } +#endif + if (ahd->name != NULL) + free(ahd->name, M_DEVBUF); + if (ahd->seep_config != NULL) + free(ahd->seep_config, M_DEVBUF); + if (ahd->saved_stack != NULL) + free(ahd->saved_stack, M_DEVBUF); +#ifndef __FreeBSD__ + free(ahd, M_DEVBUF); +#endif + return; +} + +void +ahd_shutdown(void *arg) +{ + struct ahd_softc *ahd; + + ahd = (struct ahd_softc *)arg; + + /* + * Stop periodic timer callbacks. + */ + ahd_timer_stop(&ahd->reset_timer); + ahd_timer_stop(&ahd->stat_timer); + + /* This will reset most registers to 0, but not all */ + ahd_reset(ahd, /*reinit*/FALSE); +} + +/* + * Reset the controller and record some information about it + * that is only available just after a reset. If "reinit" is + * non-zero, this reset occured after initial configuration + * and the caller requests that the chip be fully reinitialized + * to a runable state. Chip interrupts are *not* enabled after + * a reinitialization. The caller must enable interrupts via + * ahd_intr_enable(). + */ +int +ahd_reset(struct ahd_softc *ahd, int reinit) +{ + u_int sxfrctl1; + int wait; + uint32_t cmd; + + /* + * Preserve the value of the SXFRCTL1 register for all channels. + * It contains settings that affect termination and we don't want + * to disturb the integrity of the bus. + */ + ahd_pause(ahd); + ahd_update_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + sxfrctl1 = ahd_inb(ahd, SXFRCTL1); + + cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2); + if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) { + uint32_t mod_cmd; + + /* + * A4 Razor #632 + * During the assertion of CHIPRST, the chip + * does not disable its parity logic prior to + * the start of the reset. This may cause a + * parity error to be detected and thus a + * spurious SERR or PERR assertion. Disble + * PERR and SERR responses during the CHIPRST. + */ + mod_cmd = cmd & ~(PCIM_CMD_PERRESPEN|PCIM_CMD_SERRESPEN); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + mod_cmd, /*bytes*/2); + } + ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause); + + /* + * Ensure that the reset has finished. We delay 1000us + * prior to reading the register to make sure the chip + * has sufficiently completed its reset to handle register + * accesses. + */ + wait = 1000; + do { + ahd_delay(1000); + } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK)); + + if (wait == 0) { + printf("%s: WARNING - Failed chip reset! " + "Trying to initialize anyway.\n", ahd_name(ahd)); + } + ahd_outb(ahd, HCNTRL, ahd->pause); + + if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) { + /* + * Clear any latched PCI error status and restore + * previous SERR and PERR response enables. + */ + ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, + 0xFF, /*bytes*/1); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + cmd, /*bytes*/2); + } + + /* + * Mode should be SCSI after a chip reset, but lets + * set it just to be safe. We touch the MODE_PTR + * register directly so as to bypass the lazy update + * code in ahd_set_modes(). + */ + ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, MODE_PTR, + ahd_build_mode_state(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI)); + + /* + * Restore SXFRCTL1. + * + * We must always initialize STPWEN to 1 before we + * restore the saved values. STPWEN is initialized + * to a tri-state condition which can only be cleared + * by turning it on. + */ + ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN); + ahd_outb(ahd, SXFRCTL1, sxfrctl1); + + /* Determine chip configuration */ + ahd->features &= ~AHD_WIDE; + if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0) + ahd->features |= AHD_WIDE; + + /* + * If a recovery action has forced a chip reset, + * re-initialize the chip to our liking. + */ + if (reinit != 0) + ahd_chip_init(ahd); + + return (0); +} + +/* + * Determine the number of SCBs available on the controller + */ +int +ahd_probe_scbs(struct ahd_softc *ahd) { + int i; + + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + for (i = 0; i < AHD_SCB_MAX; i++) { + int j; + + ahd_set_scbptr(ahd, i); + ahd_outw(ahd, SCB_BASE, i); + for (j = 2; j < 64; j++) + ahd_outb(ahd, SCB_BASE+j, 0); + /* Start out life as unallocated (needing an abort) */ + ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE); + if (ahd_inw_scbram(ahd, SCB_BASE) != i) + break; + ahd_set_scbptr(ahd, 0); + if (ahd_inw_scbram(ahd, SCB_BASE) != 0) + break; + } + return (i); +} + +static void +ahd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + bus_addr_t *baddr; + + baddr = (bus_addr_t *)arg; + *baddr = segs->ds_addr; +} + +static void +ahd_initialize_hscbs(struct ahd_softc *ahd) +{ + int i; + + for (i = 0; i < ahd->scb_data.maxhscbs; i++) { + ahd_set_scbptr(ahd, i); + + /* Clear the control byte. */ + ahd_outb(ahd, SCB_CONTROL, 0); + + /* Set the next pointer */ + ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL); + } +} + +static int +ahd_init_scbdata(struct ahd_softc *ahd) +{ + struct scb_data *scb_data; + int i; + + scb_data = &ahd->scb_data; + TAILQ_INIT(&scb_data->free_scbs); + for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++) + LIST_INIT(&scb_data->free_scb_lists[i]); + LIST_INIT(&scb_data->any_dev_free_scb_list); + SLIST_INIT(&scb_data->hscb_maps); + SLIST_INIT(&scb_data->sg_maps); + SLIST_INIT(&scb_data->sense_maps); + + /* Determine the number of hardware SCBs and initialize them */ + scb_data->maxhscbs = ahd_probe_scbs(ahd); + if (scb_data->maxhscbs == 0) { + printf("%s: No SCB space found\n", ahd_name(ahd)); + return (ENXIO); + } + + ahd_initialize_hscbs(ahd); + + /* + * Create our DMA tags. These tags define the kinds of device + * accessible memory allocations and memory mappings we will + * need to perform during normal operation. + * + * Unless we need to further restrict the allocation, we rely + * on the restrictions of the parent dmat, hence the common + * use of MAXADDR and MAXSIZE. + */ + + /* DMA tag for our hardware scb structures */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + PAGE_SIZE, /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &scb_data->hscb_dmat) != 0) { + goto error_exit; + } + + scb_data->init_level++; + + /* DMA tag for our S/G structures. */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/8, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + ahd_sglist_allocsize(ahd), /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &scb_data->sg_dmat) != 0) { + goto error_exit; + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MEMORY) != 0) + printf("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd), + ahd_sglist_allocsize(ahd)); +#endif + + scb_data->init_level++; + + /* DMA tag for our sense buffers. We allocate in page sized chunks */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + PAGE_SIZE, /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &scb_data->sense_dmat) != 0) { + goto error_exit; + } + + scb_data->init_level++; + + /* Perform initial CCB allocation */ + ahd_alloc_scbs(ahd); + + if (scb_data->numscbs == 0) { + printf("%s: ahd_init_scbdata - " + "Unable to allocate initial scbs\n", + ahd_name(ahd)); + goto error_exit; + } + + /* + * Note that we were successfull + */ + return (0); + +error_exit: + + return (ENOMEM); +} + +static struct scb * +ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag) +{ + struct scb *scb; + + /* + * Look on the pending list. + */ + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + if (SCB_GET_TAG(scb) == tag) + return (scb); + } + + /* + * Then on all of the collision free lists. + */ + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { + struct scb *list_scb; + + list_scb = scb; + do { + if (SCB_GET_TAG(list_scb) == tag) + return (list_scb); + list_scb = LIST_NEXT(list_scb, collision_links); + } while (list_scb); + } + + /* + * And finally on the generic free list. + */ + LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { + if (SCB_GET_TAG(scb) == tag) + return (scb); + } + + return (NULL); +} + +static void +ahd_fini_scbdata(struct ahd_softc *ahd) +{ + struct scb_data *scb_data; + + scb_data = &ahd->scb_data; + if (scb_data == NULL) + return; + + switch (scb_data->init_level) { + default: + case 7: + { + struct map_node *sns_map; + + while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) { + SLIST_REMOVE_HEAD(&scb_data->sense_maps, links); + ahd_dmamap_unload(ahd, scb_data->sense_dmat, + sns_map->dmamap); + ahd_dmamem_free(ahd, scb_data->sense_dmat, + sns_map->vaddr, sns_map->dmamap); + free(sns_map, M_DEVBUF); + } + ahd_dma_tag_destroy(ahd, scb_data->sense_dmat); + /* FALLTHROUGH */ + } + case 6: + { + struct map_node *sg_map; + + while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) { + SLIST_REMOVE_HEAD(&scb_data->sg_maps, links); + ahd_dmamap_unload(ahd, scb_data->sg_dmat, + sg_map->dmamap); + ahd_dmamem_free(ahd, scb_data->sg_dmat, + sg_map->vaddr, sg_map->dmamap); + free(sg_map, M_DEVBUF); + } + ahd_dma_tag_destroy(ahd, scb_data->sg_dmat); + /* FALLTHROUGH */ + } + case 5: + { + struct map_node *hscb_map; + + while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) { + SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links); + ahd_dmamap_unload(ahd, scb_data->hscb_dmat, + hscb_map->dmamap); + ahd_dmamem_free(ahd, scb_data->hscb_dmat, + hscb_map->vaddr, hscb_map->dmamap); + free(hscb_map, M_DEVBUF); + } + ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat); + /* FALLTHROUGH */ + } + case 4: + case 3: + case 2: + case 1: + case 0: + break; + } +} + +/* + * DSP filter Bypass must be enabled until the first selection + * after a change in bus mode (Razor #491 and #493). + */ +static void +ahd_setup_iocell_workaround(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL) + | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS); + ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI)); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: Setting up iocell workaround\n", ahd_name(ahd)); +#endif + ahd_restore_modes(ahd, saved_modes); +} + +static void +ahd_iocell_first_selection(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + u_int sblkctl; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + sblkctl = ahd_inb(ahd, SBLKCTL); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: iocell first selection\n", ahd_name(ahd)); +#endif + if ((sblkctl & ENAB40) != 0) { + ahd_outb(ahd, DSPDATACTL, + ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: BYPASS now disabled\n", ahd_name(ahd)); +#endif + } + ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI)); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + ahd_restore_modes(ahd, saved_modes); +} + +/*************************** SCB Management ***********************************/ +static void +ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx) +{ + struct scb_list *free_list; + struct scb_tailq *free_tailq; + struct scb *first_scb; + + scb->flags |= SCB_ON_COL_LIST; + AHD_SET_SCB_COL_IDX(scb, col_idx); + free_list = &ahd->scb_data.free_scb_lists[col_idx]; + free_tailq = &ahd->scb_data.free_scbs; + first_scb = LIST_FIRST(free_list); + if (first_scb != NULL) { + LIST_INSERT_AFTER(first_scb, scb, collision_links); + } else { + LIST_INSERT_HEAD(free_list, scb, collision_links); + TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe); + } +} + +static void +ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb) +{ + struct scb_list *free_list; + struct scb_tailq *free_tailq; + struct scb *first_scb; + u_int col_idx; + + scb->flags &= ~SCB_ON_COL_LIST; + col_idx = AHD_GET_SCB_COL_IDX(ahd, scb); + free_list = &ahd->scb_data.free_scb_lists[col_idx]; + free_tailq = &ahd->scb_data.free_scbs; + first_scb = LIST_FIRST(free_list); + if (first_scb == scb) { + struct scb *next_scb; + + /* + * Maintain order in the collision free + * lists for fairness if this device has + * other colliding tags active. + */ + next_scb = LIST_NEXT(scb, collision_links); + if (next_scb != NULL) { + TAILQ_INSERT_AFTER(free_tailq, scb, + next_scb, links.tqe); + } + TAILQ_REMOVE(free_tailq, scb, links.tqe); + } + LIST_REMOVE(scb, collision_links); +} + +/* + * Get a free scb. If there are none, see if we can allocate a new SCB. + */ +struct scb * +ahd_get_scb(struct ahd_softc *ahd, u_int col_idx) +{ + struct scb *scb; + int tries; + + tries = 0; +look_again: + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { + if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) { + ahd_rem_col_list(ahd, scb); + goto found; + } + } + if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL) { + + if (tries++ != 0) + return (NULL); + ahd_alloc_scbs(ahd); + goto look_again; + } + LIST_REMOVE(scb, links.le); + if (col_idx != AHD_NEVER_COL_IDX + && (scb->col_scb != NULL) + && (scb->col_scb->flags & SCB_ACTIVE) == 0) { + LIST_REMOVE(scb->col_scb, links.le); + ahd_add_col_list(ahd, scb->col_scb, col_idx); + } +found: + scb->flags |= SCB_ACTIVE; + return (scb); +} + +/* + * Return an SCB resource to the free list. + */ +void +ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) +{ + + /* Clean up for the next user */ + scb->flags = SCB_FLAG_NONE; + scb->hscb->control = 0; + ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL; + + if (scb->col_scb == NULL) { + + /* + * No collision possible. Just free normally. + */ + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb, links.le); + } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) { + + /* + * The SCB we might have collided with is on + * a free collision list. Put both SCBs on + * the generic list. + */ + ahd_rem_col_list(ahd, scb->col_scb); + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb, links.le); + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb->col_scb, links.le); + } else if ((scb->col_scb->flags + & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE + && (scb->col_scb->hscb->control & TAG_ENB) != 0) { + + /* + * The SCB we might collide with on the next allocation + * is still active in a non-packetized, tagged, context. + * Put us on the SCB collision list. + */ + ahd_add_col_list(ahd, scb, + AHD_GET_SCB_COL_IDX(ahd, scb->col_scb)); + } else { + /* + * The SCB we might collide with on the next allocation + * is either active in a packetized context, or free. + * Since we can't collide, put this SCB on the generic + * free list. + */ + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, + scb, links.le); + } + + ahd_platform_scb_free(ahd, scb); +} + +void +ahd_alloc_scbs(struct ahd_softc *ahd) +{ + struct scb_data *scb_data; + struct scb *next_scb; + struct hardware_scb *hscb; + struct map_node *hscb_map; + struct map_node *sg_map; + struct map_node *sense_map; + uint8_t *segs; + uint8_t *sense_data; + bus_addr_t hscb_busaddr; + bus_addr_t sg_busaddr; + bus_addr_t sense_busaddr; + int newcount; + int i; + + scb_data = &ahd->scb_data; + if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC) + /* Can't allocate any more */ + return; + + if (scb_data->scbs_left != 0) { + int offset; + + offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left; + hscb_map = SLIST_FIRST(&scb_data->hscb_maps); + hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset]; + hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb)); + } else { + hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_NOWAIT); + + if (hscb_map == NULL) + return; + + /* Allocate the next batch of hardware SCBs */ + if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat, + (void **)&hscb_map->vaddr, + BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) { + free(hscb_map, M_DEVBUF); + return; + } + + SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links); + + ahd_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap, + hscb_map->vaddr, PAGE_SIZE, ahd_dmamap_cb, + &hscb_map->physaddr, /*flags*/0); + + hscb = (struct hardware_scb *)hscb_map->vaddr; + hscb_busaddr = hscb_map->physaddr; + scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb); + } + + if (scb_data->sgs_left != 0) { + int offset; + + offset = ((ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd)) + - scb_data->sgs_left) * ahd_sglist_size(ahd); + sg_map = SLIST_FIRST(&scb_data->sg_maps); + segs = sg_map->vaddr + offset; + sg_busaddr = sg_map->physaddr + offset; + } else { + sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); + + if (sg_map == NULL) + return; + + /* Allocate the next batch of S/G lists */ + if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat, + (void **)&sg_map->vaddr, + BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) { + free(sg_map, M_DEVBUF); + return; + } + + SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links); + + ahd_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap, + sg_map->vaddr, ahd_sglist_allocsize(ahd), + ahd_dmamap_cb, &sg_map->physaddr, /*flags*/0); + + segs = sg_map->vaddr; + sg_busaddr = sg_map->physaddr; + scb_data->sgs_left = + ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_MEMORY) + printf("Mapped SG data\n"); +#endif + } + + if (scb_data->sense_left != 0) { + int offset; + + offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left); + sense_map = SLIST_FIRST(&scb_data->sense_maps); + sense_data = sense_map->vaddr + offset; + sense_busaddr = sense_map->physaddr + offset; + } else { + sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_NOWAIT); + + if (sense_map == NULL) + return; + + /* Allocate the next batch of sense buffers */ + if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat, + (void **)&sense_map->vaddr, + BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) { + free(sense_map, M_DEVBUF); + return; + } + + SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links); + + ahd_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap, + sense_map->vaddr, PAGE_SIZE, ahd_dmamap_cb, + &sense_map->physaddr, /*flags*/0); + + sense_data = sense_map->vaddr; + sense_busaddr = sense_map->physaddr; + scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_MEMORY) + printf("Mapped sense data\n"); +#endif + } + + newcount = MIN(scb_data->sense_left, scb_data->scbs_left); + newcount = MIN(newcount, scb_data->sgs_left); + newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); + scb_data->sense_left -= newcount; + scb_data->scbs_left -= newcount; + scb_data->sgs_left -= newcount; + for (i = 0; i < newcount; i++) { + u_int col_tag; + + struct scb_platform_data *pdata; +#ifndef __linux__ + int error; +#endif + next_scb = (struct scb *)malloc(sizeof(*next_scb), + M_DEVBUF, M_NOWAIT); + if (next_scb == NULL) + break; + + pdata = (struct scb_platform_data *)malloc(sizeof(*pdata), + M_DEVBUF, M_NOWAIT); + if (pdata == NULL) { + free(next_scb, M_DEVBUF); + break; + } + next_scb->platform_data = pdata; + next_scb->hscb_map = hscb_map; + next_scb->sg_map = sg_map; + next_scb->sense_map = sense_map; + next_scb->sg_list = segs; + next_scb->sense_data = sense_data; + next_scb->sense_busaddr = sense_busaddr; + memset(hscb, 0, sizeof(*hscb)); + next_scb->hscb = hscb; + hscb->hscb_busaddr = ahd_htole32(hscb_busaddr); + + /* + * The sequencer always starts with the second entry. + * The first entry is embedded in the scb. + */ + next_scb->sg_list_busaddr = sg_busaddr; + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + next_scb->sg_list_busaddr + += sizeof(struct ahd_dma64_seg); + else + next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg); + next_scb->ahd_softc = ahd; + next_scb->flags = SCB_FLAG_NONE; +#ifndef __linux__ + error = ahd_dmamap_create(ahd, ahd->buffer_dmat, /*flags*/0, + &next_scb->dmamap); + if (error != 0) { + free(next_scb, M_DEVBUF); + free(pdata, M_DEVBUF); + break; + } +#endif + next_scb->hscb->tag = ahd_htole16(scb_data->numscbs); + col_tag = scb_data->numscbs ^ 0x100; + next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag); + if (next_scb->col_scb != NULL) + next_scb->col_scb->col_scb = next_scb; + ahd_free_scb(ahd, next_scb); + hscb++; + hscb_busaddr += sizeof(*hscb); + segs += ahd_sglist_size(ahd); + sg_busaddr += ahd_sglist_size(ahd); + sense_data += AHD_SENSE_BUFSIZE; + sense_busaddr += AHD_SENSE_BUFSIZE; + scb_data->numscbs++; + } +} + +void +ahd_controller_info(struct ahd_softc *ahd, char *buf) +{ + const char *speed; + const char *type; + int len; + + len = sprintf(buf, "%s: ", ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]); + buf += len; + + speed = "Ultra320 "; + if ((ahd->features & AHD_WIDE) != 0) { + type = "Wide "; + } else { + type = "Single "; + } + len = sprintf(buf, "%s%sChannel %c, SCSI Id=%d, ", + speed, type, ahd->channel, ahd->our_id); + buf += len; + + sprintf(buf, "%s, %d SCBs", ahd->bus_description, + ahd->scb_data.maxhscbs); +} + +static const char *channel_strings[] = { + "Primary Low", + "Primary High", + "Secondary Low", + "Secondary High" +}; + +static const char *termstat_strings[] = { + "Terminated Correctly", + "Over Terminated", + "Under Terminated", + "Not Configured" +}; + +/* + * Start the board, ready for normal operation + */ +int +ahd_init(struct ahd_softc *ahd) +{ + uint8_t *base_vaddr; + uint8_t *next_vaddr; + bus_addr_t next_baddr; + size_t driver_data_size; + int i; + int error; + u_int warn_user; + uint8_t current_sensing; + uint8_t fstat; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + + ahd->stack_size = ahd_probe_stack_size(ahd); + ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t), + M_DEVBUF, M_NOWAIT); + if (ahd->saved_stack == NULL) + return (ENOMEM); + + /* + * Verify that the compiler hasn't over-agressively + * padded important structures. + */ + if (sizeof(struct hardware_scb) != 64) + panic("Hardware SCB size is incorrect"); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0) + ahd->flags |= AHD_SEQUENCER_DEBUG; +#endif + + /* + * Default to allowing initiator operations. + */ + ahd->flags |= AHD_INITIATORROLE; + + /* + * Only allow target mode features if this unit has them enabled. + */ + if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0) + ahd->features &= ~AHD_TARGETMODE; + +#ifndef __linux__ + /* DMA tag for mapping buffers into device visible space. */ + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/ahd->flags & AHD_39BIT_ADDRESSING + ? (bus_addr_t)0x7FFFFFFFFFULL + : BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + /*maxsize*/(AHD_NSEG - 1) * PAGE_SIZE, + /*nsegments*/AHD_NSEG, + /*maxsegsz*/AHD_MAXTRANSFER_SIZE, + /*flags*/BUS_DMA_ALLOCNOW, + &ahd->buffer_dmat) != 0) { + return (ENOMEM); + } +#endif + + ahd->init_level++; + + /* + * DMA tag for our command fifos and other data in system memory + * the card's sequencer must be able to access. For initiator + * roles, we need to allocate space for the qoutfifo. When providing + * for the target mode role, we must additionally provide space for + * the incoming target command fifo. + */ + driver_data_size = AHD_SCB_MAX * sizeof(uint16_t) + + sizeof(struct hardware_scb); + if ((ahd->features & AHD_TARGETMODE) != 0) + driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd); + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) + driver_data_size += PKT_OVERRUN_BUFSIZE; + if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, + /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + driver_data_size, + /*nsegments*/1, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, &ahd->shared_data_dmat) != 0) { + return (ENOMEM); + } + + ahd->init_level++; + + /* Allocation of driver data */ + if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, + (void **)&base_vaddr, + BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) { + return (ENOMEM); + } + + ahd->init_level++; + + /* And permanently map it in */ + ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, + base_vaddr, driver_data_size, ahd_dmamap_cb, + &ahd->shared_data_busaddr, /*flags*/0); + ahd->qoutfifo = (uint16_t *)base_vaddr; + next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; + next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t); + if ((ahd->features & AHD_TARGETMODE) != 0) { + ahd->targetcmds = (struct target_cmd *)next_vaddr; + next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); + next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); + } + + if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) { + ahd->overrun_buf = next_vaddr; + next_vaddr += PKT_OVERRUN_BUFSIZE; + next_baddr += PKT_OVERRUN_BUFSIZE; + } + + /* + * We need one SCB to serve as the "next SCB". Since the + * tag identifier in this SCB will never be used, there is + * no point in using a valid HSCB tag from an SCB pulled from + * the standard free pool. So, we allocate this "sentinel" + * specially from the DMA safe memory chunk used for the QOUTFIFO. + */ + ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; + ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr); + + ahd->init_level++; + + /* Allocate SCB data now that buffer_dmat is initialized */ + if (ahd_init_scbdata(ahd) != 0) + return (ENOMEM); + + if ((ahd->flags & AHD_INITIATORROLE) == 0) + ahd->flags &= ~AHD_RESET_BUS_A; + + /* + * Before committing these settings to the chip, give + * the OSM one last chance to modify our configuration. + */ + ahd_platform_init(ahd); + + /* Bring up the chip. */ + ahd_chip_init(ahd); + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + + if ((ahd->flags & AHD_CURRENT_SENSING) == 0) + goto init_done; + + /* + * Verify termination based on current draw and + * warn user if the bus is over/under terminated. + */ + error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, + CURSENSE_ENB); + if (error != 0) { + printf("%s: current sensing timeout 1\n", ahd_name(ahd)); + goto init_done; + } + for (i = 20, fstat = FLX_FSTAT_BUSY; + (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) { + error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat); + if (error != 0) { + printf("%s: current sensing timeout 2\n", + ahd_name(ahd)); + goto init_done; + } + } + if (i == 0) { + printf("%s: Timedout during current-sensing test\n", + ahd_name(ahd)); + goto init_done; + } + + /* Latch Current Sensing status. */ + error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, ¤t_sensing); + if (error != 0) { + printf("%s: current sensing timeout 3\n", ahd_name(ahd)); + goto init_done; + } + + /* Diable current sensing. */ + ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) { + printf("%s: current_sensing == 0x%x\n", + ahd_name(ahd), current_sensing); + } +#endif + warn_user = 0; + for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) { + u_int term_stat; + + term_stat = (current_sensing & FLX_CSTAT_MASK); + switch (term_stat) { + case FLX_CSTAT_OVER: + case FLX_CSTAT_UNDER: + warn_user++; + case FLX_CSTAT_INVALID: + case FLX_CSTAT_OKAY: + if (warn_user == 0 && bootverbose == 0) + break; + printf("%s: %s Channel %s\n", ahd_name(ahd), + channel_strings[i], termstat_strings[term_stat]); + break; + } + } + if (warn_user) { + printf("%s: WARNING. Termination is not configured correctly.\n" + "%s: WARNING. SCSI bus operations may FAIL.\n", + ahd_name(ahd), ahd_name(ahd)); + } +init_done: + ahd_restart(ahd); + ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, + ahd_stat_timer, ahd); + return (0); +} + +/* + * (Re)initialize chip state after a chip reset. + */ +static void +ahd_chip_init(struct ahd_softc *ahd) +{ + uint32_t busaddr; + u_int sxfrctl1; + u_int scsiseq_template; + u_int wait; + u_int i; + u_int target; + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + /* + * Take the LED out of diagnostic mode + */ + ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON)); + + /* + * Return HS_MAILBOX to its default value. + */ + ahd->hs_mailbox = 0; + ahd_outb(ahd, HS_MAILBOX, 0); + + /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1. */ + ahd_outb(ahd, IOWNID, ahd->our_id); + ahd_outb(ahd, TOWNID, ahd->our_id); + sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0; + sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0; + if ((ahd->bugs & AHD_LONG_SETIMO_BUG) + && (ahd->seltime != STIMESEL_MIN)) { + /* + * The selection timer duration is twice as long + * as it should be. Halve it by adding "1" to + * the user specified setting. + */ + sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ; + } else { + sxfrctl1 |= ahd->seltime; + } + + ahd_outb(ahd, SXFRCTL0, DFON); + ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN); + ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR); + + /* + * Now that termination is set, wait for up + * to 500ms for our transceivers to settle. If + * the adapter does not have a cable attached, + * the transceivers may never settle, so don't + * complain if we fail here. + */ + for (wait = 10000; + (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait; + wait--) + ahd_delay(100); + + /* Clear any false bus resets due to the transceivers settling */ + ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + + /* Initialize mode specific S/G state. */ + for (i = 0; i < 2; i++) { + ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); + ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); + ahd_outb(ahd, SG_STATE, 0); + ahd_outb(ahd, CLRSEQINTSRC, 0xFF); + ahd_outb(ahd, SEQIMODE, + ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT + |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD); + } + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN); + ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75); + ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN); + ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR); + if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { + ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE); + } else { + ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE); + } + ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN|SHVALIDSTDIS); + if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX) + /* + * Do not issue a target abort when a split completion + * error occurs. Let our PCIX interrupt handler deal + * with it instead. H2A4 Razor #625 + */ + ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS); + + if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0) + ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER); + + /* + * Tweak IOCELL settings. + */ + if ((ahd->flags & AHD_HP_BOARD) != 0) { + for (i = 0; i < NUMDSPS; i++) { + ahd_outb(ahd, DSPSELECT, i); + ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT); + } +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd), + WRTBIASCTL_HP_DEFAULT); +#endif + } + ahd_setup_iocell_workaround(ahd); + + /* + * Enable LQI Manager interrupts. + */ + ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT + | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI + | ENLQIOVERI_LQ|ENLQIOVERI_NLQ); + ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC); + /* + * An interrupt from LQOBUSFREE is made redundant by the + * BUSFREE interrupt. We choose to have the sequencer catch + * LQOPHCHGINPKT errors manually for the command phase at the + * start of a packetized selection case. + ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT); + */ + ahd_outb(ahd, LQOMODE1, 0); + + /* + * Setup sequencer interrupt handlers. + */ + ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr)); + ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr)); + + /* + * Setup SCB Offset registers. + */ + if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { + ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, + pkt_long_lun)); + } else { + ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun)); + } + ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len)); + ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute)); + ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management)); + ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb, + shared_data.idata.cdb)); + ahd_outb(ahd, QNEXTPTR, + offsetof(struct hardware_scb, next_hscb_busaddr)); + ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET); + ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control)); + if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) { + ahd_outb(ahd, LUNLEN, + sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1); + } else { + ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN); + } + ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1); + ahd_outb(ahd, MAXCMD, 0xFF); + ahd_outb(ahd, SCBAUTOPTR, + AUSCBPTR_EN | offsetof(struct hardware_scb, tag)); + + /* We haven't been enabled for target mode yet. */ + ahd_outb(ahd, MULTARGID, 0); + ahd_outb(ahd, MULTARGID + 1, 0); + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + /* Initialize the negotiation table. */ + if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) { + /* + * Clear the spare bytes in the neg table to avoid + * spurious parity errors. + */ + for (target = 0; target < AHD_NUM_TARGETS; target++) { + ahd_outb(ahd, NEGOADDR, target); + ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0); + for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++) + ahd_outb(ahd, ANNEXDAT, 0); + } + } + for (target = 0; target < AHD_NUM_TARGETS; target++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + target, &tstate); + ahd_compile_devinfo(&devinfo, ahd->our_id, + target, CAM_LUN_WILDCARD, + 'A', ROLE_INITIATOR); + ahd_update_neg_table(ahd, &devinfo, &tinfo->curr); + } + + ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR); + ahd_outb(ahd, CLRINT, CLRSCSIINT); + + /* + * Always enable abort on incoming L_Qs if this feature is + * supported. We use this to catch invalid SCB references. + */ + if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0) + ahd_outb(ahd, LQCTL1, ABORTPENDING); + else + ahd_outb(ahd, LQCTL1, 0); + + /* All of our queues are empty */ + ahd->qoutfifonext = 0; + ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE; + ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8); + for (i = 0; i < AHD_QOUT_SIZE; i++) + ahd->qoutfifo[i] = 0; + ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD); + + ahd->qinfifonext = 0; + for (i = 0; i < AHD_QIN_SIZE; i++) + ahd->qinfifo[i] = SCB_LIST_NULL; + + if ((ahd->features & AHD_TARGETMODE) != 0) { + /* All target command blocks start out invalid. */ + for (i = 0; i < AHD_TMODE_CMDS; i++) + ahd->targetcmds[i].cmd_valid = 0; + ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD); + ahd->tqinfifonext = 1; + ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1); + ahd_outb(ahd, TQINPOS, ahd->tqinfifonext); + } + + /* Initialize Scratch Ram. */ + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_outb(ahd, SEQ_FLAGS2, 0); + + /* We don't have any waiting selections */ + ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL); + ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL); + for (i = 0; i < AHD_NUM_TARGETS; i++) + ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL); + + /* + * Nobody is waiting to be DMAed into the QOUTFIFO. + */ + ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); + ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL); + ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); + + /* + * The Freeze Count is 0. + */ + ahd_outw(ahd, QFREEZE_COUNT, 0); + + /* + * Tell the sequencer where it can find our arrays in memory. + */ + busaddr = ahd->shared_data_busaddr; + ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF); + ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF); + + /* + * Setup the allowed SCSI Sequences based on operational mode. + * If we are a target, we'll enable select in operations once + * we've had a lun enabled. + */ + scsiseq_template = ENAUTOATNP; + if ((ahd->flags & AHD_INITIATORROLE) != 0) + scsiseq_template |= ENRSELI; + ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template); + + /* There are no busy SCBs yet. */ + for (target = 0; target < AHD_NUM_TARGETS; target++) { + int lun; + + for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++) + ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun)); + } + + /* + * Initialize the group code to command length table. + * Vendor Unique codes are set to 0 so we only capture + * the first byte of the cdb. These can be overridden + * when target mode is enabled. + */ + ahd_outb(ahd, CMDSIZE_TABLE, 5); + ahd_outb(ahd, CMDSIZE_TABLE + 1, 9); + ahd_outb(ahd, CMDSIZE_TABLE + 2, 9); + ahd_outb(ahd, CMDSIZE_TABLE + 3, 0); + ahd_outb(ahd, CMDSIZE_TABLE + 4, 15); + ahd_outb(ahd, CMDSIZE_TABLE + 5, 11); + ahd_outb(ahd, CMDSIZE_TABLE + 6, 0); + ahd_outb(ahd, CMDSIZE_TABLE + 7, 0); + + /* Tell the sequencer of our initial queue positions */ + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512); + ahd->qinfifonext = 0; + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); + ahd_set_hescb_qoff(ahd, 0); + ahd_set_snscb_qoff(ahd, 0); + ahd_set_sescb_qoff(ahd, 0); + ahd_set_sdscb_qoff(ahd, 0); + + /* + * Tell the sequencer which SCB will be the next one it receives. + */ + busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); + + /* + * Default to coalescing disabled. + */ + ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0); + ahd_outw(ahd, CMDS_PENDING, 0); + ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer, + ahd->int_coalescing_maxcmds, + ahd->int_coalescing_mincmds); + ahd_enable_coalescing(ahd, FALSE); + + ahd_loadseq(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); +} + +/* + * Setup default device and controller settings. + * This should only be called if our probe has + * determined that no configuration data is available. + */ +int +ahd_default_config(struct ahd_softc *ahd) +{ + int targ; + + ahd->our_id = 7; + + /* + * Allocate a tstate to house information for our + * initiator presence on the bus as well as the user + * data for any target mode initiator. + */ + if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { + printf("%s: unable to allocate ahd_tmode_tstate. " + "Failing attach\n", ahd_name(ahd)); + return (ENOMEM); + } + + for (targ = 0; targ < AHD_NUM_TARGETS; targ++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + uint16_t target_mask; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + targ, &tstate); + /* + * We support SPC2 and SPI4. + */ + tinfo->user.protocol_version = 4; + tinfo->user.transport_version = 4; + + target_mask = 0x01 << targ; + ahd->user_discenable |= target_mask; + tstate->discenable |= target_mask; + ahd->user_tagenable |= target_mask; +#ifdef AHD_FORCE_160 + tinfo->user.period = AHD_SYNCRATE_DT; +#else + tinfo->user.period = AHD_SYNCRATE_160; +#endif + tinfo->user.offset = MAX_OFFSET; + tinfo->user.ppr_options = MSG_EXT_PPR_RD_STRM + | MSG_EXT_PPR_WR_FLOW + | MSG_EXT_PPR_HOLD_MCS + | MSG_EXT_PPR_IU_REQ + | MSG_EXT_PPR_QAS_REQ + | MSG_EXT_PPR_DT_REQ; + if ((ahd->features & AHD_RTI) != 0) + tinfo->user.ppr_options |= MSG_EXT_PPR_RTI; + + tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT; + + /* + * Start out Async/Narrow/Untagged and with + * conservative protocol support. + */ + tinfo->goal.protocol_version = 2; + tinfo->goal.transport_version = 2; + tinfo->curr.protocol_version = 2; + tinfo->curr.transport_version = 2; + ahd_compile_devinfo(&devinfo, ahd->our_id, + targ, CAM_LUN_WILDCARD, + 'A', ROLE_INITIATOR); + tstate->tagenable &= ~target_mask; + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, + /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + } + return (0); +} + +/* + * Parse device configuration information. + */ +int +ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc) +{ + int targ; + int max_targ; + + max_targ = sc->max_targets & CFMAXTARG; + ahd->our_id = sc->brtime_id & CFSCSIID; + + /* + * Allocate a tstate to house information for our + * initiator presence on the bus as well as the user + * data for any target mode initiator. + */ + if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { + printf("%s: unable to allocate ahd_tmode_tstate. " + "Failing attach\n", ahd_name(ahd)); + return (ENOMEM); + } + + for (targ = 0; targ < max_targ; targ++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_transinfo *user_tinfo; + struct ahd_tmode_tstate *tstate; + uint16_t target_mask; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + targ, &tstate); + user_tinfo = &tinfo->user; + + /* + * We support SPC2 and SPI4. + */ + tinfo->user.protocol_version = 4; + tinfo->user.transport_version = 4; + + target_mask = 0x01 << targ; + ahd->user_discenable &= ~target_mask; + tstate->discenable &= ~target_mask; + ahd->user_tagenable &= ~target_mask; + if (sc->device_flags[targ] & CFDISC) { + tstate->discenable |= target_mask; + ahd->user_discenable |= target_mask; + ahd->user_tagenable |= target_mask; + } else { + /* + * Cannot be packetized without disconnection. + */ + sc->device_flags[targ] &= ~CFPACKETIZED; + } + + user_tinfo->ppr_options = 0; + user_tinfo->period = (sc->device_flags[targ] & CFXFER); + if (user_tinfo->period < CFXFER_ASYNC) { + if (user_tinfo->period <= AHD_PERIOD_10MHz) + user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ; + user_tinfo->offset = MAX_OFFSET; + } else { + user_tinfo->offset = 0; + user_tinfo->period = AHD_ASYNC_XFER_PERIOD; + } +#ifdef AHD_FORCE_160 + if (user_tinfo->period <= AHD_SYNCRATE_160) + user_tinfo->period = AHD_SYNCRATE_DT; +#endif + + if ((sc->device_flags[targ] & CFPACKETIZED) != 0) { + user_tinfo->ppr_options |= MSG_EXT_PPR_RD_STRM + | MSG_EXT_PPR_WR_FLOW + | MSG_EXT_PPR_HOLD_MCS + | MSG_EXT_PPR_IU_REQ; + if ((ahd->features & AHD_RTI) != 0) + user_tinfo->ppr_options |= MSG_EXT_PPR_RTI; + } + + if ((sc->device_flags[targ] & CFQAS) != 0) + user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ; + + if ((sc->device_flags[targ] & CFWIDEB) != 0) + user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT; + else + user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) + printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width, + user_tinfo->period, user_tinfo->offset, + user_tinfo->ppr_options); +#endif + /* + * Start out Async/Narrow/Untagged and with + * conservative protocol support. + */ + tstate->tagenable &= ~target_mask; + tinfo->goal.protocol_version = 2; + tinfo->goal.transport_version = 2; + tinfo->curr.protocol_version = 2; + tinfo->curr.transport_version = 2; + ahd_compile_devinfo(&devinfo, ahd->our_id, + targ, CAM_LUN_WILDCARD, + 'A', ROLE_INITIATOR); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, + /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, + /*paused*/TRUE); + } + + ahd->flags &= ~AHD_SPCHK_ENB_A; + if (sc->bios_control & CFSPARITY) + ahd->flags |= AHD_SPCHK_ENB_A; + + ahd->flags &= ~AHD_RESET_BUS_A; + if (sc->bios_control & CFRESETB) + ahd->flags |= AHD_RESET_BUS_A; + + ahd->flags &= ~AHD_EXTENDED_TRANS_A; + if (sc->bios_control & CFEXTEND) + ahd->flags |= AHD_EXTENDED_TRANS_A; + + ahd->flags &= ~AHD_BIOS_ENABLED; + if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED) + ahd->flags |= AHD_BIOS_ENABLED; + + ahd->flags &= ~AHD_STPWLEVEL_A; + if ((sc->adapter_control & CFSTPWLEVEL) != 0) + ahd->flags |= AHD_STPWLEVEL_A; + + return (0); +} + +/* + * Parse device configuration information. + */ +int +ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd) +{ + int error; + + error = ahd_verify_vpd_cksum(vpd); + if (error == 0) + return (EINVAL); + if ((vpd->bios_flags & VPDBOOTHOST) != 0) + ahd->flags |= AHD_BOOT_CHANNEL; + return (0); +} + +void +ahd_intr_enable(struct ahd_softc *ahd, int enable) +{ + u_int hcntrl; + + hcntrl = ahd_inb(ahd, HCNTRL); + hcntrl &= ~INTEN; + ahd->pause &= ~INTEN; + ahd->unpause &= ~INTEN; + if (enable) { + hcntrl |= INTEN; + ahd->pause |= INTEN; + ahd->unpause |= INTEN; + } + ahd_outb(ahd, HCNTRL, hcntrl); +} + +void +ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, + u_int mincmds) +{ + if (timer > AHD_TIMER_MAX_US) + timer = AHD_TIMER_MAX_US; + ahd->int_coalescing_timer = timer; + + if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX) + maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX; + if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX) + mincmds = AHD_INT_COALESCING_MINCMDS_MAX; + ahd->int_coalescing_maxcmds = maxcmds; + ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK); + ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds); + ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds); +} + +void +ahd_enable_coalescing(struct ahd_softc *ahd, int enable) +{ + + ahd->hs_mailbox &= ~ENINT_COALESCE; + if (enable) + ahd->hs_mailbox |= ENINT_COALESCE; + ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox); + ahd_flush_device_writes(ahd); + ahd_run_qoutfifo(ahd); +} + +/* + * Ensure that the card is paused in a location + * outside of all critical sections and that all + * pending work is completed prior to returning. + * This routine should only be called from outside + * an interrupt context. + */ +void +ahd_pause_and_flushwork(struct ahd_softc *ahd) +{ + u_int intstat; + u_int maxloops; + u_int qfreeze_cnt; + + maxloops = 1000; + ahd->flags |= AHD_ALL_INTERRUPTS; + ahd_pause(ahd); + /* + * Increment the QFreeze Count so that the sequencer + * will not start new selections. We do this only + * until we are safely paused without further selections + * pending. + */ + ahd_outw(ahd, QFREEZE_COUNT, ahd_inw(ahd, QFREEZE_COUNT) + 1); + ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN); + do { + struct scb *waiting_scb; + + ahd_unpause(ahd); + ahd_intr(ahd); + ahd_pause(ahd); + ahd_clear_critical_section(ahd); + intstat = ahd_inb(ahd, INTSTAT); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0) + ahd_outb(ahd, SCSISEQ0, + ahd_inb(ahd, SCSISEQ0) & ~ENSELO); + /* + * In the non-packetized case, the sequencer (for Rev A), + * relies on ENSELO remaining set after SELDO. The hardware + * auto-clears ENSELO in the packetized case. + */ + waiting_scb = ahd_lookup_scb(ahd, + ahd_inw(ahd, WAITING_TID_HEAD)); + if (waiting_scb != NULL + && (waiting_scb->flags & SCB_PACKETIZED) == 0 + && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0) + ahd_outb(ahd, SCSISEQ0, + ahd_inb(ahd, SCSISEQ0) | ENSELO); + } while (--maxloops + && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0) + && ((intstat & INT_PEND) != 0 + || (ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0 + || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0)); + + if (maxloops == 0) { + printf("Infinite interrupt loop, INTSTAT = %x", + ahd_inb(ahd, INTSTAT)); + } + qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT); + if (qfreeze_cnt == 0) { + printf("%s: ahd_pause_and_flushwork with 0 qfreeze count!\n", + ahd_name(ahd)); + } else { + qfreeze_cnt--; + } + ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt); + if (qfreeze_cnt == 0) + ahd_outb(ahd, SEQ_FLAGS2, + ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN); + + ahd_flush_qoutfifo(ahd); + + ahd_platform_flushwork(ahd); + ahd->flags &= ~AHD_ALL_INTERRUPTS; +} + +int +ahd_suspend(struct ahd_softc *ahd) +{ + + ahd_pause_and_flushwork(ahd); + + if (LIST_FIRST(&ahd->pending_scbs) != NULL) { + ahd_unpause(ahd); + return (EBUSY); + } + ahd_shutdown(ahd); + return (0); +} + +int +ahd_resume(struct ahd_softc *ahd) +{ + + ahd_reset(ahd, /*reinit*/TRUE); + ahd_intr_enable(ahd, TRUE); + ahd_restart(ahd); + return (0); +} + +/************************** Busy Target Table *********************************/ +/* + * Set SCBPTR to the SCB that contains the busy + * table entry for TCL. Return the offset into + * the SCB that contains the entry for TCL. + * saved_scbid is dereferenced and set to the + * scbid that should be restored once manipualtion + * of the TCL entry is complete. + */ +static __inline u_int +ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl) +{ + /* + * Index to the SCB that contains the busy entry. + */ + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + *saved_scbid = ahd_get_scbptr(ahd); + ahd_set_scbptr(ahd, TCL_LUN(tcl) + | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4)); + + /* + * And now calculate the SCB offset to the entry. + * Each entry is 2 bytes wide, hence the + * multiplication by 2. + */ + return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS); +} + +/* + * Return the untagged transaction id for a given target/channel lun. + */ +u_int +ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) +{ + u_int scbid; + u_int scb_offset; + u_int saved_scbptr; + + scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl); + scbid = ahd_inw_scbram(ahd, scb_offset); + ahd_set_scbptr(ahd, saved_scbptr); + return (scbid); +} + +void +ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) +{ + u_int scb_offset; + u_int saved_scbptr; + + scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl); + ahd_outw(ahd, scb_offset, scbid); + ahd_set_scbptr(ahd, saved_scbptr); +} + +/************************** SCB and SCB queue management **********************/ +int +ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, + char channel, int lun, u_int tag, role_t role) +{ + int targ = SCB_GET_TARGET(ahd, scb); + char chan = SCB_GET_CHANNEL(ahd, scb); + int slun = SCB_GET_LUN(scb); + int match; + + match = ((chan == channel) || (channel == ALL_CHANNELS)); + if (match != 0) + match = ((targ == target) || (target == CAM_TARGET_WILDCARD)); + if (match != 0) + match = ((lun == slun) || (lun == CAM_LUN_WILDCARD)); + if (match != 0) { +#if AHD_TARGET_MODE + int group; + + group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code); + if (role == ROLE_INITIATOR) { + match = (group != XPT_FC_GROUP_TMODE) + && ((tag == SCB_GET_TAG(scb)) + || (tag == SCB_LIST_NULL)); + } else if (role == ROLE_TARGET) { + match = (group == XPT_FC_GROUP_TMODE) + && ((tag == scb->io_ctx->csio.tag_id) + || (tag == SCB_LIST_NULL)); + } +#else /* !AHD_TARGET_MODE */ + match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL)); +#endif /* AHD_TARGET_MODE */ + } + + return match; +} + +void +ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb) +{ + int target; + char channel; + int lun; + + target = SCB_GET_TARGET(ahd, scb); + lun = SCB_GET_LUN(scb); + channel = SCB_GET_CHANNEL(ahd, scb); + + ahd_search_qinfifo(ahd, target, channel, lun, + /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN, + CAM_REQUEUE_REQ, SEARCH_COMPLETE); + + ahd_platform_freeze_devq(ahd, scb); +} + +void +ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb) +{ + struct scb *prev_scb; + ahd_mode_state saved_modes; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + prev_scb = NULL; + if (ahd_qinfifo_count(ahd) != 0) { + u_int prev_tag; + u_int prev_pos; + + prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1); + prev_tag = ahd->qinfifo[prev_pos]; + prev_scb = ahd_lookup_scb(ahd, prev_tag); + } + ahd_qinfifo_requeue(ahd, prev_scb, scb); + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); + ahd_restore_modes(ahd, saved_modes); +} + +static void +ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb, + struct scb *scb) +{ + if (prev_scb == NULL) { + uint32_t busaddr; + + busaddr = ahd_le32toh(scb->hscb->hscb_busaddr); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); + } else { + prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; + ahd_sync_scb(ahd, prev_scb, + BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + } + ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); + ahd->qinfifonext++; + scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr; + ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); +} + +static int +ahd_qinfifo_count(struct ahd_softc *ahd) +{ + u_int qinpos; + u_int wrap_qinpos; + u_int wrap_qinfifonext; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + qinpos = ahd_get_snscb_qoff(ahd); + wrap_qinpos = AHD_QIN_WRAP(qinpos); + wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext); + if (wrap_qinfifonext >= wrap_qinpos) + return (wrap_qinfifonext - wrap_qinpos); + else + return (wrap_qinfifonext + + NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos); +} + +void +ahd_reset_cmds_pending(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int pending_cmds; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + + /* + * Don't count any commands as outstanding that the + * sequencer has already marked for completion. + */ + ahd_flush_qoutfifo(ahd); + + pending_cmds = 0; + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + pending_cmds++; + } + ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd)); + ahd_restore_modes(ahd, saved_modes); + ahd->flags &= ~AHD_UPDATE_PEND_CMDS; +} + +int +ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status, + ahd_search_action action) +{ + struct scb *scb; + struct scb *prev_scb; + ahd_mode_state saved_modes; + u_int qinstart; + u_int qinpos; + u_int qintail; + u_int tid_next; + u_int tid_prev; + u_int scbid; + u_int savedscbptr; + uint32_t busaddr; + int found; + int targets; + + /* Must be in CCHAN mode */ + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + + /* + * Halt any pending SCB DMA. The sequencer will reinitiate + * this dma if the qinfifo is not empty once we unpause. + */ + if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR)) + == (CCARREN|CCSCBEN|CCSCBDIR)) { + ahd_outb(ahd, CCSCBCTL, + ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN)); + while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) + ; + } + /* Determine sequencer's position in the qinfifo. */ + qintail = AHD_QIN_WRAP(ahd->qinfifonext); + qinstart = ahd_get_snscb_qoff(ahd); + qinpos = AHD_QIN_WRAP(qinstart); + found = 0; + prev_scb = NULL; + + if (action == SEARCH_PRINT) { + printf("qinstart = %d qinfifonext = %d\nQINFIFO:", + qinstart, ahd->qinfifonext); + } + + /* + * Start with an empty queue. Entries that are not chosen + * for removal will be re-added to the queue as we go. + */ + ahd->qinfifonext = qinstart; + busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); + ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); + + while (qinpos != qintail) { + scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]); + if (scb == NULL) { + printf("qinpos = %d, SCB index = %d\n", + qinpos, ahd->qinfifo[qinpos]); + panic("Loop 1\n"); + } + + if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) { + /* + * We found an scb that needs to be acted on. + */ + found++; + switch (action) { + case SEARCH_COMPLETE: + { + cam_status ostat; + cam_status cstat; + + ostat = ahd_get_transaction_status(scb); + if (ostat == CAM_REQ_INPROG) + ahd_set_transaction_status(scb, + status); + cstat = ahd_get_transaction_status(scb); + if (cstat != CAM_REQ_CMP) + ahd_freeze_scb(scb); + if ((scb->flags & SCB_ACTIVE) == 0) + printf("Inactive SCB in qinfifo\n"); + ahd_done(ahd, scb); + + /* FALLTHROUGH */ + } + case SEARCH_REMOVE: + break; + case SEARCH_PRINT: + printf(" 0x%x", ahd->qinfifo[qinpos]); + /* FALLTHROUGH */ + case SEARCH_COUNT: + ahd_qinfifo_requeue(ahd, prev_scb, scb); + prev_scb = scb; + break; + } + } else { + ahd_qinfifo_requeue(ahd, prev_scb, scb); + prev_scb = scb; + } + qinpos = AHD_QIN_WRAP(qinpos+1); + } + + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); + + if (action == SEARCH_PRINT) + printf("\nWAITING_TID_QUEUES:\n"); + + /* + * Search waiting for selection lists. We traverse the + * list of "their ids" waiting for selection and, if + * appropriate, traverse the SCBs of each "their id" + * looking for matches. + */ + savedscbptr = ahd_get_scbptr(ahd); + tid_next = ahd_inw(ahd, WAITING_TID_HEAD); + tid_prev = SCB_LIST_NULL; + targets = 0; + for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) { + u_int tid_head; + + /* + * We limit based on the number of SCBs since + * MK_MESSAGE SCBs are not in the per-tid lists. + */ + targets++; + if (targets > AHD_SCB_MAX) { + panic("TID LIST LOOP"); + } + if (scbid >= ahd->scb_data.numscbs) { + printf("%s: Waiting TID List inconsistency. " + "SCB index == 0x%x, yet numscbs == 0x%x.", + ahd_name(ahd), scbid, ahd->scb_data.numscbs); + ahd_dump_card_state(ahd); + panic("for safety"); + } + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: SCB = 0x%x Not Active!\n", + ahd_name(ahd), scbid); + panic("Waiting TID List traversal\n"); + } + ahd_set_scbptr(ahd, scbid); + tid_next = ahd_inw_scbram(ahd, SCB_NEXT2); + if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD, + SCB_LIST_NULL, ROLE_UNKNOWN) == 0) { + tid_prev = scbid; + continue; + } + + /* + * We found a list of scbs that needs to be searched. + */ + if (action == SEARCH_PRINT) + printf(" %d ( ", SCB_GET_TARGET(ahd, scb)); + tid_head = scbid; + found += ahd_search_scb_list(ahd, target, channel, + lun, tag, role, status, + action, &tid_head, + SCB_GET_TARGET(ahd, scb)); + if (tid_head != scbid) + ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next); + if (!SCBID_IS_NULL(tid_head)) + tid_prev = tid_head; + if (action == SEARCH_PRINT) + printf(")\n"); + } + ahd_set_scbptr(ahd, savedscbptr); + ahd_restore_modes(ahd, saved_modes); + return (found); +} + +static int +ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status, + ahd_search_action action, u_int *list_head, u_int tid) +{ + struct scb *scb; + u_int scbid; + u_int next; + u_int prev; + int found; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + found = 0; + prev = SCB_LIST_NULL; + next = *list_head; + for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) { + if (scbid >= ahd->scb_data.numscbs) { + printf("%s:SCB List inconsistency. " + "SCB == 0x%x, yet numscbs == 0x%x.", + ahd_name(ahd), scbid, ahd->scb_data.numscbs); + ahd_dump_card_state(ahd); + panic("for safety"); + } + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: SCB = %d Not Active!\n", + ahd_name(ahd), scbid); + panic("Waiting List traversal\n"); + } + ahd_set_scbptr(ahd, scbid); + next = ahd_inw_scbram(ahd, SCB_NEXT); + if (ahd_match_scb(ahd, scb, target, channel, + lun, SCB_LIST_NULL, role) == 0) { + prev = scbid; + continue; + } + found++; + switch (action) { + case SEARCH_COMPLETE: + { + cam_status ostat; + cam_status cstat; + + ostat = ahd_get_transaction_status(scb); + if (ostat == CAM_REQ_INPROG) + ahd_set_transaction_status(scb, status); + cstat = ahd_get_transaction_status(scb); + if (cstat != CAM_REQ_CMP) + ahd_freeze_scb(scb); + if ((scb->flags & SCB_ACTIVE) == 0) + printf("Inactive SCB in Waiting List\n"); + ahd_done(ahd, scb); + /* FALLTHROUGH */ + } + case SEARCH_REMOVE: + ahd_rem_wscb(ahd, scbid, prev, next, tid); + if (prev == SCB_LIST_NULL) + *list_head = next; + break; + case SEARCH_PRINT: + printf("0x%x ", scbid); + case SEARCH_COUNT: + prev = scbid; + break; + } + if (found > AHD_SCB_MAX) + panic("SCB LIST LOOP"); + } + if (action == SEARCH_COMPLETE + || action == SEARCH_REMOVE) + ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found); + return (found); +} + +static void +ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev, + u_int tid_cur, u_int tid_next) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + + if (SCBID_IS_NULL(tid_cur)) { + + /* Bypass current TID list */ + if (SCBID_IS_NULL(tid_prev)) { + ahd_outw(ahd, WAITING_TID_HEAD, tid_next); + } else { + ahd_set_scbptr(ahd, tid_prev); + ahd_outw(ahd, SCB_NEXT2, tid_next); + } + if (SCBID_IS_NULL(tid_next)) + ahd_outw(ahd, WAITING_TID_TAIL, tid_prev); + } else { + + /* Stitch through tid_cur */ + if (SCBID_IS_NULL(tid_prev)) { + ahd_outw(ahd, WAITING_TID_HEAD, tid_cur); + } else { + ahd_set_scbptr(ahd, tid_prev); + ahd_outw(ahd, SCB_NEXT2, tid_cur); + } + ahd_set_scbptr(ahd, tid_cur); + ahd_outw(ahd, SCB_NEXT2, tid_next); + + if (SCBID_IS_NULL(tid_next)) + ahd_outw(ahd, WAITING_TID_TAIL, tid_cur); + } +} + +/* + * Manipulate the waiting for selection list and return the + * scb that follows the one that we remove. + */ +static u_int +ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, + u_int prev, u_int next, u_int tid) +{ + u_int tail_offset; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + if (!SCBID_IS_NULL(prev)) { + ahd_set_scbptr(ahd, prev); + ahd_outw(ahd, SCB_NEXT, next); + } + + /* + * SCBs that had MK_MESSAGE set in them will not + * be queued to the per-target lists, so don't + * blindly clear the tail pointer. + */ + tail_offset = WAITING_SCB_TAILS + (2 * tid); + if (SCBID_IS_NULL(next) + && ahd_inw(ahd, tail_offset) == scbid) + ahd_outw(ahd, tail_offset, prev); + ahd_add_scb_to_free_list(ahd, scbid); + return (next); +} + +/* + * Add the SCB as selected by SCBPTR onto the on chip list of + * free hardware SCBs. This list is empty/unused if we are not + * performing SCB paging. + */ +static void +ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid) +{ +/* XXX Need some other mechanism to designate "free". */ + /* + * Invalidate the tag so that our abort + * routines don't think it's active. + ahd_outb(ahd, SCB_TAG, SCB_LIST_NULL); + */ +} + +/******************************** Error Handling ******************************/ +/* + * Abort all SCBs that match the given description (target/channel/lun/tag), + * setting their status to the passed in status if the status has not already + * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer + * is paused before it is called. + */ +int +ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status) +{ + struct scb *scbp; + struct scb *scbp_next; + u_int i, j; + u_int maxtarget; + u_int minlun; + u_int maxlun; + int found; + ahd_mode_state saved_modes; + + /* restore this when we're done */ + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL, + role, CAM_REQUEUE_REQ, SEARCH_COMPLETE); + + /* + * Clean out the busy target table for any untagged commands. + */ + i = 0; + maxtarget = 16; + if (target != CAM_TARGET_WILDCARD) { + i = target; + if (channel == 'B') + i += 8; + maxtarget = i + 1; + } + + if (lun == CAM_LUN_WILDCARD) { + minlun = 0; + maxlun = AHD_NUM_LUNS_NONPKT; + } else if (lun >= AHD_NUM_LUNS_NONPKT) { + minlun = maxlun = 0; + } else { + minlun = lun; + maxlun = lun + 1; + } + + if (role != ROLE_TARGET) { + for (;i < maxtarget; i++) { + for (j = minlun;j < maxlun; j++) { + u_int scbid; + u_int tcl; + + tcl = BUILD_TCL_RAW(i, 'A', j); + scbid = ahd_find_busy_tcl(ahd, tcl); + scbp = ahd_lookup_scb(ahd, scbid); + if (scbp == NULL + || ahd_match_scb(ahd, scbp, target, channel, + lun, tag, role) == 0) + continue; + ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j)); + } + } + } + + /* + * Don't abort commands that have already completed, + * but haven't quite made it up to the host yet. + */ + ahd_flush_qoutfifo(ahd); + + /* + * Go through the pending CCB list and look for + * commands for this target that are still active. + * These are other tagged commands that were + * disconnected when the reset occurred. + */ + scbp_next = LIST_FIRST(&ahd->pending_scbs); + while (scbp_next != NULL) { + scbp = scbp_next; + scbp_next = LIST_NEXT(scbp, pending_links); + if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) { + cam_status ostat; + + ostat = ahd_get_transaction_status(scbp); + if (ostat == CAM_REQ_INPROG) + ahd_set_transaction_status(scbp, status); + if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP) + ahd_freeze_scb(scbp); + if ((scbp->flags & SCB_ACTIVE) == 0) + printf("Inactive SCB on pending list\n"); + ahd_done(ahd, scbp); + found++; + } + } + ahd_restore_modes(ahd, saved_modes); + ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status); + ahd->flags |= AHD_UPDATE_PEND_CMDS; + return found; +} + +static void +ahd_reset_current_bus(struct ahd_softc *ahd) +{ + uint8_t scsiseq; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST); + scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO); + ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO); + ahd_delay(AHD_BUSRESET_DELAY); + /* Turn off the bus reset */ + ahd_outb(ahd, SCSISEQ0, scsiseq); + if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) { + /* + * 2A Razor #474 + * Certain chip state is not cleared for + * SCSI bus resets that we initiate, so + * we must reset the chip. + */ + ahd_delay(AHD_BUSRESET_DELAY); + ahd_reset(ahd, /*reinit*/TRUE); + ahd_intr_enable(ahd, /*enable*/TRUE); + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + } + + ahd_clear_intstat(ahd); +} + +int +ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) +{ + struct ahd_devinfo devinfo; + u_int initiator; + u_int target; + u_int max_scsiid; + int found; + u_int fifo; + u_int next_fifo; + + ahd->pending_device = NULL; + + ahd_compile_devinfo(&devinfo, + CAM_TARGET_WILDCARD, + CAM_TARGET_WILDCARD, + CAM_LUN_WILDCARD, + channel, ROLE_UNKNOWN); + ahd_pause(ahd); + + /* Make sure the sequencer is in a safe location. */ + ahd_clear_critical_section(ahd); + +#if AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0) { + ahd_run_tqinfifo(ahd, /*paused*/TRUE); + } +#endif + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + /* + * Disable selections so no automatic hardware + * functions will modify chip state. + */ + ahd_outb(ahd, SCSISEQ0, 0); + ahd_outb(ahd, SCSISEQ1, 0); + + /* + * Safely shut down our DMA engines. Always start with + * the FIFO that is not currently active (if any are + * actively connected). + */ + next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO; + if (next_fifo > CURRFIFO_1) + /* If disconneced, arbitrarily start with FIFO1. */ + next_fifo = fifo = 0; + do { + next_fifo ^= CURRFIFO_1; + ahd_set_modes(ahd, next_fifo, next_fifo); + ahd_outb(ahd, DFCNTRL, + ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN)); + while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0) + ahd_delay(10); + /* + * Set CURRFIFO to the now inactive channel. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, DFFSTAT, next_fifo); + } while (next_fifo != fifo); + + /* + * Reset the bus if we are initiating this reset + */ + ahd_clear_msg_state(ahd); + ahd_outb(ahd, SIMODE1, + ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE)); + + if (initiate_reset) + ahd_reset_current_bus(ahd); + + ahd_clear_intstat(ahd); + + /* + * Clean up all the state information for the + * pending transactions on this bus. + */ + found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_UNKNOWN, CAM_SCSI_BUS_RESET); + + /* + * Cleanup anything left in the FIFOs. + */ + ahd_clear_fifo(ahd, 0); + ahd_clear_fifo(ahd, 1); + + /* + * Revert to async/narrow transfers until we renegotiate. + */ + max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; + for (target = 0; target <= max_scsiid; target++) { + + if (ahd->enabled_targets[target] == NULL) + continue; + for (initiator = 0; initiator <= max_scsiid; initiator++) { + struct ahd_devinfo devinfo; + + ahd_compile_devinfo(&devinfo, target, initiator, + CAM_LUN_WILDCARD, + 'A', ROLE_UNKNOWN); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_CUR, /*paused*/TRUE); + } + } + +#ifdef AHD_TARGET_MODE + max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; + + /* + * Send an immediate notify ccb to all target more peripheral + * drivers affected by this action. + */ + for (target = 0; target <= max_scsiid; target++) { + struct ahd_tmode_tstate* tstate; + u_int lun; + + tstate = ahd->enabled_targets[target]; + if (tstate == NULL) + continue; + for (lun = 0; lun < AHD_NUM_LUNS; lun++) { + struct ahd_tmode_lstate* lstate; + + lstate = tstate->enabled_luns[lun]; + if (lstate == NULL) + continue; + + ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD, + EVENT_TYPE_BUS_RESET, /*arg*/0); + ahd_send_lstate_events(ahd, lstate); + } + } +#endif + /* Notify the XPT that a bus reset occurred */ + ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, + CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); + ahd_restart(ahd); + /* + * Freeze the SIMQ until our poller can determine that + * the bus reset has really gone away. We set the initial + * timer to 0 to have the check performed as soon as possible + * from the timer context. + */ + if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) { + ahd->flags |= AHD_RESET_POLL_ACTIVE; + ahd_freeze_simq(ahd); + ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd); + } + return (found); +} + + +#define AHD_RESET_POLL_US 1000 +static void +ahd_reset_poll(void *arg) +{ + struct ahd_softc *ahd; + u_int scsiseq1; + u_long l; + u_long s; + + ahd_list_lock(&l); + ahd = ahd_find_softc((struct ahd_softc *)arg); + if (ahd == NULL) { + printf("ahd_reset_poll: Instance %p no longer exists\n", arg); + ahd_list_unlock(&l); + return; + } + ahd_lock(ahd, &s); + ahd_pause(ahd); + ahd_update_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); + if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) { + ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US, + ahd_reset_poll, ahd); + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + ahd_list_unlock(&l); + return; + } + + /* Reset is now low. Complete chip reinitialization. */ + ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); + scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); + ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP)); + ahd_unpause(ahd); + ahd->flags &= ~AHD_RESET_POLL_ACTIVE; + ahd_unlock(ahd, &s); + ahd_release_simq(ahd); + ahd_list_unlock(&l); +} + +/**************************** Statistics Processing ***************************/ +static void +ahd_stat_timer(void *arg) +{ + struct ahd_softc *ahd; + u_long l; + u_long s; + int enint_coal; + + ahd_list_lock(&l); + ahd = ahd_find_softc((struct ahd_softc *)arg); + if (ahd == NULL) { + printf("ahd_stat_timer: Instance %p no longer exists\n", arg); + ahd_list_unlock(&l); + return; + } + ahd_lock(ahd, &s); + + enint_coal = ahd->hs_mailbox & ENINT_COALESCE; + if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold) + enint_coal |= ENINT_COALESCE; + else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold) + enint_coal &= ~ENINT_COALESCE; + + if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) { + ahd_enable_coalescing(ahd, enint_coal); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0) + printf("%s: Interrupt coalescing " + "now %sabled. Cmds %d\n", + ahd_name(ahd), + (enint_coal & ENINT_COALESCE) ? "en" : "dis", + ahd->cmdcmplt_total); +#endif + } + + ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1); + ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]; + ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0; + ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, + ahd_stat_timer, ahd); + ahd_unlock(ahd, &s); + ahd_list_unlock(&l); +} + +/****************************** Status Processing *****************************/ +void +ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) +{ + if (scb->hscb->shared_data.istatus.scsi_status != 0) { + ahd_handle_scsi_status(ahd, scb); + } else { + ahd_calc_residual(ahd, scb); + ahd_done(ahd, scb); + } +} + +void +ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) +{ + struct hardware_scb *hscb; + u_int qfreeze_cnt; + + /* + * The sequencer freezes its select-out queue + * anytime a SCSI status error occurs. We must + * handle the error and decrement the QFREEZE count + * to allow the sequencer to continue. + */ + hscb = scb->hscb; + + /* Freeze the queue until the client sees the error. */ + ahd_freeze_devq(ahd, scb); + ahd_freeze_scb(scb); + qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT); + if (qfreeze_cnt == 0) { + printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd)); + } else { + qfreeze_cnt--; + ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt); + } + if (qfreeze_cnt == 0) + ahd_outb(ahd, SEQ_FLAGS2, + ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN); + + /* Don't want to clobber the original sense code */ + if ((scb->flags & SCB_SENSE) != 0) { + /* + * Clear the SCB_SENSE Flag and perform + * a normal command completion. + */ + scb->flags &= ~SCB_SENSE; + ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); + ahd_done(ahd, scb); + return; + } + ahd_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR); + ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status); + switch (hscb->shared_data.istatus.scsi_status) { + case STATUS_PKT_SENSE: + { + struct scsi_status_iu_header *siu; + + ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD); + siu = (struct scsi_status_iu_header *)scb->sense_data; + ahd_set_scsi_status(scb, siu->status); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SENSE) != 0) { + ahd_print_path(ahd, scb); + printf("SCB 0x%x Received PKT Status of 0x%x\n", + SCB_GET_TAG(scb), siu->status); + printf("\tflags = 0x%x, sense len = 0x%x, " + "pktfail = 0x%x\n", + siu->flags, scsi_4btoul(siu->sense_length), + scsi_4btoul(siu->pkt_failures_length)); + } +#endif + if ((siu->flags & SIU_RSPVALID) != 0) { + ahd_print_path(ahd, scb); + if (scsi_4btoul(siu->pkt_failures_length) < 4) { + printf("Unable to parse pkt_failures\n"); + } else { + + switch (SIU_PKTFAIL_CODE(siu)) { + case SIU_PFC_NONE: + printf("No packet failure found\n"); + break; + case SIU_PFC_CIU_FIELDS_INVALID: + printf("Invalid Command IU Field\n"); + break; + case SIU_PFC_TMF_NOT_SUPPORTED: + printf("TMF not supportd\n"); + break; + case SIU_PFC_TMF_FAILED: + printf("TMF failed\n"); + break; + case SIU_PFC_INVALID_TYPE_CODE: + printf("Invalid L_Q Type code\n"); + break; + case SIU_PFC_ILLEGAL_REQUEST: + printf("Illegal request\n"); + default: + break; + } + } + if (siu->status == SCSI_STATUS_OK) + ahd_set_transaction_status(scb, + CAM_REQ_CMP_ERR); + } + if ((siu->flags & SIU_SNSVALID) != 0) { + scb->flags |= SCB_PKT_SENSE; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SENSE) != 0) + printf("Sense data available\n"); +#endif + } + ahd_done(ahd, scb); + break; + } + case SCSI_STATUS_CMD_TERMINATED: + case SCSI_STATUS_CHECK_COND: + { + struct ahd_devinfo devinfo; + struct ahd_dma_seg *sg; + struct scsi_sense *sc; + struct ahd_initiator_tinfo *targ_info; + struct ahd_tmode_tstate *tstate; + struct ahd_transinfo *tinfo; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_SENSE) { + ahd_print_path(ahd, scb); + printf("SCB %d: requests Check Status\n", + SCB_GET_TAG(scb)); + } +#endif + + if (ahd_perform_autosense(scb) == 0) + break; + + ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb), + SCB_GET_TARGET(ahd, scb), + SCB_GET_LUN(scb), + SCB_GET_CHANNEL(ahd, scb), + ROLE_INITIATOR); + targ_info = ahd_fetch_transinfo(ahd, + devinfo.channel, + devinfo.our_scsiid, + devinfo.target, + &tstate); + tinfo = &targ_info->curr; + sg = scb->sg_list; + sc = (struct scsi_sense *)hscb->shared_data.idata.cdb; + /* + * Save off the residual if there is one. + */ + ahd_update_residual(ahd, scb); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_SENSE) { + ahd_print_path(ahd, scb); + printf("Sending Sense\n"); + } +#endif + scb->sg_count = 0; + sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb), + ahd_get_sense_bufsize(ahd, scb), + /*last*/TRUE); + sc->opcode = REQUEST_SENSE; + sc->byte2 = 0; + if (tinfo->protocol_version <= SCSI_REV_2 + && SCB_GET_LUN(scb) < 8) + sc->byte2 = SCB_GET_LUN(scb) << 5; + sc->unused[0] = 0; + sc->unused[1] = 0; + sc->length = ahd_get_sense_bufsize(ahd, scb); + sc->control = 0; + + /* + * We can't allow the target to disconnect. + * This will be an untagged transaction and + * having the target disconnect will make this + * transaction indestinguishable from outstanding + * tagged transactions. + */ + hscb->control = 0; + + /* + * This request sense could be because the + * the device lost power or in some other + * way has lost our transfer negotiations. + * Renegotiate if appropriate. Unit attention + * errors will be reported before any data + * phases occur. + */ + if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) { + ahd_update_neg_request(ahd, &devinfo, + tstate, targ_info, + AHD_NEG_IF_NON_ASYNC); + } + if (tstate->auto_negotiate & devinfo.target_mask) { + hscb->control |= MK_MESSAGE; + scb->flags &= + ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET); + scb->flags |= SCB_AUTO_NEGOTIATE; + } + hscb->cdb_len = sizeof(*sc); + ahd_setup_data_scb(ahd, scb); + scb->flags |= SCB_SENSE; + ahd_queue_scb(ahd, scb); + /* + * Ensure we have enough time to actually + * retrieve the sense. + */ + ahd_scb_timer_reset(scb, 5 * 1000000); + break; + } + case SCSI_STATUS_OK: + printf("%s: Interrupted for staus of 0???\n", + ahd_name(ahd)); + /* FALLTHROUGH */ + default: + ahd_done(ahd, scb); + break; + } +} + +/* + * Calculate the residual for a just completed SCB. + */ +void +ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb) +{ + struct hardware_scb *hscb; + struct initiator_status *spkt; + uint32_t sgptr; + uint32_t resid_sgptr; + uint32_t resid; + + /* + * 5 cases. + * 1) No residual. + * SG_STATUS_VALID clear in sgptr. + * 2) Transferless command + * 3) Never performed any transfers. + * sgptr has SG_FULL_RESID set. + * 4) No residual but target did not + * save data pointers after the + * last transfer, so sgptr was + * never updated. + * 5) We have a partial residual. + * Use residual_sgptr to determine + * where we are. + */ + + hscb = scb->hscb; + sgptr = ahd_le32toh(hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) == 0) + /* Case 1 */ + return; + sgptr &= ~SG_STATUS_VALID; + + if ((sgptr & SG_LIST_NULL) != 0) + /* Case 2 */ + return; + + /* + * Residual fields are the same in both + * target and initiator status packets, + * so we can always use the initiator fields + * regardless of the role for this SCB. + */ + spkt = &hscb->shared_data.istatus; + resid_sgptr = ahd_le32toh(spkt->residual_sgptr); + if ((sgptr & SG_FULL_RESID) != 0) { + /* Case 3 */ + resid = ahd_get_transfer_length(scb); + } else if ((resid_sgptr & SG_LIST_NULL) != 0) { + /* Case 4 */ + return; + } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) { + ahd_print_path(ahd, scb); + printf("data overrun detected Tag == 0x%x.\n", + SCB_GET_TAG(scb)); + ahd_freeze_devq(ahd, scb); + ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); + ahd_freeze_scb(scb); + return; + } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) { + panic("Bogus resid sgptr value 0x%x\n", resid_sgptr); + /* NOTREACHED */ + } else { + struct ahd_dma_seg *sg; + + /* + * Remainder of the SG where the transfer + * stopped. + */ + resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK; + sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK); + + /* The residual sg_ptr always points to the next sg */ + sg--; + + /* + * Add up the contents of all residual + * SG segments that are after the SG where + * the transfer stopped. + */ + while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) { + sg++; + resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK; + } + } + if ((scb->flags & SCB_SENSE) == 0) + ahd_set_residual(scb, resid); + else + ahd_set_sense_residual(scb, resid); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) { + ahd_print_path(ahd, scb); + printf("Handled %sResidual of %d bytes\n", + (scb->flags & SCB_SENSE) ? "Sense " : "", resid); + } +#endif +} + +/******************************* Target Mode **********************************/ +#ifdef AHD_TARGET_MODE +/* + * Add a target mode event to this lun's queue + */ +static void +ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate, + u_int initiator_id, u_int event_type, u_int event_arg) +{ + struct ahd_tmode_event *event; + int pending; + + xpt_freeze_devq(lstate->path, /*count*/1); + if (lstate->event_w_idx >= lstate->event_r_idx) + pending = lstate->event_w_idx - lstate->event_r_idx; + else + pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1 + - (lstate->event_r_idx - lstate->event_w_idx); + + if (event_type == EVENT_TYPE_BUS_RESET + || event_type == MSG_BUS_DEV_RESET) { + /* + * Any earlier events are irrelevant, so reset our buffer. + * This has the effect of allowing us to deal with reset + * floods (an external device holding down the reset line) + * without losing the event that is really interesting. + */ + lstate->event_r_idx = 0; + lstate->event_w_idx = 0; + xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE); + } + + if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) { + xpt_print_path(lstate->path); + printf("immediate event %x:%x lost\n", + lstate->event_buffer[lstate->event_r_idx].event_type, + lstate->event_buffer[lstate->event_r_idx].event_arg); + lstate->event_r_idx++; + if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE) + lstate->event_r_idx = 0; + xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE); + } + + event = &lstate->event_buffer[lstate->event_w_idx]; + event->initiator_id = initiator_id; + event->event_type = event_type; + event->event_arg = event_arg; + lstate->event_w_idx++; + if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE) + lstate->event_w_idx = 0; +} + +/* + * Send any target mode events queued up waiting + * for immediate notify resources. + */ +void +ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate) +{ + struct ccb_hdr *ccbh; + struct ccb_immed_notify *inot; + + while (lstate->event_r_idx != lstate->event_w_idx + && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) { + struct ahd_tmode_event *event; + + event = &lstate->event_buffer[lstate->event_r_idx]; + SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle); + inot = (struct ccb_immed_notify *)ccbh; + switch (event->event_type) { + case EVENT_TYPE_BUS_RESET: + ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN; + break; + default: + ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN; + inot->message_args[0] = event->event_type; + inot->message_args[1] = event->event_arg; + break; + } + inot->initiator_id = event->initiator_id; + inot->sense_len = 0; + xpt_done((union ccb *)inot); + lstate->event_r_idx++; + if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE) + lstate->event_r_idx = 0; + } +} +#endif + +/******************** Sequencer Program Patching/Download *********************/ + +#ifdef AHD_DUMP_SEQ +void +ahd_dumpseq(struct ahd_softc* ahd) +{ + int i; + int max_prog; + + max_prog = 2048; + + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); + ahd_outb(ahd, PRGMCNT, 0); + ahd_outb(ahd, PRGMCNT+1, 0); + for (i = 0; i < max_prog; i++) { + uint8_t ins_bytes[4]; + + ahd_insb(ahd, SEQRAM, ins_bytes, 4); + printf("0x%08x\n", ins_bytes[0] << 24 + | ins_bytes[1] << 16 + | ins_bytes[2] << 8 + | ins_bytes[3]); + } +} +#endif + +static void +ahd_loadseq(struct ahd_softc *ahd) +{ + struct cs cs_table[num_critical_sections]; + u_int begin_set[num_critical_sections]; + u_int end_set[num_critical_sections]; + struct patch *cur_patch; + u_int cs_count; + u_int cur_cs; + u_int i; + int downloaded; + u_int skip_addr; + u_int sg_prefetch_cnt; + u_int sg_prefetch_cnt_limit; + u_int sg_prefetch_align; + u_int sg_size; + uint8_t download_consts[DOWNLOAD_CONST_COUNT]; + + if (bootverbose) + printf("%s: Downloading Sequencer Program...", + ahd_name(ahd)); + +#if DOWNLOAD_CONST_COUNT != 7 +#error "Download Const Mismatch" +#endif + /* + * Start out with 0 critical sections + * that apply to this firmware load. + */ + cs_count = 0; + cur_cs = 0; + memset(begin_set, 0, sizeof(begin_set)); + memset(end_set, 0, sizeof(end_set)); + + /* + * Setup downloadable constant table. + * + * The computation for the S/G prefetch variables is + * a bit complicated. We would like to always fetch + * in terms of cachelined sized increments. However, + * if the cacheline is not an even multiple of the + * SG element size or is larger than our SG RAM, using + * just the cache size might leave us with only a portion + * of an SG element at the tail of a prefetch. If the + * cacheline is larger than our S/G prefetch buffer less + * the size of an SG element, we may round down to a cacheline + * that doesn't contain any or all of the S/G of interest + * within the bounds of our S/G ram. Provide variables to + * the sequencer that will allow it to handle these edge + * cases. + */ + /* Start by aligning to the nearest cacheline. */ + sg_prefetch_align = ahd->pci_cachesize; + if (sg_prefetch_align == 0) + sg_prefetch_align = 8; + /* Round down to the nearest power of 2. */ + while (powerof2(sg_prefetch_align) == 0) + sg_prefetch_align--; + /* + * If the cacheline boundary is greater than half our prefetch RAM + * we risk not being able to fetch even a single complete S/G + * segment if we align to that boundary. + */ + if (sg_prefetch_align > CCSGADDR_MAX/2) + sg_prefetch_align = CCSGADDR_MAX/2; + /* Start by fetching a single cacheline. */ + sg_prefetch_cnt = sg_prefetch_align; + /* + * Increment the prefetch count by cachelines until + * at least one S/G element will fit. + */ + sg_size = sizeof(struct ahd_dma_seg); + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + sg_size = sizeof(struct ahd_dma64_seg); + while (sg_prefetch_cnt < sg_size) + sg_prefetch_cnt += sg_prefetch_align; + /* + * If the cacheline is not an even multiple of + * the S/G size, we may only get a partial S/G when + * we align. Add a cacheline if this is the case. + */ + if ((sg_prefetch_align % sg_size) != 0 + && (sg_prefetch_cnt < CCSGADDR_MAX)) + sg_prefetch_cnt += sg_prefetch_align; + /* + * Lastly, compute a value that the sequencer can use + * to determine if the remainder of the CCSGRAM buffer + * has a full S/G element in it. + */ + sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1); + download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt; + download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit; + download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1); + download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1); + download_consts[SG_SIZEOF] = sg_size; + download_consts[PKT_OVERRUN_BUFOFFSET] = + (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256; + download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN; + cur_patch = patches; + downloaded = 0; + skip_addr = 0; + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); + ahd_outb(ahd, PRGMCNT, 0); + ahd_outb(ahd, PRGMCNT+1, 0); + + for (i = 0; i < sizeof(seqprog)/4; i++) { + if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) { + /* + * Don't download this instruction as it + * is in a patch that was removed. + */ + continue; + } + /* + * Move through the CS table until we find a CS + * that might apply to this instruction. + */ + for (; cur_cs < num_critical_sections; cur_cs++) { + if (critical_sections[cur_cs].end <= i) { + if (begin_set[cs_count] == TRUE + && end_set[cs_count] == FALSE) { + cs_table[cs_count].end = downloaded; + end_set[cs_count] = TRUE; + cs_count++; + } + continue; + } + if (critical_sections[cur_cs].begin <= i + && begin_set[cs_count] == FALSE) { + cs_table[cs_count].begin = downloaded; + begin_set[cs_count] = TRUE; + } + break; + } + ahd_download_instr(ahd, i, download_consts); + downloaded++; + } + + ahd->num_critical_sections = cs_count; + if (cs_count != 0) { + + cs_count *= sizeof(struct cs); + ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT); + if (ahd->critical_sections == NULL) + panic("ahd_loadseq: Could not malloc"); + memcpy(ahd->critical_sections, cs_table, cs_count); + } + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE); + + if (bootverbose) { + printf(" %d instructions downloaded\n", downloaded); + printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n", + ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags); + } +} + +static int +ahd_check_patch(struct ahd_softc *ahd, struct patch **start_patch, + u_int start_instr, u_int *skip_addr) +{ + struct patch *cur_patch; + struct patch *last_patch; + u_int num_patches; + + num_patches = sizeof(patches)/sizeof(struct patch); + last_patch = &patches[num_patches]; + cur_patch = *start_patch; + + while (cur_patch < last_patch && start_instr == cur_patch->begin) { + + if (cur_patch->patch_func(ahd) == 0) { + + /* Start rejecting code */ + *skip_addr = start_instr + cur_patch->skip_instr; + cur_patch += cur_patch->skip_patch; + } else { + /* Accepted this patch. Advance to the next + * one and wait for our intruction pointer to + * hit this point. + */ + cur_patch++; + } + } + + *start_patch = cur_patch; + if (start_instr < *skip_addr) + /* Still skipping */ + return (0); + + return (1); +} + +static u_int +ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address) +{ + struct patch *cur_patch; + int address_offset; + u_int skip_addr; + u_int i; + + address_offset = 0; + cur_patch = patches; + skip_addr = 0; + + for (i = 0; i < address;) { + + ahd_check_patch(ahd, &cur_patch, i, &skip_addr); + + if (skip_addr > i) { + int end_addr; + + end_addr = MIN(address, skip_addr); + address_offset += end_addr - i; + i = skip_addr; + } else { + i++; + } + } + return (address - address_offset); +} + +static void +ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts) +{ + union ins_formats instr; + struct ins_format1 *fmt1_ins; + struct ins_format3 *fmt3_ins; + u_int opcode; + + /* + * The firmware is always compiled into a little endian format. + */ + instr.integer = ahd_le32toh(*(uint32_t*)&seqprog[instrptr * 4]); + + fmt1_ins = &instr.format1; + fmt3_ins = NULL; + + /* Pull the opcode */ + opcode = instr.format1.opcode; + switch (opcode) { + case AIC_OP_JMP: + case AIC_OP_JC: + case AIC_OP_JNC: + case AIC_OP_CALL: + case AIC_OP_JNE: + case AIC_OP_JNZ: + case AIC_OP_JE: + case AIC_OP_JZ: + { + fmt3_ins = &instr.format3; + fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address); + /* FALLTHROUGH */ + } + case AIC_OP_OR: + case AIC_OP_AND: + case AIC_OP_XOR: + case AIC_OP_ADD: + case AIC_OP_ADC: + case AIC_OP_BMOV: + if (fmt1_ins->parity != 0) { + fmt1_ins->immediate = dconsts[fmt1_ins->immediate]; + } + fmt1_ins->parity = 0; + /* FALLTHROUGH */ + case AIC_OP_ROL: + { + int i, count; + + /* Calculate odd parity for the instruction */ + for (i = 0, count = 0; i < 31; i++) { + uint32_t mask; + + mask = 0x01 << i; + if ((instr.integer & mask) != 0) + count++; + } + if ((count & 0x01) == 0) + instr.format1.parity = 1; + + /* The sequencer is a little endian cpu */ + instr.integer = ahd_htole32(instr.integer); + ahd_outsb(ahd, SEQRAM, instr.bytes, 4); + break; + } + default: + panic("Unknown opcode encountered in seq program"); + break; + } +} + +static int +ahd_probe_stack_size(struct ahd_softc *ahd) +{ + int last_probe; + + last_probe = 0; + while (1) { + int i; + + /* + * We avoid using 0 as a pattern to avoid + * confusion if the stack implementation + * "back-fills" with zeros when "poping' + * entries. + */ + for (i = 1; i <= last_probe+1; i++) { + ahd_outb(ahd, STACK, i & 0xFF); + ahd_outb(ahd, STACK, (i >> 8) & 0xFF); + } + + /* Verify */ + for (i = last_probe+1; i > 0; i--) { + u_int stack_entry; + + stack_entry = ahd_inb(ahd, STACK) + |(ahd_inb(ahd, STACK) << 8); + if (stack_entry != i) + goto sized; + } + last_probe++; + } +sized: + return (last_probe); +} + +void +ahd_dump_all_cards_state(void) +{ + struct ahd_softc *list_ahd; + + TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { + ahd_dump_card_state(list_ahd); + } +} + +int +ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries, + const char *name, u_int address, u_int value, + u_int *cur_column, u_int wrap_point) +{ + int printed; + u_int printed_mask; + + if (cur_column != NULL && *cur_column >= wrap_point) { + printf("\n"); + *cur_column = 0; + } + printed = printf("%s[0x%x]", name, value); + if (table == NULL) { + printed += printf(" "); + *cur_column += printed; + return (printed); + } + printed_mask = 0; + while (printed_mask != 0xFF) { + int entry; + + for (entry = 0; entry < num_entries; entry++) { + if (((value & table[entry].mask) + != table[entry].value) + || ((printed_mask & table[entry].mask) + == table[entry].mask)) + continue; + + printed += printf("%s%s", + printed_mask == 0 ? ":(" : "|", + table[entry].name); + printed_mask |= table[entry].mask; + + break; + } + if (entry >= num_entries) + break; + } + if (printed_mask != 0) + printed += printf(") "); + else + printed += printf(" "); + if (cur_column != NULL) + *cur_column += printed; + return (printed); +} + +void +ahd_dump_card_state(struct ahd_softc *ahd) +{ + struct scb *scb; + ahd_mode_state saved_modes; + u_int dffstat; + int paused; + u_int scb_index; + u_int saved_scb_index; + u_int cur_col; + int i; + + if (ahd_is_paused(ahd)) { + paused = 1; + } else { + paused = 0; + ahd_pause(ahd); + } + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" + "%s: Dumping Card State at program address 0x%x Mode 0x%x\n", + ahd_name(ahd), + ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8), + ahd_build_mode_state(ahd, ahd->saved_src_mode, + ahd->saved_dst_mode)); + if (paused) + printf("Card was paused\n"); + /* + * Mode independent registers. + */ + cur_col = 0; + ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50); + ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50); + ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50); + ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50); + ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50); + ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50); + ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50); + ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50); + ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50); + ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50); + ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50); + ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50); + ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50); + ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50); + ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50); + ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50); + ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50); + ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50); + ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50); + ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50); + ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50); + ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50); + ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50); + ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50); + ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50); + ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50); + ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50); + printf("\n"); + printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x " + "CURRSCB 0x%x NEXTSCB 0x%x\n", + ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING), + ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB), + ahd_inw(ahd, NEXTSCB)); + cur_col = 0; + /* QINFIFO */ + ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_UNKNOWN, /*status*/0, SEARCH_PRINT); + saved_scb_index = ahd_get_scbptr(ahd); + printf("Pending list:"); + i = 0; + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + if (i++ > AHD_SCB_MAX) + break; + cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb), + ahd_inb(ahd, SCB_FIFO_USE_COUNT)); + ahd_set_scbptr(ahd, SCB_GET_TAG(scb)); + ahd_scb_control_print(ahd_inb(ahd, SCB_CONTROL), &cur_col, 60); + ahd_scb_scsiid_print(ahd_inb(ahd, SCB_SCSIID), &cur_col, 60); + } + printf("\nTotal %d\n", i); + + printf("Kernel Free SCB list: "); + i = 0; + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { + struct scb *list_scb; + + list_scb = scb; + do { + printf("%d ", SCB_GET_TAG(list_scb)); + list_scb = LIST_NEXT(list_scb, collision_links); + } while (list_scb && i++ < AHD_SCB_MAX); + } + + LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { + if (i++ > AHD_SCB_MAX) + break; + printf("%d ", SCB_GET_TAG(scb)); + } + printf("\n"); + + printf("Sequencer Complete DMA-inprog list: "); + scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD); + i = 0; + while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { + ahd_set_scbptr(ahd, scb_index); + printf("%d ", scb_index); + scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); + } + printf("\n"); + + printf("Sequencer Complete list: "); + scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD); + i = 0; + while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { + ahd_set_scbptr(ahd, scb_index); + printf("%d ", scb_index); + scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); + } + printf("\n"); + + + printf("Sequencer DMA-Up and Complete list: "); + scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); + i = 0; + while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { + ahd_set_scbptr(ahd, scb_index); + printf("%d ", scb_index); + scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE); + } + printf("\n"); + ahd_set_scbptr(ahd, saved_scb_index); + dffstat = ahd_inb(ahd, DFFSTAT); + for (i = 0; i < 2; i++) { +#ifdef AHD_DEBUG + struct scb *fifo_scb; +#endif + u_int fifo_scbptr; + + ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); + fifo_scbptr = ahd_get_scbptr(ahd); + printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n", + ahd_name(ahd), i, + (dffstat & (FIFO0FREE << i)) ? "Free" : "Active", + ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr); + cur_col = 0; + ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50); + ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50); + ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50); + ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50); + ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW), + &cur_col, 50); + ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50); + ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50); + ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50); + ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50); + if (cur_col > 50) { + printf("\n"); + cur_col = 0; + } + cur_col += printf("SHADDR = 0x%x%x, SHCNT = 0x%x ", + ahd_inl(ahd, SHADDR+4), + ahd_inl(ahd, SHADDR), + (ahd_inb(ahd, SHCNT) + | (ahd_inb(ahd, SHCNT + 1) << 8) + | (ahd_inb(ahd, SHCNT + 2) << 16))); + if (cur_col > 50) { + printf("\n"); + cur_col = 0; + } + cur_col += printf("HADDR = 0x%x%x, HCNT = 0x%x ", + ahd_inl(ahd, HADDR+4), + ahd_inl(ahd, HADDR), + (ahd_inb(ahd, HCNT) + | (ahd_inb(ahd, HCNT + 1) << 8) + | (ahd_inb(ahd, HCNT + 2) << 16))); + ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_SG) != 0) { + fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr); + if (fifo_scb != NULL) + ahd_dump_sglist(fifo_scb); + } +#endif + } + printf("\nLQIN: "); + for (i = 0; i < 20; i++) + printf("0x%x ", ahd_inb(ahd, LQIN + i)); + printf("\n"); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE), + ahd_inb(ahd, OPTIONMODE)); + printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT), + ahd_inb(ahd, MAXCMDCNT)); + ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50); + printf("\n"); + ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); + cur_col = 0; + ahd_ccscbctl_print(ahd_inb(ahd, CCSCBCTL), &cur_col, 50); + printf("\n"); + ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); + printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n", + ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX), + ahd_inw(ahd, DINDEX)); + printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n", + ahd_name(ahd), ahd_get_scbptr(ahd), ahd_inw(ahd, SCB_NEXT), + ahd_inw(ahd, SCB_NEXT2)); + printf("CDB %x %x %x %x %x %x\n", + ahd_inb(ahd, SCB_CDB_STORE), + ahd_inb(ahd, SCB_CDB_STORE+1), + ahd_inb(ahd, SCB_CDB_STORE+2), + ahd_inb(ahd, SCB_CDB_STORE+3), + ahd_inb(ahd, SCB_CDB_STORE+4), + ahd_inb(ahd, SCB_CDB_STORE+5)); + printf("STACK:"); + for (i = 0; i < ahd->stack_size; i++) { + ahd->saved_stack[i] = + ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8); + printf(" 0x%x", ahd->saved_stack[i]); + } + for (i = ahd->stack_size-1; i >= 0; i--) { + ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF); + ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF); + } + printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); + ahd_platform_dump_card_state(ahd); + ahd_restore_modes(ahd, saved_modes); + if (paused == 0) + ahd_unpause(ahd); +} + +void +ahd_dump_scbs(struct ahd_softc *ahd) +{ + ahd_mode_state saved_modes; + u_int saved_scb_index; + int i; + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + saved_scb_index = ahd_get_scbptr(ahd); + for (i = 0; i < AHD_SCB_MAX; i++) { + ahd_set_scbptr(ahd, i); + printf("%3d", i); + printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n", + ahd_inb(ahd, SCB_CONTROL), + ahd_inb(ahd, SCB_SCSIID), ahd_inw(ahd, SCB_NEXT), + ahd_inw(ahd, SCB_NEXT2), ahd_inl(ahd, SCB_SGPTR), + ahd_inl(ahd, SCB_RESIDUAL_SGPTR)); + } + printf("\n"); + ahd_set_scbptr(ahd, saved_scb_index); + ahd_restore_modes(ahd, saved_modes); +} + +/**************************** Flexport Logic **********************************/ +/* + * Read count 16bit words from 16bit word address start_addr from the + * SEEPROM attached to the controller, into buf, using the controller's + * SEEPROM reading state machine. Optionally treat the data as a byte + * stream in terms of byte order. + */ +int +ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count, int bytestream) +{ + u_int cur_addr; + u_int end_addr; + int error; + + /* + * If we never make it through the loop even once, + * we were passed invalid arguments. + */ + error = EINVAL; + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + end_addr = start_addr + count; + for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) { + + ahd_outb(ahd, SEEADR, cur_addr); + ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART); + + error = ahd_wait_seeprom(ahd); + if (error) + break; + if (bytestream != 0) { + uint8_t *bytestream_ptr; + + bytestream_ptr = (uint8_t *)buf; + *bytestream_ptr++ = ahd_inb(ahd, SEEDAT); + *bytestream_ptr = ahd_inb(ahd, SEEDAT+1); + } else { + /* + * ahd_inw() already handles machine byte order. + */ + *buf = ahd_inw(ahd, SEEDAT); + } + buf++; + } + return (error); +} + +/* + * Write count 16bit words from buf, into SEEPROM attache to the + * controller starting at 16bit word address start_addr, using the + * controller's SEEPROM writing state machine. + */ +int +ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, + u_int start_addr, u_int count) +{ + u_int cur_addr; + u_int end_addr; + int error; + int retval; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + error = ENOENT; + + /* Place the chip into write-enable mode */ + ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR); + ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART); + error = ahd_wait_seeprom(ahd); + if (error) + return (error); + + /* + * Write the data. If we don't get throught the loop at + * least once, the arguments were invalid. + */ + retval = EINVAL; + end_addr = start_addr + count; + for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) { + ahd_outw(ahd, SEEDAT, *buf++); + ahd_outb(ahd, SEEADR, cur_addr); + ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART); + + retval = ahd_wait_seeprom(ahd); + if (retval) + break; + } + + /* + * Disable writes. + */ + ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR); + ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART); + error = ahd_wait_seeprom(ahd); + if (error) + return (error); + return (retval); +} + +/* + * Wait ~100us for the serial eeprom to satisfy our request. + */ +int +ahd_wait_seeprom(struct ahd_softc *ahd) +{ + int cnt; + + cnt = 20; + while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt) + ahd_delay(5); + + if (cnt == 0) + return (ETIMEDOUT); + return (0); +} + +/* + * Validate the two checksums in the per_channel + * vital product data struct. + */ +int +ahd_verify_vpd_cksum(struct vpd_config *vpd) +{ + int i; + int maxaddr; + uint32_t checksum; + uint8_t *vpdarray; + + vpdarray = (uint8_t *)vpd; + maxaddr = offsetof(struct vpd_config, vpd_checksum); + checksum = 0; + for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++) + checksum = checksum + vpdarray[i]; + if (checksum == 0 + || (-checksum & 0xFF) != vpd->vpd_checksum) + return (0); + + checksum = 0; + maxaddr = offsetof(struct vpd_config, checksum); + for (i = offsetof(struct vpd_config, default_target_flags); + i < maxaddr; i++) + checksum = checksum + vpdarray[i]; + if (checksum == 0 + || (-checksum & 0xFF) != vpd->checksum) + return (0); + return (1); +} + +int +ahd_verify_cksum(struct seeprom_config *sc) +{ + int i; + int maxaddr; + uint32_t checksum; + uint16_t *scarray; + + maxaddr = (sizeof(*sc)/2) - 1; + checksum = 0; + scarray = (uint16_t *)sc; + + for (i = 0; i < maxaddr; i++) + checksum = checksum + scarray[i]; + if (checksum == 0 + || (checksum & 0xFFFF) != sc->checksum) { + return (0); + } else { + return (1); + } +} + +int +ahd_acquire_seeprom(struct ahd_softc *ahd) +{ + /* + * We should be able to determine the SEEPROM type + * from the flexport logic, but unfortunately not + * all implementations have this logic and there is + * no programatic method for determining if the logic + * is present. + */ + return (1); +#if 0 + uint8_t seetype; + int error; + + error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype); + if (error != 0 + || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE)) + return (0); + return (1); +#endif +} + +void +ahd_release_seeprom(struct ahd_softc *ahd) +{ + /* Currently a no-op */ +} + +int +ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value) +{ + int error; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + if (addr > 7) + panic("ahd_write_flexport: address out of range"); + ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3)); + error = ahd_wait_flexport(ahd); + if (error != 0) + return (error); + ahd_outb(ahd, BRDDAT, value); + ahd_flush_device_writes(ahd); + ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3)); + ahd_flush_device_writes(ahd); + ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3)); + ahd_flush_device_writes(ahd); + ahd_outb(ahd, BRDCTL, 0); + ahd_flush_device_writes(ahd); + return (0); +} + +int +ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value) +{ + int error; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + if (addr > 7) + panic("ahd_read_flexport: address out of range"); + ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3)); + error = ahd_wait_flexport(ahd); + if (error != 0) + return (error); + *value = ahd_inb(ahd, BRDDAT); + ahd_outb(ahd, BRDCTL, 0); + ahd_flush_device_writes(ahd); + return (0); +} + +/* + * Wait at most 2 seconds for flexport arbitration to succeed. + */ +int +ahd_wait_flexport(struct ahd_softc *ahd) +{ + int cnt; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + cnt = 1000000 * 2 / 5; + while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) + ahd_delay(5); + + if (cnt == 0) + return (ETIMEDOUT); + return (0); +} + +/************************* Target Mode ****************************************/ +#ifdef AHD_TARGET_MODE +cam_status +ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb, + struct ahd_tmode_tstate **tstate, + struct ahd_tmode_lstate **lstate, + int notfound_failure) +{ + + if ((ahd->features & AHD_TARGETMODE) == 0) + return (CAM_REQ_INVALID); + + /* + * Handle the 'black hole' device that sucks up + * requests to unattached luns on enabled targets. + */ + if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD + && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) { + *tstate = NULL; + *lstate = ahd->black_hole; + } else { + u_int max_id; + + max_id = (ahd->features & AHD_WIDE) ? 15 : 7; + if (ccb->ccb_h.target_id > max_id) + return (CAM_TID_INVALID); + + if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS) + return (CAM_LUN_INVALID); + + *tstate = ahd->enabled_targets[ccb->ccb_h.target_id]; + *lstate = NULL; + if (*tstate != NULL) + *lstate = + (*tstate)->enabled_luns[ccb->ccb_h.target_lun]; + } + + if (notfound_failure != 0 && *lstate == NULL) + return (CAM_PATH_INVALID); + + return (CAM_REQ_CMP); +} + +void +ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) +{ +#if NOT_YET + struct ahd_tmode_tstate *tstate; + struct ahd_tmode_lstate *lstate; + struct ccb_en_lun *cel; + cam_status status; + u_int target; + u_int lun; + u_int target_mask; + u_long s; + char channel; + + status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate, + /*notfound_failure*/FALSE); + + if (status != CAM_REQ_CMP) { + ccb->ccb_h.status = status; + return; + } + + if ((ahd->features & AHD_MULTIROLE) != 0) { + u_int our_id; + + our_id = ahd->our_id; + if (ccb->ccb_h.target_id != our_id) { + if ((ahd->features & AHD_MULTI_TID) != 0 + && (ahd->flags & AHD_INITIATORROLE) != 0) { + /* + * Only allow additional targets if + * the initiator role is disabled. + * The hardware cannot handle a re-select-in + * on the initiator id during a re-select-out + * on a different target id. + */ + status = CAM_TID_INVALID; + } else if ((ahd->flags & AHD_INITIATORROLE) != 0 + || ahd->enabled_luns > 0) { + /* + * Only allow our target id to change + * if the initiator role is not configured + * and there are no enabled luns which + * are attached to the currently registered + * scsi id. + */ + status = CAM_TID_INVALID; + } + } + } + + if (status != CAM_REQ_CMP) { + ccb->ccb_h.status = status; + return; + } + + /* + * We now have an id that is valid. + * If we aren't in target mode, switch modes. + */ + if ((ahd->flags & AHD_TARGETROLE) == 0 + && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { + u_long s; + + printf("Configuring Target Mode\n"); + ahd_lock(ahd, &s); + if (LIST_FIRST(&ahd->pending_scbs) != NULL) { + ccb->ccb_h.status = CAM_BUSY; + ahd_unlock(ahd, &s); + return; + } + ahd->flags |= AHD_TARGETROLE; + if ((ahd->features & AHD_MULTIROLE) == 0) + ahd->flags &= ~AHD_INITIATORROLE; + ahd_pause(ahd); + ahd_loadseq(ahd); + ahd_restart(ahd); + ahd_unlock(ahd, &s); + } + cel = &ccb->cel; + target = ccb->ccb_h.target_id; + lun = ccb->ccb_h.target_lun; + channel = SIM_CHANNEL(ahd, sim); + target_mask = 0x01 << target; + if (channel == 'B') + target_mask <<= 8; + + if (cel->enable != 0) { + u_int scsiseq1; + + /* Are we already enabled?? */ + if (lstate != NULL) { + xpt_print_path(ccb->ccb_h.path); + printf("Lun already enabled\n"); + ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; + return; + } + + if (cel->grp6_len != 0 + || cel->grp7_len != 0) { + /* + * Don't (yet?) support vendor + * specific commands. + */ + ccb->ccb_h.status = CAM_REQ_INVALID; + printf("Non-zero Group Codes\n"); + return; + } + + /* + * Seems to be okay. + * Setup our data structures. + */ + if (target != CAM_TARGET_WILDCARD && tstate == NULL) { + tstate = ahd_alloc_tstate(ahd, target, channel); + if (tstate == NULL) { + xpt_print_path(ccb->ccb_h.path); + printf("Couldn't allocate tstate\n"); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + return; + } + } + lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT); + if (lstate == NULL) { + xpt_print_path(ccb->ccb_h.path); + printf("Couldn't allocate lstate\n"); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + return; + } + memset(lstate, 0, sizeof(*lstate)); + status = xpt_create_path(&lstate->path, /*periph*/NULL, + xpt_path_path_id(ccb->ccb_h.path), + xpt_path_target_id(ccb->ccb_h.path), + xpt_path_lun_id(ccb->ccb_h.path)); + if (status != CAM_REQ_CMP) { + free(lstate, M_DEVBUF); + xpt_print_path(ccb->ccb_h.path); + printf("Couldn't allocate path\n"); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + return; + } + SLIST_INIT(&lstate->accept_tios); + SLIST_INIT(&lstate->immed_notifies); + ahd_lock(ahd, &s); + ahd_pause(ahd); + if (target != CAM_TARGET_WILDCARD) { + tstate->enabled_luns[lun] = lstate; + ahd->enabled_luns++; + + if ((ahd->features & AHD_MULTI_TID) != 0) { + u_int targid_mask; + + targid_mask = ahd_inb(ahd, TARGID) + | (ahd_inb(ahd, TARGID + 1) << 8); + + targid_mask |= target_mask; + ahd_outb(ahd, TARGID, targid_mask); + ahd_outb(ahd, TARGID+1, (targid_mask >> 8)); + + ahd_update_scsiid(ahd, targid_mask); + } else { + u_int our_id; + char channel; + + channel = SIM_CHANNEL(ahd, sim); + our_id = SIM_SCSI_ID(ahd, sim); + + /* + * This can only happen if selections + * are not enabled + */ + if (target != our_id) { + u_int sblkctl; + char cur_channel; + int swap; + + sblkctl = ahd_inb(ahd, SBLKCTL); + cur_channel = (sblkctl & SELBUSB) + ? 'B' : 'A'; + if ((ahd->features & AHD_TWIN) == 0) + cur_channel = 'A'; + swap = cur_channel != channel; + ahd->our_id = target; + + if (swap) + ahd_outb(ahd, SBLKCTL, + sblkctl ^ SELBUSB); + + ahd_outb(ahd, SCSIID, target); + + if (swap) + ahd_outb(ahd, SBLKCTL, sblkctl); + } + } + } else + ahd->black_hole = lstate; + /* Allow select-in operations */ + if (ahd->black_hole != NULL && ahd->enabled_luns > 0) { + scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); + scsiseq1 |= ENSELI; + ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1); + scsiseq1 = ahd_inb(ahd, SCSISEQ1); + scsiseq1 |= ENSELI; + ahd_outb(ahd, SCSISEQ1, scsiseq1); + } + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_print_path(ccb->ccb_h.path); + printf("Lun now enabled for target mode\n"); + } else { + struct scb *scb; + int i, empty; + + if (lstate == NULL) { + ccb->ccb_h.status = CAM_LUN_INVALID; + return; + } + + ahd_lock(ahd, &s); + + ccb->ccb_h.status = CAM_REQ_CMP; + LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + struct ccb_hdr *ccbh; + + ccbh = &scb->io_ctx->ccb_h; + if (ccbh->func_code == XPT_CONT_TARGET_IO + && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){ + printf("CTIO pending\n"); + ccb->ccb_h.status = CAM_REQ_INVALID; + ahd_unlock(ahd, &s); + return; + } + } + + if (SLIST_FIRST(&lstate->accept_tios) != NULL) { + printf("ATIOs pending\n"); + ccb->ccb_h.status = CAM_REQ_INVALID; + } + + if (SLIST_FIRST(&lstate->immed_notifies) != NULL) { + printf("INOTs pending\n"); + ccb->ccb_h.status = CAM_REQ_INVALID; + } + + if (ccb->ccb_h.status != CAM_REQ_CMP) { + ahd_unlock(ahd, &s); + return; + } + + xpt_print_path(ccb->ccb_h.path); + printf("Target mode disabled\n"); + xpt_free_path(lstate->path); + free(lstate, M_DEVBUF); + + ahd_pause(ahd); + /* Can we clean up the target too? */ + if (target != CAM_TARGET_WILDCARD) { + tstate->enabled_luns[lun] = NULL; + ahd->enabled_luns--; + for (empty = 1, i = 0; i < 8; i++) + if (tstate->enabled_luns[i] != NULL) { + empty = 0; + break; + } + + if (empty) { + ahd_free_tstate(ahd, target, channel, + /*force*/FALSE); + if (ahd->features & AHD_MULTI_TID) { + u_int targid_mask; + + targid_mask = ahd_inb(ahd, TARGID) + | (ahd_inb(ahd, TARGID + 1) + << 8); + + targid_mask &= ~target_mask; + ahd_outb(ahd, TARGID, targid_mask); + ahd_outb(ahd, TARGID+1, + (targid_mask >> 8)); + ahd_update_scsiid(ahd, targid_mask); + } + } + } else { + + ahd->black_hole = NULL; + + /* + * We can't allow selections without + * our black hole device. + */ + empty = TRUE; + } + if (ahd->enabled_luns == 0) { + /* Disallow select-in */ + u_int scsiseq1; + + scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); + scsiseq1 &= ~ENSELI; + ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1); + scsiseq1 = ahd_inb(ahd, SCSISEQ1); + scsiseq1 &= ~ENSELI; + ahd_outb(ahd, SCSISEQ1, scsiseq1); + + if ((ahd->features & AHD_MULTIROLE) == 0) { + printf("Configuring Initiator Mode\n"); + ahd->flags &= ~AHD_TARGETROLE; + ahd->flags |= AHD_INITIATORROLE; + ahd_pause(ahd); + ahd_loadseq(ahd); + ahd_restart(ahd); + /* + * Unpaused. The extra unpause + * that follows is harmless. + */ + } + } + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + } +#endif +} + +static void +ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask) +{ +#if NOT_YET + u_int scsiid_mask; + u_int scsiid; + + if ((ahd->features & AHD_MULTI_TID) == 0) + panic("ahd_update_scsiid called on non-multitid unit\n"); + + /* + * Since we will rely on the TARGID mask + * for selection enables, ensure that OID + * in SCSIID is not set to some other ID + * that we don't want to allow selections on. + */ + if ((ahd->features & AHD_ULTRA2) != 0) + scsiid = ahd_inb(ahd, SCSIID_ULTRA2); + else + scsiid = ahd_inb(ahd, SCSIID); + scsiid_mask = 0x1 << (scsiid & OID); + if ((targid_mask & scsiid_mask) == 0) { + u_int our_id; + + /* ffs counts from 1 */ + our_id = ffs(targid_mask); + if (our_id == 0) + our_id = ahd->our_id; + else + our_id--; + scsiid &= TID; + scsiid |= our_id; + } + if ((ahd->features & AHD_ULTRA2) != 0) + ahd_outb(ahd, SCSIID_ULTRA2, scsiid); + else + ahd_outb(ahd, SCSIID, scsiid); +#endif +} + +void +ahd_run_tqinfifo(struct ahd_softc *ahd, int paused) +{ + struct target_cmd *cmd; + + ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD); + while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) { + + /* + * Only advance through the queue if we + * have the resources to process the command. + */ + if (ahd_handle_target_cmd(ahd, cmd) != 0) + break; + + cmd->cmd_valid = 0; + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap, + ahd_targetcmd_offset(ahd, ahd->tqinfifonext), + sizeof(struct target_cmd), + BUS_DMASYNC_PREREAD); + ahd->tqinfifonext++; + + /* + * Lazily update our position in the target mode incoming + * command queue as seen by the sequencer. + */ + if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) { + u_int hs_mailbox; + + hs_mailbox = ahd_inb(ahd, HS_MAILBOX); + hs_mailbox &= ~HOST_TQINPOS; + hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS; + ahd_outb(ahd, HS_MAILBOX, hs_mailbox); + } + } +} + +static int +ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd) +{ + struct ahd_tmode_tstate *tstate; + struct ahd_tmode_lstate *lstate; + struct ccb_accept_tio *atio; + uint8_t *byte; + int initiator; + int target; + int lun; + + initiator = SCSIID_TARGET(ahd, cmd->scsiid); + target = SCSIID_OUR_ID(cmd->scsiid); + lun = (cmd->identify & MSG_IDENTIFY_LUNMASK); + + byte = cmd->bytes; + tstate = ahd->enabled_targets[target]; + lstate = NULL; + if (tstate != NULL) + lstate = tstate->enabled_luns[lun]; + + /* + * Commands for disabled luns go to the black hole driver. + */ + if (lstate == NULL) + lstate = ahd->black_hole; + + atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios); + if (atio == NULL) { + ahd->flags |= AHD_TQINFIFO_BLOCKED; + /* + * Wait for more ATIOs from the peripheral driver for this lun. + */ + return (1); + } else + ahd->flags &= ~AHD_TQINFIFO_BLOCKED; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_TQIN) != 0) + printf("Incoming command from %d for %d:%d%s\n", + initiator, target, lun, + lstate == ahd->black_hole ? "(Black Holed)" : ""); +#endif + SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle); + + if (lstate == ahd->black_hole) { + /* Fill in the wildcards */ + atio->ccb_h.target_id = target; + atio->ccb_h.target_lun = lun; + } + + /* + * Package it up and send it off to + * whomever has this lun enabled. + */ + atio->sense_len = 0; + atio->init_id = initiator; + if (byte[0] != 0xFF) { + /* Tag was included */ + atio->tag_action = *byte++; + atio->tag_id = *byte++; + atio->ccb_h.flags = CAM_TAG_ACTION_VALID; + } else { + atio->ccb_h.flags = 0; + } + byte++; + + /* Okay. Now determine the cdb size based on the command code */ + switch (*byte >> CMD_GROUP_CODE_SHIFT) { + case 0: + atio->cdb_len = 6; + break; + case 1: + case 2: + atio->cdb_len = 10; + break; + case 4: + atio->cdb_len = 16; + break; + case 5: + atio->cdb_len = 12; + break; + case 3: + default: + /* Only copy the opcode. */ + atio->cdb_len = 1; + printf("Reserved or VU command code type encountered\n"); + break; + } + + memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len); + + atio->ccb_h.status |= CAM_CDB_RECVD; + + if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) { + /* + * We weren't allowed to disconnect. + * We're hanging on the bus until a + * continue target I/O comes in response + * to this accept tio. + */ +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_TQIN) != 0) + printf("Received Immediate Command %d:%d:%d - %p\n", + initiator, target, lun, ahd->pending_device); +#endif + ahd->pending_device = lstate; + ahd_freeze_ccb((union ccb *)atio); + atio->ccb_h.flags |= CAM_DIS_DISCONNECT; + } + xpt_done((union ccb*)atio); + return (0); +} + +#endif diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_inline.h linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_inline.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_inline.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_inline.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,958 @@ +/* + * Inline routines shareable across OS platforms. + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2003 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $ + * + * $FreeBSD$ + */ + +#ifndef _AIC79XX_INLINE_H_ +#define _AIC79XX_INLINE_H_ + +/******************************** Debugging ***********************************/ +static __inline char *ahd_name(struct ahd_softc *ahd); + +static __inline char * +ahd_name(struct ahd_softc *ahd) +{ + return (ahd->name); +} + +/************************ Sequencer Execution Control *************************/ +static __inline void ahd_known_modes(struct ahd_softc *ahd, + ahd_mode src, ahd_mode dst); +static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd, + ahd_mode src, + ahd_mode dst); +static __inline void ahd_extract_mode_state(struct ahd_softc *ahd, + ahd_mode_state state, + ahd_mode *src, ahd_mode *dst); +static __inline void ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, + ahd_mode dst); +static __inline void ahd_update_modes(struct ahd_softc *ahd); +static __inline void ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, + ahd_mode dstmode, const char *file, + int line); +static __inline ahd_mode_state ahd_save_modes(struct ahd_softc *ahd); +static __inline void ahd_restore_modes(struct ahd_softc *ahd, + ahd_mode_state state); +static __inline int ahd_is_paused(struct ahd_softc *ahd); +static __inline void ahd_pause(struct ahd_softc *ahd); +static __inline void ahd_unpause(struct ahd_softc *ahd); + +static __inline void +ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) +{ + ahd->src_mode = src; + ahd->dst_mode = dst; + ahd->saved_src_mode = src; + ahd->saved_dst_mode = dst; +} + +static __inline ahd_mode_state +ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) +{ + return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT)); +} + +static __inline void +ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state, + ahd_mode *src, ahd_mode *dst) +{ + *src = (state & SRC_MODE) >> SRC_MODE_SHIFT; + *dst = (state & DST_MODE) >> DST_MODE_SHIFT; +} + +static __inline void +ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) +{ + if (ahd->src_mode == src && ahd->dst_mode == dst) + return; +#ifdef AHD_DEBUG + if (ahd->src_mode == AHD_MODE_UNKNOWN + || ahd->dst_mode == AHD_MODE_UNKNOWN) + panic("Setting mode prior to saving it.\n"); + if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) + printf("%s: Setting mode 0x%x\n", ahd_name(ahd), + ahd_build_mode_state(ahd, src, dst)); +#endif + ahd_outb(ahd, MODE_PTR, ahd_build_mode_state(ahd, src, dst)); + ahd->src_mode = src; + ahd->dst_mode = dst; +} + +static __inline void +ahd_update_modes(struct ahd_softc *ahd) +{ + ahd_mode_state mode_ptr; + ahd_mode src; + ahd_mode dst; + + mode_ptr = ahd_inb(ahd, MODE_PTR); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) + printf("Reading mode 0x%x\n", mode_ptr); +#endif + ahd_extract_mode_state(ahd, mode_ptr, &src, &dst); + ahd_known_modes(ahd, src, dst); +} + +static __inline void +ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, + ahd_mode dstmode, const char *file, int line) +{ +#ifdef AHD_DEBUG + if ((srcmode & AHD_MK_MSK(ahd->src_mode)) == 0 + || (dstmode & AHD_MK_MSK(ahd->dst_mode)) == 0) { + panic("%s:%s:%d: Mode assertion failed.\n", + ahd_name(ahd), file, line); + } +#endif +} + +static __inline ahd_mode_state +ahd_save_modes(struct ahd_softc *ahd) +{ + if (ahd->src_mode == AHD_MODE_UNKNOWN + || ahd->dst_mode == AHD_MODE_UNKNOWN) + ahd_update_modes(ahd); + + return (ahd_build_mode_state(ahd, ahd->src_mode, ahd->dst_mode)); +} + +static __inline void +ahd_restore_modes(struct ahd_softc *ahd, ahd_mode_state state) +{ + ahd_mode src; + ahd_mode dst; + + ahd_extract_mode_state(ahd, state, &src, &dst); + ahd_set_modes(ahd, src, dst); +} + +#define AHD_ASSERT_MODES(ahd, source, dest) \ + ahd_assert_modes(ahd, source, dest, __FILE__, __LINE__); + +/* + * Determine whether the sequencer has halted code execution. + * Returns non-zero status if the sequencer is stopped. + */ +static __inline int +ahd_is_paused(struct ahd_softc *ahd) +{ + return ((ahd_inb(ahd, HCNTRL) & PAUSE) != 0); +} + +/* + * Request that the sequencer stop and wait, indefinitely, for it + * to stop. The sequencer will only acknowledge that it is paused + * once it has reached an instruction boundary and PAUSEDIS is + * cleared in the SEQCTL register. The sequencer may use PAUSEDIS + * for critical sections. + */ +static __inline void +ahd_pause(struct ahd_softc *ahd) +{ + ahd_outb(ahd, HCNTRL, ahd->pause); + + /* + * Since the sequencer can disable pausing in a critical section, we + * must loop until it actually stops. + */ + while (ahd_is_paused(ahd) == 0) + ; +} + +/* + * Allow the sequencer to continue program execution. + * We check here to ensure that no additional interrupt + * sources that would cause the sequencer to halt have been + * asserted. If, for example, a SCSI bus reset is detected + * while we are fielding a different, pausing, interrupt type, + * we don't want to release the sequencer before going back + * into our interrupt handler and dealing with this new + * condition. + */ +static __inline void +ahd_unpause(struct ahd_softc *ahd) +{ + /* + * Automatically restore our modes to those saved + * prior to the first change of the mode. + */ + if (ahd->saved_src_mode != AHD_MODE_UNKNOWN + && ahd->saved_dst_mode != AHD_MODE_UNKNOWN) { + if ((ahd->flags & AHD_UPDATE_PEND_CMDS) != 0) + ahd_reset_cmds_pending(ahd); + ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); + } + + if ((ahd_inb(ahd, INTSTAT) & ~CMDCMPLT) == 0) + ahd_outb(ahd, HCNTRL, ahd->unpause); + + ahd_known_modes(ahd, AHD_MODE_UNKNOWN, AHD_MODE_UNKNOWN); +} + +/*********************** Scatter Gather List Handling *************************/ +static __inline void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, + void *sgptr, bus_addr_t addr, + bus_size_t len, int last); +static __inline void ahd_setup_scb_common(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_setup_data_scb(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_setup_noxfer_scb(struct ahd_softc *ahd, + struct scb *scb); + +static __inline void * +ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, + void *sgptr, bus_addr_t addr, bus_size_t len, int last) +{ + scb->sg_count++; + if (sizeof(bus_addr_t) > 4 + && (ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = (struct ahd_dma64_seg *)sgptr; + sg->addr = ahd_htole64(addr); + sg->len = ahd_htole32(len | (last ? AHD_DMA_LAST_SEG : 0)); + return (sg + 1); + } else { + struct ahd_dma_seg *sg; + + sg = (struct ahd_dma_seg *)sgptr; + sg->addr = ahd_htole32(addr & 0xFFFFFFFF); + sg->len = ahd_htole32(len | ((addr >> 8) & 0x7F000000) + | (last ? AHD_DMA_LAST_SEG : 0)); + return (sg + 1); + } +} + +static __inline void +ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb) +{ + /* XXX Handle target mode SCBs. */ + scb->crc_retry_count = 0; + if ((scb->flags & SCB_PACKETIZED) != 0) { + /* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */ + scb->hscb->task_attribute = scb->hscb->control & SCB_TAG_TYPE; + } else { + if (ahd_get_transfer_length(scb) & 0x01) + scb->hscb->task_attribute = SCB_XFERLEN_ODD; + else + scb->hscb->task_attribute = 0; + } + + if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR + || (scb->hscb->cdb_len & SCB_CDB_LEN_PTR) != 0) + scb->hscb->shared_data.idata.cdb_plus_saddr.sense_addr = + ahd_htole32(scb->sense_busaddr); +} + +static __inline void +ahd_setup_data_scb(struct ahd_softc *ahd, struct scb *scb) +{ + /* + * Copy the first SG into the "current" data ponter area. + */ + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg; + + sg = (struct ahd_dma64_seg *)scb->sg_list; + scb->hscb->dataptr = sg->addr; + scb->hscb->datacnt = sg->len; + } else { + struct ahd_dma_seg *sg; + uint32_t *dataptr_words; + + sg = (struct ahd_dma_seg *)scb->sg_list; + dataptr_words = (uint32_t*)&scb->hscb->dataptr; + dataptr_words[0] = sg->addr; + dataptr_words[1] = 0; + if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { + uint64_t high_addr; + + high_addr = ahd_le32toh(sg->len) & 0x7F000000; + scb->hscb->dataptr |= ahd_htole64(high_addr << 8); + } + scb->hscb->datacnt = sg->len; + } + /* + * Note where to find the SG entries in bus space. + * We also set the full residual flag which the + * sequencer will clear as soon as a data transfer + * occurs. + */ + scb->hscb->sgptr = ahd_htole32(scb->sg_list_busaddr|SG_FULL_RESID); +} + +static __inline void +ahd_setup_noxfer_scb(struct ahd_softc *ahd, struct scb *scb) +{ + scb->hscb->sgptr = ahd_htole32(SG_LIST_NULL); + scb->hscb->dataptr = 0; + scb->hscb->datacnt = 0; +} + +/************************** Memory mapping routines ***************************/ +static __inline size_t ahd_sg_size(struct ahd_softc *ahd); +static __inline void * + ahd_sg_bus_to_virt(struct ahd_softc *ahd, + struct scb *scb, + uint32_t sg_busaddr); +static __inline uint32_t + ahd_sg_virt_to_bus(struct ahd_softc *ahd, + struct scb *scb, + void *sg); +static __inline void ahd_sync_scb(struct ahd_softc *ahd, + struct scb *scb, int op); +static __inline void ahd_sync_sglist(struct ahd_softc *ahd, + struct scb *scb, int op); +static __inline void ahd_sync_sense(struct ahd_softc *ahd, + struct scb *scb, int op); +static __inline uint32_t + ahd_targetcmd_offset(struct ahd_softc *ahd, + u_int index); + +static __inline size_t +ahd_sg_size(struct ahd_softc *ahd) +{ + if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) + return (sizeof(struct ahd_dma64_seg)); + return (sizeof(struct ahd_dma_seg)); +} + +static __inline void * +ahd_sg_bus_to_virt(struct ahd_softc *ahd, struct scb *scb, uint32_t sg_busaddr) +{ + bus_addr_t sg_offset; + + /* sg_list_phys points to entry 1, not 0 */ + sg_offset = sg_busaddr - (scb->sg_list_busaddr - ahd_sg_size(ahd)); + return ((uint8_t *)scb->sg_list + sg_offset); +} + +static __inline uint32_t +ahd_sg_virt_to_bus(struct ahd_softc *ahd, struct scb *scb, void *sg) +{ + bus_addr_t sg_offset; + + /* sg_list_phys points to entry 1, not 0 */ + sg_offset = ((uint8_t *)sg - (uint8_t *)scb->sg_list) + - ahd_sg_size(ahd); + + return (scb->sg_list_busaddr + sg_offset); +} + +static __inline void +ahd_sync_scb(struct ahd_softc *ahd, struct scb *scb, int op) +{ + ahd_dmamap_sync(ahd, ahd->scb_data.hscb_dmat, + scb->hscb_map->dmamap, + /*offset*/(uint8_t*)scb->hscb - scb->hscb_map->vaddr, + /*len*/sizeof(*scb->hscb), op); +} + +static __inline void +ahd_sync_sglist(struct ahd_softc *ahd, struct scb *scb, int op) +{ + if (scb->sg_count == 0) + return; + + ahd_dmamap_sync(ahd, ahd->scb_data.sg_dmat, + scb->sg_map->dmamap, + /*offset*/scb->sg_list_busaddr - ahd_sg_size(ahd), + /*len*/ahd_sg_size(ahd) * scb->sg_count, op); +} + +static __inline void +ahd_sync_sense(struct ahd_softc *ahd, struct scb *scb, int op) +{ + ahd_dmamap_sync(ahd, ahd->scb_data.sense_dmat, + scb->sense_map->dmamap, + /*offset*/scb->sense_busaddr, + /*len*/AHD_SENSE_BUFSIZE, op); +} + +static __inline uint32_t +ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) +{ + return (((uint8_t *)&ahd->targetcmds[index]) + - (uint8_t *)ahd->qoutfifo); +} + +/*********************** Miscelaneous Support Functions ***********************/ +static __inline void ahd_complete_scb(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_update_residual(struct ahd_softc *ahd, + struct scb *scb); +static __inline struct ahd_initiator_tinfo * + ahd_fetch_transinfo(struct ahd_softc *ahd, + char channel, u_int our_id, + u_int remote_id, + struct ahd_tmode_tstate **tstate); +static __inline uint16_t + ahd_inw(struct ahd_softc *ahd, u_int port); +static __inline void ahd_outw(struct ahd_softc *ahd, u_int port, + u_int value); +static __inline uint32_t + ahd_inl(struct ahd_softc *ahd, u_int port); +static __inline void ahd_outl(struct ahd_softc *ahd, u_int port, + uint32_t value); +static __inline uint64_t + ahd_inq(struct ahd_softc *ahd, u_int port); +static __inline void ahd_outq(struct ahd_softc *ahd, u_int port, + uint64_t value); +static __inline u_int ahd_get_scbptr(struct ahd_softc *ahd); +static __inline void ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr); +static __inline u_int ahd_get_hnscb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_hescb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_snscb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_sescb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_get_sdscb_qoff(struct ahd_softc *ahd); +static __inline void ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value); +static __inline u_int ahd_inb_scbram(struct ahd_softc *ahd, u_int offset); +static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset); +static __inline uint32_t + ahd_inl_scbram(struct ahd_softc *ahd, u_int offset); +static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb); +static __inline uint8_t * + ahd_get_sense_buf(struct ahd_softc *ahd, + struct scb *scb); +static __inline uint32_t + ahd_get_sense_bufaddr(struct ahd_softc *ahd, + struct scb *scb); + +static __inline void +ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_handle_scb_status(ahd, scb); + else + ahd_done(ahd, scb); +} + +/* + * Determine whether the sequencer reported a residual + * for this SCB/transaction. + */ +static __inline void +ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_calc_residual(ahd, scb); +} + +/* + * Return pointers to the transfer negotiation information + * for the specified our_id/remote_id pair. + */ +static __inline struct ahd_initiator_tinfo * +ahd_fetch_transinfo(struct ahd_softc *ahd, char channel, u_int our_id, + u_int remote_id, struct ahd_tmode_tstate **tstate) +{ + /* + * Transfer data structures are stored from the perspective + * of the target role. Since the parameters for a connection + * in the initiator role to a given target are the same as + * when the roles are reversed, we pretend we are the target. + */ + if (channel == 'B') + our_id += 8; + *tstate = ahd->enabled_targets[our_id]; + return (&(*tstate)->transinfo[remote_id]); +} + +#define AHD_COPY_COL_IDX(dst, src) \ +do { \ + dst->hscb->scsiid = src->hscb->scsiid; \ + dst->hscb->lun = src->hscb->lun; \ +} while (0) + +static __inline uint16_t +ahd_inw(struct ahd_softc *ahd, u_int port) +{ + return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); +} + +static __inline void +ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) +{ + ahd_outb(ahd, port, value & 0xFF); + ahd_outb(ahd, port+1, (value >> 8) & 0xFF); +} + +static __inline uint32_t +ahd_inl(struct ahd_softc *ahd, u_int port) +{ + return ((ahd_inb(ahd, port)) + | (ahd_inb(ahd, port+1) << 8) + | (ahd_inb(ahd, port+2) << 16) + | (ahd_inb(ahd, port+3) << 24)); +} + +static __inline void +ahd_outl(struct ahd_softc *ahd, u_int port, uint32_t value) +{ + ahd_outb(ahd, port, (value) & 0xFF); + ahd_outb(ahd, port+1, ((value) >> 8) & 0xFF); + ahd_outb(ahd, port+2, ((value) >> 16) & 0xFF); + ahd_outb(ahd, port+3, ((value) >> 24) & 0xFF); +} + +static __inline uint64_t +ahd_inq(struct ahd_softc *ahd, u_int port) +{ + return ((ahd_inb(ahd, port)) + | (ahd_inb(ahd, port+1) << 8) + | (ahd_inb(ahd, port+2) << 16) + | (ahd_inb(ahd, port+3) << 24) + | (((uint64_t)ahd_inb(ahd, port+4)) << 32) + | (((uint64_t)ahd_inb(ahd, port+5)) << 40) + | (((uint64_t)ahd_inb(ahd, port+6)) << 48) + | (((uint64_t)ahd_inb(ahd, port+7)) << 56)); +} + +static __inline void +ahd_outq(struct ahd_softc *ahd, u_int port, uint64_t value) +{ + ahd_outb(ahd, port, value & 0xFF); + ahd_outb(ahd, port+1, (value >> 8) & 0xFF); + ahd_outb(ahd, port+2, (value >> 16) & 0xFF); + ahd_outb(ahd, port+3, (value >> 24) & 0xFF); + ahd_outb(ahd, port+4, (value >> 32) & 0xFF); + ahd_outb(ahd, port+5, (value >> 40) & 0xFF); + ahd_outb(ahd, port+6, (value >> 48) & 0xFF); + ahd_outb(ahd, port+7, (value >> 56) & 0xFF); +} + +static __inline u_int +ahd_get_scbptr(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + return (ahd_inb(ahd, SCBPTR) | (ahd_inb(ahd, SCBPTR + 1) << 8)); +} + +static __inline void +ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr) +{ + AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), + ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); + ahd_outb(ahd, SCBPTR, scbptr & 0xFF); + ahd_outb(ahd, SCBPTR+1, (scbptr >> 8) & 0xFF); +} + +static __inline u_int +ahd_get_hnscb_qoff(struct ahd_softc *ahd) +{ + return (ahd_inw_atomic(ahd, HNSCB_QOFF)); +} + +static __inline void +ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value) +{ + ahd_outw_atomic(ahd, HNSCB_QOFF, value); +} + +static __inline u_int +ahd_get_hescb_qoff(struct ahd_softc *ahd) +{ + return (ahd_inb(ahd, HESCB_QOFF)); +} + +static __inline void +ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value) +{ + ahd_outb(ahd, HESCB_QOFF, value); +} + +static __inline u_int +ahd_get_snscb_qoff(struct ahd_softc *ahd) +{ + u_int oldvalue; + + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + oldvalue = ahd_inw(ahd, SNSCB_QOFF); + ahd_outw(ahd, SNSCB_QOFF, oldvalue); + return (oldvalue); +} + +static __inline void +ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + ahd_outw(ahd, SNSCB_QOFF, value); +} + +static __inline u_int +ahd_get_sescb_qoff(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + return (ahd_inb(ahd, SESCB_QOFF)); +} + +static __inline void +ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + ahd_outb(ahd, SESCB_QOFF, value); +} + +static __inline u_int +ahd_get_sdscb_qoff(struct ahd_softc *ahd) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + return (ahd_inb(ahd, SDSCB_QOFF) | (ahd_inb(ahd, SDSCB_QOFF + 1) << 8)); +} + +static __inline void +ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value) +{ + AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); + ahd_outb(ahd, SDSCB_QOFF, value & 0xFF); + ahd_outb(ahd, SDSCB_QOFF+1, (value >> 8) & 0xFF); +} + +static __inline u_int +ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) +{ + u_int value; + + /* + * Workaround PCI-X Rev A. hardware bug. + * After a host read of SCB memory, the chip + * may become confused into thinking prefetch + * was required. This starts the discard timer + * running and can cause an unexpected discard + * timer interrupt. The work around is to read + * a normal register prior to the exhaustion of + * the discard timer. The mode pointer register + * has no side effects and so serves well for + * this purpose. + * + * Razor #528 + */ + value = ahd_inb(ahd, offset); + if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0) + ahd_inb(ahd, MODE_PTR); + return (value); +} + +static __inline u_int +ahd_inw_scbram(struct ahd_softc *ahd, u_int offset) +{ + return (ahd_inb_scbram(ahd, offset) + | (ahd_inb_scbram(ahd, offset+1) << 8)); +} + +static __inline uint32_t +ahd_inl_scbram(struct ahd_softc *ahd, u_int offset) +{ + return (ahd_inb_scbram(ahd, offset) + | (ahd_inb_scbram(ahd, offset+1) << 8) + | (ahd_inb_scbram(ahd, offset+2) << 16) + | (ahd_inb_scbram(ahd, offset+3) << 24)); +} + +static __inline struct scb * +ahd_lookup_scb(struct ahd_softc *ahd, u_int tag) +{ + struct scb* scb; + + if (tag >= AHD_SCB_MAX) + return (NULL); + scb = ahd->scb_data.scbindex[tag]; + if (scb != NULL) + ahd_sync_scb(ahd, scb, + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); + return (scb); +} + +static __inline void +ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) +{ + struct hardware_scb *q_hscb; + uint32_t saved_hscb_busaddr; + + /* + * Our queuing method is a bit tricky. The card + * knows in advance which HSCB (by address) to download, + * and we can't disappoint it. To achieve this, the next + * HSCB to download is saved off in ahd->next_queued_hscb. + * When we are called to queue "an arbitrary scb", + * we copy the contents of the incoming HSCB to the one + * the sequencer knows about, swap HSCB pointers and + * finally assign the SCB to the tag indexed location + * in the scb_array. This makes sure that we can still + * locate the correct SCB by SCB_TAG. + */ + q_hscb = ahd->next_queued_hscb; + saved_hscb_busaddr = q_hscb->hscb_busaddr; + memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); + q_hscb->hscb_busaddr = saved_hscb_busaddr; + q_hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; + + /* Now swap HSCB pointers. */ + ahd->next_queued_hscb = scb->hscb; + scb->hscb = q_hscb; + + /* Now define the mapping from tag to SCB in the scbindex */ + ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; +} + +/* + * Tell the sequencer about a new transaction to execute. + */ +static __inline void +ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb) +{ + ahd_swap_with_next_hscb(ahd, scb); + + if (SCBID_IS_NULL(SCB_GET_TAG(scb))) + panic("Attempt to queue invalid SCB tag %x\n", + SCB_GET_TAG(scb)); + + /* + * Keep a history of SCBs we've downloaded in the qinfifo. + */ + ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); + ahd->qinfifonext++; + + if (scb->sg_count != 0) + ahd_setup_data_scb(ahd, scb); + else + ahd_setup_noxfer_scb(ahd, scb); + ahd_setup_scb_common(ahd, scb); + + /* + * Make sure our data is consistent from the + * perspective of the adapter. + */ + ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_QUEUE) != 0) { + uint64_t host_dataptr; + + host_dataptr = ahd_le64toh(scb->hscb->dataptr); + printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n", + ahd_name(ahd), + SCB_GET_TAG(scb), ahd_le32toh(scb->hscb->hscb_busaddr), + (u_int)((host_dataptr >> 32) & 0xFFFFFFFF), + (u_int)(host_dataptr & 0xFFFFFFFF), + ahd_le32toh(scb->hscb->datacnt)); + } +#endif + /* Tell the adapter about the newly queued SCB */ + ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); +} + +static __inline uint8_t * +ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb) +{ + return (scb->sense_data); +} + +static __inline uint32_t +ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb) +{ + return (scb->sense_busaddr); +} + +/************************** Interrupt Processing ******************************/ +static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op); +static __inline void ahd_sync_tqinfifo(struct ahd_softc *ahd, int op); +static __inline u_int ahd_check_cmdcmpltqueues(struct ahd_softc *ahd); +static __inline int ahd_intr(struct ahd_softc *ahd); + +static __inline void +ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) +{ + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, + /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op); +} + +static __inline void +ahd_sync_tqinfifo(struct ahd_softc *ahd, int op) +{ +#ifdef AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0) { + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap, + ahd_targetcmd_offset(ahd, 0), + sizeof(struct target_cmd) * AHD_TMODE_CMDS, + op); + } +#endif +} + +/* + * See if the firmware has posted any completed commands + * into our in-core command complete fifos. + */ +#define AHD_RUN_QOUTFIFO 0x1 +#define AHD_RUN_TQINFIFO 0x2 +static __inline u_int +ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) +{ + u_int retval; + + retval = 0; + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, + /*offset*/ahd->qoutfifonext, /*len*/2, + BUS_DMASYNC_POSTREAD); + if ((ahd->qoutfifo[ahd->qoutfifonext] + & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) + retval |= AHD_RUN_QOUTFIFO; +#ifdef AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0 + && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, + ahd->shared_data_dmamap, + ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), + /*len*/sizeof(struct target_cmd), + BUS_DMASYNC_POSTREAD); + if (ahd->targetcmds[ahd->tqinfifonext].cmd_valid != 0) + retval |= AHD_RUN_TQINFIFO; + } +#endif + return (retval); +} + +/* + * Catch an interrupt from the adapter + */ +static __inline int +ahd_intr(struct ahd_softc *ahd) +{ + u_int intstat; + + if ((ahd->pause & INTEN) == 0) { + /* + * Our interrupt is not enabled on the chip + * and may be disabled for re-entrancy reasons, + * so just return. This is likely just a shared + * interrupt. + */ + return (0); + } + + /* + * Instead of directly reading the interrupt status register, + * infer the cause of the interrupt by checking our in-core + * completion queues. This avoids a costly PCI bus read in + * most cases. + */ + if ((ahd->flags & AHD_ALL_INTERRUPTS) == 0 + && (ahd_check_cmdcmpltqueues(ahd) != 0)) + intstat = CMDCMPLT; + else + intstat = ahd_inb(ahd, INTSTAT); + + if ((intstat & INT_PEND) == 0) + return (0); + + if (intstat & CMDCMPLT) { + ahd_outb(ahd, CLRINT, CLRCMDINT); + + /* + * Ensure that the chip sees that we've cleared + * this interrupt before we walk the output fifo. + * Otherwise, we may, due to posted bus writes, + * clear the interrupt after we finish the scan, + * and after the sequencer has added new entries + * and asserted the interrupt again. + */ + if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { + if (ahd_is_paused(ahd)) { + /* + * Potentially lost SEQINT. + * If SEQINTCODE is non-zero, + * simulate the SEQINT. + */ + if (ahd_inb(ahd, SEQINTCODE) != NO_SEQINT) + intstat |= SEQINT; + } + } else { + ahd_flush_device_writes(ahd); + } + ahd_run_qoutfifo(ahd); + ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]++; + ahd->cmdcmplt_total++; +#ifdef AHD_TARGET_MODE + if ((ahd->flags & AHD_TARGETROLE) != 0) + ahd_run_tqinfifo(ahd, /*paused*/FALSE); +#endif + } + + /* + * Handle statuses that may invalidate our cached + * copy of INTSTAT separately. + */ + if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) { + /* Hot eject. Do nothing */ + } else if (intstat & HWERRINT) { + ahd_handle_hwerrint(ahd); + } else if ((intstat & (PCIINT|SPLTINT)) != 0) { + ahd->bus_intr(ahd); + } else { + + if ((intstat & SEQINT) != 0) + ahd_handle_seqint(ahd, intstat); + + if ((intstat & SCSIINT) != 0) + ahd_handle_scsiint(ahd, intstat); + } + return (1); +} + +#endif /* _AIC79XX_INLINE_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_osm.c linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_osm.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_osm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_osm.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,5129 @@ +/* + * Adaptec AIC79xx device driver for Linux. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#169 $ + * + * -------------------------------------------------------------------------- + * Copyright (c) 1994-2000 Justin T. Gibbs. + * Copyright (c) 1997-1999 Doug Ledford + * Copyright (c) 2000-2003 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" +#include + +/* + * Include aiclib.c as part of our + * "module dependencies are hard" work around. + */ +#include "aiclib.c" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) +#include /* __setup */ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#include "sd.h" /* For geometry detection */ +#endif + +#include /* For fetching system memory size */ + +/* + * Lock protecting manipulation of the ahd softc list. + */ +spinlock_t ahd_list_spinlock; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +struct proc_dir_entry proc_scsi_aic79xx = { + PROC_SCSI_AIC79XX, 7, "aic79xx", + S_IFDIR | S_IRUGO | S_IXUGO, 2, + 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* For dynamic sglist size calculation. */ +u_int ahd_linux_nseg; +#endif + +/* + * Bucket size for counting good commands in between bad ones. + */ +#define AHD_LINUX_ERR_THRESH 1000 + +/* + * Set this to the delay in seconds after SCSI bus reset. + * Note, we honor this only for the initial bus reset. + * The scsi error recovery code performs its own bus settle + * delay handling for error recovery actions. + */ +#ifdef CONFIG_AIC79XX_RESET_DELAY_MS +#define AIC79XX_RESET_DELAY CONFIG_AIC79XX_RESET_DELAY_MS +#else +#define AIC79XX_RESET_DELAY 5000 +#endif + +/* + * To change the default number of tagged transactions allowed per-device, + * add a line to the lilo.conf file like: + * append="aic79xx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}" + * which will result in the first four devices on the first two + * controllers being set to a tagged queue depth of 32. + * + * The tag_commands is an array of 16 to allow for wide and twin adapters. + * Twin adapters will use indexes 0-7 for channel 0, and indexes 8-15 + * for channel 1. + */ +typedef struct { + uint16_t tag_commands[16]; /* Allow for wide/twin adapters. */ +} adapter_tag_info_t; + +/* + * Modify this as you see fit for your system. + * + * 0 tagged queuing disabled + * 1 <= n <= 253 n == max tags ever dispatched. + * + * The driver will throttle the number of commands dispatched to a + * device if it returns queue full. For devices with a fixed maximum + * queue depth, the driver will eventually determine this depth and + * lock it in (a console message is printed to indicate that a lock + * has occurred). On some devices, queue full is returned for a temporary + * resource shortage. These devices will return queue full at varying + * depths. The driver will throttle back when the queue fulls occur and + * attempt to slowly increase the depth over time as the device recovers + * from the resource shortage. + * + * In this example, the first line will disable tagged queueing for all + * the devices on the first probed aic79xx adapter. + * + * The second line enables tagged queueing with 4 commands/LUN for IDs + * (0, 2-11, 13-15), disables tagged queueing for ID 12, and tells the + * driver to attempt to use up to 64 tags for ID 1. + * + * The third line is the same as the first line. + * + * The fourth line disables tagged queueing for devices 0 and 3. It + * enables tagged queueing for the other IDs, with 16 commands/LUN + * for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for + * IDs 2, 5-7, and 9-15. + */ + +/* + * NOTE: The below structure is for reference only, the actual structure + * to modify in order to change things is just below this comment block. +adapter_tag_info_t aic79xx_tag_info[] = +{ + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{4, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 16, 4, 0, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}} +}; +*/ + +#ifdef CONFIG_AIC79XX_CMDS_PER_DEVICE +#define AIC79XX_CMDS_PER_DEVICE CONFIG_AIC79XX_CMDS_PER_DEVICE +#else +#define AIC79XX_CMDS_PER_DEVICE AHD_MAX_QUEUE +#endif + +#define AIC79XX_CONFIGED_TAG_COMMANDS { \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \ + AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE \ +} + +/* + * By default, use the number of commands specified by + * the users kernel configuration. + */ +static adapter_tag_info_t aic79xx_tag_info[] = +{ + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS}, + {AIC79XX_CONFIGED_TAG_COMMANDS} +}; + +/* + * By default, read streaming is disabled. In theory, + * read streaming should enhance performance, but early + * U320 drive firmware actually performs slower with + * read streaming enabled. + */ +#ifdef CONFIG_AIC79XX_ENABLE_RD_STRM +#define AIC79XX_CONFIGED_RD_STRM 0xFFFF +#else +#define AIC79XX_CONFIGED_RD_STRM 0 +#endif + +static uint16_t aic79xx_rd_strm_info[] = +{ + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM, + AIC79XX_CONFIGED_RD_STRM +}; + +/* + * DV option: + * + * positive value = DV Enabled + * zero = DV Disabled + * negative value = DV Default for adapter type/seeprom + */ +#ifdef CONFIG_AIC79XX_DV_SETTING +#define AIC79XX_CONFIGED_DV CONFIG_AIC79XX_DV_SETTING +#else +#define AIC79XX_CONFIGED_DV -1 +#endif + +static int8_t aic79xx_dv_settings[] = +{ + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV, + AIC79XX_CONFIGED_DV +}; + +/* + * The I/O cell on the chip is very configurable in respect to its analog + * characteristics. Set the defaults here; they can be overriden with + * the proper insmod parameters. + */ +struct ahd_linux_iocell_opts +{ + uint8_t precomp; + uint8_t slewrate; + uint8_t amplitude; +}; +#define AIC79XX_DEFAULT_PRECOMP 0xFF +#define AIC79XX_DEFAULT_SLEWRATE 0xFF +#define AIC79XX_DEFAULT_AMPLITUDE 0xFF +#define AIC79XX_DEFAULT_IOOPTS \ +{ \ + AIC79XX_DEFAULT_PRECOMP, \ + AIC79XX_DEFAULT_SLEWRATE, \ + AIC79XX_DEFAULT_AMPLITUDE \ +} +#define AIC79XX_PRECOMP_INDEX 0 +#define AIC79XX_SLEWRATE_INDEX 1 +#define AIC79XX_AMPLITUDE_INDEX 2 +static struct ahd_linux_iocell_opts aic79xx_iocell_info[] = +{ + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS, + AIC79XX_DEFAULT_IOOPTS +}; + +/* + * There should be a specific return value for this in scsi.h, but + * it seems that most drivers ignore it. + */ +#define DID_UNDERFLOW DID_ERROR + +void +ahd_print_path(struct ahd_softc *ahd, struct scb *scb) +{ + printk("(scsi%d:%c:%d:%d): ", + ahd->platform_data->host->host_no, + scb != NULL ? SCB_GET_CHANNEL(ahd, scb) : 'X', + scb != NULL ? SCB_GET_TARGET(ahd, scb) : -1, + scb != NULL ? SCB_GET_LUN(scb) : -1); +} + +/* + * XXX - these options apply unilaterally to _all_ adapters + * cards in the system. This should be fixed. Exceptions to this + * rule are noted in the comments. + */ + +/* + * Skip the scsi bus reset. Non 0 make us skip the reset at startup. This + * has no effect on any later resets that might occur due to things like + * SCSI bus timeouts. + */ +static uint32_t aic79xx_no_reset; + +/* + * Certain PCI motherboards will scan PCI devices from highest to lowest, + * others scan from lowest to highest, and they tend to do all kinds of + * strange things when they come into contact with PCI bridge chips. The + * net result of all this is that the PCI card that is actually used to boot + * the machine is very hard to detect. Most motherboards go from lowest + * PCI slot number to highest, and the first SCSI controller found is the + * one you boot from. The only exceptions to this are when a controller + * has its BIOS disabled. So, we by default sort all of our SCSI controllers + * from lowest PCI slot number to highest PCI slot number. We also force + * all controllers with their BIOS disabled to the end of the list. This + * works on *almost* all computers. Where it doesn't work, we have this + * option. Setting this option to non-0 will reverse the order of the sort + * to highest first, then lowest, but will still leave cards with their BIOS + * disabled at the very end. That should fix everyone up unless there are + * really strange cirumstances. + */ +static uint32_t aic79xx_reverse_scan; + +/* + * Should we force EXTENDED translation on a controller. + * 0 == Use whatever is in the SEEPROM or default to off + * 1 == Use whatever is in the SEEPROM or default to on + */ +static uint32_t aic79xx_extended; + +/* + * PCI bus parity checking of the Adaptec controllers. This is somewhat + * dubious at best. To my knowledge, this option has never actually + * solved a PCI parity problem, but on certain machines with broken PCI + * chipset configurations, it can generate tons of false error messages. + * It's included in the driver for completeness. + * 0 = Shut off PCI parity check + * non-0 = Enable PCI parity check + * + * NOTE: you can't actually pass -1 on the lilo prompt. So, to set this + * variable to -1 you would actually want to simply pass the variable + * name without a number. That will invert the 0 which will result in + * -1. + */ +static uint32_t aic79xx_pci_parity = ~0; + +/* + * There are lots of broken chipsets in the world. Some of them will + * violate the PCI spec when we issue byte sized memory writes to our + * controller. I/O mapped register access, if allowed by the given + * platform, will work in almost all cases. + */ +uint32_t aic79xx_allow_memio = ~0; + +/* + * aic79xx_detect() has been run, so register all device arrivals + * immediately with the system rather than deferring to the sorted + * attachment performed by aic79xx_detect(). + */ +int aic79xx_detect_complete; + +/* + * So that we can set how long each device is given as a selection timeout. + * The table of values goes like this: + * 0 - 256ms + * 1 - 128ms + * 2 - 64ms + * 3 - 32ms + * We default to 256ms because some older devices need a longer time + * to respond to initial selection. + */ +static uint32_t aic79xx_seltime; + +/* + * Certain devices do not perform any aging on commands. Should the + * device be saturated by commands in one portion of the disk, it is + * possible for transactions on far away sectors to never be serviced. + * To handle these devices, we can periodically send an ordered tag to + * force all outstanding transactions to be serviced prior to a new + * transaction. + */ +uint32_t aic79xx_periodic_otag; + +/* + * Module information and settable options. + */ +#ifdef MODULE +static char *aic79xx = NULL; +/* + * Just in case someone uses commas to separate items on the insmod + * command line, we define a dummy buffer here to avoid having insmod + * write wild stuff into our code segment + */ +static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n"; + +MODULE_AUTHOR("Maintainer: Justin T. Gibbs "); +MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("Dual BSD/GPL"); +#endif +MODULE_PARM(aic79xx, "s"); +MODULE_PARM_DESC(aic79xx, +"period delimited, options string.\n" +" verbose Enable verbose/diagnostic logging\n" +" allow_memio Allow device registers to be memory mapped\n" +" debug Bitmask of debug values to enable\n" +" no_reset Supress initial bus resets\n" +" extended Enable extended geometry on all controllers\n" +" periodic_otag Send an ordered tagged transaction\n" +" periodically to prevent tag starvation.\n" +" This may be required by some older disk\n" +" or drives/RAID arrays.\n" +" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" +" tag_info: Set per-target tag depth\n" +" global_tag_depth: Global tag depth for all targets on all buses\n" +" rd_strm: Set per-target read streaming setting.\n" +" dv: Set per-controller Domain Validation Setting.\n" +" slewrate:Set the signal slew rate (0-15).\n" +" precomp: Set the signal precompensation (0-7).\n" +" amplitude: Set the signal amplitude (0-7).\n" +" seltime: Selection Timeout:\n" +" (0/256ms,1/128ms,2/64ms,3/32ms)\n" +"\n" +" Sample /etc/modules.conf line:\n" +" Enable verbose logging\n" +" Set tag depth on Controller 2/Target 2 to 10 tags\n" +" Shorten the selection timeout to 128ms\n" +"\n" +" options aic79xx 'aic79xx=verbose.tag_info:{{}.{}.{..10}}.seltime:1'\n" +"\n" +" Sample /etc/modules.conf line:\n" +" Change Read Streaming for Controller's 2 and 3\n" +"\n" +" options aic79xx 'aic79xx=rd_strm:{..0xFFF0.0xC0F0}'"); +#endif + +static void ahd_linux_handle_scsi_status(struct ahd_softc *, + struct ahd_linux_device *, + struct scb *); +static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, + Scsi_Cmnd *cmd); +static void ahd_linux_filter_inquiry(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dev_timed_unfreeze(u_long arg); +static void ahd_linux_sem_timeout(u_long arg); +static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); +static void ahd_linux_size_nseg(void); +static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd); +static void ahd_linux_start_dv(struct ahd_softc *ahd); +static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd); +static int ahd_linux_dv_thread(void *data); +static void ahd_linux_kill_dv_thread(struct ahd_softc *ahd); +static void ahd_linux_dv_target(struct ahd_softc *ahd, u_int target); +static void ahd_linux_dv_transition(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dv_inq(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ, + u_int request_length); +static void ahd_linux_dv_tur(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dv_rebd(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_web(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_reb(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static void ahd_linux_dv_su(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ); +static __inline int + ahd_linux_dv_fallback(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static int ahd_linux_fallback(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static __inline int ahd_linux_dv_fallback(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static void ahd_linux_dv_complete(Scsi_Cmnd *cmd); +static void ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ); +static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo); +static u_int ahd_linux_user_dv_setting(struct ahd_softc *ahd); +static void ahd_linux_setup_user_rd_strm_settings(struct ahd_softc *ahd); +static void ahd_linux_device_queue_depth(struct ahd_softc *ahd, + struct ahd_linux_device *dev); +static struct ahd_linux_target* ahd_linux_alloc_target(struct ahd_softc*, + u_int, u_int); +static void ahd_linux_free_target(struct ahd_softc*, + struct ahd_linux_target*); +static struct ahd_linux_device* ahd_linux_alloc_device(struct ahd_softc*, + struct ahd_linux_target*, + u_int); +static void ahd_linux_free_device(struct ahd_softc*, + struct ahd_linux_device*); +static void ahd_linux_run_device_queue(struct ahd_softc*, + struct ahd_linux_device*); +static void ahd_linux_setup_tag_info_global(char *p); +static aic_option_callback_t ahd_linux_setup_tag_info; +static aic_option_callback_t ahd_linux_setup_rd_strm_info; +static aic_option_callback_t ahd_linux_setup_dv; +static aic_option_callback_t ahd_linux_setup_iocell_info; +static int ahd_linux_next_unit(void); +static void ahd_runq_tasklet(unsigned long data); +static int aic79xx_setup(char *c); + +/****************************** Inlines ***************************************/ +static __inline void ahd_schedule_completeq(struct ahd_softc *ahd); +static __inline void ahd_schedule_runq(struct ahd_softc *ahd); +static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd); +static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd); +static __inline struct ahd_linux_device* + ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, + u_int target, u_int lun, int alloc); +static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd); +static __inline void ahd_linux_check_device_queue(struct ahd_softc *ahd, + struct ahd_linux_device *dev); +static __inline struct ahd_linux_device * + ahd_linux_next_device_to_run(struct ahd_softc *ahd); +static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd); +static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); + +static __inline int ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, + struct ahd_dma_seg *sg, + bus_addr_t addr, bus_size_t len); + +static __inline void +ahd_schedule_completeq(struct ahd_softc *ahd) +{ + if ((ahd->platform_data->flags & AHD_RUN_CMPLT_Q_TIMER) == 0) { + ahd->platform_data->flags |= AHD_RUN_CMPLT_Q_TIMER; + ahd->platform_data->completeq_timer.expires = jiffies; + add_timer(&ahd->platform_data->completeq_timer); + } +} + +/* + * Must be called with our lock held. + */ +static __inline void +ahd_schedule_runq(struct ahd_softc *ahd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_schedule(&ahd->platform_data->runq_tasklet); +#else + /* + * Tasklets are not available, so run inline. + */ + ahd_runq_tasklet((unsigned long)ahd); +#endif +} + +static __inline +void ahd_setup_runq_tasklet(struct ahd_softc *ahd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_init(&ahd->platform_data->runq_tasklet, ahd_runq_tasklet, + (unsigned long)ahd); +#endif +} + +static __inline void +ahd_teardown_runq_tasklet(struct ahd_softc *ahd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_kill(&ahd->platform_data->runq_tasklet); +#endif +} + +static __inline struct ahd_linux_device* +ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target, + u_int lun, int alloc) +{ + struct ahd_linux_target *targ; + struct ahd_linux_device *dev; + u_int target_offset; + + target_offset = target; + if (channel != 0) + target_offset += 8; + targ = ahd->platform_data->targets[target_offset]; + if (targ == NULL) { + if (alloc != 0) { + targ = ahd_linux_alloc_target(ahd, channel, target); + if (targ == NULL) + return (NULL); + } else + return (NULL); + } + dev = targ->devices[lun]; + if (dev == NULL && alloc != 0) + dev = ahd_linux_alloc_device(ahd, targ, lun); + return (dev); +} + +#define AHD_LINUX_MAX_RETURNED_ERRORS 4 +static struct ahd_cmd * +ahd_linux_run_complete_queue(struct ahd_softc *ahd) +{ + struct ahd_cmd *acmd; + u_long done_flags; + int with_errors; + + with_errors = 0; + ahd_done_lock(ahd, &done_flags); + while ((acmd = TAILQ_FIRST(&ahd->platform_data->completeq)) != NULL) { + Scsi_Cmnd *cmd; + + if (with_errors > AHD_LINUX_MAX_RETURNED_ERRORS) { + /* + * Linux uses stack recursion to requeue + * commands that need to be retried. Avoid + * blowing out the stack by "spoon feeding" + * commands that completed with error back + * the operating system in case they are going + * to be retried. "ick" + */ + ahd_schedule_completeq(ahd); + break; + } + TAILQ_REMOVE(&ahd->platform_data->completeq, + acmd, acmd_links.tqe); + cmd = &acmd_scsi_cmd(acmd); + cmd->host_scribble = NULL; + if (ahd_cmd_get_transaction_status(cmd) != DID_OK + || (cmd->result & 0xFF) != SCSI_STATUS_OK) + with_errors++; + + cmd->scsi_done(cmd); + } + ahd_done_unlock(ahd, &done_flags); + return (acmd); +} + +static __inline void +ahd_linux_check_device_queue(struct ahd_softc *ahd, + struct ahd_linux_device *dev) +{ + if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) != 0 + && dev->active == 0) { + dev->flags &= ~AHD_DEV_FREEZE_TIL_EMPTY; + dev->qfrozen--; + } + + if (TAILQ_FIRST(&dev->busyq) == NULL + || dev->openings == 0 || dev->qfrozen != 0) + return; + + ahd_linux_run_device_queue(ahd, dev); +} + +static __inline struct ahd_linux_device * +ahd_linux_next_device_to_run(struct ahd_softc *ahd) +{ + + if ((ahd->flags & AHD_RESOURCE_SHORTAGE) != 0 + || (ahd->platform_data->qfrozen != 0 + && AHD_DV_SIMQ_FROZEN(ahd) == 0)) + return (NULL); + return (TAILQ_FIRST(&ahd->platform_data->device_runq)); +} + +static __inline void +ahd_linux_run_device_queues(struct ahd_softc *ahd) +{ + struct ahd_linux_device *dev; + + while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { + TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); + dev->flags &= ~AHD_DEV_ON_RUN_LIST; + ahd_linux_check_device_queue(ahd, dev); + } +} + +static __inline void +ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) +{ + Scsi_Cmnd *cmd; + int direction; + + cmd = scb->io_ctx; + direction = scsi_to_pci_dma_dir(cmd->sc_data_direction); + ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE); + if (cmd->use_sg != 0) { + struct scatterlist *sg; + + sg = (struct scatterlist *)cmd->request_buffer; + pci_unmap_sg(ahd->dev_softc, sg, cmd->use_sg, direction); + } else if (cmd->request_bufflen != 0) { + pci_unmap_single(ahd->dev_softc, + scb->platform_data->buf_busaddr, + cmd->request_bufflen, direction); + } +} + +static __inline int +ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, + struct ahd_dma_seg *sg, bus_addr_t addr, bus_size_t len) +{ + int consumed; + + if ((scb->sg_count + 1) > AHD_NSEG) + panic("Too few segs for dma mapping. " + "Increase AHD_NSEG\n"); + + consumed = 1; + sg->addr = ahd_htole32(addr & 0xFFFFFFFF); + scb->platform_data->xfer_len += len; + + if (sizeof(bus_addr_t) > 4 + && (ahd->flags & AHD_39BIT_ADDRESSING) != 0) + len |= (addr >> 8) & AHD_SG_HIGH_ADDR_MASK; + + sg->len = ahd_htole32(len); + return (consumed); +} + +/******************************** Macros **************************************/ +#define BUILD_SCSIID(ahd, cmd) \ + ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id) + +/************************ Host template entry points *************************/ +static int ahd_linux_detect(Scsi_Host_Template *); +static const char *ahd_linux_info(struct Scsi_Host *); +static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int ahd_linux_slave_alloc(Scsi_Device *); +static int ahd_linux_slave_configure(Scsi_Device *); +static void ahd_linux_slave_destroy(Scsi_Device *); +#if defined(__i386__) +static int ahd_linux_biosparam(struct scsi_device*, + struct block_device*, sector_t, int[]); +#endif +#else +static int ahd_linux_release(struct Scsi_Host *); +static void ahd_linux_select_queue_depth(struct Scsi_Host *host, + Scsi_Device *scsi_devs); +#if defined(__i386__) +static int ahd_linux_biosparam(Disk *, kdev_t, int[]); +#endif +#endif +static int ahd_linux_bus_reset(Scsi_Cmnd *); +static int ahd_linux_dev_reset(Scsi_Cmnd *); +static int ahd_linux_abort(Scsi_Cmnd *); + +/* + * Calculate a safe value for AHD_NSEG (as expressed through ahd_linux_nseg). + * + * In pre-2.5.X... + * The midlayer allocates an S/G array dynamically when a command is issued + * using SCSI malloc. This array, which is in an OS dependent format that + * must later be copied to our private S/G list, is sized to house just the + * number of segments needed for the current transfer. Since the code that + * sizes the SCSI malloc pool does not take into consideration fragmentation + * of the pool, executing transactions numbering just a fraction of our + * concurrent transaction limit with SG list lengths aproaching AHC_NSEG will + * quickly depleat the SCSI malloc pool of usable space. Unfortunately, the + * mid-layer does not properly handle this scsi malloc failures for the S/G + * array and the result can be a lockup of the I/O subsystem. We try to size + * our S/G list so that it satisfies our drivers allocation requirements in + * addition to avoiding fragmentation of the SCSI malloc pool. + */ +static void +ahd_linux_size_nseg(void) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + u_int cur_size; + u_int best_size; + + /* + * The SCSI allocator rounds to the nearest 512 bytes + * an cannot allocate across a page boundary. Our algorithm + * is to start at 1K of scsi malloc space per-command and + * loop through all factors of the PAGE_SIZE and pick the best. + */ + best_size = 0; + for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) { + u_int nseg; + + nseg = cur_size / sizeof(struct scatterlist); + if (nseg < AHD_LINUX_MIN_NSEG) + continue; + + if (best_size == 0) { + best_size = cur_size; + ahd_linux_nseg = nseg; + } else { + u_int best_rem; + u_int cur_rem; + + /* + * Compare the traits of the current "best_size" + * with the current size to determine if the + * current size is a better size. + */ + best_rem = best_size % sizeof(struct scatterlist); + cur_rem = cur_size % sizeof(struct scatterlist); + if (cur_rem < best_rem) { + best_size = cur_size; + ahd_linux_nseg = nseg; + } + } + } +#endif +} + +/* + * Try to detect an Adaptec 79XX controller. + */ +static int +ahd_linux_detect(Scsi_Host_Template *template) +{ + struct ahd_softc *ahd; + int found; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * It is a bug that the upper layer takes + * this lock just prior to calling us. + */ + spin_unlock_irq(&io_request_lock); +#endif + + /* + * Sanity checking of Linux SCSI data structures so + * that some of our hacks^H^H^H^H^Hassumptions aren't + * violated. + */ + if (offsetof(struct ahd_cmd_internal, end) + > offsetof(struct scsi_cmnd, host_scribble)) { + printf("ahd_linux_detect: SCSI data structures changed.\n"); + printf("ahd_linux_detect: Unable to attach\n"); + return (0); + } + /* + * Determine an appropriate size for our Scatter Gatther lists. + */ + ahd_linux_size_nseg(); +#ifdef MODULE + /* + * If we've been passed any parameters, process them now. + */ + if (aic79xx) + aic79xx_setup(aic79xx); + if (dummy_buffer[0] != 'P') + printk(KERN_WARNING +"aic79xx: Please read the file /usr/src/linux/drivers/scsi/README.aic79xx\n" +"aic79xx: to see the proper way to specify options to the aic79xx module\n" +"aic79xx: Specifically, don't use any commas when passing arguments to\n" +"aic79xx: insmod or else it might trash certain memory areas.\n"); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) + template->proc_name = "aic79xx"; +#else + template->proc_dir = &proc_scsi_aic79xx; +#endif + + /* + * Initialize our softc list lock prior to + * probing for any adapters. + */ + ahd_list_lockinit(); + +#ifdef CONFIG_PCI + ahd_linux_pci_init(); +#endif + + /* + * Register with the SCSI layer all + * controllers we've found. + */ + found = 0; + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + + if (ahd_linux_register_host(ahd, template) == 0) + found++; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + aic79xx_detect_complete++; + return (found); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* + * Free the passed in Scsi_Host memory structures prior to unloading the + * module. + */ +static int +ahd_linux_release(struct Scsi_Host * host) +{ + struct ahd_softc *ahd; + u_long l; + + ahd_list_lock(&l); + if (host != NULL) { + + /* + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. + */ + ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata); + if (ahd != NULL) { + u_long s; + + ahd_lock(ahd, &s); + ahd_intr_enable(ahd, FALSE); + ahd_unlock(ahd, &s); + ahd_free(ahd); + } + } + ahd_list_unlock(&l); + return (0); +} +#endif + +/* + * Return a string describing the driver. + */ +static const char * +ahd_linux_info(struct Scsi_Host *host) +{ + static char buffer[512]; + char ahd_info[256]; + char *bp; + struct ahd_softc *ahd; + + bp = &buffer[0]; + ahd = *(struct ahd_softc **)host->hostdata; + memset(bp, 0, sizeof(buffer)); + strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev "); + strcat(bp, AIC79XX_DRIVER_VERSION); + strcat(bp, "\n"); + strcat(bp, " <"); + strcat(bp, ahd->description); + strcat(bp, ">\n"); + strcat(bp, " "); + ahd_controller_info(ahd, ahd_info); + strcat(bp, ahd_info); + strcat(bp, "\n"); + + return (bp); +} + +/* + * Queue an SCB to the controller. + */ +static int +ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + + /* + * Save the callback on completion function. + */ + cmd->scsi_done = scsi_done; + + ahd_midlayer_entrypoint_lock(ahd, &flags); + + /* + * Close the race of a command that was in the process of + * being queued to us just as our simq was frozen. Let + * DV commands through so long as we are only frozen to + * perform DV. + */ + if (ahd->platform_data->qfrozen != 0 + && AHD_DV_CMD(cmd) == 0) { + + ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); + ahd_linux_queue_cmd_complete(ahd, cmd); + ahd_schedule_completeq(ahd); + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); + } + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, cmd->device->lun, + /*alloc*/TRUE); + if (dev == NULL) { + ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL); + ahd_linux_queue_cmd_complete(ahd, cmd); + ahd_schedule_completeq(ahd); + ahd_midlayer_entrypoint_unlock(ahd, &flags); + printf("%s: aic79xx_linux_queue - Unable to allocate device!\n", + ahd_name(ahd)); + return (0); + } + if (cmd->cmd_len > MAX_CDB_LEN) + return (-EINVAL); + cmd->result = CAM_REQ_INPROG << 16; + TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe); + if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + ahd_linux_run_device_queues(ahd); + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int +ahd_linux_slave_alloc(Scsi_Device *device) +{ + struct ahd_softc *ahd; + + ahd = *((struct ahd_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Alloc %d\n", ahd_name(ahd), device->id); + return (0); +} + +static int +ahd_linux_slave_configure(Scsi_Device *device) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *((struct ahd_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Configure %d\n", ahd_name(ahd), device->id); + ahd_midlayer_entrypoint_lock(ahd, &flags); + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHD_DEV_UNCONFIGURED; + dev->flags |= AHD_DEV_SLAVE_CONFIGURED; + dev->scsi_device = device; + ahd_linux_device_queue_depth(ahd, dev); + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); +} + +static void +ahd_linux_slave_destroy(Scsi_Device *device) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *((struct ahd_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Destroy %d\n", ahd_name(ahd), device->id); + ahd_midlayer_entrypoint_lock(ahd, &flags); + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/FALSE); + + /* + * Filter out "silly" deletions of real devices by only + * deleting devices that have had slave_configure() + * called on them. All other devices that have not + * been configured will automatically be deleted by + * the refcounting process. + */ + if (dev != NULL + && (dev->flags & AHD_DEV_SLAVE_CONFIGURED) != 0) { + dev->flags |= AHD_DEV_UNCONFIGURED; + if (TAILQ_EMPTY(&dev->busyq) + && dev->active == 0 + && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0) + ahd_linux_free_device(ahd, dev); + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); +} +#else +/* + * Sets the queue depth for each SCSI device hanging + * off the input host adapter. + */ +static void +ahd_linux_select_queue_depth(struct Scsi_Host * host, + Scsi_Device * scsi_devs) +{ + Scsi_Device *device; + Scsi_Device *ldev; + struct ahd_softc *ahd; + u_long flags; + + ahd = *((struct ahd_softc **)host->hostdata); + ahd_lock(ahd, &flags); + for (device = scsi_devs; device != NULL; device = device->next) { + + /* + * Watch out for duplicate devices. This works around + * some quirks in how the SCSI scanning code does its + * device management. + */ + for (ldev = scsi_devs; ldev != device; ldev = ldev->next) { + if (ldev->host == device->host + && ldev->channel == device->channel + && ldev->id == device->id + && ldev->lun == device->lun) + break; + } + /* Skip duplicate. */ + if (ldev != device) + continue; + + if (device->host == host) { + struct ahd_linux_device *dev; + + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHD_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahd_linux_device_queue_depth(ahd, dev); + device->queue_depth = dev->openings + + dev->active; + if ((dev->flags & (AHD_DEV_Q_BASIC + | AHD_DEV_Q_TAGGED)) == 0) { + /* + * We allow the OS to queue 2 untagged + * transactions to us at any time even + * though we can only execute them + * serially on the controller/device. + * This should remove some latency. + */ + device->queue_depth = 2; + } + } + } + } + ahd_unlock(ahd, &flags); +} +#endif + +#if defined(__i386__) +/* + * Return the disk geometry for the given SCSI device. + */ +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]) +{ + uint8_t *bh; +#else +ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) +{ + struct scsi_device *sdev = disk->device; + u_long capacity = disk->capacity; + struct buffer_head *bh; +#endif + int heads; + int sectors; + int cylinders; + int ret; + int extended; + struct ahd_softc *ahd; + + ahd = *((struct ahd_softc **)sdev->host->hostdata); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + bh = scsi_bios_ptable(bdev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); +#else + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); +#endif + + if (bh) { + ret = scsi_partsize(bh, capacity, + &geom[2], &geom[0], &geom[1]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + kfree(bh); +#else + brelse(bh); +#endif + if (ret != -1) + return (ret); + } + heads = 64; + sectors = 32; + cylinders = aic_sector_div(capacity, heads, sectors); + + if (aic79xx_extended != 0) + extended = 1; + else + extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0; + if (extended && cylinders >= 1024) { + heads = 255; + sectors = 63; + cylinders = aic_sector_div(capacity, heads, sectors); + } + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + return (0); +} +#endif + +/* + * Abort the current SCSI command(s). + */ +static int +ahd_linux_abort(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + struct ahd_cmd *acmd; + struct ahd_cmd *list_acmd; + struct ahd_linux_device *dev; + struct scb *pending_scb; + u_long s; + u_int saved_scbptr; + u_int active_scbptr; + u_int last_phase; + u_int cdb_byte; + int retval; + int was_paused; + int paused; + int wait; + int disconnected; + ahd_mode_state saved_modes; + + pending_scb = NULL; + paused = FALSE; + wait = FALSE; + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + acmd = (struct ahd_cmd *)cmd; + + printf("%s:%d:%d:%d: Attempting to abort cmd %p:", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun, cmd); + for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++) + printf(" 0x%x", cmd->cmnd[cdb_byte]); + printf("\n"); + + /* + * In all versions of Linux, we have to work around + * a major flaw in how the mid-layer is locked down + * if we are to sleep successfully in our error handler + * while allowing our interrupt handler to run. Since + * the midlayer acquires either the io_request_lock or + * our lock prior to calling us, we must use the + * spin_unlock_irq() method for unlocking our lock. + * This will force interrupts to be enabled on the + * current CPU. Since the EH thread should not have + * been running with CPU interrupts disabled other than + * by acquiring either the io_request_lock or our own + * lock, this *should* be safe. + */ + ahd_midlayer_entrypoint_lock(ahd, &s); + + /* + * First determine if we currently own this command. + * Start by searching the device queue. If not found + * there, check the pending_scb list. If not found + * at all, and the system wanted us to just abort the + * command, return success. + */ + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, cmd->device->lun, + /*alloc*/FALSE); + + if (dev == NULL) { + /* + * No target device for this command exists, + * so we must not still own the command. + */ + printf("%s:%d:%d:%d: Is not an active device\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + retval = SUCCESS; + goto no_cmd; + } + + TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { + if (list_acmd == acmd) + break; + } + + if (list_acmd != NULL) { + printf("%s:%d:%d:%d: Command found on device queue\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); + cmd->result = DID_ABORT << 16; + ahd_linux_queue_cmd_complete(ahd, cmd); + retval = SUCCESS; + goto done; + } + + /* + * See if we can find a matching cmd in the pending list. + */ + LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + if (pending_scb->io_ctx == cmd) + break; + } + + if (pending_scb == NULL) { + printf("%s:%d:%d:%d: Command not found\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + goto no_cmd; + } + + if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) { + /* + * We can't queue two recovery actions using the same SCB + */ + retval = FAILED; + goto done; + } + + /* + * Ensure that the card doesn't do anything + * behind our back. Also make sure that we + * didn't "just" miss an interrupt that would + * affect this cmd. + */ + was_paused = ahd_is_paused(ahd); + ahd_pause_and_flushwork(ahd); + paused = TRUE; + + if ((pending_scb->flags & SCB_ACTIVE) == 0) { + printf("%s:%d:%d:%d: Command already completed\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + goto no_cmd; + } + + printf("%s: At time of recovery, card was %spaused\n", + ahd_name(ahd), was_paused ? "" : "not "); + ahd_dump_card_state(ahd); + + disconnected = TRUE; + if (ahd_search_qinfifo(ahd, cmd->device->id, cmd->device->channel + 'A', + cmd->device->lun, SCB_GET_TAG(pending_scb), + ROLE_INITIATOR, CAM_REQ_ABORTED, + SEARCH_COMPLETE) > 0) { + printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + retval = SUCCESS; + goto done; + } + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + last_phase = ahd_inb(ahd, LASTPHASE); + saved_scbptr = ahd_get_scbptr(ahd); + active_scbptr = saved_scbptr; + if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { + struct scb *bus_scb; + + bus_scb = ahd_lookup_scb(ahd, active_scbptr); + if (bus_scb == pending_scb) + disconnected = FALSE; + } + + /* + * At this point, pending_scb is the scb associated with the + * passed in command. That command is currently active on the + * bus or is in the disconnected state. + */ + if (last_phase != P_BUSFREE + && SCB_GET_TAG(pending_scb) == active_scbptr) { + + /* + * We're active on the bus, so assert ATN + * and hope that the target responds. + */ + pending_scb = ahd_lookup_scb(ahd, active_scbptr); + pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, SCSISIGO, last_phase|ATNO); + printf("%s:%d:%d:%d: Device is active, asserting ATN\n", + ahd_name(ahd), cmd->device->channel, + cmd->device->id, cmd->device->lun); + wait = TRUE; + } else if (disconnected) { + + /* + * Actually re-queue this SCB in an attempt + * to select the device before it reconnects. + */ + pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb)); + pending_scb->hscb->cdb_len = 0; + pending_scb->hscb->task_attribute = 0; + pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK; + + if ((pending_scb->flags & SCB_PACKETIZED) != 0) { + /* + * Mark the SCB has having an outstanding + * task management function. Should the command + * complete normally before the task management + * function can be sent, the host will be notified + * to abort our requeued SCB. + */ + ahd_outb(ahd, SCB_TASK_MANAGEMENT, + pending_scb->hscb->task_management); + } else { + /* + * If non-packetized, set the MK_MESSAGE control + * bit indicating that we desire to send a message. + * We also set the disconnected flag since there is + * no guarantee that our SCB control byte matches + * the version on the card. We don't want the + * sequencer to abort the command thinking an + * unsolicited reselection occurred. + */ + pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED; + + /* + * The sequencer will never re-reference the + * in-core SCB. To make sure we are notified + * during reslection, set the MK_MESSAGE flag in + * the card's copy of the SCB. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE); + } + + /* + * Clear out any entries in the QINFIFO first + * so we are the next SCB for this target + * to run. + */ + ahd_search_qinfifo(ahd, cmd->device->id, + cmd->device->channel + 'A', cmd->device->lun, + SCB_LIST_NULL, ROLE_INITIATOR, + CAM_REQUEUE_REQ, SEARCH_COMPLETE); + ahd_qinfifo_requeue_tail(ahd, pending_scb); + ahd_set_scbptr(ahd, saved_scbptr); + ahd_print_path(ahd, pending_scb); + printf("Device is disconnected, re-queuing SCB\n"); + wait = TRUE; + } else { + printf("%s:%d:%d:%d: Unable to deliver message\n", + ahd_name(ahd), cmd->device->channel, + cmd->device->id, cmd->device->lun); + retval = FAILED; + goto done; + } + +no_cmd: + /* + * Our assumption is that if we don't have the command, no + * recovery action was required, so we return success. Again, + * the semantics of the mid-layer recovery engine are not + * well defined, so this may change in time. + */ + retval = SUCCESS; +done: + if (paused) + ahd_unpause(ahd); + if (wait) { + struct timer_list timer; + int ret; + + pending_scb->platform_data->flags |= AHD_SCB_UP_EH_SEM; + spin_unlock_irq(&ahd->platform_data->spin_lock); + init_timer(&timer); + timer.data = (u_long)pending_scb; + timer.expires = jiffies + (5 * HZ); + timer.function = ahd_linux_sem_timeout; + add_timer(&timer); + printf("Recovery code sleeping\n"); + down(&ahd->platform_data->eh_sem); + printf("Recovery code awake\n"); + ret = del_timer_sync(&timer); + if (ret == 0) { + printf("Timer Expired\n"); + retval = FAILED; + } + spin_lock_irq(&ahd->platform_data->spin_lock); + } + ahd_schedule_runq(ahd); + ahd_linux_run_complete_queue(ahd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (retval); +} + + +static void +ahd_linux_dev_reset_complete(Scsi_Cmnd *cmd) +{ + free(cmd, M_DEVBUF); +} + +/* + * Attempt to send a target reset message to the device that timed out. + */ +static int +ahd_linux_dev_reset(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + struct scsi_cmnd *recovery_cmd; + struct ahd_linux_device *dev; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + struct scb *scb; + struct hardware_scb *hscb; + u_long s; + struct timer_list timer; + int retval; + + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + recovery_cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + memset(recovery_cmd, 0, sizeof(struct scsi_cmnd)); + recovery_cmd->device = cmd->device; + recovery_cmd->scsi_done = ahd_linux_dev_reset_complete; +#if AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s:%d:%d:%d: Device reset called for cmd %p\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun, cmd); +#endif + ahd_midlayer_entrypoint_lock(ahd, &s); + + dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/FALSE); + if (dev == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (FAILED); + } + if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (FAILED); + } + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + cmd->device->id, &tstate); + recovery_cmd->result = CAM_REQ_INPROG << 16; + recovery_cmd->host_scribble = (char *)scb; + scb->io_ctx = recovery_cmd; + scb->platform_data->dev = dev; + scb->sg_count = 0; + ahd_set_residual(scb, 0); + ahd_set_sense_residual(scb, 0); + hscb = scb->hscb; + hscb->control = 0; + hscb->scsiid = BUILD_SCSIID(ahd, cmd); + hscb->lun = cmd->device->lun; + hscb->cdb_len = 0; + hscb->task_management = SIU_TASKMGMT_LUN_RESET; + scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE; + if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + scb->flags |= SCB_PACKETIZED; + } else { + hscb->control |= MK_MESSAGE; + } + dev->openings--; + dev->active++; + dev->commands_issued++; + LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); + ahd_queue_scb(ahd, scb); + + scb->platform_data->flags |= AHD_SCB_UP_EH_SEM; + spin_unlock_irq(&ahd->platform_data->spin_lock); + init_timer(&timer); + timer.data = (u_long)scb; + timer.expires = jiffies + (5 * HZ); + timer.function = ahd_linux_sem_timeout; + add_timer(&timer); + printf("Recovery code sleeping\n"); + down(&ahd->platform_data->eh_sem); + printf("Recovery code awake\n"); + retval = SUCCESS; + if (del_timer_sync(&timer) == 0) { + printf("Timer Expired\n"); + retval = FAILED; + } + spin_lock_irq(&ahd->platform_data->spin_lock); + ahd_schedule_runq(ahd); + ahd_linux_run_complete_queue(ahd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval); + return (retval); +} + +/* + * Reset the SCSI bus. + */ +static int +ahd_linux_bus_reset(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + u_long s; + int found; + + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s: Bus reset called for cmd %p\n", + ahd_name(ahd), cmd); +#endif + ahd_midlayer_entrypoint_lock(ahd, &s); + found = ahd_reset_channel(ahd, cmd->device->channel + 'A', + /*initiate reset*/TRUE); + ahd_linux_run_complete_queue(ahd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + + if (bootverbose) + printf("%s: SCSI bus reset delivered. " + "%d SCBs aborted.\n", ahd_name(ahd), found); + + return (SUCCESS); +} + +Scsi_Host_Template aic79xx_driver_template = { + .module = THIS_MODULE, + .name = "aic79xx", + .proc_info = ahd_linux_proc_info, + .info = ahd_linux_info, + .queuecommand = ahd_linux_queue, + .eh_abort_handler = ahd_linux_abort, + .eh_device_reset_handler = ahd_linux_dev_reset, + .eh_bus_reset_handler = ahd_linux_bus_reset, +#if defined(__i386__) + .bios_param = ahd_linux_biosparam, +#endif + .can_queue = AHD_MAX_QUEUE, + .this_id = -1, + .cmd_per_lun = 2, + .use_clustering = ENABLE_CLUSTERING, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) + /* + * We can only map 16MB per-SG + * so create a sector limit of + * "16MB" in 2K sectors. + */ + .max_sectors = 8192, +#endif +#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) +/* Assume RedHat Distribution with its different HIGHIO conventions. */ + .can_dma_32 = 1, + .single_sg_okay = 1, +#else + .highmem_io = 1, +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + .slave_alloc = ahd_linux_slave_alloc, + .slave_configure = ahd_linux_slave_configure, + .slave_destroy = ahd_linux_slave_destroy, +#else + .detect = ahd_linux_detect, + .release = ahd_linux_release, + .select_queue_depths = ahd_linux_select_queue_depth, + .use_new_eh_code = 1, +#endif +}; + +/**************************** Tasklet Handler *********************************/ + +/* + * In 2.4.X and above, this routine is called from a tasklet, + * so we must re-acquire our lock prior to executing this code. + * In all prior kernels, ahd_schedule_runq() calls this routine + * directly and ahd_schedule_runq() is called with our lock held. + */ +static void +ahd_runq_tasklet(unsigned long data) +{ + struct ahd_softc* ahd; + struct ahd_linux_device *dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + u_long flags; +#endif + + ahd = (struct ahd_softc *)data; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + ahd_lock(ahd, &flags); +#endif + while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { + + TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); + dev->flags &= ~AHD_DEV_ON_RUN_LIST; + ahd_linux_check_device_queue(ahd, dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + /* Yeild to our interrupt handler */ + ahd_unlock(ahd, &flags); + ahd_lock(ahd, &flags); +#endif + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + ahd_unlock(ahd, &flags); +#endif +} + +/******************************** Bus DMA *************************************/ +int +ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, + bus_size_t alignment, bus_size_t boundary, + bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, + bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) +{ + bus_dma_tag_t dmat; + + dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT); + if (dmat == NULL) + return (ENOMEM); + + /* + * Linux is very simplistic about DMA memory. For now don't + * maintain all specification information. Once Linux supplies + * better facilities for doing these operations, or the + * needs of this particular driver change, we might need to do + * more here. + */ + dmat->alignment = alignment; + dmat->boundary = boundary; + dmat->maxsize = maxsize; + *ret_tag = dmat; + return (0); +} + +void +ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat) +{ + free(dmat, M_DEVBUF); +} + +int +ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr, + int flags, bus_dmamap_t *mapp) +{ + bus_dmamap_t map; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); + if (map == NULL) + return (ENOMEM); + /* + * Although we can dma data above 4GB, our + * "consistent" memory is below 4GB for + * space efficiency reasons (only need a 4byte + * address). For this reason, we have to reset + * our dma mask when doing allocations. + */ + if (ahd->dev_softc != NULL) + ahd_pci_set_dma_mask(ahd->dev_softc, 0xFFFFFFFF); + *vaddr = pci_alloc_consistent(ahd->dev_softc, + dmat->maxsize, &map->bus_addr); + if (ahd->dev_softc != NULL) + ahd_pci_set_dma_mask(ahd->dev_softc, + ahd->platform_data->hw_dma_mask); +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ + /* + * At least in 2.2.14, malloc is a slab allocator so all + * allocations are aligned. We assume for these kernel versions + * that all allocations will be bellow 4Gig, physically contiguous, + * and accessible via DMA by the controller. + */ + map = NULL; /* No additional information to store */ + *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); +#endif + if (*vaddr == NULL) + return (ENOMEM); + *mapp = map; + return(0); +} + +void +ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat, + void* vaddr, bus_dmamap_t map) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + pci_free_consistent(ahd->dev_softc, dmat->maxsize, + vaddr, map->bus_addr); +#else + free(vaddr, M_DEVBUF); +#endif +} + +int +ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map, + void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, + void *cb_arg, int flags) +{ + /* + * Assume for now that this will only be used during + * initialization and not for per-transaction buffer mapping. + */ + bus_dma_segment_t stack_sg; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + stack_sg.ds_addr = map->bus_addr; +#else +#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a)) + stack_sg.ds_addr = VIRT_TO_BUS(buf); +#endif + stack_sg.ds_len = dmat->maxsize; + cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); + return (0); +} + +void +ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* + * The map may is NULL in our < 2.3.X implementation. + */ + if (map != NULL) + free(map, M_DEVBUF); +} + +int +ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* Nothing to do */ + return (0); +} + +/********************* Platform Dependent Functions ***************************/ +/* + * Compare "left hand" softc with "right hand" softc, returning: + * < 0 - lahd has a lower priority than rahd + * 0 - Softcs are equal + * > 0 - lahd has a higher priority than rahd + */ +int +ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd) +{ + int value; + + /* + * Under Linux, cards are ordered as follows: + * 1) PCI devices that are marked as the boot controller. + * 2) PCI devices with BIOS enabled sorted by bus/slot/func. + * 3) All remaining PCI devices sorted by bus/slot/func. + */ +#if 0 + value = (lahd->flags & AHD_BOOT_CHANNEL) + - (rahd->flags & AHD_BOOT_CHANNEL); + if (value != 0) + /* Controllers set for boot have a *higher* priority */ + return (value); +#endif + + value = (lahd->flags & AHD_BIOS_ENABLED) + - (rahd->flags & AHD_BIOS_ENABLED); + if (value != 0) + /* Controllers with BIOS enabled have a *higher* priority */ + return (value); + + /* Still equal. Sort by bus/slot/func. */ + if (aic79xx_reverse_scan != 0) + value = ahd_get_pci_bus(lahd->dev_softc) + - ahd_get_pci_bus(rahd->dev_softc); + else + value = ahd_get_pci_bus(rahd->dev_softc) + - ahd_get_pci_bus(lahd->dev_softc); + if (value != 0) + return (value); + if (aic79xx_reverse_scan != 0) + value = ahd_get_pci_slot(lahd->dev_softc) + - ahd_get_pci_slot(rahd->dev_softc); + else + value = ahd_get_pci_slot(rahd->dev_softc) + - ahd_get_pci_slot(lahd->dev_softc); + if (value != 0) + return (value); + + value = rahd->channel - lahd->channel; + return (value); +} + +static void +ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) +{ + + if ((instance >= 0) && (targ >= 0) + && (instance < NUM_ELEMENTS(aic79xx_tag_info)) + && (targ < AHD_NUM_TARGETS)) { + aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF; + if (bootverbose) + printf("tag_info[%d:%d] = %d\n", instance, targ, value); + } +} + +static void +ahd_linux_setup_rd_strm_info(u_long arg, int instance, int targ, int32_t value) +{ + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic79xx_rd_strm_info))) { + aic79xx_rd_strm_info[instance] = value & 0xFFFF; + if (bootverbose) + printf("rd_strm[%d] = 0x%x\n", instance, value); + } +} + +static void +ahd_linux_setup_dv(u_long arg, int instance, int targ, int32_t value) +{ + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic79xx_dv_settings))) { + aic79xx_dv_settings[instance] = value; + if (bootverbose) + printf("dv[%d] = %d\n", instance, value); + } +} + +static void +ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value) +{ + + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic79xx_iocell_info))) { + uint8_t *iocell_info; + + iocell_info = (uint8_t*)&aic79xx_iocell_info[instance]; + iocell_info[index] = value & 0xFFFF; + if (bootverbose) + printf("iocell[%d:%ld] = %d\n", instance, index, value); + } +} + +static void +ahd_linux_setup_tag_info_global(char *p) +{ + int tags, i, j; + + tags = simple_strtoul(p + 1, NULL, 0) & 0xff; + printf("Setting Global Tags= %d\n", tags); + + for (i = 0; i < NUM_ELEMENTS(aic79xx_tag_info); i++) { + for (j = 0; j < AHD_NUM_TARGETS; j++) { + aic79xx_tag_info[i].tag_commands[j] = tags; + } + } +} + +/* + * Handle Linux boot parameters. This routine allows for assigning a value + * to a parameter with a ':' between the parameter and the value. + * ie. aic79xx=stpwlev:1,extended + */ +static int +aic79xx_setup(char *s) +{ + int i, n; + char *p; + char *end; + + static struct { + const char *name; + uint32_t *flag; + } options[] = { + { "extended", &aic79xx_extended }, + { "no_reset", &aic79xx_no_reset }, + { "verbose", &aic79xx_verbose }, + { "allow_memio", &aic79xx_allow_memio}, +#ifdef AHD_DEBUG + { "debug", &ahd_debug }, +#endif + { "reverse_scan", &aic79xx_reverse_scan }, + { "periodic_otag", &aic79xx_periodic_otag }, + { "pci_parity", &aic79xx_pci_parity }, + { "seltime", &aic79xx_seltime }, + { "tag_info", NULL }, + { "global_tag_depth", NULL}, + { "rd_strm", NULL }, + { "dv", NULL }, + { "slewrate", NULL }, + { "precomp", NULL }, + { "amplitude", NULL }, + }; + + end = strchr(s, '\0'); + + /* + * XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS + * will never be 0 in this case. + */ + n = 0; + + while ((p = strsep(&s, ",.")) != NULL) { + if (*p == '\0') + continue; + for (i = 0; i < NUM_ELEMENTS(options); i++) { + + n = strlen(options[i].name); + if (strncmp(options[i].name, p, n) == 0) + break; + } + if (i == NUM_ELEMENTS(options)) + continue; + + if (strncmp(p, "global_tag_depth", n) == 0) { + ahd_linux_setup_tag_info_global(p + n); + } else if (strncmp(p, "tag_info", n) == 0) { + s = aic_parse_brace_option("tag_info", p + n, end, + 2, ahd_linux_setup_tag_info, 0); + } else if (strncmp(p, "rd_strm", n) == 0) { + s = aic_parse_brace_option("rd_strm", p + n, end, + 1, ahd_linux_setup_rd_strm_info, 0); + } else if (strncmp(p, "dv", n) == 0) { + s = aic_parse_brace_option("dv", p + n, end, 1, + ahd_linux_setup_dv, 0); + } else if (strncmp(p, "slewrate", n) == 0) { + s = aic_parse_brace_option("slewrate", + p + n, end, 1, ahd_linux_setup_iocell_info, + AIC79XX_SLEWRATE_INDEX); + } else if (strncmp(p, "precomp", n) == 0) { + s = aic_parse_brace_option("precomp", + p + n, end, 1, ahd_linux_setup_iocell_info, + AIC79XX_PRECOMP_INDEX); + } else if (strncmp(p, "amplitude", n) == 0) { + s = aic_parse_brace_option("amplitude", + p + n, end, 1, ahd_linux_setup_iocell_info, + AIC79XX_AMPLITUDE_INDEX); + } else if (p[n] == ':') { + *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); + } else if (!strncmp(p, "verbose", n)) { + *(options[i].flag) = 1; + } else { + *(options[i].flag) ^= 0xFFFFFFFF; + } + } + return 1; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) +__setup("aic79xx=", aic79xx_setup); +#endif + +uint32_t aic79xx_verbose; + +int +ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) +{ + char buf[80]; + struct Scsi_Host *host; + char *new_name; + u_long s; + u_long target; + + template->name = ahd->description; + host = scsi_register(template, sizeof(struct ahd_softc *)); + if (host == NULL) + return (ENOMEM); + + *((struct ahd_softc **)host->hostdata) = ahd; + ahd_lock(ahd, &s); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_assign_lock(host, &ahd->platform_data->spin_lock); +#elif AHD_SCSI_HAS_HOST_LOCK != 0 + host->lock = &ahd->platform_data->spin_lock; +#endif + ahd->platform_data->host = host; + host->can_queue = AHD_MAX_QUEUE; + host->cmd_per_lun = 2; + host->sg_tablesize = AHD_NSEG; + host->this_id = ahd->our_id; + host->irq = ahd->platform_data->irq; + host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8; + host->max_lun = AHD_NUM_LUNS; + host->max_channel = 0; + host->sg_tablesize = AHD_NSEG; + ahd_set_unit(ahd, ahd_linux_next_unit()); + sprintf(buf, "scsi%d", host->host_no); + new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); + if (new_name != NULL) { + strcpy(new_name, buf); + ahd_set_name(ahd, new_name); + } + host->unique_id = ahd->unit; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + scsi_set_pci_device(host, ahd->dev_softc); +#endif + ahd_linux_setup_user_rd_strm_settings(ahd); + ahd_linux_initialize_scsi_bus(ahd); + ahd_unlock(ahd, &s); + ahd->platform_data->dv_pid = kernel_thread(ahd_linux_dv_thread, ahd, 0); + ahd_lock(ahd, &s); + if (ahd->platform_data->dv_pid < 0) { + printf("%s: Failed to create DV thread, error= %d\n", + ahd_name(ahd), ahd->platform_data->dv_pid); + return (-ahd->platform_data->dv_pid); + } + /* + * Initially allocate *all* of our linux target objects + * so that the DV thread will scan them all in parallel + * just after driver initialization. Any device that + * does not exist will have its target object destroyed + * by the selection timeout handler. In the case of a + * device that appears after the initial DV scan, async + * negotiation will occur for the first command, and DV + * will comence should that first command be successful. + */ + for (target = 0; target < host->max_id; target++) { + + /* + * Skip our own ID. Some Compaq/HP storage devices + * have enclosure management devices that respond to + * single bit selection (i.e. selecting ourselves). + * It is expected that either an external application + * or a modified kernel will be used to probe this + * ID if it is appropriate. To accommodate these + * installations, ahc_linux_alloc_target() will allocate + * for our ID if asked to do so. + */ + if (target == ahd->our_id) + continue; + + ahd_linux_alloc_target(ahd, 0, target); + } + ahd_intr_enable(ahd, TRUE); + ahd_linux_start_dv(ahd); + ahd_unlock(ahd, &s); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_add_host(host, &ahd->dev_softc->dev); +#endif + return (0); +} + +uint64_t +ahd_linux_get_memsize(void) +{ + struct sysinfo si; + + si_meminfo(&si); + return ((uint64_t)si.totalram << PAGE_SHIFT); +} + +/* + * Find the smallest available unit number to use + * for a new device. We don't just use a static + * count to handle the "repeated hot-(un)plug" + * scenario. + */ +static int +ahd_linux_next_unit(void) +{ + struct ahd_softc *ahd; + int unit; + + unit = 0; +retry: + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + if (ahd->unit == unit) { + unit++; + goto retry; + } + } + return (unit); +} + +/* + * Place the SCSI bus into a known state by either resetting it, + * or forcing transfer negotiations on the next command to any + * target. + */ +static void +ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd) +{ + u_int target_id; + u_int numtarg; + + target_id = 0; + numtarg = 0; + + if (aic79xx_no_reset != 0) + ahd->flags &= ~AHD_RESET_BUS_A; + + if ((ahd->flags & AHD_RESET_BUS_A) != 0) + ahd_reset_channel(ahd, 'A', /*initiate_reset*/TRUE); + else + numtarg = (ahd->features & AHD_WIDE) ? 16 : 8; + + /* + * Force negotiation to async for all targets that + * will not see an initial bus reset. + */ + for (; target_id < numtarg; target_id++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + target_id, &tstate); + ahd_compile_devinfo(&devinfo, ahd->our_id, target_id, + CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR); + ahd_update_neg_request(ahd, &devinfo, tstate, + tinfo, AHD_NEG_ALWAYS); + } + /* Give the bus some time to recover */ + if ((ahd->flags & AHD_RESET_BUS_A) != 0) { + ahd_freeze_simq(ahd); + init_timer(&ahd->platform_data->reset_timer); + ahd->platform_data->reset_timer.data = (u_long)ahd; + ahd->platform_data->reset_timer.expires = + jiffies + (AIC79XX_RESET_DELAY * HZ)/1000; + ahd->platform_data->reset_timer.function = + (ahd_linux_callback_t *)ahd_release_simq; + add_timer(&ahd->platform_data->reset_timer); + } +} + +int +ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) +{ + ahd->platform_data = + malloc(sizeof(struct ahd_platform_data), M_DEVBUF, M_NOWAIT); + if (ahd->platform_data == NULL) + return (ENOMEM); + memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); + TAILQ_INIT(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->device_runq); + ahd->platform_data->irq = AHD_LINUX_NOIRQ; + ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; + ahd_lockinit(ahd); + ahd_done_lockinit(ahd); + init_timer(&ahd->platform_data->completeq_timer); + ahd->platform_data->completeq_timer.data = (u_long)ahd; + ahd->platform_data->completeq_timer.function = + (ahd_linux_callback_t *)ahd_linux_thread_run_complete_queue; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + init_MUTEX_LOCKED(&ahd->platform_data->eh_sem); + init_MUTEX_LOCKED(&ahd->platform_data->dv_sem); + init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem); +#else + ahd->platform_data->eh_sem = MUTEX_LOCKED; + ahd->platform_data->dv_sem = MUTEX_LOCKED; + ahd->platform_data->dv_cmd_sem = MUTEX_LOCKED; +#endif + ahd_setup_runq_tasklet(ahd); + ahd->seltime = (aic79xx_seltime & 0x3) << 4; + return (0); +} + +void +ahd_platform_free(struct ahd_softc *ahd) +{ + struct ahd_linux_target *targ; + struct ahd_linux_device *dev; + int i, j; + + if (ahd->platform_data != NULL) { + del_timer_sync(&ahd->platform_data->completeq_timer); + ahd_linux_kill_dv_thread(ahd); + ahd_teardown_runq_tasklet(ahd); + if (ahd->platform_data->host != NULL) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_remove_host(ahd->platform_data->host); +#endif + scsi_unregister(ahd->platform_data->host); + } + + /* destroy all of the device and target objects */ + for (i = 0; i < AHD_NUM_TARGETS; i++) { + targ = ahd->platform_data->targets[i]; + if (targ != NULL) { + /* Keep target around through the loop. */ + targ->refcount++; + for (j = 0; j < AHD_NUM_LUNS; j++) { + + if (targ->devices[j] == NULL) + continue; + dev = targ->devices[j]; + ahd_linux_free_device(ahd, dev); + } + /* + * Forcibly free the target now that + * all devices are gone. + */ + ahd_linux_free_target(ahd, targ); + } + } + + if (ahd->platform_data->irq != AHD_LINUX_NOIRQ) + free_irq(ahd->platform_data->irq, ahd); + if (ahd->tags[0] == BUS_SPACE_PIO + && ahd->bshs[0].ioport != 0) + release_region(ahd->bshs[0].ioport, 256); + if (ahd->tags[1] == BUS_SPACE_PIO + && ahd->bshs[1].ioport != 0) + release_region(ahd->bshs[1].ioport, 256); + if (ahd->tags[0] == BUS_SPACE_MEMIO + && ahd->bshs[0].maddr != NULL) { + u_long base_addr; + + base_addr = (u_long)ahd->bshs[0].maddr; + base_addr &= PAGE_MASK; + iounmap((void *)base_addr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(ahd->platform_data->mem_busaddr, + 0x1000); +#endif + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * In 2.4 we detach from the scsi midlayer before the PCI + * layer invokes our remove callback. No per-instance + * detach is provided, so we must reach inside the PCI + * subsystem's internals and detach our driver manually. + */ + if (ahd->dev_softc != NULL) + ahd->dev_softc->driver = NULL; +#endif + free(ahd->platform_data, M_DEVBUF); + } +} + +void +ahd_platform_init(struct ahd_softc *ahd) +{ + /* + * Lookup and commit any modified IO Cell options. + */ + if (ahd->unit < NUM_ELEMENTS(aic79xx_iocell_info)) { + struct ahd_linux_iocell_opts *iocell_opts; + + iocell_opts = &aic79xx_iocell_info[ahd->unit]; + if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP) + AHD_SET_PRECOMP(ahd, iocell_opts->precomp); + if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE) + AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate); + if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE) + AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude); + } + +} + +void +ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb) +{ + ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), SCB_LIST_NULL, + ROLE_UNKNOWN, CAM_REQUEUE_REQ); +} + +void +ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, + ahd_queue_alg alg) +{ + struct ahd_linux_device *dev; + int was_queuing; + int now_queuing; + + dev = ahd_linux_get_device(ahd, devinfo->channel - 'A', + devinfo->target, + devinfo->lun, /*alloc*/FALSE); + if (dev == NULL) + return; + was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED); + switch (alg) { + default: + case AHD_QUEUE_NONE: + now_queuing = 0; + break; + case AHD_QUEUE_BASIC: + now_queuing = AHD_DEV_Q_BASIC; + break; + case AHD_QUEUE_TAGGED: + now_queuing = AHD_DEV_Q_TAGGED; + break; + } + if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0 + && (was_queuing != now_queuing) + && (dev->active != 0)) { + dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY; + dev->qfrozen++; + } + + dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG); + if (now_queuing) { + u_int usertags; + + usertags = ahd_linux_user_tagdepth(ahd, devinfo); + if (!was_queuing) { + /* + * Start out agressively and allow our + * dynamic queue depth algorithm to take + * care of the rest. + */ + dev->maxtags = usertags; + dev->openings = dev->maxtags - dev->active; + } + if (dev->maxtags == 0) { + /* + * Queueing is disabled by the user. + */ + dev->openings = 1; + } else if (alg == AHD_QUEUE_TAGGED) { + dev->flags |= AHD_DEV_Q_TAGGED; + if (aic79xx_periodic_otag != 0) + dev->flags |= AHD_DEV_PERIODIC_OTAG; + } else + dev->flags |= AHD_DEV_Q_BASIC; + } else { + /* We can only have one opening. */ + dev->maxtags = 0; + dev->openings = 1 - dev->active; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (dev->scsi_device != NULL) { + switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { + case AHD_DEV_Q_BASIC: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_SIMPLE_TASK, + dev->openings + dev->active); + break; + case AHD_DEV_Q_TAGGED: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_ORDERED_TASK, + dev->openings + dev->active); + break; + default: + /* + * We allow the OS to queue 2 untagged transactions to + * us at any time even though we can only execute them + * serially on the controller/device. This should + * remove some latency. + */ + scsi_adjust_queue_depth(dev->scsi_device, + /*NON-TAGGED*/0, + /*queue depth*/2); + break; + } + } +#endif +} + +int +ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status) +{ + int targ; + int maxtarg; + int maxlun; + int clun; + int count; + + if (tag != SCB_LIST_NULL) + return (0); + + targ = 0; + if (target != CAM_TARGET_WILDCARD) { + targ = target; + maxtarg = targ + 1; + } else { + maxtarg = (ahd->features & AHD_WIDE) ? 16 : 8; + } + clun = 0; + if (lun != CAM_LUN_WILDCARD) { + clun = lun; + maxlun = clun + 1; + } else { + maxlun = AHD_NUM_LUNS; + } + + count = 0; + for (; targ < maxtarg; targ++) { + + for (; clun < maxlun; clun++) { + struct ahd_linux_device *dev; + struct ahd_busyq *busyq; + struct ahd_cmd *acmd; + + dev = ahd_linux_get_device(ahd, /*chan*/0, targ, + clun, /*alloc*/FALSE); + if (dev == NULL) + continue; + + busyq = &dev->busyq; + while ((acmd = TAILQ_FIRST(busyq)) != NULL) { + Scsi_Cmnd *cmd; + + cmd = &acmd_scsi_cmd(acmd); + TAILQ_REMOVE(busyq, acmd, + acmd_links.tqe); + count++; + cmd->result = status << 16; + ahd_linux_queue_cmd_complete(ahd, cmd); + } + } + } + + return (count); +} + +static void +ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd) +{ + u_long flags; + + ahd_lock(ahd, &flags); + del_timer(&ahd->platform_data->completeq_timer); + ahd->platform_data->flags &= ~AHD_RUN_CMPLT_Q_TIMER; + ahd_linux_run_complete_queue(ahd); + ahd_unlock(ahd, &flags); +} + +static void +ahd_linux_start_dv(struct ahd_softc *ahd) +{ + + /* + * Freeze the simq and signal ahd_linux_queue to not let any + * more commands through + */ + if ((ahd->platform_data->flags & AHD_DV_ACTIVE) == 0) { +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s: Starting DV\n", ahd_name(ahd)); +#endif + + ahd->platform_data->flags |= AHD_DV_ACTIVE; + ahd_freeze_simq(ahd); + + /* Wake up the DV kthread */ + up(&ahd->platform_data->dv_sem); + } +} + +static int +ahd_linux_dv_thread(void *data) +{ + struct ahd_softc *ahd; + int target; + u_long s; + + ahd = (struct ahd_softc *)data; + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("In DV Thread\n"); +#endif + + /* + * Complete thread creation. + */ + lock_kernel(); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60) + /* + * Don't care about any signals. + */ + siginitsetinv(¤t->blocked, 0); + + daemonize(); + sprintf(current->comm, "ahd_dv_%d", ahd->unit); +#else + daemonize("ahd_dv_%d", ahd->unit); +#endif + unlock_kernel(); + + while (1) { + /* + * Use down_interruptible() rather than down() to + * avoid inclusion in the load average. + */ + down_interruptible(&ahd->platform_data->dv_sem); + + /* Check to see if we've been signaled to exit */ + ahd_lock(ahd, &s); + if ((ahd->platform_data->flags & AHD_DV_SHUTDOWN) != 0) { + ahd_unlock(ahd, &s); + break; + } + ahd_unlock(ahd, &s); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s: Beginning Domain Validation\n", + ahd_name(ahd)); +#endif + + /* + * Wait for any pending commands to drain before proceeding. + */ + ahd_lock(ahd, &s); + while (LIST_FIRST(&ahd->pending_scbs) != NULL) { + ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_EMPTY; + ahd_unlock(ahd, &s); + down_interruptible(&ahd->platform_data->dv_sem); + ahd_lock(ahd, &s); + } + + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + while (AHD_DV_SIMQ_FROZEN(ahd) == 0) { + ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE; + ahd_unlock(ahd, &s); + down_interruptible(&ahd->platform_data->dv_sem); + ahd_lock(ahd, &s); + } + ahd_unlock(ahd, &s); + + for (target = 0; target < AHD_NUM_TARGETS; target++) + ahd_linux_dv_target(ahd, target); + + ahd_lock(ahd, &s); + ahd->platform_data->flags &= ~AHD_DV_ACTIVE; + ahd_unlock(ahd, &s); + + /* + * Release the SIMQ so that normal commands are + * allowed to continue on the bus. + */ + ahd_release_simq(ahd); + } + up(&ahd->platform_data->eh_sem); + return (0); +} + +static void +ahd_linux_kill_dv_thread(struct ahd_softc *ahd) +{ + u_long s; + + ahd_lock(ahd, &s); + if (ahd->platform_data->dv_pid != 0) { + ahd->platform_data->flags |= AHD_DV_SHUTDOWN; + ahd_unlock(ahd, &s); + up(&ahd->platform_data->dv_sem); + + /* + * Use the eh_sem as an indicator that the + * dv thread is exiting. Note that the dv + * thread must still return after performing + * the up on our semaphore before it has + * completely exited this module. Unfortunately, + * there seems to be no easy way to wait for the + * exit of a thread for which you are not the + * parent (dv threads are parented by init). + * Cross your fingers... + */ + down(&ahd->platform_data->eh_sem); + + /* + * Mark the dv thread as already dead. This + * avoids attempting to kill it a second time. + * This is necessary because we must kill the + * DV thread before calling ahd_free() in the + * module shutdown case to avoid bogus locking + * in the SCSI mid-layer, but we ahd_free() is + * called without killing the DV thread in the + * instance detach case, so ahd_platform_free() + * calls us again to verify that the DV thread + * is dead. + */ + ahd->platform_data->dv_pid = 0; + } else { + ahd_unlock(ahd, &s); + } +} + +#define AHD_LINUX_DV_INQ_SHORT_LEN 36 +#define AHD_LINUX_DV_INQ_LEN 256 +#define AHD_LINUX_DV_TIMEOUT (HZ / 4) + +#define AHD_SET_DV_STATE(ahd, targ, newstate) \ + ahd_set_dv_state(ahd, targ, newstate, __LINE__) + +static __inline void +ahd_set_dv_state(struct ahd_softc *ahd, struct ahd_linux_target *targ, + ahd_dv_state newstate, u_int line) +{ + ahd_dv_state oldstate; + + oldstate = targ->dv_state; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s:%d: Going from state %d to state %d\n", + ahd_name(ahd), line, oldstate, newstate); +#endif + + if (oldstate == newstate) + targ->dv_state_retry++; + else + targ->dv_state_retry = 0; + targ->dv_state = newstate; +} + +static void +ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset) +{ + struct ahd_devinfo devinfo; + struct ahd_linux_target *targ; + struct scsi_cmnd *cmd; + struct scsi_device *scsi_dev; + struct scsi_sense_data *sense; + uint8_t *buffer; + u_long s; + u_int timeout; + int echo_size; + + sense = NULL; + buffer = NULL; + echo_size = 0; + ahd_lock(ahd, &s); + targ = ahd->platform_data->targets[target_offset]; + if (targ == NULL || (targ->flags & AHD_DV_REQUIRED) == 0) { + ahd_unlock(ahd, &s); + return; + } + ahd_compile_devinfo(&devinfo, ahd->our_id, targ->target, /*lun*/0, + targ->channel + 'A', ROLE_INITIATOR); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, &devinfo); + printf("Performing DV\n"); + } +#endif + + ahd_unlock(ahd, &s); + + cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK); + scsi_dev->host = ahd->platform_data->host; + scsi_dev->id = devinfo.target; + scsi_dev->lun = devinfo.lun; + scsi_dev->channel = devinfo.channel - 'A'; + ahd->platform_data->dv_scsi_dev = scsi_dev; + + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_SHORT_ASYNC); + + while (targ->dv_state != AHD_DV_STATE_EXIT) { + timeout = AHD_LINUX_DV_TIMEOUT; + switch (targ->dv_state) { + case AHD_DV_STATE_INQ_SHORT_ASYNC: + case AHD_DV_STATE_INQ_ASYNC: + case AHD_DV_STATE_INQ_ASYNC_VERIFY: + /* + * Set things to async narrow to reduce the + * chance that the INQ will fail. + */ + ahd_lock(ahd, &s); + ahd_set_syncrate(ahd, &devinfo, 0, 0, 0, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_unlock(ahd, &s); + timeout = 10 * HZ; + targ->flags &= ~AHD_INQ_VALID; + /* FALLTHROUGH */ + case AHD_DV_STATE_INQ_VERIFY: + { + u_int inq_len; + + if (targ->dv_state == AHD_DV_STATE_INQ_SHORT_ASYNC) + inq_len = AHD_LINUX_DV_INQ_SHORT_LEN; + else + inq_len = targ->inq_data->additional_length + 5; + ahd_linux_dv_inq(ahd, cmd, &devinfo, targ, inq_len); + break; + } + case AHD_DV_STATE_TUR: + case AHD_DV_STATE_BUSY: + timeout = 5 * HZ; + ahd_linux_dv_tur(ahd, cmd, &devinfo); + break; + case AHD_DV_STATE_REBD: + ahd_linux_dv_rebd(ahd, cmd, &devinfo, targ); + break; + case AHD_DV_STATE_WEB: + ahd_linux_dv_web(ahd, cmd, &devinfo, targ); + break; + + case AHD_DV_STATE_REB: + ahd_linux_dv_reb(ahd, cmd, &devinfo, targ); + break; + + case AHD_DV_STATE_SU: + ahd_linux_dv_su(ahd, cmd, &devinfo, targ); + timeout = 50 * HZ; + break; + + default: + ahd_print_devinfo(ahd, &devinfo); + printf("Unknown DV state %d\n", targ->dv_state); + goto out; + } + + /* Queue the command and wait for it to complete */ + /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */ + init_timer(&cmd->eh_timeout); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) + /* + * All of the printfs during negotiation + * really slow down the negotiation. + * Add a bit of time just to be safe. + */ + timeout += HZ; +#endif + scsi_add_timer(cmd, timeout, ahd_linux_dv_timeout); + /* + * In 2.5.X, it is assumed that all calls from the + * "midlayer" (which we are emulating) will have the + * ahd host lock held. For other kernels, the + * io_request_lock must be held. + */ +#if AHD_SCSI_HAS_HOST_LOCK != 0 + ahd_lock(ahd, &s); +#else + spin_lock_irqsave(&io_request_lock, s); +#endif + ahd_linux_queue(cmd, ahd_linux_dv_complete); +#if AHD_SCSI_HAS_HOST_LOCK != 0 + ahd_unlock(ahd, &s); +#else + spin_unlock_irqrestore(&io_request_lock, s); +#endif + down_interruptible(&ahd->platform_data->dv_cmd_sem); + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + ahd_lock(ahd, &s); + while (AHD_DV_SIMQ_FROZEN(ahd) == 0) { + ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE; + ahd_unlock(ahd, &s); + down_interruptible(&ahd->platform_data->dv_sem); + ahd_lock(ahd, &s); + } + ahd_unlock(ahd, &s); + + ahd_linux_dv_transition(ahd, cmd, &devinfo, targ); + } + +out: + if ((targ->flags & AHD_INQ_VALID) != 0 + && ahd_linux_get_device(ahd, devinfo.channel - 'A', + devinfo.target, devinfo.lun, + /*alloc*/FALSE) == NULL) { + /* + * The DV state machine failed to configure this device. + * This is normal if DV is disabled. Since we have inquiry + * data, filter it and use the "optimistic" negotiation + * parameters found in the inquiry string. + */ + ahd_linux_filter_inquiry(ahd, &devinfo); + if ((targ->flags & (AHD_BASIC_DV|AHD_ENHANCED_DV)) != 0) { + ahd_print_devinfo(ahd, &devinfo); + printf("DV failed to configure device. " + "Please file a bug report against " + "this driver.\n"); + } + } + + if (cmd != NULL) + free(cmd, M_DEVBUF); + + if (ahd->platform_data->dv_scsi_dev != NULL) { + free(ahd->platform_data->dv_scsi_dev, M_DEVBUF); + ahd->platform_data->dv_scsi_dev = NULL; + } + + ahd_lock(ahd, &s); + if (targ->dv_buffer != NULL) { + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = NULL; + } + if (targ->dv_buffer1 != NULL) { + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = NULL; + } + targ->flags &= ~AHD_DV_REQUIRED; + if (targ->refcount == 0) + ahd_linux_free_target(ahd, targ); + ahd_unlock(ahd, &s); +} + +static void +ahd_linux_dv_transition(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ) +{ + u_int32_t status; + + status = aic_error_action(cmd, targ->inq_data, + ahd_cmd_get_transaction_status(cmd), + ahd_cmd_get_scsi_status(cmd)); + + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Entering ahd_linux_dv_transition, state= %d, " + "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state, + status, cmd->result); + } +#endif + + switch (targ->dv_state) { + case AHD_DV_STATE_INQ_SHORT_ASYNC: + case AHD_DV_STATE_INQ_ASYNC: + switch (status & SS_MASK) { + case SS_NOP: + { + AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1); + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if ((status & SS_ERRMASK) == EBUSY) + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHD_DV_STATE_INQ_ASYNC_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + u_int xportflags; + u_int spi3data; + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHD_LINUX_DV_INQ_LEN) != 0) { + /* + * Inquiry data must have changed. + * Try from the top again. + */ + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + } + + AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1); + targ->flags |= AHD_INQ_VALID; + if (ahd_linux_user_dv_setting(ahd) == 0) + break; + + xportflags = targ->inq_data->flags; + if ((xportflags & (SID_Sync|SID_WBus16)) == 0) + break; + + spi3data = targ->inq_data->spi3data; + switch (spi3data & SID_SPI_CLOCK_DT_ST) { + default: + case SID_SPI_CLOCK_ST: + /* Assume only basic DV is supported. */ + targ->flags |= AHD_BASIC_DV; + break; + case SID_SPI_CLOCK_DT: + case SID_SPI_CLOCK_DT_ST: + targ->flags |= AHD_ENHANCED_DV; + break; + } + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + + if ((status & SS_ERRMASK) == EBUSY) + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHD_DV_STATE_INQ_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHD_LINUX_DV_INQ_LEN) == 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + int i; + + ahd_print_devinfo(ahd, devinfo); + printf("Inquiry buffer mismatch:"); + for (i = 0; i < AHD_LINUX_DV_INQ_LEN; i++) { + if ((i & 0xF) == 0) + printf("\n "); + printf("0x%x:0x0%x ", + ((uint8_t *)targ->inq_data)[i], + targ->dv_buffer[i]); + } + printf("\n"); + } +#endif + + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } else if ((status & SS_ERRMASK) == EBUSY) + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + + case AHD_DV_STATE_TUR: + switch (status & SS_MASK) { + case SS_NOP: + if ((targ->flags & AHD_BASIC_DV) != 0) { + ahd_linux_filter_inquiry(ahd, devinfo); + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_VERIFY); + } else if ((targ->flags & AHD_ENHANCED_DV) != 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REBD); + } else { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + } + break; + case SS_RETRY: + case SS_TUR: + if ((status & SS_ERRMASK) == EBUSY) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY); + break; + } + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry >= 10) { +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV TUR reties exhausted\n"); + } +#endif + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + if (status & SSQ_DELAY) + scsi_sleep(1 * HZ); + + break; + case SS_START: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_SU); + break; + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_REBD: + switch (status & SS_MASK) { + case SS_NOP: + { + uint32_t echo_size; + + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB); + echo_size = scsi_3btoul(&targ->dv_buffer[1]); + echo_size &= 0x1FFF; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Echo buffer size= %d\n", echo_size); + } +#endif + if (echo_size == 0) { + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + + /* Generate the buffer pattern */ + targ->dv_echo_size = echo_size; + ahd_linux_generate_dv_pattern(targ); + /* + * Setup initial negotiation values. + */ + ahd_linux_filter_inquiry(ahd, devinfo); + break; + } + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if (targ->dv_state_retry <= 10) + break; +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV REBD reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + case SS_FATAL: + default: + /* + * Setup initial negotiation values + * and try level 1 DV. + */ + ahd_linux_filter_inquiry(ahd, devinfo); + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_VERIFY); + targ->dv_echo_size = 0; + break; + } + break; + + case AHD_DV_STATE_WEB: + switch (status & SS_MASK) { + case SS_NOP: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REB); + break; + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry <= 10) + break; + /* FALLTHROUGH */ +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV WEB reties exhausted\n"); + } +#endif + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_REB: + switch (status & SS_MASK) { + case SS_NOP: + if (memcmp(targ->dv_buffer, targ->dv_buffer1, + targ->dv_echo_size) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + else + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_WEB); + break; + } + + if (targ->dv_buffer != NULL) { + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = NULL; + } + if (targ->dv_buffer1 != NULL) { + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = NULL; + } + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahd_linux_dv_fallback(ahd, devinfo) != 0) { + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_EXIT); + break; + } + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB); + } + if (targ->dv_state_retry <= 10) { + if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0) + scsi_sleep(ahd->our_id*HZ/10); + break; + } +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV REB reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_SU: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + case AHD_DV_STATE_BUSY: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHD_SET_DV_STATE(ahd, targ, + AHD_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHD_SET_DV_STATE(ahd, targ, targ->dv_state); + if (ahd_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if (targ->dv_state_retry < 60) { + if ((status & SSQ_DELAY) != 0) + scsi_sleep(1 * HZ); + } else { +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("DV BUSY reties exhausted\n"); + } +#endif + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + } + break; + default: + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } + break; + + default: + printf("%s: Invalid DV completion state %d\n", ahd_name(ahd), + targ->dv_state); + AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT); + break; + } +} + +static void +ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo) +{ + memset(cmd, 0, sizeof(struct scsi_cmnd)); + cmd->device = ahd->platform_data->dv_scsi_dev; + cmd->scsi_done = ahd_linux_dv_complete; +} + +/* + * Synthesize an inquiry command. On the return trip, it'll be + * sniffed and the device transfer settings set for us. + */ +static void +ahd_linux_dv_inq(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ, + u_int request_length) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending INQ\n"); + } +#endif + if (targ->inq_data == NULL) + targ->inq_data = malloc(AHD_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) { + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHD_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + } + + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 6; + cmd->cmnd[0] = INQUIRY; + cmd->cmnd[4] = request_length; + cmd->request_bufflen = request_length; + if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) + cmd->request_buffer = targ->dv_buffer; + else + cmd->request_buffer = targ->inq_data; + memset(cmd->request_buffer, 0, AHD_LINUX_DV_INQ_LEN); +} + +static void +ahd_linux_dv_tur(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending TUR\n"); + } +#endif + /* Do a TUR to clear out any non-fatal transitional state */ + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = TEST_UNIT_READY; +} + +#define AHD_REBD_LEN 4 + +static void +ahd_linux_dv_rebd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending REBD\n"); + } +#endif + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHD_REBD_LEN, M_DEVBUF, M_WAITOK); + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0b; + scsi_ulto3b(AHD_REBD_LEN, &cmd->cmnd[6]); + cmd->request_bufflen = AHD_REBD_LEN; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; +} + +static void +ahd_linux_dv_web(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending WEB\n"); + } +#endif + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_WRITE; + cmd->cmd_len = 10; + cmd->cmnd[0] = WRITE_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; +} + +static void +ahd_linux_dv_reb(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) +{ + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending REB\n"); + } +#endif + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer1; +} + +static void +ahd_linux_dv_su(struct ahd_softc *ahd, struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + struct ahd_linux_target *targ) +{ + u_int le; + + le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0; + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Sending SU\n"); + } +#endif + ahd_linux_dv_fill_cmd(ahd, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = START_STOP_UNIT; + cmd->cmnd[4] = le | SSS_START; +} + +static __inline int +ahd_linux_dv_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + u_long s; + int retval; + + ahd_lock(ahd, &s); + retval = ahd_linux_fallback(ahd, devinfo); + ahd_unlock(ahd, &s); + + return (retval); +} + +static int +ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct ahd_linux_target *targ; + struct ahd_initiator_tinfo *tinfo; + struct ahd_transinfo *goal; + struct ahd_tmode_tstate *tstate; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int cur_speed; + u_int wide_speed; + u_int narrow_speed; + u_int fallback_speed; + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + ahd_print_devinfo(ahd, devinfo); + printf("Trying to fallback\n"); + } +#endif + targ = ahd->platform_data->targets[devinfo->target_offset]; + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + goal = &tinfo->goal; + width = goal->width; + period = goal->period; + offset = goal->offset; + ppr_options = goal->ppr_options; + if (offset == 0) + period = AHD_ASYNC_XFER_PERIOD; + if (targ->dv_next_narrow_period == 0) + targ->dv_next_narrow_period = MAX(period, AHD_SYNCRATE_ULTRA2); + if (targ->dv_next_wide_period == 0) + targ->dv_next_wide_period = period; + if (targ->dv_max_width == 0) + targ->dv_max_width = width; + if (targ->dv_max_ppr_options == 0) + targ->dv_max_ppr_options = ppr_options; + if (targ->dv_last_ppr_options == 0) + targ->dv_last_ppr_options = ppr_options; + + cur_speed = aic_calc_speed(width, period, offset, AHD_SYNCRATE_MIN); + wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, + targ->dv_next_wide_period, + MAX_OFFSET, AHD_SYNCRATE_MIN); + narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, + targ->dv_next_narrow_period, + MAX_OFFSET, AHD_SYNCRATE_MIN); + fallback_speed = aic_calc_speed(width, period+1, offset, + AHD_SYNCRATE_MIN); +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, " + "fallback_speed= %d\n", cur_speed, wide_speed, + narrow_speed, fallback_speed); + } +#endif + + if (cur_speed > 160000) { + /* + * Paced/DT/IU_REQ only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + } else if (cur_speed > 80000) { + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + /* + * Try without IU_REQ as it may be confusing + * an expander. + */ + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else { + /* + * Paced/DT only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + ppr_options = targ->dv_max_ppr_options; + } + } else if (cur_speed > 3300) { + + /* + * In this range we the following + * options ordered from highest to + * lowest desireability: + * + * o Wide/DT + * o Wide/non-DT + * o Narrow at a potentally higher sync rate. + * + * All modes are tested with and without IU_REQ + * set since using IUs may confuse an expander. + */ + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { + /* + * Try going non-DT. + */ + ppr_options = targ->dv_max_ppr_options; + ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } else if (targ->dv_last_ppr_options != 0) { + /* + * Try without QAS or any other PPR options. + * We may need a non-PPR message to work with + * an expander. We look at the "last PPR options" + * so we will perform this fallback even if the + * target responded to our PPR negotiation with + * no option bits set. + */ + ppr_options = 0; + } else if (width == MSG_EXT_WDTR_BUS_16_BIT) { + /* + * If the next narrow speed is greater than + * the next wide speed, fallback to narrow. + * Otherwise fallback to the next DT/Wide setting. + * The narrow async speed will always be smaller + * than the wide async speed, so handle this case + * specifically. + */ + ppr_options = targ->dv_max_ppr_options; + if (narrow_speed > fallback_speed + || period >= AHD_ASYNC_XFER_PERIOD) { + targ->dv_next_wide_period = period+1; + width = MSG_EXT_WDTR_BUS_8_BIT; + period = targ->dv_next_narrow_period; + } else { + period++; + } + } else if ((ahd->features & AHD_WIDE) != 0 + && targ->dv_max_width != 0 + && wide_speed >= fallback_speed + && (targ->dv_next_wide_period <= AHD_ASYNC_XFER_PERIOD + || period >= AHD_ASYNC_XFER_PERIOD)) { + + /* + * We are narrow. Try falling back + * to the next wide speed with + * all supported ppr options set. + */ + targ->dv_next_narrow_period = period+1; + width = MSG_EXT_WDTR_BUS_16_BIT; + period = targ->dv_next_wide_period; + ppr_options = targ->dv_max_ppr_options; + } else { + /* Only narrow fallback is allowed. */ + period++; + ppr_options = targ->dv_max_ppr_options; + } + } else { + return (-1); + } + offset = MAX_OFFSET; + ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_PACED); + ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, FALSE); + if (period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + if (width == MSG_EXT_WDTR_BUS_8_BIT) + targ->dv_next_narrow_period = AHD_ASYNC_XFER_PERIOD; + else + targ->dv_next_wide_period = AHD_ASYNC_XFER_PERIOD; + } + ahd_set_syncrate(ahd, devinfo, period, offset, + ppr_options, AHD_TRANS_GOAL, FALSE); + targ->dv_last_ppr_options = ppr_options; + return (0); +} + +static void +ahd_linux_dv_timeout(struct scsi_cmnd *cmd) +{ + struct ahd_softc *ahd; + struct scb *scb; + u_long flags; + + ahd = *((struct ahd_softc **)cmd->device->host->hostdata); + ahd_lock(ahd, &flags); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) { + printf("%s: Timeout while doing DV command %x.\n", + ahd_name(ahd), cmd->cmnd[0]); + ahd_dump_card_state(ahd); + } +#endif + + /* + * Guard against "done race". No action is + * required if we just completed. + */ + if ((scb = (struct scb *)cmd->host_scribble) == NULL) { + ahd_unlock(ahd, &flags); + return; + } + + /* + * Command has not completed. Mark this + * SCB as having failing status prior to + * resetting the bus, so we get the correct + * error code. + */ + if ((scb->flags & SCB_SENSE) != 0) + ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); + else + ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); + ahd_reset_channel(ahd, cmd->device->channel + 'A', /*initiate*/TRUE); + + /* + * Add a minimal bus settle delay for devices that are slow to + * respond after bus resets. + */ + ahd_freeze_simq(ahd); + init_timer(&ahd->platform_data->reset_timer); + ahd->platform_data->reset_timer.data = (u_long)ahd; + ahd->platform_data->reset_timer.expires = jiffies + HZ / 2; + ahd->platform_data->reset_timer.function = + (ahd_linux_callback_t *)ahd_release_simq; + add_timer(&ahd->platform_data->reset_timer); + if (ahd_linux_next_device_to_run(ahd) != NULL) + ahd_schedule_runq(ahd); + ahd_linux_run_complete_queue(ahd); + ahd_unlock(ahd, &flags); +} + +static void +ahd_linux_dv_complete(struct scsi_cmnd *cmd) +{ + struct ahd_softc *ahd; + + ahd = *((struct ahd_softc **)cmd->device->host->hostdata); + + /* Delete the DV timer before it goes off! */ + scsi_delete_timer(cmd); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_DV) + printf("%s:%c:%d: Command completed, status= 0x%x\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->result); +#endif + + /* Wake up the state machine */ + up(&ahd->platform_data->dv_cmd_sem); +} + +static void +ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ) +{ + uint16_t b; + u_int i; + u_int j; + + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); + + i = 0; + + b = 0x0001; + for (j = 0 ; i < targ->dv_echo_size; j++) { + if (j < 32) { + /* + * 32bytes of sequential numbers. + */ + targ->dv_buffer[i++] = j & 0xff; + } else if (j < 48) { + /* + * 32bytes of repeating 0x0000, 0xffff. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00; + } else if (j < 64) { + /* + * 32bytes of repeating 0x5555, 0xaaaa. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55; + } else { + /* + * Remaining buffer is filled with a repeating + * patter of: + * + * 0xffff + * ~0x0001 << shifted once in each loop. + */ + if (j & 0x02) { + if (j & 0x01) { + targ->dv_buffer[i++] = ~(b >> 8) & 0xff; + b <<= 1; + if (b == 0x0000) + b = 0x0001; + } else { + targ->dv_buffer[i++] = (~b & 0xff); + } + } else { + targ->dv_buffer[i++] = 0xff; + } + } + } +} + +static u_int +ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + static int warned_user; + u_int tags; + + tags = 0; + if ((ahd->user_discenable & devinfo->target_mask) != 0) { + if (ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) { + + if (warned_user == 0) { + printf(KERN_WARNING +"aic79xx: WARNING: Insufficient tag_info instances\n" +"aic79xx: for installed controllers. Using defaults\n" +"aic79xx: Please update the aic79xx_tag_info array in\n" +"aic79xx: the aic79xx_osm.c source file.\n"); + warned_user++; + } + tags = AHD_MAX_QUEUE; + } else { + adapter_tag_info_t *tag_info; + + tag_info = &aic79xx_tag_info[ahd->unit]; + tags = tag_info->tag_commands[devinfo->target_offset]; + if (tags > AHD_MAX_QUEUE) + tags = AHD_MAX_QUEUE; + } + } + return (tags); +} + +static u_int +ahd_linux_user_dv_setting(struct ahd_softc *ahd) +{ + static int warned_user; + int dv; + + if (ahd->unit >= NUM_ELEMENTS(aic79xx_dv_settings)) { + + if (warned_user == 0) { + printf(KERN_WARNING +"aic79xx: WARNING: Insufficient dv settings instances\n" +"aic79xx: for installed controllers. Using defaults\n" +"aic79xx: Please update the aic79xx_dv_settings array in" +"aic79xx: the aic79xx_osm.c source file.\n"); + warned_user++; + } + dv = -1; + } else { + + dv = aic79xx_dv_settings[ahd->unit]; + } + + if (dv < 0) { + /* + * Apply the default. + */ + dv = 1; + if (ahd->seep_config != 0) + dv = (ahd->seep_config->bios_control & CFENABLEDV); + } + return (dv); +} + +static void +ahd_linux_setup_user_rd_strm_settings(struct ahd_softc *ahd) +{ + static int warned_user; + u_int rd_strm_mask; + u_int target_id; + + /* + * If we have specific read streaming info for this controller, + * apply it. Otherwise use the defaults. + */ + if (ahd->unit >= NUM_ELEMENTS(aic79xx_rd_strm_info)) { + + if (warned_user == 0) { + + printf(KERN_WARNING +"aic79xx: WARNING: Insufficient rd_strm instances\n" +"aic79xx: for installed controllers. Using defaults\n" +"aic79xx: Please update the aic79xx_rd_strm_info array\n" +"aic79xx: in the aic79xx_osm.c source file.\n"); + warned_user++; + } + rd_strm_mask = AIC79XX_CONFIGED_RD_STRM; + } else { + + rd_strm_mask = aic79xx_rd_strm_info[ahd->unit]; + } + for (target_id = 0; target_id < 16; target_id++) { + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + target_id, &tstate); + ahd_compile_devinfo(&devinfo, ahd->our_id, target_id, + CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR); + tinfo->user.ppr_options &= ~MSG_EXT_PPR_RD_STRM; + if ((rd_strm_mask & devinfo.target_mask) != 0) + tinfo->user.ppr_options |= MSG_EXT_PPR_RD_STRM; + } +} + +/* + * Determines the queue depth for a given device. + */ +static void +ahd_linux_device_queue_depth(struct ahd_softc *ahd, + struct ahd_linux_device *dev) +{ + struct ahd_devinfo devinfo; + u_int tags; + + ahd_compile_devinfo(&devinfo, + ahd->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', + ROLE_INITIATOR); + tags = ahd_linux_user_tagdepth(ahd, &devinfo); + if (tags != 0 + && dev->scsi_device != NULL + && dev->scsi_device->tagged_supported != 0) { + + ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED); + ahd_print_devinfo(ahd, &devinfo); + printf("Tagged Queuing enabled. Depth %d\n", tags); + } else { + ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE); + } +} + +static void +ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev) +{ + struct ahd_cmd *acmd; + struct scsi_cmnd *cmd; + struct scb *scb; + struct hardware_scb *hscb; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int col_idx; + uint16_t mask; + + if ((dev->flags & AHD_DEV_ON_RUN_LIST) != 0) + panic("running device on run list"); + + while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL + && dev->openings > 0 && dev->qfrozen == 0) { + + /* + * Schedule us to run later. The only reason we are not + * running is because the whole controller Q is frozen. + */ + if (ahd->platform_data->qfrozen != 0 + && AHD_DV_SIMQ_FROZEN(ahd) == 0) { + + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, + dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + return; + } + + cmd = &acmd_scsi_cmd(acmd); + + /* + * Get an scb to use. + */ + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + cmd->device->id, &tstate); + if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0 + || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + col_idx = AHD_NEVER_COL_IDX; + } else { + col_idx = AHD_BUILD_COL_IDX(cmd->device->id, + cmd->device->lun); + } + if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, + dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + ahd->flags |= AHD_RESOURCE_SHORTAGE; + return; + } + TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe); + scb->io_ctx = cmd; + scb->platform_data->dev = dev; + hscb = scb->hscb; + cmd->host_scribble = (char *)scb; + + /* + * Fill out basics of the HSCB. + */ + hscb->control = 0; + hscb->scsiid = BUILD_SCSIID(ahd, cmd); + hscb->lun = cmd->device->lun; + scb->hscb->task_management = 0; + mask = SCB_GET_TARGET_MASK(ahd, scb); + + if ((ahd->user_discenable & mask) != 0) + hscb->control |= DISCENB; + + if (AHD_DV_CMD(cmd) != 0) + scb->flags |= SCB_SILENT; + + if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) + scb->flags |= SCB_PACKETIZED; + + if ((tstate->auto_negotiate & mask) != 0) { + scb->flags |= SCB_AUTO_NEGOTIATE; + scb->hscb->control |= MK_MESSAGE; + } + + if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + int msg_bytes; + uint8_t tag_msgs[2]; + + msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); + if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { + hscb->control |= tag_msgs[0]; + if (tag_msgs[0] == MSG_ORDERED_TASK) + dev->commands_since_idle_or_otag = 0; + } else +#endif + if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH + && (dev->flags & AHD_DEV_Q_TAGGED) != 0) { + hscb->control |= MSG_ORDERED_TASK; + dev->commands_since_idle_or_otag = 0; + } else { + hscb->control |= MSG_SIMPLE_TASK; + } + } + + hscb->cdb_len = cmd->cmd_len; + memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len); + + scb->sg_count = 0; + ahd_set_residual(scb, 0); + ahd_set_sense_residual(scb, 0); + if (cmd->use_sg != 0) { + void *sg; + struct scatterlist *cur_seg; + u_int nseg; + int dir; + + cur_seg = (struct scatterlist *)cmd->request_buffer; + dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + nseg = pci_map_sg(ahd->dev_softc, cur_seg, + cmd->use_sg, dir); + scb->platform_data->xfer_len = 0; + for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) { + bus_addr_t addr; + bus_size_t len; + + addr = sg_dma_address(cur_seg); + len = sg_dma_len(cur_seg); + scb->platform_data->xfer_len += len; + sg = ahd_sg_setup(ahd, scb, sg, addr, len, + /*last*/nseg == 1); + } + } else if (cmd->request_bufflen != 0) { + void *sg; + bus_addr_t addr; + int dir; + + sg = scb->sg_list; + dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + addr = pci_map_single(ahd->dev_softc, + cmd->request_buffer, + cmd->request_bufflen, dir); + scb->platform_data->xfer_len = cmd->request_bufflen; + scb->platform_data->buf_busaddr = addr; + sg = ahd_sg_setup(ahd, scb, sg, addr, + cmd->request_bufflen, /*last*/TRUE); + } + + LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); + dev->openings--; + dev->active++; + dev->commands_issued++; + + /* Update the error counting bucket and dump if needed */ + if (dev->target->cmds_since_error) { + dev->target->cmds_since_error++; + if (dev->target->cmds_since_error > + AHD_LINUX_ERR_THRESH) + dev->target->cmds_since_error = 0; + } + + if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0) + dev->commands_since_idle_or_otag++; + scb->flags |= SCB_ACTIVE; + ahd_queue_scb(ahd, scb); + } +} + +/* + * SCSI controller interrupt handler. + */ +irqreturn_t +ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) +{ + struct ahd_softc *ahd; + u_long flags; + int ours; + + ahd = (struct ahd_softc *) dev_id; + ahd_lock(ahd, &flags); + ours = ahd_intr(ahd); + if (ahd_linux_next_device_to_run(ahd) != NULL) + ahd_schedule_runq(ahd); + ahd_linux_run_complete_queue(ahd); + ahd_unlock(ahd, &flags); + return IRQ_RETVAL(ours); +} + +void +ahd_platform_flushwork(struct ahd_softc *ahd) +{ + + while (ahd_linux_run_complete_queue(ahd) != NULL) + ; +} + +static struct ahd_linux_target* +ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target) +{ + struct ahd_linux_target *targ; + + targ = malloc(sizeof(*targ), M_DEVBUF, M_NOWAIT); + if (targ == NULL) + return (NULL); + memset(targ, 0, sizeof(*targ)); + targ->channel = channel; + targ->target = target; + targ->ahd = ahd; + targ->flags = AHD_DV_REQUIRED; + ahd->platform_data->targets[target] = targ; + return (targ); +} + +static void +ahd_linux_free_target(struct ahd_softc *ahd, struct ahd_linux_target *targ) +{ + struct ahd_devinfo devinfo; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + u_int our_id; + u_int target_offset; + char channel; + + /* + * Force a negotiation to async/narrow on any + * future command to this device unless a bus + * reset occurs between now and that command. + */ + channel = 'A' + targ->channel; + our_id = ahd->our_id; + target_offset = targ->target; + tinfo = ahd_fetch_transinfo(ahd, channel, our_id, + targ->target, &tstate); + ahd_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD, + channel, ROLE_INITIATOR); + ahd_set_syncrate(ahd, &devinfo, 0, 0, 0, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_update_neg_request(ahd, &devinfo, tstate, tinfo, AHD_NEG_ALWAYS); + ahd->platform_data->targets[target_offset] = NULL; + if (targ->inq_data != NULL) + free(targ->inq_data, M_DEVBUF); + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + free(targ, M_DEVBUF); +} + +static struct ahd_linux_device* +ahd_linux_alloc_device(struct ahd_softc *ahd, + struct ahd_linux_target *targ, u_int lun) +{ + struct ahd_linux_device *dev; + + dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT); + if (dev == NULL) + return (NULL); + memset(dev, 0, sizeof(*dev)); + init_timer(&dev->timer); + TAILQ_INIT(&dev->busyq); + dev->flags = AHD_DEV_UNCONFIGURED; + dev->lun = lun; + dev->target = targ; + + /* + * We start out life using untagged + * transactions of which we allow one. + */ + dev->openings = 1; + + /* + * Set maxtags to 0. This will be changed if we + * later determine that we are dealing with + * a tagged queuing capable device. + */ + dev->maxtags = 0; + + targ->refcount++; + targ->devices[lun] = dev; + return (dev); +} + +static void +ahd_linux_free_device(struct ahd_softc *ahd, struct ahd_linux_device *dev) +{ + struct ahd_linux_target *targ; + + del_timer(&dev->timer); + targ = dev->target; + targ->devices[dev->lun] = NULL; + free(dev, M_DEVBUF); + targ->refcount--; + if (targ->refcount == 0 + && (targ->flags & AHD_DV_REQUIRED) == 0) + ahd_linux_free_target(ahd, targ); +} + +void +ahd_send_async(struct ahd_softc *ahd, char channel, + u_int target, u_int lun, ac_code code, void *arg) +{ + switch (code) { + case AC_TRANSFER_NEG: + { + char buf[80]; + struct ahd_linux_target *targ; + struct info_str info; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + + info.buffer = buf; + info.length = sizeof(buf); + info.offset = 0; + info.pos = 0; + tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id, + target, &tstate); + + /* + * Don't bother reporting results while + * negotiations are still pending. + */ + if (tinfo->curr.period != tinfo->goal.period + || tinfo->curr.width != tinfo->goal.width + || tinfo->curr.offset != tinfo->goal.offset + || tinfo->curr.ppr_options != tinfo->goal.ppr_options) + if (bootverbose == 0) + break; + + /* + * Don't bother reporting results that + * are identical to those last reported. + */ + targ = ahd->platform_data->targets[target]; + if (targ == NULL) + break; + if (tinfo->curr.period == targ->last_tinfo.period + && tinfo->curr.width == targ->last_tinfo.width + && tinfo->curr.offset == targ->last_tinfo.offset + && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options) + if (bootverbose == 0) + break; + + targ->last_tinfo.period = tinfo->curr.period; + targ->last_tinfo.width = tinfo->curr.width; + targ->last_tinfo.offset = tinfo->curr.offset; + targ->last_tinfo.ppr_options = tinfo->curr.ppr_options; + + printf("(%s:%c:", ahd_name(ahd), channel); + if (target == CAM_TARGET_WILDCARD) + printf("*): "); + else + printf("%d): ", target); + ahd_format_transinfo(&info, &tinfo->curr); + if (info.pos < info.length) + *info.buffer = '\0'; + else + buf[info.length - 1] = '\0'; + printf("%s", buf); + break; + } + case AC_SENT_BDR: + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + WARN_ON(lun != CAM_LUN_WILDCARD); + scsi_report_device_reset(ahd->platform_data->host, + channel - 'A', target); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + Scsi_Device *scsi_dev; + + /* + * Find the SCSI device associated with this + * request and indicate that a UA is expected. + */ + for (scsi_dev = ahd->platform_data->host->host_queue; + scsi_dev != NULL; scsi_dev = scsi_dev->next) { + if (channel - 'A' == scsi_dev->channel + && target == scsi_dev->id + && (lun == CAM_LUN_WILDCARD + || lun == scsi_dev->lun)) { + scsi_dev->was_reset = 1; + scsi_dev->expecting_cc_ua = 1; + } + } +#endif + break; + } + case AC_BUS_RESET: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + if (ahd->platform_data->host != NULL) { + scsi_report_bus_reset(ahd->platform_data->host, + channel - 'A'); + } +#endif + break; + default: + panic("ahd_send_async: Unexpected async event"); + } +} + +/* + * Calls the higher level scsi done function and frees the scb. + */ +void +ahd_done(struct ahd_softc *ahd, struct scb *scb) +{ + Scsi_Cmnd *cmd; + struct ahd_linux_device *dev; + + if ((scb->flags & SCB_ACTIVE) == 0) { + printf("SCB %d done'd twice\n", SCB_GET_TAG(scb)); + ahd_dump_card_state(ahd); + panic("Stopping for safety"); + } + LIST_REMOVE(scb, pending_links); + cmd = scb->io_ctx; + dev = scb->platform_data->dev; + dev->active--; + dev->openings++; + if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) { + cmd->result &= ~(CAM_DEV_QFRZN << 16); + dev->qfrozen--; + } + ahd_linux_unmap_scb(ahd, scb); + + /* + * Guard against stale sense data. + * The Linux mid-layer assumes that sense + * was retrieved anytime the first byte of + * the sense buffer looks "sane". + */ + cmd->sense_buffer[0] = 0; + if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) { + uint32_t amount_xferred; + + amount_xferred = + ahd_get_transfer_length(scb) - ahd_get_residual(scb); + if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) { +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MISC) != 0) { + ahd_print_path(ahd, scb); + printf("Set CAM_UNCOR_PARITY\n"); + } +#endif + ahd_set_transaction_status(scb, CAM_UNCOR_PARITY); + } else if (amount_xferred < scb->io_ctx->underflow) { + u_int i; + + ahd_print_path(ahd, scb); + printf("CDB:"); + for (i = 0; i < scb->io_ctx->cmd_len; i++) + printf(" 0x%x", scb->io_ctx->cmnd[i]); + printf("\n"); + ahd_print_path(ahd, scb); + printf("Saw underflow (%ld of %ld bytes). " + "Treated as error\n", + ahd_get_residual(scb), + ahd_get_transfer_length(scb)); + ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR); + } else { + ahd_set_transaction_status(scb, CAM_REQ_CMP); + } + } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { + ahd_linux_handle_scsi_status(ahd, dev, scb); + } else if (ahd_get_transaction_status(scb) == CAM_SEL_TIMEOUT) { + dev->flags |= AHD_DEV_UNCONFIGURED; + if (AHD_DV_CMD(cmd) == FALSE) + dev->target->flags &= ~AHD_DV_REQUIRED; + } + /* + * Start DV for devices that require it assuming the first command + * sent does not result in a selection timeout. + */ + if (ahd_get_transaction_status(scb) != CAM_SEL_TIMEOUT + && (dev->target->flags & AHD_DV_REQUIRED) != 0) + ahd_linux_start_dv(ahd); + + if (dev->openings == 1 + && ahd_get_transaction_status(scb) == CAM_REQ_CMP + && ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL) + dev->tag_success_count++; + /* + * Some devices deal with temporary internal resource + * shortages by returning queue full. When the queue + * full occurrs, we throttle back. Slowly try to get + * back to our previous queue depth. + */ + if ((dev->openings + dev->active) < dev->maxtags + && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) { + dev->tag_success_count = 0; + dev->openings++; + } + + if (dev->active == 0) + dev->commands_since_idle_or_otag = 0; + + if (TAILQ_EMPTY(&dev->busyq)) { + if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 + && dev->active == 0 + && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0) + ahd_linux_free_device(ahd, dev); + } else if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + } + + if ((scb->flags & SCB_RECOVERY_SCB) != 0) { + printf("Recovery SCB completes\n"); + if (ahd_get_transaction_status(scb) == CAM_BDR_SENT + || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) + ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); + if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) { + scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM; + up(&ahd->platform_data->eh_sem); + } + } + + ahd_free_scb(ahd, scb); + ahd_linux_queue_cmd_complete(ahd, cmd); + + if ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_EMPTY) != 0 + && LIST_FIRST(&ahd->pending_scbs) == NULL) { + ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_EMPTY; + up(&ahd->platform_data->dv_sem); + } +} + +static void +ahd_linux_handle_scsi_status(struct ahd_softc *ahd, + struct ahd_linux_device *dev, struct scb *scb) +{ + struct ahd_devinfo devinfo; + + ahd_compile_devinfo(&devinfo, + ahd->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', + ROLE_INITIATOR); + + /* + * We don't currently trust the mid-layer to + * properly deal with queue full or busy. So, + * when one occurs, we tell the mid-layer to + * unconditionally requeue the command to us + * so that we can retry it ourselves. We also + * implement our own throttling mechanism so + * we don't clobber the device with too many + * commands. + */ + switch (ahd_get_scsi_status(scb)) { + default: + break; + case SCSI_STATUS_CHECK_COND: + case SCSI_STATUS_CMD_TERMINATED: + { + Scsi_Cmnd *cmd; + + /* + * Copy sense information to the OS's cmd + * structure if it is available. + */ + cmd = scb->io_ctx; + if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) { + struct scsi_status_iu_header *siu; + u_int sense_size; + u_int sense_offset; + + if (scb->flags & SCB_SENSE) { + sense_size = MIN(sizeof(struct scsi_sense_data) + - ahd_get_sense_residual(scb), + sizeof(cmd->sense_buffer)); + sense_offset = 0; + } else { + /* + * Copy only the sense data into the provided + * buffer. + */ + siu = (struct scsi_status_iu_header *) + scb->sense_data; + sense_size = MIN(scsi_4btoul(siu->sense_length), + sizeof(cmd->sense_buffer)); + sense_offset = SIU_SENSE_OFFSET(siu); + } + + memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); + memcpy(cmd->sense_buffer, + ahd_get_sense_buf(ahd, scb) + + sense_offset, sense_size); + cmd->result |= (DRIVER_SENSE << 24); + +#ifdef AHD_DEBUG + if (ahd_debug & AHD_SHOW_SENSE) { + int i; + + printf("Copied %d bytes of sense data at %d:", + sense_size, sense_offset); + for (i = 0; i < sense_size; i++) { + if ((i & 0xF) == 0) + printf("\n"); + printf("0x%x ", cmd->sense_buffer[i]); + } + printf("\n"); + } +#endif + } + break; + } + case SCSI_STATUS_QUEUE_FULL: + { + /* + * By the time the core driver has returned this + * command, all other commands that were queued + * to us but not the device have been returned. + * This ensures that dev->active is equal to + * the number of commands actually queued to + * the device. + */ + dev->tag_success_count = 0; + if (dev->active != 0) { + /* + * Drop our opening count to the number + * of commands currently outstanding. + */ + dev->openings = 0; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_QFULL) != 0) { + ahd_print_path(ahd, scb); + printf("Dropping tag count to %d\n", + dev->active); + } +#endif + if (dev->active == dev->tags_on_last_queuefull) { + + dev->last_queuefull_same_count++; + /* + * If we repeatedly see a queue full + * at the same queue depth, this + * device has a fixed number of tag + * slots. Lock in this tag depth + * so we stop seeing queue fulls from + * this device. + */ + if (dev->last_queuefull_same_count + == AHD_LOCK_TAGS_COUNT) { + dev->maxtags = dev->active; + ahd_print_path(ahd, scb); + printf("Locking max tag count at %d\n", + dev->active); + } + } else { + dev->tags_on_last_queuefull = dev->active; + dev->last_queuefull_same_count = 0; + } + ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); + ahd_set_scsi_status(scb, SCSI_STATUS_OK); + ahd_platform_set_tags(ahd, &devinfo, + (dev->flags & AHD_DEV_Q_BASIC) + ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); + break; + } + /* + * Drop down to a single opening, and treat this + * as if the target returned BUSY SCSI status. + */ + dev->openings = 1; + ahd_platform_set_tags(ahd, &devinfo, + (dev->flags & AHD_DEV_Q_BASIC) + ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); + ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); + /* FALLTHROUGH */ + } + case SCSI_STATUS_BUSY: + /* + * Set a short timer to defer sending commands for + * a bit since Linux will not delay in this case. + */ + if ((dev->flags & AHD_DEV_TIMER_ACTIVE) != 0) { + printf("%s:%c:%d: Device Timer still active during " + "busy processing\n", ahd_name(ahd), + dev->target->channel, dev->target->target); + break; + } + dev->flags |= AHD_DEV_TIMER_ACTIVE; + dev->qfrozen++; + init_timer(&dev->timer); + dev->timer.data = (u_long)dev; + dev->timer.expires = jiffies + (HZ/2); + dev->timer.function = ahd_linux_dev_timed_unfreeze; + add_timer(&dev->timer); + break; + } +} + +static void +ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, Scsi_Cmnd *cmd) +{ + /* + * Typically, the complete queue has very few entries + * queued to it before the queue is emptied by + * ahd_linux_run_complete_queue, so sorting the entries + * by generation number should be inexpensive. + * We perform the sort so that commands that complete + * with an error are retuned in the order origionally + * queued to the controller so that any subsequent retries + * are performed in order. The underlying ahd routines do + * not guarantee the order that aborted commands will be + * returned to us. + */ + struct ahd_completeq *completeq; + struct ahd_cmd *list_cmd; + struct ahd_cmd *acmd; + + /* + * Map CAM error codes into Linux Error codes. We + * avoid the conversion so that the DV code has the + * full error information available when making + * state change decisions. + */ + if (AHD_DV_CMD(cmd) == FALSE) { + uint32_t status; + u_int new_status; + + status = ahd_cmd_get_transaction_status(cmd); + if (status != CAM_REQ_CMP) { + struct ahd_linux_device *dev; + struct ahd_devinfo devinfo; + cam_status cam_status; + uint32_t action; + u_int scsi_status; + + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, + cmd->device->lun, + /*alloc*/FALSE); + + if (dev == NULL) + goto no_fallback; + + ahd_compile_devinfo(&devinfo, + ahd->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A':'B', + ROLE_INITIATOR); + + scsi_status = ahd_cmd_get_scsi_status(cmd); + cam_status = ahd_cmd_get_transaction_status(cmd); + action = aic_error_action(cmd, dev->target->inq_data, + cam_status, scsi_status); + if ((action & SSQ_FALLBACK) != 0) { + + /* Update stats */ + dev->target->errors_detected++; + if (dev->target->cmds_since_error == 0) + dev->target->cmds_since_error++; + else { + dev->target->cmds_since_error = 0; + ahd_linux_fallback(ahd, &devinfo); + } + } + } +no_fallback: + switch (status) { + case CAM_REQ_INPROG: + case CAM_REQ_CMP: + case CAM_SCSI_STATUS_ERROR: + new_status = DID_OK; + break; + case CAM_REQ_ABORTED: + new_status = DID_ABORT; + break; + case CAM_BUSY: + new_status = DID_BUS_BUSY; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + new_status = DID_BAD_TARGET; + break; + case CAM_SEL_TIMEOUT: + new_status = DID_NO_CONNECT; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + new_status = DID_RESET; + break; + case CAM_UNCOR_PARITY: + new_status = DID_PARITY; + break; + case CAM_CMD_TIMEOUT: + new_status = DID_TIME_OUT; + break; + case CAM_UA_ABORT: + case CAM_REQ_CMP_ERR: + case CAM_AUTOSENSE_FAIL: + case CAM_NO_HBA: + case CAM_DATA_RUN_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_SEQUENCE_FAIL: + case CAM_CCB_LEN_ERR: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TERMIO: + case CAM_UNREC_HBA_ERROR: + case CAM_REQ_TOO_BIG: + new_status = DID_ERROR; + break; + case CAM_REQUEUE_REQ: + /* + * If we want the request requeued, make sure there + * are sufficent retries. In the old scsi error code, + * we used to be able to specify a result code that + * bypassed the retry count. Now we must use this + * hack. We also "fake" a check condition with + * a sense code of ABORTED COMMAND. This seems to + * evoke a retry even if this command is being sent + * via the eh thread. Ick! Ick! Ick! + */ + if (cmd->retries > 0) + cmd->retries--; + new_status = DID_OK; + ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); + cmd->result |= (DRIVER_SENSE << 24); + memset(cmd->sense_buffer, 0, + sizeof(cmd->sense_buffer)); + cmd->sense_buffer[0] = SSD_ERRCODE_VALID + | SSD_CURRENT_ERROR; + cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND; + break; + default: + /* We should never get here */ + new_status = DID_ERROR; + break; + } + + ahd_cmd_set_transaction_status(cmd, new_status); + } + + completeq = &ahd->platform_data->completeq; + list_cmd = TAILQ_FIRST(completeq); + acmd = (struct ahd_cmd *)cmd; + while (list_cmd != NULL + && acmd_scsi_cmd(list_cmd).serial_number + < acmd_scsi_cmd(acmd).serial_number) + list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); + if (list_cmd != NULL) + TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); + else + TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); +} + +static void +ahd_linux_filter_inquiry(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) +{ + struct scsi_inquiry_data *sid; + struct ahd_initiator_tinfo *tinfo; + struct ahd_transinfo *user; + struct ahd_transinfo *goal; + struct ahd_transinfo *curr; + struct ahd_tmode_tstate *tstate; + struct ahd_linux_device *dev; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int trans_version; + u_int prot_version; + + /* + * Determine if this lun actually exists. If so, + * hold on to its corresponding device structure. + * If not, make sure we release the device and + * don't bother processing the rest of this inquiry + * command. + */ + dev = ahd_linux_get_device(ahd, devinfo->channel - 'A', + devinfo->target, devinfo->lun, + /*alloc*/TRUE); + + sid = (struct scsi_inquiry_data *)dev->target->inq_data; + if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) { + + dev->flags &= ~AHD_DEV_UNCONFIGURED; + } else { + dev->flags |= AHD_DEV_UNCONFIGURED; + return; + } + + /* + * Update our notion of this device's transfer + * negotiation capabilities. + */ + tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + user = &tinfo->user; + goal = &tinfo->goal; + curr = &tinfo->curr; + width = user->width; + period = user->period; + offset = user->offset; + ppr_options = user->ppr_options; + trans_version = user->transport_version; + prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid)); + + /* + * Only attempt SPI3/4 once we've verified that + * the device claims to support SPI3/4 features. + */ + if (prot_version < SCSI_REV_2) + trans_version = SID_ANSI_REV(sid); + else + trans_version = SCSI_REV_2; + + if ((sid->flags & SID_WBus16) == 0) + width = MSG_EXT_WDTR_BUS_8_BIT; + if ((sid->flags & SID_Sync) == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + if ((sid->spi3data & SID_SPI_QAS) == 0) + ppr_options &= ~MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0) + ppr_options &= MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_IUS) == 0) + ppr_options &= (MSG_EXT_PPR_DT_REQ + | MSG_EXT_PPR_QAS_REQ); + + if (prot_version > SCSI_REV_2 + && ppr_options != 0) + trans_version = user->transport_version; + + ahd_validate_width(ahd, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN); + ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_MAX); + ahd_validate_offset(ahd, /*tinfo limit*/NULL, period, + &offset, width, ROLE_UNKNOWN); + if (offset == 0 || period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + /* Apply our filtered user settings. */ + curr->transport_version = trans_version; + curr->protocol_version = prot_version; + ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, /*paused*/FALSE); + ahd_set_syncrate(ahd, devinfo, period, offset, ppr_options, + AHD_TRANS_GOAL, /*paused*/FALSE); +} + +void +ahd_freeze_simq(struct ahd_softc *ahd) +{ + ahd->platform_data->qfrozen++; + if (ahd->platform_data->qfrozen == 1) { + scsi_block_requests(ahd->platform_data->host); + ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ); + } +} + +void +ahd_release_simq(struct ahd_softc *ahd) +{ + u_long s; + int unblock_reqs; + + unblock_reqs = 0; + ahd_lock(ahd, &s); + if (ahd->platform_data->qfrozen > 0) + ahd->platform_data->qfrozen--; + if (ahd->platform_data->qfrozen == 0) { + unblock_reqs = 1; + } + if (AHD_DV_SIMQ_FROZEN(ahd) + && ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_RELEASE) != 0)) { + ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE; + up(&ahd->platform_data->dv_sem); + } + ahd_schedule_runq(ahd); + ahd_unlock(ahd, &s); + /* + * There is still a race here. The mid-layer + * should keep its own freeze count and use + * a bottom half handler to run the queues + * so we can unblock with our own lock held. + */ + if (unblock_reqs) + scsi_unblock_requests(ahd->platform_data->host); +} + +static void +ahd_linux_sem_timeout(u_long arg) +{ + struct scb *scb; + struct ahd_softc *ahd; + u_long s; + + scb = (struct scb *)arg; + ahd = scb->ahd_softc; + ahd_lock(ahd, &s); + if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) { + scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM; + up(&ahd->platform_data->eh_sem); + } + ahd_unlock(ahd, &s); +} + +static void +ahd_linux_dev_timed_unfreeze(u_long arg) +{ + struct ahd_linux_device *dev; + struct ahd_softc *ahd; + u_long s; + + dev = (struct ahd_linux_device *)arg; + ahd = dev->target->ahd; + ahd_lock(ahd, &s); + dev->flags &= ~AHD_DEV_TIMER_ACTIVE; + if (dev->qfrozen > 0) + dev->qfrozen--; + if (dev->qfrozen == 0 + && (dev->flags & AHD_DEV_ON_RUN_LIST) == 0) + ahd_linux_run_device_queue(ahd, dev); + if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 + && dev->active == 0) + ahd_linux_free_device(ahd, dev); + ahd_unlock(ahd, &s); +} + +void +ahd_platform_dump_card_state(struct ahd_softc *ahd) +{ + struct ahd_linux_device *dev; + int target; + int maxtarget; + int lun; + int i; + + maxtarget = (ahd->features & AHD_WIDE) ? 15 : 7; + for (target = 0; target <=maxtarget; target++) { + + for (lun = 0; lun < AHD_NUM_LUNS; lun++) { + struct ahd_cmd *acmd; + + dev = ahd_linux_get_device(ahd, 0, target, + lun, /*alloc*/FALSE); + if (dev == NULL) + continue; + + printf("DevQ(%d:%d:%d): ", 0, target, lun); + i = 0; + TAILQ_FOREACH(acmd, &dev->busyq, acmd_links.tqe) { + if (i++ > AHD_SCB_MAX) + break; + } + printf("%d waiting\n", i); + } + } +} + +static int __init +ahd_linux_init(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + return (ahd_linux_detect(&aic79xx_driver_template) ? 0 : -ENODEV); +#else + scsi_register_module(MODULE_SCSI_HA, &aic79xx_driver_template); + if (aic79xx_driver_template.present == 0) { + scsi_unregister_module(MODULE_SCSI_HA, + &aic79xx_driver_template); + return (-ENODEV); + } + + return (0); +#endif +} + +static void __exit +ahd_linux_exit(void) +{ + struct ahd_softc *ahd; + u_long l; + + /* + * Shutdown DV threads before going into the SCSI mid-layer. + * This avoids situations where the mid-layer locks the entire + * kernel so that waiting for our DV threads to exit leads + * to deadlock. + */ + ahd_list_lock(&l); + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + + ahd_linux_kill_dv_thread(ahd); + } + ahd_list_unlock(&l); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * In 2.4 we have to unregister from the PCI core _after_ + * unregistering from the scsi midlayer to avoid dangling + * references. + */ + scsi_unregister_module(MODULE_SCSI_HA, &aic79xx_driver_template); +#endif + ahd_linux_pci_exit(); +} + +module_init(ahd_linux_init); +module_exit(ahd_linux_exit); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_osm.h linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_osm.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_osm.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_osm.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1236 @@ +/* + * Adaptec AIC79xx device driver for Linux. + * + * Copyright (c) 2000-2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#135 $ + * + */ +#ifndef _AIC79XX_LINUX_H_ +#define _AIC79XX_LINUX_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#include /* For tasklet support. */ +#include +#include +#else +#include +#endif + +/* Core SCSI definitions */ +#define AIC_LIB_PREFIX ahd +#include "scsi.h" +#include "hosts.h" + +/* Name space conflict with BSD queue macros */ +#ifdef LIST_HEAD +#undef LIST_HEAD +#endif + +#include "cam.h" +#include "queue.h" +#include "scsi_message.h" +#include "scsi_iu.h" +#include "aiclib.h" + +/*********************************** Debugging ********************************/ +#ifdef CONFIG_AIC79XX_DEBUG_ENABLE +#ifdef CONFIG_AIC79XX_DEBUG_MASK +#define AHD_DEBUG 1 +#define AHD_DEBUG_OPTS CONFIG_AIC79XX_DEBUG_MASK +#else +/* + * Compile in debugging code, but do not enable any printfs. + */ +#define AHD_DEBUG 1 +#define AHD_DEBUG_OPTS 0 +#endif +/* No debugging code. */ +#endif + +/********************************** Misc Macros *******************************/ +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#define powerof2(x) ((((x)-1)&(x))==0) + +/************************* Forward Declarations *******************************/ +struct ahd_softc; +typedef struct pci_dev *ahd_dev_softc_t; +typedef Scsi_Cmnd *ahd_io_ctx_t; + +/******************************* Byte Order ***********************************/ +#define ahd_htobe16(x) cpu_to_be16(x) +#define ahd_htobe32(x) cpu_to_be32(x) +#define ahd_htobe64(x) cpu_to_be64(x) +#define ahd_htole16(x) cpu_to_le16(x) +#define ahd_htole32(x) cpu_to_le32(x) +#define ahd_htole64(x) cpu_to_le64(x) + +#define ahd_be16toh(x) be16_to_cpu(x) +#define ahd_be32toh(x) be32_to_cpu(x) +#define ahd_be64toh(x) be64_to_cpu(x) +#define ahd_le16toh(x) le16_to_cpu(x) +#define ahd_le32toh(x) le32_to_cpu(x) +#define ahd_le64toh(x) le64_to_cpu(x) + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#ifndef BYTE_ORDER +#if defined(__BIG_ENDIAN) +#define BYTE_ORDER BIG_ENDIAN +#endif +#if defined(__LITTLE_ENDIAN) +#define BYTE_ORDER LITTLE_ENDIAN +#endif +#endif /* BYTE_ORDER */ + +/************************* Configuration Data *********************************/ +extern uint32_t aic79xx_allow_memio; +extern int aic79xx_detect_complete; +extern Scsi_Host_Template aic79xx_driver_template; + +/***************************** Bus Space/DMA **********************************/ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17) +typedef dma_addr_t bus_addr_t; +#else +typedef uint32_t bus_addr_t; +#endif +typedef uint32_t bus_size_t; + +typedef enum { + BUS_SPACE_MEMIO, + BUS_SPACE_PIO +} bus_space_tag_t; + +typedef union { + u_long ioport; + volatile uint8_t *maddr; +} bus_space_handle_t; + +typedef struct bus_dma_segment +{ + bus_addr_t ds_addr; + bus_size_t ds_len; +} bus_dma_segment_t; + +struct ahd_linux_dma_tag +{ + bus_size_t alignment; + bus_size_t boundary; + bus_size_t maxsize; +}; +typedef struct ahd_linux_dma_tag* bus_dma_tag_t; + +struct ahd_linux_dmamap +{ + bus_addr_t bus_addr; +}; +typedef struct ahd_linux_dmamap* bus_dmamap_t; + +typedef int bus_dma_filter_t(void*, bus_addr_t); +typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); + +#define BUS_DMA_WAITOK 0x0 +#define BUS_DMA_NOWAIT 0x1 +#define BUS_DMA_ALLOCNOW 0x2 +#define BUS_DMA_LOAD_SEGS 0x4 /* + * Argument is an S/G list not + * a single buffer. + */ + +#define BUS_SPACE_MAXADDR 0xFFFFFFFF +#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF +#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF + +int ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/, + bus_size_t /*alignment*/, bus_size_t /*boundary*/, + bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/, + bus_dma_filter_t*/*filter*/, void */*filterarg*/, + bus_size_t /*maxsize*/, int /*nsegments*/, + bus_size_t /*maxsegsz*/, int /*flags*/, + bus_dma_tag_t */*dma_tagp*/); + +void ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/); + +int ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t /*dmat*/, + void** /*vaddr*/, int /*flags*/, + bus_dmamap_t* /*mapp*/); + +void ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t /*dmat*/, + void* /*vaddr*/, bus_dmamap_t /*map*/); + +void ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/, + bus_dmamap_t /*map*/); + +int ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t /*dmat*/, + bus_dmamap_t /*map*/, void * /*buf*/, + bus_size_t /*buflen*/, bus_dmamap_callback_t *, + void */*callback_arg*/, int /*flags*/); + +int ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t); + +/* + * Operations performed by ahd_dmamap_sync(). + */ +#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ +#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ +#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ +#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ + +/* + * XXX + * ahd_dmamap_sync is only used on buffers allocated with + * the pci_alloc_consistent() API. Although I'm not sure how + * this works on architectures with a write buffer, Linux does + * not have an API to sync "coherent" memory. Perhaps we need + * to do an mb()? + */ +#define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op) + +/************************** Timer DataStructures ******************************/ +typedef struct timer_list ahd_timer_t; + +/********************************** Includes **********************************/ +#ifdef CONFIG_AIC79XX_REG_PRETTY_PRINT +#define AIC_DEBUG_REGISTERS 1 +#else +#define AIC_DEBUG_REGISTERS 0 +#endif +#include "aic79xx.h" + +/***************************** Timer Facilities *******************************/ +#define ahd_timer_init init_timer +#define ahd_timer_stop del_timer_sync +typedef void ahd_linux_callback_t (u_long); +static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec, + ahd_callback_t *func, void *arg); +static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec); + +static __inline void +ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg) +{ + struct ahd_softc *ahd; + + ahd = (struct ahd_softc *)arg; + del_timer(timer); + timer->data = (u_long)arg; + timer->expires = jiffies + (usec * HZ)/1000000; + timer->function = (ahd_linux_callback_t*)func; + add_timer(timer); +} + +static __inline void +ahd_scb_timer_reset(struct scb *scb, u_int usec) +{ + mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); +} + +/***************************** SMP support ************************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17) +#include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) +#include +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) +#define AHD_SCSI_HAS_HOST_LOCK 1 +#else +#define AHD_SCSI_HAS_HOST_LOCK 0 +#endif + +#define AIC79XX_DRIVER_VERSION "1.3.10" + +/**************************** Front End Queues ********************************/ +/* + * Data structure used to cast the Linux struct scsi_cmnd to something + * that allows us to use the queue macros. The linux structure has + * plenty of space to hold the links fields as required by the queue + * macros, but the queue macors require them to have the correct type. + */ +struct ahd_cmd_internal { + /* Area owned by the Linux scsi layer. */ + uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)]; + union { + STAILQ_ENTRY(ahd_cmd) ste; + LIST_ENTRY(ahd_cmd) le; + TAILQ_ENTRY(ahd_cmd) tqe; + } links; + uint32_t end; +}; + +struct ahd_cmd { + union { + struct ahd_cmd_internal icmd; + struct scsi_cmnd scsi_cmd; + } un; +}; + +#define acmd_icmd(cmd) ((cmd)->un.icmd) +#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd) +#define acmd_links un.icmd.links + +/*************************** Device Data Structures ***************************/ +/* + * A per probed device structure used to deal with some error recovery + * scenarios that the Linux mid-layer code just doesn't know how to + * handle. The structure allocated for a device only becomes persistent + * after a successfully completed inquiry command to the target when + * that inquiry data indicates a lun is present. + */ +TAILQ_HEAD(ahd_busyq, ahd_cmd); +typedef enum { + AHD_DEV_UNCONFIGURED = 0x01, + AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ + AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ + AHD_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ + AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ + AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ + AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ + AHD_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ +} ahd_linux_dev_flags; + +struct ahd_linux_target; +struct ahd_linux_device { + TAILQ_ENTRY(ahd_linux_device) links; + struct ahd_busyq busyq; + + /* + * The number of transactions currently + * queued to the device. + */ + int active; + + /* + * The currently allowed number of + * transactions that can be queued to + * the device. Must be signed for + * conversion from tagged to untagged + * mode where the device may have more + * than one outstanding active transaction. + */ + int openings; + + /* + * A positive count indicates that this + * device's queue is halted. + */ + u_int qfrozen; + + /* + * Cumulative command counter. + */ + u_long commands_issued; + + /* + * The number of tagged transactions when + * running at our current opening level + * that have been successfully received by + * this device since the last QUEUE FULL. + */ + u_int tag_success_count; +#define AHD_TAG_SUCCESS_INTERVAL 50 + + ahd_linux_dev_flags flags; + + /* + * Per device timer. + */ + struct timer_list timer; + + /* + * The high limit for the tags variable. + */ + u_int maxtags; + + /* + * The computed number of tags outstanding + * at the time of the last QUEUE FULL event. + */ + u_int tags_on_last_queuefull; + + /* + * How many times we have seen a queue full + * with the same number of tags. This is used + * to stop our adaptive queue depth algorithm + * on devices with a fixed number of tags. + */ + u_int last_queuefull_same_count; +#define AHD_LOCK_TAGS_COUNT 50 + + /* + * How many transactions have been queued + * without the device going idle. We use + * this statistic to determine when to issue + * an ordered tag to prevent transaction + * starvation. This statistic is only updated + * if the AHD_DEV_PERIODIC_OTAG flag is set + * on this device. + */ + u_int commands_since_idle_or_otag; +#define AHD_OTAG_THRESH 500 + + int lun; + Scsi_Device *scsi_device; + struct ahd_linux_target *target; +}; + +typedef enum { + AHD_DV_REQUIRED = 0x01, + AHD_INQ_VALID = 0x02, + AHD_BASIC_DV = 0x04, + AHD_ENHANCED_DV = 0x08 +} ahd_linux_targ_flags; + +/* DV States */ +typedef enum { + AHD_DV_STATE_EXIT = 0, + AHD_DV_STATE_INQ_SHORT_ASYNC, + AHD_DV_STATE_INQ_ASYNC, + AHD_DV_STATE_INQ_ASYNC_VERIFY, + AHD_DV_STATE_TUR, + AHD_DV_STATE_REBD, + AHD_DV_STATE_INQ_VERIFY, + AHD_DV_STATE_WEB, + AHD_DV_STATE_REB, + AHD_DV_STATE_SU, + AHD_DV_STATE_BUSY +} ahd_dv_state; + +struct ahd_linux_target { + struct ahd_linux_device *devices[AHD_NUM_LUNS]; + int channel; + int target; + int refcount; + struct ahd_transinfo last_tinfo; + struct ahd_softc *ahd; + ahd_linux_targ_flags flags; + struct scsi_inquiry_data *inq_data; + /* + * The next "fallback" period to use for narrow/wide transfers. + */ + uint8_t dv_next_narrow_period; + uint8_t dv_next_wide_period; + uint8_t dv_max_width; + uint8_t dv_max_ppr_options; + uint8_t dv_last_ppr_options; + u_int dv_echo_size; + ahd_dv_state dv_state; + u_int dv_state_retry; + uint8_t *dv_buffer; + uint8_t *dv_buffer1; + + /* + * Cumulative counter of errors. + */ + u_long errors_detected; + u_long cmds_since_error; +}; + +/********************* Definitions Required by the Core ***********************/ +/* + * Number of SG segments we require. So long as the S/G segments for + * a particular transaction are allocated in a physically contiguous + * manner and are allocated below 4GB, the number of S/G segments is + * unrestricted. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* + * We dynamically adjust the number of segments in pre-2.5 kernels to + * avoid fragmentation issues in the SCSI mid-layer's private memory + * allocator. See aic79xx_osm.c ahd_linux_size_nseg() for details. + */ +extern u_int ahd_linux_nseg; +#define AHD_NSEG ahd_linux_nseg +#define AHD_LINUX_MIN_NSEG 64 +#else +#define AHD_NSEG 128 +#endif + +/* + * Per-SCB OSM storage. + */ +typedef enum { + AHD_SCB_UP_EH_SEM = 0x1 +} ahd_linux_scb_flags; + +struct scb_platform_data { + struct ahd_linux_device *dev; + bus_addr_t buf_busaddr; + uint32_t xfer_len; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) + uint32_t resid; /* Transfer residual */ +#endif + uint32_t sense_resid; /* Auto-Sense residual */ + ahd_linux_scb_flags flags; +}; + +/* + * Define a structure used for each host adapter. All members are + * aligned on a boundary >= the size of the member to honor the + * alignment restrictions of the various platforms supported by + * this driver. + */ +typedef enum { + AHD_DV_WAIT_SIMQ_EMPTY = 0x01, + AHD_DV_WAIT_SIMQ_RELEASE = 0x02, + AHD_DV_ACTIVE = 0x04, + AHD_DV_SHUTDOWN = 0x08, + AHD_RUN_CMPLT_Q_TIMER = 0x10 +} ahd_linux_softc_flags; + +TAILQ_HEAD(ahd_completeq, ahd_cmd); + +struct ahd_platform_data { + /* + * Fields accessed from interrupt context. + */ + struct ahd_linux_target *targets[AHD_NUM_TARGETS]; + TAILQ_HEAD(, ahd_linux_device) device_runq; + struct ahd_completeq completeq; + + spinlock_t spin_lock; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + struct tasklet_struct runq_tasklet; +#endif + u_int qfrozen; + pid_t dv_pid; + struct timer_list completeq_timer; + struct timer_list reset_timer; + struct timer_list stats_timer; + struct semaphore eh_sem; + struct semaphore dv_sem; + struct semaphore dv_cmd_sem; /* XXX This needs to be in + * the target struct + */ + struct scsi_device *dv_scsi_dev; + struct Scsi_Host *host; /* pointer to scsi host */ +#define AHD_LINUX_NOIRQ ((uint32_t)~0) + uint32_t irq; /* IRQ for this adapter */ + uint32_t bios_address; + uint32_t mem_busaddr; /* Mem Base Addr */ + bus_addr_t hw_dma_mask; + ahd_linux_softc_flags flags; +}; + +/************************** OS Utility Wrappers *******************************/ +#define printf printk +#define M_NOWAIT GFP_ATOMIC +#define M_WAITOK 0 +#define malloc(size, type, flags) kmalloc(size, flags) +#define free(ptr, type) kfree(ptr) + +static __inline void ahd_delay(long); +static __inline void +ahd_delay(long usec) +{ + /* + * udelay on Linux can have problems for + * multi-millisecond waits. Wait at most + * 1024us per call. + */ + while (usec > 0) { + udelay(usec % 1024); + usec -= 1024; + } +} + + +/***************************** Low Level I/O **********************************/ +#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__) +#define MMAPIO +#endif + +static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port); +static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port); +static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val); +static __inline void ahd_outw_atomic(struct ahd_softc * ahd, + long port, uint16_t val); +static __inline void ahd_outsb(struct ahd_softc * ahd, long port, + uint8_t *, int count); +static __inline void ahd_insb(struct ahd_softc * ahd, long port, + uint8_t *, int count); + +static __inline uint8_t +ahd_inb(struct ahd_softc * ahd, long port) +{ + uint8_t x; +#ifdef MMAPIO + + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + x = readb(ahd->bshs[0].maddr + port); + } else { + x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); + } +#else + x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); +#endif + mb(); + return (x); +} + +static __inline uint16_t +ahd_inw_atomic(struct ahd_softc * ahd, long port) +{ + uint8_t x; +#ifdef MMAPIO + + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + x = readw(ahd->bshs[0].maddr + port); + } else { + x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); + } +#else + x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); +#endif + mb(); + return (x); +} + +static __inline void +ahd_outb(struct ahd_softc * ahd, long port, uint8_t val) +{ +#ifdef MMAPIO + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + writeb(val, ahd->bshs[0].maddr + port); + } else { + outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); + } +#else + outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); +#endif + mb(); +} + +static __inline void +ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val) +{ +#ifdef MMAPIO + if (ahd->tags[0] == BUS_SPACE_MEMIO) { + writew(val, ahd->bshs[0].maddr + port); + } else { + outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); + } +#else + outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); +#endif + mb(); +} + +static __inline void +ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count) +{ + int i; + + /* + * There is probably a more efficient way to do this on Linux + * but we don't use this for anything speed critical and this + * should work. + */ + for (i = 0; i < count; i++) + ahd_outb(ahd, port, *array++); +} + +static __inline void +ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count) +{ + int i; + + /* + * There is probably a more efficient way to do this on Linux + * but we don't use this for anything speed critical and this + * should work. + */ + for (i = 0; i < count; i++) + *array++ = ahd_inb(ahd, port); +} + +/**************************** Initialization **********************************/ +int ahd_linux_register_host(struct ahd_softc *, + Scsi_Host_Template *); + +uint64_t ahd_linux_get_memsize(void); + +/*************************** Pretty Printing **********************************/ +struct info_str { + char *buffer; + int length; + off_t offset; + int pos; +}; + +void ahd_format_transinfo(struct info_str *info, + struct ahd_transinfo *tinfo); + +/******************************** Locking *************************************/ +/* Lock protecting internal data structures */ +static __inline void ahd_lockinit(struct ahd_softc *); +static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags); +static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags); + +/* Lock acquisition and release of the above lock in midlayer entry points. */ +static __inline void ahd_midlayer_entrypoint_lock(struct ahd_softc *, + unsigned long *flags); +static __inline void ahd_midlayer_entrypoint_unlock(struct ahd_softc *, + unsigned long *flags); + +/* Lock held during command compeletion to the upper layer */ +static __inline void ahd_done_lockinit(struct ahd_softc *); +static __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags); +static __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags); + +/* Lock held during ahd_list manipulation and ahd softc frees */ +extern spinlock_t ahd_list_spinlock; +static __inline void ahd_list_lockinit(void); +static __inline void ahd_list_lock(unsigned long *flags); +static __inline void ahd_list_unlock(unsigned long *flags); + +static __inline void +ahd_lockinit(struct ahd_softc *ahd) +{ + spin_lock_init(&ahd->platform_data->spin_lock); +} + +static __inline void +ahd_lock(struct ahd_softc *ahd, unsigned long *flags) +{ + spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags); +} + +static __inline void +ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ + spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags); +} + +static __inline void +ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags) +{ + /* + * In 2.5.X and some 2.4.X versions, the midlayer takes our + * lock just before calling us, so we avoid locking again. + * For other kernel versions, the io_request_lock is taken + * just before our entry point is called. In this case, we + * trade the io_request_lock for our per-softc lock. + */ +#if AHD_SCSI_HAS_HOST_LOCK == 0 + spin_unlock(&io_request_lock); + spin_lock(&ahd->platform_data->spin_lock); +#endif +} + +static __inline void +ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ +#if AHD_SCSI_HAS_HOST_LOCK == 0 + spin_unlock(&ahd->platform_data->spin_lock); + spin_lock(&io_request_lock); +#endif +} + +static __inline void +ahd_done_lockinit(struct ahd_softc *ahd) +{ + /* + * In 2.5.X, our own lock is held during completions. + * In previous versions, the io_request_lock is used. + * In either case, we can't initialize this lock again. + */ +} + +static __inline void +ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) +{ +#if AHD_SCSI_HAS_HOST_LOCK == 0 + spin_lock(&io_request_lock); +#endif +} + +static __inline void +ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) +{ +#if AHD_SCSI_HAS_HOST_LOCK == 0 + spin_unlock(&io_request_lock); +#endif +} + +static __inline void +ahd_list_lockinit() +{ + spin_lock_init(&ahd_list_spinlock); +} + +static __inline void +ahd_list_lock(unsigned long *flags) +{ + spin_lock_irqsave(&ahd_list_spinlock, *flags); +} + +static __inline void +ahd_list_unlock(unsigned long *flags) +{ + spin_unlock_irqrestore(&ahd_list_spinlock, *flags); +} + +/******************************* PCI Definitions ******************************/ +/* + * PCIM_xxx: mask to locate subfield in register + * PCIR_xxx: config register offset + * PCIC_xxx: device class + * PCIS_xxx: device subclass + * PCIP_xxx: device programming interface + * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) + * PCID_xxx: device ID + */ +#define PCIR_DEVVENDOR 0x00 +#define PCIR_VENDOR 0x00 +#define PCIR_DEVICE 0x02 +#define PCIR_COMMAND 0x04 +#define PCIM_CMD_PORTEN 0x0001 +#define PCIM_CMD_MEMEN 0x0002 +#define PCIM_CMD_BUSMASTEREN 0x0004 +#define PCIM_CMD_MWRICEN 0x0010 +#define PCIM_CMD_PERRESPEN 0x0040 +#define PCIM_CMD_SERRESPEN 0x0100 +#define PCIR_STATUS 0x06 +#define PCIR_REVID 0x08 +#define PCIR_PROGIF 0x09 +#define PCIR_SUBCLASS 0x0a +#define PCIR_CLASS 0x0b +#define PCIR_CACHELNSZ 0x0c +#define PCIR_LATTIMER 0x0d +#define PCIR_HEADERTYPE 0x0e +#define PCIM_MFDEV 0x80 +#define PCIR_BIST 0x0f +#define PCIR_CAP_PTR 0x34 + +/* config registers for header type 0 devices */ +#define PCIR_MAPS 0x10 +#define PCIR_SUBVEND_0 0x2c +#define PCIR_SUBDEV_0 0x2e + +/****************************** PCI-X definitions *****************************/ +#define PCIXR_COMMAND 0x96 +#define PCIXR_DEVADDR 0x98 +#define PCIXM_DEVADDR_FNUM 0x0003 /* Function Number */ +#define PCIXM_DEVADDR_DNUM 0x00F8 /* Device Number */ +#define PCIXM_DEVADDR_BNUM 0xFF00 /* Bus Number */ +#define PCIXR_STATUS 0x9A +#define PCIXM_STATUS_64BIT 0x0001 /* Active 64bit connection to device. */ +#define PCIXM_STATUS_133CAP 0x0002 /* Device is 133MHz capable */ +#define PCIXM_STATUS_SCDISC 0x0004 /* Split Completion Discarded */ +#define PCIXM_STATUS_UNEXPSC 0x0008 /* Unexpected Split Completion */ +#define PCIXM_STATUS_CMPLEXDEV 0x0010 /* Device Complexity (set == bridge) */ +#define PCIXM_STATUS_MAXMRDBC 0x0060 /* Maximum Burst Read Count */ +#define PCIXM_STATUS_MAXSPLITS 0x0380 /* Maximum Split Transactions */ +#define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ +#define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +extern struct pci_driver aic79xx_pci_driver; +#endif + +typedef enum +{ + AHD_POWER_STATE_D0, + AHD_POWER_STATE_D1, + AHD_POWER_STATE_D2, + AHD_POWER_STATE_D3 +} ahd_power_state; + +void ahd_power_state_change(struct ahd_softc *ahd, + ahd_power_state new_state); + +/******************************* PCI Routines *********************************/ +int ahd_linux_pci_init(void); +void ahd_linux_pci_exit(void); +int ahd_pci_map_registers(struct ahd_softc *ahd); +int ahd_pci_map_int(struct ahd_softc *ahd); + +static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci, + int reg, int width); + +static __inline uint32_t +ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width) +{ + switch (width) { + case 1: + { + uint8_t retval; + + pci_read_config_byte(pci, reg, &retval); + return (retval); + } + case 2: + { + uint16_t retval; + pci_read_config_word(pci, reg, &retval); + return (retval); + } + case 4: + { + uint32_t retval; + pci_read_config_dword(pci, reg, &retval); + return (retval); + } + default: + panic("ahd_pci_read_config: Read size too big"); + /* NOTREACHED */ + return (0); + } +} + +static __inline void ahd_pci_write_config(ahd_dev_softc_t pci, + int reg, uint32_t value, + int width); + +static __inline void +ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width) +{ + switch (width) { + case 1: + pci_write_config_byte(pci, reg, value); + break; + case 2: + pci_write_config_word(pci, reg, value); + break; + case 4: + pci_write_config_dword(pci, reg, value); + break; + default: + panic("ahd_pci_write_config: Write size too big"); + /* NOTREACHED */ + } +} + +static __inline int ahd_get_pci_function(ahd_dev_softc_t); +static __inline int +ahd_get_pci_function(ahd_dev_softc_t pci) +{ + return (PCI_FUNC(pci->devfn)); +} + +static __inline int ahd_get_pci_slot(ahd_dev_softc_t); +static __inline int +ahd_get_pci_slot(ahd_dev_softc_t pci) +{ + return (PCI_SLOT(pci->devfn)); +} + +static __inline int ahd_get_pci_bus(ahd_dev_softc_t); +static __inline int +ahd_get_pci_bus(ahd_dev_softc_t pci) +{ + return (pci->bus->number); +} + +static __inline void ahd_flush_device_writes(struct ahd_softc *); +static __inline void +ahd_flush_device_writes(struct ahd_softc *ahd) +{ + /* XXX Is this sufficient for all architectures??? */ + ahd_inb(ahd, INTSTAT); +} + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0) +#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg) +#define pci_unmap_sg(pdev, sg_list, nseg, direction) +#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address)) +#define sg_dma_len(sg) ((sg)->length) +#define pci_map_single(pdev, buffer, bufflen, direction) \ + (VIRT_TO_BUS(buffer)) +#define pci_unmap_single(pdev, buffer, buflen, direction) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) +#define ahd_pci_set_dma_mask pci_set_dma_mask +#else +/* + * Always "return" 0 for success. + */ +#define ahd_pci_set_dma_mask(dev_softc, mask) \ + (((dev_softc)->dma_mask = mask) && 0) +#endif +/**************************** Proc FS Support *********************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +int ahd_linux_proc_info(char *, char **, off_t, int, int, int); +#else +int ahd_linux_proc_info(struct Scsi_Host *, char *, char **, + off_t, int, int); +#endif + +/*************************** Domain Validation ********************************/ +#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete) +#define AHD_DV_SIMQ_FROZEN(ahd) \ + ((((ahd)->platform_data->flags & AHD_DV_ACTIVE) != 0) \ + && (ahd)->platform_data->qfrozen == 1) + +/*********************** Transaction Access Wrappers **************************/ +static __inline void ahd_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); +static __inline void ahd_set_transaction_status(struct scb *, uint32_t); +static __inline void ahd_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); +static __inline void ahd_set_scsi_status(struct scb *, uint32_t); +static __inline uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahd_get_transaction_status(struct scb *); +static __inline uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahd_get_scsi_status(struct scb *); +static __inline void ahd_set_transaction_tag(struct scb *, int, u_int); +static __inline u_long ahd_get_transfer_length(struct scb *); +static __inline int ahd_get_transfer_dir(struct scb *); +static __inline void ahd_set_residual(struct scb *, u_long); +static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid); +static __inline u_long ahd_get_residual(struct scb *); +static __inline u_long ahd_get_sense_residual(struct scb *); +static __inline int ahd_perform_autosense(struct scb *); +static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *, + struct scb *); +static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *, + struct ahd_devinfo *); +static __inline void ahd_platform_scb_free(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_freeze_scb(struct scb *scb); + +static __inline +void ahd_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~(CAM_STATUS_MASK << 16); + cmd->result |= status << 16; +} + +static __inline +void ahd_set_transaction_status(struct scb *scb, uint32_t status) +{ + ahd_cmd_set_transaction_status(scb->io_ctx,status); +} + +static __inline +void ahd_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~0xFFFF; + cmd->result |= status; +} + +static __inline +void ahd_set_scsi_status(struct scb *scb, uint32_t status) +{ + ahd_cmd_set_scsi_status(scb->io_ctx, status); +} + +static __inline +uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd) +{ + return ((cmd->result >> 16) & CAM_STATUS_MASK); +} + +static __inline +uint32_t ahd_get_transaction_status(struct scb *scb) +{ + return (ahd_cmd_get_transaction_status(scb->io_ctx)); +} + +static __inline +uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd) +{ + return (cmd->result & 0xFFFF); +} + +static __inline +uint32_t ahd_get_scsi_status(struct scb *scb) +{ + return (ahd_cmd_get_scsi_status(scb->io_ctx)); +} + +static __inline +void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type) +{ + /* + * Nothing to do for linux as the incoming transaction + * has no concept of tag/non tagged, etc. + */ +} + +static __inline +u_long ahd_get_transfer_length(struct scb *scb) +{ + return (scb->platform_data->xfer_len); +} + +static __inline +int ahd_get_transfer_dir(struct scb *scb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40) + return (scb->io_ctx->sc_data_direction); +#else + if (scb->io_ctx->bufflen == 0) + return (CAM_DIR_NONE); + + switch(scb->io_ctx->cmnd[0]) { + case 0x08: /* READ(6) */ + case 0x28: /* READ(10) */ + case 0xA8: /* READ(12) */ + return (CAM_DIR_IN); + case 0x0A: /* WRITE(6) */ + case 0x2A: /* WRITE(10) */ + case 0xAA: /* WRITE(12) */ + return (CAM_DIR_OUT); + default: + return (CAM_DIR_NONE); + } +#endif +} + +static __inline +void ahd_set_residual(struct scb *scb, u_long resid) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + scb->io_ctx->resid = resid; +#else + scb->platform_data->resid = resid; +#endif +} + +static __inline +void ahd_set_sense_residual(struct scb *scb, u_long resid) +{ + scb->platform_data->sense_resid = resid; +} + +static __inline +u_long ahd_get_residual(struct scb *scb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + return (scb->io_ctx->resid); +#else + return (scb->platform_data->resid); +#endif +} + +static __inline +u_long ahd_get_sense_residual(struct scb *scb) +{ + return (scb->platform_data->sense_resid); +} + +static __inline +int ahd_perform_autosense(struct scb *scb) +{ + /* + * We always perform autosense in Linux. + * On other platforms this is set on a + * per-transaction basis. + */ + return (1); +} + +static __inline uint32_t +ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb) +{ + return (sizeof(struct scsi_sense_data)); +} + +static __inline void +ahd_notify_xfer_settings_change(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo) +{ + /* Nothing to do here for linux */ +} + +static __inline void +ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb) +{ + ahd->flags &= ~AHD_RESOURCE_SHORTAGE; +} + +int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); +void ahd_platform_free(struct ahd_softc *ahd); +void ahd_platform_init(struct ahd_softc *ahd); +void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb); +void ahd_freeze_simq(struct ahd_softc *ahd); +void ahd_release_simq(struct ahd_softc *ahd); + +static __inline void +ahd_freeze_scb(struct scb *scb) +{ + if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) { + scb->io_ctx->result |= CAM_DEV_QFRZN << 16; + scb->platform_data->dev->qfrozen++; + } +} + +void ahd_platform_set_tags(struct ahd_softc *ahd, + struct ahd_devinfo *devinfo, ahd_queue_alg); +int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status); +irqreturn_t + ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); +void ahd_platform_flushwork(struct ahd_softc *ahd); +int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *); +void ahd_done(struct ahd_softc*, struct scb*); +void ahd_send_async(struct ahd_softc *, char channel, + u_int target, u_int lun, ac_code, void *); +void ahd_print_path(struct ahd_softc *, struct scb *); +void ahd_platform_dump_card_state(struct ahd_softc *ahd); + +#ifdef CONFIG_PCI +#define AHD_PCI_CONFIG 1 +#else +#define AHD_PCI_CONFIG 0 +#endif +#define bootverbose aic79xx_verbose +extern uint32_t aic79xx_verbose; +#endif /* _AIC79XX_LINUX_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_osm_pci.c linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_osm_pci.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,447 @@ +/* + * Linux driver attachment glue for PCI based U320 controllers. + * + * Copyright (c) 2000-2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#24 $ + */ + +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +struct pci_device_id +{ +}; +#endif + +static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, + u_long *base, u_long *base2); +static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, + u_long *bus_addr, + uint8_t **maddr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); + +/* We do our own ID filtering. So, grab all SCSI storage class devices. */ +static struct pci_device_id ahd_linux_pci_id_table[] = { + { + 0x9005, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0 + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); + +struct pci_driver aic79xx_pci_driver = { + name: "aic79xx", + probe: ahd_linux_pci_dev_probe, + remove: ahd_linux_pci_dev_remove, + id_table: ahd_linux_pci_id_table +}; + +static void +ahd_linux_pci_dev_remove(struct pci_dev *pdev) +{ + struct ahd_softc *ahd; + u_long l; + + /* + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. + */ + ahd_list_lock(&l); + ahd = ahd_find_softc((struct ahd_softc *)pci_get_drvdata(pdev)); + if (ahd != NULL) { + u_long s; + + ahd_lock(ahd, &s); + ahd_intr_enable(ahd, FALSE); + ahd_unlock(ahd, &s); + ahd_free(ahd); + } + ahd_list_unlock(&l); +} +#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */ + +static int +ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + char buf[80]; + struct ahd_softc *ahd; + ahd_dev_softc_t pci; + struct ahd_pci_identity *entry; + char *name; + int error; + + /* + * Some BIOSen report the same device multiple times. + */ + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + struct pci_dev *probed_pdev; + + probed_pdev = ahd->dev_softc; + if (probed_pdev->bus->number == pdev->bus->number + && probed_pdev->devfn == pdev->devfn) + break; + } + if (ahd != NULL) { + /* Skip duplicate. */ + return (-ENODEV); + } + + pci = pdev; + entry = ahd_find_pci_device(pci); + if (entry == NULL) + return (-ENODEV); + + /* + * Allocate a softc for this card and + * set it up for attachment by our + * common detect routine. + */ + sprintf(buf, "ahd_pci:%d:%d:%d", + ahd_get_pci_bus(pci), + ahd_get_pci_slot(pci), + ahd_get_pci_function(pci)); + name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); + if (name == NULL) + return (-ENOMEM); + strcpy(name, buf); + ahd = ahd_alloc(NULL, name); + if (ahd == NULL) + return (-ENOMEM); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + if (pci_enable_device(pdev)) { + ahd_free(ahd); + return (-ENODEV); + } + pci_set_master(pdev); + + if (sizeof(bus_addr_t) > 4) { + uint64_t memsize; + bus_addr_t mask_64bit; + bus_addr_t mask_39bit; + + memsize = ahd_linux_get_memsize(); + mask_64bit = (bus_addr_t)0xFFFFFFFFFFFFFFFFULL; + mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL; + if (memsize >= 0x8000000000ULL + && ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) { + ahd->flags |= AHD_64BIT_ADDRESSING; + ahd->platform_data->hw_dma_mask = mask_64bit; + } else if (memsize > 0x80000000 + && ahd_pci_set_dma_mask(pdev, mask_39bit) == 0) { + ahd->flags |= AHD_39BIT_ADDRESSING; + ahd->platform_data->hw_dma_mask = mask_39bit; + } + } else { + ahd_pci_set_dma_mask(pdev, 0xFFFFFFFF); + ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; + } +#endif + ahd->dev_softc = pci; + error = ahd_pci_config(ahd, entry); + if (error != 0) { + ahd_free(ahd); + return (-error); + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + pci_set_drvdata(pdev, ahd); + if (aic79xx_detect_complete) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahd_linux_register_host(ahd, &aic79xx_driver_template); +#else + printf("aic79xx: ignoring PCI device found after " + "initialization\n"); + return (-ENODEV); +#endif + } +#endif + return (0); +} + +int +ahd_linux_pci_init(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + return (pci_module_init(&aic79xx_pci_driver)); +#else + struct pci_dev *pdev; + u_int class; + int found; + + /* If we don't have a PCI bus, we can't find any adapters. */ + if (pci_present() == 0) + return (0); + + found = 0; + pdev = NULL; + class = PCI_CLASS_STORAGE_SCSI << 8; + while ((pdev = pci_find_class(class, pdev)) != NULL) { + ahd_dev_softc_t pci; + int error; + + pci = pdev; + error = ahd_linux_pci_dev_probe(pdev, /*pci_devid*/NULL); + if (error == 0) + found++; + } + return (found); +#endif +} + +void +ahd_linux_pci_exit(void) +{ + pci_unregister_driver(&aic79xx_pci_driver); +} + +static int +ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base, + u_long *base2) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + *base = pci_resource_start(ahd->dev_softc, 0); + /* + * This is really the 3rd bar and should be at index 2, + * but the Linux PCI code doesn't know how to "count" 64bit + * bars. + */ + *base2 = pci_resource_start(ahd->dev_softc, 3); +#else + *base = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR0, 4); + *base2 = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR1, 4); + *base &= PCI_BASE_ADDRESS_IO_MASK; + *base2 &= PCI_BASE_ADDRESS_IO_MASK; +#endif + if (*base == 0 || *base2 == 0) + return (ENOMEM); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + if (check_region(*base, 256) != 0 + || check_region(*base2, 256) != 0) + return (ENOMEM); + request_region(*base, 256, "aic79xx"); + request_region(*base2, 256, "aic79xx"); +#else + if (request_region(*base, 256, "aic79xx") == 0) + return (ENOMEM); + if (request_region(*base2, 256, "aic79xx") == 0) { + release_region(*base2, 256); + return (ENOMEM); + } +#endif + return (0); +} + +static int +ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, + u_long *bus_addr, + uint8_t **maddr) +{ + u_long start; + u_long base_page; + u_long base_offset; + int error; + + if (aic79xx_allow_memio == 0) + return (ENOMEM); + + if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0) + return (ENOMEM); + + error = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + start = pci_resource_start(ahd->dev_softc, 1); + base_page = start & PAGE_MASK; + base_offset = start - base_page; +#else + start = ahd_pci_read_config(ahd->dev_softc, PCIR_MAPS+4, 4); + base_offset = start & PCI_BASE_ADDRESS_MEM_MASK; + base_page = base_offset & PAGE_MASK; + base_offset -= base_page; +#endif + if (start != 0) { + *bus_addr = start; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + if (request_mem_region(start, 0x1000, "aic79xx") == 0) + error = ENOMEM; +#endif + if (error == 0) { + *maddr = ioremap_nocache(base_page, base_offset + 256); + if (*maddr == NULL) { + error = ENOMEM; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(start, 0x1000); +#endif + } else + *maddr += base_offset; + } + } else + error = ENOMEM; + return (error); +} + +int +ahd_pci_map_registers(struct ahd_softc *ahd) +{ + uint32_t command; + u_long base; + uint8_t *maddr; + int error; + + /* + * If its allowed, we prefer memory mapped access. + */ + command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4); + command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); + base = 0; + maddr = NULL; +#ifdef MMAPIO + error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr); + if (error == 0) { + ahd->platform_data->mem_busaddr = base; + ahd->tags[0] = BUS_SPACE_MEMIO; + ahd->bshs[0].maddr = maddr; + ahd->tags[1] = BUS_SPACE_MEMIO; + ahd->bshs[1].maddr = maddr + 0x100; + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + command | PCIM_CMD_MEMEN, 4); + + if (ahd_pci_test_register_access(ahd) != 0) { + + printf("aic79xx: PCI Device %d:%d:%d " + "failed memory mapped test. Using PIO.\n", + ahd_get_pci_bus(ahd->dev_softc), + ahd_get_pci_slot(ahd->dev_softc), + ahd_get_pci_function(ahd->dev_softc)); + iounmap((void *)((u_long)maddr & PAGE_MASK)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(ahd->platform_data->mem_busaddr, + 0x1000); +#endif + ahd->bshs[0].maddr = NULL; + maddr = NULL; + } else + command |= PCIM_CMD_MEMEN; + } else if (bootverbose) { + printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx " + "unavailable. Cannot memory map device.\n", + ahd_get_pci_bus(ahd->dev_softc), + ahd_get_pci_slot(ahd->dev_softc), + ahd_get_pci_function(ahd->dev_softc), + base); + } +#endif + + if (maddr == NULL) { + u_long base2; + + error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2); + if (error == 0) { + ahd->tags[0] = BUS_SPACE_PIO; + ahd->tags[1] = BUS_SPACE_PIO; + ahd->bshs[0].ioport = base; + ahd->bshs[1].ioport = base2; + command |= PCIM_CMD_PORTEN; + } else { + printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx" + "unavailable. Cannot map device.\n", + ahd_get_pci_bus(ahd->dev_softc), + ahd_get_pci_slot(ahd->dev_softc), + ahd_get_pci_function(ahd->dev_softc), + base, base2); + } + } + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4); + return (error); +} + +int +ahd_pci_map_int(struct ahd_softc *ahd) +{ + int error; + + error = request_irq(ahd->dev_softc->irq, ahd_linux_isr, + SA_SHIRQ, "aic79xx", ahd); + if (error == 0) + ahd->platform_data->irq = ahd->dev_softc->irq; + + return (-error); +} + +void +ahd_power_state_change(struct ahd_softc *ahd, ahd_power_state new_state) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + pci_set_power_state(ahd->dev_softc, new_state); +#else + uint32_t cap; + u_int cap_offset; + + /* + * Traverse the capability list looking for + * the power management capability. + */ + cap = 0; + cap_offset = ahd_pci_read_config(ahd->dev_softc, + PCIR_CAP_PTR, /*bytes*/1); + while (cap_offset != 0) { + + cap = ahd_pci_read_config(ahd->dev_softc, + cap_offset, /*bytes*/4); + if ((cap & 0xFF) == 1 + && ((cap >> 16) & 0x3) > 0) { + uint32_t pm_control; + + pm_control = ahd_pci_read_config(ahd->dev_softc, + cap_offset + 4, + /*bytes*/4); + pm_control &= ~0x3; + pm_control |= new_state; + ahd_pci_write_config(ahd->dev_softc, + cap_offset + 4, + pm_control, /*bytes*/2); + break; + } + cap_offset = (cap >> 8) & 0xFF; + } +#endif +} diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_pci.c linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_pci.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_pci.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1006 @@ +/* + * Product specific probe and attach routines for: + * aic7901 and aic7902 SCSI controllers + * + * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#75 $ + * + * $FreeBSD$ + */ + +#ifdef __linux__ +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" +#else +#include +#include +#endif + +static __inline uint64_t +ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) +{ + uint64_t id; + + id = subvendor + | (subdevice << 16) + | ((uint64_t)vendor << 32) + | ((uint64_t)device << 48); + + return (id); +} + +#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull +#define ID_ALL_IROC_MASK 0xFFFFFF7FFFFFFFFFull +#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull +#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull +#define ID_9005_GENERIC_IROC_MASK 0xFFF0FF7F00000000ull + +#define ID_AIC7901 0x800F9005FFFF9005ull +#define ID_AHA_29320A 0x8000900500609005ull +#define ID_AHA_29320ALP 0x8017900500449005ull + +#define ID_AIC7901A 0x801E9005FFFF9005ull +#define ID_AHA_29320 0x8012900500429005ull +#define ID_AHA_29320B 0x8013900500439005ull +#define ID_AHA_29320LP 0x8014900500449005ull + +#define ID_AIC7902 0x801F9005FFFF9005ull +#define ID_AIC7902_B 0x801D9005FFFF9005ull +#define ID_AHA_39320 0x8010900500409005ull +#define ID_AHA_39320_B 0x8015900500409005ull +#define ID_AHA_39320A 0x8016900500409005ull +#define ID_AHA_39320D 0x8011900500419005ull +#define ID_AHA_39320D_B 0x801C900500419005ull +#define ID_AHA_39320D_HP 0x8011900500AC0E11ull +#define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull +#define ID_AIC7902_PCI_REV_A4 0x3 +#define ID_AIC7902_PCI_REV_B0 0x10 +#define SUBID_HP 0x0E11 + +#define DEVID_9005_TYPE(id) ((id) & 0xF) +#define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */ +#define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */ +#define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */ +#define DEVID_9005_TYPE_MB 0xF /* On Motherboard */ + +#define DEVID_9005_MFUNC(id) ((id) & 0x10) + +#define DEVID_9005_PACKETIZED(id) ((id) & 0x8000) + +#define SUBID_9005_TYPE(id) ((id) & 0xF) +#define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */ +#define SUBID_9005_TYPE_MB 0xF /* On Motherboard */ + +#define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0) + +#define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20) + +#define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6) +#define SUBID_9005_SEEPTYPE_NONE 0x0 +#define SUBID_9005_SEEPTYPE_4K 0x1 + +static ahd_device_setup_t ahd_aic7901_setup; +static ahd_device_setup_t ahd_aic7901A_setup; +static ahd_device_setup_t ahd_aic7902_setup; + +struct ahd_pci_identity ahd_pci_ident_table [] = +{ + /* aic7901 based controllers */ + { + ID_AHA_29320A, + ID_ALL_MASK, + "Adaptec 29320A Ultra320 SCSI adapter", + ahd_aic7901_setup + }, + { + ID_AHA_29320ALP, + ID_ALL_MASK, + "Adaptec 29320ALP Ultra320 SCSI adapter", + ahd_aic7901_setup + }, + /* aic7901A based controllers */ + { + ID_AHA_29320, + ID_ALL_MASK, + "Adaptec 29320 Ultra320 SCSI adapter", + ahd_aic7901A_setup + }, + { + ID_AHA_29320B, + ID_ALL_MASK, + "Adaptec 29320B Ultra320 SCSI adapter", + ahd_aic7901A_setup + }, + { + ID_AHA_29320LP, + ID_ALL_MASK, + "Adaptec 29320LP Ultra320 SCSI adapter", + ahd_aic7901A_setup + }, + /* aic7902 based controllers */ + { + ID_AHA_39320, + ID_ALL_MASK, + "Adaptec 39320 Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320_B, + ID_ALL_MASK, + "Adaptec 39320 Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320A, + ID_ALL_MASK, + "Adaptec 39320A Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D, + ID_ALL_MASK, + "Adaptec 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D_HP, + ID_ALL_MASK, + "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D_B, + ID_ALL_MASK, + "Adaptec 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_39320D_B_HP, + ID_ALL_MASK, + "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_29320, + ID_ALL_MASK, + "Adaptec 29320 Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + { + ID_AHA_29320B, + ID_ALL_MASK, + "Adaptec 29320B Ultra320 SCSI adapter", + ahd_aic7902_setup + }, + /* Generic chip probes for devices we don't know 'exactly' */ + { + ID_AIC7901 & ID_DEV_VENDOR_MASK, + ID_DEV_VENDOR_MASK, + "Adaptec AIC7901 Ultra320 SCSI adapter", + ahd_aic7901_setup + }, + { + ID_AIC7901A & ID_DEV_VENDOR_MASK, + ID_DEV_VENDOR_MASK, + "Adaptec AIC7901A Ultra320 SCSI adapter", + ahd_aic7901A_setup + }, + { + ID_AIC7902 & ID_9005_GENERIC_MASK, + ID_9005_GENERIC_MASK, + "Adaptec AIC7902 Ultra320 SCSI adapter", + ahd_aic7902_setup + } +}; + +const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table); + +#define DEVCONFIG 0x40 +#define PCIXINITPAT 0x0000E000ul +#define PCIXINIT_PCI33_66 0x0000E000ul +#define PCIXINIT_PCIX50_66 0x0000C000ul +#define PCIXINIT_PCIX66_100 0x0000A000ul +#define PCIXINIT_PCIX100_133 0x00008000ul +#define PCI_BUS_MODES_INDEX(devconfig) \ + (((devconfig) & PCIXINITPAT) >> 13) +static const char *pci_bus_modes[] = +{ + "PCI bus mode unknown", + "PCI bus mode unknown", + "PCI bus mode unknown", + "PCI bus mode unknown", + "PCI-X 101-133Mhz", + "PCI-X 67-100Mhz", + "PCI-X 50-66Mhz", + "PCI 33 or 66Mhz" +}; + +#define TESTMODE 0x00000800ul +#define IRDY_RST 0x00000200ul +#define FRAME_RST 0x00000100ul +#define PCI64BIT 0x00000080ul +#define MRDCEN 0x00000040ul +#define ENDIANSEL 0x00000020ul +#define MIXQWENDIANEN 0x00000008ul +#define DACEN 0x00000004ul +#define STPWLEVEL 0x00000002ul +#define QWENDIANSEL 0x00000001ul + +#define DEVCONFIG1 0x44 +#define PREQDIS 0x01 + +#define CSIZE_LATTIME 0x0c +#define CACHESIZE 0x000000fful +#define LATTIME 0x0000ff00ul + +static int ahd_check_extport(struct ahd_softc *ahd); +static void ahd_configure_termination(struct ahd_softc *ahd, + u_int adapter_control); +static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); + +struct ahd_pci_identity * +ahd_find_pci_device(ahd_dev_softc_t pci) +{ + uint64_t full_id; + uint16_t device; + uint16_t vendor; + uint16_t subdevice; + uint16_t subvendor; + struct ahd_pci_identity *entry; + u_int i; + + vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2); + device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2); + subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2); + subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2); + full_id = ahd_compose_id(device, + vendor, + subdevice, + subvendor); + + for (i = 0; i < ahd_num_pci_devs; i++) { + entry = &ahd_pci_ident_table[i]; + if (entry->full_id == (full_id & entry->id_mask)) { + /* Honor exclusion entries. */ + if (entry->name == NULL) + return (NULL); + return (entry); + } + } + return (NULL); +} + +int +ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) +{ + struct scb_data *shared_scb_data; + u_long l; + u_int command; + uint32_t devconfig; + uint16_t subvendor; + int error; + + shared_scb_data = NULL; + ahd->description = entry->name; + /* + * Record if this is an HP board. + */ + subvendor = ahd_pci_read_config(ahd->dev_softc, + PCIR_SUBVEND_0, /*bytes*/2); + if (subvendor == SUBID_HP) + ahd->flags |= AHD_HP_BOARD; + + error = entry->setup(ahd); + if (error != 0) + return (error); + + devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4); + if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) { + ahd->chip |= AHD_PCI; + /* Disable PCIX workarounds when running in PCI mode. */ + ahd->bugs &= ~AHD_PCIX_BUG_MASK; + } else { + ahd->chip |= AHD_PCIX; + } + ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)]; + + ahd_power_state_change(ahd, AHD_POWER_STATE_D0); + + error = ahd_pci_map_registers(ahd); + if (error != 0) + return (error); + + /* + * If we need to support high memory, enable dual + * address cycles. This bit must be set to enable + * high address bit generation even if we are on a + * 64bit bus (PCI64BIT set in devconfig). + */ + if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) { + uint32_t devconfig; + + if (bootverbose) + printf("%s: Enabling 39Bit Addressing\n", + ahd_name(ahd)); + devconfig = ahd_pci_read_config(ahd->dev_softc, + DEVCONFIG, /*bytes*/4); + devconfig |= DACEN; + ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, + devconfig, /*bytes*/4); + } + + /* Ensure busmastering is enabled */ + command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2); + command |= PCIM_CMD_BUSMASTEREN; + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2); + + error = ahd_softc_init(ahd); + if (error != 0) + return (error); + + ahd->bus_intr = ahd_pci_intr; + + error = ahd_reset(ahd, /*reinit*/FALSE); + if (error != 0) + return (ENXIO); + + ahd->pci_cachesize = + ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, + /*bytes*/1) & CACHESIZE; + ahd->pci_cachesize *= 4; + + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + /* See if we have a SEEPROM and perform auto-term */ + error = ahd_check_extport(ahd); + if (error != 0) + return (error); + + /* Core initialization */ + error = ahd_init(ahd); + if (error != 0) + return (error); + + /* + * Allow interrupts now that we are completely setup. + */ + error = ahd_pci_map_int(ahd); + if (error != 0) + return (error); + + ahd_list_lock(&l); + /* + * Link this softc in with all other ahd instances. + */ + ahd_softc_insert(ahd); + ahd_list_unlock(&l); + return (0); +} + +/* + * Perform some simple tests that should catch situations where + * our registers are invalidly mapped. + */ +int +ahd_pci_test_register_access(struct ahd_softc *ahd) +{ + uint32_t cmd; + u_int targpcistat; + u_int pci_status1; + int error; + uint8_t hcntrl; + + error = EIO; + + /* + * Enable PCI error interrupt status, but suppress NMIs + * generated by SERR raised due to target aborts. + */ + cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, + cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); + + /* + * First a simple test to see if any + * registers can be read. Reading + * HCNTRL has no side effects and has + * at least one bit that is guaranteed to + * be zero so it is a good register to + * use for this test. + */ + hcntrl = ahd_inb(ahd, HCNTRL); + if (hcntrl == 0xFF) + goto fail; + + /* + * Next create a situation where write combining + * or read prefetching could be initiated by the + * CPU or host bridge. Our device does not support + * either, so look for data corruption and/or flaged + * PCI errors. + */ + ahd_outb(ahd, HCNTRL, hcntrl|PAUSE); + while (ahd_is_paused(ahd) == 0) + ; + + /* Clear any PCI errors that occurred before our driver attached. */ + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + targpcistat = ahd_inb(ahd, TARGPCISTAT); + ahd_outb(ahd, TARGPCISTAT, targpcistat); + pci_status1 = ahd_pci_read_config(ahd->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, + pci_status1, /*bytes*/1); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRINT, CLRPCIINT); + + ahd_outb(ahd, SEQCTL0, PERRORDIS); + ahd_outl(ahd, SRAM_BASE, 0x5aa555aa); + if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa) + goto fail; + + if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { + u_int targpcistat; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + targpcistat = ahd_inb(ahd, TARGPCISTAT); + if ((targpcistat & STA) != 0) + goto fail; + } + + error = 0; + +fail: + if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + targpcistat = ahd_inb(ahd, TARGPCISTAT); + + /* Silently clear any latched errors. */ + ahd_outb(ahd, TARGPCISTAT, targpcistat); + pci_status1 = ahd_pci_read_config(ahd->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, + pci_status1, /*bytes*/1); + ahd_outb(ahd, CLRINT, CLRPCIINT); + } + ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS); + ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); + return (error); +} + +/* + * Check the external port logic for a serial eeprom + * and termination/cable detection contrls. + */ +static int +ahd_check_extport(struct ahd_softc *ahd) +{ + struct vpd_config vpd; + struct seeprom_config *sc; + u_int adapter_control; + int have_seeprom; + int error; + + sc = ahd->seep_config; + have_seeprom = ahd_acquire_seeprom(ahd); + if (have_seeprom) { + u_int start_addr; + + /* + * Fetch VPD for this function and parse it. + */ + if (bootverbose) + printf("%s: Reading VPD from SEEPROM...", + ahd_name(ahd)); + + /* Address is always in units of 16bit words */ + start_addr = ((2 * sizeof(*sc)) + + (sizeof(vpd) * (ahd->channel - 'A'))) / 2; + + error = ahd_read_seeprom(ahd, (uint16_t *)&vpd, + start_addr, sizeof(vpd)/2, + /*bytestream*/TRUE); + if (error == 0) + error = ahd_parse_vpddata(ahd, &vpd); + if (bootverbose) + printf("%s: VPD parsing %s\n", + ahd_name(ahd), + error == 0 ? "successful" : "failed"); + + if (bootverbose) + printf("%s: Reading SEEPROM...", ahd_name(ahd)); + + /* Address is always in units of 16bit words */ + start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A'); + + error = ahd_read_seeprom(ahd, (uint16_t *)sc, + start_addr, sizeof(*sc)/2, + /*bytestream*/FALSE); + + if (error != 0) { + printf("Unable to read SEEPROM\n"); + have_seeprom = 0; + } else { + have_seeprom = ahd_verify_cksum(sc); + + if (bootverbose) { + if (have_seeprom == 0) + printf ("checksum error\n"); + else + printf ("done.\n"); + } + } + ahd_release_seeprom(ahd); + } + + if (!have_seeprom) { + u_int nvram_scb; + + /* + * Pull scratch ram settings and treat them as + * if they are the contents of an seeprom if + * the 'ADPT', 'BIOS', or 'ASPI' signature is found + * in SCB 0xFF. We manually compose the data as 16bit + * values to avoid endian issues. + */ + ahd_set_scbptr(ahd, 0xFF); + nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET); + if (nvram_scb != 0xFF + && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' + && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D' + && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' + && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T') + || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B' + && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I' + && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O' + && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S') + || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' + && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S' + && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' + && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) { + uint16_t *sc_data; + int i; + + ahd_set_scbptr(ahd, nvram_scb); + sc_data = (uint16_t *)sc; + for (i = 0; i < 64; i += 2) + *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i); + have_seeprom = ahd_verify_cksum(sc); + if (have_seeprom) + ahd->flags |= AHD_SCB_CONFIG_USED; + } + } + +#if AHD_DEBUG + if (have_seeprom != 0 + && (ahd_debug & AHD_DUMP_SEEPROM) != 0) { + uint16_t *sc_data; + int i; + + printf("%s: Seeprom Contents:", ahd_name(ahd)); + sc_data = (uint16_t *)sc; + for (i = 0; i < (sizeof(*sc)); i += 2) + printf("\n\t0x%.4x", sc_data[i]); + printf("\n"); + } +#endif + + if (!have_seeprom) { + if (bootverbose) + printf("%s: No SEEPROM available.\n", ahd_name(ahd)); + ahd->flags |= AHD_USEDEFAULTS; + error = ahd_default_config(ahd); + adapter_control = CFAUTOTERM|CFSEAUTOTERM; + free(ahd->seep_config, M_DEVBUF); + ahd->seep_config = NULL; + } else { + error = ahd_parse_cfgdata(ahd, sc); + adapter_control = sc->adapter_control; + } + if (error != 0) + return (error); + + ahd_configure_termination(ahd, adapter_control); + + return (0); +} + +static void +ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control) +{ + int error; + u_int sxfrctl1; + uint8_t termctl; + uint32_t devconfig; + + devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4); + devconfig &= ~STPWLEVEL; + if ((ahd->flags & AHD_STPWLEVEL_A) != 0) + devconfig |= STPWLEVEL; + if (bootverbose) + printf("%s: STPWLEVEL is %s\n", + ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off"); + ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); + + /* Make sure current sensing is off. */ + if ((ahd->flags & AHD_CURRENT_SENSING) != 0) { + (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0); + } + + /* + * Read to sense. Write to set. + */ + error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl); + if ((adapter_control & CFAUTOTERM) == 0) { + if (bootverbose) + printf("%s: Manual Primary Termination\n", + ahd_name(ahd)); + termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH); + if ((adapter_control & CFSTERM) != 0) + termctl |= FLX_TERMCTL_ENPRILOW; + if ((adapter_control & CFWSTERM) != 0) + termctl |= FLX_TERMCTL_ENPRIHIGH; + } else if (error != 0) { + printf("%s: Primary Auto-Term Sensing failed! " + "Using Defaults.\n", ahd_name(ahd)); + termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH; + } + + if ((adapter_control & CFSEAUTOTERM) == 0) { + if (bootverbose) + printf("%s: Manual Secondary Termination\n", + ahd_name(ahd)); + termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH); + if ((adapter_control & CFSELOWTERM) != 0) + termctl |= FLX_TERMCTL_ENSECLOW; + if ((adapter_control & CFSEHIGHTERM) != 0) + termctl |= FLX_TERMCTL_ENSECHIGH; + } else if (error != 0) { + printf("%s: Secondary Auto-Term Sensing failed! " + "Using Defaults.\n", ahd_name(ahd)); + termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH; + } + + /* + * Now set the termination based on what we found. + */ + sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN; + if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) { + ahd->flags |= AHD_TERM_ENB_A; + sxfrctl1 |= STPWEN; + } + /* Must set the latch once in order to be effective. */ + ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN); + ahd_outb(ahd, SXFRCTL1, sxfrctl1); + + error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl); + if (error != 0) { + printf("%s: Unable to set termination settings!\n", + ahd_name(ahd)); + } else if (bootverbose) { + printf("%s: Primary High byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis"); + + printf("%s: Primary Low byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis"); + + printf("%s: Secondary High byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis"); + + printf("%s: Secondary Low byte termination %sabled\n", + ahd_name(ahd), + (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis"); + } + return; +} + +#define DPE 0x80 +#define SSE 0x40 +#define RMA 0x20 +#define RTA 0x10 +#define STA 0x08 +#define DPR 0x01 + +static const char *split_status_source[] = +{ + "DFF0", + "DFF1", + "OVLY", + "CMC", +}; + +static const char *pci_status_source[] = +{ + "DFF0", + "DFF1", + "SG", + "CMC", + "OVLY", + "NONE", + "MSI", + "TARG" +}; + +static const char *split_status_strings[] = +{ + "%s: Received split response in %s.\n", + "%s: Received split completion error message in %s\n", + "%s: Receive overrun in %s\n", + "%s: Count not complete in %s\n", + "%s: Split completion data bucket in %s\n", + "%s: Split completion address error in %s\n", + "%s: Split completion byte count error in %s\n", + "%s: Signaled Target-abort to early terminate a split in %s\n" +}; + +static const char *pci_status_strings[] = +{ + "%s: Data Parity Error has been reported via PERR# in %s\n", + "%s: Target initial wait state error in %s\n", + "%s: Split completion read data parity error in %s\n", + "%s: Split completion address attribute parity error in %s\n", + "%s: Received a Target Abort in %s\n", + "%s: Received a Master Abort in %s\n", + "%s: Signal System Error Detected in %s\n", + "%s: Address or Write Phase Parity Error Detected in %s.\n" +}; + +void +ahd_pci_intr(struct ahd_softc *ahd) +{ + uint8_t pci_status[8]; + ahd_mode_state saved_modes; + u_int pci_status1; + u_int intstat; + u_int i; + u_int reg; + + intstat = ahd_inb(ahd, INTSTAT); + + if ((intstat & SPLTINT) != 0) + ahd_pci_split_intr(ahd, intstat); + + if ((intstat & PCIINT) == 0) + return; + + printf("%s: PCI error Interrupt\n", ahd_name(ahd)); + saved_modes = ahd_save_modes(ahd); + ahd_dump_card_state(ahd); + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) { + + if (i == 5) + continue; + pci_status[i] = ahd_inb(ahd, reg); + /* Clear latched errors. So our interrupt deasserts. */ + ahd_outb(ahd, reg, pci_status[i]); + } + + for (i = 0; i < 8; i++) { + u_int bit; + + if (i == 5) + continue; + + for (bit = 0; bit < 8; bit++) { + + if ((pci_status[i] & (0x1 << bit)) != 0) { + static const char *s; + + s = pci_status_strings[bit]; + if (i == 7/*TARG*/ && bit == 3) + s = "%s: Signaled Target Abort\n"; + printf(s, ahd_name(ahd), pci_status_source[i]); + } + } + } + pci_status1 = ahd_pci_read_config(ahd->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, + pci_status1, /*bytes*/1); + ahd_restore_modes(ahd, saved_modes); + ahd_outb(ahd, CLRINT, CLRPCIINT); + ahd_unpause(ahd); +} + +static void +ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) +{ + uint8_t split_status[4]; + uint8_t split_status1[4]; + uint8_t sg_split_status[2]; + uint8_t sg_split_status1[2]; + ahd_mode_state saved_modes; + u_int i; + uint16_t pcix_status; + + /* + * Check for splits in all modes. Modes 0 and 1 + * additionally have SG engine splits to look at. + */ + pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS, + /*bytes*/2); + printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n", + ahd_name(ahd), pcix_status); + saved_modes = ahd_save_modes(ahd); + for (i = 0; i < 4; i++) { + ahd_set_modes(ahd, i, i); + + split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0); + split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1); + /* Clear latched errors. So our interrupt deasserts. */ + ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]); + ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]); + if (i > 1) + continue; + sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0); + sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1); + /* Clear latched errors. So our interrupt deasserts. */ + ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]); + ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]); + } + + for (i = 0; i < 4; i++) { + u_int bit; + + for (bit = 0; bit < 8; bit++) { + + if ((split_status[i] & (0x1 << bit)) != 0) { + static const char *s; + + s = split_status_strings[bit]; + printf(s, ahd_name(ahd), + split_status_source[i]); + } + + if (i > 1) + continue; + + if ((sg_split_status[i] & (0x1 << bit)) != 0) { + static const char *s; + + s = split_status_strings[bit]; + printf(s, ahd_name(ahd), "SG"); + } + } + } + /* + * Clear PCI-X status bits. + */ + ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS, + pcix_status, /*bytes*/2); + ahd_outb(ahd, CLRINT, CLRSPLTINT); + ahd_restore_modes(ahd, saved_modes); +} + +static int +ahd_aic7901_setup(struct ahd_softc *ahd) +{ + int error; + + error = ahd_aic7902_setup(ahd); + if (error != 0) + return (error); + ahd->chip = AHD_AIC7901; + return (0); +} + +static int +ahd_aic7901A_setup(struct ahd_softc *ahd) +{ + int error; + + error = ahd_aic7902_setup(ahd); + if (error != 0) + return (error); + ahd->chip = AHD_AIC7901A; + return (0); +} + +static int +ahd_aic7902_setup(struct ahd_softc *ahd) +{ + ahd_dev_softc_t pci; + u_int rev; + + pci = ahd->dev_softc; + rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1); + if (rev < ID_AIC7902_PCI_REV_A4) { + printf("%s: Unable to attach to unsupported chip revision %d\n", + ahd_name(ahd), rev); + ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2); + return (ENXIO); + } + ahd->channel = ahd_get_pci_function(pci) + 'A'; + ahd->chip = AHD_AIC7902; + ahd->features = AHD_AIC7902_FE; + if (rev < ID_AIC7902_PCI_REV_B0) { + /* + * Enable A series workarounds. + */ + ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG + | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG + | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG + | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG + | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG + | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG + | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG + | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG + | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG + | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG + | AHD_FAINT_LED_BUG; + + /* + * IO Cell paramter setup. + */ + AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); + + if ((ahd->flags & AHD_HP_BOARD) == 0) + AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA); + } else { + u_int devconfig1; + + ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS + | AHD_NEW_DFCNTRL_OPTS; + ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG + | AHD_INTCOLLISION_BUG|AHD_EARLY_REQ_BUG; + + /* + * IO Cell paramter setup. + */ + AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); + AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB); + AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF); + + /* + * Set the PREQDIS bit for H2B which disables some workaround + * that doesn't work on regular PCI busses. + * XXX - Find out exactly what this does from the hardware + * folks! + */ + devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1); + ahd_pci_write_config(pci, DEVCONFIG1, + devconfig1|PREQDIS, /*bytes*/1); + devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1); + } + + return (0); +} diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_proc.c linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_proc.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_proc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_proc.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2000-2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * String handling code courtesy of Gerard Roudier's + * sym driver. + * + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#19 $ + */ +#include "aic79xx_osm.h" +#include "aic79xx_inline.h" + +static void copy_mem_info(struct info_str *info, char *data, int len); +static int copy_info(struct info_str *info, char *fmt, ...); +static void ahd_dump_target_state(struct ahd_softc *ahd, + struct info_str *info, + u_int our_id, char channel, + u_int target_id, u_int target_offset); +static void ahd_dump_device_state(struct info_str *info, + struct ahd_linux_device *dev); +static int ahd_proc_write_seeprom(struct ahd_softc *ahd, + char *buffer, int length); + +static void +copy_mem_info(struct info_str *info, char *data, int len) +{ + if (info->pos + len > info->offset + info->length) + len = info->offset + info->length - info->pos; + + if (info->pos + len < info->offset) { + info->pos += len; + return; + } + + if (info->pos < info->offset) { + off_t partial; + + partial = info->offset - info->pos; + data += partial; + info->pos += partial; + len -= partial; + } + + if (len > 0) { + memcpy(info->buffer, data, len); + info->pos += len; + info->buffer += len; + } +} + +static int +copy_info(struct info_str *info, char *fmt, ...) +{ + va_list args; + char buf[256]; + int len; + + va_start(args, fmt); + len = vsprintf(buf, fmt, args); + va_end(args); + + copy_mem_info(info, buf, len); + return (len); +} + +void +ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) +{ + u_int speed; + u_int freq; + u_int mb; + + if (tinfo->period == AHD_PERIOD_UNKNOWN) { + copy_info(info, "Renegotiation Pending\n"); + return; + } + speed = 3300; + freq = 0; + if (tinfo->offset != 0) { + freq = aic_calc_syncsrate(tinfo->period); + speed = freq; + } + speed *= (0x01 << tinfo->width); + mb = speed / 1000; + if (mb > 0) + copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000); + else + copy_info(info, "%dKB/s transfers", speed); + + if (freq != 0) { + int printed_options; + + printed_options = 0; + copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000); + if ((tinfo->ppr_options & MSG_EXT_PPR_RD_STRM) != 0) { + copy_info(info, " RDSTRM"); + printed_options++; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { + copy_info(info, "%s", printed_options ? "|DT" : " DT"); + printed_options++; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + copy_info(info, "%s", printed_options ? "|IU" : " IU"); + printed_options++; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_RTI) != 0) { + copy_info(info, "%s", + printed_options ? "|RTI" : " RTI"); + printed_options++; + } + if ((tinfo->ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) { + copy_info(info, "%s", + printed_options ? "|QAS" : " QAS"); + printed_options++; + } + } + + if (tinfo->width > 0) { + if (freq != 0) { + copy_info(info, ", "); + } else { + copy_info(info, " ("); + } + copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width)); + } else if (freq != 0) { + copy_info(info, ")"); + } + copy_info(info, "\n"); +} + +static void +ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, + u_int our_id, char channel, u_int target_id, + u_int target_offset) +{ + struct ahd_linux_target *targ; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + int lun; + + tinfo = ahd_fetch_transinfo(ahd, channel, our_id, + target_id, &tstate); + copy_info(info, "Target %d Negotiation Settings\n", target_id); + copy_info(info, "\tUser: "); + ahd_format_transinfo(info, &tinfo->user); + targ = ahd->platform_data->targets[target_offset]; + if (targ == NULL) + return; + + copy_info(info, "\tGoal: "); + ahd_format_transinfo(info, &tinfo->goal); + copy_info(info, "\tCurr: "); + ahd_format_transinfo(info, &tinfo->curr); + copy_info(info, "\tTransmission Errors %ld\n", targ->errors_detected); + + for (lun = 0; lun < AHD_NUM_LUNS; lun++) { + struct ahd_linux_device *dev; + + dev = targ->devices[lun]; + + if (dev == NULL) + continue; + + ahd_dump_device_state(info, dev); + } +} + +static void +ahd_dump_device_state(struct info_str *info, struct ahd_linux_device *dev) +{ + copy_info(info, "\tChannel %c Target %d Lun %d Settings\n", + dev->target->channel + 'A', dev->target->target, dev->lun); + + copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued); + copy_info(info, "\t\tCommands Active %d\n", dev->active); + copy_info(info, "\t\tCommand Openings %d\n", dev->openings); + copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags); + copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen); +} + +static int +ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length) +{ + ahd_mode_state saved_modes; + int have_seeprom; + u_long s; + int paused; + int written; + + /* Default to failure. */ + written = -EINVAL; + ahd_lock(ahd, &s); + paused = ahd_is_paused(ahd); + if (!paused) + ahd_pause(ahd); + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + if (length != sizeof(struct seeprom_config)) { + printf("ahd_proc_write_seeprom: incorrect buffer size\n"); + goto done; + } + + have_seeprom = ahd_verify_cksum((struct seeprom_config*)buffer); + if (have_seeprom == 0) { + printf("ahd_proc_write_seeprom: cksum verification failed\n"); + goto done; + } + + have_seeprom = ahd_acquire_seeprom(ahd); + if (!have_seeprom) { + printf("ahd_proc_write_seeprom: No Serial EEPROM\n"); + goto done; + } else { + u_int start_addr; + + if (ahd->seep_config == NULL) { + ahd->seep_config = malloc(sizeof(*ahd->seep_config), + M_DEVBUF, M_NOWAIT); + if (ahd->seep_config == NULL) { + printf("aic79xx: Unable to allocate serial " + "eeprom buffer. Write failing\n"); + goto done; + } + } + printf("aic79xx: Writing Serial EEPROM\n"); + start_addr = 32 * (ahd->channel - 'A'); + ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr, + sizeof(struct seeprom_config)/2); + ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config, + start_addr, sizeof(struct seeprom_config)/2, + /*ByteStream*/FALSE); + ahd_release_seeprom(ahd); + written = length; + } + +done: + ahd_restore_modes(ahd, saved_modes); + if (!paused) + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + return (written); +} +/* + * Return information to handle /proc support for the driver. + */ +int +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +ahd_linux_proc_info(char *buffer, char **start, off_t offset, + int length, int hostno, int inout) +#else +ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, + off_t offset, int length, int inout) +#endif +{ + struct ahd_softc *ahd; + struct info_str info; + char ahd_info[256]; + u_long l; + u_int max_targ; + u_int i; + int retval; + + retval = -EINVAL; + ahd_list_lock(&l); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + if (ahd->platform_data->host->host_no == hostno) + break; + } +#else + ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata); +#endif + + if (ahd == NULL) + goto done; + + /* Has data been written to the file? */ + if (inout == TRUE) { + retval = ahd_proc_write_seeprom(ahd, buffer, length); + goto done; + } + + if (start) + *start = buffer; + + info.buffer = buffer; + info.length = length; + info.offset = offset; + info.pos = 0; + + copy_info(&info, "Adaptec AIC79xx driver version: %s\n", + AIC79XX_DRIVER_VERSION); + copy_info(&info, "%s\n", ahd->description); + ahd_controller_info(ahd, ahd_info); + copy_info(&info, "%s\n", ahd_info); + copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", + ahd->scb_data.numscbs, AHD_NSEG); + + max_targ = 15; + + if (ahd->seep_config == NULL) + copy_info(&info, "No Serial EEPROM\n"); + else { + copy_info(&info, "Serial EEPROM:\n"); + for (i = 0; i < sizeof(*ahd->seep_config)/2; i++) { + if (((i % 8) == 0) && (i != 0)) { + copy_info(&info, "\n"); + } + copy_info(&info, "0x%.4x ", + ((uint16_t*)ahd->seep_config)[i]); + } + copy_info(&info, "\n"); + } + copy_info(&info, "\n"); + + if ((ahd->features & AHD_WIDE) == 0) + max_targ = 7; + + for (i = 0; i <= max_targ; i++) { + + ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', + /*target_id*/i, /*target_offset*/i); + } + retval = info.pos > info.offset ? info.pos - info.offset : 0; +done: + ahd_list_unlock(&l); + return (retval); +} diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_reg.h linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_reg.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_reg.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_reg.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,3776 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $ + */ +typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); +typedef struct ahd_reg_parse_entry { + char *name; + uint8_t value; + uint8_t mask; +} ahd_reg_parse_entry_t; + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_mode_ptr_print; +#else +#define ahd_mode_ptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MODE_PTR", 0x00, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intstat_print; +#else +#define ahd_intstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTSTAT", 0x01, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintcode_print; +#else +#define ahd_seqintcode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTCODE", 0x02, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrint_print; +#else +#define ahd_clrint_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRINT", 0x03, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_error_print; +#else +#define ahd_error_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ERROR", 0x04, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrerr_print; +#else +#define ahd_clrerr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRERR", 0x04, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hcntrl_print; +#else +#define ahd_hcntrl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HCNTRL", 0x05, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hnscb_qoff_print; +#else +#define ahd_hnscb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HNSCB_QOFF", 0x06, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hescb_qoff_print; +#else +#define ahd_hescb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HESCB_QOFF", 0x08, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hs_mailbox_print; +#else +#define ahd_hs_mailbox_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HS_MAILBOX", 0x0b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrseqintstat_print; +#else +#define ahd_clrseqintstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSEQINTSTAT", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintstat_print; +#else +#define ahd_seqintstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTSTAT", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_swtimer_print; +#else +#define ahd_swtimer_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SWTIMER", 0x0e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_snscb_qoff_print; +#else +#define ahd_snscb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SNSCB_QOFF", 0x10, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sescb_qoff_print; +#else +#define ahd_sescb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SESCB_QOFF", 0x12, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sdscb_qoff_print; +#else +#define ahd_sdscb_qoff_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SDSCB_QOFF", 0x14, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qoff_ctlsta_print; +#else +#define ahd_qoff_ctlsta_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QOFF_CTLSTA", 0x16, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intctl_print; +#else +#define ahd_intctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTCTL", 0x18, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfcntrl_print; +#else +#define ahd_dfcntrl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFCNTRL", 0x19, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dscommand0_print; +#else +#define ahd_dscommand0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSCOMMAND0", 0x19, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfstatus_print; +#else +#define ahd_dfstatus_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFSTATUS", 0x1a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sg_cache_shadow_print; +#else +#define ahd_sg_cache_shadow_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SG_CACHE_SHADOW", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_arbctl_print; +#else +#define ahd_arbctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ARBCTL", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sg_cache_pre_print; +#else +#define ahd_sg_cache_pre_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SG_CACHE_PRE", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqin_print; +#else +#define ahd_lqin_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQIN", 0x20, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_typeptr_print; +#else +#define ahd_typeptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TYPEPTR", 0x20, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_tagptr_print; +#else +#define ahd_tagptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TAGPTR", 0x21, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lunptr_print; +#else +#define ahd_lunptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LUNPTR", 0x22, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_datalenptr_print; +#else +#define ahd_datalenptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DATALENPTR", 0x23, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_statlenptr_print; +#else +#define ahd_statlenptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "STATLENPTR", 0x24, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdlenptr_print; +#else +#define ahd_cmdlenptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDLENPTR", 0x25, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_attrptr_print; +#else +#define ahd_attrptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ATTRPTR", 0x26, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flagptr_print; +#else +#define ahd_flagptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLAGPTR", 0x27, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdptr_print; +#else +#define ahd_cmdptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDPTR", 0x28, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qnextptr_print; +#else +#define ahd_qnextptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QNEXTPTR", 0x29, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_idptr_print; +#else +#define ahd_idptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "IDPTR", 0x2a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_abrtbyteptr_print; +#else +#define ahd_abrtbyteptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ABRTBYTEPTR", 0x2b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_abrtbitptr_print; +#else +#define ahd_abrtbitptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ABRTBITPTR", 0x2c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmdbytes_print; +#else +#define ahd_maxcmdbytes_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMDBYTES", 0x2d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmd2rcv_print; +#else +#define ahd_maxcmd2rcv_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMD2RCV", 0x2e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shortthresh_print; +#else +#define ahd_shortthresh_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHORTTHRESH", 0x2f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lunlen_print; +#else +#define ahd_lunlen_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LUNLEN", 0x30, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cdblimit_print; +#else +#define ahd_cdblimit_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CDBLIMIT", 0x31, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmd_print; +#else +#define ahd_maxcmd_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMD", 0x32, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_maxcmdcnt_print; +#else +#define ahd_maxcmdcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MAXCMDCNT", 0x33, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqrsvd01_print; +#else +#define ahd_lqrsvd01_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQRSVD01", 0x34, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqrsvd16_print; +#else +#define ahd_lqrsvd16_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQRSVD16", 0x35, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqrsvd17_print; +#else +#define ahd_lqrsvd17_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQRSVD17", 0x36, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdrsvd0_print; +#else +#define ahd_cmdrsvd0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDRSVD0", 0x37, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqctl0_print; +#else +#define ahd_lqctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQCTL0", 0x38, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqctl1_print; +#else +#define ahd_lqctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQCTL1", 0x38, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsbist0_print; +#else +#define ahd_scsbist0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSBIST0", 0x39, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqctl2_print; +#else +#define ahd_lqctl2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQCTL2", 0x39, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsbist1_print; +#else +#define ahd_scsbist1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSBIST1", 0x3a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiseq0_print; +#else +#define ahd_scsiseq0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISEQ0", 0x3a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiseq1_print; +#else +#define ahd_scsiseq1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISEQ1", 0x3b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sxfrctl0_print; +#else +#define ahd_sxfrctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SXFRCTL0", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_businitid_print; +#else +#define ahd_businitid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BUSINITID", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dlcount_print; +#else +#define ahd_dlcount_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DLCOUNT", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sxfrctl1_print; +#else +#define ahd_sxfrctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SXFRCTL1", 0x3d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_bustargid_print; +#else +#define ahd_bustargid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BUSTARGID", 0x3e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sxfrctl2_print; +#else +#define ahd_sxfrctl2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SXFRCTL2", 0x3e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dffstat_print; +#else +#define ahd_dffstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFFSTAT", 0x3f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsisigo_print; +#else +#define ahd_scsisigo_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISIGO", 0x40, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_multargid_print; +#else +#define ahd_multargid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MULTARGID", 0x40, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsisigi_print; +#else +#define ahd_scsisigi_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISIGI", 0x41, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiphase_print; +#else +#define ahd_scsiphase_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIPHASE", 0x42, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsidat0_img_print; +#else +#define ahd_scsidat0_img_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIDAT0_IMG", 0x43, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsidat_print; +#else +#define ahd_scsidat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIDAT", 0x44, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsibus_print; +#else +#define ahd_scsibus_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSIBUS", 0x46, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_targidin_print; +#else +#define ahd_targidin_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TARGIDIN", 0x48, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_selid_print; +#else +#define ahd_selid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SELID", 0x49, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sblkctl_print; +#else +#define ahd_sblkctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SBLKCTL", 0x4a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_optionmode_print; +#else +#define ahd_optionmode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OPTIONMODE", 0x4a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat0_print; +#else +#define ahd_sstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT0", 0x4b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint0_print; +#else +#define ahd_clrsint0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT0", 0x4b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode0_print; +#else +#define ahd_simode0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE0", 0x4b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint1_print; +#else +#define ahd_clrsint1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT1", 0x4c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat1_print; +#else +#define ahd_sstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT1", 0x4c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat2_print; +#else +#define ahd_sstat2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT2", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint2_print; +#else +#define ahd_clrsint2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT2", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode2_print; +#else +#define ahd_simode2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE2", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_perrdiag_print; +#else +#define ahd_perrdiag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PERRDIAG", 0x4e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistate_print; +#else +#define ahd_lqistate_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTATE", 0x4e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_soffcnt_print; +#else +#define ahd_soffcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SOFFCNT", 0x4f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostate_print; +#else +#define ahd_lqostate_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTATE", 0x4f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistat0_print; +#else +#define ahd_lqistat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTAT0", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqiint0_print; +#else +#define ahd_clrlqiint0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQIINT0", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqimode0_print; +#else +#define ahd_lqimode0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQIMODE0", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqimode1_print; +#else +#define ahd_lqimode1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQIMODE1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistat1_print; +#else +#define ahd_lqistat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTAT1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqiint1_print; +#else +#define ahd_clrlqiint1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQIINT1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqistat2_print; +#else +#define ahd_lqistat2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQISTAT2", 0x52, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sstat3_print; +#else +#define ahd_sstat3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SSTAT3", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode3_print; +#else +#define ahd_simode3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE3", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrsint3_print; +#else +#define ahd_clrsint3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSINT3", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqomode0_print; +#else +#define ahd_lqomode0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOMODE0", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostat0_print; +#else +#define ahd_lqostat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTAT0", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqoint0_print; +#else +#define ahd_clrlqoint0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQOINT0", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostat1_print; +#else +#define ahd_lqostat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTAT1", 0x55, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrlqoint1_print; +#else +#define ahd_clrlqoint1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRLQOINT1", 0x55, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqomode1_print; +#else +#define ahd_lqomode1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOMODE1", 0x55, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqostat2_print; +#else +#define ahd_lqostat2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSTAT2", 0x56, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_os_space_cnt_print; +#else +#define ahd_os_space_cnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OS_SPACE_CNT", 0x56, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_simode1_print; +#else +#define ahd_simode1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SIMODE1", 0x57, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_gsfifo_print; +#else +#define ahd_gsfifo_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "GSFIFO", 0x58, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dffsxfrctl_print; +#else +#define ahd_dffsxfrctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFFSXFRCTL", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lqoscsctl_print; +#else +#define ahd_lqoscsctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LQOSCSCTL", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_nextscb_print; +#else +#define ahd_nextscb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEXTSCB", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_clrseqintsrc_print; +#else +#define ahd_clrseqintsrc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CLRSEQINTSRC", 0x5b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintsrc_print; +#else +#define ahd_seqintsrc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTSRC", 0x5b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_currscb_print; +#else +#define ahd_currscb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CURRSCB", 0x5c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqimode_print; +#else +#define ahd_seqimode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQIMODE", 0x5c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_mdffstat_print; +#else +#define ahd_mdffstat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MDFFSTAT", 0x5d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_crccontrol_print; +#else +#define ahd_crccontrol_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CRCCONTROL", 0x5d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfftag_print; +#else +#define ahd_dfftag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFFTAG", 0x5e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lastscb_print; +#else +#define ahd_lastscb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LASTSCB", 0x5e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsitest_print; +#else +#define ahd_scsitest_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSITEST", 0x5e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_iopdnctl_print; +#else +#define ahd_iopdnctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "IOPDNCTL", 0x5f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shaddr_print; +#else +#define ahd_shaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHADDR", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negoaddr_print; +#else +#define ahd_negoaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGOADDR", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dgrpcrci_print; +#else +#define ahd_dgrpcrci_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DGRPCRCI", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negperiod_print; +#else +#define ahd_negperiod_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGPERIOD", 0x61, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_packcrci_print; +#else +#define ahd_packcrci_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PACKCRCI", 0x62, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negoffset_print; +#else +#define ahd_negoffset_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGOFFSET", 0x62, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negppropts_print; +#else +#define ahd_negppropts_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGPPROPTS", 0x63, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_negconopts_print; +#else +#define ahd_negconopts_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEGCONOPTS", 0x64, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_annexcol_print; +#else +#define ahd_annexcol_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ANNEXCOL", 0x65, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scschkn_print; +#else +#define ahd_scschkn_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSCHKN", 0x66, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_annexdat_print; +#else +#define ahd_annexdat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ANNEXDAT", 0x66, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_iownid_print; +#else +#define ahd_iownid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "IOWNID", 0x67, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll960ctl0_print; +#else +#define ahd_pll960ctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL960CTL0", 0x68, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shcnt_print; +#else +#define ahd_shcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHCNT", 0x68, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_townid_print; +#else +#define ahd_townid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TOWNID", 0x69, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll960ctl1_print; +#else +#define ahd_pll960ctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL960CTL1", 0x69, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll960cnt0_print; +#else +#define ahd_pll960cnt0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL960CNT0", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_xsig_print; +#else +#define ahd_xsig_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "XSIG", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seloid_print; +#else +#define ahd_seloid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SELOID", 0x6b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll400ctl0_print; +#else +#define ahd_pll400ctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL400CTL0", 0x6c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_fairness_print; +#else +#define ahd_fairness_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FAIRNESS", 0x6c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll400ctl1_print; +#else +#define ahd_pll400ctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL400CTL1", 0x6d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pll400cnt0_print; +#else +#define ahd_pll400cnt0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLL400CNT0", 0x6e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_unfairness_print; +#else +#define ahd_unfairness_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "UNFAIRNESS", 0x6e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_haddr_print; +#else +#define ahd_haddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HADDR", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_plldelay_print; +#else +#define ahd_plldelay_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PLLDELAY", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hodmaadr_print; +#else +#define ahd_hodmaadr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HODMAADR", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hodmacnt_print; +#else +#define ahd_hodmacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HODMACNT", 0x78, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hcnt_print; +#else +#define ahd_hcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HCNT", 0x78, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_hodmaen_print; +#else +#define ahd_hodmaen_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "HODMAEN", 0x7a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sghaddr_print; +#else +#define ahd_sghaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGHADDR", 0x7c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbhaddr_print; +#else +#define ahd_scbhaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBHADDR", 0x7c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sghcnt_print; +#else +#define ahd_sghcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGHCNT", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbhcnt_print; +#else +#define ahd_scbhcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBHCNT", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dff_thrsh_print; +#else +#define ahd_dff_thrsh_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFF_THRSH", 0x88, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_romaddr_print; +#else +#define ahd_romaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROMADDR", 0x8a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_romcntrl_print; +#else +#define ahd_romcntrl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROMCNTRL", 0x8d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_romdata_print; +#else +#define ahd_romdata_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROMDATA", 0x8e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg0_print; +#else +#define ahd_cmcrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG0", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_roenable_print; +#else +#define ahd_roenable_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ROENABLE", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg0_print; +#else +#define ahd_ovlyrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG0", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg0_print; +#else +#define ahd_dchrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG0", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg1_print; +#else +#define ahd_ovlyrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG1", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_nsenable_print; +#else +#define ahd_nsenable_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NSENABLE", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg1_print; +#else +#define ahd_dchrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG1", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg1_print; +#else +#define ahd_cmcrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG1", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg2_print; +#else +#define ahd_dchrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG2", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg2_print; +#else +#define ahd_ovlyrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG2", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg2_print; +#else +#define ahd_cmcrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG2", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ost_print; +#else +#define ahd_ost_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OST", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchrxmsg3_print; +#else +#define ahd_dchrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHRXMSG3", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcrxmsg3_print; +#else +#define ahd_cmcrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCRXMSG3", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_pcixctl_print; +#else +#define ahd_pcixctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PCIXCTL", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyrxmsg3_print; +#else +#define ahd_ovlyrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYRXMSG3", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyseqbcnt_print; +#else +#define ahd_ovlyseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYSEQBCNT", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcseqbcnt_print; +#else +#define ahd_cmcseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCSEQBCNT", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchseqbcnt_print; +#else +#define ahd_dchseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHSEQBCNT", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcspltstat0_print; +#else +#define ahd_cmcspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCSPLTSTAT0", 0x96, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyspltstat0_print; +#else +#define ahd_ovlyspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYSPLTSTAT0", 0x96, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchspltstat0_print; +#else +#define ahd_dchspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHSPLTSTAT0", 0x96, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dchspltstat1_print; +#else +#define ahd_dchspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DCHSPLTSTAT1", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcspltstat1_print; +#else +#define ahd_cmcspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCSPLTSTAT1", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyspltstat1_print; +#else +#define ahd_ovlyspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYSPLTSTAT1", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg0_print; +#else +#define ahd_sgrxmsg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG0", 0x98, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr0_print; +#else +#define ahd_slvspltoutadr0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR0", 0x98, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg1_print; +#else +#define ahd_sgrxmsg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG1", 0x99, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr1_print; +#else +#define ahd_slvspltoutadr1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR1", 0x99, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg2_print; +#else +#define ahd_sgrxmsg2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG2", 0x9a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr2_print; +#else +#define ahd_slvspltoutadr2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR2", 0x9a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgrxmsg3_print; +#else +#define ahd_sgrxmsg3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGRXMSG3", 0x9b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutadr3_print; +#else +#define ahd_slvspltoutadr3_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTADR3", 0x9b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgseqbcnt_print; +#else +#define ahd_sgseqbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGSEQBCNT", 0x9c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutattr0_print; +#else +#define ahd_slvspltoutattr0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTATTR0", 0x9c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutattr1_print; +#else +#define ahd_slvspltoutattr1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTATTR1", 0x9d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_slvspltoutattr2_print; +#else +#define ahd_slvspltoutattr2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SLVSPLTOUTATTR2", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgspltstat0_print; +#else +#define ahd_sgspltstat0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGSPLTSTAT0", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sfunct_print; +#else +#define ahd_sfunct_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgspltstat1_print; +#else +#define ahd_sgspltstat1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGSPLTSTAT1", 0x9f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_df0pcistat_print; +#else +#define ahd_df0pcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DF0PCISTAT", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_reg0_print; +#else +#define ahd_reg0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "REG0", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_df1pcistat_print; +#else +#define ahd_df1pcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DF1PCISTAT", 0xa1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sgpcistat_print; +#else +#define ahd_sgpcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SGPCISTAT", 0xa2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_reg1_print; +#else +#define ahd_reg1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "REG1", 0xa2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmcpcistat_print; +#else +#define ahd_cmcpcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMCPCISTAT", 0xa3, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlypcistat_print; +#else +#define ahd_ovlypcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYPCISTAT", 0xa4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_reg_isr_print; +#else +#define ahd_reg_isr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "REG_ISR", 0xa4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sg_state_print; +#else +#define ahd_sg_state_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SG_STATE", 0xa6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_msipcistat_print; +#else +#define ahd_msipcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MSIPCISTAT", 0xa6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_targpcistat_print; +#else +#define ahd_targpcistat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TARGPCISTAT", 0xa7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_data_count_odd_print; +#else +#define ahd_data_count_odd_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DATA_COUNT_ODD", 0xa7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbptr_print; +#else +#define ahd_scbptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBPTR", 0xa8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbacnt_print; +#else +#define ahd_ccscbacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBACNT", 0xab, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbautoptr_print; +#else +#define ahd_scbautoptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBAUTOPTR", 0xab, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccsgaddr_print; +#else +#define ahd_ccsgaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSGADDR", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbaddr_print; +#else +#define ahd_ccscbaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBADDR", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbadr_bk_print; +#else +#define ahd_ccscbadr_bk_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBADR_BK", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmc_rambist_print; +#else +#define ahd_cmc_rambist_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMC_RAMBIST", 0xad, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccsgctl_print; +#else +#define ahd_ccsgctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSGCTL", 0xad, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbctl_print; +#else +#define ahd_ccscbctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBCTL", 0xad, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccsgram_print; +#else +#define ahd_ccsgram_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSGRAM", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexadr_print; +#else +#define ahd_flexadr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXADR", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ccscbram_print; +#else +#define ahd_ccscbram_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CCSCBRAM", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexcnt_print; +#else +#define ahd_flexcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXCNT", 0xb3, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexdmastat_print; +#else +#define ahd_flexdmastat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXDMASTAT", 0xb5, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flexdata_print; +#else +#define ahd_flexdata_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLEXDATA", 0xb6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brddat_print; +#else +#define ahd_brddat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRDDAT", 0xb8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brdctl_print; +#else +#define ahd_brdctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRDCTL", 0xb9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seeadr_print; +#else +#define ahd_seeadr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEEADR", 0xba, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seedat_print; +#else +#define ahd_seedat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEEDAT", 0xbc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seectl_print; +#else +#define ahd_seectl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEECTL", 0xbe, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seestat_print; +#else +#define ahd_seestat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEESTAT", 0xbe, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scbcnt_print; +#else +#define ahd_scbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCBCNT", 0xbf, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfwaddr_print; +#else +#define ahd_dfwaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFWADDR", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspfltrctl_print; +#else +#define ahd_dspfltrctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPFLTRCTL", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspdatactl_print; +#else +#define ahd_dspdatactl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPDATACTL", 0xc1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfraddr_print; +#else +#define ahd_dfraddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFRADDR", 0xc2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspreqctl_print; +#else +#define ahd_dspreqctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPREQCTL", 0xc2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspackctl_print; +#else +#define ahd_dspackctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPACKCTL", 0xc3, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfdat_print; +#else +#define ahd_dfdat_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFDAT", 0xc4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dspselect_print; +#else +#define ahd_dspselect_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DSPSELECT", 0xc4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_wrtbiasctl_print; +#else +#define ahd_wrtbiasctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WRTBIASCTL", 0xc5, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_rcvrbiosctl_print; +#else +#define ahd_rcvrbiosctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "RCVRBIOSCTL", 0xc6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_wrtbiascalc_print; +#else +#define ahd_wrtbiascalc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WRTBIASCALC", 0xc7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfptrs_print; +#else +#define ahd_dfptrs_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFPTRS", 0xc8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_rcvrbiascalc_print; +#else +#define ahd_rcvrbiascalc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "RCVRBIASCALC", 0xc8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfbkptr_print; +#else +#define ahd_dfbkptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFBKPTR", 0xc9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_skewcalc_print; +#else +#define ahd_skewcalc_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SKEWCALC", 0xc9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfdbctl_print; +#else +#define ahd_dfdbctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFDBCTL", 0xcb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfscnt_print; +#else +#define ahd_dfscnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFSCNT", 0xcc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dfbcnt_print; +#else +#define ahd_dfbcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DFBCNT", 0xce, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ovlyaddr_print; +#else +#define ahd_ovlyaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "OVLYADDR", 0xd4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqctl0_print; +#else +#define ahd_seqctl0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQCTL0", 0xd6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqctl1_print; +#else +#define ahd_seqctl1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQCTL1", 0xd7, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_flags_print; +#else +#define ahd_flags_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FLAGS", 0xd8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqintctl_print; +#else +#define ahd_seqintctl_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQINTCTL", 0xd9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seqram_print; +#else +#define ahd_seqram_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQRAM", 0xda, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_prgmcnt_print; +#else +#define ahd_prgmcnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "PRGMCNT", 0xde, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_accum_print; +#else +#define ahd_accum_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ACCUM", 0xe0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sindex_print; +#else +#define ahd_sindex_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SINDEX", 0xe2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dindex_print; +#else +#define ahd_dindex_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DINDEX", 0xe4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brkaddr1_print; +#else +#define ahd_brkaddr1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRKADDR1", 0xe6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_brkaddr0_print; +#else +#define ahd_brkaddr0_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "BRKADDR0", 0xe6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_allones_print; +#else +#define ahd_allones_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ALLONES", 0xe8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_allzeros_print; +#else +#define ahd_allzeros_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ALLZEROS", 0xea, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_none_print; +#else +#define ahd_none_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NONE", 0xea, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sindir_print; +#else +#define ahd_sindir_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SINDIR", 0xec, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dindir_print; +#else +#define ahd_dindir_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DINDIR", 0xed, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_function1_print; +#else +#define ahd_function1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "FUNCTION1", 0xf0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_stack_print; +#else +#define ahd_stack_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "STACK", 0xf2, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_curaddr_print; +#else +#define ahd_curaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CURADDR", 0xf4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intvec1_addr_print; +#else +#define ahd_intvec1_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTVEC1_ADDR", 0xf4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_intvec2_addr_print; +#else +#define ahd_intvec2_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INTVEC2_ADDR", 0xf6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lastaddr_print; +#else +#define ahd_lastaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LASTADDR", 0xf6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_longjmp_addr_print; +#else +#define ahd_longjmp_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LONGJMP_ADDR", 0xf8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_accum_save_print; +#else +#define ahd_accum_save_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ACCUM_SAVE", 0xfa, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_waiting_scb_tails_print; +#else +#define ahd_waiting_scb_tails_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", 0x100, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_ahd_pci_config_base_print; +#else +#define ahd_ahd_pci_config_base_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE", 0x100, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_sram_base_print; +#else +#define ahd_sram_base_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SRAM_BASE", 0x100, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_waiting_tid_head_print; +#else +#define ahd_waiting_tid_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WAITING_TID_HEAD", 0x120, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_waiting_tid_tail_print; +#else +#define ahd_waiting_tid_tail_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "WAITING_TID_TAIL", 0x122, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_next_queued_scb_addr_print; +#else +#define ahd_next_queued_scb_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR", 0x124, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_complete_scb_head_print; +#else +#define ahd_complete_scb_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD", 0x128, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_complete_scb_dmainprog_head_print; +#else +#define ahd_complete_scb_dmainprog_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD", 0x12a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_complete_dma_scb_head_print; +#else +#define ahd_complete_dma_scb_head_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD", 0x12c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qfreeze_count_print; +#else +#define ahd_qfreeze_count_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QFREEZE_COUNT", 0x12e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_saved_mode_print; +#else +#define ahd_saved_mode_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SAVED_MODE", 0x130, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_msg_out_print; +#else +#define ahd_msg_out_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MSG_OUT", 0x131, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_dmaparams_print; +#else +#define ahd_dmaparams_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "DMAPARAMS", 0x132, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seq_flags_print; +#else +#define ahd_seq_flags_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQ_FLAGS", 0x133, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_saved_scsiid_print; +#else +#define ahd_saved_scsiid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SAVED_SCSIID", 0x134, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_saved_lun_print; +#else +#define ahd_saved_lun_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SAVED_LUN", 0x135, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_lastphase_print; +#else +#define ahd_lastphase_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LASTPHASE", 0x136, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qoutfifo_entry_valid_tag_print; +#else +#define ahd_qoutfifo_entry_valid_tag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG", 0x137, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_shared_data_addr_print; +#else +#define ahd_shared_data_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x138, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_qoutfifo_next_addr_print; +#else +#define ahd_qoutfifo_next_addr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", 0x13c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_kernel_tqinpos_print; +#else +#define ahd_kernel_tqinpos_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "KERNEL_TQINPOS", 0x140, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_tqinpos_print; +#else +#define ahd_tqinpos_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "TQINPOS", 0x141, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_arg_1_print; +#else +#define ahd_arg_1_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ARG_1", 0x142, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_arg_2_print; +#else +#define ahd_arg_2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ARG_2", 0x143, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_last_msg_print; +#else +#define ahd_last_msg_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LAST_MSG", 0x144, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scsiseq_template_print; +#else +#define ahd_scsiseq_template_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x145, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_initiator_tag_print; +#else +#define ahd_initiator_tag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INITIATOR_TAG", 0x146, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_seq_flags2_print; +#else +#define ahd_seq_flags2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SEQ_FLAGS2", 0x147, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_allocfifo_scbptr_print; +#else +#define ahd_allocfifo_scbptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR", 0x148, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalescing_timer_print; +#else +#define ahd_int_coalescing_timer_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESCING_TIMER", 0x14a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalescing_maxcmds_print; +#else +#define ahd_int_coalescing_maxcmds_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS", 0x14c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalescing_mincmds_print; +#else +#define ahd_int_coalescing_mincmds_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS", 0x14d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmds_pending_print; +#else +#define ahd_cmds_pending_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDS_PENDING", 0x14e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_int_coalescing_cmdcount_print; +#else +#define ahd_int_coalescing_cmdcount_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT", 0x150, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_local_hs_mailbox_print; +#else +#define ahd_local_hs_mailbox_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX", 0x151, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_cmdsize_table_print; +#else +#define ahd_cmdsize_table_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "CMDSIZE_TABLE", 0x152, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_base_print; +#else +#define ahd_scb_base_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_BASE", 0x180, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_residual_datacnt_print; +#else +#define ahd_scb_residual_datacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", 0x180, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_residual_sgptr_print; +#else +#define ahd_scb_residual_sgptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0x184, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_scsi_status_print; +#else +#define ahd_scb_scsi_status_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", 0x188, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_target_phases_print; +#else +#define ahd_scb_target_phases_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TARGET_PHASES", 0x189, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_target_data_dir_print; +#else +#define ahd_scb_target_data_dir_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0x18a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_target_itag_print; +#else +#define ahd_scb_target_itag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TARGET_ITAG", 0x18b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_sense_busaddr_print; +#else +#define ahd_scb_sense_busaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR", 0x18c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_tag_print; +#else +#define ahd_scb_tag_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_control_print; +#else +#define ahd_scb_control_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_CONTROL", 0x192, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_scsiid_print; +#else +#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SCSIID", 0x193, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_lun_print; +#else +#define ahd_scb_lun_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_LUN", 0x194, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_task_attribute_print; +#else +#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x195, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_cdb_len_print; +#else +#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x196, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_task_management_print; +#else +#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x197, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_dataptr_print; +#else +#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_datacnt_print; +#else +#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_sgptr_print; +#else +#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_busaddr_print; +#else +#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_next_print; +#else +#define ahd_scb_next_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_NEXT", 0x1ac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_next2_print; +#else +#define ahd_scb_next2_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1ae, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_spare_print; +#else +#define ahd_scb_spare_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_SPARE", 0x1b0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_scb_disconnected_lists_print; +#else +#define ahd_scb_disconnected_lists_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS", 0x1b8, regvalue, cur_col, wrap) +#endif + + +#define MODE_PTR 0x00 +#define DST_MODE 0x70 +#define SRC_MODE 0x07 + +#define INTSTAT 0x01 +#define INT_PEND 0xff +#define HWERRINT 0x80 +#define BRKADRINT 0x40 +#define SWTMINT 0x20 +#define PCIINT 0x10 +#define SCSIINT 0x08 +#define SEQINT 0x04 +#define CMDCMPLT 0x02 +#define SPLTINT 0x01 + +#define SEQINTCODE 0x02 +#define BAD_SCB_STATUS 0x1a +#define SAW_HWERR 0x19 +#define TRACEPOINT3 0x18 +#define TRACEPOINT2 0x17 +#define TRACEPOINT1 0x16 +#define TRACEPOINT0 0x15 +#define TASKMGMT_CMD_CMPLT_OKAY 0x14 +#define TASKMGMT_FUNC_COMPLETE 0x13 +#define ENTERING_NONPACK 0x12 +#define CFG4OVERRUN 0x11 +#define STATUS_OVERRUN 0x10 +#define CFG4ISTAT_INTR 0x0f +#define INVALID_SEQINT 0x0e +#define ILLEGAL_PHASE 0x0d +#define DUMP_CARD_STATE 0x0c +#define MISSED_BUSFREE 0x0b +#define MKMSG_FAILED 0x0a +#define DATA_OVERRUN 0x09 +#define BAD_STATUS 0x08 +#define HOST_MSG_LOOP 0x07 +#define PDATA_REINIT 0x06 +#define IGN_WIDE_RES 0x05 +#define NO_MATCH 0x04 +#define PROTO_VIOLATION 0x03 +#define SEND_REJECT 0x02 +#define BAD_PHASE 0x01 +#define NO_SEQINT 0x00 + +#define CLRINT 0x03 +#define CLRHWERRINT 0x80 +#define CLRBRKADRINT 0x40 +#define CLRSWTMINT 0x20 +#define CLRPCIINT 0x10 +#define CLRSCSIINT 0x08 +#define CLRSEQINT 0x04 +#define CLRCMDINT 0x02 +#define CLRSPLTINT 0x01 + +#define ERROR 0x04 +#define CIOPARERR 0x80 +#define CIOACCESFAIL 0x40 +#define MPARERR 0x20 +#define DPARERR 0x10 +#define SQPARERR 0x08 +#define ILLOPCODE 0x04 +#define DSCTMOUT 0x02 + +#define CLRERR 0x04 +#define CLRCIOPARERR 0x80 +#define CLRCIOACCESFAIL 0x40 +#define CLRMPARERR 0x20 +#define CLRDPARERR 0x10 +#define CLRSQPARERR 0x08 +#define CLRILLOPCODE 0x04 +#define CLRDSCTMOUT 0x02 + +#define HCNTRL 0x05 +#define SEQ_RESET 0x80 +#define POWRDN 0x40 +#define SWINT 0x10 +#define SWTIMER_START_B 0x08 +#define PAUSE 0x04 +#define INTEN 0x02 +#define CHIPRST 0x01 +#define CHIPRSTACK 0x01 + +#define HNSCB_QOFF 0x06 + +#define HESCB_QOFF 0x08 + +#define HS_MAILBOX 0x0b +#define HOST_TQINPOS 0x80 +#define ENINT_COALESCE 0x40 + +#define CLRSEQINTSTAT 0x0c +#define CLRSEQ_SWTMRTO 0x10 +#define CLRSEQ_SEQINT 0x08 +#define CLRSEQ_SCSIINT 0x04 +#define CLRSEQ_PCIINT 0x02 +#define CLRSEQ_SPLTINT 0x01 + +#define SEQINTSTAT 0x0c +#define SEQ_SWTMRTO 0x10 +#define SEQ_SEQINT 0x08 +#define SEQ_SCSIINT 0x04 +#define SEQ_PCIINT 0x02 +#define SEQ_SPLTINT 0x01 + +#define SWTIMER 0x0e + +#define SNSCB_QOFF 0x10 + +#define SESCB_QOFF 0x12 + +#define SDSCB_QOFF 0x14 + +#define QOFF_CTLSTA 0x16 +#define EMPTY_SCB_AVAIL 0x80 +#define NEW_SCB_AVAIL 0x40 +#define SDSCB_ROLLOVR 0x20 +#define HS_MAILBOX_ACT 0x10 +#define SCB_QSIZE 0x0f +#define SCB_QSIZE_16384 0x0c +#define SCB_QSIZE_8192 0x0b +#define SCB_QSIZE_4096 0x0a +#define SCB_QSIZE_2048 0x09 +#define SCB_QSIZE_1024 0x08 +#define SCB_QSIZE_512 0x07 +#define SCB_QSIZE_256 0x06 +#define SCB_QSIZE_128 0x05 +#define SCB_QSIZE_64 0x04 +#define SCB_QSIZE_32 0x03 +#define SCB_QSIZE_16 0x02 +#define SCB_QSIZE_8 0x01 +#define SCB_QSIZE_4 0x00 + +#define INTCTL 0x18 +#define SWTMINTMASK 0x80 +#define SWTMINTEN 0x40 +#define SWTIMER_START 0x20 +#define AUTOCLRCMDINT 0x10 +#define PCIINTEN 0x08 +#define SCSIINTEN 0x04 +#define SEQINTEN 0x02 +#define SPLTINTEN 0x01 + +#define DFCNTRL 0x19 +#define SCSIENWRDIS 0x40 +#define SCSIENACK 0x20 +#define DIRECTIONACK 0x04 +#define FIFOFLUSHACK 0x02 +#define DIRECTIONEN 0x01 + +#define DSCOMMAND0 0x19 +#define CACHETHEN 0x80 +#define DPARCKEN 0x40 +#define MPARCKEN 0x20 +#define EXTREQLCK 0x10 +#define DISABLE_TWATE 0x02 +#define CIOPARCKEN 0x01 + +#define DFSTATUS 0x1a +#define PRELOAD_AVAIL 0x80 +#define PKT_PRELOAD_AVAIL 0x40 +#define MREQPEND 0x10 +#define HDONE 0x08 +#define DFTHRESH 0x04 +#define FIFOFULL 0x02 +#define FIFOEMP 0x01 + +#define SG_CACHE_SHADOW 0x1b +#define ODD_SEG 0x04 +#define LAST_SEG 0x02 +#define LAST_SEG_DONE 0x01 + +#define ARBCTL 0x1b +#define RESET_HARB 0x80 +#define RETRY_SWEN 0x08 +#define USE_TIME 0x07 + +#define SG_CACHE_PRE 0x1b + +#define LQIN 0x20 + +#define TYPEPTR 0x20 + +#define TAGPTR 0x21 + +#define LUNPTR 0x22 + +#define DATALENPTR 0x23 + +#define STATLENPTR 0x24 + +#define CMDLENPTR 0x25 + +#define ATTRPTR 0x26 + +#define FLAGPTR 0x27 + +#define CMDPTR 0x28 + +#define QNEXTPTR 0x29 + +#define IDPTR 0x2a + +#define ABRTBYTEPTR 0x2b + +#define ABRTBITPTR 0x2c + +#define MAXCMDBYTES 0x2d + +#define MAXCMD2RCV 0x2e + +#define SHORTTHRESH 0x2f + +#define LUNLEN 0x30 +#define TLUNLEN 0xf0 +#define ILUNLEN 0x0f + +#define CDBLIMIT 0x31 + +#define MAXCMD 0x32 + +#define MAXCMDCNT 0x33 + +#define LQRSVD01 0x34 + +#define LQRSVD16 0x35 + +#define LQRSVD17 0x36 + +#define CMDRSVD0 0x37 + +#define LQCTL0 0x38 +#define LQITARGCLT 0xc0 +#define LQIINITGCLT 0x30 +#define LQ0TARGCLT 0x0c +#define LQ0INITGCLT 0x03 + +#define LQCTL1 0x38 +#define PCI2PCI 0x04 +#define SINGLECMD 0x02 +#define ABORTPENDING 0x01 + +#define SCSBIST0 0x39 +#define GSBISTERR 0x40 +#define GSBISTDONE 0x20 +#define GSBISTRUN 0x10 +#define OSBISTERR 0x04 +#define OSBISTDONE 0x02 +#define OSBISTRUN 0x01 + +#define LQCTL2 0x39 +#define LQIRETRY 0x80 +#define LQICONTINUE 0x40 +#define LQITOIDLE 0x20 +#define LQIPAUSE 0x10 +#define LQORETRY 0x08 +#define LQOCONTINUE 0x04 +#define LQOTOIDLE 0x02 +#define LQOPAUSE 0x01 + +#define SCSBIST1 0x3a +#define NTBISTERR 0x04 +#define NTBISTDONE 0x02 +#define NTBISTRUN 0x01 + +#define SCSISEQ0 0x3a +#define TEMODEO 0x80 +#define ENSELO 0x40 +#define ENARBO 0x20 +#define FORCEBUSFREE 0x10 +#define SCSIRSTO 0x01 + +#define SCSISEQ1 0x3b + +#define SXFRCTL0 0x3c +#define DFON 0x80 +#define DFPEXP 0x40 +#define BIOSCANCELEN 0x10 +#define SPIOEN 0x08 + +#define BUSINITID 0x3c + +#define DLCOUNT 0x3c + +#define SXFRCTL1 0x3d +#define BITBUCKET 0x80 +#define ENSACHK 0x40 +#define ENSPCHK 0x20 +#define STIMESEL 0x18 +#define ENSTIMER 0x04 +#define ACTNEGEN 0x02 +#define STPWEN 0x01 + +#define BUSTARGID 0x3e + +#define SXFRCTL2 0x3e +#define AUTORSTDIS 0x10 +#define CMDDMAEN 0x08 +#define ASU 0x07 + +#define DFFSTAT 0x3f +#define CURRFIFO 0x03 +#define FIFO1FREE 0x20 +#define FIFO0FREE 0x10 +#define CURRFIFO_NONE 0x03 +#define CURRFIFO_1 0x01 +#define CURRFIFO_0 0x00 + +#define SCSISIGO 0x40 +#define CDO 0x80 +#define IOO 0x40 +#define MSGO 0x20 +#define ATNO 0x10 +#define SELO 0x08 +#define BSYO 0x04 +#define REQO 0x02 +#define ACKO 0x01 + +#define MULTARGID 0x40 + +#define SCSISIGI 0x41 +#define ATNI 0x10 +#define SELI 0x08 +#define BSYI 0x04 +#define REQI 0x02 +#define ACKI 0x01 + +#define SCSIPHASE 0x42 +#define STATUS_PHASE 0x20 +#define COMMAND_PHASE 0x10 +#define MSG_IN_PHASE 0x08 +#define MSG_OUT_PHASE 0x04 +#define DATA_PHASE_MASK 0x03 +#define DATA_IN_PHASE 0x02 +#define DATA_OUT_PHASE 0x01 + +#define SCSIDAT0_IMG 0x43 + +#define SCSIDAT 0x44 + +#define SCSIBUS 0x46 + +#define TARGIDIN 0x48 +#define CLKOUT 0x80 +#define TARGID 0x0f + +#define SELID 0x49 +#define SELID_MASK 0xf0 +#define ONEBIT 0x08 + +#define SBLKCTL 0x4a +#define DIAGLEDEN 0x80 +#define DIAGLEDON 0x40 +#define ENAB40 0x08 +#define ENAB20 0x04 +#define SELWIDE 0x02 + +#define OPTIONMODE 0x4a +#define OPTIONMODE_DEFAULTS 0x02 +#define BIOSCANCTL 0x80 +#define AUTOACKEN 0x40 +#define BIASCANCTL 0x20 +#define BUSFREEREV 0x10 +#define ENDGFORMCHK 0x04 +#define AUTO_MSGOUT_DE 0x02 + +#define SSTAT0 0x4b +#define TARGET 0x80 +#define SELDO 0x40 +#define SELDI 0x20 +#define SELINGO 0x10 +#define IOERR 0x08 +#define OVERRUN 0x04 +#define SPIORDY 0x02 +#define ARBDO 0x01 + +#define CLRSINT0 0x4b +#define CLRSELDO 0x40 +#define CLRSELDI 0x20 +#define CLRSELINGO 0x10 +#define CLRIOERR 0x08 +#define CLROVERRUN 0x04 +#define CLRSPIORDY 0x02 +#define CLRARBDO 0x01 + +#define SIMODE0 0x4b +#define ENSELDO 0x40 +#define ENSELDI 0x20 +#define ENSELINGO 0x10 +#define ENIOERR 0x08 +#define ENOVERRUN 0x04 +#define ENSPIORDY 0x02 +#define ENARBDO 0x01 + +#define CLRSINT1 0x4c +#define CLRSELTIMEO 0x80 +#define CLRATNO 0x40 +#define CLRSCSIRSTI 0x20 +#define CLRBUSFREE 0x08 +#define CLRSCSIPERR 0x04 +#define CLRSTRB2FAST 0x02 +#define CLRREQINIT 0x01 + +#define SSTAT1 0x4c +#define SELTO 0x80 +#define ATNTARG 0x40 +#define SCSIRSTI 0x20 +#define PHASEMIS 0x10 +#define BUSFREE 0x08 +#define SCSIPERR 0x04 +#define STRB2FAST 0x02 +#define REQINIT 0x01 + +#define SSTAT2 0x4d +#define BUSFREETIME 0xc0 +#define NONPACKREQ 0x20 +#define EXP_ACTIVE 0x10 +#define BSYX 0x08 +#define WIDE_RES 0x04 +#define SDONE 0x02 +#define DMADONE 0x01 +#define BUSFREE_DFF1 0xc0 +#define BUSFREE_DFF0 0x80 +#define BUSFREE_LQO 0x40 + +#define CLRSINT2 0x4d +#define CLRNONPACKREQ 0x20 +#define CLRWIDE_RES 0x04 +#define CLRSDONE 0x02 +#define CLRDMADONE 0x01 + +#define SIMODE2 0x4d +#define ENWIDE_RES 0x04 +#define ENSDONE 0x02 +#define ENDMADONE 0x01 + +#define PERRDIAG 0x4e +#define HIZERO 0x80 +#define HIPERR 0x40 +#define PREVPHASE 0x20 +#define PARITYERR 0x10 +#define AIPERR 0x08 +#define CRCERR 0x04 +#define DGFORMERR 0x02 +#define DTERR 0x01 + +#define LQISTATE 0x4e + +#define SOFFCNT 0x4f + +#define LQOSTATE 0x4f + +#define LQISTAT0 0x50 +#define LQIATNQAS 0x20 +#define LQICRCT1 0x10 +#define LQICRCT2 0x08 +#define LQIBADLQT 0x04 +#define LQIATNLQ 0x02 +#define LQIATNCMD 0x01 + +#define CLRLQIINT0 0x50 +#define CLRLQIATNQAS 0x20 +#define CLRLQICRCT1 0x10 +#define CLRLQICRCT2 0x08 +#define CLRLQIBADLQT 0x04 +#define CLRLQIATNLQ 0x02 +#define CLRLQIATNCMD 0x01 + +#define LQIMODE0 0x50 +#define ENLQIATNQASK 0x20 +#define ENLQICRCT1 0x10 +#define ENLQICRCT2 0x08 +#define ENLQIBADLQT 0x04 +#define ENLQIATNLQ 0x02 +#define ENLQIATNCMD 0x01 + +#define LQIMODE1 0x51 +#define ENLQIPHASE_LQ 0x80 +#define ENLQIPHASE_NLQ 0x40 +#define ENLIQABORT 0x20 +#define ENLQICRCI_LQ 0x10 +#define ENLQICRCI_NLQ 0x08 +#define ENLQIBADLQI 0x04 +#define ENLQIOVERI_LQ 0x02 +#define ENLQIOVERI_NLQ 0x01 + +#define LQISTAT1 0x51 +#define LQIPHASE_LQ 0x80 +#define LQIPHASE_NLQ 0x40 +#define LQIABORT 0x20 +#define LQICRCI_LQ 0x10 +#define LQICRCI_NLQ 0x08 +#define LQIBADLQI 0x04 +#define LQIOVERI_LQ 0x02 +#define LQIOVERI_NLQ 0x01 + +#define CLRLQIINT1 0x51 +#define CLRLQIPHASE_LQ 0x80 +#define CLRLQIPHASE_NLQ 0x40 +#define CLRLIQABORT 0x20 +#define CLRLQICRCI_LQ 0x10 +#define CLRLQICRCI_NLQ 0x08 +#define CLRLQIBADLQI 0x04 +#define CLRLQIOVERI_LQ 0x02 +#define CLRLQIOVERI_NLQ 0x01 + +#define LQISTAT2 0x52 +#define PACKETIZED 0x80 +#define LQIPHASE_OUTPKT 0x40 +#define LQIWORKONLQ 0x20 +#define LQIWAITFIFO 0x10 +#define LQISTOPPKT 0x08 +#define LQISTOPLQ 0x04 +#define LQISTOPCMD 0x02 +#define LQIGSAVAIL 0x01 + +#define SSTAT3 0x53 +#define NTRAMPERR 0x02 +#define OSRAMPERR 0x01 + +#define SIMODE3 0x53 +#define ENNTRAMPERR 0x02 +#define ENOSRAMPERR 0x01 + +#define CLRSINT3 0x53 +#define CLRNTRAMPERR 0x02 +#define CLROSRAMPERR 0x01 + +#define LQOMODE0 0x54 +#define ENLQOTARGSCBPERR 0x10 +#define ENLQOSTOPT2 0x08 +#define ENLQOATNLQ 0x04 +#define ENLQOATNPKT 0x02 +#define ENLQOTCRC 0x01 + +#define LQOSTAT0 0x54 +#define LQOTARGSCBPERR 0x10 +#define LQOSTOPT2 0x08 +#define LQOATNLQ 0x04 +#define LQOATNPKT 0x02 +#define LQOTCRC 0x01 + +#define CLRLQOINT0 0x54 +#define CLRLQOTARGSCBPERR 0x10 +#define CLRLQOSTOPT2 0x08 +#define CLRLQOATNLQ 0x04 +#define CLRLQOATNPKT 0x02 +#define CLRLQOTCRC 0x01 + +#define LQOSTAT1 0x55 +#define LQOINITSCBPERR 0x10 +#define LQOSTOPI2 0x08 +#define LQOBADQAS 0x04 +#define LQOBUSFREE 0x02 +#define LQOPHACHGINPKT 0x01 + +#define CLRLQOINT1 0x55 +#define CLRLQOINITSCBPERR 0x10 +#define CLRLQOSTOPI2 0x08 +#define CLRLQOBADQAS 0x04 +#define CLRLQOBUSFREE 0x02 +#define CLRLQOPHACHGINPKT 0x01 + +#define LQOMODE1 0x55 +#define ENLQOINITSCBPERR 0x10 +#define ENLQOSTOPI2 0x08 +#define ENLQOBADQAS 0x04 +#define ENLQOBUSFREE 0x02 +#define ENLQOPHACHGINPKT 0x01 + +#define LQOSTAT2 0x56 +#define LQOPKT 0xe0 +#define LQOWAITFIFO 0x10 +#define LQOPHACHGOUTPKT 0x02 +#define LQOSTOP0 0x01 + +#define OS_SPACE_CNT 0x56 + +#define SIMODE1 0x57 +#define ENSELTIMO 0x80 +#define ENATNTARG 0x40 +#define ENSCSIRST 0x20 +#define ENPHASEMIS 0x10 +#define ENBUSFREE 0x08 +#define ENSCSIPERR 0x04 +#define ENSTRB2FAST 0x02 +#define ENREQINIT 0x01 + +#define GSFIFO 0x58 + +#define DFFSXFRCTL 0x5a +#define DFFBITBUCKET 0x08 +#define CLRSHCNT 0x04 +#define CLRCHN 0x02 +#define RSTCHN 0x01 + +#define LQOSCSCTL 0x5a +#define LQOH2A_VERSION 0x80 +#define LQONOCHKOVER 0x01 + +#define NEXTSCB 0x5a + +#define CLRSEQINTSRC 0x5b +#define CLRCTXTDONE 0x40 +#define CLRSAVEPTRS 0x20 +#define CLRCFG4DATA 0x10 +#define CLRCFG4ISTAT 0x08 +#define CLRCFG4TSTAT 0x04 +#define CLRCFG4ICMD 0x02 +#define CLRCFG4TCMD 0x01 + +#define SEQINTSRC 0x5b +#define CTXTDONE 0x40 +#define SAVEPTRS 0x20 +#define CFG4DATA 0x10 +#define CFG4ISTAT 0x08 +#define CFG4TSTAT 0x04 +#define CFG4ICMD 0x02 +#define CFG4TCMD 0x01 + +#define CURRSCB 0x5c + +#define SEQIMODE 0x5c +#define ENCTXTDONE 0x40 +#define ENSAVEPTRS 0x20 +#define ENCFG4DATA 0x10 +#define ENCFG4ISTAT 0x08 +#define ENCFG4TSTAT 0x04 +#define ENCFG4ICMD 0x02 +#define ENCFG4TCMD 0x01 + +#define MDFFSTAT 0x5d +#define SHCNTNEGATIVE 0x40 +#define SHCNTMINUS1 0x20 +#define LASTSDONE 0x10 +#define SHVALID 0x08 +#define DLZERO 0x04 +#define DATAINFIFO 0x02 +#define FIFOFREE 0x01 + +#define CRCCONTROL 0x5d +#define CRCVALCHKEN 0x40 + +#define DFFTAG 0x5e + +#define LASTSCB 0x5e + +#define SCSITEST 0x5e +#define CNTRTEST 0x08 +#define SEL_TXPLL_DEBUG 0x04 + +#define IOPDNCTL 0x5f +#define DISABLE_OE 0x80 +#define PDN_IDIST 0x04 +#define PDN_DIFFSENSE 0x01 + +#define SHADDR 0x60 + +#define NEGOADDR 0x60 + +#define DGRPCRCI 0x60 + +#define NEGPERIOD 0x61 + +#define PACKCRCI 0x62 + +#define NEGOFFSET 0x62 + +#define NEGPPROPTS 0x63 +#define PPROPT_PACE 0x08 +#define PPROPT_QAS 0x04 +#define PPROPT_DT 0x02 +#define PPROPT_IUT 0x01 + +#define NEGCONOPTS 0x64 +#define ENSNAPSHOT 0x40 +#define RTI_WRTDIS 0x20 +#define RTI_OVRDTRN 0x10 +#define ENSLOWCRC 0x08 +#define ENAUTOATNI 0x04 +#define ENAUTOATNO 0x02 +#define WIDEXFER 0x01 + +#define ANNEXCOL 0x65 + +#define SCSCHKN 0x66 +#define STSELSKIDDIS 0x40 +#define CURRFIFODEF 0x20 +#define WIDERESEN 0x10 +#define SDONEMSKDIS 0x08 +#define DFFACTCLR 0x04 +#define SHVALIDSTDIS 0x02 +#define LSTSGCLRDIS 0x01 + +#define ANNEXDAT 0x66 + +#define IOWNID 0x67 + +#define PLL960CTL0 0x68 + +#define SHCNT 0x68 + +#define TOWNID 0x69 + +#define PLL960CTL1 0x69 + +#define PLL960CNT0 0x6a + +#define XSIG 0x6a + +#define SELOID 0x6b + +#define PLL400CTL0 0x6c +#define PLL_VCOSEL 0x80 +#define PLL_PWDN 0x40 +#define PLL_NS 0x30 +#define PLL_ENLUD 0x08 +#define PLL_ENLPF 0x04 +#define PLL_DLPF 0x02 +#define PLL_ENFBM 0x01 + +#define FAIRNESS 0x6c + +#define PLL400CTL1 0x6d +#define PLL_CNTEN 0x80 +#define PLL_CNTCLR 0x40 +#define PLL_RST 0x01 + +#define PLL400CNT0 0x6e + +#define UNFAIRNESS 0x6e + +#define HADDR 0x70 + +#define PLLDELAY 0x70 +#define SPLIT_DROP_REQ 0x80 + +#define HODMAADR 0x70 + +#define HODMACNT 0x78 + +#define HCNT 0x78 + +#define HODMAEN 0x7a + +#define SGHADDR 0x7c + +#define SCBHADDR 0x7c + +#define SGHCNT 0x84 + +#define SCBHCNT 0x84 + +#define DFF_THRSH 0x88 +#define WR_DFTHRSH 0x70 +#define RD_DFTHRSH 0x07 +#define WR_DFTHRSH_MAX 0x70 +#define WR_DFTHRSH_90 0x60 +#define WR_DFTHRSH_85 0x50 +#define WR_DFTHRSH_75 0x40 +#define WR_DFTHRSH_63 0x30 +#define WR_DFTHRSH_50 0x20 +#define WR_DFTHRSH_25 0x10 +#define RD_DFTHRSH_MAX 0x07 +#define RD_DFTHRSH_90 0x06 +#define RD_DFTHRSH_85 0x05 +#define RD_DFTHRSH_75 0x04 +#define RD_DFTHRSH_63 0x03 +#define RD_DFTHRSH_50 0x02 +#define RD_DFTHRSH_25 0x01 +#define WR_DFTHRSH_MIN 0x00 +#define RD_DFTHRSH_MIN 0x00 + +#define ROMADDR 0x8a + +#define ROMCNTRL 0x8d +#define ROMOP 0xe0 +#define ROMSPD 0x18 +#define REPEAT 0x02 +#define RDY 0x01 + +#define ROMDATA 0x8e + +#define CMCRXMSG0 0x90 + +#define ROENABLE 0x90 +#define MSIROEN 0x20 +#define OVLYROEN 0x10 +#define CMCROEN 0x08 +#define SGROEN 0x04 +#define DCH1ROEN 0x02 +#define DCH0ROEN 0x01 + +#define OVLYRXMSG0 0x90 + +#define DCHRXMSG0 0x90 + +#define OVLYRXMSG1 0x91 + +#define NSENABLE 0x91 +#define MSINSEN 0x20 +#define OVLYNSEN 0x10 +#define CMCNSEN 0x08 +#define SGNSEN 0x04 +#define DCH1NSEN 0x02 +#define DCH0NSEN 0x01 + +#define DCHRXMSG1 0x91 + +#define CMCRXMSG1 0x91 + +#define DCHRXMSG2 0x92 + +#define OVLYRXMSG2 0x92 + +#define CMCRXMSG2 0x92 + +#define OST 0x92 + +#define DCHRXMSG3 0x93 + +#define CMCRXMSG3 0x93 + +#define PCIXCTL 0x93 +#define SERRPULSE 0x80 +#define UNEXPSCIEN 0x20 +#define SPLTSMADIS 0x10 +#define SPLTSTADIS 0x08 +#define SRSPDPEEN 0x04 +#define TSCSERREN 0x02 +#define CMPABCDIS 0x01 + +#define OVLYRXMSG3 0x93 + +#define OVLYSEQBCNT 0x94 + +#define CMCSEQBCNT 0x94 + +#define DCHSEQBCNT 0x94 + +#define CMCSPLTSTAT0 0x96 + +#define OVLYSPLTSTAT0 0x96 + +#define DCHSPLTSTAT0 0x96 + +#define DCHSPLTSTAT1 0x97 + +#define CMCSPLTSTAT1 0x97 + +#define OVLYSPLTSTAT1 0x97 + +#define SGRXMSG0 0x98 +#define CDNUM 0xf8 +#define CFNUM 0x07 + +#define SLVSPLTOUTADR0 0x98 +#define LOWER_ADDR 0x7f + +#define SGRXMSG1 0x99 +#define CBNUM 0xff + +#define SLVSPLTOUTADR1 0x99 +#define REQ_DNUM 0xf8 +#define REQ_FNUM 0x07 + +#define SGRXMSG2 0x9a +#define MINDEX 0xff + +#define SLVSPLTOUTADR2 0x9a +#define REQ_BNUM 0xff + +#define SGRXMSG3 0x9b +#define MCLASS 0x0f + +#define SLVSPLTOUTADR3 0x9b +#define TAG_NUM 0x1f +#define RLXORD 0x10 + +#define SGSEQBCNT 0x9c + +#define SLVSPLTOUTATTR0 0x9c +#define LOWER_BCNT 0xff + +#define SLVSPLTOUTATTR1 0x9d +#define CMPLT_DNUM 0xf8 +#define CMPLT_FNUM 0x07 + +#define SLVSPLTOUTATTR2 0x9e +#define CMPLT_BNUM 0xff + +#define SGSPLTSTAT0 0x9e +#define STAETERM 0x80 +#define SCBCERR 0x40 +#define SCADERR 0x20 +#define SCDATBUCKET 0x10 +#define CNTNOTCMPLT 0x08 +#define RXOVRUN 0x04 +#define RXSCEMSG 0x02 +#define RXSPLTRSP 0x01 + +#define SFUNCT 0x9f +#define TEST_GROUP 0xf0 +#define TEST_NUM 0x0f + +#define SGSPLTSTAT1 0x9f +#define RXDATABUCKET 0x01 + +#define DF0PCISTAT 0xa0 + +#define REG0 0xa0 + +#define DF1PCISTAT 0xa1 + +#define SGPCISTAT 0xa2 + +#define REG1 0xa2 + +#define CMCPCISTAT 0xa3 + +#define OVLYPCISTAT 0xa4 +#define SCAAPERR 0x08 +#define RDPERR 0x04 + +#define REG_ISR 0xa4 + +#define SG_STATE 0xa6 +#define FETCH_INPROG 0x04 +#define LOADING_NEEDED 0x02 +#define SEGS_AVAIL 0x01 + +#define MSIPCISTAT 0xa6 +#define RMA 0x20 +#define RTA 0x10 +#define CLRPENDMSI 0x08 +#define DPR 0x01 + +#define TARGPCISTAT 0xa7 +#define DPE 0x80 +#define SSE 0x40 +#define STA 0x08 +#define TWATERR 0x02 + +#define DATA_COUNT_ODD 0xa7 + +#define SCBPTR 0xa8 + +#define CCSCBACNT 0xab + +#define SCBAUTOPTR 0xab +#define AUSCBPTR_EN 0x80 +#define SCBPTR_ADDR 0x38 +#define SCBPTR_OFF 0x07 + +#define CCSGADDR 0xac + +#define CCSCBADDR 0xac + +#define CCSCBADR_BK 0xac + +#define CMC_RAMBIST 0xad +#define SG_ELEMENT_SIZE 0x80 +#define SCBRAMBIST_FAIL 0x40 +#define SG_BIST_FAIL 0x20 +#define SG_BIST_EN 0x10 +#define CMC_BUFFER_BIST_FAIL 0x02 +#define CMC_BUFFER_BIST_EN 0x01 + +#define CCSGCTL 0xad +#define CCSGEN 0x0c +#define CCSGDONE 0x80 +#define SG_CACHE_AVAIL 0x10 +#define CCSGENACK 0x08 +#define SG_FETCH_REQ 0x02 +#define CCSGRESET 0x01 + +#define CCSCBCTL 0xad +#define CCSCBDONE 0x80 +#define ARRDONE 0x40 +#define CCARREN 0x10 +#define CCSCBEN 0x08 +#define CCSCBDIR 0x04 +#define CCSCBRESET 0x01 + +#define CCSGRAM 0xb0 + +#define FLEXADR 0xb0 + +#define CCSCBRAM 0xb0 + +#define FLEXCNT 0xb3 + +#define FLEXDMASTAT 0xb5 +#define FLEXDMAERR 0x02 +#define FLEXDMADONE 0x01 + +#define FLEXDATA 0xb6 + +#define BRDDAT 0xb8 + +#define BRDCTL 0xb9 +#define FLXARBACK 0x80 +#define FLXARBREQ 0x40 +#define BRDADDR 0x38 +#define BRDEN 0x04 +#define BRDRW 0x02 +#define BRDSTB 0x01 + +#define SEEADR 0xba + +#define SEEDAT 0xbc + +#define SEECTL 0xbe +#define SEEOP_EWEN 0x40 +#define SEEOP_WALL 0x40 +#define SEEOP_EWDS 0x40 +#define SEEOPCODE 0x70 +#define SEERST 0x02 +#define SEESTART 0x01 +#define SEEOP_ERASE 0x70 +#define SEEOP_READ 0x60 +#define SEEOP_WRITE 0x50 +#define SEEOP_ERAL 0x40 + +#define SEESTAT 0xbe +#define INIT_DONE 0x80 +#define LDALTID_L 0x08 +#define SEEARBACK 0x04 +#define SEEBUSY 0x02 + +#define SCBCNT 0xbf + +#define DFWADDR 0xc0 + +#define DSPFLTRCTL 0xc0 +#define FLTRDISABLE 0x20 +#define EDGESENSE 0x10 +#define DSPFCNTSEL 0x0f + +#define DSPDATACTL 0xc1 +#define BYPASSENAB 0x80 +#define DESQDIS 0x10 +#define RCVROFFSTDIS 0x04 +#define XMITOFFSTDIS 0x02 + +#define DFRADDR 0xc2 + +#define DSPREQCTL 0xc2 +#define MANREQCTL 0xc0 +#define MANREQDLY 0x3f + +#define DSPACKCTL 0xc3 +#define MANACKCTL 0xc0 +#define MANACKDLY 0x3f + +#define DFDAT 0xc4 + +#define DSPSELECT 0xc4 +#define AUTOINCEN 0x80 +#define DSPSEL 0x1f + +#define WRTBIASCTL 0xc5 +#define AUTOXBCDIS 0x80 +#define XMITMANVAL 0x3f + +#define RCVRBIOSCTL 0xc6 +#define AUTORBCDIS 0x80 +#define RCVRMANVAL 0x3f + +#define WRTBIASCALC 0xc7 + +#define DFPTRS 0xc8 + +#define RCVRBIASCALC 0xc8 + +#define DFBKPTR 0xc9 + +#define SKEWCALC 0xc9 + +#define DFDBCTL 0xcb +#define DFF_CIO_WR_RDY 0x20 +#define DFF_CIO_RD_RDY 0x10 +#define DFF_DIR_ERR 0x08 +#define DFF_RAMBIST_FAIL 0x04 +#define DFF_RAMBIST_DONE 0x02 +#define DFF_RAMBIST_EN 0x01 + +#define DFSCNT 0xcc + +#define DFBCNT 0xce + +#define OVLYADDR 0xd4 + +#define SEQCTL0 0xd6 +#define PERRORDIS 0x80 +#define PAUSEDIS 0x40 +#define FAILDIS 0x20 +#define FASTMODE 0x10 +#define BRKADRINTEN 0x08 +#define STEP 0x04 +#define SEQRESET 0x02 +#define LOADRAM 0x01 + +#define SEQCTL1 0xd7 +#define OVRLAY_DATA_CHK 0x08 +#define RAMBIST_DONE 0x04 +#define RAMBIST_FAIL 0x02 +#define RAMBIST_EN 0x01 + +#define FLAGS 0xd8 +#define ZERO 0x02 +#define CARRY 0x01 + +#define SEQINTCTL 0xd9 +#define INTVEC1DSL 0x80 +#define INT1_CONTEXT 0x20 +#define SCS_SEQ_INT1M1 0x10 +#define SCS_SEQ_INT1M0 0x08 +#define INTMASK2 0x04 +#define INTMASK1 0x02 +#define IRET 0x01 + +#define SEQRAM 0xda + +#define PRGMCNT 0xde + +#define ACCUM 0xe0 + +#define SINDEX 0xe2 + +#define DINDEX 0xe4 + +#define BRKADDR1 0xe6 +#define BRKDIS 0x80 + +#define BRKADDR0 0xe6 + +#define ALLONES 0xe8 + +#define ALLZEROS 0xea + +#define NONE 0xea + +#define SINDIR 0xec + +#define DINDIR 0xed + +#define FUNCTION1 0xf0 + +#define STACK 0xf2 + +#define CURADDR 0xf4 + +#define INTVEC1_ADDR 0xf4 + +#define INTVEC2_ADDR 0xf6 + +#define LASTADDR 0xf6 + +#define LONGJMP_ADDR 0xf8 + +#define ACCUM_SAVE 0xfa + +#define WAITING_SCB_TAILS 0x100 + +#define AHD_PCI_CONFIG_BASE 0x100 + +#define SRAM_BASE 0x100 + +#define WAITING_TID_HEAD 0x120 + +#define WAITING_TID_TAIL 0x122 + +#define NEXT_QUEUED_SCB_ADDR 0x124 + +#define COMPLETE_SCB_HEAD 0x128 + +#define COMPLETE_SCB_DMAINPROG_HEAD 0x12a + +#define COMPLETE_DMA_SCB_HEAD 0x12c + +#define QFREEZE_COUNT 0x12e + +#define SAVED_MODE 0x130 + +#define MSG_OUT 0x131 + +#define DMAPARAMS 0x132 +#define PRELOADEN 0x80 +#define WIDEODD 0x40 +#define SCSIEN 0x20 +#define SDMAEN 0x10 +#define SDMAENACK 0x10 +#define HDMAENACK 0x08 +#define HDMAEN 0x08 +#define DIRECTION 0x04 +#define FIFOFLUSH 0x02 +#define FIFORESET 0x01 + +#define SEQ_FLAGS 0x133 +#define NOT_IDENTIFIED 0x80 +#define NO_CDB_SENT 0x40 +#define TARGET_CMD_IS_TAGGED 0x40 +#define DPHASE 0x20 +#define TARG_CMD_PENDING 0x10 +#define CMDPHASE_PENDING 0x08 +#define DPHASE_PENDING 0x04 +#define SPHASE_PENDING 0x02 +#define NO_DISCONNECT 0x01 + +#define SAVED_SCSIID 0x134 + +#define SAVED_LUN 0x135 + +#define LASTPHASE 0x136 +#define PHASE_MASK 0xe0 +#define CDI 0x80 +#define IOI 0x40 +#define MSGI 0x20 +#define P_BUSFREE 0x01 +#define P_MESGIN 0xe0 +#define P_STATUS 0xc0 +#define P_MESGOUT 0xa0 +#define P_COMMAND 0x80 +#define P_DATAIN_DT 0x60 +#define P_DATAIN 0x40 +#define P_DATAOUT_DT 0x20 +#define P_DATAOUT 0x00 + +#define QOUTFIFO_ENTRY_VALID_TAG 0x137 + +#define SHARED_DATA_ADDR 0x138 + +#define QOUTFIFO_NEXT_ADDR 0x13c + +#define KERNEL_TQINPOS 0x140 + +#define TQINPOS 0x141 + +#define ARG_1 0x142 +#define RETURN_1 0x142 +#define SEND_MSG 0x80 +#define SEND_SENSE 0x40 +#define SEND_REJ 0x20 +#define MSGOUT_PHASEMIS 0x10 +#define EXIT_MSG_LOOP 0x08 +#define CONT_MSG_LOOP_WRITE 0x04 +#define CONT_MSG_LOOP_READ 0x03 +#define CONT_MSG_LOOP_TARG 0x02 + +#define ARG_2 0x143 +#define RETURN_2 0x143 + +#define LAST_MSG 0x144 + +#define SCSISEQ_TEMPLATE 0x145 +#define MANUALCTL 0x40 +#define ENSELI 0x20 +#define ENRSELI 0x10 +#define MANUALP 0x0c +#define ENAUTOATNP 0x02 +#define ALTSTIM 0x01 + +#define INITIATOR_TAG 0x146 + +#define SEQ_FLAGS2 0x147 +#define SELECTOUT_QFROZEN 0x04 +#define TARGET_MSG_PENDING 0x02 + +#define ALLOCFIFO_SCBPTR 0x148 + +#define INT_COALESCING_TIMER 0x14a + +#define INT_COALESCING_MAXCMDS 0x14c + +#define INT_COALESCING_MINCMDS 0x14d + +#define CMDS_PENDING 0x14e + +#define INT_COALESCING_CMDCOUNT 0x150 + +#define LOCAL_HS_MAILBOX 0x151 + +#define CMDSIZE_TABLE 0x152 + +#define SCB_BASE 0x180 + +#define SCB_RESIDUAL_DATACNT 0x180 +#define SCB_CDB_STORE 0x180 +#define SCB_HOST_CDB_PTR 0x180 + +#define SCB_RESIDUAL_SGPTR 0x184 +#define SG_ADDR_MASK 0xf8 +#define SG_OVERRUN_RESID 0x02 + +#define SCB_SCSI_STATUS 0x188 +#define SCB_HOST_CDB_LEN 0x188 + +#define SCB_TARGET_PHASES 0x189 + +#define SCB_TARGET_DATA_DIR 0x18a + +#define SCB_TARGET_ITAG 0x18b + +#define SCB_SENSE_BUSADDR 0x18c +#define SCB_NEXT_COMPLETE 0x18c + +#define SCB_TAG 0x190 +#define SCB_FIFO_USE_COUNT 0x190 + +#define SCB_CONTROL 0x192 +#define TARGET_SCB 0x80 +#define DISCENB 0x40 +#define TAG_ENB 0x20 +#define MK_MESSAGE 0x10 +#define STATUS_RCVD 0x08 +#define DISCONNECTED 0x04 +#define SCB_TAG_TYPE 0x03 + +#define SCB_SCSIID 0x193 +#define TID 0xf0 +#define OID 0x0f + +#define SCB_LUN 0x194 +#define LID 0xff + +#define SCB_TASK_ATTRIBUTE 0x195 +#define SCB_XFERLEN_ODD 0x01 + +#define SCB_CDB_LEN 0x196 +#define SCB_CDB_LEN_PTR 0x80 + +#define SCB_TASK_MANAGEMENT 0x197 + +#define SCB_DATAPTR 0x198 + +#define SCB_DATACNT 0x1a0 +#define SG_LAST_SEG 0x80 +#define SG_HIGH_ADDR_BITS 0x7f + +#define SCB_SGPTR 0x1a4 +#define SG_STATUS_VALID 0x04 +#define SG_FULL_RESID 0x02 +#define SG_LIST_NULL 0x01 + +#define SCB_BUSADDR 0x1a8 + +#define SCB_NEXT 0x1ac +#define SCB_NEXT_SCB_BUSADDR 0x1ac + +#define SCB_NEXT2 0x1ae + +#define SCB_SPARE 0x1b0 +#define SCB_PKT_LUN 0x1b0 + +#define SCB_DISCONNECTED_LISTS 0x1b8 + + +#define AHD_TIMER_US_PER_TICK 0x19 +#define SCB_TRANSFER_SIZE_FULL_LUN 0x38 +#define STATUS_QUEUE_FULL 0x28 +#define STATUS_BUSY 0x08 +#define MAX_OFFSET_NON_PACED 0x7f +#define MAX_OFFSET_PACED 0xfe +#define BUS_32_BIT 0x02 +#define CCSGADDR_MAX 0x80 +#define TID_SHIFT 0x04 +#define MK_MESSAGE_BIT_OFFSET 0x04 +#define WRTBIASCTL_HP_DEFAULT 0x00 +#define SEEOP_EWDS_ADDR 0x00 +#define AHD_AMPLITUDE_SHIFT 0x00 +#define AHD_AMPLITUDE_MASK 0x07 +#define AHD_ANNEXCOL_AMPLITUDE 0x06 +#define AHD_SLEWRATE_DEF_REVA 0x08 +#define AHD_SLEWRATE_SHIFT 0x03 +#define AHD_SLEWRATE_MASK 0x78 +#define AHD_PRECOMP_CUTBACK_29 0x06 +#define AHD_NUM_PER_DEV_ANNEXCOLS 0x04 +#define B_CURRFIFO_0 0x02 +#define LUNLEN_SINGLE_LEVEL_LUN 0x0f +#define NVRAM_SCB_OFFSET 0x2c +#define AHD_TIMER_MAX_US 0x18ffe7 +#define AHD_TIMER_MAX_TICKS 0xffff +#define STATUS_PKT_SENSE 0xff +#define CMD_GROUP_CODE_SHIFT 0x05 +#define AHD_SENSE_BUFSIZE 0x100 +#define MAX_OFFSET_PACED_BUG 0x7f +#define BUS_8_BIT 0x00 +#define STIMESEL_BUG_ADJ 0x08 +#define STIMESEL_MIN 0x18 +#define STIMESEL_SHIFT 0x03 +#define CCSGRAM_MAXSEGS 0x10 +#define INVALID_ADDR 0x80 +#define TARGET_CMD_CMPLT 0xfe +#define SEEOP_WRAL_ADDR 0x40 +#define SEEOP_ERAL_ADDR 0x80 +#define AHD_AMPLITUDE_DEF 0x07 +#define AHD_SLEWRATE_DEF_REVB 0x08 +#define AHD_PRECOMP_CUTBACK_37 0x07 +#define AHD_PRECOMP_CUTBACK_17 0x04 +#define AHD_PRECOMP_SHIFT 0x00 +#define AHD_PRECOMP_MASK 0x07 +#define AHD_ANNEXCOL_PRECOMP_SLEW 0x04 +#define SRC_MODE_SHIFT 0x00 +#define PKT_OVERRUN_BUFSIZE 0x200 +#define SCB_TRANSFER_SIZE_1BYTE_LUN 0x30 +#define TARGET_DATA_IN 0x01 +#define HOST_MSG 0xff +#define MAX_OFFSET 0xfe +#define BUS_16_BIT 0x01 +#define CCSCBADDR_MAX 0x80 +#define NUMDSPS 0x14 +#define SEEOP_EWEN_ADDR 0xc0 +#define AHD_ANNEXCOL_PER_DEV0 0x04 +#define DST_MODE_SHIFT 0x04 + + +/* Downloaded Constant Definitions */ +#define SCB_TRANSFER_SIZE 0x06 +#define PKT_OVERRUN_BUFOFFSET 0x05 +#define SG_SIZEOF 0x04 +#define SG_PREFETCH_ADDR_MASK 0x03 +#define SG_PREFETCH_ALIGN_MASK 0x02 +#define SG_PREFETCH_CNT_LIMIT 0x01 +#define SG_PREFETCH_CNT 0x00 +#define DOWNLOAD_CONST_COUNT 0x07 + + +/* Exported Labels */ +#define LABEL_seq_isr 0x269 +#define LABEL_timer_isr 0x265 diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_reg_print.c linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_reg_print.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_reg_print.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_reg_print.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,3635 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $ + */ + +#include "aic79xx_osm.h" + +static ahd_reg_parse_entry_t MODE_PTR_parse_table[] = { + { "SRC_MODE", 0x07, 0x07 }, + { "DST_MODE", 0x70, 0x70 } +}; + +int +ahd_mode_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(MODE_PTR_parse_table, 2, "MODE_PTR", + 0x00, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t INTSTAT_parse_table[] = { + { "SPLTINT", 0x01, 0x01 }, + { "CMDCMPLT", 0x02, 0x02 }, + { "SEQINT", 0x04, 0x04 }, + { "SCSIINT", 0x08, 0x08 }, + { "PCIINT", 0x10, 0x10 }, + { "SWTMINT", 0x20, 0x20 }, + { "BRKADRINT", 0x40, 0x40 }, + { "HWERRINT", 0x80, 0x80 }, + { "INT_PEND", 0xff, 0xff } +}; + +int +ahd_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(INTSTAT_parse_table, 9, "INTSTAT", + 0x01, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = { + { "NO_SEQINT", 0x00, 0xff }, + { "BAD_PHASE", 0x01, 0xff }, + { "SEND_REJECT", 0x02, 0xff }, + { "PROTO_VIOLATION", 0x03, 0xff }, + { "NO_MATCH", 0x04, 0xff }, + { "IGN_WIDE_RES", 0x05, 0xff }, + { "PDATA_REINIT", 0x06, 0xff }, + { "HOST_MSG_LOOP", 0x07, 0xff }, + { "BAD_STATUS", 0x08, 0xff }, + { "DATA_OVERRUN", 0x09, 0xff }, + { "MKMSG_FAILED", 0x0a, 0xff }, + { "MISSED_BUSFREE", 0x0b, 0xff }, + { "DUMP_CARD_STATE", 0x0c, 0xff }, + { "ILLEGAL_PHASE", 0x0d, 0xff }, + { "INVALID_SEQINT", 0x0e, 0xff }, + { "CFG4ISTAT_INTR", 0x0f, 0xff }, + { "STATUS_OVERRUN", 0x10, 0xff }, + { "CFG4OVERRUN", 0x11, 0xff }, + { "ENTERING_NONPACK", 0x12, 0xff }, + { "TASKMGMT_FUNC_COMPLETE",0x13, 0xff }, + { "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff }, + { "TRACEPOINT0", 0x15, 0xff }, + { "TRACEPOINT1", 0x16, 0xff }, + { "TRACEPOINT2", 0x17, 0xff }, + { "TRACEPOINT3", 0x18, 0xff }, + { "SAW_HWERR", 0x19, 0xff }, + { "BAD_SCB_STATUS", 0x1a, 0xff } +}; + +int +ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTCODE_parse_table, 27, "SEQINTCODE", + 0x02, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRINT_parse_table[] = { + { "CLRSPLTINT", 0x01, 0x01 }, + { "CLRCMDINT", 0x02, 0x02 }, + { "CLRSEQINT", 0x04, 0x04 }, + { "CLRSCSIINT", 0x08, 0x08 }, + { "CLRPCIINT", 0x10, 0x10 }, + { "CLRSWTMINT", 0x20, 0x20 }, + { "CLRBRKADRINT", 0x40, 0x40 }, + { "CLRHWERRINT", 0x80, 0x80 } +}; + +int +ahd_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRINT_parse_table, 8, "CLRINT", + 0x03, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ERROR_parse_table[] = { + { "DSCTMOUT", 0x02, 0x02 }, + { "ILLOPCODE", 0x04, 0x04 }, + { "SQPARERR", 0x08, 0x08 }, + { "DPARERR", 0x10, 0x10 }, + { "MPARERR", 0x20, 0x20 }, + { "CIOACCESFAIL", 0x40, 0x40 }, + { "CIOPARERR", 0x80, 0x80 } +}; + +int +ahd_error_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ERROR_parse_table, 7, "ERROR", + 0x04, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRERR_parse_table[] = { + { "CLRDSCTMOUT", 0x02, 0x02 }, + { "CLRILLOPCODE", 0x04, 0x04 }, + { "CLRSQPARERR", 0x08, 0x08 }, + { "CLRDPARERR", 0x10, 0x10 }, + { "CLRMPARERR", 0x20, 0x20 }, + { "CLRCIOACCESFAIL", 0x40, 0x40 }, + { "CLRCIOPARERR", 0x80, 0x80 } +}; + +int +ahd_clrerr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRERR_parse_table, 7, "CLRERR", + 0x04, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t HCNTRL_parse_table[] = { + { "CHIPRST", 0x01, 0x01 }, + { "CHIPRSTACK", 0x01, 0x01 }, + { "INTEN", 0x02, 0x02 }, + { "PAUSE", 0x04, 0x04 }, + { "SWTIMER_START_B", 0x08, 0x08 }, + { "SWINT", 0x10, 0x10 }, + { "POWRDN", 0x40, 0x40 }, + { "SEQ_RESET", 0x80, 0x80 } +}; + +int +ahd_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(HCNTRL_parse_table, 8, "HCNTRL", + 0x05, regvalue, cur_col, wrap)); +} + +int +ahd_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HNSCB_QOFF", + 0x06, regvalue, cur_col, wrap)); +} + +int +ahd_hescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HESCB_QOFF", + 0x08, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t HS_MAILBOX_parse_table[] = { + { "ENINT_COALESCE", 0x40, 0x40 }, + { "HOST_TQINPOS", 0x80, 0x80 } +}; + +int +ahd_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(HS_MAILBOX_parse_table, 2, "HS_MAILBOX", + 0x0b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSEQINTSTAT_parse_table[] = { + { "CLRSEQ_SPLTINT", 0x01, 0x01 }, + { "CLRSEQ_PCIINT", 0x02, 0x02 }, + { "CLRSEQ_SCSIINT", 0x04, 0x04 }, + { "CLRSEQ_SEQINT", 0x08, 0x08 }, + { "CLRSEQ_SWTMRTO", 0x10, 0x10 } +}; + +int +ahd_clrseqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSEQINTSTAT_parse_table, 5, "CLRSEQINTSTAT", + 0x0c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTSTAT_parse_table[] = { + { "SEQ_SPLTINT", 0x01, 0x01 }, + { "SEQ_PCIINT", 0x02, 0x02 }, + { "SEQ_SCSIINT", 0x04, 0x04 }, + { "SEQ_SEQINT", 0x08, 0x08 }, + { "SEQ_SWTMRTO", 0x10, 0x10 } +}; + +int +ahd_seqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTSTAT_parse_table, 5, "SEQINTSTAT", + 0x0c, regvalue, cur_col, wrap)); +} + +int +ahd_swtimer_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SWTIMER", + 0x0e, regvalue, cur_col, wrap)); +} + +int +ahd_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SNSCB_QOFF", + 0x10, regvalue, cur_col, wrap)); +} + +int +ahd_sescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SESCB_QOFF", + 0x12, regvalue, cur_col, wrap)); +} + +int +ahd_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SDSCB_QOFF", + 0x14, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = { + { "SCB_QSIZE_4", 0x00, 0x0f }, + { "SCB_QSIZE_8", 0x01, 0x0f }, + { "SCB_QSIZE_16", 0x02, 0x0f }, + { "SCB_QSIZE_32", 0x03, 0x0f }, + { "SCB_QSIZE_64", 0x04, 0x0f }, + { "SCB_QSIZE_128", 0x05, 0x0f }, + { "SCB_QSIZE_256", 0x06, 0x0f }, + { "SCB_QSIZE_512", 0x07, 0x0f }, + { "SCB_QSIZE_1024", 0x08, 0x0f }, + { "SCB_QSIZE_2048", 0x09, 0x0f }, + { "SCB_QSIZE_4096", 0x0a, 0x0f }, + { "SCB_QSIZE_8192", 0x0b, 0x0f }, + { "SCB_QSIZE_16384", 0x0c, 0x0f }, + { "SCB_QSIZE", 0x0f, 0x0f }, + { "HS_MAILBOX_ACT", 0x10, 0x10 }, + { "SDSCB_ROLLOVR", 0x20, 0x20 }, + { "NEW_SCB_AVAIL", 0x40, 0x40 }, + { "EMPTY_SCB_AVAIL", 0x80, 0x80 } +}; + +int +ahd_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(QOFF_CTLSTA_parse_table, 18, "QOFF_CTLSTA", + 0x16, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t INTCTL_parse_table[] = { + { "SPLTINTEN", 0x01, 0x01 }, + { "SEQINTEN", 0x02, 0x02 }, + { "SCSIINTEN", 0x04, 0x04 }, + { "PCIINTEN", 0x08, 0x08 }, + { "AUTOCLRCMDINT", 0x10, 0x10 }, + { "SWTIMER_START", 0x20, 0x20 }, + { "SWTMINTEN", 0x40, 0x40 }, + { "SWTMINTMASK", 0x80, 0x80 } +}; + +int +ahd_intctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(INTCTL_parse_table, 8, "INTCTL", + 0x18, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFCNTRL_parse_table[] = { + { "DIRECTIONEN", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "FIFOFLUSHACK", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "DIRECTIONACK", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SCSIEN", 0x20, 0x20 }, + { "SCSIENACK", 0x20, 0x20 }, + { "SCSIENWRDIS", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahd_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFCNTRL_parse_table, 11, "DFCNTRL", + 0x19, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSCOMMAND0_parse_table[] = { + { "CIOPARCKEN", 0x01, 0x01 }, + { "DISABLE_TWATE", 0x02, 0x02 }, + { "EXTREQLCK", 0x10, 0x10 }, + { "MPARCKEN", 0x20, 0x20 }, + { "DPARCKEN", 0x40, 0x40 }, + { "CACHETHEN", 0x80, 0x80 } +}; + +int +ahd_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSCOMMAND0_parse_table, 6, "DSCOMMAND0", + 0x19, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFSTATUS_parse_table[] = { + { "FIFOEMP", 0x01, 0x01 }, + { "FIFOFULL", 0x02, 0x02 }, + { "DFTHRESH", 0x04, 0x04 }, + { "HDONE", 0x08, 0x08 }, + { "MREQPEND", 0x10, 0x10 }, + { "PKT_PRELOAD_AVAIL", 0x40, 0x40 }, + { "PRELOAD_AVAIL", 0x80, 0x80 } +}; + +int +ahd_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFSTATUS_parse_table, 7, "DFSTATUS", + 0x1a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = { + { "LAST_SEG_DONE", 0x01, 0x01 }, + { "LAST_SEG", 0x02, 0x02 }, + { "ODD_SEG", 0x04, 0x04 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahd_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SG_CACHE_SHADOW_parse_table, 4, "SG_CACHE_SHADOW", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ARBCTL_parse_table[] = { + { "USE_TIME", 0x07, 0x07 }, + { "RETRY_SWEN", 0x08, 0x08 }, + { "RESET_HARB", 0x80, 0x80 } +}; + +int +ahd_arbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ARBCTL_parse_table, 3, "ARBCTL", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = { + { "LAST_SEG", 0x02, 0x02 }, + { "ODD_SEG", 0x04, 0x04 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahd_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE", + 0x1b, regvalue, cur_col, wrap)); +} + +int +ahd_lqin_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQIN", + 0x20, regvalue, cur_col, wrap)); +} + +int +ahd_typeptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TYPEPTR", + 0x20, regvalue, cur_col, wrap)); +} + +int +ahd_tagptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TAGPTR", + 0x21, regvalue, cur_col, wrap)); +} + +int +ahd_lunptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LUNPTR", + 0x22, regvalue, cur_col, wrap)); +} + +int +ahd_datalenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DATALENPTR", + 0x23, regvalue, cur_col, wrap)); +} + +int +ahd_statlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "STATLENPTR", + 0x24, regvalue, cur_col, wrap)); +} + +int +ahd_cmdlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDLENPTR", + 0x25, regvalue, cur_col, wrap)); +} + +int +ahd_attrptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ATTRPTR", + 0x26, regvalue, cur_col, wrap)); +} + +int +ahd_flagptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLAGPTR", + 0x27, regvalue, cur_col, wrap)); +} + +int +ahd_cmdptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDPTR", + 0x28, regvalue, cur_col, wrap)); +} + +int +ahd_qnextptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QNEXTPTR", + 0x29, regvalue, cur_col, wrap)); +} + +int +ahd_idptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "IDPTR", + 0x2a, regvalue, cur_col, wrap)); +} + +int +ahd_abrtbyteptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ABRTBYTEPTR", + 0x2b, regvalue, cur_col, wrap)); +} + +int +ahd_abrtbitptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ABRTBITPTR", + 0x2c, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmdbytes_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMDBYTES", + 0x2d, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmd2rcv_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMD2RCV", + 0x2e, regvalue, cur_col, wrap)); +} + +int +ahd_shortthresh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHORTTHRESH", + 0x2f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LUNLEN_parse_table[] = { + { "ILUNLEN", 0x0f, 0x0f }, + { "TLUNLEN", 0xf0, 0xf0 } +}; + +int +ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LUNLEN_parse_table, 2, "LUNLEN", + 0x30, regvalue, cur_col, wrap)); +} + +int +ahd_cdblimit_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CDBLIMIT", + 0x31, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmd_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMD", + 0x32, regvalue, cur_col, wrap)); +} + +int +ahd_maxcmdcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MAXCMDCNT", + 0x33, regvalue, cur_col, wrap)); +} + +int +ahd_lqrsvd01_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQRSVD01", + 0x34, regvalue, cur_col, wrap)); +} + +int +ahd_lqrsvd16_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQRSVD16", + 0x35, regvalue, cur_col, wrap)); +} + +int +ahd_lqrsvd17_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQRSVD17", + 0x36, regvalue, cur_col, wrap)); +} + +int +ahd_cmdrsvd0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDRSVD0", + 0x37, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQCTL0_parse_table[] = { + { "LQ0INITGCLT", 0x03, 0x03 }, + { "LQ0TARGCLT", 0x0c, 0x0c }, + { "LQIINITGCLT", 0x30, 0x30 }, + { "LQITARGCLT", 0xc0, 0xc0 } +}; + +int +ahd_lqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQCTL0_parse_table, 4, "LQCTL0", + 0x38, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQCTL1_parse_table[] = { + { "ABORTPENDING", 0x01, 0x01 }, + { "SINGLECMD", 0x02, 0x02 }, + { "PCI2PCI", 0x04, 0x04 } +}; + +int +ahd_lqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQCTL1_parse_table, 3, "LQCTL1", + 0x38, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSBIST0_parse_table[] = { + { "OSBISTRUN", 0x01, 0x01 }, + { "OSBISTDONE", 0x02, 0x02 }, + { "OSBISTERR", 0x04, 0x04 }, + { "GSBISTRUN", 0x10, 0x10 }, + { "GSBISTDONE", 0x20, 0x20 }, + { "GSBISTERR", 0x40, 0x40 } +}; + +int +ahd_scsbist0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSBIST0_parse_table, 6, "SCSBIST0", + 0x39, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQCTL2_parse_table[] = { + { "LQOPAUSE", 0x01, 0x01 }, + { "LQOTOIDLE", 0x02, 0x02 }, + { "LQOCONTINUE", 0x04, 0x04 }, + { "LQORETRY", 0x08, 0x08 }, + { "LQIPAUSE", 0x10, 0x10 }, + { "LQITOIDLE", 0x20, 0x20 }, + { "LQICONTINUE", 0x40, 0x40 }, + { "LQIRETRY", 0x80, 0x80 } +}; + +int +ahd_lqctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQCTL2_parse_table, 8, "LQCTL2", + 0x39, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSBIST1_parse_table[] = { + { "NTBISTRUN", 0x01, 0x01 }, + { "NTBISTDONE", 0x02, 0x02 }, + { "NTBISTERR", 0x04, 0x04 } +}; + +int +ahd_scsbist1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSBIST1_parse_table, 3, "SCSBIST1", + 0x3a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISEQ0_parse_table[] = { + { "SCSIRSTO", 0x01, 0x01 }, + { "FORCEBUSFREE", 0x10, 0x10 }, + { "ENARBO", 0x20, 0x20 }, + { "ENSELO", 0x40, 0x40 }, + { "TEMODEO", 0x80, 0x80 } +}; + +int +ahd_scsiseq0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISEQ0_parse_table, 5, "SCSISEQ0", + 0x3a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISEQ1_parse_table[] = { + { "ALTSTIM", 0x01, 0x01 }, + { "ENAUTOATNP", 0x02, 0x02 }, + { "MANUALP", 0x0c, 0x0c }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "MANUALCTL", 0x40, 0x40 } +}; + +int +ahd_scsiseq1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISEQ1_parse_table, 6, "SCSISEQ1", + 0x3b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SXFRCTL0_parse_table[] = { + { "SPIOEN", 0x08, 0x08 }, + { "BIOSCANCELEN", 0x10, 0x10 }, + { "DFPEXP", 0x40, 0x40 }, + { "DFON", 0x80, 0x80 } +}; + +int +ahd_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SXFRCTL0_parse_table, 4, "SXFRCTL0", + 0x3c, regvalue, cur_col, wrap)); +} + +int +ahd_businitid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BUSINITID", + 0x3c, regvalue, cur_col, wrap)); +} + +int +ahd_dlcount_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DLCOUNT", + 0x3c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SXFRCTL1_parse_table[] = { + { "STPWEN", 0x01, 0x01 }, + { "ACTNEGEN", 0x02, 0x02 }, + { "ENSTIMER", 0x04, 0x04 }, + { "STIMESEL", 0x18, 0x18 }, + { "ENSPCHK", 0x20, 0x20 }, + { "ENSACHK", 0x40, 0x40 }, + { "BITBUCKET", 0x80, 0x80 } +}; + +int +ahd_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1", + 0x3d, regvalue, cur_col, wrap)); +} + +int +ahd_bustargid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BUSTARGID", + 0x3e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SXFRCTL2_parse_table[] = { + { "ASU", 0x07, 0x07 }, + { "CMDDMAEN", 0x08, 0x08 }, + { "AUTORSTDIS", 0x10, 0x10 } +}; + +int +ahd_sxfrctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SXFRCTL2_parse_table, 3, "SXFRCTL2", + 0x3e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFFSTAT_parse_table[] = { + { "CURRFIFO_0", 0x00, 0x03 }, + { "CURRFIFO_1", 0x01, 0x03 }, + { "CURRFIFO_NONE", 0x03, 0x03 }, + { "FIFO0FREE", 0x10, 0x10 }, + { "FIFO1FREE", 0x20, 0x20 }, + { "CURRFIFO", 0x03, 0x03 } +}; + +int +ahd_dffstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFFSTAT_parse_table, 6, "DFFSTAT", + 0x3f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISIGO_parse_table[] = { + { "P_DATAOUT", 0x00, 0xe0 }, + { "P_DATAOUT_DT", 0x20, 0xe0 }, + { "P_DATAIN", 0x40, 0xe0 }, + { "P_DATAIN_DT", 0x60, 0xe0 }, + { "P_COMMAND", 0x80, 0xe0 }, + { "P_MESGOUT", 0xa0, 0xe0 }, + { "P_STATUS", 0xc0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 }, + { "ACKO", 0x01, 0x01 }, + { "REQO", 0x02, 0x02 }, + { "BSYO", 0x04, 0x04 }, + { "SELO", 0x08, 0x08 }, + { "ATNO", 0x10, 0x10 }, + { "MSGO", 0x20, 0x20 }, + { "IOO", 0x40, 0x40 }, + { "CDO", 0x80, 0x80 }, + { "PHASE_MASK", 0xe0, 0xe0 } +}; + +int +ahd_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISIGO_parse_table, 17, "SCSISIGO", + 0x40, regvalue, cur_col, wrap)); +} + +int +ahd_multargid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MULTARGID", + 0x40, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISIGI_parse_table[] = { + { "P_DATAOUT", 0x00, 0xe0 }, + { "P_DATAOUT_DT", 0x20, 0xe0 }, + { "P_DATAIN", 0x40, 0xe0 }, + { "P_DATAIN_DT", 0x60, 0xe0 }, + { "P_COMMAND", 0x80, 0xe0 }, + { "P_MESGOUT", 0xa0, 0xe0 }, + { "P_STATUS", 0xc0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 }, + { "ACKI", 0x01, 0x01 }, + { "REQI", 0x02, 0x02 }, + { "BSYI", 0x04, 0x04 }, + { "SELI", 0x08, 0x08 }, + { "ATNI", 0x10, 0x10 }, + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "PHASE_MASK", 0xe0, 0xe0 } +}; + +int +ahd_scsisigi_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISIGI_parse_table, 17, "SCSISIGI", + 0x41, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSIPHASE_parse_table[] = { + { "DATA_OUT_PHASE", 0x01, 0x03 }, + { "DATA_IN_PHASE", 0x02, 0x03 }, + { "DATA_PHASE_MASK", 0x03, 0x03 }, + { "MSG_OUT_PHASE", 0x04, 0x04 }, + { "MSG_IN_PHASE", 0x08, 0x08 }, + { "COMMAND_PHASE", 0x10, 0x10 }, + { "STATUS_PHASE", 0x20, 0x20 } +}; + +int +ahd_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE", + 0x42, regvalue, cur_col, wrap)); +} + +int +ahd_scsidat0_img_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCSIDAT0_IMG", + 0x43, regvalue, cur_col, wrap)); +} + +int +ahd_scsidat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCSIDAT", + 0x44, regvalue, cur_col, wrap)); +} + +int +ahd_scsibus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCSIBUS", + 0x46, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t TARGIDIN_parse_table[] = { + { "TARGID", 0x0f, 0x0f }, + { "CLKOUT", 0x80, 0x80 } +}; + +int +ahd_targidin_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(TARGIDIN_parse_table, 2, "TARGIDIN", + 0x48, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SELID_parse_table[] = { + { "ONEBIT", 0x08, 0x08 }, + { "SELID_MASK", 0xf0, 0xf0 } +}; + +int +ahd_selid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SELID_parse_table, 2, "SELID", + 0x49, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SBLKCTL_parse_table[] = { + { "SELWIDE", 0x02, 0x02 }, + { "ENAB20", 0x04, 0x04 }, + { "ENAB40", 0x08, 0x08 }, + { "DIAGLEDON", 0x40, 0x40 }, + { "DIAGLEDEN", 0x80, 0x80 } +}; + +int +ahd_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL", + 0x4a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OPTIONMODE_parse_table[] = { + { "AUTO_MSGOUT_DE", 0x02, 0x02 }, + { "ENDGFORMCHK", 0x04, 0x04 }, + { "BUSFREEREV", 0x10, 0x10 }, + { "BIASCANCTL", 0x20, 0x20 }, + { "AUTOACKEN", 0x40, 0x40 }, + { "BIOSCANCTL", 0x80, 0x80 }, + { "OPTIONMODE_DEFAULTS",0x02, 0x02 } +}; + +int +ahd_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OPTIONMODE_parse_table, 7, "OPTIONMODE", + 0x4a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT0_parse_table[] = { + { "ARBDO", 0x01, 0x01 }, + { "SPIORDY", 0x02, 0x02 }, + { "OVERRUN", 0x04, 0x04 }, + { "IOERR", 0x08, 0x08 }, + { "SELINGO", 0x10, 0x10 }, + { "SELDI", 0x20, 0x20 }, + { "SELDO", 0x40, 0x40 }, + { "TARGET", 0x80, 0x80 } +}; + +int +ahd_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT0_parse_table, 8, "SSTAT0", + 0x4b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT0_parse_table[] = { + { "CLRARBDO", 0x01, 0x01 }, + { "CLRSPIORDY", 0x02, 0x02 }, + { "CLROVERRUN", 0x04, 0x04 }, + { "CLRIOERR", 0x08, 0x08 }, + { "CLRSELINGO", 0x10, 0x10 }, + { "CLRSELDI", 0x20, 0x20 }, + { "CLRSELDO", 0x40, 0x40 } +}; + +int +ahd_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT0_parse_table, 7, "CLRSINT0", + 0x4b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE0_parse_table[] = { + { "ENARBDO", 0x01, 0x01 }, + { "ENSPIORDY", 0x02, 0x02 }, + { "ENOVERRUN", 0x04, 0x04 }, + { "ENIOERR", 0x08, 0x08 }, + { "ENSELINGO", 0x10, 0x10 }, + { "ENSELDI", 0x20, 0x20 }, + { "ENSELDO", 0x40, 0x40 } +}; + +int +ahd_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE0_parse_table, 7, "SIMODE0", + 0x4b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT1_parse_table[] = { + { "CLRREQINIT", 0x01, 0x01 }, + { "CLRSTRB2FAST", 0x02, 0x02 }, + { "CLRSCSIPERR", 0x04, 0x04 }, + { "CLRBUSFREE", 0x08, 0x08 }, + { "CLRSCSIRSTI", 0x20, 0x20 }, + { "CLRATNO", 0x40, 0x40 }, + { "CLRSELTIMEO", 0x80, 0x80 } +}; + +int +ahd_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT1_parse_table, 7, "CLRSINT1", + 0x4c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT1_parse_table[] = { + { "REQINIT", 0x01, 0x01 }, + { "STRB2FAST", 0x02, 0x02 }, + { "SCSIPERR", 0x04, 0x04 }, + { "BUSFREE", 0x08, 0x08 }, + { "PHASEMIS", 0x10, 0x10 }, + { "SCSIRSTI", 0x20, 0x20 }, + { "ATNTARG", 0x40, 0x40 }, + { "SELTO", 0x80, 0x80 } +}; + +int +ahd_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT1_parse_table, 8, "SSTAT1", + 0x4c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT2_parse_table[] = { + { "BUSFREE_LQO", 0x40, 0xc0 }, + { "BUSFREE_DFF0", 0x80, 0xc0 }, + { "BUSFREE_DFF1", 0xc0, 0xc0 }, + { "DMADONE", 0x01, 0x01 }, + { "SDONE", 0x02, 0x02 }, + { "WIDE_RES", 0x04, 0x04 }, + { "BSYX", 0x08, 0x08 }, + { "EXP_ACTIVE", 0x10, 0x10 }, + { "NONPACKREQ", 0x20, 0x20 }, + { "BUSFREETIME", 0xc0, 0xc0 } +}; + +int +ahd_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT2_parse_table, 10, "SSTAT2", + 0x4d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT2_parse_table[] = { + { "CLRDMADONE", 0x01, 0x01 }, + { "CLRSDONE", 0x02, 0x02 }, + { "CLRWIDE_RES", 0x04, 0x04 }, + { "CLRNONPACKREQ", 0x20, 0x20 } +}; + +int +ahd_clrsint2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT2_parse_table, 4, "CLRSINT2", + 0x4d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE2_parse_table[] = { + { "ENDMADONE", 0x01, 0x01 }, + { "ENSDONE", 0x02, 0x02 }, + { "ENWIDE_RES", 0x04, 0x04 } +}; + +int +ahd_simode2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE2_parse_table, 3, "SIMODE2", + 0x4d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PERRDIAG_parse_table[] = { + { "DTERR", 0x01, 0x01 }, + { "DGFORMERR", 0x02, 0x02 }, + { "CRCERR", 0x04, 0x04 }, + { "AIPERR", 0x08, 0x08 }, + { "PARITYERR", 0x10, 0x10 }, + { "PREVPHASE", 0x20, 0x20 }, + { "HIPERR", 0x40, 0x40 }, + { "HIZERO", 0x80, 0x80 } +}; + +int +ahd_perrdiag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PERRDIAG_parse_table, 8, "PERRDIAG", + 0x4e, regvalue, cur_col, wrap)); +} + +int +ahd_lqistate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQISTATE", + 0x4e, regvalue, cur_col, wrap)); +} + +int +ahd_soffcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SOFFCNT", + 0x4f, regvalue, cur_col, wrap)); +} + +int +ahd_lqostate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LQOSTATE", + 0x4f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQISTAT0_parse_table[] = { + { "LQIATNCMD", 0x01, 0x01 }, + { "LQIATNLQ", 0x02, 0x02 }, + { "LQIBADLQT", 0x04, 0x04 }, + { "LQICRCT2", 0x08, 0x08 }, + { "LQICRCT1", 0x10, 0x10 }, + { "LQIATNQAS", 0x20, 0x20 } +}; + +int +ahd_lqistat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQISTAT0_parse_table, 6, "LQISTAT0", + 0x50, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQIINT0_parse_table[] = { + { "CLRLQIATNCMD", 0x01, 0x01 }, + { "CLRLQIATNLQ", 0x02, 0x02 }, + { "CLRLQIBADLQT", 0x04, 0x04 }, + { "CLRLQICRCT2", 0x08, 0x08 }, + { "CLRLQICRCT1", 0x10, 0x10 }, + { "CLRLQIATNQAS", 0x20, 0x20 } +}; + +int +ahd_clrlqiint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQIINT0_parse_table, 6, "CLRLQIINT0", + 0x50, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQIMODE0_parse_table[] = { + { "ENLQIATNCMD", 0x01, 0x01 }, + { "ENLQIATNLQ", 0x02, 0x02 }, + { "ENLQIBADLQT", 0x04, 0x04 }, + { "ENLQICRCT2", 0x08, 0x08 }, + { "ENLQICRCT1", 0x10, 0x10 }, + { "ENLQIATNQASK", 0x20, 0x20 } +}; + +int +ahd_lqimode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQIMODE0_parse_table, 6, "LQIMODE0", + 0x50, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQIMODE1_parse_table[] = { + { "ENLQIOVERI_NLQ", 0x01, 0x01 }, + { "ENLQIOVERI_LQ", 0x02, 0x02 }, + { "ENLQIBADLQI", 0x04, 0x04 }, + { "ENLQICRCI_NLQ", 0x08, 0x08 }, + { "ENLQICRCI_LQ", 0x10, 0x10 }, + { "ENLIQABORT", 0x20, 0x20 }, + { "ENLQIPHASE_NLQ", 0x40, 0x40 }, + { "ENLQIPHASE_LQ", 0x80, 0x80 } +}; + +int +ahd_lqimode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQIMODE1_parse_table, 8, "LQIMODE1", + 0x51, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQISTAT1_parse_table[] = { + { "LQIOVERI_NLQ", 0x01, 0x01 }, + { "LQIOVERI_LQ", 0x02, 0x02 }, + { "LQIBADLQI", 0x04, 0x04 }, + { "LQICRCI_NLQ", 0x08, 0x08 }, + { "LQICRCI_LQ", 0x10, 0x10 }, + { "LQIABORT", 0x20, 0x20 }, + { "LQIPHASE_NLQ", 0x40, 0x40 }, + { "LQIPHASE_LQ", 0x80, 0x80 } +}; + +int +ahd_lqistat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQISTAT1_parse_table, 8, "LQISTAT1", + 0x51, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQIINT1_parse_table[] = { + { "CLRLQIOVERI_NLQ", 0x01, 0x01 }, + { "CLRLQIOVERI_LQ", 0x02, 0x02 }, + { "CLRLQIBADLQI", 0x04, 0x04 }, + { "CLRLQICRCI_NLQ", 0x08, 0x08 }, + { "CLRLQICRCI_LQ", 0x10, 0x10 }, + { "CLRLIQABORT", 0x20, 0x20 }, + { "CLRLQIPHASE_NLQ", 0x40, 0x40 }, + { "CLRLQIPHASE_LQ", 0x80, 0x80 } +}; + +int +ahd_clrlqiint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQIINT1_parse_table, 8, "CLRLQIINT1", + 0x51, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQISTAT2_parse_table[] = { + { "LQIGSAVAIL", 0x01, 0x01 }, + { "LQISTOPCMD", 0x02, 0x02 }, + { "LQISTOPLQ", 0x04, 0x04 }, + { "LQISTOPPKT", 0x08, 0x08 }, + { "LQIWAITFIFO", 0x10, 0x10 }, + { "LQIWORKONLQ", 0x20, 0x20 }, + { "LQIPHASE_OUTPKT", 0x40, 0x40 }, + { "PACKETIZED", 0x80, 0x80 } +}; + +int +ahd_lqistat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQISTAT2_parse_table, 8, "LQISTAT2", + 0x52, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SSTAT3_parse_table[] = { + { "OSRAMPERR", 0x01, 0x01 }, + { "NTRAMPERR", 0x02, 0x02 } +}; + +int +ahd_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SSTAT3_parse_table, 2, "SSTAT3", + 0x53, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE3_parse_table[] = { + { "ENOSRAMPERR", 0x01, 0x01 }, + { "ENNTRAMPERR", 0x02, 0x02 } +}; + +int +ahd_simode3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE3_parse_table, 2, "SIMODE3", + 0x53, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSINT3_parse_table[] = { + { "CLROSRAMPERR", 0x01, 0x01 }, + { "CLRNTRAMPERR", 0x02, 0x02 } +}; + +int +ahd_clrsint3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSINT3_parse_table, 2, "CLRSINT3", + 0x53, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOMODE0_parse_table[] = { + { "ENLQOTCRC", 0x01, 0x01 }, + { "ENLQOATNPKT", 0x02, 0x02 }, + { "ENLQOATNLQ", 0x04, 0x04 }, + { "ENLQOSTOPT2", 0x08, 0x08 }, + { "ENLQOTARGSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqomode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOMODE0_parse_table, 5, "LQOMODE0", + 0x54, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSTAT0_parse_table[] = { + { "LQOTCRC", 0x01, 0x01 }, + { "LQOATNPKT", 0x02, 0x02 }, + { "LQOATNLQ", 0x04, 0x04 }, + { "LQOSTOPT2", 0x08, 0x08 }, + { "LQOTARGSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqostat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSTAT0_parse_table, 5, "LQOSTAT0", + 0x54, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQOINT0_parse_table[] = { + { "CLRLQOTCRC", 0x01, 0x01 }, + { "CLRLQOATNPKT", 0x02, 0x02 }, + { "CLRLQOATNLQ", 0x04, 0x04 }, + { "CLRLQOSTOPT2", 0x08, 0x08 }, + { "CLRLQOTARGSCBPERR", 0x10, 0x10 } +}; + +int +ahd_clrlqoint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQOINT0_parse_table, 5, "CLRLQOINT0", + 0x54, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSTAT1_parse_table[] = { + { "LQOPHACHGINPKT", 0x01, 0x01 }, + { "LQOBUSFREE", 0x02, 0x02 }, + { "LQOBADQAS", 0x04, 0x04 }, + { "LQOSTOPI2", 0x08, 0x08 }, + { "LQOINITSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqostat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSTAT1_parse_table, 5, "LQOSTAT1", + 0x55, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRLQOINT1_parse_table[] = { + { "CLRLQOPHACHGINPKT", 0x01, 0x01 }, + { "CLRLQOBUSFREE", 0x02, 0x02 }, + { "CLRLQOBADQAS", 0x04, 0x04 }, + { "CLRLQOSTOPI2", 0x08, 0x08 }, + { "CLRLQOINITSCBPERR", 0x10, 0x10 } +}; + +int +ahd_clrlqoint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRLQOINT1_parse_table, 5, "CLRLQOINT1", + 0x55, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOMODE1_parse_table[] = { + { "ENLQOPHACHGINPKT", 0x01, 0x01 }, + { "ENLQOBUSFREE", 0x02, 0x02 }, + { "ENLQOBADQAS", 0x04, 0x04 }, + { "ENLQOSTOPI2", 0x08, 0x08 }, + { "ENLQOINITSCBPERR", 0x10, 0x10 } +}; + +int +ahd_lqomode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOMODE1_parse_table, 5, "LQOMODE1", + 0x55, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSTAT2_parse_table[] = { + { "LQOSTOP0", 0x01, 0x01 }, + { "LQOPHACHGOUTPKT", 0x02, 0x02 }, + { "LQOWAITFIFO", 0x10, 0x10 }, + { "LQOPKT", 0xe0, 0xe0 } +}; + +int +ahd_lqostat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSTAT2_parse_table, 4, "LQOSTAT2", + 0x56, regvalue, cur_col, wrap)); +} + +int +ahd_os_space_cnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OS_SPACE_CNT", + 0x56, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SIMODE1_parse_table[] = { + { "ENREQINIT", 0x01, 0x01 }, + { "ENSTRB2FAST", 0x02, 0x02 }, + { "ENSCSIPERR", 0x04, 0x04 }, + { "ENBUSFREE", 0x08, 0x08 }, + { "ENPHASEMIS", 0x10, 0x10 }, + { "ENSCSIRST", 0x20, 0x20 }, + { "ENATNTARG", 0x40, 0x40 }, + { "ENSELTIMO", 0x80, 0x80 } +}; + +int +ahd_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SIMODE1_parse_table, 8, "SIMODE1", + 0x57, regvalue, cur_col, wrap)); +} + +int +ahd_gsfifo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "GSFIFO", + 0x58, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFFSXFRCTL_parse_table[] = { + { "RSTCHN", 0x01, 0x01 }, + { "CLRCHN", 0x02, 0x02 }, + { "CLRSHCNT", 0x04, 0x04 }, + { "DFFBITBUCKET", 0x08, 0x08 } +}; + +int +ahd_dffsxfrctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFFSXFRCTL_parse_table, 4, "DFFSXFRCTL", + 0x5a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LQOSCSCTL_parse_table[] = { + { "LQONOCHKOVER", 0x01, 0x01 }, + { "LQOH2A_VERSION", 0x80, 0x80 } +}; + +int +ahd_lqoscsctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LQOSCSCTL_parse_table, 2, "LQOSCSCTL", + 0x5a, regvalue, cur_col, wrap)); +} + +int +ahd_nextscb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEXTSCB", + 0x5a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CLRSEQINTSRC_parse_table[] = { + { "CLRCFG4TCMD", 0x01, 0x01 }, + { "CLRCFG4ICMD", 0x02, 0x02 }, + { "CLRCFG4TSTAT", 0x04, 0x04 }, + { "CLRCFG4ISTAT", 0x08, 0x08 }, + { "CLRCFG4DATA", 0x10, 0x10 }, + { "CLRSAVEPTRS", 0x20, 0x20 }, + { "CLRCTXTDONE", 0x40, 0x40 } +}; + +int +ahd_clrseqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CLRSEQINTSRC_parse_table, 7, "CLRSEQINTSRC", + 0x5b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTSRC_parse_table[] = { + { "CFG4TCMD", 0x01, 0x01 }, + { "CFG4ICMD", 0x02, 0x02 }, + { "CFG4TSTAT", 0x04, 0x04 }, + { "CFG4ISTAT", 0x08, 0x08 }, + { "CFG4DATA", 0x10, 0x10 }, + { "SAVEPTRS", 0x20, 0x20 }, + { "CTXTDONE", 0x40, 0x40 } +}; + +int +ahd_seqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTSRC_parse_table, 7, "SEQINTSRC", + 0x5b, regvalue, cur_col, wrap)); +} + +int +ahd_currscb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CURRSCB", + 0x5c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQIMODE_parse_table[] = { + { "ENCFG4TCMD", 0x01, 0x01 }, + { "ENCFG4ICMD", 0x02, 0x02 }, + { "ENCFG4TSTAT", 0x04, 0x04 }, + { "ENCFG4ISTAT", 0x08, 0x08 }, + { "ENCFG4DATA", 0x10, 0x10 }, + { "ENSAVEPTRS", 0x20, 0x20 }, + { "ENCTXTDONE", 0x40, 0x40 } +}; + +int +ahd_seqimode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQIMODE_parse_table, 7, "SEQIMODE", + 0x5c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t MDFFSTAT_parse_table[] = { + { "FIFOFREE", 0x01, 0x01 }, + { "DATAINFIFO", 0x02, 0x02 }, + { "DLZERO", 0x04, 0x04 }, + { "SHVALID", 0x08, 0x08 }, + { "LASTSDONE", 0x10, 0x10 }, + { "SHCNTMINUS1", 0x20, 0x20 }, + { "SHCNTNEGATIVE", 0x40, 0x40 } +}; + +int +ahd_mdffstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(MDFFSTAT_parse_table, 7, "MDFFSTAT", + 0x5d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CRCCONTROL_parse_table[] = { + { "CRCVALCHKEN", 0x40, 0x40 } +}; + +int +ahd_crccontrol_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CRCCONTROL_parse_table, 1, "CRCCONTROL", + 0x5d, regvalue, cur_col, wrap)); +} + +int +ahd_dfftag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFFTAG", + 0x5e, regvalue, cur_col, wrap)); +} + +int +ahd_lastscb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LASTSCB", + 0x5e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSITEST_parse_table[] = { + { "SEL_TXPLL_DEBUG", 0x04, 0x04 }, + { "CNTRTEST", 0x08, 0x08 } +}; + +int +ahd_scsitest_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSITEST_parse_table, 2, "SCSITEST", + 0x5e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t IOPDNCTL_parse_table[] = { + { "PDN_DIFFSENSE", 0x01, 0x01 }, + { "PDN_IDIST", 0x04, 0x04 }, + { "DISABLE_OE", 0x80, 0x80 } +}; + +int +ahd_iopdnctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(IOPDNCTL_parse_table, 3, "IOPDNCTL", + 0x5f, regvalue, cur_col, wrap)); +} + +int +ahd_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHADDR", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahd_negoaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEGOADDR", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahd_dgrpcrci_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DGRPCRCI", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahd_negperiod_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEGPERIOD", + 0x61, regvalue, cur_col, wrap)); +} + +int +ahd_packcrci_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PACKCRCI", + 0x62, regvalue, cur_col, wrap)); +} + +int +ahd_negoffset_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEGOFFSET", + 0x62, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t NEGPPROPTS_parse_table[] = { + { "PPROPT_IUT", 0x01, 0x01 }, + { "PPROPT_DT", 0x02, 0x02 }, + { "PPROPT_QAS", 0x04, 0x04 }, + { "PPROPT_PACE", 0x08, 0x08 } +}; + +int +ahd_negppropts_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NEGPPROPTS_parse_table, 4, "NEGPPROPTS", + 0x63, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t NEGCONOPTS_parse_table[] = { + { "WIDEXFER", 0x01, 0x01 }, + { "ENAUTOATNO", 0x02, 0x02 }, + { "ENAUTOATNI", 0x04, 0x04 }, + { "ENSLOWCRC", 0x08, 0x08 }, + { "RTI_OVRDTRN", 0x10, 0x10 }, + { "RTI_WRTDIS", 0x20, 0x20 }, + { "ENSNAPSHOT", 0x40, 0x40 } +}; + +int +ahd_negconopts_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NEGCONOPTS_parse_table, 7, "NEGCONOPTS", + 0x64, regvalue, cur_col, wrap)); +} + +int +ahd_annexcol_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ANNEXCOL", + 0x65, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSCHKN_parse_table[] = { + { "LSTSGCLRDIS", 0x01, 0x01 }, + { "SHVALIDSTDIS", 0x02, 0x02 }, + { "DFFACTCLR", 0x04, 0x04 }, + { "SDONEMSKDIS", 0x08, 0x08 }, + { "WIDERESEN", 0x10, 0x10 }, + { "CURRFIFODEF", 0x20, 0x20 }, + { "STSELSKIDDIS", 0x40, 0x40 } +}; + +int +ahd_scschkn_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSCHKN_parse_table, 7, "SCSCHKN", + 0x66, regvalue, cur_col, wrap)); +} + +int +ahd_annexdat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ANNEXDAT", + 0x66, regvalue, cur_col, wrap)); +} + +int +ahd_iownid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "IOWNID", + 0x67, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL960CTL0_parse_table[] = { + { "PLL_ENFBM", 0x01, 0x01 }, + { "PLL_DLPF", 0x02, 0x02 }, + { "PLL_ENLPF", 0x04, 0x04 }, + { "PLL_ENLUD", 0x08, 0x08 }, + { "PLL_NS", 0x30, 0x30 }, + { "PLL_PWDN", 0x40, 0x40 }, + { "PLL_VCOSEL", 0x80, 0x80 } +}; + +int +ahd_pll960ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL960CTL0_parse_table, 7, "PLL960CTL0", + 0x68, regvalue, cur_col, wrap)); +} + +int +ahd_shcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHCNT", + 0x68, regvalue, cur_col, wrap)); +} + +int +ahd_townid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TOWNID", + 0x69, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL960CTL1_parse_table[] = { + { "PLL_RST", 0x01, 0x01 }, + { "PLL_CNTCLR", 0x40, 0x40 }, + { "PLL_CNTEN", 0x80, 0x80 } +}; + +int +ahd_pll960ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL960CTL1_parse_table, 3, "PLL960CTL1", + 0x69, regvalue, cur_col, wrap)); +} + +int +ahd_pll960cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PLL960CNT0", + 0x6a, regvalue, cur_col, wrap)); +} + +int +ahd_xsig_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "XSIG", + 0x6a, regvalue, cur_col, wrap)); +} + +int +ahd_seloid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SELOID", + 0x6b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL400CTL0_parse_table[] = { + { "PLL_ENFBM", 0x01, 0x01 }, + { "PLL_DLPF", 0x02, 0x02 }, + { "PLL_ENLPF", 0x04, 0x04 }, + { "PLL_ENLUD", 0x08, 0x08 }, + { "PLL_NS", 0x30, 0x30 }, + { "PLL_PWDN", 0x40, 0x40 }, + { "PLL_VCOSEL", 0x80, 0x80 } +}; + +int +ahd_pll400ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL400CTL0_parse_table, 7, "PLL400CTL0", + 0x6c, regvalue, cur_col, wrap)); +} + +int +ahd_fairness_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FAIRNESS", + 0x6c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLL400CTL1_parse_table[] = { + { "PLL_RST", 0x01, 0x01 }, + { "PLL_CNTCLR", 0x40, 0x40 }, + { "PLL_CNTEN", 0x80, 0x80 } +}; + +int +ahd_pll400ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLL400CTL1_parse_table, 3, "PLL400CTL1", + 0x6d, regvalue, cur_col, wrap)); +} + +int +ahd_pll400cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PLL400CNT0", + 0x6e, regvalue, cur_col, wrap)); +} + +int +ahd_unfairness_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "UNFAIRNESS", + 0x6e, regvalue, cur_col, wrap)); +} + +int +ahd_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HADDR", + 0x70, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PLLDELAY_parse_table[] = { + { "SPLIT_DROP_REQ", 0x80, 0x80 } +}; + +int +ahd_plldelay_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PLLDELAY_parse_table, 1, "PLLDELAY", + 0x70, regvalue, cur_col, wrap)); +} + +int +ahd_hodmaadr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HODMAADR", + 0x70, regvalue, cur_col, wrap)); +} + +int +ahd_hodmacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HODMACNT", + 0x78, regvalue, cur_col, wrap)); +} + +int +ahd_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HCNT", + 0x78, regvalue, cur_col, wrap)); +} + +int +ahd_hodmaen_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "HODMAEN", + 0x7a, regvalue, cur_col, wrap)); +} + +int +ahd_sghaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SGHADDR", + 0x7c, regvalue, cur_col, wrap)); +} + +int +ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBHADDR", + 0x7c, regvalue, cur_col, wrap)); +} + +int +ahd_sghcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SGHCNT", + 0x84, regvalue, cur_col, wrap)); +} + +int +ahd_scbhcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBHCNT", + 0x84, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFF_THRSH_parse_table[] = { + { "WR_DFTHRSH_MIN", 0x00, 0x70 }, + { "RD_DFTHRSH_MIN", 0x00, 0x07 }, + { "RD_DFTHRSH_25", 0x01, 0x07 }, + { "RD_DFTHRSH_50", 0x02, 0x07 }, + { "RD_DFTHRSH_63", 0x03, 0x07 }, + { "RD_DFTHRSH_75", 0x04, 0x07 }, + { "RD_DFTHRSH_85", 0x05, 0x07 }, + { "RD_DFTHRSH_90", 0x06, 0x07 }, + { "RD_DFTHRSH_MAX", 0x07, 0x07 }, + { "WR_DFTHRSH_25", 0x10, 0x70 }, + { "WR_DFTHRSH_50", 0x20, 0x70 }, + { "WR_DFTHRSH_63", 0x30, 0x70 }, + { "WR_DFTHRSH_75", 0x40, 0x70 }, + { "WR_DFTHRSH_85", 0x50, 0x70 }, + { "WR_DFTHRSH_90", 0x60, 0x70 }, + { "WR_DFTHRSH_MAX", 0x70, 0x70 }, + { "RD_DFTHRSH", 0x07, 0x07 }, + { "WR_DFTHRSH", 0x70, 0x70 } +}; + +int +ahd_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH", + 0x88, regvalue, cur_col, wrap)); +} + +int +ahd_romaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ROMADDR", + 0x8a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ROMCNTRL_parse_table[] = { + { "RDY", 0x01, 0x01 }, + { "REPEAT", 0x02, 0x02 }, + { "ROMSPD", 0x18, 0x18 }, + { "ROMOP", 0xe0, 0xe0 } +}; + +int +ahd_romcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ROMCNTRL_parse_table, 4, "ROMCNTRL", + 0x8d, regvalue, cur_col, wrap)); +} + +int +ahd_romdata_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ROMDATA", + 0x8e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_cmcrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG0_parse_table, 2, "CMCRXMSG0", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ROENABLE_parse_table[] = { + { "DCH0ROEN", 0x01, 0x01 }, + { "DCH1ROEN", 0x02, 0x02 }, + { "SGROEN", 0x04, 0x04 }, + { "CMCROEN", 0x08, 0x08 }, + { "OVLYROEN", 0x10, 0x10 }, + { "MSIROEN", 0x20, 0x20 } +}; + +int +ahd_roenable_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ROENABLE_parse_table, 6, "ROENABLE", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_ovlyrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG0_parse_table, 2, "OVLYRXMSG0", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_dchrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG0_parse_table, 2, "DCHRXMSG0", + 0x90, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_ovlyrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG1_parse_table, 1, "OVLYRXMSG1", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t NSENABLE_parse_table[] = { + { "DCH0NSEN", 0x01, 0x01 }, + { "DCH1NSEN", 0x02, 0x02 }, + { "SGNSEN", 0x04, 0x04 }, + { "CMCNSEN", 0x08, 0x08 }, + { "OVLYNSEN", 0x10, 0x10 }, + { "MSINSEN", 0x20, 0x20 } +}; + +int +ahd_nsenable_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NSENABLE_parse_table, 6, "NSENABLE", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_dchrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG1_parse_table, 1, "DCHRXMSG1", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_cmcrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG1_parse_table, 1, "CMCRXMSG1", + 0x91, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_dchrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG2_parse_table, 1, "DCHRXMSG2", + 0x92, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_ovlyrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG2_parse_table, 1, "OVLYRXMSG2", + 0x92, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_cmcrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG2_parse_table, 1, "CMCRXMSG2", + 0x92, regvalue, cur_col, wrap)); +} + +int +ahd_ost_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OST", + 0x92, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_dchrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHRXMSG3_parse_table, 1, "DCHRXMSG3", + 0x93, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_cmcrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCRXMSG3_parse_table, 1, "CMCRXMSG3", + 0x93, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t PCIXCTL_parse_table[] = { + { "CMPABCDIS", 0x01, 0x01 }, + { "TSCSERREN", 0x02, 0x02 }, + { "SRSPDPEEN", 0x04, 0x04 }, + { "SPLTSTADIS", 0x08, 0x08 }, + { "SPLTSMADIS", 0x10, 0x10 }, + { "UNEXPSCIEN", 0x20, 0x20 }, + { "SERRPULSE", 0x80, 0x80 } +}; + +int +ahd_pcixctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(PCIXCTL_parse_table, 7, "PCIXCTL", + 0x93, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_ovlyrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYRXMSG3_parse_table, 1, "OVLYRXMSG3", + 0x93, regvalue, cur_col, wrap)); +} + +int +ahd_ovlyseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OVLYSEQBCNT", + 0x94, regvalue, cur_col, wrap)); +} + +int +ahd_cmcseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMCSEQBCNT", + 0x94, regvalue, cur_col, wrap)); +} + +int +ahd_dchseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DCHSEQBCNT", + 0x94, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_cmcspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCSPLTSTAT0_parse_table, 8, "CMCSPLTSTAT0", + 0x96, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_ovlyspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYSPLTSTAT0_parse_table, 8, "OVLYSPLTSTAT0", + 0x96, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_dchspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHSPLTSTAT0_parse_table, 8, "DCHSPLTSTAT0", + 0x96, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_dchspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DCHSPLTSTAT1_parse_table, 1, "DCHSPLTSTAT1", + 0x97, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_cmcspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCSPLTSTAT1_parse_table, 1, "CMCSPLTSTAT1", + 0x97, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_ovlyspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYSPLTSTAT1_parse_table, 1, "OVLYSPLTSTAT1", + 0x97, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG0_parse_table[] = { + { "CFNUM", 0x07, 0x07 }, + { "CDNUM", 0xf8, 0xf8 } +}; + +int +ahd_sgrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG0_parse_table, 2, "SGRXMSG0", + 0x98, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR0_parse_table[] = { + { "LOWER_ADDR", 0x7f, 0x7f } +}; + +int +ahd_slvspltoutadr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR0_parse_table, 1, "SLVSPLTOUTADR0", + 0x98, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG1_parse_table[] = { + { "CBNUM", 0xff, 0xff } +}; + +int +ahd_sgrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG1_parse_table, 1, "SGRXMSG1", + 0x99, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR1_parse_table[] = { + { "REQ_FNUM", 0x07, 0x07 }, + { "REQ_DNUM", 0xf8, 0xf8 } +}; + +int +ahd_slvspltoutadr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR1_parse_table, 2, "SLVSPLTOUTADR1", + 0x99, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG2_parse_table[] = { + { "MINDEX", 0xff, 0xff } +}; + +int +ahd_sgrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG2_parse_table, 1, "SGRXMSG2", + 0x9a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR2_parse_table[] = { + { "REQ_BNUM", 0xff, 0xff } +}; + +int +ahd_slvspltoutadr2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR2_parse_table, 1, "SLVSPLTOUTADR2", + 0x9a, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGRXMSG3_parse_table[] = { + { "MCLASS", 0x0f, 0x0f } +}; + +int +ahd_sgrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGRXMSG3_parse_table, 1, "SGRXMSG3", + 0x9b, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTADR3_parse_table[] = { + { "RLXORD", 0x10, 0x10 }, + { "TAG_NUM", 0x1f, 0x1f } +}; + +int +ahd_slvspltoutadr3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTADR3_parse_table, 2, "SLVSPLTOUTADR3", + 0x9b, regvalue, cur_col, wrap)); +} + +int +ahd_sgseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SGSEQBCNT", + 0x9c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTATTR0_parse_table[] = { + { "LOWER_BCNT", 0xff, 0xff } +}; + +int +ahd_slvspltoutattr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTATTR0_parse_table, 1, "SLVSPLTOUTATTR0", + 0x9c, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTATTR1_parse_table[] = { + { "CMPLT_FNUM", 0x07, 0x07 }, + { "CMPLT_DNUM", 0xf8, 0xf8 } +}; + +int +ahd_slvspltoutattr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTATTR1_parse_table, 2, "SLVSPLTOUTATTR1", + 0x9d, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SLVSPLTOUTATTR2_parse_table[] = { + { "CMPLT_BNUM", 0xff, 0xff } +}; + +int +ahd_slvspltoutattr2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SLVSPLTOUTATTR2_parse_table, 1, "SLVSPLTOUTATTR2", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGSPLTSTAT0_parse_table[] = { + { "RXSPLTRSP", 0x01, 0x01 }, + { "RXSCEMSG", 0x02, 0x02 }, + { "RXOVRUN", 0x04, 0x04 }, + { "CNTNOTCMPLT", 0x08, 0x08 }, + { "SCDATBUCKET", 0x10, 0x10 }, + { "SCADERR", 0x20, 0x20 }, + { "SCBCERR", 0x40, 0x40 }, + { "STAETERM", 0x80, 0x80 } +}; + +int +ahd_sgspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGSPLTSTAT0_parse_table, 8, "SGSPLTSTAT0", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SFUNCT_parse_table[] = { + { "TEST_NUM", 0x0f, 0x0f }, + { "TEST_GROUP", 0xf0, 0xf0 } +}; + +int +ahd_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SFUNCT_parse_table, 2, "SFUNCT", + 0x9f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGSPLTSTAT1_parse_table[] = { + { "RXDATABUCKET", 0x01, 0x01 } +}; + +int +ahd_sgspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGSPLTSTAT1_parse_table, 1, "SGSPLTSTAT1", + 0x9f, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DF0PCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_df0pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DF0PCISTAT_parse_table, 8, "DF0PCISTAT", + 0xa0, regvalue, cur_col, wrap)); +} + +int +ahd_reg0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "REG0", + 0xa0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DF1PCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_df1pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DF1PCISTAT_parse_table, 8, "DF1PCISTAT", + 0xa1, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SGPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_sgpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SGPCISTAT_parse_table, 7, "SGPCISTAT", + 0xa2, regvalue, cur_col, wrap)); +} + +int +ahd_reg1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "REG1", + 0xa2, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMCPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_cmcpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMCPCISTAT_parse_table, 8, "CMCPCISTAT", + 0xa3, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t OVLYPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "RDPERR", 0x04, 0x04 }, + { "SCAAPERR", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_ovlypcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(OVLYPCISTAT_parse_table, 7, "OVLYPCISTAT", + 0xa4, regvalue, cur_col, wrap)); +} + +int +ahd_reg_isr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "REG_ISR", + 0xa4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SG_STATE_parse_table[] = { + { "SEGS_AVAIL", 0x01, 0x01 }, + { "LOADING_NEEDED", 0x02, 0x02 }, + { "FETCH_INPROG", 0x04, 0x04 } +}; + +int +ahd_sg_state_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SG_STATE_parse_table, 3, "SG_STATE", + 0xa6, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t MSIPCISTAT_parse_table[] = { + { "DPR", 0x01, 0x01 }, + { "TWATERR", 0x02, 0x02 }, + { "CLRPENDMSI", 0x08, 0x08 }, + { "RTA", 0x10, 0x10 }, + { "RMA", 0x20, 0x20 }, + { "SSE", 0x40, 0x40 } +}; + +int +ahd_msipcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(MSIPCISTAT_parse_table, 6, "MSIPCISTAT", + 0xa6, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t TARGPCISTAT_parse_table[] = { + { "TWATERR", 0x02, 0x02 }, + { "STA", 0x08, 0x08 }, + { "SSE", 0x40, 0x40 }, + { "DPE", 0x80, 0x80 } +}; + +int +ahd_targpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(TARGPCISTAT_parse_table, 4, "TARGPCISTAT", + 0xa7, regvalue, cur_col, wrap)); +} + +int +ahd_data_count_odd_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DATA_COUNT_ODD", + 0xa7, regvalue, cur_col, wrap)); +} + +int +ahd_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBPTR", + 0xa8, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBACNT", + 0xab, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCBAUTOPTR_parse_table[] = { + { "SCBPTR_OFF", 0x07, 0x07 }, + { "SCBPTR_ADDR", 0x38, 0x38 }, + { "AUSCBPTR_EN", 0x80, 0x80 } +}; + +int +ahd_scbautoptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCBAUTOPTR_parse_table, 3, "SCBAUTOPTR", + 0xab, regvalue, cur_col, wrap)); +} + +int +ahd_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSGADDR", + 0xac, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBADDR", + 0xac, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbadr_bk_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBADR_BK", + 0xac, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CMC_RAMBIST_parse_table[] = { + { "CMC_BUFFER_BIST_EN", 0x01, 0x01 }, + { "CMC_BUFFER_BIST_FAIL",0x02, 0x02 }, + { "SG_BIST_EN", 0x10, 0x10 }, + { "SG_BIST_FAIL", 0x20, 0x20 }, + { "SCBRAMBIST_FAIL", 0x40, 0x40 }, + { "SG_ELEMENT_SIZE", 0x80, 0x80 } +}; + +int +ahd_cmc_rambist_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CMC_RAMBIST_parse_table, 6, "CMC_RAMBIST", + 0xad, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CCSGCTL_parse_table[] = { + { "CCSGRESET", 0x01, 0x01 }, + { "SG_FETCH_REQ", 0x02, 0x02 }, + { "CCSGENACK", 0x08, 0x08 }, + { "SG_CACHE_AVAIL", 0x10, 0x10 }, + { "CCSGDONE", 0x80, 0x80 }, + { "CCSGEN", 0x0c, 0x0c } +}; + +int +ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL", + 0xad, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = { + { "CCSCBRESET", 0x01, 0x01 }, + { "CCSCBDIR", 0x04, 0x04 }, + { "CCSCBEN", 0x08, 0x08 }, + { "CCARREN", 0x10, 0x10 }, + { "ARRDONE", 0x40, 0x40 }, + { "CCSCBDONE", 0x80, 0x80 } +}; + +int +ahd_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL", + 0xad, regvalue, cur_col, wrap)); +} + +int +ahd_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSGRAM", + 0xb0, regvalue, cur_col, wrap)); +} + +int +ahd_flexadr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLEXADR", + 0xb0, regvalue, cur_col, wrap)); +} + +int +ahd_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CCSCBRAM", + 0xb0, regvalue, cur_col, wrap)); +} + +int +ahd_flexcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLEXCNT", + 0xb3, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t FLEXDMASTAT_parse_table[] = { + { "FLEXDMADONE", 0x01, 0x01 }, + { "FLEXDMAERR", 0x02, 0x02 } +}; + +int +ahd_flexdmastat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(FLEXDMASTAT_parse_table, 2, "FLEXDMASTAT", + 0xb5, regvalue, cur_col, wrap)); +} + +int +ahd_flexdata_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FLEXDATA", + 0xb6, regvalue, cur_col, wrap)); +} + +int +ahd_brddat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BRDDAT", + 0xb8, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t BRDCTL_parse_table[] = { + { "BRDSTB", 0x01, 0x01 }, + { "BRDRW", 0x02, 0x02 }, + { "BRDEN", 0x04, 0x04 }, + { "BRDADDR", 0x38, 0x38 }, + { "FLXARBREQ", 0x40, 0x40 }, + { "FLXARBACK", 0x80, 0x80 } +}; + +int +ahd_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(BRDCTL_parse_table, 6, "BRDCTL", + 0xb9, regvalue, cur_col, wrap)); +} + +int +ahd_seeadr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SEEADR", + 0xba, regvalue, cur_col, wrap)); +} + +int +ahd_seedat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SEEDAT", + 0xbc, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEECTL_parse_table[] = { + { "SEEOP_ERAL", 0x40, 0x70 }, + { "SEEOP_WRITE", 0x50, 0x70 }, + { "SEEOP_READ", 0x60, 0x70 }, + { "SEEOP_ERASE", 0x70, 0x70 }, + { "SEESTART", 0x01, 0x01 }, + { "SEERST", 0x02, 0x02 }, + { "SEEOPCODE", 0x70, 0x70 }, + { "SEEOP_EWEN", 0x40, 0x40 }, + { "SEEOP_WALL", 0x40, 0x40 }, + { "SEEOP_EWDS", 0x40, 0x40 } +}; + +int +ahd_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEECTL_parse_table, 10, "SEECTL", + 0xbe, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEESTAT_parse_table[] = { + { "SEESTART", 0x01, 0x01 }, + { "SEEBUSY", 0x02, 0x02 }, + { "SEEARBACK", 0x04, 0x04 }, + { "LDALTID_L", 0x08, 0x08 }, + { "SEEOPCODE", 0x70, 0x70 }, + { "INIT_DONE", 0x80, 0x80 } +}; + +int +ahd_seestat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEESTAT_parse_table, 6, "SEESTAT", + 0xbe, regvalue, cur_col, wrap)); +} + +int +ahd_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCBCNT", + 0xbf, regvalue, cur_col, wrap)); +} + +int +ahd_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFWADDR", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPFLTRCTL_parse_table[] = { + { "DSPFCNTSEL", 0x0f, 0x0f }, + { "EDGESENSE", 0x10, 0x10 }, + { "FLTRDISABLE", 0x20, 0x20 } +}; + +int +ahd_dspfltrctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPFLTRCTL_parse_table, 3, "DSPFLTRCTL", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPDATACTL_parse_table[] = { + { "XMITOFFSTDIS", 0x02, 0x02 }, + { "RCVROFFSTDIS", 0x04, 0x04 }, + { "DESQDIS", 0x10, 0x10 }, + { "BYPASSENAB", 0x80, 0x80 } +}; + +int +ahd_dspdatactl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPDATACTL_parse_table, 4, "DSPDATACTL", + 0xc1, regvalue, cur_col, wrap)); +} + +int +ahd_dfraddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFRADDR", + 0xc2, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPREQCTL_parse_table[] = { + { "MANREQDLY", 0x3f, 0x3f }, + { "MANREQCTL", 0xc0, 0xc0 } +}; + +int +ahd_dspreqctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPREQCTL_parse_table, 2, "DSPREQCTL", + 0xc2, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPACKCTL_parse_table[] = { + { "MANACKDLY", 0x3f, 0x3f }, + { "MANACKCTL", 0xc0, 0xc0 } +}; + +int +ahd_dspackctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPACKCTL_parse_table, 2, "DSPACKCTL", + 0xc3, regvalue, cur_col, wrap)); +} + +int +ahd_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFDAT", + 0xc4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DSPSELECT_parse_table[] = { + { "DSPSEL", 0x1f, 0x1f }, + { "AUTOINCEN", 0x80, 0x80 } +}; + +int +ahd_dspselect_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DSPSELECT_parse_table, 2, "DSPSELECT", + 0xc4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t WRTBIASCTL_parse_table[] = { + { "XMITMANVAL", 0x3f, 0x3f }, + { "AUTOXBCDIS", 0x80, 0x80 } +}; + +int +ahd_wrtbiasctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(WRTBIASCTL_parse_table, 2, "WRTBIASCTL", + 0xc5, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t RCVRBIOSCTL_parse_table[] = { + { "RCVRMANVAL", 0x3f, 0x3f }, + { "AUTORBCDIS", 0x80, 0x80 } +}; + +int +ahd_rcvrbiosctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(RCVRBIOSCTL_parse_table, 2, "RCVRBIOSCTL", + 0xc6, regvalue, cur_col, wrap)); +} + +int +ahd_wrtbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WRTBIASCALC", + 0xc7, regvalue, cur_col, wrap)); +} + +int +ahd_dfptrs_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFPTRS", + 0xc8, regvalue, cur_col, wrap)); +} + +int +ahd_rcvrbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "RCVRBIASCALC", + 0xc8, regvalue, cur_col, wrap)); +} + +int +ahd_dfbkptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFBKPTR", + 0xc9, regvalue, cur_col, wrap)); +} + +int +ahd_skewcalc_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SKEWCALC", + 0xc9, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DFDBCTL_parse_table[] = { + { "DFF_RAMBIST_EN", 0x01, 0x01 }, + { "DFF_RAMBIST_DONE", 0x02, 0x02 }, + { "DFF_RAMBIST_FAIL", 0x04, 0x04 }, + { "DFF_DIR_ERR", 0x08, 0x08 }, + { "DFF_CIO_RD_RDY", 0x10, 0x10 }, + { "DFF_CIO_WR_RDY", 0x20, 0x20 } +}; + +int +ahd_dfdbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DFDBCTL_parse_table, 6, "DFDBCTL", + 0xcb, regvalue, cur_col, wrap)); +} + +int +ahd_dfscnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFSCNT", + 0xcc, regvalue, cur_col, wrap)); +} + +int +ahd_dfbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DFBCNT", + 0xce, regvalue, cur_col, wrap)); +} + +int +ahd_ovlyaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "OVLYADDR", + 0xd4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQCTL0_parse_table[] = { + { "LOADRAM", 0x01, 0x01 }, + { "SEQRESET", 0x02, 0x02 }, + { "STEP", 0x04, 0x04 }, + { "BRKADRINTEN", 0x08, 0x08 }, + { "FASTMODE", 0x10, 0x10 }, + { "FAILDIS", 0x20, 0x20 }, + { "PAUSEDIS", 0x40, 0x40 }, + { "PERRORDIS", 0x80, 0x80 } +}; + +int +ahd_seqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQCTL0_parse_table, 8, "SEQCTL0", + 0xd6, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQCTL1_parse_table[] = { + { "RAMBIST_EN", 0x01, 0x01 }, + { "RAMBIST_FAIL", 0x02, 0x02 }, + { "RAMBIST_DONE", 0x04, 0x04 }, + { "OVRLAY_DATA_CHK", 0x08, 0x08 } +}; + +int +ahd_seqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQCTL1_parse_table, 4, "SEQCTL1", + 0xd7, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t FLAGS_parse_table[] = { + { "CARRY", 0x01, 0x01 }, + { "ZERO", 0x02, 0x02 } +}; + +int +ahd_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(FLAGS_parse_table, 2, "FLAGS", + 0xd8, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQINTCTL_parse_table[] = { + { "IRET", 0x01, 0x01 }, + { "INTMASK1", 0x02, 0x02 }, + { "INTMASK2", 0x04, 0x04 }, + { "SCS_SEQ_INT1M0", 0x08, 0x08 }, + { "SCS_SEQ_INT1M1", 0x10, 0x10 }, + { "INT1_CONTEXT", 0x20, 0x20 }, + { "INTVEC1DSL", 0x80, 0x80 } +}; + +int +ahd_seqintctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQINTCTL_parse_table, 7, "SEQINTCTL", + 0xd9, regvalue, cur_col, wrap)); +} + +int +ahd_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SEQRAM", + 0xda, regvalue, cur_col, wrap)); +} + +int +ahd_prgmcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "PRGMCNT", + 0xde, regvalue, cur_col, wrap)); +} + +int +ahd_accum_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ACCUM", + 0xe0, regvalue, cur_col, wrap)); +} + +int +ahd_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SINDEX", + 0xe2, regvalue, cur_col, wrap)); +} + +int +ahd_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DINDEX", + 0xe4, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t BRKADDR1_parse_table[] = { + { "BRKDIS", 0x80, 0x80 } +}; + +int +ahd_brkaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(BRKADDR1_parse_table, 1, "BRKADDR1", + 0xe6, regvalue, cur_col, wrap)); +} + +int +ahd_brkaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "BRKADDR0", + 0xe6, regvalue, cur_col, wrap)); +} + +int +ahd_allones_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ALLONES", + 0xe8, regvalue, cur_col, wrap)); +} + +int +ahd_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ALLZEROS", + 0xea, regvalue, cur_col, wrap)); +} + +int +ahd_none_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NONE", + 0xea, regvalue, cur_col, wrap)); +} + +int +ahd_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SINDIR", + 0xec, regvalue, cur_col, wrap)); +} + +int +ahd_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "DINDIR", + 0xed, regvalue, cur_col, wrap)); +} + +int +ahd_function1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "FUNCTION1", + 0xf0, regvalue, cur_col, wrap)); +} + +int +ahd_stack_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "STACK", + 0xf2, regvalue, cur_col, wrap)); +} + +int +ahd_curaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CURADDR", + 0xf4, regvalue, cur_col, wrap)); +} + +int +ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INTVEC1_ADDR", + 0xf4, regvalue, cur_col, wrap)); +} + +int +ahd_intvec2_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INTVEC2_ADDR", + 0xf6, regvalue, cur_col, wrap)); +} + +int +ahd_lastaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LASTADDR", + 0xf6, regvalue, cur_col, wrap)); +} + +int +ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LONGJMP_ADDR", + 0xf8, regvalue, cur_col, wrap)); +} + +int +ahd_accum_save_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ACCUM_SAVE", + 0xfa, regvalue, cur_col, wrap)); +} + +int +ahd_waiting_scb_tails_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", + 0x100, regvalue, cur_col, wrap)); +} + +int +ahd_ahd_pci_config_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE", + 0x100, regvalue, cur_col, wrap)); +} + +int +ahd_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SRAM_BASE", + 0x100, regvalue, cur_col, wrap)); +} + +int +ahd_waiting_tid_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WAITING_TID_HEAD", + 0x120, regvalue, cur_col, wrap)); +} + +int +ahd_waiting_tid_tail_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "WAITING_TID_TAIL", + 0x122, regvalue, cur_col, wrap)); +} + +int +ahd_next_queued_scb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR", + 0x124, regvalue, cur_col, wrap)); +} + +int +ahd_complete_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD", + 0x128, regvalue, cur_col, wrap)); +} + +int +ahd_complete_scb_dmainprog_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD", + 0x12a, regvalue, cur_col, wrap)); +} + +int +ahd_complete_dma_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD", + 0x12c, regvalue, cur_col, wrap)); +} + +int +ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QFREEZE_COUNT", + 0x12e, regvalue, cur_col, wrap)); +} + +int +ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SAVED_MODE", + 0x130, regvalue, cur_col, wrap)); +} + +int +ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MSG_OUT", + 0x131, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t DMAPARAMS_parse_table[] = { + { "FIFORESET", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SDMAEN", 0x10, 0x10 }, + { "SDMAENACK", 0x10, 0x10 }, + { "SCSIEN", 0x20, 0x20 }, + { "WIDEODD", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS", + 0x132, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = { + { "NO_DISCONNECT", 0x01, 0x01 }, + { "SPHASE_PENDING", 0x02, 0x02 }, + { "DPHASE_PENDING", 0x04, 0x04 }, + { "CMDPHASE_PENDING", 0x08, 0x08 }, + { "TARG_CMD_PENDING", 0x10, 0x10 }, + { "DPHASE", 0x20, 0x20 }, + { "NO_CDB_SENT", 0x40, 0x40 }, + { "TARGET_CMD_IS_TAGGED",0x40, 0x40 }, + { "NOT_IDENTIFIED", 0x80, 0x80 } +}; + +int +ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS", + 0x133, regvalue, cur_col, wrap)); +} + +int +ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SAVED_SCSIID", + 0x134, regvalue, cur_col, wrap)); +} + +int +ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SAVED_LUN", + 0x135, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t LASTPHASE_parse_table[] = { + { "P_DATAOUT", 0x00, 0xe0 }, + { "P_DATAOUT_DT", 0x20, 0xe0 }, + { "P_DATAIN", 0x40, 0xe0 }, + { "P_DATAIN_DT", 0x60, 0xe0 }, + { "P_COMMAND", 0x80, 0xe0 }, + { "P_MESGOUT", 0xa0, 0xe0 }, + { "P_STATUS", 0xc0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 }, + { "P_BUSFREE", 0x01, 0x01 }, + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "PHASE_MASK", 0xe0, 0xe0 } +}; + +int +ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE", + 0x136, regvalue, cur_col, wrap)); +} + +int +ahd_qoutfifo_entry_valid_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG", + 0x137, regvalue, cur_col, wrap)); +} + +int +ahd_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", + 0x138, regvalue, cur_col, wrap)); +} + +int +ahd_qoutfifo_next_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", + 0x13c, regvalue, cur_col, wrap)); +} + +int +ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS", + 0x140, regvalue, cur_col, wrap)); +} + +int +ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "TQINPOS", + 0x141, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t ARG_1_parse_table[] = { + { "CONT_MSG_LOOP_TARG", 0x02, 0x02 }, + { "CONT_MSG_LOOP_READ", 0x03, 0x03 }, + { "CONT_MSG_LOOP_WRITE",0x04, 0x04 }, + { "EXIT_MSG_LOOP", 0x08, 0x08 }, + { "MSGOUT_PHASEMIS", 0x10, 0x10 }, + { "SEND_REJ", 0x20, 0x20 }, + { "SEND_SENSE", 0x40, 0x40 }, + { "SEND_MSG", 0x80, 0x80 } +}; + +int +ahd_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(ARG_1_parse_table, 8, "ARG_1", + 0x142, regvalue, cur_col, wrap)); +} + +int +ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ARG_2", + 0x143, regvalue, cur_col, wrap)); +} + +int +ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LAST_MSG", + 0x144, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = { + { "ALTSTIM", 0x01, 0x01 }, + { "ENAUTOATNP", 0x02, 0x02 }, + { "MANUALP", 0x0c, 0x0c }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "MANUALCTL", 0x40, 0x40 } +}; + +int +ahd_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE", + 0x145, regvalue, cur_col, wrap)); +} + +int +ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INITIATOR_TAG", + 0x146, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = { + { "TARGET_MSG_PENDING", 0x02, 0x02 }, + { "SELECTOUT_QFROZEN", 0x04, 0x04 } +}; + +int +ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2", + 0x147, regvalue, cur_col, wrap)); +} + +int +ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR", + 0x148, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER", + 0x14a, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS", + 0x14c, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS", + 0x14d, regvalue, cur_col, wrap)); +} + +int +ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDS_PENDING", + 0x14e, regvalue, cur_col, wrap)); +} + +int +ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT", + 0x150, regvalue, cur_col, wrap)); +} + +int +ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX", + 0x151, regvalue, cur_col, wrap)); +} + +int +ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE", + 0x152, regvalue, cur_col, wrap)); +} + +int +ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_BASE", + 0x180, regvalue, cur_col, wrap)); +} + +int +ahd_scb_residual_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", + 0x180, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_RESIDUAL_SGPTR_parse_table[] = { + { "SG_LIST_NULL", 0x01, 0x01 }, + { "SG_OVERRUN_RESID", 0x02, 0x02 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahd_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_RESIDUAL_SGPTR_parse_table, 3, "SCB_RESIDUAL_SGPTR", + 0x184, regvalue, cur_col, wrap)); +} + +int +ahd_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", + 0x188, regvalue, cur_col, wrap)); +} + +int +ahd_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TARGET_PHASES", + 0x189, regvalue, cur_col, wrap)); +} + +int +ahd_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", + 0x18a, regvalue, cur_col, wrap)); +} + +int +ahd_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TARGET_ITAG", + 0x18b, regvalue, cur_col, wrap)); +} + +int +ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR", + 0x18c, regvalue, cur_col, wrap)); +} + +int +ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TAG", + 0x190, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = { + { "SCB_TAG_TYPE", 0x03, 0x03 }, + { "DISCONNECTED", 0x04, 0x04 }, + { "STATUS_RCVD", 0x08, 0x08 }, + { "MK_MESSAGE", 0x10, 0x10 }, + { "TAG_ENB", 0x20, 0x20 }, + { "DISCENB", 0x40, 0x40 }, + { "TARGET_SCB", 0x80, 0x80 } +}; + +int +ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL", + 0x192, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = { + { "OID", 0x0f, 0x0f }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID", + 0x193, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = { + { "LID", 0xff, 0xff } +}; + +int +ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN", + 0x194, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_TASK_ATTRIBUTE_parse_table[] = { + { "SCB_XFERLEN_ODD", 0x01, 0x01 } +}; + +int +ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_TASK_ATTRIBUTE_parse_table, 1, "SCB_TASK_ATTRIBUTE", + 0x195, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = { + { "SCB_CDB_LEN_PTR", 0x80, 0x80 } +}; + +int +ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN", + 0x196, regvalue, cur_col, wrap)); +} + +int +ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", + 0x197, regvalue, cur_col, wrap)); +} + +int +ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_DATAPTR", + 0x198, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = { + { "SG_HIGH_ADDR_BITS", 0x7f, 0x7f }, + { "SG_LAST_SEG", 0x80, 0x80 } +}; + +int +ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT", + 0x1a0, regvalue, cur_col, wrap)); +} + +static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = { + { "SG_LIST_NULL", 0x01, 0x01 }, + { "SG_FULL_RESID", 0x02, 0x02 }, + { "SG_STATUS_VALID", 0x04, 0x04 } +}; + +int +ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR", + 0x1a4, regvalue, cur_col, wrap)); +} + +int +ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_BUSADDR", + 0x1a8, regvalue, cur_col, wrap)); +} + +int +ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_NEXT", + 0x1ac, regvalue, cur_col, wrap)); +} + +int +ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_NEXT2", + 0x1ae, regvalue, cur_col, wrap)); +} + +int +ahd_scb_spare_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_SPARE", + 0x1b0, regvalue, cur_col, wrap)); +} + +int +ahd_scb_disconnected_lists_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS", + 0x1b8, regvalue, cur_col, wrap)); +} + diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_seq.h linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_seq.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic79xx_seq.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic79xx_seq.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1139 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $ + */ +static uint8_t seqprog[] = { + 0xff, 0x02, 0x06, 0x78, + 0x00, 0xea, 0x50, 0x59, + 0x01, 0xea, 0x04, 0x30, + 0xff, 0x04, 0x0c, 0x78, + 0x19, 0xea, 0x50, 0x59, + 0x19, 0xea, 0x04, 0x00, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x60, 0x3a, 0x1a, 0x68, + 0x04, 0x47, 0x1b, 0x68, + 0xff, 0x21, 0x1b, 0x70, + 0x40, 0x4b, 0x92, 0x69, + 0x00, 0xe2, 0x54, 0x59, + 0x40, 0x4b, 0x92, 0x69, + 0x20, 0x4b, 0x82, 0x69, + 0xfc, 0x42, 0x24, 0x78, + 0x10, 0x40, 0x24, 0x78, + 0x00, 0xe2, 0xc4, 0x5d, + 0x20, 0x4d, 0x28, 0x78, + 0x00, 0xe2, 0xc4, 0x5d, + 0x30, 0x3f, 0xc0, 0x09, + 0x30, 0xe0, 0x30, 0x60, + 0x7f, 0x4a, 0x94, 0x08, + 0x00, 0xe2, 0x32, 0x40, + 0xc0, 0x4a, 0x94, 0x00, + 0x00, 0xe2, 0x3e, 0x58, + 0x00, 0xe2, 0x56, 0x58, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0xe2, 0x06, 0x40, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x01, 0x52, 0x64, 0x78, + 0x02, 0x58, 0x50, 0x31, + 0xff, 0xea, 0x10, 0x0b, + 0xff, 0x97, 0x4f, 0x78, + 0x50, 0x4b, 0x4a, 0x68, + 0xbf, 0x3a, 0x74, 0x08, + 0x14, 0xea, 0x50, 0x59, + 0x14, 0xea, 0x04, 0x00, + 0x08, 0x92, 0x25, 0x03, + 0xff, 0x90, 0x3f, 0x68, + 0x00, 0xe2, 0x56, 0x5b, + 0x00, 0xe2, 0x3e, 0x40, + 0x00, 0xea, 0x44, 0x59, + 0x01, 0xea, 0x00, 0x30, + 0x80, 0xf9, 0x5e, 0x68, + 0x00, 0xe2, 0x42, 0x59, + 0x11, 0xea, 0x44, 0x59, + 0x11, 0xea, 0x00, 0x00, + 0x80, 0xf9, 0x42, 0x79, + 0xff, 0xea, 0xd4, 0x0d, + 0x22, 0xea, 0x44, 0x59, + 0x22, 0xea, 0x00, 0x00, + 0x10, 0x16, 0x70, 0x78, + 0x01, 0x0b, 0xa2, 0x32, + 0x10, 0x16, 0x2c, 0x00, + 0x18, 0xad, 0x00, 0x79, + 0x04, 0xad, 0xca, 0x68, + 0x80, 0xad, 0x64, 0x78, + 0x10, 0xad, 0x98, 0x78, + 0xff, 0x88, 0x83, 0x68, + 0xe7, 0xad, 0x5a, 0x09, + 0x02, 0x8c, 0x59, 0x32, + 0x02, 0x28, 0x19, 0x33, + 0x02, 0xa8, 0x50, 0x36, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x40, 0x3a, 0x64, 0x68, + 0x50, 0x4b, 0x64, 0x68, + 0x22, 0xea, 0x44, 0x59, + 0x22, 0xea, 0x00, 0x00, + 0xe7, 0xad, 0x5a, 0x09, + 0x02, 0x8c, 0x59, 0x32, + 0x1a, 0xea, 0x50, 0x59, + 0x1a, 0xea, 0x04, 0x00, + 0xff, 0xea, 0xd4, 0x0d, + 0xe7, 0xad, 0x5a, 0x09, + 0x00, 0xe2, 0xa6, 0x58, + 0xff, 0xea, 0x56, 0x02, + 0x04, 0x7c, 0x78, 0x32, + 0x20, 0x16, 0x64, 0x78, + 0x04, 0x38, 0x79, 0x32, + 0x80, 0x37, 0x6f, 0x16, + 0xff, 0x2d, 0xb5, 0x60, + 0xff, 0x29, 0xb5, 0x60, + 0x40, 0x51, 0xc5, 0x78, + 0xff, 0x4f, 0xb5, 0x68, + 0xff, 0x4d, 0xc1, 0x19, + 0x00, 0x4e, 0xd5, 0x19, + 0x00, 0xe2, 0xc4, 0x50, + 0x01, 0x4c, 0xc1, 0x31, + 0x00, 0x50, 0xd5, 0x19, + 0x00, 0xe2, 0xc4, 0x48, + 0x80, 0x18, 0x64, 0x78, + 0x02, 0x4a, 0x1d, 0x30, + 0x10, 0xea, 0x18, 0x00, + 0x60, 0x18, 0x30, 0x00, + 0x7f, 0x18, 0x30, 0x0c, + 0x02, 0xea, 0x02, 0x00, + 0xff, 0xea, 0xa0, 0x0a, + 0x80, 0x18, 0x30, 0x04, + 0x40, 0xad, 0x64, 0x78, + 0xe7, 0xad, 0x5a, 0x09, + 0x02, 0xa8, 0x40, 0x31, + 0xff, 0xea, 0xc0, 0x09, + 0x01, 0x4e, 0x9d, 0x1a, + 0x00, 0x4f, 0x9f, 0x22, + 0x01, 0x94, 0x6d, 0x33, + 0x01, 0xea, 0x20, 0x33, + 0x04, 0xac, 0x49, 0x32, + 0xff, 0xea, 0x5a, 0x03, + 0xff, 0xea, 0x5e, 0x03, + 0x01, 0x10, 0xd4, 0x31, + 0x10, 0x92, 0xf5, 0x68, + 0x3d, 0x93, 0xc5, 0x29, + 0xfe, 0xe2, 0xc4, 0x09, + 0x01, 0xea, 0xc6, 0x01, + 0x02, 0xe2, 0xc8, 0x31, + 0x02, 0xec, 0x50, 0x31, + 0x02, 0xa0, 0xda, 0x31, + 0xff, 0xa9, 0xf4, 0x70, + 0x02, 0xa0, 0x58, 0x37, + 0xff, 0x21, 0xfd, 0x70, + 0x02, 0x22, 0x51, 0x31, + 0x02, 0xa0, 0x5c, 0x33, + 0x02, 0xa0, 0x44, 0x36, + 0x02, 0xa0, 0x40, 0x32, + 0x02, 0xa0, 0x44, 0x36, + 0x04, 0x47, 0x05, 0x69, + 0x40, 0x16, 0x30, 0x69, + 0xff, 0x2d, 0x35, 0x61, + 0xff, 0x29, 0x65, 0x70, + 0x01, 0x37, 0xc1, 0x31, + 0x02, 0x28, 0x55, 0x32, + 0x01, 0xea, 0x5a, 0x01, + 0x04, 0x3c, 0xf9, 0x30, + 0x02, 0x28, 0x51, 0x31, + 0x01, 0xa8, 0x60, 0x31, + 0x00, 0xa9, 0x60, 0x01, + 0x01, 0x14, 0xd4, 0x31, + 0x01, 0x50, 0xa1, 0x1a, + 0xff, 0x4e, 0x9d, 0x1a, + 0xff, 0x4f, 0x9f, 0x22, + 0xff, 0x8d, 0x29, 0x71, + 0x80, 0xac, 0x28, 0x71, + 0x20, 0x16, 0x28, 0x69, + 0x02, 0x8c, 0x51, 0x31, + 0x00, 0xe2, 0x12, 0x41, + 0x01, 0xac, 0x08, 0x31, + 0x09, 0xea, 0x5a, 0x01, + 0x02, 0x8c, 0x51, 0x32, + 0xff, 0xea, 0x1a, 0x07, + 0x04, 0x24, 0xf9, 0x30, + 0x1d, 0xea, 0x3a, 0x41, + 0x02, 0x2c, 0x51, 0x31, + 0x04, 0xa8, 0xf9, 0x30, + 0x19, 0xea, 0x3a, 0x41, + 0x06, 0xea, 0x08, 0x81, + 0x01, 0xe2, 0x5a, 0x35, + 0x02, 0xf2, 0xf0, 0x35, + 0x02, 0xf2, 0xf0, 0x31, + 0x02, 0xf8, 0xe4, 0x35, + 0x80, 0xea, 0xb2, 0x01, + 0x01, 0xe2, 0x00, 0x30, + 0xff, 0xea, 0xb2, 0x0d, + 0x80, 0xea, 0xb2, 0x01, + 0x11, 0x00, 0x00, 0x10, + 0xff, 0xea, 0xb2, 0x0d, + 0x01, 0xe2, 0x04, 0x30, + 0x01, 0xea, 0x04, 0x34, + 0x02, 0x20, 0xbd, 0x30, + 0x02, 0x20, 0xb9, 0x30, + 0x02, 0x20, 0x51, 0x31, + 0x4c, 0x93, 0xd7, 0x28, + 0x10, 0x92, 0x63, 0x79, + 0x01, 0x6b, 0xc0, 0x30, + 0x02, 0x64, 0xc8, 0x00, + 0x40, 0x3a, 0x74, 0x04, + 0x00, 0xe2, 0x56, 0x58, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x30, 0x3f, 0xc0, 0x09, + 0x30, 0xe0, 0x64, 0x61, + 0x20, 0x3f, 0x7a, 0x69, + 0x10, 0x3f, 0x64, 0x79, + 0x02, 0xea, 0x7e, 0x00, + 0x00, 0xea, 0x44, 0x59, + 0x01, 0xea, 0x00, 0x30, + 0x02, 0x48, 0x51, 0x35, + 0x01, 0xea, 0x7e, 0x00, + 0x11, 0xea, 0x44, 0x59, + 0x11, 0xea, 0x00, 0x00, + 0x02, 0x48, 0x51, 0x35, + 0x08, 0xea, 0x98, 0x00, + 0x08, 0x57, 0xae, 0x00, + 0x08, 0x3c, 0x78, 0x00, + 0xf0, 0x49, 0x68, 0x0a, + 0x0f, 0x67, 0xc0, 0x09, + 0x00, 0x34, 0x69, 0x02, + 0x20, 0xea, 0x96, 0x00, + 0x00, 0xe2, 0xf8, 0x41, + 0x40, 0x3a, 0xae, 0x69, + 0x02, 0x55, 0x06, 0x68, + 0x02, 0x56, 0xae, 0x69, + 0xff, 0x5b, 0xae, 0x61, + 0x02, 0x20, 0x51, 0x31, + 0x80, 0xea, 0xb2, 0x01, + 0x44, 0xea, 0x00, 0x00, + 0x01, 0x33, 0xc0, 0x31, + 0x33, 0xea, 0x00, 0x00, + 0xff, 0xea, 0xb2, 0x09, + 0xff, 0xe0, 0xc0, 0x19, + 0xff, 0xe0, 0xb0, 0x79, + 0x02, 0xac, 0x51, 0x31, + 0x00, 0xe2, 0xa6, 0x41, + 0x02, 0x5e, 0x50, 0x31, + 0x02, 0xa8, 0xb8, 0x30, + 0x02, 0x5c, 0x50, 0x31, + 0xff, 0xad, 0xc1, 0x71, + 0x02, 0xac, 0x41, 0x31, + 0x02, 0x22, 0x51, 0x31, + 0x02, 0xa0, 0x5c, 0x33, + 0x02, 0xa0, 0x44, 0x32, + 0x00, 0xe2, 0xca, 0x41, + 0x10, 0x92, 0xcb, 0x69, + 0x3d, 0x93, 0xc9, 0x29, + 0x01, 0xe4, 0xc8, 0x01, + 0x01, 0xea, 0xca, 0x01, + 0xff, 0xea, 0xda, 0x01, + 0x02, 0x20, 0x51, 0x31, + 0x02, 0xae, 0x41, 0x32, + 0xff, 0x21, 0xd3, 0x61, + 0xff, 0xea, 0x46, 0x02, + 0x02, 0x5c, 0x50, 0x31, + 0x40, 0xea, 0x96, 0x00, + 0x02, 0x56, 0xcc, 0x6d, + 0x01, 0x55, 0xcc, 0x6d, + 0x10, 0x92, 0xdf, 0x79, + 0x10, 0x40, 0xe8, 0x69, + 0x01, 0x56, 0xe8, 0x79, + 0xff, 0x97, 0x07, 0x78, + 0x13, 0xea, 0x50, 0x59, + 0x13, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x06, 0x40, + 0xbf, 0x3a, 0x74, 0x08, + 0x08, 0xea, 0x98, 0x00, + 0x08, 0x57, 0xae, 0x00, + 0x01, 0x93, 0x69, 0x32, + 0x01, 0x94, 0x6b, 0x32, + 0x40, 0xea, 0x66, 0x02, + 0x08, 0x3c, 0x78, 0x00, + 0x80, 0xea, 0x62, 0x02, + 0x00, 0xe2, 0xb8, 0x5b, + 0x01, 0x36, 0xc1, 0x31, + 0x9f, 0xe0, 0x4c, 0x7c, + 0x80, 0xe0, 0x0c, 0x72, + 0xa0, 0xe0, 0x44, 0x72, + 0xc0, 0xe0, 0x3a, 0x72, + 0xe0, 0xe0, 0x74, 0x72, + 0x01, 0xea, 0x50, 0x59, + 0x01, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xf8, 0x41, + 0x80, 0x33, 0x13, 0x7a, + 0x03, 0xea, 0x50, 0x59, + 0x03, 0xea, 0x04, 0x00, + 0xee, 0x00, 0x1a, 0x6a, + 0x05, 0xea, 0xb4, 0x00, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x02, 0xa8, 0x90, 0x32, + 0x00, 0xe2, 0x6a, 0x59, + 0xef, 0x96, 0xd5, 0x19, + 0x00, 0xe2, 0x2a, 0x52, + 0x09, 0x80, 0xe1, 0x30, + 0x02, 0xea, 0x36, 0x00, + 0xa8, 0xea, 0x32, 0x00, + 0x00, 0xe2, 0x30, 0x42, + 0x01, 0x96, 0xd1, 0x30, + 0x10, 0x80, 0x89, 0x31, + 0x20, 0xea, 0x32, 0x00, + 0xbf, 0x33, 0x67, 0x0a, + 0x20, 0x19, 0x32, 0x6a, + 0x02, 0x4d, 0xf8, 0x69, + 0x40, 0x33, 0x67, 0x02, + 0x00, 0xe2, 0xf8, 0x41, + 0x80, 0x33, 0xb5, 0x6a, + 0x01, 0x44, 0x10, 0x33, + 0x08, 0x92, 0x25, 0x03, + 0x00, 0xe2, 0xf8, 0x41, + 0x10, 0xea, 0x80, 0x00, + 0x01, 0x31, 0xc5, 0x31, + 0x80, 0xe2, 0x60, 0x62, + 0x10, 0x92, 0x85, 0x6a, + 0xc0, 0x94, 0xc5, 0x01, + 0x40, 0x92, 0x51, 0x6a, + 0xbf, 0xe2, 0xc4, 0x09, + 0x20, 0x92, 0x65, 0x7a, + 0x01, 0xe2, 0x88, 0x30, + 0x00, 0xe2, 0xb8, 0x5b, + 0xa0, 0x36, 0x6d, 0x62, + 0x23, 0x92, 0x89, 0x08, + 0x00, 0xe2, 0xb8, 0x5b, + 0xa0, 0x36, 0x6d, 0x62, + 0x00, 0xa8, 0x64, 0x42, + 0xff, 0xe2, 0x64, 0x62, + 0x00, 0xe2, 0x84, 0x42, + 0x40, 0xea, 0x98, 0x00, + 0x01, 0xe2, 0x88, 0x30, + 0x00, 0xe2, 0xb8, 0x5b, + 0xa0, 0x36, 0x43, 0x72, + 0x40, 0xea, 0x98, 0x00, + 0x01, 0x31, 0x89, 0x32, + 0x08, 0xea, 0x62, 0x02, + 0x00, 0xe2, 0xf8, 0x41, + 0xe0, 0xea, 0xd4, 0x5b, + 0x80, 0xe0, 0xc0, 0x6a, + 0x04, 0xe0, 0x66, 0x73, + 0x02, 0xe0, 0x96, 0x73, + 0x00, 0xea, 0x1e, 0x73, + 0x03, 0xe0, 0xa6, 0x73, + 0x23, 0xe0, 0x96, 0x72, + 0x08, 0xe0, 0xbc, 0x72, + 0x00, 0xe2, 0xb8, 0x5b, + 0x07, 0xea, 0x50, 0x59, + 0x07, 0xea, 0x04, 0x00, + 0x08, 0x42, 0xf9, 0x71, + 0x04, 0x42, 0x93, 0x62, + 0x01, 0x43, 0x89, 0x30, + 0x00, 0xe2, 0x84, 0x42, + 0x01, 0x44, 0xd4, 0x31, + 0x00, 0xe2, 0x84, 0x42, + 0x01, 0x00, 0x60, 0x32, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x4c, 0x34, 0xc1, 0x28, + 0x01, 0x64, 0xc0, 0x31, + 0x00, 0x30, 0x45, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x01, 0xe0, 0xba, 0x7a, + 0xa0, 0xea, 0xca, 0x5b, + 0x01, 0xa0, 0xba, 0x62, + 0x01, 0x84, 0xaf, 0x7a, + 0x01, 0x95, 0xbd, 0x6a, + 0x05, 0xea, 0x50, 0x59, + 0x05, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xbc, 0x42, + 0x03, 0xea, 0x50, 0x59, + 0x03, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xbc, 0x42, + 0x07, 0xea, 0xdc, 0x5b, + 0x01, 0x44, 0xd4, 0x31, + 0x00, 0xe2, 0xf8, 0x41, + 0x3f, 0xe0, 0x6a, 0x0a, + 0xc0, 0x34, 0xc1, 0x09, + 0x00, 0x35, 0x51, 0x01, + 0xff, 0xea, 0x52, 0x09, + 0x30, 0x34, 0xc5, 0x09, + 0x3d, 0xe2, 0xc4, 0x29, + 0xb8, 0xe2, 0xc4, 0x19, + 0x01, 0xea, 0xc6, 0x01, + 0x02, 0xe2, 0xc8, 0x31, + 0x02, 0xec, 0x40, 0x31, + 0xff, 0xa1, 0xdc, 0x72, + 0x02, 0xe8, 0xda, 0x31, + 0x02, 0xa0, 0x50, 0x31, + 0x00, 0xe2, 0xfe, 0x42, + 0x80, 0x33, 0x67, 0x02, + 0x01, 0x44, 0xd4, 0x31, + 0x00, 0xe2, 0xb8, 0x5b, + 0x01, 0x33, 0x67, 0x02, + 0xe0, 0x36, 0x19, 0x63, + 0x02, 0x33, 0x67, 0x02, + 0x20, 0x46, 0x12, 0x63, + 0xff, 0xea, 0x52, 0x09, + 0xa8, 0xea, 0xca, 0x5b, + 0x04, 0x92, 0xf9, 0x7a, + 0x01, 0x34, 0xc1, 0x31, + 0x00, 0x93, 0xf9, 0x62, + 0x01, 0x35, 0xc1, 0x31, + 0x00, 0x94, 0x03, 0x73, + 0x01, 0xa9, 0x52, 0x11, + 0xff, 0xa9, 0xee, 0x6a, + 0x00, 0xe2, 0x12, 0x43, + 0x10, 0x33, 0x67, 0x02, + 0x04, 0x92, 0x13, 0x7b, + 0xfb, 0x92, 0x25, 0x0b, + 0xff, 0xea, 0x66, 0x0a, + 0x01, 0xa4, 0x0d, 0x6b, + 0x02, 0xa8, 0x90, 0x32, + 0x00, 0xe2, 0x6a, 0x59, + 0x10, 0x92, 0xbd, 0x7a, + 0xff, 0xea, 0xdc, 0x5b, + 0x00, 0xe2, 0xbc, 0x42, + 0x04, 0xea, 0x50, 0x59, + 0x04, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xbc, 0x42, + 0x04, 0xea, 0x50, 0x59, + 0x04, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xf8, 0x41, + 0x08, 0x92, 0xb5, 0x7a, + 0xc0, 0x33, 0x29, 0x7b, + 0x80, 0x33, 0xb5, 0x6a, + 0xff, 0x88, 0x29, 0x6b, + 0x40, 0x33, 0xb5, 0x6a, + 0x10, 0x92, 0x2f, 0x7b, + 0x0a, 0xea, 0x50, 0x59, + 0x0a, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x4e, 0x5b, + 0x00, 0xe2, 0x82, 0x43, + 0x50, 0x4b, 0x36, 0x6b, + 0xbf, 0x3a, 0x74, 0x08, + 0x01, 0xe0, 0xf4, 0x31, + 0xff, 0xea, 0xc0, 0x09, + 0x01, 0x2e, 0x5d, 0x1a, + 0x00, 0x2f, 0x5f, 0x22, + 0x04, 0x47, 0x8f, 0x02, + 0x01, 0xfa, 0xc0, 0x35, + 0x02, 0xa8, 0x84, 0x32, + 0x02, 0xea, 0xb4, 0x00, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x02, 0x42, 0x51, 0x31, + 0xff, 0x90, 0x65, 0x68, + 0xff, 0x88, 0x5b, 0x6b, + 0x01, 0xa4, 0x57, 0x6b, + 0x02, 0xa4, 0x5f, 0x6b, + 0x01, 0x84, 0x5f, 0x7b, + 0x02, 0x28, 0x19, 0x33, + 0x02, 0xa8, 0x50, 0x36, + 0xff, 0x88, 0x5f, 0x73, + 0x00, 0xe2, 0x32, 0x5b, + 0x02, 0xa8, 0x20, 0x33, + 0x02, 0x2c, 0x19, 0x33, + 0x02, 0xa8, 0x58, 0x32, + 0x04, 0xa4, 0x49, 0x07, + 0xc0, 0x33, 0xb5, 0x6a, + 0x04, 0x92, 0x25, 0x03, + 0x20, 0x92, 0x83, 0x6b, + 0x02, 0xa8, 0x40, 0x31, + 0xc0, 0x34, 0xc1, 0x09, + 0x00, 0x35, 0x51, 0x01, + 0xff, 0xea, 0x52, 0x09, + 0x30, 0x34, 0xc5, 0x09, + 0x3d, 0xe2, 0xc4, 0x29, + 0xb8, 0xe2, 0xc4, 0x19, + 0x01, 0xea, 0xc6, 0x01, + 0x02, 0xe2, 0xc8, 0x31, + 0x02, 0xa0, 0xda, 0x31, + 0x02, 0xa0, 0x50, 0x31, + 0xf7, 0x57, 0xae, 0x08, + 0x08, 0xea, 0x98, 0x00, + 0x01, 0x44, 0xd4, 0x31, + 0xee, 0x00, 0x8c, 0x6b, + 0x02, 0xea, 0xb4, 0x00, + 0x00, 0xe2, 0xb4, 0x5b, + 0x09, 0x4c, 0x8e, 0x7b, + 0x08, 0x4c, 0x06, 0x68, + 0x0b, 0xea, 0x50, 0x59, + 0x0b, 0xea, 0x04, 0x00, + 0x01, 0x44, 0xd4, 0x31, + 0x20, 0x33, 0xf9, 0x79, + 0x00, 0xe2, 0x9e, 0x5b, + 0x00, 0xe2, 0xf8, 0x41, + 0x01, 0x84, 0xa3, 0x7b, + 0x01, 0xa4, 0x49, 0x07, + 0x08, 0x60, 0x30, 0x33, + 0x08, 0x80, 0x41, 0x37, + 0xdf, 0x33, 0x67, 0x0a, + 0xee, 0x00, 0xb0, 0x6b, + 0x05, 0xea, 0xb4, 0x00, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x00, 0xe2, 0x6a, 0x59, + 0x00, 0xe2, 0xbc, 0x42, + 0x01, 0xea, 0x6c, 0x02, + 0xc0, 0xea, 0x66, 0x06, + 0xff, 0x42, 0xc4, 0x6b, + 0x01, 0x41, 0xb8, 0x6b, + 0x02, 0x41, 0xb8, 0x7b, + 0xff, 0x42, 0xc4, 0x6b, + 0x01, 0x41, 0xb8, 0x6b, + 0x02, 0x41, 0xb8, 0x7b, + 0xff, 0x42, 0xc4, 0x7b, + 0x04, 0x4c, 0xb8, 0x6b, + 0xe0, 0x41, 0x6c, 0x0e, + 0x01, 0x44, 0xd4, 0x31, + 0xff, 0x42, 0xcc, 0x7b, + 0x04, 0x4c, 0xcc, 0x6b, + 0xe0, 0x41, 0x6c, 0x0a, + 0xe0, 0x36, 0xf9, 0x61, + 0xff, 0xea, 0xca, 0x09, + 0x01, 0xe2, 0xc8, 0x31, + 0x01, 0x46, 0xda, 0x35, + 0x01, 0x44, 0xd4, 0x35, + 0x10, 0xea, 0x80, 0x00, + 0x01, 0xe2, 0x62, 0x36, + 0x04, 0xa6, 0xe4, 0x7b, + 0xff, 0xea, 0x5a, 0x09, + 0xff, 0xea, 0x4c, 0x0d, + 0x01, 0xa6, 0x02, 0x6c, + 0x10, 0xad, 0x64, 0x78, + 0x80, 0xad, 0xfa, 0x6b, + 0x08, 0xad, 0x64, 0x68, + 0x04, 0x84, 0xf9, 0x30, + 0x00, 0xea, 0x08, 0x81, + 0xff, 0xea, 0xd4, 0x09, + 0x02, 0x84, 0xf9, 0x88, + 0x0d, 0xea, 0x5a, 0x01, + 0x04, 0xa6, 0x4c, 0x05, + 0x04, 0xa6, 0x64, 0x78, + 0xff, 0xea, 0x5a, 0x09, + 0x03, 0x84, 0x59, 0x89, + 0x03, 0xea, 0x4c, 0x01, + 0x80, 0x1a, 0x64, 0x78, + 0x08, 0x19, 0x64, 0x78, + 0x08, 0xb0, 0xe0, 0x30, + 0x04, 0xb0, 0xe0, 0x30, + 0x03, 0xb0, 0xf0, 0x30, + 0x01, 0xb0, 0x06, 0x33, + 0x7f, 0x83, 0xe9, 0x08, + 0x04, 0xac, 0x58, 0x19, + 0xff, 0xea, 0xc0, 0x09, + 0x04, 0x84, 0x09, 0x9b, + 0x00, 0x85, 0x0b, 0x23, + 0x00, 0x86, 0x0d, 0x23, + 0x00, 0x87, 0x0f, 0x23, + 0x01, 0x84, 0xc5, 0x31, + 0x80, 0x83, 0x25, 0x7c, + 0x02, 0xe2, 0xc4, 0x01, + 0xff, 0xea, 0x4c, 0x09, + 0x01, 0xe2, 0x36, 0x30, + 0xc8, 0x19, 0x32, 0x00, + 0x88, 0x19, 0x32, 0x00, + 0x01, 0xac, 0xd4, 0x99, + 0x00, 0xe2, 0x64, 0x50, + 0xfe, 0xa6, 0x4c, 0x0d, + 0x0b, 0x98, 0xe1, 0x30, + 0xfd, 0xa4, 0x49, 0x09, + 0x80, 0xa3, 0x39, 0x7c, + 0x02, 0xa4, 0x48, 0x01, + 0x01, 0xa4, 0x36, 0x30, + 0xa8, 0xea, 0x32, 0x00, + 0xfd, 0xa4, 0x49, 0x0b, + 0x05, 0xa3, 0x07, 0x33, + 0x80, 0x83, 0x45, 0x6c, + 0x02, 0xea, 0x4c, 0x05, + 0xff, 0xea, 0x4c, 0x0d, + 0x00, 0xe2, 0x3e, 0x59, + 0x02, 0xa6, 0xe6, 0x6b, + 0x80, 0xf9, 0xf2, 0x05, + 0xc0, 0x33, 0x53, 0x7c, + 0x03, 0xea, 0x50, 0x59, + 0x03, 0xea, 0x04, 0x00, + 0x20, 0x33, 0x77, 0x7c, + 0x01, 0x84, 0x5d, 0x6c, + 0x06, 0xea, 0x50, 0x59, + 0x06, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x7a, 0x44, + 0x01, 0x00, 0x60, 0x32, + 0xee, 0x00, 0x66, 0x6c, + 0x05, 0xea, 0xb4, 0x00, + 0x33, 0xea, 0x44, 0x59, + 0x33, 0xea, 0x00, 0x00, + 0x80, 0x3d, 0x7a, 0x00, + 0xfc, 0x42, 0x68, 0x7c, + 0x7f, 0x3d, 0x7a, 0x08, + 0x00, 0x30, 0x45, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x09, 0xea, 0x50, 0x59, + 0x09, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xf8, 0x41, + 0x01, 0xa4, 0x5d, 0x6c, + 0x00, 0xe2, 0x30, 0x5c, + 0x20, 0x33, 0x67, 0x02, + 0x01, 0x00, 0x60, 0x32, + 0x02, 0xa6, 0x82, 0x7c, + 0x00, 0xe2, 0x46, 0x5c, + 0x00, 0xe2, 0x56, 0x58, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0xe2, 0x3a, 0x58, + 0x00, 0x30, 0x45, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x20, 0x19, 0x82, 0x6c, + 0x00, 0xe2, 0xb2, 0x5c, + 0x04, 0x19, 0x9c, 0x6c, + 0x02, 0x19, 0x32, 0x00, + 0x01, 0x84, 0x9d, 0x7c, + 0x01, 0x1b, 0x96, 0x7c, + 0x01, 0x1a, 0x9c, 0x6c, + 0x00, 0xe2, 0x4c, 0x44, + 0x80, 0x4b, 0xa2, 0x6c, + 0x01, 0x4c, 0x9e, 0x7c, + 0x03, 0x42, 0x4c, 0x6c, + 0x00, 0xe2, 0xe0, 0x5b, + 0x80, 0xf9, 0xf2, 0x01, + 0x04, 0x33, 0xf9, 0x79, + 0x00, 0xe2, 0xf8, 0x41, + 0x08, 0x5d, 0xba, 0x6c, + 0x00, 0xe2, 0x56, 0x58, + 0x00, 0x30, 0x45, 0x59, + 0x01, 0x30, 0x01, 0x30, + 0x02, 0x1b, 0xaa, 0x7c, + 0x08, 0x5d, 0xb8, 0x7c, + 0x03, 0x68, 0x00, 0x37, + 0x01, 0x84, 0x09, 0x07, + 0x80, 0x1b, 0xc4, 0x7c, + 0x80, 0x84, 0xc5, 0x6c, + 0xff, 0x85, 0x0b, 0x1b, + 0xff, 0x86, 0x0d, 0x23, + 0xff, 0x87, 0x0f, 0x23, + 0xf8, 0x1b, 0x08, 0x0b, + 0xff, 0xea, 0x06, 0x0b, + 0x03, 0x68, 0x00, 0x37, + 0x00, 0xe2, 0xc4, 0x58, + 0x10, 0xea, 0x18, 0x00, + 0xf9, 0xd9, 0xb2, 0x0d, + 0x01, 0xd9, 0xb2, 0x05, + 0x01, 0x52, 0x48, 0x31, + 0x20, 0xa4, 0xee, 0x7c, + 0x20, 0x5b, 0xee, 0x7c, + 0x80, 0xf9, 0xfc, 0x7c, + 0x02, 0xea, 0xb4, 0x00, + 0x11, 0x00, 0x00, 0x10, + 0x04, 0x19, 0x08, 0x7d, + 0xdf, 0x19, 0x32, 0x08, + 0x60, 0x5b, 0xe6, 0x6c, + 0x01, 0x4c, 0xe2, 0x7c, + 0x20, 0x19, 0x32, 0x00, + 0x01, 0xd9, 0xb2, 0x05, + 0x02, 0xea, 0xb4, 0x00, + 0x01, 0xd9, 0xb2, 0x05, + 0x10, 0x5b, 0x00, 0x6d, + 0x08, 0x5b, 0x0a, 0x6d, + 0x20, 0x5b, 0xfa, 0x6c, + 0x02, 0x5b, 0x2a, 0x6d, + 0x0e, 0xea, 0x50, 0x59, + 0x0e, 0xea, 0x04, 0x00, + 0x80, 0xf9, 0xea, 0x6c, + 0xdf, 0x5c, 0xb8, 0x08, + 0x01, 0xd9, 0xb2, 0x05, + 0x01, 0xa4, 0xe5, 0x6d, + 0x00, 0xe2, 0x30, 0x5c, + 0x00, 0xe2, 0x34, 0x5d, + 0x01, 0x90, 0x21, 0x1b, + 0x01, 0xd9, 0xb2, 0x05, + 0x00, 0xe2, 0x32, 0x5b, + 0xf3, 0x96, 0xd5, 0x19, + 0x00, 0xe2, 0x18, 0x55, + 0x80, 0x96, 0x19, 0x6d, + 0x0f, 0xea, 0x50, 0x59, + 0x0f, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x20, 0x45, + 0x04, 0x8c, 0xe1, 0x30, + 0x01, 0xea, 0xf2, 0x00, + 0x02, 0xea, 0x36, 0x00, + 0xa8, 0xea, 0x32, 0x00, + 0xff, 0x97, 0x27, 0x7d, + 0x14, 0xea, 0x50, 0x59, + 0x14, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x96, 0x5d, + 0x01, 0xd9, 0xb2, 0x05, + 0x09, 0x80, 0xe1, 0x30, + 0x02, 0xea, 0x36, 0x00, + 0xa8, 0xea, 0x32, 0x00, + 0x00, 0xe2, 0x8e, 0x5d, + 0x01, 0xd9, 0xb2, 0x05, + 0x02, 0xa6, 0x44, 0x7d, + 0x00, 0xe2, 0x3e, 0x59, + 0x20, 0x5b, 0x52, 0x6d, + 0xfc, 0x42, 0x3e, 0x7d, + 0x10, 0x40, 0x40, 0x6d, + 0x20, 0x4d, 0x42, 0x7d, + 0x08, 0x5d, 0x52, 0x6d, + 0x02, 0xa6, 0xe6, 0x6b, + 0x00, 0xe2, 0x3e, 0x59, + 0x20, 0x5b, 0x52, 0x6d, + 0x01, 0x1b, 0x72, 0x6d, + 0xfc, 0x42, 0x4e, 0x7d, + 0x10, 0x40, 0x50, 0x6d, + 0x20, 0x4d, 0x64, 0x78, + 0x08, 0x5d, 0x64, 0x78, + 0x02, 0x19, 0x32, 0x00, + 0x01, 0x5b, 0x40, 0x31, + 0x00, 0xe2, 0xb2, 0x5c, + 0x00, 0xe2, 0x9e, 0x5b, + 0x20, 0xea, 0xb6, 0x00, + 0x00, 0xe2, 0xe0, 0x5b, + 0x20, 0x5c, 0xb8, 0x00, + 0x04, 0x19, 0x68, 0x6d, + 0x01, 0x1a, 0x68, 0x6d, + 0x00, 0xe2, 0x3e, 0x59, + 0x01, 0x1a, 0x64, 0x78, + 0x80, 0xf9, 0xf2, 0x01, + 0x20, 0xa0, 0xcc, 0x7d, + 0xff, 0x90, 0x21, 0x1b, + 0x08, 0x92, 0x43, 0x6b, + 0x02, 0xea, 0xb4, 0x04, + 0x01, 0xa4, 0x49, 0x03, + 0x40, 0x5b, 0x82, 0x6d, + 0x00, 0xe2, 0x3e, 0x59, + 0x40, 0x5b, 0x82, 0x6d, + 0x04, 0x5d, 0xe6, 0x7d, + 0x01, 0x1a, 0xe6, 0x7d, + 0x20, 0x4d, 0x64, 0x78, + 0x40, 0x5b, 0xcc, 0x7d, + 0x04, 0x5d, 0xe6, 0x7d, + 0x01, 0x1a, 0xe6, 0x7d, + 0x80, 0xf9, 0xf2, 0x01, + 0xff, 0x90, 0x21, 0x1b, + 0x08, 0x92, 0x43, 0x6b, + 0x02, 0xea, 0xb4, 0x04, + 0x00, 0xe2, 0x3e, 0x59, + 0x01, 0x1b, 0x64, 0x78, + 0x80, 0xf9, 0xf2, 0x01, + 0x02, 0xea, 0xb4, 0x04, + 0x00, 0xe2, 0x3e, 0x59, + 0x01, 0x1b, 0xaa, 0x6d, + 0x40, 0x5b, 0xb8, 0x7d, + 0x01, 0x1b, 0xaa, 0x6d, + 0x02, 0x19, 0x32, 0x00, + 0x01, 0x1a, 0x64, 0x78, + 0x80, 0xf9, 0xf2, 0x01, + 0xff, 0xea, 0x10, 0x03, + 0x08, 0x92, 0x25, 0x03, + 0x00, 0xe2, 0x42, 0x43, + 0x01, 0x1a, 0xb4, 0x7d, + 0x40, 0x5b, 0xb0, 0x7d, + 0x01, 0x1a, 0x9e, 0x6d, + 0xfc, 0x42, 0x64, 0x78, + 0x01, 0x1a, 0xb8, 0x6d, + 0x10, 0xea, 0x50, 0x59, + 0x10, 0xea, 0x04, 0x00, + 0xfc, 0x42, 0x64, 0x78, + 0x10, 0x40, 0xbe, 0x6d, + 0x20, 0x4d, 0x64, 0x78, + 0x40, 0x5b, 0x9e, 0x6d, + 0x01, 0x1a, 0x64, 0x78, + 0x01, 0x90, 0x21, 0x1b, + 0x30, 0x3f, 0xc0, 0x09, + 0x30, 0xe0, 0x64, 0x60, + 0x40, 0x4b, 0x64, 0x68, + 0xff, 0xea, 0x52, 0x01, + 0xee, 0x00, 0xd2, 0x6d, + 0x80, 0xf9, 0xf2, 0x01, + 0xff, 0x90, 0x21, 0x1b, + 0x02, 0xea, 0xb4, 0x00, + 0x20, 0xea, 0x9a, 0x00, + 0xf3, 0x42, 0xde, 0x6d, + 0x12, 0xea, 0x50, 0x59, + 0x12, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xf8, 0x41, + 0x0d, 0xea, 0x50, 0x59, + 0x0d, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0xf8, 0x41, + 0x01, 0x90, 0x21, 0x1b, + 0x11, 0xea, 0x50, 0x59, + 0x11, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x32, 0x5b, + 0x08, 0x5a, 0xb4, 0x00, + 0x00, 0xe2, 0x0c, 0x5e, + 0xa8, 0xea, 0x32, 0x00, + 0x00, 0xe2, 0x3e, 0x59, + 0x80, 0x1a, 0xfa, 0x7d, + 0x00, 0xe2, 0x0c, 0x5e, + 0x80, 0x19, 0x32, 0x00, + 0x40, 0x5b, 0x00, 0x6e, + 0x08, 0x5a, 0x00, 0x7e, + 0x20, 0x4d, 0x64, 0x78, + 0x02, 0x84, 0x09, 0x03, + 0x40, 0x5b, 0xcc, 0x7d, + 0xff, 0x90, 0x21, 0x1b, + 0x80, 0xf9, 0xf2, 0x01, + 0x08, 0x92, 0x43, 0x6b, + 0x02, 0xea, 0xb4, 0x04, + 0x01, 0x38, 0xe1, 0x30, + 0x05, 0x39, 0xe3, 0x98, + 0x01, 0xe0, 0xf4, 0x31, + 0xff, 0xea, 0xc0, 0x09, + 0x00, 0x3a, 0xe5, 0x20, + 0x00, 0x3b, 0xe7, 0x20, + 0x01, 0xfa, 0xc0, 0x31, + 0x04, 0xea, 0xe8, 0x30, + 0xff, 0xea, 0xf0, 0x08, + 0x02, 0xea, 0xf2, 0x00, + 0xff, 0xea, 0xf4, 0x0c +}; + +typedef int ahd_patch_func_t (struct ahd_softc *ahd); +static ahd_patch_func_t ahd_patch22_func; + +static int +ahd_patch22_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch21_func; + +static int +ahd_patch21_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0); +} + +static ahd_patch_func_t ahd_patch20_func; + +static int +ahd_patch20_func(struct ahd_softc *ahd) +{ + return ((ahd->features & AHD_RTI) == 0); +} + +static ahd_patch_func_t ahd_patch19_func; + +static int +ahd_patch19_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_INITIATORROLE) != 0); +} + +static ahd_patch_func_t ahd_patch18_func; + +static int +ahd_patch18_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_TARGETROLE) != 0); +} + +static ahd_patch_func_t ahd_patch17_func; + +static int +ahd_patch17_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch16_func; + +static int +ahd_patch16_func(struct ahd_softc *ahd) +{ + return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0); +} + +static ahd_patch_func_t ahd_patch15_func; + +static int +ahd_patch15_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0); +} + +static ahd_patch_func_t ahd_patch14_func; + +static int +ahd_patch14_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0); +} + +static ahd_patch_func_t ahd_patch13_func; + +static int +ahd_patch13_func(struct ahd_softc *ahd) +{ + return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0); +} + +static ahd_patch_func_t ahd_patch12_func; + +static int +ahd_patch12_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch11_func; + +static int +ahd_patch11_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch10_func; + +static int +ahd_patch10_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0); +} + +static ahd_patch_func_t ahd_patch9_func; + +static int +ahd_patch9_func(struct ahd_softc *ahd) +{ + return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0); +} + +static ahd_patch_func_t ahd_patch8_func; + +static int +ahd_patch8_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch7_func; + +static int +ahd_patch7_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch6_func; + +static int +ahd_patch6_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch5_func; + +static int +ahd_patch5_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch4_func; + +static int +ahd_patch4_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_PKT_LUN_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch3_func; + +static int +ahd_patch3_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_FAINT_LED_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch2_func; + +static int +ahd_patch2_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_SET_MODE_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch1_func; + +static int +ahd_patch1_func(struct ahd_softc *ahd) +{ + return ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0); +} + +static ahd_patch_func_t ahd_patch0_func; + +static int +ahd_patch0_func(struct ahd_softc *ahd) +{ + return (0); +} + +static struct patch { + ahd_patch_func_t *patch_func; + uint32_t begin :10, + skip_instr :10, + skip_patch :12; +} patches[] = { + { ahd_patch1_func, 0, 3, 3 }, + { ahd_patch1_func, 1, 1, 2 }, + { ahd_patch0_func, 2, 1, 1 }, + { ahd_patch1_func, 3, 3, 3 }, + { ahd_patch1_func, 4, 1, 2 }, + { ahd_patch0_func, 5, 1, 1 }, + { ahd_patch2_func, 6, 1, 2 }, + { ahd_patch0_func, 7, 1, 1 }, + { ahd_patch3_func, 20, 5, 1 }, + { ahd_patch2_func, 29, 1, 2 }, + { ahd_patch0_func, 30, 1, 1 }, + { ahd_patch1_func, 37, 1, 2 }, + { ahd_patch0_func, 38, 1, 1 }, + { ahd_patch2_func, 43, 1, 2 }, + { ahd_patch0_func, 44, 1, 1 }, + { ahd_patch2_func, 47, 1, 2 }, + { ahd_patch0_func, 48, 1, 1 }, + { ahd_patch2_func, 51, 1, 2 }, + { ahd_patch0_func, 52, 1, 1 }, + { ahd_patch2_func, 65, 1, 2 }, + { ahd_patch0_func, 66, 1, 1 }, + { ahd_patch2_func, 69, 1, 2 }, + { ahd_patch0_func, 70, 1, 1 }, + { ahd_patch1_func, 73, 1, 2 }, + { ahd_patch0_func, 74, 1, 1 }, + { ahd_patch4_func, 107, 1, 1 }, + { ahd_patch2_func, 162, 6, 1 }, + { ahd_patch1_func, 168, 2, 1 }, + { ahd_patch5_func, 170, 1, 1 }, + { ahd_patch2_func, 179, 1, 2 }, + { ahd_patch0_func, 180, 1, 1 }, + { ahd_patch6_func, 181, 2, 2 }, + { ahd_patch0_func, 183, 6, 3 }, + { ahd_patch2_func, 186, 1, 2 }, + { ahd_patch0_func, 187, 1, 1 }, + { ahd_patch2_func, 190, 1, 2 }, + { ahd_patch0_func, 191, 1, 1 }, + { ahd_patch7_func, 193, 2, 1 }, + { ahd_patch5_func, 201, 16, 2 }, + { ahd_patch0_func, 217, 1, 1 }, + { ahd_patch8_func, 237, 2, 1 }, + { ahd_patch1_func, 241, 1, 2 }, + { ahd_patch0_func, 242, 1, 1 }, + { ahd_patch7_func, 245, 2, 1 }, + { ahd_patch1_func, 259, 1, 2 }, + { ahd_patch0_func, 260, 1, 1 }, + { ahd_patch1_func, 263, 1, 2 }, + { ahd_patch0_func, 264, 1, 1 }, + { ahd_patch2_func, 267, 1, 2 }, + { ahd_patch0_func, 268, 1, 1 }, + { ahd_patch1_func, 323, 1, 2 }, + { ahd_patch0_func, 324, 1, 1 }, + { ahd_patch2_func, 332, 1, 2 }, + { ahd_patch0_func, 333, 1, 1 }, + { ahd_patch2_func, 336, 1, 2 }, + { ahd_patch0_func, 337, 1, 1 }, + { ahd_patch1_func, 343, 1, 2 }, + { ahd_patch0_func, 344, 1, 1 }, + { ahd_patch1_func, 346, 1, 2 }, + { ahd_patch0_func, 347, 1, 1 }, + { ahd_patch9_func, 366, 1, 1 }, + { ahd_patch9_func, 369, 1, 1 }, + { ahd_patch9_func, 371, 1, 1 }, + { ahd_patch9_func, 383, 1, 1 }, + { ahd_patch1_func, 393, 1, 2 }, + { ahd_patch0_func, 394, 1, 1 }, + { ahd_patch1_func, 396, 1, 2 }, + { ahd_patch0_func, 397, 1, 1 }, + { ahd_patch1_func, 405, 1, 2 }, + { ahd_patch0_func, 406, 1, 1 }, + { ahd_patch2_func, 419, 1, 2 }, + { ahd_patch0_func, 420, 1, 1 }, + { ahd_patch10_func, 450, 1, 1 }, + { ahd_patch1_func, 457, 1, 2 }, + { ahd_patch0_func, 458, 1, 1 }, + { ahd_patch2_func, 470, 1, 2 }, + { ahd_patch0_func, 471, 1, 1 }, + { ahd_patch11_func, 476, 6, 2 }, + { ahd_patch0_func, 482, 1, 1 }, + { ahd_patch12_func, 505, 1, 1 }, + { ahd_patch13_func, 514, 1, 1 }, + { ahd_patch14_func, 515, 1, 2 }, + { ahd_patch0_func, 516, 1, 1 }, + { ahd_patch15_func, 519, 1, 1 }, + { ahd_patch14_func, 520, 1, 1 }, + { ahd_patch16_func, 531, 1, 2 }, + { ahd_patch0_func, 532, 1, 1 }, + { ahd_patch1_func, 551, 1, 2 }, + { ahd_patch0_func, 552, 1, 1 }, + { ahd_patch1_func, 555, 1, 2 }, + { ahd_patch0_func, 556, 1, 1 }, + { ahd_patch2_func, 561, 1, 2 }, + { ahd_patch0_func, 562, 1, 1 }, + { ahd_patch2_func, 566, 1, 2 }, + { ahd_patch0_func, 567, 1, 1 }, + { ahd_patch1_func, 568, 1, 2 }, + { ahd_patch0_func, 569, 1, 1 }, + { ahd_patch2_func, 580, 1, 2 }, + { ahd_patch0_func, 581, 1, 1 }, + { ahd_patch17_func, 585, 1, 1 }, + { ahd_patch18_func, 590, 1, 1 }, + { ahd_patch19_func, 591, 2, 1 }, + { ahd_patch18_func, 595, 1, 2 }, + { ahd_patch0_func, 596, 1, 1 }, + { ahd_patch2_func, 599, 1, 2 }, + { ahd_patch0_func, 600, 1, 1 }, + { ahd_patch2_func, 615, 1, 2 }, + { ahd_patch0_func, 616, 1, 1 }, + { ahd_patch20_func, 617, 14, 1 }, + { ahd_patch1_func, 635, 1, 2 }, + { ahd_patch0_func, 636, 1, 1 }, + { ahd_patch20_func, 637, 1, 1 }, + { ahd_patch1_func, 649, 1, 2 }, + { ahd_patch0_func, 650, 1, 1 }, + { ahd_patch1_func, 657, 1, 2 }, + { ahd_patch0_func, 658, 1, 1 }, + { ahd_patch17_func, 681, 1, 1 }, + { ahd_patch17_func, 719, 1, 1 }, + { ahd_patch1_func, 730, 1, 2 }, + { ahd_patch0_func, 731, 1, 1 }, + { ahd_patch1_func, 748, 1, 2 }, + { ahd_patch0_func, 749, 1, 1 }, + { ahd_patch1_func, 751, 1, 2 }, + { ahd_patch0_func, 752, 1, 1 }, + { ahd_patch1_func, 755, 1, 2 }, + { ahd_patch0_func, 756, 1, 1 }, + { ahd_patch21_func, 758, 1, 2 }, + { ahd_patch0_func, 759, 2, 1 }, + { ahd_patch22_func, 762, 4, 2 }, + { ahd_patch0_func, 766, 1, 1 }, + { ahd_patch22_func, 774, 11, 1 } +}; + +static struct cs { + uint16_t begin; + uint16_t end; +} critical_sections[] = { + { 11, 12 }, + { 13, 14 }, + { 29, 42 }, + { 56, 59 }, + { 101, 128 }, + { 129, 157 }, + { 159, 162 }, + { 170, 178 }, + { 201, 250 }, + { 681, 697 }, + { 697, 711 }, + { 721, 725 } +}; + +static const int num_critical_sections = sizeof(critical_sections) + / sizeof(*critical_sections); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx.h linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx.h 2003-08-25 04:44:42.000000000 -0700 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#45 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#79 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.16.2.13 2002/04/29 19:36:29 gibbs Exp $ + * $FreeBSD$ */ #ifndef _AIC7XXX_H_ @@ -93,11 +93,19 @@ #define SCB_GET_CHANNEL(ahc, scb) \ SCSIID_CHANNEL(ahc, (scb)->hscb->scsiid) #define SCB_GET_LUN(scb) \ - ((scb)->hscb->lun) + ((scb)->hscb->lun & LID) #define SCB_GET_TARGET_OFFSET(ahc, scb) \ (SCB_GET_TARGET(ahc, scb) + (SCB_IS_SCSIBUS_B(ahc, scb) ? 8 : 0)) #define SCB_GET_TARGET_MASK(ahc, scb) \ (0x01 << (SCB_GET_TARGET_OFFSET(ahc, scb))) +#ifdef AHC_DEBUG +#define SCB_IS_SILENT(scb) \ + ((ahc_debug & AHC_SHOW_MASKED_ERRORS) == 0 \ + && (((scb)->flags & SCB_SILENT) != 0)) +#else +#define SCB_IS_SILENT(scb) \ + (((scb)->flags & SCB_SILENT) != 0) +#endif #define TCL_TARGET_OFFSET(tcl) \ ((((tcl) >> 4) & TID) >> 4) #define TCL_LUN(tcl) \ @@ -171,7 +179,7 @@ #define AHC_TMODE_CMDS 256 /* Reset line assertion time in us */ -#define AHC_BUSRESET_DELAY 250 +#define AHC_BUSRESET_DELAY 25 /******************* Chip Characteristics/Operating Settings *****************/ /* @@ -310,11 +318,11 @@ */ typedef enum { AHC_FNONE = 0x000, - AHC_PRIMARY_CHANNEL = 0x003,/* + AHC_PRIMARY_CHANNEL = 0x003, /* * The channel that should * be probed first. */ - AHC_USEDEFAULTS = 0x004,/* + AHC_USEDEFAULTS = 0x004, /* * For cards without an seeprom * or a BIOS to initialize the chip's * SRAM, we use the default target @@ -322,29 +330,29 @@ */ AHC_SEQUENCER_DEBUG = 0x008, AHC_SHARED_SRAM = 0x010, - AHC_LARGE_SEEPROM = 0x020,/* Uses C56_66 not C46 */ + AHC_LARGE_SEEPROM = 0x020, /* Uses C56_66 not C46 */ AHC_RESET_BUS_A = 0x040, AHC_RESET_BUS_B = 0x080, AHC_EXTENDED_TRANS_A = 0x100, AHC_EXTENDED_TRANS_B = 0x200, AHC_TERM_ENB_A = 0x400, AHC_TERM_ENB_B = 0x800, - AHC_INITIATORROLE = 0x1000,/* + AHC_INITIATORROLE = 0x1000, /* * Allow initiator operations on * this controller. */ - AHC_TARGETROLE = 0x2000,/* + AHC_TARGETROLE = 0x2000, /* * Allow target operations on this * controller. */ AHC_NEWEEPROM_FMT = 0x4000, AHC_RESOURCE_SHORTAGE = 0x8000, - AHC_TQINFIFO_BLOCKED = 0x10000,/* Blocked waiting for ATIOs */ - AHC_INT50_SPEEDFLEX = 0x20000,/* + AHC_TQINFIFO_BLOCKED = 0x10000, /* Blocked waiting for ATIOs */ + AHC_INT50_SPEEDFLEX = 0x20000, /* * Internal 50pin connector * sits behind an aic3860 */ - AHC_SCB_BTT = 0x40000,/* + AHC_SCB_BTT = 0x40000, /* * The busy targets table is * stored in SCB space rather * than SRAM. @@ -355,14 +363,17 @@ AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */ AHC_39BIT_ADDRESSING = 0x1000000, /* Use 39 bit addressing scheme. */ AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */ - AHC_SCB_CONFIG_USED = 0x4000000 /* No SEEPROM but SCB2 had info. */ + AHC_SCB_CONFIG_USED = 0x4000000, /* No SEEPROM but SCB2 had info. */ + AHC_NO_BIOS_INIT = 0x8000000, /* No BIOS left over settings. */ + AHC_DISABLE_PCI_PERR = 0x10000000, + AHC_HAS_TERM_LOGIC = 0x20000000 } ahc_flag; /************************* Hardware SCB Definition ***************************/ /* * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB - * consists of a "hardware SCB" mirroring the fields availible on the card + * consists of a "hardware SCB" mirroring the fields available on the card * and additional information the kernel stores for each transaction. * * To minimize space utilization, a portion of the hardware scb stores @@ -534,10 +545,27 @@ SCB_RECOVERY_SCB = 0x0020, SCB_AUTO_NEGOTIATE = 0x0040,/* Negotiate to achieve goal. */ SCB_NEGOTIATE = 0x0080,/* Negotiation forced for command. */ - SCB_ABORT = 0x1000, - SCB_UNTAGGEDQ = 0x2000, - SCB_ACTIVE = 0x4000, - SCB_TARGET_IMMEDIATE = 0x8000 + SCB_ABORT = 0x0100, + SCB_UNTAGGEDQ = 0x0200, + SCB_ACTIVE = 0x0400, + SCB_TARGET_IMMEDIATE = 0x0800, + SCB_TRANSMISSION_ERROR = 0x1000,/* + * We detected a parity or CRC + * error that has effected the + * payload of the command. This + * flag is checked when normal + * status is returned to catch + * the case of a target not + * responding to our attempt + * to report the error. + */ + SCB_TARGET_SCB = 0x2000, + SCB_SILENT = 0x4000 /* + * Be quiet about transmission type + * errors. They are expected and we + * don't want to upset the user. This + * flag is typically used during DV. + */ } scb_flag; struct scb { @@ -662,6 +690,11 @@ #define AHC_TRANS_GOAL 0x04 /* Modify negotiation goal */ #define AHC_TRANS_USER 0x08 /* Modify user negotiation settings */ +#define AHC_WIDTH_UNKNOWN 0xFF +#define AHC_PERIOD_UNKNOWN 0xFF +#define AHC_OFFSET_UNKNOWN 0xFF +#define AHC_PPR_OPTS_UNKNOWN 0xFF + /* * Transfer Negotiation Information. */ @@ -716,10 +749,9 @@ char *rate; }; -/* - * The synchronouse transfer rate table. - */ -extern struct ahc_syncrate ahc_syncrates[]; +/* Safe and valid period for async negotiations. */ +#define AHC_ASYNC_XFER_PERIOD 0x45 +#define AHC_ULTRA2_XFER_PERIOD 0x0a /* * Indexes into our table of syncronous transfer rates. @@ -728,6 +760,8 @@ #define AHC_SYNCRATE_ULTRA2 1 #define AHC_SYNCRATE_ULTRA 3 #define AHC_SYNCRATE_FAST 6 +#define AHC_SYNCRATE_MAX AHC_SYNCRATE_DT +#define AHC_SYNCRATE_MIN 13 /***************************** Lookup Tables **********************************/ /* @@ -802,7 +836,7 @@ #define CFSEAUTOTERM 0x0400 /* Ultra2 Perform secondary Auto Term*/ #define CFSELOWTERM 0x0800 /* Ultra2 secondary low term */ #define CFSEHIGHTERM 0x1000 /* Ultra2 secondary high term */ -#define CFDOMAINVAL 0x4000 /* Perform Domain Validation*/ +#define CFENABLEDV 0x4000 /* Perform Domain Validation*/ /* * Bus Release Time, Host Adapter ID @@ -844,31 +878,40 @@ /*********************** Software Configuration Structure *********************/ TAILQ_HEAD(scb_tailq, scb); -struct ahc_suspend_channel_state { - uint8_t scsiseq; - uint8_t sxfrctl0; - uint8_t sxfrctl1; - uint8_t simode0; - uint8_t simode1; - uint8_t seltimer; - uint8_t seqctl; -}; - -struct ahc_suspend_state { - struct ahc_suspend_channel_state channel[2]; - uint8_t optionmode; - uint8_t dscommand0; - uint8_t dspcistatus; - /* hsmailbox */ - uint8_t crccontrol1; - uint8_t scbbaddr; - /* Host and sequencer SCB counts */ - uint8_t dff_thrsh; - uint8_t *scratch_ram; - uint8_t *btt; +struct ahc_aic7770_softc { + /* + * Saved register state used for chip_init(). + */ + uint8_t busspd; + uint8_t bustime; +}; + +struct ahc_pci_softc { + /* + * Saved register state used for chip_init(). + */ + uint32_t devconfig; + uint16_t targcrccnt; + uint8_t command; + uint8_t csize_lattime; + uint8_t optionmode; + uint8_t crccontrol1; + uint8_t dscommand0; + uint8_t dspcistatus; + uint8_t scbbaddr; + uint8_t dff_thrsh; +}; + +union ahc_bus_softc { + struct ahc_aic7770_softc aic7770_softc; + struct ahc_pci_softc pci_softc; }; typedef void (*ahc_bus_intr_t)(struct ahc_softc *); +typedef int (*ahc_bus_chip_init_t)(struct ahc_softc *); +typedef int (*ahc_bus_suspend_t)(struct ahc_softc *); +typedef int (*ahc_bus_resume_t)(struct ahc_softc *); +typedef void ahc_callback_t (void *); struct ahc_softc { bus_space_tag_t tag; @@ -903,6 +946,11 @@ struct scb_tailq untagged_queues[AHC_NUM_TARGETS]; /* + * Bus attachment specific data. + */ + union ahc_bus_softc bus_softc; + + /* * Platform specific data. */ struct ahc_platform_data *platform_data; @@ -918,6 +966,22 @@ ahc_bus_intr_t bus_intr; /* + * Bus specific initialization required + * after a chip reset. + */ + ahc_bus_chip_init_t bus_chip_init; + + /* + * Bus specific suspend routine. + */ + ahc_bus_suspend_t bus_suspend; + + /* + * Bus specific resume routine. + */ + ahc_bus_resume_t bus_resume; + + /* * Target mode related state kept on a per enabled lun basis. * Targets that are not enabled will have null entries. * As an initiator, we keep one target entry for our initiator @@ -983,6 +1047,11 @@ uint8_t tqinfifonext; /* + * Cached copy of the sequencer control register. + */ + uint8_t seqctl; + + /* * Incoming and outgoing message handling. */ uint8_t send_msg_perror; @@ -1009,9 +1078,6 @@ */ bus_addr_t dma_bug_buf; - /* Information saved through suspend/resume cycles */ - struct ahc_suspend_state suspend_state; - /* Number of enabled target mode device on this card */ u_int enabled_luns; @@ -1021,6 +1087,17 @@ /* PCI cacheline size. */ u_int pci_cachesize; + /* + * Count of parity errors we have seen as a target. + * We auto-disable parity error checking after seeing + * AHC_PCI_TARGET_PERR_THRESH number of errors. + */ + u_int pci_target_perr_count; +#define AHC_PCI_TARGET_PERR_THRESH 10 + + /* Maximum number of sequencer instructions supported. */ + u_int instruction_ram_size; + /* Per-Unit descriptive information */ const char *description; char *name; @@ -1066,17 +1143,17 @@ char *name; ahc_device_setup_t *setup; }; -extern struct ahc_pci_identity ahc_pci_ident_table []; +extern struct ahc_pci_identity ahc_pci_ident_table[]; extern const u_int ahc_num_pci_devs; /***************************** VL/EISA Declarations ***************************/ struct aic7770_identity { uint32_t full_id; uint32_t id_mask; - char *name; + const char *name; ahc_device_setup_t *setup; }; -extern struct aic7770_identity aic7770_ident_table []; +extern struct aic7770_identity aic7770_ident_table[]; extern const int ahc_num_aic7770_devs; #define AHC_EISA_SLOT_OFFSET 0xc00 @@ -1093,6 +1170,7 @@ struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t); int ahc_pci_config(struct ahc_softc *, struct ahc_pci_identity *); +int ahc_pci_test_register_access(struct ahc_softc *); /*************************** EISA/VL Front End ********************************/ struct aic7770_identity *aic7770_find_device(uint32_t); @@ -1115,6 +1193,7 @@ struct ahc_softc *ahc_alloc(void *platform_arg, char *name); int ahc_softc_init(struct ahc_softc *); void ahc_controller_info(struct ahc_softc *ahc, char *buf); +int ahc_chip_init(struct ahc_softc *ahc); int ahc_init(struct ahc_softc *ahc); void ahc_intr_enable(struct ahc_softc *ahc, int enable); void ahc_pause_and_flushwork(struct ahc_softc *ahc); @@ -1126,11 +1205,10 @@ void ahc_set_name(struct ahc_softc *, char *); void ahc_alloc_scbs(struct ahc_softc *ahc); void ahc_free(struct ahc_softc *ahc); -int ahc_reset(struct ahc_softc *ahc); +int ahc_reset(struct ahc_softc *ahc, int reinit); void ahc_shutdown(void *arg); /*************************** Interrupt Services *******************************/ -void ahc_pci_intr(struct ahc_softc *ahc); void ahc_clear_intstat(struct ahc_softc *ahc); void ahc_run_qoutfifo(struct ahc_softc *ahc); #ifdef AHC_TARGET_MODE @@ -1191,11 +1269,20 @@ struct ahc_initiator_tinfo *tinfo, u_int *bus_width, role_t role); +/* + * Negotiation types. These are used to qualify if we should renegotiate + * even if our goal and current transport parameters are identical. + */ +typedef enum { + AHC_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */ + AHC_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */ + AHC_NEG_ALWAYS /* Renegotiat even if goal is async. */ +} ahc_neg_type; int ahc_update_neg_request(struct ahc_softc*, struct ahc_devinfo*, struct ahc_tmode_tstate*, struct ahc_initiator_tinfo*, - int /*force*/); + ahc_neg_type); void ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, u_int width, u_int type, int paused); @@ -1232,12 +1319,32 @@ #endif /******************************* Debug ***************************************/ #ifdef AHC_DEBUG -extern int ahc_debug; -#define AHC_SHOWMISC 0x1 -#define AHC_SHOWSENSE 0x2 +extern uint32_t ahc_debug; +#define AHC_SHOW_MISC 0x0001 +#define AHC_SHOW_SENSE 0x0002 +#define AHC_DUMP_SEEPROM 0x0004 +#define AHC_SHOW_TERMCTL 0x0008 +#define AHC_SHOW_MEMORY 0x0010 +#define AHC_SHOW_MESSAGES 0x0020 +#define AHC_SHOW_DV 0x0040 +#define AHC_SHOW_SELTO 0x0080 +#define AHC_SHOW_QFULL 0x0200 +#define AHC_SHOW_QUEUE 0x0400 +#define AHC_SHOW_TQIN 0x0800 +#define AHC_SHOW_MASKED_ERRORS 0x1000 +#define AHC_DEBUG_SEQUENCER 0x2000 #endif void ahc_print_scb(struct scb *scb); +void ahc_print_devinfo(struct ahc_softc *ahc, + struct ahc_devinfo *dev); void ahc_dump_card_state(struct ahc_softc *ahc); +int ahc_print_register(ahc_reg_parse_entry_t *table, + u_int num_entries, + const char *name, + u_int address, + u_int value, + u_int *cur_column, + u_int wrap_point); /******************************* SEEPROM *************************************/ int ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx.reg linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx.reg --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx.reg 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx.reg 2003-08-25 04:44:42.000000000 -0700 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.reg,v 1.20.2.11 2002/04/29 19:36:30 gibbs Exp $ + * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $" /* * This file is processed by the aic7xxx_asm utility for use in assembling @@ -57,14 +57,14 @@ register SCSISEQ { address 0x000 access_mode RW - bit TEMODE 0x80 - bit ENSELO 0x40 - bit ENSELI 0x20 - bit ENRSELI 0x10 - bit ENAUTOATNO 0x08 - bit ENAUTOATNI 0x04 - bit ENAUTOATNP 0x02 - bit SCSIRSTO 0x01 + field TEMODE 0x80 + field ENSELO 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field ENAUTOATNO 0x08 + field ENAUTOATNI 0x04 + field ENAUTOATNP 0x02 + field SCSIRSTO 0x01 } /* @@ -74,13 +74,13 @@ register SXFRCTL0 { address 0x001 access_mode RW - bit DFON 0x80 - bit DFPEXP 0x40 - bit FAST20 0x20 - bit CLRSTCNT 0x10 - bit SPIOEN 0x08 - bit SCAMEN 0x04 - bit CLRCHN 0x02 + field DFON 0x80 + field DFPEXP 0x40 + field FAST20 0x20 + field CLRSTCNT 0x10 + field SPIOEN 0x08 + field SCAMEN 0x04 + field CLRCHN 0x02 } /* @@ -90,13 +90,13 @@ register SXFRCTL1 { address 0x002 access_mode RW - bit BITBUCKET 0x80 - bit SWRAPEN 0x40 - bit ENSPCHK 0x20 + field BITBUCKET 0x80 + field SWRAPEN 0x40 + field ENSPCHK 0x20 mask STIMESEL 0x18 - bit ENSTIMER 0x04 - bit ACTNEGEN 0x02 - bit STPWEN 0x01 /* Powered Termination */ + field ENSTIMER 0x04 + field ACTNEGEN 0x02 + field STPWEN 0x01 /* Powered Termination */ } /* @@ -106,14 +106,14 @@ register SCSISIGI { address 0x003 access_mode RO - bit CDI 0x80 - bit IOI 0x40 - bit MSGI 0x20 - bit ATNI 0x10 - bit SELI 0x08 - bit BSYI 0x04 - bit REQI 0x02 - bit ACKI 0x01 + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 + field ATNI 0x10 + field SELI 0x08 + field BSYI 0x04 + field REQI 0x02 + field ACKI 0x01 /* * Possible phases in SCSISIGI */ @@ -137,14 +137,14 @@ register SCSISIGO { address 0x003 access_mode WO - bit CDO 0x80 - bit IOO 0x40 - bit MSGO 0x20 - bit ATNO 0x10 - bit SELO 0x08 - bit BSYO 0x04 - bit REQO 0x02 - bit ACKO 0x01 + field CDO 0x80 + field IOO 0x40 + field MSGO 0x20 + field ATNO 0x10 + field SELO 0x08 + field BSYO 0x04 + field REQO 0x02 + field ACKO 0x01 /* * Possible phases to write into SCSISIG0 */ @@ -167,9 +167,9 @@ register SCSIRATE { address 0x004 access_mode RW - bit WIDEXFER 0x80 /* Wide transfer control */ - bit ENABLE_CRC 0x40 /* CRC for D-Phases */ - bit SINGLE_EDGE 0x10 /* Disable DT Transfers */ + field WIDEXFER 0x80 /* Wide transfer control */ + field ENABLE_CRC 0x40 /* CRC for D-Phases */ + field SINGLE_EDGE 0x10 /* Disable DT Transfers */ mask SXFR 0x70 /* Sync transfer rate */ mask SXFR_ULTRA2 0x0f /* Sync transfer rate */ mask SOFS 0x0f /* Sync offset */ @@ -185,7 +185,7 @@ access_mode RW mask TID 0xf0 /* Target ID mask */ mask TWIN_TID 0x70 - bit TWIN_CHNLB 0x80 + field TWIN_CHNLB 0x80 mask OID 0x0f /* Our ID mask */ /* * SCSI Maximum Offset (p. 4-61 aic7890/91 Data Book) @@ -225,18 +225,27 @@ access_mode RW } +/* ALT_MODE registers (Ultra2 and Ultra160 chips) */ +register SXFRCTL2 { + address 0x013 + access_mode RW + field AUTORSTDIS 0x10 + field CMDDMAEN 0x08 + mask ASYNC_SETUP 0x07 +} + /* ALT_MODE register on Ultra160 chips */ register OPTIONMODE { address 0x008 access_mode RW - bit AUTORATEEN 0x80 - bit AUTOACKEN 0x40 - bit ATNMGMNTEN 0x20 - bit BUSFREEREV 0x10 - bit EXPPHASEDIS 0x08 - bit SCSIDATL_IMGEN 0x04 - bit AUTO_MSGOUT_DE 0x02 - bit DIS_MSGIN_DUALEDGE 0x01 + field AUTORATEEN 0x80 + field AUTOACKEN 0x40 + field ATNMGMNTEN 0x20 + field BUSFREEREV 0x10 + field EXPPHASEDIS 0x08 + field SCSIDATL_IMGEN 0x04 + field AUTO_MSGOUT_DE 0x02 + field DIS_MSGIN_DUALEDGE 0x01 mask OPTIONMODE_DEFAULTS AUTO_MSGOUT_DE|DIS_MSGIN_DUALEDGE } @@ -254,12 +263,12 @@ register CLRSINT0 { address 0x00b access_mode WO - bit CLRSELDO 0x40 - bit CLRSELDI 0x20 - bit CLRSELINGO 0x10 - bit CLRSWRAP 0x08 - bit CLRIOERR 0x08 /* Ultra2 Only */ - bit CLRSPIORDY 0x02 + field CLRSELDO 0x40 + field CLRSELDI 0x20 + field CLRSELINGO 0x10 + field CLRSWRAP 0x08 + field CLRIOERR 0x08 /* Ultra2 Only */ + field CLRSPIORDY 0x02 } /* @@ -270,15 +279,15 @@ register SSTAT0 { address 0x00b access_mode RO - bit TARGET 0x80 /* Board acting as target */ - bit SELDO 0x40 /* Selection Done */ - bit SELDI 0x20 /* Board has been selected */ - bit SELINGO 0x10 /* Selection In Progress */ - bit SWRAP 0x08 /* 24bit counter wrap */ - bit IOERR 0x08 /* LVD Tranceiver mode changed */ - bit SDONE 0x04 /* STCNT = 0x000000 */ - bit SPIORDY 0x02 /* SCSI PIO Ready */ - bit DMADONE 0x01 /* DMA transfer completed */ + field TARGET 0x80 /* Board acting as target */ + field SELDO 0x40 /* Selection Done */ + field SELDI 0x20 /* Board has been selected */ + field SELINGO 0x10 /* Selection In Progress */ + field SWRAP 0x08 /* 24bit counter wrap */ + field IOERR 0x08 /* LVD Tranceiver mode changed */ + field SDONE 0x04 /* STCNT = 0x000000 */ + field SPIORDY 0x02 /* SCSI PIO Ready */ + field DMADONE 0x01 /* DMA transfer completed */ } /* @@ -288,13 +297,13 @@ register CLRSINT1 { address 0x00c access_mode WO - bit CLRSELTIMEO 0x80 - bit CLRATNO 0x40 - bit CLRSCSIRSTI 0x20 - bit CLRBUSFREE 0x08 - bit CLRSCSIPERR 0x04 - bit CLRPHASECHG 0x02 - bit CLRREQINIT 0x01 + field CLRSELTIMEO 0x80 + field CLRATNO 0x40 + field CLRSCSIRSTI 0x20 + field CLRBUSFREE 0x08 + field CLRSCSIPERR 0x04 + field CLRPHASECHG 0x02 + field CLRREQINIT 0x01 } /* @@ -303,14 +312,14 @@ register SSTAT1 { address 0x00c access_mode RO - bit SELTO 0x80 - bit ATNTARG 0x40 - bit SCSIRSTI 0x20 - bit PHASEMIS 0x10 - bit BUSFREE 0x08 - bit SCSIPERR 0x04 - bit PHASECHG 0x02 - bit REQINIT 0x01 + field SELTO 0x80 + field ATNTARG 0x40 + field SCSIRSTI 0x20 + field PHASEMIS 0x10 + field BUSFREE 0x08 + field SCSIPERR 0x04 + field PHASECHG 0x02 + field REQINIT 0x01 } /* @@ -319,13 +328,13 @@ register SSTAT2 { address 0x00d access_mode RO - bit OVERRUN 0x80 - bit SHVALID 0x40 /* Shaddow Layer non-zero */ - bit EXP_ACTIVE 0x10 /* SCSI Expander Active */ - bit CRCVALERR 0x08 /* CRC doesn't match (U3 only) */ - bit CRCENDERR 0x04 /* No terminal CRC packet (U3 only) */ - bit CRCREQERR 0x02 /* Illegal CRC packet req (U3 only) */ - bit DUAL_EDGE_ERR 0x01 /* Incorrect data phase (U3 only) */ + field OVERRUN 0x80 + field SHVALID 0x40 /* Shaddow Layer non-zero */ + field EXP_ACTIVE 0x10 /* SCSI Expander Active */ + field CRCVALERR 0x08 /* CRC doesn't match (U3 only) */ + field CRCENDERR 0x04 /* No terminal CRC packet (U3 only) */ + field CRCREQERR 0x02 /* Illegal CRC packet req (U3 only) */ + field DUAL_EDGE_ERR 0x01 /* Incorrect data phase (U3 only) */ mask SFCNT 0x1f } @@ -358,14 +367,14 @@ register SIMODE0 { address 0x010 access_mode RW - bit ENSELDO 0x40 - bit ENSELDI 0x20 - bit ENSELINGO 0x10 - bit ENSWRAP 0x08 - bit ENIOERR 0x08 /* LVD Tranceiver mode changes */ - bit ENSDONE 0x04 - bit ENSPIORDY 0x02 - bit ENDMADONE 0x01 + field ENSELDO 0x40 + field ENSELDI 0x20 + field ENSELINGO 0x10 + field ENSWRAP 0x08 + field ENIOERR 0x08 /* LVD Tranceiver mode changes */ + field ENSDONE 0x04 + field ENSPIORDY 0x02 + field ENDMADONE 0x01 } /* @@ -376,14 +385,14 @@ register SIMODE1 { address 0x011 access_mode RW - bit ENSELTIMO 0x80 - bit ENATNTARG 0x40 - bit ENSCSIRST 0x20 - bit ENPHASEMIS 0x10 - bit ENBUSFREE 0x08 - bit ENSCSIPERR 0x04 - bit ENPHASECHG 0x02 - bit ENREQINIT 0x01 + field ENSELTIMO 0x80 + field ENATNTARG 0x40 + field ENSCSIRST 0x20 + field ENPHASEMIS 0x10 + field ENBUSFREE 0x08 + field ENSCSIPERR 0x04 + field ENPHASECHG 0x02 + field ENREQINIT 0x01 } /* @@ -420,12 +429,12 @@ register SELTIMER { address 0x018 access_mode RW - bit STAGE6 0x20 - bit STAGE5 0x10 - bit STAGE4 0x08 - bit STAGE3 0x04 - bit STAGE2 0x02 - bit STAGE1 0x01 + field STAGE6 0x20 + field STAGE5 0x10 + field STAGE4 0x08 + field STAGE3 0x04 + field STAGE2 0x02 + field STAGE1 0x01 alias TARGIDIN } @@ -438,16 +447,16 @@ address 0x019 access_mode RW mask SELID_MASK 0xf0 - bit ONEBIT 0x08 + field ONEBIT 0x08 } register SCAMCTL { address 0x01a access_mode RW - bit ENSCAMSELO 0x80 - bit CLRSCAMSELID 0x40 - bit ALTSTIM 0x20 - bit DFLTTID 0x10 + field ENSCAMSELO 0x80 + field CLRSCAMSELID 0x40 + field ALTSTIM 0x20 + field DFLTTID 0x10 mask SCAMLVL 0x03 } @@ -471,32 +480,32 @@ register SPIOCAP { address 0x01b access_mode RW - bit SOFT1 0x80 - bit SOFT0 0x40 - bit SOFTCMDEN 0x20 - bit EXT_BRDCTL 0x10 /* External Board control */ - bit SEEPROM 0x08 /* External serial eeprom logic */ - bit EEPROM 0x04 /* Writable external BIOS ROM */ - bit ROM 0x02 /* Logic for accessing external ROM */ - bit SSPIOCPS 0x01 /* Termination and cable detection */ + field SOFT1 0x80 + field SOFT0 0x40 + field SOFTCMDEN 0x20 + field EXT_BRDCTL 0x10 /* External Board control */ + field SEEPROM 0x08 /* External serial eeprom logic */ + field EEPROM 0x04 /* Writable external BIOS ROM */ + field ROM 0x02 /* Logic for accessing external ROM */ + field SSPIOCPS 0x01 /* Termination and cable detection */ } register BRDCTL { address 0x01d - bit BRDDAT7 0x80 - bit BRDDAT6 0x40 - bit BRDDAT5 0x20 - bit BRDSTB 0x10 - bit BRDCS 0x08 - bit BRDRW 0x04 - bit BRDCTL1 0x02 - bit BRDCTL0 0x01 + field BRDDAT7 0x80 + field BRDDAT6 0x40 + field BRDDAT5 0x20 + field BRDSTB 0x10 + field BRDCS 0x08 + field BRDRW 0x04 + field BRDCTL1 0x02 + field BRDCTL0 0x01 /* 7890 Definitions */ - bit BRDDAT4 0x10 - bit BRDDAT3 0x08 - bit BRDDAT2 0x04 - bit BRDRW_ULTRA2 0x02 - bit BRDSTB_ULTRA2 0x01 + field BRDDAT4 0x10 + field BRDDAT3 0x08 + field BRDDAT2 0x04 + field BRDRW_ULTRA2 0x02 + field BRDSTB_ULTRA2 0x01 } /* @@ -525,14 +534,14 @@ */ register SEECTL { address 0x01e - bit EXTARBACK 0x80 - bit EXTARBREQ 0x40 - bit SEEMS 0x20 - bit SEERDY 0x10 - bit SEECS 0x08 - bit SEECK 0x04 - bit SEEDO 0x02 - bit SEEDI 0x01 + field EXTARBACK 0x80 + field EXTARBREQ 0x40 + field SEEMS 0x20 + field SEERDY 0x10 + field SEECS 0x08 + field SEECK 0x04 + field SEEDO 0x02 + field SEEDI 0x01 } /* * SCSI Block Control (p. 3-32) @@ -544,14 +553,14 @@ register SBLKCTL { address 0x01f access_mode RW - bit DIAGLEDEN 0x80 /* Aic78X0 only */ - bit DIAGLEDON 0x40 /* Aic78X0 only */ - bit AUTOFLUSHDIS 0x20 - bit SELBUSB 0x08 - bit ENAB40 0x08 /* LVD transceiver active */ - bit ENAB20 0x04 /* SE/HVD transceiver active */ - bit SELWIDE 0x02 - bit XCVR 0x01 /* External transceiver active */ + field DIAGLEDEN 0x80 /* Aic78X0 only */ + field DIAGLEDON 0x40 /* Aic78X0 only */ + field AUTOFLUSHDIS 0x20 + field SELBUSB 0x08 + field ENAB40 0x08 /* LVD transceiver active */ + field ENAB20 0x04 /* SE/HVD transceiver active */ + field SELWIDE 0x02 + field XCVR 0x01 /* External transceiver active */ } /* @@ -561,14 +570,14 @@ register SEQCTL { address 0x060 access_mode RW - bit PERRORDIS 0x80 - bit PAUSEDIS 0x40 - bit FAILDIS 0x20 - bit FASTMODE 0x10 - bit BRKADRINTEN 0x08 - bit STEP 0x04 - bit SEQRESET 0x02 - bit LOADRAM 0x01 + field PERRORDIS 0x80 + field PAUSEDIS 0x40 + field FAILDIS 0x20 + field FASTMODE 0x10 + field BRKADRINTEN 0x08 + field STEP 0x04 + field SEQRESET 0x02 + field LOADRAM 0x01 } /* @@ -640,8 +649,8 @@ register FLAGS { address 0x06b access_mode RO - bit ZERO 0x02 - bit CARRY 0x01 + field ZERO 0x02 + field CARRY 0x01 } register SINDIR { @@ -664,14 +673,16 @@ access_mode RO } +const STACK_SIZE 4 + /* * Board Control (p. 3-43) */ register BCTL { address 0x084 access_mode RW - bit ACE 0x08 - bit ENABLE 0x01 + field ACE 0x08 + field ENABLE 0x01 } /* @@ -681,23 +692,23 @@ register DSCOMMAND0 { address 0x084 access_mode RW - bit CACHETHEN 0x80 /* Cache Threshold enable */ - bit DPARCKEN 0x40 /* Data Parity Check Enable */ - bit MPARCKEN 0x20 /* Memory Parity Check Enable */ - bit EXTREQLCK 0x10 /* External Request Lock */ + field CACHETHEN 0x80 /* Cache Threshold enable */ + field DPARCKEN 0x40 /* Data Parity Check Enable */ + field MPARCKEN 0x20 /* Memory Parity Check Enable */ + field EXTREQLCK 0x10 /* External Request Lock */ /* aic7890/91/96/97 only */ - bit INTSCBRAMSEL 0x08 /* Internal SCB RAM Select */ - bit RAMPS 0x04 /* External SCB RAM Present */ - bit USCBSIZE32 0x02 /* Use 32byte SCB Page Size */ - bit CIOPARCKEN 0x01 /* Internal bus parity error enable */ + field INTSCBRAMSEL 0x08 /* Internal SCB RAM Select */ + field RAMPS 0x04 /* External SCB RAM Present */ + field USCBSIZE32 0x02 /* Use 32byte SCB Page Size */ + field CIOPARCKEN 0x01 /* Internal bus parity error enable */ } register DSCOMMAND1 { address 0x085 access_mode RW mask DSLATT 0xfc /* PCI latency timer (non-ultra2) */ - bit HADDLDSEL1 0x02 /* Host Address Load Select Bits */ - bit HADDLDSEL0 0x01 + field HADDLDSEL1 0x02 /* Host Address Load Select Bits */ + field HADDLDSEL0 0x01 } /* @@ -747,13 +758,13 @@ register HCNTRL { address 0x087 access_mode RW - bit POWRDN 0x40 - bit SWINT 0x10 - bit IRQMS 0x08 - bit PAUSE 0x04 - bit INTEN 0x02 - bit CHIPRST 0x01 - bit CHIPRSTACK 0x01 + field POWRDN 0x40 + field SWINT 0x10 + field IRQMS 0x08 + field PAUSE 0x04 + field INTEN 0x02 + field CHIPRST 0x01 + field CHIPRSTACK 0x01 } /* @@ -789,13 +800,13 @@ register INTSTAT { address 0x091 access_mode RW - bit BRKADRINT 0x08 - bit SCSIINT 0x04 - bit CMDCMPLT 0x02 - bit SEQINT 0x01 + field BRKADRINT 0x08 + field SCSIINT 0x04 + field CMDCMPLT 0x02 + field SEQINT 0x01 mask BAD_PHASE SEQINT /* unknown scsi bus phase */ mask SEND_REJECT 0x10|SEQINT /* sending a message reject */ - mask NO_IDENT 0x20|SEQINT /* no IDENTIFY after reconnect*/ + mask PROTO_VIOLATION 0x20|SEQINT /* SCSI protocol violation */ mask NO_MATCH 0x30|SEQINT /* no cmd match for reconnect */ mask IGN_WIDE_RES 0x40|SEQINT /* Complex IGN Wide Res Msg */ mask PDATA_REINIT 0x50|SEQINT /* @@ -858,14 +869,14 @@ register ERROR { address 0x092 access_mode RO - bit CIOPARERR 0x80 /* Ultra2 only */ - bit PCIERRSTAT 0x40 /* PCI only */ - bit MPARERR 0x20 /* PCI only */ - bit DPARERR 0x10 /* PCI only */ - bit SQPARERR 0x08 - bit ILLOPCODE 0x04 - bit ILLSADDR 0x02 - bit ILLHADDR 0x01 + field CIOPARERR 0x80 /* Ultra2 only */ + field PCIERRSTAT 0x40 /* PCI only */ + field MPARERR 0x20 /* PCI only */ + field DPARERR 0x10 /* PCI only */ + field SQPARERR 0x08 + field ILLOPCODE 0x04 + field ILLSADDR 0x02 + field ILLHADDR 0x01 } /* @@ -874,39 +885,39 @@ register CLRINT { address 0x092 access_mode WO - bit CLRPARERR 0x10 /* PCI only */ - bit CLRBRKADRINT 0x08 - bit CLRSCSIINT 0x04 - bit CLRCMDINT 0x02 - bit CLRSEQINT 0x01 + field CLRPARERR 0x10 /* PCI only */ + field CLRBRKADRINT 0x08 + field CLRSCSIINT 0x04 + field CLRCMDINT 0x02 + field CLRSEQINT 0x01 } register DFCNTRL { address 0x093 access_mode RW - bit PRELOADEN 0x80 /* aic7890 only */ - bit WIDEODD 0x40 - bit SCSIEN 0x20 - bit SDMAEN 0x10 - bit SDMAENACK 0x10 - bit HDMAEN 0x08 - bit HDMAENACK 0x08 - bit DIRECTION 0x04 - bit FIFOFLUSH 0x02 - bit FIFORESET 0x01 + field PRELOADEN 0x80 /* aic7890 only */ + field WIDEODD 0x40 + field SCSIEN 0x20 + field SDMAEN 0x10 + field SDMAENACK 0x10 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 + field FIFOFLUSH 0x02 + field FIFORESET 0x01 } register DFSTATUS { address 0x094 access_mode RO - bit PRELOAD_AVAIL 0x80 - bit DFCACHETH 0x40 - bit FIFOQWDEMP 0x20 - bit MREQPEND 0x10 - bit HDONE 0x08 - bit DFTHRESH 0x04 - bit FIFOFULL 0x02 - bit FIFOEMP 0x01 + field PRELOAD_AVAIL 0x80 + field DFCACHETH 0x40 + field FIFOQWDEMP 0x20 + field MREQPEND 0x10 + field HDONE 0x08 + field DFTHRESH 0x04 + field FIFOFULL 0x02 + field FIFOEMP 0x01 } register DFWADDR { @@ -932,7 +943,7 @@ register SCBCNT { address 0x09a access_mode RW - bit SCBAUTO 0x80 + field SCBAUTO 0x80 mask SCBCNT_MASK 0x1f } @@ -966,12 +977,12 @@ register CRCCONTROL1 { address 0x09d access_mode RW - bit CRCONSEEN 0x80 - bit CRCVALCHKEN 0x40 - bit CRCENDCHKEN 0x20 - bit CRCREQCHKEN 0x10 - bit TARGCRCENDEN 0x08 - bit TARGCRCCNTEN 0x04 + field CRCONSEEN 0x80 + field CRCVALCHKEN 0x40 + field CRCENDCHKEN 0x20 + field CRCREQCHKEN 0x10 + field TARGCRCENDEN 0x08 + field TARGCRCCNTEN 0x04 } @@ -987,12 +998,12 @@ register SCSIPHASE { address 0x09e access_mode RO - bit STATUS_PHASE 0x20 - bit COMMAND_PHASE 0x10 - bit MSG_IN_PHASE 0x08 - bit MSG_OUT_PHASE 0x04 - bit DATA_IN_PHASE 0x02 - bit DATA_OUT_PHASE 0x01 + field STATUS_PHASE 0x20 + field COMMAND_PHASE 0x10 + field MSG_IN_PHASE 0x08 + field MSG_OUT_PHASE 0x04 + field DATA_IN_PHASE 0x02 + field DATA_OUT_PHASE 0x01 mask DATA_PHASE_MASK 0x03 } @@ -1002,7 +1013,7 @@ register SFUNCT { address 0x09f access_mode RW - bit ALT_MODE 0x80 + field ALT_MODE 0x80 } /* @@ -1041,34 +1052,36 @@ * the data address. */ size 4 - bit SG_LAST_SEG 0x80 /* In the fourth byte */ + field SG_LAST_SEG 0x80 /* In the fourth byte */ mask SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */ } SCB_SGPTR { size 4 - bit SG_RESID_VALID 0x04 /* In the first byte */ - bit SG_FULL_RESID 0x02 /* In the first byte */ - bit SG_LIST_NULL 0x01 /* In the first byte */ + field SG_RESID_VALID 0x04 /* In the first byte */ + field SG_FULL_RESID 0x02 /* In the first byte */ + field SG_LIST_NULL 0x01 /* In the first byte */ } SCB_CONTROL { size 1 - bit TARGET_SCB 0x80 - bit DISCENB 0x40 - bit TAG_ENB 0x20 - bit MK_MESSAGE 0x10 - bit ULTRAENB 0x08 - bit DISCONNECTED 0x04 + field TARGET_SCB 0x80 + field STATUS_RCVD 0x80 + field DISCENB 0x40 + field TAG_ENB 0x20 + field MK_MESSAGE 0x10 + field ULTRAENB 0x08 + field DISCONNECTED 0x04 mask SCB_TAG_TYPE 0x03 } SCB_SCSIID { size 1 - bit TWIN_CHNLB 0x80 + field TWIN_CHNLB 0x80 mask TWIN_TID 0x70 mask TID 0xf0 mask OID 0x0f } SCB_LUN { - mask LID 0xff + field SCB_XFERLEN_ODD 0x80 + mask LID 0x3f size 1 } SCB_TAG { @@ -1105,18 +1118,18 @@ register SEECTL_2840 { address 0x0c0 access_mode RW - bit CS_2840 0x04 - bit CK_2840 0x02 - bit DO_2840 0x01 + field CS_2840 0x04 + field CK_2840 0x02 + field DO_2840 0x01 } register STATUS_2840 { address 0x0c1 access_mode RW - bit EEPROM_TF 0x80 + field EEPROM_TF 0x80 mask BIOS_SEL 0x60 mask ADSEL 0x1e - bit DI_2840 0x01 + field DI_2840 0x01 } /* --------------------- AIC-7870-only definitions -------------------- */ @@ -1140,10 +1153,10 @@ register CCSGCTL { address 0x0EB - bit CCSGDONE 0x80 - bit CCSGEN 0x08 - bit SG_FETCH_NEEDED 0x02 /* Bit used for software state */ - bit CCSGRESET 0x01 + field CCSGDONE 0x80 + field CCSGEN 0x08 + field SG_FETCH_NEEDED 0x02 /* Bit used for software state */ + field CCSGRESET 0x01 } register CCSCBCNT { @@ -1152,12 +1165,12 @@ register CCSCBCTL { address 0x0EE - bit CCSCBDONE 0x80 - bit ARRDONE 0x40 /* SCB Array prefetch done */ - bit CCARREN 0x10 - bit CCSCBEN 0x08 - bit CCSCBDIR 0x04 - bit CCSCBRESET 0x01 + field CCSCBDONE 0x80 + field ARRDONE 0x40 /* SCB Array prefetch done */ + field CCARREN 0x10 + field CCSCBEN 0x08 + field CCSCBDIR 0x04 + field CCSCBRESET 0x01 } register CCSCBADDR { @@ -1194,9 +1207,9 @@ register QOFF_CTLSTA { address 0x0FA - bit SCB_AVAIL 0x40 - bit SNSCB_ROLLOVER 0x20 - bit SDSCB_ROLLOVER 0x10 + field SCB_AVAIL 0x40 + field SNSCB_ROLLOVER 0x20 + field SDSCB_ROLLOVER 0x10 mask SCB_QSIZE 0x07 mask SCB_QSIZE_256 0x06 } @@ -1227,18 +1240,16 @@ access_mode WO address 0x0fc mask SG_ADDR_MASK 0xf8 - bit ODD_SEG 0x04 - bit LAST_SEG 0x02 - bit LAST_SEG_DONE 0x01 + field LAST_SEG 0x02 + field LAST_SEG_DONE 0x01 } register SG_CACHE_SHADOW { access_mode RO address 0x0fc mask SG_ADDR_MASK 0xf8 - bit ODD_SEG 0x04 - bit LAST_SEG 0x02 - bit LAST_SEG_DONE 0x01 + field LAST_SEG 0x02 + field LAST_SEG_DONE 0x01 } /* ---------------------- Scratch RAM Offsets ------------------------- */ /* These offsets are either to values that are initialized by the board's @@ -1295,6 +1306,7 @@ */ MWI_RESIDUAL { size 1 + alias TARG_IMMEDIATE_SCB } /* * SCBID of the next SCB to be started by the controller. @@ -1312,28 +1324,29 @@ /* Parameters for DMA Logic */ DMAPARAMS { size 1 - bit PRELOADEN 0x80 - bit WIDEODD 0x40 - bit SCSIEN 0x20 - bit SDMAEN 0x10 - bit SDMAENACK 0x10 - bit HDMAEN 0x08 - bit HDMAENACK 0x08 - bit DIRECTION 0x04 /* Set indicates PCI->SCSI */ - bit FIFOFLUSH 0x02 - bit FIFORESET 0x01 + field PRELOADEN 0x80 + field WIDEODD 0x40 + field SCSIEN 0x20 + field SDMAEN 0x10 + field SDMAENACK 0x10 + field HDMAEN 0x08 + field HDMAENACK 0x08 + field DIRECTION 0x04 /* Set indicates PCI->SCSI */ + field FIFOFLUSH 0x02 + field FIFORESET 0x01 } SEQ_FLAGS { size 1 - bit IDENTIFY_SEEN 0x80 - bit TARGET_CMD_IS_TAGGED 0x40 - bit DPHASE 0x20 + field NOT_IDENTIFIED 0x80 + field NO_CDB_SENT 0x40 + field TARGET_CMD_IS_TAGGED 0x40 + field DPHASE 0x20 /* Target flags */ - bit TARG_CMD_PENDING 0x10 - bit CMDPHASE_PENDING 0x08 - bit DPHASE_PENDING 0x04 - bit SPHASE_PENDING 0x02 - bit NO_DISCONNECT 0x01 + field TARG_CMD_PENDING 0x10 + field CMDPHASE_PENDING 0x08 + field DPHASE_PENDING 0x04 + field SPHASE_PENDING 0x02 + field NO_DISCONNECT 0x01 } /* * Temporary storage for the @@ -1351,9 +1364,9 @@ */ LASTPHASE { size 1 - bit CDI 0x80 - bit IOI 0x40 - bit MSGI 0x20 + field CDI 0x80 + field IOI 0x40 + field MSGI 0x20 mask PHASE_MASK CDI|IOI|MSGI mask P_DATAOUT 0x00 mask P_DATAIN IOI @@ -1457,20 +1470,12 @@ */ SCSISEQ_TEMPLATE { size 1 - bit ENSELO 0x40 - bit ENSELI 0x20 - bit ENRSELI 0x10 - bit ENAUTOATNO 0x08 - bit ENAUTOATNI 0x04 - bit ENAUTOATNP 0x02 - } - - /* - * Track whether the transfer byte count for - * the current data phase is odd. - */ - DATA_COUNT_ODD { - size 1 + field ENSELO 0x40 + field ENSELI 0x20 + field ENRSELI 0x10 + field ENAUTOATNO 0x08 + field ENAUTOATNI 0x04 + field ENAUTOATNP 0x02 } } @@ -1488,14 +1493,14 @@ */ HA_274_BIOSGLOBAL { size 1 - bit HA_274_EXTENDED_TRANS 0x01 + field HA_274_EXTENDED_TRANS 0x01 alias INITIATOR_TAG } SEQ_FLAGS2 { size 1 - bit SCB_DMA 0x01 - bit TARGET_MSG_PENDING 0x02 + field SCB_DMA 0x01 + field TARGET_MSG_PENDING 0x02 } } @@ -1513,16 +1518,16 @@ */ SCSICONF { size 1 - bit TERM_ENB 0x80 - bit RESET_SCSI 0x40 - bit ENSPCHK 0x20 + field TERM_ENB 0x80 + field RESET_SCSI 0x40 + field ENSPCHK 0x20 mask HSCSIID 0x07 /* our SCSI ID */ mask HWSCSIID 0x0f /* our SCSI ID if Wide Bus */ } INTDEF { address 0x05c size 1 - bit EDGE_TRIG 0x80 + field EDGE_TRIG 0x80 mask VECTOR 0x0f } HOSTCONF { @@ -1534,7 +1539,7 @@ size 1 mask BIOSMODE 0x30 mask BIOSDISABLED 0x30 - bit CHANNEL_B_PRIMARY 0x08 + field CHANNEL_B_PRIMARY 0x08 } } @@ -1566,6 +1571,7 @@ const MAX_OFFSET_8BIT 0x0f const MAX_OFFSET_16BIT 0x08 const MAX_OFFSET_ULTRA2 0x7f +const MAX_OFFSET 0x7f const HOST_MSG 0xff /* Target mode command processing constants */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx.seq linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx.seq --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx.seq 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx.seq 2003-08-25 04:44:42.000000000 -0700 @@ -37,11 +37,12 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.94.2.16 2002/04/29 19:36:30 gibbs Exp $ + * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $" PATCH_ARG_LIST = "struct ahc_softc *ahc" +PREFIX = "ahc_" #include "aic7xxx.reg" #include "scsi_message.h" @@ -69,7 +70,7 @@ * Turn off the selection hardware. We need to reset the * selection request in order to perform a new selection. */ - and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ; + and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP; and SIMODE1, ~ENBUSFREE; poll_for_work: call clear_target_state; @@ -192,7 +193,7 @@ * Setup the DMA for sending the identify and * command information. */ - or SEQ_FLAGS, CMDPHASE_PENDING; + mvi SEQ_FLAGS, CMDPHASE_PENDING; mov A, TQINPOS; if ((ahc->features & AHC_CMD_CHAN) != 0) { @@ -305,7 +306,7 @@ } else { mvi DFDAT, SCB_LIST_NULL; } - or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN; + or SEQ_FLAGS, TARG_CMD_PENDING; test SEQ_FLAGS2, TARGET_MSG_PENDING jnz target_mesgout_pending; test SCSISIGI, ATNI jnz target_mesgout_continue; @@ -389,13 +390,8 @@ } /* - * Initialize transfer settings and clear the SCSI channel. - * SINDEX should contain any additional bit's the client wants - * set in SXFRCTL0. We also assume that the current SCB is - * a valid SCB for the target we wish to talk to. + * Initialize transfer settings with SCB provided settings. */ -initialize_channel: - or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; set_transfer_settings: if ((ahc->features & AHC_ULTRA) != 0) { test SCB_CONTROL, ULTRAENB jz . + 2; @@ -441,11 +437,19 @@ mov SCBPTR, WAITING_SCBH; mov WAITING_SCBH,SCB_NEXT; mov SAVED_SCSIID, SCB_SCSIID; - mov SAVED_LUN, SCB_LUN; - call initialize_channel; + and SAVED_LUN, LID, SCB_LUN; + call set_transfer_settings; if ((ahc->flags & AHC_TARGETROLE) != 0) { test SSTAT0, TARGET jz initiator_select; + or SXFRCTL0, CLRSTCNT|CLRCHN; + + /* + * Put tag in connonical location since not + * all connections have an SCB. + */ + mov INITIATOR_TAG, SCB_TARGET_ITAG; + /* * We've just re-selected an initiator. * Assert BSY and setup the phase for @@ -457,7 +461,7 @@ /* * Start out with a simple identify message. */ - or SCB_LUN, MSG_IDENTIFYFLAG call target_outb; + or SAVED_LUN, MSG_IDENTIFYFLAG call target_outb; /* * If we are the result of a tagged command, send @@ -491,15 +495,16 @@ * on the state of NO_DISCONNECT. */ test SEQ_FLAGS, NO_DISCONNECT jz target_disconnect; - mov RETURN_1, ALLZEROS; + mvi TARG_IMMEDIATE_SCB, SCB_LIST_NULL; call complete_target_cmd; - cmp RETURN_1, CONT_MSG_LOOP jne .; if ((ahc->flags & AHC_PAGESCBS) != 0) { mov ALLZEROS call get_free_or_disc_scb; } + cmp TARG_IMMEDIATE_SCB, SCB_LIST_NULL je .; mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; - mov SCB_TAG call dma_scb; + mov TARG_IMMEDIATE_SCB call dma_scb; call set_transfer_settings; + or SXFRCTL0, CLRSTCNT|CLRCHN; jmp target_synccmd; target_mesgout: @@ -507,6 +512,7 @@ target_mesgout_continue: call target_inb; target_mesgout_pending: + and SEQ_FLAGS2, ~TARGET_MSG_PENDING; /* Local Processing goes here... */ jmp host_target_message_loop; @@ -636,13 +642,14 @@ if ((ahc->flags & AHC_INITIATORROLE) != 0) { initiator_select: + or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; /* * As soon as we get a successful selection, the target * should go into the message out phase since we have ATN * asserted. */ mvi MSG_OUT, MSG_IDENTIFYFLAG; - or SEQ_FLAGS, IDENTIFY_SEEN; + mvi SEQ_FLAGS, NO_CDB_SENT; mvi CLRSINT0, CLRSELDO; /* @@ -701,7 +708,7 @@ } mvi LASTPHASE, P_BUSFREE; /* clear target specific flags */ - clr SEQ_FLAGS ret; + mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret; sg_advance: clr A; /* add sizeof(struct scatter) */ @@ -761,16 +768,12 @@ /* Does the hardware have space for another SG entry? */ test DFSTATUS, PRELOAD_AVAIL jz return; bmov HADDR, CCSGRAM, 7; - test HCNT[0], 0x1 jz . + 2; - xor DATA_COUNT_ODD, 0x1; bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { mov SCB_RESIDUAL_DATACNT[3] call set_hhaddr; } call sg_advance; mov SINDEX, SCB_RESIDUAL_SGPTR[0]; - test DATA_COUNT_ODD, 0x1 jz . + 2; - or SINDEX, ODD_SEG; test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2; or SINDEX, LAST_SEG; mov SG_CACHE_PRE, SINDEX; @@ -815,9 +818,9 @@ } p_data: - test SEQ_FLAGS,IDENTIFY_SEEN jnz p_data_okay; - mvi NO_IDENT jmp set_seqint; -p_data_okay: + test SEQ_FLAGS,NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed; + mvi PROTO_VIOLATION call set_seqint; +p_data_allowed: if ((ahc->features & AHC_ULTRA2) != 0) { mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN; } else { @@ -868,7 +871,6 @@ call calc_mwi_residual; } and SCB_RESIDUAL_SGPTR[0], ~SG_FULL_RESID; - and DATA_COUNT_ODD, 0x1, HCNT[0]; if ((ahc->features & AHC_ULTRA2) == 0) { if ((ahc->features & AHC_CMD_CHAN) != 0) { @@ -903,8 +905,6 @@ mov SINDEX, SCB_RESIDUAL_SGPTR[0]; test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2; or SINDEX, LAST_SEG; - test DATA_COUNT_ODD, 0x1 jz . + 2; - or SINDEX, ODD_SEG; mov SG_CACHE_PRE, SINDEX; mov DFCNTRL, DMAPARAMS; ultra2_dma_loop: @@ -999,10 +999,8 @@ adc SCB_RESIDUAL_SGPTR[3], -1; sgptr_fixup_done: and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; - clr DATA_COUNT_ODD; - test SG_CACHE_SHADOW, ODD_SEG jz . + 2; - or DATA_COUNT_ODD, 0x1; - clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */ + /* We are not the last seg */ + and SCB_RESIDUAL_DATACNT[3], ~SG_LAST_SEG; residuals_correct: /* * Go ahead and shut down the DMA engine now. @@ -1046,11 +1044,19 @@ * LAST_SEG_DONE to come true on a completed transfer * and then test to see if the data FIFO is non-empty. */ - test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 4; + test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL + jz ultra2_wait_fifoemp; test SG_CACHE_SHADOW, LAST_SEG_DONE jz .; + /* + * FIFOEMP can lag LAST_SEG_DONE. Wait a few + * clocks before calling this an overrun. + */ + test DFSTATUS, FIFOEMP jnz ultra2_fifoempty; + test DFSTATUS, FIFOEMP jnz ultra2_fifoempty; test DFSTATUS, FIFOEMP jnz ultra2_fifoempty; /* Overrun */ jmp data_phase_loop; +ultra2_wait_fifoemp: test DFSTATUS, FIFOEMP jz .; } ultra2_fifoempty: @@ -1239,9 +1245,6 @@ } else { call set_stcnt_from_hcnt; } - /* Track odd'ness */ - test HCNT[0], 0x1 jz . + 2; - xor DATA_COUNT_ODD, 0x1; if ((ahc->flags & AHC_TARGETROLE) != 0) { test SSTAT0, TARGET jnz data_phase_loop; @@ -1343,7 +1346,7 @@ */ test DFCNTRL, DIRECTION jz target_ITloop; test SSTAT1, REQINIT jnz .; - test DATA_COUNT_ODD, 0x1 jz target_ITloop; + test SCB_LUN, SCB_XFERLEN_ODD jz target_ITloop; test SCSIRATE, WIDEXFER jz target_ITloop; /* * Issue an Ignore Wide Residue Message. @@ -1361,8 +1364,8 @@ * Command phase. Set up the DMA registers and let 'er rip. */ p_command: - test SEQ_FLAGS,IDENTIFY_SEEN jnz p_command_okay; - mvi NO_IDENT jmp set_seqint; + test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay; + mvi PROTO_VIOLATION call set_seqint; p_command_okay: if ((ahc->features & AHC_ULTRA2) != 0) { @@ -1394,7 +1397,7 @@ } mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET); } - jmp p_command_loop; + jmp p_command_xfer; p_command_embedded: /* * The data fifo seems to require 4 byte aligned @@ -1432,24 +1435,28 @@ call copy_to_fifo_6; or DFCNTRL, FIFOFLUSH; } -p_command_loop: +p_command_xfer: + and SEQ_FLAGS, ~NO_CDB_SENT; if ((ahc->features & AHC_DT) == 0) { test SSTAT0, SDONE jnz . + 2; - test SSTAT1, PHASEMIS jz p_command_loop; + test SSTAT1, PHASEMIS jz . - 1; /* * Wait for our ACK to go-away on it's own * instead of being killed by SCSIEN getting cleared. */ test SCSISIGI, ACKI jnz .; } else { - test DFCNTRL, SCSIEN jnz p_command_loop; + test DFCNTRL, SCSIEN jnz .; } + test SSTAT0, SDONE jnz p_command_successful; + /* + * Don't allow a data phase if the command + * was not fully transferred. + */ + or SEQ_FLAGS, NO_CDB_SENT; +p_command_successful: and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .; - if ((ahc->features & AHC_ULTRA2) != 0) { - /* Drop any residual from the S/G Preload queue */ - or SXFRCTL0, CLRSTCNT; - } jmp ITloop; /* @@ -1457,10 +1464,10 @@ * and store it into the SCB. */ p_status: - test SEQ_FLAGS,IDENTIFY_SEEN jnz p_status_okay; - mvi NO_IDENT jmp set_seqint; + test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; p_status_okay: mov SCB_SCSI_STATUS, SCSIDATL; + or SCB_CONTROL, STATUS_RCVD; jmp ITloop; /* @@ -1499,7 +1506,7 @@ cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; p_mesgout_identify: - or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN; + or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SAVED_LUN; test SCB_CONTROL, DISCENB jnz . + 2; and SINDEX, ~DISCENB; /* @@ -1576,18 +1583,20 @@ mvi ARG_1 call inb_next; cmp ARG_1, 0x01 jne mesgin_reject; test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; - test DATA_COUNT_ODD, 0x1 jz mesgin_done; + test SCB_LUN, SCB_XFERLEN_ODD jnz mesgin_done; mvi IGN_WIDE_RES call set_seqint; jmp mesgin_done; } +mesgin_proto_violation: + mvi PROTO_VIOLATION call set_seqint; + jmp mesgin_done; mesgin_reject: mvi MSG_MESSAGE_REJECT call mk_mesg; mesgin_done: mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ jmp ITloop; -mesgin_complete: /* * We received a "command complete" message. Put the SCB_TAG into the QOUTFIFO, * and trigger a completion interrupt. Before doing so, check to see if there @@ -1600,27 +1609,49 @@ * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting * RETURN_1 to SEND_SENSE. */ +mesgin_complete: -/* - * If ATN is raised, we still want to give the target a message. - * Perhaps there was a parity error on this last message byte. - * Either way, the target should take us to message out phase - * and then attempt to complete the command again. We should use a - * critical section here to guard against a timeout triggering - * for this command and setting ATN while we are still processing - * the completion. + /* + * If ATN is raised, we still want to give the target a message. + * Perhaps there was a parity error on this last message byte. + * Either way, the target should take us to message out phase + * and then attempt to complete the command again. We should use a + * critical section here to guard against a timeout triggering + * for this command and setting ATN while we are still processing + * the completion. test SCSISIGI, ATNI jnz mesgin_done; - */ + */ -/* - * See if we attempted to deliver a message but the target ingnored us. - */ + /* + * If we are identified and have successfully sent the CDB, + * any status will do. Optimize this fast path. + */ + test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation; + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; + + /* + * If the target never sent an identify message but instead went + * to mesgin to give an invalid message, let the host abort us. + */ + test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; + + /* + * If we recevied good status but never successfully sent the + * cdb, abort the command. + */ + test SCB_SCSI_STATUS,0xff jnz complete_accepted; + test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation; + +complete_accepted: + /* + * See if we attempted to deliver a message but the target ingnored us. + */ test SCB_CONTROL, MK_MESSAGE jz . + 2; mvi MKMSG_FAILED call set_seqint; -/* - * Check for residuals - */ + /* + * Check for residuals + */ test SCB_SGPTR, SG_LIST_NULL jnz check_status;/* No xfer */ test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; @@ -1673,14 +1704,15 @@ * XXX - Wait for more testing. test SCSISIGI, ATNI jnz mesgin_done; */ - + test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT + jnz mesgin_proto_violation; or SCB_CONTROL,DISCONNECTED; if ((ahc->flags & AHC_PAGESCBS) != 0) { call add_scb_to_disc_list; } test SCB_CONTROL, TAG_ENB jnz await_busfree; mov ARG_1, SCB_TAG; - mov SAVED_LUN, SCB_LUN; + and SAVED_LUN, LID, SCB_LUN; mov SCB_SCSIID call set_busy_target; jmp await_busfree; @@ -1741,7 +1773,8 @@ * Restore pointers message? Data pointers are recopied from the * SCB anytime we enter a data phase for the first time, so all * we need to do is clear the DPHASE flag and let the data phase - * code do the rest. + * code do the rest. We also reset/reallocate the FIFO to make + * sure we have a clean start for the next data or command phase. */ mesgin_rdptrs: and SEQ_FLAGS, ~DPHASE; /* @@ -1749,6 +1782,7 @@ * the next time through * the dataphase. */ + or SXFRCTL0, CLRSTCNT|CLRCHN; jmp mesgin_done; /* @@ -1776,7 +1810,7 @@ * transactions by first looking at the transaction stored in * the busy target array. If there is no untagged transaction * for this target or the transaction is for a different lun, then - * this must be an untagged transaction. + * this must be a tagged transaction. */ shr SINDEX, 4, SAVED_SCSIID; and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; @@ -1821,7 +1855,7 @@ * at a time. So, if the lun doesn't match, look * for a tag message. */ - mov A, SCB_LUN; + and A, LID, SCB_LUN; cmp SAVED_LUN, A je setup_SCB_id_lun_okay; if ((ahc->flags & AHC_PAGESCBS) != 0) { /* @@ -1879,7 +1913,7 @@ or SEQ_FLAGS, 0x8; } setup_SCB_id_okay: - mov A, SCB_LUN; + and A, LID, SCB_LUN; cmp SAVED_LUN, A jne not_found_cleanup_scb; setup_SCB_id_lun_okay: if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { @@ -1897,7 +1931,7 @@ mov SCBPTR, A; } setup_SCB_tagged: - mvi SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ + clr SEQ_FLAGS; /* make note of IDENTIFY */ call set_transfer_settings; /* See if the host wants to send a message upon reconnection */ test SCB_CONTROL, MK_MESSAGE jz mesgin_done; @@ -2218,9 +2252,9 @@ * available data to force the chip to * continue the transfer. This does not * happen for SCSI transfers as the SCSI module - * will drain the FIFO as data is made available. + * will drain the FIFO as data are made available. * When the hang occurs, we know that a multiple - * of 8 bytes are in the FIFO because the PCI + * of 8 bytes is in the FIFO because the PCI * module has an 8 byte input latch that only * dumps to the FIFO when HCNT == 0 or the * latch is full. @@ -2257,7 +2291,6 @@ } else { call dma_finish; } - /* If we were putting the SCB, we are done */ call dfdat_in_8; call dfdat_in_8; call dfdat_in_8; diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_93cx6.c linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_93cx6.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_93cx6.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_93cx6.c 2003-08-25 04:44:42.000000000 -0700 @@ -28,9 +28,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#15 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#17 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.8.2.5 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ /* diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_93cx6.h linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_93cx6.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_93cx6.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_93cx6.h 2003-08-25 04:44:42.000000000 -0700 @@ -38,9 +38,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#10 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#12 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.h,v 1.7.2.3 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ #ifndef _AIC7XXX_93CX6_H_ #define _AIC7XXX_93CX6_H_ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_core.c linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_core.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_core.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_core.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,8 +1,8 @@ /* * Core routines and tables shareable across OS platforms. * - * Copyright (c) 1994-2001 Justin T. Gibbs. - * Copyright (c) 2000-2001 Adaptec Inc. + * Copyright (c) 1994-2002 Justin T. Gibbs. + * Copyright (c) 2000-2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#69 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#133 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.41.2.22 2002/04/29 19:36:26 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -144,7 +144,8 @@ #include "aic7xxx_seq.h" /**************************** Function Declarations ***************************/ -static void ahc_force_renegotiation(struct ahc_softc *ahc); +static void ahc_force_renegotiation(struct ahc_softc *ahc, + struct ahc_devinfo *devinfo); static struct ahc_tmode_tstate* ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel); @@ -181,6 +182,7 @@ u_int period, u_int offset, u_int bus_width, u_int ppr_options); static void ahc_clear_msg_state(struct ahc_softc *ahc); +static void ahc_handle_proto_violation(struct ahc_softc *ahc); static void ahc_handle_message_phase(struct ahc_softc *ahc); typedef enum { AHCMSG_1B, @@ -200,7 +202,7 @@ struct ahc_devinfo *devinfo, cam_status status, char *message, int verbose_level); -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE static void ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, struct scb *scb); @@ -223,7 +225,7 @@ #ifdef AHC_DUMP_SEQ static void ahc_dumpseq(struct ahc_softc *ahc); #endif -static void ahc_loadseq(struct ahc_softc *ahc); +static int ahc_loadseq(struct ahc_softc *ahc); static int ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch, u_int start_instr, u_int *skip_addr); @@ -289,7 +291,7 @@ ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA); } ahc_outb(ahc, MWI_RESIDUAL, 0); - ahc_outb(ahc, SEQCTL, FASTMODE); + ahc_outb(ahc, SEQCTL, ahc->seqctl); ahc_outb(ahc, SEQADDR0, 0); ahc_outb(ahc, SEQADDR1, 0); ahc_unpause(ahc); @@ -330,7 +332,7 @@ printf("%s: WARNING no command for scb %d " "(cmdcmplt)\nQOUTPOS = %d\n", ahc_name(ahc), scb_index, - ahc->qoutfifonext - 1); + (ahc->qoutfifonext - 1) & 0xFF); continue; } @@ -388,7 +390,7 @@ ahc_dump_card_state(ahc); - /* Tell everyone that this HBA is no longer availible */ + /* Tell everyone that this HBA is no longer available */ ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS, CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN, CAM_NO_HBA); @@ -437,10 +439,10 @@ scb_index = ahc_inb(ahc, SCB_TAG); scb = ahc_lookup_scb(ahc, scb_index); if (scb == NULL) { - printf("%s:%c:%d: ahc_intr - referenced scb " + ahc_print_devinfo(ahc, &devinfo); + printf("ahc_intr - referenced scb " "not valid during seqint 0x%x scb(%d)\n", - ahc_name(ahc), devinfo.channel, - devinfo.target, intstat, scb_index); + intstat, scb_index); ahc_dump_card_state(ahc); panic("for safety"); goto unpause; @@ -478,7 +480,7 @@ struct ahc_tmode_tstate *tstate; struct ahc_transinfo *tinfo; #ifdef AHC_DEBUG - if (ahc_debug & AHC_SHOWSENSE) { + if (ahc_debug & AHC_SHOW_SENSE) { ahc_print_path(ahc, scb); printf("SCB %d: requests Check Status\n", scb->hscb->tag); @@ -501,7 +503,7 @@ */ ahc_update_residual(ahc, scb); #ifdef AHC_DEBUG - if (ahc_debug & AHC_SHOWSENSE) { + if (ahc_debug & AHC_SHOW_SENSE) { ahc_print_path(ahc, scb); printf("Sending Sense\n"); } @@ -545,7 +547,7 @@ == ahc_get_transfer_length(scb)) { ahc_update_neg_request(ahc, &devinfo, tstate, targ_info, - /*force*/TRUE); + AHC_NEG_IF_NON_ASYNC); } if (tstate->auto_negotiate & devinfo.target_mask) { hscb->control |= MK_MESSAGE; @@ -561,16 +563,11 @@ scb->flags |= SCB_SENSE; ahc_qinfifo_requeue_tail(ahc, scb); ahc_outb(ahc, RETURN_1, SEND_SENSE); -#ifdef __FreeBSD__ /* * Ensure we have enough time to actually * retrieve the sense. */ - untimeout(ahc_timeout, (caddr_t)scb, - scb->io_ctx->ccb_h.timeout_ch); - scb->io_ctx->ccb_h.timeout_ch = - timeout(ahc_timeout, (caddr_t)scb, 5 * hz); -#endif + ahc_scb_timer_reset(scb, 5 * 1000000); break; } default: @@ -624,27 +621,10 @@ ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte); break; } - case NO_IDENT: + case PROTO_VIOLATION: { - /* - * The reconnecting target either did not send an identify - * message, or did, but we didn't find an SCB to match and - * before it could respond to our ATN/abort, it hit a dataphase. - * The only safe thing to do is to blow it away with a bus - * reset. - */ - int found; - - printf("%s:%c:%d: Target did not send an IDENTIFY message. " - "LASTPHASE = 0x%x, SAVED_SCSIID == 0x%x\n", - ahc_name(ahc), devinfo.channel, devinfo.target, - ahc_inb(ahc, LASTPHASE), ahc_inb(ahc, SAVED_SCSIID)); - found = ahc_reset_channel(ahc, devinfo.channel, - /*initiate reset*/TRUE); - printf("%s: Issued Channel %c Bus Reset. " - "%d SCBs aborted\n", ahc_name(ahc), devinfo.channel, - found); - return; + ahc_handle_proto_violation(ahc); + break; } case IGN_WIDE_RES: ahc_handle_ign_wide_residue(ahc, &devinfo); @@ -725,7 +705,7 @@ ahc->msgin_index = 0; } } -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE else { if (bus_phase == P_MESGOUT) { ahc->msg_type = @@ -772,7 +752,44 @@ ahc_outb(ahc, LASTPHASE, curphase); ahc_outb(ahc, SCSISIGO, curphase); } - ahc_inb(ahc, SCSIDATL); + if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) { + int wait; + + /* + * In a data phase. Faster to bitbucket + * the data than to individually ack each + * byte. This is also the only strategy + * that will work with AUTOACK enabled. + */ + ahc_outb(ahc, SXFRCTL1, + ahc_inb(ahc, SXFRCTL1) | BITBUCKET); + wait = 5000; + while (--wait != 0) { + if ((ahc_inb(ahc, SCSISIGI) + & (CDI|MSGI)) != 0) + break; + ahc_delay(100); + } + ahc_outb(ahc, SXFRCTL1, + ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET); + if (wait == 0) { + struct scb *scb; + u_int scb_index; + + ahc_print_devinfo(ahc, &devinfo); + printf("Unable to clear parity error. " + "Resetting bus.\n"); + scb_index = ahc_inb(ahc, SCB_TAG); + scb = ahc_lookup_scb(ahc, scb_index); + if (scb != NULL) + ahc_set_transaction_status(scb, + CAM_UNCOR_PARITY); + ahc_reset_channel(ahc, devinfo.channel, + /*init reset*/TRUE); + } + } else { + ahc_inb(ahc, SCSIDATL); + } } break; } @@ -942,9 +959,6 @@ char cur_channel; char intr_channel; - /* Make sure the sequencer is in a safe location. */ - ahc_clear_critical_section(ahc); - if ((ahc->features & AHC_TWIN) != 0 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0)) cur_channel = 'B'; @@ -973,10 +987,13 @@ } } + /* Make sure the sequencer is in a safe location. */ + ahc_clear_critical_section(ahc); + scb_index = ahc_inb(ahc, SCB_TAG); scb = ahc_lookup_scb(ahc, scb_index); if (scb != NULL - && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0) + && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) scb = NULL; if ((ahc->features & AHC_ULTRA2) != 0 @@ -1016,13 +1033,15 @@ * we should look at the last phase the sequencer recorded, * or the current phase presented on the bus. */ - u_int mesg_out; - u_int curphase; - u_int errorphase; - u_int lastphase; - u_int scsirate; - u_int i; - u_int sstat2; + struct ahc_devinfo devinfo; + u_int mesg_out; + u_int curphase; + u_int errorphase; + u_int lastphase; + u_int scsirate; + u_int i; + u_int sstat2; + int silent; lastphase = ahc_inb(ahc, LASTPHASE); curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK; @@ -1050,29 +1069,47 @@ break; } mesg_out = ahc_phase_table[i].mesg_out; - if (scb != NULL) - ahc_print_path(ahc, scb); - else + silent = FALSE; + if (scb != NULL) { + if (SCB_IS_SILENT(scb)) + silent = TRUE; + else + ahc_print_path(ahc, scb); + scb->flags |= SCB_TRANSMISSION_ERROR; + } else printf("%s:%c:%d: ", ahc_name(ahc), intr_channel, SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID))); scsirate = ahc_inb(ahc, SCSIRATE); - printf("parity error detected %s. " - "SEQADDR(0x%x) SCSIRATE(0x%x)\n", - ahc_phase_table[i].phasemsg, - ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8), - scsirate); - - if ((ahc->features & AHC_DT) != 0) { + if (silent == FALSE) { + printf("parity error detected %s. " + "SEQADDR(0x%x) SCSIRATE(0x%x)\n", + ahc_phase_table[i].phasemsg, + ahc_inw(ahc, SEQADDR0), + scsirate); + if ((ahc->features & AHC_DT) != 0) { + if ((sstat2 & CRCVALERR) != 0) + printf("\tCRC Value Mismatch\n"); + if ((sstat2 & CRCENDERR) != 0) + printf("\tNo terminal CRC packet " + "recevied\n"); + if ((sstat2 & CRCREQERR) != 0) + printf("\tIllegal CRC packet " + "request\n"); + if ((sstat2 & DUAL_EDGE_ERR) != 0) + printf("\tUnexpected %sDT Data Phase\n", + (scsirate & SINGLE_EDGE) + ? "" : "non-"); + } + } - if ((sstat2 & CRCVALERR) != 0) - printf("\tCRC Value Mismatch\n"); - if ((sstat2 & CRCENDERR) != 0) - printf("\tNo terminal CRC packet recevied\n"); - if ((sstat2 & CRCREQERR) != 0) - printf("\tIllegal CRC packet request\n"); - if ((sstat2 & DUAL_EDGE_ERR) != 0) - printf("\tUnexpected %sDT Data Phase\n", - (scsirate & SINGLE_EDGE) ? "" : "non-"); + if ((ahc->features & AHC_DT) != 0 + && (sstat2 & DUAL_EDGE_ERR) != 0) { + /* + * This error applies regardless of + * data direction, so ignore the value + * in the phase table. + */ + mesg_out = MSG_INITIATOR_DET_ERR; } /* @@ -1093,7 +1130,9 @@ * case we are out of sync for some external reason * unknown (or unreported) by the target. */ - ahc_force_renegotiation(ahc); + ahc_fetch_devinfo(ahc, &devinfo); + ahc_force_renegotiation(ahc, &devinfo); + ahc_outb(ahc, CLRINT, CLRSCSIINT); ahc_unpause(ahc); } else if ((status & SELTO) != 0) { @@ -1128,31 +1167,42 @@ printf("%s: ahc_intr - referenced scb not " "valid during SELTO scb(%d, %d)\n", ahc_name(ahc), scbptr, scb_index); + ahc_dump_card_state(ahc); } else { + struct ahc_devinfo devinfo; +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_SELTO) != 0) { + ahc_print_path(ahc, scb); + printf("Saw Selection Timeout for SCB 0x%x\n", + scb_index); + } +#endif + /* + * Force a renegotiation with this target just in + * case the cable was pulled and will later be + * re-attached. The target may forget its negotiation + * settings with us should it attempt to reselect + * during the interruption. The target will not issue + * a unit attention in this case, so we must always + * renegotiate. + */ + ahc_scb_devinfo(ahc, &devinfo, scb); + ahc_force_renegotiation(ahc, &devinfo); ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT); ahc_freeze_devq(ahc, scb); } ahc_outb(ahc, CLRINT, CLRSCSIINT); - /* - * Force a renegotiation with this target just in - * case the cable was pulled and will later be - * re-attached. The target may forget its negotiation - * settings with us should it attempt to reselect - * during the interruption. The target will not issue - * a unit attention in this case, so we must always - * renegotiate. - */ - ahc_force_renegotiation(ahc); ahc_restart(ahc); } else if ((status & BUSFREE) != 0 && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) { - u_int lastphase; - u_int saved_scsiid; - u_int saved_lun; - u_int target; - u_int initiator_role_id; - char channel; - int printerror; + struct ahc_devinfo devinfo; + u_int lastphase; + u_int saved_scsiid; + u_int saved_lun; + u_int target; + u_int initiator_role_id; + char channel; + int printerror; /* * Clear our selection hardware as soon as possible. @@ -1184,13 +1234,13 @@ target = SCSIID_TARGET(ahc, saved_scsiid); initiator_role_id = SCSIID_OUR_ID(saved_scsiid); channel = SCSIID_CHANNEL(ahc, saved_scsiid); + ahc_compile_devinfo(&devinfo, initiator_role_id, + target, saved_lun, channel, ROLE_INITIATOR); printerror = 1; if (lastphase == P_MESGOUT) { - struct ahc_devinfo devinfo; u_int tag; - ahc_fetch_devinfo(ahc, &devinfo); tag = SCB_LIST_NULL; if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE) || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) { @@ -1254,17 +1304,23 @@ ahc_qinfifo_requeue_tail(ahc, scb); printerror = 0; } else if (ahc_sent_msg(ahc, AHCMSG_EXT, - MSG_EXT_WDTR, FALSE) - || ahc_sent_msg(ahc, AHCMSG_EXT, - MSG_EXT_SDTR, FALSE)) { + MSG_EXT_WDTR, FALSE)) { /* - * Negotiation Rejected. Go-async and + * Negotiation Rejected. Go-narrow and * retry command. */ ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, AHC_TRANS_CUR|AHC_TRANS_GOAL, /*paused*/TRUE); + ahc_qinfifo_requeue_tail(ahc, scb); + printerror = 0; + } else if (ahc_sent_msg(ahc, AHCMSG_EXT, + MSG_EXT_SDTR, FALSE)) { + /* + * Negotiation Rejected. Go-async and + * retry command. + */ ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL, /*period*/0, /*offset*/0, @@ -1301,13 +1357,15 @@ if (lastphase == ahc_phase_table[i].phase) break; } - /* - * Renegotiate with this device at the - * next oportunity just in case this busfree - * is due to a negotiation mismatch with the - * device. - */ - ahc_force_renegotiation(ahc); + if (lastphase != P_BUSFREE) { + /* + * Renegotiate with this device at the + * next oportunity just in case this busfree + * is due to a negotiation mismatch with the + * device. + */ + ahc_force_renegotiation(ahc, &devinfo); + } printf("Unexpected busfree %s\n" "SEQADDR == 0x%x\n", ahc_phase_table[i].phasemsg, @@ -1328,20 +1386,18 @@ * a command to the current device. */ static void -ahc_force_renegotiation(struct ahc_softc *ahc) +ahc_force_renegotiation(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) { - struct ahc_devinfo devinfo; struct ahc_initiator_tinfo *targ_info; struct ahc_tmode_tstate *tstate; - ahc_fetch_devinfo(ahc, &devinfo); targ_info = ahc_fetch_transinfo(ahc, - devinfo.channel, - devinfo.our_scsiid, - devinfo.target, + devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); - ahc_update_neg_request(ahc, &devinfo, tstate, - targ_info, /*force*/TRUE); + ahc_update_neg_request(ahc, devinfo, tstate, + targ_info, AHC_NEG_IF_NON_ASYNC); } #define AHC_MAX_STEPS 2000 @@ -1404,11 +1460,26 @@ simode0 = ahc_inb(ahc, SIMODE0); ahc_outb(ahc, SIMODE0, 0); simode1 = ahc_inb(ahc, SIMODE1); - ahc_outb(ahc, SIMODE1, 0); + if ((ahc->features & AHC_DT) != 0) + /* + * On DT class controllers, we + * use the enhanced busfree logic. + * Unfortunately we cannot re-enable + * busfree detection within the + * current connection, so we must + * leave it on while single stepping. + */ + ahc_outb(ahc, SIMODE1, ENBUSFREE); + else + ahc_outb(ahc, SIMODE1, 0); ahc_outb(ahc, CLRINT, CLRSCSIINT); - ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) | STEP); + ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP); stepping = TRUE; } + if ((ahc->features & AHC_DT) != 0) { + ahc_outb(ahc, CLRSINT1, CLRBUSFREE); + ahc_outb(ahc, CLRINT, CLRSCSIINT); + } ahc_outb(ahc, HCNTRL, ahc->unpause); while (!ahc_is_paused(ahc)) ahc_delay(200); @@ -1416,7 +1487,7 @@ if (stepping) { ahc_outb(ahc, SIMODE0, simode0); ahc_outb(ahc, SIMODE1, simode1); - ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) & ~STEP); + ahc_outb(ahc, SEQCTL, ahc->seqctl); } } @@ -1439,7 +1510,7 @@ /**************************** Debugging Routines ******************************/ #ifdef AHC_DEBUG -int ahc_debug = AHC_DEBUG; +uint32_t ahc_debug = AHC_DEBUG_OPTS; #endif void @@ -1496,7 +1567,8 @@ && ahc->enabled_targets[scsi_id] != master_tstate) panic("%s: ahc_alloc_tstate - Target already allocated", ahc_name(ahc)); - tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT); + tstate = (struct ahc_tmode_tstate*)malloc(sizeof(*tstate), + M_DEVBUF, M_NOWAIT); if (tstate == NULL) return (NULL); @@ -1593,6 +1665,10 @@ else transinfo = &tinfo->goal; *ppr_options &= transinfo->ppr_options; + if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { + maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2); + *ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } if (transinfo->period == 0) { *period = 0; *ppr_options = 0; @@ -1769,17 +1845,29 @@ int ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, struct ahc_tmode_tstate *tstate, - struct ahc_initiator_tinfo *tinfo, int force) + struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type) { u_int auto_negotiate_orig; auto_negotiate_orig = tstate->auto_negotiate; + if (neg_type == AHC_NEG_ALWAYS) { + /* + * Force our "current" settings to be + * unknown so that unless a bus reset + * occurs the need to renegotiate is + * recorded persistently. + */ + if ((ahc->features & AHC_WIDE) != 0) + tinfo->curr.width = AHC_WIDTH_UNKNOWN; + tinfo->curr.period = AHC_PERIOD_UNKNOWN; + tinfo->curr.offset = AHC_OFFSET_UNKNOWN; + } if (tinfo->curr.period != tinfo->goal.period || tinfo->curr.width != tinfo->goal.width || tinfo->curr.offset != tinfo->goal.offset || tinfo->curr.ppr_options != tinfo->goal.ppr_options - || (force - && (tinfo->goal.period != 0 + || (neg_type == AHC_NEG_IF_NON_ASYNC + && (tinfo->goal.offset != 0 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT || tinfo->goal.ppr_options != 0))) tstate->auto_negotiate |= devinfo->target_mask; @@ -1910,7 +1998,7 @@ } update_needed += ahc_update_neg_request(ahc, devinfo, tstate, - tinfo, /*force*/FALSE); + tinfo, AHC_NEG_TO_GOAL); if (update_needed) ahc_update_pending_scbs(ahc); @@ -1972,7 +2060,7 @@ } update_needed += ahc_update_neg_request(ahc, devinfo, tstate, - tinfo, /*force*/FALSE); + tinfo, AHC_NEG_TO_GOAL); if (update_needed) ahc_update_pending_scbs(ahc); } @@ -2086,7 +2174,8 @@ if (role == ROLE_TARGET && (ahc->features & AHC_MULTI_TID) != 0 - && (ahc_inb(ahc, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) { + && (ahc_inb(ahc, SEQ_FLAGS) + & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) { /* We were selected, so pull our id from TARGIDIN */ our_id = ahc_inb(ahc, TARGIDIN) & OID; } else if ((ahc->features & AHC_ULTRA2) != 0) @@ -2136,6 +2225,13 @@ devinfo->target_mask = (0x01 << devinfo->target_offset); } +void +ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) +{ + printf("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel, + devinfo->target, devinfo->lun); +} + static void ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, struct scb *scb) @@ -2145,7 +2241,7 @@ our_id = SCSIID_OUR_ID(scb->hscb->scsiid); role = ROLE_INITIATOR; - if ((scb->hscb->control & TARGET_SCB) != 0) + if ((scb->flags & SCB_TARGET_SCB) != 0) role = ROLE_TARGET; ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb), SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role); @@ -2270,7 +2366,6 @@ int dowide; int dosync; int doppr; - int use_ppr; u_int period; u_int ppr_options; u_int offset; @@ -2284,6 +2379,7 @@ * may change. */ period = tinfo->goal.period; + offset = tinfo->goal.offset; ppr_options = tinfo->goal.ppr_options; /* Target initiated PPR is not allowed in the SCSI spec */ if (devinfo->role == ROLE_TARGET) @@ -2291,24 +2387,38 @@ rate = ahc_devlimited_syncrate(ahc, tinfo, &period, &ppr_options, devinfo->role); dowide = tinfo->curr.width != tinfo->goal.width; - dosync = tinfo->curr.period != period; - doppr = tinfo->curr.ppr_options != ppr_options; + dosync = tinfo->curr.offset != offset || tinfo->curr.period != period; + /* + * Only use PPR if we have options that need it, even if the device + * claims to support it. There might be an expander in the way + * that doesn't. + */ + doppr = ppr_options != 0; if (!dowide && !dosync && !doppr) { dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT; - dosync = tinfo->goal.period != 0; - doppr = tinfo->goal.ppr_options != 0; + dosync = tinfo->goal.offset != 0; } if (!dowide && !dosync && !doppr) { - panic("ahc_intr: AWAITING_MSG for negotiation, " - "but no negotiation needed\n"); + /* + * Force async with a WDTR message if we have a wide bus, + * or just issue an SDTR with a 0 offset. + */ + if ((ahc->features & AHC_WIDE) != 0) + dowide = 1; + else + dosync = 1; + + if (bootverbose) { + ahc_print_devinfo(ahc, devinfo); + printf("Ensuring async\n"); + } } - use_ppr = (tinfo->curr.transport_version >= 3) || doppr; /* Target initiated PPR is not allowed in the SCSI spec */ if (devinfo->role == ROLE_TARGET) - use_ppr = 0; + doppr = 0; /* * Both the PPR message and SDTR message require the @@ -2318,14 +2428,14 @@ * Regardless, guarantee that if we are using WDTR and SDTR * messages that WDTR comes first. */ - if (use_ppr || (dosync && !dowide)) { + if (doppr || (dosync && !dowide)) { offset = tinfo->goal.offset; ahc_validate_offset(ahc, tinfo, rate, &offset, - use_ppr ? tinfo->goal.width - : tinfo->curr.width, + doppr ? tinfo->goal.width + : tinfo->curr.width, devinfo->role); - if (use_ppr) { + if (doppr) { ahc_construct_ppr(ahc, devinfo, period, offset, tinfo->goal.width, ppr_options); } else { @@ -2344,6 +2454,8 @@ ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, u_int period, u_int offset) { + if (offset == 0) + period = AHC_ASYNC_XFER_PERIOD; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR; @@ -2386,6 +2498,8 @@ u_int period, u_int offset, u_int bus_width, u_int ppr_options) { + if (offset == 0) + period = AHC_ASYNC_XFER_PERIOD; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN; ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR; @@ -2424,6 +2538,100 @@ ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING); } +static void +ahc_handle_proto_violation(struct ahc_softc *ahc) +{ + struct ahc_devinfo devinfo; + struct scb *scb; + u_int scbid; + u_int seq_flags; + u_int curphase; + u_int lastphase; + int found; + + ahc_fetch_devinfo(ahc, &devinfo); + scbid = ahc_inb(ahc, SCB_TAG); + scb = ahc_lookup_scb(ahc, scbid); + seq_flags = ahc_inb(ahc, SEQ_FLAGS); + curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK; + lastphase = ahc_inb(ahc, LASTPHASE); + if ((seq_flags & NOT_IDENTIFIED) != 0) { + + /* + * The reconnecting target either did not send an + * identify message, or did, but we didn't find an SCB + * to match. + */ + ahc_print_devinfo(ahc, &devinfo); + printf("Target did not send an IDENTIFY message. " + "LASTPHASE = 0x%x.\n", lastphase); + scb = NULL; + } else if (scb == NULL) { + /* + * We don't seem to have an SCB active for this + * transaction. Print an error and reset the bus. + */ + ahc_print_devinfo(ahc, &devinfo); + printf("No SCB found during protocol violation\n"); + goto proto_violation_reset; + } else { + ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL); + if ((seq_flags & NO_CDB_SENT) != 0) { + ahc_print_path(ahc, scb); + printf("No or incomplete CDB sent to device.\n"); + } else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) { + /* + * The target never bothered to provide status to + * us prior to completing the command. Since we don't + * know the disposition of this command, we must attempt + * to abort it. Assert ATN and prepare to send an abort + * message. + */ + ahc_print_path(ahc, scb); + printf("Completed command without status.\n"); + } else { + ahc_print_path(ahc, scb); + printf("Unknown protocol violation.\n"); + ahc_dump_card_state(ahc); + } + } + if ((lastphase & ~P_DATAIN_DT) == 0 + || lastphase == P_COMMAND) { +proto_violation_reset: + /* + * Target either went directly to data/command + * phase or didn't respond to our ATN. + * The only safe thing to do is to blow + * it away with a bus reset. + */ + found = ahc_reset_channel(ahc, 'A', TRUE); + printf("%s: Issued Channel %c Bus Reset. " + "%d SCBs aborted\n", ahc_name(ahc), 'A', found); + } else { + /* + * Leave the selection hardware off in case + * this abort attempt will affect yet to + * be sent commands. + */ + ahc_outb(ahc, SCSISEQ, + ahc_inb(ahc, SCSISEQ) & ~ENSELO); + ahc_assert_atn(ahc); + ahc_outb(ahc, MSG_OUT, HOST_MSG); + if (scb == NULL) { + ahc_print_devinfo(ahc, &devinfo); + ahc->msgout_buf[0] = MSG_ABORT_TASK; + ahc->msgout_len = 1; + ahc->msgout_index = 0; + ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT; + } else { + ahc_print_path(ahc, scb); + scb->flags |= SCB_ABORT; + } + printf("Protocol violation %s. Attempting to abort.\n", + ahc_lookup_phase_entry(curphase)->phasemsg); + } +} + /* * Manual message loop handler. */ @@ -2449,8 +2657,21 @@ if (ahc->msgout_len == 0) panic("HOST_MSG_LOOP interrupt with no active message"); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("INITIATOR_MSG_OUT"); + } +#endif phasemis = bus_phase != P_MESGOUT; if (phasemis) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahc_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif if (bus_phase == P_MESGIN) { /* * Change gears and see if @@ -2471,6 +2692,10 @@ if (ahc->send_msg_perror) { ahc_outb(ahc, CLRSINT1, CLRATNO); ahc_outb(ahc, CLRSINT1, CLRREQINIT); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", ahc->send_msg_perror); +#endif ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR); break; } @@ -2497,6 +2722,11 @@ * the next byte on the bus. */ ahc_outb(ahc, CLRSINT1, CLRREQINIT); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahc->msgout_buf[ahc->msgout_index]); +#endif ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]); break; } @@ -2505,9 +2735,21 @@ int phasemis; int message_done; +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("INITIATOR_MSG_IN"); + } +#endif phasemis = bus_phase != P_MESGIN; - if (phasemis) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + printf(" PHASEMIS %s\n", + ahc_lookup_phase_entry(bus_phase) + ->phasemsg); + } +#endif ahc->msgin_index = 0; if (bus_phase == P_MESGOUT && (ahc->send_msg_perror == TRUE @@ -2522,6 +2764,11 @@ /* Pull the byte in without acking it */ ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + printf(" byte 0x%x\n", + ahc->msgin_buf[ahc->msgin_index]); +#endif message_done = ahc_parse_msg(ahc, &devinfo); @@ -2537,8 +2784,15 @@ * assert ATN so the target takes us to the * message out phase. */ - if (ahc->msgout_len != 0) + if (ahc->msgout_len != 0) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("Asserting ATN for response\n"); + } +#endif ahc_assert_atn(ahc); + } } else ahc->msgin_index++; @@ -2748,9 +3002,9 @@ targ_scsirate = tinfo->scsirate; /* - * Parse as much of the message as is availible, + * Parse as much of the message as is available, * rejecting it if we don't support it. When - * the entire message is availible and has been + * the entire message is available and has been * handled, return MSGLOOP_MSGCOMPLETE, indicating * that we have parsed an entire message. * @@ -2929,23 +3183,30 @@ response = TRUE; sending_reply = TRUE; } + /* + * After a wide message, we are async, but + * some devices don't seem to honor this portion + * of the spec. Force a renegotiation of the + * sync component of our transfer agreement even + * if our goal is async. By updating our width + * after forcing the negotiation, we avoid + * renegotiating for width. + */ + ahc_update_neg_request(ahc, devinfo, tstate, + tinfo, AHC_NEG_ALWAYS); ahc_set_width(ahc, devinfo, bus_width, AHC_TRANS_ACTIVE|AHC_TRANS_GOAL, /*paused*/TRUE); - /* After a wide message, we are async */ - ahc_set_syncrate(ahc, devinfo, - /*syncrate*/NULL, /*period*/0, - /*offset*/0, /*ppr_options*/0, - AHC_TRANS_ACTIVE, /*paused*/TRUE); if (sending_reply == FALSE && reject == FALSE) { - if (tinfo->goal.period) { - ahc->msgout_index = 0; - ahc->msgout_len = 0; - ahc_build_transfer_msg(ahc, devinfo); - ahc->msgout_index = 0; - response = TRUE; - } + /* + * We will always have an SDTR to send. + */ + ahc->msgout_index = 0; + ahc->msgout_len = 0; + ahc_build_transfer_msg(ahc, devinfo); + ahc->msgout_index = 0; + response = TRUE; } done = MSGLOOP_MSGCOMPLETE; break; @@ -3204,7 +3465,7 @@ * but rejected our response, we already cleared the * sync rate before sending our WDTR. */ - if (tinfo->goal.period) { + if (tinfo->goal.offset != tinfo->curr.offset) { /* Start the sync negotiation */ ahc->msgout_index = 0; @@ -3326,7 +3587,7 @@ sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR); if ((sgptr & SG_LIST_NULL) != 0 - && ahc_inb(ahc, DATA_COUNT_ODD) == 1) { + && (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) { /* * If the residual occurred on the last * transfer and the transfer request was @@ -3339,25 +3600,27 @@ uint32_t data_addr; uint32_t sglen; - /* Pull in the rest of the sgptr */ - sgptr |= (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24) - | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16) - | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8); - sgptr &= SG_PTR_MASK; - data_cnt = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+3) << 24) - | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+2) << 16) - | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+1) << 8) - | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT)); - - data_addr = (ahc_inb(ahc, SHADDR + 3) << 24) - | (ahc_inb(ahc, SHADDR + 2) << 16) - | (ahc_inb(ahc, SHADDR + 1) << 8) - | (ahc_inb(ahc, SHADDR)); + /* Pull in all of the sgptr */ + sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR); + data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT); + + if ((sgptr & SG_LIST_NULL) != 0) { + /* + * The residual data count is not updated + * for the command run to completion case. + * Explicitly zero the count. + */ + data_cnt &= ~AHC_SG_LEN_MASK; + } + + data_addr = ahc_inl(ahc, SHADDR); data_cnt += 1; data_addr -= 1; + sgptr &= SG_PTR_MASK; sg = ahc_sg_bus_to_virt(scb, sgptr); + /* * The residual sg ptr points to the next S/G * to load so we must go back one. @@ -3383,19 +3646,17 @@ */ sg++; sgptr = ahc_sg_virt_to_bus(scb, sg); - ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 3, - sgptr >> 24); - ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 2, - sgptr >> 16); - ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 1, - sgptr >> 8); - ahc_outb(ahc, SCB_RESIDUAL_SGPTR, sgptr); } - - ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24); - ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16); - ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8); - ahc_outb(ahc, SCB_RESIDUAL_DATACNT, data_cnt); + ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr); + ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt); + /* + * Toggle the "oddness" of the transfer length + * to handle this mid-transfer ignore wide + * residue. This ensures that the oddness is + * correct for subsequent data transfers. + */ + ahc_outb(ahc, SCB_LUN, + ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD); } } } @@ -3579,6 +3840,12 @@ ahc->features = AHC_FENONE; ahc->bugs = AHC_BUGNONE; ahc->flags = AHC_FNONE; + /* + * Default to all error reporting enabled with the + * sequencer operating at its fastest speed. + * The bus attach code may modify this. + */ + ahc->seqctl = FASTMODE; for (i = 0; i < AHC_NUM_TARGETS; i++) TAILQ_INIT(&ahc->untagged_queues[i]); @@ -3658,7 +3925,7 @@ */ list_ahc = TAILQ_FIRST(&ahc_tailq); while (list_ahc != NULL - && ahc_softc_comp(list_ahc, ahc) <= 0) + && ahc_softc_comp(ahc, list_ahc) <= 0) list_ahc = TAILQ_NEXT(list_ahc, links); if (list_ahc != NULL) TAILQ_INSERT_BEFORE(list_ahc, ahc, links); @@ -3702,7 +3969,6 @@ { int i; - ahc_fini_scbdata(ahc); switch (ahc->init_level) { default: case 5: @@ -3734,12 +4000,13 @@ ahc_dma_tag_destroy(ahc, ahc->parent_dmat); #endif ahc_platform_free(ahc); + ahc_fini_scbdata(ahc); for (i = 0; i < AHC_NUM_TARGETS; i++) { struct ahc_tmode_tstate *tstate; tstate = ahc->enabled_targets[i]; if (tstate != NULL) { -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE int j; for (j = 0; j < AHC_NUM_LUNS; j++) { @@ -3755,7 +4022,7 @@ free(tstate, M_DEVBUF); } } -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE if (ahc->black_hole != NULL) { xpt_free_path(ahc->black_hole->path); free(ahc->black_hole, M_DEVBUF); @@ -3780,7 +4047,7 @@ ahc = (struct ahc_softc *)arg; /* This will reset most registers to 0, but not all */ - ahc_reset(ahc); + ahc_reset(ahc, /*reinit*/FALSE); ahc_outb(ahc, SCSISEQ, 0); ahc_outb(ahc, SXFRCTL0, 0); ahc_outb(ahc, DSPCISTATUS, 0); @@ -3791,13 +4058,19 @@ /* * Reset the controller and record some information about it - * that is only available just after a reset. + * that is only available just after a reset. If "reinit" is + * non-zero, this reset occured after initial configuration + * and the caller requests that the chip be fully reinitialized + * to a runable state. Chip interrupts are *not* enabled after + * a reinitialization. The caller must enable interrupts via + * ahc_intr_enable(). */ int -ahc_reset(struct ahc_softc *ahc) +ahc_reset(struct ahc_softc *ahc, int reinit) { u_int sblkctl; u_int sxfrctl1_a, sxfrctl1_b; + int error; int wait; /* @@ -3806,6 +4079,14 @@ * to disturb the integrity of the bus. */ ahc_pause(ahc); + if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) { + /* + * The chip has not been initialized since + * PCI/EISA/VLB bus reset. Don't trust + * "left over BIOS data". + */ + ahc->flags |= AHC_NO_BIOS_INIT; + } sxfrctl1_b = 0; if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) { u_int sblkctl; @@ -3821,7 +4102,7 @@ } sxfrctl1_a = ahc_inb(ahc, SXFRCTL1); - ahc_outb_reset(ahc, HCNTRL, CHIPRST | ahc->pause); + ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause); /* * Ensure that the reset has finished. We delay 1000us @@ -3880,12 +4161,19 @@ } ahc_outb(ahc, SXFRCTL1, sxfrctl1_a); + error = 0; + if (reinit != 0) + /* + * If a recovery action has forced a chip reset, + * re-initialize the chip to our liking. + */ + error = ahc->bus_chip_init(ahc); #ifdef AHC_DUMP_SEQ - if (ahc->init_level == 0) + else ahc_dumpseq(ahc); #endif - return (0); + return (error); } /* @@ -3955,6 +4243,14 @@ ahc_outb(ahc, SCB_LUN, 0xFF); } + if ((ahc->flags & AHC_PAGESCBS) != 0) { + /* SCB 0 heads the free list. */ + ahc_outb(ahc, FREE_SCBH, 0); + } else { + /* No free list. */ + ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL); + } + /* Make sure that the last SCB terminates the free list */ ahc_outb(ahc, SCBPTR, i-1); ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL); @@ -3980,20 +4276,11 @@ /* Determine the number of hardware SCBs and initialize them */ scb_data->maxhscbs = ahc_probe_scbs(ahc); - if ((ahc->flags & AHC_PAGESCBS) != 0) { - /* SCB 0 heads the free list */ - ahc_outb(ahc, FREE_SCBH, 0); - } else { - ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL); - } - if (ahc->scb_data->maxhscbs == 0) { printf("%s: No SCB space found\n", ahc_name(ahc)); return (ENXIO); } - ahc_build_free_scb_list(ahc); - /* * Create our DMA tags. These tags define the kinds of device * accessible memory allocations and memory mappings we will @@ -4069,7 +4356,7 @@ scb_data->init_level++; /* DMA tag for our S/G structures. We allocate in page sized chunks */ - if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1, + if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/8, /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, @@ -4095,10 +4382,9 @@ } /* - * Tell the sequencer which SCB will be the next one it receives. + * Reserve the next queued SCB. */ ahc->next_queued_scb = ahc_get_scb(ahc); - ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag); /* * Note that we were successfull @@ -4283,60 +4569,242 @@ sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs); } -/* - * Start the board, ready for normal operation - */ int -ahc_init(struct ahc_softc *ahc) +ahc_chip_init(struct ahc_softc *ahc) { - int max_targ; - int i; int term; + int error; + u_int i; u_int scsi_conf; u_int scsiseq_template; - u_int ultraenb; - u_int discenable; - u_int tagenable; - size_t driver_data_size; uint32_t physaddr; -#ifdef AHC_DEBUG_SEQUENCER - ahc->flags |= AHC_SEQUENCER_DEBUG; -#endif + ahc_outb(ahc, SEQ_FLAGS, 0); + ahc_outb(ahc, SEQ_FLAGS2, 0); -#ifdef AHC_PRINT_SRAM - printf("Scratch Ram:"); - for (i = 0x20; i < 0x5f; i++) { - if (((i % 8) == 0) && (i != 0)) { - printf ("\n "); - } - printf (" 0x%x", ahc_inb(ahc, i)); - } - if ((ahc->features & AHC_MORE_SRAM) != 0) { - for (i = 0x70; i < 0x7f; i++) { - if (((i % 8) == 0) && (i != 0)) { - printf ("\n "); - } - printf (" 0x%x", ahc_inb(ahc, i)); - } - } - printf ("\n"); - /* - * Reading uninitialized scratch ram may - * generate parity errors. - */ - ahc_outb(ahc, CLRINT, CLRPARERR); - ahc_outb(ahc, CLRINT, CLRBRKADRINT); -#endif - max_targ = 15; + /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/ + if (ahc->features & AHC_TWIN) { + + /* + * Setup Channel B first. + */ + ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB); + term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0; + ahc_outb(ahc, SCSIID, ahc->our_id_b); + scsi_conf = ahc_inb(ahc, SCSICONF + 1); + ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL)) + |term|ahc->seltime_b|ENSTIMER|ACTNEGEN); + if ((ahc->features & AHC_ULTRA2) != 0) + ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR); + ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR); + ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN); + + /* Select Channel A */ + ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB); + } + term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0; + if ((ahc->features & AHC_ULTRA2) != 0) + ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id); + else + ahc_outb(ahc, SCSIID, ahc->our_id); + scsi_conf = ahc_inb(ahc, SCSICONF); + ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL)) + |term|ahc->seltime + |ENSTIMER|ACTNEGEN); + if ((ahc->features & AHC_ULTRA2) != 0) + ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR); + ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR); + ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN); + + /* There are no untagged SCBs active yet. */ + for (i = 0; i < 16; i++) { + ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0)); + if ((ahc->flags & AHC_SCB_BTT) != 0) { + int lun; + + /* + * The SCB based BTT allows an entry per + * target and lun pair. + */ + for (lun = 1; lun < AHC_NUM_LUNS; lun++) + ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun)); + } + } + + /* All of our queues are empty */ + for (i = 0; i < 256; i++) + ahc->qoutfifo[i] = SCB_LIST_NULL; + ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD); + + for (i = 0; i < 256; i++) + ahc->qinfifo[i] = SCB_LIST_NULL; + + if ((ahc->features & AHC_MULTI_TID) != 0) { + ahc_outb(ahc, TARGID, 0); + ahc_outb(ahc, TARGID + 1, 0); + } /* - * Assume we have a board at this stage and it has been reset. - */ - if ((ahc->flags & AHC_USEDEFAULTS) != 0) - ahc->our_id = ahc->our_id_b = 7; - - /* + * Tell the sequencer where it can find our arrays in memory. + */ + physaddr = ahc->scb_data->hscb_busaddr; + ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF); + ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF); + ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF); + ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF); + + physaddr = ahc->shared_data_busaddr; + ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF); + ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF); + ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF); + ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF); + + /* + * Initialize the group code to command length table. + * This overrides the values in TARG_SCSIRATE, so only + * setup the table after we have processed that information. + */ + ahc_outb(ahc, CMDSIZE_TABLE, 5); + ahc_outb(ahc, CMDSIZE_TABLE + 1, 9); + ahc_outb(ahc, CMDSIZE_TABLE + 2, 9); + ahc_outb(ahc, CMDSIZE_TABLE + 3, 0); + ahc_outb(ahc, CMDSIZE_TABLE + 4, 15); + ahc_outb(ahc, CMDSIZE_TABLE + 5, 11); + ahc_outb(ahc, CMDSIZE_TABLE + 6, 0); + ahc_outb(ahc, CMDSIZE_TABLE + 7, 0); + + if ((ahc->features & AHC_HS_MAILBOX) != 0) + ahc_outb(ahc, HS_MAILBOX, 0); + + /* Tell the sequencer of our initial queue positions */ + if ((ahc->features & AHC_TARGETMODE) != 0) { + ahc->tqinfifonext = 1; + ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1); + ahc_outb(ahc, TQINPOS, ahc->tqinfifonext); + } + ahc->qinfifonext = 0; + ahc->qoutfifonext = 0; + if ((ahc->features & AHC_QUEUE_REGS) != 0) { + ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256); + ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext); + ahc_outb(ahc, SNSCB_QOFF, ahc->qinfifonext); + ahc_outb(ahc, SDSCB_QOFF, 0); + } else { + ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext); + ahc_outb(ahc, QINPOS, ahc->qinfifonext); + ahc_outb(ahc, QOUTPOS, ahc->qoutfifonext); + } + + /* We don't have any waiting selections */ + ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL); + + /* Our disconnection list is empty too */ + ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL); + + /* Message out buffer starts empty */ + ahc_outb(ahc, MSG_OUT, MSG_NOOP); + + /* + * Setup the allowed SCSI Sequences based on operational mode. + * If we are a target, we'll enalbe select in operations once + * we've had a lun enabled. + */ + scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP; + if ((ahc->flags & AHC_INITIATORROLE) != 0) + scsiseq_template |= ENRSELI; + ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template); + + /* Initialize our list of free SCBs. */ + ahc_build_free_scb_list(ahc); + + /* + * Tell the sequencer which SCB will be the next one it receives. + */ + ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag); + + /* + * Load the Sequencer program and Enable the adapter + * in "fast" mode. + */ + if (bootverbose) + printf("%s: Downloading Sequencer Program...", + ahc_name(ahc)); + + error = ahc_loadseq(ahc); + if (error != 0) + return (error); + + if ((ahc->features & AHC_ULTRA2) != 0) { + int wait; + + /* + * Wait for up to 500ms for our transceivers + * to settle. If the adapter does not have + * a cable attached, the transceivers may + * never settle, so don't complain if we + * fail here. + */ + for (wait = 5000; + (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait; + wait--) + ahc_delay(100); + } + ahc_restart(ahc); + return (0); +} + +/* + * Start the board, ready for normal operation + */ +int +ahc_init(struct ahc_softc *ahc) +{ + int max_targ; + u_int i; + u_int scsi_conf; + u_int ultraenb; + u_int discenable; + u_int tagenable; + size_t driver_data_size; + +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0) + ahc->flags |= AHC_SEQUENCER_DEBUG; +#endif + +#ifdef AHC_PRINT_SRAM + printf("Scratch Ram:"); + for (i = 0x20; i < 0x5f; i++) { + if (((i % 8) == 0) && (i != 0)) { + printf ("\n "); + } + printf (" 0x%x", ahc_inb(ahc, i)); + } + if ((ahc->features & AHC_MORE_SRAM) != 0) { + for (i = 0x70; i < 0x7f; i++) { + if (((i % 8) == 0) && (i != 0)) { + printf ("\n "); + } + printf (" 0x%x", ahc_inb(ahc, i)); + } + } + printf ("\n"); + /* + * Reading uninitialized scratch ram may + * generate parity errors. + */ + ahc_outb(ahc, CLRINT, CLRPARERR); + ahc_outb(ahc, CLRINT, CLRBRKADRINT); +#endif + max_targ = 15; + + /* + * Assume we have a board at this stage and it has been reset. + */ + if ((ahc->flags & AHC_USEDEFAULTS) != 0) + ahc->our_id = ahc->our_id_b = 7; + + /* * Default to allowing initiator operations. */ ahc->flags |= AHC_INITIATORROLE; @@ -4351,10 +4819,13 @@ /* DMA tag for mapping buffers into device visible space. */ if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1, /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, - /*lowaddr*/BUS_SPACE_MAXADDR, + /*lowaddr*/ahc->flags & AHC_39BIT_ADDRESSING + ? (bus_addr_t)0x7FFFFFFFFFULL + : BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG, + /*maxsize*/(AHC_NSEG - 1) * PAGE_SIZE, + /*nsegments*/AHC_NSEG, /*maxsegsz*/AHC_MAXTRANSFER_SIZE, /*flags*/BUS_DMA_ALLOCNOW, &ahc->buffer_dmat) != 0) { @@ -4414,9 +4885,6 @@ for (i = 0; i < AHC_TMODE_CMDS; i++) ahc->targetcmds[i].cmd_valid = 0; ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD); - ahc->tqinfifonext = 1; - ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1); - ahc_outb(ahc, TQINPOS, ahc->tqinfifonext); ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256]; } ahc->qinfifo = &ahc->qoutfifo[256]; @@ -4447,9 +4915,6 @@ } } - ahc_outb(ahc, SEQ_FLAGS, 0); - ahc_outb(ahc, SEQ_FLAGS2, 0); - if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) { ahc->flags |= AHC_PAGESCBS; } else { @@ -4457,63 +4922,32 @@ } #ifdef AHC_DEBUG - if (ahc_debug & AHC_SHOWMISC) { - printf("%s: hardware scb %d bytes; kernel scb %d bytes; " - "ahc_dma %d bytes\n", + if (ahc_debug & AHC_SHOW_MISC) { + printf("%s: hardware scb %u bytes; kernel scb %u bytes; " + "ahc_dma %u bytes\n", ahc_name(ahc), - sizeof(struct hardware_scb), - sizeof(struct scb), - sizeof(struct ahc_dma_seg)); + (u_int)sizeof(struct hardware_scb), + (u_int)sizeof(struct scb), + (u_int)sizeof(struct ahc_dma_seg)); } #endif /* AHC_DEBUG */ - /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/ + /* + * Look at the information that board initialization or + * the board bios has left us. + */ if (ahc->features & AHC_TWIN) { - - /* - * The device is gated to channel B after a chip reset, - * so set those values first - */ - ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB); - term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0; - ahc_outb(ahc, SCSIID, ahc->our_id_b); scsi_conf = ahc_inb(ahc, SCSICONF + 1); - ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL)) - |term|ahc->seltime_b|ENSTIMER|ACTNEGEN); - if ((ahc->features & AHC_ULTRA2) != 0) - ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR); - ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR); - ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN); - if ((scsi_conf & RESET_SCSI) != 0 && (ahc->flags & AHC_INITIATORROLE) != 0) ahc->flags |= AHC_RESET_BUS_B; - - /* Select Channel A */ - ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB); } - term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0; - if ((ahc->features & AHC_ULTRA2) != 0) - ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id); - else - ahc_outb(ahc, SCSIID, ahc->our_id); - scsi_conf = ahc_inb(ahc, SCSICONF); - ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL)) - |term|ahc->seltime - |ENSTIMER|ACTNEGEN); - if ((ahc->features & AHC_ULTRA2) != 0) - ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR); - ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR); - ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN); + scsi_conf = ahc_inb(ahc, SCSICONF); if ((scsi_conf & RESET_SCSI) != 0 && (ahc->flags & AHC_INITIATORROLE) != 0) ahc->flags |= AHC_RESET_BUS_A; - /* - * Look at the information that board initialization or - * the board bios has left us. - */ ultraenb = 0; tagenable = ALL_TARGETS_MASK; @@ -4565,7 +4999,7 @@ * connection type we have with the target. */ tinfo->user.period = ahc_syncrates->period; - tinfo->user.offset = ~0; + tinfo->user.offset = MAX_OFFSET; } else { u_int scsirate; uint16_t mask; @@ -4600,7 +5034,7 @@ if (offset == 0) tinfo->user.period = 0; else - tinfo->user.offset = ~0; + tinfo->user.offset = MAX_OFFSET; if ((scsirate & SXFR_ULTRA2) <= 8/*10MHz*/ && (ahc->features & AHC_DT) != 0) tinfo->user.ppr_options = @@ -4618,7 +5052,7 @@ ? AHC_SYNCRATE_ULTRA : AHC_SYNCRATE_FAST); if (tinfo->user.period != 0) - tinfo->user.offset = ~0; + tinfo->user.offset = MAX_OFFSET; } if (tinfo->user.period == 0) tinfo->user.offset = 0; @@ -4635,132 +5069,12 @@ tinfo->curr.protocol_version = 2; tinfo->curr.transport_version = 2; } - tstate->ultraenb = ultraenb; + tstate->ultraenb = 0; } ahc->user_discenable = discenable; ahc->user_tagenable = tagenable; - /* There are no untagged SCBs active yet. */ - for (i = 0; i < 16; i++) { - ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0)); - if ((ahc->flags & AHC_SCB_BTT) != 0) { - int lun; - - /* - * The SCB based BTT allows an entry per - * target and lun pair. - */ - for (lun = 1; lun < AHC_NUM_LUNS; lun++) - ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun)); - } - } - - /* All of our queues are empty */ - for (i = 0; i < 256; i++) - ahc->qoutfifo[i] = SCB_LIST_NULL; - ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD); - - for (i = 0; i < 256; i++) - ahc->qinfifo[i] = SCB_LIST_NULL; - - if ((ahc->features & AHC_MULTI_TID) != 0) { - ahc_outb(ahc, TARGID, 0); - ahc_outb(ahc, TARGID + 1, 0); - } - - /* - * Tell the sequencer where it can find our arrays in memory. - */ - physaddr = ahc->scb_data->hscb_busaddr; - ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF); - ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF); - ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF); - ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF); - - physaddr = ahc->shared_data_busaddr; - ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF); - ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF); - ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF); - ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF); - - /* - * Initialize the group code to command length table. - * This overrides the values in TARG_SCSIRATE, so only - * setup the table after we have processed that information. - */ - ahc_outb(ahc, CMDSIZE_TABLE, 5); - ahc_outb(ahc, CMDSIZE_TABLE + 1, 9); - ahc_outb(ahc, CMDSIZE_TABLE + 2, 9); - ahc_outb(ahc, CMDSIZE_TABLE + 3, 0); - ahc_outb(ahc, CMDSIZE_TABLE + 4, 15); - ahc_outb(ahc, CMDSIZE_TABLE + 5, 11); - ahc_outb(ahc, CMDSIZE_TABLE + 6, 0); - ahc_outb(ahc, CMDSIZE_TABLE + 7, 0); - - /* Tell the sequencer of our initial queue positions */ - ahc_outb(ahc, KERNEL_QINPOS, 0); - ahc_outb(ahc, QINPOS, 0); - ahc_outb(ahc, QOUTPOS, 0); - - /* - * Use the built in queue management registers - * if they are available. - */ - if ((ahc->features & AHC_QUEUE_REGS) != 0) { - ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256); - ahc_outb(ahc, SDSCB_QOFF, 0); - ahc_outb(ahc, SNSCB_QOFF, 0); - ahc_outb(ahc, HNSCB_QOFF, 0); - } - - - /* We don't have any waiting selections */ - ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL); - - /* Our disconnection list is empty too */ - ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL); - - /* Message out buffer starts empty */ - ahc_outb(ahc, MSG_OUT, MSG_NOOP); - - /* - * Setup the allowed SCSI Sequences based on operational mode. - * If we are a target, we'll enalbe select in operations once - * we've had a lun enabled. - */ - scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP; - if ((ahc->flags & AHC_INITIATORROLE) != 0) - scsiseq_template |= ENRSELI; - ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template); - - /* - * Load the Sequencer program and Enable the adapter - * in "fast" mode. - */ - if (bootverbose) - printf("%s: Downloading Sequencer Program...", - ahc_name(ahc)); - - ahc_loadseq(ahc); - - if ((ahc->features & AHC_ULTRA2) != 0) { - int wait; - - /* - * Wait for up to 500ms for our transceivers - * to settle. If the adapter does not have - * a cable attached, the tranceivers may - * never settle, so don't complain if we - * fail here. - */ - ahc_pause(ahc); - for (wait = 5000; - (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait; - wait--) - ahc_delay(100); - ahc_unpause(ahc); - } - return (0); + return (ahc->bus_chip_init(ahc)); } void @@ -4792,21 +5106,27 @@ { int intstat; int maxloops; + int paused; maxloops = 1000; ahc->flags |= AHC_ALL_INTERRUPTS; - intstat = 0; + paused = FALSE; do { + if (paused) + ahc_unpause(ahc); ahc_intr(ahc); ahc_pause(ahc); + paused = TRUE; + ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO); ahc_clear_critical_section(ahc); - if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) - break; - maxloops--; - } while (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) && --maxloops); + intstat = ahc_inb(ahc, INTSTAT); + } while (--maxloops + && (intstat != 0xFF || (ahc->features & AHC_REMOVABLE) == 0) + && ((intstat & INT_PEND) != 0 + || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)) != 0)); if (maxloops == 0) { printf("Infinite interrupt loop, INTSTAT = %x", - ahc_inb(ahc, INTSTAT)); + ahc_inb(ahc, INTSTAT)); } ahc_platform_flushwork(ahc); ahc->flags &= ~AHC_ALL_INTERRUPTS; @@ -4815,87 +5135,25 @@ int ahc_suspend(struct ahc_softc *ahc) { - uint8_t *ptr; - int i; ahc_pause_and_flushwork(ahc); - if (LIST_FIRST(&ahc->pending_scbs) != NULL) + if (LIST_FIRST(&ahc->pending_scbs) != NULL) { + ahc_unpause(ahc); return (EBUSY); + } -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE /* * XXX What about ATIOs that have not yet been serviced? * Perhaps we should just refuse to be suspended if we * are acting in a target role. */ - if (ahc->pending_device != NULL) + if (ahc->pending_device != NULL) { + ahc_unpause(ahc); return (EBUSY); -#endif - - /* Save volatile registers */ - if ((ahc->features & AHC_TWIN) != 0) { - ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB); - ahc->suspend_state.channel[1].scsiseq = ahc_inb(ahc, SCSISEQ); - ahc->suspend_state.channel[1].sxfrctl0 = ahc_inb(ahc, SXFRCTL0); - ahc->suspend_state.channel[1].sxfrctl1 = ahc_inb(ahc, SXFRCTL1); - ahc->suspend_state.channel[1].simode0 = ahc_inb(ahc, SIMODE0); - ahc->suspend_state.channel[1].simode1 = ahc_inb(ahc, SIMODE1); - ahc->suspend_state.channel[1].seltimer = ahc_inb(ahc, SELTIMER); - ahc->suspend_state.channel[1].seqctl = ahc_inb(ahc, SEQCTL); - ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB); - } - ahc->suspend_state.channel[0].scsiseq = ahc_inb(ahc, SCSISEQ); - ahc->suspend_state.channel[0].sxfrctl0 = ahc_inb(ahc, SXFRCTL0); - ahc->suspend_state.channel[0].sxfrctl1 = ahc_inb(ahc, SXFRCTL1); - ahc->suspend_state.channel[0].simode0 = ahc_inb(ahc, SIMODE0); - ahc->suspend_state.channel[0].simode1 = ahc_inb(ahc, SIMODE1); - ahc->suspend_state.channel[0].seltimer = ahc_inb(ahc, SELTIMER); - ahc->suspend_state.channel[0].seqctl = ahc_inb(ahc, SEQCTL); - - if ((ahc->chip & AHC_PCI) != 0) { - ahc->suspend_state.dscommand0 = ahc_inb(ahc, DSCOMMAND0); - ahc->suspend_state.dspcistatus = ahc_inb(ahc, DSPCISTATUS); - } - - if ((ahc->features & AHC_DT) != 0) { - u_int sfunct; - - sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; - ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); - ahc->suspend_state.optionmode = ahc_inb(ahc, OPTIONMODE); - ahc_outb(ahc, SFUNCT, sfunct); - ahc->suspend_state.crccontrol1 = ahc_inb(ahc, CRCCONTROL1); - } - - if ((ahc->features & AHC_MULTI_FUNC) != 0) - ahc->suspend_state.scbbaddr = ahc_inb(ahc, SCBBADDR); - - if ((ahc->features & AHC_ULTRA2) != 0) - ahc->suspend_state.dff_thrsh = ahc_inb(ahc, DFF_THRSH); - - ptr = ahc->suspend_state.scratch_ram; - for (i = 0; i < 64; i++) - *ptr++ = ahc_inb(ahc, SRAM_BASE + i); - - if ((ahc->features & AHC_MORE_SRAM) != 0) { - for (i = 0; i < 16; i++) - *ptr++ = ahc_inb(ahc, TARG_OFFSET + i); - } - - ptr = ahc->suspend_state.btt; - if ((ahc->flags & AHC_SCB_BTT) != 0) { - for (i = 0;i < AHC_NUM_TARGETS; i++) { - int j; - - for (j = 0;j < AHC_NUM_LUNS; j++) { - u_int tcl; - - tcl = BUILD_TCL(i << 4, j); - *ptr = ahc_index_busy_tcl(ahc, tcl); - } - } } +#endif ahc_shutdown(ahc); return (0); } @@ -4903,81 +5161,10 @@ int ahc_resume(struct ahc_softc *ahc) { - uint8_t *ptr; - int i; - - ahc_reset(ahc); - - ahc_build_free_scb_list(ahc); - - /* Restore volatile registers */ - if ((ahc->features & AHC_TWIN) != 0) { - ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB); - ahc_outb(ahc, SCSIID, ahc->our_id); - ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[1].scsiseq); - ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[1].sxfrctl0); - ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[1].sxfrctl1); - ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[1].simode0); - ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[1].simode1); - ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[1].seltimer); - ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[1].seqctl); - ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB); - } - ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[0].scsiseq); - ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[0].sxfrctl0); - ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[0].sxfrctl1); - ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[0].simode0); - ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[0].simode1); - ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[0].seltimer); - ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[0].seqctl); - if ((ahc->features & AHC_ULTRA2) != 0) - ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id); - else - ahc_outb(ahc, SCSIID, ahc->our_id); - - if ((ahc->chip & AHC_PCI) != 0) { - ahc_outb(ahc, DSCOMMAND0, ahc->suspend_state.dscommand0); - ahc_outb(ahc, DSPCISTATUS, ahc->suspend_state.dspcistatus); - } - - if ((ahc->features & AHC_DT) != 0) { - u_int sfunct; - sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; - ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); - ahc_outb(ahc, OPTIONMODE, ahc->suspend_state.optionmode); - ahc_outb(ahc, SFUNCT, sfunct); - ahc_outb(ahc, CRCCONTROL1, ahc->suspend_state.crccontrol1); - } - - if ((ahc->features & AHC_MULTI_FUNC) != 0) - ahc_outb(ahc, SCBBADDR, ahc->suspend_state.scbbaddr); - - if ((ahc->features & AHC_ULTRA2) != 0) - ahc_outb(ahc, DFF_THRSH, ahc->suspend_state.dff_thrsh); - - ptr = ahc->suspend_state.scratch_ram; - for (i = 0; i < 64; i++) - ahc_outb(ahc, SRAM_BASE + i, *ptr++); - - if ((ahc->features & AHC_MORE_SRAM) != 0) { - for (i = 0; i < 16; i++) - ahc_outb(ahc, TARG_OFFSET + i, *ptr++); - } - - ptr = ahc->suspend_state.btt; - if ((ahc->flags & AHC_SCB_BTT) != 0) { - for (i = 0;i < AHC_NUM_TARGETS; i++) { - int j; - - for (j = 0;j < AHC_NUM_LUNS; j++) { - u_int tcl; - - tcl = BUILD_TCL(i << 4, j); - ahc_busy_tcl(ahc, tcl, *ptr); - } - } - } + ahc_reset(ahc, /*reinit*/TRUE); + ahc_intr_enable(ahc, TRUE); + ahc_restart(ahc); return (0); } @@ -5059,7 +5246,7 @@ if (match != 0) match = ((lun == slun) || (lun == CAM_LUN_WILDCARD)); if (match != 0) { -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE int group; group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code); @@ -5139,8 +5326,8 @@ static int ahc_qinfifo_count(struct ahc_softc *ahc) { - u_int8_t qinpos; - u_int8_t diff; + uint8_t qinpos; + uint8_t diff; if ((ahc->features & AHC_QUEUE_REGS) != 0) { qinpos = ahc_inb(ahc, SNSCB_QOFF); @@ -5444,6 +5631,7 @@ break; } case SEARCH_REMOVE: + scb->flags &= ~SCB_UNTAGGEDQ; TAILQ_REMOVE(untagged_q, scb, links.tqe); break; case SEARCH_COUNT: @@ -5801,7 +5989,7 @@ * before the reset occurred. */ ahc_run_qoutfifo(ahc); -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE /* * XXX - In Twin mode, the tqinfifo may have commands * for an unaffected channel in it. However, if @@ -5833,7 +6021,7 @@ */ ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB); simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST); -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE /* * Bus resets clear ENSELI, so we cannot * defer re-enabling bus reset interrupts @@ -5852,7 +6040,7 @@ } else { /* Case 2: A command from this bus is active or we're idle */ simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST); -#if AHC_TARGET_MODE +#ifdef AHC_TARGET_MODE /* * Bus resets clear ENSELI, so we cannot * defer re-enabling bus reset interrupts @@ -6017,9 +6205,10 @@ ahc_set_sense_residual(scb, resid); #ifdef AHC_DEBUG - if ((ahc_debug & AHC_SHOWMISC) != 0) { + if ((ahc_debug & AHC_SHOW_MISC) != 0) { ahc_print_path(ahc, scb); - printf("Handled Residual of %d bytes\n", resid); + printf("Handled %sResidual of %d bytes\n", + (scb->flags & SCB_SENSE) ? "Sense " : "", resid); } #endif } @@ -6120,19 +6309,11 @@ ahc_dumpseq(struct ahc_softc* ahc) { int i; - int max_prog; - - if ((ahc->chip & AHC_BUS_MASK) < AHC_PCI) - max_prog = 448; - else if ((ahc->features & AHC_ULTRA2) != 0) - max_prog = 768; - else - max_prog = 512; ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); ahc_outb(ahc, SEQADDR0, 0); ahc_outb(ahc, SEQADDR1, 0); - for (i = 0; i < max_prog; i++) { + for (i = 0; i < ahc->instruction_ram_size; i++) { uint8_t ins_bytes[4]; ahc_insb(ahc, SEQRAM, ins_bytes, 4); @@ -6144,7 +6325,7 @@ } #endif -static void +static int ahc_loadseq(struct ahc_softc *ahc) { struct cs cs_table[num_critical_sections]; @@ -6154,9 +6335,9 @@ u_int cs_count; u_int cur_cs; u_int i; - int downloaded; u_int skip_addr; u_int sg_prefetch_cnt; + int downloaded; uint8_t download_consts[7]; /* @@ -6197,6 +6378,19 @@ */ continue; } + + if (downloaded == ahc->instruction_ram_size) { + /* + * We're about to exceed the instruction + * storage capacity for this chip. Fail + * the load. + */ + printf("\n%s: Program too large for instruction memory " + "size of %d!\n", ahc_name(ahc), + ahc->instruction_ram_size); + return (ENOMEM); + } + /* * Move through the CS table until we find a CS * that might apply to this instruction. @@ -6232,10 +6426,13 @@ memcpy(ahc->critical_sections, cs_table, cs_count); } ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE); - ahc_restart(ahc); - if (bootverbose) + if (bootverbose) { printf(" %d instructions downloaded\n", downloaded); + printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n", + ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags); + } + return (0); } static int @@ -6399,14 +6596,64 @@ } } +int +ahc_print_register(ahc_reg_parse_entry_t *table, u_int num_entries, + const char *name, u_int address, u_int value, + u_int *cur_column, u_int wrap_point) +{ + int printed; + u_int printed_mask; + + if (cur_column != NULL && *cur_column >= wrap_point) { + printf("\n"); + *cur_column = 0; + } + printed = printf("%s[0x%x]", name, value); + if (table == NULL) { + printed += printf(" "); + *cur_column += printed; + return (printed); + } + printed_mask = 0; + while (printed_mask != 0xFF) { + int entry; + + for (entry = 0; entry < num_entries; entry++) { + if (((value & table[entry].mask) + != table[entry].value) + || ((printed_mask & table[entry].mask) + == table[entry].mask)) + continue; + + printed += printf("%s%s", + printed_mask == 0 ? ":(" : "|", + table[entry].name); + printed_mask |= table[entry].mask; + + break; + } + if (entry >= num_entries) + break; + } + if (printed_mask != 0) + printed += printf(") "); + else + printed += printf(" "); + if (cur_column != NULL) + *cur_column += printed; + return (printed); +} + void ahc_dump_card_state(struct ahc_softc *ahc) { - struct scb *scb; - struct scb_tailq *untagged_q; - int target; - int maxtarget; - int i; + struct scb *scb; + struct scb_tailq *untagged_q; + u_int cur_col; + int paused; + int target; + int maxtarget; + int i; uint8_t last_phase; uint8_t qinpos; uint8_t qintail; @@ -6414,33 +6661,53 @@ uint8_t scb_index; uint8_t saved_scbptr; - saved_scbptr = ahc_inb(ahc, SCBPTR); + if (ahc_is_paused(ahc)) { + paused = 1; + } else { + paused = 0; + ahc_pause(ahc); + } + saved_scbptr = ahc_inb(ahc, SCBPTR); last_phase = ahc_inb(ahc, LASTPHASE); - printf("%s: Dumping Card State %s, at SEQADDR 0x%x\n", + printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" + "%s: Dumping Card State %s, at SEQADDR 0x%x\n", ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg, ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); + if (paused) + printf("Card was paused\n"); printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n", ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX), ahc_inb(ahc, ARG_2)); printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT), ahc_inb(ahc, SCBPTR)); - printf("SCSISEQ = 0x%x, SBLKCTL = 0x%x\n", - ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL)); - printf(" DFCNTRL = 0x%x, DFSTATUS = 0x%x\n", - ahc_inb(ahc, DFCNTRL), ahc_inb(ahc, DFSTATUS)); - printf("LASTPHASE = 0x%x, SCSISIGI = 0x%x, SXFRCTL0 = 0x%x\n", - last_phase, ahc_inb(ahc, SCSISIGI), ahc_inb(ahc, SXFRCTL0)); - printf("SSTAT0 = 0x%x, SSTAT1 = 0x%x\n", - ahc_inb(ahc, SSTAT0), ahc_inb(ahc, SSTAT1)); + cur_col = 0; if ((ahc->features & AHC_DT) != 0) - printf("SCSIPHASE = 0x%x\n", ahc_inb(ahc, SCSIPHASE)); - printf("STACK == 0x%x, 0x%x, 0x%x, 0x%x\n", - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8), - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8), - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8), - ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8)); - printf("SCB count = %d\n", ahc->scb_data->numscbs); + ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50); + ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50); + ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50); + ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50); + ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50); + ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50); + ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50); + ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50); + ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50); + ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50); + ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50); + ahc_sstat1_print(ahc_inb(ahc, SSTAT1), &cur_col, 50); + ahc_sstat2_print(ahc_inb(ahc, SSTAT2), &cur_col, 50); + ahc_sstat3_print(ahc_inb(ahc, SSTAT3), &cur_col, 50); + ahc_simode0_print(ahc_inb(ahc, SIMODE0), &cur_col, 50); + ahc_simode1_print(ahc_inb(ahc, SIMODE1), &cur_col, 50); + ahc_sxfrctl0_print(ahc_inb(ahc, SXFRCTL0), &cur_col, 50); + ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50); + ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50); + if (cur_col != 0) + printf("\n"); + printf("STACK:"); + for (i = 0; i < STACK_SIZE; i++) + printf(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8)); + printf("\nSCB count = %d\n", ahc->scb_data->numscbs); printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag); printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB)); /* QINFIFO */ @@ -6500,11 +6767,12 @@ printf("Sequencer SCB Info: "); for (i = 0; i < ahc->scb_data->maxhscbs; i++) { ahc_outb(ahc, SCBPTR, i); - printf("%d(c 0x%x, s 0x%x, l %d, t 0x%x) ", - i, ahc_inb(ahc, SCB_CONTROL), - ahc_inb(ahc, SCB_SCSIID), - ahc_inb(ahc, SCB_LUN), - ahc_inb(ahc, SCB_TAG)); + cur_col = printf("\n%3d ", i); + + ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60); + ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60); + ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60); + ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60); } printf("\n"); @@ -6513,14 +6781,17 @@ LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) { if (i++ > 256) break; - if (scb != LIST_FIRST(&ahc->pending_scbs)) - printf(", "); - printf("%d(c 0x%x, s 0x%x, l %d)", scb->hscb->tag, - scb->hscb->control, scb->hscb->scsiid, scb->hscb->lun); + cur_col = printf("\n%3d ", scb->hscb->tag); + ahc_scb_control_print(scb->hscb->control, &cur_col, 60); + ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60); + ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60); if ((ahc->flags & AHC_PAGESCBS) == 0) { ahc_outb(ahc, SCBPTR, scb->hscb->tag); - printf("(0x%x, 0x%x)", ahc_inb(ahc, SCB_CONTROL), - ahc_inb(ahc, SCB_TAG)); + printf("("); + ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), + &cur_col, 60); + ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60); + printf(")"); } } printf("\n"); @@ -6550,7 +6821,10 @@ } ahc_platform_dump_card_state(ahc); + printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); ahc_outb(ahc, SCBPTR, saved_scbptr); + if (paused == 0) + ahc_unpause(ahc); } /************************* Target Mode ****************************************/ @@ -6603,10 +6877,12 @@ struct ahc_tmode_lstate *lstate; struct ccb_en_lun *cel; cam_status status; + u_long s; u_int target; u_int lun; u_int target_mask; - u_long s; + u_int our_id; + int error; char channel; status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate, @@ -6617,15 +6893,33 @@ return; } - if ((ahc->features & AHC_MULTIROLE) != 0) { - u_int our_id; + if (cam_sim_bus(sim) == 0) + our_id = ahc->our_id; + else + our_id = ahc->our_id_b; - if (cam_sim_bus(sim) == 0) - our_id = ahc->our_id; - else - our_id = ahc->our_id_b; + if (ccb->ccb_h.target_id != our_id) { + /* + * our_id represents our initiator ID, or + * the ID of the first target to have an + * enabled lun in target mode. There are + * two cases that may preclude enabling a + * target id other than our_id. + * + * o our_id is for an active initiator role. + * Since the hardware does not support + * reselections to the initiator role at + * anything other than our_id, and our_id + * is used by the hardware to indicate the + * ID to use for both select-out and + * reselect-out operations, the only target + * ID we can support in this mode is our_id. + * + * o The MULTARGID feature is not available and + * a previous target mode ID has been enabled. + */ + if ((ahc->features & AHC_MULTIROLE) != 0) { - if (ccb->ccb_h.target_id != our_id) { if ((ahc->features & AHC_MULTI_TID) != 0 && (ahc->flags & AHC_INITIATORROLE) != 0) { /* @@ -6647,6 +6941,10 @@ */ status = CAM_TID_INVALID; } + } else if ((ahc->features & AHC_MULTI_TID) == 0 + && ahc->enabled_luns > 0) { + + status = CAM_TID_INVALID; } } @@ -6661,7 +6959,8 @@ */ if ((ahc->flags & AHC_TARGETROLE) == 0 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { - u_long s; + u_long s; + ahc_flag saved_flags; printf("Configuring Target Mode\n"); ahc_lock(ahc, &s); @@ -6670,11 +6969,29 @@ ahc_unlock(ahc, &s); return; } + saved_flags = ahc->flags; ahc->flags |= AHC_TARGETROLE; if ((ahc->features & AHC_MULTIROLE) == 0) ahc->flags &= ~AHC_INITIATORROLE; ahc_pause(ahc); - ahc_loadseq(ahc); + error = ahc_loadseq(ahc); + if (error != 0) { + /* + * Restore original configuration and notify + * the caller that we cannot support target mode. + * Since the adapter started out in this + * configuration, the firmware load will succeed, + * so there is no point in checking ahc_loadseq's + * return value. + */ + ahc->flags = saved_flags; + (void)ahc_loadseq(ahc); + ahc_restart(ahc); + ahc_unlock(ahc, &s); + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + return; + } + ahc_restart(ahc); ahc_unlock(ahc, &s); } cel = &ccb->cel; @@ -6909,8 +7226,16 @@ printf("Configuring Initiator Mode\n"); ahc->flags &= ~AHC_TARGETROLE; ahc->flags |= AHC_INITIATORROLE; - ahc_pause(ahc); - ahc_loadseq(ahc); + /* + * Returning to a configuration that + * fit previously will always succeed. + */ + (void)ahc_loadseq(ahc); + ahc_restart(ahc); + /* + * Unpaused. The extra unpause + * that follows is harmless. + */ } } ahc_unpause(ahc); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_host.h linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_host.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_host.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_host.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,96 +0,0 @@ -/* - * Adaptec AIC7xxx device driver host template for Linux. - * - * Copyright (c) 2000-2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#9 $ - */ - -#ifndef _AIC7XXX_HOST_H_ -#define _AIC7XXX_HOST_H_ - -int ahc_linux_proc_info(char *, char **, off_t, int, int, int); -int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); -int ahc_linux_detect(Scsi_Host_Template *); -int ahc_linux_release(struct Scsi_Host *); -const char *ahc_linux_info(struct Scsi_Host *); -int ahc_linux_biosparam(Disk *, kdev_t, int[]); -int ahc_linux_bus_reset(Scsi_Cmnd *); -int ahc_linux_dev_reset(Scsi_Cmnd *); -int ahc_linux_abort(Scsi_Cmnd *); - -#if defined(__i386__) -# define AIC7XXX_BIOSPARAM ahc_linux_biosparam -#else -# define AIC7XXX_BIOSPARAM NULL -#endif - -/* - * Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields - * to do with card config are filled in after the card is detected. - */ -#define AIC7XXX { \ - next: NULL, \ - module: NULL, \ - proc_dir: NULL, \ - proc_info: ahc_linux_proc_info, \ - name: NULL, \ - detect: ahc_linux_detect, \ - release: ahc_linux_release, \ - info: ahc_linux_info, \ - command: NULL, \ - queuecommand: ahc_linux_queue, \ - eh_strategy_handler: NULL, \ - eh_abort_handler: ahc_linux_abort, \ - eh_device_reset_handler: ahc_linux_dev_reset, \ - eh_bus_reset_handler: ahc_linux_bus_reset, \ - eh_host_reset_handler: NULL, \ - abort: NULL, \ - reset: NULL, \ - slave_attach: NULL, \ - bios_param: AIC7XXX_BIOSPARAM, \ - can_queue: AHC_MAX_QUEUE,/* max simultaneous cmds */\ - this_id: -1, /* scsi id of host adapter */\ - sg_tablesize: AHC_NSEG, /* max scatter-gather cmds */\ - cmd_per_lun: 2, /* cmds per lun */\ - present: 0, /* number of 7xxx's present */\ - unchecked_isa_dma: 0, /* no memory DMA restrictions*/\ - use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1, \ - highmem_io: 1, \ -} - -#endif /* _AIC7XXX_HOST_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_inline.h linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_inline.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_inline.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_inline.h 2003-08-25 04:44:42.000000000 -0700 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#35 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#43 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_inline.h,v 1.2.2.11 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ #ifndef _AIC7XXX_INLINE_H_ @@ -238,6 +238,18 @@ char channel, u_int our_id, u_int remote_id, struct ahc_tmode_tstate **tstate); +static __inline uint16_t + ahc_inw(struct ahc_softc *ahc, u_int port); +static __inline void ahc_outw(struct ahc_softc *ahc, u_int port, + u_int value); +static __inline uint32_t + ahc_inl(struct ahc_softc *ahc, u_int port); +static __inline void ahc_outl(struct ahc_softc *ahc, u_int port, + uint32_t value); +static __inline uint64_t + ahc_inq(struct ahc_softc *ahc, u_int port); +static __inline void ahc_outq(struct ahc_softc *ahc, u_int port, + uint64_t value); static __inline struct scb* ahc_get_scb(struct ahc_softc *ahc); static __inline void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb); @@ -285,6 +297,63 @@ return (&(*tstate)->transinfo[remote_id]); } +static __inline uint16_t +ahc_inw(struct ahc_softc *ahc, u_int port) +{ + return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port)); +} + +static __inline void +ahc_outw(struct ahc_softc *ahc, u_int port, u_int value) +{ + ahc_outb(ahc, port, value & 0xFF); + ahc_outb(ahc, port+1, (value >> 8) & 0xFF); +} + +static __inline uint32_t +ahc_inl(struct ahc_softc *ahc, u_int port) +{ + return ((ahc_inb(ahc, port)) + | (ahc_inb(ahc, port+1) << 8) + | (ahc_inb(ahc, port+2) << 16) + | (ahc_inb(ahc, port+3) << 24)); +} + +static __inline void +ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value) +{ + ahc_outb(ahc, port, (value) & 0xFF); + ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF); + ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF); + ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF); +} + +static __inline uint64_t +ahc_inq(struct ahc_softc *ahc, u_int port) +{ + return ((ahc_inb(ahc, port)) + | (ahc_inb(ahc, port+1) << 8) + | (ahc_inb(ahc, port+2) << 16) + | (ahc_inb(ahc, port+3) << 24) + | (((uint64_t)ahc_inb(ahc, port+4)) << 32) + | (((uint64_t)ahc_inb(ahc, port+5)) << 40) + | (((uint64_t)ahc_inb(ahc, port+6)) << 48) + | (((uint64_t)ahc_inb(ahc, port+7)) << 56)); +} + +static __inline void +ahc_outq(struct ahc_softc *ahc, u_int port, uint64_t value) +{ + ahc_outb(ahc, port, value & 0xFF); + ahc_outb(ahc, port+1, (value >> 8) & 0xFF); + ahc_outb(ahc, port+2, (value >> 16) & 0xFF); + ahc_outb(ahc, port+3, (value >> 24) & 0xFF); + ahc_outb(ahc, port+4, (value >> 32) & 0xFF); + ahc_outb(ahc, port+5, (value >> 40) & 0xFF); + ahc_outb(ahc, port+6, (value >> 48) & 0xFF); + ahc_outb(ahc, port+7, (value >> 56) & 0xFF); +} + /* * Get a free scb. If there are none, see if we can allocate a new SCB. */ @@ -386,12 +455,19 @@ scb->hscb->tag, scb->hscb->next); /* + * Setup data "oddness". + */ + scb->hscb->lun &= LID; + if (ahc_get_transfer_length(scb) & 0x1) + scb->hscb->lun |= SCB_XFERLEN_ODD; + + /* * Keep a history of SCBs we've downloaded in the qinfifo. */ ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag; /* - * Make sure our data is consistant from the + * Make sure our data is consistent from the * perspective of the adapter. */ ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); @@ -431,7 +507,7 @@ static __inline void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op); static __inline void ahc_sync_tqinfifo(struct ahc_softc *ahc, int op); static __inline u_int ahc_check_cmdcmpltqueues(struct ahc_softc *ahc); -static __inline void ahc_intr(struct ahc_softc *ahc); +static __inline int ahc_intr(struct ahc_softc *ahc); static __inline void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op) @@ -489,11 +565,20 @@ /* * Catch an interrupt from the adapter */ -static __inline void +static __inline int ahc_intr(struct ahc_softc *ahc) { u_int intstat; + if ((ahc->pause & INTEN) == 0) { + /* + * Our interrupt is not enabled on the chip + * and may be disabled for re-entrancy reasons, + * so just return. This is likely just a shared + * interrupt. + */ + return (0); + } /* * Instead of directly reading the interrupt status register, * infer the cause of the interrupt by checking our in-core @@ -507,6 +592,20 @@ intstat = ahc_inb(ahc, INTSTAT); } + if ((intstat & INT_PEND) == 0) { +#if AHC_PCI_CONFIG > 0 + if (ahc->unsolicited_ints > 500) { + ahc->unsolicited_ints = 0; + if ((ahc->chip & AHC_PCI) != 0 + && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0) + ahc->bus_intr(ahc); + } +#endif + ahc->unsolicited_ints++; + return (0); + } + ahc->unsolicited_ints = 0; + if (intstat & CMDCMPLT) { ahc_outb(ahc, CLRINT, CLRCMDINT); @@ -526,38 +625,25 @@ #endif } - if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) - /* Hot eject */ - return; - - if ((intstat & INT_PEND) == 0) { -#if AHC_PCI_CONFIG > 0 - if (ahc->unsolicited_ints > 500) { - ahc->unsolicited_ints = 0; - if ((ahc->chip & AHC_PCI) != 0 - && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0) - ahc->bus_intr(ahc); - } -#endif - ahc->unsolicited_ints++; - return; - } - ahc->unsolicited_ints = 0; - - if (intstat & BRKADRINT) { + /* + * Handle statuses that may invalidate our cached + * copy of INTSTAT separately. + */ + if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) { + /* Hot eject. Do nothing */ + } else if (intstat & BRKADRINT) { ahc_handle_brkadrint(ahc); - /* Fatal error, no more interrupts to handle. */ - return; - } + } else if ((intstat & (SEQINT|SCSIINT)) != 0) { - if ((intstat & (SEQINT|SCSIINT)) != 0) ahc_pause_bug_fix(ahc); - if ((intstat & SEQINT) != 0) - ahc_handle_seqint(ahc, intstat); + if ((intstat & SEQINT) != 0) + ahc_handle_seqint(ahc, intstat); - if ((intstat & SCSIINT) != 0) - ahc_handle_scsiint(ahc, intstat); + if ((intstat & SCSIINT) != 0) + ahc_handle_scsiint(ahc, intstat); + } + return (1); } #endif /* _AIC7XXX_INLINE_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_osm.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_osm.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_osm.c 2003-08-25 04:44:42.000000000 -0700 @@ -1,7 +1,7 @@ /* * Adaptec AIC7xxx device driver for Linux. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#103 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#234 $ * * Copyright (c) 1994 John Aycock * The University of Calgary Department of Computer Science. @@ -108,7 +108,7 @@ * but are not limited to: * * 1: Import of the latest FreeBSD sequencer code for this driver - * 2: Modification of kernel code to accomodate different sequencer semantics + * 2: Modification of kernel code to accommodate different sequencer semantics * 3: Extensive changes throughout kernel portion of driver to improve * abort/reset processing and error hanndling * 4: Other work contributed by various people on the Internet @@ -119,36 +119,37 @@ * */ -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHC_MODVERSION_FILE - #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" +#include + +/* + * Include aiclib.c as part of our + * "module dependencies are hard" work around. + */ +#include "aiclib.c" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) #include /* __setup */ #endif -#include "../sd.h" /* For geometry detection */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#include "sd.h" /* For geometry detection */ +#endif #include /* For fetching system memory size */ #include /* For block_size() */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) /* * Lock protecting manipulation of the ahc softc list. */ spinlock_t ahc_list_spinlock; -#endif -/* - * To generate the correct addresses for the controller to issue - * on the bus. Originally added for DEC Alpha support. - */ -#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a)) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* For dynamic sglist size calculation. */ +u_int ahc_linux_nseg; +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) struct proc_dir_entry proc_scsi_aic7xxx = { @@ -280,6 +281,39 @@ }; /* + * DV option: + * + * positive value = DV Enabled + * zero = DV Disabled + * negative value = DV Default for adapter type/seeprom + */ +#ifdef CONFIG_AIC7XXX_DV_SETTING +#define AIC7XXX_CONFIGED_DV CONFIG_AIC7XXX_DV_SETTING +#else +#define AIC7XXX_CONFIGED_DV -1 +#endif + +static int8_t aic7xxx_dv_settings[] = +{ + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV, + AIC7XXX_CONFIGED_DV +}; + +/* * There should be a specific return value for this in scsi.h, but * it seems that most drivers ignore it. */ @@ -325,31 +359,26 @@ * disabled at the very end. That should fix everyone up unless there are * really strange cirumstances. */ -static int aic7xxx_reverse_scan = 0; +static uint32_t aic7xxx_reverse_scan; /* * Should we force EXTENDED translation on a controller. * 0 == Use whatever is in the SEEPROM or default to off * 1 == Use whatever is in the SEEPROM or default to on */ -static uint32_t aic7xxx_extended = 0; +static uint32_t aic7xxx_extended; /* * PCI bus parity checking of the Adaptec controllers. This is somewhat * dubious at best. To my knowledge, this option has never actually * solved a PCI parity problem, but on certain machines with broken PCI - * chipset configurations, it can generate tons of false error messages. + * chipset configurations where stray PCI transactions with bad parity are + * the norm rather than the exception, the error messages can be overwelming. * It's included in the driver for completeness. - * 0 = Shut off PCI parity check - * -1 = Normal polarity pci parity checking - * 1 = reverse polarity pci parity checking - * - * NOTE: you can't actually pass -1 on the lilo prompt. So, to set this - * variable to -1 you would actually want to simply pass the variable - * name without a number. That will invert the 0 which will result in - * -1. + * 0 = Shut off PCI parity check + * non-0 = reverse polarity pci parity checking */ -static int aic7xxx_pci_parity = 0; +static uint32_t aic7xxx_pci_parity = ~0; /* * Certain newer motherboards have put new PCI based devices into the @@ -362,15 +391,20 @@ * would result in never finding any devices :) */ #ifndef CONFIG_AIC7XXX_PROBE_EISA_VL -#define CONFIG_AIC7XXX_PROBE_EISA_VL n -#endif -#if CONFIG_AIC7XXX_PROBE_EISA_VL == n -static int aic7xxx_no_probe = 1; +uint32_t aic7xxx_probe_eisa_vl; #else -static int aic7xxx_no_probe; +uint32_t aic7xxx_probe_eisa_vl = ~0; #endif /* + * There are lots of broken chipsets in the world. Some of them will + * violate the PCI spec when we issue byte sized memory writes to our + * controller. I/O mapped register access, if allowed by the given + * platform, will work in almost all cases. + */ +uint32_t aic7xxx_allow_memio = ~0; + +/* * aic7xxx_detect() has been run, so register all device arrivals * immediately with the system rather than deferring to the sorted * attachment performed by aic7xxx_detect(). @@ -387,7 +421,7 @@ * We default to 256ms because some older devices need a longer time * to respond to initial selection. */ -static int aic7xxx_seltime = 0x00; +static uint32_t aic7xxx_seltime; /* * Certain devices do not perform any aging on commands. Should the @@ -397,7 +431,7 @@ * force all outstanding transactions to be serviced prior to a new * transaction. */ -int aic7xxx_periodic_otag; +uint32_t aic7xxx_periodic_otag; /* * Module information and settable options. @@ -413,49 +447,99 @@ MODULE_AUTHOR("Maintainer: Justin T. Gibbs "); MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10) +#ifdef MODULE_LICENSE MODULE_LICENSE("Dual BSD/GPL"); #endif MODULE_PARM(aic7xxx, "s"); -MODULE_PARM_DESC(aic7xxx, "period delimited, options string.\n" +MODULE_PARM_DESC(aic7xxx, +"period delimited, options string.\n" " verbose Enable verbose/diagnostic logging\n" -" no_probe Disable EISA/VLB controller probing\n" +" allow_memio Allow device registers to be memory mapped\n" +" debug Bitmask of debug values to enable\n" +" no_probe Toggle EISA/VLB controller probing\n" +" probe_eisa_vl Toggle EISA/VLB controller probing\n" " no_reset Supress initial bus resets\n" " extended Enable extended geometry on all controllers\n" -" periodic_otag Send an ordered tagged transaction periodically\n" -" to prevent tag starvation. This may be\n" -" required by some older disk drives/RAID arrays.\n" +" periodic_otag Send an ordered tagged transaction\n" +" periodically to prevent tag starvation.\n" +" This may be required by some older disk\n" +" drives or RAID arrays.\n" " reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" " tag_info: Set per-target tag depth\n" -" seltime: Selection Timeout(0/256ms,1/128ms,2/64ms,3/32ms)\n" +" global_tag_depth: Global tag depth for every target\n" +" on every bus\n" +" dv: Set per-controller Domain Validation Setting.\n" +" seltime: Selection Timeout\n" +" (0/256ms,1/128ms,2/64ms,3/32ms)\n" "\n" " Sample /etc/modules.conf line:\n" -" Enable verbose logging\n" -" Disable EISA/VLB probing\n" -" Set tag depth on Controller 2/Target 2 to 10 tags\n" -" Shorten the selection timeout to 128ms from its default of 256\n" +" Toggle EISA/VLB probing\n" +" Set tag depth on Controller 1/Target 1 to 10 tags\n" +" Shorten the selection timeout to 128ms\n" "\n" -" options aic7xxx='\"verbose.no_probe.tag_info:{{}.{}.{..10}}.seltime:1\"'" +" options aic7xxx 'aic7xxx=probe_eisa_vl.tag_info:{{}.{.10}}.seltime:1'\n" ); #endif static void ahc_linux_handle_scsi_status(struct ahc_softc *, struct ahc_linux_device *, struct scb *); -static void ahc_linux_filter_command(struct ahc_softc*, Scsi_Cmnd*, - struct scb*); +static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, + Scsi_Cmnd *cmd); +static void ahc_linux_filter_inquiry(struct ahc_softc*, struct ahc_devinfo*); static void ahc_linux_sem_timeout(u_long arg); -static void ahc_linux_freeze_sim_queue(struct ahc_softc *ahc); -static void ahc_linux_release_sim_queue(u_long arg); +static void ahc_linux_freeze_simq(struct ahc_softc *ahc); +static void ahc_linux_release_simq(u_long arg); static void ahc_linux_dev_timed_unfreeze(u_long arg); static int ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); -static void ahc_linux_select_queue_depth(struct Scsi_Host *host, - Scsi_Device *scsi_devs); +static void ahc_linux_size_nseg(void); +static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc); +static void ahc_linux_start_dv(struct ahc_softc *ahc); +static void ahc_linux_dv_timeout(struct scsi_cmnd *cmd); +static int ahc_linux_dv_thread(void *data); +static void ahc_linux_kill_dv_thread(struct ahc_softc *ahc); +static void ahc_linux_dv_target(struct ahc_softc *ahc, u_int target); +static void ahc_linux_dv_transition(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo); +static void ahc_linux_dv_inq(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ, + u_int request_length); +static void ahc_linux_dv_tur(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo); +static void ahc_linux_dv_rebd(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_web(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_reb(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static void ahc_linux_dv_su(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ); +static int ahc_linux_fallback(struct ahc_softc *ahc, + struct ahc_devinfo *devinfo); +static void ahc_linux_dv_complete(Scsi_Cmnd *cmd); +static void ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ); static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo); +static u_int ahc_linux_user_dv_setting(struct ahc_softc *ahc); static void ahc_linux_device_queue_depth(struct ahc_softc *ahc, - Scsi_Device *device); + struct ahc_linux_device *dev); static struct ahc_linux_target* ahc_linux_alloc_target(struct ahc_softc*, u_int, u_int); static void ahc_linux_free_target(struct ahc_softc*, @@ -467,34 +551,60 @@ struct ahc_linux_device*); static void ahc_linux_run_device_queue(struct ahc_softc*, struct ahc_linux_device*); -static void ahc_linux_setup_tag_info(char *p, char *end); -static int ahc_linux_next_unit(void); +static void ahc_linux_setup_tag_info_global(char *p); +static aic_option_callback_t ahc_linux_setup_tag_info; +static aic_option_callback_t ahc_linux_setup_dv; +static int aic7xxx_setup(char *s); +static int ahc_linux_next_unit(void); static void ahc_runq_tasklet(unsigned long data); -static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf); +static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc); +/********************************* Inlines ************************************/ +static __inline void ahc_schedule_runq(struct ahc_softc *ahc); static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, u_int lun, int alloc); -static __inline void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, - Scsi_Cmnd *cmd); -static __inline void ahc_linux_run_complete_queue(struct ahc_softc *ahc, - struct ahc_cmd *acmd); +static __inline void ahc_schedule_completeq(struct ahc_softc *ahc); static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev); static __inline struct ahc_linux_device * ahc_linux_next_device_to_run(struct ahc_softc *ahc); static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc); -static __inline void ahc_linux_sniff_command(struct ahc_softc*, Scsi_Cmnd*, - struct scb*); static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, struct ahc_dma_seg *sg, bus_addr_t addr, bus_size_t len); +static __inline void +ahc_schedule_completeq(struct ahc_softc *ahc) +{ + if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) { + ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER; + ahc->platform_data->completeq_timer.expires = jiffies; + add_timer(&ahc->platform_data->completeq_timer); + } +} + +/* + * Must be called with our lock held. + */ +static __inline void +ahc_schedule_runq(struct ahc_softc *ahc) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_schedule(&ahc->platform_data->runq_tasklet); +#else + /* + * Tasklets are not available, so run inline. + */ + ahc_runq_tasklet((unsigned long)ahc); +#endif +} + static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, - u_int lun, int alloc) + u_int lun, int alloc) { struct ahc_linux_target *targ; struct ahc_linux_device *dev; @@ -518,62 +628,43 @@ return (dev); } -static __inline void -ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) +#define AHC_LINUX_MAX_RETURNED_ERRORS 4 +static struct ahc_cmd * +ahc_linux_run_complete_queue(struct ahc_softc *ahc) { - /* - * Typically, the complete queue has very few entries - * queued to it before the queue is emptied by - * ahc_linux_run_complete_queue, so sorting the entries - * by generation number should be inexpensive. - * We perform the sort so that commands that complete - * with an error are retuned in the order origionally - * queued to the controller so that any subsequent retries - * are performed in order. The underlying ahc routines do - * not guarantee the order that aborted commands will be - * returned to us. - */ - struct ahc_completeq *completeq; - struct ahc_cmd *list_cmd; - struct ahc_cmd *acmd; - - /* - * If we want the request requeued, make sure there - * are sufficent retries. In the old scsi error code, - * we used to be able to specify a result code that - * bypassed the retry count. Now we must use this - * hack. - */ - if (cmd->result == (CAM_REQUEUE_REQ << 16)) - cmd->retries--; - completeq = &ahc->platform_data->completeq; - list_cmd = TAILQ_FIRST(completeq); - acmd = (struct ahc_cmd *)cmd; - while (list_cmd != NULL - && acmd_scsi_cmd(list_cmd).serial_number - < acmd_scsi_cmd(acmd).serial_number) - list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); - if (list_cmd != NULL) - TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); - else - TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); -} - -static __inline void -ahc_linux_run_complete_queue(struct ahc_softc *ahc, struct ahc_cmd *acmd) -{ - u_long done_flags; + struct ahc_cmd *acmd; + u_long done_flags; + int with_errors; + with_errors = 0; ahc_done_lock(ahc, &done_flags); - while (acmd != NULL) { + while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) { Scsi_Cmnd *cmd; + if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) { + /* + * Linux uses stack recursion to requeue + * commands that need to be retried. Avoid + * blowing out the stack by "spoon feeding" + * commands that completed with error back + * the operating system in case they are going + * to be retried. "ick" + */ + ahc_schedule_completeq(ahc); + break; + } + TAILQ_REMOVE(&ahc->platform_data->completeq, + acmd, acmd_links.tqe); cmd = &acmd_scsi_cmd(acmd); - acmd = TAILQ_NEXT(acmd, acmd_links.tqe); cmd->host_scribble = NULL; + if (ahc_cmd_get_transaction_status(cmd) != DID_OK + || (cmd->result & 0xFF) != SCSI_STATUS_OK) + with_errors++; + cmd->scsi_done(cmd); } ahc_done_unlock(ahc, &done_flags); + return (acmd); } static __inline void @@ -598,7 +689,8 @@ { if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0 - || ahc->platform_data->qfrozen != 0) + || (ahc->platform_data->qfrozen != 0 + && AHC_DV_SIMQ_FROZEN(ahc) == 0)) return (NULL); return (TAILQ_FIRST(&ahc->platform_data->device_runq)); } @@ -616,19 +708,6 @@ } static __inline void -ahc_linux_sniff_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb) -{ - /* - * Determine whether we care to filter - * information out of this command. If so, - * pass it on to ahc_linux_filter_command() for more - * heavy weight processing. - */ - if (cmd->cmnd[0] == INQUIRY) - ahc_linux_filter_command(ahc, cmd, scb); -} - -static __inline void ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) { Scsi_Cmnd *cmd; @@ -662,906 +741,2808 @@ consumed = 1; sg->addr = ahc_htole32(addr & 0xFFFFFFFF); scb->platform_data->xfer_len += len; + if (sizeof(bus_addr_t) > 4 - && (ahc->flags & AHC_39BIT_ADDRESSING) != 0) { - /* - * Due to DAC restrictions, we can't - * cross a 4GB boundary. - */ - if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) { - struct ahc_dma_seg *next_sg; - uint32_t next_len; - - printf("Crossed Seg\n"); - if ((scb->sg_count + 2) > AHC_NSEG) - panic("Too few segs for dma mapping. " - "Increase AHC_NSEG\n"); - - consumed++; - next_sg = sg + 1; - next_sg->addr = 0; - next_len = 0x100000000 - (addr & 0xFFFFFFFF); - len -= next_len; - next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000; - next_sg->len = ahc_htole32(next_len); - } - len |= (addr >> 8) & 0x7F000000; - } + && (ahc->flags & AHC_39BIT_ADDRESSING) != 0) + len |= (addr >> 8) & AHC_SG_HIGH_ADDR_MASK; + sg->len = ahc_htole32(len); return (consumed); } -/**************************** Tasklet Handler *********************************/ +/************************ Host template entry points *************************/ +static int ahc_linux_detect(Scsi_Host_Template *); +static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); +static const char *ahc_linux_info(struct Scsi_Host *); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int ahc_linux_slave_alloc(Scsi_Device *); +static int ahc_linux_slave_configure(Scsi_Device *); +static void ahc_linux_slave_destroy(Scsi_Device *); +#if defined(__i386__) +static int ahc_linux_biosparam(struct scsi_device*, + struct block_device*, + sector_t, int[]); +#endif +#else +static int ahc_linux_release(struct Scsi_Host *); +static void ahc_linux_select_queue_depth(struct Scsi_Host *host, + Scsi_Device *scsi_devs); +#if defined(__i386__) +static int ahc_linux_biosparam(Disk *, kdev_t, int[]); +#endif +#endif +static int ahc_linux_bus_reset(Scsi_Cmnd *); +static int ahc_linux_dev_reset(Scsi_Cmnd *); +static int ahc_linux_abort(Scsi_Cmnd *); +/* + * Calculate a safe value for AHC_NSEG (as expressed through ahc_linux_nseg). + * + * In pre-2.5.X... + * The midlayer allocates an S/G array dynamically when a command is issued + * using SCSI malloc. This array, which is in an OS dependent format that + * must later be copied to our private S/G list, is sized to house just the + * number of segments needed for the current transfer. Since the code that + * sizes the SCSI malloc pool does not take into consideration fragmentation + * of the pool, executing transactions numbering just a fraction of our + * concurrent transaction limit with list lengths aproaching AHC_NSEG will + * quickly depleat the SCSI malloc pool of usable space. Unfortunately, the + * mid-layer does not properly handle this scsi malloc failures for the S/G + * array and the result can be a lockup of the I/O subsystem. We try to size + * our S/G list so that it satisfies our drivers allocation requirements in + * addition to avoiding fragmentation of the SCSI malloc pool. + */ static void -ahc_runq_tasklet(unsigned long data) +ahc_linux_size_nseg(void) { - struct ahc_softc* ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = (struct ahc_softc *)data; - ahc_lock(ahc, &flags); - while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { - - TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); - dev->flags &= ~AHC_DEV_ON_RUN_LIST; - ahc_linux_check_device_queue(ahc, dev); - /* Yeild to our interrupt handler */ - ahc_unlock(ahc, &flags); - ahc_lock(ahc, &flags); - } - ahc_unlock(ahc, &flags); -} - -/************************ Shutdown/halt/reboot hook ***************************/ -#include -#include - -static struct notifier_block ahc_linux_notifier = { - ahc_linux_halt, NULL, 0 -}; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + u_int cur_size; + u_int best_size; -static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf) -{ - struct ahc_softc *ahc; + /* + * The SCSI allocator rounds to the nearest 512 bytes + * an cannot allocate across a page boundary. Our algorithm + * is to start at 1K of scsi malloc space per-command and + * loop through all factors of the PAGE_SIZE and pick the best. + */ + best_size = 0; + for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) { + u_int nseg; + + nseg = cur_size / sizeof(struct scatterlist); + if (nseg < AHC_LINUX_MIN_NSEG) + continue; + + if (best_size == 0) { + best_size = cur_size; + ahc_linux_nseg = nseg; + } else { + u_int best_rem; + u_int cur_rem; - if (event == SYS_DOWN || event == SYS_HALT) { - TAILQ_FOREACH(ahc, &ahc_tailq, links) { - ahc_shutdown(ahc); + /* + * Compare the traits of the current "best_size" + * with the current size to determine if the + * current size is a better size. + */ + best_rem = best_size % sizeof(struct scatterlist); + cur_rem = cur_size % sizeof(struct scatterlist); + if (cur_rem < best_rem) { + best_size = cur_size; + ahc_linux_nseg = nseg; + } } } - return (NOTIFY_OK); +#endif } -/******************************** Macros **************************************/ -#define BUILD_SCSIID(ahc, cmd) \ - ((((cmd)->target << TID_SHIFT) & TID) \ - | (((cmd)->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \ - | (((cmd)->channel == 0) ? 0 : TWIN_CHNLB)) - -/******************************** Bus DMA *************************************/ -int -ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent, - bus_size_t alignment, bus_size_t boundary, - bus_addr_t lowaddr, bus_addr_t highaddr, - bus_dma_filter_t *filter, void *filterarg, - bus_size_t maxsize, int nsegments, - bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) +/* + * Try to detect an Adaptec 7XXX controller. + */ +static int +ahc_linux_detect(Scsi_Host_Template *template) { - bus_dma_tag_t dmat; - - dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT); - if (dmat == NULL) - return (ENOMEM); + struct ahc_softc *ahc; + int found; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* - * Linux is very simplistic about DMA memory. For now don't - * maintain all specification information. Once Linux supplies - * better facilities for doing these operations, or the - * needs of this particular driver change, we might need to do - * more here. + * It is a bug that the upper layer takes + * this lock just prior to calling us. */ - dmat->alignment = alignment; - dmat->boundary = boundary; - dmat->maxsize = maxsize; - *ret_tag = dmat; - return (0); -} - -void -ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat) -{ - free(dmat, M_DEVBUF); -} - -int -ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, - int flags, bus_dmamap_t *mapp) -{ - bus_dmamap_t map; + spin_unlock_irq(&io_request_lock); +#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); - if (map == NULL) - return (ENOMEM); /* - * Although we can dma data above 4GB, our - * "consistent" memory is below 4GB for - * space efficiency reasons (only need a 4byte - * address). For this reason, we have to reset - * our dma mask when doing allocations. + * Sanity checking of Linux SCSI data structures so + * that some of our hacks^H^H^H^H^Hassumptions aren't + * violated. */ - if (ahc->dev_softc != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) - pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF); -#else - ahc->dev_softc->dma_mask = 0xFFFFFFFF; -#endif - } - *vaddr = pci_alloc_consistent(ahc->dev_softc, - dmat->maxsize, &map->bus_addr); - if (ahc->dev_softc != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) - pci_set_dma_mask(ahc->dev_softc, - ahc->platform_data->hw_dma_mask); -#else - ahc->dev_softc->dma_mask = ahc->platform_data->hw_dma_mask; -#endif + if (offsetof(struct ahc_cmd_internal, end) + > offsetof(struct scsi_cmnd, host_scribble)) { + printf("ahc_linux_detect: SCSI data structures changed.\n"); + printf("ahc_linux_detect: Unable to attach\n"); + return (0); } -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ + ahc_linux_size_nseg(); +#ifdef MODULE /* - * At least in 2.2.14, malloc is a slab allocator so all - * allocations are aligned. We assume for these kernel versions - * that all allocations will be bellow 4Gig, physically contiguous, - * and accessable via DMA by the controller. + * If we've been passed any parameters, process them now. */ - map = NULL; /* No additional information to store */ - *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); + if (aic7xxx) + aic7xxx_setup(aic7xxx); + if (dummy_buffer[0] != 'P') + printk(KERN_WARNING +"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n" +"aic7xxx: to see the proper way to specify options to the aic7xxx module\n" +"aic7xxx: Specifically, don't use any commas when passing arguments to\n" +"aic7xxx: insmod or else it might trash certain memory areas.\n"); #endif - if (*vaddr == NULL) - return (ENOMEM); - *mapp = map; - return(0); -} -void -ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, - void* vaddr, bus_dmamap_t map) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - pci_free_consistent(ahc->dev_softc, dmat->maxsize, - vaddr, map->bus_addr); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) + template->proc_name = "aic7xxx"; #else - free(vaddr, M_DEVBUF); + template->proc_dir = &proc_scsi_aic7xxx; #endif -} -int -ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, - void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, - void *cb_arg, int flags) -{ /* - * Assume for now that this will only be used during - * initialization and not for per-transaction buffer mapping. + * Initialize our softc list lock prior to + * probing for any adapters. */ - bus_dma_segment_t stack_sg; + ahc_list_lockinit(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - stack_sg.ds_addr = map->bus_addr; -#else - stack_sg.ds_addr = VIRT_TO_BUS(buf); +#ifdef CONFIG_PCI + ahc_linux_pci_init(); +#endif + +#ifdef CONFIG_EISA + ahc_linux_eisa_init(); #endif - stack_sg.ds_len = dmat->maxsize; - cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); - return (0); -} -void -ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) -{ /* - * The map may is NULL in our < 2.3.X implementation. + * Register with the SCSI layer all + * controllers we've found. */ - if (map != NULL) - free(map, M_DEVBUF); -} + found = 0; + TAILQ_FOREACH(ahc, &ahc_tailq, links) { -int -ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) -{ - /* Nothing to do */ - return (0); + if (ahc_linux_register_host(ahc, template) == 0) + found++; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + aic7xxx_detect_complete++; + return (found); } -/********************* Platform Dependent Functions ***************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* + * Free the passed in Scsi_Host memory structures prior to unloading the + * module. + */ int -ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) +ahc_linux_release(struct Scsi_Host * host) { - int value; - int rvalue; - int lvalue; - - /* - * Under Linux, cards are ordered as follows: - * 1) VLB/EISA BIOS enabled devices sorted by BIOS address. - * 2) PCI devices with BIOS enabled sorted by bus/slot/func. - * 3) All remaining VLB/EISA devices sorted by ioport. - * 4) All remaining PCI devices sorted by bus/slot/func. - */ - value = (lahc->flags & AHC_BIOS_ENABLED) - - (rahc->flags & AHC_BIOS_ENABLED); - if (value != 0) - /* Controllers with BIOS enabled have a *higher* priority */ - return (-value); - - /* - * Same BIOS setting, now sort based on bus type. - * EISA and VL controllers sort together. EISA/VL - * have higher priority than PCI. - */ - rvalue = (rahc->chip & AHC_BUS_MASK); - if (rvalue == AHC_VL) - rvalue = AHC_EISA; - lvalue = (lahc->chip & AHC_BUS_MASK); - if (lvalue == AHC_VL) - lvalue = AHC_EISA; - value = lvalue - rvalue; - if (value != 0) - return (value); + struct ahc_softc *ahc; + u_long l; - /* Still equal. Sort by BIOS address, ioport, or bus/slot/func. */ - switch (rvalue) { - case AHC_PCI: - { - char primary_channel; + ahc_list_lock(&l); + if (host != NULL) { - if (aic7xxx_reverse_scan != 0) - value = ahc_get_pci_bus(rahc->dev_softc) - - ahc_get_pci_bus(lahc->dev_softc); - else - value = ahc_get_pci_bus(lahc->dev_softc) - - ahc_get_pci_bus(rahc->dev_softc); - if (value != 0) - break; - if (aic7xxx_reverse_scan != 0) - value = ahc_get_pci_slot(rahc->dev_softc) - - ahc_get_pci_slot(lahc->dev_softc); - else - value = ahc_get_pci_slot(lahc->dev_softc) - - ahc_get_pci_slot(rahc->dev_softc); - if (value != 0) - break; /* - * On multi-function devices, the user can choose - * to have function 1 probed before function 0. - * Give whichever channel is the primary channel - * the lowest priority. + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. */ - primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A'; - value = 1; - if (lahc->channel == primary_channel) - value = -1; - break; - } - case AHC_EISA: - if ((rahc->flags & AHC_BIOS_ENABLED) != 0) { - value = lahc->platform_data->bios_address - - rahc->platform_data->bios_address; - } else { - value = lahc->bsh.ioport - - rahc->bsh.ioport; + ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); + if (ahc != NULL) { + u_long s; + + ahc_lock(ahc, &s); + ahc_intr_enable(ahc, FALSE); + ahc_unlock(ahc, &s); + ahc_free(ahc); } - break; - default: - panic("ahc_softc_sort: invalid bus type"); } - return (value); + ahc_list_unlock(&l); + return (0); } +#endif -static void -ahc_linux_setup_tag_info(char *p, char *end) +/* + * Return a string describing the driver. + */ +static const char * +ahc_linux_info(struct Scsi_Host *host) { - char *base; - char *tok; - char *tok_end; - char *tok_end2; - int i; - int instance; - int targ; - int done; - char tok_list[] = {'.', ',', '{', '}', '\0'}; + static char buffer[512]; + char ahc_info[256]; + char *bp; + struct ahc_softc *ahc; - if (*p != ':') - return; + bp = &buffer[0]; + ahc = *(struct ahc_softc **)host->hostdata; + memset(bp, 0, sizeof(buffer)); + strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev "); + strcat(bp, AIC7XXX_DRIVER_VERSION); + strcat(bp, "\n"); + strcat(bp, " <"); + strcat(bp, ahc->description); + strcat(bp, ">\n"); + strcat(bp, " "); + ahc_controller_info(ahc, ahc_info); + strcat(bp, ahc_info); + strcat(bp, "\n"); - instance = -1; - targ = -1; - done = FALSE; - base = p; - /* Forward us just past the ':' */ - tok = base + 1; - tok_end = strchr(tok, '\0'); - if (tok_end < end) - *tok_end = ','; - while (!done) { - switch (*tok) { - case '{': - if (instance == -1) - instance = 0; - else if (targ == -1) - targ = 0; - tok++; - break; - case '}': - if (targ != -1) - targ = -1; - else if (instance != -1) - instance = -1; - tok++; - break; - case ',': - case '.': - if (instance == -1) - done = TRUE; - else if (targ >= 0) - targ++; - else if (instance >= 0) - instance++; - if ((targ >= AHC_NUM_TARGETS) || - (instance >= NUM_ELEMENTS(aic7xxx_tag_info))) - done = TRUE; - tok++; - if (!done) { - base = tok; - } - break; - case '\0': - done = TRUE; - break; - default: - done = TRUE; - tok_end = strchr(tok, '\0'); - for (i = 0; tok_list[i]; i++) { - tok_end2 = strchr(tok, tok_list[i]); - if ((tok_end2) && (tok_end2 < tok_end)) { - tok_end = tok_end2; - done = FALSE; - } - } - if ((instance >= 0) && (targ >= 0) - && (instance < NUM_ELEMENTS(aic7xxx_tag_info)) - && (targ < AHC_NUM_TARGETS)) { - aic7xxx_tag_info[instance].tag_commands[targ] = - simple_strtoul(tok, NULL, 0) & 0xff; - } - tok = tok_end; - break; - } - } - while ((p != base) && (p != NULL)) - p = strtok(NULL, ",."); + return (bp); } /* - * Handle Linux boot parameters. This routine allows for assigning a value - * to a parameter with a ':' between the parameter and the value. - * ie. aic7xxx=stpwlev:1,extended + * Queue an SCB to the controller. */ -int -aic7xxx_setup(char *s) +static int +ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) { - int i, n; - char *p; - char *end; + struct ahc_softc *ahc; + struct ahc_linux_device *dev; + u_long flags; - static struct { - const char *name; - uint32_t *flag; - } options[] = { - { "extended", &aic7xxx_extended }, - { "no_reset", &aic7xxx_no_reset }, - { "verbose", &aic7xxx_verbose }, - { "reverse_scan", &aic7xxx_reverse_scan }, - { "no_probe", &aic7xxx_no_probe }, - { "periodic_otag", &aic7xxx_periodic_otag }, - { "pci_parity", &aic7xxx_pci_parity }, - { "seltime", &aic7xxx_seltime }, - { "tag_info", NULL } - }; + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; - end = strchr(s, '\0'); + /* + * Save the callback on completion function. + */ + cmd->scsi_done = scsi_done; - for (p = strtok(s, ",."); p; p = strtok(NULL, ",.")) { - for (i = 0; i < NUM_ELEMENTS(options); i++) { - n = strlen(options[i].name); + ahc_midlayer_entrypoint_lock(ahc, &flags); - if (strncmp(options[i].name, p, n) != 0) - continue; + /* + * Close the race of a command that was in the process of + * being queued to us just as our simq was frozen. Let + * DV commands through so long as we are only frozen to + * perform DV. + */ + if (ahc->platform_data->qfrozen != 0 + && AHC_DV_CMD(cmd) == 0) { - if (strncmp(p, "tag_info", n) == 0) { - ahc_linux_setup_tag_info(p + n, end); - } else if (p[n] == ':') { - *(options[i].flag) = - simple_strtoul(p + n + 1, NULL, 0); - } else if (!strncmp(p, "verbose", n)) { - *(options[i].flag) = 1; - } else { - *(options[i].flag) = ~(*(options[i].flag)); - } - break; - } + ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); + ahc_linux_queue_cmd_complete(ahc, cmd); + ahc_schedule_completeq(ahc); + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); } - return 1; + dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/TRUE); + if (dev == NULL) { + ahc_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL); + ahc_linux_queue_cmd_complete(ahc, cmd); + ahc_schedule_completeq(ahc); + ahc_midlayer_entrypoint_unlock(ahc, &flags); + printf("%s: aic7xxx_linux_queue - Unable to allocate device!\n", + ahc_name(ahc)); + return (0); + } + cmd->result = CAM_REQ_INPROG << 16; + TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); + if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); + dev->flags |= AHC_DEV_ON_RUN_LIST; + ahc_linux_run_device_queues(ahc); + } + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) -__setup("aic7xxx=", aic7xxx_setup); -#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int +ahc_linux_slave_alloc(Scsi_Device *device) +{ + struct ahc_softc *ahc; -int aic7xxx_verbose; + ahc = *((struct ahc_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id); + return (0); +} -/* - * Try to detect an Adaptec 7XXX controller. - */ -int -ahc_linux_detect(Scsi_Host_Template *template) +static int +ahc_linux_slave_configure(Scsi_Device *device) { struct ahc_softc *ahc; - int found; + struct ahc_linux_device *dev; + u_long flags; + ahc = *((struct ahc_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id); + ahc_midlayer_entrypoint_lock(ahc, &flags); /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. */ - spin_unlock_irq(&io_request_lock); + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHC_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahc_linux_device_queue_depth(ahc, dev); + } + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); +} + +static void +ahc_linux_slave_destroy(Scsi_Device *device) +{ + struct ahc_softc *ahc; + struct ahc_linux_device *dev; + u_long flags; + ahc = *((struct ahc_softc **)device->host->hostdata); + if (bootverbose) + printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id); + ahc_midlayer_entrypoint_lock(ahc, &flags); + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/FALSE); /* - * Sanity checking of Linux SCSI data structures so - * that some of our hacks^H^H^H^H^Hassumptions aren't - * violated. + * Filter out "silly" deletions of real devices by only + * deleting devices that have had slave_configure() + * called on them. All other devices that have not + * been configured will automatically be deleted by + * the refcounting process. */ - if (offsetof(struct ahc_cmd_internal, end) - > offsetof(struct scsi_cmnd, host_scribble)) { - printf("ahc_linux_detect: SCSI data structures changed.\n"); - printf("ahc_linux_detect: Unable to attach\n"); - return (0); + if (dev != NULL + && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) { + dev->flags |= AHC_DEV_UNCONFIGURED; + if (TAILQ_EMPTY(&dev->busyq) + && dev->active == 0 + && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) + ahc_linux_free_device(ahc, dev); } -#ifdef MODULE - /* - * If we've been passed any parameters, process them now. - */ - if (aic7xxx) - aic7xxx_setup(aic7xxx); - if (dummy_buffer[0] != 'P') - printk(KERN_WARNING -"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n" -"aic7xxx: to see the proper way to specify options to the aic7xxx module\n" -"aic7xxx: Specifically, don't use any commas when passing arguments to\n" -"aic7xxx: insmod or else it might trash certain memory areas.\n"); + ahc_midlayer_entrypoint_unlock(ahc, &flags); +} +#else +/* + * Sets the queue depth for each SCSI device hanging + * off the input host adapter. + */ +static void +ahc_linux_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) +{ + Scsi_Device *device; + Scsi_Device *ldev; + struct ahc_softc *ahc; + u_long flags; + + ahc = *((struct ahc_softc **)host->hostdata); + ahc_lock(ahc, &flags); + for (device = scsi_devs; device != NULL; device = device->next) { + + /* + * Watch out for duplicate devices. This works around + * some quirks in how the SCSI scanning code does its + * device management. + */ + for (ldev = scsi_devs; ldev != device; ldev = ldev->next) { + if (ldev->host == device->host + && ldev->channel == device->channel + && ldev->id == device->id + && ldev->lun == device->lun) + break; + } + /* Skip duplicate. */ + if (ldev != device) + continue; + + if (device->host == host) { + struct ahc_linux_device *dev; + + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHC_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahc_linux_device_queue_depth(ahc, dev); + device->queue_depth = dev->openings + + dev->active; + if ((dev->flags & (AHC_DEV_Q_BASIC + | AHC_DEV_Q_TAGGED)) == 0) { + /* + * We allow the OS to queue 2 untagged + * transactions to us at any time even + * though we can only execute them + * serially on the controller/device. + * This should remove some latency. + */ + device->queue_depth = 2; + } + } + } + } + ahc_unlock(ahc, &flags); +} #endif -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) - template->proc_name = "aic7xxx"; +#if defined(__i386__) +/* + * Return the disk geometry for the given SCSI device. + */ +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]) +{ + uint8_t *bh; #else - template->proc_dir = &proc_scsi_aic7xxx; +ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) +{ + struct scsi_device *sdev = disk->device; + u_long capacity = disk->capacity; + struct buffer_head *bh; +#endif + int heads; + int sectors; + int cylinders; + int ret; + int extended; + struct ahc_softc *ahc; + u_int channel; + + ahc = *((struct ahc_softc **)sdev->host->hostdata); + channel = sdev->channel; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + bh = scsi_bios_ptable(bdev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); +#else + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); +#endif + + if (bh) { + ret = scsi_partsize(bh, capacity, + &geom[2], &geom[0], &geom[1]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + kfree(bh); +#else + brelse(bh); +#endif + if (ret != -1) + return (ret); + } + heads = 64; + sectors = 32; + cylinders = aic_sector_div(capacity, heads, sectors); + + if (aic7xxx_extended != 0) + extended = 1; + else if (channel == 0) + extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0; + else + extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0; + if (extended && cylinders >= 1024) { + heads = 255; + sectors = 63; + cylinders = aic_sector_div(capacity, heads, sectors); + } + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + return (0); +} #endif +/* + * Abort the current SCSI command(s). + */ +static int +ahc_linux_abort(Scsi_Cmnd *cmd) +{ + int error; + + error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT); + if (error != 0) + printf("aic7xxx_abort returns 0x%x\n", error); + return (error); +} + +/* + * Attempt to send a target reset message to the device that timed out. + */ +static int +ahc_linux_dev_reset(Scsi_Cmnd *cmd) +{ + int error; + + error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); + if (error != 0) + printf("aic7xxx_dev_reset returns 0x%x\n", error); + return (error); +} + +/* + * Reset the SCSI bus. + */ +static int +ahc_linux_bus_reset(Scsi_Cmnd *cmd) +{ + struct ahc_softc *ahc; + u_long s; + int found; + + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; + ahc_midlayer_entrypoint_lock(ahc, &s); + found = ahc_reset_channel(ahc, cmd->device->channel + 'A', + /*initiate reset*/TRUE); + ahc_linux_run_complete_queue(ahc); + ahc_midlayer_entrypoint_unlock(ahc, &s); + + if (bootverbose) + printf("%s: SCSI bus reset delivered. " + "%d SCBs aborted.\n", ahc_name(ahc), found); + + return SUCCESS; +} + +Scsi_Host_Template aic7xxx_driver_template = { + .module = THIS_MODULE, + .name = "aic7xxx", + .proc_info = ahc_linux_proc_info, + .info = ahc_linux_info, + .queuecommand = ahc_linux_queue, + .eh_abort_handler = ahc_linux_abort, + .eh_device_reset_handler = ahc_linux_dev_reset, + .eh_bus_reset_handler = ahc_linux_bus_reset, +#if defined(__i386__) + .bios_param = ahc_linux_biosparam, +#endif + .can_queue = AHC_MAX_QUEUE, + .this_id = -1, + .cmd_per_lun = 2, + .use_clustering = ENABLE_CLUSTERING, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) /* * We can only map 16MB per-SG * so create a sector limit of * "16MB" in 2K sectors. */ - template->max_sectors = 8192; + .max_sectors = 8192, #endif - - /* - * Initialize our softc list lock prior to - * probing for any adapters. - */ - ahc_list_lockinit(); - -#ifdef CONFIG_PCI - ahc_linux_pci_probe(template); +#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) +/* Assume RedHat Distribution with its different HIGHIO conventions. */ + .can_dma_32 = 1, + .single_sg_okay = 1, +#else + .highmem_io = 1, +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + .slave_alloc = ahc_linux_slave_alloc, + .slave_configure = ahc_linux_slave_configure, + .slave_destroy = ahc_linux_slave_destroy, +#else + .detect = ahc_linux_detect, + .release = ahc_linux_release, + .select_queue_depths = ahc_linux_select_queue_depth, + .use_new_eh_code = 1, #endif +}; - if (aic7xxx_no_probe == 0) - aic7770_linux_probe(template); +/**************************** Tasklet Handler *********************************/ - /* - * Register with the SCSI layer all - * controllers we've found. - */ - spin_lock_irq(&io_request_lock); - found = 0; - TAILQ_FOREACH(ahc, &ahc_tailq, links) { +/* + * In 2.4.X and above, this routine is called from a tasklet, + * so we must re-acquire our lock prior to executing this code. + * In all prior kernels, ahc_schedule_runq() calls this routine + * directly and ahc_schedule_runq() is called with our lock held. + */ +static void +ahc_runq_tasklet(unsigned long data) +{ + struct ahc_softc* ahc; + struct ahc_linux_device *dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + u_long flags; +#endif - if (ahc_linux_register_host(ahc, template) == 0) - found++; + ahc = (struct ahc_softc *)data; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + ahc_lock(ahc, &flags); +#endif + while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { + + TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); + dev->flags &= ~AHC_DEV_ON_RUN_LIST; + ahc_linux_check_device_queue(ahc, dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + /* Yeild to our interrupt handler */ + ahc_unlock(ahc, &flags); + ahc_lock(ahc, &flags); +#endif } - aic7xxx_detect_complete++; - return (found); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + ahc_unlock(ahc, &flags); +#endif } +/******************************** Macros **************************************/ +#define BUILD_SCSIID(ahc, cmd) \ + ((((cmd)->device->id << TID_SHIFT) & TID) \ + | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \ + | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB)) + +/******************************** Bus DMA *************************************/ int -ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) +ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent, + bus_size_t alignment, bus_size_t boundary, + bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, + bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) { - char buf[80]; - struct Scsi_Host *host; - char *new_name; - u_long s; - + bus_dma_tag_t dmat; - template->name = ahc->description; - host = scsi_register(template, sizeof(struct ahc_softc *)); - if (host == NULL) + dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT); + if (dmat == NULL) return (ENOMEM); - ahc_lock(ahc, &s); - *((struct ahc_softc **)host->hostdata) = ahc; - ahc->platform_data->host = host; - host->can_queue = AHC_MAX_QUEUE; - host->cmd_per_lun = 2; - host->sg_tablesize = AHC_NSEG; - host->select_queue_depths = ahc_linux_select_queue_depth; - /* XXX No way to communicate the ID for multiple channels */ - host->this_id = ahc->our_id; - host->irq = ahc->platform_data->irq; - host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8; - host->max_lun = AHC_NUM_LUNS; - host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0; - ahc_set_unit(ahc, ahc_linux_next_unit()); - sprintf(buf, "scsi%d", host->host_no); - new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); - if (new_name != NULL) { - strcpy(new_name, buf); - ahc_set_name(ahc, new_name); - } - host->unique_id = ahc->unit; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) - scsi_set_pci_device(host, ahc->dev_softc); -#endif - ahc_linux_initialize_scsi_bus(ahc); - ahc_unlock(ahc, &s); + /* + * Linux is very simplistic about DMA memory. For now don't + * maintain all specification information. Once Linux supplies + * better facilities for doing these operations, or the + * needs of this particular driver change, we might need to do + * more here. + */ + dmat->alignment = alignment; + dmat->boundary = boundary; + dmat->maxsize = maxsize; + *ret_tag = dmat; return (0); } -uint64_t -ahc_linux_get_memsize() +void +ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat) { - struct sysinfo si; - - si_meminfo(&si); - return (si.totalram << PAGE_SHIFT); + free(dmat, M_DEVBUF); } -/* - * Find the smallest available unit number to use - * for a new device. We don't just use a static - * count to handle the "repeated hot-(un)plug" - * scenario. - */ -static int -ahc_linux_next_unit() +int +ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, + int flags, bus_dmamap_t *mapp) { - struct ahc_softc *ahc; - int unit; + bus_dmamap_t map; - unit = 0; -retry: - TAILQ_FOREACH(ahc, &ahc_tailq, links) { - if (ahc->unit == unit) { - unit++; - goto retry; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); + if (map == NULL) + return (ENOMEM); + /* + * Although we can dma data above 4GB, our + * "consistent" memory is below 4GB for + * space efficiency reasons (only need a 4byte + * address). For this reason, we have to reset + * our dma mask when doing allocations. + */ + if (ahc->dev_softc != NULL) + ahc_pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF); + *vaddr = pci_alloc_consistent(ahc->dev_softc, + dmat->maxsize, &map->bus_addr); + if (ahc->dev_softc != NULL) + ahc_pci_set_dma_mask(ahc->dev_softc, + ahc->platform_data->hw_dma_mask); +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ + /* + * At least in 2.2.14, malloc is a slab allocator so all + * allocations are aligned. We assume for these kernel versions + * that all allocations will be bellow 4Gig, physically contiguous, + * and accessible via DMA by the controller. + */ + map = NULL; /* No additional information to store */ + *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); +#endif + if (*vaddr == NULL) + return (ENOMEM); + *mapp = map; + return(0); +} + +void +ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, + void* vaddr, bus_dmamap_t map) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + pci_free_consistent(ahc->dev_softc, dmat->maxsize, + vaddr, map->bus_addr); +#else + free(vaddr, M_DEVBUF); +#endif +} + +int +ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, + void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, + void *cb_arg, int flags) +{ + /* + * Assume for now that this will only be used during + * initialization and not for per-transaction buffer mapping. + */ + bus_dma_segment_t stack_sg; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + stack_sg.ds_addr = map->bus_addr; +#else +#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a)) + stack_sg.ds_addr = VIRT_TO_BUS(buf); +#endif + stack_sg.ds_len = dmat->maxsize; + cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); + return (0); +} + +void +ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* + * The map may is NULL in our < 2.3.X implementation. + */ + if (map != NULL) + free(map, M_DEVBUF); +} + +int +ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) +{ + /* Nothing to do */ + return (0); +} + +/********************* Platform Dependent Functions ***************************/ +/* + * Compare "left hand" softc with "right hand" softc, returning: + * < 0 - lahc has a lower priority than rahc + * 0 - Softcs are equal + * > 0 - lahc has a higher priority than rahc + */ +int +ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) +{ + int value; + int rvalue; + int lvalue; + + /* + * Under Linux, cards are ordered as follows: + * 1) VLB/EISA BIOS enabled devices sorted by BIOS address. + * 2) PCI devices with BIOS enabled sorted by bus/slot/func. + * 3) All remaining VLB/EISA devices sorted by ioport. + * 4) All remaining PCI devices sorted by bus/slot/func. + */ + value = (lahc->flags & AHC_BIOS_ENABLED) + - (rahc->flags & AHC_BIOS_ENABLED); + if (value != 0) + /* Controllers with BIOS enabled have a *higher* priority */ + return (value); + + /* + * Same BIOS setting, now sort based on bus type. + * EISA and VL controllers sort together. EISA/VL + * have higher priority than PCI. + */ + rvalue = (rahc->chip & AHC_BUS_MASK); + if (rvalue == AHC_VL) + rvalue = AHC_EISA; + lvalue = (lahc->chip & AHC_BUS_MASK); + if (lvalue == AHC_VL) + lvalue = AHC_EISA; + value = rvalue - lvalue; + if (value != 0) + return (value); + + /* Still equal. Sort by BIOS address, ioport, or bus/slot/func. */ + switch (rvalue) { + case AHC_PCI: + { + char primary_channel; + + if (aic7xxx_reverse_scan != 0) + value = ahc_get_pci_bus(lahc->dev_softc) + - ahc_get_pci_bus(rahc->dev_softc); + else + value = ahc_get_pci_bus(rahc->dev_softc) + - ahc_get_pci_bus(lahc->dev_softc); + if (value != 0) + break; + if (aic7xxx_reverse_scan != 0) + value = ahc_get_pci_slot(lahc->dev_softc) + - ahc_get_pci_slot(rahc->dev_softc); + else + value = ahc_get_pci_slot(rahc->dev_softc) + - ahc_get_pci_slot(lahc->dev_softc); + if (value != 0) + break; + /* + * On multi-function devices, the user can choose + * to have function 1 probed before function 0. + * Give whichever channel is the primary channel + * the highest priority. + */ + primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A'; + value = -1; + if (lahc->channel == primary_channel) + value = 1; + break; + } + case AHC_EISA: + if ((rahc->flags & AHC_BIOS_ENABLED) != 0) { + value = rahc->platform_data->bios_address + - lahc->platform_data->bios_address; + } else { + value = rahc->bsh.ioport + - lahc->bsh.ioport; + } + break; + default: + panic("ahc_softc_sort: invalid bus type"); + } + return (value); +} + +static void +ahc_linux_setup_tag_info_global(char *p) +{ + int tags, i, j; + + tags = simple_strtoul(p + 1, NULL, 0) & 0xff; + printf("Setting Global Tags= %d\n", tags); + + for (i = 0; i < NUM_ELEMENTS(aic7xxx_tag_info); i++) { + for (j = 0; j < AHC_NUM_TARGETS; j++) { + aic7xxx_tag_info[i].tag_commands[j] = tags; + } + } +} + +static void +ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) +{ + + if ((instance >= 0) && (targ >= 0) + && (instance < NUM_ELEMENTS(aic7xxx_tag_info)) + && (targ < AHC_NUM_TARGETS)) { + aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff; + if (bootverbose) + printf("tag_info[%d:%d] = %d\n", instance, targ, value); + } +} + +static void +ahc_linux_setup_dv(u_long arg, int instance, int targ, int32_t value) +{ + + if ((instance >= 0) + && (instance < NUM_ELEMENTS(aic7xxx_dv_settings))) { + aic7xxx_dv_settings[instance] = value; + if (bootverbose) + printf("dv[%d] = %d\n", instance, value); + } +} + +/* + * Handle Linux boot parameters. This routine allows for assigning a value + * to a parameter with a ':' between the parameter and the value. + * ie. aic7xxx=stpwlev:1,extended + */ +static int +aic7xxx_setup(char *s) +{ + int i, n; + char *p; + char *end; + + static struct { + const char *name; + uint32_t *flag; + } options[] = { + { "extended", &aic7xxx_extended }, + { "no_reset", &aic7xxx_no_reset }, + { "verbose", &aic7xxx_verbose }, + { "allow_memio", &aic7xxx_allow_memio}, +#ifdef AHC_DEBUG + { "debug", &ahc_debug }, +#endif + { "reverse_scan", &aic7xxx_reverse_scan }, + { "no_probe", &aic7xxx_probe_eisa_vl }, + { "probe_eisa_vl", &aic7xxx_probe_eisa_vl }, + { "periodic_otag", &aic7xxx_periodic_otag }, + { "pci_parity", &aic7xxx_pci_parity }, + { "seltime", &aic7xxx_seltime }, + { "tag_info", NULL }, + { "global_tag_depth", NULL }, + { "dv", NULL } + }; + + end = strchr(s, '\0'); + + /* + * XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS + * will never be 0 in this case. + */ + n = 0; + + while ((p = strsep(&s, ",.")) != NULL) { + if (*p == '\0') + continue; + for (i = 0; i < NUM_ELEMENTS(options); i++) { + + n = strlen(options[i].name); + if (strncmp(options[i].name, p, n) == 0) + break; + } + if (i == NUM_ELEMENTS(options)) + continue; + + if (strncmp(p, "global_tag_depth", n) == 0) { + ahc_linux_setup_tag_info_global(p + n); + } else if (strncmp(p, "tag_info", n) == 0) { + s = aic_parse_brace_option("tag_info", p + n, end, + 2, ahc_linux_setup_tag_info, 0); + } else if (strncmp(p, "dv", n) == 0) { + s = aic_parse_brace_option("dv", p + n, end, 1, + ahc_linux_setup_dv, 0); + } else if (p[n] == ':') { + *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); + } else if (strncmp(p, "verbose", n) == 0) { + *(options[i].flag) = 1; + } else { + *(options[i].flag) ^= 0xFFFFFFFF; + } + } + return 1; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) +__setup("aic7xxx=", aic7xxx_setup); +#endif + +uint32_t aic7xxx_verbose; + +int +ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) +{ + char buf[80]; + struct Scsi_Host *host; + char *new_name; + u_long s; + u_int targ_offset; + + template->name = ahc->description; + host = scsi_register(template, sizeof(struct ahc_softc *)); + if (host == NULL) + return (ENOMEM); + + *((struct ahc_softc **)host->hostdata) = ahc; + ahc_lock(ahc, &s); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_assign_lock(host, &ahc->platform_data->spin_lock); +#elif AHC_SCSI_HAS_HOST_LOCK != 0 + host->lock = &ahc->platform_data->spin_lock; +#endif + ahc->platform_data->host = host; + host->can_queue = AHC_MAX_QUEUE; + host->cmd_per_lun = 2; + /* XXX No way to communicate the ID for multiple channels */ + host->this_id = ahc->our_id; + host->irq = ahc->platform_data->irq; + host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8; + host->max_lun = AHC_NUM_LUNS; + host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0; + host->sg_tablesize = AHC_NSEG; + ahc_set_unit(ahc, ahc_linux_next_unit()); + sprintf(buf, "scsi%d", host->host_no); + new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); + if (new_name != NULL) { + strcpy(new_name, buf); + ahc_set_name(ahc, new_name); + } + host->unique_id = ahc->unit; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + scsi_set_pci_device(host, ahc->dev_softc); +#endif + ahc_linux_initialize_scsi_bus(ahc); + ahc_unlock(ahc, &s); + ahc->platform_data->dv_pid = kernel_thread(ahc_linux_dv_thread, ahc, 0); + ahc_lock(ahc, &s); + if (ahc->platform_data->dv_pid < 0) { + printf("%s: Failed to create DV thread, error= %d\n", + ahc_name(ahc), ahc->platform_data->dv_pid); + return (-ahc->platform_data->dv_pid); + } + /* + * Initially allocate *all* of our linux target objects + * so that the DV thread will scan them all in parallel + * just after driver initialization. Any device that + * does not exist will have its target object destroyed + * by the selection timeout handler. In the case of a + * device that appears after the initial DV scan, async + * negotiation will occur for the first command, and DV + * will comence should that first command be successful. + */ + for (targ_offset = 0; + targ_offset < host->max_id * (host->max_channel + 1); + targ_offset++) { + u_int channel; + u_int target; + + channel = 0; + target = targ_offset; + if (target > 7 + && (ahc->features & AHC_TWIN) != 0) { + channel = 1; + target &= 0x7; + } + /* + * Skip our own ID. Some Compaq/HP storage devices + * have enclosure management devices that respond to + * single bit selection (i.e. selecting ourselves). + * It is expected that either an external application + * or a modified kernel will be used to probe this + * ID if it is appropriate. To accommodate these + * installations, ahc_linux_alloc_target() will allocate + * for our ID if asked to do so. + */ + if ((channel == 0 && target == ahc->our_id) + || (channel == 1 && target == ahc->our_id_b)) + continue; + + ahc_linux_alloc_target(ahc, channel, target); + } + ahc_intr_enable(ahc, TRUE); + ahc_linux_start_dv(ahc); + ahc_unlock(ahc, &s); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); +#endif + return (0); +} + +uint64_t +ahc_linux_get_memsize(void) +{ + struct sysinfo si; + + si_meminfo(&si); + return ((uint64_t)si.totalram << PAGE_SHIFT); +} + +/* + * Find the smallest available unit number to use + * for a new device. We don't just use a static + * count to handle the "repeated hot-(un)plug" + * scenario. + */ +static int +ahc_linux_next_unit(void) +{ + struct ahc_softc *ahc; + int unit; + + unit = 0; +retry: + TAILQ_FOREACH(ahc, &ahc_tailq, links) { + if (ahc->unit == unit) { + unit++; + goto retry; + } + } + return (unit); +} + +/* + * Place the SCSI bus into a known state by either resetting it, + * or forcing transfer negotiations on the next command to any + * target. + */ +void +ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc) +{ + int i; + int numtarg; + + i = 0; + numtarg = 0; + + if (aic7xxx_no_reset != 0) + ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B); + + if ((ahc->flags & AHC_RESET_BUS_A) != 0) + ahc_reset_channel(ahc, 'A', /*initiate_reset*/TRUE); + else + numtarg = (ahc->features & AHC_WIDE) ? 16 : 8; + + if ((ahc->features & AHC_TWIN) != 0) { + + if ((ahc->flags & AHC_RESET_BUS_B) != 0) { + ahc_reset_channel(ahc, 'B', /*initiate_reset*/TRUE); + } else { + if (numtarg == 0) + i = 8; + numtarg += 8; + } + } + + /* + * Force negotiation to async for all targets that + * will not see an initial bus reset. + */ + for (; i < numtarg; i++) { + struct ahc_devinfo devinfo; + struct ahc_initiator_tinfo *tinfo; + struct ahc_tmode_tstate *tstate; + u_int our_id; + u_int target_id; + char channel; + + channel = 'A'; + our_id = ahc->our_id; + target_id = i; + if (i > 7 && (ahc->features & AHC_TWIN) != 0) { + channel = 'B'; + our_id = ahc->our_id_b; + target_id = i % 8; + } + tinfo = ahc_fetch_transinfo(ahc, channel, our_id, + target_id, &tstate); + ahc_compile_devinfo(&devinfo, our_id, target_id, + CAM_LUN_WILDCARD, channel, ROLE_INITIATOR); + ahc_update_neg_request(ahc, &devinfo, tstate, + tinfo, AHC_NEG_ALWAYS); + } + /* Give the bus some time to recover */ + if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) { + ahc_linux_freeze_simq(ahc); + init_timer(&ahc->platform_data->reset_timer); + ahc->platform_data->reset_timer.data = (u_long)ahc; + ahc->platform_data->reset_timer.expires = + jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000; + ahc->platform_data->reset_timer.function = + ahc_linux_release_simq; + add_timer(&ahc->platform_data->reset_timer); + } +} + +int +ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) +{ + + ahc->platform_data = + malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT); + if (ahc->platform_data == NULL) + return (ENOMEM); + memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); + TAILQ_INIT(&ahc->platform_data->completeq); + TAILQ_INIT(&ahc->platform_data->device_runq); + ahc->platform_data->irq = AHC_LINUX_NOIRQ; + ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; + ahc_lockinit(ahc); + ahc_done_lockinit(ahc); + init_timer(&ahc->platform_data->completeq_timer); + ahc->platform_data->completeq_timer.data = (u_long)ahc; + ahc->platform_data->completeq_timer.function = + (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); + init_MUTEX_LOCKED(&ahc->platform_data->dv_sem); + init_MUTEX_LOCKED(&ahc->platform_data->dv_cmd_sem); +#else + ahc->platform_data->eh_sem = MUTEX_LOCKED; + ahc->platform_data->dv_sem = MUTEX_LOCKED; + ahc->platform_data->dv_cmd_sem = MUTEX_LOCKED; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet, + (unsigned long)ahc); +#endif + ahc->seltime = (aic7xxx_seltime & 0x3) << 4; + ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; + if (aic7xxx_pci_parity == 0) + ahc->flags |= AHC_DISABLE_PCI_PERR; + + return (0); +} + +void +ahc_platform_free(struct ahc_softc *ahc) +{ + struct ahc_linux_target *targ; + struct ahc_linux_device *dev; + int i, j; + + if (ahc->platform_data != NULL) { + del_timer_sync(&ahc->platform_data->completeq_timer); + ahc_linux_kill_dv_thread(ahc); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + tasklet_kill(&ahc->platform_data->runq_tasklet); +#endif + if (ahc->platform_data->host != NULL) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_remove_host(ahc->platform_data->host); +#endif + scsi_unregister(ahc->platform_data->host); + } + + /* destroy all of the device and target objects */ + for (i = 0; i < AHC_NUM_TARGETS; i++) { + targ = ahc->platform_data->targets[i]; + if (targ != NULL) { + /* Keep target around through the loop. */ + targ->refcount++; + for (j = 0; j < AHC_NUM_LUNS; j++) { + + if (targ->devices[j] == NULL) + continue; + dev = targ->devices[j]; + ahc_linux_free_device(ahc, dev); + } + /* + * Forcibly free the target now that + * all devices are gone. + */ + ahc_linux_free_target(ahc, targ); + } + } + + if (ahc->platform_data->irq != AHC_LINUX_NOIRQ) + free_irq(ahc->platform_data->irq, ahc); + if (ahc->tag == BUS_SPACE_PIO + && ahc->bsh.ioport != 0) + release_region(ahc->bsh.ioport, 256); + if (ahc->tag == BUS_SPACE_MEMIO + && ahc->bsh.maddr != NULL) { + u_long base_addr; + + base_addr = (u_long)ahc->bsh.maddr; + base_addr &= PAGE_MASK; + iounmap((void *)base_addr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + release_mem_region(ahc->platform_data->mem_busaddr, + 0x1000); +#endif + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * In 2.4 we detach from the scsi midlayer before the PCI + * layer invokes our remove callback. No per-instance + * detach is provided, so we must reach inside the PCI + * subsystem's internals and detach our driver manually. + */ + if (ahc->dev_softc != NULL) + ahc->dev_softc->driver = NULL; +#endif + free(ahc->platform_data, M_DEVBUF); + } +} + +void +ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb) +{ + ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb), + SCB_GET_CHANNEL(ahc, scb), + SCB_GET_LUN(scb), SCB_LIST_NULL, + ROLE_UNKNOWN, CAM_REQUEUE_REQ); +} + +void +ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, + ahc_queue_alg alg) +{ + struct ahc_linux_device *dev; + int was_queuing; + int now_queuing; + + dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', + devinfo->target, + devinfo->lun, /*alloc*/FALSE); + if (dev == NULL) + return; + was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED); + switch (alg) { + default: + case AHC_QUEUE_NONE: + now_queuing = 0; + break; + case AHC_QUEUE_BASIC: + now_queuing = AHC_DEV_Q_BASIC; + break; + case AHC_QUEUE_TAGGED: + now_queuing = AHC_DEV_Q_TAGGED; + break; + } + if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0 + && (was_queuing != now_queuing) + && (dev->active != 0)) { + dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY; + dev->qfrozen++; + } + + dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG); + if (now_queuing) { + u_int usertags; + + usertags = ahc_linux_user_tagdepth(ahc, devinfo); + if (!was_queuing) { + /* + * Start out agressively and allow our + * dynamic queue depth algorithm to take + * care of the rest. + */ + dev->maxtags = usertags; + dev->openings = dev->maxtags - dev->active; + } + if (dev->maxtags == 0) { + /* + * Queueing is disabled by the user. + */ + dev->openings = 1; + } else if (alg == AHC_QUEUE_TAGGED) { + dev->flags |= AHC_DEV_Q_TAGGED; + if (aic7xxx_periodic_otag != 0) + dev->flags |= AHC_DEV_PERIODIC_OTAG; + } else + dev->flags |= AHC_DEV_Q_BASIC; + } else { + /* We can only have one opening. */ + dev->maxtags = 0; + dev->openings = 1 - dev->active; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (dev->scsi_device != NULL) { + switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { + case AHC_DEV_Q_BASIC: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_SIMPLE_TASK, + dev->openings + dev->active); + break; + case AHC_DEV_Q_TAGGED: + scsi_adjust_queue_depth(dev->scsi_device, + MSG_ORDERED_TASK, + dev->openings + dev->active); + break; + default: + /* + * We allow the OS to queue 2 untagged transactions to + * us at any time even though we can only execute them + * serially on the controller/device. This should + * remove some latency. + */ + scsi_adjust_queue_depth(dev->scsi_device, + /*NON-TAGGED*/0, + /*queue depth*/2); + break; + } + } +#endif +} + +int +ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, + int lun, u_int tag, role_t role, uint32_t status) +{ + int chan; + int maxchan; + int targ; + int maxtarg; + int clun; + int maxlun; + int count; + + if (tag != SCB_LIST_NULL) + return (0); + + chan = 0; + if (channel != ALL_CHANNELS) { + chan = channel - 'A'; + maxchan = chan + 1; + } else { + maxchan = (ahc->features & AHC_TWIN) ? 2 : 1; + } + targ = 0; + if (target != CAM_TARGET_WILDCARD) { + targ = target; + maxtarg = targ + 1; + } else { + maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8; + } + clun = 0; + if (lun != CAM_LUN_WILDCARD) { + clun = lun; + maxlun = clun + 1; + } else { + maxlun = AHC_NUM_LUNS; + } + + count = 0; + for (; chan < maxchan; chan++) { + + for (; targ < maxtarg; targ++) { + + for (; clun < maxlun; clun++) { + struct ahc_linux_device *dev; + struct ahc_busyq *busyq; + struct ahc_cmd *acmd; + + dev = ahc_linux_get_device(ahc, chan, + targ, clun, + /*alloc*/FALSE); + if (dev == NULL) + continue; + + busyq = &dev->busyq; + while ((acmd = TAILQ_FIRST(busyq)) != NULL) { + Scsi_Cmnd *cmd; + + cmd = &acmd_scsi_cmd(acmd); + TAILQ_REMOVE(busyq, acmd, + acmd_links.tqe); + count++; + cmd->result = status << 16; + ahc_linux_queue_cmd_complete(ahc, cmd); + } + } + } + } + + return (count); +} + +static void +ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc) +{ + u_long flags; + + ahc_lock(ahc, &flags); + del_timer(&ahc->platform_data->completeq_timer); + ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER; + ahc_linux_run_complete_queue(ahc); + ahc_unlock(ahc, &flags); +} + +static void +ahc_linux_start_dv(struct ahc_softc *ahc) +{ + + /* + * Freeze the simq and signal ahc_linux_queue to not let any + * more commands through. + */ + if ((ahc->platform_data->flags & AHC_DV_ACTIVE) == 0) { +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s: Waking DV thread\n", ahc_name(ahc)); +#endif + + ahc->platform_data->flags |= AHC_DV_ACTIVE; + ahc_linux_freeze_simq(ahc); + + /* Wake up the DV kthread */ + up(&ahc->platform_data->dv_sem); + } +} + +static void +ahc_linux_kill_dv_thread(struct ahc_softc *ahc) +{ + u_long s; + + ahc_lock(ahc, &s); + if (ahc->platform_data->dv_pid != 0) { + ahc->platform_data->flags |= AHC_DV_SHUTDOWN; + ahc_unlock(ahc, &s); + up(&ahc->platform_data->dv_sem); + + /* + * Use the eh_sem as an indicator that the + * dv thread is exiting. Note that the dv + * thread must still return after performing + * the up on our semaphore before it has + * completely exited this module. Unfortunately, + * there seems to be no easy way to wait for the + * exit of a thread for which you are not the + * parent (dv threads are parented by init). + * Cross your fingers... + */ + down(&ahc->platform_data->eh_sem); + + /* + * Mark the dv thread as already dead. This + * avoids attempting to kill it a second time. + * This is necessary because we must kill the + * DV thread before calling ahc_free() in the + * module shutdown case to avoid bogus locking + * in the SCSI mid-layer, but we ahc_free() is + * called without killing the DV thread in the + * instance detach case, so ahc_platform_free() + * calls us again to verify that the DV thread + * is dead. + */ + ahc->platform_data->dv_pid = 0; + } else { + ahc_unlock(ahc, &s); + } +} + +static int +ahc_linux_dv_thread(void *data) +{ + struct ahc_softc *ahc; + int target; + u_long s; + + ahc = (struct ahc_softc *)data; + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("Launching DV Thread\n"); +#endif + + /* + * Complete thread creation. + */ + lock_kernel(); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * Don't care about any signals. + */ + siginitsetinv(¤t->blocked, 0); + + daemonize(); + sprintf(current->comm, "ahc_dv_%d", ahc->unit); +#else + daemonize("ahc_dv_%d", ahc->unit); +#endif + unlock_kernel(); + + while (1) { + /* + * Use down_interruptible() rather than down() to + * avoid inclusion in the load average. + */ + down_interruptible(&ahc->platform_data->dv_sem); + + /* Check to see if we've been signaled to exit */ + ahc_lock(ahc, &s); + if ((ahc->platform_data->flags & AHC_DV_SHUTDOWN) != 0) { + ahc_unlock(ahc, &s); + break; + } + ahc_unlock(ahc, &s); + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s: Beginning Domain Validation\n", + ahc_name(ahc)); +#endif + + /* + * Wait for any pending commands to drain before proceeding. + */ + ahc_lock(ahc, &s); + while (LIST_FIRST(&ahc->pending_scbs) != NULL) { + ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_EMPTY; + ahc_unlock(ahc, &s); + down_interruptible(&ahc->platform_data->dv_sem); + ahc_lock(ahc, &s); + } + + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + while (AHC_DV_SIMQ_FROZEN(ahc) == 0) { + ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE; + ahc_unlock(ahc, &s); + down_interruptible(&ahc->platform_data->dv_sem); + ahc_lock(ahc, &s); + } + ahc_unlock(ahc, &s); + + for (target = 0; target < AHC_NUM_TARGETS; target++) + ahc_linux_dv_target(ahc, target); + + ahc_lock(ahc, &s); + ahc->platform_data->flags &= ~AHC_DV_ACTIVE; + ahc_unlock(ahc, &s); + + /* + * Release the SIMQ so that normal commands are + * allowed to continue on the bus. + */ + ahc_linux_release_simq((u_long)ahc); + } + up(&ahc->platform_data->eh_sem); + return (0); +} + +#define AHC_LINUX_DV_INQ_SHORT_LEN 36 +#define AHC_LINUX_DV_INQ_LEN 256 +#define AHC_LINUX_DV_TIMEOUT (HZ / 4) + +#define AHC_SET_DV_STATE(ahc, targ, newstate) \ + ahc_set_dv_state(ahc, targ, newstate, __LINE__) + +static __inline void +ahc_set_dv_state(struct ahc_softc *ahc, struct ahc_linux_target *targ, + ahc_dv_state newstate, u_int line) +{ + ahc_dv_state oldstate; + + oldstate = targ->dv_state; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s:%d: Going from state %d to state %d\n", + ahc_name(ahc), line, oldstate, newstate); +#endif + + if (oldstate == newstate) + targ->dv_state_retry++; + else + targ->dv_state_retry = 0; + targ->dv_state = newstate; +} + +static void +ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset) +{ + struct ahc_devinfo devinfo; + struct ahc_linux_target *targ; + struct scsi_cmnd *cmd; + struct scsi_device *scsi_dev; + struct scsi_sense_data *sense; + uint8_t *buffer; + u_long s; + u_int timeout; + int echo_size; + + sense = NULL; + buffer = NULL; + echo_size = 0; + ahc_lock(ahc, &s); + targ = ahc->platform_data->targets[target_offset]; + if (targ == NULL || (targ->flags & AHC_DV_REQUIRED) == 0) { + ahc_unlock(ahc, &s); + return; + } + ahc_compile_devinfo(&devinfo, + targ->channel == 0 ? ahc->our_id : ahc->our_id_b, + targ->target, /*lun*/0, targ->channel + 'A', + ROLE_INITIATOR); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, &devinfo); + printf("Performing DV\n"); + } +#endif + + ahc_unlock(ahc, &s); + + cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK); + scsi_dev->host = ahc->platform_data->host; + scsi_dev->id = devinfo.target; + scsi_dev->lun = devinfo.lun; + scsi_dev->channel = devinfo.channel - 'A'; + ahc->platform_data->dv_scsi_dev = scsi_dev; + + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_SHORT_ASYNC); + + while (targ->dv_state != AHC_DV_STATE_EXIT) { + timeout = AHC_LINUX_DV_TIMEOUT; + switch (targ->dv_state) { + case AHC_DV_STATE_INQ_SHORT_ASYNC: + case AHC_DV_STATE_INQ_ASYNC: + case AHC_DV_STATE_INQ_ASYNC_VERIFY: + /* + * Set things to async narrow to reduce the + * chance that the INQ will fail. + */ + ahc_lock(ahc, &s); + ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_unlock(ahc, &s); + timeout = 10 * HZ; + targ->flags &= ~AHC_INQ_VALID; + /* FALLTHROUGH */ + case AHC_DV_STATE_INQ_VERIFY: + { + u_int inq_len; + + if (targ->dv_state == AHC_DV_STATE_INQ_SHORT_ASYNC) + inq_len = AHC_LINUX_DV_INQ_SHORT_LEN; + else + inq_len = targ->inq_data->additional_length + 5; + ahc_linux_dv_inq(ahc, cmd, &devinfo, targ, inq_len); + break; + } + case AHC_DV_STATE_TUR: + case AHC_DV_STATE_BUSY: + timeout = 5 * HZ; + ahc_linux_dv_tur(ahc, cmd, &devinfo); + break; + case AHC_DV_STATE_REBD: + ahc_linux_dv_rebd(ahc, cmd, &devinfo, targ); + break; + case AHC_DV_STATE_WEB: + ahc_linux_dv_web(ahc, cmd, &devinfo, targ); + break; + + case AHC_DV_STATE_REB: + ahc_linux_dv_reb(ahc, cmd, &devinfo, targ); + break; + + case AHC_DV_STATE_SU: + ahc_linux_dv_su(ahc, cmd, &devinfo, targ); + timeout = 50 * HZ; + break; + + default: + ahc_print_devinfo(ahc, &devinfo); + printf("Unknown DV state %d\n", targ->dv_state); + goto out; + } + + /* Queue the command and wait for it to complete */ + /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */ + init_timer(&cmd->eh_timeout); +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) + /* + * All of the printfs during negotiation + * really slow down the negotiation. + * Add a bit of time just to be safe. + */ + timeout += HZ; +#endif + scsi_add_timer(cmd, timeout, ahc_linux_dv_timeout); + /* + * In 2.5.X, it is assumed that all calls from the + * "midlayer" (which we are emulating) will have the + * ahc host lock held. For other kernels, the + * io_request_lock must be held. + */ +#if AHC_SCSI_HAS_HOST_LOCK != 0 + ahc_lock(ahc, &s); +#else + spin_lock_irqsave(&io_request_lock, s); +#endif + ahc_linux_queue(cmd, ahc_linux_dv_complete); +#if AHC_SCSI_HAS_HOST_LOCK != 0 + ahc_unlock(ahc, &s); +#else + spin_unlock_irqrestore(&io_request_lock, s); +#endif + down_interruptible(&ahc->platform_data->dv_cmd_sem); + /* + * Wait for the SIMQ to be released so that DV is the + * only reason the queue is frozen. + */ + ahc_lock(ahc, &s); + while (AHC_DV_SIMQ_FROZEN(ahc) == 0) { + ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE; + ahc_unlock(ahc, &s); + down_interruptible(&ahc->platform_data->dv_sem); + ahc_lock(ahc, &s); + } + ahc_unlock(ahc, &s); + + ahc_linux_dv_transition(ahc, cmd, &devinfo, targ); + } + +out: + if ((targ->flags & AHC_INQ_VALID) != 0 + && ahc_linux_get_device(ahc, devinfo.channel - 'A', + devinfo.target, devinfo.lun, + /*alloc*/FALSE) == NULL) { + /* + * The DV state machine failed to configure this device. + * This is normal if DV is disabled. Since we have inquiry + * data, filter it and use the "optimistic" negotiation + * parameters found in the inquiry string. + */ + ahc_linux_filter_inquiry(ahc, &devinfo); + if ((targ->flags & (AHC_BASIC_DV|AHC_ENHANCED_DV)) != 0) { + ahc_print_devinfo(ahc, &devinfo); + printf("DV failed to configure device. " + "Please file a bug report against " + "this driver.\n"); + } + } + + if (cmd != NULL) + free(cmd, M_DEVBUF); + + if (ahc->platform_data->dv_scsi_dev != NULL) { + free(ahc->platform_data->dv_scsi_dev, M_DEVBUF); + ahc->platform_data->dv_scsi_dev = NULL; + } + + ahc_lock(ahc, &s); + if (targ->dv_buffer != NULL) { + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = NULL; + } + if (targ->dv_buffer1 != NULL) { + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = NULL; + } + targ->flags &= ~AHC_DV_REQUIRED; + if (targ->refcount == 0) + ahc_linux_free_target(ahc, targ); + ahc_unlock(ahc, &s); +} + +static void +ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ) +{ + u_int32_t status; + + status = aic_error_action(cmd, targ->inq_data, + ahc_cmd_get_transaction_status(cmd), + ahc_cmd_get_scsi_status(cmd)); + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Entering ahc_linux_dv_transition, state= %d, " + "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state, + status, cmd->result); + } +#endif + + switch (targ->dv_state) { + case AHC_DV_STATE_INQ_SHORT_ASYNC: + case AHC_DV_STATE_INQ_ASYNC: + switch (status & SS_MASK) { + case SS_NOP: + { + AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1); + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if ((status & SS_ERRMASK) == EBUSY) + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHC_DV_STATE_INQ_ASYNC_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + u_int xportflags; + u_int spi3data; + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHC_LINUX_DV_INQ_LEN) != 0) { + /* + * Inquiry data must have changed. + * Try from the top again. + */ + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + } + + AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1); + targ->flags |= AHC_INQ_VALID; + if (ahc_linux_user_dv_setting(ahc) == 0) + break; + + xportflags = targ->inq_data->flags; + if ((xportflags & (SID_Sync|SID_WBus16)) == 0) + break; + + spi3data = targ->inq_data->spi3data; + switch (spi3data & SID_SPI_CLOCK_DT_ST) { + default: + case SID_SPI_CLOCK_ST: + /* Assume only basic DV is supported. */ + targ->flags |= AHC_BASIC_DV; + break; + case SID_SPI_CLOCK_DT: + case SID_SPI_CLOCK_DT_ST: + targ->flags |= AHC_ENHANCED_DV; + break; + } + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + + if ((status & SS_ERRMASK) == EBUSY) + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + case AHC_DV_STATE_INQ_VERIFY: + switch (status & SS_MASK) { + case SS_NOP: + { + + if (memcmp(targ->inq_data, targ->dv_buffer, + AHC_LINUX_DV_INQ_LEN) == 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + int i; + + ahc_print_devinfo(ahc, devinfo); + printf("Inquiry buffer mismatch:"); + for (i = 0; i < AHC_LINUX_DV_INQ_LEN; i++) { + if ((i & 0xF) == 0) + printf("\n "); + printf("0x%x:0x0%x ", + ((uint8_t *)targ->inq_data)[i], + targ->dv_buffer[i]); + } + printf("\n"); + } +#endif + + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } else if ((status & SS_ERRMASK) == EBUSY) + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + if (targ->dv_state_retry < 10) + break; + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Failed DV inquiry, skipping\n"); + } +#endif + break; + } + break; + + case AHC_DV_STATE_TUR: + switch (status & SS_MASK) { + case SS_NOP: + if ((targ->flags & AHC_BASIC_DV) != 0) { + ahc_linux_filter_inquiry(ahc, devinfo); + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_VERIFY); + } else if ((targ->flags & AHC_ENHANCED_DV) != 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REBD); + } else { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + } + break; + case SS_RETRY: + case SS_TUR: + if ((status & SS_ERRMASK) == EBUSY) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY); + break; + } + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry >= 10) { +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV TUR reties exhausted\n"); + } +#endif + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + if (status & SSQ_DELAY) + scsi_sleep(1 * HZ); + + break; + case SS_START: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_SU); + break; + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_REBD: + switch (status & SS_MASK) { + case SS_NOP: + { + uint32_t echo_size; + + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB); + echo_size = scsi_3btoul(&targ->dv_buffer[1]); + echo_size &= 0x1FFF; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Echo buffer size= %d\n", echo_size); + } +#endif + if (echo_size == 0) { + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + + /* Generate the buffer pattern */ + targ->dv_echo_size = echo_size; + ahc_linux_generate_dv_pattern(targ); + /* + * Setup initial negotiation values. + */ + ahc_linux_filter_inquiry(ahc, devinfo); + break; + } + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) + targ->dv_state_retry--; + if (targ->dv_state_retry <= 10) + break; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV REBD reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + case SS_FATAL: + default: + /* + * Setup initial negotiation values + * and try level 1 DV. + */ + ahc_linux_filter_inquiry(ahc, devinfo); + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_VERIFY); + targ->dv_echo_size = 0; + break; + } + break; + + case AHC_DV_STATE_WEB: + switch (status & SS_MASK) { + case SS_NOP: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REB); + break; + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + /* + * Do not count "falling back" + * against our retries. + */ + targ->dv_state_retry = 0; + } + if (targ->dv_state_retry <= 10) + break; + /* FALLTHROUGH */ +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV WEB reties exhausted\n"); + } +#endif + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_REB: + switch (status & SS_MASK) { + case SS_NOP: + if (memcmp(targ->dv_buffer, targ->dv_buffer1, + targ->dv_echo_size) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + else + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_WEB); + break; + } + + if (targ->dv_buffer != NULL) { + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = NULL; + } + if (targ->dv_buffer1 != NULL) { + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = NULL; + } + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if ((status & SSQ_FALLBACK) != 0) { + if (ahc_linux_fallback(ahc, devinfo) != 0) { + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_EXIT); + break; + } + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB); + } + if (targ->dv_state_retry <= 10) { + if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0) + scsi_sleep(ahc->our_id*HZ/10); + break; + } +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV REB reties exhausted\n"); + } +#endif + /* FALLTHROUGH */ + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_SU: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; + } + break; + + case AHC_DV_STATE_BUSY: + switch (status & SS_MASK) { + case SS_NOP: + case SS_INQ_REFRESH: + AHC_SET_DV_STATE(ahc, targ, + AHC_DV_STATE_INQ_SHORT_ASYNC); + break; + case SS_TUR: + case SS_RETRY: + AHC_SET_DV_STATE(ahc, targ, targ->dv_state); + if (ahc_cmd_get_transaction_status(cmd) + == CAM_REQUEUE_REQ) { + targ->dv_state_retry--; + } else if (targ->dv_state_retry < 60) { + if ((status & SSQ_DELAY) != 0) + scsi_sleep(1 * HZ); + } else { +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("DV BUSY reties exhausted\n"); + } +#endif + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + } + break; + default: + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; } + break; + + default: + printf("%s: Invalid DV completion state %d\n", ahc_name(ahc), + targ->dv_state); + AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT); + break; } - return (unit); +} + +static void +ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo) +{ + memset(cmd, 0, sizeof(struct scsi_cmnd)); + cmd->device = ahc->platform_data->dv_scsi_dev; + cmd->scsi_done = ahc_linux_dv_complete; } /* - * Place the SCSI bus into a known state by either resetting it, - * or forcing transfer negotiations on the next command to any - * target. + * Synthesize an inquiry command. On the return trip, it'll be + * sniffed and the device transfer settings set for us. */ -void -ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc) +static void +ahc_linux_dv_inq(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ, + u_int request_length) { - int i; - int numtarg; - - i = 0; - numtarg = 0; - - if (aic7xxx_no_reset != 0) - ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B); - if ((ahc->flags & AHC_RESET_BUS_A) != 0) - ahc_reset_channel(ahc, 'A', /*initiate_reset*/TRUE); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending INQ\n"); + } +#endif + if (targ->inq_data == NULL) + targ->inq_data = malloc(AHC_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC) { + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHC_LINUX_DV_INQ_LEN, + M_DEVBUF, M_WAITOK); + } + + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 6; + cmd->cmnd[0] = INQUIRY; + cmd->cmnd[4] = request_length; + cmd->request_bufflen = request_length; + if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC) + cmd->request_buffer = targ->dv_buffer; else - numtarg = (ahc->features & AHC_WIDE) ? 16 : 8; + cmd->request_buffer = targ->inq_data; + memset(cmd->request_buffer, 0, AHC_LINUX_DV_INQ_LEN); +} - if ((ahc->features & AHC_TWIN) != 0) { +static void +ahc_linux_dv_tur(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo) +{ - if ((ahc->flags & AHC_RESET_BUS_B) != 0) { - ahc_reset_channel(ahc, 'B', /*initiate_reset*/TRUE); - } else { - if (numtarg == 0) - i = 8; - numtarg += 8; - } +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending TUR\n"); } +#endif + /* Do a TUR to clear out any non-fatal transitional state */ + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = TEST_UNIT_READY; +} - for (; i < numtarg; i++) { - struct ahc_devinfo devinfo; - struct ahc_initiator_tinfo *tinfo; - struct ahc_tmode_tstate *tstate; - u_int our_id; - u_int target_id; - char channel; +#define AHC_REBD_LEN 4 - channel = 'A'; - our_id = ahc->our_id; - target_id = i; - if (i > 7 && (ahc->features & AHC_TWIN) != 0) { - channel = 'B'; - our_id = ahc->our_id_b; - target_id = i % 8; - } - tinfo = ahc_fetch_transinfo(ahc, channel, our_id, - target_id, &tstate); - tinfo->goal = tinfo->user; - /* - * Don't try negotiations that require PPR messages - * until we successfully retrieve Inquiry data. - */ - tinfo->goal.ppr_options = 0; - if (tinfo->goal.transport_version > SCSI_REV_2) - tinfo->goal.transport_version = SCSI_REV_2; - ahc_compile_devinfo(&devinfo, our_id, target_id, - CAM_LUN_WILDCARD, channel, ROLE_INITIATOR); - ahc_update_neg_request(ahc, &devinfo, tstate, - tinfo, /*force*/FALSE); - } - /* Give the bus some time to recover */ - if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) { - ahc_linux_freeze_sim_queue(ahc); - init_timer(&ahc->platform_data->reset_timer); - ahc->platform_data->reset_timer.data = (u_long)ahc; - ahc->platform_data->reset_timer.expires = - jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000; - ahc->platform_data->reset_timer.function = - ahc_linux_release_sim_queue; - add_timer(&ahc->platform_data->reset_timer); +static void +ahc_linux_dv_rebd(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ) +{ + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending REBD\n"); } +#endif + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(AHC_REBD_LEN, M_DEVBUF, M_WAITOK); + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0b; + scsi_ulto3b(AHC_REBD_LEN, &cmd->cmnd[6]); + cmd->request_bufflen = AHC_REBD_LEN; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; } -int -ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) +static void +ahc_linux_dv_web(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ) { - ahc->platform_data = - malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT); - if (ahc->platform_data == NULL) - return (ENOMEM); - memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); - TAILQ_INIT(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->device_runq); - ahc->platform_data->irq = AHC_LINUX_NOIRQ; - ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; - ahc_lockinit(ahc); - ahc_done_lockinit(ahc); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); -#else - ahc->platform_data->eh_sem = MUTEX_LOCKED; -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet, - (unsigned long)ahc); + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending WEB\n"); + } #endif - ahc->seltime = (aic7xxx_seltime & 0x3) << 4; - ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; - if (TAILQ_EMPTY(&ahc_tailq)) - register_reboot_notifier(&ahc_linux_notifier); - return (0); + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_WRITE; + cmd->cmd_len = 10; + cmd->cmnd[0] = WRITE_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer; } -void -ahc_platform_free(struct ahc_softc *ahc) +static void +ahc_linux_dv_reb(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, struct ahc_linux_target *targ) { - if (ahc->platform_data != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_kill(&ahc->platform_data->runq_tasklet); -#endif - if (ahc->platform_data->host != NULL) - scsi_unregister(ahc->platform_data->host); - if (ahc->platform_data->irq != AHC_LINUX_NOIRQ) - free_irq(ahc->platform_data->irq, ahc); - if (ahc->tag == BUS_SPACE_PIO - && ahc->bsh.ioport != 0) - release_region(ahc->bsh.ioport, 256); - if (ahc->tag == BUS_SPACE_MEMIO - && ahc->bsh.maddr != NULL) { - u_long base_addr; - base_addr = (u_long)ahc->bsh.maddr; - base_addr &= PAGE_MASK; - iounmap((void *)base_addr); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - release_mem_region(ahc->platform_data->mem_busaddr, - 0x1000); -#endif - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - /* XXX Need an instance detach in the PCI code */ - if (ahc->dev_softc != NULL) - ahc->dev_softc->driver = NULL; -#endif - free(ahc->platform_data, M_DEVBUF); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending REB\n"); } - if (TAILQ_EMPTY(&ahc_tailq)) { - unregister_reboot_notifier(&ahc_linux_notifier); -#ifdef CONFIG_PCI -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - pci_unregister_driver(&aic7xxx_pci_driver); -#endif #endif - } + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_READ; + cmd->cmd_len = 10; + cmd->cmnd[0] = READ_BUFFER; + cmd->cmnd[1] = 0x0a; + scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]); + cmd->request_bufflen = targ->dv_echo_size; + cmd->underflow = cmd->request_bufflen; + cmd->request_buffer = targ->dv_buffer1; } -void -ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb) -{ - ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb), - SCB_GET_CHANNEL(ahc, scb), - SCB_GET_LUN(scb), SCB_LIST_NULL, - ROLE_UNKNOWN, CAM_REQUEUE_REQ); +static void +ahc_linux_dv_su(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + struct ahc_linux_target *targ) +{ + u_int le; + + le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0; + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Sending SU\n"); + } +#endif + ahc_linux_dv_fill_cmd(ahc, cmd, devinfo); + cmd->sc_data_direction = SCSI_DATA_NONE; + cmd->cmd_len = 6; + cmd->cmnd[0] = START_STOP_UNIT; + cmd->cmnd[4] = le | SSS_START; } -void -ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, - ahc_queue_alg alg) +static int +ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) { - struct ahc_linux_device *dev; - int was_queuing; - int now_queuing; - - dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', - devinfo->target, - devinfo->lun, /*alloc*/FALSE); - if (dev == NULL) - return; - was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED); - now_queuing = alg != AHC_QUEUE_NONE; - if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0 - && (was_queuing != now_queuing) - && (dev->active != 0)) { - dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY; - dev->qfrozen++; + struct ahc_linux_target *targ; + struct ahc_initiator_tinfo *tinfo; + struct ahc_transinfo *goal; + struct ahc_tmode_tstate *tstate; + struct ahc_syncrate *syncrate; + u_long s; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int cur_speed; + u_int wide_speed; + u_int narrow_speed; + u_int fallback_speed; + +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + ahc_print_devinfo(ahc, devinfo); + printf("Trying to fallback\n"); + } +#endif + ahc_lock(ahc, &s); + targ = ahc->platform_data->targets[devinfo->target_offset]; + tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + goal = &tinfo->goal; + width = goal->width; + period = goal->period; + offset = goal->offset; + ppr_options = goal->ppr_options; + if (offset == 0) + period = AHC_ASYNC_XFER_PERIOD; + if (targ->dv_next_narrow_period == 0) + targ->dv_next_narrow_period = MAX(period, AHC_SYNCRATE_ULTRA2); + if (targ->dv_next_wide_period == 0) + targ->dv_next_wide_period = period; + if (targ->dv_max_width == 0) + targ->dv_max_width = width; + if (targ->dv_max_ppr_options == 0) + targ->dv_max_ppr_options = ppr_options; + if (targ->dv_last_ppr_options == 0) + targ->dv_last_ppr_options = ppr_options; + + cur_speed = aic_calc_speed(width, period, offset, AHC_SYNCRATE_MIN); + wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, + targ->dv_next_wide_period, + MAX_OFFSET, + AHC_SYNCRATE_MIN); + narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, + targ->dv_next_narrow_period, + MAX_OFFSET, + AHC_SYNCRATE_MIN); + fallback_speed = aic_calc_speed(width, period+1, offset, + AHC_SYNCRATE_MIN); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, " + "fallback_speed= %d\n", cur_speed, wide_speed, + narrow_speed, fallback_speed); } +#endif - dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG); - if (now_queuing) { - u_int usertags; + if (cur_speed > 160000) { + /* + * Paced/DT/IU_REQ only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + } else if (cur_speed > 80000) { + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + /* + * Try without IU_REQ as it may be confusing + * an expander. + */ + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else { + /* + * Paced/DT only transfer speeds. All we + * can do is fallback in terms of syncrate. + */ + period++; + ppr_options = targ->dv_max_ppr_options; + } + } else if (cur_speed > 3300) { - usertags = ahc_linux_user_tagdepth(ahc, devinfo); - if (!was_queuing) { + /* + * In this range we the following + * options ordered from highest to + * lowest desireability: + * + * o Wide/DT + * o Wide/non-DT + * o Narrow at a potentally higher sync rate. + * + * All modes are tested with and without IU_REQ + * set since using IUs may confuse an expander. + */ + if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + + ppr_options &= ~MSG_EXT_PPR_IU_REQ; + } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) { /* - * Start out agressively and allow our - * dynamic queue depth algorithm to take - * care of the rest. + * Try going non-DT. */ - dev->maxtags = usertags; - dev->openings = dev->maxtags - dev->active; + ppr_options = targ->dv_max_ppr_options; + ppr_options &= ~MSG_EXT_PPR_DT_REQ; + } else if (targ->dv_last_ppr_options != 0) { + /* + * Try without QAS or any other PPR options. + * We may need a non-PPR message to work with + * an expander. We look at the "last PPR options" + * so we will perform this fallback even if the + * target responded to our PPR negotiation with + * no option bits set. + */ + ppr_options = 0; + } else if (width == MSG_EXT_WDTR_BUS_16_BIT) { + /* + * If the next narrow speed is greater than + * the next wide speed, fallback to narrow. + * Otherwise fallback to the next DT/Wide setting. + * The narrow async speed will always be smaller + * than the wide async speed, so handle this case + * specifically. + */ + ppr_options = targ->dv_max_ppr_options; + if (narrow_speed > fallback_speed + || period >= AHC_ASYNC_XFER_PERIOD) { + targ->dv_next_wide_period = period+1; + width = MSG_EXT_WDTR_BUS_8_BIT; + period = targ->dv_next_narrow_period; + } else { + period++; + } + } else if ((ahc->features & AHC_WIDE) != 0 + && targ->dv_max_width != 0 + && wide_speed >= fallback_speed + && (targ->dv_next_wide_period <= AHC_ASYNC_XFER_PERIOD + || period >= AHC_ASYNC_XFER_PERIOD)) { + + /* + * We are narrow. Try falling back + * to the next wide speed with + * all supported ppr options set. + */ + targ->dv_next_narrow_period = period+1; + width = MSG_EXT_WDTR_BUS_16_BIT; + period = targ->dv_next_wide_period; + ppr_options = targ->dv_max_ppr_options; + } else { + /* Only narrow fallback is allowed. */ + period++; + ppr_options = targ->dv_max_ppr_options; } - if (alg == AHC_QUEUE_TAGGED) { - dev->flags |= AHC_DEV_Q_TAGGED; - if (aic7xxx_periodic_otag != 0) - dev->flags |= AHC_DEV_PERIODIC_OTAG; - } else - dev->flags |= AHC_DEV_Q_BASIC; } else { - /* We can only have one opening. */ - dev->maxtags = 0; - dev->openings = 1 - dev->active; + ahc_unlock(ahc, &s); + return (-1); + } + offset = MAX_OFFSET; + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, + AHC_SYNCRATE_DT); + ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, FALSE); + if (period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + if (width == MSG_EXT_WDTR_BUS_8_BIT) + targ->dv_next_narrow_period = AHC_ASYNC_XFER_PERIOD; + else + targ->dv_next_wide_period = AHC_ASYNC_XFER_PERIOD; } + ahc_set_syncrate(ahc, devinfo, syncrate, period, offset, + ppr_options, AHC_TRANS_GOAL, FALSE); + targ->dv_last_ppr_options = ppr_options; + ahc_unlock(ahc, &s); + return (0); } -int -ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, - int lun, u_int tag, role_t role, uint32_t status) +static void +ahc_linux_dv_timeout(struct scsi_cmnd *cmd) { - int chan; - int maxchan; - int targ; - int maxtarg; - int clun; - int maxlun; - int count; + struct ahc_softc *ahc; + struct scb *scb; + u_long flags; - if (tag != SCB_LIST_NULL) - return (0); + ahc = *((struct ahc_softc **)cmd->device->host->hostdata); + ahc_lock(ahc, &flags); - chan = 0; - if (channel != ALL_CHANNELS) { - chan = channel - 'A'; - maxchan = chan + 1; - } else { - maxchan = (ahc->features & AHC_TWIN) ? 2 : 1; - } - targ = 0; - if (target != CAM_TARGET_WILDCARD) { - targ = target; - maxtarg = targ + 1; - } else { - maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8; +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) { + printf("%s: Timeout while doing DV command %x.\n", + ahc_name(ahc), cmd->cmnd[0]); + ahc_dump_card_state(ahc); } - clun = 0; - if (lun != CAM_LUN_WILDCARD) { - clun = lun; - maxlun = clun + 1; - } else { - maxlun = AHC_NUM_LUNS; +#endif + + /* + * Guard against "done race". No action is + * required if we just completed. + */ + if ((scb = (struct scb *)cmd->host_scribble) == NULL) { + ahc_unlock(ahc, &flags); + return; } - count = 0; - for (; chan < maxchan; chan++) { + /* + * Command has not completed. Mark this + * SCB as having failing status prior to + * resetting the bus, so we get the correct + * error code. + */ + if ((scb->flags & SCB_SENSE) != 0) + ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); + else + ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); + ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate*/TRUE); - for (; targ < maxtarg; targ++) { + /* + * Add a minimal bus settle delay for devices that are slow to + * respond after bus resets. + */ + ahc_linux_freeze_simq(ahc); + init_timer(&ahc->platform_data->reset_timer); + ahc->platform_data->reset_timer.data = (u_long)ahc; + ahc->platform_data->reset_timer.expires = jiffies + HZ / 2; + ahc->platform_data->reset_timer.function = + (ahc_linux_callback_t *)ahc_linux_release_simq; + add_timer(&ahc->platform_data->reset_timer); + if (ahc_linux_next_device_to_run(ahc) != NULL) + ahc_schedule_runq(ahc); + ahc_linux_run_complete_queue(ahc); + ahc_unlock(ahc, &flags); +} - for (; clun < maxlun; clun++) { - struct ahc_linux_device *dev; - struct ahc_busyq *busyq; - struct ahc_cmd *acmd; +static void +ahc_linux_dv_complete(struct scsi_cmnd *cmd) +{ + struct ahc_softc *ahc; - dev = ahc_linux_get_device(ahc, chan, - targ, clun, - /*alloc*/FALSE); - if (dev == NULL) - continue; + ahc = *((struct ahc_softc **)cmd->device->host->hostdata); - busyq = &dev->busyq; - while ((acmd = TAILQ_FIRST(busyq)) != NULL) { - Scsi_Cmnd *cmd; + /* Delete the DV timer before it goes off! */ + scsi_delete_timer(cmd); - cmd = &acmd_scsi_cmd(acmd); - TAILQ_REMOVE(busyq, acmd, - acmd_links.tqe); - count++; - cmd->result = status << 16; - ahc_linux_queue_cmd_complete(ahc, cmd); - } - } - } - } +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_DV) + printf("%s:%d:%d: Command completed, status= 0x%x\n", + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->result); +#endif - return (count); + /* Wake up the state machine */ + up(&ahc->platform_data->dv_cmd_sem); } -/* - * Sets the queue depth for each SCSI device hanging - * off the input host adapter. - */ static void -ahc_linux_select_queue_depth(struct Scsi_Host * host, - Scsi_Device * scsi_devs) +ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ) { - Scsi_Device *device; - struct ahc_softc *ahc; - u_long flags; - int scbnum; + uint16_t b; + u_int i; + u_int j; + + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); + targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK); - ahc = *((struct ahc_softc **)host->hostdata); - ahc_lock(ahc, &flags); - scbnum = 0; - for (device = scsi_devs; device != NULL; device = device->next) { - if (device->host == host) { - ahc_linux_device_queue_depth(ahc, device); - scbnum += device->queue_depth; + i = 0; + b = 0x0001; + for (j = 0 ; i < targ->dv_echo_size; j++) { + if (j < 32) { + /* + * 32bytes of sequential numbers. + */ + targ->dv_buffer[i++] = j & 0xff; + } else if (j < 48) { + /* + * 32bytes of repeating 0x0000, 0xffff. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00; + } else if (j < 64) { + /* + * 32bytes of repeating 0x5555, 0xaaaa. + */ + targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55; + } else { + /* + * Remaining buffer is filled with a repeating + * patter of: + * + * 0xffff + * ~0x0001 << shifted once in each loop. + */ + if (j & 0x02) { + if (j & 0x01) { + targ->dv_buffer[i++] = ~(b >> 8) & 0xff; + b <<= 1; + if (b == 0x0000) + b = 0x0001; + } else { + targ->dv_buffer[i++] = (~b & 0xff); + } + } else { + targ->dv_buffer[i++] = 0xff; + } } } - ahc_unlock(ahc, &flags); } static u_int @@ -1572,17 +3553,17 @@ tags = 0; if ((ahc->user_discenable & devinfo->target_mask) != 0) { - if (warned_user == 0 - && ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) { + if (ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) { + if (warned_user == 0) { - printf("aic7xxx: WARNING, insufficient " - "tag_info instances for installed " - "controllers. Using defaults\n"); - printf("aic7xxx: Please update the " - "aic7xxx_tag_info array in the " - "aic7xxx.c source file.\n"); + printf(KERN_WARNING +"aic7xxx: WARNING: Insufficient tag_info instances\n" +"aic7xxx: for installed controllers. Using defaults\n" +"aic7xxx: Please update the aic7xxx_tag_info array in\n" +"aic7xxx: the aic7xxx_osm..c source file.\n"); + warned_user++; + } tags = AHC_MAX_QUEUE; - warned_user++; } else { adapter_tag_info_t *tag_info; @@ -1595,74 +3576,75 @@ return (tags); } +static u_int +ahc_linux_user_dv_setting(struct ahc_softc *ahc) +{ + static int warned_user; + int dv; + + if (ahc->unit >= NUM_ELEMENTS(aic7xxx_dv_settings)) { + if (warned_user == 0) { + + printf(KERN_WARNING +"aic7xxx: WARNING: Insufficient dv settings instances\n" +"aic7xxx: for installed controllers. Using defaults\n" +"aic7xxx: Please update the aic7xxx_dv_settings array\n" +"aic7xxx: in the aic7xxx_osm.c source file.\n"); + warned_user++; + } + dv = -1; + } else { + + dv = aic7xxx_dv_settings[ahc->unit]; + } + + if (dv < 0) { + u_long s; + + /* + * Apply the default. + */ + /* + * XXX - Enable DV on non-U160 controllers once it + * has been tested there. + */ + ahc_lock(ahc, &s); + dv = (ahc->features & AHC_DT); + if (ahc->seep_config != 0 + && ahc->seep_config->signature >= CFSIGNATURE2) + dv = (ahc->seep_config->adapter_control & CFENABLEDV); + ahc_unlock(ahc, &s); + } + return (dv); +} + /* * Determines the queue depth for a given device. */ static void -ahc_linux_device_queue_depth(struct ahc_softc *ahc, Scsi_Device * device) +ahc_linux_device_queue_depth(struct ahc_softc *ahc, + struct ahc_linux_device *dev) { struct ahc_devinfo devinfo; u_int tags; ahc_compile_devinfo(&devinfo, - device->channel == 0 ? ahc->our_id : ahc->our_id_b, - device->id, device->lun, - device->channel == 0 ? 'A' : 'B', + dev->target->channel == 0 + ? ahc->our_id : ahc->our_id_b, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', ROLE_INITIATOR); tags = ahc_linux_user_tagdepth(ahc, &devinfo); if (tags != 0 - && device->tagged_supported != 0) { + && dev->scsi_device != NULL + && dev->scsi_device->tagged_supported != 0) { - device->queue_depth = tags; ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED); - printf("scsi%d:%c:%d:%d: Tagged Queuing enabled. Depth %d\n", - ahc->platform_data->host->host_no, devinfo.channel, - devinfo.target, devinfo.lun, tags); + ahc_print_devinfo(ahc, &devinfo); + printf("Tagged Queuing enabled. Depth %d\n", tags); } else { - /* - * We allow the OS to queue 2 untagged transactions to - * us at any time even though we can only execute them - * serially on the controller/device. This should remove - * some latency. - */ - device->queue_depth = 2; - } -} - -/* - * Queue an SCB to the controller. - */ -int -ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) -{ - struct ahc_softc *ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = *(struct ahc_softc **)cmd->host->hostdata; - - /* - * Save the callback on completion function. - */ - cmd->scsi_done = scsi_done; - - ahc_lock(ahc, &flags); - dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, - cmd->lun, /*alloc*/TRUE); - if (dev == NULL) { - ahc_unlock(ahc, &flags); - printf("aic7xxx_linux_queue: Unable to allocate device!\n"); - return (-ENOMEM); - } - cmd->result = CAM_REQ_INPROG << 16; - TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); - if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); - dev->flags |= AHC_DEV_ON_RUN_LIST; - ahc_linux_run_device_queues(ahc); + ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE); } - ahc_unlock(ahc, &flags); - return (0); } static void @@ -1686,8 +3668,8 @@ * Schedule us to run later. The only reason we are not * running is because the whole controller Q is frozen. */ - if (ahc->platform_data->qfrozen != 0) { - + if (ahc->platform_data->qfrozen != 0 + && AHC_DV_SIMQ_FROZEN(ahc) == 0) { TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); dev->flags |= AHC_DEV_ON_RUN_LIST; @@ -1715,7 +3697,7 @@ */ hscb->control = 0; hscb->scsiid = BUILD_SCSIID(ahc, cmd); - hscb->lun = cmd->lun; + hscb->lun = cmd->device->lun; mask = SCB_GET_TARGET_MASK(ahc, scb); tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb), SCB_GET_OUR_ID(scb), @@ -1728,12 +3710,26 @@ if ((ahc->user_discenable & mask) != 0) hscb->control |= DISCENB; + if (AHC_DV_CMD(cmd) != 0) + scb->flags |= SCB_SILENT; + if ((tstate->auto_negotiate & mask) != 0) { scb->flags |= SCB_AUTO_NEGOTIATE; scb->hscb->control |= MK_MESSAGE; } if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + int msg_bytes; + uint8_t tag_msgs[2]; + + msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); + if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { + hscb->control |= tag_msgs[0]; + if (tag_msgs[0] == MSG_ORDERED_TASK) + dev->commands_since_idle_or_otag = 0; + } else +#endif if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { hscb->control |= MSG_ORDERED_TASK; @@ -1763,7 +3759,7 @@ cur_seg = (struct scatterlist *)cmd->request_buffer; nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg, - scsi_to_pci_dma_dir(cmd ->sc_data_direction)); + scsi_to_pci_dma_dir(cmd->sc_data_direction)); end_seg = cur_seg + nseg; /* Copy the segments into the SG list. */ sg = scb->sg_list; @@ -1867,41 +3863,29 @@ /* * SCSI controller interrupt handler. */ -void +irqreturn_t ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs) { struct ahc_softc *ahc; - struct ahc_cmd *acmd; u_long flags; - struct ahc_linux_device *next_dev; + int ours; ahc = (struct ahc_softc *) dev_id; ahc_lock(ahc, &flags); - ahc_intr(ahc); - acmd = TAILQ_FIRST(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->completeq); - next_dev = ahc_linux_next_device_to_run(ahc); + ours = ahc_intr(ahc); + if (ahc_linux_next_device_to_run(ahc) != NULL) + ahc_schedule_runq(ahc); + ahc_linux_run_complete_queue(ahc); ahc_unlock(ahc, &flags); - if (next_dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_schedule(&ahc->platform_data->runq_tasklet); -#else - ahc_runq_tasklet((unsigned long)ahc); -#endif - } - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); + return IRQ_RETVAL(ours); } void ahc_platform_flushwork(struct ahc_softc *ahc) { - struct ahc_cmd *acmd; - acmd = TAILQ_FIRST(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->completeq); - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); + while (ahc_linux_run_complete_queue(ahc) != NULL) + ; } static struct ahc_linux_target* @@ -1910,6 +3894,10 @@ struct ahc_linux_target *targ; u_int target_offset; + target_offset = target; + if (channel != 0) + target_offset += 8; + targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT); if (targ == NULL) return (NULL); @@ -1917,9 +3905,7 @@ targ->channel = channel; targ->target = target; targ->ahc = ahc; - target_offset = target; - if (channel != 0) - target_offset += 8; + targ->flags = AHC_DV_REQUIRED; ahc->platform_data->targets[target_offset] = targ; return (targ); } @@ -1927,12 +3913,41 @@ static void ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ) { + struct ahc_devinfo devinfo; + struct ahc_initiator_tinfo *tinfo; + struct ahc_tmode_tstate *tstate; + u_int our_id; u_int target_offset; + char channel; + /* + * Force a negotiation to async/narrow on any + * future command to this device unless a bus + * reset occurs between now and that command. + */ + channel = 'A' + targ->channel; + our_id = ahc->our_id; target_offset = targ->target; - if (targ->channel != 0) + if (targ->channel != 0) { target_offset += 8; + our_id = ahc->our_id_b; + } + tinfo = ahc_fetch_transinfo(ahc, channel, our_id, + targ->target, &tstate); + ahc_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD, + channel, ROLE_INITIATOR); + ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_update_neg_request(ahc, &devinfo, tstate, tinfo, AHC_NEG_ALWAYS); ahc->platform_data->targets[target_offset] = NULL; + if (targ->inq_data != NULL) + free(targ->inq_data, M_DEVBUF); + if (targ->dv_buffer != NULL) + free(targ->dv_buffer, M_DEVBUF); + if (targ->dv_buffer1 != NULL) + free(targ->dv_buffer1, M_DEVBUF); free(targ, M_DEVBUF); } @@ -1975,43 +3990,16 @@ { struct ahc_linux_target *targ; - del_timer(&dev->timer); + del_timer_sync(&dev->timer); targ = dev->target; targ->devices[dev->lun] = NULL; free(dev, M_DEVBUF); targ->refcount--; - if (targ->refcount == 0) + if (targ->refcount == 0 + && (targ->flags & AHC_DV_REQUIRED) == 0) ahc_linux_free_target(ahc, targ); } -/* - * Return a string describing the driver. - */ -const char * -ahc_linux_info(struct Scsi_Host *host) -{ - static char buffer[512]; - char ahc_info[256]; - char *bp; - struct ahc_softc *ahc; - - bp = &buffer[0]; - ahc = *(struct ahc_softc **)host->hostdata; - memset(bp, 0, sizeof(buffer)); - strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev "); - strcat(bp, AIC7XXX_DRIVER_VERSION); - strcat(bp, "\n"); - strcat(bp, " <"); - strcat(bp, ahc->description); - strcat(bp, ">\n"); - strcat(bp, " "); - ahc_controller_info(ahc, ahc_info); - strcat(bp, ahc_info); - strcat(bp, "\n"); - - return (bp); -} - void ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun, ac_code code, void *arg) @@ -2082,7 +4070,31 @@ break; } case AC_SENT_BDR: + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + WARN_ON(lun != CAM_LUN_WILDCARD); + scsi_report_device_reset(ahc->platform_data->host, + channel - 'A', target); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + Scsi_Device *scsi_dev; + + /* + * Find the SCSI device associated with this + * request and indicate that a UA is expected. + */ + for (scsi_dev = ahc->platform_data->host->host_queue; + scsi_dev != NULL; scsi_dev = scsi_dev->next) { + if (channel - 'A' == scsi_dev->channel + && target == scsi_dev->id + && (lun == CAM_LUN_WILDCARD + || lun == scsi_dev->lun)) { + scsi_dev->was_reset = 1; + scsi_dev->expecting_cc_ua = 1; + } + } +#endif break; + } case AC_BUS_RESET: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) if (ahc->platform_data->host != NULL) { @@ -2100,10 +4112,10 @@ * Calls the higher level scsi done function and frees the scb. */ void -ahc_done(struct ahc_softc *ahc, struct scb * scb) +ahc_done(struct ahc_softc *ahc, struct scb *scb) { Scsi_Cmnd *cmd; - struct ahc_linux_device *dev; + struct ahc_linux_device *dev; LIST_REMOVE(scb, pending_links); if ((scb->flags & SCB_UNTAGGEDQ) != 0) { @@ -2125,27 +4137,41 @@ dev = scb->platform_data->dev; dev->active--; dev->openings++; - ahc_linux_unmap_scb(ahc, scb); - if (scb->flags & SCB_SENSE) { - memcpy(cmd->sense_buffer, ahc_get_sense_buf(ahc, scb), - MIN(sizeof(struct scsi_sense_data), - sizeof(cmd->sense_buffer))); - cmd->result |= (DRIVER_SENSE << 24); - } else { - /* - * Guard against stale sense data. - * The Linux mid-layer assumes that sense - * was retrieved anytime the first byte of - * the sense buffer looks "sane". - */ - cmd->sense_buffer[0] = 0; + if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) { + cmd->result &= ~(CAM_DEV_QFRZN << 16); + dev->qfrozen--; } + ahc_linux_unmap_scb(ahc, scb); + + /* + * Guard against stale sense data. + * The Linux mid-layer assumes that sense + * was retrieved anytime the first byte of + * the sense buffer looks "sane". + */ + cmd->sense_buffer[0] = 0; if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) { uint32_t amount_xferred; amount_xferred = ahc_get_transfer_length(scb) - ahc_get_residual(scb); - if (amount_xferred < scb->io_ctx->underflow) { + if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) { +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_SHOW_MISC) != 0) { + ahc_print_path(ahc, scb); + printf("Set CAM_UNCOR_PARITY\n"); + } +#endif + ahc_set_transaction_status(scb, CAM_UNCOR_PARITY); + } else if (amount_xferred < scb->io_ctx->underflow) { + u_int i; + + ahc_print_path(ahc, scb); + printf("CDB:"); + for (i = 0; i < scb->io_ctx->cmd_len; i++) + printf(" 0x%x", scb->io_ctx->cmnd[i]); + printf("\n"); + ahc_print_path(ahc, scb); printf("Saw underflow (%ld of %ld bytes). " "Treated as error\n", ahc_get_residual(scb), @@ -2153,20 +4179,21 @@ ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR); } else { ahc_set_transaction_status(scb, CAM_REQ_CMP); - ahc_linux_sniff_command(ahc, cmd, scb); } - } else if (ahc_get_transaction_status(scb) == DID_OK) { + } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { ahc_linux_handle_scsi_status(ahc, dev, scb); - } else if (ahc_get_transaction_status(scb) == DID_NO_CONNECT) { - /* - * Should a selection timeout kill the device? - * That depends on whether the selection timeout - * is persistent. Since we have no guarantee that - * the mid-layer will issue an inquiry for this device - * again, we can't just kill it off. + } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) { dev->flags |= AHC_DEV_UNCONFIGURED; - */ + if (AHC_DV_CMD(cmd) == FALSE) + dev->target->flags &= ~AHC_DV_REQUIRED; } + /* + * Start DV for devices that require it assuming the first command + * sent does not result in a selection timeout. + */ + if (ahc_get_transaction_status(scb) != CAM_SEL_TIMEOUT + && (dev->target->flags & AHC_DV_REQUIRED) != 0) + ahc_linux_start_dv(ahc); if (dev->openings == 1 && ahc_get_transaction_status(scb) == CAM_REQ_CMP @@ -2189,7 +4216,8 @@ if (TAILQ_EMPTY(&dev->busyq)) { if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0 - && dev->active == 0) + && dev->active == 0 + && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) ahc_linux_free_device(ahc, dev); } else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); @@ -2198,17 +4226,38 @@ if ((scb->flags & SCB_RECOVERY_SCB) != 0) { printf("Recovery SCB completes\n"); - up(&ahc->platform_data->eh_sem); + if (ahc_get_transaction_status(scb) == CAM_BDR_SENT + || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED) + ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); + if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { + ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; + up(&ahc->platform_data->eh_sem); + } } ahc_free_scb(ahc, scb); ahc_linux_queue_cmd_complete(ahc, cmd); + + if ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_EMPTY) != 0 + && LIST_FIRST(&ahc->pending_scbs) == NULL) { + ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_EMPTY; + up(&ahc->platform_data->dv_sem); + } + } static void ahc_linux_handle_scsi_status(struct ahc_softc *ahc, struct ahc_linux_device *dev, struct scb *scb) { + struct ahc_devinfo devinfo; + + ahc_compile_devinfo(&devinfo, + ahc->our_id, + dev->target->target, dev->lun, + dev->target->channel == 0 ? 'A' : 'B', + ROLE_INITIATOR); + /* * We don't currently trust the mid-layer to * properly deal with queue full or busy. So, @@ -2222,6 +4271,45 @@ switch (ahc_get_scsi_status(scb)) { default: break; + case SCSI_STATUS_CHECK_COND: + case SCSI_STATUS_CMD_TERMINATED: + { + Scsi_Cmnd *cmd; + + /* + * Copy sense information to the OS's cmd + * structure if it is available. + */ + cmd = scb->io_ctx; + if (scb->flags & SCB_SENSE) { + u_int sense_size; + + sense_size = MIN(sizeof(struct scsi_sense_data) + - ahc_get_sense_residual(scb), + sizeof(cmd->sense_buffer)); + memcpy(cmd->sense_buffer, + ahc_get_sense_buf(ahc, scb), sense_size); + if (sense_size < sizeof(cmd->sense_buffer)) + memset(&cmd->sense_buffer[sense_size], 0, + sizeof(cmd->sense_buffer) - sense_size); + cmd->result |= (DRIVER_SENSE << 24); +#ifdef AHC_DEBUG + if (ahc_debug & AHC_SHOW_SENSE) { + int i; + + printf("Copied %d bytes of sense data:", + sense_size); + for (i = 0; i < sense_size; i++) { + if ((i & 0xF) == 0) + printf("\n"); + printf("0x%x ", cmd->sense_buffer[i]); + } + printf("\n"); + } +#endif + } + break; + } case SCSI_STATUS_QUEUE_FULL: { /* @@ -2267,13 +4355,20 @@ } ahc_set_transaction_status(scb, CAM_REQUEUE_REQ); ahc_set_scsi_status(scb, SCSI_STATUS_OK); + ahc_platform_set_tags(ahc, &devinfo, + (dev->flags & AHC_DEV_Q_BASIC) + ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); break; } /* * Drop down to a single opening, and treat this - * as if the target return BUSY SCSI status. + * as if the target returned BUSY SCSI status. */ dev->openings = 1; + ahc_set_scsi_status(scb, SCSI_STATUS_BUSY); + ahc_platform_set_tags(ahc, &devinfo, + (dev->flags & AHC_DEV_Q_BASIC) + ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); /* FALLTHROUGH */ } case SCSI_STATUS_BUSY: @@ -2301,206 +4396,280 @@ } static void -ahc_linux_filter_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb) +ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) +{ + /* + * Typically, the complete queue has very few entries + * queued to it before the queue is emptied by + * ahc_linux_run_complete_queue, so sorting the entries + * by generation number should be inexpensive. + * We perform the sort so that commands that complete + * with an error are retuned in the order origionally + * queued to the controller so that any subsequent retries + * are performed in order. The underlying ahc routines do + * not guarantee the order that aborted commands will be + * returned to us. + */ + struct ahc_completeq *completeq; + struct ahc_cmd *list_cmd; + struct ahc_cmd *acmd; + + /* + * Map CAM error codes into Linux Error codes. We + * avoid the conversion so that the DV code has the + * full error information available when making + * state change decisions. + */ + if (AHC_DV_CMD(cmd) == FALSE) { + u_int new_status; + + switch (ahc_cmd_get_transaction_status(cmd)) { + case CAM_REQ_INPROG: + case CAM_REQ_CMP: + case CAM_SCSI_STATUS_ERROR: + new_status = DID_OK; + break; + case CAM_REQ_ABORTED: + new_status = DID_ABORT; + break; + case CAM_BUSY: + new_status = DID_BUS_BUSY; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + new_status = DID_BAD_TARGET; + break; + case CAM_SEL_TIMEOUT: + new_status = DID_NO_CONNECT; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + new_status = DID_RESET; + break; + case CAM_UNCOR_PARITY: + new_status = DID_PARITY; + break; + case CAM_CMD_TIMEOUT: + new_status = DID_TIME_OUT; + break; + case CAM_UA_ABORT: + case CAM_REQ_CMP_ERR: + case CAM_AUTOSENSE_FAIL: + case CAM_NO_HBA: + case CAM_DATA_RUN_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_SEQUENCE_FAIL: + case CAM_CCB_LEN_ERR: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TERMIO: + case CAM_UNREC_HBA_ERROR: + case CAM_REQ_TOO_BIG: + new_status = DID_ERROR; + break; + case CAM_REQUEUE_REQ: + /* + * If we want the request requeued, make sure there + * are sufficent retries. In the old scsi error code, + * we used to be able to specify a result code that + * bypassed the retry count. Now we must use this + * hack. We also "fake" a check condition with + * a sense code of ABORTED COMMAND. This seems to + * evoke a retry even if this command is being sent + * via the eh thread. Ick! Ick! Ick! + */ + if (cmd->retries > 0) + cmd->retries--; + new_status = DID_OK; + ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); + cmd->result |= (DRIVER_SENSE << 24); + memset(cmd->sense_buffer, 0, + sizeof(cmd->sense_buffer)); + cmd->sense_buffer[0] = SSD_ERRCODE_VALID + | SSD_CURRENT_ERROR; + cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND; + break; + default: + /* We should never get here */ + new_status = DID_ERROR; + break; + } + + ahc_cmd_set_transaction_status(cmd, new_status); + } + + completeq = &ahc->platform_data->completeq; + list_cmd = TAILQ_FIRST(completeq); + acmd = (struct ahc_cmd *)cmd; + while (list_cmd != NULL + && acmd_scsi_cmd(list_cmd).serial_number + < acmd_scsi_cmd(acmd).serial_number) + list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); + if (list_cmd != NULL) + TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); + else + TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); +} + +static void +ahc_linux_filter_inquiry(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) { - switch (cmd->cmnd[0]) { - case INQUIRY: - { - struct ahc_devinfo devinfo; - struct scsi_inquiry *inq; - struct scsi_inquiry_data *sid; - struct ahc_initiator_tinfo *tinfo; - struct ahc_transinfo *user; - struct ahc_transinfo *goal; - struct ahc_transinfo *curr; - struct ahc_tmode_tstate *tstate; - struct ahc_syncrate *syncrate; - struct ahc_linux_device *dev; - u_int scsiid; - u_int maxsync; - int transferred_len; - int minlen; - u_int width; - u_int period; - u_int offset; - u_int ppr_options; - - /* - * Validate the command. We only want to filter - * standard inquiry commands, not those querying - * Vital Product Data. - */ - inq = (struct scsi_inquiry *)cmd->cmnd; - if ((inq->byte2 & SI_EVPD) != 0 - || inq->page_code != 0) - break; - - if (cmd->use_sg != 0) { - printf("%s: SG Inquiry response ignored\n", - ahc_name(ahc)); - break; - } - transferred_len = ahc_get_transfer_length(scb) - - ahc_get_residual(scb); - sid = (struct scsi_inquiry_data *)cmd->request_buffer; + struct scsi_inquiry_data *sid; + struct ahc_initiator_tinfo *tinfo; + struct ahc_transinfo *user; + struct ahc_transinfo *goal; + struct ahc_transinfo *curr; + struct ahc_tmode_tstate *tstate; + struct ahc_syncrate *syncrate; + struct ahc_linux_device *dev; + u_int maxsync; + u_int width; + u_int period; + u_int offset; + u_int ppr_options; + u_int trans_version; + u_int prot_version; - /* - * Determine if this lun actually exists. If so, - * hold on to its corresponding device structure. - * If not, make sure we release the device and - * don't bother processing the rest of this inquiry - * command. - */ - dev = ahc_linux_get_device(ahc, cmd->channel, - cmd->target, cmd->lun, - /*alloc*/FALSE); - if (transferred_len >= 1 - && SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) { + /* + * Determine if this lun actually exists. If so, + * hold on to its corresponding device structure. + * If not, make sure we release the device and + * don't bother processing the rest of this inquiry + * command. + */ + dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', + devinfo->target, devinfo->lun, + /*alloc*/TRUE); - dev->flags &= ~AHC_DEV_UNCONFIGURED; - } else { - dev->flags |= AHC_DEV_UNCONFIGURED; - break; - } + sid = (struct scsi_inquiry_data *)dev->target->inq_data; + if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) { - /* - * Update our notion of this device's transfer - * negotiation capabilities. - */ - scsiid = BUILD_SCSIID(ahc, cmd); - ahc_compile_devinfo(&devinfo, SCSIID_OUR_ID(scsiid), - cmd->target, cmd->lun, - SCSIID_CHANNEL(ahc, scsiid), - ROLE_INITIATOR); - tinfo = ahc_fetch_transinfo(ahc, devinfo.channel, - devinfo.our_scsiid, - devinfo.target, &tstate); - user = &tinfo->user; - goal = &tinfo->goal; - curr = &tinfo->curr; - width = user->width; - period = user->period; - offset = user->offset; - ppr_options = user->ppr_options; - minlen = offsetof(struct scsi_inquiry_data, version) + 1; - if (transferred_len >= minlen) { - curr->protocol_version = SID_ANSI_REV(sid); + dev->flags &= ~AHC_DEV_UNCONFIGURED; + } else { + dev->flags |= AHC_DEV_UNCONFIGURED; + return; + } - /* - * Only attempt SPI3 once we've verified that - * the device claims to support SPI3 features. - */ - if (curr->protocol_version < SCSI_REV_2) - curr->transport_version = SID_ANSI_REV(sid); - else - curr->transport_version = SCSI_REV_2; - } + /* + * Update our notion of this device's transfer + * negotiation capabilities. + */ + tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, + devinfo->our_scsiid, + devinfo->target, &tstate); + user = &tinfo->user; + goal = &tinfo->goal; + curr = &tinfo->curr; + width = user->width; + period = user->period; + offset = user->offset; + ppr_options = user->ppr_options; + trans_version = user->transport_version; + prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid)); - minlen = offsetof(struct scsi_inquiry_data, flags) + 1; - if (transferred_len >= minlen - && (sid->additional_length + 4) >= minlen) { - if ((sid->flags & SID_WBus16) == 0) - width = MSG_EXT_WDTR_BUS_8_BIT; - if ((sid->flags & SID_Sync) == 0) { - period = 0; - offset = 0; - ppr_options = 0; - } - } else { - /* Keep current settings */ - break; - } - minlen = offsetof(struct scsi_inquiry_data, spi3data) + 1; - /* - * This is a kludge to deal with inquiry requests that - * are not large enough for us to pull the spi3/4 bits. - * In this case, we assume that a device that tells us - * they can provide inquiry data that spans the SPI3 - * bits and says its SCSI3 can handle a PPR request. - * If the inquiry request has sufficient buffer space to - * cover SPI3 bits, we honor them regardless of reported - * SCSI REV. We also allow any device that has had its - * goal ppr_options set to allow DT speeds to keep that - * option if a short inquiry occurs that would fail the - * normal tests outlined above. - */ - if ((sid->additional_length + 4) >= minlen) { - if (transferred_len >= minlen) { - if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0) - ppr_options = 0; - } else if ((goal->ppr_options & MSG_EXT_PPR_DT_REQ)== 0) - ppr_options = 0; + /* + * Only attempt SPI3/4 once we've verified that + * the device claims to support SPI3/4 features. + */ + if (prot_version < SCSI_REV_2) + trans_version = SID_ANSI_REV(sid); + else + trans_version = SCSI_REV_2; - if (curr->protocol_version > SCSI_REV_2) - curr->transport_version = 3; - } else { - ppr_options = 0; - } - ahc_validate_width(ahc, /*tinfo limit*/NULL, &width, - ROLE_UNKNOWN); - if ((ahc->features & AHC_ULTRA2) != 0) - maxsync = AHC_SYNCRATE_DT; - else if ((ahc->features & AHC_ULTRA) != 0) - maxsync = AHC_SYNCRATE_ULTRA; - else - maxsync = AHC_SYNCRATE_FAST; + if ((sid->flags & SID_WBus16) == 0) + width = MSG_EXT_WDTR_BUS_8_BIT; + if ((sid->flags & SID_Sync) == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + if ((sid->spi3data & SID_SPI_QAS) == 0) + ppr_options &= ~MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0) + ppr_options &= MSG_EXT_PPR_QAS_REQ; + if ((sid->spi3data & SID_SPI_IUS) == 0) + ppr_options &= (MSG_EXT_PPR_DT_REQ + | MSG_EXT_PPR_QAS_REQ); + + if (prot_version > SCSI_REV_2 + && ppr_options != 0) + trans_version = user->transport_version; + + ahc_validate_width(ahc, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN); + if ((ahc->features & AHC_ULTRA2) != 0) + maxsync = AHC_SYNCRATE_DT; + else if ((ahc->features & AHC_ULTRA) != 0) + maxsync = AHC_SYNCRATE_ULTRA; + else + maxsync = AHC_SYNCRATE_FAST; - syncrate = ahc_find_syncrate(ahc, &period, - &ppr_options, maxsync); - ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate, - &offset, width, ROLE_UNKNOWN); - if (offset == 0 || period == 0) { - period = 0; - offset = 0; - ppr_options = 0; - } - /* Apply our filtered user settings. */ - ahc_set_width(ahc, &devinfo, width, - AHC_TRANS_GOAL, /*paused*/FALSE); - ahc_set_syncrate(ahc, &devinfo, syncrate, period, - offset, ppr_options, AHC_TRANS_GOAL, - /*paused*/FALSE); - break; - } - default: - panic("ahc_linux_filter_command: Unexpected Command type %x\n", - cmd->cmnd[0]); - break; - } + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, maxsync); + ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate, + &offset, width, ROLE_UNKNOWN); + if (offset == 0 || period == 0) { + period = 0; + offset = 0; + ppr_options = 0; + } + /* Apply our filtered user settings. */ + curr->transport_version = trans_version; + curr->protocol_version = prot_version; + ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_set_syncrate(ahc, devinfo, syncrate, period, + offset, ppr_options, AHC_TRANS_GOAL, + /*paused*/FALSE); } static void ahc_linux_sem_timeout(u_long arg) { - struct semaphore *sem; + struct ahc_softc *ahc; + u_long s; + + ahc = (struct ahc_softc *)arg; - sem = (struct semaphore *)arg; - up(sem); + ahc_lock(ahc, &s); + if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { + ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; + up(&ahc->platform_data->eh_sem); + } + ahc_unlock(ahc, &s); } static void -ahc_linux_freeze_sim_queue(struct ahc_softc *ahc) +ahc_linux_freeze_simq(struct ahc_softc *ahc) { ahc->platform_data->qfrozen++; - if (ahc->platform_data->qfrozen == 1) + if (ahc->platform_data->qfrozen == 1) { scsi_block_requests(ahc->platform_data->host); + + /* XXX What about Twin channels? */ + ahc_platform_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ); + } } static void -ahc_linux_release_sim_queue(u_long arg) +ahc_linux_release_simq(u_long arg) { struct ahc_softc *ahc; u_long s; int unblock_reqs; ahc = (struct ahc_softc *)arg; + unblock_reqs = 0; ahc_lock(ahc, &s); if (ahc->platform_data->qfrozen > 0) ahc->platform_data->qfrozen--; - if (ahc->platform_data->qfrozen == 0) { + if (ahc->platform_data->qfrozen == 0) unblock_reqs = 1; + if (AHC_DV_SIMQ_FROZEN(ahc) + && ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_RELEASE) != 0)) { + ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_RELEASE; + up(&ahc->platform_data->dv_sem); } + ahc_schedule_runq(ahc); ahc_unlock(ahc, &s); /* * There is still a race here. The mid-layer @@ -2508,14 +4677,8 @@ * a bottom half handler to run the queues * so we can unblock with our own lock held. */ - if (unblock_reqs) { + if (unblock_reqs) scsi_unblock_requests(ahc->platform_data->host); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tasklet_schedule(&ahc->platform_data->runq_tasklet); -#else - ahc_runq_tasklet((unsigned long)ahc); -#endif - } } static void @@ -2534,6 +4697,9 @@ if (dev->qfrozen == 0 && (dev->flags & AHC_DEV_ON_RUN_LIST) == 0) ahc_linux_run_device_queue(ahc, dev); + if (TAILQ_EMPTY(&dev->busyq) + && dev->active == 0) + ahc_linux_free_device(ahc, dev); ahc_unlock(ahc, &s); } @@ -2549,37 +4715,55 @@ u_int saved_scbptr; u_int active_scb_index; u_int last_phase; + u_int saved_scsiid; + u_int cdb_byte; int retval; + int was_paused; int paused; int wait; int disconnected; + pending_scb = NULL; paused = FALSE; wait = FALSE; - ahc = *(struct ahc_softc **)cmd->host->hostdata; + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; acmd = (struct ahc_cmd *)cmd; printf("%s:%d:%d:%d: Attempting to queue a%s message\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun, + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->device->lun, flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); + printf("CDB:"); + for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++) + printf(" 0x%x", cmd->cmnd[cdb_byte]); + printf("\n"); + /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. + * In all versions of Linux, we have to work around + * a major flaw in how the mid-layer is locked down + * if we are to sleep successfully in our error handler + * while allowing our interrupt handler to run. Since + * the midlayer acquires either the io_request_lock or + * our lock prior to calling us, we must use the + * spin_unlock_irq() method for unlocking our lock. + * This will force interrupts to be enabled on the + * current CPU. Since the EH thread should not have + * been running with CPU interrupts disabled other than + * by acquiring either the io_request_lock or our own + * lock, this *should* be safe. */ - spin_unlock_irq(&io_request_lock); - - ahc_lock(ahc, &s); + ahc_midlayer_entrypoint_lock(ahc, &s); /* * First determine if we currently own this command. * Start by searching the device queue. If not found * there, check the pending_scb list. If not found * at all, and the system wanted us to just abort the - * command return success. + * command, return success. */ - dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, - cmd->lun, /*alloc*/FALSE); + dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/FALSE); if (dev == NULL) { /* @@ -2587,7 +4771,8 @@ * so we must not still own the command. */ printf("%s:%d:%d:%d: Is not an active device\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = SUCCESS; goto no_cmd; } @@ -2599,7 +4784,8 @@ if (list_acmd != NULL) { printf("%s:%d:%d:%d: Command found on device queue\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); if (flag == SCB_ABORT) { TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); cmd->result = DID_ABORT << 16; @@ -2610,11 +4796,13 @@ } if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 - && ahc_search_untagged_queues(ahc, cmd, cmd->target, - cmd->channel + 'A', cmd->lun, + && ahc_search_untagged_queues(ahc, cmd, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) { printf("%s:%d:%d:%d: Command found on untagged queue\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = SUCCESS; goto done; } @@ -2631,8 +4819,9 @@ /* Any SCB for this device will do for a target reset */ LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) { - if (ahc_match_scb(ahc, pending_scb, cmd->target, - cmd->channel + 'A', CAM_LUN_WILDCARD, + if (ahc_match_scb(ahc, pending_scb, cmd->device->id, + cmd->device->channel + 'A', + CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_INITIATOR) == 0) break; } @@ -2640,7 +4829,8 @@ if (pending_scb == NULL) { printf("%s:%d:%d:%d: Command not found\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); goto no_cmd; } @@ -2654,52 +4844,47 @@ /* * Ensure that the card doesn't do anything - * behind our back and that no selections have occurred - * that have not been serviced. Also make sure that we - * didn't "just" miss an interrupt that would - * affect this cmd. - */ - ahc->flags |= AHC_ALL_INTERRUPTS; - do { - if (paused) - ahc_unpause(ahc); - ahc_intr(ahc); - ahc_pause(ahc); - paused = TRUE; - ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO); - ahc_clear_critical_section(ahc); - } while ((ahc_inb(ahc, INTSTAT) & INT_PEND) != 0 - || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO))); - ahc->flags &= ~AHC_ALL_INTERRUPTS; - - ahc_dump_card_state(ahc); + * behind our back and that we didn't "just" miss + * an interrupt that would affect this cmd. + */ + was_paused = ahc_is_paused(ahc); + ahc_pause_and_flushwork(ahc); + paused = TRUE; if ((pending_scb->flags & SCB_ACTIVE) == 0) { printf("%s:%d:%d:%d: Command already completed\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); goto no_cmd; } + printf("%s: At time of recovery, card was %spaused\n", + ahc_name(ahc), was_paused ? "" : "not "); + ahc_dump_card_state(ahc); + disconnected = TRUE; if (flag == SCB_ABORT) { - if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + if (ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, + pending_scb->hscb->tag, ROLE_INITIATOR, CAM_REQ_ABORTED, SEARCH_COMPLETE) > 0) { printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", - ahc_name(ahc), cmd->channel, cmd->target, - cmd->lun); + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->device->lun); retval = SUCCESS; goto done; } - } else if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + } else if (ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, ROLE_INITIATOR, /*status*/0, SEARCH_COUNT) > 0) { disconnected = FALSE; } - if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) != 0) { + if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { struct scb *bus_scb; bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG)); @@ -2707,7 +4892,7 @@ disconnected = FALSE; else if (flag != SCB_ABORT && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid - && ahc_inb(ahc, SAVED_LUN) == pending_scb->hscb->lun) + && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb)) disconnected = FALSE; } @@ -2722,10 +4907,11 @@ last_phase = ahc_inb(ahc, LASTPHASE); saved_scbptr = ahc_inb(ahc, SCBPTR); active_scb_index = ahc_inb(ahc, SCB_TAG); + saved_scsiid = ahc_inb(ahc, SAVED_SCSIID); if (last_phase != P_BUSFREE && (pending_scb->hscb->tag == active_scb_index || (flag == SCB_DEVICE_RESET - && SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)) == cmd->target))) { + && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) { /* * We're active on the bus, so assert ATN @@ -2736,7 +4922,8 @@ ahc_outb(ahc, MSG_OUT, HOST_MSG); ahc_outb(ahc, SCSISIGO, last_phase|ATNO); printf("%s:%d:%d:%d: Device is active, asserting ATN\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); wait = TRUE; } else if (disconnected) { @@ -2766,8 +4953,9 @@ * same element in the SCB, SCB_NEXT, for * both the qinfifo and the disconnected list. */ - ahc_search_disc_list(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + ahc_search_disc_list(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, /*stop_on_first*/TRUE, /*remove*/TRUE, /*save_state*/FALSE); @@ -2790,19 +4978,20 @@ * so we are the next SCB for this target * to run. */ - ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR, - CAM_REQUEUE_REQ, SEARCH_COMPLETE); - ahc_print_path(ahc, pending_scb); - printf("Queuing a recovery SCB\n"); + ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ, + SEARCH_COMPLETE); ahc_qinfifo_requeue_tail(ahc, pending_scb); ahc_outb(ahc, SCBPTR, saved_scbptr); - printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_print_path(ahc, pending_scb); + printf("Device is disconnected, re-queuing SCB\n"); wait = TRUE; } else { printf("%s:%d:%d:%d: Unable to deliver message\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = FAILED; goto done; } @@ -2822,176 +5011,29 @@ struct timer_list timer; int ret; - ahc_unlock(ahc, &s); + ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE; + spin_unlock_irq(&ahc->platform_data->spin_lock); init_timer(&timer); - timer.data = (u_long)&ahc->platform_data->eh_sem; + timer.data = (u_long)ahc; timer.expires = jiffies + (5 * HZ); timer.function = ahc_linux_sem_timeout; add_timer(&timer); printf("Recovery code sleeping\n"); down(&ahc->platform_data->eh_sem); printf("Recovery code awake\n"); - ret = del_timer(&timer); + ret = del_timer_sync(&timer); if (ret == 0) { printf("Timer Expired\n"); retval = FAILED; } - ahc_lock(ahc, &s); + spin_lock_irq(&ahc->platform_data->spin_lock); } - acmd = TAILQ_FIRST(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->completeq); - ahc_unlock(ahc, &s); - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); - ahc_runq_tasklet((unsigned long)ahc); - spin_lock_irq(&io_request_lock); + ahc_schedule_runq(ahc); + ahc_linux_run_complete_queue(ahc); + ahc_midlayer_entrypoint_unlock(ahc, &s); return (retval); } -/* - * Abort the current SCSI command(s). - */ -int -ahc_linux_abort(Scsi_Cmnd *cmd) -{ - int error; - - error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT); - if (error != 0) - printf("aic7xxx_abort returns 0x%x\n", error); - return (error); -} - -/* - * Attempt to send a target reset message to the device that timed out. - */ -int -ahc_linux_dev_reset(Scsi_Cmnd *cmd) -{ - int error; - - error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); - if (error != 0) - printf("aic7xxx_dev_reset returns 0x%x\n", error); - return (error); -} - -/* - * Reset the SCSI bus. - */ -int -ahc_linux_bus_reset(Scsi_Cmnd *cmd) -{ - struct ahc_softc *ahc; - struct ahc_cmd *acmd; - u_long s; - int found; - - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); - - ahc = *(struct ahc_softc **)cmd->host->hostdata; - ahc_lock(ahc, &s); - found = ahc_reset_channel(ahc, cmd->channel + 'A', - /*initiate reset*/TRUE); - acmd = TAILQ_FIRST(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->completeq); - ahc_unlock(ahc, &s); - if (bootverbose) - printf("%s: SCSI bus reset delivered. " - "%d SCBs aborted.\n", ahc_name(ahc), found); - - if (acmd != NULL) - ahc_linux_run_complete_queue(ahc, acmd); - - spin_lock_irq(&io_request_lock); - return SUCCESS; -} - -/* - * Return the disk geometry for the given SCSI device. - */ -int -ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) -{ - int heads; - int sectors; - int cylinders; - int ret; - int extended; - struct ahc_softc *ahc; - struct buffer_head *bh; - - ahc = *((struct ahc_softc **)disk->device->host->hostdata); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); -#else - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); -#endif - - if (bh) { - ret = scsi_partsize(bh, disk->capacity, - &geom[2], &geom[0], &geom[1]); - brelse(bh); - if (ret != -1) - return (ret); - } - heads = 64; - sectors = 32; - cylinders = disk->capacity / (heads * sectors); - - if (aic7xxx_extended != 0) - extended = 1; - else if (disk->device->channel == 0) - extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0; - else - extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0; - if (extended && cylinders >= 1024) { - heads = 255; - sectors = 63; - cylinders = disk->capacity / (heads * sectors); - } - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; - return (0); -} - -/* - * Free the passed in Scsi_Host memory structures prior to unloading the - * module. - */ -int -ahc_linux_release(struct Scsi_Host * host) -{ - struct ahc_softc *ahc; - u_long l; - - ahc_list_lock(&l); - if (host != NULL) { - - /* - * We should be able to just perform - * the free directly, but check our - * list for extra sanity. - */ - ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); - if (ahc != NULL) { - u_long s; - - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, FALSE); - ahc_unlock(ahc, &s); - ahc_free(ahc); - } - } - ahc_list_unlock(&l); - return (0); -} - void ahc_platform_dump_card_state(struct ahc_softc *ahc) { @@ -3031,8 +5073,57 @@ } } -#if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -static Scsi_Host_Template driver_template = AIC7XXX; -Scsi_Host_Template *aic7xxx_driver_template = &driver_template; -#include "../scsi_module.c" +static int __init +ahc_linux_init(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + return (ahc_linux_detect(&aic7xxx_driver_template) ? 0 : -ENODEV); +#else + scsi_register_module(MODULE_SCSI_HA, &aic7xxx_driver_template); + if (aic7xxx_driver_template.present == 0) { + scsi_unregister_module(MODULE_SCSI_HA, + &aic7xxx_driver_template); + return (-ENODEV); + } + + return (0); +#endif +} + +static void __exit +ahc_linux_exit(void) +{ + struct ahc_softc *ahc; + u_long l; + + /* + * Shutdown DV threads before going into the SCSI mid-layer. + * This avoids situations where the mid-layer locks the entire + * kernel so that waiting for our DV threads to exit leads + * to deadlock. + */ + ahc_list_lock(&l); + TAILQ_FOREACH(ahc, &ahc_tailq, links) { + + ahc_linux_kill_dv_thread(ahc); + } + ahc_list_unlock(&l); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * In 2.4 we have to unregister from the PCI core _after_ + * unregistering from the scsi midlayer to avoid dangling + * references. + */ + scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template); +#endif +#ifdef CONFIG_PCI + ahc_linux_pci_exit(); +#endif +#ifdef CONFIG_EISA + ahc_linux_eisa_exit(); #endif +} + +module_init(ahc_linux_init); +module_exit(ahc_linux_exit); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_osm.h linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_osm.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_osm.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_osm.h 2003-08-25 04:44:42.000000000 -0700 @@ -18,9 +18,7 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 $ - * - * Copyright (c) 2000-2001 Adaptec Inc. + * Copyright (c) 2000-2003 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,7 +53,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#150 $ * */ #ifndef _AIC7XXX_LINUX_H_ @@ -67,12 +65,11 @@ #include #include #include +#include #include -#ifndef AHC_MODVERSION_FILE -#define __NO_VERSION__ -#endif #include #include +#include #ifndef KERNEL_VERSION #define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) @@ -87,8 +84,9 @@ #endif /* Core SCSI definitions */ -#include "../scsi.h" -#include "../hosts.h" +#define AIC_LIB_PREFIX ahc +#include "scsi.h" +#include "hosts.h" /* Name space conflict with BSD queue macros */ #ifdef LIST_HEAD @@ -98,6 +96,21 @@ #include "cam.h" #include "queue.h" #include "scsi_message.h" +#include "aiclib.h" + +/*********************************** Debugging ********************************/ +#ifdef CONFIG_AIC7XXX_DEBUG_ENABLE +#ifdef CONFIG_AIC7XXX_DEBUG_MASK +#define AHC_DEBUG 1 +#define AHC_DEBUG_OPTS CONFIG_AIC7XXX_DEBUG_MASK +#else +/* + * Compile in debugging code, but do not enable any printfs. + */ +#define AHC_DEBUG 1 +#endif +/* No debugging code. */ +#endif /************************* Forward Declarations *******************************/ struct ahc_softc; @@ -137,9 +150,10 @@ #endif /* BYTE_ORDER */ /************************* Configuration Data *********************************/ -extern int aic7xxx_no_probe; +extern u_int aic7xxx_no_probe; +extern u_int aic7xxx_allow_memio; extern int aic7xxx_detect_complete; -extern Scsi_Host_Template* aic7xxx_driver_template; +extern Scsi_Host_Template aic7xxx_driver_template; /***************************** Bus Space/DMA **********************************/ @@ -240,176 +254,58 @@ */ #define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op) -/************************** SCSI Constants/Structures *************************/ -#define SCSI_REV_2 2 -#define SCSI_STATUS_OK 0x00 -#define SCSI_STATUS_CHECK_COND 0x02 -#define SCSI_STATUS_COND_MET 0x04 -#define SCSI_STATUS_BUSY 0x08 -#define SCSI_STATUS_INTERMED 0x10 -#define SCSI_STATUS_INTERMED_COND_MET 0x14 -#define SCSI_STATUS_RESERV_CONFLICT 0x18 -#define SCSI_STATUS_CMD_TERMINATED 0x22 -#define SCSI_STATUS_QUEUE_FULL 0x28 - -/* - * 6 byte request sense CDB format. - */ -struct scsi_sense -{ - uint8_t opcode; - uint8_t byte2; - uint8_t unused[2]; - uint8_t length; - uint8_t control; -}; +/************************** Timer DataStructures ******************************/ +typedef struct timer_list ahc_timer_t; -struct scsi_sense_data -{ - uint8_t error_code; - uint8_t segment; - uint8_t flags; - uint8_t info[4]; - uint8_t extra_len; - uint8_t cmd_spec_info[4]; - uint8_t add_sense_code; - uint8_t add_sense_code_qual; - uint8_t fru; - uint8_t sense_key_spec[3]; - uint8_t extra_bytes[14]; -}; +/********************************** Includes **********************************/ +#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT +#define AIC_DEBUG_REGISTERS 1 +#else +#define AIC_DEBUG_REGISTERS 0 +#endif +#include "aic7xxx.h" -struct scsi_inquiry -{ - u_int8_t opcode; - u_int8_t byte2; -#define SI_EVPD 0x01 - u_int8_t page_code; - u_int8_t reserved; - u_int8_t length; - u_int8_t control; -}; +/***************************** Timer Facilities *******************************/ +#define ahc_timer_init init_timer +#define ahc_timer_stop del_timer_sync +typedef void ahc_linux_callback_t (u_long); +static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec, + ahc_callback_t *func, void *arg); +static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec); -struct scsi_inquiry_data +static __inline void +ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg) { - uint8_t device; -#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f) -#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5) -#define SID_QUAL_LU_CONNECTED 0x00 /* - * The specified peripheral device - * type is currently connected to - * logical unit. If the target cannot - * determine whether or not a physical - * device is currently connected, it - * shall also use this peripheral - * qualifier when returning the INQUIRY - * data. This peripheral qualifier - * does not mean that the device is - * ready for access by the initiator. - */ -#define SID_QUAL_LU_OFFLINE 0x01 /* - * The target is capable of supporting - * the specified peripheral device type - * on this logical unit; however, the - * physical device is not currently - * connected to this logical unit. - */ -#define SID_QUAL_RSVD 0x02 -#define SID_QUAL_BAD_LU 0x03 /* - * The target is not capable of - * supporting a physical device on - * this logical unit. For this - * peripheral qualifier the peripheral - * device type shall be set to 1Fh to - * provide compatibility with previous - * versions of SCSI. All other - * peripheral device type values are - * reserved for this peripheral - * qualifier. - */ -#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) - uint8_t dev_qual2; -#define SID_QUAL2 0x7F -#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0) - uint8_t version; -#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07) -#define SCSI_REV_0 0 -#define SCSI_REV_CCS 1 -#define SCSI_REV_2 2 -#define SCSI_REV_SPC 3 -#define SCSI_REV_SPC2 4 - -#define SID_ECMA 0x38 -#define SID_ISO 0xC0 - uint8_t response_format; -#define SID_AENC 0x80 -#define SID_TrmIOP 0x40 - uint8_t additional_length; - uint8_t reserved[2]; - uint8_t flags; -#define SID_SftRe 0x01 -#define SID_CmdQue 0x02 -#define SID_Linked 0x08 -#define SID_Sync 0x10 -#define SID_WBus16 0x20 -#define SID_WBus32 0x40 -#define SID_RelAdr 0x80 -#define SID_VENDOR_SIZE 8 - char vendor[SID_VENDOR_SIZE]; -#define SID_PRODUCT_SIZE 16 - char product[SID_PRODUCT_SIZE]; -#define SID_REVISION_SIZE 4 - char revision[SID_REVISION_SIZE]; - /* - * The following fields were taken from SCSI Primary Commands - 2 - * (SPC-2) Revision 14, Dated 11 November 1999 - */ -#define SID_VENDOR_SPECIFIC_0_SIZE 20 - u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE]; - /* - * An extension of SCSI Parallel Specific Values - */ -#define SID_SPI_IUS 0x01 -#define SID_SPI_QAS 0x02 -#define SID_SPI_CLOCK_ST 0x00 -#define SID_SPI_CLOCK_DT 0x04 -#define SID_SPI_CLOCK_DT_ST 0x0C -#define SID_SPI_MASK 0x0F - uint8_t spi3data; - uint8_t reserved2; - /* - * Version Descriptors, stored 2 byte values. - */ - uint8_t version1[2]; - uint8_t version2[2]; - uint8_t version3[2]; - uint8_t version4[2]; - uint8_t version5[2]; - uint8_t version6[2]; - uint8_t version7[2]; - uint8_t version8[2]; - - uint8_t reserved3[22]; + struct ahc_softc *ahc; -#define SID_VENDOR_SPECIFIC_1_SIZE 160 - uint8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE]; -}; - -/********************************** Includes **********************************/ -/* Host template and function declarations referenced by the template. */ -#include "aic7xxx_host.h" + ahc = (struct ahc_softc *)arg; + del_timer(timer); + timer->data = (u_long)arg; + timer->expires = jiffies + (usec * HZ)/1000000; + timer->function = (ahc_linux_callback_t*)func; + add_timer(timer); +} -/* Core driver definitions */ -#include "aic7xxx.h" +static __inline void +ahc_scb_timer_reset(struct scb *scb, u_int usec) +{ + mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); +} -/* SMP support */ +/***************************** SMP support ************************************/ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17) #include #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) #include #endif -#define AIC7XXX_DRIVER_VERSION "6.2.8" +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) +#define AHC_SCSI_HAS_HOST_LOCK 1 +#else +#define AHC_SCSI_HAS_HOST_LOCK 0 +#endif + +#define AIC7XXX_DRIVER_VERSION "6.2.36" /**************************** Front End Queues ********************************/ /* @@ -444,7 +340,7 @@ /* * A per probed device structure used to deal with some error recovery * scenarios that the Linux mid-layer code just doesn't know how to - * handle. The structure allocated for a device only becomes persistant + * handle. The structure allocated for a device only becomes persistent * after a successfully completed inquiry command to the target when * that inquiry data indicates a lun is present. */ @@ -456,8 +352,9 @@ AHC_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ - AHC_DEV_PERIODIC_OTAG = 0x40 /* Send OTAG to prevent starvation */ -} ahc_dev_flags; + AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ + AHC_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ +} ahc_linux_dev_flags; struct ahc_linux_target; struct ahc_linux_device { @@ -500,7 +397,7 @@ u_int tag_success_count; #define AHC_TAG_SUCCESS_INTERVAL 50 - ahc_dev_flags flags; + ahc_linux_dev_flags flags; /* * Per device timer. @@ -540,16 +437,54 @@ #define AHC_OTAG_THRESH 500 int lun; + Scsi_Device *scsi_device; struct ahc_linux_target *target; }; +typedef enum { + AHC_DV_REQUIRED = 0x01, + AHC_INQ_VALID = 0x02, + AHC_BASIC_DV = 0x04, + AHC_ENHANCED_DV = 0x08 +} ahc_linux_targ_flags; + +/* DV States */ +typedef enum { + AHC_DV_STATE_EXIT = 0, + AHC_DV_STATE_INQ_SHORT_ASYNC, + AHC_DV_STATE_INQ_ASYNC, + AHC_DV_STATE_INQ_ASYNC_VERIFY, + AHC_DV_STATE_TUR, + AHC_DV_STATE_REBD, + AHC_DV_STATE_INQ_VERIFY, + AHC_DV_STATE_WEB, + AHC_DV_STATE_REB, + AHC_DV_STATE_SU, + AHC_DV_STATE_BUSY +} ahc_dv_state; + struct ahc_linux_target { - struct ahc_linux_device *devices[AHC_NUM_LUNS]; - int channel; - int target; - int refcount; - struct ahc_transinfo last_tinfo; - struct ahc_softc *ahc; + struct ahc_linux_device *devices[AHC_NUM_LUNS]; + int channel; + int target; + int refcount; + struct ahc_transinfo last_tinfo; + struct ahc_softc *ahc; + ahc_linux_targ_flags flags; + struct scsi_inquiry_data *inq_data; + /* + * The next "fallback" period to use for narrow/wide transfers. + */ + uint8_t dv_next_narrow_period; + uint8_t dv_next_wide_period; + uint8_t dv_max_width; + uint8_t dv_max_ppr_options; + uint8_t dv_last_ppr_options; + u_int dv_echo_size; + ahc_dv_state dv_state; + u_int dv_state_retry; + char *dv_buffer; + char *dv_buffer1; }; /********************* Definitions Required by the Core ***********************/ @@ -559,11 +494,26 @@ * manner and are allocated below 4GB, the number of S/G segments is * unrestricted. */ -#define AHC_NSEG 128 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* + * We dynamically adjust the number of segments in pre-2.5 kernels to + * avoid fragmentation issues in the SCSI mid-layer's private memory + * allocator. See aic7xxx_osm.c ahc_linux_size_nseg() for details. + */ +extern u_int ahc_linux_nseg; +#define AHC_NSEG ahc_linux_nseg +#define AHC_LINUX_MIN_NSEG 64 +#else +#define AHC_NSEG 128 +#endif /* * Per-SCB OSM storage. */ +typedef enum { + AHC_UP_EH_SEMAPHORE = 0x1 +} ahc_linux_scb_flags; + struct scb_platform_data { struct ahc_linux_device *dev; bus_addr_t buf_busaddr; @@ -571,6 +521,8 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) uint32_t resid; /* Transfer residual */ #endif + uint32_t sense_resid; /* Auto-Sense residual */ + ahc_linux_scb_flags flags; }; /* @@ -579,7 +531,16 @@ * alignment restrictions of the various platforms supported by * this driver. */ +typedef enum { + AHC_DV_WAIT_SIMQ_EMPTY = 0x01, + AHC_DV_WAIT_SIMQ_RELEASE = 0x02, + AHC_DV_ACTIVE = 0x04, + AHC_DV_SHUTDOWN = 0x08, + AHC_RUN_CMPLT_Q_TIMER = 0x10 +} ahc_linux_softc_flags; + TAILQ_HEAD(ahc_completeq, ahc_cmd); + struct ahc_platform_data { /* * Fields accessed from interrupt context. @@ -588,21 +549,27 @@ TAILQ_HEAD(, ahc_linux_device) device_runq; struct ahc_completeq completeq; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) spinlock_t spin_lock; -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) struct tasklet_struct runq_tasklet; #endif u_int qfrozen; + pid_t dv_pid; + struct timer_list completeq_timer; struct timer_list reset_timer; struct semaphore eh_sem; + struct semaphore dv_sem; + struct semaphore dv_cmd_sem; /* XXX This needs to be in + * the target struct + */ + struct scsi_device *dv_scsi_dev; struct Scsi_Host *host; /* pointer to scsi host */ #define AHC_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ bus_addr_t hw_dma_mask; + ahc_linux_softc_flags flags; }; /************************** OS Utility Wrappers *******************************/ @@ -635,7 +602,6 @@ static __inline uint8_t ahc_inb(struct ahc_softc * ahc, long port); static __inline void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val); -static __inline void ahc_outb_reset(struct ahc_softc * ahc, long port, uint8_t val); static __inline void ahc_outsb(struct ahc_softc * ahc, long port, uint8_t *, int count); static __inline void ahc_insb(struct ahc_softc * ahc, long port, @@ -665,22 +631,6 @@ #ifdef MMAPIO if (ahc->tag == BUS_SPACE_MEMIO) { writeb(val, ahc->bsh.maddr + port); - readb(ahc->bsh.maddr + HCNTRL); /* flush PCI posting */ - } else { - outb(val, ahc->bsh.ioport + port); - } -#else - outb(val, ahc->bsh.ioport + port); -#endif - mb(); -} - -static __inline void -ahc_outb_reset(struct ahc_softc * ahc, long port, uint8_t val) -{ -#ifdef MMAPIO - if (ahc->tag == BUS_SPACE_MEMIO) { - writeb(val, ahc->bsh.maddr + port); } else { outb(val, ahc->bsh.ioport + port); } @@ -741,6 +691,12 @@ static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags); static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags); +/* Lock acquisition and release of the above lock in midlayer entry points. */ +static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *, + unsigned long *flags); +static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *, + unsigned long *flags); + /* Lock held during command compeletion to the upper layer */ static __inline void ahc_done_lockinit(struct ahc_softc *); static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags); @@ -752,7 +708,6 @@ static __inline void ahc_list_lock(unsigned long *flags); static __inline void ahc_list_unlock(unsigned long *flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) static __inline void ahc_lockinit(struct ahc_softc *ahc) { @@ -762,7 +717,6 @@ static __inline void ahc_lock(struct ahc_softc *ahc, unsigned long *flags) { - *flags = 0; spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags); } @@ -773,102 +727,73 @@ } static __inline void -ahc_done_lockinit(struct ahc_softc *ahc) -{ - /* We don't own the iorequest lock, so we don't initialize it. */ -} - -static __inline void -ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags) -{ - *flags = 0; - spin_lock_irqsave(&io_request_lock, *flags); -} - -static __inline void -ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags) -{ - spin_unlock_irqrestore(&io_request_lock, *flags); -} - -static __inline void -ahc_list_lockinit() -{ - spin_lock_init(&ahc_list_spinlock); -} - -static __inline void -ahc_list_lock(unsigned long *flags) -{ - *flags = 0; - spin_lock_irqsave(&ahc_list_spinlock, *flags); -} - -static __inline void -ahc_list_unlock(unsigned long *flags) +ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags) { - spin_unlock_irqrestore(&ahc_list_spinlock, *flags); -} - -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ - -ahc_lockinit(struct ahc_softc *ahc) -{ -} - -static __inline void -ahc_lock(struct ahc_softc *ahc, unsigned long *flags) -{ - *flags = 0; - save_flags(*flags); - cli(); + /* + * In 2.5.X and some 2.4.X versions, the midlayer takes our + * lock just before calling us, so we avoid locking again. + * For other kernel versions, the io_request_lock is taken + * just before our entry point is called. In this case, we + * trade the io_request_lock for our per-softc lock. + */ +#if AHC_SCSI_HAS_HOST_LOCK == 0 + spin_unlock(&io_request_lock); + spin_lock(&ahc->platform_data->spin_lock); +#endif } static __inline void -ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) +ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags) { - restore_flags(*flags); +#if AHC_SCSI_HAS_HOST_LOCK == 0 + spin_unlock(&ahc->platform_data->spin_lock); + spin_lock(&io_request_lock); +#endif } static __inline void ahc_done_lockinit(struct ahc_softc *ahc) { + /* + * In 2.5.X, our own lock is held during completions. + * In previous versions, the io_request_lock is used. + * In either case, we can't initialize this lock again. + */ } static __inline void ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags) { - /* - * The done lock is always held while - * the ahc lock is held so blocking - * interrupts again would have no effect. - */ +#if AHC_SCSI_HAS_HOST_LOCK == 0 + spin_lock_irqsave(&io_request_lock, *flags); +#endif } static __inline void ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags) { +#if AHC_SCSI_HAS_HOST_LOCK == 0 + spin_unlock_irqrestore(&io_request_lock, *flags); +#endif } static __inline void -ahc_list_lockinit() +ahc_list_lockinit(void) { + spin_lock_init(&ahc_list_spinlock); } static __inline void ahc_list_lock(unsigned long *flags) { - *flags = 0; - save_flags(*flags); - cli(); + spin_lock_irqsave(&ahc_list_spinlock, *flags); } static __inline void ahc_list_unlock(unsigned long *flags) { - restore_flags(*flags); + spin_unlock_irqrestore(&ahc_list_spinlock, *flags); } -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ /******************************* PCI Definitions ******************************/ /* @@ -889,6 +814,7 @@ #define PCIM_CMD_BUSMASTEREN 0x0004 #define PCIM_CMD_MWRICEN 0x0010 #define PCIM_CMD_PERRESPEN 0x0040 +#define PCIM_CMD_SERRESPEN 0x0100 #define PCIR_STATUS 0x06 #define PCIR_REVID 0x08 #define PCIR_PROGIF 0x09 @@ -918,26 +844,28 @@ AHC_POWER_STATE_D3 } ahc_power_state; -void ahc_power_state_change(struct ahc_softc *ahc, - ahc_power_state new_state); /**************************** VL/EISA Routines ********************************/ -int aic7770_linux_probe(Scsi_Host_Template *); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \ + && (defined(__i386__) || defined(__alpha__)) \ + && (!defined(CONFIG_EISA))) +#define CONFIG_EISA +#endif + +#ifdef CONFIG_EISA +extern uint32_t aic7xxx_probe_eisa_vl; +void ahc_linux_eisa_init(void); +void ahc_linux_eisa_exit(void); int aic7770_map_registers(struct ahc_softc *ahc, u_int port); int aic7770_map_int(struct ahc_softc *ahc, u_int irq); - -/******************************* PCI Routines *********************************/ -/* - * We need to use the bios32.h routines if we are kernel version 2.1.92 or less. - */ -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92) -#if defined(__sparc_v9__) || defined(__powerpc__) -#error "PPC and Sparc platforms are only support under 2.1.92 and above" -#endif -#include #endif -int ahc_linux_pci_probe(Scsi_Host_Template *); +/******************************* PCI Routines *********************************/ +#ifdef CONFIG_PCI +void ahc_power_state_change(struct ahc_softc *ahc, + ahc_power_state new_state); +int ahc_linux_pci_init(void); +void ahc_linux_pci_exit(void); int ahc_pci_map_registers(struct ahc_softc *ahc); int ahc_pci_map_int(struct ahc_softc *ahc); @@ -1017,6 +945,7 @@ { return (pci->bus->number); } +#endif static __inline void ahc_flush_device_writes(struct ahc_softc *); static __inline void @@ -1036,38 +965,104 @@ #define pci_unmap_single(pdev, buffer, buflen, direction) #endif -/*********************** Transaction Access Wrappers **************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) +#define ahc_pci_set_dma_mask pci_set_dma_mask +#else +/* + * Always "return" 0 for success. + */ +#define ahc_pci_set_dma_mask(dev_softc, mask) \ + (((dev_softc)->dma_mask = mask) && 0) +#endif +/**************************** Proc FS Support *********************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +int ahc_linux_proc_info(char *, char **, off_t, int, int, int); +#else +int ahc_linux_proc_info(struct Scsi_Host *, char *, char **, + off_t, int, int); +#endif + +/*************************** Domain Validation ********************************/ +#define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete) +#define AHC_DV_SIMQ_FROZEN(ahc) \ + ((((ahc)->platform_data->flags & AHC_DV_ACTIVE) != 0) \ + && (ahc)->platform_data->qfrozen == 1) + +/*********************** Transaction Access Wrappers *************************/ +static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); static __inline void ahc_set_transaction_status(struct scb *, uint32_t); +static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); +static __inline void ahc_set_scsi_status(struct scb *, uint32_t); +static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahc_get_transaction_status(struct scb *); +static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahc_get_scsi_status(struct scb *); +static __inline void ahc_set_transaction_tag(struct scb *, int, u_int); +static __inline u_long ahc_get_transfer_length(struct scb *); +static __inline int ahc_get_transfer_dir(struct scb *); +static __inline void ahc_set_residual(struct scb *, u_long); +static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid); +static __inline u_long ahc_get_residual(struct scb *); +static __inline u_long ahc_get_sense_residual(struct scb *); +static __inline int ahc_perform_autosense(struct scb *); +static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *, + struct scb *); +static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *, + struct ahc_devinfo *); +static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, + struct scb *scb); +static __inline void ahc_freeze_scb(struct scb *scb); + +static __inline +void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~(CAM_STATUS_MASK << 16); + cmd->result |= status << 16; +} + static __inline void ahc_set_transaction_status(struct scb *scb, uint32_t status) { - scb->io_ctx->result &= ~(CAM_STATUS_MASK << 16); - scb->io_ctx->result |= status << 16; + ahc_cmd_set_transaction_status(scb->io_ctx,status); +} + +static __inline +void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) +{ + cmd->result &= ~0xFFFF; + cmd->result |= status; } -static __inline void ahc_set_scsi_status(struct scb *, uint32_t); static __inline void ahc_set_scsi_status(struct scb *scb, uint32_t status) { - scb->io_ctx->result &= ~0xFFFF; - scb->io_ctx->result |= status; + ahc_cmd_set_scsi_status(scb->io_ctx, status); +} + +static __inline +uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd) +{ + return ((cmd->result >> 16) & CAM_STATUS_MASK); } -static __inline uint32_t ahc_get_transaction_status(struct scb *); static __inline uint32_t ahc_get_transaction_status(struct scb *scb) { - return ((scb->io_ctx->result >> 16) & CAM_STATUS_MASK); + return (ahc_cmd_get_transaction_status(scb->io_ctx)); +} + +static __inline +uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd) +{ + return (cmd->result & 0xFFFF); } -static __inline uint32_t ahc_get_scsi_status(struct scb *); static __inline uint32_t ahc_get_scsi_status(struct scb *scb) { - return (scb->io_ctx->result & 0xFFFF); + return (ahc_cmd_get_scsi_status(scb->io_ctx)); } -static __inline void ahc_set_transaction_tag(struct scb *, int, u_int); static __inline void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type) { @@ -1077,14 +1072,12 @@ */ } -static __inline u_long ahc_get_transfer_length(struct scb *); static __inline u_long ahc_get_transfer_length(struct scb *scb) { return (scb->platform_data->xfer_len); } -static __inline int ahc_get_transfer_dir(struct scb *); static __inline int ahc_get_transfer_dir(struct scb *scb) { @@ -1109,7 +1102,6 @@ #endif } -static __inline void ahc_set_residual(struct scb *, u_long); static __inline void ahc_set_residual(struct scb *scb, u_long resid) { @@ -1120,14 +1112,12 @@ #endif } -static __inline void ahc_set_sense_residual(struct scb *, u_long); static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid) { - /* This can't be reported in Linux */ + scb->platform_data->sense_resid = resid; } -static __inline u_long ahc_get_residual(struct scb *); static __inline u_long ahc_get_residual(struct scb *scb) { @@ -1138,7 +1128,12 @@ #endif } -static __inline int ahc_perform_autosense(struct scb *); +static __inline +u_long ahc_get_sense_residual(struct scb *scb) +{ + return (scb->platform_data->sense_resid); +} + static __inline int ahc_perform_autosense(struct scb *scb) { @@ -1156,8 +1151,6 @@ return (sizeof(struct scsi_sense_data)); } -static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *, - struct ahc_devinfo *); static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) @@ -1165,8 +1158,6 @@ /* Nothing to do here for linux */ } -static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, - struct scb *scb); static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb) { @@ -1176,11 +1167,14 @@ int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg); void ahc_platform_free(struct ahc_softc *ahc); void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb); -static __inline void ahc_freeze_scb(struct scb *scb); + static __inline void ahc_freeze_scb(struct scb *scb) { - /* Noting to do here for linux */ + if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) { + scb->io_ctx->result |= CAM_DEV_QFRZN << 16; + scb->platform_data->dev->qfrozen++; + } } void ahc_platform_set_tags(struct ahc_softc *ahc, @@ -1188,7 +1182,8 @@ int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, int lun, u_int tag, role_t role, uint32_t status); -void ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs); +irqreturn_t + ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs); void ahc_platform_flushwork(struct ahc_softc *ahc); int ahc_softc_comp(struct ahc_softc *, struct ahc_softc *); void ahc_done(struct ahc_softc*, struct scb*); @@ -1203,5 +1198,5 @@ #define AHC_PCI_CONFIG 0 #endif #define bootverbose aic7xxx_verbose -extern int aic7xxx_verbose; +extern u_int aic7xxx_verbose; #endif /* _AIC7XXX_LINUX_H_ */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2003-08-25 04:44:42.000000000 -0700 @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#32 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#46 $ */ #include "aic7xxx_osm.h" @@ -93,7 +93,7 @@ * list for extra sanity. */ ahc_list_lock(&l); - ahc = ahc_find_softc((struct ahc_softc *)pdev->driver_data); + ahc = ahc_find_softc((struct ahc_softc *)pci_get_drvdata(pdev)); if (ahc != NULL) { u_long s; @@ -110,6 +110,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { char buf[80]; + bus_addr_t mask_39bit; struct ahc_softc *ahc; ahc_dev_softc_t pci; struct ahc_pci_identity *entry; @@ -160,19 +161,15 @@ } pci_set_master(pdev); + mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL; if (sizeof(bus_addr_t) > 4 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) && ahc_linux_get_memsize() > 0x80000000 - && pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) { -#else - && ahc_linux_get_memsize() > 0x80000000) { - - ahc->dev_softc->dma_mask = - (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0); -#endif + && ahc_pci_set_dma_mask(pdev, mask_39bit) == 0) { ahc->flags |= AHC_39BIT_ADDRESSING; - ahc->platform_data->hw_dma_mask = - (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0); + ahc->platform_data->hw_dma_mask = mask_39bit; + } else { + ahc_pci_set_dma_mask(pdev, 0xFFFFFFFF); + ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; } #endif ahc->dev_softc = pci; @@ -183,14 +180,21 @@ } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_set_drvdata(pdev, ahc); - if (aic7xxx_detect_complete) - ahc_linux_register_host(ahc, aic7xxx_driver_template); + if (aic7xxx_detect_complete) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahc_linux_register_host(ahc, &aic7xxx_driver_template); +#else + printf("aic7xxx: ignoring PCI device found after " + "initialization\n"); + return (-ENODEV); +#endif + } #endif return (0); } int -ahc_linux_pci_probe(Scsi_Host_Template *template) +ahc_linux_pci_init(void) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) return (pci_module_init(&aic7xxx_pci_driver)); @@ -219,9 +223,18 @@ #endif } +void +ahc_linux_pci_exit(void) +{ + pci_unregister_driver(&aic7xxx_pci_driver); +} + static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base) { + if (aic7xxx_allow_memio == 0) + return (ENOMEM); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) *base = pci_resource_start(ahc->dev_softc, 0); #else @@ -233,8 +246,7 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) if (check_region(*base, 256) != 0) return (ENOMEM); - else - request_region(*base, 256, "aic7xxx"); + request_region(*base, 256, "aic7xxx"); #else if (request_region(*base, 256, "aic7xxx") == 0) return (ENOMEM); @@ -314,10 +326,10 @@ * Do a quick test to see if memory mapped * I/O is functioning correctly. */ - if (ahc_inb(ahc, HCNTRL) == 0xFF) { + if (ahc_pci_test_register_access(ahc) != 0) { printf("aic7xxx: PCI Device %d:%d:%d " - "failed memory mapped test\n", + "failed memory mapped test. Using PIO.\n", ahc_get_pci_bus(ahc->dev_softc), ahc_get_pci_slot(ahc->dev_softc), ahc_get_pci_function(ahc->dev_softc)); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_pci.c linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_pci.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_pci.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_pci.c 2003-08-25 04:44:42.000000000 -0700 @@ -39,9 +39,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#46 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.2.2.14 2002/04/29 19:36:31 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -76,7 +76,7 @@ #define ID_9005_SISL_MASK 0x000FFFFF00000000ull #define ID_9005_SISL_ID 0x0005900500000000ull #define ID_AIC7850 0x5078900400000000ull -#define ID_AHA_2902_04_10_15_20_30C 0x5078900478509004ull +#define ID_AHA_2902_04_10_15_20C_30C 0x5078900478509004ull #define ID_AIC7855 0x5578900400000000ull #define ID_AIC7859 0x3860900400000000ull #define ID_AHA_2930CU 0x3860900438699004ull @@ -245,9 +245,9 @@ { /* aic7850 based controllers */ { - ID_AHA_2902_04_10_15_20_30C, + ID_AHA_2902_04_10_15_20C_30C, ID_ALL_MASK, - "Adaptec 2902/04/10/15/20/30C SCSI adapter", + "Adaptec 2902/04/10/15/20C/30C SCSI adapter", ahc_aic785X_setup }, /* aic7860 based controllers */ @@ -641,6 +641,7 @@ #define AHC_494X_SLOT_CHANNEL_D 7 #define DEVCONFIG 0x40 +#define PCIERRGENDIS 0x80000000ul #define SCBSIZE32 0x00010000ul /* aic789X only */ #define REXTVALID 0x00001000ul /* ultra cards only */ #define MPORTMODE 0x00000400ul /* aic7870+ only */ @@ -660,6 +661,14 @@ #define CACHESIZE 0x0000003ful /* only 5 bits */ #define LATTIME 0x0000ff00ul +/* PCI STATUS definitions */ +#define DPE 0x80 +#define SSE 0x40 +#define RMA 0x20 +#define RTA 0x10 +#define STA 0x08 +#define DPR 0x01 + static int ahc_9005_subdevinfo_valid(uint16_t vendor, uint16_t device, uint16_t subvendor, uint16_t subdevice); static int ahc_ext_scbram_present(struct ahc_softc *ahc); @@ -687,8 +696,12 @@ static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, int *externalcable_present, int *eeprom_present); -static void write_brdctl(struct ahc_softc *ahc, uint8_t value); +static void write_brdctl(struct ahc_softc *ahc, uint8_t value); static uint8_t read_brdctl(struct ahc_softc *ahc); +static void ahc_pci_intr(struct ahc_softc *ahc); +static int ahc_pci_chip_init(struct ahc_softc *ahc); +static int ahc_pci_suspend(struct ahc_softc *ahc); +static int ahc_pci_resume(struct ahc_softc *ahc); static int ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, @@ -739,10 +752,7 @@ device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2); subvendor = ahc_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2); subdevice = ahc_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2); - full_id = ahc_compose_id(device, - vendor, - subdevice, - subvendor); + full_id = ahc_compose_id(device, vendor, subdevice, subvendor); /* * If the second function is not hooked up, ignore it. @@ -771,18 +781,17 @@ int ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) { - struct scb_data *shared_scb_data; - u_long l; - u_long s; - u_int command; - u_int our_id = 0; - u_int sxfrctl1; - u_int scsiseq; - u_int dscommand0; - int error; - uint8_t sblkctl; + u_long l; + u_int command; + u_int our_id; + u_int sxfrctl1; + u_int scsiseq; + u_int dscommand0; + uint32_t devconfig; + int error; + uint8_t sblkctl; - shared_scb_data = NULL; + our_id = 0; error = entry->setup(ahc); if (error != 0) return (error); @@ -803,6 +812,8 @@ */ ahc_intr_enable(ahc, FALSE); + devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); + /* * If we need to support high memory, enable dual * address cycles. This bit must be set to enable @@ -810,22 +821,23 @@ * 64bit bus (PCI64BIT set in devconfig). */ if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { - uint32_t devconfig; if (bootverbose) printf("%s: Enabling 39Bit Addressing\n", ahc_name(ahc)); - devconfig = ahc_pci_read_config(ahc->dev_softc, - DEVCONFIG, /*bytes*/4); devconfig |= DACEN; - ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, - devconfig, /*bytes*/4); } + /* Ensure that pci error generation, a test feature, is disabled. */ + devconfig |= PCIERRGENDIS; + + ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); + /* Ensure busmastering is enabled */ - command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); + command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); command |= PCIM_CMD_BUSMASTEREN; - ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1); + + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2); /* On all PCI adapters, we allow SCB paging */ ahc->flags |= AHC_PAGESCBS; @@ -834,7 +846,21 @@ if (error != 0) return (error); + /* + * Disable PCI parity error checking. Users typically + * do this to work around broken PCI chipsets that get + * the parity timing wrong and thus generate lots of spurious + * errors. The chip only allows us to disable *all* parity + * error reporting when doing this, so CIO bus, scb ram, and + * scratch ram parity errors will be ignored too. + */ + if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) + ahc->seqctl |= FAILDIS; + ahc->bus_intr = ahc_pci_intr; + ahc->bus_chip_init = ahc_pci_chip_init; + ahc->bus_suspend = ahc_pci_suspend; + ahc->bus_resume = ahc_pci_resume; /* Remeber how the card was setup in case there is no SEEPROM */ if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { @@ -851,7 +877,7 @@ scsiseq = 0; } - error = ahc_reset(ahc); + error = ahc_reset(ahc, /*reinit*/FALSE); if (error != 0) return (ENXIO); @@ -941,7 +967,8 @@ * a SEEPROM. */ /* See if someone else set us up already */ - if (scsiseq != 0) { + if ((ahc->flags & AHC_NO_BIOS_INIT) == 0 + && scsiseq != 0) { printf("%s: Using left over BIOS settings\n", ahc_name(ahc)); ahc->flags &= ~AHC_USEDEFAULTS; @@ -973,6 +1000,35 @@ if ((sxfrctl1 & STPWEN) != 0) ahc->flags |= AHC_TERM_ENB_A; + /* + * Save chip register configuration data for chip resets + * that occur during runtime and resume events. + */ + ahc->bus_softc.pci_softc.devconfig = + ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); + ahc->bus_softc.pci_softc.command = + ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); + ahc->bus_softc.pci_softc.csize_lattime = + ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1); + ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0); + ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS); + if ((ahc->features & AHC_DT) != 0) { + u_int sfunct; + + sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; + ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); + ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE); + ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT); + ahc_outb(ahc, SFUNCT, sfunct); + ahc->bus_softc.pci_softc.crccontrol1 = + ahc_inb(ahc, CRCCONTROL1); + } + if ((ahc->features & AHC_MULTI_FUNC) != 0) + ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR); + + if ((ahc->features & AHC_ULTRA2) != 0) + ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH); + /* Core initialization */ error = ahc_init(ahc); if (error != 0) @@ -990,11 +1046,6 @@ * Link this softc in with all other ahc instances. */ ahc_softc_insert(ahc); - - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, TRUE); - ahc_unlock(ahc, &s); - ahc_list_unlock(&l); return (0); } @@ -1195,6 +1246,83 @@ } /* + * Perform some simple tests that should catch situations where + * our registers are invalidly mapped. + */ +int +ahc_pci_test_register_access(struct ahc_softc *ahc) +{ + int error; + u_int status1; + uint32_t cmd; + uint8_t hcntrl; + + error = EIO; + + /* + * Enable PCI error interrupt status, but suppress NMIs + * generated by SERR raised due to target aborts. + */ + cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, + cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); + + /* + * First a simple test to see if any + * registers can be read. Reading + * HCNTRL has no side effects and has + * at least one bit that is guaranteed to + * be zero so it is a good register to + * use for this test. + */ + hcntrl = ahc_inb(ahc, HCNTRL); + if (hcntrl == 0xFF) + goto fail; + + /* + * Next create a situation where write combining + * or read prefetching could be initiated by the + * CPU or host bridge. Our device does not support + * either, so look for data corruption and/or flagged + * PCI errors. + */ + ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); + while (ahc_is_paused(ahc) == 0) + ; + + /* Clear any PCI errors that occurred before our driver attached. */ + status1 = ahc_pci_read_config(ahc->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, + status1, /*bytes*/1); + ahc_outb(ahc, CLRINT, CLRPARERR); + + ahc_outb(ahc, SEQCTL, PERRORDIS); + ahc_outb(ahc, SCBPTR, 0); + ahc_outl(ahc, SCB_BASE, 0x5aa555aa); + if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa) + goto fail; + + status1 = ahc_pci_read_config(ahc->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + if ((status1 & STA) != 0) + goto fail; + + error = 0; + +fail: + /* Silently clear any latched errors. */ + status1 = ahc_pci_read_config(ahc->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, + status1, /*bytes*/1); + ahc_outb(ahc, CLRINT, CLRPARERR); + ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); + return (error); +} + +/* * Check the external port logic for a serial eeprom * and termination/cable detection contrls. */ @@ -1279,13 +1407,12 @@ int i; sc_data = (uint16_t *)sc; - for (i = 0; i < 32; i++) { - uint16_t val; - int j; + for (i = 0; i < 32; i++, sc_data++) { + int j; j = i * 2; - val = ahc_inb(ahc, SRAM_BASE + j) - | ahc_inb(ahc, SRAM_BASE + j + 1) << 8; + *sc_data = ahc_inb(ahc, SRAM_BASE + j) + | ahc_inb(ahc, SRAM_BASE + j + 1) << 8; } have_seeprom = ahc_verify_cksum(sc); if (have_seeprom) @@ -1329,6 +1456,7 @@ } if (have_autoterm) { + ahc->flags |= AHC_HAS_TERM_LOGIC; ahc_acquire_seeprom(ahc, &sd); configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1); ahc_release_seeprom(&sd); @@ -1528,6 +1656,8 @@ aic785X_cable_detect(ahc, &internal50_present, &externalcable_present, &eeprom_present); + /* Can never support a wide connector. */ + internal68_present = 0; } else { aic787X_cable_detect(ahc, &internal50_present, &internal68_present, @@ -1760,14 +1890,52 @@ spiocap |= EXT_BRDCTL; ahc_outb(ahc, SPIOCAP, spiocap); ahc_outb(ahc, BRDCTL, BRDRW|BRDCS); + ahc_flush_device_writes(ahc); + ahc_delay(500); ahc_outb(ahc, BRDCTL, 0); + ahc_flush_device_writes(ahc); + ahc_delay(500); brdctl = ahc_inb(ahc, BRDCTL); *internal50_present = (brdctl & BRDDAT5) ? 0 : 1; *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; - *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0; } +int +ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd) +{ + int wait; + + if ((ahc->features & AHC_SPIOCAP) != 0 + && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0) + return (0); + + /* + * Request access of the memory port. When access is + * granted, SEERDY will go high. We use a 1 second + * timeout which should be near 1 second more than + * is needed. Reason: after the chip reset, there + * should be no contention. + */ + SEEPROM_OUTB(sd, sd->sd_MS); + wait = 1000; /* 1 second timeout in msec */ + while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) { + ahc_delay(1000); /* delay 1 msec */ + } + if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) { + SEEPROM_OUTB(sd, 0); + return (0); + } + return(1); +} + +void +ahc_release_seeprom(struct seeprom_descriptor *sd) +{ + /* Release access to the memory port and the serial EEPROM. */ + SEEPROM_OUTB(sd, 0); +} + static void write_brdctl(struct ahc_softc *ahc, uint8_t value) { @@ -1801,8 +1969,7 @@ } static uint8_t -read_brdctl(ahc) - struct ahc_softc *ahc; +read_brdctl(struct ahc_softc *ahc) { uint8_t brdctl; uint8_t value; @@ -1823,14 +1990,7 @@ return (value); } -#define DPE 0x80 -#define SSE 0x40 -#define RMA 0x20 -#define RTA 0x10 -#define STA 0x08 -#define DPR 0x01 - -void +static void ahc_pci_intr(struct ahc_softc *ahc) { u_int error; @@ -1848,6 +2008,7 @@ ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); if (status1 & DPE) { + ahc->pci_target_perr_count++; printf("%s: Data Parity Error Detected during address " "or write data phase\n", ahc_name(ahc)); } @@ -1879,10 +2040,90 @@ ahc_outb(ahc, CLRINT, CLRPARERR); } + if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) { + printf( +"%s: WARNING WARNING WARNING WARNING\n" +"%s: Too many PCI parity errors observed as a target.\n" +"%s: Some device on this bus is generating bad parity.\n" +"%s: This is an error *observed by*, not *generated by*, this controller.\n" +"%s: PCI parity error checking has been disabled.\n" +"%s: WARNING WARNING WARNING WARNING\n", + ahc_name(ahc), ahc_name(ahc), ahc_name(ahc), + ahc_name(ahc), ahc_name(ahc), ahc_name(ahc)); + ahc->seqctl |= FAILDIS; + ahc_outb(ahc, SEQCTL, ahc->seqctl); + } ahc_unpause(ahc); } static int +ahc_pci_chip_init(struct ahc_softc *ahc) +{ + ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0); + ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus); + if ((ahc->features & AHC_DT) != 0) { + u_int sfunct; + + sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; + ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); + ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode); + ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt); + ahc_outb(ahc, SFUNCT, sfunct); + ahc_outb(ahc, CRCCONTROL1, + ahc->bus_softc.pci_softc.crccontrol1); + } + if ((ahc->features & AHC_MULTI_FUNC) != 0) + ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr); + + if ((ahc->features & AHC_ULTRA2) != 0) + ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh); + + return (ahc_chip_init(ahc)); +} + +static int +ahc_pci_suspend(struct ahc_softc *ahc) +{ + return (ahc_suspend(ahc)); +} + +static int +ahc_pci_resume(struct ahc_softc *ahc) +{ + + ahc_power_state_change(ahc, AHC_POWER_STATE_D0); + + /* + * We assume that the OS has restored our register + * mappings, etc. Just update the config space registers + * that the OS doesn't know about and rely on our chip + * reset handler to handle the rest. + */ + ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4, + ahc->bus_softc.pci_softc.devconfig); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1, + ahc->bus_softc.pci_softc.command); + ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1, + ahc->bus_softc.pci_softc.csize_lattime); + if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) { + struct seeprom_descriptor sd; + u_int sxfrctl1; + + sd.sd_ahc = ahc; + sd.sd_control_offset = SEECTL; + sd.sd_status_offset = SEECTL; + sd.sd_dataout_offset = SEECTL; + + ahc_acquire_seeprom(ahc, &sd); + configure_termination(ahc, &sd, + ahc->seep_config->adapter_control, + &sxfrctl1); + ahc_release_seeprom(&sd); + } + return (ahc_resume(ahc)); +} + +static int ahc_aic785X_setup(struct ahc_softc *ahc) { ahc_dev_softc_t pci; @@ -1896,6 +2137,7 @@ rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); if (rev >= 1) ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; + ahc->instruction_ram_size = 512; return (0); } @@ -1913,16 +2155,15 @@ rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); if (rev >= 1) ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; + ahc->instruction_ram_size = 512; return (0); } static int ahc_apa1480_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; int error; - pci = ahc->dev_softc; error = ahc_aic7860_setup(ahc); if (error != 0) return (error); @@ -1933,13 +2174,12 @@ static int ahc_aic7870_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; - pci = ahc->dev_softc; ahc->channel = 'A'; ahc->chip = AHC_AIC7870; ahc->features = AHC_AIC7870_FE; ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; + ahc->instruction_ram_size = 512; return (0); } @@ -1993,19 +2233,16 @@ } else { ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; } + ahc->instruction_ram_size = 512; return (0); } static int ahc_aha2940Pro_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; - int error; - pci = ahc->dev_softc; ahc->flags |= AHC_INT50_SPEEDFLEX; - error = ahc_aic7880_setup(ahc); - return (0); + return (ahc_aic7880_setup(ahc)); } static int @@ -2044,20 +2281,20 @@ rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); if (rev == 0) ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG; + ahc->instruction_ram_size = 768; return (0); } static int ahc_aic7892_setup(struct ahc_softc *ahc) { - ahc_dev_softc_t pci; - pci = ahc->dev_softc; ahc->channel = 'A'; ahc->chip = AHC_AIC7892; ahc->features = AHC_AIC7892_FE; ahc->flags |= AHC_NEWEEPROM_FMT; ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; + ahc->instruction_ram_size = 1024; return (0); } @@ -2113,6 +2350,7 @@ ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1); #endif ahc->flags |= AHC_NEWEEPROM_FMT; + ahc->instruction_ram_size = 512; return (0); } @@ -2127,6 +2365,7 @@ ahc->features = AHC_AIC7896_FE; ahc->flags |= AHC_NEWEEPROM_FMT; ahc->bugs |= AHC_CACHETHEN_DIS_BUG; + ahc->instruction_ram_size = 768; return (0); } @@ -2141,6 +2380,7 @@ ahc->features = AHC_AIC7899_FE; ahc->flags |= AHC_NEWEEPROM_FMT; ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; + ahc->instruction_ram_size = 1024; return (0); } diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_proc.c linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_proc.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_proc.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_proc.c 2003-08-25 04:44:42.000000000 -0700 @@ -37,7 +37,7 @@ * String handling code courtesy of Gerard Roudier's * sym driver. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#19 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#29 $ */ #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" @@ -45,7 +45,6 @@ static void copy_mem_info(struct info_str *info, char *data, int len); static int copy_info(struct info_str *info, char *fmt, ...); -static u_int scsi_calc_syncsrate(u_int period_factor); static void ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, u_int our_id, char channel, @@ -54,44 +53,6 @@ struct ahc_linux_device *dev); static int ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length); - - -int -ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd) -{ - int wait; - - if ((ahc->features & AHC_SPIOCAP) != 0 - && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0) - return (0); - - /* - * Request access of the memory port. When access is - * granted, SEERDY will go high. We use a 1 second - * timeout which should be near 1 second more than - * is needed. Reason: after the chip reset, there - * should be no contention. - */ - SEEPROM_OUTB(sd, sd->sd_MS); - wait = 1000; /* 1 second timeout in msec */ - while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) { - ahc_delay(1000); /* delay 1 msec */ - } - if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) { - SEEPROM_OUTB(sd, 0); - return (0); - } - return(1); -} - - -void -ahc_release_seeprom(struct seeprom_descriptor *sd) -{ - /* Release access to the memory port and the serial EEPROM. */ - SEEPROM_OUTB(sd, 0); -} - static void copy_mem_info(struct info_str *info, char *data, int len) @@ -135,47 +96,6 @@ return (len); } -/* - * Table of syncrates that don't follow the "divisible by 4" - * rule. This table will be expanded in future SCSI specs. - */ -static struct { - u_int period_factor; - u_int period; /* in 10ths of ns */ -} scsi_syncrates[] = { - { 0x09, 125 }, /* FAST-80 */ - { 0x0a, 250 }, /* FAST-40 40MHz */ - { 0x0b, 303 }, /* FAST-40 33MHz */ - { 0x0c, 500 } /* FAST-20 */ -}; - -/* - * Return the frequency in kHz corresponding to the given - * sync period factor. - */ -static u_int -scsi_calc_syncsrate(u_int period_factor) -{ - int i; - int num_syncrates; - - num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); - /* See if the period is in the "exception" table */ - for (i = 0; i < num_syncrates; i++) { - - if (period_factor == scsi_syncrates[i].period_factor) { - /* Period in kHz */ - return (10000000 / scsi_syncrates[i].period); - } - } - - /* - * Wasn't in the table, so use the standard - * 4 times conversion. - */ - return (10000000 / (period_factor * 4 * 10)); -} - void ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo) { @@ -186,7 +106,7 @@ speed = 3300; freq = 0; if (tinfo->offset != 0) { - freq = scsi_calc_syncsrate(tinfo->period); + freq = aic_calc_syncsrate(tinfo->period); speed = freq; } speed *= (0x01 << tinfo->width); @@ -228,8 +148,9 @@ tinfo = ahc_fetch_transinfo(ahc, channel, our_id, target_id, &tstate); - copy_info(info, "Channel %c Target %d Negotiation Settings\n", - channel, target_id); + if ((ahc->features & AHC_TWIN) != 0) + copy_info(info, "Channel %c ", channel); + copy_info(info, "Target %d Negotiation Settings\n", target_id); copy_info(info, "\tUser: "); ahc_format_transinfo(info, &tinfo->user); targ = ahc->platform_data->targets[target_offset]; @@ -294,19 +215,8 @@ } sd.sd_ahc = ahc; - if ((ahc->chip & AHC_VL) != 0) { - sd.sd_control_offset = SEECTL_2840; - sd.sd_status_offset = STATUS_2840; - sd.sd_dataout_offset = STATUS_2840; - sd.sd_chip = C46; - sd.sd_MS = 0; - sd.sd_RDY = EEPROM_TF; - sd.sd_CS = CS_2840; - sd.sd_CK = CK_2840; - sd.sd_DO = DO_2840; - sd.sd_DI = DI_2840; - have_seeprom = TRUE; - } else { +#if AHC_PCI_CONFIG > 0 + if ((ahc->chip & AHC_PCI) != 0) { sd.sd_control_offset = SEECTL; sd.sd_status_offset = SEECTL; sd.sd_dataout_offset = SEECTL; @@ -321,6 +231,23 @@ sd.sd_DO = SEEDO; sd.sd_DI = SEEDI; have_seeprom = ahc_acquire_seeprom(ahc, &sd); + } else +#endif + if ((ahc->chip & AHC_VL) != 0) { + sd.sd_control_offset = SEECTL_2840; + sd.sd_status_offset = STATUS_2840; + sd.sd_dataout_offset = STATUS_2840; + sd.sd_chip = C46; + sd.sd_MS = 0; + sd.sd_RDY = EEPROM_TF; + sd.sd_CS = CS_2840; + sd.sd_CK = CK_2840; + sd.sd_DO = DO_2840; + sd.sd_DI = DI_2840; + have_seeprom = TRUE; + } else { + printf("ahc_proc_write_seeprom: unsupported adapter type\n"); + goto done; } if (!have_seeprom) { @@ -344,8 +271,10 @@ sizeof(struct seeprom_config)/2); ahc_read_seeprom(&sd, (uint16_t *)ahc->seep_config, start_addr, sizeof(struct seeprom_config)/2); +#if AHC_PCI_CONFIG > 0 if ((ahc->chip & AHC_VL) == 0) ahc_release_seeprom(&sd); +#endif written = length; } @@ -360,8 +289,13 @@ * Return information to handle /proc support for the driver. */ int +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ahc_linux_proc_info(char *buffer, char **start, off_t offset, - int length, int hostno, int inout) + int length, int hostno, int inout) +#else +ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, + off_t offset, int length, int inout) +#endif { struct ahc_softc *ahc; struct info_str info; @@ -373,10 +307,14 @@ retval = -EINVAL; ahc_list_lock(&s); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) TAILQ_FOREACH(ahc, &ahc_tailq, links) { if (ahc->platform_data->host->host_no == hostno) break; } +#else + ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata); +#endif if (ahc == NULL) goto done; @@ -397,8 +335,12 @@ copy_info(&info, "Adaptec AIC7xxx driver version: %s\n", AIC7XXX_DRIVER_VERSION); + copy_info(&info, "%s\n", ahc->description); ahc_controller_info(ahc, ahc_info); - copy_info(&info, "%s\n\n", ahc_info); + copy_info(&info, "%s\n", ahc_info); + copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", + ahc->scb_data->numscbs, AHC_NSEG); + if (ahc->seep_config == NULL) copy_info(&info, "No Serial EEPROM\n"); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_reg.h linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_reg.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_reg.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_reg.h 2003-08-25 04:44:42.000000000 -0700 @@ -2,9 +2,1066 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $ - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $ */ +typedef int (ahc_reg_print_t)(u_int, u_int *, u_int); +typedef struct ahc_reg_parse_entry { + char *name; + uint8_t value; + uint8_t mask; +} ahc_reg_parse_entry_t; + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiseq_print; +#else +#define ahc_scsiseq_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISEQ", 0x00, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sxfrctl0_print; +#else +#define ahc_sxfrctl0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SXFRCTL0", 0x01, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sxfrctl1_print; +#else +#define ahc_sxfrctl1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SXFRCTL1", 0x02, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsisigo_print; +#else +#define ahc_scsisigo_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISIGO", 0x03, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsisigi_print; +#else +#define ahc_scsisigi_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISIGI", 0x03, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsirate_print; +#else +#define ahc_scsirate_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIRATE", 0x04, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiid_print; +#else +#define ahc_scsiid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIID", 0x05, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsidatl_print; +#else +#define ahc_scsidatl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIDATL", 0x06, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsidath_print; +#else +#define ahc_scsidath_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIDATH", 0x07, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_stcnt_print; +#else +#define ahc_stcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "STCNT", 0x08, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_optionmode_print; +#else +#define ahc_optionmode_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "OPTIONMODE", 0x08, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_targcrccnt_print; +#else +#define ahc_targcrccnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TARGCRCCNT", 0x0a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_clrsint0_print; +#else +#define ahc_clrsint0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CLRSINT0", 0x0b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat0_print; +#else +#define ahc_sstat0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT0", 0x0b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_clrsint1_print; +#else +#define ahc_clrsint1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CLRSINT1", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat1_print; +#else +#define ahc_sstat1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT1", 0x0c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat2_print; +#else +#define ahc_sstat2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT2", 0x0d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sstat3_print; +#else +#define ahc_sstat3_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SSTAT3", 0x0e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiid_ultra2_print; +#else +#define ahc_scsiid_ultra2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIID_ULTRA2", 0x0f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_simode0_print; +#else +#define ahc_simode0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SIMODE0", 0x10, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_simode1_print; +#else +#define ahc_simode1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SIMODE1", 0x11, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsibusl_print; +#else +#define ahc_scsibusl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIBUSL", 0x12, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsibush_print; +#else +#define ahc_scsibush_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIBUSH", 0x13, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sxfrctl2_print; +#else +#define ahc_sxfrctl2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SXFRCTL2", 0x13, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_shaddr_print; +#else +#define ahc_shaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SHADDR", 0x14, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seltimer_print; +#else +#define ahc_seltimer_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SELTIMER", 0x18, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_selid_print; +#else +#define ahc_selid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SELID", 0x19, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scamctl_print; +#else +#define ahc_scamctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCAMCTL", 0x1a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_targid_print; +#else +#define ahc_targid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TARGID", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_spiocap_print; +#else +#define ahc_spiocap_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SPIOCAP", 0x1b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_brdctl_print; +#else +#define ahc_brdctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BRDCTL", 0x1d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seectl_print; +#else +#define ahc_seectl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEECTL", 0x1e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sblkctl_print; +#else +#define ahc_sblkctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SBLKCTL", 0x1f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_busy_targets_print; +#else +#define ahc_busy_targets_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BUSY_TARGETS", 0x20, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ultra_enb_print; +#else +#define ahc_ultra_enb_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ULTRA_ENB", 0x30, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_disc_dsb_print; +#else +#define ahc_disc_dsb_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DISC_DSB", 0x32, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_cmdsize_table_tail_print; +#else +#define ahc_cmdsize_table_tail_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CMDSIZE_TABLE_TAIL", 0x34, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_mwi_residual_print; +#else +#define ahc_mwi_residual_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "MWI_RESIDUAL", 0x38, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_next_queued_scb_print; +#else +#define ahc_next_queued_scb_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB", 0x39, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_msg_out_print; +#else +#define ahc_msg_out_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "MSG_OUT", 0x3a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dmaparams_print; +#else +#define ahc_dmaparams_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DMAPARAMS", 0x3b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seq_flags_print; +#else +#define ahc_seq_flags_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQ_FLAGS", 0x3c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_saved_scsiid_print; +#else +#define ahc_saved_scsiid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SAVED_SCSIID", 0x3d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_saved_lun_print; +#else +#define ahc_saved_lun_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SAVED_LUN", 0x3e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_lastphase_print; +#else +#define ahc_lastphase_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "LASTPHASE", 0x3f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_waiting_scbh_print; +#else +#define ahc_waiting_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "WAITING_SCBH", 0x40, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_disconnected_scbh_print; +#else +#define ahc_disconnected_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DISCONNECTED_SCBH", 0x41, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_free_scbh_print; +#else +#define ahc_free_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "FREE_SCBH", 0x42, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_complete_scbh_print; +#else +#define ahc_complete_scbh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "COMPLETE_SCBH", 0x43, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hscb_addr_print; +#else +#define ahc_hscb_addr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HSCB_ADDR", 0x44, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_shared_data_addr_print; +#else +#define ahc_shared_data_addr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x48, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_kernel_qinpos_print; +#else +#define ahc_kernel_qinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "KERNEL_QINPOS", 0x4c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qinpos_print; +#else +#define ahc_qinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QINPOS", 0x4d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoutpos_print; +#else +#define ahc_qoutpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOUTPOS", 0x4e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_kernel_tqinpos_print; +#else +#define ahc_kernel_tqinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "KERNEL_TQINPOS", 0x4f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_tqinpos_print; +#else +#define ahc_tqinpos_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TQINPOS", 0x50, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_arg_1_print; +#else +#define ahc_arg_1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ARG_1", 0x51, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_arg_2_print; +#else +#define ahc_arg_2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ARG_2", 0x52, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_last_msg_print; +#else +#define ahc_last_msg_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "LAST_MSG", 0x53, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiseq_template_print; +#else +#define ahc_scsiseq_template_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x54, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ha_274_biosglobal_print; +#else +#define ahc_ha_274_biosglobal_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HA_274_BIOSGLOBAL", 0x56, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seq_flags2_print; +#else +#define ahc_seq_flags2_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQ_FLAGS2", 0x57, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiconf_print; +#else +#define ahc_scsiconf_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSICONF", 0x5a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_intdef_print; +#else +#define ahc_intdef_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "INTDEF", 0x5c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hostconf_print; +#else +#define ahc_hostconf_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HOSTCONF", 0x5d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ha_274_biosctrl_print; +#else +#define ahc_ha_274_biosctrl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HA_274_BIOSCTRL", 0x5f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqctl_print; +#else +#define ahc_seqctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQCTL", 0x60, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqram_print; +#else +#define ahc_seqram_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQRAM", 0x61, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqaddr0_print; +#else +#define ahc_seqaddr0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQADDR0", 0x62, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seqaddr1_print; +#else +#define ahc_seqaddr1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEQADDR1", 0x63, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_accum_print; +#else +#define ahc_accum_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ACCUM", 0x64, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sindex_print; +#else +#define ahc_sindex_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SINDEX", 0x65, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dindex_print; +#else +#define ahc_dindex_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DINDEX", 0x66, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_allones_print; +#else +#define ahc_allones_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ALLONES", 0x69, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_allzeros_print; +#else +#define ahc_allzeros_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ALLZEROS", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_none_print; +#else +#define ahc_none_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "NONE", 0x6a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_flags_print; +#else +#define ahc_flags_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "FLAGS", 0x6b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sindir_print; +#else +#define ahc_sindir_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SINDIR", 0x6c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dindir_print; +#else +#define ahc_dindir_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DINDIR", 0x6d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_function1_print; +#else +#define ahc_function1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "FUNCTION1", 0x6e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_stack_print; +#else +#define ahc_stack_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "STACK", 0x6f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_targ_offset_print; +#else +#define ahc_targ_offset_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "TARG_OFFSET", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sram_base_print; +#else +#define ahc_sram_base_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SRAM_BASE", 0x70, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_bctl_print; +#else +#define ahc_bctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BCTL", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dscommand0_print; +#else +#define ahc_dscommand0_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DSCOMMAND0", 0x84, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_bustime_print; +#else +#define ahc_bustime_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BUSTIME", 0x85, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dscommand1_print; +#else +#define ahc_dscommand1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DSCOMMAND1", 0x85, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_busspd_print; +#else +#define ahc_busspd_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "BUSSPD", 0x86, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hs_mailbox_print; +#else +#define ahc_hs_mailbox_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HS_MAILBOX", 0x86, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dspcistatus_print; +#else +#define ahc_dspcistatus_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DSPCISTATUS", 0x86, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hcntrl_print; +#else +#define ahc_hcntrl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HCNTRL", 0x87, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_haddr_print; +#else +#define ahc_haddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HADDR", 0x88, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hcnt_print; +#else +#define ahc_hcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HCNT", 0x8c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scbptr_print; +#else +#define ahc_scbptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCBPTR", 0x90, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_intstat_print; +#else +#define ahc_intstat_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "INTSTAT", 0x91, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_clrint_print; +#else +#define ahc_clrint_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CLRINT", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_error_print; +#else +#define ahc_error_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "ERROR", 0x92, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfcntrl_print; +#else +#define ahc_dfcntrl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFCNTRL", 0x93, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfstatus_print; +#else +#define ahc_dfstatus_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFSTATUS", 0x94, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfwaddr_print; +#else +#define ahc_dfwaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFWADDR", 0x95, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfraddr_print; +#else +#define ahc_dfraddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFRADDR", 0x97, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dfdat_print; +#else +#define ahc_dfdat_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFDAT", 0x99, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scbcnt_print; +#else +#define ahc_scbcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCBCNT", 0x9a, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qinfifo_print; +#else +#define ahc_qinfifo_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QINFIFO", 0x9b, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qincnt_print; +#else +#define ahc_qincnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QINCNT", 0x9c, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoutfifo_print; +#else +#define ahc_qoutfifo_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOUTFIFO", 0x9d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_crccontrol1_print; +#else +#define ahc_crccontrol1_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CRCCONTROL1", 0x9d, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoutcnt_print; +#else +#define ahc_qoutcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOUTCNT", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scsiphase_print; +#else +#define ahc_scsiphase_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCSIPHASE", 0x9e, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sfunct_print; +#else +#define ahc_sfunct_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_base_print; +#else +#define ahc_scb_base_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_BASE", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_cdb_ptr_print; +#else +#define ahc_scb_cdb_ptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_CDB_PTR", 0xa0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_residual_sgptr_print; +#else +#define ahc_scb_residual_sgptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0xa4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsi_status_print; +#else +#define ahc_scb_scsi_status_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSI_STATUS", 0xa8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_target_phases_print; +#else +#define ahc_scb_target_phases_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TARGET_PHASES", 0xa9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_target_data_dir_print; +#else +#define ahc_scb_target_data_dir_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0xaa, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_target_itag_print; +#else +#define ahc_scb_target_itag_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TARGET_ITAG", 0xab, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_dataptr_print; +#else +#define ahc_scb_dataptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_DATAPTR", 0xac, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_datacnt_print; +#else +#define ahc_scb_datacnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_DATACNT", 0xb0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_sgptr_print; +#else +#define ahc_scb_sgptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SGPTR", 0xb4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_control_print; +#else +#define ahc_scb_control_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_CONTROL", 0xb8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsiid_print; +#else +#define ahc_scb_scsiid_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSIID", 0xb9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_lun_print; +#else +#define ahc_scb_lun_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_LUN", 0xba, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_tag_print; +#else +#define ahc_scb_tag_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_TAG", 0xbb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_cdb_len_print; +#else +#define ahc_scb_cdb_len_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_CDB_LEN", 0xbc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsirate_print; +#else +#define ahc_scb_scsirate_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSIRATE", 0xbd, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_scsioffset_print; +#else +#define ahc_scb_scsioffset_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_SCSIOFFSET", 0xbe, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_next_print; +#else +#define ahc_scb_next_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_NEXT", 0xbf, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_64_spare_print; +#else +#define ahc_scb_64_spare_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_64_SPARE", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_seectl_2840_print; +#else +#define ahc_seectl_2840_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SEECTL_2840", 0xc0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_status_2840_print; +#else +#define ahc_status_2840_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "STATUS_2840", 0xc1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scb_64_btt_print; +#else +#define ahc_scb_64_btt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCB_64_BTT", 0xd0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_cchaddr_print; +#else +#define ahc_cchaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCHADDR", 0xe0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_cchcnt_print; +#else +#define ahc_cchcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCHCNT", 0xe8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccsgram_print; +#else +#define ahc_ccsgram_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSGRAM", 0xe9, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccsgaddr_print; +#else +#define ahc_ccsgaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSGADDR", 0xea, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccsgctl_print; +#else +#define ahc_ccsgctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSGCTL", 0xeb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbram_print; +#else +#define ahc_ccscbram_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBRAM", 0xec, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbaddr_print; +#else +#define ahc_ccscbaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBADDR", 0xed, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbctl_print; +#else +#define ahc_ccscbctl_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBCTL", 0xee, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbcnt_print; +#else +#define ahc_ccscbcnt_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBCNT", 0xef, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_scbbaddr_print; +#else +#define ahc_scbbaddr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SCBBADDR", 0xf0, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_ccscbptr_print; +#else +#define ahc_ccscbptr_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "CCSCBPTR", 0xf1, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_hnscb_qoff_print; +#else +#define ahc_hnscb_qoff_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "HNSCB_QOFF", 0xf4, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_snscb_qoff_print; +#else +#define ahc_snscb_qoff_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SNSCB_QOFF", 0xf6, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sdscb_qoff_print; +#else +#define ahc_sdscb_qoff_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SDSCB_QOFF", 0xf8, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_qoff_ctlsta_print; +#else +#define ahc_qoff_ctlsta_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "QOFF_CTLSTA", 0xfa, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_dff_thrsh_print; +#else +#define ahc_dff_thrsh_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "DFF_THRSH", 0xfb, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sg_cache_shadow_print; +#else +#define ahc_sg_cache_shadow_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SG_CACHE_SHADOW", 0xfc, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahc_reg_print_t ahc_sg_cache_pre_print; +#else +#define ahc_sg_cache_pre_print(regvalue, cur_col, wrap) \ + ahc_print_register(NULL, 0, "SG_CACHE_PRE", 0xfc, regvalue, cur_col, wrap) +#endif + #define SCSISEQ 0x00 #define TEMODE 0x80 @@ -20,9 +1077,9 @@ #define CLRCHN 0x02 #define SXFRCTL1 0x02 +#define STIMESEL 0x18 #define BITBUCKET 0x80 #define SWRAPEN 0x40 -#define STIMESEL 0x18 #define ENSTIMER 0x04 #define ACTNEGEN 0x02 #define STPWEN 0x01 @@ -47,12 +1104,12 @@ #define ACKI 0x01 #define SCSIRATE 0x04 -#define WIDEXFER 0x80 #define SXFR 0x70 -#define ENABLE_CRC 0x40 -#define SINGLE_EDGE 0x10 #define SOFS 0x0f #define SXFR_ULTRA2 0x0f +#define WIDEXFER 0x80 +#define ENABLE_CRC 0x40 +#define SINGLE_EDGE 0x10 #define SCSIID 0x05 #define SCSIOFFSET 0x05 @@ -65,13 +1122,13 @@ #define STCNT 0x08 #define OPTIONMODE 0x08 +#define OPTIONMODE_DEFAULTS 0x03 #define AUTORATEEN 0x80 #define AUTOACKEN 0x40 #define ATNMGMNTEN 0x20 #define BUSFREEREV 0x10 #define EXPPHASEDIS 0x08 #define SCSIDATL_IMGEN 0x04 -#define OPTIONMODE_DEFAULTS 0x03 #define AUTO_MSGOUT_DE 0x02 #define DIS_MSGIN_DUALEDGE 0x01 @@ -116,9 +1173,9 @@ #define REQINIT 0x01 #define SSTAT2 0x0d +#define SFCNT 0x1f #define OVERRUN 0x80 #define SHVALID 0x40 -#define SFCNT 0x1f #define EXP_ACTIVE 0x10 #define CRCVALERR 0x08 #define CRCENDERR 0x04 @@ -156,6 +1213,11 @@ #define SCSIBUSH 0x13 +#define SXFRCTL2 0x13 +#define ASYNC_SETUP 0x07 +#define AUTORSTDIS 0x10 +#define CMDDMAEN 0x08 + #define SHADDR 0x14 #define SELTIMER 0x18 @@ -172,11 +1234,11 @@ #define ONEBIT 0x08 #define SCAMCTL 0x1a +#define SCAMLVL 0x03 #define ENSCAMSELO 0x80 #define CLRSCAMSELID 0x40 #define ALTSTIM 0x20 #define DFLTTID 0x10 -#define SCAMLVL 0x03 #define TARGID 0x1b @@ -236,6 +1298,7 @@ #define CMDSIZE_TABLE_TAIL 0x34 #define MWI_RESIDUAL 0x38 +#define TARG_IMMEDIATE_SCB 0x38 #define NEXT_QUEUED_SCB 0x39 @@ -254,7 +1317,8 @@ #define FIFORESET 0x01 #define SEQ_FLAGS 0x3c -#define IDENTIFY_SEEN 0x80 +#define NOT_IDENTIFIED 0x80 +#define NO_CDB_SENT 0x40 #define TARGET_CMD_IS_TAGGED 0x40 #define DPHASE 0x20 #define TARG_CMD_PENDING 0x10 @@ -273,12 +1337,12 @@ #define P_STATUS 0xc0 #define P_MESGOUT 0xa0 #define P_COMMAND 0x80 -#define CDI 0x80 #define P_DATAIN 0x40 -#define IOI 0x40 -#define MSGI 0x20 #define P_BUSFREE 0x01 #define P_DATAOUT 0x00 +#define CDI 0x80 +#define IOI 0x40 +#define MSGI 0x20 #define WAITING_SCBH 0x40 @@ -325,8 +1389,6 @@ #define ENAUTOATNI 0x04 #define ENAUTOATNP 0x02 -#define DATA_COUNT_ODD 0x55 - #define HA_274_BIOSGLOBAL 0x56 #define INITIATOR_TAG 0x56 #define HA_274_EXTENDED_TRANS 0x01 @@ -336,15 +1398,15 @@ #define SCB_DMA 0x01 #define SCSICONF 0x5a +#define HWSCSIID 0x0f +#define HSCSIID 0x07 #define TERM_ENB 0x80 #define RESET_SCSI 0x40 #define ENSPCHK 0x20 -#define HWSCSIID 0x0f -#define HSCSIID 0x07 #define INTDEF 0x5c -#define EDGE_TRIG 0x80 #define VECTOR 0x0f +#define EDGE_TRIG 0x80 #define HOSTCONF 0x5d @@ -464,13 +1526,13 @@ #define PDATA_REINIT 0x51 #define IGN_WIDE_RES 0x41 #define NO_MATCH 0x31 -#define NO_IDENT 0x21 +#define PROTO_VIOLATION 0x21 #define SEND_REJECT 0x11 #define INT_PEND 0x0f +#define BAD_PHASE 0x01 #define BRKADRINT 0x08 #define SCSIINT 0x04 #define CMDCMPLT 0x02 -#define BAD_PHASE 0x01 #define SEQINT 0x01 #define CLRINT 0x92 @@ -509,8 +1571,8 @@ #define DFDAT 0x99 #define SCBCNT 0x9a -#define SCBAUTO 0x80 #define SCBCNT_MASK 0x1f +#define SCBAUTO 0x80 #define QINFIFO 0x9b @@ -529,11 +1591,11 @@ #define QOUTCNT 0x9e #define SCSIPHASE 0x9e +#define DATA_PHASE_MASK 0x03 #define STATUS_PHASE 0x20 #define COMMAND_PHASE 0x10 #define MSG_IN_PHASE 0x08 #define MSG_OUT_PHASE 0x04 -#define DATA_PHASE_MASK 0x03 #define DATA_IN_PHASE 0x02 #define DATA_OUT_PHASE 0x01 @@ -559,8 +1621,8 @@ #define SCB_DATAPTR 0xac #define SCB_DATACNT 0xb0 -#define SG_LAST_SEG 0x80 #define SG_HIGH_ADDR_BITS 0x7f +#define SG_LAST_SEG 0x80 #define SCB_SGPTR 0xb4 #define SG_RESID_VALID 0x04 @@ -568,22 +1630,24 @@ #define SG_LIST_NULL 0x01 #define SCB_CONTROL 0xb8 +#define SCB_TAG_TYPE 0x03 +#define STATUS_RCVD 0x80 #define TARGET_SCB 0x80 #define DISCENB 0x40 #define TAG_ENB 0x20 #define MK_MESSAGE 0x10 #define ULTRAENB 0x08 #define DISCONNECTED 0x04 -#define SCB_TAG_TYPE 0x03 #define SCB_SCSIID 0xb9 #define TID 0xf0 -#define TWIN_CHNLB 0x80 #define TWIN_TID 0x70 #define OID 0x0f +#define TWIN_CHNLB 0x80 #define SCB_LUN 0xba -#define LID 0xff +#define LID 0x3f +#define SCB_XFERLEN_ODD 0x80 #define SCB_TAG 0xbb @@ -603,9 +1667,9 @@ #define DO_2840 0x01 #define STATUS_2840 0xc1 -#define EEPROM_TF 0x80 #define BIOS_SEL 0x60 #define ADSEL 0x1e +#define EEPROM_TF 0x80 #define DI_2840 0x01 #define SCB_64_BTT 0xd0 @@ -649,11 +1713,11 @@ #define SDSCB_QOFF 0xf8 #define QOFF_CTLSTA 0xfa +#define SCB_QSIZE 0x07 +#define SCB_QSIZE_256 0x06 #define SCB_AVAIL 0x40 #define SNSCB_ROLLOVER 0x20 #define SDSCB_ROLLOVER 0x10 -#define SCB_QSIZE 0x07 -#define SCB_QSIZE_256 0x06 #define DFF_THRSH 0xfb #define WR_DFTHRSH 0x70 @@ -677,7 +1741,6 @@ #define SG_CACHE_SHADOW 0xfc #define SG_ADDR_MASK 0xf8 -#define ODD_SEG 0x04 #define LAST_SEG 0x02 #define LAST_SEG_DONE 0x01 @@ -704,8 +1767,10 @@ #define SEQ_MAILBOX_SHIFT 0x00 #define TARGET_DATA_IN 0x01 #define HOST_MSG 0xff +#define MAX_OFFSET 0x7f #define BUS_16_BIT 0x01 #define SCB_UPLOAD_SIZE 0x20 +#define STACK_SIZE 0x04 /* Downloaded Constant Definitions */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_reg_print.c linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_reg_print.c --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_reg_print.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_reg_print.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1681 @@ +/* + * DO NOT EDIT - This file is automatically generated + * from the following source files: + * + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $ + */ + +#include "aic7xxx_osm.h" + +static ahc_reg_parse_entry_t SCSISEQ_parse_table[] = { + { "SCSIRSTO", 0x01, 0x01 }, + { "ENAUTOATNP", 0x02, 0x02 }, + { "ENAUTOATNI", 0x04, 0x04 }, + { "ENAUTOATNO", 0x08, 0x08 }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "ENSELO", 0x40, 0x40 }, + { "TEMODE", 0x80, 0x80 } +}; + +int +ahc_scsiseq_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISEQ_parse_table, 8, "SCSISEQ", + 0x00, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SXFRCTL0_parse_table[] = { + { "CLRCHN", 0x02, 0x02 }, + { "SCAMEN", 0x04, 0x04 }, + { "SPIOEN", 0x08, 0x08 }, + { "CLRSTCNT", 0x10, 0x10 }, + { "FAST20", 0x20, 0x20 }, + { "DFPEXP", 0x40, 0x40 }, + { "DFON", 0x80, 0x80 } +}; + +int +ahc_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SXFRCTL0_parse_table, 7, "SXFRCTL0", + 0x01, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SXFRCTL1_parse_table[] = { + { "STPWEN", 0x01, 0x01 }, + { "ACTNEGEN", 0x02, 0x02 }, + { "ENSTIMER", 0x04, 0x04 }, + { "ENSPCHK", 0x20, 0x20 }, + { "SWRAPEN", 0x40, 0x40 }, + { "BITBUCKET", 0x80, 0x80 }, + { "STIMESEL", 0x18, 0x18 } +}; + +int +ahc_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1", + 0x02, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSISIGO_parse_table[] = { + { "ACKO", 0x01, 0x01 }, + { "REQO", 0x02, 0x02 }, + { "BSYO", 0x04, 0x04 }, + { "SELO", 0x08, 0x08 }, + { "ATNO", 0x10, 0x10 }, + { "MSGO", 0x20, 0x20 }, + { "IOO", 0x40, 0x40 }, + { "CDO", 0x80, 0x80 }, + { "P_DATAOUT", 0x00, 0x00 }, + { "P_DATAIN", 0x40, 0x40 }, + { "P_COMMAND", 0x80, 0x80 }, + { "P_MESGOUT", 0xa0, 0xa0 }, + { "P_STATUS", 0xc0, 0xc0 }, + { "PHASE_MASK", 0xe0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 } +}; + +int +ahc_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISIGO_parse_table, 15, "SCSISIGO", + 0x03, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSISIGI_parse_table[] = { + { "ACKI", 0x01, 0x01 }, + { "REQI", 0x02, 0x02 }, + { "BSYI", 0x04, 0x04 }, + { "SELI", 0x08, 0x08 }, + { "ATNI", 0x10, 0x10 }, + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "P_DATAOUT", 0x00, 0x00 }, + { "P_DATAOUT_DT", 0x20, 0x20 }, + { "P_DATAIN", 0x40, 0x40 }, + { "P_DATAIN_DT", 0x60, 0x60 }, + { "P_COMMAND", 0x80, 0x80 }, + { "P_MESGOUT", 0xa0, 0xa0 }, + { "P_STATUS", 0xc0, 0xc0 }, + { "PHASE_MASK", 0xe0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 } +}; + +int +ahc_scsisigi_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISIGI_parse_table, 17, "SCSISIGI", + 0x03, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIRATE_parse_table[] = { + { "SINGLE_EDGE", 0x10, 0x10 }, + { "ENABLE_CRC", 0x40, 0x40 }, + { "WIDEXFER", 0x80, 0x80 }, + { "SXFR_ULTRA2", 0x0f, 0x0f }, + { "SOFS", 0x0f, 0x0f }, + { "SXFR", 0x70, 0x70 } +}; + +int +ahc_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIRATE_parse_table, 6, "SCSIRATE", + 0x04, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIID_parse_table[] = { + { "TWIN_CHNLB", 0x80, 0x80 }, + { "OID", 0x0f, 0x0f }, + { "TWIN_TID", 0x70, 0x70 }, + { "SOFS_ULTRA2", 0x7f, 0x7f }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahc_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIID_parse_table, 5, "SCSIID", + 0x05, regvalue, cur_col, wrap)); +} + +int +ahc_scsidatl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIDATL", + 0x06, regvalue, cur_col, wrap)); +} + +int +ahc_scsidath_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIDATH", + 0x07, regvalue, cur_col, wrap)); +} + +int +ahc_stcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "STCNT", + 0x08, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t OPTIONMODE_parse_table[] = { + { "DIS_MSGIN_DUALEDGE", 0x01, 0x01 }, + { "AUTO_MSGOUT_DE", 0x02, 0x02 }, + { "SCSIDATL_IMGEN", 0x04, 0x04 }, + { "EXPPHASEDIS", 0x08, 0x08 }, + { "BUSFREEREV", 0x10, 0x10 }, + { "ATNMGMNTEN", 0x20, 0x20 }, + { "AUTOACKEN", 0x40, 0x40 }, + { "AUTORATEEN", 0x80, 0x80 }, + { "OPTIONMODE_DEFAULTS",0x03, 0x03 } +}; + +int +ahc_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(OPTIONMODE_parse_table, 9, "OPTIONMODE", + 0x08, regvalue, cur_col, wrap)); +} + +int +ahc_targcrccnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TARGCRCCNT", + 0x0a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CLRSINT0_parse_table[] = { + { "CLRSPIORDY", 0x02, 0x02 }, + { "CLRSWRAP", 0x08, 0x08 }, + { "CLRIOERR", 0x08, 0x08 }, + { "CLRSELINGO", 0x10, 0x10 }, + { "CLRSELDI", 0x20, 0x20 }, + { "CLRSELDO", 0x40, 0x40 } +}; + +int +ahc_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CLRSINT0_parse_table, 6, "CLRSINT0", + 0x0b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT0_parse_table[] = { + { "DMADONE", 0x01, 0x01 }, + { "SPIORDY", 0x02, 0x02 }, + { "SDONE", 0x04, 0x04 }, + { "SWRAP", 0x08, 0x08 }, + { "IOERR", 0x08, 0x08 }, + { "SELINGO", 0x10, 0x10 }, + { "SELDI", 0x20, 0x20 }, + { "SELDO", 0x40, 0x40 }, + { "TARGET", 0x80, 0x80 } +}; + +int +ahc_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT0_parse_table, 9, "SSTAT0", + 0x0b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CLRSINT1_parse_table[] = { + { "CLRREQINIT", 0x01, 0x01 }, + { "CLRPHASECHG", 0x02, 0x02 }, + { "CLRSCSIPERR", 0x04, 0x04 }, + { "CLRBUSFREE", 0x08, 0x08 }, + { "CLRSCSIRSTI", 0x20, 0x20 }, + { "CLRATNO", 0x40, 0x40 }, + { "CLRSELTIMEO", 0x80, 0x80 } +}; + +int +ahc_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CLRSINT1_parse_table, 7, "CLRSINT1", + 0x0c, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT1_parse_table[] = { + { "REQINIT", 0x01, 0x01 }, + { "PHASECHG", 0x02, 0x02 }, + { "SCSIPERR", 0x04, 0x04 }, + { "BUSFREE", 0x08, 0x08 }, + { "PHASEMIS", 0x10, 0x10 }, + { "SCSIRSTI", 0x20, 0x20 }, + { "ATNTARG", 0x40, 0x40 }, + { "SELTO", 0x80, 0x80 } +}; + +int +ahc_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT1_parse_table, 8, "SSTAT1", + 0x0c, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT2_parse_table[] = { + { "DUAL_EDGE_ERR", 0x01, 0x01 }, + { "CRCREQERR", 0x02, 0x02 }, + { "CRCENDERR", 0x04, 0x04 }, + { "CRCVALERR", 0x08, 0x08 }, + { "EXP_ACTIVE", 0x10, 0x10 }, + { "SHVALID", 0x40, 0x40 }, + { "OVERRUN", 0x80, 0x80 }, + { "SFCNT", 0x1f, 0x1f } +}; + +int +ahc_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT2_parse_table, 8, "SSTAT2", + 0x0d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SSTAT3_parse_table[] = { + { "OFFCNT", 0x0f, 0x0f }, + { "U2OFFCNT", 0x7f, 0x7f }, + { "SCSICNT", 0xf0, 0xf0 } +}; + +int +ahc_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SSTAT3_parse_table, 3, "SSTAT3", + 0x0e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIID_ULTRA2_parse_table[] = { + { "OID", 0x0f, 0x0f }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahc_scsiid_ultra2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIID_ULTRA2_parse_table, 2, "SCSIID_ULTRA2", + 0x0f, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SIMODE0_parse_table[] = { + { "ENDMADONE", 0x01, 0x01 }, + { "ENSPIORDY", 0x02, 0x02 }, + { "ENSDONE", 0x04, 0x04 }, + { "ENSWRAP", 0x08, 0x08 }, + { "ENIOERR", 0x08, 0x08 }, + { "ENSELINGO", 0x10, 0x10 }, + { "ENSELDI", 0x20, 0x20 }, + { "ENSELDO", 0x40, 0x40 } +}; + +int +ahc_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SIMODE0_parse_table, 8, "SIMODE0", + 0x10, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SIMODE1_parse_table[] = { + { "ENREQINIT", 0x01, 0x01 }, + { "ENPHASECHG", 0x02, 0x02 }, + { "ENSCSIPERR", 0x04, 0x04 }, + { "ENBUSFREE", 0x08, 0x08 }, + { "ENPHASEMIS", 0x10, 0x10 }, + { "ENSCSIRST", 0x20, 0x20 }, + { "ENATNTARG", 0x40, 0x40 }, + { "ENSELTIMO", 0x80, 0x80 } +}; + +int +ahc_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SIMODE1_parse_table, 8, "SIMODE1", + 0x11, regvalue, cur_col, wrap)); +} + +int +ahc_scsibusl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIBUSL", + 0x12, regvalue, cur_col, wrap)); +} + +int +ahc_scsibush_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCSIBUSH", + 0x13, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SXFRCTL2_parse_table[] = { + { "CMDDMAEN", 0x08, 0x08 }, + { "AUTORSTDIS", 0x10, 0x10 }, + { "ASYNC_SETUP", 0x07, 0x07 } +}; + +int +ahc_sxfrctl2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SXFRCTL2_parse_table, 3, "SXFRCTL2", + 0x13, regvalue, cur_col, wrap)); +} + +int +ahc_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SHADDR", + 0x14, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SELTIMER_parse_table[] = { + { "STAGE1", 0x01, 0x01 }, + { "STAGE2", 0x02, 0x02 }, + { "STAGE3", 0x04, 0x04 }, + { "STAGE4", 0x08, 0x08 }, + { "STAGE5", 0x10, 0x10 }, + { "STAGE6", 0x20, 0x20 } +}; + +int +ahc_seltimer_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SELTIMER_parse_table, 6, "SELTIMER", + 0x18, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SELID_parse_table[] = { + { "ONEBIT", 0x08, 0x08 }, + { "SELID_MASK", 0xf0, 0xf0 } +}; + +int +ahc_selid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SELID_parse_table, 2, "SELID", + 0x19, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCAMCTL_parse_table[] = { + { "DFLTTID", 0x10, 0x10 }, + { "ALTSTIM", 0x20, 0x20 }, + { "CLRSCAMSELID", 0x40, 0x40 }, + { "ENSCAMSELO", 0x80, 0x80 }, + { "SCAMLVL", 0x03, 0x03 } +}; + +int +ahc_scamctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCAMCTL_parse_table, 5, "SCAMCTL", + 0x1a, regvalue, cur_col, wrap)); +} + +int +ahc_targid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TARGID", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SPIOCAP_parse_table[] = { + { "SSPIOCPS", 0x01, 0x01 }, + { "ROM", 0x02, 0x02 }, + { "EEPROM", 0x04, 0x04 }, + { "SEEPROM", 0x08, 0x08 }, + { "EXT_BRDCTL", 0x10, 0x10 }, + { "SOFTCMDEN", 0x20, 0x20 }, + { "SOFT0", 0x40, 0x40 }, + { "SOFT1", 0x80, 0x80 } +}; + +int +ahc_spiocap_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SPIOCAP_parse_table, 8, "SPIOCAP", + 0x1b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BRDCTL_parse_table[] = { + { "BRDCTL0", 0x01, 0x01 }, + { "BRDSTB_ULTRA2", 0x01, 0x01 }, + { "BRDCTL1", 0x02, 0x02 }, + { "BRDRW_ULTRA2", 0x02, 0x02 }, + { "BRDRW", 0x04, 0x04 }, + { "BRDDAT2", 0x04, 0x04 }, + { "BRDCS", 0x08, 0x08 }, + { "BRDDAT3", 0x08, 0x08 }, + { "BRDSTB", 0x10, 0x10 }, + { "BRDDAT4", 0x10, 0x10 }, + { "BRDDAT5", 0x20, 0x20 }, + { "BRDDAT6", 0x40, 0x40 }, + { "BRDDAT7", 0x80, 0x80 } +}; + +int +ahc_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BRDCTL_parse_table, 13, "BRDCTL", + 0x1d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEECTL_parse_table[] = { + { "SEEDI", 0x01, 0x01 }, + { "SEEDO", 0x02, 0x02 }, + { "SEECK", 0x04, 0x04 }, + { "SEECS", 0x08, 0x08 }, + { "SEERDY", 0x10, 0x10 }, + { "SEEMS", 0x20, 0x20 }, + { "EXTARBREQ", 0x40, 0x40 }, + { "EXTARBACK", 0x80, 0x80 } +}; + +int +ahc_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEECTL_parse_table, 8, "SEECTL", + 0x1e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SBLKCTL_parse_table[] = { + { "XCVR", 0x01, 0x01 }, + { "SELWIDE", 0x02, 0x02 }, + { "ENAB20", 0x04, 0x04 }, + { "SELBUSB", 0x08, 0x08 }, + { "ENAB40", 0x08, 0x08 }, + { "AUTOFLUSHDIS", 0x20, 0x20 }, + { "DIAGLEDON", 0x40, 0x40 }, + { "DIAGLEDEN", 0x80, 0x80 } +}; + +int +ahc_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SBLKCTL_parse_table, 8, "SBLKCTL", + 0x1f, regvalue, cur_col, wrap)); +} + +int +ahc_busy_targets_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "BUSY_TARGETS", + 0x20, regvalue, cur_col, wrap)); +} + +int +ahc_ultra_enb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ULTRA_ENB", + 0x30, regvalue, cur_col, wrap)); +} + +int +ahc_disc_dsb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DISC_DSB", + 0x32, regvalue, cur_col, wrap)); +} + +int +ahc_cmdsize_table_tail_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CMDSIZE_TABLE_TAIL", + 0x34, regvalue, cur_col, wrap)); +} + +int +ahc_mwi_residual_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "MWI_RESIDUAL", + 0x38, regvalue, cur_col, wrap)); +} + +int +ahc_next_queued_scb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB", + 0x39, regvalue, cur_col, wrap)); +} + +int +ahc_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "MSG_OUT", + 0x3a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DMAPARAMS_parse_table[] = { + { "FIFORESET", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SDMAEN", 0x10, 0x10 }, + { "SDMAENACK", 0x10, 0x10 }, + { "SCSIEN", 0x20, 0x20 }, + { "WIDEODD", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahc_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS", + 0x3b, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQ_FLAGS_parse_table[] = { + { "NO_DISCONNECT", 0x01, 0x01 }, + { "SPHASE_PENDING", 0x02, 0x02 }, + { "DPHASE_PENDING", 0x04, 0x04 }, + { "CMDPHASE_PENDING", 0x08, 0x08 }, + { "TARG_CMD_PENDING", 0x10, 0x10 }, + { "DPHASE", 0x20, 0x20 }, + { "NO_CDB_SENT", 0x40, 0x40 }, + { "TARGET_CMD_IS_TAGGED",0x40, 0x40 }, + { "NOT_IDENTIFIED", 0x80, 0x80 } +}; + +int +ahc_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS", + 0x3c, regvalue, cur_col, wrap)); +} + +int +ahc_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SAVED_SCSIID", + 0x3d, regvalue, cur_col, wrap)); +} + +int +ahc_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SAVED_LUN", + 0x3e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t LASTPHASE_parse_table[] = { + { "MSGI", 0x20, 0x20 }, + { "IOI", 0x40, 0x40 }, + { "CDI", 0x80, 0x80 }, + { "P_DATAOUT", 0x00, 0x00 }, + { "P_BUSFREE", 0x01, 0x01 }, + { "P_DATAIN", 0x40, 0x40 }, + { "P_COMMAND", 0x80, 0x80 }, + { "P_MESGOUT", 0xa0, 0xa0 }, + { "P_STATUS", 0xc0, 0xc0 }, + { "PHASE_MASK", 0xe0, 0xe0 }, + { "P_MESGIN", 0xe0, 0xe0 } +}; + +int +ahc_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(LASTPHASE_parse_table, 11, "LASTPHASE", + 0x3f, regvalue, cur_col, wrap)); +} + +int +ahc_waiting_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "WAITING_SCBH", + 0x40, regvalue, cur_col, wrap)); +} + +int +ahc_disconnected_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DISCONNECTED_SCBH", + 0x41, regvalue, cur_col, wrap)); +} + +int +ahc_free_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "FREE_SCBH", + 0x42, regvalue, cur_col, wrap)); +} + +int +ahc_complete_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "COMPLETE_SCBH", + 0x43, regvalue, cur_col, wrap)); +} + +int +ahc_hscb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HSCB_ADDR", + 0x44, regvalue, cur_col, wrap)); +} + +int +ahc_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SHARED_DATA_ADDR", + 0x48, regvalue, cur_col, wrap)); +} + +int +ahc_kernel_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "KERNEL_QINPOS", + 0x4c, regvalue, cur_col, wrap)); +} + +int +ahc_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QINPOS", + 0x4d, regvalue, cur_col, wrap)); +} + +int +ahc_qoutpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QOUTPOS", + 0x4e, regvalue, cur_col, wrap)); +} + +int +ahc_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "KERNEL_TQINPOS", + 0x4f, regvalue, cur_col, wrap)); +} + +int +ahc_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TQINPOS", + 0x50, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t ARG_1_parse_table[] = { + { "CONT_TARG_SESSION", 0x02, 0x02 }, + { "CONT_MSG_LOOP", 0x04, 0x04 }, + { "EXIT_MSG_LOOP", 0x08, 0x08 }, + { "MSGOUT_PHASEMIS", 0x10, 0x10 }, + { "SEND_REJ", 0x20, 0x20 }, + { "SEND_SENSE", 0x40, 0x40 }, + { "SEND_MSG", 0x80, 0x80 } +}; + +int +ahc_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(ARG_1_parse_table, 7, "ARG_1", + 0x51, regvalue, cur_col, wrap)); +} + +int +ahc_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ARG_2", + 0x52, regvalue, cur_col, wrap)); +} + +int +ahc_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "LAST_MSG", + 0x53, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = { + { "ENAUTOATNP", 0x02, 0x02 }, + { "ENAUTOATNI", 0x04, 0x04 }, + { "ENAUTOATNO", 0x08, 0x08 }, + { "ENRSELI", 0x10, 0x10 }, + { "ENSELI", 0x20, 0x20 }, + { "ENSELO", 0x40, 0x40 } +}; + +int +ahc_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE", + 0x54, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HA_274_BIOSGLOBAL_parse_table[] = { + { "HA_274_EXTENDED_TRANS",0x01, 0x01 } +}; + +int +ahc_ha_274_biosglobal_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HA_274_BIOSGLOBAL_parse_table, 1, "HA_274_BIOSGLOBAL", + 0x56, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = { + { "SCB_DMA", 0x01, 0x01 }, + { "TARGET_MSG_PENDING", 0x02, 0x02 } +}; + +int +ahc_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2", + 0x57, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSICONF_parse_table[] = { + { "ENSPCHK", 0x20, 0x20 }, + { "RESET_SCSI", 0x40, 0x40 }, + { "TERM_ENB", 0x80, 0x80 }, + { "HSCSIID", 0x07, 0x07 }, + { "HWSCSIID", 0x0f, 0x0f } +}; + +int +ahc_scsiconf_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSICONF_parse_table, 5, "SCSICONF", + 0x5a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t INTDEF_parse_table[] = { + { "EDGE_TRIG", 0x80, 0x80 }, + { "VECTOR", 0x0f, 0x0f } +}; + +int +ahc_intdef_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(INTDEF_parse_table, 2, "INTDEF", + 0x5c, regvalue, cur_col, wrap)); +} + +int +ahc_hostconf_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HOSTCONF", + 0x5d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HA_274_BIOSCTRL_parse_table[] = { + { "CHANNEL_B_PRIMARY", 0x08, 0x08 }, + { "BIOSMODE", 0x30, 0x30 }, + { "BIOSDISABLED", 0x30, 0x30 } +}; + +int +ahc_ha_274_biosctrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HA_274_BIOSCTRL_parse_table, 3, "HA_274_BIOSCTRL", + 0x5f, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQCTL_parse_table[] = { + { "LOADRAM", 0x01, 0x01 }, + { "SEQRESET", 0x02, 0x02 }, + { "STEP", 0x04, 0x04 }, + { "BRKADRINTEN", 0x08, 0x08 }, + { "FASTMODE", 0x10, 0x10 }, + { "FAILDIS", 0x20, 0x20 }, + { "PAUSEDIS", 0x40, 0x40 }, + { "PERRORDIS", 0x80, 0x80 } +}; + +int +ahc_seqctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQCTL_parse_table, 8, "SEQCTL", + 0x60, regvalue, cur_col, wrap)); +} + +int +ahc_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SEQRAM", + 0x61, regvalue, cur_col, wrap)); +} + +int +ahc_seqaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SEQADDR0", + 0x62, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEQADDR1_parse_table[] = { + { "SEQADDR1_MASK", 0x01, 0x01 } +}; + +int +ahc_seqaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEQADDR1_parse_table, 1, "SEQADDR1", + 0x63, regvalue, cur_col, wrap)); +} + +int +ahc_accum_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ACCUM", + 0x64, regvalue, cur_col, wrap)); +} + +int +ahc_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SINDEX", + 0x65, regvalue, cur_col, wrap)); +} + +int +ahc_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DINDEX", + 0x66, regvalue, cur_col, wrap)); +} + +int +ahc_allones_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ALLONES", + 0x69, regvalue, cur_col, wrap)); +} + +int +ahc_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "ALLZEROS", + 0x6a, regvalue, cur_col, wrap)); +} + +int +ahc_none_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "NONE", + 0x6a, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t FLAGS_parse_table[] = { + { "CARRY", 0x01, 0x01 }, + { "ZERO", 0x02, 0x02 } +}; + +int +ahc_flags_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(FLAGS_parse_table, 2, "FLAGS", + 0x6b, regvalue, cur_col, wrap)); +} + +int +ahc_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SINDIR", + 0x6c, regvalue, cur_col, wrap)); +} + +int +ahc_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DINDIR", + 0x6d, regvalue, cur_col, wrap)); +} + +int +ahc_function1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "FUNCTION1", + 0x6e, regvalue, cur_col, wrap)); +} + +int +ahc_stack_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "STACK", + 0x6f, regvalue, cur_col, wrap)); +} + +int +ahc_targ_offset_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "TARG_OFFSET", + 0x70, regvalue, cur_col, wrap)); +} + +int +ahc_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SRAM_BASE", + 0x70, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BCTL_parse_table[] = { + { "ENABLE", 0x01, 0x01 }, + { "ACE", 0x08, 0x08 } +}; + +int +ahc_bctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BCTL_parse_table, 2, "BCTL", + 0x84, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DSCOMMAND0_parse_table[] = { + { "CIOPARCKEN", 0x01, 0x01 }, + { "USCBSIZE32", 0x02, 0x02 }, + { "RAMPS", 0x04, 0x04 }, + { "INTSCBRAMSEL", 0x08, 0x08 }, + { "EXTREQLCK", 0x10, 0x10 }, + { "MPARCKEN", 0x20, 0x20 }, + { "DPARCKEN", 0x40, 0x40 }, + { "CACHETHEN", 0x80, 0x80 } +}; + +int +ahc_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DSCOMMAND0_parse_table, 8, "DSCOMMAND0", + 0x84, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BUSTIME_parse_table[] = { + { "BON", 0x0f, 0x0f }, + { "BOFF", 0xf0, 0xf0 } +}; + +int +ahc_bustime_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BUSTIME_parse_table, 2, "BUSTIME", + 0x85, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DSCOMMAND1_parse_table[] = { + { "HADDLDSEL0", 0x01, 0x01 }, + { "HADDLDSEL1", 0x02, 0x02 }, + { "DSLATT", 0xfc, 0xfc } +}; + +int +ahc_dscommand1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DSCOMMAND1_parse_table, 3, "DSCOMMAND1", + 0x85, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t BUSSPD_parse_table[] = { + { "STBON", 0x07, 0x07 }, + { "STBOFF", 0x38, 0x38 }, + { "DFTHRSH_75", 0x80, 0x80 }, + { "DFTHRSH", 0xc0, 0xc0 }, + { "DFTHRSH_100", 0xc0, 0xc0 } +}; + +int +ahc_busspd_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(BUSSPD_parse_table, 5, "BUSSPD", + 0x86, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HS_MAILBOX_parse_table[] = { + { "SEQ_MAILBOX", 0x0f, 0x0f }, + { "HOST_TQINPOS", 0x80, 0x80 }, + { "HOST_MAILBOX", 0xf0, 0xf0 } +}; + +int +ahc_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HS_MAILBOX_parse_table, 3, "HS_MAILBOX", + 0x86, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DSPCISTATUS_parse_table[] = { + { "DFTHRSH_100", 0xc0, 0xc0 } +}; + +int +ahc_dspcistatus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DSPCISTATUS_parse_table, 1, "DSPCISTATUS", + 0x86, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t HCNTRL_parse_table[] = { + { "CHIPRST", 0x01, 0x01 }, + { "CHIPRSTACK", 0x01, 0x01 }, + { "INTEN", 0x02, 0x02 }, + { "PAUSE", 0x04, 0x04 }, + { "IRQMS", 0x08, 0x08 }, + { "SWINT", 0x10, 0x10 }, + { "POWRDN", 0x40, 0x40 } +}; + +int +ahc_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(HCNTRL_parse_table, 7, "HCNTRL", + 0x87, regvalue, cur_col, wrap)); +} + +int +ahc_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HADDR", + 0x88, regvalue, cur_col, wrap)); +} + +int +ahc_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HCNT", + 0x8c, regvalue, cur_col, wrap)); +} + +int +ahc_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCBPTR", + 0x90, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t INTSTAT_parse_table[] = { + { "SEQINT", 0x01, 0x01 }, + { "CMDCMPLT", 0x02, 0x02 }, + { "SCSIINT", 0x04, 0x04 }, + { "BRKADRINT", 0x08, 0x08 }, + { "BAD_PHASE", 0x01, 0x01 }, + { "INT_PEND", 0x0f, 0x0f }, + { "SEND_REJECT", 0x11, 0x11 }, + { "PROTO_VIOLATION", 0x21, 0x21 }, + { "NO_MATCH", 0x31, 0x31 }, + { "IGN_WIDE_RES", 0x41, 0x41 }, + { "PDATA_REINIT", 0x51, 0x51 }, + { "HOST_MSG_LOOP", 0x61, 0x61 }, + { "BAD_STATUS", 0x71, 0x71 }, + { "PERR_DETECTED", 0x81, 0x81 }, + { "DATA_OVERRUN", 0x91, 0x91 }, + { "MKMSG_FAILED", 0xa1, 0xa1 }, + { "MISSED_BUSFREE", 0xb1, 0xb1 }, + { "SCB_MISMATCH", 0xc1, 0xc1 }, + { "NO_FREE_SCB", 0xd1, 0xd1 }, + { "OUT_OF_RANGE", 0xe1, 0xe1 }, + { "SEQINT_MASK", 0xf1, 0xf1 } +}; + +int +ahc_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(INTSTAT_parse_table, 21, "INTSTAT", + 0x91, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CLRINT_parse_table[] = { + { "CLRSEQINT", 0x01, 0x01 }, + { "CLRCMDINT", 0x02, 0x02 }, + { "CLRSCSIINT", 0x04, 0x04 }, + { "CLRBRKADRINT", 0x08, 0x08 }, + { "CLRPARERR", 0x10, 0x10 } +}; + +int +ahc_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CLRINT_parse_table, 5, "CLRINT", + 0x92, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t ERROR_parse_table[] = { + { "ILLHADDR", 0x01, 0x01 }, + { "ILLSADDR", 0x02, 0x02 }, + { "ILLOPCODE", 0x04, 0x04 }, + { "SQPARERR", 0x08, 0x08 }, + { "DPARERR", 0x10, 0x10 }, + { "MPARERR", 0x20, 0x20 }, + { "PCIERRSTAT", 0x40, 0x40 }, + { "CIOPARERR", 0x80, 0x80 } +}; + +int +ahc_error_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(ERROR_parse_table, 8, "ERROR", + 0x92, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DFCNTRL_parse_table[] = { + { "FIFORESET", 0x01, 0x01 }, + { "FIFOFLUSH", 0x02, 0x02 }, + { "DIRECTION", 0x04, 0x04 }, + { "HDMAEN", 0x08, 0x08 }, + { "HDMAENACK", 0x08, 0x08 }, + { "SDMAEN", 0x10, 0x10 }, + { "SDMAENACK", 0x10, 0x10 }, + { "SCSIEN", 0x20, 0x20 }, + { "WIDEODD", 0x40, 0x40 }, + { "PRELOADEN", 0x80, 0x80 } +}; + +int +ahc_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DFCNTRL_parse_table, 10, "DFCNTRL", + 0x93, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DFSTATUS_parse_table[] = { + { "FIFOEMP", 0x01, 0x01 }, + { "FIFOFULL", 0x02, 0x02 }, + { "DFTHRESH", 0x04, 0x04 }, + { "HDONE", 0x08, 0x08 }, + { "MREQPEND", 0x10, 0x10 }, + { "FIFOQWDEMP", 0x20, 0x20 }, + { "DFCACHETH", 0x40, 0x40 }, + { "PRELOAD_AVAIL", 0x80, 0x80 } +}; + +int +ahc_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DFSTATUS_parse_table, 8, "DFSTATUS", + 0x94, regvalue, cur_col, wrap)); +} + +int +ahc_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DFWADDR", + 0x95, regvalue, cur_col, wrap)); +} + +int +ahc_dfraddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DFRADDR", + 0x97, regvalue, cur_col, wrap)); +} + +int +ahc_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "DFDAT", + 0x99, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCBCNT_parse_table[] = { + { "SCBAUTO", 0x80, 0x80 }, + { "SCBCNT_MASK", 0x1f, 0x1f } +}; + +int +ahc_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCBCNT_parse_table, 2, "SCBCNT", + 0x9a, regvalue, cur_col, wrap)); +} + +int +ahc_qinfifo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QINFIFO", + 0x9b, regvalue, cur_col, wrap)); +} + +int +ahc_qincnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QINCNT", + 0x9c, regvalue, cur_col, wrap)); +} + +int +ahc_qoutfifo_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QOUTFIFO", + 0x9d, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CRCCONTROL1_parse_table[] = { + { "TARGCRCCNTEN", 0x04, 0x04 }, + { "TARGCRCENDEN", 0x08, 0x08 }, + { "CRCREQCHKEN", 0x10, 0x10 }, + { "CRCENDCHKEN", 0x20, 0x20 }, + { "CRCVALCHKEN", 0x40, 0x40 }, + { "CRCONSEEN", 0x80, 0x80 } +}; + +int +ahc_crccontrol1_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CRCCONTROL1_parse_table, 6, "CRCCONTROL1", + 0x9d, regvalue, cur_col, wrap)); +} + +int +ahc_qoutcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "QOUTCNT", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCSIPHASE_parse_table[] = { + { "DATA_OUT_PHASE", 0x01, 0x01 }, + { "DATA_IN_PHASE", 0x02, 0x02 }, + { "MSG_OUT_PHASE", 0x04, 0x04 }, + { "MSG_IN_PHASE", 0x08, 0x08 }, + { "COMMAND_PHASE", 0x10, 0x10 }, + { "STATUS_PHASE", 0x20, 0x20 }, + { "DATA_PHASE_MASK", 0x03, 0x03 } +}; + +int +ahc_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE", + 0x9e, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SFUNCT_parse_table[] = { + { "ALT_MODE", 0x80, 0x80 } +}; + +int +ahc_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SFUNCT_parse_table, 1, "SFUNCT", + 0x9f, regvalue, cur_col, wrap)); +} + +int +ahc_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_BASE", + 0xa0, regvalue, cur_col, wrap)); +} + +int +ahc_scb_cdb_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_CDB_PTR", + 0xa0, regvalue, cur_col, wrap)); +} + +int +ahc_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", + 0xa4, regvalue, cur_col, wrap)); +} + +int +ahc_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_SCSI_STATUS", + 0xa8, regvalue, cur_col, wrap)); +} + +int +ahc_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TARGET_PHASES", + 0xa9, regvalue, cur_col, wrap)); +} + +int +ahc_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", + 0xaa, regvalue, cur_col, wrap)); +} + +int +ahc_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TARGET_ITAG", + 0xab, regvalue, cur_col, wrap)); +} + +int +ahc_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_DATAPTR", + 0xac, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_DATACNT_parse_table[] = { + { "SG_LAST_SEG", 0x80, 0x80 }, + { "SG_HIGH_ADDR_BITS", 0x7f, 0x7f } +}; + +int +ahc_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT", + 0xb0, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_SGPTR_parse_table[] = { + { "SG_LIST_NULL", 0x01, 0x01 }, + { "SG_FULL_RESID", 0x02, 0x02 }, + { "SG_RESID_VALID", 0x04, 0x04 } +}; + +int +ahc_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR", + 0xb4, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_CONTROL_parse_table[] = { + { "DISCONNECTED", 0x04, 0x04 }, + { "ULTRAENB", 0x08, 0x08 }, + { "MK_MESSAGE", 0x10, 0x10 }, + { "TAG_ENB", 0x20, 0x20 }, + { "DISCENB", 0x40, 0x40 }, + { "TARGET_SCB", 0x80, 0x80 }, + { "STATUS_RCVD", 0x80, 0x80 }, + { "SCB_TAG_TYPE", 0x03, 0x03 } +}; + +int +ahc_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_CONTROL_parse_table, 8, "SCB_CONTROL", + 0xb8, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_SCSIID_parse_table[] = { + { "TWIN_CHNLB", 0x80, 0x80 }, + { "OID", 0x0f, 0x0f }, + { "TWIN_TID", 0x70, 0x70 }, + { "TID", 0xf0, 0xf0 } +}; + +int +ahc_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_SCSIID_parse_table, 4, "SCB_SCSIID", + 0xb9, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SCB_LUN_parse_table[] = { + { "SCB_XFERLEN_ODD", 0x80, 0x80 }, + { "LID", 0x3f, 0x3f } +}; + +int +ahc_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SCB_LUN_parse_table, 2, "SCB_LUN", + 0xba, regvalue, cur_col, wrap)); +} + +int +ahc_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_TAG", + 0xbb, regvalue, cur_col, wrap)); +} + +int +ahc_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_CDB_LEN", + 0xbc, regvalue, cur_col, wrap)); +} + +int +ahc_scb_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_SCSIRATE", + 0xbd, regvalue, cur_col, wrap)); +} + +int +ahc_scb_scsioffset_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_SCSIOFFSET", + 0xbe, regvalue, cur_col, wrap)); +} + +int +ahc_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_NEXT", + 0xbf, regvalue, cur_col, wrap)); +} + +int +ahc_scb_64_spare_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_64_SPARE", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SEECTL_2840_parse_table[] = { + { "DO_2840", 0x01, 0x01 }, + { "CK_2840", 0x02, 0x02 }, + { "CS_2840", 0x04, 0x04 } +}; + +int +ahc_seectl_2840_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SEECTL_2840_parse_table, 3, "SEECTL_2840", + 0xc0, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t STATUS_2840_parse_table[] = { + { "DI_2840", 0x01, 0x01 }, + { "EEPROM_TF", 0x80, 0x80 }, + { "ADSEL", 0x1e, 0x1e }, + { "BIOS_SEL", 0x60, 0x60 } +}; + +int +ahc_status_2840_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(STATUS_2840_parse_table, 4, "STATUS_2840", + 0xc1, regvalue, cur_col, wrap)); +} + +int +ahc_scb_64_btt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCB_64_BTT", + 0xd0, regvalue, cur_col, wrap)); +} + +int +ahc_cchaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCHADDR", + 0xe0, regvalue, cur_col, wrap)); +} + +int +ahc_cchcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCHCNT", + 0xe8, regvalue, cur_col, wrap)); +} + +int +ahc_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSGRAM", + 0xe9, regvalue, cur_col, wrap)); +} + +int +ahc_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSGADDR", + 0xea, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CCSGCTL_parse_table[] = { + { "CCSGRESET", 0x01, 0x01 }, + { "SG_FETCH_NEEDED", 0x02, 0x02 }, + { "CCSGEN", 0x08, 0x08 }, + { "CCSGDONE", 0x80, 0x80 } +}; + +int +ahc_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CCSGCTL_parse_table, 4, "CCSGCTL", + 0xeb, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBRAM", + 0xec, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBADDR", + 0xed, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t CCSCBCTL_parse_table[] = { + { "CCSCBRESET", 0x01, 0x01 }, + { "CCSCBDIR", 0x04, 0x04 }, + { "CCSCBEN", 0x08, 0x08 }, + { "CCARREN", 0x10, 0x10 }, + { "ARRDONE", 0x40, 0x40 }, + { "CCSCBDONE", 0x80, 0x80 } +}; + +int +ahc_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL", + 0xee, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBCNT", + 0xef, regvalue, cur_col, wrap)); +} + +int +ahc_scbbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SCBBADDR", + 0xf0, regvalue, cur_col, wrap)); +} + +int +ahc_ccscbptr_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "CCSCBPTR", + 0xf1, regvalue, cur_col, wrap)); +} + +int +ahc_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "HNSCB_QOFF", + 0xf4, regvalue, cur_col, wrap)); +} + +int +ahc_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SNSCB_QOFF", + 0xf6, regvalue, cur_col, wrap)); +} + +int +ahc_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(NULL, 0, "SDSCB_QOFF", + 0xf8, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = { + { "SDSCB_ROLLOVER", 0x10, 0x10 }, + { "SNSCB_ROLLOVER", 0x20, 0x20 }, + { "SCB_AVAIL", 0x40, 0x40 }, + { "SCB_QSIZE_256", 0x06, 0x06 }, + { "SCB_QSIZE", 0x07, 0x07 } +}; + +int +ahc_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(QOFF_CTLSTA_parse_table, 5, "QOFF_CTLSTA", + 0xfa, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t DFF_THRSH_parse_table[] = { + { "RD_DFTHRSH_MIN", 0x00, 0x00 }, + { "WR_DFTHRSH_MIN", 0x00, 0x00 }, + { "RD_DFTHRSH_25", 0x01, 0x01 }, + { "RD_DFTHRSH_50", 0x02, 0x02 }, + { "RD_DFTHRSH_63", 0x03, 0x03 }, + { "RD_DFTHRSH_75", 0x04, 0x04 }, + { "RD_DFTHRSH_85", 0x05, 0x05 }, + { "RD_DFTHRSH_90", 0x06, 0x06 }, + { "RD_DFTHRSH", 0x07, 0x07 }, + { "RD_DFTHRSH_MAX", 0x07, 0x07 }, + { "WR_DFTHRSH_25", 0x10, 0x10 }, + { "WR_DFTHRSH_50", 0x20, 0x20 }, + { "WR_DFTHRSH_63", 0x30, 0x30 }, + { "WR_DFTHRSH_75", 0x40, 0x40 }, + { "WR_DFTHRSH_85", 0x50, 0x50 }, + { "WR_DFTHRSH_90", 0x60, 0x60 }, + { "WR_DFTHRSH", 0x70, 0x70 }, + { "WR_DFTHRSH_MAX", 0x70, 0x70 } +}; + +int +ahc_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH", + 0xfb, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = { + { "LAST_SEG_DONE", 0x01, 0x01 }, + { "LAST_SEG", 0x02, 0x02 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahc_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 3, "SG_CACHE_SHADOW", + 0xfc, regvalue, cur_col, wrap)); +} + +static ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = { + { "LAST_SEG_DONE", 0x01, 0x01 }, + { "LAST_SEG", 0x02, 0x02 }, + { "SG_ADDR_MASK", 0xf8, 0xf8 } +}; + +int +ahc_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahc_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE", + 0xfc, regvalue, cur_col, wrap)); +} + diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_seq.h linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_seq.h --- linux-2.4.21/drivers/scsi/aic7xxx/aic7xxx_seq.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aic7xxx_seq.h 2003-08-25 04:44:42.000000000 -0700 @@ -2,13 +2,13 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $ - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $ */ static uint8_t seqprog[] = { 0xb2, 0x00, 0x00, 0x08, 0xf7, 0x11, 0x22, 0x08, - 0x00, 0x65, 0xe4, 0x59, + 0x00, 0x65, 0xec, 0x59, 0xf7, 0x01, 0x02, 0x08, 0xff, 0x6a, 0x24, 0x08, 0x40, 0x00, 0x40, 0x68, @@ -21,15 +21,15 @@ 0x01, 0x4d, 0xc8, 0x30, 0x00, 0x4c, 0x12, 0x70, 0x01, 0x39, 0xa2, 0x30, - 0x00, 0x6a, 0xb6, 0x5e, + 0x00, 0x6a, 0xc0, 0x5e, 0x01, 0x51, 0x20, 0x31, 0x01, 0x57, 0xae, 0x00, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0x51, 0x08, 0x5e, + 0x00, 0x51, 0x12, 0x5e, 0x01, 0x51, 0xc8, 0x30, 0x00, 0x39, 0xc8, 0x60, 0x00, 0xbb, 0x30, 0x70, - 0xc1, 0x6a, 0xce, 0x5e, + 0xc1, 0x6a, 0xd8, 0x5e, 0x01, 0xbf, 0x72, 0x30, 0x01, 0x40, 0x7e, 0x31, 0x01, 0x90, 0x80, 0x30, @@ -42,17 +42,17 @@ 0x08, 0x6a, 0x18, 0x00, 0x08, 0x11, 0x22, 0x00, 0x60, 0x0b, 0x00, 0x78, - 0x40, 0x0b, 0xfc, 0x68, + 0x40, 0x0b, 0xfa, 0x68, 0x80, 0x0b, 0xb6, 0x78, 0x20, 0x6a, 0x16, 0x00, 0xa4, 0x6a, 0x06, 0x00, - 0x08, 0x3c, 0x78, 0x00, + 0x08, 0x6a, 0x78, 0x00, 0x01, 0x50, 0xc8, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xf2, 0x5d, + 0x48, 0x6a, 0xfc, 0x5d, 0x01, 0x6a, 0xdc, 0x01, 0x88, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xf2, 0x5d, + 0x48, 0x6a, 0xfc, 0x5d, 0x01, 0x6a, 0x26, 0x01, 0xf0, 0x19, 0x7a, 0x08, 0x0f, 0x18, 0xc8, 0x08, @@ -63,8 +63,8 @@ 0x80, 0x3d, 0x7a, 0x00, 0x01, 0x3d, 0xd8, 0x31, 0x01, 0x3d, 0x32, 0x31, - 0x10, 0x03, 0x48, 0x79, - 0x00, 0x65, 0xf4, 0x58, + 0x10, 0x03, 0x4e, 0x79, + 0x00, 0x65, 0xf2, 0x58, 0x80, 0x66, 0xae, 0x78, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, @@ -72,29 +72,29 @@ 0x40, 0x66, 0x82, 0x68, 0x01, 0x3c, 0x78, 0x00, 0x10, 0x03, 0x9e, 0x78, - 0x00, 0x65, 0xf4, 0x58, + 0x00, 0x65, 0xf2, 0x58, 0xe0, 0x66, 0xc8, 0x18, 0x00, 0x65, 0xaa, 0x50, 0xdd, 0x66, 0xc8, 0x18, 0x00, 0x65, 0xaa, 0x48, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, - 0x10, 0x03, 0x48, 0x79, - 0x00, 0x65, 0xf4, 0x58, + 0x10, 0x03, 0x4e, 0x79, + 0x00, 0x65, 0xf2, 0x58, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, 0x01, 0x66, 0xac, 0x30, 0x40, 0x3c, 0x78, 0x00, 0xff, 0x6a, 0xd8, 0x01, 0xff, 0x6a, 0x32, 0x01, - 0x90, 0x3c, 0x78, 0x00, - 0x02, 0x57, 0x3c, 0x69, - 0x10, 0x03, 0x3a, 0x69, - 0x00, 0x65, 0x1e, 0x41, + 0x10, 0x3c, 0x78, 0x00, + 0x02, 0x57, 0x40, 0x69, + 0x10, 0x03, 0x3e, 0x69, + 0x00, 0x65, 0x20, 0x41, 0x02, 0x57, 0xae, 0x00, 0x00, 0x65, 0x9e, 0x40, - 0x61, 0x6a, 0xce, 0x5e, - 0x08, 0x51, 0x1e, 0x71, + 0x61, 0x6a, 0xd8, 0x5e, + 0x08, 0x51, 0x20, 0x71, 0x02, 0x0b, 0xb2, 0x78, 0x00, 0x65, 0xae, 0x40, 0x1a, 0x01, 0x02, 0x00, @@ -105,8 +105,8 @@ 0x08, 0x1f, 0xc4, 0x78, 0x80, 0x3d, 0x7a, 0x00, 0x20, 0x6a, 0x16, 0x00, - 0x00, 0x65, 0xc4, 0x41, - 0x00, 0x65, 0xa8, 0x5e, + 0x00, 0x65, 0xcc, 0x41, + 0x00, 0x65, 0xb2, 0x5e, 0x00, 0x65, 0x12, 0x40, 0x20, 0x11, 0xd2, 0x68, 0x20, 0x6a, 0x18, 0x00, @@ -123,169 +123,169 @@ 0x80, 0x65, 0xca, 0x00, 0x01, 0x65, 0x00, 0x34, 0x01, 0x54, 0x00, 0x34, - 0x1a, 0x01, 0x02, 0x00, - 0x08, 0xb8, 0xf0, 0x78, + 0x08, 0xb8, 0xee, 0x78, 0x20, 0x01, 0x02, 0x00, 0x02, 0xbd, 0x08, 0x34, 0x01, 0xbd, 0x08, 0x34, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0xf6, 0x78, + 0x02, 0x0b, 0xf4, 0x78, 0xf7, 0x01, 0x02, 0x08, 0x01, 0x06, 0xcc, 0x34, 0xb2, 0x00, 0x00, 0x08, 0x01, 0x40, 0x20, 0x31, 0x01, 0xbf, 0x80, 0x30, 0x01, 0xb9, 0x7a, 0x30, - 0x01, 0xba, 0x7c, 0x30, + 0x3f, 0xba, 0x7c, 0x08, 0x00, 0x65, 0xea, 0x58, - 0x80, 0x0b, 0xbe, 0x79, - 0xe4, 0x6a, 0x64, 0x5d, + 0x80, 0x0b, 0xc4, 0x79, + 0x12, 0x01, 0x02, 0x00, + 0x01, 0xab, 0xac, 0x30, + 0xe4, 0x6a, 0x6e, 0x5d, 0x40, 0x6a, 0x16, 0x00, - 0x80, 0xba, 0x7a, 0x5d, - 0x20, 0xb8, 0x16, 0x79, - 0x20, 0x6a, 0x7a, 0x5d, - 0x00, 0xab, 0x7a, 0x5d, + 0x80, 0x3e, 0x84, 0x5d, + 0x20, 0xb8, 0x18, 0x79, + 0x20, 0x6a, 0x84, 0x5d, + 0x00, 0xab, 0x84, 0x5d, 0x01, 0xa9, 0x78, 0x30, - 0x10, 0xb8, 0x1e, 0x79, - 0xe4, 0x6a, 0x64, 0x5d, + 0x10, 0xb8, 0x20, 0x79, + 0xe4, 0x6a, 0x6e, 0x5d, 0x00, 0x65, 0xae, 0x40, - 0x10, 0x03, 0x38, 0x69, - 0x08, 0x3c, 0x54, 0x69, - 0x04, 0x3c, 0x8c, 0x69, - 0x02, 0x3c, 0x92, 0x69, - 0x01, 0x3c, 0x3e, 0x79, - 0x01, 0x6a, 0xa2, 0x30, - 0x00, 0x65, 0x9e, 0x59, - 0x04, 0x51, 0x2c, 0x61, - 0x00, 0x6a, 0xb6, 0x5e, + 0x10, 0x03, 0x3c, 0x69, + 0x08, 0x3c, 0x5a, 0x69, + 0x04, 0x3c, 0x92, 0x69, + 0x02, 0x3c, 0x98, 0x69, + 0x01, 0x3c, 0x44, 0x79, + 0xff, 0x6a, 0x70, 0x00, + 0x00, 0x65, 0xa4, 0x59, + 0x00, 0x6a, 0xc0, 0x5e, + 0xff, 0x38, 0x30, 0x71, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x08, 0x5e, - 0x00, 0x65, 0xec, 0x58, - 0x00, 0x65, 0x16, 0x41, + 0x00, 0x38, 0x12, 0x5e, + 0x00, 0x65, 0xea, 0x58, + 0x12, 0x01, 0x02, 0x00, + 0x00, 0x65, 0x18, 0x41, 0xa4, 0x6a, 0x06, 0x00, - 0x00, 0x65, 0xf4, 0x58, + 0x00, 0x65, 0xf2, 0x58, + 0xfd, 0x57, 0xae, 0x08, 0x00, 0x65, 0xae, 0x40, - 0xe4, 0x6a, 0x64, 0x5d, - 0x20, 0x3c, 0x44, 0x79, - 0x02, 0x6a, 0x7a, 0x5d, - 0x04, 0x6a, 0x7a, 0x5d, - 0x01, 0x03, 0x46, 0x69, + 0xe4, 0x6a, 0x6e, 0x5d, + 0x20, 0x3c, 0x4a, 0x79, + 0x02, 0x6a, 0x84, 0x5d, + 0x04, 0x6a, 0x84, 0x5d, + 0x01, 0x03, 0x4c, 0x69, 0xf7, 0x11, 0x22, 0x08, 0xff, 0x6a, 0x24, 0x08, 0xff, 0x6a, 0x06, 0x08, 0x01, 0x6a, 0x7e, 0x00, - 0x00, 0x65, 0x9e, 0x59, + 0x00, 0x65, 0xa4, 0x59, 0x00, 0x65, 0x04, 0x40, 0x80, 0x86, 0xc8, 0x08, 0x01, 0x4f, 0xc8, 0x30, - 0x00, 0x50, 0x66, 0x61, - 0xc4, 0x6a, 0x64, 0x5d, - 0x40, 0x3c, 0x62, 0x79, - 0x28, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x46, 0x41, - 0x08, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x46, 0x41, - 0x84, 0x6a, 0x64, 0x5d, - 0x00, 0x65, 0xf4, 0x58, + 0x00, 0x50, 0x6c, 0x61, + 0xc4, 0x6a, 0x6e, 0x5d, + 0x40, 0x3c, 0x68, 0x79, + 0x28, 0x6a, 0x84, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x08, 0x6a, 0x84, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x84, 0x6a, 0x6e, 0x5d, + 0x00, 0x65, 0xf2, 0x58, 0x01, 0x66, 0xc8, 0x30, 0x01, 0x64, 0xd8, 0x31, 0x01, 0x64, 0x32, 0x31, 0x5b, 0x64, 0xc8, 0x28, 0x30, 0x64, 0xca, 0x18, 0x01, 0x6c, 0xc8, 0x30, - 0xff, 0x64, 0x88, 0x79, + 0xff, 0x64, 0x8e, 0x79, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0x7a, 0x79, - 0x01, 0x64, 0x80, 0x61, + 0x02, 0x0b, 0x80, 0x79, + 0x01, 0x64, 0x86, 0x61, 0xf7, 0x01, 0x02, 0x08, 0x01, 0x06, 0xd8, 0x31, 0x01, 0x06, 0x32, 0x31, 0xff, 0x64, 0xc8, 0x18, - 0xff, 0x64, 0x7a, 0x69, + 0xff, 0x64, 0x80, 0x69, 0xf7, 0x3c, 0x78, 0x08, - 0x00, 0x65, 0x1e, 0x41, + 0x00, 0x65, 0x20, 0x41, 0x40, 0xaa, 0x7e, 0x10, - 0x04, 0xaa, 0x64, 0x5d, + 0x04, 0xaa, 0x6e, 0x5d, 0x00, 0x65, 0x56, 0x42, - 0xc4, 0x6a, 0x64, 0x5d, + 0xc4, 0x6a, 0x6e, 0x5d, 0xc0, 0x6a, 0x7e, 0x00, - 0x00, 0xa8, 0x7a, 0x5d, + 0x00, 0xa8, 0x84, 0x5d, 0xe4, 0x6a, 0x06, 0x00, - 0x00, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x46, 0x41, - 0x10, 0x3c, 0xa2, 0x69, - 0x00, 0xbb, 0x84, 0x44, + 0x00, 0x6a, 0x84, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x10, 0x3c, 0xa8, 0x69, + 0x00, 0xbb, 0x8a, 0x44, 0x18, 0x6a, 0xda, 0x01, 0x01, 0x69, 0xd8, 0x31, 0x1c, 0x6a, 0xd0, 0x01, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0xaa, 0x79, + 0x80, 0xee, 0xb0, 0x79, 0xff, 0x6a, 0xdc, 0x09, 0x01, 0x93, 0x26, 0x01, 0x03, 0x6a, 0x2a, 0x01, 0x01, 0x69, 0x32, 0x31, - 0x1c, 0x6a, 0xd6, 0x5d, + 0x1c, 0x6a, 0xe0, 0x5d, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x5e, + 0x00, 0x65, 0xa8, 0x5e, 0x01, 0x50, 0xa0, 0x18, 0x02, 0x6a, 0x22, 0x05, + 0x1a, 0x01, 0x02, 0x00, 0x80, 0x6a, 0x74, 0x00, - 0x80, 0x3c, 0x78, 0x00, + 0x40, 0x6a, 0x78, 0x00, 0x40, 0x6a, 0x16, 0x00, - 0x00, 0x65, 0xce, 0x5d, + 0x00, 0x65, 0xd8, 0x5d, 0x01, 0x3f, 0xc8, 0x30, 0xbf, 0x64, 0x56, 0x7a, - 0x80, 0x64, 0xaa, 0x73, - 0xa0, 0x64, 0x08, 0x74, - 0xc0, 0x64, 0xfc, 0x73, - 0xe0, 0x64, 0x38, 0x74, - 0x01, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0xc4, 0x41, + 0x80, 0x64, 0x9e, 0x73, + 0xa0, 0x64, 0x00, 0x74, + 0xc0, 0x64, 0xf4, 0x73, + 0xe0, 0x64, 0x30, 0x74, + 0x01, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0xf7, 0x11, 0x22, 0x08, 0x01, 0x06, 0xd4, 0x30, 0xff, 0x6a, 0x24, 0x08, 0xf7, 0x01, 0x02, 0x08, - 0x09, 0x0c, 0xde, 0x79, + 0x09, 0x0c, 0xe6, 0x79, 0x08, 0x0c, 0x04, 0x68, - 0xb1, 0x6a, 0xce, 0x5e, + 0xb1, 0x6a, 0xd8, 0x5e, 0xff, 0x6a, 0x26, 0x09, 0x12, 0x01, 0x02, 0x00, 0x02, 0x6a, 0x08, 0x30, 0xff, 0x6a, 0x08, 0x08, 0xdf, 0x01, 0x02, 0x08, 0x01, 0x6a, 0x7e, 0x00, - 0xff, 0x6a, 0x78, 0x0c, + 0xc0, 0x6a, 0x78, 0x04, 0xff, 0x6a, 0xc8, 0x08, 0x08, 0xa4, 0x48, 0x19, 0x00, 0xa5, 0x4a, 0x21, 0x00, 0xa6, 0x4c, 0x21, 0x00, 0xa7, 0x4e, 0x25, - 0x08, 0xeb, 0xd2, 0x7e, - 0x80, 0xeb, 0xfe, 0x79, + 0x08, 0xeb, 0xdc, 0x7e, + 0x80, 0xeb, 0x06, 0x7a, 0xff, 0x6a, 0xd6, 0x09, - 0x08, 0xeb, 0x02, 0x6a, + 0x08, 0xeb, 0x0a, 0x6a, 0xff, 0x6a, 0xd4, 0x0c, - 0x80, 0xa3, 0xd2, 0x6e, - 0x88, 0xeb, 0x18, 0x72, - 0x08, 0xeb, 0xd2, 0x6e, - 0x04, 0xea, 0x1c, 0xe2, - 0x08, 0xee, 0xd2, 0x6e, + 0x80, 0xa3, 0xdc, 0x6e, + 0x88, 0xeb, 0x20, 0x72, + 0x08, 0xeb, 0xdc, 0x6e, + 0x04, 0xea, 0x24, 0xe2, + 0x08, 0xee, 0xdc, 0x6e, 0x04, 0x6a, 0xd0, 0x81, 0x05, 0xa4, 0xc0, 0x89, 0x03, 0xa5, 0xc2, 0x31, 0x09, 0x6a, 0xd6, 0x05, - 0x00, 0x65, 0x00, 0x5a, + 0x00, 0x65, 0x08, 0x5a, 0x06, 0xa4, 0xd4, 0x89, - 0x80, 0x94, 0xd2, 0x7e, + 0x80, 0x94, 0xdc, 0x7e, 0x07, 0xe9, 0x10, 0x31, - 0x01, 0x8c, 0x24, 0x7a, - 0x01, 0x55, 0xaa, 0x10, 0x01, 0xe9, 0x46, 0x31, - 0x00, 0xa3, 0xb0, 0x5e, - 0x00, 0x65, 0xf2, 0x59, + 0x00, 0xa3, 0xba, 0x5e, + 0x00, 0x65, 0xfa, 0x59, 0x01, 0xa4, 0xca, 0x30, - 0x01, 0x55, 0x30, 0x7a, - 0x04, 0x65, 0xca, 0x00, 0x80, 0xa3, 0x34, 0x7a, 0x02, 0x65, 0xca, 0x00, 0x01, 0x65, 0xf8, 0x31, @@ -294,168 +294,162 @@ 0x01, 0x8c, 0xc8, 0x30, 0x00, 0x88, 0xc8, 0x18, 0x02, 0x64, 0xc8, 0x88, - 0xff, 0x64, 0xd2, 0x7e, + 0xff, 0x64, 0xdc, 0x7e, 0xff, 0x8d, 0x4a, 0x6a, 0xff, 0x8e, 0x4a, 0x6a, 0x03, 0x8c, 0xd4, 0x98, - 0x00, 0x65, 0xd2, 0x56, + 0x00, 0x65, 0xdc, 0x56, 0x01, 0x64, 0x70, 0x30, 0xff, 0x64, 0xc8, 0x10, 0x01, 0x64, 0xc8, 0x18, 0x00, 0x8c, 0x18, 0x19, 0xff, 0x8d, 0x1a, 0x21, 0xff, 0x8e, 0x1c, 0x25, - 0x80, 0x3c, 0x5a, 0x6a, - 0x21, 0x6a, 0xce, 0x46, + 0xc0, 0x3c, 0x5a, 0x7a, + 0x21, 0x6a, 0xd8, 0x5e, 0xa8, 0x6a, 0x76, 0x00, 0x79, 0x6a, 0x76, 0x00, 0x40, 0x3f, 0x62, 0x6a, 0x04, 0x3b, 0x76, 0x00, 0x04, 0x6a, 0xd4, 0x81, 0x20, 0x3c, 0x6a, 0x7a, - 0x51, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x84, 0x42, + 0x51, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0x82, 0x42, 0x20, 0x3c, 0x78, 0x00, - 0x00, 0xb3, 0xb0, 0x5e, + 0x00, 0xb3, 0xba, 0x5e, 0x07, 0xac, 0x10, 0x31, 0x05, 0xb3, 0x46, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0xac, 0x6a, 0xe4, 0x5d, + 0xac, 0x6a, 0xee, 0x5d, 0xa3, 0x6a, 0xcc, 0x00, - 0xb3, 0x6a, 0xe8, 0x5d, + 0xb3, 0x6a, 0xf2, 0x5d, 0x00, 0x65, 0x3a, 0x5a, 0xfd, 0xa4, 0x48, 0x09, - 0x01, 0x8c, 0xaa, 0x08, 0x03, 0x8c, 0x10, 0x30, - 0x00, 0x65, 0xdc, 0x5d, - 0x01, 0xa4, 0x96, 0x7a, + 0x00, 0x65, 0xe6, 0x5d, + 0x01, 0xa4, 0x94, 0x7a, 0x04, 0x3b, 0x76, 0x08, 0x01, 0x3b, 0x26, 0x31, 0x80, 0x02, 0x04, 0x00, - 0x10, 0x0c, 0x8c, 0x7a, - 0x03, 0x9e, 0x8e, 0x6a, + 0x10, 0x0c, 0x8a, 0x7a, + 0x03, 0x9e, 0x8c, 0x6a, 0x7f, 0x02, 0x04, 0x08, - 0x91, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0xc4, 0x41, + 0x91, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0x01, 0xa4, 0xca, 0x30, - 0x80, 0xa3, 0x9c, 0x7a, + 0x80, 0xa3, 0x9a, 0x7a, 0x02, 0x65, 0xca, 0x00, - 0x01, 0x55, 0xa0, 0x7a, - 0x04, 0x65, 0xca, 0x00, 0x01, 0x65, 0xf8, 0x31, 0x01, 0x3b, 0x26, 0x31, - 0x00, 0x65, 0x06, 0x5a, - 0x01, 0xfc, 0xae, 0x6a, - 0x80, 0x0b, 0xa4, 0x6a, - 0x10, 0x0c, 0xa4, 0x7a, - 0x20, 0x93, 0xa4, 0x6a, + 0x00, 0x65, 0x0e, 0x5a, + 0x01, 0xfc, 0xa8, 0x6a, + 0x80, 0x0b, 0x9e, 0x6a, + 0x10, 0x0c, 0x9e, 0x7a, + 0x20, 0x93, 0x9e, 0x6a, 0x02, 0x93, 0x26, 0x01, - 0x02, 0xfc, 0xb8, 0x7a, - 0x40, 0x0d, 0xd2, 0x6a, + 0x02, 0xfc, 0xb2, 0x7a, + 0x40, 0x0d, 0xc6, 0x6a, 0x01, 0xa4, 0x48, 0x01, - 0x00, 0x65, 0xd2, 0x42, - 0x40, 0x0d, 0xbe, 0x6a, - 0x00, 0x65, 0x06, 0x5a, - 0x00, 0x65, 0xb0, 0x42, - 0x80, 0xfc, 0xc8, 0x7a, - 0x80, 0xa4, 0xc8, 0x6a, + 0x00, 0x65, 0xc6, 0x42, + 0x40, 0x0d, 0xb8, 0x6a, + 0x00, 0x65, 0x0e, 0x5a, + 0x00, 0x65, 0xaa, 0x42, + 0x80, 0xfc, 0xc2, 0x7a, + 0x80, 0xa4, 0xc2, 0x6a, 0xff, 0xa5, 0x4a, 0x19, 0xff, 0xa6, 0x4c, 0x21, 0xff, 0xa7, 0x4e, 0x21, 0xf8, 0xfc, 0x48, 0x09, - 0xff, 0x6a, 0xaa, 0x08, - 0x04, 0xfc, 0xd0, 0x7a, - 0x01, 0x55, 0xaa, 0x00, - 0xff, 0x6a, 0x46, 0x09, - 0x04, 0x3b, 0xea, 0x6a, + 0x7f, 0xa3, 0x46, 0x09, + 0x04, 0x3b, 0xe2, 0x6a, 0x02, 0x93, 0x26, 0x01, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0x94, 0xd4, 0x7a, - 0x01, 0xa4, 0xe8, 0x7a, - 0x01, 0xfc, 0xe2, 0x7a, - 0x01, 0x94, 0xea, 0x6a, - 0x00, 0x65, 0x84, 0x42, - 0x01, 0x94, 0xe8, 0x7a, - 0x10, 0x94, 0xea, 0x6a, + 0x01, 0x94, 0xc8, 0x7a, + 0x01, 0x94, 0xc8, 0x7a, + 0x01, 0x94, 0xc8, 0x7a, + 0x01, 0x94, 0xc8, 0x7a, + 0x01, 0x94, 0xc8, 0x7a, + 0x01, 0xa4, 0xe0, 0x7a, + 0x01, 0xfc, 0xd6, 0x7a, + 0x01, 0x94, 0xe2, 0x6a, + 0x01, 0x94, 0xe2, 0x6a, + 0x01, 0x94, 0xe2, 0x6a, + 0x00, 0x65, 0x82, 0x42, + 0x01, 0x94, 0xe0, 0x7a, + 0x10, 0x94, 0xe2, 0x6a, 0xd7, 0x93, 0x26, 0x09, - 0x28, 0x93, 0xee, 0x6a, + 0x28, 0x93, 0xe6, 0x6a, 0x01, 0x85, 0x0a, 0x01, - 0x02, 0xfc, 0xf6, 0x6a, + 0x02, 0xfc, 0xee, 0x6a, 0x01, 0x14, 0x46, 0x31, 0xff, 0x6a, 0x10, 0x09, 0xfe, 0x85, 0x0a, 0x09, - 0xff, 0x38, 0x04, 0x6b, - 0x80, 0xa3, 0x04, 0x7b, - 0x80, 0x0b, 0x02, 0x7b, - 0x04, 0x3b, 0x04, 0x7b, + 0xff, 0x38, 0xfc, 0x6a, + 0x80, 0xa3, 0xfc, 0x7a, + 0x80, 0x0b, 0xfa, 0x7a, + 0x04, 0x3b, 0xfc, 0x7a, 0xbf, 0x3b, 0x76, 0x08, 0x01, 0x3b, 0x26, 0x31, - 0x00, 0x65, 0x06, 0x5a, - 0x01, 0x0b, 0x12, 0x6b, - 0x10, 0x0c, 0x06, 0x7b, - 0x04, 0x93, 0x10, 0x6b, - 0x01, 0x94, 0x0e, 0x7b, - 0x10, 0x94, 0x10, 0x6b, + 0x00, 0x65, 0x0e, 0x5a, + 0x01, 0x0b, 0x0a, 0x6b, + 0x10, 0x0c, 0xfe, 0x7a, + 0x04, 0x93, 0x08, 0x6b, + 0x01, 0x94, 0x06, 0x7b, + 0x10, 0x94, 0x08, 0x6b, 0xc7, 0x93, 0x26, 0x09, 0x01, 0x99, 0xd4, 0x30, - 0x38, 0x93, 0x14, 0x6b, - 0xff, 0x08, 0x66, 0x6b, - 0xff, 0x09, 0x66, 0x6b, - 0xff, 0x0a, 0x66, 0x6b, - 0xff, 0x38, 0x30, 0x7b, + 0x38, 0x93, 0x0c, 0x6b, + 0xff, 0x08, 0x5a, 0x6b, + 0xff, 0x09, 0x5a, 0x6b, + 0xff, 0x0a, 0x5a, 0x6b, + 0xff, 0x38, 0x28, 0x7b, 0x04, 0x14, 0x10, 0x31, 0x01, 0x38, 0x18, 0x31, 0x02, 0x6a, 0x1a, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0x14, 0x6a, 0xea, 0x5d, - 0x00, 0x38, 0xd6, 0x5d, + 0x14, 0x6a, 0xf4, 0x5d, + 0x00, 0x38, 0xe0, 0x5d, 0xff, 0x6a, 0x70, 0x08, - 0x00, 0x65, 0x5c, 0x43, - 0x80, 0xa3, 0x36, 0x7b, + 0x00, 0x65, 0x54, 0x43, + 0x80, 0xa3, 0x2e, 0x7b, 0x01, 0xa4, 0x48, 0x01, - 0x00, 0x65, 0x66, 0x43, - 0x08, 0xeb, 0x3c, 0x7b, - 0x00, 0x65, 0x06, 0x5a, - 0x08, 0xeb, 0x38, 0x6b, + 0x00, 0x65, 0x5a, 0x43, + 0x08, 0xeb, 0x34, 0x7b, + 0x00, 0x65, 0x0e, 0x5a, + 0x08, 0xeb, 0x30, 0x6b, 0x07, 0xe9, 0x10, 0x31, 0x01, 0xe9, 0xca, 0x30, 0x01, 0x65, 0x46, 0x31, - 0x00, 0x6a, 0xb0, 0x5e, + 0x00, 0x6a, 0xba, 0x5e, 0x88, 0x6a, 0xcc, 0x00, - 0xa4, 0x6a, 0xea, 0x5d, - 0x08, 0x6a, 0xd6, 0x5d, + 0xa4, 0x6a, 0xf4, 0x5d, + 0x08, 0x6a, 0xe0, 0x5d, 0x0d, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x5e, + 0x00, 0x65, 0xa8, 0x5e, 0x88, 0x6a, 0xcc, 0x00, - 0x00, 0x65, 0x80, 0x5e, + 0x00, 0x65, 0x8a, 0x5e, 0x01, 0x99, 0x46, 0x31, - 0x00, 0xa3, 0xb0, 0x5e, + 0x00, 0xa3, 0xba, 0x5e, 0x01, 0x88, 0x10, 0x31, 0x00, 0x65, 0x3a, 0x5a, - 0x00, 0x65, 0xf2, 0x59, + 0x00, 0x65, 0xfa, 0x59, 0x03, 0x8c, 0x10, 0x30, - 0x00, 0x65, 0xdc, 0x5d, - 0x01, 0x8c, 0x64, 0x7b, - 0x01, 0x55, 0xaa, 0x10, - 0x80, 0x0b, 0x84, 0x6a, - 0x80, 0x0b, 0x6e, 0x6b, - 0x01, 0x0c, 0x68, 0x7b, - 0x10, 0x0c, 0x84, 0x7a, - 0x03, 0x9e, 0x84, 0x6a, - 0x00, 0x65, 0xfc, 0x59, - 0x00, 0x6a, 0xb0, 0x5e, - 0x01, 0xa4, 0x8e, 0x6b, - 0xff, 0x38, 0x84, 0x7b, + 0x00, 0x65, 0xe6, 0x5d, + 0x80, 0x0b, 0x82, 0x6a, + 0x80, 0x0b, 0x62, 0x6b, + 0x01, 0x0c, 0x5c, 0x7b, + 0x10, 0x0c, 0x82, 0x7a, + 0x03, 0x9e, 0x82, 0x6a, + 0x00, 0x65, 0x04, 0x5a, + 0x00, 0x6a, 0xba, 0x5e, + 0x01, 0xa4, 0x82, 0x6b, + 0xff, 0x38, 0x78, 0x7b, 0x01, 0x38, 0xc8, 0x30, 0x00, 0x08, 0x40, 0x19, 0xff, 0x6a, 0xc8, 0x08, 0x00, 0x09, 0x42, 0x21, 0x00, 0x0a, 0x44, 0x21, 0xff, 0x6a, 0x70, 0x08, - 0x00, 0x65, 0x86, 0x43, + 0x00, 0x65, 0x7a, 0x43, 0x03, 0x08, 0x40, 0x31, 0x03, 0x08, 0x40, 0x31, 0x01, 0x08, 0x40, 0x31, @@ -464,19 +458,19 @@ 0xfd, 0xb4, 0x68, 0x09, 0x12, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, - 0x04, 0x3c, 0xc4, 0x79, + 0x04, 0x3c, 0xcc, 0x79, 0xfb, 0x3c, 0x78, 0x08, - 0x04, 0x93, 0x1e, 0x79, - 0x01, 0x0c, 0x9a, 0x6b, - 0x01, 0x55, 0x1e, 0x79, - 0x80, 0x04, 0x1e, 0x79, - 0xe4, 0x6a, 0x64, 0x5d, - 0x23, 0x6a, 0x7a, 0x5d, - 0x01, 0x6a, 0x7a, 0x5d, - 0x00, 0x65, 0x1e, 0x41, - 0x00, 0x65, 0xc4, 0x41, - 0x80, 0x3c, 0xae, 0x6b, - 0x21, 0x6a, 0xce, 0x46, + 0x04, 0x93, 0x20, 0x79, + 0x01, 0x0c, 0x8e, 0x6b, + 0x80, 0xba, 0x20, 0x79, + 0x80, 0x04, 0x20, 0x79, + 0xe4, 0x6a, 0x6e, 0x5d, + 0x23, 0x6a, 0x84, 0x5d, + 0x01, 0x6a, 0x84, 0x5d, + 0x00, 0x65, 0x20, 0x41, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0x3c, 0xa2, 0x7b, + 0x21, 0x6a, 0xd8, 0x5e, 0x01, 0xbc, 0x18, 0x31, 0x02, 0x6a, 0x1a, 0x31, 0x02, 0x6a, 0xf8, 0x01, @@ -486,16 +480,16 @@ 0xff, 0x6a, 0x12, 0x08, 0xff, 0x6a, 0x14, 0x08, 0xf3, 0xbc, 0xd4, 0x18, - 0xa0, 0x6a, 0xd4, 0x53, + 0xa0, 0x6a, 0xc8, 0x53, 0x04, 0xa0, 0x10, 0x31, 0xac, 0x6a, 0x26, 0x01, 0x04, 0xa0, 0x10, 0x31, 0x03, 0x08, 0x18, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0xa0, 0x6a, 0xea, 0x5d, - 0x00, 0xbc, 0xd6, 0x5d, + 0xa0, 0x6a, 0xf4, 0x5d, + 0x00, 0xbc, 0xe0, 0x5d, 0x3d, 0x6a, 0x26, 0x01, - 0x00, 0x65, 0xec, 0x43, + 0x00, 0x65, 0xe0, 0x43, 0xff, 0x6a, 0x10, 0x09, 0xa4, 0x6a, 0x26, 0x01, 0x0c, 0xa0, 0x32, 0x31, @@ -505,117 +499,128 @@ 0x36, 0x6a, 0x26, 0x01, 0x02, 0x93, 0x26, 0x01, 0x35, 0x6a, 0x26, 0x01, - 0x00, 0x65, 0x92, 0x5e, - 0x00, 0x65, 0x92, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, 0x02, 0x93, 0x26, 0x01, - 0x04, 0x0b, 0xf0, 0x6b, - 0x10, 0x0c, 0xec, 0x7b, - 0x01, 0x03, 0xf0, 0x6b, - 0x20, 0x93, 0xec, 0x6b, + 0xbf, 0x3c, 0x78, 0x08, + 0x04, 0x0b, 0xe6, 0x6b, + 0x10, 0x0c, 0xe2, 0x7b, + 0x01, 0x03, 0xe6, 0x6b, + 0x20, 0x93, 0xe8, 0x6b, + 0x04, 0x0b, 0xee, 0x6b, + 0x40, 0x3c, 0x78, 0x00, 0xc7, 0x93, 0x26, 0x09, - 0x38, 0x93, 0xf6, 0x6b, - 0x10, 0x01, 0x02, 0x00, - 0x00, 0x65, 0xc4, 0x41, - 0x80, 0x3c, 0x00, 0x6c, - 0x21, 0x6a, 0xce, 0x46, + 0x38, 0x93, 0xf0, 0x6b, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0x3c, 0x56, 0x6c, 0x01, 0x06, 0x50, 0x31, - 0x00, 0x65, 0xc4, 0x41, + 0x80, 0xb8, 0x70, 0x01, + 0x00, 0x65, 0xcc, 0x41, 0x10, 0x3f, 0x06, 0x00, 0x10, 0x6a, 0x06, 0x00, 0x01, 0x3a, 0xca, 0x30, - 0x80, 0x65, 0x24, 0x64, - 0x10, 0xb8, 0x48, 0x6c, - 0xc0, 0xba, 0xca, 0x00, - 0x40, 0xb8, 0x14, 0x6c, + 0x80, 0x65, 0x1c, 0x64, + 0x10, 0xb8, 0x40, 0x6c, + 0xc0, 0x3e, 0xca, 0x00, + 0x40, 0xb8, 0x0c, 0x6c, 0xbf, 0x65, 0xca, 0x08, - 0x20, 0xb8, 0x28, 0x7c, + 0x20, 0xb8, 0x20, 0x7c, 0x01, 0x65, 0x0c, 0x30, - 0x00, 0x65, 0xce, 0x5d, - 0xa0, 0x3f, 0x30, 0x64, + 0x00, 0x65, 0xd8, 0x5d, + 0xa0, 0x3f, 0x28, 0x64, 0x23, 0xb8, 0x0c, 0x08, - 0x00, 0x65, 0xce, 0x5d, - 0xa0, 0x3f, 0x30, 0x64, - 0x00, 0xbb, 0x28, 0x44, - 0xff, 0x65, 0x28, 0x64, - 0x00, 0x65, 0x48, 0x44, + 0x00, 0x65, 0xd8, 0x5d, + 0xa0, 0x3f, 0x28, 0x64, + 0x00, 0xbb, 0x20, 0x44, + 0xff, 0x65, 0x20, 0x64, + 0x00, 0x65, 0x40, 0x44, 0x40, 0x6a, 0x18, 0x00, 0x01, 0x65, 0x0c, 0x30, - 0x00, 0x65, 0xce, 0x5d, - 0xa0, 0x3f, 0x04, 0x74, + 0x00, 0x65, 0xd8, 0x5d, + 0xa0, 0x3f, 0xfc, 0x73, 0x40, 0x6a, 0x18, 0x00, 0x01, 0x3a, 0xa6, 0x30, 0x08, 0x6a, 0x74, 0x00, - 0x00, 0x65, 0xc4, 0x41, - 0x64, 0x6a, 0x5e, 0x5d, - 0x80, 0x64, 0xce, 0x6c, - 0x04, 0x64, 0x94, 0x74, - 0x02, 0x64, 0xa2, 0x74, - 0x00, 0x6a, 0x64, 0x74, - 0x03, 0x64, 0xc0, 0x74, - 0x23, 0x64, 0x50, 0x74, - 0x08, 0x64, 0x60, 0x74, - 0x61, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0xce, 0x5d, - 0x08, 0x51, 0xc6, 0x71, - 0x00, 0x65, 0x48, 0x44, - 0x80, 0x04, 0x5e, 0x7c, - 0x51, 0x6a, 0x54, 0x5d, - 0x01, 0x51, 0x5e, 0x64, - 0x01, 0xa4, 0x5a, 0x7c, - 0x01, 0x55, 0x60, 0x7c, - 0x41, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x60, 0x44, - 0x07, 0x6a, 0x4a, 0x5d, + 0x00, 0x65, 0xcc, 0x41, + 0x64, 0x6a, 0x68, 0x5d, + 0x80, 0x64, 0xd8, 0x6c, + 0x04, 0x64, 0x9a, 0x74, + 0x02, 0x64, 0xaa, 0x74, + 0x00, 0x6a, 0x60, 0x74, + 0x03, 0x64, 0xc8, 0x74, + 0x23, 0x64, 0x48, 0x74, + 0x08, 0x64, 0x5c, 0x74, + 0x61, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0xd8, 0x5d, + 0x08, 0x51, 0xce, 0x71, + 0x00, 0x65, 0x40, 0x44, + 0x80, 0x04, 0x5a, 0x7c, + 0x51, 0x6a, 0x5e, 0x5d, + 0x01, 0x51, 0x5a, 0x64, + 0x01, 0xa4, 0x52, 0x7c, + 0x80, 0xba, 0x5c, 0x6c, + 0x41, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0x5c, 0x44, + 0x21, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0x5c, 0x44, + 0x07, 0x6a, 0x54, 0x5d, 0x01, 0x06, 0xd4, 0x30, - 0x00, 0x65, 0xc4, 0x41, - 0x10, 0xb8, 0x68, 0x7c, - 0xa1, 0x6a, 0xce, 0x5e, - 0x01, 0xb4, 0x6e, 0x6c, - 0x02, 0xb4, 0x70, 0x6c, - 0x01, 0xa4, 0x70, 0x7c, - 0xff, 0xa8, 0x80, 0x7c, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0xb8, 0x56, 0x7c, + 0xc0, 0x3c, 0x6a, 0x7c, + 0x80, 0x3c, 0x56, 0x6c, + 0xff, 0xa8, 0x6a, 0x6c, + 0x40, 0x3c, 0x56, 0x6c, + 0x10, 0xb8, 0x6e, 0x7c, + 0xa1, 0x6a, 0xd8, 0x5e, + 0x01, 0xb4, 0x74, 0x6c, + 0x02, 0xb4, 0x76, 0x6c, + 0x01, 0xa4, 0x76, 0x7c, + 0xff, 0xa8, 0x86, 0x7c, 0x04, 0xb4, 0x68, 0x01, 0x01, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x08, 0x5e, - 0xff, 0xa8, 0x80, 0x7c, - 0x71, 0x6a, 0xce, 0x5e, - 0x40, 0x51, 0x80, 0x64, - 0x00, 0x65, 0xa8, 0x5e, - 0x00, 0x65, 0xd6, 0x41, - 0x00, 0xbb, 0x84, 0x5c, - 0x00, 0x65, 0xd6, 0x41, - 0x00, 0x65, 0xa8, 0x5e, + 0x00, 0xbb, 0x12, 0x5e, + 0xff, 0xa8, 0x86, 0x7c, + 0x71, 0x6a, 0xd8, 0x5e, + 0x40, 0x51, 0x86, 0x64, + 0x00, 0x65, 0xb2, 0x5e, + 0x00, 0x65, 0xde, 0x41, + 0x00, 0xbb, 0x8a, 0x5c, + 0x00, 0x65, 0xde, 0x41, + 0x00, 0x65, 0xb2, 0x5e, 0x01, 0x65, 0xa2, 0x30, 0x01, 0xf8, 0xc8, 0x30, 0x01, 0x4e, 0xc8, 0x30, - 0x00, 0x6a, 0xac, 0xdd, - 0x00, 0x51, 0xbe, 0x5d, + 0x00, 0x6a, 0xb6, 0xdd, + 0x00, 0x51, 0xc8, 0x5d, 0x01, 0x4e, 0x9c, 0x18, 0x02, 0x6a, 0x22, 0x05, + 0xc0, 0x3c, 0x56, 0x6c, 0x04, 0xb8, 0x70, 0x01, - 0x00, 0x65, 0xca, 0x5e, - 0x20, 0xb8, 0xd6, 0x69, + 0x00, 0x65, 0xd4, 0x5e, + 0x20, 0xb8, 0xde, 0x69, 0x01, 0xbb, 0xa2, 0x30, - 0x01, 0xba, 0x7c, 0x30, - 0x00, 0xb9, 0xc4, 0x5c, - 0x00, 0x65, 0xd6, 0x41, + 0x3f, 0xba, 0x7c, 0x08, + 0x00, 0xb9, 0xce, 0x5c, + 0x00, 0x65, 0xde, 0x41, 0x01, 0x06, 0xd4, 0x30, - 0x20, 0x3c, 0xc4, 0x79, - 0x20, 0x3c, 0x60, 0x7c, - 0x01, 0xa4, 0xb0, 0x7c, + 0x20, 0x3c, 0xcc, 0x79, + 0x20, 0x3c, 0x5c, 0x7c, + 0x01, 0xa4, 0xb8, 0x7c, 0x01, 0xb4, 0x68, 0x01, - 0x00, 0x65, 0xc4, 0x41, - 0x00, 0x65, 0x60, 0x44, + 0x00, 0x65, 0xcc, 0x41, + 0x00, 0x65, 0x5c, 0x44, 0x04, 0x14, 0x58, 0x31, 0x01, 0x06, 0xd4, 0x30, 0x08, 0xa0, 0x60, 0x31, 0xac, 0x6a, 0xcc, 0x00, - 0x14, 0x6a, 0xea, 0x5d, + 0x14, 0x6a, 0xf4, 0x5d, 0x01, 0x06, 0xd4, 0x30, - 0xa0, 0x6a, 0xe2, 0x5d, - 0x00, 0x65, 0xc4, 0x41, + 0xa0, 0x6a, 0xec, 0x5d, + 0x00, 0x65, 0xcc, 0x41, 0xdf, 0x3c, 0x78, 0x08, - 0x00, 0x65, 0x60, 0x44, + 0x12, 0x01, 0x02, 0x00, + 0x00, 0x65, 0x5c, 0x44, 0x4c, 0x65, 0xcc, 0x28, 0x01, 0x3e, 0x20, 0x31, 0xd0, 0x66, 0xcc, 0x18, @@ -626,102 +631,102 @@ 0xd0, 0x65, 0xca, 0x18, 0x01, 0x3e, 0x20, 0x31, 0x30, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xdc, 0x4c, + 0x00, 0x65, 0xe6, 0x4c, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x20, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xe4, 0x54, + 0x00, 0x65, 0xee, 0x54, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x20, 0x65, 0xca, 0x18, 0xe0, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xee, 0x4c, + 0x00, 0x65, 0xf8, 0x4c, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0xd0, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xf6, 0x54, + 0x00, 0x65, 0x00, 0x55, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x01, 0x6c, 0xa2, 0x30, - 0xff, 0x51, 0x08, 0x75, - 0x00, 0x51, 0x84, 0x5d, + 0xff, 0x51, 0x12, 0x75, + 0x00, 0x51, 0x8e, 0x5d, 0x01, 0x51, 0x20, 0x31, - 0x00, 0x65, 0x2a, 0x45, - 0x01, 0xba, 0xc8, 0x30, - 0x00, 0x3e, 0x2a, 0x75, - 0x00, 0x65, 0xa6, 0x5e, + 0x00, 0x65, 0x34, 0x45, + 0x3f, 0xba, 0xc8, 0x08, + 0x00, 0x3e, 0x34, 0x75, + 0x00, 0x65, 0xb0, 0x5e, 0x80, 0x3c, 0x78, 0x00, 0x01, 0x06, 0xd4, 0x30, - 0x00, 0x65, 0xce, 0x5d, + 0x00, 0x65, 0xd8, 0x5d, 0x01, 0x3c, 0x78, 0x00, - 0xe0, 0x3f, 0x46, 0x65, + 0xe0, 0x3f, 0x50, 0x65, 0x02, 0x3c, 0x78, 0x00, - 0x20, 0x12, 0x46, 0x65, - 0x51, 0x6a, 0x54, 0x5d, - 0x00, 0x51, 0x84, 0x5d, - 0x51, 0x6a, 0x54, 0x5d, + 0x20, 0x12, 0x50, 0x65, + 0x51, 0x6a, 0x5e, 0x5d, + 0x00, 0x51, 0x8e, 0x5d, + 0x51, 0x6a, 0x5e, 0x5d, 0x01, 0x51, 0x20, 0x31, 0x04, 0x3c, 0x78, 0x00, 0x01, 0xb9, 0xc8, 0x30, - 0x00, 0x3d, 0x44, 0x65, + 0x00, 0x3d, 0x4e, 0x65, 0x08, 0x3c, 0x78, 0x00, - 0x01, 0xba, 0xc8, 0x30, - 0x00, 0x3e, 0x44, 0x65, + 0x3f, 0xba, 0xc8, 0x08, + 0x00, 0x3e, 0x4e, 0x65, 0x10, 0x3c, 0x78, 0x00, - 0x04, 0xb8, 0x44, 0x7d, + 0x04, 0xb8, 0x4e, 0x7d, 0xfb, 0xb8, 0x70, 0x09, - 0x20, 0xb8, 0x3a, 0x6d, + 0x20, 0xb8, 0x44, 0x6d, 0x01, 0x90, 0xc8, 0x30, 0xff, 0x6a, 0xa2, 0x00, - 0x00, 0x3d, 0xc4, 0x5c, + 0x00, 0x3d, 0xce, 0x5c, 0x01, 0x64, 0x20, 0x31, - 0x80, 0x6a, 0x78, 0x00, - 0x00, 0x65, 0xec, 0x58, - 0x10, 0xb8, 0x60, 0x7c, - 0xff, 0x6a, 0x4a, 0x5d, - 0x00, 0x65, 0x60, 0x44, - 0x00, 0x65, 0xa6, 0x5e, - 0x31, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x60, 0x44, + 0xff, 0x6a, 0x78, 0x08, + 0x00, 0x65, 0xea, 0x58, + 0x10, 0xb8, 0x5c, 0x7c, + 0xff, 0x6a, 0x54, 0x5d, + 0x00, 0x65, 0x5c, 0x44, + 0x00, 0x65, 0xb0, 0x5e, + 0x31, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0x5c, 0x44, 0x10, 0x3f, 0x06, 0x00, 0x10, 0x6a, 0x06, 0x00, 0x01, 0x65, 0x74, 0x34, - 0x81, 0x6a, 0xce, 0x5e, - 0x00, 0x65, 0x56, 0x45, + 0x81, 0x6a, 0xd8, 0x5e, + 0x00, 0x65, 0x60, 0x45, 0x01, 0x06, 0xd4, 0x30, - 0x01, 0x0c, 0x56, 0x7d, - 0x04, 0x0c, 0x50, 0x6d, + 0x01, 0x0c, 0x60, 0x7d, + 0x04, 0x0c, 0x5a, 0x6d, 0xe0, 0x03, 0x7e, 0x08, - 0xe0, 0x3f, 0xc4, 0x61, + 0xe0, 0x3f, 0xcc, 0x61, 0x01, 0x65, 0xcc, 0x30, 0x01, 0x12, 0xda, 0x34, 0x01, 0x06, 0xd4, 0x34, - 0x01, 0x03, 0x64, 0x6d, + 0x01, 0x03, 0x6e, 0x6d, 0x40, 0x03, 0xcc, 0x08, 0x01, 0x65, 0x06, 0x30, 0x40, 0x65, 0xc8, 0x08, - 0x00, 0x66, 0x72, 0x75, - 0x40, 0x65, 0x72, 0x7d, - 0x00, 0x65, 0x72, 0x5d, + 0x00, 0x66, 0x7c, 0x75, + 0x40, 0x65, 0x7c, 0x7d, + 0x00, 0x65, 0x7c, 0x5d, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x0c, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0x7c, 0x7d, + 0x02, 0x0b, 0x86, 0x7d, 0x01, 0x65, 0x0c, 0x30, - 0x02, 0x0b, 0x80, 0x7d, + 0x02, 0x0b, 0x8a, 0x7d, 0xf7, 0x01, 0x02, 0x0c, 0x01, 0x65, 0xc8, 0x30, - 0xff, 0x41, 0xa4, 0x75, + 0xff, 0x41, 0xae, 0x75, 0x01, 0x41, 0x20, 0x31, 0xff, 0x6a, 0xa4, 0x00, - 0x00, 0x65, 0x94, 0x45, - 0xff, 0xbf, 0xa4, 0x75, + 0x00, 0x65, 0x9e, 0x45, + 0xff, 0xbf, 0xae, 0x75, 0x01, 0x90, 0xa4, 0x30, 0x01, 0xbf, 0x20, 0x31, - 0x00, 0xbb, 0x8e, 0x65, - 0xff, 0x52, 0xa2, 0x75, + 0x00, 0xbb, 0x98, 0x65, + 0xff, 0x52, 0xac, 0x75, 0x01, 0xbf, 0xcc, 0x30, 0x01, 0x90, 0xca, 0x30, 0x01, 0x52, 0x20, 0x31, @@ -729,28 +734,28 @@ 0x01, 0x65, 0x20, 0x35, 0x01, 0xbf, 0x82, 0x34, 0x01, 0x64, 0xa2, 0x30, - 0x00, 0x6a, 0xb6, 0x5e, + 0x00, 0x6a, 0xc0, 0x5e, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0x51, 0x08, 0x46, + 0x00, 0x51, 0x12, 0x46, 0x01, 0x65, 0xa4, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xfc, 0x5d, + 0x48, 0x6a, 0x06, 0x5e, 0x01, 0x6a, 0xd0, 0x01, 0x01, 0x6a, 0xdc, 0x05, 0x88, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0xfc, 0x5d, - 0x01, 0x6a, 0xd6, 0x5d, + 0x48, 0x6a, 0x06, 0x5e, + 0x01, 0x6a, 0xe0, 0x5d, 0x01, 0x6a, 0x26, 0x05, 0x01, 0x65, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0xc2, 0x7d, + 0x80, 0xee, 0xcc, 0x7d, 0xff, 0x6a, 0xdc, 0x0d, 0x01, 0x65, 0x32, 0x31, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x46, - 0x81, 0x6a, 0xce, 0x5e, - 0x01, 0x0c, 0xce, 0x7d, - 0x04, 0x0c, 0xcc, 0x6d, + 0x00, 0x65, 0xa8, 0x46, + 0x81, 0x6a, 0xd8, 0x5e, + 0x01, 0x0c, 0xd8, 0x7d, + 0x04, 0x0c, 0xd6, 0x6d, 0xe0, 0x03, 0x06, 0x08, 0xe0, 0x03, 0x7e, 0x0c, 0x01, 0x65, 0x18, 0x31, @@ -769,7 +774,7 @@ 0x01, 0x6c, 0xda, 0x34, 0x3d, 0x64, 0xa4, 0x28, 0x55, 0x64, 0xc8, 0x28, - 0x00, 0x65, 0xfc, 0x45, + 0x00, 0x65, 0x06, 0x46, 0x2e, 0x64, 0xa4, 0x28, 0x66, 0x64, 0xc8, 0x28, 0x00, 0x6c, 0xda, 0x18, @@ -780,63 +785,63 @@ 0x00, 0x6c, 0xda, 0x24, 0x01, 0x65, 0xc8, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x44, 0x6a, 0xf8, 0x5d, + 0x44, 0x6a, 0x02, 0x5e, 0x01, 0x90, 0xe2, 0x31, - 0x04, 0x3b, 0x1c, 0x7e, + 0x04, 0x3b, 0x26, 0x7e, 0x30, 0x6a, 0xd0, 0x01, 0x20, 0x6a, 0xd0, 0x01, 0x1d, 0x6a, 0xdc, 0x01, - 0xdc, 0xee, 0x18, 0x66, - 0x00, 0x65, 0x34, 0x46, + 0xdc, 0xee, 0x22, 0x66, + 0x00, 0x65, 0x3e, 0x46, 0x20, 0x6a, 0xd0, 0x01, 0x01, 0x6a, 0xdc, 0x01, 0x20, 0xa0, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0x24, 0x7e, + 0x80, 0xee, 0x2e, 0x7e, 0x11, 0x6a, 0xdc, 0x01, - 0x50, 0xee, 0x28, 0x66, + 0x50, 0xee, 0x32, 0x66, 0x20, 0x6a, 0xd0, 0x01, 0x09, 0x6a, 0xdc, 0x01, - 0x88, 0xee, 0x2e, 0x66, + 0x88, 0xee, 0x38, 0x66, 0x19, 0x6a, 0xdc, 0x01, - 0xd8, 0xee, 0x32, 0x66, + 0xd8, 0xee, 0x3c, 0x66, 0xff, 0x6a, 0xdc, 0x09, - 0x18, 0xee, 0x36, 0x6e, + 0x18, 0xee, 0x40, 0x6e, 0xff, 0x6a, 0xd4, 0x0c, 0x88, 0x6a, 0xcc, 0x00, - 0x44, 0x6a, 0xf8, 0x5d, - 0x20, 0x6a, 0xd6, 0x5d, + 0x44, 0x6a, 0x02, 0x5e, + 0x20, 0x6a, 0xe0, 0x5d, 0x01, 0x3b, 0x26, 0x31, - 0x04, 0x3b, 0x50, 0x6e, + 0x04, 0x3b, 0x5a, 0x6e, 0xa0, 0x6a, 0xca, 0x00, 0x20, 0x65, 0xc8, 0x18, - 0x00, 0x65, 0x8e, 0x5e, - 0x00, 0x65, 0x48, 0x66, + 0x00, 0x65, 0x98, 0x5e, + 0x00, 0x65, 0x52, 0x66, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0x9e, 0x46, + 0x00, 0x65, 0xa8, 0x46, 0xa0, 0x6a, 0xcc, 0x00, 0xff, 0x6a, 0xc8, 0x08, - 0x20, 0x94, 0x54, 0x6e, - 0x10, 0x94, 0x56, 0x6e, - 0x08, 0x94, 0x70, 0x6e, - 0x08, 0x94, 0x70, 0x6e, - 0x08, 0x94, 0x70, 0x6e, + 0x20, 0x94, 0x5e, 0x6e, + 0x10, 0x94, 0x60, 0x6e, + 0x08, 0x94, 0x7a, 0x6e, + 0x08, 0x94, 0x7a, 0x6e, + 0x08, 0x94, 0x7a, 0x6e, 0xff, 0x8c, 0xc8, 0x10, 0xc1, 0x64, 0xc8, 0x18, 0xf8, 0x64, 0xc8, 0x08, 0x01, 0x99, 0xda, 0x30, - 0x00, 0x66, 0x64, 0x66, - 0xc0, 0x66, 0xa0, 0x76, + 0x00, 0x66, 0x6e, 0x66, + 0xc0, 0x66, 0xaa, 0x76, 0x60, 0x66, 0xc8, 0x18, 0x3d, 0x64, 0xc8, 0x28, - 0x00, 0x65, 0x54, 0x46, + 0x00, 0x65, 0x5e, 0x46, 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0x72, 0x6e, + 0x08, 0x93, 0x7c, 0x6e, 0x00, 0x62, 0xc4, 0x18, - 0x00, 0x65, 0x9e, 0x5e, - 0x00, 0x65, 0x7e, 0x5e, - 0x00, 0x65, 0x7e, 0x5e, - 0x00, 0x65, 0x7e, 0x5e, + 0x00, 0x65, 0xa8, 0x5e, + 0x00, 0x65, 0x88, 0x5e, + 0x00, 0x65, 0x88, 0x5e, + 0x00, 0x65, 0x88, 0x5e, 0x01, 0x99, 0xda, 0x30, 0x01, 0x99, 0xda, 0x30, 0x01, 0x99, 0xda, 0x30, @@ -853,11 +858,11 @@ 0x01, 0x6c, 0x32, 0x31, 0x01, 0x6c, 0x32, 0x31, 0x01, 0x6c, 0x32, 0x35, - 0x08, 0x94, 0x9e, 0x7e, + 0x08, 0x94, 0xa8, 0x7e, 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0xa2, 0x6e, + 0x08, 0x93, 0xac, 0x6e, 0xff, 0x6a, 0xd4, 0x0c, - 0x04, 0xb8, 0xca, 0x6e, + 0x04, 0xb8, 0xd4, 0x6e, 0x01, 0x42, 0x7e, 0x31, 0xff, 0x6a, 0x76, 0x01, 0x01, 0x90, 0x84, 0x34, @@ -865,14 +870,14 @@ 0x01, 0x85, 0x0a, 0x01, 0x7f, 0x65, 0x10, 0x09, 0xfe, 0x85, 0x0a, 0x0d, - 0xff, 0x42, 0xc6, 0x66, - 0xff, 0x41, 0xbe, 0x66, - 0xd1, 0x6a, 0xce, 0x5e, + 0xff, 0x42, 0xd0, 0x66, + 0xff, 0x41, 0xc8, 0x66, + 0xd1, 0x6a, 0xd8, 0x5e, 0xff, 0x6a, 0xca, 0x04, 0x01, 0x41, 0x20, 0x31, 0x01, 0xbf, 0x82, 0x30, 0x01, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x08, 0x46, + 0x00, 0xbb, 0x12, 0x46, 0x01, 0x42, 0x20, 0x31, 0x01, 0xbf, 0x84, 0x34, 0x01, 0x41, 0x7e, 0x31, @@ -882,420 +887,421 @@ 0xff, 0x6a, 0xd4, 0x0c }; -static int aic_patch23_func(struct ahc_softc *ahc); +typedef int ahc_patch_func_t (struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch23_func; static int -aic_patch23_func(struct ahc_softc *ahc) +ahc_patch23_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_SCBCHAN_UPLOAD_BUG) != 0); } -static int aic_patch22_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch22_func; static int -aic_patch22_func(struct ahc_softc *ahc) +ahc_patch22_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_CMD_CHAN) == 0); } -static int aic_patch21_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch21_func; static int -aic_patch21_func(struct ahc_softc *ahc) +ahc_patch21_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_QUEUE_REGS) == 0); } -static int aic_patch20_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch20_func; static int -aic_patch20_func(struct ahc_softc *ahc) +ahc_patch20_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_WIDE) != 0); } -static int aic_patch19_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch19_func; static int -aic_patch19_func(struct ahc_softc *ahc) +ahc_patch19_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_SCB_BTT) != 0); } -static int aic_patch18_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch18_func; static int -aic_patch18_func(struct ahc_softc *ahc) +ahc_patch18_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0); } -static int aic_patch17_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch17_func; static int -aic_patch17_func(struct ahc_softc *ahc) +ahc_patch17_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0); } -static int aic_patch16_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch16_func; static int -aic_patch16_func(struct ahc_softc *ahc) +ahc_patch16_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0); } -static int aic_patch15_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch15_func; static int -aic_patch15_func(struct ahc_softc *ahc) +ahc_patch15_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_ULTRA2) == 0); } -static int aic_patch14_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch14_func; static int -aic_patch14_func(struct ahc_softc *ahc) +ahc_patch14_func(struct ahc_softc *ahc) { return ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0); } -static int aic_patch13_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch13_func; static int -aic_patch13_func(struct ahc_softc *ahc) +ahc_patch13_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_39BIT_ADDRESSING) != 0); } -static int aic_patch12_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch12_func; static int -aic_patch12_func(struct ahc_softc *ahc) +ahc_patch12_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_HS_MAILBOX) != 0); } -static int aic_patch11_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch11_func; static int -aic_patch11_func(struct ahc_softc *ahc) +ahc_patch11_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_ULTRA) != 0); } -static int aic_patch10_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch10_func; static int -aic_patch10_func(struct ahc_softc *ahc) +ahc_patch10_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_MULTI_TID) != 0); } -static int aic_patch9_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch9_func; static int -aic_patch9_func(struct ahc_softc *ahc) +ahc_patch9_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_CMD_CHAN) != 0); } -static int aic_patch8_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch8_func; static int -aic_patch8_func(struct ahc_softc *ahc) +ahc_patch8_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_INITIATORROLE) != 0); } -static int aic_patch7_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch7_func; static int -aic_patch7_func(struct ahc_softc *ahc) +ahc_patch7_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_TARGETROLE) != 0); } -static int aic_patch6_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch6_func; static int -aic_patch6_func(struct ahc_softc *ahc) +ahc_patch6_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_DT) == 0); } -static int aic_patch5_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch5_func; static int -aic_patch5_func(struct ahc_softc *ahc) +ahc_patch5_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0); } -static int aic_patch4_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch4_func; static int -aic_patch4_func(struct ahc_softc *ahc) +ahc_patch4_func(struct ahc_softc *ahc) { return ((ahc->flags & AHC_PAGESCBS) != 0); } -static int aic_patch3_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch3_func; static int -aic_patch3_func(struct ahc_softc *ahc) +ahc_patch3_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_QUEUE_REGS) != 0); } -static int aic_patch2_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch2_func; static int -aic_patch2_func(struct ahc_softc *ahc) +ahc_patch2_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_TWIN) != 0); } -static int aic_patch1_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch1_func; static int -aic_patch1_func(struct ahc_softc *ahc) +ahc_patch1_func(struct ahc_softc *ahc) { return ((ahc->features & AHC_ULTRA2) != 0); } -static int aic_patch0_func(struct ahc_softc *ahc); +static ahc_patch_func_t ahc_patch0_func; static int -aic_patch0_func(struct ahc_softc *ahc) +ahc_patch0_func(struct ahc_softc *ahc) { return (0); } -typedef int patch_func_t (struct ahc_softc *ahc); static struct patch { - patch_func_t *patch_func; - uint32_t begin :10, - skip_instr :10, - skip_patch :12; + ahc_patch_func_t *patch_func; + uint32_t begin :10, + skip_instr :10, + skip_patch :12; } patches[] = { - { aic_patch1_func, 4, 1, 1 }, - { aic_patch2_func, 6, 2, 1 }, - { aic_patch2_func, 9, 1, 1 }, - { aic_patch3_func, 11, 1, 2 }, - { aic_patch0_func, 12, 2, 1 }, - { aic_patch4_func, 15, 1, 2 }, - { aic_patch0_func, 16, 1, 1 }, - { aic_patch5_func, 22, 2, 1 }, - { aic_patch3_func, 27, 1, 2 }, - { aic_patch0_func, 28, 1, 1 }, - { aic_patch6_func, 34, 1, 1 }, - { aic_patch7_func, 37, 54, 19 }, - { aic_patch8_func, 37, 1, 1 }, - { aic_patch9_func, 42, 3, 2 }, - { aic_patch0_func, 45, 3, 1 }, - { aic_patch10_func, 49, 1, 2 }, - { aic_patch0_func, 50, 2, 3 }, - { aic_patch1_func, 50, 1, 2 }, - { aic_patch0_func, 51, 1, 1 }, - { aic_patch2_func, 53, 2, 1 }, - { aic_patch9_func, 55, 1, 2 }, - { aic_patch0_func, 56, 1, 1 }, - { aic_patch9_func, 60, 1, 2 }, - { aic_patch0_func, 61, 1, 1 }, - { aic_patch9_func, 71, 1, 2 }, - { aic_patch0_func, 72, 1, 1 }, - { aic_patch9_func, 75, 1, 2 }, - { aic_patch0_func, 76, 1, 1 }, - { aic_patch9_func, 79, 1, 2 }, - { aic_patch0_func, 80, 1, 1 }, - { aic_patch8_func, 91, 9, 4 }, - { aic_patch1_func, 93, 1, 2 }, - { aic_patch0_func, 94, 1, 1 }, - { aic_patch2_func, 96, 2, 1 }, - { aic_patch2_func, 105, 4, 1 }, - { aic_patch1_func, 109, 1, 2 }, - { aic_patch0_func, 110, 2, 3 }, - { aic_patch2_func, 110, 1, 2 }, - { aic_patch0_func, 111, 1, 1 }, - { aic_patch7_func, 112, 4, 2 }, - { aic_patch0_func, 116, 1, 1 }, - { aic_patch11_func, 118, 2, 1 }, - { aic_patch1_func, 120, 1, 2 }, - { aic_patch0_func, 121, 1, 1 }, - { aic_patch7_func, 122, 4, 1 }, - { aic_patch7_func, 132, 91, 11 }, - { aic_patch4_func, 151, 1, 1 }, - { aic_patch1_func, 165, 1, 1 }, - { aic_patch12_func, 170, 1, 2 }, - { aic_patch0_func, 171, 1, 1 }, - { aic_patch9_func, 182, 1, 2 }, - { aic_patch0_func, 183, 1, 1 }, - { aic_patch9_func, 192, 1, 2 }, - { aic_patch0_func, 193, 1, 1 }, - { aic_patch9_func, 209, 6, 2 }, - { aic_patch0_func, 215, 6, 1 }, - { aic_patch8_func, 223, 19, 2 }, - { aic_patch1_func, 237, 1, 1 }, - { aic_patch1_func, 244, 1, 2 }, - { aic_patch0_func, 245, 2, 2 }, - { aic_patch11_func, 246, 1, 1 }, - { aic_patch9_func, 254, 31, 3 }, - { aic_patch1_func, 270, 14, 2 }, - { aic_patch13_func, 275, 1, 1 }, - { aic_patch14_func, 285, 14, 1 }, - { aic_patch1_func, 301, 1, 2 }, - { aic_patch0_func, 302, 1, 1 }, - { aic_patch9_func, 305, 1, 1 }, - { aic_patch13_func, 310, 1, 1 }, - { aic_patch9_func, 311, 2, 2 }, - { aic_patch0_func, 313, 4, 1 }, - { aic_patch14_func, 317, 1, 1 }, - { aic_patch15_func, 320, 2, 3 }, - { aic_patch9_func, 320, 1, 2 }, - { aic_patch0_func, 321, 1, 1 }, - { aic_patch6_func, 326, 1, 2 }, - { aic_patch0_func, 327, 1, 1 }, - { aic_patch1_func, 331, 50, 11 }, - { aic_patch6_func, 340, 2, 4 }, - { aic_patch7_func, 340, 1, 1 }, - { aic_patch8_func, 341, 1, 1 }, - { aic_patch0_func, 342, 1, 1 }, - { aic_patch16_func, 343, 1, 1 }, - { aic_patch6_func, 362, 6, 3 }, - { aic_patch16_func, 362, 5, 1 }, - { aic_patch0_func, 368, 5, 1 }, - { aic_patch13_func, 376, 5, 1 }, - { aic_patch0_func, 381, 54, 17 }, - { aic_patch14_func, 381, 1, 1 }, - { aic_patch7_func, 383, 2, 2 }, - { aic_patch17_func, 384, 1, 1 }, - { aic_patch9_func, 387, 1, 1 }, - { aic_patch18_func, 394, 1, 1 }, - { aic_patch14_func, 399, 9, 3 }, - { aic_patch9_func, 400, 3, 2 }, - { aic_patch0_func, 403, 3, 1 }, - { aic_patch9_func, 411, 6, 2 }, - { aic_patch0_func, 417, 9, 2 }, - { aic_patch13_func, 417, 1, 1 }, - { aic_patch13_func, 426, 2, 1 }, - { aic_patch14_func, 428, 1, 1 }, - { aic_patch9_func, 430, 1, 2 }, - { aic_patch0_func, 431, 1, 1 }, - { aic_patch7_func, 434, 1, 1 }, - { aic_patch7_func, 435, 1, 1 }, - { aic_patch8_func, 436, 3, 3 }, - { aic_patch6_func, 437, 1, 2 }, - { aic_patch0_func, 438, 1, 1 }, - { aic_patch9_func, 439, 1, 1 }, - { aic_patch15_func, 440, 1, 2 }, - { aic_patch13_func, 440, 1, 1 }, - { aic_patch14_func, 442, 9, 4 }, - { aic_patch9_func, 442, 1, 1 }, - { aic_patch9_func, 449, 2, 1 }, - { aic_patch0_func, 451, 4, 3 }, - { aic_patch9_func, 451, 1, 2 }, - { aic_patch0_func, 452, 3, 1 }, - { aic_patch1_func, 456, 2, 1 }, - { aic_patch7_func, 458, 10, 2 }, - { aic_patch0_func, 468, 1, 1 }, - { aic_patch8_func, 469, 109, 23 }, - { aic_patch1_func, 471, 3, 2 }, - { aic_patch0_func, 474, 5, 3 }, - { aic_patch9_func, 474, 2, 2 }, - { aic_patch0_func, 476, 3, 1 }, - { aic_patch1_func, 481, 2, 2 }, - { aic_patch0_func, 483, 6, 3 }, - { aic_patch9_func, 483, 2, 2 }, - { aic_patch0_func, 485, 3, 1 }, - { aic_patch1_func, 491, 2, 2 }, - { aic_patch0_func, 493, 9, 7 }, - { aic_patch9_func, 493, 5, 6 }, - { aic_patch19_func, 493, 1, 2 }, - { aic_patch0_func, 494, 1, 1 }, - { aic_patch19_func, 496, 1, 2 }, - { aic_patch0_func, 497, 1, 1 }, - { aic_patch0_func, 498, 4, 1 }, - { aic_patch6_func, 502, 3, 2 }, - { aic_patch0_func, 505, 1, 1 }, - { aic_patch1_func, 508, 1, 1 }, - { aic_patch6_func, 514, 1, 2 }, - { aic_patch0_func, 515, 1, 1 }, - { aic_patch20_func, 552, 7, 1 }, - { aic_patch3_func, 580, 1, 2 }, - { aic_patch0_func, 581, 1, 1 }, - { aic_patch21_func, 584, 1, 1 }, - { aic_patch8_func, 586, 104, 33 }, - { aic_patch4_func, 587, 1, 1 }, - { aic_patch1_func, 593, 2, 2 }, - { aic_patch0_func, 595, 1, 1 }, - { aic_patch1_func, 598, 1, 2 }, - { aic_patch0_func, 599, 1, 1 }, - { aic_patch9_func, 600, 3, 3 }, - { aic_patch15_func, 601, 1, 1 }, - { aic_patch0_func, 603, 4, 1 }, - { aic_patch19_func, 611, 2, 2 }, - { aic_patch0_func, 613, 1, 1 }, - { aic_patch19_func, 617, 10, 3 }, - { aic_patch5_func, 619, 8, 1 }, - { aic_patch0_func, 627, 9, 2 }, - { aic_patch5_func, 628, 8, 1 }, - { aic_patch4_func, 638, 1, 2 }, - { aic_patch0_func, 639, 1, 1 }, - { aic_patch19_func, 640, 1, 2 }, - { aic_patch0_func, 641, 3, 2 }, - { aic_patch4_func, 643, 1, 1 }, - { aic_patch5_func, 644, 1, 1 }, - { aic_patch5_func, 647, 1, 1 }, - { aic_patch5_func, 649, 1, 1 }, - { aic_patch4_func, 651, 2, 2 }, - { aic_patch0_func, 653, 2, 1 }, - { aic_patch5_func, 655, 1, 1 }, - { aic_patch5_func, 658, 1, 1 }, - { aic_patch5_func, 661, 1, 1 }, - { aic_patch19_func, 665, 1, 1 }, - { aic_patch19_func, 668, 1, 1 }, - { aic_patch4_func, 674, 1, 1 }, - { aic_patch6_func, 677, 1, 2 }, - { aic_patch0_func, 678, 1, 1 }, - { aic_patch7_func, 690, 16, 1 }, - { aic_patch4_func, 706, 20, 1 }, - { aic_patch9_func, 727, 4, 2 }, - { aic_patch0_func, 731, 4, 1 }, - { aic_patch9_func, 735, 4, 2 }, - { aic_patch0_func, 739, 3, 1 }, - { aic_patch6_func, 745, 1, 1 }, - { aic_patch22_func, 747, 14, 1 }, - { aic_patch7_func, 761, 3, 1 }, - { aic_patch9_func, 773, 24, 8 }, - { aic_patch19_func, 777, 1, 2 }, - { aic_patch0_func, 778, 1, 1 }, - { aic_patch15_func, 783, 4, 2 }, - { aic_patch0_func, 787, 7, 3 }, - { aic_patch23_func, 787, 5, 2 }, - { aic_patch0_func, 792, 2, 1 }, - { aic_patch0_func, 797, 42, 3 }, - { aic_patch18_func, 809, 18, 2 }, - { aic_patch0_func, 827, 1, 1 }, - { aic_patch4_func, 851, 1, 1 }, - { aic_patch4_func, 852, 3, 2 }, - { aic_patch0_func, 855, 1, 1 }, - { aic_patch13_func, 856, 3, 1 }, - { aic_patch4_func, 859, 12, 1 } + { ahc_patch1_func, 4, 1, 1 }, + { ahc_patch2_func, 6, 2, 1 }, + { ahc_patch2_func, 9, 1, 1 }, + { ahc_patch3_func, 11, 1, 2 }, + { ahc_patch0_func, 12, 2, 1 }, + { ahc_patch4_func, 15, 1, 2 }, + { ahc_patch0_func, 16, 1, 1 }, + { ahc_patch5_func, 22, 2, 1 }, + { ahc_patch3_func, 27, 1, 2 }, + { ahc_patch0_func, 28, 1, 1 }, + { ahc_patch6_func, 34, 1, 1 }, + { ahc_patch7_func, 37, 54, 19 }, + { ahc_patch8_func, 37, 1, 1 }, + { ahc_patch9_func, 42, 3, 2 }, + { ahc_patch0_func, 45, 3, 1 }, + { ahc_patch10_func, 49, 1, 2 }, + { ahc_patch0_func, 50, 2, 3 }, + { ahc_patch1_func, 50, 1, 2 }, + { ahc_patch0_func, 51, 1, 1 }, + { ahc_patch2_func, 53, 2, 1 }, + { ahc_patch9_func, 55, 1, 2 }, + { ahc_patch0_func, 56, 1, 1 }, + { ahc_patch9_func, 60, 1, 2 }, + { ahc_patch0_func, 61, 1, 1 }, + { ahc_patch9_func, 71, 1, 2 }, + { ahc_patch0_func, 72, 1, 1 }, + { ahc_patch9_func, 75, 1, 2 }, + { ahc_patch0_func, 76, 1, 1 }, + { ahc_patch9_func, 79, 1, 2 }, + { ahc_patch0_func, 80, 1, 1 }, + { ahc_patch8_func, 91, 9, 4 }, + { ahc_patch1_func, 93, 1, 2 }, + { ahc_patch0_func, 94, 1, 1 }, + { ahc_patch2_func, 96, 2, 1 }, + { ahc_patch2_func, 105, 4, 1 }, + { ahc_patch1_func, 109, 1, 2 }, + { ahc_patch0_func, 110, 2, 3 }, + { ahc_patch2_func, 110, 1, 2 }, + { ahc_patch0_func, 111, 1, 1 }, + { ahc_patch7_func, 112, 4, 2 }, + { ahc_patch0_func, 116, 1, 1 }, + { ahc_patch11_func, 117, 2, 1 }, + { ahc_patch1_func, 119, 1, 2 }, + { ahc_patch0_func, 120, 1, 1 }, + { ahc_patch7_func, 121, 4, 1 }, + { ahc_patch7_func, 131, 95, 11 }, + { ahc_patch4_func, 151, 1, 1 }, + { ahc_patch1_func, 168, 1, 1 }, + { ahc_patch12_func, 173, 1, 2 }, + { ahc_patch0_func, 174, 1, 1 }, + { ahc_patch9_func, 185, 1, 2 }, + { ahc_patch0_func, 186, 1, 1 }, + { ahc_patch9_func, 195, 1, 2 }, + { ahc_patch0_func, 196, 1, 1 }, + { ahc_patch9_func, 212, 6, 2 }, + { ahc_patch0_func, 218, 6, 1 }, + { ahc_patch8_func, 226, 20, 2 }, + { ahc_patch1_func, 241, 1, 1 }, + { ahc_patch1_func, 248, 1, 2 }, + { ahc_patch0_func, 249, 2, 2 }, + { ahc_patch11_func, 250, 1, 1 }, + { ahc_patch9_func, 258, 27, 3 }, + { ahc_patch1_func, 274, 10, 2 }, + { ahc_patch13_func, 277, 1, 1 }, + { ahc_patch14_func, 285, 14, 1 }, + { ahc_patch1_func, 301, 1, 2 }, + { ahc_patch0_func, 302, 1, 1 }, + { ahc_patch9_func, 305, 1, 1 }, + { ahc_patch13_func, 310, 1, 1 }, + { ahc_patch9_func, 311, 2, 2 }, + { ahc_patch0_func, 313, 4, 1 }, + { ahc_patch14_func, 317, 1, 1 }, + { ahc_patch15_func, 319, 2, 3 }, + { ahc_patch9_func, 319, 1, 2 }, + { ahc_patch0_func, 320, 1, 1 }, + { ahc_patch6_func, 325, 1, 2 }, + { ahc_patch0_func, 326, 1, 1 }, + { ahc_patch1_func, 330, 47, 11 }, + { ahc_patch6_func, 337, 2, 4 }, + { ahc_patch7_func, 337, 1, 1 }, + { ahc_patch8_func, 338, 1, 1 }, + { ahc_patch0_func, 339, 1, 1 }, + { ahc_patch16_func, 340, 1, 1 }, + { ahc_patch6_func, 356, 6, 3 }, + { ahc_patch16_func, 356, 5, 1 }, + { ahc_patch0_func, 362, 7, 1 }, + { ahc_patch13_func, 372, 5, 1 }, + { ahc_patch0_func, 377, 52, 17 }, + { ahc_patch14_func, 377, 1, 1 }, + { ahc_patch7_func, 379, 2, 2 }, + { ahc_patch17_func, 380, 1, 1 }, + { ahc_patch9_func, 383, 1, 1 }, + { ahc_patch18_func, 390, 1, 1 }, + { ahc_patch14_func, 395, 9, 3 }, + { ahc_patch9_func, 396, 3, 2 }, + { ahc_patch0_func, 399, 3, 1 }, + { ahc_patch9_func, 407, 6, 2 }, + { ahc_patch0_func, 413, 9, 2 }, + { ahc_patch13_func, 413, 1, 1 }, + { ahc_patch13_func, 422, 2, 1 }, + { ahc_patch14_func, 424, 1, 1 }, + { ahc_patch9_func, 426, 1, 2 }, + { ahc_patch0_func, 427, 1, 1 }, + { ahc_patch7_func, 428, 1, 1 }, + { ahc_patch7_func, 429, 1, 1 }, + { ahc_patch8_func, 430, 3, 3 }, + { ahc_patch6_func, 431, 1, 2 }, + { ahc_patch0_func, 432, 1, 1 }, + { ahc_patch9_func, 433, 1, 1 }, + { ahc_patch15_func, 434, 1, 2 }, + { ahc_patch13_func, 434, 1, 1 }, + { ahc_patch14_func, 436, 9, 4 }, + { ahc_patch9_func, 436, 1, 1 }, + { ahc_patch9_func, 443, 2, 1 }, + { ahc_patch0_func, 445, 4, 3 }, + { ahc_patch9_func, 445, 1, 2 }, + { ahc_patch0_func, 446, 3, 1 }, + { ahc_patch1_func, 450, 2, 1 }, + { ahc_patch7_func, 452, 10, 2 }, + { ahc_patch0_func, 462, 1, 1 }, + { ahc_patch8_func, 463, 118, 22 }, + { ahc_patch1_func, 465, 3, 2 }, + { ahc_patch0_func, 468, 5, 3 }, + { ahc_patch9_func, 468, 2, 2 }, + { ahc_patch0_func, 470, 3, 1 }, + { ahc_patch1_func, 475, 2, 2 }, + { ahc_patch0_func, 477, 6, 3 }, + { ahc_patch9_func, 477, 2, 2 }, + { ahc_patch0_func, 479, 3, 1 }, + { ahc_patch1_func, 485, 2, 2 }, + { ahc_patch0_func, 487, 9, 7 }, + { ahc_patch9_func, 487, 5, 6 }, + { ahc_patch19_func, 487, 1, 2 }, + { ahc_patch0_func, 488, 1, 1 }, + { ahc_patch19_func, 490, 1, 2 }, + { ahc_patch0_func, 491, 1, 1 }, + { ahc_patch0_func, 492, 4, 1 }, + { ahc_patch6_func, 497, 3, 2 }, + { ahc_patch0_func, 500, 1, 1 }, + { ahc_patch6_func, 510, 1, 2 }, + { ahc_patch0_func, 511, 1, 1 }, + { ahc_patch20_func, 548, 7, 1 }, + { ahc_patch3_func, 583, 1, 2 }, + { ahc_patch0_func, 584, 1, 1 }, + { ahc_patch21_func, 587, 1, 1 }, + { ahc_patch8_func, 589, 106, 33 }, + { ahc_patch4_func, 591, 1, 1 }, + { ahc_patch1_func, 597, 2, 2 }, + { ahc_patch0_func, 599, 1, 1 }, + { ahc_patch1_func, 602, 1, 2 }, + { ahc_patch0_func, 603, 1, 1 }, + { ahc_patch9_func, 604, 3, 3 }, + { ahc_patch15_func, 605, 1, 1 }, + { ahc_patch0_func, 607, 4, 1 }, + { ahc_patch19_func, 616, 2, 2 }, + { ahc_patch0_func, 618, 1, 1 }, + { ahc_patch19_func, 622, 10, 3 }, + { ahc_patch5_func, 624, 8, 1 }, + { ahc_patch0_func, 632, 9, 2 }, + { ahc_patch5_func, 633, 8, 1 }, + { ahc_patch4_func, 643, 1, 2 }, + { ahc_patch0_func, 644, 1, 1 }, + { ahc_patch19_func, 645, 1, 2 }, + { ahc_patch0_func, 646, 3, 2 }, + { ahc_patch4_func, 648, 1, 1 }, + { ahc_patch5_func, 649, 1, 1 }, + { ahc_patch5_func, 652, 1, 1 }, + { ahc_patch5_func, 654, 1, 1 }, + { ahc_patch4_func, 656, 2, 2 }, + { ahc_patch0_func, 658, 2, 1 }, + { ahc_patch5_func, 660, 1, 1 }, + { ahc_patch5_func, 663, 1, 1 }, + { ahc_patch5_func, 666, 1, 1 }, + { ahc_patch19_func, 670, 1, 1 }, + { ahc_patch19_func, 673, 1, 1 }, + { ahc_patch4_func, 679, 1, 1 }, + { ahc_patch6_func, 682, 1, 2 }, + { ahc_patch0_func, 683, 1, 1 }, + { ahc_patch7_func, 695, 16, 1 }, + { ahc_patch4_func, 711, 20, 1 }, + { ahc_patch9_func, 732, 4, 2 }, + { ahc_patch0_func, 736, 4, 1 }, + { ahc_patch9_func, 740, 4, 2 }, + { ahc_patch0_func, 744, 3, 1 }, + { ahc_patch6_func, 750, 1, 1 }, + { ahc_patch22_func, 752, 14, 1 }, + { ahc_patch7_func, 766, 3, 1 }, + { ahc_patch9_func, 778, 24, 8 }, + { ahc_patch19_func, 782, 1, 2 }, + { ahc_patch0_func, 783, 1, 1 }, + { ahc_patch15_func, 788, 4, 2 }, + { ahc_patch0_func, 792, 7, 3 }, + { ahc_patch23_func, 792, 5, 2 }, + { ahc_patch0_func, 797, 2, 1 }, + { ahc_patch0_func, 802, 42, 3 }, + { ahc_patch18_func, 814, 18, 2 }, + { ahc_patch0_func, 832, 1, 1 }, + { ahc_patch4_func, 856, 1, 1 }, + { ahc_patch4_func, 857, 3, 2 }, + { ahc_patch0_func, 860, 1, 1 }, + { ahc_patch13_func, 861, 3, 1 }, + { ahc_patch4_func, 864, 12, 1 } }; + static struct cs { - u_int16_t begin; - u_int16_t end; + uint16_t begin; + uint16_t end; } critical_sections[] = { { 11, 18 }, { 21, 30 }, - { 706, 722 }, - { 852, 855 }, - { 859, 865 }, - { 867, 869 }, - { 869, 871 } + { 711, 727 }, + { 857, 860 }, + { 864, 870 }, + { 872, 874 }, + { 874, 876 } }; + static const int num_critical_sections = sizeof(critical_sections) / sizeof(*critical_sections); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/Makefile linux-2.4.22/drivers/scsi/aic7xxx/aicasm/Makefile --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/Makefile 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/Makefile 2003-08-25 04:44:42.000000000 -0700 @@ -10,9 +10,10 @@ GENSRCS= $(YSRCS:.y=.c) $(LSRCS:.l=.c) SRCS= ${CSRCS} ${GENSRCS} -CLEANFILES= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) +LIBS= -ldb +clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG) # Override default kernel CFLAGS. This is a userland app. -AICASM_CFLAGS:= -I/usr/include -I. -ldb +AICASM_CFLAGS:= -I/usr/include -I. YFLAGS= -d NOMAN= noman @@ -30,10 +31,12 @@ endif $(PROG): ${GENHDRS} $(SRCS) - $(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) + $(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) $(LIBS) aicdb.h: - @if [ -e "/usr/include/db3/db_185.h" ]; then \ + @if [ -e "/usr/include/db4/db_185.h" ]; then \ + echo "#include " > aicdb.h; \ + elif [ -e "/usr/include/db3/db_185.h" ]; then \ echo "#include " > aicdb.h; \ elif [ -e "/usr/include/db2/db_185.h" ]; then \ echo "#include " > aicdb.h; \ @@ -46,7 +49,7 @@ fi clean: - rm -f $(CLEANFILES) $(PROG) + rm -f $(clean-files) aicasm_gram.c aicasm_gram.h: aicasm_gram.y $(YACC) $(YFLAGS) -b $(<:.y=) $< diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm.c linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm.c --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm.c 2003-08-25 04:44:42.000000000 -0700 @@ -2,7 +2,7 @@ * Aic7xxx SCSI host adapter firmware asssembler * * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#16 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.c,v 1.28.2.5 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #include #include @@ -85,12 +85,15 @@ struct path_list search_path; int includes_search_curdir; char *appname; +char *stock_include_file; FILE *ofile; char *ofilename; char *regfilename; FILE *regfile; char *listfilename; FILE *listfile; +char *regdiagfilename; +FILE *regdiagfile; int src_mode; int dst_mode; @@ -140,7 +143,7 @@ yydebug = 0; mmdebug = 0; #endif - while ((ch = getopt(argc, argv, "d:l:n:o:r:I:O:")) != -1) { + while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) { switch(ch) { case 'd': #if DEBUG @@ -160,6 +163,9 @@ "information", EX_SOFTWARE); #endif break; + case 'i': + stock_include_file = optarg; + break; case 'l': /* Create a program listing */ if ((listfile = fopen(optarg, "w")) == NULL) { @@ -184,6 +190,14 @@ } ofilename = optarg; break; + case 'p': + /* Create Register Diagnostic "printing" Functions */ + if ((regdiagfile = fopen(optarg, "w")) == NULL) { + perror(optarg); + stop(NULL, EX_CANTCREAT); + } + regdiagfilename = optarg; + break; case 'r': if ((regfile = fopen(optarg, "w")) == NULL) { perror(optarg); @@ -245,6 +259,14 @@ /* NOTREACHED */ } + if (regdiagfile != NULL + && (regfile == NULL || stock_include_file == NULL)) { + fprintf(stderr, + "%s: The -p option requires the -r and -i options.\n", + appname); + usage(); + /* NOTREACHED */ + } symtable_open(); inputfilename = *argv; include_file(*argv, SOURCE_FILE); @@ -271,9 +293,8 @@ if (ofile != NULL) output_code(); - if (regfile != NULL) { - symtable_dump(regfile); - } + if (regfile != NULL) + symtable_dump(regfile, regdiagfile); if (listfile != NULL) output_listing(inputfilename); } @@ -288,10 +309,10 @@ { (void)fprintf(stderr, -"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file] - [-r register_output_file] [-l program_list_file] - input_file\n", - appname); +"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n" +" [-r register_output_file [-p register_diag_file -i includefile]]\n" +" [-l program_list_file]\n" +" input_file\n", appname); exit(EX_USAGE); } @@ -335,11 +356,11 @@ instrcount = 0; fprintf(ofile, -"/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * -%s */\n", versions); +"/*\n" +" * DO NOT EDIT - This file is automatically generated\n" +" * from the following source files:\n" +" *\n" +"%s */\n", versions); fprintf(ofile, "static uint8_t seqprog[] = {\n"); for (cur_instr = STAILQ_FIRST(&seq_program); @@ -370,49 +391,54 @@ /* * Output patch information. Patch functions first. */ + fprintf(ofile, +"typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list); + for (cur_node = SLIST_FIRST(&patch_functions); cur_node != NULL; cur_node = SLIST_NEXT(cur_node,links)) { fprintf(ofile, -"static int aic_patch%d_func(%s); - -static int -aic_patch%d_func(%s) -{ - return (%s); -}\n\n", +"static %spatch_func_t %spatch%d_func;\n" +"\n" +"static int\n" +"%spatch%d_func(%s)\n" +"{\n" +" return (%s);\n" +"}\n\n", + prefix, + prefix, cur_node->symbol->info.condinfo->func_num, - patch_arg_list, + prefix, cur_node->symbol->info.condinfo->func_num, patch_arg_list, cur_node->symbol->name); } fprintf(ofile, -"typedef int patch_func_t (%s); -static struct patch { - patch_func_t *patch_func; - uint32_t begin :10, - skip_instr :10, - skip_patch :12; -} patches[] = {\n", patch_arg_list); +"static struct patch {\n" +" %spatch_func_t *patch_func;\n" +" uint32_t begin :10,\n" +" skip_instr :10,\n" +" skip_patch :12;\n" +"} patches[] = {\n", prefix); for (cur_patch = STAILQ_FIRST(&patches); cur_patch != NULL; cur_patch = STAILQ_NEXT(cur_patch,links)) { - fprintf(ofile, "%s\t{ aic_patch%d_func, %d, %d, %d }", + fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }", cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n", + prefix, cur_patch->patch_func, cur_patch->begin, cur_patch->skip_instr, cur_patch->skip_patch); } - fprintf(ofile, "\n};\n"); + fprintf(ofile, "\n};\n\n"); fprintf(ofile, -"static struct cs { - u_int16_t begin; - u_int16_t end; -} critical_sections[] = {\n"); +"static struct cs {\n" +" uint16_t begin;\n" +" uint16_t end;\n" +"} critical_sections[] = {\n"); for (cs = TAILQ_FIRST(&cs_tailq); cs != NULL; @@ -422,11 +448,11 @@ cs->begin_addr, cs->end_addr); } - fprintf(ofile, "\n};\n"); + fprintf(ofile, "\n};\n\n"); fprintf(ofile, -"static const int num_critical_sections = sizeof(critical_sections) - / sizeof(*critical_sections);\n"); +"static const int num_critical_sections = sizeof(critical_sections)\n" +" / sizeof(*critical_sections);\n"); fprintf(stderr, "%s: %d instructions used\n", appname, instrcount); } diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm.h linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm.h --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm.h 2003-08-25 04:44:42.000000000 -0700 @@ -2,7 +2,7 @@ * Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters * * Copyright (c) 1997 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#10 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#14 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.h,v 1.11.2.4 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -76,8 +76,10 @@ extern struct symlist patch_functions; extern int includes_search_curdir; /* False if we've seen -I- */ extern char *appname; +extern char *stock_include_file; extern int yylineno; extern char *yyfilename; +extern char *prefix; extern char *patch_arg_list; extern char *versions; extern int src_mode; diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y 2003-08-25 04:44:42.000000000 -0700 @@ -3,7 +3,7 @@ * Parser for the Aic7xxx SCSI Host adapter sequencer assembler. * * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,9 +38,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#15 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_gram.y,v 1.11.2.5 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #include @@ -64,11 +64,14 @@ int yylineno; char *yyfilename; +char stock_prefix[] = "aic_"; +char *prefix = stock_prefix; char *patch_arg_list; char *versions; static char errbuf[255]; static char regex_pattern[255]; static symbol_t *cur_symbol; +static symbol_t *field_symbol; static symbol_t *scb_or_sram_symbol; static symtype cur_symtype; static symbol_ref_t accumulator; @@ -82,8 +85,10 @@ static int sram_or_scb_offset; static int download_constant_count; static int in_critical_section; +static u_int enum_increment; +static u_int enum_next_value; -static void process_bitmask(int mask_type, symbol_t *sym, int mask); +static void process_field(int field_type, symbol_t *sym, int mask); static void initialize_symbol(symbol_t *symbol); static void add_macro_arg(const char *argtext, int position); static void add_macro_body(const char *bodytext); @@ -152,7 +157,9 @@ %token T_END_CS -%token T_BIT +%token T_FIELD + +%token T_ENUM %token T_MASK @@ -162,7 +169,7 @@ %token T_CEXPR -%token T_EOF T_INCLUDE T_VERSION T_PATCH_ARG_LIST +%token T_EOF T_INCLUDE T_VERSION T_PREFIX T_PATCH_ARG_LIST %token T_SHR T_SHL T_ROR T_ROL @@ -202,7 +209,7 @@ %type export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne -%type numerical_value mode_value mode_list macro_arglist +%type mode_value mode_list macro_arglist %left '|' %left '&' @@ -216,6 +223,8 @@ program: include | program include +| prefix +| program prefix | patch_arg_list | program patch_arg_list | version @@ -257,6 +266,18 @@ } ; +prefix: + T_PREFIX '=' T_STRING + { + if (prefix != stock_prefix) + stop("Prefix multiply defined", + EX_DATAERR); + prefix = strdup($3); + if (prefix == NULL) + stop("Unable to record prefix", EX_SOFTWARE); + } +; + patch_arg_list: T_PATCH_ARG_LIST '=' T_STRING { @@ -326,7 +347,8 @@ | size | access_mode | modes -| bit_defn +| field_defn +| enum_defn | mask_defn | alias | accumulator @@ -418,17 +440,68 @@ } ; -bit_defn: - T_BIT T_SYMBOL T_NUMBER +field_defn: + T_FIELD + { + field_symbol = NULL; + enum_next_value = 0; + enum_increment = 1; + } + '{' enum_entry_list '}' +| T_FIELD T_SYMBOL expression + { + process_field(FIELD, $2, $3.value); + field_symbol = $2; + enum_next_value = 0; + enum_increment = 0x01 << (ffs($3.value) - 1); + } + '{' enum_entry_list '}' +| T_FIELD T_SYMBOL expression + { + process_field(FIELD, $2, $3.value); + } +; + +enum_defn: + T_ENUM + { + field_symbol = NULL; + enum_next_value = 0; + enum_increment = 1; + } + '{' enum_entry_list '}' +| T_ENUM T_SYMBOL expression + { + process_field(ENUM, $2, $3.value); + field_symbol = $2; + enum_next_value = 0; + enum_increment = 0x01 << (ffs($3.value) - 1); + } + '{' enum_entry_list '}' +; + +enum_entry_list: + enum_entry +| enum_entry_list ',' enum_entry +; + +enum_entry: + T_SYMBOL { - process_bitmask(BIT, $2, $3); + process_field(ENUM_ENTRY, $1, enum_next_value); + enum_next_value += enum_increment; + } +| T_SYMBOL expression + { + process_field(ENUM_ENTRY, $1, $2.value); + enum_next_value = $2.value + enum_increment; } ; mask_defn: T_MASK T_SYMBOL expression { - process_bitmask(MASK, $2, $3.value); + process_field(MASK, $2, $3.value); } ; @@ -608,8 +681,10 @@ $$.value = symbol->info.rinfo->address; break; case MASK: - case BIT: - $$.value = symbol->info.minfo->mask; + case FIELD: + case ENUM: + case ENUM_ENTRY: + $$.value = symbol->info.finfo->value; break; case DOWNLOAD_CONST: case CONST: @@ -632,7 +707,7 @@ ; constant: - T_CONST T_SYMBOL numerical_value + T_CONST T_SYMBOL expression { if ($2->type != UNINITIALIZED) { stop("Re-definition of symbol as a constant", @@ -641,7 +716,7 @@ } $2->type = CONST; initialize_symbol($2); - $2->info.cinfo->value = $3; + $2->info.cinfo->value = $3.value; } | T_CONST T_SYMBOL T_DOWNLOAD { @@ -709,17 +784,6 @@ } ; -numerical_value: - T_NUMBER - { - $$ = $1; - } -| '-' T_NUMBER - { - $$ = -$2; - } -; - scratch_ram: T_SRAM '{' { @@ -862,6 +926,8 @@ | T_A { SLIST_INIT(&$$.referenced_syms); + symlist_add(&$$.referenced_syms, accumulator.symbol, + SYMLIST_INSERT_HEAD); $$.value = 0; } ; @@ -917,6 +983,7 @@ cs->begin_addr = instruction_ptr; in_critical_section = TRUE; } +; critical_section_end: T_END_CS ';' @@ -931,6 +998,7 @@ cs->end_addr = instruction_ptr; in_critical_section = FALSE; } +; export: { $$ = 0; } @@ -1161,9 +1229,22 @@ ; code: - T_MVI destination ',' immediate_or_a ret ';' + T_MVI destination ',' immediate ret ';' { - format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); + if ($4.value == 0 + && is_download_const(&$4) == 0) { + expression_t immed; + + /* + * Allow move immediates of 0 so that macros, + * that can't know the immediate's value and + * otherwise compensate, still work. + */ + make_expression(&immed, 1); + format_1_instr(AIC_OP_BMOV, &$2, &immed, &allzeros, $5); + } else { + format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); + } } ; @@ -1298,7 +1379,7 @@ %% static void -process_bitmask(int mask_type, symbol_t *sym, int mask) +process_field(int field_type, symbol_t *sym, int value) { /* * Add the current register to its @@ -1308,52 +1389,54 @@ * the "allowed bits" of this register. */ if (sym->type == UNINITIALIZED) { - sym->type = mask_type; + sym->type = field_type; initialize_symbol(sym); - if (mask_type == BIT) { - if (mask == 0) { - stop("Bitmask with no bits set", EX_DATAERR); - /* NOTREACHED */ - } - if ((mask & ~(0x01 << (ffs(mask) - 1))) != 0) { - stop("Bitmask with more than one bit set", - EX_DATAERR); + sym->info.finfo->value = value; + if (field_type != ENUM_ENTRY) { + if (field_type != MASK && value == 0) { + stop("Empty Field, or Enum", EX_DATAERR); /* NOTREACHED */ } + sym->info.finfo->value = value; + sym->info.finfo->mask = value; + } else if (field_symbol != NULL) { + sym->info.finfo->mask = field_symbol->info.finfo->value; + } else { + sym->info.finfo->mask = 0xFF; } - sym->info.minfo->mask = mask; - } else if (sym->type != mask_type) { - stop("Bit definition mirrors a definition of the same " + } else if (sym->type != field_type) { + stop("Field definition mirrors a definition of the same " " name, but a different type", EX_DATAERR); /* NOTREACHED */ - } else if (mask != sym->info.minfo->mask) { - stop("Bitmask redefined with a conflicting value", EX_DATAERR); + } else if (value != sym->info.finfo->value) { + stop("Field redefined with a conflicting value", EX_DATAERR); /* NOTREACHED */ } /* Fail if this symbol is already listed */ - if (symlist_search(&(sym->info.minfo->symrefs), + if (symlist_search(&(sym->info.finfo->symrefs), cur_symbol->name) != NULL) { - stop("Bitmask defined multiple times for register", EX_DATAERR); + stop("Field defined multiple times for register", EX_DATAERR); /* NOTREACHED */ } - symlist_add(&(sym->info.minfo->symrefs), cur_symbol, + symlist_add(&(sym->info.finfo->symrefs), cur_symbol, SYMLIST_INSERT_HEAD); - cur_symbol->info.rinfo->valid_bitmask |= mask; + cur_symbol->info.rinfo->valid_bitmask |= sym->info.finfo->mask; cur_symbol->info.rinfo->typecheck_masks = TRUE; + symlist_add(&(cur_symbol->info.rinfo->fields), sym, SYMLIST_SORT); } static void initialize_symbol(symbol_t *symbol) { switch (symbol->type) { - case UNINITIALIZED: + case UNINITIALIZED: stop("Call to initialize_symbol with type field unset", EX_SOFTWARE); /* NOTREACHED */ break; - case REGISTER: - case SRAMLOC: - case SCBLOC: + case REGISTER: + case SRAMLOC: + case SCBLOC: symbol->info.rinfo = (struct reg_info *)malloc(sizeof(struct reg_info)); if (symbol->info.rinfo == NULL) { @@ -1362,6 +1445,7 @@ } memset(symbol->info.rinfo, 0, sizeof(struct reg_info)); + SLIST_INIT(&(symbol->info.rinfo->fields)); /* * Default to allowing access in all register modes * or to the mode specified by the SCB or SRAM space @@ -1373,7 +1457,7 @@ else symbol->info.rinfo->modes = ~0; break; - case ALIAS: + case ALIAS: symbol->info.ainfo = (struct alias_info *)malloc(sizeof(struct alias_info)); if (symbol->info.ainfo == NULL) { @@ -1383,19 +1467,21 @@ memset(symbol->info.ainfo, 0, sizeof(struct alias_info)); break; - case MASK: - case BIT: - symbol->info.minfo = - (struct mask_info *)malloc(sizeof(struct mask_info)); - if (symbol->info.minfo == NULL) { - stop("Can't create bitmask info", EX_SOFTWARE); + case MASK: + case FIELD: + case ENUM: + case ENUM_ENTRY: + symbol->info.finfo = + (struct field_info *)malloc(sizeof(struct field_info)); + if (symbol->info.finfo == NULL) { + stop("Can't create field info", EX_SOFTWARE); /* NOTREACHED */ } - memset(symbol->info.minfo, 0, sizeof(struct mask_info)); - SLIST_INIT(&(symbol->info.minfo->symrefs)); + memset(symbol->info.finfo, 0, sizeof(struct field_info)); + SLIST_INIT(&(symbol->info.finfo->symrefs)); break; - case CONST: - case DOWNLOAD_CONST: + case CONST: + case DOWNLOAD_CONST: symbol->info.cinfo = (struct const_info *)malloc(sizeof(struct const_info)); if (symbol->info.cinfo == NULL) { @@ -1577,7 +1663,6 @@ case AIC_OP_OR: dst_value = src_value | immed->value; break; - break; case AIC_OP_BMOV: dst_value = src_value; break; @@ -1586,9 +1671,9 @@ } src_mode = dst_value & 0xF; dst_mode = (dst_value >> 4) & 0xF; -cant_update: } +cant_update: symlist_free(&immed->referenced_syms); instruction_ptr++; } @@ -1763,11 +1848,13 @@ node != NULL; node = node->links.sle_next) { if ((node->symbol->type == MASK - || node->symbol->type == BIT) - && symlist_search(&node->symbol->info.minfo->symrefs, + || node->symbol->type == FIELD + || node->symbol->type == ENUM + || node->symbol->type == ENUM_ENTRY) + && symlist_search(&node->symbol->info.finfo->symrefs, symbol->name) == NULL) { snprintf(errbuf, sizeof(errbuf), - "Invalid bit or mask %s " + "Invalid field or mask %s " "for register %s", node->symbol->name, symbol->name); stop(errbuf, EX_DATAERR); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 2003-08-25 04:44:42.000000000 -0700 @@ -37,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#9 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_insformat.h,v 1.3.2.3 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ struct ins_format1 { diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y 2003-08-25 04:44:42.000000000 -0700 @@ -38,9 +38,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id$ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y,v 1.1.2.1 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #include diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 2003-08-25 04:44:42.000000000 -0700 @@ -38,13 +38,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id$ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#7 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l,v 1.1.2.1 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #include +#include #include #include #include diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l 2003-08-25 04:44:42.000000000 -0700 @@ -3,7 +3,7 @@ * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. * * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. - * Copyright (c) 2001 Adaptec Inc. + * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,13 +38,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#11 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_scan.l,v 1.13.2.4 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #include +#include #include #include #include @@ -131,6 +132,7 @@ } VERSION { return T_VERSION; } +PREFIX { return T_PREFIX; } PATCH_ARG_LIST { return T_PATCH_ARG_LIST; } \" { string_buf_ptr = string_buf; @@ -173,7 +175,8 @@ END_CRITICAL { return T_END_CS; } SET_SRC_MODE { return T_SET_SRC_MODE; } SET_DST_MODE { return T_SET_DST_MODE; } -bit { return T_BIT; } +field { return T_FIELD; } +enum { return T_ENUM; } mask { return T_MASK; } alias { return T_ALIAS; } size { return T_SIZE; } diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c 2003-08-25 04:44:42.000000000 -0700 @@ -2,6 +2,7 @@ * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation * * Copyright (c) 1997 Justin T. Gibbs. + * Copyright (c) 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#14 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.c,v 1.11.2.4 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #include @@ -49,6 +50,7 @@ #include #endif #include +#include #include #include #include @@ -72,6 +74,8 @@ } memset(new_symbol, 0, sizeof(*new_symbol)); new_symbol->name = strdup(name); + if (new_symbol->name == NULL) + stop("Unable to strdup symbol name", EX_SOFTWARE); new_symbol->type = UNINITIALIZED; return (new_symbol); } @@ -98,10 +102,12 @@ free(symbol->info.ainfo); break; case MASK: - case BIT: - if (symbol->info.minfo != NULL) { - symlist_free(&symbol->info.minfo->symrefs); - free(symbol->info.minfo); + case FIELD: + case ENUM: + case ENUM_ENTRY: + if (symbol->info.finfo != NULL) { + symlist_free(&symbol->info.finfo->symrefs); + free(symbol->info.finfo); } break; case DOWNLOAD_CONST: @@ -222,17 +228,19 @@ newnode->symbol = symbol; if (how == SYMLIST_SORT) { symbol_node_t *curnode; - int mask; + int field; - mask = FALSE; + field = FALSE; switch(symbol->type) { case REGISTER: case SCBLOC: case SRAMLOC: break; - case BIT: + case FIELD: case MASK: - mask = TRUE; + case ENUM: + case ENUM_ENTRY: + field = TRUE; break; default: stop("symlist_add: Invalid symbol type for sorting", @@ -242,9 +250,12 @@ curnode = SLIST_FIRST(symlist); if (curnode == NULL - || (mask && (curnode->symbol->info.minfo->mask > - newnode->symbol->info.minfo->mask)) - || (!mask && (curnode->symbol->info.rinfo->address > + || (field + && (curnode->symbol->type > newnode->symbol->type + || (curnode->symbol->type == newnode->symbol->type + && (curnode->symbol->info.finfo->value > + newnode->symbol->info.finfo->value)))) + || (!field && (curnode->symbol->info.rinfo->address > newnode->symbol->info.rinfo->address))) { SLIST_INSERT_HEAD(symlist, newnode, links); return; @@ -259,10 +270,14 @@ symbol_t *cursymbol; cursymbol = SLIST_NEXT(curnode, links)->symbol; - if ((mask && (cursymbol->info.minfo->mask > - symbol->info.minfo->mask)) - || (!mask &&(cursymbol->info.rinfo->address > - symbol->info.rinfo->address))){ + if ((field + && (cursymbol->type > symbol->type + || (cursymbol->type == symbol->type + && (cursymbol->info.finfo->value > + symbol->info.finfo->value)))) + || (!field + && (cursymbol->info.rinfo->address > + symbol->info.rinfo->address))) { SLIST_INSERT_AFTER(curnode, newnode, links); break; @@ -307,20 +322,160 @@ } void -symtable_dump(FILE *ofile) +aic_print_file_prologue(FILE *ofile) +{ + + if (ofile == NULL) + return; + + fprintf(ofile, +"/*\n" +" * DO NOT EDIT - This file is automatically generated\n" +" * from the following source files:\n" +" *\n" +"%s */\n", + versions); +} + +void +aic_print_include(FILE *dfile, char *include_file) +{ + + if (dfile == NULL) + return; + fprintf(dfile, "\n#include \"%s\"\n\n", include_file); +} + +void +aic_print_reg_dump_types(FILE *ofile) +{ + if (ofile == NULL) + return; + + fprintf(ofile, +"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n" +"typedef struct %sreg_parse_entry {\n" +" char *name;\n" +" uint8_t value;\n" +" uint8_t mask;\n" +"} %sreg_parse_entry_t;\n" +"\n", + prefix, prefix, prefix); +} + +static void +aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode) +{ + if (dfile == NULL) + return; + + fprintf(dfile, +"static %sreg_parse_entry_t %s_parse_table[] = {\n", + prefix, + regnode->symbol->name); +} + +static void +aic_print_reg_dump_end(FILE *ofile, FILE *dfile, + symbol_node_t *regnode, u_int num_entries) +{ + char *lower_name; + char *letter; + + lower_name = strdup(regnode->symbol->name); + if (lower_name == NULL) + stop("Unable to strdup symbol name", EX_SOFTWARE); + + for (letter = lower_name; *letter != '\0'; letter++) + *letter = tolower(*letter); + + if (dfile != NULL) { + if (num_entries != 0) + fprintf(dfile, +"\n" +"};\n" +"\n"); + + fprintf(dfile, +"int\n" +"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n" +"{\n" +" return (%sprint_register(%s%s, %d, \"%s\",\n" +" 0x%02x, regvalue, cur_col, wrap));\n" +"}\n" +"\n", + prefix, + lower_name, + prefix, + num_entries != 0 ? regnode->symbol->name : "NULL", + num_entries != 0 ? "_parse_table" : "", + num_entries, + regnode->symbol->name, + regnode->symbol->info.rinfo->address); + } + + fprintf(ofile, +"#if AIC_DEBUG_REGISTERS\n" +"%sreg_print_t %s%s_print;\n" +"#else\n" +"#define %s%s_print(regvalue, cur_col, wrap) \\\n" +" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n" +"#endif\n" +"\n", + prefix, + prefix, + lower_name, + prefix, + lower_name, + prefix, + regnode->symbol->name, + regnode->symbol->info.rinfo->address); +} + +static void +aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode) +{ + int num_tabs; + + if (dfile == NULL) + return; + + fprintf(dfile, +" { \"%s\",", + curnode->symbol->name); + + num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8; + + while (num_tabs-- > 0) + fputc('\t', dfile); + fprintf(dfile, "0x%02x, 0x%02x }", + curnode->symbol->info.finfo->value, + curnode->symbol->info.finfo->mask); +} + +void +symtable_dump(FILE *ofile, FILE *dfile) { /* * Sort the registers by address with a simple insertion sort. * Put bitmasks next to the first register that defines them. * Put constants at the end. */ - symlist_t registers; - symlist_t masks; - symlist_t constants; - symlist_t download_constants; - symlist_t aliases; - symlist_t exported_labels; - u_int i; + symlist_t registers; + symlist_t masks; + symlist_t constants; + symlist_t download_constants; + symlist_t aliases; + symlist_t exported_labels; + symbol_node_t *curnode; + symbol_node_t *regnode; + DBT key; + DBT data; + int flag; + u_int i; + + if (symtable == NULL) + return; SLIST_INIT(®isters); SLIST_INIT(&masks); @@ -328,173 +483,195 @@ SLIST_INIT(&download_constants); SLIST_INIT(&aliases); SLIST_INIT(&exported_labels); + flag = R_FIRST; + while (symtable->seq(symtable, &key, &data, flag) == 0) { + symbol_t *cursym; - if (symtable != NULL) { - DBT key; - DBT data; - int flag = R_FIRST; + memcpy(&cursym, data.data, sizeof(cursym)); + switch(cursym->type) { + case REGISTER: + case SCBLOC: + case SRAMLOC: + symlist_add(®isters, cursym, SYMLIST_SORT); + break; + case MASK: + case FIELD: + case ENUM: + case ENUM_ENTRY: + symlist_add(&masks, cursym, SYMLIST_SORT); + break; + case CONST: + symlist_add(&constants, cursym, + SYMLIST_INSERT_HEAD); + break; + case DOWNLOAD_CONST: + symlist_add(&download_constants, cursym, + SYMLIST_INSERT_HEAD); + break; + case ALIAS: + symlist_add(&aliases, cursym, + SYMLIST_INSERT_HEAD); + break; + case LABEL: + if (cursym->info.linfo->exported == 0) + break; + symlist_add(&exported_labels, cursym, + SYMLIST_INSERT_HEAD); + break; + default: + break; + } + flag = R_NEXT; + } - while (symtable->seq(symtable, &key, &data, flag) == 0) { - symbol_t *cursym; + /* Register dianostic functions/declarations first. */ + aic_print_file_prologue(ofile); + aic_print_reg_dump_types(ofile); + aic_print_file_prologue(dfile); + aic_print_include(dfile, stock_include_file); + SLIST_FOREACH(curnode, ®isters, links) { - memcpy(&cursym, data.data, sizeof(cursym)); - switch(cursym->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - symlist_add(®isters, cursym, SYMLIST_SORT); - break; - case MASK: - case BIT: - symlist_add(&masks, cursym, SYMLIST_SORT); - break; - case CONST: - symlist_add(&constants, cursym, - SYMLIST_INSERT_HEAD); - break; - case DOWNLOAD_CONST: - symlist_add(&download_constants, cursym, - SYMLIST_INSERT_HEAD); - break; - case ALIAS: - symlist_add(&aliases, cursym, - SYMLIST_INSERT_HEAD); - break; - case LABEL: - if (cursym->info.linfo->exported == 0) - break; - symlist_add(&exported_labels, cursym, - SYMLIST_INSERT_HEAD); - break; - default: - break; + switch(curnode->symbol->type) { + case REGISTER: + case SCBLOC: + case SRAMLOC: + { + symlist_t *fields; + symbol_node_t *fieldnode; + int num_entries; + + num_entries = 0; + fields = &curnode->symbol->info.rinfo->fields; + SLIST_FOREACH(fieldnode, fields, links) { + if (num_entries == 0) + aic_print_reg_dump_start(dfile, + curnode); + else if (dfile != NULL) + fputs(",\n", dfile); + num_entries++; + aic_print_reg_dump_entry(dfile, fieldnode); } - flag = R_NEXT; + aic_print_reg_dump_end(ofile, dfile, + curnode, num_entries); + } + default: + break; } + } - /* Put in the masks and bits */ - while (SLIST_FIRST(&masks) != NULL) { - symbol_node_t *curnode; - symbol_node_t *regnode; - char *regname; + /* Fold in the masks and bits */ + while (SLIST_FIRST(&masks) != NULL) { + char *regname; - curnode = SLIST_FIRST(&masks); - SLIST_REMOVE_HEAD(&masks, links); + curnode = SLIST_FIRST(&masks); + SLIST_REMOVE_HEAD(&masks, links); - regnode = - SLIST_FIRST(&curnode->symbol->info.minfo->symrefs); - regname = regnode->symbol->name; - regnode = symlist_search(®isters, regname); - SLIST_INSERT_AFTER(regnode, curnode, links); - } + regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs); + regname = regnode->symbol->name; + regnode = symlist_search(®isters, regname); + SLIST_INSERT_AFTER(regnode, curnode, links); + } - /* Add the aliases */ - while (SLIST_FIRST(&aliases) != NULL) { - symbol_node_t *curnode; - symbol_node_t *regnode; - char *regname; + /* Add the aliases */ + while (SLIST_FIRST(&aliases) != NULL) { + char *regname; - curnode = SLIST_FIRST(&aliases); - SLIST_REMOVE_HEAD(&aliases, links); + curnode = SLIST_FIRST(&aliases); + SLIST_REMOVE_HEAD(&aliases, links); - regname = curnode->symbol->info.ainfo->parent->name; - regnode = symlist_search(®isters, regname); - SLIST_INSERT_AFTER(regnode, curnode, links); - } + regname = curnode->symbol->info.ainfo->parent->name; + regnode = symlist_search(®isters, regname); + SLIST_INSERT_AFTER(regnode, curnode, links); + } - /* Output what we have */ - fprintf(ofile, -"/* - * DO NOT EDIT - This file is automatically generated - * from the following source files: - * -%s */\n", versions); - while (SLIST_FIRST(®isters) != NULL) { - symbol_node_t *curnode; - u_int value; - char *tab_str; - char *tab_str2; - - curnode = SLIST_FIRST(®isters); - SLIST_REMOVE_HEAD(®isters, links); - switch(curnode->symbol->type) { - case REGISTER: - case SCBLOC: - case SRAMLOC: - fprintf(ofile, "\n"); - value = curnode->symbol->info.rinfo->address; - tab_str = "\t"; - tab_str2 = "\t\t"; - break; - case ALIAS: - { - symbol_t *parent; - - parent = curnode->symbol->info.ainfo->parent; - value = parent->info.rinfo->address; - tab_str = "\t"; - tab_str2 = "\t\t"; - break; - } - case MASK: - case BIT: - value = curnode->symbol->info.minfo->mask; - tab_str = "\t\t"; - tab_str2 = "\t"; - break; - default: - value = 0; /* Quiet compiler */ - tab_str = NULL; - tab_str2 = NULL; - stop("symtable_dump: Invalid symbol type " - "encountered", EX_SOFTWARE); - break; - } - fprintf(ofile, "#define%s%-16s%s0x%02x\n", - tab_str, curnode->symbol->name, tab_str2, - value); - free(curnode); - } - fprintf(ofile, "\n\n"); - - while (SLIST_FIRST(&constants) != NULL) { - symbol_node_t *curnode; - - curnode = SLIST_FIRST(&constants); - SLIST_REMOVE_HEAD(&constants, links); - fprintf(ofile, "#define\t%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.cinfo->value); - free(curnode); + /* Output generated #defines. */ + while (SLIST_FIRST(®isters) != NULL) { + symbol_node_t *curnode; + u_int value; + char *tab_str; + char *tab_str2; + + curnode = SLIST_FIRST(®isters); + SLIST_REMOVE_HEAD(®isters, links); + switch(curnode->symbol->type) { + case REGISTER: + case SCBLOC: + case SRAMLOC: + fprintf(ofile, "\n"); + value = curnode->symbol->info.rinfo->address; + tab_str = "\t"; + tab_str2 = "\t\t"; + break; + case ALIAS: + { + symbol_t *parent; + + parent = curnode->symbol->info.ainfo->parent; + value = parent->info.rinfo->address; + tab_str = "\t"; + tab_str2 = "\t\t"; + break; } + case MASK: + case FIELD: + case ENUM: + case ENUM_ENTRY: + value = curnode->symbol->info.finfo->value; + tab_str = "\t\t"; + tab_str2 = "\t"; + break; + default: + value = 0; /* Quiet compiler */ + tab_str = NULL; + tab_str2 = NULL; + stop("symtable_dump: Invalid symbol type " + "encountered", EX_SOFTWARE); + break; + } + fprintf(ofile, "#define%s%-16s%s0x%02x\n", + tab_str, curnode->symbol->name, tab_str2, + value); + free(curnode); + } + fprintf(ofile, "\n\n"); - - fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); + while (SLIST_FIRST(&constants) != NULL) { + symbol_node_t *curnode; + + curnode = SLIST_FIRST(&constants); + SLIST_REMOVE_HEAD(&constants, links); + fprintf(ofile, "#define\t%-8s\t0x%02x\n", + curnode->symbol->name, + curnode->symbol->info.cinfo->value); + free(curnode); + } - for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { - symbol_node_t *curnode; + + fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); - curnode = SLIST_FIRST(&download_constants); - SLIST_REMOVE_HEAD(&download_constants, links); - fprintf(ofile, "#define\t%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.cinfo->value); - free(curnode); - } - fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); - - fprintf(ofile, "\n\n/* Exported Labels */\n"); - - while (SLIST_FIRST(&exported_labels) != NULL) { - symbol_node_t *curnode; - - curnode = SLIST_FIRST(&exported_labels); - SLIST_REMOVE_HEAD(&exported_labels, links); - fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", - curnode->symbol->name, - curnode->symbol->info.linfo->address); - free(curnode); - } + for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { + symbol_node_t *curnode; + + curnode = SLIST_FIRST(&download_constants); + SLIST_REMOVE_HEAD(&download_constants, links); + fprintf(ofile, "#define\t%-8s\t0x%02x\n", + curnode->symbol->name, + curnode->symbol->info.cinfo->value); + free(curnode); + } + fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); + + fprintf(ofile, "\n\n/* Exported Labels */\n"); + + while (SLIST_FIRST(&exported_labels) != NULL) { + symbol_node_t *curnode; + + curnode = SLIST_FIRST(&exported_labels); + SLIST_REMOVE_HEAD(&exported_labels, links); + fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", + curnode->symbol->name, + curnode->symbol->info.linfo->address); + free(curnode); } } diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h --- linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h 2003-08-25 04:44:42.000000000 -0700 @@ -2,6 +2,7 @@ * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions * * Copyright (c) 1997 Justin T. Gibbs. + * Copyright (c) 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,9 +37,9 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#11 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#17 $ * - * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.h,v 1.11.2.3 2002/04/29 19:36:36 gibbs Exp $ + * $FreeBSD$ */ #ifdef __linux__ @@ -53,8 +54,10 @@ ALIAS, SCBLOC, SRAMLOC, + ENUM_ENTRY, + FIELD, MASK, - BIT, + ENUM, CONST, DOWNLOAD_CONST, LABEL, @@ -68,20 +71,22 @@ RW = 0x03 }amode_t; +typedef SLIST_HEAD(symlist, symbol_node) symlist_t; + struct reg_info { - u_int address; - int size; - amode_t mode; - u_int8_t valid_bitmask; - u_int8_t modes; - int typecheck_masks; + u_int address; + int size; + amode_t mode; + symlist_t fields; + uint8_t valid_bitmask; + uint8_t modes; + int typecheck_masks; }; -typedef SLIST_HEAD(symlist, symbol_node) symlist_t; - -struct mask_info { +struct field_info { symlist_t symrefs; - u_int8_t mask; + uint8_t value; + uint8_t mask; }; struct const_info { @@ -125,7 +130,7 @@ symtype type; union { struct reg_info *rinfo; - struct mask_info *minfo; + struct field_info *finfo; struct const_info *cinfo; struct alias_info *ainfo; struct label_info *linfo; @@ -178,25 +183,25 @@ SLIST_HEAD(scope_list, scope); TAILQ_HEAD(scope_tailq, scope); -void symbol_delete __P((symbol_t *symbol)); +void symbol_delete(symbol_t *symbol); -void symtable_open __P((void)); +void symtable_open(void); -void symtable_close __P((void)); +void symtable_close(void); symbol_t * - symtable_get __P((char *name)); + symtable_get(char *name); symbol_node_t * - symlist_search __P((symlist_t *symlist, char *symname)); + symlist_search(symlist_t *symlist, char *symname); void - symlist_add __P((symlist_t *symlist, symbol_t *symbol, int how)); + symlist_add(symlist_t *symlist, symbol_t *symbol, int how); #define SYMLIST_INSERT_HEAD 0x00 #define SYMLIST_SORT 0x01 -void symlist_free __P((symlist_t *symlist)); +void symlist_free(symlist_t *symlist); -void symlist_merge __P((symlist_t *symlist_dest, symlist_t *symlist_src1, - symlist_t *symlist_src2)); -void symtable_dump __P((FILE *ofile)); +void symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, + symlist_t *symlist_src2); +void symtable_dump(FILE *ofile, FILE *dfile); diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aiclib.c linux-2.4.22/drivers/scsi/aic7xxx/aiclib.c --- linux-2.4.21/drivers/scsi/aic7xxx/aiclib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aiclib.c 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1413 @@ +/* + * Implementation of Utility functions for all SCSI device types. + * + * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. + * Copyright (c) 1997, 1998 Kenneth D. Merry. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $ + * $Id$ + */ + +#include +#include +#include +#include + +/* Core SCSI definitions */ +#include "scsi.h" +#include "hosts.h" +#include "aiclib.h" +#include "cam.h" + +#ifndef FALSE +#define FALSE 0 +#endif /* FALSE */ +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef ERESTART +#define ERESTART -1 /* restart syscall */ +#endif +#ifndef EJUSTRETURN +#define EJUSTRETURN -2 /* don't modify regs, just return */ +#endif + +static int ascentrycomp(const void *key, const void *member); +static int senseentrycomp(const void *key, const void *member); +static void fetchtableentries(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *, + const struct sense_key_table_entry **, + const struct asc_table_entry **); +static void * scsibsearch(const void *key, const void *base, size_t nmemb, + size_t size, + int (*compar)(const void *, const void *)); +typedef int (cam_quirkmatch_t)(caddr_t, caddr_t); +static int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, + int str_len); +static caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, + int num_entries, int entry_size, + cam_quirkmatch_t *comp_func); + +#define SCSI_NO_SENSE_STRINGS 1 +#if !defined(SCSI_NO_SENSE_STRINGS) +#define SST(asc, ascq, action, desc) \ + asc, ascq, action, desc +#else +static const char empty_string[] = ""; + +#define SST(asc, ascq, action, desc) \ + asc, ascq, action, empty_string +#endif + +static const struct sense_key_table_entry sense_key_table[] = +{ + { SSD_KEY_NO_SENSE, SS_NOP, "NO SENSE" }, + { SSD_KEY_RECOVERED_ERROR, SS_NOP|SSQ_PRINT_SENSE, "RECOVERED ERROR" }, + { + SSD_KEY_NOT_READY, SS_TUR|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, + "NOT READY" + }, + { SSD_KEY_MEDIUM_ERROR, SS_RDEF, "MEDIUM ERROR" }, + { SSD_KEY_HARDWARE_ERROR, SS_RDEF, "HARDWARE FAILURE" }, + { SSD_KEY_ILLEGAL_REQUEST, SS_FATAL|EINVAL, "ILLEGAL REQUEST" }, + { SSD_KEY_UNIT_ATTENTION, SS_FATAL|ENXIO, "UNIT ATTENTION" }, + { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" }, + { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" }, + { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" }, + { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" }, + { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" }, + { SSD_KEY_EQUAL, SS_NOP, "EQUAL" }, + { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" }, + { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" }, + { SSD_KEY_RESERVED, SS_FATAL|EIO, "RESERVED" } +}; + +static const int sense_key_table_size = + sizeof(sense_key_table)/sizeof(sense_key_table[0]); + +static struct asc_table_entry quantum_fireball_entries[] = { + {SST(0x04, 0x0b, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, initializing cmd. required")} +}; + +static struct asc_table_entry sony_mo_entries[] = { + {SST(0x04, 0x00, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, cause not reportable")} +}; + +static struct scsi_sense_quirk_entry sense_quirk_table[] = { + { + /* + * The Quantum Fireball ST and SE like to return 0x04 0x0b when + * they really should return 0x04 0x02. 0x04,0x0b isn't + * defined in any SCSI spec, and it isn't mentioned in the + * hardware manual for these drives. + */ + {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"}, + /*num_sense_keys*/0, + sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry), + /*sense key entries*/NULL, + quantum_fireball_entries + }, + { + /* + * This Sony MO drive likes to return 0x04, 0x00 when it + * isn't spun up. + */ + {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"}, + /*num_sense_keys*/0, + sizeof(sony_mo_entries)/sizeof(struct asc_table_entry), + /*sense key entries*/NULL, + sony_mo_entries + } +}; + +static const int sense_quirk_table_size = + sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]); + +static struct asc_table_entry asc_table[] = { +/* + * From File: ASC-NUM.TXT + * SCSI ASC/ASCQ Assignments + * Numeric Sorted Listing + * as of 5/12/97 + * + * D - DIRECT ACCESS DEVICE (SBC) device column key + * .T - SEQUENTIAL ACCESS DEVICE (SSC) ------------------- + * . L - PRINTER DEVICE (SSC) blank = reserved + * . P - PROCESSOR DEVICE (SPC) not blank = allowed + * . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC) + * . . R - CD DEVICE (MMC) + * . . S - SCANNER DEVICE (SGC) + * . . .O - OPTICAL MEMORY DEVICE (SBC) + * . . . M - MEDIA CHANGER DEVICE (SMC) + * . . . C - COMMUNICATION DEVICE (SSC) + * . . . .A - STORAGE ARRAY DEVICE (SCC) + * . . . . E - ENCLOSURE SERVICES DEVICE (SES) + * DTLPWRSOMCAE ASC ASCQ Action Description + * ------------ ---- ---- ------ -----------------------------------*/ +/* DTLPWRSOMCAE */{SST(0x00, 0x00, SS_NOP, + "No additional sense information") }, +/* T S */{SST(0x00, 0x01, SS_RDEF, + "Filemark detected") }, +/* T S */{SST(0x00, 0x02, SS_RDEF, + "End-of-partition/medium detected") }, +/* T */{SST(0x00, 0x03, SS_RDEF, + "Setmark detected") }, +/* T S */{SST(0x00, 0x04, SS_RDEF, + "Beginning-of-partition/medium detected") }, +/* T S */{SST(0x00, 0x05, SS_RDEF, + "End-of-data detected") }, +/* DTLPWRSOMCAE */{SST(0x00, 0x06, SS_RDEF, + "I/O process terminated") }, +/* R */{SST(0x00, 0x11, SS_FATAL|EBUSY, + "Audio play operation in progress") }, +/* R */{SST(0x00, 0x12, SS_NOP, + "Audio play operation paused") }, +/* R */{SST(0x00, 0x13, SS_NOP, + "Audio play operation successfully completed") }, +/* R */{SST(0x00, 0x14, SS_RDEF, + "Audio play operation stopped due to error") }, +/* R */{SST(0x00, 0x15, SS_NOP, + "No current audio status to return") }, +/* DTLPWRSOMCAE */{SST(0x00, 0x16, SS_FATAL|EBUSY, + "Operation in progress") }, +/* DTL WRSOM AE */{SST(0x00, 0x17, SS_RDEF, + "Cleaning requested") }, +/* D W O */{SST(0x01, 0x00, SS_RDEF, + "No index/sector signal") }, +/* D WR OM */{SST(0x02, 0x00, SS_RDEF, + "No seek complete") }, +/* DTL W SO */{SST(0x03, 0x00, SS_RDEF, + "Peripheral device write fault") }, +/* T */{SST(0x03, 0x01, SS_RDEF, + "No write current") }, +/* T */{SST(0x03, 0x02, SS_RDEF, + "Excessive write errors") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x00, + SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EIO, + "Logical unit not ready, cause not reportable") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x01, + SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, + "Logical unit is in process of becoming ready") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x02, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, initializing cmd. required") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x03, SS_FATAL|ENXIO, + "Logical unit not ready, manual intervention required")}, +/* DTL O */{SST(0x04, 0x04, SS_FATAL|EBUSY, + "Logical unit not ready, format in progress") }, +/* DT W OMCA */{SST(0x04, 0x05, SS_FATAL|EBUSY, + "Logical unit not ready, rebuild in progress") }, +/* DT W OMCA */{SST(0x04, 0x06, SS_FATAL|EBUSY, + "Logical unit not ready, recalculation in progress") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x07, SS_FATAL|EBUSY, + "Logical unit not ready, operation in progress") }, +/* R */{SST(0x04, 0x08, SS_FATAL|EBUSY, + "Logical unit not ready, long write in progress") }, +/* DTL WRSOMCAE */{SST(0x05, 0x00, SS_RDEF, + "Logical unit does not respond to selection") }, +/* D WR OM */{SST(0x06, 0x00, SS_RDEF, + "No reference position found") }, +/* DTL WRSOM */{SST(0x07, 0x00, SS_RDEF, + "Multiple peripheral devices selected") }, +/* DTL WRSOMCAE */{SST(0x08, 0x00, SS_RDEF, + "Logical unit communication failure") }, +/* DTL WRSOMCAE */{SST(0x08, 0x01, SS_RDEF, + "Logical unit communication time-out") }, +/* DTL WRSOMCAE */{SST(0x08, 0x02, SS_RDEF, + "Logical unit communication parity error") }, +/* DT R OM */{SST(0x08, 0x03, SS_RDEF, + "Logical unit communication crc error (ultra-dma/32)")}, +/* DT WR O */{SST(0x09, 0x00, SS_RDEF, + "Track following error") }, +/* WR O */{SST(0x09, 0x01, SS_RDEF, + "Tracking servo failure") }, +/* WR O */{SST(0x09, 0x02, SS_RDEF, + "Focus servo failure") }, +/* WR O */{SST(0x09, 0x03, SS_RDEF, + "Spindle servo failure") }, +/* DT WR O */{SST(0x09, 0x04, SS_RDEF, + "Head select fault") }, +/* DTLPWRSOMCAE */{SST(0x0A, 0x00, SS_FATAL|ENOSPC, + "Error log overflow") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x00, SS_RDEF, + "Warning") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x01, SS_RDEF, + "Specified temperature exceeded") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x02, SS_RDEF, + "Enclosure degraded") }, +/* T RS */{SST(0x0C, 0x00, SS_RDEF, + "Write error") }, +/* D W O */{SST(0x0C, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Write error - recovered with auto reallocation") }, +/* D W O */{SST(0x0C, 0x02, SS_RDEF, + "Write error - auto reallocation failed") }, +/* D W O */{SST(0x0C, 0x03, SS_RDEF, + "Write error - recommend reassignment") }, +/* DT W O */{SST(0x0C, 0x04, SS_RDEF, + "Compression check miscompare error") }, +/* DT W O */{SST(0x0C, 0x05, SS_RDEF, + "Data expansion occurred during compression") }, +/* DT W O */{SST(0x0C, 0x06, SS_RDEF, + "Block not compressible") }, +/* R */{SST(0x0C, 0x07, SS_RDEF, + "Write error - recovery needed") }, +/* R */{SST(0x0C, 0x08, SS_RDEF, + "Write error - recovery failed") }, +/* R */{SST(0x0C, 0x09, SS_RDEF, + "Write error - loss of streaming") }, +/* R */{SST(0x0C, 0x0A, SS_RDEF, + "Write error - padding blocks added") }, +/* D W O */{SST(0x10, 0x00, SS_RDEF, + "ID CRC or ECC error") }, +/* DT WRSO */{SST(0x11, 0x00, SS_RDEF, + "Unrecovered read error") }, +/* DT W SO */{SST(0x11, 0x01, SS_RDEF, + "Read retries exhausted") }, +/* DT W SO */{SST(0x11, 0x02, SS_RDEF, + "Error too long to correct") }, +/* DT W SO */{SST(0x11, 0x03, SS_RDEF, + "Multiple read errors") }, +/* D W O */{SST(0x11, 0x04, SS_RDEF, + "Unrecovered read error - auto reallocate failed") }, +/* WR O */{SST(0x11, 0x05, SS_RDEF, + "L-EC uncorrectable error") }, +/* WR O */{SST(0x11, 0x06, SS_RDEF, + "CIRC unrecovered error") }, +/* W O */{SST(0x11, 0x07, SS_RDEF, + "Data re-synchronization error") }, +/* T */{SST(0x11, 0x08, SS_RDEF, + "Incomplete block read") }, +/* T */{SST(0x11, 0x09, SS_RDEF, + "No gap found") }, +/* DT O */{SST(0x11, 0x0A, SS_RDEF, + "Miscorrected error") }, +/* D W O */{SST(0x11, 0x0B, SS_RDEF, + "Unrecovered read error - recommend reassignment") }, +/* D W O */{SST(0x11, 0x0C, SS_RDEF, + "Unrecovered read error - recommend rewrite the data")}, +/* DT WR O */{SST(0x11, 0x0D, SS_RDEF, + "De-compression CRC error") }, +/* DT WR O */{SST(0x11, 0x0E, SS_RDEF, + "Cannot decompress using declared algorithm") }, +/* R */{SST(0x11, 0x0F, SS_RDEF, + "Error reading UPC/EAN number") }, +/* R */{SST(0x11, 0x10, SS_RDEF, + "Error reading ISRC number") }, +/* R */{SST(0x11, 0x11, SS_RDEF, + "Read error - loss of streaming") }, +/* D W O */{SST(0x12, 0x00, SS_RDEF, + "Address mark not found for id field") }, +/* D W O */{SST(0x13, 0x00, SS_RDEF, + "Address mark not found for data field") }, +/* DTL WRSO */{SST(0x14, 0x00, SS_RDEF, + "Recorded entity not found") }, +/* DT WR O */{SST(0x14, 0x01, SS_RDEF, + "Record not found") }, +/* T */{SST(0x14, 0x02, SS_RDEF, + "Filemark or setmark not found") }, +/* T */{SST(0x14, 0x03, SS_RDEF, + "End-of-data not found") }, +/* T */{SST(0x14, 0x04, SS_RDEF, + "Block sequence error") }, +/* DT W O */{SST(0x14, 0x05, SS_RDEF, + "Record not found - recommend reassignment") }, +/* DT W O */{SST(0x14, 0x06, SS_RDEF, + "Record not found - data auto-reallocated") }, +/* DTL WRSOM */{SST(0x15, 0x00, SS_RDEF, + "Random positioning error") }, +/* DTL WRSOM */{SST(0x15, 0x01, SS_RDEF, + "Mechanical positioning error") }, +/* DT WR O */{SST(0x15, 0x02, SS_RDEF, + "Positioning error detected by read of medium") }, +/* D W O */{SST(0x16, 0x00, SS_RDEF, + "Data synchronization mark error") }, +/* D W O */{SST(0x16, 0x01, SS_RDEF, + "Data sync error - data rewritten") }, +/* D W O */{SST(0x16, 0x02, SS_RDEF, + "Data sync error - recommend rewrite") }, +/* D W O */{SST(0x16, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Data sync error - data auto-reallocated") }, +/* D W O */{SST(0x16, 0x04, SS_RDEF, + "Data sync error - recommend reassignment") }, +/* DT WRSO */{SST(0x17, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with no error correction applied") }, +/* DT WRSO */{SST(0x17, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with retries") }, +/* DT WR O */{SST(0x17, 0x02, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with positive head offset") }, +/* DT WR O */{SST(0x17, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with negative head offset") }, +/* WR O */{SST(0x17, 0x04, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with retries and/or CIRC applied") }, +/* D WR O */{SST(0x17, 0x05, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data using previous sector id") }, +/* D W O */{SST(0x17, 0x06, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - data auto-reallocated") }, +/* D W O */{SST(0x17, 0x07, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - recommend reassignment")}, +/* D W O */{SST(0x17, 0x08, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - recommend rewrite") }, +/* D W O */{SST(0x17, 0x09, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - data rewritten") }, +/* D W O */{SST(0x18, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with error correction applied") }, +/* D WR O */{SST(0x18, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with error corr. & retries applied") }, +/* D WR O */{SST(0x18, 0x02, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - data auto-reallocated") }, +/* R */{SST(0x18, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with CIRC") }, +/* R */{SST(0x18, 0x04, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with L-EC") }, +/* D WR O */{SST(0x18, 0x05, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - recommend reassignment") }, +/* D WR O */{SST(0x18, 0x06, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - recommend rewrite") }, +/* D W O */{SST(0x18, 0x07, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with ECC - data rewritten") }, +/* D O */{SST(0x19, 0x00, SS_RDEF, + "Defect list error") }, +/* D O */{SST(0x19, 0x01, SS_RDEF, + "Defect list not available") }, +/* D O */{SST(0x19, 0x02, SS_RDEF, + "Defect list error in primary list") }, +/* D O */{SST(0x19, 0x03, SS_RDEF, + "Defect list error in grown list") }, +/* DTLPWRSOMCAE */{SST(0x1A, 0x00, SS_RDEF, + "Parameter list length error") }, +/* DTLPWRSOMCAE */{SST(0x1B, 0x00, SS_RDEF, + "Synchronous data transfer error") }, +/* D O */{SST(0x1C, 0x00, SS_RDEF, + "Defect list not found") }, +/* D O */{SST(0x1C, 0x01, SS_RDEF, + "Primary defect list not found") }, +/* D O */{SST(0x1C, 0x02, SS_RDEF, + "Grown defect list not found") }, +/* D W O */{SST(0x1D, 0x00, SS_FATAL, + "Miscompare during verify operation" )}, +/* D W O */{SST(0x1E, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered id with ecc correction") }, +/* D O */{SST(0x1F, 0x00, SS_RDEF, + "Partial defect list transfer") }, +/* DTLPWRSOMCAE */{SST(0x20, 0x00, SS_FATAL|EINVAL, + "Invalid command operation code") }, +/* DT WR OM */{SST(0x21, 0x00, SS_FATAL|EINVAL, + "Logical block address out of range" )}, +/* DT WR OM */{SST(0x21, 0x01, SS_FATAL|EINVAL, + "Invalid element address") }, +/* D */{SST(0x22, 0x00, SS_FATAL|EINVAL, + "Illegal function") }, /* Deprecated. Use 20 00, 24 00, or 26 00 instead */ +/* DTLPWRSOMCAE */{SST(0x24, 0x00, SS_FATAL|EINVAL, + "Invalid field in CDB") }, +/* DTLPWRSOMCAE */{SST(0x25, 0x00, SS_FATAL|ENXIO, + "Logical unit not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x00, SS_FATAL|EINVAL, + "Invalid field in parameter list") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x01, SS_FATAL|EINVAL, + "Parameter not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x02, SS_FATAL|EINVAL, + "Parameter value invalid") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x03, SS_FATAL|EINVAL, + "Threshold parameters not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x04, SS_FATAL|EINVAL, + "Invalid release of active persistent reservation") }, +/* DT W O */{SST(0x27, 0x00, SS_FATAL|EACCES, + "Write protected") }, +/* DT W O */{SST(0x27, 0x01, SS_FATAL|EACCES, + "Hardware write protected") }, +/* DT W O */{SST(0x27, 0x02, SS_FATAL|EACCES, + "Logical unit software write protected") }, +/* T */{SST(0x27, 0x03, SS_FATAL|EACCES, + "Associated write protect") }, +/* T */{SST(0x27, 0x04, SS_FATAL|EACCES, + "Persistent write protect") }, +/* T */{SST(0x27, 0x05, SS_FATAL|EACCES, + "Permanent write protect") }, +/* DTLPWRSOMCAE */{SST(0x28, 0x00, SS_RDEF, + "Not ready to ready change, medium may have changed") }, +/* DTLPWRSOMCAE */{SST(0x28, 0x01, SS_FATAL|ENXIO, + "Import or export element accessed") }, +/* + * XXX JGibbs - All of these should use the same errno, but I don't think + * ENXIO is the correct choice. Should we borrow from the networking + * errnos? ECONNRESET anyone? + */ +/* DTLPWRSOMCAE */{SST(0x29, 0x00, SS_RDEF, + "Power on, reset, or bus device reset occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x01, SS_RDEF, + "Power on occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x02, SS_RDEF, + "Scsi bus reset occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x03, SS_RDEF, + "Bus device reset function occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x04, SS_RDEF, + "Device internal reset") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x05, SS_RDEF, + "Transceiver mode changed to single-ended") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x06, SS_RDEF, + "Transceiver mode changed to LVD") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x00, SS_RDEF, + "Parameters changed") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x01, SS_RDEF, + "Mode parameters changed") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x02, SS_RDEF, + "Log parameters changed") }, +/* DTLPWRSOMCAE */{SST(0x2A, 0x03, SS_RDEF, + "Reservations preempted") }, +/* DTLPWRSO C */{SST(0x2B, 0x00, SS_RDEF, + "Copy cannot execute since host cannot disconnect") }, +/* DTLPWRSOMCAE */{SST(0x2C, 0x00, SS_RDEF, + "Command sequence error") }, +/* S */{SST(0x2C, 0x01, SS_RDEF, + "Too many windows specified") }, +/* S */{SST(0x2C, 0x02, SS_RDEF, + "Invalid combination of windows specified") }, +/* R */{SST(0x2C, 0x03, SS_RDEF, + "Current program area is not empty") }, +/* R */{SST(0x2C, 0x04, SS_RDEF, + "Current program area is empty") }, +/* T */{SST(0x2D, 0x00, SS_RDEF, + "Overwrite error on update in place") }, +/* DTLPWRSOMCAE */{SST(0x2F, 0x00, SS_RDEF, + "Commands cleared by another initiator") }, +/* DT WR OM */{SST(0x30, 0x00, SS_RDEF, + "Incompatible medium installed") }, +/* DT WR O */{SST(0x30, 0x01, SS_RDEF, + "Cannot read medium - unknown format") }, +/* DT WR O */{SST(0x30, 0x02, SS_RDEF, + "Cannot read medium - incompatible format") }, +/* DT */{SST(0x30, 0x03, SS_RDEF, + "Cleaning cartridge installed") }, +/* DT WR O */{SST(0x30, 0x04, SS_RDEF, + "Cannot write medium - unknown format") }, +/* DT WR O */{SST(0x30, 0x05, SS_RDEF, + "Cannot write medium - incompatible format") }, +/* DT W O */{SST(0x30, 0x06, SS_RDEF, + "Cannot format medium - incompatible medium") }, +/* DTL WRSOM AE */{SST(0x30, 0x07, SS_RDEF, + "Cleaning failure") }, +/* R */{SST(0x30, 0x08, SS_RDEF, + "Cannot write - application code mismatch") }, +/* R */{SST(0x30, 0x09, SS_RDEF, + "Current session not fixated for append") }, +/* DT WR O */{SST(0x31, 0x00, SS_RDEF, + "Medium format corrupted") }, +/* D L R O */{SST(0x31, 0x01, SS_RDEF, + "Format command failed") }, +/* D W O */{SST(0x32, 0x00, SS_RDEF, + "No defect spare location available") }, +/* D W O */{SST(0x32, 0x01, SS_RDEF, + "Defect list update failure") }, +/* T */{SST(0x33, 0x00, SS_RDEF, + "Tape length error") }, +/* DTLPWRSOMCAE */{SST(0x34, 0x00, SS_RDEF, + "Enclosure failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x00, SS_RDEF, + "Enclosure services failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x01, SS_RDEF, + "Unsupported enclosure function") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x02, SS_RDEF, + "Enclosure services unavailable") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x03, SS_RDEF, + "Enclosure services transfer failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x04, SS_RDEF, + "Enclosure services transfer refused") }, +/* L */{SST(0x36, 0x00, SS_RDEF, + "Ribbon, ink, or toner failure") }, +/* DTL WRSOMCAE */{SST(0x37, 0x00, SS_RDEF, + "Rounded parameter") }, +/* DTL WRSOMCAE */{SST(0x39, 0x00, SS_RDEF, + "Saving parameters not supported") }, +/* DTL WRSOM */{SST(0x3A, 0x00, SS_NOP, + "Medium not present") }, +/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, + "Medium not present - tray closed") }, +/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, + "Medium not present - tray open") }, +/* DT WR OM */{SST(0x3A, 0x03, SS_NOP, + "Medium not present - Loadable") }, +/* DT WR OM */{SST(0x3A, 0x04, SS_NOP, + "Medium not present - medium auxiliary " + "memory accessible") }, +/* DT WR OM */{SST(0x3A, 0xFF, SS_NOP, NULL) },/* Range 0x05->0xFF */ +/* TL */{SST(0x3B, 0x00, SS_RDEF, + "Sequential positioning error") }, +/* T */{SST(0x3B, 0x01, SS_RDEF, + "Tape position error at beginning-of-medium") }, +/* T */{SST(0x3B, 0x02, SS_RDEF, + "Tape position error at end-of-medium") }, +/* L */{SST(0x3B, 0x03, SS_RDEF, + "Tape or electronic vertical forms unit not ready") }, +/* L */{SST(0x3B, 0x04, SS_RDEF, + "Slew failure") }, +/* L */{SST(0x3B, 0x05, SS_RDEF, + "Paper jam") }, +/* L */{SST(0x3B, 0x06, SS_RDEF, + "Failed to sense top-of-form") }, +/* L */{SST(0x3B, 0x07, SS_RDEF, + "Failed to sense bottom-of-form") }, +/* T */{SST(0x3B, 0x08, SS_RDEF, + "Reposition error") }, +/* S */{SST(0x3B, 0x09, SS_RDEF, + "Read past end of medium") }, +/* S */{SST(0x3B, 0x0A, SS_RDEF, + "Read past beginning of medium") }, +/* S */{SST(0x3B, 0x0B, SS_RDEF, + "Position past end of medium") }, +/* T S */{SST(0x3B, 0x0C, SS_RDEF, + "Position past beginning of medium") }, +/* DT WR OM */{SST(0x3B, 0x0D, SS_FATAL|ENOSPC, + "Medium destination element full") }, +/* DT WR OM */{SST(0x3B, 0x0E, SS_RDEF, + "Medium source element empty") }, +/* R */{SST(0x3B, 0x0F, SS_RDEF, + "End of medium reached") }, +/* DT WR OM */{SST(0x3B, 0x11, SS_RDEF, + "Medium magazine not accessible") }, +/* DT WR OM */{SST(0x3B, 0x12, SS_RDEF, + "Medium magazine removed") }, +/* DT WR OM */{SST(0x3B, 0x13, SS_RDEF, + "Medium magazine inserted") }, +/* DT WR OM */{SST(0x3B, 0x14, SS_RDEF, + "Medium magazine locked") }, +/* DT WR OM */{SST(0x3B, 0x15, SS_RDEF, + "Medium magazine unlocked") }, +/* DTLPWRSOMCAE */{SST(0x3D, 0x00, SS_RDEF, + "Invalid bits in identify message") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x00, SS_RDEF, + "Logical unit has not self-configured yet") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x01, SS_RDEF, + "Logical unit failure") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x02, SS_RDEF, + "Timeout on logical unit") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x00, SS_RDEF, + "Target operating conditions have changed") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x01, SS_RDEF, + "Microcode has been changed") }, +/* DTLPWRSOMC */{SST(0x3F, 0x02, SS_RDEF, + "Changed operating definition") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x03, SS_INQ_REFRESH|SSQ_DECREMENT_COUNT, + "Inquiry data has changed") }, +/* DT WR OMCAE */{SST(0x3F, 0x04, SS_RDEF, + "Component device attached") }, +/* DT WR OMCAE */{SST(0x3F, 0x05, SS_RDEF, + "Device identifier changed") }, +/* DT WR OMCAE */{SST(0x3F, 0x06, SS_RDEF, + "Redundancy group created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x07, SS_RDEF, + "Redundancy group deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x08, SS_RDEF, + "Spare created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x09, SS_RDEF, + "Spare deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x0A, SS_RDEF, + "Volume set created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x0B, SS_RDEF, + "Volume set deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x0C, SS_RDEF, + "Volume set deassigned") }, +/* DT WR OMCAE */{SST(0x3F, 0x0D, SS_RDEF, + "Volume set reassigned") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x0E, SS_RDEF, + "Reported luns data has changed") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x0F, SS_RETRY|SSQ_DECREMENT_COUNT + | SSQ_DELAY_RANDOM|EBUSY, + "Echo buffer overwritten") }, +/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, "Medium Loadable") }, +/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, + "Medium auxiliary memory accessible") }, +/* D */{SST(0x40, 0x00, SS_RDEF, + "Ram failure") }, /* deprecated - use 40 NN instead */ +/* DTLPWRSOMCAE */{SST(0x40, 0x80, SS_RDEF, + "Diagnostic failure: ASCQ = Component ID") }, +/* DTLPWRSOMCAE */{SST(0x40, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) },/* Range 0x80->0xFF */ +/* D */{SST(0x41, 0x00, SS_RDEF, + "Data path failure") }, /* deprecated - use 40 NN instead */ +/* D */{SST(0x42, 0x00, SS_RDEF, + "Power-on or self-test failure") }, /* deprecated - use 40 NN instead */ +/* DTLPWRSOMCAE */{SST(0x43, 0x00, SS_RDEF, + "Message error") }, +/* DTLPWRSOMCAE */{SST(0x44, 0x00, SS_RDEF, + "Internal target failure") }, +/* DTLPWRSOMCAE */{SST(0x45, 0x00, SS_RDEF, + "Select or reselect failure") }, +/* DTLPWRSOMC */{SST(0x46, 0x00, SS_RDEF, + "Unsuccessful soft reset") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x00, SS_RDEF|SSQ_FALLBACK, + "SCSI parity error") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x01, SS_RDEF|SSQ_FALLBACK, + "Data Phase CRC error detected") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x02, SS_RDEF|SSQ_FALLBACK, + "SCSI parity error detected during ST data phase") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x03, SS_RDEF|SSQ_FALLBACK, + "Information Unit iuCRC error") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x04, SS_RDEF|SSQ_FALLBACK, + "Asynchronous information protection error detected") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x05, SS_RDEF|SSQ_FALLBACK, + "Protocol server CRC error") }, +/* DTLPWRSOMCAE */{SST(0x48, 0x00, SS_RDEF|SSQ_FALLBACK, + "Initiator detected error message received") }, +/* DTLPWRSOMCAE */{SST(0x49, 0x00, SS_RDEF, + "Invalid message error") }, +/* DTLPWRSOMCAE */{SST(0x4A, 0x00, SS_RDEF, + "Command phase error") }, +/* DTLPWRSOMCAE */{SST(0x4B, 0x00, SS_RDEF, + "Data phase error") }, +/* DTLPWRSOMCAE */{SST(0x4C, 0x00, SS_RDEF, + "Logical unit failed self-configuration") }, +/* DTLPWRSOMCAE */{SST(0x4D, 0x00, SS_RDEF, + "Tagged overlapped commands: ASCQ = Queue tag ID") }, +/* DTLPWRSOMCAE */{SST(0x4D, 0xFF, SS_RDEF|SSQ_RANGE, + NULL)}, /* Range 0x00->0xFF */ +/* DTLPWRSOMCAE */{SST(0x4E, 0x00, SS_RDEF, + "Overlapped commands attempted") }, +/* T */{SST(0x50, 0x00, SS_RDEF, + "Write append error") }, +/* T */{SST(0x50, 0x01, SS_RDEF, + "Write append position error") }, +/* T */{SST(0x50, 0x02, SS_RDEF, + "Position error related to timing") }, +/* T O */{SST(0x51, 0x00, SS_RDEF, + "Erase failure") }, +/* T */{SST(0x52, 0x00, SS_RDEF, + "Cartridge fault") }, +/* DTL WRSOM */{SST(0x53, 0x00, SS_RDEF, + "Media load or eject failed") }, +/* T */{SST(0x53, 0x01, SS_RDEF, + "Unload tape failure") }, +/* DT WR OM */{SST(0x53, 0x02, SS_RDEF, + "Medium removal prevented") }, +/* P */{SST(0x54, 0x00, SS_RDEF, + "Scsi to host system interface failure") }, +/* P */{SST(0x55, 0x00, SS_RDEF, + "System resource failure") }, +/* D O */{SST(0x55, 0x01, SS_FATAL|ENOSPC, + "System buffer full") }, +/* R */{SST(0x57, 0x00, SS_RDEF, + "Unable to recover table-of-contents") }, +/* O */{SST(0x58, 0x00, SS_RDEF, + "Generation does not exist") }, +/* O */{SST(0x59, 0x00, SS_RDEF, + "Updated block read") }, +/* DTLPWRSOM */{SST(0x5A, 0x00, SS_RDEF, + "Operator request or state change input") }, +/* DT WR OM */{SST(0x5A, 0x01, SS_RDEF, + "Operator medium removal request") }, +/* DT W O */{SST(0x5A, 0x02, SS_RDEF, + "Operator selected write protect") }, +/* DT W O */{SST(0x5A, 0x03, SS_RDEF, + "Operator selected write permit") }, +/* DTLPWRSOM */{SST(0x5B, 0x00, SS_RDEF, + "Log exception") }, +/* DTLPWRSOM */{SST(0x5B, 0x01, SS_RDEF, + "Threshold condition met") }, +/* DTLPWRSOM */{SST(0x5B, 0x02, SS_RDEF, + "Log counter at maximum") }, +/* DTLPWRSOM */{SST(0x5B, 0x03, SS_RDEF, + "Log list codes exhausted") }, +/* D O */{SST(0x5C, 0x00, SS_RDEF, + "RPL status change") }, +/* D O */{SST(0x5C, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Spindles synchronized") }, +/* D O */{SST(0x5C, 0x02, SS_RDEF, + "Spindles not synchronized") }, +/* DTLPWRSOMCAE */{SST(0x5D, 0x00, SS_RDEF, + "Failure prediction threshold exceeded") }, +/* DTLPWRSOMCAE */{SST(0x5D, 0xFF, SS_RDEF, + "Failure prediction threshold exceeded (false)") }, +/* DTLPWRSO CA */{SST(0x5E, 0x00, SS_RDEF, + "Low power condition on") }, +/* DTLPWRSO CA */{SST(0x5E, 0x01, SS_RDEF, + "Idle condition activated by timer") }, +/* DTLPWRSO CA */{SST(0x5E, 0x02, SS_RDEF, + "Standby condition activated by timer") }, +/* DTLPWRSO CA */{SST(0x5E, 0x03, SS_RDEF, + "Idle condition activated by command") }, +/* DTLPWRSO CA */{SST(0x5E, 0x04, SS_RDEF, + "Standby condition activated by command") }, +/* S */{SST(0x60, 0x00, SS_RDEF, + "Lamp failure") }, +/* S */{SST(0x61, 0x00, SS_RDEF, + "Video acquisition error") }, +/* S */{SST(0x61, 0x01, SS_RDEF, + "Unable to acquire video") }, +/* S */{SST(0x61, 0x02, SS_RDEF, + "Out of focus") }, +/* S */{SST(0x62, 0x00, SS_RDEF, + "Scan head positioning error") }, +/* R */{SST(0x63, 0x00, SS_RDEF, + "End of user area encountered on this track") }, +/* R */{SST(0x63, 0x01, SS_FATAL|ENOSPC, + "Packet does not fit in available space") }, +/* R */{SST(0x64, 0x00, SS_RDEF, + "Illegal mode for this track") }, +/* R */{SST(0x64, 0x01, SS_RDEF, + "Invalid packet size") }, +/* DTLPWRSOMCAE */{SST(0x65, 0x00, SS_RDEF, + "Voltage fault") }, +/* S */{SST(0x66, 0x00, SS_RDEF, + "Automatic document feeder cover up") }, +/* S */{SST(0x66, 0x01, SS_RDEF, + "Automatic document feeder lift up") }, +/* S */{SST(0x66, 0x02, SS_RDEF, + "Document jam in automatic document feeder") }, +/* S */{SST(0x66, 0x03, SS_RDEF, + "Document miss feed automatic in document feeder") }, +/* A */{SST(0x67, 0x00, SS_RDEF, + "Configuration failure") }, +/* A */{SST(0x67, 0x01, SS_RDEF, + "Configuration of incapable logical units failed") }, +/* A */{SST(0x67, 0x02, SS_RDEF, + "Add logical unit failed") }, +/* A */{SST(0x67, 0x03, SS_RDEF, + "Modification of logical unit failed") }, +/* A */{SST(0x67, 0x04, SS_RDEF, + "Exchange of logical unit failed") }, +/* A */{SST(0x67, 0x05, SS_RDEF, + "Remove of logical unit failed") }, +/* A */{SST(0x67, 0x06, SS_RDEF, + "Attachment of logical unit failed") }, +/* A */{SST(0x67, 0x07, SS_RDEF, + "Creation of logical unit failed") }, +/* A */{SST(0x68, 0x00, SS_RDEF, + "Logical unit not configured") }, +/* A */{SST(0x69, 0x00, SS_RDEF, + "Data loss on logical unit") }, +/* A */{SST(0x69, 0x01, SS_RDEF, + "Multiple logical unit failures") }, +/* A */{SST(0x69, 0x02, SS_RDEF, + "Parity/data mismatch") }, +/* A */{SST(0x6A, 0x00, SS_RDEF, + "Informational, refer to log") }, +/* A */{SST(0x6B, 0x00, SS_RDEF, + "State change has occurred") }, +/* A */{SST(0x6B, 0x01, SS_RDEF, + "Redundancy level got better") }, +/* A */{SST(0x6B, 0x02, SS_RDEF, + "Redundancy level got worse") }, +/* A */{SST(0x6C, 0x00, SS_RDEF, + "Rebuild failure occurred") }, +/* A */{SST(0x6D, 0x00, SS_RDEF, + "Recalculate failure occurred") }, +/* A */{SST(0x6E, 0x00, SS_RDEF, + "Command to logical unit failed") }, +/* T */{SST(0x70, 0x00, SS_RDEF, + "Decompression exception short: ASCQ = Algorithm ID") }, +/* T */{SST(0x70, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) }, /* Range 0x00 -> 0xFF */ +/* T */{SST(0x71, 0x00, SS_RDEF, + "Decompression exception long: ASCQ = Algorithm ID") }, +/* T */{SST(0x71, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) }, /* Range 0x00 -> 0xFF */ +/* R */{SST(0x72, 0x00, SS_RDEF, + "Session fixation error") }, +/* R */{SST(0x72, 0x01, SS_RDEF, + "Session fixation error writing lead-in") }, +/* R */{SST(0x72, 0x02, SS_RDEF, + "Session fixation error writing lead-out") }, +/* R */{SST(0x72, 0x03, SS_RDEF, + "Session fixation error - incomplete track in session") }, +/* R */{SST(0x72, 0x04, SS_RDEF, + "Empty or partially written reserved track") }, +/* R */{SST(0x73, 0x00, SS_RDEF, + "CD control error") }, +/* R */{SST(0x73, 0x01, SS_RDEF, + "Power calibration area almost full") }, +/* R */{SST(0x73, 0x02, SS_FATAL|ENOSPC, + "Power calibration area is full") }, +/* R */{SST(0x73, 0x03, SS_RDEF, + "Power calibration area error") }, +/* R */{SST(0x73, 0x04, SS_RDEF, + "Program memory area update failure") }, +/* R */{SST(0x73, 0x05, SS_RDEF, + "program memory area is full") } +}; + +static const int asc_table_size = sizeof(asc_table)/sizeof(asc_table[0]); + +struct asc_key +{ + int asc; + int ascq; +}; + +static int +ascentrycomp(const void *key, const void *member) +{ + int asc; + int ascq; + const struct asc_table_entry *table_entry; + + asc = ((const struct asc_key *)key)->asc; + ascq = ((const struct asc_key *)key)->ascq; + table_entry = (const struct asc_table_entry *)member; + + if (asc >= table_entry->asc) { + + if (asc > table_entry->asc) + return (1); + + if (ascq <= table_entry->ascq) { + /* Check for ranges */ + if (ascq == table_entry->ascq + || ((table_entry->action & SSQ_RANGE) != 0 + && ascq >= (table_entry - 1)->ascq)) + return (0); + return (-1); + } + return (1); + } + return (-1); +} + +static int +senseentrycomp(const void *key, const void *member) +{ + int sense_key; + const struct sense_key_table_entry *table_entry; + + sense_key = *((const int *)key); + table_entry = (const struct sense_key_table_entry *)member; + + if (sense_key >= table_entry->sense_key) { + if (sense_key == table_entry->sense_key) + return (0); + return (1); + } + return (-1); +} + +static void +fetchtableentries(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *inq_data, + const struct sense_key_table_entry **sense_entry, + const struct asc_table_entry **asc_entry) +{ + void *match; + const struct asc_table_entry *asc_tables[2]; + const struct sense_key_table_entry *sense_tables[2]; + struct asc_key asc_ascq; + size_t asc_tables_size[2]; + size_t sense_tables_size[2]; + int num_asc_tables; + int num_sense_tables; + int i; + + /* Default to failure */ + *sense_entry = NULL; + *asc_entry = NULL; + match = NULL; + if (inq_data != NULL) + match = cam_quirkmatch((void *)inq_data, + (void *)sense_quirk_table, + sense_quirk_table_size, + sizeof(*sense_quirk_table), + aic_inquiry_match); + + if (match != NULL) { + struct scsi_sense_quirk_entry *quirk; + + quirk = (struct scsi_sense_quirk_entry *)match; + asc_tables[0] = quirk->asc_info; + asc_tables_size[0] = quirk->num_ascs; + asc_tables[1] = asc_table; + asc_tables_size[1] = asc_table_size; + num_asc_tables = 2; + sense_tables[0] = quirk->sense_key_info; + sense_tables_size[0] = quirk->num_sense_keys; + sense_tables[1] = sense_key_table; + sense_tables_size[1] = sense_key_table_size; + num_sense_tables = 2; + } else { + asc_tables[0] = asc_table; + asc_tables_size[0] = asc_table_size; + num_asc_tables = 1; + sense_tables[0] = sense_key_table; + sense_tables_size[0] = sense_key_table_size; + num_sense_tables = 1; + } + + asc_ascq.asc = asc; + asc_ascq.ascq = ascq; + for (i = 0; i < num_asc_tables; i++) { + void *found_entry; + + found_entry = scsibsearch(&asc_ascq, asc_tables[i], + asc_tables_size[i], + sizeof(**asc_tables), + ascentrycomp); + + if (found_entry) { + *asc_entry = (struct asc_table_entry *)found_entry; + break; + } + } + + for (i = 0; i < num_sense_tables; i++) { + void *found_entry; + + found_entry = scsibsearch(&sense_key, sense_tables[i], + sense_tables_size[i], + sizeof(**sense_tables), + senseentrycomp); + + if (found_entry) { + *sense_entry = + (struct sense_key_table_entry *)found_entry; + break; + } + } +} + +static void * +scsibsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)) +{ + const void *entry; + u_int l; + u_int u; + u_int m; + + l = -1; + u = nmemb; + while (l + 1 != u) { + m = (l + u) / 2; + entry = base + m * size; + if (compar(key, entry) > 0) + l = m; + else + u = m; + } + + entry = base + u * size; + if (u == nmemb + || compar(key, entry) != 0) + return (NULL); + + return ((void *)entry); +} + +/* + * Compare string with pattern, returning 0 on match. + * Short pattern matches trailing blanks in name, + * wildcard '*' in pattern matches rest of name, + * wildcard '?' matches a single non-space character. + */ +static int +cam_strmatch(const uint8_t *str, const uint8_t *pattern, int str_len) +{ + + while (*pattern != '\0'&& str_len > 0) { + + if (*pattern == '*') { + return (0); + } + if ((*pattern != *str) + && (*pattern != '?' || *str == ' ')) { + return (1); + } + pattern++; + str++; + str_len--; + } + while (str_len > 0 && *str++ == ' ') + str_len--; + + return (str_len); +} + +static caddr_t +cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries, + int entry_size, cam_quirkmatch_t *comp_func) +{ + for (; num_entries > 0; num_entries--, quirk_table += entry_size) { + if ((*comp_func)(target, quirk_table) == 0) + return (quirk_table); + } + return (NULL); +} + +void +aic_sense_desc(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *inq_data, + const char **sense_key_desc, const char **asc_desc) +{ + const struct asc_table_entry *asc_entry; + const struct sense_key_table_entry *sense_entry; + + fetchtableentries(sense_key, asc, ascq, + inq_data, + &sense_entry, + &asc_entry); + + *sense_key_desc = sense_entry->desc; + + if (asc_entry != NULL) + *asc_desc = asc_entry->desc; + else if (asc >= 0x80 && asc <= 0xff) + *asc_desc = "Vendor Specific ASC"; + else if (ascq >= 0x80 && ascq <= 0xff) + *asc_desc = "Vendor Specific ASCQ"; + else + *asc_desc = "Reserved ASC/ASCQ pair"; +} + +/* + * Given sense and device type information, return the appropriate action. + * If we do not understand the specific error as identified by the ASC/ASCQ + * pair, fall back on the more generic actions derived from the sense key. + */ +aic_sense_action +aic_sense_error_action(struct scsi_sense_data *sense_data, + struct scsi_inquiry_data *inq_data, uint32_t sense_flags) +{ + const struct asc_table_entry *asc_entry; + const struct sense_key_table_entry *sense_entry; + int error_code, sense_key, asc, ascq; + aic_sense_action action; + + scsi_extract_sense(sense_data, &error_code, &sense_key, &asc, &ascq); + + if (error_code == SSD_DEFERRED_ERROR) { + /* + * XXX dufault@FreeBSD.org + * This error doesn't relate to the command associated + * with this request sense. A deferred error is an error + * for a command that has already returned GOOD status + * (see SCSI2 8.2.14.2). + * + * By my reading of that section, it looks like the current + * command has been cancelled, we should now clean things up + * (hopefully recovering any lost data) and then retry the + * current command. There are two easy choices, both wrong: + * + * 1. Drop through (like we had been doing), thus treating + * this as if the error were for the current command and + * return and stop the current command. + * + * 2. Issue a retry (like I made it do) thus hopefully + * recovering the current transfer, and ignoring the + * fact that we've dropped a command. + * + * These should probably be handled in a device specific + * sense handler or punted back up to a user mode daemon + */ + action = SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE; + } else { + fetchtableentries(sense_key, asc, ascq, + inq_data, + &sense_entry, + &asc_entry); + + /* + * Override the 'No additional Sense' entry (0,0) + * with the error action of the sense key. + */ + if (asc_entry != NULL + && (asc != 0 || ascq != 0)) + action = asc_entry->action; + else + action = sense_entry->action; + + if (sense_key == SSD_KEY_RECOVERED_ERROR) { + /* + * The action succeeded but the device wants + * the user to know that some recovery action + * was required. + */ + action &= ~(SS_MASK|SSQ_MASK|SS_ERRMASK); + action |= SS_NOP|SSQ_PRINT_SENSE; + } else if (sense_key == SSD_KEY_ILLEGAL_REQUEST) { + if ((sense_flags & SF_QUIET_IR) != 0) + action &= ~SSQ_PRINT_SENSE; + } else if (sense_key == SSD_KEY_UNIT_ATTENTION) { + if ((sense_flags & SF_RETRY_UA) != 0 + && (action & SS_MASK) == SS_FAIL) { + action &= ~(SS_MASK|SSQ_MASK); + action |= SS_RETRY|SSQ_DECREMENT_COUNT| + SSQ_PRINT_SENSE; + } + } + } + + if ((sense_flags & SF_PRINT_ALWAYS) != 0) + action |= SSQ_PRINT_SENSE; + else if ((sense_flags & SF_NO_PRINT) != 0) + action &= ~SSQ_PRINT_SENSE; + + return (action); +} + +/* + * Try make as good a match as possible with + * available sub drivers + */ +int +aic_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) +{ + struct scsi_inquiry_pattern *entry; + struct scsi_inquiry_data *inq; + + entry = (struct scsi_inquiry_pattern *)table_entry; + inq = (struct scsi_inquiry_data *)inqbuffer; + + if (((SID_TYPE(inq) == entry->type) + || (entry->type == T_ANY)) + && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE + : entry->media_type & SIP_MEDIA_FIXED) + && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) + && (cam_strmatch(inq->product, entry->product, + sizeof(inq->product)) == 0) + && (cam_strmatch(inq->revision, entry->revision, + sizeof(inq->revision)) == 0)) { + return (0); + } + return (-1); +} + +/* + * Table of syncrates that don't follow the "divisible by 4" + * rule. This table will be expanded in future SCSI specs. + */ +static struct { + u_int period_factor; + u_int period; /* in 100ths of ns */ +} scsi_syncrates[] = { + { 0x08, 625 }, /* FAST-160 */ + { 0x09, 1250 }, /* FAST-80 */ + { 0x0a, 2500 }, /* FAST-40 40MHz */ + { 0x0b, 3030 }, /* FAST-40 33MHz */ + { 0x0c, 5000 } /* FAST-20 */ +}; + +/* + * Return the frequency in kHz corresponding to the given + * sync period factor. + */ +u_int +aic_calc_syncsrate(u_int period_factor) +{ + int i; + int num_syncrates; + + num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); + /* See if the period is in the "exception" table */ + for (i = 0; i < num_syncrates; i++) { + + if (period_factor == scsi_syncrates[i].period_factor) { + /* Period in kHz */ + return (100000000 / scsi_syncrates[i].period); + } + } + + /* + * Wasn't in the table, so use the standard + * 4 times conversion. + */ + return (10000000 / (period_factor * 4 * 10)); +} + +/* + * Return speed in KB/s. + */ +u_int +aic_calc_speed(u_int width, u_int period, u_int offset, u_int min_rate) +{ + u_int freq; + + if (offset != 0 && period < min_rate) + freq = aic_calc_syncsrate(period); + else + /* Roughly 3.3MB/s for async */ + freq = 3300; + freq <<= width; + return (freq); +} + +uint32_t +aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data, + cam_status status, u_int scsi_status) +{ + aic_sense_action err_action; + int sense; + + sense = (cmd->result >> 24) == DRIVER_SENSE; + + switch (status) { + case CAM_REQ_CMP: + err_action = SS_NOP; + break; + case CAM_AUTOSENSE_FAIL: + case CAM_SCSI_STATUS_ERROR: + + switch (scsi_status) { + case SCSI_STATUS_OK: + case SCSI_STATUS_COND_MET: + case SCSI_STATUS_INTERMED: + case SCSI_STATUS_INTERMED_COND_MET: + err_action = SS_NOP; + break; + case SCSI_STATUS_CMD_TERMINATED: + case SCSI_STATUS_CHECK_COND: + if (sense != 0) { + struct scsi_sense_data *sense; + + sense = (struct scsi_sense_data *) + &cmd->sense_buffer; + err_action = + aic_sense_error_action(sense, inq_data, 0); + + } else { + err_action = SS_RETRY|SSQ_FALLBACK + | SSQ_DECREMENT_COUNT|EIO; + } + break; + case SCSI_STATUS_QUEUE_FULL: + case SCSI_STATUS_BUSY: + err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY + | SSQ_DECREMENT_COUNT|EBUSY; + break; + case SCSI_STATUS_RESERV_CONFLICT: + default: + err_action = SS_FAIL|EBUSY; + break; + } + break; + case CAM_CMD_TIMEOUT: + case CAM_REQ_CMP_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_UNCOR_PARITY: + case CAM_DATA_RUN_ERR: + err_action = SS_RETRY|SSQ_FALLBACK|EIO; + break; + case CAM_UA_ABORT: + case CAM_UA_TERMIO: + case CAM_MSG_REJECT_REC: + case CAM_SEL_TIMEOUT: + err_action = SS_FAIL|EIO; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + case CAM_DEV_NOT_THERE: + case CAM_NO_HBA: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TOO_BIG: + case CAM_RESRC_UNAVAIL: + case CAM_BUSY: + default: + /* panic?? These should never occur in our application. */ + err_action = SS_FAIL|EIO; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + case CAM_REQUEUE_REQ: + /* Unconditional requeue */ + err_action = SS_RETRY; + break; + } + + return (err_action); +} + +char * +aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth, + aic_option_callback_t *callback, u_long callback_arg) +{ + char *tok_end; + char *tok_end2; + int i; + int instance; + int targ; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + /* All options use a ':' name/arg separator */ + if (*opt_arg != ':') + return (opt_arg); + opt_arg++; + instance = -1; + targ = -1; + done = FALSE; + /* + * Restore separator that may be in + * the middle of our option argument. + */ + tok_end = strchr(opt_arg, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*opt_arg) { + case '{': + if (instance == -1) { + instance = 0; + } else { + if (depth > 1) { + if (targ == -1) + targ = 0; + } else { + printf("Malformed Option %s\n", + opt_name); + done = TRUE; + } + } + opt_arg++; + break; + case '}': + if (targ != -1) + targ = -1; + else if (instance != -1) + instance = -1; + opt_arg++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (targ >= 0) + targ++; + else if (instance >= 0) + instance++; + opt_arg++; + break; + case '\0': + done = TRUE; + break; + default: + tok_end = end; + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(opt_arg, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) + tok_end = tok_end2; + } + callback(callback_arg, instance, targ, + simple_strtol(opt_arg, NULL, 0)); + opt_arg = tok_end; + break; + } + } + return (opt_arg); +} diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aiclib.h linux-2.4.22/drivers/scsi/aic7xxx/aiclib.h --- linux-2.4.21/drivers/scsi/aic7xxx/aiclib.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.22/drivers/scsi/aic7xxx/aiclib.h 2003-08-25 04:44:42.000000000 -0700 @@ -0,0 +1,1046 @@ +/* + * Largely written by Julian Elischer (julian@tfs.com) + * for TRW Financial Systems. + * + * TRW Financial Systems, in accordance with their agreement with Carnegie + * Mellon University, makes this software available to CMU to distribute + * or use in any manner that they see fit as long as this message is kept with + * the software. For this reason TFS also grants any other persons or + * organisations permission to use or modify this software. + * + * TFS supplies this software to be publicly redistributed + * on the understanding that TFS is not responsible for the correct + * functioning of this software in any circumstances. + * + * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 + * + * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.21 2002/10/08 17:12:44 ken Exp $ + * + * Copyright (c) 2003 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id$ + */ + +#ifndef _AICLIB_H +#define _AICLIB_H + +/* + * Linux Interrupt Support. + */ +#ifndef IRQ_RETVAL +typedef void irqreturn_t; +#define IRQ_RETVAL(x) +#endif + +/* + * SCSI command format + */ + +/* + * Define dome bits that are in ALL (or a lot of) scsi commands + */ +#define SCSI_CTL_LINK 0x01 +#define SCSI_CTL_FLAG 0x02 +#define SCSI_CTL_VENDOR 0xC0 +#define SCSI_CMD_LUN 0xA0 /* these two should not be needed */ +#define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */ + +#define SCSI_MAX_CDBLEN 16 /* + * 16 byte commands are in the + * SCSI-3 spec + */ +/* 6byte CDBs special case 0 length to be 256 */ +#define SCSI_CDB6_LEN(len) ((len) == 0 ? 256 : len) + +/* + * This type defines actions to be taken when a particular sense code is + * received. Right now, these flags are only defined to take up 16 bits, + * but can be expanded in the future if necessary. + */ +typedef enum { + SS_NOP = 0x000000, /* Do nothing */ + SS_RETRY = 0x010000, /* Retry the command */ + SS_FAIL = 0x020000, /* Bail out */ + SS_START = 0x030000, /* Send a Start Unit command to the device, + * then retry the original command. + */ + SS_TUR = 0x040000, /* Send a Test Unit Ready command to the + * device, then retry the original command. + */ + SS_REQSENSE = 0x050000, /* Send a RequestSense command to the + * device, then retry the original command. + */ + SS_INQ_REFRESH = 0x060000, + SS_MASK = 0xff0000 +} aic_sense_action; + +typedef enum { + SSQ_NONE = 0x0000, + SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */ + SSQ_MANY = 0x0200, /* send lots of recovery commands */ + SSQ_RANGE = 0x0400, /* + * This table entry represents the + * end of a range of ASCQs that + * have identical error actions + * and text. + */ + SSQ_PRINT_SENSE = 0x0800, + SSQ_DELAY = 0x1000, /* Delay before retry. */ + SSQ_DELAY_RANDOM = 0x2000, /* Randomized delay before retry. */ + SSQ_FALLBACK = 0x4000, /* Do a speed fallback to recover */ + SSQ_MASK = 0xff00 +} aic_sense_action_qualifier; + +/* Mask for error status values */ +#define SS_ERRMASK 0xff + +/* The default, retyable, error action */ +#define SS_RDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO + +/* The retyable, error action, with table specified error code */ +#define SS_RET SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE + +/* Fatal error action, with table specified error code */ +#define SS_FATAL SS_FAIL|SSQ_PRINT_SENSE + +struct scsi_generic +{ + uint8_t opcode; + uint8_t bytes[11]; +}; + +struct scsi_request_sense +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_test_unit_ready +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[3]; + uint8_t control; +}; + +struct scsi_send_diag +{ + uint8_t opcode; + uint8_t byte2; +#define SSD_UOL 0x01 +#define SSD_DOL 0x02 +#define SSD_SELFTEST 0x04 +#define SSD_PF 0x10 + uint8_t unused[1]; + uint8_t paramlen[2]; + uint8_t control; +}; + +struct scsi_sense +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_inquiry +{ + uint8_t opcode; + uint8_t byte2; +#define SI_EVPD 0x01 + uint8_t page_code; + uint8_t reserved; + uint8_t length; + uint8_t control; +}; + +struct scsi_mode_sense_6 +{ + uint8_t opcode; + uint8_t byte2; +#define SMS_DBD 0x08 + uint8_t page; +#define SMS_PAGE_CODE 0x3F +#define SMS_VENDOR_SPECIFIC_PAGE 0x00 +#define SMS_DISCONNECT_RECONNECT_PAGE 0x02 +#define SMS_PERIPHERAL_DEVICE_PAGE 0x09 +#define SMS_CONTROL_MODE_PAGE 0x0A +#define SMS_ALL_PAGES_PAGE 0x3F +#define SMS_PAGE_CTRL_MASK 0xC0 +#define SMS_PAGE_CTRL_CURRENT 0x00 +#define SMS_PAGE_CTRL_CHANGEABLE 0x40 +#define SMS_PAGE_CTRL_DEFAULT 0x80 +#define SMS_PAGE_CTRL_SAVED 0xC0 + uint8_t unused; + uint8_t length; + uint8_t control; +}; + +struct scsi_mode_sense_10 +{ + uint8_t opcode; + uint8_t byte2; /* same bits as small version */ + uint8_t page; /* same bits as small version */ + uint8_t unused[4]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_mode_select_6 +{ + uint8_t opcode; + uint8_t byte2; +#define SMS_SP 0x01 +#define SMS_PF 0x10 + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_mode_select_10 +{ + uint8_t opcode; + uint8_t byte2; /* same bits as small version */ + uint8_t unused[5]; + uint8_t length[2]; + uint8_t control; +}; + +/* + * When sending a mode select to a tape drive, the medium type must be 0. + */ +struct scsi_mode_hdr_6 +{ + uint8_t datalen; + uint8_t medium_type; + uint8_t dev_specific; + uint8_t block_descr_len; +}; + +struct scsi_mode_hdr_10 +{ + uint8_t datalen[2]; + uint8_t medium_type; + uint8_t dev_specific; + uint8_t reserved[2]; + uint8_t block_descr_len[2]; +}; + +struct scsi_mode_block_descr +{ + uint8_t density_code; + uint8_t num_blocks[3]; + uint8_t reserved; + uint8_t block_len[3]; +}; + +struct scsi_log_sense +{ + uint8_t opcode; + uint8_t byte2; +#define SLS_SP 0x01 +#define SLS_PPC 0x02 + uint8_t page; +#define SLS_PAGE_CODE 0x3F +#define SLS_ALL_PAGES_PAGE 0x00 +#define SLS_OVERRUN_PAGE 0x01 +#define SLS_ERROR_WRITE_PAGE 0x02 +#define SLS_ERROR_READ_PAGE 0x03 +#define SLS_ERROR_READREVERSE_PAGE 0x04 +#define SLS_ERROR_VERIFY_PAGE 0x05 +#define SLS_ERROR_NONMEDIUM_PAGE 0x06 +#define SLS_ERROR_LASTN_PAGE 0x07 +#define SLS_PAGE_CTRL_MASK 0xC0 +#define SLS_PAGE_CTRL_THRESHOLD 0x00 +#define SLS_PAGE_CTRL_CUMULATIVE 0x40 +#define SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 +#define SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 + uint8_t reserved[2]; + uint8_t paramptr[2]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_log_select +{ + uint8_t opcode; + uint8_t byte2; +/* SLS_SP 0x01 */ +#define SLS_PCR 0x02 + uint8_t page; +/* SLS_PAGE_CTRL_MASK 0xC0 */ +/* SLS_PAGE_CTRL_THRESHOLD 0x00 */ +/* SLS_PAGE_CTRL_CUMULATIVE 0x40 */ +/* SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 */ +/* SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 */ + uint8_t reserved[4]; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_log_header +{ + uint8_t page; + uint8_t reserved; + uint8_t datalen[2]; +}; + +struct scsi_log_param_header { + uint8_t param_code[2]; + uint8_t param_control; +#define SLP_LP 0x01 +#define SLP_LBIN 0x02 +#define SLP_TMC_MASK 0x0C +#define SLP_TMC_ALWAYS 0x00 +#define SLP_TMC_EQUAL 0x04 +#define SLP_TMC_NOTEQUAL 0x08 +#define SLP_TMC_GREATER 0x0C +#define SLP_ETC 0x10 +#define SLP_TSD 0x20 +#define SLP_DS 0x40 +#define SLP_DU 0x80 + uint8_t param_len; +}; + +struct scsi_control_page { + uint8_t page_code; + uint8_t page_length; + uint8_t rlec; +#define SCB_RLEC 0x01 /*Report Log Exception Cond*/ + uint8_t queue_flags; +#define SCP_QUEUE_ALG_MASK 0xF0 +#define SCP_QUEUE_ALG_RESTRICTED 0x00 +#define SCP_QUEUE_ALG_UNRESTRICTED 0x10 +#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/ +#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/ + uint8_t eca_and_aen; +#define SCP_EECA 0x80 /*Enable Extended CA*/ +#define SCP_RAENP 0x04 /*Ready AEN Permission*/ +#define SCP_UAAENP 0x02 /*UA AEN Permission*/ +#define SCP_EAENP 0x01 /*Error AEN Permission*/ + uint8_t reserved; + uint8_t aen_holdoff_period[2]; +}; + +struct scsi_reserve +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_release +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t length; + uint8_t control; +}; + +struct scsi_prevent +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[2]; + uint8_t how; + uint8_t control; +}; +#define PR_PREVENT 0x01 +#define PR_ALLOW 0x00 + +struct scsi_sync_cache +{ + uint8_t opcode; + uint8_t byte2; + uint8_t begin_lba[4]; + uint8_t reserved; + uint8_t lb_count[2]; + uint8_t control; +}; + + +struct scsi_changedef +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused1; + uint8_t how; + uint8_t unused[4]; + uint8_t datalen; + uint8_t control; +}; + +struct scsi_read_buffer +{ + uint8_t opcode; + uint8_t byte2; +#define RWB_MODE 0x07 +#define RWB_MODE_HDR_DATA 0x00 +#define RWB_MODE_DATA 0x02 +#define RWB_MODE_DOWNLOAD 0x04 +#define RWB_MODE_DOWNLOAD_SAVE 0x05 + uint8_t buffer_id; + uint8_t offset[3]; + uint8_t length[3]; + uint8_t control; +}; + +struct scsi_write_buffer +{ + uint8_t opcode; + uint8_t byte2; + uint8_t buffer_id; + uint8_t offset[3]; + uint8_t length[3]; + uint8_t control; +}; + +struct scsi_rw_6 +{ + uint8_t opcode; + uint8_t addr[3]; +/* only 5 bits are valid in the MSB address byte */ +#define SRW_TOPADDR 0x1F + uint8_t length; + uint8_t control; +}; + +struct scsi_rw_10 +{ + uint8_t opcode; +#define SRW10_RELADDR 0x01 +#define SRW10_FUA 0x08 +#define SRW10_DPO 0x10 + uint8_t byte2; + uint8_t addr[4]; + uint8_t reserved; + uint8_t length[2]; + uint8_t control; +}; + +struct scsi_rw_12 +{ + uint8_t opcode; +#define SRW12_RELADDR 0x01 +#define SRW12_FUA 0x08 +#define SRW12_DPO 0x10 + uint8_t byte2; + uint8_t addr[4]; + uint8_t length[4]; + uint8_t reserved; + uint8_t control; +}; + +struct scsi_start_stop_unit +{ + uint8_t opcode; + uint8_t byte2; +#define SSS_IMMED 0x01 + uint8_t reserved[2]; + uint8_t how; +#define SSS_START 0x01 +#define SSS_LOEJ 0x02 + uint8_t control; +}; + +#define SC_SCSI_1 0x01 +#define SC_SCSI_2 0x03 + +/* + * Opcodes + */ + +#define TEST_UNIT_READY 0x00 +#define REQUEST_SENSE 0x03 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define INQUIRY 0x12 +#define MODE_SELECT_6 0x15 +#define MODE_SENSE_6 0x1a +#define START_STOP_UNIT 0x1b +#define START_STOP 0x1b +#define RESERVE 0x16 +#define RELEASE 0x17 +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define PREVENT_ALLOW 0x1e +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define POSITION_TO_ELEMENT 0x2b +#define SYNCHRONIZE_CACHE 0x35 +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define CHANGE_DEFINITION 0x40 +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#ifdef XXXCAM +#define MODE_SENSE_10 0x5A +#endif +#define MODE_SELECT_10 0x55 +#define MOVE_MEDIUM 0xa5 +#define READ_12 0xa8 +#define WRITE_12 0xaa +#define READ_ELEMENT_STATUS 0xb8 + + +/* + * Device Types + */ +#define T_DIRECT 0x00 +#define T_SEQUENTIAL 0x01 +#define T_PRINTER 0x02 +#define T_PROCESSOR 0x03 +#define T_WORM 0x04 +#define T_CDROM 0x05 +#define T_SCANNER 0x06 +#define T_OPTICAL 0x07 +#define T_CHANGER 0x08 +#define T_COMM 0x09 +#define T_ASC0 0x0a +#define T_ASC1 0x0b +#define T_STORARRAY 0x0c +#define T_ENCLOSURE 0x0d +#define T_RBC 0x0e +#define T_OCRW 0x0f +#define T_NODEVICE 0x1F +#define T_ANY 0xFF /* Used in Quirk table matches */ + +#define T_REMOV 1 +#define T_FIXED 0 + +/* + * This length is the initial inquiry length used by the probe code, as + * well as the legnth necessary for aic_print_inquiry() to function + * correctly. If either use requires a different length in the future, + * the two values should be de-coupled. + */ +#define SHORT_INQUIRY_LENGTH 36 + +struct scsi_inquiry_data +{ + uint8_t device; +#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f) +#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5) +#define SID_QUAL_LU_CONNECTED 0x00 /* + * The specified peripheral device + * type is currently connected to + * logical unit. If the target cannot + * determine whether or not a physical + * device is currently connected, it + * shall also use this peripheral + * qualifier when returning the INQUIRY + * data. This peripheral qualifier + * does not mean that the device is + * ready for access by the initiator. + */ +#define SID_QUAL_LU_OFFLINE 0x01 /* + * The target is capable of supporting + * the specified peripheral device type + * on this logical unit; however, the + * physical device is not currently + * connected to this logical unit. + */ +#define SID_QUAL_RSVD 0x02 +#define SID_QUAL_BAD_LU 0x03 /* + * The target is not capable of + * supporting a physical device on + * this logical unit. For this + * peripheral qualifier the peripheral + * device type shall be set to 1Fh to + * provide compatibility with previous + * versions of SCSI. All other + * peripheral device type values are + * reserved for this peripheral + * qualifier. + */ +#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) + uint8_t dev_qual2; +#define SID_QUAL2 0x7F +#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0) + uint8_t version; +#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07) +#define SCSI_REV_0 0 +#define SCSI_REV_CCS 1 +#define SCSI_REV_2 2 +#define SCSI_REV_SPC 3 +#define SCSI_REV_SPC2 4 + +#define SID_ECMA 0x38 +#define SID_ISO 0xC0 + uint8_t response_format; +#define SID_AENC 0x80 +#define SID_TrmIOP 0x40 + uint8_t additional_length; + uint8_t reserved[2]; + uint8_t flags; +#define SID_SftRe 0x01 +#define SID_CmdQue 0x02 +#define SID_Linked 0x08 +#define SID_Sync 0x10 +#define SID_WBus16 0x20 +#define SID_WBus32 0x40 +#define SID_RelAdr 0x80 +#define SID_VENDOR_SIZE 8 + char vendor[SID_VENDOR_SIZE]; +#define SID_PRODUCT_SIZE 16 + char product[SID_PRODUCT_SIZE]; +#define SID_REVISION_SIZE 4 + char revision[SID_REVISION_SIZE]; + /* + * The following fields were taken from SCSI Primary Commands - 2 + * (SPC-2) Revision 14, Dated 11 November 1999 + */ +#define SID_VENDOR_SPECIFIC_0_SIZE 20 + uint8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE]; + /* + * An extension of SCSI Parallel Specific Values + */ +#define SID_SPI_IUS 0x01 +#define SID_SPI_QAS 0x02 +#define SID_SPI_CLOCK_ST 0x00 +#define SID_SPI_CLOCK_DT 0x04 +#define SID_SPI_CLOCK_DT_ST 0x0C +#define SID_SPI_MASK 0x0F + uint8_t spi3data; + uint8_t reserved2; + /* + * Version Descriptors, stored 2 byte values. + */ + uint8_t version1[2]; + uint8_t version2[2]; + uint8_t version3[2]; + uint8_t version4[2]; + uint8_t version5[2]; + uint8_t version6[2]; + uint8_t version7[2]; + uint8_t version8[2]; + + uint8_t reserved3[22]; + +#define SID_VENDOR_SPECIFIC_1_SIZE 160 + uint8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE]; +}; + +struct scsi_vpd_unit_serial_number +{ + uint8_t device; + uint8_t page_code; +#define SVPD_UNIT_SERIAL_NUMBER 0x80 + uint8_t reserved; + uint8_t length; /* serial number length */ +#define SVPD_SERIAL_NUM_SIZE 251 + uint8_t serial_num[SVPD_SERIAL_NUM_SIZE]; +}; + +struct scsi_read_capacity +{ + uint8_t opcode; + uint8_t byte2; + uint8_t addr[4]; + uint8_t unused[3]; + uint8_t control; +}; + +struct scsi_read_capacity_data +{ + uint8_t addr[4]; + uint8_t length[4]; +}; + +struct scsi_report_luns +{ + uint8_t opcode; + uint8_t byte2; + uint8_t unused[3]; + uint8_t addr[4]; + uint8_t control; +}; + +struct scsi_report_luns_data { + uint8_t length[4]; /* length of LUN inventory, in bytes */ + uint8_t reserved[4]; /* unused */ + /* + * LUN inventory- we only support the type zero form for now. + */ + struct { + uint8_t lundata[8]; + } luns[1]; +}; +#define RPL_LUNDATA_ATYP_MASK 0xc0 /* MBZ for type 0 lun */ +#define RPL_LUNDATA_T0LUN 1 /* @ lundata[1] */ + + +struct scsi_sense_data +{ + uint8_t error_code; +#define SSD_ERRCODE 0x7F +#define SSD_CURRENT_ERROR 0x70 +#define SSD_DEFERRED_ERROR 0x71 +#define SSD_ERRCODE_VALID 0x80 + uint8_t segment; + uint8_t flags; +#define SSD_KEY 0x0F +#define SSD_KEY_NO_SENSE 0x00 +#define SSD_KEY_RECOVERED_ERROR 0x01 +#define SSD_KEY_NOT_READY 0x02 +#define SSD_KEY_MEDIUM_ERROR 0x03 +#define SSD_KEY_HARDWARE_ERROR 0x04 +#define SSD_KEY_ILLEGAL_REQUEST 0x05 +#define SSD_KEY_UNIT_ATTENTION 0x06 +#define SSD_KEY_DATA_PROTECT 0x07 +#define SSD_KEY_BLANK_CHECK 0x08 +#define SSD_KEY_Vendor_Specific 0x09 +#define SSD_KEY_COPY_ABORTED 0x0a +#define SSD_KEY_ABORTED_COMMAND 0x0b +#define SSD_KEY_EQUAL 0x0c +#define SSD_KEY_VOLUME_OVERFLOW 0x0d +#define SSD_KEY_MISCOMPARE 0x0e +#define SSD_KEY_RESERVED 0x0f +#define SSD_ILI 0x20 +#define SSD_EOM 0x40 +#define SSD_FILEMARK 0x80 + uint8_t info[4]; + uint8_t extra_len; + uint8_t cmd_spec_info[4]; + uint8_t add_sense_code; + uint8_t add_sense_code_qual; + uint8_t fru; + uint8_t sense_key_spec[3]; +#define SSD_SCS_VALID 0x80 +#define SSD_FIELDPTR_CMD 0x40 +#define SSD_BITPTR_VALID 0x08 +#define SSD_BITPTR_VALUE 0x07 +#define SSD_MIN_SIZE 18 + uint8_t extra_bytes[14]; +#define SSD_FULL_SIZE sizeof(struct scsi_sense_data) +}; + +struct scsi_mode_header_6 +{ + uint8_t data_length; /* Sense data length */ + uint8_t medium_type; + uint8_t dev_spec; + uint8_t blk_desc_len; +}; + +struct scsi_mode_header_10 +{ + uint8_t data_length[2];/* Sense data length */ + uint8_t medium_type; + uint8_t dev_spec; + uint8_t unused[2]; + uint8_t blk_desc_len[2]; +}; + +struct scsi_mode_page_header +{ + uint8_t page_code; + uint8_t page_length; +}; + +struct scsi_mode_blk_desc +{ + uint8_t density; + uint8_t nblocks[3]; + uint8_t reserved; + uint8_t blklen[3]; +}; + +#define SCSI_DEFAULT_DENSITY 0x00 /* use 'default' density */ +#define SCSI_SAME_DENSITY 0x7f /* use 'same' density- >= SCSI-2 only */ + + +/* + * Status Byte + */ +#define SCSI_STATUS_OK 0x00 +#define SCSI_STATUS_CHECK_COND 0x02 +#define SCSI_STATUS_COND_MET 0x04 +#define SCSI_STATUS_BUSY 0x08 +#define SCSI_STATUS_INTERMED 0x10 +#define SCSI_STATUS_INTERMED_COND_MET 0x14 +#define SCSI_STATUS_RESERV_CONFLICT 0x18 +#define SCSI_STATUS_CMD_TERMINATED 0x22 /* Obsolete in SAM-2 */ +#define SCSI_STATUS_QUEUE_FULL 0x28 +#define SCSI_STATUS_ACA_ACTIVE 0x30 +#define SCSI_STATUS_TASK_ABORTED 0x40 + +struct scsi_inquiry_pattern { + uint8_t type; + uint8_t media_type; +#define SIP_MEDIA_REMOVABLE 0x01 +#define SIP_MEDIA_FIXED 0x02 + const char *vendor; + const char *product; + const char *revision; +}; + +struct scsi_static_inquiry_pattern { + uint8_t type; + uint8_t media_type; + char vendor[SID_VENDOR_SIZE+1]; + char product[SID_PRODUCT_SIZE+1]; + char revision[SID_REVISION_SIZE+1]; +}; + +struct scsi_sense_quirk_entry { + struct scsi_inquiry_pattern inq_pat; + int num_sense_keys; + int num_ascs; + struct sense_key_table_entry *sense_key_info; + struct asc_table_entry *asc_info; +}; + +struct sense_key_table_entry { + uint8_t sense_key; + uint32_t action; + const char *desc; +}; + +struct asc_table_entry { + uint8_t asc; + uint8_t ascq; + uint32_t action; + const char *desc; +}; + +struct op_table_entry { + uint8_t opcode; + uint16_t opmask; + const char *desc; +}; + +struct scsi_op_quirk_entry { + struct scsi_inquiry_pattern inq_pat; + int num_ops; + struct op_table_entry *op_table; +}; + +typedef enum { + SSS_FLAG_NONE = 0x00, + SSS_FLAG_PRINT_COMMAND = 0x01 +} scsi_sense_string_flags; + +extern const char *scsi_sense_key_text[]; + +/************************* Large Disk Handling ********************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +static __inline int aic_sector_div(u_long capacity, int heads, int sectors); + +static __inline int +aic_sector_div(u_long capacity, int heads, int sectors) +{ + return (capacity / (heads * sectors)); +} +#else +static __inline int aic_sector_div(sector_t capacity, int heads, int sectors); + +static __inline int +aic_sector_div(sector_t capacity, int heads, int sectors) +{ + /* ugly, ugly sector_div calling convention.. */ + sector_div(capacity, (heads * sectors)); + return (int)capacity; +} +#endif + +/**************************** Module Library Hack *****************************/ +/* + * What we'd like to do is have a single "scsi library" module that both the + * aic7xxx and aic79xx drivers could load and depend on. A cursory examination + * of implementing module dependencies in Linux (handling the install and + * initrd cases) does not look promissing. For now, we just duplicate this + * code in both drivers using a simple symbol renaming scheme that hides this + * hack from the drivers. + */ +#define AIC_LIB_ENTRY_CONCAT(x, prefix) prefix ## x +#define AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix) +#define AIC_LIB_ENTRY(x) AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX) + +#define aic_sense_desc AIC_LIB_ENTRY(_sense_desc) +#define aic_sense_error_action AIC_LIB_ENTRY(_sense_error_action) +#define aic_error_action AIC_LIB_ENTRY(_error_action) +#define aic_op_desc AIC_LIB_ENTRY(_op_desc) +#define aic_cdb_string AIC_LIB_ENTRY(_cdb_string) +#define aic_print_inquiry AIC_LIB_ENTRY(_print_inquiry) +#define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate) +#define aic_calc_syncparam AIC_LIB_ENTRY(_calc_syncparam) +#define aic_calc_speed AIC_LIB_ENTRY(_calc_speed) +#define aic_inquiry_match AIC_LIB_ENTRY(_inquiry_match) +#define aic_static_inquiry_match AIC_LIB_ENTRY(_static_inquiry_match) +#define aic_parse_brace_option AIC_LIB_ENTRY(_parse_brace_option) + +/******************************************************************************/ + +void aic_sense_desc(int /*sense_key*/, int /*asc*/, + int /*ascq*/, struct scsi_inquiry_data*, + const char** /*sense_key_desc*/, + const char** /*asc_desc*/); +aic_sense_action aic_sense_error_action(struct scsi_sense_data*, + struct scsi_inquiry_data*, + uint32_t /*sense_flags*/); +uint32_t aic_error_action(struct scsi_cmnd *, + struct scsi_inquiry_data *, + cam_status, u_int); + +#define SF_RETRY_UA 0x01 +#define SF_NO_PRINT 0x02 +#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */ +#define SF_PRINT_ALWAYS 0x08 + + +const char * aic_op_desc(uint16_t /*opcode*/, struct scsi_inquiry_data*); +char * aic_cdb_string(uint8_t* /*cdb_ptr*/, char* /*cdb_string*/, + size_t /*len*/); +void aic_print_inquiry(struct scsi_inquiry_data*); + +u_int aic_calc_syncsrate(u_int /*period_factor*/); +u_int aic_calc_syncparam(u_int /*period*/); +u_int aic_calc_speed(u_int width, u_int period, u_int offset, + u_int min_rate); + +int aic_inquiry_match(caddr_t /*inqbuffer*/, + caddr_t /*table_entry*/); +int aic_static_inquiry_match(caddr_t /*inqbuffer*/, + caddr_t /*table_entry*/); + +typedef void aic_option_callback_t(u_long, int, int, int32_t); +char * aic_parse_brace_option(char *opt_name, char *opt_arg, + char *end, int depth, + aic_option_callback_t *, u_long); + +static __inline void scsi_extract_sense(struct scsi_sense_data *sense, + int *error_code, int *sense_key, + int *asc, int *ascq); +static __inline void scsi_ulto2b(uint32_t val, uint8_t *bytes); +static __inline void scsi_ulto3b(uint32_t val, uint8_t *bytes); +static __inline void scsi_ulto4b(uint32_t val, uint8_t *bytes); +static __inline uint32_t scsi_2btoul(uint8_t *bytes); +static __inline uint32_t scsi_3btoul(uint8_t *bytes); +static __inline int32_t scsi_3btol(uint8_t *bytes); +static __inline uint32_t scsi_4btoul(uint8_t *bytes); + +static __inline void scsi_extract_sense(struct scsi_sense_data *sense, + int *error_code, int *sense_key, + int *asc, int *ascq) +{ + *error_code = sense->error_code & SSD_ERRCODE; + *sense_key = sense->flags & SSD_KEY; + *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; + *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; +} + +static __inline void +scsi_ulto2b(uint32_t val, uint8_t *bytes) +{ + + bytes[0] = (val >> 8) & 0xff; + bytes[1] = val & 0xff; +} + +static __inline void +scsi_ulto3b(uint32_t val, uint8_t *bytes) +{ + + bytes[0] = (val >> 16) & 0xff; + bytes[1] = (val >> 8) & 0xff; + bytes[2] = val & 0xff; +} + +static __inline void +scsi_ulto4b(uint32_t val, uint8_t *bytes) +{ + + bytes[0] = (val >> 24) & 0xff; + bytes[1] = (val >> 16) & 0xff; + bytes[2] = (val >> 8) & 0xff; + bytes[3] = val & 0xff; +} + +static __inline uint32_t +scsi_2btoul(uint8_t *bytes) +{ + uint32_t rv; + + rv = (bytes[0] << 8) | + bytes[1]; + return (rv); +} + +static __inline uint32_t +scsi_3btoul(uint8_t *bytes) +{ + uint32_t rv; + + rv = (bytes[0] << 16) | + (bytes[1] << 8) | + bytes[2]; + return (rv); +} + +static __inline int32_t +scsi_3btol(uint8_t *bytes) +{ + uint32_t rc = scsi_3btoul(bytes); + + if (rc & 0x00800000) + rc |= 0xff000000; + + return (int32_t) rc; +} + +static __inline uint32_t +scsi_4btoul(uint8_t *bytes) +{ + uint32_t rv; + + rv = (bytes[0] << 24) | + (bytes[1] << 16) | + (bytes[2] << 8) | + bytes[3]; + return (rv); +} + +#endif /*_AICLIB_H */ diff -urN linux-2.4.21/drivers/scsi/aic7xxx/cam.h linux-2.4.22/drivers/scsi/aic7xxx/cam.h --- linux-2.4.21/drivers/scsi/aic7xxx/cam.h 2001-10-25 13:53:49.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/cam.h 2003-08-25 04:44:42.000000000 -0700 @@ -29,13 +29,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#11 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#15 $ */ #ifndef _AIC7XXX_CAM_H #define _AIC7XXX_CAM_H 1 -/* Provide a mapping from CAM constructs to Linux SCSI constructs */ +#include #define CAM_BUS_WILDCARD ((u_int)~0) #define CAM_TARGET_WILDCARD ((u_int)~0) @@ -43,56 +43,34 @@ /* CAM Status field values */ typedef enum { - /* CCB request is in progress */ - CAM_REQ_INPROG = 0x3F, /* Some value unused by Linux */ - /* CCB request completed without error */ - CAM_REQ_CMP = DID_OK, - /* CCB request aborted by the host */ - CAM_REQ_ABORTED = DID_ABORT, - /* Unable to abort CCB request */ - CAM_UA_ABORT = DID_ERROR, - /* CCB request completed with an error */ - CAM_REQ_CMP_ERR = DID_ERROR, - /* CAM subsytem is busy */ - CAM_BUSY = DID_BUS_BUSY, - /* CCB request was invalid */ - CAM_REQ_INVALID = DID_BAD_TARGET, - /* Supplied Path ID is invalid */ - CAM_PATH_INVALID = DID_BAD_TARGET, - /* Target Selection Timeout */ - CAM_SEL_TIMEOUT = DID_NO_CONNECT, - /* Command timeout */ - CAM_CMD_TIMEOUT = DID_ERROR, /* - * Should never occur in Linux - * as the upper level code - * handles all timeout processing. - */ - /* SCSI error, look at error code in CCB */ - CAM_SCSI_STATUS_ERROR = DID_OK, /* Linux looks at status byte */ - /* SCSI Bus Reset Sent/Received */ - CAM_SCSI_BUS_RESET = DID_RESET, - /* Uncorrectable parity error occurred */ - CAM_UNCOR_PARITY = DID_PARITY, - /* Autosense: request sense cmd fail */ - CAM_AUTOSENSE_FAIL = DID_ERROR, - /* No HBA Detected Error */ - CAM_NO_HBA = DID_ERROR, - /* Data Overrun error */ - CAM_DATA_RUN_ERR = DID_ERROR, - /* Unexpected Bus Free */ - CAM_UNEXP_BUSFREE = DID_ERROR, - /* CCB length supplied is inadequate */ - CAM_CCB_LEN_ERR = DID_ERROR, - /* Unable to provide requested capability */ - CAM_PROVIDE_FAIL = DID_ERROR, - /* A SCSI BDR msg was sent to target */ - CAM_BDR_SENT = DID_RESET, - /* CCB request terminated by the host */ - CAM_REQ_TERMIO = DID_ERROR, - /* Unrecoverable Host Bus Adapter Error */ - CAM_UNREC_HBA_ERROR = DID_ERROR, - /* The request was too large for this host */ - CAM_REQ_TOO_BIG = DID_ERROR, + CAM_REQ_INPROG, /* CCB request is in progress */ + CAM_REQ_CMP, /* CCB request completed without error */ + CAM_REQ_ABORTED, /* CCB request aborted by the host */ + CAM_UA_ABORT, /* Unable to abort CCB request */ + CAM_REQ_CMP_ERR, /* CCB request completed with an error */ + CAM_BUSY, /* CAM subsytem is busy */ + CAM_REQ_INVALID, /* CCB request was invalid */ + CAM_PATH_INVALID, /* Supplied Path ID is invalid */ + CAM_SEL_TIMEOUT, /* Target Selection Timeout */ + CAM_CMD_TIMEOUT, /* Command timeout */ + CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */ + CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */ + CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */ + CAM_AUTOSENSE_FAIL, /* Autosense: request sense cmd fail */ + CAM_NO_HBA, /* No HBA Detected Error */ + CAM_DATA_RUN_ERR, /* Data Overrun error */ + CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */ + CAM_SEQUENCE_FAIL, /* Protocol Violation */ + CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */ + CAM_PROVIDE_FAIL, /* Unable to provide requested capability */ + CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */ + CAM_REQ_TERMIO, /* CCB request terminated by the host */ + CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */ + CAM_REQ_TOO_BIG, /* The request was too large for this host */ + CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */ + CAM_MSG_REJECT_REC, /* Message Reject Received */ + CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */ + CAM_RESRC_UNAVAIL, /* Resource Unavailable */ /* * This request should be requeued to preserve * transaction ordering. This typically occurs @@ -101,7 +79,8 @@ * requests for the target at the sim level * back into the XPT queue. */ - CAM_REQUEUE_REQ = DID_BUS_BUSY, + CAM_REQUEUE_REQ, + CAM_DEV_QFRZN = 0x40, CAM_STATUS_MASK = 0x3F } cam_status; diff -urN linux-2.4.21/drivers/scsi/aic7xxx/scsi_iu.h linux-2.4.22/drivers/scsi/aic7xxx/scsi_iu.h --- linux-2.4.21/drivers/scsi/aic7xxx/scsi_iu.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/aic7xxx/scsi_iu.h 2003-08-25 04:44:42.000000000 -0700 @@ -28,4 +28,12 @@ (12 + (((siu)->flags & SIU_RSPVALID) \ ? scsi_4btoul((siu)->pkt_failures_length) \ : 0)) + +#define SIU_TASKMGMT_NONE 0x00 +#define SIU_TASKMGMT_ABORT_TASK 0x01 +#define SIU_TASKMGMT_ABORT_TASK_SET 0x02 +#define SIU_TASKMGMT_CLEAR_TASK_SET 0x04 +#define SIU_TASKMGMT_LUN_RESET 0x08 +#define SIU_TASKMGMT_TARGET_RESET 0x20 +#define SIU_TASKMGMT_CLEAR_ACA 0x40 #endif /*_SCSI_SCSI_IU_H*/ diff -urN linux-2.4.21/drivers/scsi/dec_esp.c linux-2.4.22/drivers/scsi/dec_esp.c --- linux-2.4.21/drivers/scsi/dec_esp.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/dec_esp.c 2003-08-25 04:44:42.000000000 -0700 @@ -17,6 +17,8 @@ * data. * 20001005 - Initialization fixes for 2.4.0-test9 * Florian Lohoff + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include @@ -26,56 +28,48 @@ #include #include #include +#include #include -#include "scsi.h" -#include "hosts.h" -#include "NCR53C9x.h" -#include "dec_esp.h" - -#include -#include -#include #include - +#include #include +#include -#include #include +#include #include #include #include +#include + +#include "scsi.h" +#include "hosts.h" +#include "NCR53C9x.h" +#include "dec_esp.h" -#include -/* - * Once upon a time the pmaz code used to be working but - * it hasn't been maintained for quite some time. - * It isn't working anymore but I'll leave here as a - * starting point. #define this an be prepared for tons - * of warnings and errors :) - */ static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); static void dma_drain(struct NCR_ESP *esp); static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp); static void dma_dump_state(struct NCR_ESP *esp); -static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); +static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length); +static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length); static void dma_ints_off(struct NCR_ESP *esp); static void dma_ints_on(struct NCR_ESP *esp); static int dma_irq_p(struct NCR_ESP *esp); static int dma_ports_p(struct NCR_ESP *esp); -static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); +static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write); static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp); static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp); static void dma_advance_sg(Scsi_Cmnd * sp); static void pmaz_dma_drain(struct NCR_ESP *esp); -static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); -static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); +static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length); +static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length); static void pmaz_dma_ints_off(struct NCR_ESP *esp); static void pmaz_dma_ints_on(struct NCR_ESP *esp); -static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); +static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write); static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp); #define TC_ESP_RAM_SIZE 0x20000 @@ -86,7 +80,7 @@ #define TC_ESP_DMAR_WRITE 0x80000000 #define TC_ESP_DMA_ADDR(x) ((unsigned)(x) & TC_ESP_DMAR_MASK) -__u32 esp_virt_buffer; +u32 esp_virt_buffer; int scsi_current_length; volatile unsigned char cmd_buffer[16]; @@ -96,13 +90,6 @@ * via PIO. */ -volatile unsigned long *scsi_dma_ptr; -volatile unsigned long *scsi_next_ptr; -volatile unsigned long *scsi_scr; -volatile unsigned long *ioasic_ssr; -volatile unsigned long *scsi_sdr0; -volatile unsigned long *scsi_sdr1; - static void scsi_dma_merr_int(int, void *, struct pt_regs *); static void scsi_dma_err_int(int, void *, struct pt_regs *); static void scsi_dma_int(int, void *, struct pt_regs *); @@ -122,17 +109,10 @@ if (IOASIC) { esp_dev = 0; esp = esp_allocate(tpnt, (void *) esp_dev); - - scsi_dma_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_P); - scsi_next_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_BP); - scsi_scr = (unsigned long *) (system_base + IOCTL + SCSI_SCR); - ioasic_ssr = (unsigned long *) (system_base + IOCTL + SSR); - scsi_sdr0 = (unsigned long *) (system_base + IOCTL + SCSI_SDR0); - scsi_sdr1 = (unsigned long *) (system_base + IOCTL + SCSI_SDR1); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; - + /* Required functions */ esp->dma_bytes_sent = &dma_bytes_sent; esp->dma_can_transfer = &dma_can_transfer; @@ -155,7 +135,7 @@ esp->dma_reset = 0; esp->dma_led_off = 0; esp->dma_led_on = 0; - + /* virtual DMA functions */ esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; @@ -167,47 +147,42 @@ /* SCSI chip speed */ esp->cfreq = 25000000; - /* - * we don't give the address of DMA channel, but the number - * of DMA channel, so we can use the jazz DMA functions - * - */ - esp->dregs = JAZZ_SCSI_DMA; - + esp->dregs = 0; + /* ESP register base */ - esp->eregs = (struct ESP_regs *) (system_base + SCSI); - + esp->eregs = (struct ESP_regs *) (system_base + IOASIC_SCSI); + /* Set the command buffer */ esp->esp_command = (volatile unsigned char *) cmd_buffer; - + /* get virtual dma address for command buffer */ - esp->esp_command_dvma = (__u32) KSEG1ADDR((volatile unsigned char *) cmd_buffer); - + esp->esp_command_dvma = virt_to_phys(cmd_buffer); + esp->irq = dec_interrupt[DEC_IRQ_ASC]; esp->scsi_id = 7; - + /* Check for differential SCSI-bus */ esp->diff = 0; esp_initialize(esp); - if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, + if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, "ncr53c94", NULL)) goto err_dealloc; if (request_irq(dec_interrupt[DEC_IRQ_ASC_MERR], - scsi_dma_merr_int, SA_INTERRUPT, + scsi_dma_merr_int, SA_INTERRUPT, "ncr53c94 error", NULL)) goto err_free_irq; if (request_irq(dec_interrupt[DEC_IRQ_ASC_ERR], - scsi_dma_err_int, SA_INTERRUPT, + scsi_dma_err_int, SA_INTERRUPT, "ncr53c94 overrun", NULL)) goto err_free_irq_merr; if (request_irq(dec_interrupt[DEC_IRQ_ASC_DMA], - scsi_dma_int, SA_INTERRUPT, + scsi_dma_int, SA_INTERRUPT, "ncr53c94 dma", NULL)) goto err_free_irq_err; - + } if (TURBOCHANNEL) { @@ -220,7 +195,7 @@ mem_start = get_tc_base_addr(slot); /* Store base addr into esp struct */ - esp->slot = mem_start; + esp->slot = PHYSADDR(mem_start); esp->dregs = 0; esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG); @@ -230,7 +205,7 @@ esp->esp_command = (volatile unsigned char *) pmaz_cmd_buffer; /* get virtual dma address for command buffer */ - esp->esp_command_dvma = (__u32) KSEG0ADDR((volatile unsigned char *) pmaz_cmd_buffer); + esp->esp_command_dvma = virt_to_phys(pmaz_cmd_buffer); esp->cfreq = get_tc_speed(); @@ -265,7 +240,7 @@ esp->dma_mmu_release_scsi_sgl = 0; esp->dma_advance_sg = 0; - if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, + if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, "PMAZ_AA", NULL)) { esp_deallocate(esp); release_tc_card(slot); @@ -310,40 +285,53 @@ static void scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs) { + u32 scsi_next_ptr; + + scsi_next_ptr = ioasic_read(IO_REG_SCSI_DMA_P); + /* next page */ - *scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3; + scsi_next_ptr = (((scsi_next_ptr >> 3) + PAGE_SIZE) & PAGE_MASK) << 3; + ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); fast_iob(); } static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) { - return fifo_count; + return fifo_count; } static void dma_drain(struct NCR_ESP *esp) { - unsigned long nw = *scsi_scr; - unsigned short *p = KSEG1ADDR((unsigned short *) ((*scsi_dma_ptr) >> 3)); + u32 nw, data0, data1, scsi_data_ptr; + u16 *p; + + nw = ioasic_read(IO_REG_SCSI_SCR); - /* + /* * Is there something in the dma buffers left? - */ + */ if (nw) { + scsi_data_ptr = ioasic_read(IO_REG_SCSI_DMA_P) >> 3; + p = phys_to_virt(scsi_data_ptr); switch (nw) { case 1: - *p = (unsigned short) *scsi_sdr0; + data0 = ioasic_read(IO_REG_SCSI_SDR0); + p[0] = data0 & 0xffff; break; case 2: - *p++ = (unsigned short) (*scsi_sdr0); - *p = (unsigned short) ((*scsi_sdr0) >> 16); + data0 = ioasic_read(IO_REG_SCSI_SDR0); + p[0] = data0 & 0xffff; + p[1] = (data0 >> 16) & 0xffff; break; case 3: - *p++ = (unsigned short) (*scsi_sdr0); - *p++ = (unsigned short) ((*scsi_sdr0) >> 16); - *p = (unsigned short) (*scsi_sdr1); + data0 = ioasic_read(IO_REG_SCSI_SDR0); + data1 = ioasic_read(IO_REG_SCSI_SDR1); + p[0] = data0 & 0xffff; + p[1] = (data0 >> 16) & 0xffff; + p[2] = data1 & 0xffff; break; default: - printk("Strange: %d words in dma buffer left\n", (int) nw); + printk("Strange: %d words in dma buffer left\n", nw); break; } } @@ -356,44 +344,74 @@ static void dma_dump_state(struct NCR_ESP *esp) { -/* - ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n", - esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_resdiue((int)esp->dregs))); - */ } -static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) +static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) { + u32 scsi_next_ptr, ioasic_ssr; + unsigned long flags; + if (vaddress & 3) - panic("dec_efs.c: unable to handle partial word transfers, yet..."); + panic("dec_esp.c: unable to handle partial word transfers, yet..."); dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length); - *ioasic_ssr &= ~SCSI_DMA_EN; - *scsi_scr = 0; - *scsi_dma_ptr = vaddress << 3; + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); + ioasic_ssr = ioasic_read(IO_REG_SSR); + + ioasic_ssr &= ~IO_SSR_SCSI_DMA_EN; + ioasic_write(IO_REG_SSR, ioasic_ssr); + + fast_wmb(); + ioasic_write(IO_REG_SCSI_SCR, 0); + ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3); /* prepare for next page */ - *scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; - *ioasic_ssr |= (SCSI_DMA_DIR | SCSI_DMA_EN); + scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; + ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); + + ioasic_ssr |= (IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN); + fast_wmb(); + ioasic_write(IO_REG_SSR, ioasic_ssr); + fast_iob(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); } -static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) +static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length) { + u32 scsi_next_ptr, ioasic_ssr; + unsigned long flags; + if (vaddress & 3) - panic("dec_efs.c: unable to handle partial word transfers, yet..."); + panic("dec_esp.c: unable to handle partial word transfers, yet..."); dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length); - *ioasic_ssr &= ~(SCSI_DMA_DIR | SCSI_DMA_EN); - *scsi_scr = 0; - *scsi_dma_ptr = vaddress << 3; + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); + ioasic_ssr = ioasic_read(IO_REG_SSR); + + ioasic_ssr &= ~(IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN); + ioasic_write(IO_REG_SSR, ioasic_ssr); + + fast_wmb(); + ioasic_write(IO_REG_SCSI_SCR, 0); + ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3); /* prepare for next page */ - *scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; - *ioasic_ssr |= SCSI_DMA_EN; + scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; + ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); + + ioasic_ssr |= IO_SSR_SCSI_DMA_EN; + fast_wmb(); + ioasic_write(IO_REG_SSR, ioasic_ssr); + fast_iob(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); } static void dma_ints_off(struct NCR_ESP *esp) @@ -408,71 +426,67 @@ static int dma_irq_p(struct NCR_ESP *esp) { - return (esp->eregs->esp_status & ESP_STAT_INTR); + return (esp->eregs->esp_status & ESP_STAT_INTR); } static int dma_ports_p(struct NCR_ESP *esp) { -/* - * FIXME: what's this good for? - */ + /* + * FIXME: what's this good for? + */ return 1; } -static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) +static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write) { - /* - * On the Sparc, DMA_ST_WRITE means "move data from device to memory" - * so when (write) is true, it actually means READ! - */ - if (write) { - dma_init_read(esp, addr, count); - } else { - dma_init_write(esp, addr, count); - } + /* + * DMA_ST_WRITE means "move data from device to memory" + * so when (write) is true, it actually means READ! + */ + if (write) + dma_init_read(esp, addr, count); + else + dma_init_write(esp, addr, count); } -/* - * These aren't used yet - */ static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp) { - sp->SCp.have_data_in = PHYSADDR(sp->SCp.buffer); - sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.have_data_in); + sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer); } static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp) { - int sz = sp->SCp.buffers_residual; - struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer; + int sz = sp->SCp.buffers_residual; + struct scatterlist *sg = sp->SCp.buffer; - while (sz >= 0) { - sg[sz].dvma_addr = PHYSADDR(sg[sz].addr); - sz--; - } - sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dma_address); + while (sz >= 0) { + sg[sz].dma_address = virt_to_phys(sg[sz].address); + sz--; + } + sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); } static void dma_advance_sg(Scsi_Cmnd * sp) { - sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dma_address); + sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); } static void pmaz_dma_drain(struct NCR_ESP *esp) { - memcpy((void *) (KSEG0ADDR(esp_virt_buffer)), - (void *) ( esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), + memcpy(phys_to_virt(esp_virt_buffer), + (void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), scsi_current_length); } -static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) +static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) { - volatile int *dmareg = (volatile int *) (esp->slot + DEC_SCSI_DMAREG); + volatile u32 *dmareg = + (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); if (length > ESP_TGT_DMA_SIZE) length = ESP_TGT_DMA_SIZE; - *dmareg = TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE); + *dmareg = TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE); iob(); @@ -480,15 +494,16 @@ scsi_current_length = length; } -static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) +static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length) { - volatile int *dmareg = (volatile int *) ( esp->slot + DEC_SCSI_DMAREG ); + volatile u32 *dmareg = + (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); - memcpy((void *) (esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), - KSEG0ADDR((void *) vaddress), length); + memcpy((void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), + phys_to_virt(vaddress), length); - *dmareg = TC_ESP_DMAR_WRITE | - TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE); + wmb(); + *dmareg = TC_ESP_DMAR_WRITE | TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE); iob(); } @@ -501,22 +516,19 @@ { } -static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) +static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write) { /* - * On the Sparc, DMA_ST_WRITE means "move data from device to memory" + * DMA_ST_WRITE means "move data from device to memory" * so when (write) is true, it actually means READ! */ - if (write) { + if (write) pmaz_dma_init_read(esp, addr, count); - } else { + else pmaz_dma_init_write(esp, addr, count); - } } static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp) { - sp->SCp.have_data_in = (int) sp->SCp.ptr = - (char *) KSEG0ADDR((sp->request_buffer)); + sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer); } - diff -urN linux-2.4.21/drivers/scsi/gdth.c linux-2.4.22/drivers/scsi/gdth.c --- linux-2.4.21/drivers/scsi/gdth.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/gdth.c 2003-08-25 04:44:42.000000000 -0700 @@ -4029,6 +4029,8 @@ break; if (gdth_search_isa(isa_bios)) { /* controller found */ shp = scsi_register(shtp,sizeof(gdth_ext_str)); + if(shp == NULL) + continue; ha = HADATA(shp); if (!gdth_init_isa(isa_bios,ha)) { scsi_unregister(shp); diff -urN linux-2.4.21/drivers/scsi/ide-scsi.c linux-2.4.22/drivers/scsi/ide-scsi.c --- linux-2.4.21/drivers/scsi/ide-scsi.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/ide-scsi.c 2003-08-25 04:44:42.000000000 -0700 @@ -1105,15 +1105,34 @@ int idescsi_reset (Scsi_Cmnd *cmd, unsigned int resetflags) { + return SCSI_RESET_SNOOZE; + +#ifdef WORK_IN_PROGRESS ide_drive_t *drive = idescsi_drives[cmd->target]; - /* We cannot reset the interface holding the lock. We can - drop the lock here however */ + /* At this point the state machine is running, that + requires we are especially careful. Ideally we want + to abort commands on timeout only if they hit the + cable but thats harder */ + + DRIVER(drive)->abort(drive, "scsi reset"); + if(HWGROUP(drive)->handler) + BUG(); + + /* Ok the state machine is halted but make sure it + doesn't restart too early */ - spin_unlock(&io_request_lock); - (void) ide_do_reset(drive); - spin_lock(&io_request_lock); + HWGROUP(drive)->busy = 1; + spin_unlock_irq(&io_request_lock); + + /* Apply the mallet of re-education firmly to the drive */ + ide_do_reset(drive); + + /* At this point the reset state machine is running and + its termination will kick off the next command */ + spin_lock_irq(&io_request_lock); return SCSI_RESET_SUCCESS; +#endif } int idescsi_bios (Disk *disk, kdev_t dev, int *parm) diff -urN linux-2.4.21/drivers/scsi/megaraid.c linux-2.4.22/drivers/scsi/megaraid.c --- linux-2.4.21/drivers/scsi/megaraid.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/megaraid.c 2003-08-25 04:44:42.000000000 -0700 @@ -4924,8 +4924,10 @@ if( !scsicmd->result && outlen ) { if (copy_to_user(uaddr, kvaddr, length)) + { ret = -EFAULT; goto out; + } } /* diff -urN linux-2.4.21/drivers/scsi/nsp32.h linux-2.4.22/drivers/scsi/nsp32.h --- linux-2.4.21/drivers/scsi/nsp32.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/nsp32.h 2003-08-25 04:44:42.000000000 -0700 @@ -425,5 +425,5 @@ #define BUSPHASE_STATUS ( BUSMON_STATUS & BUSMON_PHASE_MASK ) #define BUSPHASE_SELECT ( BUSMON_SEL | BUSMON_IO ) -#endif _NSP32_H +#endif /* _NSP32_H */ /* end */ diff -urN linux-2.4.21/drivers/scsi/nsp32_io.h linux-2.4.22/drivers/scsi/nsp32_io.h --- linux-2.4.21/drivers/scsi/nsp32_io.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/nsp32_io.h 2003-08-25 04:44:42.000000000 -0700 @@ -265,5 +265,5 @@ nsp32_multi_write4(base, FIFO_DATA_LOW, buf, count); } -#endif _NSP32_IO_H +#endif /* _NSP32_IO_H */ /* end */ diff -urN linux-2.4.21/drivers/scsi/pcmcia/aha152x_stub.c linux-2.4.22/drivers/scsi/pcmcia/aha152x_stub.c --- linux-2.4.21/drivers/scsi/pcmcia/aha152x_stub.c 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.22/drivers/scsi/pcmcia/aha152x_stub.c 2003-08-25 04:44:42.000000000 -0700 @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -139,8 +138,6 @@ if (!info) return NULL; memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; - link->release.function = &aha152x_release_cs; - link->release.data = (u_long)link; link->io.NumPorts1 = 0x20; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -193,7 +190,6 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) { aha152x_release_cs((u_long)link); if (link->state & DEV_STALE_CONFIG) { @@ -383,7 +379,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + aha152x_release_cs((u_long)link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -urN linux-2.4.21/drivers/scsi/pcmcia/fdomain_stub.c linux-2.4.22/drivers/scsi/pcmcia/fdomain_stub.c --- linux-2.4.21/drivers/scsi/pcmcia/fdomain_stub.c 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.22/drivers/scsi/pcmcia/fdomain_stub.c 2003-08-25 04:44:42.000000000 -0700 @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -125,8 +124,6 @@ if (!info) return NULL; memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; - link->release.function = &fdomain_release; - link->release.data = (u_long)link; link->io.NumPorts1 = 0x10; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -179,7 +176,6 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) { fdomain_release((u_long)link); if (link->state & DEV_STALE_CONFIG) { @@ -350,7 +346,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + fdomain_release((u_long)link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -urN linux-2.4.21/drivers/scsi/pcmcia/nsp_cs.c linux-2.4.22/drivers/scsi/pcmcia/nsp_cs.c --- linux-2.4.21/drivers/scsi/pcmcia/nsp_cs.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/pcmcia/nsp_cs.c 2003-08-25 04:44:42.000000000 -0700 @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -1341,10 +1340,6 @@ link = &info->link; link->priv = info; - /* Initialize the dev_link_t structure */ - link->release.function = &nsp_cs_release; - link->release.data = (u_long)link; - /* The io structure describes IO port mapping */ link->io.NumPorts1 = 0x10; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -1415,7 +1410,6 @@ return; } - del_timer(&link->release); if (link->state & DEV_CONFIG) { nsp_cs_release((u_long)link); if (link->state & DEV_STALE_CONFIG) { @@ -1660,7 +1654,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { ((scsi_info_t *)link->priv)->stop = 1; - mod_timer(&link->release, jiffies + HZ/20); + nsp_cs_release((u_long)link); } break; diff -urN linux-2.4.21/drivers/scsi/pcmcia/qlogic_stub.c linux-2.4.22/drivers/scsi/pcmcia/qlogic_stub.c --- linux-2.4.21/drivers/scsi/pcmcia/qlogic_stub.c 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.22/drivers/scsi/pcmcia/qlogic_stub.c 2003-08-25 04:44:42.000000000 -0700 @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -132,8 +131,6 @@ if (!info) return NULL; memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; - link->release.function = &qlogic_release; - link->release.data = (u_long)link; link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -186,7 +183,6 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) { qlogic_release((u_long)link); if (link->state & DEV_STALE_CONFIG) { @@ -371,7 +367,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + qlogic_release((u_long)link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -urN linux-2.4.21/drivers/scsi/scsi.c linux-2.4.22/drivers/scsi/scsi.c --- linux-2.4.21/drivers/scsi/scsi.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/scsi.c 2003-08-25 04:44:42.000000000 -0700 @@ -197,6 +197,7 @@ blk_init_queue(q, scsi_request_fn); blk_queue_headactive(q, 0); + blk_queue_throttle_sectors(q, 1); q->queuedata = (void *) SDpnt; } diff -urN linux-2.4.21/drivers/scsi/scsi.h linux-2.4.22/drivers/scsi/scsi.h --- linux-2.4.21/drivers/scsi/scsi.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/scsi.h 2003-08-25 04:44:42.000000000 -0700 @@ -608,6 +608,7 @@ unsigned remap:1; /* support remapping */ unsigned starved:1; /* unable to process commands because host busy */ + unsigned no_start_on_add:1; /* do not issue start on add */ // Flag to allow revalidate to succeed in sd_open int allow_revalidate; diff -urN linux-2.4.21/drivers/scsi/scsi_ioctl.c linux-2.4.22/drivers/scsi/scsi_ioctl.c --- linux-2.4.21/drivers/scsi/scsi_ioctl.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/scsi_ioctl.c 2003-08-25 04:44:42.000000000 -0700 @@ -279,6 +279,7 @@ cmd[1] = (cmd[1] & 0x1f) | (dev->lun << 5); switch (opcode) { + case SEND_DIAGNOSTIC: case FORMAT_UNIT: timeout = FORMAT_UNIT_TIMEOUT; retries = 1; diff -urN linux-2.4.21/drivers/scsi/scsi_lib.c linux-2.4.22/drivers/scsi/scsi_lib.c --- linux-2.4.21/drivers/scsi/scsi_lib.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/scsi_lib.c 2003-08-25 04:44:42.000000000 -0700 @@ -378,6 +378,7 @@ if ((bh = req->bh) != NULL) { nsect = bh->b_size >> 9; blk_finished_io(nsect); + blk_finished_sectors(req, nsect); req->bh = bh->b_reqnext; bh->b_reqnext = NULL; sectors -= nsect; diff -urN linux-2.4.21/drivers/scsi/scsi_scan.c linux-2.4.22/drivers/scsi/scsi_scan.c --- linux-2.4.21/drivers/scsi/scsi_scan.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/scsi_scan.c 2003-08-25 04:44:42.000000000 -0700 @@ -37,6 +37,8 @@ #define BLIST_ISDISK 0x100 /* Treat as (removable) disk */ #define BLIST_ISROM 0x200 /* Treat as (removable) CD-ROM */ #define BLIST_LARGELUN 0x400 /* LUNs larger than 7 despite reporting as SCSI 2 */ +#define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */ + static void print_inquiry(unsigned char *data); static int scan_scsis_single(unsigned int channel, unsigned int dev, @@ -110,9 +112,9 @@ {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */ {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */ {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */ - {"HP", "A6188A", "*", BLIST_SPARSELUN}, /* HP Va7100 Array */ - {"HP", "A6189A", "*", BLIST_SPARSELUN}, /* HP Va7400 Array */ - {"HP", "A6189B", "*", BLIST_SPARSELUN}, /* HP Va7410 Array */ + {"HP", "A6188A", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7100 Array */ + {"HP", "A6189A", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7400 Array */ + {"HP", "A6189B", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7410 Array */ {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 * extra reset */ @@ -145,7 +147,7 @@ {"EMULEX", "MD21/S2 ESDI", "*", BLIST_SINGLELUN}, {"CANON", "IPUBJD", "*", BLIST_SPARSELUN}, {"nCipher", "Fastness Crypto", "*", BLIST_FORCELUN}, - {"DEC","HSG80","*", BLIST_FORCELUN}, + {"DEC","HSG80","*", BLIST_FORCELUN | BLIST_NOSTARTONADD}, {"COMPAQ","LOGICAL VOLUME","*", BLIST_FORCELUN}, {"COMPAQ","CR3500","*", BLIST_FORCELUN}, {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, @@ -173,7 +175,10 @@ {"HP", "NetRAID-4M", "*", BLIST_FORCELUN}, {"ADAPTEC", "AACRAID", "*", BLIST_FORCELUN}, {"ADAPTEC", "Adaptec 5400S", "*", BLIST_FORCELUN}, - {"COMPAQ", "MSA1000", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"COMPAQ", "MSA1000", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD}, + {"COMPAQ", "MSA1000 VOLUME", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD}, + {"COMPAQ", "HSV110", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD}, + {"HP", "HSV100", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD}, {"HP", "C1557A", "*", BLIST_FORCELUN}, {"IBM", "AuSaV1S2", "*", BLIST_FORCELUN}, {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, @@ -182,7 +187,7 @@ {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "OPEN-", "*", BLIST_SPARSELUN}, /* HITACHI XP Arrays */ + {"HITACHI", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HITACHI XP Arrays */ {"WINSYS","FLASHDISK G6", "*", BLIST_SPARSELUN}, {"DotHill","SANnet RAID X300", "*", BLIST_SPARSELUN}, {"SUN", "T300", "*", BLIST_SPARSELUN}, @@ -194,6 +199,11 @@ {"SGI", "TP9400", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"SGI", "TP9500", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"PLATYPUS", "CX5", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"Raidtec", "FCR", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"HP", "C7200", "*", BLIST_SPARSELUN}, /* Medium Changer */ + {"SMSC", "USB 2 HS", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* * Must be at end of list... @@ -742,6 +752,13 @@ if ((bflags & BLIST_BORKEN) == 0) SDpnt->borken = 0; + /* + * Some devices may not want to have a start command automatically + * issued when a device is added. + */ + if (bflags & BLIST_NOSTARTONADD) + SDpnt->no_start_on_add = 1; + /* * If we want to only allow I/O to one of the luns attached to this device * at a time, then we set this flag. diff -urN linux-2.4.21/drivers/scsi/sd.c linux-2.4.22/drivers/scsi/sd.c --- linux-2.4.21/drivers/scsi/sd.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/sd.c 2003-08-25 04:44:42.000000000 -0700 @@ -774,7 +774,8 @@ char nbuff[6]; unsigned char *buffer; unsigned long spintime_value = 0; - int the_result, retries, spintime; + int retries, spintime; + unsigned int the_result; int sector_size; Scsi_Request *SRpnt; @@ -816,7 +817,7 @@ do { retries = 0; - while (retries < 3) { + do { cmd[0] = TEST_UNIT_READY; cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ? ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0; @@ -831,10 +832,10 @@ the_result = SRpnt->sr_result; retries++; - if (the_result == 0 - || SRpnt->sr_sense_buffer[2] != UNIT_ATTENTION) - break; - } + } while (retries < 3 + && (the_result !=0 + || ((driver_byte(the_result) & DRIVER_SENSE) + && SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION))); /* * If the drive has indicated to us that it doesn't have @@ -852,10 +853,33 @@ break; } + if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { + /* no sense, TUR either succeeded or failed + * with a status error */ + if(!spintime && the_result != 0) + printk(KERN_NOTICE "%s: Unit Not Ready, error = 0x%x\n", nbuff, the_result); + break; + } + + /* + * The device does not want the automatic start to be issued. + */ + if (rscsi_disks[i].device->no_start_on_add) { + break; + } + + /* + * If manual intervention is required, or this is an + * absent USB storage device, a spinup is meaningless. + */ + if (SRpnt->sr_sense_buffer[2] == NOT_READY && + SRpnt->sr_sense_buffer[12] == 4 /* not ready */ && + SRpnt->sr_sense_buffer[13] == 3) { + break; /* manual intervention required */ /* Look for non-removable devices that return NOT_READY. * Issue command to spin up drive for these cases. */ - if (the_result && !rscsi_disks[i].device->removable && - SRpnt->sr_sense_buffer[2] == NOT_READY) { + } else if (the_result && !rscsi_disks[i].device->removable && + SRpnt->sr_sense_buffer[2] == NOT_READY) { unsigned long time1; if (!spintime) { printk("%s: Spinning up disk...", nbuff); @@ -869,7 +893,7 @@ SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[2] = 0; - SRpnt->sr_data_direction = SCSI_DATA_READ; + SRpnt->sr_data_direction = SCSI_DATA_NONE; scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, 0/*512*/, SD_TIMEOUT, MAX_RETRIES); spintime_value = jiffies; @@ -882,6 +906,14 @@ time1 = schedule_timeout(time1); } while(time1); printk("."); + } else { + /* we don't understand the sense code, so it's + * probably pointless to loop */ + if(!spintime) { + printk(KERN_NOTICE "%s: Unit Not Ready, sense:\n", nbuff); + print_req_sense("", SRpnt); + } + break; } } while (the_result && spintime && time_after(spintime_value + 100 * HZ, jiffies)); diff -urN linux-2.4.21/drivers/scsi/seagate.c linux-2.4.22/drivers/scsi/seagate.c --- linux-2.4.21/drivers/scsi/seagate.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/seagate.c 2003-08-25 04:44:42.000000000 -0700 @@ -324,6 +324,8 @@ {"FUTURE DOMAIN TMC-950", 5, 21, FD}, /* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */ {"IBM F1 V1.2009/22/93", 5, 25, FD}, + /* Added for Dell Latitude XP 4100CX */ + {"Future Domain Corp. V1.0008/18/9364/32", 5, 38, FD}, }; #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature)) diff -urN linux-2.4.21/drivers/scsi/sgiwd93.c linux-2.4.22/drivers/scsi/sgiwd93.c --- linux-2.4.21/drivers/scsi/sgiwd93.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/scsi/sgiwd93.c 2003-08-25 04:44:42.000000000 -0700 @@ -24,9 +24,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -70,7 +70,6 @@ return value; } -/* XXX woof! */ static void sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; @@ -123,10 +122,10 @@ * IMHO a better fix would be, not to do these * dma setups in the first place */ - if (cmd->SCp.ptr == NULL) + if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries (&hcp, cmd->SCp.ptr,cmd->SCp.this_residual); + fill_hpc_entries (&hcp, cmd->SCp.ptr, cmd->SCp.this_residual); /* To make sure, if we trip an HPC bug, that we transfer * every single byte, we tag on an extra zero length dma @@ -230,7 +229,7 @@ sgiwd93_host->base = (unsigned long) hregs; sgiwd93_host->irq = SGI_WD93_0_IRQ; - buf = (uchar *) get_free_page(GFP_KERNEL); + buf = (uchar *) get_zeroed_page(GFP_KERNEL); if (!buf) { printk(KERN_WARNING "sgiwd93: Could not allocate memory for host0 buffer.\n"); scsi_unregister(sgiwd93_host); @@ -257,14 +256,14 @@ return 0; } /* set up second controller on the Indigo2 */ - if(!sgi_guiness) { + if(ip22_is_fullhouse()) { sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); if(sgiwd93_host1 != NULL) { sgiwd93_host1->base = (unsigned long) hregs1; sgiwd93_host1->irq = SGI_WD93_1_IRQ; - buf = (uchar *) get_free_page(GFP_KERNEL); + buf = (uchar *) get_zeroed_page(GFP_KERNEL); if (!buf) { printk(KERN_WARNING "sgiwd93: Could not allocate memory for host1 buffer.\n"); scsi_unregister(sgiwd93_host1); @@ -314,7 +313,7 @@ free_irq(SGI_WD93_0_IRQ, sgiwd93_intr); free_page(KSEG0ADDR(hdata->dma_bounce_buffer)); wd33c93_release(); - if(!sgi_guiness) { + if(ip22_is_fullhouse()) { free_irq(SGI_WD93_1_IRQ, sgiwd93_intr); free_page(KSEG0ADDR(hdata1->dma_bounce_buffer)); wd33c93_release(); diff -urN linux-2.4.21/drivers/scsi/sim710_d.h linux-2.4.22/drivers/scsi/sim710_d.h --- linux-2.4.21/drivers/scsi/sim710_d.h 1999-12-08 15:17:55.000000000 -0800 +++ linux-2.4.22/drivers/scsi/sim710_d.h 2003-08-25 04:44:42.000000000 -0700 @@ -18,15 +18,12 @@ ABSOLUTE reselected_identify = 0 ABSOLUTE msgin_buf = 0 +ABSOLUTE msg_reject = 0 +ABSOLUTE test1_src = 0 +ABSOLUTE test1_dst = 0 -ABSOLUTE int_bad_extmsg1a = 0xab930000 -ABSOLUTE int_bad_extmsg1b = 0xab930001 -ABSOLUTE int_bad_extmsg2a = 0xab930002 -ABSOLUTE int_bad_extmsg2b = 0xab930003 -ABSOLUTE int_bad_extmsg3a = 0xab930004 -ABSOLUTE int_bad_extmsg3b = 0xab930005 ABSOLUTE int_bad_msg1 = 0xab930006 ABSOLUTE int_bad_msg2 = 0xab930007 ABSOLUTE int_bad_msg3 = 0xab930008 @@ -50,7 +47,7 @@ ABSOLUTE int_disc2 = 0xab93001a ABSOLUTE int_disc3 = 0xab93001b ABSOLUTE int_not_rej = 0xab93001c - +ABSOLUTE int_test1 = 0xab93001d @@ -65,6 +62,9 @@ +ABSOLUTE did_reject = 0x01 + + @@ -74,1641 +74,1709 @@ at 0x00000000 : */ 0x60000200,0x00000000, /* - MOVE SCRATCH0 & 0 TO SCRATCH0 - -at 0x00000002 : */ 0x7c340000,0x00000000, -/* ; Enable selection timer MOVE CTEST7 & 0xef TO CTEST7 -at 0x00000004 : */ 0x7c1bef00,0x00000000, +at 0x00000002 : */ 0x7c1bef00,0x00000000, /* SELECT ATN FROM dsa_select, reselect -at 0x00000006 : */ 0x43000000,0x00000c48, +at 0x00000004 : */ 0x43000000,0x00000cd0, /* JUMP get_status, WHEN STATUS -at 0x00000008 : */ 0x830b0000,0x000000a0, +at 0x00000006 : */ 0x830b0000,0x00000098, /* ; Disable selection timer MOVE CTEST7 | 0x10 TO CTEST7 -at 0x0000000a : */ 0x7a1b1000,0x00000000, +at 0x00000008 : */ 0x7a1b1000,0x00000000, /* MOVE SCRATCH0 | had_select TO SCRATCH0 -at 0x0000000c : */ 0x7a340100,0x00000000, +at 0x0000000a : */ 0x7a340100,0x00000000, /* INT int_sel_no_ident, IF NOT MSG_OUT -at 0x0000000e : */ 0x9e020000,0xab930013, +at 0x0000000c : */ 0x9e020000,0xab930013, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x00000010 : */ 0x7a340200,0x00000000, +at 0x0000000e : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x00000012 : */ 0x1e000000,0x00000008, +at 0x00000010 : */ 0x1e000000,0x00000008, /* ENTRY done_ident done_ident: JUMP get_status, IF STATUS -at 0x00000014 : */ 0x830a0000,0x000000a0, +at 0x00000012 : */ 0x830a0000,0x00000098, /* redo_msgin1: JUMP get_msgin1, WHEN MSG_IN -at 0x00000016 : */ 0x870b0000,0x00000920, +at 0x00000014 : */ 0x870b0000,0x00000918, /* INT int_sel_not_cmd, IF NOT CMD -at 0x00000018 : */ 0x9a020000,0xab930014, +at 0x00000016 : */ 0x9a020000,0xab930014, /* ENTRY resume_cmd resume_cmd: MOVE SCRATCH0 | had_cmdout TO SCRATCH0 -at 0x0000001a : */ 0x7a340400,0x00000000, +at 0x00000018 : */ 0x7a340400,0x00000000, /* MOVE FROM dsa_cmnd, WHEN CMD -at 0x0000001c : */ 0x1a000000,0x00000010, +at 0x0000001a : */ 0x1a000000,0x00000010, /* ENTRY resume_pmm resume_pmm: redo_msgin2: JUMP get_msgin2, WHEN MSG_IN -at 0x0000001e : */ 0x870b0000,0x00000a20, +at 0x0000001c : */ 0x870b0000,0x00000a48, /* JUMP get_status, IF STATUS -at 0x00000020 : */ 0x830a0000,0x000000a0, +at 0x0000001e : */ 0x830a0000,0x00000098, /* JUMP input_data, IF DATA_IN -at 0x00000022 : */ 0x810a0000,0x000000e0, +at 0x00000020 : */ 0x810a0000,0x000000d8, /* JUMP output_data, IF DATA_OUT -at 0x00000024 : */ 0x800a0000,0x000004f8, +at 0x00000022 : */ 0x800a0000,0x000004f0, /* INT int_cmd_bad_phase -at 0x00000026 : */ 0x98080000,0xab930009, +at 0x00000024 : */ 0x98080000,0xab930009, /* get_status: ; Disable selection timer MOVE CTEST7 | 0x10 TO CTEST7 -at 0x00000028 : */ 0x7a1b1000,0x00000000, +at 0x00000026 : */ 0x7a1b1000,0x00000000, /* MOVE FROM dsa_status, WHEN STATUS -at 0x0000002a : */ 0x1b000000,0x00000018, +at 0x00000028 : */ 0x1b000000,0x00000018, /* INT int_status_not_msgin, WHEN NOT MSG_IN -at 0x0000002c : */ 0x9f030000,0xab930015, +at 0x0000002a : */ 0x9f030000,0xab930015, /* MOVE FROM dsa_msgin, WHEN MSG_IN -at 0x0000002e : */ 0x1f000000,0x00000020, +at 0x0000002c : */ 0x1f000000,0x00000020, /* INT int_not_cmd_complete, IF NOT 0x00 -at 0x00000030 : */ 0x98040000,0xab930012, +at 0x0000002e : */ 0x98040000,0xab930012, /* CLEAR ACK -at 0x00000032 : */ 0x60000040,0x00000000, +at 0x00000030 : */ 0x60000040,0x00000000, /* ENTRY wait_disc_complete wait_disc_complete: WAIT DISCONNECT -at 0x00000034 : */ 0x48000000,0x00000000, +at 0x00000032 : */ 0x48000000,0x00000000, /* INT int_cmd_complete -at 0x00000036 : */ 0x98080000,0xab93000a, +at 0x00000034 : */ 0x98080000,0xab93000a, /* input_data: MOVE SCRATCH0 | had_datain TO SCRATCH0 -at 0x00000038 : */ 0x7a340800,0x00000000, +at 0x00000036 : */ 0x7a340800,0x00000000, /* ENTRY patch_input_data patch_input_data: JUMP 0 -at 0x0000003a : */ 0x80080000,0x00000000, +at 0x00000038 : */ 0x80080000,0x00000000, /* MOVE FROM dsa_datain+0x0000, WHEN DATA_IN -at 0x0000003c : */ 0x19000000,0x00000028, +at 0x0000003a : */ 0x19000000,0x00000028, /* MOVE FROM dsa_datain+0x0008, WHEN DATA_IN -at 0x0000003e : */ 0x19000000,0x00000030, +at 0x0000003c : */ 0x19000000,0x00000030, /* MOVE FROM dsa_datain+0x0010, WHEN DATA_IN -at 0x00000040 : */ 0x19000000,0x00000038, +at 0x0000003e : */ 0x19000000,0x00000038, /* MOVE FROM dsa_datain+0x0018, WHEN DATA_IN -at 0x00000042 : */ 0x19000000,0x00000040, +at 0x00000040 : */ 0x19000000,0x00000040, /* MOVE FROM dsa_datain+0x0020, WHEN DATA_IN -at 0x00000044 : */ 0x19000000,0x00000048, +at 0x00000042 : */ 0x19000000,0x00000048, /* MOVE FROM dsa_datain+0x0028, WHEN DATA_IN -at 0x00000046 : */ 0x19000000,0x00000050, +at 0x00000044 : */ 0x19000000,0x00000050, /* MOVE FROM dsa_datain+0x0030, WHEN DATA_IN -at 0x00000048 : */ 0x19000000,0x00000058, +at 0x00000046 : */ 0x19000000,0x00000058, /* MOVE FROM dsa_datain+0x0038, WHEN DATA_IN -at 0x0000004a : */ 0x19000000,0x00000060, +at 0x00000048 : */ 0x19000000,0x00000060, /* MOVE FROM dsa_datain+0x0040, WHEN DATA_IN -at 0x0000004c : */ 0x19000000,0x00000068, +at 0x0000004a : */ 0x19000000,0x00000068, /* MOVE FROM dsa_datain+0x0048, WHEN DATA_IN -at 0x0000004e : */ 0x19000000,0x00000070, +at 0x0000004c : */ 0x19000000,0x00000070, /* MOVE FROM dsa_datain+0x0050, WHEN DATA_IN -at 0x00000050 : */ 0x19000000,0x00000078, +at 0x0000004e : */ 0x19000000,0x00000078, /* MOVE FROM dsa_datain+0x0058, WHEN DATA_IN -at 0x00000052 : */ 0x19000000,0x00000080, +at 0x00000050 : */ 0x19000000,0x00000080, /* MOVE FROM dsa_datain+0x0060, WHEN DATA_IN -at 0x00000054 : */ 0x19000000,0x00000088, +at 0x00000052 : */ 0x19000000,0x00000088, /* MOVE FROM dsa_datain+0x0068, WHEN DATA_IN -at 0x00000056 : */ 0x19000000,0x00000090, +at 0x00000054 : */ 0x19000000,0x00000090, /* MOVE FROM dsa_datain+0x0070, WHEN DATA_IN -at 0x00000058 : */ 0x19000000,0x00000098, +at 0x00000056 : */ 0x19000000,0x00000098, /* MOVE FROM dsa_datain+0x0078, WHEN DATA_IN -at 0x0000005a : */ 0x19000000,0x000000a0, +at 0x00000058 : */ 0x19000000,0x000000a0, /* MOVE FROM dsa_datain+0x0080, WHEN DATA_IN -at 0x0000005c : */ 0x19000000,0x000000a8, +at 0x0000005a : */ 0x19000000,0x000000a8, /* MOVE FROM dsa_datain+0x0088, WHEN DATA_IN -at 0x0000005e : */ 0x19000000,0x000000b0, +at 0x0000005c : */ 0x19000000,0x000000b0, /* MOVE FROM dsa_datain+0x0090, WHEN DATA_IN -at 0x00000060 : */ 0x19000000,0x000000b8, +at 0x0000005e : */ 0x19000000,0x000000b8, /* MOVE FROM dsa_datain+0x0098, WHEN DATA_IN -at 0x00000062 : */ 0x19000000,0x000000c0, +at 0x00000060 : */ 0x19000000,0x000000c0, /* MOVE FROM dsa_datain+0x00a0, WHEN DATA_IN -at 0x00000064 : */ 0x19000000,0x000000c8, +at 0x00000062 : */ 0x19000000,0x000000c8, /* MOVE FROM dsa_datain+0x00a8, WHEN DATA_IN -at 0x00000066 : */ 0x19000000,0x000000d0, +at 0x00000064 : */ 0x19000000,0x000000d0, /* MOVE FROM dsa_datain+0x00b0, WHEN DATA_IN -at 0x00000068 : */ 0x19000000,0x000000d8, +at 0x00000066 : */ 0x19000000,0x000000d8, /* MOVE FROM dsa_datain+0x00b8, WHEN DATA_IN -at 0x0000006a : */ 0x19000000,0x000000e0, +at 0x00000068 : */ 0x19000000,0x000000e0, /* MOVE FROM dsa_datain+0x00c0, WHEN DATA_IN -at 0x0000006c : */ 0x19000000,0x000000e8, +at 0x0000006a : */ 0x19000000,0x000000e8, /* MOVE FROM dsa_datain+0x00c8, WHEN DATA_IN -at 0x0000006e : */ 0x19000000,0x000000f0, +at 0x0000006c : */ 0x19000000,0x000000f0, /* MOVE FROM dsa_datain+0x00d0, WHEN DATA_IN -at 0x00000070 : */ 0x19000000,0x000000f8, +at 0x0000006e : */ 0x19000000,0x000000f8, /* MOVE FROM dsa_datain+0x00d8, WHEN DATA_IN -at 0x00000072 : */ 0x19000000,0x00000100, +at 0x00000070 : */ 0x19000000,0x00000100, /* MOVE FROM dsa_datain+0x00e0, WHEN DATA_IN -at 0x00000074 : */ 0x19000000,0x00000108, +at 0x00000072 : */ 0x19000000,0x00000108, /* MOVE FROM dsa_datain+0x00e8, WHEN DATA_IN -at 0x00000076 : */ 0x19000000,0x00000110, +at 0x00000074 : */ 0x19000000,0x00000110, /* MOVE FROM dsa_datain+0x00f0, WHEN DATA_IN -at 0x00000078 : */ 0x19000000,0x00000118, +at 0x00000076 : */ 0x19000000,0x00000118, /* MOVE FROM dsa_datain+0x00f8, WHEN DATA_IN -at 0x0000007a : */ 0x19000000,0x00000120, +at 0x00000078 : */ 0x19000000,0x00000120, /* MOVE FROM dsa_datain+0x0100, WHEN DATA_IN -at 0x0000007c : */ 0x19000000,0x00000128, +at 0x0000007a : */ 0x19000000,0x00000128, /* MOVE FROM dsa_datain+0x0108, WHEN DATA_IN -at 0x0000007e : */ 0x19000000,0x00000130, +at 0x0000007c : */ 0x19000000,0x00000130, /* MOVE FROM dsa_datain+0x0110, WHEN DATA_IN -at 0x00000080 : */ 0x19000000,0x00000138, +at 0x0000007e : */ 0x19000000,0x00000138, /* MOVE FROM dsa_datain+0x0118, WHEN DATA_IN -at 0x00000082 : */ 0x19000000,0x00000140, +at 0x00000080 : */ 0x19000000,0x00000140, /* MOVE FROM dsa_datain+0x0120, WHEN DATA_IN -at 0x00000084 : */ 0x19000000,0x00000148, +at 0x00000082 : */ 0x19000000,0x00000148, /* MOVE FROM dsa_datain+0x0128, WHEN DATA_IN -at 0x00000086 : */ 0x19000000,0x00000150, +at 0x00000084 : */ 0x19000000,0x00000150, /* MOVE FROM dsa_datain+0x0130, WHEN DATA_IN -at 0x00000088 : */ 0x19000000,0x00000158, +at 0x00000086 : */ 0x19000000,0x00000158, /* MOVE FROM dsa_datain+0x0138, WHEN DATA_IN -at 0x0000008a : */ 0x19000000,0x00000160, +at 0x00000088 : */ 0x19000000,0x00000160, /* MOVE FROM dsa_datain+0x0140, WHEN DATA_IN -at 0x0000008c : */ 0x19000000,0x00000168, +at 0x0000008a : */ 0x19000000,0x00000168, /* MOVE FROM dsa_datain+0x0148, WHEN DATA_IN -at 0x0000008e : */ 0x19000000,0x00000170, +at 0x0000008c : */ 0x19000000,0x00000170, /* MOVE FROM dsa_datain+0x0150, WHEN DATA_IN -at 0x00000090 : */ 0x19000000,0x00000178, +at 0x0000008e : */ 0x19000000,0x00000178, /* MOVE FROM dsa_datain+0x0158, WHEN DATA_IN -at 0x00000092 : */ 0x19000000,0x00000180, +at 0x00000090 : */ 0x19000000,0x00000180, /* MOVE FROM dsa_datain+0x0160, WHEN DATA_IN -at 0x00000094 : */ 0x19000000,0x00000188, +at 0x00000092 : */ 0x19000000,0x00000188, /* MOVE FROM dsa_datain+0x0168, WHEN DATA_IN -at 0x00000096 : */ 0x19000000,0x00000190, +at 0x00000094 : */ 0x19000000,0x00000190, /* MOVE FROM dsa_datain+0x0170, WHEN DATA_IN -at 0x00000098 : */ 0x19000000,0x00000198, +at 0x00000096 : */ 0x19000000,0x00000198, /* MOVE FROM dsa_datain+0x0178, WHEN DATA_IN -at 0x0000009a : */ 0x19000000,0x000001a0, +at 0x00000098 : */ 0x19000000,0x000001a0, /* MOVE FROM dsa_datain+0x0180, WHEN DATA_IN -at 0x0000009c : */ 0x19000000,0x000001a8, +at 0x0000009a : */ 0x19000000,0x000001a8, /* MOVE FROM dsa_datain+0x0188, WHEN DATA_IN -at 0x0000009e : */ 0x19000000,0x000001b0, +at 0x0000009c : */ 0x19000000,0x000001b0, /* MOVE FROM dsa_datain+0x0190, WHEN DATA_IN -at 0x000000a0 : */ 0x19000000,0x000001b8, +at 0x0000009e : */ 0x19000000,0x000001b8, /* MOVE FROM dsa_datain+0x0198, WHEN DATA_IN -at 0x000000a2 : */ 0x19000000,0x000001c0, +at 0x000000a0 : */ 0x19000000,0x000001c0, /* MOVE FROM dsa_datain+0x01a0, WHEN DATA_IN -at 0x000000a4 : */ 0x19000000,0x000001c8, +at 0x000000a2 : */ 0x19000000,0x000001c8, /* MOVE FROM dsa_datain+0x01a8, WHEN DATA_IN -at 0x000000a6 : */ 0x19000000,0x000001d0, +at 0x000000a4 : */ 0x19000000,0x000001d0, /* MOVE FROM dsa_datain+0x01b0, WHEN DATA_IN -at 0x000000a8 : */ 0x19000000,0x000001d8, +at 0x000000a6 : */ 0x19000000,0x000001d8, /* MOVE FROM dsa_datain+0x01b8, WHEN DATA_IN -at 0x000000aa : */ 0x19000000,0x000001e0, +at 0x000000a8 : */ 0x19000000,0x000001e0, /* MOVE FROM dsa_datain+0x01c0, WHEN DATA_IN -at 0x000000ac : */ 0x19000000,0x000001e8, +at 0x000000aa : */ 0x19000000,0x000001e8, /* MOVE FROM dsa_datain+0x01c8, WHEN DATA_IN -at 0x000000ae : */ 0x19000000,0x000001f0, +at 0x000000ac : */ 0x19000000,0x000001f0, /* MOVE FROM dsa_datain+0x01d0, WHEN DATA_IN -at 0x000000b0 : */ 0x19000000,0x000001f8, +at 0x000000ae : */ 0x19000000,0x000001f8, /* MOVE FROM dsa_datain+0x01d8, WHEN DATA_IN -at 0x000000b2 : */ 0x19000000,0x00000200, +at 0x000000b0 : */ 0x19000000,0x00000200, /* MOVE FROM dsa_datain+0x01e0, WHEN DATA_IN -at 0x000000b4 : */ 0x19000000,0x00000208, +at 0x000000b2 : */ 0x19000000,0x00000208, /* MOVE FROM dsa_datain+0x01e8, WHEN DATA_IN -at 0x000000b6 : */ 0x19000000,0x00000210, +at 0x000000b4 : */ 0x19000000,0x00000210, /* MOVE FROM dsa_datain+0x01f0, WHEN DATA_IN -at 0x000000b8 : */ 0x19000000,0x00000218, +at 0x000000b6 : */ 0x19000000,0x00000218, /* MOVE FROM dsa_datain+0x01f8, WHEN DATA_IN -at 0x000000ba : */ 0x19000000,0x00000220, +at 0x000000b8 : */ 0x19000000,0x00000220, /* MOVE FROM dsa_datain+0x0200, WHEN DATA_IN -at 0x000000bc : */ 0x19000000,0x00000228, +at 0x000000ba : */ 0x19000000,0x00000228, /* MOVE FROM dsa_datain+0x0208, WHEN DATA_IN -at 0x000000be : */ 0x19000000,0x00000230, +at 0x000000bc : */ 0x19000000,0x00000230, /* MOVE FROM dsa_datain+0x0210, WHEN DATA_IN -at 0x000000c0 : */ 0x19000000,0x00000238, +at 0x000000be : */ 0x19000000,0x00000238, /* MOVE FROM dsa_datain+0x0218, WHEN DATA_IN -at 0x000000c2 : */ 0x19000000,0x00000240, +at 0x000000c0 : */ 0x19000000,0x00000240, /* MOVE FROM dsa_datain+0x0220, WHEN DATA_IN -at 0x000000c4 : */ 0x19000000,0x00000248, +at 0x000000c2 : */ 0x19000000,0x00000248, /* MOVE FROM dsa_datain+0x0228, WHEN DATA_IN -at 0x000000c6 : */ 0x19000000,0x00000250, +at 0x000000c4 : */ 0x19000000,0x00000250, /* MOVE FROM dsa_datain+0x0230, WHEN DATA_IN -at 0x000000c8 : */ 0x19000000,0x00000258, +at 0x000000c6 : */ 0x19000000,0x00000258, /* MOVE FROM dsa_datain+0x0238, WHEN DATA_IN -at 0x000000ca : */ 0x19000000,0x00000260, +at 0x000000c8 : */ 0x19000000,0x00000260, /* MOVE FROM dsa_datain+0x0240, WHEN DATA_IN -at 0x000000cc : */ 0x19000000,0x00000268, +at 0x000000ca : */ 0x19000000,0x00000268, /* MOVE FROM dsa_datain+0x0248, WHEN DATA_IN -at 0x000000ce : */ 0x19000000,0x00000270, +at 0x000000cc : */ 0x19000000,0x00000270, /* MOVE FROM dsa_datain+0x0250, WHEN DATA_IN -at 0x000000d0 : */ 0x19000000,0x00000278, +at 0x000000ce : */ 0x19000000,0x00000278, /* MOVE FROM dsa_datain+0x0258, WHEN DATA_IN -at 0x000000d2 : */ 0x19000000,0x00000280, +at 0x000000d0 : */ 0x19000000,0x00000280, /* MOVE FROM dsa_datain+0x0260, WHEN DATA_IN -at 0x000000d4 : */ 0x19000000,0x00000288, +at 0x000000d2 : */ 0x19000000,0x00000288, /* MOVE FROM dsa_datain+0x0268, WHEN DATA_IN -at 0x000000d6 : */ 0x19000000,0x00000290, +at 0x000000d4 : */ 0x19000000,0x00000290, /* MOVE FROM dsa_datain+0x0270, WHEN DATA_IN -at 0x000000d8 : */ 0x19000000,0x00000298, +at 0x000000d6 : */ 0x19000000,0x00000298, /* MOVE FROM dsa_datain+0x0278, WHEN DATA_IN -at 0x000000da : */ 0x19000000,0x000002a0, +at 0x000000d8 : */ 0x19000000,0x000002a0, /* MOVE FROM dsa_datain+0x0280, WHEN DATA_IN -at 0x000000dc : */ 0x19000000,0x000002a8, +at 0x000000da : */ 0x19000000,0x000002a8, /* MOVE FROM dsa_datain+0x0288, WHEN DATA_IN -at 0x000000de : */ 0x19000000,0x000002b0, +at 0x000000dc : */ 0x19000000,0x000002b0, /* MOVE FROM dsa_datain+0x0290, WHEN DATA_IN -at 0x000000e0 : */ 0x19000000,0x000002b8, +at 0x000000de : */ 0x19000000,0x000002b8, /* MOVE FROM dsa_datain+0x0298, WHEN DATA_IN -at 0x000000e2 : */ 0x19000000,0x000002c0, +at 0x000000e0 : */ 0x19000000,0x000002c0, /* MOVE FROM dsa_datain+0x02a0, WHEN DATA_IN -at 0x000000e4 : */ 0x19000000,0x000002c8, +at 0x000000e2 : */ 0x19000000,0x000002c8, /* MOVE FROM dsa_datain+0x02a8, WHEN DATA_IN -at 0x000000e6 : */ 0x19000000,0x000002d0, +at 0x000000e4 : */ 0x19000000,0x000002d0, /* MOVE FROM dsa_datain+0x02b0, WHEN DATA_IN -at 0x000000e8 : */ 0x19000000,0x000002d8, +at 0x000000e6 : */ 0x19000000,0x000002d8, /* MOVE FROM dsa_datain+0x02b8, WHEN DATA_IN -at 0x000000ea : */ 0x19000000,0x000002e0, +at 0x000000e8 : */ 0x19000000,0x000002e0, /* MOVE FROM dsa_datain+0x02c0, WHEN DATA_IN -at 0x000000ec : */ 0x19000000,0x000002e8, +at 0x000000ea : */ 0x19000000,0x000002e8, /* MOVE FROM dsa_datain+0x02c8, WHEN DATA_IN -at 0x000000ee : */ 0x19000000,0x000002f0, +at 0x000000ec : */ 0x19000000,0x000002f0, /* MOVE FROM dsa_datain+0x02d0, WHEN DATA_IN -at 0x000000f0 : */ 0x19000000,0x000002f8, +at 0x000000ee : */ 0x19000000,0x000002f8, /* MOVE FROM dsa_datain+0x02d8, WHEN DATA_IN -at 0x000000f2 : */ 0x19000000,0x00000300, +at 0x000000f0 : */ 0x19000000,0x00000300, /* MOVE FROM dsa_datain+0x02e0, WHEN DATA_IN -at 0x000000f4 : */ 0x19000000,0x00000308, +at 0x000000f2 : */ 0x19000000,0x00000308, /* MOVE FROM dsa_datain+0x02e8, WHEN DATA_IN -at 0x000000f6 : */ 0x19000000,0x00000310, +at 0x000000f4 : */ 0x19000000,0x00000310, /* MOVE FROM dsa_datain+0x02f0, WHEN DATA_IN -at 0x000000f8 : */ 0x19000000,0x00000318, +at 0x000000f6 : */ 0x19000000,0x00000318, /* MOVE FROM dsa_datain+0x02f8, WHEN DATA_IN -at 0x000000fa : */ 0x19000000,0x00000320, +at 0x000000f8 : */ 0x19000000,0x00000320, /* MOVE FROM dsa_datain+0x0300, WHEN DATA_IN -at 0x000000fc : */ 0x19000000,0x00000328, +at 0x000000fa : */ 0x19000000,0x00000328, /* MOVE FROM dsa_datain+0x0308, WHEN DATA_IN -at 0x000000fe : */ 0x19000000,0x00000330, +at 0x000000fc : */ 0x19000000,0x00000330, /* MOVE FROM dsa_datain+0x0310, WHEN DATA_IN -at 0x00000100 : */ 0x19000000,0x00000338, +at 0x000000fe : */ 0x19000000,0x00000338, /* MOVE FROM dsa_datain+0x0318, WHEN DATA_IN -at 0x00000102 : */ 0x19000000,0x00000340, +at 0x00000100 : */ 0x19000000,0x00000340, /* MOVE FROM dsa_datain+0x0320, WHEN DATA_IN -at 0x00000104 : */ 0x19000000,0x00000348, +at 0x00000102 : */ 0x19000000,0x00000348, /* MOVE FROM dsa_datain+0x0328, WHEN DATA_IN -at 0x00000106 : */ 0x19000000,0x00000350, +at 0x00000104 : */ 0x19000000,0x00000350, /* MOVE FROM dsa_datain+0x0330, WHEN DATA_IN -at 0x00000108 : */ 0x19000000,0x00000358, +at 0x00000106 : */ 0x19000000,0x00000358, /* MOVE FROM dsa_datain+0x0338, WHEN DATA_IN -at 0x0000010a : */ 0x19000000,0x00000360, +at 0x00000108 : */ 0x19000000,0x00000360, /* MOVE FROM dsa_datain+0x0340, WHEN DATA_IN -at 0x0000010c : */ 0x19000000,0x00000368, +at 0x0000010a : */ 0x19000000,0x00000368, /* MOVE FROM dsa_datain+0x0348, WHEN DATA_IN -at 0x0000010e : */ 0x19000000,0x00000370, +at 0x0000010c : */ 0x19000000,0x00000370, /* MOVE FROM dsa_datain+0x0350, WHEN DATA_IN -at 0x00000110 : */ 0x19000000,0x00000378, +at 0x0000010e : */ 0x19000000,0x00000378, /* MOVE FROM dsa_datain+0x0358, WHEN DATA_IN -at 0x00000112 : */ 0x19000000,0x00000380, +at 0x00000110 : */ 0x19000000,0x00000380, /* MOVE FROM dsa_datain+0x0360, WHEN DATA_IN -at 0x00000114 : */ 0x19000000,0x00000388, +at 0x00000112 : */ 0x19000000,0x00000388, /* MOVE FROM dsa_datain+0x0368, WHEN DATA_IN -at 0x00000116 : */ 0x19000000,0x00000390, +at 0x00000114 : */ 0x19000000,0x00000390, /* MOVE FROM dsa_datain+0x0370, WHEN DATA_IN -at 0x00000118 : */ 0x19000000,0x00000398, +at 0x00000116 : */ 0x19000000,0x00000398, /* MOVE FROM dsa_datain+0x0378, WHEN DATA_IN -at 0x0000011a : */ 0x19000000,0x000003a0, +at 0x00000118 : */ 0x19000000,0x000003a0, /* MOVE FROM dsa_datain+0x0380, WHEN DATA_IN -at 0x0000011c : */ 0x19000000,0x000003a8, +at 0x0000011a : */ 0x19000000,0x000003a8, /* MOVE FROM dsa_datain+0x0388, WHEN DATA_IN -at 0x0000011e : */ 0x19000000,0x000003b0, +at 0x0000011c : */ 0x19000000,0x000003b0, /* MOVE FROM dsa_datain+0x0390, WHEN DATA_IN -at 0x00000120 : */ 0x19000000,0x000003b8, +at 0x0000011e : */ 0x19000000,0x000003b8, /* MOVE FROM dsa_datain+0x0398, WHEN DATA_IN -at 0x00000122 : */ 0x19000000,0x000003c0, +at 0x00000120 : */ 0x19000000,0x000003c0, /* MOVE FROM dsa_datain+0x03a0, WHEN DATA_IN -at 0x00000124 : */ 0x19000000,0x000003c8, +at 0x00000122 : */ 0x19000000,0x000003c8, /* MOVE FROM dsa_datain+0x03a8, WHEN DATA_IN -at 0x00000126 : */ 0x19000000,0x000003d0, +at 0x00000124 : */ 0x19000000,0x000003d0, /* MOVE FROM dsa_datain+0x03b0, WHEN DATA_IN -at 0x00000128 : */ 0x19000000,0x000003d8, +at 0x00000126 : */ 0x19000000,0x000003d8, /* MOVE FROM dsa_datain+0x03b8, WHEN DATA_IN -at 0x0000012a : */ 0x19000000,0x000003e0, +at 0x00000128 : */ 0x19000000,0x000003e0, /* MOVE FROM dsa_datain+0x03c0, WHEN DATA_IN -at 0x0000012c : */ 0x19000000,0x000003e8, +at 0x0000012a : */ 0x19000000,0x000003e8, /* MOVE FROM dsa_datain+0x03c8, WHEN DATA_IN -at 0x0000012e : */ 0x19000000,0x000003f0, +at 0x0000012c : */ 0x19000000,0x000003f0, /* MOVE FROM dsa_datain+0x03d0, WHEN DATA_IN -at 0x00000130 : */ 0x19000000,0x000003f8, +at 0x0000012e : */ 0x19000000,0x000003f8, /* MOVE FROM dsa_datain+0x03d8, WHEN DATA_IN -at 0x00000132 : */ 0x19000000,0x00000400, +at 0x00000130 : */ 0x19000000,0x00000400, /* MOVE FROM dsa_datain+0x03e0, WHEN DATA_IN -at 0x00000134 : */ 0x19000000,0x00000408, +at 0x00000132 : */ 0x19000000,0x00000408, /* MOVE FROM dsa_datain+0x03e8, WHEN DATA_IN -at 0x00000136 : */ 0x19000000,0x00000410, +at 0x00000134 : */ 0x19000000,0x00000410, /* MOVE FROM dsa_datain+0x03f0, WHEN DATA_IN -at 0x00000138 : */ 0x19000000,0x00000418, +at 0x00000136 : */ 0x19000000,0x00000418, /* MOVE FROM dsa_datain+0x03f8, WHEN DATA_IN -at 0x0000013a : */ 0x19000000,0x00000420, +at 0x00000138 : */ 0x19000000,0x00000420, /* JUMP end_data_trans -at 0x0000013c : */ 0x80080000,0x00000908, +at 0x0000013a : */ 0x80080000,0x00000900, /* output_data: MOVE SCRATCH0 | had_dataout TO SCRATCH0 -at 0x0000013e : */ 0x7a341000,0x00000000, +at 0x0000013c : */ 0x7a341000,0x00000000, /* ENTRY patch_output_data patch_output_data: JUMP 0 -at 0x00000140 : */ 0x80080000,0x00000000, +at 0x0000013e : */ 0x80080000,0x00000000, /* MOVE FROM dsa_dataout+0x0000, WHEN DATA_OUT -at 0x00000142 : */ 0x18000000,0x00000428, +at 0x00000140 : */ 0x18000000,0x00000428, /* MOVE FROM dsa_dataout+0x0008, WHEN DATA_OUT -at 0x00000144 : */ 0x18000000,0x00000430, +at 0x00000142 : */ 0x18000000,0x00000430, /* MOVE FROM dsa_dataout+0x0010, WHEN DATA_OUT -at 0x00000146 : */ 0x18000000,0x00000438, +at 0x00000144 : */ 0x18000000,0x00000438, /* MOVE FROM dsa_dataout+0x0018, WHEN DATA_OUT -at 0x00000148 : */ 0x18000000,0x00000440, +at 0x00000146 : */ 0x18000000,0x00000440, /* MOVE FROM dsa_dataout+0x0020, WHEN DATA_OUT -at 0x0000014a : */ 0x18000000,0x00000448, +at 0x00000148 : */ 0x18000000,0x00000448, /* MOVE FROM dsa_dataout+0x0028, WHEN DATA_OUT -at 0x0000014c : */ 0x18000000,0x00000450, +at 0x0000014a : */ 0x18000000,0x00000450, /* MOVE FROM dsa_dataout+0x0030, WHEN DATA_OUT -at 0x0000014e : */ 0x18000000,0x00000458, +at 0x0000014c : */ 0x18000000,0x00000458, /* MOVE FROM dsa_dataout+0x0038, WHEN DATA_OUT -at 0x00000150 : */ 0x18000000,0x00000460, +at 0x0000014e : */ 0x18000000,0x00000460, /* MOVE FROM dsa_dataout+0x0040, WHEN DATA_OUT -at 0x00000152 : */ 0x18000000,0x00000468, +at 0x00000150 : */ 0x18000000,0x00000468, /* MOVE FROM dsa_dataout+0x0048, WHEN DATA_OUT -at 0x00000154 : */ 0x18000000,0x00000470, +at 0x00000152 : */ 0x18000000,0x00000470, /* MOVE FROM dsa_dataout+0x0050, WHEN DATA_OUT -at 0x00000156 : */ 0x18000000,0x00000478, +at 0x00000154 : */ 0x18000000,0x00000478, /* MOVE FROM dsa_dataout+0x0058, WHEN DATA_OUT -at 0x00000158 : */ 0x18000000,0x00000480, +at 0x00000156 : */ 0x18000000,0x00000480, /* MOVE FROM dsa_dataout+0x0060, WHEN DATA_OUT -at 0x0000015a : */ 0x18000000,0x00000488, +at 0x00000158 : */ 0x18000000,0x00000488, /* MOVE FROM dsa_dataout+0x0068, WHEN DATA_OUT -at 0x0000015c : */ 0x18000000,0x00000490, +at 0x0000015a : */ 0x18000000,0x00000490, /* MOVE FROM dsa_dataout+0x0070, WHEN DATA_OUT -at 0x0000015e : */ 0x18000000,0x00000498, +at 0x0000015c : */ 0x18000000,0x00000498, /* MOVE FROM dsa_dataout+0x0078, WHEN DATA_OUT -at 0x00000160 : */ 0x18000000,0x000004a0, +at 0x0000015e : */ 0x18000000,0x000004a0, /* MOVE FROM dsa_dataout+0x0080, WHEN DATA_OUT -at 0x00000162 : */ 0x18000000,0x000004a8, +at 0x00000160 : */ 0x18000000,0x000004a8, /* MOVE FROM dsa_dataout+0x0088, WHEN DATA_OUT -at 0x00000164 : */ 0x18000000,0x000004b0, +at 0x00000162 : */ 0x18000000,0x000004b0, /* MOVE FROM dsa_dataout+0x0090, WHEN DATA_OUT -at 0x00000166 : */ 0x18000000,0x000004b8, +at 0x00000164 : */ 0x18000000,0x000004b8, /* MOVE FROM dsa_dataout+0x0098, WHEN DATA_OUT -at 0x00000168 : */ 0x18000000,0x000004c0, +at 0x00000166 : */ 0x18000000,0x000004c0, /* MOVE FROM dsa_dataout+0x00a0, WHEN DATA_OUT -at 0x0000016a : */ 0x18000000,0x000004c8, +at 0x00000168 : */ 0x18000000,0x000004c8, /* MOVE FROM dsa_dataout+0x00a8, WHEN DATA_OUT -at 0x0000016c : */ 0x18000000,0x000004d0, +at 0x0000016a : */ 0x18000000,0x000004d0, /* MOVE FROM dsa_dataout+0x00b0, WHEN DATA_OUT -at 0x0000016e : */ 0x18000000,0x000004d8, +at 0x0000016c : */ 0x18000000,0x000004d8, /* MOVE FROM dsa_dataout+0x00b8, WHEN DATA_OUT -at 0x00000170 : */ 0x18000000,0x000004e0, +at 0x0000016e : */ 0x18000000,0x000004e0, /* MOVE FROM dsa_dataout+0x00c0, WHEN DATA_OUT -at 0x00000172 : */ 0x18000000,0x000004e8, +at 0x00000170 : */ 0x18000000,0x000004e8, /* MOVE FROM dsa_dataout+0x00c8, WHEN DATA_OUT -at 0x00000174 : */ 0x18000000,0x000004f0, +at 0x00000172 : */ 0x18000000,0x000004f0, /* MOVE FROM dsa_dataout+0x00d0, WHEN DATA_OUT -at 0x00000176 : */ 0x18000000,0x000004f8, +at 0x00000174 : */ 0x18000000,0x000004f8, /* MOVE FROM dsa_dataout+0x00d8, WHEN DATA_OUT -at 0x00000178 : */ 0x18000000,0x00000500, +at 0x00000176 : */ 0x18000000,0x00000500, /* MOVE FROM dsa_dataout+0x00e0, WHEN DATA_OUT -at 0x0000017a : */ 0x18000000,0x00000508, +at 0x00000178 : */ 0x18000000,0x00000508, /* MOVE FROM dsa_dataout+0x00e8, WHEN DATA_OUT -at 0x0000017c : */ 0x18000000,0x00000510, +at 0x0000017a : */ 0x18000000,0x00000510, /* MOVE FROM dsa_dataout+0x00f0, WHEN DATA_OUT -at 0x0000017e : */ 0x18000000,0x00000518, +at 0x0000017c : */ 0x18000000,0x00000518, /* MOVE FROM dsa_dataout+0x00f8, WHEN DATA_OUT -at 0x00000180 : */ 0x18000000,0x00000520, +at 0x0000017e : */ 0x18000000,0x00000520, /* MOVE FROM dsa_dataout+0x0100, WHEN DATA_OUT -at 0x00000182 : */ 0x18000000,0x00000528, +at 0x00000180 : */ 0x18000000,0x00000528, /* MOVE FROM dsa_dataout+0x0108, WHEN DATA_OUT -at 0x00000184 : */ 0x18000000,0x00000530, +at 0x00000182 : */ 0x18000000,0x00000530, /* MOVE FROM dsa_dataout+0x0110, WHEN DATA_OUT -at 0x00000186 : */ 0x18000000,0x00000538, +at 0x00000184 : */ 0x18000000,0x00000538, /* MOVE FROM dsa_dataout+0x0118, WHEN DATA_OUT -at 0x00000188 : */ 0x18000000,0x00000540, +at 0x00000186 : */ 0x18000000,0x00000540, /* MOVE FROM dsa_dataout+0x0120, WHEN DATA_OUT -at 0x0000018a : */ 0x18000000,0x00000548, +at 0x00000188 : */ 0x18000000,0x00000548, /* MOVE FROM dsa_dataout+0x0128, WHEN DATA_OUT -at 0x0000018c : */ 0x18000000,0x00000550, +at 0x0000018a : */ 0x18000000,0x00000550, /* MOVE FROM dsa_dataout+0x0130, WHEN DATA_OUT -at 0x0000018e : */ 0x18000000,0x00000558, +at 0x0000018c : */ 0x18000000,0x00000558, /* MOVE FROM dsa_dataout+0x0138, WHEN DATA_OUT -at 0x00000190 : */ 0x18000000,0x00000560, +at 0x0000018e : */ 0x18000000,0x00000560, /* MOVE FROM dsa_dataout+0x0140, WHEN DATA_OUT -at 0x00000192 : */ 0x18000000,0x00000568, +at 0x00000190 : */ 0x18000000,0x00000568, /* MOVE FROM dsa_dataout+0x0148, WHEN DATA_OUT -at 0x00000194 : */ 0x18000000,0x00000570, +at 0x00000192 : */ 0x18000000,0x00000570, /* MOVE FROM dsa_dataout+0x0150, WHEN DATA_OUT -at 0x00000196 : */ 0x18000000,0x00000578, +at 0x00000194 : */ 0x18000000,0x00000578, /* MOVE FROM dsa_dataout+0x0158, WHEN DATA_OUT -at 0x00000198 : */ 0x18000000,0x00000580, +at 0x00000196 : */ 0x18000000,0x00000580, /* MOVE FROM dsa_dataout+0x0160, WHEN DATA_OUT -at 0x0000019a : */ 0x18000000,0x00000588, +at 0x00000198 : */ 0x18000000,0x00000588, /* MOVE FROM dsa_dataout+0x0168, WHEN DATA_OUT -at 0x0000019c : */ 0x18000000,0x00000590, +at 0x0000019a : */ 0x18000000,0x00000590, /* MOVE FROM dsa_dataout+0x0170, WHEN DATA_OUT -at 0x0000019e : */ 0x18000000,0x00000598, +at 0x0000019c : */ 0x18000000,0x00000598, /* MOVE FROM dsa_dataout+0x0178, WHEN DATA_OUT -at 0x000001a0 : */ 0x18000000,0x000005a0, +at 0x0000019e : */ 0x18000000,0x000005a0, /* MOVE FROM dsa_dataout+0x0180, WHEN DATA_OUT -at 0x000001a2 : */ 0x18000000,0x000005a8, +at 0x000001a0 : */ 0x18000000,0x000005a8, /* MOVE FROM dsa_dataout+0x0188, WHEN DATA_OUT -at 0x000001a4 : */ 0x18000000,0x000005b0, +at 0x000001a2 : */ 0x18000000,0x000005b0, /* MOVE FROM dsa_dataout+0x0190, WHEN DATA_OUT -at 0x000001a6 : */ 0x18000000,0x000005b8, +at 0x000001a4 : */ 0x18000000,0x000005b8, /* MOVE FROM dsa_dataout+0x0198, WHEN DATA_OUT -at 0x000001a8 : */ 0x18000000,0x000005c0, +at 0x000001a6 : */ 0x18000000,0x000005c0, /* MOVE FROM dsa_dataout+0x01a0, WHEN DATA_OUT -at 0x000001aa : */ 0x18000000,0x000005c8, +at 0x000001a8 : */ 0x18000000,0x000005c8, /* MOVE FROM dsa_dataout+0x01a8, WHEN DATA_OUT -at 0x000001ac : */ 0x18000000,0x000005d0, +at 0x000001aa : */ 0x18000000,0x000005d0, /* MOVE FROM dsa_dataout+0x01b0, WHEN DATA_OUT -at 0x000001ae : */ 0x18000000,0x000005d8, +at 0x000001ac : */ 0x18000000,0x000005d8, /* MOVE FROM dsa_dataout+0x01b8, WHEN DATA_OUT -at 0x000001b0 : */ 0x18000000,0x000005e0, +at 0x000001ae : */ 0x18000000,0x000005e0, /* MOVE FROM dsa_dataout+0x01c0, WHEN DATA_OUT -at 0x000001b2 : */ 0x18000000,0x000005e8, +at 0x000001b0 : */ 0x18000000,0x000005e8, /* MOVE FROM dsa_dataout+0x01c8, WHEN DATA_OUT -at 0x000001b4 : */ 0x18000000,0x000005f0, +at 0x000001b2 : */ 0x18000000,0x000005f0, /* MOVE FROM dsa_dataout+0x01d0, WHEN DATA_OUT -at 0x000001b6 : */ 0x18000000,0x000005f8, +at 0x000001b4 : */ 0x18000000,0x000005f8, /* MOVE FROM dsa_dataout+0x01d8, WHEN DATA_OUT -at 0x000001b8 : */ 0x18000000,0x00000600, +at 0x000001b6 : */ 0x18000000,0x00000600, /* MOVE FROM dsa_dataout+0x01e0, WHEN DATA_OUT -at 0x000001ba : */ 0x18000000,0x00000608, +at 0x000001b8 : */ 0x18000000,0x00000608, /* MOVE FROM dsa_dataout+0x01e8, WHEN DATA_OUT -at 0x000001bc : */ 0x18000000,0x00000610, +at 0x000001ba : */ 0x18000000,0x00000610, /* MOVE FROM dsa_dataout+0x01f0, WHEN DATA_OUT -at 0x000001be : */ 0x18000000,0x00000618, +at 0x000001bc : */ 0x18000000,0x00000618, /* MOVE FROM dsa_dataout+0x01f8, WHEN DATA_OUT -at 0x000001c0 : */ 0x18000000,0x00000620, +at 0x000001be : */ 0x18000000,0x00000620, /* MOVE FROM dsa_dataout+0x0200, WHEN DATA_OUT -at 0x000001c2 : */ 0x18000000,0x00000628, +at 0x000001c0 : */ 0x18000000,0x00000628, /* MOVE FROM dsa_dataout+0x0208, WHEN DATA_OUT -at 0x000001c4 : */ 0x18000000,0x00000630, +at 0x000001c2 : */ 0x18000000,0x00000630, /* MOVE FROM dsa_dataout+0x0210, WHEN DATA_OUT -at 0x000001c6 : */ 0x18000000,0x00000638, +at 0x000001c4 : */ 0x18000000,0x00000638, /* MOVE FROM dsa_dataout+0x0218, WHEN DATA_OUT -at 0x000001c8 : */ 0x18000000,0x00000640, +at 0x000001c6 : */ 0x18000000,0x00000640, /* MOVE FROM dsa_dataout+0x0220, WHEN DATA_OUT -at 0x000001ca : */ 0x18000000,0x00000648, +at 0x000001c8 : */ 0x18000000,0x00000648, /* MOVE FROM dsa_dataout+0x0228, WHEN DATA_OUT -at 0x000001cc : */ 0x18000000,0x00000650, +at 0x000001ca : */ 0x18000000,0x00000650, /* MOVE FROM dsa_dataout+0x0230, WHEN DATA_OUT -at 0x000001ce : */ 0x18000000,0x00000658, +at 0x000001cc : */ 0x18000000,0x00000658, /* MOVE FROM dsa_dataout+0x0238, WHEN DATA_OUT -at 0x000001d0 : */ 0x18000000,0x00000660, +at 0x000001ce : */ 0x18000000,0x00000660, /* MOVE FROM dsa_dataout+0x0240, WHEN DATA_OUT -at 0x000001d2 : */ 0x18000000,0x00000668, +at 0x000001d0 : */ 0x18000000,0x00000668, /* MOVE FROM dsa_dataout+0x0248, WHEN DATA_OUT -at 0x000001d4 : */ 0x18000000,0x00000670, +at 0x000001d2 : */ 0x18000000,0x00000670, /* MOVE FROM dsa_dataout+0x0250, WHEN DATA_OUT -at 0x000001d6 : */ 0x18000000,0x00000678, +at 0x000001d4 : */ 0x18000000,0x00000678, /* MOVE FROM dsa_dataout+0x0258, WHEN DATA_OUT -at 0x000001d8 : */ 0x18000000,0x00000680, +at 0x000001d6 : */ 0x18000000,0x00000680, /* MOVE FROM dsa_dataout+0x0260, WHEN DATA_OUT -at 0x000001da : */ 0x18000000,0x00000688, +at 0x000001d8 : */ 0x18000000,0x00000688, /* MOVE FROM dsa_dataout+0x0268, WHEN DATA_OUT -at 0x000001dc : */ 0x18000000,0x00000690, +at 0x000001da : */ 0x18000000,0x00000690, /* MOVE FROM dsa_dataout+0x0270, WHEN DATA_OUT -at 0x000001de : */ 0x18000000,0x00000698, +at 0x000001dc : */ 0x18000000,0x00000698, /* MOVE FROM dsa_dataout+0x0278, WHEN DATA_OUT -at 0x000001e0 : */ 0x18000000,0x000006a0, +at 0x000001de : */ 0x18000000,0x000006a0, /* MOVE FROM dsa_dataout+0x0280, WHEN DATA_OUT -at 0x000001e2 : */ 0x18000000,0x000006a8, +at 0x000001e0 : */ 0x18000000,0x000006a8, /* MOVE FROM dsa_dataout+0x0288, WHEN DATA_OUT -at 0x000001e4 : */ 0x18000000,0x000006b0, +at 0x000001e2 : */ 0x18000000,0x000006b0, /* MOVE FROM dsa_dataout+0x0290, WHEN DATA_OUT -at 0x000001e6 : */ 0x18000000,0x000006b8, +at 0x000001e4 : */ 0x18000000,0x000006b8, /* MOVE FROM dsa_dataout+0x0298, WHEN DATA_OUT -at 0x000001e8 : */ 0x18000000,0x000006c0, +at 0x000001e6 : */ 0x18000000,0x000006c0, /* MOVE FROM dsa_dataout+0x02a0, WHEN DATA_OUT -at 0x000001ea : */ 0x18000000,0x000006c8, +at 0x000001e8 : */ 0x18000000,0x000006c8, /* MOVE FROM dsa_dataout+0x02a8, WHEN DATA_OUT -at 0x000001ec : */ 0x18000000,0x000006d0, +at 0x000001ea : */ 0x18000000,0x000006d0, /* MOVE FROM dsa_dataout+0x02b0, WHEN DATA_OUT -at 0x000001ee : */ 0x18000000,0x000006d8, +at 0x000001ec : */ 0x18000000,0x000006d8, /* MOVE FROM dsa_dataout+0x02b8, WHEN DATA_OUT -at 0x000001f0 : */ 0x18000000,0x000006e0, +at 0x000001ee : */ 0x18000000,0x000006e0, /* MOVE FROM dsa_dataout+0x02c0, WHEN DATA_OUT -at 0x000001f2 : */ 0x18000000,0x000006e8, +at 0x000001f0 : */ 0x18000000,0x000006e8, /* MOVE FROM dsa_dataout+0x02c8, WHEN DATA_OUT -at 0x000001f4 : */ 0x18000000,0x000006f0, +at 0x000001f2 : */ 0x18000000,0x000006f0, /* MOVE FROM dsa_dataout+0x02d0, WHEN DATA_OUT -at 0x000001f6 : */ 0x18000000,0x000006f8, +at 0x000001f4 : */ 0x18000000,0x000006f8, /* MOVE FROM dsa_dataout+0x02d8, WHEN DATA_OUT -at 0x000001f8 : */ 0x18000000,0x00000700, +at 0x000001f6 : */ 0x18000000,0x00000700, /* MOVE FROM dsa_dataout+0x02e0, WHEN DATA_OUT -at 0x000001fa : */ 0x18000000,0x00000708, +at 0x000001f8 : */ 0x18000000,0x00000708, /* MOVE FROM dsa_dataout+0x02e8, WHEN DATA_OUT -at 0x000001fc : */ 0x18000000,0x00000710, +at 0x000001fa : */ 0x18000000,0x00000710, /* MOVE FROM dsa_dataout+0x02f0, WHEN DATA_OUT -at 0x000001fe : */ 0x18000000,0x00000718, +at 0x000001fc : */ 0x18000000,0x00000718, /* MOVE FROM dsa_dataout+0x02f8, WHEN DATA_OUT -at 0x00000200 : */ 0x18000000,0x00000720, +at 0x000001fe : */ 0x18000000,0x00000720, /* MOVE FROM dsa_dataout+0x0300, WHEN DATA_OUT -at 0x00000202 : */ 0x18000000,0x00000728, +at 0x00000200 : */ 0x18000000,0x00000728, /* MOVE FROM dsa_dataout+0x0308, WHEN DATA_OUT -at 0x00000204 : */ 0x18000000,0x00000730, +at 0x00000202 : */ 0x18000000,0x00000730, /* MOVE FROM dsa_dataout+0x0310, WHEN DATA_OUT -at 0x00000206 : */ 0x18000000,0x00000738, +at 0x00000204 : */ 0x18000000,0x00000738, /* MOVE FROM dsa_dataout+0x0318, WHEN DATA_OUT -at 0x00000208 : */ 0x18000000,0x00000740, +at 0x00000206 : */ 0x18000000,0x00000740, /* MOVE FROM dsa_dataout+0x0320, WHEN DATA_OUT -at 0x0000020a : */ 0x18000000,0x00000748, +at 0x00000208 : */ 0x18000000,0x00000748, /* MOVE FROM dsa_dataout+0x0328, WHEN DATA_OUT -at 0x0000020c : */ 0x18000000,0x00000750, +at 0x0000020a : */ 0x18000000,0x00000750, /* MOVE FROM dsa_dataout+0x0330, WHEN DATA_OUT -at 0x0000020e : */ 0x18000000,0x00000758, +at 0x0000020c : */ 0x18000000,0x00000758, /* MOVE FROM dsa_dataout+0x0338, WHEN DATA_OUT -at 0x00000210 : */ 0x18000000,0x00000760, +at 0x0000020e : */ 0x18000000,0x00000760, /* MOVE FROM dsa_dataout+0x0340, WHEN DATA_OUT -at 0x00000212 : */ 0x18000000,0x00000768, +at 0x00000210 : */ 0x18000000,0x00000768, /* MOVE FROM dsa_dataout+0x0348, WHEN DATA_OUT -at 0x00000214 : */ 0x18000000,0x00000770, +at 0x00000212 : */ 0x18000000,0x00000770, /* MOVE FROM dsa_dataout+0x0350, WHEN DATA_OUT -at 0x00000216 : */ 0x18000000,0x00000778, +at 0x00000214 : */ 0x18000000,0x00000778, /* MOVE FROM dsa_dataout+0x0358, WHEN DATA_OUT -at 0x00000218 : */ 0x18000000,0x00000780, +at 0x00000216 : */ 0x18000000,0x00000780, /* MOVE FROM dsa_dataout+0x0360, WHEN DATA_OUT -at 0x0000021a : */ 0x18000000,0x00000788, +at 0x00000218 : */ 0x18000000,0x00000788, /* MOVE FROM dsa_dataout+0x0368, WHEN DATA_OUT -at 0x0000021c : */ 0x18000000,0x00000790, +at 0x0000021a : */ 0x18000000,0x00000790, /* MOVE FROM dsa_dataout+0x0370, WHEN DATA_OUT -at 0x0000021e : */ 0x18000000,0x00000798, +at 0x0000021c : */ 0x18000000,0x00000798, /* MOVE FROM dsa_dataout+0x0378, WHEN DATA_OUT -at 0x00000220 : */ 0x18000000,0x000007a0, +at 0x0000021e : */ 0x18000000,0x000007a0, /* MOVE FROM dsa_dataout+0x0380, WHEN DATA_OUT -at 0x00000222 : */ 0x18000000,0x000007a8, +at 0x00000220 : */ 0x18000000,0x000007a8, /* MOVE FROM dsa_dataout+0x0388, WHEN DATA_OUT -at 0x00000224 : */ 0x18000000,0x000007b0, +at 0x00000222 : */ 0x18000000,0x000007b0, /* MOVE FROM dsa_dataout+0x0390, WHEN DATA_OUT -at 0x00000226 : */ 0x18000000,0x000007b8, +at 0x00000224 : */ 0x18000000,0x000007b8, /* MOVE FROM dsa_dataout+0x0398, WHEN DATA_OUT -at 0x00000228 : */ 0x18000000,0x000007c0, +at 0x00000226 : */ 0x18000000,0x000007c0, /* MOVE FROM dsa_dataout+0x03a0, WHEN DATA_OUT -at 0x0000022a : */ 0x18000000,0x000007c8, +at 0x00000228 : */ 0x18000000,0x000007c8, /* MOVE FROM dsa_dataout+0x03a8, WHEN DATA_OUT -at 0x0000022c : */ 0x18000000,0x000007d0, +at 0x0000022a : */ 0x18000000,0x000007d0, /* MOVE FROM dsa_dataout+0x03b0, WHEN DATA_OUT -at 0x0000022e : */ 0x18000000,0x000007d8, +at 0x0000022c : */ 0x18000000,0x000007d8, /* MOVE FROM dsa_dataout+0x03b8, WHEN DATA_OUT -at 0x00000230 : */ 0x18000000,0x000007e0, +at 0x0000022e : */ 0x18000000,0x000007e0, /* MOVE FROM dsa_dataout+0x03c0, WHEN DATA_OUT -at 0x00000232 : */ 0x18000000,0x000007e8, +at 0x00000230 : */ 0x18000000,0x000007e8, /* MOVE FROM dsa_dataout+0x03c8, WHEN DATA_OUT -at 0x00000234 : */ 0x18000000,0x000007f0, +at 0x00000232 : */ 0x18000000,0x000007f0, /* MOVE FROM dsa_dataout+0x03d0, WHEN DATA_OUT -at 0x00000236 : */ 0x18000000,0x000007f8, +at 0x00000234 : */ 0x18000000,0x000007f8, /* MOVE FROM dsa_dataout+0x03d8, WHEN DATA_OUT -at 0x00000238 : */ 0x18000000,0x00000800, +at 0x00000236 : */ 0x18000000,0x00000800, /* MOVE FROM dsa_dataout+0x03e0, WHEN DATA_OUT -at 0x0000023a : */ 0x18000000,0x00000808, +at 0x00000238 : */ 0x18000000,0x00000808, /* MOVE FROM dsa_dataout+0x03e8, WHEN DATA_OUT -at 0x0000023c : */ 0x18000000,0x00000810, +at 0x0000023a : */ 0x18000000,0x00000810, /* MOVE FROM dsa_dataout+0x03f0, WHEN DATA_OUT -at 0x0000023e : */ 0x18000000,0x00000818, +at 0x0000023c : */ 0x18000000,0x00000818, /* MOVE FROM dsa_dataout+0x03f8, WHEN DATA_OUT -at 0x00000240 : */ 0x18000000,0x00000820, +at 0x0000023e : */ 0x18000000,0x00000820, /* ENTRY end_data_trans end_data_trans: redo_msgin3: JUMP get_status, WHEN STATUS -at 0x00000242 : */ 0x830b0000,0x000000a0, +at 0x00000240 : */ 0x830b0000,0x00000098, /* JUMP get_msgin3, WHEN MSG_IN -at 0x00000244 : */ 0x870b0000,0x00000b20, +at 0x00000242 : */ 0x870b0000,0x00000b78, /* INT int_data_bad_phase -at 0x00000246 : */ 0x98080000,0xab93000b, +at 0x00000244 : */ 0x98080000,0xab93000b, /* get_msgin1: MOVE SCRATCH0 | had_msgin TO SCRATCH0 -at 0x00000248 : */ 0x7a344000,0x00000000, +at 0x00000246 : */ 0x7a344000,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x0000024a : */ 0x0f000001,0x00000000, +at 0x00000248 : */ 0x0f000001,0x00000000, /* JUMP ext_msg1, IF 0x01 ; Extended Message -at 0x0000024c : */ 0x800c0001,0x00000968, +at 0x0000024a : */ 0x800c0001,0x00000960, /* JUMP ignore_msg1, IF 0x02 ; Save Data Pointers -at 0x0000024e : */ 0x800c0002,0x00000958, +at 0x0000024c : */ 0x800c0002,0x00000950, /* JUMP ignore_msg1, IF 0x03 ; Save Restore Pointers -at 0x00000250 : */ 0x800c0003,0x00000958, +at 0x0000024e : */ 0x800c0003,0x00000950, /* JUMP disc1, IF 0x04 ; Disconnect -at 0x00000252 : */ 0x800c0004,0x000009c8, +at 0x00000250 : */ 0x800c0004,0x000009f0, /* INT int_bad_msg1 -at 0x00000254 : */ 0x98080000,0xab930006, +at 0x00000252 : */ 0x98080000,0xab930006, /* ignore_msg1: CLEAR ACK -at 0x00000256 : */ 0x60000040,0x00000000, +at 0x00000254 : */ 0x60000040,0x00000000, /* JUMP redo_msgin1 -at 0x00000258 : */ 0x80080000,0x00000058, +at 0x00000256 : */ 0x80080000,0x00000050, /* ext_msg1: MOVE SCRATCH0 | had_extmsg TO SCRATCH0 -at 0x0000025a : */ 0x7a348000,0x00000000, +at 0x00000258 : */ 0x7a348000,0x00000000, /* CLEAR ACK -at 0x0000025c : */ 0x60000040,0x00000000, +at 0x0000025a : */ 0x60000040,0x00000000, /* MOVE 1, msgin_buf + 1, WHEN MSG_IN -at 0x0000025e : */ 0x0f000001,0x00000001, +at 0x0000025c : */ 0x0f000001,0x00000001, /* - JUMP ext_msg1a, IF 0x03 + JUMP reject_msg1, IF NOT 0x03 ; Only handle SDTR -at 0x00000260 : */ 0x800c0003,0x00000990, +at 0x0000025e : */ 0x80040003,0x000009b0, /* - INT int_bad_extmsg1a + CLEAR ACK -at 0x00000262 : */ 0x98080000,0xab930000, +at 0x00000260 : */ 0x60000040,0x00000000, +/* + MOVE 1, msgin_buf + 2, WHEN MSG_IN + +at 0x00000262 : */ 0x0f000001,0x00000002, +/* + JUMP reject_msg1, IF NOT 0x01 ; Only handle SDTR + +at 0x00000264 : */ 0x80040001,0x000009b0, /* -ext_msg1a: CLEAR ACK -at 0x00000264 : */ 0x60000040,0x00000000, +at 0x00000266 : */ 0x60000040,0x00000000, /* - MOVE 1, msgin_buf + 2, WHEN MSG_IN + MOVE 2, msgin_buf + 3, WHEN MSG_IN -at 0x00000266 : */ 0x0f000001,0x00000002, +at 0x00000268 : */ 0x0f000002,0x00000003, /* - JUMP ext_msg1b, IF 0x01 ; Must be SDTR + INT int_msg_sdtr1 + +at 0x0000026a : */ 0x98080000,0xab93000c, +/* +reject_msg1: + MOVE SCRATCH1 | did_reject TO SCRATCH1 -at 0x00000268 : */ 0x800c0001,0x000009b0, +at 0x0000026c : */ 0x7a350100,0x00000000, /* - INT int_bad_extmsg1b + SET ATN -at 0x0000026a : */ 0x98080000,0xab930001, +at 0x0000026e : */ 0x58000008,0x00000000, /* -ext_msg1b: CLEAR ACK -at 0x0000026c : */ 0x60000040,0x00000000, +at 0x00000270 : */ 0x60000040,0x00000000, /* - MOVE 2, msgin_buf + 3, WHEN MSG_IN + JUMP reject_msg1a, WHEN NOT MSG_IN -at 0x0000026e : */ 0x0f000002,0x00000003, +at 0x00000272 : */ 0x87030000,0x000009e0, /* - INT int_msg_sdtr1 + MOVE 1, msgin_buf + 7, WHEN MSG_IN -at 0x00000270 : */ 0x98080000,0xab93000c, +at 0x00000274 : */ 0x0f000001,0x00000007, +/* + JUMP reject_msg1 + +at 0x00000276 : */ 0x80080000,0x000009b0, +/* +reject_msg1a: + MOVE 1, msg_reject, WHEN MSG_OUT + +at 0x00000278 : */ 0x0e000001,0x00000000, +/* + JUMP redo_msgin1 + +at 0x0000027a : */ 0x80080000,0x00000050, /* disc1: CLEAR ACK -at 0x00000272 : */ 0x60000040,0x00000000, +at 0x0000027c : */ 0x60000040,0x00000000, /* ENTRY wait_disc1 wait_disc1: WAIT DISCONNECT -at 0x00000274 : */ 0x48000000,0x00000000, +at 0x0000027e : */ 0x48000000,0x00000000, /* INT int_disc1 -at 0x00000276 : */ 0x98080000,0xab930019, +at 0x00000280 : */ 0x98080000,0xab930019, /* ENTRY resume_msgin1a resume_msgin1a: CLEAR ACK -at 0x00000278 : */ 0x60000040,0x00000000, +at 0x00000282 : */ 0x60000040,0x00000000, /* JUMP redo_msgin1 -at 0x0000027a : */ 0x80080000,0x00000058, +at 0x00000284 : */ 0x80080000,0x00000050, /* ENTRY resume_msgin1b resume_msgin1b: SET ATN -at 0x0000027c : */ 0x58000008,0x00000000, +at 0x00000286 : */ 0x58000008,0x00000000, /* CLEAR ACK -at 0x0000027e : */ 0x60000040,0x00000000, +at 0x00000288 : */ 0x60000040,0x00000000, /* INT int_no_msgout1, WHEN NOT MSG_OUT -at 0x00000280 : */ 0x9e030000,0xab93000f, +at 0x0000028a : */ 0x9e030000,0xab93000f, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x00000282 : */ 0x7a340200,0x00000000, +at 0x0000028c : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x00000284 : */ 0x1e000000,0x00000008, +at 0x0000028e : */ 0x1e000000,0x00000008, /* JUMP redo_msgin1 -at 0x00000286 : */ 0x80080000,0x00000058, +at 0x00000290 : */ 0x80080000,0x00000050, /* get_msgin2: MOVE SCRATCH0 | had_msgin TO SCRATCH0 -at 0x00000288 : */ 0x7a344000,0x00000000, +at 0x00000292 : */ 0x7a344000,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x0000028a : */ 0x0f000001,0x00000000, +at 0x00000294 : */ 0x0f000001,0x00000000, /* JUMP ext_msg2, IF 0x01 ; Extended Message -at 0x0000028c : */ 0x800c0001,0x00000a68, +at 0x00000296 : */ 0x800c0001,0x00000a90, /* JUMP ignore_msg2, IF 0x02 ; Save Data Pointers -at 0x0000028e : */ 0x800c0002,0x00000a58, +at 0x00000298 : */ 0x800c0002,0x00000a80, /* JUMP ignore_msg2, IF 0x03 ; Save Restore Pointers -at 0x00000290 : */ 0x800c0003,0x00000a58, +at 0x0000029a : */ 0x800c0003,0x00000a80, /* JUMP disc2, IF 0x04 ; Disconnect -at 0x00000292 : */ 0x800c0004,0x00000ac8, +at 0x0000029c : */ 0x800c0004,0x00000b20, /* INT int_bad_msg2 -at 0x00000294 : */ 0x98080000,0xab930007, +at 0x0000029e : */ 0x98080000,0xab930007, /* ignore_msg2: CLEAR ACK -at 0x00000296 : */ 0x60000040,0x00000000, +at 0x000002a0 : */ 0x60000040,0x00000000, /* JUMP redo_msgin2 -at 0x00000298 : */ 0x80080000,0x00000078, +at 0x000002a2 : */ 0x80080000,0x00000070, /* ext_msg2: MOVE SCRATCH0 | had_extmsg TO SCRATCH0 -at 0x0000029a : */ 0x7a348000,0x00000000, +at 0x000002a4 : */ 0x7a348000,0x00000000, /* CLEAR ACK -at 0x0000029c : */ 0x60000040,0x00000000, +at 0x000002a6 : */ 0x60000040,0x00000000, /* MOVE 1, msgin_buf + 1, WHEN MSG_IN -at 0x0000029e : */ 0x0f000001,0x00000001, +at 0x000002a8 : */ 0x0f000001,0x00000001, +/* + JUMP reject_msg2, IF NOT 0x03 ; Only handle SDTR + +at 0x000002aa : */ 0x80040003,0x00000ae0, +/* + CLEAR ACK + +at 0x000002ac : */ 0x60000040,0x00000000, /* - JUMP ext_msg2a, IF 0x03 + MOVE 1, msgin_buf + 2, WHEN MSG_IN -at 0x000002a0 : */ 0x800c0003,0x00000a90, +at 0x000002ae : */ 0x0f000001,0x00000002, /* - INT int_bad_extmsg2a + JUMP reject_msg2, IF NOT 0x01 ; Only handle SDTR -at 0x000002a2 : */ 0x98080000,0xab930002, +at 0x000002b0 : */ 0x80040001,0x00000ae0, /* -ext_msg2a: CLEAR ACK -at 0x000002a4 : */ 0x60000040,0x00000000, +at 0x000002b2 : */ 0x60000040,0x00000000, /* - MOVE 1, msgin_buf + 2, WHEN MSG_IN + MOVE 2, msgin_buf + 3, WHEN MSG_IN + +at 0x000002b4 : */ 0x0f000002,0x00000003, +/* + INT int_msg_sdtr2 -at 0x000002a6 : */ 0x0f000001,0x00000002, +at 0x000002b6 : */ 0x98080000,0xab93000d, /* - JUMP ext_msg2b, IF 0x01 ; Must be SDTR +reject_msg2: + MOVE SCRATCH1 | did_reject TO SCRATCH1 -at 0x000002a8 : */ 0x800c0001,0x00000ab0, +at 0x000002b8 : */ 0x7a350100,0x00000000, /* - INT int_bad_extmsg2b + SET ATN -at 0x000002aa : */ 0x98080000,0xab930003, +at 0x000002ba : */ 0x58000008,0x00000000, /* -ext_msg2b: CLEAR ACK -at 0x000002ac : */ 0x60000040,0x00000000, +at 0x000002bc : */ 0x60000040,0x00000000, /* - MOVE 2, msgin_buf + 3, WHEN MSG_IN + JUMP reject_msg2a, WHEN NOT MSG_IN -at 0x000002ae : */ 0x0f000002,0x00000003, +at 0x000002be : */ 0x87030000,0x00000b10, /* - INT int_msg_sdtr2 + MOVE 1, msgin_buf + 7, WHEN MSG_IN + +at 0x000002c0 : */ 0x0f000001,0x00000007, +/* + JUMP reject_msg2 + +at 0x000002c2 : */ 0x80080000,0x00000ae0, +/* +reject_msg2a: + MOVE 1, msg_reject, WHEN MSG_OUT + +at 0x000002c4 : */ 0x0e000001,0x00000000, +/* + JUMP redo_msgin2 -at 0x000002b0 : */ 0x98080000,0xab93000d, +at 0x000002c6 : */ 0x80080000,0x00000070, /* disc2: CLEAR ACK -at 0x000002b2 : */ 0x60000040,0x00000000, +at 0x000002c8 : */ 0x60000040,0x00000000, /* ENTRY wait_disc2 wait_disc2: WAIT DISCONNECT -at 0x000002b4 : */ 0x48000000,0x00000000, +at 0x000002ca : */ 0x48000000,0x00000000, /* INT int_disc2 -at 0x000002b6 : */ 0x98080000,0xab93001a, +at 0x000002cc : */ 0x98080000,0xab93001a, /* ENTRY resume_msgin2a resume_msgin2a: CLEAR ACK -at 0x000002b8 : */ 0x60000040,0x00000000, +at 0x000002ce : */ 0x60000040,0x00000000, /* JUMP redo_msgin2 -at 0x000002ba : */ 0x80080000,0x00000078, +at 0x000002d0 : */ 0x80080000,0x00000070, /* ENTRY resume_msgin2b resume_msgin2b: SET ATN -at 0x000002bc : */ 0x58000008,0x00000000, +at 0x000002d2 : */ 0x58000008,0x00000000, /* CLEAR ACK -at 0x000002be : */ 0x60000040,0x00000000, +at 0x000002d4 : */ 0x60000040,0x00000000, /* INT int_no_msgout2, WHEN NOT MSG_OUT -at 0x000002c0 : */ 0x9e030000,0xab930010, +at 0x000002d6 : */ 0x9e030000,0xab930010, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x000002c2 : */ 0x7a340200,0x00000000, +at 0x000002d8 : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x000002c4 : */ 0x1e000000,0x00000008, +at 0x000002da : */ 0x1e000000,0x00000008, /* JUMP redo_msgin2 -at 0x000002c6 : */ 0x80080000,0x00000078, +at 0x000002dc : */ 0x80080000,0x00000070, /* get_msgin3: MOVE SCRATCH0 | had_msgin TO SCRATCH0 -at 0x000002c8 : */ 0x7a344000,0x00000000, +at 0x000002de : */ 0x7a344000,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x000002ca : */ 0x0f000001,0x00000000, +at 0x000002e0 : */ 0x0f000001,0x00000000, /* JUMP ext_msg3, IF 0x01 ; Extended Message -at 0x000002cc : */ 0x800c0001,0x00000b68, +at 0x000002e2 : */ 0x800c0001,0x00000bc0, /* JUMP ignore_msg3, IF 0x02 ; Save Data Pointers -at 0x000002ce : */ 0x800c0002,0x00000b58, +at 0x000002e4 : */ 0x800c0002,0x00000bb0, /* JUMP ignore_msg3, IF 0x03 ; Save Restore Pointers -at 0x000002d0 : */ 0x800c0003,0x00000b58, +at 0x000002e6 : */ 0x800c0003,0x00000bb0, /* JUMP disc3, IF 0x04 ; Disconnect -at 0x000002d2 : */ 0x800c0004,0x00000bc8, +at 0x000002e8 : */ 0x800c0004,0x00000c50, /* INT int_bad_msg3 -at 0x000002d4 : */ 0x98080000,0xab930008, +at 0x000002ea : */ 0x98080000,0xab930008, /* ignore_msg3: CLEAR ACK -at 0x000002d6 : */ 0x60000040,0x00000000, +at 0x000002ec : */ 0x60000040,0x00000000, /* JUMP redo_msgin3 -at 0x000002d8 : */ 0x80080000,0x00000908, +at 0x000002ee : */ 0x80080000,0x00000900, /* ext_msg3: MOVE SCRATCH0 | had_extmsg TO SCRATCH0 -at 0x000002da : */ 0x7a348000,0x00000000, +at 0x000002f0 : */ 0x7a348000,0x00000000, /* CLEAR ACK -at 0x000002dc : */ 0x60000040,0x00000000, +at 0x000002f2 : */ 0x60000040,0x00000000, /* MOVE 1, msgin_buf + 1, WHEN MSG_IN -at 0x000002de : */ 0x0f000001,0x00000001, +at 0x000002f4 : */ 0x0f000001,0x00000001, /* - JUMP ext_msg3a, IF 0x03 + JUMP reject_msg3, IF NOT 0x03 ; Only handle SDTR -at 0x000002e0 : */ 0x800c0003,0x00000b90, +at 0x000002f6 : */ 0x80040003,0x00000c10, /* - INT int_bad_extmsg3a + CLEAR ACK -at 0x000002e2 : */ 0x98080000,0xab930004, +at 0x000002f8 : */ 0x60000040,0x00000000, +/* + MOVE 1, msgin_buf + 2, WHEN MSG_IN + +at 0x000002fa : */ 0x0f000001,0x00000002, +/* + JUMP reject_msg3, IF NOT 0x01 ; Only handle SDTR + +at 0x000002fc : */ 0x80040001,0x00000c10, /* -ext_msg3a: CLEAR ACK -at 0x000002e4 : */ 0x60000040,0x00000000, +at 0x000002fe : */ 0x60000040,0x00000000, /* - MOVE 1, msgin_buf + 2, WHEN MSG_IN + MOVE 2, msgin_buf + 3, WHEN MSG_IN + +at 0x00000300 : */ 0x0f000002,0x00000003, +/* + INT int_msg_sdtr3 -at 0x000002e6 : */ 0x0f000001,0x00000002, +at 0x00000302 : */ 0x98080000,0xab93000e, /* - JUMP ext_msg3b, IF 0x01 ; Must be SDTR +reject_msg3: + MOVE SCRATCH1 | did_reject TO SCRATCH1 -at 0x000002e8 : */ 0x800c0001,0x00000bb0, +at 0x00000304 : */ 0x7a350100,0x00000000, /* - INT int_bad_extmsg3b + SET ATN -at 0x000002ea : */ 0x98080000,0xab930005, +at 0x00000306 : */ 0x58000008,0x00000000, /* -ext_msg3b: CLEAR ACK -at 0x000002ec : */ 0x60000040,0x00000000, +at 0x00000308 : */ 0x60000040,0x00000000, /* - MOVE 2, msgin_buf + 3, WHEN MSG_IN + JUMP reject_msg3a, WHEN NOT MSG_IN -at 0x000002ee : */ 0x0f000002,0x00000003, +at 0x0000030a : */ 0x87030000,0x00000c40, /* - INT int_msg_sdtr3 + MOVE 1, msgin_buf + 7, WHEN MSG_IN + +at 0x0000030c : */ 0x0f000001,0x00000007, +/* + JUMP reject_msg3 + +at 0x0000030e : */ 0x80080000,0x00000c10, +/* +reject_msg3a: + MOVE 1, msg_reject, WHEN MSG_OUT -at 0x000002f0 : */ 0x98080000,0xab93000e, +at 0x00000310 : */ 0x0e000001,0x00000000, +/* + JUMP redo_msgin3 + +at 0x00000312 : */ 0x80080000,0x00000900, /* disc3: CLEAR ACK -at 0x000002f2 : */ 0x60000040,0x00000000, +at 0x00000314 : */ 0x60000040,0x00000000, /* ENTRY wait_disc3 wait_disc3: WAIT DISCONNECT -at 0x000002f4 : */ 0x48000000,0x00000000, +at 0x00000316 : */ 0x48000000,0x00000000, /* INT int_disc3 -at 0x000002f6 : */ 0x98080000,0xab93001b, +at 0x00000318 : */ 0x98080000,0xab93001b, /* ENTRY resume_msgin3a resume_msgin3a: CLEAR ACK -at 0x000002f8 : */ 0x60000040,0x00000000, +at 0x0000031a : */ 0x60000040,0x00000000, /* JUMP redo_msgin3 -at 0x000002fa : */ 0x80080000,0x00000908, +at 0x0000031c : */ 0x80080000,0x00000900, /* ENTRY resume_msgin3b resume_msgin3b: SET ATN -at 0x000002fc : */ 0x58000008,0x00000000, +at 0x0000031e : */ 0x58000008,0x00000000, /* CLEAR ACK -at 0x000002fe : */ 0x60000040,0x00000000, +at 0x00000320 : */ 0x60000040,0x00000000, /* INT int_no_msgout3, WHEN NOT MSG_OUT -at 0x00000300 : */ 0x9e030000,0xab930011, +at 0x00000322 : */ 0x9e030000,0xab930011, /* MOVE SCRATCH0 | had_msgout TO SCRATCH0 -at 0x00000302 : */ 0x7a340200,0x00000000, +at 0x00000324 : */ 0x7a340200,0x00000000, /* MOVE FROM dsa_msgout, when MSG_OUT -at 0x00000304 : */ 0x1e000000,0x00000008, +at 0x00000326 : */ 0x1e000000,0x00000008, /* JUMP redo_msgin3 -at 0x00000306 : */ 0x80080000,0x00000908, +at 0x00000328 : */ 0x80080000,0x00000900, /* ENTRY resume_rej_ident resume_rej_ident: CLEAR ATN -at 0x00000308 : */ 0x60000008,0x00000000, +at 0x0000032a : */ 0x60000008,0x00000000, /* MOVE 1, msgin_buf, WHEN MSG_IN -at 0x0000030a : */ 0x0f000001,0x00000000, +at 0x0000032c : */ 0x0f000001,0x00000000, /* INT int_not_rej, IF NOT 0x07 ; Reject -at 0x0000030c : */ 0x98040007,0xab93001c, +at 0x0000032e : */ 0x98040007,0xab93001c, /* CLEAR ACK -at 0x0000030e : */ 0x60000040,0x00000000, +at 0x00000330 : */ 0x60000040,0x00000000, /* JUMP done_ident -at 0x00000310 : */ 0x80080000,0x00000050, +at 0x00000332 : */ 0x80080000,0x00000048, /* ENTRY reselect @@ -1716,73 +1784,92 @@ ; Disable selection timer MOVE CTEST7 | 0x10 TO CTEST7 -at 0x00000312 : */ 0x7a1b1000,0x00000000, +at 0x00000334 : */ 0x7a1b1000,0x00000000, /* WAIT RESELECT resel_err -at 0x00000314 : */ 0x50000000,0x00000c70, +at 0x00000336 : */ 0x50000000,0x00000cf8, /* INT int_resel_not_msgin, WHEN NOT MSG_IN -at 0x00000316 : */ 0x9f030000,0xab930016, +at 0x00000338 : */ 0x9f030000,0xab930016, /* MOVE 1, reselected_identify, WHEN MSG_IN -at 0x00000318 : */ 0x0f000001,0x00000000, +at 0x0000033a : */ 0x0f000001,0x00000000, /* INT int_reselected -at 0x0000031a : */ 0x98080000,0xab930017, +at 0x0000033c : */ 0x98080000,0xab930017, /* resel_err: MOVE CTEST2 & 0x40 TO SFBR -at 0x0000031c : */ 0x74164000,0x00000000, +at 0x0000033e : */ 0x74164000,0x00000000, /* JUMP selected, IF 0x00 -at 0x0000031e : */ 0x800c0000,0x00000cb0, +at 0x00000340 : */ 0x800c0000,0x00000d38, /* MOVE SFBR & 0 TO SFBR -at 0x00000320 : */ 0x7c080000,0x00000000, +at 0x00000342 : */ 0x7c080000,0x00000000, /* ENTRY patch_new_dsa patch_new_dsa: MOVE SFBR | 0x11 TO DSA0 -at 0x00000322 : */ 0x6a101100,0x00000000, +at 0x00000344 : */ 0x6a101100,0x00000000, /* MOVE SFBR | 0x22 TO DSA1 -at 0x00000324 : */ 0x6a112200,0x00000000, +at 0x00000346 : */ 0x6a112200,0x00000000, /* MOVE SFBR | 0x33 TO DSA2 -at 0x00000326 : */ 0x6a123300,0x00000000, +at 0x00000348 : */ 0x6a123300,0x00000000, /* MOVE SFBR | 0x44 TO DSA3 -at 0x00000328 : */ 0x6a134400,0x00000000, +at 0x0000034a : */ 0x6a134400,0x00000000, /* JUMP do_select -at 0x0000032a : */ 0x80080000,0x00000000, +at 0x0000034c : */ 0x80080000,0x00000000, /* selected: INT int_selected -at 0x0000032c : */ 0x98080000,0xab930018, +at 0x0000034e : */ 0x98080000,0xab930018, +/* + +ENTRY test1 +test1: + MOVE MEMORY 4, test1_src, test1_dst + +at 0x00000350 : */ 0xc0000004,0x00000000,0x00000000, +/* + INT int_test1 + +at 0x00000353 : */ 0x98080000,0xab93001d, +}; + +#define A_did_reject 0x00000001 +static u32 A_did_reject_used[] __attribute((unused)) = { + 0x0000026c, + 0x000002b8, + 0x00000304, }; #define A_dsa_cmnd 0x00000010 static u32 A_dsa_cmnd_used[] __attribute((unused)) = { - 0x0000001d, + 0x0000001b, }; #define A_dsa_datain 0x00000028 static u32 A_dsa_datain_used[] __attribute((unused)) = { + 0x0000003b, 0x0000003d, 0x0000003f, 0x00000041, @@ -1910,11 +1997,11 @@ 0x00000135, 0x00000137, 0x00000139, - 0x0000013b, }; #define A_dsa_dataout 0x00000428 static u32 A_dsa_dataout_used[] __attribute((unused)) = { + 0x00000141, 0x00000143, 0x00000145, 0x00000147, @@ -2042,25 +2129,24 @@ 0x0000023b, 0x0000023d, 0x0000023f, - 0x00000241, }; #define A_dsa_msgin 0x00000020 static u32 A_dsa_msgin_used[] __attribute((unused)) = { - 0x0000002f, + 0x0000002d, }; #define A_dsa_msgout 0x00000008 static u32 A_dsa_msgout_used[] __attribute((unused)) = { - 0x00000013, - 0x00000285, - 0x000002c5, - 0x00000305, + 0x00000011, + 0x0000028f, + 0x000002db, + 0x00000327, }; #define A_dsa_select 0x00000000 static u32 A_dsa_select_used[] __attribute((unused)) = { - 0x00000006, + 0x00000004, }; #define A_dsa_size 0x00000828 @@ -2069,285 +2155,290 @@ #define A_dsa_status 0x00000018 static u32 A_dsa_status_used[] __attribute((unused)) = { - 0x0000002b, + 0x00000029, }; #define A_had_cmdout 0x00000004 static u32 A_had_cmdout_used[] __attribute((unused)) = { - 0x0000001a, + 0x00000018, }; #define A_had_datain 0x00000008 static u32 A_had_datain_used[] __attribute((unused)) = { - 0x00000038, + 0x00000036, }; #define A_had_dataout 0x00000010 static u32 A_had_dataout_used[] __attribute((unused)) = { - 0x0000013e, + 0x0000013c, }; #define A_had_extmsg 0x00000080 static u32 A_had_extmsg_used[] __attribute((unused)) = { - 0x0000025a, - 0x0000029a, - 0x000002da, + 0x00000258, + 0x000002a4, + 0x000002f0, }; #define A_had_msgin 0x00000040 static u32 A_had_msgin_used[] __attribute((unused)) = { - 0x00000248, - 0x00000288, - 0x000002c8, + 0x00000246, + 0x00000292, + 0x000002de, }; #define A_had_msgout 0x00000002 static u32 A_had_msgout_used[] __attribute((unused)) = { - 0x00000010, - 0x00000282, - 0x000002c2, - 0x00000302, + 0x0000000e, + 0x0000028c, + 0x000002d8, + 0x00000324, }; #define A_had_select 0x00000001 static u32 A_had_select_used[] __attribute((unused)) = { - 0x0000000c, + 0x0000000a, }; #define A_had_status 0x00000020 static u32 A_had_status_used[] __attribute((unused)) = { }; -#define A_int_bad_extmsg1a 0xab930000 -static u32 A_int_bad_extmsg1a_used[] __attribute((unused)) = { - 0x00000263, -}; - -#define A_int_bad_extmsg1b 0xab930001 -static u32 A_int_bad_extmsg1b_used[] __attribute((unused)) = { - 0x0000026b, -}; - -#define A_int_bad_extmsg2a 0xab930002 -static u32 A_int_bad_extmsg2a_used[] __attribute((unused)) = { - 0x000002a3, -}; - -#define A_int_bad_extmsg2b 0xab930003 -static u32 A_int_bad_extmsg2b_used[] __attribute((unused)) = { - 0x000002ab, -}; - -#define A_int_bad_extmsg3a 0xab930004 -static u32 A_int_bad_extmsg3a_used[] __attribute((unused)) = { - 0x000002e3, -}; - -#define A_int_bad_extmsg3b 0xab930005 -static u32 A_int_bad_extmsg3b_used[] __attribute((unused)) = { - 0x000002eb, -}; - #define A_int_bad_msg1 0xab930006 static u32 A_int_bad_msg1_used[] __attribute((unused)) = { - 0x00000255, + 0x00000253, }; #define A_int_bad_msg2 0xab930007 static u32 A_int_bad_msg2_used[] __attribute((unused)) = { - 0x00000295, + 0x0000029f, }; #define A_int_bad_msg3 0xab930008 static u32 A_int_bad_msg3_used[] __attribute((unused)) = { - 0x000002d5, + 0x000002eb, }; #define A_int_cmd_bad_phase 0xab930009 static u32 A_int_cmd_bad_phase_used[] __attribute((unused)) = { - 0x00000027, + 0x00000025, }; #define A_int_cmd_complete 0xab93000a static u32 A_int_cmd_complete_used[] __attribute((unused)) = { - 0x00000037, + 0x00000035, }; #define A_int_data_bad_phase 0xab93000b static u32 A_int_data_bad_phase_used[] __attribute((unused)) = { - 0x00000247, + 0x00000245, }; #define A_int_disc1 0xab930019 static u32 A_int_disc1_used[] __attribute((unused)) = { - 0x00000277, + 0x00000281, }; #define A_int_disc2 0xab93001a static u32 A_int_disc2_used[] __attribute((unused)) = { - 0x000002b7, + 0x000002cd, }; #define A_int_disc3 0xab93001b static u32 A_int_disc3_used[] __attribute((unused)) = { - 0x000002f7, + 0x00000319, }; #define A_int_msg_sdtr1 0xab93000c static u32 A_int_msg_sdtr1_used[] __attribute((unused)) = { - 0x00000271, + 0x0000026b, }; #define A_int_msg_sdtr2 0xab93000d static u32 A_int_msg_sdtr2_used[] __attribute((unused)) = { - 0x000002b1, + 0x000002b7, }; #define A_int_msg_sdtr3 0xab93000e static u32 A_int_msg_sdtr3_used[] __attribute((unused)) = { - 0x000002f1, + 0x00000303, }; #define A_int_no_msgout1 0xab93000f static u32 A_int_no_msgout1_used[] __attribute((unused)) = { - 0x00000281, + 0x0000028b, }; #define A_int_no_msgout2 0xab930010 static u32 A_int_no_msgout2_used[] __attribute((unused)) = { - 0x000002c1, + 0x000002d7, }; #define A_int_no_msgout3 0xab930011 static u32 A_int_no_msgout3_used[] __attribute((unused)) = { - 0x00000301, + 0x00000323, }; #define A_int_not_cmd_complete 0xab930012 static u32 A_int_not_cmd_complete_used[] __attribute((unused)) = { - 0x00000031, + 0x0000002f, }; #define A_int_not_rej 0xab93001c static u32 A_int_not_rej_used[] __attribute((unused)) = { - 0x0000030d, + 0x0000032f, }; #define A_int_resel_not_msgin 0xab930016 static u32 A_int_resel_not_msgin_used[] __attribute((unused)) = { - 0x00000317, + 0x00000339, }; #define A_int_reselected 0xab930017 static u32 A_int_reselected_used[] __attribute((unused)) = { - 0x0000031b, + 0x0000033d, }; #define A_int_sel_no_ident 0xab930013 static u32 A_int_sel_no_ident_used[] __attribute((unused)) = { - 0x0000000f, + 0x0000000d, }; #define A_int_sel_not_cmd 0xab930014 static u32 A_int_sel_not_cmd_used[] __attribute((unused)) = { - 0x00000019, + 0x00000017, }; #define A_int_selected 0xab930018 static u32 A_int_selected_used[] __attribute((unused)) = { - 0x0000032d, + 0x0000034f, }; #define A_int_status_not_msgin 0xab930015 static u32 A_int_status_not_msgin_used[] __attribute((unused)) = { - 0x0000002d, + 0x0000002b, +}; + +#define A_int_test1 0xab93001d +static u32 A_int_test1_used[] __attribute((unused)) = { + 0x00000354, +}; + +#define A_msg_reject 0x00000000 +static u32 A_msg_reject_used[] __attribute((unused)) = { + 0x00000279, + 0x000002c5, + 0x00000311, }; #define A_msgin_buf 0x00000000 static u32 A_msgin_buf_used[] __attribute((unused)) = { - 0x0000024b, - 0x0000025f, - 0x00000267, - 0x0000026f, - 0x0000028b, - 0x0000029f, - 0x000002a7, + 0x00000249, + 0x0000025d, + 0x00000263, + 0x00000269, + 0x00000275, + 0x00000295, + 0x000002a9, 0x000002af, - 0x000002cb, - 0x000002df, - 0x000002e7, - 0x000002ef, - 0x0000030b, + 0x000002b5, + 0x000002c1, + 0x000002e1, + 0x000002f5, + 0x000002fb, + 0x00000301, + 0x0000030d, + 0x0000032d, }; #define A_reselected_identify 0x00000000 static u32 A_reselected_identify_used[] __attribute((unused)) = { - 0x00000319, + 0x0000033b, +}; + +#define A_test1_dst 0x00000000 +static u32 A_test1_dst_used[] __attribute((unused)) = { + 0x00000352, +}; + +#define A_test1_src 0x00000000 +static u32 A_test1_src_used[] __attribute((unused)) = { + 0x00000351, }; #define Ent_do_select 0x00000000 -#define Ent_done_ident 0x00000050 -#define Ent_end_data_trans 0x00000908 -#define Ent_patch_input_data 0x000000e8 -#define Ent_patch_new_dsa 0x00000c88 -#define Ent_patch_output_data 0x00000500 -#define Ent_reselect 0x00000c48 -#define Ent_resume_cmd 0x00000068 -#define Ent_resume_msgin1a 0x000009e0 -#define Ent_resume_msgin1b 0x000009f0 -#define Ent_resume_msgin2a 0x00000ae0 -#define Ent_resume_msgin2b 0x00000af0 -#define Ent_resume_msgin3a 0x00000be0 -#define Ent_resume_msgin3b 0x00000bf0 -#define Ent_resume_pmm 0x00000078 -#define Ent_resume_rej_ident 0x00000c20 -#define Ent_wait_disc1 0x000009d0 -#define Ent_wait_disc2 0x00000ad0 -#define Ent_wait_disc3 0x00000bd0 -#define Ent_wait_disc_complete 0x000000d0 +#define Ent_done_ident 0x00000048 +#define Ent_end_data_trans 0x00000900 +#define Ent_patch_input_data 0x000000e0 +#define Ent_patch_new_dsa 0x00000d10 +#define Ent_patch_output_data 0x000004f8 +#define Ent_reselect 0x00000cd0 +#define Ent_resume_cmd 0x00000060 +#define Ent_resume_msgin1a 0x00000a08 +#define Ent_resume_msgin1b 0x00000a18 +#define Ent_resume_msgin2a 0x00000b38 +#define Ent_resume_msgin2b 0x00000b48 +#define Ent_resume_msgin3a 0x00000c68 +#define Ent_resume_msgin3b 0x00000c78 +#define Ent_resume_pmm 0x00000070 +#define Ent_resume_rej_ident 0x00000ca8 +#define Ent_test1 0x00000d40 +#define Ent_wait_disc1 0x000009f8 +#define Ent_wait_disc2 0x00000b28 +#define Ent_wait_disc3 0x00000c58 +#define Ent_wait_disc_complete 0x000000c8 static u32 LABELPATCHES[] __attribute((unused)) = { + 0x00000005, 0x00000007, - 0x00000009, + 0x00000013, 0x00000015, - 0x00000017, + 0x0000001d, 0x0000001f, 0x00000021, 0x00000023, - 0x00000025, - 0x0000013d, + 0x0000013b, + 0x00000241, 0x00000243, - 0x00000245, + 0x0000024b, 0x0000024d, 0x0000024f, 0x00000251, - 0x00000253, - 0x00000259, - 0x00000261, - 0x00000269, + 0x00000257, + 0x0000025f, + 0x00000265, + 0x00000273, + 0x00000277, 0x0000027b, - 0x00000287, - 0x0000028d, - 0x0000028f, + 0x00000285, 0x00000291, - 0x00000293, + 0x00000297, 0x00000299, - 0x000002a1, - 0x000002a9, - 0x000002bb, + 0x0000029b, + 0x0000029d, + 0x000002a3, + 0x000002ab, + 0x000002b1, + 0x000002bf, + 0x000002c3, 0x000002c7, - 0x000002cd, - 0x000002cf, 0x000002d1, - 0x000002d3, - 0x000002d9, - 0x000002e1, + 0x000002dd, + 0x000002e3, + 0x000002e5, + 0x000002e7, 0x000002e9, - 0x000002fb, - 0x00000307, - 0x00000311, - 0x00000315, - 0x0000031f, - 0x0000032b, + 0x000002ef, + 0x000002f7, + 0x000002fd, + 0x0000030b, + 0x0000030f, + 0x00000313, + 0x0000031d, + 0x00000329, + 0x00000333, + 0x00000337, + 0x00000341, + 0x0000034d, }; static struct { @@ -2356,6 +2447,6 @@ } EXTERNAL_PATCHES[] __attribute((unused)) = { }; -static u32 INSTRUCTIONS __attribute((unused)) = 407; -static u32 PATCHES __attribute((unused)) = 42; +static u32 INSTRUCTIONS __attribute((unused)) = 426; +static u32 PATCHES __attribute((unused)) = 51; static u32 EXTERNAL_PATCHES_LEN __attribute((unused)) = 0; diff -urN linux-2.4.21/drivers/scsi/st.c linux-2.4.22/drivers/scsi/st.c --- linux-2.4.21/drivers/scsi/st.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/st.c 2003-08-25 04:44:42.000000000 -0700 @@ -9,10 +9,10 @@ Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, Michael Schaefer, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2002 Kai Makisara - email Kai.Makisara@metla.fi + Copyright 1992 - 2003 Kai Makisara + email Kai.Makisara@kolumbus.fi - Last modified: Mon Aug 5 22:54:13 2002 by makisara + Last modified: Sun Apr 6 22:44:42 2003 by makisara Some small formal changes - aeb, 950809 Last modified: 18-JAN-1998 Richard Gooch Devfs support @@ -21,7 +21,7 @@ error handling will be discarded. */ -static char *verstr = "20020805"; +static char *verstr = "20030406"; #include @@ -72,7 +72,6 @@ #include "constants.h" static int buffer_kbs; -static int write_threshold_kbs; static int max_buffers = (-1); static int max_sg_segs; static int blocking_open = ST_BLOCKING_OPEN; @@ -84,8 +83,6 @@ MODULE_PARM(buffer_kbs, "i"); MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size (KB; 32)"); -MODULE_PARM(write_threshold_kbs, "i"); -MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 30)"); MODULE_PARM(max_buffers, "i"); MODULE_PARM_DESC(max_buffers, "Maximum number of buffer allocated at initialisation (4)"); MODULE_PARM(max_sg_segs, "i"); @@ -103,8 +100,8 @@ { "buffer_kbs", &buffer_kbs }, - { - "write_threshold_kbs", &write_threshold_kbs + { /* Retained for compatibility */ + "write_threshold_kbs", NULL }, { "max_buffers", &max_buffers @@ -122,7 +119,6 @@ /* The default definitions have been moved to st_options.h */ #define ST_BUFFER_SIZE (ST_BUFFER_BLOCKS * ST_KILOBYTE) -#define ST_WRITE_THRESHOLD (ST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE) /* The buffer size should fit into the 24 bits for length in the 6-byte SCSI read and write commands. */ @@ -153,7 +149,6 @@ static int st_nbr_buffers; static ST_buffer **st_buffers = NULL; static int st_buffer_size = ST_BUFFER_SIZE; -static int st_write_threshold = ST_WRITE_THRESHOLD; static int st_max_buffers = ST_MAX_BUFFERS; static int st_max_sg_segs = ST_MAX_SG; @@ -167,6 +162,7 @@ static int set_sg_lengths(ST_buffer *, unsigned int); static int append_to_buffer(const char *, ST_buffer *, int); static int from_buffer(ST_buffer *, char *, int); +static void move_buffer_data(ST_buffer *, int); static int st_init(void); static int st_attach(Scsi_Device *); @@ -1196,6 +1192,7 @@ ssize_t total; ssize_t i, do_count, blks, transfer; ssize_t retval = 0; + int residual, retry_eot = 0, scode; int write_threshold; int doing_write = 0; unsigned char cmd[MAX_COMMAND_SIZE]; @@ -1367,7 +1364,7 @@ write_threshold = 1; } else write_threshold = (STp->buffer)->buffer_blocks * STp->block_size; - if (!STm->do_async_writes) + if (!STm->do_async_writes || STp->block_size > 0) write_threshold--; total = count; @@ -1381,7 +1378,7 @@ b_point = buf; while ((STp->block_size == 0 && !STm->do_async_writes && count > 0) || (STp->block_size != 0 && - (STp->buffer)->buffer_bytes + count > write_threshold)) { + (STp->buffer)->buffer_bytes + count > write_threshold && !retry_eot)) { doing_write = 1; if (STp->block_size == 0) do_count = count; @@ -1398,6 +1395,7 @@ goto out; } + retry_write: if (STp->block_size == 0) blks = transfer = do_count; else { @@ -1420,46 +1418,66 @@ DEBC(printk(ST_DEB_MSG "st%d: Error on write:\n", dev)); if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && (SRpnt->sr_sense_buffer[2] & 0x40)) { + scode = SRpnt->sr_sense_buffer[2] & 0x0f; if ((SRpnt->sr_sense_buffer[0] & 0x80) != 0) - transfer = (SRpnt->sr_sense_buffer[3] << 24) | + residual = (SRpnt->sr_sense_buffer[3] << 24) | (SRpnt->sr_sense_buffer[4] << 16) | (SRpnt->sr_sense_buffer[5] << 8) | SRpnt->sr_sense_buffer[6]; else if (STp->block_size == 0 && - (SRpnt->sr_sense_buffer[2] & 0x0f) == - VOLUME_OVERFLOW) - transfer = do_count; + scode == VOLUME_OVERFLOW) + residual = do_count; else - transfer = 0; + residual = 0; if (STp->block_size != 0) - transfer *= STp->block_size; - if (transfer <= do_count) { - filp->f_pos += do_count - transfer; - count -= do_count - transfer; + residual *= STp->block_size; + if (residual <= do_count) { + /* Within the data in this write() */ + filp->f_pos += do_count - residual; + count -= do_count - residual; if (STps->drv_block >= 0) { if (STp->block_size == 0 && - transfer < do_count) + residual < do_count) STps->drv_block++; else if (STp->block_size != 0) STps->drv_block += - (do_count - transfer) / + (transfer - residual) / STp->block_size; } STps->eof = ST_EOM_OK; retval = (-ENOSPC); /* EOM within current request */ DEBC(printk(ST_DEB_MSG "st%d: EOM with %d bytes unwritten.\n", - dev, transfer)); + dev, count)); } else { - STps->eof = ST_EOM_ERROR; - STps->drv_block = (-1); /* Too cautious? */ - retval = (-EIO); /* EOM for old data */ - DEBC(printk(ST_DEB_MSG - "st%d: EOM with lost data.\n", - dev)); + /* EOT in within data buffered earlier */ + if (!retry_eot && (SRpnt->sr_sense_buffer[0] & 1) == 0 && + (scode == NO_SENSE || scode == RECOVERED_ERROR)) { + move_buffer_data(STp->buffer, transfer - residual); + retry_eot = TRUE; + if (STps->drv_block >= 0) { + STps->drv_block += (transfer - residual) / + STp->block_size; + } + STps->eof = ST_EOM_OK; + DEBC(printk(ST_DEB_MSG + "st%d: Retry write of %d bytes at EOM.\n", + dev, do_count)); + goto retry_write; + } + else { + /* Either error within data buffered by driver or failed retry */ + STps->eof = ST_EOM_ERROR; + STps->drv_block = (-1); /* Too cautious? */ + retval = (-EIO); /* EOM for old data */ + DEBC(printk(ST_DEB_MSG + "st%d: EOM with lost data.\n", + dev)); + } } } else { STps->drv_block = (-1); /* Too cautious? */ + retry_eot = FALSE; retval = (-EIO); } @@ -1483,7 +1501,7 @@ (STp->buffer)->buffer_bytes = 0; STp->dirty = 0; } - if (count != 0) { + if (count != 0 && !retry_eot) { STp->dirty = 1; i = append_to_buffer(b_point, STp->buffer, count); if (i) { @@ -1499,26 +1517,14 @@ goto out; } - if (STm->do_async_writes && - (((STp->buffer)->buffer_bytes >= STp->write_threshold && - (STp->buffer)->buffer_bytes >= STp->block_size) || - STp->block_size == 0)) { + if (STm->do_async_writes && STp->block_size == 0) { /* Schedule an asynchronous write */ - if (STp->block_size == 0) - (STp->buffer)->writing = (STp->buffer)->buffer_bytes; - else - (STp->buffer)->writing = ((STp->buffer)->buffer_bytes / - STp->block_size) * STp->block_size; - STp->dirty = !((STp->buffer)->writing == - (STp->buffer)->buffer_bytes); - - if (STp->block_size == 0) - blks = (STp->buffer)->writing; - else - blks = (STp->buffer)->writing / STp->block_size; - cmd[2] = blks >> 16; - cmd[3] = blks >> 8; - cmd[4] = blks; + (STp->buffer)->writing = (STp->buffer)->buffer_bytes; + STp->dirty = FALSE; + residual = (STp->buffer)->writing; + cmd[2] = residual >> 16; + cmd[3] = residual >> 8; + cmd[4] = residual; DEB( STp->write_pending = 1; ) SRpnt = st_do_scsi(SRpnt, STp, cmd, (STp->buffer)->writing, @@ -1532,9 +1538,9 @@ } STps->at_sm &= (total == 0); - if (total > 0) + if (total > 0 && !retry_eot) STps->eof = ST_NOEOF; - retval = total; + retval = total - count; out: if (SRpnt != NULL) @@ -1625,9 +1631,14 @@ if (SRpnt->sr_sense_buffer[2] & 0x20) { /* ILI */ if (STp->block_size == 0) { - if (transfer < 0) { + if (transfer <= 0) { + if (transfer < 0) + printk(KERN_NOTICE + "st%d: Failed to read %d byte block with %d byte read.\n", + dev, bytes - transfer, bytes); if (STps->drv_block >= 0) STps->drv_block += 1; + (STp->buffer)->buffer_bytes = 0; return (-ENOMEM); } (STp->buffer)->buffer_bytes = bytes - transfer; @@ -1694,6 +1705,9 @@ } else /* Some other extended sense code */ retval = (-EIO); } + + if ((STp->buffer)->buffer_bytes < 0) /* Caused by bogus sense data */ + (STp->buffer)->buffer_bytes = 0; } /* End of extended sense test */ else { /* Non-extended sense */ @@ -2004,16 +2018,7 @@ debugging = value; ) st_log_options(STp, STm, dev); } else if (code == MT_ST_WRITE_THRESHOLD) { - value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE; - if (value < 1 || value > st_buffer_size) { - printk(KERN_WARNING - "st%d: Write threshold %d too small or too large.\n", - dev, value); - return (-EIO); - } - STp->write_threshold = value; - printk(KERN_INFO "st%d: Write threshold set to %d bytes.\n", - dev, value); + /* Retained for compatibility */ } else if (code == MT_ST_DEF_BLKSIZE) { value = (options & ~MT_ST_OPTIONS); if (value == ~MT_ST_OPTIONS) { @@ -2155,7 +2160,7 @@ /* Send the mode page in the tape buffer to the drive. Assumes that the mode data in the buffer is correctly formatted. */ -static int write_mode_page(Scsi_Tape *STp, int page) +static int write_mode_page(Scsi_Tape *STp, int page, int slow) { int pgo; unsigned char cmd[MAX_COMMAND_SIZE]; @@ -2174,7 +2179,7 @@ (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR; SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, - STp->timeout, 0, TRUE); + (slow ? STp->long_timeout : STp->timeout), 0, TRUE); if (SRpnt == NULL) return (STp->buffer)->syscall_result; @@ -2241,7 +2246,7 @@ b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */ } - retval = write_mode_page(STp, COMPRESSION_PAGE); + retval = write_mode_page(STp, COMPRESSION_PAGE, FALSE); if (retval) { DEBC(printk(ST_DEB_MSG "st%d: Compression change failed.\n", dev)); return (-EIO); @@ -3055,7 +3060,7 @@ bp[pgo + PP_OFF_RESERVED] = 0; bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB; - result = write_mode_page(STp, PART_PAGE); + result = write_mode_page(STp, PART_PAGE, TRUE); if (result) { printk(KERN_INFO "st%d: Partitioning of tape failed.\n", dev); result = (-EIO); @@ -3644,6 +3649,50 @@ } +/* Move data towards start of buffer */ +static void move_buffer_data(ST_buffer * st_bp, int offset) +{ + int src_seg, dst_seg, src_offset = 0, dst_offset; + int count, total; + + if (offset == 0) + return; + + total=st_bp->buffer_bytes - offset; + for (src_seg=0; src_seg < st_bp->sg_segs; src_seg++) { + src_offset = offset; + if (src_offset < st_bp->sg_lengths[src_seg]) + break; + offset -= st_bp->sg_lengths[src_seg]; + } + if (src_seg == st_bp->sg_segs) { /* Should never happen */ + printk(KERN_WARNING "st: zap_buffer offset overflow.\n"); + return; + } + + st_bp->buffer_bytes = st_bp->read_pointer = total; + for (dst_seg=dst_offset=0; total > 0; ) { + count = min(st_bp->sg_lengths[dst_seg] - dst_offset, + st_bp->sg_lengths[src_seg] - src_offset); + memmove(st_bp->sg[dst_seg].address + dst_offset, + st_bp->sg[src_seg].address + src_offset, count); + printk("st: move (%d,%d) -> (%d,%d) count %d\n", + src_seg, src_offset, dst_seg, dst_offset, count); + src_offset += count; + if (src_offset >= st_bp->sg_lengths[src_seg]) { + src_seg++; + src_offset = 0; + } + dst_offset += count; + if (dst_offset >= st_bp->sg_lengths[dst_seg]) { + dst_seg++; + dst_offset = 0; + } + total -= count; + } +} + + /* Set the scatter/gather list length fields to sum up to the transfer length. Return the number of segments being used. */ static int set_sg_lengths(ST_buffer *st_bp, unsigned int length) @@ -3668,15 +3717,6 @@ { if (buffer_kbs > 0) st_buffer_size = buffer_kbs * ST_KILOBYTE; - if (write_threshold_kbs > 0) - st_write_threshold = write_threshold_kbs * ST_KILOBYTE; - else if (buffer_kbs > 0) - st_write_threshold = st_buffer_size - 2048; - if (st_write_threshold > st_buffer_size) { - st_write_threshold = st_buffer_size; - printk(KERN_WARNING "st: write_threshold limited to %d bytes.\n", - st_write_threshold); - } if (max_buffers >= 0) st_max_buffers = max_buffers; if (max_sg_segs >= ST_FIRST_SG) @@ -3695,13 +3735,15 @@ if (ints[0] > 0) { for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++) - *parms[i].val = ints[i + 1]; + if (parms[i].val) + *parms[i].val = ints[i + 1]; } else { while (stp != NULL) { for (i = 0; i < ARRAY_SIZE(parms); i++) { len = strlen(parms[i].name); if (!strncmp(stp, parms[i].name, len) && - (*(stp + len) == ':' || *(stp + len) == '=')) { + (*(stp + len) == ':' || *(stp + len) == '=') && + parms[i].val) { *parms[i].val = simple_strtoul(stp + len + 1, NULL, 0); break; @@ -3863,7 +3905,6 @@ tpnt->fast_mteom = ST_FAST_MTEOM; tpnt->scsi2_logical = ST_SCSI2LOGICAL; tpnt->immediate = ST_NOWAIT; - tpnt->write_threshold = st_write_threshold; tpnt->default_drvbuffer = 0xff; /* No forced buffering */ tpnt->partition = 0; tpnt->new_partition = 0; @@ -3941,8 +3982,8 @@ return 0; printk(KERN_INFO - "st: Version %s, bufsize %d, wrt %d, max init. bufs %d, s/g segs %d\n", - verstr, st_buffer_size, st_write_threshold, st_max_buffers, st_max_sg_segs); + "st: Version %s, bufsize %d, max init. bufs %d, s/g segs %d\n", + verstr, st_buffer_size, st_max_buffers, st_max_sg_segs); write_lock_irqsave(&st_dev_arr_lock, flags); if (!st_registered) { diff -urN linux-2.4.21/drivers/scsi/st.h linux-2.4.22/drivers/scsi/st.h --- linux-2.4.21/drivers/scsi/st.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/st.h 2003-08-25 04:44:42.000000000 -0700 @@ -86,7 +86,6 @@ unsigned char use_pf; /* Set Page Format bit in all mode selects? */ unsigned char c_algo; /* compression algorithm */ int tape_type; - int write_threshold; int timeout; /* timeout for normal commands */ int long_timeout; /* timeout for commands known to take long time */ diff -urN linux-2.4.21/drivers/scsi/st_options.h linux-2.4.22/drivers/scsi/st_options.h --- linux-2.4.21/drivers/scsi/st_options.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/scsi/st_options.h 2003-08-25 04:44:42.000000000 -0700 @@ -1,9 +1,9 @@ /* The compile-time configurable defaults for the Linux SCSI tape driver. - Copyright 1995-2002 Kai Makisara. + Copyright 1995-2003 Kai Makisara. - Last modified: Wed May 1 11:06:47 2002 by makisara + Last modified: Sun Apr 6 22:45:15 2003 by makisara */ #ifndef _ST_OPTIONS_H @@ -33,11 +33,6 @@ /* The tape driver buffer size in kilobytes. Must be non-zero. */ #define ST_BUFFER_BLOCKS 32 -/* The number of kilobytes of data in the buffer that triggers an - asynchronous write in fixed block mode. See also ST_ASYNC_WRITES - below. */ -#define ST_WRITE_THRESHOLD_BLOCKS 30 - /* The maximum number of tape buffers the driver tries to allocate at driver initialisation. The number is also constrained by the number of drives detected. If more buffers are needed, they are allocated diff -urN linux-2.4.21/drivers/scsi/sym53c8xx_2/sym_hipd.c linux-2.4.22/drivers/scsi/sym53c8xx_2/sym_hipd.c --- linux-2.4.21/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.22/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-08-25 04:44:42.000000000 -0700 @@ -4641,7 +4641,10 @@ case M_IGN_RESIDUE: if (DEBUG_FLAGS & DEBUG_POINTER) sym_print_msg(cp,"ign wide residue", np->msgin); - sym_modify_dp(np, tp, cp, -1); + if (cp->host_flags & HF_SENSE) + OUTL_DSP (SCRIPTA_BA (np, clrack)); + else + sym_modify_dp(np, tp, cp, -1); return; case M_REJECT: if (INB (HS_PRT) == HS_NEGOTIATE) diff -urN linux-2.4.21/drivers/sgi/Config.in linux-2.4.22/drivers/sgi/Config.in --- linux-2.4.21/drivers/sgi/Config.in 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/sgi/Config.in 1969-12-31 16:00:00.000000000 -0800 @@ -1,17 +0,0 @@ -# -# Character device configuration -# -mainmenu_option next_comment -comment 'SGI devices' - -bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL -if [ "$CONFIG_SGI_SERIAL" = "y" ]; then - bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE -fi -bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286 - -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'SGI Newport Graphics support (EXPERIMENTAL)' CONFIG_SGI_NEWPORT_GFX -fi - -endmenu diff -urN linux-2.4.21/drivers/sgi/Makefile linux-2.4.22/drivers/sgi/Makefile --- linux-2.4.21/drivers/sgi/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.22/drivers/sgi/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,19 +0,0 @@ -# -# Makefile for the linux kernel. -# -# 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... - -L_TARGET := sgi.a - -# -# Character and Audio devices for SGI machines. -# -subdir-y += char -subdir-m += char -obj-y += char/sgichar.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/sgi/char/Makefile linux-2.4.22/drivers/sgi/char/Makefile --- linux-2.4.21/drivers/sgi/char/Makefile 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.22/drivers/sgi/char/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,19 +0,0 @@ -# -# Makefile for the linux kernel. -# -# 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 := sgichar.o - -export-objs := newport.o rrm.o shmiq.o sgicons.o usema.o -obj-y := newport.o shmiq.o sgicons.o usema.o streamable.o - -obj-$(CONFIG_SGI_SERIAL) += sgiserial.o -obj-$(CONFIG_SGI_DS1286) += ds1286.o -obj-$(CONFIG_SGI_NEWPORT_GFX) += graphics.o rrm.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21/drivers/sgi/char/ds1286.c linux-2.4.22/drivers/sgi/char/ds1286.c --- linux-2.4.21/drivers/sgi/char/ds1286.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/sgi/char/ds1286.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,531 +0,0 @@ -/* - * DS1286 Real Time Clock interface for Linux - * - * Copyright (C) 1998, 1999, 2000 Ralf Baechle - * - * Based on code written by Paul Gortmaker. - * - * This driver allows use of the real time clock (built into nearly all - * computers) from user space. It exports the /dev/rtc interface supporting - * various ioctl() and also the /proc/rtc pseudo-file for status - * information. - * - * The ioctls can be used to set the interrupt behaviour and generation rate - * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make - * use of these timer interrupts, be they interval or alarm based. - * - * The /dev/rtc interface will block on reads until an interrupt has been - * received. If a RTC interrupt has already happened, it will output an - * unsigned long and then block. The output value contains the interrupt - * status in the low byte and the number of interrupts since the last read - * in the remaining high bytes. The /dev/rtc interface can also be used with - * the select(2) call. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define DS1286_VERSION "1.0" - -/* - * We sponge a minor off of the misc major. No need slurping - * up another valuable major dev number for this. If you add - * an ioctl, make sure you don't conflict with SPARC's RTC - * ioctls. - */ - -static DECLARE_WAIT_QUEUE_HEAD(ds1286_wait); - -static ssize_t ds1286_read(struct file *file, char *buf, - size_t count, loff_t *ppos); - -static int ds1286_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -static unsigned int ds1286_poll(struct file *file, poll_table *wait); - -void ds1286_get_alm_time (struct rtc_time *alm_tm); -void ds1286_get_time(struct rtc_time *rtc_tm); -int ds1286_set_time(struct rtc_time *rtc_tm); - -void set_rtc_irq_bit(unsigned char bit); -void clear_rtc_irq_bit(unsigned char bit); - -static inline unsigned char ds1286_is_updating(void); - -static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED; - -/* - * Bits in rtc_status. (7 bits of room for future expansion) - */ - -#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ -#define RTC_TIMER_ON 0x02 /* missed irq timer active */ - -unsigned char ds1286_status; /* bitmapped status byte. */ -unsigned long ds1286_freq; /* Current periodic IRQ rate */ - -unsigned char days_in_mo[] = -{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -/* - * Now all the various file operations that we export. - */ - -static ssize_t ds1286_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - return -EIO; -} - -static int ds1286_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - - struct rtc_time wtime; - - switch (cmd) { - case RTC_AIE_OFF: /* Mask alarm int. enab. bit */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val |= RTC_TDM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_AIE_ON: /* Allow alarm interrupts. */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val &= ~RTC_TDM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val |= RTC_WAM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_WIE_ON: /* Allow watchdog interrupts. */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val &= ~RTC_WAM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_ALM_READ: /* Read the present alarm time */ - { - /* - * This returns a struct rtc_time. Reading >= 0xc0 - * means "don't care" or "match all". Only the tm_hour, - * tm_min, and tm_sec values are filled in. - */ - - ds1286_get_alm_time(&wtime); - break; - } - case RTC_ALM_SET: /* Store a time into the alarm */ - { - /* - * This expects a struct rtc_time. Writing 0xff means - * "don't care" or "match all". Only the tm_hour, - * tm_min and tm_sec are used. - */ - unsigned char hrs, min, sec; - struct rtc_time alm_tm; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&alm_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - hrs = alm_tm.tm_hour; - min = alm_tm.tm_min; - - if (hrs >= 24) - hrs = 0xff; - - if (min >= 60) - min = 0xff; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - - spin_lock(&ds1286_lock); - CMOS_WRITE(hrs, RTC_HOURS_ALARM); - CMOS_WRITE(min, RTC_MINUTES_ALARM); - spin_unlock(&ds1286_lock); - - return 0; - } - case RTC_RD_TIME: /* Read the time/date from RTC */ - { - ds1286_get_time(&wtime); - break; - } - case RTC_SET_TIME: /* Set the RTC */ - { - struct rtc_time rtc_tm; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - return ds1286_set_time(&rtc_tm); - } - default: - return -EINVAL; - } - return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; -} - -/* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. - */ - -static int ds1286_open(struct inode *inode, struct file *file) -{ - spin_lock_irq(&ds1286_lock); - - if (ds1286_status & RTC_IS_OPEN) - goto out_busy; - - ds1286_status |= RTC_IS_OPEN; - - spin_lock_irq(&ds1286_lock); - return 0; - -out_busy: - spin_lock_irq(&ds1286_lock); - return -EBUSY; -} - -static int ds1286_release(struct inode *inode, struct file *file) -{ - ds1286_status &= ~RTC_IS_OPEN; - - return 0; -} - -static unsigned int ds1286_poll(struct file *file, poll_table *wait) -{ - poll_wait(file, &ds1286_wait, wait); - - return 0; -} - -/* - * The various file operations we support. - */ - -static struct file_operations ds1286_fops = { - llseek: no_llseek, - read: ds1286_read, - poll: ds1286_poll, - ioctl: ds1286_ioctl, - open: ds1286_open, - release: ds1286_release, -}; - -static struct miscdevice ds1286_dev= -{ - RTC_MINOR, - "rtc", - &ds1286_fops -}; - -int __init ds1286_init(void) -{ - printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); - misc_register(&ds1286_dev); - - return 0; -} - -static char *days[] = { - "***", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -/* - * Info exported via "/proc/rtc". - */ -int get_ds1286_status(char *buf) -{ - char *p, *s; - struct rtc_time tm; - unsigned char hundredth, month, cmd, amode; - - p = buf; - - ds1286_get_time(&tm); - hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND); - BCD_TO_BIN(hundredth); - - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d.%02d\n" - "rtc_date\t: %04d-%02d-%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, hundredth, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - - /* - * We implicitly assume 24hr mode here. Alarm values >= 0xc0 will - * match any value for that particular field. Values that are - * greater than a valid time, but less than 0xc0 shouldn't appear. - */ - ds1286_get_alm_time(&tm); - p += sprintf(p, "alarm\t\t: %s ", days[tm.tm_wday]); - if (tm.tm_hour <= 24) - p += sprintf(p, "%02d:", tm.tm_hour); - else - p += sprintf(p, "**:"); - - if (tm.tm_min <= 59) - p += sprintf(p, "%02d\n", tm.tm_min); - else - p += sprintf(p, "**\n"); - - month = CMOS_READ(RTC_MONTH); - p += sprintf(p, - "oscillator\t: %s\n" - "square_wave\t: %s\n", - (month & RTC_EOSC) ? "disabled" : "enabled", - (month & RTC_ESQW) ? "disabled" : "enabled"); - - amode = ((CMOS_READ(RTC_MINUTES_ALARM) & 0x80) >> 5) | - ((CMOS_READ(RTC_HOURS_ALARM) & 0x80) >> 6) | - ((CMOS_READ(RTC_DAY_ALARM) & 0x80) >> 7); - if (amode == 7) s = "each minute"; - else if (amode == 3) s = "minutes match"; - else if (amode == 1) s = "hours and minutes match"; - else if (amode == 0) s = "days, hours and minutes match"; - else s = "invalid"; - p += sprintf(p, "alarm_mode\t: %s\n", s); - - cmd = CMOS_READ(RTC_CMD); - p += sprintf(p, - "alarm_enable\t: %s\n" - "wdog_alarm\t: %s\n" - "alarm_mask\t: %s\n" - "wdog_alarm_mask\t: %s\n" - "interrupt_mode\t: %s\n" - "INTB_mode\t: %s_active\n" - "interrupt_pins\t: %s\n", - (cmd & RTC_TDF) ? "yes" : "no", - (cmd & RTC_WAF) ? "yes" : "no", - (cmd & RTC_TDM) ? "disabled" : "enabled", - (cmd & RTC_WAM) ? "disabled" : "enabled", - (cmd & RTC_PU_LVL) ? "pulse" : "level", - (cmd & RTC_IBH_LO) ? "low" : "high", - (cmd & RTC_IPSW) ? "unswapped" : "swapped"); - - return p - buf; -} - -/* - * Returns true if a clock update is in progress - */ -static inline unsigned char ds1286_is_updating(void) -{ - return CMOS_READ(RTC_CMD) & RTC_TE; -} - - -void ds1286_get_time(struct rtc_time *rtc_tm) -{ - unsigned char save_control; - unsigned int flags; - unsigned long uip_watchdog = jiffies; - - /* - * read RTC once any update in progress is done. The update - * can take just over 2ms. We wait 10 to 20ms. There is no need to - * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. - * If you need to know *exactly* when a second has started, enable - * periodic update complete interrupts, (via ioctl) and then - * immediately read /dev/rtc which will block until you get the IRQ. - * Once the read clears, read the RTC time (again via ioctl). Easy. - */ - - if (ds1286_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) - barrier(); - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - spin_lock_irqsave(&ds1286_lock, flags); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); - - rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); - rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); - rtc_tm->tm_hour = CMOS_READ(RTC_HOURS) & 0x1f; - rtc_tm->tm_mday = CMOS_READ(RTC_DATE); - rtc_tm->tm_mon = CMOS_READ(RTC_MONTH) & 0x1f; - rtc_tm->tm_year = CMOS_READ(RTC_YEAR); - - CMOS_WRITE(save_control, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - BCD_TO_BIN(rtc_tm->tm_sec); - BCD_TO_BIN(rtc_tm->tm_min); - BCD_TO_BIN(rtc_tm->tm_hour); - BCD_TO_BIN(rtc_tm->tm_mday); - BCD_TO_BIN(rtc_tm->tm_mon); - BCD_TO_BIN(rtc_tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if (rtc_tm->tm_year < 45) - rtc_tm->tm_year += 30; - if ((rtc_tm->tm_year += 40) < 70) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} - -int ds1286_set_time(struct rtc_time *rtc_tm) -{ - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned char save_control; - unsigned int yrs, flags; - - - yrs = rtc_tm->tm_year + 1900; - mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm->tm_mday; - hrs = rtc_tm->tm_hour; - min = rtc_tm->tm_min; - sec = rtc_tm->tm_sec; - - if (yrs < 1970) - return -EINVAL; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if ((yrs -= 1940) > 255) /* They are unsigned */ - return -EINVAL; - - if (yrs >= 100) - yrs -= 100; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(yrs); - - spin_lock_irqsave(&ds1286_lock, flags); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); - - CMOS_WRITE(yrs, RTC_YEAR); - CMOS_WRITE(mon, RTC_MONTH); - CMOS_WRITE(day, RTC_DATE); - CMOS_WRITE(hrs, RTC_HOURS); - CMOS_WRITE(min, RTC_MINUTES); - CMOS_WRITE(sec, RTC_SECONDS); - CMOS_WRITE(0, RTC_HUNDREDTH_SECOND); - - CMOS_WRITE(save_control, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; -} - -void ds1286_get_alm_time(struct rtc_time *alm_tm) -{ - unsigned char cmd; - unsigned int flags; - - /* - * Only the values that we read from the RTC are set. That - * means only tm_wday, tm_hour, tm_min. - */ - spin_lock_irqsave(&ds1286_lock, flags); - alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM) & 0x7f; - alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM) & 0x1f; - alm_tm->tm_wday = CMOS_READ(RTC_DAY_ALARM) & 0x07; - cmd = CMOS_READ(RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - BCD_TO_BIN(alm_tm->tm_min); - BCD_TO_BIN(alm_tm->tm_hour); - alm_tm->tm_sec = 0; -} diff -urN linux-2.4.21/drivers/sgi/char/gconsole.h linux-2.4.22/drivers/sgi/char/gconsole.h --- linux-2.4.21/drivers/sgi/char/gconsole.h 1997-12-10 10:31:11.000000000 -0800 +++ linux-2.4.22/drivers/sgi/char/gconsole.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,33 +0,0 @@ -/* - * This is a temporary measure, we should eventually migrate to - * Gert's generic graphic console code. - */ - -#define cmapsz 8192 -#define CHAR_HEIGHT 16 - -struct console_ops { - void (*set_origin)(unsigned short offset); - void (*hide_cursor)(void); - void (*set_cursor)(int currcons); - void (*get_scrmem)(int currcons); - void (*set_scrmem)(int currcons, long offset); - int (*set_get_cmap)(unsigned char *arg, int set); - void (*blitc)(unsigned short charattr, unsigned long addr); - void (*memsetw)(void *s, unsigned short c, unsigned int count); - void (*memcpyw)(unsigned short *to, unsigned short *from, unsigned int count); -}; - -void register_gconsole (struct console_ops *); - -/* This points to the system console */ -extern struct console_ops *gconsole; - -extern void gfx_init (const char **name); - -extern void __set_origin (unsigned short offset); -extern void hide_cursor (void); -extern unsigned char vga_font[]; - -extern void disable_gconsole (void); -extern void enable_gconsole (void); diff -urN linux-2.4.21/drivers/sgi/char/graphics.c linux-2.4.22/drivers/sgi/char/graphics.c --- linux-2.4.21/drivers/sgi/char/graphics.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.22/drivers/sgi/char/graphics.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,376 +0,0 @@ -/* - * gfx.c: support for SGI's /dev/graphics, /dev/opengl - * - * Author: Miguel de Icaza (miguel@nuclecu.unam.mx) - * Ralf Baechle (ralf@gnu.org) - * Ulf Carlsson (ulfc@bun.falkenberg.se) - * - * On IRIX, /dev/graphics is [10, 146] - * /dev/opengl is [10, 147] - * - * From a mail with Mark J. Kilgard, /dev/opengl and /dev/graphics are - * the same thing, the use of /dev/graphics seems deprecated though. - * - * The reason that the original SGI programmer had to use only one - * device for all the graphic cards on the system will remain a - * mistery for the rest of our lives. Why some ioctls take a board - * number and some others not? Mistery. Why do they map the hardware - * registers into the user address space with an ioctl instead of - * mmap? Mistery too. Why they did not use the standard way of - * making ioctl constants and instead sticked a random constant? - * Mistery too. - * - * We implement those misterious things, and tried not to think about - * the reasons behind them. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "gconsole.h" -#include "graphics.h" -#include "usema.h" -#include -#include -#include -#include -#include